]> git.neil.brown.name Git - history.git/commitdiff
Import 2.3.99pre10-1 2.3.99pre10-1
authorLinus Torvalds <torvalds@linuxfoundation.org>
Fri, 23 Nov 2007 20:35:07 +0000 (15:35 -0500)
committerLinus Torvalds <torvalds@linuxfoundation.org>
Fri, 23 Nov 2007 20:35:07 +0000 (15:35 -0500)
60 files changed:
CREDITS
Documentation/Configure.help
Documentation/DocBook/Makefile
Documentation/usb/ov511.txt
Makefile
arch/i386/config.in
arch/i386/kernel/entry.S
arch/i386/kernel/process.c
arch/i386/kernel/ptrace.c
arch/i386/kernel/setup.c
arch/i386/kernel/signal.c
arch/i386/kernel/traps.c
arch/sparc/kernel/Makefile
arch/sparc64/defconfig
arch/sparc64/kernel/Makefile
arch/sparc64/kernel/ioctl32.c
arch/sparc64/kernel/sparc64_ksyms.c
arch/sparc64/mm/modutil.c
drivers/char/Config.in
drivers/char/videodev.c
drivers/ide/Config.in
drivers/ide/Makefile
drivers/ide/hd.c
drivers/ide/ide-features.c
drivers/ide/ide-geometry.c
drivers/ide/ide-probe.c
drivers/ide/ide-tape.c
drivers/ide/ide.c
drivers/ide/piix.c
drivers/ide/via82cxxx.c
drivers/sound/es1370.c
drivers/sound/es1371.c
drivers/sound/esssolo1.c
drivers/sound/sonicvibes.c
drivers/usb/audio.c
drivers/usb/ibmcam.c
drivers/usb/ov511.c
fs/nfs/flushd.c
fs/nfs/inode.c
fs/nfs/write.c
fs/nfsd/nfscache.c
fs/partitions/msdos.c
fs/super.c
fs/ufs/super.c
include/asm-alpha/ide.h
include/asm-i386/ide.h
include/asm-i386/processor.h
include/asm-i386/sigcontext.h
include/asm-i386/user.h
include/asm-ia64/ide.h
include/asm-sh/ide.h
include/asm-sparc/ide.h
include/asm-sparc64/ide.h
include/linux/nfs_flushd.h
include/linux/pci_ids.h
include/linux/ufs_fs.h
kernel/ksyms.c
net/ipv6/netfilter/Config.in
scripts/kernel-doc
scripts/mkdep.c

diff --git a/CREDITS b/CREDITS
index 868858e140457c6e3d45b10ee4fc554ccaf7d74e..b0f58d59646e8b868fabe910364ab329242f771b 100644 (file)
--- a/CREDITS
+++ b/CREDITS
@@ -1632,7 +1632,7 @@ N: Claudio S. Matsuoka
 E: claudio@conectiva.com
 E: claudio@helllabs.org
 W: http://helllabs.org/~claudio
-D: OV511 driver hacks
+D: V4L, OV511 driver hacks
 S: Conectiva S.A.
 S: R. Tocantins 89
 S: 80050-430  Curitiba PR
index 4d7b936a3d123452ded77b48f34e75f7c751e241..467327737eb4de7a4d94f571169d761dfca78ba0 100644 (file)
@@ -14830,6 +14830,14 @@ CONFIG_VIDEO_DEV
   whenever you want). If you want to compile it as a module, say M
   here and read Documentation/modules.txt.
 
+Video For Linux /proc file system information
+CONFIG_VIDEO_PROC_FS
+  If you say Y here, you are able to access video device information
+  in /proc/video.
+
+  To use this option, you have to check, that the "/proc file system
+  support" (CONFIG_PROC_FS) is enabled too.
+
 AIMSlab RadioTrack (aka RadioReveal) support
 CONFIG_RADIO_RTRACK
   Choose Y here if you have one of these FM radio cards, and then fill
index 8a40bfade13a2fb75ef598030c99b1ba94b35c58..0f84cb2186f41804c919d60f290125ad6ec57367 100644 (file)
@@ -24,6 +24,12 @@ db2ps db2pdf:
 $(TOPDIR)/scripts/docproc:
        $(MAKE) -C $(TOPDIR)/scripts docproc
 
+kernel-hacking.sgml: kernel-hacking.tmpl
+       $(TOPDIR)/scripts/docgen <$< >$@
+
+kernel-locking.sgml: kernel-locking.tmpl
+       $(TOPDIR)/scripts/docgen <$< >$@
+
 wanbook.sgml: wanbook.tmpl
        $(TOPDIR)/scripts/docgen $(TOPDIR)/drivers/net/wan/syncppp.c \
                <wanbook.tmpl >wanbook.sgml
index d57cc2e236b232cec8716d0aae050f5210b186f8..65a0c4caab3e90edbe828c1b533f114d835845ce 100644 (file)
@@ -6,8 +6,8 @@ Author: Mark McClelland
 Homepage: http://alpha.dyndns.org/ov511
 
 NEW IN THIS VERSION:
- o 352x288 mode
- o force_rgb parameter for apps that expect RGB instead of BGR
+ o 384x288 and 448x336 modes
+ o better /proc/video support
 
 INTRODUCTION:
 
@@ -179,7 +179,7 @@ MODULE PARAMETERS:
         your colors look VERY wrong, you may want to change this.
 
 WORKING FEATURES:
- o Color streaming/capture at 640x480, 352x288, and 320x240
+ o Color streaming/capture at 640x480, 448x336, 384x288, 352x288, and 320x240
  o YUV420 color
  o Monochrome
  o Setting/getting of saturation, contrast and brightness (no hue yet; only
index 0fdbd42a42f73baa90bd7a5dbfd37802166d7717..a2d1995469bb7b250bc996948cd477e4e25eabcd 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,7 @@
 VERSION = 2
-PATCHLEVEL = 3
-SUBLEVEL = 99
-EXTRAVERSION = -pre9
+PATCHLEVEL = 4
+SUBLEVEL = 0
+EXTRAVERSION = -test1
 
 KERNELRELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)
 
@@ -159,8 +159,8 @@ DRIVERS-$(CONFIG_DIO) += drivers/dio/dio.a
 DRIVERS-$(CONFIG_SBUS) += drivers/sbus/sbus.a
 DRIVERS-$(CONFIG_ZORRO) += drivers/zorro/zorro.a
 DRIVERS-$(CONFIG_FC4) += drivers/fc4/fc4.a
-DRIVERS-$(CONFIG_PPC) += drivers/macintosh/macintosh.a
-DRIVERS-$(CONFIG_MAC) += drivers/macintosh/macintosh.a
+DRIVERS-$(CONFIG_PPC) += drivers/macintosh/macintosh.o
+DRIVERS-$(CONFIG_MAC) += drivers/macintosh/macintosh.o
 DRIVERS-$(CONFIG_ISAPNP) += drivers/pnp/pnp.o
 DRIVERS-$(CONFIG_SGI_IP22) += drivers/sgi/sgi.a
 DRIVERS-$(CONFIG_VT) += drivers/video/video.o
@@ -427,7 +427,7 @@ sums:
 
 dep-files: scripts/mkdep archdep include/linux/version.h
        scripts/mkdep init/*.c > .depend
-       scripts/mkdep `find $(FINDHPATH) -follow -name \*.h ! -name modversions.h -print` > .hdepend
+       scripts/mkdep `find $(FINDHPATH) -name SCCS -prune -or -follow -name \*.h ! -name modversions.h -print` > .hdepend
        $(MAKE) $(patsubst %,_sfdep_%,$(SUBDIRS)) _FASTDEP_ALL_SUB_DIRS="$(SUBDIRS)"
 
 ifdef CONFIG_MODVERSIONS
index 1208a6b82a6cc9e221d42066cf2cde1e54b4fc37..5bc10fd501f69beb205ed61f655ea7e20a327c1b 100644 (file)
@@ -23,6 +23,7 @@ choice 'Processor family' \
         586/K5/5x86/6x86/6x86MX        CONFIG_M586     \
         Pentium/TSC            CONFIG_M586TSC  \
         PPro/P-II/P-III        CONFIG_M686 \
+        Pentium-III            CONFIG_M686FX \
         K6/II/III              CONFIG_MK6 \
         Athlon                 CONFIG_MK7" PPro
 #
@@ -60,6 +61,14 @@ if [ "$CONFIG_M686" = "y" ]; then
    define_bool CONFIG_X86_PGE y
    define_bool CONFIG_X86_USE_PPRO_CHECKSUM y
 fi
+if [ "$CONFIG_M686FX" = "y" ]; then
+   define_int  CONFIG_X86_L1_CACHE_BYTES 32
+   define_bool CONFIG_X86_TSC y
+   define_bool CONFIG_X86_GOOD_APIC y
+   define_bool CONFIG_X86_PGE y
+   define_bool CONFIG_X86_USE_PPRO_CHECKSUM y
+   define_bool CONFIG_X86_FX y
+fi
 if [ "$CONFIG_MK6" = "y" ]; then
    define_int  CONFIG_X86_L1_CACHE_BYTES 32
    define_bool CONFIG_X86_ALIGNMENT_16 y
@@ -89,7 +98,9 @@ if [ "$CONFIG_HIGHMEM64G" = "y" ]; then
    define_bool CONFIG_X86_PAE y
 fi
 
-bool 'Math emulation' CONFIG_MATH_EMULATION
+if [ "$CONFIG_X86_FX" != "y" ]; then
+   bool 'Math emulation' CONFIG_MATH_EMULATION
+fi
 bool 'MTRR (Memory Type Range Register) support' CONFIG_MTRR
 bool 'Symmetric multi-processing support' CONFIG_SMP
 if [ "$CONFIG_SMP" != "y" ]; then
index 50887c15c7e0e86cec1c6164e51d14eede853d2c..26f3d505de788545c4e698f126ca6983ab5fb836 100644 (file)
@@ -413,6 +413,11 @@ ENTRY(spurious_interrupt_bug)
        pushl $ SYMBOL_NAME(do_spurious_interrupt_bug)
        jmp error_code
 
+ENTRY(xmm_fault)
+       pushl $0
+       pushl $ SYMBOL_NAME(do_xmm_fault)
+       jmp error_code
+
 .data
 ENTRY(sys_call_table)
        .long SYMBOL_NAME(sys_ni_syscall)       /* 0  -  old "setup()" system call*/
index 96eedb51959bf07a5f9a97e6e3f1deb58cc5ff24..dddd807c8469dedca8a8763df03b1db519abae11 100644 (file)
@@ -2,6 +2,8 @@
  *  linux/arch/i386/kernel/process.c
  *
  *  Copyright (C) 1995  Linus Torvalds
+ *  Pentium III code by Ingo Molnar with changes and support for 
+ *  OS exception support by Goutham Rao
  */
 
 /*
@@ -469,6 +471,94 @@ void copy_segments(struct task_struct *p, struct mm_struct *new_mm)
        return;
 }
 
+#ifdef CONFIG_X86_FX
+
+int i387_hard_to_user ( struct _fpstate * user,
+                       struct i387_hard_struct * hard)
+{
+       int     i, err = 0;
+       short   *tmp, *tmp2;
+       long    *ltmp1, *ltmp2;
+
+       err |= put_user(hard->cwd, &user->cw);
+       err |= put_user(hard->swd, &user->sw);
+       err |= put_user(fputag_KNIto387(hard->twd), &user->tag);
+       err |= put_user(hard->fip, &user->ipoff);
+       err |= put_user(hard->fcs, &user->cssel);
+       err |= put_user(hard->fdp, &user->dataoff);
+       err |= put_user(hard->fds, &user->datasel);
+       err |= put_user(hard->mxcsr, &user->mxcsr);
+
+       tmp = (short *)&user->_st;
+       tmp2 = (short *)&hard->st_space;
+
+       /*
+        * Transform the two layouts:
+        * (we do not mix 32-bit access with 16-bit access because
+        * thats suboptimal on PPros)
+        */
+       for (i = 0; i < 8; i++) 
+       {
+               err |= put_user(*tmp2, tmp); tmp++; tmp2++;
+               err |= put_user(*tmp2, tmp); tmp++; tmp2++;
+               err |= put_user(*tmp2, tmp); tmp++; tmp2++;
+               err |= put_user(*tmp2, tmp); tmp++; tmp2++;
+               err |= put_user(*tmp2, tmp); tmp++; tmp2 += 3;
+       }
+
+       ltmp1 = (unsigned long *)&(user->_xmm[0]);
+       ltmp2 = (unsigned long *)&(hard->xmm_space[0]);
+       for(i = 0; i < 88; i++)
+       {
+               err |= put_user(*ltmp2, ltmp1);
+               ltmp1++; ltmp2++;
+       }
+
+       return err;
+}
+
+int i387_user_to_hard (struct i387_hard_struct * hard,
+                      struct _fpstate * user)
+{
+       int     i, err = 0;
+       short   *tmp, *tmp2;
+       long    *ltmp1, *ltmp2;
+
+       err |= get_user(hard->cwd, &user->cw);
+       err |= get_user(hard->swd, &user->sw);
+       err |= get_user(hard->twd, &user->tag);
+       hard->twd = fputag_387toKNI(hard->twd);
+       err |= get_user(hard->fip, &user->ipoff);
+       err |= get_user(hard->fcs, &user->cssel);
+       err |= get_user(hard->fdp, &user->dataoff);
+       err |= get_user(hard->fds, &user->datasel);
+       err |= get_user(hard->mxcsr, &user->mxcsr);
+
+       tmp2 = (short *)&hard->st_space;
+       tmp = (short *)&user->_st;
+
+       for (i = 0; i < 8; i++) 
+       {
+               err |= get_user(*tmp2, tmp); tmp++; tmp2++;
+               err |= get_user(*tmp2, tmp); tmp++; tmp2++;
+               err |= get_user(*tmp2, tmp); tmp++; tmp2++;
+               err |= get_user(*tmp2, tmp); tmp++; tmp2++;
+               err |= get_user(*tmp2, tmp); tmp++; tmp2 += 3;
+       }
+
+       ltmp1 = (unsigned long *)(&user->_xmm[0]);
+       ltmp2 = (unsigned long *)(&hard->xmm_space[0]);
+       for(i = 0; i < (88); i++)
+       {
+               err |= get_user(*ltmp2, ltmp1);
+               ltmp2++; ltmp1++;
+       }
+
+       return err;
+}
+
+#endif
+
 /*
  * Save a segment.
  */
index de965615045c9eff01374cd729a4f3abd2157ab0..01edbc37afcfa07a03e647c57f80fc84bb77be2f 100644 (file)
@@ -1,5 +1,6 @@
 /* ptrace.c */
 /* By Ross Biro 1/23/92 */
+/* FXSAVE/FXRSTOR support by Ingo Molnar and modifications by Goutham Rao */
 /* edited by Linus Torvalds */
 
 #include <linux/config.h> /* for CONFIG_MATH_EMULATION */
