diff -u --recursive v2.1.35/linux/Documentation/Changes linux/Documentation/Changes --- v2.1.35/linux/Documentation/Changes Wed Apr 16 14:14:58 1997 +++ linux/Documentation/Changes Thu Apr 17 12:46:56 1997 @@ -29,7 +29,7 @@ Also, don't forget http://www.linuxhq.com/ for all your Linux kernel needs. -Last updated: April 15, 1997. +Last updated: April 17, 1997. Current Author: Chris Ricker (gt1355b@prism.gatech.edu). Current Minimal Requirements @@ -184,7 +184,7 @@ Binutils: ld -v Gnu C: gcc -v or gcc --version -Kbd: loadkeys -h +Kbd: dumpkeys -h Ld.so: ldd -v Libc: ls -l /lib/libc.so.* Libc++: ls -l /usr/lib/libg++.so.* @@ -249,7 +249,7 @@ The 2.1.34 release: ftp://ftp.redhat.com/pub/alphabits/modutils-2.1.34.tar.gz -ftp://ftp.kernel.org/pub/linux/kernel/modutils-2.1.34.tar.gz +ftp://ftp.kernel.org/pub/linux/kernel/v2.1/modutils-2.1.34.tar.gz Procps utilities ================ diff -u --recursive v2.1.35/linux/Documentation/Configure.help linux/Documentation/Configure.help --- v2.1.35/linux/Documentation/Configure.help Wed Apr 16 14:14:58 1997 +++ linux/Documentation/Configure.help Thu Apr 17 14:40:36 1997 @@ -3063,22 +3063,20 @@ Documentation/networking/net-modules.txt. The module will be called pt.o. -WaveLAN support +AT&T WaveLAN & DEC RoamAbout DS support CONFIG_WAVELAN - These are cards for wireless ethernet-like networking. Supported are - AT&T GIS and NCR WaveLAN cards. If you want to use a card of this - type under Linux, say Y and read the Ethernet-HOWTO, available via - ftp (user: anonymous) in sunsite.unc.edu:/pub/Linux/docs/HOWTO. Some - more specific information is contained in - drivers/net/README.wavelan. This driver is also available as a - module ( = code which can be inserted in and removed from the - running kernel whenever you want). The module will be called - wavelan.o. If you want to compile it as a module, say M here and - read Documentation/modules.txt as well as - Documentation/networking/net-modules.txt. If you plan to use more - than one network card under linux, read the - Multiple-Ethernet-mini-HOWTO, available from - sunsite.unc.edu:/pub/Linux/docs/HOWTO/mini. + The Lucent Wavelan (formerly NCR and AT&T ; or DEC RoamAbout DS) + is a Radio LAN (wireless ethernet-like) at 900 MHz and 2.4 GHz. + This driver support the ISA version of the Wavelan. A driver for + the pcmcia hardware is available in David Hinds's pcmcia package. + This driver is fairly stable and may be compiled as a module + (wavelan.o). It implements many nice feature and the Wireless + Extensions (you must get the Wireless tools from the net). + For documentation, refer to : + o the wavelan man page, wireless tools man pages + o wavelan.p.h and the source code + o Ethernet-HOWTO, Multiple-Ethernet-mini-HOWTO, Module-HOWTO + o More documentation to come when I will have the time :-) HP PCLAN+ (27247B and 27252A) support CONFIG_HPLAN_PLUS diff -u --recursive v2.1.35/linux/Documentation/parport.txt linux/Documentation/parport.txt --- v2.1.35/linux/Documentation/parport.txt Sun Apr 13 10:18:20 1997 +++ linux/Documentation/parport.txt Thu Apr 17 14:48:53 1997 @@ -47,9 +47,13 @@ Also: * If you selected the device autoprobe at compile time, you can say -`lp=auto' on the kernel command line, and lp will create devices only -for those ports that seem to have printers attached. + `lp=auto' on the kernel command line, and lp will create devices + only for those ports that seem to have printers attached. * If you give PLIP the `timid' parameter, either with `plip=timid' on -the command line, or with `insmod plip timid=1' when using modules, it -will avoid any ports that seem to be in use by other devices. + the command line, or with `insmod plip timid=1' when using modules, + it will avoid any ports that seem to be in use by other devices. + + * If your BIOS allows you to engage "ECP mode", you may find that + your port's IRQ can be autoprobed, without having to specify any + parameters. diff -u --recursive v2.1.35/linux/Makefile linux/Makefile --- v2.1.35/linux/Makefile Wed Apr 16 14:14:59 1997 +++ linux/Makefile Thu Apr 17 14:48:53 1997 @@ -1,6 +1,6 @@ VERSION = 2 PATCHLEVEL = 1 -SUBLEVEL = 35 +SUBLEVEL = 36 ARCH := $(shell uname -m | sed s/i.86/i386/) @@ -118,7 +118,8 @@ FILESYSTEMS =fs/filesystems.a NETWORKS =net/network.a DRIVERS =drivers/block/block.a \ - drivers/char/char.a + drivers/char/char.a \ + drivers/pnp/pnp.a LIBS =$(TOPDIR)/lib/lib.a SUBDIRS =kernel drivers mm fs net ipc lib @@ -142,10 +143,6 @@ ifdef CONFIG_PCI DRIVERS := $(DRIVERS) drivers/pci/pci.a -endif - -ifdef CONFIG_PNP -DRIVERS := $(DRIVERS) drivers/pnp/pnp.a endif ifdef CONFIG_SBUS diff -u --recursive v2.1.35/linux/arch/alpha/kernel/osf_sys.c linux/arch/alpha/kernel/osf_sys.c --- v2.1.35/linux/arch/alpha/kernel/osf_sys.c Tue Mar 4 10:25:23 1997 +++ linux/arch/alpha/kernel/osf_sys.c Thu Apr 17 09:22:27 1997 @@ -171,7 +171,7 @@ int prio; /* - * We don't need to aquire the kernel lock here, because + * We don't need to acquire the kernel lock here, because * all of these operations are local. sys_getpriority * will get the lock as required.. */ @@ -193,7 +193,7 @@ } /* - * No need to aquire the kernel lock, we're local.. + * No need to acquire the kernel lock, we're local.. */ asmlinkage unsigned long sys_getxuid(int a0, int a1, int a2, int a3, int a4, int a5, struct pt_regs regs) @@ -218,7 +218,7 @@ /* * This isn't strictly "local" any more and we should actually - * aquire the kernel lock. The "p_opptr" pointer might change + * acquire the kernel lock. The "p_opptr" pointer might change * if the parent goes away (or due to ptrace). But any race * isn't actually going to matter, as if the parent happens * to change we can happily return either of the pids. diff -u --recursive v2.1.35/linux/arch/alpha/kernel/process.c linux/arch/alpha/kernel/process.c --- v2.1.35/linux/arch/alpha/kernel/process.c Wed Apr 16 14:14:59 1997 +++ linux/arch/alpha/kernel/process.c Thu Apr 17 09:22:40 1997 @@ -39,7 +39,7 @@ #include /* - * No need to aquire the kernel lock, we're entirely local.. + * No need to acquire the kernel lock, we're entirely local.. */ asmlinkage int sys_sethae(unsigned long hae, unsigned long a1, unsigned long a2, unsigned long a3, unsigned long a4, unsigned long a5, diff -u --recursive v2.1.35/linux/arch/alpha/kernel/signal.c linux/arch/alpha/kernel/signal.c --- v2.1.35/linux/arch/alpha/kernel/signal.c Mon Apr 7 11:35:29 1997 +++ linux/arch/alpha/kernel/signal.c Thu Apr 17 09:22:50 1997 @@ -41,7 +41,7 @@ * We change the range to -1 .. 1 in order to let gcc easily * use the conditional move instructions. * - * Note that we don't need to aquire the kernel lock for SMP + * Note that we don't need to acquire the kernel lock for SMP * operation, as all of this is local to this thread. */ asmlinkage unsigned long osf_sigprocmask(int how, unsigned long newmask, diff -u --recursive v2.1.35/linux/arch/i386/Makefile linux/arch/i386/Makefile --- v2.1.35/linux/arch/i386/Makefile Wed Apr 16 14:14:59 1997 +++ linux/arch/i386/Makefile Thu Apr 17 18:02:14 1997 @@ -21,7 +21,7 @@ CPP=$(CC) -E OBJCOPY=$(CROSS_COMPILE)objcopy -O binary -R .note -R .comment -S LDFLAGS=-e stext -LINKFLAGS =-T arch/i386/vmlinux.lds $(LDFLAGS) +LINKFLAGS =-T $(TOPDIR)/arch/i386/vmlinux.lds $(LDFLAGS) CFLAGS := $(CFLAGS) -pipe -fno-strength-reduce diff -u --recursive v2.1.35/linux/arch/i386/boot/Makefile linux/arch/i386/boot/Makefile --- v2.1.35/linux/arch/i386/boot/Makefile Wed Apr 16 14:14:59 1997 +++ linux/arch/i386/boot/Makefile Thu Apr 17 14:24:47 1997 @@ -40,8 +40,8 @@ cp $(TOPDIR)/System.map $(INSTALL_PATH)/ if [ -x /sbin/lilo ]; then /sbin/lilo; else /etc/lilo/install; fi -install: $(CONFIGURE) zImage - sh ./install.sh $(VERSION).$(PATCHLEVEL).$(SUBLEVEL) zImage $(TOPDIR)/System.map "$(INSTALL_PATH)" +install: $(CONFIGURE) $(BOOTIMAGE) + sh -x ./install.sh $(VERSION).$(PATCHLEVEL).$(SUBLEVEL) $(BOOTIMAGE) $(TOPDIR)/System.map "$(INSTALL_PATH)" tools/build: tools/build.c $(HOSTCC) $(HOSTCFLAGS) -o $@ $< -I$(TOPDIR)/include diff -u --recursive v2.1.35/linux/arch/i386/kernel/bios32.c linux/arch/i386/kernel/bios32.c --- v2.1.35/linux/arch/i386/kernel/bios32.c Wed Apr 16 14:14:59 1997 +++ linux/arch/i386/kernel/bios32.c Wed Apr 16 14:53:37 1997 @@ -738,7 +738,7 @@ outb (0x00, 0xCFB); outb (0x00, 0xCF8); outb (0x00, 0xCFA); - if (inb (0xCF8) == 0x00 && inb (0xCFC) == 0x00) { + if (inb (0xCF8) == 0x00 && inb (0xCFB) == 0x00) { restore_flags(flags); printk("pcibios_init: Using configuration type 2\n"); return &pci_direct_conf2; diff -u --recursive v2.1.35/linux/arch/i386/kernel/i386_ksyms.c linux/arch/i386/kernel/i386_ksyms.c --- v2.1.35/linux/arch/i386/kernel/i386_ksyms.c Sun Apr 13 10:18:20 1997 +++ linux/arch/i386/kernel/i386_ksyms.c Wed Apr 16 16:04:15 1997 @@ -6,6 +6,7 @@ #include #include #include +#include #include #include @@ -31,7 +32,7 @@ EXPORT_SYMBOL_NOVERS(__down_failed); EXPORT_SYMBOL_NOVERS(__down_failed_interruptible); EXPORT_SYMBOL_NOVERS(__up_wakeup); - +EXPORT_SYMBOL(__intel_bh_counter); /* Networking helper routines. */ EXPORT_SYMBOL(csum_partial_copy); @@ -42,6 +43,13 @@ EXPORT_SYMBOL(active_kernel_processor); EXPORT_SYMBOL(smp_invalidate_needed); EXPORT_SYMBOL_NOVERS(__lock_kernel); + +/* Global SMP irq stuff */ +EXPORT_SYMBOL(global_irq_holder); +EXPORT_SYMBOL(__global_cli); +EXPORT_SYMBOL(__global_sti); +EXPORT_SYMBOL(__global_save_flags); +EXPORT_SYMBOL(__global_restore_flags); #endif #ifdef CONFIG_MCA diff -u --recursive v2.1.35/linux/arch/i386/kernel/irq.c linux/arch/i386/kernel/irq.c --- v2.1.35/linux/arch/i386/kernel/irq.c Wed Apr 16 14:14:59 1997 +++ linux/arch/i386/kernel/irq.c Wed Apr 16 16:52:23 1997 @@ -128,6 +128,11 @@ * other interrupts would have to avoid using the jiffies variable for delay * and interval timing operations to avoid hanging the system. */ + +#if NR_IRQS != 16 +#error make irq stub building NR_IRQS dependent and remove me. +#endif + BUILD_TIMER_IRQ(FIRST,0,0x01) BUILD_IRQ(FIRST,1,0x02) BUILD_IRQ(FIRST,2,0x04) @@ -231,7 +236,7 @@ int i, len = 0; struct irqaction * action; - for (i = 0 ; i < 16 ; i++) { + for (i = 0 ; i < NR_IRQS ; i++) { action = irq_action[i]; if (!action) continue; @@ -734,15 +739,9 @@ outb_p(LATCH & 0xff , 0x40); /* LSB */ outb(LATCH >> 8 , 0x40); /* MSB */ - for (i = 0; i < 16 ; i++) + for (i = 0; i < NR_IRQS ; i++) set_intr_gate(0x20+i,bad_interrupt[i]); - /* - * This bit is a hack because we don't send timer messages to all - * processors yet. It has to be here .. it doesn't work if you put - * it down the bottom - assembler explodes 8) - */ - #ifdef __SMP__ /* * NOTE! The local APIC isn't very good at handling @@ -752,8 +751,19 @@ * want to spread these out a bit so that they don't * all fall in the same interrupt level */ + + /* + * The reschedule interrupt slowly changes it's functionality, + * while so far it was a kind of broadcasted timer interrupt, + * in the future it should become a CPU-to-CPU rescheduling IPI, + * driven by schedule() ? + * + * [ It has to be here .. it doesn't work if you put + * it down the bottom - assembler explodes 8) ] + */ /* IRQ '16' (trap 0x30) - IPI for rescheduling */ set_intr_gate(0x20+i, reschedule_interrupt); + /* IRQ '17' (trap 0x31) - IPI for invalidation */ set_intr_gate(0x21+i, invalidate_interrupt); diff -u --recursive v2.1.35/linux/arch/i386/kernel/irq.h linux/arch/i386/kernel/irq.h --- v2.1.35/linux/arch/i386/kernel/irq.h Wed Apr 16 14:14:59 1997 +++ linux/arch/i386/kernel/irq.h Wed Apr 16 16:52:23 1997 @@ -266,4 +266,26 @@ UNBLK_##chip(mask) \ "jmp ret_from_intr\n"); +/* + * x86 profiling function, SMP safe. We might want to do this in + * assembly totally? + */ +static inline void x86_do_profile (unsigned long eip) +{ + if (prof_buffer && current->pid) { + extern int _stext; + eip -= (unsigned long) &_stext; + eip >>= prof_shift; + if (eip < prof_len) + atomic_inc((atomic_t *)&prof_buffer[eip]); + else + /* + * Dont ignore out-of-bounds EIP values silently, + * put them into the last histogram slot, so if + * present, they will show up as a sharp peak. + */ + atomic_inc((atomic_t *)&prof_buffer[prof_len-1]); + } +} + #endif diff -u --recursive v2.1.35/linux/arch/i386/kernel/ptrace.c linux/arch/i386/kernel/ptrace.c --- v2.1.35/linux/arch/i386/kernel/ptrace.c Sun Jan 26 02:07:04 1997 +++ linux/arch/i386/kernel/ptrace.c Thu Apr 17 13:20:40 1997 @@ -584,10 +584,9 @@ asmlinkage void syscall_trace(void) { - lock_kernel(); if ((current->flags & (PF_PTRACED|PF_TRACESYS)) != (PF_PTRACED|PF_TRACESYS)) - goto out; + return; current->exit_code = SIGTRAP; current->state = TASK_STOPPED; notify_parent(current); @@ -597,9 +596,10 @@ * for normal use. strace only continues with a signal if the * stopping signal is not SIGTRAP. -brl */ - if (current->exit_code) + if (current->exit_code) { + spin_lock_irq(¤t->sigmask_lock); current->signal |= (1 << (current->exit_code - 1)); + spin_unlock_irq(¤t->sigmask_lock); + } current->exit_code = 0; -out: - unlock_kernel(); } diff -u --recursive v2.1.35/linux/arch/i386/kernel/signal.c linux/arch/i386/kernel/signal.c --- v2.1.35/linux/arch/i386/kernel/signal.c Sun Jan 26 02:07:04 1997 +++ linux/arch/i386/kernel/signal.c Thu Apr 17 13:20:40 1997 @@ -23,7 +23,9 @@ #define _BLOCKABLE (~(_S(SIGKILL) | _S(SIGSTOP))) -asmlinkage int sys_waitpid(pid_t pid,unsigned long * stat_addr, int options); +asmlinkage int sys_wait4(pid_t pid, unsigned long *stat_addr, + int options, unsigned long *ru); + asmlinkage int do_signal(unsigned long oldmask, struct pt_regs * regs); /* @@ -31,24 +33,21 @@ */ asmlinkage int sys_sigsuspend(int restart, unsigned long oldmask, unsigned long set) { + struct pt_regs * regs = (struct pt_regs *) &restart; unsigned long mask; - struct pt_regs * regs; - int res = -EINTR; - lock_kernel(); - regs = (struct pt_regs *) &restart; + spin_lock_irq(¤t->sigmask_lock); mask = current->blocked; current->blocked = set & _BLOCKABLE; + spin_unlock_irq(¤t->sigmask_lock); + regs->eax = -EINTR; while (1) { current->state = TASK_INTERRUPTIBLE; schedule(); - if (do_signal(mask,regs)) - goto out; + if (do_signal(mask, regs)) + return -EINTR; } -out: - unlock_kernel(); - return res; } static inline void restore_i387_hard(struct _fpstate *buf) @@ -108,9 +107,7 @@ __asm__("mov %w0,%%" #seg: :"r" (tmp)); } struct sigcontext * context; struct pt_regs * regs; - int res; - lock_kernel(); regs = (struct pt_regs *) &__unused; context = (struct sigcontext *) regs->esp; if (verify_area(VERIFY_READ, context, sizeof(*context))) @@ -136,11 +133,12 @@ goto badframe; restore_i387(buf); } - res = context->eax; - unlock_kernel(); - return res; + return context->eax; + badframe: + lock_kernel(); do_exit(SIGSEGV); + unlock_kernel(); } static inline struct _fpstate * save_i387_hard(struct _fpstate * buf) @@ -194,7 +192,7 @@ frame = (unsigned long *) sa->sa_restorer; frame -= 64; if (!access_ok(VERIFY_WRITE,frame,64*4)) - do_exit(SIGSEGV); + goto segv_and_exit; /* set up the "normal" stack seen by the signal handler (iBCS2) */ #define __CODE ((unsigned long)(frame+24)) @@ -206,7 +204,7 @@ We use __put_user() here because the access_ok() call was already done earlier. */ if (__put_user(__CODE,frame)) - do_exit(SIGSEGV); + goto segv_and_exit; if (current->exec_domain && current->exec_domain->signal_invmap) __put_user(current->exec_domain->signal_invmap[signr], frame+1); else @@ -259,6 +257,12 @@ regs->xcs = USER_CS; } regs->eflags &= ~TF_MASK; + return; + +segv_and_exit: + lock_kernel(); + do_exit(SIGSEGV); + unlock_kernel(); } /* @@ -292,8 +296,11 @@ if (sa->sa_flags & SA_ONESHOT) sa->sa_handler = NULL; - if (!(sa->sa_flags & SA_NOMASK)) + if (!(sa->sa_flags & SA_NOMASK)) { + spin_lock_irq(¤t->sigmask_lock); current->blocked |= (sa->sa_mask | _S(signr)) & _BLOCKABLE; + spin_unlock_irq(¤t->sigmask_lock); + } } /* @@ -310,9 +317,7 @@ unsigned long mask; unsigned long signr; struct sigaction * sa; - int res; - lock_kernel(); mask = ~current->blocked; while ((signr = current->signal & mask)) { /* @@ -322,6 +327,9 @@ */ struct task_struct *t=current; __asm__("bsf %3,%1\n\t" +#ifdef __SMP__ + "lock ; " +#endif "btrl %1,%0" :"=m" (t->signal),"=r" (signr) :"0" (t->signal), "1" (signr)); @@ -338,7 +346,9 @@ if (signr == SIGSTOP) continue; if (_S(signr) & current->blocked) { + spin_lock_irq(¤t->sigmask_lock); current->signal |= _S(signr); + spin_unlock_irq(¤t->sigmask_lock); continue; } sa = current->sig->action + signr - 1; @@ -347,7 +357,7 @@ if (signr != SIGCHLD) continue; /* check for SIGCHLD: it's special */ - while (sys_waitpid(-1,NULL,WNOHANG) > 0) + while (sys_wait4(-1,NULL,WNOHANG, NULL) > 0) /* nothing */; continue; } @@ -380,14 +390,19 @@ } /* fall through */ default: + spin_lock_irq(¤t->sigmask_lock); current->signal |= _S(signr & 0x7f); + spin_unlock_irq(¤t->sigmask_lock); + current->flags |= PF_SIGNALED; + + lock_kernel(); /* 8-( */ do_exit(signr); + unlock_kernel(); } } handle_signal(signr, sa, oldmask, regs); - res = 1; - goto out; + return 1; } /* Did we come from a system call? */ @@ -400,8 +415,5 @@ regs->eip -= 2; } } - res = 0; -out: - unlock_kernel(); - return res; + return 0; } diff -u --recursive v2.1.35/linux/arch/i386/kernel/smp.c linux/arch/i386/kernel/smp.c --- v2.1.35/linux/arch/i386/kernel/smp.c Wed Apr 16 14:14:59 1997 +++ linux/arch/i386/kernel/smp.c Wed Apr 16 16:52:23 1997 @@ -49,6 +49,9 @@ #include "irq.h" extern unsigned long start_kernel, _etext; +extern void update_one_process( struct task_struct *p, + unsigned long ticks, unsigned long user, + unsigned long system); void setup_APIC_clock (void); /* @@ -1307,37 +1310,6 @@ } /* - * Platform specific profiling function. - * it builds a 'prof_shift' resolution EIP distribution histogram - * - * it's SMP safe. - */ - -static inline void x86_do_profile (unsigned long eip) -{ - if (prof_buffer && current->pid) { - extern int _stext; - eip -= (unsigned long) &_stext; - eip >>= prof_shift; - if (eip < prof_len) - atomic_inc(&prof_buffer[eip]); - else - /* - * Dont ignore out-of-bounds EIP values silently, - * put them into the last histogram slot, so if - * present, they will show up as a sharp peak. - */ - atomic_inc(&prof_buffer[prof_len-1]); - } -} - -unsigned int prof_multiplier[NR_CPUS]; -unsigned int prof_counter[NR_CPUS]; - -extern void update_one_process( struct task_struct *p, - unsigned long ticks, unsigned long user, - unsigned long system); -/* * Local timer interrupt handler. It does both profiling and * process statistics/rescheduling. * @@ -1346,14 +1318,19 @@ * multiplier is 1 and it can be changed by writing a 4 bytes multiplier * value into /proc/profile. */ + +unsigned int prof_multiplier[NR_CPUS]; +unsigned int prof_counter[NR_CPUS]; + static inline void smp_local_timer_interrupt(struct pt_regs * regs) { int cpu = smp_processor_id(); + /* - * Both the profiling function and the statistics - * counters are SMP safe. We leave the APIC irq - * unacked while updating the profiling info, thus - * we cannot be interrupted by the same APIC interrupt. + * The profiling function is SMP safe. (nothing can mess + * around with "current", and the profiling counters are + * updated with atomic operations). This is especially + * useful with a profiling multiplier != 1 */ if (!user_mode(regs)) x86_do_profile (regs->eip); @@ -1363,13 +1340,10 @@ struct task_struct * p = current; /* - * We mess around with thread statistics, but - * since we are the CPU running it, we dont - * have to lock it. We assume that switch_to() - * protects 'current' against local irqs via __cli. - * - * kernel statistics counters are updated via atomic - * operations. + * After doing the above, we need to make like + * a normal interrupt - otherwise timer interrupts + * ignore the global interrupt lock, which is the + * WrongThing (tm) to do. */ if (user_mode(regs)) @@ -1377,7 +1351,9 @@ else system=1; + irq_enter(cpu, 0); if (p->pid) { + update_one_process(p, 1, user, system); p->counter -= 1; @@ -1386,25 +1362,21 @@ need_resched = 1; } if (p->priority < DEF_PRIORITY) - atomic_add (user, &kstat.cpu_nice); + kstat.cpu_nice += user; else - atomic_add (user, &kstat.cpu_user); + kstat.cpu_user += user; - atomic_add (system, &kstat.cpu_system); + kstat.cpu_system += system; } else { #ifdef __SMP_PROF__ if (test_bit(cpu,&smp_idle_map)) smp_idle_count[cpu]++; #endif - /* - * This is a hack until we have need_resched[] - */ - if (read_smp_counter(&smp_process_available)) - need_resched=1; } - prof_counter[cpu]=prof_multiplier[cpu]; + + irq_exit(cpu, 0); } #ifdef __SMP_PROF__ @@ -1432,8 +1404,6 @@ */ void smp_apic_timer_interrupt(struct pt_regs * regs) { - int cpu = smp_processor_id(); - /* * NOTE! We'd better ACK the irq immediately, * because timer handling can be slow, and we @@ -1442,15 +1412,7 @@ */ ack_APIC_irq (); - /* - * After doing the above, we need to make like - * a normal interrupt - otherwise timer interrupts - * ignore the global interrupt lock, which is the - * WrongThing (tm) to do. - */ - irq_enter(cpu, 0); smp_local_timer_interrupt(regs); - irq_exit(cpu, 0); } /* diff -u --recursive v2.1.35/linux/arch/i386/kernel/time.c linux/arch/i386/kernel/time.c --- v2.1.35/linux/arch/i386/kernel/time.c Wed Apr 16 14:14:59 1997 +++ linux/arch/i386/kernel/time.c Wed Apr 16 16:52:23 1997 @@ -33,6 +33,11 @@ #include #include +/* + * for x86_do_profile() + */ +#include "irq.h" + extern int setup_x86_irq(int, struct irqaction *); extern volatile unsigned long lost_ticks; @@ -364,29 +369,6 @@ /* last time the cmos clock got updated */ static long last_rtc_update = 0; - - -/* - * Move this to a header file - right now it shows - * up both here and in smp.c - */ -static inline void x86_do_profile (unsigned long eip) -{ - if (prof_buffer && current->pid) { - extern int _stext; - eip -= (unsigned long) &_stext; - eip >>= prof_shift; - if (eip < prof_len) - atomic_inc(&prof_buffer[eip]); - else - /* - * Dont ignore out-of-bounds EIP values silently, - * put them into the last histogram slot, so if - * present, they will show up as a sharp peak. - */ - atomic_inc(&prof_buffer[prof_len-1]); - } -} /* * timer_interrupt() needs to keep up the real-time clock, diff -u --recursive v2.1.35/linux/arch/i386/mm/init.c linux/arch/i386/mm/init.c --- v2.1.35/linux/arch/i386/mm/init.c Wed Apr 16 14:15:00 1997 +++ linux/arch/i386/mm/init.c Thu Apr 17 13:20:40 1997 @@ -322,6 +322,7 @@ atomic_set(&mem_map[MAP_NR(addr)].count, 1); free_page(addr); } + printk ("Freeing unused kernel memory: %dk freed\n", (&__init_end - &__init_begin) >> 10); } void si_meminfo(struct sysinfo *val) diff -u --recursive v2.1.35/linux/arch/m68k/Makefile linux/arch/m68k/Makefile --- v2.1.35/linux/arch/m68k/Makefile Fri Apr 4 08:52:17 1997 +++ linux/arch/m68k/Makefile Thu Apr 17 13:20:40 1997 @@ -36,7 +36,7 @@ LINKFLAGS = -Ttext 0x1000 -CFLAGS := $(CFLAGS) -pipe +CFLAGS := $(CFLAGS) -pipe -fno-strength-reduce ifdef CONFIG_OPTIMIZE_040 CFLAGS := $(CFLAGS) -m68040 @@ -46,40 +46,46 @@ CFLAGS := $(CFLAGS) -m68020-40 endif +ifdef CONFIG_KGDB +# If configured for kgdb support, include debugging infos and keep the +# frame pointer +CFLAGS := $(subst -fomit-frame-pointer,,$(CFLAGS)) -g +endif + HEAD := arch/m68k/kernel/head.o SUBDIRS += arch/m68k/kernel arch/m68k/mm arch/m68k/lib -ARCHIVES := arch/m68k/kernel/kernel.o arch/m68k/mm/mm.o $(ARCHIVES) +CORE_FILES := arch/m68k/kernel/kernel.o arch/m68k/mm/mm.o $(CORE_FILES) LIBS += arch/m68k/lib/lib.a ifdef CONFIG_AMIGA -ARCHIVES := $(ARCHIVES) arch/m68k/amiga/amiga.o +CORE_FILES := $(CORE_FILES) arch/m68k/amiga/amiga.o SUBDIRS := $(SUBDIRS) arch/m68k/amiga endif ifdef CONFIG_ATARI -ARCHIVES := $(ARCHIVES) arch/m68k/atari/atari.o +CORE_FILES := $(CORE_FILES) arch/m68k/atari/atari.o SUBDIRS := $(SUBDIRS) arch/m68k/atari endif ifdef CONFIG_MAC -ARCHIVES := $(ARCHIVES) arch/m68k/mac/mac.o +CORE_FILES := $(CORE_FILES) arch/m68k/mac/mac.o SUBDIRS := $(SUBDIRS) arch/m68k/mac endif ifdef CONFIG_VT # add in console.a after {amiga,atari}.o that need it -ARCHIVES := $(ARCHIVES) arch/m68k/console/console.a +CORE_FILES := $(CORE_FILES) arch/m68k/console/console.a SUBDIRS := $(SUBDIRS) arch/m68k/console endif ifdef CONFIG_M68040 -ARCHIVES := $(ARCHIVES) arch/m68k/fpsp040/fpsp.o +CORE_FILES := $(CORE_FILES) arch/m68k/fpsp040/fpsp.o SUBDIRS := $(SUBDIRS) arch/m68k/fpsp040 endif ifdef CONFIG_M68060 -ARCHIVES := $(ARCHIVES) arch/m68k/ifpsp060/ifpsp.o +CORE_FILES := $(CORE_FILES) arch/m68k/ifpsp060/ifpsp.o SUBDIRS := $(SUBDIRS) arch/m68k/ifpsp060 endif @@ -92,10 +98,24 @@ cp System.map $(INSTALL_PATH)/System.map if [ -x /sbin/lilo ]; then /sbin/lilo; else /etc/lilo/install; fi -bootstrap: +zImage compressed: vmlinux.gz + +vmlinux.gz: vmlinux + +ifdef CONFIG_KGDB + cp vmlinux vmlinux.tmp + $(STRIP) vmlinux.tmp + gzip -9c vmlinux.tmp >vmlinux.gz + rm vmlinux.tmp +else + gzip -9c vmlinux >vmlinux.gz +endif + +bootstrap: dummy @$(MAKEBOOT) bootstrap archclean: + rm -f vmlinux.gz @$(MAKEBOOT) clean archdep: diff -u --recursive v2.1.35/linux/arch/m68k/amiga/Makefile linux/arch/m68k/amiga/Makefile --- v2.1.35/linux/arch/m68k/amiga/Makefile Fri Jan 3 01:33:25 1997 +++ linux/arch/m68k/amiga/Makefile Thu Apr 17 13:20:40 1997 @@ -16,4 +16,8 @@ O_OBJS := $(O_OBJS) cyberfb.o endif +ifdef CONFIG_FB_RETINAZ3 +O_OBJS := $(O_OBJS) retz3fb.o +endif + include $(TOPDIR)/Rules.make diff -u --recursive v2.1.35/linux/arch/m68k/amiga/amifb.c linux/arch/m68k/amiga/amifb.c --- v2.1.35/linux/arch/m68k/amiga/amifb.c Fri Dec 20 01:19:57 1996 +++ linux/arch/m68k/amiga/amifb.c Thu Apr 17 13:20:41 1997 @@ -1242,6 +1242,7 @@ static int amifbcon_switch(int con); static int amifbcon_updatevar(int con); static void amifbcon_blank(int blank); +static int amifbcon_setcmap(struct fb_cmap *cmap, int con); /* * Internal routines @@ -1315,7 +1316,15 @@ extern struct fb_info *Cyber_fb_init(long *mem_start); static int amifb_Cyber = 0; -#endif /* CONFIG_FB_CYBER */ +#endif + +#ifdef CONFIG_FB_RETINAZ3 /* RetinaZ3 */ +extern int retz3_probe(void); +extern void retz3_video_setup(char *options, int *ints); +extern struct fb_info *retz3_fb_init(long *mem_start); + +static int amifb_retz3 = 0; +#endif #ifdef CONFIG_GSP_RESOLVER /* DMI Resolver */ extern int resolver_probe(void); @@ -1323,7 +1332,7 @@ extern struct fb_info *resolver_fb_init(long *mem_start); static int amifb_resolver = 0; -#endif /* CONFIG_GSP_RESOLVER */ +#endif static struct fb_ops amiga_fb_ops = { amiga_fb_get_fix, amiga_fb_get_var, amiga_fb_set_var, amiga_fb_get_cmap, @@ -1347,7 +1356,15 @@ Cyber_video_setup(options, ints); return; } -#endif /* CONFIG_FB_CYBER */ +#endif +#ifdef CONFIG_FB_RETINAZ3 + if (options && *options) + if (!strncmp(options, "retz3", 5) && retz3_probe()) { + amifb_retz3 = 1; + retz3_video_setup(options, ints); + return; + } +#endif #ifdef CONFIG_GSP_RESOLVER if (options && *options) if (!strncmp(options, "resolver", 5) && resolver_probe()) { @@ -1797,7 +1814,14 @@ #ifdef CONFIG_FB_CYBER if (amifb_Cyber) return Cyber_fb_init(mem_start); -#endif /* CONFIG_FB_CYBER */ +#endif +#ifdef CONFIG_FB_RETINAZ3 + if (amifb_retz3){ + custom.dmacon = DMAF_MASTER | DMAF_RASTER | DMAF_COPPER | + DMAF_BLITTER | DMAF_SPRITE; + return retz3_fb_init(mem_start); + } +#endif #ifdef CONFIG_GSP_RESOLVER if (amifb_resolver){ custom.dmacon = DMAF_MASTER | DMAF_RASTER | DMAF_COPPER | @@ -1943,11 +1967,11 @@ check_default_mode(); - if (request_irq(IRQ3, amifb_interrupt, IRQ_FLG_LOCK, + if (request_irq(IRQ_AMIGA_AUTO_3, amifb_interrupt, IRQ_FLG_LOCK, "fb vertb handler", NULL)) panic("Couldn't add vblank interrupt\n"); - ami_intena_vals[IRQ_IDX(IRQ_AMIGA_VERTB)] = IF_COPER; - ami_intena_vals[IRQ_IDX(IRQ_AMIGA_COPPER)] = 0; + ami_intena_vals[IRQ_AMIGA_VERTB] = IF_COPER; + ami_intena_vals[IRQ_AMIGA_COPPER] = 0; custom.intena = IF_VERTB; custom.intena = IF_SETCLR | IF_COPER; @@ -1957,6 +1981,7 @@ fb_info.switch_con = &amifbcon_switch; fb_info.updatevar = &amifbcon_updatevar; fb_info.blank = &amifbcon_blank; + fb_info.setcmap = &amifbcon_setcmap; amiga_fb_set_var(&amiga_fb_predefined[0], 0); @@ -1995,6 +2020,15 @@ do_blank = blank ? blank : -1; } + /* + * Set the colormap + */ + +static int amifbcon_setcmap(struct fb_cmap *cmap, int con) +{ + return(amiga_fb_set_cmap(cmap, 1, con)); +} + /* ---------------------------- Generic routines ---------------------------- */ static struct fb_cmap *get_default_colormap(int bpp) @@ -2213,10 +2247,11 @@ { u_short ints = custom.intreqr & custom.intenar; static struct irq_server server = {0, 0}; + unsigned long flags; if (ints & IF_BLIT) { custom.intreq = IF_BLIT; - amiga_do_irq(IRQ_IDX(IRQ_AMIGA_BLIT), fp); + amiga_do_irq(IRQ_AMIGA_BLIT, fp); } if (ints & IF_COPER) { @@ -2240,8 +2275,11 @@ ami_set_sprite(); } - if (get_vbpos() < down2(currentpar.diwstrt_v - 4)) + save_flags(flags); + cli(); + if (get_vbpos() < down2(currentpar.diwstrt_v - 6)) custom.copjmp2 = 0; + restore_flags(flags); if (do_blank) { ami_do_blank(); @@ -2252,7 +2290,7 @@ ami_reinit_copper(); do_vmode_full = 0; } - amiga_do_irq_list(IRQ_IDX(IRQ_AMIGA_VERTB), fp, &server); + amiga_do_irq_list(IRQ_AMIGA_VERTB, fp, &server); } if (ints & IF_VERTB) { diff -u --recursive v2.1.35/linux/arch/m68k/amiga/amiga_ksyms.c linux/arch/m68k/amiga/amiga_ksyms.c --- v2.1.35/linux/arch/m68k/amiga/amiga_ksyms.c Fri Jan 3 01:33:25 1997 +++ linux/arch/m68k/amiga/amiga_ksyms.c Thu Apr 17 13:20:41 1997 @@ -1,6 +1,7 @@ -#include +#include #include -#include +#include +#include #include extern volatile u_short amiga_audio_min_period; diff -u --recursive v2.1.35/linux/arch/m68k/amiga/amiints.c linux/arch/m68k/amiga/amiints.c --- v2.1.35/linux/arch/m68k/amiga/amiints.c Fri Dec 20 01:19:57 1996 +++ linux/arch/m68k/amiga/amiints.c Thu Apr 17 13:20:41 1997 @@ -172,12 +172,16 @@ return -ENXIO; } - if (irq >= IRQ_IDX(IRQ_AMIGA_CIAB)) - return cia_request_irq(&ciab_base, irq - IRQ_IDX(IRQ_AMIGA_CIAB), + if (irq >= IRQ_AMIGA_AUTO) + return sys_request_irq(irq - IRQ_AMIGA_AUTO, handler, + flags, devname, dev_id); + + if (irq >= IRQ_AMIGA_CIAB) + return cia_request_irq(&ciab_base, irq - IRQ_AMIGA_CIAB, handler, flags, devname, dev_id); - if (irq >= IRQ_IDX(IRQ_AMIGA_CIAA)) - return cia_request_irq(&ciaa_base, irq - IRQ_IDX(IRQ_AMIGA_CIAA), + if (irq >= IRQ_AMIGA_CIAA) + return cia_request_irq(&ciaa_base, irq - IRQ_AMIGA_CIAA, handler, flags, devname, dev_id); if (ami_servers[irq]) { @@ -196,7 +200,7 @@ __FUNCTION__, irq, ami_irq_list[irq]->devname); return -EBUSY; } - if (flags & IRQ_FLG_REPLACE) { + if (!(flags & IRQ_FLG_REPLACE)) { printk("%s: %s can't replace IRQ %d from %s\n", __FUNCTION__, devname, irq, ami_irq_list[irq]->devname); return -EBUSY; @@ -209,7 +213,7 @@ } /* enable the interrupt */ - if (irq < IRQ_IDX(IRQ_AMIGA_PORTS) && !ami_ablecount[irq]) + if (irq < IRQ_AMIGA_PORTS && !ami_ablecount[irq]) custom.intena = IF_SETCLR | ami_intena_vals[irq]; return 0; @@ -222,20 +226,23 @@ return; } - if (irq >= IRQ_IDX(IRQ_AMIGA_CIAB)) { - cia_free_irq(&ciab_base, irq - IRQ_IDX(IRQ_AMIGA_CIAB), dev_id); + if (irq >= IRQ_AMIGA_AUTO) + sys_free_irq(irq - IRQ_AMIGA_AUTO, dev_id); + + if (irq >= IRQ_AMIGA_CIAB) { + cia_free_irq(&ciab_base, irq - IRQ_AMIGA_CIAB, dev_id); return; } - if (irq >= IRQ_IDX(IRQ_AMIGA_CIAA)) { - cia_free_irq(&ciaa_base, irq - IRQ_IDX(IRQ_AMIGA_CIAA), dev_id); + if (irq >= IRQ_AMIGA_CIAA) { + cia_free_irq(&ciaa_base, irq - IRQ_AMIGA_CIAA, dev_id); return; } if (ami_servers[irq]) { amiga_delete_irq(&ami_irq_list[irq], dev_id); /* if server list empty, disable the interrupt */ - if (!ami_irq_list[irq] && irq < IRQ_IDX(IRQ_AMIGA_PORTS)) + if (!ami_irq_list[irq] && irq < IRQ_AMIGA_PORTS) custom.intena = ami_intena_vals[irq]; } else { if (ami_irq_list[irq]->dev_id != dev_id) @@ -267,15 +274,22 @@ if (--ami_ablecount[irq]) return; - if (irq >= IRQ_IDX(IRQ_AMIGA_CIAB)) { + /* No action for auto-vector interrupts */ + if (irq >= IRQ_AMIGA_AUTO){ + printk("%s: Trying to enable auto-vector IRQ %i\n", + __FUNCTION__, irq - IRQ_AMIGA_AUTO); + return; + } + + if (irq >= IRQ_AMIGA_CIAB) { cia_able_irq(&ciab_base, CIA_ICR_SETCLR | - (1 << (irq - IRQ_IDX(IRQ_AMIGA_CIAB)))); + (1 << (irq - IRQ_AMIGA_CIAB))); return; } - if (irq >= IRQ_IDX(IRQ_AMIGA_CIAA)) { + if (irq >= IRQ_AMIGA_CIAA) { cia_able_irq(&ciaa_base, CIA_ICR_SETCLR | - (1 << (irq - IRQ_IDX(IRQ_AMIGA_CIAA)))); + (1 << (irq - IRQ_AMIGA_CIAA))); return; } @@ -293,13 +307,20 @@ if (ami_ablecount[irq]++) return; - if (irq >= IRQ_IDX(IRQ_AMIGA_CIAB)) { - cia_able_irq(&ciab_base, 1 << (irq - IRQ_IDX(IRQ_AMIGA_CIAB))); + /* No action for auto-vector interrupts */ + if (irq >= IRQ_AMIGA_AUTO) { + printk("%s: Trying to disable auto-vector IRQ %i\n", + __FUNCTION__, irq - IRQ_AMIGA_AUTO); + return; + } + + if (irq >= IRQ_AMIGA_CIAB) { + cia_able_irq(&ciab_base, 1 << (irq - IRQ_AMIGA_CIAB)); return; } - if (irq >= IRQ_IDX(IRQ_AMIGA_CIAA)) { - cia_able_irq(&ciaa_base, 1 << (irq - IRQ_IDX(IRQ_AMIGA_CIAA))); + if (irq >= IRQ_AMIGA_CIAA) { + cia_able_irq(&ciaa_base, 1 << (irq - IRQ_AMIGA_CIAA)); return; } @@ -310,13 +331,12 @@ inline void amiga_do_irq(int irq, struct pt_regs *fp) { kstat.interrupts[SYS_IRQS + irq]++; - ami_irq_list[irq]->handler(irq | IRQ_MACHSPEC, ami_irq_list[irq]->dev_id, fp); + ami_irq_list[irq]->handler(irq, ami_irq_list[irq]->dev_id, fp); } void amiga_do_irq_list(int irq, struct pt_regs *fp, struct irq_server *server) { irq_node_t *node, *slow_nodes; - int mach_irq = irq | IRQ_MACHSPEC; unsigned short flags; kstat.interrupts[SYS_IRQS + irq]++; @@ -326,7 +346,7 @@ for (node = ami_irq_list[irq]; node && (!(node->flags & IRQ_FLG_SLOW)); node = node->next) - node->handler(mach_irq, node->dev_id, fp); + node->handler(irq, node->dev_id, fp); custom.intreq = ami_intena_vals[irq]; if (!node) { server->count--; @@ -338,7 +358,7 @@ slow_nodes = node; for (;;) { for (; node; node = node->next) - node->handler(mach_irq, node->dev_id, fp); + node->handler(irq, node->dev_id, fp); /* if reentrance occured, serve slow handlers again */ custom.intena = ami_intena_vals[irq]; if (!server->reentrance) { @@ -363,19 +383,19 @@ /* if serial transmit buffer empty, interrupt */ if (ints & IF_TBE) { custom.intreq = IF_TBE; - amiga_do_irq(IRQ_IDX(IRQ_AMIGA_TBE), fp); + amiga_do_irq(IRQ_AMIGA_TBE, fp); } /* if floppy disk transfer complete, interrupt */ if (ints & IF_DSKBLK) { custom.intreq = IF_DSKBLK; - amiga_do_irq(IRQ_IDX(IRQ_AMIGA_DSKBLK), fp); + amiga_do_irq(IRQ_AMIGA_DSKBLK, fp); } /* if software interrupt set, interrupt */ if (ints & IF_SOFT) { custom.intreq = IF_SOFT; - amiga_do_irq(IRQ_IDX(IRQ_AMIGA_SOFT), fp); + amiga_do_irq(IRQ_AMIGA_SOFT, fp); } } @@ -387,18 +407,18 @@ /* if a blitter interrupt */ if (ints & IF_BLIT) { custom.intreq = IF_BLIT; - amiga_do_irq(IRQ_IDX(IRQ_AMIGA_BLIT), fp); + amiga_do_irq(IRQ_AMIGA_BLIT, fp); } /* if a copper interrupt */ if (ints & IF_COPER) { custom.intreq = IF_COPER; - amiga_do_irq(IRQ_IDX(IRQ_AMIGA_COPPER), fp); + amiga_do_irq(IRQ_AMIGA_COPPER, fp); } /* if a vertical blank interrupt */ if (ints & IF_VERTB) - amiga_do_irq_list(IRQ_IDX(IRQ_AMIGA_VERTB), fp, &server); + amiga_do_irq_list(IRQ_AMIGA_VERTB, fp, &server); } static void ami_int4(int irq, void *dev_id, struct pt_regs *fp) @@ -408,25 +428,25 @@ /* if audio 0 interrupt */ if (ints & IF_AUD0) { custom.intreq = IF_AUD0; - amiga_do_irq(IRQ_IDX(IRQ_AMIGA_AUD0), fp); + amiga_do_irq(IRQ_AMIGA_AUD0, fp); } /* if audio 1 interrupt */ if (ints & IF_AUD1) { custom.intreq = IF_AUD1; - amiga_do_irq(IRQ_IDX(IRQ_AMIGA_AUD1), fp); + amiga_do_irq(IRQ_AMIGA_AUD1, fp); } /* if audio 2 interrupt */ if (ints & IF_AUD2) { custom.intreq = IF_AUD2; - amiga_do_irq(IRQ_IDX(IRQ_AMIGA_AUD2), fp); + amiga_do_irq(IRQ_AMIGA_AUD2, fp); } /* if audio 3 interrupt */ if (ints & IF_AUD3) { custom.intreq = IF_AUD3; - amiga_do_irq(IRQ_IDX(IRQ_AMIGA_AUD3), fp); + amiga_do_irq(IRQ_AMIGA_AUD3, fp); } } @@ -437,13 +457,13 @@ /* if serial receive buffer full interrupt */ if (ints & IF_RBF) { /* acknowledge of IF_RBF must be done by the serial interrupt */ - amiga_do_irq(IRQ_IDX(IRQ_AMIGA_RBF), fp); + amiga_do_irq(IRQ_AMIGA_RBF, fp); } /* if a disk sync interrupt */ if (ints & IF_DSKSYN) { custom.intreq = IF_DSKSYN; - amiga_do_irq(IRQ_IDX(IRQ_AMIGA_DSKSYN), fp); + amiga_do_irq(IRQ_AMIGA_DSKSYN, fp); } } diff -u --recursive v2.1.35/linux/arch/m68k/amiga/cia.c linux/arch/m68k/amiga/cia.c --- v2.1.35/linux/arch/m68k/amiga/cia.c Fri Nov 22 05:56:33 1996 +++ linux/arch/m68k/amiga/cia.c Thu Apr 17 13:20:41 1997 @@ -30,13 +30,13 @@ irq_handler_t irq_list[CIA_IRQS]; } ciaa_base = { &ciaa, 0, 0, IF_PORTS, - IRQ2, IRQ_AMIGA_CIAA, - IRQ_IDX(IRQ_AMIGA_PORTS), + IRQ_AMIGA_AUTO_2, IRQ_AMIGA_CIAA, + IRQ_AMIGA_PORTS, "CIAA handler", {0, 0} }, ciab_base = { &ciab, 0, 0, IF_EXTER, - IRQ6, IRQ_AMIGA_CIAB, - IRQ_IDX(IRQ_AMIGA_EXTER), + IRQ_AMIGA_AUTO_6, IRQ_AMIGA_CIAB, + IRQ_AMIGA_EXTER, "CIAB handler", {0, 0} }; @@ -95,14 +95,14 @@ if (!(base->irq_list[irq].flags & IRQ_FLG_STD)) { if (base->irq_list[irq].flags & IRQ_FLG_LOCK) { - printk("%s: IRQ %ld from %s is not replaceable\n", - __FUNCTION__, IRQ_IDX(base->cia_irq + irq), + printk("%s: IRQ %i from %s is not replaceable\n", + __FUNCTION__, base->cia_irq + irq, base->irq_list[irq].devname); return -EBUSY; } - if (flags & IRQ_FLG_REPLACE) { - printk("%s: %s can't replace IRQ %ld from %s\n", __FUNCTION__, - devname, IRQ_IDX(base->cia_irq + irq), + if (!(flags & IRQ_FLG_REPLACE)) { + printk("%s: %s can't replace IRQ %i from %s\n", __FUNCTION__, + devname, base->cia_irq + irq, base->irq_list[irq].devname); return -EBUSY; } @@ -122,8 +122,8 @@ void cia_free_irq(struct ciabase *base, unsigned int irq, void *dev_id) { if (base->irq_list[irq].dev_id != dev_id) - printk("%s: removing probably wrong IRQ %ld from %s\n", - __FUNCTION__, IRQ_IDX(base->cia_irq + irq), + printk("%s: removing probably wrong IRQ %i from %s\n", + __FUNCTION__, base->cia_irq + irq, base->irq_list[irq].devname); base->irq_list[irq].handler = NULL; @@ -139,7 +139,7 @@ unsigned char ints; mach_irq = base->cia_irq; - irq = SYS_IRQS + IRQ_IDX(mach_irq); + irq = SYS_IRQS + mach_irq; ints = cia_set_irq(base, CIA_ICR_ALL); custom.intreq = base->int_mask; for (i = 0; i < CIA_IRQS; i++, irq++, mach_irq++) { @@ -176,7 +176,7 @@ { int i, j, len = 0; - j = IRQ_IDX(base->cia_irq); + j = base->cia_irq; for (i = 0; i < CIA_IRQS; i++) { if (!(base->irq_list[i].flags & IRQ_FLG_STD)) { len += sprintf(buf+len, "cia %2d: %10d ", j + i, diff -u --recursive v2.1.35/linux/arch/m68k/amiga/config.c linux/arch/m68k/amiga/config.c --- v2.1.35/linux/arch/m68k/amiga/config.c Fri Dec 20 01:19:57 1996 +++ linux/arch/m68k/amiga/config.c Thu Apr 17 13:20:41 1997 @@ -29,7 +29,7 @@ #include #include #include -#include +#include u_long amiga_model; u_long amiga_eclock; @@ -56,7 +56,7 @@ extern void (*amiga_default_handler[]) (int, void *, struct pt_regs *); extern int amiga_request_irq (unsigned int irq, void (*handler)(int, void *, struct pt_regs *), unsigned long flags, const char *devname, void *dev_id); -extern int amiga_free_irq (unsigned int irq, void *dev_id); +extern void amiga_free_irq (unsigned int irq, void *dev_id); extern void amiga_enable_irq (unsigned int); extern void amiga_disable_irq (unsigned int); static void amiga_get_model(char *model); @@ -74,15 +74,20 @@ extern void amiga_floppy_setup(char *, int *); #endif static void amiga_reset (void); -static void amiga_waitbut(void); +static void amiga_wait_key(void); extern struct consw fb_con; extern struct fb_info *amiga_fb_init(long *); extern void zorro_init(void); -static void ami_savekmsg_init(void); -static void ami_mem_print(const char *b); +static void amiga_savekmsg_init(void); +static void amiga_mem_console_write(const char *b, unsigned int count); +static void amiga_serial_console_write(const char *s, unsigned int count); static void amiga_debug_init(void); + extern void amiga_video_setup(char *, int *); -extern void amiga_syms_export(void); + +static struct console amiga_console_driver = { + NULL, NULL, amiga_wait_key +}; extern void (*kd_mksound)(unsigned int, unsigned int); @@ -151,6 +156,8 @@ memset(&amiga_hw_present, 0, sizeof(amiga_hw_present)); + amiga_debug_init(); + printk("Amiga hardware found: "); if (amiga_model >= AMI_500 && amiga_model <= AMI_DRACO) printk("[%s] ", amiga_models[amiga_model-AMI_500]); @@ -304,8 +311,8 @@ mach_default_handler = &amiga_default_handler; mach_request_irq = amiga_request_irq; mach_free_irq = amiga_free_irq; - mach_enable_irq = amiga_enable_irq; - mach_disable_irq = amiga_disable_irq; + enable_irq = amiga_enable_irq; + disable_irq = amiga_disable_irq; mach_get_model = amiga_get_model; mach_get_hardware_list = amiga_get_hardware_list; mach_get_irq_list = amiga_get_irq_list; @@ -329,18 +336,14 @@ mach_hwclk = amiga_hwclk; mach_set_clock_mmss = amiga_set_clock_mmss; - mach_mksound = amiga_mksound; #ifdef CONFIG_BLK_DEV_FD mach_floppy_init = amiga_floppy_init; mach_floppy_setup = amiga_floppy_setup; #endif mach_reset = amiga_reset; - waitbut = amiga_waitbut; conswitchp = &fb_con; mach_fb_init = amiga_fb_init; - mach_debug_init = amiga_debug_init; mach_video_setup = amiga_video_setup; - mach_syms_export = amiga_syms_export; kd_mksound = amiga_mksound; /* Fill in the clock values (based on the 700 kHz E-Clock) */ @@ -355,10 +358,6 @@ /* initialize chipram allocator */ amiga_chip_init (); - /* initialize only once here, not every time the debug level is raised */ - if (!strcmp( m68k_debug_device, "mem" )) - ami_savekmsg_init(); - /* * if it is an A3000, set the magic bit that forces * a hard rekick @@ -588,7 +587,7 @@ return 0; } -static void amiga_waitbut (void) +static void amiga_wait_key (void) { int i; @@ -614,33 +613,6 @@ } } -void ami_serial_print (const char *str) -{ - while (*str) { - if (*str == '\n') { - custom.serdat = (unsigned char)'\r' | 0x100; - while (!(custom.serdatr & 0x2000)) - ; - } - custom.serdat = (unsigned char)*str++ | 0x100; - while (!(custom.serdatr & 0x2000)) - ; - } -} - -static void amiga_debug_init (void) -{ - extern void (*debug_print_proc)(const char *); - - if (!strcmp( m68k_debug_device, "ser" )) { - /* no initialization required (?) */ - debug_print_proc = ami_serial_print; - } else if (!strcmp( m68k_debug_device, "mem" )) { - /* already initialized by config_amiga() (needed only once) */ - debug_print_proc = ami_mem_print; - } -} - void dbprintf(const char *fmt , ...) { static char buf[1024]; @@ -672,8 +644,10 @@ ("movel %0,%/d0\n\t" "andl #0xff000000,%/d0\n\t" "orw #0xe020,%/d0\n\t" /* map 16 MB, enable, cacheable */ - ".long 0x4e7b0004\n\t" /* movec d0,itt0 */ - ".long 0x4e7b0006\n\t" /* movec d0,dtt0 */ + ".chip 68040\n\t" + "movec %%d0,%%itt0\n\t" + "movec %%d0,%%dtt0\n\t" + ".chip 68k\n\t" "jmp %0@\n\t" : /* no outputs */ : "a" (jmp_addr040)); @@ -692,7 +666,9 @@ /* disable translation on '040 now */ __asm__ __volatile__ ("moveq #0,%/d0\n\t" - ".long 0x4e7b0003\n\t" /* movec d0,tc; disable MMU */ + ".chip 68040\n\t" + "movec %%d0,%%tc\n\t" /* disable MMU */ + ".chip 68k\n\t" : /* no outputs */ : /* no inputs */ : "d0"); @@ -718,12 +694,13 @@ } -extern void *amiga_chip_alloc(long size); + /* + * Debugging + */ #define SAVEKMSG_MAXMEM 128*1024 - #define SAVEKMSG_MAGIC1 0x53415645 /* 'SAVE' */ #define SAVEKMSG_MAGIC2 0x4B4D5347 /* 'KMSG' */ @@ -737,8 +714,15 @@ static struct savekmsg *savekmsg = NULL; +static void amiga_mem_console_write(const char *s, unsigned int count) +{ + if (savekmsg->size+count <= SAVEKMSG_MAXMEM-sizeof(struct savekmsg)) { + memcpy(savekmsg->data+savekmsg->size, s, count); + savekmsg->size += count; + } +} -static void ami_savekmsg_init(void) +static void amiga_savekmsg_init(void) { savekmsg = (struct savekmsg *)amiga_chip_alloc(SAVEKMSG_MAXMEM); savekmsg->magic1 = SAVEKMSG_MAGIC1; @@ -747,18 +731,87 @@ savekmsg->size = 0; } +static void amiga_serial_putc(char c) +{ + custom.serdat = (unsigned char)c | 0x100; + while (!(custom.serdatr & 0x2000)) + ; +} + +static void amiga_serial_console_write(const char *s, unsigned int count) +{ + while (count--) { + if (*s == '\n') + amiga_serial_putc('\r'); + amiga_serial_putc(*s++); + } +} + +#ifdef CONFIG_SERIAL_CONSOLE +void amiga_serial_puts(const char *s) +{ + amiga_serial_console_write(s, strlen(s)); +} -static void ami_mem_print(const char *b) +void amiga_serial_gets(char *s, int len) { - int len; + int ch, cnt = 0; - for (len = 0; b[len]; len++); - if (savekmsg->size+len <= SAVEKMSG_MAXMEM) { - memcpy(savekmsg->data+savekmsg->size, b, len); - savekmsg->size += len; + while (1) { + while (!(custom.intreqr & IF_RBF)) + barrier(); + ch = custom.serdatr & 0xff; + /* clear the interrupt, so that another character can be read */ + custom.intreq = IF_RBF; + + /* Check for backspace. */ + if (ch == 8 || ch == 127) { + if (cnt == 0) { + amiga_serial_putc('\007'); + continue; + } + cnt--; + amiga_serial_puts("\010 \010"); + continue; + } + + /* Check for enter. */ + if (ch == 10 || ch == 13) + break; + + /* See if line is too long. */ + if (cnt >= len + 1) { + amiga_serial_putc(7); + cnt--; + continue; + } + + /* Store and echo character. */ + s[cnt++] = ch; + amiga_serial_putc(ch); + } + /* Print enter. */ + amiga_serial_puts("\r\n"); + s[cnt] = 0; +} +#endif + +static void amiga_debug_init(void) +{ + if (!strcmp( m68k_debug_device, "ser" )) { + /* no initialization required (?) */ + amiga_console_driver.write = amiga_serial_console_write; + } else if (!strcmp( m68k_debug_device, "mem" )) { + amiga_savekmsg_init(); + amiga_console_driver.write = amiga_mem_console_write; } + register_console(&amiga_console_driver); } + + /* + * Amiga specific parts of /proc + */ static void amiga_get_model(char *model) { diff -u --recursive v2.1.35/linux/arch/m68k/amiga/cyberfb.c linux/arch/m68k/amiga/cyberfb.c --- v2.1.35/linux/arch/m68k/amiga/cyberfb.c Fri Dec 20 01:19:57 1996 +++ linux/arch/m68k/amiga/cyberfb.c Thu Apr 17 13:20:41 1997 @@ -32,7 +32,7 @@ #include #include #include -#include +#include #include #include #include "s3blit.h" @@ -235,6 +235,7 @@ static int Cyberfb_switch(int con); static int Cyberfb_updatevar(int con); static void Cyberfb_blank(int blank); +static int Cyberfb_setcmap(struct fb_cmap *cmap, int con); /* @@ -1179,6 +1180,7 @@ fb_info.switch_con = &Cyberfb_switch; fb_info.updatevar = &Cyberfb_updatevar; fb_info.blank = &Cyberfb_blank; + fb_info.setcmap = &Cyberfb_setcmap; do_fb_set_var(&Cyber_fb_predefined[0], 1); Cyber_fb_get_var(&disp[0].var, -1); @@ -1222,6 +1224,16 @@ static void Cyberfb_blank(int blank) { fbhw->blank(blank); +} + + + /* + * Set the colormap + */ + +static int Cyberfb_setcmap(struct fb_cmap *cmap, int con) +{ + return(Cyber_fb_set_cmap(cmap, 1, con)); } Only in linux/arch/m68k/amiga: retz3fb.c Only in linux/arch/m68k/amiga: retz3fb.h diff -u --recursive v2.1.35/linux/arch/m68k/amiga/zorro.c linux/arch/m68k/amiga/zorro.c --- v2.1.35/linux/arch/m68k/amiga/zorro.c Fri Dec 20 01:19:57 1996 +++ linux/arch/m68k/amiga/zorro.c Thu Apr 17 13:20:41 1997 @@ -16,7 +16,7 @@ #include #include #include -#include +#include #ifdef CONFIG_ZORRO @@ -82,6 +82,10 @@ PROD("Stormbringer", STORMBRINGER) END +BEGIN_PROD(3_STATE) + PROD("Megamix 2000 RAM", MEGAMIX_2000) +END + BEGIN_PROD(COMMODORE2) PROD("A2088 XT Bridgeboard", A2088) PROD("A2286 AT Bridgeboard", A2286) @@ -141,8 +145,12 @@ PROD("StarDrive", STARDRIVE) PROD("8-Up (Rev A)", 8_UP_A) PROD("8-Up (Rev Z)", 8_UP_Z) + PROD("Delta Card RAM", DELTA_RAM) + PROD("8-Star RAM", 8_STAR_RAM) + PROD("8-Star", 8_STAR) PROD("VXL RAM", VXL_RAM) PROD("VXL-30 Turbo Board", VXL_30) + PROD("Delta Card", DELTA) PROD("MBX 1200", MBX_1200) PROD("Hardframe 2000", HARDFRAME_2000) PROD("MBX 1200", MBX_1200_2) @@ -180,8 +188,8 @@ PROD("SupraDrive 4x4 SCSI Controller", SUPRADRIVE_4x4) PROD("2000 DMA HD", SUPRA_2000) PROD("500 HD/RAM", SUPRA_500) + PROD("500XP/2000 RAM", SUPRA_500XP) PROD("500RX/2000 RAM", SUPRA_500RX) - PROD("500RX/2000 RAM", SUPRA_500RX_2) PROD("2400zi Modem", SUPRA_2400ZI) PROD("Wordsync SCSI Controller", WORDSYNC) PROD("Wordsync II SCSI Controller", WORDSYNC_II) @@ -193,6 +201,10 @@ PROD("12 Gauge SCSI Controller", 12GAUGE) END +BEGIN_PROD(MTEC2) + PROD("AT500 RAM", AT500_2) +END + BEGIN_PROD(GVP3) PROD("Impact SCSI/Memory", IMPACT) END @@ -203,7 +215,11 @@ BEGIN_PROD(POWER_COMPUTING) PROD("DKB 3128 RAM", DKB_3128) + PROD("Rapid Fire SCSI Controller", RAPID_FIRE) + PROD("DKB 1202 RAM", DKB_1202) PROD("DKB Cobra / Viper II Turbo Board", VIPER_II_COBRA) + PROD("WildFire 060 Turbo Board", WILDFIRE_060) + PROD("WildFire 060 Turbo Board", WILDFIRE_060_2) END BEGIN_PROD(GVP) @@ -257,6 +273,9 @@ PROD("PP&S A500 68040 Turbo Board", PPS_A500_040) END +BEGIN_PROD(XEBEC) +END + BEGIN_PROD(SPIRIT) PROD("HDA 506 Harddisk", HDA_506) PROD("OctaByte RAM", OCTABYTE_RAM) @@ -268,6 +287,7 @@ BEGIN_PROD(BSC3) PROD("ALF 2 SCSI Controller", ALF_2_SCSI) + PROD("ALF 2 SCSI Controller", ALF_2_SCSI_2) PROD("ALF 3 SCSI Controller", ALF_3_SCSI_2) END @@ -291,9 +311,17 @@ BEGIN_PROD(KUPKE2) PROD("Golem SCSI-II Controller", KUPKE_SCSI_II) PROD("Golem Box", GOLEM_BOX) + PROD("030/882 Turbo Board", KUPKE_TURBO) PROD("Golem SCSI/AT Controller", KUPKE_SCSI_AT) END +BEGIN_PROD(GVP4) + PROD("A2000-RAM8/2", A2000_RAM8) +END + +BEGIN_PROD(INTERWORKS_NET) +END + BEGIN_PROD(HARDITAL) PROD("TQM 68030+68882 Turbo Board", TQM) END @@ -301,10 +329,14 @@ BEGIN_PROD(BSC2) PROD("Oktagon 2008 SCSI Controller", OKTAGON_SCSI) PROD("Tandem AT-2008/508 IDE Controller", TANDEM) + PROD("Alpha RAM 1200", ALPHA_RAM_1200) PROD("Oktagon 2008 RAM", OKTAGON_RAM) PROD("Alfa Data MultiFace I", MULTIFACE_I) PROD("Alfa Data MultiFace II", MULTIFACE_II) PROD("Alfa Data MultiFace III", MULTIFACE_III) + PROD("Framebuffer", BSC_FRAEMBUFFER) + PROD("Graffiti Graphics Board (RAM)", GRAFFITI_RAM) + PROD("Graffiti Graphics Board (REG)", GRAFFITI_REG) PROD("ISDN MasterCard", ISDN_MASTERCARD) PROD("ISDN MasterCard II", ISDN_MASTERCARD_2) END @@ -319,12 +351,15 @@ END BEGIN_PROD(IVS) - PROD("GrandSlam RAM", GRANDSLAM) + PROD("GrandSlam PIC 2 RAM", GRANDSLAM_PIC_2) + PROD("GrandSlam PIC 1 RAM", GRANDSLAM_PIC_1) PROD("OverDrive HD", IVS_OVERDRIVE) PROD("Trumpcard Classic SCSI Controller", TRUMPCARD_CLASSIC) PROD("Trumpcard Pro SCSI Controller", TRUMPCARD_PRO) PROD("Meta-4 RAM", META_4) + PROD("Wavetools Sound Board", WAVETOOLS) PROD("Vector SCSI Controller", VECTOR) + PROD("Vector SCSI Controller", VECTOR_2) END BEGIN_PROD(VECTOR) @@ -336,6 +371,7 @@ PROD("Visiona Graphics Board (REG)", VISIONA_REG) PROD("Merlin Graphics Board (RAM)", MERLIN_RAM) PROD("Merlin Graphics Board (REG)", MERLIN_REG) + PROD("Merlin Graphics Board (REG)", MERLIN_REG_2) END BEGIN_PROD(HYDRA_SYSTEMS) @@ -388,7 +424,11 @@ PROD("Domino Graphics Board (REG)", DOMINO_REG) PROD("Picasso II Graphics Board (RAM)", PICASSO_II_RAM) PROD("Picasso II Graphics Board (REG)", PICASSO_II_REG) - PROD("Picasso II Graphics Board (REG)", PICASSO_II_REG_2) + PROD("Picasso II/II+ Graphics Board (Segmented Mode)", PICASSO_II_SEGM) + PROD("Picassio IV Graphics Board", PICASSO_IV) + PROD("Picassio IV Graphics Board", PICASSO_IV_2) + PROD("Picassio IV Graphics Board", PICASSO_IV_3) + PROD("Picassio IV Graphics Board", PICASSO_IV_4) PROD("Ariadne Ethernet Card", ARIADNE) END @@ -402,8 +442,18 @@ PROD("CD-RAM Memory", AMITRIX_CD_RAM) END +BEGIN_PROD(ARMAX) + PROD("OmniBus Graphics Board", OMNIBUS) +END + +BEGIN_PROD(NEWTEK) + PROD("VideoToaster", VIDEOTOASTER) +END + BEGIN_PROD(MTEC) + PROD("AT500 IDE Controller", AT500) PROD("68030 Turbo Board", MTEC_68030) + PROD("68020i Turbo Board", MTEC_68020I) PROD("A1200 T68030/42 RTC Turbo Board", MTEC_T1230) PROD("8MB RAM", MTEC_RAM) END @@ -439,6 +489,11 @@ PROD("RCA 120 RAM", RCA_120) END +BEGIN_PROD(MEGA_MICRO) + PROD("SCRAM 500 SCSI Controller", SCRAM_500_SCSI) + PROD("SCRAM 500 RAM", SCRAM_500_RAM) +END + BEGIN_PROD(IMTRONICS2) PROD("Hurricane 2800 68030", HURRICANE_2800_3) PROD("Hurricane 2800 68030", HURRICANE_2800_4) @@ -448,6 +503,15 @@ PROD("Golem HD 3000", GOLEM_3000) END +BEGIN_PROD(ITH) + PROD("ISDN-Master II", ISDN_MASTER_II) +END + +BEGIN_PROD(VMC) + PROD("ISDN Blaster Z2", ISDN_BLASTER_Z2) + PROD("HyperCom 4", HYPERCOM_4) +END + BEGIN_PROD(INFORMATION) PROD("ISDN Engine I", ISDN_ENGINE_I) END @@ -479,6 +543,8 @@ PROD("Blizzard 2060 SCSI Controller", BLIZZARD_2060SCSI) PROD("CyberStorm Mk II", CYBERSTORM_II) PROD("CyberVision64 Graphics Board", CYBERVISION) + PROD("CyberVision64-3D Graphics Board Prototype)", CYBERVISION3D_PRT) + PROD("CyberVision64-3D Graphics Board", CYBERVISION3D) END BEGIN_PROD(DPS) @@ -487,6 +553,7 @@ BEGIN_PROD(APOLLO2) PROD("A620 68020 Accelerator", A620) + PROD("A620 68020 Accelerator", A620_2) END BEGIN_PROD(APOLLO) @@ -494,6 +561,10 @@ PROD("Turbo Board", APOLLO_TURBO) END +BEGIN_PROD(PETSOFF) + PROD("Delfina DSP", DELFINA) +END + BEGIN_PROD(UWE_GERLACH) PROD("RAM/ROM", UG_RAM_ROM) END @@ -507,6 +578,7 @@ PROD("Toccata Sound Board", TOCCATA) PROD("Retina Z3 Graphics Board", RETINA_Z3) PROD("VLab Motion", VLAB_MOTION) + PROD("Altais Graphics Board", ALTAIS) PROD("Falcon '040 Turbo Board", FALCON_040) END @@ -514,11 +586,12 @@ END BEGIN_PROD(SKI) + PROD("MAST Fireball SCSI Controller", MAST_FIREBALL) PROD("SCSI / Dual Serial", SKI_SCSI_SERIAL) END BEGIN_PROD(CAMERON) - PROD("Scanner Interface", CAMERON_SCANNER) + PROD("Personal A4", PERSONAL_A4) END BEGIN_PROD(REIS_WARE) @@ -530,6 +603,7 @@ MANUF("Pacific Peripherals", PACIFIC) MANUF("Kupke", KUPKE) MANUF("Memphis", MEMPHIS) + MANUF("3-State", 3_STATE) MANUF("Commodore", COMMODORE2) MANUF("Commodore", COMMODORE) MANUF("Commodore", COMMODORE3) @@ -546,7 +620,8 @@ MANUF("University of Lowell", UNIV_OF_LOWELL) MANUF("Ameristar", AMERISTAR) MANUF("Supra", SUPRA) - MANUF("CSA", CSA) + MANUF("Computer Systems Ass.", CSA) + MANUF("M-Tech", MTEC2) MANUF("Great Valley Products", GVP3) MANUF("ByteBox", BYTEBOX) MANUF("Power Computing", POWER_COMPUTING) @@ -554,6 +629,7 @@ MANUF("Synergy", SYNERGY) MANUF("Xetec", XETEC) MANUF("Progressive Peripherals", PPI) + MANUF("Xebec", XEBEC) MANUF("Spirit", SPIRIT) MANUF("BSC", BSC) MANUF("BSC", BSC3) @@ -562,6 +638,8 @@ MANUF("Checkpoint Technologies", CHECKPOINT) MANUF("ICD", ICD) MANUF("Kupke", KUPKE2) + MANUF("Great Valley Products", GVP4) + MANUF("Interworks Network", INTERWORKS_NET) MANUF("Hardital Synthesis", HARDITAL) MANUF("BSC", BSC2) MANUF("Advanced Systems & Software", ADV_SYS_SOFT) @@ -582,15 +660,20 @@ MANUF("Village Tronic", VILLAGE_TRONIC) MANUF("Utilities Unlimited", UTILITIES_ULTD) MANUF("Amitrix", AMITRIX) - MANUF("MTEC", MTEC) + MANUF("ArMax", ARMAX) + MANUF("NewTek", NEWTEK) + MANUF("M-Tech", MTEC) MANUF("Great Valley Products", GVP2) MANUF("Helfrich", HELFRICH2) MANUF("MacroSystems", MACROSYSTEMS) MANUF("ElBox Computer", ELBOX) MANUF("Harms Professional", HARMS_PROF) MANUF("Micronik", MICRONIK) + MANUF("MegaMicro", MEGA_MICRO) MANUF("Imtronics", IMTRONICS2) MANUF("Kupke", KUPKE3) + MANUF("ITH", ITH) + MANUF("VMC", VMC) MANUF("Information", INFORMATION) MANUF("Vortex", VORTEX) MANUF("DataFlyer", DATAFLYER) @@ -599,6 +682,7 @@ MANUF("DPS", DPS) MANUF("Apollo", APOLLO2) MANUF("Apollo", APOLLO) + MANUF("Petsoff LP", PETSOFF) MANUF("Uwe Gerlach", UWE_GERLACH) MANUF("MacroSystems", MACROSYSTEMS2) MANUF("Combitec", COMBITEC) @@ -758,7 +842,11 @@ identified = 1; break; } else { - epc = *(enum GVP_ident *)ZTWO_VADDR(addr+0x8000) & + /* + * The epc must be read as a short from the + * hardware. + */ + epc = *(unsigned short *)ZTWO_VADDR(addr+0x8000) & GVP_PRODMASK; for (k = 0; k < NUM_GVP_PROD; k++) if (Ext_Prod_GVP[k].ID == epc) { diff -u --recursive v2.1.35/linux/arch/m68k/atari/atafb.c linux/arch/m68k/atari/atafb.c --- v2.1.35/linux/arch/m68k/atari/atafb.c Fri Dec 20 01:19:57 1996 +++ linux/arch/m68k/atari/atafb.c Thu Apr 17 13:20:41 1997 @@ -2905,6 +2905,12 @@ do_install_cmap(currcon); } +static int +atafb_setcmap(struct fb_cmap *cmap, int con) +{ + return(atari_fb_set_cmap(cmap, 1, con)); +} + struct fb_info * atari_fb_init(long *mem_start) { @@ -2999,6 +3005,7 @@ fb_info.switch_con=&atafb_switch; fb_info.updatevar=&fb_update_var; fb_info.blank=&atafb_blank; + fb_info.setcmap=&atafb_setcmap; var=atari_fb_predefined+default_par-1; do_fb_set_var(var,1); strcat(fb_info.modename,fb_var_names[default_par-1][0]); diff -u --recursive v2.1.35/linux/arch/m68k/atari/ataints.c linux/arch/m68k/atari/ataints.c --- v2.1.35/linux/arch/m68k/atari/ataints.c Fri Dec 20 01:19:58 1996 +++ linux/arch/m68k/atari/ataints.c Thu Apr 17 13:20:41 1997 @@ -56,9 +56,7 @@ * All interrupt source have an internal number (defined in * ): Autovector interrupts are 1..7, then follow ST-MFP, * TT-MFP, SCC, and finally VME interrupts. Vector numbers for the latter can - * be allocated by atari_register_vme_int(). Currently, all int source numbers - * have the IRQ_MACHSPEC bit set, to keep the general int handling functions - * in kernel/ints.c from them. + * be allocated by atari_register_vme_int(). * * Each interrupt can be of three types: * @@ -180,7 +178,7 @@ void atari_slow_irq_##n##_dummy (void) { \ __asm__ (ALIGN_STR "\n" \ SYMBOL_NAME_STR(atari_slow_irq_) #n "_handler:\t" \ -" addql #1,"SYMBOL_NAME_STR(intr_count)"\n" \ +" addql #1,"SYMBOL_NAME_STR(local_irq_count)"\n" \ SAVE_ALL "\n" \ " andb #~(1<<(" #n "&7))," /* mask this interrupt */ \ "("MFP_MK_BASE"+(((" #n "&8)^8)>>2)+((" #n "&16)<<3)):w\n" \ @@ -192,7 +190,7 @@ " lea "SYMBOL_NAME_STR(irq_handler)"+("#n"+8)*8,%%a0\n" \ " pea %%sp@\n" /* push addr of frame */ \ " movel %%a0@(4),%%sp@-\n" /* push handler data */ \ -" pea (" #n "+0x10000008)\n" /* push int number */ \ +" pea (" #n "+8)\n" /* push int number */ \ " movel %%a0@,%%a0\n" \ " jbsr %%a0@\n" /* call the handler */ \ " addql #8,%%sp\n" \ @@ -283,7 +281,7 @@ SYMBOL_NAME_STR(atari_fast_irq_handler) ": orw #0x700,%%sr /* disable all interrupts */ "SYMBOL_NAME_STR(atari_prio_irq_handler) ":\t - addql #1,"SYMBOL_NAME_STR(intr_count)"\n" + addql #1,"SYMBOL_NAME_STR(local_irq_count)"\n" SAVE_ALL " /* get vector number from stack frame and convert to source */ bfextu %%sp@(" FORMATVEC "){#4,#10},%%d0 @@ -296,7 +294,6 @@ lea %%a0@(%%d0:l:8),%%a0 pea %%sp@ /* push frame address */ movel %%a0@(4),%%sp@- /* push handler data */ - bset #28,%%d0 /* set MACHSPEC bit */ movel %%d0,%%sp@- /* push int number */ movel %%a0@,%%a0 jsr %%a0@ /* and call the handler */ @@ -587,14 +584,12 @@ return 0; free_vme_vec_bitmap |= 1 << i; - return (VME_SOURCE_BASE + i) | IRQ_MACHSPEC; + return (VME_SOURCE_BASE + i); } void atari_unregister_vme_int(unsigned long irq) { - irq &= ~IRQ_MACHSPEC; - if(irq >= VME_SOURCE_BASE && irq < VME_SOURCE_BASE + VME_MAX_SOURCES) { irq -= VME_SOURCE_BASE; free_vme_vec_bitmap &= ~(1 << irq); diff -u --recursive v2.1.35/linux/arch/m68k/atari/atakeyb.c linux/arch/m68k/atari/atakeyb.c --- v2.1.35/linux/arch/m68k/atari/atakeyb.c Wed Sep 25 00:47:38 1996 +++ linux/arch/m68k/atari/atakeyb.c Thu Apr 17 13:20:41 1997 @@ -14,6 +14,7 @@ */ #include +#include #include #include #include @@ -40,6 +41,15 @@ /* Hook for mouse driver */ void (*atari_mouse_interrupt_hook) (char *); +/* variables for IKBD self test: */ + +/* state: 0: off; >0: in progress; >1: 0xf1 received */ +static volatile int ikbd_self_test; +/* timestamp when last received a char */ +static volatile unsigned long self_test_last_rcv; +/* bitmap of keys reported as broken */ +static unsigned long broken_keys[128/(sizeof(unsigned long)*8)] = { 0, }; + #define BREAK_MASK (0x80) /* @@ -331,12 +341,15 @@ { /* a very fast typist or a slow system, give a warning */ /* ...happens often if interrupts were disabled for too long */ - printk( "Keyboard overrun\n" ); + printk( KERN_DEBUG "Keyboard overrun\n" ); scancode = acia.key_data; /* Turn off autorepeating in case a break code has been lost */ del_timer( &atakeyb_rep_timer ); rep_scancode = 0; - if (IS_SYNC_CODE(scancode)) { + if (ikbd_self_test) + /* During self test, don't do resyncing, just process the code */ + goto interpret_scancode; + else if (IS_SYNC_CODE(scancode)) { /* This code seem already to be the start of a new packet or a * single scancode */ kb_state.state = KEYBOARD; @@ -386,10 +399,47 @@ kb_state.buf[0] = scancode; break; + case 0xF1: + /* during self-test, note that 0xf1 received */ + if (ikbd_self_test) { + ++ikbd_self_test; + self_test_last_rcv = jiffies; + break; + } + /* FALL THROUGH */ + default: break_flag = scancode & BREAK_MASK; scancode &= ~BREAK_MASK; + if (ikbd_self_test) { + /* Scancodes sent during the self-test stand for broken + * keys (keys being down). The code *should* be a break + * code, but nevertheless some AT keyboard interfaces send + * make codes instead. Therefore, simply ignore + * break_flag... + * */ + int keyval = ataplain_map[scancode], keytyp; + + set_bit( scancode, broken_keys ); + self_test_last_rcv = jiffies; + keyval = ataplain_map[scancode]; + keytyp = KTYP(keyval) - 0xf0; + keyval = KVAL(keyval); + + printk( KERN_WARNING "Key with scancode %d ", scancode ); + if (keytyp == KT_LATIN || keytyp == KT_LETTER) { + if (keyval < ' ') + printk( "('^%c') ", keyval + '@' ); + else + printk( "('%c') ", keyval ); + } + printk( "is broken -- will be ignored.\n" ); + break; + } + else if (test_bit( scancode, broken_keys )) + break; + if (break_flag) { del_timer( &atakeyb_rep_timer ); rep_scancode = 0; @@ -815,7 +865,18 @@ mfp.active_edge &= ~0x10; atari_turnon_irq(IRQ_MFP_ACIA); + ikbd_self_test = 1; ikbd_reset(); + /* wait for a period of inactivity (here: 0.25s), then assume the IKBD's + * self-test is finished */ + self_test_last_rcv = jiffies; + while( jiffies < self_test_last_rcv + HZ/4 ) + barrier(); + /* if not incremented: no 0xf1 received */ + if (ikbd_self_test == 1) + printk( KERN_ERR "WARNING: keyboard self test failed!\n" ); + ikbd_self_test = 0; + ikbd_mouse_disable(); ikbd_joystick_disable(); diff -u --recursive v2.1.35/linux/arch/m68k/atari/atari_ksyms.c linux/arch/m68k/atari/atari_ksyms.c --- v2.1.35/linux/arch/m68k/atari/atari_ksyms.c Fri Jan 3 01:33:25 1997 +++ linux/arch/m68k/atari/atari_ksyms.c Thu Apr 17 13:20:41 1997 @@ -1,3 +1,4 @@ +#include #include #include #include @@ -8,11 +9,12 @@ #include extern void atari_microwire_cmd( int cmd ); - +extern int atari_SCC_reset_done; EXPORT_SYMBOL(atari_mch_cookie); EXPORT_SYMBOL(atari_hw_present); EXPORT_SYMBOL(is_medusa); +EXPORT_SYMBOL(is_hades); EXPORT_SYMBOL(atari_register_vme_int); EXPORT_SYMBOL(atari_unregister_vme_int); EXPORT_SYMBOL(stdma_lock); @@ -23,7 +25,7 @@ EXPORT_SYMBOL(atari_mouse_buttons); EXPORT_SYMBOL(atari_mouse_interrupt_hook); EXPORT_SYMBOL(atari_MIDI_interrupt_hook); -EXPORT_SYMBOL(atari_mch_cookie); +EXPORT_SYMBOL(atari_SCC_reset_done); EXPORT_SYMBOL(ikbd_write); EXPORT_SYMBOL(ikbd_mouse_y0_top); EXPORT_SYMBOL(ikbd_mouse_thresh); diff -u --recursive v2.1.35/linux/arch/m68k/atari/config.c linux/arch/m68k/atari/config.c --- v2.1.35/linux/arch/m68k/atari/config.c Fri Dec 20 01:19:58 1996 +++ linux/arch/m68k/atari/config.c Thu Apr 17 13:20:41 1997 @@ -45,9 +45,15 @@ #include #include +#ifdef CONFIG_KGDB +#include +#endif + u_long atari_mch_cookie; struct atari_hw_present atari_hw_present; +extern char m68k_debug_device[]; + static void atari_sched_init(void (*)(int, void *, struct pt_regs *)); /* atari specific keyboard functions */ extern int atari_keyb_init(void); @@ -57,7 +63,7 @@ extern void atari_init_IRQ (void); extern int atari_request_irq (unsigned int irq, void (*handler)(int, void *, struct pt_regs *), unsigned long flags, const char *devname, void *dev_id); -extern int atari_free_irq (unsigned int irq, void *dev_id); +extern void atari_free_irq (unsigned int irq, void *dev_id); extern void atari_enable_irq (unsigned int); extern void atari_disable_irq (unsigned int); extern int atari_get_irq_list (char *buf); @@ -77,12 +83,17 @@ extern int atari_floppy_init (void); extern void atari_floppy_setup(char *, int *); #endif -static void atari_waitbut (void); extern struct consw fb_con; extern struct fb_info *atari_fb_init(long *); -static void atari_debug_init (void); +static void atari_debug_init(void); extern void atari_video_setup(char *, int *); -extern void atari_syms_export(void); + +static struct console atari_console_driver; + +/* Can be set somewhere, if a SCC master reset has already be done and should + * not be repeated; used by kgdb */ +int atari_SCC_reset_done = 0; + extern void (*kd_mksound)(unsigned int, unsigned int); @@ -240,6 +251,8 @@ { memset(&atari_hw_present, 0, sizeof(atari_hw_present)); + atari_debug_init(); + mach_sched_init = atari_sched_init; mach_keyb_init = atari_keyb_init; mach_kbdrate = atari_kbdrate; @@ -247,25 +260,21 @@ mach_init_IRQ = atari_init_IRQ; mach_request_irq = atari_request_irq; mach_free_irq = atari_free_irq; - mach_enable_irq = atari_enable_irq; - mach_disable_irq = atari_disable_irq; + enable_irq = atari_enable_irq; + disable_irq = atari_disable_irq; mach_get_model = atari_get_model; mach_get_hardware_list = atari_get_hardware_list; mach_get_irq_list = atari_get_irq_list; mach_gettimeoffset = atari_gettimeoffset; - mach_mksound = atari_mksound; mach_reset = atari_reset; #ifdef CONFIG_BLK_DEV_FD mach_floppy_init = atari_floppy_init; mach_floppy_setup = atari_floppy_setup; #endif conswitchp = &fb_con; - waitbut = atari_waitbut; mach_fb_init = atari_fb_init; mach_max_dma_address = 0xffffff; - mach_debug_init = atari_debug_init; mach_video_setup = atari_video_setup; - mach_syms_export = atari_syms_export; kd_mksound = atari_mksound; /* ++bjoern: @@ -273,7 +282,7 @@ */ printk( "Atari hardware found: " ); - if (is_medusa) { + if (is_medusa || is_hades) { /* There's no Atari video hardware on the Medusa, but all the * addresses below generate a DTACK so no bus error occurs! */ } @@ -315,7 +324,7 @@ ATARIHW_SET(SCSI_DMA); printk( "TT_SCSI_DMA " ); } - if (hwreg_present( &st_dma.dma_hi )) { + if (!is_hades && hwreg_present( &st_dma.dma_hi )) { ATARIHW_SET(STND_DMA); printk( "STND_DMA " ); } @@ -337,21 +346,25 @@ ATARIHW_SET(YM_2149); printk( "YM2149 " ); } - if (!is_medusa && hwreg_present( &tt_dmasnd.ctrl )) { + if (!is_medusa && !is_hades && hwreg_present( &tt_dmasnd.ctrl )) { ATARIHW_SET(PCM_8BIT); printk( "PCM " ); } - if (hwreg_present( (void *)(0xffff8940) )) { + if (!is_hades && hwreg_present( &codec.unused5 )) { ATARIHW_SET(CODEC); printk( "CODEC " ); } + if (hwreg_present( &dsp56k_host_interface.icr )) { + ATARIHW_SET(DSP56K); + printk( "DSP56K " ); + } if (hwreg_present( &tt_scc_dma.dma_ctrl ) && #if 0 /* This test sucks! Who knows some better? */ (tt_scc_dma.dma_ctrl = 0x01, (tt_scc_dma.dma_ctrl & 1) == 1) && (tt_scc_dma.dma_ctrl = 0x00, (tt_scc_dma.dma_ctrl & 1) == 0) #else - !is_medusa + !is_medusa && !is_hades #endif ) { ATARIHW_SET(SCC_DMA); @@ -365,7 +378,12 @@ ATARIHW_SET( ST_ESCC ); printk( "ST_ESCC " ); } - if (hwreg_present( &tt_scu.sys_mask )) { + if (is_hades) + { + ATARIHW_SET( VME ); + printk( "VME " ); + } + else if (hwreg_present( &tt_scu.sys_mask )) { ATARIHW_SET(SCU); /* Assume a VME bus if there's a SCU */ ATARIHW_SET( VME ); @@ -375,7 +393,7 @@ ATARIHW_SET(ANALOG_JOY); printk( "ANALOG_JOY " ); } - if (hwreg_present( blitter.halftone )) { + if (!is_hades && hwreg_present( blitter.halftone )) { ATARIHW_SET(BLITTER); printk( "BLITTER " ); } @@ -384,7 +402,7 @@ printk( "IDE " ); } #if 1 /* This maybe wrong */ - if (!is_medusa && + if (!is_medusa && !is_hades && hwreg_present( &tt_microwire.data ) && hwreg_present( &tt_microwire.mask ) && (tt_microwire.mask = 0x7ff, @@ -402,20 +420,20 @@ mach_hwclk = atari_hwclk; mach_set_clock_mmss = atari_set_clock_mmss; } - if (hwreg_present( &mste_rtc.sec_ones)) { + if (!is_hades && hwreg_present( &mste_rtc.sec_ones)) { ATARIHW_SET(MSTE_CLK); printk( "MSTE_CLK "); mach_gettod = atari_mste_gettod; mach_hwclk = atari_mste_hwclk; mach_set_clock_mmss = atari_mste_set_clock_mmss; } - if (!is_medusa && + if (!is_medusa && !is_hades && hwreg_present( &dma_wd.fdc_speed ) && hwreg_write( &dma_wd.fdc_speed, 0 )) { ATARIHW_SET(FDCSPEED); printk( "FDC_SPEED "); } - if (!ATARIHW_PRESENT(ST_SCSI)) { + if (!is_hades && !ATARIHW_PRESENT(ST_SCSI)) { ATARIHW_SET(ACSI); printk( "ACSI " ); } @@ -426,9 +444,11 @@ * translation (the one that must not be turned off in * head.S...) */ - __asm__ volatile ("moveq #0,%/d0;" - ".long 0x4e7b0004;" /* movec d0,itt0 */ - ".long 0x4e7b0006;" /* movec d0,dtt0 */ + __asm__ volatile ("moveq #0,%/d0\n\t" + ".chip 68040\n\t" + "movec %%d0,%%itt0\n\t" + "movec %%d0,%%dtt0\n\t" + ".chip 68k" : /* no outputs */ : /* no inputs */ : "d0"); @@ -452,13 +472,18 @@ tt1_val = 0xfe008543; /* Translate 0xfexxxxxx, enable, cache * inhibit, read and write, FDC mask = 3, * FDC val = 4 -> Supervisor only */ - __asm__ __volatile__ ( "pmove %0@,%/tt1" : : "a" (&tt1_val) ); + __asm__ __volatile__ ( ".chip 68030\n\t" + "pmove %0@,%/tt1\n\t" + ".chip 68k" + : : "a" (&tt1_val) ); } else { __asm__ __volatile__ ( "movel %0,%/d0\n\t" - ".long 0x4e7b0005\n\t" /* movec d0,itt1 */ - ".long 0x4e7b0007" /* movec d0,dtt1 */ + ".chip 68040\n\t" + "movec %%d0,%%itt1\n\t" + "movec %%d0,%%dtt1\n\t" + ".chip 68k" : : "g" (0xfe00a040) /* Translate 0xfexxxxxx, enable, * supervisor only, non-cacheable/ @@ -621,7 +646,7 @@ we use the fact that in head.S we have set up a mapping 0xFFxxxxxx -> 0x00xxxxxx, so that the first 16MB is accessible in the last 16MB of the address space. */ - tos_version = is_medusa ? 0xfff : *(unsigned short *)0xFF000002; + tos_version = (is_medusa || is_hades) ? 0xfff : *(unsigned short *)0xFF000002; *yearp += (tos_version < 0x306) ? 70 : 68; } @@ -696,7 +721,7 @@ /* Tos version at Physical 2. See above for explanation why we cannot use PTOV(2). */ - tos_version = is_medusa ? 0xfff : *(unsigned short *)0xff000002; + tos_version = (is_medusa || is_hades) ? 0xfff : *(unsigned short *)0xff000002; ctrl = RTC_READ(RTC_CONTROL); /* control registers are * independent from the UIP */ @@ -875,13 +900,6 @@ return retval; } - -static void atari_waitbut (void) -{ - /* sorry, no-op */ -} - - static inline void ata_mfp_out (char c) { while (!(mfp.trn_stat & 0x80)) /* wait for tx buf empty */ @@ -889,12 +907,12 @@ mfp.usart_dta = c; } -void ata_mfp_print (const char *str) +static void atari_mfp_console_write (const char *str, unsigned int count) { - for( ; *str; ++str ) { + while (count--) { if (*str == '\n') ata_mfp_out( '\r' ); - ata_mfp_out( *str ); + ata_mfp_out( *str++ ); } } @@ -907,12 +925,12 @@ scc.cha_b_data = c; } -void ata_scc_print (const char *str) +static void atari_scc_console_write (const char *str, unsigned int count) { - for( ; *str; ++str ) { + while (count--) { if (*str == '\n') ata_scc_out( '\r' ); - ata_scc_out( *str ); + ata_scc_out( *str++ ); } } @@ -937,20 +955,20 @@ return( 1 ); } -void ata_par_print (const char *str) +static void atari_par_console_write (const char *str, unsigned int count) { static int printer_present = 1; if (!printer_present) return; - for( ; *str; ++str ) { + while (count--) { if (*str == '\n') if (!ata_par_out( '\r' )) { printer_present = 0; return; } - if (!ata_par_out( *str )) { + if (!ata_par_out( *str++ )) { printer_present = 0; return; } @@ -958,11 +976,14 @@ } -static void atari_debug_init( void ) +static void atari_debug_init(void) { - extern void (*debug_print_proc)(const char *); - extern char m68k_debug_device[]; - +#ifdef CONFIG_KGDB + /* if the m68k_debug_device is used by the GDB stub, do nothing here */ + if (kgdb_initialized) + return(NULL); +#endif + if (!strcmp( m68k_debug_device, "ser" )) { /* defaults to ser2 for a Falcon and ser1 otherwise */ strcpy( m68k_debug_device, @@ -979,7 +1000,7 @@ mfp.tim_dt_d = 2; /* 9600 bps */ mfp.tim_ct_cd |= 0x01; /* start timer D, 1:4 */ mfp.trn_stat |= 0x01; /* enable TX */ - debug_print_proc = ata_mfp_print; + atari_console_driver.write = atari_mfp_console_write; } else if (!strcmp( m68k_debug_device, "ser2" )) { /* SCC Modem2 serial port */ @@ -1005,7 +1026,7 @@ scc.cha_b_ctrl = *p++; MFPDELAY(); } - debug_print_proc = ata_scc_print; + atari_console_driver.write = atari_scc_console_write; } else if (!strcmp( m68k_debug_device, "par" )) { /* parallel printer */ @@ -1016,29 +1037,10 @@ sound_ym.wd_data = 0; /* no char */ sound_ym.rd_data_reg_sel = 14; /* select port A */ sound_ym.wd_data = sound_ym.rd_data_reg_sel | 0x20; /* strobe H */ - debug_print_proc = ata_par_print; - } - else - debug_print_proc = NULL; -} - - -void ata_serial_print (const char *str) -{ - int c; - - while (c = *str++, c != 0) - { - if (c == '\n') - { - while (!(mfp.trn_stat & (1 << 7))) - barrier (); - mfp.usart_dta = '\r'; - } - while (!(mfp.trn_stat & (1 << 7))) - barrier (); - mfp.usart_dta = c; + atari_console_driver.write = atari_par_console_write; } + if (atari_console_driver.write) + register_console(&atari_console_driver); } /* ++roman: @@ -1079,7 +1081,8 @@ /* On the Medusa, phys. 0x4 may contain garbage because it's no ROM. See above for explanation why we cannot use PTOV(4). */ - reset_addr = is_medusa ? 0xe00030 : *(unsigned long *) 0xff000004; + reset_addr = is_hades ? 0x7fe00030 : + (is_medusa ? 0xe00030 : *(unsigned long *) 0xff000004); acia.key_ctrl = ACIA_RESET; /* reset ACIA for switch off OverScan, if it's active */ @@ -1159,6 +1162,8 @@ if (is_medusa) /* Medusa has TT _MCH cookie */ strcat (model, "Medusa"); + else if (is_hades) + strcat(model, "Hades"); else strcat (model, "TT"); break; @@ -1215,6 +1220,7 @@ ATARIHW_ANNOUNCE(SCU, "System Control Unit"); ATARIHW_ANNOUNCE(BLITTER, "Blitter"); ATARIHW_ANNOUNCE(VME, "VME Bus"); + ATARIHW_ANNOUNCE(DSP56K, "DSP56001 processor"); return(len); } diff -u --recursive v2.1.35/linux/arch/m68k/atari/joystick.c linux/arch/m68k/atari/joystick.c --- v2.1.35/linux/arch/m68k/atari/joystick.c Fri Apr 4 08:52:17 1997 +++ linux/arch/m68k/atari/joystick.c Thu Apr 17 13:20:41 1997 @@ -10,6 +10,7 @@ #include #include #include +#include #include #include @@ -90,30 +91,28 @@ char *buffer, unsigned long count) { int minor = DEVICE_NR(inode->i_rdev); - int i; if (count < 2) return -EINVAL; if (!joystick[minor].ready) return -EAGAIN; - put_user(joystick[minor].fire, buffer++); - put_user(joystick[minor].dir, buffer++); - for (i = 0; i < count; i++) - put_user(0, buffer++); joystick[minor].ready = 0; - - return i; + if (put_user(joystick[minor].fire, buffer++) || + put_user(joystick[minor].dir, buffer++)) + return -EFAULT; + if (count > 2) + if (clear_user(buffer, count - 2)) + return -EFAULT; + return count; } -static int joystick_select(struct inode *inode, struct file *file, int sel_type, select_table *wait) +static unsigned int joystick_poll(struct file *file, poll_table *wait) { - int minor = DEVICE_NR(inode->i_rdev); + int minor = DEVICE_NR(file->f_inode->i_rdev); - if (sel_type != SEL_IN) - return 0; + poll_wait(&joystick[minor].wait, wait); if (joystick[minor].ready) - return 1; - select_wait(&joystick[minor].wait, wait); + return POLLIN | POLLRDNORM; return 0; } @@ -122,7 +121,7 @@ read_joystick, write_joystick, NULL, /* joystick_readdir */ - joystick_select, + joystick_poll, NULL, /* joystick_ioctl */ NULL, /* joystick_mmap */ open_joystick, @@ -135,7 +134,7 @@ joystick[0].ready = joystick[1].ready = 0; joystick[0].wait = joystick[1].wait = NULL; - if (register_chrdev(MAJOR_NR, "joystick", &atari_joystick_fops)) + if (register_chrdev(MAJOR_NR, "Joystick", &atari_joystick_fops)) printk("unable to get major %d for joystick devices\n", MAJOR_NR); return 0; diff -u --recursive v2.1.35/linux/arch/m68k/boot/Makefile linux/arch/m68k/boot/Makefile --- v2.1.35/linux/arch/m68k/boot/Makefile Wed Sep 25 00:47:38 1996 +++ linux/arch/m68k/boot/Makefile Thu Apr 17 13:20:41 1997 @@ -8,14 +8,16 @@ ifdef CONFIG_AMIGA AMIGA_BOOTSTRAP = amiga_bootstrap AMIGA_BOOTOBJS := amiga/bootstrap.o amiga/linuxboot.o -AMIGA_HOSTCC = m68k-cbm-amigados-gcc -I$(TOPDIR)/include +AMIGA_HOSTCC = m68k-cbm-amigados-gcc +AMIGA_HOSTINC = -I$(TOPDIR)/include AMIGA_HOSTFLAGS=-m68030 -O2 -Wall -Dlinux endif ifdef CONFIG_ATARI ATARI_BOOTSTRAP = atari_bootstrap ATARI_BOOTOBJS := atari/bootstrap.o -ATARI_HOSTCC = m68k-mint-gcc -I$(TOPDIR)/include +ATARI_HOSTCC = m68k-mint-gcc +ATARI_HOSTINC = -I$(TOPDIR)/include ATARI_HOSTFLAGS = -m68030 -m68881 -Dlinux -O2 -Wall # BOOTP/TFTP support in bootstrap? @@ -36,27 +38,28 @@ ifdef CONFIG_ATARI atari_bootstrap: $(ATARI_BOOTOBJS) - $(ATARI_HOSTCC) $(ATARI_HOSTFLAGS) -o $@ $(ATARI_BOOTOBJS) + $(ATARI_HOSTCC) $(ATARI_HOSTINC) $(ATARI_HOSTFLAGS) -o $@ $(ATARI_BOOTOBJS) rm -f ../../../bootstrap ln $@ ../../../bootstrap endif ifdef CONFIG_AMIGA amiga_bootstrap: $(AMIGA_BOOTOBJS) - $(AMIGA_HOSTCC) $(AMIGA_HOSTFLAGS) -o $@ -s -noixemul $(AMIGA_BOOTOBJS) + $(AMIGA_HOSTCC) $(AMIGA_HOSTINC) $(AMIGA_HOSTFLAGS) -o $@ -s -noixemul $(AMIGA_BOOTOBJS) rm -f ../../../bootstrap ln $@ ../../../bootstrap endif $(AMIGA_BOOTOBJS): %.o: %.c - $(AMIGA_HOSTCC) $(AMIGA_HOSTFLAGS) -c $< -o $@ + $(AMIGA_HOSTCC) $(AMIGA_HOSTINC) $(AMIGA_HOSTFLAGS) -c $< -o $@ $(ATARI_BOOTOBJS): %.o: %.c - $(ATARI_HOSTCC) $(ATARI_HOSTFLAGS) -c $< -o $@ + $(ATARI_HOSTCC) $(ATARI_HOSTINC) $(ATARI_HOSTFLAGS) -c $< -o $@ bootstrap: $(AMIGA_BOOTSTRAP) $(ATARI_BOOTSTRAP) clean: - rm -f *.o amiga/*.o atari/*.o amiga_bootstrap atari_bootstrap + rm -f *.o amiga/*.o atari/*.o amiga_bootstrap atari_bootstrap \ + ../../../bootstrap dep: diff -u --recursive v2.1.35/linux/arch/m68k/boot/amiga/bootstrap.c linux/arch/m68k/boot/amiga/bootstrap.c --- v2.1.35/linux/arch/m68k/boot/amiga/bootstrap.c Fri Dec 20 01:19:58 1996 +++ linux/arch/m68k/boot/amiga/bootstrap.c Thu Apr 17 13:20:41 1997 @@ -51,9 +51,8 @@ /* Library Bases */ +long __oslibversion = 36; extern const struct ExecBase *SysBase; -const struct ExpansionBase *ExpansionBase; -const struct GfxBase *GfxBase; static const char *memfile_name = NULL; @@ -80,24 +79,25 @@ static void Close(int fd); static int FileSize(const char *path); static void Sleep(u_long micros); -static int ModifyBootinfo(struct amiga_bootinfo *bi); static void Usage(void) { fprintf(stderr, - "Linux/m68k Amiga Bootstrap version " AMIBOOT_VERSION "\n\n" - "Usage: %s [options] [kernel command line]\n\n" - "Valid options are:\n" - " -h, --help Display this usage information\n" - " -k, --kernel file Use kernel image `file' (default is `vmlinux')\n" - " -r, --ramdisk file Use ramdisk image `file'\n" - " -d, --debug Enable debug mode\n" - " -b, --baud speed Set the serial port speed (default is 9600)\n" - " -m, --memfile file Use memory file `file'\n" - " -v, --keep-video Don't reset the video mode\n" - " -t, --model id Set the Amiga model to `id'\n\n", - ProgramName); + "Linux/m68k Amiga Bootstrap version " AMIBOOT_VERSION "\n\n" + "Usage: %s [options] [kernel command line]\n\n" + "Basic options:\n" + " -h, --help Display this usage information\n" + " -k, --kernel file Use kernel image `file' (default is `vmlinux')\n" + " -r, --ramdisk file Use ramdisk image `file'\n" + "Advanced options:\n" + " -d, --debug Enable debug mode\n" + " -b, --baud speed Set the serial port speed (default is 9600)\n" + " -m, --memfile file Use memory file `file'\n" + " -v, --keep-video Don't reset the video mode\n" + " -t, --model id Set the Amiga model to `id'\n" + " -p, --processor cfm Set the processor type to `cfm\n\n", + ProgramName); exit(EXIT_FAILURE); } @@ -105,7 +105,7 @@ int main(int argc, char *argv[]) { int i; - int debugflag = 0, keep_video = 0; + int processor = 0, debugflag = 0, keep_video = 0; u_int baud = 0; const char *kernel_name = NULL; const char *ramdisk_name = NULL; @@ -117,17 +117,17 @@ if (!strcmp(argv[0], "-h") || !strcmp(argv[0], "--help")) Usage(); else if (!strcmp(argv[0], "-k") || !strcmp(argv[0], "--kernel")) - if (--argc && !kernel_name) { - kernel_name = argv[1]; - argv++; - } else - Usage(); + if (--argc && !kernel_name) { + kernel_name = argv[1]; + argv++; + } else + Usage(); else if (!strcmp(argv[0], "-r") || !strcmp(argv[0], "--ramdisk")) - if (--argc && !ramdisk_name) { - ramdisk_name = argv[1]; - argv++; - } else - Usage(); + if (--argc && !ramdisk_name) { + ramdisk_name = argv[1]; + argv++; + } else + Usage(); else if (!strcmp(argv[0], "-d") || !strcmp(argv[0], "--debug")) debugflag = 1; else if (!strcmp(argv[0], "-b") || !strcmp(argv[0], "--baud")) @@ -137,19 +137,25 @@ } else Usage(); else if (!strcmp(argv[0], "-m") || !strcmp(argv[0], "--memfile")) - if (--argc && !memfile_name) { - memfile_name = argv[1]; - argv++; - } else - Usage(); + if (--argc && !memfile_name) { + memfile_name = argv[1]; + argv++; + } else + Usage(); else if (!strcmp(argv[0], "-v") || !strcmp(argv[0], "--keep-video")) keep_video = 1; else if (!strcmp(argv[0], "-t") || !strcmp(argv[0], "--model")) - if (--argc && !model) { - model = atoi(argv[1]); - argv++; - } else - Usage(); + if (--argc && !model) { + model = atoi(argv[1]); + argv++; + } else + Usage(); + else if (!strcmp(argv[0], "-p") || !strcmp(argv[0], "--processor")) + if (--argc && !processor) { + processor = atoi(argv[1]); + argv++; + } else + Usage(); else break; } @@ -158,22 +164,6 @@ SysBase = *(struct ExecBase **)4; - /* open Expansion Library */ - ExpansionBase = (struct ExpansionBase *)OpenLibrary("expansion.library", - 36); - if (!ExpansionBase) { - fputs("Unable to open expansion.library V36 or greater! Aborting...\n", - stderr); - exit(EXIT_FAILURE); - } - - /* open Graphics Library */ - GfxBase = (struct GfxBase *)OpenLibrary ("graphics.library", 0); - if (!GfxBase) { - fputs("Unable to open graphics.library! Aborting...\n", stderr); - exit(EXIT_FAILURE); - } - /* * Join command line options */ @@ -187,9 +177,52 @@ } } + memset(&args.bi, 0, sizeof(args.bi)); + if (processor) { + int cpu = processor/100%10; + int fpu = processor/10%10; + int mmu = processor%10; + if (cpu) + args.bi.cputype = 1<<(cpu-1); + if (fpu) + args.bi.fputype = 1<<(fpu-1); + if (mmu) + args.bi.mmutype = 1<<(mmu-1); + } + /* + * If we have a memory file, read the memory information from it + */ + if (memfile_name) { + FILE *fp; + int i; + + if ((fp = fopen(memfile_name, "r")) == NULL) { + perror("open memory file"); + fprintf(stderr, "Cannot open memory file %s\n", memfile_name); + return(FALSE); + } + + if (fscanf(fp, "%lu", &args.bi.chip_size) != 1) { + fprintf(stderr, "memory file does not contain chip memory size\n"); + fclose(fp); + return(FALSE); + } + + for (i = 0; i < NUM_MEMINFO; i++) + if (fscanf(fp, "%lx %lu", &args.bi.memory[i].addr, + &args.bi.memory[i].size) != 2) + break; + + fclose(fp); + args.bi.num_memory = i; + } + strncpy(args.bi.command_line, commandline, CL_SIZE); + args.bi.command_line[CL_SIZE-1] = '\0'; + if (model != AMI_UNKNOWN) + args.bi.model = model; + args.kernelname = kernel_name; args.ramdiskname = ramdisk_name; - args.commandline = commandline; args.debugflag = debugflag; args.keep_video = keep_video; args.reset_boards = 1; @@ -204,14 +237,10 @@ args.close = Close; args.filesize = FileSize; args.sleep = Sleep; - args.modify_bootinfo = ModifyBootinfo; /* Do The Right Stuff */ linuxboot(&args); - CloseLibrary((struct Library *)GfxBase); - CloseLibrary((struct Library *)ExpansionBase); - /* if we ever get here, something went wrong */ exit(EXIT_FAILURE); } @@ -224,6 +253,7 @@ static void Puts(const char *str) { fputs(str, stderr); + fflush(stderr); } static long GetChar(void) @@ -234,6 +264,7 @@ static void PutChar(char c) { fputc(c, stderr); + fflush(stderr); } static void Printf(const char *fmt, ...) @@ -243,6 +274,7 @@ va_start(args, fmt); vfprintf(stderr, fmt, args); va_end(args); + fflush(stderr); } static int Open(const char *path) @@ -271,8 +303,8 @@ int fd, size = -1; if ((fd = open(path, O_RDONLY)) != -1) { - size = lseek(fd, 0, SEEK_END); - close(fd); + size = lseek(fd, 0, SEEK_END); + close(fd); } return(size); } @@ -298,47 +330,4 @@ } DeleteMsgPort(TimerPort); } -} - - -static int ModifyBootinfo(struct amiga_bootinfo *bi) -{ - /* - * if we have a memory file, read the memory information from it - */ - if (memfile_name) { - FILE *fp; - int i; - - if ((fp = fopen(memfile_name, "r")) == NULL) { - perror("open memory file"); - fprintf(stderr, "Cannot open memory file %s\n", memfile_name); - return(FALSE); - } - - if (fscanf(fp, "%lu", &bi->chip_size) != 1) { - fprintf(stderr, "memory file does not contain chip memory size\n"); - fclose(fp); - return(FALSE); - } - - for (i = 0; i < NUM_MEMINFO; i++) { - if (fscanf(fp, "%lx %lu", &bi->memory[i].addr, &bi->memory[i].size) - != 2) - break; - } - - fclose(fp); - - if (i != bi->num_memory && i > 0) - bi->num_memory = i; - } - - /* - * change the Amiga model, if necessary - */ - if (model != AMI_UNKNOWN) - bi->model = model; - - return(TRUE); } diff -u --recursive v2.1.35/linux/arch/m68k/boot/amiga/bootstrap.h linux/arch/m68k/boot/amiga/bootstrap.h --- v2.1.35/linux/arch/m68k/boot/amiga/bootstrap.h Fri Dec 20 01:19:58 1996 +++ linux/arch/m68k/boot/amiga/bootstrap.h Thu Apr 17 13:20:41 1997 @@ -59,30 +59,6 @@ struct IORequest; -static __inline void CloseLibrary(struct Library *library) -{ - register const struct ExecBase *a6 __asm("a6") = SysBase; - register struct Library *a1 __asm("a1") = library; - __asm __volatile ("jsr a6@(-0x19e)" - : /* no output */ - : "r" (a6), "r" (a1) - : "a0","a1","d0","d1", "memory"); -} - -static __inline struct Library *OpenLibrary(char *libName, - unsigned long version) -{ - register struct Library * _res __asm("d0"); - register const struct ExecBase *a6 __asm("a6") = SysBase; - register u_char *a1 __asm("a1") = libName; - register unsigned long d0 __asm("d0") = version; - __asm __volatile ("jsr a6@(-0x228)" - : "=r" (_res) - : "r" (a6), "r" (a1), "r" (d0) - : "a0","a1","d0","d1", "memory"); - return _res; -} - static __inline char OpenDevice(u_char *devName, u_long unit, struct IORequest *ioRequest, u_long flags) { diff -u --recursive v2.1.35/linux/arch/m68k/boot/amiga/linuxboot.c linux/arch/m68k/boot/amiga/linuxboot.c --- v2.1.35/linux/arch/m68k/boot/amiga/linuxboot.c Fri Dec 20 01:19:58 1996 +++ linux/arch/m68k/boot/amiga/linuxboot.c Thu Apr 17 13:20:42 1997 @@ -20,6 +20,24 @@ * This file is subject to the terms and conditions of the GNU General Public * License. See the file COPYING in the main directory of this archive * for more details. + * + * History: + * 03 Feb 1997 Implemented kernel decompression (Geert, based on Roman's + * code for ataboot) + * 30 Dec 1996 Reverted the CPU detection to the old scheme + * New boot parameter override scheme (Geert) + * 27 Nov 1996 Compatibility with bootinfo interface version 1.0 (Geert) + * 9 Sep 1996 Rewritten option parsing + * New parameter passing to linuxboot() (linuxboot_args) + * (Geert) + * 18 Aug 1996 Updated for the new boot information structure (Geert) + * 10 Jan 1996 The real Linux/m68k boot code moved to linuxboot.[ch] + * (Geert) + * 11 Jul 1995 Support for ELF kernel (untested!) (Andreas) + * 7 Mar 1995 Memory block sizes are rounded to a multiple of 256K + * instead of 1M (Geert) + * 31 May 1994 Memory thrash problem solved (Geert) + * 11 May 1994 A3640 MapROM check (Geert) */ @@ -29,6 +47,8 @@ #define BOOTINFO_COMPAT_1_0 /* bootinfo interface version 1.0 compatible */ +/* support compressed kernels? */ +#define ZKERNEL #include #include @@ -60,7 +80,7 @@ static const struct linuxboot_args *linuxboot_args; /* Bootinfo */ -static struct amiga_bootinfo bi; +struct amiga_bootinfo bi; #ifdef BOOTINFO_COMPAT_1_0 static struct compat_bootinfo compat_bootinfo; @@ -75,7 +95,6 @@ #define kernelname linuxboot_args->kernelname #define ramdiskname linuxboot_args->ramdiskname -#define commandline linuxboot_args->commandline #define debugflag linuxboot_args->debugflag #define keep_video linuxboot_args->keep_video #define reset_boards linuxboot_args->reset_boards @@ -91,8 +110,6 @@ #define Close linuxboot_args->close #define FileSize linuxboot_args->filesize #define Sleep linuxboot_args->sleep -#define ModifyBootinfo linuxboot_args->modify_bootinfo - /* * Function Prototypes @@ -115,6 +132,16 @@ u_long kernel_size) __attribute__ ((noreturn)); asmlinkage u_long maprommed(void); asmlinkage u_long check346(void); +#ifdef ZKERNEL +static int load_zkernel(int fd); +static int KRead(int fd, void *buf, int cnt); +static int KSeek(int fd, int offset); +static int KClose(int fd); +#else +#define KRead Read +#define KSeek Seek +#define KClose Close +#endif /* @@ -174,7 +201,7 @@ u_long linuxboot(const struct linuxboot_args *args) { - int kfd = -1, rfd = -1, elf_kernel = 0; + int kfd = -1, rfd = -1, elf_kernel = 0, do_fast, do_chip; int i, j; const struct MemHeader *mnp; struct ConfigDev *cdp = NULL; @@ -196,38 +223,42 @@ Puts("\nLinux/m68k Amiga Bootstrap version " AMIBOOT_VERSION "\n"); Puts("Copyright 1993,1994 by Hamish Macdonald and Greg Harp\n\n"); - memset(&bi, 0, sizeof(bi)); + /* Note: Initial values in bi override detected values */ + bi = args->bi; /* machine is Amiga */ bi.machtype = MACH_AMIGA; /* determine chipset */ - bi.chipset = get_chipset(); + if (!bi.chipset) + bi.chipset = get_chipset(); /* determine CPU, FPU and MMU type */ - get_processor(&bi.cputype, &bi.fputype, &bi.mmutype); + if (!bi.cputype) + get_processor(&bi.cputype, &bi.fputype, &bi.mmutype); /* determine Amiga model */ - bi.model = get_model(bi.chipset); + if (!bi.model) + bi.model = get_model(bi.chipset); model_mask = (bi.model != AMI_UNKNOWN) ? 1<cd_BoardAddr); - } + if (!bi.num_autocon) + for (i = 0; (cdp = (struct ConfigDev *)FindConfigDev(cdp, -1, -1)); i++) + if (bi.num_autocon < ZORRO_NUM_AUTO) + /* copy the contents of each structure into our boot info and + count this device */ + memcpy(&bi.autocon[bi.num_autocon++], cdp, + sizeof(struct ConfigDev)); + else + Printf("Warning: too many AutoConfig devices. Ignoring device at " + "0x%08lx\n", cdp->cd_BoardAddr); + do_fast = bi.num_memory ? 0 : 1; + do_chip = bi.chip_size ? 0 : 1; /* find out the memory in the system */ - bi.num_memory = 0; for (mnp = (struct MemHeader *)SysBase->MemList.lh_Head; mnp->mh_Node.ln_Succ; mnp = (struct MemHeader *)mnp->mh_Node.ln_Succ) { @@ -266,7 +297,7 @@ mh.mh_Lower = (void *)((u_long)mh.mh_Lower & 0xfffff000); /* if fast memory */ - if (mh.mh_Attributes & MEMF_FAST) { + if (do_fast && mh.mh_Attributes & MEMF_FAST) { /* set the size value to the size of this block and mask off to a 256K increment */ u_long size = ((u_long)mh.mh_Upper-(u_long)mh.mh_Lower)&0xfffc0000; @@ -279,30 +310,26 @@ bi.num_memory++; } else Printf("Warning: too many memory blocks. Ignoring block " - "of %ldK at 0x%08x\n", size>>10, + "of %ldK at 0x%08x\n", size>>10, (u_long)mh.mh_Lower); - } else if (mh.mh_Attributes & MEMF_CHIP) + } else if (do_chip && mh.mh_Attributes & MEMF_CHIP) /* if CHIP memory, record the size */ bi.chip_size = (u_long)mh.mh_Upper; } /* get info from ExecBase */ - bi.vblank = SysBase->VBlankFrequency; - bi.psfreq = SysBase->PowerSupplyFrequency; - bi.eclock = SysBase->ex_EClockFrequency; + if (!bi.vblank) + bi.vblank = SysBase->VBlankFrequency; + if (!bi.psfreq) + bi.psfreq = SysBase->PowerSupplyFrequency; + if (!bi.eclock) + bi.eclock = SysBase->ex_EClockFrequency; /* serial port */ - realbaud = baud ? baud : DEFAULT_BAUD; - bi.serper = (5*bi.eclock+realbaud/2)/realbaud-1; - - /* copy command line options into the kernel command line */ - strncpy(bi.command_line, commandline, CL_SIZE); - bi.command_line[CL_SIZE-1] = '\0'; - - - /* modify the bootinfo, e.g. to change the memory configuration */ - if (ModifyBootinfo && !ModifyBootinfo(&bi)) - goto Fail; + if (!bi.serper) { + realbaud = baud ? baud : DEFAULT_BAUD; + bi.serper = (5*bi.eclock+realbaud/2)/realbaud-1; + } /* display Amiga model */ if (bi.model >= first_amiga_model && bi.model <= last_amiga_model) @@ -347,7 +374,7 @@ } /* display the chipset */ - switch(bi.chipset) { + switch (bi.chipset) { case CS_STONEAGE: Puts(", old or unknown chipset"); break; @@ -457,11 +484,24 @@ Printf("Unable to open kernel file `%s'\n", kernelname); goto Fail; } - if (Read(kfd, (void *)&kexec, sizeof(kexec)) != sizeof(kexec)) { + if (KRead(kfd, (void *)&kexec, sizeof(kexec)) != sizeof(kexec)) { Puts("Unable to read exec header from kernel file\n"); goto Fail; } +#ifdef ZKERNEL + if (((unsigned char *)&kexec)[0] == 037 && + (((unsigned char *)&kexec)[1] == 0213 || + ((unsigned char *)&kexec)[1] == 0236)) { + /* That's a compressed kernel */ + Puts("Kernel is compressed\n"); + if (load_zkernel(kfd)) { + Puts("Decompression error -- aborting\n"); + goto Fail; + } + } +#endif + switch (N_MAGIC(kexec)) { case ZMAGIC: if (debugflag) @@ -479,8 +519,8 @@ default: /* Try to parse it as an ELF header */ - Seek(kfd, 0); - if ((Read(kfd, (void *)&kexec_elf, sizeof(kexec_elf)) == + KSeek(kfd, 0); + if ((KRead(kfd, (void *)&kexec_elf, sizeof(kexec_elf)) == sizeof(kexec_elf)) && (memcmp(&kexec_elf.e_ident[EI_MAG0], ELFMAG, SELFMAG) == 0)) { elf_kernel = 1; @@ -501,8 +541,8 @@ Puts("Unable to allocate memory for program headers\n"); goto Fail; } - Seek(kfd, kexec_elf.e_phoff); - if (Read(kfd, (void *)kernel_phdrs, + KSeek(kfd, kexec_elf.e_phoff); + if (KRead(kfd, (void *)kernel_phdrs, kexec_elf.e_phnum*sizeof(*kernel_phdrs)) != kexec_elf.e_phnum*sizeof(*kernel_phdrs)) { Puts("Unable to read program headers from kernel file\n"); @@ -557,32 +597,32 @@ /* read the text and data segments from the kernel image */ if (elf_kernel) for (i = 0; i < kexec_elf.e_phnum; i++) { - if (Seek(kfd, kernel_phdrs[i].p_offset) == -1) { + if (KSeek(kfd, kernel_phdrs[i].p_offset) == -1) { Printf("Failed to seek to segment %ld\n", i); goto Fail; } - if (Read(kfd, memptr+kernel_phdrs[i].p_vaddr-PAGE_SIZE, - kernel_phdrs[i].p_filesz) != kernel_phdrs[i].p_filesz) { + if (KRead(kfd, memptr+kernel_phdrs[i].p_vaddr-PAGE_SIZE, + kernel_phdrs[i].p_filesz) != kernel_phdrs[i].p_filesz) { Printf("Failed to read segment %ld\n", i); goto Fail; } } else { - if (Seek(kfd, text_offset) == -1) { + if (KSeek(kfd, text_offset) == -1) { Puts("Failed to seek to text\n"); goto Fail; } - if (Read(kfd, memptr, kexec.a_text) != kexec.a_text) { + if (KRead(kfd, memptr, kexec.a_text) != kexec.a_text) { Puts("Failed to read text\n"); goto Fail; } /* data follows immediately after text */ - if (Read(kfd, memptr+kexec.a_text, kexec.a_data) != kexec.a_data) { + if (KRead(kfd, memptr+kexec.a_text, kexec.a_data) != kexec.a_data) { Puts("Failed to read data\n"); goto Fail; } } - Close(kfd); + KClose(kfd); kfd = -1; /* Check kernel's bootinfo version */ @@ -706,7 +746,7 @@ /* Clean up and exit in case of a failure */ Fail: if (kfd != -1) - Close(kfd); + KClose(kfd); if (rfd != -1) Close(rfd); if (memptr) @@ -748,37 +788,17 @@ * Determine the CPU Type */ -/* Dectection of 68030 and up is unreliable, so we check ourself */ -/* Keep consistent with asm/setup.h! */ -/* 24.11.1996 Joerg Dorchain */ -asm( ".text\n" -ALIGN_STR "\n" -SYMBOL_NAME_STR(check346) ": - orw #0x700,%sr | disable ints - movec %vbr,%a0 | get vbr - movel %a0@(11*4),%a1 | save old trap vector (Line F) - movel #L1,%a0@(11*4) | set L1 as new vector - movel %sp,%d1 | save stack pointer - moveq #2,%d0 | value with exception (030) - .long 0xf6208000 | move16 %a0@+,%a0@+, the 030 test instruction - nop | clear instruction pipeline - movel %d1,%sp | restore stack pointer - movec %vbr,%a0 | get vbr again - moveq #4,%d0 | value with exception (040) - .word 0xf5c8 | plpar %a0@, the 040 test instruction - nop | clear instruction pipeline - moveq #8,%d0 | value if we come here -L1: movel %d1,%sp | restore stack pointer - movel %a1,%a0@(11*4) | restore vector - rte" -); - static void get_processor(u_long *cpu, u_long *fpu, u_long *mmu) { - if (SysBase->AttnFlags & (AFF_68030|AFF_68040|AFF_68060)) - *cpu = Supervisor(check346); + *cpu = *fpu = 0; + if (SysBase->AttnFlags & AFF_68060) + *cpu = CPU_68060; + else if (SysBase->AttnFlags & AFF_68040) + *cpu = CPU_68040; + else if (SysBase->AttnFlags & AFF_68030) + *cpu = CPU_68030; else if (SysBase->AttnFlags & AFF_68020) - *cpu = CPU_68020; + *cpu = CPU_68020; if (*cpu == CPU_68040 || *cpu == CPU_68060) { if (SysBase->AttnFlags & AFF_FPU40) *fpu = *cpu; @@ -786,7 +806,7 @@ if (SysBase->AttnFlags & AFF_68882) *fpu = FPU_68882; else if (SysBase->AttnFlags & AFF_68881) - *cpu = FPU_68881; + *fpu = FPU_68881; } *mmu = *cpu; } @@ -806,7 +826,7 @@ else { if (debugflag) Puts(" Chipset: "); - switch(chipset) { + switch (chipset) { case CS_STONEAGE: if (debugflag) Puts("Old or unknown\n"); @@ -1361,7 +1381,7 @@ Disable(); *nic_cr = 0x21; /* nic command register: software reset etc. */ - while(((*nic_isr & 0x80) == 0) && --n) /* wait for reset to complete */ + while (((*nic_isr & 0x80) == 0) && --n) /* wait for reset to complete */ ; Enable(); @@ -1373,3 +1393,294 @@ #error reset_a2060: not yet implemented } #endif + + +#ifdef ZKERNEL + +#define ZFILE_CHUNK_BITS 16 /* chunk is 64 KB */ +#define ZFILE_CHUNK_SIZE (1 << ZFILE_CHUNK_BITS) +#define ZFILE_CHUNK_MASK (ZFILE_CHUNK_SIZE-1) +#define ZFILE_N_CHUNKS (2*1024*1024/ZFILE_CHUNK_SIZE) + +/* variables for storing the uncompressed data */ +static char *ZFile[ZFILE_N_CHUNKS]; +static int ZFileSize = 0; +static int ZFpos = 0; +static int Zwpos = 0; + +static int Zinfd = 0; /* fd of compressed file */ + +/* + * gzip declarations + */ + +#define OF(args) args + +#define memzero(s, n) memset ((s), 0, (n)) + +typedef unsigned char uch; +typedef unsigned short ush; +typedef unsigned long ulg; + +#define INBUFSIZ 4096 +#define WSIZE 0x8000 /* window size--must be a power of two, and */ + /* at least 32K for zip's deflate method */ + +static uch *inbuf; +static uch *window; + +static unsigned insize = 0; /* valid bytes in inbuf */ +static unsigned inptr = 0; /* index of next byte to be processed in inbuf */ +static unsigned outcnt = 0; /* bytes in output buffer */ +static int exit_code = 0; +static long bytes_out = 0; + +#define get_byte() (inptr < insize ? inbuf[inptr++] : fill_inbuf()) + +/* Diagnostic functions (stubbed out) */ +#define Assert(cond,msg) +#define Trace(x) +#define Tracev(x) +#define Tracevv(x) +#define Tracec(c,x) +#define Tracecv(c,x) + +#define STATIC static + +static int fill_inbuf(void); +static void flush_window(void); +static void error(char *m); +static void gzip_mark(void **); +static void gzip_release(void **); + +#define malloc(x) AllocVec(x, MEMF_FAST | MEMF_PUBLIC) +#define free(x) FreeVec(x) + +#ifdef LILO +#include "inflate.c" +#else +#include "../../../../lib/inflate.c" +#endif + +static void gzip_mark(void **ptr) +{ +} + +static void gzip_release(void **ptr) +{ +} + + +/* + * Fill the input buffer. This is called only when the buffer is empty + * and at least one byte is really needed. + */ +static int fill_inbuf(void) +{ + if (exit_code) + return -1; + + insize = Read(Zinfd, inbuf, INBUFSIZ); + if (insize <= 0) + return -1; + + inptr = 1; + return(inbuf[0]); +} + +/* + * Write the output window window[0..outcnt-1] and update crc and bytes_out. + * (Used for the decompressed data only.) + */ +static void flush_window(void) +{ + ulg c = crc; /* temporary variable */ + unsigned n; + uch *in, ch; + int chunk = Zwpos >> ZFILE_CHUNK_BITS; + + if (exit_code) + return; + + if (chunk >= ZFILE_N_CHUNKS) { + error("Compressed image too large! Aborting.\n"); + return; + } + if (!ZFile[chunk]) { + if (!(ZFile[chunk] = (char *)AllocMem(ZFILE_CHUNK_SIZE, + MEMF_FAST | MEMF_PUBLIC))) { + error("Out of memory for decompresing kernel image\n"); + return; + } + } + memcpy(ZFile[chunk] + (Zwpos & ZFILE_CHUNK_MASK), window, outcnt); + Zwpos += outcnt; + +#define DISPLAY_BITS 10 + if ((Zwpos & ((1 << DISPLAY_BITS)-1)) == 0) + PutChar('.'); + + in = window; + for (n = 0; n < outcnt; n++) { + ch = *in++; + c = crc_32_tab[((int)c ^ ch) & 0xff] ^ (c >> 8); + } + crc = c; + bytes_out += (ulg)outcnt; + outcnt = 0; +} + +static void error(char *x) +{ + Printf("\n%s", x); + exit_code = 1; +} + +static inline int call_sub(int (*func)(void), void *stackp) +{ + register int _res __asm("d0"); + register int (*a0)(void) __asm("a0") = func; + register int (*a1)(void) __asm("a1") = stackp; + + __asm __volatile ("movel sp,a2;" + "movel a1,sp;" + "jsr a0@;" + "movel a2,sp" + : "=r" (_res) + : "r" (a0), "r" (a1) + : "a0", "a1", "a2", "d0", "d1", "memory"); + return(_res); +} + +static int load_zkernel(int fd) +{ + int i, err = -1; +#define ZSTACKSIZE (16384) + u_long *zstack; + + for (i = 0; i < ZFILE_N_CHUNKS; ++i) + ZFile[i] = NULL; + Zinfd = fd; + Seek(fd, 0); + + if (!(inbuf = (uch *)AllocMem(INBUFSIZ, MEMF_FAST | MEMF_PUBLIC))) + Puts("Couldn't allocate gunzip buffer\n"); + else { + if (!(window = (uch *)AllocMem(WSIZE, MEMF_FAST | MEMF_PUBLIC))) + Puts("Couldn't allocate gunzip window\n"); + else { + if (!(zstack = (u_long *)AllocMem(ZSTACKSIZE, + MEMF_FAST | MEMF_PUBLIC))) + Puts("Couldn't allocate gunzip stack\n"); + else { + Puts("Uncompressing kernel image "); + makecrc(); + if (!(err = call_sub(gunzip, (char *)zstack+ZSTACKSIZE))) + Puts("done\n"); + ZFileSize = Zwpos; + FreeMem(zstack, ZSTACKSIZE); + } + FreeMem(window, WSIZE); + window = NULL; + } + FreeMem(inbuf, INBUFSIZ); + inbuf = NULL; + } + Close(Zinfd); /* input file not needed anymore */ + return(err); +} + + +/* Note about the read/lseek wrapper and its memory management: It assumes + * that all seeks are only forward, and thus data already read or skipped can + * be freed. This is true for current organization of bootstrap and kernels. + * Little exception: The struct kexec at the start of the file. After reading + * it, there may be a seek back to the end of the file. But this currently + * doesn't hurt. (Roman) + */ + +static int KRead(int fd, void *buf, int cnt) +{ + unsigned done = 0; + + if (!ZFileSize) + return(Read(fd, buf, cnt)); + + if (ZFpos + cnt > ZFileSize) + cnt = ZFileSize - ZFpos; + + while (cnt > 0) { + unsigned chunk = ZFpos >> ZFILE_CHUNK_BITS; + unsigned endchunk = (chunk+1) << ZFILE_CHUNK_BITS; + unsigned n = cnt; + + if (ZFpos + n > endchunk) + n = endchunk - ZFpos; + memcpy(buf, ZFile[chunk] + (ZFpos & ZFILE_CHUNK_MASK), n); + cnt -= n; + buf += n; + done += n; + ZFpos += n; + + if (ZFpos == endchunk) { + FreeMem(ZFile[chunk], ZFILE_CHUNK_SIZE); + ZFile[chunk] = NULL; + } + } + + return(done); +} + + +static int KSeek(int fd, int offset) +{ + unsigned oldpos, oldchunk, newchunk; + + if (!ZFileSize) + return(Seek(fd, offset)); + + oldpos = ZFpos; + ZFpos = offset; + if (ZFpos < 0) { + ZFpos = 0; + return(-1); + } else if (ZFpos > ZFileSize) { + ZFpos = ZFileSize; + return(-1); + } + + /* free memory of skipped-over data */ + oldchunk = oldpos >> ZFILE_CHUNK_BITS; + newchunk = ZFpos >> ZFILE_CHUNK_BITS; + while(oldchunk < newchunk) { + if (ZFile[oldchunk]) { + FreeMem(ZFile[oldchunk], ZFILE_CHUNK_SIZE); + ZFile[oldchunk] = NULL; + } + ++oldchunk; + } + return(ZFpos); +} + + +static void free_zfile(void) +{ + int i; + + for (i = 0; i < ZFILE_N_CHUNKS; ++i) + if (ZFile[i]) { + FreeMem(ZFile[i], ZFILE_CHUNK_SIZE); + ZFile[i] = NULL; + } +} + +static int KClose(int fd) +{ + if (ZFileSize) { + free_zfile(); + ZFileSize = 0; + } else + Close(fd); + return(0); +} +#endif /* ZKERNEL */ diff -u --recursive v2.1.35/linux/arch/m68k/boot/amiga/linuxboot.h linux/arch/m68k/boot/amiga/linuxboot.h --- v2.1.35/linux/arch/m68k/boot/amiga/linuxboot.h Fri Dec 20 01:19:58 1996 +++ linux/arch/m68k/boot/amiga/linuxboot.h Thu Apr 17 13:20:42 1997 @@ -24,14 +24,14 @@ #include -#include +#include /* * Amiboot Version */ -#define AMIBOOT_VERSION "5.1" +#define AMIBOOT_VERSION "5.4" /* @@ -42,7 +42,7 @@ */ struct amiga_bootinfo { - u_long machtype; /* machine type */ + u_long machtype; /* machine type = MACH_AMIGA */ u_long cputype; /* system CPU */ u_long fputype; /* system FPU */ u_long mmutype; /* system MMU */ @@ -67,9 +67,9 @@ */ struct linuxboot_args { + struct amiga_bootinfo bi; /* Initial values override detected values */ const char *kernelname; const char *ramdiskname; - const char *commandline; int debugflag; int keep_video; int reset_boards; @@ -84,7 +84,6 @@ void (*close)(int fd); int (*filesize)(const char *path); void (*sleep)(u_long micros); - int (*modify_bootinfo)(struct amiga_bootinfo *bi); }; diff -u --recursive v2.1.35/linux/arch/m68k/boot/atari/bootp.c linux/arch/m68k/boot/atari/bootp.c --- v2.1.35/linux/arch/m68k/boot/atari/bootp.c Wed Sep 25 00:47:39 1996 +++ linux/arch/m68k/boot/atari/bootp.c Thu Apr 17 13:20:42 1997 @@ -203,18 +203,20 @@ /* get_remote_kernel(): * Perform all necessary steps to get the kernel image * from the boot server. If successfull (retval == 0), subsequent calls to - * kread() can access the data. + * kread() can access the data. Fatal errors (i.e., retrying is useless) + * return -2, others -1. */ int get_remote_kernel( const char *kname /* optional */ ) { char image_name[256]; - + int rv; + /* Check if a Ethernet interface is present and determine the Ethernet * address */ if (check_ethif() < 0) { printf( "No Ethernet interface found -- no remote boot possible.\n" ); - return( -1 ); + return( -2 ); } /* Do a BOOTP request to find out our IP address and the kernel image's @@ -223,23 +225,23 @@ strcpy( image_name, kname ); else *image_name = 0; - if (bootp( image_name ) < 0) - return( -1 ); + if ((rv = bootp( image_name )) < 0) + return( rv ); /* Now start a TFTP connection to receive the kernel image */ - if (tftp( image_name ) < 0) - return( -1 ); + if ((rv = tftp( image_name )) < 0) + return( rv ); return( 0 ); } -/* kread(), klseek(), kclose(): +/* ll_read(), ll_lseek(), ll_close(): * Functions for accessing the received kernel image like with read(), * lseek(), close(). */ -int kread( int fd, void *buf, unsigned cnt ) +int ll_read( int fd, void *buf, unsigned cnt ) { unsigned done = 0; @@ -261,18 +263,26 @@ buf += n; done += n; KFpos += n; + + if (KFpos == endchunk) { + free( KFile[chunk] ); + KFile[chunk] = NULL; + } } return( done ); } -int klseek( int fd, int where, int whence ) +int ll_lseek( int fd, int where, int whence ) { + unsigned oldpos, oldchunk, newchunk; + if (!KFileSize) return( lseek( fd, where, whence ) ); + oldpos = KFpos; switch( whence ) { case SEEK_SET: KFpos = where; @@ -295,11 +305,22 @@ return( -1 ); } + /* free memory of skipped-over data */ + oldchunk = oldpos >> KFILE_CHUNK_BITS; + newchunk = KFpos >> KFILE_CHUNK_BITS; + while( oldchunk < newchunk ) { + if (KFile[oldchunk]) { + free( KFile[oldchunk] ); + KFile[oldchunk] = NULL; + } + ++oldchunk; + } + return( KFpos ); } -int kclose( int fd ) +int ll_close( int fd ) { if (!KFileSize) @@ -382,7 +403,7 @@ } if (retry >= BOOTP_RETRYS) { printf( "No response from a bootp server\n" ); - return( -1 ); + return( -2 ); } ServerIPaddr = reply->bootp.siaddr; @@ -433,7 +454,7 @@ printf( "TFTP RREQ: %s\n", ErrStr[-err-1] ); if (--retries > 0) goto repeat_req; - return( -1 ); + return( err == ETIMEO ? -2 : -1 ); } retries = 5; diff -u --recursive v2.1.35/linux/arch/m68k/boot/atari/bootp.h linux/arch/m68k/boot/atari/bootp.h --- v2.1.35/linux/arch/m68k/boot/atari/bootp.h Wed Sep 25 00:47:39 1996 +++ linux/arch/m68k/boot/atari/bootp.h Thu Apr 17 13:20:42 1997 @@ -34,9 +34,9 @@ /***************************** Prototypes *****************************/ int get_remote_kernel( const char *kname ); -int kread( int fd, void *buf, unsigned cnt ); -int klseek( int fd, int where, int whence ); -int kclose( int fd ); +int ll_read( int fd, void *buf, unsigned cnt ); +int ll_lseek( int fd, int where, int whence ); +int ll_close( int fd ); /************************* End of Prototypes **************************/ diff -u --recursive v2.1.35/linux/arch/m68k/boot/atari/bootstrap.c linux/arch/m68k/boot/atari/bootstrap.c --- v2.1.35/linux/arch/m68k/boot/atari/bootstrap.c Fri Dec 20 01:19:58 1996 +++ linux/arch/m68k/boot/atari/bootstrap.c Thu Apr 17 13:20:42 1997 @@ -8,6 +8,8 @@ ** for more details. ** ** History: +** 01 Feb 1997 Implemented kernel decompression (Roman) +** 28 Nov 1996 Fixed and tested previous change (James) ** 27 Nov 1996 Compatibility with bootinfo interface version 1.0 (Geert) ** 12 Nov 1996 Fixed and tested previous change (Andreas) ** 18 Aug 1996 Updated for the new boot information structure (untested!) @@ -32,6 +34,8 @@ #define BOOTINFO_COMPAT_1_0 /* bootinfo interface version 1.0 compatible */ +/* support compressed kernels? */ +#define ZKERNEL #include #include @@ -159,6 +163,9 @@ * ...err! On the Afterburner040 (for the Falcon) it's the same... So we do * another test with 0x00ff82fe, that gives a bus error on the Falcon, but is * in the range where the Medusa always asserts DTACK. + * On the Hades address 0 is writeable as well and it asserts DTACK on + * address 0x00ff82fe. To test if the machine is a Hades, address 0xb0000000 + * is tested. On the Medusa this gives a bus error. */ int test_medusa( void ) @@ -177,7 +184,10 @@ "nop \n\t" "tstb 0x00ff82fe\n\t" "nop \n\t" - "moveq #1,%0\n" + "moveq #1,%0\n\t" + "tstb 0xb0000000\n\t" + "nop \n\t" + "moveq #0,%0\n" "Lberr:\t" "movel a1,sp\n\t" "movel a0,0x8" @@ -357,11 +367,21 @@ #ifdef USE_BOOTP # include "bootp.h" #else -# define kread read -# define klseek lseek -# define kclose close +# define ll_read read +# define ll_lseek lseek +# define ll_close close #endif +#ifdef ZKERNEL +static int load_zkernel( int fd ); +static int kread( int fd, void *buf, unsigned cnt ); +static int klseek( int fd, int where, int whence ); +static int kclose( int fd ); +#else +# define kread read +# define klseek lseek +# define kclose close +#endif /* ++andreas: this must be inline due to Super */ static inline void boot_exit (int) __attribute__ ((noreturn)); @@ -385,16 +405,18 @@ Elf32_Ehdr kexec_elf; Elf32_Phdr *kernel_phdrs = NULL; u_long start_mem, mem_size, rd_size, text_offset = 0, kernel_size; + int prefer_bootp = 1, kname_set = 0, n_knames; #ifdef USE_BOOTP - int prefer_bootp = 1, kname_set = 0; + int err; #endif + char kname_list[5][64]; void *bi_ptr; ramdisk_name = NULL; kernel_name = "vmlinux"; /* print the startup message */ - puts("\fLinux/68k Atari Bootstrap version 2.0" + puts("\fLinux/68k Atari Bootstrap version 2.2" #ifdef USE_BOOTP " (with BOOTP)" #endif @@ -410,11 +432,7 @@ bi.machtype = MACH_ATARI; /* check arguments */ -#ifdef USE_BOOTP while ((ch = getopt(argc, argv, "bdtsk:r:")) != EOF) -#else - while ((ch = getopt(argc, argv, "dtsk:r:")) != EOF) -#endif switch (ch) { case 'd': debugflag = 1; @@ -427,18 +445,14 @@ break; case 'k': kernel_name = optarg; -#ifdef USE_BOOTP kname_set = 1; -#endif break; case 'r': ramdisk_name = optarg; break; -#ifdef USE_BOOTP case 'b': prefer_bootp = 0; break; -#endif case '?': default: usage(); @@ -744,38 +758,60 @@ boot_exit(-1); #endif /* TEST */ + i = 0; #ifdef USE_BOOTP + if (!kname_set) + kname_list[i++][0] = '\0'; /* default kernel which BOOTP server says */ +#endif +#ifdef ZKERNEL + strcpy( kname_list[i], kernel_name ); + strcat( kname_list[i], ".gz" ); + ++i; +#endif + strcpy( kname_list[i++], kernel_name ); +#ifdef ZKERNEL + if (!kname_set) + strcpy( kname_list[i++], "vmlinuz" ); +#endif + n_knames = i; + kfd = -1; +#ifdef USE_BOOTP if (prefer_bootp) { - /* First try to get a remote kernel, then use a local kernel (if - * present) */ - if (get_remote_kernel( kname_set ? kernel_name : NULL ) < 0) { - printf( "\nremote boot failed; trying local kernel\n" ); - if ((kfd = open (kernel_name, O_RDONLY)) == -1) { - fprintf (stderr, "Unable to open kernel file %s\n", - kernel_name); - boot_exit (EXIT_FAILURE); - } + for( i = 0; i < n_knames; ++i ) { + if ((err = get_remote_kernel( kname_list[i] )) >= 0) + goto kernel_open; + if (err < -1) /* fatal error; retries don't help... */ + break; } + printf( "\nremote boot failed; trying local kernel\n" ); } - else { - /* Try BOOTP if local kernel cannot be opened */ - if ((kfd = open (kernel_name, O_RDONLY)) == -1) { - printf( "\nlocal kernel failed; trying remote boot\n" ); - if (get_remote_kernel( kname_set ? kernel_name : NULL ) < 0) { - fprintf (stderr, "Unable to remote boot and " - "to open kernel file %s\n", kernel_name); - boot_exit (EXIT_FAILURE); - } - } +#endif + for( i = 0; i < n_knames; ++i ) { + if ((kfd = open( kname_list[i], O_RDONLY )) != -1) + goto kernel_open; } -#else - /* open kernel executable and read exec header */ - if ((kfd = open (kernel_name, O_RDONLY)) == -1) { - fprintf (stderr, "Unable to open kernel file %s\n", kernel_name); - boot_exit (EXIT_FAILURE); +#ifdef USE_BOOTP + if (!prefer_bootp) { + printf( "\nlocal kernel failed; trying remote boot\n" ); + for( i = 0; i < n_knames; ++i ) { + if ((err = get_remote_kernel( kname_list[i] )) >= 0) + goto kernel_open; + if (err < -1) /* fatal error; retries don't help... */ + break; + } } #endif + fprintf( stderr, "Unable to open any kernel file\n(Tried " ); + for( i = 0; i < n_knames; ++i ) { + fprintf( stderr, "%s%s", kname_list[i], + i < n_knames-2 ? ", " : + i == n_knames-2 ? ", and " : + ")\n" ); + } + boot_exit( EXIT_FAILURE ); + + kernel_open: if (kread (kfd, (void *)&kexec, sizeof(kexec)) != sizeof(kexec)) { @@ -783,6 +819,19 @@ boot_exit (EXIT_FAILURE); } +#ifdef ZKERNEL + if (((unsigned char *)&kexec)[0] == 037 && + (((unsigned char *)&kexec)[1] == 0213 || + ((unsigned char *)&kexec)[1] == 0236)) { + /* That's a compressed kernel */ + printf( "Kernel is compressed\n" ); + if (load_zkernel( kfd )) { + printf( "Decompression error -- aborting\n" ); + boot_exit( EXIT_FAILURE ); + } + } +#endif + switch (N_MAGIC(kexec)) { case ZMAGIC: text_offset = N_TXTOFF(kexec); @@ -847,18 +896,6 @@ } else bi.ramdisk.size = 0; - - rd_size = bi.ramdisk.size; - if (mem_size - rd_size < MB && bi.num_memory > 1) - /* If running low on ST ram load ramdisk into alternate ram. */ - bi.ramdisk.addr = (u_long) bi.memory[1].addr + bi.memory[1].size - rd_size; - else - /* Else hopefully there is enough ST ram. */ - bi.ramdisk.addr = (u_long)start_mem + mem_size - rd_size; - - /* create the bootinfo structure */ - if (!create_bootinfo()) - boot_exit (EXIT_FAILURE); /* calculate the total required amount of memory */ if (elf_kernel) @@ -885,6 +922,19 @@ } else kernel_size = kexec.a_text + kexec.a_data + kexec.a_bss; + + rd_size = bi.ramdisk.size; + if (rd_size + kernel_size > mem_size - MB/2 && bi.num_memory > 1) + /* If running low on ST ram load ramdisk into alternate ram. */ + bi.ramdisk.addr = (u_long) bi.memory[1].addr + bi.memory[1].size - rd_size; + else + /* Else hopefully there is enough ST ram. */ + bi.ramdisk.addr = (u_long)start_mem + mem_size - rd_size; + + /* create the bootinfo structure */ + if (!create_bootinfo()) + boot_exit (EXIT_FAILURE); + memreq = kernel_size + bi_size; #ifdef BOOTINFO_COMPAT_1_0 if (sizeof(compat_bootinfo) > bi_size) @@ -997,7 +1047,7 @@ if (debugflag) { if (bi.ramdisk.size) - printf ("RAM disk at %#lx, size is %ldK\n", + printf ("RAM disk at %#lx, size is %ld\n", (u_long)(memptr + memreq - rd_size), bi.ramdisk.size); @@ -1192,7 +1242,7 @@ static int add_bi_record(u_short tag, u_short size, const void *data) { struct bi_record *record; - u_int size2; + u_short size2; size2 = (sizeof(struct bi_record)+size+3)&-4; if (bi_size+size2+sizeof(bi_union.record.tag) > MAX_BI_SIZE) { @@ -1238,7 +1288,7 @@ else if (bi.cputype & CPU_68060) compat_bootinfo.cputype = COMPAT_CPU_68060; else { - Printf("CPU type 0x%08lx not supported by kernel\n", bi.cputype); + printf("CPU type 0x%08lx not supported by kernel\n", bi.cputype); return(0); } if (bi.fputype & FPU_68881) @@ -1250,12 +1300,12 @@ else if (bi.fputype & FPU_68060) compat_bootinfo.cputype |= COMPAT_FPU_68060; else { - Printf("FPU type 0x%08lx not supported by kernel\n", bi.fputype); + printf("FPU type 0x%08lx not supported by kernel\n", bi.fputype); return(0); } compat_bootinfo.num_memory = bi.num_memory; if (compat_bootinfo.num_memory > COMPAT_NUM_MEMINFO) { - Printf("Warning: using only %d blocks of memory\n", + printf("Warning: using only %d blocks of memory\n", COMPAT_NUM_MEMINFO); compat_bootinfo.num_memory = COMPAT_NUM_MEMINFO; } @@ -1278,3 +1328,275 @@ return(1); } #endif /* BOOTINFO_COMPAT_1_0 */ + + +#ifdef ZKERNEL + +#define ZFILE_CHUNK_BITS 16 /* chunk is 64 KB */ +#define ZFILE_CHUNK_SIZE (1 << ZFILE_CHUNK_BITS) +#define ZFILE_CHUNK_MASK (ZFILE_CHUNK_SIZE-1) +#define ZFILE_N_CHUNKS (2*1024*1024/ZFILE_CHUNK_SIZE) + +/* variables for storing the uncompressed data */ +static char *ZFile[ZFILE_N_CHUNKS]; +static int ZFileSize = 0; +static int ZFpos = 0; +static int Zwpos = 0; + +static int Zinfd = 0; /* fd of compressed file */ + +/* + * gzip declarations + */ + +#define OF(args) args + +#define memzero(s, n) memset ((s), 0, (n)) + +typedef unsigned char uch; +typedef unsigned short ush; +typedef unsigned long ulg; + +#define INBUFSIZ 4096 +#define WSIZE 0x8000 /* window size--must be a power of two, and */ + /* at least 32K for zip's deflate method */ + +static uch *inbuf; +static uch *window; + +static unsigned insize = 0; /* valid bytes in inbuf */ +static unsigned inptr = 0; /* index of next byte to be processed in inbuf */ +static unsigned outcnt = 0; /* bytes in output buffer */ +static int exit_code = 0; +static long bytes_out = 0; + +#define get_byte() (inptr < insize ? inbuf[inptr++] : fill_inbuf()) + +/* Diagnostic functions (stubbed out) */ +#define Assert(cond,msg) +#define Trace(x) +#define Tracev(x) +#define Tracevv(x) +#define Tracec(c,x) +#define Tracecv(c,x) + +#define STATIC static + +static int fill_inbuf(void); +static void flush_window(void); +static void error(char *m); +static void gzip_mark(void **); +static void gzip_release(void **); + +#include "../../../../lib/inflate.c" + +static void gzip_mark( void **ptr ) +{ +} + +static void gzip_release( void **ptr ) +{ +} + + +/* + * Fill the input buffer. This is called only when the buffer is empty + * and at least one byte is really needed. + */ +static int fill_inbuf( void ) +{ + if (exit_code) + return -1; + + insize = ll_read( Zinfd, inbuf, INBUFSIZ ); + if (insize <= 0) + return -1; + + inptr = 1; + return( inbuf[0] ); +} + +/* + * Write the output window window[0..outcnt-1] and update crc and bytes_out. + * (Used for the decompressed data only.) + */ +static void flush_window( void ) +{ + ulg c = crc; /* temporary variable */ + unsigned n; + uch *in, ch; + int chunk = Zwpos >> ZFILE_CHUNK_BITS; + + if (chunk >= ZFILE_N_CHUNKS) { + fprintf( stderr, "compressed image too large! Aborting.\n" ); + boot_exit( EXIT_FAILURE ); + } + if (!ZFile[chunk]) { + if (!(ZFile[chunk] = (char *)Malloc( ZFILE_CHUNK_SIZE ))) { + fprintf( stderr, "Out of memory for decompresing kernel image\n" ); + boot_exit( EXIT_FAILURE ); + } + } + memcpy( ZFile[chunk] + (Zwpos & ZFILE_CHUNK_MASK), window, outcnt ); + Zwpos += outcnt; + +#define DISPLAY_BITS 13 + if ((Zwpos & ((1 << DISPLAY_BITS)-1)) == 0) { + printf( "." ); + fflush( stdout ); + } + + in = window; + for (n = 0; n < outcnt; n++) { + ch = *in++; + c = crc_32_tab[((int)c ^ ch) & 0xff] ^ (c >> 8); + } + crc = c; + bytes_out += (ulg)outcnt; + outcnt = 0; +} + +static void error( char *x ) +{ + fprintf( stderr, "\n%s", x); + exit_code = 1; +} + +static int load_zkernel( int fd ) +{ + int i, err; + + for( i = 0; i < ZFILE_N_CHUNKS; ++i ) + ZFile[i] = NULL; + Zinfd = fd; + ll_lseek( fd, 0, SEEK_SET ); + + if (!(inbuf = (uch *)Malloc( INBUFSIZ ))) { + fprintf( stderr, "Couldn't allocate gunzip buffer\n" ); + boot_exit( EXIT_FAILURE ); + } + if (!(window = (uch *)Malloc( WSIZE ))) { + fprintf( stderr, "Couldn't allocate gunzip window\n" ); + boot_exit( EXIT_FAILURE ); + } + + printf( "Uncompressing kernel image " ); + fflush( stdout ); + makecrc(); + if (!(err = gunzip())) + printf( "done\n" ); + ZFileSize = Zwpos; + ll_close( Zinfd ); /* input file not needed anymore */ + + Mfree( inbuf ); + Mfree( window ); + return( err ); +} + +/* Note about the read/lseek wrapper and its memory management: It assumes + * that all seeks are only forward, and thus data already read or skipped can + * be freed. This is true for current organization of bootstrap and kernels. + * Little exception: The struct kexec at the start of the file. After reading + * it, there may be a seek back to the end of the file. But this currently + * doesn't hurt. Same considerations apply to the TFTP file buffers. (Roman) + */ + +static int kread( int fd, void *buf, unsigned cnt ) +{ + unsigned done = 0; + + if (!ZFileSize) + return( ll_read( fd, buf, cnt ) ); + + if (ZFpos + cnt > ZFileSize) + cnt = ZFileSize - ZFpos; + + while( cnt > 0 ) { + unsigned chunk = ZFpos >> ZFILE_CHUNK_BITS; + unsigned endchunk = (chunk+1) << ZFILE_CHUNK_BITS; + unsigned n = cnt; + + if (ZFpos + n > endchunk) + n = endchunk - ZFpos; + memcpy( buf, ZFile[chunk] + (ZFpos & ZFILE_CHUNK_MASK), n ); + cnt -= n; + buf += n; + done += n; + ZFpos += n; + + if (ZFpos == endchunk) { + Mfree( ZFile[chunk] ); + ZFile[chunk] = NULL; + } + } + + return( done ); +} + + +static int klseek( int fd, int where, int whence ) +{ + unsigned oldpos, oldchunk, newchunk; + + if (!ZFileSize) + return( ll_lseek( fd, where, whence ) ); + + oldpos = ZFpos; + switch( whence ) { + case SEEK_SET: + ZFpos = where; + break; + case SEEK_CUR: + ZFpos += where; + break; + case SEEK_END: + ZFpos = ZFileSize + where; + break; + default: + return( -1 ); + } + if (ZFpos < 0) { + ZFpos = 0; + return( -1 ); + } + else if (ZFpos > ZFileSize) { + ZFpos = ZFileSize; + return( -1 ); + } + + /* free memory of skipped-over data */ + oldchunk = oldpos >> ZFILE_CHUNK_BITS; + newchunk = ZFpos >> ZFILE_CHUNK_BITS; + while( oldchunk < newchunk ) { + if (ZFile[oldchunk]) { + Mfree( ZFile[oldchunk] ); + ZFile[oldchunk] = NULL; + } + ++oldchunk; + } + + return( ZFpos ); +} + + +static void free_zfile( void ) +{ + int i; + + for( i = 0; i < ZFILE_N_CHUNKS; ++i ) + if (ZFile[i]) Mfree( ZFile[i] ); +} + +static int kclose( int fd ) +{ + if (ZFileSize) { + free_zfile(); + return( 0 ); + } + else + return( ll_close( fd ) ); +} + + + +#endif /* ZKERNEL */ diff -u --recursive v2.1.35/linux/arch/m68k/config.in linux/arch/m68k/config.in --- v2.1.35/linux/arch/m68k/config.in Mon Apr 7 11:35:29 1997 +++ linux/arch/m68k/config.in Thu Apr 17 13:20:42 1997 @@ -58,6 +58,9 @@ bool 'Amiga ECS chipset support' CONFIG_AMIFB_ECS bool 'Amiga AGA chipset support' CONFIG_AMIFB_AGA bool 'Amiga Cybervision support' CONFIG_FB_CYBER + if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then + bool 'Amiga RetinaZ3 support' CONFIG_FB_RETINAZ3 + fi # bool 'Amiga GSP (TMS340x0) support' CONFIG_AMIGA_GSP # if [ "$CONFIG_AMIGA_GSP" = "y" ]; then # bool 'DMI Resolver support' CONFIG_GSP_RESOLVER @@ -82,15 +85,15 @@ dep_tristate ' SCSI emulation support' CONFIG_BLK_DEV_IDESCSI $CONFIG_BLK_DEV_IDE fi if [ "$CONFIG_AMIGA" = "y" ]; then -tristate 'Amiga Zorro II ramdisk support' CONFIG_AMIGA_Z2RAM + tristate 'Amiga Zorro II ramdisk support' CONFIG_AMIGA_Z2RAM fi if [ "$CONFIG_ATARI" = "y" ]; then -tristate 'Atari ACSI support' CONFIG_ATARI_ACSI -if [ "$CONFIG_ATARI_ACSI" != "n" ]; then -comment 'Some devices (e.g. CD jukebox) support multiple LUNs' -bool 'Probe all LUNs on each ACSI device' CONFIG_ACSI_MULTI_LUN -dep_tristate 'Atari SLM laser printer support' CONFIG_ATARI_SLM $CONFIG_ATARI_ACSI -fi + tristate 'Atari ACSI support' CONFIG_ATARI_ACSI + if [ "$CONFIG_ATARI_ACSI" != "n" ]; then + comment 'Some devices (e.g. CD jukebox) support multiple LUNs' + bool 'Probe all LUNs on each ACSI device' CONFIG_ACSI_MULTI_LUN + dep_tristate 'Atari SLM laser printer support' CONFIG_ATARI_SLM $CONFIG_ATARI_ACSI + fi fi comment 'Additional Block Devices' @@ -138,17 +141,23 @@ comment 'SCSI low-level drivers' if [ "$CONFIG_AMIGA" = "y" ]; then -tristate 'A3000 WD33C93A support' CONFIG_A3000_SCSI -tristate 'A2091 WD33C93A support' CONFIG_A2091_SCSI -tristate 'GVP Series II WD33C93A support' CONFIG_GVP11_SCSI -bool 'CyberStorm SCSI support' CONFIG_CYBERSTORM_SCSI -bool 'CyberStorm SCSI Mk II support' CONFIG_CYBERSTORMII_SCSI -bool 'Blizzard 2060 SCSI support' CONFIG_BLZ2060_SCSI -bool 'Blizzard 1230IV/1260 SCSI support' CONFIG_BLZ1230_SCSI + tristate 'A3000 WD33C93A support' CONFIG_A3000_SCSI + tristate 'A2091 WD33C93A support' CONFIG_A2091_SCSI + tristate 'GVP Series II WD33C93A support' CONFIG_GVP11_SCSI + bool 'CyberStorm SCSI support' CONFIG_CYBERSTORM_SCSI + bool 'CyberStorm SCSI Mk II support' CONFIG_CYBERSTORMII_SCSI + bool 'Blizzard 2060 SCSI support' CONFIG_BLZ2060_SCSI + bool 'Blizzard 1230IV/1260 SCSI support' CONFIG_BLZ1230_SCSI + bool 'Fastlane SCSI support' CONFIG_FASTLANE_SCSI + if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then + bool 'A4000T SCSI support' CONFIG_A4000T_SCSI + bool 'A4091 SCSI support' CONFIG_A4091_SCSI + bool 'WarpEngine SCSI support' CONFIG_WARPENGINE_SCSI + fi fi if [ "$CONFIG_ATARI" = "y" ]; then -dep_tristate 'Atari native SCSI support' CONFIG_ATARI_SCSI $CONFIG_SCSI -bool 'Long delays for Toshiba CD-ROMs' CONFIG_ATARI_SCSI_TOSHIBA_DELAY + dep_tristate 'Atari native SCSI support' CONFIG_ATARI_SCSI $CONFIG_SCSI + bool 'Long delays for Toshiba CD-ROMs' CONFIG_ATARI_SCSI_TOSHIBA_DELAY fi #dep_tristate 'SCSI debugging host adapter' CONFIG_SCSI_DEBUG $CONFIG_SCSI endmenu @@ -202,6 +211,7 @@ define_bool CONFIG_VT y define_bool CONFIG_VT_CONSOLE y +define_bool CONFIG_FB_CONSOLE y tristate 'Parallel printer support' CONFIG_PRINTER if [ "$CONFIG_AMIGA" = "y" ]; then @@ -214,13 +224,26 @@ if [ "$CONFIG_ATARI" = "y" ]; then tristate 'Atari MFP serial support' CONFIG_ATARI_MFPSER tristate 'Atari SCC serial support' CONFIG_ATARI_SCC + if [ "$CONFIG_ATARI_SCC" = "y" -o "$CONFIG_ATARI_SCC" = "m" ]; then + bool 'Atari SCC serial DMA support' CONFIG_ATARI_SCC_DMA + fi tristate 'Atari MIDI serial support' CONFIG_ATARI_MIDI + if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then + tristate 'Atari DSP56k support (EXPERIMENTAL)' CONFIG_ATARI_DSP56K + fi fi if [ "$CONFIG_AMIGA" = "y" ]; then tristate 'Amiga builtin serial support' CONFIG_AMIGA_BUILTIN_SERIAL - bool 'GVP IO-Extender support' CONFIG_GVPIOEXT + tristate 'GVP IO-Extender support' CONFIG_GVPIOEXT + dep_tristate 'GVP IO-Extender parallel printer support' CONFIG_GVPIOEXT_LP $CONFIG_GVPIOEXT + dep_tristate 'GVP IO-Extender PLIP support' CONFIG_GVPIOEXT_PLIP $CONFIG_GVPIOEXT tristate 'Multiface Card III serial support' CONFIG_MULTIFACE_III_TTY fi +if [ "$CONFIG_ATARI_MFPSER" = "y" -o "$CONFIG_ATARI_SCC" = "y" -o \ + "$CONFIG_ATARI_MIDI" = "y" -o "$CONFIG_AMIGA_BUILTIN_SERIAL" = "y" -o \ + "$CONFIG_GVPIOEXT" = "y" -o "$CONFIG_MULTIFACE_III_TTY" = "y" ]; then + bool 'Serial console support' CONFIG_SERIAL_CONSOLE +fi bool 'Support for user serial device modules' CONFIG_USERIAL bool 'Watchdog Timer Support' CONFIG_WATCHDOG if [ "$CONFIG_WATCHDOG" != "n" ]; then @@ -228,6 +251,9 @@ bool ' Software Watchdog' CONFIG_SOFT_WATCHDOG fi bool 'Support for user misc device modules' CONFIG_UMISC +if [ "$CONFIG_AMIGA" = "y" -o "$CONFIG_ATARI" = "y" ]; then + define_bool CONFIG_ABSTRACT_CONSOLE y +fi endmenu mainmenu_option next_comment @@ -247,4 +273,5 @@ if [ "$CONFIG_PROFILE" = "y" ]; then int ' Profile shift count' CONFIG_PROFILE_SHIFT 2 fi +bool 'Remote debugging support' CONFIG_KGDB endmenu diff -u --recursive v2.1.35/linux/arch/m68k/console/fbcon.c linux/arch/m68k/console/fbcon.c --- v2.1.35/linux/arch/m68k/console/fbcon.c Fri Dec 20 01:19:58 1996 +++ linux/arch/m68k/console/fbcon.c Thu Apr 17 13:20:42 1997 @@ -61,7 +61,7 @@ #endif #ifdef CONFIG_FB_CYBER #include "../amiga/s3blit.h" -#endif /* CONFIG_FB_CYBER */ +#endif #include #include #include @@ -70,7 +70,7 @@ #include #include "../../../drivers/char/vt_kern.h" /* vt_cons and vc_resize_con() */ - +#include "../../../drivers/char/console_struct.h" /* Import console_blanked from console.c */ @@ -95,6 +95,7 @@ #undef CONFIG_FBCON_24PACKED #undef CONFIG_FBCON_32PACKED #undef CONFIG_FBCON_CYBER +#undef CONFIG_FBCON_RETINAZ3 /* Monochrome is default */ @@ -117,7 +118,18 @@ #ifndef CONFIG_FBCON_CYBER #define CONFIG_FBCON_CYBER #endif -#endif /* CONFIG_FB_CYBER */ +#endif + +/* RetinaZ3 Graphics Board */ + +#ifdef CONFIG_FB_RETINAZ3 +#ifndef CONFIG_FBCON_RETINAZ3 +#define CONFIG_FBCON_RETINAZ3 +#endif +#ifndef CONFIG_FBCON_8PACKED +#define CONFIG_FBCON_8PACKED +#endif +#endif #endif /* CONFIG_AMIGA */ @@ -151,9 +163,9 @@ #undef CONFIG_FBCON_IPLAN2 #endif -#if defined(CONFIG_FBCON_CYBER) || defined(CONFIG_FBCON_8PACKED) || \ - defined(CONFIG_FBCON_16PACKED) || defined(CONFIG_FBCON_24PACKED) || \ - defined(CONFIG_FBCON_32PACKED) +#if defined(CONFIG_FBCON_CYBER) || defined(CONFIG_FBCON_RETINAZ3) || \ + defined(CONFIG_FBCON_8PACKED) || defined(CONFIG_FBCON_16PACKED) || \ + defined(CONFIG_FBCON_24PACKED) || defined(CONFIG_FBCON_32PACKED) #define CONFIG_FBCON_PACKED #else #undef CONFIG_FBCON_PACKED @@ -224,21 +236,24 @@ * Interface used by the world */ -static u_long fbcon_startup(u_long kmem_start, char **display_desc); +static u_long fbcon_startup(u_long kmem_start, const char **display_desc); static void fbcon_init(struct vc_data *conp); static int fbcon_deinit(struct vc_data *conp); static int fbcon_changevar(int con); static int fbcon_clear(struct vc_data *conp, int sy, int sx, int height, int width); -static int fbcon_putc(struct vc_data *conp, int c, int y, int x); -static int fbcon_putcs(struct vc_data *conp, const char *s, int count, int y, - int x); +static int fbcon_putc(struct vc_data *conp, int c, int yy, int xx); +static int fbcon_putcs(struct vc_data *conp, const char *s, int count, int yy, + int xx); static int fbcon_cursor(struct vc_data *conp, int mode); static int fbcon_scroll(struct vc_data *conp, int t, int b, int dir, int count); static int fbcon_bmove(struct vc_data *conp, int sy, int sx, int dy, int dx, int height, int width); static int fbcon_switch(struct vc_data *conp); static int fbcon_blank(int blank); +static int fbcon_get_font(struct vc_data *conp, int *w, int *h, char *data); +static int fbcon_set_font(struct vc_data *conp, int w, int h, char *data); +static int fbcon_set_palette(struct vc_data *conp, unsigned char *table); /* @@ -264,14 +279,22 @@ u_long val2, u_long val3, u_long val4); static __inline__ void memmove_8p_col(void *d, void *s, int h, int bpr); static __inline__ void expand8dl(u_char c, u_long *ret1, u_long *ret2); -static __inline__ void memclear_2p_col(void *d, size_t h, u_short val, int bpr); +static __inline__ void memclear_2p_col(void *d, size_t h, u_short val, + int bpr); static __inline__ void memset_even_2p(void *d, size_t count, u_long val); static __inline__ void memmove_2p_col(void *d, void *s, int h, int bpr); static __inline__ u_short expand2w(u_char c); static __inline__ u_long expand2l(u_char c); static __inline__ u_short dup2w(u_char c); -static __inline__ int real_y(struct display *p, int y); +static __inline__ int real_y(struct display *p, int yy); static void fbcon_vbl_handler(int irq, void *dummy, struct pt_regs *fp); +static __inline__ void updatescrollmode(struct display *p); +static __inline__ void ywrap_up(int unit, struct display *p, int count); +static __inline__ void ywrap_down(int unit, struct display *p, int count); +static __inline__ void ypan_up(int unit, struct vc_data *conp, + struct display *p, int count); +static __inline__ void ypan_down(int unit, struct vc_data *conp, + struct display *p, int count); static void fbcon_bmove_rec(struct display *p, int sy, int sx, int dy, int dx, int height, int width, u_int y_break); @@ -285,11 +308,11 @@ int height, int width); static void clear_mono(struct vc_data *conp, struct display *p, int sy, int sx, int height, int width); -static void putc_mono(struct vc_data *conp, struct display *p, int c, int y, - int x); +static void putc_mono(struct vc_data *conp, struct display *p, int c, int yy, + int xx); static void putcs_mono(struct vc_data *conp, struct display *p, const char *s, - int count, int y, int x); -static void rev_char_mono(struct display *p, int x, int y); + int count, int yy, int xx); +static void rev_char_mono(struct display *p, int xx, int yy); #endif /* CONFIG_FBCON_MONO */ @@ -302,11 +325,11 @@ int height, int width); static void clear_ilbm(struct vc_data *conp, struct display *p, int sy, int sx, int height, int width); -static void putc_ilbm(struct vc_data *conp, struct display *p, int c, int y, - int x); +static void putc_ilbm(struct vc_data *conp, struct display *p, int c, int yy, + int xx); static void putcs_ilbm(struct vc_data *conp, struct display *p, const char *s, - int count, int y, int x); -static void rev_char_ilbm(struct display *p, int x, int y); + int count, int yy, int xx); +static void rev_char_ilbm(struct display *p, int xx, int yy); #endif /* CONFIG_FBCON_ILBM */ @@ -319,11 +342,11 @@ int height, int width); static void clear_plan(struct vc_data *conp, struct display *p, int sy, int sx, int height, int width); -static void putc_plan(struct vc_data *conp, struct display *p, int c, int y, - int x); +static void putc_plan(struct vc_data *conp, struct display *p, int c, int yy, + int xx); static void putcs_plan(struct vc_data *conp, struct display *p, const char *s, - int count, int y, int x); -static void rev_char_plan(struct display *p, int x, int y); + int count, int yy, int xx); +static void rev_char_plan(struct display *p, int xx, int yy); #endif /* CONFIG_FBCON_PLANES */ @@ -336,11 +359,11 @@ int height, int width); static void clear_2_plane(struct vc_data *conp, struct display *p, int sy, int sx, int height, int width); -static void putc_2_plane(struct vc_data *conp, struct display *p, int c, int y, - int x); +static void putc_2_plane(struct vc_data *conp, struct display *p, int c, int yy, + int xx); static void putcs_2_plane(struct vc_data *conp, struct display *p, - const char *s, int count, int y, int x); -static void rev_char_2_plane(struct display *display, int x, int y); + const char *s, int count, int yy, int xx); +static void rev_char_2_plane(struct display *display, int xx, int yy); #endif /* CONFIG_FBCON_2PLANE */ @@ -353,11 +376,11 @@ int height, int width); static void clear_4_plane(struct vc_data *conp, struct display *p, int sy, int sx, int height, int width); -static void putc_4_plane(struct vc_data *conp, struct display *p, int c, int y, - int x); +static void putc_4_plane(struct vc_data *conp, struct display *p, int c, int yy, + int xx); static void putcs_4_plane(struct vc_data *conp, struct display *p, - const char *s, int count, int y, int x); -static void rev_char_4_plane(struct display *p, int x, int y); + const char *s, int count, int yy, int xx); +static void rev_char_4_plane(struct display *p, int xx, int yy); #endif /* CONFIG_FBCON_4PLANE */ @@ -370,11 +393,11 @@ int height, int width); static void clear_8_plane(struct vc_data *conp, struct display *p, int sy, int sx, int height, int width); -static void putc_8_plane(struct vc_data *conp, struct display *p, int c, int y, - int x); +static void putc_8_plane(struct vc_data *conp, struct display *p, int c, int yy, + int xx); static void putcs_8_plane(struct vc_data *conp, struct display *p, - const char *s, int count, int y, int x); -static void rev_char_8_plane(struct display *display, int x, int y); + const char *s, int count, int yy, int xx); +static void rev_char_8_plane(struct display *display, int xx, int yy); #endif /* CONFIG_FBCON_8PLANE */ @@ -387,11 +410,11 @@ int height, int width); static void clear_8_packed(struct vc_data *conp, struct display *p, int sy, int sx, int height, int width); -static void putc_8_packed(struct vc_data *conp, struct display *p, int c, int y, - int x); +static void putc_8_packed(struct vc_data *conp, struct display *p, int c, int yy, + int xx); static void putcs_8_packed(struct vc_data *conp, struct display *p, - const char *s, int count, int y, int x); -static void rev_char_8_packed(struct display *p, int x, int y); + const char *s, int count, int yy, int xx); +static void rev_char_8_packed(struct display *p, int xx, int yy); #endif /* CONFIG_FBCON_8PACKED */ @@ -405,10 +428,10 @@ static void clear_16_packed(struct vc_data *conp, struct display *p, int sy, int sx, int height, int width); static void putc_16_packed(struct vc_data *conp, struct display *p, int c, - int y, int x); + int yy, int xx); static void putcs_16_packed(struct vc_data *conp, struct display *p, - const char *s, int count, int y, int x); -static void rev_char_16_packed(struct display *p, int x, int y); + const char *s, int count, int yy, int xx); +static void rev_char_16_packed(struct display *p, int xx, int yy); #endif */ CONFIG_FBCON_8PACKED */ @@ -421,22 +444,38 @@ int height, int width); static void clear_cyber(struct vc_data *conp, struct display *p, int sy, int sx, int height, int width); -static void putc_cyber(struct vc_data *conp, struct display *p, int c, int y, - int x); +static void putc_cyber(struct vc_data *conp, struct display *p, int c, int yy, + int xx); static void putcs_cyber(struct vc_data *conp, struct display *p, const char *s, - int count, int y, int x); -static void rev_char_cyber(struct display *p, int x, int y); + int count, int yy, int xx); +static void rev_char_cyber(struct display *p, int xx, int yy); extern void Cyber_WaitQueue(u_short fifo); extern void Cyber_WaitBlit(void); extern void Cyber_BitBLT(u_short curx, u_short cury, u_short destx, u_short desty, u_short width, u_short height, u_short mode); -extern void Cyber_RectFill(u_short x, u_short y, u_short width, u_short height, +extern void Cyber_RectFill(u_short xx, u_short yy, u_short width, u_short height, u_short mode, u_short color); -extern void Cyber_MoveCursor(u_short x, u_short y); +extern void Cyber_MoveCursor(u_short xx, u_short yy); #endif /* CONFIG_FBCON_CYBER */ +#ifdef CONFIG_FBCON_RETINAZ3 +static void clear_retz3(struct vc_data *conp, struct display *p, int + sy, int sx, int height, int width); +static void bmove_retz3(struct display *p, int sy, int sx, int dy, int dx, + int height, int width); +extern void retz3_bitblt(struct fb_var_screeninfo *scr, + unsigned short srcx, unsigned short srcy, unsigned + short destx, unsigned short desty, unsigned short + width, unsigned short height, unsigned short cmd, + unsigned short mask); +static void putc_retz3(struct vc_data *conp, struct display *p, int c, + int yy, int xx); +static void putcs_retz3(struct vc_data *conp, struct display *p, const + char *s, int count, int yy, int xx); +static void rev_char_retz3(struct display *p, int xx, int yy); +#endif /* * `switch' for the Low Level Operations @@ -447,10 +486,10 @@ int width); void (*clear)(struct vc_data *conp, struct display *p, int sy, int sx, int height, int width); - void (*putc)(struct vc_data *conp, struct display *p, int c, int y, int x); + void (*putc)(struct vc_data *conp, struct display *p, int c, int yy, int xx); void (*putcs)(struct vc_data *conp, struct display *p, const char *s, - int count, int y, int x); - void (*rev_char)(struct display *p, int x, int y); + int count, int yy, int xx); + void (*rev_char)(struct display *p, int xx, int yy); }; @@ -509,8 +548,15 @@ }; #endif /* CONFIG_FBCON_CYBER */ +#ifdef CONFIG_FBCON_RETINAZ3 +static struct display_switch dispsw_retz3 = { + bmove_retz3, clear_retz3, putc_retz3, + putcs_retz3, rev_char_retz3 +}; +#endif + -static u_long fbcon_startup(u_long kmem_start, char **display_desc) +static u_long fbcon_startup(u_long kmem_start, const char **display_desc) { int irqres = 0; @@ -566,6 +612,19 @@ } +static __inline__ void updatescrollmode(struct display *p) +{ + if (divides(p->ywrapstep, p->fontheight) && + divides(p->fontheight, p->var.yres_virtual)) + p->scrollmode = SCROLL_YWRAP; + else if (divides(p->ypanstep, p->fontheight) && + p->var.yres_virtual >= p->var.yres+p->fontheight) + p->scrollmode = SCROLL_YPAN; + else + p->scrollmode = SCROLL_YMOVE; +} + + static void fbcon_setup(int con, int setcol, int init) { struct display *p = &disp[con]; @@ -579,16 +638,12 @@ &p->fontdata) || p->fontwidth != 8) getdefaultfont(p->var.xres, p->var.yres, NULL, &p->fontwidth, &p->fontheight, &p->fontdata); - if (p->fontwidth != 8) - panic("fbcon_setup: No support for fontwidth != 8"); - - if (divides(p->ywrapstep, p->fontheight) && divides(p->fontheight, p->var.yres_virtual)) - p->scrollmode = SCROLL_YWRAP; - else if (divides(p->ypanstep, p->fontheight) && - p->var.yres_virtual >= p->var.yres+p->fontheight) - p->scrollmode = SCROLL_YPAN; - else - p->scrollmode = SCROLL_YMOVE; + if (p->fontwidth != 8) { + /* ++Geert: changed from panic() to `correct and continue' */ + printk("fbcon_setup: No support for fontwidth != 8"); + p->fontwidth = 8; + } + updatescrollmode(p); nr_cols = p->var.xres/p->fontwidth; nr_rows = p->var.yres/p->fontheight; @@ -638,7 +693,8 @@ if (p->type == FB_TYPE_INTERLEAVED_PLANES && p->type_aux != 2) { if (p->line_length) { p->next_line = p->line_length*p->var.bits_per_pixel; - p->next_plane = p->line_length; + p->next_plane = p->line_length +; } else { p->next_line = p->type_aux; p->next_plane = p->type_aux/p->var.bits_per_pixel; @@ -658,13 +714,18 @@ #endif /* CONFIG_FBCON_PLANES */ #ifdef CONFIG_FBCON_PACKED if (p->type == FB_TYPE_PACKED_PIXELS) { - p->next_line = p->var.xres_virtual*p->var.bits_per_pixel>>3; + p->next_line = (p->var.xres_virtual*p->var.bits_per_pixel)>>3; p->next_plane = 0; #ifdef CONFIG_FBCON_CYBER if (p->var.accel == FB_ACCEL_CYBERVISION) p->dispsw = &dispsw_cyber; else -#endif /* CONFIG_FBCON_CYBER */ +#endif +#ifdef CONFIG_FBCON_RETINAZ3 + if (p->var.accel == FB_ACCEL_RETINAZ3) + p->dispsw = &dispsw_retz3; + else +#endif #ifdef CONFIG_FBCON_8PACKED if (p->var.bits_per_pixel == 8) p->dispsw = &dispsw_8_packed; @@ -1399,12 +1460,12 @@ * restriction is simplicity & efficiency at the moment. */ -static __inline__ int real_y(struct display *p, int y) +static __inline__ int real_y(struct display *p, int yy) { int rows = p->vrows; - y += p->yscroll; - return(y < rows ? y : y-rows); + yy += p->yscroll; + return(yy < rows ? yy : yy-rows); } @@ -1436,7 +1497,7 @@ } -static int fbcon_putc(struct vc_data *conp, int c, int y, int x) +static int fbcon_putc(struct vc_data *conp, int c, int yy, int xx) { int unit = conp->vc_num; struct display *p = &disp[unit]; @@ -1444,17 +1505,17 @@ if (!p->can_soft_blank && console_blanked) return(0); - if ((p->cursor_x == x) && (p->cursor_y == y)) + if ((p->cursor_x == xx) && (p->cursor_y == yy)) CURSOR_UNDRAWN(); - p->dispsw->putc(conp, p, c, real_y(p, y), x); + p->dispsw->putc(conp, p, c, real_y(p, yy), xx); return(0); } -static int fbcon_putcs(struct vc_data *conp, const char *s, int count, int y, - int x) +static int fbcon_putcs(struct vc_data *conp, const char *s, int count, int yy, + int xx) { int unit = conp->vc_num; struct display *p = &disp[unit]; @@ -1462,10 +1523,10 @@ if (!p->can_soft_blank && console_blanked) return(0); - if ((p->cursor_y == y) && (x <= p->cursor_x) && (p->cursor_x < x+count)) + if ((p->cursor_y == yy) && (xx <= p->cursor_x) && (p->cursor_x < xx+count)) CURSOR_UNDRAWN(); - p->dispsw->putcs(conp, p, s, count, real_y(p, y), x); + p->dispsw->putcs(conp, p, s, count, real_y(p, yy), xx); return(0); } @@ -1520,6 +1581,62 @@ } +static __inline__ void ywrap_up(int unit, struct display *p, int count) +{ + p->yscroll += count; + if (p->yscroll >= p->vrows) /* Deal with wrap */ + p->yscroll -= p->vrows; + p->var.xoffset = 0; + p->var.yoffset = p->yscroll*p->fontheight; + p->var.vmode |= FB_VMODE_YWRAP; + fb_info->updatevar(unit); +} + + +static __inline__ void ywrap_down(int unit, struct display *p, int count) +{ + p->yscroll -= count; + if (p->yscroll < 0) /* Deal with wrap */ + p->yscroll += p->vrows; + p->var.xoffset = 0; + p->var.yoffset = p->yscroll*p->fontheight; + p->var.vmode |= FB_VMODE_YWRAP; + fb_info->updatevar(unit); +} + + +static __inline__ void ypan_up(int unit, struct vc_data *conp, + struct display *p, int count) +{ + p->yscroll += count; + if (p->yscroll+conp->vc_rows > p->vrows) { + p->dispsw->bmove(p, p->yscroll, 0, 0, 0, conp->vc_rows-count, + conp->vc_cols); + p->yscroll = 0; + } + p->var.xoffset = 0; + p->var.yoffset = p->yscroll*p->fontheight; + p->var.vmode &= ~FB_VMODE_YWRAP; + fb_info->updatevar(unit); +} + + +static __inline__ void ypan_down(int unit, struct vc_data *conp, + struct display *p, int count) +{ + p->yscroll -= count; + if (p->yscroll < 0) { + p->yscroll = p->vrows-conp->vc_rows; + p->dispsw->bmove(p, 0, 0, p->yscroll+count, 0, conp->vc_rows-count, + conp->vc_cols); + } + p->var.xoffset = 0; + p->var.yoffset = p->yscroll*p->fontheight; + p->var.vmode &= ~FB_VMODE_YWRAP; + fb_info->updatevar(unit); +} + + static int fbcon_scroll(struct vc_data *conp, int t, int b, int dir, int count) { int unit = conp->vc_num; @@ -1536,84 +1653,98 @@ switch (dir) { case SM_UP: - if (t == 0 && b == conp->vc_rows && - vt_cons[unit]->vc_mode == KD_TEXT) { - if (count > conp->vc_rows) /* Maximum realistic size */ - count = conp->vc_rows; - switch (p->scrollmode) { - case SCROLL_YWRAP: - p->yscroll += count; - if (p->yscroll >= p->vrows) /* Deal with wrap */ - p->yscroll -= p->vrows; - p->var.xoffset = 0; - p->var.yoffset = p->yscroll*p->fontheight; - p->var.vmode |= FB_VMODE_YWRAP; - fb_info->updatevar(unit); - break; - - case SCROLL_YPAN: - p->yscroll += count; - if (p->yscroll+conp->vc_rows > p->vrows) { - p->dispsw->bmove(p, p->yscroll, 0, 0, 0, b-count, - conp->vc_cols); - p->yscroll = 0; - } - p->var.xoffset = 0; - p->var.yoffset = p->yscroll*p->fontheight; - p->var.vmode &= ~FB_VMODE_YWRAP; - fb_info->updatevar(unit); - break; - - case SCROLL_YMOVE: - p->dispsw->bmove(p, count, 0, 0, 0, b-count, conp->vc_cols); - break; - } - } else - fbcon_bmove(conp, t+count, 0, t, 0, b-t-count, conp->vc_cols); - fbcon_clear(conp, b-count, 0, count, conp->vc_cols); + if (count > conp->vc_rows) /* Maximum realistic size */ + count = conp->vc_rows; + if (vt_cons[unit]->vc_mode == KD_TEXT) + switch (p->scrollmode) { + case SCROLL_YWRAP: + if (b-t-count > 3*conp->vc_rows>>2) { + if (t > 0) + fbcon_bmove(conp, 0, 0, count, 0, t, conp->vc_cols); + ywrap_up(unit, p, count); + if (conp->vc_rows-b > 0) + fbcon_bmove(conp, b-count, 0, b, 0, conp->vc_rows-b, + conp->vc_cols); + } else + fbcon_bmove(conp, t+count, 0, t, 0, b-t-count, + conp->vc_cols); + fbcon_clear(conp, b-count, 0, count, conp->vc_cols); + break; + + case SCROLL_YPAN: + if (b-t-count > 3*conp->vc_rows>>2) { + if (t > 0) + fbcon_bmove(conp, 0, 0, count, 0, t, conp->vc_cols); + ypan_up(unit, conp, p, count); + if (conp->vc_rows-b > 0) + fbcon_bmove(conp, b-count, 0, b, 0, conp->vc_rows-b, + conp->vc_cols); + } else + fbcon_bmove(conp, t+count, 0, t, 0, b-t-count, + conp->vc_cols); + fbcon_clear(conp, b-count, 0, count, conp->vc_cols); + break; + + case SCROLL_YMOVE: + p->dispsw->bmove(p, t+count, 0, t, 0, b-t-count, + conp->vc_cols); + p->dispsw->clear(conp, p, b-count, 0, count, conp->vc_cols); + break; + } + else { + fbcon_bmove(conp, t+count, 0, t, 0, b-t-count, conp->vc_cols); + fbcon_clear(conp, b-count, 0, count, conp->vc_cols); + } break; case SM_DOWN: - if (t == 0 && b == conp->vc_rows && - vt_cons[unit]->vc_mode == KD_TEXT) { - if (count > conp->vc_rows) /* Maximum realistic size */ - count = conp->vc_rows; - switch (p->scrollmode) { - case SCROLL_YWRAP: - p->yscroll -= count; - if (p->yscroll < 0) /* Deal with wrap */ - p->yscroll += p->vrows; - p->var.xoffset = 0; - p->var.yoffset = p->yscroll*p->fontheight; - p->var.vmode |= FB_VMODE_YWRAP; - fb_info->updatevar(unit); - break; - - case SCROLL_YPAN: - p->yscroll -= count; - if (p->yscroll < 0) { - p->yscroll = p->vrows-conp->vc_rows; - p->dispsw->bmove(p, 0, 0, p->yscroll+count, 0, b-count, - conp->vc_cols); - } - p->var.xoffset = 0; - p->var.yoffset = p->yscroll*p->fontheight; - p->var.vmode &= ~FB_VMODE_YWRAP; - fb_info->updatevar(unit); - break; - - case SCROLL_YMOVE: - p->dispsw->bmove(p, 0, 0, count, 0, b-count, conp->vc_cols); - break; - } - } else - fbcon_bmove(conp, t, 0, t+count, 0, b-t-count, conp->vc_cols); - - /* Fixed bmove() should end Arno's frustration with copying? - * Confucius says: - * Man who copies in wrong direction, end up with trashed data - */ - fbcon_clear(conp, t, 0, count, conp->vc_cols); + if (count > conp->vc_rows) /* Maximum realistic size */ + count = conp->vc_rows; + if (vt_cons[unit]->vc_mode == KD_TEXT) + switch (p->scrollmode) { + case SCROLL_YWRAP: + if (b-t-count > 3*conp->vc_rows>>2) { + if (conp->vc_rows-b > 0) + fbcon_bmove(conp, b, 0, b-count, 0, conp->vc_rows-b, + conp->vc_cols); + ywrap_down(unit, p, count); + if (t > 0) + fbcon_bmove(conp, count, 0, 0, 0, t, conp->vc_cols); + } else + fbcon_bmove(conp, t, 0, t+count, 0, b-t-count, + conp->vc_cols); + fbcon_clear(conp, t, 0, count, conp->vc_cols); + break; + + case SCROLL_YPAN: + if (b-t-count > 3*conp->vc_rows>>2) { + if (conp->vc_rows-b > 0) + fbcon_bmove(conp, b, 0, b-count, 0, conp->vc_rows-b, + conp->vc_cols); + ypan_down(unit, conp, p, count); + if (t > 0) + fbcon_bmove(conp, count, 0, 0, 0, t, conp->vc_cols); + } else + fbcon_bmove(conp, t, 0, t+count, 0, b-t-count, + conp->vc_cols); + fbcon_clear(conp, t, 0, count, conp->vc_cols); + break; + + case SCROLL_YMOVE: + p->dispsw->bmove(p, t, 0, t+count, 0, b-t-count, + conp->vc_cols); + p->dispsw->clear(conp, p, t, 0, count, conp->vc_cols); + break; + } + else { + /* + * Fixed bmove() should end Arno's frustration with copying? + * Confucius says: + * Man who copies in wrong direction, end up with trashed data + */ + fbcon_bmove(conp, t, 0, t+count, 0, b-t-count, conp->vc_cols); + fbcon_clear(conp, t, 0, count, conp->vc_cols); + } break; case SM_LEFT: @@ -1832,14 +1963,7 @@ /* Adjust the virtual screen-size to fontheight*rows */ p->var.yres_virtual = (p->var.yres/h)*h; p->vrows = p->var.yres_virtual/h; - if (divides(p->ywrapstep, p->fontheight)) - p->scrollmode = SCROLL_YWRAP; - else if (divides(p->ypanstep, p->fontheight) && - p->var.yres_virtual >= p->var.yres+p->fontheight) - p->scrollmode = SCROLL_YPAN; - else - p->scrollmode = SCROLL_YMOVE; - + updatescrollmode(p); vc_resize_con( p->var.yres/h, p->var.xres/w, unit ); } else if (unit == fg_console) @@ -1854,6 +1978,38 @@ return( 0 ); } +static unsigned short palette_red[16]; +static unsigned short palette_green[16]; +static unsigned short palette_blue[16]; + +static struct fb_cmap palette_cmap = { + 0, 16, palette_red, palette_green, palette_blue, NULL +}; + +static int fbcon_set_palette(struct vc_data *conp, unsigned char *table) +{ + int unit = conp->vc_num; + struct display *p = &disp[unit]; + int i, j, k; + u_char val; + + if (!conp->vc_can_do_color || (!p->can_soft_blank && console_blanked)) + return(-EINVAL); + for (i = j = 0; i < 16; i++) { + k = table[i]; + val = conp->vc_palette[j++]; + palette_red[k] = (val<<8)|val; + val = conp->vc_palette[j++]; + palette_green[k] = (val<<8)|val; + val = conp->vc_palette[j++]; + palette_blue[k] = (val<<8)|val; + } + palette_cmap.len = 1<var.bits_per_pixel; + if (palette_cmap.len > 16) + palette_cmap.len = 16; + return(fb_info->setcmap(&palette_cmap, unit)); +} + /* ====================================================================== */ @@ -1882,8 +2038,8 @@ u_char *src, *dest; u_int rows; - if (sx == 0 && sy == 0 && width == p->next_line) { - src = p->screen_base; + if (sx == 0 && dx == 0 && width == p->next_line) { + src = p->screen_base+sy*p->fontheight*width; dest = p->screen_base+dy*p->fontheight*width; mymemmove(dest, src, height*p->fontheight*width); } else if (dy <= sy) { @@ -1928,28 +2084,28 @@ } -static void putc_mono(struct vc_data *conp, struct display *p, int c, int y, - int x) +static void putc_mono(struct vc_data *conp, struct display *p, int c, int yy, + int xx) { u_char *dest, *cdat; - u_int rows, bold, reverse, underline; + u_int rows, bold, revs, underl; u_char d; c &= 0xff; - dest = p->screen_base+y*p->fontheight*p->next_line+x; + dest = p->screen_base + yy*p->fontheight*p->next_line + xx; cdat = p->fontdata+c*p->fontheight; bold = attr_bold(p,conp); - reverse = attr_reverse(p,conp); - underline = attr_underline(p,conp); + revs = attr_reverse(p,conp); + underl = attr_underline(p,conp); for (rows = p->fontheight; rows--; dest += p->next_line) { d = *cdat++; - if (underline && !rows) + if (underl && !rows) d = 0xff; else if (bold) d |= d>>1; - if (reverse) + if (revs) d = ~d; *dest = d; } @@ -1957,16 +2113,16 @@ static void putcs_mono(struct vc_data *conp, struct display *p, const char *s, - int count, int y, int x) + int count, int yy, int xx) { u_char *dest, *dest0, *cdat; - u_int rows, bold, reverse, underline; + u_int rows, bold, revs, underl; u_char c, d; - dest0 = p->screen_base+y*p->fontheight*p->next_line+x; + dest0 = p->screen_base + yy*p->fontheight*p->next_line + xx; bold = attr_bold(p,conp); - reverse = attr_reverse(p,conp); - underline = attr_underline(p,conp); + revs = attr_reverse(p,conp); + underl = attr_underline(p,conp); while (count--) { c = *s++; @@ -1974,11 +2130,11 @@ cdat = p->fontdata+c*p->fontheight; for (rows = p->fontheight; rows--; dest += p->next_line) { d = *cdat++; - if (underline && !rows) + if (underl && !rows) d = 0xff; else if (bold) d |= d>>1; - if (reverse) + if (revs) d = ~d; *dest = d; } @@ -1986,12 +2142,12 @@ } -static void rev_char_mono(struct display *p, int x, int y) +static void rev_char_mono(struct display *p, int xx, int yy) { u_char *dest; u_int rows; - dest = p->screen_base+y*p->fontheight*p->next_line+x; + dest = p->screen_base + yy*p->fontheight*p->next_line + xx; for (rows = p->fontheight; rows--; dest += p->next_line) *dest = ~*dest; } @@ -2017,8 +2173,9 @@ static void bmove_ilbm(struct display *p, int sy, int sx, int dy, int dx, int height, int width) { - if (sx == 0 && sy == 0 && width == p->next_plane) - mymemmove(p->screen_base+dy*p->fontheight*p->next_line, p->screen_base, + if (sx == 0 && dx == 0 && width == p->next_plane) + mymemmove(p->screen_base+dy*p->fontheight*p->next_line, + p->screen_base+sy*p->fontheight*p->next_line, height*p->fontheight*p->next_line); else { u_char *src, *dest; @@ -2068,8 +2225,8 @@ } -static void putc_ilbm(struct vc_data *conp, struct display *p, int c, int y, - int x) +static void putc_ilbm(struct vc_data *conp, struct display *p, int c, int yy, + int xx) { u_char *dest, *cdat; u_int rows, i; @@ -2078,7 +2235,7 @@ c &= 0xff; - dest = p->screen_base+y*p->fontheight*p->next_line+x; + dest = p->screen_base + yy*p->fontheight*p->next_line + xx; cdat = p->fontdata+c*p->fontheight; fg0 = attr_fgcol(p,conp); bg0 = attr_bgcol(p,conp); @@ -2114,14 +2271,14 @@ * address, to reduce the number of expensive Chip RAM * accesses. * - * Experiments on my A4000/040 revealed that this makes a console switch on a - * 640x400 screen with 256 colors about 3 times faster. + * Experiments on my A4000/040 revealed that this makes a console + * switch on a 640x400 screen with 256 colors about 3 times faster. * * Geert */ static void putcs_ilbm(struct vc_data *conp, struct display *p, const char *s, - int count, int y, int x) + int count, int yy, int xx) { u_char *dest0, *dest, *cdat1, *cdat2, *cdat3, *cdat4; u_int rows, i; @@ -2129,15 +2286,15 @@ u_long d; int fg0, bg0, fg, bg; - dest0 = p->screen_base+y*p->fontheight*p->next_line+x; + dest0 = p->screen_base + yy*p->fontheight*p->next_line + xx; fg0 = attr_fgcol(p,conp); bg0 = attr_bgcol(p,conp); while (count--) - if (x&3 || count < 3) { /* Slow version */ + if (xx & 3 || count < 3) { /* Slow version */ c1 = *s++; dest = dest0++; - x++; + xx++; cdat1 = p->fontdata+c1*p->fontheight; for (rows = p->fontheight; rows--;) { @@ -2191,19 +2348,19 @@ } s += 4; dest0 += 4; - x += 4; + xx += 4; count -= 3; } } -static void rev_char_ilbm(struct display *p, int x, int y) +static void rev_char_ilbm(struct display *p, int xx, int yy) { u_char *dest, *dest0; u_int rows, i; int mask; - dest0 = p->screen_base+y*p->fontheight*p->next_line+x; + dest0 = p->screen_base + yy*p->fontheight*p->next_line + xx; mask = p->fgcol ^ p->bgcol; /* @@ -2239,8 +2396,8 @@ u_char *src, *dest, *src0, *dest0; u_int i, rows; - if (sx == 0 && sy == 0 && width == p->next_line) { - src = p->screen_base; + if (sx == 0 && dx == 0 && width == p->next_line) { + src = p->screen_base+sy*p->fontheight*width; dest = p->screen_base+dy*p->fontheight*width; for (i = p->var.bits_per_pixel; i--;) { mymemmove(dest, src, height*p->fontheight*width); @@ -2301,8 +2458,8 @@ } -static void putc_plan(struct vc_data *conp, struct display *p, int c, int y, - int x) +static void putc_plan(struct vc_data *conp, struct display *p, int c, int yy, + int xx) { u_char *dest, *dest0, *cdat, *cdat0; u_int rows, i; @@ -2311,7 +2468,7 @@ c &= 0xff; - dest0 = p->screen_base+y*p->fontheight*p->next_line+x; + dest0 = p->screen_base + yy*p->fontheight*p->next_line + xx; cdat0 = p->fontdata+c*p->fontheight; fg = attr_fgcol(p,conp); bg = attr_bgcol(p,conp); @@ -2344,7 +2501,7 @@ */ static void putcs_plan(struct vc_data *conp, struct display *p, const char *s, - int count, int y, int x) + int count, int yy, int xx) { u_char *dest, *dest0, *dest1; u_char *cdat1, *cdat2, *cdat3, *cdat4, *cdat10, *cdat20, *cdat30, *cdat40; @@ -2353,15 +2510,15 @@ u_long d; int fg0, bg0, fg, bg; - dest0 = p->screen_base+y*p->fontheight*p->next_line+x; + dest0 = p->screen_base + yy*p->fontheight*p->next_line + xx; fg0 = attr_fgcol(p,conp); bg0 = attr_bgcol(p,conp); while (count--) - if (x&3 || count < 3) { /* Slow version */ + if (xx & 3 || count < 3) { /* Slow version */ c1 = *s++; dest1 = dest0++; - x++; + xx++; cdat10 = p->fontdata+c1*p->fontheight; fg = fg0; @@ -2424,19 +2581,19 @@ } s += 4; dest0 += 4; - x += 4; + xx += 4; count -= 3; } } -static void rev_char_plan(struct display *p, int x, int y) +static void rev_char_plan(struct display *p, int xx, int yy) { u_char *dest, *dest0; u_int rows, i; int mask; - dest0 = p->screen_base+y*p->fontheight*p->next_line+x; + dest0 = p->screen_base + yy*p->fontheight*p->next_line + xx; mask = p->fgcol ^ p->bgcol; /* @@ -2499,8 +2656,8 @@ * done with memmove() */ mymemmove(p->screen_base + dy * p->next_line * p->fontheight, - p->screen_base + sy * p->next_line * p->fontheight, - p->next_line * height * p->fontheight); + p->screen_base + sy * p->next_line * p->fontheight, + p->next_line * height * p->fontheight); } else { int rows, cols; u_char *src; @@ -2607,8 +2764,8 @@ int bytes = p->next_line; int lines = height * p->fontheight; ulong size; - u_long cval; - u_short pcval; + u_long cval; + u_short pcval; cval = expand2l (COLOR_2P (attr_bgcol_ec(p,conp))); @@ -2650,43 +2807,45 @@ } -static void putc_2_plane(struct vc_data *conp, struct display *p, int c, int y, - int x) +static void putc_2_plane(struct vc_data *conp, struct display *p, int + c, int yy, int xx) { - u_char *dest; - u_char *cdat; - int rows; - int bytes = p->next_line; - ulong eorx, fgx, bgx, fdx; + u_char *dest; + u_char *cdat; + int rows; + int bytes = p->next_line; + ulong eorx, fgx, bgx, fdx; c &= 0xff; - dest = p->screen_base + y * p->fontheight * bytes + (x>>1)*4 + (x & 1); - cdat = p->fontdata + (c * p->fontheight); + dest = p->screen_base + yy * p->fontheight * bytes + + (xx >> 1)*4 + (xx & 1); + cdat = p->fontdata + (c * p->fontheight); fgx = expand2w(COLOR_2P(attr_fgcol(p,conp))); bgx = expand2w(COLOR_2P(attr_bgcol(p,conp))); eorx = fgx ^ bgx; - for(rows = p->fontheight ; rows-- ; dest += bytes) { + for(rows = p->fontheight ; rows-- ; dest += bytes) { fdx = dup2w(*cdat++); __asm__ __volatile__ ("movepw %1,%0@(0)" : /* no outputs */ - : "a" (dest), "d" ((fdx & eorx) ^ bgx)); + : "a" (dest), "d" ((fdx & eorx) ^ bgx)); } } static void putcs_2_plane(struct vc_data *conp, struct display *p, - const char *s, int count, int y, int x) + const char *s, int count, int yy, int xx) { u_char *dest, *dest0; - u_char *cdat, c; - int rows; - int bytes; - ulong eorx, fgx, bgx, fdx; - - bytes = p->next_line; - dest0 = p->screen_base + y * p->fontheight * bytes + (x>>1)*4 + (x & 1); + u_char *cdat, c; + int rows; + int bytes; + ulong eorx, fgx, bgx, fdx; + + bytes = p->next_line; + dest0 = p->screen_base + yy * p->fontheight * bytes + + (xx >> 1)*4 + (xx & 1); fgx = expand2w(COLOR_2P(attr_fgcol(p,conp))); bgx = expand2w(COLOR_2P(attr_bgcol(p,conp))); eorx = fgx ^ bgx; @@ -2699,32 +2858,33 @@ for(rows = p->fontheight, dest = dest0; rows-- ; dest += bytes) { fdx = dup2w(*cdat++); __asm__ __volatile__ ("movepw %1,%0@(0)" : /* no outputs */ - : "a" (dest), "d" ((fdx & eorx) ^ bgx)); + : "a" (dest), "d" ((fdx & eorx) ^ bgx)); } INC_2P(dest0); } } -static void rev_char_2_plane(struct display *p, int x, int y) +static void rev_char_2_plane(struct display *p, int xx, int yy) { - u_char *dest; - int j; - int bytes; + u_char *dest; + int j; + int bytes; - dest = p->screen_base + y * p->fontheight * p->next_line + (x>>1)*4 + (x & 1); - j = p->fontheight; - bytes = p->next_line; - while (j--) - { - /* This should really obey the individual character's - * background and foreground colors instead of simply - * inverting. - */ - dest[0] = ~dest[0]; - dest[2] = ~dest[2]; - dest += bytes; - } + dest = p->screen_base + yy * p->fontheight * p->next_line + + (xx >> 1)*4 + (xx & 1); + j = p->fontheight; + bytes = p->next_line; + while (j--) + { + /* This should really obey the individual character's + * background and foreground colors instead of simply + * inverting. + */ + dest[0] = ~dest[0]; + dest[2] = ~dest[2]; + dest += bytes; + } } #endif /* CONFIG_FBCON_2PLANE */ @@ -2763,8 +2923,8 @@ * done with memmove() */ mymemmove(p->screen_base + dy * p->next_line * p->fontheight, - p->screen_base + sy * p->next_line * p->fontheight, - p->next_line * height * p->fontheight); + p->screen_base + sy * p->next_line * p->fontheight, + p->next_line * height * p->fontheight); } else { int rows, cols; u_char *src; @@ -2871,9 +3031,9 @@ int bytes = p->next_line; int lines = height * p->fontheight; ulong size; - u_long cval1, cval2, pcval; + u_long cval1, cval2, pcval; - expand4dl(attr_bgcol_ec(p,conp), &cval1, &cval2); + expand4dl(attr_bgcol_ec(p,conp), &cval1, &cval2); if (sx == 0 && width == bytes/4) { @@ -2913,43 +3073,45 @@ } -static void putc_4_plane(struct vc_data *conp, struct display *p, int c, int y, - int x) +static void putc_4_plane(struct vc_data *conp, struct display *p, int + c, int yy, int xx) { u_char *dest; - u_char *cdat; - int rows; - int bytes = p->next_line; - ulong eorx, fgx, bgx, fdx; + u_char *cdat; + int rows; + int bytes = p->next_line; + ulong eorx, fgx, bgx, fdx; c &= 0xff; - dest = p->screen_base + y * p->fontheight * bytes + (x>>1)*8 + (x & 1); - cdat = p->fontdata + (c * p->fontheight); + dest = p->screen_base + yy * p->fontheight * bytes + + (xx >> 1)*8 + (xx & 1); + cdat = p->fontdata + (c * p->fontheight); fgx = expand4l(attr_fgcol(p,conp)); bgx = expand4l(attr_bgcol(p,conp)); eorx = fgx ^ bgx; - for(rows = p->fontheight ; rows-- ; dest += bytes) { + for(rows = p->fontheight ; rows-- ; dest += bytes) { fdx = dup4l(*cdat++); __asm__ __volatile__ ("movepl %1,%0@(0)" : /* no outputs */ - : "a" (dest), "d" ((fdx & eorx) ^ bgx)); + : "a" (dest), "d" ((fdx & eorx) ^ bgx)); } } static void putcs_4_plane(struct vc_data *conp, struct display *p, - const char *s, int count, int y, int x) + const char *s, int count, int yy, int xx) { u_char *dest, *dest0; - u_char *cdat, c; - int rows; - int bytes; - ulong eorx, fgx, bgx, fdx; - - bytes = p->next_line; - dest0 = p->screen_base + y * p->fontheight * bytes + (x>>1)*8 + (x & 1); + u_char *cdat, c; + int rows; + int bytes; + ulong eorx, fgx, bgx, fdx; + + bytes = p->next_line; + dest0 = p->screen_base + yy * p->fontheight * bytes + + (xx >> 1)*8 + (xx & 1); fgx = expand4l(attr_fgcol(p,conp)); bgx = expand4l(attr_bgcol(p,conp)); eorx = fgx ^ bgx; @@ -2969,20 +3131,21 @@ for(rows = p->fontheight, dest = dest0; rows-- ; dest += bytes) { fdx = dup4l(*cdat++); __asm__ __volatile__ ("movepl %1,%0@(0)" : /* no outputs */ - : "a" (dest), "d" ((fdx & eorx) ^ bgx)); + : "a" (dest), "d" ((fdx & eorx) ^ bgx)); } INC_4P(dest0); } } -static void rev_char_4_plane(struct display *p, int x, int y) +static void rev_char_4_plane(struct display *p, int xx, int yy) { u_char *dest; int j; int bytes; - dest = p->screen_base + y * p->fontheight * p->next_line + (x>>1)*8 + (x & 1); + dest = p->screen_base + yy * p->fontheight * p->next_line + + (xx >> 1)*8 + (xx & 1); j = p->fontheight; bytes = p->next_line; @@ -3150,15 +3313,16 @@ int bytes = p->next_line; int lines = height * p->fontheight; ulong size; - u_long cval1, cval2, cval3, cval4, pcval1, pcval2; + u_long cval1, cval2, cval3, cval4, pcval1, pcval2; - expand8ql(attr_bgcol_ec(p,conp), cval1, cval2, cval3, cval4); + expand8ql(attr_bgcol_ec(p,conp), cval1, cval2, cval3, cval4); if (sx == 0 && width == bytes/8) { offset = sy * bytes * p->fontheight; size = lines * bytes; - memset_even_8p(p->screen_base+offset, size, cval1, cval2, cval3, cval4); + memset_even_8p(p->screen_base+offset, size, cval1, + cval2, cval3, cval4); } else { @@ -3193,48 +3357,50 @@ } -static void putc_8_plane(struct vc_data *conp, struct display *p, int c, int y, - int x) +static void putc_8_plane(struct vc_data *conp, struct display *p, int c, int yy, + int xx) { u_char *dest; - u_char *cdat; - int rows; - int bytes = p->next_line; - ulong eorx1, eorx2, fgx1, fgx2, bgx1, bgx2, fdx; + u_char *cdat; + int rows; + int bytes = p->next_line; + ulong eorx1, eorx2, fgx1, fgx2, bgx1, bgx2, fdx; c &= 0xff; - dest = p->screen_base + y * p->fontheight * bytes + (x>>1)*16 + (x & 1); - cdat = p->fontdata + (c * p->fontheight); + dest = p->screen_base + yy * p->fontheight * bytes + + (xx >> 1)*16 + (xx & 1); + cdat = p->fontdata + (c * p->fontheight); expand8dl(attr_fgcol(p,conp), &fgx1, &fgx2); expand8dl(attr_bgcol(p,conp), &bgx1, &bgx2); eorx1 = fgx1 ^ bgx1; eorx2 = fgx2 ^ bgx2; - for(rows = p->fontheight ; rows-- ; dest += bytes) { + for(rows = p->fontheight ; rows-- ; dest += bytes) { fdx = dup4l(*cdat++); __asm__ __volatile__ ("movepl %1,%0@(0)\n\t" - "movepl %2,%0@(8)" - : /* no outputs */ - : "a" (dest), "d" ((fdx & eorx1) ^ bgx1), - "d" ((fdx & eorx2) ^ bgx2) + "movepl %2,%0@(8)" + : /* no outputs */ + : "a" (dest), "d" ((fdx & eorx1) ^ bgx1), + "d" ((fdx & eorx2) ^ bgx2) ); } } static void putcs_8_plane(struct vc_data *conp, struct display *p, - const char *s, int count, int y, int x) + const char *s, int count, int yy, int xx) { u_char *dest, *dest0; - u_char *cdat, c; - int rows; - int bytes; - ulong eorx1, eorx2, fgx1, fgx2, bgx1, bgx2, fdx; - - bytes = p->next_line; - dest0 = p->screen_base + y * p->fontheight * bytes + (x>>1)*16 + (x & 1); + u_char *cdat, c; + int rows; + int bytes; + ulong eorx1, eorx2, fgx1, fgx2, bgx1, bgx2, fdx; + + bytes = p->next_line; + dest0 = p->screen_base + yy * p->fontheight * bytes + + (xx >> 1)*16 + (xx & 1); expand8dl(attr_fgcol(p,conp), &fgx1, &fgx2); expand8dl(attr_bgcol(p,conp), &bgx1, &bgx2); @@ -3267,30 +3433,31 @@ } -static void rev_char_8_plane(struct display *p, int x, int y) +static void rev_char_8_plane(struct display *p, int xx, int yy) { - u_char *dest; - int j; - int bytes; - - dest = p->screen_base + y * p->fontheight * p->next_line + (x>>1)*16 + (x & 1); - j = p->fontheight; - bytes = p->next_line; + u_char *dest; + int j; + int bytes; - while (j--) - { - /* This should really obey the individual character's - * background and foreground colors instead of simply - * inverting. For 8 plane mode, only the lower 4 bits of the - * color are inverted, because only that color registers have - * been set up. - */ - dest[0] = ~dest[0]; - dest[2] = ~dest[2]; - dest[4] = ~dest[4]; - dest[6] = ~dest[6]; - dest += bytes; - } + dest = p->screen_base + yy * p->fontheight * p->next_line + + (xx >> 1)*16 + (xx & 1); + j = p->fontheight; + bytes = p->next_line; + + while (j--) + { + /* This should really obey the individual character's + * background and foreground colors instead of simply + * inverting. For 8 plane mode, only the lower 4 bits of the + * color are inverted, because only that color registers have + * been set up. + */ + dest[0] = ~dest[0]; + dest[2] = ~dest[2]; + dest[4] = ~dest[4]; + dest[6] = ~dest[6]; + dest += bytes; + } } #endif /* CONFIG_FBCON_8PLANE */ @@ -3378,8 +3545,8 @@ } -static void putc_8_packed(struct vc_data *conp, struct display *p, int c, int y, - int x) +static void putc_8_packed(struct vc_data *conp, struct display *p, int c, + int yy, int xx) { u_char *dest,*cdat; int bytes=p->next_line,rows; @@ -3387,7 +3554,7 @@ c &= 0xff; - dest = p->screen_base + y * p->fontheight * bytes + x * 8; + dest = p->screen_base + yy * p->fontheight * bytes + xx * 8; cdat = p->fontdata + c * p->fontheight; fgx=attr_fgcol(p,conp); @@ -3408,13 +3575,13 @@ static void putcs_8_packed(struct vc_data *conp, struct display *p, - const char *s, int count, int y, int x) + const char *s, int count, int yy, int xx) { u_char *cdat, c, *dest, *dest0; int rows,bytes=p->next_line; u_long eorx, fgx, bgx; - dest0 = p->screen_base + y * p->fontheight * bytes + x * 8; + dest0 = p->screen_base + yy * p->fontheight * bytes + xx * 8; fgx=attr_fgcol(p,conp); bgx=attr_bgcol(p,conp); fgx |= (fgx << 8); @@ -3437,12 +3604,12 @@ } -static void rev_char_8_packed(struct display *p, int x, int y) +static void rev_char_8_packed(struct display *p, int xx, int yy) { u_char *dest; int bytes=p->next_line, rows; - dest = p->screen_base + y * p->fontheight * bytes + x * 8; + dest = p->screen_base + yy * p->fontheight * bytes + xx * 8; for (rows = p->fontheight ; rows-- ; dest += bytes) { ((u_long *)dest)[0] ^= 0x0f0f0f0f; ((u_long *)dest)[1] ^= 0x0f0f0f0f; @@ -3539,7 +3706,7 @@ static void putc_16_packed(struct vc_data *conp, struct display *p, int c, - int y, int x) + int yy, int xx) { u_char *dest,*cdat; int bytes=p->next_line,rows; @@ -3547,7 +3714,7 @@ c &= 0xff; - dest = p->screen_base + y * p->fontheight * bytes + x * 16; + dest = p->screen_base + yy * p->fontheight * bytes + xx * 16; cdat = p->fontdata + c * p->fontheight; fgx = attr_fgcol(p,conp); @@ -3573,13 +3740,13 @@ /* TODO */ static void putcs_16_packed(struct vc_data *conp, struct display *p, - const char *s, int count, int y, int x) + const char *s, int count, int yy, int xx) { u_char *cdat, c, *dest, *dest0; int rows,bytes=p->next_line; u_long eorx, fgx, bgx; - dest0 = p->screen_base + y * p->fontheight * bytes + x * 16; + dest0 = p->screen_base + yy * p->fontheight * bytes + xx * 16; fgx = attr_fgcol(p,conp); fgx = packed16_cmap[fgx]; bgx = attr_bgcol(p,conp); @@ -3606,12 +3773,12 @@ } -static void rev_char_16_packed(struct display *p, int x, int y) +static void rev_char_16_packed(struct display *p, int xx, int yy) { u_char *dest; int bytes=p->next_line, rows; - dest = p->screen_base + y * p->fontheight * bytes + x * 16; + dest = p->screen_base + yy * p->fontheight * bytes + xx * 16; for (rows = p->fontheight ; rows-- ; dest += bytes) { ((u_long *)dest)[0] ^= 0xffffffff; ((u_long *)dest)[1] ^= 0xffffffff; @@ -3641,87 +3808,90 @@ } -static void clear_cyber(struct vc_data *conp, struct display *p, int sy, int sx, - int height, int width) +static void clear_cyber(struct vc_data *conp, struct display *p, int + sy, int sx, int height, int width) { - u_char bg; + unsigned char bg; sx *= 8; width *= 8; bg = attr_bgcol_ec(p,conp); - Cyber_RectFill((u_short)sx, (u_short)(sy*p->fontheight), (u_short)width, - (u_short)(height*p->fontheight), (u_short)S3_NEW, - (u_short)bg); + Cyber_RectFill((u_short)sx, + (u_short)(sy*p->fontheight), + (u_short)width, + (u_short)(height*p->fontheight), + (u_short)S3_NEW, + (u_short)bg); } -static void putc_cyber(struct vc_data *conp, struct display *p, int c, int y, - int x) +static void putc_cyber(struct vc_data *conp, struct display *p, int c, int yy, + int xx) { u_char *dest, *cdat; u_long tmp; - u_int rows, reverse, underline; + u_int rows, revs, underl; u_char d; - u_char fg, bg; + u_char fg, bg; - c &= 0xff; + c &= 0xff; dest = p->screen_base+y*p->fontheight*p->next_line+8*x; cdat = p->fontdata+(c*p->fontheight); - fg = disp->fgcol; - bg = disp->bgcol; - reverse = conp->vc_reverse; - underline = conp->vc_underline; + fg = disp->fgcol; + bg = disp->bgcol; + revs = conp->vc_reverse; + underl = conp->vc_underline; Cyber_WaitBlit(); for (rows = p->fontheight; rows--; dest += p->next_line) { d = *cdat++; - if (underline && !rows) + if (underl && !rows) d = 0xff; - if (reverse) + if (revs) d = ~d; - tmp = ((d & 0x80) ? fg : bg) << 24; - tmp |= ((d & 0x40) ? fg : bg) << 16; - tmp |= ((d & 0x20) ? fg : bg) << 8; - tmp |= ((d & 0x10) ? fg : bg); - *((u_long*) dest) = tmp; - tmp = ((d & 0x8) ? fg : bg) << 24; - tmp |= ((d & 0x4) ? fg : bg) << 16; - tmp |= ((d & 0x2) ? fg : bg) << 8; - tmp |= ((d & 0x1) ? fg : bg); - *((u_long*) dest + 1) = tmp; + tmp = ((d & 0x80) ? fg : bg) << 24; + tmp |= ((d & 0x40) ? fg : bg) << 16; + tmp |= ((d & 0x20) ? fg : bg) << 8; + tmp |= ((d & 0x10) ? fg : bg); + *((u_long*) dest) = tmp; + tmp = ((d & 0x8) ? fg : bg) << 24; + tmp |= ((d & 0x4) ? fg : bg) << 16; + tmp |= ((d & 0x2) ? fg : bg) << 8; + tmp |= ((d & 0x1) ? fg : bg); + *((u_long*) dest + 1) = tmp; } } static void putcs_cyber(struct vc_data *conp, struct display *p, const char *s, - int count, int y, int x) + int count, int yy, int xx) { u_char *dest, *dest0, *cdat; - u_long tmp; - u_int rows, reverse, underline; + u_long tmp; + u_int rows, revs, underl; u_char c, d; - u_char fg, bg; + u_char fg, bg; dest0 = p->screen_base+y*p->fontheight*p->next_line+8*x; - fg = disp->fgcol; - bg = disp->bgcol; - reverse = conp->vc_reverse; - underline = conp->vc_underline; + fg = disp->fgcol; + bg = disp->bgcol; + revs = conp->vc_reverse; + underl = conp->vc_underline; Cyber_WaitBlit(); while (count--) { c = *s++; dest = dest0; - dest0 += 8; + dest0 += 8; cdat = p->fontdata+(c*p->fontheight); for (rows = p->fontheight; rows--; dest += p->next_line) { d = *cdat++; - if (underline && !rows) + if (underl && !rows) d = 0xff; - if (reverse) + if (revs) d = ~d; tmp = ((d & 0x80) ? fg : bg) << 24; @@ -3739,32 +3909,208 @@ } -static void rev_char_cyber(struct display *p, int x, int y) +static void rev_char_cyber(struct display *p, int xx, int yy) { - u_char *dest; - u_int rows; - u_char fg, bg; + unsigned char *dest; + unsigned int rows; + unsigned char fg, bg; - fg = disp->fgcol; - bg = disp->bgcol; + fg = disp->fgcol; + bg = disp->bgcol; dest = p->screen_base+y*p->fontheight*p->next_line+8*x; Cyber_WaitBlit(); for (rows = p->fontheight; rows--; dest += p->next_line) { *dest = (*dest == fg) ? bg : fg; - *(dest+1) = (*(dest + 1) == fg) ? bg : fg; - *(dest+2) = (*(dest + 2) == fg) ? bg : fg; - *(dest+3) = (*(dest + 3) == fg) ? bg : fg; - *(dest+4) = (*(dest + 4) == fg) ? bg : fg; - *(dest+5) = (*(dest + 5) == fg) ? bg : fg; - *(dest+6) = (*(dest + 6) == fg) ? bg : fg; - *(dest+7) = (*(dest + 7) == fg) ? bg : fg; + *(dest+1) = (*(dest + 1) == fg) ? bg : fg; + *(dest+2) = (*(dest + 2) == fg) ? bg : fg; + *(dest+3) = (*(dest + 3) == fg) ? bg : fg; + *(dest+4) = (*(dest + 4) == fg) ? bg : fg; + *(dest+5) = (*(dest + 5) == fg) ? bg : fg; + *(dest+6) = (*(dest + 6) == fg) ? bg : fg; + *(dest+7) = (*(dest + 7) == fg) ? bg : fg; } } #endif /* CONFIG_FBCON_CYBER */ +#ifdef CONFIG_FBCON_RETINAZ3 + +/* + * RetinaZ3 (accelerated) + */ + +#define Z3BLTcopy 0xc0 +#define Z3BLTset 0xf0 + +static void clear_retz3(struct vc_data *conp, struct display *p, int + sy, int sx, int height, int width) +{ + unsigned short col; + int fontwidth = p->fontwidth; + + sx *= fontwidth; + width *= fontwidth; + + col = attr_bgcol_ec(p, conp); + col &= 0xff; + col |= (col << 8); + + retz3_bitblt(&p->var, + (unsigned short)sx, + (unsigned short)(sy*p->fontheight), + (unsigned short)sx, + (unsigned short)(sy*p->fontheight), + (unsigned short)width, + (unsigned short)(height*p->fontheight), + Z3BLTset, + col); +} + +static void bmove_retz3(struct display *p, int sy, int sx, int dy, int dx, + int height, int width) +{ + int fontwidth = p->fontwidth; + + sx *= fontwidth; + dx *= fontwidth; + width *= fontwidth; + + retz3_bitblt(&p->var, + (unsigned short)sx, + (unsigned short)(sy*p->fontheight), + (unsigned short)dx, + (unsigned short)(dy*p->fontheight), + (unsigned short)width, + (unsigned short)(height*p->fontheight), + Z3BLTcopy, + 0xffff); +} + +static void putc_retz3(struct vc_data *conp, struct display *p, + int c, int yy, int xx) +{ + unsigned char *dest, *cdat; + unsigned long tmp; + unsigned int rows, revs, underl, bytes; + unsigned char d; + unsigned char fg, bg; + + c &= 0xff; + + bytes = p->next_line; + + dest = p->screen_base + yy*p->fontheight*bytes + + xx*p->var.bits_per_pixel; + cdat = p->fontdata + c * p->fontheight; + + fg = disp->fgcol; + bg = disp->bgcol; + revs = conp->vc_reverse; + underl = conp->vc_underline; + + for (rows = p->fontheight; rows--; dest += bytes) { + d = *cdat++; + + if (underl && !rows) + d = 0xff; + if (revs) + d = ~d; + + tmp = ((d & 0x80) ? fg : bg) << 24; + tmp |= ((d & 0x40) ? fg : bg) << 16; + tmp |= ((d & 0x20) ? fg : bg) << 8; + tmp |= ((d & 0x10) ? fg : bg); + *((unsigned long*) dest) = tmp; + tmp = ((d & 0x8) ? fg : bg) << 24; + tmp |= ((d & 0x4) ? fg : bg) << 16; + tmp |= ((d & 0x2) ? fg : bg) << 8; + tmp |= ((d & 0x1) ? fg : bg); + *((unsigned long*) dest + 1) = tmp; + } +} + + +static void putcs_retz3(struct vc_data *conp, struct display *p, + const char *s, int count, int yy, int xx) +{ + unsigned char *dest, *dest0, *cdat; + unsigned long tmp; + unsigned int rows, revs, underl, bytes; + unsigned char c, d; + unsigned char fg, bg; + + bytes = p->next_line; + + dest0 = p->screen_base + yy*p->fontheight*bytes + + xx * p->var.bits_per_pixel; + fg = disp->fgcol; + bg = disp->bgcol; + revs = conp->vc_reverse; + underl = conp->vc_underline; + + while (count--) { + c = *s++; + dest = dest0; + dest0 += 8; + + cdat = p->fontdata + c * p->fontheight; + for (rows = p->fontheight; rows--; dest += bytes) { + d = *cdat++; + + if (underl && !rows) + d = 0xff; + if (revs) + d = ~d; + + tmp = ((d & 0x80) ? fg : bg) << 24; + tmp |= ((d & 0x40) ? fg : bg) << 16; + tmp |= ((d & 0x20) ? fg : bg) << 8; + tmp |= ((d & 0x10) ? fg : bg); + *((unsigned long*) dest) = tmp; + tmp = ((d & 0x8) ? fg : bg) << 24; + tmp |= ((d & 0x4) ? fg : bg) << 16; + tmp |= ((d & 0x2) ? fg : bg) << 8; + tmp |= ((d & 0x1) ? fg : bg); + *((unsigned long*) dest + 1) = tmp; + } + } +} + +static void rev_char_retz3(struct display *p, int xx, int yy) +{ + unsigned char *dest; + int bytes=p->next_line, rows; + unsigned int bpp, mask; + + bpp = p->var.bits_per_pixel; + + switch (bpp){ + case 8: + mask = 0x0f0f0f0f; + break; + case 16: + mask = 0xffffffff; + break; + case 24: + mask = 0xffffffff; /* ??? */ + break; + default: + printk("illegal depth for rev_char_retz3(), bpp = %i\n", bpp); + return; + } + + dest = p->screen_base + yy * p->fontheight * bytes + xx * bpp; + + for (rows = p->fontheight ; rows-- ; dest += bytes) { + ((unsigned long *)dest)[0] ^= mask; + ((unsigned long *)dest)[1] ^= mask; + } +} + +#endif + /* ====================================================================== */ /* @@ -3774,5 +4120,5 @@ struct consw fb_con = { fbcon_startup, fbcon_init, fbcon_deinit, fbcon_clear, fbcon_putc, fbcon_putcs, fbcon_cursor, fbcon_scroll, fbcon_bmove, fbcon_switch, - fbcon_blank, fbcon_get_font, fbcon_set_font + fbcon_blank, fbcon_get_font, fbcon_set_font, fbcon_set_palette }; diff -u --recursive v2.1.35/linux/arch/m68k/console/txtcon.c linux/arch/m68k/console/txtcon.c --- v2.1.35/linux/arch/m68k/console/txtcon.c Sun May 19 21:54:26 1996 +++ linux/arch/m68k/console/txtcon.c Thu Apr 17 13:20:42 1997 @@ -22,7 +22,7 @@ * Interface used by the world */ -static u_long txtcon_startup(u_long kmem_start, char **display_desc); +static u_long txtcon_startup(u_long kmem_start, const char **display_desc); static void txtcon_init(struct vc_data *conp); static int txtcon_deinit(struct vc_data *conp); static int txtcon_clear(struct vc_data *conp, int sy, int sx, int height, @@ -36,10 +36,12 @@ int height, int width); static int txtcon_switch(struct vc_data *conp); static int txtcon_blank(int blank); +static int txtcon_get_font(struct vc_data *conp, int *w, int *h, char *data); +static int txtcon_set_font(struct vc_data *conp, int w, int h, char *data); +static int txtcon_set_palette(struct vc_data *conp, unsigned char *table); - -static u_long txtcon_startup(u_long kmem_start, char **display_desc) +static u_long txtcon_startup(u_long kmem_start, const char **display_desc) { *display_desc = "Not yet implemented"; return(kmem_start); @@ -113,6 +115,24 @@ } +static int txtcon_get_font(struct vc_data *conp, int *w, int *h, char *data) +{ + return(0); +} + + +static int txtcon_set_font(struct vc_data *conp, int w, int h, char *data) +{ + return(0); +} + + +static int txtcon_set_palette(struct vc_data *conp, unsigned char *table) +{ + return(0); +} + + /* ====================================================================== */ /* @@ -122,6 +142,6 @@ struct consw txt_con = { txtcon_startup, txtcon_init, txtcon_deinit, txtcon_clear, txtcon_putc, txtcon_putcs, txtcon_cursor, txtcon_scroll, txtcon_bmove, txtcon_switch, - txtcon_blank + txtcon_blank, txtcon_get_font, txtcon_set_font, txtcon_set_palette }; diff -u --recursive v2.1.35/linux/arch/m68k/defconfig linux/arch/m68k/defconfig --- v2.1.35/linux/arch/m68k/defconfig Mon Apr 7 11:35:29 1997 +++ linux/arch/m68k/defconfig Thu Apr 17 13:20:42 1997 @@ -46,6 +46,7 @@ CONFIG_AMIFB_ECS=y CONFIG_AMIFB_AGA=y # CONFIG_FB_CYBER is not set +# CONFIG_FB_RETINAZ3 is not set # CONFIG_AMIGA_GSP is not set # CONFIG_GSP_RESOLVER is not set # CONFIG_GSP_A2410 is not set @@ -79,9 +80,10 @@ # CONFIG_FIREWALL is not set # CONFIG_NET_ALIAS is not set CONFIG_INET=y -# CONFIG_IP_FORWARD is not set # CONFIG_IP_MULTICAST is not set # CONFIG_IP_ACCT is not set +# CONFIG_IP_ROUTER is not set +# CONFIG_NET_IPIP is not set # # (it is safe to leave these untouched) @@ -123,18 +125,19 @@ # SCSI low-level drivers # CONFIG_A3000_SCSI=y -# CONFIG_A2091_SCSI is not set -# CONFIG_GVP11_SCSI is not set +CONFIG_A2091_SCSI=y +CONFIG_GVP11_SCSI=y # CONFIG_CYBERSTORM_SCSI is not set # CONFIG_CYBERSTORMII_SCSI is not set # CONFIG_BLZ2060_SCSI is not set # CONFIG_BLZ1230_SCSI is not set +# CONFIG_FASTLANE_SCSI is not set CONFIG_ATARI_SCSI=y # # Network device support # -# CONFIG_NETDEVICES is not set +CONFIG_NETDEVICES=y # CONFIG_DUMMY is not set # CONFIG_SLIP is not set # CONFIG_PPP is not set @@ -164,6 +167,7 @@ # CONFIG_HPFS_FS is not set # CONFIG_SYSV_FS is not set # CONFIG_AFFS_FS is not set +# CONFIG_ROMFS_FS is not set # CONFIG_UFS_FS is not set # @@ -176,6 +180,8 @@ CONFIG_ATARIMOUSE=y CONFIG_AMIGA_BUILTIN_SERIAL=y # CONFIG_GVPIOEXT is not set +# CONFIG_GVPIOEXT_LP is not set +# CONFIG_GVPIOEXT_PLIP is not set # CONFIG_MULTIFACE_III_TTY is not set # CONFIG_USERIAL is not set # CONFIG_WATCHDOG is not set diff -u --recursive v2.1.35/linux/arch/m68k/fpsp040/skeleton.S linux/arch/m68k/fpsp040/skeleton.S --- v2.1.35/linux/arch/m68k/fpsp040/skeleton.S Wed Sep 25 00:47:39 1996 +++ linux/arch/m68k/fpsp040/skeleton.S Thu Apr 17 13:20:42 1997 @@ -513,9 +513,12 @@ movel 12(%sp),%d0 | count subl #1,%d0 | dec count by 1 for dbra movel #1,%d1 - movec %d1,%DFC | set dfc for user data space + +| DFC is already set +| movec %d1,%DFC | set dfc for user data space moreout: moveb (%a0)+,%d1 | fetch supervisor byte +out_ea: movesb %d1,(%a1)+ | write user byte dbf %d0,moreout rts @@ -526,11 +529,24 @@ movel 12(%sp),%d0 | count subl #1,%d0 | dec count by 1 for dbra movel #1,%d1 - movec %d1,%SFC | set sfc for user space +| SFC is already set +| movec %d1,%SFC | set sfc for user space morein: +in_ea: movesb (%a0)+,%d1 | fetch user byte moveb %d1,(%a1)+ | write supervisor byte dbf %d0,morein rts + + .section .fixup,#alloc,#execinstr + .even +1: + jbra SYMBOL_NAME(fpsp040_die) + + .section __ex_table,#alloc + .align 4 + + .long in_ea,1b + .long out_ea,1b |end diff -u --recursive v2.1.35/linux/arch/m68k/ifpsp060/os.S linux/arch/m68k/ifpsp060/os.S --- v2.1.35/linux/arch/m68k/ifpsp060/os.S Wed Sep 25 00:47:39 1996 +++ linux/arch/m68k/ifpsp060/os.S Thu Apr 17 13:20:42 1997 @@ -153,7 +153,7 @@ btst #0x5,0x4(%a6) | check for supervisor state bnes dmrbs | supervisor dmrbu: clr.l %d0 | clear whole longword - movs.b (%a0),%d0 | fetch user byte +dmrbuae:movs.b (%a0),%d0 | fetch user byte bras dmrbr dmrbs: clr.l %d0 | clear whole longword move.b (%a0),%d0 | fetch super byte @@ -190,7 +190,7 @@ btst #0x5,0x4(%a6) | check for supervisor state bnes dmrws | supervisor dmrwu: clr.l %d0 | clear whole longword - movs.w (%a0), %d0 | fetch user word +dmrwuae:movs.w (%a0), %d0 | fetch user word bras dmrwr dmrws: clr.l %d0 | clear whole longword move.w (%a0), %d0 | fetch super word @@ -226,7 +226,8 @@ _060_imem_read_long: btst #0x5,0x4(%a6) | check for supervisor state bnes dmrls | supervisor -dmrlu: movs.l (%a0),%d0 | fetch user longword +dmrlu: +dmrluae:movs.l (%a0),%d0 | fetch user longword bras dmrlr dmrls: move.l (%a0),%d0 | fetch super longword dmrlr: clr.l %d1 | return success @@ -248,7 +249,8 @@ _060_dmem_write_byte: btst #0x5,0x4(%a6) | check for supervisor state bnes dmwbs | supervisor -dmwbu: movs.b %d0,(%a0) | store user byte +dmwbu: +dmwbuae:movs.b %d0,(%a0) | store user byte bras dmwbr dmwbs: move.b %d0,(%a0) | store super byte dmwbr: clr.l %d1 | return success @@ -270,7 +272,8 @@ _060_dmem_write_word: btst #0x5,0x4(%a6) | check for supervisor state bnes dmwws | supervisor -dmwwu: movs.w %d0,(%a0) | store user word +dmwwu: +dmwwuae:movs.w %d0,(%a0) | store user word bras dmwwr dmwws: move.w %d0,(%a0) | store super word dmwwr: clr.l %d1 | return success @@ -292,7 +295,8 @@ _060_dmem_write_long: btst #0x5,0x4(%a6) | check for supervisor state bnes dmwls | supervisor -dmwlu: movs.l %d0,(%a0) | store user longword +dmwlu: +dmwluae:movs.l %d0,(%a0) | store user longword bra dmwlr dmwls: move.l %d0,(%a0) | store super longword dmwlr: clr.l %d1 | return success @@ -322,9 +326,10 @@ subq.l #1,%d0 moreout: move.b (%a0)+,%d1 | fetch supervisor byte +copyoutae: movs.b %d1,(%a1)+ | store user byte dbra %d0,moreout | are we through yet? - moveq #0,%d0 | return success + moveq #0,%d0 | return success rts | @@ -337,11 +342,12 @@ move.l 12(%sp),%d0 | count subq.l #1,%d0 morein: +copyinae: movs.b (%a0)+,%d1 | fetch user byte move.b %d1,(%a1)+ | write supervisor byte subq.l #0x1,%d0 | are we through yet? dbra %d0,morein | are we through yet? - moveq #0,%d0 | return success + moveq #0,%d0 | return success rts |########################################################################### @@ -374,3 +380,22 @@ .global _060_real_access _060_real_access: bral SYMBOL_NAME(buserr) + + + +| Execption handling for movs access to illegal memory + .section .fixup,#alloc,#execinstr + .even +1: moveq #-1,%d1 + rts +.section __ex_table,#alloc + .align 4 + .long dmrbuae,1b + .long dmrwuae,1b + .long dmrluae,1b + .long dmwbuae,1b + .long dmwwuae,1b + .long dmwluae,1b + .long copyoutae,1b + .long copyinae,1b + .text diff -u --recursive v2.1.35/linux/arch/m68k/kernel/Makefile linux/arch/m68k/kernel/Makefile --- v2.1.35/linux/arch/m68k/kernel/Makefile Fri Apr 4 08:52:17 1997 +++ linux/arch/m68k/kernel/Makefile Thu Apr 17 13:20:42 1997 @@ -19,6 +19,10 @@ endif OX_OBJS := m68k_ksyms.o +ifdef CONFIG_KGDB +O_OBJS += kgdb.o +endif + head.o: head.S include $(TOPDIR)/Rules.make diff -u --recursive v2.1.35/linux/arch/m68k/kernel/console.c linux/arch/m68k/kernel/console.c --- v2.1.35/linux/arch/m68k/kernel/console.c Fri Apr 4 08:52:17 1997 +++ linux/arch/m68k/kernel/console.c Thu Apr 17 13:20:42 1997 @@ -20,7 +20,7 @@ * 'unsigned long con_init(unsigned long)' * 'int con_open(struct tty_struct *tty, struct file * filp)' * 'void con_write(struct tty_struct * tty)' - * 'void console_print(const char * b)' + * 'void vt_console_print(const char * b)' * 'void update_screen(int new_console)' * * 'void do_blank_screen(int)' @@ -103,11 +103,13 @@ * interrupt, as we use trap-gates. Hopefully all is well. */ +#include #include #include #include #include #include +#include #include #include #include @@ -127,6 +129,7 @@ #include "../../../drivers/char/vt_kern.h" #include "../../../drivers/char/consolemap.h" #include "../../../drivers/char/selection.h" +#include "../../../drivers/char/console_struct.h" #ifndef MIN @@ -146,12 +149,13 @@ static void save_cur(int currcons); static void blank_screen(void); static void unblank_screen(void); +static int con_open(struct tty_struct *, struct file *); extern void change_console(unsigned int); static inline void set_cursor(int currcons); static void reset_terminal(int currcons, int do_clear); extern void reset_vc(unsigned int new_console); extern void vt_init(void); -extern void register_console(void (*proc)(const char *)); +static void set_vesa_blanking(unsigned long arg); extern void vesa_blank(void); extern void vesa_unblank(void); extern void compute_shiftstate(void); @@ -170,6 +174,7 @@ static unsigned short console_charmask = 0x0ff; static unsigned short *vc_scrbuf[MAX_NR_CONSOLES]; +struct vc vc_cons [MAX_NR_CONSOLES]; /* used by kbd_bh - set by keyboard_interrupt */ int do_poke_blanked_console = 0; @@ -189,13 +194,6 @@ int want_console = -1; int kmsg_redirect = 0; -static struct vc { - struct vc_data *d; - - /* might add scrmem, vt_struct, kbd at some time, - to have everything in one place - the disadvantage - would be that vc_cons etc can no longer be static */ -} vc_cons [MAX_NR_CONSOLES]; struct consw *conswitchp; #define cols (vc_cons[currcons].d->vc_cols) @@ -270,8 +268,6 @@ #define vtnewvt (vt_cons[currcons]->vt_newvt) #endif -#define structsize (sizeof(struct vc_data) + sizeof(struct vt_struct)) - int vc_cons_allocated(unsigned int i) { return (i < MAX_NR_CONSOLES && vc_cons[i].d); @@ -621,8 +617,7 @@ return; } -static void scrup(int currcons, unsigned int t, unsigned int b, - int nr) +static void scrup(int currcons, unsigned int t, unsigned int b, int nr) { unsigned short *p; int i; @@ -636,10 +631,10 @@ p = video_mem_start + (b - nr) * cols; for (i = nr * cols; i > 0; i--) - *p++ = video_erase_char; + *p++ = video_erase_char; if (currcons != fg_console) - return; + return; /* * Arno: * Scrolling has now been moved to amicon.c where it should have @@ -812,8 +807,8 @@ if (!vpar) vpar++; - start=pos; - count=(vpar > cols-x) ? (cols-x) : vpar; + start = pos; + count = (vpar > cols-x) ? (cols-x) : vpar; if (currcons == fg_console) sw->con_clear(vc_cons[currcons].d,y,x,1,count); @@ -1008,7 +1003,7 @@ respond_string(buf, tty); } -/* invoked via ioctl(TIOCLINUX) */ +/* invoked via ioctl(TIOCLINUX) and through set_selection */ int mouse_reporting(void) { int currcons = fg_console; @@ -1309,12 +1304,12 @@ unsigned short *p = pos; for (i = cols - x - 2; i >= 0; i--) - p[i + 1] = p[i]; + p[i + 1] = p[i]; *pos = video_erase_char; need_wrap = 0; if (currcons != fg_console) - return; + return; /* Arno: * Move the remainder of the line (-1 character) one spot to the right @@ -1338,19 +1333,19 @@ p = pos + cols - x - nr; while (--p >= pos) - p[nr] = *p; + p[nr] = *p; for (i = 0; i < nr; i++) - *++p = video_erase_char; + *++p = video_erase_char; need_wrap = 0; if (currcons != fg_console) - return; + return; sw->con_bmove (vc_cons[currcons].d, y, x, y, x + nr, 1, cols - x - nr); while (nr--) - sw->con_putc (vc_cons[currcons].d, video_erase_char & 0x00ff, - y, x + nr); + sw->con_putc (vc_cons[currcons].d, + video_erase_char & 0x00ff, y, x + nr); } static void csi_L(int currcons, unsigned int nr) @@ -1645,9 +1640,9 @@ */ /* Only use this for the foreground console, - where we really draw the chars */ + where we really draw the chars */ - if (count > 2 && + if (count > 2 && !decim && !utf && currcons == fg_console) { static char putcs_buf[256]; char *p = putcs_buf; @@ -1660,13 +1655,11 @@ if (nextx == cols) { sw->con_putc(vc_cons[currcons].d, *putcs_buf, y, x); - pos--; + ((unsigned short *)pos)--; need_wrap = decawm; continue; } - /* TAB TAB TAB - Arghh!!!! */ - while (count) { enable_bh(CONSOLE_BH); @@ -2129,12 +2122,13 @@ /* DPC: New version of console_print using putcs */ -void console_print(const char * b) +#ifdef CONFIG_VT_CONSOLE +void vt_console_print(const char * b, unsigned int count) { int currcons = fg_console; unsigned char c; const char *start = b; - ushort count = 0; + ushort cnt = 0; ushort myx = x; static int printing = 0; @@ -2147,7 +2141,7 @@ if (!vc_cons_allocated(currcons)) { /* impossible */ - printk("console_print: tty %d not allocated ??\n", currcons+1); + printk("vt_console_print: tty %d not allocated ??\n", currcons+1); printing = 0; return; } @@ -2157,52 +2151,51 @@ /* Contrived structure to try to emulate original need_wrap behaviour * Problems caused when we have need_wrap set on '\n' character */ - - while ((c = *(b++)) != 0) { - if (c == 10 || c == 13 || c == 8 || need_wrap) { - if ((count = b - start - 1) > 0) { - sw->con_putcs(vc_cons[currcons].d, start, count , - y, x); - x += count; - if (need_wrap) - x--; - } - - if (c == 8) { /* backspace */ - bs(currcons); - start = b; - myx = x; - continue; + + while (count-- > 0) { + c = *(b++); + if (c == 10 || c == 13 || c == 8 || need_wrap) { + if ((cnt = b - start - 1) > 0) { + sw->con_putcs(vc_cons[currcons].d, + start, cnt, y, x); + x += cnt; + if (need_wrap) + x--; + } + + if (c == 8) { /* backspace */ + bs(currcons); + start = b; + myx = x; + continue; + } + if (c != 13) + lf(currcons); + cr(currcons); + + if (c == 10 || c == 13) { + start = b; myx = x; continue; + } + + start = b-1; myx = x; } - if (c != 13) - lf(currcons); - cr(currcons); - - if (c == 10 || c == 13) { - start = b; myx = x; continue; - } - - start = b-1; myx = x; - } - - *pos = c | (attr << 8); - if (myx == cols - 1) { - need_wrap = 1; - continue; - } - pos++; - myx++; + + *pos = c | (attr << 8); + if (myx == cols - 1) { + need_wrap = 1; + continue; + } + pos++; + myx++; } - if ((count = b - start -1) > 0) { - sw->con_putcs(vc_cons[currcons].d, start, count , - y, x); - x += count; - if (x == cols) - { - x--; - need_wrap = 1; - } + if ((cnt = b - start) > 0) { + sw->con_putcs(vc_cons[currcons].d, start, cnt, y, x); + x += cnt; + if (x == cols){ + x--; + need_wrap = 1; + } } set_cursor(currcons); @@ -2210,6 +2203,18 @@ printing = 0; } +static int vt_console_device(void) +{ + return MKDEV(TTY_MAJOR, fg_console + 1); +} + +extern void keyboard_wait_for_keypress(void); + +struct console vt_console_driver = { + vt_console_print, do_unblank_screen, + keyboard_wait_for_keypress, vt_console_device +}; +#endif /* * con_throttle and con_unthrottle are only used for @@ -2280,7 +2285,7 @@ */ unsigned long con_init(unsigned long kmem_start) { - char *display_desc = "????"; + const char *display_desc = "????"; unsigned int currcons = 0; extern int serial_debug; @@ -2354,14 +2359,15 @@ printable = 1; /* If "serdebug" cmd line option was present, don't register for printk */ +#ifdef CONFIG_VT_CONSOLE if (!serial_debug) - register_console(console_print); + register_console(&vt_console_driver); printk("Console: %s %s %ldx%ld, %d virtual console%s (max %d)\n", can_do_color ? "colour":"mono", display_desc, cols,rows, MIN_NR_CONSOLES, (MIN_NR_CONSOLES == 1) ? "" : "s", MAX_NR_CONSOLES); - +#endif init_bh(CONSOLE_BH, console_bh); return kmem_start; } @@ -2527,7 +2533,7 @@ /* * Allocate the console screen memory. */ -int con_open(struct tty_struct *tty, struct file * filp) +static int con_open(struct tty_struct *tty, struct file * filp) { unsigned int currcons; int i; @@ -2664,7 +2670,7 @@ return -EINVAL; } -void set_vesa_blanking(int arg) +static void set_vesa_blanking(unsigned long arg) { char *argp = (char *)arg + 1; unsigned int mode; diff -u --recursive v2.1.35/linux/arch/m68k/kernel/entry.S linux/arch/m68k/kernel/entry.S --- v2.1.35/linux/arch/m68k/kernel/entry.S Fri Dec 20 01:19:58 1996 +++ linux/arch/m68k/kernel/entry.S Thu Apr 17 13:20:42 1997 @@ -52,6 +52,10 @@ #include #include #include +#ifdef CONFIG_KGDB +#include +.globl SYMBOL_NAME(kgdb_registers) +#endif LENOSYS = 38 @@ -66,7 +70,7 @@ LTASK_FLAGS = 20 /* the following macro is used when enabling interrupts */ -#if defined(CONFIG_ATARI_ONLY) +#if defined(MACH_ATARI_ONLY) /* block out HSYNC on the atari */ #define ALLOWINT 0xfbff #define MAX_NOINT_IPL 3 @@ -87,11 +91,23 @@ * regs are a2-a6 and d6-d7 preserved by C code * the kernel doesn't mess with usp unless it needs to */ +#ifndef CONFIG_KGDB #define SAVE_ALL \ clrl %sp@-; /* stk_adj */ \ movel %d0,%sp@-; /* orig d0 */ \ movel %d0,%sp@-; /* d0 */ \ moveml %d1-%d5/%a0-%a1,%sp@- +#else +/* Need to save the "missing" registers for kgdb... + */ +#define SAVE_ALL \ + clrl %sp@-; /* stk_adj */ \ + movel %d0,%sp@-; /* orig d0 */ \ + movel %d0,%sp@-; /* d0 */ \ + moveml %d1-%d5/%a0-%a1,%sp@-; \ + moveml %d6-%d7,SYMBOL_NAME(kgdb_registers)+GDBOFFA_D6; \ + moveml %a2-%a6,SYMBOL_NAME(kgdb_registers)+GDBOFFA_A2 +#endif #define RESTORE_ALL \ moveml %sp@+,%a0-%a1/%d1-%d5; \ @@ -244,7 +260,7 @@ movel %d0,%sp@(LORIG_D0) | a -1 in the ORIG_D0 field | signifies that the stack frame | is NOT for syscall - addql #1,SYMBOL_NAME(intr_count) + addql #1,SYMBOL_NAME(local_irq_count) | put exception # in d0 bfextu %sp@(LFORMATVEC){#4,#10},%d0 @@ -255,27 +271,26 @@ SYMBOL_NAME_LABEL(ret_from_interrupt) /* check if we need to do software interrupts */ -1: - movel SYMBOL_NAME(intr_count),%d1 + movel SYMBOL_NAME(local_irq_count),%d1 subql #1,%d1 jne 4f - bfextu %sp@(LSR){#5,#3},%d0 | Check for nested interrupt. +#if 0 + bfextu %sp@(LSR){#5,#3},%d0 | Check for nested interrupt. #if MAX_NOINT_IPL > 0 cmpiw #MAX_NOINT_IPL,%d0 #endif jhi 4f -2: +#endif movel SYMBOL_NAME(bh_active),%d0 andl SYMBOL_NAME(bh_mask),%d0 - jne 3f + jeq 3f - clrl SYMBOL_NAME(intr_count) | deliver signals, reschedule etc.. - jra SYMBOL_NAME(ret_from_exception) -3: jbsr SYMBOL_NAME(do_bottom_half) - jbra 2b +3: + clrl SYMBOL_NAME(local_irq_count) + jra SYMBOL_NAME(ret_from_exception) 4: - movel %d1,SYMBOL_NAME(intr_count) + movel %d1,SYMBOL_NAME(local_irq_count) RESTORE_ALL @@ -339,8 +354,10 @@ /* save sr */ movew %sr,%a0@(LTSS_SR) +#if 0 /* disable interrupts */ oriw #0x0700,%sr +#endif /* save fs (sfc,%dfc) (may be pointing to kernel memory) */ movec %sfc,%d0 @@ -361,18 +378,18 @@ fsave %a0@(LTSS_FPCTXT+27*4) #if defined(CONFIG_M68060) -#if !defined(CONFIG_M68060_ONLY) +#if !defined(CPU_M68060_ONLY) btst #3,SYMBOL_NAME(m68k_cputype)+3 beqs 1f #endif /* The 060 FPU keeps status in bits 15-8 of the first longword */ tstb %a0@(LTSS_FPCTXT+27*4+2) jeq 3f -#if !defined(CONFIG_M68060_ONLY) +#if !defined(CPU_M68060_ONLY) jra 2f #endif #endif /* CONFIG_M68060 */ -#if !defined(CONFIG_M68060_ONLY) +#if !defined(CPU_M68060_ONLY) 1: tstb %a0@(LTSS_FPCTXT+27*4) jeq 3f #endif @@ -388,12 +405,12 @@ tstb %d2 jne 4f -#if defined(CONFIG_M68020_OR_M68030) && defined(CONFIG_M68040_OR_M68060) +#if defined(CPU_M68020_OR_M68030) && defined(CPU_M68040_OR_M68060) /* 68040 or 68060 ? */ tstl SYMBOL_NAME(m68k_is040or060) bnes 1f #endif -#if defined(CONFIG_M68020_OR_M68030) +#if defined(CPU_M68020_OR_M68030) /* * switch address space */ @@ -407,11 +424,11 @@ pmove %a1@(LTSS_CRP),%crp #endif -#if defined(CONFIG_M68020_OR_M68030) && defined(CONFIG_M68040_OR_M68060) +#if defined(CPU_M68020_OR_M68030) && defined(CPU_M68040_OR_M68060) jra 2f /* skip m68040 stuff */ 1: #endif -#if defined(CONFIG_M68040_OR_M68060) +#if defined(CPU_M68040_OR_M68060) /* * switch address space */ @@ -434,24 +451,24 @@ movec %d0,%cacr #endif /* CONFIG_M68060 */ .chip 68k -#endif /* CONFIG_M68040_OR_M68060 */ +#endif /* CPU_M68040_OR_M68060 */ 2: 4: /* restore floating point context */ #if defined(CONFIG_M68060) -#if !defined(CONFIG_M68060_ONLY) +#if !defined(CPU_M68060_ONLY) btst #3,SYMBOL_NAME(m68k_cputype)+3 beqs 1f #endif /* The 060 FPU keeps status in bits 15-8 of the first longword */ tstb %a1@(LTSS_FPCTXT+27*4+2) jeq 3f -#if !defined(CONFIG_M68060_ONLY) +#if !defined(CPU_M68060_ONLY) jra 2f #endif #endif /* CONFIG_M68060 */ -#if !defined(CONFIG_M68060_ONLY) +#if !defined(CPU_M68060_ONLY) 1: tstb %a1@(LTSS_FPCTXT+27*4) jeq 3f #endif @@ -647,8 +664,11 @@ .long SYMBOL_NAME(sys_nanosleep) .long SYMBOL_NAME(sys_mremap) .long SYMBOL_NAME(sys_setresuid) - .long SYMBOL_NAME(sys_getresuid) + .long SYMBOL_NAME(sys_getresuid) /* 165 */ .long SYMBOL_NAME(sys_ni_syscall) /* for vm86 */ + .long SYMBOL_NAME(sys_query_module) + .long SYMBOL_NAME(sys_poll) + .long SYMBOL_NAME(sys_ni_syscall) /* will be sys_nfsservctl */ .rept NR_syscalls-(.-SYMBOL_NAME(sys_call_table))/4 .long SYMBOL_NAME(sys_ni_syscall) .endr diff -u --recursive v2.1.35/linux/arch/m68k/kernel/head.S linux/arch/m68k/kernel/head.S --- v2.1.35/linux/arch/m68k/kernel/head.S Fri Dec 20 01:19:58 1996 +++ linux/arch/m68k/kernel/head.S Thu Apr 17 13:20:42 1997 @@ -73,6 +73,7 @@ .globl SYMBOL_NAME(kernel_pg_dir), SYMBOL_NAME(kpt) .globl SYMBOL_NAME(availmem), SYMBOL_NAME(is_medusa) +.globl SYMBOL_NAME(is_hades) .globl SYMBOL_NAME(m68k_pgtable_cachemode) .globl SYMBOL_NAME(kernel_pmd_table), SYMBOL_NAME(swapper_pg_dir) @@ -235,8 +236,58 @@ #endif /* + If running on an Atari, determine the I/O base of the + serial port and test if we are running on a Medusa or Hades. + This test is necessary here, because on the Hades the serial + port is only accessible in the high I/O memory area. + + The test whether it is a Medusa is done by writing to the byte at + phys. 0x0. This should result in a bus error on all other machines. + + ...should, but doesn't. The Afterburner040 for the Falcon has the + same behaviour (0x0..0x7 are no ROM shadow). So we have to do + another test to distinguish Medusa and AB040. This is a + read attempt for 0x00ff82fe phys. that should bus error on a Falcon + (+AB040), but is in the range where the Medusa always asserts DTACK. + + The test for the Hades is done by reading address 0xb0000000. This + should give a bus error on the Medusa. + */ + +#ifdef CONFIG_ATARI + is_not_atari(Lnotypetest) + + moveq #0,%d3 /* base addr for others: 0x00000000 */ + moveq #0,%d2 /* no Hades */ + movec %d3,%vbr + lea %pc@(Ltest_berr),%a0 + movel %a0,0x8 + movel %sp,%a0 + moveb 0x0,%d1 + clrb 0x0 + nop + moveb %d1,0x0 + nop + tstb 0x00ff82fe + nop + movel #0xff000000,%d3 /* Medusa base addr: 0xff000000 */ + tstb 0xb0000000 + nop + movel #0xff000000,%d2 /* Computer is a Hades */ + moveq #0,%d3 +Ltest_berr: + movel %a0,%sp + lea %pc@(SYMBOL_NAME(is_hades)),%a0 + movel %d2,%a0@ + lea %pc@(SYMBOL_NAME(is_medusa)),%a0 + movel %d3,%a0@ +Lnotypetest: +#endif + +/* * Initialize serial port */ + jbsr Lserial_init putr() @@ -491,35 +542,16 @@ For the Medusa it is better to map the I/O region transparently (i.e. 0xffxxxxxx -> 0xffxxxxxx), because some I/O registers are - accessible only in the high area. The test whether it is a Medusa - is done by writing to the byte at phys. 0x0. This should result - in a bus error on all other machines. + accessible only in the high area. - ...should, but doesn't. The Afterburner040 for the Falcon has the - same behaviour (0x0..0x7 are no ROM shadow). So we have to do - another test to distinguish Medusa and AB040. This is a - read attempt for 0x00ff82fe phys. that should bus error on a Falcon - (+AB040), but is in the range where the Medusa always asserts DTACK. + On the Hades all I/O registers are only accessible in the high + area. */ - moveq #0,%d3 /* base addr for others: 0x00000000 */ - movec %d3,%vbr - lea %pc@(Ltest_berr),%a0 - movel %a0,0x8 - movel %sp,%a0 - moveb 0x0,%d1 - clrb 0x0 - nop - moveb %d1,0x0 - nop - tstb 0x00ff82fe - nop - movel #0xff000000,%d3 /* Medusa base addr: 0xff000000 */ -Ltest_berr: - movel %a0,%sp - lea %pc@(SYMBOL_NAME(is_medusa)),%a0 - movel %d3,%a0@ - + movel %pc@(is_medusa),%d3 + bne 1f + movel %pc@(is_hades),%d3 +1: /* Let the root table point to the new pointer table */ lea %a4@(PTR_TABLE_SIZE<<2),%a4 movel %a4,%a0 @@ -979,19 +1011,20 @@ #ifdef CONFIG_ATARI cmpil #MACH_ATARI,%d4 jne 4f + movel %pc@(Liobase),%a1 #ifdef USE_PRINTER - bclr #0,LSTMFP_IERB - bclr #0,LSTMFP_DDR - moveb #LPSG_CONTROL,LPSG_SELECT - moveb #0xff,LPSG_WRITE - moveb #LPSG_IO_B,LPSG_SELECT - clrb LPSG_WRITE - moveb #LPSG_IO_A,LPSG_SELECT - moveb LPSG_READ,%d0 + bclr #0,%a1@(LSTMFP_IERB) + bclr #0,%a1@(LSTMFP_DDR) + moveb #LPSG_CONTROL,%a1@(LPSG_SELECT) + moveb #0xff,%a1@(LPSG_WRITE) + moveb #LPSG_IO_B,%a1@(LPSG_SELECT) + clrb %a1@(LPSG_WRITE) + moveb #LPSG_IO_A,%a1@(LPSG_SELECT) + moveb %a1@(LPSG_READ),%d0 bset #5,%d0 - moveb %d0,LPSG_WRITE + moveb %d0,%a1@(LPSG_WRITE) #elif defined(USE_SCC) - lea LSCC_CTRL_B,%a0 + lea %a1@(LSCC_CTRL_B),%a0 lea %pc@(scc_initable:w),%a1 2: moveb %a1@+,%d0 jmi 3f @@ -1000,12 +1033,12 @@ jra 2b 3: clrb %a0@ #elif defined(USE_MFP) - bclr #1,LMFP_TSR - moveb #0x88,LMFP_UCR - andb #0x70,LMFP_TDCDR - moveb #2,LMFP_TDDR - orb #1,LMFP_TDCDR - bset #1,LMFP_TSR + bclr #1,%a1@(LMFP_TSR) + moveb #0x88,%a1@(LMFP_UCR) + andb #0x70,%a1@(LMFP_TDCDR) + moveb #2,%a1@(LMFP_TDDR) + orb #1,%a1@(LMFP_TDCDR) + bset #1,%a1@(LMFP_TSR) #endif 4: #endif @@ -1140,6 +1173,8 @@ SYMBOL_NAME_LABEL(availmem) .long 0 SYMBOL_NAME_LABEL(is_medusa) + .long 0 +SYMBOL_NAME_LABEL(is_hades) .long 0 SYMBOL_NAME_LABEL(m68k_pgtable_cachemode) .long 0 diff -u --recursive v2.1.35/linux/arch/m68k/kernel/ints.c linux/arch/m68k/kernel/ints.c --- v2.1.35/linux/arch/m68k/kernel/ints.c Wed Sep 25 00:47:39 1996 +++ linux/arch/m68k/kernel/ints.c Thu Apr 17 13:20:42 1997 @@ -50,6 +50,24 @@ #define NUM_IRQ_NODES 100 static irq_node_t nodes[NUM_IRQ_NODES]; +unsigned int local_irq_count[NR_CPUS]; + +int __m68k_bh_counter; + +static void dummy_enable_irq(unsigned int irq); +static void dummy_disable_irq(unsigned int irq); +static int dummy_request_irq(unsigned int irq, + void (*handler) (int, void *, struct pt_regs *), + unsigned long flags, const char *devname, void *dev_id); +static void dummy_free_irq(unsigned int irq, void *dev_id); + +void (*enable_irq) (unsigned int) = dummy_enable_irq; +void (*disable_irq) (unsigned int) = dummy_disable_irq; + +int (*mach_request_irq) (unsigned int, void (*)(int, void *, struct pt_regs *), + unsigned long, const char *, void *) = dummy_request_irq; +void (*mach_free_irq) (unsigned int, void *) = dummy_free_irq; + /* * void init_IRQ(void) * @@ -92,14 +110,30 @@ return NULL; } -int request_irq(unsigned int irq, void (*handler)(int, void *, struct pt_regs *), - unsigned long flags, const char *devname, void *dev_id) +/* + * We will keep these functions until I have convinced Linus to move + * the declaration of them from include/linux/sched.h to + * include/asm/irq.h. + */ +int request_irq(unsigned int irq, + void (*handler) (int, void *, struct pt_regs *), + unsigned long flags, const char *devname, void *dev_id) +{ + return mach_request_irq(irq, handler, flags, devname, dev_id); +} + +void free_irq(unsigned int irq, void *dev_id) { - if (irq & IRQ_MACHSPEC) - return mach_request_irq(IRQ_IDX(irq), handler, flags, devname, dev_id); + mach_free_irq(irq, dev_id); +} +int sys_request_irq(unsigned int irq, + void (*handler)(int, void *, struct pt_regs *), + unsigned long flags, const char *devname, void *dev_id) +{ if (irq < IRQ1 || irq > IRQ7) { - printk("%s: Incorrect IRQ %d from %s\n", __FUNCTION__, irq, devname); + printk("%s: Incorrect IRQ %d from %s\n", + __FUNCTION__, irq, devname); return -ENXIO; } @@ -109,7 +143,7 @@ __FUNCTION__, irq, irq_list[irq].devname); return -EBUSY; } - if (flags & IRQ_FLG_REPLACE) { + if (!(flags & IRQ_FLG_REPLACE)) { printk("%s: %s can't replace IRQ %d from %s\n", __FUNCTION__, devname, irq, irq_list[irq].devname); return -EBUSY; @@ -122,13 +156,8 @@ return 0; } -void free_irq(unsigned int irq, void *dev_id) +void sys_free_irq(unsigned int irq, void *dev_id) { - if (irq & IRQ_MACHSPEC) { - mach_free_irq(IRQ_IDX(irq), dev_id); - return; - } - if (irq < IRQ1 || irq > IRQ7) { printk("%s: Incorrect IRQ %d\n", __FUNCTION__, irq); return; @@ -157,31 +186,42 @@ return 0; } -void enable_irq(unsigned int irq) +static void dummy_enable_irq(unsigned int irq) { - if ((irq & IRQ_MACHSPEC) && mach_enable_irq) - mach_enable_irq(IRQ_IDX(irq)); + printk("calling uninitialized enable_irq()\n"); } -void disable_irq(unsigned int irq) +static void dummy_disable_irq(unsigned int irq) { - if ((irq & IRQ_MACHSPEC) && mach_disable_irq) - mach_disable_irq(IRQ_IDX(irq)); + printk("calling uninitialized disable_irq()\n"); +} + +static int dummy_request_irq(unsigned int irq, + void (*handler) (int, void *, struct pt_regs *), + unsigned long flags, const char *devname, void *dev_id) +{ + printk("calling uninitialized request_irq()\n"); + return 0; +} + +static void dummy_free_irq(unsigned int irq, void *dev_id) +{ + printk("calling uninitialized disable_irq()\n"); } asmlinkage void process_int(unsigned long vec, struct pt_regs *fp) { - if (vec < VEC_INT1 || vec > VEC_INT7) { + if (vec >= VEC_INT1 && vec <= VEC_INT7) { + vec -= VEC_SPUR; + kstat.interrupts[vec]++; + irq_list[vec].handler(vec, irq_list[vec].dev_id, fp); + } else { if (mach_process_int) mach_process_int(vec, fp); else panic("Can't process interrupt vector %ld\n", vec); return; } - - vec -= VEC_SPUR; - kstat.interrupts[vec]++; - irq_list[vec].handler(vec, irq_list[vec].dev_id, fp); } int get_irq_list(char *buf) diff -u --recursive v2.1.35/linux/arch/m68k/kernel/m68k_ksyms.c linux/arch/m68k/kernel/m68k_ksyms.c --- v2.1.35/linux/arch/m68k/kernel/m68k_ksyms.c Thu Mar 27 14:39:59 1997 +++ linux/arch/m68k/kernel/m68k_ksyms.c Thu Apr 17 13:20:42 1997 @@ -1,3 +1,4 @@ +#include #include #include #include @@ -11,6 +12,8 @@ #include #include #include +#include +#include asmlinkage long long __ashrdi3 (long long, int); extern char m68k_debug_device[]; @@ -31,13 +34,15 @@ EXPORT_SYMBOL(mm_ptov); EXPORT_SYMBOL(mm_end_of_chunk); EXPORT_SYMBOL(m68k_debug_device); -EXPORT_SYMBOL(request_irq); -EXPORT_SYMBOL(free_irq); EXPORT_SYMBOL(dump_fpu); EXPORT_SYMBOL(dump_thread); EXPORT_SYMBOL(strnlen); EXPORT_SYMBOL(strrchr); EXPORT_SYMBOL(strstr); +EXPORT_SYMBOL(local_irq_count); + +/* Networking helper routines. */ +EXPORT_SYMBOL(csum_partial_copy); /* The following are special because they're not called explicitly (the C compiler generates them). Fortunately, diff -u --recursive v2.1.35/linux/arch/m68k/kernel/process.c linux/arch/m68k/kernel/process.c --- v2.1.35/linux/arch/m68k/kernel/process.c Sun Jan 26 02:07:05 1997 +++ linux/arch/m68k/kernel/process.c Thu Apr 17 13:20:42 1997 @@ -22,6 +22,7 @@ #include #include #include +#include #include #include @@ -43,6 +44,7 @@ goto out; /* endless idle loop with no priority at all */ + current->priority = -100; current->counter = -100; for (;;) schedule(); @@ -52,12 +54,23 @@ return ret; } -void hard_reset_now(void) +void machine_restart(char * __unused) { if (mach_reset) mach_reset(); } +void machine_halt(void) +{ +} + +void machine_power_off(void) +{ +#if defined(CONFIG_APM) && defined(CONFIG_APM_POWER_OFF) + apm_set_power_state(APM_STATE_OFF); +#endif +} + void show_regs(struct pt_regs * regs) { printk("\n"); @@ -169,7 +182,7 @@ /* Fill in the fpu structure for a core dump. */ -int dump_fpu (struct user_m68kfp_struct *fpu) +int dump_fpu (struct pt_regs *regs, struct user_m68kfp_struct *fpu) { char fpustate[216]; @@ -207,7 +220,7 @@ if (dump->start_stack < TASK_SIZE) dump->u_ssize = ((unsigned long) (TASK_SIZE - dump->start_stack)) >> PAGE_SHIFT; - dump->u_ar0 = (struct pt_regs *)(((int)(&dump->regs)) -((int)(dump))); + dump->u_ar0 = (struct user_regs_struct *)((int)&dump->regs - (int)dump); sw = ((struct switch_stack *)regs) - 1; dump->regs.d1 = regs->d1; dump->regs.d2 = regs->d2; @@ -230,7 +243,7 @@ dump->regs.pc = regs->pc; dump->regs.fmtvec = (regs->format << 12) | regs->vector; /* dump floating point stuff */ - dump->u_fpvalid = dump_fpu (&dump->m68kfp); + dump->u_fpvalid = dump_fpu (regs, &dump->m68kfp); } /* diff -u --recursive v2.1.35/linux/arch/m68k/kernel/ptrace.c linux/arch/m68k/kernel/ptrace.c --- v2.1.35/linux/arch/m68k/kernel/ptrace.c Sun Jan 26 02:07:05 1997 +++ linux/arch/m68k/kernel/ptrace.c Thu Apr 17 13:20:43 1997 @@ -324,7 +324,6 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data) { struct task_struct *child; - struct user * dummy = NULL; int ret; lock_kernel(); diff -u --recursive v2.1.35/linux/arch/m68k/kernel/setup.c linux/arch/m68k/kernel/setup.c --- v2.1.35/linux/arch/m68k/kernel/setup.c Fri Dec 20 01:19:58 1996 +++ linux/arch/m68k/kernel/setup.c Thu Apr 17 13:20:43 1997 @@ -55,11 +55,6 @@ static char m68k_command_line[CL_SIZE]; char saved_command_line[CL_SIZE]; -/* setup some dummy routines */ -static void dummy_waitbut(void) -{ -} - void (*mach_sched_init) (void (*handler)(int, void *, struct pt_regs *)); /* machine dependent keyboard functions */ int (*mach_keyb_init) (void); @@ -68,11 +63,6 @@ /* machine dependent irq functions */ void (*mach_init_IRQ) (void); void (*(*mach_default_handler)[]) (int, void *, struct pt_regs *) = NULL; -int (*mach_request_irq) (unsigned int, void (*)(int, void *, struct pt_regs *), - unsigned long, const char *, void *); -int (*mach_free_irq) (unsigned int, void *); -void (*mach_enable_irq) (unsigned int) = NULL; -void (*mach_disable_irq) (unsigned int) = NULL; void (*mach_get_model) (char *model) = NULL; int (*mach_get_hardware_list) (char *buffer) = NULL; int (*mach_get_irq_list) (char *) = NULL; @@ -82,19 +72,15 @@ void (*mach_gettod) (int*, int*, int*, int*, int*, int*); int (*mach_hwclk) (int, struct hwclk_time*) = NULL; int (*mach_set_clock_mmss) (unsigned long) = NULL; -void (*mach_mksound)( unsigned int count, unsigned int ticks ); void (*mach_reset)( void ); -void (*waitbut)(void) = dummy_waitbut; struct fb_info *(*mach_fb_init)(long *); long mach_max_dma_address = 0x00ffffff; /* default set to the lower 16MB */ -void (*mach_debug_init)(void); void (*mach_video_setup) (char *, int *); #ifdef CONFIG_BLK_DEV_FD int (*mach_floppy_init) (void) = NULL; void (*mach_floppy_setup) (char *, int *) = NULL; void (*mach_floppy_eject) (void) = NULL; #endif -void (*mach_syms_export)(void) = NULL; extern int amiga_parse_bootinfo(const struct bi_record *); extern int atari_parse_bootinfo(const struct bi_record *); @@ -105,10 +91,6 @@ extern void config_sun3(void); extern void config_apollo(void); -extern void register_console(void (*proc)(const char *)); -extern void ami_serial_print(const char *str); -extern void ata_serial_print(const char *str); - #define MASK_256K 0xfffc0000 @@ -166,12 +148,6 @@ extern int _etext, _edata, _end; int i; char *p, *q; - - /* machtype is set up by head.S, thus we know our gender */ - if (MACH_IS_AMIGA) - register_console(ami_serial_print); - if (MACH_IS_ATARI) - register_console(ata_serial_print); /* The bootinfo is located right after the kernel bss */ m68k_parse_bootinfo((const struct bi_record *)&_end); diff -u --recursive v2.1.35/linux/arch/m68k/kernel/signal.c linux/arch/m68k/kernel/signal.c --- v2.1.35/linux/arch/m68k/kernel/signal.c Fri Jan 3 08:48:37 1997 +++ linux/arch/m68k/kernel/signal.c Thu Apr 17 13:20:43 1997 @@ -291,20 +291,23 @@ tframe = frame; /* return address points to code on stack */ - put_user((ulong)(frame+4), tframe); tframe++; + + if(put_user((ulong)(frame+4), tframe)) + do_exit(SIGSEGV); + tframe++; if (current->exec_domain && current->exec_domain->signal_invmap) - put_user(current->exec_domain->signal_invmap[signr], tframe); + __put_user(current->exec_domain->signal_invmap[signr], tframe); else - put_user(signr, tframe); + __put_user(signr, tframe); tframe++; - put_user(regs->vector, tframe); tframe++; + __put_user(regs->vector, tframe); tframe++; /* "scp" parameter. points to sigcontext */ - put_user((ulong)(frame+6), tframe); tframe++; + __put_user((ulong)(frame+6), tframe); tframe++; /* set up the return code... */ - put_user(0xdefc0014,tframe); tframe++; /* addaw #20,sp */ - put_user(0x70774e40,tframe); tframe++; /* moveq #119,d0; trap #0 */ + __put_user(0xdefc0014,tframe); tframe++; /* addaw #20,sp */ + __put_user(0x70774e40,tframe); tframe++; /* moveq #119,d0; trap #0 */ /* Flush caches so the instructions will be correctly executed. (MA) */ cache_push_v ((unsigned long)frame, (int)tframe - (int)frame); diff -u --recursive v2.1.35/linux/arch/m68k/kernel/sys_m68k.c linux/arch/m68k/kernel/sys_m68k.c --- v2.1.35/linux/arch/m68k/kernel/sys_m68k.c Sun Jan 26 02:07:05 1997 +++ linux/arch/m68k/kernel/sys_m68k.c Thu Apr 17 13:20:43 1997 @@ -34,15 +34,11 @@ int error; lock_kernel(); - error = verify_area(VERIFY_WRITE,fildes,8); - if (error) - goto out; error = do_pipe(fd); - if (error) - goto out; - put_user(fd[0],0+fildes); - put_user(fd[1],1+fildes); -out: + if (!error) { + if (copy_to_user(fildes, fd, 2*sizeof(int))) + error = -EFAULT; + } unlock_kernel(); return error; } @@ -70,10 +66,10 @@ struct mmap_arg_struct a; lock_kernel(); - error = verify_area(VERIFY_READ, arg, sizeof(*arg)); - if (error) + error = -EFAULT; + if (copy_from_user(&a, arg, sizeof(a))) goto out; - copy_from_user(&a, arg, sizeof(a)); + if (!(a.flags & MAP_ANONYMOUS)) { error = -EBADF; if (a.fd >= NR_OPEN || !(file = current->files->fd[a.fd])) @@ -98,15 +94,11 @@ asmlinkage int old_select(struct sel_arg_struct *arg) { struct sel_arg_struct a; - int ret = -EFAULT; - lock_kernel(); if (copy_from_user(&a, arg, sizeof(a))) - goto out; - ret = sys_select(a.n, a.inp, a.outp, a.exp, a.tvp); -out: - unlock_kernel(); - return ret; + return -EFAULT; + /* sys_select() does the appropriate kernel locking */ + return sys_select(a.n, a.inp, a.outp, a.exp, a.tvp); } /* @@ -134,9 +126,8 @@ ret = -EINVAL; if (!ptr) goto out; - if ((ret = verify_area (VERIFY_READ, ptr, sizeof(long)))) + if ((ret = get_user(fourth.__pad, (void **) ptr))) goto out; - get_user(fourth.__pad, (void **)ptr); ret = sys_semctl (first, second, third, fourth); goto out; } @@ -183,22 +174,13 @@ switch (version) { case 0: default: { ulong raddr; - if ((ret = verify_area(VERIFY_WRITE, (ulong*) third, sizeof(ulong)))) - goto out; ret = sys_shmat (first, (char *) ptr, second, &raddr); if (ret) goto out; - put_user (raddr, (ulong *) third); - ret = 0; - goto out; - } - case 1: /* iBCS2 emulator entry point */ - ret = -EINVAL; - if (get_fs() != get_ds()) - goto out; - ret = sys_shmat (first, (char *) ptr, second, (ulong *) third); + ret = put_user (raddr, (ulong *) third); goto out; } + } case SHMDT: ret = sys_shmdt ((char *)ptr); goto out; @@ -212,8 +194,7 @@ ret = -EINVAL; goto out; } - else - ret = -EINVAL; + ret = -EINVAL; out: unlock_kernel(); return ret; diff -u --recursive v2.1.35/linux/arch/m68k/kernel/traps.c linux/arch/m68k/kernel/traps.c --- v2.1.35/linux/arch/m68k/kernel/traps.c Fri Dec 20 01:19:59 1996 +++ linux/arch/m68k/kernel/traps.c Thu Apr 17 13:20:43 1997 @@ -29,11 +29,15 @@ #include #include +#include #include #include #include #include #include +#ifdef CONFIG_KGDB +#include +#endif /* assembler routines */ asmlinkage void system_call(void); @@ -140,10 +144,9 @@ { extern int console_loglevel; console_loglevel = 15; - mach_debug_init(); } -char *vec_names[] = { +static char *vec_names[] = { "RESET SP", "RESET PC", "BUS ERROR", "ADDRESS ERROR", "ILLEGAL INSTRUCTION", "ZERO DIVIDE", "CHK", "TRAPcc", "PRIVILEGE VIOLATION", "TRACE", "LINE 1010", "LINE 1111", @@ -162,17 +165,17 @@ "FPCP BSUN", "FPCP INEXACT", "FPCP DIV BY 0", "FPCP UNDERFLOW", "FPCP OPERAND ERROR", "FPCP OVERFLOW", "FPCP SNAN", "FPCP UNSUPPORTED OPERATION", - "MMU CONFIGUATION ERROR" + "MMU CONFIGURATION ERROR" }; -char *space_names[] = { +static char *space_names[] = { "Space 0", "User Data", "User Program", "Space 3", "Space 4", "Super Data", "Super Program", "CPU" }; -extern void die_if_kernel(char *,struct pt_regs *,int); +void die_if_kernel(char *,struct pt_regs *,int); asmlinkage int do_page_fault(struct pt_regs *regs, unsigned long address, unsigned long error_code); @@ -184,7 +187,7 @@ unsigned long fslw = fp->un.fmt4.pc; /* is really FSLW for access error */ #ifdef DEBUG - printk("fslw=%#lx, fa=%#lx\n", ssw, fp->un.fmt4.effaddr); + printk("fslw=%#lx, fa=%#lx\n", fslw, fp->un.fmt4.effaddr); #endif if (fslw & MMU060_BPE) { @@ -194,7 +197,7 @@ "movec %/d0,%/cacr" : : : "d0" ); /* return if there's no other error */ - if (!(fslw & MMU060_ERR_BITS)) + if ((!(fslw & MMU060_ERR_BITS)) && !(fslw & MMU060_SEE)) return; } @@ -209,8 +212,13 @@ if (fslw & MMU060_MA) addr = PAGE_ALIGN(addr); do_page_fault(&fp->ptregs, addr, errorcode); - } - else { + } else if (fslw & (MMU060_SEE)){ + /* Software Emulation Error. Probably an instruction + * using an unsupported addressing mode + */ + send_sig (SIGSEGV, current, 1); + } else { + printk("pc=%#lx, fa=%#lx\n", fp->ptregs.pc, fp->un.fmt4.effaddr); printk( "68060 access error, fslw=%lx\n", fslw ); trap_c( fp ); } @@ -349,7 +357,7 @@ } #endif /* CONFIG_M68040 */ -#if defined(CONFIG_M68020_OR_M68030) +#if defined(CPU_M68020_OR_M68030) static inline void bus_error030 (struct frame *fp) { volatile unsigned short temp; @@ -628,7 +636,7 @@ asm volatile ("ploadr #2,%0@" : /* no outputs */ : "a" (addr)); } -#endif /* CONFIG_M68020_OR_M68030 */ +#endif /* CPU_M68020_OR_M68030 */ asmlinkage void buserr_c(struct frame *fp) { @@ -651,7 +659,7 @@ access_error040 (fp); break; #endif -#if defined (CONFIG_M68020_OR_M68030) +#if defined (CPU_M68020_OR_M68030) case 0xa: case 0xb: bus_error030 (fp); @@ -675,6 +683,11 @@ static void dump_stack(struct frame *fp) { +#ifdef CONFIG_KGDB + /* This will never return to here, if kgdb has been initialized. And if + * it returns from there, then to where the error happened... */ + enter_kgdb( &fp->ptregs ); +#else unsigned long *stack, *endstack, addr, module_start, module_end; extern char _start, _etext; int i; @@ -772,10 +785,15 @@ for (i = 0; i < 10; i++) printk("%04x ", 0xffff & ((short *) fp->ptregs.pc)[i]); printk ("\n"); +#endif } void bad_super_trap (struct frame *fp) { +#ifdef CONFIG_KGDB + /* Save the register dump if we'll enter kgdb anyways */ + if (!kgdb_initialized) { +#endif console_verbose(); if (fp->ptregs.vector < 4*sizeof(vec_names)/sizeof(vec_names[0])) printk ("*** %s *** FORMAT=%X\n", @@ -805,6 +823,9 @@ fp->ptregs.pc); } printk ("Current process id is %d\n", current->pid); +#ifdef CONFIG_KGDB + } +#endif die_if_kernel("BAD KERNEL TRAP", &fp->ptregs, 0); } @@ -863,7 +884,7 @@ case VEC_FPOVER: case VEC_FPNAN: { - unsigned char fstate[216]; + unsigned char fstate[FPSTATESIZE]; __asm__ __volatile__ (".chip 68k/68881\n\t" "fsave %0@\n\t" @@ -905,9 +926,13 @@ if (!(fp->sr & PS_S)) return; +#ifdef CONFIG_KGDB + /* Save the register dump if we'll enter kgdb anyways */ + if (!kgdb_initialized) { +#endif console_verbose(); printk("%s: %08x\n",str,nr); - printk("PC: %08lx\nSR: %04x SP: %p\n", fp->pc, fp->sr, fp); + printk("PC: [<%08lx>]\nSR: %04x SP: %p\n", fp->pc, fp->sr, fp); printk("d0: %08lx d1: %08lx d2: %08lx d3: %08lx\n", fp->d0, fp->d1, fp->d2, fp->d3); printk("d4: %08lx d5: %08lx a0: %08lx a1: %08lx\n", @@ -917,6 +942,18 @@ printk("Corrupted stack page\n"); printk("Process %s (pid: %d, stackpage=%08lx)\n", current->comm, current->pid, current->kernel_stack_page); +#ifdef CONFIG_KGDB + } +#endif dump_stack((struct frame *)fp); + do_exit(SIGSEGV); +} + +/* + * This function is called if an error occur while accessing + * user-space from the fpsp040 code. + */ +asmlinkage void fpsp040_die(void) +{ do_exit(SIGSEGV); } diff -u --recursive v2.1.35/linux/arch/m68k/lib/checksum.c linux/arch/m68k/lib/checksum.c --- v2.1.35/linux/arch/m68k/lib/checksum.c Fri Jan 3 08:48:37 1997 +++ linux/arch/m68k/lib/checksum.c Thu Apr 17 13:20:43 1997 @@ -19,8 +19,8 @@ * (%1). Thanks to Roman Hodek for pointing this out. * B: GCC seems to mess up if one uses too many * data-registers to hold input values and one tries to - * specify d0 and d1 as scratch registers. Letting gcc choose these - * registers itself solves the problem. + * specify d0 and d1 as scratch registers. Letting gcc + * choose these registers itself solves the problem. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -124,13 +124,20 @@ /* - * copy from user space while checksumming, otherwise like csum_partial + * copy from user space while checksumming, with exception handling. */ unsigned int -csum_partial_copy_fromuser(const char *src, char *dst, int len, int sum) +csum_partial_copy_from_user(const char *src, char *dst, int len, + int sum, int *csum_err) { + /* + * GCC doesn't like more than 10 operands for the asm + * statements so we have to use tmp2 for the error + * code. + */ unsigned long tmp1, tmp2; + __asm__("movel %2,%4\n\t" "btst #1,%4\n\t" /* Check alignment */ "jeq 2f\n\t" @@ -226,27 +233,49 @@ "6:\t" "addl %5,%0\n\t" /* now add rest long to sum */ "clrl %5\n\t" - "addxl %5,%0\n" /* add X bit */ - "7:\n" + "addxl %5,%0\n\t" /* add X bit */ + "7:\t" + "clrl %5\n" /* no error - clear return value */ + "8:\n" + ".section .fixup,\"ax\"\n" + ".even\n" + "9:\t" + "moveq #-14,%5\n\t" /* -EFAULT, out of inputs to asm ;( */ + "jra 8b\n" + ".previous\n" ".section __ex_table,\"a\"\n" - ".long 10b,7b\n" - ".long 11b,7b\n" - ".long 12b,7b\n" - ".long 13b,7b\n" - ".long 14b,7b\n" - ".long 15b,7b\n" - ".long 16b,7b\n" - ".long 17b,7b\n" - ".long 18b,7b\n" - ".long 19b,7b\n" - ".long 20b,7b\n" - ".long 21b,7b\n" + ".long 10b,9b\n" + ".long 11b,9b\n" + ".long 12b,9b\n" + ".long 13b,9b\n" + ".long 14b,9b\n" + ".long 15b,9b\n" + ".long 16b,9b\n" + ".long 17b,9b\n" + ".long 18b,9b\n" + ".long 19b,9b\n" + ".long 20b,9b\n" + ".long 21b,9b\n" ".previous" : "=d" (sum), "=d" (len), "=a" (src), "=a" (dst), - "=&d" (tmp1), "=&d" (tmp2) + "=&d" (tmp1), "=d" (tmp2) : "0" (sum), "1" (len), "2" (src), "3" (dst) ); + + *csum_err = tmp2; + return(sum); +} + +/* + * This one will go away soon. + */ +unsigned int +csum_partial_copy_fromuser(const char *src, char *dst, int len, int sum) +{ + int dummy; + + return csum_partial_copy_from_user(src, dst, len, sum, &dummy); } /* * copy from kernel space while checksumming, otherwise like csum_partial diff -u --recursive v2.1.35/linux/arch/m68k/lib/semaphore.S linux/arch/m68k/lib/semaphore.S --- v2.1.35/linux/arch/m68k/lib/semaphore.S Fri Nov 22 05:56:35 1996 +++ linux/arch/m68k/lib/semaphore.S Thu Apr 17 13:20:43 1997 @@ -9,18 +9,26 @@ #include /* - * "down_failed" is called with the eventual return address - * in %a0, and the address of the semaphore in %a1. We need - * to call "__down()", and then re-try until we succeed.. + * The semaphore operations have a special calling sequence that + * allow us to do a simpler in-line version of them. These routines + * need to convert that sequence back into the C sequence when + * there is contention on the semaphore. */ ENTRY(__down_failed) moveml %a0/%d0/%d1,-(%sp) -1: movel %a1,-(%sp) + movel %a1,-(%sp) jbsr SYMBOL_NAME(__down) movel (%sp)+,%a1 - subql #1,(%a1) - jmi 1b movel (%sp)+,%d0 + movel (%sp)+,%d1 + rts + +ENTRY(__down_failed_interruptible) + movel %a0,-(%sp) + movel %d1,-(%sp) + movel %a1,-(%sp) + jbsr SYMBOL_NAME(__down_interruptible) + movel (%sp)+,%a1 movel (%sp)+,%d1 rts diff -u --recursive v2.1.35/linux/arch/m68k/mm/extable.c linux/arch/m68k/mm/extable.c --- v2.1.35/linux/arch/m68k/mm/extable.c Fri Dec 27 02:03:20 1996 +++ linux/arch/m68k/mm/extable.c Thu Apr 17 13:20:43 1997 @@ -46,7 +46,7 @@ if (mp->ex_table_start == NULL) continue; ret = search_one_table(mp->ex_table_start, - mp->ex_table_stop-1, addr); + mp->ex_table_end-1, addr); if (ret) return ret; } #endif diff -u --recursive v2.1.35/linux/arch/m68k/mm/fault.c linux/arch/m68k/mm/fault.c --- v2.1.35/linux/arch/m68k/mm/fault.c Sat Dec 21 04:24:02 1996 +++ linux/arch/m68k/mm/fault.c Thu Apr 17 13:20:43 1997 @@ -108,10 +108,7 @@ up(&mm->mmap_sem); /* Are we prepared to handle this fault? */ - if (CPU_IS_060 && regs->format == 4) - fault_pc = ((struct frame *)regs)->un.fmt4.pc; - else - fault_pc = regs->pc; + fault_pc = regs->pc; if ((fixup = search_exception_table(fault_pc)) != 0) { struct pt_regs *tregs; printk(KERN_DEBUG "Exception at [<%lx>] (%lx)\n", fault_pc, fixup); diff -u --recursive v2.1.35/linux/arch/m68k/mm/init.c linux/arch/m68k/mm/init.c --- v2.1.35/linux/arch/m68k/mm/init.c Mon Apr 14 16:28:06 1997 +++ linux/arch/m68k/mm/init.c Thu Apr 17 13:20:43 1997 @@ -109,6 +109,8 @@ else ptablep = (pte_t *)__get_free_page(GFP_KERNEL); + flush_page_to_ram((unsigned long) ptablep); + flush_tlb_kernel_page((unsigned long) ptablep); nocache_page ((unsigned long)ptablep); return ptablep; @@ -293,8 +295,6 @@ { int chunk; unsigned long mem_avail = 0; - /* pointer to page table for kernel stacks */ - extern unsigned long availmem; #ifdef DEBUG { @@ -324,21 +324,12 @@ for (chunk = 0; chunk < m68k_num_memory; chunk++) { mem_avail = map_chunk (m68k_memory[chunk].addr, - m68k_memory[chunk].size, &availmem); + m68k_memory[chunk].size, &start_mem); } flush_tlb_all(); #ifdef DEBUG printk ("memory available is %ldKB\n", mem_avail >> 10); -#endif - - /* - * virtual address after end of kernel - * "availmem" is setup by the code in head.S. - */ - start_mem = availmem; - -#ifdef DEBUG printk ("start_mem is %#lx\nvirtual_end is %#lx\n", start_mem, end_mem); #endif @@ -401,7 +392,7 @@ printk ("before free_area_init\n"); #endif - return free_area_init (start_mem, end_mem); + return PAGE_ALIGN(free_area_init (start_mem, end_mem)); } void mem_init(unsigned long start_mem, unsigned long end_mem) diff -u --recursive v2.1.35/linux/arch/m68k/mm/memory.c linux/arch/m68k/mm/memory.c --- v2.1.35/linux/arch/m68k/mm/memory.c Fri Dec 20 01:19:59 1996 +++ linux/arch/m68k/mm/memory.c Thu Apr 17 13:20:43 1997 @@ -63,11 +63,12 @@ return 0; } - if (!(dp->page = __get_free_page (GFP_KERNEL))) { + if (!(dp->page = get_free_page (GFP_KERNEL))) { kfree (dp); return 0; } + flush_tlb_kernel_page((unsigned long) dp->page); nocache_page (dp->page); dp->alloced = 0; @@ -210,10 +211,11 @@ return NULL; } if (!(page = kptr_pages.page[i])) { - if (!(page = (pmd_tablepage *)__get_free_page(GFP_KERNEL))) { + if (!(page = (pmd_tablepage *)get_free_page(GFP_KERNEL))) { printk("No space for kernel pointer table!\n"); return NULL; } + flush_tlb_kernel_page((unsigned long) page); nocache_page((u_long)(kptr_pages.page[i] = page)); } asm volatile("bfset %0@{%1,#1}" @@ -306,21 +308,31 @@ if (CPU_IS_030) { unsigned long ttreg; - asm volatile( "pmove %/tt0,%0@" : : "a" (&ttreg) ); + asm volatile( ".chip 68030\n\t" + "pmove %/tt0,%0@\n\t" + ".chip 68k" + : : "a" (&ttreg) ); if (transp_transl_matches( ttreg, vaddr )) return vaddr; - asm volatile( "pmove %/tt1,%0@" : : "a" (&ttreg) ); + asm volatile( ".chip 68030\n\t" + "pmove %/tt1,%0@\n\t" + ".chip 68k" + : : "a" (&ttreg) ); if (transp_transl_matches( ttreg, vaddr )) return vaddr; } - else { - register unsigned long ttreg __asm__( "d0" ); + else if (CPU_IS_040_OR_060) { + unsigned long ttreg; - asm volatile( ".long 0x4e7a0006" /* movec %dtt0,%d0 */ + asm volatile( ".chip 68040\n\t" + "movec %%dtt0,%0\n\t" + ".chip 68k" : "=d" (ttreg) ); if (transp_transl_matches( ttreg, vaddr )) return vaddr; - asm volatile( ".long 0x4e7a0007" /* movec %dtt1,%d0 */ + asm volatile( ".chip 68040\n\t" + "movec %%dtt1,%0\n\t" + ".chip 68k" : "=d" (ttreg) ); if (transp_transl_matches( ttreg, vaddr )) return vaddr; diff -u --recursive v2.1.35/linux/arch/sparc/defconfig linux/arch/sparc/defconfig --- v2.1.35/linux/arch/sparc/defconfig Mon Apr 14 16:28:06 1997 +++ linux/arch/sparc/defconfig Thu Apr 17 13:20:43 1997 @@ -145,7 +145,7 @@ # # Some SCSI devices (e.g. CD jukebox) support multiple LUNs # -# CONFIG_SCSI_MULTI_LUN is not set +CONFIG_SCSI_MULTI_LUN=y CONFIG_SCSI_CONSTANTS=y # diff -u --recursive v2.1.35/linux/arch/sparc/kernel/entry.S linux/arch/sparc/kernel/entry.S --- v2.1.35/linux/arch/sparc/kernel/entry.S Mon Apr 14 16:28:07 1997 +++ linux/arch/sparc/kernel/entry.S Tue Apr 15 21:47:23 1997 @@ -1,4 +1,4 @@ -/* $Id: entry.S,v 1.137 1997/04/14 05:38:17 davem Exp $ +/* $Id: entry.S,v 1.138 1997/04/15 09:00:50 davem Exp $ * arch/sparc/kernel/entry.S: Sparc trap low-level entry points. * * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) @@ -301,15 +301,26 @@ mov %l7, %o0 ! irq level call C_LABEL(handler_irq) add %sp, REGWIN_SZ, %o1 ! pt_regs ptr - -#if 1 /* ndef __SMP__ */ /* You don't want to know... -DaveM */ wr %l0, PSR_ET, %psr WRITE_PAUSE -#endif RESTORE_ALL #ifdef __SMP__ + /* SMP per-cpu ticker interrupts are handled specially. */ +smp_ticker: + bne real_irq_continue + or %l0, PSR_PIL, %g2 + wr %g2, 0x0, %psr + WRITE_PAUSE + wr %g2, PSR_ET, %psr + WRITE_PAUSE + call C_LABEL(smp_percpu_timer_interrupt) + add %sp, REGWIN_SZ, %o0 + wr %l0, PSR_ET, %psr + WRITE_PAUSE + RESTORE_ALL + /* Here is where we check for possible SMP IPI passed to us * on some level other than 15 which is the NMI and only used * for cross calls. That has a seperate entry point below. @@ -322,8 +333,9 @@ sll %o3, 12, %o3 ld [%o5 + %o3], %o1 andcc %o1, %o4, %g0 - be real_irq_continue - cmp %l7, 13 + be,a smp_ticker + cmp %l7, 14 + cmp %l7, 13 add %o5, %o3, %o5 bne,a 1f sethi %hi(0x40000000), %o2 diff -u --recursive v2.1.35/linux/arch/sparc/kernel/head.S linux/arch/sparc/kernel/head.S --- v2.1.35/linux/arch/sparc/kernel/head.S Mon Mar 17 14:54:20 1997 +++ linux/arch/sparc/kernel/head.S Thu Apr 17 13:20:43 1997 @@ -1,4 +1,4 @@ -/* $Id: head.S,v 1.79 1997/03/04 16:26:31 jj Exp $ +/* $Id: head.S,v 1.81 1997/04/16 07:15:48 davem Exp $ * head.S: The initial boot code for the Sparc port of Linux. * * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) diff -u --recursive v2.1.35/linux/arch/sparc/kernel/irq.c linux/arch/sparc/kernel/irq.c --- v2.1.35/linux/arch/sparc/kernel/irq.c Mon Apr 14 16:28:07 1997 +++ linux/arch/sparc/kernel/irq.c Thu Apr 17 13:20:43 1997 @@ -1,4 +1,4 @@ -/* $Id: irq.c,v 1.66 1997/04/14 05:38:21 davem Exp $ +/* $Id: irq.c,v 1.68 1997/04/16 05:55:58 davem Exp $ * arch/sparc/kernel/irq.c: Interrupt request handling routines. On the * Sparc the IRQ's are basically 'cast in stone' * and you are supposed to probe the prom's device @@ -41,6 +41,10 @@ #include #include +#ifdef __SMP_PROF__ +extern volatile unsigned long smp_local_timer_ticks[1+NR_CPUS]; +#endif + /* * Dave Redman (djhr@tadpole.co.uk) * @@ -71,11 +75,11 @@ void (*disable_irq)(unsigned int) = (void (*)(unsigned int)) irq_panic; void (*enable_pil_irq)(unsigned int) = (void (*)(unsigned int)) irq_panic; void (*disable_pil_irq)(unsigned int) = (void (*)(unsigned int)) irq_panic; -void (*clear_clock_irq)( void ) = irq_panic; -void (*clear_profile_irq)( void ) = irq_panic; -void (*load_profile_irq)( unsigned int ) = (void (*)(unsigned int)) irq_panic; -void (*init_timers)( void (*)(int, void *,struct pt_regs *)) = - (void (*)( void (*)(int, void *,struct pt_regs *))) irq_panic; +void (*clear_clock_irq)(void) = irq_panic; +void (*clear_profile_irq)(int) = (void (*)(int)) irq_panic; +void (*load_profile_irq)(int, unsigned int) = (void (*)(int, unsigned int)) irq_panic; +void (*init_timers)(void (*)(int, void *,struct pt_regs *)) = + (void (*)(void (*)(int, void *,struct pt_regs *))) irq_panic; #ifdef __SMP__ void (*set_cpu_int)(int, int); @@ -128,6 +132,109 @@ return len; } +#ifdef __SMP_PROF__ + +static unsigned int int_count[NR_CPUS][NR_IRQS] = {{0},}; + +extern unsigned int prof_multiplier[NR_CPUS]; +extern unsigned int prof_counter[NR_CPUS]; + +int get_smp_prof_list(char *buf) { + int i,j, len = 0; + struct irqaction * action; + unsigned long sum_spins = 0; + unsigned long sum_spins_syscall = 0; + unsigned long sum_spins_sys_idle = 0; + unsigned long sum_smp_idle_count = 0; + unsigned long sum_local_timer_ticks = 0; + + for (i=0;ihandler) + continue; + len += sprintf(buf+len, "%3d: %10d ", + i, kstat.interrupts[i]); + for (j=0;jflags & SA_INTERRUPT) ? '+' : ' ', + action->name); + for (action=action->next; action; action = action->next) { + len += sprintf(buf+len, ",%s %s", + (action->flags & SA_INTERRUPT) ? " +" : "", + action->name); + } + len += sprintf(buf+len, "\n"); + } + len+=sprintf(buf+len, "LCK: %10lu", + sum_spins); + + for (i=0;ihandler(irq, action->dev_id, regs); action = action->next; } while (action); - irq_exit(cpu, irq); + irq_exit(cpu, cpu_irq); enable_pil_irq(cpu_irq); } diff -u --recursive v2.1.35/linux/arch/sparc/kernel/ptrace.c linux/arch/sparc/kernel/ptrace.c --- v2.1.35/linux/arch/sparc/kernel/ptrace.c Mon Apr 14 16:28:07 1997 +++ linux/arch/sparc/kernel/ptrace.c Thu Apr 17 13:20:43 1997 @@ -889,13 +889,12 @@ asmlinkage void syscall_trace(void) { - lock_kernel(); #ifdef DEBUG_PTRACE printk("%s [%d]: syscall_trace\n", current->comm, current->pid); #endif if ((current->flags & (PF_PTRACED|PF_TRACESYS)) != (PF_PTRACED|PF_TRACESYS)) - goto out; + return; current->exit_code = SIGTRAP; current->state = TASK_STOPPED; current->tss.flags ^= MAGIC_CONSTANT; @@ -911,9 +910,9 @@ current->pid, current->exit_code); #endif if (current->exit_code) { + spin_lock_irq(¤t->sigmask_lock); current->signal |= (1 << (current->exit_code - 1)); + spin_unlock_irq(¤t->sigmask_lock); } current->exit_code = 0; -out: - unlock_kernel(); } diff -u --recursive v2.1.35/linux/arch/sparc/kernel/signal.c linux/arch/sparc/kernel/signal.c --- v2.1.35/linux/arch/sparc/kernel/signal.c Mon Mar 17 14:54:21 1997 +++ linux/arch/sparc/kernel/signal.c Thu Apr 17 13:20:43 1997 @@ -1,4 +1,4 @@ -/* $Id: signal.c,v 1.72 1997/03/03 16:51:43 jj Exp $ +/* $Id: signal.c,v 1.73 1997/04/16 05:56:05 davem Exp $ * linux/arch/sparc/kernel/signal.c * * Copyright (C) 1991, 1992 Linus Torvalds @@ -28,7 +28,8 @@ #define _BLOCKABLE (~(_S(SIGKILL) | _S(SIGSTOP))) -asmlinkage int sys_waitpid(pid_t pid, unsigned long *stat_addr, int options); +asmlinkage int sys_wait4(pid_t pid, unsigned long *stat_addr, + int options, unsigned long *ru); extern void fpsave(unsigned long *fpregs, unsigned long *fsr, void *fpqueue, unsigned long *fpqdepth); @@ -85,12 +86,15 @@ * atomically swap in the new signal mask, and wait for a signal. * This is really tricky on the Sparc, watch out... */ -asmlinkage inline void _sigpause_common(unsigned int set, struct pt_regs *regs) +asmlinkage void _sigpause_common(unsigned int set, struct pt_regs *regs) { unsigned long mask; + spin_lock_irq(¤t->sigmask_lock); mask = current->blocked; current->blocked = set & _BLOCKABLE; + spin_unlock_irq(¤t->sigmask_lock); + regs->pc = regs->npc; regs->npc += 4; @@ -115,16 +119,12 @@ asmlinkage void do_sigpause(unsigned int set, struct pt_regs *regs) { - lock_kernel(); _sigpause_common(set, regs); - unlock_kernel(); } asmlinkage void do_sigsuspend (struct pt_regs *regs) { - lock_kernel(); _sigpause_common(regs->u_regs[UREG_I0], regs); - unlock_kernel(); } @@ -159,26 +159,20 @@ struct new_signal_frame *sf; unsigned long up_psr, pc, npc, mask; - lock_kernel(); sf = (struct new_signal_frame *) regs->u_regs [UREG_FP]; /* 1. Make sure we are not getting garbage from the user */ - if (verify_area (VERIFY_READ, sf, sizeof (*sf))){ - do_exit (SIGSEGV); - goto out; - } - if (((uint) sf) & 3){ - do_exit (SIGSEGV); - goto out; - } + if (verify_area (VERIFY_READ, sf, sizeof (*sf))) + goto segv_and_exit; + + if (((uint) sf) & 3) + goto segv_and_exit; __get_user(pc, &sf->info.si_regs.pc); __get_user(npc, &sf->info.si_regs.npc); - if ((pc | npc) & 3) { - do_exit (SIGSEGV); - goto out; - } + if ((pc | npc) & 3) + goto segv_and_exit; /* 2. Restore the state */ up_psr = regs->psr; @@ -191,43 +185,55 @@ if (sf->fpu_save) restore_fpu_state(regs, sf->fpu_save); + /* This is pretty much atomic, no amount locking would prevent + * the races which exist anyways. + */ __get_user(mask, &sf->info.si_mask); current->blocked = (mask & _BLOCKABLE); -out: + return; + +segv_and_exit: + /* Ugh, we need to grab master lock in these rare cases ;-( */ + lock_kernel(); + do_exit(SIGSEGV); unlock_kernel(); } asmlinkage void do_sigreturn(struct pt_regs *regs) { struct sigcontext *scptr; - unsigned long pc, npc, psr; + unsigned long pc, npc, psr, mask; - lock_kernel(); synchronize_user_stack(); - if (current->tss.new_signal){ - do_new_sigreturn (regs); - goto out; - } + + if (current->tss.new_signal) + return do_new_sigreturn (regs); + scptr = (struct sigcontext *) regs->u_regs[UREG_I0]; + /* Check sanity of the user arg. */ if(verify_area(VERIFY_READ, scptr, sizeof(struct sigcontext)) || - (((unsigned long) scptr) & 3)) { - printk("%s [%d]: do_sigreturn, scptr is invalid at " - "pc<%08lx> scptr<%p>\n", - current->comm, current->pid, regs->pc, scptr); - do_exit(SIGSEGV); - } + (((unsigned long) scptr) & 3)) + goto segv_and_exit; + __get_user(pc, &scptr->sigc_pc); __get_user(npc, &scptr->sigc_npc); + if((pc | npc) & 3) - do_exit(SIGSEGV); /* Nice try. */ + goto segv_and_exit; + + /* This is pretty much atomic, no amount locking would prevent + * the races which exist anyways. + */ + __get_user(mask, &scptr->sigc_mask); + current->blocked = (mask & _BLOCKABLE); - __get_user(current->blocked, &scptr->sigc_mask); - current->blocked &= _BLOCKABLE; __get_user(current->tss.sstk_info.cur_status, &scptr->sigc_onstack); current->tss.sstk_info.cur_status &= 1; + regs->pc = pc; regs->npc = npc; + __get_user(regs->u_regs[UREG_FP], &scptr->sigc_sp); __get_user(regs->u_regs[UREG_I0], &scptr->sigc_o0); __get_user(regs->u_regs[UREG_G1], &scptr->sigc_g1); @@ -236,7 +242,12 @@ __get_user(psr, &scptr->sigc_psr); regs->psr &= ~(PSR_ICC); regs->psr |= (psr & PSR_ICC); -out: + return; + +segv_and_exit: + /* Ugh, we need to grab master lock in these rare cases ;-( */ + lock_kernel(); + do_exit(SIGSEGV); unlock_kernel(); } @@ -252,9 +263,8 @@ return 0; } -static inline void -setup_frame(struct sigaction *sa, unsigned long pc, unsigned long npc, - struct pt_regs *regs, int signr, unsigned long oldmask) +static void setup_frame(struct sigaction *sa, unsigned long pc, unsigned long npc, + struct pt_regs *regs, int signr, unsigned long oldmask) { struct signal_sframe *sframep; struct sigcontext *sc; @@ -274,8 +284,7 @@ /* Don't change signal code and address, so that * post mortem debuggers can have a look. */ - do_exit(SIGILL); - return; + goto sigill_and_return; } sc = &sframep->sig_context; @@ -319,6 +328,13 @@ regs->u_regs[UREG_FP] = (unsigned long) sframep; regs->pc = (unsigned long) sa->sa_handler; regs->npc = (regs->pc + 4); + return; + +sigill_and_return: + /* Ugh, we need to grab master lock in these rare cases ;-( */ + lock_kernel(); + do_exit(SIGILL); + unlock_kernel(); } @@ -353,9 +369,8 @@ current->used_math = 0; } - -static inline void -new_setup_frame(struct sigaction *sa, struct pt_regs *regs, int signo, unsigned long oldmask) +static void new_setup_frame(struct sigaction *sa, struct pt_regs *regs, + int signo, unsigned long oldmask) { struct new_signal_frame *sf; int sigframe_size; @@ -369,16 +384,13 @@ sf = (struct new_signal_frame *)(regs->u_regs[UREG_FP] - sigframe_size); - if (invalid_frame_pointer (sf, sigframe_size)){ - do_exit(SIGILL); - return; - } + if (invalid_frame_pointer (sf, sigframe_size)) + goto sigill_and_return; - if (current->tss.w_saved != 0){ + if (current->tss.w_saved != 0) { printk ("%s [%d]: Invalid user stack frame for " "signal delivery.\n", current->comm, current->pid); - do_exit (SIGILL); - return; + goto sigill_and_return; } /* 2. Save the current process state */ @@ -411,6 +423,12 @@ /* Flush instruction space. */ flush_sig_insns(current->mm, (unsigned long) &(sf->insns[0])); + return; + +sigill_and_return: + lock_kernel(); + do_exit(SIGILL); + unlock_kernel(); } @@ -435,8 +453,7 @@ #ifdef DEBUG_SIGNALS printk ("Invalid stack frame\n"); #endif - do_exit(SIGILL); - return; + goto sigill_and_return; } /* Start with a clean frame pointer and fill it */ @@ -525,23 +542,26 @@ regs->u_regs[UREG_I1] = (uint) si; regs->u_regs[UREG_I2] = (uint) uc; } + return; + +sigill_and_return: + lock_kernel(); + do_exit(SIGILL); + unlock_kernel(); } -asmlinkage int -svr4_getcontext (svr4_ucontext_t *uc, struct pt_regs *regs) +asmlinkage int svr4_getcontext (svr4_ucontext_t *uc, struct pt_regs *regs) { svr4_gregset_t *gr; svr4_mcontext_t *mc; - int ret = -EFAULT; - lock_kernel(); synchronize_user_stack(); - if (current->tss.w_saved){ - printk ("Uh oh, w_saved is not zero (%ld)\n", current->tss.w_saved); - do_exit (SIGSEGV); - } + + if (current->tss.w_saved) + goto sigsegv_and_return; + if(clear_user(uc, sizeof (*uc))) - goto out; + return -EFAULT; /* Setup convenience variables */ mc = &uc->mcontext; @@ -568,58 +588,53 @@ /* The register file is not saved * we have already stuffed all of it with sync_user_stack */ - ret = 0; -out: + return 0; + +sigsegv_and_return: + lock_kernel(); + do_exit(SIGSEGV); unlock_kernel(); - return ret; + return -EFAULT; } - /* Set the context for a svr4 application, this is Solaris way to sigreturn */ asmlinkage int svr4_setcontext (svr4_ucontext_t *c, struct pt_regs *regs) { struct thread_struct *tp = ¤t->tss; svr4_gregset_t *gr; - unsigned long pc, npc, psr; - int ret = -EINTR; + unsigned long pc, npc, psr, mask; - lock_kernel(); /* Fixme: restore windows, or is this already taken care of in * svr4_setup_frame when sync_user_windows is done? */ flush_user_windows(); - if (tp->w_saved){ - printk ("Uh oh, w_saved is: 0x%lx\n", tp->w_saved); - do_exit(SIGSEGV); - goto out; - } - if (((uint) c) & 3){ - printk ("Unaligned structure passed\n"); - do_exit (SIGSEGV); - goto out; - } + if (tp->w_saved) + goto sigsegv_and_return; - if(!__access_ok((unsigned long)c, sizeof(*c))) { - /* Miguel, add nice debugging msg _here_. ;-) */ - do_exit(SIGSEGV); - goto out; - } + if (((uint) c) & 3) + goto sigsegv_and_return; + + if(!__access_ok((unsigned long)c, sizeof(*c))) + goto sigsegv_and_return; /* Check for valid PC and nPC */ gr = &c->mcontext.greg; __get_user(pc, &((*gr)[SVR4_PC])); __get_user(npc, &((*gr)[SVR4_NPC])); - if((pc | npc) & 3) { - printk ("setcontext, PC or nPC were bogus\n"); - do_exit (SIGSEGV); - goto out; - } + + if((pc | npc) & 3) + goto sigsegv_and_return; + /* Retrieve information from passed ucontext */ - /* note that nPC is ored a 1, this is used to inform entry.S */ - /* that we don't want it to mess with our PC and nPC */ - __get_user(current->blocked, &c->sigmask.sigbits [0]); - current->blocked &= _BLOCKABLE; + /* note that nPC is ored a 1, this is used to inform entry.S */ + /* that we don't want it to mess with our PC and nPC */ + + /* This is pretty much atomic, no amount locking would prevent + * the races which exist anyways. + */ + __get_user(mask, &c->sigmask.sigbits [0]); + current->blocked = (mask & _BLOCKABLE); regs->pc = pc; regs->npc = npc | 1; __get_user(regs->y, &((*gr) [SVR4_Y])); @@ -630,9 +645,13 @@ /* Restore g[1..7] and o[0..7] registers */ copy_from_user(®s->u_regs [UREG_G1], &(*gr)[SVR4_G1], sizeof (long) * 7); copy_from_user(®s->u_regs [UREG_I0], &(*gr)[SVR4_O0], sizeof (long) * 8); -out: + return 0; + +sigsegv_and_return: + lock_kernel(); + do_exit(SIGSEGV); unlock_kernel(); - return ret; + return -EFAULT; } static inline void handle_signal(unsigned long signr, struct sigaction *sa, @@ -649,8 +668,11 @@ } if(sa->sa_flags & SA_ONESHOT) sa->sa_handler = NULL; - if(!(sa->sa_flags & SA_NOMASK)) + if(!(sa->sa_flags & SA_NOMASK)) { + spin_lock_irq(¤t->sigmask_lock); current->blocked |= (sa->sa_mask | _S(signr)) & _BLOCKABLE; + spin_unlock_irq(¤t->sigmask_lock); + } } static inline void syscall_restart(unsigned long orig_i0, struct pt_regs *regs, @@ -683,17 +705,23 @@ unsigned long signr, mask = ~current->blocked; struct sigaction *sa; int svr4_signal = current->personality == PER_SVR4; - int ret; - lock_kernel(); while ((signr = current->signal & mask) != 0) { signr = ffz(~signr); - clear_bit(signr, ¤t->signal); + + spin_lock_irq(¤t->sigmask_lock); + current->signal &= ~(1 << signr); + spin_unlock_irq(¤t->sigmask_lock); + sa = current->sig->action + signr; signr++; if ((current->flags & PF_PTRACED) && signr != SIGKILL) { current->exit_code = signr; current->state = TASK_STOPPED; + + /* This happens to be SMP safe so no need to + * grab master kernel lock even in this case. + */ notify_parent(current); schedule(); if (!(signr = current->exit_code)) @@ -702,7 +730,9 @@ if (signr == SIGSTOP) continue; if (_S(signr) & current->blocked) { + spin_lock_irq(¤t->sigmask_lock); current->signal |= _S(signr); + spin_unlock_irq(¤t->sigmask_lock); continue; } sa = current->sig->action + signr - 1; @@ -710,7 +740,14 @@ if(sa->sa_handler == SIG_IGN) { if(signr != SIGCHLD) continue; - while(sys_waitpid(-1,NULL,WNOHANG) > 0); + + /* sys_wait4() grabs the master kernel lock, so + * we need not do so, that sucker should be + * threaded and would not be that difficult to + * do anyways. + */ + while(sys_wait4(-1, NULL, WNOHANG, NULL) > 0) + ; continue; } if(sa->sa_handler == SIG_DFL) { @@ -721,6 +758,9 @@ continue; case SIGTSTP: case SIGTTIN: case SIGTTOU: + /* The operations performed by is_orphaned_pgrp() + * are protected by the tasklist_lock. + */ if (is_orphaned_pgrp(current->pgrp)) continue; @@ -729,6 +769,8 @@ continue; current->state = TASK_STOPPED; current->exit_code = signr; + + /* notify_parent() is SMP safe */ if(!(current->p_pptr->sig->action[SIGCHLD-1].sa_flags & SA_NOCLDSTOP)) notify_parent(current); @@ -748,16 +790,21 @@ #endif /* fall through */ default: + spin_lock_irq(¤t->sigmask_lock); current->signal |= _S(signr & 0x7f); + spin_unlock_irq(¤t->sigmask_lock); + current->flags |= PF_SIGNALED; + + lock_kernel(); /* 8-( */ do_exit(signr); + unlock_kernel(); } } if(restart_syscall) syscall_restart(orig_i0, regs, sa); handle_signal(signr, sa, oldmask, regs, svr4_signal); - ret = 1; - goto out; + return 1; } if(restart_syscall && (regs->u_regs[UREG_I0] == ERESTARTNOHAND || @@ -768,10 +815,7 @@ regs->pc -= 4; regs->npc -= 4; } - ret = 0; -out: - unlock_kernel(); - return ret; + return 0; } asmlinkage int diff -u --recursive v2.1.35/linux/arch/sparc/kernel/smp.c linux/arch/sparc/kernel/smp.c --- v2.1.35/linux/arch/sparc/kernel/smp.c Mon Apr 14 16:28:07 1997 +++ linux/arch/sparc/kernel/smp.c Tue Apr 15 21:47:23 1997 @@ -12,6 +12,7 @@ #include #include #include +#include #include #include @@ -139,6 +140,8 @@ local_flush_tlb_all(); } +static void smp_setup_percpu_timer(void); + void smp_callin(void) { int cpuid = smp_processor_id(); @@ -146,6 +149,10 @@ local_flush_cache_all(); local_flush_tlb_all(); set_irq_udt(mid_xlate[boot_cpu_id]); + + /* Get our local ticker going. */ + smp_setup_percpu_timer(); + calibrate_delay(); smp_store_cpu_info(cpuid); local_flush_cache_all(); @@ -215,6 +222,7 @@ klock_info.akp = boot_cpu_id; smp_store_cpu_info(boot_cpu_id); set_irq_udt(mid_xlate[boot_cpu_id]); + smp_setup_percpu_timer(); local_flush_cache_all(); if(linux_num_cpus == 1) return; /* Not an MP box. */ @@ -506,4 +514,102 @@ __sti(); while(1) barrier(); +} + +/* Protects counters touched during level14 ticker */ +spinlock_t ticker_lock = SPIN_LOCK_UNLOCKED; + +/* 32-bit Sparc specific profiling function. */ +static inline void sparc_do_profile(unsigned long pc) +{ + if(prof_buffer && current->pid) { + extern int _stext; + + pc -= (unsigned long) &_stext; + pc >>= prof_shift; + + spin_lock(&ticker_lock); + if(pc < prof_len) + prof_buffer[pc]++; + else + prof_buffer[prof_len - 1]++; + spin_unlock(&ticker_lock); + } +} + +volatile unsigned long smp_local_timer_ticks[1+NR_CPUS]={0,}; + +unsigned int prof_multiplier[NR_CPUS]; +unsigned int prof_counter[NR_CPUS]; + +extern void update_one_process(struct task_struct *p, unsigned long ticks, + unsigned long user, unsigned long system); + +void smp_percpu_timer_interrupt(struct pt_regs *regs) +{ + int cpu = smp_processor_id(); + + clear_profile_irq(mid_xlate[cpu]); + if(!user_mode(regs)) + sparc_do_profile(regs->pc); + if(!--prof_counter[cpu]) { + int user = user_mode(regs); + if(current->pid) { + update_one_process(current, 1, user, !user); + + if(--current->counter < 0) { + current->counter = 0; + need_resched = 1; + } + + spin_lock(&ticker_lock); + if(user) { + if(current->priority < DEF_PRIORITY) + kstat.cpu_nice++; + else + kstat.cpu_user++; + } else { + kstat.cpu_system++; + } + spin_unlock(&ticker_lock); + } + prof_counter[cpu] = prof_multiplier[cpu]; + } +#ifdef __SMP_PROF__ + smp_local_timer_ticks[cpu]++; +#endif +} + +extern unsigned int lvl14_resolution; + +static void smp_setup_percpu_timer(void) +{ + int cpu = smp_processor_id(); + + prof_counter[cpu] = prof_multiplier[cpu] = 1; + load_profile_irq(mid_xlate[cpu], lvl14_resolution); + + if(cpu == boot_cpu_id) + enable_pil_irq(14); +} + +int setup_profiling_timer(unsigned int multiplier) +{ + int i; + unsigned long flags; + + /* Prevent level14 ticker IRQ flooding. */ + if((!multiplier) || (lvl14_resolution / multiplier) < 500) + return -EINVAL; + + save_and_cli(flags); + for(i = 0; i < NR_CPUS; i++) { + if(cpu_present_map & (1 << i)) { + load_profile_irq(mid_xlate[i], lvl14_resolution / multiplier); + prof_multiplier[i] = multiplier; + } + } + restore_flags(flags); + + return 0; } diff -u --recursive v2.1.35/linux/arch/sparc/kernel/sparc_ksyms.c linux/arch/sparc/kernel/sparc_ksyms.c --- v2.1.35/linux/arch/sparc/kernel/sparc_ksyms.c Mon Apr 14 16:28:07 1997 +++ linux/arch/sparc/kernel/sparc_ksyms.c Thu Apr 17 13:20:43 1997 @@ -1,4 +1,4 @@ -/* $Id: sparc_ksyms.c,v 1.54 1997/04/14 05:38:25 davem Exp $ +/* $Id: sparc_ksyms.c,v 1.55 1997/04/17 03:28:56 davem Exp $ * arch/sparc/kernel/ksyms.c: Sparc specific ksyms support. * * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu) @@ -87,6 +87,9 @@ EXPORT_SYMBOL_PRIVATE(_lock_kernel); EXPORT_SYMBOL_PRIVATE(_unlock_kernel); EXPORT_SYMBOL_PRIVATE(_spinlock_waitfor); +EXPORT_SYMBOL_PRIVATE(_rw_read_enter); +EXPORT_SYMBOL_PRIVATE(_rw_read_exit); +EXPORT_SYMBOL_PRIVATE(_rw_write_enter); EXPORT_SYMBOL(__sparc_bh_counter); EXPORT_SYMBOL(page_offset); EXPORT_SYMBOL(stack_top); diff -u --recursive v2.1.35/linux/arch/sparc/kernel/sun4c_irq.c linux/arch/sparc/kernel/sun4c_irq.c --- v2.1.35/linux/arch/sparc/kernel/sun4c_irq.c Mon Apr 14 16:28:07 1997 +++ linux/arch/sparc/kernel/sun4c_irq.c Tue Apr 15 21:47:23 1997 @@ -111,12 +111,12 @@ clear_intr = sun4c_timers->timer_limit10; } -static void sun4c_clear_profile_irq(void) +static void sun4c_clear_profile_irq(int cpu) { /* Errm.. not sure how to do this.. */ } -static void sun4c_load_profile_irq(unsigned int limit) +static void sun4c_load_profile_irq(int cpu, unsigned int limit) { /* Errm.. not sure how to do this.. */ } diff -u --recursive v2.1.35/linux/arch/sparc/kernel/sun4m_irq.c linux/arch/sparc/kernel/sun4m_irq.c --- v2.1.35/linux/arch/sparc/kernel/sun4m_irq.c Mon Apr 14 16:28:07 1997 +++ linux/arch/sparc/kernel/sun4m_irq.c Thu Apr 17 13:20:43 1997 @@ -29,6 +29,7 @@ #include #include #include +#include #include #include #include @@ -145,7 +146,7 @@ /*11*/ SUN4M_INT_SBUS(5) | SUN4M_INT_VME(5) | SUN4M_INT_FLOPPY, /*12*/ SUN4M_INT_SERIAL | SUN4M_INT_KBDMS, /*13*/ SUN4M_INT_AUDIO, -/*14*/ 0x00000000, +/*14*/ SUN4M_INT_E14, /*15*/ 0x00000000 }; @@ -196,37 +197,18 @@ clear_intr = sun4m_timers->l10_timer_limit; } -static void sun4m_clear_profile_irq(void) +static void sun4m_clear_profile_irq(int cpu) { volatile unsigned int clear; - clear = sun4m_timers->cpu_timers[0].l14_timer_limit; + clear = sun4m_timers->cpu_timers[cpu].l14_timer_limit; } -static void sun4m_load_profile_irq(unsigned int limit) +static void sun4m_load_profile_irq(int cpu, unsigned int limit) { - sun4m_timers->cpu_timers[0].l14_timer_limit = limit; + sun4m_timers->cpu_timers[cpu].l14_timer_limit = limit; } -#if HANDLE_LVL14_IRQ -static void sun4m_lvl14_handler(int irq, void *dev_id, struct pt_regs * regs) -{ - volatile unsigned int clear; - - printk("CPU[%d]: TOOK A LEVEL14!\n", smp_processor_id()); - /* we do nothing with this at present - * this is purely to prevent OBP getting its mucky paws - * in linux. - */ - clear = sun4m_timers->cpu_timers[0].l14_timer_limit; /* clear interrupt */ - - /* reload with value, this allows on the fly retuning of the level14 - * timer - */ - sun4m_timers->cpu_timers[0].l14_timer_limit = lvl14_resolution; -} -#endif /* HANDLE_LVL14_IRQ */ - __initfunc(static void sun4m_init_timers(void (*counter_fn)(int, void *, struct pt_regs *))) { int reg_count, irq, cpu; @@ -282,13 +264,6 @@ prom_halt(); } - /* Can't cope with multiple CPUS yet so no level14 tick events */ -#if HANDLE_LVL14_IRQ - if (linux_num_cpus > 1) - claim_ticker14(NULL, PROFILE_IRQ, 0); - else - claim_ticker14(sun4m_lvl14_handler, PROFILE_IRQ, lvl14_resolution); -#endif /* HANDLE_LVL14_IRQ */ if(linux_num_cpus > 1) { for(cpu = 0; cpu < 4; cpu++) sun4m_timers->cpu_timers[cpu].l14_timer_limit = 0; @@ -296,6 +271,25 @@ } else { sun4m_timers->cpu_timers[0].l14_timer_limit = 0; } +#ifdef __SMP__ + { + unsigned long flags; + extern unsigned long lvl14_save[4]; + struct tt_entry *trap_table = &sparc_ttable[SP_TRAP_IRQ1 + (14 - 1)]; + + /* For SMP we use the level 14 ticker, however the bootup code + * has copied the firmwares level 14 vector into boot cpu's + * trap table, we must fix this now or we get squashed. + */ + __save_and_cli(flags); + trap_table->inst_one = lvl14_save[0]; + trap_table->inst_two = lvl14_save[1]; + trap_table->inst_three = lvl14_save[2]; + trap_table->inst_four = lvl14_save[3]; + local_flush_cache_all(); + __restore_flags(flags); + } +#endif } __initfunc(void sun4m_init_IRQ(void)) @@ -349,10 +343,6 @@ * Not sure, but writing here on SLAVIO systems may puke * so I don't do it unless there is more than 1 cpu. */ -#if 0 - printk("Warning:" - "sun4m multiple CPU interrupt code requires work\n"); -#endif irq_rcvreg = (unsigned long *) &sun4m_interrupts->undirected_target; sun4m_interrupts->undirected_target = 0; diff -u --recursive v2.1.35/linux/arch/sparc/kernel/sys_sparc.c linux/arch/sparc/kernel/sys_sparc.c --- v2.1.35/linux/arch/sparc/kernel/sys_sparc.c Sun Jan 26 02:07:08 1997 +++ linux/arch/sparc/kernel/sys_sparc.c Thu Apr 17 13:20:43 1997 @@ -1,4 +1,4 @@ -/* $Id: sys_sparc.c,v 1.34 1997/01/06 06:52:35 davem Exp $ +/* $Id: sys_sparc.c,v 1.35 1997/04/16 05:56:09 davem Exp $ * linux/arch/sparc/kernel/sys_sparc.c * * This file contains various random system calls that @@ -254,49 +254,45 @@ sparc_sigaction (int signum, const struct sigaction *action, struct sigaction *oldaction) { struct sigaction new_sa, *p; - int err = -EINVAL; - lock_kernel(); if(signum < 0) { current->tss.new_signal = 1; signum = -signum; } + if(signum<1 || signum>32) + return -EINVAL; - if (signum<1 || signum>32) - goto out; p = signum - 1 + current->sig->action; - if (action) { - err = verify_area(VERIFY_READ,action,sizeof(struct sigaction)); - if (err) - goto out; - err = -EINVAL; + if(action) { + if(verify_area(VERIFY_READ,action,sizeof(struct sigaction))) + return -EFAULT; if (signum==SIGKILL || signum==SIGSTOP) - goto out; - err = -EFAULT; + return -EINVAL; if(copy_from_user(&new_sa, action, sizeof(struct sigaction))) - goto out; + return -EFAULT; if (new_sa.sa_handler != SIG_DFL && new_sa.sa_handler != SIG_IGN) { - err = verify_area(VERIFY_READ, new_sa.sa_handler, 1); - if (err) - goto out; + if(verify_area(VERIFY_READ, new_sa.sa_handler, 1)) + return -EFAULT; } } if (oldaction) { - err = -EFAULT; + /* In the clone() case we could copy half consistant + * state to the user, however this could sleep and + * deadlock us if we held the signal lock on SMP. So for + * now I take the easy way out and do no locking. + */ if (copy_to_user(oldaction, p, sizeof(struct sigaction))) - goto out; + return -EFAULT; } if (action) { + spin_lock_irq(¤t->sig->siglock); *p = new_sa; check_pending(signum); + spin_unlock_irq(¤t->sig->siglock); } - - err = 0; -out: - unlock_kernel(); - return err; + return 0; } #ifndef CONFIG_AP1000 diff -u --recursive v2.1.35/linux/arch/sparc/kernel/sys_sunos.c linux/arch/sparc/kernel/sys_sunos.c --- v2.1.35/linux/arch/sparc/kernel/sys_sunos.c Mon Mar 17 14:54:21 1997 +++ linux/arch/sparc/kernel/sys_sunos.c Thu Apr 17 13:20:44 1997 @@ -1,4 +1,4 @@ -/* $Id: sys_sunos.c,v 1.77 1997/02/15 01:17:04 davem Exp $ +/* $Id: sys_sunos.c,v 1.78 1997/04/16 05:56:12 davem Exp $ * sys_sunos.c: SunOS specific syscall compatibility support. * * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) @@ -1184,39 +1184,39 @@ struct sigaction *oldaction) { struct sigaction new_sa, *p; - const int sigaction_size = sizeof (struct sigaction) - sizeof (void *); - int err = -EINVAL; + const int sigaction_size = sizeof (struct sigaction) - sizeof (void *); - lock_kernel(); current->personality |= PER_BSD; - - if (signum<1 || signum>32) - goto out; + if(signum < 1 || signum > 32) + return -EINVAL; p = signum - 1 + current->sig->action; - if (action) { - err = -EFAULT; + + if(action) { if(copy_from_user(&new_sa, action, sigaction_size)) - goto out; - err = -EINVAL; + return -EFAULT; if (signum==SIGKILL || signum==SIGSTOP) - goto out; + return -EINVAL; memset(&new_sa, 0, sizeof(struct sigaction)); - err = -EFAULT; if(copy_from_user(&new_sa, action, sigaction_size)) - goto out; + return -EFAULT; if (new_sa.sa_handler != SIG_DFL && new_sa.sa_handler != SIG_IGN) { - err = verify_area(VERIFY_READ, new_sa.sa_handler, 1); - if (err) - goto out; + if(verify_area(VERIFY_READ, new_sa.sa_handler, 1)) + return -EFAULT; } new_sa.sa_flags ^= SUNOS_SV_INTERRUPT; } if (oldaction) { - err = -EFAULT; + /* In the clone() case we could copy half consistant + * state to the user, however this could sleep and + * deadlock us if we held the signal lock on SMP. So for + * now I take the easy way out and do no locking. + * But then again we don't support SunOS lwp's anyways ;-) + */ if (copy_to_user(oldaction, p, sigaction_size)) - goto out; + return -EFAULT; + if (oldaction->sa_flags & SA_RESTART) oldaction->sa_flags &= ~SA_RESTART; else @@ -1224,13 +1224,12 @@ } if (action) { + spin_lock_irq(¤t->sig->siglock); *p = new_sa; check_pending(signum); + spin_unlock_irq(¤t->sig->siglock); } - err = 0; -out: - unlock_kernel(); - return err; + return 0; } diff -u --recursive v2.1.35/linux/arch/sparc/kernel/tick14.c linux/arch/sparc/kernel/tick14.c --- v2.1.35/linux/arch/sparc/kernel/tick14.c Sat Nov 9 00:11:50 1996 +++ linux/arch/sparc/kernel/tick14.c Tue Apr 15 21:47:23 1997 @@ -60,6 +60,8 @@ void claim_ticker14(void (*handler)(int, void *, struct pt_regs *), int irq_nr, unsigned int timeout ) { + int cpu = smp_processor_id(); + /* first we copy the obp handler instructions */ disable_irq(irq_nr); @@ -78,7 +80,7 @@ "counter14", NULL)) { install_linux_ticker(); - load_profile_irq(timeout); + load_profile_irq(cpu, timeout); enable_irq(irq_nr); } } diff -u --recursive v2.1.35/linux/arch/sparc/kernel/time.c linux/arch/sparc/kernel/time.c --- v2.1.35/linux/arch/sparc/kernel/time.c Mon Apr 14 16:28:07 1997 +++ linux/arch/sparc/kernel/time.c Tue Apr 15 21:47:23 1997 @@ -1,4 +1,4 @@ -/* $Id: time.c,v 1.27 1997/04/14 05:38:31 davem Exp $ +/* $Id: time.c,v 1.28 1997/04/15 09:01:10 davem Exp $ * linux/arch/sparc/kernel/time.c * * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) @@ -54,11 +54,6 @@ last_rtc_update = xtime.tv_sec; else last_rtc_update = xtime.tv_sec - 600; /* do it again in 60 s */ - -#ifdef __SMP__ - /* I really think it should not be done this way... -DaveM */ - smp_message_pass(MSG_ALL_BUT_SELF, MSG_RESCHEDULE, 0L, 0); -#endif } /* Converts Gregorian date to seconds since 1970-01-01 00:00:00. diff -u --recursive v2.1.35/linux/arch/sparc/lib/locks.S linux/arch/sparc/lib/locks.S --- v2.1.35/linux/arch/sparc/lib/locks.S Mon Apr 14 16:28:08 1997 +++ linux/arch/sparc/lib/locks.S Thu Apr 17 13:20:44 1997 @@ -1,4 +1,4 @@ -/* $Id: locks.S,v 1.9 1997/04/14 05:38:41 davem Exp $ +/* $Id: locks.S,v 1.11 1997/04/17 03:29:03 davem Exp $ * locks.S: SMP low-level lock primitives on Sparc. * * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu) @@ -7,6 +7,7 @@ #include #include #include +#include #include .text @@ -19,8 +20,8 @@ * itself in %g1, %g4 must be restored into %o7 when we return, * and the caller wants us to return to him at three instructions * previous to the call instruction which got us here. See how - * this is used in asm-sparc/smp_lock.h if what I just said - * confuses you to no end. + * this is used in asm/smp_lock.h and asm/spinlock.h if what I + * just said confuses you to no end. */ .globl ___spinlock_waitfor ___spinlock_waitfor: @@ -59,8 +60,8 @@ 9: jmpl %o7 + 0x8, %g0 mov %g4, %o7 - .globl ___lock_reaquire_kernel -___lock_reaquire_kernel: + .globl ___lock_reacquire_kernel +___lock_reacquire_kernel: rd %psr, %g3 or %g3, PSR_PIL, %g7 wr %g7, 0x0, %psr @@ -81,9 +82,6 @@ jmpl %o7 + 0x8, %g0 mov %g4, %o7 -#undef NO_PROC_ID -#define NO_PROC_ID 0xff - .globl ___unlock_kernel ___unlock_kernel: addcc %g2, 1, %g2 @@ -100,4 +98,65 @@ wr %g3, 0x0, %psr nop; nop; nop; 1: jmpl %o7 + 0x8, %g0 + mov %g4, %o7 + + /* Read/writer locks, as usual this is overly clever to make it + * as fast as possible. + */ + + /* caches... */ +___rw_read_enter_spin_on_wlock: + orcc %g2, 0x0, %g0 + be,a ___rw_read_enter + ldstub [%g1 + 3], %g2 + b ___rw_read_enter_spin_on_wlock + ldub [%g1 + 3], %g2 +___rw_write_enter_spin_on_wlock: + orcc %g2, 0x0, %g0 + be,a ___rw_write_enter + ldstub [%g1 + 3], %g2 + b ___rw_write_enter_spin_on_wlock + ldub [%g1 + 3], %g2 + + .globl ___rw_read_enter +___rw_read_enter: + orcc %g2, 0x0, %g0 + bne,a ___rw_read_enter_spin_on_wlock + ldub [%g1 + 3], %g2 +1: + ldstub [%g1 + 2], %g7 + orcc %g7, 0x0, %g0 + bne 1b + ldsh [%g1], %g2 + add %g2, 1, %g2 + sth %g2, [%g1] + sth %g0, [%g1 + 2] + retl + mov %g4, %o7 + + /* We must be careful here to not blow away wlock. */ + .globl ___rw_read_exit +___rw_read_exit_spin: + ldstub [%g1 + 2], %g2 +___rw_read_exit: + orcc %g2, 0x0, %g0 + bne ___rw_read_exit_spin + ldsh [%g1], %g7 + sub %g7, 1, %g7 + sth %g7, [%g1] + stb %g0, [%g1 + 2] + retl + mov %g4, %o7 + + .globl ___rw_write_enter +___rw_write_enter: + orcc %g2, 0x0, %g0 + bne,a ___rw_write_enter_spin_on_wlock + ldub [%g1 + 3], %g2 + ld [%g1], %g2 +1: + andncc %g2, 0xff, %g0 + bne,a 1b + ld [%g1], %g2 + retl mov %g4, %o7 diff -u --recursive v2.1.35/linux/arch/sparc64/Makefile linux/arch/sparc64/Makefile --- v2.1.35/linux/arch/sparc64/Makefile Mon Apr 14 16:28:08 1997 +++ linux/arch/sparc64/Makefile Tue Apr 15 21:47:23 1997 @@ -1,4 +1,4 @@ -# $Id: Makefile,v 1.14 1997/04/10 23:32:33 davem Exp $ +# $Id: Makefile,v 1.15 1997/04/14 17:04:49 jj Exp $ # sparc64/Makefile # # Makefile for the architecture dependent flags and dependencies on the @@ -24,7 +24,7 @@ # debugging of the kernel to get the proper debugging information. #CFLAGS := $(CFLAGS) -g -pipe -fcall-used-g5 -fcall-used-g7 -CFLAGS := $(CFLAGS) -pipe -fno-sibling-call \ +CFLAGS := $(CFLAGS) -pipe \ -fcall-used-g5 -fcall-used-g7 -Wno-sign-compare LINKFLAGS = -T arch/sparc64/vmlinux.lds diff -u --recursive v2.1.35/linux/arch/sparc64/defconfig linux/arch/sparc64/defconfig --- v2.1.35/linux/arch/sparc64/defconfig Mon Apr 14 16:28:08 1997 +++ linux/arch/sparc64/defconfig Thu Apr 17 13:20:44 1997 @@ -107,7 +107,7 @@ # # Some SCSI devices (e.g. CD jukebox) support multiple LUNs # -# CONFIG_SCSI_MULTI_LUN is not set +CONFIG_SCSI_MULTI_LUN=y CONFIG_SCSI_CONSTANTS=y # diff -u --recursive v2.1.35/linux/arch/sparc64/kernel/etrap.S linux/arch/sparc64/kernel/etrap.S --- v2.1.35/linux/arch/sparc64/kernel/etrap.S Mon Apr 14 16:28:09 1997 +++ linux/arch/sparc64/kernel/etrap.S Tue Apr 15 21:47:23 1997 @@ -1,4 +1,4 @@ -/* $Id: etrap.S,v 1.10 1997/04/03 13:03:49 davem Exp $ +/* $Id: etrap.S,v 1.11 1997/04/14 17:04:45 jj Exp $ * etrap.S: Preparing for entry into the kernel on Sparc V9. * * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu) @@ -19,9 +19,8 @@ etrap: rdpr %pil, %g4 etrap_irq: - rdpr %wstate, %g5 - sllx %g4, 20, %g4 rdpr %tstate, %g1 + sllx %g4, 20, %g4 rdpr %tpc, %g2 or %g1, %g4, %g1 rdpr %tnpc, %g3 @@ -39,6 +38,7 @@ * trap level until PRIMARY_CONTEXT is set to zero, else * we fall out of NUCLEUS too soon and crash hard. */ + rdpr %wstate, %g5 mov PRIMARY_CONTEXT, %g7 ldxa [%g7] ASI_DMMU, %g4 mov SECONDARY_CONTEXT, %g6 diff -u --recursive v2.1.35/linux/arch/sparc64/kernel/idprom.c linux/arch/sparc64/kernel/idprom.c --- v2.1.35/linux/arch/sparc64/kernel/idprom.c Mon Dec 30 01:59:59 1996 +++ linux/arch/sparc64/kernel/idprom.c Thu Apr 17 13:20:44 1997 @@ -1,4 +1,4 @@ -/* $Id: idprom.c,v 1.1 1996/12/28 18:39:38 davem Exp $ +/* $Id: idprom.c,v 1.2 1997/04/17 02:28:10 miguel Exp $ * idprom.c: Routines to load the idprom into kernel addresses and * interpret the data contained within. * @@ -34,14 +34,12 @@ idprom = &idprom_buffer; if (idprom->id_format != 0x01) { - prom_printf("IDPROM: Unknown format type!\n"); - prom_halt(); + prom_printf("IDPROM: Warning, unknown format type!\n"); } if (idprom->id_cksum != calc_idprom_cksum(idprom)) { - prom_printf("IDPROM: Checksum failure (nvram=%x, calc=%x)!\n", + prom_printf("IDPROM: Warning, checksum failure (nvram=%x, calc=%x)!\n", idprom->id_cksum, calc_idprom_cksum(idprom)); - prom_halt(); } printk("Ethernet address: %02x:%02x:%02x:%02x:%02x:%02x\n", diff -u --recursive v2.1.35/linux/arch/sparc64/kernel/irq.c linux/arch/sparc64/kernel/irq.c --- v2.1.35/linux/arch/sparc64/kernel/irq.c Mon Apr 14 16:28:09 1997 +++ linux/arch/sparc64/kernel/irq.c Thu Apr 17 13:20:44 1997 @@ -1,4 +1,4 @@ -/* $Id: irq.c,v 1.11 1997/04/14 05:38:59 davem Exp $ +/* $Id: irq.c,v 1.12 1997/04/16 05:56:20 davem Exp $ * irq.c: UltraSparc IRQ handling/init/registry. * * Copyright (C) 1997 David S. Miller (davem@caip.rutgers.edu) @@ -382,7 +382,7 @@ /* Per-processor IRQ locking depth, both SMP and non-SMP code use this. */ unsigned int local_irq_count[NR_CPUS]; -atomic_t __sparc64_bh_counter; +atomic_t __sparc64_bh_counter = ATOMIC_INIT(0); #ifdef __SMP__ #error SMP not supported on sparc64 just yet diff -u --recursive v2.1.35/linux/arch/sparc64/kernel/signal32.c linux/arch/sparc64/kernel/signal32.c --- v2.1.35/linux/arch/sparc64/kernel/signal32.c Mon Apr 14 16:28:09 1997 +++ linux/arch/sparc64/kernel/signal32.c Thu Apr 17 13:20:44 1997 @@ -1,4 +1,4 @@ -/* $Id: signal32.c,v 1.5 1997/04/07 18:57:09 jj Exp $ +/* $Id: signal32.c,v 1.6 1997/04/16 10:27:17 jj Exp $ * arch/sparc64/kernel/signal32.c * * Copyright (C) 1991, 1992 Linus Torvalds @@ -32,7 +32,8 @@ #define synchronize_user_stack() do { } while (0) -asmlinkage int sys_waitpid(pid_t pid, unsigned long *stat_addr, int options); +asmlinkage int sys_wait4(pid_t pid, unsigned long *stat_addr, + int options, unsigned long *ru); asmlinkage int do_signal32(unsigned long oldmask, struct pt_regs * regs, unsigned long orig_o0, int ret_from_syscall); @@ -85,12 +86,15 @@ * atomically swap in the new signal mask, and wait for a signal. * This is really tricky on the Sparc, watch out... */ -asmlinkage inline void _sigpause32_common(unsigned int set, struct pt_regs *regs) +asmlinkage void _sigpause32_common(unsigned int set, struct pt_regs *regs) { unsigned int mask; + spin_lock_irq(¤t->sigmask_lock); mask = current->blocked; current->blocked = set & _BLOCKABLE; + spin_unlock_irq(¤t->sigmask_lock); + regs->tpc = regs->tnpc; regs->tnpc += 4; @@ -115,16 +119,12 @@ asmlinkage void do_sigpause32(unsigned int set, struct pt_regs *regs) { - lock_kernel (); _sigpause32_common(set, regs); - unlock_kernel (); } asmlinkage void do_sigsuspend32(struct pt_regs *regs) { - lock_kernel (); _sigpause32_common(regs->u_regs[UREG_I0], regs); - unlock_kernel (); } @@ -158,15 +158,15 @@ sf = (struct new_signal_frame32 *) regs->u_regs [UREG_FP]; /* 1. Make sure we are not getting garbage from the user */ if (verify_area (VERIFY_READ, sf, sizeof (*sf))){ - do_exit (SIGSEGV); + goto segv; } if (((unsigned long) sf) & 3){ - do_exit (SIGSEGV); + goto segv; } get_user(pc, &sf->info.si_regs.pc); __get_user(npc, &sf->info.si_regs.npc); if ((pc | npc) & 3){ - do_exit (SIGSEGV); + goto segv; } regs->tpc = pc; regs->tnpc = npc; @@ -187,15 +187,18 @@ restore_fpu_state32(regs, &sf->fpu_state); __get_user(mask, &sf->info.si_mask); current->blocked = mask & _BLOCKABLE; - unlock_kernel(); + return; +segv: + lock_kernel(); + do_exit(SIGSEGV); } asmlinkage void do_sigreturn32(struct pt_regs *regs) { struct sigcontext32 *scptr; unsigned pc, npc, psr; + unsigned long mask; - lock_kernel (); synchronize_user_stack(); if (current->tss.new_signal) return do_new_sigreturn32(regs); @@ -204,18 +207,15 @@ /* Check sanity of the user arg. */ if(verify_area(VERIFY_READ, scptr, sizeof(struct sigcontext32)) || (((unsigned long) scptr) & 3)) { - printk("%s [%d]: do_sigreturn, scptr is invalid at " - "pc<%016lx> scptr<%p>\n", - current->comm, current->pid, regs->tpc, scptr); - do_exit(SIGSEGV); + goto segv; } __get_user(pc, &scptr->sigc_pc); __get_user(npc, &scptr->sigc_npc); if((pc | npc) & 3) - do_exit(SIGSEGV); /* Nice try. */ + goto segv; /* Nice try. */ - __get_user(current->blocked, &scptr->sigc_mask); - current->blocked &= _BLOCKABLE; + __get_user(mask, &scptr->sigc_mask); + current->blocked = (mask & _BLOCKABLE); __get_user(current->tss.sstk_info.cur_status, &scptr->sigc_onstack); current->tss.sstk_info.cur_status &= 1; regs->tpc = pc; @@ -228,7 +228,10 @@ __get_user(psr, &scptr->sigc_psr); regs->tstate &= ~(TSTATE_ICC); regs->tstate |= psr_to_tstate_icc(psr); - unlock_kernel (); + return; +segv: + lock_kernel (); + do_exit (SIGSEGV); } /* Checks if the fp is valid */ @@ -239,7 +242,7 @@ return 0; } -static inline void +static void setup_frame32(struct sigaction *sa, unsigned long pc, unsigned long npc, struct pt_regs *regs, int signr, unsigned long oldmask) { @@ -264,8 +267,8 @@ /* Don't change signal code and address, so that * post mortem debuggers can have a look. */ + lock_kernel (); do_exit(SIGILL); - return; } sc = &sframep->sig_context; @@ -358,15 +361,15 @@ sf = (struct new_signal_frame32 *)(regs->u_regs[UREG_FP] - sigframe_size); if (invalid_frame_pointer (sf, sigframe_size)){ + lock_kernel (); do_exit(SIGILL); - return; } if (current->tss.w_saved != 0){ printk ("%s[%d]: Invalid user stack frame for " "signal delivery.\n", current->comm, current->pid); + lock_kernel (); do_exit (SIGILL); - return; } /* 2. Save the current process state */ @@ -433,8 +436,8 @@ #ifdef DEBUG_SIGNALS printk ("Invalid stack frame\n"); #endif + lock_kernel (); do_exit(SIGILL); - return; } /* Start with a clean frame pointer and fill it */ @@ -705,7 +708,14 @@ if(sa->sa_handler == SIG_IGN) { if(signr != SIGCHLD) continue; - while(sys_waitpid(-1,NULL,WNOHANG) > 0); + + /* sys_wait4() grabs the master kernel lock, so + * we need not do so, that sucker should be + * threaded and would not be that difficult to + * do anyways. + */ + while(sys_wait4(-1, NULL, WNOHANG, NULL) > 0) + ; continue; } if(sa->sa_handler == SIG_DFL) { diff -u --recursive v2.1.35/linux/arch/sparc64/kernel/sparc64_ksyms.c linux/arch/sparc64/kernel/sparc64_ksyms.c --- v2.1.35/linux/arch/sparc64/kernel/sparc64_ksyms.c Thu Mar 27 14:40:01 1997 +++ linux/arch/sparc64/kernel/sparc64_ksyms.c Tue Apr 15 21:47:23 1997 @@ -1,4 +1,4 @@ -/* $Id: sparc64_ksyms.c,v 1.3 1997/03/18 17:59:10 jj Exp $ +/* $Id: sparc64_ksyms.c,v 1.4 1997/04/14 17:04:43 jj Exp $ * arch/sparc/kernel/ksyms.c: Sparc specific ksyms support. * * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu) @@ -162,7 +162,8 @@ EXPORT_SYMBOL(__csum_partial_copy_sparc_generic); /* Moving data to/from userspace. */ -EXPORT_SYMBOL(__copy_user); +EXPORT_SYMBOL(__copy_to_user); +EXPORT_SYMBOL(__copy_from_user); EXPORT_SYMBOL(__strncpy_from_user); /* No version information on this, heavily used in inline asm, diff -u --recursive v2.1.35/linux/arch/sparc64/kernel/sparcelf32.c linux/arch/sparc64/kernel/sparcelf32.c --- v2.1.35/linux/arch/sparc64/kernel/sparcelf32.c Mon Apr 14 16:28:09 1997 +++ linux/arch/sparc64/kernel/sparcelf32.c Thu Apr 17 13:20:44 1997 @@ -38,6 +38,7 @@ #include #include #include +#include #include #include @@ -156,20 +157,20 @@ sp -= argc+1; argv = (__u32 *) sp; if (!ibcs) { - __put_user(((__u32) envp),--sp); - __put_user(((__u32) argv),--sp); + __put_user(((__u32)(long) envp),--sp); + __put_user(((__u32)(long) argv),--sp); } __put_user((__u32)argc,--sp); current->mm->arg_start = (unsigned long) p; while (argc-->0) { - __put_user(((__u32)p),argv++); + __put_user(((__u32)(long)p),argv++); p += strlen_user(p); } __put_user(NULL, argv); current->mm->arg_end = current->mm->env_start = (unsigned long) p; while (envc-->0) { - __put_user(((__u32)p),envp++); + __put_user(((__u32)(long)p),envp++); p += strlen_user(p); } __put_user(NULL, envp); @@ -1108,7 +1109,7 @@ #else if (sizeof(elf_gregset_t) != sizeof(struct pt_regs)) { - printk("sizeof(elf_gregset_t) (%d) != sizeof(struct pt_regs) (%d)\n", + printk("sizeof(elf_gregset_t) (%ld) != sizeof(struct pt_regs) (%ld)\n", sizeof(elf_gregset_t), sizeof(struct pt_regs)); } else @@ -1255,7 +1256,7 @@ } #endif /* USE_ELF_CORE_DUMP */ -int init_elf32_binfmt(void) +__initfunc(int init_elf32_binfmt(void)) { return register_binfmt(&elf32_format); } diff -u --recursive v2.1.35/linux/arch/sparc64/kernel/sys_sparc32.c linux/arch/sparc64/kernel/sys_sparc32.c --- v2.1.35/linux/arch/sparc64/kernel/sys_sparc32.c Mon Apr 14 16:28:09 1997 +++ linux/arch/sparc64/kernel/sys_sparc32.c Thu Apr 17 13:20:44 1997 @@ -1,4 +1,4 @@ -/* $Id: sys_sparc32.c,v 1.3 1997/04/09 08:25:17 jj Exp $ +/* $Id: sys_sparc32.c,v 1.6 1997/04/16 14:52:29 jj Exp $ * sys_sparc32.c: Conversion between 32bit and 64bit native syscalls. * * Copyright (C) 1997 Jakub Jelinek (jj@sunsite.mff.cuni.cz) @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include @@ -21,6 +22,8 @@ #include #include #include +#include +#include #include #include @@ -32,9 +35,6 @@ * produce warnings */ #define A(x) ((unsigned long)x) -/* FIXME: All struct * etc. stuff should be examined and proper structure conversions - * added ASAP -JJ */ - extern asmlinkage int sys_ioperm(unsigned long from, unsigned long num, int on); extern asmlinkage unsigned long sys_brk(unsigned long brk); extern asmlinkage unsigned long sys_mmap(unsigned long addr, unsigned long len, unsigned long prot, unsigned long flags, unsigned long fd, unsigned long off); @@ -69,7 +69,6 @@ extern asmlinkage long sys_write(unsigned int fd, const char * buf, unsigned long count); extern asmlinkage long sys_readv(unsigned long fd, const struct iovec * vector, unsigned long count); extern asmlinkage long sys_writev(unsigned long fd, const struct iovec * vector, unsigned long count); -extern asmlinkage int sys_getdents(unsigned int fd, void * dirent, unsigned int count); extern asmlinkage int sys_select(int n, fd_set *inp, fd_set *outp, fd_set *exp, struct timeval *tvp); extern asmlinkage int sys_poll(struct pollfd * ufds, unsigned int nfds, int timeout); extern asmlinkage int sys_newstat(char * filename, struct stat * statbuf); @@ -142,6 +141,50 @@ return sys_ioperm((unsigned long)from, (unsigned long)num, on); } +struct msgbuf32 { s32 mtype; char mtext[1]; }; + +struct ipc_perm32 +{ + key_t key; + __kernel_uid_t32 uid; + __kernel_gid_t32 gid; + __kernel_uid_t32 cuid; + __kernel_gid_t32 cgid; + __kernel_mode_t32 mode; + unsigned short seq; +}; + +struct msqid_ds32 +{ + struct ipc_perm32 msg_perm; + u32 msg_first; + u32 msg_last; + __kernel_time_t32 msg_stime; + __kernel_time_t32 msg_rtime; + __kernel_time_t32 msg_ctime; + u32 wwait; + u32 rwait; + unsigned short msg_cbytes; + unsigned short msg_qnum; + unsigned short msg_qbytes; + __kernel_ipc_pid_t32 msg_lspid; + __kernel_ipc_pid_t32 msg_lrpid; +}; + +struct shmid_ds32 { + struct ipc_perm32 shm_perm; + int shm_segsz; + __kernel_time_t32 shm_atime; + __kernel_time_t32 shm_dtime; + __kernel_time_t32 shm_ctime; + __kernel_ipc_pid_t32 shm_cpid; + __kernel_ipc_pid_t32 shm_lpid; + unsigned short shm_nattch; + unsigned short shm_npages; + u32 shm_pages; + u32 attaches; +}; + /* * sys32_ipc() is the de-multiplexer for the SysV IPC calls in 32bit emulation.. * @@ -184,32 +227,111 @@ if (call <= MSGCTL) switch (call) { case MSGSND: - /* XXX struct msgbuf has a long first :(( */ - err = sys_msgsnd (first, (struct msgbuf *) A(ptr), - second, third); + { + struct msgbuf *p = kmalloc (second + sizeof (struct msgbuf), GFP_KERNEL); + + if (!p) err = -ENOMEM; + else { + if (get_user(p->mtype, &(((struct msgbuf32 *)A(ptr))->mtype)) || + __copy_from_user(p->mtext, &(((struct msgbuf32 *)A(ptr))->mtext), second)) + err = -EFAULT; + else { + unsigned long old_fs = get_fs(); + set_fs (KERNEL_DS); + err = sys_msgsnd (first, p, second, third); + set_fs (old_fs); + } + kfree (p); + } + } goto out; case MSGRCV: - switch (version) { - case 0: { - struct ipc_kludge tmp; - err = -EINVAL; - if (!ptr) - goto out; - err = -EFAULT; - if(copy_from_user(&tmp,(struct ipc_kludge *) ptr, sizeof (tmp))) + { + struct msgbuf *p; + unsigned long old_fs; + + if (!version) { + struct ipc_kludge tmp; + err = -EINVAL; + if (!ptr) + goto out; + err = -EFAULT; + if(copy_from_user(&tmp,(struct ipc_kludge *)A(ptr), sizeof (tmp))) + goto out; + ptr = tmp.msgp; + fifth = tmp.msgtyp; + } + p = kmalloc (second + sizeof (struct msgbuf), GFP_KERNEL); + if (!p) { + err = -EFAULT; goto out; - err = sys_msgrcv (first, tmp.msgp, second, tmp.msgtyp, third); - goto out; } - case 1: default: - err = sys_msgrcv (first, (struct msgbuf *) ptr, second, fifth, third); + old_fs = get_fs(); + set_fs (KERNEL_DS); + err = sys_msgrcv (first, p, second, fifth, third); + set_fs (old_fs); + if (put_user (p->mtype, &(((struct msgbuf32 *)A(ptr))->mtype)) || + __copy_to_user(&(((struct msgbuf32 *)A(ptr))->mtext), p->mtext, second)) + err = -EFAULT; + kfree (p); goto out; } case MSGGET: err = sys_msgget ((key_t) first, second); goto out; case MSGCTL: - err = sys_msgctl (first, second, (struct msqid_ds *) ptr); + { + struct msqid_ds m; + unsigned long old_fs; + + switch (second) { + case IPC_INFO: + case MSG_INFO: + /* struct msginfo is the same */ + case IPC_RMID: + /* and this doesn't care about ptr */ + err = sys_msgctl (first, second, (struct msqid_ds *)A(ptr)); + goto out; + + case IPC_SET: + if (get_user (m.msg_perm.uid, &(((struct msqid_ds32 *)A(ptr))->msg_perm.uid)) || + __get_user (m.msg_perm.gid, &(((struct msqid_ds32 *)A(ptr))->msg_perm.gid)) || + __get_user (m.msg_perm.mode, &(((struct msqid_ds32 *)A(ptr))->msg_perm.mode)) || + __get_user (m.msg_qbytes, &(((struct msqid_ds32 *)A(ptr))->msg_qbytes))) { + err = -EFAULT; + goto out; + } + default: + break; + } + old_fs = get_fs(); + set_fs (KERNEL_DS); + err = sys_msgctl (first, second, &m); + set_fs (old_fs); + switch (second) { + case MSG_STAT: + case IPC_STAT: + if (put_user (m.msg_perm.key, &(((struct msqid_ds32 *)A(ptr))->msg_perm.key)) || + __put_user (m.msg_perm.uid, &(((struct msqid_ds32 *)A(ptr))->msg_perm.uid)) || + __put_user (m.msg_perm.gid, &(((struct msqid_ds32 *)A(ptr))->msg_perm.gid)) || + __put_user (m.msg_perm.cuid, &(((struct msqid_ds32 *)A(ptr))->msg_perm.cuid)) || + __put_user (m.msg_perm.cgid, &(((struct msqid_ds32 *)A(ptr))->msg_perm.cgid)) || + __put_user (m.msg_perm.mode, &(((struct msqid_ds32 *)A(ptr))->msg_perm.mode)) || + __put_user (m.msg_perm.seq, &(((struct msqid_ds32 *)A(ptr))->msg_perm.seq)) || + __put_user (m.msg_stime, &(((struct msqid_ds32 *)A(ptr))->msg_stime)) || + __put_user (m.msg_rtime, &(((struct msqid_ds32 *)A(ptr))->msg_rtime)) || + __put_user (m.msg_ctime, &(((struct msqid_ds32 *)A(ptr))->msg_ctime)) || + __put_user (m.msg_cbytes, &(((struct msqid_ds32 *)A(ptr))->msg_cbytes)) || + __put_user (m.msg_qnum, &(((struct msqid_ds32 *)A(ptr))->msg_qnum)) || + __put_user (m.msg_qbytes, &(((struct msqid_ds32 *)A(ptr))->msg_qbytes)) || + __put_user (m.msg_lspid, &(((struct msqid_ds32 *)A(ptr))->msg_lspid)) || + __put_user (m.msg_lrpid, &(((struct msqid_ds32 *)A(ptr))->msg_lrpid))) + err = -EFAULT; + break; + default: + break; + } + } goto out; default: err = -EINVAL; @@ -220,28 +342,92 @@ case SHMAT: switch (version) { case 0: default: { - ulong raddr; - err = sys_shmat (first, (char *) ptr, second, &raddr); + unsigned long raddr; + err = sys_shmat (first, (char *)A(ptr), second, &raddr); if (err) goto out; err = -EFAULT; - if(put_user (raddr, (ulong *) third)) + if(put_user (raddr, ((u32 *)A(third)))) goto out; err = 0; goto out; } - case 1: /* iBCS2 emulator entry point */ - err = sys_shmat (first, (char *) ptr, second, (ulong *) third); + case 1: /* If iBCS2 should ever run, then for sure in 64bit mode, not 32bit... */ + err = -EINVAL; goto out; } case SHMDT: - err = sys_shmdt ((char *)ptr); + err = sys_shmdt ((char *)A(ptr)); goto out; case SHMGET: err = sys_shmget (first, second, third); goto out; case SHMCTL: - err = sys_shmctl (first, second, (struct shmid_ds *) ptr); + { + struct shmid_ds s; + unsigned long old_fs; + + switch (second) { + case IPC_INFO: + /* struct shminfo is the same */ + case SHM_LOCK: + case SHM_UNLOCK: + case IPC_RMID: + /* and these three aren't using ptr at all */ + err = sys_shmctl (first, second, (struct shmid_ds *)A(ptr)); + goto out; + + case IPC_SET: + if (get_user (s.shm_perm.uid, &(((struct shmid_ds32 *)A(ptr))->shm_perm.uid)) || + __get_user (s.shm_perm.gid, &(((struct shmid_ds32 *)A(ptr))->shm_perm.gid)) || + __get_user (s.shm_perm.mode, &(((struct shmid_ds32 *)A(ptr))->shm_perm.mode))) { + err = -EFAULT; + goto out; + } + default: + break; + } + old_fs = get_fs(); + set_fs (KERNEL_DS); + err = sys_shmctl (first, second, &s); + set_fs (old_fs); + switch (second) { + case SHM_INFO: + { + struct shm_info32 { int used_ids; u32 shm_tot; u32 shm_rss; u32 shm_swp; u32 swap_attempts; u32 swap_successes; }; + struct shm_info *si = (struct shm_info *)&s; + + if (put_user (si->used_ids, &(((struct shm_info32 *)A(ptr))->used_ids)) || + __put_user (si->shm_tot, &(((struct shm_info32 *)A(ptr))->shm_tot)) || + __put_user (si->shm_rss, &(((struct shm_info32 *)A(ptr))->shm_rss)) || + __put_user (si->shm_swp, &(((struct shm_info32 *)A(ptr))->shm_swp)) || + __put_user (si->swap_attempts, &(((struct shm_info32 *)A(ptr))->swap_attempts)) || + __put_user (si->swap_successes, &(((struct shm_info32 *)A(ptr))->swap_successes))) + err = -EFAULT; + } + break; + case SHM_STAT: + case IPC_STAT: + if (put_user (s.shm_perm.key, &(((struct shmid_ds32 *)A(ptr))->shm_perm.key)) || + __put_user (s.shm_perm.uid, &(((struct shmid_ds32 *)A(ptr))->shm_perm.uid)) || + __put_user (s.shm_perm.gid, &(((struct shmid_ds32 *)A(ptr))->shm_perm.gid)) || + __put_user (s.shm_perm.cuid, &(((struct shmid_ds32 *)A(ptr))->shm_perm.cuid)) || + __put_user (s.shm_perm.cgid, &(((struct shmid_ds32 *)A(ptr))->shm_perm.cgid)) || + __put_user (s.shm_perm.mode, &(((struct shmid_ds32 *)A(ptr))->shm_perm.mode)) || + __put_user (s.shm_perm.seq, &(((struct shmid_ds32 *)A(ptr))->shm_perm.seq)) || + __put_user (s.shm_atime, &(((struct shmid_ds32 *)A(ptr))->shm_atime)) || + __put_user (s.shm_dtime, &(((struct shmid_ds32 *)A(ptr))->shm_dtime)) || + __put_user (s.shm_ctime, &(((struct shmid_ds32 *)A(ptr))->shm_ctime)) || + __put_user (s.shm_segsz, &(((struct shmid_ds32 *)A(ptr))->shm_segsz)) || + __put_user (s.shm_nattch, &(((struct shmid_ds32 *)A(ptr))->shm_nattch)) || + __put_user (s.shm_lpid, &(((struct shmid_ds32 *)A(ptr))->shm_cpid)) || + __put_user (s.shm_cpid, &(((struct shmid_ds32 *)A(ptr))->shm_lpid))) + err = -EFAULT; + break; + default: + break; + } + } goto out; default: err = -EINVAL; @@ -272,15 +458,45 @@ asmlinkage long sys32_fcntl(unsigned int fd, unsigned int cmd, u32 arg) { - return sys_fcntl(fd, cmd, (unsigned long)arg); + switch (cmd) { + case F_GETLK: + case F_SETLK: + case F_SETLKW: + { + struct flock f; + unsigned long old_fs; + long ret; + + if (get_user (f.l_type, &(((struct flock32 *)A(arg))->l_type)) || + __get_user (f.l_whence, &(((struct flock32 *)A(arg))->l_whence)) || + __get_user (f.l_start, &(((struct flock32 *)A(arg))->l_start)) || + __get_user (f.l_len, &(((struct flock32 *)A(arg))->l_len)) || + __get_user (f.l_pid, &(((struct flock32 *)A(arg))->l_pid))) + return -EFAULT; + old_fs = get_fs(); set_fs (KERNEL_DS); + ret = sys_fcntl(fd, cmd, (unsigned long)&f); + set_fs (old_fs); + if (__put_user (f.l_type, &(((struct flock32 *)A(arg))->l_type)) || + __put_user (f.l_whence, &(((struct flock32 *)A(arg))->l_whence)) || + __put_user (f.l_start, &(((struct flock32 *)A(arg))->l_start)) || + __put_user (f.l_len, &(((struct flock32 *)A(arg))->l_len)) || + __put_user (f.l_pid, &(((struct flock32 *)A(arg))->l_pid))) + return -EFAULT; + return ret; + } + default: + return sys_fcntl(fd, cmd, (unsigned long)arg); + } } +/* Conversion of args should be probably done in all the locations where it is handled, + using if (current->tss.flags & SPARC_FLAG_32BIT */ asmlinkage int sys32_ioctl(unsigned int fd, unsigned int cmd, u32 arg) { return sys_ioctl(fd, cmd, (unsigned long)arg); } -asmlinkage int sys32_mknod(u32 filename, int mode, dev_t dev) +asmlinkage int sys32_mknod(u32 filename, int mode, __kernel_dev_t32 dev) { return sys_mknod((const char *)A(filename), mode, dev); } @@ -315,19 +531,52 @@ return sys_rename((const char *)A(oldname), (const char *)A(newname)); } +/* XXX: Play with the addr, it will be ugly :(( */ asmlinkage int sys32_quotactl(int cmd, u32 special, int id, u32 addr) { return sys_quotactl(cmd, (const char *)A(special), id, (caddr_t)A(addr)); } +static int put_statfs (u32 buf, struct statfs *s) +{ + if (put_user (s->f_type, &(((struct statfs32 *)A(buf))->f_type)) || + __put_user (s->f_bsize, &(((struct statfs32 *)A(buf))->f_bsize)) || + __put_user (s->f_blocks, &(((struct statfs32 *)A(buf))->f_blocks)) || + __put_user (s->f_bfree, &(((struct statfs32 *)A(buf))->f_bfree)) || + __put_user (s->f_bavail, &(((struct statfs32 *)A(buf))->f_bavail)) || + __put_user (s->f_files, &(((struct statfs32 *)A(buf))->f_files)) || + __put_user (s->f_ffree, &(((struct statfs32 *)A(buf))->f_ffree)) || + __put_user (s->f_namelen, &(((struct statfs32 *)A(buf))->f_namelen)) || + __put_user (s->f_fsid.val[0], &(((struct statfs32 *)A(buf))->f_fsid.val[0])) || + __put_user (s->f_fsid.val[1], &(((struct statfs32 *)A(buf))->f_fsid.val[1]))) + return -EFAULT; + return 0; +} + asmlinkage int sys32_statfs(u32 path, u32 buf) { - return sys_statfs((const char *)A(path), (struct statfs *)A(buf)); + int ret; + struct statfs s; + unsigned long old_fs = get_fs(); + + set_fs (KERNEL_DS); + ret = sys_statfs((const char *)A(path), &s); + set_fs (old_fs); + if (put_statfs(buf, &s)) return -EFAULT; + return ret; } asmlinkage int sys32_fstatfs(unsigned int fd, u32 buf) { - return sys_fstatfs(fd, (struct statfs *)A(buf)); + int ret; + struct statfs s; + unsigned long old_fs = get_fs(); + + set_fs (KERNEL_DS); + ret = sys_fstatfs(fd, &s); + set_fs (old_fs); + if (put_statfs(buf, &s)) return -EFAULT; + return ret; } asmlinkage int sys32_truncate(u32 path, u32 length) @@ -342,11 +591,24 @@ asmlinkage int sys32_utime(u32 filename, u32 times) { - return sys_utime((char *)A(filename), (struct utimbuf *)A(times)); + struct utimbuf32 { __kernel_time_t32 actime, modtime; }; + struct utimbuf t; + unsigned long old_fs; + int ret; + + if (get_user (t.actime, &(((struct utimbuf32 *)A(times))->actime)) || + __get_user (t.modtime, &(((struct utimbuf32 *)A(times))->modtime))) + return -EFAULT; + old_fs = get_fs(); + set_fs (KERNEL_DS); + ret = sys_utime((char *)A(filename), &t); + set_fs (old_fs); + return ret; } asmlinkage int sys32_utimes(u32 filename, u32 utimes) { + /* struct timeval is the same :)) */ return sys_utimes((char *)A(filename), (struct timeval *)A(utimes)); } @@ -365,12 +627,12 @@ return sys_chroot((const char *)A(filename)); } -asmlinkage int sys32_chmod(u32 filename, mode_t mode) +asmlinkage int sys32_chmod(u32 filename, __kernel_mode_t32 mode) { return sys_chmod((const char *)A(filename), mode); } -asmlinkage int sys32_chown(u32 filename, uid_t user, gid_t group) +asmlinkage int sys32_chown(u32 filename, __kernel_uid_t32 user, __kernel_gid_t32 group) { return sys_chown((const char *)A(filename), user, group); } @@ -392,6 +654,7 @@ asmlinkage int sys32_llseek(unsigned int fd, u32 offset_high, u32 offset_low, u32 result, unsigned int origin) { + /* loff_t is the same :)) */ return sys_llseek(fd, (unsigned long)offset_high, (unsigned long)offset_low, (loff_t *)A(result), origin); } @@ -407,22 +670,234 @@ asmlinkage long sys32_readv(u32 fd, u32 vector, u32 count) { - return sys_readv((unsigned long)fd, (const struct iovec *)A(vector), (unsigned long)count); + struct iovec32 { u32 iov_base; __kernel_size_t32 iov_len; }; + struct iovec *v; + u32 i; + long ret; + unsigned long old_fs; + + if (!count) return 0; if (count > UIO_MAXIOV) return -EINVAL; + v = kmalloc (count * sizeof (struct iovec), GFP_KERNEL); if (!v) return -ENOMEM; + for (i = 0; i < count; i++) { + if (__get_user ((unsigned long)(v[i].iov_base), &((((struct iovec32 *)A(vector))+i)->iov_base)) || + __get_user (v[i].iov_len, &((((struct iovec32 *)A(vector))+i)->iov_len))) { + kfree (v); + return -EFAULT; + } + } + old_fs = get_fs(); + set_fs (KERNEL_DS); + ret = sys_readv((unsigned long)fd, v, (unsigned long)count); + set_fs (old_fs); + kfree (v); + return ret; } asmlinkage long sys32_writev(u32 fd, u32 vector, u32 count) { - return sys_writev((unsigned long)fd, (const struct iovec *)A(vector), (unsigned long)count); + struct iovec32 { u32 iov_base; __kernel_size_t32 iov_len; }; + struct iovec *v; + u32 i; + long ret; + unsigned long old_fs; + + if (!count) return 0; if (count > UIO_MAXIOV) return -EINVAL; + v = kmalloc (count * sizeof (struct iovec), GFP_KERNEL); if (!v) return -ENOMEM; + for (i = 0; i < count; i++) { + if (__get_user ((unsigned long)(v[i].iov_base), &((((struct iovec32 *)A(vector))+i)->iov_base)) || + __get_user (v[i].iov_len, &((((struct iovec32 *)A(vector))+i)->iov_len))) { + kfree (v); + return -EFAULT; + } + } + old_fs = get_fs(); + set_fs (KERNEL_DS); + ret = sys_writev((unsigned long)fd, v, (unsigned long)count); + set_fs (old_fs); + kfree (v); + return ret; +} + +/* readdir & getdents */ + +#define NAME_OFFSET(de) ((int) ((de)->d_name - (char *) (de))) +#define ROUND_UP(x) (((x)+sizeof(long)-1) & ~(sizeof(long)-1)) + +struct old_linux_dirent32 { + u32 d_ino; + u32 d_offset; + unsigned short d_namlen; + char d_name[1]; +}; + +struct readdir_callback32 { + struct old_linux_dirent32 * dirent; + int count; +}; + +static int fillonedir(void * __buf, const char * name, int namlen, off_t offset, ino_t ino) +{ + struct readdir_callback32 * buf = (struct readdir_callback32 *) __buf; + struct old_linux_dirent32 * dirent; + + if (buf->count) + return -EINVAL; + buf->count++; + dirent = buf->dirent; + put_user(ino, &dirent->d_ino); + put_user(offset, &dirent->d_offset); + put_user(namlen, &dirent->d_namlen); + copy_to_user(dirent->d_name, name, namlen); + put_user(0, dirent->d_name + namlen); + return 0; +} + +asmlinkage int old32_readdir(unsigned int fd, u32 dirent, unsigned int count) +{ + int error = -EBADF; + struct file * file; + struct readdir_callback32 buf; + + lock_kernel(); + if (fd >= NR_OPEN || !(file = current->files->fd[fd])) + goto out; + error = -ENOTDIR; + if (!file->f_op || !file->f_op->readdir) + goto out; + error = verify_area(VERIFY_WRITE, (void *)A(dirent), sizeof(struct old_linux_dirent32)); + if (error) + goto out; + buf.count = 0; + buf.dirent = (struct old_linux_dirent32 *)A(dirent); + error = file->f_op->readdir(file->f_inode, file, &buf, fillonedir); + if (error < 0) + goto out; + error = buf.count; +out: + unlock_kernel(); + return error; +} + +struct linux_dirent32 { + u32 d_ino; + u32 d_off; + unsigned short d_reclen; + char d_name[1]; +}; + +struct getdents_callback32 { + struct linux_dirent32 * current_dir; + struct linux_dirent32 * previous; + int count; + int error; +}; + +static int filldir(void * __buf, const char * name, int namlen, off_t offset, ino_t ino) +{ + struct linux_dirent32 * dirent; + struct getdents_callback32 * buf = (struct getdents_callback32 *) __buf; + int reclen = ROUND_UP(NAME_OFFSET(dirent) + namlen + 1); + + buf->error = -EINVAL; /* only used if we fail.. */ + if (reclen > buf->count) + return -EINVAL; + dirent = buf->previous; + if (dirent) + put_user(offset, &dirent->d_off); + dirent = buf->current_dir; + buf->previous = dirent; + put_user(ino, &dirent->d_ino); + put_user(reclen, &dirent->d_reclen); + copy_to_user(dirent->d_name, name, namlen); + put_user(0, dirent->d_name + namlen); + ((char *) dirent) += reclen; + buf->current_dir = dirent; + buf->count -= reclen; + return 0; } asmlinkage int sys32_getdents(unsigned int fd, u32 dirent, unsigned int count) { - return sys_getdents(fd, (void *)A(dirent), count); + struct file * file; + struct linux_dirent32 * lastdirent; + struct getdents_callback32 buf; + int error = -EBADF; + + lock_kernel(); + if (fd >= NR_OPEN || !(file = current->files->fd[fd])) + goto out; + error = -ENOTDIR; + if (!file->f_op || !file->f_op->readdir) + goto out; + error = verify_area(VERIFY_WRITE, (void *)A(dirent), count); + if (error) + goto out; + buf.current_dir = (struct linux_dirent32 *) A(dirent); + buf.previous = NULL; + buf.count = count; + buf.error = 0; + error = file->f_op->readdir(file->f_inode, file, &buf, filldir); + if (error < 0) + goto out; + lastdirent = buf.previous; + if (!lastdirent) { + error = buf.error; + } else { + put_user(file->f_pos, &lastdirent->d_off); + error = count - buf.count; + } +out: + unlock_kernel(); + return error; } +/* end of readdir & getdents */ + asmlinkage int sys32_select(int n, u32 inp, u32 outp, u32 exp, u32 tvp) { - return sys_select(n, (fd_set *)A(inp), (fd_set *)A(outp), (fd_set *)A(exp), (struct timeval *)A(tvp)); + unsigned long old_fs; + char *p; + u32 *q; + int i, ret = -EINVAL, nn; + u32 *Inp, *Outp, *Exp; + + if (n < 0 || n > PAGE_SIZE*2) return -EINVAL; + lock_kernel (); + p = (char *)__get_free_page (GFP_KERNEL); + if (!p) goto out; + q = (u32 *)p; + nn = (n + 8 * sizeof(unsigned long) - 1) / (8 * sizeof (unsigned long)); + Inp = (u32 *)A(inp); Outp = (u32 *)A(outp); Exp = (u32 *)A(exp); + ret = -EFAULT; + for (i = 0; i < ret; i++, Inp += 2, Outp += 2, Exp += 2, q += 2) { + if (__get_user (q[1], Inp) || + __get_user (q[0], Inp+1) || + __get_user (q[1+PAGE_SIZE/4], Outp) || + __get_user (q[PAGE_SIZE/4], Outp+1) || + __get_user (q[1+PAGE_SIZE/2], Exp) || + __get_user (q[PAGE_SIZE/2], Exp+1)) + goto out; + } + old_fs = get_fs (); + set_fs (KERNEL_DS); + ret = sys_select(n, (fd_set *)p, (fd_set *)(p + PAGE_SIZE/4), (fd_set *)(p + PAGE_SIZE/2), (struct timeval *)A(tvp)); + set_fs (old_fs); + q = (u32 *)p; + Inp = (u32 *)A(inp); Outp = (u32 *)A(outp); Exp = (u32 *)A(exp); + for (i = 0; i < ret; i++, Inp += 2, Outp += 2, Exp += 2, q += 2) { + if (__put_user (q[1], Inp) || + __put_user (q[0], Inp+1) || + __put_user (q[1+PAGE_SIZE/4], Outp) || + __put_user (q[PAGE_SIZE/4], Outp+1) || + __put_user (q[1+PAGE_SIZE/2], Exp) || + __put_user (q[PAGE_SIZE/2], Exp+1)) { + ret = -EFAULT; + goto out; + } + } +out: + free_page ((unsigned long)p); + return ret; } asmlinkage int sys32_poll(u32 ufds, unsigned int nfds, int timeout) @@ -430,19 +905,62 @@ return sys_poll((struct pollfd *)A(ufds), nfds, timeout); } +static inline int putstat(u32 statbuf, struct stat *s) +{ + if (put_user (s->st_dev, &(((struct stat32 *)A(statbuf))->st_dev)) || + __put_user (s->st_ino, &(((struct stat32 *)A(statbuf))->st_ino)) || + __put_user (s->st_mode, &(((struct stat32 *)A(statbuf))->st_mode)) || + __put_user (s->st_nlink, &(((struct stat32 *)A(statbuf))->st_nlink)) || + __put_user (s->st_uid, &(((struct stat32 *)A(statbuf))->st_uid)) || + __put_user (s->st_gid, &(((struct stat32 *)A(statbuf))->st_gid)) || + __put_user (s->st_rdev, &(((struct stat32 *)A(statbuf))->st_rdev)) || + __put_user (s->st_size, &(((struct stat32 *)A(statbuf))->st_size)) || + __put_user (s->st_atime, &(((struct stat32 *)A(statbuf))->st_atime)) || + __put_user (s->st_mtime, &(((struct stat32 *)A(statbuf))->st_mtime)) || + __put_user (s->st_ctime, &(((struct stat32 *)A(statbuf))->st_ctime)) || + __put_user (s->st_blksize, &(((struct stat32 *)A(statbuf))->st_blksize)) || + __put_user (s->st_blocks, &(((struct stat32 *)A(statbuf))->st_blocks))) + return -EFAULT; + return 0; +} + asmlinkage int sys32_newstat(u32 filename, u32 statbuf) { - return sys_newstat((char *)A(filename), (struct stat *)A(statbuf)); + int ret; + struct stat s; + unsigned long old_fs = get_fs(); + + set_fs (KERNEL_DS); + ret = sys_newstat((char *)A(filename), &s); + set_fs (old_fs); + if (putstat (statbuf, &s)) return -EFAULT; + return ret; } asmlinkage int sys32_newlstat(u32 filename, u32 statbuf) { - return sys_newlstat((char *)A(filename), (struct stat *)A(statbuf)); + int ret; + struct stat s; + unsigned long old_fs = get_fs(); + + set_fs (KERNEL_DS); + ret = sys_newlstat((char *)A(filename), &s); + set_fs (old_fs); + if (putstat (statbuf, &s)) return -EFAULT; + return ret; } asmlinkage int sys32_newfstat(unsigned int fd, u32 statbuf) { - return sys_newfstat(fd, (struct stat *)A(statbuf)); + int ret; + struct stat s; + unsigned long old_fs = get_fs(); + + set_fs (KERNEL_DS); + ret = sys_newfstat(fd, &s); + set_fs (old_fs); + if (putstat (statbuf, &s)) return -EFAULT; + return ret; } asmlinkage int sys32_readlink(u32 path, u32 buf, int bufsiz) @@ -454,7 +972,7 @@ { va_list args; unsigned int x; - int ret; + int ret = -EINVAL; va_start(args, option); switch (option) { @@ -473,6 +991,7 @@ return ret; } +/* Continue here */ asmlinkage int sys32_ustat(dev_t dev, u32 ubuf) { return sys_ustat(dev, (struct ustat *)A(ubuf)); diff -u --recursive v2.1.35/linux/arch/sparc64/kernel/systbls.S linux/arch/sparc64/kernel/systbls.S --- v2.1.35/linux/arch/sparc64/kernel/systbls.S Mon Apr 14 16:28:09 1997 +++ linux/arch/sparc64/kernel/systbls.S Thu Apr 17 13:20:44 1997 @@ -1,4 +1,4 @@ -/* $Id: systbls.S,v 1.5 1997/04/09 08:25:16 jj Exp $ +/* $Id: systbls.S,v 1.6 1997/04/16 10:27:15 jj Exp $ * systbls.S: System call entry point tables for OS compatibility. * The native Linux system call table lives here also. * @@ -56,7 +56,7 @@ .xword sys_setpgid, sys_nis_syscall, sys_nis_syscall, sys_nis_syscall, sys32_newuname /*190*/ .xword sys_nis_syscall, sys32_personality, sys_prof, sys_break, sys_lock .xword sys_mpx, sys_ulimit, sys_getppid, sparc32_sigaction, sys_sgetmask -/*200*/ .xword sys_ssetmask, sys_sigsuspend, sys32_newlstat, sys32_uselib, old_readdir +/*200*/ .xword sys_ssetmask, sys_sigsuspend, sys32_newlstat, sys32_uselib, old32_readdir .xword sys_nis_syscall, sys32_socketcall, sys32_syslog, sys32_olduname, sys_nis_syscall /*210*/ .xword sys_idle, sys_nis_syscall, sys32_waitpid, sys32_swapoff, sys32_sysinfo .xword sys32_ipc, sys_sigreturn, sys_clone, sys_nis_syscall, sys32_adjtimex diff -u --recursive v2.1.35/linux/arch/sparc64/mm/init.c linux/arch/sparc64/mm/init.c --- v2.1.35/linux/arch/sparc64/mm/init.c Mon Apr 14 16:28:10 1997 +++ linux/arch/sparc64/mm/init.c Thu Apr 17 13:20:44 1997 @@ -1,4 +1,4 @@ -/* $Id: init.c,v 1.22 1997/04/12 04:28:48 davem Exp $ +/* $Id: init.c,v 1.23 1997/04/16 10:27:18 jj Exp $ * arch/sparc64/mm/init.c * * Copyright (C) 1996,1997 David S. Miller (davem@caip.rutgers.edu) @@ -32,6 +32,9 @@ unsigned long tlb_context_cache = CTX_FIRST_VERSION; +/* References to section boundaries */ +extern char __init_begin, __init_end, etext, __p1275_loc, __bss_start; + /* * BAD_PAGE is the page that is used for page faults when linux * is out-of-memory. Older versions of linux just did a @@ -268,6 +271,7 @@ char *mmu_info(void) { + /* XXX */ return "MMU Type: Spitfire\n\tFIXME: Write this\n"; } @@ -436,15 +440,6 @@ else pte = mk_pte_phys(physaddr, __pgprot(pg_iobits | __DIRTY_BITS)); -#if 0 - prom_printf("IOMAP: vaddr[%016lx]paddr[%016lx]ptep[%016lx]pte[%016lx])\n", - virt_addr, physaddr, (unsigned long) ptep, pte_val(pte)); - prom_printf("IOMAP: pgd[%016lx,%016lx]\n", - (unsigned long) pgdp, pgd_val(*pgdp)); - prom_printf("IOMAP: pmd[%016lx,%016lx]\n", - (unsigned long) pmdp, pmd_val(*pmdp)); -#endif - set_pte(ptep, pte); } @@ -462,6 +457,7 @@ pte_clear(ptep); } +#ifdef DEBUG_MMU void sparc_ultra_dump_itlb(void) { int slot; @@ -485,6 +481,7 @@ slot+1, spitfire_get_dtlb_tag(slot+1), spitfire_get_dtlb_data(slot+1)); } } +#endif /* paging_init() sets up the page tables */ @@ -493,7 +490,6 @@ __initfunc(unsigned long paging_init(unsigned long start_mem, unsigned long end_mem)) { - extern unsigned long __p1275_loc; extern unsigned long phys_base; extern void setup_tba(unsigned long kpgdir); extern void __bfill64(void *, unsigned long); @@ -637,9 +633,10 @@ { int codepages = 0; int datapages = 0; + int initpages = 0; + int prompages = 0; unsigned long tmp2, addr; unsigned long data_end; - extern char etext; end_mem &= PAGE_MASK; max_mapnr = MAP_NR(end_mem); @@ -665,6 +662,10 @@ if(PageReserved(mem_map + MAP_NR(addr))) { if ((addr < (unsigned long) &etext) && (addr >= PAGE_OFFSET)) codepages++; + else if((addr >= (unsigned long)&__init_begin && addr < (unsigned long)&__init_end)) + initpages++; + else if((addr >= (unsigned long)&__p1275_loc && addr < (unsigned long)&__bss_start)) + prompages++; else if((addr < data_end) && (addr >= PAGE_OFFSET)) datapages++; continue; @@ -680,26 +681,23 @@ tmp2 = nr_free_pages << PAGE_SHIFT; - printk("Memory: %luk available (%dk kernel code, %dk data) [%016lx,%016lx]\n", + printk("Memory: %luk available (%dk kernel code, %dk data, %dk init, %dk prom) [%016lx,%016lx]\n", tmp2 >> 10, codepages << (PAGE_SHIFT-10), - datapages << (PAGE_SHIFT-10), PAGE_OFFSET, end_mem); + datapages << (PAGE_SHIFT-10), + initpages << (PAGE_SHIFT-10), + prompages << (PAGE_SHIFT-10), + PAGE_OFFSET, end_mem); min_free_pages = nr_free_pages >> 7; if(min_free_pages < 16) min_free_pages = 16; free_pages_low = min_free_pages + (min_free_pages >> 1); free_pages_high = min_free_pages + min_free_pages; - -#if 0 - printk("Done in mem_init() halting\n"); - prom_cmdline(); -#endif } void free_initmem (void) { - extern char __init_begin, __init_end; unsigned long addr; addr = (unsigned long)(&__init_begin); diff -u --recursive v2.1.35/linux/drivers/Makefile linux/drivers/Makefile --- v2.1.35/linux/drivers/Makefile Sun Apr 13 10:18:20 1997 +++ linux/drivers/Makefile Thu Apr 17 14:48:53 1997 @@ -7,17 +7,12 @@ # # Note 2! The CFLAGS definitions are now in the main makefile... -SUB_DIRS := block char net #streams +SUB_DIRS := block char net pnp #streams MOD_SUB_DIRS := $(SUB_DIRS) sbus ALL_SUB_DIRS := $(SUB_DIRS) pci scsi sbus sound cdrom isdn pnp ifdef CONFIG_PCI SUB_DIRS += pci -endif - -ifdef CONFIG_PNP -SUB_DIRS += pnp -MOD_SUB_DIRS += pnp endif ifdef CONFIG_SBUS diff -u --recursive v2.1.35/linux/drivers/block/acsi.c linux/drivers/block/acsi.c --- v2.1.35/linux/drivers/block/acsi.c Fri Dec 20 01:19:59 1996 +++ linux/drivers/block/acsi.c Thu Apr 17 13:20:44 1997 @@ -43,8 +43,6 @@ * */ -#include - #define MAJOR_NR ACSI_MAJOR #include @@ -1127,9 +1125,8 @@ * ACSI disks... */ case BLKGETSIZE: /* Return device size */ - if (put_user(acsi_part[MINOR(inode->i_rdev)].nr_sects, - (long *)arg)) - return -EFAULT; + return put_user(acsi_part[MINOR(inode->i_rdev)].nr_sects, + (long *) arg); case BLKFLSBUF: if(!suser()) return -EACCES; if(!inode->i_rdev) return -EINVAL; @@ -1629,33 +1626,23 @@ return DEV_SUPPORTED; } -#ifdef CONFIG_ATARI_SLM_MODULE -void acsi_attach_SLMs( int (*attach_func)( int, int ) ); -#endif +EXPORT_SYMBOL(acsi_delay_start); +EXPORT_SYMBOL(acsi_delay_end); +EXPORT_SYMBOL(acsi_wait_for_IRQ); +EXPORT_SYMBOL(acsi_wait_for_noIRQ); +EXPORT_SYMBOL(acsicmd_nodma); +EXPORT_SYMBOL(acsi_getstatus); +EXPORT_SYMBOL(acsi_buffer); +EXPORT_SYMBOL(phys_acsi_buffer); -static struct symbol_table acsi_symbol_table = -{ -#include - - X(acsi_delay_start), - X(acsi_delay_end), - X(acsi_wait_for_IRQ), - X(acsi_wait_for_noIRQ), - X(acsicmd_nodma), - X(acsi_getstatus), - X(acsi_buffer), - X(phys_acsi_buffer), #ifdef CONFIG_ATARI_SLM_MODULE - X(acsi_extstatus), - X(acsi_end_extstatus), - X(acsi_extcmd), - X(acsi_attach_SLMs), -#endif +void acsi_attach_SLMs( int (*attach_func)( int, int ) ); -#include -}; +EXPORT_SYMBOL(acsi_extstatus); +EXPORT_SYMBOL(acsi_end_extstatus); +EXPORT_SYMBOL(acsi_extcmd); +EXPORT_SYMBOL(acsi_attach_SLMs); -#ifdef CONFIG_ATARI_SLM_MODULE /* to remember IDs of SLM devices, SLM module is loaded later * (index is target#, contents is lun#, -1 means "no SLM") */ int SLM_devices[8]; @@ -1751,7 +1738,6 @@ for( i = 0; i < (MAX_DEV << 4); i++ ) acsi_blocksizes[i] = 1024; blksize_size[MAJOR_NR] = acsi_blocksizes; - register_symtab (&acsi_symbol_table); } #ifdef CONFIG_ATARI_SLM_MODULE diff -u --recursive v2.1.35/linux/drivers/block/amiflop.c linux/drivers/block/amiflop.c --- v2.1.35/linux/drivers/block/amiflop.c Fri Apr 4 08:52:17 1997 +++ linux/drivers/block/amiflop.c Thu Apr 17 13:20:44 1997 @@ -56,6 +56,7 @@ #include #include #include +#include #include #include #include @@ -401,6 +402,7 @@ restore_flags(flags); if (on_attempts == 0) { + on_attempts = -1; #if 0 printk (KERN_ERR "motor_on failed, turning motor off\n"); fd_motor_off (nr); @@ -1511,93 +1513,103 @@ int error; unsigned long flags; - switch(cmd) - { - case FDFMTBEG: - get_hw(drive); - if (fd_ref[drive] > 1) { - rel_hw(); - return -EBUSY; - } - fsync_dev(inode->i_rdev); - if (motor_on(drive) == 0) { - rel_hw(); - return -ENODEV; - } - if (fd_calibrate(drive) == 0) { - rel_hw(); - return -ENXIO; - } - floppy_off(drive); - rel_hw(); - break; - case FDFMTTRK: - if (param < unit[drive].type->tracks * unit[drive].type->heads) - { - get_fdc(drive); - get_hw(drive); - fd_select(drive); - if (fd_seek(drive,param)!=0) - { - savedtrack=param; - memset(trackdata,FD_FILL_BYTE,unit[drive].sects*512); - non_int_flush_track(drive); - } - floppy_off(drive); - rel_hw(); - rel_fdc(); - } - else - return -EINVAL; - break; - case FDFMTEND: - floppy_off(drive); - invalidate_inodes(inode->i_rdev); - invalidate_buffers(inode->i_rdev); - break; - case FDGETPRM: - error = verify_area(VERIFY_WRITE, (void *)param, - sizeof(struct floppy_struct)); - if (error) - return error; - memset((void *)&getprm, 0, sizeof (getprm)); - getprm.track=unit[drive].type->tracks; - getprm.head=unit[drive].type->heads; - getprm.sect=unit[drive].sects; - getprm.size=unit[drive].blocks; - copy_to_user((void *)param,(void *)&getprm,sizeof(struct floppy_struct)); + switch(cmd){ + case HDIO_GETGEO: + { + struct hd_geometry loc; + loc.heads = unit[drive].type->heads; + loc.sectors = unit[drive].sects; + loc.cylinders = unit[drive].type->tracks; + loc.start = 0; + if ((error = copy_to_user((void *)param, (void *)&loc, + sizeof(struct hd_geometry)))) + return error; + break; + } + case FDFMTBEG: + get_hw(drive); + if (fd_ref[drive] > 1) { + rel_hw(); + return -EBUSY; + } + fsync_dev(inode->i_rdev); + if (motor_on(drive) == 0) { + rel_hw(); + return -ENODEV; + } + if (fd_calibrate(drive) == 0) { + rel_hw(); + return -ENXIO; + } + floppy_off(drive); + rel_hw(); + break; + case FDFMTTRK: + if (param < unit[drive].type->tracks * unit[drive].type->heads) + { + get_fdc(drive); + get_hw(drive); + fd_select(drive); + if (fd_seek(drive,param)!=0){ + savedtrack=param; + memset(trackdata, FD_FILL_BYTE, + unit[drive].sects*512); + non_int_flush_track(drive); + } + floppy_off(drive); + rel_hw(); + rel_fdc(); + } + else + return -EINVAL; + break; + case FDFMTEND: + floppy_off(drive); + invalidate_inodes(inode->i_rdev); + invalidate_buffers(inode->i_rdev); + break; + case FDGETPRM: + memset((void *)&getprm, 0, sizeof (getprm)); + getprm.track=unit[drive].type->tracks; + getprm.head=unit[drive].type->heads; + getprm.sect=unit[drive].sects; + getprm.size=unit[drive].blocks; + if ((error = copy_to_user((void *)param, + (void *)&getprm, + sizeof(struct floppy_struct)))) + return error; break; - case BLKGETSIZE: - if (put_user(unit[drive].blocks,(long *)param)) - return -EFAULT; - break; - case FDSETPRM: - case FDDEFPRM: - return -EINVAL; - case FDFLUSH: - save_flags(flags); - cli(); - if ((drive == selected) && (writepending)) { - del_timer (&flush_track_timer); - restore_flags(flags); - non_int_flush_track(selected); - } - else - restore_flags(flags); - break; + case BLKGETSIZE: + if (put_user(unit[drive].blocks,(long *)param)) + return -EFAULT; + break; + case FDSETPRM: + case FDDEFPRM: + return -EINVAL; + case FDFLUSH: + save_flags(flags); + cli(); + if ((drive == selected) && (writepending)) { + del_timer (&flush_track_timer); + restore_flags(flags); + non_int_flush_track(selected); + } + else + restore_flags(flags); + break; #ifdef RAW_IOCTL - case IOCTL_RAW_TRACK: - error = verify_area(VERIFY_WRITE, (void *)param, - unit[drive].type->read_size); - if (error) - return error; - copy_to_user((void *)param, raw_buf, unit[drive].type->read_size); - return unit[drive].type->read_size; + case IOCTL_RAW_TRACK: + error = copy_to_user((void *)param, raw_buf, + unit[drive].type->read_size); + if (error) + return error; + else + return unit[drive].type->read_size; #endif - default: - printk(KERN_DEBUG "fd_ioctl: unknown cmd %d for drive %d.",cmd,drive); - return -ENOSYS; - } + default: + printk(KERN_DEBUG "fd_ioctl: unknown cmd %d for drive %d.",cmd,drive); + return -ENOSYS; + } return 0; } diff -u --recursive v2.1.35/linux/drivers/block/ataflop.c linux/drivers/block/ataflop.c --- v2.1.35/linux/drivers/block/ataflop.c Fri Apr 4 08:52:17 1997 +++ linux/drivers/block/ataflop.c Thu Apr 17 13:20:44 1997 @@ -52,6 +52,9 @@ * Michael (MSch) 11/07/96: * - implemented FDSETPRM and FDDEFPRM ioctl * + * Andreas (97/03/19): + * - implemented missing BLK* ioctls + * * Things left to do: * - Formatting * - Maybe a better strategy for disk change detection (does anyone @@ -281,6 +284,7 @@ static unsigned long PhysDMABuffer; /* physical address */ static int UseTrackbuffer = -1; /* Do track buffering? */ +MODULE_PARM(UseTrackbuffer, "i"); unsigned char *TrackBuffer; /* buffer for reads */ static unsigned long PhysTrackBuffer; /* physical address */ @@ -305,6 +309,7 @@ static int IsFormatting = 0, FormatError; static int UserSteprate[FD_MAX_UNITS] = { -1, -1 }; +MODULE_PARM(UserSteprate, "1-" __MODULE_STRING(FD_MAX_UNITS) "i"); /* Synchronization of FDC access. */ static volatile int fdc_busy = 0; @@ -405,7 +410,7 @@ static int fd_test_drive_present( int drive ); static void config_types( void ); static int floppy_open( struct inode *inode, struct file *filp ); -static void floppy_release( struct inode * inode, struct file * filp ); +static int floppy_release( struct inode * inode, struct file * filp ); /************************* End of Prototypes **************************/ @@ -1582,6 +1587,7 @@ drive &= 3; switch (cmd) { case FDGETPRM: + case BLKGETSIZE: if (type) { if (--type >= NUM_DISK_MINORS) return -ENODEV; @@ -1599,6 +1605,9 @@ else dtp = UDT; } + if (cmd == BLKGETSIZE) + return put_user(dtp->blocks, (long *)param); + memset((void *)&getprm, 0, sizeof(getprm)); getprm.size = dtp->blocks; getprm.sect = dtp->spt; @@ -1607,6 +1616,22 @@ getprm.stretch = dtp->stretch; if (copy_to_user((void *)param, &getprm, sizeof(getprm))) return -EFAULT; + return 0; + case BLKRASET: + if (!suser()) + return -EACCES; + if (param > 0xff) + return -EINVAL; + read_ahead[MAJOR(inode->i_rdev)] = param; + return 0; + case BLKRAGET: + return put_user(read_ahead[MAJOR(inode->i_rdev)], + (int *) param); + case BLKFLSBUF: + if (!suser()) + return -EACCES; + fsync_dev(inode->i_rdev); + invalidate_buffers(inode->i_rdev); return 0; } if (!IOCTL_ALLOWED) diff -u --recursive v2.1.35/linux/drivers/block/floppy.c linux/drivers/block/floppy.c --- v2.1.35/linux/drivers/block/floppy.c Mon Apr 14 16:28:11 1997 +++ linux/drivers/block/floppy.c Tue Apr 15 22:26:28 1997 @@ -1676,10 +1676,13 @@ } while ((ST0 & 0x83) != UNIT(current_drive) && inr == 2); } if (handler) { - if (in_interrupt()) - schedule_bh( (void *)(void *) handler); - else + if(softirq_trylock()) { + /* got the lock, call the handler immediately */ handler(); + softirq_endlock(); + } else + /* we interrupted a bottom half. Defer handler */ + schedule_bh( (void *)(void *) handler); } else FDCS->reset = 1; is_alive("normal interrupt end"); diff -u --recursive v2.1.35/linux/drivers/block/genhd.c linux/drivers/block/genhd.c --- v2.1.35/linux/drivers/block/genhd.c Sun Apr 13 10:18:20 1997 +++ linux/drivers/block/genhd.c Thu Apr 17 13:20:44 1997 @@ -25,6 +25,7 @@ #include #include #include +#include #include @@ -739,7 +740,7 @@ } } -static void setup_dev(struct gendisk *dev) +static inline void setup_dev(struct gendisk *dev) { int i, drive; int end_minor = dev->max_nr * dev->max_p; @@ -762,7 +763,7 @@ } } -void device_setup(void) +__initfunc(void device_setup(void)) { extern void console_map_init(void); #ifdef CONFIG_PNP_PARPORT diff -u --recursive v2.1.35/linux/drivers/block/ll_rw_blk.c linux/drivers/block/ll_rw_blk.c --- v2.1.35/linux/drivers/block/ll_rw_blk.c Thu Mar 27 14:40:02 1997 +++ linux/drivers/block/ll_rw_blk.c Thu Apr 17 13:20:44 1997 @@ -16,6 +16,7 @@ #include #include #include +#include #include #include @@ -631,7 +632,7 @@ extern void bpcd_init( void ); #endif -int blk_dev_init(void) +__initfunc(int blk_dev_init(void)) { struct request * req; struct blk_dev_struct *dev; diff -u --recursive v2.1.35/linux/drivers/block/rd.c linux/drivers/block/rd.c --- v2.1.35/linux/drivers/block/rd.c Fri Apr 4 08:52:18 1997 +++ linux/drivers/block/rd.c Thu Apr 17 13:20:44 1997 @@ -200,7 +200,7 @@ { unsigned long i; - if (--initrd_users) return; + if (--initrd_users) return 0; for (i = initrd_start; i < initrd_end; i += PAGE_SIZE) free_page(i); initrd_start = 0; @@ -405,11 +405,11 @@ } /* Try ext2 */ - if (ext2sb->s_magic == EXT2_SUPER_MAGIC) { + if (ext2sb->s_magic == cpu_to_le16(EXT2_SUPER_MAGIC)) { printk(KERN_NOTICE "RAMDISK: Ext2 filesystem found at block %d\n", start_block); - nblocks = ext2sb->s_blocks_count; + nblocks = le32_to_cpu(ext2sb->s_blocks_count); goto done; } diff -u --recursive v2.1.35/linux/drivers/block/z2ram.c linux/drivers/block/z2ram.c --- v2.1.35/linux/drivers/block/z2ram.c Sun Jan 26 02:07:11 1997 +++ linux/drivers/block/z2ram.c Thu Apr 17 13:20:44 1997 @@ -36,7 +36,7 @@ #include #include #include -#include +#include #define TRUE (1) #define FALSE (0) diff -u --recursive v2.1.35/linux/drivers/char/Makefile linux/drivers/char/Makefile --- v2.1.35/linux/drivers/char/Makefile Fri Apr 4 08:52:18 1997 +++ linux/drivers/char/Makefile Thu Apr 17 13:20:45 1997 @@ -43,6 +43,16 @@ endif endif +ifeq ($(CONFIG_ATARI_DSP56K),y) +L_OBJS += dsp56k.o +S = y +else + ifeq ($(CONFIG_ATARI_DSP56K),m) + M_OBJS += dsp56k.o + SM = y + endif +endif + ifeq ($(CONFIG_DIGI),y) L_OBJS += pcxx.o else diff -u --recursive v2.1.35/linux/drivers/char/amigamouse.c linux/drivers/char/amigamouse.c --- v2.1.35/linux/drivers/char/amigamouse.c Fri Apr 4 08:52:18 1997 +++ linux/drivers/char/amigamouse.c Thu Apr 17 13:20:45 1997 @@ -172,11 +172,11 @@ * close access to the mouse */ -static int close_mouse(struct inode * inode, struct file * file) +static int release_mouse(struct inode * inode, struct file * file) { fasync_mouse(inode, file, 0); if (--mouse.active) - return; + return 0; free_irq(IRQ_AMIGA_VERTB, mouse_interrupt); MSE_INT_OFF(); MOD_DEC_USE_COUNT; @@ -299,7 +299,7 @@ NULL, /* mouse_ioctl */ NULL, /* mouse_mmap */ open_mouse, - close_mouse, + release_mouse, NULL, fasync_mouse, }; diff -u --recursive v2.1.35/linux/drivers/char/atarimouse.c linux/drivers/char/atarimouse.c --- v2.1.35/linux/drivers/char/atarimouse.c Fri Apr 4 08:52:18 1997 +++ linux/drivers/char/atarimouse.c Thu Apr 17 13:20:45 1997 @@ -27,7 +27,8 @@ #include static struct mouse_status mouse; -static int atari_mouse_x_threshold = 2, atari_mouse_y_threshold = 2; +static int mouse_threshold[2] = {2,2}; +MODULE_PARM(mouse_threshold, "2i"); extern int atari_mouse_buttons; static void atari_mouse_interrupt(char *buf) @@ -82,7 +83,7 @@ mouse.dx = mouse.dy = 0; atari_mouse_buttons = 0; ikbd_mouse_y0_top (); - ikbd_mouse_thresh (atari_mouse_x_threshold, atari_mouse_y_threshold); + ikbd_mouse_thresh (mouse_threshold[0], mouse_threshold[1]); ikbd_mouse_rel_pos(); MOD_INC_USE_COUNT; atari_mouse_interrupt_hook = atari_mouse_interrupt; @@ -99,12 +100,9 @@ char *buffer, unsigned long count) { int dx, dy, buttons; - int r; if (count < 3) return -EINVAL; - if ((r = verify_area(VERIFY_WRITE, buffer, count))) - return r; if (!mouse.ready) return -EAGAIN; /* ikbd_mouse_disable */ @@ -124,12 +122,14 @@ if (mouse.dx == 0 && mouse.dy == 0) mouse.ready = 0; /* ikbd_mouse_rel_pos(); */ - put_user(buttons | 0x80, buffer); - put_user((char) dx, buffer + 1); - put_user((char) dy, buffer + 2); - for (r = 3; r < count; r++) - put_user (0, buffer + r); - return r; + if (put_user(buttons | 0x80, buffer++) || + put_user((char) dx, buffer++) || + put_user((char) dy, buffer++)) + return -EFAULT; + if (count > 3) + if (clear_user(buffer, count - 3)) + return -EFAULT; + return count; } static unsigned int mouse_poll(struct file *file, poll_table *wait) @@ -188,13 +188,13 @@ if (ints[1] < MIN_THRESHOLD || ints[1] > MAX_THRESHOLD) printk( "atari_mouse_setup: bad threshold value (ignored)\n" ); else { - atari_mouse_x_threshold = ints[1]; - atari_mouse_y_threshold = ints[1]; + mouse_threshold[0] = ints[1]; + mouse_threshold[1] = ints[1]; if (ints[0] > 1) { if (ints[2] < MIN_THRESHOLD || ints[2] > MAX_THRESHOLD) printk("atari_mouse_setup: bad threshold value (ignored)\n" ); else - atari_mouse_y_threshold = ints[2]; + mouse_threshold[1] = ints[2]; } } Only in linux/drivers/char: dsp56k.c diff -u --recursive v2.1.35/linux/drivers/char/lp.c linux/drivers/char/lp.c --- v2.1.35/linux/drivers/char/lp.c Mon Apr 14 16:28:11 1997 +++ linux/drivers/char/lp.c Thu Apr 17 14:48:53 1997 @@ -693,24 +693,27 @@ pb = parport_enumerate(); while (pb) { - if (parport[0] == -1 || lp_searchfor(parport, count) || - (parport[0] == -3 && - pb->probe_info.class == PARPORT_CLASS_PRINTER)) { - lp_table[count].dev = - parport_register_device(pb, dev_name, NULL, - lp_wakeup, - lp_interrupt, PARPORT_DEV_TRAN, - (void *) &lp_table[count]); - lp_table[count].flags |= LP_EXIST; - printk(KERN_INFO "lp%d: using %s at 0x%x, ", count, - pb->name, pb->base); - if (pb->irq == -1) - printk("polling.\n"); - else - printk("irq %d.\n", pb->irq); + /* We only understand PC-style ports. */ + if (pb->modes & PARPORT_MODE_SPP) { + if (parport[0] == -1 || lp_searchfor(parport, count) || + (parport[0] == -3 && + pb->probe_info.class == PARPORT_CLASS_PRINTER)) { + lp_table[count].dev = + parport_register_device(pb, dev_name, NULL, + lp_wakeup, + lp_interrupt, PARPORT_DEV_TRAN, + (void *) &lp_table[count]); + lp_table[count].flags |= LP_EXIST; + printk(KERN_INFO "lp%d: using %s at 0x%x, ", + count, pb->name, pb->base); + if (pb->irq == -1) + printk("polling.\n"); + else + printk("irq %d.\n", pb->irq); + } + if (++count == LP_NO) + break; } - if (++count == LP_NO) - break; pb = pb->next; } diff -u --recursive v2.1.35/linux/drivers/char/lp_m68k.c linux/drivers/char/lp_m68k.c --- v2.1.35/linux/drivers/char/lp_m68k.c Fri Apr 4 08:52:19 1997 +++ linux/drivers/char/lp_m68k.c Thu Apr 17 13:20:45 1997 @@ -34,8 +34,8 @@ * */ -#include #include +#include #include #include #include @@ -139,40 +139,35 @@ static int lp_error; -void lp_interrupt(int irq, void *dummy, struct pt_regs *fp) +void lp_interrupt(int dev) { - unsigned long flags; - int dev; - - for (dev = 0; dev < MAX_LP; dev++) { - if ((lp_table[dev] != NULL) && (lp_table[dev]->lp_my_interrupt(dev) != 0)) - if (lp_table[dev]->do_print) - { - if (lp_table[dev]->copy_size) - { - save_flags(flags); - cli(); - if (lp_char_interrupt(lp_table[dev]->lp_buffer[lp_table[dev]->bytes_written], dev)) { - --lp_table[dev]->copy_size; - ++lp_table[dev]->bytes_written; - restore_flags(flags); - } - else - { - lp_table[dev]->do_print = 0; - restore_flags(flags); - lp_error = 1; - wake_up_interruptible(&lp_table[dev]->lp_wait_q); - } - } - else - { - lp_table[dev]->do_print = 0; - lp_error = 0; - wake_up_interruptible(&lp_table[dev]->lp_wait_q); - } + if (dev >= 0 && dev < MAX_LP && lp_table[dev]->do_print) + { + if (lp_table[dev]->copy_size) + { + unsigned long flags; + save_flags(flags); + cli(); + if (lp_char_interrupt(lp_table[dev]->lp_buffer[lp_table[dev]->bytes_written], dev)) { + --lp_table[dev]->copy_size; + ++lp_table[dev]->bytes_written; + restore_flags(flags); + } + else + { + lp_table[dev]->do_print = 0; + restore_flags(flags); + lp_error = 1; + wake_up_interruptible(&lp_table[dev]->lp_wait_q); + } + } + else + { + lp_table[dev]->do_print = 0; + lp_error = 0; + wake_up_interruptible(&lp_table[dev]->lp_wait_q); + } - } } } @@ -366,6 +361,7 @@ static int lp_open(struct inode *inode, struct file *file) { int dev = MINOR(inode->i_rdev); + int ret; if (dev >= MAX_LP) return -ENODEV; @@ -386,10 +382,14 @@ lp_table[dev]->flags |= LP_BUSY; - MOD_INC_USE_COUNT; - lp_table[dev]->lp_open(); - - return 0; + ret = lp_table[dev]->lp_open(dev); + if (ret != 0) { + lp_table[dev]->flags &= ~LP_BUSY; + } + else { + MOD_INC_USE_COUNT; + } + return ret; } static int lp_release(struct inode *inode, struct file *file) @@ -397,7 +397,7 @@ int dev =MINOR(inode->i_rdev); lp_table[dev]->flags &= ~LP_BUSY; - lp_table[dev]->lp_release(); + lp_table[dev]->lp_release(dev); MOD_DEC_USE_COUNT; return 0; } @@ -458,18 +458,12 @@ lp_release }; -#ifdef CONFIG_MODULES -static struct symbol_table parallel_syms = { -#include - X(lp_table), - X(lp_irq), - X(lp_interrupt), - X(lp_init), - X(register_parallel), - X(unregister_parallel), -#include -}; -#endif +EXPORT_SYMBOL(lp_table); +EXPORT_SYMBOL(lp_irq); +EXPORT_SYMBOL(lp_interrupt); +EXPORT_SYMBOL(lp_init); +EXPORT_SYMBOL(register_parallel); +EXPORT_SYMBOL(unregister_parallel); int lp_init(void) { @@ -482,14 +476,6 @@ printk(KERN_ERR "unable to get major %d for line printer\n", LP_MAJOR); return -ENXIO; } - -#ifdef CONFIG_MODULES - if (register_symtab(¶llel_syms)) { - unregister_chrdev(LP_MAJOR, "lp"); - printk(KERN_CRIT "unable to register parallel symtab\n"); - return -ENXIO; - } -#endif #if WHICH_DRIVER == FORCE_POLLING lp_irq = 0; diff -u --recursive v2.1.35/linux/drivers/char/mem.c linux/drivers/char/mem.c --- v2.1.35/linux/drivers/char/mem.c Sat Jan 25 13:46:13 1997 +++ linux/drivers/char/mem.c Thu Apr 17 13:20:45 1997 @@ -19,6 +19,7 @@ #include #include #include +#include #include #include @@ -491,7 +492,7 @@ NULL /* fsync */ }; -int chr_dev_init(void) +__initfunc(int chr_dev_init(void)) { if (register_chrdev(MEM_MAJOR,"mem",&memory_fops)) printk("unable to get major %d for memory devs\n", MEM_MAJOR); diff -u --recursive v2.1.35/linux/drivers/char/vt.c linux/drivers/char/vt.c --- v2.1.35/linux/drivers/char/vt.c Mon Apr 14 16:28:11 1997 +++ linux/drivers/char/vt.c Thu Apr 17 09:20:38 1997 @@ -311,7 +311,7 @@ int sz; int delta; char *first_free, *fj, *fnw; - int j, k, i = 0; + int i, j, k; /* we mostly copy too much here (512bytes), but who cares ;) */ if (copy_from_user(&tmp, user_kdgkb, sizeof(struct kbsentry))) @@ -319,6 +319,7 @@ tmp.kb_string[sizeof(tmp.kb_string)-1] = '\0'; if (tmp.kb_func >= MAX_NR_FUNC) return -EINVAL; + i = tmp.kb_func; switch (cmd) { case KDGKBSENT: diff -u --recursive v2.1.35/linux/drivers/isdn/sc/init.c linux/drivers/isdn/sc/init.c --- v2.1.35/linux/drivers/isdn/sc/init.c Thu Feb 27 10:57:30 1997 +++ linux/drivers/isdn/sc/init.c Thu Apr 17 09:23:17 1997 @@ -305,7 +305,7 @@ /* * No interrupt could be used */ - pr_debug("Failed to aquire an IRQ line\n"); + pr_debug("Failed to acquire an IRQ line\n"); continue; } diff -u --recursive v2.1.35/linux/drivers/net/Config.in linux/drivers/net/Config.in --- v2.1.35/linux/drivers/net/Config.in Sun Apr 13 10:18:21 1997 +++ linux/drivers/net/Config.in Tue Apr 15 21:47:23 1997 @@ -73,7 +73,7 @@ if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then tristate 'Ansel Communications EISA 3200 support (EXPERIMENTAL)' CONFIG_AC3200 fi - + tristate 'Apricot Xen-II on board ethernet' CONFIG_APRICOT tristate 'CS89x0 support' CONFIG_CS89x0 tristate 'Generic DECchip & DIGITAL EtherWORKS PCI/EISA' CONFIG_DE4X5 diff -u --recursive v2.1.35/linux/drivers/net/Space.c linux/drivers/net/Space.c --- v2.1.35/linux/drivers/net/Space.c Sun Apr 13 10:18:21 1997 +++ linux/drivers/net/Space.c Thu Apr 17 13:20:45 1997 @@ -30,6 +30,7 @@ #include #include #include +#include #define NEXT_DEV NULL @@ -93,7 +94,7 @@ extern int de600_probe(struct device *); extern int de620_probe(struct device *); -static int ethif_probe(struct device *dev) +__initfunc(static int ethif_probe(struct device *dev)) { u_long base_addr = dev->base_addr; diff -u --recursive v2.1.35/linux/drivers/net/a2065.c linux/drivers/net/a2065.c --- v2.1.35/linux/drivers/net/a2065.c Fri Apr 4 08:52:20 1997 +++ linux/drivers/net/a2065.c Thu Apr 17 13:20:45 1997 @@ -55,7 +55,7 @@ #include #include -#include +#include #include #include @@ -302,14 +302,16 @@ lp->stats.rx_errors++; continue; } else if (bits & LE_R1_ERR) { - /* Count only the end frame as a tx error, not the beginning */ + /* Count only the end frame as a rx error, + * not the beginning + */ if (bits & LE_R1_BUF) lp->stats.rx_fifo_errors++; if (bits & LE_R1_CRC) lp->stats.rx_crc_errors++; if (bits & LE_R1_OFL) lp->stats.rx_over_errors++; if (bits & LE_R1_FRA) lp->stats.rx_frame_errors++; if (bits & LE_R1_EOP) lp->stats.rx_errors++; } else { - len = rd->mblength; + len = (rd->mblength & 0xfff) - 4; skb = dev_alloc_skb (len+2); if (skb == 0) { @@ -582,6 +584,16 @@ return status; } + if (skb == NULL) { + dev_tint (dev); + printk ("skb is NULL\n"); + return 0; + } + + if (skb->len <= 0) { + printk ("skb len is %d\n", skb->len); + return 0; + } /* Block a timer-based transmit from overlapping. */ #ifdef OLD_METHOD dev->tbusy = 1; @@ -698,18 +710,13 @@ struct lance_private *lp = (struct lance_private *) dev->priv; volatile struct lance_init_block *ib = lp->init_block; volatile struct lance_regs *ll = lp->ll; - char shown; - shown = 0; while (dev->tbusy) - if (!shown++) - printk ("Waiting for tbusy to go down\n"); + schedule(); set_bit (0, (void *) &dev->tbusy); - shown = 0; while (lp->tx_old != lp->tx_new) - if (!shown) - printk ("Waiting for buffer to empty\n"); + schedule(); ll->rap = LE_CSR0; ll->rdp = LE_C0_STOP; diff -u --recursive v2.1.35/linux/drivers/net/ariadne.c linux/drivers/net/ariadne.c --- v2.1.35/linux/drivers/net/ariadne.c Fri Apr 4 08:52:20 1997 +++ linux/drivers/net/ariadne.c Thu Apr 17 13:20:45 1997 @@ -53,7 +53,7 @@ #include #include #include -#include +#include #include #include @@ -365,7 +365,7 @@ if (ariadne_debug > 1) { printk("%s: Shutting down ethercard, status was %2.2x.\n", dev->name, board->Lance.RDP); - printk("%s: %d packets missed\n", dev->name, + printk("%s: %lu packets missed\n", dev->name, priv->stats.rx_missed_errors); } diff -u --recursive v2.1.35/linux/drivers/net/atari_bionet.c linux/drivers/net/atari_bionet.c --- v2.1.35/linux/drivers/net/atari_bionet.c Fri Apr 4 08:52:20 1997 +++ linux/drivers/net/atari_bionet.c Thu Apr 17 13:20:45 1997 @@ -80,12 +80,7 @@ static char *version = "bionet.c:v1.0 06-feb-96 (c) Hartmut Laue.\n"; -#ifdef MODULE #include -#else -#define MOD_INC_USE_COUNT -#define MOD_DEC_USE_COUNT -#endif #include #include @@ -596,22 +591,13 @@ #ifdef MODULE -#include - -/* We should include the kernel identification string in the module. - */ -static char kernel_version[] = UTS_RELEASE; - -#undef NEXT_DEV -#define NEXT_DEV (&bio_dev) - static char bio_name[16]; static struct device bio_dev = { bio_name, /* filled in by register_netdev() */ 0, 0, 0, 0, /* memory */ 0, 0, /* base, irq */ - 0, 0, 0, NEXT_DEV, bionet_probe, + 0, 0, 0, NULL, bionet_probe, }; int diff -u --recursive v2.1.35/linux/drivers/net/atari_pamsnet.c linux/drivers/net/atari_pamsnet.c --- v2.1.35/linux/drivers/net/atari_pamsnet.c Fri Apr 4 08:52:20 1997 +++ linux/drivers/net/atari_pamsnet.c Thu Apr 17 13:20:45 1997 @@ -77,12 +77,7 @@ static char *version = "pamsnet.c:v0.2beta 30-mar-96 (c) Torsten Lang.\n"; -#ifdef MODULE #include -#else -#define MOD_INC_USE_COUNT -#define MOD_DEC_USE_COUNT -#endif #include #include @@ -868,21 +863,12 @@ #ifdef MODULE -#include - -/* We should include the kernel identification string in the module. - */ -static char kernel_version[] = UTS_RELEASE; - -#undef NEXT_DEV -#define NEXT_DEV (&pam_dev) - static struct device pam_dev = { " ", /* filled in by register_netdev() */ 0, 0, 0, 0, /* memory */ 0, 0, /* base, irq */ - 0, 0, 0, NEXT_DEV, pamsnet_probe, + 0, 0, 0, NULL, pamsnet_probe, }; int diff -u --recursive v2.1.35/linux/drivers/net/eexpress.c linux/drivers/net/eexpress.c --- v2.1.35/linux/drivers/net/eexpress.c Fri Apr 4 08:52:21 1997 +++ linux/drivers/net/eexpress.c Thu Apr 17 09:29:32 1997 @@ -4,6 +4,8 @@ * based on original code by Donald Becker, with changes by * Alan Cox and Pauline Middelink. * + * Support for 8-bit mode by Zoltan Szilagyi + * * Many modifications, and currently maintained, by * Philip Blundell */ @@ -16,12 +18,6 @@ * things seem to be getting better slowly. */ -/* It would be nice to seperate out all the 82586-specific code, so that it - * could be shared between drivers (as with 8390.c). But this would be quite - * a messy job. The main motivation for doing this would be to bring 3c507 - * support back up to scratch. - */ - /* If your card is confused about what sort of interface it has (eg it * persistently reports "10baseT" when none is fitted), running 'SOFTSET /BART' * or 'SOFTSET /LISA' from DOS seems to help. @@ -60,13 +56,28 @@ /* Known bugs: * - * - 8-bit mode is not supported, and makes things go wrong. - * - Multicast and promiscuous modes are not supported. * - The card seems to want to give us two interrupts every time something * happens, where just one would be better. - * - The statistics may not be getting reported properly. */ +/* + * + * Note by Zoltan Szilagyi 10-12-96: + * + * I've succeeded in eliminating the "CU wedged" messages, and hence the + * lockups, which were only occuring with cards running in 8-bit mode ("force + * 8-bit operation" in Intel's SoftSet utility). This version of the driver + * sets the 82586 and the ASIC to 8-bit mode at startup; it also stops the + * CU before submitting a packet for transmission, and then restarts it as soon + * as the process of handing the packet is complete. This is definitely an + * unnecessary slowdown if the card is running in 16-bit mode; therefore one + * should detect 16-bit vs 8-bit mode from the EEPROM settings and act + * accordingly. In 8-bit mode with this bugfix I'm getting about 150 K/s for + * ftp's, which is significantly better than I get in DOS, so the overhead of + * stopping and restarting the CU with each transmit is not prohibitive in + * practice. + */ + #include #include @@ -104,9 +115,11 @@ struct net_local { struct net_device_stats stats; + unsigned long last_tx; /* jiffies when last transmit started */ unsigned long init_time; /* jiffies when eexp_hw_init586 called */ unsigned short rx_first; /* first rx buf, same as RX_BUF_START */ unsigned short rx_last; /* last rx buf */ + unsigned short rx_ptr; /* first rx buf to look at */ unsigned short tx_head; /* next free tx buf */ unsigned short tx_reap; /* first in-use tx buf */ unsigned short tx_tail; /* previous tx buf to tx_head */ @@ -114,11 +127,13 @@ unsigned short last_tx_restart; /* set to tx_link when we restart the CU */ unsigned char started; - unsigned char promisc; unsigned short rx_buf_start; unsigned short rx_buf_end; unsigned short num_tx_bufs; unsigned short num_rx_bufs; + unsigned char width; /* 0 for 16bit, 1 for 8bit */ + unsigned char was_promisc; + unsigned char old_mc_count; }; /* This is the code and data that is downloaded to the EtherExpress card's @@ -126,11 +141,6 @@ */ static unsigned short start_code[] = { -/* 0xfff6 */ - 0x0000, /* set bus to 16 bits */ - 0x0000,0x0000, - 0x0000,0x0000, /* address of ISCP (lo,hi) */ - /* 0x0000 */ 0x0001, /* ISCP: busy - cleared after reset */ 0x0008,0x0000,0x0000, /* offset,address (lo,hi) of SCB */ @@ -144,9 +154,9 @@ 0x0000,0x0000, /* pad */ 0x0000,0x0000, -/* 0x0020 -- start of 82586 CU program */ -#define CONF_LINK 0x0020 - 0x0000,Cmd_Config, +/* 0x20 -- start of 82586 CU program */ +#define CONF_LINK 0x20 + 0x0000,Cmd_Config, 0x0032, /* link to next command */ 0x080c, /* 12 bytes follow : fifo threshold=8 */ 0x2e40, /* don't rx bad frames @@ -156,27 +166,43 @@ */ 0x6000, /* default backoff method & priority * interframe spacing = 0x60 */ - 0xf200, /* slot time=0x200 + 0xf200, /* slot time=0x200 * max collision retry = 0xf */ - 0x0000, /* no HDLC : normal CRC : enable broadcast +#define CONF_PROMISC 0x2e + 0x0000, /* no HDLC : normal CRC : enable broadcast * disable promiscuous/multicast modes */ 0x003c, /* minimum frame length = 60 octets) */ - 0x0000,Cmd_INT|Cmd_SetAddr, + 0x0000,Cmd_SetAddr, 0x003e, /* link to next command */ +#define CONF_HWADDR 0x38 0x0000,0x0000,0x0000, /* hardware address placed here */ - 0x0000,Cmd_TDR,0x0048, -/* 0x0044 -- TDR result placed here */ - 0x0000, 0x0000, - -/* Eventually, a set-multicast will go in here */ + 0x0000,Cmd_MCast, + 0x0076, /* link to next command */ +#define CONF_NR_MULTICAST 0x44 + 0x0000, /* number of multicast addresses */ +#define CONF_MULTICAST 0x46 + 0x0000, 0x0000, 0x0000, /* some addresses */ + 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, + +#define CONF_DIAG_RESULT 0x76 + 0x0000, Cmd_Diag, + 0x007c, /* link to next command */ + + 0x0000,Cmd_TDR|Cmd_INT, + 0x0084, +#define CONF_TDR_RESULT 0x82 + 0x0000, 0x0000,Cmd_END|Cmd_Nop, /* end of configure sequence */ - 0x0048, - - 0x0000 - + 0x0084 /* dummy link */ }; /* maps irq number to EtherExpress magic value */ @@ -213,6 +239,13 @@ static void eexp_hw_rxinit (struct device *dev); static void eexp_hw_init586 (struct device *dev); +static void eexp_setup_filter (struct device *dev); + +static char *eexp_ifmap[]={"AUI", "BNC", "RJ45"}; +enum eexp_iftype {AUI=0, BNC=1, TPE=2}; + +#define STARTED_RU 2 +#define STARTED_CU 1 /* * Primitive hardware access functions. @@ -270,7 +303,8 @@ int express_probe(struct device *dev) { - unsigned short *port,ports[] = { 0x0300,0x0270,0x0320,0x0340,0 }; + unsigned short *port; + static unsigned short ports[] = { 0x300,0x310,0x270,0x320,0x340,0 }; unsigned short ioaddr = dev->base_addr; if (ioaddr&0xfe00) @@ -302,6 +336,7 @@ { int irq = dev->irq; unsigned short ioaddr = dev->base_addr; + struct net_local *lp = (struct net_local *)dev->priv; #if NET_DEBUG > 6 printk(KERN_DEBUG "%s: eexp_open()\n", dev->name); @@ -316,8 +351,16 @@ return -EAGAIN; request_region(ioaddr, EEXP_IO_EXTENT, "EtherExpress"); + request_region(ioaddr+0x4000, 16, "EtherExpress shadow"); + request_region(ioaddr+0x8000, 16, "EtherExpress shadow"); + request_region(ioaddr+0xc000, 16, "EtherExpress shadow"); dev->tbusy = 0; dev->interrupt = 0; + + if (lp->width) { + printk("%s: forcing ASIC to 8-bit mode\n", dev->name); + outb(inb(dev->base_addr+Config)&~4, dev->base_addr+Config); + } eexp_hw_init586(dev); dev->start = 1; @@ -331,6 +374,7 @@ /* * close and disable the interface, leaving the 586 in reset. */ + static int eexp_close(struct device *dev) { unsigned short ioaddr = dev->base_addr; @@ -464,9 +508,23 @@ /* If dev->tbusy is set, all our tx buffers are full but the kernel * is calling us anyway. Check that nothing bad is happening. */ - if (dev->tbusy) - unstick_cu(dev); - + if (dev->tbusy) { + int status = scb_status(dev); + unstick_cu(dev); + if ((jiffies - lp->last_tx) < HZ) + return 1; + printk(KERN_INFO "%s: transmit timed out, %s?", dev->name, + (SCB_complete(status)?"lost interrupt": + "board on fire")); + lp->stats.tx_errors++; + dev->tbusy = 0; + lp->last_tx = jiffies; + if (!SCB_complete(status)) { + scb_command(dev, SCB_CUabort); + outb(0,dev->base_addr+SIGNAL_CA); + } + } + if (set_bit(0,(void *)&dev->tbusy)) { lp->stats.tx_dropped++; @@ -477,6 +535,8 @@ ETH_ZLEN; unsigned short *data = (unsigned short *)buf->data; + lp->stats.tx_bytes += length; + eexp_hw_tx_pio(dev,data,length); } dev_kfree_skb(buf, FREE_WRITE); @@ -491,11 +551,86 @@ * check to make sure we've not become wedged. */ +/* + * Handle an EtherExpress interrupt + * If we've finished initializing, start the RU and CU up. + * If we've already started, reap tx buffers, handle any received packets, + * check to make sure we've not become wedged. + */ + +static unsigned short eexp_start_irq(struct device *dev, + unsigned short status) +{ + unsigned short ack_cmd = SCB_ack(status); + struct net_local *lp = (struct net_local *)dev->priv; + unsigned short ioaddr = dev->base_addr; + if ((dev->flags & IFF_UP) && !(lp->started & STARTED_CU)) { + short diag_status, tdr_status; + while (SCB_CUstat(status)==2) + status = scb_status(dev); +#if NET_DEBUG > 4 + printk("%s: CU went non-active (status %04x)\n", + dev->name, status); +#endif + + outw(CONF_DIAG_RESULT & ~31, ioaddr + SM_PTR); + diag_status = inw(ioaddr + SHADOW(CONF_DIAG_RESULT)); + if (diag_status & 1<<11) { + printk(KERN_WARNING "%s: 82586 failed self-test\n", + dev->name); + } else if (!(diag_status & 1<<13)) { + printk(KERN_WARNING "%s: 82586 self-test failed to complete\n", dev->name); + } + + outw(CONF_TDR_RESULT & ~31, ioaddr + SM_PTR); + tdr_status = inw(ioaddr + SHADOW(CONF_TDR_RESULT)); + if (tdr_status & (TDR_SHORT|TDR_OPEN)) { + printk(KERN_WARNING "%s: TDR reports cable %s at %d tick%s\n", dev->name, (tdr_status & TDR_SHORT)?"short":"broken", tdr_status & TDR_TIME, ((tdr_status & TDR_TIME) != 1) ? "s" : ""); + } + else if (tdr_status & TDR_XCVRPROBLEM) { + printk(KERN_WARNING "%s: TDR reports transceiver problem\n", dev->name); + } + else if (tdr_status & TDR_LINKOK) { +#if NET_DEBUG > 4 + printk(KERN_DEBUG "%s: TDR reports link OK\n", dev->name); +#endif + } else { + printk("%s: TDR is ga-ga (status %04x)\n", dev->name, + tdr_status); + } + + lp->started |= STARTED_CU; + scb_wrcbl(dev, lp->tx_link); + /* if the RU isn't running, start it now */ + if (!(lp->started & STARTED_RU)) { + ack_cmd |= SCB_RUstart; + scb_wrrfa(dev, lp->rx_buf_start); + lp->rx_ptr = lp->rx_buf_start; + } + ack_cmd |= SCB_CUstart | 0x2000; + } + + if ((dev->flags & IFF_UP) && !(lp->started & STARTED_RU) && SCB_RUstat(status)==4) + lp->started|=STARTED_RU; + + return ack_cmd; +} + +static void eexp_cmd_clear(struct device *dev) +{ + unsigned long int oldtime = jiffies; + while (scb_rdcmd(dev) && ((jiffies-oldtime)<10)); + if (scb_rdcmd(dev)) { + printk("%s: command didn't clear\n", dev->name); + } +} + static void eexp_irq(int irq, void *dev_info, struct pt_regs *regs) { struct device *dev = irq2dev_map[irq]; struct net_local *lp; unsigned short ioaddr,status,ack_cmd; + unsigned short old_read_ptr, old_write_ptr; if (dev==NULL) { @@ -507,6 +642,9 @@ lp = (struct net_local *)dev->priv; ioaddr = dev->base_addr; + old_read_ptr = inw(ioaddr+READ_PTR); + old_write_ptr = inw(ioaddr+WRITE_PTR); + outb(SIRQ_dis|irqrmap[irq],ioaddr+SET_IRQ); dev->interrupt = 1; @@ -517,75 +655,73 @@ printk(KERN_DEBUG "%s: interrupt (status %x)\n", dev->name, status); #endif - ack_cmd = SCB_ack(status); + if (lp->started == (STARTED_CU | STARTED_RU)) { - if (lp->started==0 && SCB_complete(status)) - { - while (SCB_CUstat(status)==2) - status = scb_status(dev); -#if NET_DEBUG > 4 - printk(KERN_DEBUG "%s: CU went non-active (status = %08x)\n", - dev->name, status); -#endif + do { + eexp_cmd_clear(dev); - /* now get the TDR status */ - { - short tdr_status; - outw(0x40, dev->base_addr + SM_PTR); - tdr_status = inw(dev->base_addr + 0x8004); - if (tdr_status & TDR_SHORT) { - printk(KERN_WARNING "%s: TDR reports cable short at %d tick%s\n", dev->name, tdr_status & TDR_TIME, ((tdr_status & TDR_TIME) != 1) ? "s" : ""); - } - else if (tdr_status & TDR_OPEN) { - printk(KERN_WARNING "%s: TDR reports cable broken at %d tick%s\n", dev->name, tdr_status & TDR_TIME, ((tdr_status & TDR_TIME) != 1) ? "s" : ""); - } - else if (tdr_status & TDR_XCVRPROBLEM) { - printk(KERN_WARNING "%s: TDR reports transceiver problem\n", dev->name); - } -#if NET_DEBUG > 4 - else if (tdr_status & TDR_LINKOK) { - printk(KERN_DEBUG "%s: TDR reports link OK\n", dev->name); - } -#endif - } + ack_cmd = SCB_ack(status); + scb_command(dev, ack_cmd); + outb(0,ioaddr+SIGNAL_CA); - lp->started=1; - scb_wrcbl(dev, lp->tx_link); - scb_wrrfa(dev, lp->rx_buf_start); - ack_cmd |= SCB_CUstart | SCB_RUstart | 0x2000; - } - else if (lp->started) - { - unsigned short txstatus; - txstatus = eexp_hw_lasttxstat(dev); - } + eexp_cmd_clear(dev); - if (SCB_rxdframe(status)) - { - eexp_hw_rx_pio(dev); - } + if (SCB_complete(status)) { + if (!eexp_hw_lasttxstat(dev)) { + printk("%s: tx interrupt but no status\n", dev->name); + } + } + + if (SCB_rxdframe(status)) + eexp_hw_rx_pio(dev); - if ((lp->started&2)!=0 && SCB_RUstat(status)!=4) - { - printk(KERN_WARNING "%s: RU stopped: status %04x\n", - dev->name,status); - lp->stats.rx_errors++; - eexp_hw_rxinit(dev); - scb_wrrfa(dev, lp->rx_buf_start); - ack_cmd |= SCB_RUstart; + status = scb_status(dev); + } while (status & 0xc000); + + if (SCB_RUdead(status)) + { + printk(KERN_WARNING "%s: RU stopped: status %04x\n", + dev->name,status); +#if 0 + printk(KERN_WARNING "%s: cur_rfd=%04x, cur_rbd=%04x\n", dev->name, lp->cur_rfd, lp->cur_rbd); + outw(lp->cur_rfd, ioaddr+READ_PTR); + printk(KERN_WARNING "%s: [%04x]\n", dev->name, inw(ioaddr+DATAPORT)); + outw(lp->cur_rfd+6, ioaddr+READ_PTR); + printk(KERN_WARNING "%s: rbd is %04x\n", dev->name, rbd= inw(ioaddr+DATAPORT)); + outw(rbd, ioaddr+READ_PTR); + printk(KERN_WARNING "%s: [%04x %04x] ", dev->name, inw(ioaddr+DATAPORT), inw(ioaddr+DATAPORT)); + outw(rbd+8, ioaddr+READ_PTR); + printk("[%04x]\n", inw(ioaddr+DATAPORT)); +#endif + lp->stats.rx_errors++; +#if 1 + eexp_hw_rxinit(dev); +#else + lp->cur_rfd = lp->first_rfd; +#endif + scb_wrrfa(dev, lp->rx_buf_start); + scb_command(dev, SCB_RUstart); + outb(0,ioaddr+SIGNAL_CA); + } + } else { + if (status & 0x8000) + ack_cmd = eexp_start_irq(dev, status); + else + ack_cmd = SCB_ack(status); + scb_command(dev, ack_cmd); + outb(0,ioaddr+SIGNAL_CA); } - else if (lp->started==1 && SCB_RUstat(status)==4) - lp->started|=2; - scb_command(dev, ack_cmd); - outb(0,ioaddr+SIGNAL_CA); + eexp_cmd_clear(dev); - outb(SIRQ_en|irqrmap[irq],ioaddr+SET_IRQ); + outb(SIRQ_en|irqrmap[irq],ioaddr+SET_IRQ); dev->interrupt = 0; -#if NET_DEBUG > 6 - printk(KERN_DEBUG "%s: leaving eexp_irq()\n", dev->name); +#if NET_DEBUG > 6 + printk("%s: leaving eexp_irq()\n", dev->name); #endif + outw(old_read_ptr, ioaddr+READ_PTR); + outw(old_write_ptr, ioaddr+WRITE_PTR); return; } @@ -594,6 +730,25 @@ */ /* + * Set the cable type to use. + */ + +static void eexp_hw_set_interface(struct device *dev) +{ + unsigned char oldval = inb(dev->base_addr + 0x300e); + oldval &= ~0x82; + switch (dev->if_port) { + case TPE: + oldval |= 0x2; + case BNC: + oldval |= 0x80; + break; + } + outb(oldval, dev->base_addr+0x300e); + udelay(20000); +} + +/* * Check all the receive buffers, and hand any received packets * to the upper levels. Basic sanity check on each frame * descriptor, though we don't bother trying to fix broken ones. @@ -602,41 +757,49 @@ static void eexp_hw_rx_pio(struct device *dev) { struct net_local *lp = (struct net_local *)dev->priv; - unsigned short rx_block = lp->rx_first; + unsigned short rx_block = lp->rx_ptr; unsigned short boguscount = lp->num_rx_bufs; unsigned short ioaddr = dev->base_addr; + unsigned short status; #if NET_DEBUG > 6 printk(KERN_DEBUG "%s: eexp_hw_rx()\n", dev->name); #endif - while (boguscount--) - { - unsigned short status, rfd_cmd, rx_next, pbuf, pkt_len; - + do { + unsigned short rfd_cmd, rx_next, pbuf, pkt_len; + outw(rx_block, ioaddr + READ_PTR); status = inw(ioaddr + DATAPORT); - rfd_cmd = inw(ioaddr + DATAPORT); - rx_next = inw(ioaddr + DATAPORT); - pbuf = inw(ioaddr + DATAPORT); if (FD_Done(status)) { + rfd_cmd = inw(ioaddr + DATAPORT); + rx_next = inw(ioaddr + DATAPORT); + pbuf = inw(ioaddr + DATAPORT); + outw(pbuf, ioaddr + READ_PTR); pkt_len = inw(ioaddr + DATAPORT); - if (rfd_cmd!=0x0000 || pbuf!=rx_block+0x16 - || (pkt_len & 0xc000)!=0xc000) + if (rfd_cmd!=0x0000) + { + printk(KERN_WARNING "%s: rfd_cmd not zero:0x%04x\n", + dev->name, rfd_cmd); + continue; + } + else if (pbuf!=rx_block+0x16) { - /* This should never happen. If it does, - * we almost certainly have a driver bug. - */ - printk(KERN_WARNING "%s: Rx frame at %04x corrupted, status %04x, cmd %04x, " - "next %04x, pbuf %04x, len %04x\n",dev->name,rx_block, - status,rfd_cmd,rx_next,pbuf,pkt_len); + printk(KERN_WARNING "%s: rfd and rbd out of sync 0x%04x 0x%04x\n", + dev->name, rx_block+0x16, pbuf); continue; } - else if (!FD_OK(status)) + else if ((pkt_len & 0xc000)!=0xc000) + { + printk(KERN_WARNING "%s: EOF or F not set on received buffer (%04x)\n", + dev->name, pkt_len & 0xc000); + continue; + } + else if (!FD_OK(status)) { lp->stats.rx_errors++; if (FD_CRC(status)) @@ -668,13 +831,15 @@ skb->protocol = eth_type_trans(skb,dev); netif_rx(skb); lp->stats.rx_packets++; + lp->stats.rx_bytes += pkt_len; } outw(rx_block, ioaddr+WRITE_PTR); outw(0, ioaddr+DATAPORT); outw(0, ioaddr+DATAPORT); + rx_block = rx_next; } - rx_block = rx_next; - } + } while (FD_Done(status) && boguscount--); + lp->rx_ptr = rx_block; } /* @@ -690,7 +855,17 @@ struct net_local *lp = (struct net_local *)dev->priv; unsigned short ioaddr = dev->base_addr; - outw(lp->tx_head, ioaddr + WRITE_PTR); + if (lp->width) { + /* Stop the CU so that there is no chance that it + jumps off to a bogus address while we are writing the + pointer to the next transmit packet in 8-bit mode -- + this eliminates the "CU wedged" errors in 8-bit mode. + (Zoltan Szilagyi 10-12-96) */ + scb_command(dev, SCB_CUsuspend); + outw(0xFFFF, ioaddr+SIGNAL_CA); + } + + outw(lp->tx_head, ioaddr + WRITE_PTR); outw(0x0000, ioaddr + DATAPORT); outw(Cmd_INT|Cmd_Xmit, ioaddr + DATAPORT); @@ -719,6 +894,16 @@ lp->tx_head += TX_BUF_SIZE; if (lp->tx_head != lp->tx_reap) dev->tbusy = 0; + + if (lp->width) { + /* Restart the CU so that the packet can actually + be transmitted. (Zoltan Szilagyi 10-12-96) */ + scb_command(dev, SCB_CUresume); + outw(0xFFFF, ioaddr+SIGNAL_CA); + } + + lp->stats.tx_packets++; + lp->last_tx = jiffies; } /* @@ -731,14 +916,13 @@ static int eexp_hw_probe(struct device *dev, unsigned short ioaddr) { unsigned short hw_addr[3]; + unsigned char buswidth; unsigned int memory_size; - static char *ifmap[]={"AUI", "BNC", "RJ45"}; - enum iftype {AUI=0, BNC=1, TP=2}; int i; unsigned short xsum = 0; struct net_local *lp; - printk("%s: EtherExpress 16 at %#x",dev->name,ioaddr); + printk("%s: EtherExpress 16 at %#x ",dev->name,ioaddr); outb(ASIC_RST, ioaddr+EEPROM_Ctrl); outb(0, ioaddr+EEPROM_Ctrl); @@ -769,7 +953,7 @@ dev->dev_addr[i] = ((unsigned char *)hw_addr)[5-i]; { - char irqmap[]={0, 9, 3, 4, 5, 10, 11, 0}; + static char irqmap[]={0, 9, 3, 4, 5, 10, 11, 0}; unsigned short setupval = eexp_hw_readeeprom(ioaddr,0); /* Use the IRQ from EEPROM if none was given */ @@ -777,7 +961,9 @@ dev->irq = irqmap[setupval>>13]; dev->if_port = !(setupval & 0x1000) ? AUI : - eexp_hw_readeeprom(ioaddr,5) & 0x1 ? TP : BNC; + eexp_hw_readeeprom(ioaddr,5) & 0x1 ? TPE : BNC; + + buswidth = !((setupval & 0x400) >> 10); } dev->priv = lp = kmalloc(sizeof(struct net_local), GFP_KERNEL); @@ -786,8 +972,11 @@ memset(dev->priv, 0, sizeof(struct net_local)); - printk("; using IRQ %d, %s connector", dev->irq,ifmap[dev->if_port]); - + printk("(IRQ %d, %s connector, %d-bit bus", dev->irq, + eexp_ifmap[dev->if_port], buswidth?8:16); + + eexp_hw_set_interface(dev); + /* Find out how much RAM we have on the card */ outw(0, dev->base_addr + WRITE_PTR); for (i = 0; i < 32768; i++) @@ -795,10 +984,10 @@ for (memory_size = 0; memory_size < 64; memory_size++) { - outw(memory_size<<10, dev->base_addr + WRITE_PTR); outw(memory_size<<10, dev->base_addr + READ_PTR); if (inw(dev->base_addr+DATAPORT)) break; + outw(memory_size<<10, dev->base_addr + WRITE_PTR); outw(memory_size | 0x5000, dev->base_addr+DATAPORT); outw(memory_size<<10, dev->base_addr + READ_PTR); if (inw(dev->base_addr+DATAPORT) != (memory_size | 0x5000)) @@ -820,16 +1009,17 @@ case 32: lp->rx_buf_end += 0x4000; case 16: - printk(", %dk RAM.\n", memory_size); + printk(", %dk RAM)\n", memory_size); break; default: - printk("; bad memory size (%dk).\n", memory_size); + printk(") bad memory size (%dk).\n", memory_size); kfree(dev->priv); return ENODEV; break; } lp->rx_buf_start = TX_BUF_START + (lp->num_tx_bufs*TX_BUF_SIZE); + lp->width = buswidth; dev->open = eexp_open; dev->stop = eexp_close; @@ -905,8 +1095,8 @@ do { - outw(tx_block, dev->base_addr + SM_PTR); - status = inw(SHADOW(tx_block)); + outw(tx_block & ~31, dev->base_addr + SM_PTR); + status = inw(dev->base_addr + SHADOW(tx_block)); if (!Stat_Done(status)) { lp->tx_link = tx_block; @@ -918,12 +1108,29 @@ lp->stats.collisions += Stat_NoColl(status); if (!Stat_OK(status)) { - if (Stat_Abort(status)) - lp->stats.tx_aborted_errors++; - if (Stat_TNoCar(status) || Stat_TNoCTS(status)) + char *whatsup = NULL; + lp->stats.tx_errors++; + if (Stat_Abort(status)) + lp->stats.tx_aborted_errors++; + if (Stat_TNoCar(status)) { + whatsup = "aborted, no carrier"; lp->stats.tx_carrier_errors++; - if (Stat_TNoDMA(status)) - lp->stats.tx_fifo_errors++; + } + if (Stat_TNoCTS(status)) { + whatsup = "aborted, lost CTS"; + lp->stats.tx_carrier_errors++; + } + if (Stat_TNoDMA(status)) { + whatsup = "FIFO underran"; + lp->stats.tx_fifo_errors++; + } + if (Stat_TXColl(status)) { + whatsup = "aborted, too many collisions"; + lp->stats.tx_aborted_errors++; + } + if (whatsup) + printk(KERN_INFO "%s: transmit %s\n", + dev->name, whatsup); } else lp->stats.tx_packets++; @@ -1043,7 +1250,7 @@ unsigned short ioaddr = dev->base_addr; lp->num_rx_bufs = 0; - lp->rx_first = rx_block; + lp->rx_first = lp->rx_ptr = rx_block; do { lp->num_rx_bufs++; @@ -1052,9 +1259,9 @@ outw(0, ioaddr + DATAPORT); outw(0, ioaddr+DATAPORT); outw(rx_block + RX_BUF_SIZE, ioaddr+DATAPORT); - outw(rx_block + 0x16, ioaddr+DATAPORT); + outw(0xffff, ioaddr+DATAPORT); - outw(0xdead, ioaddr+DATAPORT); + outw(0x0000, ioaddr+DATAPORT); outw(0xdead, ioaddr+DATAPORT); outw(0xdead, ioaddr+DATAPORT); outw(0xdead, ioaddr+DATAPORT); @@ -1062,19 +1269,30 @@ outw(0xdead, ioaddr+DATAPORT); outw(0xdead, ioaddr+DATAPORT); - outw(0x8000, ioaddr+DATAPORT); - outw(0xffff, ioaddr+DATAPORT); + outw(0x0000, ioaddr+DATAPORT); + outw(rx_block + RX_BUF_SIZE + 0x16, ioaddr+DATAPORT); outw(rx_block + 0x20, ioaddr+DATAPORT); outw(0, ioaddr+DATAPORT); - outw(0x8000 | (RX_BUF_SIZE-0x20), ioaddr+DATAPORT); + outw(RX_BUF_SIZE-0x20, ioaddr+DATAPORT); lp->rx_last = rx_block; rx_block += RX_BUF_SIZE; } while (rx_block <= lp->rx_buf_end-RX_BUF_SIZE); - outw(lp->rx_last + 4, ioaddr+WRITE_PTR); - outw(lp->rx_first, ioaddr+DATAPORT); + /* Make first Rx frame descriptor point to first Rx buffer + descriptor */ + outw(lp->rx_first + 6, ioaddr+WRITE_PTR); + outw(lp->rx_first + 0x16, ioaddr+DATAPORT); + + /* Close Rx frame descriptor ring */ + outw(lp->rx_last + 4, ioaddr+WRITE_PTR); + outw(lp->rx_first, ioaddr+DATAPORT); + + /* Close Rx buffer descriptor ring */ + outw(lp->rx_last + 0x16 + 2, ioaddr+WRITE_PTR); + outw(lp->rx_first + 0x16, ioaddr+DATAPORT); + } /* @@ -1083,6 +1301,7 @@ * us. We can't start the receive/transmission system up before we know that * the hardware is configured correctly. */ + static void eexp_hw_init586(struct device *dev) { struct net_local *lp = (struct net_local *)dev->priv; @@ -1097,24 +1316,19 @@ set_loopback(dev); - /* Bash the startup code a bit */ - start_code[28] = (dev->flags & IFF_PROMISC)?(start_code[28] | 1): - (start_code[28] & ~1); - lp->promisc = dev->flags & IFF_PROMISC; - memcpy(&start_code[33], &dev->dev_addr[0], 6); - outb(SIRQ_dis|irqrmap[dev->irq],ioaddr+SET_IRQ); /* Download the startup code */ outw(lp->rx_buf_end & ~31, ioaddr + SM_PTR); - outw(start_code[0], ioaddr + 0x8006); - outw(start_code[1], ioaddr + 0x8008); - outw(start_code[2], ioaddr + 0x800a); - outw(start_code[3], ioaddr + 0x800c); - outw(start_code[4], ioaddr + 0x800e); - for (i = 10; i < (sizeof(start_code)); i+=32) { + outw(lp->width?0x0001:0x0000, ioaddr + 0x8006); + outw(0x0000, ioaddr + 0x8008); + outw(0x0000, ioaddr + 0x800a); + outw(0x0000, ioaddr + 0x800c); + outw(0x0000, ioaddr + 0x800e); + + for (i = 0; i < (sizeof(start_code)); i+=32) { int j; - outw(i-10, ioaddr + SM_PTR); + outw(i, ioaddr + SM_PTR); for (j = 0; j < 16; j+=2) outw(start_code[(i+j)/2], ioaddr+0x4000+j); @@ -1123,6 +1337,24 @@ ioaddr+0x8000+j); } + /* Do we want promiscuous mode or multicast? */ + outw(CONF_PROMISC & ~31, ioaddr+SM_PTR); + i = inw(ioaddr+SHADOW(CONF_PROMISC)); + outw((dev->flags & IFF_PROMISC)?(i|1):(i & ~1), + ioaddr+SHADOW(CONF_PROMISC)); + lp->was_promisc = dev->flags & IFF_PROMISC; +#if 0 + eexp_setup_filter(dev); +#endif + + /* Write our hardware address */ + outw(CONF_HWADDR & ~31, ioaddr+SM_PTR); + outw(((unsigned short *)dev->dev_addr)[0], ioaddr+SHADOW(CONF_HWADDR)); + outw(((unsigned short *)dev->dev_addr)[1], + ioaddr+SHADOW(CONF_HWADDR+2)); + outw(((unsigned short *)dev->dev_addr)[2], + ioaddr+SHADOW(CONF_HWADDR+4)); + eexp_hw_txinit(dev); eexp_hw_rxinit(dev); @@ -1193,6 +1425,38 @@ return; } +static void eexp_setup_filter(struct device *dev) +{ + struct dev_mc_list *dmi = dev->mc_list; + unsigned short ioaddr = dev->base_addr; + int count = dev->mc_count; + int i; + if (count > 8) { + printk(KERN_INFO "%s: too many multicast addresses (%d)\n", + dev->name, count); + count = 8; + } + + outw(CONF_NR_MULTICAST & ~31, ioaddr+SM_PTR); + outw(count, ioaddr+SHADOW(CONF_NR_MULTICAST)); + for (i = 0; i < count; i++) { + unsigned short *data = (unsigned short *)dmi->dmi_addr; + if (!dmi) { + printk(KERN_INFO "%s: too few multicast addresses\n", dev->name); + break; + } + if (dmi->dmi_addrlen != ETH_ALEN) { + printk(KERN_INFO "%s: invalid multicast address length given.\n", dev->name); + continue; + } + outw((CONF_MULTICAST+(6*i)) & ~31, ioaddr+SM_PTR); + outw(data[0], ioaddr+SHADOW(CONF_MULTICAST+(6*i))); + outw((CONF_MULTICAST+(6*i)+2) & ~31, ioaddr+SM_PTR); + outw(data[1], ioaddr+SHADOW(CONF_MULTICAST+(6*i)+2)); + outw((CONF_MULTICAST+(6*i)+4) & ~31, ioaddr+SM_PTR); + outw(data[2], ioaddr+SHADOW(CONF_MULTICAST+(6*i)+4)); + } +} /* * Set or clear the multicast filter for this adaptor. @@ -1200,12 +1464,49 @@ static void eexp_set_multicast(struct device *dev) { + unsigned short ioaddr = dev->base_addr; + struct net_local *lp = (struct net_local *)dev->priv; + int kick = 0, i; + if ((dev->flags & IFF_PROMISC) != lp->was_promisc) { + outw(CONF_PROMISC & ~31, ioaddr+SM_PTR); + i = inw(ioaddr+SHADOW(CONF_PROMISC)); + outw((dev->flags & IFF_PROMISC)?(i|1):(i & ~1), + ioaddr+SHADOW(CONF_PROMISC)); + lp->was_promisc = dev->flags & IFF_PROMISC; + kick = 1; + } + if (!(dev->flags & IFF_PROMISC)) { + eexp_setup_filter(dev); + if (lp->old_mc_count != dev->mc_count) { + kick = 1; + lp->old_mc_count = dev->mc_count; + } + } + if (kick) { + unsigned long oj; + scb_command(dev, SCB_CUsuspend); + outb(0, ioaddr+SIGNAL_CA); + outb(0, ioaddr+SIGNAL_CA); +#if 0 + printk("%s: waiting for CU to go suspended\n", dev->name); +#endif + oj = jiffies; + while ((SCB_CUstat(scb_status(dev)) == 2) && + ((jiffies-oj) < 100)); + if (SCB_CUstat(scb_status(dev)) == 2) + printk("%s: warning, CU didn't stop\n", dev->name); + lp->started &= ~(STARTED_CU); + scb_wrcbl(dev, CONF_LINK); + scb_command(dev, SCB_CUstart); + outb(0, ioaddr+SIGNAL_CA); + } } /* * MODULE stuff */ + #ifdef MODULE #define EEXP_MAX_CARDS 4 /* max number of cards to support */ diff -u --recursive v2.1.35/linux/drivers/net/hydra.c linux/drivers/net/hydra.c --- v2.1.35/linux/drivers/net/hydra.c Sun Feb 2 05:18:40 1997 +++ linux/drivers/net/hydra.c Thu Apr 17 13:20:45 1997 @@ -34,7 +34,7 @@ #include #include -#include +#include #include "hydra.h" @@ -193,7 +193,9 @@ dev->stop = &hydra_close; dev->hard_start_xmit = &hydra_start_xmit; dev->get_stats = &hydra_get_stats; - dev->set_multicast_list = &hydra_set_multicast_list; +#ifdef HAVE_MULTICAST + dev->set_multicast_list = &set_multicast_list; +#endif /* * Cannot yet do multicast @@ -643,6 +645,7 @@ return(&priv->stats); } +#ifdef HAVE_MULTICAST static void set_multicast_list(struct device *dev, int num_addrs, void *addrs) { struct hydra_private *priv = (struct hydra_private *)dev->priv; @@ -652,6 +655,7 @@ /* (personally i don't care about multicasts at all :) */ return; } +#endif #ifdef MODULE diff -u --recursive v2.1.35/linux/drivers/net/myri_code.h linux/drivers/net/myri_code.h --- v2.1.35/linux/drivers/net/myri_code.h Thu Dec 19 01:03:34 1996 +++ linux/drivers/net/myri_code.h Thu Apr 17 13:20:45 1997 @@ -2,7 +2,7 @@ /* Generated by cat $MYRI_HOME/lib/lanai/mcp4.dat > myri_code4.h */ static unsigned int lanai4_code_off = 0x0000; /* half-word offset */ -static unsigned char lanai4_code[76256] = { +static unsigned char lanai4_code[76256] __initdata = { 0xF2,0x0E, 0xFE,0x00, 0xC2,0x90, 0x00,0x00, 0x07,0x88, 0x00,0x08, 0xE0,0x01, 0x01,0x4C, 0x97,0x93, 0xFF,0xFC, 0xE0,0x00, 0x00,0x14, 0x00,0x00, 0x00,0x01, 0x00,0x00, 0x00,0x00, 0x92,0x93, @@ -4775,7 +4775,7 @@ /* This is the LANai data */ static unsigned int lanai4_data_off = 0x94F0; /* half-word offset */ -static unsigned char lanai4_data[20472] = { +static unsigned char lanai4_data[20472] __initdata = { 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, diff -u --recursive v2.1.35/linux/drivers/net/myri_sbus.c linux/drivers/net/myri_sbus.c --- v2.1.35/linux/drivers/net/myri_sbus.c Mon Apr 14 16:28:12 1997 +++ linux/drivers/net/myri_sbus.c Thu Apr 17 13:20:45 1997 @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include @@ -171,7 +172,7 @@ return 0; } -static int myri_load_lanai(struct myri_eth *mp) +static inline int myri_load_lanai(struct myri_eth *mp) { struct device *dev = mp->dev; struct myri_shmem *shmem = mp->shmem; @@ -893,7 +894,7 @@ } #endif -static int myri_ether_init(struct device *dev, struct linux_sbus_device *sdev, int num) +static inline int myri_ether_init(struct device *dev, struct linux_sbus_device *sdev, int num) { static unsigned version_printed = 0; struct myri_eth *mp; @@ -1105,7 +1106,7 @@ return 0; } -int myri_sbus_probe(struct device *dev) +__initfunc(int myri_sbus_probe(struct device *dev)) { struct linux_sbus *bus; struct linux_sbus_device *sdev = 0; diff -u --recursive v2.1.35/linux/drivers/net/plip.c linux/drivers/net/plip.c --- v2.1.35/linux/drivers/net/plip.c Sun Apr 13 10:18:21 1997 +++ linux/drivers/net/plip.c Thu Apr 17 14:48:53 1997 @@ -1,4 +1,4 @@ -/* $Id: plip.c,v 1.1.1.1.2.6 1997/03/26 17:52:20 phil Exp $ */ +/* $Id: plip.c,v 1.3.6.2 1997/04/16 15:07:56 phil Exp $ */ /* PLIP: A parallel port "network" driver for Linux. */ /* This driver is for parallel port with 5-bit cable (LapLink (R) cable). */ /* @@ -1190,6 +1190,36 @@ return 0; } +static int +plip_init_one(int i, struct parport *pb) +{ + if (i == PLIP_MAX) { + printk(KERN_ERR "plip: too many devices\n"); + return 1; + } + dev_plip[i] = kmalloc(sizeof(struct device), + GFP_KERNEL); + if (!dev_plip[i]) { + printk(KERN_ERR "plip: memory squeeze\n"); + return 1; + } + memset(dev_plip[i], 0, sizeof(struct device)); + dev_plip[i]->name = kmalloc(strlen("plipXXX"), GFP_KERNEL); + if (!dev_plip[i]->name) { + printk(KERN_ERR "plip: memory squeeze.\n"); + kfree(dev_plip[i]); + return 1; + } + sprintf(dev_plip[i]->name, "plip%d", i); + dev_plip[i]->priv = pb; + if (plip_init_dev(dev_plip[i],pb) || register_netdev(dev_plip[i])) { + kfree(dev_plip[i]->name); + kfree(dev_plip[i]); + return 1; + } + return 0; +} + int plip_init(void) { @@ -1207,38 +1237,17 @@ /* When user feeds parameters, use them */ while (pb) { - if ((parport[0] == -1 && (!timid || !pb->devices)) || - plip_searchfor(parport, i)) { - if (i == PLIP_MAX) { - printk(KERN_ERR "plip: too many devices\n"); - break; - } - dev_plip[i] = kmalloc(sizeof(struct device), - GFP_KERNEL); - if (!dev_plip[i]) { - printk(KERN_ERR "plip: memory squeeze\n"); - break; - } - memset(dev_plip[i], 0, sizeof(struct device)); - dev_plip[i]->name = - kmalloc(strlen("plipXXX"), GFP_KERNEL); - if (!dev_plip[i]->name) { - printk(KERN_ERR "plip: memory squeeze.\n"); - kfree(dev_plip[i]); - break; - } - sprintf(dev_plip[i]->name, "plip%d", i); - dev_plip[i]->priv = pb; - if (plip_init_dev(dev_plip[i],pb) || register_netdev(dev_plip[i])) { - kfree(dev_plip[i]->name); - kfree(dev_plip[i]); - } else { + if (pb->modes & PARPORT_MODE_SPP) { + if ((parport[0] == -1 && (!timid || !pb->devices)) || + plip_searchfor(parport, i)) { + if (plip_init_one(i, pb)) + continue; devices++; } + i++; } - i++; pb = pb->next; - } + } if (devices == 0) { printk(KERN_INFO "plip: no devices registered\n"); diff -u --recursive v2.1.35/linux/drivers/net/sunhme.c linux/drivers/net/sunhme.c --- v2.1.35/linux/drivers/net/sunhme.c Mon Apr 14 16:28:12 1997 +++ linux/drivers/net/sunhme.c Thu Apr 17 13:20:46 1997 @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include @@ -2058,7 +2059,7 @@ dev->tbusy = 0; } -static int happy_meal_ether_init(struct device *dev, struct linux_sbus_device *sdev) +static inline int happy_meal_ether_init(struct device *dev, struct linux_sbus_device *sdev) { static unsigned version_printed = 0; struct happy_meal *hp; @@ -2201,7 +2202,7 @@ return 0; } -int happy_meal_probe(struct device *dev) +__initfunc(int happy_meal_probe(struct device *dev)) { struct linux_sbus *bus; struct linux_sbus_device *sdev = 0; diff -u --recursive v2.1.35/linux/drivers/net/sunlance.c linux/drivers/net/sunlance.c --- v2.1.35/linux/drivers/net/sunlance.c Mon Apr 14 16:28:12 1997 +++ linux/drivers/net/sunlance.c Thu Apr 17 13:20:46 1997 @@ -1,4 +1,4 @@ -/* $Id: sunlance.c,v 1.61 1997/04/10 06:40:54 davem Exp $ +/* $Id: sunlance.c,v 1.62 1997/04/16 10:27:25 jj Exp $ * lance.c: Linux/Sparc/Lance driver * * Written 1995, 1996 by Miguel de Icaza @@ -75,6 +75,7 @@ #include #include #include +#include #include #include #include @@ -934,9 +935,10 @@ dev->tbusy = 0; } -int sparc_lance_init (struct device *dev, struct linux_sbus_device *sdev, - struct Linux_SBus_DMA *ledma, - struct linux_sbus_device *lebuffer) +__initfunc(static int +sparc_lance_init (struct device *dev, struct linux_sbus_device *sdev, + struct Linux_SBus_DMA *ledma, + struct linux_sbus_device *lebuffer)) { static unsigned version_printed = 0; int i; @@ -1097,7 +1099,7 @@ } /* On 4m, find the associated dma for the lance chip */ -static struct Linux_SBus_DMA * +static inline struct Linux_SBus_DMA * find_ledma (struct linux_sbus_device *dev) { struct Linux_SBus_DMA *p; @@ -1109,7 +1111,7 @@ } /* Find all the lance cards on the system and initialize them */ -int sparc_lance_probe (struct device *dev) +__initfunc(int sparc_lance_probe (struct device *dev)) { struct linux_sbus *bus; struct linux_sbus_device *sdev = 0; diff -u --recursive v2.1.35/linux/drivers/net/sunqe.c linux/drivers/net/sunqe.c --- v2.1.35/linux/drivers/net/sunqe.c Mon Apr 14 16:28:12 1997 +++ linux/drivers/net/sunqe.c Thu Apr 17 13:20:46 1997 @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include @@ -902,7 +903,7 @@ } /* Four QE's per QEC card. */ -static int qec_ether_init(struct device *dev, struct linux_sbus_device *sdev) +static inline int qec_ether_init(struct device *dev, struct linux_sbus_device *sdev) { static unsigned version_printed = 0; struct device *qe_devs[4]; @@ -1149,7 +1150,7 @@ return res; } -int qec_probe(struct device *dev) +__initfunc(int qec_probe(struct device *dev)) { struct linux_sbus *bus; struct linux_sbus_device *sdev = 0; diff -u --recursive v2.1.35/linux/drivers/net/wavelan.c linux/drivers/net/wavelan.c --- v2.1.35/linux/drivers/net/wavelan.c Fri Apr 4 08:52:22 1997 +++ linux/drivers/net/wavelan.c Thu Apr 17 14:40:36 1997 @@ -112,7 +112,7 @@ * Read from card's Host Adaptor Status Register. */ static inline u_short -hasr_read(u_short ioaddr) +hasr_read(u_long ioaddr) { return(inw(HASR(ioaddr))); } /* hasr_read */ @@ -122,7 +122,7 @@ * Write to card's Host Adapter Command Register. */ static inline void -hacr_write(u_short ioaddr, +hacr_write(u_long ioaddr, u_short hacr) { outw(hacr, HACR(ioaddr)); @@ -134,7 +134,7 @@ * those times when it is needed. */ static inline void -hacr_write_slow(u_short ioaddr, +hacr_write_slow(u_long ioaddr, u_short hacr) { hacr_write(ioaddr, hacr); @@ -147,7 +147,7 @@ * Set the channel attention bit. */ static inline void -set_chan_attn(u_short ioaddr, +set_chan_attn(u_long ioaddr, u_short hacr) { hacr_write(ioaddr, hacr | HACR_CA); @@ -158,7 +158,7 @@ * Reset, and then set host adaptor into default mode. */ static inline void -wv_hacr_reset(u_short ioaddr) +wv_hacr_reset(u_long ioaddr) { hacr_write_slow(ioaddr, HACR_RESET); hacr_write(ioaddr, HACR_DEFAULT); @@ -169,7 +169,7 @@ * Set the i/o transfer over the ISA bus to 8 bits mode */ static inline void -wv_16_off(u_short ioaddr, +wv_16_off(u_long ioaddr, u_short hacr) { hacr &= ~HACR_16BITS; @@ -181,7 +181,7 @@ * Set the i/o transfer over the ISA bus to 8 bits mode */ static inline void -wv_16_on(u_short ioaddr, +wv_16_on(u_long ioaddr, u_short hacr) { hacr |= HACR_16BITS; @@ -196,7 +196,7 @@ wv_ints_off(device * dev) { net_local * lp = (net_local *)dev->priv; - u_short ioaddr = dev->base_addr; + u_long ioaddr = dev->base_addr; u_long x; x = wv_splhi(); @@ -215,7 +215,7 @@ wv_ints_on(device * dev) { net_local * lp = (net_local *)dev->priv; - u_short ioaddr = dev->base_addr; + u_long ioaddr = dev->base_addr; u_long x; x = wv_splhi(); @@ -239,7 +239,7 @@ * Read bytes from the PSA. */ static void -psa_read(u_short ioaddr, +psa_read(u_long ioaddr, u_short hacr, int o, /* offset in PSA */ u_char * b, /* buffer to fill */ @@ -262,7 +262,7 @@ * Write the Paramter Storage Area to the WaveLAN card's memory */ static void -psa_write(u_short ioaddr, +psa_write(u_long ioaddr, u_short hacr, int o, /* Offset in psa */ u_char * b, /* Buffer in memory */ @@ -329,7 +329,7 @@ * Write 1 byte to the MMC. */ static inline void -mmc_out(u_short ioaddr, +mmc_out(u_long ioaddr, u_short o, u_char d) { @@ -347,7 +347,7 @@ * We start by the end because it is the way it should be ! */ static inline void -mmc_write(u_short ioaddr, +mmc_write(u_long ioaddr, u_char o, u_char * b, int n) @@ -365,7 +365,7 @@ * Optimised version for 1 byte, avoid using memory... */ static inline u_char -mmc_in(u_short ioaddr, +mmc_in(u_long ioaddr, u_short o) { while(inw(HASR(ioaddr)) & HASR_MMC_BUSY) @@ -386,7 +386,7 @@ * We start by the end because it is the way it should be ! */ static inline void -mmc_read(u_short ioaddr, +mmc_read(u_long ioaddr, u_char o, u_char * b, int n) @@ -400,11 +400,27 @@ /*------------------------------------------------------------------*/ /* + * Get the type of encryption available... + */ +static inline int +mmc_encr(u_long ioaddr) /* i/o port of the card */ +{ + int temp; + + temp = mmc_in(ioaddr, mmroff(0, mmr_des_avail)); + if((temp != MMR_DES_AVAIL_DES) && (temp != MMR_DES_AVAIL_AES)) + return 0; + else + return temp; +} + +/*------------------------------------------------------------------*/ +/* * Wait for the frequency EEprom to complete a command... * I hope this one will be optimally inlined... */ static inline void -fee_wait(u_short ioaddr, /* i/o port of the card */ +fee_wait(u_long ioaddr, /* i/o port of the card */ int delay, /* Base delay to wait for */ int number) /* Number of time to wait */ { @@ -420,7 +436,7 @@ * Read bytes from the Frequency EEprom (frequency select cards). */ static void -fee_read(u_short ioaddr, /* i/o port of the card */ +fee_read(u_long ioaddr, /* i/o port of the card */ u_short o, /* destination offset */ u_short * b, /* data buffer */ int n) /* number of registers */ @@ -445,6 +461,8 @@ } } +#ifdef WIRELESS_EXT /* If wireless extension exist in the kernel */ + /*------------------------------------------------------------------*/ /* * Write bytes from the Frequency EEprom (frequency select cards). @@ -453,7 +471,7 @@ * Jean II */ static void -fee_write(u_short ioaddr, /* i/o port of the card */ +fee_write(u_long ioaddr, /* i/o port of the card */ u_short o, /* destination offset */ u_short * b, /* data buffer */ int n) /* number of registers */ @@ -528,6 +546,7 @@ fee_wait(ioaddr, 10, 100); #endif /* EEPROM_IS_PROTECTED */ } +#endif /* WIRELESS_EXT */ /************************ I82586 SUBROUTINES *************************/ /* @@ -540,7 +559,7 @@ * Why inlining this function make it fail ??? */ static /*inline*/ void -obram_read(u_short ioaddr, +obram_read(u_long ioaddr, u_short o, u_char * b, int n) @@ -554,7 +573,7 @@ * Write bytes to the on-board RAM. */ static inline void -obram_write(u_short ioaddr, +obram_write(u_long ioaddr, u_short o, u_char * b, int n) @@ -571,7 +590,7 @@ wv_ack(device * dev) { net_local * lp = (net_local *)dev->priv; - u_short ioaddr = dev->base_addr; + u_long ioaddr = dev->base_addr; u_short scb_cs; int i; @@ -614,7 +633,7 @@ const char * str) { net_local * lp = (net_local *)dev->priv; - u_short ioaddr = dev->base_addr; + u_long ioaddr = dev->base_addr; u_short scb_cmd; ach_t cb; int i; @@ -660,7 +679,7 @@ */ static inline int wv_config_complete(device * dev, - u_short ioaddr, + u_long ioaddr, net_local * lp) { unsigned short mcs_addr; @@ -722,7 +741,7 @@ */ static int wv_complete(device * dev, - u_short ioaddr, + u_long ioaddr, net_local * lp) { int nreaped = 0; @@ -992,7 +1011,7 @@ static void wv_mmc_show(device * dev) { - u_short ioaddr = dev->base_addr; + u_long ioaddr = dev->base_addr; net_local * lp = (net_local *)dev->priv; mmr_t m; @@ -1077,7 +1096,7 @@ * Print the last block of the i82586 memory */ static void -wv_scb_show(unsigned short ioaddr) +wv_scb_show(u_long ioaddr) { scb_t scb; @@ -1162,7 +1181,7 @@ int i, u_short p) { - unsigned short ioaddr; + u_long ioaddr; ac_tx_t actx; ioaddr = dev->base_addr; @@ -1529,7 +1548,7 @@ * (called in wavelan_ioctl) */ static inline int -wv_set_frequency(u_short ioaddr, /* i/o port of the card */ +wv_set_frequency(u_long ioaddr, /* i/o port of the card */ iw_freq * frequency) { const int BAND_NUM = 10; /* Number of bands */ @@ -1550,7 +1569,7 @@ } /* Setting by channel (same as wfreqsel) */ - /* Warning : each channel is 11MHz wide, so some of the channels + /* Warning : each channel is 22MHz wide, so some of the channels * will interfere... */ if((frequency->e == 0) && (frequency->m >= 0) && (frequency->m < BAND_NUM)) @@ -1729,7 +1748,7 @@ * Give the list of available frequencies */ static inline int -wv_frequency_list(u_short ioaddr, /* i/o port of the card */ +wv_frequency_list(u_long ioaddr, /* i/o port of the card */ iw_freq * list, /* List of frequency to fill */ int max) /* Maximum number of frequencies */ { @@ -1826,7 +1845,7 @@ struct ifreq * rq, /* Data passed */ int cmd) /* Ioctl number */ { - unsigned short ioaddr = dev->base_addr; + u_long ioaddr = dev->base_addr; net_local * lp = (net_local *)dev->priv; /* lp is not unused */ struct iwreq * wrq = (struct iwreq *) rq; psa_t psa; @@ -1866,9 +1885,7 @@ m.w.mmw_netw_id_h = (wrq->u.nwid.nwid & 0xFF00) >> 8; mmc_write(ioaddr, (char *)&m.w.mmw_netw_id_l - (char *)&m, (unsigned char *)&m.w.mmw_netw_id_l, 2); - m.w.mmw_loopt_sel = 0x00; - mmc_write(ioaddr, (char *)&m.w.mmw_loopt_sel - (char *)&m, - (unsigned char *)&m.w.mmw_loopt_sel, 1); + mmc_out(ioaddr, mmwoff(0, mmw_loopt_sel), 0x00); } else { @@ -1878,10 +1895,8 @@ (char *)&psa.psa_nwid_select - (char *)&psa, (unsigned char *)&psa.psa_nwid_select, 1); - /* Disable nwid in the mmc (no check) */ - m.w.mmw_loopt_sel = MMW_LOOPT_SEL_DIS_NWID; - mmc_write(ioaddr, (char *)&m.w.mmw_loopt_sel - (char *)&m, - (unsigned char *)&m.w.mmw_loopt_sel, 1); + /* Disable nwid in the mmc (no filtering) */ + mmc_out(ioaddr, mmwoff(0, mmw_loopt_sel), MMW_LOOPT_SEL_DIS_NWID); } break; @@ -1950,6 +1965,82 @@ wrq->u.sensitivity = psa.psa_thr_pre_set & 0x3F; break; + case SIOCSIWENCODE: + /* Set encryption key */ + if(!mmc_encr(ioaddr)) + { + ret = -EOPNOTSUPP; + break; + } + + if(wrq->u.encoding.method) + { /* enable encryption */ + int i; + long long key = wrq->u.encoding.code; + + for(i = 7; i >= 0; i--) + { + psa.psa_encryption_key[i] = key & 0xFF; + key >>= 8; + } + psa.psa_encryption_select = 1; + psa_write(ioaddr, lp->hacr, + (char *) &psa.psa_encryption_select - (char *) &psa, + (unsigned char *) &psa.psa_encryption_select, 8+1); + + mmc_out(ioaddr, mmwoff(0, mmw_encr_enable), + MMW_ENCR_ENABLE_EN | MMW_ENCR_ENABLE_MODE); + mmc_write(ioaddr, mmwoff(0, mmw_encr_key), + (unsigned char *) &psa.psa_encryption_key, 8); + } + else + { /* disable encryption */ + psa.psa_encryption_select = 0; + psa_write(ioaddr, lp->hacr, + (char *) &psa.psa_encryption_select - (char *) &psa, + (unsigned char *) &psa.psa_encryption_select, 1); + + mmc_out(ioaddr, mmwoff(0, mmw_encr_enable), 0); + } + break; + + case SIOCGIWENCODE: + /* Read the encryption key */ + if(!mmc_encr(ioaddr)) + { + ret = -EOPNOTSUPP; + break; + } + + /* only super-user can see encryption key */ + if(!suser()) + { + ret = -EPERM; + break; + } + else + { + int i; + long long key = 0; + + psa_read(ioaddr, lp->hacr, + (char *) &psa.psa_encryption_select - (char *) &psa, + (unsigned char *) &psa.psa_encryption_select, 1+8); + for(i = 0; i < 8; i++) + { + key <<= 8; + key += psa.psa_encryption_key[i]; + } + wrq->u.encoding.code = key; + + /* encryption is enabled */ + if(psa.psa_encryption_select) + wrq->u.encoding.method = mmc_encr(ioaddr); + else + wrq->u.encoding.method = 0; + } + break; + case SIOCGIWRANGE: /* Basic checking... */ if(wrq->u.data.pointer != (caddr_t) 0) @@ -2207,7 +2298,7 @@ static iw_stats * wavelan_get_wireless_stats(device * dev) { - unsigned short ioaddr = dev->base_addr; + u_long ioaddr = dev->base_addr; net_local * lp = (net_local *) dev->priv; mmr_t m; iw_stats * wstats; @@ -2281,7 +2372,7 @@ int sksize) { net_local * lp = (net_local *) dev->priv; - u_short ioaddr = dev->base_addr; + u_long ioaddr = dev->base_addr; struct sk_buff * skb; #ifdef DEBUG_RX_TRACE @@ -2353,8 +2444,9 @@ */ netif_rx(skb); + /* Keep stats up to date */ lp->stats.rx_packets++; - lp->stats.rx_bytes+=sksize; + lp->stats.rx_bytes += skb->len; #ifdef DEBUG_RX_TRACE printk(KERN_DEBUG "%s: <-wv_packet_read()\n", dev->name); @@ -2370,7 +2462,7 @@ static inline void wv_receive(device * dev) { - u_short ioaddr = dev->base_addr; + u_long ioaddr = dev->base_addr; net_local * lp = (net_local *)dev->priv; int nreaped = 0; @@ -2556,7 +2648,7 @@ short length) { net_local * lp = (net_local *) dev->priv; - u_short ioaddr = dev->base_addr; + u_long ioaddr = dev->base_addr; unsigned short txblock; unsigned short txpred; unsigned short tx_addr; @@ -2649,6 +2741,9 @@ (unsigned char *) &nop.nop_h.ac_link, sizeof(nop.nop_h.ac_link)); + /* Keep stats up to date */ + lp->stats.tx_bytes += length; + /* If watchdog not already active, activate it... */ if(lp->watchdog.prev == (timer_list *) NULL) { @@ -2701,20 +2796,6 @@ return 1; /* - * If some higher layer thinks we've missed - * a tx-done interrupt we are passed NULL. - * Caution: dev_tint() handles the cli()/sti() itself. - */ - if(skb == (struct sk_buff *)0) - { -#ifdef DEBUG_TX_ERROR - printk(KERN_INFO "%s: wavelan_packet_xmit(): skb == NULL\n", dev->name); -#endif - dev_tint(dev); - return 0; - } - - /* * Block a timer-based transmit from overlapping. * In other words, prevent reentering this routine. */ @@ -2761,7 +2842,7 @@ static inline int wv_mmc_init(device * dev) { - u_short ioaddr = dev->base_addr; + u_long ioaddr = dev->base_addr; net_local * lp = (net_local *)dev->priv; psa_t psa; mmw_t m; @@ -2790,6 +2871,9 @@ /* As NWID is not set : no NWID checking */ psa.psa_nwid_select = 0; + /* Disable encryption */ + psa.psa_encryption_select = 0; + /* Set to standard values * 0x04 for AT, * 0x01 for MCA, @@ -2807,7 +2891,7 @@ #ifdef USE_PSA_CONFIG /* Write the psa */ psa_write(ioaddr, lp->hacr, (char *)psa.psa_nwid - (char *)&psa, - (unsigned char *)psa.psa_nwid, 3); + (unsigned char *)psa.psa_nwid, 4); psa_write(ioaddr, lp->hacr, (char *)&psa.psa_thr_pre_set - (char *)&psa, (unsigned char *)&psa.psa_thr_pre_set, 1); psa_write(ioaddr, lp->hacr, (char *)&psa.psa_quality_thr - (char *)&psa, @@ -2829,6 +2913,14 @@ else m.mmw_loopt_sel = MMW_LOOPT_SEL_DIS_NWID; + memcpy(&m.mmw_encr_key, &psa.psa_encryption_key, + sizeof(m.mmw_encr_key)); + + if(psa.psa_encryption_select) + m.mmw_encr_enable = MMW_ENCR_ENABLE_EN | MMW_ENCR_ENABLE_MODE; + else + m.mmw_encr_enable = 0; + m.mmw_thr_pre_set = psa.psa_thr_pre_set & 0x3F; m.mmw_quality_thr = psa.psa_quality_thr & 0x0F; @@ -2920,7 +3012,7 @@ wv_ru_start(device * dev) { net_local * lp = (net_local *) dev->priv; - u_short ioaddr = dev->base_addr; + u_long ioaddr = dev->base_addr; u_short scb_cs; fd_t fd; rbd_t rbd; @@ -3014,7 +3106,7 @@ wv_cu_start(device * dev) { net_local * lp = (net_local *) dev->priv; - u_short ioaddr = dev->base_addr; + u_long ioaddr = dev->base_addr; int i; u_short txblock; u_short first_nop; @@ -3115,7 +3207,7 @@ wv_82586_start(device * dev) { net_local * lp = (net_local *) dev->priv; - u_short ioaddr = dev->base_addr; + u_long ioaddr = dev->base_addr; scp_t scp; /* system configuration pointer */ iscp_t iscp; /* intermediate scp */ scb_t scb; /* system control block */ @@ -3245,7 +3337,7 @@ wv_82586_config(device * dev) { net_local * lp = (net_local *) dev->priv; - u_short ioaddr = dev->base_addr; + u_long ioaddr = dev->base_addr; unsigned short txblock; unsigned short txpred; unsigned short tx_addr; @@ -3441,7 +3533,7 @@ wv_82586_stop(device * dev) { net_local * lp = (net_local *) dev->priv; - u_short ioaddr = dev->base_addr; + u_long ioaddr = dev->base_addr; u_short scb_cmd; #ifdef DEBUG_CONFIG_TRACE @@ -3476,7 +3568,7 @@ wv_hw_reset(device * dev) { net_local * lp = (net_local *)dev->priv; - u_short ioaddr = dev->base_addr; + u_long ioaddr = dev->base_addr; #ifdef DEBUG_CONFIG_TRACE printk(KERN_DEBUG "%s: ->wv_hw_reset(dev=0x%x)\n", dev->name, @@ -3521,7 +3613,7 @@ * (called in wavelan_probe() and init_module()) */ static int -wv_check_ioaddr(u_short ioaddr, +wv_check_ioaddr(u_long ioaddr, u_char * mac) { int i; /* Loop counter */ @@ -3568,7 +3660,7 @@ struct pt_regs * regs) { device * dev; - u_short ioaddr; + u_long ioaddr; net_local * lp; u_short hasr; u_short status; @@ -3715,7 +3807,7 @@ { device * dev; net_local * lp; - unsigned short ioaddr; + u_long ioaddr; unsigned long x; unsigned int nreaped; @@ -3910,7 +4002,7 @@ static int wavelan_config(device * dev) { - u_short ioaddr = dev->base_addr; + u_long ioaddr = dev->base_addr; u_char irq_mask; int irq; net_local * lp; diff -u --recursive v2.1.35/linux/drivers/net/wavelan.p.h linux/drivers/net/wavelan.p.h --- v2.1.35/linux/drivers/net/wavelan.p.h Mon Mar 17 14:54:27 1997 +++ linux/drivers/net/wavelan.p.h Thu Apr 17 14:40:36 1997 @@ -35,6 +35,12 @@ /* ------------------------ SPECIFIC NOTES ------------------------ */ /* + * wavelan.o is darn too big + * ------------------------- + * That's true ! There is a very simple way to reduce the driver + * object by 33% (yes !). Comment out the following line : + * #include + * * MAC address and hardware detection : * ---------------------------------- * The detection code of the wavelan chech that the first 3 @@ -80,14 +86,12 @@ * caracteristics of the hardware in a standard way and support for * applications for taking advantage of it (like Mobile IP). * - * By default, these wireless extensions are disabled, because they - * need a patch to the Linux Kernel. This simple patch may be found - * with the driver + some utilities to access those wireless - * extensions (iwconfig...). Hopefully, those wireless extensions will - * make their way in the kernel someday. + * You will need to enable the CONFIG_NET_RADIO define in the kernel + * configuration to enable the wireless extensions (this is the one + * giving access to the radio network device choice). * - * You also will need to enable the CONFIG_NET_RADIO in the kernel - * configuration to enable the wireless extensions. + * It might also be a good idea as well to fetch the wireless tools to + * configure the device and play a bit. */ /* ---------------------------- FILES ---------------------------- */ @@ -161,6 +165,7 @@ * Ajay Bakre (bakre@paul.rutgers.edu), * Donald Becker (becker@cesdis.gsfc.nasa.gov), * Loeke Brederveld (Loeke.Brederveld@Utrecht.NCR.com), + * Brent Elphick , * Anders Klemets (klemets@it.kth.se), * Vladimir V. Kolpakov (w@stier.koenig.ru), * Marc Meertens (Marc.Meertens@Utrecht.NCR.com), @@ -185,6 +190,7 @@ * John Rosenberg (johnr@cs.usyd.edu.au), * George Rossi (george@phm.gov.au), * Arthur Scott (arthur@cs.usyd.edu.au), + * Stanislav Sinyagin * Peter Storey, * for their assistance and advice. * @@ -254,16 +260,22 @@ * - Update to wireless extensions changes * - Silly bug in card initial configuration (psa_conf_status) * - * Changes made for release in 2.1.27 : - * ---------------------------------- + * Changes made for release in 2.1.27 & 2.0.30 : + * ------------------------------------------- * - Small bug in debug code (probably not the last one...) * - Remove extern kerword for wavelan_probe() * - Level threshold is now a standard wireless extension (version 4 !) * - modules parameters types (new module interface) * + * Changes made for release in 2.1.36 : + * ---------------------------------- + * - byte count stats (courtesy of David Hinds) + * - Remove dev_tint stuff (courtesy of David Hinds) + * - Encryption setting from Brent Elphick (thanks a lot !) + * - 'ioaddr' to 'u_long' for the Alpha (thanks to Stanislav Sinyagin) + * * Wishes & dreams : * --------------- - * - Encryption stuff * - Roaming */ @@ -347,7 +359,7 @@ /************************ CONSTANTS & MACROS ************************/ #ifdef DEBUG_VERSION_SHOW -static const char *version = "wavelan.c : v15 (wireless extensions) 12/2/97\n"; +static const char *version = "wavelan.c : v16 (wireless extensions) 17/4/97\n"; #endif /* Watchdog temporisation */ @@ -436,69 +448,65 @@ wv_psa_to_irq(u_char); /* ------------------- HOST ADAPTER SUBROUTINES ------------------- */ static inline u_short /* data */ - hasr_read(u_short); /* Read the host interface : base address */ + hasr_read(u_long); /* Read the host interface : base address */ static inline void - hacr_write(u_short, /* Write to host interface : base address */ + hacr_write(u_long, /* Write to host interface : base address */ u_short), /* data */ - hacr_write_slow(u_short, + hacr_write_slow(u_long, u_short), - set_chan_attn(u_short, /* ioaddr */ + set_chan_attn(u_long, /* ioaddr */ u_short), /* hacr */ - wv_hacr_reset(u_short), /* ioaddr */ - wv_16_off(u_short, /* ioaddr */ + wv_hacr_reset(u_long), /* ioaddr */ + wv_16_off(u_long, /* ioaddr */ u_short), /* hacr */ - wv_16_on(u_short, /* ioaddr */ + wv_16_on(u_long, /* ioaddr */ u_short), /* hacr */ wv_ints_off(device *), wv_ints_on(device *); /* ----------------- MODEM MANAGEMENT SUBROUTINES ----------------- */ static void - psa_read(u_short, /* Read the Parameter Storage Area */ + psa_read(u_long, /* Read the Parameter Storage Area */ u_short, /* hacr */ int, /* offset in PSA */ u_char *, /* buffer to fill */ int), /* size to read */ - psa_write(u_short, /* Write to the PSA */ + psa_write(u_long, /* Write to the PSA */ u_short, /* hacr */ int, /* Offset in psa */ u_char *, /* Buffer in memory */ int); /* Length of buffer */ static inline void - mmc_out(u_short, /* Write 1 byte to the Modem Manag Control */ + mmc_out(u_long, /* Write 1 byte to the Modem Manag Control */ u_short, u_char), - mmc_write(u_short, /* Write n bytes to the MMC */ + mmc_write(u_long, /* Write n bytes to the MMC */ u_char, u_char *, int); static inline u_char /* Read 1 byte from the MMC */ - mmc_in(u_short, + mmc_in(u_long, u_short); static inline void - mmc_read(u_short, /* Read n bytes from the MMC */ + mmc_read(u_long, /* Read n bytes from the MMC */ u_char, u_char *, int), - fee_wait(u_short, /* Wait for frequency EEprom : base address */ + fee_wait(u_long, /* Wait for frequency EEprom : base address */ int, /* Base delay to wait for */ int); /* Number of time to wait */ static void - fee_read(u_short, /* Read the frequency EEprom : base address */ + fee_read(u_long, /* Read the frequency EEprom : base address */ u_short, /* destination offset */ u_short *, /* data buffer */ - int), /* number of registers */ - fee_write(u_short, /* Write to frequency EEprom : base address */ - u_short, /* destination offset */ - u_short *, /* data buffer */ - int); /* number of registers */ + int); /* number of registers */ /* ---------------------- I82586 SUBROUTINES ----------------------- */ static /*inline*/ void - obram_read(u_short, /* ioaddr */ + obram_read(u_long, /* ioaddr */ u_short, /* o */ u_char *, /* b */ int); /* n */ static inline void - obram_write(u_short, /* ioaddr */ + obram_write(u_long, /* ioaddr */ u_short, /* o */ u_char *, /* b */ int); /* n */ @@ -508,11 +516,11 @@ wv_synchronous_cmd(device *, const char *), wv_config_complete(device *, - u_short, + u_long, net_local *); static int wv_complete(device *, - u_short, + u_long, net_local *); static inline void wv_82586_reconfig(device *); @@ -554,7 +562,7 @@ wv_82586_stop(device *); static int wv_hw_reset(device *), /* Reset the wavelan hardware */ - wv_check_ioaddr(u_short, /* ioaddr */ + wv_check_ioaddr(u_long, /* ioaddr */ u_char *); /* mac address (read) */ /* ---------------------- INTERRUPT HANDLING ---------------------- */ static void diff -u --recursive v2.1.35/linux/drivers/pnp/BUGS-parport linux/drivers/pnp/BUGS-parport --- v2.1.35/linux/drivers/pnp/BUGS-parport Sun Apr 13 10:18:21 1997 +++ linux/drivers/pnp/BUGS-parport Thu Apr 17 14:48:53 1997 @@ -1,8 +1,6 @@ Currently known (or at least suspected) bugs in parport: -o /proc/parport is buggy under 2.0.29 (ls /proc/parport/0 gives no such - file or directory). David has suggested a fix for this. [/proc/parport - has been temporarily taken out] +o /proc/parport is untested under 2.0.XX o SCSI aborts for PPA under 2.0.29 [reported by jmr]. Under investigation. diff -u --recursive v2.1.35/linux/drivers/pnp/Makefile linux/drivers/pnp/Makefile --- v2.1.35/linux/drivers/pnp/Makefile Sun Apr 13 10:18:21 1997 +++ linux/drivers/pnp/Makefile Thu Apr 17 14:48:53 1997 @@ -23,14 +23,20 @@ MIX_OBJS := ifeq ($(CONFIG_PNP_PARPORT),y) - L_OBJS += parport_share.o parport_procfs.o + L_OBJS += parport_share.o + ifeq ($(CONFIG_PROC_FS),y) + L_OBJS += parport_procfs.o + endif ifeq ($(CONFIG_PNP_PARPORT_AUTOPROBE),y) L_OBJS += parport_probe.o endif LX_OBJS += parport_init.o else ifeq ($(CONFIG_PNP_PARPORT),m) - MI_OBJS += parport_share.o parport_procfs.o + MI_OBJS += parport_share.o + ifneq ($(CONFIG_PROC_FS),n) + MI_OBJS += parport_procfs.o + endif ifeq ($(CONFIG_PNP_PARPORT_AUTOPROBE),y) MI_OBJS += parport_probe.o endif diff -u --recursive v2.1.35/linux/drivers/pnp/TODO-parport linux/drivers/pnp/TODO-parport --- v2.1.35/linux/drivers/pnp/TODO-parport Sun Apr 13 10:18:21 1997 +++ linux/drivers/pnp/TODO-parport Thu Apr 17 14:48:53 1997 @@ -2,31 +2,9 @@ 0. Fix the bugs (see BUGS-parport). -1. Write a /proc interface for parport. As a starting point, we could - probably have something like this: +1. Proper documentation. - /proc/parport/N/hardware - - Details of the port hardware - chipset, capabilities and so on. - Read-only. - - /proc/parport/N/irq - - IRQ number of the port. Read-write. - - /proc/parport/N/devices - - List of devices connected to this bus, with the currently active - one marked in some way. Probably you'd have the device in the - first column, and '*' (for the current device) or '-' (for a - lurker) in the second column. - - NOTE: The directory structure has been coded -- but the files are - missing ... - -2. Proper documentation. - -3. Overhaul lp.c: +2. Overhaul lp.c: a) It's a mess, and there is a lot of code duplication. @@ -40,4 +18,4 @@ bits when they have something to say. We should read out and deal with (maybe just log) whatever the printer wants to tell the world. -4. Assimilate more drivers. +3. Assimilate more drivers. diff -u --recursive v2.1.35/linux/drivers/pnp/parport_init.c linux/drivers/pnp/parport_init.c --- v2.1.35/linux/drivers/pnp/parport_init.c Mon Apr 14 16:28:12 1997 +++ linux/drivers/pnp/parport_init.c Thu Apr 17 15:04:40 1997 @@ -1,4 +1,4 @@ -/* $Id: parport_init.c,v 1.1.2.4 1997/04/01 18:19:10 phil Exp $ +/* $Id: parport_init.c,v 1.3.2.4 1997/04/16 21:20:44 phil Exp $ * Parallel-port initialisation code. * * Authors: David Campbell @@ -26,8 +26,8 @@ #include "parport_ll_io.h" static int io[PARPORT_MAX] = { 0, }; -static int irq[PARPORT_MAX] = { -1, }; -static int dma[PARPORT_MAX] = { -1, }; +static int irq[PARPORT_MAX] = { PARPORT_IRQ_NONE, }; +static int dma[PARPORT_MAX] = { PARPORT_DMA_NONE, }; /****************************************************** * DMA detection section: @@ -76,7 +76,7 @@ return dma; } -static int parport_detect_dma_transfer(int dma,int size) +static int parport_detect_dma_transfer(int dma,int size,int *resid) { int i,n,retv; int count=0; @@ -88,10 +88,11 @@ clear_dma_ff(i); n = get_dma_residue(i); if (n != size) { + *resid = n; retv = i; if (count > 0) { retv = -1; /* Multiple DMA's */ - printk("Multiple DMA detected.\n"); + printk(KERN_ERR "parport: multiple DMA detected. Huh?\n"); } count++; } @@ -118,7 +119,7 @@ return dma; } -/* Only called if port support ECP mode. +/* Only called if port supports ECP mode. * * The only restriction on DMA channels is that it has to be * between 0 to 7 (inclusive). Used only in an ECP mode, DMAs are @@ -146,12 +147,11 @@ char *buff; retv = programmable_dma_support(pb); - if( retv != -1 ) + if (retv != -1) return retv; - buff = kmalloc(16, GFP_KERNEL | GFP_DMA); - if( !buff ){ - printk("parport: memory squezze\n"); + if (!(buff = kmalloc(2048, GFP_KERNEL | GFP_DMA))) { + printk(KERN_ERR "parport: memory squeeze\n"); return -1; } @@ -160,24 +160,26 @@ w_ecr(pb, 0xc0); /* ECP MODE */ w_ctr(pb, dsr_read ); - dma=parport_prepare_dma(buff,8); + dma=parport_prepare_dma(buff,1000); w_ecr(pb, 0xd8); /* ECP FIFO + enable DMA */ parport_enable_dma(dma); - udelay(30); /* Give some for DMA tranfer */ - retv = parport_detect_dma_transfer(dma,8); + udelay(500); /* Give some for DMA tranfer */ + retv = parport_detect_dma_transfer(dma,1000,&pb->speed); + pb->speed = pb->speed * 2000; /* 500uSec * 2000 = 1sec */ /* * National Semiconductors only supports DMA tranfers * in ECP MODE */ - if( retv == -1 ){ + if (retv == -1) { w_ecr(pb, 0x60); /* ECP MODE */ w_ctr(pb, dsr_read ); - dma=parport_prepare_dma(buff,8); + dma=parport_prepare_dma(buff,1000); w_ecr(pb, 0x68); /* ECP FIFO + enable DMA */ parport_enable_dma(dma); - udelay(30); /* Give some for DMA tranfer */ - retv = parport_detect_dma_transfer(dma,8); + udelay(500); /* Give some for DMA tranfer */ + retv = parport_detect_dma_transfer(dma,1000,&pb->speed); + pb->speed = pb->speed * 2000; /* 500uSec * 2000 = 1sec */ } kfree(buff); @@ -198,10 +200,10 @@ { int r; - if( !(r_str(pb) & 0x01) ) + if (!(r_str(pb) & 0x01)) return 1; - /* To clear timeout some chip requiere double read */ + /* To clear timeout some chips require double read */ r_str(pb); r = r_str(pb); w_str(pb, r | 0x01); /* Some reset by writing 1 */ @@ -213,23 +215,18 @@ /* - * Checks for por existence, all ports support SPP MODE + * Checks for port existence, all ports support SPP MODE */ static int parport_SPP_supported(struct parport *pb) { - int r,rr; - /* Do a simple read-write test to make sure the port exists. */ + w_dtr(pb, 0xaa); - r = r_dtr(pb); + if (r_dtr(pb) != 0xaa) return 0; w_dtr(pb, 0x55); - rr = r_dtr(pb); - - if (r != 0xaa || rr != 0x55) { - return 0; - } - + if (r_dtr(pb) != 0x55) return 0; + return PARPORT_MODE_SPP; } @@ -249,23 +246,20 @@ { int r; - if( pb->base == 0x3BC ) - return 0; - r= r_ctr(pb); - if( (r_ecr(pb) & 0x03) == (r & 0x03) ){ + if ((r_ecr(pb) & 0x03) == (r & 0x03)) { w_ctr(pb, r ^ 0x03 ); /* Toggle bits 0-1 */ r= r_ctr(pb); - if( (r_ecr(pb) & 0x03) == (r & 0x03) ) + if ((r_ecr(pb) & 0x03) == (r & 0x03)) return 0; /* Sure that no ECR register exists */ } - if( (r_ecr(pb) & 0x03 ) != 0x01 ) + if ((r_ecr(pb) & 0x03 ) != 0x01) return 0; w_ecr(pb,0x34); - if( r_ecr(pb) != 0x35 ) + if (r_ecr(pb) != 0x35) return 0; w_ecr(pb,pb->ecr); @@ -278,20 +272,22 @@ { int i; - if( !(pb->modes & PARPORT_MODE_ECR) ) + /* If there is no ECR, we have no hope of supporting ECP. */ + if (!(pb->modes & PARPORT_MODE_ECR)) return 0; + /* - * Usign LGS chipset it uses ECR register, but + * Using LGS chipset it uses ECR register, but * it doesn't support ECP or FIFO MODE */ - w_ecr(pb,0xc0); /* TEST FIFO */ - for( i=0 ; i < 1024 && (r_ecr(pb) & 0x01) ; i++ ) + w_ecr(pb, 0xc0); /* TEST FIFO */ + for (i=0; i < 1024 && (r_ecr(pb) & 0x01); i++) w_fifo(pb, 0xaa); - w_ecr(pb,pb->ecr); + w_ecr(pb, pb->ecr); - if( i >= 1024 ) + if (i == 1024) return 0; return PARPORT_MODE_ECP; @@ -311,11 +307,8 @@ */ static int parport_EPP_supported(struct parport *pb) { - if( pb->base == 0x3BC ) - return 0; - /* If EPP timeout bit clear then EPP available */ - if( !epp_clear_timeout(pb) ) + if (!epp_clear_timeout(pb)) return 0; /* No way to clear timeout */ w_ctr(pb, r_ctr(pb) | 0x20); @@ -325,7 +318,7 @@ r_epp(pb); udelay(30); /* Wait for possible EPP timeout */ - if( r_str(pb) & 0x01 ){ + if (r_str(pb) & 0x01) { epp_clear_timeout(pb); return PARPORT_MODE_EPP; } @@ -337,7 +330,7 @@ { int mode; - if( !(pb->modes & PARPORT_MODE_ECR) ) + if (!(pb->modes & PARPORT_MODE_ECR)) return 0; /* Search for SMC style EPP+ECP mode */ @@ -345,47 +338,55 @@ mode = parport_EPP_supported(pb); - w_ecr(pb,pb->ecr); + w_ecr(pb, pb->ecr); - if( mode ) + if (mode) return PARPORT_MODE_ECPEPP; return 0; } -/* Detect LP_PS2 support - * Bit 5 (0x20) sets the PS/2 data direction, setting this high - * allows us to read data from the data lines, old style SPP ports - * will return 0xff. This may not be reliable if there is a - * peripheral attached to the port. +/* Detect PS/2 support. + * + * Bit 5 (0x20) sets the PS/2 data direction; setting this high + * allows us to read data from the data lines. In theory we would get back + * 0xff but any peripheral attached to the port may drag some or all of the + * lines down to zero. So if we get back anything that isn't the contents + * of the data register we deem PS/2 support to be present. + * + * Some SPP ports have "half PS/2" ability - you can't turn off the line + * drivers, but an external peripheral with sufficiently beefy drivers of + * its own can overpower them and assert its own levels onto the bus, from + * where they can then be read back as normal. Ports with this property + * and the right type of device attached are likely to fail the SPP test, + * (as they will appear to have stuck bits) and so the fact that they might + * be misdetected here is rather academic. */ + static int parport_PS2_supported(struct parport *pb) { - int r,rr; - + int ok = 0; + epp_clear_timeout(pb); - w_ctr(pb, pb->ctr | 0x20); /* Tri-state the buffer */ + w_ctr(pb, pb->ctr | 0x20); /* try to tri-state the buffer */ - w_dtr(pb, 0xAA); - r = r_dtr(pb); - w_dtr(pb, 0x55); - rr = r_dtr(pb); - - w_ctr(pb, pb->ctr); /* Reset CTR register */ + if (r_dtr(pb) != 0x55) ok++; - if (r != 0xAA || rr != 0x55 ) - return PARPORT_MODE_PS2; + w_dtr(pb, 0xaa); + if (r_dtr(pb) != 0xaa) ok++; - return 0; + w_ctr(pb, pb->ctr); /* cancel input mode */ + + return ok?PARPORT_MODE_PS2:0; } static int parport_ECPPS2_supported(struct parport *pb) { int mode; - if( !(pb->modes & PARPORT_MODE_ECR) ) + if (!(pb->modes & PARPORT_MODE_ECR)) return 0; w_ecr(pb, 0x20); @@ -402,15 +403,19 @@ /****************************************************** * IRQ detection section: - */ -/* + * * This code is for detecting ECP interrupts (due to problems with the * monolithic interrupt probing routines). * * In short this is a voting system where the interrupt with the most * "votes" is the elected interrupt (it SHOULD work...) + * + * This is horribly x86-specific at the moment. I'm not convinced it + * belongs at all. */ + static int intr_vote[16]; + static void parport_vote_intr_func(int irq, void *dev_id, struct pt_regs *regs) { intr_vote[irq]++; @@ -434,17 +439,16 @@ static int close_intr_election(long tmp) { - long max_vote = 0; - int irq = -1; + int irq = PARPORT_IRQ_NONE; int i; /* We ignore the timer - irq 0 */ for (i = 1; i < 16; i++) if (tmp & (1 << i)) { - if (intr_vote[i] > max_vote) { - if (max_vote) - return -1; - max_vote = intr_vote[i]; + if (intr_vote[i]) { + if (irq != PARPORT_IRQ_NONE) + /* More than one interrupt */ + return PARPORT_IRQ_NONE; irq = i; } free_irq(i, intr_vote); @@ -488,7 +492,7 @@ irqs = open_intr_election(); w_ecr(pb, 0x00); /* Reset FIFO */ - w_ctr(pb, pb->ctr ); /* Force direction = 0 */ + w_ctr(pb, pb->ctr ); /* Force direction = 0 */ w_ecr(pb, 0xd0); /* TEST FIFO + nErrIntrEn */ /* If Full FIFO sure that WriteIntrThresold is generated */ @@ -497,8 +501,6 @@ } pb->irq = close_intr_election(irqs); - if (pb->irq == 0) - pb->irq = -1; /* No interrupt detected */ w_ecr(pb, pb->ecr); @@ -506,7 +508,7 @@ } /* - * It's called only if supports EPP on National Semiconductors + * This detection seems that only works in National Semiconductors * This doesn't work in SMC, LGS, and Winbond */ static int irq_probe_EPP(struct parport *pb) @@ -535,8 +537,6 @@ udelay(20); pb->irq = close_intr_election(irqs); - if (pb->irq == 0) - pb->irq = -1; /* No interrupt detected */ w_ctr(pb,pb->ctr); @@ -572,7 +572,7 @@ pb->irq = probe_irq_off(irqs); if (pb->irq <= 0) - pb->irq = -1; /* No interrupt detected */ + pb->irq = PARPORT_IRQ_NONE; /* No interrupt detected */ w_ctr(pb,pb->ctr); @@ -583,18 +583,18 @@ * such as sound cards and network cards seem to like using the * printer IRQs. * - * When LP_ECP is available we can autoprobe for IRQs. + * When ECP is available we can autoprobe for IRQs. * NOTE: If we can autoprobe it, we can register the IRQ. */ static int parport_irq_probe(struct parport *pb) { - if( pb->modes & PARPORT_MODE_ECR ) + if (pb->modes & PARPORT_MODE_ECR) pb->irq = programmable_irq_support(pb); - if( pb->modes & PARPORT_MODE_ECP ) + if (pb->modes & PARPORT_MODE_ECP) pb->irq = irq_probe_ECP(pb); - if( pb->irq == -1 && (pb->modes & PARPORT_MODE_ECPEPP)){ + if (pb->irq == PARPORT_IRQ_NONE && (pb->modes & PARPORT_MODE_ECPEPP)) { w_ecr(pb,0x80); pb->irq = irq_probe_EPP(pb); w_ecr(pb,pb->ecr); @@ -602,12 +602,12 @@ epp_clear_timeout(pb); - if( pb->irq == -1 && (pb->modes & PARPORT_MODE_EPP)) + if (pb->irq == PARPORT_IRQ_NONE && (pb->modes & PARPORT_MODE_EPP)) pb->irq = irq_probe_EPP(pb); epp_clear_timeout(pb); - if( pb->irq == -1 ) + if (pb->irq == PARPORT_IRQ_NONE) pb->irq = irq_probe_SPP(pb); return pb->irq; @@ -618,12 +618,12 @@ { /* Check some parameters */ if (dma < -2) { - printk("parport: Invalid DMA[%d] at base 0x%lx\n",dma,base); + printk(KERN_ERR "parport: Invalid DMA[%d] at base 0x%lx\n",dma,base); return 0; } if (irq < -2) { - printk("parport: Invalid IRQ[%d] at base 0x%lx\n",irq,base); + printk(KERN_ERR "parport: Invalid IRQ[%d] at base 0x%lx\n",irq,base); return 0; } @@ -643,7 +643,7 @@ pb->name = kmalloc(15, GFP_KERNEL); if (!pb->name) { - printk("parport: memory squeeze\n"); + printk(KERN_ERR "parport: memory squeeze\n"); return 0; } sprintf(pb->name, "parport%d", count); @@ -657,12 +657,15 @@ } pb->modes |= PARPORT_MODE_SPP; /* All ports support SPP mode. */ - pb->modes |= parport_ECR_present(pb); - pb->modes |= parport_ECP_supported(pb); pb->modes |= parport_PS2_supported(pb); - pb->modes |= parport_ECPPS2_supported(pb); - pb->modes |= parport_EPP_supported(pb); - pb->modes |= parport_ECPEPP_supported(pb); + + if (pb->base != 0x3bc) { + pb->modes |= parport_ECR_present(pb); + pb->modes |= parport_ECP_supported(pb); + pb->modes |= parport_ECPPS2_supported(pb); + pb->modes |= parport_EPP_supported(pb); + pb->modes |= parport_ECPEPP_supported(pb); + } /* Now register regions */ if ((pb->modes & (PARPORT_MODE_EPP | PARPORT_MODE_ECPEPP)) && @@ -678,17 +681,17 @@ /* DMA check */ if (pb->modes & PARPORT_MODE_ECP) { - if (pb->dma == -1) + if (pb->dma == PARPORT_DMA_NONE) pb->dma = parport_dma_probe(pb); else if (pb->dma == -2) - pb->dma = -1; + pb->dma = PARPORT_DMA_NONE; } /* IRQ check */ - if (pb->irq == -1) + if (pb->irq == PARPORT_IRQ_NONE) pb->irq = parport_irq_probe(pb); else if (pb->irq == -2) - pb->irq = -1; + pb->irq = PARPORT_IRQ_NONE; return 1; } @@ -700,7 +703,7 @@ { if (ints[0] == 0 || ints[1] == 0) { /* Disable parport if "parport=" or "parport=0" in cmdline */ - io[0] = -2; + io[0] = PARPORT_DISABLE; return; } if (parport_setup_ptr < PARPORT_MAX) { @@ -738,17 +741,20 @@ struct parport *pb; printk(KERN_INFO "Parallel port sharing: %s\n", - "$Revision: 1.1.2.4 $"); + "$Revision: 1.3.2.4 $"); - if (io[0] == -2) return 1; + if (io[0] == PARPORT_DISABLE) return 1; - /* Register /proc/parport */ +#ifdef CONFIG_PROC_FS parport_proc_register(NULL); +#endif /* Run probes to ensure parport does exist */ #define PORT(a,b,c) \ if ((pb = parport_register_port((a), (b), (c)))) \ parport_destroy(pb); + + if (io[0]) { /* If the user specified any ports, use them */ int i; @@ -757,16 +763,22 @@ } } else { /* Go for the standard ports. */ - PORT(0x378, -1, -1); - PORT(0x278, -1, -1); - PORT(0x3bc, -1, -1); + PORT(0x378, PARPORT_IRQ_NONE, PARPORT_DMA_NONE); + PORT(0x278, PARPORT_IRQ_NONE, PARPORT_DMA_NONE); + PORT(0x3bc, PARPORT_IRQ_NONE, PARPORT_DMA_NONE); #undef PORT } +#if defined(CONFIG_PNP_PARPORT_AUTOPROBE) || defined(CONFIG_PROC_FS) + for (pb = parport_enumerate(); pb; pb = pb->next) { #ifdef CONFIG_PNP_PARPORT_AUTOPROBE - for (pb = parport_enumerate(); pb; pb = pb->next) parport_probe_one(pb); #endif +#ifdef CONFIG_PROC_FS + parport_proc_register(pb); +#endif + } +#endif return 0; } @@ -784,7 +796,7 @@ kfree(port); } - parport_proc_unregister(NULL); + parport_proc_cleanup(); } #endif diff -u --recursive v2.1.35/linux/drivers/pnp/parport_procfs.c linux/drivers/pnp/parport_procfs.c --- v2.1.35/linux/drivers/pnp/parport_procfs.c Mon Apr 14 16:28:13 1997 +++ linux/drivers/pnp/parport_procfs.c Thu Apr 17 14:48:53 1997 @@ -1,4 +1,4 @@ -/* $Id: parport_procfs.c,v 1.1.2.2 1997/03/26 17:50:36 phil Exp $ +/* $Id: parport_procfs.c,v 1.3.2.6 1997/04/16 21:30:38 phil Exp $ * Parallel port /proc interface code. * * Authors: David Campbell @@ -21,108 +21,320 @@ #include #include -#ifdef CONFIG_PROC_FS #include -#endif #include +#include "parport_ll_io.h" + +#undef PARPORT_INCLUDE_BENCH -#if defined(CONFIG_PROC_FS) && defined(NOT_DEFINED) +struct proc_dir_entry *base=NULL; -/************************************************/ -static long proc_readparport(struct inode * inode, struct file * file, - char * buf, unsigned long count) +void parport_null_intr_func(int irq, void *dev_id, struct pt_regs *regs); + +static int irq_write_proc(struct file *file, const char *buffer, + unsigned long count, void *data) { - printk("proc_readparport\n"); - return 0; + int newirq; + struct parport *pp = (struct parport *)data; + + if (count > 4 ) /* more than 4 digits for a irq 0x?? 0?? ?? */ + return(-EOVERFLOW); + + if (buffer[0] < 32 || !strncmp(buffer, "none", 4)) { + newirq = PARPORT_IRQ_NONE; + } else { + if (buffer[0] == '0') { + if( buffer[1] == 'x' ) + newirq = simple_strtoul(&buffer[2],0,16); + else + newirq = simple_strtoul(&buffer[1],0,8); + } else { + newirq = simple_strtoul(buffer,0,10); + } + } + + if (pp->irq != PARPORT_IRQ_NONE && !(pp->flags & PARPORT_FLAG_COMA)) + free_irq(pp->irq, pp); + + pp->irq = newirq; + + if (pp->irq != PARPORT_IRQ_NONE && !(pp->flags & PARPORT_FLAG_COMA)) { + struct ppd *pd = pp->cad; + + if (pd == NULL) { + pd = pp->devices; + if (pd != NULL) + request_irq(pp->irq, pd->irq_func ? + pd->irq_func : + parport_null_intr_func, + SA_INTERRUPT, pd->name, pd->port); + } else { + request_irq(pp->irq, pd->irq_func ? pd->irq_func : + parport_null_intr_func, + SA_INTERRUPT, pp->name, pd->port); + } + } + + return count; } -static long proc_writeparport(struct inode * inode, struct file * file, - const char * buf, unsigned long count) +static int irq_read_proc(char *page, char **start, off_t off, + int count, int *eof, void *data) { - printk("proc_writeparport\n"); + struct parport *pp = (struct parport *)data; + int len; - return 0; + if (pp->irq == PARPORT_IRQ_NONE) + len = sprintf(page, "none\n"); + else + len = sprintf(page, "%d\n", pp->irq); + + *start = 0; + *eof = 1; + return len; } -static long long proc_parportlseek(struct inode * inode, struct file * file, - long long offset, int orig) +static int devices_read_proc(char *page, char **start, off_t off, + int count, int *eof, void *data) { - switch (orig) { - case 0: - file->f_pos = offset; - return(file->f_pos); - case 1: - file->f_pos += offset; - return(file->f_pos); - case 2: - return(-EINVAL); - default: - return(-EINVAL); - } -} - -static struct file_operations proc_dir_operations = { - proc_parportlseek, /* lseek */ - proc_readparport, /* read */ - proc_writeparport, /* write */ - proc_readdir, /* readdir */ - NULL, /* poll */ - NULL, /* ioctl */ - NULL, /* mmap */ - NULL, /* no special open code */ - NULL, /* no special release code */ - NULL /* can't fsync */ -}; - -/************************************************/ -static struct inode_operations parport_proc_dir_inode_operations = { - &proc_dir_operations, /* default net directory file-ops */ - NULL, /* create */ - proc_lookup, /* lookup */ - NULL, /* link */ - NULL, /* unlink */ - NULL, /* symlink */ - NULL, /* mkdir */ - NULL, /* rmdir */ - NULL, /* mknod */ - NULL, /* rename */ - NULL, /* readlink */ - NULL, /* follow_link */ - NULL, /* readpage */ - NULL, /* writepage */ - NULL, /* bmap */ - NULL, /* truncate */ - NULL /* permission */ -}; - -static struct proc_dir_entry proc_root_parport = { - PROC_PARPORT, 7, "parport", - S_IFDIR | S_IRUGO | S_IXUGO, 2, 0, 0, - 0, &parport_proc_dir_inode_operations, - NULL, NULL, - NULL, &proc_root, NULL, - NULL, NULL -}; + struct parport *pp = (struct parport *)data; + struct ppd *pd1; + int len=0; + + for (pd1 = pp->devices; pd1 ; pd1 = pd1->next) { + if (pd1 == pp->cad) + len += sprintf(page+len, "+"); + else + len += sprintf(page+len, " "); + + len += sprintf(page+len, "%s",pd1->name); + + if (pd1 == pp->lurker) + len += sprintf(page+len, " LURK"); + + len += sprintf(page+len,"\n"); + } + + *start = 0; + *eof = 1; + return len; +} + +static int hardware_read_proc(char *page, char **start, off_t off, + int count, int *eof, void *data) +{ + struct parport *pp = (struct parport *)data; + int len=0; + + len += sprintf(page+len, "base:\t0x%x\n",pp->base); + if (pp->irq == PARPORT_IRQ_NONE) + len += sprintf(page+len, "irq:\tnone\n"); + else + len += sprintf(page+len, "irq:\t%d\n",pp->irq); + len += sprintf(page+len, "dma:\t%d\n",pp->dma); + + len += sprintf(page+len, "modes:\t"); + { +#define printmode(x) {if(pp->modes&PARPORT_MODE_##x){len+=sprintf(page+len,"%s%s",f?",":"",#x);f++;}} + int f = 0; + printmode(SPP); + printmode(PS2); + printmode(EPP); + printmode(ECP); + printmode(ECPEPP); + printmode(ECPPS2); +#undef printmode + } + len += sprintf(page+len, "\n"); + + len += sprintf(page+len, "mode:\t"); + if (pp->modes & PARPORT_MODE_ECR) { + switch (r_ecr(pp) >> 5) { + case 0: + len += sprintf(page+len, "SPP"); + if( pp->modes & PARPORT_MODE_PS2 ) + len += sprintf(page+len, ",PS2"); + if( pp->modes & PARPORT_MODE_EPP ) + len += sprintf(page+len, ",EPP"); + break; + case 1: + len += sprintf(page+len, "ECPPS2"); + break; + case 2: + len += sprintf(page+len, "DATAFIFO"); + break; + case 3: + len += sprintf(page+len, "ECP"); + break; + case 4: + len += sprintf(page+len, "ECPEPP"); + break; + case 5: + len += sprintf(page+len, "Reserved?"); + break; + case 6: + len += sprintf(page+len, "TEST"); + break; + case 7: + len += sprintf(page+len, "Configuration"); + break; + } + } else { + len += sprintf(page+len, "SPP"); + if (pp->modes & PARPORT_MODE_PS2) + len += sprintf(page+len, ",PS2"); + if (pp->modes & PARPORT_MODE_EPP) + len += sprintf(page+len, ",EPP"); + } + len += sprintf(page+len, "\n"); + +#if 0 + /* Now no detection, please fix with an external function */ + len += sprintf(page+len, "chipset:\tunknown\n"); #endif +#ifdef PARPORT_INCLUDE_BENCHMARK + if (pp->speed) + len += sprintf(page+len, "bench:\t%d Bytes/s\n",pp->speed); + else + len += sprintf(page+len, "bench:\tunknown\n"); +#endif + + *start = 0; + *eof = 1; + return len; +} + +static struct proc_dir_entry *new_proc_entry(const char *name, mode_t mode, + struct proc_dir_entry *parent, + unsigned short ino) +{ + struct proc_dir_entry *ent; + + ent = kmalloc(sizeof(struct proc_dir_entry), GFP_KERNEL); + if (!ent) + return NULL; + memset(ent, 0, sizeof(struct proc_dir_entry)); + + if (mode == S_IFDIR) + mode |= S_IRUGO | S_IXUGO; + else if (mode == 0) + mode = S_IFREG | S_IRUGO; + + + ent->low_ino = ino; + ent->name = name; + ent->namelen = strlen(name); + ent->mode = mode; + if (S_ISDIR(mode)) + ent->nlink = 2; + else + ent->nlink = 1; + + proc_register(parent, ent); + + return ent; +} + + +int parport_proc_init() +{ + base = new_proc_entry("parport", S_IFDIR, &proc_root,PROC_PARPORT); + + if (base) + return 1; + else { + printk(KERN_ERR "parport: Error creating proc entry /proc/parport\n"); + return 0; + } +} + +int parport_proc_cleanup() +{ + if (base) + proc_unregister(&proc_root,base->low_ino); + + base = NULL; + + return 0; +} int parport_proc_register(struct parport *pp) { -#if defined(CONFIG_PROC_FS) && defined(NOT_DEFINED) - return proc_register(&proc_root, &proc_root_parport); -#else + struct proc_dir_entry *ent; + static int conta=0; + char *name; + + memset(&pp->pdir,0,sizeof(struct parport_dir)); + + if (!base) { + printk(KERN_ERR "parport: Error entry /proc/parport, not generated?\n"); + return 1; + } + + name = pp->pdir.name; + sprintf(name,"%d",conta++); + + ent = new_proc_entry(name, S_IFDIR, base,0); + if (!ent) { + printk(KERN_ERR "parport: Error registering proc_entry /proc/%s\n",name); + return 1; + } + pp->pdir.entry = ent; + + ent = new_proc_entry("irq", S_IFREG | S_IRUGO | S_IWUSR, pp->pdir.entry,0); + if (!ent) { + printk(KERN_ERR "parport: Error registering proc_entry /proc/%s/irq\n",name); + return 1; + } + ent->read_proc = irq_read_proc; + ent->write_proc= irq_write_proc; + ent->data = pp; + pp->pdir.irq = ent; + + ent = new_proc_entry("devices", 0, pp->pdir.entry,0); + if (!ent) { + printk(KERN_ERR "parport: Error registering proc_entry /proc/%s/devices\n",name); + return 1; + } + ent->read_proc = devices_read_proc; + ent->data = pp; + pp->pdir.devices = ent; + + ent = new_proc_entry("hardware", 0, pp->pdir.entry,0); + if (!ent) { + printk(KERN_ERR "parport: Error registering proc_entry /proc/%s/hardware\n",name); + return 1; + } + ent->read_proc = hardware_read_proc; + ent->data = pp; + pp->pdir.hardware = ent; return 0; -#endif } -void parport_proc_unregister(struct parport *pp) +int parport_proc_unregister(struct parport *pp) { -#if defined(CONFIG_PROC_FS) && defined(NOT_DEFINED) - if( pp ){ - proc_unregister(&proc_root_parport, pp->proc_dir->low_ino); - kfree(pp->proc_dir); - }else{ - proc_unregister(&proc_root, proc_root_parport.low_ino); + if (pp->pdir.entry) { + if (pp->pdir.irq) { + proc_unregister(pp->pdir.entry, pp->pdir.irq->low_ino); + kfree(pp->pdir.irq); + } + + if (pp->pdir.devices) { + proc_unregister(pp->pdir.entry, + pp->pdir.devices->low_ino); + kfree(pp->pdir.devices); + } + + if (pp->pdir.hardware) { + proc_unregister(pp->pdir.entry, + pp->pdir.hardware->low_ino); + kfree(pp->pdir.hardware); + } + + proc_unregister(base, pp->pdir.entry->low_ino); + kfree(pp->pdir.entry); } -#endif + + return 0; } diff -u --recursive v2.1.35/linux/drivers/pnp/parport_share.c linux/drivers/pnp/parport_share.c --- v2.1.35/linux/drivers/pnp/parport_share.c Mon Apr 14 16:28:13 1997 +++ linux/drivers/pnp/parport_share.c Thu Apr 17 14:48:53 1997 @@ -1,4 +1,4 @@ -/* $Id: parport_share.c,v 1.1.2.4 1997/04/01 18:19:11 phil Exp $ +/* $Id: parport_share.c,v 1.3.2.5 1997/04/16 21:20:44 phil Exp $ * Parallel-port resource manager code. * * Authors: David Campbell @@ -21,6 +21,8 @@ #include #include +#undef PARPORT_PARANOID + #include "parport_ll_io.h" static struct parport *portlist = NULL, *portlist_tail = NULL; @@ -36,7 +38,7 @@ return portlist; } -static void parport_null_intr_func(int irq, void *dev_id, struct pt_regs *regs) +void parport_null_intr_func(int irq, void *dev_id, struct pt_regs *regs) { /* NULL function - Does nothing */ return; @@ -85,7 +87,7 @@ } memcpy(tmp, &new, sizeof(struct parport)); - if (new.irq != -1) { + if (new.irq != PARPORT_IRQ_NONE) { if (request_irq(new.irq, parport_null_intr_func, SA_INTERRUPT, new.name, tmp) != 0) { printk(KERN_INFO "%s: unable to claim IRQ %d\n", @@ -197,11 +199,10 @@ return NULL; } } - if (port->irq != -1) { - if (request_irq(port->irq, - parport_null_intr_func, - SA_INTERRUPT, port->name, - port) != 0) { + if (port->irq != PARPORT_IRQ_NONE) { + if (request_irq(port->irq, parport_null_intr_func, + SA_INTERRUPT, port->name, + port) != 0) { release_region(port->base, port->size); if( port->modes & PARPORT_MODE_ECR ) release_region(port->base+0x400, 3); @@ -213,7 +214,6 @@ port->flags &= ~PARPORT_FLAG_COMA; } - tmp = kmalloc(sizeof(struct ppd), GFP_KERNEL); tmp->name = (char *) name; tmp->port = port; @@ -251,8 +251,7 @@ port = dev->port; if (port->cad == dev) { - printk(KERN_INFO "%s: refused to unregister currently active device %s\n", - port->name, dev->name); + printk(KERN_INFO "%s: refused to unregister currently active device %s\n", port->name, dev->name); return; } @@ -299,8 +298,9 @@ if (dev->port->modes & PARPORT_MODE_ECR) dev->port->cad->ecr = dev->port->ecr = r_ecr(dev->port); - dev->port->cad->ctr = dev->port->ctr = - r_ctr(dev->port); + if (dev->port->modes & PARPORT_MODE_SPP) + dev->port->cad->ctr = dev->port->ctr = + r_ctr(dev->port); } else return -EAGAIN; } @@ -326,7 +326,8 @@ /* Restore control registers */ if (dev->port->modes & PARPORT_MODE_ECR) if (dev->ecr != dev->port->ecr) w_ecr(dev->port, dev->ecr); - if (dev->ctr != dev->port->ctr) w_ctr(dev->port, dev->ctr); + if (dev->port->modes & PARPORT_MODE_SPP) + if (dev->ctr != dev->port->ctr) w_ctr(dev->port, dev->ctr); return 0; } @@ -337,8 +338,7 @@ /* Make sure that dev is the current device */ if (dev->port->cad != dev) { - printk(KERN_WARNING "%s: %s tried to release parport when not owner\n", - dev->port->name, dev->name); + printk(KERN_WARNING "%s: %s tried to release parport when not owner\n", dev->port->name, dev->name); return; } dev->port->cad = NULL; @@ -346,12 +346,13 @@ /* Save control registers */ if (dev->port->modes & PARPORT_MODE_ECR) dev->ecr = dev->port->ecr = r_ecr(dev->port); - dev->ctr = dev->port->ctr = r_ctr(dev->port); + if (dev->port->modes & PARPORT_MODE_SPP) + dev->ctr = dev->port->ctr = r_ctr(dev->port); if (dev->port->irq >= 0) { free_irq(dev->port->irq, dev->port); request_irq(dev->port->irq, parport_null_intr_func, - SA_INTERRUPT, dev->port->name, dev->port); + SA_INTERRUPT, dev->port->name, dev->port); } /* Walk the list, offering a wakeup callback to everybody other @@ -384,16 +385,22 @@ if (dev->port->lurker && (dev->port->lurker != dev)) { if (dev->port->lurker->wakeup) { dev->port->lurker->wakeup(dev->port->lurker->private); - return; + } +#ifdef PARPORT_PARANOID + else { /* can't happen */ + printk(KERN_DEBUG + "%s (%s): lurker's wakeup callback went away!\n", + dev->port->name, dev->name); } - printk(KERN_DEBUG - "%s (%s): lurker's wakeup callback went away!\n", - dev->port->name, dev->name); +#endif } } /* The following read funktions are an implementation of a status readback * and device id request confirming to IEEE1284-1994. + * + * These probably ought to go in some seperate file, so people like the SPARC + * don't have to pull them in. */ /* Wait for Status line(s) to change in 35 ms - see IEEE1284-1994 page 24 to diff -u --recursive v2.1.35/linux/drivers/sbus/char/Config.in linux/drivers/sbus/char/Config.in --- v2.1.35/linux/drivers/sbus/char/Config.in Mon Apr 14 16:28:13 1997 +++ linux/drivers/sbus/char/Config.in Thu Apr 17 13:20:46 1997 @@ -10,6 +10,7 @@ bool 'bwtwo support' SUN_FB_BWTWO bool 'leo/zx support' SUN_FB_LEO bool 'weitek P9X00 support' TADPOLE_FB_WEITEK + bool 'creator support' SUN_FB_CREATOR if [ "$TADPOLE_FB_WEITEK" = "n" ]; then fbs=$SUN_FB_CGSIX fbs=$fbs$SUN_FB_TCX @@ -34,6 +35,7 @@ define_bool SUN_FB_BWTWO y define_bool SUN_FB_LEO y define_bool TADPOLE_FB_WEITEK y + define_bool SUN_FB_CREATOR y fi comment 'Misc Linux/SPARC drivers' diff -u --recursive v2.1.35/linux/drivers/sbus/char/Makefile linux/drivers/sbus/char/Makefile --- v2.1.35/linux/drivers/sbus/char/Makefile Mon Apr 14 16:28:13 1997 +++ linux/drivers/sbus/char/Makefile Thu Apr 17 13:20:46 1997 @@ -31,6 +31,9 @@ ifdef TADPOLE_FB_WEITEK FB_OBJS += weitek.o endif +ifdef SUN_FB_CREATOR + FB_OBJS += creator.o +endif #ifdef SUN_FB_FAST_ONE # FB_OBJS += sun_8bit_fast1.o #endif diff -u --recursive v2.1.35/linux/drivers/sbus/char/bpp.c linux/drivers/sbus/char/bpp.c --- v2.1.35/linux/drivers/sbus/char/bpp.c Thu Mar 27 14:40:05 1997 +++ linux/drivers/sbus/char/bpp.c Thu Apr 17 13:20:46 1997 @@ -29,6 +29,7 @@ #endif #if defined(__sparc__) +# include # include /* udelay() */ # include /* OpenProm Library */ diff -u --recursive v2.1.35/linux/drivers/sbus/char/bwtwo.c linux/drivers/sbus/char/bwtwo.c --- v2.1.35/linux/drivers/sbus/char/bwtwo.c Mon Apr 14 16:28:13 1997 +++ linux/drivers/sbus/char/bwtwo.c Tue Apr 15 21:47:23 1997 @@ -1,4 +1,4 @@ -/* $Id: bwtwo.c,v 1.12 1997/04/10 03:02:40 davem Exp $ +/* $Id: bwtwo.c,v 1.13 1997/04/14 17:04:55 jj Exp $ * bwtwo.c: bwtwo console driver * * Copyright (C) 1996 Miguel de Icaza (miguel@nuclecu.unam.mx) @@ -86,7 +86,7 @@ /* This routine should also map the register if asked for, * but we don't do that yet. */ - map_offset = get_phys ((uint) fb->base); + map_offset = get_phys ((unsigned long) fb->base); r = io_remap_page_range (vma->vm_start, map_offset, map_size, vma->vm_page_prot, fb->space); if (r) return -EAGAIN; @@ -143,10 +143,10 @@ 0x10, 0x20, 0 }; -__initfunc(void bwtwo_setup (fbinfo_t *fb, int slot, unsigned long bwtwo, int bw2_io, +__initfunc(void bwtwo_setup (fbinfo_t *fb, int slot, u32 bwtwo, int bw2_io, struct linux_sbus_device *sbdp)) { - printk ("bwtwo%d at 0x%8.8x\n", slot, (uint)bwtwo); + printk ("bwtwo%d at 0x%8.8x\n", slot, bwtwo); fb->type.fb_cmsize = 0; fb->mmap = bwtwo_mmap; fb->loadcmap = 0; @@ -156,7 +156,7 @@ fb->unblank = bwtwo_unblank; fb->info.bwtwo.regs = - sparc_alloc_io ((u32)(bwtwo + BWTWO_REGISTER_OFFSET), + sparc_alloc_io (bwtwo + BWTWO_REGISTER_OFFSET, 0, sizeof (struct bwtwo_regs), "bwtwo_regs", bw2_io, 0); @@ -201,7 +201,7 @@ } if(!fb->base) - fb->base = (unsigned long) sparc_alloc_io((u32)bwtwo, 0, + fb->base = (unsigned long) sparc_alloc_io(bwtwo, 0, ((fb->type.fb_depth*fb->type.fb_height*fb->type.fb_width)/8), "bwtwo_fbase", bw2_io, 0); diff -u --recursive v2.1.35/linux/drivers/sbus/char/cgfourteen.c linux/drivers/sbus/char/cgfourteen.c --- v2.1.35/linux/drivers/sbus/char/cgfourteen.c Mon Apr 14 16:28:13 1997 +++ linux/drivers/sbus/char/cgfourteen.c Tue Apr 15 21:47:23 1997 @@ -1,4 +1,4 @@ -/* $Id: cgfourteen.c,v 1.18 1997/03/24 17:44:27 jj Exp $ +/* $Id: cgfourteen.c,v 1.19 1997/04/14 17:04:57 jj Exp $ * cgfourteen.c: Sun SparcStation console support. * * Copyright (C) 1995 Miguel de Icaza (miguel@nuclecu.unam.mx) @@ -183,22 +183,22 @@ printk ("Wee! They are mapping the register, report this to miguel@gnu.ai.mit.edu\n"); printk ("Mapping fb->info.regs!\n"); map_size = 0x7000; - map_offset = get_phys ((uint) fb->info.cg14.regs); + map_offset = get_phys ((unsigned long) fb->info.cg14.regs); break; case CG3_MMAP_OFFSET: map_size = size-page; - map_offset = get_phys ((uint) fb->base); + map_offset = get_phys ((unsigned long) fb->base); break; case MDI_PLANAR_X16_MAP: map_size = ram_size/2; - map_offset = get_phys ((uint) fb->base) | 0x2000000; + map_offset = get_phys ((unsigned long) fb->base) | 0x2000000; break; case MDI_PLANAR_C16_MAP: map_size = ram_size/2; - map_offset = get_phys ((uint) fb->base) | 0x2800000; + map_offset = get_phys ((unsigned long) fb->base) | 0x2800000; break; case MDI_CHUNKY_XBGR_MAP: @@ -208,50 +208,50 @@ case MDI_CHUNKY_BGR_MAP: map_size = ram_size; - map_offset = get_phys ((uint) fb->base) | 0x1000000; + map_offset = get_phys ((unsigned long) fb->base) | 0x1000000; break; case MDI_PLANAR_X32_MAP: map_size = ram_size/4; - map_offset = get_phys ((uint) fb->base) | 0x3000000; + map_offset = get_phys ((unsigned long) fb->base) | 0x3000000; break; case MDI_PLANAR_B32_MAP: map_size = ram_size/4; - map_offset = get_phys ((uint) fb->base) | 0x3400000; + map_offset = get_phys ((unsigned long) fb->base) | 0x3400000; break; case MDI_PLANAR_G32_MAP: map_size = ram_size/4; - map_offset = get_phys ((uint) fb->base) | 0x3800000; + map_offset = get_phys ((unsigned long) fb->base) | 0x3800000; break; case MDI_PLANAR_R32_MAP: map_size = ram_size/4; - map_offset = get_phys ((uint) fb->base) | 0x3c00000; + map_offset = get_phys ((unsigned long) fb->base) | 0x3c00000; break; case MDI_CURSOR_MAP: map_size = PAGE_SIZE; - map_offset = get_phys ((uint) fb->info.cg14.cursor_regs); + map_offset = get_phys ((unsigned long) fb->info.cg14.cursor_regs); break; case CG14_REGS: printk ("Wee! They are mapping the register, report this to miguel@gnu.ai.mit.edu\n"); map_size = PAGE_SIZE; - map_offset = get_phys ((uint) fb->info.cg14.regs); + map_offset = get_phys ((unsigned long) fb->info.cg14.regs); break; case CG14_XLUT: map_size = PAGE_SIZE; - map_offset = get_phys ((uint) fb->info.cg14.regs+0x3000); + map_offset = get_phys ((unsigned long) fb->info.cg14.regs+0x3000); break; case CG14_CLUT1: map_size = PAGE_SIZE; - map_offset = get_phys ((uint) fb->info.cg14.regs+0x4000); + map_offset = get_phys ((unsigned long) fb->info.cg14.regs+0x4000); break; case CG14_CLUT2: map_size = PAGE_SIZE; - map_offset = get_phys ((uint) fb->info.cg14.regs+0x5000); + map_offset = get_phys ((unsigned long) fb->info.cg14.regs+0x5000); break; default: @@ -424,11 +424,11 @@ *mcr = (*mcr & ~(CG14_MCR_PIXMODE_MASK)); } -__initfunc(void cg14_setup (fbinfo_t *fb, int slot, int con_node, unsigned long cg14, int cg14_io)) +__initfunc(void cg14_setup (fbinfo_t *fb, int slot, int con_node, u32 cg14, int cg14_io)) { struct cg14_info *cg14info; uint bases [2]; - uint cg14regs = 0; + unsigned long cg14regs = 0; struct cg14_regs *regs = 0; if (!cg14) { @@ -468,5 +468,5 @@ /* If the bit is turned on, the card has 8 mb of ram, otherwise just 4 */ cg14info->ramsize = (regs->vca & CG14_VCA_8MB_MASK ? 8 : 4) * 1024 * 1024; printk ("cgfourteen%d at 0x%8.8x with %d megs of RAM rev=%d, impl=%d\n", - slot, (uint)cg14, cg14info->ramsize/(1024*1024), regs->rev >> 4, regs->rev & 0xf); + slot, cg14, cg14info->ramsize/(1024*1024), regs->rev >> 4, regs->rev & 0xf); } diff -u --recursive v2.1.35/linux/drivers/sbus/char/cgsix.c linux/drivers/sbus/char/cgsix.c --- v2.1.35/linux/drivers/sbus/char/cgsix.c Mon Apr 14 16:28:13 1997 +++ linux/drivers/sbus/char/cgsix.c Tue Apr 15 21:47:23 1997 @@ -1,4 +1,4 @@ -/* $Id: cgsix.c,v 1.26 1997/04/10 03:02:40 davem Exp $ +/* $Id: cgsix.c,v 1.27 1997/04/14 17:04:55 jj Exp $ * cgsix.c: cgsix frame buffer driver * * Copyright (C) 1996 Miguel de Icaza (miguel@nuclecu.unam.mx) @@ -264,17 +264,14 @@ map_size = PAGE_SIZE; map_offset = get_phys ((unsigned long)fb->info.cg6.bt); break; - case CG6_DHC: map_size = PAGE_SIZE * 40; map_offset = get_phys ((unsigned long)fb->info.cg6.dhc); break; - case CG6_ROM: map_size = PAGE_SIZE * 16; map_offset = get_phys ((unsigned long)fb->info.cg6.rom); break; - case CG6_RAM: map_size = size-page; map_offset = get_phys ((unsigned long) fb->base); @@ -422,12 +419,12 @@ cg6->bt->control |= 0x03 << 24; } -__initfunc(void cg6_setup (fbinfo_t *fb, int slot, unsigned long cg6, int cg6_io)) +__initfunc(void cg6_setup (fbinfo_t *fb, int slot, u32 cg6, int cg6_io)) { struct cg6_info *cg6info; unsigned int rev, cpu, conf; - printk ("cgsix%d at 0x%8.8x ", slot, (uint) cg6); + printk ("cgsix%d at 0x%8.8x ", slot, cg6); /* Fill in parameters we left out */ fb->type.fb_cmsize = 256; @@ -447,23 +444,23 @@ cg6info = (struct cg6_info *) &fb->info.cg6; /* Map the hardware registers */ - cg6info->bt = sparc_alloc_io ((u32)(cg6+CG6_BROOKTREE_OFFSET), 0, + cg6info->bt = sparc_alloc_io (cg6+CG6_BROOKTREE_OFFSET, 0, sizeof (struct bt_regs), "cgsix_dac", cg6_io, 0); - cg6info->fhc = sparc_alloc_io ((u32)(cg6+CG6_FHC_OFFSET), 0, + cg6info->fhc = sparc_alloc_io (cg6+CG6_FHC_OFFSET, 0, sizeof (int), "cgsix_fhc", cg6_io, 0); - cg6info->thc = sparc_alloc_io ((u32)(cg6+CG6_THC_OFFSET), 0, + cg6info->thc = sparc_alloc_io (cg6+CG6_THC_OFFSET, 0, sizeof (struct cg6_thc), "cgsix_thc", cg6_io, 0); - cg6info->tec = sparc_alloc_io ((u32)(cg6+CG6_TEC_OFFSET), 0, + cg6info->tec = sparc_alloc_io (cg6+CG6_TEC_OFFSET, 0, sizeof (struct cg6_tec), "cgsix_tec", cg6_io, 0); - cg6info->dhc = sparc_alloc_io ((u32)(cg6+CG6_DHC_OFFSET), 0, + cg6info->dhc = sparc_alloc_io (cg6+CG6_DHC_OFFSET, 0, 0x40000, "cgsix_dhc", cg6_io, 0); - cg6info->fbc = sparc_alloc_io ((u32)(cg6+CG6_FBC_OFFSET), 0, + cg6info->fbc = sparc_alloc_io (cg6+CG6_FBC_OFFSET, 0, 0x1000, "cgsix_fbc", cg6_io, 0); - cg6info->rom = sparc_alloc_io ((u32)(cg6+CG6_ROM_OFFSET), 0, + cg6info->rom = sparc_alloc_io (cg6+CG6_ROM_OFFSET, 0, 0x10000, "cgsix_rom", cg6_io, 0); if (!fb->base) { fb->base = (unsigned long) - sparc_alloc_io ((u32)(cg6+CG6_RAM_OFFSET), 0, + sparc_alloc_io (cg6+CG6_RAM_OFFSET, 0, fb->type.fb_size, "cgsix_ram", cg6_io, 0); } if (slot == sun_prom_console_id) diff -u --recursive v2.1.35/linux/drivers/sbus/char/cgthree.c linux/drivers/sbus/char/cgthree.c --- v2.1.35/linux/drivers/sbus/char/cgthree.c Mon Apr 14 16:28:13 1997 +++ linux/drivers/sbus/char/cgthree.c Thu Apr 17 13:20:46 1997 @@ -1,4 +1,4 @@ -/* $Id: cgthree.c,v 1.16 1997/04/10 03:02:41 davem Exp $ +/* $Id: cgthree.c,v 1.18 1997/04/16 17:51:09 jj Exp $ * cgtree.c: cg3 frame buffer driver * * Copyright (C) 1996 Miguel de Icaza (miguel@nuclecu.unam.mx) @@ -109,7 +109,7 @@ switch (vma->vm_offset+page){ case CG3_MMAP_OFFSET: map_size = size-page; - map_offset = get_phys ((uint) fb->base); + map_offset = get_phys ((unsigned long) fb->base); if (map_size > fb->type.fb_size) map_size = fb->type.fb_size; break; @@ -178,7 +178,7 @@ }; -__initfunc(void cg3_setup (fbinfo_t *fb, int slot, unsigned long cg3, int cg3_io, +__initfunc(void cg3_setup (fbinfo_t *fb, int slot, u32 cg3, int cg3_io, struct linux_sbus_device *sbdp)) { struct cg3_info *cg3info = (struct cg3_info *) &fb->info.cg3; @@ -200,10 +200,10 @@ } } } - printk ("cgRDI%d at 0x%8.8x\n", slot, (uint)cg3); + printk ("cgRDI%d at 0x%8.8x\n", slot, cg3); cg3info->cgrdi = 1; } else { - printk ("cgthree%d at 0x%8.8x\n", slot, (uint)cg3); + printk ("cgthree%d at 0x%8.8x\n", slot, cg3); cg3info->cgrdi = 0; } @@ -218,7 +218,7 @@ fb->unblank = cg3_unblank; /* Map the card registers */ - cg3info->regs = sparc_alloc_io ((u32)(cg3+CG3_REGS), 0, + cg3info->regs = sparc_alloc_io (cg3+CG3_REGS, 0, sizeof (struct cg3_regs),"cg3_regs", cg3_io, 0); if (!prom_getbool(sbdp->prom_node, "width")) { @@ -258,8 +258,8 @@ } if (!fb->base){ - fb->base=(uint) sparc_alloc_io ((u32)(cg3+CG3_RAM), 0, - fb->type.fb_size, "cg3_ram", cg3_io, 0); + fb->base=(unsigned long) sparc_alloc_io (cg3+CG3_RAM, 0, + fb->type.fb_size, "cg3_ram", cg3_io, 0); } } Only in linux/drivers/sbus/char: creator.c diff -u --recursive v2.1.35/linux/drivers/sbus/char/fb.h linux/drivers/sbus/char/fb.h --- v2.1.35/linux/drivers/sbus/char/fb.h Mon Apr 14 16:28:13 1997 +++ linux/drivers/sbus/char/fb.h Thu Apr 17 13:20:46 1997 @@ -1,4 +1,4 @@ -/* $Id: fb.h,v 1.24 1997/03/24 17:44:15 jj Exp $ +/* $Id: fb.h,v 1.26 1997/04/17 02:29:33 miguel Exp $ * fb.h: contains the definitions of the structures that various sun * frame buffer can use to do console driver stuff. * @@ -183,8 +183,8 @@ extern int ints_per_line; /* used in the mmap routines */ -extern unsigned int get_phys (unsigned int addr); -extern int get_iospace (unsigned int addr); +extern unsigned int get_phys (unsigned long addr); +extern int get_iospace (unsigned long addr); extern void render_screen(void); extern void sun_hw_hide_cursor(void); @@ -197,12 +197,14 @@ #define FB_DEV(x) (MINOR(x) / 32) -extern void cg3_setup (fbinfo_t *, int, unsigned long, int, struct linux_sbus_device *); -extern void cg6_setup (fbinfo_t *, int, unsigned long, int); -extern void cg14_setup (fbinfo_t *, int, int, unsigned long, int); -extern void bwtwo_setup (fbinfo_t *, int, unsigned long, int, +extern void cg3_setup (fbinfo_t *, int, u32, int, struct linux_sbus_device *); +extern void cg6_setup (fbinfo_t *, int, u32, int); +extern void cg14_setup (fbinfo_t *, int, int, u32, int); +extern void bwtwo_setup (fbinfo_t *, int, u32, int, struct linux_sbus_device *); -extern void leo_setup (fbinfo_t *, int, unsigned long, int); -extern void tcx_setup (fbinfo_t *, int, int, unsigned long, struct linux_sbus_device *); +extern void leo_setup (fbinfo_t *, int, u32, int); +extern void tcx_setup (fbinfo_t *, int, int, u32, struct linux_sbus_device *); +extern void creator_setup (fbinfo_t *, int, int, unsigned long, int); +extern int io_remap_page_range(unsigned long from, unsigned long offset, unsigned long size, pgprot_t prot, int space); #endif __SPARC_FB_H_ diff -u --recursive v2.1.35/linux/drivers/sbus/char/leo.c linux/drivers/sbus/char/leo.c --- v2.1.35/linux/drivers/sbus/char/leo.c Mon Apr 14 16:28:13 1997 +++ linux/drivers/sbus/char/leo.c Tue Apr 15 21:47:23 1997 @@ -1,4 +1,4 @@ -/* $Id: leo.c,v 1.14 1997/04/10 17:06:09 jj Exp $ +/* $Id: leo.c,v 1.15 1997/04/14 17:04:54 jj Exp $ * leo.c: SUNW,leo 24/8bit frame buffer driver * * Copyright (C) 1996 Jakub Jelinek (jj@sunsite.mff.cuni.cz) @@ -156,19 +156,19 @@ switch (vma->vm_offset+page){ case LEO_SS0_MAP: map_size = 0x800000; - map_offset = get_phys ((uint)fb->base); + map_offset = get_phys ((unsigned long)fb->base); break; case LEO_LC_SS0_USR_MAP: map_size = PAGE_SIZE; - map_offset = get_phys ((uint)fb->info.leo.lc_ss0_usr); + map_offset = get_phys ((unsigned long)fb->info.leo.lc_ss0_usr); break; case LEO_LD_SS0_MAP: map_size = PAGE_SIZE; - map_offset = get_phys ((uint)fb->info.leo.ld_ss0); + map_offset = get_phys ((unsigned long)fb->info.leo.ld_ss0); break; case LEO_LX_CURSOR_MAP: map_size = PAGE_SIZE; - map_offset = get_phys ((uint)fb->info.leo.cursor); + map_offset = get_phys ((unsigned long)fb->info.leo.cursor); break; case LEO_SS1_MAP: map_size = 0x800000; @@ -176,11 +176,11 @@ break; case LEO_LC_SS1_USR_MAP: map_size = PAGE_SIZE; - map_offset = get_phys ((uint)fb->info.leo.lc_ss1_usr); + map_offset = get_phys ((unsigned long)fb->info.leo.lc_ss1_usr); break; case LEO_LD_SS1_MAP: map_size = PAGE_SIZE; - map_offset = get_phys ((uint)fb->info.leo.ld_ss1); + map_offset = get_phys ((unsigned long)fb->info.leo.ld_ss1); break; case LEO_UNK_MAP: map_size = PAGE_SIZE; @@ -188,19 +188,19 @@ break; case LEO_LX_KRN_MAP: map_size = PAGE_SIZE; - map_offset = get_phys ((uint)fb->info.leo.lx_krn); + map_offset = get_phys ((unsigned long)fb->info.leo.lx_krn); break; case LEO_LC_SS0_KRN_MAP: map_size = PAGE_SIZE; - map_offset = get_phys ((uint)fb->info.leo.lc_ss0_krn); + map_offset = get_phys ((unsigned long)fb->info.leo.lc_ss0_krn); break; case LEO_LC_SS1_KRN_MAP: map_size = PAGE_SIZE; - map_offset = get_phys ((uint)fb->info.leo.lc_ss1_krn); + map_offset = get_phys ((unsigned long)fb->info.leo.lc_ss1_krn); break; case LEO_LD_GBL_MAP: map_size = PAGE_SIZE; - map_offset = get_phys ((uint)fb->info.leo.ld_gbl); + map_offset = get_phys ((unsigned long)fb->info.leo.ld_gbl); break; case LEO_UNK2_MAP: map_size = 0x100000; @@ -509,14 +509,14 @@ return memory_start + (256*4*3) + 256 + 256*3; } -__initfunc(void leo_setup (fbinfo_t *fb, int slot, unsigned long leo, int leo_io)) +__initfunc(void leo_setup (fbinfo_t *fb, int slot, u32 leo, int leo_io)) { struct leo_info *leoinfo; int i; struct fb_wid_item wi; struct fb_wid_list wl; - printk ("leo%d at 0x%8.8x ", slot, (uint) leo); + printk ("leo%d at 0x%8.8x ", slot, leo); /* Fill in parameters we left out */ fb->type.fb_size = 0x800000; /* 8MB */ @@ -543,25 +543,25 @@ leoinfo->offset = leo; /* Map the hardware registers */ - leoinfo->lc_ss0_krn = sparc_alloc_io((u32)(leo + LEO_OFF_LC_SS0_KRN), 0, + leoinfo->lc_ss0_krn = sparc_alloc_io(leo + LEO_OFF_LC_SS0_KRN, 0, PAGE_SIZE,"leo_lc_ss0_krn", fb->space, 0); - leoinfo->lc_ss0_usr = sparc_alloc_io((u32)(leo + LEO_OFF_LC_SS0_USR), 0, + leoinfo->lc_ss0_usr = sparc_alloc_io(leo + LEO_OFF_LC_SS0_USR, 0, PAGE_SIZE,"leo_lc_ss0_usr", fb->space, 0); - leoinfo->lc_ss1_krn = sparc_alloc_io((u32)(leo + LEO_OFF_LC_SS1_KRN), 0, + leoinfo->lc_ss1_krn = sparc_alloc_io(leo + LEO_OFF_LC_SS1_KRN, 0, PAGE_SIZE,"leo_lc_ss1_krn", fb->space, 0); - leoinfo->lc_ss1_usr = sparc_alloc_io((u32)(leo + LEO_OFF_LC_SS1_USR), 0, + leoinfo->lc_ss1_usr = sparc_alloc_io(leo + LEO_OFF_LC_SS1_USR, 0, PAGE_SIZE,"leo_lc_ss1_usr", fb->space, 0); - leoinfo->ld_ss0 = sparc_alloc_io((u32)(leo + LEO_OFF_LD_SS0), 0, + leoinfo->ld_ss0 = sparc_alloc_io(leo + LEO_OFF_LD_SS0, 0, PAGE_SIZE,"leo_ld_ss0", fb->space, 0); - leoinfo->ld_ss1 = sparc_alloc_io((u32)(leo + LEO_OFF_LD_SS1), 0, + leoinfo->ld_ss1 = sparc_alloc_io(leo + LEO_OFF_LD_SS1, 0, PAGE_SIZE,"leo_ld_ss1", fb->space, 0); - leoinfo->ld_gbl = sparc_alloc_io((u32)(leo + LEO_OFF_LD_GBL), 0, + leoinfo->ld_gbl = sparc_alloc_io(leo + LEO_OFF_LD_GBL, 0, PAGE_SIZE,"leo_ld_gbl", fb->space, 0); - leoinfo->lx_krn = sparc_alloc_io((u32)(leo + LEO_OFF_LX_KRN), 0, + leoinfo->lx_krn = sparc_alloc_io(leo + LEO_OFF_LX_KRN, 0, PAGE_SIZE,"leo_lx_krn", fb->space, 0); - leoinfo->cursor = sparc_alloc_io((u32)(leo + LEO_OFF_LX_CURSOR), 0, + leoinfo->cursor = sparc_alloc_io(leo + LEO_OFF_LX_CURSOR, 0, sizeof(struct leo_cursor),"leo_lx_crsr", fb->space, 0); - fb->base = (long)sparc_alloc_io((u32)(leo + LEO_OFF_SS0), 0, + fb->base = (long)sparc_alloc_io(leo + LEO_OFF_SS0, 0, 0x800000,"leo_ss0", fb->space, 0); leoinfo->ld_ss0->unk = 0xffff; Only in v2.1.35/linux/drivers/sbus/char: linux_logo.h diff -u --recursive v2.1.35/linux/drivers/sbus/char/suncons.c linux/drivers/sbus/char/suncons.c --- v2.1.35/linux/drivers/sbus/char/suncons.c Mon Apr 14 16:28:13 1997 +++ linux/drivers/sbus/char/suncons.c Thu Apr 17 13:20:46 1997 @@ -1,4 +1,4 @@ -/* $Id: suncons.c,v 1.58 1997/04/04 00:50:04 davem Exp $ +/* $Id: suncons.c,v 1.61 1997/04/17 02:29:36 miguel Exp $ * * suncons.c: Sun SparcStation console support. * @@ -87,7 +87,7 @@ #define cmapsz 8192 #include "suncons_font.h" -#include "linux_logo.h" +#include fbinfo_t *fbinfo; int fbinfos; @@ -382,7 +382,7 @@ count = video_num_columns * video_num_lines; contents = (unsigned short *) video_mem_base; - + for (;count--; contents++) sun_blitc (*contents, (unsigned long) contents); } @@ -434,11 +434,7 @@ putconsxy(0, q); ush = (unsigned short *) video_mem_base + video_num_columns * 2 + 20 + 11 * (linux_num_cpus - 1); -#ifdef __sparc_v9__ - p = "Linux/UltraSPARC version " UTS_RELEASE; -#else - p = "Linux/SPARC version " UTS_RELEASE; -#endif + p = linux_logo_banner; for (; *p; p++, ush++) { *ush = (attr << 8) + *p; sun_blitc (*ush, (unsigned long) ush); @@ -764,35 +760,15 @@ } unsigned int -get_phys (unsigned int addr) +get_phys (unsigned long addr) { - switch (sparc_cpu_model){ - case sun4c: - return sun4c_get_pte (addr) << PAGE_SHIFT; - case sun4m: - return ((srmmu_get_pte (addr) & 0xffffff00) << 4); - case sun4u: - /* FIXME: */ return 0; - default: - panic ("get_phys called for unsupported cpu model\n"); - return 0; - } + return __get_phys(addr); } int -get_iospace (unsigned int addr) +get_iospace (unsigned long addr) { - switch (sparc_cpu_model){ - case sun4c: - return -1; /* Don't check iospace on sun4c */ - case sun4m: - return (srmmu_get_pte (addr) >> 28); - case sun4u: - /* FIXME: */ return 0; - default: - panic ("get_iospace called for unsupported cpu model\n"); - return -1; - } + return __get_iospace(addr); } __initfunc(unsigned long sun_cg_postsetup(fbinfo_t *fb, unsigned long start_mem)) @@ -803,7 +779,7 @@ static char *known_cards [] __initdata = { "cgsix", "cgthree", "cgRDI", "cgthree+", "bwtwo", "SUNW,tcx", - "cgfourteen", "SUNW,leo", 0 + "cgfourteen", "SUNW,leo", "SUNW,ffb", 0 }; static char *v0_known_cards [] __initdata = { "cgsix", "cgthree", "cgRDI", "cgthree+", "bwtwo", 0 @@ -848,6 +824,16 @@ return n; } +__initfunc(static int creator_present (void)) +{ + int root, n; + + root = prom_getchild (prom_root_node); + if ((n = prom_searchsiblings (root, "SUNW,ffb")) == 0) + return 0; + return n; +} + __initfunc(static void sparc_framebuffer_setup(int primary, int con_node, int type, struct linux_sbus_device *sbdp, @@ -941,78 +927,86 @@ leo_setup (&fbinfo [n], n, base, io); break; #endif +#ifdef SUN_FB_CREATOR + case FBTYPE_CREATOR: + creator_setup (&fbinfo [n], n, con_node, base, io); + break; +#endif default: fbinfo [n].type.fb_type = FBTYPE_NOTYPE; return; } - if (!n) { - con_type = type; - con_height = fbinfo [n].type.fb_height; - con_width = fbinfo [n].type.fb_width; - con_depth = (type == FBTYPE_SUN2BW) ? 1 : 8; - for (i = 0; scr_def [i].depth; i++){ - if ((scr_def [i].resx != con_width) || - (scr_def [i].resy != con_height)) - continue; - if (scr_def [i].depth != con_depth) - continue; - x_margin = scr_def [i].x_margin; - y_margin = scr_def [i].y_margin; - chars_per_line = (con_width * con_depth) / 8; - skip_bytes = chars_per_line * y_margin + x_margin; - ints_per_line = chars_per_line / 4; - ints_per_cursor = 14 * ints_per_line; - bytes_per_row = CHAR_HEIGHT * chars_per_line; - ORIG_VIDEO_COLS = con_width / 8 - - 2 * x_margin / con_depth; - ORIG_VIDEO_LINES = (con_height - 2 * y_margin) / 16; - switch (chars_per_line) { - case 1280: - if (ORIG_VIDEO_COLS == 144) - color_fbuf_offset = - color_fbuf_offset_1280_144; - break; - case 1152: - if (ORIG_VIDEO_COLS == 128) - color_fbuf_offset = - color_fbuf_offset_1152_128; - break; - case 1024: - if (ORIG_VIDEO_COLS == 128) - color_fbuf_offset = - color_fbuf_offset_1024_128; - break; - case 800: - if (ORIG_VIDEO_COLS == 96) - color_fbuf_offset = - color_fbuf_offset_800_96; - break; - case 640: - if (ORIG_VIDEO_COLS == 80) - color_fbuf_offset = - color_fbuf_offset_640_80; - break; - } - break; - } - - if (!scr_def [i].depth){ - x_margin = y_margin = 0; - prom_printf ("console: unknown video resolution %dx%d," - " depth %d\n", - con_width, con_height, con_depth); - prom_halt (); - } - /* P3: I fear this strips 15inch 1024/768 PC-like - * monitors out. */ - if ((linebytes*8) / con_depth != con_width) { - prom_printf("console: unusual video, linebytes=%d, " - "width=%d, height=%d depth=%d\n", - linebytes, con_width, con_height, - con_depth); - prom_halt (); + if (n) + return; + + /* Code below here is just executed for the first frame buffer */ + con_type = type; + con_height = fbinfo [n].type.fb_height; + con_width = fbinfo [n].type.fb_width; + con_depth = (type == FBTYPE_SUN2BW) ? 1 : 8; + for (i = 0; scr_def [i].depth; i++){ + if ((scr_def [i].resx != con_width) || + (scr_def [i].resy != con_height)) + continue; + if (scr_def [i].depth != con_depth) + continue; + x_margin = scr_def [i].x_margin; + y_margin = scr_def [i].y_margin; + chars_per_line = (con_width * con_depth) / 8; + skip_bytes = chars_per_line * y_margin + x_margin; + ints_per_line = chars_per_line / 4; + ints_per_cursor = 14 * ints_per_line; + bytes_per_row = CHAR_HEIGHT * chars_per_line; + ORIG_VIDEO_COLS = con_width / 8 - + 2 * x_margin / con_depth; + ORIG_VIDEO_LINES = (con_height - 2 * y_margin) / 16; + switch (chars_per_line) { + case 1280: + if (ORIG_VIDEO_COLS == 144) + color_fbuf_offset = + color_fbuf_offset_1280_144; + break; + case 1152: + if (ORIG_VIDEO_COLS == 128) + color_fbuf_offset = + color_fbuf_offset_1152_128; + break; + case 1024: + if (ORIG_VIDEO_COLS == 128) + color_fbuf_offset = + color_fbuf_offset_1024_128; + break; + case 800: + if (ORIG_VIDEO_COLS == 96) + color_fbuf_offset = + color_fbuf_offset_800_96; + break; + case 640: + if (ORIG_VIDEO_COLS == 80) + color_fbuf_offset = + color_fbuf_offset_640_80; + break; } + break; + } + + if (!scr_def [i].depth){ + x_margin = y_margin = 0; + prom_printf ("console: unknown video resolution %dx%d," + " depth %d\n", + con_width, con_height, con_depth); + prom_halt (); + } + + /* P3: I fear this strips 15inch 1024/768 PC-like + * monitors out. */ + if ((linebytes*8) / con_depth != con_width) { + prom_printf("console: unusual video, linebytes=%d, " + "width=%d, height=%d depth=%d\n", + linebytes, con_width, con_height, + con_depth); + prom_halt (); } } @@ -1022,9 +1016,9 @@ char prop[16]; struct linux_sbus_device *sbdp, *sbdprom; struct linux_sbus *sbus; - int cg14 = 0; + int creator = 0, cg14 = 0; char prom_name[40]; - int type; + int type, card_found = 0; unsigned long con_base; u32 tmp; u32 prom_console_node = 0; @@ -1109,18 +1103,22 @@ break; } } - if (!sbdprom) /* I'm just wondering if this if shouldn't be deleted. - Is /obio/cgfourteen present only if /sbus/cgfourteen - is not? If so, then the test here should be deleted. - Otherwise, this comment should be deleted. */ - cg14 = cg14_present (); - if (!sbdprom && !cg14) { + if (sbdprom) + card_found = 1; + if (!card_found) + card_found = cg14 = cg14_present (); + if (!card_found){ + prom_printf ("Searching for a creator\n"); + card_found = creator = creator_present (); + } + if (!card_found){ prom_printf ("Could not find a known video card on this machine\n"); prom_halt (); } for_all_sbusdev(sbdp, sbus) { - if (!known_card (sbdp->prom_name, known_cards)) continue; + if (!known_card (sbdp->prom_name, known_cards)) + continue; con_node = sbdp->prom_node; prom_apply_sbus_ranges (sbdp->my_bus, &sbdp->reg_addrs [0], sbdp->num_registers, sbdp); @@ -1170,6 +1168,11 @@ sparc_framebuffer_setup (!sbdprom, cg14, FBTYPE_MDICOLOR, 0, 0, 0, prom_console_node == cg14, prom_searchsiblings (prom_getchild (prom_root_node), "obio")); + } + if (creator){ + sparc_framebuffer_setup (!sbdprom, creator, FBTYPE_CREATOR, + 0, 0, 0, prom_console_node == creator, + prom_getchild (prom_root_node)); } break; default: diff -u --recursive v2.1.35/linux/drivers/sbus/char/sunserial.c linux/drivers/sbus/char/sunserial.c --- v2.1.35/linux/drivers/sbus/char/sunserial.c Mon Apr 14 16:28:14 1997 +++ linux/drivers/sbus/char/sunserial.c Tue Apr 15 21:47:23 1997 @@ -1,4 +1,4 @@ -/* $Id: sunserial.c,v 1.37 1997/04/12 23:33:14 ecd Exp $ +/* $Id: sunserial.c,v 1.38 1997/04/14 17:05:00 jj Exp $ * serial.c: Serial port driver for the Sparc. * * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) @@ -1857,7 +1857,7 @@ static void show_serial_version(void) { - char *revision = "$Revision: 1.37 $"; + char *revision = "$Revision: 1.38 $"; char *version, *p; version = strchr(revision, ' '); @@ -1991,7 +1991,7 @@ if(!vaddr[0]) panic("get_zs whee no serial chip mappable"); - return (struct sun_zslayout *) vaddr[0]; + return (struct sun_zslayout *)(unsigned long) vaddr[0]; } static inline void @@ -2541,7 +2541,7 @@ for (info = zs_chain, i=0; info; info = info->zs_next, i++) { info->magic = SERIAL_MAGIC; - info->port = (int) info->zs_channel; + info->port = (long) info->zs_channel; info->line = i; info->tty = 0; info->irq = zilog_irq; diff -u --recursive v2.1.35/linux/drivers/sbus/char/tcx.c linux/drivers/sbus/char/tcx.c --- v2.1.35/linux/drivers/sbus/char/tcx.c Mon Apr 14 16:28:14 1997 +++ linux/drivers/sbus/char/tcx.c Tue Apr 15 21:47:23 1997 @@ -1,4 +1,4 @@ -/* $Id: tcx.c,v 1.11 1997/04/10 03:02:43 davem Exp $ +/* $Id: tcx.c,v 1.12 1997/04/14 17:04:51 jj Exp $ * tcx.c: SUNW,tcx 24/8bit frame buffer driver * * Copyright (C) 1996 Jakub Jelinek (jj@sunsite.mff.cuni.cz) @@ -126,24 +126,24 @@ switch (vma->vm_offset+page){ case TCX_RAM8BIT: map_size = fb->type.fb_size; - map_offset = get_phys ((uint) fb->base); + map_offset = get_phys ((unsigned long) fb->base); break; case TCX_TEC: map_size = PAGE_SIZE; - map_offset = get_phys ((uint)fb->info.tcx.tec); + map_offset = get_phys ((unsigned long)fb->info.tcx.tec); break; case TCX_BTREGS: map_size = PAGE_SIZE; - map_offset = get_phys ((uint)fb->info.tcx.bt); + map_offset = get_phys ((unsigned long)fb->info.tcx.bt); break; case TCX_THC: map_size = PAGE_SIZE; - map_offset = get_phys ((uint)fb->info.tcx.thc); + map_offset = get_phys ((unsigned long)fb->info.tcx.thc); break; case TCX_CONTROLPLANE: if (fb->info.tcx.tcx_cplane) { map_size = fb->info.tcx.tcx_sizes [TCX_CONTROLPLANE_OFFSET]; - map_offset = get_phys ((uint)fb->info.tcx.tcx_cplane); + map_offset = get_phys ((unsigned long)fb->info.tcx.tcx_cplane); } else map_size = 0; break; @@ -272,12 +272,12 @@ tcx->bt->control |= 0x03 << 24; } -__initfunc(void tcx_setup (fbinfo_t *fb, int slot, int node, unsigned long tcx, struct linux_sbus_device *sbdp)) +__initfunc(void tcx_setup (fbinfo_t *fb, int slot, int node, u32 tcx, struct linux_sbus_device *sbdp)) { struct tcx_info *tcxinfo; int i; - printk ("tcx%d at 0x%8.8x ", slot, (uint) tcx); + printk ("tcx%d at 0x%8.8x ", slot, tcx); /* Fill in parameters we left out */ fb->type.fb_cmsize = 256; diff -u --recursive v2.1.35/linux/drivers/sbus/char/weitek.c linux/drivers/sbus/char/weitek.c --- v2.1.35/linux/drivers/sbus/char/weitek.c Mon Apr 14 16:28:15 1997 +++ linux/drivers/sbus/char/weitek.c Tue Apr 15 21:47:23 1997 @@ -1,4 +1,4 @@ -/* $Id: weitek.c,v 1.8 1997/03/24 17:44:26 jj Exp $ +/* $Id: weitek.c,v 1.9 1997/04/14 17:04:57 jj Exp $ * weitek.c: Tadpole P9100/P9000 console driver * * Copyright (C) 1996 David Redman (djhr@tadpole.co.uk) @@ -54,13 +54,13 @@ switch (vma->vm_offset+page){ case WEITEK_VRAM_OFFSET: map_size = size-page; - map_offset = get_phys ((uint) fb->base); + map_offset = get_phys ((unsigned long) fb->base); if (map_size > fb->type.fb_size) map_size = fb->type.fb_size; break; case WEITEK_GX_REG_OFFSET: map_size = size-page; - map_offset = get_phys ((uint) fb->base); + map_offset = get_phys ((unsigned long) fb->base); if (map_size > fb->type.fb_size) map_size = fb->type.fb_size; break; @@ -95,11 +95,11 @@ } #endif -__initfunc(void weitek_setup(fbinfo_t *fb, int slot, unsigned long addr, int io)) +__initfunc(void weitek_setup(fbinfo_t *fb, int slot, u32 addr, int io)) { extern struct screen_info screen_info; - printk ("weitek%d at 0x%8.8x\n", slot, (uint)addr); + printk ("weitek%d at 0x%8.8x\n", slot, addr); /* Fill in parameters we left out */ fb->type.fb_type = FBTYPE_NOTSUN1; diff -u --recursive v2.1.35/linux/drivers/sbus/sbus.c linux/drivers/sbus/sbus.c --- v2.1.35/linux/drivers/sbus/sbus.c Mon Apr 14 16:28:15 1997 +++ linux/drivers/sbus/sbus.c Tue Apr 15 21:47:23 1997 @@ -74,10 +74,10 @@ sbus_dev->slot = sbus_dev->reg_addrs[0].which_io; sbus_dev->offset = base; sbus_dev->reg_addrs[0].phys_addr = - (char *) sbus_devaddr(sbus_dev->slot, base); + sbus_devaddr(sbus_dev->slot, base); for(grrr=1; grrrnum_registers; grrr++) { base = (unsigned long) sbus_dev->reg_addrs[grrr].phys_addr; - sbus_dev->reg_addrs[grrr].phys_addr = (char *) + sbus_dev->reg_addrs[grrr].phys_addr = sbus_devaddr(sbus_dev->slot, base); } /* That surely sucked */ diff -u --recursive v2.1.35/linux/drivers/scsi/a2091.c linux/drivers/scsi/a2091.c --- v2.1.35/linux/drivers/scsi/a2091.c Fri Dec 20 01:20:01 1996 +++ linux/drivers/scsi/a2091.c Thu Apr 17 13:20:46 1997 @@ -9,7 +9,7 @@ #include #include #include -#include +#include #include #include "scsi.h" @@ -211,7 +211,7 @@ address = cd->cd_BoardAddr; instance = scsi_register (tpnt, sizeof (struct WD33C93_hostdata)); instance->base = (unsigned char *)ZTWO_VADDR(address); - instance->irq = IRQ_AMIGA_PORTS & ~IRQ_MACHSPEC; + instance->irq = IRQ_AMIGA_PORTS; instance->unique_id = key; DMA(instance)->DAWR = DAWR_A2091; wd33c93_init(instance, (wd33c93_regs *)&(DMA(instance)->SASR), diff -u --recursive v2.1.35/linux/drivers/scsi/a3000.c linux/drivers/scsi/a3000.c --- v2.1.35/linux/drivers/scsi/a3000.c Fri Dec 20 01:20:02 1996 +++ linux/drivers/scsi/a3000.c Thu Apr 17 13:20:46 1997 @@ -181,7 +181,7 @@ a3000_host = scsi_register (tpnt, sizeof(struct WD33C93_hostdata)); a3000_host->base = (unsigned char *)ZTWO_VADDR(0xDD0000); - a3000_host->irq = IRQ_AMIGA_PORTS & ~IRQ_MACHSPEC; + a3000_host->irq = IRQ_AMIGA_PORTS; DMA(a3000_host)->DAWR = DAWR_A3000; wd33c93_init(a3000_host, (wd33c93_regs *)&(DMA(a3000_host)->SASR), dma_setup, dma_stop, WD33C93_FS_12_15); diff -u --recursive v2.1.35/linux/drivers/scsi/atari_NCR5380.c linux/drivers/scsi/atari_NCR5380.c --- v2.1.35/linux/drivers/scsi/atari_NCR5380.c Mon Apr 14 16:28:16 1997 +++ linux/drivers/scsi/atari_NCR5380.c Thu Apr 17 13:20:46 1997 @@ -753,10 +753,6 @@ pos += sprintf(pos, fmt , ## args); } while(0) static char *lprint_Scsi_Cmnd (Scsi_Cmnd *cmd, char *pos, char *buffer, int length); -static -char *lprint_command (unsigned char *cmd, char *pos, char *buffer, int len); -static -char *lprint_opcode(int opcode, char *pos, char *buffer, int length); #ifndef NCR5380_proc_info static @@ -769,6 +765,14 @@ struct NCR5380_hostdata *hostdata; Scsi_Cmnd *ptr; unsigned long flags; + off_t begin = 0; +#define check_offset() \ + do { \ + if (pos - buffer < offset - begin) { \ + begin += pos - buffer; \ + pos = buffer; \ + } \ + } while (0) for (instance = first_instance; instance && HOSTNO != hostno; instance = instance->next) @@ -781,58 +785,54 @@ return(-ENOSYS); /* Currently this is a no-op */ } SPRINTF("NCR5380 core release=%d.\n", NCR5380_PUBLIC_RELEASE); + check_offset(); save_flags(flags); cli(); SPRINTF("NCR5380: coroutine is%s running.\n", main_running ? "" : "n't"); + check_offset(); if (!hostdata->connected) SPRINTF("scsi%d: no currently connected command\n", HOSTNO); else pos = lprint_Scsi_Cmnd ((Scsi_Cmnd *) hostdata->connected, pos, buffer, length); SPRINTF("scsi%d: issue_queue\n", HOSTNO); - for (ptr = (Scsi_Cmnd *) hostdata->issue_queue; ptr; ptr = NEXT(ptr)) + check_offset(); + for (ptr = (Scsi_Cmnd *) hostdata->issue_queue; ptr; ptr = NEXT(ptr)) { pos = lprint_Scsi_Cmnd (ptr, pos, buffer, length); + check_offset(); + } SPRINTF("scsi%d: disconnected_queue\n", HOSTNO); + check_offset(); for (ptr = (Scsi_Cmnd *) hostdata->disconnected_queue; ptr; - ptr = NEXT(ptr)) + ptr = NEXT(ptr)) { pos = lprint_Scsi_Cmnd (ptr, pos, buffer, length); + check_offset(); + } restore_flags(flags); - *start = buffer; - if (pos - buffer < offset) + *start = buffer + (offset - begin); + if (pos - buffer < offset - begin) return 0; - else if (pos - buffer - offset < length) - return pos - buffer - offset; + else if (pos - buffer - (offset - begin) < length) + return pos - buffer - (offset - begin); return length; } static char * lprint_Scsi_Cmnd (Scsi_Cmnd *cmd, char *pos, char *buffer, int length) { + int i, s; + unsigned char *command; SPRINTF("scsi%d: destination target %d, lun %d\n", H_NO(cmd), cmd->target, cmd->lun); SPRINTF(" command = "); - pos = lprint_command (cmd->cmnd, pos, buffer, length); - return (pos); -} - -static char * -lprint_command (unsigned char *command, char *pos, char *buffer, int length) -{ - int i, s; - pos = lprint_opcode(command[0], pos, buffer, length); + command = cmd->cmnd; + SPRINTF("%2d (0x%02x)", command[0], command[0]); for (i = 1, s = COMMAND_SIZE(command[0]); i < s; ++i) - SPRINTF("%02x ", command[i]); + SPRINTF(" %02x", command[i]); SPRINTF("\n"); - return(pos); -} - -static -char *lprint_opcode(int opcode, char *pos, char *buffer, int length) -{ - SPRINTF("%2d (0x%02x)", opcode, opcode); - return(pos); + return pos; } diff -u --recursive v2.1.35/linux/drivers/scsi/atari_scsi.c linux/drivers/scsi/atari_scsi.c --- v2.1.35/linux/drivers/scsi/atari_scsi.c Mon Apr 14 16:28:16 1997 +++ linux/drivers/scsi/atari_scsi.c Thu Apr 17 13:20:46 1997 @@ -239,13 +239,18 @@ static int atari_read_overruns = 0; #endif -int setup_can_queue = -1; -int setup_cmd_per_lun = -1; -int setup_sg_tablesize = -1; +static int setup_can_queue = -1; +MODULE_PARM(setup_can_queue, "i"); +static int setup_cmd_per_lun = -1; +MODULE_PARM(setup_cmd_per_lun, "i"); +static int setup_sg_tablesize = -1; +MODULE_PARM(setup_sg_tablesize, "i"); #ifdef SUPPORT_TAGS -int setup_use_tagged_queuing = -1; +static int setup_use_tagged_queuing = -1; +MODULE_PARM(setup_use_tagged_queuing, "i"); #endif -int setup_hostid = -1; +static int setup_hostid = -1; +MODULE_PARM(setup_hostid, "i"); #if defined(REAL_DMA) @@ -660,7 +665,7 @@ if (setup_use_tagged_queuing < 0) setup_use_tagged_queuing = DEFAULT_USE_TAGGED_QUEUING; #endif - +#ifdef REAL_DMA /* If running on a Falcon and if there's TT-Ram (i.e., more than one * memory block, since there's always ST-Ram in a Falcon), then allocate a * STRAM_BUFFER_SIZE byte dribble buffer for transfers from/to alternative @@ -673,10 +678,14 @@ atari_dma_phys_buffer = VTOP( atari_dma_buffer ); atari_dma_orig_addr = 0; } - +#endif instance = scsi_register (host, sizeof (struct NCR5380_hostdata)); atari_scsi_host = instance; - instance->irq = IS_A_TT() ? IRQ_TT_MFP_SCSI : IRQ_MFP_FSCSI; + /* Set irq to 0, to avoid that the mid-level code disables our interrupt + * during queue_command calls. This is completely unnecessary, and even + * worse causes bad problems on the Falcon, where the int is shared with + * IDE and floppy! */ + instance->irq = 0; atari_scsi_reset_boot(); NCR5380_init (instance, 0); @@ -693,8 +702,8 @@ tt_scsi_dma.dma_ctrl = 0; atari_dma_residual = 0; #endif /* REAL_DMA */ - - if (is_medusa) { +#ifdef REAL_DMA + if (is_medusa || is_hades) { /* While the read overruns (described by Drew Eckhardt in * NCR5380.c) never happened on TTs, they do in fact on the Medusa * (This was the cause why SCSI didn't work right for so long @@ -709,6 +718,7 @@ */ atari_read_overruns = 4; } +#endif } else { /* ! IS_A_TT */ diff -u --recursive v2.1.35/linux/drivers/scsi/esp.c linux/drivers/scsi/esp.c --- v2.1.35/linux/drivers/scsi/esp.c Mon Apr 14 16:28:16 1997 +++ linux/drivers/scsi/esp.c Thu Apr 17 13:20:47 1997 @@ -20,6 +20,7 @@ #include #include #include +#include #include "scsi.h" #include "hosts.h" @@ -639,7 +640,7 @@ /* Detecting ESP chips on the machine. This is the simple and easy * version. */ -int esp_detect(Scsi_Host_Template *tpnt) +__initfunc(int esp_detect(Scsi_Host_Template *tpnt)) { struct Sparc_ESP *esp, *elink; struct Scsi_Host *esp_host; diff -u --recursive v2.1.35/linux/drivers/scsi/gvp11.c linux/drivers/scsi/gvp11.c --- v2.1.35/linux/drivers/scsi/gvp11.c Fri Dec 20 01:20:02 1996 +++ linux/drivers/scsi/gvp11.c Thu Apr 17 13:20:47 1997 @@ -9,7 +9,7 @@ #include #include #include -#include +#include #include #include "scsi.h" @@ -204,7 +204,7 @@ struct Scsi_Host *instance; caddr_t address; enum GVP_ident epc; - int key; + int key = 0; struct ConfigDev *cd; if (!MACH_IS_AMIGA || called) @@ -214,9 +214,18 @@ tpnt->proc_dir = &proc_scsi_gvp11; tpnt->proc_info = &wd33c93_proc_info; - while ((key = zorro_find(MANUF_GVP, PROD_GVPIISCSI, 0, 0))) { + while ((key = zorro_find(MANUF_GVP, PROD_GVPIISCSI, 0, key))) { cd = zorro_get_board(key); address = cd->cd_BoardAddr; + + /* + * Rumors state that some GVP ram boards use the same product + * code as the SCSI controllers. Therefore if the board-size + * is not 64KB we asume it is a ram board and bail out. + */ + if (cd->cd_BoardSize != 0x10000) + continue; + /* check extended product code */ epc = *(unsigned short *)(ZTWO_VADDR(address) + 0x8000); epc = epc & GVP_PRODMASK; @@ -237,7 +246,7 @@ instance = scsi_register (tpnt, sizeof (struct WD33C93_hostdata)); instance->base = (unsigned char *)ZTWO_VADDR(address); - instance->irq = IRQ_AMIGA_PORTS & ~IRQ_MACHSPEC; + instance->irq = IRQ_AMIGA_PORTS; instance->unique_id = key; if (gvp11_xfer_mask) @@ -307,11 +316,11 @@ int gvp11_release(struct Scsi_Host *instance) { #ifdef MODULE -DMA(instance)->CNTR = 0; -zorro_unconfig_board(instance->unique_id, 0); -if (--num_gvp11 == 0) - free_irq(IRQ_AMIGA_PORTS, gvp11_intr); - wd33c93_release(); + DMA(instance)->CNTR = 0; + zorro_unconfig_board(instance->unique_id, 0); + if (--num_gvp11 == 0) + free_irq(IRQ_AMIGA_PORTS, gvp11_intr); + wd33c93_release(); #endif -return 1; + return 1; } diff -u --recursive v2.1.35/linux/drivers/scsi/ncr53c8xx.c linux/drivers/scsi/ncr53c8xx.c --- v2.1.35/linux/drivers/scsi/ncr53c8xx.c Sun Apr 13 10:18:21 1997 +++ linux/drivers/scsi/ncr53c8xx.c Thu Apr 17 14:48:16 1997 @@ -40,7 +40,7 @@ */ /* -** 6 April 1997, version 1.18d +** 16 April 1997, version 1.18e ** ** Supported SCSI-II features: ** Synchronous negotiation @@ -4520,7 +4520,7 @@ ** **========================================================== */ -int ncr_reset_bus (Scsi_Cmnd *cmd) +int ncr_reset_bus (Scsi_Cmnd *cmd, int sync_reset) { struct Scsi_Host *host = cmd->host; /* Scsi_Device *device = cmd->device; */ @@ -4572,11 +4572,12 @@ */ ncr_wakeup(np, HS_RESET); /* - * If the involved command was not in a driver queue, and is - * not in the waiting list, complete it with DID_RESET status, + * If the involved command was not in a driver queue, and the + * scsi driver told us reset is synchronous, and the command is not + * currently in the waiting list, complete it with DID_RESET status, * in order to keep it alive. */ - if (!found && cmd && !remove_from_waiting_list(np, cmd)) { + if (!found && sync_reset && !retrieve_from_waiting_list(0, np, cmd)) { cmd->result = ScsiResult(DID_RESET, 0); cmd->scsi_done(cmd); } @@ -6363,27 +6364,13 @@ ((INL(nc_dbc) & 0xf8000000) == SCR_WAIT_DISC)) { /* ** Unexpected data cycle while waiting for disconnect. - */ - if (INB(nc_sstat2) & LDSC) { - /* - ** It's an early reconnect. - ** Let's continue ... - */ - OUTONB (nc_dcntl, (STD|NOCOM)); - /* - ** info message - */ - printf ("%s: INFO: LDSC while IID.\n", - ncr_name (np)); - return; - }; - printf ("%s: target %d doesn't release the bus.\n", - ncr_name (np), (int)INB (nc_ctest0)&0x0f); - /* - ** return without restarting the NCR. - ** timeout will do the real work. - */ - return; + ** LDSC and CON bits may help in order to understand + ** what really happened. Print some info message and let + ** the reset function reset the BUS and the NCR. + */ + printf("%s:%d: data cycle while waiting for disconnect, LDSC=%d CON=%d\n", + ncr_name (np), (int)(INB(nc_ctest0)&0x0f), + (0!=(INB(nc_sstat2)&LDSC)), (0!=(INB(nc_scntl1)&ISCON))); }; /*---------------------------------------- @@ -7375,7 +7362,7 @@ /*========================================================== ** ** -** Aquire a control block +** Acquire a control block ** ** **========================================================== @@ -8617,25 +8604,93 @@ ** Linux entry point of reset() function */ -#if LINUX_VERSION_CODE >= LinuxVersionCode(1,3,98) +#if defined SCSI_RESET_SYNCHRONOUS && defined SCSI_RESET_ASYNCHRONOUS + int ncr53c8xx_reset(Scsi_Cmnd *cmd, unsigned int reset_flags) +{ + int sts; + unsigned long flags; + + printk("ncr53c8xx_reset: pid=%lu reset_flags=%x serial_number=%ld serial_number_at_timeout=%ld\n", + cmd->pid, reset_flags, cmd->serial_number, cmd->serial_number_at_timeout); + + save_flags(flags); cli(); + + /* + * We have to just ignore reset requests in some situations. + */ +#if defined SCSI_RESET_NOT_RUNNING + if (cmd->serial_number != cmd->serial_number_at_timeout) { + sts = SCSI_RESET_NOT_RUNNING; + goto out; + } +#endif + /* + * If the mid-level driver told us reset is synchronous, it seems + * that we must call the done() callback for the involved command, + * even if this command was not queued to the low-level driver, + * before returning SCSI_RESET_SUCCESS. + */ + + sts = ncr_reset_bus(cmd, + (reset_flags & (SCSI_RESET_SYNCHRONOUS | SCSI_RESET_ASYNCHRONOUS)) == SCSI_RESET_SYNCHRONOUS); + /* + * Since we always reset the controller, when we return success, + * we add this information to the return code. + */ +#if defined SCSI_RESET_HOST_RESET + if (sts == SCSI_RESET_SUCCESS) + sts |= SCSI_RESET_HOST_RESET; +#endif + +out: + restore_flags(flags); + return sts; +} #else int ncr53c8xx_reset(Scsi_Cmnd *cmd) -#endif { printk("ncr53c8xx_reset: command pid %lu\n", cmd->pid); - return ncr_reset_bus(cmd); + return ncr_reset_bus(cmd, 1); } +#endif /* ** Linux entry point of abort() function */ +#if defined SCSI_RESET_SYNCHRONOUS && defined SCSI_RESET_ASYNCHRONOUS + +int ncr53c8xx_abort(Scsi_Cmnd *cmd) +{ + int sts; + unsigned long flags; + + printk("ncr53c8xx_abort: pid=%lu serial_number=%ld serial_number_at_timeout=%ld\n", + cmd->pid, cmd->serial_number, cmd->serial_number_at_timeout); + + save_flags(flags); cli(); + + /* + * We have to just ignore abort requests in some situations. + */ + if (cmd->serial_number != cmd->serial_number_at_timeout) { + sts = SCSI_ABORT_NOT_RUNNING; + goto out; + } + + sts = ncr_abort_command(cmd); +out: + restore_flags(flags); + return sts; +} +#else int ncr53c8xx_abort(Scsi_Cmnd *cmd) { printk("ncr53c8xx_abort: command pid %lu\n", cmd->pid); return ncr_abort_command(cmd); } +#endif #ifdef MODULE int ncr53c8xx_release(struct Scsi_Host *host) diff -u --recursive v2.1.35/linux/drivers/scsi/ncr53c8xx.h linux/drivers/scsi/ncr53c8xx.h --- v2.1.35/linux/drivers/scsi/ncr53c8xx.h Sun Apr 13 10:18:21 1997 +++ linux/drivers/scsi/ncr53c8xx.h Thu Apr 17 14:48:16 1997 @@ -45,7 +45,7 @@ /* ** Name and revision of the driver */ -#define SCSI_NCR_DRIVER_NAME "ncr53c8xx - revision 1.18d" +#define SCSI_NCR_DRIVER_NAME "ncr53c8xx - revision 1.18e" /* ** If SCSI_NCR_SETUP_SPECIAL_FEATURES is defined, diff -u --recursive v2.1.35/linux/drivers/scsi/ppa.c linux/drivers/scsi/ppa.c --- v2.1.35/linux/drivers/scsi/ppa.c Mon Apr 14 16:28:16 1997 +++ linux/drivers/scsi/ppa.c Thu Apr 17 14:48:53 1997 @@ -1132,69 +1132,72 @@ nhosts = 0; for (i = 0; pb; i++, pb=pb->next) { - int modes; + int modes = pb->modes; - /* transfer global values here */ - if (ppa_speed >= 0) - ppa_hosts[i].speed = ppa_speed; - if (ppa_speed_fast >= 0) - ppa_hosts[i].speed_fast = ppa_speed_fast; + /* We only understand PC-style ports */ + if (modes & PARPORT_MODE_SPP) { - ppa_hosts[i].dev = - parport_register_device(pb, "ppa", NULL, ppa_wakeup, - NULL, PARPORT_DEV_TRAN, (void *) &ppa_hosts[i]); - - /* Claim the bus so it remembers what we do to the control - * registers. [ CTR and ECP ] - */ - ppa_pb_claim(i); - w_ctr(i, 0x0c); - modes = ppa_hosts[i].dev->port->modes; - - ppa_hosts[i].mode = PPA_NIBBLE; - if (modes & (PARPORT_MODE_EPP | PARPORT_MODE_ECPEPP)) { - ppa_hosts[i].mode = PPA_EPP_32; - printk("PPA: Parport [ EPP ]\n"); - } else if (modes & PARPORT_MODE_ECP) { - w_ecr(i, 0x20); - ppa_hosts[i].mode = PPA_PS2; - printk("PPA: Parport [ ECP in PS2 submode ]\n"); - } else if (modes & PARPORT_MODE_PS2) { - ppa_hosts[i].mode = PPA_PS2; - printk("PPA: Parport [ PS2 ]\n"); - } - /* Done configuration */ - ppa_pb_release(i); - - rs = ppa_init(i); - if (rs) { - parport_unregister_device(ppa_hosts[i].dev); - continue; - } - /* now the glue ... */ - switch (ppa_hosts[i].mode) { - case PPA_NIBBLE: - case PPA_PS2: - ports = 3; - break; - case PPA_EPP_8: - case PPA_EPP_16: - case PPA_EPP_32: - ports = 8; - break; - default: /* Never gets here */ - continue; + /* transfer global values here */ + if (ppa_speed >= 0) + ppa_hosts[i].speed = ppa_speed; + if (ppa_speed_fast >= 0) + ppa_hosts[i].speed_fast = ppa_speed_fast; + + ppa_hosts[i].dev = parport_register_device(pb, "ppa", + NULL, ppa_wakeup, NULL, + PARPORT_DEV_TRAN, (void *) &ppa_hosts[i]); + + /* Claim the bus so it remembers what we do to the + * control registers. [ CTR and ECP ] + */ + ppa_pb_claim(i); + w_ctr(i, 0x0c); + + ppa_hosts[i].mode = PPA_NIBBLE; + if (modes & (PARPORT_MODE_EPP | PARPORT_MODE_ECPEPP)) { + ppa_hosts[i].mode = PPA_EPP_32; + printk("PPA: Parport [ EPP ]\n"); + } else if (modes & PARPORT_MODE_ECP) { + w_ecr(i, 0x20); + ppa_hosts[i].mode = PPA_PS2; + printk("PPA: Parport [ ECP in PS2 submode ]\n"); + } else if (modes & PARPORT_MODE_PS2) { + ppa_hosts[i].mode = PPA_PS2; + printk("PPA: Parport [ PS2 ]\n"); + } + /* Done configuration */ + ppa_pb_release(i); + + rs = ppa_init(i); + if (rs) { + parport_unregister_device(ppa_hosts[i].dev); + continue; + } + /* now the glue ... */ + switch (ppa_hosts[i].mode) { + case PPA_NIBBLE: + case PPA_PS2: + ports = 3; + break; + case PPA_EPP_8: + case PPA_EPP_16: + case PPA_EPP_32: + ports = 8; + break; + default: /* Never gets here */ + continue; + } + + host->can_queue = PPA_CAN_QUEUE; + host->sg_tablesize = ppa_sg; + hreg = scsi_register(host, 0); + hreg->io_port = pb->base; + hreg->n_io_port = ports; + hreg->dma_channel = -1; + hreg->unique_id = i; + ppa_hosts[i].host = hreg->host_no; + nhosts++; } - - host->can_queue = PPA_CAN_QUEUE; - host->sg_tablesize = ppa_sg; - hreg = scsi_register(host, 0); - hreg->io_port = pb->base; - hreg->n_io_port = ports; - hreg->dma_channel = -1; - hreg->unique_id = i; - ppa_hosts[i].host = hreg->host_no; - nhosts++; } if (nhosts == 0) return 0; diff -u --recursive v2.1.35/linux/drivers/scsi/qlogicpti.c linux/drivers/scsi/qlogicpti.c --- v2.1.35/linux/drivers/scsi/qlogicpti.c Mon Apr 14 16:28:16 1997 +++ linux/drivers/scsi/qlogicpti.c Thu Apr 17 13:20:47 1997 @@ -18,6 +18,7 @@ #include #include #include +#include #include @@ -342,7 +343,7 @@ #define PTI_RESET_LIMIT 400 -static int qlogicpti_load_firmware(struct qlogicpti *qpti) +__initfunc(static int qlogicpti_load_firmware(struct qlogicpti *qpti)) { struct qlogicpti_regs *qregs = qpti->qregs; unsigned short csum = 0; @@ -561,7 +562,7 @@ static void qlogicpti_intr_handler(int irq, void *dev_id, struct pt_regs *regs); /* Detect all PTI Qlogic ISP's in the machine. */ -int qlogicpti_detect(Scsi_Host_Template *tpnt) +__initfunc(int qlogicpti_detect(Scsi_Host_Template *tpnt)) { struct qlogicpti *qpti, *qlink; struct Scsi_Host *qpti_host; diff -u --recursive v2.1.35/linux/drivers/scsi/qlogicpti_asm.c linux/drivers/scsi/qlogicpti_asm.c --- v2.1.35/linux/drivers/scsi/qlogicpti_asm.c Fri Dec 13 01:37:38 1996 +++ linux/drivers/scsi/qlogicpti_asm.c Thu Apr 17 13:20:47 1997 @@ -2,7 +2,7 @@ unsigned short risc_code_addr01 = 0x1000; -unsigned short risc_code01[] = { +unsigned short risc_code01[] __initdata = { 0x0078, 0x1030, 0x0000, 0x231f, 0x0000, 0x12ff, 0x2043, 0x4f50, 0x5952, 0x4947, 0x4854, 0x2031, 0x3939, 0x312c, 0x3139, 0x3932, 0x2c31, 0x3939, 0x332c, 0x3139, 0x3934, 0x2051, 0x4c4f, 0x4749, diff -u --recursive v2.1.35/linux/drivers/scsi/wd33c93.c linux/drivers/scsi/wd33c93.c --- v2.1.35/linux/drivers/scsi/wd33c93.c Fri Dec 20 01:20:02 1996 +++ linux/drivers/scsi/wd33c93.c Thu Apr 17 13:20:47 1997 @@ -28,9 +28,9 @@ * * - Target Disconnection/Reconnection is now supported. Any * system with more than one device active on the SCSI bus - * will benefit from this. The driver defaults to what I'm - * 'adaptive disconnect' - meaning that each command is - * evaluated individually as to whether or not it should + * will benefit from this. The driver defaults to what I + * call 'adaptive disconnect' - meaning that each command + * is evaluated individually as to whether or not it should * be run with the option to disconnect/reselect (if the * device chooses), or as a "SCSI-bus-hog". * @@ -87,23 +87,19 @@ #include "hosts.h" -#define PROC_INTERFACE /* add code for /proc/scsi/wd33c93/xxx interface */ -#ifdef PROC_INTERFACE -#define PROC_STATISTICS /* add code for keeping various real time stats */ -#endif - -#define SYNC_DEBUG /* extra info on sync negotiation printed */ -#undef DEBUGGING_ON /* enable command-line debugging bitmask */ -#define DEBUG_DEFAULTS 0 /* default debugging bitmask */ - -#define WD33C93_VERSION "1.23" -#define WD33C93_DATE "04/Nov/1996" +#define WD33C93_VERSION "1.24" +#define WD33C93_DATE "29/Jan/1997" -#ifdef DEBUGGING_ON -#define DB(f,a) if (hostdata->args & (f)) a; -#else -#define DB(f,a) -#endif +/* + * Note - the following defines have been moved to 'wd33c93.h': + * + * PROC_INTERFACE + * PROC_STATISTICS + * SYNC_DEBUG + * DEBUGGING_ON + * DEBUG_DEFAULTS + * + */ #include "wd33c93.h" @@ -118,10 +114,11 @@ * keywords (lower case required) and arguments: * * - nosync:bitmask -bitmask is a byte where the 1st 7 bits correspond with - * the 7 possible SCSI devices. Set a bit to prevent sync - * negotiation on that device. To maintain backwards - * compatibility, a command-line such as "wd33c93=255" will - * be automatically translated to "wd33c93=nosync:0xff". + * the 7 possible SCSI devices. Set a bit to negotiate for + * asynchronous transfers on that device. To maintain + * backwards compatibility, a command-line such as + * "wd33c93=255" will be automatically translated to + * "wd33c93=nosync:0xff". * - nodma:x -x = 1 to disable DMA, x = 0 to enable it. Argument is * optional - if not present, same as "nodma:1". * - period:ns -ns is the minimum # of nanoseconds in a SCSI data transfer @@ -166,7 +163,7 @@ -inline uchar read_wd33c93(wd33c93_regs *regp,uchar reg_num) +static inline uchar read_wd33c93(wd33c93_regs *regp,uchar reg_num) { regp->SASR = reg_num; return(regp->SCMD); @@ -176,21 +173,21 @@ #define READ_AUX_STAT() (regp->SASR) -inline void write_wd33c93(wd33c93_regs *regp,uchar reg_num, uchar value) +static inline void write_wd33c93(wd33c93_regs *regp,uchar reg_num, uchar value) { regp->SASR = reg_num; regp->SCMD = value; } -inline void write_wd33c93_cmd(wd33c93_regs *regp, uchar cmd) +static inline void write_wd33c93_cmd(wd33c93_regs *regp, uchar cmd) { regp->SASR = WD_COMMAND; regp->SCMD = cmd; } -inline uchar read_1_byte(wd33c93_regs *regp) +static inline uchar read_1_byte(wd33c93_regs *regp) { uchar asr; uchar x = 0; @@ -206,7 +203,7 @@ } -void write_wd33c93_count(wd33c93_regs *regp,unsigned long value) +static void write_wd33c93_count(wd33c93_regs *regp,unsigned long value) { regp->SASR = WD_TRANSFER_COUNT_MSB; regp->SCMD = value >> 16; @@ -215,7 +212,7 @@ } -unsigned long read_wd33c93_count(wd33c93_regs *regp) +static unsigned long read_wd33c93_count(wd33c93_regs *regp) { unsigned long value; @@ -265,7 +262,7 @@ {1000,0x00}, {0, 0} }; -int round_period(unsigned int period) +static int round_period(unsigned int period) { int x; @@ -278,7 +275,7 @@ return 7; } -uchar calc_sync_xfer(unsigned int period, unsigned int offset) +static uchar calc_sync_xfer(unsigned int period, unsigned int offset) { uchar result; @@ -290,14 +287,13 @@ -void wd33c93_execute(struct Scsi_Host *instance); +static void wd33c93_execute(struct Scsi_Host *instance); int wd33c93_queuecommand (Scsi_Cmnd *cmd, void (*done)(Scsi_Cmnd *)) { -struct WD33C93_hostdata *hostdata; -Scsi_Cmnd *tmp; - - disable_irq(cmd->host->irq); + struct WD33C93_hostdata *hostdata; + Scsi_Cmnd *tmp; + unsigned long flags; hostdata = (struct WD33C93_hostdata *)cmd->host->hostdata; @@ -351,6 +347,9 @@ * sense data is not lost before REQUEST_SENSE executes. */ + save_flags(flags); + cli(); + if (!(hostdata->input_Q) || (cmd->cmnd[0] == REQUEST_SENSE)) { cmd->host_scribble = (uchar *)hostdata->input_Q; hostdata->input_Q = cmd; @@ -370,7 +369,7 @@ DB(DB_QUEUE_COMMAND,printk(")Q-%ld ",cmd->pid)) - enable_irq(cmd->host->irq); + restore_flags(flags); return 0; } @@ -381,15 +380,18 @@ * already connected, we give up immediately. Otherwise, look through * the input_Q, using the first command we find that's intended * for a currently non-busy target/lun. + * + * wd33c93_execute() is always called with interrupts disabled or from + * the wd33c93_intr itself, which means that a wd33c93 interrupt + * cannot occur while we are in here. */ -void wd33c93_execute (struct Scsi_Host *instance) +static void wd33c93_execute (struct Scsi_Host *instance) { struct WD33C93_hostdata *hostdata; wd33c93_regs *regp; Scsi_Cmnd *cmd, *prev; int i; - disable_irq(instance->irq); hostdata = (struct WD33C93_hostdata *)instance->hostdata; regp = hostdata->regp; @@ -399,7 +401,6 @@ DB(DB_EXECUTE,printk(")EX-0 ")) - enable_irq(instance->irq); return; } @@ -423,7 +424,6 @@ DB(DB_EXECUTE,printk(")EX-1 ")) - enable_irq(instance->irq); return; } @@ -500,6 +500,7 @@ #endif no: + write_wd33c93(regp, WD_SOURCE_ID, ((cmd->SCp.phase)?SRCID_ER:0)); write_wd33c93(regp, WD_TARGET_LUN, cmd->lun); @@ -525,17 +526,14 @@ * sync_xfer[] entry is initialized to the default/safe value. SS_UNSET * means that the parameters are undetermined as yet, and that we * need to send an SDTR message to this device after selection is - * complete. We set SS_FIRST to tell the interrupt routine to do so, - * unless we've been asked not to try synchronous transfers on this - * target (and _all_ luns within it): In this case we set SS_SET to - * make the defaults final. - */ - if (hostdata->sync_stat[cmd->target] == SS_UNSET) { - if (hostdata->no_sync & (1 << cmd->target)) - hostdata->sync_stat[cmd->target] = SS_SET; - else + * complete: We set SS_FIRST to tell the interrupt routine to do so. + * If we've been asked not to try synchronous transfers on this + * target (and _all_ luns within it), we'll still send the SDTR message + * later, but at that time we'll negotiate for async by specifying a + * sync fifo depth of 0. + */ + if (hostdata->sync_stat[cmd->target] == SS_UNSET) hostdata->sync_stat[cmd->target] = SS_FIRST; - } hostdata->state = S_SELECTING; write_wd33c93_count(regp,0); /* guarantee a DATA_PHASE interrupt */ write_wd33c93_cmd(regp, WD_CMD_SEL_ATN); @@ -600,13 +598,11 @@ */ DB(DB_EXECUTE,printk("%s%ld)EX-2 ",(cmd->SCp.phase)?"d:":"",cmd->pid)) - - enable_irq(instance->irq); } -void transfer_pio(wd33c93_regs *regp, uchar *buf, int cnt, +static void transfer_pio(wd33c93_regs *regp, uchar *buf, int cnt, int data_in_dir, struct WD33C93_hostdata *hostdata) { uchar asr; @@ -642,7 +638,7 @@ -void transfer_bytes(wd33c93_regs *regp, Scsi_Cmnd *cmd, int data_in_dir) +static void transfer_bytes(wd33c93_regs *regp, Scsi_Cmnd *cmd, int data_in_dir) { struct WD33C93_hostdata *hostdata; unsigned long length; @@ -725,7 +721,7 @@ Scsi_Cmnd *patch, *cmd; wd33c93_regs *regp; uchar asr, sr, phs, id, lun, *ucp, msg; -unsigned long length; +unsigned long length, flags; hostdata = (struct WD33C93_hostdata *)instance->hostdata; regp = hostdata->regp; @@ -734,6 +730,8 @@ if (!(asr & ASR_INT) || (asr & ASR_BSY)) return; + save_flags(flags); + #ifdef PROC_STATISTICS hostdata->int_cnt++; #endif @@ -776,7 +774,6 @@ case CSR_TIMEOUT: DB(DB_INTR,printk("TIMEOUT")) - disable_irq(instance->irq); if (hostdata->state == S_RUNNING_LEVEL2) hostdata->connected = NULL; else { @@ -789,11 +786,22 @@ hostdata->state = S_UNCONNECTED; cmd->scsi_done(cmd); + /* From esp.c: + * There is a window of time within the scsi_done() path + * of execution where interrupts are turned back on full + * blast and left that way. During that time we could + * reconnect to a disconnected command, then we'd bomb + * out below. We could also end up executing two commands + * at _once_. ...just so you know why the restore_flags() + * is here... + */ + + restore_flags(flags); + /* We are not connected to a target - check to see if there * are commands waiting to be executed. */ - enable_irq(instance->irq); wd33c93_execute(instance); break; @@ -801,7 +809,6 @@ /* Note: this interrupt should not occur in a LEVEL2 command */ case CSR_SELECT: - disable_irq(instance->irq); DB(DB_INTR,printk("SELECT")) hostdata->connected = cmd = (Scsi_Cmnd *)hostdata->selecting; @@ -820,13 +827,23 @@ hostdata->sync_stat[cmd->target] = SS_WAITING; - /* tack on a 2nd message to ask about synchronous transfers */ +/* Tack on a 2nd message to ask about synchronous transfers. If we've + * been asked to do only asynchronous transfers on this device, we + * request a fifo depth of 0, which is equivalent to async - should + * solve the problems some people have had with GVP's Guru ROM. + */ hostdata->outgoing_msg[1] = EXTENDED_MESSAGE; hostdata->outgoing_msg[2] = 3; hostdata->outgoing_msg[3] = EXTENDED_SDTR; + if (hostdata->no_sync & (1 << cmd->target)) { + hostdata->outgoing_msg[4] = hostdata->default_sx_per/4; + hostdata->outgoing_msg[5] = 0; + } + else { hostdata->outgoing_msg[4] = OPTIMUM_SX_PER/4; hostdata->outgoing_msg[5] = OPTIMUM_SX_OFF; + } hostdata->outgoing_len = 6; } else @@ -891,7 +908,6 @@ case CSR_SRV_REQ |PHS_MESS_IN: DB(DB_INTR,printk("MSG_IN=")) - disable_irq(instance->irq); msg = read_1_byte(regp); sr = read_wd33c93(regp, WD_SCSI_STATUS); /* clear interrupt */ @@ -1034,13 +1050,13 @@ write_wd33c93_cmd(regp,WD_CMD_NEGATE_ACK); hostdata->state = S_CONNECTED; } + restore_flags(flags); break; /* Note: this interrupt will occur only after a LEVEL2 command */ case CSR_SEL_XFER_DONE: - disable_irq(instance->irq); /* Make sure that reselection is enabled at this point - it may * have been turned off for the command that just completed. @@ -1065,7 +1081,7 @@ /* We are no longer connected to a target - check to see if * there are commands waiting to be executed. */ - enable_irq(instance->irq); + restore_flags(flags); wd33c93_execute(instance); } else { @@ -1124,8 +1140,6 @@ * so we treat it as a normal command-complete-disconnect. */ - disable_irq(instance->irq); - /* Make sure that reselection is enabled at this point - it may * have been turned off for the command that just completed. */ @@ -1149,13 +1163,13 @@ /* We are no longer connected to a target - check to see if * there are commands waiting to be executed. */ - enable_irq(instance->irq); + /* look above for comments on scsi_done() */ + restore_flags(flags); wd33c93_execute(instance); break; case CSR_DISC: - disable_irq(instance->irq); /* Make sure that reselection is enabled at this point - it may * have been turned off for the command that just completed. @@ -1177,6 +1191,7 @@ else if (cmd->SCp.Status != GOOD) cmd->result = (cmd->result & 0x00ffff) | (DID_ERROR << 16); cmd->scsi_done(cmd); + restore_flags(flags); break; case S_PRE_TMP_DISC: case S_RUNNING_LEVEL2: @@ -1198,7 +1213,6 @@ /* We are no longer connected to a target - check to see if * there are commands waiting to be executed. */ - enable_irq(instance->irq); wd33c93_execute(instance); break; @@ -1206,8 +1220,6 @@ case CSR_RESEL_AM: DB(DB_INTR,printk("RESEL")) - disable_irq(instance->irq); - /* First we have to make sure this reselection didn't */ /* happen during Arbitration/Selection of some other device. */ /* If yes, put losing command back on top of input_Q. */ @@ -1306,15 +1318,13 @@ printk("--UNKNOWN INTERRUPT:%02x:%02x:%02x--",asr,sr,phs); } - enable_irq(instance->irq); - DB(DB_INTR,printk("} ")) } -void reset_wd33c93(struct Scsi_Host *instance) +static void reset_wd33c93(struct Scsi_Host *instance) { struct WD33C93_hostdata *hostdata; wd33c93_regs *regp; @@ -1595,7 +1605,7 @@ /* check_setup_strings() returns index if key found, 0 if not */ -int check_setup_strings(char *key, int *flags, int *val, char *buf) +static int check_setup_strings(char *key, int *flags, int *val, char *buf) { int x; char *cp; @@ -1724,16 +1734,17 @@ reset_wd33c93(instance); sti(); - printk("wd33c93-%d: chip=%s/%d no_sync=0x%x no_dma=%d\n",instance->host_no, + printk("wd33c93-%d: chip=%s/%d no_sync=0x%x no_dma=%d",instance->host_no, (hostdata->chip==C_WD33C93)?"WD33c93": (hostdata->chip==C_WD33C93A)?"WD33c93A": (hostdata->chip==C_WD33C93B)?"WD33c93B":"unknown", hostdata->microcode,hostdata->no_sync,hostdata->no_dma); #ifdef DEBUGGING_ON - printk(" debug_flags=0x%02x setup_strings=",hostdata->args); + printk(" debug_flags=0x%02x\n",hostdata->args); #else - printk(" debugging=OFF setup_strings="); + printk(" debugging=OFF\n"); #endif + printk(" setup_strings="); for (i=0; iargs & (f)) a; +#else +#define DB(f,a) +#endif + #define uchar unsigned char @@ -231,13 +247,17 @@ uchar sync_stat[8]; /* status of sync negotiation per target */ uchar no_sync; /* bitmask: don't do sync on these targets */ uchar no_dma; /* set this flag to disable DMA */ +#ifdef PROC_INTERFACE uchar proc; /* bitmask: what's in proc output */ +#ifdef PROC_STATISTICS unsigned long cmd_cnt[8]; /* # of commands issued per target */ unsigned long int_cnt; /* # of interrupts serviced */ unsigned long pio_cnt; /* # of pio data transfers */ unsigned long dma_cnt; /* # of DMA data transfers */ unsigned long disc_allowed_cnt[8]; /* # of disconnects allowed per target */ unsigned long disc_done_cnt[8]; /* # of disconnects done per target*/ +#endif +#endif }; diff -u --recursive v2.1.35/linux/fs/affs/inode.c linux/fs/affs/inode.c --- v2.1.35/linux/fs/affs/inode.c Fri Dec 27 02:03:24 1996 +++ linux/fs/affs/inode.c Thu Apr 17 13:20:47 1997 @@ -26,6 +26,7 @@ #include #include #include +#include #include #include @@ -987,8 +988,7 @@ NULL }; -int -init_affs_fs(void) +__initfunc(int init_affs_fs(void)) { return register_filesystem(&affs_fs_type); } diff -u --recursive v2.1.35/linux/fs/autofs/init.c linux/fs/autofs/init.c --- v2.1.35/linux/fs/autofs/init.c Fri Apr 4 08:52:24 1997 +++ linux/fs/autofs/init.c Tue Apr 15 22:30:38 1997 @@ -10,7 +10,6 @@ * * ------------------------------------------------------------------------- */ -#include #include #include diff -u --recursive v2.1.35/linux/fs/binfmt_aout.c linux/fs/binfmt_aout.c --- v2.1.35/linux/fs/binfmt_aout.c Sun Jan 26 02:07:24 1997 +++ linux/fs/binfmt_aout.c Thu Apr 17 13:20:47 1997 @@ -22,6 +22,7 @@ #include #include #include +#include #include #include @@ -89,7 +90,7 @@ # define START_DATA(u) (u.start_data) #elif defined(__sparc__) # define START_DATA(u) (u.u_tsize) -#elif defined(__i386__) +#elif defined(__i386__) || defined(__mc68000__) # define START_DATA(u) (u.u_tsize << PAGE_SHIFT) #endif #ifdef __sparc__ @@ -555,7 +556,8 @@ } -int init_aout_binfmt(void) { +__initfunc(int init_aout_binfmt(void)) +{ return register_binfmt(&aout_format); } diff -u --recursive v2.1.35/linux/fs/binfmt_elf.c linux/fs/binfmt_elf.c --- v2.1.35/linux/fs/binfmt_elf.c Sun Jan 26 02:07:30 1997 +++ linux/fs/binfmt_elf.c Thu Apr 17 13:20:47 1997 @@ -27,6 +27,7 @@ #include #include #include +#include #include #include @@ -1124,7 +1125,7 @@ #else if (sizeof(elf_gregset_t) != sizeof(struct pt_regs)) { - printk("sizeof(elf_gregset_t) (%d) != sizeof(struct pt_regs) (%d)\n", + printk("sizeof(elf_gregset_t) (%ld) != sizeof(struct pt_regs) (%ld)\n", sizeof(elf_gregset_t), sizeof(struct pt_regs)); } else @@ -1276,7 +1277,7 @@ } #endif /* USE_ELF_CORE_DUMP */ -int init_elf_binfmt(void) +__initfunc(int init_elf_binfmt(void)) { return register_binfmt(&elf_format); } diff -u --recursive v2.1.35/linux/fs/binfmt_em86.c linux/fs/binfmt_em86.c --- v2.1.35/linux/fs/binfmt_em86.c Mon Apr 14 16:28:17 1997 +++ linux/fs/binfmt_em86.c Thu Apr 17 13:20:47 1997 @@ -100,11 +100,12 @@ #ifndef MODULE NULL, 0, load_em86, NULL, NULL #else - NULL, &mod_use_count_, load_em86, NULL, NULL + NULL, &__this_module, load_em86, NULL, NULL #endif }; -int init_em86_binfmt(void) { +__initfunc(int init_em86_binfmt(void)) +{ return register_binfmt(&em86_format); } diff -u --recursive v2.1.35/linux/fs/binfmt_java.c linux/fs/binfmt_java.c --- v2.1.35/linux/fs/binfmt_java.c Sun Jan 26 02:07:30 1997 +++ linux/fs/binfmt_java.c Thu Apr 17 13:20:47 1997 @@ -13,6 +13,7 @@ #include #include #include +#include #define _PATH_JAVA "/usr/bin/java" #define _PATH_APPLET "/usr/bin/appletviewer" @@ -165,7 +166,8 @@ #endif }; -int init_java_binfmt(void) { +__initfunc(int init_java_binfmt(void)) +{ register_binfmt(&java_format); return register_binfmt(&applet_format); } diff -u --recursive v2.1.35/linux/fs/binfmt_script.c linux/fs/binfmt_script.c --- v2.1.35/linux/fs/binfmt_script.c Tue Jan 28 00:02:45 1997 +++ linux/fs/binfmt_script.c Thu Apr 17 13:20:47 1997 @@ -10,6 +10,7 @@ #include #include #include +#include static int do_load_script(struct linux_binprm *bprm,struct pt_regs *regs) { @@ -103,7 +104,8 @@ #endif }; -int init_script_binfmt(void) { +__initfunc(int init_script_binfmt(void)) +{ return register_binfmt(&script_format); } diff -u --recursive v2.1.35/linux/fs/exec.c linux/fs/exec.c --- v2.1.35/linux/fs/exec.c Mon Apr 14 16:28:17 1997 +++ linux/fs/exec.c Thu Apr 17 13:20:47 1997 @@ -41,6 +41,7 @@ #include #include #include +#include #include #include @@ -65,7 +66,7 @@ static struct linux_binfmt *formats = (struct linux_binfmt *) NULL; -void binfmt_setup(void) +__initfunc(void binfmt_setup(void)) { #ifdef CONFIG_BINFMT_ELF init_elf_binfmt(); @@ -533,7 +534,7 @@ if (IS_NOSUID(bprm->inode) || (current->flags & PF_PTRACED) || (current->fs->count > 1) - || (current->sig->count > 1) + || (atomic_read(¤t->sig->count) > 1) || (current->files->count > 1)) { if (!suser()) return -EPERM; diff -u --recursive v2.1.35/linux/fs/ext2/super.c linux/fs/ext2/super.c --- v2.1.35/linux/fs/ext2/super.c Mon Apr 7 11:35:30 1997 +++ linux/fs/ext2/super.c Thu Apr 17 13:20:47 1997 @@ -33,6 +33,7 @@ #include #include #include +#include static char error_buf[1024]; @@ -727,7 +728,7 @@ ext2_read_super, "ext2", 1, NULL }; -int init_ext2_fs(void) +__initfunc(int init_ext2_fs(void)) { return register_filesystem(&ext2_fs_type); } diff -u --recursive v2.1.35/linux/fs/hpfs/hpfs_fs.c linux/fs/hpfs/hpfs_fs.c --- v2.1.35/linux/fs/hpfs/hpfs_fs.c Sun Jan 26 02:07:44 1997 +++ linux/fs/hpfs/hpfs_fs.c Thu Apr 17 13:20:47 1997 @@ -23,6 +23,7 @@ #include #include #include +#include #include #include @@ -1748,7 +1749,7 @@ hpfs_read_super, "hpfs", 1, NULL }; -int init_hpfs_fs(void) +__initfunc(int init_hpfs_fs(void)) { return register_filesystem(&hpfs_fs_type); } diff -u --recursive v2.1.35/linux/fs/isofs/dir.c linux/fs/isofs/dir.c --- v2.1.35/linux/fs/isofs/dir.c Mon Apr 14 16:28:17 1997 +++ linux/fs/isofs/dir.c Thu Apr 17 09:28:01 1997 @@ -155,6 +155,11 @@ filp->f_pos = ((filp->f_pos & ~(ISOFS_BLOCK_SIZE - 1)) + ISOFS_BLOCK_SIZE); offset = 0; + if( filp->f_pos >= inode->i_size ) + { + return 0; + } + block = isofs_bmap(inode, (filp->f_pos) >> bufbits); if (!block) return 0; diff -u --recursive v2.1.35/linux/fs/isofs/inode.c linux/fs/isofs/inode.c --- v2.1.35/linux/fs/isofs/inode.c Mon Apr 14 16:28:17 1997 +++ linux/fs/isofs/inode.c Thu Apr 17 13:20:47 1997 @@ -22,6 +22,7 @@ #include #include #include +#include #include #include @@ -920,7 +921,7 @@ isofs_read_super, "iso9660", 1, NULL }; -int init_iso9660_fs(void) +__initfunc(int init_iso9660_fs(void)) { return register_filesystem(&iso9660_fs_type); } diff -u --recursive v2.1.35/linux/fs/isofs/namei.c linux/fs/isofs/namei.c --- v2.1.35/linux/fs/isofs/namei.c Sat Nov 30 02:24:01 1996 +++ linux/fs/isofs/namei.c Thu Apr 17 09:28:01 1997 @@ -98,6 +98,12 @@ offset = 0; f_pos = ((f_pos & ~(ISOFS_BLOCK_SIZE - 1)) + ISOFS_BLOCK_SIZE); + + if( f_pos >= dir->i_size ) + { + return 0; + } + block = isofs_bmap(dir,f_pos>>bufbits); if (!block || !(bh = bread(dir->i_dev,block,bufsize))) return 0; diff -u --recursive v2.1.35/linux/fs/lockd/host.c linux/fs/lockd/host.c --- v2.1.35/linux/fs/lockd/host.c Mon Apr 7 11:35:30 1997 +++ linux/fs/lockd/host.c Tue Apr 15 21:47:24 1997 @@ -21,7 +21,7 @@ #define NLM_HOST_MAX 64 #define NLM_HOST_NRHASH 32 #define NLM_ADDRHASH(addr) (ntohl(addr) & (NLM_HOST_NRHASH-1)) -#define NLM_PTRHASH(ptr) ((((u32) ptr) / 32) & (NLM_HOST_NRHASH-1)) +#define NLM_PTRHASH(ptr) ((((u32)(unsigned long) ptr) / 32) & (NLM_HOST_NRHASH-1)) #define NLM_HOST_REBIND (60 * HZ) #define NLM_HOST_EXPIRE ((nrhosts > NLM_HOST_MAX)? 300 * HZ : 120 * HZ) #define NLM_HOST_COLLECT ((nrhosts > NLM_HOST_MAX)? 120 * HZ : 60 * HZ) @@ -81,8 +81,8 @@ return NULL; } - dprintk("lockd: nlm_lookup_host(%08lx, p=%d, v=%d)\n", - sin? ntohl(sin->sin_addr.s_addr) : 0, proto, version); + dprintk("lockd: nlm_lookup_host(%08x, p=%d, v=%d)\n", + (unsigned)(sin? ntohl(sin->sin_addr.s_addr) : 0), proto, version); if (clnt) hash = NLM_PTRHASH(clnt); @@ -164,8 +164,8 @@ struct rpc_clnt *clnt; struct rpc_xprt *xprt; - dprintk("lockd: nlm_bind_host(%08lx)\n", - ntohl(host->h_addr.sin_addr.s_addr)); + dprintk("lockd: nlm_bind_host(%08x)\n", + (unsigned)ntohl(host->h_addr.sin_addr.s_addr)); /* Lock host handle */ down(&host->h_sema); diff -u --recursive v2.1.35/linux/fs/lockd/svc.c linux/fs/lockd/svc.c --- v2.1.35/linux/fs/lockd/svc.c Mon Apr 7 11:35:30 1997 +++ linux/fs/lockd/svc.c Tue Apr 15 21:47:24 1997 @@ -130,8 +130,8 @@ break; } - dprintk("lockd: request from %08lx\n", - ntohl(rqstp->rq_addr.sin_addr.s_addr)); + dprintk("lockd: request from %08x\n", + (unsigned)ntohl(rqstp->rq_addr.sin_addr.s_addr)); /* * Look up the NFS client handle. The handle is needed for diff -u --recursive v2.1.35/linux/fs/minix/inode.c linux/fs/minix/inode.c --- v2.1.35/linux/fs/minix/inode.c Fri Dec 27 02:03:25 1996 +++ linux/fs/minix/inode.c Thu Apr 17 13:20:47 1997 @@ -18,6 +18,7 @@ #include #include #include +#include #include #include @@ -946,7 +947,7 @@ minix_read_super, "minix", 1, NULL }; -int init_minix_fs(void) +__initfunc(int init_minix_fs(void)) { return register_filesystem(&minix_fs_type); } diff -u --recursive v2.1.35/linux/fs/msdos/msdosfs_syms.c linux/fs/msdos/msdosfs_syms.c --- v2.1.35/linux/fs/msdos/msdosfs_syms.c Thu Mar 27 14:40:06 1997 +++ linux/fs/msdos/msdosfs_syms.c Thu Apr 17 13:20:48 1997 @@ -10,6 +10,7 @@ #include #include +#include /* * Support for umsdos fs @@ -33,7 +34,7 @@ msdos_read_super, "msdos", 1, NULL }; -int init_msdos_fs(void) +__initfunc(int init_msdos_fs(void)) { return register_filesystem(&msdos_fs_type); } diff -u --recursive v2.1.35/linux/fs/ncpfs/inode.c linux/fs/ncpfs/inode.c --- v2.1.35/linux/fs/ncpfs/inode.c Fri Apr 4 08:52:24 1997 +++ linux/fs/ncpfs/inode.c Thu Apr 17 13:20:48 1997 @@ -23,6 +23,7 @@ #include #include #include +#include #ifdef CONFIG_KERNELD #include #endif @@ -409,7 +410,7 @@ ncp_read_super, "ncpfs", 0, NULL }; -int init_ncp_fs(void) +__initfunc(int init_ncp_fs(void)) { return register_filesystem(&ncp_fs_type); } diff -u --recursive v2.1.35/linux/fs/nfs/dir.c linux/fs/nfs/dir.c --- v2.1.35/linux/fs/nfs/dir.c Mon Apr 7 11:35:30 1997 +++ linux/fs/nfs/dir.c Tue Apr 15 21:47:24 1997 @@ -206,7 +206,7 @@ } if (entry) { dfprintk(DIRCACHE, "NFS: found dircache entry %d\n", - cache - dircache); + (int)(cache - dircache)); cache->locked = 1; break; } @@ -223,7 +223,7 @@ goto again; } dfprintk(DIRCACHE, "NFS: using free dircache entry %d\n", - free - dircache); + (int)(free - dircache)); cache->cookie = cookie; cache->locked = 1; cache->valid = 0; @@ -298,7 +298,7 @@ ino_t ino = inode->i_ino; int i; - dfprintk(DIRCACHE, "NFS: invalidate dircache for %x/%ld\n", dev, ino); + dfprintk(DIRCACHE, "NFS: invalidate dircache for %x/%ld\n", dev, (long)ino); for (i = 0, cache = dircache; i < NFS_MAX_DIRCACHE; i++, cache++) { if (!cache->locked && cache->dev == dev && cache->ino == ino) cache->valid = 0; /* brute force */ @@ -445,7 +445,7 @@ return; dfprintk(LOOKUPCACHE, "NFS: lookup_cache_remove(%x/%ld)\n", - dev, fileid); + dev, (long)fileid); for (i = 0; i < NFS_LOOKUP_CACHE_SIZE; i++) { entry = nfs_lookup_cache + i; diff -u --recursive v2.1.35/linux/fs/nfs/mount_clnt.c linux/fs/nfs/mount_clnt.c --- v2.1.35/linux/fs/nfs/mount_clnt.c Mon Apr 14 16:28:17 1997 +++ linux/fs/nfs/mount_clnt.c Tue Apr 15 21:47:24 1997 @@ -49,8 +49,8 @@ char hostname[32]; int status; - dprintk("NFS: nfs_mount(%08lx:%s)\n", - ntohl(addr->sin_addr.s_addr), path); + dprintk("NFS: nfs_mount(%08x:%s)\n", + (unsigned)ntohl(addr->sin_addr.s_addr), path); strcpy(hostname, in_ntoa(addr->sin_addr.s_addr)); if (!(mnt_clnt = mnt_create(hostname, addr))) diff -u --recursive v2.1.35/linux/fs/nfs/nfs2xdr.c linux/fs/nfs/nfs2xdr.c --- v2.1.35/linux/fs/nfs/nfs2xdr.c Mon Apr 14 16:28:17 1997 +++ linux/fs/nfs/nfs2xdr.c Wed Apr 16 14:20:12 1997 @@ -222,7 +222,7 @@ struct iovec *iov = req->rq_rvec; int status, count, recvd, hdrlen; - dprintk("RPC: readres OK status %lx\n", ntohl(*p)); + dprintk("RPC: readres OK status %lx\n", (long)ntohl(*p)); if ((status = ntohl(*p++))) return -nfs_stat_to_errno(status); p = xdr_decode_fattr(p, res->fattr); @@ -414,9 +414,16 @@ } string -= len; if ((void *) (entry+1) > (void *) string) { + /* This may actually happen because an nfs_entry + * will take up more space than the XDR data. On + * 32bit machines that's due to 8byte alignment, + * on 64bit machines that's because the char * takes + * up 2 longs. + * + * THIS IS BAD! + */ printk(KERN_NOTICE "NFS: should not happen in %s!\n", - __FUNCTION__); - printk(KERN_NOTICE "NFS: len = %d, entry+1=%p, string=%p\n", len, entry+1, string); + __FUNCTION__); break; } @@ -464,7 +471,7 @@ { int status; - dprintk("RPC: attrstat status %lx\n", ntohl(*p)); + dprintk("RPC: attrstat status %lx\n", (long)ntohl(*p)); if ((status = ntohl(*p++))) return -nfs_stat_to_errno(status); xdr_decode_fattr(p, fattr); @@ -482,7 +489,7 @@ { int status; - dprintk("RPC: diropres status %lx\n", ntohl(*p)); + dprintk("RPC: diropres status %lx\n", (long)ntohl(*p)); if ((status = ntohl(*p++))) return -nfs_stat_to_errno(status); p = xdr_decode_fhandle(p, res->fh); diff -u --recursive v2.1.35/linux/fs/nfsd/vfs.c linux/fs/nfsd/vfs.c --- v2.1.35/linux/fs/nfsd/vfs.c Mon Apr 14 16:28:18 1997 +++ linux/fs/nfsd/vfs.c Tue Apr 15 21:47:24 1997 @@ -26,7 +26,6 @@ #include #include #include -#include #include #include #include diff -u --recursive v2.1.35/linux/fs/proc/root.c linux/fs/proc/root.c --- v2.1.35/linux/fs/proc/root.c Mon Apr 7 11:35:31 1997 +++ linux/fs/proc/root.c Wed Apr 16 10:55:21 1997 @@ -365,7 +365,7 @@ char tmp[30]; iput(inode); - len = 1 + sprintf(tmp, "%d", current->pid); + len = sprintf(tmp, "%d", current->pid); if (buflen < len) len = buflen; copy_to_user(buffer, tmp, len); diff -u --recursive v2.1.35/linux/fs/romfs/inode.c linux/fs/romfs/inode.c --- v2.1.35/linux/fs/romfs/inode.c Mon Apr 14 16:28:18 1997 +++ linux/fs/romfs/inode.c Thu Apr 17 13:20:48 1997 @@ -39,6 +39,7 @@ #include #include #include +#include #include @@ -640,8 +641,7 @@ romfs_read_super, "romfs", 1, NULL }; -int -init_romfs_fs(void) +__initfunc(int init_romfs_fs(void)) { return register_filesystem(&romfs_fs_type); } diff -u --recursive v2.1.35/linux/fs/smbfs/inode.c linux/fs/smbfs/inode.c --- v2.1.35/linux/fs/smbfs/inode.c Sun Jan 19 05:47:26 1997 +++ linux/fs/smbfs/inode.c Thu Apr 17 13:20:48 1997 @@ -19,6 +19,7 @@ #include #include #include +#include #include #include @@ -432,8 +433,7 @@ smb_read_super, "smbfs", 0, NULL }; -int -init_smb_fs(void) +__initfunc(int init_smb_fs(void)) { return register_filesystem(&smb_fs_type); } diff -u --recursive v2.1.35/linux/fs/sysv/inode.c linux/fs/sysv/inode.c --- v2.1.35/linux/fs/sysv/inode.c Fri Jan 3 01:33:26 1997 +++ linux/fs/sysv/inode.c Thu Apr 17 13:20:48 1997 @@ -30,6 +30,7 @@ #include #include #include +#include #include @@ -979,7 +980,7 @@ {sysv_read_super, "coherent", 1, NULL} }; -int init_sysv_fs(void) +__initfunc(int init_sysv_fs(void)) { int i; int ouch; diff -u --recursive v2.1.35/linux/fs/ufs/ufs_super.c linux/fs/ufs/ufs_super.c --- v2.1.35/linux/fs/ufs/ufs_super.c Sun Jan 26 02:07:46 1997 +++ linux/fs/ufs/ufs_super.c Thu Apr 17 13:20:48 1997 @@ -8,7 +8,7 @@ * * Copyright (C) 1996 Eddie C. Dost (ecd@skynet.be) * - * $Id: ufs_super.c,v 1.22 1997/01/16 14:17:41 davem Exp $ + * $Id: ufs_super.c,v 1.23 1997/04/16 04:53:39 tdyas Exp $ * */ @@ -27,6 +27,7 @@ #include #include #include +#include #include @@ -51,8 +52,7 @@ ufs_read_super, "ufs", 1, NULL }; -int -init_ufs_fs(void) +__initfunc(int init_ufs_fs(void)) { return(register_filesystem(&ufs_fs_type)); } diff -u --recursive v2.1.35/linux/fs/umsdos/inode.c linux/fs/umsdos/inode.c --- v2.1.35/linux/fs/umsdos/inode.c Fri Dec 27 02:03:26 1996 +++ linux/fs/umsdos/inode.c Thu Apr 17 13:20:48 1997 @@ -8,6 +8,7 @@ #include +#include #include #include #include @@ -499,7 +500,7 @@ UMSDOS_read_super, "umsdos", 1, NULL }; -int init_umsdos_fs(void) +__initfunc(int init_umsdos_fs(void)) { return register_filesystem(&umsdos_fs_type); } diff -u --recursive v2.1.35/linux/fs/vfat/namei.c linux/fs/vfat/namei.c --- v2.1.35/linux/fs/vfat/namei.c Fri Jan 3 01:33:26 1997 +++ linux/fs/vfat/namei.c Thu Apr 17 13:20:48 1997 @@ -20,6 +20,7 @@ #include #include #include +#include #include @@ -1587,7 +1588,7 @@ EXPORT_SYMBOL(vfat_read_inode); EXPORT_SYMBOL(vfat_lookup); -int init_vfat_fs(void) +__initfunc(int init_vfat_fs(void)) { return register_filesystem(&vfat_fs_type); } diff -u --recursive v2.1.35/linux/include/asm-alpha/atomic.h linux/include/asm-alpha/atomic.h --- v2.1.35/linux/include/asm-alpha/atomic.h Wed Apr 16 14:15:00 1997 +++ linux/include/asm-alpha/atomic.h Thu Apr 17 13:20:48 1997 @@ -15,7 +15,7 @@ typedef struct { int counter; } atomic_t; #endif -#define ATOMIC_INIT { 0 } +#define ATOMIC_INIT(i) { (i) } #define atomic_read(v) ((v)->counter) #define atomic_set(v,i) ((v)->counter = (i)) diff -u --recursive v2.1.35/linux/include/asm-alpha/semaphore.h linux/include/asm-alpha/semaphore.h --- v2.1.35/linux/include/asm-alpha/semaphore.h Wed Apr 16 14:15:00 1997 +++ linux/include/asm-alpha/semaphore.h Thu Apr 17 13:20:48 1997 @@ -15,8 +15,8 @@ struct wait_queue * wait; }; -#define MUTEX ((struct semaphore) { { 1 }, { 0 }, NULL }) -#define MUTEX_LOCKED ((struct semaphore) { { 0 }, { 0 }, NULL }) +#define MUTEX ((struct semaphore) { ATOMIC_INIT(1), ATOMIC_INIT(0), NULL }) +#define MUTEX_LOCKED ((struct semaphore) { ATOMIC_INIT(0), ATOMIC_INIT(0), NULL }) extern void __down(struct semaphore * sem); extern int __down_interruptible(struct semaphore * sem); diff -u --recursive v2.1.35/linux/include/asm-alpha/smp_lock.h linux/include/asm-alpha/smp_lock.h --- v2.1.35/linux/include/asm-alpha/smp_lock.h Fri Apr 4 08:52:24 1997 +++ linux/include/asm-alpha/smp_lock.h Thu Apr 17 09:23:54 1997 @@ -6,7 +6,7 @@ #define lock_kernel() do { } while(0) #define unlock_kernel() do { } while(0) #define release_kernel_lock(task, cpu, depth) ((depth) = 1) -#define reaquire_kernel_lock(task, cpu, depth) do { } while (0) +#define reacquire_kernel_lock(task, cpu, depth) do { } while (0) #else diff -u --recursive v2.1.35/linux/include/asm-alpha/spinlock.h linux/include/asm-alpha/spinlock.h --- v2.1.35/linux/include/asm-alpha/spinlock.h Wed Apr 16 14:15:00 1997 +++ linux/include/asm-alpha/spinlock.h Thu Apr 17 13:20:48 1997 @@ -6,16 +6,37 @@ typedef struct { } spinlock_t; #define SPIN_LOCK_UNLOCKED { } -#define spin_lock_init(lock) do { } while(0) +/* + * Basic spinlocks - one can enter at a time + */ + #define spin_lock(lock) do { } while(0) #define spin_trylock(lock) do { } while(0) #define spin_unlock(lock) do { } while(0) #define spin_lock_irq(lock) setipl(7) #define spin_unlock_irq(lock) setipl(0) - #define spin_lock_irqsave(lock, flags) swpipl(flags,7) #define spin_unlock_irqrestore(lock, flags) setipl(flags) +/* + * Read-write locks: we can have multiple readers, but + * only one writer + */ + +#define read_lock(lock) do { } while(0) +#define read_unlock(lock) do { } while(0) +#define read_lock_irq(lock) setipl(7) +#define read_unlock_irq(lock) setipl(0) +#define read_lock_irqsave(lock, flags) swpipl(flags,7) +#define read_unlock_irqrestore(lock, flags) setipl(flags) + +#define write_lock(lock) do { } while(0) +#define write_unlock(lock) do { } while(0) +#define write_lock_irq(lock) setipl(7) +#define write_unlock_irq(lock) setipl(0) +#define write_lock_irqsave(lock, flags) swpipl(flags,7) +#define write_unlock_irqrestore(lock, flags) setipl(flags) + #else /* Simple spin lock operations. There are two variants, one clears IRQ's @@ -30,6 +51,8 @@ } spinlock_t; #define SPIN_LOCK_UNLOCKED { 0, 0 } + +#define spin_lock_init(lock) do { (lock)->lock = 0; (lock)->previous = 0; } while(0) typedef struct { unsigned long a[100]; } __dummy_lock_t; #define __dummy_lock(lock) (*(__dummy_lock_t *)(lock)) diff -u --recursive v2.1.35/linux/include/asm-i386/atomic.h linux/include/asm-i386/atomic.h --- v2.1.35/linux/include/asm-i386/atomic.h Mon Apr 14 16:28:18 1997 +++ linux/include/asm-i386/atomic.h Thu Apr 17 13:20:48 1997 @@ -25,7 +25,7 @@ typedef struct { int counter; } atomic_t; #endif -#define ATOMIC_INIT { 0 } +#define ATOMIC_INIT(i) { (i) } #define atomic_read(v) ((v)->counter) #define atomic_set(v,i) (((v)->counter) = (i)) diff -u --recursive v2.1.35/linux/include/asm-i386/init.h linux/include/asm-i386/init.h --- v2.1.35/linux/include/asm-i386/init.h Wed Apr 16 14:15:00 1997 +++ linux/include/asm-i386/init.h Thu Apr 17 13:20:48 1997 @@ -1,7 +1,6 @@ #ifndef _I386_INIT_H #define _I386_INIT_H -#ifndef MODULE #define __init __attribute__ ((__section__ (".text.init"))) #define __initdata __attribute__ ((__section__ (".data.init"))) #define __initfunc(__arginit) \ @@ -11,14 +10,5 @@ #define __INIT .section ".text.init",#alloc,#execinstr #define __FINIT .previous #define __INITDATA .section ".data.init",#alloc,#write -#else -#define __init -#define __initdata -#define __initfunc(__arginit) __arginit -/* For assembly routines */ -#define __INIT -#define __FINIT -#define __INITDATA -#endif #endif diff -u --recursive v2.1.35/linux/include/asm-i386/semaphore.h linux/include/asm-i386/semaphore.h --- v2.1.35/linux/include/asm-i386/semaphore.h Mon Apr 14 16:28:19 1997 +++ linux/include/asm-i386/semaphore.h Thu Apr 17 13:20:48 1997 @@ -28,8 +28,8 @@ struct wait_queue * wait; }; -#define MUTEX ((struct semaphore) { { 1 }, 0, NULL }) -#define MUTEX_LOCKED ((struct semaphore) { { 0 }, 0, NULL }) +#define MUTEX ((struct semaphore) { ATOMIC_INIT(1), 0, NULL }) +#define MUTEX_LOCKED ((struct semaphore) { ATOMIC_INIT(0), 0, NULL }) asmlinkage void __down_failed(void /* special register calling convention */); asmlinkage int __down_failed_interruptible(void /* params in registers */); diff -u --recursive v2.1.35/linux/include/asm-i386/smp.h linux/include/asm-i386/smp.h --- v2.1.35/linux/include/asm-i386/smp.h Thu Feb 27 10:57:31 1997 +++ linux/include/asm-i386/smp.h Tue Apr 15 21:47:24 1997 @@ -234,52 +234,6 @@ return GET_APIC_ID(*(unsigned long *)(apic_reg+APIC_ID)); } -/* These read/change the "processes available" counter in the scheduler. */ -extern __inline__ __volatile__ void inc_smp_counter(volatile int *ctr) -{ - int cpu = smp_processor_id(); - while(set_bit(31, ctr)) - { - while(test_bit(31,ctr)) - { - if(clear_bit(cpu,&smp_invalidate_needed)) - { - unsigned long tmpreg; - __asm__ __volatile__("movl %%cr3,%0\n\tmovl %0,%%cr3" - : "=r" (tmpreg) : : "memory"); - set_bit(cpu,&cpu_callin_map[0]); - } - } - } - *ctr = (*ctr + 1); - clear_bit(31, ctr); -} - -extern __inline__ __volatile__ void dec_smp_counter(volatile int *ctr) -{ - int cpu = smp_processor_id(); - while(set_bit(31, ctr)) - { - while(test_bit(31,ctr)) - { - if(clear_bit(cpu,&smp_invalidate_needed)) - { - unsigned long tmpreg; - __asm__ __volatile__("movl %%cr3,%0\n\tmovl %0,%%cr3" - : "=r" (tmpreg) : : "memory"); - set_bit(cpu,&cpu_callin_map[0]); - } - } - } - *ctr = (*ctr - 1); - clear_bit(31, ctr); -} - -extern __inline__ __volatile__ int read_smp_counter(volatile int *ctr) -{ - return (*ctr & 0x7fffffff); -} - #endif /* !ASSEMBLY */ #define NO_PROC_ID 0xFF /* No processor magic marker */ diff -u --recursive v2.1.35/linux/include/asm-i386/smp_lock.h linux/include/asm-i386/smp_lock.h --- v2.1.35/linux/include/asm-i386/smp_lock.h Fri Apr 4 08:52:25 1997 +++ linux/include/asm-i386/smp_lock.h Thu Apr 17 13:29:54 1997 @@ -8,7 +8,7 @@ #define lock_kernel() do { } while(0) #define unlock_kernel() do { } while(0) #define release_kernel_lock(task, cpu, depth) ((depth) = 1) -#define reaquire_kernel_lock(task, cpu, depth) do { } while(0) +#define reacquire_kernel_lock(task, cpu, depth) do { } while(0) #else @@ -27,8 +27,8 @@ __sti(); \ } while (0) -/* Re-aquire the kernel lock */ -#define reaquire_kernel_lock(task, cpu, depth) \ +/* Re-acquire the kernel lock */ +#define reacquire_kernel_lock(task, cpu, depth) \ do { if (depth) __asm__ __volatile__( \ "cli\n\t" \ "movl $0f,%%eax\n\t" \ diff -u --recursive v2.1.35/linux/include/asm-i386/spinlock.h linux/include/asm-i386/spinlock.h --- v2.1.35/linux/include/asm-i386/spinlock.h Thu Mar 27 14:40:06 1997 +++ linux/include/asm-i386/spinlock.h Fri Apr 18 21:18:49 1997 @@ -3,6 +3,9 @@ #ifndef __SMP__ +/* + * Your basic spinlocks, allowing only a single CPU anywhere + */ typedef struct { } spinlock_t; #define SPIN_LOCK_UNLOCKED { } @@ -18,9 +21,41 @@ #define spin_unlock_irqrestore(lock, flags) \ restore_flags(flags) +/* + * Read-write spinlocks, allowing multiple readers + * but only one writer. + * + * NOTE! it is quite common to have readers in interrupts + * but no interrupt writers. For those circumstances we + * can "mix" irq-safe locks - any writer needs to get a + * irq-safe write-lock, but readers can get non-irqsafe + * read-locks. + */ +typedef struct { } rwlock_t; +#define RW_LOCK_UNLOCKED { } + +#define read_lock(lock) do { } while(0) +#define read_unlock(lock) do { } while(0) +#define write_lock(lock) do { } while(0) +#define write_unlock(lock) do { } while(0) +#define read_lock_irq(lock) cli() +#define read_unlock_irq(lock) sti() +#define write_lock_irq(lock) cli() +#define write_unlock_irq(lock) sti() + +#define read_lock_irqsave(lock, flags) \ + do { save_flags(flags); cli(); } while (0) +#define read_unlock_irqrestore(lock, flags) \ + restore_flags(flags) +#define write_lock_irqsave(lock, flags) \ + do { save_flags(flags); cli(); } while (0) +#define write_unlock_irqrestore(lock, flags) \ + restore_flags(flags) + #else -/* Simple spin lock operations. There are two variants, one clears IRQ's +/* + * Simple spin lock operations. There are two variants, one clears IRQ's * on the local processor, one does not. * * We make no fairness assumptions. They have a cost. @@ -33,6 +68,8 @@ #define SPIN_LOCK_UNLOCKED { 0, 0 } +#define spin_lock_init(x) do { (x)->lock = 0; (x)->previous = 0; } while(0) + typedef struct { unsigned long a[100]; } __dummy_lock_t; #define __dummy_lock(lock) (*(__dummy_lock_t *)(lock)) @@ -91,6 +128,80 @@ #define spin_unlock_irqrestore(lock, flags) \ do { spin_unlock(lock); __restore_flags(flags); } while (0) + +/* + * Read-write spinlocks, allowing multiple readers + * but only one writer. + * + * NOTE! it is quite common to have readers in interrupts + * but no interrupt writers. For those circumstances we + * can "mix" irq-safe locks - any writer needs to get a + * irq-safe write-lock, but readers can get non-irqsafe + * read-locks. + */ +typedef struct { + volatile unsigned int lock; + unsigned long previous; +} rwlock_t; + +#define RW_LOCK_UNLOCKED { 0, 0 } + +/* + * On x86, we implement read-write locks as a 32-bit counter + * with the high bit (sign) being the "write" bit. + * + * The inline assembly is non-obvious. Think about it. + */ +#define read_lock(rw) \ + asm volatile("\n1:\t" \ + "lock ; incl %0\n\t" \ + "js 2f\n" \ + ".text 2\n" \ + "2:\tlock ; decl %0\n" \ + "3:\tcmpl $0,%0\n\t" \ + "js 3b\n\t" \ + "jmp 1b\n" \ + ".text" \ + :"=m" (__dummy_lock(&(rw)->lock))) + +#define read_unlock(rw) \ + asm volatile("lock ; decl %0" \ + :"=m" (__dummy_lock(&(rw)->lock))) + +#define write_lock(rw) \ + asm volatile("\n1:\t" \ + "lock ; btsl $31,%0\n\t" \ + "jc 3f\n\t" \ + "testl $0x7fffffff,%0\n\t" \ + "jne 4f\n" \ + "2:\n" \ + ".text 2\n" \ + "3:\ttestl $-1,%0\n\t" \ + "js 3b\n\t" \ + "lock ; btsl $31,%0\n\t" \ + "jc 3b\n" \ + "4:\ttestl $0x7fffffff,%0\n\t" \ + "jne 4b\n\t" \ + "jmp 2b\n" \ + ".text" \ + :"=m" (__dummy_lock(&(rw)->lock))) + +#define write_unlock(rw) \ + asm volatile("lock ; btrl $31,%0":"=m" (__dummy_lock(&(rw)->lock))) + +#define read_lock_irq(lock) do { __cli(); read_lock(lock); } while (0) +#define read_unlock_irq(lock) do { read_unlock(lock); __sti(); } while (0) +#define write_lock_irq(lock) do { __cli(); write_lock(lock); } while (0) +#define write_unlock_irq(lock) do { write_unlock(lock); __sti(); } while (0) + +#define read_lock_irqsave(lock, flags) \ + do { __save_flags(flags); __cli(); read_lock(lock); } while (0) +#define read_unlock_irqrestore(lock, flags) \ + do { read_unlock(lock); __restore_flags(flags); } while (0) +#define write_lock_irqsave(lock, flags) \ + do { __save_flags(flags); __cli(); write_lock(lock); } while (0) +#define write_unlock_irqrestore(lock, flags) \ + do { write_unlock(lock); __restore_flags(flags); } while (0) #endif /* SMP */ #endif /* __ASM_SPINLOCK_H */ diff -u --recursive v2.1.35/linux/include/asm-m68k/amigaints.h linux/include/asm-m68k/amigaints.h --- v2.1.35/linux/include/asm-m68k/amigaints.h Wed Sep 25 00:47:41 1996 +++ linux/include/asm-m68k/amigaints.h Thu Apr 17 13:20:48 1997 @@ -18,53 +18,65 @@ ** */ -#define AMI_IRQS (24) +#define AUTO_IRQS (8) #define AMI_STD_IRQS (14) #define CIA_IRQS (5) +#define AMI_IRQS (32) /* AUTO_IRQS+AMI_STD_IRQS+2*CIA_IRQS */ /* vertical blanking interrupt */ -#define IRQ_AMIGA_VERTB (IRQ_MACHSPEC | 0) +#define IRQ_AMIGA_VERTB 0 /* copper interrupt */ -#define IRQ_AMIGA_COPPER (IRQ_MACHSPEC | 1) +#define IRQ_AMIGA_COPPER 1 /* Audio interrupts */ -#define IRQ_AMIGA_AUD0 (IRQ_MACHSPEC | 2) -#define IRQ_AMIGA_AUD1 (IRQ_MACHSPEC | 3) -#define IRQ_AMIGA_AUD2 (IRQ_MACHSPEC | 4) -#define IRQ_AMIGA_AUD3 (IRQ_MACHSPEC | 5) +#define IRQ_AMIGA_AUD0 2 +#define IRQ_AMIGA_AUD1 3 +#define IRQ_AMIGA_AUD2 4 +#define IRQ_AMIGA_AUD3 5 /* Blitter done interrupt */ -#define IRQ_AMIGA_BLIT (IRQ_MACHSPEC | 6) +#define IRQ_AMIGA_BLIT 6 /* floppy disk interrupts */ -#define IRQ_AMIGA_DSKSYN (IRQ_MACHSPEC | 7) -#define IRQ_AMIGA_DSKBLK (IRQ_MACHSPEC | 8) +#define IRQ_AMIGA_DSKSYN 7 +#define IRQ_AMIGA_DSKBLK 8 /* builtin serial port interrupts */ -#define IRQ_AMIGA_RBF (IRQ_MACHSPEC | 9) -#define IRQ_AMIGA_TBE (IRQ_MACHSPEC | 10) +#define IRQ_AMIGA_RBF 9 +#define IRQ_AMIGA_TBE 10 /* software interrupts */ -#define IRQ_AMIGA_SOFT (IRQ_MACHSPEC | 11) +#define IRQ_AMIGA_SOFT 11 /* interrupts from external hardware */ -#define IRQ_AMIGA_PORTS (IRQ_MACHSPEC | 12) -#define IRQ_AMIGA_EXTER (IRQ_MACHSPEC | 13) +#define IRQ_AMIGA_PORTS 12 +#define IRQ_AMIGA_EXTER 13 /* CIA interrupt sources */ -#define IRQ_AMIGA_CIAA (IRQ_MACHSPEC | 14) -#define IRQ_AMIGA_CIAA_TA (IRQ_MACHSPEC | 14) -#define IRQ_AMIGA_CIAA_TB (IRQ_MACHSPEC | 15) -#define IRQ_AMIGA_CIAA_ALRM (IRQ_MACHSPEC | 16) -#define IRQ_AMIGA_CIAA_SP (IRQ_MACHSPEC | 17) -#define IRQ_AMIGA_CIAA_FLG (IRQ_MACHSPEC | 18) -#define IRQ_AMIGA_CIAB (IRQ_MACHSPEC | 19) -#define IRQ_AMIGA_CIAB_TA (IRQ_MACHSPEC | 19) -#define IRQ_AMIGA_CIAB_TB (IRQ_MACHSPEC | 20) -#define IRQ_AMIGA_CIAB_ALRM (IRQ_MACHSPEC | 21) -#define IRQ_AMIGA_CIAB_SP (IRQ_MACHSPEC | 22) -#define IRQ_AMIGA_CIAB_FLG (IRQ_MACHSPEC | 23) +#define IRQ_AMIGA_CIAA 14 +#define IRQ_AMIGA_CIAA_TA 14 +#define IRQ_AMIGA_CIAA_TB 15 +#define IRQ_AMIGA_CIAA_ALRM 16 +#define IRQ_AMIGA_CIAA_SP 17 +#define IRQ_AMIGA_CIAA_FLG 18 +#define IRQ_AMIGA_CIAB 19 +#define IRQ_AMIGA_CIAB_TA 19 +#define IRQ_AMIGA_CIAB_TB 20 +#define IRQ_AMIGA_CIAB_ALRM 21 +#define IRQ_AMIGA_CIAB_SP 22 +#define IRQ_AMIGA_CIAB_FLG 23 + +/* auto-vector interrupts */ +#define IRQ_AMIGA_AUTO 24 +#define IRQ_AMIGA_AUTO_0 24 /* This is just a dummy */ +#define IRQ_AMIGA_AUTO_1 25 +#define IRQ_AMIGA_AUTO_2 26 +#define IRQ_AMIGA_AUTO_3 27 +#define IRQ_AMIGA_AUTO_4 28 +#define IRQ_AMIGA_AUTO_5 29 +#define IRQ_AMIGA_AUTO_6 30 +#define IRQ_AMIGA_AUTO_7 31 #define IRQ_FLOPPY IRQ_AMIGA_DSKBLK diff -u --recursive v2.1.35/linux/include/asm-m68k/atarihw.h linux/include/asm-m68k/atarihw.h --- v2.1.35/linux/include/asm-m68k/atarihw.h Fri Dec 20 01:20:02 1996 +++ linux/include/asm-m68k/atarihw.h Thu Apr 17 13:20:48 1997 @@ -79,6 +79,7 @@ ATARIHW_DECLARE(SCU); /* System Control Unit */ ATARIHW_DECLARE(BLITTER); /* Blitter */ ATARIHW_DECLARE(VME); /* VME Bus */ + ATARIHW_DECLARE(DSP56K); /* DSP56k processor in Falcon */ }; extern struct atari_hw_present atari_hw_present; @@ -97,6 +98,7 @@ void atari_stram_free (void *); extern int is_medusa; +extern int is_hades; /* Do cache push/invalidate for DMA read/write. This function obeys the * snooping on some machines (Medusa) and processors: The Medusa itself can @@ -356,8 +358,8 @@ { u_char tracks; u_char input_source; -#define CODEC_SOURCE_MATRIX 1 -#define CODEC_SOURCE_ADC 2 +#define CODEC_SOURCE_ADC 1 +#define CODEC_SOURCE_MATRIX 2 u_char adc_source; #define ADC_SOURCE_RIGHT_PSG 1 #define ADC_SOURCE_LEFT_PSG 2 @@ -673,17 +675,28 @@ }; # define tt_dmasnd ((*(volatile struct TT_DMASND *)TT_DMASND_BAS)) -#define DMASND_CTRL_OFF 0x00 -#define DMASND_CTRL_ON 0x01 -#define DMASND_CTRL_REPEAT 0x02 -#define DMASND_MODE_MONO 0x80 -#define DMASND_MODE_STEREO 0x00 -#define DMASND_MODE_8BIT 0x00 -#define DMASND_MODE_16BIT 0x40 /* Falcon only */ -#define DMASND_MODE_6KHZ 0x00 /* Falcon: mute */ -#define DMASND_MODE_12KHZ 0x01 -#define DMASND_MODE_25KHZ 0x02 -#define DMASND_MODE_50KHZ 0x03 +#define DMASND_MFP_INT_REPLAY 0x01 +#define DMASND_MFP_INT_RECORD 0x02 +#define DMASND_TIMERA_INT_REPLAY 0x04 +#define DMASND_TIMERA_INT_RECORD 0x08 + +#define DMASND_CTRL_OFF 0x00 +#define DMASND_CTRL_ON 0x01 +#define DMASND_CTRL_REPEAT 0x02 +#define DMASND_CTRL_RECORD_ON 0x10 +#define DMASND_CTRL_RECORD_OFF 0x00 +#define DMASND_CTRL_RECORD_REPEAT 0x20 +#define DMASND_CTRL_SELECT_REPLAY 0x00 +#define DMASND_CTRL_SELECT_RECORD 0x80 +#define DMASND_MODE_MONO 0x80 +#define DMASND_MODE_STEREO 0x00 +#define DMASND_MODE_8BIT 0x00 +#define DMASND_MODE_16BIT 0x40 /* Falcon only */ +#define DMASND_MODE_6KHZ 0x00 /* Falcon: mute */ +#define DMASND_MODE_12KHZ 0x01 +#define DMASND_MODE_25KHZ 0x02 +#define DMASND_MODE_50KHZ 0x03 + #define DMASNDSetBase(bufstart) \ do { \ diff -u --recursive v2.1.35/linux/include/asm-m68k/atariints.h linux/include/asm-m68k/atariints.h --- v2.1.35/linux/include/asm-m68k/atariints.h Wed Sep 25 00:47:41 1996 +++ linux/include/asm-m68k/atariints.h Thu Apr 17 13:20:48 1997 @@ -26,11 +26,11 @@ ** */ -#define STMFP_SOURCE_BASE 8 -#define TTMFP_SOURCE_BASE 24 -#define SCC_SOURCE_BASE 40 -#define VME_SOURCE_BASE 56 -#define VME_MAX_SOURCES 16 +#define STMFP_SOURCE_BASE 8 +#define TTMFP_SOURCE_BASE 24 +#define SCC_SOURCE_BASE 40 +#define VME_SOURCE_BASE 56 +#define VME_MAX_SOURCES 16 #define NUM_ATARI_SOURCES (VME_SOURCE_BASE+VME_MAX_SOURCES-STMFP_SOURCE_BASE) @@ -45,65 +45,65 @@ #define IRQ_TYPE_FAST 1 #define IRQ_TYPE_PRIO 2 -#define IRQ_SPURIOUS (IRQ_MACHSPEC | 0) +#define IRQ_SPURIOUS (0) /* auto-vector interrupts */ -#define IRQ_AUTO_1 (IRQ_MACHSPEC | 1) -#define IRQ_AUTO_2 (IRQ_MACHSPEC | 2) -#define IRQ_AUTO_3 (IRQ_MACHSPEC | 3) -#define IRQ_AUTO_4 (IRQ_MACHSPEC | 4) -#define IRQ_AUTO_5 (IRQ_MACHSPEC | 5) -#define IRQ_AUTO_6 (IRQ_MACHSPEC | 6) -#define IRQ_AUTO_7 (IRQ_MACHSPEC | 7) +#define IRQ_AUTO_1 (1) +#define IRQ_AUTO_2 (2) +#define IRQ_AUTO_3 (3) +#define IRQ_AUTO_4 (4) +#define IRQ_AUTO_5 (5) +#define IRQ_AUTO_6 (6) +#define IRQ_AUTO_7 (7) /* ST-MFP interrupts */ -#define IRQ_MFP_BUSY (IRQ_MACHSPEC | 8) -#define IRQ_MFP_DCD (IRQ_MACHSPEC | 9) -#define IRQ_MFP_CTS (IRQ_MACHSPEC | 10) -#define IRQ_MFP_GPU (IRQ_MACHSPEC | 11) -#define IRQ_MFP_TIMD (IRQ_MACHSPEC | 12) -#define IRQ_MFP_TIMC (IRQ_MACHSPEC | 13) -#define IRQ_MFP_ACIA (IRQ_MACHSPEC | 14) -#define IRQ_MFP_FDC (IRQ_MACHSPEC | 15) +#define IRQ_MFP_BUSY (8) +#define IRQ_MFP_DCD (9) +#define IRQ_MFP_CTS (10) +#define IRQ_MFP_GPU (11) +#define IRQ_MFP_TIMD (12) +#define IRQ_MFP_TIMC (13) +#define IRQ_MFP_ACIA (14) +#define IRQ_MFP_FDC (15) #define IRQ_MFP_ACSI IRQ_MFP_FDC #define IRQ_MFP_FSCSI IRQ_MFP_FDC #define IRQ_MFP_IDE IRQ_MFP_FDC -#define IRQ_MFP_TIMB (IRQ_MACHSPEC | 16) -#define IRQ_MFP_SERERR (IRQ_MACHSPEC | 17) -#define IRQ_MFP_SEREMPT (IRQ_MACHSPEC | 18) -#define IRQ_MFP_RECERR (IRQ_MACHSPEC | 19) -#define IRQ_MFP_RECFULL (IRQ_MACHSPEC | 20) -#define IRQ_MFP_TIMA (IRQ_MACHSPEC | 21) -#define IRQ_MFP_RI (IRQ_MACHSPEC | 22) -#define IRQ_MFP_MMD (IRQ_MACHSPEC | 23) +#define IRQ_MFP_TIMB (16) +#define IRQ_MFP_SERERR (17) +#define IRQ_MFP_SEREMPT (18) +#define IRQ_MFP_RECERR (19) +#define IRQ_MFP_RECFULL (20) +#define IRQ_MFP_TIMA (21) +#define IRQ_MFP_RI (22) +#define IRQ_MFP_MMD (23) /* TT-MFP interrupts */ -#define IRQ_TT_MFP_IO0 (IRQ_MACHSPEC | 24) -#define IRQ_TT_MFP_IO1 (IRQ_MACHSPEC | 25) -#define IRQ_TT_MFP_SCC (IRQ_MACHSPEC | 26) -#define IRQ_TT_MFP_RI (IRQ_MACHSPEC | 27) -#define IRQ_TT_MFP_TIMD (IRQ_MACHSPEC | 28) -#define IRQ_TT_MFP_TIMC (IRQ_MACHSPEC | 29) -#define IRQ_TT_MFP_DRVRDY (IRQ_MACHSPEC | 30) -#define IRQ_TT_MFP_SCSIDMA (IRQ_MACHSPEC | 31) -#define IRQ_TT_MFP_TIMB (IRQ_MACHSPEC | 32) -#define IRQ_TT_MFP_SERERR (IRQ_MACHSPEC | 33) -#define IRQ_TT_MFP_SEREMPT (IRQ_MACHSPEC | 34) -#define IRQ_TT_MFP_RECERR (IRQ_MACHSPEC | 35) -#define IRQ_TT_MFP_RECFULL (IRQ_MACHSPEC | 36) -#define IRQ_TT_MFP_TIMA (IRQ_MACHSPEC | 37) -#define IRQ_TT_MFP_RTC (IRQ_MACHSPEC | 38) -#define IRQ_TT_MFP_SCSI (IRQ_MACHSPEC | 39) +#define IRQ_TT_MFP_IO0 (24) +#define IRQ_TT_MFP_IO1 (25) +#define IRQ_TT_MFP_SCC (26) +#define IRQ_TT_MFP_RI (27) +#define IRQ_TT_MFP_TIMD (28) +#define IRQ_TT_MFP_TIMC (29) +#define IRQ_TT_MFP_DRVRDY (30) +#define IRQ_TT_MFP_SCSIDMA (31) +#define IRQ_TT_MFP_TIMB (32) +#define IRQ_TT_MFP_SERERR (33) +#define IRQ_TT_MFP_SEREMPT (34) +#define IRQ_TT_MFP_RECERR (35) +#define IRQ_TT_MFP_RECFULL (36) +#define IRQ_TT_MFP_TIMA (37) +#define IRQ_TT_MFP_RTC (38) +#define IRQ_TT_MFP_SCSI (39) /* SCC interrupts */ -#define IRQ_SCCB_TX (IRQ_MACHSPEC | 40) -#define IRQ_SCCB_STAT (IRQ_MACHSPEC | 42) -#define IRQ_SCCB_RX (IRQ_MACHSPEC | 44) -#define IRQ_SCCB_SPCOND (IRQ_MACHSPEC | 46) -#define IRQ_SCCA_TX (IRQ_MACHSPEC | 48) -#define IRQ_SCCA_STAT (IRQ_MACHSPEC | 50) -#define IRQ_SCCA_RX (IRQ_MACHSPEC | 52) -#define IRQ_SCCA_SPCOND (IRQ_MACHSPEC | 54) +#define IRQ_SCCB_TX (40) +#define IRQ_SCCB_STAT (42) +#define IRQ_SCCB_RX (44) +#define IRQ_SCCB_SPCOND (46) +#define IRQ_SCCA_TX (48) +#define IRQ_SCCA_STAT (50) +#define IRQ_SCCA_RX (52) +#define IRQ_SCCA_SPCOND (54) #define INT_CLK 24576 /* CLK while int_clk =2.456MHz and divide = 100 */ @@ -164,7 +164,6 @@ static inline void atari_enable_irq( unsigned irq ) { - irq &= ~IRQ_MACHSPEC; if (irq < STMFP_SOURCE_BASE || irq >= SCC_SOURCE_BASE) return; set_mfp_bit( irq, MFP_MASK ); } @@ -172,7 +171,6 @@ static inline void atari_disable_irq( unsigned irq ) { - irq &= ~IRQ_MACHSPEC; if (irq < STMFP_SOURCE_BASE || irq >= SCC_SOURCE_BASE) return; clear_mfp_bit( irq, MFP_MASK ); } @@ -185,7 +183,6 @@ extern inline void atari_turnon_irq( unsigned irq ) { - irq &= ~IRQ_MACHSPEC; if (irq < STMFP_SOURCE_BASE || irq >= SCC_SOURCE_BASE) return; set_mfp_bit( irq, MFP_ENABLE ); } @@ -193,7 +190,6 @@ extern inline void atari_turnoff_irq( unsigned irq ) { - irq &= ~IRQ_MACHSPEC; if (irq < STMFP_SOURCE_BASE || irq >= SCC_SOURCE_BASE) return; clear_mfp_bit( irq, MFP_ENABLE ); clear_mfp_bit( irq, MFP_PENDING ); @@ -202,7 +198,6 @@ extern inline void atari_clear_pending_irq( unsigned irq ) { - irq &= ~IRQ_MACHSPEC; if (irq < STMFP_SOURCE_BASE || irq >= SCC_SOURCE_BASE) return; clear_mfp_bit( irq, MFP_PENDING ); } @@ -210,7 +205,6 @@ extern inline int atari_irq_pending( unsigned irq ) { - irq &= ~IRQ_MACHSPEC; if (irq < STMFP_SOURCE_BASE || irq >= SCC_SOURCE_BASE) return( 0 ); return( get_mfp_bit( irq, MFP_PENDING ) ); } diff -u --recursive v2.1.35/linux/include/asm-m68k/atomic.h linux/include/asm-m68k/atomic.h --- v2.1.35/linux/include/asm-m68k/atomic.h Mon Apr 14 16:28:19 1997 +++ linux/include/asm-m68k/atomic.h Thu Apr 17 13:20:48 1997 @@ -14,7 +14,7 @@ #define ATOMIC_INIT { 0 } #define atomic_read(v) ((v)->counter) -#define atomic_set(v) (((v)->counter) = i) +#define atomic_set(v, i) (((v)->counter) = i) static __inline__ void atomic_add(int i, atomic_t *v) { @@ -26,21 +26,27 @@ __asm__ __volatile__("subl %1,%0" : : "m" (*v), "id" (i)); } -static __inline__ void atomic_inc(atomic_t *v) +static __inline__ void atomic_inc(volatile atomic_t *v) { __asm__ __volatile__("addql #1,%0" : : "m" (*v)); } -static __inline__ void atomic_dec(atomic_t *v) +static __inline__ void atomic_dec(volatile atomic_t *v) { __asm__ __volatile__("subql #1,%0" : : "m" (*v)); } -static __inline__ int atomic_dec_and_test(atomic_t *v) +static __inline__ int atomic_dec_and_test(volatile atomic_t *v) { char c; __asm__ __volatile__("subql #1,%1; seq %0" : "=d" (c) : "m" (*v)); return c != 0; } + +#define atomic_clear_mask(mask, v) \ + __asm__ __volatile__("andl %1,%0" : : "m" (*v), "id" (~(mask))) + +#define atomic_set_mask(mask, v) \ + __asm__ __volatile__("orl %1,%0" : : "m" (*v), "id" (mask)); #endif /* __ARCH_M68K_ATOMIC __ */ diff -u --recursive v2.1.35/linux/include/asm-m68k/bootinfo.h linux/include/asm-m68k/bootinfo.h --- v2.1.35/linux/include/asm-m68k/bootinfo.h Fri Dec 20 01:20:02 1996 +++ linux/include/asm-m68k/bootinfo.h Thu Apr 17 13:20:48 1997 @@ -141,8 +141,7 @@ #define COMPAT_AMIGA_BOOTI_VERSION MK_BI_VERSION( 1, 0 ) #define COMPAT_ATARI_BOOTI_VERSION MK_BI_VERSION( 1, 0 ) -#include -#include +#include #define COMPAT_NUM_AUTO 16 diff -u --recursive v2.1.35/linux/include/asm-m68k/byteorder.h linux/include/asm-m68k/byteorder.h --- v2.1.35/linux/include/asm-m68k/byteorder.h Fri Dec 20 01:20:02 1996 +++ linux/include/asm-m68k/byteorder.h Thu Apr 17 13:20:48 1997 @@ -10,7 +10,6 @@ #endif #ifdef __KERNEL__ -#include #include /* diff -u --recursive v2.1.35/linux/include/asm-m68k/cache.h linux/include/asm-m68k/cache.h --- v2.1.35/linux/include/asm-m68k/cache.h Sun Jan 26 02:07:46 1997 +++ linux/include/asm-m68k/cache.h Thu Apr 17 13:20:48 1997 @@ -5,7 +5,7 @@ #define __ARCH_M68K_CACHE_H /* bytes per L1 cache line */ -#define L1_CACHE_BYTES 32 /* a guess */ +#define L1_CACHE_BYTES 16 #define L1_CACHE_ALIGN(x) (((x)+(L1_CACHE_BYTES-1))&~(L1_CACHE_BYTES-1)) diff -u --recursive v2.1.35/linux/include/asm-m68k/checksum.h linux/include/asm-m68k/checksum.h --- v2.1.35/linux/include/asm-m68k/checksum.h Fri Dec 20 01:20:02 1996 +++ linux/include/asm-m68k/checksum.h Thu Apr 17 13:20:48 1997 @@ -35,6 +35,9 @@ unsigned int csum_partial_copy_fromuser(const char *src, char *dst, int len, int sum); +extern unsigned int +csum_partial_copy_from_user ( const char *src, char *dst, + int len, int sum, int *csum_err); /* * This is a version of ip_compute_csum() optimized for IP headers, Only in linux/include/asm-m68k: dsp56k.h Only in linux/include/asm-m68k: fpu.h Only in linux/include/asm-m68k: hardirq.h diff -u --recursive v2.1.35/linux/include/asm-m68k/ide.h linux/include/asm-m68k/ide.h --- v2.1.35/linux/include/asm-m68k/ide.h Mon Apr 14 16:28:19 1997 +++ linux/include/asm-m68k/ide.h Thu Apr 17 13:20:49 1997 @@ -40,6 +40,7 @@ #endif /* CONFIG_AMIGA */ #ifdef CONFIG_ATARI +#include /* intr_count */ #include #include #include diff -u --recursive v2.1.35/linux/include/asm-m68k/ioctl.h linux/include/asm-m68k/ioctl.h --- v2.1.35/linux/include/asm-m68k/ioctl.h Wed Sep 25 00:47:41 1996 +++ linux/include/asm-m68k/ioctl.h Thu Apr 17 13:20:49 1997 @@ -1,4 +1,4 @@ -/* $Id: ioctl.h,v 1.1 1996/08/24 12:43:44 root Exp $ +/* $Id: ioctl.h,v 1.3 1997/04/16 15:10:07 jes Exp $ * * linux/ioctl.h for Linux by H.H. Bergman. */ diff -u --recursive v2.1.35/linux/include/asm-m68k/irq.h linux/include/asm-m68k/irq.h --- v2.1.35/linux/include/asm-m68k/irq.h Wed Sep 25 00:47:41 1996 +++ linux/include/asm-m68k/irq.h Thu Apr 17 13:20:49 1997 @@ -1,9 +1,6 @@ #ifndef _M68K_IRQ_H_ #define _M68K_IRQ_H_ -extern void disable_irq(unsigned int); -extern void enable_irq(unsigned int); - #include /* @@ -54,10 +51,24 @@ * Adding an interrupt service routine for a source with this bit * set indicates a special machine specific interrupt source. * The machine specific files define these sources. + * + * The IRQ_MACHSPEC bit is now gone - the only thing it did was to + * introduce unnecessary overhead. + * + * All interrupt handling is actually machine specific so it is better + * to use function pointers, as used by the Sparc port, and select the + * interrupt handling functions when initializing the kernel. This way + * we save some unnecessary overhead at run-time. + * 01/11/97 - Jes */ -#define IRQ_MACHSPEC (0x10000000L) -#define IRQ_IDX(irq) ((irq) & ~IRQ_MACHSPEC) +extern void (*enable_irq)(unsigned int); +extern void (*disable_irq)(unsigned int); + +extern int sys_request_irq(unsigned int, + void (*)(int, void *, struct pt_regs *), + unsigned long, const char *, void *); +extern void sys_free_irq(unsigned int, void *); /* * various flags for request_irq() diff -u --recursive v2.1.35/linux/include/asm-m68k/machdep.h linux/include/asm-m68k/machdep.h --- v2.1.35/linux/include/asm-m68k/machdep.h Fri Dec 20 01:20:02 1996 +++ linux/include/asm-m68k/machdep.h Thu Apr 17 13:20:49 1997 @@ -18,9 +18,7 @@ extern void (*(*mach_default_handler)[]) (int, void *, struct pt_regs *); extern int (*mach_request_irq) (unsigned int irq, void (*handler)(int, void *, struct pt_regs *), unsigned long flags, const char *devname, void *dev_id); -extern int (*mach_free_irq) (unsigned int irq, void *dev_id); -extern void (*mach_enable_irq) (unsigned int irq); -extern void (*mach_disable_irq) (unsigned int irq); +extern void (*mach_free_irq) (unsigned int irq, void *dev_id); extern void (*mach_get_model) (char *model); extern int (*mach_get_hardware_list) (char *buffer); extern int (*mach_get_irq_list) (char *buf); @@ -31,18 +29,14 @@ int *min, int *sec); extern int (*mach_hwclk)(int, struct hwclk_time*); extern int (*mach_set_clock_mmss)(unsigned long); -extern void (*mach_mksound)( unsigned int count, unsigned int ticks ); extern void (*mach_reset)( void ); extern int (*mach_floppy_init) (void); extern unsigned long (*mach_hd_init) (unsigned long, unsigned long); extern void (*mach_hd_setup)(char *, int *); -extern void (*waitbut)(void); extern struct fb_info *(*mach_fb_init)(long *); extern long mach_max_dma_address; -extern void (*mach_debug_init)(void); extern void (*mach_video_setup)(char *, int *); extern void (*mach_floppy_setup)(char *, int *); extern void (*mach_floppy_eject)(void); -extern void (*mach_syms_export)(void); #endif /* _M68K_MACHDEP_H */ Only in linux/include/asm-m68k: namei.h diff -u --recursive v2.1.35/linux/include/asm-m68k/page.h linux/include/asm-m68k/page.h --- v2.1.35/linux/include/asm-m68k/page.h Fri Nov 22 05:56:36 1996 +++ linux/include/asm-m68k/page.h Thu Apr 17 13:20:50 1997 @@ -8,10 +8,58 @@ #ifdef __KERNEL__ +#include + #define STRICT_MM_TYPECHECKS +/* + * We don't need to check for alignment etc. + */ +#if defined(CONFIG_OPTIMIZE_040) || defined(CONFIG_OPTIMIZE_060) +static inline void copy_page(unsigned long to, unsigned long from) +{ + unsigned long tmp; + + __asm__ __volatile__("1:\t" + ".chip 68040\n\t" + "move16 %1@+,%0@+\n\t" + "move16 %1@+,%0@+\n\t" + ".chip 68k\n\t" + "dbra %2,1b\n\t" + : "=a" (to), "=a" (from), "=d" (tmp) + : "0" (to), "1" (from) , "2" (PAGE_SIZE / 32 - 1) + ); +} + +static inline void clear_page(unsigned long page) +{ + unsigned long data, sp, tmp; + + sp = page; + + data = 0; + + *((unsigned long *)(page))++ = 0; + *((unsigned long *)(page))++ = 0; + *((unsigned long *)(page))++ = 0; + *((unsigned long *)(page))++ = 0; + + __asm__ __volatile__("1:\t" + ".chip 68040\n\t" + "move16 %2@+,%0@+\n\t" + ".chip 68k\n\t" + "subqw #8,%2\n\t" + "subqw #8,%2\n\t" + "dbra %1,1b\n\t" + : "=a" (page), "=d" (tmp) + : "a" (sp), "0" (page), + "1" ((PAGE_SIZE - 16) / 16 - 1)); +} + +#else #define clear_page(page) memset((void *)(page), 0, PAGE_SIZE) #define copy_page(to,from) memcpy((void *)(to), (void *)(from), PAGE_SIZE) +#endif #ifdef STRICT_MM_TYPECHECKS /* diff -u --recursive v2.1.35/linux/include/asm-m68k/pgtable.h linux/include/asm-m68k/pgtable.h --- v2.1.35/linux/include/asm-m68k/pgtable.h Fri Dec 20 01:20:03 1996 +++ linux/include/asm-m68k/pgtable.h Thu Apr 17 13:20:50 1997 @@ -10,6 +10,170 @@ * the m68k page table tree. */ +/* For virtual address to physical address conversion */ +extern unsigned long mm_vtop(unsigned long addr) __attribute__ ((const)); +extern unsigned long mm_ptov(unsigned long addr) __attribute__ ((const)); +#define VTOP(addr) (mm_vtop((unsigned long)(addr))) +#define PTOV(addr) (mm_ptov((unsigned long)(addr))) + +/* + * Cache handling functions + */ + +#define flush_icache() \ +do { \ + if (CPU_IS_040_OR_060) \ + asm __volatile__ ("nop\n\t" \ + ".chip 68040\n\t" \ + "cinva %%ic\n\t" \ + ".chip 68k"); \ + else { \ + unsigned long _tmp; \ + asm __volatile__ ("movec %%cacr,%0\n\t" \ + "orw %1,%0\n\t" \ + "movec %0,%%cacr" \ + : "=&d" (_tmp) \ + : "id" (FLUSH_I)); \ + } \ +} while (0) + +/* + * invalidate the cache for the specified memory range. + * It starts at the physical address specified for + * the given number of bytes. + */ +extern void cache_clear (unsigned long paddr, int len); +/* + * push any dirty cache in the specified memory range. + * It starts at the physical address specified for + * the given number of bytes. + */ +extern void cache_push (unsigned long paddr, int len); + +/* + * push and invalidate pages in the specified user virtual + * memory range. + */ +extern void cache_push_v (unsigned long vaddr, int len); + +/* cache code */ +#define FLUSH_I_AND_D (0x00000808) +#define FLUSH_I (0x00000008) + +/* This is needed whenever the virtual mapping of the current + process changes. */ +#define __flush_cache_all() \ + do { \ + if (CPU_IS_040_OR_060) \ + __asm__ __volatile__ ("nop\n\t" \ + ".chip 68040\n\t" \ + "cpusha %dc\n\t" \ + ".chip 68k"); \ + else { \ + unsigned long _tmp; \ + __asm__ __volatile__ ("movec %%cacr,%0\n\t" \ + "orw %1,%0\n\t" \ + "movec %0,%%cacr" \ + : "=&d" (_tmp) \ + : "di" (FLUSH_I_AND_D)); \ + } \ + } while (0) + +#define __flush_cache_030() \ + do { \ + if (CPU_IS_020_OR_030) { \ + unsigned long _tmp; \ + __asm__ __volatile__ ("movec %%cacr,%0\n\t" \ + "orw %1,%0\n\t" \ + "movec %0,%%cacr" \ + : "=&d" (_tmp) \ + : "di" (FLUSH_I_AND_D)); \ + } \ + } while (0) + +#define flush_cache_all() __flush_cache_all() + +extern inline void flush_cache_mm(struct mm_struct *mm) +{ +#if FLUSH_VIRTUAL_CACHE_040 + if (mm == current->mm) __flush_cache_all(); +#else + if (mm == current->mm) __flush_cache_030(); +#endif +} + +extern inline void flush_cache_range(struct mm_struct *mm, + unsigned long start, + unsigned long end) +{ + if (mm == current->mm){ +#if FLUSH_VIRTUAL_CACHE_040 + if (CPU_IS_040_OR_060) + cache_push_v(start, end-start); + else +#endif + __flush_cache_030(); + } +} + +extern inline void flush_cache_page(struct vm_area_struct *vma, + unsigned long vmaddr) +{ + if (vma->vm_mm == current->mm){ +#if FLUSH_VIRTUAL_CACHE_040 + if (CPU_IS_040_OR_060) + cache_push_v(vmaddr, PAGE_SIZE); + else +#endif + __flush_cache_030(); + } +} + +/* Push the page at kernel virtual address and clear the icache */ +extern inline void flush_page_to_ram (unsigned long address) +{ + if (CPU_IS_040_OR_060) { + __asm__ __volatile__ ("nop\n\t" + ".chip 68040\n\t" + "cpushp %%dc,(%0)\n\t" + "cinvp %%ic,(%0)\n\t" + ".chip 68k" + : : "a" (VTOP(address))); + } + else { + unsigned long _tmp; + __asm volatile ("movec %%cacr,%0\n\t" + "orw %1,%0\n\t" + "movec %0,%%cacr" + : "=&d" (_tmp) + : "di" (FLUSH_I)); + } +} + +/* Push n pages at kernel virtual address and clear the icache */ +extern inline void flush_pages_to_ram (unsigned long address, int n) +{ + if (CPU_IS_040_OR_060) { + while (n--) { + __asm__ __volatile__ ("nop\n\t" + ".chip 68040\n\t" + "cpushp %%dc,(%0)\n\t" + "cinvp %%ic,(%0)\n\t" + ".chip 68k" + : : "a" (VTOP(address))); + address += PAGE_SIZE; + } + } + else { + unsigned long _tmp; + __asm volatile ("movec %%cacr,%0\n\t" + "orw %1,%0\n\t" + "movec %0,%%cacr" + : "=&d" (_tmp) + : "di" (FLUSH_I)); + } +} + /* * flush all atc entries (user-space entries only for the 680[46]0). */ @@ -31,7 +195,7 @@ ".chip 68k" : : "a" (addr)); } else - __asm__ __volatile__("pflush #0,#0,(%0)" : : "a" (addr)); + __asm__ __volatile__("pflush #0,#4,(%0)" : : "a" (addr)); } #define flush_tlb() __flush_tlb() @@ -69,17 +233,27 @@ __flush_tlb(); } +extern inline void flush_tlb_kernel_page(unsigned long addr) +{ + if (CPU_IS_040_OR_060) { + unsigned long old_fs = get_fs(); + set_fs(KERNEL_DS); + __asm__ __volatile__(".chip 68040\n\t" + "pflush (%0)\n\t" + ".chip 68k" + : : "a" (addr)); + set_fs(old_fs); + } else + __asm__ __volatile__("pflush #4,#4,(%0)" : : "a" (addr)); +} + /* Certain architectures need to do special things when pte's * within a page table are directly modified. Thus, the following * hook is made available. */ #define set_pte(pteptr, pteval) \ do{ \ - *(pteptr) = (pteval); \ - if (CPU_IS_060) \ - __asm__ __volatile__(".chip 68060\n\t" \ - "pflusha\n\t" \ - ".chip 68k"); \ + *(pteptr) = (pteval); \ } while(0) @@ -160,9 +334,9 @@ * and initialized in head.S */ extern int m68k_pgtable_cachemode; -#if defined(CONFIG_M68040_OR_M68060_ONLY) +#if defined(CPU_M68040_OR_M68060_ONLY) #define mm_cachebits _PAGE_CACHE040 -#elif defined(CONFIG_M68020_OR_M68030_ONLY) +#elif defined(CPU_M68020_OR_M68030_ONLY) #define mm_cachebits 0 #else extern unsigned long mm_cachebits; @@ -234,12 +408,6 @@ #define PAGE_PTR(address) \ ((unsigned long)(address)>>(PAGE_SHIFT-SIZEOF_PTR_LOG2)&PTR_MASK&~PAGE_MASK) -/* For virtual address to physical address conversion */ -extern unsigned long mm_vtop(unsigned long addr) __attribute__ ((const)); -extern unsigned long mm_ptov(unsigned long addr) __attribute__ ((const)); -#define VTOP(addr) (mm_vtop((unsigned long)(addr))) -#define PTOV(addr) (mm_ptov((unsigned long)(addr))) - /* * Conversion functions: convert a page and protection to a page entry, * and a page entry and page directory to the page they refer to. @@ -393,19 +561,17 @@ * if any. */ -extern inline void nocache_page (unsigned long vaddr) +/* Prior to calling these routines, the page should have been flushed + * from both the cache and ATC, or the CPU might not notice that the + * cache setting for the page has been changed. -jskov + */ +static inline void nocache_page (unsigned long vaddr) { if (CPU_IS_040_OR_060) { pgd_t *dir; pmd_t *pmdp; pte_t *ptep; - if(CPU_IS_060) - __asm__ __volatile__ (".chip 68060\n\t" - "cpushp (%0)\n\t" - ".chip 68k" - : : "a" (VTOP(vaddr))); - dir = pgd_offset_k(vaddr); pmdp = pmd_offset(dir,vaddr); ptep = pte_offset(pmdp,vaddr); @@ -447,6 +613,8 @@ if (pmd_none(*pmd)) { if (page) { memset((void *) page, 0, PAGE_SIZE); + flush_page_to_ram((unsigned long)page); + flush_tlb_kernel_page((unsigned long)page); nocache_page((unsigned long)page); pmd_set(pmd,page); return page + address; @@ -510,6 +678,7 @@ pte_t * page = (pte_t *) get_free_page(GFP_KERNEL); if (pmd_none(*pmd)) { if (page) { + flush_tlb_kernel_page((unsigned long)page); nocache_page((unsigned long)page); pmd_set(pmd, page); return page + address; @@ -563,160 +732,6 @@ extern inline pgd_t * pgd_alloc(void) { return (pgd_t *)get_pointer_table (); -} - -#define flush_icache() \ -do { \ - if (CPU_IS_040_OR_060) \ - asm __volatile__ ("nop\n\t" \ - ".chip 68040\n\t" \ - "cinva %%ic\n\t" \ - ".chip 68k"); \ - else { \ - unsigned long _tmp; \ - asm __volatile__ ("movec %%cacr,%0\n\t" \ - "orw %1,%0\n\t" \ - "movec %0,%%cacr" \ - : "=&d" (_tmp) \ - : "id" (FLUSH_I)); \ - } \ -} while (0) - -/* - * invalidate the cache for the specified memory range. - * It starts at the physical address specified for - * the given number of bytes. - */ -extern void cache_clear (unsigned long paddr, int len); -/* - * push any dirty cache in the specified memory range. - * It starts at the physical address specified for - * the given number of bytes. - */ -extern void cache_push (unsigned long paddr, int len); - -/* - * push and invalidate pages in the specified user virtual - * memory range. - */ -extern void cache_push_v (unsigned long vaddr, int len); - -/* cache code */ -#define FLUSH_I_AND_D (0x00000808) -#define FLUSH_I (0x00000008) - -/* This is needed whenever the virtual mapping of the current - process changes. */ -#define __flush_cache_all() \ - do { \ - if (CPU_IS_040_OR_060) \ - __asm__ __volatile__ ("nop\n\t" \ - ".chip 68040\n\t" \ - "cpusha %dc\n\t" \ - ".chip 68k"); \ - else { \ - unsigned long _tmp; \ - __asm__ __volatile__ ("movec %%cacr,%0\n\t" \ - "orw %1,%0\n\t" \ - "movec %0,%%cacr" \ - : "=&d" (_tmp) \ - : "di" (FLUSH_I_AND_D)); \ - } \ - } while (0) - -#define __flush_cache_030() \ - do { \ - if (CPU_IS_020_OR_030) { \ - unsigned long _tmp; \ - __asm__ __volatile__ ("movec %%cacr,%0\n\t" \ - "orw %1,%0\n\t" \ - "movec %0,%%cacr" \ - : "=&d" (_tmp) \ - : "di" (FLUSH_I_AND_D)); \ - } \ - } while (0) - -#define flush_cache_all() __flush_cache_all() - -extern inline void flush_cache_mm(struct mm_struct *mm) -{ -#if FLUSH_VIRTUAL_CACHE_040 - if (mm == current->mm) __flush_cache_all(); -#else - if (mm == current->mm) __flush_cache_030(); -#endif -} - -extern inline void flush_cache_range(struct mm_struct *mm, - unsigned long start, - unsigned long end) -{ - if (mm == current->mm){ -#if FLUSH_VIRTUAL_CACHE_040 - if (CPU_IS_040_OR_060) - cache_push_v(start, end-start); - else -#endif - __flush_cache_030(); - } -} - -extern inline void flush_cache_page(struct vm_area_struct *vma, - unsigned long vmaddr) -{ - if (vma->vm_mm == current->mm){ -#if FLUSH_VIRTUAL_CACHE_040 - if (CPU_IS_040_OR_060) - cache_push_v(vmaddr, PAGE_SIZE); - else -#endif - __flush_cache_030(); - } -} - -/* Push the page at kernel virtual address and clear the icache */ -extern inline void flush_page_to_ram (unsigned long address) -{ - if (CPU_IS_040_OR_060) { - __asm__ __volatile__ ("nop\n\t" - ".chip 68040\n\t" - "cpushp %%dc,(%0)\n\t" - "cinvp %%ic,(%0)\n\t" - ".chip 68k" - : : "a" (VTOP(address))); - } - else { - unsigned long _tmp; - __asm volatile ("movec %%cacr,%0\n\t" - "orw %1,%0\n\t" - "movec %0,%%cacr" - : "=&d" (_tmp) - : "di" (FLUSH_I)); - } -} - -/* Push n pages at kernel virtual address and clear the icache */ -extern inline void flush_pages_to_ram (unsigned long address, int n) -{ - if (CPU_IS_040_OR_060) { - while (n--) { - __asm__ __volatile__ ("nop\n\t" - ".chip 68040\n\t" - "cpushp %%dc,(%0)\n\t" - "cinvp %%ic,(%0)\n\t" - ".chip 68k" - : : "a" (VTOP(address))); - address += PAGE_SIZE; - } - } - else { - unsigned long _tmp; - __asm volatile ("movec %%cacr,%0\n\t" - "orw %1,%0\n\t" - "movec %0,%%cacr" - : "=&d" (_tmp) - : "di" (FLUSH_I)); - } } /* Only in linux/include/asm-m68k: poll.h diff -u --recursive v2.1.35/linux/include/asm-m68k/processor.h linux/include/asm-m68k/processor.h --- v2.1.35/linux/include/asm-m68k/processor.h Sun Jan 26 02:07:46 1997 +++ linux/include/asm-m68k/processor.h Thu Apr 17 13:20:50 1997 @@ -8,6 +8,7 @@ #define __ASM_M68K_PROCESSOR_H #include +#include /* * User space process size: 3.75GB. This is hardcoded into a few places, @@ -18,16 +19,13 @@ /* This decides where the kernel will search for a free chunk of vm * space during mmap's. */ -#define TASK_UNMAPPED_BASE (TASK_SIZE / 3) +#define TASK_UNMAPPED_BASE 0xC0000000UL /* * Bus types */ #define EISA_bus 0 #define MCA_bus 0 - -/* MAX floating point unit state size (FSAVE/FRESTORE) */ -#define FPSTATESIZE (216/sizeof(unsigned char)) /* * if you change this structure, you must change the code and offsets diff -u --recursive v2.1.35/linux/include/asm-m68k/scatterlist.h linux/include/asm-m68k/scatterlist.h --- v2.1.35/linux/include/asm-m68k/scatterlist.h Mon Dec 30 03:01:10 1996 +++ linux/include/asm-m68k/scatterlist.h Thu Apr 17 13:20:50 1997 @@ -6,12 +6,9 @@ char * alt_address; /* Location of actual if address is a * dma indirect buffer. NULL otherwise */ unsigned int length; - -#ifdef __sparc__ - char * dvma_address; /* A place to hang host-specific addresses at. */ -#endif }; +/* This is bogus and should go away. */ #define ISA_DMA_THRESHOLD (0x00ffffff) #endif /* !(_M68K_SCATTERLIST_H) */ diff -u --recursive v2.1.35/linux/include/asm-m68k/semaphore.h linux/include/asm-m68k/semaphore.h --- v2.1.35/linux/include/asm-m68k/semaphore.h Mon Apr 14 16:28:19 1997 +++ linux/include/asm-m68k/semaphore.h Thu Apr 17 13:20:50 1997 @@ -2,6 +2,8 @@ #define _M68K_SEMAPHORE_H #include +#include +#include /* * SMP- and interrupt-safe semaphores.. @@ -12,21 +14,27 @@ */ struct semaphore { - int count; - int waiting; + atomic_t count; + atomic_t waking; struct wait_queue * wait; }; -#define MUTEX ((struct semaphore) { 1, 0, NULL }) -#define MUTEX_LOCKED ((struct semaphore) { 0, 0, NULL }) +#define MUTEX ((struct semaphore) { { 1 }, { 0 }, NULL }) +#define MUTEX_LOCKED ((struct semaphore) { { 0 }, { 0 }, NULL }) asmlinkage void __down_failed(void /* special register calling convention */); +asmlinkage int __down_failed_interruptible(void /* params in registers */); asmlinkage void __up_wakeup(void /* special register calling convention */); extern void __down(struct semaphore * sem); extern void __up(struct semaphore * sem); -#define sema_init(sem, val) ((sem)->count = val) +#define sema_init(sem, val) atomic_set(&((sem)->count), val) + +static inline void wake_one_more(struct semaphore * sem) +{ + atomic_inc(&sem->waking); +} static inline int waking_non_zero(struct semaphore *sem) { @@ -54,12 +62,34 @@ __asm__ __volatile__( "| atomic down operation\n\t" "lea %%pc@(1f),%%a0\n\t" - "subql #1,%0\n\t" + "subql #1,%0@\n\t" "jmi " SYMBOL_NAME_STR(__down_failed) "\n" "1:" : /* no outputs */ - : "m" (sem->count), "a" (sem1) + : "a" (sem1) : "%a0", "memory"); +} + +/* + * This version waits in interruptible state so that the waiting + * process can be killed. The down_failed_interruptible routine + * returns negative for signalled and zero for semaphore acquired. + */ +extern inline int down_interruptible(struct semaphore * sem) +{ + register int ret __asm__ ("%d0"); + register struct semaphore *sem1 __asm__ ("%a1") = sem; + __asm__ __volatile__( + "| atomic interruptible down operation\n\t" + "lea %%pc@(1f),%%a0\n\t" + "subql #1,%1@\n\t" + "jmi " SYMBOL_NAME_STR(__down_failed_interruptible) "\n\t" + "clrl %0\n" + "1:" + : "=d" (ret) + : "a" (sem1) + : "%d0", "%a0", "memory"); + return ret; } /* diff -u --recursive v2.1.35/linux/include/asm-m68k/serial.h linux/include/asm-m68k/serial.h --- v2.1.35/linux/include/asm-m68k/serial.h Fri Dec 20 01:20:03 1996 +++ linux/include/asm-m68k/serial.h Thu Apr 17 13:20:50 1997 @@ -171,7 +171,10 @@ */ struct serial_icounter_struct { int cts, dsr, rng, dcd; - int reserved[16]; + int rx, tx; + int frame, overrun, parity, brk; + int buf_overrun; + int reserved[9]; }; @@ -192,7 +195,9 @@ * Counters of the input lines (CTS, DSR, RI, CD) interrupts */ struct async_icount { - __u32 cts, dsr, rng, dcd; + __u32 cts, dsr, rng, dcd, tx, rx; + __u32 frame, parity, overrun, brk; + __u32 buf_overrun; }; struct async_struct { @@ -281,7 +286,7 @@ static __inline__ void rs_sched_event(struct async_struct *info, int event) { info->event |= 1 << event; - queue_task_irq(&info->tqueue, &tq_serial); + queue_task(&info->tqueue, &tq_serial); mark_bh(SERIAL_BH); } @@ -299,7 +304,8 @@ } *tty->flip.flag_buf_ptr++ = err; *tty->flip.char_buf_ptr++ = ch; - queue_task_irq(&tty->flip.tqueue, &tq_timer); + info->icount.rx++; + queue_task(&tty->flip.tqueue, &tq_timer); } static __inline__ int rs_get_tx_char( struct async_struct *info ) @@ -308,6 +314,7 @@ if (info->x_char) { ch = info->x_char; + info->icount.tx++; info->x_char = 0; return( ch ); } @@ -317,6 +324,7 @@ ch = info->xmit_buf[info->xmit_tail++]; info->xmit_tail &= SERIAL_XMIT_SIZE - 1; + info->icount.tx++; if (--info->xmit_cnt < WAKEUP_CHARS) rs_sched_event(info, RS_EVENT_WRITE_WAKEUP); return( ch ); @@ -348,8 +356,7 @@ #ifdef SERIAL_DEBUG_OPEN printk("scheduling hangup..."); #endif - queue_task_irq(&info->tqueue_hangup, - &tq_scheduler); + queue_task(&info->tqueue_hangup, &tq_scheduler); } } } diff -u --recursive v2.1.35/linux/include/asm-m68k/setup.h linux/include/asm-m68k/setup.h --- v2.1.35/linux/include/asm-m68k/setup.h Fri Dec 20 01:20:03 1996 +++ linux/include/asm-m68k/setup.h Thu Apr 17 13:20:50 1997 @@ -48,7 +48,7 @@ #elif defined(CONFIG_ATARI) || defined(CONFIG_MAC) # define MACH_IS_AMIGA (m68k_machtype == MACH_AMIGA) #else -# define CONFIG_AMIGA_ONLY +# define MACH_AMIGA_ONLY # define MACH_IS_AMIGA (1) # define MACH_TYPE (MACH_AMIGA) #endif @@ -58,7 +58,7 @@ #elif defined(CONFIG_AMIGA) || defined(CONFIG_MAC) # define MACH_IS_ATARI (m68k_machtype == MACH_ATARI) #else -# define CONFIG_ATARI_ONLY +# define MACH_ATARI_ONLY # define MACH_IS_ATARI (1) # define MACH_TYPE (MACH_ATARI) #endif @@ -149,7 +149,7 @@ #elif defined(CONFIG_M68030) || defined(CONFIG_M68040) || defined(CONFIG_M68060) # define CPU_IS_020 (m68k_cputype & CPU_68020) #else -# define CONFIG_M68020_ONLY +# define CPU_M68020_ONLY # define CPU_IS_020 (1) #endif @@ -158,7 +158,7 @@ #elif defined(CONFIG_M68020) || defined(CONFIG_M68040) || defined(CONFIG_M68060) # define CPU_IS_030 (m68k_cputype & CPU_68030) #else -# define CONFIG_M68030_ONLY +# define CPU_M68030_ONLY # define CPU_IS_030 (1) #endif @@ -167,7 +167,7 @@ #elif defined(CONFIG_M68020) || defined(CONFIG_M68030) || defined(CONFIG_M68060) # define CPU_IS_040 (m68k_cputype & CPU_68040) #else -# define CONFIG_M68040_ONLY +# define CPU_M68040_ONLY # define CPU_IS_040 (1) #endif @@ -176,18 +176,18 @@ #elif defined(CONFIG_M68020) || defined(CONFIG_M68030) || defined(CONFIG_M68040) # define CPU_IS_060 (m68k_cputype & CPU_68060) #else -# define CONFIG_M68060_ONLY +# define CPU_M68060_ONLY # define CPU_IS_060 (1) #endif #if !defined(CONFIG_M68020) && !defined(CONFIG_M68030) # define CPU_IS_020_OR_030 (0) #else -# define CONFIG_M68020_OR_M68030 +# define CPU_M68020_OR_M68030 # if defined(CONFIG_M68040) || defined(CONFIG_M68060) # define CPU_IS_020_OR_030 (!m68k_is040or060) # else -# define CONFIG_M68020_OR_M68030_ONLY +# define CPU_M68020_OR_M68030_ONLY # define CPU_IS_020_OR_030 (1) # endif #endif @@ -195,11 +195,11 @@ #if !defined(CONFIG_M68040) && !defined(CONFIG_M68060) # define CPU_IS_040_OR_060 (0) #else -# define CONFIG_M68040_OR_M68060 +# define CPU_M68040_OR_M68060 # if defined(CONFIG_M68020) || defined(CONFIG_M68030) # define CPU_IS_040_OR_060 (m68k_is040or060) # else -# define CONFIG_M68040_OR_M68060_ONLY +# define CPU_M68040_OR_M68060_ONLY # define CPU_IS_040_OR_060 (1) # endif #endif diff -u --recursive v2.1.35/linux/include/asm-m68k/sigcontext.h linux/include/asm-m68k/sigcontext.h --- v2.1.35/linux/include/asm-m68k/sigcontext.h Fri Nov 22 05:56:36 1996 +++ linux/include/asm-m68k/sigcontext.h Thu Apr 17 13:20:50 1997 @@ -1,6 +1,8 @@ #ifndef _ASM_M68k_SIGCONTEXT_H #define _ASM_M68k_SIGCONTEXT_H +#include + struct sigcontext { unsigned long sc_mask; /* old sigmask */ unsigned long sc_usp; /* old user stack pointer */ @@ -13,7 +15,7 @@ unsigned short sc_formatvec; unsigned long sc_fpregs[2*3]; /* room for two fp registers */ unsigned long sc_fpcntl[3]; - unsigned char sc_fpstate[216]; + unsigned char sc_fpstate[FPSTATESIZE]; }; #endif Only in linux/include/asm-m68k: smp_lock.h Only in linux/include/asm-m68k: softirq.h Only in linux/include/asm-m68k: spinlock.h diff -u --recursive v2.1.35/linux/include/asm-m68k/system.h linux/include/asm-m68k/system.h --- v2.1.35/linux/include/asm-m68k/system.h Wed Sep 25 00:47:42 1996 +++ linux/include/asm-m68k/system.h Thu Apr 17 13:20:50 1997 @@ -65,21 +65,24 @@ #if defined(CONFIG_ATARI) && !defined(CONFIG_AMIGA) && !defined(CONFIG_MAC) /* block out HSYNC on the atari */ -#define sti() __asm__ __volatile__ ("andiw #0xfbff,%/sr": : : "memory") +#define __sti() __asm__ __volatile__ ("andiw #0xfbff,%/sr": : : "memory") #else /* portable version */ -#define sti() __asm__ __volatile__ ("andiw #0xf8ff,%/sr": : : "memory") +#define __sti() __asm__ __volatile__ ("andiw #0xf8ff,%/sr": : : "memory") #endif /* machine compilation types */ -#define cli() __asm__ __volatile__ ("oriw #0x0700,%/sr": : : "memory") +#define __cli() __asm__ __volatile__ ("oriw #0x0700,%/sr": : : "memory") #define nop() __asm__ __volatile__ ("nop"::) #define mb() __asm__ __volatile__ ("" : : :"memory") -#define save_flags(x) \ +#define __save_flags(x) \ __asm__ __volatile__("movew %/sr,%0":"=d" (x) : /* no input */ :"memory") -#define restore_flags(x) \ +#define __restore_flags(x) \ __asm__ __volatile__("movew %0,%/sr": /* no outputs */ :"d" (x) : "memory") -#define iret() __asm__ __volatile__ ("rte": : :"memory", "sp", "cc") +#define cli() __cli() +#define sti() __sti() +#define save_flags(x) __save_flags(x) +#define restore_flags(x) __restore_flags(x) #ifndef CONFIG_RMW_INSNS static inline unsigned long __xchg(unsigned long x, volatile void * ptr, int size) diff -u --recursive v2.1.35/linux/include/asm-m68k/termbits.h linux/include/asm-m68k/termbits.h --- v2.1.35/linux/include/asm-m68k/termbits.h Wed May 8 00:32:41 1996 +++ linux/include/asm-m68k/termbits.h Thu Apr 17 13:20:50 1997 @@ -123,6 +123,7 @@ #define B230400 0010003 #define B460800 0010004 #define CIBAUD 002003600000 /* input baud rate (not used) */ +#define CMSPAR 010000000000 /* mark or space (stick) parity */ #define CRTSCTS 020000000000 /* flow control */ /* c_lflag bits */ diff -u --recursive v2.1.35/linux/include/asm-m68k/termios.h linux/include/asm-m68k/termios.h --- v2.1.35/linux/include/asm-m68k/termios.h Thu Mar 27 14:40:07 1997 +++ linux/include/asm-m68k/termios.h Thu Apr 17 13:20:50 1997 @@ -53,6 +53,7 @@ #define N_PPP 3 #define N_STRIP 4 #define N_AX25 5 +#define N_X25 6 /* X.25 async */ #ifdef __KERNEL__ diff -u --recursive v2.1.35/linux/include/asm-m68k/uaccess.h linux/include/asm-m68k/uaccess.h --- v2.1.35/linux/include/asm-m68k/uaccess.h Fri Jan 3 08:48:37 1997 +++ linux/include/asm-m68k/uaccess.h Thu Apr 17 13:20:50 1997 @@ -714,6 +714,9 @@ __constant_copy_to_user(to, from, n) : \ __generic_copy_to_user(to, from, n)) +#define __copy_from_user(to, from, n) copy_from_user(to, from, n) +#define __copy_to_user(to, from, n) copy_to_user(to, from, n) + /* * Copy a null terminated string from userspace. */ diff -u --recursive v2.1.35/linux/include/asm-m68k/unistd.h linux/include/asm-m68k/unistd.h --- v2.1.35/linux/include/asm-m68k/unistd.h Fri Apr 4 08:52:25 1997 +++ linux/include/asm-m68k/unistd.h Thu Apr 17 13:20:50 1997 @@ -171,7 +171,9 @@ #define __NR_mremap 163 #define __NR_setresuid 164 #define __NR_getresuid 165 -#define __NR_nfsservctl 166 +#define __NR_query_module 167 +#define __NR_poll 168 +#define __NR_nfsservctl 169 /* user-visible error numbers are in the range -1 - -122: see */ @@ -179,7 +181,10 @@ #define __syscall_return(type, res) \ do { \ if ((unsigned long)(res) >= (unsigned long)(-125)) { \ - errno = -(res); \ + /* avoid using res which is declared to be in register d0; \ + errno might expand to a function call and clobber it. */ \ + int __err = -(res); \ + errno = __err; \ res = -1; \ } \ return (type) (res); \ diff -u --recursive v2.1.35/linux/include/asm-m68k/user.h linux/include/asm-m68k/user.h --- v2.1.35/linux/include/asm-m68k/user.h Fri Nov 22 05:56:36 1996 +++ linux/include/asm-m68k/user.h Thu Apr 17 13:20:50 1997 @@ -2,7 +2,7 @@ #define _M68K_USER_H #include -#include + /* Core file format: The core file is written in such a way that gdb can understand it and provide useful information to the user (under linux we use the 'trad-core' bfd). There are quite a number of @@ -74,7 +74,8 @@ esp register. */ long int signal; /* Signal that caused the core dump. */ int reserved; /* No longer used */ - struct pt_regs * u_ar0; /* Used by gdb to help find the values for */ + struct user_regs_struct *u_ar0; + /* Used by gdb to help find the values for */ /* the registers. */ struct user_m68kfp_struct* u_fpstate; /* Math Co-processor pointer. */ unsigned long magic; /* To uniquely identify a core file */ Only in v2.1.35/linux/include/asm-m68k: zorro.h diff -u --recursive v2.1.35/linux/include/asm-ppc/atomic.h linux/include/asm-ppc/atomic.h --- v2.1.35/linux/include/asm-ppc/atomic.h Mon Apr 14 16:28:19 1997 +++ linux/include/asm-ppc/atomic.h Thu Apr 17 13:20:51 1997 @@ -6,7 +6,7 @@ #define _ASM_PPC_ATOMIC_H_ typedef struct { int counter; } atomic_t; -#define ATOMIC_INIT { 0 } +#define ATOMIC_INIT(i) { (i) } /* * Make sure gcc doesn't try to be clever and move things around diff -u --recursive v2.1.35/linux/include/asm-ppc/semaphore.h linux/include/asm-ppc/semaphore.h --- v2.1.35/linux/include/asm-ppc/semaphore.h Mon Apr 14 16:28:19 1997 +++ linux/include/asm-ppc/semaphore.h Thu Apr 17 13:20:51 1997 @@ -9,8 +9,8 @@ struct wait_queue * wait; }; -#define MUTEX ((struct semaphore) { 1, 0, NULL }) -#define MUTEX_LOCKED ((struct semaphore) { 0, 0, NULL }) +#define MUTEX ((struct semaphore) { ATOMIC_INIT(1), ATOMIC_INIT(0), NULL }) +#define MUTEX_LOCKED ((struct semaphore) { ATOMIC_INIT(0), ATOMIC_INIT(0), NULL }) extern void __down(struct semaphore * sem); extern void __up(struct semaphore * sem); diff -u --recursive v2.1.35/linux/include/asm-sparc/atomic.h linux/include/asm-sparc/atomic.h --- v2.1.35/linux/include/asm-sparc/atomic.h Mon Apr 14 16:28:19 1997 +++ linux/include/asm-sparc/atomic.h Thu Apr 17 13:20:51 1997 @@ -13,7 +13,7 @@ typedef struct { int counter; } atomic_t; #endif -#define ATOMIC_INIT { 0 } +#define ATOMIC_INIT(i) { (i << 8) } #ifdef __KERNEL__ #include diff -u --recursive v2.1.35/linux/include/asm-sparc/errno.h linux/include/asm-sparc/errno.h --- v2.1.35/linux/include/asm-sparc/errno.h Sat Nov 9 00:29:22 1996 +++ linux/include/asm-sparc/errno.h Tue Apr 15 21:47:24 1997 @@ -1,4 +1,4 @@ -/* $Id: errno.h,v 1.5 1996/07/13 02:05:13 tridge Exp $ */ +/* $Id: errno.h,v 1.6 1997/04/15 09:03:38 davem Exp $ */ #ifndef _SPARC_ERRNO_H #define _SPARC_ERRNO_H @@ -129,5 +129,8 @@ #define EILSEQ 122 /* Illegal byte sequence */ #define ELIBMAX 123 /* Atmpt to link in too many shared libs */ #define ELIBSCN 124 /* .lib section in a.out corrupted */ + +#define ENOMEDIUM 125 /* No medium found */ +#define EMEDIUMTYPE 126 /* Wrong medium type */ #endif diff -u --recursive v2.1.35/linux/include/asm-sparc/fbio.h linux/include/asm-sparc/fbio.h --- v2.1.35/linux/include/asm-sparc/fbio.h Sat Nov 9 00:29:23 1996 +++ linux/include/asm-sparc/fbio.h Thu Apr 17 13:20:51 1997 @@ -33,6 +33,9 @@ #define FBTYPE_LASTPLUSONE 21 /* This is not last + 1 in fact... */ +/* Does not seem to be listed in the Sun file either */ +#define FBTYPE_CREATOR 22 + /* fbio ioctls */ /* Returned by FBIOGTYPE */ struct fbtype { diff -u --recursive v2.1.35/linux/include/asm-sparc/init.h linux/include/asm-sparc/init.h --- v2.1.35/linux/include/asm-sparc/init.h Thu Mar 27 14:40:07 1997 +++ linux/include/asm-sparc/init.h Thu Apr 17 13:20:51 1997 @@ -1,8 +1,7 @@ #ifndef _SPARC_INIT_H #define _SPARC_INIT_H -#ifndef __init -#if (defined (__svr4__) || defined (__ELF__)) && !defined (MODULE) +#if (defined (__svr4__) || defined (__ELF__)) #define __init __attribute__ ((__section__ (".text.init"))) #define __initdata __attribute__ ((__section__ (".data.init"))) #define __initfunc(__arginit) \ @@ -20,7 +19,6 @@ #define __INIT #define __FINIT #define __INITDATA -#endif #endif #endif diff -u --recursive v2.1.35/linux/include/asm-sparc/irq.h linux/include/asm-sparc/irq.h --- v2.1.35/linux/include/asm-sparc/irq.h Mon Apr 14 16:28:20 1997 +++ linux/include/asm-sparc/irq.h Tue Apr 15 21:47:24 1997 @@ -1,4 +1,4 @@ -/* $Id: irq.h,v 1.15 1997/04/14 05:39:28 davem Exp $ +/* $Id: irq.h,v 1.16 1997/04/15 09:03:40 davem Exp $ * irq.h: IRQ registers on the Sparc. * * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) @@ -22,9 +22,9 @@ extern void (*enable_irq)(unsigned int); extern void (*disable_pil_irq)(unsigned int); extern void (*enable_pil_irq)(unsigned int); -extern void (*clear_clock_irq)( void ); -extern void (*clear_profile_irq)( void ); -extern void (*load_profile_irq)( unsigned int timeout ); +extern void (*clear_clock_irq)(void); +extern void (*clear_profile_irq)(int); +extern void (*load_profile_irq)(int cpu, unsigned int timeout); extern void (*init_timers)(void (*lvl10_irq)(int, void *, struct pt_regs *)); extern void claim_ticker14(void (*irq_handler)(int, void *, struct pt_regs *), int irq, Only in linux/include/asm-sparc: linux_logo.h diff -u --recursive v2.1.35/linux/include/asm-sparc/pgtable.h linux/include/asm-sparc/pgtable.h --- v2.1.35/linux/include/asm-sparc/pgtable.h Mon Apr 14 16:28:21 1997 +++ linux/include/asm-sparc/pgtable.h Tue Apr 15 21:47:24 1997 @@ -1,4 +1,4 @@ -/* $Id: pgtable.h,v 1.59 1997/04/10 05:13:23 davem Exp $ */ +/* $Id: pgtable.h,v 1.60 1997/04/14 17:05:16 jj Exp $ */ #ifndef _SPARC_PGTABLE_H #define _SPARC_PGTABLE_H @@ -367,5 +367,31 @@ } #define add_to_free_ctxlist(entry) add_to_ctx_list(&ctx_free, entry) #define add_to_used_ctxlist(entry) add_to_ctx_list(&ctx_used, entry) + +extern __inline__ unsigned int +__get_phys (unsigned long addr) +{ + switch (sparc_cpu_model){ + case sun4c: + return sun4c_get_pte (addr) << PAGE_SHIFT; + case sun4m: + return ((srmmu_get_pte (addr) & 0xffffff00) << 4); + default: + return 0; + } +} + +extern __inline__ int +__get_iospace (unsigned long addr) +{ + switch (sparc_cpu_model){ + case sun4c: + return -1; /* Don't check iospace on sun4c */ + case sun4m: + return (srmmu_get_pte (addr) >> 28); + default: + return -1; + } +} #endif /* !(_SPARC_PGTABLE_H) */ diff -u --recursive v2.1.35/linux/include/asm-sparc/semaphore.h linux/include/asm-sparc/semaphore.h --- v2.1.35/linux/include/asm-sparc/semaphore.h Mon Apr 14 16:28:21 1997 +++ linux/include/asm-sparc/semaphore.h Thu Apr 17 13:20:51 1997 @@ -13,8 +13,8 @@ struct wait_queue * wait; }; -#define MUTEX ((struct semaphore) { { (1 << 8) }, { 0 }, NULL }) -#define MUTEX_LOCKED ((struct semaphore) { { 0 }, { 0 }, NULL }) +#define MUTEX ((struct semaphore) { ATOMIC_INIT(1), ATOMIC_INIT(0), NULL }) +#define MUTEX_LOCKED ((struct semaphore) { ATOMIC_INIT(0), ATOMIC_INIT(0), NULL }) extern void __down(struct semaphore * sem); extern int __down_interruptible(struct semaphore * sem); @@ -22,6 +22,12 @@ #define sema_init(sem, val) atomic_set(&((sem)->count), val) +#define wake_one_more(sem) atomic_inc(&sem->waking); + +/* XXX Put this in raw assembler for SMP case so that the atomic_t + * XXX spinlock can allow this to be done without grabbing the IRQ + * XXX global lock. + */ static inline int waking_non_zero(struct semaphore *sem) { unsigned long flags; diff -u --recursive v2.1.35/linux/include/asm-sparc/smp.h linux/include/asm-sparc/smp.h --- v2.1.35/linux/include/asm-sparc/smp.h Mon Apr 14 16:28:21 1997 +++ linux/include/asm-sparc/smp.h Tue Apr 15 21:47:24 1997 @@ -96,48 +96,6 @@ return cpuid; } -extern __volatile__ int smp_process_available; - -extern __inline__ int smp_swap(volatile int *addr, int value) -{ - __asm__ __volatile__("swap [%2], %0\n\t" : - "=&r" (value) : - "0" (value), "r" (addr)); - return value; -} - -extern __inline__ __volatile__ void inc_smp_counter(volatile int *ctr) -{ - int tmp; - - while((tmp = smp_swap(ctr, -1)) == -1) - while(*ctr == -1) - ; - - *ctr = (tmp + 1); -} - -extern __inline__ __volatile__ void dec_smp_counter(volatile int *ctr) -{ - int tmp; - - while((tmp = smp_swap(ctr, -1)) == -1) - while(*ctr == -1) - ; - - *ctr = (tmp - 1); -} - -extern __inline__ __volatile__ int read_smp_counter(volatile int *ctr) -{ - int value; - - while((value = *ctr) == -1) - ; - - return value; -} - #endif /* !(__ASSEMBLY__) */ /* Sparc specific messages. */ @@ -154,13 +112,13 @@ #define MBOX_IDLECPU2 0xFD #define MBOX_STOPCPU2 0xFE -#define NO_PROC_ID 0xFF - #define PROC_CHANGE_PENALTY 20 #define SMP_FROM_INT 1 #define SMP_FROM_SYSCALL 2 #endif /* !(__SMP__) */ + +#define NO_PROC_ID 0xFF #endif /* !(_SPARC_SMP_H) */ diff -u --recursive v2.1.35/linux/include/asm-sparc/smp_lock.h linux/include/asm-sparc/smp_lock.h --- v2.1.35/linux/include/asm-sparc/smp_lock.h Mon Apr 14 16:28:21 1997 +++ linux/include/asm-sparc/smp_lock.h Thu Apr 17 09:24:32 1997 @@ -14,7 +14,7 @@ #define lock_kernel() do { } while(0) #define unlock_kernel() do { } while(0) #define release_kernel_lock(task, cpu, depth) ((depth) = 1) -#define reaquire_kernel_lock(task, cpu, depth) do { } while(0) +#define reacquire_kernel_lock(task, cpu, depth) do { } while(0) #else @@ -34,7 +34,7 @@ } while(0) /* Do not fuck with this without consulting arch/sparc/lib/locks.S first! */ -#define reaquire_kernel_lock(task, cpu, depth) \ +#define reacquire_kernel_lock(task, cpu, depth) \ do { \ if(depth) { \ register struct klock_info *klip asm("g1"); \ @@ -42,7 +42,7 @@ klip = &klock_info; \ proc = cpu; \ __asm__ __volatile__("mov %%o7, %%g4\n\t" \ - "call ___lock_reaquire_kernel\n\t" \ + "call ___lock_reacquire_kernel\n\t" \ " mov %2, %%g2" \ : /* No outputs. */ \ : "r" (klip), "r" (proc), "r" (depth) \ diff -u --recursive v2.1.35/linux/include/asm-sparc/spinlock.h linux/include/asm-sparc/spinlock.h --- v2.1.35/linux/include/asm-sparc/spinlock.h Mon Apr 14 16:28:21 1997 +++ linux/include/asm-sparc/spinlock.h Thu Apr 17 13:20:51 1997 @@ -23,6 +23,33 @@ #define spin_lock_irqsave(lock, flags) save_and_cli(flags) #define spin_unlock_irqrestore(lock, flags) restore_flags(flags) +/* + * Read-write spinlocks, allowing multiple readers + * but only one writer. + * + * NOTE! it is quite common to have readers in interrupts + * but no interrupt writers. For those circumstances we + * can "mix" irq-safe locks - any writer needs to get a + * irq-safe write-lock, but readers can get non-irqsafe + * read-locks. + */ +typedef struct { } rwlock_t; +#define RW_LOCK_UNLOCKED { } + +#define read_lock(lock) do { } while(0) +#define read_unlock(lock) do { } while(0) +#define write_lock(lock) do { } while(0) +#define write_unlock(lock) do { } while(0) +#define read_lock_irq(lock) cli() +#define read_unlock_irq(lock) sti() +#define write_lock_irq(lock) cli() +#define write_unlock_irq(lock) sti() + +#define read_lock_irqsave(lock, flags) save_and_cli(flags) +#define read_unlock_irqrestore(lock, flags) restore_flags(flags) +#define write_lock_irqsave(lock, flags) save_and_cli(flags) +#define write_unlock_irqrestore(lock, flags) restore_flags(flags) + #else /* !(__SMP__) */ #include @@ -30,6 +57,8 @@ typedef unsigned char spinlock_t; #define SPIN_LOCK_UNLOCKED 0 +#define spin_lock_init(lock) (*(lock) = 0) + extern __inline__ void spin_lock(spinlock_t *lock) { register spinlock_t *lp asm("g1"); @@ -124,6 +153,92 @@ : "r" (lock), "r" (flags) : "memory", "cc"); } + +/* Read-write spinlocks, allowing multiple readers + * but only one writer. + * + * NOTE! it is quite common to have readers in interrupts + * but no interrupt writers. For those circumstances we + * can "mix" irq-safe locks - any writer needs to get a + * irq-safe write-lock, but readers can get non-irqsafe + * read-locks. + * + * XXX This might create some problems with my dual spinlock + * XXX scheme, deadlocks etc. -DaveM + */ +typedef struct { volatile unsigned int lock; } rwlock_t; + +#define RW_LOCK_UNLOCKED { 0 } + +/* Sort of like atomic_t's on Sparc, but even more clever. + * + * ------------------------------------ + * | 16-bit counter | clock | wlock | rwlock_t + * ------------------------------------ + * 31 16 15 8 7 0 + * + * wlock signifies the one writer is in, the clock protects + * counter bumping, however a reader must acquire wlock + * before he can bump the counter on a read_lock(). + * Similarly a writer, once he has the wlock, must await + * for the top 24 bits to all clear before he can finish + * going in (this includes the clock of course). + * + * Unfortunately this scheme limits us to ~65,000 cpus. + */ +extern __inline__ void read_lock(rwlock_t *rw) +{ + register rwlock_t *lp asm("g1"); + lp = rw; + __asm__ __volatile__(" + mov %%o7, %%g4 + call ___rw_read_enter + ldstub [%%g1 + 3], %%g2 +" : /* no outputs */ + : "r" (lp) + : "g2", "g4", "g7", "memory", "cc"); +} + +extern __inline__ void read_unlock(rwlock_t *rw) +{ + register rwlock_t *lp asm("g1"); + lp = rw; + __asm__ __volatile__(" + mov %%o7, %%g4 + call ___rw_read_exit + ldstub [%%g1 + 2], %%g2 +" : /* no outputs */ + : "r" (lp) + : "g2", "g4", "g7", "memory", "cc"); +} + +extern __inline__ void write_lock(rwlock_t *rw) +{ + register rwlock_t *lp asm("g1"); + lp = rw; + __asm__ __volatile__(" + mov %%o7, %%g4 + call ___rw_write_enter + ldstub [%%g1 + 3], %%g2 +" : /* no outputs */ + : "r" (lp) + : "g2", "g4", "g7", "memory", "cc"); +} + +#define write_unlock(rw) do { (rw)->lock = 0; } while(0) +#define read_lock_irq(lock) do { __cli(); read_lock(lock); } while (0) +#define read_unlock_irq(lock) do { read_unlock(lock); __sti(); } while (0) +#define write_lock_irq(lock) do { __cli(); write_lock(lock); } while (0) +#define write_unlock_irq(lock) do { write_unlock(lock); __sti(); } while (0) + +#define read_lock_irqsave(lock, flags) \ + do { __save_and_cli(flags); read_lock(lock); } while (0) +#define read_unlock_irqrestore(lock, flags) \ + do { read_unlock(lock); __restore_flags(flags); } while (0) +#define write_lock_irqsave(lock, flags) \ + do { __save_and_cli(flags); write_lock(lock); } while (0) +#define write_unlock_irqrestore(lock, flags) \ + do { write_unlock(lock); __restore_flags(flags); } while (0) #endif /* __SMP__ */ diff -u --recursive v2.1.35/linux/include/asm-sparc/system.h linux/include/asm-sparc/system.h --- v2.1.35/linux/include/asm-sparc/system.h Mon Apr 14 16:28:21 1997 +++ linux/include/asm-sparc/system.h Tue Apr 15 21:47:24 1997 @@ -1,4 +1,4 @@ -/* $Id: system.h,v 1.56 1997/04/14 05:39:30 davem Exp $ */ +/* $Id: system.h,v 1.57 1997/04/15 09:03:45 davem Exp $ */ #ifndef __SPARC_SYSTEM_H #define __SPARC_SYSTEM_H @@ -93,9 +93,7 @@ "rd %%wim, %%g5\n\t" \ "wr %%g4, 0x20, %%psr\n\t" \ "nop\n\t" \ - "mov %5, %%g7\n\t" \ "std %%g4, [%%g6 + %2]\n\t" \ - "st %%g7, [%%g6 + %6]\n\t" \ "ldd [%1 + %2], %%g4\n\t" \ "mov %1, %%g6\n\t" \ "st %1, [%0]\n\t" \ @@ -113,8 +111,7 @@ " nop\n\t" : : "r" (&(current_set[smp_processor_id()])), "r" (next), \ "i" ((const unsigned long)(&((struct task_struct *)0)->tss.kpsr)), \ "i" ((const unsigned long)(&((struct task_struct *)0)->tss.ksp)), \ - "r" (task_pc), "i" (255), \ - "i" ((const unsigned long)(&((struct task_struct *)0)->processor)) \ + "r" (task_pc) \ : "g1", "g2", "g3", "g4", "g5", "g7", "l2", "l3", \ "l4", "l5", "l6", "l7", "i0", "i1", "i2", "i3", "i4", "i5", "o0", "o1", "o2", \ "o3"); \ diff -u --recursive v2.1.35/linux/include/asm-sparc64/atomic.h linux/include/asm-sparc64/atomic.h --- v2.1.35/linux/include/asm-sparc64/atomic.h Mon Apr 14 16:28:22 1997 +++ linux/include/asm-sparc64/atomic.h Thu Apr 17 13:20:51 1997 @@ -1,4 +1,4 @@ -/* $Id: atomic.h,v 1.13 1997/04/14 06:56:57 davem Exp $ +/* $Id: atomic.h,v 1.14 1997/04/16 05:57:06 davem Exp $ * atomic.h: Thankfully the V9 is at least reasonable for this * stuff. * @@ -15,7 +15,7 @@ #define __atomic_fool_gcc(x) ((struct { int a[100]; } *)x) typedef struct { int counter; } atomic_t; -#define ATOMIC_INIT { 0 } +#define ATOMIC_INIT(i) { (i) } #define atomic_read(v) ((v)->counter) #define atomic_set(v, i) (((v)->counter) = i) diff -u --recursive v2.1.35/linux/include/asm-sparc64/errno.h linux/include/asm-sparc64/errno.h --- v2.1.35/linux/include/asm-sparc64/errno.h Fri Dec 13 01:37:41 1996 +++ linux/include/asm-sparc64/errno.h Tue Apr 15 21:47:24 1997 @@ -1,4 +1,4 @@ -/* $Id: errno.h,v 1.1 1996/11/20 15:27:39 davem Exp $ */ +/* $Id: errno.h,v 1.2 1997/04/15 12:46:11 jj Exp $ */ #ifndef _SPARC64_ERRNO_H #define _SPARC64_ERRNO_H @@ -129,5 +129,8 @@ #define EILSEQ 122 /* Illegal byte sequence */ #define ELIBMAX 123 /* Atmpt to link in too many shared libs */ #define ELIBSCN 124 /* .lib section in a.out corrupted */ + +#define ENOMEDIUM 125 /* No medium found */ +#define EMEDIUMTYPE 126 /* Wrong medium type */ #endif /* !(_SPARC64_ERRNO_H) */ diff -u --recursive v2.1.35/linux/include/asm-sparc64/fbio.h linux/include/asm-sparc64/fbio.h --- v2.1.35/linux/include/asm-sparc64/fbio.h Mon Apr 14 16:28:22 1997 +++ linux/include/asm-sparc64/fbio.h Thu Apr 17 13:20:51 1997 @@ -33,6 +33,9 @@ #define FBTYPE_LASTPLUSONE 21 /* This is not last + 1 in fact... */ +/* Does not seem to be listed in the Sun file either */ +#define FBTYPE_CREATOR 22 + /* fbio ioctls */ /* Returned by FBIOGTYPE */ struct fbtype { diff -u --recursive v2.1.35/linux/include/asm-sparc64/fcntl.h linux/include/asm-sparc64/fcntl.h --- v2.1.35/linux/include/asm-sparc64/fcntl.h Mon Apr 14 16:28:22 1997 +++ linux/include/asm-sparc64/fcntl.h Tue Apr 15 21:47:24 1997 @@ -1,4 +1,4 @@ -/* $Id: fcntl.h,v 1.2 1997/04/04 00:50:15 davem Exp $ */ +/* $Id: fcntl.h,v 1.3 1997/04/14 17:05:20 jj Exp $ */ #ifndef _SPARC64_FCNTL_H #define _SPARC64_FCNTL_H @@ -48,7 +48,6 @@ blocking */ #define LOCK_UN 8 /* remove lock */ -/* XXX 32-bit binary compatability item... -DaveM */ struct flock { short l_type; short l_whence; @@ -57,5 +56,16 @@ pid_t l_pid; short __unused; }; + +#ifdef __KERNEL__ +struct flock32 { + short l_type; + short l_whence; + __kernel_off_t32 l_start; + __kernel_off_t32 l_len; + __kernel_pid_t32 l_pid; + short __unused; +}; +#endif #endif /* !(_SPARC64_FCNTL_H) */ diff -u --recursive v2.1.35/linux/include/asm-sparc64/init.h linux/include/asm-sparc64/init.h --- v2.1.35/linux/include/asm-sparc64/init.h Thu Mar 27 14:40:09 1997 +++ linux/include/asm-sparc64/init.h Thu Apr 17 13:20:51 1997 @@ -1,9 +1,6 @@ -#ifndef _SPARC64_INIT_H -#define _SPARC64_INIT_H +#ifndef _SPARC_INIT_H +#define _SPARC_INIT_H -#ifndef __init -/* 'cause of buggy linker, we don't use this for now... */ -#if 0 && !defined (MODULE) #define __init __attribute__ ((__section__ (".text.init"))) #define __initdata __attribute__ ((__section__ (".data.init"))) #define __initfunc(__arginit) \ @@ -13,15 +10,5 @@ #define __INIT .section ".text.init",#alloc,#execinstr #define __FINIT .previous #define __INITDATA .section ".data.init",#alloc,#write -#else -#define __init -#define __initdata -#define __initfunc(__arginit) __arginit -/* For assembly routines */ -#define __INIT -#define __FINIT -#define __INITDATA -#endif -#endif #endif diff -u --recursive v2.1.35/linux/include/asm-sparc64/ipc.h linux/include/asm-sparc64/ipc.h --- v2.1.35/linux/include/asm-sparc64/ipc.h Mon Apr 14 16:28:22 1997 +++ linux/include/asm-sparc64/ipc.h Tue Apr 15 21:47:24 1997 @@ -4,12 +4,11 @@ /* * These are used to wrap system calls on the sparc. * - * See arch/sparc64/kernel/sys_sparc.c for ugly details.. + * See arch/sparc64/kernel/sys_sparc32.c for ugly details.. */ -/* XXX 32-bit binary compatability... */ struct ipc_kludge { - struct msgbuf *msgp; - long msgtyp; + u32 msgp; + s32 msgtyp; }; #define SEMOP 1 @@ -24,6 +23,7 @@ #define SHMGET 23 #define SHMCTL 24 -#define IPCCALL(version,op) ((version)<<16 | (op)) +/* We don't need to maintain backward compatibility on 64bit, we've started fresh */ +#define IPCCALL(version,op) (op) #endif Only in linux/include/asm-sparc64: linux_logo.h diff -u --recursive v2.1.35/linux/include/asm-sparc64/pgtable.h linux/include/asm-sparc64/pgtable.h --- v2.1.35/linux/include/asm-sparc64/pgtable.h Mon Apr 14 16:28:23 1997 +++ linux/include/asm-sparc64/pgtable.h Tue Apr 15 21:47:24 1997 @@ -1,4 +1,4 @@ -/* $Id: pgtable.h,v 1.27 1997/04/10 23:32:46 davem Exp $ +/* $Id: pgtable.h,v 1.28 1997/04/14 17:05:19 jj Exp $ * pgtable.h: SpitFire page table operations. * * Copyright 1996 David S. Miller (davem@caip.rutgers.edu) @@ -672,6 +672,31 @@ #define SWP_TYPE(entry) (((entry>>PAGE_SHIFT) & 0xff)) #define SWP_OFFSET(entry) ((entry) >> (PAGE_SHIFT+8)) #define SWP_ENTRY(type,offset) pte_val(mk_swap_pte((type),(offset))) + +extern __inline__ unsigned long +sun4u_get_pte (unsigned long addr) +{ + pgd_t *pgdp; + pmd_t *pmdp; + pte_t *ptep; + + pgdp = pgd_offset (current->mm, addr); + pmdp = pmd_offset (pgdp, addr); + ptep = pte_offset (pmdp, addr); + return pte_val (*ptep) & _PAGE_PADDR; +} + +extern __inline__ unsigned int +__get_phys (unsigned long addr) +{ + return (sun4u_get_pte (addr) & 0x0fffffff); +} + +extern __inline__ int +__get_iospace (unsigned long addr) +{ + return ((sun4u_get_pte (addr) & 0xf0000000) >> 28); +} #endif /* !(__ASSEMBLY__) */ diff -u --recursive v2.1.35/linux/include/asm-sparc64/posix_types.h linux/include/asm-sparc64/posix_types.h --- v2.1.35/linux/include/asm-sparc64/posix_types.h Mon Apr 14 16:28:23 1997 +++ linux/include/asm-sparc64/posix_types.h Tue Apr 15 21:47:24 1997 @@ -34,6 +34,27 @@ int val[2]; } __kernel_fsid_t; +/* Now 32bit compatibility types */ +typedef unsigned int __kernel_size_t32; +typedef int __kernel_ssize_t32; +typedef int __kernel_ptrdiff_t32; +typedef int __kernel_time_t32; +typedef int __kernel_clock_t32; +typedef int __kernel_pid_t32; +typedef unsigned short __kernel_ipc_pid_t32; +typedef unsigned short __kernel_uid_t32; +typedef unsigned short __kernel_gid_t32; +typedef unsigned short __kernel_dev_t32; +typedef unsigned int __kernel_ino_t32; +typedef unsigned short __kernel_mode_t32; +typedef unsigned short __kernel_umode_t32; +typedef short __kernel_nlink_t32; +typedef int __kernel_daddr_t32; +typedef int __kernel_off_t32; +typedef unsigned int __kernel_caddr_t32; +typedef long __kernel_loff_t32; +typedef __kernel_fsid_t __kernel_fsid_t32; + #undef __FD_SET static __inline__ void __FD_SET(unsigned long fd, __kernel_fd_set *fdsetp) { diff -u --recursive v2.1.35/linux/include/asm-sparc64/processor.h linux/include/asm-sparc64/processor.h --- v2.1.35/linux/include/asm-sparc64/processor.h Mon Apr 14 16:28:23 1997 +++ linux/include/asm-sparc64/processor.h Tue Apr 15 21:47:24 1997 @@ -1,4 +1,4 @@ -/* $Id: processor.h,v 1.20 1997/04/11 22:34:54 davem Exp $ +/* $Id: processor.h,v 1.21 1997/04/14 17:05:18 jj Exp $ * include/asm-sparc64/processor.h * * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu) @@ -132,6 +132,7 @@ "stx %%g0, [%0 + %2 + 0x68]\n\t" \ "stx %1, [%0 + %2 + 0x70]\n\t" \ "stx %%g0, [%0 + %2 + 0x78]\n\t" \ + "wrpr %%g0, 1, %%wstate\n\t" \ : \ : "r" (regs), "r" (sp - REGWIN_SZ), \ "i" ((const unsigned long)(&((struct pt_regs *)0)->u_regs[0]))); \ @@ -167,6 +168,7 @@ "stx %%g0, [%0 + %2 + 0x68]\n\t" \ "stx %1, [%0 + %2 + 0x70]\n\t" \ "stx %%g0, [%0 + %2 + 0x78]\n\t" \ + "wrpr %%g0, 2, %%wstate\n\t" \ : \ : "r" (regs), "r" (sp - REGWIN32_SZ), \ "i" ((const unsigned long)(&((struct pt_regs *)0)->u_regs[0])), \ diff -u --recursive v2.1.35/linux/include/asm-sparc64/semaphore.h linux/include/asm-sparc64/semaphore.h --- v2.1.35/linux/include/asm-sparc64/semaphore.h Mon Apr 14 16:28:24 1997 +++ linux/include/asm-sparc64/semaphore.h Thu Apr 17 13:20:51 1997 @@ -2,8 +2,10 @@ #define _SPARC64_SEMAPHORE_H /* These are actually reasonable on the V9. */ +#ifdef __KERNEL__ #include +#include struct semaphore { atomic_t count; @@ -11,8 +13,8 @@ struct wait_queue * wait; }; -#define MUTEX ((struct semaphore) { { 1 }, { 0 }, NULL }) -#define MUTEX_LOCKED ((struct semaphore) { { 0 }, { 0 }, NULL }) +#define MUTEX ((struct semaphore) { ATOMIC_INIT(1), ATOMIC_INIT(0), NULL }) +#define MUTEX_LOCKED ((struct semaphore) { ATOMIC_INIT(0), ATOMIC_INIT(0), NULL }) extern void __down(struct semaphore * sem); extern int __down_interruptible(struct semaphore * sem); @@ -20,6 +22,23 @@ #define sema_init(sem, val) atomic_set(&((sem)->count), val) +#define wake_one_more(sem) atomic_inc(&sem->waking); + +extern __inline__ int waking_non_zero(struct semaphore *sem) +{ + unsigned long flags; + int ret = 0; + + save_flags(flags); + cli(); + if (atomic_read(&sem->waking) > 0) { + atomic_dec(&sem->waking); + ret = 1; + } + restore_flags(flags); + return ret; +} + extern __inline__ void down(struct semaphore * sem) { if (atomic_dec_return(&sem->count) < 0) @@ -39,5 +58,7 @@ if (atomic_inc_return(&sem->count) <= 0) __up(sem); } + +#endif /* __KERNEL__ */ #endif /* !(_SPARC64_SEMAPHORE_H) */ diff -u --recursive v2.1.35/linux/include/asm-sparc64/smp.h linux/include/asm-sparc64/smp.h --- v2.1.35/linux/include/asm-sparc64/smp.h Mon Apr 14 16:28:24 1997 +++ linux/include/asm-sparc64/smp.h Tue Apr 15 21:47:24 1997 @@ -106,51 +106,6 @@ extern __volatile__ unsigned long smp_proc_in_lock[NR_CPUS]; /* for computing process time */ -extern __volatile__ int smp_process_available; - -extern __inline__ __volatile__ void inc_smp_counter(volatile int *ctr) -{ - unsigned long temp0, temp1; - - __asm__ __volatile__(" - lduw [%2], %0 -1: - add %0, 1, %1 - cas [%2], %0, %1 - cmp %0, %1 - bne,a,pn %%icc, 1b - lduw [%2], %0 -2: - membar #StoreStore | #StoreLoad -" : "=&r" (temp0), "=&r" (temp1), "=r" (ctr) - : "ir" (i), "r" (ctr) - : "cc"); -} - -extern __inline__ __volatile__ void dec_smp_counter(volatile int *ctr) -{ - unsigned long temp0, temp1; - - __asm__ __volatile__(" - lduw [%2], %0 -1: - sub %0, 1, %1 - cas [%2], %0, %1 - cmp %0, %1 - bne,a,pn %%icc, 1b - lduw [%2], %0 -2: - membar #StoreStore | #StoreLoad -" : "=&r" (temp0), "=&r" (temp1), "=r" (ctr) - : "ir" (i), "r" (ctr) - : "cc"); -} - -extern __inline__ __volatile__ int read_smp_counter(volatile int *ctr) -{ - return *ctr; -} - #endif /* !(__ASSEMBLY__) */ /* Sparc specific messages. */ diff -u --recursive v2.1.35/linux/include/asm-sparc64/smp_lock.h linux/include/asm-sparc64/smp_lock.h --- v2.1.35/linux/include/asm-sparc64/smp_lock.h Mon Apr 14 16:28:24 1997 +++ linux/include/asm-sparc64/smp_lock.h Thu Apr 17 09:24:45 1997 @@ -15,7 +15,7 @@ #define lock_kernel() do { } while(0) #define unlock_kernel() do { } while(0) #define release_kernel_lock(task, cpu, depth) ((depth) = 1) -#define reaquire_kernel_lock(task, cpu, depth) do { } while(0) +#define reacquire_kernel_lock(task, cpu, depth) do { } while(0) #else #error SMP on sparc64 not supported yet diff -u --recursive v2.1.35/linux/include/asm-sparc64/stat.h linux/include/asm-sparc64/stat.h --- v2.1.35/linux/include/asm-sparc64/stat.h Mon Dec 30 02:00:03 1996 +++ linux/include/asm-sparc64/stat.h Thu Apr 17 13:20:51 1997 @@ -1,4 +1,4 @@ -/* $Id: stat.h,v 1.1 1996/12/26 14:22:31 davem Exp $ */ +/* $Id: stat.h,v 1.2 1997/04/16 14:52:34 jj Exp $ */ #ifndef _SPARC64_STAT_H #define _SPARC64_STAT_H @@ -18,24 +18,23 @@ unsigned long st_ctime; }; -/* XXX Fix this for full backwards 32-bit compat. */ struct stat32 { - dev_t st_dev; - ino_t st_ino; - mode_t st_mode; - short st_nlink; - uid_t st_uid; - gid_t st_gid; - dev_t st_rdev; - off_t st_size; - time_t st_atime; - unsigned int __unused1; - time_t st_mtime; - unsigned int __unused2; - time_t st_ctime; - unsigned int __unused3; - off_t st_blksize; - off_t st_blocks; + __kernel_dev_t32 st_dev; + __kernel_ino_t32 st_ino; + __kernel_mode_t32 st_mode; + short st_nlink; + __kernel_uid_t32 st_uid; + __kernel_gid_t32 st_gid; + __kernel_dev_t32 st_rdev; + __kernel_off_t32 st_size; + __kernel_time_t32 st_atime; + unsigned int __unused1; + __kernel_time_t32 st_mtime; + unsigned int __unused2; + __kernel_time_t32 st_ctime; + unsigned int __unused3; + __kernel_off_t32 st_blksize; + __kernel_off_t32 st_blocks; unsigned int __unused4[2]; }; diff -u --recursive v2.1.35/linux/include/asm-sparc64/statfs.h linux/include/asm-sparc64/statfs.h --- v2.1.35/linux/include/asm-sparc64/statfs.h Mon Dec 30 02:00:03 1996 +++ linux/include/asm-sparc64/statfs.h Tue Apr 15 21:47:24 1997 @@ -1,4 +1,4 @@ -/* $Id: statfs.h,v 1.1 1996/12/26 14:22:40 davem Exp $ */ +/* $Id: statfs.h,v 1.2 1997/04/14 17:05:22 jj Exp $ */ #ifndef _SPARC64_STATFS_H #define _SPARC64_STATFS_H @@ -10,7 +10,6 @@ #endif -/* XXX Fix this for full backwards 32-bit compat. */ struct statfs32 { int f_type; int f_bsize; @@ -19,7 +18,7 @@ int f_bavail; int f_files; int f_ffree; - __kernel_fsid_t f_fsid; + __kernel_fsid_t32 f_fsid; int f_namelen; /* SunOS ignores this field. */ int f_spare[6]; }; diff -u --recursive v2.1.35/linux/include/linux/init.h linux/include/linux/init.h --- v2.1.35/linux/include/linux/init.h Thu Mar 27 14:40:10 1997 +++ linux/include/linux/init.h Thu Apr 17 13:20:51 1997 @@ -30,6 +30,22 @@ * static char linux_logo[] __initdata = { 0x32, 0x36, ... }; */ +/* + * Disable the __initfunc macros if a file that is a part of a + * module attempts to use them. We do not want to interfere + * with module linking. + */ + +#ifndef MODULE #include +#else +#define __init +#define __initdata +#define __initfunc(__arginit) __arginit +/* For assembly routines */ +#define __INIT +#define __FINIT +#define __INITDATA +#endif #endif diff -u --recursive v2.1.35/linux/include/linux/parport.h linux/include/linux/parport.h --- v2.1.35/linux/include/linux/parport.h Sun Apr 13 10:18:22 1997 +++ linux/include/linux/parport.h Thu Apr 17 14:48:53 1997 @@ -1,14 +1,20 @@ -/* $Id: parport.h,v 1.1.2.5 1997/03/29 21:08:31 phil Exp $ */ +/* $Id: parport.h,v 1.2.6.3 1997/04/16 21:21:03 phil Exp $ */ #ifndef _PARPORT_H_ #define _PARPORT_H_ #include #include +#include /* Maximum of 8 ports per machine */ #define PARPORT_MAX 8 +/* Magic numbers */ +#define PARPORT_IRQ_NONE -1 +#define PARPORT_DMA_NONE -1 +#define PARPORT_DISABLE -2 + /* Type classes for Plug-and-Play probe */ typedef enum { @@ -78,6 +84,14 @@ struct ppd *prev; }; +struct parport_dir{ + struct proc_dir_entry *entry; /* Directory /proc/parport/X */ + struct proc_dir_entry *irq; /* IRQ entry /proc/parport/X/irq */ + struct proc_dir_entry *devices; /* /proc/parport/X/devices */ + struct proc_dir_entry *hardware; /* /proc/parport/X/hardware */ + char name[4]; /* /proc/parport/"XXXX" */ +}; + /* A parallel port */ struct parport { unsigned int base; /* base address */ @@ -93,8 +107,9 @@ unsigned int ecr; /* ECP ECR register */ struct parport *next; unsigned int flags; - struct proc_dir_entry *proc_dir; + struct parport_dir pdir; struct parport_device_info probe_info; + int speed; /* Max Write in Bytes/s */ }; /* parport_register_port registers a new parallel port at the given address (if @@ -174,8 +189,10 @@ char); /* Prototypes from parport_procfs */ +extern int parport_proc_init(void); +extern int parport_proc_cleanup(void); extern int parport_proc_register(struct parport *pp); -extern void parport_proc_unregister(struct parport *pp); +extern int parport_proc_unregister(struct parport *pp); /* Prototypes from parport_ksyms.c */ extern void dec_parport_count(void); diff -u --recursive v2.1.35/linux/include/linux/sched.h linux/include/linux/sched.h --- v2.1.35/linux/include/linux/sched.h Wed Apr 16 14:15:00 1997 +++ linux/include/linux/sched.h Thu Apr 17 13:31:25 1997 @@ -112,8 +112,8 @@ * _adding_ to the beginning of the run-queue has * a separate lock). */ +extern rwlock_t tasklist_lock; extern spinlock_t scheduler_lock; -extern spinlock_t tasklist_lock; extern void sched_init(void); extern void show_state(void); @@ -174,14 +174,16 @@ &init_mmap, &init_mmap, MUTEX } struct signal_struct { - int count; - struct sigaction action[32]; + atomic_t count; + struct sigaction action[32]; + spinlock_t siglock; }; #define INIT_SIGNALS { \ - 1, \ - { {0,}, } } + ATOMIC_INIT(1), \ + { {0,}, }, \ + SPIN_LOCK_UNLOCKED } struct task_struct { /* these are hardcoded - don't touch */ @@ -261,6 +263,8 @@ int processor; int last_processor; int lock_depth; /* Lock depth. We can context switch in and out of holding a syscall kernel lock... */ + /* Spinlocks for various pieces or per-task state. */ + spinlock_t sigmask_lock; /* Protects signal and blocked */ }; /* @@ -471,11 +475,11 @@ p->nr++; } -#define REMOVE_LINKS(p) do { \ - spin_lock(&tasklist_lock); \ +#define REMOVE_LINKS(p) do { unsigned long flags; \ + write_lock_irqsave(&tasklist_lock, flags); \ (p)->next_task->prev_task = (p)->prev_task; \ (p)->prev_task->next_task = (p)->next_task; \ - spin_unlock(&tasklist_lock); \ + write_unlock_irqrestore(&tasklist_lock, flags); \ if ((p)->p_osptr) \ (p)->p_osptr->p_ysptr = (p)->p_ysptr; \ if ((p)->p_ysptr) \ @@ -484,13 +488,13 @@ (p)->p_pptr->p_cptr = (p)->p_osptr; \ } while (0) -#define SET_LINKS(p) do { \ - spin_lock(&tasklist_lock); \ +#define SET_LINKS(p) do { unsigned long flags; \ + write_lock_irqsave(&tasklist_lock, flags); \ (p)->next_task = &init_task; \ (p)->prev_task = init_task.prev_task; \ init_task.prev_task->next_task = (p); \ init_task.prev_task = (p); \ - spin_unlock(&tasklist_lock); \ + write_unlock_irqrestore(&tasklist_lock, flags); \ (p)->p_ysptr = NULL; \ if (((p)->p_osptr = (p)->p_pptr->p_cptr) != NULL) \ (p)->p_osptr->p_ysptr = p; \ diff -u --recursive v2.1.35/linux/include/linux/wireless.h linux/include/linux/wireless.h --- v2.1.35/linux/include/linux/wireless.h Mon Mar 17 14:54:35 1997 +++ linux/include/linux/wireless.h Thu Apr 17 14:40:36 1997 @@ -63,20 +63,25 @@ * (there is some stuff that will be added in the future...) * I just plan to increment with each new version. */ -#define WIRELESS_EXT 4 +#define WIRELESS_EXT 5 /* * Changes : * * V2 to V3 * -------- - * Alan Cox start some imcompatibles changes. I've integrated a bit more. + * Alan Cox start some incompatibles changes. I've integrated a bit more. * - Encryption renamed to Encode to avoid US regulation problems * - Frequency changed from float to struct to avoid problems on old 386 * * V3 to V4 * -------- * - Add sensitivity + * + * V4 to V5 + * -------- + * - Missing encoding definitions in range + * - Access points stuff */ /* -------------------------- IOCTL LIST -------------------------- */ @@ -103,11 +108,16 @@ #define SIOCSIWSPY 0x8B10 /* set spy addresses */ #define SIOCGIWSPY 0x8B11 /* get spy info (quality of link) */ +/* Access Point manipulation */ +#define SIOCSIWAP 0x8B14 /* set access point hardware addresses */ +#define SIOCGIWAP 0x8B15 /* get access point hardware addresses */ +#define SIOCGIWAPLIST 0x8B17 /* get list of access point in range */ + /* ------------------------- IOCTL STUFF ------------------------- */ /* The first and the last (range) */ #define SIOCIWFIRST 0x8B00 -#define SIOCIWLAST 0x8B13 +#define SIOCIWLAST 0x8B17 /* Even : get (world access), odd : set (root access) */ #define IW_IS_SET(cmd) (!((cmd) & 0x1)) @@ -185,6 +195,17 @@ __u32 misc; /* Others cases */ }; +/* + * Encoding information (setting and so on) + * Encoding might be hardware encryption, scrambing or others + */ +struct iw_encoding +{ + __u8 method; /* Algorithm number / key used */ + __u64 code; /* Data/key used for algorithm */ +}; + + /* ------------------------ WIRELESS STATS ------------------------ */ /* * Wireless statistics (used for /proc/net/wireless) @@ -234,13 +255,11 @@ * 0-1000 = channel * > 1000 = frequency in Hz */ - struct /* Encoding stuff */ - { - __u8 method; /* Algorithm number / off */ - __u64 code; /* Data used for algorithm */ - } encoding; + struct iw_encoding encoding; /* Encoding stuff */ - __u32 sensitivity; /* signal level threshold */ + __u32 sensitivity; /* signal level threshold */ + + struct sockaddr ap_addr; /* Access point address */ struct /* For all data bigger than 16 octets */ { @@ -275,16 +294,16 @@ __u16 num_channels; /* Number of channels [0; num - 1] */ __u8 num_frequency; /* Number of entry in the list */ struct iw_freq freq[IW_MAX_FREQUENCIES]; /* list */ - /* Note : this frequency list doesn't need to fit channel numbers */ - /* Encoder stuff */ - /* signal level threshold range */ __u32 sensitivity; /* Quality of link & SNR stuff */ struct iw_quality max_qual; /* Quality of the link */ + + /* Encoder stuff */ + struct iw_encoding max_encoding; /* Encoding max range */ }; /* Only in linux/include/linux: zorro.h diff -u --recursive v2.1.35/linux/include/net/sock.h linux/include/net/sock.h --- v2.1.35/linux/include/net/sock.h Mon Apr 14 16:28:26 1997 +++ linux/include/net/sock.h Thu Apr 17 13:32:53 1997 @@ -389,7 +389,7 @@ unsigned short cong_window; unsigned short cong_count; - atomic_t packets_out; + int packets_out; unsigned short shutdown; #if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE) diff -u --recursive v2.1.35/linux/init/main.c linux/init/main.c --- v2.1.35/linux/init/main.c Wed Apr 16 14:15:00 1997 +++ linux/init/main.c Fri Apr 18 21:21:35 1997 @@ -948,7 +948,7 @@ } #ifdef CONFIG_BLK_DEV_INITRD -__initfunc(static int do_linuxrc(void * shell)) +static int do_linuxrc(void * shell) { static char *argv[] = { "linuxrc", NULL, }; diff -u --recursive v2.1.35/linux/kernel/exit.c linux/kernel/exit.c --- v2.1.35/linux/kernel/exit.c Sun Apr 13 10:18:22 1997 +++ linux/kernel/exit.c Thu Apr 17 13:20:51 1997 @@ -41,18 +41,23 @@ * be handled immediately (ie non-blocked and untraced) * and that is ignored (either explicitly or by default) */ + spin_lock_irq(&p->sig->siglock); if (!(mask & p->blocked) && !(p->flags & PF_PTRACED)) { /* don't bother with ignored signals (but SIGCHLD is special) */ if (sa->sa_handler == SIG_IGN && sig != SIGCHLD) - return; + goto out; /* some signals are ignored by default.. (but SIGCONT already did its deed) */ if ((sa->sa_handler == SIG_DFL) && (sig == SIGCONT || sig == SIGCHLD || sig == SIGWINCH || sig == SIGURG)) - return; + goto out; } + spin_lock(&p->sigmask_lock); p->signal |= mask; + spin_unlock(&p->sigmask_lock); if (p->state == TASK_INTERRUPTIBLE && (p->signal & ~p->blocked)) wake_up_process(p); +out: + spin_unlock_irq(&p->sig->siglock); } /* @@ -65,16 +70,23 @@ if (p->sig) { unsigned long mask = 1UL << sig; struct sigaction *sa = p->sig->action + sig; + + spin_lock_irq(&p->sig->siglock); + + spin_lock(&p->sigmask_lock); p->signal |= mask; p->blocked &= ~mask; + spin_unlock(&p->sigmask_lock); + if (sa->sa_handler == SIG_IGN) sa->sa_handler = SIG_DFL; if (p->state == TASK_INTERRUPTIBLE) wake_up_process(p); + + spin_unlock_irq(&p->sig->siglock); } } - int send_sig(unsigned long sig,struct task_struct * p,int priv) { if (!p || sig > 32) @@ -84,24 +96,23 @@ (current->uid ^ p->suid) && (current->uid ^ p->uid) && !suser()) return -EPERM; - if (!sig) - return 0; - /* - * Forget it if the process is already zombie'd. - */ - if (!p->sig) - return 0; - if ((sig == SIGKILL) || (sig == SIGCONT)) { - if (p->state == TASK_STOPPED) - wake_up_process(p); - p->exit_code = 0; - p->signal &= ~( (1<<(SIGSTOP-1)) | (1<<(SIGTSTP-1)) | - (1<<(SIGTTIN-1)) | (1<<(SIGTTOU-1)) ); - } - if (sig == SIGSTOP || sig == SIGTSTP || sig == SIGTTIN || sig == SIGTTOU) - p->signal &= ~(1<<(SIGCONT-1)); - /* Actually generate the signal */ - generate(sig,p); + + if (sig && p->sig) { + spin_lock_irq(&p->sigmask_lock); + if ((sig == SIGKILL) || (sig == SIGCONT)) { + if (p->state == TASK_STOPPED) + wake_up_process(p); + p->exit_code = 0; + p->signal &= ~( (1<<(SIGSTOP-1)) | (1<<(SIGTSTP-1)) | + (1<<(SIGTTIN-1)) | (1<<(SIGTTOU-1)) ); + } + if (sig == SIGSTOP || sig == SIGTSTP || sig == SIGTTIN || sig == SIGTTOU) + p->signal &= ~(1<<(SIGCONT-1)); + spin_unlock_irq(&p->sigmask_lock); + + /* Actually generate the signal */ + generate(sig,p); + } return 0; } @@ -245,14 +256,18 @@ int fallback; fallback = -1; + read_lock(&tasklist_lock); for_each_task(p) { if (p->session <= 0) continue; - if (p->pgrp == pgrp) - return p->session; + if (p->pgrp == pgrp) { + fallback = p->session; + break; + } if (p->pid == pgrp) fallback = p->session; } + read_unlock(&tasklist_lock); return fallback; } @@ -262,21 +277,29 @@ */ int kill_pg(int pgrp, int sig, int priv) { - struct task_struct *p; - int err,retval = -ESRCH; - int found = 0; + int retval; - if (sig<0 || sig>32 || pgrp<=0) - return -EINVAL; - for_each_task(p) { - if (p->pgrp == pgrp) { - if ((err = send_sig(sig,p,priv)) != 0) - retval = err; - else - found++; + retval = -EINVAL; + if (sig >= 0 && sig <= 32 && pgrp > 0) { + struct task_struct *p; + int found = 0; + + retval = -ESRCH; + read_lock(&tasklist_lock); + for_each_task(p) { + if (p->pgrp == pgrp) { + int err = send_sig(sig,p,priv); + if (err != 0) + retval = err; + else + found++; + } } + read_unlock(&tasklist_lock); + if (found) + retval = 0; } - return(found ? 0 : retval); + return retval; } /* @@ -286,34 +309,51 @@ */ int kill_sl(int sess, int sig, int priv) { - struct task_struct *p; - int err,retval = -ESRCH; - int found = 0; + int retval; - if (sig<0 || sig>32 || sess<=0) - return -EINVAL; - for_each_task(p) { - if (p->session == sess && p->leader) { - if ((err = send_sig(sig,p,priv)) != 0) - retval = err; - else - found++; + retval = -EINVAL; + if (sig >= 0 && sig <= 32 && sess > 0) { + struct task_struct *p; + int found = 0; + + retval = -ESRCH; + read_lock(&tasklist_lock); + for_each_task(p) { + if (p->leader && p->session == sess) { + int err = send_sig(sig,p,priv); + + if (err) + retval = err; + else + found++; + } } + read_unlock(&tasklist_lock); + if (found) + retval = 0; } - return(found ? 0 : retval); + return retval; } int kill_proc(int pid, int sig, int priv) { - struct task_struct *p; + int retval; - if (sig<0 || sig>32) - return -EINVAL; - for_each_task(p) { - if (p && p->pid == pid) - return send_sig(sig,p,priv); + retval = -EINVAL; + if (sig >= 0 && sig <= 32) { + struct task_struct *p; + + retval = -ESRCH; + read_lock(&tasklist_lock); + for_each_task(p) { + if (p->pid != pid) + continue; + retval = send_sig(sig,p,priv); + break; + } + read_unlock(&tasklist_lock); } - return(-ESRCH); + return retval; } /* @@ -322,34 +362,30 @@ */ asmlinkage int sys_kill(int pid,int sig) { - int err, retval = 0, count = 0; + if (!pid) + return kill_pg(current->pgrp,sig,0); - lock_kernel(); - if (!pid) { - err = kill_pg(current->pgrp,sig,0); - goto out; - } if (pid == -1) { + int retval = 0, count = 0; struct task_struct * p; + + read_lock(&tasklist_lock); for_each_task(p) { if (p->pid > 1 && p != current) { + int err; ++count; if ((err = send_sig(sig,p,0)) != -EPERM) retval = err; } } - err = count ? retval : -ESRCH; - goto out; - } - if (pid < 0) { - err = kill_pg(-pid,sig,0); - goto out; + read_unlock(&tasklist_lock); + return count ? retval : -ESRCH; } + if (pid < 0) + return kill_pg(-pid,sig,0); + /* Normal kill */ - err = kill_proc(pid,sig,0); -out: - unlock_kernel(); - return err; + return kill_proc(pid,sig,0); } /* @@ -364,16 +400,20 @@ { struct task_struct *p; + read_lock(&tasklist_lock); for_each_task(p) { if ((p == ignored_task) || (p->pgrp != pgrp) || (p->state == TASK_ZOMBIE) || (p->p_pptr->pid == 1)) continue; if ((p->p_pptr->pgrp != pgrp) && - (p->p_pptr->session == p->session)) - return 0; + (p->p_pptr->session == p->session)) { + read_unlock(&tasklist_lock); + return 0; + } } - return(1); /* (sighing) "Often!" */ + read_unlock(&tasklist_lock); + return 1; /* (sighing) "Often!" */ } int is_orphaned_pgrp(int pgrp) @@ -383,21 +423,27 @@ static inline int has_stopped_jobs(int pgrp) { + int retval = 0; struct task_struct * p; + read_lock(&tasklist_lock); for_each_task(p) { if (p->pgrp != pgrp) continue; - if (p->state == TASK_STOPPED) - return(1); + if (p->state != TASK_STOPPED) + continue; + retval = 1; + break; } - return(0); + read_unlock(&tasklist_lock); + return retval; } static inline void forget_original_parent(struct task_struct * father) { struct task_struct * p; + read_lock(&tasklist_lock); for_each_task(p) { if (p->p_opptr == father) if (task[smp_num_cpus]) /* init */ @@ -405,6 +451,7 @@ else p->p_opptr = task[0]; } + read_unlock(&tasklist_lock); } static inline void close_files(struct files_struct * files) @@ -470,9 +517,8 @@ if (sig) { tsk->sig = NULL; - if (!--sig->count) { + if (atomic_dec_and_test(&sig->count)) kfree(sig); - } } } @@ -635,24 +681,22 @@ struct wait_queue wait = { current, NULL }; struct task_struct *p; - lock_kernel(); if (stat_addr) { - retval = verify_area(VERIFY_WRITE, stat_addr, sizeof(*stat_addr)); - if (retval) - goto out; + if(verify_area(VERIFY_WRITE, stat_addr, sizeof(*stat_addr))) + return -EFAULT; } if (ru) { - retval = verify_area(VERIFY_WRITE, ru, sizeof(*ru)); - if (retval) - goto out; + if(verify_area(VERIFY_WRITE, ru, sizeof(*ru))) + return -EFAULT; } - retval = -EINVAL; + if (options & ~(WNOHANG|WUNTRACED|__WCLONE)) - goto out; + return -EINVAL; + lock_kernel(); add_wait_queue(¤t->wait_chldexit,&wait); repeat: - flag=0; + flag = retval = 0; for (p = current->p_cptr ; p ; p = p->p_osptr) { if (pid>0) { if (p->pid != pid) @@ -719,7 +763,6 @@ retval = -ECHILD; end_wait4: remove_wait_queue(¤t->wait_chldexit,&wait); -out: unlock_kernel(); return retval; } @@ -732,12 +775,7 @@ */ asmlinkage int sys_waitpid(pid_t pid,unsigned int * stat_addr, int options) { - int ret; - - lock_kernel(); - ret = sys_wait4(pid, stat_addr, options, NULL); - unlock_kernel(); - return ret; + return sys_wait4(pid, stat_addr, options, NULL); } #endif diff -u --recursive v2.1.35/linux/kernel/fork.c linux/kernel/fork.c --- v2.1.35/linux/kernel/fork.c Sun Apr 13 10:18:22 1997 +++ linux/kernel/fork.c Thu Apr 17 13:20:51 1997 @@ -203,13 +203,14 @@ static inline int copy_sighand(unsigned long clone_flags, struct task_struct * tsk) { if (clone_flags & CLONE_SIGHAND) { - current->sig->count++; + atomic_inc(¤t->sig->count); return 0; } tsk->sig = kmalloc(sizeof(*tsk->sig), GFP_KERNEL); if (!tsk->sig) return -1; - tsk->sig->count = 1; + spin_lock_init(&tsk->sig->siglock); + atomic_set(&tsk->sig->count, 1); memcpy(tsk->sig->action, current->sig->action, sizeof(tsk->sig->action)); return 0; } diff -u --recursive v2.1.35/linux/kernel/ksyms.c linux/kernel/ksyms.c --- v2.1.35/linux/kernel/ksyms.c Mon Apr 14 16:28:26 1997 +++ linux/kernel/ksyms.c Wed Apr 16 16:05:00 1997 @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include @@ -130,6 +131,10 @@ EXPORT_SYMBOL(num_physpages); EXPORT_SYMBOL(high_memory); EXPORT_SYMBOL(update_vm_cache); +EXPORT_SYMBOL(kmem_cache_create); +EXPORT_SYMBOL(kmem_cache_destroy); +EXPORT_SYMBOL(kmem_cache_alloc); +EXPORT_SYMBOL(kmem_cache_free); /* filesystem internal functions */ EXPORT_SYMBOL(getname); @@ -258,7 +263,10 @@ EXPORT_SYMBOL(tq_scheduler); EXPORT_SYMBOL(timer_active); EXPORT_SYMBOL(timer_table); + #ifdef __SMP__ +/* Various random spinlocks we want to export */ +EXPORT_SYMBOL(tqueue_lock); EXPORT_SYMBOL(waitqueue_lock); #endif diff -u --recursive v2.1.35/linux/kernel/sched.c linux/kernel/sched.c --- v2.1.35/linux/kernel/sched.c Wed Apr 16 14:15:00 1997 +++ linux/kernel/sched.c Thu Apr 17 09:25:05 1997 @@ -126,22 +126,6 @@ (p->prev_run = init_task.prev_run)->next_run = p; p->next_run = &init_task; init_task.prev_run = p; -#if 0 /* def __SMP__ */ - /* this is safe only if called with cli()*/ - inc_smp_counter(&smp_process_available); - if ((0!=p->pid) && smp_threads_ready) - { - int i; - for (i=0;ipid) - { - smp_message_pass(cpu_logical_map[i], MSG_RESCHEDULE, 0L, 0); - break; - } - } - } -#endif } static inline void del_from_runqueue(struct task_struct * p) @@ -187,9 +171,7 @@ } /* - * The tasklist_lock protects the linked list of processes - * and doesn't need to be interrupt-safe as interrupts never - * use the task-list. + * The tasklist_lock protects the linked list of processes. * * The scheduler lock is protecting against multiple entry * into the scheduling code, and doesn't need to worry @@ -199,7 +181,7 @@ * The run-queue lock locks the parts that actually access * and change the run-queues, and have to be interrupt-safe. */ -spinlock_t tasklist_lock = SPIN_LOCK_UNLOCKED; +rwlock_t tasklist_lock = RW_LOCK_UNLOCKED; spinlock_t scheduler_lock = SPIN_LOCK_UNLOCKED; static spinlock_t runqueue_lock = SPIN_LOCK_UNLOCKED; @@ -391,10 +373,10 @@ /* Do we need to re-calculate counters? */ if (!c) { struct task_struct *p; - spin_lock(&tasklist_lock); + read_lock(&tasklist_lock); for_each_task(p) p->counter = (p->counter >> 1) + p->priority; - spin_unlock(&tasklist_lock); + read_unlock(&tasklist_lock); } } } @@ -421,7 +403,7 @@ } spin_unlock(&scheduler_lock); - reaquire_kernel_lock(prev, smp_processor_id(), lock_depth); + reacquire_kernel_lock(prev, smp_processor_id(), lock_depth); } #ifndef __alpha__ diff -u --recursive v2.1.35/linux/kernel/signal.c linux/kernel/signal.c --- v2.1.35/linux/kernel/signal.c Thu Mar 27 14:40:12 1997 +++ linux/kernel/signal.c Thu Apr 17 13:20:51 1997 @@ -31,6 +31,9 @@ * We don't need to get the kernel lock - this is all local to this * particular thread.. (and that's good, because this is _heavily_ * used by various programs) + * + * No SMP locking would prevent the inherent races present in this + * routine, thus we do not perform any locking at all. */ asmlinkage int sys_sigprocmask(int how, sigset_t *set, sigset_t *oset) { @@ -38,9 +41,10 @@ if (set) { sigset_t new_set; - int error = get_user(new_set, set); - if (error) - return error; + + if(get_user(new_set, set)) + return -EFAULT; + new_set &= _BLOCKABLE; switch (how) { default: @@ -57,9 +61,8 @@ current->blocked = new_set; } if (oset) { - int error = put_user(old_set, oset); - if (error) - return error; + if(put_user(old_set, oset)) + return -EFAULT; } return 0; } @@ -69,21 +72,19 @@ */ asmlinkage int sys_sgetmask(void) { - int ret; - /* SMP safe */ - ret = current->blocked; - return ret; + return current->blocked; } asmlinkage int sys_ssetmask(int newmask) { int old; - lock_kernel(); + spin_lock_irq(¤t->sigmask_lock); old = current->blocked; current->blocked = newmask & _BLOCKABLE; - unlock_kernel(); + spin_unlock_irq(¤t->sigmask_lock); + return old; } @@ -114,22 +115,24 @@ * Note the silly behaviour of SIGCHLD: SIG_IGN means that the signal * isn't actually ignored, but does automatic child reaping, while * SIG_DFL is explicitly said by POSIX to force the signal to be ignored.. + * + * All callers of check_pending must be holding current->sig->siglock. */ inline void check_pending(int signum) { struct sigaction *p; p = signum - 1 + current->sig->action; + spin_lock(¤t->sigmask_lock); if (p->sa_handler == SIG_IGN) { current->signal &= ~_S(signum); - return; - } - if (p->sa_handler == SIG_DFL) { - if (signum != SIGCONT && signum != SIGCHLD && signum != SIGWINCH) - return; - current->signal &= ~_S(signum); - return; + } else if (p->sa_handler == SIG_DFL) { + if (signum == SIGCONT || + signum == SIGCHLD || + signum != SIGWINCH) + current->signal &= ~_S(signum); } + spin_unlock(¤t->sigmask_lock); } #ifndef __alpha__ @@ -138,30 +141,28 @@ */ asmlinkage unsigned long sys_signal(int signum, __sighandler_t handler) { - unsigned long err; struct sigaction tmp; - lock_kernel(); - err = -EINVAL; if (signum<1 || signum>32) - goto out; + return -EINVAL; if (signum==SIGKILL || signum==SIGSTOP) - goto out; + return -EINVAL; if (handler != SIG_DFL && handler != SIG_IGN) { - err = verify_area(VERIFY_READ, handler, 1); - if (err) - goto out; + if(verify_area(VERIFY_READ, handler, 1)) + return -EFAULT; } + memset(&tmp, 0, sizeof(tmp)); tmp.sa_handler = handler; tmp.sa_flags = SA_ONESHOT | SA_NOMASK; + + spin_lock_irq(¤t->sig->siglock); handler = current->sig->action[signum-1].sa_handler; current->sig->action[signum-1] = tmp; check_pending(signum); - err = (unsigned long) handler; -out: - unlock_kernel(); - return err; + spin_unlock_irq(¤t->sig->siglock); + + return (unsigned long) handler; } #endif @@ -171,22 +172,33 @@ { struct sigaction new_sa, *p; - if (signum<1 || signum>32) + if (signum < 1 || signum > 32) return -EINVAL; + p = signum - 1 + current->sig->action; + if (action) { if (copy_from_user(&new_sa, action, sizeof(struct sigaction))) return -EFAULT; if (signum==SIGKILL || signum==SIGSTOP) return -EINVAL; } + if (oldaction) { + /* In the clone() case we could copy half consistant + * state to the user, however this could sleep and + * deadlock us if we held the signal lock on SMP. So for + * now I take the easy way out and do no locking. + */ if (copy_to_user(oldaction, p, sizeof(struct sigaction))) return -EFAULT; } + if (action) { + spin_lock_irq(¤t->sig->siglock); *p = new_sa; check_pending(signum); + spin_unlock_irq(¤t->sig->siglock); } return 0; } diff -u --recursive v2.1.35/linux/kernel/sys.c linux/kernel/sys.c --- v2.1.35/linux/kernel/sys.c Sun Apr 13 10:18:22 1997 +++ linux/kernel/sys.c Wed Apr 16 13:42:36 1997 @@ -810,8 +810,7 @@ if (!pid) { ret = current->session; } else { - /* Walking the process table needs locks */ - lock_kernel(); + read_lock(&tasklist_lock); for_each_task(p) { if (p->pid == pid) { ret = p->session; @@ -820,7 +819,7 @@ } ret = -ESRCH; out: - unlock_kernel(); + read_unlock(&tasklist_lock); } return ret; } @@ -830,7 +829,7 @@ struct task_struct * p; int err = -EPERM; - lock_kernel(); + read_lock(&tasklist_lock); for_each_task(p) { if (p->pgrp == current->pid) goto out; @@ -842,7 +841,7 @@ current->tty_old_pgrp = 0; err = current->pgrp; out: - unlock_kernel(); + read_unlock(&tasklist_lock); return err; } diff -u --recursive v2.1.35/linux/mm/swap.c linux/mm/swap.c --- v2.1.35/linux/mm/swap.c Mon Apr 14 16:28:27 1997 +++ linux/mm/swap.c Thu Apr 17 13:20:52 1997 @@ -44,7 +44,7 @@ /* We track the number of pages currently being asynchronously swapped out, so that we don't try to swap TOO many pages out at once */ -atomic_t nr_async_pages = ATOMIC_INIT; +atomic_t nr_async_pages = ATOMIC_INIT(0); /* * Constants for the page aging mechanism: the maximum age (actually, diff -u --recursive v2.1.35/linux/net/core/dev.c linux/net/core/dev.c --- v2.1.35/linux/net/core/dev.c Mon Apr 14 16:28:27 1997 +++ linux/net/core/dev.c Thu Apr 17 13:20:52 1997 @@ -79,6 +79,7 @@ #include #include #include +#include #ifdef CONFIG_KERNELD #include #endif @@ -122,7 +123,7 @@ * Device list lock */ -atomic_t dev_lockct = ATOMIC_INIT; +atomic_t dev_lockct = ATOMIC_INIT(0); /* * Our notifier list @@ -1578,7 +1579,7 @@ #endif /* CONFIG_PROC_FS */ #endif /* CONFIG_NET_RADIO */ -int net_dev_init(void) +__initfunc(int net_dev_init(void)) { struct device *dev, **dp; diff -u --recursive v2.1.35/linux/net/core/dst.c linux/net/core/dst.c --- v2.1.35/linux/net/core/dst.c Mon Apr 14 16:28:27 1997 +++ linux/net/core/dst.c Thu Apr 17 13:20:52 1997 @@ -20,7 +20,7 @@ #include struct dst_entry * dst_garbage_list; -atomic_t dst_total = ATOMIC_INIT; +atomic_t dst_total = ATOMIC_INIT(0); static unsigned long dst_gc_timer_expires; static unsigned long dst_gc_timer_inc = DST_GC_MAX; diff -u --recursive v2.1.35/linux/net/core/skbuff.c linux/net/core/skbuff.c --- v2.1.35/linux/net/core/skbuff.c Mon Apr 14 16:28:27 1997 +++ linux/net/core/skbuff.c Thu Apr 17 13:20:52 1997 @@ -60,9 +60,9 @@ * Resource tracking variables */ -static atomic_t net_skbcount = ATOMIC_INIT; -static atomic_t net_allocs = ATOMIC_INIT; -static atomic_t net_fails = ATOMIC_INIT; +static atomic_t net_skbcount = ATOMIC_INIT(0); +static atomic_t net_allocs = ATOMIC_INIT(0); +static atomic_t net_fails = ATOMIC_INIT(0); extern atomic_t ip_frag_mem; diff -u --recursive v2.1.35/linux/net/core/sock.c linux/net/core/sock.c --- v2.1.35/linux/net/core/sock.c Mon Apr 14 16:28:27 1997 +++ linux/net/core/sock.c Fri Apr 18 10:53:54 1997 @@ -189,7 +189,7 @@ * is best */ - if(val > SK_WMEM_MAX*2 || val < 2048) + if(val > SK_WMEM_MAX*2) return -EINVAL; /* * Once this is all 32bit values we can @@ -197,7 +197,7 @@ */ if(val > 65535) return -EINVAL; - sk->sndbuf = val; + sk->sndbuf = max(val,2048); /* * Wake up sending tasks if we * upped the value. @@ -206,12 +206,12 @@ break; case SO_RCVBUF: - if(val > SK_RMEM_MAX*2 || val < 256) + if(val > SK_RMEM_MAX*2) return -EINVAL; /* Can go soon: FIXME */ if(val > 65535) return -EINVAL; - sk->rcvbuf = val; + sk->rcvbuf = max(val,256); break; case SO_KEEPALIVE: diff -u --recursive v2.1.35/linux/net/ipv4/arp.c linux/net/ipv4/arp.c --- v2.1.35/linux/net/ipv4/arp.c Mon Apr 14 16:28:27 1997 +++ linux/net/ipv4/arp.c Thu Apr 17 13:20:52 1997 @@ -230,13 +230,6 @@ int sysctl_arp_dead_res_time = ARP_DEAD_RES_TIME; -/* This should be completely nuked... -DaveM */ -#if RT_CACHE_DEBUG >= 1 -#define ASSERT_BH() if (!in_interrupt()) printk(KERN_CRIT __FUNCTION__ " called from SPL=0\n"); -#else -#define ASSERT_BH() -#endif - static void arp_neigh_destroy(struct neighbour *neigh); /* @@ -251,8 +244,8 @@ }; -static atomic_t arp_size = ATOMIC_INIT; -static atomic_t arp_unres_size = ATOMIC_INIT; +static atomic_t arp_size = ATOMIC_INIT(0); +static atomic_t arp_unres_size = ATOMIC_INIT(0); #ifdef CONFIG_ARPD static int arpd_not_running; @@ -340,12 +333,9 @@ { struct sk_buff *skb; - ASSERT_BH(); - /* Release the list of `skb' pointers. */ while ((skb = skb_dequeue(&entry->u.neigh.arp_queue)) != NULL) kfree_skb(skb, FREE_WRITE); - return; } static void arp_free(struct arp_table **entryp) @@ -353,8 +343,6 @@ struct arp_table *entry = *entryp; *entryp = entry->u.next; - ASSERT_BH(); - if (!(entry->flags&ATF_PUBL)) { atomic_dec(&arp_size); if (!(entry->flags&ATF_COM)) @@ -373,8 +361,6 @@ struct arp_table *entry = (struct arp_table*)neigh; struct hh_cache *hh, *next; - ASSERT_BH(); - del_timer(&entry->timer); arp_purge_send_q(entry); @@ -877,11 +863,8 @@ { struct sk_buff *skb; - ASSERT_BH(); - - while((skb = skb_dequeue(&entry->u.neigh.arp_queue)) != NULL) { + while((skb = skb_dequeue(&entry->u.neigh.arp_queue)) != NULL) dev_queue_xmit(skb); - } } diff -u --recursive v2.1.35/linux/net/ipv4/fib.c linux/net/ipv4/fib.c --- v2.1.35/linux/net/ipv4/fib.c Mon Apr 14 16:28:27 1997 +++ linux/net/ipv4/fib.c Thu Apr 17 13:20:52 1997 @@ -117,7 +117,7 @@ */ static struct wait_queue *fib_wait; -static atomic_t fib_users = ATOMIC_INIT; +static atomic_t fib_users = ATOMIC_INIT(0); static void fib_lock(void) { diff -u --recursive v2.1.35/linux/net/ipv4/ip_fragment.c linux/net/ipv4/ip_fragment.c --- v2.1.35/linux/net/ipv4/ip_fragment.c Mon Apr 14 16:28:27 1997 +++ linux/net/ipv4/ip_fragment.c Thu Apr 17 13:20:52 1997 @@ -46,7 +46,7 @@ static struct ipq *ipqueue = NULL; /* IP fragment queue */ -atomic_t ip_frag_mem = ATOMIC_INIT; /* Memory used for fragments */ +atomic_t ip_frag_mem = ATOMIC_INIT(0); /* Memory used for fragments */ char *in_ntoa(unsigned long in); diff -u --recursive v2.1.35/linux/net/ipv4/route.c linux/net/ipv4/route.c --- v2.1.35/linux/net/ipv4/route.c Mon Apr 14 16:28:27 1997 +++ linux/net/ipv4/route.c Thu Apr 17 13:20:52 1997 @@ -111,7 +111,7 @@ * Route cache. */ -static atomic_t rt_cache_size = ATOMIC_INIT; +static atomic_t rt_cache_size = ATOMIC_INIT(0); static struct rtable *rt_hash_table[RT_HASH_DIVISOR]; static struct rtable * rt_intern_hash(unsigned hash, struct rtable * rth, u16 protocol); diff -u --recursive v2.1.35/linux/net/ipv4/tcp.c linux/net/ipv4/tcp.c --- v2.1.35/linux/net/ipv4/tcp.c Mon Apr 14 16:28:28 1997 +++ linux/net/ipv4/tcp.c Thu Apr 17 13:20:52 1997 @@ -5,7 +5,7 @@ * * Implementation of the Transmission Control Protocol(TCP). * - * Version: $Id: tcp.c,v 1.55 1997/04/13 10:31:45 davem Exp $ + * Version: $Id: tcp.c,v 1.56 1997/04/16 09:18:42 davem Exp $ * * Authors: Ross Biro, * Fred N. van Kempen, @@ -949,7 +949,7 @@ tmp = MAX_HEADER + sk->prot->max_header + sizeof(struct sk_buff) + 15; if (copy < min(sk->mss, sk->max_window >> 1) && - !(flags & MSG_OOB) && atomic_read(&sk->packets_out)) + !(flags & MSG_OOB) && sk->packets_out) { tmp += min(sk->mss, sk->max_window); } diff -u --recursive v2.1.35/linux/net/ipv4/tcp_input.c linux/net/ipv4/tcp_input.c --- v2.1.35/linux/net/ipv4/tcp_input.c Mon Apr 14 16:28:28 1997 +++ linux/net/ipv4/tcp_input.c Thu Apr 17 13:20:52 1997 @@ -5,7 +5,7 @@ * * Implementation of the Transmission Control Protocol(TCP). * - * Version: $Id: tcp_input.c,v 1.42 1997/04/12 04:32:24 davem Exp $ + * Version: $Id: tcp_input.c,v 1.43 1997/04/16 09:18:47 davem Exp $ * * Authors: Ross Biro, * Fred N. van Kempen, @@ -332,7 +332,7 @@ * The packet acked data after high_seq; */ - if (ack == tp->snd_una && atomic_read(&sk->packets_out) && (not_dup == 0)) + if (ack == tp->snd_una && sk->packets_out && (not_dup == 0)) { /* * 1. When the third duplicate ack is received, set ssthresh @@ -591,7 +591,7 @@ * do packet "repackaging" for stacks that don't * like overlapping packets. */ - atomic_dec(&sk->packets_out); + sk->packets_out--; *seq = skb->seq; *seq_rtt = now - skb->when; @@ -744,7 +744,7 @@ if (atomic_read(&sk->retransmits)) { - if (atomic_read(&sk->packets_out) == 0) + if (sk->packets_out == 0) atomic_set(&sk->retransmits, 0); } else @@ -769,7 +769,7 @@ } } - if (atomic_read(&sk->packets_out)) + if (sk->packets_out) { if (flag & FLAG_DATA_ACKED) { @@ -1152,7 +1152,7 @@ if ((skb = tp->send_head)) { if (!after(skb->end_seq, tp->snd_una + tp->snd_wnd) && - atomic_read(&sk->packets_out) < tp->snd_cwnd ) + sk->packets_out < tp->snd_cwnd ) { /* * Add more data to the send queue. @@ -1165,7 +1165,7 @@ if(!sk->dead) sk->write_space(sk); } - else if (atomic_read(&sk->packets_out) == 0 && !tp->pending) + else if (sk->packets_out == 0 && !tp->pending) { /* * Data to queue but no room. diff -u --recursive v2.1.35/linux/net/ipv4/tcp_ipv4.c linux/net/ipv4/tcp_ipv4.c --- v2.1.35/linux/net/ipv4/tcp_ipv4.c Mon Apr 14 16:28:28 1997 +++ linux/net/ipv4/tcp_ipv4.c Fri Apr 18 10:53:54 1997 @@ -5,7 +5,7 @@ * * Implementation of the Transmission Control Protocol(TCP). * - * Version: $Id: tcp_ipv4.c,v 1.30 1997/04/13 10:31:44 davem Exp $ + * Version: $Id: tcp_ipv4.c,v 1.31 1997/04/16 09:18:50 davem Exp $ * * IPv4 specific functions * @@ -585,7 +585,7 @@ skb_queue_tail(&sk->write_queue, buff); - atomic_inc(&sk->packets_out); + sk->packets_out++; buff->when = jiffies; skb1 = skb_clone(buff, GFP_KERNEL); @@ -816,7 +816,7 @@ return; } - mss = (skb->dst->pmtu - sizeof(struct iphdr) + sizeof(struct tcphdr)); + mss = (skb->dst->pmtu - sizeof(struct iphdr) - sizeof(struct tcphdr)); if (sk->user_mss) mss = min(mss, sk->user_mss); skb->h.th = th = (struct tcphdr *) skb_put(skb, sizeof(struct tcphdr)); @@ -1020,7 +1020,7 @@ newtp->snd_nxt = newsk->write_seq; newsk->urg_data = 0; - atomic_set(&newsk->packets_out, 0); + newsk->packets_out = 0; atomic_set(&newsk->retransmits, 0); newsk->linger=0; newsk->destroy = 0; diff -u --recursive v2.1.35/linux/net/ipv4/tcp_output.c linux/net/ipv4/tcp_output.c --- v2.1.35/linux/net/ipv4/tcp_output.c Mon Apr 14 16:28:28 1997 +++ linux/net/ipv4/tcp_output.c Thu Apr 17 13:20:52 1997 @@ -5,7 +5,7 @@ * * Implementation of the Transmission Control Protocol(TCP). * - * Version: $Id: tcp_output.c,v 1.34 1997/04/12 04:32:33 davem Exp $ + * Version: $Id: tcp_output.c,v 1.35 1997/04/16 09:18:53 davem Exp $ * * Authors: Ross Biro, * Fred N. van Kempen, @@ -79,12 +79,12 @@ len = skb->end_seq - skb->seq; - if (!sk->nonagle && len < (sk->mss >> 1) && atomic_read(&sk->packets_out)) + if (!sk->nonagle && len < (sk->mss >> 1) && sk->packets_out) { nagle_check = 0; } - return (nagle_check && atomic_read(&sk->packets_out) < tp->snd_cwnd && + return (nagle_check && sk->packets_out < tp->snd_cwnd && !after(skb->end_seq, tp->snd_una + tp->snd_wnd) && atomic_read(&sk->retransmits) == 0); } @@ -168,7 +168,7 @@ skb_set_owner_w(buff, sk); tp->snd_nxt = skb->end_seq; - atomic_inc(&sk->packets_out); + sk->packets_out++; skb->when = jiffies; @@ -189,7 +189,7 @@ if (tp->send_head == NULL) tp->send_head = skb; - if (atomic_read(&sk->packets_out) == 0 && !tp->pending) + if (sk->packets_out == 0 && !tp->pending) { tp->pending = TIME_PROBE0; tcp_reset_xmit_timer(sk, TIME_PROBE0, tp->rto); @@ -333,7 +333,7 @@ { /* !tcp_frament Failed! */ tp->send_head = skb; - atomic_dec(&sk->packets_out); + sk->packets_out--; return -1; } else @@ -441,7 +441,7 @@ update_send_head(sk); clear_delayed_acks(sk); - atomic_inc(&sk->packets_out); + sk->packets_out++; skb_set_owner_w(buff, sk); tp->snd_nxt = skb->end_seq; @@ -610,7 +610,7 @@ */ kfree_skb(buff, FREE_WRITE); - atomic_dec(&sk->packets_out); + sk->packets_out--; /* * Header checksum will be set by the retransmit procedure @@ -672,7 +672,7 @@ printk(KERN_DEBUG "tcp_fragment failed\n"); return; } - atomic_inc(&sk->packets_out); + sk->packets_out++; } if (!th->syn && @@ -833,7 +833,7 @@ { struct sk_buff *skb1; - atomic_inc(&sk->packets_out); + sk->packets_out++; tp->snd_nxt = sk->write_seq; buff->when = jiffies; @@ -910,7 +910,7 @@ { skb_set_owner_w(buff, sk); - atomic_inc(&sk->packets_out); + sk->packets_out++; skb->when = jiffies; tp->af_specific->queue_xmit(buff); @@ -1107,7 +1107,7 @@ return; } skb_set_owner_w(buff, sk); - atomic_inc(&sk->packets_out); + sk->packets_out++; clear_delayed_acks(sk); diff -u --recursive v2.1.35/linux/net/ipv4/tcp_timer.c linux/net/ipv4/tcp_timer.c --- v2.1.35/linux/net/ipv4/tcp_timer.c Mon Apr 14 16:28:28 1997 +++ linux/net/ipv4/tcp_timer.c Thu Apr 17 13:20:52 1997 @@ -34,8 +34,8 @@ struct tcp_sl_timer tcp_slt_array[TCP_SLT_MAX] = { - {ATOMIC_INIT, TCP_SYNACK_PERIOD, 0, tcp_syn_recv_timer},/* SYNACK */ - {ATOMIC_INIT, TCP_KEEPALIVE_PERIOD, 0, tcp_keepalive} /* KEEPALIVE */ + {ATOMIC_INIT(0), TCP_SYNACK_PERIOD, 0, tcp_syn_recv_timer},/* SYNACK */ + {ATOMIC_INIT(0), TCP_KEEPALIVE_PERIOD, 0, tcp_keepalive} /* KEEPALIVE */ }; /* diff -u --recursive v2.1.35/linux/net/ipv6/addrconf.c linux/net/ipv6/addrconf.c --- v2.1.35/linux/net/ipv6/addrconf.c Mon Apr 14 16:28:28 1997 +++ linux/net/ipv6/addrconf.c Thu Apr 17 13:20:52 1997 @@ -5,7 +5,7 @@ * Authors: * Pedro Roque * - * $Id: addrconf.c,v 1.16 1997/04/12 04:32:44 davem Exp $ + * $Id: addrconf.c,v 1.18 1997/04/16 05:58:03 davem Exp $ * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -69,7 +69,7 @@ */ struct inet6_dev *inet6_dev_lst[IN6_ADDR_HSIZE]; -static atomic_t addr_list_lock = ATOMIC_INIT; +static atomic_t addr_list_lock = ATOMIC_INIT(0); void addrconf_verify(unsigned long); diff -u --recursive v2.1.35/linux/net/ipv6/ipv6_sockglue.c linux/net/ipv6/ipv6_sockglue.c --- v2.1.35/linux/net/ipv6/ipv6_sockglue.c Mon Apr 14 16:28:28 1997 +++ linux/net/ipv6/ipv6_sockglue.c Tue Apr 15 21:47:24 1997 @@ -7,7 +7,7 @@ * * Based on linux/net/ipv4/ip_sockglue.c * - * $Id: ipv6_sockglue.c,v 1.9 1997/04/07 06:55:51 davem Exp $ + * $Id: ipv6_sockglue.c,v 1.10 1997/04/15 09:06:33 davem Exp $ * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License diff -u --recursive v2.1.35/linux/net/ipv6/route.c linux/net/ipv6/route.c --- v2.1.35/linux/net/ipv6/route.c Mon Apr 14 16:28:28 1997 +++ linux/net/ipv6/route.c Thu Apr 17 13:20:52 1997 @@ -5,7 +5,7 @@ * Authors: * Pedro Roque * - * $Id: route.c,v 1.10 1997/04/12 04:32:57 davem Exp $ + * $Id: route.c,v 1.11 1997/04/16 05:58:05 davem Exp $ * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -62,7 +62,7 @@ }; struct rt6_info ip6_null_entry = { - {{NULL, ATOMIC_INIT, ATOMIC_INIT, NULL, + {{NULL, ATOMIC_INIT(0), ATOMIC_INIT(0), NULL, 0, 0, 0, 0, 0, 0, 0, 0, -ENETUNREACH, NULL, NULL, ip6_pkt_discard, ip6_pkt_discard, &ip6_dst_ops}}, NULL, {{{0}}}, 256, RTF_REJECT|RTF_NONEXTHOP, ~0UL, @@ -93,7 +93,7 @@ #define ip6_rt_policy (0) #endif -static atomic_t rt6_tbl_lock = ATOMIC_INIT; +static atomic_t rt6_tbl_lock = ATOMIC_INIT(0); static int rt6_bh_mask = 0; #define RT_BH_REQUEST 1 diff -u --recursive v2.1.35/linux/net/ipv6/tcp_ipv6.c linux/net/ipv6/tcp_ipv6.c --- v2.1.35/linux/net/ipv6/tcp_ipv6.c Mon Apr 14 16:28:28 1997 +++ linux/net/ipv6/tcp_ipv6.c Thu Apr 17 13:20:52 1997 @@ -5,7 +5,7 @@ * Authors: * Pedro Roque * - * $Id: tcp_ipv6.c,v 1.20 1997/04/13 10:31:48 davem Exp $ + * $Id: tcp_ipv6.c,v 1.21 1997/04/16 09:19:01 davem Exp $ * * Based on: * linux/net/ipv4/tcp.c @@ -448,7 +448,7 @@ atomic_set(&sk->retransmits, 0); skb_queue_tail(&sk->write_queue, buff); - atomic_inc(&sk->packets_out); + sk->packets_out++; buff->when = jiffies; skb1 = skb_clone(buff, GFP_KERNEL); skb_set_owner_w(skb1, sk); @@ -821,7 +821,7 @@ newtp->snd_nxt = newsk->write_seq; newsk->urg_data = 0; - atomic_set(&newsk->packets_out, 0); + newsk->packets_out = 0; atomic_set(&newsk->retransmits, 0); newsk->linger=0; newsk->destroy = 0; diff -u --recursive v2.1.35/linux/net/unix/af_unix.c linux/net/unix/af_unix.c --- v2.1.35/linux/net/unix/af_unix.c Mon Apr 14 16:28:29 1997 +++ linux/net/unix/af_unix.c Fri Apr 18 10:53:54 1997 @@ -936,6 +936,7 @@ if (scm->fp) unix_attach_fds(scm, skb); + skb->h.raw = skb->data; memcpy_fromiovec(skb_put(skb,len), msg->msg_iov, len); other = unix_peer(sk);