···177178---------------------------1790000000000180What: remove EXPORT_SYMBOL(tasklist_lock)181When: August 2006182Files: kernel/fork.c
···177178---------------------------179180+What: Unused EXPORT_SYMBOL/EXPORT_SYMBOL_GPL exports181+ (temporary transition config option provided until then)182+ The transition config option will also be removed at the same time.183+When: before 2.6.19184+Why: Unused symbols are both increasing the size of the kernel binary185+ and are often a sign of "wrong API"186+Who: Arjan van de Ven <arjan@linux.intel.com>187+188+---------------------------189+190What: remove EXPORT_SYMBOL(tasklist_lock)191When: August 2006192Files: kernel/fork.c
+2-71
Documentation/watchdog/pcwd-watchdog.txt
···22 to run the program with an "&" to run it in the background!)2324 If you want to write a program to be compatible with the PC Watchdog25- driver, simply do the following:02627--- Snippet of code --28-/*29- * Watchdog Driver Test Program30- */31-32-#include <stdio.h>33-#include <stdlib.h>34-#include <string.h>35-#include <unistd.h>36-#include <fcntl.h>37-#include <sys/ioctl.h>38-#include <linux/types.h>39-#include <linux/watchdog.h>40-41-int fd;42-43-/*44- * This function simply sends an IOCTL to the driver, which in turn ticks45- * the PC Watchdog card to reset its internal timer so it doesn't trigger46- * a computer reset.47- */48-void keep_alive(void)49-{50- int dummy;51-52- ioctl(fd, WDIOC_KEEPALIVE, &dummy);53-}54-55-/*56- * The main program. Run the program with "-d" to disable the card,57- * or "-e" to enable the card.58- */59-int main(int argc, char *argv[])60-{61- fd = open("/dev/watchdog", O_WRONLY);62-63- if (fd == -1) {64- fprintf(stderr, "Watchdog device not enabled.\n");65- fflush(stderr);66- exit(-1);67- }68-69- if (argc > 1) {70- if (!strncasecmp(argv[1], "-d", 2)) {71- ioctl(fd, WDIOC_SETOPTIONS, WDIOS_DISABLECARD);72- fprintf(stderr, "Watchdog card disabled.\n");73- fflush(stderr);74- exit(0);75- } else if (!strncasecmp(argv[1], "-e", 2)) {76- ioctl(fd, WDIOC_SETOPTIONS, WDIOS_ENABLECARD);77- fprintf(stderr, "Watchdog card enabled.\n");78- fflush(stderr);79- exit(0);80- } else {81- fprintf(stderr, "-d to disable, -e to enable.\n");82- fprintf(stderr, "run by itself to tick the card.\n");83- fflush(stderr);84- exit(0);85- }86- } else {87- fprintf(stderr, "Watchdog Ticking Away!\n");88- fflush(stderr);89- }90-91- while(1) {92- keep_alive();93- sleep(1);94- }95-}96--- End snippet --9798 Other IOCTL functions include:99
···22 to run the program with an "&" to run it in the background!)2324 If you want to write a program to be compatible with the PC Watchdog25+ driver, simply use of modify the watchdog test program:26+ Documentation/watchdog/src/watchdog-test.c2700000000000000000000000000000000000000000000000000000000000000000000002829 Other IOCTL functions include:30
···1+/*2+ * Watchdog Driver Test Program3+ */4+5+#include <stdio.h>6+#include <stdlib.h>7+#include <string.h>8+#include <unistd.h>9+#include <fcntl.h>10+#include <sys/ioctl.h>11+#include <linux/types.h>12+#include <linux/watchdog.h>13+14+int fd;15+16+/*17+ * This function simply sends an IOCTL to the driver, which in turn ticks18+ * the PC Watchdog card to reset its internal timer so it doesn't trigger19+ * a computer reset.20+ */21+void keep_alive(void)22+{23+ int dummy;24+25+ ioctl(fd, WDIOC_KEEPALIVE, &dummy);26+}27+28+/*29+ * The main program. Run the program with "-d" to disable the card,30+ * or "-e" to enable the card.31+ */32+int main(int argc, char *argv[])33+{34+ fd = open("/dev/watchdog", O_WRONLY);35+36+ if (fd == -1) {37+ fprintf(stderr, "Watchdog device not enabled.\n");38+ fflush(stderr);39+ exit(-1);40+ }41+42+ if (argc > 1) {43+ if (!strncasecmp(argv[1], "-d", 2)) {44+ ioctl(fd, WDIOC_SETOPTIONS, WDIOS_DISABLECARD);45+ fprintf(stderr, "Watchdog card disabled.\n");46+ fflush(stderr);47+ exit(0);48+ } else if (!strncasecmp(argv[1], "-e", 2)) {49+ ioctl(fd, WDIOC_SETOPTIONS, WDIOS_ENABLECARD);50+ fprintf(stderr, "Watchdog card enabled.\n");51+ fflush(stderr);52+ exit(0);53+ } else {54+ fprintf(stderr, "-d to disable, -e to enable.\n");55+ fprintf(stderr, "run by itself to tick the card.\n");56+ fflush(stderr);57+ exit(0);58+ }59+ } else {60+ fprintf(stderr, "Watchdog Ticking Away!\n");61+ fflush(stderr);62+ }63+64+ while(1) {65+ keep_alive();66+ sleep(1);67+ }68+}
+39-17
Documentation/watchdog/watchdog-api.txt
···34the watchdog is pinged within a certain time, this time is called the35timeout or margin. The simplest way to ping the watchdog is to write36some data to the device. So a very simple watchdog daemon would look37-like this:38-39-#include <stdlib.h>40-#include <fcntl.h>41-42-int main(int argc, const char *argv[]) {43- int fd=open("/dev/watchdog",O_WRONLY);44- if (fd==-1) {45- perror("watchdog");46- exit(1);47- }48- while(1) {49- write(fd, "\0", 1);50- sleep(10);51- }52-}5354A more advanced driver could for example check that a HTTP server is55still responding before doing the write call to ping the watchdog.···95 ioctl(fd, WDIOC_GETTIMEOUT, &timeout);96 printf("The timeout was is %d seconds\n", timeout);9798-Envinronmental monitoring:00000000000000000000000000000000099100All watchdog drivers are required return more information about the system,101some do temperature, fan and power level monitoring, some can tell you···186The watchdog saw a keepalive ping since it was last queried.187188 WDIOF_SETTIMEOUT Can set/get the timeout0000189190191For those drivers that return any bits set in the option field, the
···34the watchdog is pinged within a certain time, this time is called the35timeout or margin. The simplest way to ping the watchdog is to write36some data to the device. So a very simple watchdog daemon would look37+like this source file: see Documentation/watchdog/src/watchdog-simple.c0000000000000003839A more advanced driver could for example check that a HTTP server is40still responding before doing the write call to ping the watchdog.···110 ioctl(fd, WDIOC_GETTIMEOUT, &timeout);111 printf("The timeout was is %d seconds\n", timeout);112113+Pretimeouts:114+115+Some watchdog timers can be set to have a trigger go off before the116+actual time they will reset the system. This can be done with an NMI,117+interrupt, or other mechanism. This allows Linux to record useful118+information (like panic information and kernel coredumps) before it119+resets.120+121+ pretimeout = 10;122+ ioctl(fd, WDIOC_SETPRETIMEOUT, &pretimeout);123+124+Note that the pretimeout is the number of seconds before the time125+when the timeout will go off. It is not the number of seconds until126+the pretimeout. So, for instance, if you set the timeout to 60 seconds127+and the pretimeout to 10 seconds, the pretimout will go of in 50128+seconds. Setting a pretimeout to zero disables it.129+130+There is also a get function for getting the pretimeout:131+132+ ioctl(fd, WDIOC_GETPRETIMEOUT, &timeout);133+ printf("The pretimeout was is %d seconds\n", timeout);134+135+Not all watchdog drivers will support a pretimeout.136+137+Get the number of seconds before reboot:138+139+Some watchdog drivers have the ability to report the remaining time140+before the system will reboot. The WDIOC_GETTIMELEFT is the ioctl141+that returns the number of seconds before reboot.142+143+ ioctl(fd, WDIOC_GETTIMELEFT, &timeleft);144+ printf("The timeout was is %d seconds\n", timeleft);145+146+Environmental monitoring:147148All watchdog drivers are required return more information about the system,149some do temperature, fan and power level monitoring, some can tell you···168The watchdog saw a keepalive ping since it was last queried.169170 WDIOF_SETTIMEOUT Can set/get the timeout171+172+The watchdog can do pretimeouts.173+174+ WDIOF_PRETIMEOUT Pretimeout (in seconds), get/set175176177For those drivers that return any bits set in the option field, the
+1-22
Documentation/watchdog/watchdog.txt
···65Minor numbers are however allocated for it.666768-Example Watchdog Driver69------------------------70-71-#include <stdio.h>72-#include <unistd.h>73-#include <fcntl.h>74-75-int main(int argc, const char *argv[])76-{77- int fd=open("/dev/watchdog",O_WRONLY);78- if(fd==-1)79- {80- perror("watchdog");81- exit(1);82- }83- while(1)84- {85- write(fd,"\0",1);86- fsync(fd);87- sleep(10);88- }89-}909192Contact Information
···65Minor numbers are however allocated for it.666768+Example Watchdog Driver: see Documentation/watchdog/src/watchdog-simple.c000000000000000000000697071Contact Information
+9
arch/arm/Kconfig
···188189config ARCH_IOP3XX190 bool "IOP3xx-based"0191 select PCI192 help193 Support for Intel's IOP3XX (XScale) family of processors.194195config ARCH_IXP4XX196 bool "IXP4xx-based"0197 help198 Support for Intel's IXP4XX (XScale) family of processors.199200config ARCH_IXP2000201 bool "IXP2400/2800-based"0202 select PCI203 help204 Support for Intel's IXP2400/2800 (XScale) family of processors.205206config ARCH_IXP23XX207 bool "IXP23XX-based"0208 select PCI209 help210 Support for Intel's IXP23xx (XScale) family of processors.···233234config ARCH_PXA235 bool "PXA2xx-based"0236 select ARCH_MTD_XIP237 help238 Support for Intel's PXA2XX processor line.···343 bool344 depends on CPU_XSCALE && !XSCALE_PMU_TIMER345 default y0000346347endmenu348
···188189config ARCH_IOP3XX190 bool "IOP3xx-based"191+ depends on MMU192 select PCI193 help194 Support for Intel's IOP3XX (XScale) family of processors.195196config ARCH_IXP4XX197 bool "IXP4xx-based"198+ depends on MMU199 help200 Support for Intel's IXP4XX (XScale) family of processors.201202config ARCH_IXP2000203 bool "IXP2400/2800-based"204+ depends on MMU205 select PCI206 help207 Support for Intel's IXP2400/2800 (XScale) family of processors.208209config ARCH_IXP23XX210 bool "IXP23XX-based"211+ depends on MMU212 select PCI213 help214 Support for Intel's IXP23xx (XScale) family of processors.···229230config ARCH_PXA231 bool "PXA2xx-based"232+ depends on MMU233 select ARCH_MTD_XIP234 help235 Support for Intel's PXA2XX processor line.···338 bool339 depends on CPU_XSCALE && !XSCALE_PMU_TIMER340 default y341+342+if !MMU343+source "arch/arm/Kconfig-nommu"344+endif345346endmenu347
···109EXPORT_SYMBOL(__memzero);110111 /* user mem (segment) */112-EXPORT_SYMBOL(__arch_copy_from_user);113-EXPORT_SYMBOL(__arch_copy_to_user);114-EXPORT_SYMBOL(__arch_clear_user);115-EXPORT_SYMBOL(__arch_strnlen_user);116-EXPORT_SYMBOL(__arch_strncpy_from_user);00117118EXPORT_SYMBOL(__get_user_1);119EXPORT_SYMBOL(__get_user_2);···125EXPORT_SYMBOL(__put_user_2);126EXPORT_SYMBOL(__put_user_4);127EXPORT_SYMBOL(__put_user_8);0128129 /* crypto hash */130EXPORT_SYMBOL(sha_transform);
···109EXPORT_SYMBOL(__memzero);110111 /* user mem (segment) */112+EXPORT_SYMBOL(__strnlen_user);113+EXPORT_SYMBOL(__strncpy_from_user);114+115+#ifdef CONFIG_MMU116+EXPORT_SYMBOL(__copy_from_user);117+EXPORT_SYMBOL(__copy_to_user);118+EXPORT_SYMBOL(__clear_user);119120EXPORT_SYMBOL(__get_user_1);121EXPORT_SYMBOL(__get_user_2);···123EXPORT_SYMBOL(__put_user_2);124EXPORT_SYMBOL(__put_user_4);125EXPORT_SYMBOL(__put_user_8);126+#endif127128 /* crypto hash */129EXPORT_SYMBOL(sha_transform);
···1+/*2+ * arch/arm/kernel/crunch.c3+ * Cirrus MaverickCrunch context switching and handling4+ *5+ * Copyright (C) 2006 Lennert Buytenhek <buytenh@wantstofly.org>6+ *7+ * This program is free software; you can redistribute it and/or modify8+ * it under the terms of the GNU General Public License version 2 as9+ * published by the Free Software Foundation.10+ */11+12+#include <linux/module.h>13+#include <linux/config.h>14+#include <linux/types.h>15+#include <linux/kernel.h>16+#include <linux/signal.h>17+#include <linux/sched.h>18+#include <linux/init.h>19+#include <asm/arch/ep93xx-regs.h>20+#include <asm/thread_notify.h>21+#include <asm/io.h>22+23+struct crunch_state *crunch_owner;24+25+void crunch_task_release(struct thread_info *thread)26+{27+ local_irq_disable();28+ if (crunch_owner == &thread->crunchstate)29+ crunch_owner = NULL;30+ local_irq_enable();31+}32+33+static int crunch_enabled(u32 devcfg)34+{35+ return !!(devcfg & EP93XX_SYSCON_DEVICE_CONFIG_CRUNCH_ENABLE);36+}37+38+static int crunch_do(struct notifier_block *self, unsigned long cmd, void *t)39+{40+ struct thread_info *thread = (struct thread_info *)t;41+ struct crunch_state *crunch_state;42+ u32 devcfg;43+44+ crunch_state = &thread->crunchstate;45+46+ switch (cmd) {47+ case THREAD_NOTIFY_FLUSH:48+ memset(crunch_state, 0, sizeof(*crunch_state));49+50+ /*51+ * FALLTHROUGH: Ensure we don't try to overwrite our newly52+ * initialised state information on the first fault.53+ */54+55+ case THREAD_NOTIFY_RELEASE:56+ crunch_task_release(thread);57+ break;58+59+ case THREAD_NOTIFY_SWITCH:60+ devcfg = __raw_readl(EP93XX_SYSCON_DEVICE_CONFIG);61+ if (crunch_enabled(devcfg) || crunch_owner == crunch_state) {62+ devcfg ^= EP93XX_SYSCON_DEVICE_CONFIG_CRUNCH_ENABLE;63+ __raw_writel(0xaa, EP93XX_SYSCON_SWLOCK);64+ __raw_writel(devcfg, EP93XX_SYSCON_DEVICE_CONFIG);65+ }66+ break;67+ }68+69+ return NOTIFY_DONE;70+}71+72+static struct notifier_block crunch_notifier_block = {73+ .notifier_call = crunch_do,74+};75+76+static int __init crunch_init(void)77+{78+ thread_register_notifier(&crunch_notifier_block);79+80+ return 0;81+}82+83+late_initcall(crunch_init);
+6
arch/arm/kernel/entry-armv.S
···492 b do_fpe @ CP#1 (FPE)493 b do_fpe @ CP#2 (FPE)494 mov pc, lr @ CP#300000495 mov pc, lr @ CP#4496 mov pc, lr @ CP#5497 mov pc, lr @ CP#60498 mov pc, lr @ CP#7499 mov pc, lr @ CP#8500 mov pc, lr @ CP#9
···492 b do_fpe @ CP#1 (FPE)493 b do_fpe @ CP#2 (FPE)494 mov pc, lr @ CP#3495+#ifdef CONFIG_CRUNCH496+ b crunch_task_enable @ CP#4 (MaverickCrunch)497+ b crunch_task_enable @ CP#5 (MaverickCrunch)498+ b crunch_task_enable @ CP#6 (MaverickCrunch)499+#else500 mov pc, lr @ CP#4501 mov pc, lr @ CP#5502 mov pc, lr @ CP#6503+#endif504 mov pc, lr @ CP#7505 mov pc, lr @ CP#8506 mov pc, lr @ CP#9
+36
arch/arm/kernel/ptrace.c
···634635#endif63600000000000000000000000000637long arch_ptrace(struct task_struct *child, long request, long addr, long data)638{639 unsigned long tmp;···790 ret = 0;791 child->ptrace_message = data;792 break;0000000000793794 default:795 ret = ptrace_request(child, request, addr, data);
···634635#endif636637+#ifdef CONFIG_CRUNCH638+/*639+ * Get the child Crunch state.640+ */641+static int ptrace_getcrunchregs(struct task_struct *tsk, void __user *ufp)642+{643+ struct thread_info *thread = task_thread_info(tsk);644+645+ crunch_task_disable(thread); /* force it to ram */646+ return copy_to_user(ufp, &thread->crunchstate, CRUNCH_SIZE)647+ ? -EFAULT : 0;648+}649+650+/*651+ * Set the child Crunch state.652+ */653+static int ptrace_setcrunchregs(struct task_struct *tsk, void __user *ufp)654+{655+ struct thread_info *thread = task_thread_info(tsk);656+657+ crunch_task_release(thread); /* force a reload */658+ return copy_from_user(&thread->crunchstate, ufp, CRUNCH_SIZE)659+ ? -EFAULT : 0;660+}661+#endif662+663long arch_ptrace(struct task_struct *child, long request, long addr, long data)664{665 unsigned long tmp;···764 ret = 0;765 child->ptrace_message = data;766 break;767+768+#ifdef CONFIG_CRUNCH769+ case PTRACE_GETCRUNCHREGS:770+ ret = ptrace_getcrunchregs(child, (void __user *)data);771+ break;772+773+ case PTRACE_SETCRUNCHREGS:774+ ret = ptrace_setcrunchregs(child, (void __user *)data);775+ break;776+#endif777778 default:779 ret = ptrace_request(child, request, addr, data);
+39
arch/arm/kernel/signal.c
···132 return ret;133}1340000000000000000000000000000000135#ifdef CONFIG_IWMMXT136137static int preserve_iwmmxt_context(struct iwmmxt_sigframe *frame)···245 err |= !valid_user_regs(regs);246247 aux = (struct aux_sigframe __user *) sf->uc.uc_regspace;0000248#ifdef CONFIG_IWMMXT249 if (err == 0 && test_thread_flag(TIF_USING_IWMMXT))250 err |= restore_iwmmxt_context(&aux->iwmmxt);···368 err |= __copy_to_user(&sf->uc.uc_sigmask, set, sizeof(*set));369370 aux = (struct aux_sigframe __user *) sf->uc.uc_regspace;0000371#ifdef CONFIG_IWMMXT372 if (err == 0 && test_thread_flag(TIF_USING_IWMMXT))373 err |= preserve_iwmmxt_context(&aux->iwmmxt);
···132 return ret;133}134135+#ifdef CONFIG_CRUNCH136+static int preserve_crunch_context(struct crunch_sigframe *frame)137+{138+ char kbuf[sizeof(*frame) + 8];139+ struct crunch_sigframe *kframe;140+141+ /* the crunch context must be 64 bit aligned */142+ kframe = (struct crunch_sigframe *)((unsigned long)(kbuf + 8) & ~7);143+ kframe->magic = CRUNCH_MAGIC;144+ kframe->size = CRUNCH_STORAGE_SIZE;145+ crunch_task_copy(current_thread_info(), &kframe->storage);146+ return __copy_to_user(frame, kframe, sizeof(*frame));147+}148+149+static int restore_crunch_context(struct crunch_sigframe *frame)150+{151+ char kbuf[sizeof(*frame) + 8];152+ struct crunch_sigframe *kframe;153+154+ /* the crunch context must be 64 bit aligned */155+ kframe = (struct crunch_sigframe *)((unsigned long)(kbuf + 8) & ~7);156+ if (__copy_from_user(kframe, frame, sizeof(*frame)))157+ return -1;158+ if (kframe->magic != CRUNCH_MAGIC ||159+ kframe->size != CRUNCH_STORAGE_SIZE)160+ return -1;161+ crunch_task_restore(current_thread_info(), &kframe->storage);162+ return 0;163+}164+#endif165+166#ifdef CONFIG_IWMMXT167168static int preserve_iwmmxt_context(struct iwmmxt_sigframe *frame)···214 err |= !valid_user_regs(regs);215216 aux = (struct aux_sigframe __user *) sf->uc.uc_regspace;217+#ifdef CONFIG_CRUNCH218+ if (err == 0)219+ err |= restore_crunch_context(&aux->crunch);220+#endif221#ifdef CONFIG_IWMMXT222 if (err == 0 && test_thread_flag(TIF_USING_IWMMXT))223 err |= restore_iwmmxt_context(&aux->iwmmxt);···333 err |= __copy_to_user(&sf->uc.uc_sigmask, set, sizeof(*set));334335 aux = (struct aux_sigframe __user *) sf->uc.uc_regspace;336+#ifdef CONFIG_CRUNCH337+ if (err == 0)338+ err |= preserve_crunch_context(&aux->crunch);339+#endif340#ifdef CONFIG_IWMMXT341 if (err == 0 && test_thread_flag(TIF_USING_IWMMXT))342 err |= preserve_iwmmxt_context(&aux->iwmmxt);
···97 b 1007f9899/*100+ * Fixup for LDMDB. Note that this must not be in the fixup section.101 */001021007: ldr r0, =.Lbad103 mov r1, frame104 bl printk105 ldmfd sp!, {r4 - r8, pc}106 .ltorg0107108 .section __ex_table,"a"109 .align 3
+2-2
arch/arm/lib/clear_user.S
···1213 .text1415-/* Prototype: int __arch_clear_user(void *addr, size_t sz)16 * Purpose : clear some user memory17 * Params : addr - user memory address to clear18 * : sz - number of bytes to clear19 * Returns : number of bytes NOT cleared20 */21-ENTRY(__arch_clear_user)22 stmfd sp!, {r1, lr}23 mov r2, #024 cmp r1, #4
···1213 .text1415+/* Prototype: int __clear_user(void *addr, size_t sz)16 * Purpose : clear some user memory17 * Params : addr - user memory address to clear18 * : sz - number of bytes to clear19 * Returns : number of bytes NOT cleared20 */21+ENTRY(__clear_user)22 stmfd sp!, {r1, lr}23 mov r2, #024 cmp r1, #4
···20 * returns the number of characters copied (strlen of copied string),21 * -EFAULT on exception, or "len" if we fill the whole buffer22 */23-ENTRY(__arch_strncpy_from_user)24 mov ip, r1251: subs r2, r2, #126USER( ldrplbt r3, [r1], #1)
···20 * returns the number of characters copied (strlen of copied string),21 * -EFAULT on exception, or "len" if we fill the whole buffer22 */23+ENTRY(__strncpy_from_user)24 mov ip, r1251: subs r2, r2, #126USER( ldrplbt r3, [r1], #1)
+2-2
arch/arm/lib/strnlen_user.S
···14 .text15 .align 51617-/* Prototype: unsigned long __arch_strnlen_user(const char *str, long n)18 * Purpose : get length of a string in user memory19 * Params : str - address of string in user memory20 * Returns : length of string *including terminator*21 * or zero on exception, or n + 1 if too long22 */23-ENTRY(__arch_strnlen_user)24 mov r2, r0251:26USER( ldrbt r3, [r0], #1)
···14 .text15 .align 51617+/* Prototype: unsigned long __strnlen_user(const char *str, long n)18 * Purpose : get length of a string in user memory19 * Params : str - address of string in user memory20 * Returns : length of string *including terminator*21 * or zero on exception, or n + 1 if too long22 */23+ENTRY(__strnlen_user)24 mov r2, r0251:26USER( ldrbt r3, [r0], #1)
+4-4
arch/arm/lib/uaccess.S
···1920#define PAGE_SHIFT 122122-/* Prototype: int __arch_copy_to_user(void *to, const char *from, size_t n)23 * Purpose : copy a block to user memory from kernel memory24 * Params : to - user memory25 * : from - kernel memory···39 sub r2, r2, ip40 b .Lc2u_dest_aligned4142-ENTRY(__arch_copy_to_user)43 stmfd sp!, {r2, r4 - r7, lr}44 cmp r2, #445 blt .Lc2u_not_enough···2839001: ldmfd sp!, {r0, r4 - r7, pc}284 .previous285286-/* Prototype: unsigned long __arch_copy_from_user(void *to,const void *from,unsigned long n);287 * Purpose : copy a block from user memory to kernel memory288 * Params : to - kernel memory289 * : from - user memory···302 sub r2, r2, ip303 b .Lcfu_dest_aligned304305-ENTRY(__arch_copy_from_user)306 stmfd sp!, {r0, r2, r4 - r7, lr}307 cmp r2, #4308 blt .Lcfu_not_enough
···1920#define PAGE_SHIFT 122122+/* Prototype: int __copy_to_user(void *to, const char *from, size_t n)23 * Purpose : copy a block to user memory from kernel memory24 * Params : to - user memory25 * : from - kernel memory···39 sub r2, r2, ip40 b .Lc2u_dest_aligned4142+ENTRY(__copy_to_user)43 stmfd sp!, {r2, r4 - r7, lr}44 cmp r2, #445 blt .Lc2u_not_enough···2839001: ldmfd sp!, {r0, r4 - r7, pc}284 .previous285286+/* Prototype: unsigned long __copy_from_user(void *to,const void *from,unsigned long n);287 * Purpose : copy a block from user memory to kernel memory288 * Params : to - kernel memory289 * : from - user memory···302 sub r2, r2, ip303 b .Lcfu_dest_aligned304305+ENTRY(__copy_from_user)306 stmfd sp!, {r0, r2, r4 - r7, lr}307 cmp r2, #4308 blt .Lcfu_not_enough
···23menu "Cirrus EP93xx Implementation Options"45+config CRUNCH6+ bool "Support for MaverickCrunch"7+ help8+ Enable kernel support for MaverickCrunch.9+10comment "EP93xx Platforms"11+12+config MACH_EDB931513+ bool "Support Cirrus Logic EDB9315"14+ help15+ Say 'Y' here if you want your kernel to support the Cirrus16+ Logic EDB9315 Evaluation Board.1718config MACH_GESBC931219 bool "Support Glomation GESBC-9312-sx"
···8889 if (type == IRQT_PROBE) {90 /* Don't mess with enabled GPIOs using preconfigured edges or91- GPIOs set to alternate function during probe */92- if ((GPIO_IRQ_rising_edge[idx] | GPIO_IRQ_falling_edge[idx]) &93 GPIO_bit(gpio))94 return 0;95 if (GAFR(gpio) & (0x3 << (((gpio) & 0xf)*2)))
···8889 if (type == IRQT_PROBE) {90 /* Don't mess with enabled GPIOs using preconfigured edges or91+ GPIOs set to alternate function or to output during probe */92+ if ((GPIO_IRQ_rising_edge[idx] | GPIO_IRQ_falling_edge[idx] | GPDR(gpio)) &93 GPIO_bit(gpio))94 return 0;95 if (GAFR(gpio) & (0x3 << (((gpio) & 0xf)*2)))
···15 select CPU_32v316 select CPU_CACHE_V317 select CPU_CACHE_VIVT18- select CPU_COPY_V319- select CPU_TLB_V320 help21 The ARM610 is the successor to the ARM3 processor22 and was produced by VLSI Technology Inc.···31 select CPU_32v332 select CPU_CACHE_V333 select CPU_CACHE_VIVT34- select CPU_COPY_V335- select CPU_TLB_V336 help37 A 32-bit RISC microprocessor based on the ARM7 processor core38 designed by Advanced RISC Machines Ltd. The ARM710 is the···50 select CPU_ABRT_LV4T51 select CPU_CACHE_V452 select CPU_CACHE_VIVT53- select CPU_COPY_V4WT54- select CPU_TLB_V4WT55 help56 A 32-bit RISC processor with 8kByte Cache, Write Buffer and57 MMU built around an ARM7TDMI core.···68 select CPU_ABRT_EV4T69 select CPU_CACHE_V4WT70 select CPU_CACHE_VIVT71- select CPU_COPY_V4WB72- select CPU_TLB_V4WBI73 help74 The ARM920T is licensed to be produced by numerous vendors,75 and is used in the Maverick EP9312 and the Samsung S3C2410.···89 select CPU_ABRT_EV4T90 select CPU_CACHE_V4WT91 select CPU_CACHE_VIVT92- select CPU_COPY_V4WB93- select CPU_TLB_V4WBI94 help95 The ARM922T is a version of the ARM920T, but with smaller96 instruction and data caches. It is used in Altera's···108 select CPU_ABRT_EV4T109 select CPU_CACHE_V4WT110 select CPU_CACHE_VIVT111- select CPU_COPY_V4WB112- select CPU_TLB_V4WBI113 help114 The ARM925T is a mix between the ARM920T and ARM926T, but with115 different instruction and data caches. It is used in TI's OMAP···126 select CPU_32v5127 select CPU_ABRT_EV5TJ128 select CPU_CACHE_VIVT129- select CPU_COPY_V4WB130- select CPU_TLB_V4WBI131 help132 This is a variant of the ARM920. It has slightly different133 instruction sequences for cache and TLB operations. Curiously,···144 select CPU_ABRT_EV4T145 select CPU_CACHE_V4WT146 select CPU_CACHE_VIVT147- select CPU_COPY_V4WB148- select CPU_TLB_V4WBI149 help150 The ARM1020 is the 32K cached version of the ARM10 processor,151 with an addition of a floating-point unit.···161 select CPU_ABRT_EV4T162 select CPU_CACHE_V4WT163 select CPU_CACHE_VIVT164- select CPU_COPY_V4WB165- select CPU_TLB_V4WBI166 depends on n167168# ARM1022E···172 select CPU_32v5173 select CPU_ABRT_EV4T174 select CPU_CACHE_VIVT175- select CPU_COPY_V4WB # can probably do better176- select CPU_TLB_V4WBI177 help178 The ARM1022E is an implementation of the ARMv5TE architecture179 based upon the ARM10 integer core with a 16KiB L1 Harvard cache,···189 select CPU_32v5190 select CPU_ABRT_EV5T # But need Jazelle, but EV5TJ ignores bit 10191 select CPU_CACHE_VIVT192- select CPU_COPY_V4WB # can probably do better193- select CPU_TLB_V4WBI194 help195 The ARM1026EJ-S is an implementation of the ARMv5TEJ architecture196 based upon the ARM10 integer core.···207 select CPU_ABRT_EV4208 select CPU_CACHE_V4WB209 select CPU_CACHE_VIVT210- select CPU_COPY_V4WB211- select CPU_TLB_V4WB212 help213 The Intel StrongARM(R) SA-110 is a 32-bit microprocessor and214 is available at five speeds ranging from 100 MHz to 233 MHz.···227 select CPU_ABRT_EV4228 select CPU_CACHE_V4WB229 select CPU_CACHE_VIVT230- select CPU_TLB_V4WB231232# XScale233config CPU_XSCALE···237 select CPU_32v5238 select CPU_ABRT_EV5T239 select CPU_CACHE_VIVT240- select CPU_TLB_V4WBI241242# XScale Core Version 3243config CPU_XSC3···247 select CPU_32v5248 select CPU_ABRT_EV5T249 select CPU_CACHE_VIVT250- select CPU_TLB_V4WBI251 select IO_36252253# ARMv6···258 select CPU_ABRT_EV6259 select CPU_CACHE_V6260 select CPU_CACHE_VIPT261- select CPU_COPY_V6262- select CPU_TLB_V6263264# ARMv6k265config CPU_32v6K···277# This defines the compiler instruction set which depends on the machine type.278config CPU_32v3279 bool280- select TLS_REG_EMUL if SMP281 select NEEDS_SYSCALL_FOR_CMPXCHG if SMP282283config CPU_32v4284 bool285- select TLS_REG_EMUL if SMP286 select NEEDS_SYSCALL_FOR_CMPXCHG if SMP287288config CPU_32v5289 bool290- select TLS_REG_EMUL if SMP291 select NEEDS_SYSCALL_FOR_CMPXCHG if SMP292293config CPU_32v6···334config CPU_CACHE_VIPT335 bool3360337# The copy-page model338config CPU_COPY_V3339 bool···372373config CPU_TLB_V6374 bool00375376#377# CPU supports 36-bit I/O
···15 select CPU_32v316 select CPU_CACHE_V317 select CPU_CACHE_VIVT18+ select CPU_COPY_V3 if MMU19+ select CPU_TLB_V3 if MMU20 help21 The ARM610 is the successor to the ARM3 processor22 and was produced by VLSI Technology Inc.···31 select CPU_32v332 select CPU_CACHE_V333 select CPU_CACHE_VIVT34+ select CPU_COPY_V3 if MMU35+ select CPU_TLB_V3 if MMU36 help37 A 32-bit RISC microprocessor based on the ARM7 processor core38 designed by Advanced RISC Machines Ltd. The ARM710 is the···50 select CPU_ABRT_LV4T51 select CPU_CACHE_V452 select CPU_CACHE_VIVT53+ select CPU_COPY_V4WT if MMU54+ select CPU_TLB_V4WT if MMU55 help56 A 32-bit RISC processor with 8kByte Cache, Write Buffer and57 MMU built around an ARM7TDMI core.···68 select CPU_ABRT_EV4T69 select CPU_CACHE_V4WT70 select CPU_CACHE_VIVT71+ select CPU_COPY_V4WB if MMU72+ select CPU_TLB_V4WBI if MMU73 help74 The ARM920T is licensed to be produced by numerous vendors,75 and is used in the Maverick EP9312 and the Samsung S3C2410.···89 select CPU_ABRT_EV4T90 select CPU_CACHE_V4WT91 select CPU_CACHE_VIVT92+ select CPU_COPY_V4WB if MMU93+ select CPU_TLB_V4WBI if MMU94 help95 The ARM922T is a version of the ARM920T, but with smaller96 instruction and data caches. It is used in Altera's···108 select CPU_ABRT_EV4T109 select CPU_CACHE_V4WT110 select CPU_CACHE_VIVT111+ select CPU_COPY_V4WB if MMU112+ select CPU_TLB_V4WBI if MMU113 help114 The ARM925T is a mix between the ARM920T and ARM926T, but with115 different instruction and data caches. It is used in TI's OMAP···126 select CPU_32v5127 select CPU_ABRT_EV5TJ128 select CPU_CACHE_VIVT129+ select CPU_COPY_V4WB if MMU130+ select CPU_TLB_V4WBI if MMU131 help132 This is a variant of the ARM920. It has slightly different133 instruction sequences for cache and TLB operations. Curiously,···144 select CPU_ABRT_EV4T145 select CPU_CACHE_V4WT146 select CPU_CACHE_VIVT147+ select CPU_COPY_V4WB if MMU148+ select CPU_TLB_V4WBI if MMU149 help150 The ARM1020 is the 32K cached version of the ARM10 processor,151 with an addition of a floating-point unit.···161 select CPU_ABRT_EV4T162 select CPU_CACHE_V4WT163 select CPU_CACHE_VIVT164+ select CPU_COPY_V4WB if MMU165+ select CPU_TLB_V4WBI if MMU166 depends on n167168# ARM1022E···172 select CPU_32v5173 select CPU_ABRT_EV4T174 select CPU_CACHE_VIVT175+ select CPU_COPY_V4WB if MMU # can probably do better176+ select CPU_TLB_V4WBI if MMU177 help178 The ARM1022E is an implementation of the ARMv5TE architecture179 based upon the ARM10 integer core with a 16KiB L1 Harvard cache,···189 select CPU_32v5190 select CPU_ABRT_EV5T # But need Jazelle, but EV5TJ ignores bit 10191 select CPU_CACHE_VIVT192+ select CPU_COPY_V4WB if MMU # can probably do better193+ select CPU_TLB_V4WBI if MMU194 help195 The ARM1026EJ-S is an implementation of the ARMv5TEJ architecture196 based upon the ARM10 integer core.···207 select CPU_ABRT_EV4208 select CPU_CACHE_V4WB209 select CPU_CACHE_VIVT210+ select CPU_COPY_V4WB if MMU211+ select CPU_TLB_V4WB if MMU212 help213 The Intel StrongARM(R) SA-110 is a 32-bit microprocessor and214 is available at five speeds ranging from 100 MHz to 233 MHz.···227 select CPU_ABRT_EV4228 select CPU_CACHE_V4WB229 select CPU_CACHE_VIVT230+ select CPU_TLB_V4WB if MMU231232# XScale233config CPU_XSCALE···237 select CPU_32v5238 select CPU_ABRT_EV5T239 select CPU_CACHE_VIVT240+ select CPU_TLB_V4WBI if MMU241242# XScale Core Version 3243config CPU_XSC3···247 select CPU_32v5248 select CPU_ABRT_EV5T249 select CPU_CACHE_VIVT250+ select CPU_TLB_V4WBI if MMU251 select IO_36252253# ARMv6···258 select CPU_ABRT_EV6259 select CPU_CACHE_V6260 select CPU_CACHE_VIPT261+ select CPU_COPY_V6 if MMU262+ select CPU_TLB_V6 if MMU263264# ARMv6k265config CPU_32v6K···277# This defines the compiler instruction set which depends on the machine type.278config CPU_32v3279 bool280+ select TLS_REG_EMUL if SMP || !MMU281 select NEEDS_SYSCALL_FOR_CMPXCHG if SMP282283config CPU_32v4284 bool285+ select TLS_REG_EMUL if SMP || !MMU286 select NEEDS_SYSCALL_FOR_CMPXCHG if SMP287288config CPU_32v5289 bool290+ select TLS_REG_EMUL if SMP || !MMU291 select NEEDS_SYSCALL_FOR_CMPXCHG if SMP292293config CPU_32v6···334config CPU_CACHE_VIPT335 bool336337+if MMU338# The copy-page model339config CPU_COPY_V3340 bool···371372config CPU_TLB_V6373 bool374+375+endif376377#378# CPU supports 36-bit I/O
+8-2
arch/arm/mm/Makefile
···2# Makefile for the linux arm-specific parts of the memory manager.3#45-obj-y := consistent.o extable.o fault-armv.o \6- fault.o flush.o init.o ioremap.o mmap.o \007 mm-armv.o000089obj-$(CONFIG_MODULES) += proc-syms.o10
···2# Makefile for the linux arm-specific parts of the memory manager.3#45+obj-y := consistent.o extable.o fault.o init.o \6+ iomap.o7+8+obj-$(CONFIG_MMU) += fault-armv.o flush.o ioremap.o mmap.o \9 mm-armv.o10+11+ifneq ($(CONFIG_MMU),y)12+obj-y += nommu.o13+endif1415obj-$(CONFIG_MODULES) += proc-syms.o16
···4 * Copyright (C) 2000 Steve Hill (sjhill@cotw.com)5 * Rob Scott (rscott@mtrob.fdns.net)6 * Copyright (C) 2000 ARM Limited, Deep Blue Solutions Ltd.07 *8 * This program is free software; you can redistribute it and/or modify9 * it under the terms of the GNU General Public License as published by···30 * out of 'proc-arm6,7.S' per RMK discussion31 * 07-25-2000 SJH Added idle function.32 * 08-25-2000 DBS Updated for integration of ARM Ltd version.033 */34#include <linux/linkage.h>35#include <linux/init.h>···77 * the new.78 */79ENTRY(cpu_arm720_switch_mm)080 mov r1, #081 mcr p15, 0, r1, c7, c7, 0 @ invalidate cache82 mcr p15, 0, r0, c2, c0, 0 @ update page table ptr83 mcr p15, 0, r1, c8, c7, 0 @ flush TLB (v4)084 mov pc, lr8586/*···93 */94 .align 595ENTRY(cpu_arm720_set_pte)096 str r1, [r0], #-2048 @ linux version9798 eor r1, r1, #L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_WRITE | L_PTE_DIRTY···112 movne r2, #0113114 str r2, [r0] @ hardware version0115 mov pc, lr116117/*···123ENTRY(cpu_arm720_reset)124 mov ip, #0125 mcr p15, 0, ip, c7, c7, 0 @ invalidate cache0126 mcr p15, 0, ip, c8, c7, 0 @ flush TLB (v4)0127 mrc p15, 0, ip, c1, c0, 0 @ get ctrl register128 bic ip, ip, #0x000f @ ............wcam129 bic ip, ip, #0x2100 @ ..v....s........···138__arm710_setup:139 mov r0, #0140 mcr p15, 0, r0, c7, c7, 0 @ invalidate caches0141 mcr p15, 0, r0, c8, c7, 0 @ flush TLB (v4)0142 mrc p15, 0, r0, c1, c0 @ get control register143 ldr r5, arm710_cr1_clear144 bic r0, r0, r5···166__arm720_setup:167 mov r0, #0168 mcr p15, 0, r0, c7, c7, 0 @ invalidate caches0169 mcr p15, 0, r0, c8, c7, 0 @ flush TLB (v4)0170 mrc p15, 0, r0, c1, c0 @ get control register171 ldr r5, arm720_cr1_clear172 bic r0, r0, r5
···4 * Copyright (C) 2000 Steve Hill (sjhill@cotw.com)5 * Rob Scott (rscott@mtrob.fdns.net)6 * Copyright (C) 2000 ARM Limited, Deep Blue Solutions Ltd.7+ * hacked for non-paged-MM by Hyok S. Choi, 2004.8 *9 * This program is free software; you can redistribute it and/or modify10 * it under the terms of the GNU General Public License as published by···29 * out of 'proc-arm6,7.S' per RMK discussion30 * 07-25-2000 SJH Added idle function.31 * 08-25-2000 DBS Updated for integration of ARM Ltd version.32+ * 04-20-2004 HSC modified for non-paged memory management mode.33 */34#include <linux/linkage.h>35#include <linux/init.h>···75 * the new.76 */77ENTRY(cpu_arm720_switch_mm)78+#ifdef CONFIG_MMU79 mov r1, #080 mcr p15, 0, r1, c7, c7, 0 @ invalidate cache81 mcr p15, 0, r0, c2, c0, 0 @ update page table ptr82 mcr p15, 0, r1, c8, c7, 0 @ flush TLB (v4)83+#endif84 mov pc, lr8586/*···89 */90 .align 591ENTRY(cpu_arm720_set_pte)92+#ifdef CONFIG_MMU93 str r1, [r0], #-2048 @ linux version9495 eor r1, r1, #L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_WRITE | L_PTE_DIRTY···107 movne r2, #0108109 str r2, [r0] @ hardware version110+#endif111 mov pc, lr112113/*···117ENTRY(cpu_arm720_reset)118 mov ip, #0119 mcr p15, 0, ip, c7, c7, 0 @ invalidate cache120+#ifdef CONFIG_MMU121 mcr p15, 0, ip, c8, c7, 0 @ flush TLB (v4)122+#endif123 mrc p15, 0, ip, c1, c0, 0 @ get ctrl register124 bic ip, ip, #0x000f @ ............wcam125 bic ip, ip, #0x2100 @ ..v....s........···130__arm710_setup:131 mov r0, #0132 mcr p15, 0, r0, c7, c7, 0 @ invalidate caches133+#ifdef CONFIG_MMU134 mcr p15, 0, r0, c8, c7, 0 @ flush TLB (v4)135+#endif136 mrc p15, 0, r0, c1, c0 @ get control register137 ldr r5, arm710_cr1_clear138 bic r0, r0, r5···156__arm720_setup:157 mov r0, #0158 mcr p15, 0, r0, c7, c7, 0 @ invalidate caches159+#ifdef CONFIG_MMU160 mcr p15, 0, r0, c8, c7, 0 @ flush TLB (v4)161+#endif162 mrc p15, 0, r0, c1, c0 @ get control register163 ldr r5, arm720_cr1_clear164 bic r0, r0, r5
+9
arch/arm/mm/proc-arm920.S
···3 *4 * Copyright (C) 1999,2000 ARM Limited5 * Copyright (C) 2000 Deep Blue Solutions Ltd.06 *7 * This program is free software; you can redistribute it and/or modify8 * it under the terms of the GNU General Public License as published by···98 mov ip, #099 mcr p15, 0, ip, c7, c7, 0 @ invalidate I,D caches100 mcr p15, 0, ip, c7, c10, 4 @ drain WB0101 mcr p15, 0, ip, c8, c7, 0 @ invalidate I & D TLBs0102 mrc p15, 0, ip, c1, c0, 0 @ ctrl register103 bic ip, ip, #0x000f @ ............wcam104 bic ip, ip, #0x1100 @ ...i...s........···320 */321 .align 5322ENTRY(cpu_arm920_switch_mm)0323 mov ip, #0324#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH325 mcr p15, 0, ip, c7, c6, 0 @ invalidate D cache···341 mcr p15, 0, ip, c7, c10, 4 @ drain WB342 mcr p15, 0, r0, c2, c0, 0 @ load page table pointer343 mcr p15, 0, ip, c8, c7, 0 @ invalidate I & D TLBs0344 mov pc, lr345346/*···351 */352 .align 5353ENTRY(cpu_arm920_set_pte)0354 str r1, [r0], #-2048 @ linux version355356 eor r1, r1, #L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_WRITE | L_PTE_DIRTY···378 mov r0, r0379 mcr p15, 0, r0, c7, c10, 1 @ clean D entry380 mcr p15, 0, r0, c7, c10, 4 @ drain WB0381 mov pc, lr382383 __INIT···388 mov r0, #0389 mcr p15, 0, r0, c7, c7 @ invalidate I,D caches on v4390 mcr p15, 0, r0, c7, c10, 4 @ drain write buffer on v40391 mcr p15, 0, r0, c8, c7 @ invalidate I,D TLBs on v40392 mrc p15, 0, r0, c1, c0 @ get control register v4393 ldr r5, arm920_cr1_clear394 bic r0, r0, r5
···3 *4 * Copyright (C) 1999,2000 ARM Limited5 * Copyright (C) 2000 Deep Blue Solutions Ltd.6+ * hacked for non-paged-MM by Hyok S. Choi, 2003.7 *8 * This program is free software; you can redistribute it and/or modify9 * it under the terms of the GNU General Public License as published by···97 mov ip, #098 mcr p15, 0, ip, c7, c7, 0 @ invalidate I,D caches99 mcr p15, 0, ip, c7, c10, 4 @ drain WB100+#ifdef CONFIG_MMU101 mcr p15, 0, ip, c8, c7, 0 @ invalidate I & D TLBs102+#endif103 mrc p15, 0, ip, c1, c0, 0 @ ctrl register104 bic ip, ip, #0x000f @ ............wcam105 bic ip, ip, #0x1100 @ ...i...s........···317 */318 .align 5319ENTRY(cpu_arm920_switch_mm)320+#ifdef CONFIG_MMU321 mov ip, #0322#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH323 mcr p15, 0, ip, c7, c6, 0 @ invalidate D cache···337 mcr p15, 0, ip, c7, c10, 4 @ drain WB338 mcr p15, 0, r0, c2, c0, 0 @ load page table pointer339 mcr p15, 0, ip, c8, c7, 0 @ invalidate I & D TLBs340+#endif341 mov pc, lr342343/*···346 */347 .align 5348ENTRY(cpu_arm920_set_pte)349+#ifdef CONFIG_MMU350 str r1, [r0], #-2048 @ linux version351352 eor r1, r1, #L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_WRITE | L_PTE_DIRTY···372 mov r0, r0373 mcr p15, 0, r0, c7, c10, 1 @ clean D entry374 mcr p15, 0, r0, c7, c10, 4 @ drain WB375+#endif /* CONFIG_MMU */376 mov pc, lr377378 __INIT···381 mov r0, #0382 mcr p15, 0, r0, c7, c7 @ invalidate I,D caches on v4383 mcr p15, 0, r0, c7, c10, 4 @ drain write buffer on v4384+#ifdef CONFIG_MMU385 mcr p15, 0, r0, c8, c7 @ invalidate I,D TLBs on v4386+#endif387 mrc p15, 0, r0, c1, c0 @ get control register v4388 ldr r5, arm920_cr1_clear389 bic r0, r0, r5
+9
arch/arm/mm/proc-arm922.S
···4 * Copyright (C) 1999,2000 ARM Limited5 * Copyright (C) 2000 Deep Blue Solutions Ltd.6 * Copyright (C) 2001 Altera Corporation07 *8 * This program is free software; you can redistribute it and/or modify9 * it under the terms of the GNU General Public License as published by···100 mov ip, #0101 mcr p15, 0, ip, c7, c7, 0 @ invalidate I,D caches102 mcr p15, 0, ip, c7, c10, 4 @ drain WB0103 mcr p15, 0, ip, c8, c7, 0 @ invalidate I & D TLBs0104 mrc p15, 0, ip, c1, c0, 0 @ ctrl register105 bic ip, ip, #0x000f @ ............wcam106 bic ip, ip, #0x1100 @ ...i...s........···324 */325 .align 5326ENTRY(cpu_arm922_switch_mm)0327 mov ip, #0328#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH329 mcr p15, 0, ip, c7, c6, 0 @ invalidate D cache···345 mcr p15, 0, ip, c7, c10, 4 @ drain WB346 mcr p15, 0, r0, c2, c0, 0 @ load page table pointer347 mcr p15, 0, ip, c8, c7, 0 @ invalidate I & D TLBs0348 mov pc, lr349350/*···355 */356 .align 5357ENTRY(cpu_arm922_set_pte)0358 str r1, [r0], #-2048 @ linux version359360 eor r1, r1, #L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_WRITE | L_PTE_DIRTY···382 mov r0, r0383 mcr p15, 0, r0, c7, c10, 1 @ clean D entry384 mcr p15, 0, r0, c7, c10, 4 @ drain WB0385 mov pc, lr386387 __INIT···392 mov r0, #0393 mcr p15, 0, r0, c7, c7 @ invalidate I,D caches on v4394 mcr p15, 0, r0, c7, c10, 4 @ drain write buffer on v40395 mcr p15, 0, r0, c8, c7 @ invalidate I,D TLBs on v40396 mrc p15, 0, r0, c1, c0 @ get control register v4397 ldr r5, arm922_cr1_clear398 bic r0, r0, r5
···4 * Copyright (C) 1999,2000 ARM Limited5 * Copyright (C) 2000 Deep Blue Solutions Ltd.6 * Copyright (C) 2001 Altera Corporation7+ * hacked for non-paged-MM by Hyok S. Choi, 2003.8 *9 * This program is free software; you can redistribute it and/or modify10 * it under the terms of the GNU General Public License as published by···99 mov ip, #0100 mcr p15, 0, ip, c7, c7, 0 @ invalidate I,D caches101 mcr p15, 0, ip, c7, c10, 4 @ drain WB102+#ifdef CONFIG_MMU103 mcr p15, 0, ip, c8, c7, 0 @ invalidate I & D TLBs104+#endif105 mrc p15, 0, ip, c1, c0, 0 @ ctrl register106 bic ip, ip, #0x000f @ ............wcam107 bic ip, ip, #0x1100 @ ...i...s........···321 */322 .align 5323ENTRY(cpu_arm922_switch_mm)324+#ifdef CONFIG_MMU325 mov ip, #0326#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH327 mcr p15, 0, ip, c7, c6, 0 @ invalidate D cache···341 mcr p15, 0, ip, c7, c10, 4 @ drain WB342 mcr p15, 0, r0, c2, c0, 0 @ load page table pointer343 mcr p15, 0, ip, c8, c7, 0 @ invalidate I & D TLBs344+#endif345 mov pc, lr346347/*···350 */351 .align 5352ENTRY(cpu_arm922_set_pte)353+#ifdef CONFIG_MMU354 str r1, [r0], #-2048 @ linux version355356 eor r1, r1, #L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_WRITE | L_PTE_DIRTY···376 mov r0, r0377 mcr p15, 0, r0, c7, c10, 1 @ clean D entry378 mcr p15, 0, r0, c7, c10, 4 @ drain WB379+#endif /* CONFIG_MMU */380 mov pc, lr381382 __INIT···385 mov r0, #0386 mcr p15, 0, r0, c7, c7 @ invalidate I,D caches on v4387 mcr p15, 0, r0, c7, c10, 4 @ drain write buffer on v4388+#ifdef CONFIG_MMU389 mcr p15, 0, r0, c8, c7 @ invalidate I,D TLBs on v4390+#endif391 mrc p15, 0, r0, c1, c0 @ get control register v4392 ldr r5, arm922_cr1_clear393 bic r0, r0, r5
+10
arch/arm/mm/proc-arm925.S
···9 * Update for Linux-2.6 and cache flush improvements10 * Copyright (C) 2004 Nokia Corporation by Tony Lindgren <tony@atomide.com>11 *0012 * This program is free software; you can redistribute it and/or modify13 * it under the terms of the GNU General Public License as published by14 * the Free Software Foundation; either version 2 of the License, or···124 mov ip, #0125 mcr p15, 0, ip, c7, c7, 0 @ invalidate I,D caches126 mcr p15, 0, ip, c7, c10, 4 @ drain WB0127 mcr p15, 0, ip, c8, c7, 0 @ invalidate I & D TLBs0128 mrc p15, 0, ip, c1, c0, 0 @ ctrl register129 bic ip, ip, #0x000f @ ............wcam130 bic ip, ip, #0x1100 @ ...i...s........···373 */374 .align 5375ENTRY(cpu_arm925_switch_mm)0376 mov ip, #0377#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH378 mcr p15, 0, ip, c7, c6, 0 @ invalidate D cache···388 mcr p15, 0, ip, c7, c10, 4 @ drain WB389 mcr p15, 0, r0, c2, c0, 0 @ load page table pointer390 mcr p15, 0, ip, c8, c7, 0 @ invalidate I & D TLBs0391 mov pc, lr392393/*···398 */399 .align 5400ENTRY(cpu_arm925_set_pte)0401 str r1, [r0], #-2048 @ linux version402403 eor r1, r1, #L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_WRITE | L_PTE_DIRTY···427 mcr p15, 0, r0, c7, c10, 1 @ clean D entry428#endif429 mcr p15, 0, r0, c7, c10, 4 @ drain WB0430 mov pc, lr431432 __INIT···446 mov r0, #0447 mcr p15, 0, r0, c7, c7 @ invalidate I,D caches on v4448 mcr p15, 0, r0, c7, c10, 4 @ drain write buffer on v40449 mcr p15, 0, r0, c8, c7 @ invalidate I,D TLBs on v40450451#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH452 mov r0, #4 @ disable write-back on caches explicitly
···9 * Update for Linux-2.6 and cache flush improvements10 * Copyright (C) 2004 Nokia Corporation by Tony Lindgren <tony@atomide.com>11 *12+ * hacked for non-paged-MM by Hyok S. Choi, 2004.13+ *14 * This program is free software; you can redistribute it and/or modify15 * it under the terms of the GNU General Public License as published by16 * the Free Software Foundation; either version 2 of the License, or···122 mov ip, #0123 mcr p15, 0, ip, c7, c7, 0 @ invalidate I,D caches124 mcr p15, 0, ip, c7, c10, 4 @ drain WB125+#ifdef CONFIG_MMU126 mcr p15, 0, ip, c8, c7, 0 @ invalidate I & D TLBs127+#endif128 mrc p15, 0, ip, c1, c0, 0 @ ctrl register129 bic ip, ip, #0x000f @ ............wcam130 bic ip, ip, #0x1100 @ ...i...s........···369 */370 .align 5371ENTRY(cpu_arm925_switch_mm)372+#ifdef CONFIG_MMU373 mov ip, #0374#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH375 mcr p15, 0, ip, c7, c6, 0 @ invalidate D cache···383 mcr p15, 0, ip, c7, c10, 4 @ drain WB384 mcr p15, 0, r0, c2, c0, 0 @ load page table pointer385 mcr p15, 0, ip, c8, c7, 0 @ invalidate I & D TLBs386+#endif387 mov pc, lr388389/*···392 */393 .align 5394ENTRY(cpu_arm925_set_pte)395+#ifdef CONFIG_MMU396 str r1, [r0], #-2048 @ linux version397398 eor r1, r1, #L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_WRITE | L_PTE_DIRTY···420 mcr p15, 0, r0, c7, c10, 1 @ clean D entry421#endif422 mcr p15, 0, r0, c7, c10, 4 @ drain WB423+#endif /* CONFIG_MMU */424 mov pc, lr425426 __INIT···438 mov r0, #0439 mcr p15, 0, r0, c7, c7 @ invalidate I,D caches on v4440 mcr p15, 0, r0, c7, c10, 4 @ drain write buffer on v4441+#ifdef CONFIG_MMU442 mcr p15, 0, r0, c8, c7 @ invalidate I,D TLBs on v4443+#endif444445#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH446 mov r0, #4 @ disable write-back on caches explicitly
+9
arch/arm/mm/proc-arm926.S
···3 *4 * Copyright (C) 1999-2001 ARM Limited5 * Copyright (C) 2000 Deep Blue Solutions Ltd.06 *7 * This program is free software; you can redistribute it and/or modify8 * it under the terms of the GNU General Public License as published by···86 mov ip, #087 mcr p15, 0, ip, c7, c7, 0 @ invalidate I,D caches88 mcr p15, 0, ip, c7, c10, 4 @ drain WB089 mcr p15, 0, ip, c8, c7, 0 @ invalidate I & D TLBs090 mrc p15, 0, ip, c1, c0, 0 @ ctrl register91 bic ip, ip, #0x000f @ ............wcam92 bic ip, ip, #0x1100 @ ...i...s........···332 */333 .align 5334ENTRY(cpu_arm926_switch_mm)0335 mov ip, #0336#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH337 mcr p15, 0, ip, c7, c6, 0 @ invalidate D cache···345 mcr p15, 0, ip, c7, c10, 4 @ drain WB346 mcr p15, 0, r0, c2, c0, 0 @ load page table pointer347 mcr p15, 0, ip, c8, c7, 0 @ invalidate I & D TLBs0348 mov pc, lr349350/*···355 */356 .align 5357ENTRY(cpu_arm926_set_pte)0358 str r1, [r0], #-2048 @ linux version359360 eor r1, r1, #L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_WRITE | L_PTE_DIRTY···384 mcr p15, 0, r0, c7, c10, 1 @ clean D entry385#endif386 mcr p15, 0, r0, c7, c10, 4 @ drain WB0387 mov pc, lr388389 __INIT···394 mov r0, #0395 mcr p15, 0, r0, c7, c7 @ invalidate I,D caches on v4396 mcr p15, 0, r0, c7, c10, 4 @ drain write buffer on v40397 mcr p15, 0, r0, c8, c7 @ invalidate I,D TLBs on v40398399400#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
···3 *4 * Copyright (C) 1999-2001 ARM Limited5 * Copyright (C) 2000 Deep Blue Solutions Ltd.6+ * hacked for non-paged-MM by Hyok S. Choi, 2003.7 *8 * This program is free software; you can redistribute it and/or modify9 * it under the terms of the GNU General Public License as published by···85 mov ip, #086 mcr p15, 0, ip, c7, c7, 0 @ invalidate I,D caches87 mcr p15, 0, ip, c7, c10, 4 @ drain WB88+#ifdef CONFIG_MMU89 mcr p15, 0, ip, c8, c7, 0 @ invalidate I & D TLBs90+#endif91 mrc p15, 0, ip, c1, c0, 0 @ ctrl register92 bic ip, ip, #0x000f @ ............wcam93 bic ip, ip, #0x1100 @ ...i...s........···329 */330 .align 5331ENTRY(cpu_arm926_switch_mm)332+#ifdef CONFIG_MMU333 mov ip, #0334#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH335 mcr p15, 0, ip, c7, c6, 0 @ invalidate D cache···341 mcr p15, 0, ip, c7, c10, 4 @ drain WB342 mcr p15, 0, r0, c2, c0, 0 @ load page table pointer343 mcr p15, 0, ip, c8, c7, 0 @ invalidate I & D TLBs344+#endif345 mov pc, lr346347/*···350 */351 .align 5352ENTRY(cpu_arm926_set_pte)353+#ifdef CONFIG_MMU354 str r1, [r0], #-2048 @ linux version355356 eor r1, r1, #L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_WRITE | L_PTE_DIRTY···378 mcr p15, 0, r0, c7, c10, 1 @ clean D entry379#endif380 mcr p15, 0, r0, c7, c10, 4 @ drain WB381+#endif382 mov pc, lr383384 __INIT···387 mov r0, #0388 mcr p15, 0, r0, c7, c7 @ invalidate I,D caches on v4389 mcr p15, 0, r0, c7, c10, 4 @ drain write buffer on v4390+#ifdef CONFIG_MMU391 mcr p15, 0, r0, c8, c7 @ invalidate I,D TLBs on v4392+#endif393394395#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
+11
arch/arm/mm/proc-sa110.S
···2 * linux/arch/arm/mm/proc-sa110.S3 *4 * Copyright (C) 1997-2002 Russell King05 *6 * This program is free software; you can redistribute it and/or modify7 * it under the terms of the GNU General Public License version 2 as···68 mov ip, #069 mcr p15, 0, ip, c7, c7, 0 @ invalidate I,D caches70 mcr p15, 0, ip, c7, c10, 4 @ drain WB071 mcr p15, 0, ip, c8, c7, 0 @ invalidate I & D TLBs072 mrc p15, 0, ip, c1, c0, 0 @ ctrl register73 bic ip, ip, #0x000f @ ............wcam74 bic ip, ip, #0x1100 @ ...i...s........···133 */134 .align 5135ENTRY(cpu_sa110_switch_mm)0136 str lr, [sp, #-4]!137 bl v4wb_flush_kern_cache_all @ clears IP138 mcr p15, 0, r0, c2, c0, 0 @ load page table pointer139 mcr p15, 0, ip, c8, c7, 0 @ invalidate I & D TLBs140 ldr pc, [sp], #4000141142/*143 * cpu_sa110_set_pte(ptep, pte)···150 */151 .align 5152ENTRY(cpu_sa110_set_pte)0153 str r1, [r0], #-2048 @ linux version154155 eor r1, r1, #L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_WRITE | L_PTE_DIRTY···172 mov r0, r0173 mcr p15, 0, r0, c7, c10, 1 @ clean D entry174 mcr p15, 0, r0, c7, c10, 4 @ drain WB0175 mov pc, lr176177 __INIT···182 mov r10, #0183 mcr p15, 0, r10, c7, c7 @ invalidate I,D caches on v4184 mcr p15, 0, r10, c7, c10, 4 @ drain write buffer on v40185 mcr p15, 0, r10, c8, c7 @ invalidate I,D TLBs on v40186 mrc p15, 0, r0, c1, c0 @ get control register v4187 ldr r5, sa110_cr1_clear188 bic r0, r0, r5
···2 * linux/arch/arm/mm/proc-sa110.S3 *4 * Copyright (C) 1997-2002 Russell King5+ * hacked for non-paged-MM by Hyok S. Choi, 2003.6 *7 * This program is free software; you can redistribute it and/or modify8 * it under the terms of the GNU General Public License version 2 as···67 mov ip, #068 mcr p15, 0, ip, c7, c7, 0 @ invalidate I,D caches69 mcr p15, 0, ip, c7, c10, 4 @ drain WB70+#ifdef CONFIG_MMU71 mcr p15, 0, ip, c8, c7, 0 @ invalidate I & D TLBs72+#endif73 mrc p15, 0, ip, c1, c0, 0 @ ctrl register74 bic ip, ip, #0x000f @ ............wcam75 bic ip, ip, #0x1100 @ ...i...s........···130 */131 .align 5132ENTRY(cpu_sa110_switch_mm)133+#ifdef CONFIG_MMU134 str lr, [sp, #-4]!135 bl v4wb_flush_kern_cache_all @ clears IP136 mcr p15, 0, r0, c2, c0, 0 @ load page table pointer137 mcr p15, 0, ip, c8, c7, 0 @ invalidate I & D TLBs138 ldr pc, [sp], #4139+#else140+ mov pc, lr141+#endif142143/*144 * cpu_sa110_set_pte(ptep, pte)···143 */144 .align 5145ENTRY(cpu_sa110_set_pte)146+#ifdef CONFIG_MMU147 str r1, [r0], #-2048 @ linux version148149 eor r1, r1, #L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_WRITE | L_PTE_DIRTY···164 mov r0, r0165 mcr p15, 0, r0, c7, c10, 1 @ clean D entry166 mcr p15, 0, r0, c7, c10, 4 @ drain WB167+#endif168 mov pc, lr169170 __INIT···173 mov r10, #0174 mcr p15, 0, r10, c7, c7 @ invalidate I,D caches on v4175 mcr p15, 0, r10, c7, c10, 4 @ drain write buffer on v4176+#ifdef CONFIG_MMU177 mcr p15, 0, r10, c8, c7 @ invalidate I,D TLBs on v4178+#endif179 mrc p15, 0, r0, c1, c0 @ get control register v4180 ldr r5, sa110_cr1_clear181 bic r0, r0, r5
+11
arch/arm/mm/proc-sa1100.S
···2 * linux/arch/arm/mm/proc-sa1100.S3 *4 * Copyright (C) 1997-2002 Russell King05 *6 * This program is free software; you can redistribute it and/or modify7 * it under the terms of the GNU General Public License version 2 as···78 mov ip, #079 mcr p15, 0, ip, c7, c7, 0 @ invalidate I,D caches80 mcr p15, 0, ip, c7, c10, 4 @ drain WB081 mcr p15, 0, ip, c8, c7, 0 @ invalidate I & D TLBs082 mrc p15, 0, ip, c1, c0, 0 @ ctrl register83 bic ip, ip, #0x000f @ ............wcam84 bic ip, ip, #0x1100 @ ...i...s........···145 */146 .align 5147ENTRY(cpu_sa1100_switch_mm)0148 str lr, [sp, #-4]!149 bl v4wb_flush_kern_cache_all @ clears IP150 mcr p15, 0, ip, c9, c0, 0 @ invalidate RB151 mcr p15, 0, r0, c2, c0, 0 @ load page table pointer152 mcr p15, 0, ip, c8, c7, 0 @ invalidate I & D TLBs153 ldr pc, [sp], #4000154155/*156 * cpu_sa1100_set_pte(ptep, pte)···163 */164 .align 5165ENTRY(cpu_sa1100_set_pte)0166 str r1, [r0], #-2048 @ linux version167168 eor r1, r1, #L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_WRITE | L_PTE_DIRTY···185 mov r0, r0186 mcr p15, 0, r0, c7, c10, 1 @ clean D entry187 mcr p15, 0, r0, c7, c10, 4 @ drain WB0188 mov pc, lr189190 __INIT···195 mov r0, #0196 mcr p15, 0, r0, c7, c7 @ invalidate I,D caches on v4197 mcr p15, 0, r0, c7, c10, 4 @ drain write buffer on v40198 mcr p15, 0, r0, c8, c7 @ invalidate I,D TLBs on v40199 mrc p15, 0, r0, c1, c0 @ get control register v4200 ldr r5, sa1100_cr1_clear201 bic r0, r0, r5
···2 * linux/arch/arm/mm/proc-sa1100.S3 *4 * Copyright (C) 1997-2002 Russell King5+ * hacked for non-paged-MM by Hyok S. Choi, 2003.6 *7 * This program is free software; you can redistribute it and/or modify8 * it under the terms of the GNU General Public License version 2 as···77 mov ip, #078 mcr p15, 0, ip, c7, c7, 0 @ invalidate I,D caches79 mcr p15, 0, ip, c7, c10, 4 @ drain WB80+#ifdef CONFIG_MMU81 mcr p15, 0, ip, c8, c7, 0 @ invalidate I & D TLBs82+#endif83 mrc p15, 0, ip, c1, c0, 0 @ ctrl register84 bic ip, ip, #0x000f @ ............wcam85 bic ip, ip, #0x1100 @ ...i...s........···142 */143 .align 5144ENTRY(cpu_sa1100_switch_mm)145+#ifdef CONFIG_MMU146 str lr, [sp, #-4]!147 bl v4wb_flush_kern_cache_all @ clears IP148 mcr p15, 0, ip, c9, c0, 0 @ invalidate RB149 mcr p15, 0, r0, c2, c0, 0 @ load page table pointer150 mcr p15, 0, ip, c8, c7, 0 @ invalidate I & D TLBs151 ldr pc, [sp], #4152+#else153+ mov pc, lr154+#endif155156/*157 * cpu_sa1100_set_pte(ptep, pte)···156 */157 .align 5158ENTRY(cpu_sa1100_set_pte)159+#ifdef CONFIG_MMU160 str r1, [r0], #-2048 @ linux version161162 eor r1, r1, #L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_WRITE | L_PTE_DIRTY···177 mov r0, r0178 mcr p15, 0, r0, c7, c10, 1 @ clean D entry179 mcr p15, 0, r0, c7, c10, 4 @ drain WB180+#endif181 mov pc, lr182183 __INIT···186 mov r0, #0187 mcr p15, 0, r0, c7, c7 @ invalidate I,D caches on v4188 mcr p15, 0, r0, c7, c10, 4 @ drain write buffer on v4189+#ifdef CONFIG_MMU190 mcr p15, 0, r0, c8, c7 @ invalidate I,D TLBs on v4191+#endif192 mrc p15, 0, r0, c1, c0 @ get control register v4193 ldr r5, sa1100_cr1_clear194 bic r0, r0, r5
+7
arch/arm/mm/proc-v6.S
···2 * linux/arch/arm/mm/proc-v6.S3 *4 * Copyright (C) 2001 Deep Blue Solutions Ltd.05 *6 * This program is free software; you can redistribute it and/or modify7 * it under the terms of the GNU General Public License version 2 as···89 * - we are not using split page tables90 */91ENTRY(cpu_v6_switch_mm)092 mov r2, #093 ldr r1, [r1, #MM_CONTEXT_ID] @ get mm->context.id94#ifdef CONFIG_SMP···99 mcr p15, 0, r2, c7, c10, 4 @ drain write buffer100 mcr p15, 0, r0, c2, c0, 0 @ set TTB 0101 mcr p15, 0, r1, c13, c0, 1 @ set context ID0102 mov pc, lr103104/*···122 * 1111 0 1 1 r/w r/w123 */124ENTRY(cpu_v6_set_pte)0125 str r1, [r0], #-2048 @ linux version126127 bic r2, r1, #0x000003f0···149150 str r2, [r0]151 mcr p15, 0, r0, c7, c10, 1 @ flush_pte0152 mov pc, lr153154···199 mcr p15, 0, r0, c7, c5, 0 @ invalidate I cache200 mcr p15, 0, r0, c7, c15, 0 @ clean+invalidate cache201 mcr p15, 0, r0, c7, c10, 4 @ drain write buffer0202 mcr p15, 0, r0, c8, c7, 0 @ invalidate I + D TLBs203 mcr p15, 0, r0, c2, c0, 2 @ TTB control register204#ifdef CONFIG_SMP205 orr r4, r4, #TTB_RGN_WBWA|TTB_S @ mark PTWs shared, outer cacheable206#endif207 mcr p15, 0, r4, c2, c0, 1 @ load TTB10208#ifdef CONFIG_VFP209 mrc p15, 0, r0, c1, c0, 2210 orr r0, r0, #(0xf << 20)
···2 * linux/arch/arm/mm/proc-v6.S3 *4 * Copyright (C) 2001 Deep Blue Solutions Ltd.5+ * Modified by Catalin Marinas for noMMU support6 *7 * This program is free software; you can redistribute it and/or modify8 * it under the terms of the GNU General Public License version 2 as···88 * - we are not using split page tables89 */90ENTRY(cpu_v6_switch_mm)91+#ifdef CONFIG_MMU92 mov r2, #093 ldr r1, [r1, #MM_CONTEXT_ID] @ get mm->context.id94#ifdef CONFIG_SMP···97 mcr p15, 0, r2, c7, c10, 4 @ drain write buffer98 mcr p15, 0, r0, c2, c0, 0 @ set TTB 099 mcr p15, 0, r1, c13, c0, 1 @ set context ID100+#endif101 mov pc, lr102103/*···119 * 1111 0 1 1 r/w r/w120 */121ENTRY(cpu_v6_set_pte)122+#ifdef CONFIG_MMU123 str r1, [r0], #-2048 @ linux version124125 bic r2, r1, #0x000003f0···145146 str r2, [r0]147 mcr p15, 0, r0, c7, c10, 1 @ flush_pte148+#endif149 mov pc, lr150151···194 mcr p15, 0, r0, c7, c5, 0 @ invalidate I cache195 mcr p15, 0, r0, c7, c15, 0 @ clean+invalidate cache196 mcr p15, 0, r0, c7, c10, 4 @ drain write buffer197+#ifdef CONFIG_MMU198 mcr p15, 0, r0, c8, c7, 0 @ invalidate I + D TLBs199 mcr p15, 0, r0, c2, c0, 2 @ TTB control register200#ifdef CONFIG_SMP201 orr r4, r4, #TTB_RGN_WBWA|TTB_S @ mark PTWs shared, outer cacheable202#endif203 mcr p15, 0, r4, c2, c0, 1 @ load TTB1204+#endif /* CONFIG_MMU */205#ifdef CONFIG_VFP206 mrc p15, 0, r0, c1, c0, 2207 orr r0, r0, #(0xf << 20)
+6
arch/i386/kernel/irq.c
···60 u32 *isp;61#endif6200000063 irq_enter();64#ifdef CONFIG_DEBUG_STACKOVERFLOW65 /* Debugging check for stack overflow: is there less than 1KB free? */
···60 u32 *isp;61#endif6263+ if (unlikely((unsigned)irq >= NR_IRQS)) {64+ printk(KERN_EMERG "%s: cannot handle IRQ %d\n",65+ __FUNCTION__, irq);66+ BUG();67+ }68+69 irq_enter();70#ifdef CONFIG_DEBUG_STACKOVERFLOW71 /* Debugging check for stack overflow: is there less than 1KB free? */
···998 }9991000 /* Register for future delivery via notify registration */1001- register_cpu_notifier(&palinfo_cpu_notifier);10021003 return 0;1004}
···998 }9991000 /* Register for future delivery via notify registration */1001+ register_hotcpu_notifier(&palinfo_cpu_notifier);10021003 return 0;1004}
+9-3
arch/ia64/sn/kernel/setup.c
···458 * support here so we don't have to listen to failed keyboard probe459 * messages.460 */461- if (version <= 0x0209 && acpi_kbd_controller_present) {462 printk(KERN_INFO "Disabling legacy keyboard support as prom "463 "is too old and doesn't provide FADT\n");464 acpi_kbd_controller_present = 0;···577 int i;578 static int wars_have_been_checked;579580- if (smp_processor_id() == 0 && IS_MEDUSA()) {0581 if (ia64_sn_is_fake_prom())582 sn_prom_type = 2;583 else···598 sn_hub_info->as_shift = sn_hub_info->nasid_shift - 2;599600 /*000000601 * The boot cpu makes this call again after platform initialization is602 * complete.603 */···614 if (ia64_sn_get_prom_feature_set(i, &sn_prom_features[i]) != 0)615 break;616617- cpuid = smp_processor_id();618 cpuphyid = get_sapicid();619620 if (ia64_sn_get_sapic_info(cpuphyid, &nasid, &subnode, &slice))
···458 * support here so we don't have to listen to failed keyboard probe459 * messages.460 */461+ if (is_shub1() && version <= 0x0209 && acpi_kbd_controller_present) {462 printk(KERN_INFO "Disabling legacy keyboard support as prom "463 "is too old and doesn't provide FADT\n");464 acpi_kbd_controller_present = 0;···577 int i;578 static int wars_have_been_checked;579580+ cpuid = smp_processor_id();581+ if (cpuid == 0 && IS_MEDUSA()) {582 if (ia64_sn_is_fake_prom())583 sn_prom_type = 2;584 else···597 sn_hub_info->as_shift = sn_hub_info->nasid_shift - 2;598599 /*600+ * Don't check status. The SAL call is not supported on all PROMs601+ * but a failure is harmless.602+ */603+ (void) ia64_sn_set_cpu_number(cpuid);604+605+ /*606 * The boot cpu makes this call again after platform initialization is607 * complete.608 */···607 if (ia64_sn_get_prom_feature_set(i, &sn_prom_features[i]) != 0)608 break;6090610 cpuphyid = get_sapicid();611612 if (ia64_sn_get_sapic_info(cpuphyid, &nasid, &subnode, &slice))
···540541endchoice542543+comment "ROM configuration"544+545+config ROM546+ bool "Specify ROM linker regions"547+ default n548+ help549+ Define a ROM region for the linker script. This creates a kernel550+ that can be stored in flash, with possibly the text, and data551+ regions being copied out to RAM at startup.552+553+config ROMBASE554+ hex "Address of the base of ROM device"555+ default "0"556+ depends on ROM557+ help558+ Define the address that the ROM region starts at. Some platforms559+ use this to set their chip select region accordingly for the boot560+ device.561+562+config ROMVEC563+ hex "Address of the base of the ROM vectors"564+ default "0"565+ depends on ROM566+ help567+ This is almost always the same as the base of the ROM. Since on all568+ 68000 type varients the vectors are at the base of the boot device569+ on system startup.570+571+config ROMVECSIZE572+ hex "Size of ROM vector region (in bytes)"573+ default "0x400"574+ depends on ROM575+ help576+ Define the size of the vector region in ROM. For most 68000577+ varients this would be 0x400 bytes in size. Set to 0 if you do578+ not want a vector region at the start of the ROM.579+580+config ROMSTART581+ hex "Address of the base of system image in ROM"582+ default "0x400"583+ depends on ROM584+ help585+ Define the start address of the system image in ROM. Commonly this586+ is strait after the ROM vectors.587+588+config ROMSIZE589+ hex "Size of the ROM device"590+ default "0x100000"591+ depends on ROM592+ help593+ Size of the ROM device. On some platforms this is used to setup594+ the chip select that controls the boot ROM device.595+596choice597 prompt "Kernel executes from"598 ---help---
+6-60
arch/m68knommu/kernel/vmlinux.lds.S
···3 *4 * (C) Copyright 2002-2006, Greg Ungerer <gerg@snapgear.com>5 *6- * This ends up looking compilcated, because of the number of7- * address variations for ram and rom/flash layouts. The real8- * work of the linker script is all at the end, and reasonably9- * strait forward.10 */1112#include <linux/config.h>13#include <asm-generic/vmlinux.lds.h>14-15-/*16- * Original Palm pilot (same for Xcopilot).17- * There is really only a rom target for this.18- */19-#ifdef CONFIG_PILOT320-#define ROMVEC_START 0x10c0000021-#define ROMVEC_LENGTH 0x1040022-#define ROM_START 0x10c1040023-#define ROM_LENGTH 0xfec0024-#define ROM_END 0x10d0000025-#define DATA_ADDR CONFIG_KERNELBASE26-#endif27-28-/*29- * Same setup on both the uCsimm and uCdimm.30- */31-#if defined(CONFIG_UCSIMM) || defined(CONFIG_UCDIMM)32-#ifdef CONFIG_RAMKERNEL33-#define ROMVEC_START 0x10c1000034-#define ROMVEC_LENGTH 0x40035-#define ROM_START 0x10c1040036-#define ROM_LENGTH 0x1efc0037-#define ROM_END 0x10e0000038-#endif39-#ifdef CONFIG_ROMKERNEL40-#define ROMVEC_START 0x10c1000041-#define ROMVEC_LENGTH 0x40042-#define ROM_START 0x10c1040043-#define ROM_LENGTH 0x1efc0044-#define ROM_END 0x10e0000045-#endif46-#ifdef CONFIG_HIMEMKERNEL47-#define ROMVEC_START 0x0060000048-#define ROMVEC_LENGTH 0x40049-#define ROM_START 0x0060040050-#define ROM_LENGTH 0x1efc0051-#define ROM_END 0x007f000052-#endif53-#endif54-55-#ifdef CONFIG_UCQUICC56-#define ROMVEC_START 0x0000000057-#define ROMVEC_LENGTH 0x40458-#define ROM_START 0x0000040459-#define ROM_LENGTH 0x1ff6fc60-#define ROM_END 0x0020000061-#endif6263#if defined(CONFIG_RAMKERNEL)64#define RAM_START CONFIG_KERNELBASE···21#if defined(CONFIG_ROMKERNEL) || defined(CONFIG_HIMEMKERNEL)22#define RAM_START CONFIG_RAMBASE23#define RAM_LENGTH CONFIG_RAMSIZE000024#define TEXT rom25#define DATA ram26#define INIT ram···44#ifdef ROM_START45 romvec : ORIGIN = ROMVEC_START, LENGTH = ROMVEC_LENGTH46 rom : ORIGIN = ROM_START, LENGTH = ROM_LENGTH47- erom : ORIGIN = ROM_END, LENGTH = 048#endif49}50···119 . = ALIGN(4) ;120 _etext = . ;121 } > TEXT122-123-#ifdef ROM_END124- . = ROM_END ;125- .erom : {126- __rom_end = . ;127- } > erom128-#endif129130 .data DATA_ADDR : {131 . = ALIGN(4);
···3 *4 * (C) Copyright 2002-2006, Greg Ungerer <gerg@snapgear.com>5 *6+ * This linker script is equiped to build either ROM loaded or RAM7+ * run kernels.008 */910#include <linux/config.h>11#include <asm-generic/vmlinux.lds.h>0000000000000000000000000000000000000000000000001213#if defined(CONFIG_RAMKERNEL)14#define RAM_START CONFIG_KERNELBASE···71#if defined(CONFIG_ROMKERNEL) || defined(CONFIG_HIMEMKERNEL)72#define RAM_START CONFIG_RAMBASE73#define RAM_LENGTH CONFIG_RAMSIZE74+#define ROMVEC_START CONFIG_ROMVEC75+#define ROMVEC_LENGTH CONFIG_ROMVECSIZE76+#define ROM_START CONFIG_ROMSTART77+#define ROM_LENGTH CONFIG_ROMSIZE78#define TEXT rom79#define DATA ram80#define INIT ram···90#ifdef ROM_START91 romvec : ORIGIN = ROMVEC_START, LENGTH = ROMVEC_LENGTH92 rom : ORIGIN = ROM_START, LENGTH = ROM_LENGTH093#endif94}95···166 . = ALIGN(4) ;167 _etext = . ;168 } > TEXT0000000169170 .data DATA_ADDR : {171 . = ALIGN(4);
···1819#include <asm/system.h>20#include <asm/irq.h>21+#include <asm/irqnode.h>22#include <asm/traps.h>23#include <asm/io.h>24#include <asm/machdep.h>···8182/* irq node variables for the 32 (potential) on chip sources */83static irq_node_t int_irq_list[NR_IRQS];00000000000000000008485/*86 * This function should be called during kernel startup to initialize
+37
arch/m68knommu/platform/68328/romvec.S
···0000000000000000000000000000000000000
···1+/*2+ * linux/arch/m68knommu/platform/68328/romvec.S3+ *4+ * This file is subject to the terms and conditions of the GNU General Public5+ * License. See the file COPYING in the main directory of this archive6+ * for more details.7+ *8+ * Copyright 1996 Roman Zippel9+ * Copyright 1999 D. Jeff Dionne <jeff@rt-control.com>10+ * Copyright 2006 Greg Ungerer <gerg@snapgear.com>11+ */12+13+#include <linux/config.h>14+15+.global _start16+.global _buserr17+.global trap18+.global system_call19+20+.section .romvec21+22+e_vectors:23+.long CONFIG_RAMBASE+CONFIG_RAMSIZE-4, _start, buserr, trap24+.long trap, trap, trap, trap25+.long trap, trap, trap, trap26+.long trap, trap, trap, trap27+.long trap, trap, trap, trap28+.long trap, trap, trap, trap29+.long trap, trap, trap, trap30+.long trap, trap, trap, trap31+/* TRAP #0-15 */32+.long system_call, trap, trap, trap33+.long trap, trap, trap, trap34+.long trap, trap, trap, trap35+.long trap, trap, trap, trap36+.long 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,037+
···118 /* high bit used in ret_from_ code */119 unsigned irq = ~regs->orig_rax;120000000121 exit_idle();122 irq_enter();123#ifdef CONFIG_DEBUG_STACKOVERFLOW
···118 /* high bit used in ret_from_ code */119 unsigned irq = ~regs->orig_rax;120121+ if (unlikely(irq >= NR_IRQS)) {122+ printk(KERN_EMERG "%s: cannot handle IRQ %d\n",123+ __FUNCTION__, irq);124+ BUG();125+ }126+127 exit_idle();128 irq_enter();129#ifdef CONFIG_DEBUG_STACKOVERFLOW
···55#include <linux/mutex.h>56#include <linux/kthread.h>57#include <asm/irq.h>58-#ifdef CONFIG_HIGH_RES_TIMERS59-#include <linux/hrtime.h>60-# if defined(schedule_next_int)61-/* Old high-res timer code, do translations. */62-# define get_arch_cycles(a) quick_update_jiffies_sub(a)63-# define arch_cycles_per_jiffy cycles_per_jiffies64-# endif65-static inline void add_usec_to_timer(struct timer_list *t, long v)66-{67- t->arch_cycle_expires += nsec_to_arch_cycle(v * 1000);68- while (t->arch_cycle_expires >= arch_cycles_per_jiffy)69- {70- t->expires++;71- t->arch_cycle_expires -= arch_cycles_per_jiffy;72- }73-}74-#endif75#include <linux/interrupt.h>76#include <linux/rcupdate.h>77#include <linux/ipmi_smi.h>···225{226 return atomic_notifier_chain_register(&xaction_notifier_list, nb);227}228-229-static void si_restart_short_timer(struct smi_info *smi_info);230231static void deliver_recv_msg(struct smi_info *smi_info,232 struct ipmi_smi_msg *msg)···749 && (smi_info->curr_msg == NULL))750 {751 start_next_msg(smi_info);752- si_restart_short_timer(smi_info);753 }754 spin_unlock_irqrestore(&(smi_info->si_lock), flags);755}···813814static int initialized = 0;815816-/* Must be called with interrupts off and with the si_lock held. */817-static void si_restart_short_timer(struct smi_info *smi_info)818-{819-#if defined(CONFIG_HIGH_RES_TIMERS)820- unsigned long flags;821- unsigned long jiffies_now;822- unsigned long seq;823-824- if (del_timer(&(smi_info->si_timer))) {825- /* If we don't delete the timer, then it will go off826- immediately, anyway. So we only process if we827- actually delete the timer. */828-829- do {830- seq = read_seqbegin_irqsave(&xtime_lock, flags);831- jiffies_now = jiffies;832- smi_info->si_timer.expires = jiffies_now;833- smi_info->si_timer.arch_cycle_expires834- = get_arch_cycles(jiffies_now);835- } while (read_seqretry_irqrestore(&xtime_lock, seq, flags));836-837- add_usec_to_timer(&smi_info->si_timer, SI_SHORT_TIMEOUT_USEC);838-839- add_timer(&(smi_info->si_timer));840- spin_lock_irqsave(&smi_info->count_lock, flags);841- smi_info->timeout_restarts++;842- spin_unlock_irqrestore(&smi_info->count_lock, flags);843- }844-#endif845-}846-847static void smi_timeout(unsigned long data)848{849 struct smi_info *smi_info = (struct smi_info *) data;···853 /* If the state machine asks for a short delay, then shorten854 the timer timeout. */855 if (smi_result == SI_SM_CALL_WITH_DELAY) {856-#if defined(CONFIG_HIGH_RES_TIMERS)857- unsigned long seq;858-#endif859 spin_lock_irqsave(&smi_info->count_lock, flags);860 smi_info->short_timeouts++;861 spin_unlock_irqrestore(&smi_info->count_lock, flags);862-#if defined(CONFIG_HIGH_RES_TIMERS)863- do {864- seq = read_seqbegin_irqsave(&xtime_lock, flags);865- smi_info->si_timer.expires = jiffies;866- smi_info->si_timer.arch_cycle_expires867- = get_arch_cycles(smi_info->si_timer.expires);868- } while (read_seqretry_irqrestore(&xtime_lock, seq, flags));869- add_usec_to_timer(&smi_info->si_timer, SI_SHORT_TIMEOUT_USEC);870-#else871 smi_info->si_timer.expires = jiffies + 1;872-#endif873 } else {874 spin_lock_irqsave(&smi_info->count_lock, flags);875 smi_info->long_timeouts++;876 spin_unlock_irqrestore(&smi_info->count_lock, flags);877 smi_info->si_timer.expires = jiffies + SI_TIMEOUT_JIFFIES;878-#if defined(CONFIG_HIGH_RES_TIMERS)879- smi_info->si_timer.arch_cycle_expires = 0;880-#endif881 }882883 do_add_timer:
···55#include <linux/mutex.h>56#include <linux/kthread.h>57#include <asm/irq.h>0000000000000000058#include <linux/interrupt.h>59#include <linux/rcupdate.h>60#include <linux/ipmi_smi.h>···242{243 return atomic_notifier_chain_register(&xaction_notifier_list, nb);244}00245246static void deliver_recv_msg(struct smi_info *smi_info,247 struct ipmi_smi_msg *msg)···768 && (smi_info->curr_msg == NULL))769 {770 start_next_msg(smi_info);0771 }772 spin_unlock_irqrestore(&(smi_info->si_lock), flags);773}···833834static int initialized = 0;8350000000000000000000000000000000836static void smi_timeout(unsigned long data)837{838 struct smi_info *smi_info = (struct smi_info *) data;···904 /* If the state machine asks for a short delay, then shorten905 the timer timeout. */906 if (smi_result == SI_SM_CALL_WITH_DELAY) {000907 spin_lock_irqsave(&smi_info->count_lock, flags);908 smi_info->short_timeouts++;909 spin_unlock_irqrestore(&smi_info->count_lock, flags);000000000910 smi_info->si_timer.expires = jiffies + 1;0911 } else {912 spin_lock_irqsave(&smi_info->count_lock, flags);913 smi_info->long_timeouts++;914 spin_unlock_irqrestore(&smi_info->count_lock, flags);915 smi_info->si_timer.expires = jiffies + SI_TIMEOUT_JIFFIES;000916 }917918 do_add_timer:
+10-8
drivers/char/ipmi/ipmi_watchdog.c
···949 /* Disable the WDT if we are shutting down. */950 ipmi_watchdog_state = WDOG_TIMEOUT_NONE;951 panic_halt_ipmi_set_timeout();952- } else {953 /* Set a long timer to let the reboot happens, but954- reboot if it hangs. */0955 timeout = 120;956 pretimeout = 0;957 ipmi_watchdog_state = WDOG_TIMEOUT_RESET;···974{975 static int panic_event_handled = 0;976977- /* On a panic, if we have a panic timeout, make sure that the thing978- reboots, even if it hangs during that panic. */979- if (watchdog_user && !panic_event_handled) {980- /* Make sure the panic doesn't hang, and make sure we981- do this only once. */00982 panic_event_handled = 1;983984 timeout = 255;985 pretimeout = 0;986- ipmi_watchdog_state = WDOG_TIMEOUT_RESET;987 panic_halt_ipmi_set_timeout();988 }989
···949 /* Disable the WDT if we are shutting down. */950 ipmi_watchdog_state = WDOG_TIMEOUT_NONE;951 panic_halt_ipmi_set_timeout();952+ } else if (ipmi_watchdog_state != WDOG_TIMEOUT_NONE) {953 /* Set a long timer to let the reboot happens, but954+ reboot if it hangs, but only if the watchdog955+ timer was already running. */956 timeout = 120;957 pretimeout = 0;958 ipmi_watchdog_state = WDOG_TIMEOUT_RESET;···973{974 static int panic_event_handled = 0;975976+ /* On a panic, if we have a panic timeout, make sure to extend977+ the watchdog timer to a reasonable value to complete the978+ panic, if the watchdog timer is running. Plus the979+ pretimeout is meaningless at panic time. */980+ if (watchdog_user && !panic_event_handled &&981+ ipmi_watchdog_state != WDOG_TIMEOUT_NONE) {982+ /* Make sure we do this only once. */983 panic_event_handled = 1;984985 timeout = 255;986 pretimeout = 0;0987 panic_halt_ipmi_set_timeout();988 }989
+665-1150
drivers/char/istallion.c
···42#include <linux/devfs_fs_kernel.h>43#include <linux/device.h>44#include <linux/wait.h>04546#include <asm/io.h>47#include <asm/uaccess.h>4849-#ifdef CONFIG_PCI50#include <linux/pci.h>51-#endif5253/*****************************************************************************/54···136137static int stli_nrbrds = ARRAY_SIZE(stli_brdconf);1380000139/*140 * There is some experimental EISA board detection code in this driver.141 * By default it is disabled, but for those that want to try it out,···176177static struct tty_driver *stli_serial;178179-/*180- * We will need to allocate a temporary write buffer for chars that181- * come direct from user space. The problem is that a copy from user182- * space might cause a page fault (typically on a system that is183- * swapping!). All ports will share one buffer - since if the system184- * is already swapping a shared buffer won't make things any worse.185- */186-static char *stli_tmpwritebuf;187188#define STLI_TXBUFSIZE 4096189···414#endif415416static struct pci_device_id istallion_pci_tbl[] = {417- { PCI_VENDOR_ID_STALLION, PCI_DEVICE_ID_ECRA, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },418 { 0 }419};420MODULE_DEVICE_TABLE(pci, istallion_pci_tbl);···677static ssize_t stli_memread(struct file *fp, char __user *buf, size_t count, loff_t *offp);678static ssize_t stli_memwrite(struct file *fp, const char __user *buf, size_t count, loff_t *offp);679static int stli_memioctl(struct inode *ip, struct file *fp, unsigned int cmd, unsigned long arg);680-static void stli_brdpoll(stlibrd_t *brdp, volatile cdkhdr_t *hdrp);681static void stli_poll(unsigned long arg);682static int stli_hostcmd(stlibrd_t *brdp, stliport_t *portp);683static int stli_initopen(stlibrd_t *brdp, stliport_t *portp);···688static int stli_setport(stliport_t *portp);689static int stli_cmdwait(stlibrd_t *brdp, stliport_t *portp, unsigned long cmd, void *arg, int size, int copyback);690static void stli_sendcmd(stlibrd_t *brdp, stliport_t *portp, unsigned long cmd, void *arg, int size, int copyback);691-static void stli_dodelaycmd(stliport_t *portp, volatile cdkctrl_t *cp);0692static void stli_mkasyport(stliport_t *portp, asyport_t *pp, struct termios *tiosp);693static void stli_mkasysigs(asysigs_t *sp, int dtr, int rts);694static long stli_mktiocm(unsigned long sigvalue);···795796static int __init istallion_module_init(void)797{798- unsigned long flags;799-800-#ifdef DEBUG801- printk("init_module()\n");802-#endif803-804- save_flags(flags);805- cli();806 stli_init();807- restore_flags(flags);808-809- return(0);810}811812/*****************************************************************************/···805{806 stlibrd_t *brdp;807 stliport_t *portp;808- unsigned long flags;809 int i, j;810-811-#ifdef DEBUG812- printk("cleanup_module()\n");813-#endif814815 printk(KERN_INFO "Unloading %s: version %s\n", stli_drvtitle,816 stli_drvversion);817818- save_flags(flags);819- cli();820-821-/*822- * Free up all allocated resources used by the ports. This includes823- * memory and interrupts.824- */825 if (stli_timeron) {826 stli_timeron = 0;827- del_timer(&stli_timerlist);828 }829830 i = tty_unregister_driver(stli_serial);831 if (i) {832 printk("STALLION: failed to un-register tty driver, "833 "errno=%d\n", -i);834- restore_flags(flags);835 return;836 }837 put_tty_driver(stli_serial);···836 printk("STALLION: failed to un-register serial memory device, "837 "errno=%d\n", -i);838839- kfree(stli_tmpwritebuf);840 kfree(stli_txcookbuf);841842 for (i = 0; (i < stli_nrbrds); i++) {843- if ((brdp = stli_brds[i]) == (stlibrd_t *) NULL)844 continue;845 for (j = 0; (j < STL_MAXPORTS); j++) {846 portp = brdp->ports[j];847- if (portp != (stliport_t *) NULL) {848- if (portp->tty != (struct tty_struct *) NULL)849 tty_hangup(portp->tty);850 kfree(portp);851 }···854 if (brdp->iosize > 0)855 release_region(brdp->iobase, brdp->iosize);856 kfree(brdp);857- stli_brds[i] = (stlibrd_t *) NULL;858 }859-860- restore_flags(flags);861}862863module_init(istallion_module_init);···869870static void stli_argbrds(void)871{872- stlconf_t conf;873- stlibrd_t *brdp;874- int i;875-876-#ifdef DEBUG877- printk("stli_argbrds()\n");878-#endif879880 for (i = stli_nrbrds; i < ARRAY_SIZE(stli_brdsp); i++) {881 memset(&conf, 0, sizeof(conf));882 if (stli_parsebrd(&conf, stli_brdsp[i]) == 0)883 continue;884- if ((brdp = stli_allocbrd()) == (stlibrd_t *) NULL)885 continue;886 stli_nrbrds = i + 1;887 brdp->brdnr = i;···896897static unsigned long stli_atol(char *str)898{899- unsigned long val;900- int base, c;901- char *sp;902903 val = 0;904 sp = str;···932933static int stli_parsebrd(stlconf_t *confp, char **argp)934{935- char *sp;936- int i;937938-#ifdef DEBUG939- printk("stli_parsebrd(confp=%x,argp=%x)\n", (int) confp, (int) argp);940-#endif941-942- if ((argp[0] == (char *) NULL) || (*argp[0] == 0))943- return(0);944945 for (sp = argp[0], i = 0; ((*sp != 0) && (i < 25)); sp++, i++)946 *sp = TOLOWER(*sp);···951 }952953 confp->brdtype = stli_brdstr[i].type;954- if ((argp[1] != (char *) NULL) && (*argp[1] != 0))955 confp->ioaddr1 = stli_atol(argp[1]);956- if ((argp[2] != (char *) NULL) && (*argp[2] != 0))957 confp->memaddr = stli_atol(argp[2]);958 return(1);959}···964965static int stli_open(struct tty_struct *tty, struct file *filp)966{967- stlibrd_t *brdp;968- stliport_t *portp;969- unsigned int minordev;970- int brdnr, portnr, rc;971-972-#ifdef DEBUG973- printk("stli_open(tty=%x,filp=%x): device=%s\n", (int) tty,974- (int) filp, tty->name);975-#endif976977 minordev = tty->index;978 brdnr = MINOR2BRD(minordev);979 if (brdnr >= stli_nrbrds)980- return(-ENODEV);981 brdp = stli_brds[brdnr];982- if (brdp == (stlibrd_t *) NULL)983- return(-ENODEV);984 if ((brdp->state & BST_STARTED) == 0)985- return(-ENODEV);986 portnr = MINOR2PORT(minordev);987 if ((portnr < 0) || (portnr > brdp->nrports))988- return(-ENODEV);989990 portp = brdp->ports[portnr];991- if (portp == (stliport_t *) NULL)992- return(-ENODEV);993 if (portp->devnr < 1)994- return(-ENODEV);995996997/*···998 if (portp->flags & ASYNC_CLOSING) {999 interruptible_sleep_on(&portp->close_wait);1000 if (portp->flags & ASYNC_HUP_NOTIFY)1001- return(-EAGAIN);1002- return(-ERESTARTSYS);1003 }10041005/*···1015 wait_event_interruptible(portp->raw_wait,1016 !test_bit(ST_INITIALIZING, &portp->state));1017 if (signal_pending(current))1018- return(-ERESTARTSYS);10191020 if ((portp->flags & ASYNC_INITIALIZED) == 0) {1021 set_bit(ST_INITIALIZING, &portp->state);···1026 clear_bit(ST_INITIALIZING, &portp->state);1027 wake_up_interruptible(&portp->raw_wait);1028 if (rc < 0)1029- return(rc);1030 }10311032/*···1038 if (portp->flags & ASYNC_CLOSING) {1039 interruptible_sleep_on(&portp->close_wait);1040 if (portp->flags & ASYNC_HUP_NOTIFY)1041- return(-EAGAIN);1042- return(-ERESTARTSYS);1043 }10441045/*···1049 */1050 if (!(filp->f_flags & O_NONBLOCK)) {1051 if ((rc = stli_waitcarrier(brdp, portp, filp)) != 0)1052- return(rc);1053 }1054 portp->flags |= ASYNC_NORMAL_ACTIVE;1055- return(0);1056}10571058/*****************************************************************************/10591060static void stli_close(struct tty_struct *tty, struct file *filp)1061{1062- stlibrd_t *brdp;1063- stliport_t *portp;1064- unsigned long flags;1065-1066-#ifdef DEBUG1067- printk("stli_close(tty=%x,filp=%x)\n", (int) tty, (int) filp);1068-#endif10691070 portp = tty->driver_data;1071- if (portp == (stliport_t *) NULL)1072 return;10731074- save_flags(flags);1075- cli();1076 if (tty_hung_up_p(filp)) {1077- restore_flags(flags);1078 return;1079 }1080 if ((tty->count == 1) && (portp->refcount != 1))1081 portp->refcount = 1;1082 if (portp->refcount-- > 1) {1083- restore_flags(flags);1084 return;1085 }1086···1090 if (tty == stli_txcooktty)1091 stli_flushchars(tty);1092 tty->closing = 1;001093 if (portp->closing_wait != ASYNC_CLOSING_WAIT_NONE)1094 tty_wait_until_sent(tty, portp->closing_wait);1095···1115 stli_flushbuffer(tty);11161117 tty->closing = 0;1118- portp->tty = (struct tty_struct *) NULL;11191120 if (portp->openwaitcnt) {1121 if (portp->close_delay)···11251126 portp->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING);1127 wake_up_interruptible(&portp->close_wait);1128- restore_flags(flags);1129}11301131/*****************************************************************************/···11391140static int stli_initopen(stlibrd_t *brdp, stliport_t *portp)1141{1142- struct tty_struct *tty;1143- asynotify_t nt;1144- asyport_t aport;1145- int rc;1146-1147-#ifdef DEBUG1148- printk("stli_initopen(brdp=%x,portp=%x)\n", (int) brdp, (int) portp);1149-#endif11501151 if ((rc = stli_rawopen(brdp, portp, 0, 1)) < 0)1152- return(rc);11531154 memset(&nt, 0, sizeof(asynotify_t));1155 nt.data = (DT_TXLOW | DT_TXEMPTY | DT_RXBUSY | DT_RXBREAK);1156 nt.signal = SG_DCD;1157 if ((rc = stli_cmdwait(brdp, portp, A_SETNOTIFY, &nt,1158 sizeof(asynotify_t), 0)) < 0)1159- return(rc);11601161 tty = portp->tty;1162- if (tty == (struct tty_struct *) NULL)1163- return(-ENODEV);1164 stli_mkasyport(portp, &aport, tty->termios);1165 if ((rc = stli_cmdwait(brdp, portp, A_SETPORT, &aport,1166 sizeof(asyport_t), 0)) < 0)1167- return(rc);11681169 set_bit(ST_GETSIGS, &portp->state);1170 if ((rc = stli_cmdwait(brdp, portp, A_GETSIGNALS, &portp->asig,1171 sizeof(asysigs_t), 1)) < 0)1172- return(rc);1173 if (test_and_clear_bit(ST_GETSIGS, &portp->state))1174 portp->sigs = stli_mktiocm(portp->asig.sigvalue);1175 stli_mkasysigs(&portp->asig, 1, 1);1176 if ((rc = stli_cmdwait(brdp, portp, A_SETSIGNALS, &portp->asig,1177 sizeof(asysigs_t), 0)) < 0)1178- return(rc);11791180- return(0);1181}11821183/*****************************************************************************/···11871188static int stli_rawopen(stlibrd_t *brdp, stliport_t *portp, unsigned long arg, int wait)1189{1190- volatile cdkhdr_t *hdrp;1191- volatile cdkctrl_t *cp;1192- volatile unsigned char *bits;1193- unsigned long flags;1194- int rc;1195-1196-#ifdef DEBUG1197- printk("stli_rawopen(brdp=%x,portp=%x,arg=%x,wait=%d)\n",1198- (int) brdp, (int) portp, (int) arg, wait);1199-#endif12001201/*1202 * Send a message to the slave to open this port.1203 */1204- save_flags(flags);1205- cli();12061207/*1208 * Slave is already closing this port. This can happen if a hangup···1206 wait_event_interruptible(portp->raw_wait,1207 !test_bit(ST_CLOSING, &portp->state));1208 if (signal_pending(current)) {1209- restore_flags(flags);1210 return -ERESTARTSYS;1211 }1212···1214 * memory. Once the message is in set the service bits to say that1215 * this port wants service.1216 */01217 EBRDENABLE(brdp);1218- cp = &((volatile cdkasy_t *) EBRDGETMEMPTR(brdp, portp->addr))->ctrl;1219- cp->openarg = arg;1220- cp->open = 1;1221- hdrp = (volatile cdkhdr_t *) EBRDGETMEMPTR(brdp, CDK_CDKADDR);1222- bits = ((volatile unsigned char *) hdrp) + brdp->slaveoffset +1223 portp->portidx;1224- *bits |= portp->portbit;1225 EBRDDISABLE(brdp);12261227 if (wait == 0) {1228- restore_flags(flags);1229- return(0);1230 }12311232/*···1236 */1237 rc = 0;1238 set_bit(ST_OPENING, &portp->state);001239 wait_event_interruptible(portp->raw_wait,1240 !test_bit(ST_OPENING, &portp->state));1241 if (signal_pending(current))1242 rc = -ERESTARTSYS;1243- restore_flags(flags);12441245 if ((rc == 0) && (portp->rc != 0))1246 rc = -EIO;1247- return(rc);1248}12491250/*****************************************************************************/···12581259static int stli_rawclose(stlibrd_t *brdp, stliport_t *portp, unsigned long arg, int wait)1260{1261- volatile cdkhdr_t *hdrp;1262- volatile cdkctrl_t *cp;1263- volatile unsigned char *bits;1264- unsigned long flags;1265- int rc;1266-1267-#ifdef DEBUG1268- printk("stli_rawclose(brdp=%x,portp=%x,arg=%x,wait=%d)\n",1269- (int) brdp, (int) portp, (int) arg, wait);1270-#endif1271-1272- save_flags(flags);1273- cli();12741275/*1276 * Slave is already closing this port. This can happen if a hangup···1272 wait_event_interruptible(portp->raw_wait,1273 !test_bit(ST_CLOSING, &portp->state));1274 if (signal_pending(current)) {1275- restore_flags(flags);1276 return -ERESTARTSYS;1277 }1278 }···1279/*1280 * Write the close command into shared memory.1281 */01282 EBRDENABLE(brdp);1283- cp = &((volatile cdkasy_t *) EBRDGETMEMPTR(brdp, portp->addr))->ctrl;1284- cp->closearg = arg;1285- cp->close = 1;1286- hdrp = (volatile cdkhdr_t *) EBRDGETMEMPTR(brdp, CDK_CDKADDR);1287- bits = ((volatile unsigned char *) hdrp) + brdp->slaveoffset +1288 portp->portidx;1289- *bits |= portp->portbit;1290 EBRDDISABLE(brdp);12911292 set_bit(ST_CLOSING, &portp->state);1293- if (wait == 0) {1294- restore_flags(flags);1295- return(0);1296- }12971298/*1299 * Slave is in action, so now we must wait for the open acknowledgment···1305 !test_bit(ST_CLOSING, &portp->state));1306 if (signal_pending(current))1307 rc = -ERESTARTSYS;1308- restore_flags(flags);13091310 if ((rc == 0) && (portp->rc != 0))1311 rc = -EIO;1312- return(rc);1313}13141315/*****************************************************************************/···13221323static int stli_cmdwait(stlibrd_t *brdp, stliport_t *portp, unsigned long cmd, void *arg, int size, int copyback)1324{1325- unsigned long flags;1326-1327-#ifdef DEBUG1328- printk("stli_cmdwait(brdp=%x,portp=%x,cmd=%x,arg=%x,size=%d,"1329- "copyback=%d)\n", (int) brdp, (int) portp, (int) cmd,1330- (int) arg, size, copyback);1331-#endif1332-1333- save_flags(flags);1334- cli();1335 wait_event_interruptible(portp->raw_wait,1336 !test_bit(ST_CMDING, &portp->state));1337- if (signal_pending(current)) {1338- restore_flags(flags);1339 return -ERESTARTSYS;1340- }13411342 stli_sendcmd(brdp, portp, cmd, arg, size, copyback);13431344 wait_event_interruptible(portp->raw_wait,1345 !test_bit(ST_CMDING, &portp->state));1346- if (signal_pending(current)) {1347- restore_flags(flags);1348 return -ERESTARTSYS;1349- }1350- restore_flags(flags);13511352 if (portp->rc != 0)1353- return(-EIO);1354- return(0);1355}13561357/*****************************************************************************/···13481349static int stli_setport(stliport_t *portp)1350{1351- stlibrd_t *brdp;1352- asyport_t aport;13531354-#ifdef DEBUG1355- printk("stli_setport(portp=%x)\n", (int) portp);1356-#endif1357-1358- if (portp == (stliport_t *) NULL)1359- return(-ENODEV);1360- if (portp->tty == (struct tty_struct *) NULL)1361- return(-ENODEV);1362- if ((portp->brdnr < 0) && (portp->brdnr >= stli_nrbrds))1363- return(-ENODEV);1364 brdp = stli_brds[portp->brdnr];1365- if (brdp == (stlibrd_t *) NULL)1366- return(-ENODEV);13671368 stli_mkasyport(portp, &aport, portp->tty->termios);1369 return(stli_cmdwait(brdp, portp, A_SETPORT, &aport, sizeof(asyport_t), 0));···13741375static int stli_waitcarrier(stlibrd_t *brdp, stliport_t *portp, struct file *filp)1376{1377- unsigned long flags;1378- int rc, doclocal;1379-1380-#ifdef DEBUG1381- printk("stli_waitcarrier(brdp=%x,portp=%x,filp=%x)\n",1382- (int) brdp, (int) portp, (int) filp);1383-#endif13841385 rc = 0;1386 doclocal = 0;···1383 if (portp->tty->termios->c_cflag & CLOCAL)1384 doclocal++;13851386- save_flags(flags);1387- cli();1388 portp->openwaitcnt++;1389 if (! tty_hung_up_p(filp))1390 portp->refcount--;013911392 for (;;) {1393 stli_mkasysigs(&portp->asig, 1, 1);···1413 interruptible_sleep_on(&portp->open_wait);1414 }141501416 if (! tty_hung_up_p(filp))1417 portp->refcount++;1418 portp->openwaitcnt--;1419- restore_flags(flags);14201421- return(rc);1422}14231424/*****************************************************************************/···14321433static int stli_write(struct tty_struct *tty, const unsigned char *buf, int count)1434{1435- volatile cdkasy_t *ap;1436- volatile cdkhdr_t *hdrp;1437- volatile unsigned char *bits;1438- unsigned char *shbuf, *chbuf;1439- stliport_t *portp;1440- stlibrd_t *brdp;1441- unsigned int len, stlen, head, tail, size;1442- unsigned long flags;014431444-#ifdef DEBUG1445- printk("stli_write(tty=%x,buf=%x,count=%d)\n",1446- (int) tty, (int) buf, count);1447-#endif1448-1449- if ((tty == (struct tty_struct *) NULL) ||1450- (stli_tmpwritebuf == (char *) NULL))1451- return(0);1452 if (tty == stli_txcooktty)1453 stli_flushchars(tty);1454 portp = tty->driver_data;1455- if (portp == (stliport_t *) NULL)1456- return(0);1457 if ((portp->brdnr < 0) || (portp->brdnr >= stli_nrbrds))1458- return(0);1459 brdp = stli_brds[portp->brdnr];1460- if (brdp == (stlibrd_t *) NULL)1461- return(0);1462 chbuf = (unsigned char *) buf;14631464/*1465 * All data is now local, shove as much as possible into shared memory.1466 */1467- save_flags(flags);1468- cli();1469 EBRDENABLE(brdp);1470- ap = (volatile cdkasy_t *) EBRDGETMEMPTR(brdp, portp->addr);1471- head = (unsigned int) ap->txq.head;1472- tail = (unsigned int) ap->txq.tail;1473- if (tail != ((unsigned int) ap->txq.tail))1474- tail = (unsigned int) ap->txq.tail;1475 size = portp->txsize;1476 if (head >= tail) {1477 len = size - (head - tail) - 1;···14751476 len = MIN(len, count);1477 count = 0;1478- shbuf = (char *) EBRDGETMEMPTR(brdp, portp->txoffset);14791480 while (len > 0) {1481 stlen = MIN(len, stlen);1482- memcpy((shbuf + head), chbuf, stlen);1483 chbuf += stlen;1484 len -= stlen;1485 count += stlen;···1490 }1491 }14921493- ap = (volatile cdkasy_t *) EBRDGETMEMPTR(brdp, portp->addr);1494- ap->txq.head = head;1495 if (test_bit(ST_TXBUSY, &portp->state)) {1496- if (ap->changed.data & DT_TXEMPTY)1497- ap->changed.data &= ~DT_TXEMPTY;1498 }1499- hdrp = (volatile cdkhdr_t *) EBRDGETMEMPTR(brdp, CDK_CDKADDR);1500- bits = ((volatile unsigned char *) hdrp) + brdp->slaveoffset +1501 portp->portidx;1502- *bits |= portp->portbit;1503 set_bit(ST_TXBUSY, &portp->state);1504 EBRDDISABLE(brdp);1505-1506- restore_flags(flags);15071508 return(count);1509}···15191520static void stli_putchar(struct tty_struct *tty, unsigned char ch)1521{1522-#ifdef DEBUG1523- printk("stli_putchar(tty=%x,ch=%x)\n", (int) tty, (int) ch);1524-#endif1525-1526- if (tty == (struct tty_struct *) NULL)1527- return;1528 if (tty != stli_txcooktty) {1529- if (stli_txcooktty != (struct tty_struct *) NULL)1530 stli_flushchars(stli_txcooktty);1531 stli_txcooktty = tty;1532 }···15401541static void stli_flushchars(struct tty_struct *tty)1542{1543- volatile cdkhdr_t *hdrp;1544- volatile unsigned char *bits;1545- volatile cdkasy_t *ap;1546- struct tty_struct *cooktty;1547- stliport_t *portp;1548- stlibrd_t *brdp;1549- unsigned int len, stlen, head, tail, size, count, cooksize;1550- unsigned char *buf, *shbuf;1551- unsigned long flags;1552-1553-#ifdef DEBUG1554- printk("stli_flushchars(tty=%x)\n", (int) tty);1555-#endif15561557 cooksize = stli_txcooksize;1558 cooktty = stli_txcooktty;1559 stli_txcooksize = 0;1560 stli_txcookrealsize = 0;1561- stli_txcooktty = (struct tty_struct *) NULL;15621563- if (tty == (struct tty_struct *) NULL)1564 return;1565- if (cooktty == (struct tty_struct *) NULL)1566 return;1567 if (tty != cooktty)1568 tty = cooktty;···1567 return;15681569 portp = tty->driver_data;1570- if (portp == (stliport_t *) NULL)1571 return;1572 if ((portp->brdnr < 0) || (portp->brdnr >= stli_nrbrds))1573 return;1574 brdp = stli_brds[portp->brdnr];1575- if (brdp == (stlibrd_t *) NULL)1576 return;15771578- save_flags(flags);1579- cli();1580 EBRDENABLE(brdp);15811582- ap = (volatile cdkasy_t *) EBRDGETMEMPTR(brdp, portp->addr);1583- head = (unsigned int) ap->txq.head;1584- tail = (unsigned int) ap->txq.tail;1585- if (tail != ((unsigned int) ap->txq.tail))1586- tail = (unsigned int) ap->txq.tail;1587 size = portp->txsize;1588 if (head >= tail) {1589 len = size - (head - tail) - 1;···15991600 while (len > 0) {1601 stlen = MIN(len, stlen);1602- memcpy((shbuf + head), buf, stlen);1603 buf += stlen;1604 len -= stlen;1605 count += stlen;···1610 }1611 }16121613- ap = (volatile cdkasy_t *) EBRDGETMEMPTR(brdp, portp->addr);1614- ap->txq.head = head;16151616 if (test_bit(ST_TXBUSY, &portp->state)) {1617- if (ap->changed.data & DT_TXEMPTY)1618- ap->changed.data &= ~DT_TXEMPTY;1619 }1620- hdrp = (volatile cdkhdr_t *) EBRDGETMEMPTR(brdp, CDK_CDKADDR);1621- bits = ((volatile unsigned char *) hdrp) + brdp->slaveoffset +1622 portp->portidx;1623- *bits |= portp->portbit;1624 set_bit(ST_TXBUSY, &portp->state);16251626 EBRDDISABLE(brdp);1627- restore_flags(flags);1628}16291630/*****************************************************************************/16311632static int stli_writeroom(struct tty_struct *tty)1633{1634- volatile cdkasyrq_t *rp;1635- stliport_t *portp;1636- stlibrd_t *brdp;1637- unsigned int head, tail, len;1638- unsigned long flags;16391640-#ifdef DEBUG1641- printk("stli_writeroom(tty=%x)\n", (int) tty);1642-#endif1643-1644- if (tty == (struct tty_struct *) NULL)1645- return(0);1646 if (tty == stli_txcooktty) {1647 if (stli_txcookrealsize != 0) {1648 len = stli_txcookrealsize - stli_txcooksize;1649- return(len);1650 }1651 }16521653 portp = tty->driver_data;1654- if (portp == (stliport_t *) NULL)1655- return(0);1656 if ((portp->brdnr < 0) || (portp->brdnr >= stli_nrbrds))1657- return(0);1658 brdp = stli_brds[portp->brdnr];1659- if (brdp == (stlibrd_t *) NULL)1660- return(0);16611662- save_flags(flags);1663- cli();1664 EBRDENABLE(brdp);1665- rp = &((volatile cdkasy_t *) EBRDGETMEMPTR(brdp, portp->addr))->txq;1666- head = (unsigned int) rp->head;1667- tail = (unsigned int) rp->tail;1668- if (tail != ((unsigned int) rp->tail))1669- tail = (unsigned int) rp->tail;1670 len = (head >= tail) ? (portp->txsize - (head - tail)) : (tail - head);1671 len--;1672 EBRDDISABLE(brdp);1673- restore_flags(flags);16741675 if (tty == stli_txcooktty) {1676 stli_txcookrealsize = len;1677 len -= stli_txcooksize;1678 }1679- return(len);1680}16811682/*****************************************************************************/···16841685static int stli_charsinbuffer(struct tty_struct *tty)1686{1687- volatile cdkasyrq_t *rp;1688- stliport_t *portp;1689- stlibrd_t *brdp;1690- unsigned int head, tail, len;1691- unsigned long flags;16921693-#ifdef DEBUG1694- printk("stli_charsinbuffer(tty=%x)\n", (int) tty);1695-#endif1696-1697- if (tty == (struct tty_struct *) NULL)1698- return(0);1699 if (tty == stli_txcooktty)1700 stli_flushchars(tty);1701 portp = tty->driver_data;1702- if (portp == (stliport_t *) NULL)1703- return(0);1704 if ((portp->brdnr < 0) || (portp->brdnr >= stli_nrbrds))1705- return(0);1706 brdp = stli_brds[portp->brdnr];1707- if (brdp == (stlibrd_t *) NULL)1708- return(0);17091710- save_flags(flags);1711- cli();1712 EBRDENABLE(brdp);1713- rp = &((volatile cdkasy_t *) EBRDGETMEMPTR(brdp, portp->addr))->txq;1714- head = (unsigned int) rp->head;1715- tail = (unsigned int) rp->tail;1716- if (tail != ((unsigned int) rp->tail))1717- tail = (unsigned int) rp->tail;1718 len = (head >= tail) ? (head - tail) : (portp->txsize - (tail - head));1719 if ((len == 0) && test_bit(ST_TXBUSY, &portp->state))1720 len = 1;1721 EBRDDISABLE(brdp);1722- restore_flags(flags);17231724- return(len);1725}17261727/*****************************************************************************/···17251726static int stli_getserial(stliport_t *portp, struct serial_struct __user *sp)1727{1728- struct serial_struct sio;1729- stlibrd_t *brdp;1730-1731-#ifdef DEBUG1732- printk("stli_getserial(portp=%x,sp=%x)\n", (int) portp, (int) sp);1733-#endif17341735 memset(&sio, 0, sizeof(struct serial_struct));1736 sio.type = PORT_UNKNOWN;···1741 sio.hub6 = 0;17421743 brdp = stli_brds[portp->brdnr];1744- if (brdp != (stlibrd_t *) NULL)1745 sio.port = brdp->iobase;17461747 return copy_to_user(sp, &sio, sizeof(struct serial_struct)) ?···17581759static int stli_setserial(stliport_t *portp, struct serial_struct __user *sp)1760{1761- struct serial_struct sio;1762- int rc;1763-1764-#ifdef DEBUG1765- printk("stli_setserial(portp=%p,sp=%p)\n", portp, sp);1766-#endif17671768 if (copy_from_user(&sio, sp, sizeof(struct serial_struct)))1769 return -EFAULT;···1768 (sio.close_delay != portp->close_delay) ||1769 ((sio.flags & ~ASYNC_USR_MASK) !=1770 (portp->flags & ~ASYNC_USR_MASK)))1771- return(-EPERM);1772 } 17731774 portp->flags = (portp->flags & ~ASYNC_USR_MASK) |···1779 portp->custom_divisor = sio.custom_divisor;17801781 if ((rc = stli_setport(portp)) < 0)1782- return(rc);1783- return(0);1784}17851786/*****************************************************************************/···1791 stlibrd_t *brdp;1792 int rc;17931794- if (portp == (stliport_t *) NULL)1795- return(-ENODEV);1796- if ((portp->brdnr < 0) || (portp->brdnr >= stli_nrbrds))1797- return(0);1798 brdp = stli_brds[portp->brdnr];1799- if (brdp == (stlibrd_t *) NULL)1800- return(0);1801 if (tty->flags & (1 << TTY_IO_ERROR))1802- return(-EIO);18031804 if ((rc = stli_cmdwait(brdp, portp, A_GETSIGNALS,1805 &portp->asig, sizeof(asysigs_t), 1)) < 0)1806- return(rc);18071808 return stli_mktiocm(portp->asig.sigvalue);1809}···1815 stlibrd_t *brdp;1816 int rts = -1, dtr = -1;18171818- if (portp == (stliport_t *) NULL)1819- return(-ENODEV);1820- if ((portp->brdnr < 0) || (portp->brdnr >= stli_nrbrds))1821- return(0);1822 brdp = stli_brds[portp->brdnr];1823- if (brdp == (stlibrd_t *) NULL)1824- return(0);1825 if (tty->flags & (1 << TTY_IO_ERROR))1826- return(-EIO);18271828 if (set & TIOCM_RTS)1829 rts = 1;···18421843static int stli_ioctl(struct tty_struct *tty, struct file *file, unsigned int cmd, unsigned long arg)1844{1845- stliport_t *portp;1846- stlibrd_t *brdp;1847- unsigned int ival;1848- int rc;1849 void __user *argp = (void __user *)arg;18501851-#ifdef DEBUG1852- printk("stli_ioctl(tty=%x,file=%x,cmd=%x,arg=%x)\n",1853- (int) tty, (int) file, cmd, (int) arg);1854-#endif1855-1856- if (tty == (struct tty_struct *) NULL)1857- return(-ENODEV);1858 portp = tty->driver_data;1859- if (portp == (stliport_t *) NULL)1860- return(-ENODEV);1861- if ((portp->brdnr < 0) || (portp->brdnr >= stli_nrbrds))1862- return(0);1863 brdp = stli_brds[portp->brdnr];1864- if (brdp == (stlibrd_t *) NULL)1865- return(0);18661867 if ((cmd != TIOCGSERIAL) && (cmd != TIOCSSERIAL) &&1868 (cmd != COM_GETPORTSTATS) && (cmd != COM_CLRPORTSTATS)) {1869 if (tty->flags & (1 << TTY_IO_ERROR))1870- return(-EIO);1871 }18721873 rc = 0;···1907 break;1908 }19091910- return(rc);1911}19121913/*****************************************************************************/···19191920static void stli_settermios(struct tty_struct *tty, struct termios *old)1921{1922- stliport_t *portp;1923- stlibrd_t *brdp;1924- struct termios *tiosp;1925- asyport_t aport;19261927-#ifdef DEBUG1928- printk("stli_settermios(tty=%x,old=%x)\n", (int) tty, (int) old);1929-#endif1930-1931- if (tty == (struct tty_struct *) NULL)1932 return;1933 portp = tty->driver_data;1934- if (portp == (stliport_t *) NULL)1935 return;1936- if ((portp->brdnr < 0) || (portp->brdnr >= stli_nrbrds))1937 return;1938 brdp = stli_brds[portp->brdnr];1939- if (brdp == (stlibrd_t *) NULL)1940 return;19411942 tiosp = tty->termios;···19651966static void stli_throttle(struct tty_struct *tty)1967{1968- stliport_t *portp;1969-1970-#ifdef DEBUG1971- printk("stli_throttle(tty=%x)\n", (int) tty);1972-#endif1973-1974- if (tty == (struct tty_struct *) NULL)1975 return;1976- portp = tty->driver_data;1977- if (portp == (stliport_t *) NULL)1978- return;1979-1980 set_bit(ST_RXSTOP, &portp->state);1981}1982···19811982static void stli_unthrottle(struct tty_struct *tty)1983{1984- stliport_t *portp;1985-1986-#ifdef DEBUG1987- printk("stli_unthrottle(tty=%x)\n", (int) tty);1988-#endif1989-1990- if (tty == (struct tty_struct *) NULL)1991 return;1992- portp = tty->driver_data;1993- if (portp == (stliport_t *) NULL)1994- return;1995-1996 clear_bit(ST_RXSTOP, &portp->state);1997}19981999/*****************************************************************************/20002001/*2002- * Stop the transmitter. Basically to do this we will just turn TX2003- * interrupts off.2004 */20052006static void stli_stop(struct tty_struct *tty)2007{2008- stlibrd_t *brdp;2009- stliport_t *portp;2010- asyctrl_t actrl;2011-2012-#ifdef DEBUG2013- printk("stli_stop(tty=%x)\n", (int) tty);2014-#endif2015-2016- if (tty == (struct tty_struct *) NULL)2017- return;2018- portp = tty->driver_data;2019- if (portp == (stliport_t *) NULL)2020- return;2021- if ((portp->brdnr < 0) || (portp->brdnr >= stli_nrbrds))2022- return;2023- brdp = stli_brds[portp->brdnr];2024- if (brdp == (stlibrd_t *) NULL)2025- return;2026-2027- memset(&actrl, 0, sizeof(asyctrl_t));2028- actrl.txctrl = CT_STOPFLOW;2029-#if 02030- stli_cmdwait(brdp, portp, A_PORTCTRL, &actrl, sizeof(asyctrl_t), 0);2031-#endif2032}20332034/*****************************************************************************/20352036/*2037- * Start the transmitter again. Just turn TX interrupts back on.2038 */20392040static void stli_start(struct tty_struct *tty)2041{2042- stliport_t *portp;2043- stlibrd_t *brdp;2044- asyctrl_t actrl;2045-2046-#ifdef DEBUG2047- printk("stli_start(tty=%x)\n", (int) tty);2048-#endif2049-2050- if (tty == (struct tty_struct *) NULL)2051- return;2052- portp = tty->driver_data;2053- if (portp == (stliport_t *) NULL)2054- return;2055- if ((portp->brdnr < 0) || (portp->brdnr >= stli_nrbrds))2056- return;2057- brdp = stli_brds[portp->brdnr];2058- if (brdp == (stlibrd_t *) NULL)2059- return;2060-2061- memset(&actrl, 0, sizeof(asyctrl_t));2062- actrl.txctrl = CT_STARTFLOW;2063-#if 02064- stli_cmdwait(brdp, portp, A_PORTCTRL, &actrl, sizeof(asyctrl_t), 0);2065-#endif2066}20672068/*****************************************************************************/···20202021static void stli_dohangup(void *arg)2022{2023- stliport_t *portp;2024-2025-#ifdef DEBUG2026- printk(KERN_DEBUG "stli_dohangup(portp=%x)\n", (int) arg);2027-#endif2028-2029- /*2030- * FIXME: There's a module removal race here: tty_hangup2031- * calls schedule_work which will call into this2032- * driver later.2033- */2034- portp = (stliport_t *) arg;2035- if (portp != (stliport_t *) NULL) {2036- if (portp->tty != (struct tty_struct *) NULL) {2037- tty_hangup(portp->tty);2038- }2039 }2040}2041···20372038static void stli_hangup(struct tty_struct *tty)2039{2040- stliport_t *portp;2041- stlibrd_t *brdp;2042- unsigned long flags;20432044-#ifdef DEBUG2045- printk(KERN_DEBUG "stli_hangup(tty=%x)\n", (int) tty);2046-#endif2047-2048- if (tty == (struct tty_struct *) NULL)2049- return;2050 portp = tty->driver_data;2051- if (portp == (stliport_t *) NULL)2052 return;2053- if ((portp->brdnr < 0) || (portp->brdnr >= stli_nrbrds))2054 return;2055 brdp = stli_brds[portp->brdnr];2056- if (brdp == (stlibrd_t *) NULL)2057 return;20582059 portp->flags &= ~ASYNC_INITIALIZED;20602061- save_flags(flags);2062- cli();2063- if (! test_bit(ST_CLOSING, &portp->state))2064 stli_rawclose(brdp, portp, 0, 0);002065 if (tty->termios->c_cflag & HUPCL) {2066 stli_mkasysigs(&portp->asig, 0, 0);2067 if (test_bit(ST_CMDING, &portp->state)) {···2067 &portp->asig, sizeof(asysigs_t), 0);2068 }2069 }2070- restore_flags(flags);20712072 clear_bit(ST_TXBUSY, &portp->state);2073 clear_bit(ST_RXSTOP, &portp->state);2074 set_bit(TTY_IO_ERROR, &tty->flags);2075- portp->tty = (struct tty_struct *) NULL;2076 portp->flags &= ~ASYNC_NORMAL_ACTIVE;2077 portp->refcount = 0;002078 wake_up_interruptible(&portp->open_wait);2079}2080···20902091static void stli_flushbuffer(struct tty_struct *tty)2092{2093- stliport_t *portp;2094- stlibrd_t *brdp;2095- unsigned long ftype, flags;20962097-#ifdef DEBUG2098- printk(KERN_DEBUG "stli_flushbuffer(tty=%x)\n", (int) tty);2099-#endif2100-2101- if (tty == (struct tty_struct *) NULL)2102- return;2103 portp = tty->driver_data;2104- if (portp == (stliport_t *) NULL)2105 return;2106- if ((portp->brdnr < 0) || (portp->brdnr >= stli_nrbrds))2107 return;2108 brdp = stli_brds[portp->brdnr];2109- if (brdp == (stlibrd_t *) NULL)2110 return;21112112- save_flags(flags);2113- cli();2114 if (tty == stli_txcooktty) {2115- stli_txcooktty = (struct tty_struct *) NULL;2116 stli_txcooksize = 0;2117 stli_txcookrealsize = 0;2118 }···2117 ftype |= FLUSHRX;2118 clear_bit(ST_DOFLUSHRX, &portp->state);2119 }2120- stli_sendcmd(brdp, portp, A_FLUSH, &ftype,2121- sizeof(unsigned long), 0);2122 }2123- restore_flags(flags);2124-2125- wake_up_interruptible(&tty->write_wait);2126- if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&2127- tty->ldisc.write_wakeup)2128- (tty->ldisc.write_wakeup)(tty);2129}21302131/*****************************************************************************/···2130 stlibrd_t *brdp;2131 stliport_t *portp;2132 long arg;2133- /* long savestate, savetime; */21342135-#ifdef DEBUG2136- printk(KERN_DEBUG "stli_breakctl(tty=%x,state=%d)\n", (int) tty, state);2137-#endif2138-2139- if (tty == (struct tty_struct *) NULL)2140- return;2141 portp = tty->driver_data;2142- if (portp == (stliport_t *) NULL)2143 return;2144- if ((portp->brdnr < 0) || (portp->brdnr >= stli_nrbrds))2145 return;2146 brdp = stli_brds[portp->brdnr];2147- if (brdp == (stlibrd_t *) NULL)2148 return;2149-2150-/*2151- * Due to a bug in the tty send_break() code we need to preserve2152- * the current process state and timeout...2153- savetime = current->timeout;2154- savestate = current->state;2155- */21562157 arg = (state == -1) ? BREAKON : BREAKOFF;2158 stli_cmdwait(brdp, portp, A_BREAK, &arg, sizeof(long), 0);2159-2160-/*2161- *2162- current->timeout = savetime;2163- current->state = savestate;2164- */2165}21662167/*****************************************************************************/21682169static void stli_waituntilsent(struct tty_struct *tty, int timeout)2170{2171- stliport_t *portp;2172- unsigned long tend;21732174-#ifdef DEBUG2175- printk(KERN_DEBUG "stli_waituntilsent(tty=%x,timeout=%x)\n", (int) tty, timeout);2176-#endif2177-2178- if (tty == (struct tty_struct *) NULL)2179 return;2180 portp = tty->driver_data;2181- if (portp == (stliport_t *) NULL)2182 return;21832184 if (timeout == 0)···2178 stliport_t *portp;2179 asyctrl_t actrl;21802181-#ifdef DEBUG2182- printk(KERN_DEBUG "stli_sendxchar(tty=%x,ch=%x)\n", (int) tty, ch);2183-#endif2184-2185- if (tty == (struct tty_struct *) NULL)2186- return;2187 portp = tty->driver_data;2188- if (portp == (stliport_t *) NULL)2189 return;2190- if ((portp->brdnr < 0) || (portp->brdnr >= stli_nrbrds))2191 return;2192 brdp = stli_brds[portp->brdnr];2193- if (brdp == (stlibrd_t *) NULL)2194 return;21952196 memset(&actrl, 0, sizeof(asyctrl_t));···2196 actrl.txctrl = CT_SENDCHR;2197 actrl.tximdch = ch;2198 }2199-2200 stli_cmdwait(brdp, portp, A_PORTCTRL, &actrl, sizeof(asyctrl_t), 0);2201}2202···22112212static int stli_portinfo(stlibrd_t *brdp, stliport_t *portp, int portnr, char *pos)2213{2214- char *sp, *uart;2215- int rc, cnt;22162217 rc = stli_portcmdstats(portp);22182219 uart = "UNKNOWN";2220 if (brdp->state & BST_STARTED) {2221 switch (stli_comstats.hwid) {2222- case 0: uart = "2681"; break;2223- case 1: uart = "SC26198"; break;2224- default: uart = "CD1400"; break;2225 }2226 }2227···22722273static int stli_readproc(char *page, char **start, off_t off, int count, int *eof, void *data)2274{2275- stlibrd_t *brdp;2276- stliport_t *portp;2277- int brdnr, portnr, totalport;2278- int curoff, maxoff;2279- char *pos;2280-2281-#ifdef DEBUG2282- printk(KERN_DEBUG "stli_readproc(page=%x,start=%x,off=%x,count=%d,eof=%x,"2283- "data=%x\n", (int) page, (int) start, (int) off, count,2284- (int) eof, (int) data);2285-#endif22862287 pos = page;2288 totalport = 0;···2297 */2298 for (brdnr = 0; (brdnr < stli_nrbrds); brdnr++) {2299 brdp = stli_brds[brdnr];2300- if (brdp == (stlibrd_t *) NULL)2301 continue;2302 if (brdp->state == 0)2303 continue;···2312 for (portnr = 0; (portnr < brdp->nrports); portnr++,2313 totalport++) {2314 portp = brdp->ports[portnr];2315- if (portp == (stliport_t *) NULL)2316 continue;2317 if (off >= (curoff += MAXLINE))2318 continue;···2339 * a poll routine that does not have user context. Therefore you cannot2340 * copy back directly into user space, or to the kernel stack of a2341 * process. This routine does not sleep, so can be called from anywhere.0002342 */23432344-static void stli_sendcmd(stlibrd_t *brdp, stliport_t *portp, unsigned long cmd, void *arg, int size, int copyback)2345{2346- volatile cdkhdr_t *hdrp;2347- volatile cdkctrl_t *cp;2348- volatile unsigned char *bits;2349- unsigned long flags;23502351-#ifdef DEBUG2352- printk(KERN_DEBUG "stli_sendcmd(brdp=%x,portp=%x,cmd=%x,arg=%x,size=%d,"2353- "copyback=%d)\n", (int) brdp, (int) portp, (int) cmd,2354- (int) arg, size, copyback);2355-#endif2356-2357- save_flags(flags);2358- cli();23592360 if (test_bit(ST_CMDING, &portp->state)) {2361 printk(KERN_ERR "STALLION: command already busy, cmd=%x!\n",2362 (int) cmd);2363- restore_flags(flags);2364 return;2365 }23662367 EBRDENABLE(brdp);2368- cp = &((volatile cdkasy_t *) EBRDGETMEMPTR(brdp, portp->addr))->ctrl;2369 if (size > 0) {2370- memcpy((void *) &(cp->args[0]), arg, size);2371 if (copyback) {2372 portp->argp = arg;2373 portp->argsize = size;2374 }2375 }2376- cp->status = 0;2377- cp->cmd = cmd;2378- hdrp = (volatile cdkhdr_t *) EBRDGETMEMPTR(brdp, CDK_CDKADDR);2379- bits = ((volatile unsigned char *) hdrp) + brdp->slaveoffset +2380 portp->portidx;2381- *bits |= portp->portbit;2382 set_bit(ST_CMDING, &portp->state);2383 EBRDDISABLE(brdp);2384- restore_flags(flags);0000000002385}23862387/*****************************************************************************/···24012402static void stli_read(stlibrd_t *brdp, stliport_t *portp)2403{2404- volatile cdkasyrq_t *rp;2405- volatile char *shbuf;2406 struct tty_struct *tty;2407- unsigned int head, tail, size;2408- unsigned int len, stlen;2409-2410-#ifdef DEBUG2411- printk(KERN_DEBUG "stli_read(brdp=%x,portp=%d)\n",2412- (int) brdp, (int) portp);2413-#endif24142415 if (test_bit(ST_RXSTOP, &portp->state))2416 return;2417 tty = portp->tty;2418- if (tty == (struct tty_struct *) NULL)2419 return;24202421- rp = &((volatile cdkasy_t *) EBRDGETMEMPTR(brdp, portp->addr))->rxq;2422- head = (unsigned int) rp->head;2423- if (head != ((unsigned int) rp->head))2424- head = (unsigned int) rp->head;2425- tail = (unsigned int) rp->tail;2426 size = portp->rxsize;2427 if (head >= tail) {2428 len = head - tail;···2428 }24292430 len = tty_buffer_request_room(tty, len);2431- /* FIXME : iomap ? */2432- shbuf = (volatile char *) EBRDGETMEMPTR(brdp, portp->rxoffset);24332434 while (len > 0) {002435 stlen = MIN(len, stlen);2436- tty_insert_flip_string(tty, (char *)(shbuf + tail), stlen);02437 len -= stlen;2438 tail += stlen;2439 if (tail >= size) {···2444 stlen = head;2445 }2446 }2447- rp = &((volatile cdkasy_t *) EBRDGETMEMPTR(brdp, portp->addr))->rxq;2448- rp->tail = tail;24492450 if (head != tail)2451 set_bit(ST_RXING, &portp->state);···2461 * difficult to deal with them here.2462 */24632464-static void stli_dodelaycmd(stliport_t *portp, volatile cdkctrl_t *cp)2465{2466- int cmd;24672468 if (test_bit(ST_DOSIGS, &portp->state)) {2469 if (test_bit(ST_DOFLUSHTX, &portp->state) &&···2478 clear_bit(ST_DOFLUSHTX, &portp->state);2479 clear_bit(ST_DOFLUSHRX, &portp->state);2480 clear_bit(ST_DOSIGS, &portp->state);2481- memcpy((void *) &(cp->args[0]), (void *) &portp->asig,2482 sizeof(asysigs_t));2483- cp->status = 0;2484- cp->cmd = cmd;2485 set_bit(ST_CMDING, &portp->state);2486 } else if (test_bit(ST_DOFLUSHTX, &portp->state) ||2487 test_bit(ST_DOFLUSHRX, &portp->state)) {···2489 cmd |= ((test_bit(ST_DOFLUSHRX, &portp->state)) ? FLUSHRX : 0);2490 clear_bit(ST_DOFLUSHTX, &portp->state);2491 clear_bit(ST_DOFLUSHRX, &portp->state);2492- memcpy((void *) &(cp->args[0]), (void *) &cmd, sizeof(int));2493- cp->status = 0;2494- cp->cmd = A_FLUSH;2495 set_bit(ST_CMDING, &portp->state);2496 }2497}···25112512static int stli_hostcmd(stlibrd_t *brdp, stliport_t *portp)2513{2514- volatile cdkasy_t *ap;2515- volatile cdkctrl_t *cp;2516- struct tty_struct *tty;2517- asynotify_t nt;2518- unsigned long oldsigs;2519- int rc, donerx;25202521-#ifdef DEBUG2522- printk(KERN_DEBUG "stli_hostcmd(brdp=%x,channr=%d)\n",2523- (int) brdp, channr);2524-#endif2525-2526- ap = (volatile cdkasy_t *) EBRDGETMEMPTR(brdp, portp->addr);2527 cp = &ap->ctrl;25282529/*2530 * Check if we are waiting for an open completion message.2531 */2532 if (test_bit(ST_OPENING, &portp->state)) {2533- rc = (int) cp->openarg;2534- if ((cp->open == 0) && (rc != 0)) {2535 if (rc > 0)2536 rc--;2537- cp->openarg = 0;2538 portp->rc = rc;2539 clear_bit(ST_OPENING, &portp->state);2540 wake_up_interruptible(&portp->raw_wait);···2540 * Check if we are waiting for a close completion message.2541 */2542 if (test_bit(ST_CLOSING, &portp->state)) {2543- rc = (int) cp->closearg;2544- if ((cp->close == 0) && (rc != 0)) {2545 if (rc > 0)2546 rc--;2547- cp->closearg = 0;2548 portp->rc = rc;2549 clear_bit(ST_CLOSING, &portp->state);2550 wake_up_interruptible(&portp->raw_wait);···2556 * need to copy out the command results associated with this command.2557 */2558 if (test_bit(ST_CMDING, &portp->state)) {2559- rc = cp->status;2560- if ((cp->cmd == 0) && (rc != 0)) {2561 if (rc > 0)2562 rc--;2563- if (portp->argp != (void *) NULL) {2564- memcpy(portp->argp, (void *) &(cp->args[0]),2565 portp->argsize);2566- portp->argp = (void *) NULL;2567 }2568- cp->status = 0;2569 portp->rc = rc;2570 clear_bit(ST_CMDING, &portp->state);2571 stli_dodelaycmd(portp, cp);···2604 if (nt.data & DT_TXEMPTY)2605 clear_bit(ST_TXBUSY, &portp->state);2606 if (nt.data & (DT_TXEMPTY | DT_TXLOW)) {2607- if (tty != (struct tty_struct *) NULL) {2608- if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&2609- tty->ldisc.write_wakeup) {2610- (tty->ldisc.write_wakeup)(tty);2611- EBRDENABLE(brdp);2612- }2613 wake_up_interruptible(&tty->write_wait);2614 }2615 }26162617 if ((nt.data & DT_RXBREAK) && (portp->rxmarkmsk & BRKINT)) {2618- if (tty != (struct tty_struct *) NULL) {2619 tty_insert_flip_char(tty, 0, TTY_BREAK);2620 if (portp->flags & ASYNC_SAK) {2621 do_SAK(tty);···2656 * at the cdk header structure.2657 */26582659-static void stli_brdpoll(stlibrd_t *brdp, volatile cdkhdr_t *hdrp)2660{2661- stliport_t *portp;2662- unsigned char hostbits[(STL_MAXCHANS / 8) + 1];2663- unsigned char slavebits[(STL_MAXCHANS / 8) + 1];2664- unsigned char *slavep;2665- int bitpos, bitat, bitsize;2666- int channr, nrdevs, slavebitchange;26672668 bitsize = brdp->bitsize;2669 nrdevs = brdp->nrdevs;···2675 * 8 service bits at a time in the inner loop, so we can bypass2676 * the lot if none of them want service.2677 */2678- memcpy(&hostbits[0], (((unsigned char *) hdrp) + brdp->hostoffset),2679 bitsize);26802681 memset(&slavebits[0], 0, bitsize);···2702 * service may initiate more slave requests.2703 */2704 if (slavebitchange) {2705- hdrp = (volatile cdkhdr_t *) EBRDGETMEMPTR(brdp, CDK_CDKADDR);2706- slavep = ((unsigned char *) hdrp) + brdp->slaveoffset;2707 for (bitpos = 0; (bitpos < bitsize); bitpos++) {2708- if (slavebits[bitpos])2709- slavep[bitpos] &= ~slavebits[bitpos];2710 }2711 }2712}···27242725static void stli_poll(unsigned long arg)2726{2727- volatile cdkhdr_t *hdrp;2728- stlibrd_t *brdp;2729- int brdnr;27302731 stli_timerlist.expires = STLI_TIMEOUT;2732 add_timer(&stli_timerlist);···2736 */2737 for (brdnr = 0; (brdnr < stli_nrbrds); brdnr++) {2738 brdp = stli_brds[brdnr];2739- if (brdp == (stlibrd_t *) NULL)2740 continue;2741 if ((brdp->state & BST_STARTED) == 0)2742 continue;274302744 EBRDENABLE(brdp);2745- hdrp = (volatile cdkhdr_t *) EBRDGETMEMPTR(brdp, CDK_CDKADDR);2746- if (hdrp->hostreq)2747 stli_brdpoll(brdp, hdrp);2748 EBRDDISABLE(brdp);02749 }2750}2751···27602761static void stli_mkasyport(stliport_t *portp, asyport_t *pp, struct termios *tiosp)2762{2763-#ifdef DEBUG2764- printk(KERN_DEBUG "stli_mkasyport(portp=%x,pp=%x,tiosp=%d)\n",2765- (int) portp, (int) pp, (int) tiosp);2766-#endif2767-2768 memset(pp, 0, sizeof(asyport_t));27692770/*···28782879static void stli_mkasysigs(asysigs_t *sp, int dtr, int rts)2880{2881-#ifdef DEBUG2882- printk(KERN_DEBUG "stli_mkasysigs(sp=%x,dtr=%d,rts=%d)\n",2883- (int) sp, dtr, rts);2884-#endif2885-2886 memset(sp, 0, sizeof(asysigs_t));2887 if (dtr >= 0) {2888 sp->signal |= SG_DTR;···28982899static long stli_mktiocm(unsigned long sigvalue)2900{2901- long tiocm;2902-2903-#ifdef DEBUG2904- printk(KERN_DEBUG "stli_mktiocm(sigvalue=%x)\n", (int) sigvalue);2905-#endif2906-2907- tiocm = 0;2908 tiocm |= ((sigvalue & SG_DCD) ? TIOCM_CD : 0);2909 tiocm |= ((sigvalue & SG_CTS) ? TIOCM_CTS : 0);2910 tiocm |= ((sigvalue & SG_RI) ? TIOCM_RI : 0);···2919{2920 stliport_t *portp;2921 int i, panelnr, panelport;2922-2923-#ifdef DEBUG2924- printk(KERN_DEBUG "stli_initports(brdp=%x)\n", (int) brdp);2925-#endif29262927 for (i = 0, panelnr = 0, panelport = 0; (i < brdp->nrports); i++) {2928 portp = kzalloc(sizeof(stliport_t), GFP_KERNEL);···2946 brdp->ports[i] = portp;2947 }29482949- return(0);2950}29512952/*****************************************************************************/···2958static void stli_ecpinit(stlibrd_t *brdp)2959{2960 unsigned long memconf;2961-2962-#ifdef DEBUG2963- printk(KERN_DEBUG "stli_ecpinit(brdp=%d)\n", (int) brdp);2964-#endif29652966 outb(ECP_ATSTOP, (brdp->iobase + ECP_ATCONFR));2967 udelay(10);···29722973static void stli_ecpenable(stlibrd_t *brdp)2974{ 2975-#ifdef DEBUG2976- printk(KERN_DEBUG "stli_ecpenable(brdp=%x)\n", (int) brdp);2977-#endif2978 outb(ECP_ATENABLE, (brdp->iobase + ECP_ATCONFR));2979}2980···29792980static void stli_ecpdisable(stlibrd_t *brdp)2981{ 2982-#ifdef DEBUG2983- printk(KERN_DEBUG "stli_ecpdisable(brdp=%x)\n", (int) brdp);2984-#endif2985 outb(ECP_ATDISABLE, (brdp->iobase + ECP_ATCONFR));2986}2987···29862987static char *stli_ecpgetmemptr(stlibrd_t *brdp, unsigned long offset, int line)2988{ 2989- void *ptr;2990- unsigned char val;2991-2992-#ifdef DEBUG2993- printk(KERN_DEBUG "stli_ecpgetmemptr(brdp=%x,offset=%x)\n", (int) brdp,2994- (int) offset);2995-#endif29962997 if (offset > brdp->memsize) {2998 printk(KERN_ERR "STALLION: shared memory pointer=%x out of "···30073008static void stli_ecpreset(stlibrd_t *brdp)3009{ 3010-#ifdef DEBUG3011- printk(KERN_DEBUG "stli_ecpreset(brdp=%x)\n", (int) brdp);3012-#endif3013-3014 outb(ECP_ATSTOP, (brdp->iobase + ECP_ATCONFR));3015 udelay(10);3016 outb(ECP_ATDISABLE, (brdp->iobase + ECP_ATCONFR));···30173018static void stli_ecpintr(stlibrd_t *brdp)3019{ 3020-#ifdef DEBUG3021- printk(KERN_DEBUG "stli_ecpintr(brdp=%x)\n", (int) brdp);3022-#endif3023 outb(0x1, brdp->iobase);3024}3025···3029static void stli_ecpeiinit(stlibrd_t *brdp)3030{3031 unsigned long memconf;3032-3033-#ifdef DEBUG3034- printk(KERN_DEBUG "stli_ecpeiinit(brdp=%x)\n", (int) brdp);3035-#endif30363037 outb(0x1, (brdp->iobase + ECP_EIBRDENAB));3038 outb(ECP_EISTOP, (brdp->iobase + ECP_EICONFR));···3062{ 3063 void *ptr;3064 unsigned char val;3065-3066-#ifdef DEBUG3067- printk(KERN_DEBUG "stli_ecpeigetmemptr(brdp=%x,offset=%x,line=%d)\n",3068- (int) brdp, (int) offset, line);3069-#endif30703071 if (offset > brdp->memsize) {3072 printk(KERN_ERR "STALLION: shared memory pointer=%x out of "···31123113static char *stli_ecpmcgetmemptr(stlibrd_t *brdp, unsigned long offset, int line)3114{ 3115- void *ptr;3116- unsigned char val;31173118 if (offset > brdp->memsize) {3119 printk(KERN_ERR "STALLION: shared memory pointer=%x out of "···31473148static void stli_ecppciinit(stlibrd_t *brdp)3149{3150-#ifdef DEBUG3151- printk(KERN_DEBUG "stli_ecppciinit(brdp=%x)\n", (int) brdp);3152-#endif3153-3154 outb(ECP_PCISTOP, (brdp->iobase + ECP_PCICONFR));3155 udelay(10);3156 outb(0, (brdp->iobase + ECP_PCICONFR));···3159{ 3160 void *ptr;3161 unsigned char val;3162-3163-#ifdef DEBUG3164- printk(KERN_DEBUG "stli_ecppcigetmemptr(brdp=%x,offset=%x,line=%d)\n",3165- (int) brdp, (int) offset, line);3166-#endif31673168 if (offset > brdp->memsize) {3169 printk(KERN_ERR "STALLION: shared memory pointer=%x out of "···3194{3195 unsigned long memconf;31963197-#ifdef DEBUG3198- printk(KERN_DEBUG "stli_onbinit(brdp=%d)\n", (int) brdp);3199-#endif3200-3201 outb(ONB_ATSTOP, (brdp->iobase + ONB_ATCONFR));3202 udelay(10);3203 outb(ONB_ATDISABLE, (brdp->iobase + ONB_ATCONFR));···32093210static void stli_onbenable(stlibrd_t *brdp)3211{ 3212-#ifdef DEBUG3213- printk(KERN_DEBUG "stli_onbenable(brdp=%x)\n", (int) brdp);3214-#endif3215 outb((brdp->enabval | ONB_ATENABLE), (brdp->iobase + ONB_ATCONFR));3216}3217···32163217static void stli_onbdisable(stlibrd_t *brdp)3218{ 3219-#ifdef DEBUG3220- printk(KERN_DEBUG "stli_onbdisable(brdp=%x)\n", (int) brdp);3221-#endif3222 outb((brdp->enabval | ONB_ATDISABLE), (brdp->iobase + ONB_ATCONFR));3223}3224···3224static char *stli_onbgetmemptr(stlibrd_t *brdp, unsigned long offset, int line)3225{ 3226 void *ptr;3227-3228-#ifdef DEBUG3229- printk(KERN_DEBUG "stli_onbgetmemptr(brdp=%x,offset=%x)\n", (int) brdp,3230- (int) offset);3231-#endif32323233 if (offset > brdp->memsize) {3234 printk(KERN_ERR "STALLION: shared memory pointer=%x out of "···32403241static void stli_onbreset(stlibrd_t *brdp)3242{ 3243-3244-#ifdef DEBUG3245- printk(KERN_DEBUG "stli_onbreset(brdp=%x)\n", (int) brdp);3246-#endif3247-3248 outb(ONB_ATSTOP, (brdp->iobase + ONB_ATCONFR));3249 udelay(10);3250 outb(ONB_ATDISABLE, (brdp->iobase + ONB_ATCONFR));···3255static void stli_onbeinit(stlibrd_t *brdp)3256{3257 unsigned long memconf;3258-3259-#ifdef DEBUG3260- printk(KERN_DEBUG "stli_onbeinit(brdp=%d)\n", (int) brdp);3261-#endif32623263 outb(0x1, (brdp->iobase + ONB_EIBRDENAB));3264 outb(ONB_EISTOP, (brdp->iobase + ONB_EICONFR));···32743275static void stli_onbeenable(stlibrd_t *brdp)3276{ 3277-#ifdef DEBUG3278- printk(KERN_DEBUG "stli_onbeenable(brdp=%x)\n", (int) brdp);3279-#endif3280 outb(ONB_EIENABLE, (brdp->iobase + ONB_EICONFR));3281}3282···32813282static void stli_onbedisable(stlibrd_t *brdp)3283{ 3284-#ifdef DEBUG3285- printk(KERN_DEBUG "stli_onbedisable(brdp=%x)\n", (int) brdp);3286-#endif3287 outb(ONB_EIDISABLE, (brdp->iobase + ONB_EICONFR));3288}3289···32883289static char *stli_onbegetmemptr(stlibrd_t *brdp, unsigned long offset, int line)3290{ 3291- void *ptr;3292- unsigned char val;3293-3294-#ifdef DEBUG3295- printk(KERN_DEBUG "stli_onbegetmemptr(brdp=%x,offset=%x,line=%d)\n",3296- (int) brdp, (int) offset, line);3297-#endif32983299 if (offset > brdp->memsize) {3300 printk(KERN_ERR "STALLION: shared memory pointer=%x out of "···33123313static void stli_onbereset(stlibrd_t *brdp)3314{ 3315-3316-#ifdef DEBUG3317- printk(KERN_ERR "stli_onbereset(brdp=%x)\n", (int) brdp);3318-#endif3319-3320 outb(ONB_EISTOP, (brdp->iobase + ONB_EICONFR));3321 udelay(10);3322 outb(ONB_EIDISABLE, (brdp->iobase + ONB_EICONFR));···33263327static void stli_bbyinit(stlibrd_t *brdp)3328{3329-3330-#ifdef DEBUG3331- printk(KERN_ERR "stli_bbyinit(brdp=%d)\n", (int) brdp);3332-#endif3333-3334 outb(BBY_ATSTOP, (brdp->iobase + BBY_ATCONFR));3335 udelay(10);3336 outb(0, (brdp->iobase + BBY_ATCONFR));···33383339static char *stli_bbygetmemptr(stlibrd_t *brdp, unsigned long offset, int line)3340{ 3341- void *ptr;3342- unsigned char val;33433344-#ifdef DEBUG3345- printk(KERN_ERR "stli_bbygetmemptr(brdp=%x,offset=%x)\n", (int) brdp,3346- (int) offset);3347-#endif33483349- if (offset > brdp->memsize) {3350- printk(KERN_ERR "STALLION: shared memory pointer=%x out of "3351- "range at line=%d(%d), brd=%d\n",3352- (int) offset, line, __LINE__, brdp->brdnr);3353- ptr = NULL;3354- val = 0;3355- } else {3356- ptr = brdp->membase + (offset % BBY_PAGESIZE);3357- val = (unsigned char) (offset / BBY_PAGESIZE);3358- }3359 outb(val, (brdp->iobase + BBY_ATCONFR));3360 return(ptr);3361}···33533354static void stli_bbyreset(stlibrd_t *brdp)3355{ 3356-3357-#ifdef DEBUG3358- printk(KERN_DEBUG "stli_bbyreset(brdp=%x)\n", (int) brdp);3359-#endif3360-3361 outb(BBY_ATSTOP, (brdp->iobase + BBY_ATCONFR));3362 udelay(10);3363 outb(0, (brdp->iobase + BBY_ATCONFR));···33673368static void stli_stalinit(stlibrd_t *brdp)3369{3370-3371-#ifdef DEBUG3372- printk(KERN_DEBUG "stli_stalinit(brdp=%d)\n", (int) brdp);3373-#endif3374-3375 outb(0x1, brdp->iobase);3376 mdelay(1000);3377}···33753376static char *stli_stalgetmemptr(stlibrd_t *brdp, unsigned long offset, int line)3377{ 3378- void *ptr;3379-3380-#ifdef DEBUG3381- printk(KERN_DEBUG "stli_stalgetmemptr(brdp=%x,offset=%x)\n", (int) brdp,3382- (int) offset);3383-#endif3384-3385- if (offset > brdp->memsize) {3386- printk(KERN_ERR "STALLION: shared memory pointer=%x out of "3387- "range at line=%d(%d), brd=%d\n",3388- (int) offset, line, __LINE__, brdp->brdnr);3389- ptr = NULL;3390- } else {3391- ptr = brdp->membase + (offset % STAL_PAGESIZE);3392- }3393- return(ptr);3394}33953396/*****************************************************************************/33973398static void stli_stalreset(stlibrd_t *brdp)3399{ 3400- volatile unsigned long *vecp;34013402-#ifdef DEBUG3403- printk(KERN_DEBUG "stli_stalreset(brdp=%x)\n", (int) brdp);3404-#endif3405-3406- vecp = (volatile unsigned long *) (brdp->membase + 0x30);3407- *vecp = 0xffff0000;3408 outb(0, brdp->iobase);3409 mdelay(1000);3410}···34003401static int stli_initecp(stlibrd_t *brdp)3402{3403- cdkecpsig_t sig;3404- cdkecpsig_t *sigsp;3405- unsigned int status, nxtid;3406- char *name;3407- int panelnr, nrports;3408-3409-#ifdef DEBUG3410- printk(KERN_DEBUG "stli_initecp(brdp=%x)\n", (int) brdp);3411-#endif34123413 if (!request_region(brdp->iobase, brdp->iosize, "istallion"))3414 return -EIO;···3412 if ((brdp->iobase == 0) || (brdp->memaddr == 0))3413 {3414 release_region(brdp->iobase, brdp->iosize);3415- return(-ENODEV);3416 }34173418 brdp->iosize = ECP_IOSIZE;···34813482 default:3483 release_region(brdp->iobase, brdp->iosize);3484- return(-EINVAL);3485 }34863487/*···3493 EBRDINIT(brdp);34943495 brdp->membase = ioremap(brdp->memaddr, brdp->memsize);3496- if (brdp->membase == (void *) NULL)3497 {3498 release_region(brdp->iobase, brdp->iosize);3499- return(-ENOMEM);3500 }35013502/*···3505 * this is, and what it is connected to it.3506 */3507 EBRDENABLE(brdp);3508- sigsp = (cdkecpsig_t *) EBRDGETMEMPTR(brdp, CDK_SIGADDR);3509 memcpy(&sig, sigsp, sizeof(cdkecpsig_t));3510 EBRDDISABLE(brdp);35113512-#if 03513- printk("%s(%d): sig-> magic=%x rom=%x panel=%x,%x,%x,%x,%x,%x,%x,%x\n",3514- __FILE__, __LINE__, (int) sig.magic, sig.romver, sig.panelid[0],3515- (int) sig.panelid[1], (int) sig.panelid[2],3516- (int) sig.panelid[3], (int) sig.panelid[4],3517- (int) sig.panelid[5], (int) sig.panelid[6],3518- (int) sig.panelid[7]);3519-#endif3520-3521- if (sig.magic != ECP_MAGIC)3522 {3523 release_region(brdp->iobase, brdp->iosize);3524- return(-ENODEV);3525 }35263527/*···353635373538 brdp->state |= BST_FOUND;3539- return(0);3540}35413542/*****************************************************************************/···35483549static int stli_initonb(stlibrd_t *brdp)3550{3551- cdkonbsig_t sig;3552- cdkonbsig_t *sigsp;3553- char *name;3554- int i;3555-3556-#ifdef DEBUG3557- printk(KERN_DEBUG "stli_initonb(brdp=%x)\n", (int) brdp);3558-#endif35593560/*3561 * Do a basic sanity check on the IO and memory addresses.3562 */3563- if ((brdp->iobase == 0) || (brdp->memaddr == 0))3564- return(-ENODEV);35653566 brdp->iosize = ONB_IOSIZE;3567···3575 case BRD_ONBOARD2:3576 case BRD_ONBOARD2_32:3577 case BRD_ONBOARDRS:3578- brdp->membase = (void *) brdp->memaddr;3579 brdp->memsize = ONB_MEMSIZE;3580 brdp->pagesize = ONB_ATPAGESIZE;3581 brdp->init = stli_onbinit;···3592 break;35933594 case BRD_ONBOARDE:3595- brdp->membase = (void *) brdp->memaddr;3596 brdp->memsize = ONB_EIMEMSIZE;3597 brdp->pagesize = ONB_EIPAGESIZE;3598 brdp->init = stli_onbeinit;···3607 case BRD_BRUMBY4:3608 case BRD_BRUMBY8:3609 case BRD_BRUMBY16:3610- brdp->membase = (void *) brdp->memaddr;3611 brdp->memsize = BBY_MEMSIZE;3612 brdp->pagesize = BBY_PAGESIZE;3613 brdp->init = stli_bbyinit;···3620 break;36213622 case BRD_STALLION:3623- brdp->membase = (void *) brdp->memaddr;3624 brdp->memsize = STAL_MEMSIZE;3625 brdp->pagesize = STAL_PAGESIZE;3626 brdp->init = stli_stalinit;···36343635 default:3636 release_region(brdp->iobase, brdp->iosize);3637- return(-EINVAL);3638 }36393640/*···3646 EBRDINIT(brdp);36473648 brdp->membase = ioremap(brdp->memaddr, brdp->memsize);3649- if (brdp->membase == (void *) NULL)3650 {3651 release_region(brdp->iobase, brdp->iosize);3652- return(-ENOMEM);3653 }36543655/*···3658 * this is, and how many ports.3659 */3660 EBRDENABLE(brdp);3661- sigsp = (cdkonbsig_t *) EBRDGETMEMPTR(brdp, CDK_SIGADDR);3662- memcpy(&sig, sigsp, sizeof(cdkonbsig_t));3663 EBRDDISABLE(brdp);36643665-#if 03666- printk("%s(%d): sig-> magic=%x:%x:%x:%x romver=%x amask=%x:%x:%x\n",3667- __FILE__, __LINE__, sig.magic0, sig.magic1, sig.magic2,3668- sig.magic3, sig.romver, sig.amask0, sig.amask1, sig.amask2);3669-#endif3670-3671- if ((sig.magic0 != ONB_MAGIC0) || (sig.magic1 != ONB_MAGIC1) ||3672- (sig.magic2 != ONB_MAGIC2) || (sig.magic3 != ONB_MAGIC3))3673 {3674 release_region(brdp->iobase, brdp->iosize);3675- return(-ENODEV);3676 }36773678/*···368936903691 brdp->state |= BST_FOUND;3692- return(0);3693}36943695/*****************************************************************************/···37023703static int stli_startbrd(stlibrd_t *brdp)3704{3705- volatile cdkhdr_t *hdrp;3706- volatile cdkmem_t *memp;3707- volatile cdkasy_t *ap;3708- unsigned long flags;3709- stliport_t *portp;3710- int portnr, nrdevs, i, rc;037113712-#ifdef DEBUG3713- printk(KERN_DEBUG "stli_startbrd(brdp=%x)\n", (int) brdp);3714-#endif3715-3716- rc = 0;3717-3718- save_flags(flags);3719- cli();3720 EBRDENABLE(brdp);3721- hdrp = (volatile cdkhdr_t *) EBRDGETMEMPTR(brdp, CDK_CDKADDR);3722 nrdevs = hdrp->nrdevs;37233724#if 03725 printk("%s(%d): CDK version %d.%d.%d --> "3726 "nrdevs=%d memp=%x hostp=%x slavep=%x\n",3727- __FILE__, __LINE__, hdrp->ver_release, hdrp->ver_modification,3728- hdrp->ver_fix, nrdevs, (int) hdrp->memp, (int) hdrp->hostp,3729- (int) hdrp->slavep);3730#endif37313732 if (nrdevs < (brdp->nrports + 1)) {···3732 brdp->hostoffset = hdrp->hostp - CDK_CDKADDR;3733 brdp->slaveoffset = hdrp->slavep - CDK_CDKADDR;3734 brdp->bitsize = (nrdevs + 7) / 8;3735- memp = (volatile cdkmem_t *) hdrp->memp;3736- if (((unsigned long) memp) > brdp->memsize) {3737 printk(KERN_ERR "STALLION: corrupted shared memory region?\n");3738 rc = -EIO;3739 goto stli_donestartup;3740 }3741- memp = (volatile cdkmem_t *) EBRDGETMEMPTR(brdp, (unsigned long) memp);3742- if (memp->dtype != TYP_ASYNCTRL) {3743 printk(KERN_ERR "STALLION: no slave control device found\n");3744 goto stli_donestartup;3745 }···3751 * change pages while reading memory map.3752 */3753 for (i = 1, portnr = 0; (i < nrdevs); i++, portnr++, memp++) {3754- if (memp->dtype != TYP_ASYNC)3755 break;3756 portp = brdp->ports[portnr];3757- if (portp == (stliport_t *) NULL)3758 break;3759 portp->devnr = i;3760- portp->addr = memp->offset;3761 portp->reqbit = (unsigned char) (0x1 << (i * 8 / nrdevs));3762 portp->portidx = (unsigned char) (i / 8);3763 portp->portbit = (unsigned char) (0x1 << (i % 8));3764 }37653766- hdrp->slavereq = 0xff;37673768/*3769 * For each port setup a local copy of the RX and TX buffer offsets···3772 */3773 for (i = 1, portnr = 0; (i < nrdevs); i++, portnr++) {3774 portp = brdp->ports[portnr];3775- if (portp == (stliport_t *) NULL)3776 break;3777 if (portp->addr == 0)3778 break;3779- ap = (volatile cdkasy_t *) EBRDGETMEMPTR(brdp, portp->addr);3780- if (ap != (volatile cdkasy_t *) NULL) {3781- portp->rxsize = ap->rxq.size;3782- portp->txsize = ap->txq.size;3783- portp->rxoffset = ap->rxq.offset;3784- portp->txoffset = ap->txq.offset;3785 }3786 }37873788stli_donestartup:3789 EBRDDISABLE(brdp);3790- restore_flags(flags);37913792 if (rc == 0)3793 brdp->state |= BST_STARTED;···3798 add_timer(&stli_timerlist);3799 }38003801- return(rc);3802}38033804/*****************************************************************************/···38093810static int __init stli_brdinit(stlibrd_t *brdp)3811{3812-#ifdef DEBUG3813- printk(KERN_DEBUG "stli_brdinit(brdp=%x)\n", (int) brdp);3814-#endif3815-3816 stli_brds[brdp->brdnr] = brdp;38173818 switch (brdp->brdtype) {···3836 case BRD_ECHPCI:3837 printk(KERN_ERR "STALLION: %s board type not supported in "3838 "this driver\n", stli_brdnames[brdp->brdtype]);3839- return(ENODEV);3840 default:3841 printk(KERN_ERR "STALLION: board=%d is unknown board "3842 "type=%d\n", brdp->brdnr, brdp->brdtype);3843- return(ENODEV);3844 }38453846 if ((brdp->state & BST_FOUND) == 0) {···3848 "io=%x mem=%x\n",3849 stli_brdnames[brdp->brdtype], brdp->brdnr,3850 brdp->iobase, (int) brdp->memaddr);3851- return(ENODEV);3852 }38533854 stli_initports(brdp);···3856 "nrpanels=%d nrports=%d\n", stli_brdnames[brdp->brdtype],3857 brdp->brdnr, brdp->iobase, (int) brdp->memaddr,3858 brdp->nrpanels, brdp->nrports);3859- return(0);3860}38613862/*****************************************************************************/···38683869static int stli_eisamemprobe(stlibrd_t *brdp)3870{3871- cdkecpsig_t ecpsig, *ecpsigp;3872- cdkonbsig_t onbsig, *onbsigp;3873 int i, foundit;3874-3875-#ifdef DEBUG3876- printk(KERN_DEBUG "stli_eisamemprobe(brdp=%x)\n", (int) brdp);3877-#endif38783879/*3880 * First up we reset the board, to get it into a known state. There···3895 mdelay(1);3896 stli_onbeenable(brdp);3897 } else {3898- return(-ENODEV);3899 }39003901 foundit = 0;···3907 */3908 for (i = 0; (i < stli_eisamempsize); i++) {3909 brdp->memaddr = stli_eisamemprobeaddrs[i];3910- brdp->membase = (void *) brdp->memaddr;3911 brdp->membase = ioremap(brdp->memaddr, brdp->memsize);3912- if (brdp->membase == (void *) NULL)3913 continue;39143915 if (brdp->brdtype == BRD_ECPE) {3916- ecpsigp = (cdkecpsig_t *) stli_ecpeigetmemptr(brdp,3917 CDK_SIGADDR, __LINE__);3918- memcpy(&ecpsig, ecpsigp, sizeof(cdkecpsig_t));3919- if (ecpsig.magic == ECP_MAGIC)3920 foundit = 1;3921 } else {3922- onbsigp = (cdkonbsig_t *) stli_onbegetmemptr(brdp,3923 CDK_SIGADDR, __LINE__);3924- memcpy(&onbsig, onbsigp, sizeof(cdkonbsig_t));3925- if ((onbsig.magic0 == ONB_MAGIC0) &&3926- (onbsig.magic1 == ONB_MAGIC1) &&3927- (onbsig.magic2 == ONB_MAGIC2) &&3928- (onbsig.magic3 == ONB_MAGIC3))3929 foundit = 1;3930 }3931···3948 printk(KERN_ERR "STALLION: failed to probe shared memory "3949 "region for %s in EISA slot=%d\n",3950 stli_brdnames[brdp->brdtype], (brdp->iobase >> 12));3951- return(-ENODEV);3952 }3953- return(0);3954}39553956static int stli_getbrdnr(void)···39813982static int stli_findeisabrds(void)3983{3984- stlibrd_t *brdp;3985- unsigned int iobase, eid;3986- int i;3987-3988-#ifdef DEBUG3989- printk(KERN_DEBUG "stli_findeisabrds()\n");3990-#endif39913992/*3993- * Firstly check if this is an EISA system. Do this by probing for3994- * the system board EISA ID. If this is not an EISA system then3995 * don't bother going any further!3996 */3997- outb(0xff, 0xc80);3998- if (inb(0xc80) == 0xff)3999- return(0);40004001/*4002 * Looks like an EISA system, so go searching for EISA boards.···4008 */4009 for (i = 0; (i < STL_MAXBRDS); i++) {4010 brdp = stli_brds[i];4011- if (brdp == (stlibrd_t *) NULL)4012 continue;4013 if (brdp->iobase == iobase)4014 break;···4020 * We have found a Stallion board and it is not configured already.4021 * Allocate a board structure and initialize it.4022 */4023- if ((brdp = stli_allocbrd()) == (stlibrd_t *) NULL)4024- return(-ENOMEM);4025 if ((brdp->brdnr = stli_getbrdnr()) < 0)4026- return(-ENOMEM);4027 eid = inb(iobase + 0xc82);4028 if (eid == ECP_EISAID)4029 brdp->brdtype = BRD_ECPE;···4038 stli_brdinit(brdp);4039 }40404041- return(0);4042}40434044/*****************************************************************************/···40594060static int stli_initpcibrd(int brdtype, struct pci_dev *devp)4061{4062- stlibrd_t *brdp;4063-4064-#ifdef DEBUG4065- printk(KERN_DEBUG "stli_initpcibrd(brdtype=%d,busnr=%x,devnr=%x)\n",4066- brdtype, dev->bus->number, dev->devfn);4067-#endif40684069 if (pci_enable_device(devp))4070- return(-EIO);4071- if ((brdp = stli_allocbrd()) == (stlibrd_t *) NULL)4072- return(-ENOMEM);4073 if ((brdp->brdnr = stli_getbrdnr()) < 0) {4074 printk(KERN_INFO "STALLION: too many boards found, "4075 "maximum supported %d\n", STL_MAXBRDS);4076- return(0);4077 }4078 brdp->brdtype = brdtype;4079-4080-#ifdef DEBUG4081- printk(KERN_DEBUG "%s(%d): BAR[]=%lx,%lx,%lx,%lx\n", __FILE__, __LINE__,4082- pci_resource_start(devp, 0),4083- pci_resource_start(devp, 1),4084- pci_resource_start(devp, 2),4085- pci_resource_start(devp, 3));4086-#endif4087-4088/*4089 * We have all resources from the board, so lets setup the actual4090 * board structure now.···4079 brdp->memaddr = pci_resource_start(devp, 2);4080 stli_brdinit(brdp);40814082- return(0);4083}40844085/*****************************************************************************/···40914092static int stli_findpcibrds(void)4093{4094- struct pci_dev *dev = NULL;4095- int rc;40964097-#ifdef DEBUG4098- printk("stli_findpcibrds()\n");4099-#endif4100-4101- while ((dev = pci_find_device(PCI_VENDOR_ID_STALLION,4102- PCI_DEVICE_ID_ECRA, dev))) {4103- if ((rc = stli_initpcibrd(BRD_ECPPCI, dev)))4104- return(rc);4105 }4106-4107- return(0);4108}41094110#endif···41094110static stlibrd_t *stli_allocbrd(void)4111{4112- stlibrd_t *brdp;41134114 brdp = kzalloc(sizeof(stlibrd_t), GFP_KERNEL);4115 if (!brdp) {4116 printk(KERN_ERR "STALLION: failed to allocate memory "4117- "(size=%d)\n", sizeof(stlibrd_t));4118 return NULL;4119 }4120-4121 brdp->magic = STLI_BOARDMAGIC;4122- return(brdp);4123}41244125/*****************************************************************************/···41304131static int stli_initbrds(void)4132{4133- stlibrd_t *brdp, *nxtbrdp;4134- stlconf_t *confp;4135- int i, j;4136-4137-#ifdef DEBUG4138- printk(KERN_DEBUG "stli_initbrds()\n");4139-#endif41404141 if (stli_nrbrds > STL_MAXBRDS) {4142 printk(KERN_INFO "STALLION: too many boards in configuration "···4147 */4148 for (i = 0; (i < stli_nrbrds); i++) {4149 confp = &stli_brdconf[i];4150-#ifdef MODULE4151 stli_parsebrd(confp, stli_brdsp[i]);4152-#endif4153- if ((brdp = stli_allocbrd()) == (stlibrd_t *) NULL)4154- return(-ENOMEM);4155 brdp->brdnr = i;4156 brdp->brdtype = confp->brdtype;4157 brdp->iobase = confp->ioaddr1;···4161 * Static configuration table done, so now use dynamic methods to4162 * see if any more boards should be configured.4163 */4164-#ifdef MODULE4165 stli_argbrds();4166-#endif4167 if (STLI_EISAPROBE)4168 stli_findeisabrds();4169#ifdef CONFIG_PCI···4177 if (stli_nrbrds > 1) {4178 for (i = 0; (i < stli_nrbrds); i++) {4179 brdp = stli_brds[i];4180- if (brdp == (stlibrd_t *) NULL)4181 continue;4182 for (j = i + 1; (j < stli_nrbrds); j++) {4183 nxtbrdp = stli_brds[j];4184- if (nxtbrdp == (stlibrd_t *) NULL)4185 continue;4186 if ((brdp->membase >= nxtbrdp->membase) &&4187 (brdp->membase <= (nxtbrdp->membase +···4196 if (stli_shared == 0) {4197 for (i = 0; (i < stli_nrbrds); i++) {4198 brdp = stli_brds[i];4199- if (brdp == (stlibrd_t *) NULL)4200 continue;4201 if (brdp->state & BST_FOUND) {4202 EBRDENABLE(brdp);···4206 }4207 }42084209- return(0);4210}42114212/*****************************************************************************/···42194220static ssize_t stli_memread(struct file *fp, char __user *buf, size_t count, loff_t *offp)4221{4222- unsigned long flags;4223- void *memptr;4224- stlibrd_t *brdp;4225- int brdnr, size, n;4226-4227-#ifdef DEBUG4228- printk(KERN_DEBUG "stli_memread(fp=%x,buf=%x,count=%x,offp=%x)\n",4229- (int) fp, (int) buf, count, (int) offp);4230-#endif42314232 brdnr = iminor(fp->f_dentry->d_inode);4233 if (brdnr >= stli_nrbrds)4234- return(-ENODEV);4235 brdp = stli_brds[brdnr];4236- if (brdp == (stlibrd_t *) NULL)4237- return(-ENODEV);4238 if (brdp->state == 0)4239- return(-ENODEV);4240- if (fp->f_pos >= brdp->memsize)4241- return(0);42424243- size = MIN(count, (brdp->memsize - fp->f_pos));42444245- save_flags(flags);4246- cli();4247- EBRDENABLE(brdp);000004248 while (size > 0) {4249- memptr = (void *) EBRDGETMEMPTR(brdp, fp->f_pos);4250- n = MIN(size, (brdp->pagesize - (((unsigned long) fp->f_pos) % brdp->pagesize)));4251- if (copy_to_user(buf, memptr, n)) {0000004252 count = -EFAULT;4253 goto out;4254 }4255- fp->f_pos += n;4256 buf += n;4257 size -= n;4258 }4259out:4260- EBRDDISABLE(brdp);4261- restore_flags(flags);4262-4263- return(count);4264}42654266/*****************************************************************************/···4276 * Code to handle an "staliomem" write operation. This device is the 4277 * contents of the board shared memory. It is used for down loading4278 * the slave image (and debugging :-)004279 */42804281static ssize_t stli_memwrite(struct file *fp, const char __user *buf, size_t count, loff_t *offp)4282{4283- unsigned long flags;4284- void *memptr;4285- stlibrd_t *brdp;4286- char __user *chbuf;4287- int brdnr, size, n;4288-4289-#ifdef DEBUG4290- printk(KERN_DEBUG "stli_memwrite(fp=%x,buf=%x,count=%x,offp=%x)\n",4291- (int) fp, (int) buf, count, (int) offp);4292-#endif42934294 brdnr = iminor(fp->f_dentry->d_inode);04295 if (brdnr >= stli_nrbrds)4296- return(-ENODEV);4297 brdp = stli_brds[brdnr];4298- if (brdp == (stlibrd_t *) NULL)4299- return(-ENODEV);4300 if (brdp->state == 0)4301- return(-ENODEV);4302- if (fp->f_pos >= brdp->memsize)4303- return(0);43044305 chbuf = (char __user *) buf;4306- size = MIN(count, (brdp->memsize - fp->f_pos));43074308- save_flags(flags);4309- cli();4310- EBRDENABLE(brdp);000004311 while (size > 0) {4312- memptr = (void *) EBRDGETMEMPTR(brdp, fp->f_pos);4313- n = MIN(size, (brdp->pagesize - (((unsigned long) fp->f_pos) % brdp->pagesize)));4314- if (copy_from_user(memptr, chbuf, n)) {4315- count = -EFAULT;04316 goto out;4317 }4318- fp->f_pos += n;0000004319 chbuf += n;4320 size -= n;4321 }4322out:4323- EBRDDISABLE(brdp);4324- restore_flags(flags);4325-4326- return(count);4327}43284329/*****************************************************************************/···43454346static int stli_getbrdstats(combrd_t __user *bp)4347{4348- stlibrd_t *brdp;4349- int i;43504351 if (copy_from_user(&stli_brdstats, bp, sizeof(combrd_t)))4352 return -EFAULT;4353 if (stli_brdstats.brd >= STL_MAXBRDS)4354- return(-ENODEV);4355 brdp = stli_brds[stli_brdstats.brd];4356- if (brdp == (stlibrd_t *) NULL)4357- return(-ENODEV);43584359 memset(&stli_brdstats, 0, sizeof(combrd_t));4360 stli_brdstats.brd = brdp->brdnr;···43734374 if (copy_to_user(bp, &stli_brdstats, sizeof(combrd_t)))4375 return -EFAULT;4376- return(0);4377}43784379/*****************************************************************************/···43844385static stliport_t *stli_getport(int brdnr, int panelnr, int portnr)4386{4387- stlibrd_t *brdp;4388- int i;43894390- if ((brdnr < 0) || (brdnr >= STL_MAXBRDS))4391- return((stliport_t *) NULL);4392 brdp = stli_brds[brdnr];4393- if (brdp == (stlibrd_t *) NULL)4394- return((stliport_t *) NULL);4395 for (i = 0; (i < panelnr); i++)4396 portnr += brdp->panels[i];4397 if ((portnr < 0) || (portnr >= brdp->nrports))4398- return((stliport_t *) NULL);4399- return(brdp->ports[portnr]);4400}44014402/*****************************************************************************/···44154416 memset(&stli_comstats, 0, sizeof(comstats_t));44174418- if (portp == (stliport_t *) NULL)4419- return(-ENODEV);4420 brdp = stli_brds[portp->brdnr];4421- if (brdp == (stlibrd_t *) NULL)4422- return(-ENODEV);44234424 if (brdp->state & BST_STARTED) {4425 if ((rc = stli_cmdwait(brdp, portp, A_GETSTATS,4426 &stli_cdkstats, sizeof(asystats_t), 1)) < 0)4427- return(rc);4428 } else {4429 memset(&stli_cdkstats, 0, sizeof(asystats_t));4430 }···4435 stli_comstats.state = portp->state;4436 stli_comstats.flags = portp->flags;44374438- save_flags(flags);4439- cli();4440- if (portp->tty != (struct tty_struct *) NULL) {4441 if (portp->tty->driver_data == portp) {4442 stli_comstats.ttystate = portp->tty->flags;4443- stli_comstats.rxbuffered = -1 /*portp->tty->flip.count*/;4444- if (portp->tty->termios != (struct termios *) NULL) {4445 stli_comstats.cflags = portp->tty->termios->c_cflag;4446 stli_comstats.iflags = portp->tty->termios->c_iflag;4447 stli_comstats.oflags = portp->tty->termios->c_oflag;···4448 }4449 }4450 }4451- restore_flags(flags);44524453 stli_comstats.txtotal = stli_cdkstats.txchars;4454 stli_comstats.rxtotal = stli_cdkstats.rxchars + stli_cdkstats.ringover;···4470 stli_comstats.hwid = stli_cdkstats.hwid;4471 stli_comstats.signals = stli_mktiocm(stli_cdkstats.signals);44724473- return(0);4474}44754476/*****************************************************************************/···44834484static int stli_getportstats(stliport_t *portp, comstats_t __user *cp)4485{4486- stlibrd_t *brdp;4487- int rc;44884489 if (!portp) {4490 if (copy_from_user(&stli_comstats, cp, sizeof(comstats_t)))···45144515static int stli_clrportstats(stliport_t *portp, comstats_t __user *cp)4516{4517- stlibrd_t *brdp;4518- int rc;45194520 if (!portp) {4521 if (copy_from_user(&stli_comstats, cp, sizeof(comstats_t)))···45534554static int stli_getportstruct(stliport_t __user *arg)4555{4556- stliport_t *portp;45574558 if (copy_from_user(&stli_dummyport, arg, sizeof(stliport_t)))4559 return -EFAULT;···45744575static int stli_getbrdstruct(stlibrd_t __user *arg)4576{4577- stlibrd_t *brdp;45784579 if (copy_from_user(&stli_dummybrd, arg, sizeof(stlibrd_t)))4580 return -EFAULT;···45984599static int stli_memioctl(struct inode *ip, struct file *fp, unsigned int cmd, unsigned long arg)4600{4601- stlibrd_t *brdp;4602- int brdnr, rc, done;4603 void __user *argp = (void __user *)arg;4604-4605-#ifdef DEBUG4606- printk(KERN_DEBUG "stli_memioctl(ip=%x,fp=%x,cmd=%x,arg=%x)\n",4607- (int) ip, (int) fp, cmd, (int) arg);4608-#endif46094610/*4611 * First up handle the board independent ioctls.···4632 }46334634 if (done)4635- return(rc);46364637/*4638 * Now handle the board specific ioctls. These all depend on the···4640 */4641 brdnr = iminor(ip);4642 if (brdnr >= STL_MAXBRDS)4643- return(-ENODEV);4644 brdp = stli_brds[brdnr];4645 if (!brdp)4646- return(-ENODEV);4647 if (brdp->state == 0)4648- return(-ENODEV);46494650 switch (cmd) {4651 case STL_BINTR:···4669 rc = -ENOIOCTLCMD;4670 break;4671 }4672-4673- return(rc);4674}46754676static struct tty_operations stli_ops = {···4703 int i;4704 printk(KERN_INFO "%s: version %s\n", stli_drvtitle, stli_drvversion);47050004706 stli_initbrds();47074708 stli_serial = alloc_tty_driver(STL_MAXBRDS * STL_MAXPORTS);···4715/*4716 * Allocate a temporary write buffer.4717 */4718- stli_tmpwritebuf = kmalloc(STLI_TXBUFSIZE, GFP_KERNEL);4719- if (!stli_tmpwritebuf)4720- printk(KERN_ERR "STALLION: failed to allocate memory "4721- "(size=%d)\n", STLI_TXBUFSIZE);4722 stli_txcookbuf = kmalloc(STLI_TXBUFSIZE, GFP_KERNEL);4723 if (!stli_txcookbuf)4724 printk(KERN_ERR "STALLION: failed to allocate memory "···4758 printk(KERN_ERR "STALLION: failed to register serial driver\n");4759 return -EBUSY;4760 }4761- return(0);4762}47634764/*****************************************************************************/
···42#include <linux/devfs_fs_kernel.h>43#include <linux/device.h>44#include <linux/wait.h>45+#include <linux/eisa.h>4647#include <asm/io.h>48#include <asm/uaccess.h>49050#include <linux/pci.h>05152/*****************************************************************************/53···137138static int stli_nrbrds = ARRAY_SIZE(stli_brdconf);139140+/* stli_lock must NOT be taken holding brd_lock */141+static spinlock_t stli_lock; /* TTY logic lock */142+static spinlock_t brd_lock; /* Board logic lock */143+144/*145 * There is some experimental EISA board detection code in this driver.146 * By default it is disabled, but for those that want to try it out,···173174static struct tty_driver *stli_serial;17500000000176177#define STLI_TXBUFSIZE 4096178···419#endif420421static struct pci_device_id istallion_pci_tbl[] = {422+ { PCI_DEVICE(PCI_VENDOR_ID_STALLION, PCI_DEVICE_ID_ECRA), },423 { 0 }424};425MODULE_DEVICE_TABLE(pci, istallion_pci_tbl);···682static ssize_t stli_memread(struct file *fp, char __user *buf, size_t count, loff_t *offp);683static ssize_t stli_memwrite(struct file *fp, const char __user *buf, size_t count, loff_t *offp);684static int stli_memioctl(struct inode *ip, struct file *fp, unsigned int cmd, unsigned long arg);685+static void stli_brdpoll(stlibrd_t *brdp, cdkhdr_t __iomem *hdrp);686static void stli_poll(unsigned long arg);687static int stli_hostcmd(stlibrd_t *brdp, stliport_t *portp);688static int stli_initopen(stlibrd_t *brdp, stliport_t *portp);···693static int stli_setport(stliport_t *portp);694static int stli_cmdwait(stlibrd_t *brdp, stliport_t *portp, unsigned long cmd, void *arg, int size, int copyback);695static void stli_sendcmd(stlibrd_t *brdp, stliport_t *portp, unsigned long cmd, void *arg, int size, int copyback);696+static void __stli_sendcmd(stlibrd_t *brdp, stliport_t *portp, unsigned long cmd, void *arg, int size, int copyback);697+static void stli_dodelaycmd(stliport_t *portp, cdkctrl_t __iomem *cp);698static void stli_mkasyport(stliport_t *portp, asyport_t *pp, struct termios *tiosp);699static void stli_mkasysigs(asysigs_t *sp, int dtr, int rts);700static long stli_mktiocm(unsigned long sigvalue);···799800static int __init istallion_module_init(void)801{00000000802 stli_init();803+ return 0;00804}805806/*****************************************************************************/···819{820 stlibrd_t *brdp;821 stliport_t *portp;0822 int i, j;0000823824 printk(KERN_INFO "Unloading %s: version %s\n", stli_drvtitle,825 stli_drvversion);826827+ /*828+ * Free up all allocated resources used by the ports. This includes829+ * memory and interrupts.830+ */000831 if (stli_timeron) {832 stli_timeron = 0;833+ del_timer_sync(&stli_timerlist);834 }835836 i = tty_unregister_driver(stli_serial);837 if (i) {838 printk("STALLION: failed to un-register tty driver, "839 "errno=%d\n", -i);0840 return;841 }842 put_tty_driver(stli_serial);···859 printk("STALLION: failed to un-register serial memory device, "860 "errno=%d\n", -i);8610862 kfree(stli_txcookbuf);863864 for (i = 0; (i < stli_nrbrds); i++) {865+ if ((brdp = stli_brds[i]) == NULL)866 continue;867 for (j = 0; (j < STL_MAXPORTS); j++) {868 portp = brdp->ports[j];869+ if (portp != NULL) {870+ if (portp->tty != NULL)871 tty_hangup(portp->tty);872 kfree(portp);873 }···878 if (brdp->iosize > 0)879 release_region(brdp->iobase, brdp->iosize);880 kfree(brdp);881+ stli_brds[i] = NULL;882 }00883}884885module_init(istallion_module_init);···895896static void stli_argbrds(void)897{898+ stlconf_t conf;899+ stlibrd_t *brdp;900+ int i;0000901902 for (i = stli_nrbrds; i < ARRAY_SIZE(stli_brdsp); i++) {903 memset(&conf, 0, sizeof(conf));904 if (stli_parsebrd(&conf, stli_brdsp[i]) == 0)905 continue;906+ if ((brdp = stli_allocbrd()) == NULL)907 continue;908 stli_nrbrds = i + 1;909 brdp->brdnr = i;···926927static unsigned long stli_atol(char *str)928{929+ unsigned long val;930+ int base, c;931+ char *sp;932933 val = 0;934 sp = str;···962963static int stli_parsebrd(stlconf_t *confp, char **argp)964{965+ char *sp;966+ int i;967968+ if (argp[0] == NULL || *argp[0] == 0)969+ return 0;0000970971 for (sp = argp[0], i = 0; ((*sp != 0) && (i < 25)); sp++, i++)972 *sp = TOLOWER(*sp);···985 }986987 confp->brdtype = stli_brdstr[i].type;988+ if (argp[1] != NULL && *argp[1] != 0)989 confp->ioaddr1 = stli_atol(argp[1]);990+ if (argp[2] != NULL && *argp[2] != 0)991 confp->memaddr = stli_atol(argp[2]);992 return(1);993}···998999static int stli_open(struct tty_struct *tty, struct file *filp)1000{1001+ stlibrd_t *brdp;1002+ stliport_t *portp;1003+ unsigned int minordev;1004+ int brdnr, portnr, rc;0000010051006 minordev = tty->index;1007 brdnr = MINOR2BRD(minordev);1008 if (brdnr >= stli_nrbrds)1009+ return -ENODEV;1010 brdp = stli_brds[brdnr];1011+ if (brdp == NULL)1012+ return -ENODEV;1013 if ((brdp->state & BST_STARTED) == 0)1014+ return -ENODEV;1015 portnr = MINOR2PORT(minordev);1016 if ((portnr < 0) || (portnr > brdp->nrports))1017+ return -ENODEV;10181019 portp = brdp->ports[portnr];1020+ if (portp == NULL)1021+ return -ENODEV;1022 if (portp->devnr < 1)1023+ return -ENODEV;102410251026/*···1037 if (portp->flags & ASYNC_CLOSING) {1038 interruptible_sleep_on(&portp->close_wait);1039 if (portp->flags & ASYNC_HUP_NOTIFY)1040+ return -EAGAIN;1041+ return -ERESTARTSYS;1042 }10431044/*···1054 wait_event_interruptible(portp->raw_wait,1055 !test_bit(ST_INITIALIZING, &portp->state));1056 if (signal_pending(current))1057+ return -ERESTARTSYS;10581059 if ((portp->flags & ASYNC_INITIALIZED) == 0) {1060 set_bit(ST_INITIALIZING, &portp->state);···1065 clear_bit(ST_INITIALIZING, &portp->state);1066 wake_up_interruptible(&portp->raw_wait);1067 if (rc < 0)1068+ return rc;1069 }10701071/*···1077 if (portp->flags & ASYNC_CLOSING) {1078 interruptible_sleep_on(&portp->close_wait);1079 if (portp->flags & ASYNC_HUP_NOTIFY)1080+ return -EAGAIN;1081+ return -ERESTARTSYS;1082 }10831084/*···1088 */1089 if (!(filp->f_flags & O_NONBLOCK)) {1090 if ((rc = stli_waitcarrier(brdp, portp, filp)) != 0)1091+ return rc;1092 }1093 portp->flags |= ASYNC_NORMAL_ACTIVE;1094+ return 0;1095}10961097/*****************************************************************************/10981099static void stli_close(struct tty_struct *tty, struct file *filp)1100{1101+ stlibrd_t *brdp;1102+ stliport_t *portp;1103+ unsigned long flags;000011041105 portp = tty->driver_data;1106+ if (portp == NULL)1107 return;11081109+ spin_lock_irqsave(&stli_lock, flags);01110 if (tty_hung_up_p(filp)) {1111+ spin_unlock_irqrestore(&stli_lock, flags);1112 return;1113 }1114 if ((tty->count == 1) && (portp->refcount != 1))1115 portp->refcount = 1;1116 if (portp->refcount-- > 1) {1117+ spin_unlock_irqrestore(&stli_lock, flags);1118 return;1119 }1120···1134 if (tty == stli_txcooktty)1135 stli_flushchars(tty);1136 tty->closing = 1;1137+ spin_unlock_irqrestore(&stli_lock, flags);1138+1139 if (portp->closing_wait != ASYNC_CLOSING_WAIT_NONE)1140 tty_wait_until_sent(tty, portp->closing_wait);1141···1157 stli_flushbuffer(tty);11581159 tty->closing = 0;1160+ portp->tty = NULL;11611162 if (portp->openwaitcnt) {1163 if (portp->close_delay)···11671168 portp->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING);1169 wake_up_interruptible(&portp->close_wait);01170}11711172/*****************************************************************************/···11821183static int stli_initopen(stlibrd_t *brdp, stliport_t *portp)1184{1185+ struct tty_struct *tty;1186+ asynotify_t nt;1187+ asyport_t aport;1188+ int rc;000011891190 if ((rc = stli_rawopen(brdp, portp, 0, 1)) < 0)1191+ return rc;11921193 memset(&nt, 0, sizeof(asynotify_t));1194 nt.data = (DT_TXLOW | DT_TXEMPTY | DT_RXBUSY | DT_RXBREAK);1195 nt.signal = SG_DCD;1196 if ((rc = stli_cmdwait(brdp, portp, A_SETNOTIFY, &nt,1197 sizeof(asynotify_t), 0)) < 0)1198+ return rc;11991200 tty = portp->tty;1201+ if (tty == NULL)1202+ return -ENODEV;1203 stli_mkasyport(portp, &aport, tty->termios);1204 if ((rc = stli_cmdwait(brdp, portp, A_SETPORT, &aport,1205 sizeof(asyport_t), 0)) < 0)1206+ return rc;12071208 set_bit(ST_GETSIGS, &portp->state);1209 if ((rc = stli_cmdwait(brdp, portp, A_GETSIGNALS, &portp->asig,1210 sizeof(asysigs_t), 1)) < 0)1211+ return rc;1212 if (test_and_clear_bit(ST_GETSIGS, &portp->state))1213 portp->sigs = stli_mktiocm(portp->asig.sigvalue);1214 stli_mkasysigs(&portp->asig, 1, 1);1215 if ((rc = stli_cmdwait(brdp, portp, A_SETSIGNALS, &portp->asig,1216 sizeof(asysigs_t), 0)) < 0)1217+ return rc;12181219+ return 0;1220}12211222/*****************************************************************************/···12341235static int stli_rawopen(stlibrd_t *brdp, stliport_t *portp, unsigned long arg, int wait)1236{1237+ cdkhdr_t __iomem *hdrp;1238+ cdkctrl_t __iomem *cp;1239+ unsigned char __iomem *bits;1240+ unsigned long flags;1241+ int rc;0000012421243/*1244 * Send a message to the slave to open this port.1245 */0012461247/*1248 * Slave is already closing this port. This can happen if a hangup···1260 wait_event_interruptible(portp->raw_wait,1261 !test_bit(ST_CLOSING, &portp->state));1262 if (signal_pending(current)) {01263 return -ERESTARTSYS;1264 }1265···1269 * memory. Once the message is in set the service bits to say that1270 * this port wants service.1271 */1272+ spin_lock_irqsave(&brd_lock, flags);1273 EBRDENABLE(brdp);1274+ cp = &((cdkasy_t __iomem *) EBRDGETMEMPTR(brdp, portp->addr))->ctrl;1275+ writel(arg, &cp->openarg);1276+ writeb(1, &cp->open);1277+ hdrp = (cdkhdr_t __iomem *) EBRDGETMEMPTR(brdp, CDK_CDKADDR);1278+ bits = ((unsigned char __iomem *) hdrp) + brdp->slaveoffset +1279 portp->portidx;1280+ writeb(readb(bits) | portp->portbit, bits);1281 EBRDDISABLE(brdp);12821283 if (wait == 0) {1284+ spin_unlock_irqrestore(&brd_lock, flags);1285+ return 0;1286 }12871288/*···1290 */1291 rc = 0;1292 set_bit(ST_OPENING, &portp->state);1293+ spin_unlock_irqrestore(&brd_lock, flags);1294+1295 wait_event_interruptible(portp->raw_wait,1296 !test_bit(ST_OPENING, &portp->state));1297 if (signal_pending(current))1298 rc = -ERESTARTSYS;012991300 if ((rc == 0) && (portp->rc != 0))1301 rc = -EIO;1302+ return rc;1303}13041305/*****************************************************************************/···13111312static int stli_rawclose(stlibrd_t *brdp, stliport_t *portp, unsigned long arg, int wait)1313{1314+ cdkhdr_t __iomem *hdrp;1315+ cdkctrl_t __iomem *cp;1316+ unsigned char __iomem *bits;1317+ unsigned long flags;1318+ int rc;0000000013191320/*1321 * Slave is already closing this port. This can happen if a hangup···1333 wait_event_interruptible(portp->raw_wait,1334 !test_bit(ST_CLOSING, &portp->state));1335 if (signal_pending(current)) {01336 return -ERESTARTSYS;1337 }1338 }···1341/*1342 * Write the close command into shared memory.1343 */1344+ spin_lock_irqsave(&brd_lock, flags);1345 EBRDENABLE(brdp);1346+ cp = &((cdkasy_t __iomem *) EBRDGETMEMPTR(brdp, portp->addr))->ctrl;1347+ writel(arg, &cp->closearg);1348+ writeb(1, &cp->close);1349+ hdrp = (cdkhdr_t __iomem *) EBRDGETMEMPTR(brdp, CDK_CDKADDR);1350+ bits = ((unsigned char __iomem *) hdrp) + brdp->slaveoffset +1351 portp->portidx;1352+ writeb(readb(bits) |portp->portbit, bits);1353 EBRDDISABLE(brdp);13541355 set_bit(ST_CLOSING, &portp->state);1356+ spin_unlock_irqrestore(&brd_lock, flags);1357+1358+ if (wait == 0)1359+ return 0;13601361/*1362 * Slave is in action, so now we must wait for the open acknowledgment···1366 !test_bit(ST_CLOSING, &portp->state));1367 if (signal_pending(current))1368 rc = -ERESTARTSYS;013691370 if ((rc == 0) && (portp->rc != 0))1371 rc = -EIO;1372+ return rc;1373}13741375/*****************************************************************************/···13841385static int stli_cmdwait(stlibrd_t *brdp, stliport_t *portp, unsigned long cmd, void *arg, int size, int copyback)1386{00000000001387 wait_event_interruptible(portp->raw_wait,1388 !test_bit(ST_CMDING, &portp->state));1389+ if (signal_pending(current))01390 return -ERESTARTSYS;013911392 stli_sendcmd(brdp, portp, cmd, arg, size, copyback);13931394 wait_event_interruptible(portp->raw_wait,1395 !test_bit(ST_CMDING, &portp->state));1396+ if (signal_pending(current))01397 return -ERESTARTSYS;0013981399 if (portp->rc != 0)1400+ return -EIO;1401+ return 0;1402}14031404/*****************************************************************************/···14251426static int stli_setport(stliport_t *portp)1427{1428+ stlibrd_t *brdp;1429+ asyport_t aport;14301431+ if (portp == NULL)1432+ return -ENODEV;1433+ if (portp->tty == NULL)1434+ return -ENODEV;1435+ if (portp->brdnr < 0 && portp->brdnr >= stli_nrbrds)1436+ return -ENODEV;00001437 brdp = stli_brds[portp->brdnr];1438+ if (brdp == NULL)1439+ return -ENODEV;14401441 stli_mkasyport(portp, &aport, portp->tty->termios);1442 return(stli_cmdwait(brdp, portp, A_SETPORT, &aport, sizeof(asyport_t), 0));···14551456static int stli_waitcarrier(stlibrd_t *brdp, stliport_t *portp, struct file *filp)1457{1458+ unsigned long flags;1459+ int rc, doclocal;0000014601461 rc = 0;1462 doclocal = 0;···1469 if (portp->tty->termios->c_cflag & CLOCAL)1470 doclocal++;14711472+ spin_lock_irqsave(&stli_lock, flags);01473 portp->openwaitcnt++;1474 if (! tty_hung_up_p(filp))1475 portp->refcount--;1476+ spin_unlock_irqrestore(&stli_lock, flags);14771478 for (;;) {1479 stli_mkasysigs(&portp->asig, 1, 1);···1499 interruptible_sleep_on(&portp->open_wait);1500 }15011502+ spin_lock_irqsave(&stli_lock, flags);1503 if (! tty_hung_up_p(filp))1504 portp->refcount++;1505 portp->openwaitcnt--;1506+ spin_unlock_irqrestore(&stli_lock, flags);15071508+ return rc;1509}15101511/*****************************************************************************/···15171518static int stli_write(struct tty_struct *tty, const unsigned char *buf, int count)1519{1520+ cdkasy_t __iomem *ap;1521+ cdkhdr_t __iomem *hdrp;1522+ unsigned char __iomem *bits;1523+ unsigned char __iomem *shbuf;1524+ unsigned char *chbuf;1525+ stliport_t *portp;1526+ stlibrd_t *brdp;1527+ unsigned int len, stlen, head, tail, size;1528+ unsigned long flags;1529000000001530 if (tty == stli_txcooktty)1531 stli_flushchars(tty);1532 portp = tty->driver_data;1533+ if (portp == NULL)1534+ return 0;1535 if ((portp->brdnr < 0) || (portp->brdnr >= stli_nrbrds))1536+ return 0;1537 brdp = stli_brds[portp->brdnr];1538+ if (brdp == NULL)1539+ return 0;1540 chbuf = (unsigned char *) buf;15411542/*1543 * All data is now local, shove as much as possible into shared memory.1544 */1545+ spin_lock_irqsave(&brd_lock, flags);01546 EBRDENABLE(brdp);1547+ ap = (cdkasy_t __iomem *) EBRDGETMEMPTR(brdp, portp->addr);1548+ head = (unsigned int) readw(&ap->txq.head);1549+ tail = (unsigned int) readw(&ap->txq.tail);1550+ if (tail != ((unsigned int) readw(&ap->txq.tail)))1551+ tail = (unsigned int) readw(&ap->txq.tail);1552 size = portp->txsize;1553 if (head >= tail) {1554 len = size - (head - tail) - 1;···15681569 len = MIN(len, count);1570 count = 0;1571+ shbuf = (char __iomem *) EBRDGETMEMPTR(brdp, portp->txoffset);15721573 while (len > 0) {1574 stlen = MIN(len, stlen);1575+ memcpy_toio(shbuf + head, chbuf, stlen);1576 chbuf += stlen;1577 len -= stlen;1578 count += stlen;···1583 }1584 }15851586+ ap = (cdkasy_t __iomem *) EBRDGETMEMPTR(brdp, portp->addr);1587+ writew(head, &ap->txq.head);1588 if (test_bit(ST_TXBUSY, &portp->state)) {1589+ if (readl(&ap->changed.data) & DT_TXEMPTY)1590+ writel(readl(&ap->changed.data) & ~DT_TXEMPTY, &ap->changed.data);1591 }1592+ hdrp = (cdkhdr_t __iomem *) EBRDGETMEMPTR(brdp, CDK_CDKADDR);1593+ bits = ((unsigned char __iomem *) hdrp) + brdp->slaveoffset +1594 portp->portidx;1595+ writeb(readb(bits) | portp->portbit, bits);1596 set_bit(ST_TXBUSY, &portp->state);1597 EBRDDISABLE(brdp);1598+ spin_unlock_irqrestore(&brd_lock, flags);015991600 return(count);1601}···16131614static void stli_putchar(struct tty_struct *tty, unsigned char ch)1615{0000001616 if (tty != stli_txcooktty) {1617+ if (stli_txcooktty != NULL)1618 stli_flushchars(stli_txcooktty);1619 stli_txcooktty = tty;1620 }···16401641static void stli_flushchars(struct tty_struct *tty)1642{1643+ cdkhdr_t __iomem *hdrp;1644+ unsigned char __iomem *bits;1645+ cdkasy_t __iomem *ap;1646+ struct tty_struct *cooktty;1647+ stliport_t *portp;1648+ stlibrd_t *brdp;1649+ unsigned int len, stlen, head, tail, size, count, cooksize;1650+ unsigned char *buf;1651+ unsigned char __iomem *shbuf;1652+ unsigned long flags;00016531654 cooksize = stli_txcooksize;1655 cooktty = stli_txcooktty;1656 stli_txcooksize = 0;1657 stli_txcookrealsize = 0;1658+ stli_txcooktty = NULL;16591660+ if (tty == NULL)1661 return;1662+ if (cooktty == NULL)1663 return;1664 if (tty != cooktty)1665 tty = cooktty;···1670 return;16711672 portp = tty->driver_data;1673+ if (portp == NULL)1674 return;1675 if ((portp->brdnr < 0) || (portp->brdnr >= stli_nrbrds))1676 return;1677 brdp = stli_brds[portp->brdnr];1678+ if (brdp == NULL)1679 return;16801681+ spin_lock_irqsave(&brd_lock, flags);01682 EBRDENABLE(brdp);16831684+ ap = (cdkasy_t __iomem *) EBRDGETMEMPTR(brdp, portp->addr);1685+ head = (unsigned int) readw(&ap->txq.head);1686+ tail = (unsigned int) readw(&ap->txq.tail);1687+ if (tail != ((unsigned int) readw(&ap->txq.tail)))1688+ tail = (unsigned int) readw(&ap->txq.tail);1689 size = portp->txsize;1690 if (head >= tail) {1691 len = size - (head - tail) - 1;···17031704 while (len > 0) {1705 stlen = MIN(len, stlen);1706+ memcpy_toio(shbuf + head, buf, stlen);1707 buf += stlen;1708 len -= stlen;1709 count += stlen;···1714 }1715 }17161717+ ap = (cdkasy_t __iomem *) EBRDGETMEMPTR(brdp, portp->addr);1718+ writew(head, &ap->txq.head);17191720 if (test_bit(ST_TXBUSY, &portp->state)) {1721+ if (readl(&ap->changed.data) & DT_TXEMPTY)1722+ writel(readl(&ap->changed.data) & ~DT_TXEMPTY, &ap->changed.data);1723 }1724+ hdrp = (cdkhdr_t __iomem *) EBRDGETMEMPTR(brdp, CDK_CDKADDR);1725+ bits = ((unsigned char __iomem *) hdrp) + brdp->slaveoffset +1726 portp->portidx;1727+ writeb(readb(bits) | portp->portbit, bits);1728 set_bit(ST_TXBUSY, &portp->state);17291730 EBRDDISABLE(brdp);1731+ spin_unlock_irqrestore(&brd_lock, flags);1732}17331734/*****************************************************************************/17351736static int stli_writeroom(struct tty_struct *tty)1737{1738+ cdkasyrq_t __iomem *rp;1739+ stliport_t *portp;1740+ stlibrd_t *brdp;1741+ unsigned int head, tail, len;1742+ unsigned long flags;17430000001744 if (tty == stli_txcooktty) {1745 if (stli_txcookrealsize != 0) {1746 len = stli_txcookrealsize - stli_txcooksize;1747+ return len;1748 }1749 }17501751 portp = tty->driver_data;1752+ if (portp == NULL)1753+ return 0;1754 if ((portp->brdnr < 0) || (portp->brdnr >= stli_nrbrds))1755+ return 0;1756 brdp = stli_brds[portp->brdnr];1757+ if (brdp == NULL)1758+ return 0;17591760+ spin_lock_irqsave(&brd_lock, flags);01761 EBRDENABLE(brdp);1762+ rp = &((cdkasy_t __iomem *) EBRDGETMEMPTR(brdp, portp->addr))->txq;1763+ head = (unsigned int) readw(&rp->head);1764+ tail = (unsigned int) readw(&rp->tail);1765+ if (tail != ((unsigned int) readw(&rp->tail)))1766+ tail = (unsigned int) readw(&rp->tail);1767 len = (head >= tail) ? (portp->txsize - (head - tail)) : (tail - head);1768 len--;1769 EBRDDISABLE(brdp);1770+ spin_unlock_irqrestore(&brd_lock, flags);17711772 if (tty == stli_txcooktty) {1773 stli_txcookrealsize = len;1774 len -= stli_txcooksize;1775 }1776+ return len;1777}17781779/*****************************************************************************/···17951796static int stli_charsinbuffer(struct tty_struct *tty)1797{1798+ cdkasyrq_t __iomem *rp;1799+ stliport_t *portp;1800+ stlibrd_t *brdp;1801+ unsigned int head, tail, len;1802+ unsigned long flags;18030000001804 if (tty == stli_txcooktty)1805 stli_flushchars(tty);1806 portp = tty->driver_data;1807+ if (portp == NULL)1808+ return 0;1809 if ((portp->brdnr < 0) || (portp->brdnr >= stli_nrbrds))1810+ return 0;1811 brdp = stli_brds[portp->brdnr];1812+ if (brdp == NULL)1813+ return 0;18141815+ spin_lock_irqsave(&brd_lock, flags);01816 EBRDENABLE(brdp);1817+ rp = &((cdkasy_t __iomem *) EBRDGETMEMPTR(brdp, portp->addr))->txq;1818+ head = (unsigned int) readw(&rp->head);1819+ tail = (unsigned int) readw(&rp->tail);1820+ if (tail != ((unsigned int) readw(&rp->tail)))1821+ tail = (unsigned int) readw(&rp->tail);1822 len = (head >= tail) ? (head - tail) : (portp->txsize - (tail - head));1823 if ((len == 0) && test_bit(ST_TXBUSY, &portp->state))1824 len = 1;1825 EBRDDISABLE(brdp);1826+ spin_unlock_irqrestore(&brd_lock, flags);18271828+ return len;1829}18301831/*****************************************************************************/···18431844static int stli_getserial(stliport_t *portp, struct serial_struct __user *sp)1845{1846+ struct serial_struct sio;1847+ stlibrd_t *brdp;000018481849 memset(&sio, 0, sizeof(struct serial_struct));1850 sio.type = PORT_UNKNOWN;···1863 sio.hub6 = 0;18641865 brdp = stli_brds[portp->brdnr];1866+ if (brdp != NULL)1867 sio.port = brdp->iobase;18681869 return copy_to_user(sp, &sio, sizeof(struct serial_struct)) ?···18801881static int stli_setserial(stliport_t *portp, struct serial_struct __user *sp)1882{1883+ struct serial_struct sio;1884+ int rc;000018851886 if (copy_from_user(&sio, sp, sizeof(struct serial_struct)))1887 return -EFAULT;···1894 (sio.close_delay != portp->close_delay) ||1895 ((sio.flags & ~ASYNC_USR_MASK) !=1896 (portp->flags & ~ASYNC_USR_MASK)))1897+ return -EPERM;1898 } 18991900 portp->flags = (portp->flags & ~ASYNC_USR_MASK) |···1905 portp->custom_divisor = sio.custom_divisor;19061907 if ((rc = stli_setport(portp)) < 0)1908+ return rc;1909+ return 0;1910}19111912/*****************************************************************************/···1917 stlibrd_t *brdp;1918 int rc;19191920+ if (portp == NULL)1921+ return -ENODEV;1922+ if (portp->brdnr < 0 || portp->brdnr >= stli_nrbrds)1923+ return 0;1924 brdp = stli_brds[portp->brdnr];1925+ if (brdp == NULL)1926+ return 0;1927 if (tty->flags & (1 << TTY_IO_ERROR))1928+ return -EIO;19291930 if ((rc = stli_cmdwait(brdp, portp, A_GETSIGNALS,1931 &portp->asig, sizeof(asysigs_t), 1)) < 0)1932+ return rc;19331934 return stli_mktiocm(portp->asig.sigvalue);1935}···1941 stlibrd_t *brdp;1942 int rts = -1, dtr = -1;19431944+ if (portp == NULL)1945+ return -ENODEV;1946+ if (portp->brdnr < 0 || portp->brdnr >= stli_nrbrds)1947+ return 0;1948 brdp = stli_brds[portp->brdnr];1949+ if (brdp == NULL)1950+ return 0;1951 if (tty->flags & (1 << TTY_IO_ERROR))1952+ return -EIO;19531954 if (set & TIOCM_RTS)1955 rts = 1;···19681969static int stli_ioctl(struct tty_struct *tty, struct file *file, unsigned int cmd, unsigned long arg)1970{1971+ stliport_t *portp;1972+ stlibrd_t *brdp;1973+ unsigned int ival;1974+ int rc;1975 void __user *argp = (void __user *)arg;197600000001977 portp = tty->driver_data;1978+ if (portp == NULL)1979+ return -ENODEV;1980+ if (portp->brdnr < 0 || portp->brdnr >= stli_nrbrds)1981+ return 0;1982 brdp = stli_brds[portp->brdnr];1983+ if (brdp == NULL)1984+ return 0;19851986 if ((cmd != TIOCGSERIAL) && (cmd != TIOCSSERIAL) &&1987 (cmd != COM_GETPORTSTATS) && (cmd != COM_CLRPORTSTATS)) {1988 if (tty->flags & (1 << TTY_IO_ERROR))1989+ return -EIO;1990 }19911992 rc = 0;···2040 break;2041 }20422043+ return rc;2044}20452046/*****************************************************************************/···20522053static void stli_settermios(struct tty_struct *tty, struct termios *old)2054{2055+ stliport_t *portp;2056+ stlibrd_t *brdp;2057+ struct termios *tiosp;2058+ asyport_t aport;20592060+ if (tty == NULL)00002061 return;2062 portp = tty->driver_data;2063+ if (portp == NULL)2064 return;2065+ if (portp->brdnr < 0 || portp->brdnr >= stli_nrbrds)2066 return;2067 brdp = stli_brds[portp->brdnr];2068+ if (brdp == NULL)2069 return;20702071 tiosp = tty->termios;···21022103static void stli_throttle(struct tty_struct *tty)2104{2105+ stliport_t *portp = tty->driver_data;2106+ if (portp == NULL)000002107 return;00002108 set_bit(ST_RXSTOP, &portp->state);2109}2110···21272128static void stli_unthrottle(struct tty_struct *tty)2129{2130+ stliport_t *portp = tty->driver_data;2131+ if (portp == NULL)000002132 return;00002133 clear_bit(ST_RXSTOP, &portp->state);2134}21352136/*****************************************************************************/21372138/*2139+ * Stop the transmitter.02140 */21412142static void stli_stop(struct tty_struct *tty)2143{0000000000000000000000002144}21452146/*****************************************************************************/21472148/*2149+ * Start the transmitter again.2150 */21512152static void stli_start(struct tty_struct *tty)2153{0000000000000000000000002154}21552156/*****************************************************************************/···22242225static void stli_dohangup(void *arg)2226{2227+ stliport_t *portp = (stliport_t *) arg;2228+ if (portp->tty != NULL) {2229+ tty_hangup(portp->tty);00000000000002230 }2231}2232···22542255static void stli_hangup(struct tty_struct *tty)2256{2257+ stliport_t *portp;2258+ stlibrd_t *brdp;2259+ unsigned long flags;22600000002261 portp = tty->driver_data;2262+ if (portp == NULL)2263 return;2264+ if (portp->brdnr < 0 || portp->brdnr >= stli_nrbrds)2265 return;2266 brdp = stli_brds[portp->brdnr];2267+ if (brdp == NULL)2268 return;22692270 portp->flags &= ~ASYNC_INITIALIZED;22712272+ if (!test_bit(ST_CLOSING, &portp->state))002273 stli_rawclose(brdp, portp, 0, 0);2274+2275+ spin_lock_irqsave(&stli_lock, flags);2276 if (tty->termios->c_cflag & HUPCL) {2277 stli_mkasysigs(&portp->asig, 0, 0);2278 if (test_bit(ST_CMDING, &portp->state)) {···2290 &portp->asig, sizeof(asysigs_t), 0);2291 }2292 }022932294 clear_bit(ST_TXBUSY, &portp->state);2295 clear_bit(ST_RXSTOP, &portp->state);2296 set_bit(TTY_IO_ERROR, &tty->flags);2297+ portp->tty = NULL;2298 portp->flags &= ~ASYNC_NORMAL_ACTIVE;2299 portp->refcount = 0;2300+ spin_unlock_irqrestore(&stli_lock, flags);2301+2302 wake_up_interruptible(&portp->open_wait);2303}2304···23122313static void stli_flushbuffer(struct tty_struct *tty)2314{2315+ stliport_t *portp;2316+ stlibrd_t *brdp;2317+ unsigned long ftype, flags;23180000002319 portp = tty->driver_data;2320+ if (portp == NULL)2321 return;2322+ if (portp->brdnr < 0 || portp->brdnr >= stli_nrbrds)2323 return;2324 brdp = stli_brds[portp->brdnr];2325+ if (brdp == NULL)2326 return;23272328+ spin_lock_irqsave(&brd_lock, flags);02329 if (tty == stli_txcooktty) {2330+ stli_txcooktty = NULL;2331 stli_txcooksize = 0;2332 stli_txcookrealsize = 0;2333 }···2346 ftype |= FLUSHRX;2347 clear_bit(ST_DOFLUSHRX, &portp->state);2348 }2349+ __stli_sendcmd(brdp, portp, A_FLUSH, &ftype, sizeof(u32), 0);02350 }2351+ spin_unlock_irqrestore(&brd_lock, flags);2352+ tty_wakeup(tty);00002353}23542355/*****************************************************************************/···2364 stlibrd_t *brdp;2365 stliport_t *portp;2366 long arg;023670000002368 portp = tty->driver_data;2369+ if (portp == NULL)2370 return;2371+ if (portp->brdnr < 0 || portp->brdnr >= stli_nrbrds)2372 return;2373 brdp = stli_brds[portp->brdnr];2374+ if (brdp == NULL)2375 return;000000023762377 arg = (state == -1) ? BREAKON : BREAKOFF;2378 stli_cmdwait(brdp, portp, A_BREAK, &arg, sizeof(long), 0);0000002379}23802381/*****************************************************************************/23822383static void stli_waituntilsent(struct tty_struct *tty, int timeout)2384{2385+ stliport_t *portp;2386+ unsigned long tend;23872388+ if (tty == NULL)00002389 return;2390 portp = tty->driver_data;2391+ if (portp == NULL)2392 return;23932394 if (timeout == 0)···2436 stliport_t *portp;2437 asyctrl_t actrl;24380000002439 portp = tty->driver_data;2440+ if (portp == NULL)2441 return;2442+ if (portp->brdnr < 0 || portp->brdnr >= stli_nrbrds)2443 return;2444 brdp = stli_brds[portp->brdnr];2445+ if (brdp == NULL)2446 return;24472448 memset(&actrl, 0, sizeof(asyctrl_t));···2460 actrl.txctrl = CT_SENDCHR;2461 actrl.tximdch = ch;2462 }02463 stli_cmdwait(brdp, portp, A_PORTCTRL, &actrl, sizeof(asyctrl_t), 0);2464}2465···24762477static int stli_portinfo(stlibrd_t *brdp, stliport_t *portp, int portnr, char *pos)2478{2479+ char *sp, *uart;2480+ int rc, cnt;24812482 rc = stli_portcmdstats(portp);24832484 uart = "UNKNOWN";2485 if (brdp->state & BST_STARTED) {2486 switch (stli_comstats.hwid) {2487+ case 0: uart = "2681"; break;2488+ case 1: uart = "SC26198"; break;2489+ default:uart = "CD1400"; break;2490 }2491 }2492···25372538static int stli_readproc(char *page, char **start, off_t off, int count, int *eof, void *data)2539{2540+ stlibrd_t *brdp;2541+ stliport_t *portp;2542+ int brdnr, portnr, totalport;2543+ int curoff, maxoff;2544+ char *pos;00000025452546 pos = page;2547 totalport = 0;···2568 */2569 for (brdnr = 0; (brdnr < stli_nrbrds); brdnr++) {2570 brdp = stli_brds[brdnr];2571+ if (brdp == NULL)2572 continue;2573 if (brdp->state == 0)2574 continue;···2583 for (portnr = 0; (portnr < brdp->nrports); portnr++,2584 totalport++) {2585 portp = brdp->ports[portnr];2586+ if (portp == NULL)2587 continue;2588 if (off >= (curoff += MAXLINE))2589 continue;···2610 * a poll routine that does not have user context. Therefore you cannot2611 * copy back directly into user space, or to the kernel stack of a2612 * process. This routine does not sleep, so can be called from anywhere.2613+ *2614+ * The caller must hold the brd_lock (see also stli_sendcmd the usual2615+ * entry point)2616 */26172618+static void __stli_sendcmd(stlibrd_t *brdp, stliport_t *portp, unsigned long cmd, void *arg, int size, int copyback)2619{2620+ cdkhdr_t __iomem *hdrp;2621+ cdkctrl_t __iomem *cp;2622+ unsigned char __iomem *bits;2623+ unsigned long flags;26242625+ spin_lock_irqsave(&brd_lock, flags);000000026262627 if (test_bit(ST_CMDING, &portp->state)) {2628 printk(KERN_ERR "STALLION: command already busy, cmd=%x!\n",2629 (int) cmd);2630+ spin_unlock_irqrestore(&brd_lock, flags);2631 return;2632 }26332634 EBRDENABLE(brdp);2635+ cp = &((cdkasy_t __iomem *) EBRDGETMEMPTR(brdp, portp->addr))->ctrl;2636 if (size > 0) {2637+ memcpy_toio((void __iomem *) &(cp->args[0]), arg, size);2638 if (copyback) {2639 portp->argp = arg;2640 portp->argsize = size;2641 }2642 }2643+ writel(0, &cp->status);2644+ writel(cmd, &cp->cmd);2645+ hdrp = (cdkhdr_t __iomem *) EBRDGETMEMPTR(brdp, CDK_CDKADDR);2646+ bits = ((unsigned char __iomem *) hdrp) + brdp->slaveoffset +2647 portp->portidx;2648+ writeb(readb(bits) | portp->portbit, bits);2649 set_bit(ST_CMDING, &portp->state);2650 EBRDDISABLE(brdp);2651+ spin_unlock_irqrestore(&brd_lock, flags);2652+}2653+2654+static void stli_sendcmd(stlibrd_t *brdp, stliport_t *portp, unsigned long cmd, void *arg, int size, int copyback)2655+{2656+ unsigned long flags;2657+2658+ spin_lock_irqsave(&brd_lock, flags);2659+ __stli_sendcmd(brdp, portp, cmd, arg, size, copyback);2660+ spin_unlock_irqrestore(&brd_lock, flags);2661}26622663/*****************************************************************************/···26672668static void stli_read(stlibrd_t *brdp, stliport_t *portp)2669{2670+ cdkasyrq_t __iomem *rp;2671+ char __iomem *shbuf;2672 struct tty_struct *tty;2673+ unsigned int head, tail, size;2674+ unsigned int len, stlen;0000026752676 if (test_bit(ST_RXSTOP, &portp->state))2677 return;2678 tty = portp->tty;2679+ if (tty == NULL)2680 return;26812682+ rp = &((cdkasy_t __iomem *) EBRDGETMEMPTR(brdp, portp->addr))->rxq;2683+ head = (unsigned int) readw(&rp->head);2684+ if (head != ((unsigned int) readw(&rp->head)))2685+ head = (unsigned int) readw(&rp->head);2686+ tail = (unsigned int) readw(&rp->tail);2687 size = portp->rxsize;2688 if (head >= tail) {2689 len = head - tail;···2699 }27002701 len = tty_buffer_request_room(tty, len);2702+2703+ shbuf = (char __iomem *) EBRDGETMEMPTR(brdp, portp->rxoffset);27042705 while (len > 0) {2706+ unsigned char *cptr;2707+2708 stlen = MIN(len, stlen);2709+ tty_prepare_flip_string(tty, &cptr, stlen);2710+ memcpy_fromio(cptr, shbuf + tail, stlen);2711 len -= stlen;2712 tail += stlen;2713 if (tail >= size) {···2712 stlen = head;2713 }2714 }2715+ rp = &((cdkasy_t __iomem *) EBRDGETMEMPTR(brdp, portp->addr))->rxq;2716+ writew(tail, &rp->tail);27172718 if (head != tail)2719 set_bit(ST_RXING, &portp->state);···2729 * difficult to deal with them here.2730 */27312732+static void stli_dodelaycmd(stliport_t *portp, cdkctrl_t __iomem *cp)2733{2734+ int cmd;27352736 if (test_bit(ST_DOSIGS, &portp->state)) {2737 if (test_bit(ST_DOFLUSHTX, &portp->state) &&···2746 clear_bit(ST_DOFLUSHTX, &portp->state);2747 clear_bit(ST_DOFLUSHRX, &portp->state);2748 clear_bit(ST_DOSIGS, &portp->state);2749+ memcpy_toio((void __iomem *) &(cp->args[0]), (void *) &portp->asig,2750 sizeof(asysigs_t));2751+ writel(0, &cp->status);2752+ writel(cmd, &cp->cmd);2753 set_bit(ST_CMDING, &portp->state);2754 } else if (test_bit(ST_DOFLUSHTX, &portp->state) ||2755 test_bit(ST_DOFLUSHRX, &portp->state)) {···2757 cmd |= ((test_bit(ST_DOFLUSHRX, &portp->state)) ? FLUSHRX : 0);2758 clear_bit(ST_DOFLUSHTX, &portp->state);2759 clear_bit(ST_DOFLUSHRX, &portp->state);2760+ memcpy_toio((void __iomem *) &(cp->args[0]), (void *) &cmd, sizeof(int));2761+ writel(0, &cp->status);2762+ writel(A_FLUSH, &cp->cmd);2763 set_bit(ST_CMDING, &portp->state);2764 }2765}···27792780static int stli_hostcmd(stlibrd_t *brdp, stliport_t *portp)2781{2782+ cdkasy_t __iomem *ap;2783+ cdkctrl_t __iomem *cp;2784+ struct tty_struct *tty;2785+ asynotify_t nt;2786+ unsigned long oldsigs;2787+ int rc, donerx;27882789+ ap = (cdkasy_t __iomem *) EBRDGETMEMPTR(brdp, portp->addr);000002790 cp = &ap->ctrl;27912792/*2793 * Check if we are waiting for an open completion message.2794 */2795 if (test_bit(ST_OPENING, &portp->state)) {2796+ rc = readl(&cp->openarg);2797+ if (readb(&cp->open) == 0 && rc != 0) {2798 if (rc > 0)2799 rc--;2800+ writel(0, &cp->openarg);2801 portp->rc = rc;2802 clear_bit(ST_OPENING, &portp->state);2803 wake_up_interruptible(&portp->raw_wait);···2813 * Check if we are waiting for a close completion message.2814 */2815 if (test_bit(ST_CLOSING, &portp->state)) {2816+ rc = (int) readl(&cp->closearg);2817+ if (readb(&cp->close) == 0 && rc != 0) {2818 if (rc > 0)2819 rc--;2820+ writel(0, &cp->closearg);2821 portp->rc = rc;2822 clear_bit(ST_CLOSING, &portp->state);2823 wake_up_interruptible(&portp->raw_wait);···2829 * need to copy out the command results associated with this command.2830 */2831 if (test_bit(ST_CMDING, &portp->state)) {2832+ rc = readl(&cp->status);2833+ if (readl(&cp->cmd) == 0 && rc != 0) {2834 if (rc > 0)2835 rc--;2836+ if (portp->argp != NULL) {2837+ memcpy_fromio(portp->argp, (void __iomem *) &(cp->args[0]),2838 portp->argsize);2839+ portp->argp = NULL;2840 }2841+ writel(0, &cp->status);2842 portp->rc = rc;2843 clear_bit(ST_CMDING, &portp->state);2844 stli_dodelaycmd(portp, cp);···2877 if (nt.data & DT_TXEMPTY)2878 clear_bit(ST_TXBUSY, &portp->state);2879 if (nt.data & (DT_TXEMPTY | DT_TXLOW)) {2880+ if (tty != NULL) {2881+ tty_wakeup(tty);2882+ EBRDENABLE(brdp);0002883 wake_up_interruptible(&tty->write_wait);2884 }2885 }28862887 if ((nt.data & DT_RXBREAK) && (portp->rxmarkmsk & BRKINT)) {2888+ if (tty != NULL) {2889 tty_insert_flip_char(tty, 0, TTY_BREAK);2890 if (portp->flags & ASYNC_SAK) {2891 do_SAK(tty);···2932 * at the cdk header structure.2933 */29342935+static void stli_brdpoll(stlibrd_t *brdp, cdkhdr_t __iomem *hdrp)2936{2937+ stliport_t *portp;2938+ unsigned char hostbits[(STL_MAXCHANS / 8) + 1];2939+ unsigned char slavebits[(STL_MAXCHANS / 8) + 1];2940+ unsigned char __iomem *slavep;2941+ int bitpos, bitat, bitsize;2942+ int channr, nrdevs, slavebitchange;29432944 bitsize = brdp->bitsize;2945 nrdevs = brdp->nrdevs;···2951 * 8 service bits at a time in the inner loop, so we can bypass2952 * the lot if none of them want service.2953 */2954+ memcpy_fromio(&hostbits[0], (((unsigned char __iomem *) hdrp) + brdp->hostoffset),2955 bitsize);29562957 memset(&slavebits[0], 0, bitsize);···2978 * service may initiate more slave requests.2979 */2980 if (slavebitchange) {2981+ hdrp = (cdkhdr_t __iomem *) EBRDGETMEMPTR(brdp, CDK_CDKADDR);2982+ slavep = ((unsigned char __iomem *) hdrp) + brdp->slaveoffset;2983 for (bitpos = 0; (bitpos < bitsize); bitpos++) {2984+ if (readb(slavebits + bitpos))2985+ writeb(readb(slavep + bitpos) & ~slavebits[bitpos], slavebits + bitpos);2986 }2987 }2988}···30003001static void stli_poll(unsigned long arg)3002{3003+ cdkhdr_t __iomem *hdrp;3004+ stlibrd_t *brdp;3005+ int brdnr;30063007 stli_timerlist.expires = STLI_TIMEOUT;3008 add_timer(&stli_timerlist);···3012 */3013 for (brdnr = 0; (brdnr < stli_nrbrds); brdnr++) {3014 brdp = stli_brds[brdnr];3015+ if (brdp == NULL)3016 continue;3017 if ((brdp->state & BST_STARTED) == 0)3018 continue;30193020+ spin_lock(&brd_lock);3021 EBRDENABLE(brdp);3022+ hdrp = (cdkhdr_t __iomem *) EBRDGETMEMPTR(brdp, CDK_CDKADDR);3023+ if (readb(&hdrp->hostreq))3024 stli_brdpoll(brdp, hdrp);3025 EBRDDISABLE(brdp);3026+ spin_unlock(&brd_lock);3027 }3028}3029···30343035static void stli_mkasyport(stliport_t *portp, asyport_t *pp, struct termios *tiosp)3036{000003037 memset(pp, 0, sizeof(asyport_t));30383039/*···31573158static void stli_mkasysigs(asysigs_t *sp, int dtr, int rts)3159{000003160 memset(sp, 0, sizeof(asysigs_t));3161 if (dtr >= 0) {3162 sp->signal |= SG_DTR;···31823183static long stli_mktiocm(unsigned long sigvalue)3184{3185+ long tiocm = 0;0000003186 tiocm |= ((sigvalue & SG_DCD) ? TIOCM_CD : 0);3187 tiocm |= ((sigvalue & SG_CTS) ? TIOCM_CTS : 0);3188 tiocm |= ((sigvalue & SG_RI) ? TIOCM_RI : 0);···3209{3210 stliport_t *portp;3211 int i, panelnr, panelport;000032123213 for (i = 0, panelnr = 0, panelport = 0; (i < brdp->nrports); i++) {3214 portp = kzalloc(sizeof(stliport_t), GFP_KERNEL);···3240 brdp->ports[i] = portp;3241 }32423243+ return 0;3244}32453246/*****************************************************************************/···3252static void stli_ecpinit(stlibrd_t *brdp)3253{3254 unsigned long memconf;000032553256 outb(ECP_ATSTOP, (brdp->iobase + ECP_ATCONFR));3257 udelay(10);···32703271static void stli_ecpenable(stlibrd_t *brdp)3272{ 0003273 outb(ECP_ATENABLE, (brdp->iobase + ECP_ATCONFR));3274}3275···32803281static void stli_ecpdisable(stlibrd_t *brdp)3282{ 0003283 outb(ECP_ATDISABLE, (brdp->iobase + ECP_ATCONFR));3284}3285···32903291static char *stli_ecpgetmemptr(stlibrd_t *brdp, unsigned long offset, int line)3292{ 3293+ void *ptr;3294+ unsigned char val;0000032953296 if (offset > brdp->memsize) {3297 printk(KERN_ERR "STALLION: shared memory pointer=%x out of "···33163317static void stli_ecpreset(stlibrd_t *brdp)3318{ 00003319 outb(ECP_ATSTOP, (brdp->iobase + ECP_ATCONFR));3320 udelay(10);3321 outb(ECP_ATDISABLE, (brdp->iobase + ECP_ATCONFR));···33303331static void stli_ecpintr(stlibrd_t *brdp)3332{ 0003333 outb(0x1, brdp->iobase);3334}3335···3345static void stli_ecpeiinit(stlibrd_t *brdp)3346{3347 unsigned long memconf;000033483349 outb(0x1, (brdp->iobase + ECP_EIBRDENAB));3350 outb(ECP_EISTOP, (brdp->iobase + ECP_EICONFR));···3382{ 3383 void *ptr;3384 unsigned char val;0000033853386 if (offset > brdp->memsize) {3387 printk(KERN_ERR "STALLION: shared memory pointer=%x out of "···34373438static char *stli_ecpmcgetmemptr(stlibrd_t *brdp, unsigned long offset, int line)3439{ 3440+ void *ptr;3441+ unsigned char val;34423443 if (offset > brdp->memsize) {3444 printk(KERN_ERR "STALLION: shared memory pointer=%x out of "···34723473static void stli_ecppciinit(stlibrd_t *brdp)3474{00003475 outb(ECP_PCISTOP, (brdp->iobase + ECP_PCICONFR));3476 udelay(10);3477 outb(0, (brdp->iobase + ECP_PCICONFR));···3488{ 3489 void *ptr;3490 unsigned char val;0000034913492 if (offset > brdp->memsize) {3493 printk(KERN_ERR "STALLION: shared memory pointer=%x out of "···3528{3529 unsigned long memconf;353000003531 outb(ONB_ATSTOP, (brdp->iobase + ONB_ATCONFR));3532 udelay(10);3533 outb(ONB_ATDISABLE, (brdp->iobase + ONB_ATCONFR));···35473548static void stli_onbenable(stlibrd_t *brdp)3549{ 0003550 outb((brdp->enabval | ONB_ATENABLE), (brdp->iobase + ONB_ATCONFR));3551}3552···35573558static void stli_onbdisable(stlibrd_t *brdp)3559{ 0003560 outb((brdp->enabval | ONB_ATDISABLE), (brdp->iobase + ONB_ATCONFR));3561}3562···3568static char *stli_onbgetmemptr(stlibrd_t *brdp, unsigned long offset, int line)3569{ 3570 void *ptr;0000035713572 if (offset > brdp->memsize) {3573 printk(KERN_ERR "STALLION: shared memory pointer=%x out of "···35893590static void stli_onbreset(stlibrd_t *brdp)3591{ 000003592 outb(ONB_ATSTOP, (brdp->iobase + ONB_ATCONFR));3593 udelay(10);3594 outb(ONB_ATDISABLE, (brdp->iobase + ONB_ATCONFR));···3609static void stli_onbeinit(stlibrd_t *brdp)3610{3611 unsigned long memconf;000036123613 outb(0x1, (brdp->iobase + ONB_EIBRDENAB));3614 outb(ONB_EISTOP, (brdp->iobase + ONB_EICONFR));···36323633static void stli_onbeenable(stlibrd_t *brdp)3634{ 0003635 outb(ONB_EIENABLE, (brdp->iobase + ONB_EICONFR));3636}3637···36423643static void stli_onbedisable(stlibrd_t *brdp)3644{ 0003645 outb(ONB_EIDISABLE, (brdp->iobase + ONB_EICONFR));3646}3647···36523653static char *stli_onbegetmemptr(stlibrd_t *brdp, unsigned long offset, int line)3654{ 3655+ void *ptr;3656+ unsigned char val;0000036573658 if (offset > brdp->memsize) {3659 printk(KERN_ERR "STALLION: shared memory pointer=%x out of "···36813682static void stli_onbereset(stlibrd_t *brdp)3683{ 000003684 outb(ONB_EISTOP, (brdp->iobase + ONB_EICONFR));3685 udelay(10);3686 outb(ONB_EIDISABLE, (brdp->iobase + ONB_EICONFR));···37003701static void stli_bbyinit(stlibrd_t *brdp)3702{000003703 outb(BBY_ATSTOP, (brdp->iobase + BBY_ATCONFR));3704 udelay(10);3705 outb(0, (brdp->iobase + BBY_ATCONFR));···37173718static char *stli_bbygetmemptr(stlibrd_t *brdp, unsigned long offset, int line)3719{ 3720+ void *ptr;3721+ unsigned char val;37223723+ BUG_ON(offset > brdp->memsize);00037243725+ ptr = brdp->membase + (offset % BBY_PAGESIZE);3726+ val = (unsigned char) (offset / BBY_PAGESIZE);000000003727 outb(val, (brdp->iobase + BBY_ATCONFR));3728 return(ptr);3729}···37433744static void stli_bbyreset(stlibrd_t *brdp)3745{ 000003746 outb(BBY_ATSTOP, (brdp->iobase + BBY_ATCONFR));3747 udelay(10);3748 outb(0, (brdp->iobase + BBY_ATCONFR));···37623763static void stli_stalinit(stlibrd_t *brdp)3764{000003765 outb(0x1, brdp->iobase);3766 mdelay(1000);3767}···37753776static char *stli_stalgetmemptr(stlibrd_t *brdp, unsigned long offset, int line)3777{ 3778+ BUG_ON(offset > brdp->memsize);3779+ return brdp->membase + (offset % STAL_PAGESIZE);000000000000003780}37813782/*****************************************************************************/37833784static void stli_stalreset(stlibrd_t *brdp)3785{ 3786+ u32 __iomem *vecp;37873788+ vecp = (u32 __iomem *) (brdp->membase + 0x30);3789+ writel(0xffff0000, vecp);00003790 outb(0, brdp->iobase);3791 mdelay(1000);3792}···38183819static int stli_initecp(stlibrd_t *brdp)3820{3821+ cdkecpsig_t sig;3822+ cdkecpsig_t __iomem *sigsp;3823+ unsigned int status, nxtid;3824+ char *name;3825+ int panelnr, nrports;000038263827 if (!request_region(brdp->iobase, brdp->iosize, "istallion"))3828 return -EIO;···3834 if ((brdp->iobase == 0) || (brdp->memaddr == 0))3835 {3836 release_region(brdp->iobase, brdp->iosize);3837+ return -ENODEV;3838 }38393840 brdp->iosize = ECP_IOSIZE;···39033904 default:3905 release_region(brdp->iobase, brdp->iosize);3906+ return -EINVAL;3907 }39083909/*···3915 EBRDINIT(brdp);39163917 brdp->membase = ioremap(brdp->memaddr, brdp->memsize);3918+ if (brdp->membase == NULL)3919 {3920 release_region(brdp->iobase, brdp->iosize);3921+ return -ENOMEM;3922 }39233924/*···3927 * this is, and what it is connected to it.3928 */3929 EBRDENABLE(brdp);3930+ sigsp = (cdkecpsig_t __iomem *) EBRDGETMEMPTR(brdp, CDK_SIGADDR);3931 memcpy(&sig, sigsp, sizeof(cdkecpsig_t));3932 EBRDDISABLE(brdp);39333934+ if (sig.magic != cpu_to_le32(ECP_MAGIC))0000000003935 {3936 release_region(brdp->iobase, brdp->iosize);3937+ return -ENODEV;3938 }39393940/*···396739683969 brdp->state |= BST_FOUND;3970+ return 0;3971}39723973/*****************************************************************************/···39793980static int stli_initonb(stlibrd_t *brdp)3981{3982+ cdkonbsig_t sig;3983+ cdkonbsig_t __iomem *sigsp;3984+ char *name;3985+ int i;000039863987/*3988 * Do a basic sanity check on the IO and memory addresses.3989 */3990+ if (brdp->iobase == 0 || brdp->memaddr == 0)3991+ return -ENODEV;39923993 brdp->iosize = ONB_IOSIZE;3994···4010 case BRD_ONBOARD2:4011 case BRD_ONBOARD2_32:4012 case BRD_ONBOARDRS:04013 brdp->memsize = ONB_MEMSIZE;4014 brdp->pagesize = ONB_ATPAGESIZE;4015 brdp->init = stli_onbinit;···4028 break;40294030 case BRD_ONBOARDE:04031 brdp->memsize = ONB_EIMEMSIZE;4032 brdp->pagesize = ONB_EIPAGESIZE;4033 brdp->init = stli_onbeinit;···4044 case BRD_BRUMBY4:4045 case BRD_BRUMBY8:4046 case BRD_BRUMBY16:04047 brdp->memsize = BBY_MEMSIZE;4048 brdp->pagesize = BBY_PAGESIZE;4049 brdp->init = stli_bbyinit;···4058 break;40594060 case BRD_STALLION:04061 brdp->memsize = STAL_MEMSIZE;4062 brdp->pagesize = STAL_PAGESIZE;4063 brdp->init = stli_stalinit;···40734074 default:4075 release_region(brdp->iobase, brdp->iosize);4076+ return -EINVAL;4077 }40784079/*···4085 EBRDINIT(brdp);40864087 brdp->membase = ioremap(brdp->memaddr, brdp->memsize);4088+ if (brdp->membase == NULL)4089 {4090 release_region(brdp->iobase, brdp->iosize);4091+ return -ENOMEM;4092 }40934094/*···4097 * this is, and how many ports.4098 */4099 EBRDENABLE(brdp);4100+ sigsp = (cdkonbsig_t __iomem *) EBRDGETMEMPTR(brdp, CDK_SIGADDR);4101+ memcpy_fromio(&sig, sigsp, sizeof(cdkonbsig_t));4102 EBRDDISABLE(brdp);41034104+ if (sig.magic0 != cpu_to_le16(ONB_MAGIC0) ||4105+ sig.magic1 != cpu_to_le16(ONB_MAGIC1) ||4106+ sig.magic2 != cpu_to_le16(ONB_MAGIC2) ||4107+ sig.magic3 != cpu_to_le16(ONB_MAGIC3))00004108 {4109 release_region(brdp->iobase, brdp->iosize);4110+ return -ENODEV;4111 }41124113/*···413241334134 brdp->state |= BST_FOUND;4135+ return 0;4136}41374138/*****************************************************************************/···41454146static int stli_startbrd(stlibrd_t *brdp)4147{4148+ cdkhdr_t __iomem *hdrp;4149+ cdkmem_t __iomem *memp;4150+ cdkasy_t __iomem *ap;4151+ unsigned long flags;4152+ stliport_t *portp;4153+ int portnr, nrdevs, i, rc = 0;4154+ u32 memoff;41554156+ spin_lock_irqsave(&brd_lock, flags);00000004157 EBRDENABLE(brdp);4158+ hdrp = (cdkhdr_t __iomem *) EBRDGETMEMPTR(brdp, CDK_CDKADDR);4159 nrdevs = hdrp->nrdevs;41604161#if 04162 printk("%s(%d): CDK version %d.%d.%d --> "4163 "nrdevs=%d memp=%x hostp=%x slavep=%x\n",4164+ __FILE__, __LINE__, readb(&hdrp->ver_release), readb(&hdrp->ver_modification),4165+ readb(&hdrp->ver_fix), nrdevs, (int) readl(&hdrp->memp), readl(&hdrp->hostp),4166+ readl(&hdrp->slavep));4167#endif41684169 if (nrdevs < (brdp->nrports + 1)) {···4181 brdp->hostoffset = hdrp->hostp - CDK_CDKADDR;4182 brdp->slaveoffset = hdrp->slavep - CDK_CDKADDR;4183 brdp->bitsize = (nrdevs + 7) / 8;4184+ memoff = readl(&hdrp->memp);4185+ if (memoff > brdp->memsize) {4186 printk(KERN_ERR "STALLION: corrupted shared memory region?\n");4187 rc = -EIO;4188 goto stli_donestartup;4189 }4190+ memp = (cdkmem_t __iomem *) EBRDGETMEMPTR(brdp, memoff);4191+ if (readw(&memp->dtype) != TYP_ASYNCTRL) {4192 printk(KERN_ERR "STALLION: no slave control device found\n");4193 goto stli_donestartup;4194 }···4200 * change pages while reading memory map.4201 */4202 for (i = 1, portnr = 0; (i < nrdevs); i++, portnr++, memp++) {4203+ if (readw(&memp->dtype) != TYP_ASYNC)4204 break;4205 portp = brdp->ports[portnr];4206+ if (portp == NULL)4207 break;4208 portp->devnr = i;4209+ portp->addr = readl(&memp->offset);4210 portp->reqbit = (unsigned char) (0x1 << (i * 8 / nrdevs));4211 portp->portidx = (unsigned char) (i / 8);4212 portp->portbit = (unsigned char) (0x1 << (i % 8));4213 }42144215+ writeb(0xff, &hdrp->slavereq);42164217/*4218 * For each port setup a local copy of the RX and TX buffer offsets···4221 */4222 for (i = 1, portnr = 0; (i < nrdevs); i++, portnr++) {4223 portp = brdp->ports[portnr];4224+ if (portp == NULL)4225 break;4226 if (portp->addr == 0)4227 break;4228+ ap = (cdkasy_t __iomem *) EBRDGETMEMPTR(brdp, portp->addr);4229+ if (ap != NULL) {4230+ portp->rxsize = readw(&ap->rxq.size);4231+ portp->txsize = readw(&ap->txq.size);4232+ portp->rxoffset = readl(&ap->rxq.offset);4233+ portp->txoffset = readl(&ap->txq.offset);4234 }4235 }42364237stli_donestartup:4238 EBRDDISABLE(brdp);4239+ spin_unlock_irqrestore(&brd_lock, flags);42404241 if (rc == 0)4242 brdp->state |= BST_STARTED;···4247 add_timer(&stli_timerlist);4248 }42494250+ return rc;4251}42524253/*****************************************************************************/···42584259static int __init stli_brdinit(stlibrd_t *brdp)4260{00004261 stli_brds[brdp->brdnr] = brdp;42624263 switch (brdp->brdtype) {···4289 case BRD_ECHPCI:4290 printk(KERN_ERR "STALLION: %s board type not supported in "4291 "this driver\n", stli_brdnames[brdp->brdtype]);4292+ return -ENODEV;4293 default:4294 printk(KERN_ERR "STALLION: board=%d is unknown board "4295 "type=%d\n", brdp->brdnr, brdp->brdtype);4296+ return -ENODEV;4297 }42984299 if ((brdp->state & BST_FOUND) == 0) {···4301 "io=%x mem=%x\n",4302 stli_brdnames[brdp->brdtype], brdp->brdnr,4303 brdp->iobase, (int) brdp->memaddr);4304+ return -ENODEV;4305 }43064307 stli_initports(brdp);···4309 "nrpanels=%d nrports=%d\n", stli_brdnames[brdp->brdtype],4310 brdp->brdnr, brdp->iobase, (int) brdp->memaddr,4311 brdp->nrpanels, brdp->nrports);4312+ return 0;4313}43144315/*****************************************************************************/···43214322static int stli_eisamemprobe(stlibrd_t *brdp)4323{4324+ cdkecpsig_t ecpsig, __iomem *ecpsigp;4325+ cdkonbsig_t onbsig, __iomem *onbsigp;4326 int i, foundit;000043274328/*4329 * First up we reset the board, to get it into a known state. There···4352 mdelay(1);4353 stli_onbeenable(brdp);4354 } else {4355+ return -ENODEV;4356 }43574358 foundit = 0;···4364 */4365 for (i = 0; (i < stli_eisamempsize); i++) {4366 brdp->memaddr = stli_eisamemprobeaddrs[i];04367 brdp->membase = ioremap(brdp->memaddr, brdp->memsize);4368+ if (brdp->membase == NULL)4369 continue;43704371 if (brdp->brdtype == BRD_ECPE) {4372+ ecpsigp = (cdkecpsig_t __iomem *) stli_ecpeigetmemptr(brdp,4373 CDK_SIGADDR, __LINE__);4374+ memcpy_fromio(&ecpsig, ecpsigp, sizeof(cdkecpsig_t));4375+ if (ecpsig.magic == cpu_to_le32(ECP_MAGIC))4376 foundit = 1;4377 } else {4378+ onbsigp = (cdkonbsig_t __iomem *) stli_onbegetmemptr(brdp,4379 CDK_SIGADDR, __LINE__);4380+ memcpy_fromio(&onbsig, onbsigp, sizeof(cdkonbsig_t));4381+ if ((onbsig.magic0 == cpu_to_le16(ONB_MAGIC0)) &&4382+ (onbsig.magic1 == cpu_to_le16(ONB_MAGIC1)) &&4383+ (onbsig.magic2 == cpu_to_le16(ONB_MAGIC2)) &&4384+ (onbsig.magic3 == cpu_to_le16(ONB_MAGIC3)))4385 foundit = 1;4386 }4387···4406 printk(KERN_ERR "STALLION: failed to probe shared memory "4407 "region for %s in EISA slot=%d\n",4408 stli_brdnames[brdp->brdtype], (brdp->iobase >> 12));4409+ return -ENODEV;4410 }4411+ return 0;4412}44134414static int stli_getbrdnr(void)···44394440static int stli_findeisabrds(void)4441{4442+ stlibrd_t *brdp;4443+ unsigned int iobase, eid;4444+ int i;000044454446/*4447+ * Firstly check if this is an EISA system. If this is not an EISA system then04448 * don't bother going any further!4449 */4450+ if (EISA_bus)4451+ return 0;044524453/*4454 * Looks like an EISA system, so go searching for EISA boards.···4472 */4473 for (i = 0; (i < STL_MAXBRDS); i++) {4474 brdp = stli_brds[i];4475+ if (brdp == NULL)4476 continue;4477 if (brdp->iobase == iobase)4478 break;···4484 * We have found a Stallion board and it is not configured already.4485 * Allocate a board structure and initialize it.4486 */4487+ if ((brdp = stli_allocbrd()) == NULL)4488+ return -ENOMEM;4489 if ((brdp->brdnr = stli_getbrdnr()) < 0)4490+ return -ENOMEM;4491 eid = inb(iobase + 0xc82);4492 if (eid == ECP_EISAID)4493 brdp->brdtype = BRD_ECPE;···4502 stli_brdinit(brdp);4503 }45044505+ return 0;4506}45074508/*****************************************************************************/···45234524static int stli_initpcibrd(int brdtype, struct pci_dev *devp)4525{4526+ stlibrd_t *brdp;0000045274528 if (pci_enable_device(devp))4529+ return -EIO;4530+ if ((brdp = stli_allocbrd()) == NULL)4531+ return -ENOMEM;4532 if ((brdp->brdnr = stli_getbrdnr()) < 0) {4533 printk(KERN_INFO "STALLION: too many boards found, "4534 "maximum supported %d\n", STL_MAXBRDS);4535+ return 0;4536 }4537 brdp->brdtype = brdtype;0000000004538/*4539 * We have all resources from the board, so lets setup the actual4540 * board structure now.···4557 brdp->memaddr = pci_resource_start(devp, 2);4558 stli_brdinit(brdp);45594560+ return 0;4561}45624563/*****************************************************************************/···45694570static int stli_findpcibrds(void)4571{4572+ struct pci_dev *dev = NULL;045734574+ while ((dev = pci_get_device(PCI_VENDOR_ID_STALLION, PCI_DEVICE_ID_ECRA, dev))) {4575+ stli_initpcibrd(BRD_ECPPCI, dev);0000004576 }4577+ return 0;04578}45794580#endif···45954596static stlibrd_t *stli_allocbrd(void)4597{4598+ stlibrd_t *brdp;45994600 brdp = kzalloc(sizeof(stlibrd_t), GFP_KERNEL);4601 if (!brdp) {4602 printk(KERN_ERR "STALLION: failed to allocate memory "4603+ "(size=%Zd)\n", sizeof(stlibrd_t));4604 return NULL;4605 }04606 brdp->magic = STLI_BOARDMAGIC;4607+ return brdp;4608}46094610/*****************************************************************************/···46174618static int stli_initbrds(void)4619{4620+ stlibrd_t *brdp, *nxtbrdp;4621+ stlconf_t *confp;4622+ int i, j;000046234624 if (stli_nrbrds > STL_MAXBRDS) {4625 printk(KERN_INFO "STALLION: too many boards in configuration "···4638 */4639 for (i = 0; (i < stli_nrbrds); i++) {4640 confp = &stli_brdconf[i];04641 stli_parsebrd(confp, stli_brdsp[i]);4642+ if ((brdp = stli_allocbrd()) == NULL)4643+ return -ENOMEM;04644 brdp->brdnr = i;4645 brdp->brdtype = confp->brdtype;4646 brdp->iobase = confp->ioaddr1;···4654 * Static configuration table done, so now use dynamic methods to4655 * see if any more boards should be configured.4656 */04657 stli_argbrds();04658 if (STLI_EISAPROBE)4659 stli_findeisabrds();4660#ifdef CONFIG_PCI···4672 if (stli_nrbrds > 1) {4673 for (i = 0; (i < stli_nrbrds); i++) {4674 brdp = stli_brds[i];4675+ if (brdp == NULL)4676 continue;4677 for (j = i + 1; (j < stli_nrbrds); j++) {4678 nxtbrdp = stli_brds[j];4679+ if (nxtbrdp == NULL)4680 continue;4681 if ((brdp->membase >= nxtbrdp->membase) &&4682 (brdp->membase <= (nxtbrdp->membase +···4691 if (stli_shared == 0) {4692 for (i = 0; (i < stli_nrbrds); i++) {4693 brdp = stli_brds[i];4694+ if (brdp == NULL)4695 continue;4696 if (brdp->state & BST_FOUND) {4697 EBRDENABLE(brdp);···4701 }4702 }47034704+ return 0;4705}47064707/*****************************************************************************/···47144715static ssize_t stli_memread(struct file *fp, char __user *buf, size_t count, loff_t *offp)4716{4717+ unsigned long flags;4718+ void *memptr;4719+ stlibrd_t *brdp;4720+ int brdnr, size, n;4721+ void *p;4722+ loff_t off = *offp;00047234724 brdnr = iminor(fp->f_dentry->d_inode);4725 if (brdnr >= stli_nrbrds)4726+ return -ENODEV;4727 brdp = stli_brds[brdnr];4728+ if (brdp == NULL)4729+ return -ENODEV;4730 if (brdp->state == 0)4731+ return -ENODEV;4732+ if (off >= brdp->memsize || off + count < off)4733+ return 0;47344735+ size = MIN(count, (brdp->memsize - off));47364737+ /*4738+ * Copy the data a page at a time4739+ */4740+4741+ p = (void *)__get_free_page(GFP_KERNEL);4742+ if(p == NULL)4743+ return -ENOMEM;4744+4745 while (size > 0) {4746+ spin_lock_irqsave(&brd_lock, flags);4747+ EBRDENABLE(brdp);4748+ memptr = (void *) EBRDGETMEMPTR(brdp, off);4749+ n = MIN(size, (brdp->pagesize - (((unsigned long) off) % brdp->pagesize)));4750+ n = MIN(n, PAGE_SIZE);4751+ memcpy_fromio(p, memptr, n);4752+ EBRDDISABLE(brdp);4753+ spin_unlock_irqrestore(&brd_lock, flags);4754+ if (copy_to_user(buf, p, n)) {4755 count = -EFAULT;4756 goto out;4757 }4758+ off += n;4759 buf += n;4760 size -= n;4761 }4762out:4763+ *offp = off;4764+ free_page((unsigned long)p);4765+ return count;04766}47674768/*****************************************************************************/···4764 * Code to handle an "staliomem" write operation. This device is the 4765 * contents of the board shared memory. It is used for down loading4766 * the slave image (and debugging :-)4767+ *4768+ * FIXME: copy under lock4769 */47704771static ssize_t stli_memwrite(struct file *fp, const char __user *buf, size_t count, loff_t *offp)4772{4773+ unsigned long flags;4774+ void *memptr;4775+ stlibrd_t *brdp;4776+ char __user *chbuf;4777+ int brdnr, size, n;4778+ void *p;4779+ loff_t off = *offp;00047804781 brdnr = iminor(fp->f_dentry->d_inode);4782+4783 if (brdnr >= stli_nrbrds)4784+ return -ENODEV;4785 brdp = stli_brds[brdnr];4786+ if (brdp == NULL)4787+ return -ENODEV;4788 if (brdp->state == 0)4789+ return -ENODEV;4790+ if (off >= brdp->memsize || off + count < off)4791+ return 0;47924793 chbuf = (char __user *) buf;4794+ size = MIN(count, (brdp->memsize - off));47954796+ /*4797+ * Copy the data a page at a time4798+ */4799+4800+ p = (void *)__get_free_page(GFP_KERNEL);4801+ if(p == NULL)4802+ return -ENOMEM;4803+4804 while (size > 0) {4805+ n = MIN(size, (brdp->pagesize - (((unsigned long) off) % brdp->pagesize)));4806+ n = MIN(n, PAGE_SIZE);4807+ if (copy_from_user(p, chbuf, n)) {4808+ if (count == 0)4809+ count = -EFAULT;4810 goto out;4811 }4812+ spin_lock_irqsave(&brd_lock, flags);4813+ EBRDENABLE(brdp);4814+ memptr = (void *) EBRDGETMEMPTR(brdp, off);4815+ memcpy_toio(memptr, p, n);4816+ EBRDDISABLE(brdp);4817+ spin_unlock_irqrestore(&brd_lock, flags);4818+ off += n;4819 chbuf += n;4820 size -= n;4821 }4822out:4823+ free_page((unsigned long) p);4824+ *offp = off;4825+ return count;04826}48274828/*****************************************************************************/···48224823static int stli_getbrdstats(combrd_t __user *bp)4824{4825+ stlibrd_t *brdp;4826+ int i;48274828 if (copy_from_user(&stli_brdstats, bp, sizeof(combrd_t)))4829 return -EFAULT;4830 if (stli_brdstats.brd >= STL_MAXBRDS)4831+ return -ENODEV;4832 brdp = stli_brds[stli_brdstats.brd];4833+ if (brdp == NULL)4834+ return -ENODEV;48354836 memset(&stli_brdstats, 0, sizeof(combrd_t));4837 stli_brdstats.brd = brdp->brdnr;···48504851 if (copy_to_user(bp, &stli_brdstats, sizeof(combrd_t)))4852 return -EFAULT;4853+ return 0;4854}48554856/*****************************************************************************/···48614862static stliport_t *stli_getport(int brdnr, int panelnr, int portnr)4863{4864+ stlibrd_t *brdp;4865+ int i;48664867+ if (brdnr < 0 || brdnr >= STL_MAXBRDS)4868+ return NULL;4869 brdp = stli_brds[brdnr];4870+ if (brdp == NULL)4871+ return NULL;4872 for (i = 0; (i < panelnr); i++)4873 portnr += brdp->panels[i];4874 if ((portnr < 0) || (portnr >= brdp->nrports))4875+ return NULL;4876+ return brdp->ports[portnr];4877}48784879/*****************************************************************************/···48924893 memset(&stli_comstats, 0, sizeof(comstats_t));48944895+ if (portp == NULL)4896+ return -ENODEV;4897 brdp = stli_brds[portp->brdnr];4898+ if (brdp == NULL)4899+ return -ENODEV;49004901 if (brdp->state & BST_STARTED) {4902 if ((rc = stli_cmdwait(brdp, portp, A_GETSTATS,4903 &stli_cdkstats, sizeof(asystats_t), 1)) < 0)4904+ return rc;4905 } else {4906 memset(&stli_cdkstats, 0, sizeof(asystats_t));4907 }···4912 stli_comstats.state = portp->state;4913 stli_comstats.flags = portp->flags;49144915+ spin_lock_irqsave(&brd_lock, flags);4916+ if (portp->tty != NULL) {04917 if (portp->tty->driver_data == portp) {4918 stli_comstats.ttystate = portp->tty->flags;4919+ stli_comstats.rxbuffered = -1;4920+ if (portp->tty->termios != NULL) {4921 stli_comstats.cflags = portp->tty->termios->c_cflag;4922 stli_comstats.iflags = portp->tty->termios->c_iflag;4923 stli_comstats.oflags = portp->tty->termios->c_oflag;···4926 }4927 }4928 }4929+ spin_unlock_irqrestore(&brd_lock, flags);49304931 stli_comstats.txtotal = stli_cdkstats.txchars;4932 stli_comstats.rxtotal = stli_cdkstats.rxchars + stli_cdkstats.ringover;···4948 stli_comstats.hwid = stli_cdkstats.hwid;4949 stli_comstats.signals = stli_mktiocm(stli_cdkstats.signals);49504951+ return 0;4952}49534954/*****************************************************************************/···49614962static int stli_getportstats(stliport_t *portp, comstats_t __user *cp)4963{4964+ stlibrd_t *brdp;4965+ int rc;49664967 if (!portp) {4968 if (copy_from_user(&stli_comstats, cp, sizeof(comstats_t)))···49924993static int stli_clrportstats(stliport_t *portp, comstats_t __user *cp)4994{4995+ stlibrd_t *brdp;4996+ int rc;49974998 if (!portp) {4999 if (copy_from_user(&stli_comstats, cp, sizeof(comstats_t)))···50315032static int stli_getportstruct(stliport_t __user *arg)5033{5034+ stliport_t *portp;50355036 if (copy_from_user(&stli_dummyport, arg, sizeof(stliport_t)))5037 return -EFAULT;···50525053static int stli_getbrdstruct(stlibrd_t __user *arg)5054{5055+ stlibrd_t *brdp;50565057 if (copy_from_user(&stli_dummybrd, arg, sizeof(stlibrd_t)))5058 return -EFAULT;···50765077static int stli_memioctl(struct inode *ip, struct file *fp, unsigned int cmd, unsigned long arg)5078{5079+ stlibrd_t *brdp;5080+ int brdnr, rc, done;5081 void __user *argp = (void __user *)arg;0000050825083/*5084 * First up handle the board independent ioctls.···5115 }51165117 if (done)5118+ return rc;51195120/*5121 * Now handle the board specific ioctls. These all depend on the···5123 */5124 brdnr = iminor(ip);5125 if (brdnr >= STL_MAXBRDS)5126+ return -ENODEV;5127 brdp = stli_brds[brdnr];5128 if (!brdp)5129+ return -ENODEV;5130 if (brdp->state == 0)5131+ return -ENODEV;51325133 switch (cmd) {5134 case STL_BINTR:···5152 rc = -ENOIOCTLCMD;5153 break;5154 }5155+ return rc;05156}51575158static struct tty_operations stli_ops = {···5187 int i;5188 printk(KERN_INFO "%s: version %s\n", stli_drvtitle, stli_drvversion);51895190+ spin_lock_init(&stli_lock);5191+ spin_lock_init(&brd_lock);5192+5193 stli_initbrds();51945195 stli_serial = alloc_tty_driver(STL_MAXBRDS * STL_MAXPORTS);···5196/*5197 * Allocate a temporary write buffer.5198 */00005199 stli_txcookbuf = kmalloc(STLI_TXBUFSIZE, GFP_KERNEL);5200 if (!stli_txcookbuf)5201 printk(KERN_ERR "STALLION: failed to allocate memory "···5243 printk(KERN_ERR "STALLION: failed to register serial driver\n");5244 return -EBUSY;5245 }5246+ return 0;5247}52485249/*****************************************************************************/
···1132 * buffer, and once to drain the space from the (physical) beginning of1133 * the buffer to head pointer.1134 *1135- * Called under the tty->atomic_read_lock sem and with TTY_DONT_FLIP set1136 *1137 */1138···1271 }12721273 add_wait_queue(&tty->read_wait, &wait);1274- set_bit(TTY_DONT_FLIP, &tty->flags);1275 while (nr) {1276 /* First test for status change. */1277 if (tty->packet && tty->link->ctrl_status) {···1314 break;1315 }1316 n_tty_set_room(tty);1317- clear_bit(TTY_DONT_FLIP, &tty->flags);1318 timeout = schedule_timeout(timeout);1319- set_bit(TTY_DONT_FLIP, &tty->flags);1320 continue;1321 }1322 __set_current_state(TASK_RUNNING);···1391 if (time)1392 timeout = time;1393 }1394- clear_bit(TTY_DONT_FLIP, &tty->flags);1395 mutex_unlock(&tty->atomic_read_lock);1396 remove_wait_queue(&tty->read_wait, &wait);1397
···1132 * buffer, and once to drain the space from the (physical) beginning of1133 * the buffer to head pointer.1134 *1135+ * Called under the tty->atomic_read_lock sem1136 *1137 */1138···1271 }12721273 add_wait_queue(&tty->read_wait, &wait);01274 while (nr) {1275 /* First test for status change. */1276 if (tty->packet && tty->link->ctrl_status) {···1315 break;1316 }1317 n_tty_set_room(tty);01318 timeout = schedule_timeout(timeout);01319 continue;1320 }1321 __set_current_state(TASK_RUNNING);···1394 if (time)1395 timeout = time;1396 }01397 mutex_unlock(&tty->atomic_read_lock);1398 remove_wait_queue(&tty->read_wait, &wait);1399
+1-1
drivers/char/pty.c
···101 *102 * FIXME: Our pty_write method is called with our ldisc lock held but103 * not our partners. We can't just take the other one blindly without104- * risking deadlocks. There is also the small matter of TTY_DONT_FLIP105 */106static int pty_write(struct tty_struct * tty, const unsigned char *buf, int count)107{
···101 *102 * FIXME: Our pty_write method is called with our ldisc lock held but103 * not our partners. We can't just take the other one blindly without104+ * risking deadlocks.105 */106static int pty_write(struct tty_struct * tty, const unsigned char *buf, int count)107{
+3
drivers/char/stallion.c
···3029 int i;3030 printk(KERN_INFO "%s: version %s\n", stl_drvtitle, stl_drvversion);30310003032 stl_initbrds();30333034 stl_serial = alloc_tty_driver(STL_MAXBRDS * STL_MAXPORTS);
···3029 int i;3030 printk(KERN_INFO "%s: version %s\n", stl_drvtitle, stl_drvversion);30313032+ spin_lock_init(&stallion_lock);3033+ spin_lock_init(&brd_lock);3034+3035 stl_initbrds();30363037 stl_serial = alloc_tty_driver(STL_MAXBRDS * STL_MAXPORTS);
+30-38
drivers/char/tty_io.c
···267 p->used = 0;268 p->size = size;269 p->next = NULL;270- p->active = 0;271 p->commit = 0;272 p->read = 0;273 p->char_buf_ptr = (char *)(p->data);···326 /* OPTIMISATION: We could keep a per tty "zero" sized buffer to327 remove this conditional if its worth it. This would be invisible328 to the callers */329- if ((b = tty->buf.tail) != NULL) {330 left = b->size - b->used;331- b->active = 1;332- } else333 left = 0;334335 if (left < size) {···336 if ((n = tty_buffer_find(tty, size)) != NULL) {337 if (b != NULL) {338 b->next = n;339- b->active = 0;340 b->commit = b->used;341 } else342 tty->buf.head = n;343 tty->buf.tail = n;344- n->active = 1;345 } else346 size = left;347 }···400{401 unsigned long flags;402 spin_lock_irqsave(&tty->buf.lock, flags);403- if (tty->buf.tail != NULL) {404- tty->buf.tail->active = 0;405 tty->buf.tail->commit = tty->buf.tail->used;406- }407 spin_unlock_irqrestore(&tty->buf.lock, flags);408 schedule_delayed_work(&tty->buf.work, 1);409}···778 }779780 clear_bit(TTY_LDISC, &tty->flags);781- clear_bit(TTY_DONT_FLIP, &tty->flags);782- if (o_tty) {783 clear_bit(TTY_LDISC, &o_tty->flags);784- clear_bit(TTY_DONT_FLIP, &o_tty->flags);785- }786 spin_unlock_irqrestore(&tty_ldisc_lock, flags);787788 /*···1946 * race with the set_ldisc code path.1947 */1948 clear_bit(TTY_LDISC, &tty->flags);1949- clear_bit(TTY_DONT_FLIP, &tty->flags);1950 cancel_delayed_work(&tty->buf.work);19511952 /*···2765 struct tty_struct *tty = (struct tty_struct *) private_;2766 unsigned long flags;2767 struct tty_ldisc *disc;2768- struct tty_buffer *tbuf;2769- int count;2770 char *char_buf;2771 unsigned char *flag_buf;2772···2773 if (disc == NULL) /* !TTY_LDISC */2774 return;27752776- if (test_bit(TTY_DONT_FLIP, &tty->flags)) {2777- /*2778- * Do it after the next timer tick:2779- */2780- schedule_delayed_work(&tty->buf.work, 1);2781- goto out;2782- }2783 spin_lock_irqsave(&tty->buf.lock, flags);2784- while((tbuf = tty->buf.head) != NULL) {2785- while ((count = tbuf->commit - tbuf->read) != 0) {2786- char_buf = tbuf->char_buf_ptr + tbuf->read;2787- flag_buf = tbuf->flag_buf_ptr + tbuf->read;2788- tbuf->read += count;000000000000000002789 spin_unlock_irqrestore(&tty->buf.lock, flags);2790 disc->receive_buf(tty, char_buf, flag_buf, count);2791 spin_lock_irqsave(&tty->buf.lock, flags);2792 }2793- if (tbuf->active)2794- break;2795- tty->buf.head = tbuf->next;2796- if (tty->buf.head == NULL)2797- tty->buf.tail = NULL;2798- tty_buffer_free(tty, tbuf);2799 }2800 spin_unlock_irqrestore(&tty->buf.lock, flags);2801-out:2802 tty_ldisc_deref(disc);2803}2804···2896{2897 unsigned long flags;2898 spin_lock_irqsave(&tty->buf.lock, flags);2899- if (tty->buf.tail != NULL) {2900- tty->buf.tail->active = 0;2901 tty->buf.tail->commit = tty->buf.tail->used;2902- }2903 spin_unlock_irqrestore(&tty->buf.lock, flags);29042905 if (tty->low_latency)
···267 p->used = 0;268 p->size = size;269 p->next = NULL;0270 p->commit = 0;271 p->read = 0;272 p->char_buf_ptr = (char *)(p->data);···327 /* OPTIMISATION: We could keep a per tty "zero" sized buffer to328 remove this conditional if its worth it. This would be invisible329 to the callers */330+ if ((b = tty->buf.tail) != NULL)331 left = b->size - b->used;332+ else0333 left = 0;334335 if (left < size) {···338 if ((n = tty_buffer_find(tty, size)) != NULL) {339 if (b != NULL) {340 b->next = n;0341 b->commit = b->used;342 } else343 tty->buf.head = n;344 tty->buf.tail = n;0345 } else346 size = left;347 }···404{405 unsigned long flags;406 spin_lock_irqsave(&tty->buf.lock, flags);407+ if (tty->buf.tail != NULL)0408 tty->buf.tail->commit = tty->buf.tail->used;0409 spin_unlock_irqrestore(&tty->buf.lock, flags);410 schedule_delayed_work(&tty->buf.work, 1);411}···784 }785786 clear_bit(TTY_LDISC, &tty->flags);787+ if (o_tty)0788 clear_bit(TTY_LDISC, &o_tty->flags);00789 spin_unlock_irqrestore(&tty_ldisc_lock, flags);790791 /*···1955 * race with the set_ldisc code path.1956 */1957 clear_bit(TTY_LDISC, &tty->flags);01958 cancel_delayed_work(&tty->buf.work);19591960 /*···2775 struct tty_struct *tty = (struct tty_struct *) private_;2776 unsigned long flags;2777 struct tty_ldisc *disc;2778+ struct tty_buffer *tbuf, *head;02779 char *char_buf;2780 unsigned char *flag_buf;2781···2784 if (disc == NULL) /* !TTY_LDISC */2785 return;278600000002787 spin_lock_irqsave(&tty->buf.lock, flags);2788+ head = tty->buf.head;2789+ if (head != NULL) {2790+ tty->buf.head = NULL;2791+ for (;;) {2792+ int count = head->commit - head->read;2793+ if (!count) {2794+ if (head->next == NULL)2795+ break;2796+ tbuf = head;2797+ head = head->next;2798+ tty_buffer_free(tty, tbuf);2799+ continue;2800+ }2801+ if (!tty->receive_room) {2802+ schedule_delayed_work(&tty->buf.work, 1);2803+ break;2804+ }2805+ if (count > tty->receive_room)2806+ count = tty->receive_room;2807+ char_buf = head->char_buf_ptr + head->read;2808+ flag_buf = head->flag_buf_ptr + head->read;2809+ head->read += count;2810 spin_unlock_irqrestore(&tty->buf.lock, flags);2811 disc->receive_buf(tty, char_buf, flag_buf, count);2812 spin_lock_irqsave(&tty->buf.lock, flags);2813 }2814+ tty->buf.head = head;000002815 }2816 spin_unlock_irqrestore(&tty->buf.lock, flags);2817+2818 tty_ldisc_deref(disc);2819}2820···2902{2903 unsigned long flags;2904 spin_lock_irqsave(&tty->buf.lock, flags);2905+ if (tty->buf.tail != NULL)02906 tty->buf.tail->commit = tty->buf.tail->used;02907 spin_unlock_irqrestore(&tty->buf.lock, flags);29082909 if (tty->low_latency)
+71-11
drivers/char/watchdog/at91_wdt.c
···17#include <linux/miscdevice.h>18#include <linux/module.h>19#include <linux/moduleparam.h>020#include <linux/types.h>21#include <linux/watchdog.h>22#include <asm/bitops.h>23#include <asm/uaccess.h>242526-#define WDT_DEFAULT_TIME 5 /* 5 seconds */27-#define WDT_MAX_TIME 256 /* 256 seconds */2829static int wdt_time = WDT_DEFAULT_TIME;30static int nowayout = WATCHDOG_NOWAYOUT;···33module_param(wdt_time, int, 0);34MODULE_PARM_DESC(wdt_time, "Watchdog time in seconds. (default="__MODULE_STRING(WDT_DEFAULT_TIME) ")");35036module_param(nowayout, int, 0);37MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");0383940static unsigned long at91wdt_busy;···141 case WDIOC_SETTIMEOUT:142 if (get_user(new_value, p))143 return -EFAULT;144-145 if (at91_wdt_settimeout(new_value))146 return -EINVAL;147···199 .fops = &at91wdt_fops,200};201202-static int __init at91_wdt_init(void)203{204 int res;205206- /* Check that the heartbeat value is within range; if not reset to the default */207- if (at91_wdt_settimeout(wdt_time)) {208- at91_wdt_settimeout(WDT_DEFAULT_TIME);209- printk(KERN_INFO "at91_wdt: wdt_time value must be 1 <= wdt_time <= 256, using %d\n", wdt_time);210- }211212 res = misc_register(&at91wdt_miscdev);213 if (res)214 return res;215216- printk("AT91 Watchdog Timer enabled (%d seconds, nowayout=%d)\n", wdt_time, nowayout);217 return 0;00000000000000000000000000000000000000000000000000000000000218}219220static void __exit at91_wdt_exit(void)221{222- misc_deregister(&at91wdt_miscdev);223}224225module_init(at91_wdt_init);
···17#include <linux/miscdevice.h>18#include <linux/module.h>19#include <linux/moduleparam.h>20+#include <linux/platform_device.h>21#include <linux/types.h>22#include <linux/watchdog.h>23#include <asm/bitops.h>24#include <asm/uaccess.h>252627+#define WDT_DEFAULT_TIME 5 /* seconds */28+#define WDT_MAX_TIME 256 /* seconds */2930static int wdt_time = WDT_DEFAULT_TIME;31static int nowayout = WATCHDOG_NOWAYOUT;···32module_param(wdt_time, int, 0);33MODULE_PARM_DESC(wdt_time, "Watchdog time in seconds. (default="__MODULE_STRING(WDT_DEFAULT_TIME) ")");3435+#ifdef CONFIG_WATCHDOG_NOWAYOUT36module_param(nowayout, int, 0);37MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");38+#endif394041static unsigned long at91wdt_busy;···138 case WDIOC_SETTIMEOUT:139 if (get_user(new_value, p))140 return -EFAULT;141+142 if (at91_wdt_settimeout(new_value))143 return -EINVAL;144···196 .fops = &at91wdt_fops,197};198199+static int __init at91wdt_probe(struct platform_device *pdev)200{201 int res;202203+ if (at91wdt_miscdev.dev)204+ return -EBUSY;205+ at91wdt_miscdev.dev = &pdev->dev;00206207 res = misc_register(&at91wdt_miscdev);208 if (res)209 return res;210211+ printk("AT91 Watchdog Timer enabled (%d seconds%s)\n", wdt_time, nowayout ? ", nowayout" : "");212 return 0;213+}214+215+static int __exit at91wdt_remove(struct platform_device *pdev)216+{217+ int res;218+219+ res = misc_deregister(&at91wdt_miscdev);220+ if (!res)221+ at91wdt_miscdev.dev = NULL;222+223+ return res;224+}225+226+static void at91wdt_shutdown(struct platform_device *pdev)227+{228+ at91_wdt_stop();229+}230+231+#ifdef CONFIG_PM232+233+static int at91wdt_suspend(struct platform_device *pdev, pm_message_t message)234+{235+ at91_wdt_stop();236+ return 0;237+}238+239+static int at91wdt_resume(struct platform_device *pdev)240+{241+ if (at91wdt_busy)242+ at91_wdt_start();243+ return 0;244+}245+246+#else247+#define at91wdt_suspend NULL248+#define at91wdt_resume NULL249+#endif250+251+static struct platform_driver at91wdt_driver = {252+ .probe = at91wdt_probe,253+ .remove = __exit_p(at91wdt_remove),254+ .shutdown = at91wdt_shutdown,255+ .suspend = at91wdt_suspend,256+ .resume = at91wdt_resume,257+ .driver = {258+ .name = "at91_wdt",259+ .owner = THIS_MODULE,260+ },261+};262+263+static int __init at91_wdt_init(void)264+{265+ /* Check that the heartbeat value is within range; if not reset to the default */266+ if (at91_wdt_settimeout(wdt_time)) {267+ at91_wdt_settimeout(WDT_DEFAULT_TIME);268+ pr_info("at91_wdt: wdt_time value must be 1 <= wdt_time <= 256, using %d\n", wdt_time);269+ }270+271+ return platform_driver_register(&at91wdt_driver);272}273274static void __exit at91_wdt_exit(void)275{276+ platform_driver_unregister(&at91wdt_driver);277}278279module_init(at91_wdt_init);
+27-1
drivers/char/watchdog/i8xx_tco.c
···205 return 0;206}20700000000000000000208/*209 * /dev/watchdog handling210 */···289{290 int new_options, retval = -EINVAL;291 int new_heartbeat;0292 void __user *argp = (void __user *)arg;293 int __user *p = argp;294 static struct watchdog_info ident = {···338 return -EFAULT;339340 if (tco_timer_set_heartbeat(new_heartbeat))341- return -EINVAL;342343 tco_timer_keepalive ();344 /* Fall */···346347 case WDIOC_GETTIMEOUT:348 return put_user(heartbeat, p);00000000349350 default:351 return -ENOIOCTLCMD;
···205 return 0;206}207208+static int tco_timer_get_timeleft (int *time_left)209+{210+ unsigned char val;211+212+ spin_lock(&tco_lock);213+214+ /* read the TCO Timer */215+ val = inb (TCO1_RLD);216+ val &= 0x3f;217+218+ spin_unlock(&tco_lock);219+220+ *time_left = (int)((val * 6) / 10);221+222+ return 0;223+}224+225/*226 * /dev/watchdog handling227 */···272{273 int new_options, retval = -EINVAL;274 int new_heartbeat;275+ int time_left;276 void __user *argp = (void __user *)arg;277 int __user *p = argp;278 static struct watchdog_info ident = {···320 return -EFAULT;321322 if (tco_timer_set_heartbeat(new_heartbeat))323+ return -EINVAL;324325 tco_timer_keepalive ();326 /* Fall */···328329 case WDIOC_GETTIMEOUT:330 return put_user(heartbeat, p);331+332+ case WDIOC_GETTIMELEFT:333+ {334+ if (tco_timer_get_timeleft(&time_left))335+ return -EINVAL;336+337+ return put_user(time_left, p);338+ }339340 default:341 return -ENOIOCTLCMD;
+29-1
drivers/char/watchdog/pcwd_pci.c
···21 */2223/*24- * A bells and whistles driver is available from: 25 * http://www.kernel.org/pub/linux/kernel/people/wim/pcwd/pcwd_pci/26 *27 * More info available at http://www.berkprod.com/ or http://www.pcwatchdog.com/···390 return 0;391}392000000000000000000393/*394 * /dev/watchdog handling395 */···529530 case WDIOC_GETTIMEOUT:531 return put_user(heartbeat, p);0000000000532533 default:534 return -ENOIOCTLCMD;
···21 */2223/*24+ * A bells and whistles driver is available from:25 * http://www.kernel.org/pub/linux/kernel/people/wim/pcwd/pcwd_pci/26 *27 * More info available at http://www.berkprod.com/ or http://www.pcwatchdog.com/···390 return 0;391}392393+static int pcipcwd_get_timeleft(int *time_left)394+{395+ int msb;396+ int lsb;397+398+ /* Read the time that's left before rebooting */399+ /* Note: if the board is not yet armed then we will read 0xFFFF */400+ send_command(CMD_READ_WATCHDOG_TIMEOUT, &msb, &lsb);401+402+ *time_left = (msb << 8) + lsb;403+404+ if (debug >= VERBOSE)405+ printk(KERN_DEBUG PFX "Time left before next reboot: %d\n",406+ *time_left);407+408+ return 0;409+}410+411/*412 * /dev/watchdog handling413 */···511512 case WDIOC_GETTIMEOUT:513 return put_user(heartbeat, p);514+515+ case WDIOC_GETTIMELEFT:516+ {517+ int time_left;518+519+ if (pcipcwd_get_timeleft(&time_left))520+ return -EFAULT;521+522+ return put_user(time_left, p);523+ }524525 default:526 return -ENOIOCTLCMD;
···317 return 0;318}319320+static int usb_pcwd_get_timeleft(struct usb_pcwd_private *usb_pcwd, int *time_left)321+{322+ unsigned char msb, lsb;323+324+ /* Read the time that's left before rebooting */325+ /* Note: if the board is not yet armed then we will read 0xFFFF */326+ usb_pcwd_send_command(usb_pcwd, CMD_READ_WATCHDOG_TIMEOUT, &msb, &lsb);327+328+ *time_left = (msb << 8) + lsb;329+330+ return 0;331+}332+333/*334 * /dev/watchdog handling335 */···421422 case WDIOC_GETTIMEOUT:423 return put_user(heartbeat, p);424+425+ case WDIOC_GETTIMELEFT:426+ {427+ int time_left;428+429+ if (usb_pcwd_get_timeleft(usb_pcwd_device, &time_left))430+ return -EFAULT;431+432+ return put_user(time_left, p);433+ }434435 default:436 return -ENOIOCTLCMD;
+1-1
drivers/ide/ide-io.c
···505 }506 }507508- if ((stat & DRQ_STAT) && rq_data_dir(rq) == READ)509 try_to_flush_leftover_data(drive);510511 if (hwif->INB(IDE_STATUS_REG) & (BUSY_STAT|DRQ_STAT))
···505 }506 }507508+ if ((stat & DRQ_STAT) && rq_data_dir(rq) == READ && hwif->err_stops_fifo == 0)509 try_to_flush_leftover_data(drive);510511 if (hwif->INB(IDE_STATUS_REG) & (BUSY_STAT|DRQ_STAT))
···597{598 if(HWIF(drive)->udma_four == 0)599 return 0;600+601+ /* Check for SATA but only if we are ATA5 or higher */602+ if (drive->id->hw_config == 0 && (drive->id->major_rev_num & 0x7FE0))603+ return 1;604 if (!(drive->id->hw_config & 0x6000))605 return 0;606#ifndef CONFIG_IDEDMA_IVB
···190#endif /* defined(DISPLAY_CMD64X_TIMINGS) && defined(CONFIG_PROC_FS) */191192/*193- * Registers and masks for easy access by drive index:194- */195-#if 0196-static u8 prefetch_regs[4] = {CNTRL, CNTRL, ARTTIM23, ARTTIM23};197-static u8 prefetch_masks[4] = {CNTRL_DIS_RA0, CNTRL_DIS_RA1, ARTTIM23_DIS_RA2, ARTTIM23_DIS_RA3};198-#endif199-200-/*201 * This routine writes the prepared setup/active/recovery counts202 * for a drive into the cmd646 chipset registers to active them.203 */···597598 pci_read_config_dword(dev, PCI_CLASS_REVISION, &class_rev);599 class_rev &= 0xff;600-601-#ifdef __i386__602- if (dev->resource[PCI_ROM_RESOURCE].start) {603- pci_write_config_dword(dev, PCI_ROM_ADDRESS, dev->resource[PCI_ROM_RESOURCE].start | PCI_ROM_ADDRESS_ENABLE);604- printk(KERN_INFO "%s: ROM enabled at 0x%08lx\n", name, dev->resource[PCI_ROM_RESOURCE].start);605- }606-#endif607608 switch(dev->device) {609 case PCI_DEVICE_ID_CMD_643:
···190#endif /* defined(DISPLAY_CMD64X_TIMINGS) && defined(CONFIG_PROC_FS) */191192/*00000000193 * This routine writes the prepared setup/active/recovery counts194 * for a drive into the cmd646 chipset registers to active them.195 */···605606 pci_read_config_dword(dev, PCI_CLASS_REVISION, &class_rev);607 class_rev &= 0xff;0000000608609 switch(dev->device) {610 case PCI_DEVICE_ID_CMD_643:
···162 This driver can also be built as a module. If so, the module163 will be called rtc-pcf8583.1640000000000165config RTC_DRV_RS5C372166 tristate "Ricoh RS5C372A/B"167 depends on RTC_CLASS && I2C
···162 This driver can also be built as a module. If so, the module163 will be called rtc-pcf8583.164165+config RTC_DRV_RS5C348166+ tristate "Ricoh RS5C348A/B"167+ depends on RTC_CLASS && SPI168+ help169+ If you say yes here you get support for the170+ Ricoh RS5C348A and RS5C348B RTC chips.171+172+ This driver can also be built as a module. If so, the module173+ will be called rtc-rs5c348.174+175config RTC_DRV_RS5C372176 tristate "Ricoh RS5C372A/B"177 depends on RTC_CLASS && I2C
···589 ld = tty_ldisc_ref(tp);590591 /*592- * If the DONT_FLIP flag is on, don't flush our buffer, and act593- * like the ld doesn't have any space to put the data right now.594- */595- if (test_bit(TTY_DONT_FLIP, &tp->flags))596- len = 0;597-598- /*599 * If we were unable to get a reference to the ld,600 * don't flush our buffer, and act like the ld doesn't601 * have any space to put the data right now.
···589 ld = tty_ldisc_ref(tp);590591 /*0000000592 * If we were unable to get a reference to the ld,593 * don't flush our buffer, and act like the ld doesn't594 * have any space to put the data right now.
···453 tty = port->tty;454455 /*456- * FIXME: must not do this in IRQ context,457- * must honour TTY_DONT_FLIP458 */459 tty->ldisc.receive_buf(460 tty,
···453 tty = port->tty;454455 /*456+ * FIXME: must not do this in IRQ context0457 */458 tty->ldisc.receive_buf(459 tty,
+3-3
drivers/video/aty/radeon_backlight.c
···4041 mutex_unlock(&info->bl_mutex);4243- if (pdata->negative)44- rlevel = MAX_RADEON_LEVEL - rlevel;45-46 if (rlevel < 0)47 rlevel = 0;48 else if (rlevel > MAX_RADEON_LEVEL)49 rlevel = MAX_RADEON_LEVEL;0005051 return rlevel;52}
···4041 mutex_unlock(&info->bl_mutex);4200043 if (rlevel < 0)44 rlevel = 0;45 else if (rlevel > MAX_RADEON_LEVEL)46 rlevel = MAX_RADEON_LEVEL;47+48+ if (pdata->negative)49+ rlevel = MAX_RADEON_LEVEL - rlevel;5051 return rlevel;52}
···139 put_metapage(mp);140}141142-extern struct address_space_operations jfs_metapage_aops;143144/*145 * This routines invalidate all pages for an extent.
···139 put_metapage(mp);140}141142+extern const struct address_space_operations jfs_metapage_aops;143144/*145 * This routines invalidate all pages for an extent.
···1544/**1545 * ntfs_aops - general address space operations for inodes and attributes1546 */1547-struct address_space_operations ntfs_aops = {1548 .readpage = ntfs_readpage, /* Fill page with data. */1549 .sync_page = block_sync_page, /* Currently, just unplugs the1550 disk request queue. */···1560 * ntfs_mst_aops - general address space operations for mst protecteed inodes1561 * and attributes1562 */1563-struct address_space_operations ntfs_mst_aops = {1564 .readpage = ntfs_readpage, /* Fill page with data. */1565 .sync_page = block_sync_page, /* Currently, just unplugs the1566 disk request queue. */
···1544/**1545 * ntfs_aops - general address space operations for inodes and attributes1546 */1547+const struct address_space_operations ntfs_aops = {1548 .readpage = ntfs_readpage, /* Fill page with data. */1549 .sync_page = block_sync_page, /* Currently, just unplugs the1550 disk request queue. */···1560 * ntfs_mst_aops - general address space operations for mst protecteed inodes1561 * and attributes1562 */1563+const struct address_space_operations ntfs_mst_aops = {1564 .readpage = ntfs_readpage, /* Fill page with data. */1565 .sync_page = block_sync_page, /* Currently, just unplugs the1566 disk request queue. */
+2-2
fs/ntfs/ntfs.h
···57extern struct kmem_cache *ntfs_index_ctx_cache;5859/* The various operations structs defined throughout the driver files. */60-extern struct address_space_operations ntfs_aops;61-extern struct address_space_operations ntfs_mst_aops;6263extern const struct file_operations ntfs_file_ops;64extern struct inode_operations ntfs_file_inode_ops;
···57extern struct kmem_cache *ntfs_index_ctx_cache;5859/* The various operations structs defined throughout the driver files. */60+extern const struct address_space_operations ntfs_aops;61+extern const struct address_space_operations ntfs_mst_aops;6263extern const struct file_operations ntfs_file_ops;64extern struct inode_operations ntfs_file_inode_ops;
···33 * bus_to_virt: Used to convert an address for DMA operations34 * to an address that the kernel can use.35 */36-#define __virt_to_bus__is_a_macro37#define __virt_to_bus(x) __virt_to_phys(x)38-#define __bus_to_virt__is_a_macro39#define __bus_to_virt(x) __phys_to_virt(x)4041#endif
···33 * bus_to_virt: Used to convert an address for DMA operations34 * to an address that the kernel can use.35 */036#define __virt_to_bus(x) __virt_to_phys(x)037#define __bus_to_virt(x) __phys_to_virt(x)3839#endif
-2
include/asm-arm/arch-h720x/memory.h
···23 * There is something to do here later !, Mar 2000, Jungjun Kim24 */2526-#define __virt_to_bus__is_a_macro27#define __virt_to_bus(x) __virt_to_phys(x)28-#define __bus_to_virt__is_a_macro29#define __bus_to_virt(x) __phys_to_virt(x)3031#endif
···23 * There is something to do here later !, Mar 2000, Jungjun Kim24 */25026#define __virt_to_bus(x) __virt_to_phys(x)027#define __bus_to_virt(x) __phys_to_virt(x)2829#endif
+2-4
include/asm-arm/arch-imx/memory.h
···30 * bus_to_virt: Used to convert an address for DMA operations31 * to an address that the kernel can use.32 */33-#define __virt_to_bus__is_a_macro34-#define __virt_to_bus(x) (x - PAGE_OFFSET + PHYS_OFFSET)35-#define __bus_to_virt__is_a_macro36-#define __bus_to_virt(x) (x - PHYS_OFFSET + PAGE_OFFSET)3738#endif
···30 * bus_to_virt: Used to convert an address for DMA operations31 * to an address that the kernel can use.32 */33+#define __virt_to_bus(x) (x - PAGE_OFFSET + PHYS_OFFSET)34+#define __bus_to_virt(x) (x - PHYS_OFFSET + PAGE_OFFSET)003536#endif
-11
include/asm-arm/arch-ixp23xx/ixp23xx.h
···295#define IXP23XX_PCI_CPP_ADDR_BITS IXP23XX_PCI_CSR(0x0160)296297298-#ifndef __ASSEMBLY__299-/*300- * Is system memory on the XSI or CPP bus?301- */302-static inline unsigned ixp23xx_cpp_boot(void)303-{304- return (*IXP23XX_EXP_CFG0 & IXP23XX_EXP_CFG0_XSI_NOT_PRES);305-}306-#endif307-308-309#endif
···4344#define IXP23XX_UART_XTAL 147456004546+#ifndef __ASSEMBLY__47+/*48+ * Is system memory on the XSI or CPP bus?49+ */50+static inline unsigned ixp23xx_cpp_boot(void)51+{52+ return (*IXP23XX_EXP_CFG0 & IXP23XX_EXP_CFG0_XSI_NOT_PRES);53+}54+#endif55+5657#endif
···7 * it under the terms of the GNU General Public License version 2 as8 * published by the Free Software Foundation.9 *10- * S3C2440 Signal Drive Strength Control11- *12- * Changelog:13- * 11-Aug-2004 BJD Created file14- * 25-Aug-2004 BJD Added the _SELECT_* defs for using with functions15*/161718#ifndef __ASM_ARCH_REGS_DSC_H19#define __ASM_ARCH_REGS_DSC_H "2440-dsc"2021-#ifdef CONFIG_CPU_S3C2440000002223#define S3C2440_DSC0 S3C2410_GPIOREG(0xc4)24#define S3C2440_DSC1 S3C2410_GPIOREG(0xc8)25-26-#define S3C2412_DSC0 S3C2410_GPIOREG(0xdc)27-#define S3C2412_DSC1 S3C2410_GPIOREG(0xe0)2829#define S3C2440_SELECT_DSC0 (0)30#define S3C2440_SELECT_DSC1 (1<<31)
···7 * it under the terms of the GNU General Public License version 2 as8 * published by the Free Software Foundation.9 *10+ * S3C2440/S3C2412 Signal Drive Strength Control000011*/121314#ifndef __ASM_ARCH_REGS_DSC_H15#define __ASM_ARCH_REGS_DSC_H "2440-dsc"1617+#if defined(CONFIG_CPU_S3C2412)18+#define S3C2412_DSC0 S3C2410_GPIOREG(0xdc)19+#define S3C2412_DSC1 S3C2410_GPIOREG(0xe0)20+#endif21+22+#if defined(CONFIG_CPU_S3C2440)2324#define S3C2440_DSC0 S3C2410_GPIOREG(0xc4)25#define S3C2440_DSC1 S3C2410_GPIOREG(0xc8)0002627#define S3C2440_SELECT_DSC0 (0)28#define S3C2440_SELECT_DSC1 (1<<31)
···16 unsigned int type;17};180019#define MT_DEVICE 020#define MT_CACHECLEAN 121#define MT_MINICLEAN 2···28#define MT_IXP2000_DEVICE 729#define MT_NONSHARED_DEVICE 83031+#ifdef CONFIG_MMU032extern void iotable_init(struct map_desc *, int);33+#else34+#define iotable_init(map,num) do { } while (0)35+#endif
+57-18
include/asm-arm/memory.h
···2 * linux/include/asm-arm/memory.h3 *4 * Copyright (C) 2000-2002 Russell King05 *6 * This program is free software; you can redistribute it and/or modify7 * it under the terms of the GNU General Public License version 2 as···27#include <asm/arch/memory.h>28#include <asm/sizes.h>290030#ifndef TASK_SIZE31/*32 * TASK_SIZE - the maximum size of a user space task.···49#ifndef PAGE_OFFSET50#define PAGE_OFFSET UL(0xc0000000)51#endif0000000000000000000000000000000000000000000000000000005253/*54 * Size of DMA-consistent memory region. Must be multiple of 2M,···127 */128#define __phys_to_pfn(paddr) ((paddr) >> PAGE_SHIFT)129#define __pfn_to_phys(pfn) ((pfn) << PAGE_SHIFT)130-131-/*132- * The module space lives between the addresses given by TASK_SIZE133- * and PAGE_OFFSET - it must be within 32MB of the kernel text.134- */135-#define MODULE_END (PAGE_OFFSET)136-#define MODULE_START (MODULE_END - 16*1048576)137-138-#if TASK_SIZE > MODULE_START139-#error Top of user space clashes with start of module space140-#endif141-142-/*143- * The XIP kernel gets mapped at the bottom of the module vm area.144- * Since we use sections to map it, this macro replaces the physical address145- * with its virtual address while keeping offset from the base section.146- */147-#define XIP_VIRT_ADDR(physaddr) (MODULE_START + ((physaddr) & 0x000fffff))148149#ifndef __ASSEMBLY__150
···2 * linux/include/asm-arm/memory.h3 *4 * Copyright (C) 2000-2002 Russell King5+ * modification for nommu, Hyok S. Choi, 20046 *7 * This program is free software; you can redistribute it and/or modify8 * it under the terms of the GNU General Public License version 2 as···26#include <asm/arch/memory.h>27#include <asm/sizes.h>2829+#ifdef CONFIG_MMU30+31#ifndef TASK_SIZE32/*33 * TASK_SIZE - the maximum size of a user space task.···46#ifndef PAGE_OFFSET47#define PAGE_OFFSET UL(0xc0000000)48#endif49+50+/*51+ * The module space lives between the addresses given by TASK_SIZE52+ * and PAGE_OFFSET - it must be within 32MB of the kernel text.53+ */54+#define MODULE_END (PAGE_OFFSET)55+#define MODULE_START (MODULE_END - 16*1048576)56+57+#if TASK_SIZE > MODULE_START58+#error Top of user space clashes with start of module space59+#endif60+61+/*62+ * The XIP kernel gets mapped at the bottom of the module vm area.63+ * Since we use sections to map it, this macro replaces the physical address64+ * with its virtual address while keeping offset from the base section.65+ */66+#define XIP_VIRT_ADDR(physaddr) (MODULE_START + ((physaddr) & 0x000fffff))67+68+#else /* CONFIG_MMU */69+70+/*71+ * The limitation of user task size can grow up to the end of free ram region.72+ * It is difficult to define and perhaps will never meet the original meaning73+ * of this define that was meant to.74+ * Fortunately, there is no reference for this in noMMU mode, for now.75+ */76+#ifndef TASK_SIZE77+#define TASK_SIZE (CONFIG_DRAM_SIZE)78+#endif79+80+#ifndef TASK_UNMAPPED_BASE81+#define TASK_UNMAPPED_BASE UL(0x00000000)82+#endif83+84+#ifndef PHYS_OFFSET85+#define PHYS_OFFSET (CONFIG_DRAM_BASE)86+#endif87+88+#ifndef END_MEM89+#define END_MEM (CONFIG_DRAM_BASE + CONFIG_DRAM_SIZE)90+#endif91+92+#ifndef PAGE_OFFSET93+#define PAGE_OFFSET (PHYS_OFFSET)94+#endif95+96+/*97+ * The module can be at any place in ram in nommu mode.98+ */99+#define MODULE_END (END_MEM)100+#define MODULE_START (PHYS_OFFSET)101+102+#endif /* !CONFIG_MMU */103104/*105 * Size of DMA-consistent memory region. Must be multiple of 2M,···70 */71#define __phys_to_pfn(paddr) ((paddr) >> PAGE_SHIFT)72#define __pfn_to_phys(pfn) ((pfn) << PAGE_SHIFT)0000000000000000007374#ifndef __ASSEMBLY__75
···1#ifndef __ARM_MMU_H2#define __ARM_MMU_H34+#ifdef CONFIG_MMU5+6typedef struct {7#if __LINUX_ARM_ARCH__ >= 68 unsigned int id;···11#define ASID(mm) ((mm)->context.id & 255)12#else13#define ASID(mm) (0)14+#endif15+16+#else17+18+/*19+ * From nommu.h:20+ * Copyright (C) 2002, David McCullough <davidm@snapgear.com>21+ * modified for 2.6 by Hyok S. Choi <hyok.choi@samsung.com>22+ */23+typedef struct {24+ struct vm_list_struct *vmlist;25+ unsigned long end_brk;26+} mm_context_t;27+28#endif2930#endif
+2
include/asm-arm/mmu_context.h
···82switch_mm(struct mm_struct *prev, struct mm_struct *next,83 struct task_struct *tsk)84{085 unsigned int cpu = smp_processor_id();8687 if (prev != next) {···92 if (cache_is_vivt())93 cpu_clear(cpu, prev->cpu_vm_mask);94 }095}9697#define deactivate_mm(tsk,mm) do { } while (0)
···82switch_mm(struct mm_struct *prev, struct mm_struct *next,83 struct task_struct *tsk)84{85+#ifdef CONFIG_MMU86 unsigned int cpu = smp_processor_id();8788 if (prev != next) {···91 if (cache_is_vivt())92 cpu_clear(cpu, prev->cpu_vm_mask);93 }94+#endif95}9697#define deactivate_mm(tsk,mm) do { } while (0)
···1+/*2+ * linux/include/asm-arm/page-nommu.h3+ *4+ * Copyright (C) 2004 Hyok S. Choi5+ *6+ * This program is free software; you can redistribute it and/or modify7+ * it under the terms of the GNU General Public License version 2 as8+ * published by the Free Software Foundation.9+ */10+#ifndef _ASMARM_PAGE_NOMMU_H11+#define _ASMARM_PAGE_NOMMU_H12+13+#if !defined(CONFIG_SMALL_TASKS) && PAGE_SHIFT < 1314+#define KTHREAD_SIZE (8192)15+#else16+#define KTHREAD_SIZE PAGE_SIZE17+#endif18+19+#define get_user_page(vaddr) __get_free_page(GFP_KERNEL)20+#define free_user_page(page, addr) free_page(addr)21+22+#define clear_page(page) memset((page), 0, PAGE_SIZE)23+#define copy_page(to,from) memcpy((to), (from), PAGE_SIZE)24+25+#define clear_user_page(page, vaddr, pg) clear_page(page)26+#define copy_user_page(to, from, vaddr, pg) copy_page(to, from)27+28+/*29+ * These are used to make use of C type-checking..30+ */31+typedef unsigned long pte_t;32+typedef unsigned long pmd_t;33+typedef unsigned long pgd_t[2];34+typedef unsigned long pgprot_t;35+36+#define pte_val(x) (x)37+#define pmd_val(x) (x)38+#define pgd_val(x) ((x)[0])39+#define pgprot_val(x) (x)40+41+#define __pte(x) (x)42+#define __pmd(x) (x)43+#define __pgprot(x) (x)44+45+/* to align the pointer to the (next) page boundary */46+#define PAGE_ALIGN(addr) (((addr)+PAGE_SIZE-1)&PAGE_MASK)47+48+extern unsigned long memory_start;49+extern unsigned long memory_end;50+51+#endif
···1+/*2+ * linux/include/asm-arm/pgtable-nommu.h3+ *4+ * Copyright (C) 1995-2002 Russell King5+ * Copyright (C) 2004 Hyok S. Choi6+ *7+ * This program is free software; you can redistribute it and/or modify8+ * it under the terms of the GNU General Public License version 2 as9+ * published by the Free Software Foundation.10+ */11+#ifndef _ASMARM_PGTABLE_NOMMU_H12+#define _ASMARM_PGTABLE_NOMMU_H13+14+#ifndef __ASSEMBLY__15+16+#include <linux/config.h>17+#include <linux/slab.h>18+#include <asm/processor.h>19+#include <asm/page.h>20+#include <asm/io.h>21+22+/*23+ * Trivial page table functions.24+ */25+#define pgd_present(pgd) (1)26+#define pgd_none(pgd) (0)27+#define pgd_bad(pgd) (0)28+#define pgd_clear(pgdp)29+#define kern_addr_valid(addr) (1)30+#define pmd_offset(a, b) ((void *)0)31+/* FIXME */32+/*33+ * PMD_SHIFT determines the size of the area a second-level page table can map34+ * PGDIR_SHIFT determines what a third-level page table entry can map35+ */36+#define PGDIR_SHIFT 2137+38+#define PGDIR_SIZE (1UL << PGDIR_SHIFT)39+#define PGDIR_MASK (~(PGDIR_SIZE-1))40+/* FIXME */41+42+#define PAGE_NONE __pgprot(0)43+#define PAGE_SHARED __pgprot(0)44+#define PAGE_COPY __pgprot(0)45+#define PAGE_READONLY __pgprot(0)46+#define PAGE_KERNEL __pgprot(0)47+48+//extern void paging_init(struct meminfo *, struct machine_desc *);49+#define swapper_pg_dir ((pgd_t *) 0)50+51+#define __swp_type(x) (0)52+#define __swp_offset(x) (0)53+#define __swp_entry(typ,off) ((swp_entry_t) { ((typ) | ((off) << 7)) })54+#define __pte_to_swp_entry(pte) ((swp_entry_t) { pte_val(pte) })55+#define __swp_entry_to_pte(x) ((pte_t) { (x).val })56+57+58+typedef pte_t *pte_addr_t;59+60+static inline int pte_file(pte_t pte) { return 0; }61+62+/*63+ * ZERO_PAGE is a global shared page that is always zero: used64+ * for zero-mapped memory areas etc..65+ */66+#define ZERO_PAGE(vaddr) (virt_to_page(0))67+68+/*69+ * Mark the prot value as uncacheable and unbufferable.70+ */71+#define pgprot_noncached(prot) __pgprot(0)72+#define pgprot_writecombine(prot) __pgprot(0)73+74+75+/*76+ * These would be in other places but having them here reduces the diffs.77+ */78+extern unsigned int kobjsize(const void *objp);79+extern int is_in_rom(unsigned long);80+81+/*82+ * No page table caches to initialise.83+ */84+#define pgtable_cache_init() do { } while (0)85+#define io_remap_page_range remap_page_range86+#define io_remap_pfn_range remap_pfn_range87+88+#define MK_IOSPACE_PFN(space, pfn) (pfn)89+#define GET_IOSPACE(pfn) 090+#define GET_PFN(pfn) (pfn)91+92+93+/*94+ * All 32bit addresses are effectively valid for vmalloc...95+ * Sort of meaningless for non-VM targets.96+ */97+#define VMALLOC_START 098+#define VMALLOC_END 0xffffffff99+100+#define FIRST_USER_ADDRESS (0)101+102+#else 103+104+/*105+ * dummy tlb and user structures.106+ */107+#define v3_tlb_fns (0)108+#define v4_tlb_fns (0)109+#define v4wb_tlb_fns (0)110+#define v4wbi_tlb_fns (0)111+#define v6_tlb_fns (0)112+113+#define v3_user_fns (0)114+#define v4_user_fns (0)115+#define v4_mc_user_fns (0)116+#define v4wb_user_fns (0)117+#define v4wt_user_fns (0)118+#define v6_user_fns (0)119+#define xscale_mc_user_fns (0)120+121+#endif /*__ASSEMBLY__*/122+123+#endif /* _ASMARM_PGTABLE_H */
+9-1
include/asm-arm/pgtable.h
···11#define _ASMARM_PGTABLE_H1213#include <asm-generic/4level-fixup.h>00000001415#include <asm/memory.h>16-#include <asm/proc-fns.h>17#include <asm/arch/vmalloc.h>1819/*···383#define pgtable_cache_init() do { } while (0)384385#endif /* !__ASSEMBLY__ */00386387#endif /* _ASMARM_PGTABLE_H */
···41extern int fixup_exception(struct pt_regs *regs);4243/*000000044 * Note that this is actually 0x1,0000,000045 */46#define KERNEL_DS 0x0000000047-#define USER_DS TASK_SIZE48-49#define get_ds() (KERNEL_DS)000050#define get_fs() (current_thread_info()->addr_limit)5152-static inline void set_fs (mm_segment_t fs)53{54 current_thread_info()->addr_limit = fs;55 modify_domain(DOMAIN_KERNEL, fs ? DOMAIN_CLIENT : DOMAIN_MANAGER);···84 : "cc"); \85 flag; })8687-#define access_ok(type,addr,size) (__range_ok(addr,size) == 0)88-89/*90 * Single-value transfer routines. They automatically use the right91 * size if we just have the right pointer type. Note that the functions···94 * fixup code, but there are a few places where it intrudes on the95 * main code path. When we only write to user space, there is no96 * problem.97- *98- * The "__xxx" versions of the user access functions do not verify the99- * address space - it must have been done previously with a separate100- * "access_ok()" call.101- *102- * The "xxx_error" versions set the third argument to EFAULT if an103- * error occurs, and leave it unchanged on success. Note that these104- * versions are void (ie, don't return a value as such).105 */106-107extern int __get_user_1(void *);108extern int __get_user_2(void *);109extern int __get_user_4(void *);110-extern int __get_user_bad(void);111112#define __get_user_x(__r2,__p,__e,__s,__i...) \113 __asm__ __volatile__ ( \···128 __e; \129 })13000000000000000000000000000000000000000000000000000000000000000000000131#define __get_user(x,ptr) \132({ \133 long __gu_err = 0; \···276 : "+r" (err), "=&r" (x) \277 : "r" (addr), "i" (-EFAULT) \278 : "cc")279-280-extern int __put_user_1(void *, unsigned int);281-extern int __put_user_2(void *, unsigned int);282-extern int __put_user_4(void *, unsigned int);283-extern int __put_user_8(void *, unsigned long long);284-extern int __put_user_bad(void);285-286-#define __put_user_x(__r2,__p,__e,__s) \287- __asm__ __volatile__ ( \288- __asmeq("%0", "r0") __asmeq("%2", "r2") \289- "bl __put_user_" #__s \290- : "=&r" (__e) \291- : "0" (__p), "r" (__r2) \292- : "ip", "lr", "cc")293-294-#define put_user(x,p) \295- ({ \296- const register typeof(*(p)) __r2 asm("r2") = (x); \297- const register typeof(*(p)) __user *__p asm("r0") = (p);\298- register int __e asm("r0"); \299- switch (sizeof(*(__p))) { \300- case 1: \301- __put_user_x(__r2, __p, __e, 1); \302- break; \303- case 2: \304- __put_user_x(__r2, __p, __e, 2); \305- break; \306- case 4: \307- __put_user_x(__r2, __p, __e, 4); \308- break; \309- case 8: \310- __put_user_x(__r2, __p, __e, 8); \311- break; \312- default: __e = __put_user_bad(); break; \313- } \314- __e; \315- })316317#define __put_user(x,ptr) \318({ \···381 : "r" (x), "i" (-EFAULT) \382 : "cc")383384-extern unsigned long __arch_copy_from_user(void *to, const void __user *from, unsigned long n);385-extern unsigned long __arch_copy_to_user(void __user *to, const void *from, unsigned long n);386-extern unsigned long __arch_clear_user(void __user *addr, unsigned long n);387-extern unsigned long __arch_strncpy_from_user(char *to, const char __user *from, unsigned long count);388-extern unsigned long __arch_strnlen_user(const char __user *s, long n);00000000389390static inline unsigned long copy_from_user(void *to, const void __user *from, unsigned long n)391{392 if (access_ok(VERIFY_READ, from, n))393- n = __arch_copy_from_user(to, from, n);394 else /* security hole - plug it */395 memzero(to, n);396 return n;397}398399-static inline unsigned long __copy_from_user(void *to, const void __user *from, unsigned long n)400-{401- return __arch_copy_from_user(to, from, n);402-}403-404static inline unsigned long copy_to_user(void __user *to, const void *from, unsigned long n)405{406 if (access_ok(VERIFY_WRITE, to, n))407- n = __arch_copy_to_user(to, from, n);408 return n;409-}410-411-static inline unsigned long __copy_to_user(void __user *to, const void *from, unsigned long n)412-{413- return __arch_copy_to_user(to, from, n);414}415416#define __copy_to_user_inatomic __copy_to_user417#define __copy_from_user_inatomic __copy_from_user418419-static inline unsigned long clear_user (void __user *to, unsigned long n)420{421 if (access_ok(VERIFY_WRITE, to, n))422- n = __arch_clear_user(to, n);423 return n;424}425426-static inline unsigned long __clear_user (void __user *to, unsigned long n)427-{428- return __arch_clear_user(to, n);429-}430-431-static inline long strncpy_from_user (char *dst, const char __user *src, long count)432{433 long res = -EFAULT;434 if (access_ok(VERIFY_READ, src, 1))435- res = __arch_strncpy_from_user(dst, src, count);436 return res;437-}438-439-static inline long __strncpy_from_user (char *dst, const char __user *src, long count)440-{441- return __arch_strncpy_from_user(dst, src, count);442}443444#define strlen_user(s) strnlen_user(s, ~0UL >> 1)···436 unsigned long res = 0;437438 if (__addr_ok(s))439- res = __arch_strnlen_user(s, n);440441 return res;442}
···41extern int fixup_exception(struct pt_regs *regs);4243/*44+ * These two are intentionally not defined anywhere - if the kernel45+ * code generates any references to them, that's a bug.46+ */47+extern int __get_user_bad(void);48+extern int __put_user_bad(void);49+50+/*51 * Note that this is actually 0x1,0000,000052 */53#define KERNEL_DS 0x000000000054#define get_ds() (KERNEL_DS)55+56+#ifdef CONFIG_MMU57+58+#define USER_DS TASK_SIZE59#define get_fs() (current_thread_info()->addr_limit)6061+static inline void set_fs(mm_segment_t fs)62{63 current_thread_info()->addr_limit = fs;64 modify_domain(DOMAIN_KERNEL, fs ? DOMAIN_CLIENT : DOMAIN_MANAGER);···75 : "cc"); \76 flag; })770078/*79 * Single-value transfer routines. They automatically use the right80 * size if we just have the right pointer type. Note that the functions···87 * fixup code, but there are a few places where it intrudes on the88 * main code path. When we only write to user space, there is no89 * problem.0000000090 */091extern int __get_user_1(void *);92extern int __get_user_2(void *);93extern int __get_user_4(void *);09495#define __get_user_x(__r2,__p,__e,__s,__i...) \96 __asm__ __volatile__ ( \···131 __e; \132 })133134+extern int __put_user_1(void *, unsigned int);135+extern int __put_user_2(void *, unsigned int);136+extern int __put_user_4(void *, unsigned int);137+extern int __put_user_8(void *, unsigned long long);138+139+#define __put_user_x(__r2,__p,__e,__s) \140+ __asm__ __volatile__ ( \141+ __asmeq("%0", "r0") __asmeq("%2", "r2") \142+ "bl __put_user_" #__s \143+ : "=&r" (__e) \144+ : "0" (__p), "r" (__r2) \145+ : "ip", "lr", "cc")146+147+#define put_user(x,p) \148+ ({ \149+ const register typeof(*(p)) __r2 asm("r2") = (x); \150+ const register typeof(*(p)) __user *__p asm("r0") = (p);\151+ register int __e asm("r0"); \152+ switch (sizeof(*(__p))) { \153+ case 1: \154+ __put_user_x(__r2, __p, __e, 1); \155+ break; \156+ case 2: \157+ __put_user_x(__r2, __p, __e, 2); \158+ break; \159+ case 4: \160+ __put_user_x(__r2, __p, __e, 4); \161+ break; \162+ case 8: \163+ __put_user_x(__r2, __p, __e, 8); \164+ break; \165+ default: __e = __put_user_bad(); break; \166+ } \167+ __e; \168+ })169+170+#else /* CONFIG_MMU */171+172+/*173+ * uClinux has only one addr space, so has simplified address limits.174+ */175+#define USER_DS KERNEL_DS176+177+#define segment_eq(a,b) (1)178+#define __addr_ok(addr) (1)179+#define __range_ok(addr,size) (0)180+#define get_fs() (KERNEL_DS)181+182+static inline void set_fs(mm_segment_t fs)183+{184+}185+186+#define get_user(x,p) __get_user(x,p)187+#define put_user(x,p) __put_user(x,p)188+189+#endif /* CONFIG_MMU */190+191+#define access_ok(type,addr,size) (__range_ok(addr,size) == 0)192+193+/*194+ * The "__xxx" versions of the user access functions do not verify the195+ * address space - it must have been done previously with a separate196+ * "access_ok()" call.197+ *198+ * The "xxx_error" versions set the third argument to EFAULT if an199+ * error occurs, and leave it unchanged on success. Note that these200+ * versions are void (ie, don't return a value as such).201+ */202#define __get_user(x,ptr) \203({ \204 long __gu_err = 0; \···211 : "+r" (err), "=&r" (x) \212 : "r" (addr), "i" (-EFAULT) \213 : "cc")0000000000000000000000000000000000000214215#define __put_user(x,ptr) \216({ \···353 : "r" (x), "i" (-EFAULT) \354 : "cc")355356+357+#ifdef CONFIG_MMU358+extern unsigned long __copy_from_user(void *to, const void __user *from, unsigned long n);359+extern unsigned long __copy_to_user(void __user *to, const void *from, unsigned long n);360+extern unsigned long __clear_user(void __user *addr, unsigned long n);361+#else362+#define __copy_from_user(to,from,n) (memcpy(to, (void __force *)from, n), 0)363+#define __copy_to_user(to,from,n) (memcpy((void __force *)to, from, n), 0)364+#define __clear_user(addr,n) (memset((void __force *)addr, 0, n), 0)365+#endif366+367+extern unsigned long __strncpy_from_user(char *to, const char __user *from, unsigned long count);368+extern unsigned long __strnlen_user(const char __user *s, long n);369370static inline unsigned long copy_from_user(void *to, const void __user *from, unsigned long n)371{372 if (access_ok(VERIFY_READ, from, n))373+ n = __copy_from_user(to, from, n);374 else /* security hole - plug it */375 memzero(to, n);376 return n;377}37800000379static inline unsigned long copy_to_user(void __user *to, const void *from, unsigned long n)380{381 if (access_ok(VERIFY_WRITE, to, n))382+ n = __copy_to_user(to, from, n);383 return n;00000384}385386#define __copy_to_user_inatomic __copy_to_user387#define __copy_from_user_inatomic __copy_from_user388389+static inline unsigned long clear_user(void __user *to, unsigned long n)390{391 if (access_ok(VERIFY_WRITE, to, n))392+ n = __clear_user(to, n);393 return n;394}395396+static inline long strncpy_from_user(char *dst, const char __user *src, long count)00000397{398 long res = -EFAULT;399 if (access_ok(VERIFY_READ, src, 1))400+ res = __strncpy_from_user(dst, src, count);401 return res;00000402}403404#define strlen_user(s) strnlen_user(s, ~0UL >> 1)···420 unsigned long res = 0;421422 if (__addr_ok(s))423+ res = __strnlen_user(s, n);424425 return res;426}
+14
include/asm-arm/ucontext.h
···35 * bytes, to prevent unpredictable padding in the signal frame.36 */370000000000038#ifdef CONFIG_IWMMXT39/* iwmmxt_area is 0x98 bytes long, preceeded by 8 bytes of signature */40#define IWMMXT_MAGIC 0x12ef842a···85 * one of these.86 */87struct aux_sigframe {00088#ifdef CONFIG_IWMMXT89 struct iwmmxt_sigframe iwmmxt;90#endif
···35 * bytes, to prevent unpredictable padding in the signal frame.36 */3738+#ifdef CONFIG_CRUNCH39+#define CRUNCH_MAGIC 0x5065cf0340+#define CRUNCH_STORAGE_SIZE (CRUNCH_SIZE + 8)41+42+struct crunch_sigframe {43+ unsigned long magic;44+ unsigned long size;45+ struct crunch_state storage;46+} __attribute__((__aligned__(8)));47+#endif48+49#ifdef CONFIG_IWMMXT50/* iwmmxt_area is 0x98 bytes long, preceeded by 8 bytes of signature */51#define IWMMXT_MAGIC 0x12ef842a···74 * one of these.75 */76struct aux_sigframe {77+#ifdef CONFIG_CRUNCH78+ struct crunch_sigframe crunch;79+#endif80#ifdef CONFIG_IWMMXT81 struct iwmmxt_sigframe iwmmxt;82#endif
···155{156 unsigned long flags;157 spin_lock_irqsave(&t->buf.lock, flags);158+ if (t->buf.tail != NULL)0159 t->buf.tail->commit = t->buf.tail->used;0160 spin_unlock_irqrestore(&t->buf.lock, flags);161 schedule_work(&t->buf.work);162}
+20
include/linux/module.h
···203#define EXPORT_SYMBOL_GPL_FUTURE(sym) \204 __EXPORT_SYMBOL(sym, "_gpl_future")205000000000206#endif207208struct module_ref···269 const struct kernel_symbol *gpl_syms;270 unsigned int num_gpl_syms;271 const unsigned long *gpl_crcs;000000000272273 /* symbols that will be GPL-only in the near future. */274 const struct kernel_symbol *gpl_future_syms;···474#define EXPORT_SYMBOL(sym)475#define EXPORT_SYMBOL_GPL(sym)476#define EXPORT_SYMBOL_GPL_FUTURE(sym)00477478/* Given an address, look for it in the exception tables. */479static inline const struct exception_table_entry *
···203#define EXPORT_SYMBOL_GPL_FUTURE(sym) \204 __EXPORT_SYMBOL(sym, "_gpl_future")205206+207+#ifdef CONFIG_UNUSED_SYMBOLS208+#define EXPORT_UNUSED_SYMBOL(sym) __EXPORT_SYMBOL(sym, "_unused")209+#define EXPORT_UNUSED_SYMBOL_GPL(sym) __EXPORT_SYMBOL(sym, "_unused_gpl")210+#else211+#define EXPORT_UNUSED_SYMBOL(sym)212+#define EXPORT_UNUSED_SYMBOL_GPL(sym)213+#endif214+215#endif216217struct module_ref···260 const struct kernel_symbol *gpl_syms;261 unsigned int num_gpl_syms;262 const unsigned long *gpl_crcs;263+264+ /* unused exported symbols. */265+ const struct kernel_symbol *unused_syms;266+ unsigned int num_unused_syms;267+ const unsigned long *unused_crcs;268+ /* GPL-only, unused exported symbols. */269+ const struct kernel_symbol *unused_gpl_syms;270+ unsigned int num_unused_gpl_syms;271+ const unsigned long *unused_gpl_crcs;272273 /* symbols that will be GPL-only in the near future. */274 const struct kernel_symbol *gpl_future_syms;···456#define EXPORT_SYMBOL(sym)457#define EXPORT_SYMBOL_GPL(sym)458#define EXPORT_SYMBOL_GPL_FUTURE(sym)459+#define EXPORT_UNUSED_SYMBOL(sym)460+#define EXPORT_UNUSED_SYMBOL_GPL(sym)461462/* Given an address, look for it in the exception tables. */463static inline const struct exception_table_entry *
···642 u16 bus_num;643 u16 chip_select;64400000645 /* ... may need additional spi_device chip config data here.646 * avoid stuff protocol drivers can set; but include stuff647 * needed to behave without being bound to a driver:648- * - chipselect polarity649 * - quirks like clock rate mattering when not selected650 */651};
···642 u16 bus_num;643 u16 chip_select;644645+ /* mode becomes spi_device.mode, and is essential for chips646+ * where the default of SPI_CS_HIGH = 0 is wrong.647+ */648+ u8 mode;649+650 /* ... may need additional spi_device chip config data here.651 * avoid stuff protocol drivers can set; but include stuff652 * needed to behave without being bound to a driver:0653 * - quirks like clock rate mattering when not selected654 */655};
-2
include/linux/tty.h
···57 unsigned char *flag_buf_ptr;58 int used;59 int size;60- int active;61 int commit;62 int read;63 /* Data points here */···258#define TTY_DO_WRITE_WAKEUP 5 /* Call write_wakeup after queuing new */259#define TTY_PUSH 6 /* n_tty private */260#define TTY_CLOSING 7 /* ->close() in progress */261-#define TTY_DONT_FLIP 8 /* Defer buffer flip */262#define TTY_LDISC 9 /* Line discipline attached */263#define TTY_HW_COOK_OUT 14 /* Hardware can do output cooking */264#define TTY_HW_COOK_IN 15 /* Hardware can do input cooking */
···57 unsigned char *flag_buf_ptr;58 int used;59 int size;060 int commit;61 int read;62 /* Data points here */···259#define TTY_DO_WRITE_WAKEUP 5 /* Call write_wakeup after queuing new */260#define TTY_PUSH 6 /* n_tty private */261#define TTY_CLOSING 7 /* ->close() in progress */0262#define TTY_LDISC 9 /* Line discipline attached */263#define TTY_HW_COOK_OUT 14 /* Hardware can do output cooking */264#define TTY_HW_COOK_IN 15 /* Hardware can do input cooking */
···1+/*2 Copyright (C) 2002 Richard Henderson3 Copyright (C) 2001 Rusty Russell, 2002 Rusty Russell IBM.4···122extern const struct kernel_symbol __stop___ksymtab_gpl[];123extern const struct kernel_symbol __start___ksymtab_gpl_future[];124extern const struct kernel_symbol __stop___ksymtab_gpl_future[];125+extern const struct kernel_symbol __start___ksymtab_unused[];126+extern const struct kernel_symbol __stop___ksymtab_unused[];127+extern const struct kernel_symbol __start___ksymtab_unused_gpl[];128+extern const struct kernel_symbol __stop___ksymtab_unused_gpl[];129+extern const struct kernel_symbol __start___ksymtab_gpl_future[];130+extern const struct kernel_symbol __stop___ksymtab_gpl_future[];131extern const unsigned long __start___kcrctab[];132extern const unsigned long __start___kcrctab_gpl[];133extern const unsigned long __start___kcrctab_gpl_future[];134+extern const unsigned long __start___kcrctab_unused[];135+extern const unsigned long __start___kcrctab_unused_gpl[];136137#ifndef CONFIG_MODVERSIONS138#define symversion(base, idx) NULL···142 if (strcmp(ks->name, name) == 0)143 return ks;144 return NULL;145+}146+147+static void printk_unused_warning(const char *name)148+{149+ printk(KERN_WARNING "Symbol %s is marked as UNUSED, "150+ "however this module is using it.\n", name);151+ printk(KERN_WARNING "This symbol will go away in the future.\n");152+ printk(KERN_WARNING "Please evalute if this is the right api to use, "153+ "and if it really is, submit a report the linux kernel "154+ "mailinglist together with submitting your code for "155+ "inclusion.\n");156}157158/* Find a symbol, return value, crc and module which owns it */···186 return ks->value;187 }188189+ ks = lookup_symbol(name, __start___ksymtab_unused,190+ __stop___ksymtab_unused);191+ if (ks) {192+ printk_unused_warning(name);193+ *crc = symversion(__start___kcrctab_unused,194+ (ks - __start___ksymtab_unused));195+ return ks->value;196+ }197+198+ if (gplok)199+ ks = lookup_symbol(name, __start___ksymtab_unused_gpl,200+ __stop___ksymtab_unused_gpl);201+ if (ks) {202+ printk_unused_warning(name);203+ *crc = symversion(__start___kcrctab_unused_gpl,204+ (ks - __start___ksymtab_unused_gpl));205+ return ks->value;206+ }207+208 /* Now try modules. */ 209 list_for_each_entry(mod, &modules, list) {210 *owner = mod;···201 if (ks) {202 *crc = symversion(mod->gpl_crcs,203 (ks - mod->gpl_syms));204+ return ks->value;205+ }206+ }207+ ks = lookup_symbol(name, mod->unused_syms, mod->unused_syms + mod->num_unused_syms);208+ if (ks) {209+ printk_unused_warning(name);210+ *crc = symversion(mod->unused_crcs, (ks - mod->unused_syms));211+ return ks->value;212+ }213+214+ if (gplok) {215+ ks = lookup_symbol(name, mod->unused_gpl_syms,216+ mod->unused_gpl_syms + mod->num_unused_gpl_syms);217+ if (ks) {218+ printk_unused_warning(name);219+ *crc = symversion(mod->unused_gpl_crcs,220+ (ks - mod->unused_gpl_syms));221 return ks->value;222 }223 }···1403 Elf_Ehdr *hdr;1404 Elf_Shdr *sechdrs;1405 char *secstrings, *args, *modmagic, *strtab = NULL;1406+ unsigned int i;1407+ unsigned int symindex = 0;1408+ unsigned int strindex = 0;1409+ unsigned int setupindex;1410+ unsigned int exindex;1411+ unsigned int exportindex;1412+ unsigned int modindex;1413+ unsigned int obsparmindex;1414+ unsigned int infoindex;1415+ unsigned int gplindex;1416+ unsigned int crcindex;1417+ unsigned int gplcrcindex;1418+ unsigned int versindex;1419+ unsigned int pcpuindex;1420+ unsigned int gplfutureindex;1421+ unsigned int gplfuturecrcindex;1422+ unsigned int unwindex = 0;1423+ unsigned int unusedindex;1424+ unsigned int unusedcrcindex;1425+ unsigned int unusedgplindex;1426+ unsigned int unusedgplcrcindex;1427 struct module *mod;1428 long err = 0;1429 void *percpu = NULL, *ptr = NULL; /* Stops spurious gcc warning */···1487 exportindex = find_sec(hdr, sechdrs, secstrings, "__ksymtab");1488 gplindex = find_sec(hdr, sechdrs, secstrings, "__ksymtab_gpl");1489 gplfutureindex = find_sec(hdr, sechdrs, secstrings, "__ksymtab_gpl_future");1490+ unusedindex = find_sec(hdr, sechdrs, secstrings, "__ksymtab_unused");1491+ unusedgplindex = find_sec(hdr, sechdrs, secstrings, "__ksymtab_unused_gpl");1492 crcindex = find_sec(hdr, sechdrs, secstrings, "__kcrctab");1493 gplcrcindex = find_sec(hdr, sechdrs, secstrings, "__kcrctab_gpl");1494 gplfuturecrcindex = find_sec(hdr, sechdrs, secstrings, "__kcrctab_gpl_future");1495+ unusedcrcindex = find_sec(hdr, sechdrs, secstrings, "__kcrctab_unused");1496+ unusedgplcrcindex = find_sec(hdr, sechdrs, secstrings, "__kcrctab_unused_gpl");1497 setupindex = find_sec(hdr, sechdrs, secstrings, "__param");1498 exindex = find_sec(hdr, sechdrs, secstrings, "__ex_table");1499 obsparmindex = find_sec(hdr, sechdrs, secstrings, "__obsparm");···1638 mod->gpl_crcs = (void *)sechdrs[gplcrcindex].sh_addr;1639 mod->num_gpl_future_syms = sechdrs[gplfutureindex].sh_size /1640 sizeof(*mod->gpl_future_syms);1641+ mod->num_unused_syms = sechdrs[unusedindex].sh_size /1642+ sizeof(*mod->unused_syms);1643+ mod->num_unused_gpl_syms = sechdrs[unusedgplindex].sh_size /1644+ sizeof(*mod->unused_gpl_syms);1645 mod->gpl_future_syms = (void *)sechdrs[gplfutureindex].sh_addr;1646 if (gplfuturecrcindex)1647 mod->gpl_future_crcs = (void *)sechdrs[gplfuturecrcindex].sh_addr;16481649+ mod->unused_syms = (void *)sechdrs[unusedindex].sh_addr;1650+ if (unusedcrcindex)1651+ mod->unused_crcs = (void *)sechdrs[unusedcrcindex].sh_addr;1652+ mod->unused_gpl_syms = (void *)sechdrs[unusedgplindex].sh_addr;1653+ if (unusedgplcrcindex)1654+ mod->unused_crcs = (void *)sechdrs[unusedgplcrcindex].sh_addr;1655+1656#ifdef CONFIG_MODVERSIONS1657 if ((mod->num_syms && !crcindex) || 1658 (mod->num_gpl_syms && !gplcrcindex) ||1659+ (mod->num_gpl_future_syms && !gplfuturecrcindex) ||1660+ (mod->num_unused_syms && !unusedcrcindex) ||1661+ (mod->num_unused_gpl_syms && !unusedgplcrcindex)) {1662 printk(KERN_WARNING "%s: No versions for exported symbols."1663 " Tainting kernel.\n", mod->name);1664 add_taint(TAINT_FORCED_MODULE);
+16
lib/Kconfig.debug
···23 keys are documented in <file:Documentation/sysrq.txt>. Don't say Y24 unless you really know what this hack does.25000000000000000026config DEBUG_KERNEL27 bool "Kernel debugging"28 help
···23 keys are documented in <file:Documentation/sysrq.txt>. Don't say Y24 unless you really know what this hack does.2526+config UNUSED_SYMBOLS27+ bool "Enable unused/obsolete exported symbols"28+ default y if X8629+ help30+ Unused but exported symbols make the kernel needlessly bigger. For31+ that reason most of these unused exports will soon be removed. This32+ option is provided temporarily to provide a transition period in case33+ some external kernel module needs one of these symbols anyway. If you34+ encounter such a case in your module, consider if you are actually35+ using the right API. (rationale: since nobody in the kernel is using36+ this in a module, there is a pretty good chance it's actually the37+ wrong interface to use). If you really need the symbol, please send a38+ mail to the linux kernel mailing list mentioning the symbol and why39+ you really need it, and what the merge plan to the mainline kernel for40+ your module is.41+42config DEBUG_KERNEL43 bool "Kernel debugging"44 help
+1-1
lib/vsprintf.c
···489 if (str < end)490 *str = '\0';491 else492- *end = '\0';493 }494 /* the trailing null byte doesn't count towards the total */495 return str-buf;
···489 if (str < end)490 *str = '\0';491 else492+ end[-1] = '\0';493 }494 /* the trailing null byte doesn't count towards the total */495 return str-buf;
···24 * vmscan's shrink_list, to make sync_page look nicer, and to allow25 * future use of radix_tree tags in the swap cache.26 */27-static struct address_space_operations swap_aops = {28 .writepage = swap_writepage,29 .sync_page = block_sync_page,30 .set_page_dirty = __set_page_dirty_nobuffers,
···24 * vmscan's shrink_list, to make sync_page look nicer, and to allow25 * future use of radix_tree tags in the swap cache.26 */27+static const struct address_space_operations swap_aops = {28 .writepage = swap_writepage,29 .sync_page = block_sync_page,30 .set_page_dirty = __set_page_dirty_nobuffers,