@@ -398,14 +399,14 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
                ret = 0;
                if ( !child->used_math ) {
                        /* Simulate an empty FPU. */
-                       child->thread.i387.hard.cwd = 0xffff037f;
-                       child->thread.i387.hard.swd = 0xffff0000;
-                       child->thread.i387.hard.twd = 0xffffffff;
-               }
+                       i387_set_cwd(child->thread.i387.hard, 0x037f);
+                       i387_set_swd(child->thread.i387.hard, 0x0000);
+                       i387_set_twd(child->thread.i387.hard, 0xffff);
+       }
 #ifdef CONFIG_MATH_EMULATION
                if ( boot_cpu_data.hard_math ) {
 #endif
-                       __copy_to_user((void *)data, &child->thread.i387.hard, sizeof(struct user_i387_struct));
+                       i387_hard_to_user((struct _fpstate *)data, &child->thread.i387.hard);
 #ifdef CONFIG_MATH_EMULATION
                } else {
                        save_i387_soft(&child->thread.i387.soft, (struct _fpstate *)data);
@@ -423,7 +424,7 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
 #ifdef CONFIG_MATH_EMULATION
                if ( boot_cpu_data.hard_math ) {
 #endif
-                       __copy_from_user(&child->thread.i387.hard, (void *)data, sizeof(struct user_i387_struct));
+                       i387_user_to_hard(&child->thread.i387.hard,(struct _fpstate *)data);
 #ifdef CONFIG_MATH_EMULATION
                } else {
                        restore_i387_soft(&child->thread.i387.soft, (struct _fpstate *)data);
index 358d9f91764eff7f3aa55521e26ea904ce56c956..6a1e10f104d3bcdef0ed2439d90a3567551beaf0 100644 (file)
@@ -39,7 +39,8 @@
  *  Detection for Celeron coppermine, identify_cpu() overhauled,
  *  and a few other clean ups.
  *  Dave Jones <dave@powertweak.com>, April 2000
- *     
+ *  Pentium-III code by Ingo Molnar and modifications by Goutham Rao
+ *
  */
 
 /*
@@ -800,6 +801,20 @@ void __init setup_arch(char **cmdline_p)
        conswitchp = &dummy_con;
 #endif
 #endif
+#ifdef CONFIG_X86_FX
+       if (boot_cpu_data.x86_capability & X86_FEATURE_FXSR)
+       {
+               printk("Enabling extended fast FPU save and restore ... ");
+               set_in_cr4(X86_CR4_OSFXSR);
+               printk("done.\n");
+       }
+       if (boot_cpu_data.x86_capability & X86_FEATURE_XMM) 
+       {
+               printk("Enabling KNI unmasked exception support ... ");
+               set_in_cr4(X86_CR4_OSXMMEXCPT);
+               printk("done.\n");
+       }
+#endif
 }
 
 static int __init get_model_name(struct cpuinfo_x86 *c)
@@ -1513,7 +1528,9 @@ int get_cpuinfo(char * buffer)
 
                    case X86_VENDOR_INTEL:
                                x86_cap_flags[16] = "pat";
+                               x86_cap_flags[18] = "pn";
                                x86_cap_flags[24] = "fxsr";
+                               x86_cap_flags[25] = "xmm";
                                break;
 
                    case X86_VENDOR_CENTAUR:
index 4e813fac7cdf8c8d6084a5e5f05791b851fedb20..9ae16467294c005b365d90c8fc1a727cc9c51843 100644 (file)
@@ -4,6 +4,8 @@
  *  Copyright (C) 1991, 1992  Linus Torvalds
  *
  *  1997-11-28  Modified for POSIX.1b signals by Richard Henderson
+ *  Pentium III support by Ingo Molnar, modifications and OS Exception support
+ *              by Goutham Rao
  */
 
 #include <linux/config.h>
@@ -155,7 +157,7 @@ static inline int restore_i387_hard(struct _fpstate *buf)
 {
        struct task_struct *tsk = current;
        clear_fpu(tsk);
-       return __copy_from_user(&tsk->thread.i387.hard, buf, sizeof(*buf));
+       return i387_user_to_hard(&tsk->thread.i387.hard, buf);
 }
 
 static inline int restore_i387(struct _fpstate *buf)
@@ -309,7 +311,7 @@ static inline int save_i387_hard(struct _fpstate * buf)
 
        unlazy_fpu(tsk);
        tsk->thread.i387.hard.status = tsk->thread.i387.hard.swd;
-       if (__copy_to_user(buf, &tsk->thread.i387.hard, sizeof(*buf)))
+       if (i387_hard_to_user(buf, &tsk->thread.i387.hard))
                return -1;
        return 1;
 }
index 7fb5ebc6114055405d413a3e4828c4cd2b785937..7e2986134fa37c6f912ff8c2f5af49ae8273a15a 100644 (file)
@@ -2,6 +2,7 @@
  *  linux/arch/i386/traps.c
  *
  *  Copyright (C) 1991, 1992  Linus Torvalds
+ *  FXSAVE/FXRSTOR support by Ingo Molnar, OS exception support by Goutham Rao
  */
 
 /*
@@ -120,6 +121,7 @@ asmlinkage void coprocessor_error(void);
 asmlinkage void reserved(void);
 asmlinkage void alignment_check(void);
 asmlinkage void spurious_interrupt_bug(void);
+asmlinkage void xmm_fault(void);
 
 int kstack_depth_to_print = 24;
 
@@ -273,21 +275,7 @@ DO_ERROR(11, SIGBUS,  "segment not present", segment_not_present, current)
 DO_ERROR(12, SIGBUS,  "stack segment", stack_segment, current)
 DO_ERROR(17, SIGSEGV, "alignment check", alignment_check, current)
 DO_ERROR(18, SIGSEGV, "reserved", reserved, current)
-/* I don't have documents for this but it does seem to cover the cache
-   flush from user space exception some people get. */
-DO_ERROR(19, SIGSEGV, "cache flush denied", cache_flush_denied, current)
-
-asmlinkage void cache_flush_denied(struct pt_regs * regs, long error_code)
-{
-       if (regs->eflags & VM_MASK) {
-               handle_vm86_fault((struct kernel_vm86_regs *) regs, error_code);
-               return;
-       }
-       die_if_kernel("cache flush denied",regs,error_code);
-       current->thread.error_code = error_code;
-       current->thread.trap_no = 19;
-       force_sig(SIGSEGV, current);
-}
+DO_VM86_ERROR(19, SIGFPE, "XMM fault", xmm_fault, current)
 
 asmlinkage void do_general_protection(struct pt_regs * regs, long error_code)
 {
@@ -586,7 +574,7 @@ asmlinkage void math_state_restore(struct pt_regs regs)
        __asm__ __volatile__("clts");           /* Allow maths ops (or we recurse) */
 
        if(current->used_math)
-               __asm__("frstor %0": :"m" (current->thread.i387));
+               i387_restore_hard(current->thread.i387);
        else
        {
                /*
@@ -829,6 +817,8 @@ void __init trap_init(void)
        set_trap_gate(15,&spurious_interrupt_bug);
        set_trap_gate(16,&coprocessor_error);
        set_trap_gate(17,&alignment_check);
+       set_trap_gate(19,&xmm_fault);
+
        set_system_gate(SYSCALL_VECTOR,&system_call);
 
        /*
index f63f542bad559782b220838b76bf5346bef535fd..e8524e430e0c27009b31c83a481ac69dbf7614b4 100644 (file)
@@ -1,4 +1,4 @@
-# $Id: Makefile,v 1.54 2000/05/12 23:51:24 davem Exp $
+# $Id: Makefile,v 1.55 2000/05/23 23:09:08 davem Exp $
 # Makefile for the linux kernel.
 #
 # Note! Dependencies are done automagically by 'make dep', which also
index 135ee279eea304edc241369f0aac2ec0fff6d7d7..2800d1bd57104788d6ef3a662cb781e926e1f067 100644 (file)
@@ -201,6 +201,13 @@ CONFIG_BLK_DEV_IDE=y
 # CONFIG_BLK_DEV_HD is not set
 CONFIG_BLK_DEV_IDEDISK=y
 # CONFIG_IDEDISK_MULTI_MODE is not set
+# CONFIG_BLK_DEV_IDEDISK_VENDOR is not set
+# CONFIG_BLK_DEV_IDEDISK_FUJITSU is not set
+# CONFIG_BLK_DEV_IDEDISK_IBM is not set
+# CONFIG_BLK_DEV_IDEDISK_MAXTOR is not set
+# CONFIG_BLK_DEV_IDEDISK_QUANTUM is not set
+# CONFIG_BLK_DEV_IDEDISK_SEAGATE is not set
+# CONFIG_BLK_DEV_IDEDISK_WD is not set
 # CONFIG_BLK_DEV_IDECS is not set
 CONFIG_BLK_DEV_IDECD=y
 CONFIG_BLK_DEV_IDETAPE=m
index edb6b05718aa68067182577cd43e9c0150b5d866..df823619ca9a62fe3a672ebdf30daff1ce4d37d2 100644 (file)
@@ -81,13 +81,11 @@ check_asm: dummy
        @echo -e "#  error Please issue 'make check_asm' in linux top-level directory first\n# endif\n#endif\n" >> asm_offsets.h
        @echo -e "#ifndef CONFIG_SMP\n" >> asm_offsets.h
        @echo "#include <linux/config.h>" > tmp.c
-       @echo "#undef __SMP__" >> tmp.c
        @echo "#undef CONFIG_SMP" >> tmp.c
        @echo "#include <linux/sched.h>" >> tmp.c
        $(CPP) $(CPPFLAGS) tmp.c -o tmp.i
        @echo "/* Automatically generated. Do not edit. */" > check_asm.c
        @echo "#include <linux/config.h>" >> check_asm.c
-       @echo "#undef __SMP__" >> check_asm.c
        @echo "#undef CONFIG_SMP" >> check_asm.c
        @echo "#include <linux/sched.h>" >> check_asm.c
        @echo 'struct task_struct _task;' >> check_asm.c
@@ -128,7 +126,7 @@ check_asm: dummy
        $(SH) ./check_asm.sh thread tmp.i check_asm.c
        @echo 'return 0; }' >> check_asm.c
        @rm -f tmp.[ci]
-       #$(CC) -D__SMP__ -o check_asm check_asm.c
+       #$(CC) -o check_asm check_asm.c
        # <hack> Until we can do this natively, a hack has to take place
        $(CC) $(CPPFLAGS) $(CMODEL_CFLAG) -ffixed-g4 -S -o check_asm.s check_asm.c
        $(HOSTCC) -Wa,-Av9a -o check_asm check_asm.s
@@ -153,7 +151,7 @@ check_asm: dummy
        $(SH) ./check_asm.sh thread tmp.i check_asm.c
        @echo 'return 0; }' >> check_asm.c
        @rm -f tmp.[ci]
-       #$(CC) -D__SMP__ -DSPIN_LOCK_DEBUG -o check_asm check_asm.c
+       #$(CC) -DSPIN_LOCK_DEBUG -o check_asm check_asm.c
        # <hack> Until we can do this natively, a hack has to take place
        $(CC) $(CPPFLAGS) -DSPIN_LOCK_DEBUG $(CMODEL_CFLAG) -ffixed-g4 -S -o check_asm.s check_asm.c
        $(HOSTCC) -Wa,-Av9a -o check_asm check_asm.s
index 6c00ba2f69c0c30ec25a766fb9b7fa41b0c54ff3..9f5626b5bc3ecb7925eae9b511edd30e798c4b44 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: ioctl32.c,v 1.90 2000/05/22 07:29:39 davem Exp $
+/* $Id: ioctl32.c,v 1.91 2000/05/23 05:25:44 davem Exp $
  * ioctl32.c: Conversion between 32bit and 64bit native ioctls.
  *
  * Copyright (C) 1997-2000  Jakub Jelinek  (jakub@redhat.com)
@@ -2353,6 +2353,542 @@ static int do_lvm_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg)
 }
 #endif
 
+#if defined(CONFIG_DRM) || defined(CONFIG_DRM_MODULE)
+/* This really belongs in include/linux/drm.h -DaveM */
+#include "../../../drivers/char/drm/drm.h"
+
+typedef struct drm32_version {
+       int    version_major;     /* Major version                          */
+       int    version_minor;     /* Minor version                          */
+       int    version_patchlevel;/* Patch level                            */
+       int    name_len;          /* Length of name buffer                  */
+       u32    name;              /* Name of driver                         */
+       int    date_len;          /* Length of date buffer                  */
+       u32    date;              /* User-space buffer to hold date         */
+       int    desc_len;          /* Length of desc buffer                  */
+       u32    desc;              /* User-space buffer to hold desc         */
+} drm32_version_t;
+#define DRM32_IOCTL_VERSION    DRM_IOWR(0x00, drm32_version_t)
+
+static int drm32_version(unsigned int fd, unsigned int cmd, unsigned long arg)
+{
+       drm32_version_t *uversion = (drm32_version_t *)arg;
+       char *name_ptr, *date_ptr, *desc_ptr;
+       u32 tmp1, tmp2, tmp3;
+       drm_version_t kversion;
+       mm_segment_t old_fs;
+       int ret;
+
+       memset(&kversion, 0, sizeof(kversion));
+       if (get_user(kversion.name_len, &uversion->name_len) ||
+           get_user(kversion.date_len, &uversion->date_len) ||
+           get_user(kversion.desc_len, &uversion->desc_len) ||
+           get_user(tmp1, &uversion->name) ||
+           get_user(tmp2, &uversion->date) ||
+           get_user(tmp3, &uversion->desc))
+               return -EFAULT;
+
+       name_ptr = (char *) A(tmp1);
+       date_ptr = (char *) A(tmp2);
+       desc_ptr = (char *) A(tmp3);
+
+       ret = -ENOMEM;
+       if (kversion.name_len && name_ptr) {
+               kversion.name = kmalloc(kversion.name_len, GFP_KERNEL);
+               if (!kversion.name)
+                       goto out;
+       }
+       if (kversion.date_len && date_ptr) {
+               kversion.date = kmalloc(kversion.date_len, GFP_KERNEL);
+               if (!kversion.date)
+                       goto out;
+       }
+       if (kversion.desc_len && desc_ptr) {
+               kversion.desc = kmalloc(kversion.desc_len, GFP_KERNEL);
+               if (!kversion.desc)
+                       goto out;
+       }
+
+        old_fs = get_fs();
+       set_fs(KERNEL_DS);
+        ret = sys_ioctl (fd, DRM_IOCTL_VERSION, (unsigned long)&kversion);
+        set_fs(old_fs);
+
+       if (!ret) {
+               if ((kversion.name &&
+                    copy_to_user(name_ptr, kversion.name, kversion.name_len)) ||
+                   (kversion.date &&
+                    copy_to_user(date_ptr, kversion.date, kversion.date_len)) ||
+                   (kversion.desc &&
+                    copy_to_user(desc_ptr, kversion.desc, kversion.desc_len)))
+                       ret = -EFAULT;
+               if (put_user(kversion.version_major, &uversion->version_major) ||
+                   put_user(kversion.version_minor, &uversion->version_minor) ||
+                   put_user(kversion.version_patchlevel, &uversion->version_patchlevel) ||
+                   put_user(kversion.name_len, &uversion->name_len) ||
+                   put_user(kversion.date_len, &uversion->date_len) ||
+                   put_user(kversion.desc_len, &uversion->desc_len))
+                       ret = -EFAULT;
+       }
+
+out:
+       if (kversion.name)
+               kfree(kversion.name);
+       if (kversion.date)
+               kfree(kversion.date);
+       if (kversion.desc)
+               kfree(kversion.desc);
+       return ret;
+}
+
+typedef struct drm32_unique {
+       size_t unique_len;        /* Length of unique                       */
+       u32    unique;            /* Unique name for driver instantiation   */
+} drm32_unique_t;
+#define DRM32_IOCTL_GET_UNIQUE DRM_IOWR(0x01, drm32_unique_t)
+#define DRM32_IOCTL_SET_UNIQUE DRM_IOW( 0x10, drm32_unique_t)
+
+static int drm32_getsetunique(unsigned int fd, unsigned int cmd, unsigned long arg)
+{
+       drm32_unique_t *uarg = (drm32_unique_t *)arg;
+       drm_unique_t karg;
+       mm_segment_t old_fs;
+       char *uptr;
+       u32 tmp;
+       int ret;
+
+       if (get_user(karg.unique_len, &uarg->unique_len))
+               return -EFAULT;
+       karg.unique = NULL;
+
+       if (get_user(tmp, &uarg->unique))
+               return -EFAULT;
+
+       uptr = (char *) A(tmp);
+
+       if (uptr) {
+               karg.unique = kmalloc(karg.unique_len, GFP_KERNEL);
+               if (!karg.unique)
+                       return -ENOMEM;
+               if (cmd == DRM32_IOCTL_SET_UNIQUE &&
+                   copy_from_user(karg.unique, uptr, karg.unique_len)) {
+                       kfree(karg.unique);
+                       return -EFAULT;
+               }
+       }
+
+       old_fs = get_fs();
+       set_fs(KERNEL_DS);
+       if (cmd == DRM32_IOCTL_GET_UNIQUE)
+               ret = sys_ioctl (fd, DRM_IOCTL_GET_UNIQUE, (unsigned long)&karg);
+       else
+               ret = sys_ioctl (fd, DRM_IOCTL_SET_UNIQUE, (unsigned long)&karg);
+        set_fs(old_fs);
+
+       if (!ret) {
+               if (cmd == DRM32_IOCTL_GET_UNIQUE &&
+                   copy_to_user(uptr, karg.unique, karg.unique_len))
+                       ret = -EFAULT;
+               if (put_user(karg.unique_len, &uarg->unique_len))
+                       ret = -EFAULT;
+       }
+
+       kfree(karg.unique);
+
+       return ret;
+}
+
+typedef struct drm32_map {
+       u32             offset;  /* Requested physical address (0 for SAREA)*/
+       u32             size;    /* Requested physical size (bytes)         */
+       drm_map_type_t  type;    /* Type of memory to map                   */
+       drm_map_flags_t flags;   /* Flags                                   */
+       u32             handle;  /* User-space: "Handle" to pass to mmap    */
+                                /* Kernel-space: kernel-virtual address    */
+       int             mtrr;    /* MTRR slot used                          */
+                                /* Private data                            */
+} drm32_map_t;
+#define DRM32_IOCTL_ADD_MAP    DRM_IOWR(0x15, drm32_map_t)
+
+static int drm32_addmap(unsigned int fd, unsigned int cmd, unsigned long arg)
+{
+       drm32_map_t *uarg = (drm32_map_t *) arg;
+       drm_map_t karg;
+       mm_segment_t old_fs;
+       u32 tmp;
+       int ret;
+
+       ret  = get_user(karg.offset, &uarg->offset);
+       ret |= get_user(karg.size, &uarg->size);
+       ret |= get_user(karg.type, &uarg->type);
+       ret |= get_user(karg.flags, &uarg->flags);
+       ret |= get_user(tmp, &uarg->handle);
+       ret |= get_user(karg.mtrr, &uarg->mtrr);
+       if (ret)
+               return -EFAULT;
+
+       karg.handle = (void *) A(tmp);
+
+       old_fs = get_fs();
+       set_fs(KERNEL_DS);
+       ret = sys_ioctl(fd, DRM_IOCTL_ADD_MAP, (unsigned long) &karg);
+       set_fs(old_fs);
+
+       if (!ret) {
+               ret  = put_user(karg.offset, &uarg->offset);
+               ret |= put_user(karg.size, &uarg->size);
+               ret |= put_user(karg.type, &uarg->type);
+               ret |= put_user(karg.flags, &uarg->flags);
+               tmp = (u32) (long)karg.handle;
+               ret |= put_user(tmp, &uarg->handle);
+               ret |= put_user(karg.mtrr, &uarg->mtrr);
+               if (ret)
+                       ret = -EFAULT;
+       }
+
+       return ret;
+}
+
+typedef struct drm32_buf_info {
+       int            count;   /* Entries in list                           */
+       u32            list;    /* (drm_buf_desc_t *) */ 
+} drm32_buf_info_t;
+#define DRM32_IOCTL_INFO_BUFS  DRM_IOWR(0x18, drm32_buf_info_t)
+
+static int drm32_info_bufs(unsigned int fd, unsigned int cmd, unsigned long arg)
+{
+       drm32_buf_info_t *uarg = (drm32_buf_info_t *)arg;
+       drm_buf_desc_t *ulist;
+       drm_buf_info_t karg;
+       mm_segment_t old_fs;
+       int orig_count, ret;
+       u32 tmp;
+
+       if (get_user(karg.count, &uarg->count) ||
+           get_user(tmp, &uarg->list))
+               return -EFAULT;
+
+       ulist = (drm_buf_desc_t *) A(tmp);
+
+       orig_count = karg.count;
+
+       karg.list = kmalloc(karg.count * sizeof(drm_buf_desc_t), GFP_KERNEL);
+       if (!karg.list)
+               return -EFAULT;
+
+       old_fs = get_fs();
+       set_fs(KERNEL_DS);
+       ret = sys_ioctl(fd, DRM_IOCTL_INFO_BUFS, (unsigned long) &karg);
+       set_fs(old_fs);
+
+       if (!ret) {
+               if (karg.count <= orig_count &&
+                   (copy_to_user(ulist, karg.list,
+                                 karg.count * sizeof(drm_buf_desc_t))))
+                       ret = -EFAULT;
+               if (put_user(karg.count, &uarg->count))
+                       ret = -EFAULT;
+       }
+
+       kfree(karg.list);
+
+       return ret;
+}
+
+typedef struct drm32_buf_free {
+       int            count;
+       u32            list;    /* (int *) */
+} drm32_buf_free_t;
+#define DRM32_IOCTL_FREE_BUFS  DRM_IOW( 0x1a, drm32_buf_free_t)
+
+static int drm32_free_bufs(unsigned int fd, unsigned int cmd, unsigned long arg)
+{
+       drm32_buf_free_t *uarg = (drm32_buf_free_t *)arg;
+       drm_buf_free_t karg;
+       mm_segment_t old_fs;
+       int *ulist;
+       int ret;
+       u32 tmp;
+
+       if (get_user(karg.count, &uarg->count) ||
+           get_user(tmp, &uarg->list))
+               return -EFAULT;
+
+       ulist = (int *) A(tmp);
+
+       karg.list = kmalloc(karg.count * sizeof(int), GFP_KERNEL);
+       if (!karg.list)
+               return -ENOMEM;
+
+       ret = -EFAULT;
+       if (copy_from_user(karg.list, ulist, (karg.count * sizeof(int))))
+               goto out;
+
+       old_fs = get_fs();
+       set_fs(KERNEL_DS);
+       ret = sys_ioctl(fd, DRM_IOCTL_FREE_BUFS, (unsigned long) &karg);
+       set_fs(old_fs);
+
+out:
+       kfree(karg.list);
+
+       return ret;
+}
+
+typedef struct drm32_buf_pub {
+       int               idx;         /* Index into master buflist          */
+       int               total;       /* Buffer size                        */
+       int               used;        /* Amount of buffer in use (for DMA)  */
+       u32               address;     /* Address of buffer (void *)         */
+} drm32_buf_pub_t;
+
+typedef struct drm32_buf_map {
+       int           count;    /* Length of buflist                        */
+       u32           virtual;  /* Mmaped area in user-virtual (void *)     */
+       u32           list;     /* Buffer information (drm_buf_pub_t *)     */
+} drm32_buf_map_t;
+#define DRM32_IOCTL_MAP_BUFS   DRM_IOWR(0x19, drm32_buf_map_t)
+
+static int drm32_map_bufs(unsigned int fd, unsigned int cmd, unsigned long arg)
+{
+       drm32_buf_map_t *uarg = (drm32_buf_map_t *)arg;
+       drm32_buf_pub_t *ulist;
+       drm_buf_map_t karg;
+       mm_segment_t old_fs;
+       int orig_count, ret, i;
+       u32 tmp1, tmp2;
+
+       if (get_user(karg.count, &uarg->count) ||
+           get_user(tmp1, &uarg->virtual) ||
+           get_user(tmp2, &uarg->list))
+               return -EFAULT;
+
+       karg.virtual = (void *) A(tmp1);
+       ulist = (drm32_buf_pub_t *) A(tmp2);
+
+       orig_count = karg.count;
+
+       karg.list = kmalloc(karg.count * sizeof(drm_buf_pub_t), GFP_KERNEL);
+       if (!karg.list)
+               return -ENOMEM;
+
+       ret = -EFAULT;
+       for (i = 0; i < karg.count; i++) {
+               if (get_user(karg.list[i].idx, &ulist[i].idx) ||
+                   get_user(karg.list[i].total, &ulist[i].total) ||
+                   get_user(karg.list[i].used, &ulist[i].used) ||
+                   get_user(tmp1, &ulist[i].address))
+                       goto out;
+
+               karg.list[i].address = (void *) A(tmp1);
+       }
+
+       old_fs = get_fs();
+       set_fs(KERNEL_DS);
+       ret = sys_ioctl(fd, DRM_IOCTL_MAP_BUFS, (unsigned long) &karg);
+       set_fs(old_fs);
+
+       if (!ret) {
+               for (i = 0; i < orig_count; i++) {
+                       tmp1 = (u32) (long) karg.list[i].address;
+                       if (put_user(karg.list[i].idx, &ulist[i].idx) ||
+                           put_user(karg.list[i].total, &ulist[i].total) ||
+                           put_user(karg.list[i].used, &ulist[i].used) ||
+                           put_user(tmp1, &ulist[i].address)) {
+                               ret = -EFAULT;
+                               goto out;
+                       }
+               }
+               if (put_user(karg.count, &uarg->count))
+                       ret = -EFAULT;
+       }
+
+out:
+       kfree(karg.list);
+       return ret;
+}
+
+typedef struct drm32_dma {
+                               /* Indices here refer to the offset into
+                                  buflist in drm_buf_get_t.  */
+       int             context;          /* Context handle                 */
+       int             send_count;       /* Number of buffers to send      */
+       u32             send_indices;     /* List of handles to buffers (int *) */
+       u32             send_sizes;       /* Lengths of data to send (int *) */
+       drm_dma_flags_t flags;            /* Flags                          */
+       int             request_count;    /* Number of buffers requested    */
+       int             request_size;     /* Desired size for buffers       */
+       u32             request_indices;  /* Buffer information (int *)     */
+       u32             request_sizes;    /* (int *) */
+       int             granted_count;    /* Number of buffers granted      */
+} drm32_dma_t;
+#define DRM32_IOCTL_DMA             DRM_IOWR(0x29, drm32_dma_t)
+
+/* RED PEN     The DRM layer blindly dereferences the send/request
+ *             indice/size arrays even though they are userland
+ *             pointers.  -DaveM
+ */
+static int drm32_dma(unsigned int fd, unsigned int cmd, unsigned long arg)
+{
+       drm32_dma_t *uarg = (drm32_dma_t *) arg;
+       int *u_si, *u_ss, *u_ri, *u_rs;
+       drm_dma_t karg;
+       mm_segment_t old_fs;
+       int ret;
+       u32 tmp1, tmp2, tmp3, tmp4;
+
+       karg.send_indices = karg.send_sizes = NULL;
+       karg.request_indices = karg.request_sizes = NULL;
+
+       if (get_user(karg.context, &uarg->context) ||
+           get_user(karg.send_count, &uarg->send_count) ||
+           get_user(tmp1, &uarg->send_indices) ||
+           get_user(tmp2, &uarg->send_sizes) ||
+           get_user(karg.flags, &uarg->flags) ||
+           get_user(karg.request_count, &uarg->request_count) ||
+           get_user(karg.request_size, &uarg->request_size) ||
+           get_user(tmp3, &uarg->request_indices) ||
+           get_user(tmp4, &uarg->request_sizes) ||
+           get_user(karg.granted_count, &uarg->granted_count))
+               return -EFAULT;
+
+       u_si = (int *) A(tmp1);
+       u_ss = (int *) A(tmp2);
+       u_ri = (int *) A(tmp3);
+       u_rs = (int *) A(tmp4);
+
+       if (karg.send_count) {
+               karg.send_indices = kmalloc(karg.send_count * sizeof(int), GFP_KERNEL);
+               karg.send_sizes = kmalloc(karg.send_count * sizeof(int), GFP_KERNEL);
+
+               ret = -ENOMEM;
+               if (!karg.send_indices || !karg.send_sizes)
+                       goto out;
+
+               ret = -EFAULT;
+               if (copy_from_user(karg.send_indices, u_si,
+                                  (karg.send_count * sizeof(int))) ||
+                   copy_from_user(karg.send_sizes, u_ss,
+                                  (karg.send_count * sizeof(int))))
+                       goto out;
+       }
+
+       if (karg.request_count) {
+               karg.request_indices = kmalloc(karg.request_count * sizeof(int), GFP_KERNEL);
+               karg.request_sizes = kmalloc(karg.request_count * sizeof(int), GFP_KERNEL);
+
+               ret = -ENOMEM;
+               if (!karg.request_indices || !karg.request_sizes)
+                       goto out;
+
+               ret = -EFAULT;
+               if (copy_from_user(karg.request_indices, u_ri,
+                                  (karg.request_count * sizeof(int))) ||
+                   copy_from_user(karg.request_sizes, u_rs,
+                                  (karg.request_count * sizeof(int))))
+                       goto out;
+       }
+
+       old_fs = get_fs();
+       set_fs(KERNEL_DS);
+       ret = sys_ioctl(fd, DRM_IOCTL_DMA, (unsigned long) &karg);
+       set_fs(old_fs);
+
+       if (!ret) {
+               if (put_user(karg.context, &uarg->context) ||
+                   put_user(karg.send_count, &uarg->send_count) ||
+                   put_user(karg.flags, &uarg->flags) ||
+                   put_user(karg.request_count, &uarg->request_count) ||
+                   put_user(karg.request_size, &uarg->request_size) ||
+                   put_user(karg.granted_count, &uarg->granted_count))
+                       ret = -EFAULT;
+
+               if (karg.send_count) {
+                       if (copy_to_user(u_si, karg.send_indices,
+                                        (karg.send_count * sizeof(int))) ||
+                           copy_to_user(u_ss, karg.send_sizes,
+                                        (karg.send_count * sizeof(int))))
+                               ret = -EFAULT;
+               }
+               if (karg.request_count) {
+                       if (copy_to_user(u_ri, karg.request_indices,
+                                        (karg.request_count * sizeof(int))) ||
+                           copy_to_user(u_rs, karg.request_sizes,
+                                        (karg.request_count * sizeof(int))))
+                               ret = -EFAULT;
+               }
+       }
+
+out:
+       if (karg.send_indices)
+               kfree(karg.send_indices);
+       if (karg.send_sizes)
+               kfree(karg.send_sizes);
+       if (karg.request_indices)
+               kfree(karg.request_indices);
+       if (karg.request_sizes)
+               kfree(karg.request_sizes);
+
+       return ret;
+}
+
+typedef struct drm32_ctx_res {
+       int             count;
+       u32             contexts; /* (drm_ctx_t *) */
+} drm32_ctx_res_t;
+#define DRM32_IOCTL_RES_CTX    DRM_IOWR(0x26, drm_ctx_res_t)
+
+static int drm32_res_ctx(unsigned int fd, unsigned int cmd, unsigned long arg)
+{
+       drm32_ctx_res_t *uarg = (drm32_ctx_res_t *) arg;
+       drm_ctx_t *ulist;
+       drm_ctx_res_t karg;
+       mm_segment_t old_fs;
+       int orig_count, ret;
+       u32 tmp;
+
+       karg.contexts = NULL;
+       if (get_user(karg.count, &uarg->count) ||
+           get_user(tmp, &uarg->contexts))
+               return -EFAULT;
+
+       ulist = (drm_ctx_t *) A(tmp);
+
+       orig_count = karg.count;
+       if (karg.count && ulist) {
+               karg.contexts = kmalloc((karg.count * sizeof(drm_ctx_t)), GFP_KERNEL);
+               if (!karg.contexts)
+                       return -ENOMEM;
+               if (copy_from_user(karg.contexts, ulist,
+                                  (karg.count * sizeof(drm_ctx_t)))) {
+                       kfree(karg.contexts);
+                       return -EFAULT;
+               }
+       }
+
+       old_fs = get_fs();
+       set_fs(KERNEL_DS);
+       ret = sys_ioctl(fd, DRM_IOCTL_RES_CTX, (unsigned long) &karg);
+       set_fs(old_fs);
+
+       if (!ret) {
+               if (orig_count) {
+                       if (copy_to_user(ulist, karg.contexts,
+                                        (orig_count * sizeof(drm_ctx_t))))
+                               ret = -EFAULT;
+               }
+               if (put_user(karg.count, &uarg->count))
+                       ret = -EFAULT;
+       }
+
+       if (karg.contexts)
+               kfree(karg.contexts);
+
+       return ret;
+}
+
+#endif
+
 static int ret_einval(unsigned int fd, unsigned int cmd, unsigned long arg)
 {
        return -EINVAL;
@@ -2961,6 +3497,27 @@ COMPATIBLE_IOCTL(LV_SET_ACCESS)
 COMPATIBLE_IOCTL(LV_SET_STATUS)
 COMPATIBLE_IOCTL(LV_SET_ALLOCATION)
 #endif /* LVM */
+#if defined(CONFIG_DRM) || defined(CONFIG_DRM_MODULE)
+COMPATIBLE_IOCTL(DRM_IOCTL_GET_MAGIC)
+COMPATIBLE_IOCTL(DRM_IOCTL_IRQ_BUSID)
+COMPATIBLE_IOCTL(DRM_IOCTL_AUTH_MAGIC)
+COMPATIBLE_IOCTL(DRM_IOCTL_BLOCK)
+COMPATIBLE_IOCTL(DRM_IOCTL_UNBLOCK)
+COMPATIBLE_IOCTL(DRM_IOCTL_CONTROL)
+COMPATIBLE_IOCTL(DRM_IOCTL_ADD_BUFS)
+COMPATIBLE_IOCTL(DRM_IOCTL_MARK_BUFS)
+COMPATIBLE_IOCTL(DRM_IOCTL_ADD_CTX)
+COMPATIBLE_IOCTL(DRM_IOCTL_RM_CTX)
+COMPATIBLE_IOCTL(DRM_IOCTL_MOD_CTX)
+COMPATIBLE_IOCTL(DRM_IOCTL_GET_CTX)
+COMPATIBLE_IOCTL(DRM_IOCTL_SWITCH_CTX)
+COMPATIBLE_IOCTL(DRM_IOCTL_NEW_CTX)
+COMPATIBLE_IOCTL(DRM_IOCTL_ADD_DRAW)
+COMPATIBLE_IOCTL(DRM_IOCTL_RM_DRAW)
+COMPATIBLE_IOCTL(DRM_IOCTL_LOCK)
+COMPATIBLE_IOCTL(DRM_IOCTL_UNLOCK)
+COMPATIBLE_IOCTL(DRM_IOCTL_FINISH)
+#endif /* DRM */
 /* elevator */
 COMPATIBLE_IOCTL(BLKELVGET)
 COMPATIBLE_IOCTL(BLKELVSET)
@@ -3108,6 +3665,17 @@ HANDLE_IOCTL(LE_REMAP, do_lvm_ioctl)
 HANDLE_IOCTL(PV_CHANGE, do_lvm_ioctl)
 HANDLE_IOCTL(PV_STATUS, do_lvm_ioctl)
 #endif /* LVM */
+#if defined(CONFIG_DRM) || defined(CONFIG_DRM_MODULE)
+HANDLE_IOCTL(DRM32_IOCTL_VERSION, drm32_version);
+HANDLE_IOCTL(DRM32_IOCTL_GET_UNIQUE, drm32_getsetunique);
+HANDLE_IOCTL(DRM32_IOCTL_SET_UNIQUE, drm32_getsetunique);
+HANDLE_IOCTL(DRM32_IOCTL_ADD_MAP, drm32_addmap);
+HANDLE_IOCTL(DRM32_IOCTL_INFO_BUFS, drm32_info_bufs);
+HANDLE_IOCTL(DRM32_IOCTL_FREE_BUFS, drm32_free_bufs);
+HANDLE_IOCTL(DRM32_IOCTL_MAP_BUFS, drm32_map_bufs);
+HANDLE_IOCTL(DRM32_IOCTL_DMA, drm32_dma);
+HANDLE_IOCTL(DRM32_IOCTL_RES_CTX, drm32_res_ctx);
+#endif /* DRM */
 IOCTL_TABLE_END
 
 unsigned int ioctl32_hash_table[1024];
index 12a872447040f55283a740db30cb15103180276e..942f3764010ae4b7454c05282bb7d68a72b0241d 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: sparc64_ksyms.c,v 1.84 2000/05/09 17:40:14 davem Exp $
+/* $Id: sparc64_ksyms.c,v 1.85 2000/05/23 02:14:25 davem Exp $
  * arch/sparc64/kernel/sparc64_ksyms.c: Sparc64 specific ksyms support.
  *
  * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu)
@@ -83,6 +83,7 @@ extern int (*handle_mathemu)(struct pt_regs *, struct fpustate *);
 extern long sparc32_open(const char * filename, int flags, int mode);
 extern int register_ioctl32_conversion(unsigned int cmd, int (*handler)(unsigned int, unsigned int, unsigned long, struct file *));
 extern int unregister_ioctl32_conversion(unsigned int cmd);
+extern int io_remap_page_range(unsigned long from, unsigned long offset, unsigned long size, pgprot_t prot, int space);
                 
 extern void bcopy (const char *, char *, int);
 extern int __ashrdi3(int, int);
@@ -223,6 +224,9 @@ EXPORT_SYMBOL(pci_dma_supported);
 EXPORT_SYMBOL(register_ioctl32_conversion);
 EXPORT_SYMBOL(unregister_ioctl32_conversion);
 
+/* I/O device mmaping on Sparc64. */
+EXPORT_SYMBOL(io_remap_page_range);
+
 /* Solaris/SunOS binary compatibility */
 EXPORT_SYMBOL(_sigpause_common);
 
index 6d68d7468761509108e265d9277a9c0ecc90c5b0..8ae715c3828ad8c15e25792a1ee02155af603c1c 100644 (file)
@@ -1,4 +1,4 @@
-/*  $Id: modutil.c,v 1.4 1998/07/26 06:29:08 davem Exp $
+/*  $Id: modutil.c,v 1.5 2000/05/23 23:09:08 davem Exp $
  *  arch/sparc64/mm/modutil.c
  *
  *  Copyright (C) 1997,1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
@@ -58,7 +58,7 @@ void * module_map (unsigned long size)
        area->next = *p;
        *p = area;
 
-       if (vmalloc_area_pages(VMALLOC_VMADDR(addr), size)) {
+       if (vmalloc_area_pages(VMALLOC_VMADDR(addr), size, GFP_KERNEL)) {
                vfree(addr);
                return NULL;
        }
index 792832a306e404cf3efdd4cc2afe1349661fa12e..5fed698d65f224969258c8efbac5cd494c0b5acd 100644 (file)
@@ -157,6 +157,7 @@ comment 'Video For Linux'
 
 tristate 'Video For Linux' CONFIG_VIDEO_DEV
 if [ "$CONFIG_VIDEO_DEV" != "n" ]; then
+   bool '  V4L information in proc filesystem' CONFIG_VIDEO_PROC_FS Y
    dep_tristate '  I2C on parallel port' CONFIG_I2C_PARPORT $CONFIG_PARPORT $CONFIG_I2C
    comment 'Radio Adapters'
    dep_tristate '  ADS Cadet AM/FM Tuner' CONFIG_RADIO_CADET $CONFIG_VIDEO_DEV
index 618f02f85d22d4d820533f7b63c064328f06ecd6..98c9e97315e4a6a4af13b320e43dd9452bb744a3 100644 (file)
@@ -11,7 +11,8 @@
  *
  * Author:     Alan Cox, <alan@redhat.com>
  *
- * Fixes:
+ * Fixes:      20000516  Claudio Matsuoka <claudio@conectiva.com>
+ *             - Added procfs support
  */
 
 #include <linux/config.h>
  
 static struct video_device *video_device[VIDEO_NUM_DEVICES];
 
+
+#if defined(CONFIG_PROC_FS) && defined(CONFIG_VIDEO_PROC_FS)
+
+#include <linux/proc_fs.h>
+
+struct videodev_proc_data {
+       struct list_head proc_list;
+       char name[16];
+       struct video_device *vdev;
+       struct proc_dir_entry *proc_entry;
+       struct video_capability vcap;
+};
+
+static struct proc_dir_entry *video_dev_proc_entry = NULL;
+struct proc_dir_entry *video_proc_entry = NULL;
+EXPORT_SYMBOL(video_proc_entry);
+LIST_HEAD(videodev_proc_list);
+
+#endif /* CONFIG_PROC_FS && CONFIG_VIDEO_PROC_FS */
+
+
 #ifdef CONFIG_VIDEO_BT848
 extern int i2c_tuner_init(struct video_init *);
 #endif
@@ -215,6 +237,152 @@ int video_mmap(struct file *file, struct vm_area_struct *vma)
        return -EINVAL;
 }
 
+/*
+ *     /proc support
+ */
+
+#if defined(CONFIG_PROC_FS) && defined(CONFIG_VIDEO_PROC_FS)
+
+/* Hmm... i'd like to see video_capability information here, but
+ * how can I access it (without changing the other drivers? -claudio
+ */
+static int videodev_proc_read(char *page, char **start, off_t off,
+                              int count, int *eof, void *data)
+{
+       char *out = page;
+       struct video_device *vfd = data;
+       struct videodev_proc_data *d;
+       struct list_head *tmp;
+       int len;
+       char c = ' ';
+
+       list_for_each (tmp, &videodev_proc_list) {
+               d = list_entry(tmp, struct videodev_proc_data, proc_list);
+               if (vfd == d->vdev)
+                       break;
+       }
+
+       /* Sanity check */
+       if (tmp == &videodev_proc_list)
+               goto skip;
+               
+#define PRINT_VID_TYPE(x) do { if (vfd->type & x) \
+       out += sprintf (out, "%c%s", c, #x); c='|';} while (0)
+
+       out += sprintf (out, "name            : %s\n", vfd->name);
+       out += sprintf (out, "type            :");
+               PRINT_VID_TYPE(VID_TYPE_CAPTURE);
+               PRINT_VID_TYPE(VID_TYPE_TUNER);
+               PRINT_VID_TYPE(VID_TYPE_TELETEXT);
+               PRINT_VID_TYPE(VID_TYPE_OVERLAY);
+               PRINT_VID_TYPE(VID_TYPE_CHROMAKEY);
+               PRINT_VID_TYPE(VID_TYPE_CLIPPING);
+               PRINT_VID_TYPE(VID_TYPE_FRAMERAM);
+               PRINT_VID_TYPE(VID_TYPE_SCALES);
+               PRINT_VID_TYPE(VID_TYPE_MONOCHROME);
+               PRINT_VID_TYPE(VID_TYPE_SUBCAPTURE);
+               PRINT_VID_TYPE(VID_TYPE_MPEG_DECODER);
+               PRINT_VID_TYPE(VID_TYPE_MPEG_ENCODER);
+               PRINT_VID_TYPE(VID_TYPE_MJPEG_DECODER);
+               PRINT_VID_TYPE(VID_TYPE_MJPEG_ENCODER);
+       out += sprintf (out, "\n");
+       out += sprintf (out, "hardware        : 0x%x\n", vfd->hardware);
+#if 0
+       out += sprintf (out, "channels        : %d\n", d->vcap.channels);
+       out += sprintf (out, "audios          : %d\n", d->vcap.audios);
+       out += sprintf (out, "maxwidth        : %d\n", d->vcap.maxwidth);
+       out += sprintf (out, "maxheight       : %d\n", d->vcap.maxheight);
+       out += sprintf (out, "minwidth        : %d\n", d->vcap.minwidth);
+       out += sprintf (out, "minheight       : %d\n", d->vcap.minheight);
+#endif
+
+skip:
+       len = out - page;
+       len -= off;
+       if (len < count) {
+               *eof = 1;
+               if (len <= 0)
+                       return 0;
+       } else
+               len = count;
+
+       *start = page + off;
+
+       return len;
+}
+
+static void videodev_proc_create(void)
+{
+       video_proc_entry = create_proc_entry("video", S_IFDIR, &proc_root);
+
+       if (video_proc_entry == NULL) {
+               printk("video_dev: unable to initialise /proc/video\n");
+               return;
+       }
+
+       video_proc_entry->owner = THIS_MODULE;
+       video_dev_proc_entry = create_proc_entry("dev", S_IFDIR, video_proc_entry);
+
+       if (video_dev_proc_entry == NULL) {
+               printk("video_dev: unable to initialise /proc/video/dev\n");
+               return;
+       }
+
+       video_dev_proc_entry->owner = THIS_MODULE;
+}
+
+static void videodev_proc_destroy(void)
+{
+       if (video_dev_proc_entry != NULL)
+               remove_proc_entry("dev", video_proc_entry);
+
+       if (video_proc_entry != NULL)
+               remove_proc_entry("video", &proc_root);
+}
+
+static void videodev_proc_create_dev (struct video_device *vfd, char *name)
+{
+       struct videodev_proc_data *d;
+       struct proc_dir_entry *p;
+
+       if (video_dev_proc_entry == NULL)
+               return;
+
+       d = kmalloc (sizeof (struct videodev_proc_data), GFP_KERNEL);
+       if (!d)
+               return;
+
+       p = create_proc_entry(name, S_IFREG|S_IRUGO|S_IWUSR, video_dev_proc_entry);
+       p->data = vfd;
+       p->read_proc = videodev_proc_read;
+
+       d->proc_entry = p;
+       d->vdev = vfd;
+       strcpy (d->name, name);
+
+       /* How can I get capability information ? */
+
+       list_add (&d->proc_list, &videodev_proc_list);
+}
+
+static void videodev_proc_destroy_dev (struct video_device *vfd)
+{
+       struct list_head *tmp;
+       struct videodev_proc_data *d;
+
+       list_for_each (tmp, &videodev_proc_list) {
+               d = list_entry(tmp, struct videodev_proc_data, proc_list);
+               if (vfd == d->vdev) {
+                       remove_proc_entry(d->name, video_dev_proc_entry);
+                       list_del (&d->proc_list);
+                       kfree (d);
+                       break;
+               }
+       }
+}
+
+#endif /* CONFIG_VIDEO_PROC_FS */
+
 extern struct file_operations video_fops;
 
 /**
@@ -306,6 +474,13 @@ int video_register_device(struct video_device *vfd, int type)
                                            VIDEO_MAJOR, vfd->minor,
                                            S_IFCHR | S_IRUSR | S_IWUSR, 0, 0,
                                            &video_fops, NULL);
+
+#if defined(CONFIG_PROC_FS) && defined(CONFIG_VIDEO_PROC_FS)
+                       sprintf (name, "%s%d", name_base, i - base);
+                       videodev_proc_create_dev (vfd, name);
+#endif
+                       
+
                        return 0;
                }
        }
@@ -324,6 +499,11 @@ void video_unregister_device(struct video_device *vfd)
 {
        if(video_device[vfd->minor]!=vfd)
                panic("vfd: bad unregister");
+
+#if defined(CONFIG_PROC_FS) && defined(CONFIG_VIDEO_PROC_FS)
+       videodev_proc_destroy_dev (vfd);
+#endif
+
        devfs_unregister (vfd->devfs_handle);
        video_device[vfd->minor]=NULL;
        MOD_DEC_USE_COUNT;
@@ -361,6 +541,10 @@ int __init videodev_init(void)
         *      Init kernel installed video drivers
         */
                
+#if defined(CONFIG_PROC_FS) && defined(CONFIG_VIDEO_PROC_FS)
+       videodev_proc_create ();
+#endif
+       
        while(vfli->init!=NULL)
        {
                vfli->init(vfli);
@@ -377,6 +561,10 @@ int init_module(void)
 
 void cleanup_module(void)
 {
+#if defined(CONFIG_PROC_FS) && defined(CONFIG_VIDEO_PROC_FS)
+       videodev_proc_destroy ();
+#endif
+       
        devfs_unregister_chrdev(VIDEO_MAJOR, "video_capture");
 }
 
index 09c6451cfd1347c58dba58711c62d58752b5791f..b591b3563c523f9928f76ffe873e0a4912c55cb1 100644 (file)
@@ -41,7 +41,6 @@ if [ "$CONFIG_BLK_DEV_IDE" != "n" ]; then
            bool '    Boot off-board chipsets first support' CONFIG_BLK_DEV_OFFBOARD
            dep_bool '      Use PCI DMA by default when available' CONFIG_IDEDMA_PCI_AUTO $CONFIG_BLK_DEV_IDEDMA_PCI
            define_bool CONFIG_BLK_DEV_IDEDMA $CONFIG_BLK_DEV_IDEDMA_PCI
-           define_bool CONFIG_IDEDMA_PCI_EXPERIMENTAL $CONFIG_EXPERIMENTAL
            dep_bool '      ATA Work(s) In Progress (EXPERIMENTAL)' CONFIG_IDEDMA_PCI_WIP $CONFIG_BLK_DEV_IDEDMA_PCI $CONFIG_EXPERIMENTAL
            dep_bool '      Good-Bad DMA Model-Firmware (WIP)' CONFIG_IDEDMA_NEW_DRIVE_LISTINGS $CONFIG_IDEDMA_PCI_WIP
            dep_bool '    AEC62XX chipset support' CONFIG_BLK_DEV_AEC62XX $CONFIG_BLK_DEV_IDEDMA_PCI
@@ -82,12 +81,14 @@ if [ "$CONFIG_BLK_DEV_IDE" != "n" ]; then
         dep_bool '      PowerMac IDE DMA support' CONFIG_BLK_DEV_IDEDMA_PMAC $CONFIG_BLK_DEV_IDE_PMAC
         dep_bool '        Use DMA by default' CONFIG_IDEDMA_PMAC_AUTO $CONFIG_BLK_DEV_IDEDMA_PMAC
         define_bool CONFIG_BLK_DEV_IDEDMA $CONFIG_BLK_DEV_IDEDMA_PMAC
+        define_bool CONFIG_BLK_DEV_IDEDMA_PCI $CONFIG_BLK_DEV_IDEDMA_PMAC
       fi
       if [ "$CONFIG_ARCH_ACORN" = "y" ]; then
         dep_bool '    ICS IDE interface support' CONFIG_BLK_DEV_IDE_ICSIDE $CONFIG_ARCH_ACORN
         dep_bool '      ICS DMA support' CONFIG_BLK_DEV_IDEDMA_ICS $CONFIG_BLK_DEV_IDE_ICSIDE
         dep_bool '        Use ICS DMA by default' CONFIG_IDEDMA_ICS_AUTO $CONFIG_BLK_DEV_IDEDMA_ICS
         define_bool CONFIG_BLK_DEV_IDEDMA $CONFIG_BLK_DEV_IDEDMA_ICS
+        define_bool CONFIG_BLK_DEV_IDEDMA_PCI $CONFIG_BLK_DEV_IDEDMA_ICS
         dep_bool '    RapIDE interface support' CONFIG_BLK_DEV_IDE_RAPIDE $CONFIG_ARCH_ACORN
       fi
       if [ "$CONFIG_AMIGA" = "y" ]; then
index 278ad7ab7038a9968ebca80317b19d07e0e9c840..028dbcffeff3331a33f30ea79fbf6f5a3251baca 100644 (file)
@@ -97,7 +97,7 @@ ifeq ($(CONFIG_BLK_DEV_IDE_ICSIDE),y)
 IDE_OBJS += icside.o
 endif
 
-ifeq ($(CONFIG_BLK_DEV_IDEDMA),y)
+ifeq ($(CONFIG_BLK_DEV_IDEDMA_PCI),y)
 IDE_OBJS += ide-dma.o
 endif
 
index 1c6a0b286d6e83c3f310e7e5110b3595e7276b7e..eb73c24456c88cb18c7d51f919e57467133d4327 100644 (file)
@@ -778,6 +778,8 @@ static void hd_geninit(void)
 #endif
 
        for (drive=0 ; drive < NR_HD ; drive++) {
+               hd[drive<<6].nr_sects = hd_info[drive].head *
+                       hd_info[drive].sect * hd_info[drive].cyl;
                printk ("hd%c: %ldMB, CHS=%d/%d/%d\n", drive+'a',
                        hd[drive<<6].nr_sects / 2048, hd_info[drive].cyl,
                        hd_info[drive].head, hd_info[drive].sect);
@@ -890,3 +892,4 @@ static int parse_hd_setup (char *line) {
        return 0;
 }
 __setup("hd=", parse_hd_setup);
+
index fcf0aab6337729b7a25ae7023a848ca899251f89..cb3790fa62f4f5868f7635f0536c2d2e3be33a4b 100644 (file)
@@ -12,6 +12,7 @@
  *  May be copied or modified under the terms of the GNU General Public License
  */
 
+#include <linux/config.h>
 #define __NO_VERSION__
 #include <linux/module.h>
 #include <linux/types.h>
@@ -257,11 +258,12 @@ int ide_config_drive_speed (ide_drive_t *drive, byte speed)
 {
        ide_hwif_t *hwif = HWIF(drive);
        int     i, error = 1;
-       byte unit = (drive->select.b.unit & 0x01);
        byte stat;
 
+#ifdef CONFIG_BLK_DEV_IDEDMA_PCI
+       byte unit = (drive->select.b.unit & 0x01);
        outb(inb(hwif->dma_base+2) & ~(1<<(5+unit)), hwif->dma_base+2);
-
+#endif /* CONFIG_BLK_DEV_IDEDMA_PCI */
        /*
         * Don't use ide_wait_cmd here - it will
         * attempt to set_geometry and recalibrate,
@@ -324,11 +326,13 @@ int ide_config_drive_speed (ide_drive_t *drive, byte speed)
        drive->id->dma_mword &= ~0x0F00;
        drive->id->dma_1word &= ~0x0F00;
 
+#ifdef CONFIG_BLK_DEV_IDEDMA_PCI
        if (speed > XFER_PIO_4) {
                outb(inb(hwif->dma_base+2)|(1<<(5+unit)), hwif->dma_base+2);
        } else {
                outb(inb(hwif->dma_base+2) & ~(1<<(5+unit)), hwif->dma_base+2);
        }
+#endif /* CONFIG_BLK_DEV_IDEDMA_PCI */
 
        switch(speed) {
                case XFER_UDMA_7:   drive->id->dma_ultra |= 0x8080; break;
index 29de5bb09d56b54f50d97ba327932d9e78361ad5..a291785971cf521b089912a62f0ab9967bd37e83 100644 (file)
@@ -3,7 +3,7 @@
  */
 #include <linux/config.h>
 
-#ifdef CONFIG_IDE
+#if defined(CONFIG_IDE) && !defined(CONFIG_BLK_DEV_HD)
 #include <linux/ide.h>
 
 #include <asm/io.h>
@@ -211,4 +211,4 @@ int ide_xlate_1024 (kdev_t i_rdev, int xparm, int ptheads, const char *msg)
                       drive->bios_cyl, drive->bios_head, drive->bios_sect);
        return ret;
 }
-#endif /* CONFIG_IDE */
+#endif /* (CONFIG_IDE) && !(CONFIG_BLK_DEV_HD) */
index 83b14b1fd7d3a01d961f6bc2ec6bb9e8e0667dc7..ddf6c8daefa78ebc0948017da4d75fe6c4c9d4ff 100644 (file)
@@ -425,10 +425,10 @@ static int hwif_check_regions (ide_hwif_t *hwif)
 
        if (hwif->io_ports[IDE_CONTROL_OFFSET])
                region_errors += ide_check_region(hwif->io_ports[IDE_CONTROL_OFFSET], 1);
-
+#if defined(CONFIG_AMIGA) || defined(CONFIG_MAC)
        if (hwif->io_ports[IDE_IRQ_OFFSET])
                region_errors += ide_check_region(hwif->io_ports[IDE_IRQ_OFFSET], 1);
-
+#endif /* (CONFIG_AMIGA) || (CONFIG_MAC) */
        /*
         * If any errors are return, we drop the hwif interface.
         */
@@ -437,8 +437,8 @@ static int hwif_check_regions (ide_hwif_t *hwif)
 
 static void hwif_register (ide_hwif_t *hwif)
 {
-       if ((hwif->io_ports[IDE_DATA_OFFSET] | 7) ==
-           (hwif->io_ports[IDE_STATUS_OFFSET])) {
+       if (((unsigned long)hwif->io_ports[IDE_DATA_OFFSET] | 7) ==
+           ((unsigned long)hwif->io_ports[IDE_STATUS_OFFSET])) {
                ide_request_region(hwif->io_ports[IDE_DATA_OFFSET], 8, hwif->name);
                hwif->straight8 = 1;
                goto jump_straight8;
@@ -464,8 +464,10 @@ static void hwif_register (ide_hwif_t *hwif)
 jump_straight8:
        if (hwif->io_ports[IDE_CONTROL_OFFSET])
                ide_request_region(hwif->io_ports[IDE_CONTROL_OFFSET], 1, hwif->name);
+#if defined(CONFIG_AMIGA) || defined(CONFIG_MAC)
        if (hwif->io_ports[IDE_IRQ_OFFSET])
                ide_request_region(hwif->io_ports[IDE_IRQ_OFFSET], 1, hwif->name);
+#endif /* (CONFIG_AMIGA) || (CONFIG_MAC) */
 }
 
 /*
index 2b590266b680fc74d96e06574ec660cf5a9711b3..09e1b12fb71eb8c262581edca60cdd2f597ed79f 100644 (file)
@@ -3912,8 +3912,12 @@ static int idetape_get_logical_blk (ide_drive_t *drive, int logical_blk_num, int
 #endif
                                clear_bit(IDETAPE_PIPELINE_ERROR, &tape->flags);
                                position = idetape_read_position(drive);
-                               printk(KERN_INFO "ide-tape: %s: blank block detected, positioning tape to block %d\n", tape->name, position + 60);
-                               idetape_position_tape(drive, position + 60, 0, 1);
+                               if (position >= 2980 && position < 3000)
+                                       position = 3000;
+                               else
+                                       position += 60;
+                               printk(KERN_INFO "ide-tape: %s: blank block detected, positioning tape to block %d\n", tape->name, position);
+                               idetape_position_tape(drive, position, 0, 1);
                                cnt += 40;
                                continue;
                        } else
index cb34d354478e3a414c7e80471debb1ed5cd1d75d..a3394807b1668467048c525f40a1c09b8b24f1ab 100644 (file)
@@ -824,7 +824,7 @@ byte ide_dump_status (ide_drive_t *drive, const char *msg, byte stat)
                if (drive->media == ide_disk) {
                        printk(" { ");
                        if (err & ABRT_ERR)     printk("DriveStatusError ");
-                       if (err & ICRC_ERR)     printk((err & ABRT_ERR) ? "BadCRC " : "BadSector ");
+                       if (err & ICRC_ERR)     printk("%s", (err & ABRT_ERR) ? "BadCRC " : "BadSector ");
                        if (err & ECC_ERR)      printk("UncorrectableError ");
                        if (err & ID_ERR)       printk("SectorIdNotFound ");
                        if (err & TRK0_ERR)     printk("TrackZeroNotFound ");
@@ -1896,8 +1896,10 @@ void hwif_unregister (ide_hwif_t *hwif)
 jump_eight:
        if (hwif->io_ports[IDE_CONTROL_OFFSET])
                ide_release_region(hwif->io_ports[IDE_CONTROL_OFFSET], 1);
+#if defined(CONFIG_AMIGA) || defined(CONFIG_MAC)
        if (hwif->io_ports[IDE_IRQ_OFFSET])
                ide_release_region(hwif->io_ports[IDE_IRQ_OFFSET], 1);
+#endif /* (CONFIG_AMIGA) || (CONFIG_MAC) */
 }
 
 void ide_unregister (unsigned int index)
@@ -2006,12 +2008,12 @@ void ide_unregister (unsigned int index)
        else
                hwgroup->hwif = HWIF(hwgroup->drive);
 
-#ifdef CONFIG_BLK_DEV_IDEDMA
+#ifdef CONFIG_BLK_DEV_IDEDMA_PCI
        if (hwif->dma_base) {
                (void) ide_release_dma(hwif);
                hwif->dma_base = 0;
        }
-#endif /* CONFIG_BLK_DEV_IDEDMA */
+#endif /* CONFIG_BLK_DEV_IDEDMA_PCI */
 
        /*
         * Remove us from the kernel's knowledge
@@ -2087,9 +2089,11 @@ void ide_setup_ports (   hw_regs_t *hw,
                                case IDE_CONTROL_OFFSET:
                                        hw->io_ports[i] = ctrl;
                                        break;
+#if defined(CONFIG_AMIGA) || defined(CONFIG_MAC)
                                case IDE_IRQ_OFFSET:
                                        hw->io_ports[i] = intr;
                                        break;
+#endif /* (CONFIG_AMIGA) || (CONFIG_MAC) */
                                default:
                                        hw->io_ports[i] = 0;
                                        break;
@@ -2552,8 +2556,6 @@ static int ide_ioctl (struct inode *inode, struct file *file,
                                if ((HWIF(drive)->speedproc) != NULL)
                                        HWIF(drive)->speedproc(drive, xfer_rate);
                                ide_driveid_update(drive);
-                       } else {
-                               printk("%s: \n", drive->name);
                        }
                abort:
                        if (copy_to_user((void *)arg, argbuf, argsize))
@@ -3617,10 +3619,10 @@ void cleanup_module (void)
 
        for (index = 0; index < MAX_HWIFS; ++index) {
                ide_unregister(index);
-#ifdef CONFIG_BLK_DEV_IDEDMA
+#ifdef CONFIG_BLK_DEV_IDEDMA_PCI
                if (ide_hwifs[index].dma_base)
                        (void) ide_release_dma(&ide_hwifs[index]);
-#endif /* CONFIG_BLK_DEV_IDEDMA */
+#endif /* CONFIG_BLK_DEV_IDEDMA_PCI */
        }
 
 #ifdef CONFIG_PROC_FS
index 90af168c351ff2d13154bc5aec72ac70936172e7..56c1852361d43b695ad34efd4460d51af96b3cc6 100644 (file)
@@ -86,7 +86,7 @@ static int piix_get_info (char *buffer, char **addr, off_t offset, int count)
        u32 bibma = bmide_dev->resource[4].start;
         u16 reg40 = 0, psitre = 0, reg42 = 0, ssitre = 0;
        u8  c0 = 0, c1 = 0;
-       u8  reg44 = 0, reg48 = 0, reg4a = 0, reg4b = 0, reg54 = 0;
+       u8  reg44 = 0, reg48 = 0, reg4a = 0, reg4b = 0, reg54 = 0, reg55 = 0;
 
        pci_read_config_word(bmide_dev, 0x40, &reg40);
        pci_read_config_word(bmide_dev, 0x42, &reg42);
@@ -95,6 +95,7 @@ static int piix_get_info (char *buffer, char **addr, off_t offset, int count)
        pci_read_config_byte(bmide_dev, 0x4a, &reg4a);
        pci_read_config_byte(bmide_dev, 0x4b, &reg4b);
        pci_read_config_byte(bmide_dev, 0x54, &reg54);
+       pci_read_config_byte(bmide_dev, 0x55, &reg55);
 
        psitre = (reg40 & 0x4000) ? 1 : 0;
        ssitre = (reg42 & 0x4000) ? 1 : 0;
@@ -264,13 +265,15 @@ static int piix_tune_chipset (ide_drive_t *drive, byte speed)
        ide_hwif_t *hwif        = HWIF(drive);
        struct pci_dev *dev     = hwif->pci_dev;
        byte maslave            = hwif->channel ? 0x42 : 0x40;
-       int a_speed             = 2 << (drive->dn * 4);
+       int a_speed             = 3 << (drive->dn * 4);
        int u_flag              = 1 << drive->dn;
-       int v_flag              = 0x10 << drive->dn;
+       int v_flag              = 0x01 << drive->dn;
+       int w_flag              = 0x10 << drive->dn;
        int u_speed             = 0;
        int err                 = 0;
        int                     sitre;
        short                   reg4042, reg44, reg48, reg4a, reg54;
+       byte                    reg55;
 
        pci_read_config_word(dev, maslave, &reg4042);
        sitre = (reg4042 & 0x4000) ? 1 : 0;
@@ -278,6 +281,7 @@ static int piix_tune_chipset (ide_drive_t *drive, byte speed)
        pci_read_config_word(dev, 0x48, &reg48);
        pci_read_config_word(dev, 0x4a, &reg4a);
        pci_read_config_word(dev, 0x54, &reg54);
+       pci_read_config_byte(dev, 0x55, &reg55);
 
        switch(speed) {
                case XFER_UDMA_4:
@@ -294,6 +298,7 @@ static int piix_tune_chipset (ide_drive_t *drive, byte speed)
        if (speed >= XFER_UDMA_0) {
                if (!(reg48 & u_flag))
                        pci_write_config_word(dev, 0x48, reg48|u_flag);
+               pci_write_config_byte(dev, 0x55, (byte) reg55 & ~w_flag);
                if (!(reg4a & u_speed)) {
                        pci_write_config_word(dev, 0x4a, reg4a & ~a_speed);
                        pci_write_config_word(dev, 0x4a, reg4a|u_speed);
@@ -313,6 +318,8 @@ static int piix_tune_chipset (ide_drive_t *drive, byte speed)
                        pci_write_config_word(dev, 0x4a, reg4a & ~a_speed);
                if (reg54 & v_flag)
                        pci_write_config_word(dev, 0x54, reg54 & ~v_flag);
+               if (reg55 & w_flag)
+                       pci_write_config_byte(dev, 0x55, (byte) reg55 & ~w_flag);
        }
 
        piix_tune_drive(drive, piix_dma_2_pio(speed));
@@ -404,10 +411,11 @@ unsigned int __init pci_init_piix (struct pci_dev *dev, const char *name)
 unsigned int __init ata66_piix (ide_hwif_t *hwif)
 {
        byte reg54h = 0, reg55h = 0, ata66 = 0;
-       byte mask = hwif->channel ? 0x0c : 0x03;
+       byte mask = hwif->channel ? 0xc0 : 0x30;
 
        pci_read_config_byte(hwif->pci_dev, 0x54, &reg54h);
        pci_read_config_byte(hwif->pci_dev, 0x55, &reg55h);
+
        ata66 = (reg54h & mask) ? 1 : 0;
 
        return ata66;
@@ -415,8 +423,10 @@ unsigned int __init ata66_piix (ide_hwif_t *hwif)
 
 void __init ide_init_piix (ide_hwif_t *hwif)
 {
+#ifndef CONFIG_IA64
        if (!hwif->irq)
                hwif->irq = hwif->channel ? 15 : 14;
+#endif /* CONFIG_IA64 */
 
        hwif->tuneproc = &piix_tune_drive;
        hwif->drives[0].autotune = 1;
index 39258362ca8dca70b99cc4e810ecced8a58ef86f..6c201599f81f846729d4a7b250593a58ef996e58 100644 (file)
@@ -243,7 +243,7 @@ static const struct {
 
 #define arraysize(x)   (sizeof(x)/sizeof(*(x)))
 
-#define DISPLAY_VIA_TIMINGS
+#undef DISPLAY_VIA_TIMINGS
 
 #if defined(DISPLAY_VIA_TIMINGS) && defined(CONFIG_PROC_FS)
 #include <linux/stat.h>
@@ -657,6 +657,7 @@ static int via82cxxx_tune_chipset (ide_drive_t *drive, byte speed)
        struct pci_dev *dev     = hwif->pci_dev;
        struct chipset_bus_clock_list_entry * temp_table = NULL;
 
+       byte unit               = (drive->select.b.unit & 0x01) ? 1 : 0;
        byte ata2_pci           = 0x00;
        byte ata3_pci           = 0x00;
        byte timing             = 0x00;
@@ -677,7 +678,9 @@ static int via82cxxx_tune_chipset (ide_drive_t *drive, byte speed)
                        return -1;
        }
 
-       if ((via82cxxx_table == via82cxxx_type_four) && (speed <= XFER_UDMA_2)) {
+       if ((via82cxxx_table == via82cxxx_type_four) &&
+           (!(hwif->udma_four)) &&
+           (speed <= XFER_UDMA_2)) {
                temp_table = via82cxxx_type_three;
        } else {
                temp_table = via82cxxx_table;
@@ -689,6 +692,8 @@ static int via82cxxx_tune_chipset (ide_drive_t *drive, byte speed)
 
        pci_read_config_byte(dev, ata3_pci, &ultra);
        ultra = pci_bus_clock_list_ultra(speed, bus_speed, temp_table);
+       if ((unit) && (hwif->udma_four))
+               ultra |= 0x04;
        pci_write_config_byte(dev, ata3_pci, ultra);
 
        if (!drive->init_speed)
index 7f05925cd5e7845ca3086dfc95d15ea171f4dcd7..ec3849a748b72b249279b99fcd91193ca0104a92 100644 (file)
@@ -2455,9 +2455,8 @@ static struct initvol {
        { SOUND_MIXER_WRITE_OGAIN, 0x4040 }
 };
 
-#define RSRCISIOREGION(dev,num) ((dev)->resource[(num)].start != 0 && \
-                                ((dev)->resource[(num)].flags & PCI_BASE_ADDRESS_SPACE) == PCI_BASE_ADDRESS_SPACE_IO)
-#define RSRCADDRESS(dev,num) ((dev)->resource[(num)].start)
+#define RSRCISIOREGION(dev,num) (pci_resource_start((dev), (num)) != 0 && \
+                                pci_resource_flags((dev), (num)) & IORESOURCE_IO)
 
 static int __devinit es1370_probe(struct pci_dev *pcidev, const struct pci_device_id *pciid)
 {
@@ -2488,7 +2487,7 @@ static int __devinit es1370_probe(struct pci_dev *pcidev, const struct pci_devic
        spin_lock_init(&s->lock);
        s->magic = ES1370_MAGIC;
        s->dev = pcidev;
-       s->io = RSRCADDRESS(pcidev, 0);
+       s->io = pci_resource_start(pcidev, 0);
        s->irq = pcidev->irq;
        if (!request_region(s->io, ES1370_EXTENT, "es1370")) {
                printk(KERN_ERR "es1370: io ports %#lx-%#lx in use\n", s->io, s->io+ES1370_EXTENT-1);
@@ -2616,12 +2615,7 @@ static int __init init_es1370(void)
        if (!pci_present())   /* No PCI bus in this machine! */
                return -ENODEV;
        printk(KERN_INFO "es1370: version v0.33 time " __TIME__ " " __DATE__ "\n");
-       if (!pci_register_driver(&es1370_driver)) {
-               pci_unregister_driver(&es1370_driver);
-               return -ENODEV;
-       }
-        return 0;
-
+       return pci_module_init(&es1370_driver);
 }
 
 static void __exit cleanup_es1370(void)
index 1623c98ba681c71ac64ecc2f151cf4428548dc32..44189f010c0b45371c399cf1b48ee4ac306d7aec 100644 (file)
  *                       Tim Janik's BSE (Bedevilled Sound Engine) found this
  *    07.02.2000   0.24  Use pci_alloc_consistent and pci_register_driver
  *    07.02.2000   0.25  Use ac97_codec
+ *    01.03.2000   0.26  SPDIF patch by Mikael Bouillot <mikael.bouillot@bigfoot.com>
+ *                       Use pci_module_init
  */
 
 /*****************************************************************************/
 static const unsigned sample_size[] = { 1, 2, 2, 4 };
 static const unsigned sample_shift[] = { 0, 1, 1, 2 };
 
+#define CTRL_RECEN_B    0x08000000  /* 1 = don't mix analog in to digital out */
 #define CTRL_SPDIFEN_B  0x04000000
 #define CTRL_JOY_SHIFT  24
 #define CTRL_JOY_MASK   3
@@ -344,22 +347,6 @@ static const unsigned sample_shift[] = { 0, 1, 1, 2 };
 #define SCTRL_P1FMT       0x00000003  /* format mask */
 #define SCTRL_SH_P1FMT    0
 
-/* codec constants */
-
-#define CODEC_ID_DEDICATEDMIC    0x001
-#define CODEC_ID_MODEMCODEC      0x002
-#define CODEC_ID_BASSTREBLE      0x004
-#define CODEC_ID_SIMULATEDSTEREO 0x008
-#define CODEC_ID_HEADPHONEOUT    0x010
-#define CODEC_ID_LOUDNESS        0x020
-#define CODEC_ID_18BITDAC        0x040
-#define CODEC_ID_20BITDAC        0x080
-#define CODEC_ID_18BITADC        0x100
-#define CODEC_ID_20BITADC        0x200
-
-#define CODEC_ID_SESHIFT    10
-#define CODEC_ID_SEMASK     0x1f
-
 
 /* misc stuff */
 #define POLL_COUNT   0x1000
@@ -405,6 +392,9 @@ struct es1371_state {
        u16 device;
         u8 rev; /* the chip revision */
 
+       /* options */
+       int spdif_volume; /* S/PDIF output is enabled if != -1 */
+
 #ifdef ES1371_DEBUG
         /* debug /proc entry */
        struct proc_dir_entry *ps;
@@ -1135,6 +1125,67 @@ static loff_t es1371_llseek(struct file *file, loff_t offset, int origin)
 
 /* --------------------------------------------------------------------- */
 
+/* Conversion table for S/PDIF PCM volume emulation through the SRC */
+/* dB-linear table of DAC vol values; -0dB to -46.5dB with mute */
+static const unsigned short DACVolTable[101] =
+{
+       0x1000, 0x0f2a, 0x0e60, 0x0da0, 0x0cea, 0x0c3e, 0x0b9a, 0x0aff,
+       0x0a6d, 0x09e1, 0x095e, 0x08e1, 0x086a, 0x07fa, 0x078f, 0x072a,
+       0x06cb, 0x0670, 0x061a, 0x05c9, 0x057b, 0x0532, 0x04ed, 0x04ab,
+       0x046d, 0x0432, 0x03fa, 0x03c5, 0x0392, 0x0363, 0x0335, 0x030b,
+       0x02e2, 0x02bc, 0x0297, 0x0275, 0x0254, 0x0235, 0x0217, 0x01fb,
+       0x01e1, 0x01c8, 0x01b0, 0x0199, 0x0184, 0x0170, 0x015d, 0x014b,
+       0x0139, 0x0129, 0x0119, 0x010b, 0x00fd, 0x00f0, 0x00e3, 0x00d7,
+       0x00cc, 0x00c1, 0x00b7, 0x00ae, 0x00a5, 0x009c, 0x0094, 0x008c,
+       0x0085, 0x007e, 0x0077, 0x0071, 0x006b, 0x0066, 0x0060, 0x005b,
+       0x0057, 0x0052, 0x004e, 0x004a, 0x0046, 0x0042, 0x003f, 0x003c,
+       0x0038, 0x0036, 0x0033, 0x0030, 0x002e, 0x002b, 0x0029, 0x0027,
+       0x0025, 0x0023, 0x0021, 0x001f, 0x001e, 0x001c, 0x001b, 0x0019,
+       0x0018, 0x0017, 0x0016, 0x0014, 0x0000
+};
+
+/*
+ * when we are in S/PDIF mode, we want to disable any analog output so
+ * we filter the mixer ioctls 
+ */
+static int mixdev_ioctl(struct ac97_codec *codec, unsigned int cmd, unsigned long arg)
+{
+       struct es1371_state *s = (struct es1371_state *)codec->private_data;
+       int val;
+       unsigned long flags;
+       unsigned int left, right;
+
+       VALIDATE_STATE(s);
+       /* filter mixer ioctls to catch PCM and MASTER volume when in S/PDIF mode */
+       if (s->spdif_volume == -1)
+               return codec->mixer_ioctl(codec, cmd, arg);
+       switch (cmd) {
+       case SOUND_MIXER_WRITE_VOLUME:
+               return 0;
+
+       case SOUND_MIXER_WRITE_PCM:   /* use SRC for PCM volume */
+               get_user_ret(val, (int *)arg, -EFAULT);
+               right = ((val >> 8)  & 0xff);
+               left = (val  & 0xff);
+               if (right > 100)
+                       right = 100;
+               if (left > 100)
+                       left = 100;
+               s->spdif_volume = (right << 8) | left;
+               spin_lock_irqsave(&s->lock, flags);
+               src_write(s, SRCREG_VOL_DAC2, DACVolTable[100 - left]);
+               src_write(s, SRCREG_VOL_DAC2+1, DACVolTable[100 - right]);
+               spin_unlock_irqrestore(&s->lock, flags);
+               return 0;
+       
+       case SOUND_MIXER_READ_PCM:
+               return put_user(s->spdif_volume, (int *)arg);
+       }
+       return codec->mixer_ioctl(codec, cmd, arg);
+}
+
+/* --------------------------------------------------------------------- */
+
 /*
  * AC97 Mixer Register to Connections mapping of the Concert 97 board
  *
@@ -1180,8 +1231,10 @@ static int es1371_release_mixdev(struct inode *inode, struct file *file)
 
 static int es1371_ioctl_mixdev(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
 {
-       struct ac97_codec *codec = &((struct es1371_state *)file->private_data)->codec;
-       return codec->mixer_ioctl(codec, cmd, arg);
+       struct es1371_state *s = (struct es1371_state *)file->private_data;
+       struct ac97_codec *codec = &s->codec;
+
+       return mixdev_ioctl(codec, cmd, arg);
 }
 
 static /*const*/ struct file_operations es1371_mixer_fops = {
@@ -1778,7 +1831,7 @@ static int es1371_ioctl(struct inode *inode, struct file *file, unsigned int cmd
                 return -EINVAL;
                
        }
-       return s->codec.mixer_ioctl(&s->codec, cmd, arg);
+       return mixdev_ioctl(&s->codec, cmd, arg);
 }
 
 static int es1371_open(struct inode *inode, struct file *file)
@@ -2181,7 +2234,7 @@ static int es1371_ioctl_dac(struct inode *inode, struct file *file, unsigned int
                 return -EINVAL;
                
        }
-       return s->codec.mixer_ioctl(&s->codec, cmd, arg);
+       return mixdev_ioctl(&s->codec, cmd, arg);
 }
 
 static int es1371_open_dac(struct inode *inode, struct file *file)
@@ -2581,6 +2634,7 @@ static int proc_es1371_dump (char *buf, char **start, off_t fpos, int length, in
 
 static int joystick[NR_DEVICE] = { 0, };
 static int spdif[NR_DEVICE] = { 0, };
+static int nomix[NR_DEVICE] = { 0, };
 
 static unsigned int devindex = 0;
 
@@ -2588,6 +2642,8 @@ MODULE_PARM(joystick, "1-" __MODULE_STRING(NR_DEVICE) "i");
 MODULE_PARM_DESC(joystick, "sets address and enables joystick interface (still need separate driver)");
 MODULE_PARM(spdif, "1-" __MODULE_STRING(NR_DEVICE) "i");
 MODULE_PARM_DESC(spdif, "if 1 the output is in S/PDIF digital mode");
+MODULE_PARM(nomix, "1-" __MODULE_STRING(NR_DEVICE) "i");
+MODULE_PARM_DESC(nomix, "if 1 no analog audio is mixed to the digital output");
 
 MODULE_AUTHOR("Thomas M. Sailer, sailer@ife.ee.ethz.ch, hb9jnx@hb9w.che.eu");
 MODULE_DESCRIPTION("ES1371 AudioPCI97 Driver");
@@ -2613,9 +2669,8 @@ static struct initvol {
        { SOUND_MIXER_WRITE_IGAIN, 0x4040 }
 };
 
-#define RSRCISIOREGION(dev,num) ((dev)->resource[(num)].start != 0 && \
-                                ((dev)->resource[(num)].flags & PCI_BASE_ADDRESS_SPACE) == PCI_BASE_ADDRESS_SPACE_IO)
-#define RSRCADDRESS(dev,num) ((dev)->resource[(num)].start)
+#define RSRCISIOREGION(dev,num) (pci_resource_start((dev), (num)) != 0 && \
+                                (pci_resource_flags((dev), (num)) & IORESOURCE_IO))
 
 static int __devinit es1371_probe(struct pci_dev *pcidev, const struct pci_device_id *pciid)
 {
@@ -2649,7 +2704,7 @@ static int __devinit es1371_probe(struct pci_dev *pcidev, const struct pci_devic
        spin_lock_init(&s->lock);
        s->magic = ES1371_MAGIC;
        s->dev = pcidev;
-       s->io = RSRCADDRESS(pcidev, 0);
+       s->io = pci_resource_start(pcidev, 0);
        s->irq = pcidev->irq;
        s->vendor = pcidev->vendor;
        s->device = pcidev->device;
@@ -2688,6 +2743,10 @@ static int __devinit es1371_probe(struct pci_dev *pcidev, const struct pci_devic
        
        /* initialize codec registers */
        s->ctrl = 0;
+       if (pcidev->subsystem_vendor == 0x107b && pcidev->subsystem_device == 0x2150) {
+               s->ctrl |= CTRL_GPIO_OUT0;
+               printk(KERN_INFO PFX "Running On Gateway 2000 Solo 2510 - Amp On \n");
+       }       
        if ((joystick[devindex] & ~0x18) == 0x200) {
                if (check_region(joystick[devindex], JOY_EXTENT))
                        printk(KERN_ERR PFX "joystick address 0x%x already in use\n", joystick[devindex]);
@@ -2697,12 +2756,16 @@ static int __devinit es1371_probe(struct pci_dev *pcidev, const struct pci_devic
        }
        s->sctrl = 0;
        cssr = 0;
+       s->spdif_volume = -1;
        /* check to see if s/pdif mode is being requested */
        if (spdif[devindex]) {
                if (s->rev >= 4) {
                        printk(KERN_INFO PFX "enabling S/PDIF output\n");
+                       s->spdif_volume = 0;
                        cssr |= STAT_EN_SPDIF;
                        s->ctrl |= CTRL_SPDIFEN_B;
+                       if (nomix[devindex]) /* don't mix analog inputs to s/pdif output */
+                               s->ctrl |= CTRL_RECEN_B;
                } else {
                        printk(KERN_ERR PFX "revision %d does not support S/PDIF\n", s->rev);
                }
@@ -2742,10 +2805,16 @@ static int __devinit es1371_probe(struct pci_dev *pcidev, const struct pci_devic
        fs = get_fs();
        set_fs(KERNEL_DS);
        val = SOUND_MASK_LINE;
-       s->codec.mixer_ioctl(&s->codec, SOUND_MIXER_WRITE_RECSRC, (unsigned long)&val);
+       mixdev_ioctl(&s->codec, SOUND_MIXER_WRITE_RECSRC, (unsigned long)&val);
        for (i = 0; i < sizeof(initvol)/sizeof(initvol[0]); i++) {
                val = initvol[i].vol;
-               s->codec.mixer_ioctl(&s->codec, initvol[i].mixch, (unsigned long)&val);
+               mixdev_ioctl(&s->codec, initvol[i].mixch, (unsigned long)&val);
+       }
+       /* mute master and PCM when in S/PDIF mode */
+       if (s->spdif_volume != -1) {
+               val = 0x0000;
+               s->codec.mixer_ioctl(&s->codec, SOUND_MIXER_WRITE_VOLUME, (unsigned long)&val);
+               s->codec.mixer_ioctl(&s->codec, SOUND_MIXER_WRITE_PCM, (unsigned long)&val);
        }
        set_fs(fs);
        /* turn on S/PDIF output driver if requested */
@@ -2820,12 +2889,8 @@ static int __init init_es1371(void)
 {
        if (!pci_present())   /* No PCI bus in this machine! */
                return -ENODEV;
-       printk(KERN_INFO "es1371: version v0.25 time " __TIME__ " " __DATE__ "\n");
-       if (!pci_register_driver(&es1371_driver)) {
-               pci_unregister_driver(&es1371_driver);
-               return -ENODEV;
-       }
-       return 0;
+       printk(KERN_INFO PFX "version v0.26 time " __TIME__ " " __DATE__ "\n");
+       return pci_module_init(&es1371_driver);
 }
 
 static void __exit cleanup_es1371(void)
index 1c62eafed743fcf0616bf8c601c1035c149fbe1a..2d7e15f5132bf90926379923ea720d758afec642 100644 (file)
@@ -68,6 +68,7 @@
  *                       Integrated (aka redid 8-)) APM support patch by Zach Brown
  *    07.02.2000   0.13  Use pci_alloc_consistent and pci_register_driver
  *    19.02.2000   0.14  Use pci_dma_supported to determine if recording should be disabled
+ *    13.03.2000   0.15  Reintroduce initialization of a couple of PCI config space registers
  */
 
 /*****************************************************************************/
@@ -2130,6 +2131,14 @@ static int setup_solo1(struct solo1_state *s)
        mm_segment_t fs;
        int i, val;
 
+       /* initialize DDMA base address */
+       printk(KERN_DEBUG "solo1: ddma base address: 0x%lx\n", s->ddmabase);
+       pci_write_config_word(pcidev, 0x60, (s->ddmabase & (~0xf)) | 1);
+       /* set DMA policy to DDMA, IRQ emulation off (CLKRUN disabled for now) */
+       pci_write_config_dword(pcidev, 0x50, 0);
+       /* disable legacy audio address decode */
+       pci_write_config_word(pcidev, 0x40, 0x907f);
+
        /* initialize the chips */
        if (!reset_ctrl(s)) {
                printk(KERN_ERR "esssolo1: cannot reset controller\n");
@@ -2190,9 +2199,8 @@ static int solo1_pm_callback(struct pm_dev *dev, pm_request_t rqst, void *data)
 }
 
 
-#define RSRCISIOREGION(dev,num) ((dev)->resource[(num)].start != 0 && \
-                                ((dev)->resource[(num)].flags & PCI_BASE_ADDRESS_SPACE) == PCI_BASE_ADDRESS_SPACE_IO)
-#define RSRCADDRESS(dev,num) ((dev)->resource[(num)].start)
+#define RSRCISIOREGION(dev,num) (pci_resource_start((dev), (num)) != 0 && \
+                                (pci_resource_flags((dev), (num)) & IORESOURCE_IO))
 
 static int __devinit solo1_probe(struct pci_dev *pcidev, const struct pci_device_id *pciid)
 {
@@ -2229,12 +2237,12 @@ static int __devinit solo1_probe(struct pci_dev *pcidev, const struct pci_device
        spin_lock_init(&s->lock);
        s->magic = SOLO1_MAGIC;
        s->dev = pcidev;
-       s->iobase = RSRCADDRESS(pcidev, 0);
-       s->sbbase = RSRCADDRESS(pcidev, 1);
-       s->vcbase = RSRCADDRESS(pcidev, 2);
+       s->iobase = pci_resource_start(pcidev, 0);
+       s->sbbase = pci_resource_start(pcidev, 1);
+       s->vcbase = pci_resource_start(pcidev, 2);
        s->ddmabase = s->vcbase + DDMABASE_OFFSET;
-       s->mpubase = RSRCADDRESS(pcidev, 3);
-       s->gpbase = RSRCADDRESS(pcidev, 4);
+       s->mpubase = pci_resource_start(pcidev, 3);
+       s->gpbase = pci_resource_start(pcidev, 4);
        s->irq = pcidev->irq;
        if (!request_region(s->iobase, IOBASE_EXTENT, "ESS Solo1")) {
                printk(KERN_ERR "solo1: io ports in use\n");
@@ -2252,13 +2260,12 @@ static int __devinit solo1_probe(struct pci_dev *pcidev, const struct pci_device
                printk(KERN_ERR "solo1: io ports in use\n");
                goto err_region4;
        }
-       if (pci_enable_device(pcidev))
-               goto err_irq;
        if (request_irq(s->irq, solo1_interrupt, SA_SHIRQ, "ESS Solo1", s)) {
                printk(KERN_ERR "solo1: irq %u in use\n", s->irq);
                goto err_irq;
        }
-       printk(KERN_DEBUG "solo1: ddma base address: 0x%lx\n", s->ddmabase);
+       if (pci_enable_device(pcidev))
+               goto err_irq;
        printk(KERN_INFO "solo1: joystick port at %#lx\n", s->gpbase+1);
        /* register devices */
        if ((s->dev_audio = register_sound_dsp(&solo1_audio_fops, -1)) < 0)
@@ -2352,7 +2359,7 @@ static int __init init_solo1(void)
 {
        if (!pci_present())   /* No PCI bus in this machine! */
                return -ENODEV;
-       printk(KERN_INFO "solo1: version v0.14 time " __TIME__ " " __DATE__ "\n");
+       printk(KERN_INFO "solo1: version v0.15 time " __TIME__ " " __DATE__ "\n");
        if (!pci_register_driver(&solo1_driver)) {
                pci_unregister_driver(&solo1_driver);
                 return -ENODEV;
index 5aa31f506575bc5b57fd27767993fe766e0d9015..7a8a7117b4730e3b0e7e013ff92c130cce3868ee 100644 (file)
@@ -2428,9 +2428,8 @@ static struct initvol {
        { SOUND_MIXER_WRITE_PCM, 0x4040 }
 };
 
-#define RSRCISIOREGION(dev,num) ((dev)->resource[(num)].start != 0 && \
-                                ((dev)->resource[(num)].flags & PCI_BASE_ADDRESS_SPACE) == PCI_BASE_ADDRESS_SPACE_IO)
-#define RSRCADDRESS(dev,num) ((dev)->resource[(num)].start)
+#define RSRCISIOREGION(dev,num) (pci_resource_start((dev), (num)) != 0 && \
+                                (pci_resource_flags((dev), (num)) & IORESOURCE_IO))
 
 static int __devinit sv_probe(struct pci_dev *pcidev, const struct pci_device_id *pciid)
 {
@@ -2484,13 +2483,13 @@ static int __devinit sv_probe(struct pci_dev *pcidev, const struct pci_device_id
        spin_lock_init(&s->lock);
        s->magic = SV_MAGIC;
        s->dev = pcidev;
-       s->iosb = RSRCADDRESS(pcidev, RESOURCE_SB);
-       s->ioenh = RSRCADDRESS(pcidev, RESOURCE_ENH);
-       s->iosynth = RSRCADDRESS(pcidev, RESOURCE_SYNTH);
-       s->iomidi = RSRCADDRESS(pcidev, RESOURCE_MIDI);
-       s->iogame = RSRCADDRESS(pcidev, RESOURCE_GAME);
-       s->iodmaa = RSRCADDRESS(pcidev, RESOURCE_DDMA);
-       s->iodmac = RSRCADDRESS(pcidev, RESOURCE_DDMA) + SV_EXTENT_DMA;
+       s->iosb = pci_resource_start(pcidev, RESOURCE_SB);
+       s->ioenh = pci_resource_start(pcidev, RESOURCE_ENH);
+       s->iosynth = pci_resource_start(pcidev, RESOURCE_SYNTH);
+       s->iomidi = pci_resource_start(pcidev, RESOURCE_MIDI);
+       s->iogame = pci_resource_start(pcidev, RESOURCE_GAME);
+       s->iodmaa = pci_resource_start(pcidev, RESOURCE_DDMA);
+       s->iodmac = pci_resource_start(pcidev, RESOURCE_DDMA) + SV_EXTENT_DMA;
        pci_write_config_dword(pcidev, 0x40, s->iodmaa | 9);  /* enable and use extended mode */
        pci_write_config_dword(pcidev, 0x48, s->iodmac | 9);  /* enable */
        printk(KERN_DEBUG "sv: io ports: %#lx %#lx %#lx %#lx %#lx %#x %#x\n",
@@ -2655,11 +2654,7 @@ static int __init init_sonicvibes(void)
        if (!(wavetable_mem = __get_free_pages(GFP_KERNEL, 20-PAGE_SHIFT)))
                printk(KERN_INFO "sv: cannot allocate 1MB of contiguous nonpageable memory for wavetable data\n");
 #endif
-       if (!pci_register_driver(&sv_driver)) {
-               pci_unregister_driver(&sv_driver);
-                return -ENODEV;
-       }
-        return 0;
+       return pci_module_init(&sv_driver);
 }
 
 static void __exit cleanup_sonicvibes(void)
index 40903a9c299a7523d9660cd582f275a08a6ea50d..ad94fef5562bdfc67ace092d8b1e9559a175047d 100644 (file)
  *             decent headphones!
  *             "Let's make things better" -> but please Philips start with your
  *             own stuff!!!!
- * 1999-11-02:  It takes the Philips boxes several seconds to acquire synchronisation
+ * 1999-11-02:  Thomas Sailer
+ *             It takes the Philips boxes several seconds to acquire synchronisation
  *             that means they won't play short sounds. Should probably maintain
  *             the ISO datastream even if there's nothing to play.
  *             Fix counting the total_bytes counter, RealPlayer G2 depends on it.
- * 1999-12-20:  Fix bad bug in conversion to per interface probing.
+ * 1999-12-20:  Thomas Sailer
+ *             Fix bad bug in conversion to per interface probing.
  *             disconnect was called multiple times for the audio device,
  *             leading to a premature freeing of the audio structures
- * 2000-05-13:  I don't remember who changed the find_format routine,
+ * 2000-05-13:  Thomas Sailer
+ *             I don't remember who changed the find_format routine,
  *              but the change was completely broken for the Dallas
  *              chip. Anyway taking sampling rate into account in find_format
  *              is bad and should not be done unless there are devices with
  *                  for the Dallas chip.
  *              Also fix a rather long standing problem with applications that
  *              use "small" writes producing no sound at all.
- * 2000-05-15:  My fears came true, the Philips camera indeed has pretty stupid
+ * 2000-05-15:  Thomas Sailer
+ *             My fears came true, the Philips camera indeed has pretty stupid
  *              audio descriptors.
+ * 2000-05-17:  Thomas Sailer
+ *             Nemsoft spotted my stupid last minute change, thanks
+ * 2000-05-19:  Thomas Sailer
+ *             Fixed FEATURE_UNIT thinkos found thanks to the KC Technology
+ *              Xtend device. Basically the driver treated FEATURE_UNIT's sourced
+ *              by mono terminals as stereo.
+ * 2000-05-20:  Thomas Sailer
+ *             SELECTOR support (and thus selecting record channels from the mixer).
+ *              Somewhat peculiar due to OSS interface limitations. Only works
+ *              for channels where a "slider" is already in front of it (i.e.
+ *              a MIXER unit or a FEATURE unit with volume capability).
  *
  */
 
@@ -211,6 +226,7 @@ struct mixerchannel {
        __u16 value;
        __u16 osschannel;  /* number of the OSS channel */
        __s16 minval, maxval;
+       __u16 slctunitid;
        __u8 unitid;
        __u8 selector;
        __u8 chnum;
@@ -988,7 +1004,7 @@ static int usbin_start(struct usb_audiodev *as)
                }
                spin_lock_irqsave(&as->lock, flags);
        }
-       if (u->dma.count <= 0 && !u->dma.mapped)
+       if (u->dma.count >= u->dma.dmasize && !u->dma.mapped)
                return 0;
        u->flags |= FLG_RUNNING;
        if (!(u->flags & FLG_URB0RUNNING)) {
@@ -1719,7 +1735,7 @@ static int wrmixer(struct usb_mixerdev *ms, unsigned mixch, unsigned value)
                if (usb_control_msg(dev, usb_sndctrlpipe(dev, 0), SET_CUR, USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_OUT,
                                    (ch->selector << 8) | ch->chnum, ms->iface | (ch->unitid << 8), data, 2, HZ) < 0)
                        goto err;
-               if (ch->chnum == 0)
+               if (!(ch->flags & (MIXFLG_STEREOIN | MIXFLG_STEREOOUT)))
                        return 0;
                data[0] = v2;
                data[1] = v2 >> 8;
@@ -1735,7 +1751,7 @@ static int wrmixer(struct usb_mixerdev *ms, unsigned mixch, unsigned value)
                if (usb_control_msg(dev, usb_sndctrlpipe(dev, 0), SET_CUR, USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_OUT,
                                    (ch->selector << 8) | ch->chnum, ms->iface | (ch->unitid << 8), data, 1, HZ) < 0)
                        goto err;
-               if (ch->chnum == 0)
+               if (!(ch->flags & (MIXFLG_STEREOIN | MIXFLG_STEREOOUT)))
                        return 0;
                data[0] = v2 >> 8;
                if (usb_control_msg(dev, usb_sndctrlpipe(dev, 0), SET_CUR, USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_OUT,
@@ -1754,6 +1770,89 @@ static int wrmixer(struct usb_mixerdev *ms, unsigned mixch, unsigned value)
        return -1;
 }
 
+static int get_rec_src(struct usb_mixerdev *ms)
+{
+       struct usb_device *dev = ms->state->usbdev;
+       unsigned int mask = 0, retmask = 0;
+       unsigned int i, j;
+       unsigned char buf;
+       int err = 0;
+
+       for (i = 0; i < ms->numch; i++) {
+               if (!ms->ch[i].slctunitid || (mask & (1 << i)))
+                       continue;
+               if (usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), GET_CUR, USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN,
+                                   0, ms->iface | (ms->ch[i].slctunitid << 8), &buf, 1, HZ) < 0) {
+                       err = -EIO;
+                       printk(KERN_ERR "usbaudio: selector read request device %u if %u unit %u failed\n", 
+                              dev->devnum, ms->iface, ms->ch[i].slctunitid & 0xff);
+                       continue;
+               }
+               for (j = i; j < ms->numch; i++) {
+                       if ((ms->ch[i].slctunitid ^ ms->ch[j].slctunitid) & 0xff)
+                               continue;
+                       mask |= 1 << j;
+                       if (buf == (ms->ch[j].slctunitid >> 8))
+                               retmask |= 1 << ms->ch[j].osschannel;
+               }
+       }
+       if (err)
+               return -EIO;
+       return retmask;
+}
+
+static int set_rec_src(struct usb_mixerdev *ms, int srcmask)
+{
+       struct usb_device *dev = ms->state->usbdev;
+       unsigned int mask = 0, smask, bmask;
+       unsigned int i, j;
+       unsigned char buf;
+       int err = 0;
+
+       for (i = 0; i < ms->numch; i++) {
+               if (!ms->ch[i].slctunitid || (mask & (1 << i)))
+                       continue;
+               if (usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), GET_CUR, USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN,
+                                   0, ms->iface | (ms->ch[i].slctunitid << 8), &buf, 1, HZ) < 0) {
+                       err = -EIO;
+                       printk(KERN_ERR "usbaudio: selector read request device %u if %u unit %u failed\n", 
+                              dev->devnum, ms->iface, ms->ch[i].slctunitid & 0xff);
+                       continue;
+               }
+               /* first generate smask */
+               smask = bmask = 0;
+               for (j = i; j < ms->numch; i++) {
+                       if ((ms->ch[i].slctunitid ^ ms->ch[j].slctunitid) & 0xff)
+                               continue;
+                       smask |= 1 << ms->ch[j].osschannel;
+                       if (buf == (ms->ch[j].slctunitid >> 8))
+                               bmask |= 1 << ms->ch[j].osschannel;
+                       mask |= 1 << j;
+               }
+               /* check for multiple set sources */
+               j = hweight32(srcmask & smask);
+               if (j == 0)
+                       continue;
+               if (j > 1)
+                       srcmask &= ~bmask;
+               for (j = i; j < ms->numch; i++) {
+                       if ((ms->ch[i].slctunitid ^ ms->ch[j].slctunitid) & 0xff)
+                               continue;
+                       if (!(srcmask & (1 << ms->ch[j].osschannel)))
+                               continue;
+                       buf = ms->ch[j].slctunitid >> 8;
+                       if (usb_control_msg(dev, usb_sndctrlpipe(dev, 0), SET_CUR, USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_OUT,
+                                   0, ms->iface | (ms->ch[j].slctunitid << 8), &buf, 1, HZ) < 0) {
+                               err = -EIO;
+                               printk(KERN_ERR "usbaudio: selector write request device %u if %u unit %u failed\n", 
+                                      dev->devnum, ms->iface, ms->ch[j].slctunitid & 0xff);
+                               continue;
+                       }
+               }
+       }
+       return err ? -EIO : 0;
+}
+
 /* --------------------------------------------------------------------- */
 
 /*
@@ -1886,8 +1985,10 @@ static int usb_audio_ioctl_mixdev(struct inode *inode, struct file *file, unsign
        if (_IOC_DIR(cmd) == _IOC_READ) {
                switch (_IOC_NR(cmd)) {
                case SOUND_MIXER_RECSRC: /* Arg contains a bit for each recording source */
-                       /* don't know how to handle this yet */
-                       return put_user(0, (int *)arg);
+                       val = get_rec_src(ms);
+                       if (val < 0)
+                               return val;
+                       return put_user(val, (int *)arg);
 
                case SOUND_MIXER_DEVMASK: /* Arg contains a bit for each supported device */
                        for (val = i = 0; i < ms->numch; i++)
@@ -1895,9 +1996,11 @@ static int usb_audio_ioctl_mixdev(struct inode *inode, struct file *file, unsign
                        return put_user(val, (int *)arg);
 
                case SOUND_MIXER_RECMASK: /* Arg contains a bit for each supported recording source */
-                       /* don't know how to handle this yet */
-                       return put_user(0, (int *)arg);
-                        
+                       for (val = i = 0; i < ms->numch; i++)
+                               if (ms->ch[i].slctunitid)
+                                       val |= 1 << ms->ch[i].osschannel;
+                       return put_user(val, (int *)arg);
+
                case SOUND_MIXER_STEREODEVS: /* Mixer channels supporting stereo */
                        for (val = i = 0; i < ms->numch; i++)
                                if (ms->ch[i].flags & (MIXFLG_STEREOIN | MIXFLG_STEREOOUT))
@@ -1905,7 +2008,7 @@ static int usb_audio_ioctl_mixdev(struct inode *inode, struct file *file, unsign
                        return put_user(val, (int *)arg);
                        
                case SOUND_MIXER_CAPS:
-                       return put_user(0, (int *)arg);
+                       return put_user(SOUND_CAP_EXCL_INPUT, (int *)arg);
 
                default:
                        i = _IOC_NR(cmd);
@@ -1925,8 +2028,7 @@ static int usb_audio_ioctl_mixdev(struct inode *inode, struct file *file, unsign
        switch (_IOC_NR(cmd)) {
        case SOUND_MIXER_RECSRC: /* Arg contains a bit for each recording source */
                get_user_ret(val, (int *)arg, -EFAULT);
-               /* set recording source: val */
-               return 0;
+               return set_rec_src(ms, val);
 
        default:
                i = _IOC_NR(cmd);
@@ -2852,7 +2954,7 @@ static unsigned int getvolchannel(struct consmixstate *state)
 {
        unsigned int u;
 
-       if ((state->termtype & 0xff00) == 0x0000 && !(state->mixchmask & SOUND_MASK_VOLUME))
+       if ((state->termtype & 0xff00) == 0x0000 && (state->mixchmask & SOUND_MASK_VOLUME))
                return SOUND_MIXER_VOLUME;
        if ((state->termtype & 0xff00) == 0x0100) {
                if (state->mixchmask & SOUND_MASK_PCM)
@@ -2864,8 +2966,6 @@ static unsigned int getvolchannel(struct consmixstate *state)
                return SOUND_MIXER_MIC;
        if ((state->termtype & 0xff00) == 0x0300 && (state->mixchmask & SOUND_MASK_SPEAKER))
                return SOUND_MIXER_SPEAKER;
-       if ((state->termtype & 0xff00) == 0x0300 && (state->mixchmask & SOUND_MASK_SPEAKER))
-               return SOUND_MIXER_SPEAKER;
        if ((state->termtype & 0xff00) == 0x0500) {
                if (state->mixchmask & SOUND_MASK_PHONEIN)
                        return SOUND_MIXER_PHONEIN;
@@ -2950,7 +3050,7 @@ static void prepmixch(struct consmixstate *state)
                if (v3 > 100)
                        v3 = 100;
                ch->value = v3;
-               if (ch->chnum != 0) {
+               if (ch->flags & (MIXFLG_STEREOIN | MIXFLG_STEREOOUT)) {
                        if (usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), GET_CUR, USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN,
                                            (ch->selector << 8) | (ch->chnum + 1), state->ctrlif | (ch->unitid << 8), buf, 2, HZ) < 0)
                                goto err;
@@ -2986,7 +3086,7 @@ static void prepmixch(struct consmixstate *state)
                if (v3 > 100)
                        v3 = 100;
                ch->value = v3;
-               if (ch->chnum != 0) {
+               if (ch->flags & (MIXFLG_STEREOIN | MIXFLG_STEREOOUT)) {
                        if (usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), GET_CUR, USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN,
                                            (ch->selector << 8) | (ch->chnum + 1), state->ctrlif | (ch->unitid << 8), buf, 1, HZ) < 0)
                                goto err;
@@ -3095,15 +3195,24 @@ static void usb_audio_mixerunit(struct consmixstate *state, unsigned char *mixer
 
 static void usb_audio_selectorunit(struct consmixstate *state, unsigned char *selector)
 {
-       unsigned int chnum, i;
+       unsigned int chnum, i, mixch;
+       struct mixerchannel *mch;
 
        if (!selector[4]) {
                printk(KERN_ERR "usbaudio: unit %u invalid SELECTOR_UNIT descriptor\n", selector[3]);
                return;
        }
+       mixch = state->nrmixch;
        usb_audio_recurseunit(state, selector[5]);
+       if (state->nrmixch != mixch) {
+               mch = &state->mixch[state->nrmixch-1];
+               mch->slctunitid = selector[5] | (1 << 8);
+       } else {
+               printk(KERN_INFO "usbaudio: selector unit %u: ignoring channel 1\n", selector[3]);
+       }
        chnum = state->nrchannels;
        for (i = 1; i < selector[4]; i++) {
+               mixch = state->nrmixch;
                usb_audio_recurseunit(state, selector[5+i]);
                if (chnum != state->nrchannels) {
                        printk(KERN_ERR "usbaudio: selector unit %u: input pins with varying channel numbers\n", selector[3]);
@@ -3112,6 +3221,12 @@ static void usb_audio_selectorunit(struct consmixstate *state, unsigned char *se
                        state->nrchannels = 0;
                        return;
                }
+               if (state->nrmixch != mixch) {
+                       mch = &state->mixch[state->nrmixch-1];
+                       mch->slctunitid = selector[5] | ((i + 1) << 8);
+               } else {
+                       printk(KERN_INFO "usbaudio: selector unit %u: ignoring channel %u\n", selector[3], i+1);
+               }
        }
        state->termtype = 0;
        state->chconfig = 0;
@@ -3167,7 +3282,7 @@ static void usb_audio_featureunit(struct consmixstate *state, unsigned char *ftr
                        ch->unitid = ftr[3];
                        ch->selector = VOLUME_CONTROL;
                        ch->chnum = 1;
-                       ch->flags = MIXFLG_STEREOIN | MIXFLG_STEREOOUT;
+                       ch->flags = (state->nrchannels > 1) ? (MIXFLG_STEREOIN | MIXFLG_STEREOOUT) : 0;
                        prepmixch(state);
                }
        } else if (mchftr & 2) {
@@ -3187,7 +3302,7 @@ static void usb_audio_featureunit(struct consmixstate *state, unsigned char *ftr
                        ch->unitid = ftr[3];
                        ch->selector = BASS_CONTROL;
                        ch->chnum = 1;
-                       ch->flags = MIXFLG_STEREOIN | MIXFLG_STEREOOUT;
+                       ch->flags = (state->nrchannels > 1) ? (MIXFLG_STEREOIN | MIXFLG_STEREOOUT) : 0;
                        prepmixch(state);
                }
        } else if (mchftr & 4) {
@@ -3207,7 +3322,7 @@ static void usb_audio_featureunit(struct consmixstate *state, unsigned char *ftr
                        ch->unitid = ftr[3];
                        ch->selector = TREBLE_CONTROL;
                        ch->chnum = 1;
-                       ch->flags = MIXFLG_STEREOIN | MIXFLG_STEREOOUT;
+                       ch->flags = (state->nrchannels > 1) ? (MIXFLG_STEREOIN | MIXFLG_STEREOOUT) : 0;
                        prepmixch(state);
                }
        } else if (mchftr & 16) {
@@ -3239,7 +3354,7 @@ static void usb_audio_recurseunit(struct consmixstate *state, unsigned char unit
        unsigned int i, j;
 
        if (test_and_set_bit(unitid, &state->unitbitmap)) {
-               printk(KERN_ERR "usbaudio: mixer path recursion detected, unit %d!\n", unitid);
+               printk(KERN_INFO "usbaudio: mixer path revisits unit %d\n", unitid);
                return;
        }
        p1 = find_audiocontrol_unit(state->buffer, state->buflen, NULL, unitid, state->ctrlif);
index 2deab03fa63110b7b49889fa33e109bc02436d97..c083f2982326efdc025fb38e0c5c92f34961cc7c 100644 (file)
@@ -7,6 +7,22 @@
  *
  * (C) Copyright 1999 Johannes Erdfelt
  * (C) Copyright 1999 Randy Dunlap
+ *
+ * 5/24/00 Removed optional (and unnecessary) locking of the driver while
+ * the device remains plugged in. Corrected race conditions in ibmcam_open
+ * and ibmcam_probe() routines using this as a guideline:
+ *
+ * (2) The big kernel lock is automatically released when a process sleeps
+ *   in the kernel and is automatically reacquired on reschedule if the
+ *   process had the lock originally.  Any code that can be compiled as
+ *   a module and is entered with the big kernel lock held *MUST*
+ *   increment the use count to activate the indirect module protection
+ *   before doing anything that might sleep.
+ *
+ *   In practice, this means that all routines that live in modules and
+ *   are invoked under the big kernel lock should do MOD_INC_USE_COUNT
+ *   as their very first action.  And all failure paths from that
+ *   routine must do MOD_DEC_USE_COUNT before returning.
  */
 
 #include <linux/kernel.h>
 
 #include "ibmcam.h"
 
-/*
- * IBMCAM_LOCKS_DRIVER_WHILE_DEVICE_IS_PLUGGED: This symbol controls
- * the locking of the driver. If non-zero, the driver counts the
- * probe() call as usage and increments module usage counter; this
- * effectively prevents removal of the module (with rmmod) until the
- * device is unplugged (then disconnect() callback reduces the module
- * usage counter back, and module can be removed).
- *
- * This behavior may be useful if you prefer to lock the driver in
- * memory until device is unplugged. However you can't reload the
- * driver if you want to alter some parameters - you'd need to unplug
- * the camera first. Therefore, I recommend setting 0.
- */
-#define IBMCAM_LOCKS_DRIVER_WHILE_DEVICE_IS_PLUGGED    0
-
 #define        ENABLE_HEXDUMP  0       /* Enable if you need it */
 static int debug = 0;
 
@@ -2346,6 +2347,7 @@ static int ibmcam_new_frame(struct usb_ibmcam *ibmcam, int framenum)
  *          camera is also initialized here (once per connect), at
  *          expense of V4L client (it waits on open() call).
  * 1/27/00  Used IBMCAM_NUMSBUF as number of URB buffers.
+ * 5/24/00  Corrected to prevent race condition (MOD_xxx_USE_COUNT).
  */
 static int ibmcam_open(struct video_device *dev, int flags)
 {
@@ -2353,6 +2355,7 @@ static int ibmcam_open(struct video_device *dev, int flags)
        const int sb_size = FRAMES_PER_DESC * ibmcam->iso_packet_len;
        int i, err = 0;
 
+       MOD_INC_USE_COUNT;
        down(&ibmcam->lock);
 
        if (ibmcam->user)
@@ -2425,14 +2428,13 @@ static int ibmcam_open(struct video_device *dev, int flags)
                                else
                                        err = -EBUSY;
                        }
-                       if (!err) {
+                       if (!err)
                                ibmcam->user++;
-                               MOD_INC_USE_COUNT;
-                       }
                }
        }
-
        up(&ibmcam->lock);
+       if (err)
+               MOD_DEC_USE_COUNT;
        return err;
 }
 
@@ -2446,6 +2448,7 @@ static int ibmcam_open(struct video_device *dev, int flags)
  * History:
  * 1/22/00  Moved scratch buffer deallocation here.
  * 1/27/00  Used IBMCAM_NUMSBUF as number of URB buffers.
+ * 5/24/00  Moved MOD_DEC_USE_COUNT outside of code that can sleep.
  */
 static void ibmcam_close(struct video_device *dev)
 {
@@ -2462,13 +2465,13 @@ static void ibmcam_close(struct video_device *dev)
                kfree(ibmcam->sbuf[i].data);
 
        ibmcam->user--;
-       MOD_DEC_USE_COUNT;
 
        if (ibmcam->remove_pending) {
                printk(KERN_INFO "ibmcam_close: Final disconnect.\n");
                usb_ibmcam_release(ibmcam);
        }
        up(&ibmcam->lock);
+       MOD_DEC_USE_COUNT;
 }
 
 static int ibmcam_init_done(struct video_device *dev)
@@ -2891,7 +2894,7 @@ static void usb_ibmcam_configure_video(struct usb_ibmcam *ibmcam)
 }
 
 /*
- * usb_ibmcam_release()
+ * ibmcam_find_struct()
  *
  * This code searches the array of preallocated (static) structures
  * and returns index of the first one that isn't in use. Returns -1
@@ -2929,6 +2932,7 @@ static int ibmcam_find_struct(void)
  * History:
  * 1/22/00  Moved camera init code to ibmcam_open()
  * 1/27/00  Changed to use static structures, added locking.
+ * 5/24/00  Corrected to prevent race condition (MOD_xxx_USE_COUNT).
  */
 static void *usb_ibmcam_probe(struct usb_device *dev, unsigned int ifnum)
 {
@@ -2994,10 +2998,14 @@ static void *usb_ibmcam_probe(struct usb_device *dev, unsigned int ifnum)
                RESTRICT_TO_RANGE(videosize, VIDEOSIZE_176x144, VIDEOSIZE_352x240);
        }
 
+       /* Code below may sleep, need to lock module while we are here */
+       MOD_INC_USE_COUNT;
+
        devnum = ibmcam_find_struct();
        if (devnum == -1) {
                printk(KERN_INFO "IBM USB camera driver: Too many devices!\n");
-               return NULL;
+               ibmcam = NULL; /* Do not free, it's preallocated */
+               goto probe_done;
        }
        ibmcam = &cams[devnum];
 
@@ -3017,17 +3025,14 @@ static void *usb_ibmcam_probe(struct usb_device *dev, unsigned int ifnum)
        usb_ibmcam_configure_video(ibmcam);
        up (&ibmcam->lock);
 
-#if IBMCAM_LOCKS_DRIVER_WHILE_DEVICE_IS_PLUGGED
-       MOD_INC_USE_COUNT;
-#endif
-
        if (video_register_device(&ibmcam->vdev, VFL_TYPE_GRABBER) == -1) {
                printk(KERN_ERR "video_register_device failed\n");
-               return NULL;
+               ibmcam = NULL; /* Do not free, it's preallocated */
        }
        if (debug > 1)
                printk(KERN_DEBUG "video_register_device() successful\n");
-
+probe_done:
+       MOD_DEC_USE_COUNT;
        return ibmcam;
 }
 
@@ -3055,17 +3060,26 @@ static void usb_ibmcam_release(struct usb_ibmcam *ibmcam)
  * structure (pointed by 'ptr') and after that driver should be removable
  * with no ill consequences.
  *
- * TODO: This code behaves badly on surprise removal!
+ * This code handles surprise removal. The ibmcam->user is a counter which
+ * increments on open() and decrements on close(). If we see here that
+ * this counter is not 0 then we have a client who still has us opened.
+ * We set ibmcam->remove_pending flag as early as possible, and after that
+ * all access to the camera will gracefully fail. These failures should
+ * prompt client to (eventually) close the video device, and then - in
+ * ibmcam_close() - we decrement ibmcam->ibmcam_used and usage counter.
  *
  * History:
  * 1/22/00  Added polling of MOD_IN_USE to delay removal until all users gone.
  * 1/27/00  Reworked to allow pending disconnects; see ibmcam_close()
+ * 5/24/00  Corrected to prevent race condition (MOD_xxx_USE_COUNT).
  */
 static void usb_ibmcam_disconnect(struct usb_device *dev, void *ptr)
 {
        static const char proc[] = "usb_ibmcam_disconnect";
        struct usb_ibmcam *ibmcam = (struct usb_ibmcam *) ptr;
 
+       MOD_INC_USE_COUNT;
+
        if (debug > 0)
                printk(KERN_DEBUG "%s(%p,%p.)\n", proc, dev, ptr);
 
@@ -3077,16 +3091,14 @@ static void usb_ibmcam_disconnect(struct usb_device *dev, void *ptr)
 
        ibmcam->dev = NULL;         /* USB device is no more */
 
-#if IBMCAM_LOCKS_DRIVER_WHILE_DEVICE_IS_PLUGGED
-       MOD_DEC_USE_COUNT;
-#endif
        if (ibmcam->user)
                printk(KERN_INFO "%s: In use, disconnect pending.\n", proc);
        else
                usb_ibmcam_release(ibmcam);
        up(&ibmcam->lock);
-
        printk(KERN_INFO "IBM USB camera disconnected.\n");
+
+       MOD_DEC_USE_COUNT;
 }
 
 static struct usb_driver ibmcam_driver = {
index e97410c32ecd5e20a507d7f9a624309b50915f09..73a54a7b2039b17543305560d628598f57ead828 100644 (file)
@@ -30,7 +30,7 @@
  * Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
-static const char version[] = "1.14";
+static const char version[] = "1.15";
 
 #define __NO_VERSION__
 
@@ -263,9 +263,10 @@ static void rvfree(void *mem, unsigned long size)
  * Based on the CPiA driver version 0.7.4 -claudio
  **********************************************************************/
 
-#ifdef CONFIG_PROC_FS
+#if defined(CONFIG_PROC_FS) && defined(CONFIG_VIDEO_PROC_FS)
+
 static struct proc_dir_entry *ov511_proc_entry = NULL;
-static struct proc_dir_entry *video_proc_entry = NULL;
+extern struct proc_dir_entry *video_proc_entry;
 
 #define YES_NO(x) ((x) ? "yes" : "no")
 
@@ -343,6 +344,7 @@ static int ov511_read_proc(char *page, char **start, off_t off,
                len = count;
 
        *start = page + off;
+
        return len;
 }
 
@@ -357,12 +359,11 @@ static void create_proc_ov511_cam (struct usb_ov511 *ov511)
        char name[7];
        struct proc_dir_entry *ent;
        
-       PDEBUG (4, "creating /proc/video/ov511/videoX entry");
        if (!ov511_proc_entry || !ov511)
                return;
 
        sprintf(name, "video%d", ov511->vdev.minor);
-       PDEBUG (4, "creating %s", name);
+       PDEBUG (4, "creating /proc/video/ov511/%s", name);
        
        ent = create_proc_entry(name, S_IFREG|S_IRUGO|S_IWUSR, ov511_proc_entry);
 
@@ -372,7 +373,6 @@ static void create_proc_ov511_cam (struct usb_ov511 *ov511)
        ent->data = ov511;
        ent->read_proc = ov511_read_proc;
        ent->write_proc = ov511_write_proc;
-       ent->size = 3626;       /* FIXME */
        ov511->proc_entry = ent;
 }
 
@@ -391,22 +391,13 @@ static void destroy_proc_ov511_cam (struct usb_ov511 *ov511)
 
 static void proc_ov511_create(void)
 {
-       struct proc_dir_entry *p = NULL;
-
        /* No current standard here. Alan prefers /proc/video/ as it keeps
         * /proc "less cluttered than /proc/randomcardifoundintheshed/"
         * -claudio
         */
-       PDEBUG (3, "creating /proc/video");
-       video_proc_entry = proc_mkdir("video", p);
-       if (!video_proc_entry) {
-               if (!p) {
-                       err("Unable to initialise /proc/video\n");
-                       return;
-               } else {        /* FIXME - this doesn't work */
-                       PDEBUG (3, "/proc/video already exists");
-                       video_proc_entry = p;
-               }
+       if (video_proc_entry == NULL) {
+               err("Unable to initialise /proc/video/ov511");
+               return;
        }
 
        ov511_proc_entry = create_proc_entry("ov511", S_IFDIR, video_proc_entry);
@@ -414,16 +405,19 @@ static void proc_ov511_create(void)
        if (ov511_proc_entry)
                ov511_proc_entry->owner = THIS_MODULE;
        else
-               err("Unable to initialise /proc/video/ov511\n");
+               err("Unable to initialise /proc/ov511");
 }
 
 static void proc_ov511_destroy(void)
 {
        PDEBUG (3, "removing /proc/video/ov511");
+
+       if (ov511_proc_entry == NULL)
+               return;
+
        remove_proc_entry("ov511", video_proc_entry);
-       remove_proc_entry("video", NULL);
 }
-#endif /* CONFIG_PROC_FS */
+#endif /* CONFIG_PROC_FS && CONFIG_VIDEO_PROC_FS */
 
 
 /**********************************************************************
@@ -852,7 +846,7 @@ ov7610_get_picture(struct usb_ov511 *ov511, struct video_picture *p)
        return 0;
 }
 
-/* FIXME: add 176x144, 160x140 */
+/* FIXME: add 400x300, 176x144, 160x140 */
 static struct mode_list mlist[] = {
        { 640, 480, VIDEO_PALETTE_GREY, 0x4f, 0x3d, 0x00, 0x00,
          0x4f, 0x3d, 0x00, 0x00, 0x04, 0x03, 0x24, 0x04, 0x9e },
@@ -866,6 +860,14 @@ static struct mode_list mlist[] = {
          0x2b, 0x25, 0x00, 0x00, 0x01, 0x03, 0x04, 0x04, 0x1e },
        { 352, 288, VIDEO_PALETTE_RGB24,0x2b, 0x25, 0x00, 0x00,
          0x2b, 0x25, 0x00, 0x00, 0x01, 0x03, 0x04, 0x04, 0x1e },
+       { 384, 288, VIDEO_PALETTE_GREY, 0x2f, 0x25, 0x00, 0x00,
+         0x2f, 0x25, 0x00, 0x00, 0x01, 0x03, 0x04, 0x04, 0x1e },
+       { 384, 288, VIDEO_PALETTE_RGB24,0x2f, 0x25, 0x00, 0x00,
+         0x2f, 0x25, 0x00, 0x00, 0x01, 0x03, 0x04, 0x04, 0x1e },
+       { 448, 336, VIDEO_PALETTE_GREY, 0x37, 0x29, 0x00, 0x00,
+         0x37, 0x29, 0x00, 0x00, 0x01, 0x03, 0x04, 0x04, 0x1e },
+       { 448, 336, VIDEO_PALETTE_RGB24,0x37, 0x29, 0x00, 0x00,
+         0x37, 0x29, 0x00, 0x00, 0x01, 0x03, 0x04, 0x04, 0x1e },
        { 0, 0 }
 };
 
@@ -1302,158 +1304,190 @@ static int ov511_move_data(struct usb_ov511 *ov511, urb_t *urb)
        int i, totlen = 0;
        int aPackNum[10];
        struct ov511_frame *frame;
+       unsigned char *pData;
+       int iPix;
 
-       PDEBUG(4, "ov511_move_data");
+       PDEBUG (4, "Moving %d packets", urb->number_of_packets);
 
        for (i = 0; i < urb->number_of_packets; i++) {
                int n = urb->iso_frame_desc[i].actual_length;
                int st = urb->iso_frame_desc[i].status;
+
                urb->iso_frame_desc[i].actual_length = 0;
                urb->iso_frame_desc[i].status = 0;
+
                cdata = urb->transfer_buffer + urb->iso_frame_desc[i].offset;
 
                aPackNum[i] = n ? cdata[ov511->packet_size - 1] : -1;
 
-               if (!n || ov511->curframe == -1) continue;
+               if (!n || ov511->curframe == -1)
+                       continue;
 
                if (st)
                        PDEBUG(2, "data error: [%d] len=%d, status=%d", i, n, st);
 
                frame = &ov511->frame[ov511->curframe];
                
-               /* Can we find a frame end */
+               /* SOF/EOF packets have 1st to 8th bytes zeroed and the 9th
+                * byte non-zero. The EOF packet has image width/height in the
+                * 10th and 11th packets. The 9th bit is given as follows:
+                *
+                * bit 7: EOF
+                *     6: compression enabled
+                *     5: 422/420/400 modes
+                *     4: 422/420/400 modes
+                *     3: 1
+                *     2: snapshot bottom on
+                *     1: snapshot frame
+                *     0: even/odd field
+                */
+
+               /* Check for SOF/EOF packet */
                if ((cdata[0] | cdata[1] | cdata[2] | cdata[3] | 
-                    cdata[4] | cdata[5] | cdata[6] | cdata[7]) == 0 &&
-                   (cdata[8] & 8) && (cdata[8] & 0x80)) {
+                    cdata[4] | cdata[5] | cdata[6] | cdata[7]) ||
+                    (~cdata[8] & 0x08))
+                       goto check_middle;
+
+               /* Frame end */
+               if (cdata[8] & 0x80) {
+#if 0
+                       struct timeval *ts;
+
+                       ts = (struct timeval *)(frame->data + MAX_FRAME_SIZE);
+                       do_gettimeofday (ts);
+#endif
 
-                   struct timeval *ts;
-                   ts = (struct timeval *)(frame->data + MAX_FRAME_SIZE);
-                   do_gettimeofday(ts);
+                       PDEBUG(4, "Frame end, curframe = %d, packnum=%d, hw=%d, vw=%d",
+                               ov511->curframe, (int)(cdata[ov511->packet_size - 1]),
+                               (int)(cdata[9]), (int)(cdata[10]));
 
-                   PDEBUG(4, "Frame End, curframe = %d, packnum=%d, hw=%d, vw=%d",
-                          ov511->curframe, (int)(cdata[ov511->packet_size - 1]),
-                          (int)(cdata[9]), (int)(cdata[10]));
+                       if (frame->scanstate == STATE_LINES) {
+                               int iFrameNext;
 
-                   if (frame->scanstate == STATE_LINES) {
-                       int iFrameNext;
                                if (fix_rgb_offset)
                                        fixFrameRGBoffset(frame);
                                frame->grabstate = FRAME_DONE;
-                       if (waitqueue_active(&frame->wq)) {
-                                       frame->grabstate = FRAME_DONE;
-                                       wake_up_interruptible(&frame->wq);
+
+                               if (waitqueue_active(&frame->wq)) {
+                                       frame->grabstate = FRAME_DONE;
+                                       wake_up_interruptible(&frame->wq);
                                }
-                               /* If next frame is ready or grabbing, point to it */
+
+                               /* If next frame is ready or grabbing,
+                                 * point to it */
                                iFrameNext = (ov511->curframe + 1) % OV511_NUMFRAMES;
-                               if (ov511->frame[iFrameNext].grabstate== FRAME_READY ||
-                                   ov511->frame[iFrameNext].grabstate== FRAME_GRABBING) {
-                                 ov511->curframe = iFrameNext;
-                                 ov511->frame[iFrameNext].scanstate = STATE_SCANNING;
+                               if (ov511->frame[iFrameNext].grabstate == FRAME_READY
+                                   || ov511->frame[iFrameNext].grabstate == FRAME_GRABBING) {
+                                       ov511->curframe = iFrameNext;
+                                       ov511->frame[iFrameNext].scanstate = STATE_SCANNING;
                                } else {
-
-                                 PDEBUG(4, "Frame not ready? state = %d",
-                                        ov511->frame[iFrameNext].grabstate);
-
-                                 ov511->curframe = -1;
+                                       if (frame->grabstate == FRAME_DONE) {
+                                               PDEBUG(4, "Frame done! congratulations");
+                                       } else {
+                                               PDEBUG(4, "Frame not ready? state = %d",
+                                                       ov511->frame[iFrameNext].grabstate);
+                                       }
+
+                                       ov511->curframe = -1;
                                }
-                   }
-               }
-
-               /* Can we find a frame start */
-               else if ((cdata[0] | cdata[1] | cdata[2] | cdata[3] | 
-                         cdata[4] | cdata[5] | cdata[6] | cdata[7]) == 0 &&
-                        (cdata[8] & 8)) {
-
-                       PDEBUG(4, "ov511: Found Frame Start!, framenum = %d",
-                              ov511->curframe);
+                       }
+                       /* Image corruption caused by misplaced frame->segment = 0
+                        * fixed by carlosf@conectiva.com.br
+                        */
+               } else {
+                       /* Frame start */
+                       PDEBUG(4, "Frame start, framenum = %d", ov511->curframe);
 
                        /* Check to see if it's a snapshot frame */
                        /* FIXME?? Should the snapshot reset go here? Performance? */
                        if (cdata[8] & 0x02) {
                                frame->snapshot = 1;
-                               PDEBUG(3, "ov511_move_data: snapshot detected");
+                               PDEBUG(3, "snapshot detected");
                        }
 
                        frame->scanstate = STATE_LINES;
                        frame->segment = 0;
                }
 
+check_middle:
                /* Are we in a frame? */
-               if (frame->scanstate == STATE_LINES) {
-                       unsigned char * pData;
-                       int iPix;
-
-                       /* Deal with leftover from last segment, if any */
-                       if (frame->segment) {
-                         pData = ov511->scratch;
-                         iPix = - ov511->scratchlen;
-                         memmove(pData + ov511->scratchlen, cdata,
-                                 iPix+frame->segsize);
-                       } else {
-                         pData = &cdata[iPix = 9];
-                       }
-
-                       /* Parse the segments */
-                       while(iPix <= (ov511->packet_size - 1) - frame->segsize &&
-                             frame->segment < frame->width * frame->height / 256) {
-                         int iSegY;
-                         int iSegUV;
-                         int iY, jY, iUV, jUV;
-                         int iOutY, iOutUV;
-                         unsigned char * pOut;
-
-                         iSegY = iSegUV = frame->segment;
-                         pOut = frame->data;
-                         
-                         frame->segment++;
-                         iPix += frame->segsize;
-
-                         if (frame->sub_flag) {
-                           int iSeg1;
-                           iSeg1 = iSegY / (ov511->subw / 32);
-                           iSeg1 *= frame->width / 32;
-                           iSegY = iSeg1 + (iSegY % (ov511->subw / 32));
-                           if (iSegY >= frame->width * ov511->subh / 256)
-                             break;
-
-                           iSeg1 = iSegUV / (ov511->subw / 16);
-                           iSeg1 *= frame->width / 16;
-                           iSegUV = iSeg1 + (iSegUV % (ov511->subw / 16));
-
-                           pOut += (ov511->subx +
-                                    ov511->suby * frame->width) * frame->depth;
-                         }
-
-                         iY     = iSegY / (frame->width / WDIV);
-                         jY     = iSegY - iY * (frame->width / WDIV);
-                         iOutY  = (iY*HDIV*frame->width + jY*WDIV) * frame->depth;
-                         iUV    = iSegUV / (frame->width / WDIV * 2);
-                         jUV    = iSegUV - iUV * (frame->width / WDIV * 2);
-                         iOutUV = (iUV*HDIV*2*frame->width + jUV*WDIV/2) * frame->depth;
-
-                         if (frame->format == VIDEO_PALETTE_GREY) {
-                           ov511_parse_data_grey(pData, pOut, iOutY, frame->width);
-                         } else if (frame->format == VIDEO_PALETTE_RGB24) {
-                           ov511_parse_data_rgb24(pData, pOut, iOutY, iOutUV, iY & 1,
-                                                  frame->width);
-                         }
-                         pData = &cdata[iPix];
-                       }
+               if (frame->scanstate != STATE_LINES)
+                       continue;
 
-                       /* Save extra data for next time */
-                       if (frame->segment < frame->width * frame->height / 256) {
-                         ov511->scratchlen = (ov511->packet_size - 1) - iPix;
-                         if (ov511->scratchlen < frame->segsize) {
-                           memmove(ov511->scratch, pData, ov511->scratchlen);
-                         } else {
-                           ov511->scratchlen = 0;
-                         }
+               /* Deal with leftover from last segment, if any */
+               if (frame->segment) {
+                       pData = ov511->scratch;
+                       iPix = -ov511->scratchlen;
+                       memmove(pData + ov511->scratchlen, cdata,
+                               iPix+frame->segsize);
+               } else {
+                       pData = &cdata[iPix = 9];
+               }
+
+               /* Parse the segments */
+               while (iPix <= (ov511->packet_size - 1) - frame->segsize &&
+                   frame->segment < frame->width * frame->height / 256) {
+                       int iSegY, iSegUV;
+                       int iY, jY, iUV, jUV;
+                       int iOutY, iOutUV;
+                       unsigned char *pOut;
+
+                       iSegY = iSegUV = frame->segment;
+                       pOut = frame->data;
+                       frame->segment++;
+                       iPix += frame->segsize;
+
+                       /* Handle subwindow */
+                       if (frame->sub_flag) {
+                               int iSeg1;
+
+                               iSeg1 = iSegY / (ov511->subw / 32);
+                               iSeg1 *= frame->width / 32;
+                               iSegY = iSeg1 + (iSegY % (ov511->subw / 32));
+                               if (iSegY >= frame->width * ov511->subh / 256)
+                                       break;
+
+                               iSeg1 = iSegUV / (ov511->subw / 16);
+                               iSeg1 *= frame->width / 16;
+                               iSegUV = iSeg1 + (iSegUV % (ov511->subw / 16));
+
+                               pOut += (ov511->subx + ov511->suby * frame->width) *
+                                       (frame->depth >> 3);
                        }
+
+                       /* 
+                        * iY counts segment lines
+                        * jY counts segment columns
+                        * iOutY is the offset (in bytes) of the segment upper left corner
+                        */
+                       iY = iSegY / (frame->width / WDIV);
+                       jY = iSegY - iY * (frame->width / WDIV);
+                       iOutY = (iY*HDIV*frame->width + jY*WDIV) * (frame->depth >> 3);
+                       iUV = iSegUV / (frame->width / WDIV * 2);
+                       jUV = iSegUV - iUV * (frame->width / WDIV * 2);
+                       iOutUV = (iUV*HDIV*2*frame->width + jUV*WDIV/2) * (frame->depth >> 3);
+
+                       if (frame->format == VIDEO_PALETTE_GREY)
+                               ov511_parse_data_grey (pData, pOut, iOutY, frame->width);
+                       else if (frame->format == VIDEO_PALETTE_RGB24)
+                               ov511_parse_data_rgb24 (pData, pOut, iOutY, iOutUV,
+                                       iY & 1, frame->width);
+
+                       pData = &cdata[iPix];
                }
-       }
 
+               /* Save extra data for next time */
+               if (frame->segment < frame->width * frame->height / 256) {
+                       ov511->scratchlen = (ov511->packet_size - 1) - iPix;
+                       if (ov511->scratchlen < frame->segsize)
+                               memmove(ov511->scratch, pData,
+                                       ov511->scratchlen);
+                       else
+                               ov511->scratchlen = 0;
+               }
+       }
 
-       PDEBUG(5, "pn: %d %d %d %d %d %d %d %d %d %d\n",
+       PDEBUG(5, "pn: %d %d %d %d %d %d %d %d %d %d",
               aPackNum[0], aPackNum[1], aPackNum[2], aPackNum[3], aPackNum[4],
               aPackNum[5],aPackNum[6], aPackNum[7], aPackNum[8], aPackNum[9]);
 
@@ -1472,8 +1506,6 @@ static void ov511_isoc_irq(struct urb *urb)
        if (!ov511->streaming) {
                PDEBUG(2, "hmmm... not streaming, but got interrupt");
                return;
-       } else {
-               PDEBUG(5, "streaming. got interrupt");
        }
        
        sbuf = &ov511->sbuf[ov511->cursbuf];
@@ -1723,7 +1755,7 @@ static void ov511_close(struct video_device *dev)
 
 static int ov511_init_done(struct video_device *dev)
 {
-#ifdef CONFIG_PROC_FS
+#if defined(CONFIG_PROC_FS) && defined(CONFIG_VIDEO_PROC_FS)
        create_proc_ov511_cam((struct usb_ov511 *)dev);
 #endif
 
@@ -1749,6 +1781,8 @@ static int ov511_ioctl(struct video_device *vdev, unsigned int cmd, void *arg)
        {
                struct video_capability b;
 
+               PDEBUG (4, "VIDIOCGCAP");
+
                strcpy(b.name, "OV511 USB Camera");
                b.type = VID_TYPE_CAPTURE | VID_TYPE_SUBCAPTURE;
                b.channels = 1;
@@ -1798,6 +1832,8 @@ static int ov511_ioctl(struct video_device *vdev, unsigned int cmd, void *arg)
        {
                struct video_picture p;
 
+               PDEBUG (4, "VIDIOCGPICT");
+
                if (ov7610_get_picture(ov511, &p))
                        return -EIO;
                                                        
@@ -1809,18 +1845,33 @@ static int ov511_ioctl(struct video_device *vdev, unsigned int cmd, void *arg)
        case VIDIOCSPICT:
        {
                struct video_picture p;
+               int i;
+
+               PDEBUG (4, "VIDIOCSPICT");
 
                if (copy_from_user(&p, arg, sizeof(p)))
                        return -EFAULT;
-                       
+
                if (ov7610_set_picture(ov511, &p))
                        return -EIO;
 
+               /* FIXME: check validity */
+
+               PDEBUG(4, "Setting depth=%d, palette=%d", p.depth, p.palette);
+               for (i = 0; i < OV511_NUMFRAMES; i++) {
+                       ov511->frame[i].depth = p.depth;
+                       ov511->frame[i].format = p.palette;
+                       ov511->frame[i].segsize = GET_SEGSIZE(p.palette);
+               }
+
                return 0;
        }
        case VIDIOCGCAPTURE:
        {
                int vf;
+
+               PDEBUG (4, "VIDIOCGCAPTURE");
+
                if (copy_from_user(&vf, arg, sizeof(vf)))
                        return -EFAULT;
                ov511->sub_flag = vf;
@@ -1836,16 +1887,25 @@ static int ov511_ioctl(struct video_device *vdev, unsigned int cmd, void *arg)
                        return -EINVAL;
                if (vc.decimation)
                        return -EINVAL;
+#if 0
                vc.x /= 4;
                vc.x *= 4;
                vc.y /= 2;
                vc.y *= 2;
                vc.width /= 32;
                vc.width *= 32;
-               if (vc.width == 0) vc.width = 32;
+#else
+               vc.x &= ~3L;
+               vc.y &= ~1L;
+               vc.y &= ~31L;
+#endif
+               if (vc.width == 0)
+                       vc.width = 32;
+
                vc.height /= 16;
                vc.height *= 16;
-               if (vc.height == 0) vc.height = 16;
+               if (vc.height == 0)
+                       vc.height = 16;
 
                ov511->subx = vc.x;
                ov511->suby = vc.y;
@@ -1857,9 +1917,15 @@ static int ov511_ioctl(struct video_device *vdev, unsigned int cmd, void *arg)
        case VIDIOCSWIN:
        {
                struct video_window vw;
+               int i, result;
 
                if (copy_from_user(&vw, arg, sizeof(vw)))
                        return -EFAULT;
+
+               PDEBUG (4, "VIDIOCSWIN: width=%d, height=%d",
+                       vw.width, vw.height);
+
+#if 0
                if (vw.flags)
                        return -EINVAL;
                if (vw.clipcount)
@@ -1868,8 +1934,22 @@ static int ov511_ioctl(struct video_device *vdev, unsigned int cmd, void *arg)
                        return -EINVAL;
                if (vw.width != DEFAULT_WIDTH)
                        return -EINVAL;
+#endif
+
+               /* If we're collecting previous frame wait
+                  before changing modes */
+               interruptible_sleep_on(&ov511->wq);
+               if (signal_pending(current)) return -EINTR;
 
-               ov511->compress = 0;
+               result = ov511_mode_init_regs(ov511, vw.width, vw.height,
+                       ov511->frame[0].format, ov511->sub_flag);
+               if (result < 0)
+                       return result;
+
+               for (i = 0; i < OV511_NUMFRAMES; i++) {
+                       ov511->frame[i].width = vw.width;
+                       ov511->frame[i].height = vw.height;
+               }
 
                return 0;
        }
@@ -1877,13 +1957,15 @@ static int ov511_ioctl(struct video_device *vdev, unsigned int cmd, void *arg)
        {
                struct video_window vw;
 
-               vw.x = 0;
+               vw.x = 0;               /* FIXME */
                vw.y = 0;
-               vw.width = DEFAULT_WIDTH;
-               vw.height = DEFAULT_HEIGHT;
+               vw.width = ov511->frame[0].width;
+               vw.height = ov511->frame[0].height;
                vw.chromakey = 0;
                vw.flags = 30;
 
+               PDEBUG (4, "VIDIOCGWIN: %dx%d", vw.width, vw.height);
+
                if (copy_to_user(arg, &vw, sizeof(vw)))
                        return -EFAULT;
 
@@ -1935,19 +2017,16 @@ static int ov511_ioctl(struct video_device *vdev, unsigned int cmd, void *arg)
                           before changing modes */
                        interruptible_sleep_on(&ov511->wq);
                        if (signal_pending(current)) return -EINTR;
-                       ov511_mode_init_regs(ov511,
-                                            vm.width, vm.height,
-                                            vm.format, ov511->sub_flag);
+                       ov511_mode_init_regs(ov511, vm.width, vm.height,
+                               vm.format, ov511->sub_flag);
                }
 
                ov511->frame[vm.frame].width = vm.width;
                ov511->frame[vm.frame].height = vm.height;
                ov511->frame[vm.frame].format = vm.format;
                ov511->frame[vm.frame].sub_flag = ov511->sub_flag;
-               ov511->frame[vm.frame].segsize =
-                 vm.format == VIDEO_PALETTE_RGB24 ? 384 : 256;
-               ov511->frame[vm.frame].depth =
-                 vm.format == VIDEO_PALETTE_RGB24 ? 3 : 1;
+               ov511->frame[vm.frame].segsize = GET_SEGSIZE(vm.format);
+               ov511->frame[vm.frame].depth = GET_DEPTH(vm.format);
 
                /* Mark it as ready */
                ov511->frame[vm.frame].grabstate = FRAME_READY;
@@ -1965,11 +2044,11 @@ static int ov511_ioctl(struct video_device *vdev, unsigned int cmd, void *arg)
                       ov511->frame[frame].grabstate);
 
                switch (ov511->frame[frame].grabstate) {
-                       case FRAME_UNUSED:
-                               return -EINVAL;
-                       case FRAME_READY:
-                       case FRAME_GRABBING:
-                       case FRAME_ERROR:
+               case FRAME_UNUSED:
+                       return -EINVAL;
+               case FRAME_READY:
+               case FRAME_GRABBING:
+               case FRAME_ERROR:
 redo:
                        if (!ov511->dev)
                                return -EIO;
@@ -1989,23 +2068,21 @@ redo:
                                if ((ret = ov511_new_frame(ov511, frame)) < 0)
                                        return ret;
                                goto redo;
-                       }                               
-                       case FRAME_DONE:
-                               ov511->frame[frame].grabstate = FRAME_UNUSED;
-                               break;
-               }
-
-               ov511->frame[frame].grabstate = FRAME_UNUSED;
-
-               /* Reset the hardware snapshot button */
-               /* FIXME - Is this the best place for this? */
-               if ((ov511->snap_enabled) &&
-                   (ov511->frame[frame].snapshot)) {
-                       ov511->frame[frame].snapshot = 0;
-                       ov511_reg_write(ov511->dev, 0x52, 0x01);
-                       ov511_reg_write(ov511->dev, 0x52, 0x03);
-                       ov511_reg_write(ov511->dev, 0x52, 0x01);
-               }
+                       }                       
+               case FRAME_DONE:
+                       ov511->frame[frame].grabstate = FRAME_UNUSED;
+
+                       /* Reset the hardware snapshot button */
+                       /* FIXME - Is this the best place for this? */
+                       if ((ov511->snap_enabled) &&
+                           (ov511->frame[frame].snapshot)) {
+                               ov511->frame[frame].snapshot = 0;
+                               ov511_reg_write(ov511->dev, OV511_REG_SYSTEM_SNAPSHOT, 0x01);
+                               ov511_reg_write(ov511->dev, OV511_REG_SYSTEM_SNAPSHOT, 0x03);
+                               ov511_reg_write(ov511->dev, OV511_REG_SYSTEM_SNAPSHOT, 0x01);
+                       }
+                       break;
+               } /* end switch */
 
                return 0;
        }
@@ -2038,7 +2115,7 @@ redo:
                return -EINVAL;
        default:
                return -ENOIOCTLCMD;
-       }       /* End switch(cmd) */
+       } /* end switch */
 
        return 0;
 }
@@ -2610,7 +2687,7 @@ static void ov511_disconnect(struct usb_device *dev, void *ptr)
                ov511->sbuf[0].urb = NULL;
        }
 
-#ifdef CONFIG_PROC_FS
+#if defined(CONFIG_PROC_FS) && defined(CONFIG_VIDEO_PROC_FS)
         destroy_proc_ov511_cam(ov511);
 #endif
 
@@ -2637,8 +2714,7 @@ static struct usb_driver ov511_driver = {
 
 static int __init usb_ov511_init(void)
 {
-#ifdef CONFIG_PROC_FS
-       PDEBUG(3, "creating /proc/ov511");
+#if defined(CONFIG_PROC_FS) && defined(CONFIG_VIDEO_PROC_FS)
         proc_ov511_create();
 #endif
 
@@ -2655,7 +2731,7 @@ static void __exit usb_ov511_exit(void)
        usb_deregister(&ov511_driver);
        info("ov511 driver deregistered");
 
-#ifdef CONFIG_PROC_FS
+#if defined(CONFIG_PROC_FS) && defined(CONFIG_VIDEO_PROC_FS)
         proc_ov511_destroy();
 #endif 
 }
index 460d4eba965e326a8f36d1ba4602f246a1002470..02024c90e4a90e2df5e8c0efd4bc93707f3423e9 100644 (file)
@@ -136,6 +136,7 @@ int nfs_reqlist_alloc(struct nfs_server *server)
                return -ENOMEM;
 
        memset(cache, 0, sizeof(*cache));
+       atomic_set(&cache->nr_requests, 0);
        init_waitqueue_head(&cache->request_wait);
        server->rw_requests = cache;
 
@@ -280,7 +281,7 @@ nfs_flushd(struct rpc_task *task)
        cache->runat = jiffies + task->tk_timeout;
 
        spin_lock(&nfs_flushd_lock);
-       if (!cache->nr_requests && !cache->inodes) {
+       if (!atomic_read(&cache->nr_requests) && !cache->inodes) {
                cache->task = NULL;
                task->tk_action = NULL;
        } else
index 44e3030c38142ef3a3acb92d871c9ae4e844d928..cf0ea6ef34cb2a067322ad9bbb85d0c0c705f5b2 100644 (file)
@@ -417,6 +417,8 @@ nfs_read_super(struct super_block *sb, void *raw_data, int silent)
        if (data->wsize == 0)
                server->wsize = nfs_block_size(fsinfo.wtpref, NULL);
        server->dtsize = nfs_block_size(fsinfo.dtpref, NULL);
+       if (server->dtsize > PAGE_CACHE_SIZE)
+               server->dtsize = PAGE_CACHE_SIZE;
        /* NFSv3: we don't have bsize, but rather rtmult and wtmult... */
        if (!fsinfo.bsize)
                fsinfo.bsize = (fsinfo.rtmult>fsinfo.wtmult) ? fsinfo.rtmult : fsinfo.wtmult;
index 464776ac3c685ab6b9f053908f0a9095f05f67a3..cb97c40bc4a69fd0b19fce459e0821ce5c8dc703 100644 (file)
@@ -68,7 +68,7 @@
  * Spinlock
  */
 spinlock_t nfs_wreq_lock = SPIN_LOCK_UNLOCKED;
-static unsigned int    nfs_nr_requests = 0;
+static atomic_t        nfs_nr_requests = ATOMIC_INIT(0);
 
 /*
  * Local structures
@@ -490,9 +490,9 @@ struct nfs_page *nfs_create_request(struct file *file, struct page *page,
         */
        do {
                /* If we're over the global soft limit, wake up all requests */
-               if (nfs_nr_requests >= MAX_REQUEST_SOFT) {
+               if (atomic_read(&nfs_nr_requests) >= MAX_REQUEST_SOFT) {
                        dprintk("NFS:      hit soft limit (%d requests)\n",
-                               nfs_nr_requests);
+                               atomic_read(&nfs_nr_requests));
                        if (!cache->task)
                                nfs_reqlist_init(NFS_SERVER(inode));
                        nfs_wake_flushd();
@@ -500,7 +500,7 @@ struct nfs_page *nfs_create_request(struct file *file, struct page *page,
 
                /* If we haven't reached the local hard limit yet,
                 * try to allocate the request struct */
-               if (cache->nr_requests < MAX_REQUEST_HARD) {
+               if (atomic_read(&cache->nr_requests) < MAX_REQUEST_HARD) {
                        req = nfs_page_alloc();
                        if (req != NULL)
                                break;
@@ -508,7 +508,7 @@ struct nfs_page *nfs_create_request(struct file *file, struct page *page,
 
                /* We're over the hard limit. Wait for better times */
                dprintk("NFS:      create_request sleeping (total %d pid %d)\n",
-                       cache->nr_requests, current->pid);
+                       atomic_read(&cache->nr_requests), current->pid);
 
                timeout = 1 * HZ;
                if (NFS_SERVER(inode)->flags & NFS_MOUNT_INTR) {
@@ -520,7 +520,7 @@ struct nfs_page *nfs_create_request(struct file *file, struct page *page,
                        sleep_on_timeout(&cache->request_wait, timeout);
 
                dprintk("NFS:      create_request waking up (tot %d pid %d)\n",
-                       cache->nr_requests, current->pid);
+                       atomic_read(&cache->nr_requests), current->pid);
        } while (!req);
        if (!req)
                return NULL;
@@ -539,8 +539,8 @@ struct nfs_page *nfs_create_request(struct file *file, struct page *page,
        req->wb_count   = 1;
 
        /* register request's existence */
-       cache->nr_requests++;
-       nfs_nr_requests++;
+       atomic_inc(&cache->nr_requests);
+       atomic_inc(&nfs_nr_requests);
        return req;
 }
 
@@ -580,9 +580,15 @@ nfs_release_request(struct nfs_page *req)
        page_cache_release(page);
        nfs_page_free(req);
        /* wake up anyone waiting to allocate a request */
-       cache->nr_requests--;
-       nfs_nr_requests--;
+       atomic_dec(&cache->nr_requests);
+       atomic_dec(&nfs_nr_requests);
        wake_up(&cache->request_wait);
+#ifdef NFS_PARANOIA
+       if (atomic_read(&cache->nr_requests) < 0)
+               BUG();
+       if (atomic_read(&nfs_nr_requests) < 0)
+               BUG();
+#endif
 }
 
 /*
@@ -931,7 +937,7 @@ nfs_strategy(struct inode *inode)
                if (dirty >= wpages)
                        nfs_flush_file(inode, NULL, 0, 0, 0);
                if (inode->u.nfs_i.ncommit > NFS_STRATEGY_PAGES * wpages &&
-                   nfs_nr_requests > MAX_REQUEST_SOFT)
+                   atomic_read(&nfs_nr_requests) > MAX_REQUEST_SOFT)
                        nfs_commit_file(inode, NULL, 0, 0, 0);
        }
 #else
index c47830ff30a10217171f8226a17a9c7ec0218fe4..c5c8b0a917b82e7f09927ecf5ea58b6d6b2d34ad 100644 (file)
@@ -98,6 +98,8 @@ void
 nfsd_cache_shutdown(void)
 {
        struct svc_cacherep     *rp;
+       size_t                  i;
+       unsigned long           order;
 
        if (!cache_initialized)
                return;
@@ -110,7 +112,10 @@ nfsd_cache_shutdown(void)
        cache_initialized = 0;
        cache_disabled = 1;
 
-       kfree (nfscache);
+       i = CACHESIZE * sizeof (struct svc_cacherep);
+       for (order = 0; (PAGE_SIZE << order) < i; order++)
+               ;
+       free_pages ((unsigned long)nfscache, order);
        nfscache = NULL;
        kfree (hash_list);
        hash_list = NULL;
index 886e2f4c0bd613153439e4bbce44488ecfc68abd..53386a08d42bbda0fe1d20ae439533c22530cfce 100644 (file)
@@ -27,9 +27,9 @@
 #include <linux/string.h>
 #include <linux/blk.h>
 
-#if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_HD)
+#ifdef CONFIG_BLK_DEV_IDE
 #include <linux/ide.h> /* IDE xlate */
-#endif /* (CONFIG_BLK_DEV_IDE) || (CONFIG_BLK_DEV_HD) */
+#endif /* CONFIG_BLK_DEV_IDE */
 
 #include <asm/system.h>
 
@@ -350,19 +350,19 @@ int msdos_partition(struct gendisk *hd, kdev_t dev,
        unsigned char *data;
        int mask = (1 << hd->minor_shift) - 1;
        int sector_size = get_hardsect_size(dev) / 512;
-#if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_HD)
+#ifdef CONFIG_BLK_DEV_IDE
        int tested_for_xlate = 0;
 
 read_mbr:
-#endif /* (CONFIG_BLK_DEV_IDE) || (CONFIG_BLK_DEV_HD) */
+#endif /* CONFIG_BLK_DEV_IDE */
        if (!(bh = bread(dev,0,get_ptable_blocksize(dev)))) {
                if (warn_no_part) printk(" unable to read partition table\n");
                return -1;
        }
        data = bh->b_data;
-#if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_HD)
+#ifdef CONFIG_BLK_DEV_IDE
 check_table:
-#endif /* (CONFIG_BLK_DEV_IDE) || (CONFIG_BLK_DEV_HD) */
+#endif /* CONFIG_BLK_DEV_IDE */
        /* Use bforget(), because we may have changed the disk geometry */
        if (*(unsigned short *)  (0x1fe + data) != cpu_to_le16(MSDOS_LABEL_MAGIC)) {
                bforget(bh);
@@ -370,7 +370,7 @@ check_table:
        }
        p = (struct partition *) (0x1be + data);
 
-#if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_HD)
+#ifdef CONFIG_BLK_DEV_IDE
        if (!tested_for_xlate++) {      /* Do this only once per disk */
                /*
                 * Look for various forms of IDE disk geometry translation
@@ -426,7 +426,7 @@ check_table:
                        (void) ide_xlate_1024(dev, 2, heads, " [PTBL]");
                }
        }
-#endif /* (CONFIG_BLK_DEV_IDE) || (CONFIG_BLK_DEV_HD) */
+#endif /* CONFIG_BLK_DEV_IDE */
 
        /* Look for partitions in two passes:
           First find the primary partitions, and the DOS-type extended partitions.
index f1d8733310562365660a20b29aad307d68ac8640..5b8974e5b0ef37722899b492d7a206c84557cea7 100644 (file)
@@ -1167,7 +1167,8 @@ static int copy_mount_options (const void *data, unsigned long *where)
 {
        int i;
        unsigned long page;
-
+       unsigned long size;
+       
        *where = 0;
        if (!data)
                return 0;
@@ -1179,13 +1180,18 @@ static int copy_mount_options (const void *data, unsigned long *where)
         * gave us is valid.  Just in case, we'll zero
         * the remainder of the page.
         */
-       i = copy_from_user((void *)page, data, PAGE_SIZE);
-       if (i == PAGE_SIZE) {
+       /* copy_from_user cannot cross TASK_SIZE ! */
+       size = TASK_SIZE - (unsigned long)data;
+       if (size > PAGE_SIZE)
+               size = PAGE_SIZE;
+
+       i = size - copy_from_user((void *)page, data, size);
+       if (!i) {
                free_page(page); 
                return -EFAULT;
        }
-       if (i)
-               memset((char *)page + PAGE_SIZE - i, 0, i);
+       if (i != PAGE_SIZE)
+               memset((char *)page + i, 0, PAGE_SIZE - i);
        *where = page;
        return 0;
 }
index d9620a1c6ca963d07a6e8488ccf16ff93881160f..7784203e0f1a435095417f91c790fe3d40c2eef0 100644 (file)
@@ -55,6 +55,9 @@
  *
  * write support Daniel Pirkl <daniel.pirkl@email.cz> 1998
  * 
+ * HP/UX hfs filesystem support added by
+ * Martin K. Petersen <mkp@mkp.net>, August 1999
+ *
  */
 
 
@@ -279,6 +282,8 @@ static int ufs_parse_options (char * options, unsigned * mount_options)
                                ufs_set_opt (*mount_options, UFSTYPE_OPENSTEP);
                        else if (!strcmp (value, "sunx86"))
                                ufs_set_opt (*mount_options, UFSTYPE_SUNx86);
+                       else if (!strcmp (value, "hp"))
+                               ufs_set_opt (*mount_options, UFSTYPE_HP);
                        else {
                                printk ("UFS-fs: Invalid type option: %s\n", value);
                                return 0;
@@ -473,7 +478,7 @@ struct super_block * ufs_read_super (struct super_block * sb, void * data,
        if (!(sb->u.ufs_sb.s_mount_opt & UFS_MOUNT_UFSTYPE)) {
                printk("You didn't specify the type of your ufs filesystem\n\n"
                "mount -t ufs -o ufstype="
-               "sun|sunx86|44bsd|old|nextstep|netxstep-cd|openstep ...\n\n"
+               "sun|sunx86|44bsd|old|hp|nextstep|netxstep-cd|openstep ...\n\n"
                ">>>WARNING<<< Wrong ufstype may corrupt your filesystem, "
                "default is ufstype=old\n");
                ufs_set_opt (sb->u.ufs_sb.s_mount_opt, UFSTYPE_OLD);
@@ -573,6 +578,19 @@ struct super_block * ufs_read_super (struct super_block * sb, void * data,
                }
                break;
        
+       case UFS_MOUNT_UFSTYPE_HP:
+               UFSD(("ufstype=hp\n"))
+               uspi->s_fsize = block_size = 1024;
+               uspi->s_fmask = ~(1024 - 1);
+               uspi->s_fshift = 10;
+               uspi->s_sbsize = super_block_size = 2048;
+               uspi->s_sbbase = 0;
+               flags |= UFS_DE_OLD | UFS_UID_OLD | UFS_ST_OLD | UFS_CG_OLD;
+               if (!(sb->s_flags & MS_RDONLY)) {
+                       printk(KERN_INFO "ufstype=hp is supported read-only\n");
+                       sb->s_flags |= MS_RDONLY;
+               }
+               break;
        default:
                printk("unknown ufstype\n");
                goto failed;
@@ -598,18 +616,30 @@ again:
 #if defined(__LITTLE_ENDIAN) || defined(__BIG_ENDIAN) /* sane bytesex */
        switch (usb3->fs_magic) {
                case UFS_MAGIC:
+               case UFS_MAGIC_LFN:
+               case UFS_MAGIC_FEA:
+               case UFS_MAGIC_4GB:
                        swab = UFS_NATIVE_ENDIAN;
                        goto magic_found;
                case UFS_CIGAM:
+               case UFS_CIGAM_LFN:
+               case UFS_CIGAM_FEA:
+               case UFS_CIGAM_4GB:
                        swab = UFS_SWABBED_ENDIAN;
                        goto magic_found;
        }
 #else /* bytesex perversion */
        switch (le32_to_cpup(&usb3->fs_magic)) {
                case UFS_MAGIC:
+               case UFS_MAGIC_LFN:
+               case UFS_MAGIC_FEA:
+               case UFS_MAGIC_4GB:
                        swab = UFS_LITTLE_ENDIAN;
                        goto magic_found;
                case UFS_CIGAM:
+               case UFS_CIGAM_LFN:
+               case UFS_CIGAM_FEA:
+               case UFS_CIGAM_4GB:
                        swab = UFS_BIG_ENDIAN;
                        goto magic_found;
        }
index f142fc6dc73f7f379c69b141036f426187898d50..da698627e2833387555ad70166c2c8305ad51e23 100644 (file)
@@ -61,6 +61,7 @@ static __inline__ void ide_init_hwif_ports(hw_regs_t *hw, ide_ioreg_t data_port,
        }
        if (irq != NULL)
                *irq = 0;
+       hw->io_ports[IDE_IRQ_OFFSET] = 0;
 }
 
 /*
@@ -74,7 +75,6 @@ static __inline__ void ide_init_default_hwifs(void)
        int index;
 
        for (index = 0; index < MAX_HWIFS; index++) {
-               memset(&hw, 0, sizeof(hw_regs_t));
                ide_init_hwif_ports(&hw, ide_default_io_base(index), 0, NULL);
                hw.irq = ide_default_irq(ide_default_io_base(index));
                ide_register_hw(&hw, NULL);
index 25ec3b5942969059c7f37e9af9ad7c79fed65b46..6ac787665c0a74adc284fbf9efbe75d94391782a 100644 (file)
@@ -69,6 +69,7 @@ static __inline__ void ide_init_hwif_ports(hw_regs_t *hw, ide_ioreg_t data_port,
        }
        if (irq != NULL)
                *irq = 0;
+       hw->io_ports[IDE_IRQ_OFFSET] = 0;
 }
 
 static __inline__ void ide_init_default_hwifs(void)
@@ -78,7 +79,6 @@ static __inline__ void ide_init_default_hwifs(void)
        int index;
 
        for(index = 0; index < MAX_HWIFS; index++) {
-               memset(&hw, 0, sizeof(hw_regs_t));
                ide_init_hwif_ports(&hw, ide_default_io_base(index), 0, NULL);
                hw.irq = ide_default_irq(ide_default_io_base(index));
                ide_register_hw(&hw, NULL);
index 41f386716d1e01dfae2f69a7df34e173cf0ec07c..01f9832dd8079c235f1c7fd2c9ee95ddb062276f 100644 (file)
@@ -12,6 +12,7 @@
 #include <asm/segment.h>
 #include <asm/page.h>
 #include <asm/types.h>
+#include <asm/sigcontext.h>
 #include <linux/config.h>
 #include <linux/threads.h>
 
@@ -90,13 +91,15 @@ struct cpuinfo_x86 {
 #define X86_FEATURE_22         0x00400000
 #define X86_FEATURE_MMX                0x00800000      /* multimedia extensions */
 #define X86_FEATURE_FXSR       0x01000000      /* FXSAVE and FXRSTOR instructions (fast save and restore of FPU context), and CR4.OSFXSR (OS uses these instructions) available */
-#define X86_FEATURE_25         0x02000000
+#define X86_FEATURE_XMM         0x02000000      /* Intel MMX2 instruction set */
 #define X86_FEATURE_26         0x04000000
 #define X86_FEATURE_27         0x08000000
 #define X86_FEATURE_28         0x10000000
 #define X86_FEATURE_29         0x20000000
 #define X86_FEATURE_30         0x40000000
 #define X86_FEATURE_AMD3D      0x80000000
+#define X86_CR4_OSFXSR         0x0200          /* fast FPU save/restore */
+#define X86_CR4_OSXMMEXCPT     0x0400          /* KNI (MMX2) unmasked exception 16 */
 
 extern struct cpuinfo_x86 boot_cpu_data;
 extern struct tss_struct init_tss[NR_CPUS];
@@ -240,6 +243,22 @@ extern unsigned int mca_pentium_flag;
 #define IO_BITMAP_OFFSET offsetof(struct tss_struct,io_bitmap)
 #define INVALID_IO_BITMAP_OFFSET 0x8000
 
+#ifndef CONFIG_X86_FX
+
+#define i387_save_hard(x) \
+       __asm__("fnsave %0\n\tfwait": :"m" (x))
+#define i387_restore_hard(x) \
+       __asm__("frstor %0": :"m" (x))
+
+#define i387_hard_to_user(uaddr, x) \
+       __copy_to_user((uaddr), (x), sizeof(struct i387_hard_struct))
+#define i387_user_to_hard(x, uaddr) \
+       __copy_from_user((x), (uaddr), sizeof(struct i387_hard_struct))
+
+#define i387_set_cwd(x,v) do { (x).cwd = 0xffff0000 | (v); } while (0)
+#define i387_set_swd(x,v) do { (x).swd = 0xffff0000 | (v); } while (0)
+#define i387_set_twd(x,v) do { (x).twd = 0xffff0000 | (v); } while (0)
+
 struct i387_hard_struct {
        long    cwd;
        long    swd;
@@ -252,6 +271,69 @@ struct i387_hard_struct {
        long    status;         /* software status information */
 };
 
+#else
+
+/*
+ * has to be 128-bit aligned
+ */
+struct i387_hard_struct {
+       unsigned short  cwd;
+       unsigned short  swd;
+       unsigned short  twd;
+       unsigned short  fopcode;
+       unsigned int    fip;
+       unsigned short  fcs;
+       unsigned short  __reserved_01;
+       unsigned int    fdp;
+       unsigned short  fds;
+       unsigned short  __reserved_02;
+       unsigned int    mxcsr;
+       unsigned int    __reserved_03;
+       unsigned int    st_space[32]; /* 8*16 bytes for each FP/MMX-reg = 128 bytes */
+       unsigned int    xmm_space[22*4]; /* 22 cachelines for MMX2 registers */
+       unsigned long   status;
+} __attribute__ ((aligned (16)));
+
+/*
+ * tag word conversion (thanks to Gabriel Paubert for noticing the
+ * subtle format difference and implementing these functions)
+ *
+ * there are several erratas wrt. the tag word in the i387, thus
+ * any software relying on it's value is questionable, but we
+ * definitely want to be as close as possible.
+ */
+static inline unsigned short fputag_KNIto387(unsigned char tb) {
+       unsigned short tw = tb;
+       tw = ((tw<<4) | tw) &0x0f0f; /* zzzz7654zzzz3210 */
+       tw = ((tw<<2) | tw) &0x3333; /* zz76zz54zz32zz10 */
+       tw = ((tw<<1) | tw) &0x5555; /* z7z6z5z4z3z2z1z0 */
+       return ~(tw*3);
+}
+
+static inline unsigned char fputag_387toKNI(unsigned short tw) {
+       tw = ~tw;
+       tw = (tw | (tw>>1)) & 0x5555; /* z7z6z5z4z3z2z1z0 */
+       tw = (tw | (tw>>1)) & 0x3333; /* zz76zz54zz32zz10 */
+       tw = (tw | (tw>>3)) & 0x0f0f; /* zzzz7654zzzz3210 */
+       return (tw|(tw>>4)) & 0x00ff; /* zzzzzzzz76543210 */
+}
+
+#define i387_set_cwd(x,v) do { (x).cwd = (short)(v); } while (0)
+#define i387_set_swd(x,v) do { (x).swd = (short)(v); } while (0)
+#define i387_set_twd(x,v) do { (x).twd = fputag_387toKNI(v); } while (0)
+
+#define i387_save_hard(x) \
+ { __asm__ __volatile__(".byte 0x0f, 0xae, 0x06": :"S" (&(x))); } while (0)
+
+#define i387_restore_hard(x) \
+do { __asm__ __volatile__(".byte 0x0f, 0xae, 0x4f, 0x00": :"D" (&(x))); } while(0)
+
+extern int i387_hard_to_user ( struct _fpstate * user,
+                             struct i387_hard_struct * hard);
+extern int i387_user_to_hard (struct i387_hard_struct * hard,
+                             struct _fpstate * user);
+#endif
+
 struct i387_soft_struct {
        long    cwd;
        long    swd;
@@ -387,7 +469,7 @@ extern void forget_segments(void);
  * FPU lazy state save handling..
  */
 #define save_fpu(tsk) do { \
-       asm volatile("fnsave %0\n\tfwait":"=m" (tsk->thread.i387)); \
+        i387_save_hard(tsk->thread.i387); \
        tsk->flags &= ~PF_USEDFPU; \
        stts(); \
 } while (0)
index 616fb14158af2e3a1699f37b1bfbb9068e6b5515..424ce8bdce36963364adeb94ec6e4b174cf40171 100644 (file)
@@ -24,6 +24,10 @@ struct _fpstate {
                        datasel;
        struct _fpreg   _st[8];
        unsigned long   status;
+#ifdef CONFIG_X86_FX
+       unsigned long   mxcsr;
+       unsigned long   _xmm[4*22];
+#endif
 };
 
 struct sigcontext {
index b0d067e7af1342acfe04ba5ae147350ec672f11e..2d084973836986a05617e2c06d13d8c5e44b0b27 100644 (file)
@@ -36,8 +36,8 @@ struct user_i387_struct {
        long    twd;
        long    fip;
        long    fcs;
-       long    foo;
-       long    fos;
+       long    fdp;
+       long    fds;
        long    st_space[20];   /* 8*10 bytes for each FP-reg = 80 bytes */
 };
 
index 1b473c2529919474f646a2c45d9b0f8462cd2157..c0fe76856689114ed43c80b8fb453d03bedeab01 100644 (file)
@@ -74,6 +74,7 @@ ide_init_hwif_ports (hw_regs_t *hw, ide_ioreg_t data_port, ide_ioreg_t ctrl_port
        }
        if (irq != NULL)
                *irq = 0;
+       hw->io_ports[IDE_IRQ_OFFSET] = 0;
 }
 
 static __inline__ void
@@ -84,7 +85,6 @@ ide_init_default_hwifs (void)
        int index;
 
        for(index = 0; index < MAX_HWIFS; index++) {
-               memset(&hw, 0, sizeof(hw_regs_t));
                ide_init_hwif_ports(&hw, ide_default_io_base(index), 0, NULL);
                hw.irq = ide_default_irq(ide_default_io_base(index));
                ide_register_hw(&hw, NULL);
index ec82befa24a44eb6808a1a61f9f276aa3b10bcce..cc30fac03d327d18b2f2456e90d4bf1168282829 100644 (file)
@@ -17,7 +17,7 @@
 #include <linux/config.h>
 
 #ifndef MAX_HWIFS
-#define MAX_HWIFS      1
+#define MAX_HWIFS      1       /* XXX: For my board -- gniibe */
 #endif
 
 #define ide__sti()     __sti()
@@ -25,8 +25,8 @@
 static __inline__ int ide_default_irq(ide_ioreg_t base)
 {
        switch (base) {
-               case 0x01f0: return 14;
-               case 0x0170: return 15;
+               case 0xba0001f0: return 14;
+               case 0xba000170: return 14;
                default:
                        return 0;
        }
@@ -36,9 +36,9 @@ static __inline__ ide_ioreg_t ide_default_io_base(int index)
 {
        switch (index) {
                case 0: 
-                       return 0x01f0;
+                       return 0xba0001f0;
                case 1: 
-                       return 0x0170;
+                       return 0xba000170;
                default:
                        return 0;
        }
@@ -60,6 +60,7 @@ static __inline__ void ide_init_hwif_ports(hw_regs_t *hw, ide_ioreg_t data_port,
        }
        if (irq != NULL)
                *irq = 0;
+       hw->io_ports[IDE_IRQ_OFFSET] = 0;
 }
 
 static __inline__ void ide_init_default_hwifs(void)
@@ -69,7 +70,6 @@ static __inline__ void ide_init_default_hwifs(void)
        int index;
 
        for(index = 0; index < MAX_HWIFS; index++) {
-               memset(&hw, 0, sizeof(hw_regs_t));
                ide_init_hwif_ports(&hw, ide_default_io_base(index), 0, NULL);
                hw.irq = ide_default_irq(ide_default_io_base(index));
                ide_register_hw(&hw, NULL);
index 79b0e47a1344cc246da6b0ac82f66f5518875fda..aa0bcbfdbd723d359d1447ebaceb3a15ccec8018 100644 (file)
@@ -52,6 +52,7 @@ static __inline__ void ide_init_hwif_ports(hw_regs_t *hw, ide_ioreg_t data_port,
        }
        if (irq != NULL)
                *irq = 0;
+       hw->io_ports[IDE_IRQ_OFFSET] = 0;
 }
 
 /*
@@ -65,7 +66,6 @@ static __inline__ void ide_init_default_hwifs(void)
        int index;
 
        for (index = 0; index < MAX_HWIFS; index++) {
-               memset(&hw, 0, sizeof(hw_regs_t));
                ide_init_hwif_ports(&hw, ide_default_io_base(index), 0, NULL);
                hw.irq = ide_default_irq(ide_default_io_base(index));
                ide_register_hw(&hw, NULL);
index 471ee71a055da874cc6ccf4ff34a8b4eed41b20c..71bfa67ca7ce2b49e7aa14c3a43c13cf023bde03 100644 (file)
@@ -46,6 +46,7 @@ static __inline__ void ide_init_hwif_ports(hw_regs_t *hw, ide_ioreg_t data_port,
        }
        if (irq != NULL)
                *irq = 0;
+       hw->io_ports[IDE_IRQ_OFFSET] = 0;
 }
 
 /*
@@ -59,7 +60,6 @@ static __inline__ void ide_init_default_hwifs(void)
        int index;
 
        for (index = 0; index < MAX_HWIFS; index++) {
-               memset(&hw, 0, sizeof(hw_regs_t));
                ide_init_hwif_ports(&hw, ide_default_io_base(index), 0, NULL);
                hw.irq = ide_default_irq(ide_default_io_base(index));
                ide_register_hw(&hw, NULL);
index 015a3c032724961baa26764a4cb37b224b1da152..ff235df973ea2caad0dfda97a1b9f1cbaea70f2a 100644 (file)
@@ -4,6 +4,7 @@
 
 
 #ifdef __KERNEL__
+#include <asm/atomic.h>
 #include <linux/nfs_fs_sb.h>
 
 /*
@@ -43,7 +44,7 @@ extern void           nfs_wake_flushd(void);
  * This is the per-mount writeback cache.
  */
 struct nfs_reqlist {
-       unsigned int            nr_requests;
+       atomic_t                nr_requests;
        unsigned long           runat;
        wait_queue_head_t       request_wait;
 
index ff648072eb8b7a3e4974947fc878997d7f512575..0c2289c061cfbdfe077685f71dfba858778e03fc 100644 (file)
 #define PCI_DEVICE_ID_ATI_RAGE128_RL   0x524c
 #define PCI_DEVICE_ID_ATI_RAGE128_PF   0x5046
 #define PCI_DEVICE_ID_ATI_RAGE128_PR   0x5052
+#define PCI_DEVICE_ID_ATI_RAGE128_LE   0x4c45
+#define PCI_DEVICE_ID_ATI_RAGE128_LF   0x4c46
 
 #define PCI_VENDOR_ID_VLSI             0x1004
 #define PCI_DEVICE_ID_VLSI_82C592      0x0005
 #define PCI_DEVICE_ID_IBM_TR_WAKE      0x003e
 #define PCI_DEVICE_ID_IBM_MPIC         0x0046
 #define PCI_DEVICE_ID_IBM_3780IDSP     0x007d
+#define        PCI_DEVICE_ID_IBM_405GP         0x0156
 #define PCI_DEVICE_ID_IBM_MPIC_2       0xffff
 
 #define PCI_VENDOR_ID_WD               0x101c
index 631791186172d693e3633853c005bd313e1c01bc..96cb38e67bd6618dee632aaf7334007ef5dcf63b 100644 (file)
  * Niels Kristian Bech Jensen <nkbj@image.dk>.
  *
  * Write support by Daniel Pirkl <daniel.pirkl@email.cz>
+ *
+ * HP/UX hfs filesystem support added by
+ * Martin K. Petersen <mkp@mkp.net>, August 1999
+ *
  */
 
 #ifndef __LINUX_UFS_FS_H
 #define UFS_MAGIC 0x00011954
 #define UFS_CIGAM 0x54190100 /* byteswapped MAGIC */
 
+
+/* HP specific MAGIC values */
+
+#define UFS_MAGIC_LFN   0x00095014 /* fs supports filenames > 14 chars */
+#define UFS_CIGAM_LFN   0x14500900 /* srahc 41 < semanelif stroppus sf */
+
+#define UFS_MAGIC_SEC   0x00612195 /* B1 security fs */
+#define UFS_CIGAM_SEC   0x95216100
+
+#define UFS_MAGIC_FEA   0x00195612 /* fs_featurebits supported */
+#define UFS_CIGAM_FEA   0x12561900
+
+#define UFS_MAGIC_4GB   0x05231994 /* fs > 4 GB && fs_featurebits */
+#define UFS_CIGAM_4GB   0x94192305
+
+/* Seems somebody at HP goofed here. B1 and lfs are both 0x2 !?! */
+#define UFS_FSF_LFN     0x00000001 /* long file names */
+#define UFS_FSF_B1      0x00000002 /* B1 security */
+#define UFS_FSF_LFS     0x00000002 /* large files */
+#define UFS_FSF_LUID    0x00000004 /* large UIDs */
+
+/* End of HP stuff */
+
+
 #define UFS_BSIZE      8192
 #define UFS_MINBSIZE   4096
 #define UFS_FSIZE      1024
 #define UFS_MOUNT_ONERROR_UMOUNT       0x00000004
 #define UFS_MOUNT_ONERROR_REPAIR       0x00000008
 
-#define UFS_MOUNT_UFSTYPE              0x000007F0
+#define UFS_MOUNT_UFSTYPE              0x00000FF0
 #define UFS_MOUNT_UFSTYPE_OLD          0x00000010
 #define UFS_MOUNT_UFSTYPE_44BSD                0x00000020
 #define UFS_MOUNT_UFSTYPE_SUN          0x00000040
 #define UFS_MOUNT_UFSTYPE_NEXTSTEP_CD  0x00000100
 #define UFS_MOUNT_UFSTYPE_OPENSTEP     0x00000200
 #define UFS_MOUNT_UFSTYPE_SUNx86       0x00000400
+#define UFS_MOUNT_UFSTYPE_HP           0x00000800
 
 #define ufs_clear_opt(o,opt)   o &= ~UFS_MOUNT_##opt
 #define ufs_set_opt(o,opt)     o |= UFS_MOUNT_##opt
index 597d292f5fb146cdca0a6b9cf0c58cc75d6bb072..beeddf7db4a8942f3d9065a01c06cce738e18a3e 100644 (file)
@@ -116,7 +116,6 @@ EXPORT_SYMBOL(kmem_cache_free);
 EXPORT_SYMBOL(kmalloc);
 EXPORT_SYMBOL(kfree);
 EXPORT_SYMBOL(kfree_s);
-EXPORT_SYMBOL(vmalloc);
 EXPORT_SYMBOL(vfree);
 EXPORT_SYMBOL(__vmalloc);
 EXPORT_SYMBOL(mem_map);
index 626e1634d0de7aefc0f12f3987b25c8cffcf303f..3895451ba38cec02d416420eb5ab3565f92241e0 100644 (file)
@@ -31,12 +31,12 @@ if [ "$CONFIG_IP6_NF_IPTABLES" != "n" ]; then
 # The targets
   dep_tristate '  Packet filtering' CONFIG_IP6_NF_FILTER $CONFIG_IP6_NF_IPTABLES 
 
-  if [ "$CONFIG_IP6_NF_FILTER" != "n" ]; then
+#  if [ "$CONFIG_IP6_NF_FILTER" != "n" ]; then
 #    dep_tristate '    REJECT target support' CONFIG_IP6_NF_TARGET_REJECT $CONFIG_IP6_NF_FILTER
 #    if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
 #      dep_tristate '    MIRROR target support (EXPERIMENTAL)' CONFIG_IP6_NF_TARGET_MIRROR $CONFIG_IP6_NF_FILTER
 #    fi
-  fi
+#  fi
 
   dep_tristate '  Packet mangling' CONFIG_IP6_NF_MANGLE $CONFIG_IP6_NF_IPTABLES 
   if [ "$CONFIG_IP6_NF_MANGLE" != "n" ]; then
index a5370a1ab418ad8b3010e8f59cd2fec1d7841e8b..f58867de76a26d0ce1a4196413863cb3c7d56ea9 100644 (file)
@@ -316,7 +316,7 @@ sub output_sgml {
     my $count;
     my $id;
 
-    $id = $args{'module'}."-".$args{'function'};
+    $id = "API-".$args{'function'};
     $id =~ s/[^A-Za-z0-9]/-/g;
 
     print "<refentry>\n";
index aa46a07baa93af6ca538b8d607d478b9cb34b364..433fba27c9decc7ff44ecb892d2e0c4db855ef58 100644 (file)
@@ -285,8 +285,8 @@ void use_config(const char * name, int len)
  */
 #define MAX2(a,b) ((a)>(b)?(a):(b))
 #define MIN2(a,b) ((a)<(b)?(a):(b))
-#define MAX6(a,b,c,d,e,f) (MAX2(a,MAX2(b,MAX2(c,MAX2(d,MAX2(e,f))))))
-#define MIN6(a,b,c,d,e,f) (MIN2(a,MIN2(b,MIN2(c,MIN2(d,MIN2(e,f))))))
+#define MAX5(a,b,c,d,e) (MAX2(a,MAX2(b,MAX2(c,MAX2(d,e)))))
+#define MIN5(a,b,c,d,e) (MIN2(a,MIN2(b,MIN2(c,MIN2(d,e)))))
 
 
 
@@ -304,7 +304,7 @@ void use_config(const char * name, int len)
  * About 98% of the CPU time is spent here, and most of that is in
  * the 'start' paragraph.  Because the current characters are
  * in a register, the start loop usually eats 4 or 8 characters
- * per memory read.  The MAX6 and MIN6 tests dispose of most
+ * per memory read.  The MAX5 and MIN5 tests dispose of most
  * input characters with 1 or 2 comparisons.
  */
 void state_machine(const char * map, const char * end)
@@ -317,8 +317,8 @@ void state_machine(const char * map, const char * end)
 start:
        GETNEXT
 __start:
-       if (current > MAX6('/','\'','"','#','C','_')) goto start;
-       if (current < MIN6('/','\'','"','#','C','_')) goto start;
+       if (current > MAX5('/','\'','"','#','C')) goto start;
+       if (current < MIN5('/','\'','"','#','C')) goto start;
        CASE('/',  slash);
        CASE('\'', squote);
        CASE('"',  dquote);