diff -u --recursive --new-file v1.3.10/linux/CREDITS linux/CREDITS --- v1.3.10/linux/CREDITS Thu Jul 13 16:20:19 1995 +++ linux/CREDITS Sun Jul 16 21:44:59 1995 @@ -688,7 +688,9 @@ N: Michael Neuffer 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: 55127 Mainz S: Germany diff -u --recursive --new-file v1.3.10/linux/Makefile linux/Makefile --- v1.3.10/linux/Makefile Thu Jul 13 16:20:19 1995 +++ linux/Makefile Thu Jul 13 17:39:27 1995 @@ -1,6 +1,6 @@ VERSION = 1 PATCHLEVEL = 3 -SUBLEVEL = 10 +SUBLEVEL = 11 ARCH = i386 diff -u --recursive --new-file v1.3.10/linux/arch/alpha/kernel/entry.S linux/arch/alpha/kernel/entry.S --- v1.3.10/linux/arch/alpha/kernel/entry.S Thu Jul 13 16:20:19 1995 +++ linux/arch/alpha/kernel/entry.S Sun Jul 16 22:58:10 1995 @@ -9,7 +9,7 @@ #define halt .long PAL_halt #define rti .long PAL_rti -#define NR_SYSCALLS 310 +#define NR_SYSCALLS 320 #define osf_vfork sys_fork /* @@ -565,3 +565,6 @@ /* linux-specific system calls start at 300 */ /*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_syslog, do_entSys, do_entSys, do_entSys, do_entSys + .quad do_entSys, do_entSys, do_entSys, do_entSys, do_entSys + diff -u --recursive --new-file v1.3.10/linux/arch/alpha/kernel/ptrace.c linux/arch/alpha/kernel/ptrace.c --- v1.3.10/linux/arch/alpha/kernel/ptrace.c Thu Jul 13 16:20:19 1995 +++ linux/arch/alpha/kernel/ptrace.c Mon Jul 17 12:12:38 1995 @@ -693,7 +693,7 @@ else child->flags &= ~PF_TRACESYS; child->exit_code = data; - child->state = TASK_RUNNING; + wake_up_process(child); ptrace_cancel_bpt(child); set_success(®s,data); return 0; @@ -705,7 +705,7 @@ * exit. */ case PTRACE_KILL: { - child->state = TASK_RUNNING; + wake_up_process(child); child->exit_code = SIGKILL; ptrace_cancel_bpt(child); return 0; @@ -721,7 +721,7 @@ return res; } child->flags &= ~PF_TRACESYS; - child->state = TASK_RUNNING; + wake_up_process(child); child->exit_code = data; /* give it a chance to run. */ return 0; @@ -733,7 +733,7 @@ return -EIO; } child->flags &= ~(PF_PTRACED|PF_TRACESYS); - child->state = TASK_RUNNING; + wake_up_process(child); child->exit_code = data; REMOVE_LINKS(child); child->p_pptr = child->p_opptr; diff -u --recursive --new-file v1.3.10/linux/arch/alpha/lib/Makefile linux/arch/alpha/lib/Makefile --- v1.3.10/linux/arch/alpha/lib/Makefile Tue Jul 11 10:02:47 1995 +++ linux/arch/alpha/lib/Makefile Mon Jul 17 09:23:48 1995 @@ -8,7 +8,7 @@ $(CC) $(CFLAGS) -c $< OBJS = __divqu.o __remqu.o __divlu.o __remlu.o memset.o memcpy.o io.o \ - checksum.o + checksum.o strlen.o lib.a: $(OBJS) $(AR) rcs lib.a $(OBJS) diff -u --recursive --new-file v1.3.10/linux/arch/alpha/lib/strlen.S linux/arch/alpha/lib/strlen.S --- v1.3.10/linux/arch/alpha/lib/strlen.S Thu Jan 1 02:00:00 1970 +++ linux/arch/alpha/lib/strlen.S Mon Jul 17 08:50:12 1995 @@ -0,0 +1,57 @@ +/* + * 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 diff -u --recursive --new-file v1.3.10/linux/arch/i386/kernel/ptrace.c linux/arch/i386/kernel/ptrace.c --- v1.3.10/linux/arch/i386/kernel/ptrace.c Tue May 30 12:17:18 1995 +++ linux/arch/i386/kernel/ptrace.c Mon Jul 17 12:11:59 1995 @@ -466,7 +466,7 @@ else child->flags &= ~PF_TRACESYS; child->exit_code = data; - child->state = TASK_RUNNING; + wake_up_process(child); /* make sure the single step bit is not set. */ tmp = get_stack_long(child, sizeof(long)*EFL-MAGICNUMBER) & ~TRAP_FLAG; put_stack_long(child, sizeof(long)*EFL-MAGICNUMBER,tmp); @@ -481,7 +481,7 @@ case PTRACE_KILL: { long tmp; - child->state = TASK_RUNNING; + wake_up_process(child); child->exit_code = SIGKILL; /* make sure the single step bit is not set. */ tmp = get_stack_long(child, sizeof(long)*EFL-MAGICNUMBER) & ~TRAP_FLAG; @@ -497,7 +497,7 @@ child->flags &= ~PF_TRACESYS; tmp = get_stack_long(child, sizeof(long)*EFL-MAGICNUMBER) | TRAP_FLAG; put_stack_long(child, sizeof(long)*EFL-MAGICNUMBER,tmp); - child->state = TASK_RUNNING; + wake_up_process(child); child->exit_code = data; /* give it a chance to run. */ return 0; @@ -509,7 +509,7 @@ if ((unsigned long) data > NSIG) return -EIO; child->flags &= ~(PF_PTRACED|PF_TRACESYS); - child->state = TASK_RUNNING; + wake_up_process(child); child->exit_code = data; REMOVE_LINKS(child); child->p_pptr = child->p_opptr; diff -u --recursive --new-file v1.3.10/linux/arch/mips/kernel/ptrace.c linux/arch/mips/kernel/ptrace.c --- v1.3.10/linux/arch/mips/kernel/ptrace.c Wed Jan 25 08:54:22 1995 +++ linux/arch/mips/kernel/ptrace.c Mon Jul 17 12:13:20 1995 @@ -448,7 +448,7 @@ else child->flags &= ~PF_TRACESYS; child->exit_code = data; - child->state = TASK_RUNNING; + wake_up_process(child); /* make sure the single step bit is not set. */ tmp = get_stack_long(child, sizeof(long)*EFL-MAGICNUMBER) & ~TRAP_FLAG; put_stack_long(child, sizeof(long)*EFL-MAGICNUMBER,tmp); @@ -463,7 +463,7 @@ case PTRACE_KILL: { long tmp; - child->state = TASK_RUNNING; + wake_up_process(child); child->exit_code = SIGKILL; /* make sure the single step bit is not set. */ tmp = get_stack_long(child, sizeof(long)*EFL-MAGICNUMBER) & ~TRAP_FLAG; @@ -479,7 +479,7 @@ child->flags &= ~PF_TRACESYS; tmp = get_stack_long(child, sizeof(long)*EFL-MAGICNUMBER) | TRAP_FLAG; put_stack_long(child, sizeof(long)*EFL-MAGICNUMBER,tmp); - child->state = TASK_RUNNING; + wake_up_process(child); child->exit_code = data; /* give it a chance to run. */ return 0; @@ -491,7 +491,7 @@ if ((unsigned long) data > NSIG) return -EIO; child->flags &= ~(PF_PTRACED|PF_TRACESYS); - child->state = TASK_RUNNING; + wake_up_process(child); child->exit_code = data; REMOVE_LINKS(child); child->p_pptr = child->p_opptr; diff -u --recursive --new-file v1.3.10/linux/drivers/Makefile linux/drivers/Makefile --- v1.3.10/linux/drivers/Makefile Tue Jul 11 10:02:48 1995 +++ linux/drivers/Makefile Sun Jul 16 21:58:49 1995 @@ -15,7 +15,6 @@ $(CC) $(CFLAGS) -c $< SUBDIRS = block char net #streams -ALL_SUBDIRS = block char net scsi #streams ifdef CONFIG_PCI SUBDIRS := $(SUBDIRS) pci @@ -35,9 +34,9 @@ set -e; for i in $(SUBDIRS); do $(MAKE) -C $$i; done 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: - 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 diff -u --recursive --new-file v1.3.10/linux/drivers/block/README.sjcd linux/drivers/block/README.sjcd --- v1.3.10/linux/drivers/block/README.sjcd Fri Jul 7 08:54:44 1995 +++ linux/drivers/block/README.sjcd Sun Jul 16 21:47:22 1995 @@ -1,3 +1,4 @@ + -- README.sjcd 80% of the work takes 20% of the time, 20% of the work takes 80% of the time... (Murphy law) @@ -5,21 +6,36 @@ Once started, training can not be stopped... (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 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, including the "soft configurable" MediaMagic sound card. To make this sound card (and others like "Mozart") working, it has to get "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 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 -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 +ISP16 configuration routines reside at Vadim's server rbrf.msk.su:/linux/mediamagic/ and at Eberhard's mirror ftp.gwdg.de:/pub/linux/cdrom/drivers/sanyo/ @@ -28,6 +44,26 @@ dutette.et.tudelft.nl:/pub/linux/ and at Eberhard's mirror 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=,, +(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 or vadim@ipsun.ras.ru diff -u --recursive --new-file v1.3.10/linux/drivers/block/ide.c linux/drivers/block/ide.c --- v1.3.10/linux/drivers/block/ide.c Tue Jul 11 10:02:49 1995 +++ linux/drivers/block/ide.c Mon Jul 17 17:00:30 1995 @@ -1358,7 +1358,7 @@ sleep_on(&dev->wqueue); dev->usage++; 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); #ifdef CONFIG_BLK_DEV_IDECD if (dev->type == cdrom) @@ -1654,7 +1654,7 @@ if (dev->type == cdrom) return cdrom_check_media_change (dev); #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 0; } diff -u --recursive --new-file v1.3.10/linux/drivers/block/sjcd.c linux/drivers/block/sjcd.c --- v1.3.10/linux/drivers/block/sjcd.c Fri Jul 7 08:54:45 1995 +++ linux/drivers/block/sjcd.c Sun Jul 16 21:47:22 1995 @@ -1,15 +1,24 @@ -/* - * Sanyo CD-ROM device driver implementation. +/* -- sjcd.c * + * Sanyo CD-ROM device driver implementation, Version 1.3 * Copyright (C) 1995 Vadim V. Model * * model@cecmow.enet.dec.com * vadim@rbrf.msk.su * 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); * 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 * a "mixed use" on one cable possible for all kinds of drives which use @@ -29,6 +38,15 @@ * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * 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=,, + * 1.3 Some minor changes to README.sjcd. + * */ #include @@ -49,11 +67,60 @@ #define MAJOR_NR SANYO_CDROM_MAJOR #include "blk.h" -#ifdef CONFIG_ISP_16 -#include -#endif #include +/* 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; #define SJCD_BUF_SIZ 32 /* cdr-h94a has internal 64K buffer */ @@ -86,6 +153,7 @@ static short sjcd_port = SJCD_BASE_ADDR; static int sjcd_irq = SJCD_INTR_NR; +static int sjcd_dma = SJCD_DMA; static struct wait_queue *sjcd_waitq = NULL; @@ -131,10 +199,17 @@ #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 ){ - 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 @@ }; /* - * 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 * will be reset. Then read the version of the drive and load status. */ @@ -1281,22 +1356,21 @@ unsigned long sjcd_init( unsigned long mem_start, unsigned long mem_end ){ int i; - if( sjcd_port != 0x340 || sjcd_irq != 0x0A /* 10 */ ){ - printk( "skip sjcd_init\n" ); - return( mem_start ); + if ( (isp16_type=isp16_detect()) < 0 ) + printk( "No ISP16 cdrom interface found.\n" ); + else { + u_char expected_drive; + + printk( "ISP16 cdrom interface (%s optional IDE) detected.\n", + (isp16_type==2)?"with":"without" ); + + expected_drive = (isp16_type?ISP16_SANYO1:ISP16_SANYO0); + + 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); + } } - -#ifdef CONFIG_ISP_16 - /* - * 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 - printk( "sjcd=0x%x,%d: ", sjcd_port, sjcd_irq ); -#endif if( register_blkdev( MAJOR_NR, "sjcd", &sjcd_fops ) != 0 ){ printk( "Unable to get major %d for Sanyo CD-ROM\n", MAJOR_NR ); @@ -1356,3 +1430,189 @@ return( mem_start ); } +/* + * -- ISP16 detection and configuration + * + * Copyright (c) 1995, Eric van der Maarel + * + * 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); +} diff -u --recursive --new-file v1.3.10/linux/drivers/char/scc.c linux/drivers/char/scc.c --- v1.3.10/linux/drivers/char/scc.c Tue Jun 27 14:11:34 1995 +++ linux/drivers/char/scc.c Mon Jul 17 14:49:30 1995 @@ -1,9 +1,8 @@ #include /* fastest method */ #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 * */ @@ -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 - chk_rcv_queue() [stupid error] - 950304 - fixed underrun/zcount handling - 950305 - the driver registers port addresses now - 950314 - fixed underrun interrupt handling again + chk_rcv_queue() [stupid error] dl1bke + 950229 - buffer timeout for vergotten buffer :-( pe1ayx + 950304 - fixed underrun/zcount handling dl1bke + 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: - + DL1BKE Joerg - for some good ideas 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 - 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 PE1KOX Rob, DG1RTF Thomas, ON5QK Roland, @@ -46,13 +56,7 @@ 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... - - Jörg Reuter DL1BKE - + */ @@ -110,8 +114,6 @@ static void z8530_init(void); 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 scc_key_trx (struct scc_channel *scc, char tx); static void scc_txint(register struct scc_channel *scc); @@ -124,6 +126,14 @@ /* 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[] = { 0, 50, 75, 110, 134, 150, 200, 300, 600, 1200, 1800, 2400, 4800, 9600, 19200, 38400, 57600, 115200, 0 }; @@ -142,6 +152,8 @@ static struct sccbuf *sccfreelist[MAX_IBUFS] = {0}; static int allocated_ibufs = 0; +#define SERIAL_TYPE_NORMAL 1 + /* ******************************************************************** */ /* * Port Access Functions * */ @@ -197,10 +209,6 @@ /* * 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 */ void scc_alloc_buffer_pool(void) @@ -209,6 +217,8 @@ struct sccbuf *sccb; struct mbuf *bp; + start_controle = 0; + for (i = 0 ; i < MAX_IBUFS ; i++) { sccb = (struct sccbuf *)kmalloc(sizeof(struct sccbuf), GFP_ATOMIC); @@ -286,6 +296,7 @@ sccfreelist[i]->bp->refcnt = 1; sccfreelist[i]->bp->cnt = 0; sccfreelist[i]->bp->in_use = 0; + sccfreelist[i]->bp->time_out = CURRENT_TIME + 300; restore_flags(flags); return sccfreelist[i]->bp; @@ -314,7 +325,33 @@ save_flags(flags); cli(); 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) { for(i = 0 ; i < allocated_ibufs ; i++) @@ -481,13 +518,13 @@ if (Vector_Latch) { - while(1) /* forever...? */ + while(1) { Outb(Vector_Latch, 0); /* Generate INTACK */ /* Read the vector */ - if((vector=Inb(Vector_Latch)) >= 16 * Nchips) break; - /* ...not forever! */ + if((vector=Inb(Vector_Latch)) >= 16 * Nchips) + break; /* Extract channel number and status from vector. */ /* Isolate channel nummer */ @@ -619,39 +656,20 @@ /* 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 flush_FIFO(register struct scc_channel *scc) { register int k; for (k=0; k<3; k++) 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++; /* then count it as an error */ - - scc_toss_buffer(scc); /* throw away buffer */ + scc->stat.rxerrs++; + scc->rxbufcnt = 0; /* throw away frame */ } } - - /* External/Status interrupt handler */ static void scc_exint(register struct scc_channel *scc) @@ -729,7 +747,7 @@ static void scc_rxint(register struct scc_channel *scc) { - register struct mbuf *bp; + unsigned char ch; scc->stat.rxints++; @@ -740,32 +758,36 @@ return; } - if ((bp = scc->rbp1) == NULLBUF || bp->cnt >= bp->size) - { /* 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 */ - or(scc,R3,ENT_HM); /* enter hunt mode */ - scc_toss_buffer(scc); /* throw away buffers */ - scc->stat.nospace++; /* and count this error */ - return; - } + if (scc->rxbufcnt > 2044) /* no buffer available? */ + { + Inb(scc->data); /* discard character */ + or(scc,R3,ENT_HM); /* enter hunt mode */ + scc->rxbufcnt = 0; /* throw away frame */ + scc->stat.nospace++; /* and count this error */ + 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 @@ scc_spint(register struct scc_channel *scc) { register unsigned char status; - register struct mbuf *bp; + int i; + unsigned char *cp; + char *fp; + int count; + 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 */ - or(scc,R3,ENT_HM); /* enter hunt mode for next flag */ - scc_toss_buffer(scc); /* rewind the buffer and toss */ + scc->stat.rx_over++; + or(scc,R3,ENT_HM); /* enter hunt mode */ + 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->rbp->cnt) + if (!(status & CRC_ERR) && (status & 0xe) == RES8 && scc->rxbufcnt > 0) { - /* ignore last received byte (first of the CRC bytes) */ + scc->rxbufcnt--; /*strip the CRC */ + scc->rxbuf[scc->rxbufcnt++] = FEND; + + for(i = 0 ; i < scc->rxbufcnt ; i++) + { + 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); + } + } + + 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); + scc->stat.rxframes++; + + scc->rxbufcnt = 0; - for (bp = scc->rbp; bp->next != NULLBUF; bp = bp->next) ; - bp->cnt--; /* last byte is first CRC byte */ - - scc_enqueue(&scc->rcvq,scc->rbp); - scc->rbp = scc->rbp1 = NULLBUF; - scc->stat.rxframes++; - scc->stat.rx_queued++; - } else { /* a bad frame */ - scc_toss_buffer(scc); /* throw away frame */ + } else { + scc->rxbufcnt = 0; /* frame is not good */ scc->stat.rxerrs++; - } + } } - Outb(scc->ctrl,ERR_RES); } @@ -934,7 +996,7 @@ Outb(scc->ctrl,RES_EXT_INT); /* must be done twice */ 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,R9,MIE); /* master interrupt enable */ @@ -1142,42 +1204,13 @@ 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 scc_timer(void) { register struct scc_channel *scc; register int chan; unsigned long flags; - + save_flags(flags); cli(); for (chan = 0; chan < (Nchips * 2); chan++) @@ -1186,11 +1219,7 @@ if (scc->tty && scc->init) { - kiss_encode(scc); - check_rcv_queue(scc); - /* KISS-TNC emulation */ - if (Expired(t_dwait)) dw_slot_timeout(scc) ; else if (Expired(t_slot)) dw_slot_timeout(scc) ; else if (Expired(t_txdel)) txdel_timeout(scc) ; else @@ -1201,8 +1230,10 @@ if (Expired(t_mbusy)) busy_timeout(scc); if (Expired(t_maxk)) maxk_idle_timeout(scc); if (Expired(t_idle)) maxk_idle_timeout(scc); + } } + timer_table[SCC_TIMER].fn = scc_timer; timer_table[SCC_TIMER].expires = jiffies + HZ/TPS; @@ -1259,7 +1290,7 @@ case PARAM_TXTAIL: scc->kiss.tailtime = VAL; break; case PARAM_FULLDUP: - scc->kiss.fulldup = val; break; + scc->kiss.fulldup = val; break; case PARAM_WAIT: scc->kiss.waittime = VAL; break; case PARAM_MAXKEY: @@ -1423,97 +1454,6 @@ } -/* ----> 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... * */ /* ******************************************************************* */ @@ -1523,11 +1463,10 @@ z8530_init(void) { struct scc_channel *scc; - int chip,chan; + int chip; unsigned long flags; - int k; - /* reset and pre-init all chips in the system */ + /* reset all scc chips */ for (chip = 0; chip < Nchips; chip++) { /* Special SCC cards */ @@ -1538,30 +1477,25 @@ if(Board & (PC100 | PRIMUS)) /* this is a PC100/EAGLE card */ Outb(Special_Port,Option); /* set the MODEM mode (22H normally) */ - /* Init SCC */ - scc=&SCC_Info[2*chip]; if (!scc->ctrl) continue; save_flags(flags); cli(); - Outb(scc->ctrl, 0); - OutReg(scc->ctrl,R9,FHWRES); /* force hardware reset */ - for (k=1; k < 1000; k++) ; - - for (chan = 0; chan < 2; chan++) - { - scc=&SCC_Info[2*chip+chan]; - - wr(scc,R1, 0); - wr(scc,R2, chip*16); /* No of chip is vector */ - wr(scc,R9,VIS); /* vector includes status */ - } + OutReg(scc->ctrl,R9,FHWRES); /* force hardware reset */ + OutReg(scc->ctrl,R9,0); /* end hardware reset */ + OutReg(scc->ctrl,R9,CHRA); /* reset channel A */ + OutReg(scc->ctrl,R9,CHRB); /* reset channel B */ + OutReg(scc->ctrl,R1, 0); /* No Rx irq from channel A */ + scc=&SCC_Info[2*chip+1]; + OutReg(scc->ctrl,R1, 0); /* No Rx irq from channel B */ + scc=&SCC_Info[2*chip]; + OutReg(scc->ctrl,R2, chip*16); /* Set Interrupt vector */ 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"); Driver_Initialized = 1; @@ -1613,6 +1547,9 @@ scc = &SCC_Info[chan]; tty->driver_data = scc; + tty->termios->c_iflag = IGNBRK | IGNPAR; + tty->termios->c_cflag = B9600 | CS8 | CLOCAL; + tty->termios->c_cflag &= ~CBAUD; if (!Driver_Initialized) @@ -1643,7 +1580,28 @@ timer_table[SCC_TIMER].fn = scc_timer; timer_table[SCC_TIMER].expires = 0; /* now! */ 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; } @@ -1796,7 +1754,7 @@ scc->kiss.softdcd = 0; /* hardware dcd */ } - scc->init = 1; + scc->init = 1; return 0; } @@ -1821,7 +1779,7 @@ restore_flags(flags); - put_user(result,(unsigned int *) arg); + put_fs_long(result,(unsigned long *) arg); return 0; case TIOCMBIS: case TIOCMBIC: @@ -1836,7 +1794,7 @@ scc->wreg[R5] &= ~RTS; break; case TIOCMSET: - value = get_user((unsigned int *) arg); + value = get_fs_long((unsigned long *) arg); if(value & TIOCM_DTR) scc->wreg[R5] |= DTR; @@ -2022,6 +1980,7 @@ scc->sndq1->anext = bp; } + } @@ -2031,12 +1990,14 @@ /* send raw frame to SCC. used for AX.25 */ 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; - unsigned char tbuf[BUFSIZE], *p; int cnt, cnt2; - - if (!tty) return count; - + + if (!tty || !tmp_buf) + return 0; + if (scc_paranoia_check(scc, tty->device, "scc_write")) return 0; @@ -2044,31 +2005,43 @@ check_tx_queue(scc); + save_flags(flags); + cnt2 = count; while (cnt2) { - cnt = cnt2 > BUFSIZE? BUFSIZE:cnt2; + cli(); + cnt = cnt2 > SERIAL_XMIT_SIZE? SERIAL_XMIT_SIZE:cnt2; cnt2 -= cnt; - if (from_user) - memcpy_fromfs(tbuf, buf, cnt); + if (from_user){ + down(&tmp_buf_sem); + memcpy_fromfs(tmp_buf, buf, cnt); + up(&tmp_buf_sem); + } else - memcpy(tbuf, buf, cnt); + memcpy(tmp_buf, buf, cnt); buf += cnt; - p=tbuf; + p=tmp_buf; while(cnt--) if (kiss_decode(scc, *p++)) { scc->stat.nospace++; + restore_flags(flags); return 0; } } /* 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; } @@ -2092,7 +2065,7 @@ struct scc_channel *scc = tty->driver_data; scc_paranoia_check(scc, tty->device, "scc_flush_chars"); /* just to annoy the user... */ - + return; /* no flush needed */ } @@ -2101,7 +2074,7 @@ static int scc_write_room(struct tty_struct *tty) { struct scc_channel *scc = tty->driver_data; - + if (scc_paranoia_check(scc, tty->device, "scc_write_room")) return 0; @@ -2117,7 +2090,7 @@ static int scc_chars_in_buffer(struct tty_struct *tty) { struct scc_channel *scc = tty->driver_data; - + if (scc && scc->sndq2) return scc->sndq2->cnt; else @@ -2127,37 +2100,35 @@ static void scc_flush_buffer(struct tty_struct *tty) { struct scc_channel *scc = tty->driver_data; - + if (scc_paranoia_check(scc, tty->device, "scc_flush_buffer")) return; 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) { struct scc_channel *scc = tty->driver_data; - + if (scc_paranoia_check(scc, tty->device, "scc_throttle")) return; /* dummy */ + } static void scc_unthrottle(struct tty_struct *tty) { struct scc_channel *scc = tty->driver_data; - + if (scc_paranoia_check(scc, tty->device, "scc_unthrottle")) return; /* dummy */ + } static void scc_start(struct tty_struct *tty) @@ -2181,6 +2152,14 @@ /* 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 * */ @@ -2188,7 +2167,11 @@ long scc_init (long kmem_start) { - int chip, chan; + + int chip; +#ifdef VERBOSE_BOOTMSG + int chan; +#endif register io_port ctrl; long flags; @@ -2200,31 +2183,31 @@ scc_driver.minor_start = 96; scc_driver.num = Nchips*2; 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.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.refcount = &scc_refcount; /* not needed yet */ scc_driver.table = scc_table; scc_driver.termios = (struct termios **) scc_termios; scc_driver.termios_locked = (struct termios **) scc_termios_locked; + scc_driver.open = scc_open; scc_driver.close = scc_close; scc_driver.write = scc_write; - scc_driver.start = scc_start; - scc_driver.stop = scc_stop; - scc_driver.put_char = scc_put_char; scc_driver.flush_chars = scc_flush_chars; scc_driver.write_room = scc_write_room; scc_driver.chars_in_buffer = scc_chars_in_buffer; scc_driver.flush_buffer = scc_flush_buffer; - + scc_driver.ioctl = scc_ioctl; scc_driver.throttle = scc_throttle; scc_driver.unthrottle = scc_unthrottle; - - scc_driver.ioctl = scc_ioctl; 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)) panic("Couldn't register Z8530 SCC driver\n"); diff -u --recursive --new-file v1.3.10/linux/drivers/net/Makefile linux/drivers/net/Makefile --- v1.3.10/linux/drivers/net/Makefile Tue Jul 11 10:02:49 1995 +++ linux/drivers/net/Makefile Fri Jul 14 07:24:58 1995 @@ -42,6 +42,8 @@ ifdef CONFIG_HP100 NETDRV_OBJS := $(NETDRV_OBJS) hp100.o +else +MODULES := $(MODULES) hp100.o endif ifdef CONFIG_WD80x3 diff -u --recursive --new-file v1.3.10/linux/drivers/net/hp100.c linux/drivers/net/hp100.c --- v1.3.10/linux/drivers/net/hp100.c Fri Jul 7 08:54:47 1995 +++ linux/drivers/net/hp100.c Fri Jul 14 07:24:58 1995 @@ -65,6 +65,7 @@ * 0.11 14-Jun-95 Reset interface bug fixed? * Little bug in hp100_close function fixed. * 100Mb/s connection debugged. + * 0.12 14-Jul-95 Link down is now handled better. * */ @@ -350,12 +351,6 @@ int ioaddr = dev -> base_addr; 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 ) ) { printk( "%s: unable to get IRQ %d\n", dev -> name, dev -> irq ); @@ -372,6 +367,7 @@ dev -> interrupt = 0; dev -> start = 1; + lp -> lan_type = hp100_sense_lan( dev ); lp -> mac1_mode = HP100_MAC1MODE3; lp -> mac2_mode = HP100_MAC2MODE3; @@ -424,11 +420,11 @@ struct hp100_private *lp = (struct hp100_private *)dev -> priv; 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 ); dev -> tbusy = 1; @@ -452,6 +448,20 @@ int ioaddr = dev -> base_addr; u_short val; 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 ) { @@ -463,11 +473,9 @@ /* 100Mb/s adapter isn't connected to hub */ { printk( "%s: login to 100Mb/s hub retry\n", dev -> name ); - hp100_ints_off(); hp100_stop_interface( dev ); lp -> hub_status = hp100_login_to_vg_hub( dev ); hp100_start_interface( dev ); - hp100_ints_on(); } else { @@ -483,20 +491,16 @@ /* it's very heavy - all network setting must be changed!!! */ printk( "%s: cable change 10Mb/s <-> 100Mb/s detected\n", dev -> name ); lp -> lan_type = i; - hp100_ints_off(); hp100_stop_interface( dev ); if ( lp -> lan_type == HP100_LAN_100 ) lp -> hub_status = hp100_login_to_vg_hub( dev ); hp100_start_interface( dev ); - hp100_ints_on(); } else { printk( "%s: interface reset\n", dev -> name ); - hp100_ints_off(); hp100_stop_interface( dev ); hp100_start_interface( dev ); - hp100_ints_on(); } } dev -> trans_start = jiffies; @@ -566,6 +570,15 @@ u_int header; 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 ); #ifdef HP100_DEBUG if ( packets > 1 ) @@ -730,6 +743,7 @@ printk( "%s: re-entering the interrupt handler\n", dev -> name ); hp100_ints_off(); dev -> interrupt = 1; + hp100_page( PERFORMANCE ); val = hp100_inw( IRQ_STATUS ); #ifdef HP100_DEBUG_IRQ printk( "hp100_interrupt: irq_status = 0x%x\n", val ); diff -u --recursive --new-file v1.3.10/linux/drivers/net/pi2.c linux/drivers/net/pi2.c --- v1.3.10/linux/drivers/net/pi2.c Thu Jul 13 16:20:20 1995 +++ linux/drivers/net/pi2.c Tue Jul 18 14:53:05 1995 @@ -49,6 +49,7 @@ April 23, 1995 (dp) Fixed ioctl so it works properly with piconfig program when changing the baud rate or clock mode. version 0.8 ALPHA + July 17, 1995 (ac) Finally polishing of AX25.030+ support */ @@ -59,7 +60,7 @@ of each transmitted packet. If this causes you to lose sleep, #undefine it. */ -#define STUFF2 1 +/*#define STUFF2 1*/ /* The default configuration */ #define PI_DMA 3 @@ -1429,10 +1430,10 @@ dev->rebuild_header = pi_rebuild_header; dev->set_mac_address = pi_set_mac_address; - dev->type = ARPHRD_AX25; /* AF_AX25 device */ - dev->hard_header_len = 17; /* We don't do digipeaters */ - dev->mtu = 1500; /* eth_mtu is the default */ - dev->addr_len = 7; /* sizeof an ax.25 address */ + dev->type = ARPHRD_AX25; /* AF_AX25 device */ + dev->hard_header_len = 73; /* We do digipeaters now */ + dev->mtu = 1500; /* eth_mtu is the default */ + dev->addr_len = 7; /* sizeof an ax.25 address */ memcpy(dev->broadcast, ax25_bcast, 7); memcpy(dev->dev_addr, ax25_test, 7); diff -u --recursive --new-file v1.3.10/linux/drivers/net/slip.c linux/drivers/net/slip.c --- v1.3.10/linux/drivers/net/slip.c Thu Jul 13 16:20:21 1995 +++ linux/drivers/net/slip.c Tue Jul 18 14:53:05 1995 @@ -36,6 +36,7 @@ * statistics. Include CSLIP code only * if it really needed. * Alan Cox : Free slhc buffers in the right place. + * Alan Cox : Allow for digipeated IP over AX.25 * * * @@ -1014,7 +1015,7 @@ #else if ((tmp & SL_MODE_AX25) || (tmp & SL_MODE_AX25VC)) { 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 { sl->dev->addr_len=0; /* No mac addr in slip mode */ sl->dev->hard_header_len=0; Binary files v1.3.10/linux/drivers/scsi/aic7770 and linux/drivers/scsi/aic7770 differ diff -u --recursive --new-file v1.3.10/linux/drivers/scsi/aic7xxx.c linux/drivers/scsi/aic7xxx.c --- v1.3.10/linux/drivers/scsi/aic7xxx.c Thu Jun 29 19:02:48 1995 +++ linux/drivers/scsi/aic7xxx.c Tue Jul 18 10:22:02 1995 @@ -3,36 +3,24 @@ * * Copyright (c) 1994 John Aycock * The University of Calgary Department of Computer Science. - * All rights reserved. * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * 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 program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + * + * An alternate version of this driver with a BSD-style copyright can + * be found on XXX. * - * 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 * driver (ultrastor.c), various Linux kernel source, the Adaptec EISA * config file (!adp7771.cfg), the Adaptec AHA-2740A Series User's Guide, diff -u --recursive --new-file v1.3.10/linux/drivers/scsi/aic7xxx.h linux/drivers/scsi/aic7xxx.h --- v1.3.10/linux/drivers/scsi/aic7xxx.h Fri Jul 7 08:54:49 1995 +++ linux/drivers/scsi/aic7xxx.h Tue Jul 18 10:23:11 1995 @@ -3,36 +3,24 @@ * * Copyright (c) 1994 John Aycock * The University of Calgary Department of Computer Science. - * All rights reserved. * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * 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 program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. * - * 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. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. * + * An alternate version of this driver with a BSD-style copyright can + * be found on XXX. + * * $Id: aic7xxx.h,v 1.18 1995/06/22 04:17:56 deang Exp $ *-M*************************************************************************/ #ifndef _aic7xxx_h diff -u --recursive --new-file v1.3.10/linux/drivers/scsi/aic7xxx_asm.c linux/drivers/scsi/aic7xxx_asm.c --- v1.3.10/linux/drivers/scsi/aic7xxx_asm.c Thu Jun 29 19:02:48 1995 +++ linux/drivers/scsi/aic7xxx_asm.c Tue Jul 18 10:23:11 1995 @@ -3,35 +3,23 @@ * * Copyright (c) 1994 John Aycock * The University of Calgary Department of Computer Science. - * All rights reserved. * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * 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 program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. * - * 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. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + * + * An alternate version of this driver with a BSD-style copyright can + * be found on XXX. * * Comments are started by `#' and continue to the end of the line; lines * may be of the form: diff -u --recursive --new-file v1.3.10/linux/drivers/scsi/eata_dma.c linux/drivers/scsi/eata_dma.c --- v1.3.10/linux/drivers/scsi/eata_dma.c Fri Jun 30 16:22:29 1995 +++ linux/drivers/scsi/eata_dma.c Sun Jul 16 21:45:00 1995 @@ -1,52 +1,54 @@ /************************************************************ - * * - * Linux EATA SCSI driver * - * * - * based on the CAM document CAM/89-004 rev. 2.0c, * + * * + * Linux EATA SCSI driver * + * * + * based on the CAM document CAM/89-004 rev. 2.0c, * * DPT's driver kit, some internal documents and source, * * and several other Linux scsi drivers and kernel docs. * - * * - * The driver currently: * - * -supports all ISA based EATA-DMA boards * - * -supports all EISA based EATA-DMA boards * - * -supports all PCI based EATA-DMA boards * - * -supports multiple HBAs with & without IRQ sharing * - * -supports all SCSI channels on multi channel boards * - * -can be loaded as module * - * -displays statistical and hardware information * - * in /proc/scsi/eata_dma * - * -needs identical HBA ids on all channels * - * * - * (c)1993,94,95 Michael Neuffer * - * neuffer@goofy.zdv.uni-mainz.de * - * * + * * + * The driver currently: * + * -supports all ISA based EATA-DMA boards * + * -supports all EISA based EATA-DMA boards * + * -supports all PCI based EATA-DMA boards * + * -supports multiple HBAs with & without IRQ sharing * + * -supports all SCSI channels on multi channel boards * + * -needs identical IDs on all channels of a HBA * + * -can be loaded as module * + * -displays statistical and hardware information * + * in /proc/scsi/eata_dma * + * -provides rudimentary latency measurement * + * possibilities via /proc/scsi/eata_dma/ * + * * + * (c)1993,94,95 Michael Neuffer * + * neuffer@goofy.zdv.uni-mainz.de * + * * * This program is free software; you can redistribute it * - * and/or modify it under the terms of the GNU General * - * Public License as published by the Free Software * - * Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * + * and/or modify it under the terms of the GNU General * + * Public License as published by the Free Software * + * Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * * This program is distributed in the hope that it will be * - * useful, but WITHOUT ANY WARRANTY; without even the * + * useful, but WITHOUT ANY WARRANTY; without even the * * implied warranty of MERCHANTABILITY or FITNESS FOR A * - * PARTICULAR PURPOSE. See the GNU General Public License * - * for more details. * - * * - * You should have received a copy of the GNU General * + * PARTICULAR PURPOSE. See the GNU General Public License * + * for more details. * + * * + * You should have received a copy of the GNU General * * Public License along with this kernel; if not, write to * - * the Free Software Foundation, Inc., 675 Mass Ave, * - * Cambridge, MA 02139, USA. * - * * + * the Free Software Foundation, Inc., 675 Mass Ave, * + * Cambridge, MA 02139, USA. * + * * * I have to thank DPT for their excellent support. I took * * me almost a year and a stopover at their HQ, on my first * * trip to the USA, to get it, but since then they've been * - * very helpful and tried to give me all the infos and * - * support I need. * - * * + * very helpful and tried to give me all the infos and * + * support I need. * + * * * 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 */ @@ -205,13 +207,33 @@ eata_stat, hba_stat)); switch (hba_stat) { - case HA_NO_ERROR: /* NO Error */ + case HA_NO_ERROR: /* NO Error */ if (scsi_stat == CONDITION_GOOD && cmd->device->type == TYPE_DISK && (HD(cmd)->t_state[cp->cp_channel][cp->cp_id] == RESET)) - result = DID_BUS_BUSY << 16; - else if (scsi_stat == GOOD) + result = DID_BUS_BUSY << 16; + else if (scsi_stat == GOOD) { 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 && cmd->device->type == TYPE_DISK && (cmd->sense_buffer[2] & 0xf) == RECOVERED_ERROR) @@ -220,10 +242,10 @@ result = DID_OK << 16; HD(cmd)->t_timeout[cp->cp_channel][cp->cp_id] = OK; break; - case HA_ERR_SEL_TO: /* Selection Timeout */ + case HA_ERR_SEL_TO: /* Selection Timeout */ result = DID_BAD_TARGET << 16; break; - case HA_ERR_CMD_TO: /* Command Timeout */ + case HA_ERR_CMD_TO: /* Command Timeout */ if (HD(cmd)->t_timeout[cp->cp_channel][cp->cp_id] > 1) result = DID_ERROR << 16; else { @@ -231,8 +253,8 @@ HD(cmd)->t_timeout[cp->cp_channel][cp->cp_id]++; } break; - case HA_ERR_RESET: /* SCSI Bus Reset Received */ - case HA_INIT_POWERUP: /* Initial Controller Power-up */ + case HA_ERR_RESET: /* SCSI Bus Reset Received */ + case HA_INIT_POWERUP: /* Initial Controller Power-up */ if (cmd->device->type != TYPE_TAPE) result = DID_BUS_BUSY << 16; else @@ -241,14 +263,14 @@ for (i = 0; i < MAXTARGET; i++) HD(cmd)->t_state[cp->cp_channel][i] = RESET; break; - case HA_UNX_BUSPHASE: /* Unexpected Bus Phase */ - case HA_UNX_BUS_FREE: /* Unexpected Bus Free */ - case HA_BUS_PARITY: /* Bus Parity Error */ - case HA_SCSI_HUNG: /* SCSI Hung */ - case HA_UNX_MSGRJCT: /* Unexpected Message Reject */ - case HA_RESET_STUCK: /* SCSI Bus Reset Stuck */ - case HA_RSENSE_FAIL: /* Auto Request-Sense Failed */ - case HA_PARITY_ERR: /* Controller Ram Parity */ + case HA_UNX_BUSPHASE: /* Unexpected Bus Phase */ + case HA_UNX_BUS_FREE: /* Unexpected Bus Free */ + case HA_BUS_PARITY: /* Bus Parity Error */ + case HA_SCSI_HUNG: /* SCSI Hung */ + case HA_UNX_MSGRJCT: /* Unexpected Message Reject */ + case HA_RESET_STUCK: /* SCSI Bus Reset Stuck */ + case HA_RSENSE_FAIL: /* Auto Request-Sense Failed */ + case HA_PARITY_ERR: /* Controller Ram Parity */ default: result = DID_ERROR << 16; break; @@ -267,7 +289,7 @@ DBG(DBG_INTR&&DBG_DELAY,DEL2(800)); #endif - cp->status = FREE; /* now we can release the slot */ + cp->status = FREE; /* now we can release the slot */ restore_flags(flags); if(cmd->scsi_done != eata_scsi_done) cmd->scsi_done(cmd); @@ -291,7 +313,7 @@ if (--loop == 0) return(FALSE); - outb( addr & 0x000000ff, base + HA_WDMAADDR); + outb( addr & 0x000000ff, base + HA_WDMAADDR); outb((addr & 0x0000ff00) >> 8, base + HA_WDMAADDR + 1); outb((addr & 0x00ff0000) >> 16, base + HA_WDMAADDR + 2); outb((addr & 0xff000000) >> 24, base + HA_WDMAADDR + 3); @@ -304,8 +326,8 @@ u8 lun) { if(addr){ - outb( addr & 0x000000ff, base + HA_WDMAADDR); - outb((addr & 0x0000ff00) >> 8, base + HA_WDMAADDR + 1); + outb( addr & 0x000000ff, base + HA_WDMAADDR); + outb((addr & 0x0000ff00) >> 8, base + HA_WDMAADDR + 1); outb((addr & 0x00ff0000) >> 16, base + HA_WDMAADDR + 2); outb((addr & 0xff000000) >> 24, base + HA_WDMAADDR + 3); } else { @@ -314,7 +336,7 @@ } outb(cmnd2, base + HA_WCOMMAND2); - outb(cmnd, base + HA_WCOMMAND); + outb(cmnd, base + HA_WCOMMAND); return(TRUE); } #endif @@ -327,10 +349,10 @@ struct Scsi_Host *sh; struct eata_ccb *cp; struct scatterlist *sl; - + save_flags(flags); cli(); - + queue_counter++; if (done == (void *)eata_scsi_done) { @@ -354,61 +376,93 @@ hd->last_ccb = y; if (x == sh->can_queue) { - DBG(DBG_QUEUE, printk("can_queue %d, x %d, y %d\n", sh->can_queue, x, y)); -#if DEBUG_EATA + panic("eata_dma: run out of queue slots cmdno:%ld intrno: %ld\n", queue_counter, int_counter); -#else - panic("eata_dma: run out of queue slots....\n"); -#endif } cp = &hd->ccb[y]; memset(cp, 0, sizeof(struct eata_ccb) - sizeof(struct eata_sg_list *)); - cp->status = USED; /* claim free slot */ + cp->status = USED; /* claim free slot */ DBG(DBG_QUEUE, printk("eata_queue pid %ld, target: %x, lun: %x, y %d\n", cmd->pid, cmd->target, cmd->lun, y)); 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; switch (cmd->cmnd[0]) { - case CHANGE_DEFINITION: case COMPARE: case COPY: - case COPY_VERIFY: case LOG_SELECT: case MODE_SELECT: + case CHANGE_DEFINITION: case COMPARE: case COPY: + case COPY_VERIFY: case LOG_SELECT: case MODE_SELECT: case MODE_SELECT_10: case SEND_DIAGNOSTIC: case WRITE_BUFFER: - case FORMAT_UNIT: case REASSIGN_BLOCKS: case RESERVE: - case SEARCH_EQUAL: case SEARCH_HIGH: case SEARCH_LOW: - case WRITE_6: case WRITE_10: case WRITE_VERIFY: - case UPDATE_BLOCK: case WRITE_LONG: case WRITE_SAME: + case FORMAT_UNIT: case REASSIGN_BLOCKS: case RESERVE: + case SEARCH_EQUAL: case SEARCH_HIGH: case SEARCH_LOW: + case WRITE_6: case WRITE_10: case WRITE_VERIFY: + case UPDATE_BLOCK: case WRITE_LONG: case WRITE_SAME: case SEARCH_HIGH_12: case SEARCH_EQUAL_12: case SEARCH_LOW_12: - case WRITE_12: case WRITE_VERIFY_12: case SET_WINDOW: - case MEDIUM_SCAN: case SEND_VOLUME_TAG: - case 0xea: /* alternate number for WRITE LONG */ - cp->DataOut = TRUE; /* Output mode */ + case WRITE_12: case WRITE_VERIFY_12: case SET_WINDOW: + case MEDIUM_SCAN: case SEND_VOLUME_TAG: + case 0xea: /* alternate number for WRITE LONG */ + cp->DataOut = TRUE; /* Output mode */ break; case TEST_UNIT_READY: default: - cp->DataIn = TRUE; /* Input mode */ + cp->DataIn = TRUE; /* Input mode */ } if ((done == (void *) eata_scsi_done && HBA_interpret == TRUE) || cmd->target == sh->this_id) - cp->Interpret = TRUE; /* Interpret command */ + cp->Interpret = TRUE; /* Interpret command */ if (cmd->use_sg) { - cp->scatter = TRUE; /* SG mode */ + cp->scatter = TRUE; /* SG mode */ if (cp->sg_list == NULL) { cp->sg_list = kmalloc(SG_SIZE_BIG*sizeof(struct eata_sg_list), - GFP_ATOMIC | GFP_DMA); + GFP_ATOMIC | GFP_DMA); } cp->cp_dataDMA = htonl((ulong)cp->sg_list); if (cp->cp_dataDMA == 0) panic("eata_dma: Run out of DMA memory for SG lists !\n"); - + cp->cp_datalen = htonl(cmd->use_sg * sizeof(struct eata_sg_list)); sl=(struct scatterlist *)cmd->request_buffer; for(i = 0; i < cmd->use_sg; i++, sl++){ @@ -436,7 +490,7 @@ cp->cp_viraddr = cp; cp->cmd = cmd; - cmd->host_scribble = (char *)&hd->ccb[y]; + cmd->host_scribble = (char *)&hd->ccb[y]; if(eata_send_command((u32) cp, (u32) sh->base, EATA_CMD_DMA_SEND_CP) == FALSE) { cmd->result = DID_ERROR << 16; @@ -563,7 +617,7 @@ } /* hard reset the HBA */ - inb((u32) (cmd->host->base) + HA_RSTATUS); /* This might cause trouble */ + inb((u32) (cmd->host->base) + HA_RSTATUS); /* This might cause trouble */ eata_send_command(0, (u32) cmd->host->base, EATA_CMD_RESET); DBG(DBG_ABNORM, printk("eata_reset: board reset done, enabling interrupts.\n")); @@ -572,7 +626,7 @@ restore_flags(flags); time = jiffies; - while (jiffies < (time + 300) && limit++ < 10000000) + while (jiffies < (time + (3 * HZ)) && limit++ < 10000000) /* nothing */; save_flags(flags); @@ -635,7 +689,7 @@ memset(sp, 0, sizeof(struct eata_sp)); memset(buff, 0, 256); - cp->DataIn = TRUE; + cp->DataIn = TRUE; cp->Interpret = TRUE; /* Interpret command */ cp->cp_datalen = htonl(255); @@ -659,7 +713,7 @@ 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) barrier(); @@ -676,7 +730,7 @@ inb((u32) (base) + HA_RSTATUS); eata_send_command(0, base, EATA_CMD_RESET); i = jiffies; - while (jiffies < (i + 300) && limit++ < 10000000) + while (jiffies < (i + (3 * HZ)) && limit++ < 10000000) barrier(); return (NULL); } else @@ -734,7 +788,7 @@ *p = inw(base + HA_RDATA); } - if (!(inb(base + HA_RSTATUS) & HA_SERROR)) { /* Error ? */ + if (!(inb(base + HA_RSTATUS) & HA_SERROR)) { /* Error ? */ if (htonl(EATA_SIGNATURE) == buf->signature) { DBG(DBG_PIO&&DBG_PROBE, printk("EATA Controller found at %x " "EATA Level: %x\n", (uint) base, @@ -767,7 +821,7 @@ gc->SG_64K, gc->SG_UAE, gc->MAX_ID, gc->MAX_CHAN, gc->MAX_LUN); printk("RIDQ:%d PCI:%d EISA:%d\n", 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, @@ -779,6 +833,7 @@ unchar bugs = 0; struct Scsi_Host *sh; hostdata *hd; + int x; DBG(DBG_REGISTER, print_config(gc)); @@ -792,7 +847,7 @@ if(gc->HAA_valid == FALSE || ntohl(gc->len) < 0x22) gc->MAX_CHAN = 0; - if (reg_IRQ[gc->IRQ] == FALSE) { /* Interrupt already registered ? */ + if (reg_IRQ[gc->IRQ] == FALSE) { /* Interrupt already registered ? */ if (!request_irq(gc->IRQ, (void *) eata_fake_int_handler, SA_INTERRUPT, "eata_dma")){ reg_IRQ[gc->IRQ]++; @@ -802,7 +857,7 @@ printk("Couldn't allocate IRQ %d, Sorry.", gc->IRQ); return (FALSE); } - } else { /* More than one HBA on this IRQ */ + } else { /* More than one HBA on this IRQ */ if (reg_IRQL[gc->IRQ] == TRUE) { printk("Can't support more than one HBA on this IRQ,\n" " if the IRQ is edge triggered. Sorry.\n"); @@ -861,7 +916,7 @@ if(ntohs(gc->queuesiz) == 0) { gc->queuesiz = ntohs(64); printk("Warning: Queue size has to be corrected. Assuming 64 queueslots\n" - " This might be a PM2012B with a defective Firmware\n"); + " This might be a PM2012B with a defective Firmware\n"); } size = sizeof(hostdata) + ((sizeof(struct eata_ccb) + sizeof(long)) @@ -883,7 +938,7 @@ return (FALSE); } - hd = SD(sh); + hd = SD(sh); memset(hd->ccb, 0, sizeof(struct eata_ccb) * ntohs(gc->queuesiz)); memset(hd->reads, 0, sizeof(u32) * 26); @@ -894,7 +949,7 @@ strcpy(SD(sh)->vendor, "DPT"); strcpy(SD(sh)->name, "??????????"); strcpy(SD(sh)->revision, "???.?"); - } else { + } else { strncpy(SD(sh)->vendor, &buff[8], 8); SD(sh)->vendor[8] = 0; strncpy(SD(sh)->name, &buff[16], 17); @@ -918,7 +973,7 @@ SD(sh)->EATA_revision = 'c'; break; case 0x24: - SD(sh)->EATA_revision = 'z'; + SD(sh)->EATA_revision = 'z'; default: SD(sh)->EATA_revision = '?'; } @@ -948,7 +1003,7 @@ sh->max_lun = 8; } - hd->channel = gc->MAX_CHAN; + hd->channel = gc->MAX_CHAN; sh->max_channel = gc->MAX_CHAN; sh->base = (char *) base; sh->io_port = (u16) base; @@ -960,7 +1015,7 @@ * SCSI midlevel code should support different HBA ids on every channel */ 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(hd->bustype != IS_ISA) @@ -997,15 +1052,20 @@ else hd->primary = TRUE; - sh->wish_block = FALSE; + sh->wish_block = FALSE; if (hd->bustype != IS_ISA) { sh->unchecked_isa_dma = FALSE; } else { - sh->unchecked_isa_dma = TRUE; /* We're doing ISA DMA */ + sh->unchecked_isa_dma = TRUE; /* We're doing ISA DMA */ } - hd->next = NULL; /* build a linked list of all HBAs */ + 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->prev = last_HBA; if(hd->prev != NULL) SD(hd->prev)->next = sh; @@ -1028,7 +1088,7 @@ #endif for (i = 0; i < MAXEISA; i++) { - if (EISAbases[i] == TRUE) { /* Still a possibility ? */ + if (EISAbases[i] == TRUE) { /* Still a possibility ? */ base = 0x1c88 + (i * 0x1000); #if CHECKPAL @@ -1090,7 +1150,7 @@ #else u8 pci_bus, pci_device_fn; - static s16 pci_index = 0; /* Device index to PCI BIOS calls */ + static s16 pci_index = 0; /* Device index to PCI BIOS calls */ u32 base = 0; u16 com_adr; u16 rev_device; @@ -1142,8 +1202,8 @@ if (base != 0x1f8) { /* We didn't find it in the primary search */ if (get_conf_PIO(base, buf) == TRUE) { - if (buf->FORCADR) /* If the address is forced */ - continue; /* we'll find it later */ + if (buf->FORCADR) /* If the address is forced */ + continue; /* we'll find it later */ /* OK. We made it till here, so we can go now * and register it. We only have to check and @@ -1177,7 +1237,7 @@ } else printk("eata_dma: No BIOS32 extensions present. This driver release " "still depends on it.\n" - " Skipping scan for PCI HBAs. \n"); + " Skipping scan for PCI HBAs. \n"); #endif /* #ifndef CONFIG_PCI */ return; } @@ -1210,14 +1270,14 @@ if (registered_HBAs != 0) { printk("EATA (Extended Attachment) driver version: %d.%d%s\n" - "developed in co-operation with DPT\n" + "developed in co-operation with DPT\n" "(c) 1993-95 Michael Neuffer, neuffer@goofy.zdv.uni-mainz.de\n", VER_MAJOR, VER_MINOR, VER_SUB); printk("Registered HBAs:"); printk("\nHBA no. Boardtype: Revis: EATA: Bus: BaseIO: IRQ: DMA: Ch: " "ID: Pr: QS: SG: CPL:\n"); for (i = 1; i <= registered_HBAs; i++) { - printk("scsi%-2d: %.10s v%s 2.0%c %s %#.4x %2d", + printk("scsi%-2d: %.10s v%s 2.0%c %s %#.4x %2d", HBA_ptr->host_no, SD(HBA_ptr)->name, SD(HBA_ptr)->revision, SD(HBA_ptr)->EATA_revision, (SD(HBA_ptr)->bustype == 'P')? "PCI ":(SD(HBA_ptr)->bustype == 'E')?"EISA":"ISA ", @@ -1226,7 +1286,7 @@ printk(" %2x ", HBA_ptr->dma_channel); else printk(" %s", "BMST"); - printk(" %d %d %c %2d %2d %2d\n", SD(HBA_ptr)->channel, + printk(" %d %d %c %2d %2d %2d\n", SD(HBA_ptr)->channel, HBA_ptr->this_id, (SD(HBA_ptr)->primary == TRUE)?'Y':'N', HBA_ptr->can_queue, HBA_ptr->sg_tablesize, HBA_ptr->cmd_per_lun); HBA_ptr = SD(HBA_ptr)->next; @@ -1237,7 +1297,7 @@ scsi_init_free((void *)dma_scratch, 512); - DBG(DPT_DEBUG, DELAY(1200)); + DBG(DPT_DEBUG, DELAY(12)); return(registered_HBAs); } @@ -1262,7 +1322,6 @@ * c-label-offset: -4 * c-continued-statement-offset: 4 * c-continued-brace-offset: 0 - * indent-tabs-mode: nil * tab-width: 8 * End: */ diff -u --recursive --new-file v1.3.10/linux/drivers/scsi/eata_dma.h linux/drivers/scsi/eata_dma.h --- v1.3.10/linux/drivers/scsi/eata_dma.h Fri Jun 30 16:22:29 1995 +++ linux/drivers/scsi/eata_dma.h Sun Jul 16 21:45:00 1995 @@ -16,7 +16,7 @@ #define VER_MAJOR 2 #define VER_MINOR 5 -#define VER_SUB "6a" +#define VER_SUB "7a" /************************************************************************ diff -u --recursive --new-file v1.3.10/linux/drivers/scsi/eata_dma_proc.c linux/drivers/scsi/eata_dma_proc.c --- v1.3.10/linux/drivers/scsi/eata_dma_proc.c Tue Jul 11 10:02:50 1995 +++ linux/drivers/scsi/eata_dma_proc.c Sun Jul 16 21:45:00 1995 @@ -4,11 +4,11 @@ { "Direct-Access ", "Sequential-Access", - "Printer ", - "Processor ", - "WORM ", - "CD-ROM ", - "Scanner ", + "Printer ", + "Processor ", + "WORM ", + "CD-ROM ", + "Scanner ", "Optical Device ", "Medium Changer ", "Communications " @@ -47,8 +47,24 @@ */ int eata_set_info(char *buffer, int length, struct Scsi_Host *HBA_ptr) { - DBG(DBG_PROC_WRITE, printk("%s\n", buffer)); - return(-ENOSYS); /* Currently this is a no-op */ + if (length >= 8 && strncmp(buffer, "eata_dma", 8) == 0) { + 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); } /* @@ -72,19 +88,19 @@ static u8 buff[512]; static u8 buff2[512]; hst_cmd_stat *rhcs, *whcs; - coco *cc; - scsitrans *st; - scsimod *sm; - hobu *hb; - scbu *sb; - boty *bt; - memco *mc; - firm *fm; - subinf *si; - pcinf *pi; - arrlim *al; + coco *cc; + scsitrans *st; + scsimod *sm; + hobu *hb; + scbu *sb; + boty *bt; + memco *mc; + firm *fm; + subinf *si; + pcinf *pi; + arrlim *al; int i, x; - int size, len = 0; + int size, len = 0; off_t begin = 0; off_t pos = 0; @@ -327,7 +343,7 @@ SD(HBA_ptr)->writes[11]); len += size; 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)->writes[12]); len += size; @@ -341,6 +357,79 @@ if (pos > offset + length) 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; size = sprintf(buffer+len,"Attached devices: %s\n", (scd)?"":"none"); @@ -350,7 +439,8 @@ while (scd) { 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); for (x = 0; x < 8; x++) { if (scd->vendor[x] >= 0x20) diff -u --recursive --new-file v1.3.10/linux/drivers/scsi/eata_generic.h linux/drivers/scsi/eata_generic.h --- v1.3.10/linux/drivers/scsi/eata_generic.h Fri Jun 30 16:22:29 1995 +++ linux/drivers/scsi/eata_generic.h Sun Jul 16 21:45:00 1995 @@ -51,19 +51,19 @@ #define SG_SIZE_BIG 509 /* max. 509 */ #define C_P_L_DIV 2 /* 1 <= C_P_L_DIV <= 8 - * You can use this parameter to fine-tune - * the driver. Depending on the number of - * devices and their speed and ability to queue - * commands, you will get the best results with a - * value - * ~= numdevices-(devices_unable_to_queue_commands/2) - * The reason for this is that the disk driver - * tends to flood the queue, so that other - * drivers have problems to queue commands - * themselves. This can for example result in - * the effect that the tape stops during disk - * accesses. - */ + * You can use this parameter to fine-tune + * the driver. Depending on the number of + * devices and their speed and ability to queue + * commands, you will get the best results with a + * value + * ~= numdevices-(devices_unable_to_queue_commands/2) + * The reason for this is that the disk driver + * tends to flood the queue, so that other + * drivers have problems to queue commands + * themselves. This can for example result in + * the effect that the tape stops during disk + * accesses. + */ #define FREE 0 #define OK 0 @@ -77,7 +77,7 @@ #define CD(cmd) ((struct eata_ccb *)(cmd->host_scribble)) #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++); } /*********************************************** @@ -189,9 +189,9 @@ __u8 data_reg[2]; /* R, couldn't figure this one out */ __u8 cp_addr[4]; /* W, CP address register */ union { - __u8 command; /* W, command code: [read|set] conf, send CP*/ - struct reg_bit status; /* R, see register_bit1 */ - __u8 statusbyte; + __u8 command; /* W, command code: [read|set] conf, send CP*/ + struct reg_bit status; /* R, see register_bit1 */ + __u8 statusbyte; } ovr; struct reg_abit aux_stat; /* R, see register_bit2 */ }; @@ -200,48 +200,48 @@ __u32 len; /* Should return 0x22, 0x24, etc */ __u32 signature; /* Signature MUST be "EATA" */ __u8 version2:4, - version:4; /* EATA Version level */ + version:4; /* EATA Version level */ __u8 OCS_enabled:1, /* Overlap Command Support enabled */ - TAR_support:1, /* SCSI Target Mode supported */ - TRNXFR:1, /* Truncate Transfer Cmd not necessary */ - /* Only used in PIO Mode */ - MORE_support:1, /* MORE supported (only PIO Mode) */ - DMA_support:1, /* DMA supported Driver uses only */ - /* this mode */ - DMA_valid:1, /* DRQ value in Byte 30 is valid */ - ATA:1, /* ATA device connected (not supported) */ - HAA_valid:1; /* Hostadapter Address is valid */ - - __u16 cppadlen; /* Number of pad bytes send after CD data */ - /* set to zero for DMA commands */ - __u8 scsi_id[4]; /* SCSI ID of controller 2-0 Byte 0 res. */ - /* if not, zero is returned */ + TAR_support:1, /* SCSI Target Mode supported */ + TRNXFR:1, /* Truncate Transfer Cmd not necessary * + * Only used in PIO Mode */ + MORE_support:1, /* MORE supported (only PIO Mode) */ + DMA_support:1, /* DMA supported Driver uses only * + * this mode */ + DMA_valid:1, /* DRQ value in Byte 30 is valid */ + ATA:1, /* ATA device connected (not supported) */ + HAA_valid:1; /* Hostadapter Address is valid */ + + __u16 cppadlen; /* Number of pad bytes send after CD data * + * set to zero for DMA commands */ + __u8 scsi_id[4]; /* SCSI ID of controller 2-0 Byte 0 res. * + * if not, zero is returned */ __u32 cplen; /* CP length: number of valid cp bytes */ - __u32 splen; /* Number of bytes returned after */ - /* Receive SP command */ + __u32 splen; /* Number of bytes returned after * + * Receive SP command */ __u16 queuesiz; /* max number of queueable CPs */ __u16 dummy; __u16 SGsiz; /* max number of SG table entries */ __u8 IRQ:4, /* IRQ used this HA */ - IRQ_TR:1, /* IRQ Trigger: 0=edge, 1=level */ - SECOND:1, /* This is a secondary controller */ + IRQ_TR:1, /* IRQ Trigger: 0=edge, 1=level */ + SECOND:1, /* This is a secondary controller */ DMA_channel:2; /* DRQ index, DRQ is 2comp of DRQX */ - __u8 sync; /* device at ID 7 tru 0 is running in */ - /* synchronous mode, this will disappear */ + __u8 sync; /* device at ID 7 tru 0 is running in * + * synchronous mode, this will disappear */ __u8 DSBLE:1, /* ISA i/o addressing is disabled */ - FORCADR:1, /* i/o address has been forced */ - SG_64K:1, - SG_UAE:1, - :4; + FORCADR:1, /* i/o address has been forced */ + SG_64K:1, + SG_UAE:1, + :4; __u8 MAX_ID:5, /* Max number of SCSI target IDs */ - MAX_CHAN:3; /* Number of SCSI busses on HBA */ + MAX_CHAN:3; /* Number of SCSI busses on HBA */ __u8 MAX_LUN; /* Max number of LUNs */ __u8 :3, - AUTOTRM:1, - M1_inst:1, - ID_qest:1, /* Raidnum ID is questionable */ - is_PCI:1, /* HBA is PCI */ - is_EISA:1; /* HBA is EISA */ + AUTOTRM:1, + M1_inst:1, + ID_qest:1, /* Raidnum ID is questionable */ + is_PCI:1, /* HBA is PCI */ + is_EISA:1; /* HBA is EISA */ __u8 unused[478]; }; @@ -253,60 +253,62 @@ struct eata_ccb { /* Send Command Packet structure */ - __u8 SCSI_Reset:1, /* Cause a SCSI Bus reset on the cmd */ - HBA_Init:1, /* Cause Controller to reinitialize */ - Auto_Req_Sen:1, /* Do Auto Request Sense on errors */ - scatter:1, /* Data Ptr points to a SG Packet */ - Resrvd:1, /* RFU */ - Interpret:1, /* Interpret the SCSI cdb of own use */ - DataOut:1, /* Data Out phase with command */ - DataIn:1; /* Data In phase with command */ - __u8 reqlen; /* Request Sense Length */ - /* Valid if Auto_Req_Sen=1 */ + __u8 SCSI_Reset:1, /* Cause a SCSI Bus reset on the cmd */ + HBA_Init:1, /* Cause Controller to reinitialize */ + Auto_Req_Sen:1, /* Do Auto Request Sense on errors */ + scatter:1, /* Data Ptr points to a SG Packet */ + Resrvd:1, /* RFU */ + Interpret:1, /* Interpret the SCSI cdb of own use */ + DataOut:1, /* Data Out phase with command */ + DataIn:1; /* Data In phase with command */ + __u8 reqlen; /* Request Sense Length * + * Valid if Auto_Req_Sen=1 */ __u8 unused[3]; - __u8 FWNEST:1, /* send cmd to phys RAID component*/ - unused2:7; - __u8 Phsunit:1, /* physical unit on mirrored pair */ - I_AT:1, /* inhibit address translation */ - I_HBA_C:1, /* HBA inhibit caching */ - unused3:5; + __u8 FWNEST:1, /* send cmd to phys RAID component */ + unused2:7; + __u8 Phsunit:1, /* physical unit on mirrored pair */ + I_AT:1, /* inhibit address translation */ + I_HBA_C:1, /* HBA inhibit caching */ + unused3:5; - __u8 cp_id:5, /* SCSI Device ID of target */ - cp_channel:3; /* SCSI Channel # of HBA */ + __u8 cp_id:5, /* SCSI Device ID of target */ + cp_channel:3; /* SCSI Channel # of HBA */ __u8 cp_lun:3, - :2, - cp_luntar:1, /* CP is for target ROUTINE */ - cp_dispri:1, /* Grant disconnect privilege */ - cp_identify:1; /* Always TRUE */ - __u8 cp_msg1; /* Message bytes 0-3 */ + :2, + cp_luntar:1, /* CP is for target ROUTINE */ + cp_dispri:1, /* Grant disconnect privilege */ + cp_identify:1; /* Always TRUE */ + __u8 cp_msg1; /* Message bytes 0-3 */ __u8 cp_msg2; __u8 cp_msg3; - __u8 cp_cdb[12]; /* Command Descriptor Block */ - __u32 cp_datalen; /* Data Transfer Length */ - /* If scatter=1 len of sg package */ - void *cp_viraddr; /* address of this ccb */ - __u32 cp_dataDMA; /* Data Address, if scatter=1 * - * address of scatter packet */ - __u32 cp_statDMA; /* address for Status Packet */ - __u32 cp_reqDMA; /* Request Sense Address, used if */ - /* CP command ends with error */ - /* Additional CP info begins here */ + __u8 cp_cdb[12]; /* Command Descriptor Block */ + __u32 cp_datalen; /* Data Transfer Length * + * If scatter=1 len of sg package */ + void *cp_viraddr; /* address of this ccb */ + __u32 cp_dataDMA; /* Data Address, if scatter=1 * + * address of scatter packet */ + __u32 cp_statDMA; /* address for Status Packet */ + __u32 cp_reqDMA; /* Request Sense Address, used if * + * CP command ends with error */ + /* Additional CP info begins here */ + __u32 timestamp; /* Needed to measure command latency */ __u32 timeout; + __u8 sizeindex; + __u8 rw_latency; __u8 retries; - __u8 status; /* status of this queueslot */ - - Scsi_Cmnd *cmd; /* address of cmd */ + __u8 status; /* status of this queueslot */ + Scsi_Cmnd *cmd; /* address of cmd */ struct eata_sg_list *sg_list; }; struct eata_sp { - __u8 hba_stat:7, /* HBA status */ - EOC:1; /* True if command finished */ - __u8 scsi_stat; /* Target SCSI status */ + __u8 hba_stat:7, /* HBA status */ + EOC:1; /* True if command finished */ + __u8 scsi_stat; /* Target SCSI status */ __u8 reserved[2]; - __u32 residue_len; /* Number of bytes not transferred */ - struct eata_ccb *ccb; /* Address set in COMMAND PACKET */ + __u32 residue_len; /* Number of bytes not transferred */ + struct eata_ccb *ccb; /* Address set in COMMAND PACKET */ __u8 msg[12]; }; @@ -320,12 +322,15 @@ __u8 state; /* state of HBA */ __u8 primary; /* true if primary */ __u8 broken_INQUIRY:1; /* This is an EISA HBA with * - * broken INQUIRY */ + * broken INQUIRY */ + __u8 do_latency; /* Latency measurement flag */ __u32 reads[13]; __u32 writes[13]; - /* state of Target (RESET,..) */ + __u32 reads_lat[12][4]; + __u32 writes_lat[12][4]; + /* state of Target (RESET,..) */ __u8 t_state[MAXCHANNEL][MAXTARGET]; - /* timeouts on target */ + /* timeouts on target */ __u32 t_timeout[MAXCHANNEL][MAXTARGET]; __u32 last_ccb; /* Last used ccb */ __u32 cplen; /* size of CP in words */ @@ -372,7 +377,6 @@ * c-label-offset: -4 * c-continued-statement-offset: 4 * c-continued-brace-offset: 0 - * indent-tabs-mode: nil * tab-width: 8 * End: */ diff -u --recursive --new-file v1.3.10/linux/drivers/scsi/eata_pio.c linux/drivers/scsi/eata_pio.c --- v1.3.10/linux/drivers/scsi/eata_pio.c Fri Jun 30 16:22:29 1995 +++ linux/drivers/scsi/eata_pio.c Sun Jul 16 21:45:00 1995 @@ -32,7 +32,7 @@ * 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 */ @@ -504,7 +504,7 @@ HD(cmd)->state = RESET; 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 && DBG_DELAY, DEL2(500)); @@ -650,7 +650,7 @@ printk("IRQ:%d IRQT:%d FORCADR:%d MCH:%d RIDQ:%d\n", gc->IRQ, gc->IRQ_TR, gc->FORCADR, gc->MAX_CHAN, gc->ID_qest); - DBG(DPT_DEBUG, DELAY(1400)); + DBG(DPT_DEBUG, DELAY(14)); } static uint print_selftest(uint base) @@ -1014,7 +1014,7 @@ HBA_ptr = SD(HBA_ptr)->next; } } - DBG(DPT_DEBUG,DELAY(1200)); + DBG(DPT_DEBUG,DELAY(12)); return (registered_HBAs); } diff -u --recursive --new-file v1.3.10/linux/drivers/scsi/scsi.h linux/drivers/scsi/scsi.h --- v1.3.10/linux/drivers/scsi/scsi.h Tue Jul 11 10:02:50 1995 +++ linux/drivers/scsi/scsi.h Sun Jul 16 21:45:00 1995 @@ -80,6 +80,7 @@ #define LOG_SENSE 0x4d #define MODE_SELECT_10 0x55 #define MODE_SENSE_10 0x5a +#define READ_12 0xa8 #define WRITE_12 0xaa #define WRITE_VERIFY_12 0xae #define SEARCH_HIGH_12 0xb0 diff -u --recursive --new-file v1.3.10/linux/drivers/sound/ics2101.c linux/drivers/sound/ics2101.c --- v1.3.10/linux/drivers/sound/ics2101.c Tue Jul 11 10:02:53 1995 +++ linux/drivers/sound/ics2101.c Sun Jul 16 21:12:04 1995 @@ -30,7 +30,7 @@ #include "sound_config.h" #if defined(CONFIGURE_SOUNDCARD) && !defined(EXCLUDE_GUS) -#include "ultrasound.h" +#include #include "gus_hw.h" #define MIX_DEVS (SOUND_MASK_MIC|SOUND_MASK_LINE| \ diff -u --recursive --new-file v1.3.10/linux/fs/nfs/inode.c linux/fs/nfs/inode.c --- v1.3.10/linux/fs/nfs/inode.c Mon Jun 12 16:49:41 1995 +++ linux/fs/nfs/inode.c Tue Jul 18 14:53:16 1995 @@ -7,6 +7,10 @@ * * Modularised by Alan Cox , while hacking some * 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 @@ -76,6 +80,7 @@ struct nfs_server *server; unsigned int fd; struct file *filp; + dev_t dev = sb->s_dev; MOD_INC_USE_COUNT; @@ -104,6 +109,7 @@ } filp->f_count++; lock_super(sb); + sb->s_blocksize = 1024; /* XXX */ sb->s_blocksize_bits = 10; sb->s_magic = NFS_SUPER_MAGIC; @@ -131,6 +137,31 @@ server->acdirmin = data->acdirmin*HZ; server->acdirmax = data->acdirmax*HZ; 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; unlock_super(sb); if (!(sb->s_mounted = nfs_fhget(sb, &data->root, NULL))) { diff -u --recursive --new-file v1.3.10/linux/fs/nfs/sock.c linux/fs/nfs/sock.c --- v1.3.10/linux/fs/nfs/sock.c Tue Feb 7 11:43:23 1995 +++ linux/fs/nfs/sock.c Tue Jul 18 14:53:16 1995 @@ -102,7 +102,10 @@ fs = get_fs(); set_fs(get_ds()); 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) { printk("nfs_rpc_call: send error = %d\n", result); break; diff -u --recursive --new-file v1.3.10/linux/include/asm-alpha/system.h linux/include/asm-alpha/system.h --- v1.3.10/linux/include/asm-alpha/system.h Tue Jun 27 14:11:44 1995 +++ linux/include/asm-alpha/system.h Tue Jul 18 14:45:58 1995 @@ -85,7 +85,7 @@ #define save_flags(flags) do { flags = getipl(); } while (0) #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; @@ -100,7 +100,7 @@ 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; @@ -115,9 +115,19 @@ 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__ */ diff -u --recursive --new-file v1.3.10/linux/include/asm-alpha/unistd.h linux/include/asm-alpha/unistd.h --- v1.3.10/linux/include/asm-alpha/unistd.h Fri Jun 16 22:02:55 1995 +++ linux/include/asm-alpha/unistd.h Sun Jul 16 22:57:36 1995 @@ -8,6 +8,123 @@ * 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__ /* XXX - _foo needs to be __foo, while __NR_bar could be _NR_bar. */ diff -u --recursive --new-file v1.3.10/linux/include/asm-i386/system.h linux/include/asm-i386/system.h --- v1.3.10/linux/include/asm-i386/system.h Thu Jun 29 19:02:55 1995 +++ linux/include/asm-i386/system.h Tue Jul 18 14:45:58 1995 @@ -138,32 +138,32 @@ :"ax") -extern inline unsigned long xchg_u8(char * m, unsigned long val) -{ - __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; -} +#define xchg(ptr,x) ((__typeof__(*(ptr)))__xchg((unsigned long)(x),(ptr),sizeof(*(ptr)))) +#define tas(ptr) (xchg((ptr),1)) -extern inline unsigned long xchg_u32(int * m, unsigned long val) -{ - __asm__("xchgl %0,%1":"=r" (val),"=m" (*m):"0" (val):"memory"); - return val; -} - -extern inline int tas(char * m) -{ - return xchg_u8(m,1); -} +struct __xchg_dummy { unsigned long a[100]; }; +#define __xg(x) ((volatile struct __xchg_dummy *)(x)) -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") diff -u --recursive --new-file v1.3.10/linux/include/asm-i386/unistd.h linux/include/asm-i386/unistd.h --- v1.3.10/linux/include/asm-i386/unistd.h Fri Feb 24 16:46:58 1995 +++ linux/include/asm-i386/unistd.h Sun Jul 16 22:27:12 1995 @@ -1,6 +1,155 @@ #ifndef _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. */ #define _syscall0(type,name) \ type name(void) \ diff -u --recursive --new-file v1.3.10/linux/include/linux/mm.h linux/include/linux/mm.h --- v1.3.10/linux/include/linux/mm.h Thu Jun 29 19:02:55 1995 +++ linux/include/linux/mm.h Mon Jul 17 12:43:26 1995 @@ -275,7 +275,7 @@ #ifdef SWAP_CACHE_INFO swap_cache_find_total++; #endif - entry = (unsigned long) xchg_ptr(swap_cache + MAP_NR(addr), NULL); + entry = xchg(swap_cache + MAP_NR(addr), 0); #ifdef SWAP_CACHE_INFO if (entry) swap_cache_find_success++; @@ -290,7 +290,7 @@ #ifdef SWAP_CACHE_INFO swap_cache_del_total++; #endif - entry= (unsigned long) xchg_ptr(swap_cache + MAP_NR(addr), NULL); + entry= xchg(swap_cache + MAP_NR(addr), 0); if (entry) { #ifdef SWAP_CACHE_INFO swap_cache_del_success++; diff -u --recursive --new-file v1.3.10/linux/include/linux/netdevice.h linux/include/linux/netdevice.h --- v1.3.10/linux/include/linux/netdevice.h Thu Jul 13 16:20:21 1995 +++ linux/include/linux/netdevice.h Tue Jul 18 14:53:10 1995 @@ -31,7 +31,11 @@ /* for future expansion when we will have different priorities. */ #define DEV_NUMBUFFS 3 #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_LOOPBACK 2 /* address is for LOOPBACK */ @@ -73,12 +77,12 @@ unsigned long mem_end; /* sahared mem end */ unsigned long mem_start; /* shared mem start */ unsigned long base_addr; /* device I/O address */ - unsigned long tbusy; /* transmitter busy must be long for bitops */ unsigned char irq; /* device IRQ number */ /* Low-level status flags. */ volatile unsigned char start, /* start an operation */ interrupt; /* interrupt arrived */ + unsigned long tbusy; /* transmitter busy must be long for bitops */ struct device *next; diff -u --recursive --new-file v1.3.10/linux/include/linux/nfs_fs_sb.h linux/include/linux/nfs_fs_sb.h --- v1.3.10/linux/include/linux/nfs_fs_sb.h Wed Dec 1 14:44:15 1993 +++ linux/include/linux/nfs_fs_sb.h Tue Jul 18 14:53:16 1995 @@ -5,6 +5,7 @@ struct nfs_server { struct file *file; + struct sockaddr toaddr ; /* Added for change to NFS code to use sendto() 1995-06-02 JSP */ int lock; struct wait_queue *wait; int flags; diff -u --recursive --new-file v1.3.10/linux/include/linux/scc.h linux/include/linux/scc.h --- v1.3.10/linux/include/linux/scc.h Tue Jun 6 11:22:12 1995 +++ linux/include/linux/scc.h Sun Jul 16 18:54:02 1995 @@ -1,4 +1,3 @@ -/* $Id: scc.h,v 1.9 1995/01/12 18:24:40 JReuter Exp JReuter $ */ #ifndef _SCC_H #define _SCC_H @@ -15,9 +14,9 @@ /* Constants */ #define MAXSCC 4 /* number of max. supported chips */ -#define MAX_IBUFS 200 /* change this if you run out of memory */ -#define BUFSIZE 128 /* must not exceed 4096 */ -#define TPS 25 /* scc_timer(): Ticks Per Second */ +#define MAX_IBUFS 300 /* change this if you run out of memory */ +#define BUFSIZE 64 /* must not exceed 4096 */ +#define TPS 25 /* scc_timer(): 25 Ticks Per Second */ #define SCC_TIMER 3 @@ -134,15 +133,13 @@ /* Basic message buffer structure */ -/* looks familiar? Hmm, yes... */ - struct mbuf { struct mbuf *next; /* Links mbufs belonging to single packets */ struct mbuf *anext; /* Links packets on queues */ - + 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 refcnt; /* Reference count */ struct mbuf *dup; /* Pointer to duplicated mbuf */ @@ -240,16 +237,19 @@ struct scc_stat stat; /* statistical information */ struct scc_modem modem; /* modem information */ - struct mbuf *rbp; /* rx: Head of mbuf chain being filled */ - struct mbuf *rbp1; /* rx: Pointer to mbuf currently being written */ - struct mbuf *rcvq; /* Pointer to mbuf packets currently received */ - + char rxbuf[2048]; /* Rx frame buffer max framesize * 2 */ + int rxbufcnt; /* Rx frame counter */ + struct mbuf *sndq; /* tx: Packets awaiting transmission */ struct mbuf *tbp; /* tx: Transmit mbuf being sent */ struct mbuf *sndq1; /* 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 */ diff -u --recursive --new-file v1.3.10/linux/include/linux/sched.h linux/include/linux/sched.h --- v1.3.10/linux/include/linux/sched.h Thu Jul 13 16:20:21 1995 +++ linux/include/linux/sched.h Mon Jul 17 12:05:15 1995 @@ -61,6 +61,7 @@ #include #include #include +#include #include @@ -174,6 +175,7 @@ unsigned long timeout; unsigned long it_real_value, it_prof_value, it_virt_value; unsigned long it_real_incr, it_prof_incr, it_virt_incr; + struct timer_list real_timer; long utime, stime, cutime, cstime, start_time; struct rlimit rlim[RLIM_NLIMITS]; unsigned short used_math; @@ -237,7 +239,9 @@ /* suppl grps*/ {NOGROUP,}, \ /* proc links*/ &init_task,&init_task,NULL,NULL,NULL,NULL, \ /* 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}, \ {LONG_MAX, LONG_MAX}, {_STK_LIM, _STK_LIM}, \ { 0, LONG_MAX}, {LONG_MAX, LONG_MAX}, \ @@ -271,6 +275,7 @@ extern void interruptible_sleep_on(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_process(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); diff -u --recursive --new-file v1.3.10/linux/include/linux/sjcd.h linux/include/linux/sjcd.h --- v1.3.10/linux/include/linux/sjcd.h Fri Jul 7 08:54:54 1995 +++ linux/include/linux/sjcd.h Sun Jul 16 21:47:22 1995 @@ -1,4 +1,5 @@ -/* +/* -- sjcd.h + * * Definitions for a Sanyo CD-ROM interface * * Copyright (C) 1995 Vadim V. Model @@ -21,6 +22,11 @@ * Change this to set the irq. */ #define SJCD_INTR_NR 10 + +/* + * Change this to set the dma channel. + */ +#define SJCD_DMA 0 /* * port access macros diff -u --recursive --new-file v1.3.10/linux/include/linux/timer.h linux/include/linux/timer.h --- v1.3.10/linux/include/linux/timer.h Fri Jul 7 08:54:54 1995 +++ linux/include/linux/timer.h Mon Jul 17 10:52:42 1995 @@ -87,6 +87,8 @@ extern void add_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) { timer->next = NULL; diff -u --recursive --new-file v1.3.10/linux/include/linux/tqueue.h linux/include/linux/tqueue.h --- v1.3.10/linux/include/linux/tqueue.h Wed Apr 12 21:24:17 1995 +++ linux/include/linux/tqueue.h Mon Jul 17 12:44:39 1995 @@ -143,7 +143,7 @@ void (*f) (void *); while(1) { - p = xchg_ptr(list,&tq_last); + p = xchg(list,&tq_last); if(p == &tq_last) break; diff -u --recursive --new-file v1.3.10/linux/include/linux/trdevice.h linux/include/linux/trdevice.h --- v1.3.10/linux/include/linux/trdevice.h Fri Jun 30 16:22:30 1995 +++ linux/include/linux/trdevice.h Fri Jul 14 06:20:04 1995 @@ -28,9 +28,9 @@ #include #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, - void *saddr, unsigned len); + void *saddr, unsigned len, struct sk_buff *skb); extern int tr_rebuild_header(void *buff, struct device *dev, unsigned long raddr, struct sk_buff *skb); extern unsigned short tr_type_trans(struct sk_buff *skb, struct device *dev); diff -u --recursive --new-file v1.3.10/linux/include/linux/unistd.h linux/include/linux/unistd.h --- v1.3.10/linux/include/linux/unistd.h Sun Jun 11 19:03:07 1995 +++ linux/include/linux/unistd.h Sun Jul 16 22:27:12 1995 @@ -1,155 +1,6 @@ #ifndef _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; /* diff -u --recursive --new-file v1.3.10/linux/kernel/dma.c linux/kernel/dma.c --- v1.3.10/linux/kernel/dma.c Wed Jan 4 21:16:06 1995 +++ linux/kernel/dma.c Mon Jul 17 12:42:06 1995 @@ -74,7 +74,7 @@ if (dmanr >= MAX_DMA_CHANNELS) return -EINVAL; - if (xchg_u32(&dma_chan_busy[dmanr].lock, 1) != 0) + if (xchg(&dma_chan_busy[dmanr].lock, 1) != 0) return -EBUSY; dma_chan_busy[dmanr].device_id = device_id; @@ -91,7 +91,7 @@ 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); return; } diff -u --recursive --new-file v1.3.10/linux/kernel/exit.c linux/kernel/exit.c --- v1.3.10/linux/kernel/exit.c Fri Jun 30 16:22:30 1995 +++ linux/kernel/exit.c Mon Jul 17 12:10:39 1995 @@ -27,18 +27,18 @@ struct sigaction * sa = sig + p->sigaction - 1; /* always generate signals for traced processes ??? */ - if (p->flags & PF_PTRACED) { - p->signal |= mask; - return 1; + if (!(p->flags & PF_PTRACED)) { + /* don't bother with ignored signals (but SIGCHLD is special) */ + if (sa->sa_handler == SIG_IGN && sig != SIGCHLD) + return 0; + /* some signals are ignored by default.. (but SIGCONT already did its deed) */ + if ((sa->sa_handler == SIG_DFL) && + (sig == SIGCONT || sig == SIGCHLD || sig == SIGWINCH)) + return 0; } - /* don't bother with ignored signals (but SIGCHLD is special) */ - if (sa->sa_handler == SIG_IGN && sig != SIGCHLD) - return 0; - /* some signals are ignored by default.. (but SIGCONT already did its deed) */ - if ((sa->sa_handler == SIG_DFL) && - (sig == SIGCONT || sig == SIGCHLD || sig == SIGWINCH)) - return 0; p->signal |= mask; + if (p->state == TASK_INTERRUPTIBLE && (p->signal & ~p->blocked)) + wake_up_process(p); return 1; } @@ -58,7 +58,7 @@ return 0; if ((sig == SIGKILL) || (sig == SIGCONT)) { if (p->state == TASK_STOPPED) - p->state = TASK_RUNNING; + wake_up_process(p); p->exit_code = 0; p->signal &= ~( (1<<(SIGSTOP-1)) | (1<<(SIGTSTP-1)) | (1<<(SIGTTIN-1)) | (1<<(SIGTTOU-1)) ); @@ -382,6 +382,7 @@ } fake_volatile: current->flags |= PF_EXITING; + del_timer(¤t->real_timer); sem_exit(); exit_mmap(current); free_page_tables(current); diff -u --recursive --new-file v1.3.10/linux/kernel/fork.c linux/kernel/fork.c --- v1.3.10/linux/kernel/fork.c Mon Jun 12 15:56:40 1995 +++ linux/kernel/fork.c Mon Jul 17 12:11:07 1995 @@ -197,6 +197,8 @@ p->signal = 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; + init_timer(&p->real_timer); + p->real_timer.data = (unsigned long) p; p->leader = 0; /* process leadership doesn't inherit */ p->tty_old_pgrp = 0; p->utime = p->stime = 0; @@ -219,7 +221,7 @@ p->mm->swappable = 1; p->exit_signal = clone_flags & CSIGNAL; 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; bad_fork_cleanup: task[nr] = NULL; diff -u --recursive --new-file v1.3.10/linux/kernel/itimer.c linux/kernel/itimer.c --- v1.3.10/linux/kernel/itimer.c Mon Jan 23 23:04:10 1995 +++ linux/kernel/itimer.c Mon Jul 17 10:59:51 1995 @@ -71,6 +71,17 @@ 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) { register unsigned long i, j; @@ -82,10 +93,10 @@ return k; switch (which) { case ITIMER_REAL: + del_timer(¤t->real_timer); if (j) { - j += 1+itimer_ticks; - if (j < itimer_next) - itimer_next = j; + current->real_timer.expires = j; + add_timer(¤t->real_timer); } current->it_real_value = j; current->it_real_incr = i; diff -u --recursive --new-file v1.3.10/linux/kernel/ksyms.c linux/kernel/ksyms.c --- v1.3.10/linux/kernel/ksyms.c Tue Jul 11 10:03:00 1995 +++ linux/kernel/ksyms.c Sun Jul 16 22:25:19 1995 @@ -151,6 +151,7 @@ X(kfree_s), X(vmalloc), X(vfree), + X(mem_map), /* filesystem internal functions */ X(getname), @@ -243,6 +244,7 @@ X(tq_last), X(timer_active), X(timer_table), + X(intr_count), /* dma handling */ X(request_dma), @@ -310,6 +312,7 @@ X(slhc_remember), X(slhc_compress), X(slhc_uncompress), + X(slhc_toss), #endif #endif /* Device callback registration */ @@ -384,8 +387,6 @@ X(generic_proc_info), X(scsi_devices), X(free_pages), - X(intr_count), - X(mem_map), X(print_msg), X(print_status), X(gendisk_head), /* Needed for sd.c */ @@ -395,8 +396,6 @@ * With no scsi configured, we still need to export a few * symbols so that scsi can be loaded later via insmod. */ - X(intr_count), - X(mem_map), X(gendisk_head), X(resetup_one_dev), diff -u --recursive --new-file v1.3.10/linux/kernel/sched.c linux/kernel/sched.c --- v1.3.10/linux/kernel/sched.c Fri Jun 16 22:02:56 1995 +++ linux/kernel/sched.c Mon Jul 17 17:38:34 1995 @@ -92,8 +92,27 @@ 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 @@ -103,16 +122,12 @@ * 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' * 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) { int c; struct task_struct * p; struct task_struct * next; - unsigned long ticks; /* check alarm, wake up any interruptible tasks that have got a signal */ @@ -121,69 +136,35 @@ intr_count = 0; } run_task_queue(&tq_scheduler); - cli(); - ticks = itimer_ticks; - itimer_ticks = 0; - itimer_next = ~0; - sti(); + + if (current->state == TASK_INTERRUPTIBLE) { + if (current->signal & ~current->blocked) + current->state = TASK_RUNNING; + } need_resched = 0; nr_running = 0; - p = &init_task; - for (;;) { - if ((p = p->next_task) == &init_task) - goto confuse_gcc1; - if (ticks && p->it_real_value) { - if (p->it_real_value <= ticks) { - send_sig(SIGALRM, p, 1); - if (!p->it_real_incr) { - 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; - if (p->signal & ~p->blocked) { - p->state = TASK_RUNNING; - continue; - } - if (p->timeout && p->timeout <= jiffies) { - p->timeout = 0; - p->state = 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++; - if (p->counter > c) - c = p->counter, next = p; + next = &init_task; + for_each_task(p) { + switch (p->state) { + case TASK_INTERRUPTIBLE: + if (!p->timeout) + continue; + if (p->timeout > jiffies) + continue; + p->timeout = 0; + p->state = TASK_RUNNING; + /* fall through */ + case TASK_RUNNING: + nr_running++; + if (p->counter > c) + c = p->counter, next = p; } } -confuse_gcc2: + + /* if all runnable processes have "counter == 0", re-calculate counters */ if (!c) { for_each_task(p) p->counter = (p->counter >> 1) + p->priority; @@ -219,11 +200,8 @@ do { if ((p = tmp->task) != NULL) { if ((p->state == TASK_UNINTERRUPTIBLE) || - (p->state == TASK_INTERRUPTIBLE)) { - p->state = TASK_RUNNING; - if (p->counter > current->counter + 3) - need_resched = 1; - } + (p->state == TASK_INTERRUPTIBLE)) + wake_up_process(p); } if (!tmp->next) { printk("wait_queue is bad (eip = %p)\n", @@ -246,11 +224,8 @@ return; do { if ((p = tmp->task) != NULL) { - if (p->state == TASK_INTERRUPTIBLE) { - p->state = TASK_RUNNING; - if (p->counter > current->counter + 3) - need_resched = 1; - } + if (p->state == TASK_INTERRUPTIBLE) + wake_up_process(p); } if (!tmp->next) { printk("wait_queue is bad (eip = %p)\n", @@ -665,9 +640,6 @@ mark_bh(TIMER_BH); } cli(); - itimer_ticks++; - if (itimer_ticks > itimer_next) - need_resched = 1; if (timer_head.next->expires < jiffies) mark_bh(TIMER_BH); if (tq_timer != &tq_last) diff -u --recursive --new-file v1.3.10/linux/mm/swap.c linux/mm/swap.c --- v1.3.10/linux/mm/swap.c Fri Jun 30 16:22:30 1995 +++ linux/mm/swap.c Mon Jul 17 12:42:48 1995 @@ -82,7 +82,7 @@ swap_cache_add_total++; #endif 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) { printk("swap_cache: replacing non-NULL entry\n"); } diff -u --recursive --new-file v1.3.10/linux/net/appletalk/aarp.c linux/net/appletalk/aarp.c --- v1.3.10/linux/net/appletalk/aarp.c Fri Jul 7 08:54:56 1995 +++ linux/net/appletalk/aarp.c Tue Jul 18 14:53:23 1995 @@ -178,7 +178,6 @@ eah = (struct elapaarp *)skb_put(skb,sizeof(struct elapaarp)); skb->arp = 1; skb->free = 1; - skb_put(skb,len); skb->dev = dev; /* @@ -243,7 +242,6 @@ skb->arp = 1; skb->free = 1; - skb_put(skb,len); skb->dev = dev; /* diff -u --recursive --new-file v1.3.10/linux/net/ethernet/eth.c linux/net/ethernet/eth.c --- v1.3.10/linux/net/ethernet/eth.c Tue Jul 11 10:03:00 1995 +++ linux/net/ethernet/eth.c Tue Jul 18 15:24:15 1995 @@ -26,6 +26,7 @@ * Alan Cox : ARP only when compiled with CONFIG_INET * Greg Page : 802.2 and SNAP stuff. * 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 * modify it under the terms of the GNU General Public License @@ -231,11 +232,13 @@ /* * 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) { struct ethhdr *eth; + struct iphdr *iph; IS_SKB(dest); eth=(struct ethhdr *)dest->data; @@ -246,6 +249,14 @@ memcpy(dest->data+34,src+34,length); 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->ip_summed=1; } diff -u --recursive --new-file v1.3.10/linux/net/ipv4/ip_fw.c linux/net/ipv4/ip_fw.c --- v1.3.10/linux/net/ipv4/ip_fw.c Fri Jun 30 16:22:32 1995 +++ linux/net/ipv4/ip_fw.c Tue Jul 18 14:53:16 1995 @@ -733,7 +733,7 @@ if (portptr[1]==htons(21)) { skb = revamp(*skb_ptr, dev, ms); - skb = *skb_ptr; + *skb_ptr = skb; iph = skb->h.iph; portptr = (unsigned short *)&(((char *)iph)[iph->ihl*4]); } diff -u --recursive --new-file v1.3.10/linux/net/ipv4/tcp.c linux/net/ipv4/tcp.c --- v1.3.10/linux/net/ipv4/tcp.c Fri Jul 7 13:42:58 1995 +++ linux/net/ipv4/tcp.c Tue Jul 18 14:54:29 1995 @@ -145,6 +145,11 @@ * sk->retransmits misupdating fixed. * Fixed tcp_write_timeout: stuck close, * 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: @@ -439,6 +444,7 @@ struct proto *prot; struct device *dev; int ct=0; + struct rtable *rt; prot = sk->prot; skb = sk->send_head; @@ -454,6 +460,12 @@ 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 * need to use the current ack and window fields. Urg and * urg_ptr could possibly stand to be updated as well, but we @@ -462,60 +474,89 @@ * 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)); - 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 * 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++); ip_send_check(iph); - - /* - * This is not the right way to handle this. We have to - * issue an up to date window and ack report with this - * retransmit to keep the odd buggy tcp that relies on - * the fact BSD does this happy. - * We don't however need to recalculate the entire - * checksum, so someone wanting a small problem to play - * with might like to implement RFC1141/RFC1624 and speed - * this up by avoiding a full checksum. - */ - - th->ack_seq = ntohl(sk->acked_seq); - th->window = ntohs(tcp_select_window(sk)); - tcp_send_check(th, sk->saddr, sk->daddr, size, sk); /* - * If the interface is (still) up and running, kick it. + * Put a MAC header back on (may cause ARPing) */ - - if (dev->flags & IFF_UP) + + 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; + } + /* - * If the packet is still being sent by the device/protocol - * below then don't retransmit. This is both needed, and good - - * especially with connected mode AX.25 where it stops resends - * occurring of an as yet unsent anyway frame! - * We still add up the counts as the round trip time wants - * adjusting. + * This is not the right way to handle this. We have to + * issue an up to date window and ack report with this + * retransmit to keep the odd buggy tcp that relies on + * the fact BSD does this happy. + * We don't however need to recalculate the entire + * checksum, so someone wanting a small problem to play + * with might like to implement RFC1141/RFC1624 and speed + * this up by avoiding a full checksum. */ - if (sk && !skb_device_locked(skb)) + + th->ack_seq = ntohl(sk->acked_seq); + th->window = ntohs(tcp_select_window(sk)); + tcp_send_check(th, sk->saddr, sk->daddr, size, sk); + + /* + * If the interface is (still) up and running, kick it. + */ + + if (dev->flags & IFF_UP) { - /* Remove it from any existing driver queue first! */ - skb_unlink(skb); - /* Now queue it */ - ip_statistics.IpOutRequests++; - dev_queue_xmit(skb, dev, sk->priority); + /* + * If the packet is still being sent by the device/protocol + * below then don't retransmit. This is both needed, and good - + * especially with connected mode AX.25 where it stops resends + * occurring of an as yet unsent anyway frame! + * We still add up the counts as the round trip time wants + * adjusting. + */ + if (sk && !skb_device_locked(skb)) + { + /* Remove it from any existing driver queue first! */ + skb_unlink(skb); + /* Now queue it */ + ip_statistics.IpOutRequests++; + dev_queue_xmit(skb, dev, sk->priority); + } } } - + /* * Count retransmissions */ @@ -1772,6 +1813,13 @@ 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 * being called. Being called once in a while is ok, so only check * if this is the second time in a row. @@ -3034,8 +3082,7 @@ * Ack and window will in general have changed since this packet was put * on the write queue. */ - iph = (struct iphdr *)(skb->data + - skb->dev->hard_header_len); + iph = skb->ip_hdr; th = (struct tcphdr *)(((char *)iph) +(iph->ihl << 2)); size = skb->len - (((unsigned char *) th) - skb->data); diff -u --recursive --new-file v1.3.10/linux/net/ipv4/udp.c linux/net/ipv4/udp.c --- v1.3.10/linux/net/ipv4/udp.c Thu Jul 13 16:20:22 1995 +++ linux/net/ipv4/udp.c Tue Jul 18 15:29:26 1995 @@ -45,8 +45,7 @@ * Arnt Gulbrandsen : New udp_send and stuff * Alan Cox : Cache last socket * Alan Cox : Route cache - * Alan Cox : Checksum precompute is bogus is some lame - * software is padding its udp frames in IP! + * Jon Peatfield : Minor efficientcy fix to sendto(). * * * This program is free software; you can redistribute it and/or @@ -301,10 +300,9 @@ { if (addr_len < sizeof(sin)) return(-EINVAL); - memcpy(&sin,usin,sizeof(sin)); - if (sin.sin_family && sin.sin_family != AF_INET) + if (usin->sin_family && usin->sin_family != AF_INET) return(-EINVAL); - if (sin.sin_port == 0) + if (usin->sin_port == 0) return(-EINVAL); } else @@ -314,6 +312,7 @@ sin.sin_family = AF_INET; sin.sin_port = sk->dummy_th.dest; sin.sin_addr.s_addr = sk->daddr; + usin = &sin; } /* @@ -321,16 +320,16 @@ * broadcasting of data. */ - if(sin.sin_addr.s_addr==INADDR_ANY) - sin.sin_addr.s_addr=ip_my_addr(); + if(usin->sin_addr.s_addr==INADDR_ANY) + 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 */ sk->inuse = 1; /* 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. */ release_sock(sk); @@ -538,9 +537,6 @@ ulen = ntohs(uh->len); - if(ulen!=len) - skb->ip_summed=0; /* Bogoid padded frame */ - if (ulen > len || len < sizeof(*uh) || ulen < sizeof(*uh)) { NETDEBUG(printk("UDP: short packet: %d/%d\n", ulen, len));