Commit cac3e1c7 authored by Linus Torvalds's avatar Linus Torvalds

Import 1.3.12

parent b872e060
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`
......
......@@ -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
......
......@@ -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;
}
......
......@@ -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(&regs,0);
if (request == PTRACE_TRACEME) {
/* are we already being traced? */
if (current->flags & PF_PTRACED) {
set_failure(&regs,-EPERM);
return -EPERM;
}
/* set the ptrace bit in the process flags. */
current->flags |= PF_PTRACED;
return 0;
if (current->flags & PF_PTRACED) {
set_failure(&regs,-EPERM);
return -EPERM;
}
/* set the ptrace bit in the process flags. */
current->flags |= PF_PTRACED;
return 0;
}
if (pid == 1) {
set_failure(&regs,-EPERM);
return -EPERM;
if (pid == 1) { /* you may not mess with init */
set_failure(&regs,-EPERM);
return -EPERM;
}
if (!(child = get_task(pid))) {
set_failure(&regs,-ESRCH);
return -ESRCH;
set_failure(&regs,-ESRCH);
return -ESRCH;
}
if (request == PTRACE_ATTACH) {
if (child == current) {
set_failure(&regs,-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(&regs,-EPERM);
return -EPERM;
}
/* the same process cannot be attached many times */
if (child->flags & PF_PTRACED) {
set_failure(&regs,-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(&regs,-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(&regs,-EPERM);
return -EPERM;
}
/* the same process cannot be attached many times */
if (child->flags & PF_PTRACED) {
set_failure(&regs,-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(&regs,-ESRCH);
return -ESRCH;
DBG(DBG_MEM, ("child not traced\n"));
set_failure(&regs,-ESRCH);
return -ESRCH;
}
if (child->state != TASK_STOPPED) {
DBG(DBG_MEM, ("child process not stopped\n"));
if (request != PTRACE_KILL) {
set_failure(&regs,-ESRCH);
return -ESRCH;
}
DBG(DBG_MEM, ("child process not stopped\n"));
if (request != PTRACE_KILL) {
set_failure(&regs,-ESRCH);
return -ESRCH;
}
}
if (child->p_pptr != current) {
DBG(DBG_MEM, ("child not parent of this process\n"));
set_failure(&regs,-ESRCH);
return -ESRCH;
DBG(DBG_MEM, ("child not parent of this process\n"));
set_failure(&regs,-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(&regs,res);
return res;
}
else {
set_success(&regs,tmp);
return 0;
set_failure(&regs,res);
return res;
} else {
set_success(&regs,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(&regs, -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(&regs, -EIO);
return -EIO;
}
tmp = get_stack_long(child, addr);
DBG(DBG_MEM, ("%d = reg 0x%lx=tmp\n",reg,tmp));
}
set_success(&regs,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(&regs,res);
long res = write_long(child,addr,data);
if (res) {
set_failure(&regs,res);
}
return res;
}
case PTRACE_POKEUSR: /* write the specified register */
{
long res;
addr= offset_of_register(addr);
if(addr < 0) {
set_failure(&regs,-EIO);
return -EIO;
}
res=put_stack_long(child,addr,data);
if(res) {
set_failure(&regs,res);
}
return res;
}
{
long res;
addr = offset_of_register(addr);
if(addr < 0) {
set_failure(&regs,-EIO);
return -EIO;
}
res = put_stack_long(child, addr, data);
if (res) {
set_failure(&regs,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(&regs,-EIO);
return -EIO;
set_failure(&regs,-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(&regs,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(&regs,-EIO);
return -EIO;
set_failure(&regs,-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(&regs,-EIO);
return -EIO;
set_failure(&regs,-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(&regs,-EIO);
return -EIO;
}
}
set_failure(&regs,-EIO);
return -EIO;
}
}
asmlinkage void syscall_trace(void)
......
......@@ -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
}
......@@ -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);
......
......@@ -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
......
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
......
......@@ -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.
......
#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;
......
......@@ -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 @@ do_cdu31a_request(void)
}
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;
}
......
......@@ -53,6 +53,12 @@
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 @@
* - 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 <linux/module.h>
......@@ -95,6 +101,7 @@ char kernel_version[]=UTS_RELEASE;
#include <linux/timer.h>
#include <linux/cdrom.h>
#include <linux/ioport.h>
#include <linux/mm.h>
#include <asm/io.h>
......@@ -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];
......
......@@ -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 <ag784@freenet.buffalo.edu>
07 July 1995 Modifications by Andrew J. Kroll
*/
#include <linux/config.h>
......@@ -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];
......
......@@ -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)
......
......@@ -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... */
......
......@@ -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",
......
......@@ -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;
......
......@@ -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
*/
......
......@@ -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
......
......@@ -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,
......
......@@ -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
......
......@@ -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:
* <label>*
......
......@@ -757,7 +757,7 @@ void scan_scsis (struct Scsi_Host * shpnt, unchar hardcoded,
if(SDpnt != NULL)
scsi_init_free((char *) SDpnt, sizeof(Scsi_Device));
if(SDpnt != NULL)
if(SCpnt != NULL)
scsi_init_free((char *) SCpnt, sizeof(Scsi_Cmnd));
/* If we allocated a buffer so we could do DMA, free it now */
......
......@@ -167,7 +167,7 @@ static char *sg_malloc(int size)
if (size<=4096)
return (char *) scsi_malloc(size);
#ifdef SG_BIG_BUFF
if (size<SG_BIG_BUFF)
if (size<=SG_BIG_BUFF)
{
while(big_inuse)
{
......
......@@ -33,7 +33,7 @@
#include "pas.h"
#if !defined(EXCLUDE_PAS) && !defined(EXCLUDE_MIDI) && defined(EXCLUDE_PRO_MIDI)
#if !defined(EXCLUDE_PAS) && !defined(EXCLUDE_MIDI)
static int midi_busy = 0, input_opened = 0;
static int my_dev;
......
......@@ -77,7 +77,7 @@ extern void _outl (unsigned int l,unsigned long port);
# define outl(l,p) _outl((l),(p))
#endif
#endif /* __KERNEL__ */
#endif /* !__KERNEL__ */
/*
* There are different version of the alpha motherboards: the
......@@ -90,6 +90,8 @@ extern void _outl (unsigned int l,unsigned long port);
#include <asm/jensen.h>
#endif
#ifdef __KERNEL__
/*
* String version of IO memory access ops:
*/
......@@ -123,4 +125,6 @@ extern void outsl (unsigned long port, void *dst, unsigned long count);
#define memcpy_fromio(to,from,len) (memcpy_fromio)((to),(unsigned long)(from),(len))
#define memcpy_toio(to,from,len) (memcpy_toio)((unsigned long)(to),(from),(len))
#endif /* __KERNEL__ */
#endif
#ifndef __ALPHA_MMAN_H__
#define __ALPHA_MMAN_H__
#define PROT_READ 0x1 /* page can be read */
#define PROT_WRITE 0x2 /* page can be written */
#define PROT_EXEC 0x4 /* page can be executed */
#define PROT_NONE 0x0 /* page can not be accessed */
#define MAP_SHARED 0x01 /* Share changes */
#define MAP_PRIVATE 0x02 /* Changes are private */
#define MAP_TYPE 0x0f /* Mask for type of mapping (OSF/1 is _wrong_) */
#define MAP_FIXED 0x100 /* Interpret addr exactly */
#define MAP_ANONYMOUS 0x10 /* don't use a file */
/* not used by linux, but here to make sure we don't clash with OSF/1 defines */
#define MAP_HASSEMAPHORE 0x0200
#define MAP_INHERIT 0x0400
#define MAP_UNALIGNED 0x0800
/* These are linux-specific */
#define MAP_GROWSDOWN 0x1000 /* stack-like segment */
#define MAP_DENYWRITE 0x2000 /* ETXTBSY */
#define MAP_EXECUTABLE 0x4000 /* mark it as a executable */
#define MS_ASYNC 1 /* sync memory asynchronously */
#define MS_SYNC 2 /* synchronous memory sync */
#define MS_INVALIDATE 4 /* invalidate the caches */
#endif /* __ALPHA_MMAN_H__ */
#ifndef _ASMAXP_SIGCONTEXT_H
#define _ASMAXP_SIGCONTEXT_H
struct sigcontext_struct {
/*
* what should we have here? I'd probably better use the same
* stack layout as OSF/1, just in case we ever want to try
* running their binaries..
*
* This is the basic layout, but I don't know if we'll ever
* actually fill in all the values..
*/
long sc_onstack;
long sc_mask;
long sc_pc;
long sc_ps;
long sc_regs[32];
long sc_ownedfp;
long sc_fpregs[32];
unsigned long sc_fpcr;
unsigned long sc_fp_control;
unsigned long sc_reserved1, sc_reserved2;
unsigned long sc_ssize;
char * sc_sbase;
unsigned long sc_traparg_a0;
unsigned long sc_traparg_a1;
unsigned long sc_traparg_a2;
unsigned long sc_fp_trap_pc;
unsigned long sc_fp_trigger_sum;
unsigned long sc_fp_trigger_inst;
unsigned long sc_retcode[2];
};
#endif
......@@ -78,37 +78,7 @@ struct sigaction {
};
#ifdef __KERNEL__
struct sigcontext_struct {
/*
* what should we have here? I'd probably better use the same
* stack layout as OSF/1, just in case we ever want to try
* running their binaries..
*
* This is the basic layout, but I don't know if we'll ever
* actually fill in all the values..
*/
long sc_onstack;
long sc_mask;
long sc_pc;
long sc_ps;
long sc_regs[32];
long sc_ownedfp;
long sc_fpregs[32];
unsigned long sc_fpcr;
unsigned long sc_fp_control;
unsigned long sc_reserved1, sc_reserved2;
unsigned long sc_ssize;
char * sc_sbase;
unsigned long sc_traparg_a0;
unsigned long sc_traparg_a1;
unsigned long sc_traparg_a2;
unsigned long sc_fp_trap_pc;
unsigned long sc_fp_trigger_sum;
unsigned long sc_fp_trigger_inst;
unsigned long sc_retcode[2];
};
#include <asm/sigcontext.h>
#endif
#endif
......@@ -5,11 +5,12 @@ extern void * __constant_c_memset(void *, unsigned long, long);
extern void * __memset(void *, char, size_t);
extern void * __memcpy(void *, const void *, size_t);
#define __HAVE_ARCH_MEMSET
#define memset(s, c, count) \
(__builtin_constant_p(c) ? \
__constant_c_memset((s),(0x0101010101010101UL*(unsigned char)c),(count)) : \
__memset((s),(c),(count)))
#define memcpy(d,s,count) __memcpy((d),(s),(count))
#define __HAVE_ARCH_STRLEN
#endif
......@@ -118,6 +118,16 @@ extern inline unsigned long xchg_u64(volatile long * m, unsigned long val)
#define xchg(ptr,x) ((__typeof__(*(ptr)))__xchg((unsigned long)(x),(ptr),sizeof(*(ptr))))
#define tas(ptr) (xchg((ptr),1))
/*
* This function doesn't exist, so you'll get a linker error
* if something tries to do an invalid xchg().
*
* This only works if the compiler isn't horribly bad at optimizing.
* gcc-2.5.8 reportedly can't handle this, but as that doesn't work
* too well on the alpha anyway..
*/
extern void __xchg_called_with_bad_pointer(void);
static inline unsigned long __xchg(unsigned long x, volatile void * ptr, int size)
{
switch (size) {
......@@ -126,7 +136,7 @@ static inline unsigned long __xchg(unsigned long x, volatile void * ptr, int siz
case 8:
return xchg_u64(ptr, x);
}
printk("Argh.. xchg() with unsupported size\n");
__xchg_called_with_bad_pointer();
return x;
}
......
......@@ -50,7 +50,7 @@
#define __NR_vhangup 76
#define __NR_getgroups 79
#define __NR_setgroups 80
#define __NR_setpgid 82
#define __NR_setpgrp 82
#define __NR_setitimer 83
#define __NR_getitimer 86
#define __NR_gethostname 87
......
#ifndef __I386_MMAN_H__
#define __I386_MMAN_H__
#define PROT_READ 0x1 /* page can be read */
#define PROT_WRITE 0x2 /* page can be written */
#define PROT_EXEC 0x4 /* page can be executed */
#define PROT_NONE 0x0 /* page can not be accessed */
#define MAP_SHARED 0x01 /* Share changes */
#define MAP_PRIVATE 0x02 /* Changes are private */
#define MAP_TYPE 0x0f /* Mask for type of mapping */
#define MAP_FIXED 0x10 /* Interpret addr exactly */
#define MAP_ANONYMOUS 0x20 /* don't use a file */
#define MAP_GROWSDOWN 0x0100 /* stack-like segment */
#define MAP_DENYWRITE 0x0800 /* ETXTBSY */
#define MAP_EXECUTABLE 0x1000 /* mark it as a executable */
#define MS_ASYNC 1 /* sync memory asynchronously */
#define MS_INVALIDATE 2 /* invalidate the caches */
#define MS_SYNC 4 /* synchronous memory sync */
#endif /* __I386_MMAN_H__ */
#ifndef _ASMi386_SIGCONTEXT_H
#define _ASMi386_SIGCONTEXT_H
struct sigcontext_struct {
unsigned short gs, __gsh;
unsigned short fs, __fsh;
unsigned short es, __esh;
unsigned short ds, __dsh;
unsigned long edi;
unsigned long esi;
unsigned long ebp;
unsigned long esp;
unsigned long ebx;
unsigned long edx;
unsigned long ecx;
unsigned long eax;
unsigned long trapno;
unsigned long err;
unsigned long eip;
unsigned short cs, __csh;
unsigned long eflags;
unsigned long esp_at_signal;
unsigned short ss, __ssh;
unsigned long i387;
unsigned long oldmask;
unsigned long cr2;
};
#endif
......@@ -77,32 +77,7 @@ struct sigaction {
};
#ifdef __KERNEL__
struct sigcontext_struct {
unsigned short gs, __gsh;
unsigned short fs, __fsh;
unsigned short es, __esh;
unsigned short ds, __dsh;
unsigned long edi;
unsigned long esi;
unsigned long ebp;
unsigned long esp;
unsigned long ebx;
unsigned long edx;
unsigned long ecx;
unsigned long eax;
unsigned long trapno;
unsigned long err;
unsigned long eip;
unsigned short cs, __csh;
unsigned long eflags;
unsigned long esp_at_signal;
unsigned short ss, __ssh;
unsigned long i387;
unsigned long oldmask;
unsigned long cr2;
};
#include <asm/sigcontext.h>
#endif
#endif
......@@ -12,7 +12,8 @@
*
* Copyright (C) 1991, 1992 Linus Torvalds
*/
#define __HAVE_ARCH_STRCPY
extern inline char * strcpy(char * dest,const char *src)
{
__asm__ __volatile__(
......@@ -26,6 +27,7 @@ __asm__ __volatile__(
return dest;
}
#define __HAVE_ARCH_STRNCPY
extern inline char * strncpy(char * dest,const char *src,size_t count)
{
__asm__ __volatile__(
......@@ -44,6 +46,7 @@ __asm__ __volatile__(
return dest;
}
#define __HAVE_ARCH_STRCAT
extern inline char * strcat(char * dest,const char * src)
{
__asm__ __volatile__(
......@@ -60,6 +63,7 @@ __asm__ __volatile__(
return dest;
}
#define __HAVE_ARCH_STRNCAT
extern inline char * strncat(char * dest,const char * src,size_t count)
{
__asm__ __volatile__(
......@@ -82,6 +86,7 @@ __asm__ __volatile__(
return dest;
}
#define __HAVE_ARCH_STRCMP
extern inline int strcmp(const char * cs,const char * ct)
{
register int __res;
......@@ -101,6 +106,7 @@ __asm__ __volatile__(
return __res;
}
#define __HAVE_ARCH_STRNCMP
extern inline int strncmp(const char * cs,const char * ct,size_t count)
{
register int __res;
......@@ -122,6 +128,7 @@ __asm__ __volatile__(
return __res;
}
#define __HAVE_ARCH_STRCHR
extern inline char * strchr(const char * s, int c)
{
register char * __res;
......@@ -140,6 +147,7 @@ __asm__ __volatile__(
return __res;
}
#define __HAVE_ARCH_STRRCHR
extern inline char * strrchr(const char * s, int c)
{
register char * __res;
......@@ -156,6 +164,7 @@ __asm__ __volatile__(
return __res;
}
#define __HAVE_ARCH_STRSPN
extern inline size_t strspn(const char * cs, const char * ct)
{
register char * __res;
......@@ -181,6 +190,7 @@ __asm__ __volatile__(
return __res-cs;
}
#define __HAVE_ARCH_STRCSPN
extern inline size_t strcspn(const char * cs, const char * ct)
{
register char * __res;
......@@ -206,6 +216,7 @@ __asm__ __volatile__(
return __res-cs;
}
#define __HAVE_ARCH_STRPBRK
extern inline char * strpbrk(const char * cs,const char * ct)
{
register char * __res;
......@@ -234,6 +245,7 @@ __asm__ __volatile__(
return __res;
}
#define __HAVE_ARCH_STRSTR
extern inline char * strstr(const char * cs,const char * ct)
{
register char * __res;
......@@ -262,6 +274,7 @@ __asm__ __volatile__(
return __res;
}
#define __HAVE_ARCH_STRLEN
extern inline size_t strlen(const char * s)
{
register int __res;
......@@ -277,6 +290,7 @@ return __res;
extern char * ___strtok;
#define __HAVE_ARCH_STRTOK
extern inline char * strtok(char * s,const char * ct)
{
register char * __res;
......@@ -395,11 +409,13 @@ __asm__("cld\n\t" \
#undef COMMON
}
#define __HAVE_ARCH_MEMCPY
#define memcpy(t, f, n) \
(__builtin_constant_p(n) ? \
__constant_memcpy((t),(f),(n)) : \
__memcpy((t),(f),(n)))
#define __HAVE_ARCH_MEMMOVE
extern inline void * memmove(void * dest,const void * src, size_t n)
{
if (dest<src)
......@@ -426,6 +442,7 @@ return dest;
#define memcmp __builtin_memcmp
#define __HAVE_ARCH_MEMCHR
extern inline void * memchr(const void * cs,int c,size_t count)
{
register void * __res;
......@@ -532,6 +549,7 @@ __asm__("cld\n\t" \
__constant_count_memset((s),(c),(count)) : \
__memset_generic((s),(c),(count)))
#define __HAVE_ARCH_MEMSET
#define memset(s, c, count) \
(__builtin_constant_p(c) ? \
__constant_c_x_memset((s),(0x01010101UL*(unsigned char)c),(count)) : \
......@@ -540,6 +558,7 @@ __asm__("cld\n\t" \
/*
* find the first occurrence of byte 'c', or 1 past the area if none
*/
#define __HAVE_ARCH_MEMSCAN
extern inline void * memscan(void * addr, int c, size_t size)
{
if (!size)
......
/* $Id: aztcd.h,v 1.30 1995/07/04 08:28:17 root Exp $
/* $Id: aztcd.h,v 1.40 1995/07/15 20:35:01 root Exp root $
*
* Definitions for a AztechCD268 CD-ROM interface
* Copyright (C) 1994, 1995 Werner Zimmermann
*
......@@ -42,11 +43,17 @@
don't want the auto-eject feature*/
#define AZT_AUTO_EJECT 0
/*Set this to 1, if you want multisession support. Be warned, this function has
not been tested !!!*/
#define AZT_MULTISESSION 0
/*Set this to 1, if you want to use incompatible ioctls for reading in raw and
cooked mode */
#define AZT_PRIVATE_IOCTLS 1
/*---------------------------------------------------------------------------*/
/*------------nothing to be configured below this line-----------------------*/
/* use incompatible ioctls for reading in raw and cooked mode */
#define AZT_PRIVATE_IOCTLS
/* Increase this if you get lots of timeouts; if you get kernel panic, replace
STEN_LOW_WAIT by STEN_LOW in the source code */
......@@ -108,6 +115,10 @@
#define MAX_TRACKS 104
#define CD_DATA 0x01
#define CD_AUDIO 0x02
#define CD_XA (CD_DATA|CD_AUDIO)
struct msf {
unsigned char min;
unsigned char sec;
......@@ -124,6 +135,9 @@ struct azt_DiskInfo {
unsigned char last;
struct msf diskLength;
struct msf firstTrack;
unsigned char multi;
struct msf lastTrack;
unsigned char type;
};
struct azt_Toc {
......
......@@ -3,20 +3,23 @@
*/
/* First, the cm260 stuff */
/* The ports and irq used. If it is not defined, make it variable,
and initialize them at some reasonable value */
/* The ports and irq used. Although CM206_BASE and CM206_IRQ are defined
below, the values are not used unless autoprobing is turned off and
no LILO boot options or module command line options are given. Change
these values to your own as last resort if autoprobing and options
don't work. */
#define CM206_BASE 0x340
#define CM206_IRQ 11
#define r_data_status (CM206_BASE)
#define r_uart_receive (CM206_BASE+0x2)
#define r_fifo_output_buffer (CM206_BASE+0x4)
#define r_line_status (CM206_BASE+0x6)
#define r_data_control (CM206_BASE+0x8)
#define r_uart_transmit (CM206_BASE+0xa)
#define r_test_clock (CM206_BASE+0xc)
#define r_test_control (CM206_BASE+0xe)
#define r_data_status (cm206_base)
#define r_uart_receive (cm206_base+0x2)
#define r_fifo_output_buffer (cm206_base+0x4)
#define r_line_status (cm206_base+0x6)
#define r_data_control (cm206_base+0x8)
#define r_uart_transmit (cm206_base+0xa)
#define r_test_clock (cm206_base+0xc)
#define r_test_control (cm206_base+0xe)
/* the data_status flags */
#define ds_ram_size 0x4000
......@@ -123,4 +126,3 @@
#define CM206CTL_GET_STAT 0x2000
#define CM206CTL_GET_LAST_STAT 0x2001
#define CM206_RESET_DRIVE 0x2002 /* use with care */
......@@ -193,7 +193,7 @@ struct ppp {
struct tty_struct *tty; /* ptr to TTY structure */
struct device *dev; /* easy for intr handling */
struct slcompress *slcomp; /* for header compression */
__u32 last_xmit; /* time of last transmission */
unsigned long last_xmit; /* time of last transmission */
/* These are pointers to the malloc()ed frame buffers.
These buffers are used while processing a packet. If a packet
......
#ifndef _LINUX_MMAN_H
#define _LINUX_MMAN_H
#define PROT_READ 0x1 /* page can be read */
#define PROT_WRITE 0x2 /* page can be written */
#define PROT_EXEC 0x4 /* page can be executed */
#define PROT_NONE 0x0 /* page can not be accessed */
#define MAP_SHARED 1 /* Share changes */
#define MAP_PRIVATE 2 /* Changes are private */
#define MAP_TYPE 0xf /* Mask for type of mapping */
#define MAP_FIXED 0x10 /* Interpret addr exactly */
#define MAP_ANONYMOUS 0x20 /* don't use a file */
#define MAP_GROWSDOWN 0x0100 /* stack-like segment */
#define MAP_DENYWRITE 0x0800 /* ETXTBSY */
#define MAP_EXECUTABLE 0x1000 /* mark it as a executable */
#define MS_ASYNC 1 /* sync memory asynchronously */
#define MS_INVALIDATE 2 /* invalidate the caches */
#define MS_SYNC 4 /* synchronous memory sync */
#include <asm/mman.h>
#endif /* _LINUX_MMAN_H */
This diff is collapsed.
#include <linux/modules/ksyms.ver>
......@@ -28,9 +28,9 @@
#include <linux/if_tr.h>
#ifdef __KERNEL__
extern int tr_header(unsigned char *buff, struct device *dev,
extern int tr_header(struct sk_buff *skb, struct device *dev,
unsigned short type, void *daddr,
void *saddr, unsigned len, struct sk_buff *skb);
void *saddr, unsigned len);
extern int tr_rebuild_header(void *buff, struct device *dev,
unsigned long raddr, struct sk_buff *skb);
extern unsigned short tr_type_trans(struct sk_buff *skb, struct device *dev);
......
......@@ -192,6 +192,8 @@ int do_fork(unsigned long clone_flags, unsigned long usp, struct pt_regs *regs)
p->state = TASK_UNINTERRUPTIBLE;
p->flags &= ~(PF_PTRACED|PF_TRACESYS);
p->pid = last_pid;
p->next_run = NULL;
p->prev_run = NULL;
p->p_pptr = p->p_opptr = current;
p->p_cptr = NULL;
p->signal = 0;
......
......@@ -386,9 +386,6 @@ struct symbol_table symbol_table = {
X(dispatch_scsi_info_ptr),
X(generic_proc_info),
X(scsi_devices),
X(free_pages),
X(print_msg),
X(print_status),
X(gendisk_head), /* Needed for sd.c */
X(resetup_one_dev), /* Needed for sd.c */
#else
......
......@@ -92,32 +92,77 @@ struct task_struct * task[NR_TASKS] = {&init_task, };
struct kernel_stat kstat = { 0 };
static inline void add_to_runqueue(struct task_struct * p)
{
#if 1 /* sanity tests */
if (p->next_run || p->prev_run) {
printk("task already on run-queue\n");
return;
}
#endif
if (p->counter > current->counter + 3)
need_resched = 1;
nr_running++;
(p->next_run = init_task.next_run)->prev_run = p;
p->prev_run = &init_task;
init_task.next_run = p;
}
static inline void del_from_runqueue(struct task_struct * p)
{
struct task_struct *next = p->next_run;
struct task_struct *prev = p->prev_run;
#if 1 /* sanity tests */
if (!next || !prev) {
printk("task not on run-queue\n");
return;
}
#endif
if (p == &init_task) {
printk("idle task may not sleep\n");
return;
}
nr_running--;
next->prev_run = prev;
prev->next_run = next;
p->next_run = NULL;
p->prev_run = NULL;
}
/*
* Wake up a process. Put it on the run-queue if it's not
* already there. The "current" process is always on the
* run-queue, and as such you're allowed to do the simpler
* run-queue (except when the actual re-schedule is in
* progress), and as such you're allowed to do the simpler
* "current->state = TASK_RUNNING" to mark yourself runnable
* without the overhead of this.
*
* (actually, the run-queue isn't implemented yet, so this
* function is mostly a dummy one)
*/
inline void wake_up_process(struct task_struct * p)
{
long oldstate;
unsigned long flags;
oldstate = xchg(&p->state, TASK_RUNNING);
/* already on run-queue? */
if (oldstate == TASK_RUNNING || p == current)
return;
if (p->counter > current->counter + 3)
need_resched = 1;
save_flags(flags);
cli();
p->state = TASK_RUNNING;
if (!p->next_run)
add_to_runqueue(p);
restore_flags(flags);
}
static void process_timeout(unsigned long __data)
{
struct task_struct * p = (struct task_struct *) __data;
p->timeout = 0;
wake_up_process(p);
}
/*
* 'schedule()' is the scheduler function. It's a very simple and nice
* scheduler: it's not perfect, but certainly works for most things.
* The one thing you might take a look at is the signal-handler code here.
*
* The goto is "interesting".
*
* NOTE!! Task 0 is the 'idle' task, which gets called when no other
* tasks can run. It can not be killed, and it cannot sleep. The 'state'
......@@ -128,6 +173,7 @@ asmlinkage void schedule(void)
int c;
struct task_struct * p;
struct task_struct * next;
unsigned long timeout = 0;
/* check alarm, wake up any interruptible tasks that have got a signal */
......@@ -137,31 +183,39 @@ asmlinkage void schedule(void)
}
run_task_queue(&tq_scheduler);
if (current->state == TASK_INTERRUPTIBLE) {
if (current->signal & ~current->blocked)
current->state = TASK_RUNNING;
}
need_resched = 0;
nr_running = 0;
cli();
switch (current->state) {
case TASK_INTERRUPTIBLE:
if (current->signal & ~current->blocked)
goto makerunnable;
timeout = current->timeout;
if (timeout && (timeout <= jiffies)) {
current->timeout = 0;
timeout = 0;
makerunnable:
current->state = TASK_RUNNING;
break;
}
default:
del_from_runqueue(current);
case TASK_RUNNING:
}
p = init_task.next_run;
sti();
/*
* Note! there may appear new tasks on the run-queue during this, as
* interrupts are enabled. However, they will be put on front of the
* list, so our list starting at "p" is essentially fixed.
*/
/* this is the scheduler proper: */
c = -1000;
next = &init_task;
for_each_task(p) {
switch (p->state) {
case TASK_INTERRUPTIBLE:
if (!p->timeout)
continue;
if (p->timeout > jiffies)
continue;
p->timeout = 0;
p->state = TASK_RUNNING;
/* fall through */
case TASK_RUNNING:
nr_running++;
if (p->counter > c)
c = p->counter, next = p;
}
while (p != &init_task) {
if (p->counter > c)
c = p->counter, next = p;
p = p->next_run;
}
/* if all runnable processes have "counter == 0", re-calculate counters */
......@@ -169,10 +223,21 @@ asmlinkage void schedule(void)
for_each_task(p)
p->counter = (p->counter >> 1) + p->priority;
}
if (current == next)
return;
kstat.context_swtch++;
switch_to(next);
if (current != next) {
struct timer_list timer;
kstat.context_swtch++;
if (timeout) {
init_timer(&timer);
timer.expires = timeout - jiffies;
timer.data = (unsigned long) current;
timer.function = process_timeout;
add_timer(&timer);
}
switch_to(next);
if (timeout)
del_timer(&timer);
}
}
asmlinkage int sys_pause(void)
......
......@@ -12,9 +12,11 @@
*/
#include <linux/types.h>
#include <linux/string.h>
char * ___strtok = NULL;
#ifndef __HAVE_ARCH_STRCPY
char * strcpy(char * dest,const char *src)
{
char *tmp = dest;
......@@ -23,7 +25,9 @@ char * strcpy(char * dest,const char *src)
/* nothing */;
return tmp;
}
#endif
#ifndef __HAVE_ARCH_STRNCPY
char * strncpy(char * dest,const char *src,size_t count)
{
char *tmp = dest;
......@@ -33,7 +37,9 @@ char * strncpy(char * dest,const char *src,size_t count)
return tmp;
}
#endif
#ifndef __HAVE_ARCH_STRCAT
char * strcat(char * dest, const char * src)
{
char *tmp = dest;
......@@ -45,7 +51,9 @@ char * strcat(char * dest, const char * src)
return tmp;
}
#endif
#ifndef __HAVE_ARCH_STRNCAT
char * strncat(char *dest, const char *src, size_t count)
{
char *tmp = dest;
......@@ -61,7 +69,9 @@ char * strncat(char *dest, const char *src, size_t count)
return tmp;
}
#endif
#ifndef __HAVE_ARCH_STRCMP
int strcmp(const char * cs,const char * ct)
{
register signed char __res;
......@@ -73,7 +83,9 @@ int strcmp(const char * cs,const char * ct)
return __res;
}
#endif
#ifndef __HAVE_ARCH_STRNCMP
int strncmp(const char * cs,const char * ct,size_t count)
{
register signed char __res = 0;
......@@ -86,7 +98,9 @@ int strncmp(const char * cs,const char * ct,size_t count)
return __res;
}
#endif
#ifndef __HAVE_ARCH_STRCHR
char * strchr(const char * s,char c)
{
for(; *s != c; ++s)
......@@ -94,7 +108,9 @@ char * strchr(const char * s,char c)
return NULL;
return (char *) s;
}
#endif
#ifndef __HAVE_ARCH_STRLEN
size_t strlen(const char * s)
{
const char *sc;
......@@ -103,7 +119,9 @@ size_t strlen(const char * s)
/* nothing */;
return sc - s;
}
#endif
#ifndef __HAVE_ARCH_STRNLEN
size_t strnlen(const char * s, size_t count)
{
const char *sc;
......@@ -112,7 +130,9 @@ size_t strnlen(const char * s, size_t count)
/* nothing */;
return sc - s;
}
#endif
#ifndef __HAVE_ARCH_STRSPN
size_t strspn(const char *s, const char *accept)
{
const char *p;
......@@ -131,7 +151,9 @@ size_t strspn(const char *s, const char *accept)
return count;
}
#endif
#ifndef __HAVE_ARCH_STRPBRK
char * strpbrk(const char * cs,const char * ct)
{
const char *sc1,*sc2;
......@@ -144,7 +166,9 @@ char * strpbrk(const char * cs,const char * ct)
}
return NULL;
}
#endif
#ifndef __HAVE_ARCH_STRTOK
char * strtok(char * s,const char * ct)
{
char *sbegin, *send;
......@@ -164,7 +188,9 @@ char * strtok(char * s,const char * ct)
___strtok = send;
return (sbegin);
}
#endif
#ifndef __HAVE_ARCH_MEMSET
void * memset(void * s,char c,size_t count)
{
char *xs = (char *) s;
......@@ -174,7 +200,9 @@ void * memset(void * s,char c,size_t count)
return s;
}
#endif
#ifndef __HAVE_ARCH_BCOPY
char * bcopy(const char * src, char * dest, int count)
{
char *tmp = dest;
......@@ -184,7 +212,9 @@ char * bcopy(const char * src, char * dest, int count)
return dest;
}
#endif
#ifndef __HAVE_ARCH_MEMCPY
void * memcpy(void * dest,const void *src,size_t count)
{
char *tmp = (char *) dest, *s = (char *) src;
......@@ -194,7 +224,9 @@ void * memcpy(void * dest,const void *src,size_t count)
return dest;
}
#endif
#ifndef __HAVE_ARCH_MEMMOVE
void * memmove(void * dest,const void *src,size_t count)
{
char *tmp, *s;
......@@ -214,7 +246,9 @@ void * memmove(void * dest,const void *src,size_t count)
return dest;
}
#endif
#ifndef __HAVE_ARCH_MEMCMP
int memcmp(const void * cs,const void * ct,size_t count)
{
const unsigned char *su1, *su2;
......@@ -225,10 +259,12 @@ int memcmp(const void * cs,const void * ct,size_t count)
break;
return res;
}
#endif
/*
* find the first occurrence of byte 'c', or 1 past the area if none
*/
#ifndef __HAVE_ARCH_MEMSCAN
void * memscan(void * addr, unsigned char c, size_t size)
{
unsigned char * p = (unsigned char *) addr;
......@@ -241,7 +277,9 @@ void * memscan(void * addr, unsigned char c, size_t size)
}
return (void *) p;
}
#endif
#ifndef __HAVE_ARCH_STRSTR
char * strstr(const char * s1,const char * s2)
{
int l1, l2;
......@@ -258,3 +296,4 @@ char * strstr(const char * s1,const char * s2)
}
return NULL;
}
#endif
......@@ -38,11 +38,12 @@ rif_cache rif_table[RIF_TABLE_SIZE]={ NULL, };
#define RIF_CHECK_INTERVAL 60*HZ
static struct timer_list rif_timer={ NULL,NULL,RIF_CHECK_INTERVAL,0L,rif_check_expire };
int tr_header(unsigned char *buff, struct device *dev, unsigned short type,
void *daddr, void *saddr, unsigned len, struct sk_buff *skb) {
int tr_header(struct sk_buff *skb, struct device *dev, unsigned short type,
void *daddr, void *saddr, unsigned len)
{
struct trh_hdr *trh=(struct trh_hdr *)skb_push(skb,dev->hard_header_len);
struct trllc *trllc=(struct trllc *)(buff+sizeof(struct trh_hdr));
struct trllc *trllc=(struct trllc *)(trh+1);
trh->ac=AC;
trh->fc=LLC_FRAME;
......@@ -92,6 +93,8 @@ unsigned short tr_type_trans(struct sk_buff *skb, struct device *dev) {
struct trh_hdr *trh=(struct trh_hdr *)skb->data;
struct trllc *trllc=(struct trllc *)(skb->data+sizeof(struct trh_hdr));
skb->mac.raw = skb->data;
skb_pull(skb,dev->hard_header_len);
if(trh->saddr[0] & TR_RII)
......
......@@ -172,6 +172,7 @@ void dev_remove_pack(struct packet_type *pt)
return;
}
}
printk("dev_remove_pack: %p not found.\n", pt);
}
/*****************************************************************************************
......
......@@ -85,6 +85,8 @@
* Dave Bonn,Alan Cox : Faster IP forwarding whenever possible.
* Alan Cox : Memory leaks, tramples, misc debugging.
* Alan Cox : Fixed multicast (by popular demand 8))
* Alan Cox : Fixed forwarding (by even more popular demand 8))
* Alan Cox : Fixed SNMP statistics [I think]
*
*
*
......@@ -153,7 +155,7 @@ extern void sort_send(struct sock *sk);
#ifdef CONFIG_IP_FORWARD
struct ip_mib ip_statistics={1,64,}; /* Forwarding=Yes, Default TTL=64 */
#else
struct ip_mib ip_statistics={0,64,}; /* Forwarding=No, Default TTL=64 */
struct ip_mib ip_statistics={2,64,}; /* Forwarding=No, Default TTL=64 */
#endif
/*
......@@ -1139,7 +1141,7 @@ int ip_forward(struct sk_buff *skb, struct device *dev, int is_frag, unsigned lo
*/
dev2 = rt->rt_dev;
/*
* In IP you never have to forward a frame on the interface that it
* arrived upon. We now generate an ICMP HOST REDIRECT giving the route
......@@ -1165,33 +1167,35 @@ int ip_forward(struct sk_buff *skb, struct device *dev, int is_frag, unsigned lo
if (!(is_frag&4) && fw_res==2)
ip_fw_masquerade(&skb, dev2);
#endif
IS_SKB(skb);
if(skb_headroom(skb)<dev2->hard_header_len)
{
skb2 = alloc_skb(dev2->hard_header_len + skb->len + 15, GFP_ATOMIC);
else skb2=skb;
IS_SKB(skb2);
/*
* This is rare and since IP is tolerant of network failures
* quite harmless.
*/
/*
* This is rare and since IP is tolerant of network failures
* quite harmless.
*/
if (skb2 == NULL)
{
NETDEBUG(printk("\nIP: No memory available for IP forward\n"));
return -1;
}
if (skb2 == NULL)
{
NETDEBUG(printk("\nIP: No memory available for IP forward\n"));
return -1;
}
/*
* Add the physical headers.
*/
/* Now build the MAC header. */
(void) ip_send(skb2, raddr, skb->len, dev2, dev2->pa_addr);
ip_send(skb2,raddr,skb->len,dev2,dev2->pa_addr);
/*
* We have to copy the bytes over as the new header wouldn't fit
* the old buffer. This should be very rare.
*/
if(skb2!=skb)
{
/*
* We have to copy the bytes over as the new header wouldn't fit
* the old buffer. This should be very rare.
*/
ptr = skb_put(skb2,skb->len);
skb2->free = 1;
skb2->h.raw = ptr;
......@@ -1201,9 +1205,23 @@ int ip_forward(struct sk_buff *skb, struct device *dev, int is_frag, unsigned lo
*/
memcpy(ptr, skb->h.raw, skb->len);
}
else
{
/*
* Build a new MAC header.
*/
ip_statistics.IpForwDatagrams++;
skb2 = skb;
skb2->dev=dev2;
skb->arp=1;
skb->raddr=raddr;
if(dev2->hard_header)
{
if(dev2->hard_header(skb, dev2, ETH_P_IP, NULL, NULL, skb->len)<0)
skb->arp=0;
}
ip_statistics.IpForwDatagrams++;
}
/*
* See if it needs fragmenting. Note in ip_rcv we tagged
* the fragment type. This must be right so that
......@@ -2347,6 +2365,7 @@ int ip_build_xmit(struct sock *sk,
struct iphdr *iph;
int local=0;
struct device *dev;
int nfrags=0;
ip_statistics.IpOutRequests++;
......@@ -2437,7 +2456,10 @@ int ip_build_xmit(struct sock *sk,
int error;
struct sk_buff *skb=sock_alloc_send_skb(sk, length+20+15+dev->hard_header_len,0,&error);
if(skb==NULL)
{
ip_statistics.IpOutDiscards++;
return error;
}
skb->dev=dev;
skb->free=1;
skb->when=jiffies;
......@@ -2555,8 +2577,13 @@ int ip_build_xmit(struct sock *sk,
skb = sock_alloc_send_skb(sk, fraglen+15, 0, &error);
if (skb == NULL)
{
ip_statistics.IpOutDiscards++;
if(nfrags>1)
ip_statistics.IpFragCreates++;
return(error);
}
/*
* Fill in the control structures
*/
......@@ -2689,6 +2716,9 @@ int ip_build_xmit(struct sock *sk,
kfree_skb(skb, FREE_READ);
}
#endif
nfrags++;
/*
* BSD loops broadcasts
*/
......@@ -2715,12 +2745,15 @@ int ip_build_xmit(struct sock *sk,
*/
ip_statistics.IpOutDiscards++;
if(nfrags>1)
ip_statistics.IpFragCreates+=nfrags;
kfree_skb(skb, FREE_WRITE);
return(0); /* lose rest of fragments */
}
}
while (offset >= 0);
if(nfrags>1)
ip_statistics.IpFragCreates+=nfrags;
return(0);
}
......
......@@ -1483,7 +1483,7 @@ int ip_msqhst_procinfo(char *buffer, char **start, off_t offset, int length)
int timer_active = del_timer(&ms->timer);
if (!timer_active)
ms->timer.expires = 0;
len+=sprintf(buffer+len,"%s %08lX:%04X %08lX:%04X %04X %08lX %5d %lu\n",
len+=sprintf(buffer+len,"%s %08lX:%04X %08lX:%04X %04X %08X %5d %lu\n",
strProt[ms->protocol==IPPROTO_TCP],
ntohl(ms->src),ntohs(ms->sport),
ntohl(ms->dst),ntohs(ms->dport),
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment