From cac3e1c7bb05780f8a2182a6145d22cb07873ee7 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Fri, 23 Nov 2007 15:10:07 -0500 Subject: [PATCH] Import 1.3.12 --- Makefile | 4 +- arch/alpha/kernel/entry.S | 14 +++ arch/alpha/kernel/osf_sys.c | 17 +-- arch/alpha/kernel/ptrace.c | 200 ++++++++++++++++---------------- arch/alpha/kernel/setup.c | 9 +- arch/alpha/kernel/signal.c | 3 + arch/alpha/kernel/traps.c | 34 ++++-- drivers/block/README.aztcd | 24 ++-- drivers/block/README.cm206 | 30 +++-- drivers/block/aztcd.c | 97 +++++++++++++--- drivers/block/cdu31a.c | 34 +++++- drivers/block/cm206.c | 116 ++++++++++++++---- drivers/block/mcd.c | 103 ++++++++++++++-- drivers/char/Makefile | 2 +- drivers/net/de4x5.c | 6 +- drivers/net/depca.c | 2 +- drivers/net/loopback.c | 1 + drivers/net/slhc.c | 32 +++-- drivers/scsi/Makefile | 2 + drivers/scsi/aic7xxx.c | 3 - drivers/scsi/aic7xxx.h | 3 - drivers/scsi/aic7xxx_asm.c | 3 - drivers/scsi/scsi.c | 2 +- drivers/scsi/sg.c | 2 +- drivers/sound/pas2_midi.c | 2 +- include/asm-alpha/io.h | 6 +- include/asm-alpha/mman.h | 29 +++++ include/asm-alpha/sigcontext.h | 34 ++++++ include/asm-alpha/signal.h | 32 +---- include/asm-alpha/string.h | 3 +- include/asm-alpha/system.h | 12 +- include/asm-alpha/unistd.h | 2 +- include/asm-i386/mman.h | 23 ++++ include/asm-i386/sigcontext.h | 29 +++++ include/asm-i386/signal.h | 27 +---- include/asm-i386/string.h | 21 +++- include/linux/aztcd.h | 20 +++- include/linux/cm206.h | 24 ++-- include/linux/if_ppp.h | 2 +- include/linux/mman.h | 19 +-- include/linux/modules/ksyms.ver | 194 ------------------------------- include/linux/modversions.h | 1 - include/linux/trdevice.h | 4 +- kernel/fork.c | 2 + kernel/ksyms.c | 3 - kernel/sched.c | 137 ++++++++++++++++------ lib/string.c | 39 +++++++ net/802/tr.c | 9 +- net/core/dev.c | 1 + net/ipv4/ip.c | 83 +++++++++---- net/ipv4/ip_fw.c | 2 +- 51 files changed, 911 insertions(+), 592 deletions(-) create mode 100644 include/asm-alpha/mman.h create mode 100644 include/asm-alpha/sigcontext.h create mode 100644 include/asm-i386/mman.h create mode 100644 include/asm-i386/sigcontext.h delete mode 100644 include/linux/modules/ksyms.ver delete mode 100644 include/linux/modversions.h diff --git a/Makefile b/Makefile index c3a586254508..59d2a209876b 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ VERSION = 1 PATCHLEVEL = 3 -SUBLEVEL = 11 +SUBLEVEL = 12 ARCH = i386 @@ -239,10 +239,8 @@ mrproper: clean rm -f .version .config* config.in config.old rm -f include/asm rm -f .depend `find . -name .depend -print` -ifdef CONFIG_MODVERSIONS rm -f $(TOPDIR)/include/linux/modversions.h rm -f $(TOPDIR)/include/linux/modules/* -endif distclean: mrproper rm -f core `find . -name '*.orig' -print` diff --git a/arch/alpha/kernel/entry.S b/arch/alpha/kernel/entry.S index 14c520ffd0e6..90519b929c32 100644 --- a/arch/alpha/kernel/entry.S +++ b/arch/alpha/kernel/entry.S @@ -300,10 +300,13 @@ undo_switch_stack: entUna: lda $30,-256($30) stq $0,0($30) + ldq $0,256($30) /* get PS */ stq $1,8($30) stq $2,16($30) stq $3,24($30) + and $0,8,$0 /* user mode? */ stq $4,32($30) + bne $0,entUnaUser /* yup -> do user-level unaligned fault */ stq $5,40($30) stq $6,48($30) stq $7,56($30) @@ -364,6 +367,17 @@ entUna: rti .end entUna +.align 3 +.ent entUnaUser +entUnaUser: + ldq $0,0($30) /* restore original $0 */ + lda $30,256($30) /* pop entUna's stack frame */ + SAVE_ALL /* setup normal kernel stack */ + lda $27,do_entUnaUser + lda $26,ret_from_sys_call + jsr $31,($27),do_entUnaUser +.end entUnaUser + .align 3 .globl sys_fork .ent sys_fork diff --git a/arch/alpha/kernel/osf_sys.c b/arch/alpha/kernel/osf_sys.c index 48d68918cb5e..874033d724ef 100644 --- a/arch/alpha/kernel/osf_sys.c +++ b/arch/alpha/kernel/osf_sys.c @@ -153,26 +153,15 @@ asmlinkage unsigned long sys_getxpid(int a0, int a1, int a2, int a3, int a4, int return current->pid; } -#define OSF_MAP_ANONYMOUS 0x0010 -#define OSF_MAP_FIXED 0x0100 -#define OSF_MAP_HASSEMAPHORE 0x0200 -#define OSF_MAP_INHERIT 0x0400 -#define OSF_MAP_UNALIGNED 0x0800 - asmlinkage unsigned long osf_mmap(unsigned long addr, unsigned long len, - unsigned long prot, unsigned long osf_flags, unsigned long fd, + unsigned long prot, unsigned long flags, unsigned long fd, unsigned long off) { struct file * file = NULL; - unsigned long flags = osf_flags & 0x0f; - if (osf_flags & (OSF_MAP_HASSEMAPHORE | OSF_MAP_INHERIT | OSF_MAP_UNALIGNED)) + if (flags & (MAP_HASSEMAPHORE | MAP_INHERIT | MAP_UNALIGNED)) printk("%s: unimplemented OSF mmap flags %04lx\n", current->comm, osf_flags); - if (osf_flags & OSF_MAP_FIXED) - flags |= MAP_FIXED; - if (osf_flags & OSF_MAP_ANONYMOUS) - flags |= MAP_ANONYMOUS; - else { + if (!(flags & MAP_ANONYMOUS)) { if (fd >= NR_OPEN || !(file = current->files->fd[fd])) return -EBADF; } diff --git a/arch/alpha/kernel/ptrace.c b/arch/alpha/kernel/ptrace.c index d7999c26ec21..bf9c3b67a364 100644 --- a/arch/alpha/kernel/ptrace.c +++ b/arch/alpha/kernel/ptrace.c @@ -531,6 +531,12 @@ int ptrace_cancel_bpt(struct task_struct *child) int i, nsaved = child->debugreg[4]; child->debugreg[4] = 0; + + if (nsaved > 2) { + printk("ptrace_cancel_bpt: bogus nsaved: %d!\n", nsaved); + nsaved = 2; + } + for (i = 0; i < nsaved; ++i) { write_int(child, child->debugreg[i], child->debugreg[i + 2]); } @@ -550,65 +556,65 @@ asmlinkage long sys_ptrace(long request, long pid, long addr, long data, int a4, set_success(®s,0); if (request == PTRACE_TRACEME) { /* are we already being traced? */ - if (current->flags & PF_PTRACED) { - set_failure(®s,-EPERM); - return -EPERM; - } - /* set the ptrace bit in the process flags. */ - current->flags |= PF_PTRACED; - return 0; + if (current->flags & PF_PTRACED) { + set_failure(®s,-EPERM); + return -EPERM; + } + /* set the ptrace bit in the process flags. */ + current->flags |= PF_PTRACED; + return 0; } - if (pid == 1) { - set_failure(®s,-EPERM); - return -EPERM; + if (pid == 1) { /* you may not mess with init */ + set_failure(®s,-EPERM); + return -EPERM; } if (!(child = get_task(pid))) { - set_failure(®s,-ESRCH); - return -ESRCH; + set_failure(®s,-ESRCH); + return -ESRCH; } if (request == PTRACE_ATTACH) { - if (child == current) { - set_failure(®s,-EPERM); - return -EPERM; - } - if ((!child->dumpable || - (current->uid != child->euid) || - (current->uid != child->uid) || - (current->gid != child->egid) || - (current->gid != child->gid)) && !suser()) { - set_failure(®s,-EPERM); - return -EPERM; - } - /* the same process cannot be attached many times */ - if (child->flags & PF_PTRACED) { - set_failure(®s,-EPERM); - return -EPERM; - } - child->flags |= PF_PTRACED; - if (child->p_pptr != current) { - REMOVE_LINKS(child); - child->p_pptr = current; - SET_LINKS(child); - } - send_sig(SIGSTOP, child, 1); - return 0; + if (child == current) { + set_failure(®s,-EPERM); + return -EPERM; + } + if ((!child->dumpable || + (current->uid != child->euid) || + (current->uid != child->uid) || + (current->gid != child->egid) || + (current->gid != child->gid)) && !suser()) { + set_failure(®s,-EPERM); + return -EPERM; + } + /* the same process cannot be attached many times */ + if (child->flags & PF_PTRACED) { + set_failure(®s,-EPERM); + return -EPERM; + } + child->flags |= PF_PTRACED; + if (child->p_pptr != current) { + REMOVE_LINKS(child); + child->p_pptr = current; + SET_LINKS(child); + } + send_sig(SIGSTOP, child, 1); + return 0; } if (!(child->flags & PF_PTRACED)) { - DBG(DBG_MEM, ("child not traced\n")); - set_failure(®s,-ESRCH); - return -ESRCH; + DBG(DBG_MEM, ("child not traced\n")); + set_failure(®s,-ESRCH); + return -ESRCH; } if (child->state != TASK_STOPPED) { - DBG(DBG_MEM, ("child process not stopped\n")); - if (request != PTRACE_KILL) { - set_failure(®s,-ESRCH); - return -ESRCH; - } + DBG(DBG_MEM, ("child process not stopped\n")); + if (request != PTRACE_KILL) { + set_failure(®s,-ESRCH); + return -ESRCH; + } } if (child->p_pptr != current) { - DBG(DBG_MEM, ("child not parent of this process\n")); - set_failure(®s,-ESRCH); - return -ESRCH; + DBG(DBG_MEM, ("child not parent of this process\n")); + set_failure(®s,-ESRCH); + return -ESRCH; } switch (request) { @@ -621,12 +627,11 @@ asmlinkage long sys_ptrace(long request, long pid, long addr, long data, int a4, DBG(DBG_MEM, ("doing request at addr 0x%lx\n",addr)); res = read_long(child, addr, &tmp); if (res < 0) { - set_failure(®s,res); - return res; - } - else { - set_success(®s,tmp); - return 0; + set_failure(®s,res); + return res; + } else { + set_success(®s,tmp); + return 0; } } @@ -636,21 +641,20 @@ asmlinkage long sys_ptrace(long request, long pid, long addr, long data, int a4, unsigned long tmp; tmp = 0; /* Default return condition */ - if(addr==30) { - /* stack pointer */ - tmp=child->tss.usp; - } - else { + if (addr == 30) { + /* stack pointer */ + tmp=child->tss.usp; + } else { #ifdef DEBUG - int reg=addr; + int reg = addr; #endif - addr = offset_of_register(addr); - if (addr < 0) { - set_failure(®s, -EIO); - return -EIO; - } - tmp = get_stack_long(child, addr); - DBG(DBG_MEM, ("%d = reg 0x%lx=tmp\n",reg,tmp)); + addr = offset_of_register(addr); + if (addr < 0) { + set_failure(®s, -EIO); + return -EIO; + } + tmp = get_stack_long(child, addr); + DBG(DBG_MEM, ("%d = reg 0x%lx=tmp\n",reg,tmp)); } set_success(®s,tmp); return 0; @@ -659,34 +663,34 @@ asmlinkage long sys_ptrace(long request, long pid, long addr, long data, int a4, /* when I and D space are separate, this will have to be fixed. */ case PTRACE_POKETEXT: /* write the word at location addr. */ case PTRACE_POKEDATA: { - long res=write_long(child,addr,data); - if(res) { - set_failure(®s,res); + long res = write_long(child,addr,data); + if (res) { + set_failure(®s,res); } return res; } case PTRACE_POKEUSR: /* write the specified register */ - { - long res; - addr= offset_of_register(addr); - if(addr < 0) { - set_failure(®s,-EIO); - return -EIO; - } - res=put_stack_long(child,addr,data); - if(res) { - set_failure(®s,res); - } - return res; - } + { + long res; + addr = offset_of_register(addr); + if(addr < 0) { + set_failure(®s,-EIO); + return -EIO; + } + res = put_stack_long(child, addr, data); + if (res) { + set_failure(®s,res); + } + return res; + } case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */ case PTRACE_CONT: { /* restart after signal. */ if ((unsigned long) data > NSIG) { - set_failure(®s,-EIO); - return -EIO; + set_failure(®s,-EIO); + return -EIO; } if (request == PTRACE_SYSCALL) child->flags |= PF_TRACESYS; @@ -694,12 +698,13 @@ asmlinkage long sys_ptrace(long request, long pid, long addr, long data, int a4, child->flags &= ~PF_TRACESYS; child->exit_code = data; wake_up_process(child); + /* make sure single-step breakpoint is gone. */ ptrace_cancel_bpt(child); set_success(®s,data); return 0; } - /* +/* * make the child exit. Best I can do is send it a sigkill. * perhaps it should be put in the status that it wants to * exit. @@ -707,14 +712,15 @@ asmlinkage long sys_ptrace(long request, long pid, long addr, long data, int a4, case PTRACE_KILL: { wake_up_process(child); child->exit_code = SIGKILL; + /* make sure single-step breakpoint is gone. */ ptrace_cancel_bpt(child); return 0; } - case PTRACE_SINGLESTEP: { /* set the trap flag. */ + case PTRACE_SINGLESTEP: { /* execute signle instruction. */ if ((unsigned long) data > NSIG) { - set_failure(®s,-EIO); - return -EIO; + set_failure(®s,-EIO); + return -EIO; } res = set_bpt(child); if (res < 0) { @@ -723,14 +729,14 @@ asmlinkage long sys_ptrace(long request, long pid, long addr, long data, int a4, child->flags &= ~PF_TRACESYS; wake_up_process(child); child->exit_code = data; - /* give it a chance to run. */ + /* give it a chance to run. */ return 0; } case PTRACE_DETACH: { /* detach a process that was attached. */ if ((unsigned long) data > NSIG) { - set_failure(®s,-EIO); - return -EIO; + set_failure(®s,-EIO); + return -EIO; } child->flags &= ~(PF_PTRACED|PF_TRACESYS); wake_up_process(child); @@ -738,17 +744,15 @@ asmlinkage long sys_ptrace(long request, long pid, long addr, long data, int a4, REMOVE_LINKS(child); child->p_pptr = child->p_opptr; SET_LINKS(child); - /* make sure the single step bit is not set. */ + /* make sure single-step breakpoint is gone. */ ptrace_cancel_bpt(child); return 0; } default: - { - set_failure(®s,-EIO); - return -EIO; - } - } + set_failure(®s,-EIO); + return -EIO; + } } asmlinkage void syscall_trace(void) diff --git a/arch/alpha/kernel/setup.c b/arch/alpha/kernel/setup.c index 344eefa683bb..db648776a2c8 100644 --- a/arch/alpha/kernel/setup.c +++ b/arch/alpha/kernel/setup.c @@ -130,6 +130,9 @@ int get_cpuinfo(char *buffer) }; struct percpu_struct *cpu; unsigned int cpu_index, system_index; + extern struct unaligned_stat { + unsigned long count, va, pc; + } unaligned; # define N(a) (sizeof(a)/sizeof(a[0])) cpu = (struct percpu_struct*)((char*)hwrpb + hwrpb->processor_offset); @@ -151,7 +154,8 @@ int get_cpuinfo(char *buffer) "page size [bytes]\t: %ld\n" "phys. address bits\t: %ld\n" "max. addr. space #\t: %ld\n" - "BogoMIPS\t\t: %lu.%02lu\n", + "BogoMIPS\t\t: %lu.%02lu\n" + "unaligned accesses\t: %ld (pc=%lx,va=%lx)\n", (cpu_index < N(cpu_name) ? cpu_name[cpu_index] : "Unknown"), cpu->variation, cpu->revision, (char*)cpu->serial_no, @@ -164,6 +168,7 @@ int get_cpuinfo(char *buffer) hwrpb->pagesize, hwrpb->pa_bits, hwrpb->max_asn, - loops_per_sec / 500000, (loops_per_sec / 5000) % 100); + loops_per_sec / 500000, (loops_per_sec / 5000) % 100, + unaligned.count, unaligned.pc, unaligned.va); # undef N } diff --git a/arch/alpha/kernel/signal.c b/arch/alpha/kernel/signal.c index cc7069728479..0199e29704b4 100644 --- a/arch/alpha/kernel/signal.c +++ b/arch/alpha/kernel/signal.c @@ -214,6 +214,9 @@ asmlinkage int do_signal(unsigned long oldmask, unsigned long pc = 0; unsigned long signr; struct sigaction * sa; + extern ptrace_cancel_bpt (struct task_struct *child); + + ptrace_cancel_bpt(current); /* make sure single-step bpt is gone */ while ((signr = current->signal & mask) != 0) { signr = ffz(~signr); diff --git a/arch/alpha/kernel/traps.c b/arch/alpha/kernel/traps.c index d1a3e3e2476c..b098b382fa0d 100644 --- a/arch/alpha/kernel/traps.c +++ b/arch/alpha/kernel/traps.c @@ -67,8 +67,6 @@ asmlinkage void do_entIF(unsigned long type, unsigned long a1, unsigned long a2, if (ptrace_cancel_bpt(current)) { regs.pc -= 4; /* make pc point to former bpt */ } - if (current->flags & PF_PTRACED) - current->blocked &= ~(1 << (SIGTRAP - 1)); send_sig(SIGTRAP, current, 1); break; @@ -90,9 +88,8 @@ asmlinkage void do_entIF(unsigned long type, unsigned long a1, unsigned long a2, * fp-regs), and it needs to have them in order for simpler access. * * Due to the non-standard register layout (and because we don't want - * to handle floating-point regs), we disallow user-mode unaligned - * accesses (we'd need to do "verify_area()" checking, as well as - * do a full "ret_from_sys_call" return). + * to handle floating-point regs), user-mode unaligned accesses are + * handled separately by do_entUnaUser below. * * Oh, btw, we don't handle the "gp" register correctly, but if we fault * on a gp-register unaligned load/store, something is _very_ wrong @@ -103,17 +100,24 @@ struct allregs { unsigned long ps, pc, gp, a0, a1, a2; }; +struct unaligned_stat { + unsigned long count, va, pc; +} unaligned; + asmlinkage void do_entUna(void * va, unsigned long opcode, unsigned long reg, unsigned long a3, unsigned long a4, unsigned long a5, struct allregs regs) { static int cnt = 0; - if (regs.ps & 8) - do_exit(SIGSEGV); if (++cnt < 5) printk("Unaligned trap at %016lx: %p %lx %ld\n", regs.pc, va, opcode, reg); + + ++unaligned.count; + unaligned.va = (unsigned long) va - 4; + unaligned.pc = regs.pc; + /* $16-$18 are PAL-saved, and are offset by 19 entries */ if (reg >= 16 && reg <= 18) reg += 19; @@ -136,6 +140,22 @@ asmlinkage void do_entUna(void * va, unsigned long opcode, unsigned long reg, do_exit(SIGSEGV); } +/* + * Handle user-level unaligned fault. For now, simply send a + * SIGSEGV---there should be little reason for users not wanting to + * fix their code instead. Notice that we have the regular kernel + * stack layout here, so finding the appropriate registers is a little + * more difficult than in the kernel case. Also, we'd need to do + * a "verify_area()" before accessing memory on behalf of the user. + */ +asmlinkage void do_entUnaUser(void *va, unsigned long opcode, unsigned long reg, + unsigned long a3, unsigned long a4, unsigned long a5, + struct pt_regs regs) +{ + regs.pc -= 4; /* make pc point to faulting insn */ + send_sig(SIGSEGV, current, 1); +} + /* * DEC means people to use the "retsys" instruction for return from * a system call, but they are clearly misguided about this. We use diff --git a/drivers/block/README.aztcd b/drivers/block/README.aztcd index 99f0a9c7e6d1..48876877e2cd 100644 --- a/drivers/block/README.aztcd +++ b/drivers/block/README.aztcd @@ -1,7 +1,7 @@ Readme-File README.aztcd for Aztech CD-ROM CDA268-01A, ORCHID CD-3110, OKANO/WEARNES CDD110 CD-ROM Driver - Version 1.2 and newer + Version 1.4 and newer (for other drives see 6.-8.) NOTE: THIS DRIVER WILL WORK WITH THE CD-ROM DRIVES LISTED, WHICH HAVE @@ -104,6 +104,8 @@ filesystem, you have to recompile your kernel: have to set up. If you have a soundcard, read chapter 4.2. Users of other drives should read chapter OTHER DRIVES of this file. You also can configure that address by LILO boot parameter aztcd=... +- There are some other points, which may be configured, e.g. auto-eject the + CD when umounting a drive, tray locking etc., see aztcd.h for details. - Build a new kernel, configure it for 'Aztech/Orchid/Okano/Wearnes support' (if you want aztcd to be part of the kernel). Do not configure it for 'Aztech... support', if you want to use aztcd as a run time loadable module. @@ -139,7 +141,9 @@ the source kernel version, from which you create the modules. So rebuild your kernel, if necessary. Now edit the base address of your AZTECH interface card in -/usr/src/linux/include/linux/aztcd.h to the appropriate value. Then change +/usr/src/linux/include/linux/aztcd.h to the appropriate value. There are +also some special features which may be configured, e.g. auto-eject a CD +when unmounting the drive etc; see aztcd.h for details. Then change to /usr/src/linux and do a make modules make modules_install @@ -175,11 +179,12 @@ configured and mail me (see 6.) the appropriate information. 5. KNOWN PROBLEMS, FUTURE DEVELOPMENTS 5.1 MULTISESSION SUPPORT -The driver does not support applications such as photo CD, multi session CD -etc.. I do not plan to include the support for that in the driver, because I -do not use such applications. If you are interested in that stuff and would -like to extend the drivers capability on your own, please contact me, I'll -support you as far as I can. +I have now (July 1995) started support of multisession CDs. Unfortunately I +do neither have a multisession CD nor use appropriate applications, so I can +program, but will not test it :-(. If you'd like to help me, please contact +me. As of version 1.4 you can enable the multisession support in aztcd.h by +setting AZT_MULTISESSION to 1. As I have not tested it, I don't know, if it +works ... 5.2 STATUS RECOGNITION The drive status recognition does not work correctly in all cases. Changing @@ -210,7 +215,10 @@ might hang for some 30sec. So be patient, when using dosemu's CD-ROM support in combination with aztcd :-) ! Unfortunately up to now, I could not locate the root cause of that problem. It seems to be somewhere in the interaction of the kernel with dosemu's and aztcd's buffers. I appreciate any help on -this subject ! +this subject ! +This problem has now (July 1995) been fixed by a modification to dosemu's +CD-ROM driver, but it is unclear, with which version of dosemu this modi- +fication will officially be included. 6. BUG REPORTS Please send detailed bug reports and bug fixes via EMail to diff --git a/drivers/block/README.cm206 b/drivers/block/README.cm206 index 6035f8c51753..9c4f9288f461 100644 --- a/drivers/block/README.cm206 +++ b/drivers/block/README.cm206 @@ -6,7 +6,8 @@ cm206 in combination with the cm260 host adapter card. Features as of version 0.33 --------------------------- - Full audio support, that is, both workman, workbone and cdp work - now reasonably. Reading TOC still takes some time. + now reasonably. Reading TOC still takes some time. xmcd has been + reported to run successfully. - Made auto-probe code a little better, i hope Features as of version 0.28 @@ -41,12 +42,6 @@ options: autoprobing, which is the default. In that case you can move on to the next step. - If autoprobing does not work, you can hard-wire the default values - of the base port address (CM206_BASE) and interrupt request line - (CM206_IRQ) into the file ./linux/drivers/block/cm206.c. Uncomment - the defines of CM206_IRQ and CM206_BASE, and change there meaning - to the appropriate values, if necessary. - Compiling the kernel -------------------- 1) move to /usr/src/linux and do a @@ -54,14 +49,14 @@ Compiling the kernel make config If you have chosen for option (a), answer yes to CONFIG_CM206 and - CONFIG_ISO9660_FS (should be default). + CONFIG_ISO9660_FS. If you have chosen for option (b), answer yes to CONFIG_MODVERSIONS and no (!) to CONFIG_CM206 and CONFIG_ISO9660_FS. 2) then do a - make dep; make zImage; make modules + make dep; make clean; make zImage; make modules 3) do the usual things to install a new image (backup the old one, run `rdev -R zImage 1', copy the new image in place, run lilo). Might @@ -82,8 +77,10 @@ line to be used, e.g. insmod /usr/src/linux/modules/cm206.o cm206=0x300,11 -You may also have to install the file-system module `iso9660.o', if you -didn't compile that into the kernel. If you use `tcsh' as shell, you +The order of base port and irq line don't matter; you may specify only +one, the other will have the value of the compiled-in default. You +may also have to install the file-system module `iso9660.o', if you +didn't compile that into the kernel. (If you use `tcsh' as shell, you might consider defining alias listinstalledmodules 'cat /proc/modules | awk \{print\$1\}' @@ -92,7 +89,7 @@ might consider defining alias insmod 'insmod /usr/src/linux/modules/\!:1 \!:2*' complete insmod 'p/1/`listcompiledmodules`/' -which makes typing insmod and rmmod somewhat easier. +which makes typing insmod and rmmod somewhat easier.) Using the driver as part of the kernel -------------------------------------- @@ -106,6 +103,15 @@ If you may specify either IRQ (3--11) or base port (0x300--0x370), auto probing is turned off for both settings, thus setting the other value to the compiled-in default. +If module parameters and LILO config options don't work +------------------------------------------------------- +If autoprobing does not work, you can hard-wire the default values +of the base port address (CM206_BASE) and interrupt request line +(CM206_IRQ) into the file ./include/linux/cm206.h. Change +the defines of CM206_IRQ and CM206_BASE. + + + Mounting the cdrom ------------------ 1) Make sure that there is the right device installed in /dev. diff --git a/drivers/block/aztcd.c b/drivers/block/aztcd.c index 1476cfbca739..394676bd4ed2 100644 --- a/drivers/block/aztcd.c +++ b/drivers/block/aztcd.c @@ -1,5 +1,5 @@ -#define AZT_VERSION "1.30" -/* $Id: aztcd.c,v 1.30 1995/07/04 08:28:06 root Exp $ +#define AZT_VERSION "1.40" +/* $Id: aztcd.c,v 1.40 1995/07/15 20:35:15 root Exp root $ linux/drivers/block/aztcd.c - AztechCD268 CDROM driver Copyright (C) 1994,1995 Werner Zimmermann (zimmerma@rz.fht-esslingen.de) @@ -116,6 +116,10 @@ Werner Zimmermann, May 22, 95 V1.30 Auto-eject feature. Inspired by Franc Racis (racis@psu.edu) Werner Zimmermann, July 4, 95 + V1.40 Started multisession support. Implementation copied from mcdx.c + by Heiko Schlittermann. Not tested, as I do not have a multi- + session CD. If you can test it, please contact me. + Werner Zimmermann, July 15, 95 NOTE: Points marked with ??? are questionable ! */ @@ -189,7 +193,7 @@ static int aztPresent = 0; static volatile int azt_transfer_is_active=0; static char azt_buf[2048*AZT_BUF_SIZ]; /*buffer for block size conversion*/ -#ifdef AZT_PRIVATE_IOCTLS +#if AZT_PRIVATE_IOCTLS static char buf[2336]; /*separate buffer for the ioctls*/ #endif @@ -364,7 +368,7 @@ static void aztCloseDoor(void) static void aztLockDoor(void) { -#ifdef AZT_ALLOW_TRAY_LOCK +#if AZT_ALLOW_TRAY_LOCK aztSendCmd(ACMD_LOCK); STEN_LOW; #endif @@ -373,7 +377,7 @@ static void aztLockDoor(void) static void aztUnlockDoor(void) { -#ifdef AZT_ALLOW_TRAY_LOCK +#if AZT_ALLOW_TRAY_LOCK aztSendCmd(ACMD_UNLOCK); STEN_LOW; #endif @@ -523,7 +527,7 @@ static int aztPlay(struct azt_Play_msf *arg) long azt_msf2hsg(struct msf *mp) { return azt_bcd2bin(mp -> frame) + azt_bcd2bin(mp -> sec) * 75 - + azt_bcd2bin(mp -> min) * 4500 - 150; + + azt_bcd2bin(mp -> min) * 4500 - CD_BLOCK_OFFSET; } static int aztcd_ioctl(struct inode *ip, struct file *fp, unsigned int cmd, unsigned long arg) @@ -550,7 +554,7 @@ static int aztcd_ioctl(struct inode *ip, struct file *fp, unsigned int cmd, unsi { case CDROMSTART: /* Spin up the drive. Don't know, what to do, at least close the tray */ -#ifdef AZT_PRIVATE_IOCTLS +#if AZT_PRIVATE_IOCTLS if (aztSendCmd(ACMD_CLOSE)) RETURNM("aztcd_ioctl 4",-1); STEN_LOW_WAIT; #endif @@ -585,6 +589,47 @@ static int aztcd_ioctl(struct inode *ip, struct file *fp, unsigned int cmd, unsi } aztAudioStatus = CDROM_AUDIO_PLAY; break; +#if AZT_MULTISESSION + case CDROMMULTISESSION: /*multisession support -- not tested ???*/ + { struct cdrom_multisession ms; +#ifdef AZT_DEBUG + printk("aztcd ioctl MULTISESSION\n"); +#endif + st = verify_area(VERIFY_READ, (void*) arg, sizeof(struct cdrom_multisession)); + if (st) return st; + memcpy_fromfs(&ms, (void*) arg, sizeof(struct cdrom_multisession)); + if (ms.addr_format == CDROM_MSF) + { ms.addr.msf.minute = azt_bcd2bin(DiskInfo.lastTrack.min); + ms.addr.msf.second = azt_bcd2bin(DiskInfo.lastTrack.sec); + ms.addr.msf.frame = azt_bcd2bin(DiskInfo.lastTrack.frame); + } + else if (ms.addr_format == CDROM_LBA) + ms.addr.lba = azt_msf2hsg(&DiskInfo.lastTrack); + else + return -EINVAL; + if (DiskInfo.type == CD_XA) + { ms.xa_flag = 0x01; /*XA-Disk*/ + } + else + { ms.xa_flag = 0x00; + } + st = verify_area(VERIFY_WRITE, (void*) arg, sizeof(struct cdrom_multisession)); + if (st) return st; + memcpy_tofs((void*) arg, &ms, sizeof(struct cdrom_multisession)); +#ifdef AZT_DEBUG + if (ms.addr_format == CDROM_MSF) + printk("aztcd multisession %d, %02x:%02x.%02x [%02x:%02x.%02x])\n", + ms.xa_flag, ms.addr.msf.minute, ms.addr.msf.second, + ms.addr.msf.frame, DiskInfo.lastTrack.min, + DiskInfo.lastTrack.sec, DiskInfo.lastTrack.frame); + else + printk("atzcd multisession %d, 0x%08x [%02x:%02x.%02x])\n", + ms.xa_flag, ms.addr.lba, DiskInfo.lastTrack.min, + DiskInfo.lastTrack.sec, DiskInfo.lastTrack.frame); +#endif + return 0; + } +#endif case CDROMPLAYTRKIND: /* Play a track. This currently ignores index. */ st = verify_area(VERIFY_READ, (void *) arg, sizeof ti); if (st) return st; @@ -595,7 +640,7 @@ static int aztcd_ioctl(struct inode *ip, struct file *fp, unsigned int cmd, unsi { return -EINVAL; } if (ti.cdti_trk1 > DiskInfo.last) - ti. cdti_trk1 = DiskInfo.last; + ti.cdti_trk1 = DiskInfo.last; azt_Play.start = Toc[ti.cdti_trk0].diskTime; azt_Play.end = Toc[ti.cdti_trk1 + 1].diskTime; #ifdef AZT_DEBUG @@ -758,10 +803,10 @@ azt_Play.end.min, azt_Play.end.sec, azt_Play.end.frame); case CDROMREADMODE1: /*read data in mode 1 (2048 Bytes)*/ case CDROMREADMODE2: /*read data in mode 2 (2336 Bytes)*/ /*Take care, the following code is not compatible with other CD-ROM drivers, - use it at your own risk with cdplay.c. Normally it is not activated, as - AZT_PRIVATE_IOCTLS is not defined + use it at your own risk with cdplay.c. Set AZT_PRIVATE_IOCTLS to 0 in aztcd.h, + if you do not want to use it! */ -#ifdef AZT_PRIVATE_IOCTLS +#if AZT_PRIVATE_IOCTLS { st = verify_area(VERIFY_READ, (void *) arg, sizeof msf); if (st) return st; st = verify_area(VERIFY_WRITE, (void *) arg, sizeof buf); @@ -1653,12 +1698,12 @@ static int aztGetDiskInfo() for (limit=300;limit>0;limit--) { if (aztGetQChannelInfo(&qInfo)<0) RETURNM("aztGetDiskInfo 2",-1); if (qInfo.pointIndex==0xA0) /*Number of FirstTrack*/ - { DiskInfo.first=qInfo.diskTime.min; + { DiskInfo.first = qInfo.diskTime.min; DiskInfo.first = azt_bcd2bin(DiskInfo.first); test=test|0x01; } if (qInfo.pointIndex==0xA1) /*Number of LastTrack*/ - { DiskInfo.last=qInfo.diskTime.min; + { DiskInfo.last = qInfo.diskTime.min; DiskInfo.last = azt_bcd2bin(DiskInfo.last); test=test|0x02; } @@ -1692,7 +1737,6 @@ printk("Disk Info: first %d last %d length %02x:%02x.%02x first %02x:%02x.%02x\n return 0; } - /* * Read the table of contents (TOC) */ @@ -1737,6 +1781,18 @@ static int aztGetToc() Toc[DiskInfo.last + 1].diskTime = DiskInfo.diskLength; + DiskInfo.lastTrack.sec=2; + DiskInfo.type = 0; + for (i=0;i<=DiskInfo.last;i++) /*Unterscheidung zw. Audio- und Datendisk???*/ + { if ((Toc[i].ctrl_addr)==0x01) + DiskInfo.type=DiskInfo.type|CD_AUDIO; + if ((Toc[i].ctrl_addr)==0x41) + DiskInfo.type=DiskInfo.type|CD_DATA; + } + DiskInfo.lastTrack.min =Toc[DiskInfo.last].diskTime.min; + DiskInfo.lastTrack.sec =Toc[DiskInfo.last].diskTime.sec; + DiskInfo.lastTrack.frame=Toc[DiskInfo.last].diskTime.frame; + #ifdef AZT_DEBUG printk("aztcd: exiting aztGetToc Time:%li\n",jiffies); for (i = 1; i <= DiskInfo.last+1; i++) @@ -1749,6 +1805,19 @@ printk("i = %2d ctl-adr = %02X track %2d px %02X %02X:%02X.%02X %02X:%02X.%02 i, Toc[i].ctrl_addr, Toc[i].track, Toc[i].pointIndex, Toc[i].trackTime.min, Toc[i].trackTime.sec, Toc[i].trackTime.frame, Toc[i].diskTime.min, Toc[i].diskTime.sec, Toc[i].diskTime.frame); +printk("\nDisk Info: first %d last %d length %02x:%02x.%02x first %02x:%02x.%02x last %02x:%02x.%02x type %02x\n", + DiskInfo.first, + DiskInfo.last, + DiskInfo.diskLength.min, + DiskInfo.diskLength.sec, + DiskInfo.diskLength.frame, + DiskInfo.firstTrack.min, + DiskInfo.firstTrack.sec, + DiskInfo.firstTrack.frame, + DiskInfo.lastTrack.min, + DiskInfo.lastTrack.sec, + DiskInfo.lastTrack.frame, + DiskInfo.type); #endif return limit > 0 ? 0 : -1; diff --git a/drivers/block/cdu31a.c b/drivers/block/cdu31a.c index e6d9d5a5f567..7c43dee9b530 100644 --- a/drivers/block/cdu31a.c +++ b/drivers/block/cdu31a.c @@ -325,6 +325,11 @@ static char *readahead_buffer = NULL; /* Used for 1024 byte blocksize. */ static int readahead_dataleft = 0; static int readahead_bad = 0; +/* Used to time a short period to abort an operation after the + drive has been idle for a while. This keeps the light on + the drive from flashing for very long. */ +static struct timer_list cdu31a_abort_timer; + /* * This routine returns 1 if the disk has been changed since the last @@ -1096,6 +1101,14 @@ abort_read(void) readahead_bad = 0; } +/* Called when the timer times out. This will abort the + pending read operation. */ +static void +handle_abort_timeout(unsigned long data) +{ + abort_read(); +} + /* Actually get data and status from the drive. */ static void input_data(char *buffer, @@ -1392,17 +1405,24 @@ do_cdu31a_request(void) { end_request(0); } + restore_flags(flags); return; } } sony_inuse = 1; has_cd_task = current; - restore_flags(flags); + sti(); /* Get drive status before doing anything. */ while (handle_sony_cd_attention()) ; + /* If the timer is running, cancel it. */ + if (cdu31a_abort_timer.next != NULL) + { + del_timer(&cdu31a_abort_timer); + } + while (1) { cdu31a_request_startover: @@ -1573,14 +1593,20 @@ try_read_again: } end_do_cdu31a_request: -#if 1 +#if 0 /* After finished, cancel any pending operations. */ abort_read(); +#else + /* Start a timer to time out after a while to disable + the read. */ + cdu31a_abort_timer.expires = 200; /* Wait 2 seconds */ + add_timer(&cdu31a_abort_timer); #endif has_cd_task = NULL; sony_inuse = 0; wake_up_interruptible(&sony_wait); + restore_flags(flags); } /* Copy overlapping buffers. */ @@ -2969,6 +2995,10 @@ cdu31a_init(unsigned long mem_start, unsigned long mem_end) mem_start += CD_FRAMESIZE_RAW; sony_toc = (struct s_sony_session_toc *) mem_start; mem_start += sizeof(struct s_sony_session_toc); + + cdu31a_abort_timer.next = NULL; + cdu31a_abort_timer.prev = NULL; + cdu31a_abort_timer.function = handle_abort_timeout; } diff --git a/drivers/block/cm206.c b/drivers/block/cm206.c index fdad07320bbe..73402e3e49ff 100644 --- a/drivers/block/cm206.c +++ b/drivers/block/cm206.c @@ -53,6 +53,12 @@ History: 1 jun 1995: 0.32 Removed probe_irq_on/off for module version. 10 jun 1995: 0.33 Workman still behaves funny, but you should be able to eject and substitute another disc. + + An adaption of 0.33 is included in linux-1.3.7 by Eberhard Moenkeberg + + 18 jul 1996: 0.34 Patch by Heiko Eissfeldt included, mainly considering + verify_area's in the ioctls. Some bugs introduced by + EM considering the base port and irq fixed. * * Parts of the code are based upon lmscd.c written by Kai Petzke, * sbpcd.c written by Eberhard Moenkeberg, and mcd.c by Martin @@ -73,7 +79,7 @@ History: * - Philips/LMS cm260 product specification * * David van Leeuwen, david@tm.tno.nl. */ -#define VERSION "0.33" +#define VERSION "0.34" #ifdef MODULE /* OK, so some of this is stolen */ #include @@ -95,6 +101,7 @@ char kernel_version[]=UTS_RELEASE; #include #include #include +#include #include @@ -108,9 +115,8 @@ char kernel_version[]=UTS_RELEASE; */ static int auto_probe=1; /* Yes, why not? */ -#define cm206_base cm206 /* for compatible "insmod" parameter passing */ static int cm206_base = CM206_BASE; -static int cm206_irq = CM206_IRQ; /* must directly follow cm206_base */ +static int cm206_irq = CM206_IRQ; #undef DEBUG #undef DEBUG_SECTORS @@ -674,10 +680,19 @@ static void do_cm206_request(void) int get_multi_session_info(struct cdrom_multisession * mssp) { if (!FIRST_TRACK) get_disc_status(); - if (mssp && DISC_STATUS & cds_multi_session) { /* multi-session */ - mssp->addr.lba = fsm2lba(&cd->disc_status[3]); - mssp->xa_flag = 1; /* don't know */ - mssp->addr_format = CDROM_LBA; /* too bad if fsm requested! */ + if (mssp) { + if (DISC_STATUS & cds_multi_session) { /* multi-session */ + if (mssp->addr_format == CDROM_LBA) + mssp->addr.lba = fsm2lba(&cd->disc_status[3]); + else { + mssp->addr.msf.frame = cd->disc_status[3]; + mssp->addr.msf.second = cd->disc_status[4]; + mssp->addr.msf.minute = cd->disc_status[5]; + } + mssp->xa_flag = 1; + } else { + mssp->xa_flag = 0; + } return 1; } return 0; @@ -889,33 +904,41 @@ static int cm206_ioctl(struct inode * inode, struct file * file, #endif case CDROMMULTISESSION: { struct cdrom_multisession ms_info; + int st; stats(ioctl_multisession); - if (get_multi_session_info(&ms_info)) { - memcpy_tofs((struct cdrom_multisession *) arg, &ms_info, + + st=verify_area(VERIFY_WRITE, (void *) arg, + sizeof(struct cdrom_multisession)); + if (st) return (st); + memcpy_fromfs(&ms_info, (struct cdrom_multisession *) arg, sizeof(struct cdrom_multisession)); - return 0; - } - else return -cmd; + get_multi_session_info(&ms_info); + memcpy_tofs((struct cdrom_multisession *) arg, &ms_info, + sizeof(struct cdrom_multisession)); + return 0; } - case CM206_RESET_DRIVE: + case CDROMRESET: /* If needed, it's probably too late anyway */ stop_read(); reset_cm260(); outw(dc_normal | dc_break | READ_AHEAD, r_data_control); udelay(1000); /* 750 musec minimum */ outw(dc_normal | READ_AHEAD, r_data_control); - cd->sector_last = -1; /* flag no data buffered */ + cd->sector_last = -1; /* flag no data buffered */ cd->adapter_last = -1; return 0; } + get_drive_status(); if (cd->dsb & (dsb_drive_not_ready | dsb_tray_not_closed) ) return -EAGAIN; + switch (cmd) { case CDROMREADTOCHDR: { struct cdrom_tochdr header; - get_drive_status(); - if (cd->dsb & (dsb_drive_not_ready | dsb_tray_not_closed) ) - return -EAGAIN; + int st; + + st=verify_area(VERIFY_WRITE, (void *) arg, sizeof(header)); + if (st) return (st); if (read_toc_header(&header)) { memcpy_tofs((struct cdrom_tochdr *) arg, &header, sizeof(header)); return 0; @@ -924,6 +947,10 @@ static int cm206_ioctl(struct inode * inode, struct file * file, } case CDROMREADTOCENTRY: { struct cdrom_tocentry entry; + int st; + + st=verify_area(VERIFY_WRITE, (void *) arg, sizeof(entry)); + if (st) return (st); memcpy_fromfs(&entry, (struct cdrom_tocentry *) arg, sizeof entry); get_toc_entry(&entry); memcpy_tofs((struct cdrom_tocentry *) arg, &entry, sizeof entry); @@ -931,12 +958,20 @@ static int cm206_ioctl(struct inode * inode, struct file * file, } case CDROMPLAYMSF: { struct cdrom_msf msf; + int st; + + st=verify_area(VERIFY_READ, (void *) arg, sizeof(msf)); + if (st) return (st); memcpy_fromfs(&msf, (struct cdrom_mdf *) arg, sizeof msf); play_from_to_msf(&msf); return 0; } case CDROMPLAYTRKIND: { struct cdrom_ti track_index; + int st; + + st=verify_area(VERIFY_READ, (void *) arg, sizeof(track_index)); + if (st) return (st); memcpy_fromfs(&track_index, (struct cdrom_ti *) arg, sizeof(track_index)); play_from_to_track(track_index.cdti_trk0, track_index.cdti_trk1); return 0; @@ -970,6 +1005,10 @@ static int cm206_ioctl(struct inode * inode, struct file * file, return 0; case CDROMSUBCHNL: { struct cdrom_subchnl q; + int st; + + st=verify_area(VERIFY_WRITE, (void *) arg, sizeof(q)); + if (st) return (st); memcpy_fromfs(&q, (struct cdrom_subchnl *) arg, sizeof q); if (get_current_q(&q)) { memcpy_tofs((struct cdrom_subchnl *) arg, &q, sizeof q); @@ -979,6 +1018,10 @@ static int cm206_ioctl(struct inode * inode, struct file * file, } case CDROM_GET_UPC: { uch upc[10]; + int st; + + st=verify_area(VERIFY_WRITE, (void *) arg, 8); + if (st) return (st); if (type_1_command(c_read_upc, 10, upc)) return -EIO; memcpy_tofs((uch *) arg, &upc[1], 8); return 0; @@ -1081,14 +1124,36 @@ int probe_irq(int nr) { } #endif -/* Wow is this piece of #ifdeffing ugly! */ #ifdef MODULE #define OK 0 #define ERROR -EIO -int init_module(void) -#else + +static int cm206[2] = {0,0}; /* for compatible `insmod' parameter passing */ +void parse_options() +{ + int i; + for (i=0; i<2; i++) { + if (0x300 <= cm206[i] && i<= 0x370 && cm206[i] % 0x10 == 0) { + cm206_base = cm206[i]; + auto_probe=0; + } + else if (3 <= cm206[i] && cm206[i] <= 15) { + cm206_irq = cm206[i]; + auto_probe=0; + } + } +} + +#else MODULE + #define OK mem_start+size #define ERROR mem_start + +#endif MODULE + +#ifdef MODULE +int init_module(void) +#else unsigned long cm206_init(unsigned long mem_start, unsigned long mem_end) #endif { @@ -1096,8 +1161,11 @@ unsigned long cm206_init(unsigned long mem_start, unsigned long mem_end) long int size=sizeof(struct cm206_struct); printk("cm206: v" VERSION); -#if defined(MODULE) && !defined(AUTO_PROBE_MODULE) - auto_probe=0; +#if defined(MODULE) + parse_options(); +#if !defined(AUTO_PROBE_MODULE) + auto_probe=0; +#endif #endif cm206_base = probe_base_port(auto_probe ? 0 : cm206_base); if (!cm206_base) { @@ -1173,7 +1241,7 @@ void cleanup_module(void) cleanup(4); printk("cm206 removed\n"); } - + #else MODULE /* This setup function accepts either `auto' or numbers in the range @@ -1181,9 +1249,7 @@ void cleanup_module(void) void cm206_setup(char *s, int *p) { int i; -#ifdef AUTO_PROBE_MODULE if (!strcmp(s, "auto")) auto_probe=1; -#endif for(i=1; i<=p[0]; i++) { if (0x300 <= p[i] && i<= 0x370 && p[i] % 0x10 == 0) { cm206_base = p[i]; diff --git a/drivers/block/mcd.c b/drivers/block/mcd.c index dfb9dca75836..06fbe878c6cf 100644 --- a/drivers/block/mcd.c +++ b/drivers/block/mcd.c @@ -38,9 +38,28 @@ November 93 added code for FX001 S,D (single & double speed). February 94 added code for broken M 5/6 series of 16-bit single speed. - 0.4 Added support for loadable MODULEs, so mcd can now also be - loaded by insmod and removed by rmmod during runtime. - Werner Zimmermann (zimmerma@rz.fht-esslingen.de), Mar. 26, 95 + + 0.4 + Added support for loadable MODULEs, so mcd can now also be loaded by + insmod and removed by rmmod during runtime. + Werner Zimmermann (zimmerma@rz.fht-esslingen.de), Mar. 26, 95 + + 0.5 + I added code for FX001 D to drop from double speed to single speed + when encountering errors... this helps with some "problematic" CD's + that are supposedly "OUT OF TOLERANCE" (but are really shitty presses!) + severly scratched, or possibly slightly warped! I have noticed that + the Mitsumi 2x/4x drives are just less tolerant and the firmware is + not smart enough to drop speed, so let's just kludge it with software! + ****** THE 4X SPEED MITSUMI DRIVES HAVE THE SAME PROBLEM!!!!!! ****** + Anyone want to "DONATE" one to me?! ;) I hear sometimes they are + even WORSE! ;) + ** HINT... HINT... TAKE NOTES MITSUMI This could save some hassels with + certain "large" CD's that have data on the outside edge in your + DOS DRIVERS .... Accuracy counts... speed is secondary ;) + 17 June 95 Modifications By Andrew J. Kroll + 07 July 1995 Modifications by Andrew J. Kroll + */ #include @@ -82,6 +101,24 @@ static int mcd_sizes[] = { 0 }; #endif +/* I know putting defines in this file is probably stupid, but it should be */ +/* the only place that they are really needed... I HOPE! :) */ + +/* How many sectors to read at 1x when an error at 2x speed occurs. */ +/* You can change this to anything from 2 to 32767, but 30 seems to */ +/* work best for me. I have found that when the drive has problems */ +/* reading one sector, it will have troubles reading the next few. */ +#define SINGLE_HOLD_SECTORS 30 + +#define MCMD_2X_READ 0xC1 /* Double Speed Read DON'T TOUCH! */ + +/* I added A flag to drop to 1x speed if too many errors 0 = 1X ; 1 = 2X */ +static int mcdDouble = 0; + +/* How many sectors to hold at 1x speed counter */ +static int mcd1xhold = 0; + +/* Is the drive connected properly and responding?? */ static int mcdPresent = 0; #if 0 @@ -667,35 +704,71 @@ mcd_poll(void) int st; - if (mcd_error) { - if (mcd_error & 0xA5) { + if (mcd_error) + { + if (mcd_error & 0xA5) + { printk("mcd: I/O error 0x%02x", mcd_error); if (mcd_error & 0x80) printk(" (Door open)"); if (mcd_error & 0x20) printk(" (Disk changed)"); if (mcd_error & 0x04) - printk(" (Read error)"); + { + printk(" (Read error)"); /* Bitch about the problem. */ + + /* Time to get fancy! If at 2x speed and 1 error, drop to 1x speed! */ + /* Interesting how it STAYS at MCD_RETRY_ATTEMPTS on first error! */ + /* But I find that rather HANDY!!! */ + /* Neat! it REALLY WORKS on those LOW QUALITY CD's!!! Smile! :) */ + /* AJK [06/17/95] */ + + /* Slap the CD down to single speed! */ + if (mcdDouble == 1 && McdTries == MCD_RETRY_ATTEMPTS && MCMD_DATA_READ == MCMD_2X_READ) + { + MCMD_DATA_READ = MCMD_PLAY_READ; /* Uhhh, Ummmm, muhuh-huh! */ + mcd1xhold = SINGLE_HOLD_SECTORS; /* Hey Bevis! */ + printk(" Speed now 1x"); /* Pull my finger! */ + } + } printk("\n"); mcd_invalidate_buffers(); #ifdef WARN_IF_READ_FAILURE - if (McdTries == 5) + if (McdTries == MCD_RETRY_ATTEMPTS) printk("mcd: read of block %d failed\n", mcd_next_bn); #endif - if (!McdTries--) { + if (!McdTries--) + { + /* Nuts! This cd is ready for recycling! */ + /* When WAS the last time YOU cleaned it CORRECTLY?! */ printk("mcd: read of block %d failed, giving up\n", mcd_next_bn); - if (mcd_transfer_is_active) { + if (mcd_transfer_is_active) + { McdTries = 0; goto ret; } if (CURRENT_VALID) end_request(0); - McdTries = 5; + McdTries = MCD_RETRY_ATTEMPTS; } } mcd_error = 0; mcd_state = MCD_S_STOP; } + /* Switch back to Double speed if enough GOOD sectors were read! */ + + /* Are we a double speed with a crappy CD?! */ + if (mcdDouble == 1 && McdTries == MCD_RETRY_ATTEMPTS && MCMD_DATA_READ == MCMD_PLAY_READ) + { + /* We ARE a double speed and we ARE bitching! */ + if (mcd1xhold == 0) /* Okay, Like are we STILL at single speed? */ + { /* We need to switch back to double speed now... */ + MCMD_DATA_READ = MCMD_2X_READ; /* Uhhh... BACK You GO! */ + printk("mcd: Switching back to 2X speed!\n"); /* Tell 'em! */ + } + else mcd1xhold--; /* No?! Count down the good reads some more... */ + /* and try, try again! */ + } @@ -1183,10 +1256,16 @@ int init_module(void) #else return -EIO; #endif - printk("Mitsumi status, type and version : %02X %c %x\n", + printk("Mitsumi status, type and version : %02X %c %x ", result[0],result[1],result[2]); - if (result[1] == 'D') MCMD_DATA_READ= 0xC1; + if (result[1] == 'D') + { + printk("Double Speed CD ROM\n"); + MCMD_DATA_READ = MCMD_2X_READ; + mcdDouble = 1; /* Added flag to drop to 1x speed if too many errors */ + } + else printk("Single Speed CD ROM\n"); mcdVersion=result[2]; diff --git a/drivers/char/Makefile b/drivers/char/Makefile index 2d4927a3cc76..cae4efeaa873 100644 --- a/drivers/char/Makefile +++ b/drivers/char/Makefile @@ -83,7 +83,7 @@ SRCS := $(SRCS) scc.c endif -all: char.a +all: uni_hash_tbl.h char.a char.a: $(OBJS) $(AR) rcs char.a $(OBJS) diff --git a/drivers/net/de4x5.c b/drivers/net/de4x5.c index fa800358d077..578c6e9c80d1 100644 --- a/drivers/net/de4x5.c +++ b/drivers/net/de4x5.c @@ -213,7 +213,7 @@ static s32 de4x5_full_duplex = 0; #define MIN_DAT_SZ 1 /* Minimum ethernet data length */ #define PKT_HDR_LEN 14 /* Addresses and data length info */ #define FAKE_FRAME_LEN (MAX_PKT_SZ + 1) -#define QUEUE_PKT_TIMEOUT (300) /* Jiffies */ +#define QUEUE_PKT_TIMEOUT (3*HZ) /* 3 second timeout */ #define CRC_POLYNOMIAL_BE 0x04c11db7UL /* Ethernet CRC, big endian */ @@ -916,7 +916,7 @@ de4x5_init(struct device *dev) outl(omr|OMR_ST, DE4X5_OMR); /* Poll for completion of setup frame (interrupts are disabled for now) */ - for (j=0, i=jiffies;(i==jiffies) && (j==0);) { + for (j=0, i=jiffies;(i<=jiffies+HZ/100) && (j==0);) { if (lp->tx_ring[lp->tx_new].status >= 0) j=1; } outl(omr, DE4X5_OMR); /* Stop everything! */ @@ -973,7 +973,7 @@ de4x5_queue_pkt(struct sk_buff *skb, struct device *dev) status = -1; } else { if (de4x5_debug >= 1) { - printk("%s: transmit timed out, status %08x, tbusy:%d, lostMedia:%d tickssofar:%ld, resetting.\n",dev->name, inl(DE4X5_STS), dev->tbusy, lp->lostMedia, tickssofar); + printk("%s: transmit timed out, status %08x, tbusy:%ld, lostMedia:%d tickssofar:%ld, resetting.\n",dev->name, inl(DE4X5_STS), dev->tbusy, lp->lostMedia, tickssofar); } /* Stop and reset the TX and RX... */ diff --git a/drivers/net/depca.c b/drivers/net/depca.c index 95ba7cad4f1d..e2fd02a554d3 100644 --- a/drivers/net/depca.c +++ b/drivers/net/depca.c @@ -817,7 +817,7 @@ depca_start_xmit(struct sk_buff *skb, struct device *dev) /* Transmitter timeout, serious problems. */ if (dev->tbusy) { int tickssofar = jiffies - dev->trans_start; - if (tickssofar < 100) { + if (tickssofar < 1*HZ) { status = -1; } else { printk("%s: transmit timed out, status %04x, resetting.\n", diff --git a/drivers/net/loopback.c b/drivers/net/loopback.c index 00bf67d96118..e1a0b39dbb13 100644 --- a/drivers/net/loopback.c +++ b/drivers/net/loopback.c @@ -101,6 +101,7 @@ static int loopback_xmit(struct sk_buff *skb, struct device *dev) restore_flags(flags); stats->tx_packets++; + stats->rx_packets++; dev->tbusy = 0; diff --git a/drivers/net/slhc.c b/drivers/net/slhc.c index ad59454cc680..ba0c7d9fade6 100644 --- a/drivers/net/slhc.c +++ b/drivers/net/slhc.c @@ -615,8 +615,8 @@ slhc_uncompress(struct slcompress *comp, unsigned char *icp, int isize) cp += 20; if (ip->ihl > 5) { - memcpy(cp, cs->cs_ipopt, ((ip->ihl) - 5) * 4); - cp += ((ip->ihl) - 5) * 4; + memcpy(cp, cs->cs_ipopt, (ip->ihl - 5) * 4); + cp += (ip->ihl - 5) * 4; } ((struct iphdr *)icp)->check = ip_fast_csum(icp, ((struct iphdr*)icp)->ihl); @@ -640,9 +640,7 @@ int slhc_remember(struct slcompress *comp, unsigned char *icp, int isize) { register struct cstate *cs; - short ip_len; - struct iphdr *ip; - struct tcphdr *thp; + unsigned ihl; unsigned char index; @@ -651,23 +649,21 @@ slhc_remember(struct slcompress *comp, unsigned char *icp, int isize) comp->sls_i_runt++; return slhc_toss( comp ); } - /* Sneak a peek at the IP header's IHL field to find its length */ - ip_len = (icp[0] & 0xf) << 2; - if(ip_len < 20){ + /* Peek at the IP header's IHL field to find its length */ + ihl = icp[0] & 0xf; + if(ihl < 20 / 4){ /* The IP header length field is too small */ comp->sls_i_runt++; return slhc_toss( comp ); } index = icp[9]; icp[9] = IPPROTO_TCP; - ip = (struct iphdr *) icp; - if (ip_fast_csum(icp, ip->ihl)) { + if (ip_fast_csum(icp, ihl)) { /* Bad IP header checksum; discard */ comp->sls_i_badcheck++; return slhc_toss( comp ); } - thp = (struct tcphdr *)(((unsigned char *)ip) + ip->ihl*4); if(index > comp->rslot_limit) { comp->sls_i_error++; return slhc_toss(comp); @@ -676,13 +672,13 @@ slhc_remember(struct slcompress *comp, unsigned char *icp, int isize) /* Update local state */ cs = &comp->rstate[comp->recv_current = index]; comp->flags &=~ SLF_TOSS; - memcpy(&cs->cs_ip,ip,20); - memcpy(&cs->cs_tcp,thp,20); - if (ip->ihl > 5) - memcpy(cs->cs_ipopt, ip+1, ((ip->ihl) - 5) * 4); - if (thp->doff > 5) - memcpy(cs->cs_tcpopt, thp+1, ((thp->doff) - 5) * 4); - cs->cs_hsize = ip->ihl*2 + thp->doff*2; + memcpy(&cs->cs_ip,icp,20); + memcpy(&cs->cs_tcp,icp + ihl*4,20); + if (ihl > 5) + memcpy(cs->cs_ipopt, icp + sizeof(struct iphdr), (ihl - 5) * 4); + if (cs->cs_tcp.doff > 5) + memcpy(cs->cs_tcpopt, icp + ihl*4 + sizeof(struct tcphdr), (cs->cs_tcp.doff - 5) * 4); + cs->cs_hsize = ihl*2 + cs->cs_tcp.doff*2; /* Put headers back on packet * Neither header checksum is recalculated */ diff --git a/drivers/scsi/Makefile b/drivers/scsi/Makefile index f240fbecb7d0..944e1d9e2af0 100644 --- a/drivers/scsi/Makefile +++ b/drivers/scsi/Makefile @@ -11,8 +11,10 @@ .c.o: $(CC) $(CFLAGS) -c $< +ifdef CONFIG_KERNEL_ELF # This is used for ELF - it needs to migrate or be moved. LD_RFLAG = -m elf_i386 +endif AHA152X = -DDEBUG_AHA152X -DAUTOCONF -DSKIP_BIOSTEST -DIRQ=11 diff --git a/drivers/scsi/aic7xxx.c b/drivers/scsi/aic7xxx.c index 3e5f47464dcb..bae1776d2ba6 100644 --- a/drivers/scsi/aic7xxx.c +++ b/drivers/scsi/aic7xxx.c @@ -18,9 +18,6 @@ * along with this program; see the file COPYING. If not, write to * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. * - * An alternate version of this driver with a BSD-style copyright can - * be found on XXX. - * * Sources include the Adaptec 1740 driver (aha1740.c), the Ultrastor 24F * driver (ultrastor.c), various Linux kernel source, the Adaptec EISA * config file (!adp7771.cfg), the Adaptec AHA-2740A Series User's Guide, diff --git a/drivers/scsi/aic7xxx.h b/drivers/scsi/aic7xxx.h index aad3b67c1115..5cc2fec57123 100644 --- a/drivers/scsi/aic7xxx.h +++ b/drivers/scsi/aic7xxx.h @@ -18,9 +18,6 @@ * along with this program; see the file COPYING. If not, write to * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. * - * An alternate version of this driver with a BSD-style copyright can - * be found on XXX. - * * $Id: aic7xxx.h,v 1.18 1995/06/22 04:17:56 deang Exp $ *-M*************************************************************************/ #ifndef _aic7xxx_h diff --git a/drivers/scsi/aic7xxx_asm.c b/drivers/scsi/aic7xxx_asm.c index 65485f6e5d26..8b2baf60d5db 100644 --- a/drivers/scsi/aic7xxx_asm.c +++ b/drivers/scsi/aic7xxx_asm.c @@ -18,9 +18,6 @@ * along with this program; see the file COPYING. If not, write to * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. * - * An alternate version of this driver with a BSD-style copyright can - * be found on XXX. - * * Comments are started by `#' and continue to the end of the line; lines * may be of the form: *