Commit b872e060 authored by Linus Torvalds's avatar Linus Torvalds

Import 1.3.11

parent bb9c5bf1
...@@ -688,7 +688,9 @@ S: United Kingdom ...@@ -688,7 +688,9 @@ S: United Kingdom
N: Michael Neuffer N: Michael Neuffer
E: neuffer@goofy.zdv.uni-mainz.de E: neuffer@goofy.zdv.uni-mainz.de
D: developer and maintainer of the eata_dma SCSI driver D: Developer and maintainer of the EATA-DMA SCSI driver
D: Co-developer EATA-PIO SCSI driver
D: Assorted other snippets
S: Zum Schiersteiner Grund 2 S: Zum Schiersteiner Grund 2
S: 55127 Mainz S: 55127 Mainz
S: Germany S: Germany
......
VERSION = 1 VERSION = 1
PATCHLEVEL = 3 PATCHLEVEL = 3
SUBLEVEL = 10 SUBLEVEL = 11
ARCH = i386 ARCH = i386
......
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
#define halt .long PAL_halt #define halt .long PAL_halt
#define rti .long PAL_rti #define rti .long PAL_rti
#define NR_SYSCALLS 310 #define NR_SYSCALLS 320
#define osf_vfork sys_fork #define osf_vfork sys_fork
/* /*
...@@ -565,3 +565,6 @@ sys_call_table: ...@@ -565,3 +565,6 @@ sys_call_table:
/* linux-specific system calls start at 300 */ /* linux-specific system calls start at 300 */
/*300*/ .quad sys_bdflush, sys_sethae, sys_mount, sys_adjtimex, sys_swapoff /*300*/ .quad sys_bdflush, sys_sethae, sys_mount, sys_adjtimex, sys_swapoff
.quad sys_getdents, sys_create_module, sys_init_module, sys_delete_module, sys_get_kernel_syms .quad sys_getdents, sys_create_module, sys_init_module, sys_delete_module, sys_get_kernel_syms
.quad sys_syslog, do_entSys, do_entSys, do_entSys, do_entSys
.quad do_entSys, do_entSys, do_entSys, do_entSys, do_entSys
...@@ -693,7 +693,7 @@ asmlinkage long sys_ptrace(long request, long pid, long addr, long data, int a4, ...@@ -693,7 +693,7 @@ asmlinkage long sys_ptrace(long request, long pid, long addr, long data, int a4,
else else
child->flags &= ~PF_TRACESYS; child->flags &= ~PF_TRACESYS;
child->exit_code = data; child->exit_code = data;
child->state = TASK_RUNNING; wake_up_process(child);
ptrace_cancel_bpt(child); ptrace_cancel_bpt(child);
set_success(&regs,data); set_success(&regs,data);
return 0; return 0;
...@@ -705,7 +705,7 @@ asmlinkage long sys_ptrace(long request, long pid, long addr, long data, int a4, ...@@ -705,7 +705,7 @@ asmlinkage long sys_ptrace(long request, long pid, long addr, long data, int a4,
* exit. * exit.
*/ */
case PTRACE_KILL: { case PTRACE_KILL: {
child->state = TASK_RUNNING; wake_up_process(child);
child->exit_code = SIGKILL; child->exit_code = SIGKILL;
ptrace_cancel_bpt(child); ptrace_cancel_bpt(child);
return 0; return 0;
...@@ -721,7 +721,7 @@ asmlinkage long sys_ptrace(long request, long pid, long addr, long data, int a4, ...@@ -721,7 +721,7 @@ asmlinkage long sys_ptrace(long request, long pid, long addr, long data, int a4,
return res; return res;
} }
child->flags &= ~PF_TRACESYS; child->flags &= ~PF_TRACESYS;
child->state = TASK_RUNNING; wake_up_process(child);
child->exit_code = data; child->exit_code = data;
/* give it a chance to run. */ /* give it a chance to run. */
return 0; return 0;
...@@ -733,7 +733,7 @@ asmlinkage long sys_ptrace(long request, long pid, long addr, long data, int a4, ...@@ -733,7 +733,7 @@ asmlinkage long sys_ptrace(long request, long pid, long addr, long data, int a4,
return -EIO; return -EIO;
} }
child->flags &= ~(PF_PTRACED|PF_TRACESYS); child->flags &= ~(PF_PTRACED|PF_TRACESYS);
child->state = TASK_RUNNING; wake_up_process(child);
child->exit_code = data; child->exit_code = data;
REMOVE_LINKS(child); REMOVE_LINKS(child);
child->p_pptr = child->p_opptr; child->p_pptr = child->p_opptr;
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
$(CC) $(CFLAGS) -c $< $(CC) $(CFLAGS) -c $<
OBJS = __divqu.o __remqu.o __divlu.o __remlu.o memset.o memcpy.o io.o \ OBJS = __divqu.o __remqu.o __divlu.o __remlu.o memset.o memcpy.o io.o \
checksum.o checksum.o strlen.o
lib.a: $(OBJS) lib.a: $(OBJS)
$(AR) rcs lib.a $(OBJS) $(AR) rcs lib.a $(OBJS)
......
/*
* strlen.S (c) 1995 David Mosberger (davidm@cs.arizona.edu)
*
* Finds length of a 0-terminated string. Optimized for the
* Alpha architecture:
*
* - memory accessed as aligned quadwords only
* - uses bcmpge to compare 8 bytes in parallel
* - does binary search to find 0 byte in last
* quadword (HAKMEM needed 12 instructions to
* do this instead of the 9 instructions that
* binary search needs).
*/
.set noreorder
.set noat
.align 3
.globl strlen
.ent strlen
strlen:
ldq_u $1, 0($16) # load first quadword ($16 may be misaligned)
lda $2, -1($31)
insqh $2, $16, $2
andnot $16, 7, $0
or $2, $1, $1
cmpbge $31, $1, $2 # $2 <- bitmask: bit i == 1 <==> i-th byte == 0
bne $2, found
loop: ldq $1, 8($0)
addq $0, 8, $0 # addr += 8
nop # helps dual issue last two insns
cmpbge $31, $1, $2
beq $2, loop
found: blbs $2, done # make aligned case fast
negq $2, $3
and $2, $3, $2
and $2, 0x0f, $1
addq $0, 4, $3
cmoveq $1, $3, $0
and $2, 0x33, $1
addq $0, 2, $3
cmoveq $1, $3, $0
and $2, 0x55, $1
addq $0, 1, $3
cmoveq $1, $3, $0
done: subq $0, $16, $0
ret $31, ($26)
.end strlen
...@@ -466,7 +466,7 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data) ...@@ -466,7 +466,7 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
else else
child->flags &= ~PF_TRACESYS; child->flags &= ~PF_TRACESYS;
child->exit_code = data; child->exit_code = data;
child->state = TASK_RUNNING; wake_up_process(child);
/* make sure the single step bit is not set. */ /* make sure the single step bit is not set. */
tmp = get_stack_long(child, sizeof(long)*EFL-MAGICNUMBER) & ~TRAP_FLAG; tmp = get_stack_long(child, sizeof(long)*EFL-MAGICNUMBER) & ~TRAP_FLAG;
put_stack_long(child, sizeof(long)*EFL-MAGICNUMBER,tmp); put_stack_long(child, sizeof(long)*EFL-MAGICNUMBER,tmp);
...@@ -481,7 +481,7 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data) ...@@ -481,7 +481,7 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
case PTRACE_KILL: { case PTRACE_KILL: {
long tmp; long tmp;
child->state = TASK_RUNNING; wake_up_process(child);
child->exit_code = SIGKILL; child->exit_code = SIGKILL;
/* make sure the single step bit is not set. */ /* make sure the single step bit is not set. */
tmp = get_stack_long(child, sizeof(long)*EFL-MAGICNUMBER) & ~TRAP_FLAG; tmp = get_stack_long(child, sizeof(long)*EFL-MAGICNUMBER) & ~TRAP_FLAG;
...@@ -497,7 +497,7 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data) ...@@ -497,7 +497,7 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
child->flags &= ~PF_TRACESYS; child->flags &= ~PF_TRACESYS;
tmp = get_stack_long(child, sizeof(long)*EFL-MAGICNUMBER) | TRAP_FLAG; tmp = get_stack_long(child, sizeof(long)*EFL-MAGICNUMBER) | TRAP_FLAG;
put_stack_long(child, sizeof(long)*EFL-MAGICNUMBER,tmp); put_stack_long(child, sizeof(long)*EFL-MAGICNUMBER,tmp);
child->state = TASK_RUNNING; wake_up_process(child);
child->exit_code = data; child->exit_code = data;
/* give it a chance to run. */ /* give it a chance to run. */
return 0; return 0;
...@@ -509,7 +509,7 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data) ...@@ -509,7 +509,7 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
if ((unsigned long) data > NSIG) if ((unsigned long) data > NSIG)
return -EIO; return -EIO;
child->flags &= ~(PF_PTRACED|PF_TRACESYS); child->flags &= ~(PF_PTRACED|PF_TRACESYS);
child->state = TASK_RUNNING; wake_up_process(child);
child->exit_code = data; child->exit_code = data;
REMOVE_LINKS(child); REMOVE_LINKS(child);
child->p_pptr = child->p_opptr; child->p_pptr = child->p_opptr;
......
...@@ -448,7 +448,7 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data) ...@@ -448,7 +448,7 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
else else
child->flags &= ~PF_TRACESYS; child->flags &= ~PF_TRACESYS;
child->exit_code = data; child->exit_code = data;
child->state = TASK_RUNNING; wake_up_process(child);
/* make sure the single step bit is not set. */ /* make sure the single step bit is not set. */
tmp = get_stack_long(child, sizeof(long)*EFL-MAGICNUMBER) & ~TRAP_FLAG; tmp = get_stack_long(child, sizeof(long)*EFL-MAGICNUMBER) & ~TRAP_FLAG;
put_stack_long(child, sizeof(long)*EFL-MAGICNUMBER,tmp); put_stack_long(child, sizeof(long)*EFL-MAGICNUMBER,tmp);
...@@ -463,7 +463,7 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data) ...@@ -463,7 +463,7 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
case PTRACE_KILL: { case PTRACE_KILL: {
long tmp; long tmp;
child->state = TASK_RUNNING; wake_up_process(child);
child->exit_code = SIGKILL; child->exit_code = SIGKILL;
/* make sure the single step bit is not set. */ /* make sure the single step bit is not set. */
tmp = get_stack_long(child, sizeof(long)*EFL-MAGICNUMBER) & ~TRAP_FLAG; tmp = get_stack_long(child, sizeof(long)*EFL-MAGICNUMBER) & ~TRAP_FLAG;
...@@ -479,7 +479,7 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data) ...@@ -479,7 +479,7 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
child->flags &= ~PF_TRACESYS; child->flags &= ~PF_TRACESYS;
tmp = get_stack_long(child, sizeof(long)*EFL-MAGICNUMBER) | TRAP_FLAG; tmp = get_stack_long(child, sizeof(long)*EFL-MAGICNUMBER) | TRAP_FLAG;
put_stack_long(child, sizeof(long)*EFL-MAGICNUMBER,tmp); put_stack_long(child, sizeof(long)*EFL-MAGICNUMBER,tmp);
child->state = TASK_RUNNING; wake_up_process(child);
child->exit_code = data; child->exit_code = data;
/* give it a chance to run. */ /* give it a chance to run. */
return 0; return 0;
...@@ -491,7 +491,7 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data) ...@@ -491,7 +491,7 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
if ((unsigned long) data > NSIG) if ((unsigned long) data > NSIG)
return -EIO; return -EIO;
child->flags &= ~(PF_PTRACED|PF_TRACESYS); child->flags &= ~(PF_PTRACED|PF_TRACESYS);
child->state = TASK_RUNNING; wake_up_process(child);
child->exit_code = data; child->exit_code = data;
REMOVE_LINKS(child); REMOVE_LINKS(child);
child->p_pptr = child->p_opptr; child->p_pptr = child->p_opptr;
......
...@@ -15,7 +15,6 @@ ...@@ -15,7 +15,6 @@
$(CC) $(CFLAGS) -c $< $(CC) $(CFLAGS) -c $<
SUBDIRS = block char net #streams SUBDIRS = block char net #streams
ALL_SUBDIRS = block char net scsi #streams
ifdef CONFIG_PCI ifdef CONFIG_PCI
SUBDIRS := $(SUBDIRS) pci SUBDIRS := $(SUBDIRS) pci
...@@ -35,9 +34,9 @@ driversubdirs: dummy ...@@ -35,9 +34,9 @@ driversubdirs: dummy
set -e; for i in $(SUBDIRS); do $(MAKE) -C $$i; done set -e; for i in $(SUBDIRS); do $(MAKE) -C $$i; done
modules: dummy modules: dummy
set -e; for i in $(ALL_SUBDIRS); do $(MAKE) -C $$i modules; done set -e; for i in $(SUBDIRS); do $(MAKE) -C $$i modules; done
dep: dep:
set -e; for i in $(ALL_SUBDIRS); do $(MAKE) -C $$i dep; done set -e; for i in $(SUBDIRS); do $(MAKE) -C $$i dep; done
include $(TOPDIR)/Rules.make include $(TOPDIR)/Rules.make
-- README.sjcd
80% of the work takes 20% of the time, 80% of the work takes 20% of the time,
20% of the work takes 80% of the time... 20% of the work takes 80% of the time...
(Murphy law) (Murphy law)
...@@ -5,21 +6,36 @@ ...@@ -5,21 +6,36 @@
Once started, training can not be stopped... Once started, training can not be stopped...
(StarWars) (StarWars)
This is the README for the sjcd cdrom driver, version 1.3.
This file is meant as a tips & tricks edge for the usage of the SANYO CDR-H94A This file is meant as a tips & tricks edge for the usage of the SANYO CDR-H94A
cdrom drive. It will grow as the questions arise. ;-) cdrom drive. It will grow as the questions arise. ;-)
Since the drive often comes with an ISP16 soundcard, which can be used
as cdrom interface, this is also the place for ISP16 related issues.
The driver should work with any SoundBlaster/Panasonic style CDROM interface, The driver should work with any SoundBlaster/Panasonic style CDROM interface,
including the "soft configurable" MediaMagic sound card. including the "soft configurable" MediaMagic sound card.
To make this sound card (and others like "Mozart") working, it has to get To make this sound card (and others like "Mozart") working, it has to get
"configured" by software. "configured" by software.
So, you should boot DOS once (and by this, run the "configuration driver") The suggestion to configure the ISP16 soundcard by booting DOS and
a warm reboot to boot Linux somehow doesn't work, at least not
on Eric's machine (IPC P90), with the version of the ISP16
card he has (there appear to be at least two versions: Eric's card with
no jumpered IDE support and Vadim's version with a jumper to enable
IDE support).
Therefore detection and configuration of the ISP16 interfaces is included
in the driver.
If we should support any other interfaces (which cannot be configured
through DOS) or if there are any more ISP16 types, please let us
know (maarel@marin.nl) and we'll see.
Otherwise, you should boot DOS once (and by this, run the "configuration driver")
and then switch to Linux by use of CTL-ALT-DEL. Each use of the RESET and then switch to Linux by use of CTL-ALT-DEL. Each use of the RESET
button or the power switch makes this procedure necessary again. button or the power switch makes this procedure necessary again.
If no ISP16 is detected, there's no harm done; a card configured trough DOS
may still work as expected.
Vadim has implemented a Linux "configuration driver" to set up the ISP16 configuration routines reside at Vadim's server
registers of the MediaMagic (ISP-16) sound card. These routines have to get
integrated into the related CDROM and sound drivers directly at a later
time. Currently, they reside at Vadim's server
rbrf.msk.su:/linux/mediamagic/ rbrf.msk.su:/linux/mediamagic/
and at Eberhard's mirror and at Eberhard's mirror
ftp.gwdg.de:/pub/linux/cdrom/drivers/sanyo/ ftp.gwdg.de:/pub/linux/cdrom/drivers/sanyo/
...@@ -29,6 +45,26 @@ Leo Spiekman's configuration routines for the ISP-16 card can get found at ...@@ -29,6 +45,26 @@ Leo Spiekman's configuration routines for the ISP-16 card can get found at
and at Eberhard's mirror and at Eberhard's mirror
ftp.gwdg.de:/pub/linux/cdrom/drivers/optics/ ftp.gwdg.de:/pub/linux/cdrom/drivers/optics/
Eric van der Maarel's routines are included in sjcd.c.
This, and any related stuff may be found by anonymous ftp at
ftp.gwdg.de:/pub/linux/cdrom/drivers/sanyo/
The device major for sjcd is 18, and minor is 0. Create a block special
file in your /dev directory (e.g., /dev/sjcd) with these numbers.
(For those who don't know, being root and the following should do the trick:
mknod -m 644 /dev/sjcd b 18 0
and mount the cdrom by /dev/sjcd).
The default configuration parameters are:
base address 0x340
irq 10
no dma
As of version 1.2, setting base address, irq and dma at boot time is supported
through the use of command line options: type at the "boot:" prompt:
linux sjcd=<base address>,<irq>,<dma>
(where your kernel is assumed to be called by saying "linux" to
the boot manager).
If something is wrong, e-mail to vadim@rbrf.msk.su If something is wrong, e-mail to vadim@rbrf.msk.su
or vadim@ipsun.ras.ru or vadim@ipsun.ras.ru
or model@cecmow.enet.dec.com or model@cecmow.enet.dec.com
......
...@@ -1358,7 +1358,7 @@ static int ide_open(struct inode * inode, struct file * filp) ...@@ -1358,7 +1358,7 @@ static int ide_open(struct inode * inode, struct file * filp)
sleep_on(&dev->wqueue); sleep_on(&dev->wqueue);
dev->usage++; dev->usage++;
restore_flags(flags); restore_flags(flags);
if (dev->id->config & (1<<7)) /* for removeable disks */ if (dev->id && (dev->id->config & (1<<7))) /* for removeable disks */
check_disk_change(inode->i_rdev); check_disk_change(inode->i_rdev);
#ifdef CONFIG_BLK_DEV_IDECD #ifdef CONFIG_BLK_DEV_IDECD
if (dev->type == cdrom) if (dev->type == cdrom)
...@@ -1654,7 +1654,7 @@ static int ide_check_media_change (dev_t full_dev) ...@@ -1654,7 +1654,7 @@ static int ide_check_media_change (dev_t full_dev)
if (dev->type == cdrom) if (dev->type == cdrom)
return cdrom_check_media_change (dev); return cdrom_check_media_change (dev);
#endif /* CONFIG_BLK_DEV_IDECD */ #endif /* CONFIG_BLK_DEV_IDECD */
if (dev->id->config & (1<<7)) /* for removeable disks */ if (dev->id && (dev->id->config & (1<<7))) /* for removeable disks */
return 1; /* always assume it was changed */ return 1; /* always assume it was changed */
return 0; return 0;
} }
......
/* /* -- sjcd.c
* Sanyo CD-ROM device driver implementation.
* *
* Sanyo CD-ROM device driver implementation, Version 1.3
* Copyright (C) 1995 Vadim V. Model * Copyright (C) 1995 Vadim V. Model
* *
* model@cecmow.enet.dec.com * model@cecmow.enet.dec.com
* vadim@rbrf.msk.su * vadim@rbrf.msk.su
* vadim@ipsun.ras.ru * vadim@ipsun.ras.ru
* *
* ISP16 detection and configuration.
* Copyright (C) 1995 Eric van der Maarel (maarel@marin.nl)
*
*
* This driver is based on pre-works by Eberhard Moenkeberg (emoenke@gwdg.de); * This driver is based on pre-works by Eberhard Moenkeberg (emoenke@gwdg.de);
* it was developed under use of mcd.c from Martin Harriss, with help of * it was developed under use of mcd.c from Martin Harriss, with help of
* E. van der Maarel (maarel@marin.nl). * Eric van der Maarel (maarel@marin.nl).
*
* ISP16 detection and configuration by Eric van der Maarel (maarel@marin.nl),
* with some data communicated by Vadim V. Model (vadim@rbrf.msk.su)
* and Leo Spiekman (spiekman@et.tudelft.nl)
*
* *
* It is planned to include these routines into sbpcd.c later - to make * It is planned to include these routines into sbpcd.c later - to make
* a "mixed use" on one cable possible for all kinds of drives which use * a "mixed use" on one cable possible for all kinds of drives which use
...@@ -29,6 +38,15 @@ ...@@ -29,6 +38,15 @@
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* History:
* 1.1 First public release with kernel version 1.3.7.
* Written by Vadim Model.
* 1.2 Added detection and configuration of cdrom interface
* on ISP16 soundcard.
* Allow for command line options: sjcd=<io_base>,<irq>,<dma>
* 1.3 Some minor changes to README.sjcd.
*
*/ */
#include <linux/errno.h> #include <linux/errno.h>
...@@ -49,11 +67,60 @@ ...@@ -49,11 +67,60 @@
#define MAJOR_NR SANYO_CDROM_MAJOR #define MAJOR_NR SANYO_CDROM_MAJOR
#include "blk.h" #include "blk.h"
#ifdef CONFIG_ISP_16
#include <linux/isp16.h>
#endif
#include <linux/sjcd.h> #include <linux/sjcd.h>
/* Some (Media)Magic */
/* define types of drive the interface on an ISP16 card may be looking at */
#define ISP16_DRIVE_X 0x00
#define ISP16_SONY 0x02
#define ISP16_PANASONIC0 0x02
#define ISP16_SANYO0 0x02
#define ISP16_MITSUMI 0x04
#define ISP16_PANASONIC1 0x06
#define ISP16_SANYO1 0x06
#define ISP16_DRIVE_NOT_USED 0x08 /* not used */
#define ISP16_DRIVE_SET_MASK 0xF1 /* don't change 0-bit or 4-7-bits*/
/* ...for port */
#define ISP16_DRIVE_SET_PORT 0xF8D
/* set io parameters */
#define ISP16_BASE_340 0x00
#define ISP16_BASE_330 0x40
#define ISP16_BASE_360 0x80
#define ISP16_BASE_320 0xC0
#define ISP16_IRQ_X 0x00
#define ISP16_IRQ_5 0x04 /* shouldn't be used due to soundcard conflicts */
#define ISP16_IRQ_7 0x08 /* shouldn't be used due to soundcard conflicts */
#define ISP16_IRQ_3 0x0C
#define ISP16_IRQ_9 0x10
#define ISP16_IRQ_10 0x14
#define ISP16_IRQ_11 0x18
#define ISP16_DMA_X 0x03
#define ISP16_DMA_3 0x00
#define ISP16_DMA_5 0x00
#define ISP16_DMA_6 0x01
#define ISP16_DMA_7 0x02
#define ISP16_IO_SET_MASK 0x20 /* don't change 5-bit */
/* ...for port */
#define ISP16_IO_SET_PORT 0xF8E
/* enable the drive */
#define ISP16_NO_IDE__ENABLE_CDROM_PORT 0xF90 /* ISP16 without IDE interface */
#define ISP16_IDE__ENABLE_CDROM_PORT 0xF91 /* ISP16 with IDE interface */
#define ISP16_ENABLE_CDROM 0x80 /* seven bit */
/* the magic stuff */
#define ISP16_CTRL_PORT 0xF8F
#define ISP16_NO_IDE__CTRL 0xE2 /* ISP16 without IDE interface */
#define ISP16_IDE__CTRL 0xE3 /* ISP16 with IDE interface */
static short isp16_detect(void);
static short isp16_no_ide__detect(void);
static short isp16_with_ide__detect(void);
static short isp16_config( int base, u_char drive_type, int irq, int dma );
static short isp16_type; /* dependent on type of interface card */
static u_char isp16_ctrl;
static u_short isp16_enable_cdrom_port;
static int sjcd_present = 0; static int sjcd_present = 0;
#define SJCD_BUF_SIZ 32 /* cdr-h94a has internal 64K buffer */ #define SJCD_BUF_SIZ 32 /* cdr-h94a has internal 64K buffer */
...@@ -86,6 +153,7 @@ static struct sjcd_play_msf sjcd_playing; ...@@ -86,6 +153,7 @@ static struct sjcd_play_msf sjcd_playing;
static short sjcd_port = SJCD_BASE_ADDR; static short sjcd_port = SJCD_BASE_ADDR;
static int sjcd_irq = SJCD_INTR_NR; static int sjcd_irq = SJCD_INTR_NR;
static int sjcd_dma = SJCD_DMA;
static struct wait_queue *sjcd_waitq = NULL; static struct wait_queue *sjcd_waitq = NULL;
...@@ -131,10 +199,17 @@ static struct timer_list sjcd_delay_timer = { NULL, NULL, 0, 0, NULL }; ...@@ -131,10 +199,17 @@ static struct timer_list sjcd_delay_timer = { NULL, NULL, 0, 0, NULL };
#define CLEAR_TIMER del_timer( &sjcd_delay_timer ) #define CLEAR_TIMER del_timer( &sjcd_delay_timer )
/* /*
* Set up device. Not yet implemented. * Set up device, i.e., use command line data to set
* base address, irq and dma.
*/ */
void sjcd_setup( char *str, int *ints ){ void sjcd_setup( char *str, int *ints ){
printk( "Sanyo CDR-H94A device driver setup is called (%s).\n", str );
if (ints[0] > 0)
sjcd_port = ints[1];
if (ints[0] > 1)
sjcd_irq = ints[2];
if (ints[0] > 2)
sjcd_dma = ints[3];
} }
/* /*
...@@ -1266,7 +1341,7 @@ static struct file_operations sjcd_fops = { ...@@ -1266,7 +1341,7 @@ static struct file_operations sjcd_fops = {
}; };
/* /*
* Following staff is intended for initialization of the cdrom. It * Following stuff is intended for initialization of the cdrom. It
* first looks for presence of device. If the device is present, it * first looks for presence of device. If the device is present, it
* will be reset. Then read the version of the drive and load status. * will be reset. Then read the version of the drive and load status.
*/ */
...@@ -1281,22 +1356,21 @@ static struct { ...@@ -1281,22 +1356,21 @@ static struct {
unsigned long sjcd_init( unsigned long mem_start, unsigned long mem_end ){ unsigned long sjcd_init( unsigned long mem_start, unsigned long mem_end ){
int i; int i;
if( sjcd_port != 0x340 || sjcd_irq != 0x0A /* 10 */ ){ if ( (isp16_type=isp16_detect()) < 0 )
printk( "skip sjcd_init\n" ); printk( "No ISP16 cdrom interface found.\n" );
return( mem_start ); else {
} u_char expected_drive;
#ifdef CONFIG_ISP_16 printk( "ISP16 cdrom interface (%s optional IDE) detected.\n",
/* (isp16_type==2)?"with":"without" );
* Initialize the CDROM interface of the card.
*/
isp16_cdi_setup( ISP_CDROM_SANYO, ISP_CDROM_IRQ_10,
ISP_CDROM_DMA_DISABLED, ISP_CDROM_PORT_340 );
#endif
#if 0 expected_drive = (isp16_type?ISP16_SANYO1:ISP16_SANYO0);
printk( "sjcd=0x%x,%d: ", sjcd_port, sjcd_irq );
#endif if ( isp16_config( sjcd_port, expected_drive, sjcd_irq, sjcd_dma ) < 0 ) {
printk( "ISP16 cdrom interface has not been properly configured.\n" );
return(mem_start);
}
}
if( register_blkdev( MAJOR_NR, "sjcd", &sjcd_fops ) != 0 ){ if( register_blkdev( MAJOR_NR, "sjcd", &sjcd_fops ) != 0 ){
printk( "Unable to get major %d for Sanyo CD-ROM\n", MAJOR_NR ); printk( "Unable to get major %d for Sanyo CD-ROM\n", MAJOR_NR );
...@@ -1356,3 +1430,189 @@ unsigned long sjcd_init( unsigned long mem_start, unsigned long mem_end ){ ...@@ -1356,3 +1430,189 @@ unsigned long sjcd_init( unsigned long mem_start, unsigned long mem_end ){
return( mem_start ); return( mem_start );
} }
/*
* -- ISP16 detection and configuration
*
* Copyright (c) 1995, Eric van der Maarel <maarel@marin.nl>
*
* Version 0.5
*
* Detect cdrom interface on ISP16 soundcard.
* Configure cdrom interface.
*
* Algorithm for the card with no IDE support option taken
* from the CDSETUP.SYS driver for MSDOS,
* by OPTi Computers, version 2.03.
* Algorithm for the IDE supporting ISP16 as communicated
* to me by Vadim Model and Leo Spiekman.
*
* Use, modifification or redistribution of this software is
* allowed under the terms of the GPL.
*
*/
#define ISP16_IN(p) (outb(isp16_ctrl,ISP16_CTRL_PORT), inb(p))
#define ISP16_OUT(p,b) (outb(isp16_ctrl,ISP16_CTRL_PORT), outb(b,p))
static short
isp16_detect(void)
{
if ( !( isp16_with_ide__detect() < 0 ) )
return(2);
else
return( isp16_no_ide__detect() );
}
static short
isp16_no_ide__detect(void)
{
u_char ctrl;
u_char enable_cdrom;
u_char io;
short i = -1;
isp16_ctrl = ISP16_NO_IDE__CTRL;
isp16_enable_cdrom_port = ISP16_NO_IDE__ENABLE_CDROM_PORT;
/* read' and write' are a special read and write, respectively */
/* read' ISP16_CTRL_PORT, clear last two bits and write' back the result */
ctrl = ISP16_IN( ISP16_CTRL_PORT ) & 0xFC;
ISP16_OUT( ISP16_CTRL_PORT, ctrl );
/* read' 3,4 and 5-bit from the cdrom enable port */
enable_cdrom = ISP16_IN( ISP16_NO_IDE__ENABLE_CDROM_PORT ) & 0x38;
if ( !(enable_cdrom & 0x20) ) { /* 5-bit not set */
/* read' last 2 bits of ISP16_IO_SET_PORT */
io = ISP16_IN( ISP16_IO_SET_PORT ) & 0x03;
if ( ((io&0x01)<<1) == (io&0x02) ) { /* bits are the same */
if ( io == 0 ) { /* ...the same and 0 */
i = 0;
enable_cdrom |= 0x20;
}
else { /* ...the same and 1 */ /* my card, first time 'round */
i = 1;
enable_cdrom |= 0x28;
}
ISP16_OUT( ISP16_NO_IDE__ENABLE_CDROM_PORT, enable_cdrom );
}
else { /* bits are not the same */
ISP16_OUT( ISP16_CTRL_PORT, ctrl );
return(i); /* -> not detected: possibly incorrect conclusion */
}
}
else if ( enable_cdrom == 0x20 )
i = 0;
else if ( enable_cdrom == 0x28 ) /* my card, already initialised */
i = 1;
ISP16_OUT( ISP16_CTRL_PORT, ctrl );
return(i);
}
static short
isp16_with_ide__detect(void)
{
u_char ctrl;
u_char tmp;
isp16_ctrl = ISP16_IDE__CTRL;
isp16_enable_cdrom_port = ISP16_IDE__ENABLE_CDROM_PORT;
/* read' and write' are a special read and write, respectively */
/* read' ISP16_CTRL_PORT and save */
ctrl = ISP16_IN( ISP16_CTRL_PORT );
/* write' zero to the ctrl port and get response */
ISP16_OUT( ISP16_CTRL_PORT, 0 );
tmp = ISP16_IN( ISP16_CTRL_PORT );
if ( tmp != 2 ) /* isp16 with ide option not detected */
return(-1);
/* restore ctrl port value */
ISP16_OUT( ISP16_CTRL_PORT, ctrl );
return(2);
}
static short
isp16_config( int base, u_char drive_type, int irq, int dma )
{
u_char base_code;
u_char irq_code;
u_char dma_code;
u_char i;
if ( (drive_type == ISP16_MITSUMI) && (dma != 0) )
printk( "Mitsumi cdrom drive has no dma support.\n" );
switch (base) {
case 0x340: base_code = ISP16_BASE_340; break;
case 0x330: base_code = ISP16_BASE_330; break;
case 0x360: base_code = ISP16_BASE_360; break;
case 0x320: base_code = ISP16_BASE_320; break;
default:
printk( "Base address 0x%03X not supported by cdrom interface on ISP16.\n", base );
return(-1);
}
switch (irq) {
case 0: irq_code = ISP16_IRQ_X; break; /* disable irq */
case 5: irq_code = ISP16_IRQ_5;
printk( "Irq 5 shouldn't be used by cdrom interface on ISP16,"
" due to possible conflicts with the soundcard.\n");
break;
case 7: irq_code = ISP16_IRQ_7;
printk( "Irq 7 shouldn't be used by cdrom interface on ISP16,"
" due to possible conflicts with the soundcard.\n");
break;
case 3: irq_code = ISP16_IRQ_3; break;
case 9: irq_code = ISP16_IRQ_9; break;
case 10: irq_code = ISP16_IRQ_10; break;
case 11: irq_code = ISP16_IRQ_11; break;
default:
printk( "Irq %d not supported by cdrom interface on ISP16.\n", irq );
return(-1);
}
switch (dma) {
case 0: dma_code = ISP16_DMA_X; break; /* disable dma */
case 1: printk( "Dma 1 cannot be used by cdrom interface on ISP16,"
" due to conflict with the soundcard.\n");
return(-1); break;
case 3: dma_code = ISP16_DMA_3; break;
case 5: dma_code = ISP16_DMA_5; break;
case 6: dma_code = ISP16_DMA_6; break;
case 7: dma_code = ISP16_DMA_7; break;
default:
printk( "Dma %d not supported by cdrom interface on ISP16.\n", dma );
return(-1);
}
if ( drive_type != ISP16_SONY && drive_type != ISP16_PANASONIC0 &&
drive_type != ISP16_PANASONIC1 && drive_type != ISP16_SANYO0 &&
drive_type != ISP16_SANYO1 && drive_type != ISP16_MITSUMI &&
drive_type != ISP16_DRIVE_X ) {
printk( "Drive type (code 0x%02X) not supported by cdrom"
" interface on ISP16.\n", drive_type );
return(-1);
}
/* set type of interface */
i = ISP16_IN(ISP16_DRIVE_SET_PORT) & ISP16_DRIVE_SET_MASK; /* clear some bits */
ISP16_OUT( ISP16_DRIVE_SET_PORT, i|drive_type );
/* enable cdrom on interface with ide support */
if ( isp16_type > 1 )
ISP16_OUT( isp16_enable_cdrom_port, ISP16_ENABLE_CDROM );
/* set base address, irq and dma */
i = ISP16_IN(ISP16_IO_SET_PORT) & ISP16_IO_SET_MASK; /* keep some bits */
ISP16_OUT( ISP16_IO_SET_PORT, i|base_code|irq_code|dma_code );
return(0);
}
#include <linux/autoconf.h> /* fastest method */ #include <linux/autoconf.h> /* fastest method */
#ifdef CONFIG_SCC #ifdef CONFIG_SCC
#define RCS_ID "$Id: scc.c,v 1.17 1995/03/15 23:28:12 JReuter Exp JReuter $"
#define BANNER "Z8530 SCC driver v1.8.dl1bke (beta) by dl1bke\n" #define BANNER "Z8530 SCC driver v1.8.17test.17.7.95 PE1AYX (c)\n"
/* ******************************************************************** */ /* ******************************************************************** */
/* * SCC.C - Linux driver for Z8530 based HDLC cards for AX.25 * */ /* * SCC.C - Linux driver for Z8530 based HDLC cards for AX.25 * */
...@@ -11,34 +10,45 @@ ...@@ -11,34 +10,45 @@
/* ******************************************************************** /* ********************************************************************
(c) 1995 by Joerg Reuter DL1BKE (c) Hans Alblas PE1AYX 1993,1994,1995
Released for GNU
portions (c) 1995 by Joerg Reuter DL1BKE
(c) 1993 Guido ten Dolle PE1NNZ
portions (c) 1994 Hans Alblas PE1AYX
and (c) 1993 Guido ten Dolle PE1NNZ
for the complete copyright notice see >> Copying.Z8530DRV <<
******************************************************************** */ ******************************************************************** */
/* /*
940913 - started to rewrite the drive
950131 - changed copyright notice to GPL without limitations. 931100 - started with the projekt pe1ayx
9406?? - KISS-parameter setting and BayCom USCC support dl1bke
940613 - fixed memory leak ,main memory fragmentation problem,
speeded up the interupt routines ,has now its own
memory buffer pool and source cleanup. pe1ayx
940620 - bug fixed in line disipline change ,local ringbuf
reorganisation ,and some little bugfixes.
940715 - first release to the public (scc15b.tgz) pe1ayx
950228 - (hopefully) fixed the reason for kernel panics in 950228 - (hopefully) fixed the reason for kernel panics in
chk_rcv_queue() [stupid error] chk_rcv_queue() [stupid error] dl1bke
950304 - fixed underrun/zcount handling 950229 - buffer timeout for vergotten buffer :-( pe1ayx
950305 - the driver registers port addresses now 950304 - fixed underrun/zcount handling dl1bke
950314 - fixed underrun interrupt handling again 950305 - the driver registers port addresses now dl1bke
950314 - fixed underrun interrupt handling again dl1bke
950514 - fixed slip tty wakeup (it wil now work again with kernel ax25)pe1ayx
950703 - rewrote the 8530 init/reset routines pe1ayx
950712 - rewrote the RXirq + buffering routines pe1ayx
950716 - It can now handle ax25 rx frame info > 256
O - rewrite TX + buffering (there is a little mem leak ,but
wil not be dangerous since my buffer timeout routine
wil put back vergotten buffers in the queue pe1ayx
O - change the tty i/o so that the tty wakeup is handled properly
pe1ayx
Thanks to: Thanks to:
DL1BKE Joerg - for some good ideas
PE1CHL Rob - for a lot of good ideas from his SCC driver for DOS PE1CHL Rob - for a lot of good ideas from his SCC driver for DOS
PE1NNZ Guido - for his port of the original driver to Linux PE1NNZ Guido - for his port of the original driver to Linux
KA9Q Phil - from whom we stole the mbuf-structure
PA3AYX Hans - who rewrote the memory management and some minor,
but nevertheless useful changes
DL8MBT Flori - for support
DG0FT Rene - for the BayCom USCC support
PA3AOU Harry - for ESCC testing, information supply and support PA3AOU Harry - for ESCC testing, information supply and support
PE1KOX Rob, DG1RTF Thomas, ON5QK Roland, PE1KOX Rob, DG1RTF Thomas, ON5QK Roland,
...@@ -46,12 +56,6 @@ ...@@ -46,12 +56,6 @@
and all who sent me bug reports and ideas... and all who sent me bug reports and ideas...
NB -- if you find errors, change something, please let me know
first before you distribute it... And please don't touch
the version number. Just replace my callsign in
"v1.8.dl1bke" with your own. Just to avoid confusion...
Jrg Reuter DL1BKE
*/ */
...@@ -110,8 +114,6 @@ static void scc_stop(struct tty_struct *tty); ...@@ -110,8 +114,6 @@ static void scc_stop(struct tty_struct *tty);
static void z8530_init(void); static void z8530_init(void);
static void scc_change_speed(struct scc_channel *scc); static void scc_change_speed(struct scc_channel *scc);
static void kiss_encode(struct scc_channel *scc);
static void init_channel(struct scc_channel *scc); static void init_channel(struct scc_channel *scc);
static void scc_key_trx (struct scc_channel *scc, char tx); static void scc_key_trx (struct scc_channel *scc, char tx);
static void scc_txint(register struct scc_channel *scc); static void scc_txint(register struct scc_channel *scc);
...@@ -124,6 +126,14 @@ static void scc_init_timer(struct scc_channel *scc); ...@@ -124,6 +126,14 @@ static void scc_init_timer(struct scc_channel *scc);
/* from serial.c */ /* from serial.c */
#ifndef MIN
#define MIN(a,b) ((a) < (b) ? (a) : (b))
#endif
static unsigned char *tmp_buf = 0;
static struct semaphore tmp_buf_sem = MUTEX;
static unsigned int start_controle;
static int baud_table[] = { static int baud_table[] = {
0, 50, 75, 110, 134, 150, 200, 300, 600, 1200, 1800, 2400, 4800, 0, 50, 75, 110, 134, 150, 200, 300, 600, 1200, 1800, 2400, 4800,
9600, 19200, 38400, 57600, 115200, 0 }; 9600, 19200, 38400, 57600, 115200, 0 };
...@@ -142,6 +152,8 @@ unsigned char Driver_Initialized = 0; ...@@ -142,6 +152,8 @@ unsigned char Driver_Initialized = 0;
static struct sccbuf *sccfreelist[MAX_IBUFS] = {0}; static struct sccbuf *sccfreelist[MAX_IBUFS] = {0};
static int allocated_ibufs = 0; static int allocated_ibufs = 0;
#define SERIAL_TYPE_NORMAL 1
/* ******************************************************************** */ /* ******************************************************************** */
/* * Port Access Functions * */ /* * Port Access Functions * */
...@@ -197,10 +209,6 @@ cl(register struct scc_channel *scc, register unsigned char reg, register unsign ...@@ -197,10 +209,6 @@ cl(register struct scc_channel *scc, register unsigned char reg, register unsign
/* * Memory Buffer Management */ /* * Memory Buffer Management */
/* ******************************************************************** */ /* ******************************************************************** */
/* mbuf concept lent from KA9Q. Tnx PE1AYX for the buffer pool concept */
/* (sorry, do you have any better ideas?) */
/* allocate memory for the interrupt buffer pool */ /* allocate memory for the interrupt buffer pool */
void scc_alloc_buffer_pool(void) void scc_alloc_buffer_pool(void)
...@@ -209,6 +217,8 @@ void scc_alloc_buffer_pool(void) ...@@ -209,6 +217,8 @@ void scc_alloc_buffer_pool(void)
struct sccbuf *sccb; struct sccbuf *sccb;
struct mbuf *bp; struct mbuf *bp;
start_controle = 0;
for (i = 0 ; i < MAX_IBUFS ; i++) for (i = 0 ; i < MAX_IBUFS ; i++)
{ {
sccb = (struct sccbuf *)kmalloc(sizeof(struct sccbuf), GFP_ATOMIC); sccb = (struct sccbuf *)kmalloc(sizeof(struct sccbuf), GFP_ATOMIC);
...@@ -286,6 +296,7 @@ scc_get_buffer(char type) ...@@ -286,6 +296,7 @@ scc_get_buffer(char type)
sccfreelist[i]->bp->refcnt = 1; sccfreelist[i]->bp->refcnt = 1;
sccfreelist[i]->bp->cnt = 0; sccfreelist[i]->bp->cnt = 0;
sccfreelist[i]->bp->in_use = 0; sccfreelist[i]->bp->in_use = 0;
sccfreelist[i]->bp->time_out = CURRENT_TIME + 300;
restore_flags(flags); restore_flags(flags);
return sccfreelist[i]->bp; return sccfreelist[i]->bp;
...@@ -314,6 +325,32 @@ scc_return_buffer(register struct mbuf *bp, char type) ...@@ -314,6 +325,32 @@ scc_return_buffer(register struct mbuf *bp, char type)
save_flags(flags); cli(); save_flags(flags); cli();
bpnext = bp->next; bpnext = bp->next;
/*=========================================================================*/
/*== THIS IS A LITTLE ROUTINE TO FIX THE TX MEM LEAK ==*/
/*== UNTIL I HAVE REWRITE THE TX ROUTINES ==*/
/*== PE1AYX@PI8HRL.AMPR.ORG ==*/
/*=========================================================================*/
start_controle++;
if(start_controle > 100){
if(bp->type == BT_TRANSMIT){
start_controle = 0;
for(i = 0 ; i < allocated_ibufs ; i++)
{
if(sccfreelist[i]->inuse == 1)
if(sccfreelist[i]->bp->type == BT_TRANSMIT)
if(sccfreelist[i]->bp->time_out < CURRENT_TIME)
{
sccfreelist[i]->bp->cnt = 0;
sccfreelist[i]->bp->refcnt = 0;
sccfreelist[i]->inuse = 0;
}
}
}
}
/*=========================================================================*/
/*== END OF THAT SILLY STUPID ROUTINE ==*/
/*=========================================================================*/
if (bp->dup) if (bp->dup)
{ {
...@@ -481,13 +518,13 @@ scc_isr(int irq, struct pt_regs *regs) ...@@ -481,13 +518,13 @@ scc_isr(int irq, struct pt_regs *regs)
if (Vector_Latch) if (Vector_Latch)
{ {
while(1) /* forever...? */ while(1)
{ {
Outb(Vector_Latch, 0); /* Generate INTACK */ Outb(Vector_Latch, 0); /* Generate INTACK */
/* Read the vector */ /* Read the vector */
if((vector=Inb(Vector_Latch)) >= 16 * Nchips) break; if((vector=Inb(Vector_Latch)) >= 16 * Nchips)
/* ...not forever! */ break;
/* Extract channel number and status from vector. */ /* Extract channel number and status from vector. */
/* Isolate channel nummer */ /* Isolate channel nummer */
...@@ -618,21 +655,6 @@ scc_txint(register struct scc_channel *scc) ...@@ -618,21 +655,6 @@ scc_txint(register struct scc_channel *scc)
/* Throw away received mbuf(s) when an error occurred */ /* Throw away received mbuf(s) when an error occurred */
static inline void
scc_toss_buffer(register struct scc_channel *scc)
{
register struct mbuf *bp;
if((bp = scc->rbp) != NULLBUF)
{
scc_free_chain(bp->next, BT_RECEIVE);
bp->next = NULLBUF;
scc->rbp1 = bp; /* Don't throw this one away */
bp->cnt = 0; /* Simply rewind it */
bp->in_use = 0;
}
}
static inline void static inline void
flush_FIFO(register struct scc_channel *scc) flush_FIFO(register struct scc_channel *scc)
{ {
...@@ -641,17 +663,13 @@ flush_FIFO(register struct scc_channel *scc) ...@@ -641,17 +663,13 @@ flush_FIFO(register struct scc_channel *scc)
for (k=0; k<3; k++) for (k=0; k<3; k++)
Inb(scc->data); Inb(scc->data);
if(scc->rbp != NULLBUF) /* did we receive something? */ if(scc->rxbufcnt > 0)
{ {
if(scc->rbp->next != NULLBUF || scc->rbp->cnt > 0) scc->stat.rxerrs++;
scc->stat.rxerrs++; /* then count it as an error */ scc->rxbufcnt = 0; /* throw away frame */
scc_toss_buffer(scc); /* throw away buffer */
} }
} }
/* External/Status interrupt handler */ /* External/Status interrupt handler */
static void static void
scc_exint(register struct scc_channel *scc) scc_exint(register struct scc_channel *scc)
...@@ -729,7 +747,7 @@ scc_exint(register struct scc_channel *scc) ...@@ -729,7 +747,7 @@ scc_exint(register struct scc_channel *scc)
static void static void
scc_rxint(register struct scc_channel *scc) scc_rxint(register struct scc_channel *scc)
{ {
register struct mbuf *bp; unsigned char ch;
scc->stat.rxints++; scc->stat.rxints++;
...@@ -740,32 +758,36 @@ scc_rxint(register struct scc_channel *scc) ...@@ -740,32 +758,36 @@ scc_rxint(register struct scc_channel *scc)
return; return;
} }
if ((bp = scc->rbp1) == NULLBUF || bp->cnt >= bp->size) if (scc->rxbufcnt > 2044) /* no buffer available? */
{ /* no buffer available or buffer full */
if (scc->rbp == NULLBUF)
{
if ((bp = scc_get_buffer(BT_RECEIVE)) != NULLBUF)
scc->rbp = scc->rbp1 = bp;
}
else if ((bp = scc_get_buffer(BT_RECEIVE)))
{
scc_append_to_chain(&scc->rbp, bp);
scc->rbp1 = bp;
}
if (bp == NULLBUF) /* no buffer available? */
{ {
Inb(scc->data); /* discard character */ Inb(scc->data); /* discard character */
or(scc,R3,ENT_HM); /* enter hunt mode */ or(scc,R3,ENT_HM); /* enter hunt mode */
scc_toss_buffer(scc); /* throw away buffers */ scc->rxbufcnt = 0; /* throw away frame */
scc->stat.nospace++; /* and count this error */ scc->stat.nospace++; /* and count this error */
return; return;
} }
if(scc->rxbufcnt == 0) /* make begin of kissframe */
{
scc->rxbuf[scc->rxbufcnt++] = FEND;
if (scc->kiss.not_slip)
scc->rxbuf[scc->rxbufcnt++] = 0;
}
switch( ch = Inb(scc->data) )
{
case FEND:
scc->rxbuf[scc->rxbufcnt++] = FESC;
scc->rxbuf[scc->rxbufcnt++] = TFEND;
break;
case FESC:
scc->rxbuf[scc->rxbufcnt++] = FESC;
scc->rxbuf[scc->rxbufcnt++] = TFESC;
break;
default:
scc->rxbuf[scc->rxbufcnt++] = ch;
} }
/* now, we have a buffer. read character and store it */
bp->data[bp->cnt++] = Inb(scc->data);
} }
...@@ -774,42 +796,82 @@ static void ...@@ -774,42 +796,82 @@ static void
scc_spint(register struct scc_channel *scc) scc_spint(register struct scc_channel *scc)
{ {
register unsigned char status; register unsigned char status;
register struct mbuf *bp; int i;
unsigned char *cp;
char *fp;
int count;
scc->stat.spints++; scc->stat.spints++;
status = InReg(scc->ctrl,R1); /* read receiver status */ status = InReg(scc->ctrl,R1); /* read Special Receive Condition status */
Inb(scc->data); /* throw away Rx byte */ Inb(scc->data); /* read byte */
if(status & Rx_OVR) /* receiver overrun */ if(status & Rx_OVR) /* RX_OVerRrun? */
{ {
scc->stat.rx_over++; /* count them */ scc->stat.rx_over++;
or(scc,R3,ENT_HM); /* enter hunt mode for next flag */ or(scc,R3,ENT_HM); /* enter hunt mode */
scc_toss_buffer(scc); /* rewind the buffer and toss */ scc->rxbufcnt = 0; /* rewind the buffer */
} }
if(status & END_FR && scc->rbp != NULLBUF) /* end of frame */ if(status & END_FR && scc->rxbufcnt != 0) /* END of FRame */
{ {
/* CRC okay, frame ends on 8 bit boundary and received something ? */ if (!(status & CRC_ERR) && (status & 0xe) == RES8 && scc->rxbufcnt > 0)
if (!(status & CRC_ERR) && (status & 0xe) == RES8 && scc->rbp->cnt)
{ {
/* ignore last received byte (first of the CRC bytes) */ scc->rxbufcnt--; /*strip the CRC */
scc->rxbuf[scc->rxbufcnt++] = FEND;
for (bp = scc->rbp; bp->next != NULLBUF; bp = bp->next) ; for(i = 0 ; i < scc->rxbufcnt ; i++)
bp->cnt--; /* last byte is first CRC byte */ {
if((scc->tty->flip.count + 1) < TTY_FLIPBUF_SIZE)
tty_insert_flip_char(scc->tty, scc->rxbuf[i], 0);
else {
if (scc->tty->flip.buf_num) {
cp = scc->tty->flip.char_buf + TTY_FLIPBUF_SIZE;
fp = scc->tty->flip.flag_buf + TTY_FLIPBUF_SIZE;
scc->tty->flip.buf_num = 0;
scc->tty->flip.char_buf_ptr = scc->tty->flip.char_buf;
scc->tty->flip.flag_buf_ptr = scc->tty->flip.flag_buf;
} else {
cp = scc->tty->flip.char_buf;
fp = scc->tty->flip.flag_buf;
scc->tty->flip.buf_num = 1;
scc->tty->flip.char_buf_ptr = scc->tty->flip.char_buf + TTY_FLIPBUF_SIZE;
scc->tty->flip.flag_buf_ptr = scc->tty->flip.flag_buf + TTY_FLIPBUF_SIZE;
}
count = scc->tty->flip.count;
scc->tty->flip.count = 0;
scc->tty->ldisc.receive_buf(scc->tty, cp, fp, count);
tty_insert_flip_char(scc->tty, scc->rxbuf[i], 0);
}
}
scc_enqueue(&scc->rcvq,scc->rbp); if (scc->tty->flip.buf_num) {
scc->rbp = scc->rbp1 = NULLBUF; cp = scc->tty->flip.char_buf + TTY_FLIPBUF_SIZE;
fp = scc->tty->flip.flag_buf + TTY_FLIPBUF_SIZE;
scc->tty->flip.buf_num = 0;
scc->tty->flip.char_buf_ptr = scc->tty->flip.char_buf;
scc->tty->flip.flag_buf_ptr = scc->tty->flip.flag_buf;
} else {
cp = scc->tty->flip.char_buf;
fp = scc->tty->flip.flag_buf;
scc->tty->flip.buf_num = 1;
scc->tty->flip.char_buf_ptr = scc->tty->flip.char_buf + TTY_FLIPBUF_SIZE;
scc->tty->flip.flag_buf_ptr = scc->tty->flip.flag_buf + TTY_FLIPBUF_SIZE;
}
count = scc->tty->flip.count;
scc->tty->flip.count = 0;
scc->tty->ldisc.receive_buf(scc->tty, cp, fp, count);
scc->stat.rxframes++; scc->stat.rxframes++;
scc->stat.rx_queued++;
} else { /* a bad frame */ scc->rxbufcnt = 0;
scc_toss_buffer(scc); /* throw away frame */
} else {
scc->rxbufcnt = 0; /* frame is not good */
scc->stat.rxerrs++; scc->stat.rxerrs++;
} }
} }
Outb(scc->ctrl,ERR_RES); Outb(scc->ctrl,ERR_RES);
} }
...@@ -934,7 +996,7 @@ init_channel(register struct scc_channel *scc) ...@@ -934,7 +996,7 @@ init_channel(register struct scc_channel *scc)
Outb(scc->ctrl,RES_EXT_INT); /* must be done twice */ Outb(scc->ctrl,RES_EXT_INT); /* must be done twice */
scc->status = InReg(scc->ctrl,R0); /* read initial status */ scc->status = InReg(scc->ctrl,R0); /* read initial status */
scc->rxbufcnt = 0;
or(scc,R1,INT_ALL_Rx|TxINT_ENAB|EXT_INT_ENAB); /* enable interrupts */ or(scc,R1,INT_ALL_Rx|TxINT_ENAB|EXT_INT_ENAB); /* enable interrupts */
or(scc,R9,MIE); /* master interrupt enable */ or(scc,R9,MIE); /* master interrupt enable */
...@@ -1142,35 +1204,6 @@ static inline void maxk_idle_timeout(register struct scc_channel *scc) ...@@ -1142,35 +1204,6 @@ static inline void maxk_idle_timeout(register struct scc_channel *scc)
scc->t_tail = scc->kiss.tailtime; scc->t_tail = scc->kiss.tailtime;
} }
static inline void check_rcv_queue(register struct scc_channel *scc)
{
register struct mbuf *bp;
if (scc->stat.rx_queued > QUEUE_THRES)
{
if (scc->rcvq == NULLBUF)
{
printk("z8530drv: Warning - scc->stat.rx_queued shows overflow"
" (%d) but queue is empty\n", scc->stat.rx_queued);
scc->stat.rx_queued = 0; /* correct it */
scc->stat.nospace = 12345; /* draw attention to it */
return;
}
bp = scc->rcvq->anext; /* don't use the one we currently use */
while (bp && (scc->stat.rx_queued > QUEUE_HYST))
{
bp = scc_free_chain(bp, BT_RECEIVE);
scc->stat.rx_queued--;
scc->stat.nospace++;
}
scc->rcvq->anext = bp;
}
}
static void static void
scc_timer(void) scc_timer(void)
{ {
...@@ -1186,11 +1219,7 @@ scc_timer(void) ...@@ -1186,11 +1219,7 @@ scc_timer(void)
if (scc->tty && scc->init) if (scc->tty && scc->init)
{ {
kiss_encode(scc);
check_rcv_queue(scc);
/* KISS-TNC emulation */ /* KISS-TNC emulation */
if (Expired(t_dwait)) dw_slot_timeout(scc) ; else if (Expired(t_dwait)) dw_slot_timeout(scc) ; else
if (Expired(t_slot)) dw_slot_timeout(scc) ; else if (Expired(t_slot)) dw_slot_timeout(scc) ; else
if (Expired(t_txdel)) txdel_timeout(scc) ; else if (Expired(t_txdel)) txdel_timeout(scc) ; else
...@@ -1201,9 +1230,11 @@ scc_timer(void) ...@@ -1201,9 +1230,11 @@ scc_timer(void)
if (Expired(t_mbusy)) busy_timeout(scc); if (Expired(t_mbusy)) busy_timeout(scc);
if (Expired(t_maxk)) maxk_idle_timeout(scc); if (Expired(t_maxk)) maxk_idle_timeout(scc);
if (Expired(t_idle)) maxk_idle_timeout(scc); if (Expired(t_idle)) maxk_idle_timeout(scc);
} }
} }
timer_table[SCC_TIMER].fn = scc_timer; timer_table[SCC_TIMER].fn = scc_timer;
timer_table[SCC_TIMER].expires = jiffies + HZ/TPS; timer_table[SCC_TIMER].expires = jiffies + HZ/TPS;
timer_active |= 1 << SCC_TIMER; timer_active |= 1 << SCC_TIMER;
...@@ -1423,97 +1454,6 @@ static inline int kiss_decode(struct scc_channel *scc, unsigned char ch) ...@@ -1423,97 +1454,6 @@ static inline int kiss_decode(struct scc_channel *scc, unsigned char ch)
} }
/* ----> Encode received data and write it to the flip-buffer <---- */
/* receive raw frame from SCC. used for AX.25 */
static void
kiss_encode(register struct scc_channel *scc)
{
struct mbuf *bp,*bp2;
struct tty_struct * tty = scc->tty;
unsigned long flags;
unsigned char ch;
if(!scc->rcvq)
{
scc->stat.rx_kiss_state = KISS_IDLE;
return;
}
/* worst case: FEND 0 FESC TFEND -> 4 bytes */
while(tty->flip.count < TTY_FLIPBUF_SIZE-3)
{
if (scc->rcvq->cnt)
{
bp = scc->rcvq;
if (scc->stat.rx_kiss_state == KISS_IDLE)
{
tty_insert_flip_char(tty, FEND, 0);
if (scc->kiss.not_slip)
tty_insert_flip_char(tty, 0, 0);
scc->stat.rx_kiss_state = KISS_RXFRAME;
}
switch(ch = bp->data[bp->in_use++])
{
case FEND:
tty_insert_flip_char(tty, FESC, 0);
tty_insert_flip_char(tty, TFEND, 0);
break;
case FESC:
tty_insert_flip_char(tty, FESC, 0);
tty_insert_flip_char(tty, TFESC, 0);
break;
default:
tty_insert_flip_char(tty, ch, 0);
}
bp->cnt--;
} else {
save_flags(flags); cli();
while (!scc->rcvq->cnt)
{ /* buffer empty? */
bp = scc->rcvq->next; /* next buffer */
bp2 = scc->rcvq->anext; /* next packet */
scc_return_buffer(scc->rcvq, BT_RECEIVE);
if (!bp) /* end of frame ? */
{
scc->rcvq = bp2;
if (--scc->stat.rx_queued < 0)
scc->stat.rx_queued = 0;
if (scc->stat.rx_kiss_state == KISS_RXFRAME) /* new packet? */
{
tty_insert_flip_char(tty, FEND, 0); /* send FEND for old frame */
scc->stat.rx_kiss_state = KISS_IDLE; /* generate FEND for new frame */
}
restore_flags(flags);
queue_task(&tty->flip.tqueue, &tq_timer);
return;
} else scc->rcvq = bp; /* next buffer */
}
restore_flags(flags);
}
}
queue_task(&tty->flip.tqueue, &tq_timer); /* kick it... */
}
/* ******************************************************************* */ /* ******************************************************************* */
/* * Init channel structures, special HW, etc... * */ /* * Init channel structures, special HW, etc... * */
/* ******************************************************************* */ /* ******************************************************************* */
...@@ -1523,11 +1463,10 @@ static void ...@@ -1523,11 +1463,10 @@ static void
z8530_init(void) z8530_init(void)
{ {
struct scc_channel *scc; struct scc_channel *scc;
int chip,chan; int chip;
unsigned long flags; unsigned long flags;
int k;
/* reset and pre-init all chips in the system */ /* reset all scc chips */
for (chip = 0; chip < Nchips; chip++) for (chip = 0; chip < Nchips; chip++)
{ {
/* Special SCC cards */ /* Special SCC cards */
...@@ -1538,30 +1477,25 @@ z8530_init(void) ...@@ -1538,30 +1477,25 @@ z8530_init(void)
if(Board & (PC100 | PRIMUS)) /* this is a PC100/EAGLE card */ if(Board & (PC100 | PRIMUS)) /* this is a PC100/EAGLE card */
Outb(Special_Port,Option); /* set the MODEM mode (22H normally) */ Outb(Special_Port,Option); /* set the MODEM mode (22H normally) */
/* Init SCC */
scc=&SCC_Info[2*chip]; scc=&SCC_Info[2*chip];
if (!scc->ctrl) continue; if (!scc->ctrl) continue;
save_flags(flags); cli(); save_flags(flags); cli();
Outb(scc->ctrl, 0);
OutReg(scc->ctrl,R9,FHWRES); /* force hardware reset */ OutReg(scc->ctrl,R9,FHWRES); /* force hardware reset */
for (k=1; k < 1000; k++) ; OutReg(scc->ctrl,R9,0); /* end hardware reset */
OutReg(scc->ctrl,R9,CHRA); /* reset channel A */
for (chan = 0; chan < 2; chan++) OutReg(scc->ctrl,R9,CHRB); /* reset channel B */
{ OutReg(scc->ctrl,R1, 0); /* No Rx irq from channel A */
scc=&SCC_Info[2*chip+chan]; scc=&SCC_Info[2*chip+1];
OutReg(scc->ctrl,R1, 0); /* No Rx irq from channel B */
wr(scc,R1, 0); scc=&SCC_Info[2*chip];
wr(scc,R2, chip*16); /* No of chip is vector */ OutReg(scc->ctrl,R2, chip*16); /* Set Interrupt vector */
wr(scc,R9,VIS); /* vector includes status */
}
restore_flags(flags); restore_flags(flags);
} }
if (Ivec == 2) Ivec = 9; /* this f... IBM AT-design! */ if (Ivec == 2) Ivec = 9;
request_irq(Ivec, scc_isr, SA_INTERRUPT, "AX.25 SCC"); request_irq(Ivec, scc_isr, SA_INTERRUPT, "AX.25 SCC");
Driver_Initialized = 1; Driver_Initialized = 1;
...@@ -1613,6 +1547,9 @@ int scc_open(struct tty_struct *tty, struct file * filp) ...@@ -1613,6 +1547,9 @@ int scc_open(struct tty_struct *tty, struct file * filp)
scc = &SCC_Info[chan]; scc = &SCC_Info[chan];
tty->driver_data = scc; tty->driver_data = scc;
tty->termios->c_iflag = IGNBRK | IGNPAR;
tty->termios->c_cflag = B9600 | CS8 | CLOCAL;
tty->termios->c_cflag &= ~CBAUD; tty->termios->c_cflag &= ~CBAUD;
if (!Driver_Initialized) if (!Driver_Initialized)
...@@ -1644,6 +1581,27 @@ int scc_open(struct tty_struct *tty, struct file * filp) ...@@ -1644,6 +1581,27 @@ int scc_open(struct tty_struct *tty, struct file * filp)
timer_table[SCC_TIMER].expires = 0; /* now! */ timer_table[SCC_TIMER].expires = 0; /* now! */
timer_active |= 1 << SCC_TIMER; timer_active |= 1 << SCC_TIMER;
/*====================new pe1ayx====================
planed for the new TX routines
if (!scc->xmit_buf) {
scc->xmit_buf = (unsigned char *) get_free_page(GFP_KERNEL);
if (!scc->xmit_buf)
return -ENOMEM;
}
scc->xmit_cnt = scc->xmit_head = scc->xmit_tail = 0;
====================new pe1ayx end================*/
if (!tmp_buf) {
tmp_buf = (unsigned char *) get_free_page(GFP_KERNEL);
if (!tmp_buf)
return -ENOMEM;
}
return 0; return 0;
} }
...@@ -1821,7 +1779,7 @@ scc_ioctl(struct tty_struct *tty, struct file * file, unsigned int cmd, unsigned ...@@ -1821,7 +1779,7 @@ scc_ioctl(struct tty_struct *tty, struct file * file, unsigned int cmd, unsigned
restore_flags(flags); restore_flags(flags);
put_user(result,(unsigned int *) arg); put_fs_long(result,(unsigned long *) arg);
return 0; return 0;
case TIOCMBIS: case TIOCMBIS:
case TIOCMBIC: case TIOCMBIC:
...@@ -1836,7 +1794,7 @@ scc_ioctl(struct tty_struct *tty, struct file * file, unsigned int cmd, unsigned ...@@ -1836,7 +1794,7 @@ scc_ioctl(struct tty_struct *tty, struct file * file, unsigned int cmd, unsigned
scc->wreg[R5] &= ~RTS; scc->wreg[R5] &= ~RTS;
break; break;
case TIOCMSET: case TIOCMSET:
value = get_user((unsigned int *) arg); value = get_fs_long((unsigned long *) arg);
if(value & TIOCM_DTR) if(value & TIOCM_DTR)
scc->wreg[R5] |= DTR; scc->wreg[R5] |= DTR;
...@@ -2022,6 +1980,7 @@ static inline void check_tx_queue(register struct scc_channel *scc) ...@@ -2022,6 +1980,7 @@ static inline void check_tx_queue(register struct scc_channel *scc)
scc->sndq1->anext = bp; scc->sndq1->anext = bp;
} }
} }
...@@ -2031,11 +1990,13 @@ static inline void check_tx_queue(register struct scc_channel *scc) ...@@ -2031,11 +1990,13 @@ static inline void check_tx_queue(register struct scc_channel *scc)
/* send raw frame to SCC. used for AX.25 */ /* send raw frame to SCC. used for AX.25 */
int scc_write(struct tty_struct *tty, int from_user, unsigned char *buf, int count) int scc_write(struct tty_struct *tty, int from_user, unsigned char *buf, int count)
{ {
unsigned long flags;
static unsigned char *p;
struct scc_channel * scc = tty->driver_data; struct scc_channel * scc = tty->driver_data;
unsigned char tbuf[BUFSIZE], *p;
int cnt, cnt2; int cnt, cnt2;
if (!tty) return count; if (!tty || !tmp_buf)
return 0;
if (scc_paranoia_check(scc, tty->device, "scc_write")) if (scc_paranoia_check(scc, tty->device, "scc_write"))
return 0; return 0;
...@@ -2044,31 +2005,43 @@ int scc_write(struct tty_struct *tty, int from_user, unsigned char *buf, int cou ...@@ -2044,31 +2005,43 @@ int scc_write(struct tty_struct *tty, int from_user, unsigned char *buf, int cou
check_tx_queue(scc); check_tx_queue(scc);
save_flags(flags);
cnt2 = count; cnt2 = count;
while (cnt2) while (cnt2)
{ {
cnt = cnt2 > BUFSIZE? BUFSIZE:cnt2; cli();
cnt = cnt2 > SERIAL_XMIT_SIZE? SERIAL_XMIT_SIZE:cnt2;
cnt2 -= cnt; cnt2 -= cnt;
if (from_user) if (from_user){
memcpy_fromfs(tbuf, buf, cnt); down(&tmp_buf_sem);
memcpy_fromfs(tmp_buf, buf, cnt);
up(&tmp_buf_sem);
}
else else
memcpy(tbuf, buf, cnt); memcpy(tmp_buf, buf, cnt);
buf += cnt; buf += cnt;
p=tbuf; p=tmp_buf;
while(cnt--) while(cnt--)
if (kiss_decode(scc, *p++)) if (kiss_decode(scc, *p++))
{ {
scc->stat.nospace++; scc->stat.nospace++;
restore_flags(flags);
return 0; return 0;
} }
} /* while cnt2 */ } /* while cnt2 */
if ((scc->tty->flags & (1 << TTY_DO_WRITE_WAKEUP))
&& scc->tty->ldisc.write_wakeup)
(scc->tty->ldisc.write_wakeup)(scc->tty);
restore_flags(flags);
return count; return count;
} }
...@@ -2133,10 +2106,6 @@ static void scc_flush_buffer(struct tty_struct *tty) ...@@ -2133,10 +2106,6 @@ static void scc_flush_buffer(struct tty_struct *tty)
scc->stat.tx_kiss_state = KISS_IDLE; scc->stat.tx_kiss_state = KISS_IDLE;
wake_up_interruptible(&tty->write_wait);
if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
tty->ldisc.write_wakeup)
(tty->ldisc.write_wakeup)(tty);
} }
static void scc_throttle(struct tty_struct *tty) static void scc_throttle(struct tty_struct *tty)
...@@ -2148,6 +2117,7 @@ static void scc_throttle(struct tty_struct *tty) ...@@ -2148,6 +2117,7 @@ static void scc_throttle(struct tty_struct *tty)
/* dummy */ /* dummy */
} }
static void scc_unthrottle(struct tty_struct *tty) static void scc_unthrottle(struct tty_struct *tty)
...@@ -2158,6 +2128,7 @@ static void scc_unthrottle(struct tty_struct *tty) ...@@ -2158,6 +2128,7 @@ static void scc_unthrottle(struct tty_struct *tty)
return; return;
/* dummy */ /* dummy */
} }
static void scc_start(struct tty_struct *tty) static void scc_start(struct tty_struct *tty)
...@@ -2181,6 +2152,14 @@ static void scc_stop(struct tty_struct *tty) ...@@ -2181,6 +2152,14 @@ static void scc_stop(struct tty_struct *tty)
/* dummy */ /* dummy */
} }
void scc_hangup(struct tty_struct *tty)
{
struct scc_channel *scc = tty->driver_data;
if (scc_paranoia_check(scc, tty->device, "scc_hangup"))
return;
}
/* ******************************************************************** */ /* ******************************************************************** */
/* * Init SCC driver * */ /* * Init SCC driver * */
...@@ -2188,7 +2167,11 @@ static void scc_stop(struct tty_struct *tty) ...@@ -2188,7 +2167,11 @@ static void scc_stop(struct tty_struct *tty)
long scc_init (long kmem_start) long scc_init (long kmem_start)
{ {
int chip, chan;
int chip;
#ifdef VERBOSE_BOOTMSG
int chan;
#endif
register io_port ctrl; register io_port ctrl;
long flags; long flags;
...@@ -2200,31 +2183,31 @@ long scc_init (long kmem_start) ...@@ -2200,31 +2183,31 @@ long scc_init (long kmem_start)
scc_driver.minor_start = 96; scc_driver.minor_start = 96;
scc_driver.num = Nchips*2; scc_driver.num = Nchips*2;
scc_driver.type = TTY_DRIVER_TYPE_SERIAL; scc_driver.type = TTY_DRIVER_TYPE_SERIAL;
scc_driver.subtype = 0; /* not needed */ scc_driver.subtype = SERIAL_TYPE_NORMAL; /* not needed */
scc_driver.init_termios = tty_std_termios; scc_driver.init_termios = tty_std_termios;
scc_driver.init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL; scc_driver.init_termios.c_iflag = IGNBRK | IGNPAR;
scc_driver.init_termios.c_cflag = B9600 | CS8 | CLOCAL;
scc_driver.flags = TTY_DRIVER_REAL_RAW; scc_driver.flags = TTY_DRIVER_REAL_RAW;
scc_driver.refcount = &scc_refcount; /* not needed yet */ scc_driver.refcount = &scc_refcount; /* not needed yet */
scc_driver.table = scc_table; scc_driver.table = scc_table;
scc_driver.termios = (struct termios **) scc_termios; scc_driver.termios = (struct termios **) scc_termios;
scc_driver.termios_locked = (struct termios **) scc_termios_locked; scc_driver.termios_locked = (struct termios **) scc_termios_locked;
scc_driver.open = scc_open; scc_driver.open = scc_open;
scc_driver.close = scc_close; scc_driver.close = scc_close;
scc_driver.write = scc_write; scc_driver.write = scc_write;
scc_driver.start = scc_start;
scc_driver.stop = scc_stop;
scc_driver.put_char = scc_put_char; scc_driver.put_char = scc_put_char;
scc_driver.flush_chars = scc_flush_chars; scc_driver.flush_chars = scc_flush_chars;
scc_driver.write_room = scc_write_room; scc_driver.write_room = scc_write_room;
scc_driver.chars_in_buffer = scc_chars_in_buffer; scc_driver.chars_in_buffer = scc_chars_in_buffer;
scc_driver.flush_buffer = scc_flush_buffer; scc_driver.flush_buffer = scc_flush_buffer;
scc_driver.ioctl = scc_ioctl;
scc_driver.throttle = scc_throttle; scc_driver.throttle = scc_throttle;
scc_driver.unthrottle = scc_unthrottle; scc_driver.unthrottle = scc_unthrottle;
scc_driver.ioctl = scc_ioctl;
scc_driver.set_termios = scc_set_termios; scc_driver.set_termios = scc_set_termios;
scc_driver.stop = scc_stop;
scc_driver.start = scc_start;
scc_driver.hangup = scc_hangup;
if (tty_register_driver(&scc_driver)) if (tty_register_driver(&scc_driver))
panic("Couldn't register Z8530 SCC driver\n"); panic("Couldn't register Z8530 SCC driver\n");
......
...@@ -42,6 +42,8 @@ endif ...@@ -42,6 +42,8 @@ endif
ifdef CONFIG_HP100 ifdef CONFIG_HP100
NETDRV_OBJS := $(NETDRV_OBJS) hp100.o NETDRV_OBJS := $(NETDRV_OBJS) hp100.o
else
MODULES := $(MODULES) hp100.o
endif endif
ifdef CONFIG_WD80x3 ifdef CONFIG_WD80x3
......
...@@ -65,6 +65,7 @@ ...@@ -65,6 +65,7 @@
* 0.11 14-Jun-95 Reset interface bug fixed? * 0.11 14-Jun-95 Reset interface bug fixed?
* Little bug in hp100_close function fixed. * Little bug in hp100_close function fixed.
* 100Mb/s connection debugged. * 100Mb/s connection debugged.
* 0.12 14-Jul-95 Link down is now handled better.
* *
*/ */
...@@ -350,12 +351,6 @@ static int hp100_open( struct device *dev ) ...@@ -350,12 +351,6 @@ static int hp100_open( struct device *dev )
int ioaddr = dev -> base_addr; int ioaddr = dev -> base_addr;
struct hp100_private *lp = (struct hp100_private *)dev -> priv; struct hp100_private *lp = (struct hp100_private *)dev -> priv;
if ( ( lp -> lan_type = hp100_sense_lan( dev ) ) < 0 )
{
printk( "%s: no connection found - check wire\n", dev -> name );
return -EIO;
}
if ( request_irq( dev -> irq, hp100_interrupt, SA_INTERRUPT, lp -> id -> name ) ) if ( request_irq( dev -> irq, hp100_interrupt, SA_INTERRUPT, lp -> id -> name ) )
{ {
printk( "%s: unable to get IRQ %d\n", dev -> name, dev -> irq ); printk( "%s: unable to get IRQ %d\n", dev -> name, dev -> irq );
...@@ -372,6 +367,7 @@ static int hp100_open( struct device *dev ) ...@@ -372,6 +367,7 @@ static int hp100_open( struct device *dev )
dev -> interrupt = 0; dev -> interrupt = 0;
dev -> start = 1; dev -> start = 1;
lp -> lan_type = hp100_sense_lan( dev );
lp -> mac1_mode = HP100_MAC1MODE3; lp -> mac1_mode = HP100_MAC1MODE3;
lp -> mac2_mode = HP100_MAC2MODE3; lp -> mac2_mode = HP100_MAC2MODE3;
...@@ -424,11 +420,11 @@ static int hp100_close( struct device *dev ) ...@@ -424,11 +420,11 @@ static int hp100_close( struct device *dev )
struct hp100_private *lp = (struct hp100_private *)dev -> priv; struct hp100_private *lp = (struct hp100_private *)dev -> priv;
hp100_page( PERFORMANCE ); hp100_page( PERFORMANCE );
hp100_outw( 0xfefe, IRQ_MASK ); /* mask off all ints */ hp100_outw( 0xfefe, IRQ_MASK ); /* mask off all IRQs */
hp100_stop_interface( dev ); /* relogin */ hp100_stop_interface( dev );
if ( lp -> lan_type == HP100_LAN_100 ) if ( lp -> lan_type == HP100_LAN_100 ) /* relogin */
hp100_login_to_vg_hub( dev ); hp100_login_to_vg_hub( dev );
dev -> tbusy = 1; dev -> tbusy = 1;
...@@ -453,6 +449,20 @@ static int hp100_start_xmit( struct sk_buff *skb, struct device *dev ) ...@@ -453,6 +449,20 @@ static int hp100_start_xmit( struct sk_buff *skb, struct device *dev )
u_short val; u_short val;
struct hp100_private *lp = (struct hp100_private *)dev -> priv; struct hp100_private *lp = (struct hp100_private *)dev -> priv;
if ( lp -> lan_type < 0 )
{
hp100_stop_interface( dev );
if ( ( lp -> lan_type = hp100_sense_lan( dev ) ) < 0 )
{
printk( "%s: no connection found - check wire\n", dev -> name );
hp100_start_interface( dev ); /* 10Mb/s RX packets maybe handled */
return -EIO;
}
if ( lp -> lan_type == HP100_LAN_100 )
lp -> hub_status = hp100_login_to_vg_hub( dev );
hp100_start_interface( dev );
}
if ( ( i = ( hp100_inl( TX_MEM_FREE ) & ~0x7fffffff ) ) < skb -> len + 16 ) if ( ( i = ( hp100_inl( TX_MEM_FREE ) & ~0x7fffffff ) ) < skb -> len + 16 )
{ {
#ifdef HP100_DEBUG #ifdef HP100_DEBUG
...@@ -463,11 +473,9 @@ static int hp100_start_xmit( struct sk_buff *skb, struct device *dev ) ...@@ -463,11 +473,9 @@ static int hp100_start_xmit( struct sk_buff *skb, struct device *dev )
/* 100Mb/s adapter isn't connected to hub */ /* 100Mb/s adapter isn't connected to hub */
{ {
printk( "%s: login to 100Mb/s hub retry\n", dev -> name ); printk( "%s: login to 100Mb/s hub retry\n", dev -> name );
hp100_ints_off();
hp100_stop_interface( dev ); hp100_stop_interface( dev );
lp -> hub_status = hp100_login_to_vg_hub( dev ); lp -> hub_status = hp100_login_to_vg_hub( dev );
hp100_start_interface( dev ); hp100_start_interface( dev );
hp100_ints_on();
} }
else else
{ {
...@@ -483,20 +491,16 @@ static int hp100_start_xmit( struct sk_buff *skb, struct device *dev ) ...@@ -483,20 +491,16 @@ static int hp100_start_xmit( struct sk_buff *skb, struct device *dev )
/* it's very heavy - all network setting must be changed!!! */ /* it's very heavy - all network setting must be changed!!! */
printk( "%s: cable change 10Mb/s <-> 100Mb/s detected\n", dev -> name ); printk( "%s: cable change 10Mb/s <-> 100Mb/s detected\n", dev -> name );
lp -> lan_type = i; lp -> lan_type = i;
hp100_ints_off();
hp100_stop_interface( dev ); hp100_stop_interface( dev );
if ( lp -> lan_type == HP100_LAN_100 ) if ( lp -> lan_type == HP100_LAN_100 )
lp -> hub_status = hp100_login_to_vg_hub( dev ); lp -> hub_status = hp100_login_to_vg_hub( dev );
hp100_start_interface( dev ); hp100_start_interface( dev );
hp100_ints_on();
} }
else else
{ {
printk( "%s: interface reset\n", dev -> name ); printk( "%s: interface reset\n", dev -> name );
hp100_ints_off();
hp100_stop_interface( dev ); hp100_stop_interface( dev );
hp100_start_interface( dev ); hp100_start_interface( dev );
hp100_ints_on();
} }
} }
dev -> trans_start = jiffies; dev -> trans_start = jiffies;
...@@ -566,6 +570,15 @@ static void hp100_rx( struct device *dev ) ...@@ -566,6 +570,15 @@ static void hp100_rx( struct device *dev )
u_int header; u_int header;
struct sk_buff *skb; struct sk_buff *skb;
#if 0
if ( lp -> lan_type < 0 )
{
if ( ( lp -> lan_type = hp100_sense_lan( dev ) ) == HP100_LAN_100 )
lp -> hub_status = hp100_login_to_vg_hub( dev );
hp100_page( PERFORMANCE );
}
#endif
packets = hp100_inb( RX_PKT_CNT ); packets = hp100_inb( RX_PKT_CNT );
#ifdef HP100_DEBUG #ifdef HP100_DEBUG
if ( packets > 1 ) if ( packets > 1 )
...@@ -730,6 +743,7 @@ static void hp100_interrupt( int irq ) ...@@ -730,6 +743,7 @@ static void hp100_interrupt( int irq )
printk( "%s: re-entering the interrupt handler\n", dev -> name ); printk( "%s: re-entering the interrupt handler\n", dev -> name );
hp100_ints_off(); hp100_ints_off();
dev -> interrupt = 1; dev -> interrupt = 1;
hp100_page( PERFORMANCE );
val = hp100_inw( IRQ_STATUS ); val = hp100_inw( IRQ_STATUS );
#ifdef HP100_DEBUG_IRQ #ifdef HP100_DEBUG_IRQ
printk( "hp100_interrupt: irq_status = 0x%x\n", val ); printk( "hp100_interrupt: irq_status = 0x%x\n", val );
......
...@@ -49,6 +49,7 @@ ...@@ -49,6 +49,7 @@
April 23, 1995 (dp) Fixed ioctl so it works properly with piconfig program April 23, 1995 (dp) Fixed ioctl so it works properly with piconfig program
when changing the baud rate or clock mode. when changing the baud rate or clock mode.
version 0.8 ALPHA version 0.8 ALPHA
July 17, 1995 (ac) Finally polishing of AX25.030+ support
*/ */
...@@ -59,7 +60,7 @@ ...@@ -59,7 +60,7 @@
of each transmitted packet. If this causes you to lose sleep, #undefine it. of each transmitted packet. If this causes you to lose sleep, #undefine it.
*/ */
#define STUFF2 1 /*#define STUFF2 1*/
/* The default configuration */ /* The default configuration */
#define PI_DMA 3 #define PI_DMA 3
...@@ -1430,7 +1431,7 @@ static int pi_probe(struct device *dev, int card_type) ...@@ -1430,7 +1431,7 @@ static int pi_probe(struct device *dev, int card_type)
dev->set_mac_address = pi_set_mac_address; dev->set_mac_address = pi_set_mac_address;
dev->type = ARPHRD_AX25; /* AF_AX25 device */ dev->type = ARPHRD_AX25; /* AF_AX25 device */
dev->hard_header_len = 17; /* We don't do digipeaters */ dev->hard_header_len = 73; /* We do digipeaters now */
dev->mtu = 1500; /* eth_mtu is the default */ dev->mtu = 1500; /* eth_mtu is the default */
dev->addr_len = 7; /* sizeof an ax.25 address */ dev->addr_len = 7; /* sizeof an ax.25 address */
memcpy(dev->broadcast, ax25_bcast, 7); memcpy(dev->broadcast, ax25_bcast, 7);
......
...@@ -36,6 +36,7 @@ ...@@ -36,6 +36,7 @@
* statistics. Include CSLIP code only * statistics. Include CSLIP code only
* if it really needed. * if it really needed.
* Alan Cox : Free slhc buffers in the right place. * Alan Cox : Free slhc buffers in the right place.
* Alan Cox : Allow for digipeated IP over AX.25
* *
* *
* *
...@@ -1014,7 +1015,7 @@ slip_ioctl(struct tty_struct *tty, void *file, int cmd, void *arg) ...@@ -1014,7 +1015,7 @@ slip_ioctl(struct tty_struct *tty, void *file, int cmd, void *arg)
#else #else
if ((tmp & SL_MODE_AX25) || (tmp & SL_MODE_AX25VC)) { if ((tmp & SL_MODE_AX25) || (tmp & SL_MODE_AX25VC)) {
sl->dev->addr_len=AX25_ADDR_LEN; /* sizeof an AX.25 addr */ sl->dev->addr_len=AX25_ADDR_LEN; /* sizeof an AX.25 addr */
sl->dev->hard_header_len=AX25_HEADER_LEN; /* We don't do digipeaters */ sl->dev->hard_header_len=73; /* We don't do digipeaters */
} else { } else {
sl->dev->addr_len=0; /* No mac addr in slip mode */ sl->dev->addr_len=0; /* No mac addr in slip mode */
sl->dev->hard_header_len=0; sl->dev->hard_header_len=0;
......
...@@ -3,35 +3,23 @@ ...@@ -3,35 +3,23 @@
* *
* Copyright (c) 1994 John Aycock * Copyright (c) 1994 John Aycock
* The University of Calgary Department of Computer Science. * The University of Calgary Department of Computer Science.
* All rights reserved. *
* * This program is free software; you can redistribute it and/or modify
* Redistribution and use in source and binary forms, with or without * it under the terms of the GNU General Public License as published by
* modification, are permitted provided that the following conditions * the Free Software Foundation; either version 2, or (at your option)
* are met: * any later version.
* 1. Redistributions of source code must retain the above copyright *
* notice, this list of conditions, and the following disclaimer. * This program is distributed in the hope that it will be useful,
* 2. Redistributions in binary form must reproduce the above copyright * but WITHOUT ANY WARRANTY; without even the implied warranty of
* notice, this list of conditions and the following disclaimer in the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* documentation and/or other materials provided with the distribution. * GNU General Public License for more details.
* 3. All advertising materials mentioning features or use of this software *
* must display the following acknowledgement: * You should have received a copy of the GNU General Public License
* This product includes software developed by the University of Calgary * along with this program; see the file COPYING. If not, write to
* Department of Computer Science and its contributors. * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
* 4. Neither the name of the University nor the names of its contributors *
* may be used to endorse or promote products derived from this software * An alternate version of this driver with a BSD-style copyright can
* without specific prior written permission. * be found on XXX.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* *
* Sources include the Adaptec 1740 driver (aha1740.c), the Ultrastor 24F * Sources include the Adaptec 1740 driver (aha1740.c), the Ultrastor 24F
* driver (ultrastor.c), various Linux kernel source, the Adaptec EISA * driver (ultrastor.c), various Linux kernel source, the Adaptec EISA
......
...@@ -3,35 +3,23 @@ ...@@ -3,35 +3,23 @@
* *
* Copyright (c) 1994 John Aycock * Copyright (c) 1994 John Aycock
* The University of Calgary Department of Computer Science. * The University of Calgary Department of Computer Science.
* All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * This program is free software; you can redistribute it and/or modify
* modification, are permitted provided that the following conditions * it under the terms of the GNU General Public License as published by
* are met: * the Free Software Foundation; either version 2, or (at your option)
* 1. Redistributions of source code must retain the above copyright * any later version.
* notice, this list of conditions, and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of Calgary
* Department of Computer Science and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * This program is distributed in the hope that it will be useful,
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * but WITHOUT ANY WARRANTY; without even the implied warranty of
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * GNU General Public License for more details.
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL *
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * You should have received a copy of the GNU General Public License
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * along with this program; see the file COPYING. If not, write to
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY *
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * An alternate version of this driver with a BSD-style copyright can
* SUCH DAMAGE. * be found on XXX.
* *
* $Id: aic7xxx.h,v 1.18 1995/06/22 04:17:56 deang Exp $ * $Id: aic7xxx.h,v 1.18 1995/06/22 04:17:56 deang Exp $
*-M*************************************************************************/ *-M*************************************************************************/
......
...@@ -3,35 +3,23 @@ ...@@ -3,35 +3,23 @@
* *
* Copyright (c) 1994 John Aycock * Copyright (c) 1994 John Aycock
* The University of Calgary Department of Computer Science. * The University of Calgary Department of Computer Science.
* All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * This program is free software; you can redistribute it and/or modify
* modification, are permitted provided that the following conditions * it under the terms of the GNU General Public License as published by
* are met: * the Free Software Foundation; either version 2, or (at your option)
* 1. Redistributions of source code must retain the above copyright * any later version.
* notice, this list of conditions, and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of Calgary
* Department of Computer Science and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * This program is distributed in the hope that it will be useful,
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * but WITHOUT ANY WARRANTY; without even the implied warranty of
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * GNU General Public License for more details.
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL *
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * You should have received a copy of the GNU General Public License
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * along with this program; see the file COPYING. If not, write to
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY *
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * An alternate version of this driver with a BSD-style copyright can
* SUCH DAMAGE. * be found on XXX.
* *
* Comments are started by `#' and continue to the end of the line; lines * Comments are started by `#' and continue to the end of the line; lines
* may be of the form: * may be of the form:
......
...@@ -12,10 +12,12 @@ ...@@ -12,10 +12,12 @@
* -supports all PCI based EATA-DMA boards * * -supports all PCI based EATA-DMA boards *
* -supports multiple HBAs with & without IRQ sharing * * -supports multiple HBAs with & without IRQ sharing *
* -supports all SCSI channels on multi channel boards * * -supports all SCSI channels on multi channel boards *
* -needs identical IDs on all channels of a HBA *
* -can be loaded as module * * -can be loaded as module *
* -displays statistical and hardware information * * -displays statistical and hardware information *
* in /proc/scsi/eata_dma * * in /proc/scsi/eata_dma *
* -needs identical HBA ids on all channels * * -provides rudimentary latency measurement *
* possibilities via /proc/scsi/eata_dma/<hostnum> *
* * * *
* (c)1993,94,95 Michael Neuffer * * (c)1993,94,95 Michael Neuffer *
* neuffer@goofy.zdv.uni-mainz.de * * neuffer@goofy.zdv.uni-mainz.de *
...@@ -46,7 +48,7 @@ ...@@ -46,7 +48,7 @@
* Thanks also to Greg Hosler who did a lot of testing and * * Thanks also to Greg Hosler who did a lot of testing and *
* found quite a number of bugs during the development. * * found quite a number of bugs during the development. *
************************************************************ ************************************************************
* last change: 95/06/28 OS: Linux 1.3.4 + pre1.3 SCSI pat.* * last change: 95/07/11 OS: Linux 1.3.9 *
************************************************************/ ************************************************************/
/* Look in eata_dma.h for configuration and revision information */ /* Look in eata_dma.h for configuration and revision information */
...@@ -210,8 +212,28 @@ void eata_int_handler(int irq, struct pt_regs * regs) ...@@ -210,8 +212,28 @@ void eata_int_handler(int irq, struct pt_regs * regs)
&& cmd->device->type == TYPE_DISK && cmd->device->type == TYPE_DISK
&& (HD(cmd)->t_state[cp->cp_channel][cp->cp_id] == RESET)) && (HD(cmd)->t_state[cp->cp_channel][cp->cp_id] == RESET))
result = DID_BUS_BUSY << 16; result = DID_BUS_BUSY << 16;
else if (scsi_stat == GOOD) else if (scsi_stat == GOOD) {
HD(cmd)->t_state[cp->cp_channel][cp->cp_id] = OK; HD(cmd)->t_state[cp->cp_channel][cp->cp_id] = OK;
if(HD(cmd)->do_latency == TRUE && cp->timestamp) {
uint time;
time = jiffies - cp->timestamp;
if((cp->rw_latency) == TRUE) { /* was WRITE */
if(HD(cmd)->writes_lat[cp->sizeindex][1] > time)
HD(cmd)->writes_lat[cp->sizeindex][1] = time;
if(HD(cmd)->writes_lat[cp->sizeindex][2] < time)
HD(cmd)->writes_lat[cp->sizeindex][2] = time;
HD(cmd)->writes_lat[cp->sizeindex][3] += time;
HD(cmd)->writes_lat[cp->sizeindex][0]++;
} else {
if(HD(cmd)->reads_lat[cp->sizeindex][1] > time)
HD(cmd)->reads_lat[cp->sizeindex][1] = time;
if(HD(cmd)->reads_lat[cp->sizeindex][2] < time)
HD(cmd)->reads_lat[cp->sizeindex][2] = time;
HD(cmd)->reads_lat[cp->sizeindex][3] += time;
HD(cmd)->reads_lat[cp->sizeindex][0]++;
}
}
}
else if (scsi_stat == CHECK_CONDITION else if (scsi_stat == CHECK_CONDITION
&& cmd->device->type == TYPE_DISK && cmd->device->type == TYPE_DISK
&& (cmd->sense_buffer[2] & 0xf) == RECOVERED_ERROR) && (cmd->sense_buffer[2] & 0xf) == RECOVERED_ERROR)
...@@ -354,15 +376,11 @@ int eata_queue(Scsi_Cmnd * cmd, void (* done) (Scsi_Cmnd *)) ...@@ -354,15 +376,11 @@ int eata_queue(Scsi_Cmnd * cmd, void (* done) (Scsi_Cmnd *))
hd->last_ccb = y; hd->last_ccb = y;
if (x == sh->can_queue) { if (x == sh->can_queue) {
DBG(DBG_QUEUE, printk("can_queue %d, x %d, y %d\n", DBG(DBG_QUEUE, printk("can_queue %d, x %d, y %d\n",
sh->can_queue, x, y)); sh->can_queue, x, y));
#if DEBUG_EATA
panic("eata_dma: run out of queue slots cmdno:%ld intrno: %ld\n", panic("eata_dma: run out of queue slots cmdno:%ld intrno: %ld\n",
queue_counter, int_counter); queue_counter, int_counter);
#else
panic("eata_dma: run out of queue slots....\n");
#endif
} }
cp = &hd->ccb[y]; cp = &hd->ccb[y];
...@@ -374,6 +392,42 @@ int eata_queue(Scsi_Cmnd * cmd, void (* done) (Scsi_Cmnd *)) ...@@ -374,6 +392,42 @@ int eata_queue(Scsi_Cmnd * cmd, void (* done) (Scsi_Cmnd *))
DBG(DBG_QUEUE, printk("eata_queue pid %ld, target: %x, lun: %x, y %d\n", DBG(DBG_QUEUE, printk("eata_queue pid %ld, target: %x, lun: %x, y %d\n",
cmd->pid, cmd->target, cmd->lun, y)); cmd->pid, cmd->target, cmd->lun, y));
DBG(DBG_QUEUE && DBG_DELAY, DEL2(250)); DBG(DBG_QUEUE && DBG_DELAY, DEL2(250));
if(hd->do_latency == TRUE) {
int x, z;
short *sho;
long *lon;
x = 0; /* just to keep GCC quiet */
if (cmd->cmnd[0] == WRITE_6 || cmd->cmnd[0] == WRITE_10 ||
cmd->cmnd[0] == WRITE_12 || cmd->cmnd[0] == READ_6 ||
cmd->cmnd[0] == READ_10 || cmd->cmnd[0] == READ_12) {
cp->timestamp = jiffies; /* For latency measurements */
switch(cmd->cmnd[0]) {
case WRITE_6:
case READ_6:
x = cmd->cmnd[4]/2;
break;
case WRITE_10:
case READ_10:
sho = (short *) &cmd->cmnd[7];
x = ntohs(*sho)/2;
break;
case WRITE_12:
case READ_12:
lon = (long *) &cmd->cmnd[6];
x = ntohl(*lon)/2;
break;
}
for(z = 0; z <= 11, x > (1 << z); z++)
/* nothing */;
cp->sizeindex = z;
if (cmd->cmnd[0] == WRITE_6 || cmd->cmnd[0] == WRITE_10 ||
cmd->cmnd[0] == WRITE_12){
cp->rw_latency = TRUE;
}
}
}
cmd->scsi_done = (void *)done; cmd->scsi_done = (void *)done;
switch (cmd->cmnd[0]) { switch (cmd->cmnd[0]) {
...@@ -572,7 +626,7 @@ int eata_reset(Scsi_Cmnd * cmd) ...@@ -572,7 +626,7 @@ int eata_reset(Scsi_Cmnd * cmd)
restore_flags(flags); restore_flags(flags);
time = jiffies; time = jiffies;
while (jiffies < (time + 300) && limit++ < 10000000) while (jiffies < (time + (3 * HZ)) && limit++ < 10000000)
/* nothing */; /* nothing */;
save_flags(flags); save_flags(flags);
...@@ -659,7 +713,7 @@ char * get_board_data(u32 base, u32 irq, u32 id) ...@@ -659,7 +713,7 @@ char * get_board_data(u32 base, u32 irq, u32 id)
eata_send_command((u32) cp, (u32) base, EATA_CMD_DMA_SEND_CP); eata_send_command((u32) cp, (u32) base, EATA_CMD_DMA_SEND_CP);
i = jiffies + 300; i = jiffies + (3 * HZ) ;
while (fake_int_result == FALSE && jiffies <= i) while (fake_int_result == FALSE && jiffies <= i)
barrier(); barrier();
...@@ -676,7 +730,7 @@ char * get_board_data(u32 base, u32 irq, u32 id) ...@@ -676,7 +730,7 @@ char * get_board_data(u32 base, u32 irq, u32 id)
inb((u32) (base) + HA_RSTATUS); inb((u32) (base) + HA_RSTATUS);
eata_send_command(0, base, EATA_CMD_RESET); eata_send_command(0, base, EATA_CMD_RESET);
i = jiffies; i = jiffies;
while (jiffies < (i + 300) && limit++ < 10000000) while (jiffies < (i + (3 * HZ)) && limit++ < 10000000)
barrier(); barrier();
return (NULL); return (NULL);
} else } else
...@@ -767,7 +821,7 @@ void print_config(struct get_conf *gc) ...@@ -767,7 +821,7 @@ void print_config(struct get_conf *gc)
gc->SG_64K, gc->SG_UAE, gc->MAX_ID, gc->MAX_CHAN, gc->MAX_LUN); gc->SG_64K, gc->SG_UAE, gc->MAX_ID, gc->MAX_CHAN, gc->MAX_LUN);
printk("RIDQ:%d PCI:%d EISA:%d\n", printk("RIDQ:%d PCI:%d EISA:%d\n",
gc->ID_qest, gc->is_PCI, gc->is_EISA); gc->ID_qest, gc->is_PCI, gc->is_EISA);
DBG(DPT_DEBUG, DELAY(1400)); DBG(DPT_DEBUG, DELAY(14));
} }
short register_HBA(u32 base, struct get_conf *gc, Scsi_Host_Template * tpnt, short register_HBA(u32 base, struct get_conf *gc, Scsi_Host_Template * tpnt,
...@@ -779,6 +833,7 @@ short register_HBA(u32 base, struct get_conf *gc, Scsi_Host_Template * tpnt, ...@@ -779,6 +833,7 @@ short register_HBA(u32 base, struct get_conf *gc, Scsi_Host_Template * tpnt,
unchar bugs = 0; unchar bugs = 0;
struct Scsi_Host *sh; struct Scsi_Host *sh;
hostdata *hd; hostdata *hd;
int x;
DBG(DBG_REGISTER, print_config(gc)); DBG(DBG_REGISTER, print_config(gc));
...@@ -960,7 +1015,7 @@ short register_HBA(u32 base, struct get_conf *gc, Scsi_Host_Template * tpnt, ...@@ -960,7 +1015,7 @@ short register_HBA(u32 base, struct get_conf *gc, Scsi_Host_Template * tpnt,
* SCSI midlevel code should support different HBA ids on every channel * SCSI midlevel code should support different HBA ids on every channel
*/ */
sh->this_id = gc->scsi_id[3]; sh->this_id = gc->scsi_id[3];
sh->can_queue = ntohs(gc->queuesiz); sh->can_queue = ntohs(gc->queuesiz) - 1; /* Keep one free for internals */
if (gc->OCS_enabled == TRUE) if (gc->OCS_enabled == TRUE)
if(hd->bustype != IS_ISA) if(hd->bustype != IS_ISA)
...@@ -1005,6 +1060,11 @@ short register_HBA(u32 base, struct get_conf *gc, Scsi_Host_Template * tpnt, ...@@ -1005,6 +1060,11 @@ short register_HBA(u32 base, struct get_conf *gc, Scsi_Host_Template * tpnt,
sh->unchecked_isa_dma = TRUE; /* We're doing ISA DMA */ sh->unchecked_isa_dma = TRUE; /* We're doing ISA DMA */
} }
for(x = 0; x <= 11; x++){ /* Initialize min. latency */
hd->writes_lat[x][1] = 0xffffffff;
hd->reads_lat[x][1] = 0xffffffff;
}
hd->next = NULL; /* build a linked list of all HBAs */ hd->next = NULL; /* build a linked list of all HBAs */
hd->prev = last_HBA; hd->prev = last_HBA;
if(hd->prev != NULL) if(hd->prev != NULL)
...@@ -1237,7 +1297,7 @@ int eata_detect(Scsi_Host_Template * tpnt) ...@@ -1237,7 +1297,7 @@ int eata_detect(Scsi_Host_Template * tpnt)
scsi_init_free((void *)dma_scratch, 512); scsi_init_free((void *)dma_scratch, 512);
DBG(DPT_DEBUG, DELAY(1200)); DBG(DPT_DEBUG, DELAY(12));
return(registered_HBAs); return(registered_HBAs);
} }
...@@ -1262,7 +1322,6 @@ Scsi_Host_Template driver_template = EATA_DMA; ...@@ -1262,7 +1322,6 @@ Scsi_Host_Template driver_template = EATA_DMA;
* c-label-offset: -4 * c-label-offset: -4
* c-continued-statement-offset: 4 * c-continued-statement-offset: 4
* c-continued-brace-offset: 0 * c-continued-brace-offset: 0
* indent-tabs-mode: nil
* tab-width: 8 * tab-width: 8
* End: * End:
*/ */
...@@ -16,7 +16,7 @@ ...@@ -16,7 +16,7 @@
#define VER_MAJOR 2 #define VER_MAJOR 2
#define VER_MINOR 5 #define VER_MINOR 5
#define VER_SUB "6a" #define VER_SUB "7a"
/************************************************************************ /************************************************************************
......
...@@ -47,8 +47,24 @@ void swap_statistics(u8 *p) ...@@ -47,8 +47,24 @@ void swap_statistics(u8 *p)
*/ */
int eata_set_info(char *buffer, int length, struct Scsi_Host *HBA_ptr) int eata_set_info(char *buffer, int length, struct Scsi_Host *HBA_ptr)
{ {
DBG(DBG_PROC_WRITE, printk("%s\n", buffer)); if (length >= 8 && strncmp(buffer, "eata_dma", 8) == 0) {
return(-ENOSYS); /* Currently this is a no-op */ buffer += 9;
length -= 9;
if(length >= 8 && strncmp(buffer, "latency", 7) == 0) {
SD(HBA_ptr)->do_latency = TRUE;
return(length+9);
}
if(length >=10 && strncmp(buffer, "nolatency", 9) == 0) {
SD(HBA_ptr)->do_latency = FALSE;
return(length+9);
}
printk("Unknown command:%s length: %d\n", buffer, length);
} else
printk("Wrong Signature:%10s\n", (char *) ((ulong)buffer-9));
return(-EINVAL);
} }
/* /*
...@@ -327,7 +343,7 @@ int eata_proc_info(char *buffer, char **start, off_t offset, int length, ...@@ -327,7 +343,7 @@ int eata_proc_info(char *buffer, char **start, off_t offset, int length,
SD(HBA_ptr)->writes[11]); SD(HBA_ptr)->writes[11]);
len += size; len += size;
pos = begin + len; pos = begin + len;
size = sprintf(buffer+len,"Sum :%12u %12u\n", size = sprintf(buffer+len,"Sum : %12u %12u\n",
SD(HBA_ptr)->reads[12], SD(HBA_ptr)->reads[12],
SD(HBA_ptr)->writes[12]); SD(HBA_ptr)->writes[12]);
len += size; len += size;
...@@ -341,6 +357,79 @@ int eata_proc_info(char *buffer, char **start, off_t offset, int length, ...@@ -341,6 +357,79 @@ int eata_proc_info(char *buffer, char **start, off_t offset, int length,
if (pos > offset + length) if (pos > offset + length)
goto stop_output; goto stop_output;
if(SD(HBA_ptr)->do_latency == TRUE) {
size = sprintf(buffer + len, "Host Latency Command Statistics:\n"
"Current timer resolution: 10ms\n"
" Reads: Min:(ms) Max:(ms) Ave:(ms)\n");
len += size;
pos = begin + len;
for (x = 0; x <= 10; x++) {
size = sprintf(buffer+len,"%5dk:%12u %12u %12u %12u\n",
1 << x,
SD(HBA_ptr)->reads_lat[x][0],
(SD(HBA_ptr)->reads_lat[x][1] == 0xffffffff)
? 0:(SD(HBA_ptr)->reads_lat[x][1] * 10),
SD(HBA_ptr)->reads_lat[x][2] * 10,
SD(HBA_ptr)->reads_lat[x][3] * 10 /
((SD(HBA_ptr)->reads_lat[x][0])
? SD(HBA_ptr)->reads_lat[x][0]:1));
len += size;
pos = begin + len;
}
size = sprintf(buffer+len,">1024k:%12u %12u %12u %12u\n",
SD(HBA_ptr)->reads_lat[11][0],
(SD(HBA_ptr)->reads_lat[11][1] == 0xffffffff)
? 0:(SD(HBA_ptr)->reads_lat[11][1] * 10),
SD(HBA_ptr)->reads_lat[11][2] * 10,
SD(HBA_ptr)->reads_lat[11][3] * 10 /
((SD(HBA_ptr)->reads_lat[x][0])
? SD(HBA_ptr)->reads_lat[x][0]:1));
len += size;
pos = begin + len;
if (pos < offset) {
len = 0;
begin = pos;
}
if (pos > offset + length)
goto stop_output;
size = sprintf(buffer + len,
" Writes: Min:(ms) Max:(ms) Ave:(ms)\n");
len += size;
pos = begin + len;
for (x = 0; x <= 10; x++) {
size = sprintf(buffer+len,"%5dk:%12u %12u %12u %12u\n",
1 << x,
SD(HBA_ptr)->writes_lat[x][0],
(SD(HBA_ptr)->writes_lat[x][1] == 0xffffffff)
? 0:(SD(HBA_ptr)->writes_lat[x][1] * 10),
SD(HBA_ptr)->writes_lat[x][2] * 10,
SD(HBA_ptr)->writes_lat[x][3] * 10 /
((SD(HBA_ptr)->writes_lat[x][0])
? SD(HBA_ptr)->writes_lat[x][0]:1));
len += size;
pos = begin + len;
}
size = sprintf(buffer+len,">1024k:%12u %12u %12u %12u\n",
SD(HBA_ptr)->writes_lat[11][0],
(SD(HBA_ptr)->writes_lat[11][1] == 0xffffffff)
? 0:(SD(HBA_ptr)->writes_lat[x][1] * 10),
SD(HBA_ptr)->writes_lat[11][2] * 10,
SD(HBA_ptr)->writes_lat[11][3] * 10/
((SD(HBA_ptr)->writes_lat[x][0])
? SD(HBA_ptr)->writes_lat[x][0]:1));
len += size;
pos = begin + len;
if (pos < offset) {
len = 0;
begin = pos;
}
if (pos > offset + length)
goto stop_output;
}
scd = scsi_devices; scd = scsi_devices;
size = sprintf(buffer+len,"Attached devices: %s\n", (scd)?"":"none"); size = sprintf(buffer+len,"Attached devices: %s\n", (scd)?"":"none");
...@@ -350,7 +439,8 @@ int eata_proc_info(char *buffer, char **start, off_t offset, int length, ...@@ -350,7 +439,8 @@ int eata_proc_info(char *buffer, char **start, off_t offset, int length,
while (scd) { while (scd) {
if (scd->host == HBA_ptr) { if (scd->host == HBA_ptr) {
size = sprintf(buffer + len, "Channel: %02d Id: %02d Lun: %02d\n Vendor: ", size = sprintf(buffer + len,
"Channel: %02d Id: %02d Lun: %02d\n Vendor: ",
scd->channel, scd->id, scd->lun); scd->channel, scd->id, scd->lun);
for (x = 0; x < 8; x++) { for (x = 0; x < 8; x++) {
if (scd->vendor[x] >= 0x20) if (scd->vendor[x] >= 0x20)
......
...@@ -77,7 +77,7 @@ ...@@ -77,7 +77,7 @@
#define CD(cmd) ((struct eata_ccb *)(cmd->host_scribble)) #define CD(cmd) ((struct eata_ccb *)(cmd->host_scribble))
#define SD(host) ((hostdata *)&(host->hostdata)) #define SD(host) ((hostdata *)&(host->hostdata))
#define DELAY(x) { __u32 i; i = jiffies + x; while (jiffies < i); } #define DELAY(x) { __u32 i; i = jiffies + (x * HZ); while (jiffies < i) barrier(); }
#define DEL2(x) { __u32 i; for (i = 0; i < 0xffff * x; i++); } #define DEL2(x) { __u32 i; for (i = 0; i < 0xffff * x; i++); }
/*********************************************** /***********************************************
...@@ -203,22 +203,22 @@ struct get_conf { /* Read Configuration Array */ ...@@ -203,22 +203,22 @@ struct get_conf { /* Read Configuration Array */
version:4; /* EATA Version level */ version:4; /* EATA Version level */
__u8 OCS_enabled:1, /* Overlap Command Support enabled */ __u8 OCS_enabled:1, /* Overlap Command Support enabled */
TAR_support:1, /* SCSI Target Mode supported */ TAR_support:1, /* SCSI Target Mode supported */
TRNXFR:1, /* Truncate Transfer Cmd not necessary */ TRNXFR:1, /* Truncate Transfer Cmd not necessary *
/* Only used in PIO Mode */ * Only used in PIO Mode */
MORE_support:1, /* MORE supported (only PIO Mode) */ MORE_support:1, /* MORE supported (only PIO Mode) */
DMA_support:1, /* DMA supported Driver uses only */ DMA_support:1, /* DMA supported Driver uses only *
/* this mode */ * this mode */
DMA_valid:1, /* DRQ value in Byte 30 is valid */ DMA_valid:1, /* DRQ value in Byte 30 is valid */
ATA:1, /* ATA device connected (not supported) */ ATA:1, /* ATA device connected (not supported) */
HAA_valid:1; /* Hostadapter Address is valid */ HAA_valid:1; /* Hostadapter Address is valid */
__u16 cppadlen; /* Number of pad bytes send after CD data */ __u16 cppadlen; /* Number of pad bytes send after CD data *
/* set to zero for DMA commands */ * set to zero for DMA commands */
__u8 scsi_id[4]; /* SCSI ID of controller 2-0 Byte 0 res. */ __u8 scsi_id[4]; /* SCSI ID of controller 2-0 Byte 0 res. *
/* if not, zero is returned */ * if not, zero is returned */
__u32 cplen; /* CP length: number of valid cp bytes */ __u32 cplen; /* CP length: number of valid cp bytes */
__u32 splen; /* Number of bytes returned after */ __u32 splen; /* Number of bytes returned after *
/* Receive SP command */ * Receive SP command */
__u16 queuesiz; /* max number of queueable CPs */ __u16 queuesiz; /* max number of queueable CPs */
__u16 dummy; __u16 dummy;
__u16 SGsiz; /* max number of SG table entries */ __u16 SGsiz; /* max number of SG table entries */
...@@ -226,8 +226,8 @@ struct get_conf { /* Read Configuration Array */ ...@@ -226,8 +226,8 @@ struct get_conf { /* Read Configuration Array */
IRQ_TR:1, /* IRQ Trigger: 0=edge, 1=level */ IRQ_TR:1, /* IRQ Trigger: 0=edge, 1=level */
SECOND:1, /* This is a secondary controller */ SECOND:1, /* This is a secondary controller */
DMA_channel:2; /* DRQ index, DRQ is 2comp of DRQX */ DMA_channel:2; /* DRQ index, DRQ is 2comp of DRQX */
__u8 sync; /* device at ID 7 tru 0 is running in */ __u8 sync; /* device at ID 7 tru 0 is running in *
/* synchronous mode, this will disappear */ * synchronous mode, this will disappear */
__u8 DSBLE:1, /* ISA i/o addressing is disabled */ __u8 DSBLE:1, /* ISA i/o addressing is disabled */
FORCADR:1, /* i/o address has been forced */ FORCADR:1, /* i/o address has been forced */
SG_64K:1, SG_64K:1,
...@@ -261,10 +261,10 @@ struct eata_ccb { /* Send Command Packet structure */ ...@@ -261,10 +261,10 @@ struct eata_ccb { /* Send Command Packet structure */
Interpret:1, /* Interpret the SCSI cdb of own use */ Interpret:1, /* Interpret the SCSI cdb of own use */
DataOut:1, /* Data Out phase with command */ DataOut:1, /* Data Out phase with command */
DataIn:1; /* Data In phase with command */ DataIn:1; /* Data In phase with command */
__u8 reqlen; /* Request Sense Length */ __u8 reqlen; /* Request Sense Length *
/* Valid if Auto_Req_Sen=1 */ * Valid if Auto_Req_Sen=1 */
__u8 unused[3]; __u8 unused[3];
__u8 FWNEST:1, /* send cmd to phys RAID component*/ __u8 FWNEST:1, /* send cmd to phys RAID component */
unused2:7; unused2:7;
__u8 Phsunit:1, /* physical unit on mirrored pair */ __u8 Phsunit:1, /* physical unit on mirrored pair */
I_AT:1, /* inhibit address translation */ I_AT:1, /* inhibit address translation */
...@@ -282,19 +282,21 @@ struct eata_ccb { /* Send Command Packet structure */ ...@@ -282,19 +282,21 @@ struct eata_ccb { /* Send Command Packet structure */
__u8 cp_msg2; __u8 cp_msg2;
__u8 cp_msg3; __u8 cp_msg3;
__u8 cp_cdb[12]; /* Command Descriptor Block */ __u8 cp_cdb[12]; /* Command Descriptor Block */
__u32 cp_datalen; /* Data Transfer Length */ __u32 cp_datalen; /* Data Transfer Length *
/* If scatter=1 len of sg package */ * If scatter=1 len of sg package */
void *cp_viraddr; /* address of this ccb */ void *cp_viraddr; /* address of this ccb */
__u32 cp_dataDMA; /* Data Address, if scatter=1 * __u32 cp_dataDMA; /* Data Address, if scatter=1 *
* address of scatter packet */ * address of scatter packet */
__u32 cp_statDMA; /* address for Status Packet */ __u32 cp_statDMA; /* address for Status Packet */
__u32 cp_reqDMA; /* Request Sense Address, used if */ __u32 cp_reqDMA; /* Request Sense Address, used if *
/* CP command ends with error */ * CP command ends with error */
/* Additional CP info begins here */ /* Additional CP info begins here */
__u32 timestamp; /* Needed to measure command latency */
__u32 timeout; __u32 timeout;
__u8 sizeindex;
__u8 rw_latency;
__u8 retries; __u8 retries;
__u8 status; /* status of this queueslot */ __u8 status; /* status of this queueslot */
Scsi_Cmnd *cmd; /* address of cmd */ Scsi_Cmnd *cmd; /* address of cmd */
struct eata_sg_list *sg_list; struct eata_sg_list *sg_list;
}; };
...@@ -321,8 +323,11 @@ typedef struct hstd { ...@@ -321,8 +323,11 @@ typedef struct hstd {
__u8 primary; /* true if primary */ __u8 primary; /* true if primary */
__u8 broken_INQUIRY:1; /* This is an EISA HBA with * __u8 broken_INQUIRY:1; /* This is an EISA HBA with *
* broken INQUIRY */ * broken INQUIRY */
__u8 do_latency; /* Latency measurement flag */
__u32 reads[13]; __u32 reads[13];
__u32 writes[13]; __u32 writes[13];
__u32 reads_lat[12][4];
__u32 writes_lat[12][4];
/* state of Target (RESET,..) */ /* state of Target (RESET,..) */
__u8 t_state[MAXCHANNEL][MAXTARGET]; __u8 t_state[MAXCHANNEL][MAXTARGET];
/* timeouts on target */ /* timeouts on target */
...@@ -372,7 +377,6 @@ struct geom_emul { ...@@ -372,7 +377,6 @@ struct geom_emul {
* c-label-offset: -4 * c-label-offset: -4
* c-continued-statement-offset: 4 * c-continued-statement-offset: 4
* c-continued-brace-offset: 0 * c-continued-brace-offset: 0
* indent-tabs-mode: nil
* tab-width: 8 * tab-width: 8
* End: * End:
*/ */
...@@ -32,7 +32,7 @@ ...@@ -32,7 +32,7 @@
* Cambridge, MA 02139, USA. * * Cambridge, MA 02139, USA. *
* * * *
************************************************************ ************************************************************
* last change: 95/06/20 OS: Linux 1.3.3 + pre1.3 SCSI pat.* * last change: 95/07/13 OS: Linux 1.3.9 *
************************************************************/ ************************************************************/
/* Look in eata_pio.h for configuration information */ /* Look in eata_pio.h for configuration information */
...@@ -504,7 +504,7 @@ int eata_pio_reset(Scsi_Cmnd * cmd) ...@@ -504,7 +504,7 @@ int eata_pio_reset(Scsi_Cmnd * cmd)
HD(cmd)->state = RESET; HD(cmd)->state = RESET;
time = jiffies; time = jiffies;
while (jiffies < (time + 300) && limit++ < 10000000); while (jiffies < (time + (3 * HZ)) && limit++ < 10000000);
DBG(DBG_ABNORM, printk("eata_pio_reset: interrupts disabled, loops %d.\n", limit)); DBG(DBG_ABNORM, printk("eata_pio_reset: interrupts disabled, loops %d.\n", limit));
DBG(DBG_ABNORM && DBG_DELAY, DEL2(500)); DBG(DBG_ABNORM && DBG_DELAY, DEL2(500));
...@@ -650,7 +650,7 @@ void print_pio_config(struct get_conf *gc) ...@@ -650,7 +650,7 @@ void print_pio_config(struct get_conf *gc)
printk("IRQ:%d IRQT:%d FORCADR:%d MCH:%d RIDQ:%d\n", printk("IRQ:%d IRQT:%d FORCADR:%d MCH:%d RIDQ:%d\n",
gc->IRQ, gc->IRQ_TR, gc->FORCADR, gc->IRQ, gc->IRQ_TR, gc->FORCADR,
gc->MAX_CHAN, gc->ID_qest); gc->MAX_CHAN, gc->ID_qest);
DBG(DPT_DEBUG, DELAY(1400)); DBG(DPT_DEBUG, DELAY(14));
} }
static uint print_selftest(uint base) static uint print_selftest(uint base)
...@@ -1014,7 +1014,7 @@ int eata_pio_detect(Scsi_Host_Template * tpnt) ...@@ -1014,7 +1014,7 @@ int eata_pio_detect(Scsi_Host_Template * tpnt)
HBA_ptr = SD(HBA_ptr)->next; HBA_ptr = SD(HBA_ptr)->next;
} }
} }
DBG(DPT_DEBUG,DELAY(1200)); DBG(DPT_DEBUG,DELAY(12));
return (registered_HBAs); return (registered_HBAs);
} }
......
...@@ -80,6 +80,7 @@ ...@@ -80,6 +80,7 @@
#define LOG_SENSE 0x4d #define LOG_SENSE 0x4d
#define MODE_SELECT_10 0x55 #define MODE_SELECT_10 0x55
#define MODE_SENSE_10 0x5a #define MODE_SENSE_10 0x5a
#define READ_12 0xa8
#define WRITE_12 0xaa #define WRITE_12 0xaa
#define WRITE_VERIFY_12 0xae #define WRITE_VERIFY_12 0xae
#define SEARCH_HIGH_12 0xb0 #define SEARCH_HIGH_12 0xb0
......
...@@ -30,7 +30,7 @@ ...@@ -30,7 +30,7 @@
#include "sound_config.h" #include "sound_config.h"
#if defined(CONFIGURE_SOUNDCARD) && !defined(EXCLUDE_GUS) #if defined(CONFIGURE_SOUNDCARD) && !defined(EXCLUDE_GUS)
#include "ultrasound.h" #include <linux/ultrasound.h>
#include "gus_hw.h" #include "gus_hw.h"
#define MIX_DEVS (SOUND_MASK_MIC|SOUND_MASK_LINE| \ #define MIX_DEVS (SOUND_MASK_MIC|SOUND_MASK_LINE| \
......
...@@ -7,6 +7,10 @@ ...@@ -7,6 +7,10 @@
* *
* Modularised by Alan Cox <Alan.Cox@linux.org>, while hacking some * Modularised by Alan Cox <Alan.Cox@linux.org>, while hacking some
* experimental NFS changes. Modularisation taken straight from SYS5 fs. * experimental NFS changes. Modularisation taken straight from SYS5 fs.
*
* Change to nfs_read_super() to permit NFS mounts to multi-homed hosts.
* J.S.Peatfield@damtp.cam.ac.uk
*
*/ */
#ifdef MODULE #ifdef MODULE
...@@ -76,6 +80,7 @@ struct super_block *nfs_read_super(struct super_block *sb, void *raw_data, ...@@ -76,6 +80,7 @@ struct super_block *nfs_read_super(struct super_block *sb, void *raw_data,
struct nfs_server *server; struct nfs_server *server;
unsigned int fd; unsigned int fd;
struct file *filp; struct file *filp;
dev_t dev = sb->s_dev; dev_t dev = sb->s_dev;
MOD_INC_USE_COUNT; MOD_INC_USE_COUNT;
...@@ -104,6 +109,7 @@ struct super_block *nfs_read_super(struct super_block *sb, void *raw_data, ...@@ -104,6 +109,7 @@ struct super_block *nfs_read_super(struct super_block *sb, void *raw_data,
} }
filp->f_count++; filp->f_count++;
lock_super(sb); lock_super(sb);
sb->s_blocksize = 1024; /* XXX */ sb->s_blocksize = 1024; /* XXX */
sb->s_blocksize_bits = 10; sb->s_blocksize_bits = 10;
sb->s_magic = NFS_SUPER_MAGIC; sb->s_magic = NFS_SUPER_MAGIC;
...@@ -131,6 +137,31 @@ struct super_block *nfs_read_super(struct super_block *sb, void *raw_data, ...@@ -131,6 +137,31 @@ struct super_block *nfs_read_super(struct super_block *sb, void *raw_data,
server->acdirmin = data->acdirmin*HZ; server->acdirmin = data->acdirmin*HZ;
server->acdirmax = data->acdirmax*HZ; server->acdirmax = data->acdirmax*HZ;
strcpy(server->hostname, data->hostname); strcpy(server->hostname, data->hostname);
/* Start of JSP NFS patch */
/* Check if passed address in data->addr */
if (data->addr.sin_addr.s_addr == INADDR_ANY) { /* No address passed */
if (((struct sockaddr_in *)(&server->toaddr))->sin_addr.s_addr == INADDR_ANY) {
printk("NFS: Error passed unconnected socket and no address\n") ;
return NULL ;
} else {
/* Need access to socket internals JSP */
struct socket *sock;
int dummylen ;
/* printk("NFS: using socket address\n") ;*/
sock = &((filp->f_inode)->u.socket_i);
/* extract the other end of the socket into server->toaddr */
sock->ops->getname(sock, &(server->toaddr), &dummylen, 1) ;
}
} else {
/* printk("NFS: coppying passed addr to server->toaddr\n") ;*/
memcpy((char *)&(server->toaddr),(char *)(&data->addr),sizeof(server->toaddr));
}
/* End of JSP NFS patch */
sb->u.nfs_sb.s_root = data->root; sb->u.nfs_sb.s_root = data->root;
unlock_super(sb); unlock_super(sb);
if (!(sb->s_mounted = nfs_fhget(sb, &data->root, NULL))) { if (!(sb->s_mounted = nfs_fhget(sb, &data->root, NULL))) {
......
...@@ -102,7 +102,10 @@ static int do_nfs_rpc_call(struct nfs_server *server, int *start, int *end, int ...@@ -102,7 +102,10 @@ static int do_nfs_rpc_call(struct nfs_server *server, int *start, int *end, int
fs = get_fs(); fs = get_fs();
set_fs(get_ds()); set_fs(get_ds());
for (n = 0, timeout = init_timeout; ; n++, timeout <<= 1) { for (n = 0, timeout = init_timeout; ; n++, timeout <<= 1) {
result = sock->ops->send(sock, (void *) start, len, 0, 0); /* JSP 1995-07-01 Use sendto() not send() to cope with multi-homed hosts
as we have set the socket to have INADDR_ANY as it's desination */
result = sock->ops->sendto(sock, (void *) start, len, 0, 0,
&(server->toaddr), sizeof((server->toaddr))) ;
if (result < 0) { if (result < 0) {
printk("nfs_rpc_call: send error = %d\n", result); printk("nfs_rpc_call: send error = %d\n", result);
break; break;
......
...@@ -85,7 +85,7 @@ __old_ipl; }) ...@@ -85,7 +85,7 @@ __old_ipl; })
#define save_flags(flags) do { flags = getipl(); } while (0) #define save_flags(flags) do { flags = getipl(); } while (0)
#define restore_flags(flags) setipl(flags) #define restore_flags(flags) setipl(flags)
extern inline unsigned long xchg_u32(int * m, unsigned long val) extern inline unsigned long xchg_u32(volatile int * m, unsigned long val)
{ {
unsigned long dummy, dummy2; unsigned long dummy, dummy2;
...@@ -100,7 +100,7 @@ extern inline unsigned long xchg_u32(int * m, unsigned long val) ...@@ -100,7 +100,7 @@ extern inline unsigned long xchg_u32(int * m, unsigned long val)
return val; return val;
} }
extern inline unsigned long xchg_u64(long * m, unsigned long val) extern inline unsigned long xchg_u64(volatile long * m, unsigned long val)
{ {
unsigned long dummy, dummy2; unsigned long dummy, dummy2;
...@@ -115,9 +115,19 @@ extern inline unsigned long xchg_u64(long * m, unsigned long val) ...@@ -115,9 +115,19 @@ extern inline unsigned long xchg_u64(long * m, unsigned long val)
return val; return val;
} }
extern inline void * xchg_ptr(void *m, void *val) #define xchg(ptr,x) ((__typeof__(*(ptr)))__xchg((unsigned long)(x),(ptr),sizeof(*(ptr))))
#define tas(ptr) (xchg((ptr),1))
static inline unsigned long __xchg(unsigned long x, volatile void * ptr, int size)
{ {
return (void *) xchg_u64((long *) m, (unsigned long) val); switch (size) {
case 4:
return xchg_u32(ptr, x);
case 8:
return xchg_u64(ptr, x);
}
printk("Argh.. xchg() with unsupported size\n");
return x;
} }
#endif /* __ASSEMBLY__ */ #endif /* __ASSEMBLY__ */
......
...@@ -8,6 +8,123 @@ ...@@ -8,6 +8,123 @@
* yet. I'll have to see about this later.. * yet. I'll have to see about this later..
*/ */
#define __NR_exit 1
#define __NR_fork 2
#define __NR_read 3
#define __NR_write 4
#define __NR_close 6
#define __NR_wait4 7
#define __NR_link 9
#define __NR_unlink 10
#define __NR_chdir 12
#define __NR_fchdir 13
#define __NR_mknod 14
#define __NR_chmod 15
#define __NR_chown 16
#define __NR_brk 17
#define __NR_lseek 19
#define __NR_getxpid 20
#define __NR_setuid 23
#define __NR_getxuid 24
#define __NR_ptrace 26
#define __NR_access 33
#define __NR_sync 36
#define __NR_kill 37
#define __NR_setpgid 39
#define __NR_dup 41
#define __NR_pipe 42
#define __NR_open 45
#define __NR_getxgid 47
#define __NR_ioctl 54
#define __NR_symlink 57
#define __NR_readlink 58
#define __NR_execve 59
#define __NR_umask 60
#define __NR_getpgrp 63
#define __NR_getpagesize 64
#define __NR_stat 67
#define __NR_lstat 68
#define __NR_munmap 73
#define __NR_mprotect 74
#define __NR_madvise 75
#define __NR_vhangup 76
#define __NR_getgroups 79
#define __NR_setgroups 80
#define __NR_setpgid 82
#define __NR_setitimer 83
#define __NR_getitimer 86
#define __NR_gethostname 87
#define __NR_sethostname 88
#define __NR_getdtablesize 89
#define __NR_dup2 90
#define __NR_fstat 91
#define __NR_fcntl 92
#define __NR_select 93
#define __NR_fsync 95
#define __NR_setpriority 96
#define __NR_socket 97
#define __NR_connect 98
#define __NR_accept 99
#define __NR_getpriority 100
#define __NR_send 101
#define __NR_recv 102
#define __NR_sigreturn 103
#define __NR_bind 104
#define __NR_setsockopt 105
#define __NR_listen 106
#define __NR_sigsuspend 111
#define __NR_gettimeofday 116
#define __NR_getrusage 117
#define __NR_getsockopt 118
#define __NR_settimeofday 122
#define __NR_fchown 123
#define __NR_fchmod 124
#define __NR_recvfrom 125
#define __NR_setreuid 126
#define __NR_setregid 127
#define __NR_rename 128
#define __NR_truncate 129
#define __NR_ftruncate 130
#define __NR_setgid 132
#define __NR_sendto 133
#define __NR_shutdown 134
#define __NR_socketpair 135
#define __NR_mkdir 136
#define __NR_rmdir 137
#define __NR_utimes 138
#define __NR_getpeername 141
#define __NR_getrlimit 144
#define __NR_setrlimit 145
#define __NR_setsid 147
#define __NR_getsockname 150
#define __NR_sigaction 156
#define __NR_msgctl 200
#define __NR_msgget 201
#define __NR_msgrcv 202
#define __NR_msgsnd 203
#define __NR_semctl 204
#define __NR_semget 205
#define __NR_semop 206
#define __NR_shmctl 210
#define __NR_shmdt 211
#define __NR_shmget 212
/*
* Linux-specific system calls begin at 300
*/
#define __NR_bdflush 300
#define __NR_sethae 301
#define __NR_mount 302
#define __NR_adjtimex 303
#define __NR_swapoff 304
#define __NR_getdents 305
#define __NR_create_module 306
#define __NR_init_module 307
#define __NR_delete_module 308
#define __NR_get_kernel_syms 309
#define __NR_syslog 310
#ifdef __LIBRARY__ #ifdef __LIBRARY__
/* XXX - _foo needs to be __foo, while __NR_bar could be _NR_bar. */ /* XXX - _foo needs to be __foo, while __NR_bar could be _NR_bar. */
......
...@@ -138,32 +138,32 @@ __asm__ __volatile__ ( \ ...@@ -138,32 +138,32 @@ __asm__ __volatile__ ( \
:"ax") :"ax")
extern inline unsigned long xchg_u8(char * m, unsigned long val) #define xchg(ptr,x) ((__typeof__(*(ptr)))__xchg((unsigned long)(x),(ptr),sizeof(*(ptr))))
{ #define tas(ptr) (xchg((ptr),1))
__asm__("xchgb %b0,%1":"=q" (val),"=m" (*m):"0" (val):"memory");
return val;
}
extern inline unsigned long xchg_u16(short * m, unsigned long val)
{
__asm__("xchgw %w0,%1":"=r" (val),"=m" (*m):"0" (val):"memory");
return val;
}
extern inline unsigned long xchg_u32(int * m, unsigned long val) struct __xchg_dummy { unsigned long a[100]; };
{ #define __xg(x) ((volatile struct __xchg_dummy *)(x))
__asm__("xchgl %0,%1":"=r" (val),"=m" (*m):"0" (val):"memory");
return val;
}
extern inline int tas(char * m)
{
return xchg_u8(m,1);
}
extern inline void * xchg_ptr(void * m, void * val) static inline unsigned long __xchg(unsigned long x, volatile void * ptr, int size)
{ {
return (void *) xchg_u32(m, (unsigned long) val); switch (size) {
case 1:
__asm__("xchgb %b0,%1"
:"=q" (x), "=m" (*__xg(ptr))
:"0" (x), "m" (*__xg(ptr)));
break;
case 2:
__asm__("xchgw %w0,%1"
:"=r" (x), "=m" (*__xg(ptr))
:"0" (x), "m" (*__xg(ptr)));
break;
case 4:
__asm__("xchgl %0,%1"
:"=r" (x), "=m" (*__xg(ptr))
:"0" (x), "m" (*__xg(ptr)));
break;
}
return x;
} }
#define mb() __asm__ __volatile__ ("" : : :"memory") #define mb() __asm__ __volatile__ ("" : : :"memory")
......
#ifndef _ASM_I386_UNISTD_H_ #ifndef _ASM_I386_UNISTD_H_
#define _ASM_I386_UNISTD_H_ #define _ASM_I386_UNISTD_H_
/*
* This file contains the system call numbers.
*/
#define __NR_setup 0 /* used only by init, to get system going */
#define __NR_exit 1
#define __NR_fork 2
#define __NR_read 3
#define __NR_write 4
#define __NR_open 5
#define __NR_close 6
#define __NR_waitpid 7
#define __NR_creat 8
#define __NR_link 9
#define __NR_unlink 10
#define __NR_execve 11
#define __NR_chdir 12
#define __NR_time 13
#define __NR_mknod 14
#define __NR_chmod 15
#define __NR_chown 16
#define __NR_break 17
#define __NR_oldstat 18
#define __NR_lseek 19
#define __NR_getpid 20
#define __NR_mount 21
#define __NR_umount 22
#define __NR_setuid 23
#define __NR_getuid 24
#define __NR_stime 25
#define __NR_ptrace 26
#define __NR_alarm 27
#define __NR_oldfstat 28
#define __NR_pause 29
#define __NR_utime 30
#define __NR_stty 31
#define __NR_gtty 32
#define __NR_access 33
#define __NR_nice 34
#define __NR_ftime 35
#define __NR_sync 36
#define __NR_kill 37
#define __NR_rename 38
#define __NR_mkdir 39
#define __NR_rmdir 40
#define __NR_dup 41
#define __NR_pipe 42
#define __NR_times 43
#define __NR_prof 44
#define __NR_brk 45
#define __NR_setgid 46
#define __NR_getgid 47
#define __NR_signal 48
#define __NR_geteuid 49
#define __NR_getegid 50
#define __NR_acct 51
#define __NR_phys 52
#define __NR_lock 53
#define __NR_ioctl 54
#define __NR_fcntl 55
#define __NR_mpx 56
#define __NR_setpgid 57
#define __NR_ulimit 58
#define __NR_oldolduname 59
#define __NR_umask 60
#define __NR_chroot 61
#define __NR_ustat 62
#define __NR_dup2 63
#define __NR_getppid 64
#define __NR_getpgrp 65
#define __NR_setsid 66
#define __NR_sigaction 67
#define __NR_sgetmask 68
#define __NR_ssetmask 69
#define __NR_setreuid 70
#define __NR_setregid 71
#define __NR_sigsuspend 72
#define __NR_sigpending 73
#define __NR_sethostname 74
#define __NR_setrlimit 75
#define __NR_getrlimit 76
#define __NR_getrusage 77
#define __NR_gettimeofday 78
#define __NR_settimeofday 79
#define __NR_getgroups 80
#define __NR_setgroups 81
#define __NR_select 82
#define __NR_symlink 83
#define __NR_oldlstat 84
#define __NR_readlink 85
#define __NR_uselib 86
#define __NR_swapon 87
#define __NR_reboot 88
#define __NR_readdir 89
#define __NR_mmap 90
#define __NR_munmap 91
#define __NR_truncate 92
#define __NR_ftruncate 93
#define __NR_fchmod 94
#define __NR_fchown 95
#define __NR_getpriority 96
#define __NR_setpriority 97
#define __NR_profil 98
#define __NR_statfs 99
#define __NR_fstatfs 100
#define __NR_ioperm 101
#define __NR_socketcall 102
#define __NR_syslog 103
#define __NR_setitimer 104
#define __NR_getitimer 105
#define __NR_stat 106
#define __NR_lstat 107
#define __NR_fstat 108
#define __NR_olduname 109
#define __NR_iopl 110
#define __NR_vhangup 111
#define __NR_idle 112
#define __NR_vm86 113
#define __NR_wait4 114
#define __NR_swapoff 115
#define __NR_sysinfo 116
#define __NR_ipc 117
#define __NR_fsync 118
#define __NR_sigreturn 119
#define __NR_clone 120
#define __NR_setdomainname 121
#define __NR_uname 122
#define __NR_modify_ldt 123
#define __NR_adjtimex 124
#define __NR_mprotect 125
#define __NR_sigprocmask 126
#define __NR_create_module 127
#define __NR_init_module 128
#define __NR_delete_module 129
#define __NR_get_kernel_syms 130
#define __NR_quotactl 131
#define __NR_getpgid 132
#define __NR_fchdir 133
#define __NR_bdflush 134
#define __NR_sysfs 135
#define __NR_personality 136
#define __NR_afs_syscall 137 /* Syscall for Andrew File System */
#define __NR_setfsuid 138
#define __NR_setfsgid 139
#define __NR__llseek 140
#define __NR_getdents 141
#define __NR__newselect 142
#define __NR_flock 143
/* XXX - _foo needs to be __foo, while __NR_bar could be _NR_bar. */ /* XXX - _foo needs to be __foo, while __NR_bar could be _NR_bar. */
#define _syscall0(type,name) \ #define _syscall0(type,name) \
type name(void) \ type name(void) \
......
...@@ -275,7 +275,7 @@ extern inline long find_in_swap_cache (unsigned long addr) ...@@ -275,7 +275,7 @@ extern inline long find_in_swap_cache (unsigned long addr)
#ifdef SWAP_CACHE_INFO #ifdef SWAP_CACHE_INFO
swap_cache_find_total++; swap_cache_find_total++;
#endif #endif
entry = (unsigned long) xchg_ptr(swap_cache + MAP_NR(addr), NULL); entry = xchg(swap_cache + MAP_NR(addr), 0);
#ifdef SWAP_CACHE_INFO #ifdef SWAP_CACHE_INFO
if (entry) if (entry)
swap_cache_find_success++; swap_cache_find_success++;
...@@ -290,7 +290,7 @@ extern inline int delete_from_swap_cache(unsigned long addr) ...@@ -290,7 +290,7 @@ extern inline int delete_from_swap_cache(unsigned long addr)
#ifdef SWAP_CACHE_INFO #ifdef SWAP_CACHE_INFO
swap_cache_del_total++; swap_cache_del_total++;
#endif #endif
entry= (unsigned long) xchg_ptr(swap_cache + MAP_NR(addr), NULL); entry= xchg(swap_cache + MAP_NR(addr), 0);
if (entry) { if (entry) {
#ifdef SWAP_CACHE_INFO #ifdef SWAP_CACHE_INFO
swap_cache_del_success++; swap_cache_del_success++;
......
...@@ -31,7 +31,11 @@ ...@@ -31,7 +31,11 @@
/* for future expansion when we will have different priorities. */ /* for future expansion when we will have different priorities. */
#define DEV_NUMBUFFS 3 #define DEV_NUMBUFFS 3
#define MAX_ADDR_LEN 7 #define MAX_ADDR_LEN 7
#define MAX_HEADER 38 #ifndef CONFIG_AX25
#define MAX_HEADER 32 /* We really need about 18 worst case .. so 32 is aligned */
#else
#define MAX_HEADER 96 /* AX.25 + NetROM */
#endif
#define IS_MYADDR 1 /* address is (one of) our own */ #define IS_MYADDR 1 /* address is (one of) our own */
#define IS_LOOPBACK 2 /* address is for LOOPBACK */ #define IS_LOOPBACK 2 /* address is for LOOPBACK */
...@@ -73,12 +77,12 @@ struct device ...@@ -73,12 +77,12 @@ struct device
unsigned long mem_end; /* sahared mem end */ unsigned long mem_end; /* sahared mem end */
unsigned long mem_start; /* shared mem start */ unsigned long mem_start; /* shared mem start */
unsigned long base_addr; /* device I/O address */ unsigned long base_addr; /* device I/O address */
unsigned long tbusy; /* transmitter busy must be long for bitops */
unsigned char irq; /* device IRQ number */ unsigned char irq; /* device IRQ number */
/* Low-level status flags. */ /* Low-level status flags. */
volatile unsigned char start, /* start an operation */ volatile unsigned char start, /* start an operation */
interrupt; /* interrupt arrived */ interrupt; /* interrupt arrived */
unsigned long tbusy; /* transmitter busy must be long for bitops */
struct device *next; struct device *next;
......
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
struct nfs_server { struct nfs_server {
struct file *file; struct file *file;
struct sockaddr toaddr ; /* Added for change to NFS code to use sendto() 1995-06-02 JSP */
int lock; int lock;
struct wait_queue *wait; struct wait_queue *wait;
int flags; int flags;
......
/* $Id: scc.h,v 1.9 1995/01/12 18:24:40 JReuter Exp JReuter $ */
#ifndef _SCC_H #ifndef _SCC_H
#define _SCC_H #define _SCC_H
...@@ -15,9 +14,9 @@ ...@@ -15,9 +14,9 @@
/* Constants */ /* Constants */
#define MAXSCC 4 /* number of max. supported chips */ #define MAXSCC 4 /* number of max. supported chips */
#define MAX_IBUFS 200 /* change this if you run out of memory */ #define MAX_IBUFS 300 /* change this if you run out of memory */
#define BUFSIZE 128 /* must not exceed 4096 */ #define BUFSIZE 64 /* must not exceed 4096 */
#define TPS 25 /* scc_timer(): Ticks Per Second */ #define TPS 25 /* scc_timer(): 25 Ticks Per Second */
#define SCC_TIMER 3 #define SCC_TIMER 3
...@@ -134,14 +133,12 @@ typedef unsigned short ioaddr; /* old def */ ...@@ -134,14 +133,12 @@ typedef unsigned short ioaddr; /* old def */
/* Basic message buffer structure */ /* Basic message buffer structure */
/* looks familiar? Hmm, yes... */
struct mbuf { struct mbuf {
struct mbuf *next; /* Links mbufs belonging to single packets */ struct mbuf *next; /* Links mbufs belonging to single packets */
struct mbuf *anext; /* Links packets on queues */ struct mbuf *anext; /* Links packets on queues */
char type; /* who allocated this buffer? */ char type; /* who allocated this buffer? */
int time_out; /* unimplemented yet */ unsigned long time_out;/* buffer time out */
int size; /* Size of associated data buffer */ int size; /* Size of associated data buffer */
int refcnt; /* Reference count */ int refcnt; /* Reference count */
...@@ -240,9 +237,8 @@ struct scc_channel { ...@@ -240,9 +237,8 @@ struct scc_channel {
struct scc_stat stat; /* statistical information */ struct scc_stat stat; /* statistical information */
struct scc_modem modem; /* modem information */ struct scc_modem modem; /* modem information */
struct mbuf *rbp; /* rx: Head of mbuf chain being filled */ char rxbuf[2048]; /* Rx frame buffer max framesize * 2 */
struct mbuf *rbp1; /* rx: Pointer to mbuf currently being written */ int rxbufcnt; /* Rx frame counter */
struct mbuf *rcvq; /* Pointer to mbuf packets currently received */
struct mbuf *sndq; /* tx: Packets awaiting transmission */ struct mbuf *sndq; /* tx: Packets awaiting transmission */
struct mbuf *tbp; /* tx: Transmit mbuf being sent */ struct mbuf *tbp; /* tx: Transmit mbuf being sent */
...@@ -250,6 +246,10 @@ struct scc_channel { ...@@ -250,6 +246,10 @@ struct scc_channel {
struct mbuf *sndq1; /* Pointer to mbuf currently under construction */ struct mbuf *sndq1; /* Pointer to mbuf currently under construction */
struct mbuf *sndq2; /* Pointer to mbuf currently under construction */ struct mbuf *sndq2; /* Pointer to mbuf currently under construction */
/* unsigned char *xmit_buf;
int xmit_head;
int xmit_tail;
int xmit_cnt;*/
/* Timer */ /* Timer */
......
...@@ -61,6 +61,7 @@ extern int nr_running, nr_tasks; ...@@ -61,6 +61,7 @@ extern int nr_running, nr_tasks;
#include <linux/vm86.h> #include <linux/vm86.h>
#include <linux/math_emu.h> #include <linux/math_emu.h>
#include <linux/ptrace.h> #include <linux/ptrace.h>
#include <linux/timer.h>
#include <asm/processor.h> #include <asm/processor.h>
...@@ -174,6 +175,7 @@ struct task_struct { ...@@ -174,6 +175,7 @@ struct task_struct {
unsigned long timeout; unsigned long timeout;
unsigned long it_real_value, it_prof_value, it_virt_value; unsigned long it_real_value, it_prof_value, it_virt_value;
unsigned long it_real_incr, it_prof_incr, it_virt_incr; unsigned long it_real_incr, it_prof_incr, it_virt_incr;
struct timer_list real_timer;
long utime, stime, cutime, cstime, start_time; long utime, stime, cutime, cstime, start_time;
struct rlimit rlim[RLIM_NLIMITS]; struct rlimit rlim[RLIM_NLIMITS];
unsigned short used_math; unsigned short used_math;
...@@ -237,7 +239,9 @@ struct task_struct { ...@@ -237,7 +239,9 @@ struct task_struct {
/* suppl grps*/ {NOGROUP,}, \ /* suppl grps*/ {NOGROUP,}, \
/* proc links*/ &init_task,&init_task,NULL,NULL,NULL,NULL, \ /* proc links*/ &init_task,&init_task,NULL,NULL,NULL,NULL, \
/* uid etc */ 0,0,0,0,0,0,0,0, \ /* uid etc */ 0,0,0,0,0,0,0,0, \
/* timeout */ 0,0,0,0,0,0,0,0,0,0,0,0, \ /* timeout */ 0,0,0,0,0,0,0, \
/* timer */ { NULL, NULL, 0, 0, it_real_fn }, \
/* utime */ 0,0,0,0,0, \
/* rlimits */ { {LONG_MAX, LONG_MAX}, {LONG_MAX, LONG_MAX}, \ /* rlimits */ { {LONG_MAX, LONG_MAX}, {LONG_MAX, LONG_MAX}, \
{LONG_MAX, LONG_MAX}, {_STK_LIM, _STK_LIM}, \ {LONG_MAX, LONG_MAX}, {_STK_LIM, _STK_LIM}, \
{ 0, LONG_MAX}, {LONG_MAX, LONG_MAX}, \ { 0, LONG_MAX}, {LONG_MAX, LONG_MAX}, \
...@@ -271,6 +275,7 @@ extern void sleep_on(struct wait_queue ** p); ...@@ -271,6 +275,7 @@ extern void sleep_on(struct wait_queue ** p);
extern void interruptible_sleep_on(struct wait_queue ** p); extern void interruptible_sleep_on(struct wait_queue ** p);
extern void wake_up(struct wait_queue ** p); extern void wake_up(struct wait_queue ** p);
extern void wake_up_interruptible(struct wait_queue ** p); extern void wake_up_interruptible(struct wait_queue ** p);
extern void wake_up_process(struct task_struct * tsk);
extern void notify_parent(struct task_struct * tsk); extern void notify_parent(struct task_struct * tsk);
extern int send_sig(unsigned long sig,struct task_struct * p,int priv); extern int send_sig(unsigned long sig,struct task_struct * p,int priv);
......
/* /* -- sjcd.h
*
* Definitions for a Sanyo CD-ROM interface * Definitions for a Sanyo CD-ROM interface
* *
* Copyright (C) 1995 Vadim V. Model * Copyright (C) 1995 Vadim V. Model
...@@ -22,6 +23,11 @@ ...@@ -22,6 +23,11 @@
*/ */
#define SJCD_INTR_NR 10 #define SJCD_INTR_NR 10
/*
* Change this to set the dma channel.
*/
#define SJCD_DMA 0
/* /*
* port access macros * port access macros
*/ */
......
...@@ -87,6 +87,8 @@ struct timer_list { ...@@ -87,6 +87,8 @@ struct timer_list {
extern void add_timer(struct timer_list * timer); extern void add_timer(struct timer_list * timer);
extern int del_timer(struct timer_list * timer); extern int del_timer(struct timer_list * timer);
extern void it_real_fn(unsigned long);
extern inline void init_timer(struct timer_list * timer) extern inline void init_timer(struct timer_list * timer)
{ {
timer->next = NULL; timer->next = NULL;
......
...@@ -143,7 +143,7 @@ _INLINE_ void run_task_queue(task_queue *list) ...@@ -143,7 +143,7 @@ _INLINE_ void run_task_queue(task_queue *list)
void (*f) (void *); void (*f) (void *);
while(1) { while(1) {
p = xchg_ptr(list,&tq_last); p = xchg(list,&tq_last);
if(p == &tq_last) if(p == &tq_last)
break; break;
......
...@@ -28,9 +28,9 @@ ...@@ -28,9 +28,9 @@
#include <linux/if_tr.h> #include <linux/if_tr.h>
#ifdef __KERNEL__ #ifdef __KERNEL__
extern int tr_header(struct sk_buff *skb, struct device *dev, extern int tr_header(unsigned char *buff, struct device *dev,
unsigned short type, void *daddr, unsigned short type, void *daddr,
void *saddr, unsigned len); void *saddr, unsigned len, struct sk_buff *skb);
extern int tr_rebuild_header(void *buff, struct device *dev, extern int tr_rebuild_header(void *buff, struct device *dev,
unsigned long raddr, struct sk_buff *skb); unsigned long raddr, struct sk_buff *skb);
extern unsigned short tr_type_trans(struct sk_buff *skb, struct device *dev); extern unsigned short tr_type_trans(struct sk_buff *skb, struct device *dev);
......
#ifndef _LINUX_UNISTD_H_ #ifndef _LINUX_UNISTD_H_
#define _LINUX_UNISTD_H_ #define _LINUX_UNISTD_H_
/*
* This file contains the system call numbers.
*/
#define __NR_setup 0 /* used only by init, to get system going */
#define __NR_exit 1
#define __NR_fork 2
#define __NR_read 3
#define __NR_write 4
#define __NR_open 5
#define __NR_close 6
#define __NR_waitpid 7
#define __NR_creat 8
#define __NR_link 9
#define __NR_unlink 10
#define __NR_execve 11
#define __NR_chdir 12
#define __NR_time 13
#define __NR_mknod 14
#define __NR_chmod 15
#define __NR_chown 16
#define __NR_break 17
#define __NR_oldstat 18
#define __NR_lseek 19
#define __NR_getpid 20
#define __NR_mount 21
#define __NR_umount 22
#define __NR_setuid 23
#define __NR_getuid 24
#define __NR_stime 25
#define __NR_ptrace 26
#define __NR_alarm 27
#define __NR_oldfstat 28
#define __NR_pause 29
#define __NR_utime 30
#define __NR_stty 31
#define __NR_gtty 32
#define __NR_access 33
#define __NR_nice 34
#define __NR_ftime 35
#define __NR_sync 36
#define __NR_kill 37
#define __NR_rename 38
#define __NR_mkdir 39
#define __NR_rmdir 40
#define __NR_dup 41
#define __NR_pipe 42
#define __NR_times 43
#define __NR_prof 44
#define __NR_brk 45
#define __NR_setgid 46
#define __NR_getgid 47
#define __NR_signal 48
#define __NR_geteuid 49
#define __NR_getegid 50
#define __NR_acct 51
#define __NR_phys 52
#define __NR_lock 53
#define __NR_ioctl 54
#define __NR_fcntl 55
#define __NR_mpx 56
#define __NR_setpgid 57
#define __NR_ulimit 58
#define __NR_oldolduname 59
#define __NR_umask 60
#define __NR_chroot 61
#define __NR_ustat 62
#define __NR_dup2 63
#define __NR_getppid 64
#define __NR_getpgrp 65
#define __NR_setsid 66
#define __NR_sigaction 67
#define __NR_sgetmask 68
#define __NR_ssetmask 69
#define __NR_setreuid 70
#define __NR_setregid 71
#define __NR_sigsuspend 72
#define __NR_sigpending 73
#define __NR_sethostname 74
#define __NR_setrlimit 75
#define __NR_getrlimit 76
#define __NR_getrusage 77
#define __NR_gettimeofday 78
#define __NR_settimeofday 79
#define __NR_getgroups 80
#define __NR_setgroups 81
#define __NR_select 82
#define __NR_symlink 83
#define __NR_oldlstat 84
#define __NR_readlink 85
#define __NR_uselib 86
#define __NR_swapon 87
#define __NR_reboot 88
#define __NR_readdir 89
#define __NR_mmap 90
#define __NR_munmap 91
#define __NR_truncate 92
#define __NR_ftruncate 93
#define __NR_fchmod 94
#define __NR_fchown 95
#define __NR_getpriority 96
#define __NR_setpriority 97
#define __NR_profil 98
#define __NR_statfs 99
#define __NR_fstatfs 100
#define __NR_ioperm 101
#define __NR_socketcall 102
#define __NR_syslog 103
#define __NR_setitimer 104
#define __NR_getitimer 105
#define __NR_stat 106
#define __NR_lstat 107
#define __NR_fstat 108
#define __NR_olduname 109
#define __NR_iopl 110
#define __NR_vhangup 111
#define __NR_idle 112
#define __NR_vm86 113
#define __NR_wait4 114
#define __NR_swapoff 115
#define __NR_sysinfo 116
#define __NR_ipc 117
#define __NR_fsync 118
#define __NR_sigreturn 119
#define __NR_clone 120
#define __NR_setdomainname 121
#define __NR_uname 122
#define __NR_modify_ldt 123
#define __NR_adjtimex 124
#define __NR_mprotect 125
#define __NR_sigprocmask 126
#define __NR_create_module 127
#define __NR_init_module 128
#define __NR_delete_module 129
#define __NR_get_kernel_syms 130
#define __NR_quotactl 131
#define __NR_getpgid 132
#define __NR_fchdir 133
#define __NR_bdflush 134
#define __NR_sysfs 135
#define __NR_personality 136
#define __NR_afs_syscall 137 /* Syscall for Andrew File System */
#define __NR_setfsuid 138
#define __NR_setfsgid 139
#define __NR__llseek 140
#define __NR_getdents 141
#define __NR__newselect 142
#define __NR_flock 143
extern int errno; extern int errno;
/* /*
......
...@@ -74,7 +74,7 @@ int request_dma(unsigned int dmanr, char * device_id) ...@@ -74,7 +74,7 @@ int request_dma(unsigned int dmanr, char * device_id)
if (dmanr >= MAX_DMA_CHANNELS) if (dmanr >= MAX_DMA_CHANNELS)
return -EINVAL; return -EINVAL;
if (xchg_u32(&dma_chan_busy[dmanr].lock, 1) != 0) if (xchg(&dma_chan_busy[dmanr].lock, 1) != 0)
return -EBUSY; return -EBUSY;
dma_chan_busy[dmanr].device_id = device_id; dma_chan_busy[dmanr].device_id = device_id;
...@@ -91,7 +91,7 @@ void free_dma(unsigned int dmanr) ...@@ -91,7 +91,7 @@ void free_dma(unsigned int dmanr)
return; return;
} }
if (xchg_u32(&dma_chan_busy[dmanr].lock, 0) == 0) { if (xchg(&dma_chan_busy[dmanr].lock, 0) == 0) {
printk("Trying to free free DMA%d\n", dmanr); printk("Trying to free free DMA%d\n", dmanr);
return; return;
} }
......
...@@ -27,10 +27,7 @@ static int generate(unsigned long sig, struct task_struct * p) ...@@ -27,10 +27,7 @@ static int generate(unsigned long sig, struct task_struct * p)
struct sigaction * sa = sig + p->sigaction - 1; struct sigaction * sa = sig + p->sigaction - 1;
/* always generate signals for traced processes ??? */ /* always generate signals for traced processes ??? */
if (p->flags & PF_PTRACED) { if (!(p->flags & PF_PTRACED)) {
p->signal |= mask;
return 1;
}
/* don't bother with ignored signals (but SIGCHLD is special) */ /* don't bother with ignored signals (but SIGCHLD is special) */
if (sa->sa_handler == SIG_IGN && sig != SIGCHLD) if (sa->sa_handler == SIG_IGN && sig != SIGCHLD)
return 0; return 0;
...@@ -38,7 +35,10 @@ static int generate(unsigned long sig, struct task_struct * p) ...@@ -38,7 +35,10 @@ static int generate(unsigned long sig, struct task_struct * p)
if ((sa->sa_handler == SIG_DFL) && if ((sa->sa_handler == SIG_DFL) &&
(sig == SIGCONT || sig == SIGCHLD || sig == SIGWINCH)) (sig == SIGCONT || sig == SIGCHLD || sig == SIGWINCH))
return 0; return 0;
}
p->signal |= mask; p->signal |= mask;
if (p->state == TASK_INTERRUPTIBLE && (p->signal & ~p->blocked))
wake_up_process(p);
return 1; return 1;
} }
...@@ -58,7 +58,7 @@ int send_sig(unsigned long sig,struct task_struct * p,int priv) ...@@ -58,7 +58,7 @@ int send_sig(unsigned long sig,struct task_struct * p,int priv)
return 0; return 0;
if ((sig == SIGKILL) || (sig == SIGCONT)) { if ((sig == SIGKILL) || (sig == SIGCONT)) {
if (p->state == TASK_STOPPED) if (p->state == TASK_STOPPED)
p->state = TASK_RUNNING; wake_up_process(p);
p->exit_code = 0; p->exit_code = 0;
p->signal &= ~( (1<<(SIGSTOP-1)) | (1<<(SIGTSTP-1)) | p->signal &= ~( (1<<(SIGSTOP-1)) | (1<<(SIGTSTP-1)) |
(1<<(SIGTTIN-1)) | (1<<(SIGTTOU-1)) ); (1<<(SIGTTIN-1)) | (1<<(SIGTTOU-1)) );
...@@ -382,6 +382,7 @@ NORET_TYPE void do_exit(long code) ...@@ -382,6 +382,7 @@ NORET_TYPE void do_exit(long code)
} }
fake_volatile: fake_volatile:
current->flags |= PF_EXITING; current->flags |= PF_EXITING;
del_timer(&current->real_timer);
sem_exit(); sem_exit();
exit_mmap(current); exit_mmap(current);
free_page_tables(current); free_page_tables(current);
......
...@@ -197,6 +197,8 @@ int do_fork(unsigned long clone_flags, unsigned long usp, struct pt_regs *regs) ...@@ -197,6 +197,8 @@ int do_fork(unsigned long clone_flags, unsigned long usp, struct pt_regs *regs)
p->signal = 0; p->signal = 0;
p->it_real_value = p->it_virt_value = p->it_prof_value = 0; p->it_real_value = p->it_virt_value = p->it_prof_value = 0;
p->it_real_incr = p->it_virt_incr = p->it_prof_incr = 0; p->it_real_incr = p->it_virt_incr = p->it_prof_incr = 0;
init_timer(&p->real_timer);
p->real_timer.data = (unsigned long) p;
p->leader = 0; /* process leadership doesn't inherit */ p->leader = 0; /* process leadership doesn't inherit */
p->tty_old_pgrp = 0; p->tty_old_pgrp = 0;
p->utime = p->stime = 0; p->utime = p->stime = 0;
...@@ -219,7 +221,7 @@ int do_fork(unsigned long clone_flags, unsigned long usp, struct pt_regs *regs) ...@@ -219,7 +221,7 @@ int do_fork(unsigned long clone_flags, unsigned long usp, struct pt_regs *regs)
p->mm->swappable = 1; p->mm->swappable = 1;
p->exit_signal = clone_flags & CSIGNAL; p->exit_signal = clone_flags & CSIGNAL;
p->counter = current->counter >> 1; p->counter = current->counter >> 1;
p->state = TASK_RUNNING; /* do this last, just in case */ wake_up_process(p); /* do this last, just in case */
return p->pid; return p->pid;
bad_fork_cleanup: bad_fork_cleanup:
task[nr] = NULL; task[nr] = NULL;
......
...@@ -71,6 +71,17 @@ asmlinkage int sys_getitimer(int which, struct itimerval *value) ...@@ -71,6 +71,17 @@ asmlinkage int sys_getitimer(int which, struct itimerval *value)
return 0; return 0;
} }
void it_real_fn(unsigned long __data)
{
struct task_struct * p = (struct task_struct *) __data;
send_sig(SIGALRM, p, 1);
if (p->it_real_incr) {
p->real_timer.expires = p->it_real_incr;
add_timer(&p->real_timer);
}
}
int _setitimer(int which, struct itimerval *value, struct itimerval *ovalue) int _setitimer(int which, struct itimerval *value, struct itimerval *ovalue)
{ {
register unsigned long i, j; register unsigned long i, j;
...@@ -82,10 +93,10 @@ int _setitimer(int which, struct itimerval *value, struct itimerval *ovalue) ...@@ -82,10 +93,10 @@ int _setitimer(int which, struct itimerval *value, struct itimerval *ovalue)
return k; return k;
switch (which) { switch (which) {
case ITIMER_REAL: case ITIMER_REAL:
del_timer(&current->real_timer);
if (j) { if (j) {
j += 1+itimer_ticks; current->real_timer.expires = j;
if (j < itimer_next) add_timer(&current->real_timer);
itimer_next = j;
} }
current->it_real_value = j; current->it_real_value = j;
current->it_real_incr = i; current->it_real_incr = i;
......
...@@ -151,6 +151,7 @@ struct symbol_table symbol_table = { ...@@ -151,6 +151,7 @@ struct symbol_table symbol_table = {
X(kfree_s), X(kfree_s),
X(vmalloc), X(vmalloc),
X(vfree), X(vfree),
X(mem_map),
/* filesystem internal functions */ /* filesystem internal functions */
X(getname), X(getname),
...@@ -243,6 +244,7 @@ struct symbol_table symbol_table = { ...@@ -243,6 +244,7 @@ struct symbol_table symbol_table = {
X(tq_last), X(tq_last),
X(timer_active), X(timer_active),
X(timer_table), X(timer_table),
X(intr_count),
/* dma handling */ /* dma handling */
X(request_dma), X(request_dma),
...@@ -310,6 +312,7 @@ struct symbol_table symbol_table = { ...@@ -310,6 +312,7 @@ struct symbol_table symbol_table = {
X(slhc_remember), X(slhc_remember),
X(slhc_compress), X(slhc_compress),
X(slhc_uncompress), X(slhc_uncompress),
X(slhc_toss),
#endif #endif
#endif #endif
/* Device callback registration */ /* Device callback registration */
...@@ -384,8 +387,6 @@ struct symbol_table symbol_table = { ...@@ -384,8 +387,6 @@ struct symbol_table symbol_table = {
X(generic_proc_info), X(generic_proc_info),
X(scsi_devices), X(scsi_devices),
X(free_pages), X(free_pages),
X(intr_count),
X(mem_map),
X(print_msg), X(print_msg),
X(print_status), X(print_status),
X(gendisk_head), /* Needed for sd.c */ X(gendisk_head), /* Needed for sd.c */
...@@ -395,8 +396,6 @@ struct symbol_table symbol_table = { ...@@ -395,8 +396,6 @@ struct symbol_table symbol_table = {
* With no scsi configured, we still need to export a few * With no scsi configured, we still need to export a few
* symbols so that scsi can be loaded later via insmod. * symbols so that scsi can be loaded later via insmod.
*/ */
X(intr_count),
X(mem_map),
X(gendisk_head), X(gendisk_head),
X(resetup_one_dev), X(resetup_one_dev),
......
...@@ -92,8 +92,27 @@ struct task_struct * task[NR_TASKS] = {&init_task, }; ...@@ -92,8 +92,27 @@ struct task_struct * task[NR_TASKS] = {&init_task, };
struct kernel_stat kstat = { 0 }; struct kernel_stat kstat = { 0 };
unsigned long itimer_ticks = 0; /*
unsigned long itimer_next = ~0; * 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
* "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;
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;
}
/* /*
* 'schedule()' is the scheduler function. It's a very simple and nice * 'schedule()' is the scheduler function. It's a very simple and nice
...@@ -103,16 +122,12 @@ unsigned long itimer_next = ~0; ...@@ -103,16 +122,12 @@ unsigned long itimer_next = ~0;
* NOTE!! Task 0 is the 'idle' task, which gets called when no other * 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' * tasks can run. It can not be killed, and it cannot sleep. The 'state'
* information in task[0] is never used. * information in task[0] is never used.
*
* The "confuse_gcc" goto is used only to get better assembly code..
* Dijkstra probably hates me.
*/ */
asmlinkage void schedule(void) asmlinkage void schedule(void)
{ {
int c; int c;
struct task_struct * p; struct task_struct * p;
struct task_struct * next; struct task_struct * next;
unsigned long ticks;
/* check alarm, wake up any interruptible tasks that have got a signal */ /* check alarm, wake up any interruptible tasks that have got a signal */
...@@ -121,69 +136,35 @@ asmlinkage void schedule(void) ...@@ -121,69 +136,35 @@ asmlinkage void schedule(void)
intr_count = 0; intr_count = 0;
} }
run_task_queue(&tq_scheduler); run_task_queue(&tq_scheduler);
cli();
ticks = itimer_ticks; if (current->state == TASK_INTERRUPTIBLE) {
itimer_ticks = 0; if (current->signal & ~current->blocked)
itimer_next = ~0; current->state = TASK_RUNNING;
sti(); }
need_resched = 0; need_resched = 0;
nr_running = 0; nr_running = 0;
p = &init_task;
for (;;) { /* this is the scheduler proper: */
if ((p = p->next_task) == &init_task) c = -1000;
goto confuse_gcc1; next = &init_task;
if (ticks && p->it_real_value) { for_each_task(p) {
if (p->it_real_value <= ticks) { switch (p->state) {
send_sig(SIGALRM, p, 1); case TASK_INTERRUPTIBLE:
if (!p->it_real_incr) { if (!p->timeout)
p->it_real_value = 0;
goto end_itimer;
}
do {
p->it_real_value += p->it_real_incr;
} while (p->it_real_value <= ticks);
}
p->it_real_value -= ticks;
if (p->it_real_value < itimer_next)
itimer_next = p->it_real_value;
}
end_itimer:
if (p->state != TASK_INTERRUPTIBLE)
continue; continue;
if (p->signal & ~p->blocked) { if (p->timeout > jiffies)
p->state = TASK_RUNNING;
continue; continue;
}
if (p->timeout && p->timeout <= jiffies) {
p->timeout = 0; p->timeout = 0;
p->state = TASK_RUNNING; p->state = TASK_RUNNING;
} /* fall through */
} case TASK_RUNNING:
confuse_gcc1:
/* this is the scheduler proper: */
#if 0
/* give processes that go to sleep a bit higher priority.. */
/* This depends on the values for TASK_XXX */
/* This gives smoother scheduling for some things, but */
/* can be very unfair under some circumstances, so.. */
if (TASK_UNINTERRUPTIBLE >= (unsigned) current->state &&
current->counter < current->priority*2) {
++current->counter;
}
#endif
c = -1000;
next = p = &init_task;
for (;;) {
if ((p = p->next_task) == &init_task)
goto confuse_gcc2;
if (p->state == TASK_RUNNING) {
nr_running++; nr_running++;
if (p->counter > c) if (p->counter > c)
c = p->counter, next = p; c = p->counter, next = p;
} }
} }
confuse_gcc2:
/* if all runnable processes have "counter == 0", re-calculate counters */
if (!c) { if (!c) {
for_each_task(p) for_each_task(p)
p->counter = (p->counter >> 1) + p->priority; p->counter = (p->counter >> 1) + p->priority;
...@@ -219,11 +200,8 @@ void wake_up(struct wait_queue **q) ...@@ -219,11 +200,8 @@ void wake_up(struct wait_queue **q)
do { do {
if ((p = tmp->task) != NULL) { if ((p = tmp->task) != NULL) {
if ((p->state == TASK_UNINTERRUPTIBLE) || if ((p->state == TASK_UNINTERRUPTIBLE) ||
(p->state == TASK_INTERRUPTIBLE)) { (p->state == TASK_INTERRUPTIBLE))
p->state = TASK_RUNNING; wake_up_process(p);
if (p->counter > current->counter + 3)
need_resched = 1;
}
} }
if (!tmp->next) { if (!tmp->next) {
printk("wait_queue is bad (eip = %p)\n", printk("wait_queue is bad (eip = %p)\n",
...@@ -246,11 +224,8 @@ void wake_up_interruptible(struct wait_queue **q) ...@@ -246,11 +224,8 @@ void wake_up_interruptible(struct wait_queue **q)
return; return;
do { do {
if ((p = tmp->task) != NULL) { if ((p = tmp->task) != NULL) {
if (p->state == TASK_INTERRUPTIBLE) { if (p->state == TASK_INTERRUPTIBLE)
p->state = TASK_RUNNING; wake_up_process(p);
if (p->counter > current->counter + 3)
need_resched = 1;
}
} }
if (!tmp->next) { if (!tmp->next) {
printk("wait_queue is bad (eip = %p)\n", printk("wait_queue is bad (eip = %p)\n",
...@@ -665,9 +640,6 @@ static void do_timer(int irq, struct pt_regs * regs) ...@@ -665,9 +640,6 @@ static void do_timer(int irq, struct pt_regs * regs)
mark_bh(TIMER_BH); mark_bh(TIMER_BH);
} }
cli(); cli();
itimer_ticks++;
if (itimer_ticks > itimer_next)
need_resched = 1;
if (timer_head.next->expires < jiffies) if (timer_head.next->expires < jiffies)
mark_bh(TIMER_BH); mark_bh(TIMER_BH);
if (tq_timer != &tq_last) if (tq_timer != &tq_last)
......
...@@ -82,7 +82,7 @@ static int add_to_swap_cache(unsigned long addr, unsigned long entry) ...@@ -82,7 +82,7 @@ static int add_to_swap_cache(unsigned long addr, unsigned long entry)
swap_cache_add_total++; swap_cache_add_total++;
#endif #endif
if ((p->flags & SWP_WRITEOK) == SWP_WRITEOK) { if ((p->flags & SWP_WRITEOK) == SWP_WRITEOK) {
entry = (unsigned long) xchg_ptr(swap_cache + MAP_NR(addr), (void *) entry); entry = xchg(swap_cache + MAP_NR(addr), entry);
if (entry) { if (entry) {
printk("swap_cache: replacing non-NULL entry\n"); printk("swap_cache: replacing non-NULL entry\n");
} }
......
...@@ -178,7 +178,6 @@ static void aarp_send_reply(struct device *dev, struct at_addr *us, struct at_ad ...@@ -178,7 +178,6 @@ static void aarp_send_reply(struct device *dev, struct at_addr *us, struct at_ad
eah = (struct elapaarp *)skb_put(skb,sizeof(struct elapaarp)); eah = (struct elapaarp *)skb_put(skb,sizeof(struct elapaarp));
skb->arp = 1; skb->arp = 1;
skb->free = 1; skb->free = 1;
skb_put(skb,len);
skb->dev = dev; skb->dev = dev;
/* /*
...@@ -243,7 +242,6 @@ void aarp_send_probe(struct device *dev, struct at_addr *us) ...@@ -243,7 +242,6 @@ void aarp_send_probe(struct device *dev, struct at_addr *us)
skb->arp = 1; skb->arp = 1;
skb->free = 1; skb->free = 1;
skb_put(skb,len);
skb->dev = dev; skb->dev = dev;
/* /*
......
...@@ -26,6 +26,7 @@ ...@@ -26,6 +26,7 @@
* Alan Cox : ARP only when compiled with CONFIG_INET * Alan Cox : ARP only when compiled with CONFIG_INET
* Greg Page : 802.2 and SNAP stuff. * Greg Page : 802.2 and SNAP stuff.
* Alan Cox : MAC layer pointers/new format. * Alan Cox : MAC layer pointers/new format.
* Paul Gortmaker : eth_copy_and_sum shouldn't csum padding.
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
...@@ -231,11 +232,13 @@ void eth_header_cache(struct device *dev, struct sock *sk, unsigned long saddr, ...@@ -231,11 +232,13 @@ void eth_header_cache(struct device *dev, struct sock *sk, unsigned long saddr,
/* /*
* Copy from an ethernet device memory space to an sk_buff while checksumming if IP * Copy from an ethernet device memory space to an sk_buff while checksumming if IP
* The magic "34" is Rx_addr+Tx_addr+type_field+sizeof(struct iphdr) == 6+6+2+20.
*/ */
void eth_copy_and_sum(struct sk_buff *dest, unsigned char *src, int length, int base) void eth_copy_and_sum(struct sk_buff *dest, unsigned char *src, int length, int base)
{ {
struct ethhdr *eth; struct ethhdr *eth;
struct iphdr *iph;
IS_SKB(dest); IS_SKB(dest);
eth=(struct ethhdr *)dest->data; eth=(struct ethhdr *)dest->data;
...@@ -246,6 +249,14 @@ void eth_copy_and_sum(struct sk_buff *dest, unsigned char *src, int length, int ...@@ -246,6 +249,14 @@ void eth_copy_and_sum(struct sk_buff *dest, unsigned char *src, int length, int
memcpy(dest->data+34,src+34,length); memcpy(dest->data+34,src+34,length);
return; return;
} }
/*
* We have to watch for padded packets. The csum doesn't include the
* padding, and there is no point in copying the padding anyway.
*/
iph=(struct iphdr*)(src+14); /* 14 = Rx_addr+Tx_addr+type_field */
if (ntohs(iph->tot_len)-sizeof(struct iphdr) <= length)
length=ntohs(iph->tot_len)-sizeof(struct iphdr);
dest->csum=csum_partial_copy(src+34,dest->data+34,length,base); dest->csum=csum_partial_copy(src+34,dest->data+34,length,base);
dest->ip_summed=1; dest->ip_summed=1;
} }
...@@ -733,7 +733,7 @@ void ip_fw_masquerade(struct sk_buff **skb_ptr, struct device *dev) ...@@ -733,7 +733,7 @@ void ip_fw_masquerade(struct sk_buff **skb_ptr, struct device *dev)
if (portptr[1]==htons(21)) if (portptr[1]==htons(21))
{ {
skb = revamp(*skb_ptr, dev, ms); skb = revamp(*skb_ptr, dev, ms);
skb = *skb_ptr; *skb_ptr = skb;
iph = skb->h.iph; iph = skb->h.iph;
portptr = (unsigned short *)&(((char *)iph)[iph->ihl*4]); portptr = (unsigned short *)&(((char *)iph)[iph->ihl*4]);
} }
......
...@@ -145,6 +145,11 @@ ...@@ -145,6 +145,11 @@
* sk->retransmits misupdating fixed. * sk->retransmits misupdating fixed.
* Fixed tcp_write_timeout: stuck close, * Fixed tcp_write_timeout: stuck close,
* and TCP syn retries gets used now. * and TCP syn retries gets used now.
* Mark Yarvis : In tcp_read_wakeup(), don't send an
* ack if stat is TCP_CLOSED.
* Alan Cox : Look up device on a retransmit - routes may
* change. Doesn't yet cope with MSS shrink right
* but its a start!
* *
* *
* To Fix: * To Fix:
...@@ -439,6 +444,7 @@ void tcp_do_retransmit(struct sock *sk, int all) ...@@ -439,6 +444,7 @@ void tcp_do_retransmit(struct sock *sk, int all)
struct proto *prot; struct proto *prot;
struct device *dev; struct device *dev;
int ct=0; int ct=0;
struct rtable *rt;
prot = sk->prot; prot = sk->prot;
skb = sk->send_head; skb = sk->send_head;
...@@ -453,6 +459,12 @@ void tcp_do_retransmit(struct sock *sk, int all) ...@@ -453,6 +459,12 @@ void tcp_do_retransmit(struct sock *sk, int all)
IS_SKB(skb); IS_SKB(skb);
skb->when = jiffies; skb->when = jiffies;
/*
* Discard the surplus MAC header
*/
skb_pull(skb,((unsigned char *)skb->ip_hdr)-skb->data);
/* /*
* In general it's OK just to use the old packet. However we * In general it's OK just to use the old packet. However we
* need to use the current ack and window fields. Urg and * need to use the current ack and window fields. Urg and
...@@ -462,21 +474,49 @@ void tcp_do_retransmit(struct sock *sk, int all) ...@@ -462,21 +474,49 @@ void tcp_do_retransmit(struct sock *sk, int all)
* changing the packet, we have to issue a new IP identifier. * changing the packet, we have to issue a new IP identifier.
*/ */
iph = (struct iphdr *)(skb->data + dev->hard_header_len); iph = (struct iphdr *)skb->data;
th = (struct tcphdr *)(((char *)iph) + (iph->ihl << 2)); th = (struct tcphdr *)(((char *)iph) + (iph->ihl << 2));
size = skb->len - (((unsigned char *) th) - skb->data); size = ntohs(iph->tot_len) - (iph->ihl<<2);
/* /*
* Note: We ought to check for window limits here but * Note: We ought to check for window limits here but
* currently this is done (less efficiently) elsewhere. * currently this is done (less efficiently) elsewhere.
* We do need to check for a route change but can't handle
* that until we have the new 1.3.x buffers in.
*
*/ */
iph->id = htons(ip_id_count++); iph->id = htons(ip_id_count++);
ip_send_check(iph); ip_send_check(iph);
/*
* Put a MAC header back on (may cause ARPing)
*/
if(skb->localroute)
rt=ip_rt_local(iph->daddr,NULL,NULL);
else
rt=ip_rt_route(iph->daddr,NULL,NULL);
if(rt==NULL) /* Deep poo */
{
if(skb->sk)
{
skb->sk->err=ENETUNREACH;
skb->sk->error_report(skb->sk);
}
}
else
{
dev=rt->rt_dev;
skb->raddr=rt->rt_gateway;
if(skb->raddr==0)
skb->raddr=iph->daddr;
skb->dev=dev;
skb->arp=1;
if(dev->hard_header)
{
if(dev->hard_header(skb, dev, ETH_P_IP, NULL, NULL, skb->len)<0)
skb->arp=0;
}
/* /*
* This is not the right way to handle this. We have to * This is not the right way to handle this. We have to
* issue an up to date window and ack report with this * issue an up to date window and ack report with this
...@@ -515,6 +555,7 @@ void tcp_do_retransmit(struct sock *sk, int all) ...@@ -515,6 +555,7 @@ void tcp_do_retransmit(struct sock *sk, int all)
dev_queue_xmit(skb, dev, sk->priority); dev_queue_xmit(skb, dev, sk->priority);
} }
} }
}
/* /*
* Count retransmissions * Count retransmissions
...@@ -1771,6 +1812,13 @@ static void tcp_read_wakeup(struct sock *sk) ...@@ -1771,6 +1812,13 @@ static void tcp_read_wakeup(struct sock *sk)
if (!sk->ack_backlog) if (!sk->ack_backlog)
return; return;
/*
* If we're closed, don't send an ack, or we'll get a RST
* from the closed destination.
*/
if ((sk->state == TCP_CLOSE) || (sk->state == TCP_TIME_WAIT))
return;
/* /*
* FIXME: we need to put code here to prevent this routine from * FIXME: we need to put code here to prevent this routine from
* being called. Being called once in a while is ok, so only check * being called. Being called once in a while is ok, so only check
...@@ -3034,8 +3082,7 @@ static void tcp_write_xmit(struct sock *sk) ...@@ -3034,8 +3082,7 @@ static void tcp_write_xmit(struct sock *sk)
* Ack and window will in general have changed since this packet was put * Ack and window will in general have changed since this packet was put
* on the write queue. * on the write queue.
*/ */
iph = (struct iphdr *)(skb->data + iph = skb->ip_hdr;
skb->dev->hard_header_len);
th = (struct tcphdr *)(((char *)iph) +(iph->ihl << 2)); th = (struct tcphdr *)(((char *)iph) +(iph->ihl << 2));
size = skb->len - (((unsigned char *) th) - skb->data); size = skb->len - (((unsigned char *) th) - skb->data);
......
...@@ -45,8 +45,7 @@ ...@@ -45,8 +45,7 @@
* Arnt Gulbrandsen : New udp_send and stuff * Arnt Gulbrandsen : New udp_send and stuff
* Alan Cox : Cache last socket * Alan Cox : Cache last socket
* Alan Cox : Route cache * Alan Cox : Route cache
* Alan Cox : Checksum precompute is bogus is some lame * Jon Peatfield : Minor efficientcy fix to sendto().
* software is padding its udp frames in IP!
* *
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
...@@ -301,10 +300,9 @@ static int udp_sendto(struct sock *sk, unsigned char *from, int len, int noblock ...@@ -301,10 +300,9 @@ static int udp_sendto(struct sock *sk, unsigned char *from, int len, int noblock
{ {
if (addr_len < sizeof(sin)) if (addr_len < sizeof(sin))
return(-EINVAL); return(-EINVAL);
memcpy(&sin,usin,sizeof(sin)); if (usin->sin_family && usin->sin_family != AF_INET)
if (sin.sin_family && sin.sin_family != AF_INET)
return(-EINVAL); return(-EINVAL);
if (sin.sin_port == 0) if (usin->sin_port == 0)
return(-EINVAL); return(-EINVAL);
} }
else else
...@@ -314,6 +312,7 @@ static int udp_sendto(struct sock *sk, unsigned char *from, int len, int noblock ...@@ -314,6 +312,7 @@ static int udp_sendto(struct sock *sk, unsigned char *from, int len, int noblock
sin.sin_family = AF_INET; sin.sin_family = AF_INET;
sin.sin_port = sk->dummy_th.dest; sin.sin_port = sk->dummy_th.dest;
sin.sin_addr.s_addr = sk->daddr; sin.sin_addr.s_addr = sk->daddr;
usin = &sin;
} }
/* /*
...@@ -321,16 +320,16 @@ static int udp_sendto(struct sock *sk, unsigned char *from, int len, int noblock ...@@ -321,16 +320,16 @@ static int udp_sendto(struct sock *sk, unsigned char *from, int len, int noblock
* broadcasting of data. * broadcasting of data.
*/ */
if(sin.sin_addr.s_addr==INADDR_ANY) if(usin->sin_addr.s_addr==INADDR_ANY)
sin.sin_addr.s_addr=ip_my_addr(); usin->sin_addr.s_addr=ip_my_addr();
if(!sk->broadcast && ip_chk_addr(sin.sin_addr.s_addr)==IS_BROADCAST) if(!sk->broadcast && ip_chk_addr(usin->sin_addr.s_addr)==IS_BROADCAST)
return -EACCES; /* Must turn broadcast on first */ return -EACCES; /* Must turn broadcast on first */
sk->inuse = 1; sk->inuse = 1;
/* Send the packet. */ /* Send the packet. */
tmp = udp_send(sk, &sin, from, len, flags); tmp = udp_send(sk, usin, from, len, flags);
/* The datagram has been sent off. Release the socket. */ /* The datagram has been sent off. Release the socket. */
release_sock(sk); release_sock(sk);
...@@ -538,9 +537,6 @@ int udp_rcv(struct sk_buff *skb, struct device *dev, struct options *opt, ...@@ -538,9 +537,6 @@ int udp_rcv(struct sk_buff *skb, struct device *dev, struct options *opt,
ulen = ntohs(uh->len); ulen = ntohs(uh->len);
if(ulen!=len)
skb->ip_summed=0; /* Bogoid padded frame */
if (ulen > len || len < sizeof(*uh) || ulen < sizeof(*uh)) if (ulen > len || len < sizeof(*uh) || ulen < sizeof(*uh))
{ {
NETDEBUG(printk("UDP: short packet: %d/%d\n", ulen, len)); NETDEBUG(printk("UDP: short packet: %d/%d\n", ulen, len));
......
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