diff -u --recursive --new-file v2.1.75/linux/CREDITS linux/CREDITS --- v2.1.75/linux/CREDITS Sun Dec 21 16:17:43 1997 +++ linux/CREDITS Sun Dec 21 23:02:21 1997 @@ -537,15 +537,6 @@ S: N.S.W., 2121 S: Australia -N: Richard E. Gooch -E: rgooch@atnf.csiro.au -D: parent process death signal to children -D: prctl() syscall -S: CSIRO Australia Telescope National Facility -S: P.O. Box 76, Epping -S: N.S.W., 2121 -S: Australia - N: Dmitry S. Gorodchanin E: begemot@bgm.rosprint.net D: RISCom/8 driver, misc kernel fixes. diff -u --recursive --new-file v2.1.75/linux/Documentation/networking/de4x5.txt linux/Documentation/networking/de4x5.txt --- v2.1.75/linux/Documentation/networking/de4x5.txt Sat Nov 29 11:25:08 1997 +++ linux/Documentation/networking/de4x5.txt Sun Dec 21 22:37:32 1997 @@ -11,9 +11,9 @@ Digital Semiconductor SROM Specification. The driver currently recognises the following chips: - DC21040 (no SROM) - DC21041[A] - DC21140[A] + DC21040 (no SROM) + DC21041[A] + DC21140[A] DC21142 DC21143 @@ -57,7 +57,7 @@ 1) copy de4x5.c from the /linux/drivers/net directory to your favourite temporary directory. 2) for fixed autoprobes (not recommended), edit the source code near - line 5537 to reflect the I/O address you're using, or assign these when + line 5594 to reflect the I/O address you're using, or assign these when loading by: insmod de4x5 io=0xghh where g = bus number @@ -92,6 +92,16 @@ can compile with a DEC_ONLY define, or if loading as a module, use the 'dec_only=1' parameter. + I've changed the timing routines to use the kernel timer and scheduling + functions so that the hangs and other assorted problems that occurred + while autosensing the media should be gone. A bonus for the DC21040 + auto media sense algorithm is that it can now use one that is more in + line with the rest (the DC21040 chip doesn't have a hardware timer). + The downside is the 1 'jiffies' (10ms) resolution. + + IEEE 802.3u MII interface code has been added in anticipation that some + products may use it in the future. + The SMC9332 card has a non-compliant SROM which needs fixing - I have patched this driver to detect it because the SROM format used complies to a previous DEC-STD format. @@ -133,11 +143,36 @@ is the preferred way to use this driver, since it doesn't have this limitation. - Where SROM media detection is used and full duplex is specified in the - SROM, the feature is ignored unless de4x5_full_duplex is set at compile - time OR during a module load (insmod de4x5 de4x5_full_duplex=1). This - is because there is no way to automatically detect full duplex links - except through autonegotiation. When I include the autonegotiation - feature in the SROM autoconf code, this detection will occur - automatically. - + Where SROM media detection is used and full duplex is specified in the + SROM, the feature is ignored unless lp->params.fdx is set at compile + time OR during a module load (insmod de4x5 args='eth??:fdx' [see + below]). This is because there is no way to automatically detect full + duplex links except through autonegotiation. When I include the + autonegotiation feature in the SROM autoconf code, this detection will + occur automatically for that case. + + Command line arguements are now allowed, similar to passing arguements + through LILO. This will allow a per adapter board set up of full duplex + and media. The only lexical constraints are: the board name (dev->name) + appears in the list before its parameters. The list of parameters ends + either at the end of the parameter list or with another board name. The + following parameters are allowed: + + fdx for full duplex + autosense to set the media/speed; with the following + sub-parameters: + TP, TP_NW, BNC, AUI, BNC_AUI, 100Mb, 10Mb, AUTO + + Case sensitivity is important for the sub-parameters. They *must* be + upper case. Examples: + + insmod de4x5 args='eth1:fdx autosense=BNC eth0:autosense=100Mb'. + + For a compiled in driver, in linux/drivers/net/CONFIG, place e.g. + DE4X5_OPTS = -DDE4X5_PARM='"eth0:fdx autosense=AUI eth2:autosense=TP"' + + Yes, I know full duplex isn't permissible on BNC or AUI; they're just + examples. By default, full duplex is turned off and AUTO is the default + autosense setting. In reality, I expect only the full duplex option to + be used. Note the use of single quotes in the two examples above and the + lack of commas to separate items. diff -u --recursive --new-file v2.1.75/linux/Makefile linux/Makefile --- v2.1.75/linux/Makefile Sun Dec 21 22:36:12 1997 +++ linux/Makefile Tue Dec 23 13:52:02 1997 @@ -1,6 +1,6 @@ VERSION = 2 PATCHLEVEL = 1 -SUBLEVEL = 75 +SUBLEVEL = 76 ARCH := $(shell uname -m | sed -e s/i.86/i386/ -e s/sun4u/sparc64/) @@ -206,7 +206,6 @@ fi oldconfig: symlinks - $(MAKE) -C drivers/sound mkscript $(CONFIG_SHELL) scripts/Configure -d arch/$(ARCH)/config.in xconfig: symlinks @@ -339,23 +338,24 @@ rm -f core `find . -name '*.[oas]' ! -regex '.*lxdialog/.*' -print` rm -f core `find . -type f -name 'core' -print` rm -f vmlinux System.map - rm -f .tmp* drivers/sound/configure + rm -f .tmp* rm -f drivers/char/consolemap_deftbl.c drivers/char/conmakehash + rm -f drivers/sound/bin2hex drivers/sound/hex2hex rm -f `find modules/ -type f -print` rm -f submenu* mrproper: clean rm -f include/linux/autoconf.h include/linux/version.h - rm -f drivers/sound/local.h drivers/sound/.defines rm -f drivers/net/soundmodem/sm_tbl_{afsk1200,afsk2666,fsk9600}.h rm -f drivers/net/soundmodem/sm_tbl_{hapn4800,psk4800}.h rm -f drivers/net/soundmodem/sm_tbl_{afsk2400_7,afsk2400_8}.h rm -f drivers/net/soundmodem/gentbl rm -f drivers/char/hfmodem/gentbl drivers/char/hfmodem/tables.h + rm -f drivers/sound/*_boot.h drivers/sound/.*.boot rm -f .version .config* config.in config.old rm -f scripts/tkparse scripts/kconfig.tk scripts/kconfig.tmp rm -f scripts/lxdialog/*.o scripts/lxdialog/lxdialog - rm -f .menuconfig .menuconfig.log + rm -f .menuconfig.log rm -f include/asm rm -f .depend `find . -name .depend -print` rm -f .hdepend scripts/mkdep @@ -367,8 +367,6 @@ rm -f core `find . \( -name '*.orig' -o -name '*.rej' -o -name '*~' \ -o -name '*.bak' -o -name '#*#' -o -name '.*.orig' \ -o -name '.*.rej' -o -name '.SUMS' -o -size 0 \) -print` TAGS -# rm -f drivers/sound/Config.in -# cp drivers/sound/Config.std drivers/sound/Config.in backup: mrproper cd .. && tar cf - linux/ | gzip -9 > backup.gz diff -u --recursive --new-file v2.1.75/linux/arch/alpha/kernel/alpha_ksyms.c linux/arch/alpha/kernel/alpha_ksyms.c --- v2.1.75/linux/arch/alpha/kernel/alpha_ksyms.c Mon Dec 1 12:04:11 1997 +++ linux/arch/alpha/kernel/alpha_ksyms.c Mon Dec 22 09:58:21 1997 @@ -22,9 +22,11 @@ #include #include +#define __KERNEL_SYSCALLS__ +#include + extern void bcopy (const char *src, char *dst, int len); extern struct hwrpb_struct *hwrpb; -extern long __kernel_thread(unsigned long, int (*)(void *), void *); extern void dump_thread(struct pt_regs *, struct user *); extern int dump_fpu(struct pt_regs *, elf_fpregset_t *); @@ -71,6 +73,7 @@ EXPORT_SYMBOL(strstr); EXPORT_SYMBOL(strtok); EXPORT_SYMBOL(strchr); +EXPORT_SYMBOL(strrchr); EXPORT_SYMBOL(memcmp); EXPORT_SYMBOL(memmove); EXPORT_SYMBOL(__memcpy); @@ -81,8 +84,20 @@ EXPORT_SYMBOL(dump_fpu); EXPORT_SYMBOL(hwrpb); EXPORT_SYMBOL(wrusp); -EXPORT_SYMBOL(__kernel_thread); EXPORT_SYMBOL(start_thread); + +/* In-kernel system calls. */ +EXPORT_SYMBOL(__kernel_thread); +EXPORT_SYMBOL(sys_open); +EXPORT_SYMBOL(sys_dup); +EXPORT_SYMBOL(sys_exit); +EXPORT_SYMBOL(sys_write); +EXPORT_SYMBOL(sys_read); +EXPORT_SYMBOL(sys_lseek); +EXPORT_SYMBOL(__kernel_execve); +EXPORT_SYMBOL(sys_setsid); +EXPORT_SYMBOL(sys_sync); +EXPORT_SYMBOL(sys_wait4); /* Networking helper routines. */ EXPORT_SYMBOL(csum_tcpudp_magic); diff -u --recursive --new-file v2.1.75/linux/arch/alpha/kernel/entry.S linux/arch/alpha/kernel/entry.S --- v2.1.75/linux/arch/alpha/kernel/entry.S Wed Dec 10 11:12:42 1997 +++ linux/arch/alpha/kernel/entry.S Mon Dec 22 09:58:21 1997 @@ -252,6 +252,28 @@ call_pal PAL_halt .end __kernel_thread +/* + * __kernel_execve(path, argv, envp, regs) + */ +.align 3 +.globl __kernel_execve +.ent __kernel_execve +__kernel_execve: + ldgp $29,0($27) /* we can be called from modules. */ + subq $30,16,$30 + .frame $30,16,$26,0 + stq $26,0($30) + stq $19,8($30) + .prologue 1 + jsr $26,do_execve + bne $0,1f /* error! */ + ldq $30,8($30) + br $31,ret_from_sys_call +1: ldq $26,0($30) + addq $30,16,$30 + ret +.end __kernel_execve + .align 3 .ent do_switch_stack do_switch_stack: diff -u --recursive --new-file v2.1.75/linux/arch/i386/kernel/head.S linux/arch/i386/kernel/head.S --- v2.1.75/linux/arch/i386/kernel/head.S Sun Dec 21 22:36:12 1997 +++ linux/arch/i386/kernel/head.S Tue Dec 23 10:45:12 1997 @@ -172,7 +172,7 @@ * if CPUID works. */ movl $0x69727943,X86_VENDOR_ID # low 4 chars - movl $0x00000078,X86_VENDOR_ID # next 4 chars + movl $0x00000078,X86_VENDOR_ID+4 # next 4 chars /* * N.B. The pattern of accesses to 0x22 and 0x23 is *important* diff -u --recursive --new-file v2.1.75/linux/arch/i386/kernel/setup.c linux/arch/i386/kernel/setup.c --- v2.1.75/linux/arch/i386/kernel/setup.c Sun Dec 21 22:36:12 1997 +++ linux/arch/i386/kernel/setup.c Tue Dec 23 10:47:27 1997 @@ -356,8 +356,8 @@ { X86_VENDOR_AMD, 5, { "K5/SSA5 (PR-75, PR-90, PR-100)", "K5 (PR-120, PR-133)", "K5 (PR-166)", "K5 (PR-200)", NULL, NULL, - "K6 (166 - 266)", "K6 (166 - 300)", "K6 (model 8)", - "K6 (model 9)", NULL, NULL, NULL, NULL, NULL, NULL }}, + "K6 (166 - 266)", "K6 (166 - 300)", "K6-3D (200 - 450)", + "K6-3D-Plus (200 - 450)", NULL, NULL, NULL, NULL, NULL, NULL }}, { X86_VENDOR_UMC, 4, { NULL, "U5D", "U5S", NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }}, diff -u --recursive --new-file v2.1.75/linux/drivers/block/raid5.c linux/drivers/block/raid5.c --- v2.1.75/linux/drivers/block/raid5.c Wed Nov 12 13:34:25 1997 +++ linux/drivers/block/raid5.c Mon Dec 22 14:15:14 1997 @@ -1019,7 +1019,7 @@ if (sh->bh_new[i]) continue; block = (int) compute_blocknr(sh, i); - bh = efind_buffer(MKDEV(MD_MAJOR, minor), block, sh->size); + bh = find_buffer(MKDEV(MD_MAJOR, minor), block, sh->size); if (bh && bh->b_count == 0 && buffer_dirty(bh) && !buffer_locked(bh)) { PRINTK(("Whee.. sector %lu, index %d (%d) found in the buffer cache!\n", sh->sector, i, block)); add_stripe_bh(sh, bh, i, WRITE); diff -u --recursive --new-file v2.1.75/linux/drivers/char/bttv.c linux/drivers/char/bttv.c --- v2.1.75/linux/drivers/char/bttv.c Sun Dec 21 22:36:13 1997 +++ linux/drivers/char/bttv.c Mon Dec 22 08:42:36 1997 @@ -1265,11 +1265,11 @@ case VIDIOCGAUDIO: { - struct video_audio vp; - vp=btv->audio_dev; - vp.flags&=~(VIDEO_AUDIO_MUTE|VIDEO_AUDIO_MUTABLE); - vp.flags|=VIDEO_AUDIO_MUTABLE; - strcpy(vp.name,"TV"); + struct video_audio v; + v=btv->audio_dev; + v.flags&=~(VIDEO_AUDIO_MUTE|VIDEO_AUDIO_MUTABLE); + v.flags|=VIDEO_AUDIO_MUTABLE; + strcpy(v.name,"TV"); if(copy_to_user(&v,arg,sizeof(v))) return -EFAULT; return 0; diff -u --recursive --new-file v2.1.75/linux/drivers/char/mem.c linux/drivers/char/mem.c --- v2.1.75/linux/drivers/char/mem.c Sun Dec 21 22:36:13 1997 +++ linux/drivers/char/mem.c Mon Dec 22 08:42:36 1997 @@ -550,5 +550,8 @@ #ifdef CONFIG_FTAPE ftape_init(); #endif +#ifdef CONFIG_VIDEO_DEV + videodev_init(); +#endif return 0; } diff -u --recursive --new-file v2.1.75/linux/drivers/char/pcwd.c linux/drivers/char/pcwd.c --- v2.1.75/linux/drivers/char/pcwd.c Fri Dec 19 15:52:58 1997 +++ linux/drivers/char/pcwd.c Mon Dec 22 09:03:50 1997 @@ -31,6 +31,8 @@ * 970912 Enabled board on open and disable on close. * 971107 Took account of recent VFS changes (broke read). * 971210 Disable board on initialisation in case board already ticking. + * 971222 Changed open/close for temperature handling + * Michael Meskes . */ #include @@ -378,14 +380,23 @@ static int pcwd_open(struct inode *ino, struct file *filep) { - if (is_open) - return -EIO; - MOD_INC_USE_COUNT; - /* Enable the port */ - if (revision == PCWD_REVISION_C) - outb_p(0x00, current_readport + 3); - is_open = 1; - return(0); + switch (MINOR(ino->i_rdev)) + { + case WD_MINOR: + if (is_open) + return -EBUSY; + MOD_INC_USE_COUNT; + /* Enable the port */ + if (revision == PCWD_REVISION_C) + outb_p(0x00, current_readport + 3); + is_open = 1; + return(0); + case TEMP_MINOR: + MOD_INC_USE_COUNT; + return(0); + default: + return (-ENODEV); + } } static ssize_t pcwd_read(struct file *file, char *buf, size_t count, @@ -400,7 +411,8 @@ switch(MINOR(file->f_dentry->d_inode->i_rdev)) { case TEMP_MINOR: - cp = c; + /* c is in celsius, we need fahrenheit */ + cp = (c*9/5)+32; if(copy_to_user(buf, &cp, 1)) return -EFAULT; return 1; @@ -411,15 +423,18 @@ static int pcwd_close(struct inode *ino, struct file *filep) { - is_open = 0; MOD_DEC_USE_COUNT; + if (MINOR(ino->i_rdev)==WD_MINOR) + { + is_open = 0; #ifndef CONFIG_WATCHDOG_NOWAYOUT - /* Disable the board */ - if (revision == PCWD_REVISION_C) { - outb_p(0xA5, current_readport + 3); - outb_p(0xA5, current_readport + 3); - } + /* Disable the board */ + if (revision == PCWD_REVISION_C) { + outb_p(0xA5, current_readport + 3); + outb_p(0xA5, current_readport + 3); + } #endif + } return 0; } diff -u --recursive --new-file v2.1.75/linux/drivers/net/CONFIG linux/drivers/net/CONFIG --- v2.1.75/linux/drivers/net/CONFIG Sun Feb 2 05:18:35 1997 +++ linux/drivers/net/CONFIG Sun Dec 21 22:37:32 1997 @@ -44,23 +44,11 @@ # DE4X5_DEBUG Set the desired debug level # DEC_ONLY Allows driver to work with DIGITAL cards only - # see linux/drivers/net/README.de4x5 -# DE4X5_AUTOSENSE (Default) auto media/mode selection -# If you want at least one board to not autosense then -# no board can autosense. For a board mix of several -# types, OR the manual values [eg for a DE500 (100M) with -# a DE450 (AUI) use '-DDE4X5_AUTOSENSE=(_100Mb|AUI)'] -# For full auto media/mode selection = AUTO -# For manual TP media selection = TP -# For manual TP/Nway media selection (DC21041) = TP_NW -# For manual BNC media selection = BNC -# For manual AUI media selection = AUI -# For manual BNC/AUI media selection (DC21040) = BNC_AUI -# For manual 10Mb/s mode selection (DC21140) = _10Mb -# For manual 100Mb/s mode selection (DC21140) = _100Mb -# The DC21040 will default to TP if TP_NW is specified -# The DC21041 will default to BNC if BNC_AUI is specified # DE4X5_DO_MEMCPY Forces the Intels to use memory copies into sk_buffs # rather than straight DMA. +# DE4X5_PARM See linux/Documentation/networking/de4x5.txt or the +# driver source code for detailed information on setting +# duplex and speed/media on individual adapters. # # DEFXX The DIGITAL series of FDDI EISA (DEFEA) and PCI (DEFPA) # controllers @@ -95,7 +83,7 @@ PLIP_OPTS = DEPCA_OPTS = EWRK3_OPTS = -DE4X5_OPTS = -DDE4X5_AUTOSENSE=AUTO +DE4X5_OPTS = DEFXX_OPTS = ELP_OPTS = TULIP_OPTS = diff -u --recursive --new-file v2.1.75/linux/drivers/net/Config.in linux/drivers/net/Config.in --- v2.1.75/linux/drivers/net/Config.in Sun Dec 21 22:36:13 1997 +++ linux/drivers/net/Config.in Tue Dec 23 13:52:02 1997 @@ -15,7 +15,9 @@ tristate 'Dummy net driver support' CONFIG_DUMMY tristate 'EQL (serial line load balancing) support' CONFIG_EQUALIZER if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then - tristate 'Ethertap network tap' CONFIG_ETHERTAP + if [ "CONFIG_NETLINK_DEV" != "n" ]; then + dep_tristate 'Ethertap network tap' CONFIG_ETHERTAP $CONFIG_NETLINK_DEV + fi fi # # Ethernet diff -u --recursive --new-file v2.1.75/linux/drivers/net/Makefile linux/drivers/net/Makefile --- v2.1.75/linux/drivers/net/Makefile Thu Dec 4 14:53:55 1997 +++ linux/drivers/net/Makefile Tue Dec 23 10:57:31 1997 @@ -198,7 +198,7 @@ endif ifdef CONFIG_PPP - M_OBJS += bsd_comp.o + M_OBJS += bsd_comp.o ppp_deflate.o endif ifeq ($(CONFIG_SLIP),y) diff -u --recursive --new-file v2.1.75/linux/drivers/net/de4x5.c linux/drivers/net/de4x5.c --- v2.1.75/linux/drivers/net/de4x5.c Sat Nov 29 11:25:09 1997 +++ linux/drivers/net/de4x5.c Sun Dec 21 22:37:32 1997 @@ -1,45 +1,45 @@ /* de4x5.c: A DIGITAL DC21x4x DECchip and DE425/DE434/DE435/DE450/DE500 - ethernet driver for Linux. + ethernet driver for Linux. - Copyright 1994, 1995 Digital Equipment Corporation. + Copyright 1994, 1995 Digital Equipment Corporation. - Testing resources for this driver have been made available - in part by NASA Ames Research Center (mjacob@nas.nasa.gov). + Testing resources for this driver have been made available + in part by NASA Ames Research Center (mjacob@nas.nasa.gov). - The author may be reached at davies@maniac.ultranet.com. + The author may be reached at davies@maniac.ultranet.com. - 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. - - THIS SOFTWARE IS PROVIDED ``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 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. - - 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. - - Originally, this driver was written for the Digital Equipment - Corporation series of EtherWORKS ethernet cards: - - DE425 TP/COAX EISA - DE434 TP PCI - DE435 TP/COAX/AUI PCI - DE450 TP/COAX/AUI PCI - DE500 10/100 PCI Fasternet - - but it will now attempt to support all cards which conform to the - Digital Semiconductor SROM Specification. The driver currently - recognises the following chips: + 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. + + THIS SOFTWARE IS PROVIDED ``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 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. + + 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. + + Originally, this driver was written for the Digital Equipment + Corporation series of EtherWORKS ethernet cards: + + DE425 TP/COAX EISA + DE434 TP PCI + DE435 TP/COAX/AUI PCI + DE450 TP/COAX/AUI PCI + DE500 10/100 PCI Fasternet + + but it will now attempt to support all cards which conform to the + Digital Semiconductor SROM Specification. The driver currently + recognises the following chips: DC21040 (no SROM) DC21041[A] @@ -49,136 +49,136 @@ So far the driver is known to work with the following cards: - KINGSTON - Linksys - ZNYX342 - SMC8432 - SMC9332 (w/new SROM) - ZNYX31[45] - ZNYX346 10/100 4 port (can act as a 10/100 bridge!) - - The driver has been tested on a relatively busy network using the DE425, - DE434, DE435 and DE500 cards and benchmarked with 'ttcp': it transferred - 16M of data to a DECstation 5000/200 as follows: - - TCP UDP - TX RX TX RX - DE425 1030k 997k 1170k 1128k - DE434 1063k 995k 1170k 1125k - DE435 1063k 995k 1170k 1125k - DE500 1063k 998k 1170k 1125k in 10Mb/s mode - - All values are typical (in kBytes/sec) from a sample of 4 for each - measurement. Their error is +/-20k on a quiet (private) network and also - depend on what load the CPU has. - - ========================================================================= - This driver has been written substantially from scratch, although its - inheritance of style and stack interface from 'ewrk3.c' and in turn from - Donald Becker's 'lance.c' should be obvious. With the module autoload of - every usable DECchip board, I pinched Donald's 'next_module' field to - link my modules together. - - Upto 15 EISA cards can be supported under this driver, limited primarily - by the available IRQ lines. I have checked different configurations of - multiple depca, EtherWORKS 3 cards and de4x5 cards and have not found a - problem yet (provided you have at least depca.c v0.38) ... - - PCI support has been added to allow the driver to work with the DE434, - DE435, DE450 and DE500 cards. The I/O accesses are a bit of a kludge due - to the differences in the EISA and PCI CSR address offsets from the base - address. - - The ability to load this driver as a loadable module has been included - and used extensively during the driver development (to save those long - reboot sequences). Loadable module support under PCI and EISA has been - achieved by letting the driver autoprobe as if it were compiled into the - kernel. Do make sure you're not sharing interrupts with anything that - cannot accommodate interrupt sharing! - - To utilise this ability, you have to do 8 things: - - 0) have a copy of the loadable modules code installed on your system. - 1) copy de4x5.c from the /linux/drivers/net directory to your favourite - temporary directory. - 2) for fixed autoprobes (not recommended), edit the source code near - line 5539 to reflect the I/O address you're using, or assign these when - loading by: - - insmod de4x5 io=0xghh where g = bus number - hh = device number - - NB: autoprobing for modules is now supported by default. You may just - use: - - insmod de4x5 - - to load all available boards. For a specific board, still use - the 'io=?' above. - 3) compile de4x5.c, but include -DMODULE in the command line to ensure - that the correct bits are compiled (see end of source code). - 4) if you are wanting to add a new card, goto 5. Otherwise, recompile a - kernel with the de4x5 configuration turned off and reboot. - 5) insmod de4x5 [io=0xghh] - 6) run the net startup bits for your new eth?? interface(s) manually - (usually /etc/rc.inet[12] at boot time). - 7) enjoy! - - To unload a module, turn off the associated interface(s) - 'ifconfig eth?? down' then 'rmmod de4x5'. - - Automedia detection is included so that in principal you can disconnect - from, e.g. TP, reconnect to BNC and things will still work (after a - pause whilst the driver figures out where its media went). My tests - using ping showed that it appears to work.... - - By default, the driver will now autodetect any DECchip based card. - Should you have a need to restrict the driver to DIGITAL only cards, you - can compile with a DEC_ONLY define, or if loading as a module, use the - 'dec_only=1' parameter. - - I've changed the timing routines to use the kernel timer and scheduling - functions so that the hangs and other assorted problems that occurred - while autosensing the media should be gone. A bonus for the DC21040 - auto media sense algorithm is that it can now use one that is more in - line with the rest (the DC21040 chip doesn't have a hardware timer). - The downside is the 1 'jiffies' (10ms) resolution. - - IEEE 802.3u MII interface code has been added in anticipation that some - products may use it in the future. - - The SMC9332 card has a non-compliant SROM which needs fixing - I have - patched this driver to detect it because the SROM format used complies - to a previous DEC-STD format. - - I have removed the buffer copies needed for receive on Intels. I cannot - remove them for Alphas since the Tulip hardware only does longword - aligned DMA transfers and the Alphas get alignment traps with non - longword aligned data copies (which makes them really slow). No comment. - - I have added SROM decoding routines to make this driver work with any - card that supports the Digital Semiconductor SROM spec. This will help - all cards running the dc2114x series chips in particular. Cards using - the dc2104x chips should run correctly with the basic driver. I'm in - debt to for the testing and feedback that helped get - this feature working. So far we have tested KINGSTON, SMC8432, SMC9332 - (with the latest SROM complying with the SROM spec V3: their first was - broken), ZNYX342 and LinkSys. ZYNX314 (dual 21041 MAC) and ZNYX 315 - (quad 21041 MAC) cards also appear to work despite their incorrectly - wired IRQs. - - I have added a temporary fix for interrupt problems when some SCSI cards - share the same interrupt as the DECchip based cards. The problem occurs - because the SCSI card wants to grab the interrupt as a fast interrupt - (runs the service routine with interrupts turned off) vs. this card - which really needs to run the service routine with interrupts turned on. - This driver will now add the interrupt service routine as a fast - interrupt if it is bounced from the slow interrupt. THIS IS NOT A - RECOMMENDED WAY TO RUN THE DRIVER and has been done for a limited time - until people sort out their compatibility issues and the kernel - interrupt service code is fixed. YOU SHOULD SEPARATE OUT THE FAST - INTERRUPT CARDS FROM THE SLOW INTERRUPT CARDS to ensure that they do not - run on the same interrupt. PCMCIA/CardBus is another can of worms... + KINGSTON + Linksys + ZNYX342 + SMC8432 + SMC9332 (w/new SROM) + ZNYX31[45] + ZNYX346 10/100 4 port (can act as a 10/100 bridge!) + + The driver has been tested on a relatively busy network using the DE425, + DE434, DE435 and DE500 cards and benchmarked with 'ttcp': it transferred + 16M of data to a DECstation 5000/200 as follows: + + TCP UDP + TX RX TX RX + DE425 1030k 997k 1170k 1128k + DE434 1063k 995k 1170k 1125k + DE435 1063k 995k 1170k 1125k + DE500 1063k 998k 1170k 1125k in 10Mb/s mode + + All values are typical (in kBytes/sec) from a sample of 4 for each + measurement. Their error is +/-20k on a quiet (private) network and also + depend on what load the CPU has. + + ========================================================================= + This driver has been written substantially from scratch, although its + inheritance of style and stack interface from 'ewrk3.c' and in turn from + Donald Becker's 'lance.c' should be obvious. With the module autoload of + every usable DECchip board, I pinched Donald's 'next_module' field to + link my modules together. + + Upto 15 EISA cards can be supported under this driver, limited primarily + by the available IRQ lines. I have checked different configurations of + multiple depca, EtherWORKS 3 cards and de4x5 cards and have not found a + problem yet (provided you have at least depca.c v0.38) ... + + PCI support has been added to allow the driver to work with the DE434, + DE435, DE450 and DE500 cards. The I/O accesses are a bit of a kludge due + to the differences in the EISA and PCI CSR address offsets from the base + address. + + The ability to load this driver as a loadable module has been included + and used extensively during the driver development (to save those long + reboot sequences). Loadable module support under PCI and EISA has been + achieved by letting the driver autoprobe as if it were compiled into the + kernel. Do make sure you're not sharing interrupts with anything that + cannot accommodate interrupt sharing! + + To utilise this ability, you have to do 8 things: + + 0) have a copy of the loadable modules code installed on your system. + 1) copy de4x5.c from the /linux/drivers/net directory to your favourite + temporary directory. + 2) for fixed autoprobes (not recommended), edit the source code near + line 5594 to reflect the I/O address you're using, or assign these when + loading by: + + insmod de4x5 io=0xghh where g = bus number + hh = device number + + NB: autoprobing for modules is now supported by default. You may just + use: + + insmod de4x5 + + to load all available boards. For a specific board, still use + the 'io=?' above. + 3) compile de4x5.c, but include -DMODULE in the command line to ensure + that the correct bits are compiled (see end of source code). + 4) if you are wanting to add a new card, goto 5. Otherwise, recompile a + kernel with the de4x5 configuration turned off and reboot. + 5) insmod de4x5 [io=0xghh] + 6) run the net startup bits for your new eth?? interface(s) manually + (usually /etc/rc.inet[12] at boot time). + 7) enjoy! + + To unload a module, turn off the associated interface(s) + 'ifconfig eth?? down' then 'rmmod de4x5'. + + Automedia detection is included so that in principal you can disconnect + from, e.g. TP, reconnect to BNC and things will still work (after a + pause whilst the driver figures out where its media went). My tests + using ping showed that it appears to work.... + + By default, the driver will now autodetect any DECchip based card. + Should you have a need to restrict the driver to DIGITAL only cards, you + can compile with a DEC_ONLY define, or if loading as a module, use the + 'dec_only=1' parameter. + + I've changed the timing routines to use the kernel timer and scheduling + functions so that the hangs and other assorted problems that occurred + while autosensing the media should be gone. A bonus for the DC21040 + auto media sense algorithm is that it can now use one that is more in + line with the rest (the DC21040 chip doesn't have a hardware timer). + The downside is the 1 'jiffies' (10ms) resolution. + + IEEE 802.3u MII interface code has been added in anticipation that some + products may use it in the future. + + The SMC9332 card has a non-compliant SROM which needs fixing - I have + patched this driver to detect it because the SROM format used complies + to a previous DEC-STD format. + + I have removed the buffer copies needed for receive on Intels. I cannot + remove them for Alphas since the Tulip hardware only does longword + aligned DMA transfers and the Alphas get alignment traps with non + longword aligned data copies (which makes them really slow). No comment. + + I have added SROM decoding routines to make this driver work with any + card that supports the Digital Semiconductor SROM spec. This will help + all cards running the dc2114x series chips in particular. Cards using + the dc2104x chips should run correctly with the basic driver. I'm in + debt to for the testing and feedback that helped get + this feature working. So far we have tested KINGSTON, SMC8432, SMC9332 + (with the latest SROM complying with the SROM spec V3: their first was + broken), ZNYX342 and LinkSys. ZYNX314 (dual 21041 MAC) and ZNYX 315 + (quad 21041 MAC) cards also appear to work despite their incorrectly + wired IRQs. + + I have added a temporary fix for interrupt problems when some SCSI cards + share the same interrupt as the DECchip based cards. The problem occurs + because the SCSI card wants to grab the interrupt as a fast interrupt + (runs the service routine with interrupts turned off) vs. this card + which really needs to run the service routine with interrupts turned on. + This driver will now add the interrupt service routine as a fast + interrupt if it is bounced from the slow interrupt. THIS IS NOT A + RECOMMENDED WAY TO RUN THE DRIVER and has been done for a limited time + until people sort out their compatibility issues and the kernel + interrupt service code is fixed. YOU SHOULD SEPARATE OUT THE FAST + INTERRUPT CARDS FROM THE SLOW INTERRUPT CARDS to ensure that they do not + run on the same interrupt. PCMCIA/CardBus is another can of worms... Finally, I think I have really fixed the module loading problem with more than one DECchip based card. As a side effect, I don't mess with @@ -188,137 +188,163 @@ is the preferred way to use this driver, since it doesn't have this limitation. - Where SROM media detection is used and full duplex is specified in the - SROM, the feature is ignored unless de4x5_full_duplex is set at compile - time OR during a module load (insmod de4x5 de4x5_full_duplex=1). This - is because there is no way to automatically detect full duplex links - except through autonegotiation. When I include the autonegotiation - feature in the SROM autoconf code, this detection will occur - automatically. + Where SROM media detection is used and full duplex is specified in the + SROM, the feature is ignored unless lp->params.fdx is set at compile + time OR during a module load (insmod de4x5 args='eth??:fdx' [see + below]). This is because there is no way to automatically detect full + duplex links except through autonegotiation. When I include the + autonegotiation feature in the SROM autoconf code, this detection will + occur automatically for that case. + + Command line arguments are now allowed, similar to passing arguments + through LILO. This will allow a per adapter board set up of full duplex + and media. The only lexical constraints are: the board name (dev->name) + appears in the list before its parameters. The list of parameters ends + either at the end of the parameter list or with another board name. The + following parameters are allowed: + + fdx for full duplex + autosense to set the media/speed; with the following + sub-parameters: + TP, TP_NW, BNC, AUI, BNC_AUI, 100Mb, 10Mb, AUTO + + Case sensitivity is important for the sub-parameters. They *must* be + upper case. Examples: + + insmod de4x5 args='eth1:fdx autosense=BNC eth0:autosense=100Mb'. + + For a compiled in driver, in linux/drivers/net/CONFIG, place e.g. + DE4X5_OPTS = -DDE4X5_PARM='"eth0:fdx autosense=AUI eth2:autosense=TP"' + + Yes, I know full duplex isn't permissible on BNC or AUI; they're just + examples. By default, full duplex is turned off and AUTO is the default + autosense setting. In reality, I expect only the full duplex option to + be used. Note the use of single quotes in the two examples above and the + lack of commas to separate items. - TO DO: - ------ + TO DO: + ------ o check what revision numbers the 21142 and 21143 have o - Revision History - ---------------- + Revision History + ---------------- - Version Date Description - - 0.1 17-Nov-94 Initial writing. ALPHA code release. - 0.2 13-Jan-95 Added PCI support for DE435's. - 0.21 19-Jan-95 Added auto media detection. - 0.22 10-Feb-95 Fix interrupt handler call . - Fix recognition bug reported by . - Add request/release_region code. - Add loadable modules support for PCI. - Clean up loadable modules support. - 0.23 28-Feb-95 Added DC21041 and DC21140 support. - Fix missed frame counter value and initialisation. - Fixed EISA probe. - 0.24 11-Apr-95 Change delay routine to use . - Change TX_BUFFS_AVAIL macro. - Change media autodetection to allow manual setting. - Completed DE500 (DC21140) support. - 0.241 18-Apr-95 Interim release without DE500 Autosense Algorithm. - 0.242 10-May-95 Minor changes. - 0.30 12-Jun-95 Timer fix for DC21140. - Portability changes. - Add ALPHA changes from . - Add DE500 semi automatic autosense. - Add Link Fail interrupt TP failure detection. - Add timer based link change detection. - Plugged a memory leak in de4x5_queue_pkt(). - 0.31 13-Jun-95 Fixed PCI stuff for 1.3.1. - 0.32 26-Jun-95 Added verify_area() calls in de4x5_ioctl() from a - suggestion by . - 0.33 8-Aug-95 Add shared interrupt support (not released yet). - 0.331 21-Aug-95 Fix de4x5_open() with fast CPUs. - Fix de4x5_interrupt(). - Fix dc21140_autoconf() mess. - No shared interrupt support. - 0.332 11-Sep-95 Added MII management interface routines. - 0.40 5-Mar-96 Fix setup frame timeout . - Add kernel timer code (h/w is too flaky). - Add MII based PHY autosense. - Add new multicasting code. - Add new autosense algorithms for media/mode - selection using kernel scheduling/timing. - Re-formatted. - Made changes suggested by : - Change driver to detect all DECchip based cards - with DEC_ONLY restriction a special case. - Changed driver to autoprobe as a module. No irq - checking is done now - assume BIOS is good! - Added SMC9332 detection - 0.41 21-Mar-96 Don't check for get_hw_addr checksum unless DEC card - only - Fix for multiple PCI cards reported by - Duh, put the SA_SHIRQ flag into request_interrupt(). - Fix SMC ethernet address in enet_det[]. - Print chip name instead of "UNKNOWN" during boot. - 0.42 26-Apr-96 Fix MII write TA bit error. - Fix bug in dc21040 and dc21041 autosense code. - Remove buffer copies on receive for Intels. - Change sk_buff handling during media disconnects to - eliminate DUP packets. - Add dynamic TX thresholding. - Change all chips to use perfect multicast filtering. - Fix alloc_device() bug - 0.43 21-Jun-96 Fix unconnected media TX retry bug. - Add Accton to the list of broken cards. - Fix TX under-run bug for non DC21140 chips. - Fix boot command probe bug in alloc_device() as - reported by and - . - Add cache locks to prevent a race condition as - reported by and - . - Upgraded alloc_device() code. - 0.431 28-Jun-96 Fix potential bug in queue_pkt() from discussion - with - 0.44 13-Aug-96 Fix RX overflow bug in 2114[023] chips. - Fix EISA probe bugs reported by - and . - 0.441 9-Sep-96 Change dc21041_autoconf() to probe quiet BNC media - with a loopback packet. - 0.442 9-Sep-96 Include AUI in dc21041 media printout. Bug reported - by - 0.45 8-Dec-96 Include endian functions for PPC use, from work - by and . - 0.451 28-Dec-96 Added fix to allow autoprobe for modules after - suggestion from . - 0.5 30-Jan-97 Added SROM decoding functions. - Updated debug flags. - Fix sleep/wakeup calls for PCI cards, bug reported - by . - Added multi-MAC, one SROM feature from discussion - with . - Added full module autoprobe capability. - Added attempt to use an SMC9332 with broken SROM. - Added fix for ZYNX multi-mac cards that didn't - get their IRQs wired correctly. - 0.51 13-Feb-97 Added endian fixes for the SROM accesses from - - Fix init_connection() to remove extra device reset. - Fix MAC/PHY reset ordering in dc21140m_autoconf(). - Fix initialisation problem with lp->timeout in - typeX_infoblock() from . - Fix MII PHY reset problem from work done by - . - 0.52 26-Apr-97 Some changes may not credit the right people - - a disk crash meant I lost some mail. - Change RX interrupt routine to drop rather than - defer packets to avoid hang reported by - . - Fix srom_exec() to return for COMPACT and type 1 - infoblocks. - Added DC21142 and DC21143 functions. - Added byte counters from - Added SA_INTERRUPT temporary fix from - . + Version Date Description + + 0.1 17-Nov-94 Initial writing. ALPHA code release. + 0.2 13-Jan-95 Added PCI support for DE435's. + 0.21 19-Jan-95 Added auto media detection. + 0.22 10-Feb-95 Fix interrupt handler call . + Fix recognition bug reported by . + Add request/release_region code. + Add loadable modules support for PCI. + Clean up loadable modules support. + 0.23 28-Feb-95 Added DC21041 and DC21140 support. + Fix missed frame counter value and initialisation. + Fixed EISA probe. + 0.24 11-Apr-95 Change delay routine to use . + Change TX_BUFFS_AVAIL macro. + Change media autodetection to allow manual setting. + Completed DE500 (DC21140) support. + 0.241 18-Apr-95 Interim release without DE500 Autosense Algorithm. + 0.242 10-May-95 Minor changes. + 0.30 12-Jun-95 Timer fix for DC21140. + Portability changes. + Add ALPHA changes from . + Add DE500 semi automatic autosense. + Add Link Fail interrupt TP failure detection. + Add timer based link change detection. + Plugged a memory leak in de4x5_queue_pkt(). + 0.31 13-Jun-95 Fixed PCI stuff for 1.3.1. + 0.32 26-Jun-95 Added verify_area() calls in de4x5_ioctl() from a + suggestion by . + 0.33 8-Aug-95 Add shared interrupt support (not released yet). + 0.331 21-Aug-95 Fix de4x5_open() with fast CPUs. + Fix de4x5_interrupt(). + Fix dc21140_autoconf() mess. + No shared interrupt support. + 0.332 11-Sep-95 Added MII management interface routines. + 0.40 5-Mar-96 Fix setup frame timeout . + Add kernel timer code (h/w is too flaky). + Add MII based PHY autosense. + Add new multicasting code. + Add new autosense algorithms for media/mode + selection using kernel scheduling/timing. + Re-formatted. + Made changes suggested by : + Change driver to detect all DECchip based cards + with DEC_ONLY restriction a special case. + Changed driver to autoprobe as a module. No irq + checking is done now - assume BIOS is good! + Added SMC9332 detection + 0.41 21-Mar-96 Don't check for get_hw_addr checksum unless DEC card + only + Fix for multiple PCI cards reported by + Duh, put the SA_SHIRQ flag into request_interrupt(). + Fix SMC ethernet address in enet_det[]. + Print chip name instead of "UNKNOWN" during boot. + 0.42 26-Apr-96 Fix MII write TA bit error. + Fix bug in dc21040 and dc21041 autosense code. + Remove buffer copies on receive for Intels. + Change sk_buff handling during media disconnects to + eliminate DUP packets. + Add dynamic TX thresholding. + Change all chips to use perfect multicast filtering. + Fix alloc_device() bug + 0.43 21-Jun-96 Fix unconnected media TX retry bug. + Add Accton to the list of broken cards. + Fix TX under-run bug for non DC21140 chips. + Fix boot command probe bug in alloc_device() as + reported by and + . + Add cache locks to prevent a race condition as + reported by and + . + Upgraded alloc_device() code. + 0.431 28-Jun-96 Fix potential bug in queue_pkt() from discussion + with + 0.44 13-Aug-96 Fix RX overflow bug in 2114[023] chips. + Fix EISA probe bugs reported by + and . + 0.441 9-Sep-96 Change dc21041_autoconf() to probe quiet BNC media + with a loopback packet. + 0.442 9-Sep-96 Include AUI in dc21041 media printout. Bug reported + by + 0.45 8-Dec-96 Include endian functions for PPC use, from work + by and . + 0.451 28-Dec-96 Added fix to allow autoprobe for modules after + suggestion from . + 0.5 30-Jan-97 Added SROM decoding functions. + Updated debug flags. + Fix sleep/wakeup calls for PCI cards, bug reported + by . + Added multi-MAC, one SROM feature from discussion + with . + Added full module autoprobe capability. + Added attempt to use an SMC9332 with broken SROM. + Added fix for ZYNX multi-mac cards that didn't + get their IRQs wired correctly. + 0.51 13-Feb-97 Added endian fixes for the SROM accesses from + + Fix init_connection() to remove extra device reset. + Fix MAC/PHY reset ordering in dc21140m_autoconf(). + Fix initialisation problem with lp->timeout in + typeX_infoblock() from . + Fix MII PHY reset problem from work done by + . + 0.52 26-Apr-97 Some changes may not credit the right people - + a disk crash meant I lost some mail. + Change RX interrupt routine to drop rather than + defer packets to avoid hang reported by + . + Fix srom_exec() to return for COMPACT and type 1 + infoblocks. + Added DC21142 and DC21143 functions. + Added byte counters from + Added SA_INTERRUPT temporary fix from + . 0.53 12-Nov-97 Fix the *_probe() to include 'eth??' name during module load: bug reported by @@ -327,11 +353,22 @@ Make above search independent of BIOS device scan direction. Completed DC2114[23] autosense functions. + 0.531 21-Dec-97 Fix DE500-XA 100Mb/s bug reported by + and + . + Added argument list to set up each board from either + a module's command line or a compiled in #define. + Added generic MII PHY functionality to deal with + newer PHY chips. + Fix the mess in 2.1.67. - ========================================================================= - */ + ========================================================================= +*/ -static const char *version = "de4x5.c:V0.53 1997/11/12 davies@maniac.ultranet.com\n"; +static const char *version = "de4x5.c:T0.531 1997/12/21 davies@maniac.ultranet.com\n"; #include @@ -388,77 +425,81 @@ #else # include # include -#endif /* LINUX_VERSION_CODE */ +#endif /* LINUX_VERSION_CODE */ #define TWIDDLE(a) (u_short)le16_to_cpu(get_unaligned((u_short *)(a))) /* ** MII Information */ struct phy_table { - int reset; /* Hard reset required? */ - int id; /* IEEE OUI */ - int ta; /* One cycle TA time - 802.3u is confusing here */ - struct { /* Non autonegotiation (parallel) speed det. */ - int reg; - int mask; - int value; - } spd; + int reset; /* Hard reset required? */ + int id; /* IEEE OUI */ + int ta; /* One cycle TA time - 802.3u is confusing here */ + struct { /* Non autonegotiation (parallel) speed det. */ + int reg; + int mask; + int value; + } spd; }; struct mii_phy { - int reset; /* Hard reset required? */ - int id; /* IEEE OUI */ - int ta; /* One cycle TA time */ - struct { /* Non autonegotiation (parallel) speed det. */ - int reg; - int mask; - int value; - } spd; - int addr; /* MII address for the PHY */ - u_char *gep; /* Start of GEP sequence block in SROM */ - u_char *rst; /* Start of reset sequence in SROM */ - u_int mc; /* Media Capabilities */ - u_int ana; /* NWay Advertisement */ - u_int fdx; /* Full DupleX capabilites for each media */ - u_int ttm; /* Transmit Threshold Mode for each media */ - u_int mci; /* 21142 MII Connector Interrupt info */ + int reset; /* Hard reset required? */ + int id; /* IEEE OUI */ + int ta; /* One cycle TA time */ + struct { /* Non autonegotiation (parallel) speed det. */ + int reg; + int mask; + int value; + } spd; + int addr; /* MII address for the PHY */ + u_char *gep; /* Start of GEP sequence block in SROM */ + u_char *rst; /* Start of reset sequence in SROM */ + u_int mc; /* Media Capabilities */ + u_int ana; /* NWay Advertisement */ + u_int fdx; /* Full DupleX capabilites for each media */ + u_int ttm; /* Transmit Threshold Mode for each media */ + u_int mci; /* 21142 MII Connector Interrupt info */ }; -#define DE4X5_MAX_PHY 8 /* Allow upto 8 attached PHY devices per board */ +#define DE4X5_MAX_PHY 8 /* Allow upto 8 attached PHY devices per board */ struct sia_phy { - u_char mc; /* Media Code */ - u_char ext; /* csr13-15 valid when set */ - int csr13; /* SIA Connectivity Register */ - int csr14; /* SIA TX/RX Register */ - int csr15; /* SIA General Register */ - int gepc; /* SIA GEP Control Information */ - int gep; /* SIA GEP Data */ + u_char mc; /* Media Code */ + u_char ext; /* csr13-15 valid when set */ + int csr13; /* SIA Connectivity Register */ + int csr14; /* SIA TX/RX Register */ + int csr15; /* SIA General Register */ + int gepc; /* SIA GEP Control Information */ + int gep; /* SIA GEP Data */ }; /* ** Define the know universe of PHY devices that can be -** recognised by this driver +** recognised by this driver. */ -static struct phy_table phy_info[] = -{ - {0, NATIONAL_TX, 1, - {0x19, 0x40, 0x00}}, /* National TX */ - {1, BROADCOM_T4, 1, - {0x10, 0x02, 0x02}}, /* Broadcom T4 */ - {0, SEEQ_T4, 1, - {0x12, 0x10, 0x10}}, /* SEEQ T4 */ - {0, CYPRESS_T4, 1, - {0x05, 0x20, 0x20}} /* Cypress T4 */ +static struct phy_table phy_info[] = { + {0, NATIONAL_TX, 1, {0x19, 0x40, 0x00}}, /* National TX */ + {1, BROADCOM_T4, 1, {0x10, 0x02, 0x02}}, /* Broadcom T4 */ + {0, SEEQ_T4 , 1, {0x12, 0x10, 0x10}}, /* SEEQ T4 */ + {0, CYPRESS_T4 , 1, {0x05, 0x20, 0x20}}, /* Cypress T4 */ + {0, 0x7810 , 1, {0x05, 0x0380, 0x0380}} /* Level One? */ }; /* +** These GENERIC values assumes that the PHY devices follow 802.3u and +** allow parallel detection to set the link partner ability register. +** Detection of 100Base-TX [H/F Duplex] and 100Base-T4 is supported. +*/ +#define GENERIC_REG 0x05 /* Autoneg. Link Partner Advertisement Reg. */ +#define GENERIC_MASK MII_ANLPA_100M /* All 100Mb/s Technologies */ +#define GENERIC_VALUE MII_ANLPA_100M /* 100B-TX, 100B-TX FDX, 100B-T4 */ + +/* ** Define special SROM detection cases */ -static c_char enet_det[][ETH_ALEN] = -{ - {0x00, 0x00, 0xc0, 0x00, 0x00, 0x00}, - {0x00, 0x00, 0xe8, 0x00, 0x00, 0x00} +static c_char enet_det[][ETH_ALEN] = { + {0x00, 0x00, 0xc0, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0xe8, 0x00, 0x00, 0x00} }; #define SMC 1 @@ -469,14 +510,14 @@ ** use this information to help figure out what to do. This is a ** "stab in the dark" and so far for SMC9332's only. */ -static c_char srom_repair_info[][100] = -{ - {0x00, 0x1e, 0x00, 0x00, 0x00, 0x08, /* SMC9332 */ - 0x1f, 0x01, 0x8f, 0x01, 0x00, 0x01, 0x00, 0x02, - 0x01, 0x00, 0x00, 0x78, 0xe0, 0x01, 0x00, 0x50, - 0x00, 0x18,} +static c_char srom_repair_info[][100] = { + {0x00,0x1e,0x00,0x00,0x00,0x08, /* SMC9332 */ + 0x1f,0x01,0x8f,0x01,0x00,0x01,0x00,0x02, + 0x01,0x00,0x00,0x78,0xe0,0x01,0x00,0x50, + 0x00,0x18,} }; + #ifdef DE4X5_DEBUG static int de4x5_debug = DE4X5_DEBUG; #else @@ -484,20 +525,29 @@ static int de4x5_debug = (DEBUG_MEDIA | DEBUG_VERSION); #endif -#ifdef DE4X5_AUTOSENSE /* Should be done on a per adapter basis */ -static int de4x5_autosense = DE4X5_AUTOSENSE; +/* +** Allow per adapter set up. For modules this is simply a command line +** parameter, e.g.: +** insmod de4x5 args='eth1:fdx autosense=BNC eth0:autosense=100Mb'. +** +** For a compiled in driver, place e.g. +** DE4X5_OPTS = -DDE4X5_PARM='"eth0:fdx autosense=AUI eth2:autosense=TP"' +** in linux/drivers/net/CONFIG +*/ +#ifdef DE4X5_PARM +static char *args = DE4X5_PARM; #else -static int de4x5_autosense = AUTO; /* Do auto media/mode sensing */ +static char *args = NULL; #endif -#define DE4X5_AUTOSENSE_MS 250 /* msec autosense tick (DE500) */ -#ifdef DE4X5_FULL_DUPLEX /* Should be done on a per adapter basis */ -static s32 de4x5_full_duplex = 1; -#else -static s32 de4x5_full_duplex = 0; -#endif +struct parameters { + int fdx; + int autosense; +}; + +#define DE4X5_AUTOSENSE_MS 250 /* msec autosense tick (DE500) */ -#define DE4X5_NDA 0xffe0 /* No Device (I/O) Address */ +#define DE4X5_NDA 0xffe0 /* No Device (I/O) Address */ /* ** Ethernet PROM defines @@ -508,24 +558,24 @@ /* ** Ethernet Info */ -#define PKT_BUF_SZ 1536 /* Buffer size for each Tx/Rx buffer */ -#define IEEE802_3_SZ 1518 /* Packet + CRC */ -#define MAX_PKT_SZ 1514 /* Maximum ethernet packet length */ -#define MAX_DAT_SZ 1500 /* Maximum ethernet data length */ -#define MIN_DAT_SZ 1 /* Minimum ethernet data length */ -#define PKT_HDR_LEN 14 /* Addresses and data length info */ +#define PKT_BUF_SZ 1536 /* Buffer size for each Tx/Rx buffer */ +#define IEEE802_3_SZ 1518 /* Packet + CRC */ +#define MAX_PKT_SZ 1514 /* Maximum ethernet packet length */ +#define MAX_DAT_SZ 1500 /* Maximum ethernet data length */ +#define MIN_DAT_SZ 1 /* Minimum ethernet data length */ +#define PKT_HDR_LEN 14 /* Addresses and data length info */ #define FAKE_FRAME_LEN (MAX_PKT_SZ + 1) -#define QUEUE_PKT_TIMEOUT (3*HZ) /* 3 second timeout */ +#define QUEUE_PKT_TIMEOUT (3*HZ) /* 3 second timeout */ -#define CRC_POLYNOMIAL_BE 0x04c11db7UL /* Ethernet CRC, big endian */ -#define CRC_POLYNOMIAL_LE 0xedb88320UL /* Ethernet CRC, little endian */ +#define CRC_POLYNOMIAL_BE 0x04c11db7UL /* Ethernet CRC, big endian */ +#define CRC_POLYNOMIAL_LE 0xedb88320UL /* Ethernet CRC, little endian */ /* ** EISA bus defines */ -#define DE4X5_EISA_IO_PORTS 0x0c00 /* I/O port base address, slot 0 */ -#define DE4X5_EISA_TOTAL_SIZE 0x100 /* I/O address extent */ +#define DE4X5_EISA_IO_PORTS 0x0c00 /* I/O port base address, slot 0 */ +#define DE4X5_EISA_TOTAL_SIZE 0x100 /* I/O address extent */ #define MAX_EISA_SLOTS 16 #define EISA_SLOT_INC 0x1000 @@ -538,8 +588,8 @@ ** PCI Bus defines */ #define PCI_MAX_BUS_NUM 8 -#define DE4X5_PCI_TOTAL_SIZE 0x80 /* I/O address extent */ -#define DE4X5_CLASS_CODE 0x00020000 /* Network controller, Ethernet */ +#define DE4X5_PCI_TOTAL_SIZE 0x80 /* I/O address extent */ +#define DE4X5_CLASS_CODE 0x00020000 /* Network controller, Ethernet */ #define NO_MORE_PCI -2 /* PCI bus search all done */ /* @@ -548,20 +598,20 @@ ** DESC_ALIGN. ALIGN aligns the start address of the private memory area ** and hence the RX descriptor ring's first entry. */ -#define ALIGN4 ((u_long)4 - 1) /* 1 longword align */ -#define ALIGN8 ((u_long)8 - 1) /* 2 longword align */ -#define ALIGN16 ((u_long)16 - 1) /* 4 longword align */ -#define ALIGN32 ((u_long)32 - 1) /* 8 longword align */ -#define ALIGN64 ((u_long)64 - 1) /* 16 longword align */ -#define ALIGN128 ((u_long)128 - 1) /* 32 longword align */ +#define ALIGN4 ((u_long)4 - 1) /* 1 longword align */ +#define ALIGN8 ((u_long)8 - 1) /* 2 longword align */ +#define ALIGN16 ((u_long)16 - 1) /* 4 longword align */ +#define ALIGN32 ((u_long)32 - 1) /* 8 longword align */ +#define ALIGN64 ((u_long)64 - 1) /* 16 longword align */ +#define ALIGN128 ((u_long)128 - 1) /* 32 longword align */ -#define ALIGN ALIGN32 /* Keep the DC21040 happy... */ +#define ALIGN ALIGN32 /* Keep the DC21040 happy... */ #define CACHE_ALIGN CAL_16LONG -#define DESC_SKIP_LEN DSL_0 /* Must agree with DESC_ALIGN */ +#define DESC_SKIP_LEN DSL_0 /* Must agree with DESC_ALIGN */ /*#define DESC_ALIGN u32 dummy[4]; / * Must agree with DESC_SKIP_LEN */ #define DESC_ALIGN -#ifndef DEC_ONLY /* See README.de4x5 for using this */ +#ifndef DEC_ONLY /* See README.de4x5 for using this */ static int dec_only = 0; #else static int dec_only = 1; @@ -610,7 +660,7 @@ /* ** DE4X5 SIA RESET */ -#define RESET_SIA outl(0, DE4X5_SICR); /* Reset SIA connectivity regs */ +#define RESET_SIA outl(0, DE4X5_SICR); /* Reset SIA connectivity regs */ /* ** DE500 AUTOSENSE TIMER INTERVAL (MILLISECS) @@ -621,18 +671,17 @@ ** SROM Structure */ struct de4x5_srom { - char sub_vendor_id[2]; - char sub_system_id[2]; - char reserved[12]; - char id_block_crc; - char reserved2; - char version; - char num_controllers; - char ieee_addr[6]; - char info[100]; - short chksum; + char sub_vendor_id[2]; + char sub_system_id[2]; + char reserved[12]; + char id_block_crc; + char reserved2; + char version; + char num_controllers; + char ieee_addr[6]; + char info[100]; + short chksum; }; - #define SUB_VENDOR_ID 0x500a /* @@ -643,106 +692,107 @@ ** is possible. 1536 showed better 'ttcp' performance. Take your pick. 32 TX ** descriptors are needed for machines with an ALPHA CPU. */ -#define NUM_RX_DESC 8 /* Number of RX descriptors */ -#define NUM_TX_DESC 32 /* Number of TX descriptors */ -#define RX_BUFF_SZ 1536 /* Power of 2 for kmalloc and */ - /* Multiple of 4 for DC21040 */ - /* Allows 512 byte alignment */ +#define NUM_RX_DESC 8 /* Number of RX descriptors */ +#define NUM_TX_DESC 32 /* Number of TX descriptors */ +#define RX_BUFF_SZ 1536 /* Power of 2 for kmalloc and */ + /* Multiple of 4 for DC21040 */ + /* Allows 512 byte alignment */ struct de4x5_desc { - volatile s32 status; - u32 des1; - u32 buf; - u32 next; - DESC_ALIGN + volatile s32 status; + u32 des1; + u32 buf; + u32 next; + DESC_ALIGN }; /* ** The DE4X5 private structure */ #define DE4X5_PKT_STAT_SZ 16 -#define DE4X5_PKT_BIN_SZ 128 /* Should be >=100 unless you - increase DE4X5_PKT_STAT_SZ */ +#define DE4X5_PKT_BIN_SZ 128 /* Should be >=100 unless you + increase DE4X5_PKT_STAT_SZ */ struct de4x5_private { - char adapter_name[80]; /* Adapter name */ - struct de4x5_desc rx_ring[NUM_RX_DESC]; /* RX descriptor ring */ - struct de4x5_desc tx_ring[NUM_TX_DESC]; /* TX descriptor ring */ - struct sk_buff *tx_skb[NUM_TX_DESC]; /* TX skb for freeing when sent */ - struct sk_buff *rx_skb[NUM_RX_DESC]; /* RX skb's */ - int rx_new, rx_old; /* RX descriptor ring pointers */ - int tx_new, tx_old; /* TX descriptor ring pointers */ - char setup_frame[SETUP_FRAME_LEN]; /* Holds MCA and PA info. */ - char frame[64]; /* Min sized packet for loopback */ - struct net_device_stats stats; /* Public stats */ - struct { - u_int bins[DE4X5_PKT_STAT_SZ]; /* Private stats counters */ - u_int unicast; - u_int multicast; - u_int broadcast; - u_int excessive_collisions; - u_int tx_underruns; - u_int excessive_underruns; - u_int rx_runt_frames; - u_int rx_collision; - u_int rx_dribble; - u_int rx_overflow; - } pktStats; - char rxRingSize; - char txRingSize; - int bus; /* EISA or PCI */ - int bus_num; /* PCI Bus number */ - int device; /* Device number on PCI bus */ - int state; /* Adapter OPENED or CLOSED */ - int chipset; /* DC21040, DC21041 or DC21140 */ - s32 irq_mask; /* Interrupt Mask (Enable) bits */ - s32 irq_en; /* Summary interrupt bits */ - int media; /* Media (eg TP), mode (eg 100B) */ - int c_media; /* Remember the last media conn */ - int fdx; /* media full duplex flag */ - int linkOK; /* Link is OK */ - int autosense; /* Allow/disallow autosensing */ - int tx_enable; /* Enable descriptor polling */ - int setup_f; /* Setup frame filtering type */ - int local_state; /* State within a 'media' state */ - struct mii_phy phy[DE4X5_MAX_PHY]; /* List of attached PHY devices */ - struct sia_phy sia; /* SIA PHY Information */ - int active; /* Index to active PHY device */ - int mii_cnt; /* Number of attached PHY's */ - int timeout; /* Scheduling counter */ - struct timer_list timer; /* Timer info for kernel */ - int tmp; /* Temporary global per card */ - struct { - void *priv; /* Original kmalloc'd mem addr */ - void *buf; /* Original kmalloc'd mem addr */ - unsigned long lock; /* Lock the cache accesses */ - s32 csr0; /* Saved Bus Mode Register */ - s32 csr6; /* Saved Operating Mode Reg. */ - s32 csr7; /* Saved IRQ Mask Register */ - s32 gep; /* Saved General Purpose Reg. */ - s32 gepc; /* Control info for GEP */ - s32 csr13; /* Saved SIA Connectivity Reg. */ - s32 csr14; /* Saved SIA TX/RX Register */ - s32 csr15; /* Saved SIA General Register */ - int save_cnt; /* Flag if state already saved */ - struct sk_buff *skb; /* Save the (re-ordered) skb's */ - } cache; - struct de4x5_srom srom; /* A copy of the SROM */ - struct device *next_module; /* Link to the next module */ - int rx_ovf; /* Check for 'RX overflow' tag */ - int useSROM; /* For non-DEC card use SROM */ - int useMII; /* Infoblock using the MII */ - int asBitValid; /* Autosense bits in GEP? */ - int asPolarity; /* 0 => asserted high */ - int asBit; /* Autosense bit number in GEP */ - int defMedium; /* SROM default medium */ - int tcount; /* Last infoblock number */ - int infoblock_init; /* Initialised this infoblock? */ - int infoleaf_offset; /* SROM infoleaf for controller */ - s32 infoblock_csr6; /* csr6 value in SROM infoblock */ - int infoblock_media; /* infoblock media */ - int (*infoleaf_fn) (struct device *); /* Pointer to infoleaf function */ - u_char *rst; /* Pointer to Type 5 reset info */ - u_char ibn; /* Infoblock number */ + char adapter_name[80]; /* Adapter name */ + struct de4x5_desc rx_ring[NUM_RX_DESC]; /* RX descriptor ring */ + struct de4x5_desc tx_ring[NUM_TX_DESC]; /* TX descriptor ring */ + struct sk_buff *tx_skb[NUM_TX_DESC]; /* TX skb for freeing when sent */ + struct sk_buff *rx_skb[NUM_RX_DESC]; /* RX skb's */ + int rx_new, rx_old; /* RX descriptor ring pointers */ + int tx_new, tx_old; /* TX descriptor ring pointers */ + char setup_frame[SETUP_FRAME_LEN]; /* Holds MCA and PA info. */ + char frame[64]; /* Min sized packet for loopback*/ + struct net_device_stats stats; /* Public stats */ + struct { + u_int bins[DE4X5_PKT_STAT_SZ]; /* Private stats counters */ + u_int unicast; + u_int multicast; + u_int broadcast; + u_int excessive_collisions; + u_int tx_underruns; + u_int excessive_underruns; + u_int rx_runt_frames; + u_int rx_collision; + u_int rx_dribble; + u_int rx_overflow; + } pktStats; + char rxRingSize; + char txRingSize; + int bus; /* EISA or PCI */ + int bus_num; /* PCI Bus number */ + int device; /* Device number on PCI bus */ + int state; /* Adapter OPENED or CLOSED */ + int chipset; /* DC21040, DC21041 or DC21140 */ + s32 irq_mask; /* Interrupt Mask (Enable) bits */ + s32 irq_en; /* Summary interrupt bits */ + int media; /* Media (eg TP), mode (eg 100B)*/ + int c_media; /* Remember the last media conn */ + int fdx; /* media full duplex flag */ + int linkOK; /* Link is OK */ + int autosense; /* Allow/disallow autosensing */ + int tx_enable; /* Enable descriptor polling */ + int setup_f; /* Setup frame filtering type */ + int local_state; /* State within a 'media' state */ + struct mii_phy phy[DE4X5_MAX_PHY]; /* List of attached PHY devices */ + struct sia_phy sia; /* SIA PHY Information */ + int active; /* Index to active PHY device */ + int mii_cnt; /* Number of attached PHY's */ + int timeout; /* Scheduling counter */ + struct timer_list timer; /* Timer info for kernel */ + int tmp; /* Temporary global per card */ + struct { + void *priv; /* Original kmalloc'd mem addr */ + void *buf; /* Original kmalloc'd mem addr */ + int lock; /* Lock the cache accesses */ + s32 csr0; /* Saved Bus Mode Register */ + s32 csr6; /* Saved Operating Mode Reg. */ + s32 csr7; /* Saved IRQ Mask Register */ + s32 gep; /* Saved General Purpose Reg. */ + s32 gepc; /* Control info for GEP */ + s32 csr13; /* Saved SIA Connectivity Reg. */ + s32 csr14; /* Saved SIA TX/RX Register */ + s32 csr15; /* Saved SIA General Register */ + int save_cnt; /* Flag if state already saved */ + struct sk_buff *skb; /* Save the (re-ordered) skb's */ + } cache; + struct de4x5_srom srom; /* A copy of the SROM */ + struct device *next_module; /* Link to the next module */ + int rx_ovf; /* Check for 'RX overflow' tag */ + int useSROM; /* For non-DEC card use SROM */ + int useMII; /* Infoblock using the MII */ + int asBitValid; /* Autosense bits in GEP? */ + int asPolarity; /* 0 => asserted high */ + int asBit; /* Autosense bit number in GEP */ + int defMedium; /* SROM default medium */ + int tcount; /* Last infoblock number */ + int infoblock_init; /* Initialised this infoblock? */ + int infoleaf_offset; /* SROM infoleaf for controller */ + s32 infoblock_csr6; /* csr6 value in SROM infoblock */ + int infoblock_media; /* infoblock media */ + int (*infoleaf_fn)(struct device *); /* Pointer to infoleaf function */ + u_char *rst; /* Pointer to Type 5 reset info */ + u_char ibn; /* Infoblock number */ + struct parameters params; /* Command line/ #defined params */ }; /* @@ -751,13 +801,13 @@ ** PROM is accessed differently. */ static struct bus_type { - int bus; - int bus_num; - int device; - int chipset; - struct de4x5_srom srom; - int autosense; - int useSROM; + int bus; + int bus_num; + int device; + int chipset; + struct de4x5_srom srom; + int autosense; + int useSROM; } bus; /* @@ -773,14 +823,11 @@ ** can't follow the PCI to PCI Bridge Architecture spec. */ static struct { - int chipset; - int bus; - int irq; - u_char addr[ETH_ALEN]; -} last = { - - 0, -}; + int chipset; + int bus; + int irq; + u_char addr[ETH_ALEN]; +} last = {0,}; /* ** The transmit ring full condition is described by the tx_old and tx_new @@ -798,143 +845,143 @@ /* ** Public Functions */ -static int de4x5_open(struct device *dev); -static int de4x5_queue_pkt(struct sk_buff *skb, struct device *dev); -static void de4x5_interrupt(int irq, void *dev_id, struct pt_regs *regs); -static int de4x5_close(struct device *dev); -static struct net_device_stats *de4x5_get_stats(struct device *dev); -static void de4x5_local_stats(struct device *dev, char *buf, int pkt_len); -static void set_multicast_list(struct device *dev); -static int de4x5_ioctl(struct device *dev, struct ifreq *rq, int cmd); +static int de4x5_open(struct device *dev); +static int de4x5_queue_pkt(struct sk_buff *skb, struct device *dev); +static void de4x5_interrupt(int irq, void *dev_id, struct pt_regs *regs); +static int de4x5_close(struct device *dev); +static struct net_device_stats *de4x5_get_stats(struct device *dev); +static void de4x5_local_stats(struct device *dev, char *buf, int pkt_len); +static void set_multicast_list(struct device *dev); +static int de4x5_ioctl(struct device *dev, struct ifreq *rq, int cmd); /* ** Private functions */ -static int de4x5_hw_init(struct device *dev, u_long iobase); -static int de4x5_init(struct device *dev); -static int de4x5_sw_reset(struct device *dev); -static int de4x5_rx(struct device *dev); -static int de4x5_tx(struct device *dev); -static int de4x5_ast(struct device *dev); -static int de4x5_txur(struct device *dev); -static int de4x5_rx_ovfc(struct device *dev); - -static int autoconf_media(struct device *dev); -static void create_packet(struct device *dev, char *frame, int len); -static void de4x5_us_delay(u32 usec); -static void de4x5_ms_delay(u32 msec); -static void load_packet(struct device *dev, char *buf, u32 flags, struct sk_buff *skb); -static int dc21040_autoconf(struct device *dev); -static int dc21041_autoconf(struct device *dev); -static int dc21140m_autoconf(struct device *dev); -static int dc2114x_autoconf(struct device *dev); -static int srom_autoconf(struct device *dev); -static int de4x5_suspect_state(struct device *dev, int timeout, int prev_state, int (*fn) (struct device *, int), int (*asfn) (struct device *)); -static int dc21040_state(struct device *dev, int csr13, int csr14, int csr15, int timeout, int next_state, int suspect_state, int (*fn) (struct device *, int)); -static int test_media(struct device *dev, s32 irqs, s32 irq_mask, s32 csr13, s32 csr14, s32 csr15, s32 msec); -static int test_for_100Mb(struct device *dev, int msec); -static int wait_for_link(struct device *dev); -static int test_mii_reg(struct device *dev, int reg, int mask, int pol, long msec); -static int is_spd_100(struct device *dev); -static int is_100_up(struct device *dev); -static int is_10_up(struct device *dev); -static int is_anc_capable(struct device *dev); -static int ping_media(struct device *dev, int msec); +static int de4x5_hw_init(struct device *dev, u_long iobase); +static int de4x5_init(struct device *dev); +static int de4x5_sw_reset(struct device *dev); +static int de4x5_rx(struct device *dev); +static int de4x5_tx(struct device *dev); +static int de4x5_ast(struct device *dev); +static int de4x5_txur(struct device *dev); +static int de4x5_rx_ovfc(struct device *dev); + +static int autoconf_media(struct device *dev); +static void create_packet(struct device *dev, char *frame, int len); +static void de4x5_us_delay(u32 usec); +static void de4x5_ms_delay(u32 msec); +static void load_packet(struct device *dev, char *buf, u32 flags, struct sk_buff *skb); +static int dc21040_autoconf(struct device *dev); +static int dc21041_autoconf(struct device *dev); +static int dc21140m_autoconf(struct device *dev); +static int dc2114x_autoconf(struct device *dev); +static int srom_autoconf(struct device *dev); +static int de4x5_suspect_state(struct device *dev, int timeout, int prev_state, int (*fn)(struct device *, int), int (*asfn)(struct device *)); +static int dc21040_state(struct device *dev, int csr13, int csr14, int csr15, int timeout, int next_state, int suspect_state, int (*fn)(struct device *, int)); +static int test_media(struct device *dev, s32 irqs, s32 irq_mask, s32 csr13, s32 csr14, s32 csr15, s32 msec); +static int test_for_100Mb(struct device *dev, int msec); +static int wait_for_link(struct device *dev); +static int test_mii_reg(struct device *dev, int reg, int mask, int pol, long msec); +static int is_spd_100(struct device *dev); +static int is_100_up(struct device *dev); +static int is_10_up(struct device *dev); +static int is_anc_capable(struct device *dev); +static int ping_media(struct device *dev, int msec); static struct sk_buff *de4x5_alloc_rx_buff(struct device *dev, int index, int len); -static void de4x5_free_rx_buffs(struct device *dev); -static void de4x5_free_tx_buffs(struct device *dev); -static void de4x5_save_skbs(struct device *dev); -static void de4x5_restore_skbs(struct device *dev); -static void de4x5_cache_state(struct device *dev, int flag); -static void de4x5_put_cache(struct device *dev, struct sk_buff *skb); -static void de4x5_putb_cache(struct device *dev, struct sk_buff *skb); -static struct sk_buff *de4x5_get_cache(struct device *dev); -static void de4x5_setup_intr(struct device *dev); -static void de4x5_init_connection(struct device *dev); -static int de4x5_reset_phy(struct device *dev); -static void reset_init_sia(struct device *dev, s32 sicr, s32 strr, s32 sigr); -static int test_ans(struct device *dev, s32 irqs, s32 irq_mask, s32 msec); -static int test_tp(struct device *dev, s32 msec); -static int EISA_signature(char *name, s32 eisa_id); -static int PCI_signature(char *name, struct bus_type *lp); -static void DevicePresent(u_long iobase); -static int de4x5_bad_srom(struct bus_type *lp); -static short srom_rd(u_long address, u_char offset); -static void srom_latch(u_int command, u_long address); -static void srom_command(u_int command, u_long address); -static void srom_address(u_int command, u_long address, u_char offset); -static short srom_data(u_int command, u_long address); -/*static void srom_busy(u_int command, u_long address); */ -static void sendto_srom(u_int command, u_long addr); -static int getfrom_srom(u_long addr); -static int srom_map_media(struct device *dev); -static int srom_infoleaf_info(struct device *dev); -static void srom_init(struct device *dev); -static void srom_exec(struct device *dev, u_char * p); -static int mii_rd(u_char phyreg, u_char phyaddr, u_long ioaddr); -static void mii_wr(int data, u_char phyreg, u_char phyaddr, u_long ioaddr); -static int mii_rdata(u_long ioaddr); -static void mii_wdata(int data, int len, u_long ioaddr); -static void mii_ta(u_long rw, u_long ioaddr); -static int mii_swap(int data, int len); -static void mii_address(u_char addr, u_long ioaddr); -static void sendto_mii(u32 command, int data, u_long ioaddr); -static int getfrom_mii(u32 command, u_long ioaddr); -static int mii_get_oui(u_char phyaddr, u_long ioaddr); -static int mii_get_phy(struct device *dev); -static void SetMulticastFilter(struct device *dev); -static int get_hw_addr(struct device *dev); -static void srom_repair(struct device *dev, int card); -static int test_bad_enet(struct device *dev, int status); - +static void de4x5_free_rx_buffs(struct device *dev); +static void de4x5_free_tx_buffs(struct device *dev); +static void de4x5_save_skbs(struct device *dev); +static void de4x5_rst_desc_ring(struct device *dev); +static void de4x5_cache_state(struct device *dev, int flag); +static void de4x5_put_cache(struct device *dev, struct sk_buff *skb); +static void de4x5_putb_cache(struct device *dev, struct sk_buff *skb); +static struct sk_buff *de4x5_get_cache(struct device *dev); +static void de4x5_setup_intr(struct device *dev); +static void de4x5_init_connection(struct device *dev); +static int de4x5_reset_phy(struct device *dev); +static void reset_init_sia(struct device *dev, s32 sicr, s32 strr, s32 sigr); +static int test_ans(struct device *dev, s32 irqs, s32 irq_mask, s32 msec); +static int test_tp(struct device *dev, s32 msec); +static int EISA_signature(char *name, s32 eisa_id); +static int PCI_signature(char *name, struct bus_type *lp); +static void DevicePresent(u_long iobase); +static int de4x5_bad_srom(struct bus_type *lp); +static short srom_rd(u_long address, u_char offset); +static void srom_latch(u_int command, u_long address); +static void srom_command(u_int command, u_long address); +static void srom_address(u_int command, u_long address, u_char offset); +static short srom_data(u_int command, u_long address); +/*static void srom_busy(u_int command, u_long address);*/ +static void sendto_srom(u_int command, u_long addr); +static int getfrom_srom(u_long addr); +static int srom_map_media(struct device *dev); +static int srom_infoleaf_info(struct device *dev); +static void srom_init(struct device *dev); +static void srom_exec(struct device *dev, u_char *p); +static int mii_rd(u_char phyreg, u_char phyaddr, u_long ioaddr); +static void mii_wr(int data, u_char phyreg, u_char phyaddr, u_long ioaddr); +static int mii_rdata(u_long ioaddr); +static void mii_wdata(int data, int len, u_long ioaddr); +static void mii_ta(u_long rw, u_long ioaddr); +static int mii_swap(int data, int len); +static void mii_address(u_char addr, u_long ioaddr); +static void sendto_mii(u32 command, int data, u_long ioaddr); +static int getfrom_mii(u32 command, u_long ioaddr); +static int mii_get_oui(u_char phyaddr, u_long ioaddr); +static int mii_get_phy(struct device *dev); +static void SetMulticastFilter(struct device *dev); +static int get_hw_addr(struct device *dev); +static void srom_repair(struct device *dev, int card); +static int test_bad_enet(struct device *dev, int status); #ifndef __sparc_v9__ -static void eisa_probe(struct device *dev, u_long iobase); +static void eisa_probe(struct device *dev, u_long iobase); #endif -static void pci_probe(struct device *dev, u_long iobase); -static void srom_search(int index); -static char *build_setup_frame(struct device *dev, int mode); -static void disable_ast(struct device *dev); -static void enable_ast(struct device *dev, u32 time_out); -static long de4x5_switch_mac_port(struct device *dev); -static int gep_rd(struct device *dev); -static void gep_wr(s32 data, struct device *dev); -static void timeout(struct device *dev, void (*fn) (u_long data), u_long data, u_long msec); -static void yawn(struct device *dev, int state); -static void link_modules(struct device *dev, struct device *tmp); -static void de4x5_dbg_open(struct device *dev); -static void de4x5_dbg_mii(struct device *dev, int k); -static void de4x5_dbg_media(struct device *dev); -static void de4x5_dbg_srom(struct de4x5_srom *p); -static void de4x5_dbg_rx(struct sk_buff *skb, int len); -static int de4x5_strncmp(char *a, char *b, int n); -static int dc21041_infoleaf(struct device *dev); -static int dc21140_infoleaf(struct device *dev); -static int dc21142_infoleaf(struct device *dev); -static int dc21143_infoleaf(struct device *dev); -static int type0_infoblock(struct device *dev, u_char count, u_char * p); -static int type1_infoblock(struct device *dev, u_char count, u_char * p); -static int type2_infoblock(struct device *dev, u_char count, u_char * p); -static int type3_infoblock(struct device *dev, u_char count, u_char * p); -static int type4_infoblock(struct device *dev, u_char count, u_char * p); -static int type5_infoblock(struct device *dev, u_char count, u_char * p); -static int compact_infoblock(struct device *dev, u_char count, u_char * p); +static void pci_probe(struct device *dev, u_long iobase); +static void srom_search(int index); +static char *build_setup_frame(struct device *dev, int mode); +static void disable_ast(struct device *dev); +static void enable_ast(struct device *dev, u32 time_out); +static long de4x5_switch_mac_port(struct device *dev); +static int gep_rd(struct device *dev); +static void gep_wr(s32 data, struct device *dev); +static void timeout(struct device *dev, void (*fn)(u_long data), u_long data, u_long msec); +static void yawn(struct device *dev, int state); +static void link_modules(struct device *dev, struct device *tmp); +static void de4x5_parse_params(struct device *dev); +static void de4x5_dbg_open(struct device *dev); +static void de4x5_dbg_mii(struct device *dev, int k); +static void de4x5_dbg_media(struct device *dev); +static void de4x5_dbg_srom(struct de4x5_srom *p); +static void de4x5_dbg_rx(struct sk_buff *skb, int len); +static int de4x5_strncmp(char *a, char *b, int n); +static int dc21041_infoleaf(struct device *dev); +static int dc21140_infoleaf(struct device *dev); +static int dc21142_infoleaf(struct device *dev); +static int dc21143_infoleaf(struct device *dev); +static int type0_infoblock(struct device *dev, u_char count, u_char *p); +static int type1_infoblock(struct device *dev, u_char count, u_char *p); +static int type2_infoblock(struct device *dev, u_char count, u_char *p); +static int type3_infoblock(struct device *dev, u_char count, u_char *p); +static int type4_infoblock(struct device *dev, u_char count, u_char *p); +static int type5_infoblock(struct device *dev, u_char count, u_char *p); +static int compact_infoblock(struct device *dev, u_char count, u_char *p); #ifdef MODULE -int init_module(void); +int init_module(void); void cleanup_module(void); -static struct device *unlink_modules(struct device *p); +static struct device *unlink_modules(struct device *p); static struct device *insert_device(struct device *dev, u_long iobase, int (*init)(struct device *)); static int count_adapters(void); static int loading_module = 1; #if LINUX_VERSION_CODE >= LinuxVersionCode(2,1,0) MODULE_PARM(de4x5_debug, "i"); -MODULE_PARM(de4x5_full_duplex, "i"); MODULE_PARM(dec_only, "i"); +MODULE_PARM(args, "s"); #endif /* LINUX_VERSION_CODE */ -#else +# else static int loading_module = 0; -#endif /* MODULE */ +#endif /* MODULE */ static char name[DE4X5_NAME_LENGTH + 1]; #ifndef __sparc_v9__ @@ -949,29 +996,28 @@ ** List the SROM infoleaf functions and chipsets */ struct InfoLeaf { - int chipset; - int (*fn) (struct device *); + int chipset; + int (*fn)(struct device *); }; -static struct InfoLeaf infoleaf_array[] = -{ - {DC21041, dc21041_infoleaf}, - {DC21140, dc21140_infoleaf}, - {DC21142, dc21142_infoleaf}, - {DC21143, dc21143_infoleaf} +static struct InfoLeaf infoleaf_array[] = { + {DC21041, dc21041_infoleaf}, + {DC21140, dc21140_infoleaf}, + {DC21142, dc21142_infoleaf}, + {DC21143, dc21143_infoleaf} }; #define INFOLEAF_SIZE (sizeof(infoleaf_array)/(sizeof(int)+sizeof(int *))) /* ** List the SROM info block functions */ -static int (*dc_infoblock[]) (struct device * dev, u_char, u_char *) = { - type0_infoblock, - type1_infoblock, - type2_infoblock, - type3_infoblock, - type4_infoblock, - type5_infoblock, - compact_infoblock +static int (*dc_infoblock[])(struct device *dev, u_char, u_char *) = { + type0_infoblock, + type1_infoblock, + type2_infoblock, + type3_infoblock, + type4_infoblock, + type5_infoblock, + compact_infoblock }; #define COMPACT (sizeof(dc_infoblock)/sizeof(int *) - 1) @@ -997,300 +1043,316 @@ outl(0x00, DE4X5_GEP);\ udelay(2000); /* Wait for 2ms */\ } - + /* ** Autoprobing in modules is allowed here. See the top of the file for ** more info. */ -__initfunc(int de4x5_probe(struct device *dev)) +__initfunc(int +de4x5_probe(struct device *dev)) { - u_long iobase = dev->base_addr; + u_long iobase = dev->base_addr; #ifndef __sparc_v9__ - eisa_probe(dev, iobase); + eisa_probe(dev, iobase); #endif - pci_probe(dev, iobase); - - return (dev->priv ? 0 : -ENODEV); + pci_probe(dev, iobase); + + return (dev->priv ? 0 : -ENODEV); } __initfunc(static int - de4x5_hw_init(struct device *dev, u_long iobase)) +de4x5_hw_init(struct device *dev, u_long iobase)) { - struct bus_type *lp = &bus; - int i, status = 0; - char *tmp; - - /* Ensure we're not sleeping */ - if (lp->bus == EISA) { - outb(WAKEUP, PCI_CFPM); - } else { - pcibios_write_config_byte(lp->bus_num, lp->device << 3, - PCI_CFDA_PSM, WAKEUP); - } - de4x5_ms_delay(10); - - RESET_DE4X5; + struct bus_type *lp = &bus; + int i, status=0; + char *tmp; + + /* Ensure we're not sleeping */ + if (lp->bus == EISA) { + outb(WAKEUP, PCI_CFPM); + } else { + pcibios_write_config_byte(lp->bus_num, lp->device << 3, + PCI_CFDA_PSM, WAKEUP); + } + de4x5_ms_delay(10); - if ((inl(DE4X5_STS) & (STS_TS | STS_RS)) != 0) { - return -ENXIO; /* Hardware could not reset */ - } + RESET_DE4X5; + + if ((inl(DE4X5_STS) & (STS_TS | STS_RS)) != 0) { + return -ENXIO; /* Hardware could not reset */ + } + + /* + ** Now find out what kind of DC21040/DC21041/DC21140 board we have. + */ + useSROM = FALSE; + if (lp->bus == PCI) { + PCI_signature(name, lp); + } else { + EISA_signature(name, EISA_ID0); + } + + if (*name == '\0') { /* Not found a board signature */ + return -ENXIO; + } + + dev->base_addr = iobase; + if (lp->bus == EISA) { + printk("%s: %s at 0x%04lx (EISA slot %ld)", + dev->name, name, iobase, ((iobase>>12)&0x0f)); + } else { /* PCI port address */ + printk("%s: %s at 0x%04lx (PCI bus %d, device %d)", dev->name, name, + iobase, lp->bus_num, lp->device); + } + + printk(", h/w address "); + status = get_hw_addr(dev); + for (i = 0; i < ETH_ALEN - 1; i++) { /* get the ethernet addr. */ + printk("%2.2x:", dev->dev_addr[i]); + } + printk("%2.2x,\n", dev->dev_addr[i]); + + if (status != 0) { + printk(" which has an Ethernet PROM CRC error.\n"); + return -ENXIO; + } else { + struct de4x5_private *lp; + /* - ** Now find out what kind of DC21040/DC21041/DC21140 board we have. + ** Reserve a section of kernel memory for the adapter + ** private area and the TX/RX descriptor rings. */ - useSROM = FALSE; - if (lp->bus == PCI) { - PCI_signature(name, lp); - } else { - EISA_signature(name, EISA_ID0); - } - - if (*name == '\0') { /* Not found a board signature */ - return -ENXIO; - } - dev->base_addr = iobase; - if (lp->bus == EISA) { - printk("%s: %s at 0x%04lx (EISA slot %ld)", - dev->name, name, iobase, ((iobase >> 12) & 0x0f)); - } else { /* PCI port address */ - printk("%s: %s at 0x%04lx (PCI bus %d, device %d)", dev->name, name, - iobase, lp->bus_num, lp->device); - } - - printk(", h/w address "); - status = get_hw_addr(dev); - for (i = 0; i < ETH_ALEN - 1; i++) { /* get the ethernet addr. */ - printk("%2.2x:", dev->dev_addr[i]); + dev->priv = (void *) kmalloc(sizeof(struct de4x5_private) + ALIGN, + GFP_KERNEL); + if (dev->priv == NULL) { + return -ENOMEM; } - printk("%2.2x,\n", dev->dev_addr[i]); + + /* + ** Align to a longword boundary + */ + tmp = dev->priv; + dev->priv = (void *)(((u_long)dev->priv + ALIGN) & ~ALIGN); + lp = (struct de4x5_private *)dev->priv; + memset(dev->priv, 0, sizeof(struct de4x5_private)); + lp->bus = bus.bus; + lp->bus_num = bus.bus_num; + lp->device = bus.device; + lp->chipset = bus.chipset; + lp->cache.priv = tmp; + lp->cache.gepc = GEP_INIT; + lp->asBit = GEP_SLNK; + lp->asPolarity = GEP_SLNK; + lp->asBitValid = TRUE; + lp->timeout = -1; + lp->useSROM = useSROM; + memcpy((char *)&lp->srom,(char *)&bus.srom,sizeof(struct de4x5_srom)); + de4x5_parse_params(dev); - if (status != 0) { - printk(" which has an Ethernet PROM CRC error.\n"); - return -ENXIO; + /* + ** Choose correct autosensing in case someone messed up + */ + if ((lp->params.autosense & AUTO) || lp->useSROM) { + lp->autosense = AUTO; } else { - struct de4x5_private *lp; - - /* - ** Reserve a section of kernel memory for the adapter - ** private area and the TX/RX descriptor rings. - */ - dev->priv = (void *) kmalloc(sizeof(struct de4x5_private) + ALIGN, - GFP_KERNEL); - if (dev->priv == NULL) { - return -ENOMEM; - } - /* - ** Align to a longword boundary - */ - tmp = dev->priv; - dev->priv = (void *) (((u_long) dev->priv + ALIGN) & ~ALIGN); - lp = (struct de4x5_private *) dev->priv; - memset(dev->priv, 0, sizeof(struct de4x5_private)); - lp->bus = bus.bus; - lp->bus_num = bus.bus_num; - lp->device = bus.device; - lp->chipset = bus.chipset; - lp->cache.priv = tmp; - lp->cache.gepc = GEP_INIT; - lp->asBit = GEP_SLNK; - lp->asPolarity = GEP_SLNK; - lp->asBitValid = TRUE; - lp->timeout = -1; - lp->useSROM = useSROM; - memcpy((char *) &lp->srom, (char *) &bus.srom, sizeof(struct de4x5_srom)); - - /* - ** Choose correct autosensing in case someone messed up - */ - if ((de4x5_autosense & AUTO) || lp->useSROM) { - lp->autosense = AUTO; - } else { - if (lp->chipset != DC21140) { - if ((lp->chipset == DC21040) && (de4x5_autosense & TP_NW)) { - de4x5_autosense = TP; - } - if ((lp->chipset == DC21041) && (de4x5_autosense & BNC_AUI)) { - de4x5_autosense = BNC; - } - lp->autosense = de4x5_autosense & 0x001f; - } else { - lp->autosense = de4x5_autosense & 0x00c0; - } - } - lp->fdx = de4x5_full_duplex; - sprintf(lp->adapter_name, "%s (%s)", name, dev->name); - - /* - ** Set up the RX descriptor ring (Intels) - ** Allocate contiguous receive buffers, long word aligned (Alphas) - */ + if (lp->chipset != DC21140) { + if ((lp->chipset==DC21040) && (lp->params.autosense&TP_NW)) { + lp->params.autosense = TP; + } + if ((lp->chipset==DC21041) && (lp->params.autosense&BNC_AUI)) { + lp->params.autosense = BNC; + } + lp->autosense = lp->params.autosense & 0x001f; + } else { + lp->autosense = lp->params.autosense & 0x00c0; + } + } + lp->fdx = lp->params.fdx; + sprintf(lp->adapter_name,"%s (%s)", name, dev->name); + + /* + ** Set up the RX descriptor ring (Intels) + ** Allocate contiguous receive buffers, long word aligned (Alphas) + */ #if !defined(__alpha__) && !defined(__powerpc__) && !defined(__sparc_v9__) && !defined(DE4X5_DO_MEMCPY) - for (i = 0; i < NUM_RX_DESC; i++) { - lp->rx_ring[i].status = 0; - lp->rx_ring[i].des1 = RX_BUFF_SZ; - lp->rx_ring[i].buf = 0; - lp->rx_ring[i].next = 0; - lp->rx_skb[i] = (struct sk_buff *) 1; /* Dummy entry */ - } + for (i=0; irx_ring[i].status = 0; + lp->rx_ring[i].des1 = RX_BUFF_SZ; + lp->rx_ring[i].buf = 0; + lp->rx_ring[i].next = 0; + lp->rx_skb[i] = (struct sk_buff *) 1; /* Dummy entry */ + } #else - if ((tmp = (void *) kmalloc(RX_BUFF_SZ * NUM_RX_DESC + ALIGN, - GFP_KERNEL)) == NULL) { - kfree(lp->cache.priv); - return -ENOMEM; - } - lp->cache.buf = tmp; - tmp = (char *) (((u_long) tmp + ALIGN) & ~ALIGN); - for (i = 0; i < NUM_RX_DESC; i++) { - lp->rx_ring[i].status = 0; - lp->rx_ring[i].des1 = cpu_to_le32(RX_BUFF_SZ); - lp->rx_ring[i].buf = cpu_to_le32(virt_to_bus(tmp + i * RX_BUFF_SZ)); - lp->rx_ring[i].next = 0; - lp->rx_skb[i] = (struct sk_buff *) 1; /* Dummy entry */ - } -#endif - - barrier(); - - request_region(iobase, (lp->bus == PCI ? DE4X5_PCI_TOTAL_SIZE : - DE4X5_EISA_TOTAL_SIZE), - lp->adapter_name); - - lp->rxRingSize = NUM_RX_DESC; - lp->txRingSize = NUM_TX_DESC; - - /* Write the end of list marker to the descriptor lists */ - lp->rx_ring[lp->rxRingSize - 1].des1 |= cpu_to_le32(RD_RER); - lp->tx_ring[lp->txRingSize - 1].des1 |= cpu_to_le32(TD_TER); - - /* Tell the adapter where the TX/RX rings are located. */ - outl(virt_to_bus(lp->rx_ring), DE4X5_RRBA); - outl(virt_to_bus(lp->tx_ring), DE4X5_TRBA); - - /* Initialise the IRQ mask and Enable/Disable */ - lp->irq_mask = IMR_RIM | IMR_TIM | IMR_TUM | IMR_UNM; - lp->irq_en = IMR_NIM | IMR_AIM; - - /* Create a loopback packet frame for later media probing */ - create_packet(dev, lp->frame, sizeof(lp->frame)); - - /* Check if the RX overflow bug needs testing for */ - i = cfrv & 0x000000fe; - if ((lp->chipset == DC21140) && (i == 0x20)) { - lp->rx_ovf = 1; - } - /* Initialise the SROM pointers if possible */ - if (lp->useSROM) { - lp->state = INITIALISED; - if (srom_infoleaf_info(dev)) { - return -ENXIO; - } - srom_init(dev); - } - lp->state = CLOSED; - - /* - ** Check for an MII interface - */ - if ((lp->chipset != DC21040) && (lp->chipset != DC21041)) { - mii_get_phy(dev); - } - printk(" and requires IRQ %x (provided by %s).\n", dev->irq, - ((lp->bus == PCI) ? "PCI BIOS" : "EISA CNFG")); + if ((tmp = (void *)kmalloc(RX_BUFF_SZ * NUM_RX_DESC + ALIGN, + GFP_KERNEL)) == NULL) { + kfree(lp->cache.priv); + return -ENOMEM; } - if (de4x5_debug & DEBUG_VERSION) { - printk(version); + lp->cache.buf = tmp; + tmp = (char *)(((u_long) tmp + ALIGN) & ~ALIGN); + for (i=0; irx_ring[i].status = 0; + lp->rx_ring[i].des1 = cpu_to_le32(RX_BUFF_SZ); + lp->rx_ring[i].buf = cpu_to_le32(virt_to_bus(tmp+i*RX_BUFF_SZ)); + lp->rx_ring[i].next = 0; + lp->rx_skb[i] = (struct sk_buff *) 1; /* Dummy entry */ } - /* The DE4X5-specific entries in the device structure. */ - dev->open = &de4x5_open; - dev->hard_start_xmit = &de4x5_queue_pkt; - dev->stop = &de4x5_close; - dev->get_stats = &de4x5_get_stats; - dev->set_multicast_list = &set_multicast_list; - dev->do_ioctl = &de4x5_ioctl; - - dev->mem_start = 0; - - /* Fill in the generic fields of the device structure. */ - ether_setup(dev); +#endif - /* Let the adapter sleep to save power */ - yawn(dev, SLEEP); + barrier(); + + request_region(iobase, (lp->bus == PCI ? DE4X5_PCI_TOTAL_SIZE : + DE4X5_EISA_TOTAL_SIZE), + lp->adapter_name); + + lp->rxRingSize = NUM_RX_DESC; + lp->txRingSize = NUM_TX_DESC; + + /* Write the end of list marker to the descriptor lists */ + lp->rx_ring[lp->rxRingSize - 1].des1 |= cpu_to_le32(RD_RER); + lp->tx_ring[lp->txRingSize - 1].des1 |= cpu_to_le32(TD_TER); + + /* Tell the adapter where the TX/RX rings are located. */ + outl(virt_to_bus(lp->rx_ring), DE4X5_RRBA); + outl(virt_to_bus(lp->tx_ring), DE4X5_TRBA); + + /* Initialise the IRQ mask and Enable/Disable */ + lp->irq_mask = IMR_RIM | IMR_TIM | IMR_TUM | IMR_UNM; + lp->irq_en = IMR_NIM | IMR_AIM; - return status; -} - + /* Create a loopback packet frame for later media probing */ + create_packet(dev, lp->frame, sizeof(lp->frame)); -static int de4x5_open(struct device *dev) -{ - struct de4x5_private *lp = (struct de4x5_private *) dev->priv; - u_long iobase = dev->base_addr; - int i, status = 0; - s32 omr; + /* Check if the RX overflow bug needs testing for */ + i = cfrv & 0x000000fe; + if ((lp->chipset == DC21140) && (i == 0x20)) { + lp->rx_ovf = 1; + } - /* Allocate the RX buffers */ - for (i = 0; i < lp->rxRingSize; i++) { - if (de4x5_alloc_rx_buff(dev, i, 0) == NULL) { - de4x5_free_rx_buffs(dev); - return -EAGAIN; - } + /* Initialise the SROM pointers if possible */ + if (lp->useSROM) { + lp->state = INITIALISED; + if (srom_infoleaf_info(dev)) { + return -ENXIO; + } + srom_init(dev); } - /* - ** Wake up the adapter - */ - yawn(dev, WAKEUP); + lp->state = CLOSED; - /* - ** Re-initialize the DE4X5... + /* + ** Check for an MII interface */ - status = de4x5_init(dev); - - lp->state = OPEN; - de4x5_dbg_open(dev); - - if (request_irq(dev->irq, (void *) de4x5_interrupt, SA_SHIRQ, - lp->adapter_name, dev)) { - printk("de4x5_open(): Requested IRQ%d is busy - attemping FAST/SHARE...", dev->irq); - if (request_irq(dev->irq, de4x5_interrupt, SA_INTERRUPT | SA_SHIRQ, - lp->adapter_name, dev)) { - printk("\n Cannot get IRQ- reconfigure your hardware.\n"); - disable_ast(dev); - de4x5_free_rx_buffs(dev); - de4x5_free_tx_buffs(dev); - yawn(dev, SLEEP); - lp->state = CLOSED; - return -EAGAIN; - } else { - printk("\n Succeeded, but you should reconfigure your hardware to avoid this.\n"); - printk("WARNING: there may be IRQ related problems in heavily loaded systems.\n"); - } + if ((lp->chipset != DC21040) && (lp->chipset != DC21041)) { + mii_get_phy(dev); } + +#ifndef __sparc_v9__ + printk(" and requires IRQ%d (provided by %s).\n", dev->irq, +#else + printk(" and requires IRQ%x (provided by %s).\n", dev->irq, +#endif + ((lp->bus == PCI) ? "PCI BIOS" : "EISA CNFG")); + } + + if (de4x5_debug & DEBUG_VERSION) { + printk(version); + } + + /* The DE4X5-specific entries in the device structure. */ + dev->open = &de4x5_open; + dev->hard_start_xmit = &de4x5_queue_pkt; + dev->stop = &de4x5_close; + dev->get_stats = &de4x5_get_stats; + dev->set_multicast_list = &set_multicast_list; + dev->do_ioctl = &de4x5_ioctl; + + dev->mem_start = 0; + + /* Fill in the generic fields of the device structure. */ + ether_setup(dev); + + /* Let the adapter sleep to save power */ + yawn(dev, SLEEP); + + return status; +} - dev->tbusy = 0; - dev->start = 1; - dev->interrupt = UNMASK_INTERRUPTS; - dev->trans_start = jiffies; - - START_DE4X5; - - de4x5_setup_intr(dev); - - if (de4x5_debug & DEBUG_OPEN) { - printk("\tsts: 0x%08x\n", inl(DE4X5_STS)); - printk("\tbmr: 0x%08x\n", inl(DE4X5_BMR)); - printk("\timr: 0x%08x\n", inl(DE4X5_IMR)); - printk("\tomr: 0x%08x\n", inl(DE4X5_OMR)); - printk("\tsisr: 0x%08x\n", inl(DE4X5_SISR)); - printk("\tsicr: 0x%08x\n", inl(DE4X5_SICR)); - printk("\tstrr: 0x%08x\n", inl(DE4X5_STRR)); - printk("\tsigr: 0x%08x\n", inl(DE4X5_SIGR)); + +static int +de4x5_open(struct device *dev) +{ + struct de4x5_private *lp = (struct de4x5_private *)dev->priv; + u_long iobase = dev->base_addr; + int i, status = 0; + s32 omr; + + /* Allocate the RX buffers */ + for (i=0; irxRingSize; i++) { + if (de4x5_alloc_rx_buff(dev, i, 0) == NULL) { + de4x5_free_rx_buffs(dev); + return -EAGAIN; + } + } + + /* + ** Wake up the adapter + */ + yawn(dev, WAKEUP); + + /* + ** Re-initialize the DE4X5... + */ + status = de4x5_init(dev); + + lp->state = OPEN; + de4x5_dbg_open(dev); + + if (request_irq(dev->irq, (void *)de4x5_interrupt, SA_SHIRQ, + lp->adapter_name, dev)) { + printk("de4x5_open(): Requested IRQ%d is busy - attemping FAST/SHARE...", dev->irq); + if (request_irq(dev->irq, de4x5_interrupt, SA_INTERRUPT | SA_SHIRQ, + lp->adapter_name, dev)) { + printk("\n Cannot get IRQ- reconfigure your hardware.\n"); + disable_ast(dev); + de4x5_free_rx_buffs(dev); + de4x5_free_tx_buffs(dev); + yawn(dev, SLEEP); + lp->state = CLOSED; + return -EAGAIN; + } else { + printk("\n Succeeded, but you should reconfigure your hardware to avoid this.\n"); + printk("WARNING: there may be IRQ related problems in heavily loaded systems.\n"); } - MOD_INC_USE_COUNT; + } - return status; + dev->tbusy = 0; + dev->start = 1; + dev->interrupt = UNMASK_INTERRUPTS; + dev->trans_start = jiffies; + + START_DE4X5; + + de4x5_setup_intr(dev); + + if (de4x5_debug & DEBUG_OPEN) { + printk("\tsts: 0x%08x\n", inl(DE4X5_STS)); + printk("\tbmr: 0x%08x\n", inl(DE4X5_BMR)); + printk("\timr: 0x%08x\n", inl(DE4X5_IMR)); + printk("\tomr: 0x%08x\n", inl(DE4X5_OMR)); + printk("\tsisr: 0x%08x\n", inl(DE4X5_SISR)); + printk("\tsicr: 0x%08x\n", inl(DE4X5_SICR)); + printk("\tstrr: 0x%08x\n", inl(DE4X5_STRR)); + printk("\tsigr: 0x%08x\n", inl(DE4X5_SIGR)); + } + + MOD_INC_USE_COUNT; + + return status; } /* @@ -1301,157 +1363,163 @@ ** to be data corruption problems if it is larger (UDP errors seen from a ** ttcp source). */ -static int de4x5_init(struct device *dev) -{ - /* Lock out other processes whilst setting up the hardware */ - test_and_set_bit(0, (void *)&dev->tbusy); - - de4x5_sw_reset(dev); - - /* Autoconfigure the connected port */ - autoconf_media(dev); - - return 0; +static int +de4x5_init(struct device *dev) +{ + /* Lock out other processes whilst setting up the hardware */ + test_and_set_bit(0, (void *)&dev->tbusy); + + de4x5_sw_reset(dev); + + /* Autoconfigure the connected port */ + autoconf_media(dev); + + return 0; } -static int de4x5_sw_reset(struct device *dev) +static int +de4x5_sw_reset(struct device *dev) { - struct de4x5_private *lp = (struct de4x5_private *) dev->priv; - u_long iobase = dev->base_addr; - int i, j, status = 0; - s32 bmr, omr; - - /* Select the MII or SRL port now and RESET the MAC */ - if (!lp->useSROM) { - if (lp->phy[lp->active].id != 0) { - lp->infoblock_csr6 = OMR_PS | OMR_HBD; - } else { - lp->infoblock_csr6 = OMR_TTM; - } - de4x5_switch_mac_port(dev); - } - /* - ** Set the programmable burst length to 8 longwords for all the DC21140 - ** Fasternet chips and 4 longwords for all others: DMA errors result - ** without these values. Cache align 16 long. - */ - bmr = (lp->chipset == DC21140 ? PBL_8 : PBL_4) | DESC_SKIP_LEN | CACHE_ALIGN; - bmr |= ((lp->chipset & ~0x00ff)==DC2114x ? BMR_RML : 0); - outl(bmr, DE4X5_BMR); - - omr = inl(DE4X5_OMR) & ~OMR_PR; /* Turn off promiscuous mode */ - if (lp->chipset == DC21140) { - omr |= (OMR_SDP | OMR_SB); - } - lp->setup_f = PERFECT; - outl(virt_to_bus(lp->rx_ring), DE4X5_RRBA); - outl(virt_to_bus(lp->tx_ring), DE4X5_TRBA); - - lp->rx_new = lp->rx_old = 0; - lp->tx_new = lp->tx_old = 0; - - for (i = 0; i < lp->rxRingSize; i++) { - lp->rx_ring[i].status = cpu_to_le32(R_OWN); - } - - for (i = 0; i < lp->txRingSize; i++) { - lp->tx_ring[i].status = cpu_to_le32(0); + struct de4x5_private *lp = (struct de4x5_private *)dev->priv; + u_long iobase = dev->base_addr; + int i, j, status = 0; + s32 bmr, omr; + + /* Select the MII or SRL port now and RESET the MAC */ + if (!lp->useSROM) { + if (lp->phy[lp->active].id != 0) { + lp->infoblock_csr6 = OMR_SDP | OMR_PS | OMR_HBD; + } else { + lp->infoblock_csr6 = OMR_SDP | OMR_TTM; } + de4x5_switch_mac_port(dev); + } - barrier(); - - /* Build the setup frame depending on filtering mode */ - SetMulticastFilter(dev); + /* + ** Set the programmable burst length to 8 longwords for all the DC21140 + ** Fasternet chips and 4 longwords for all others: DMA errors result + ** without these values. Cache align 16 long. + */ + bmr = (lp->chipset==DC21140 ? PBL_8 : PBL_4) | DESC_SKIP_LEN | CACHE_ALIGN; + bmr |= ((lp->chipset & ~0x00ff)==DC2114x ? BMR_RML : 0); + outl(bmr, DE4X5_BMR); + + omr = inl(DE4X5_OMR) & ~OMR_PR; /* Turn off promiscuous mode */ + if (lp->chipset == DC21140) { + omr |= (OMR_SDP | OMR_SB); + } + lp->setup_f = PERFECT; + outl(virt_to_bus(lp->rx_ring), DE4X5_RRBA); + outl(virt_to_bus(lp->tx_ring), DE4X5_TRBA); + + lp->rx_new = lp->rx_old = 0; + lp->tx_new = lp->tx_old = 0; + + for (i = 0; i < lp->rxRingSize; i++) { + lp->rx_ring[i].status = cpu_to_le32(R_OWN); + } + + for (i = 0; i < lp->txRingSize; i++) { + lp->tx_ring[i].status = cpu_to_le32(0); + } + + barrier(); - load_packet(dev, lp->setup_frame, PERFECT_F | TD_SET | SETUP_FRAME_LEN, NULL); - outl(omr | OMR_ST, DE4X5_OMR); + /* Build the setup frame depending on filtering mode */ + SetMulticastFilter(dev); + + load_packet(dev, lp->setup_frame, PERFECT_F|TD_SET|SETUP_FRAME_LEN, NULL); + outl(omr|OMR_ST, DE4X5_OMR); - /* Poll for setup frame completion (adapter interrupts are disabled now) */ - sti(); /* Ensure timer interrupts */ - for (j = 0, i = 0; (i < 500) && (j == 0); i++) { /* Upto 500ms delay */ - udelay(1000); - if ((s32) le32_to_cpu(lp->tx_ring[lp->tx_new].status) >= 0) - j = 1; - } - outl(omr, DE4X5_OMR); /* Stop everything! */ - - if (j == 0) { - printk("%s: Setup frame timed out, status %08x\n", dev->name, - inl(DE4X5_STS)); - status = -EIO; - } - lp->tx_new = (++lp->tx_new) % lp->txRingSize; - lp->tx_old = lp->tx_new; + /* Poll for setup frame completion (adapter interrupts are disabled now) */ + sti(); /* Ensure timer interrupts */ + for (j=0, i=0;(i<500) && (j==0);i++) { /* Upto 500ms delay */ + udelay(1000); + if ((s32)le32_to_cpu(lp->tx_ring[lp->tx_new].status) >= 0) j=1; + } + outl(omr, DE4X5_OMR); /* Stop everything! */ + + if (j == 0) { + printk("%s: Setup frame timed out, status %08x\n", dev->name, + inl(DE4X5_STS)); + status = -EIO; + } + + lp->tx_new = (++lp->tx_new) % lp->txRingSize; + lp->tx_old = lp->tx_new; - return status; + return status; } /* ** Writes a socket buffer address to the next available transmit descriptor */ -static int de4x5_queue_pkt(struct sk_buff *skb, struct device *dev) +static int +de4x5_queue_pkt(struct sk_buff *skb, struct device *dev) { - struct de4x5_private *lp = (struct de4x5_private *) dev->priv; - u_long iobase = dev->base_addr; - int status = 0; - - test_and_set_bit(0, (void*)&dev->tbusy); /* Stop send re-tries */ - if (lp->tx_enable == NO) { /* Cannot send for now */ - return -1; + struct de4x5_private *lp = (struct de4x5_private *)dev->priv; + u_long iobase = dev->base_addr; + int status = 0; + + test_and_set_bit(0, (void*)&dev->tbusy); /* Stop send re-tries */ + if (lp->tx_enable == NO) { /* Cannot send for now */ + return -1; + } + + /* + ** Clean out the TX ring asynchronously to interrupts - sometimes the + ** interrupts are lost by delayed descriptor status updates relative to + ** the irq assertion, especially with a busy PCI bus. + */ + cli(); + de4x5_tx(dev); + sti(); + + /* Test if cache is already locked - requeue skb if so */ + if (test_and_set_bit(0, (void *)&lp->cache.lock) && !dev->interrupt) + return -1; + + /* Transmit descriptor ring full or stale skb */ + if (dev->tbusy || lp->tx_skb[lp->tx_new]) { + if (dev->interrupt) { + de4x5_putb_cache(dev, skb); /* Requeue the buffer */ + } else { + de4x5_put_cache(dev, skb); } - /* - ** Clean out the TX ring asynchronously to interrupts - sometimes the - ** interrupts are lost by delayed descriptor status updates relative to - ** the irq assertion, especially with a busy PCI bus. - */ - cli(); - de4x5_tx(dev); - sti(); - - /* Test if cache is already locked - requeue skb if so */ - if (test_and_set_bit(0, (void *) &lp->cache.lock) && !dev->interrupt) - return -1; - - /* Transmit descriptor ring full or stale skb */ - if (dev->tbusy || lp->tx_skb[lp->tx_new]) { - if (dev->interrupt) { - de4x5_putb_cache(dev, skb); /* Requeue the buffer */ - } else { - de4x5_put_cache(dev, skb); - } - if (de4x5_debug & DEBUG_TX) { - printk("%s: transmit busy, lost media or stale skb found:\n STS:%08x\n tbusy:%ld\n IMR:%08x\n OMR:%08x\n Stale skb: %s\n", dev->name, inl(DE4X5_STS), dev->tbusy, inl(DE4X5_IMR), inl(DE4X5_OMR), (lp->tx_skb[lp->tx_new] ? "YES" : "NO")); - } - } else if (skb->len > 0) { - /* If we already have stuff queued locally, use that first */ - if (lp->cache.skb && !dev->interrupt) { - de4x5_put_cache(dev, skb); - skb = de4x5_get_cache(dev); - } - while (skb && !dev->tbusy && !lp->tx_skb[lp->tx_new]) { - cli(); - test_and_set_bit(0, (void*)&dev->tbusy); - load_packet(dev, skb->data, TD_IC | TD_LS | TD_FS | skb->len, skb); + if (de4x5_debug & DEBUG_TX) { + printk("%s: transmit busy, lost media or stale skb found:\n STS:%08x\n tbusy:%ld\n IMR:%08x\n OMR:%08x\n Stale skb: %s\n",dev->name, inl(DE4X5_STS), dev->tbusy, inl(DE4X5_IMR), inl(DE4X5_OMR), (lp->tx_skb[lp->tx_new] ? "YES" : "NO")); + } + } else if (skb->len > 0) { + /* If we already have stuff queued locally, use that first */ + if (lp->cache.skb && !dev->interrupt) { + de4x5_put_cache(dev, skb); + skb = de4x5_get_cache(dev); + } + + while (skb && !dev->tbusy && !lp->tx_skb[lp->tx_new]) { + cli(); + test_and_set_bit(0, (void*)&dev->tbusy); + load_packet(dev, skb->data, TD_IC | TD_LS | TD_FS | skb->len, skb); #if LINUX_VERSION_CODE >= ((2 << 16) | (1 << 8)) - lp->stats.tx_bytes += skb->len; + lp->stats.tx_bytes += skb->len; #endif - outl(POLL_DEMAND, DE4X5_TPD); /* Start the TX */ - - lp->tx_new = (++lp->tx_new) % lp->txRingSize; - dev->trans_start = jiffies; - - if (TX_BUFFS_AVAIL) { - dev->tbusy = 0; /* Another pkt may be queued */ - } - skb = de4x5_get_cache(dev); - sti(); - } - if (skb) - de4x5_putb_cache(dev, skb); + outl(POLL_DEMAND, DE4X5_TPD);/* Start the TX */ + + lp->tx_new = (++lp->tx_new) % lp->txRingSize; + dev->trans_start = jiffies; + + if (TX_BUFFS_AVAIL) { + dev->tbusy = 0; /* Another pkt may be queued */ + } + skb = de4x5_get_cache(dev); + sti(); } - lp->cache.lock = 0; + if (skb) de4x5_putb_cache(dev, skb); + } + + lp->cache.lock = 0; - return status; + return status; } /* @@ -1465,389 +1533,395 @@ ** is high and descriptor status bits cannot be set before the associated ** interrupt is asserted and this routine entered. */ -static void de4x5_interrupt(int irq, void *dev_id, struct pt_regs *regs) +static void +de4x5_interrupt(int irq, void *dev_id, struct pt_regs *regs) { - struct device *dev = (struct device *) dev_id; - struct de4x5_private *lp; - s32 imr, omr, sts, limit; - u_long iobase; - - if (dev == NULL) { - printk("de4x5_interrupt(): irq %d for unknown device.\n", irq); - return; - } - lp = (struct de4x5_private *) dev->priv; - iobase = dev->base_addr; - - if (dev->interrupt) - printk("%s: Re-entering the interrupt handler.\n", dev->name); - - DISABLE_IRQs; /* Ensure non re-entrancy */ + struct device *dev = (struct device *)dev_id; + struct de4x5_private *lp; + s32 imr, omr, sts, limit; + u_long iobase; + + if (dev == NULL) { + printk ("de4x5_interrupt(): irq %d for unknown device.\n", irq); + return; + } + lp = (struct de4x5_private *)dev->priv; + iobase = dev->base_addr; + + if (dev->interrupt) + printk("%s: Re-entering the interrupt handler.\n", dev->name); + + DISABLE_IRQs; /* Ensure non re-entrancy */ #if LINUX_VERSION_CODE >= ((2 << 16) | (1 << 8)) - synchronize_irq(); + synchronize_irq(); #endif - dev->interrupt = MASK_INTERRUPTS; - - for (limit = 0; limit < 8; limit++) { - sts = inl(DE4X5_STS); /* Read IRQ status */ - outl(sts, DE4X5_STS); /* Reset the board interrupts */ - - if (!(sts & lp->irq_mask)) - break; /* All done */ - - if (sts & (STS_RI | STS_RU)) /* Rx interrupt (packet[s] arrived) */ - de4x5_rx(dev); - - if (sts & (STS_TI | STS_TU)) /* Tx interrupt (packet sent) */ - de4x5_tx(dev); - - if (sts & STS_LNF) { /* TP Link has failed */ - lp->irq_mask &= ~IMR_LFM; - } - if (sts & STS_UNF) { /* Transmit underrun */ - de4x5_txur(dev); - } - if (sts & STS_SE) { /* Bus Error */ - STOP_DE4X5; - printk("%s: Fatal bus error occurred, sts=%#8x, device stopped.\n", - dev->name, sts); - return; - } + dev->interrupt = MASK_INTERRUPTS; + + for (limit=0; limit<8; limit++) { + sts = inl(DE4X5_STS); /* Read IRQ status */ + outl(sts, DE4X5_STS); /* Reset the board interrupts */ + + if (!(sts & lp->irq_mask)) break;/* All done */ + + if (sts & (STS_RI | STS_RU)) /* Rx interrupt (packet[s] arrived) */ + de4x5_rx(dev); + + if (sts & (STS_TI | STS_TU)) /* Tx interrupt (packet sent) */ + de4x5_tx(dev); + + if (sts & STS_LNF) { /* TP Link has failed */ + lp->irq_mask &= ~IMR_LFM; } - - /* Load the TX ring with any locally stored packets */ - if (!test_and_set_bit(0, (void *) &lp->cache.lock)) { - while (lp->cache.skb && !dev->tbusy && lp->tx_enable) { - de4x5_queue_pkt(de4x5_get_cache(dev), dev); - } - lp->cache.lock = 0; + + if (sts & STS_UNF) { /* Transmit underrun */ + de4x5_txur(dev); } - dev->interrupt = UNMASK_INTERRUPTS; - ENABLE_IRQs; + + if (sts & STS_SE) { /* Bus Error */ + STOP_DE4X5; + printk("%s: Fatal bus error occurred, sts=%#8x, device stopped.\n", + dev->name, sts); + return; + } + } + + /* Load the TX ring with any locally stored packets */ + if (!test_and_set_bit(0, (void *)&lp->cache.lock)) { + while (lp->cache.skb && !dev->tbusy && lp->tx_enable) { + de4x5_queue_pkt(de4x5_get_cache(dev), dev); + } + lp->cache.lock = 0; + } - return; + dev->interrupt = UNMASK_INTERRUPTS; + ENABLE_IRQs; + + return; } -static int de4x5_rx(struct device *dev) +static int +de4x5_rx(struct device *dev) { - struct de4x5_private *lp = (struct de4x5_private *) dev->priv; - u_long iobase = dev->base_addr; - int entry; - s32 status; - - for (entry = lp->rx_new; (s32) le32_to_cpu(lp->rx_ring[entry].status) >= 0; - entry = lp->rx_new) { - status = (s32) le32_to_cpu(lp->rx_ring[entry].status); - - if (lp->rx_ovf) { - if (inl(DE4X5_MFC) & MFC_FOCM) { - de4x5_rx_ovfc(dev); - break; - } - } - if (status & RD_FS) { /* Remember the start of frame */ - lp->rx_old = entry; - } - if (status & RD_LS) { /* Valid frame status */ - if (lp->tx_enable) - lp->linkOK++; - if (status & RD_ES) { /* There was an error. */ - lp->stats.rx_errors++; /* Update the error stats. */ - if (status & (RD_RF | RD_TL)) - lp->stats.rx_frame_errors++; - if (status & RD_CE) - lp->stats.rx_crc_errors++; - if (status & RD_OF) - lp->stats.rx_fifo_errors++; - if (status & RD_TL) - lp->stats.rx_length_errors++; - if (status & RD_RF) - lp->pktStats.rx_runt_frames++; - if (status & RD_CS) - lp->pktStats.rx_collision++; - if (status & RD_DB) - lp->pktStats.rx_dribble++; - if (status & RD_OF) - lp->pktStats.rx_overflow++; - } else { /* A valid frame received */ - struct sk_buff *skb; - short pkt_len = (short) (le32_to_cpu(lp->rx_ring[entry].status) - >> 16) - 4; - - if ((skb = de4x5_alloc_rx_buff(dev, entry, pkt_len)) == NULL) { - printk("%s: Insufficient memory; nuking packet.\n", - dev->name); - lp->stats.rx_dropped++; - } else { - de4x5_dbg_rx(skb, pkt_len); - - /* Push up the protocol stack */ - skb->protocol = eth_type_trans(skb, dev); - netif_rx(skb); + struct de4x5_private *lp = (struct de4x5_private *)dev->priv; + u_long iobase = dev->base_addr; + int entry; + s32 status; + + for (entry=lp->rx_new; (s32)le32_to_cpu(lp->rx_ring[entry].status)>=0; + entry=lp->rx_new) { + status = (s32)le32_to_cpu(lp->rx_ring[entry].status); + + if (lp->rx_ovf) { + if (inl(DE4X5_MFC) & MFC_FOCM) { + de4x5_rx_ovfc(dev); + break; + } + } - /* Update stats */ - lp->stats.rx_packets++; + if (status & RD_FS) { /* Remember the start of frame */ + lp->rx_old = entry; + } + + if (status & RD_LS) { /* Valid frame status */ + if (lp->tx_enable) lp->linkOK++; + if (status & RD_ES) { /* There was an error. */ + lp->stats.rx_errors++; /* Update the error stats. */ + if (status & (RD_RF | RD_TL)) lp->stats.rx_frame_errors++; + if (status & RD_CE) lp->stats.rx_crc_errors++; + if (status & RD_OF) lp->stats.rx_fifo_errors++; + if (status & RD_TL) lp->stats.rx_length_errors++; + if (status & RD_RF) lp->pktStats.rx_runt_frames++; + if (status & RD_CS) lp->pktStats.rx_collision++; + if (status & RD_DB) lp->pktStats.rx_dribble++; + if (status & RD_OF) lp->pktStats.rx_overflow++; + } else { /* A valid frame received */ + struct sk_buff *skb; + short pkt_len = (short)(le32_to_cpu(lp->rx_ring[entry].status) + >> 16) - 4; + + if ((skb = de4x5_alloc_rx_buff(dev, entry, pkt_len)) == NULL) { + printk("%s: Insufficient memory; nuking packet.\n", + dev->name); + lp->stats.rx_dropped++; + } else { + de4x5_dbg_rx(skb, pkt_len); + + /* Push up the protocol stack */ + skb->protocol=eth_type_trans(skb,dev); + netif_rx(skb); + + /* Update stats */ + lp->stats.rx_packets++; #if LINUX_VERSION_CODE >= ((2 << 16) | (1 << 8)) - lp->stats.rx_bytes += pkt_len; + lp->stats.rx_bytes += pkt_len; #endif - de4x5_local_stats(dev, skb->data, pkt_len); - } - } - - /* Change buffer ownership for this frame, back to the adapter */ - for (; lp->rx_old != entry; lp->rx_old = (++lp->rx_old) % lp->rxRingSize) { - lp->rx_ring[lp->rx_old].status = cpu_to_le32(R_OWN); - barrier(); - } - lp->rx_ring[entry].status = cpu_to_le32(R_OWN); - barrier(); + de4x5_local_stats(dev, skb->data, pkt_len); } - /* - ** Update entry information - */ - lp->rx_new = (++lp->rx_new) % lp->rxRingSize; + } + + /* Change buffer ownership for this frame, back to the adapter */ + for (;lp->rx_old!=entry;lp->rx_old=(++lp->rx_old)%lp->rxRingSize) { + lp->rx_ring[lp->rx_old].status = cpu_to_le32(R_OWN); + barrier(); + } + lp->rx_ring[entry].status = cpu_to_le32(R_OWN); + barrier(); } - - return 0; + + /* + ** Update entry information + */ + lp->rx_new = (++lp->rx_new) % lp->rxRingSize; + } + + return 0; } /* ** Buffer sent - check for TX buffer errors. */ -static int de4x5_tx(struct device *dev) +static int +de4x5_tx(struct device *dev) { - struct de4x5_private *lp = (struct de4x5_private *) dev->priv; - u_long iobase = dev->base_addr; - int entry; - s32 status; - - for (entry = lp->tx_old; entry != lp->tx_new; entry = lp->tx_old) { - status = (s32) le32_to_cpu(lp->tx_ring[entry].status); - if (status < 0) { /* Buffer not sent yet */ - break; - } else if (status != 0x7fffffff) { /* Not setup frame */ - if (status & TD_ES) { /* An error happened */ - lp->stats.tx_errors++; - if (status & TD_NC) - lp->stats.tx_carrier_errors++; - if (status & TD_LC) - lp->stats.tx_window_errors++; - if (status & TD_UF) - lp->stats.tx_fifo_errors++; - if (status & TD_EC) - lp->pktStats.excessive_collisions++; - if (status & TD_DE) - lp->stats.tx_aborted_errors++; - - if (TX_PKT_PENDING) { - outl(POLL_DEMAND, DE4X5_TPD); /* Restart a stalled TX */ - } - } else { /* Packet sent */ - lp->stats.tx_packets++; - if (lp->tx_enable) - lp->linkOK++; - } - /* Update the collision counter */ - lp->stats.collisions += ((status & TD_EC) ? 16 : - ((status & TD_CC) >> 3)); - - /* Free the buffer. */ - if (lp->tx_skb[entry] != NULL) { - dev_kfree_skb(lp->tx_skb[entry], FREE_WRITE); - lp->tx_skb[entry] = NULL; - } + struct de4x5_private *lp = (struct de4x5_private *)dev->priv; + u_long iobase = dev->base_addr; + int entry; + s32 status; + + for (entry = lp->tx_old; entry != lp->tx_new; entry = lp->tx_old) { + status = (s32)le32_to_cpu(lp->tx_ring[entry].status); + if (status < 0) { /* Buffer not sent yet */ + break; + } else if (status != 0x7fffffff) { /* Not setup frame */ + if (status & TD_ES) { /* An error happened */ + lp->stats.tx_errors++; + if (status & TD_NC) lp->stats.tx_carrier_errors++; + if (status & TD_LC) lp->stats.tx_window_errors++; + if (status & TD_UF) lp->stats.tx_fifo_errors++; + if (status & TD_EC) lp->pktStats.excessive_collisions++; + if (status & TD_DE) lp->stats.tx_aborted_errors++; + + if (TX_PKT_PENDING) { + outl(POLL_DEMAND, DE4X5_TPD);/* Restart a stalled TX */ } - /* Update all the pointers */ - lp->tx_old = (++lp->tx_old) % lp->txRingSize; - } - - if (TX_BUFFS_AVAIL && dev->tbusy) { /* Any resources available? */ - dev->tbusy = 0; /* Clear TX busy flag */ - if (dev->interrupt) - mark_bh(NET_BH); + } else { /* Packet sent */ + lp->stats.tx_packets++; + if (lp->tx_enable) lp->linkOK++; + } + /* Update the collision counter */ + lp->stats.collisions += ((status & TD_EC) ? 16 : + ((status & TD_CC) >> 3)); + + /* Free the buffer. */ + if (lp->tx_skb[entry] != NULL) { + dev_kfree_skb(lp->tx_skb[entry], FREE_WRITE); + lp->tx_skb[entry] = NULL; + } } - return 0; + + /* Update all the pointers */ + lp->tx_old = (++lp->tx_old) % lp->txRingSize; + } + + if (TX_BUFFS_AVAIL && dev->tbusy) { /* Any resources available? */ + dev->tbusy = 0; /* Clear TX busy flag */ + if (dev->interrupt) mark_bh(NET_BH); + } + + return 0; } -static int de4x5_ast(struct device *dev) +static int +de4x5_ast(struct device *dev) { - struct de4x5_private *lp = (struct de4x5_private *) dev->priv; - int next_tick = DE4X5_AUTOSENSE_MS; - - disable_ast(dev); - - if (lp->useSROM) { - next_tick = srom_autoconf(dev); - } else if (lp->chipset == DC21140) { - next_tick = dc21140m_autoconf(dev); - } else if (lp->chipset == DC21041) { - next_tick = dc21041_autoconf(dev); - } else if (lp->chipset == DC21040) { - next_tick = dc21040_autoconf(dev); - } - lp->linkOK = 0; - enable_ast(dev, next_tick); - - return 0; + struct de4x5_private *lp = (struct de4x5_private *)dev->priv; + int next_tick = DE4X5_AUTOSENSE_MS; + + disable_ast(dev); + + if (lp->useSROM) { + next_tick = srom_autoconf(dev); + } else if (lp->chipset == DC21140) { + next_tick = dc21140m_autoconf(dev); + } else if (lp->chipset == DC21041) { + next_tick = dc21041_autoconf(dev); + } else if (lp->chipset == DC21040) { + next_tick = dc21040_autoconf(dev); + } + lp->linkOK = 0; + enable_ast(dev, next_tick); + + return 0; } -static int de4x5_txur(struct device *dev) +static int +de4x5_txur(struct device *dev) { - struct de4x5_private *lp = (struct de4x5_private *) dev->priv; - u_long iobase = dev->base_addr; - int omr; - - omr = inl(DE4X5_OMR); - if (!(omr & OMR_SF) || (lp->chipset == DC21041) || (lp->chipset == DC21040)) { - omr &= ~(OMR_ST | OMR_SR); - outl(omr, DE4X5_OMR); - while (inl(DE4X5_STS) & STS_TS); - if ((omr & OMR_TR) < OMR_TR) { - omr += 0x4000; - } else { - omr |= OMR_SF; - } - outl(omr | OMR_ST | OMR_SR, DE4X5_OMR); + struct de4x5_private *lp = (struct de4x5_private *)dev->priv; + u_long iobase = dev->base_addr; + int omr; + + omr = inl(DE4X5_OMR); + if (!(omr & OMR_SF) || (lp->chipset==DC21041) || (lp->chipset==DC21040)) { + omr &= ~(OMR_ST|OMR_SR); + outl(omr, DE4X5_OMR); + while (inl(DE4X5_STS) & STS_TS); + if ((omr & OMR_TR) < OMR_TR) { + omr += 0x4000; + } else { + omr |= OMR_SF; } - return 0; + outl(omr | OMR_ST | OMR_SR, DE4X5_OMR); + } + + return 0; } -static int de4x5_rx_ovfc(struct device *dev) +static int +de4x5_rx_ovfc(struct device *dev) { - struct de4x5_private *lp = (struct de4x5_private *) dev->priv; - u_long iobase = dev->base_addr; - int omr; - - omr = inl(DE4X5_OMR); - outl(omr & ~OMR_SR, DE4X5_OMR); - while (inl(DE4X5_STS) & STS_RS); - - for (; (s32) le32_to_cpu(lp->rx_ring[lp->rx_new].status) >= 0;) { - lp->rx_ring[lp->rx_new].status = cpu_to_le32(R_OWN); - lp->rx_new = (++lp->rx_new % lp->rxRingSize); - } + struct de4x5_private *lp = (struct de4x5_private *)dev->priv; + u_long iobase = dev->base_addr; + int omr; - outl(omr, DE4X5_OMR); + omr = inl(DE4X5_OMR); + outl(omr & ~OMR_SR, DE4X5_OMR); + while (inl(DE4X5_STS) & STS_RS); - return 0; + for (; (s32)le32_to_cpu(lp->rx_ring[lp->rx_new].status)>=0;) { + lp->rx_ring[lp->rx_new].status = cpu_to_le32(R_OWN); + lp->rx_new = (++lp->rx_new % lp->rxRingSize); + } + + outl(omr, DE4X5_OMR); + + return 0; } -static int de4x5_close(struct device *dev) +static int +de4x5_close(struct device *dev) { - struct de4x5_private *lp = (struct de4x5_private *) dev->priv; - u_long iobase = dev->base_addr; - s32 imr, omr; - - disable_ast(dev); - dev->start = 0; - dev->tbusy = 1; - - if (de4x5_debug & DEBUG_CLOSE) { - printk("%s: Shutting down ethercard, status was %8.8x.\n", - dev->name, inl(DE4X5_STS)); - } - /* - ** We stop the DE4X5 here... mask interrupts and stop TX & RX - */ - DISABLE_IRQs; - STOP_DE4X5; - - /* Free the associated irq */ - free_irq(dev->irq, dev); - lp->state = CLOSED; - - /* Free any socket buffers */ - de4x5_free_rx_buffs(dev); - de4x5_free_tx_buffs(dev); - - MOD_DEC_USE_COUNT; - - /* Put the adapter to sleep to save power */ - yawn(dev, SLEEP); - - return 0; + struct de4x5_private *lp = (struct de4x5_private *)dev->priv; + u_long iobase = dev->base_addr; + s32 imr, omr; + + disable_ast(dev); + dev->start = 0; + dev->tbusy = 1; + + if (de4x5_debug & DEBUG_CLOSE) { + printk("%s: Shutting down ethercard, status was %8.8x.\n", + dev->name, inl(DE4X5_STS)); + } + + /* + ** We stop the DE4X5 here... mask interrupts and stop TX & RX + */ + DISABLE_IRQs; + STOP_DE4X5; + + /* Free the associated irq */ + free_irq(dev->irq, dev); + lp->state = CLOSED; + + /* Free any socket buffers */ + de4x5_free_rx_buffs(dev); + de4x5_free_tx_buffs(dev); + + MOD_DEC_USE_COUNT; + + /* Put the adapter to sleep to save power */ + yawn(dev, SLEEP); + + return 0; } static struct net_device_stats * de4x5_get_stats(struct device *dev) { - struct de4x5_private *lp = (struct de4x5_private *) dev->priv; - u_long iobase = dev->base_addr; - - lp->stats.rx_missed_errors = (int) (inl(DE4X5_MFC) & (MFC_OVFL | MFC_CNTR)); - - return &lp->stats; + struct de4x5_private *lp = (struct de4x5_private *)dev->priv; + u_long iobase = dev->base_addr; + + lp->stats.rx_missed_errors = (int)(inl(DE4X5_MFC) & (MFC_OVFL | MFC_CNTR)); + + return &lp->stats; } -static void de4x5_local_stats(struct device *dev, char *buf, int pkt_len) +static void +de4x5_local_stats(struct device *dev, char *buf, int pkt_len) { - struct de4x5_private *lp = (struct de4x5_private *) dev->priv; - int i; + struct de4x5_private *lp = (struct de4x5_private *)dev->priv; + int i; - for (i = 1; i < DE4X5_PKT_STAT_SZ - 1; i++) { - if (pkt_len < (i * DE4X5_PKT_BIN_SZ)) { - lp->pktStats.bins[i]++; - i = DE4X5_PKT_STAT_SZ; - } + for (i=1; ipktStats.bins[i]++; + i = DE4X5_PKT_STAT_SZ; } - if (buf[0] & 0x01) { /* Multicast/Broadcast */ - if ((*(s32 *) & buf[0] == -1) && (*(s16 *) & buf[4] == -1)) { - lp->pktStats.broadcast++; - } else { - lp->pktStats.multicast++; - } - } else if ((*(s32 *) & buf[0] == *(s32 *) & dev->dev_addr[0]) && - (*(s16 *) & buf[4] == *(s16 *) & dev->dev_addr[4])) { - lp->pktStats.unicast++; - } - lp->pktStats.bins[0]++; /* Duplicates stats.rx_packets */ - if (lp->pktStats.bins[0] == 0) { /* Reset counters */ - memset((char *) &lp->pktStats, 0, sizeof(lp->pktStats)); + } + if (buf[0] & 0x01) { /* Multicast/Broadcast */ + if ((*(s32 *)&buf[0] == -1) && (*(s16 *)&buf[4] == -1)) { + lp->pktStats.broadcast++; + } else { + lp->pktStats.multicast++; } - return; + } else if ((*(s32 *)&buf[0] == *(s32 *)&dev->dev_addr[0]) && + (*(s16 *)&buf[4] == *(s16 *)&dev->dev_addr[4])) { + lp->pktStats.unicast++; + } + + lp->pktStats.bins[0]++; /* Duplicates stats.rx_packets */ + if (lp->pktStats.bins[0] == 0) { /* Reset counters */ + memset((char *)&lp->pktStats, 0, sizeof(lp->pktStats)); + } + + return; } -static void load_packet(struct device *dev, char *buf, u32 flags, struct sk_buff *skb) +static void +load_packet(struct device *dev, char *buf, u32 flags, struct sk_buff *skb) { - struct de4x5_private *lp = (struct de4x5_private *) dev->priv; - - lp->tx_ring[lp->tx_new].buf = cpu_to_le32(virt_to_bus(buf)); - lp->tx_ring[lp->tx_new].des1 &= cpu_to_le32(TD_TER); - lp->tx_ring[lp->tx_new].des1 |= cpu_to_le32(flags); - lp->tx_skb[lp->tx_new] = skb; - barrier(); - lp->tx_ring[lp->tx_new].status = cpu_to_le32(T_OWN); - barrier(); - - return; + struct de4x5_private *lp = (struct de4x5_private *)dev->priv; + + lp->tx_ring[lp->tx_new].buf = cpu_to_le32(virt_to_bus(buf)); + lp->tx_ring[lp->tx_new].des1 &= cpu_to_le32(TD_TER); + lp->tx_ring[lp->tx_new].des1 |= cpu_to_le32(flags); + lp->tx_skb[lp->tx_new] = skb; + barrier(); + lp->tx_ring[lp->tx_new].status = cpu_to_le32(T_OWN); + barrier(); + + return; } /* ** Set or clear the multicast filter for this adaptor. */ -static void set_multicast_list(struct device *dev) +static void +set_multicast_list(struct device *dev) { - struct de4x5_private *lp = (struct de4x5_private *) dev->priv; - u_long iobase = dev->base_addr; + struct de4x5_private *lp = (struct de4x5_private *)dev->priv; + u_long iobase = dev->base_addr; - /* First, double check that the adapter is open */ - if (lp->state == OPEN) { - if (dev->flags & IFF_PROMISC) { /* set promiscuous mode */ - u32 omr; - omr = inl(DE4X5_OMR); - omr |= OMR_PR; - outl(omr, DE4X5_OMR); - } else { - SetMulticastFilter(dev); - load_packet(dev, lp->setup_frame, TD_IC | PERFECT_F | TD_SET | - SETUP_FRAME_LEN, NULL); - - lp->tx_new = (++lp->tx_new) % lp->txRingSize; - outl(POLL_DEMAND, DE4X5_TPD); /* Start the TX */ - dev->trans_start = jiffies; - } + /* First, double check that the adapter is open */ + if (lp->state == OPEN) { + if (dev->flags & IFF_PROMISC) { /* set promiscuous mode */ + u32 omr; + omr = inl(DE4X5_OMR); + omr |= OMR_PR; + outl(omr, DE4X5_OMR); + } else { + SetMulticastFilter(dev); + load_packet(dev, lp->setup_frame, TD_IC | PERFECT_F | TD_SET | + SETUP_FRAME_LEN, NULL); + + lp->tx_new = (++lp->tx_new) % lp->txRingSize; + outl(POLL_DEMAND, DE4X5_TPD); /* Start the TX */ + dev->trans_start = jiffies; } - return; + } + + return; } /* @@ -1855,61 +1929,61 @@ ** from a list of ethernet multicast addresses. ** Little endian crc one liner from Matt Thomas, DEC. */ -static void SetMulticastFilter(struct device *dev) +static void +SetMulticastFilter(struct device *dev) { - struct de4x5_private *lp = (struct de4x5_private *) dev->priv; - struct dev_mc_list *dmi = dev->mc_list; - u_long iobase = dev->base_addr; - int i, j, bit, byte; - u16 hashcode; - u32 omr, crc, poly = CRC_POLYNOMIAL_LE; - char *pa; - unsigned char *addrs; - - omr = inl(DE4X5_OMR); - omr &= ~(OMR_PR | OMR_PM); - pa = build_setup_frame(dev, ALL); /* Build the basic frame */ - - if ((dev->flags & IFF_ALLMULTI) || (dev->mc_count > 14)) { - omr |= OMR_PM; /* Pass all multicasts */ - } else if (lp->setup_f == HASH_PERF) { /* Hash Filtering */ - for (i = 0; i < dev->mc_count; i++) { /* for each address in the list */ - addrs = dmi->dmi_addr; - dmi = dmi->next; - if ((*addrs & 0x01) == 1) { /* multicast address? */ - crc = 0xffffffff; /* init CRC for each address */ - for (byte = 0; byte < ETH_ALEN; byte++) { /* for each address byte */ - /* process each address bit */ - for (bit = *addrs++, j = 0; j < 8; j++, bit >>= 1) { - crc = (crc >> 1) ^ (((crc ^ bit) & 0x01) ? poly : 0); - } - } - hashcode = crc & HASH_BITS; /* hashcode is 9 LSb of CRC */ - - byte = hashcode >> 3; /* bit[3-8] -> byte in filter */ - bit = 1 << (hashcode & 0x07); /* bit[0-2] -> bit in byte */ - - byte <<= 1; /* calc offset into setup frame */ - if (byte & 0x02) { - byte -= 1; - } - lp->setup_frame[byte] |= bit; - } - } - } else { /* Perfect filtering */ - for (j = 0; j < dev->mc_count; j++) { - addrs = dmi->dmi_addr; - dmi = dmi->next; - for (i = 0; i < ETH_ALEN; i++) { - *(pa + (i & 1)) = *addrs++; - if (i & 0x01) - pa += 4; - } - } + struct de4x5_private *lp = (struct de4x5_private *)dev->priv; + struct dev_mc_list *dmi=dev->mc_list; + u_long iobase = dev->base_addr; + int i, j, bit, byte; + u16 hashcode; + u32 omr, crc, poly = CRC_POLYNOMIAL_LE; + char *pa; + unsigned char *addrs; + + omr = inl(DE4X5_OMR); + omr &= ~(OMR_PR | OMR_PM); + pa = build_setup_frame(dev, ALL); /* Build the basic frame */ + + if ((dev->flags & IFF_ALLMULTI) || (dev->mc_count > 14)) { + omr |= OMR_PM; /* Pass all multicasts */ + } else if (lp->setup_f == HASH_PERF) { /* Hash Filtering */ + for (i=0;imc_count;i++) { /* for each address in the list */ + addrs=dmi->dmi_addr; + dmi=dmi->next; + if ((*addrs & 0x01) == 1) { /* multicast address? */ + crc = 0xffffffff; /* init CRC for each address */ + for (byte=0;byte>=1) { + crc = (crc >> 1) ^ (((crc ^ bit) & 0x01) ? poly : 0); + } + } + hashcode = crc & HASH_BITS; /* hashcode is 9 LSb of CRC */ + + byte = hashcode >> 3; /* bit[3-8] -> byte in filter */ + bit = 1 << (hashcode & 0x07);/* bit[0-2] -> bit in byte */ + + byte <<= 1; /* calc offset into setup frame */ + if (byte & 0x02) { + byte -= 1; + } + lp->setup_frame[byte] |= bit; + } + } + } else { /* Perfect filtering */ + for (j=0; jmc_count; j++) { + addrs=dmi->dmi_addr; + dmi=dmi->next; + for (i=0; ibus = EISA; - - if (ioaddr == 0) { /* Autoprobing */ - iobase = EISA_SLOT_INC; /* Get the first slot address */ - i = 1; - maxSlots = MAX_EISA_SLOTS; - } else { /* Probe a specific location */ - iobase = ioaddr; - i = (ioaddr >> 12); - maxSlots = i + 1; - } - - for (status = -ENODEV; (i < maxSlots) && (dev != NULL); i++, iobase += EISA_SLOT_INC) { - if (EISA_signature(name, EISA_ID)) { - cfid = (u32) inl(PCI_CFID); - cfrv = (u_short) inl(PCI_CFRV); - device = (cfid >> 8) & 0x00ffff00; - vendor = (u_short) cfid; - - /* Read the EISA Configuration Registers */ - irq = inb(EISA_REG0); - irq = de4x5_irq[(irq >> 1) & 0x03]; - - if (is_DC2114x) - device |= (cfrv & CFRV_RN); - lp->chipset = device; - - /* Write the PCI Configuration Registers */ - outl(PCI_COMMAND_IO | PCI_COMMAND_MASTER, PCI_CFCS); - outl(0x00006000, PCI_CFLT); - outl(iobase, PCI_CBIO); - - DevicePresent(DE4X5_APROM); - if (check_region(iobase, DE4X5_EISA_TOTAL_SIZE) == 0) { - dev->irq = irq; - if ((status = de4x5_hw_init(dev, iobase)) == 0) { - num_de4x5s++; - if (loading_module) link_modules(lastModule, dev); - lastEISA = i; - return; - } - } else if (ioaddr != 0) { - printk("%s: region already allocated at 0x%04lx.\n", - dev->name, iobase); - } - } + int i, maxSlots, status, device; + u_char irq; + u_short vendor; + u32 cfid; + u_long iobase; + struct bus_type *lp = &bus; + char name[DE4X5_STRLEN]; + + if (lastEISA == MAX_EISA_SLOTS) return;/* No more EISA devices to search */ + + lp->bus = EISA; + + if (ioaddr == 0) { /* Autoprobing */ + iobase = EISA_SLOT_INC; /* Get the first slot address */ + i = 1; + maxSlots = MAX_EISA_SLOTS; + } else { /* Probe a specific location */ + iobase = ioaddr; + i = (ioaddr >> 12); + maxSlots = i + 1; + } + + for (status = -ENODEV; (i> 8) & 0x00ffff00; + vendor = (u_short) cfid; + + /* Read the EISA Configuration Registers */ + irq = inb(EISA_REG0); + irq = de4x5_irq[(irq >> 1) & 0x03]; + + if (is_DC2114x) device |= (cfrv & CFRV_RN); + lp->chipset = device; + + /* Write the PCI Configuration Registers */ + outl(PCI_COMMAND_IO | PCI_COMMAND_MASTER, PCI_CFCS); + outl(0x00006000, PCI_CFLT); + outl(iobase, PCI_CBIO); + + DevicePresent(DE4X5_APROM); + if (check_region(iobase, DE4X5_EISA_TOTAL_SIZE) == 0) { + dev->irq = irq; + if ((status = de4x5_hw_init(dev, iobase)) == 0) { + num_de4x5s++; + if (loading_module) link_modules(lastModule, dev); + lastEISA = i; + return; + } + } else if (ioaddr != 0) { + printk("%s: region already allocated at 0x%04lx.\n", dev->name,iobase); + } } + } - if (ioaddr == 0) - lastEISA = i; + if (ioaddr == 0) lastEISA = i; - return; + return; } -#endif /* !(__sparc_v9__) */ +#endif /* !(__sparc_v9__) */ /* ** PCI bus I/O device probe @@ -2002,151 +2072,132 @@ #define PCI_LAST_DEV 32 __initfunc(static void - pci_probe(struct device *dev, u_long ioaddr)) +pci_probe(struct device *dev, u_long ioaddr)) { - u_char pb, pbus, dev_num, dnum, dev_fn, timer; - u_short dev_id, vendor, index, status; - u_int irq; - u_int class = DE4X5_CLASS_CODE; - u_int device; - u_long iobase; - struct bus_type *lp = &bus; - - if (lastPCI == NO_MORE_PCI) - return; - - if (!pcibios_present()) { - lastPCI = NO_MORE_PCI; - return; /* No PCI bus in this machine! */ - } - - lp->bus = PCI; - - if ((ioaddr < 0x1000) && loading_module) { - pbus = (u_short) (ioaddr >> 8); - dnum = (u_short) (ioaddr & 0xff); - } else { - pbus = 0; - dnum = 0; - } - - for (index = lastPCI+1; - (pcibios_find_class(class, index, &pb, &dev_fn) != PCIBIOS_DEVICE_NOT_FOUND); - index++) { - dev_num = PCI_SLOT(dev_fn); + u_char pb, pbus, dev_num, dnum, dev_fn, timer; + u_short dev_id, vendor, index, status; + u_int irq = 0, device, class = DE4X5_CLASS_CODE; + u_long iobase; + struct bus_type *lp = &bus; + + if (lastPCI == NO_MORE_PCI) return; + + if (!pcibios_present()) { + lastPCI = NO_MORE_PCI; + return; /* No PCI bus in this machine! */ + } + + lp->bus = PCI; + lp->bus_num = 0; - if ((!pbus && !dnum) || ((pbus == pb) && (dnum == dev_num))) { + if ((ioaddr < 0x1000) && loading_module) { + pbus = (u_short)(ioaddr >> 8); + dnum = (u_short)(ioaddr & 0xff); + } else { + pbus = 0; + dnum = 0; + } + + for (index=lastPCI+1; + (pcibios_find_class(class, index, &pb, &dev_fn)!= PCIBIOS_DEVICE_NOT_FOUND); + index++) { + dev_num = PCI_SLOT(dev_fn); + if ((!pbus && !dnum) || ((pbus == pb) && (dnum == dev_num))) { #ifdef __sparc_v9__ - struct pci_dev *pdev; - - for (pdev = pci_devices; pdev; pdev = pdev->next) - if (pdev->bus->number == pb && - pdev->devfn == dev_fn) - break; + struct pci_dev *pdev; + for (pdev = pci_devices; pdev; pdev = pdev->next) { + if ((pdev->bus->number==pb) && (pdev->devfn==dev_fn)) break; + } #endif - device = 0; - pcibios_read_config_word(pb, PCI_DEVICE, PCI_VENDOR_ID, &vendor); - pcibios_read_config_word(pb, PCI_DEVICE, PCI_DEVICE_ID, &dev_id); - device = dev_id; - device <<= 8; - if (!(is_DC21040 || is_DC21041 || is_DC21140 || is_DC2114x)) { - continue; - } + device = 0; + pcibios_read_config_word(pb, PCI_DEVICE, PCI_VENDOR_ID, &vendor); + pcibios_read_config_word(pb, PCI_DEVICE, PCI_DEVICE_ID, &dev_id); + device = dev_id; + device <<= 8; + if (!(is_DC21040 || is_DC21041 || is_DC21140 || is_DC2114x)) { + continue; + } - /* Search for an SROM on this bus */ - if (lp->bus_num != pb) { - lp->bus_num = pb; - srom_search(index); - } + /* Search for an SROM on this bus */ + if (lp->bus_num != pb) { + lp->bus_num = pb; + srom_search(index); + } - /* Get the chip configuration revision register */ - pcibios_read_config_dword(pb, PCI_DEVICE, PCI_REVISION_ID, &cfrv); + /* Get the chip configuration revision register */ + pcibios_read_config_dword(pb, PCI_DEVICE, PCI_REVISION_ID, &cfrv); - /* Set the device number information */ - lp->device = dev_num; - lp->bus_num = pb; - - /* Set the chipset information */ - if (is_DC2114x) - device |= (cfrv & CFRV_RN); - lp->chipset = device; + /* Set the device number information */ + lp->device = dev_num; + lp->bus_num = pb; + + /* Set the chipset information */ + if (is_DC2114x) device |= (cfrv & CFRV_RN); + lp->chipset = device; - /* Get the board I/O address */ -#ifdef __sparc_v9__ - iobase = pdev->base_address[0]; + /* Get the board I/O address (64 bits on sparc64) */ +#ifndef __sparc_v9__ + pcibios_read_config_dword(pb, PCI_DEVICE, PCI_BASE_ADDRESS_0, + (int *)&iobase); #else - { - unsigned int tmp; - pcibios_read_config_dword(pb, PCI_DEVICE, - PCI_BASE_ADDRESS_0, &tmp); - iobase = tmp; - } + iobase = pdev->base_address[0]; #endif - iobase &= CBIO_MASK; + iobase &= CBIO_MASK; - /* Fetch the IRQ to be used */ -#ifdef __sparc_v9__ - irq = pdev->irq; + /* Fetch the IRQ to be used */ +#ifndef __sparc_v9__ + pcibios_read_config_byte(pb, PCI_DEVICE, PCI_INTERRUPT_LINE, + (char *)&irq); #else - { - unsigned char tmp; - pcibios_read_config_byte(pb, PCI_DEVICE, - PCI_INTERRUPT_LINE, &tmp); - irq = tmp; - } - if ((irq == 0) || (irq == (u_char) 0xff)) - continue; + irq = pdev->irq; #endif - - /* Check if I/O accesses and Bus Mastering are enabled */ - pcibios_read_config_word(pb, PCI_DEVICE, PCI_COMMAND, &status); + if ((irq == 0) || (irq == 0xff) || ((int)irq == -1)) continue; + + /* Check if I/O accesses and Bus Mastering are enabled */ + pcibios_read_config_word(pb, PCI_DEVICE, PCI_COMMAND, &status); #ifdef __powerpc__ - if (!(status & PCI_COMMAND_IO)) { - status |= PCI_COMMAND_IO; - pcibios_write_config_word(pb, PCI_DEVICE, PCI_COMMAND, status); - pcibios_read_config_word(pb, PCI_DEVICE, PCI_COMMAND, &status); - } + if (!(status & PCI_COMMAND_IO)) { + status |= PCI_COMMAND_IO; + pcibios_write_config_word(pb, PCI_DEVICE, PCI_COMMAND, status); + pcibios_read_config_word(pb, PCI_DEVICE, PCI_COMMAND, &status); + } #endif /* __powerpc__ */ - if (!(status & PCI_COMMAND_IO)) - continue; - if (!(status & PCI_COMMAND_MASTER)) { - status |= PCI_COMMAND_MASTER; - pcibios_write_config_word(pb, PCI_DEVICE, PCI_COMMAND, status); - pcibios_read_config_word(pb, PCI_DEVICE, PCI_COMMAND, &status); - } - if (!(status & PCI_COMMAND_MASTER)) - continue; + if (!(status & PCI_COMMAND_IO)) continue; - /* Check the latency timer for values > 0x60 */ - pcibios_read_config_byte(pb, PCI_DEVICE, - PCI_LATENCY_TIMER, &timer); - if (timer < 0x60) { - pcibios_write_config_byte(pb, PCI_DEVICE, - PCI_LATENCY_TIMER, 0x60); - } + if (!(status & PCI_COMMAND_MASTER)) { + status |= PCI_COMMAND_MASTER; + pcibios_write_config_word(pb, PCI_DEVICE, PCI_COMMAND, status); + pcibios_read_config_word(pb, PCI_DEVICE, PCI_COMMAND, &status); + } + if (!(status & PCI_COMMAND_MASTER)) continue; - DevicePresent(DE4X5_APROM); - if (check_region(iobase, DE4X5_PCI_TOTAL_SIZE) == 0) { - dev->irq = irq; - if ((status = de4x5_hw_init(dev, iobase)) == 0) { - num_de4x5s++; - if (loading_module) { - link_modules(lastModule, dev); - lastPCI = index; - } - return; - } - } else if (ioaddr != 0) { - printk("%s: region already allocated at 0x%04x.\n", dev->name, - (u_short) iobase); - } - } + /* Check the latency timer for values > 0x60 */ + pcibios_read_config_byte(pb, PCI_DEVICE, PCI_LATENCY_TIMER, &timer); + if (timer < 0x60) { + pcibios_write_config_byte(pb, PCI_DEVICE, PCI_LATENCY_TIMER, 0x60); + } + + DevicePresent(DE4X5_APROM); + if (check_region(iobase, DE4X5_PCI_TOTAL_SIZE) == 0) { + dev->irq = irq; + if ((status = de4x5_hw_init(dev, iobase)) == 0) { + num_de4x5s++; + if (loading_module) { + link_modules(lastModule, dev); + lastPCI = index; + } + return; + } + } else if (ioaddr != 0) { + printk("%s: region already allocated at 0x%04lx.\n", dev->name, + iobase); + } } + } - if (loading_module) - lastPCI = NO_MORE_PCI; + if (loading_module) lastPCI = NO_MORE_PCI; - return; + return; } /* @@ -2156,95 +2207,106 @@ ** For single port cards this is a time waster... */ __initfunc(static void - srom_search(int index)) +srom_search(int index)) { - u_char irq, pb, dev_fn; - u_short dev_id, dev_num, vendor, status; - u_int class = DE4X5_CLASS_CODE; - u_int device, iobase; - int i, j; - struct bus_type *lp = &bus; - - for (; - (pcibios_find_class(class, index, - &pb, &dev_fn)!= PCIBIOS_DEVICE_NOT_FOUND); - index++) { - - if (lp->bus_num != pb) - return; - dev_num = PCI_SLOT(dev_fn); - device = 0; - pcibios_read_config_word(pb, PCI_DEVICE, PCI_VENDOR_ID, &vendor); - pcibios_read_config_word(pb, PCI_DEVICE, PCI_DEVICE_ID, &dev_id); - device = dev_id; - device <<= 8; - if (!(is_DC21040 || is_DC21041 || is_DC21140 || is_DC2114x)) { - continue; - } + u_char pb, dev_fn; + u_short dev_id, dev_num, vendor, status; + u_int irq = 0, device, class = DE4X5_CLASS_CODE; + u_long iobase; + int i, j; + struct bus_type *lp = &bus; + + for (; + (pcibios_find_class(class, index, &pb, &dev_fn)!= PCIBIOS_DEVICE_NOT_FOUND); + index++) { - /* Get the chip configuration revision register */ - pcibios_read_config_dword(pb, PCI_DEVICE, PCI_REVISION_ID, &cfrv); + if (lp->bus_num != pb) return; + dev_num = PCI_SLOT(dev_fn); +#ifdef __sparc_v9__ + struct pci_dev *pdev; + for (pdev = pci_devices; pdev; pdev = pdev->next) { + if ((pdev->bus->number == pb) && (pdev->devfn == dev_fn)) break; + } +#endif + device = 0; + pcibios_read_config_word(pb, PCI_DEVICE, PCI_VENDOR_ID, &vendor); + pcibios_read_config_word(pb, PCI_DEVICE, PCI_DEVICE_ID, &dev_id); + device = dev_id; + device <<= 8; + if (!(is_DC21040 || is_DC21041 || is_DC21140 || is_DC2114x)) { + continue; + } - /* Set the device number information */ - lp->device = dev_num; - lp->bus_num = pb; + /* Get the chip configuration revision register */ + pcibios_read_config_dword(pb, PCI_DEVICE, PCI_REVISION_ID, &cfrv); + + /* Set the device number information */ + lp->device = dev_num; + lp->bus_num = pb; - /* Set the chipset information */ - if (is_DC2114x) - device |= (cfrv & CFRV_RN); - lp->chipset = device; - - /* Get the board I/O address */ - pcibios_read_config_dword(pb, PCI_DEVICE, PCI_BASE_ADDRESS_0, &iobase); - iobase &= CBIO_MASK; - - /* Fetch the IRQ to be used */ - pcibios_read_config_byte(pb, PCI_DEVICE, PCI_INTERRUPT_LINE, &irq); - if ((irq == 0) || (irq == (u_char) 0xff)) - continue; - - /* Check if I/O accesses are enabled */ - pcibios_read_config_word(pb, PCI_DEVICE, PCI_COMMAND, &status); - if (!(status & PCI_COMMAND_IO)) - continue; + /* Set the chipset information */ + if (is_DC2114x) device |= (cfrv & CFRV_RN); + lp->chipset = device; - /* Search for a valid SROM attached to this DECchip */ - DevicePresent(DE4X5_APROM); - for (j=0, i=0; isrom + SROM_HWADD + i); - } - if ((j != 0) && (j != 0x5fa)) { - last.chipset = device; - last.bus = pb; - last.irq = irq; - for (i=0; isrom + SROM_HWADD + i); - } - return; - } + /* Get the board I/O address (64 bits on sparc64) */ +#ifndef __sparc_v9__ + pcibios_read_config_dword(pb, PCI_DEVICE, PCI_BASE_ADDRESS_0, + (int *)&iobase); +#else + iobase = pdev->base_address[0]; +#endif + iobase &= CBIO_MASK; + + /* Fetch the IRQ to be used */ +#ifndef __sparc_v9__ + pcibios_read_config_byte(pb, PCI_DEVICE, PCI_INTERRUPT_LINE, + (char *)&irq); +#else + irq = pdev->irq; +#endif + if ((irq == 0) || (irq == 0xff) || ((int)irq == -1)) continue; + + /* Check if I/O accesses are enabled */ + pcibios_read_config_word(pb, PCI_DEVICE, PCI_COMMAND, &status); + if (!(status & PCI_COMMAND_IO)) continue; + + /* Search for a valid SROM attached to this DECchip */ + DevicePresent(DE4X5_APROM); + for (j=0, i=0; isrom + SROM_HWADD + i); + } + if ((j != 0) && (j != 0x5fa)) { + last.chipset = device; + last.bus = pb; + last.irq = irq; + for (i=0; isrom + SROM_HWADD + i); + } + return; } + } - return; + return; } __initfunc(static void - link_modules(struct device *dev, struct device *tmp)) +link_modules(struct device *dev, struct device *tmp)) { - struct device *p = dev; + struct device *p=dev; - if (p) { - while (((struct de4x5_private *) (p->priv))->next_module) { - p = ((struct de4x5_private *) (p->priv))->next_module; - } + if (p) { + while (((struct de4x5_private *)(p->priv))->next_module) { + p = ((struct de4x5_private *)(p->priv))->next_module; + } - if (dev != tmp) { - ((struct de4x5_private *) (p->priv))->next_module = tmp; - } else { - ((struct de4x5_private *) (p->priv))->next_module = NULL; - } + if (dev != tmp) { + ((struct de4x5_private *)(p->priv))->next_module = tmp; + } else { + ((struct de4x5_private *)(p->priv))->next_module = NULL; } - return; + } + + return; } /* @@ -2254,31 +2316,33 @@ ** [TP] or no recent receive activity) to check whether the user has been ** sneaky and changed the port on us. */ -static int autoconf_media(struct device *dev) +static int +autoconf_media(struct device *dev) { - struct de4x5_private *lp = (struct de4x5_private *) dev->priv; - u_long iobase = dev->base_addr; - int next_tick = DE4X5_AUTOSENSE_MS; - - lp->linkOK = 0; - lp->c_media = AUTO; /* Bogus last media */ - disable_ast(dev); - inl(DE4X5_MFC); /* Zero the lost frames counter */ - lp->media = INIT; - lp->tcount = 0; + struct de4x5_private *lp = (struct de4x5_private *)dev->priv; + u_long iobase = dev->base_addr; + int next_tick = DE4X5_AUTOSENSE_MS; + + lp->linkOK = 0; + lp->c_media = AUTO; /* Bogus last media */ + disable_ast(dev); + inl(DE4X5_MFC); /* Zero the lost frames counter */ + lp->media = INIT; + lp->tcount = 0; + + if (lp->useSROM) { + next_tick = srom_autoconf(dev); + } else if (lp->chipset == DC21040) { + next_tick = dc21040_autoconf(dev); + } else if (lp->chipset == DC21041) { + next_tick = dc21041_autoconf(dev); + } else if (lp->chipset == DC21140) { + next_tick = dc21140m_autoconf(dev); + } - if (lp->useSROM) { - next_tick = srom_autoconf(dev); - } else if (lp->chipset == DC21040) { - next_tick = dc21040_autoconf(dev); - } else if (lp->chipset == DC21041) { - next_tick = dc21041_autoconf(dev); - } else if (lp->chipset == DC21140) { - next_tick = dc21140m_autoconf(dev); - } - enable_ast(dev, next_tick); - - return (lp->media); + enable_ast(dev, next_tick); + + return (lp->media); } /* @@ -2293,146 +2357,149 @@ ** I may have to "age out" locally queued packets so that the higher layer ** timeouts don't effectively duplicate packets on the network. */ -static int dc21040_autoconf(struct device *dev) +static int +dc21040_autoconf(struct device *dev) { - struct de4x5_private *lp = (struct de4x5_private *) dev->priv; - u_long iobase = dev->base_addr; - int next_tick = DE4X5_AUTOSENSE_MS; - s32 imr; - - switch (lp->media) { - case INIT: - DISABLE_IRQs; - lp->tx_enable = NO; - lp->timeout = -1; - de4x5_save_skbs(dev); - if ((lp->autosense == AUTO) || (lp->autosense == TP)) { - lp->media = TP; - } else if ((lp->autosense == BNC) || (lp->autosense == AUI) || (lp->autosense == BNC_AUI)) { - lp->media = BNC_AUI; - } else if (lp->autosense == EXT_SIA) { - lp->media = EXT_SIA; - } else { - lp->media = NC; - } - lp->local_state = 0; - next_tick = dc21040_autoconf(dev); - break; - - case TP: - next_tick = dc21040_state(dev, 0x8f01, 0xffff, 0x0000, 3000, BNC_AUI, - TP_SUSPECT, test_tp); - break; - - case TP_SUSPECT: - next_tick = de4x5_suspect_state(dev, 1000, TP, test_tp, dc21040_autoconf); - break; - - case BNC: - case AUI: - case BNC_AUI: - next_tick = dc21040_state(dev, 0x8f09, 0x0705, 0x0006, 3000, EXT_SIA, - BNC_AUI_SUSPECT, ping_media); - break; - - case BNC_AUI_SUSPECT: - next_tick = de4x5_suspect_state(dev, 1000, BNC_AUI, ping_media, dc21040_autoconf); - break; - - case EXT_SIA: - next_tick = dc21040_state(dev, 0x3041, 0x0000, 0x0006, 3000, - NC, EXT_SIA_SUSPECT, ping_media); - break; - - case EXT_SIA_SUSPECT: - next_tick = de4x5_suspect_state(dev, 1000, EXT_SIA, ping_media, dc21040_autoconf); - break; - - case NC: - /* default to TP for all */ - reset_init_sia(dev, 0x8f01, 0xffff, 0x0000); - if (lp->media != lp->c_media) { - de4x5_dbg_media(dev); - lp->c_media = lp->media; - } - lp->media = INIT; - lp->tx_enable = NO; - break; + struct de4x5_private *lp = (struct de4x5_private *)dev->priv; + u_long iobase = dev->base_addr; + int next_tick = DE4X5_AUTOSENSE_MS; + s32 imr; + + switch (lp->media) { + case INIT: + DISABLE_IRQs; + lp->tx_enable = NO; + lp->timeout = -1; + de4x5_save_skbs(dev); + if ((lp->autosense == AUTO) || (lp->autosense == TP)) { + lp->media = TP; + } else if ((lp->autosense == BNC) || (lp->autosense == AUI) || (lp->autosense == BNC_AUI)) { + lp->media = BNC_AUI; + } else if (lp->autosense == EXT_SIA) { + lp->media = EXT_SIA; + } else { + lp->media = NC; } - - return next_tick; + lp->local_state = 0; + next_tick = dc21040_autoconf(dev); + break; + + case TP: + next_tick = dc21040_state(dev, 0x8f01, 0xffff, 0x0000, 3000, BNC_AUI, + TP_SUSPECT, test_tp); + break; + + case TP_SUSPECT: + next_tick = de4x5_suspect_state(dev, 1000, TP, test_tp, dc21040_autoconf); + break; + + case BNC: + case AUI: + case BNC_AUI: + next_tick = dc21040_state(dev, 0x8f09, 0x0705, 0x0006, 3000, EXT_SIA, + BNC_AUI_SUSPECT, ping_media); + break; + + case BNC_AUI_SUSPECT: + next_tick = de4x5_suspect_state(dev, 1000, BNC_AUI, ping_media, dc21040_autoconf); + break; + + case EXT_SIA: + next_tick = dc21040_state(dev, 0x3041, 0x0000, 0x0006, 3000, + NC, EXT_SIA_SUSPECT, ping_media); + break; + + case EXT_SIA_SUSPECT: + next_tick = de4x5_suspect_state(dev, 1000, EXT_SIA, ping_media, dc21040_autoconf); + break; + + case NC: + /* default to TP for all */ + reset_init_sia(dev, 0x8f01, 0xffff, 0x0000); + if (lp->media != lp->c_media) { + de4x5_dbg_media(dev); + lp->c_media = lp->media; + } + lp->media = INIT; + lp->tx_enable = NO; + break; + } + + return next_tick; } -static int dc21040_state(struct device *dev, int csr13, int csr14, int csr15, int timeout, - int next_state, int suspect_state, - int (*fn) (struct device *, int)) -{ - struct de4x5_private *lp = (struct de4x5_private *) dev->priv; - int next_tick = DE4X5_AUTOSENSE_MS; - int linkBad; - - switch (lp->local_state) { - case 0: - reset_init_sia(dev, csr13, csr14, csr15); - lp->local_state++; - next_tick = 500; - break; - - case 1: - if (!lp->tx_enable) { - linkBad = fn(dev, timeout); - if (linkBad < 0) { - next_tick = linkBad & ~TIMER_CB; - } else { - if (linkBad && (lp->autosense == AUTO)) { - lp->local_state = 0; - lp->media = next_state; - } else { - de4x5_init_connection(dev); - } - } - } else if (!lp->linkOK && (lp->autosense == AUTO)) { - lp->media = suspect_state; - next_tick = 3000; - } - break; +static int +dc21040_state(struct device *dev, int csr13, int csr14, int csr15, int timeout, + int next_state, int suspect_state, + int (*fn)(struct device *, int)) +{ + struct de4x5_private *lp = (struct de4x5_private *)dev->priv; + int next_tick = DE4X5_AUTOSENSE_MS; + int linkBad; + + switch (lp->local_state) { + case 0: + reset_init_sia(dev, csr13, csr14, csr15); + lp->local_state++; + next_tick = 500; + break; + + case 1: + if (!lp->tx_enable) { + linkBad = fn(dev, timeout); + if (linkBad < 0) { + next_tick = linkBad & ~TIMER_CB; + } else { + if (linkBad && (lp->autosense == AUTO)) { + lp->local_state = 0; + lp->media = next_state; + } else { + de4x5_init_connection(dev); + } + } + } else if (!lp->linkOK && (lp->autosense == AUTO)) { + lp->media = suspect_state; + next_tick = 3000; } - - return next_tick; + break; + } + + return next_tick; } -static int de4x5_suspect_state(struct device *dev, int timeout, int prev_state, - int (*fn) (struct device *, int), - int (*asfn) (struct device *)) -{ - struct de4x5_private *lp = (struct de4x5_private *) dev->priv; - int next_tick = DE4X5_AUTOSENSE_MS; - int linkBad; - - switch (lp->local_state) { - case 1: - if (lp->linkOK) { - lp->media = prev_state; - } else { - lp->local_state++; - next_tick = asfn(dev); - } - break; +static int +de4x5_suspect_state(struct device *dev, int timeout, int prev_state, + int (*fn)(struct device *, int), + int (*asfn)(struct device *)) +{ + struct de4x5_private *lp = (struct de4x5_private *)dev->priv; + int next_tick = DE4X5_AUTOSENSE_MS; + int linkBad; + + switch (lp->local_state) { + case 1: + if (lp->linkOK) { + lp->media = prev_state; + } else { + lp->local_state++; + next_tick = asfn(dev); + } + break; - case 2: - linkBad = fn(dev, timeout); - if (linkBad < 0) { - next_tick = linkBad & ~TIMER_CB; - } else if (!linkBad) { - lp->local_state--; - lp->media = prev_state; - } else { - lp->media = INIT; - lp->tcount++; - } + case 2: + linkBad = fn(dev, timeout); + if (linkBad < 0) { + next_tick = linkBad & ~TIMER_CB; + } else if (!linkBad) { + lp->local_state--; + lp->media = prev_state; + } else { + lp->media = INIT; + lp->tcount++; } + } - return next_tick; + return next_tick; } /* @@ -2444,375 +2511,374 @@ ** any more packets to be queued to the hardware. Re-enable everything only ** when the media is found. */ -static int dc21041_autoconf(struct device *dev) +static int +dc21041_autoconf(struct device *dev) { - struct de4x5_private *lp = (struct de4x5_private *) dev->priv; - u_long iobase = dev->base_addr; - s32 sts, irqs, irq_mask, imr, omr; - int next_tick = DE4X5_AUTOSENSE_MS; - - switch (lp->media) { - case INIT: - DISABLE_IRQs; - lp->tx_enable = NO; - lp->timeout = -1; - de4x5_save_skbs(dev); /* Save non transmitted skb's */ - if ((lp->autosense == AUTO) || (lp->autosense == TP_NW)) { - lp->media = TP; /* On chip auto negotiation is broken */ - } else if (lp->autosense == TP) { - lp->media = TP; - } else if (lp->autosense == BNC) { + struct de4x5_private *lp = (struct de4x5_private *)dev->priv; + u_long iobase = dev->base_addr; + s32 sts, irqs, irq_mask, imr, omr; + int next_tick = DE4X5_AUTOSENSE_MS; + + switch (lp->media) { + case INIT: + DISABLE_IRQs; + lp->tx_enable = NO; + lp->timeout = -1; + de4x5_save_skbs(dev); /* Save non transmitted skb's */ + if ((lp->autosense == AUTO) || (lp->autosense == TP_NW)) { + lp->media = TP; /* On chip auto negotiation is broken */ + } else if (lp->autosense == TP) { + lp->media = TP; + } else if (lp->autosense == BNC) { + lp->media = BNC; + } else if (lp->autosense == AUI) { + lp->media = AUI; + } else { + lp->media = NC; + } + lp->local_state = 0; + next_tick = dc21041_autoconf(dev); + break; + + case TP_NW: + if (lp->timeout < 0) { + omr = inl(DE4X5_OMR);/* Set up full duplex for the autonegotiate */ + outl(omr | OMR_FDX, DE4X5_OMR); + } + irqs = STS_LNF | STS_LNP; + irq_mask = IMR_LFM | IMR_LPM; + sts = test_media(dev, irqs, irq_mask, 0xef01, 0xffff, 0x0008, 2400); + if (sts < 0) { + next_tick = sts & ~TIMER_CB; + } else { + if (sts & STS_LNP) { + lp->media = ANS; + } else { + lp->media = AUI; + } + next_tick = dc21041_autoconf(dev); + } + break; + + case ANS: + if (!lp->tx_enable) { + irqs = STS_LNP; + irq_mask = IMR_LPM; + sts = test_ans(dev, irqs, irq_mask, 3000); + if (sts < 0) { + next_tick = sts & ~TIMER_CB; + } else { + if (!(sts & STS_LNP) && (lp->autosense == AUTO)) { + lp->media = TP; + next_tick = dc21041_autoconf(dev); + } else { + lp->local_state = 1; + de4x5_init_connection(dev); + } + } + } else if (!lp->linkOK && (lp->autosense == AUTO)) { + lp->media = ANS_SUSPECT; + next_tick = 3000; + } + break; + + case ANS_SUSPECT: + next_tick = de4x5_suspect_state(dev, 1000, ANS, test_tp, dc21041_autoconf); + break; + + case TP: + if (!lp->tx_enable) { + if (lp->timeout < 0) { + omr = inl(DE4X5_OMR); /* Set up half duplex for TP */ + outl(omr & ~OMR_FDX, DE4X5_OMR); + } + irqs = STS_LNF | STS_LNP; + irq_mask = IMR_LFM | IMR_LPM; + sts = test_media(dev,irqs, irq_mask, 0xef01, 0xff3f, 0x0008, 2400); + if (sts < 0) { + next_tick = sts & ~TIMER_CB; + } else { + if (!(sts & STS_LNP) && (lp->autosense == AUTO)) { + if (inl(DE4X5_SISR) & SISR_NRA) { + lp->media = AUI; /* Non selected port activity */ + } else { lp->media = BNC; - } else if (lp->autosense == AUI) { - lp->media = AUI; + } + next_tick = dc21041_autoconf(dev); } else { - lp->media = NC; + lp->local_state = 1; + de4x5_init_connection(dev); } - lp->local_state = 0; + } + } else if (!lp->linkOK && (lp->autosense == AUTO)) { + lp->media = TP_SUSPECT; + next_tick = 3000; + } + break; + + case TP_SUSPECT: + next_tick = de4x5_suspect_state(dev, 1000, TP, test_tp, dc21041_autoconf); + break; + + case AUI: + if (!lp->tx_enable) { + if (lp->timeout < 0) { + omr = inl(DE4X5_OMR); /* Set up half duplex for AUI */ + outl(omr & ~OMR_FDX, DE4X5_OMR); + } + irqs = 0; + irq_mask = 0; + sts = test_media(dev,irqs, irq_mask, 0xef09, 0xf73d, 0x000e, 1000); + if (sts < 0) { + next_tick = sts & ~TIMER_CB; + } else { + if (!(inl(DE4X5_SISR) & SISR_SRA) && (lp->autosense == AUTO)) { + lp->media = BNC; + next_tick = dc21041_autoconf(dev); + } else { + lp->local_state = 1; + de4x5_init_connection(dev); + } + } + } else if (!lp->linkOK && (lp->autosense == AUTO)) { + lp->media = AUI_SUSPECT; + next_tick = 3000; + } + break; + + case AUI_SUSPECT: + next_tick = de4x5_suspect_state(dev, 1000, AUI, ping_media, dc21041_autoconf); + break; + + case BNC: + switch (lp->local_state) { + case 0: + if (lp->timeout < 0) { + omr = inl(DE4X5_OMR); /* Set up half duplex for BNC */ + outl(omr & ~OMR_FDX, DE4X5_OMR); + } + irqs = 0; + irq_mask = 0; + sts = test_media(dev,irqs, irq_mask, 0xef09, 0xf73d, 0x0006, 1000); + if (sts < 0) { + next_tick = sts & ~TIMER_CB; + } else { + lp->local_state++; /* Ensure media connected */ next_tick = dc21041_autoconf(dev); - break; - - case TP_NW: - if (lp->timeout < 0) { - omr = inl(DE4X5_OMR); /* Set up full duplex for the autonegotiate */ - outl(omr | OMR_FDX, DE4X5_OMR); - } - irqs = STS_LNF | STS_LNP; - irq_mask = IMR_LFM | IMR_LPM; - sts = test_media(dev, irqs, irq_mask, 0xef01, 0xffff, 0x0008, 2400); - if (sts < 0) { - next_tick = sts & ~TIMER_CB; + } + break; + + case 1: + if (!lp->tx_enable) { + if ((sts = ping_media(dev, 3000)) < 0) { + next_tick = sts & ~TIMER_CB; } else { - if (sts & STS_LNP) { - lp->media = ANS; - } else { - lp->media = AUI; - } - next_tick = dc21041_autoconf(dev); + if (sts) { + lp->local_state = 0; + lp->media = NC; + } else { + de4x5_init_connection(dev); + } } - break; - - case ANS: - if (!lp->tx_enable) { - irqs = STS_LNP; - irq_mask = IMR_LPM; - sts = test_ans(dev, irqs, irq_mask, 3000); - if (sts < 0) { - next_tick = sts & ~TIMER_CB; - } else { - if (!(sts & STS_LNP) && (lp->autosense == AUTO)) { - lp->media = TP; - next_tick = dc21041_autoconf(dev); - } else { - lp->local_state = 1; - de4x5_init_connection(dev); - } - } - } else if (!lp->linkOK && (lp->autosense == AUTO)) { - lp->media = ANS_SUSPECT; - next_tick = 3000; - } - break; - - case ANS_SUSPECT: - next_tick = de4x5_suspect_state(dev, 1000, ANS, test_tp, dc21041_autoconf); - break; - - case TP: - if (!lp->tx_enable) { - if (lp->timeout < 0) { - omr = inl(DE4X5_OMR); /* Set up half duplex for TP */ - outl(omr & ~OMR_FDX, DE4X5_OMR); - } - irqs = STS_LNF | STS_LNP; - irq_mask = IMR_LFM | IMR_LPM; - sts = test_media(dev, irqs, irq_mask, 0xef01, 0xff3f, 0x0008, 2400); - if (sts < 0) { - next_tick = sts & ~TIMER_CB; - } else { - if (!(sts & STS_LNP) && (lp->autosense == AUTO)) { - if (inl(DE4X5_SISR) & SISR_NRA) { - lp->media = AUI; /* Non selected port activity */ - } else { - lp->media = BNC; - } - next_tick = dc21041_autoconf(dev); - } else { - lp->local_state = 1; - de4x5_init_connection(dev); - } - } - } else if (!lp->linkOK && (lp->autosense == AUTO)) { - lp->media = TP_SUSPECT; - next_tick = 3000; - } - break; - - case TP_SUSPECT: - next_tick = de4x5_suspect_state(dev, 1000, TP, test_tp, dc21041_autoconf); - break; - - case AUI: - if (!lp->tx_enable) { - if (lp->timeout < 0) { - omr = inl(DE4X5_OMR); /* Set up half duplex for AUI */ - outl(omr & ~OMR_FDX, DE4X5_OMR); - } - irqs = 0; - irq_mask = 0; - sts = test_media(dev, irqs, irq_mask, 0xef09, 0xf73d, 0x000e, 1000); - if (sts < 0) { - next_tick = sts & ~TIMER_CB; - } else { - if (!(inl(DE4X5_SISR) & SISR_SRA) && (lp->autosense == AUTO)) { - lp->media = BNC; - next_tick = dc21041_autoconf(dev); - } else { - lp->local_state = 1; - de4x5_init_connection(dev); - } - } - } else if (!lp->linkOK && (lp->autosense == AUTO)) { - lp->media = AUI_SUSPECT; - next_tick = 3000; - } - break; - - case AUI_SUSPECT: - next_tick = de4x5_suspect_state(dev, 1000, AUI, ping_media, dc21041_autoconf); - break; - - case BNC: - switch (lp->local_state) { - case 0: - if (lp->timeout < 0) { - omr = inl(DE4X5_OMR); /* Set up half duplex for BNC */ - outl(omr & ~OMR_FDX, DE4X5_OMR); - } - irqs = 0; - irq_mask = 0; - sts = test_media(dev, irqs, irq_mask, 0xef09, 0xf73d, 0x0006, 1000); - if (sts < 0) { - next_tick = sts & ~TIMER_CB; - } else { - lp->local_state++; /* Ensure media connected */ - next_tick = dc21041_autoconf(dev); - } - break; - - case 1: - if (!lp->tx_enable) { - if ((sts = ping_media(dev, 3000)) < 0) { - next_tick = sts & ~TIMER_CB; - } else { - if (sts) { - lp->local_state = 0; - lp->media = NC; - } else { - de4x5_init_connection(dev); - } - } - } else if (!lp->linkOK && (lp->autosense == AUTO)) { - lp->media = BNC_SUSPECT; - next_tick = 3000; - } - break; - } - break; - - case BNC_SUSPECT: - next_tick = de4x5_suspect_state(dev, 1000, BNC, ping_media, dc21041_autoconf); - break; - - case NC: - omr = inl(DE4X5_OMR); /* Set up full duplex for the autonegotiate */ - outl(omr | OMR_FDX, DE4X5_OMR); - reset_init_sia(dev, 0xef01, 0xffff, 0x0008); /* Initialise the SIA */ - if (lp->media != lp->c_media) { - de4x5_dbg_media(dev); - lp->c_media = lp->media; - } - lp->media = INIT; - lp->tx_enable = NO; - break; - } - - return next_tick; -} + } else if (!lp->linkOK && (lp->autosense == AUTO)) { + lp->media = BNC_SUSPECT; + next_tick = 3000; + } + break; + } + break; + + case BNC_SUSPECT: + next_tick = de4x5_suspect_state(dev, 1000, BNC, ping_media, dc21041_autoconf); + break; + + case NC: + omr = inl(DE4X5_OMR); /* Set up full duplex for the autonegotiate */ + outl(omr | OMR_FDX, DE4X5_OMR); + reset_init_sia(dev, 0xef01, 0xffff, 0x0008);/* Initialise the SIA */ + if (lp->media != lp->c_media) { + de4x5_dbg_media(dev); + lp->c_media = lp->media; + } + lp->media = INIT; + lp->tx_enable = NO; + break; + } + + return next_tick; +} /* ** Some autonegotiation chips are broken in that they do not return the ** acknowledge bit (anlpa & MII_ANLPA_ACK) in the link partner advertisement ** register, except at the first power up negotiation. */ -static int dc21140m_autoconf(struct device *dev) +static int +dc21140m_autoconf(struct device *dev) { - struct de4x5_private *lp = (struct de4x5_private *) dev->priv; - int ana, anlpa, cap, cr, slnk, sr; - u_long iobase = dev->base_addr; - int next_tick = DE4X5_AUTOSENSE_MS; - u_long imr, omr; - - switch (lp->media) { - case INIT: - if (lp->timeout < 0) { - DISABLE_IRQs; - lp->tx_enable = FALSE; - lp->linkOK = 0; - de4x5_save_skbs(dev); /* Save non transmitted skb's */ - } - if ((next_tick = de4x5_reset_phy(dev)) < 0) { - next_tick &= ~TIMER_CB; - } else { - if (lp->useSROM) { - if (srom_map_media(dev) < 0) { - lp->tcount++; - return next_tick; - } - srom_exec(dev, lp->phy[lp->active].gep); - if (lp->infoblock_media == ANS) { - ana = lp->phy[lp->active].ana | MII_ANA_CSMA; - mii_wr(ana, MII_ANA, lp->phy[lp->active].addr, DE4X5_MII); - } - } else { - lp->tmp = MII_SR_ASSC; /* Fake out the MII speed set */ - SET_10Mb; - if (lp->autosense == _100Mb) { - lp->media = _100Mb; - } else if (lp->autosense == _10Mb) { - lp->media = _10Mb; - } else if ((lp->autosense == AUTO) && - ((sr = is_anc_capable(dev)) & MII_SR_ANC)) { - ana = (((sr >> 6) & MII_ANA_TAF) | MII_ANA_CSMA); - ana &= (lp->fdx ? ~0 : ~MII_ANA_FDAM); - mii_wr(ana, MII_ANA, lp->phy[lp->active].addr, DE4X5_MII); - lp->media = ANS; - } else if (lp->autosense == AUTO) { - lp->media = SPD_DET; - } else if (is_spd_100(dev) && is_100_up(dev)) { - lp->media = _100Mb; - } else { - lp->media = NC; - } - } - lp->local_state = 0; - next_tick = dc21140m_autoconf(dev); - } - break; - - case ANS: - switch (lp->local_state) { - case 0: - if (lp->timeout < 0) { - mii_wr(MII_CR_ASSE | MII_CR_RAN, MII_CR, lp->phy[lp->active].addr, DE4X5_MII); - } - cr = test_mii_reg(dev, MII_CR, MII_CR_RAN, FALSE, 500); - if (cr < 0) { - next_tick = cr & ~TIMER_CB; - } else { - if (cr) { - lp->local_state = 0; - lp->media = SPD_DET; - } else { - lp->local_state++; - } - next_tick = dc21140m_autoconf(dev); - } - break; - - case 1: - if ((sr = test_mii_reg(dev, MII_SR, MII_SR_ASSC, TRUE, 2000)) < 0) { - next_tick = sr & ~TIMER_CB; - } else { - lp->media = SPD_DET; - lp->local_state = 0; - if (sr) { /* Success! */ - lp->tmp = MII_SR_ASSC; - anlpa = mii_rd(MII_ANLPA, lp->phy[lp->active].addr, DE4X5_MII); - ana = mii_rd(MII_ANA, lp->phy[lp->active].addr, DE4X5_MII); - if (!(anlpa & MII_ANLPA_RF) && - (cap = anlpa & MII_ANLPA_TAF & ana)) { - if (cap & MII_ANA_100M) { - lp->fdx = ((ana & anlpa & MII_ANA_FDAM & MII_ANA_100M) ? TRUE : FALSE); - lp->media = _100Mb; - } else if (cap & MII_ANA_10M) { - lp->fdx = ((ana & anlpa & MII_ANA_FDAM & MII_ANA_10M) ? TRUE : FALSE); - - lp->media = _10Mb; - } - } - } /* Auto Negotiation failed to finish */ - next_tick = dc21140m_autoconf(dev); - } /* Auto Negotiation failed to start */ - break; - } - break; - - case SPD_DET: /* Choose 10Mb/s or 100Mb/s */ - if (lp->timeout < 0) { - lp->tmp = (lp->phy[lp->active].id ? MII_SR_LKS : - (~gep_rd(dev) & GEP_LNP)); - SET_100Mb_PDET; - } - if ((slnk = test_for_100Mb(dev, 6500)) < 0) { - next_tick = slnk & ~TIMER_CB; - } else { - if (is_spd_100(dev) && is_100_up(dev)) { - lp->media = _100Mb; - } else if ((!is_spd_100(dev) && (is_10_up(dev) & lp->tmp))) { - lp->media = _10Mb; - } else { - lp->media = NC; - } - next_tick = dc21140m_autoconf(dev); + struct de4x5_private *lp = (struct de4x5_private *)dev->priv; + int ana, anlpa, cap, cr, slnk, sr; + int next_tick = DE4X5_AUTOSENSE_MS; + u_long imr, omr, iobase = dev->base_addr; + + switch(lp->media) { + case INIT: + if (lp->timeout < 0) { + DISABLE_IRQs; + lp->tx_enable = FALSE; + lp->linkOK = 0; + de4x5_save_skbs(dev); /* Save non transmitted skb's */ + } + if ((next_tick = de4x5_reset_phy(dev)) < 0) { + next_tick &= ~TIMER_CB; + } else { + if (lp->useSROM) { + if (srom_map_media(dev) < 0) { + lp->tcount++; + return next_tick; } - break; - - case _100Mb: /* Set 100Mb/s */ - next_tick = 3000; - if (!lp->tx_enable) { - SET_100Mb; - de4x5_init_connection(dev); + srom_exec(dev, lp->phy[lp->active].gep); + if (lp->infoblock_media == ANS) { + ana = lp->phy[lp->active].ana | MII_ANA_CSMA; + mii_wr(ana, MII_ANA, lp->phy[lp->active].addr, DE4X5_MII); + } + } else { + lp->tmp = MII_SR_ASSC; /* Fake out the MII speed set */ + SET_10Mb; + if (lp->autosense == _100Mb) { + lp->media = _100Mb; + } else if (lp->autosense == _10Mb) { + lp->media = _10Mb; + } else if ((lp->autosense == AUTO) && + ((sr=is_anc_capable(dev)) & MII_SR_ANC)) { + ana = (((sr >> 6) & MII_ANA_TAF) | MII_ANA_CSMA); + ana &= (lp->fdx ? ~0 : ~MII_ANA_FDAM); + mii_wr(ana, MII_ANA, lp->phy[lp->active].addr, DE4X5_MII); + lp->media = ANS; + } else if (lp->autosense == AUTO) { + lp->media = SPD_DET; + } else if (is_spd_100(dev) && is_100_up(dev)) { + lp->media = _100Mb; + } else { + lp->media = NC; + } + } + lp->local_state = 0; + next_tick = dc21140m_autoconf(dev); + } + break; + + case ANS: + switch (lp->local_state) { + case 0: + if (lp->timeout < 0) { + mii_wr(MII_CR_ASSE | MII_CR_RAN, MII_CR, lp->phy[lp->active].addr, DE4X5_MII); + } + cr = test_mii_reg(dev, MII_CR, MII_CR_RAN, FALSE, 500); + if (cr < 0) { + next_tick = cr & ~TIMER_CB; + } else { + if (cr) { + lp->local_state = 0; + lp->media = SPD_DET; } else { - if (!lp->linkOK && (lp->autosense == AUTO)) { - if (!is_100_up(dev) || - (!lp->useSROM && !is_spd_100(dev))) { - lp->media = INIT; - lp->tcount++; - next_tick = DE4X5_AUTOSENSE_MS; - } - } + lp->local_state++; } - break; + next_tick = dc21140m_autoconf(dev); + } + break; + + case 1: + if ((sr=test_mii_reg(dev, MII_SR, MII_SR_ASSC, TRUE, 2000)) < 0) { + next_tick = sr & ~TIMER_CB; + } else { + lp->media = SPD_DET; + lp->local_state = 0; + if (sr) { /* Success! */ + lp->tmp = MII_SR_ASSC; + anlpa = mii_rd(MII_ANLPA, lp->phy[lp->active].addr, DE4X5_MII); + ana = mii_rd(MII_ANA, lp->phy[lp->active].addr, DE4X5_MII); + if (!(anlpa & MII_ANLPA_RF) && + (cap = anlpa & MII_ANLPA_TAF & ana)) { + if (cap & MII_ANA_100M) { + lp->fdx = ((ana & anlpa & MII_ANA_FDAM & MII_ANA_100M) ? TRUE : FALSE); + lp->media = _100Mb; + } else if (cap & MII_ANA_10M) { + lp->fdx = ((ana & anlpa & MII_ANA_FDAM & MII_ANA_10M) ? TRUE : FALSE); - case _10Mb: /* Set 10Mb/s */ - next_tick = 3000; - if (!lp->tx_enable) { - SET_10Mb; - de4x5_init_connection(dev); - } else { - if (!lp->linkOK && (lp->autosense == AUTO)) { - if (!is_10_up(dev) || - (!lp->useSROM && is_spd_100(dev))) { - lp->media = INIT; - lp->tcount++; - next_tick = DE4X5_AUTOSENSE_MS; - } + lp->media = _10Mb; } + } + } /* Auto Negotiation failed to finish */ + next_tick = dc21140m_autoconf(dev); + } /* Auto Negotiation failed to start */ + break; + } + break; + + case SPD_DET: /* Choose 10Mb/s or 100Mb/s */ + if (lp->timeout < 0) { + lp->tmp = (lp->phy[lp->active].id ? MII_SR_LKS : + (~gep_rd(dev) & GEP_LNP)); + SET_100Mb_PDET; + } + if ((slnk = test_for_100Mb(dev, 6500)) < 0) { + next_tick = slnk & ~TIMER_CB; + } else { + if (is_spd_100(dev) && is_100_up(dev)) { + lp->media = _100Mb; + } else if ((!is_spd_100(dev) && (is_10_up(dev) & lp->tmp))) { + lp->media = _10Mb; + } else { + lp->media = NC; + } + next_tick = dc21140m_autoconf(dev); + } + break; + + case _100Mb: /* Set 100Mb/s */ + next_tick = 3000; + if (!lp->tx_enable) { + SET_100Mb; + de4x5_init_connection(dev); + } else { + if (!lp->linkOK && (lp->autosense == AUTO)) { + if (!is_100_up(dev) || (!lp->useSROM && !is_spd_100(dev))) { + lp->media = INIT; + lp->tcount++; + next_tick = DE4X5_AUTOSENSE_MS; } - break; - - case NC: - if (lp->media != lp->c_media) { - de4x5_dbg_media(dev); - lp->c_media = lp->media; + } + } + break; + + case _10Mb: /* Set 10Mb/s */ + next_tick = 3000; + if (!lp->tx_enable) { + SET_10Mb; + de4x5_init_connection(dev); + } else { + if (!lp->linkOK && (lp->autosense == AUTO)) { + if (!is_10_up(dev) || (!lp->useSROM && is_spd_100(dev))) { + lp->media = INIT; + lp->tcount++; + next_tick = DE4X5_AUTOSENSE_MS; } - lp->media = INIT; - lp->tx_enable = FALSE; - break; + } } - - return next_tick; + break; + + case NC: + if (lp->media != lp->c_media) { + de4x5_dbg_media(dev); + lp->c_media = lp->media; + } + lp->media = INIT; + lp->tx_enable = FALSE; + break; + } + + return next_tick; } /* @@ -2832,241 +2898,231 @@ static int dc2114x_autoconf(struct device *dev) { - struct de4x5_private *lp = (struct de4x5_private *) dev->priv; - u_long iobase = dev->base_addr; - s32 cr, anlpa, ana, cap, irqs, irq_mask, imr, omr, slnk, sr, sts; - int next_tick = DE4X5_AUTOSENSE_MS; - - switch (lp->media) { - case INIT: - if (lp->timeout < 0) { - DISABLE_IRQs; - lp->tx_enable = FALSE; - lp->linkOK = 0; - lp->timeout = -1; - de4x5_save_skbs(dev); /* Save non transmitted skb's */ - } - if ((next_tick = de4x5_reset_phy(dev)) < 0) { - next_tick &= ~TIMER_CB; - } else { - lp->media = SPD_DET; - if ((lp->infoblock_media == ANS) && - ((sr=is_anc_capable(dev)) & MII_SR_ANC)) { - ana = (((sr >> 6) & MII_ANA_TAF) | MII_ANA_CSMA); - ana &= (lp->fdx ? ~0 : ~MII_ANA_FDAM); - mii_wr(ana, MII_ANA, - lp->phy[lp->active].addr, - DE4X5_MII); - lp->media = ANS; - } - lp->local_state = 0; - next_tick = dc2114x_autoconf(dev); - } - break; - - case ANS: - switch (lp->local_state) { - case 0: - if (lp->timeout < 0) { - mii_wr(MII_CR_ASSE | MII_CR_RAN, - MII_CR, lp->phy[lp->active].addr, DE4X5_MII); - } - cr = test_mii_reg(dev, MII_CR, MII_CR_RAN, FALSE, 500); - if (cr < 0) { - next_tick = cr & ~TIMER_CB; - } else { - if (cr) { - lp->local_state = 0; - lp->media = SPD_DET; - } else { - lp->local_state++; - } - next_tick = dc2114x_autoconf(dev); - } - break; + struct de4x5_private *lp = (struct de4x5_private *)dev->priv; + u_long iobase = dev->base_addr; + s32 cr, anlpa, ana, cap, irqs, irq_mask, imr, omr, slnk, sr, sts; + int next_tick = DE4X5_AUTOSENSE_MS; + + switch (lp->media) { + case INIT: + if (lp->timeout < 0) { + DISABLE_IRQs; + lp->tx_enable = FALSE; + lp->linkOK = 0; + lp->timeout = -1; + de4x5_save_skbs(dev); /* Save non transmitted skb's */ + } + if ((next_tick = de4x5_reset_phy(dev)) < 0) { + next_tick &= ~TIMER_CB; + } else { + lp->media = SPD_DET; + if ((lp->infoblock_media == ANS) && + ((sr=is_anc_capable(dev)) & MII_SR_ANC)) { + ana = (((sr >> 6) & MII_ANA_TAF) | MII_ANA_CSMA); + ana &= (lp->fdx ? ~0 : ~MII_ANA_FDAM); + mii_wr(ana, MII_ANA, lp->phy[lp->active].addr, DE4X5_MII); + lp->media = ANS; + } + lp->local_state = 0; + next_tick = dc2114x_autoconf(dev); + } + break; + + case ANS: + switch (lp->local_state) { + case 0: + if (lp->timeout < 0) { + mii_wr(MII_CR_ASSE | MII_CR_RAN, MII_CR, lp->phy[lp->active].addr, DE4X5_MII); + } + cr = test_mii_reg(dev, MII_CR, MII_CR_RAN, FALSE, 500); + if (cr < 0) { + next_tick = cr & ~TIMER_CB; + } else { + if (cr) { + lp->local_state = 0; + lp->media = SPD_DET; + } else { + lp->local_state++; + } + next_tick = dc2114x_autoconf(dev); + } + break; - case 1: - if ((sr=test_mii_reg(dev, MII_SR, MII_SR_ASSC, TRUE, 2000)) < 0) { - next_tick = sr & ~TIMER_CB; - } else { - lp->media = SPD_DET; - lp->local_state = 0; - if (sr) { /* Success! */ - lp->tmp = MII_SR_ASSC; - anlpa = mii_rd(MII_ANLPA, - lp->phy[lp->active].addr, - DE4X5_MII); - ana = mii_rd(MII_ANA, - lp->phy[lp->active].addr, - DE4X5_MII); - if (!(anlpa & MII_ANLPA_RF) && - (cap = anlpa & MII_ANLPA_TAF & ana)) { - if (cap & MII_ANA_100M) { - lp->fdx = ((ana & anlpa & MII_ANA_FDAM & MII_ANA_100M) ? TRUE : FALSE); - lp->media = _100Mb; - } else if (cap & MII_ANA_10M) { - lp->fdx = ((ana & anlpa & MII_ANA_FDAM & MII_ANA_10M) ? TRUE : FALSE); - lp->media = _10Mb; - } - } - } /* Auto Negotiation failed to finish */ - next_tick = dc2114x_autoconf(dev); - } /* Auto Negotiation failed to start */ - break; - } - break; + case 1: + if ((sr=test_mii_reg(dev, MII_SR, MII_SR_ASSC, TRUE, 2000)) < 0) { + next_tick = sr & ~TIMER_CB; + } else { + lp->media = SPD_DET; + lp->local_state = 0; + if (sr) { /* Success! */ + lp->tmp = MII_SR_ASSC; + anlpa = mii_rd(MII_ANLPA, lp->phy[lp->active].addr, DE4X5_MII); + ana = mii_rd(MII_ANA, lp->phy[lp->active].addr, DE4X5_MII); + if (!(anlpa & MII_ANLPA_RF) && + (cap = anlpa & MII_ANLPA_TAF & ana)) { + if (cap & MII_ANA_100M) { + lp->fdx = ((ana & anlpa & MII_ANA_FDAM & MII_ANA_100M) ? TRUE : FALSE); + lp->media = _100Mb; + } else if (cap & MII_ANA_10M) { + lp->fdx = ((ana & anlpa & MII_ANA_FDAM & MII_ANA_10M) ? TRUE : FALSE); + lp->media = _10Mb; + } + } + } /* Auto Negotiation failed to finish */ + next_tick = dc2114x_autoconf(dev); + } /* Auto Negotiation failed to start */ + break; + } + break; - case AUI: - if (!lp->tx_enable) { - if (lp->timeout < 0) { - omr = inl(DE4X5_OMR); /* Set up half duplex for AUI */ - outl(omr & ~OMR_FDX, DE4X5_OMR); - } - irqs = 0; - irq_mask = 0; - sts = test_media(dev,irqs, irq_mask, 0, 0, 0, 1000); - if (sts < 0) { - next_tick = sts & ~TIMER_CB; - } else { - if (!(inl(DE4X5_SISR) & SISR_SRA) && (lp->autosense == AUTO)) { - lp->media = BNC; - next_tick = dc2114x_autoconf(dev); - } else { - lp->local_state = 1; - de4x5_init_connection(dev); - } - } - } else if (!lp->linkOK && (lp->autosense == AUTO)) { - lp->media = AUI_SUSPECT; - next_tick = 3000; - } - break; + case AUI: + if (!lp->tx_enable) { + if (lp->timeout < 0) { + omr = inl(DE4X5_OMR); /* Set up half duplex for AUI */ + outl(omr & ~OMR_FDX, DE4X5_OMR); + } + irqs = 0; + irq_mask = 0; + sts = test_media(dev,irqs, irq_mask, 0, 0, 0, 1000); + if (sts < 0) { + next_tick = sts & ~TIMER_CB; + } else { + if (!(inl(DE4X5_SISR) & SISR_SRA) && (lp->autosense == AUTO)) { + lp->media = BNC; + next_tick = dc2114x_autoconf(dev); + } else { + lp->local_state = 1; + de4x5_init_connection(dev); + } + } + } else if (!lp->linkOK && (lp->autosense == AUTO)) { + lp->media = AUI_SUSPECT; + next_tick = 3000; + } + break; - case AUI_SUSPECT: - next_tick = de4x5_suspect_state(dev, 1000, AUI, - ping_media, dc2114x_autoconf); - break; + case AUI_SUSPECT: + next_tick = de4x5_suspect_state(dev, 1000, AUI, ping_media, dc2114x_autoconf); + break; - case BNC: - switch (lp->local_state) { - case 0: - if (lp->timeout < 0) { - omr = inl(DE4X5_OMR); /* Set up half duplex for BNC */ - outl(omr & ~OMR_FDX, DE4X5_OMR); - } - irqs = 0; - irq_mask = 0; - sts = test_media(dev,irqs, irq_mask, 0, 0, 0, 1000); - if (sts < 0) { - next_tick = sts & ~TIMER_CB; - } else { - lp->local_state++; /* Ensure media connected */ - next_tick = dc2114x_autoconf(dev); - } - break; + case BNC: + switch (lp->local_state) { + case 0: + if (lp->timeout < 0) { + omr = inl(DE4X5_OMR); /* Set up half duplex for BNC */ + outl(omr & ~OMR_FDX, DE4X5_OMR); + } + irqs = 0; + irq_mask = 0; + sts = test_media(dev,irqs, irq_mask, 0, 0, 0, 1000); + if (sts < 0) { + next_tick = sts & ~TIMER_CB; + } else { + lp->local_state++; /* Ensure media connected */ + next_tick = dc2114x_autoconf(dev); + } + break; - case 1: - if (!lp->tx_enable) { - if ((sts = ping_media(dev, 3000)) < 0) { - next_tick = sts & ~TIMER_CB; - } else { - if (sts) { - lp->local_state = 0; - lp->tcount++; - lp->media = INIT; - } else { - de4x5_init_connection(dev); - } - } - } else if (!lp->linkOK && (lp->autosense == AUTO)) { - lp->media = BNC_SUSPECT; - next_tick = 3000; - } - break; - } - break; - - case BNC_SUSPECT: - next_tick = de4x5_suspect_state(dev, 1000, BNC, - ping_media, dc2114x_autoconf); - break; - - case SPD_DET: /* Choose 10Mb/s or 100Mb/s */ - if (srom_map_media(dev) < 0) { - lp->tcount++; - lp->media = INIT; - return next_tick; - } - if (lp->media == _100Mb) { - if ((slnk = test_for_100Mb(dev, 6500)) < 0) { - lp->media = SPD_DET; - return (slnk & ~TIMER_CB); - } - } else { - if (wait_for_link(dev) < 0) { - lp->media = SPD_DET; - return PDET_LINK_WAIT; - } - } - if (((lp->media == _100Mb) && is_100_up(dev)) || - ((lp->media == _10Mb) && is_10_up(dev)) || - (lp->media == BNC) || (lp->media == AUI)) { - next_tick = dc2114x_autoconf(dev); + case 1: + if (!lp->tx_enable) { + if ((sts = ping_media(dev, 3000)) < 0) { + next_tick = sts & ~TIMER_CB; } else { + if (sts) { + lp->local_state = 0; lp->tcount++; lp->media = INIT; - } - break; - - case _10Mb: - next_tick = 3000; - if (!lp->tx_enable) { - SET_10Mb; + } else { de4x5_init_connection(dev); - } else { - if (!lp->linkOK && (lp->autosense == AUTO)) { - if (!is_10_up(dev) || - (!lp->useSROM && is_spd_100(dev))) { - lp->media = INIT; - lp->tcount++; - next_tick = DE4X5_AUTOSENSE_MS; - } - } + } } - break; - - case _100Mb: + } else if (!lp->linkOK && (lp->autosense == AUTO)) { + lp->media = BNC_SUSPECT; next_tick = 3000; - if (!lp->tx_enable) { - SET_100Mb; - de4x5_init_connection(dev); - } else { - if (!lp->linkOK && (lp->autosense == AUTO)) { - if (!is_100_up(dev) || - (!lp->useSROM && !is_spd_100(dev))) { - lp->media = INIT; - lp->tcount++; - next_tick = DE4X5_AUTOSENSE_MS; - } - } - } - break; - - default: - lp->tcount++; - printk("Huh?: media:%02x\n", lp->media); - lp->media = INIT; - break; + } + break; } + break; + + case BNC_SUSPECT: + next_tick = de4x5_suspect_state(dev, 1000, BNC, ping_media, dc2114x_autoconf); + break; + + case SPD_DET: /* Choose 10Mb/s or 100Mb/s */ + if (srom_map_media(dev) < 0) { + lp->tcount++; + lp->media = INIT; + return next_tick; + } + if (lp->media == _100Mb) { + if ((slnk = test_for_100Mb(dev, 6500)) < 0) { + lp->media = SPD_DET; + return (slnk & ~TIMER_CB); + } + } else { + if (wait_for_link(dev) < 0) { + lp->media = SPD_DET; + return PDET_LINK_WAIT; + } + } + if (((lp->media == _100Mb) && is_100_up(dev)) || + ((lp->media == _10Mb) && is_10_up(dev)) || + (lp->media == BNC) || (lp->media == AUI)) { + next_tick = dc2114x_autoconf(dev); + } else { + lp->tcount++; + lp->media = INIT; + } + break; + + case _10Mb: + next_tick = 3000; + if (!lp->tx_enable) { + SET_10Mb; + de4x5_init_connection(dev); + } else { + if (!lp->linkOK && (lp->autosense == AUTO)) { + if (!is_10_up(dev) || (!lp->useSROM && is_spd_100(dev))) { + lp->media = INIT; + lp->tcount++; + next_tick = DE4X5_AUTOSENSE_MS; + } + } + } + break; + + case _100Mb: + next_tick = 3000; + if (!lp->tx_enable) { + SET_100Mb; + de4x5_init_connection(dev); + } else { + if (!lp->linkOK && (lp->autosense == AUTO)) { + if (!is_100_up(dev) || (!lp->useSROM && !is_spd_100(dev))) { + lp->media = INIT; + lp->tcount++; + next_tick = DE4X5_AUTOSENSE_MS; + } + } + } + break; + + default: + lp->tcount++; +printk("Huh?: media:%02x\n", lp->media); + lp->media = INIT; + break; + } - return next_tick; + return next_tick; } -static int srom_autoconf(struct device *dev) +static int +srom_autoconf(struct device *dev) { - struct de4x5_private *lp = (struct de4x5_private *)dev->priv; + struct de4x5_private *lp = (struct de4x5_private *)dev->priv; - return lp->infoleaf_fn(dev); + return lp->infoleaf_fn(dev); } /* @@ -3074,95 +3130,91 @@ ** While it isn't strictly necessary, it helps me for the moment... ** The early return avoids a media state / SROM media space clash. */ -static int srom_map_media(struct device *dev) -{ - struct de4x5_private *lp = (struct de4x5_private *)dev->priv; - - lp->fdx = 0; - if (lp->infoblock_media == lp->media) - return 0; - - switch(lp->infoblock_media) { - case SROM_10BASETF: - if (!de4x5_full_duplex) - return -1; - lp->fdx = TRUE; - case SROM_10BASET: - if (de4x5_full_duplex && !lp->fdx) - return -1; - if ((lp->chipset == DC21140) || ((lp->chipset & ~0x00ff) == DC2114x)) { - lp->media = _10Mb; - } else { - lp->media = TP; - } - break; - - case SROM_10BASE2: - lp->media = BNC; - break; - - case SROM_10BASE5: - lp->media = AUI; - break; - - case SROM_100BASETF: - if (!de4x5_full_duplex) - return -1; - lp->fdx = TRUE; - case SROM_100BASET: - if (de4x5_full_duplex && !lp->fdx) - return -1; - lp->media = _100Mb; - break; - - case SROM_100BASET4: - lp->media = _100Mb; - break; - - case SROM_100BASEFF: - if (!de4x5_full_duplex) - return -1; - lp->fdx = TRUE; - case SROM_100BASEF: - if (de4x5_full_duplex && !lp->fdx) - return -1; - lp->media = _100Mb; - break; - - case ANS: - lp->media = ANS; - break; - - default: - printk("%s: Bad media code [%d] detected in SROM!\n", dev->name, - lp->infoblock_media); - return -1; - break; - } - - return 0; -} - -static void de4x5_init_connection(struct device *dev) +static int +srom_map_media(struct device *dev) { - struct de4x5_private *lp = (struct de4x5_private *)dev->priv; - u_long iobase = dev->base_addr; + struct de4x5_private *lp = (struct de4x5_private *)dev->priv; - if (lp->media != lp->c_media) { - de4x5_dbg_media(dev); - lp->c_media = lp->media; /* Stop scrolling media messages */ + lp->fdx = 0; + if (lp->infoblock_media == lp->media) + return 0; + + switch(lp->infoblock_media) { + case SROM_10BASETF: + if (!lp->params.fdx) return -1; + lp->fdx = TRUE; + case SROM_10BASET: + if (lp->params.fdx && !lp->fdx) return -1; + if ((lp->chipset == DC21140) || ((lp->chipset & ~0x00ff) == DC2114x)) { + lp->media = _10Mb; + } else { + lp->media = TP; } + break; - cli(); - de4x5_restore_skbs(dev); - de4x5_setup_intr(dev); - lp->tx_enable = YES; - dev->tbusy = 0; - sti(); - outl(POLL_DEMAND, DE4X5_TPD); - mark_bh(NET_BH); + case SROM_10BASE2: + lp->media = BNC; + break; + + case SROM_10BASE5: + lp->media = AUI; + break; + + case SROM_100BASETF: + if (!lp->params.fdx) return -1; + lp->fdx = TRUE; + case SROM_100BASET: + if (lp->params.fdx && !lp->fdx) return -1; + lp->media = _100Mb; + break; + + case SROM_100BASET4: + lp->media = _100Mb; + break; + + case SROM_100BASEFF: + if (!lp->params.fdx) return -1; + lp->fdx = TRUE; + case SROM_100BASEF: + if (lp->params.fdx && !lp->fdx) return -1; + lp->media = _100Mb; + break; + + case ANS: + lp->media = ANS; + break; + + default: + printk("%s: Bad media code [%d] detected in SROM!\n", dev->name, + lp->infoblock_media); + return -1; + break; + } + + return 0; +} + +static void +de4x5_init_connection(struct device *dev) +{ + struct de4x5_private *lp = (struct de4x5_private *)dev->priv; + u_long iobase = dev->base_addr; + + if (lp->media != lp->c_media) { + de4x5_dbg_media(dev); + lp->c_media = lp->media; /* Stop scrolling media messages */ + } + + cli(); + de4x5_rst_desc_ring(dev); + de4x5_setup_intr(dev); + lp->tx_enable = YES; + dev->tbusy = 0; + sti(); + outl(POLL_DEMAND, DE4X5_TPD); + mark_bh(NET_BH); - return; + return; } /* @@ -3170,94 +3222,98 @@ ** since their MII address pins can float at voltages that are dependent ** on the signal pin use. Do a double reset to ensure a reset. */ -static int de4x5_reset_phy(struct device *dev) +static int +de4x5_reset_phy(struct device *dev) { - struct de4x5_private *lp = (struct de4x5_private *)dev->priv; - u_long iobase = dev->base_addr; - int next_tick = 0; - - if ((lp->useSROM) || (lp->phy[lp->active].id)) { - if (lp->timeout < 0) { - if (lp->useSROM) { - if (lp->phy[lp->active].rst) { - srom_exec(dev, lp->phy[lp->active].rst); - srom_exec(dev, lp->phy[lp->active].rst); - } else if (lp->rst) { /* Type 5 infoblock reset */ - srom_exec(dev, lp->rst); - srom_exec(dev, lp->rst); - } - } else { - PHY_HARD_RESET; - } - if (lp->useMII) { - mii_wr(MII_CR_RST, MII_CR, - lp->phy[lp->active].addr, DE4X5_MII); - } - } - if (lp->useMII) { - next_tick = test_mii_reg(dev, MII_CR, MII_CR_RST, FALSE, 500); + struct de4x5_private *lp = (struct de4x5_private *)dev->priv; + u_long iobase = dev->base_addr; + int next_tick = 0; + + if ((lp->useSROM) || (lp->phy[lp->active].id)) { + if (lp->timeout < 0) { + if (lp->useSROM) { + if (lp->phy[lp->active].rst) { + srom_exec(dev, lp->phy[lp->active].rst); + srom_exec(dev, lp->phy[lp->active].rst); + } else if (lp->rst) { /* Type 5 infoblock reset */ + srom_exec(dev, lp->rst); + srom_exec(dev, lp->rst); } - } else if (lp->chipset == DC21140) { + } else { PHY_HARD_RESET; + } + if (lp->useMII) { + mii_wr(MII_CR_RST, MII_CR, lp->phy[lp->active].addr, DE4X5_MII); + } + } + if (lp->useMII) { + next_tick = test_mii_reg(dev, MII_CR, MII_CR_RST, FALSE, 500); } + } else if (lp->chipset == DC21140) { + PHY_HARD_RESET; + } - return next_tick; + return next_tick; } -static int test_media(struct device *dev, s32 irqs, s32 irq_mask, s32 csr13, s32 csr14, s32 csr15, s32 msec) +static int +test_media(struct device *dev, s32 irqs, s32 irq_mask, s32 csr13, s32 csr14, s32 csr15, s32 msec) { - struct de4x5_private *lp = (struct de4x5_private *) dev->priv; - u_long iobase = dev->base_addr; - s32 sts, csr12; - - if (lp->timeout < 0) { - lp->timeout = msec / 100; - if (!lp->useSROM) { /* Already done if by SROM, else dc2104[01] */ - reset_init_sia(dev, csr13, csr14, csr15); - } - - /* set up the interrupt mask */ - outl(irq_mask, DE4X5_IMR); - - /* clear all pending interrupts */ - sts = inl(DE4X5_STS); - outl(sts, DE4X5_STS); - - /* clear csr12 NRA and SRA bits */ - if ((lp->chipset == DC21041) || lp->useSROM) { - csr12 = inl(DE4X5_SISR); - outl(csr12, DE4X5_SISR); - } + struct de4x5_private *lp = (struct de4x5_private *)dev->priv; + u_long iobase = dev->base_addr; + s32 sts, csr12; + + if (lp->timeout < 0) { + lp->timeout = msec/100; + if (!lp->useSROM) { /* Already done if by SROM, else dc2104[01] */ + reset_init_sia(dev, csr13, csr14, csr15); } - sts = inl(DE4X5_STS) & ~TIMER_CB; - if (!(sts & irqs) && --lp->timeout) { - sts = 100 | TIMER_CB; - } else { - lp->timeout = -1; + /* set up the interrupt mask */ + outl(irq_mask, DE4X5_IMR); + + /* clear all pending interrupts */ + sts = inl(DE4X5_STS); + outl(sts, DE4X5_STS); + + /* clear csr12 NRA and SRA bits */ + if ((lp->chipset == DC21041) || lp->useSROM) { + csr12 = inl(DE4X5_SISR); + outl(csr12, DE4X5_SISR); } - - return sts; + } + + sts = inl(DE4X5_STS) & ~TIMER_CB; + + if (!(sts & irqs) && --lp->timeout) { + sts = 100 | TIMER_CB; + } else { + lp->timeout = -1; + } + + return sts; } -static int test_tp(struct device *dev, s32 msec) +static int +test_tp(struct device *dev, s32 msec) { - struct de4x5_private *lp = (struct de4x5_private *) dev->priv; - u_long iobase = dev->base_addr; - int sisr; - - if (lp->timeout < 0) { - lp->timeout = msec / 100; - } - sisr = (inl(DE4X5_SISR) & ~TIMER_CB) & (SISR_LKF | SISR_NCR); - - if (sisr && --lp->timeout) { - sisr = 100 | TIMER_CB; - } else { - lp->timeout = -1; - } + struct de4x5_private *lp = (struct de4x5_private *)dev->priv; + u_long iobase = dev->base_addr; + int sisr; + + if (lp->timeout < 0) { + lp->timeout = msec/100; + } + + sisr = (inl(DE4X5_SISR) & ~TIMER_CB) & (SISR_LKF | SISR_NCR); - return sisr; + if (sisr && --lp->timeout) { + sisr = 100 | TIMER_CB; + } else { + lp->timeout = -1; + } + + return sisr; } /* @@ -3267,195 +3323,204 @@ */ #define SAMPLE_INTERVAL 500 /* ms */ #define SAMPLE_DELAY 2000 /* ms */ -static int test_for_100Mb(struct device *dev, int msec) +static int +test_for_100Mb(struct device *dev, int msec) { - struct de4x5_private *lp = (struct de4x5_private *) dev->priv; - int gep = 0, ret = ((lp->chipset & ~0x00ff)==DC2114x? -1 :GEP_SLNK); + struct de4x5_private *lp = (struct de4x5_private *)dev->priv; + int gep = 0, ret = ((lp->chipset & ~0x00ff)==DC2114x? -1 :GEP_SLNK); - if (lp->timeout < 0) { - if ((msec/SAMPLE_INTERVAL) <= 0) - return 0; - if (msec > SAMPLE_DELAY) { - lp->timeout = (msec - SAMPLE_DELAY)/SAMPLE_INTERVAL; - gep = SAMPLE_DELAY | TIMER_CB; - return gep; - } else { - lp->timeout = msec/SAMPLE_INTERVAL; - } - } - if (lp->phy[lp->active].id || lp->useSROM) { - gep = is_100_up(dev) | is_spd_100(dev); - } else { - gep = (~gep_rd(dev) & (GEP_SLNK | GEP_LNP)); - } - if (!(gep & ret) && --lp->timeout) { - gep = SAMPLE_INTERVAL | TIMER_CB; + if (lp->timeout < 0) { + if ((msec/SAMPLE_INTERVAL) <= 0) return 0; + if (msec > SAMPLE_DELAY) { + lp->timeout = (msec - SAMPLE_DELAY)/SAMPLE_INTERVAL; + gep = SAMPLE_DELAY | TIMER_CB; + return gep; } else { - lp->timeout = -1; + lp->timeout = msec/SAMPLE_INTERVAL; } - - return gep; + } + + if (lp->phy[lp->active].id || lp->useSROM) { + gep = is_100_up(dev) | is_spd_100(dev); + } else { + gep = (~gep_rd(dev) & (GEP_SLNK | GEP_LNP)); + } + if (!(gep & ret) && --lp->timeout) { + gep = SAMPLE_INTERVAL | TIMER_CB; + } else { + lp->timeout = -1; + } + + return gep; } -static int wait_for_link(struct device *dev) +static int +wait_for_link(struct device *dev) { - struct de4x5_private *lp = (struct de4x5_private *)dev->priv; + struct de4x5_private *lp = (struct de4x5_private *)dev->priv; - if (lp->timeout < 0) { - lp->timeout = 1; - } + if (lp->timeout < 0) { + lp->timeout = 1; + } - if (lp->timeout--) { - return TIMER_CB; - } else { - lp->timeout = -1; - } + if (lp->timeout--) { + return TIMER_CB; + } else { + lp->timeout = -1; + } - return 0; + return 0; } /* ** ** */ -static int test_mii_reg(struct device *dev, int reg, int mask, int pol, long msec) +static int +test_mii_reg(struct device *dev, int reg, int mask, int pol, long msec) { - struct de4x5_private *lp = (struct de4x5_private *) dev->priv; - int test; - u_long iobase = dev->base_addr; - - if (lp->timeout < 0) { - lp->timeout = msec / 100; - } - if (pol) - pol = ~0; - reg = mii_rd((u_char) reg, lp->phy[lp->active].addr, DE4X5_MII) & mask; - test = (reg ^ pol) & mask; - - if (test && --lp->timeout) { - reg = 100 | TIMER_CB; - } else { - lp->timeout = -1; - } - - return reg; + struct de4x5_private *lp = (struct de4x5_private *)dev->priv; + int test; + u_long iobase = dev->base_addr; + + if (lp->timeout < 0) { + lp->timeout = msec/100; + } + + if (pol) pol = ~0; + reg = mii_rd((u_char)reg, lp->phy[lp->active].addr, DE4X5_MII) & mask; + test = (reg ^ pol) & mask; + + if (test && --lp->timeout) { + reg = 100 | TIMER_CB; + } else { + lp->timeout = -1; + } + + return reg; } -static int is_spd_100(struct device *dev) +static int +is_spd_100(struct device *dev) { - struct de4x5_private *lp = (struct de4x5_private *) dev->priv; - u_long iobase = dev->base_addr; - int spd; - - if (lp->useMII) { - spd = mii_rd(lp->phy[lp->active].spd.reg, lp->phy[lp->active].addr, DE4X5_MII); - spd = ~(spd ^ lp->phy[lp->active].spd.value); - spd &= lp->phy[lp->active].spd.mask; - } else if (!lp->useSROM) { /* de500-xa */ - spd = ((~gep_rd(dev)) & GEP_SLNK); - } else { - if ((lp->ibn == 2) || !lp->asBitValid) - return ((lp->chipset == DC21143)?(~inl(DE4X5_SISR)&SISR_LS100):0); - - spd = (lp->asBitValid & (lp->asPolarity ^ (gep_rd(dev) & lp->asBit))) | - (lp->linkOK & ~lp->asBitValid); - } - - return spd; + struct de4x5_private *lp = (struct de4x5_private *)dev->priv; + u_long iobase = dev->base_addr; + int spd; + + if (lp->useMII) { + spd = mii_rd(lp->phy[lp->active].spd.reg, lp->phy[lp->active].addr, DE4X5_MII); + spd = ~(spd ^ lp->phy[lp->active].spd.value); + spd &= lp->phy[lp->active].spd.mask; + } else if (!lp->useSROM) { /* de500-xa */ + spd = ((~gep_rd(dev)) & GEP_SLNK); + } else { + if ((lp->ibn == 2) || !lp->asBitValid) + return ((lp->chipset == DC21143)?(~inl(DE4X5_SISR)&SISR_LS100):0); + + spd = (lp->asBitValid & (lp->asPolarity ^ (gep_rd(dev) & lp->asBit))) | + (lp->linkOK & ~lp->asBitValid); + } + + return spd; } -static int is_100_up(struct device *dev) +static int +is_100_up(struct device *dev) { - struct de4x5_private *lp = (struct de4x5_private *) dev->priv; - u_long iobase = dev->base_addr; - - if (lp->useMII) { - /* Double read for sticky bits & temporary drops */ - mii_rd(MII_SR, lp->phy[lp->active].addr, DE4X5_MII); - return (mii_rd(MII_SR, lp->phy[lp->active].addr, DE4X5_MII) & MII_SR_LKS); - } else if (!lp->useSROM) { /* de500-xa */ - return ((~gep_rd(dev)) & GEP_SLNK); - } else { - if ((lp->ibn == 2) || !lp->asBitValid) - return ((lp->chipset == DC21143)?(~inl(DE4X5_SISR)&SISR_LS100):0); - - return ((lp->asBitValid&(lp->asPolarity^(gep_rd(dev)&lp->asBit))) | - (lp->linkOK & ~lp->asBitValid)); - } + struct de4x5_private *lp = (struct de4x5_private *)dev->priv; + u_long iobase = dev->base_addr; + + if (lp->useMII) { + /* Double read for sticky bits & temporary drops */ + mii_rd(MII_SR, lp->phy[lp->active].addr, DE4X5_MII); + return (mii_rd(MII_SR, lp->phy[lp->active].addr, DE4X5_MII) & MII_SR_LKS); + } else if (!lp->useSROM) { /* de500-xa */ + return ((~gep_rd(dev)) & GEP_SLNK); + } else { + if ((lp->ibn == 2) || !lp->asBitValid) + return ((lp->chipset == DC21143)?(~inl(DE4X5_SISR)&SISR_LS100):0); + + return ((lp->asBitValid&(lp->asPolarity^(gep_rd(dev)&lp->asBit))) | + (lp->linkOK & ~lp->asBitValid)); + } } -static int is_10_up(struct device *dev) +static int +is_10_up(struct device *dev) { - struct de4x5_private *lp = (struct de4x5_private *) dev->priv; - u_long iobase = dev->base_addr; - - if (lp->useMII) { - /* Double read for sticky bits & temporary drops */ - mii_rd(MII_SR, lp->phy[lp->active].addr, DE4X5_MII); - return (mii_rd(MII_SR, lp->phy[lp->active].addr, DE4X5_MII) & MII_SR_LKS); - } else if (!lp->useSROM) { /* de500-xa */ - return ((~gep_rd(dev)) & GEP_LNP); - } else { - if ((lp->ibn == 2) || !lp->asBitValid) - return (((lp->chipset & ~0x00ff) == DC2114x) ? - (~inl(DE4X5_SISR)&SISR_LS10): - 0); - - return ((lp->asBitValid&(lp->asPolarity^(gep_rd(dev)&lp->asBit))) | - (lp->linkOK & ~lp->asBitValid)); - } + struct de4x5_private *lp = (struct de4x5_private *)dev->priv; + u_long iobase = dev->base_addr; + + if (lp->useMII) { + /* Double read for sticky bits & temporary drops */ + mii_rd(MII_SR, lp->phy[lp->active].addr, DE4X5_MII); + return (mii_rd(MII_SR, lp->phy[lp->active].addr, DE4X5_MII) & MII_SR_LKS); + } else if (!lp->useSROM) { /* de500-xa */ + return ((~gep_rd(dev)) & GEP_LNP); + } else { + if ((lp->ibn == 2) || !lp->asBitValid) + return (((lp->chipset & ~0x00ff) == DC2114x) ? + (~inl(DE4X5_SISR)&SISR_LS10): + 0); + + return ((lp->asBitValid&(lp->asPolarity^(gep_rd(dev)&lp->asBit))) | + (lp->linkOK & ~lp->asBitValid)); + } } -static int is_anc_capable(struct device *dev) +static int +is_anc_capable(struct device *dev) { - struct de4x5_private *lp = (struct de4x5_private *) dev->priv; - u_long iobase = dev->base_addr; - - if (lp->phy[lp->active].id && (!lp->useSROM || lp->useMII)) { - return (mii_rd(MII_SR, lp->phy[lp->active].addr, DE4X5_MII)); - } else if ((lp->chipset & ~0x00ff) == DC2114x) { - return (inl(DE4X5_SISR) & SISR_LPN) >> 11; - } else { - return 0; - } + struct de4x5_private *lp = (struct de4x5_private *)dev->priv; + u_long iobase = dev->base_addr; + + if (lp->phy[lp->active].id && (!lp->useSROM || lp->useMII)) { + return (mii_rd(MII_SR, lp->phy[lp->active].addr, DE4X5_MII)); + } else if ((lp->chipset & ~0x00ff) == DC2114x) { + return (inl(DE4X5_SISR) & SISR_LPN) >> 11; + } else { + return 0; + } } /* ** Send a packet onto the media and watch for send errors that indicate the ** media is bad or unconnected. */ -static int ping_media(struct device *dev, int msec) +static int +ping_media(struct device *dev, int msec) { - struct de4x5_private *lp = (struct de4x5_private *) dev->priv; - u_long iobase = dev->base_addr; - int sisr; - - if (lp->timeout < 0) { - lp->timeout = msec / 100; + struct de4x5_private *lp = (struct de4x5_private *)dev->priv; + u_long iobase = dev->base_addr; + int sisr; + + if (lp->timeout < 0) { + lp->timeout = msec/100; + + lp->tmp = lp->tx_new; /* Remember the ring position */ + load_packet(dev, lp->frame, TD_LS | TD_FS | sizeof(lp->frame), NULL); + lp->tx_new = (++lp->tx_new) % lp->txRingSize; + outl(POLL_DEMAND, DE4X5_TPD); + } + + sisr = inl(DE4X5_SISR); - lp->tmp = lp->tx_new; /* Remember the ring position */ - load_packet(dev, lp->frame, TD_LS | TD_FS | sizeof(lp->frame), NULL); - lp->tx_new = (++lp->tx_new) % lp->txRingSize; - outl(POLL_DEMAND, DE4X5_TPD); - } - sisr = inl(DE4X5_SISR); - - if ((!(sisr & SISR_NCR)) && - ((s32) le32_to_cpu(lp->tx_ring[lp->tmp].status) < 0) && - (--lp->timeout)) { - sisr = 100 | TIMER_CB; - } else { - if ((!(sisr & SISR_NCR)) && - !(le32_to_cpu(lp->tx_ring[lp->tmp].status) & (T_OWN | TD_ES)) && - lp->timeout) { - sisr = 0; - } else { - sisr = 1; - } - lp->timeout = -1; + if ((!(sisr & SISR_NCR)) && + ((s32)le32_to_cpu(lp->tx_ring[lp->tmp].status) < 0) && + (--lp->timeout)) { + sisr = 100 | TIMER_CB; + } else { + if ((!(sisr & SISR_NCR)) && + !(le32_to_cpu(lp->tx_ring[lp->tmp].status) & (T_OWN | TD_ES)) && + lp->timeout) { + sisr = 0; + } else { + sisr = 1; } - - return sisr; + lp->timeout = -1; + } + + return sisr; } /* @@ -3463,93 +3528,94 @@ ** replace the one about to be passed up. On Alpha's it kmallocs a buffer ** into which the packet is copied. */ -static struct sk_buff *de4x5_alloc_rx_buff(struct device *dev, int index, int len) +static struct sk_buff * +de4x5_alloc_rx_buff(struct device *dev, int index, int len) { - struct de4x5_private *lp = (struct de4x5_private *) dev->priv; - struct sk_buff *p; + struct de4x5_private *lp = (struct de4x5_private *)dev->priv; + struct sk_buff *p; #if !defined(__alpha__) && !defined(__powerpc__) && !defined(__sparc_v9__) && !defined(DE4X5_DO_MEMCPY) - struct sk_buff *ret; - u_long i = 0, tmp; + struct sk_buff *ret; + u_long i=0, tmp; - p = dev_alloc_skb(IEEE802_3_SZ + ALIGN + 2); - if (!p) - return NULL; - - p->dev = dev; - tmp = virt_to_bus(p->data); - i = ((tmp + ALIGN) & ~ALIGN) - tmp; - skb_reserve(p, i); - lp->rx_ring[index].buf = tmp + i; + p = dev_alloc_skb(IEEE802_3_SZ + ALIGN + 2); + if (!p) return NULL; - ret = lp->rx_skb[index]; - lp->rx_skb[index] = p; + p->dev = dev; + tmp = virt_to_bus(p->data); + i = ((tmp + ALIGN) & ~ALIGN) - tmp; + skb_reserve(p, i); + lp->rx_ring[index].buf = tmp + i; + + ret = lp->rx_skb[index]; + lp->rx_skb[index] = p; + + if ((u_long) ret > 1) { + skb_put(ret, len); + } - if ((u_long) ret > 1) { - skb_put(ret, len); - } - return ret; + return ret; #else - if (lp->state != OPEN) - return (struct sk_buff *) 1; /* Fake out the open */ + if (lp->state != OPEN) return (struct sk_buff *)1; /* Fake out the open */ - p = dev_alloc_skb(len + 2); - if (!p) - return NULL; - - p->dev = dev; - skb_reserve(p, 2); /* Align */ - if (index < lp->rx_old) { /* Wrapped buffer */ - short tlen = (lp->rxRingSize - lp->rx_old) * RX_BUFF_SZ; - memcpy(skb_put(p, tlen), - bus_to_virt(le32_to_cpu(lp->rx_ring[lp->rx_old].buf)), tlen); - memcpy(skb_put(p, len - tlen), - bus_to_virt(le32_to_cpu(lp->rx_ring[0].buf)), len - tlen); - } else { /* Linear buffer */ - memcpy(skb_put(p, len), - bus_to_virt(le32_to_cpu(lp->rx_ring[lp->rx_old].buf)), len); - } + p = dev_alloc_skb(len + 2); + if (!p) return NULL; - return p; + p->dev = dev; + skb_reserve(p, 2); /* Align */ + if (index < lp->rx_old) { /* Wrapped buffer */ + short tlen = (lp->rxRingSize - lp->rx_old) * RX_BUFF_SZ; + memcpy(skb_put(p,tlen), + bus_to_virt(le32_to_cpu(lp->rx_ring[lp->rx_old].buf)),tlen); + memcpy(skb_put(p,len-tlen), + bus_to_virt(le32_to_cpu(lp->rx_ring[0].buf)), len-tlen); + } else { /* Linear buffer */ + memcpy(skb_put(p,len), + bus_to_virt(le32_to_cpu(lp->rx_ring[lp->rx_old].buf)),len); + } + + return p; #endif } -static void de4x5_free_rx_buffs(struct device *dev) +static void +de4x5_free_rx_buffs(struct device *dev) { - struct de4x5_private *lp = (struct de4x5_private *) dev->priv; - int i; + struct de4x5_private *lp = (struct de4x5_private *)dev->priv; + int i; - for (i = 0; i < lp->rxRingSize; i++) { - if ((u_long) lp->rx_skb[i] > 1) { - dev_kfree_skb(lp->rx_skb[i], FREE_WRITE); - } - lp->rx_ring[i].status = 0; - lp->rx_skb[i] = (struct sk_buff *) 1; /* Dummy entry */ + for (i=0; irxRingSize; i++) { + if ((u_long) lp->rx_skb[i] > 1) { + dev_kfree_skb(lp->rx_skb[i], FREE_WRITE); } + lp->rx_ring[i].status = 0; + lp->rx_skb[i] = (struct sk_buff *)1; /* Dummy entry */ + } - return; + return; } -static void de4x5_free_tx_buffs(struct device *dev) +static void +de4x5_free_tx_buffs(struct device *dev) { - struct de4x5_private *lp = (struct de4x5_private *) dev->priv; - int i; + struct de4x5_private *lp = (struct de4x5_private *)dev->priv; + int i; - for (i = 0; i < lp->txRingSize; i++) { - if (lp->tx_skb[i]) { - dev_kfree_skb(lp->tx_skb[i], FREE_WRITE); - lp->tx_skb[i] = NULL; - } - lp->tx_ring[i].status = 0; + for (i=0; itxRingSize; i++) { + if (lp->tx_skb[i]) { + dev_kfree_skb(lp->tx_skb[i], FREE_WRITE); + lp->tx_skb[i] = NULL; } + lp->tx_ring[i].status = 0; + } - /* Unload the locally queued packets */ - while (lp->cache.skb) { - dev_kfree_skb(de4x5_get_cache(dev), FREE_WRITE); - } + /* Unload the locally queued packets */ + while (lp->cache.skb) { + dev_kfree_skb(de4x5_get_cache(dev), FREE_WRITE); + } - return; + return; } /* @@ -3559,321 +3625,339 @@ ** the hardware and software and make any media probes using a loopback ** packet meaningful. */ -static void de4x5_save_skbs(struct device *dev) -{ - struct de4x5_private *lp = (struct de4x5_private *) dev->priv; - u_long iobase = dev->base_addr; - s32 omr; - - if (!lp->cache.save_cnt) { - STOP_DE4X5; - de4x5_tx(dev); /* Flush any sent skb's */ - de4x5_free_tx_buffs(dev); - de4x5_cache_state(dev, DE4X5_SAVE_STATE); - de4x5_sw_reset(dev); - de4x5_cache_state(dev, DE4X5_RESTORE_STATE); - lp->cache.save_cnt++; - START_DE4X5; - } - return; -} - -static void de4x5_restore_skbs(struct device *dev) +static void +de4x5_save_skbs(struct device *dev) { - struct de4x5_private *lp = (struct de4x5_private *) dev->priv; - u_long iobase = dev->base_addr; - int i; - s32 omr; - - if (lp->cache.save_cnt) { - STOP_DE4X5; - outl(virt_to_bus(lp->rx_ring), DE4X5_RRBA); - outl(virt_to_bus(lp->tx_ring), DE4X5_TRBA); - - lp->rx_new = lp->rx_old = 0; - lp->tx_new = lp->tx_old = 0; + struct de4x5_private *lp = (struct de4x5_private *)dev->priv; + u_long iobase = dev->base_addr; + s32 omr; - for (i = 0; i < lp->rxRingSize; i++) { - lp->rx_ring[i].status = cpu_to_le32(R_OWN); - } - - for (i = 0; i < lp->txRingSize; i++) { - lp->tx_ring[i].status = cpu_to_le32(0); - } + if (!lp->cache.save_cnt) { + STOP_DE4X5; + de4x5_tx(dev); /* Flush any sent skb's */ + de4x5_free_tx_buffs(dev); + de4x5_cache_state(dev, DE4X5_SAVE_STATE); + de4x5_sw_reset(dev); + de4x5_cache_state(dev, DE4X5_RESTORE_STATE); + lp->cache.save_cnt++; + START_DE4X5; + } - barrier(); - lp->cache.save_cnt--; - START_DE4X5; - } - return; + return; } -static void de4x5_cache_state(struct device *dev, int flag) +static void +de4x5_rst_desc_ring(struct device *dev) { - struct de4x5_private *lp = (struct de4x5_private *) dev->priv; - u_long iobase = dev->base_addr; - - switch (flag) { - case DE4X5_SAVE_STATE: - lp->cache.csr0 = inl(DE4X5_BMR); - lp->cache.csr6 = (inl(DE4X5_OMR) & ~(OMR_ST | OMR_SR)); - lp->cache.csr7 = inl(DE4X5_IMR); - break; + struct de4x5_private *lp = (struct de4x5_private *)dev->priv; + u_long iobase = dev->base_addr; + int i; + s32 omr; - case DE4X5_RESTORE_STATE: - outl(lp->cache.csr0, DE4X5_BMR); - outl(lp->cache.csr6, DE4X5_OMR); - outl(lp->cache.csr7, DE4X5_IMR); - if (lp->chipset == DC21140) { + if (lp->cache.save_cnt) { + STOP_DE4X5; + outl(virt_to_bus(lp->rx_ring), DE4X5_RRBA); + outl(virt_to_bus(lp->tx_ring), DE4X5_TRBA); + + lp->rx_new = lp->rx_old = 0; + lp->tx_new = lp->tx_old = 0; + + for (i = 0; i < lp->rxRingSize; i++) { + lp->rx_ring[i].status = cpu_to_le32(R_OWN); + } + + for (i = 0; i < lp->txRingSize; i++) { + lp->tx_ring[i].status = cpu_to_le32(0); + } + + barrier(); + lp->cache.save_cnt--; + START_DE4X5; + } + + return; +} + +static void +de4x5_cache_state(struct device *dev, int flag) +{ + struct de4x5_private *lp = (struct de4x5_private *)dev->priv; + u_long iobase = dev->base_addr; + + switch(flag) { + case DE4X5_SAVE_STATE: + lp->cache.csr0 = inl(DE4X5_BMR); + lp->cache.csr6 = (inl(DE4X5_OMR) & ~(OMR_ST | OMR_SR)); + lp->cache.csr7 = inl(DE4X5_IMR); + break; + + case DE4X5_RESTORE_STATE: + outl(lp->cache.csr0, DE4X5_BMR); + outl(lp->cache.csr6, DE4X5_OMR); + outl(lp->cache.csr7, DE4X5_IMR); + if (lp->chipset == DC21140) { gep_wr(lp->cache.gepc, dev); gep_wr(lp->cache.gep, dev); - } else { - reset_init_sia(dev, lp->cache.csr13, lp->cache.csr14, - lp->cache.csr15); - } - break; + } else { + reset_init_sia(dev, lp->cache.csr13, lp->cache.csr14, + lp->cache.csr15); } + break; + } - return; + return; } -static void de4x5_put_cache(struct device *dev, struct sk_buff *skb) +static void +de4x5_put_cache(struct device *dev, struct sk_buff *skb) { - struct de4x5_private *lp = (struct de4x5_private *) dev->priv; - struct sk_buff *p; + struct de4x5_private *lp = (struct de4x5_private *)dev->priv; + struct sk_buff *p; - if (lp->cache.skb) { - for (p = lp->cache.skb; p->next; p = p->next); - p->next = skb; - } else { - lp->cache.skb = skb; - } - skb->next = NULL; + if (lp->cache.skb) { + for (p=lp->cache.skb; p->next; p=p->next); + p->next = skb; + } else { + lp->cache.skb = skb; + } + skb->next = NULL; - return; + return; } -static void de4x5_putb_cache(struct device *dev, struct sk_buff *skb) +static void +de4x5_putb_cache(struct device *dev, struct sk_buff *skb) { - struct de4x5_private *lp = (struct de4x5_private *) dev->priv; - struct sk_buff *p = lp->cache.skb; + struct de4x5_private *lp = (struct de4x5_private *)dev->priv; + struct sk_buff *p = lp->cache.skb; - lp->cache.skb = skb; - skb->next = p; + lp->cache.skb = skb; + skb->next = p; - return; + return; } -static struct sk_buff *de4x5_get_cache(struct device *dev) +static struct sk_buff * +de4x5_get_cache(struct device *dev) { - struct de4x5_private *lp = (struct de4x5_private *) dev->priv; - struct sk_buff *p = lp->cache.skb; + struct de4x5_private *lp = (struct de4x5_private *)dev->priv; + struct sk_buff *p = lp->cache.skb; - if (p) { - lp->cache.skb = p->next; - p->next = NULL; - } - return p; + if (p) { + lp->cache.skb = p->next; + p->next = NULL; + } + + return p; } /* ** Check the Auto Negotiation State. Return OK when a link pass interrupt ** is received and the auto-negotiation status is NWAY OK. */ -static int test_ans(struct device *dev, s32 irqs, s32 irq_mask, s32 msec) +static int +test_ans(struct device *dev, s32 irqs, s32 irq_mask, s32 msec) { - struct de4x5_private *lp = (struct de4x5_private *) dev->priv; - u_long iobase = dev->base_addr; - s32 sts, ans; - - if (lp->timeout < 0) { - lp->timeout = msec / 100; - outl(irq_mask, DE4X5_IMR); - - /* clear all pending interrupts */ - sts = inl(DE4X5_STS); - outl(sts, DE4X5_STS); - } - ans = inl(DE4X5_SISR) & SISR_ANS; - sts = inl(DE4X5_STS) & ~TIMER_CB; - - if (!(sts & irqs) && (ans ^ ANS_NWOK) && --lp->timeout) { - sts = 100 | TIMER_CB; - } else { - lp->timeout = -1; - } - - return sts; + struct de4x5_private *lp = (struct de4x5_private *)dev->priv; + u_long iobase = dev->base_addr; + s32 sts, ans; + + if (lp->timeout < 0) { + lp->timeout = msec/100; + outl(irq_mask, DE4X5_IMR); + + /* clear all pending interrupts */ + sts = inl(DE4X5_STS); + outl(sts, DE4X5_STS); + } + + ans = inl(DE4X5_SISR) & SISR_ANS; + sts = inl(DE4X5_STS) & ~TIMER_CB; + + if (!(sts & irqs) && (ans ^ ANS_NWOK) && --lp->timeout) { + sts = 100 | TIMER_CB; + } else { + lp->timeout = -1; + } + + return sts; } -static void de4x5_setup_intr(struct device *dev) -{ - struct de4x5_private *lp = (struct de4x5_private *) dev->priv; - u_long iobase = dev->base_addr; - s32 imr, sts; - - if (inl(DE4X5_OMR) & OMR_SR) { /* Only unmask if TX/RX is enabled */ - imr = 0; - UNMASK_IRQs; - sts = inl(DE4X5_STS); /* Reset any pending (stale) interrupts */ - outl(sts, DE4X5_STS); - ENABLE_IRQs; - } - return; +static void +de4x5_setup_intr(struct device *dev) +{ + struct de4x5_private *lp = (struct de4x5_private *)dev->priv; + u_long iobase = dev->base_addr; + s32 imr, sts; + + if (inl(DE4X5_OMR) & OMR_SR) { /* Only unmask if TX/RX is enabled */ + imr = 0; + UNMASK_IRQs; + sts = inl(DE4X5_STS); /* Reset any pending (stale) interrupts */ + outl(sts, DE4X5_STS); + ENABLE_IRQs; + } + + return; } /* ** */ -void reset_init_sia(struct device *dev, s32 csr13, s32 csr14, s32 csr15) +static void +reset_init_sia(struct device *dev, s32 csr13, s32 csr14, s32 csr15) { - struct de4x5_private *lp = (struct de4x5_private *) dev->priv; - u_long iobase = dev->base_addr; + struct de4x5_private *lp = (struct de4x5_private *)dev->priv; + u_long iobase = dev->base_addr; - RESET_SIA; - if (lp->useSROM) { - if (lp->ibn == 3) { - srom_exec(dev, lp->phy[lp->active].rst); - srom_exec(dev, lp->phy[lp->active].gep); - outl(1, DE4X5_SICR); - return; - } else { - csr15 = lp->cache.csr15; - csr14 = lp->cache.csr14; - csr13 = lp->cache.csr13; - outl(csr15 | lp->cache.gepc, DE4X5_SIGR); - outl(csr15 | lp->cache.gep, DE4X5_SIGR); - } + RESET_SIA; + if (lp->useSROM) { + if (lp->ibn == 3) { + srom_exec(dev, lp->phy[lp->active].rst); + srom_exec(dev, lp->phy[lp->active].gep); + outl(1, DE4X5_SICR); + return; } else { - outl(csr15, DE4X5_SIGR); - } - outl(csr14, DE4X5_STRR); - outl(csr13, DE4X5_SICR); + csr15 = lp->cache.csr15; + csr14 = lp->cache.csr14; + csr13 = lp->cache.csr13; + outl(csr15 | lp->cache.gepc, DE4X5_SIGR); + outl(csr15 | lp->cache.gep, DE4X5_SIGR); + } + } else { + outl(csr15, DE4X5_SIGR); + } + outl(csr14, DE4X5_STRR); + outl(csr13, DE4X5_SICR); - de4x5_ms_delay(10); + de4x5_ms_delay(10); - return; + return; } /* ** Create a loopback ethernet packet */ -static void create_packet(struct device *dev, char *frame, int len) +static void +create_packet(struct device *dev, char *frame, int len) { - int i; - char *buf = frame; - - for (i = 0; i < ETH_ALEN; i++) { /* Use this source address */ - *buf++ = dev->dev_addr[i]; - } - for (i = 0; i < ETH_ALEN; i++) { /* Use this destination address */ - *buf++ = dev->dev_addr[i]; - } - - *buf++ = 0; /* Packet length (2 bytes) */ - *buf++ = 1; - - return; + int i; + char *buf = frame; + + for (i=0; idev_addr[i]; + } + for (i=0; idev_addr[i]; + } + + *buf++ = 0; /* Packet length (2 bytes) */ + *buf++ = 1; + + return; } /* ** Known delay in microseconds */ -static void de4x5_us_delay(u32 usec) +static void +de4x5_us_delay(u32 usec) { - udelay(usec); - - return; + udelay(usec); + + return; } /* ** Known delay in milliseconds, in millisecond steps. */ -static void de4x5_ms_delay(u32 msec) +static void +de4x5_ms_delay(u32 msec) { - u_int i; - - for (i = 0; i < msec; i++) { - de4x5_us_delay(1000); - } - - return; + u_int i; + + for (i=0; i> 2) & 0x1f) + 0x40); - ManCode[1] = (((Eisa.Id[1] & 0xe0) >> 5) + ((Eisa.Id[0] & 0x03) << 3) + 0x40); - ManCode[2] = (((Eisa.Id[2] >> 4) & 0x0f) + 0x30); - ManCode[3] = ((Eisa.Id[2] & 0x0f) + 0x30); - ManCode[4] = (((Eisa.Id[3] >> 4) & 0x0f) + 0x30); - ManCode[5] = '\0'; - - for (i = 0; i < siglen; i++) { - if (strstr(ManCode, signatures[i]) != NULL) { - strcpy(name, ManCode); - status = 1; - break; - } + c_char *signatures[] = DE4X5_SIGNATURE; + char ManCode[DE4X5_STRLEN]; + union { + s32 ID; + char Id[4]; + } Eisa; + int i, status = 0, siglen = sizeof(signatures)/sizeof(c_char *); + + *name = '\0'; + Eisa.ID = inl(eisa_id); + + ManCode[0]=(((Eisa.Id[0]>>2)&0x1f)+0x40); + ManCode[1]=(((Eisa.Id[1]&0xe0)>>5)+((Eisa.Id[0]&0x03)<<3)+0x40); + ManCode[2]=(((Eisa.Id[2]>>4)&0x0f)+0x30); + ManCode[3]=((Eisa.Id[2]&0x0f)+0x30); + ManCode[4]=(((Eisa.Id[3]>>4)&0x0f)+0x30); + ManCode[5]='\0'; + + for (i=0;ichipset == DC21040) { - strcpy(name, "DE434/5"); - return status; - } else { /* Search for a DEC name in the SROM */ - int i = *((char *) &lp->srom + 19) * 3; - strncpy(name, (char *) &lp->srom + 26 + i, 8); - } - name[8] = '\0'; - for (i = 0; i < siglen; i++) { - if (strstr(name, de4x5_signatures[i]) != NULL) - break; - } - if (i == siglen) { - if (dec_only) { - *name = '\0'; - } else { /* Use chip name to avoid confusion */ - strcpy(name, (((lp->chipset == DC21040) ? "DC21040" : - ((lp->chipset == DC21041) ? "DC21041" : - ((lp->chipset == DC21140) ? "DC21140" : - ((lp->chipset == DC21142) ? "DC21142" : - ((lp->chipset == DC21143) ? "DC21143" : "UNKNOWN" - ))))))); - } - if (lp->chipset != DC21041) { - useSROM = TRUE; /* card is not recognisably DEC */ - } - } else if ((lp->chipset & ~0x00ff) == DC2114x) { - useSROM = TRUE; - } - + c_char *de4x5_signatures[] = DE4X5_SIGNATURE; + int i, status = 0, siglen = sizeof(de4x5_signatures)/sizeof(c_char *); + + if (lp->chipset == DC21040) { + strcpy(name, "DE434/5"); return status; + } else { /* Search for a DEC name in the SROM */ + int i = *((char *)&lp->srom + 19) * 3; + strncpy(name, (char *)&lp->srom + 26 + i, 8); + } + name[8] = '\0'; + for (i=0; ichipset == DC21040) ? "DC21040" : + ((lp->chipset == DC21041) ? "DC21041" : + ((lp->chipset == DC21140) ? "DC21140" : + ((lp->chipset == DC21142) ? "DC21142" : + ((lp->chipset == DC21143) ? "DC21143" : "UNKNOWN" + ))))))); + } + if (lp->chipset != DC21041) { + useSROM = TRUE; /* card is not recognisably DEC */ + } + } else if ((lp->chipset & ~0x00ff) == DC2114x) { + useSROM = TRUE; + } + + return status; } /* @@ -3884,33 +3968,34 @@ ** immediately with the prior srom contents intact (the h/w address will ** be fixed up later). */ -static void DevicePresent(u_long aprom_addr) +static void +DevicePresent(u_long aprom_addr) { - int i, j=0; - struct bus_type *lp = &bus; - - if (lp->chipset == DC21040) { - outl(0, aprom_addr); /* Reset Ethernet Address ROM Pointer */ - } else { /* Read new srom */ - u_short tmp, *p = (short *)((char *)&lp->srom + SROM_HWADD); - for (i=0; i<(ETH_ALEN>>1); i++) { - tmp = srom_rd(aprom_addr, (SROM_HWADD>>1) + i); - *p = le16_to_cpu(tmp); - j += *p++; - } - if ((j == 0) || (j == 0x2fffd)) { - return; - } - - p=(short *)&lp->srom; - for (i = 0; i < (sizeof(struct de4x5_srom) >> 1); i++) { - tmp = srom_rd(aprom_addr, i); - *p++ = le16_to_cpu(tmp); - } - de4x5_dbg_srom((struct de4x5_srom *) &lp->srom); + int i, j=0; + struct bus_type *lp = &bus; + + if (lp->chipset == DC21040) { + outl(0, aprom_addr); /* Reset Ethernet Address ROM Pointer */ + } else { /* Read new srom */ + u_short tmp, *p = (short *)((char *)&lp->srom + SROM_HWADD); + for (i=0; i<(ETH_ALEN>>1); i++) { + tmp = srom_rd(aprom_addr, (SROM_HWADD>>1) + i); + *p = le16_to_cpu(tmp); + j += *p++; + } + if ((j == 0) || (j == 0x2fffd)) { + return; + } + + p=(short *)&lp->srom; + for (i=0; i<(sizeof(struct de4x5_srom)>>1); i++) { + tmp = srom_rd(aprom_addr, i); + *p++ = le16_to_cpu(tmp); } - - return; + de4x5_dbg_srom((struct de4x5_srom *)&lp->srom); + } + + return; } /* @@ -3919,302 +4004,303 @@ ** as one or more of the bytes. Only the last 3 bytes should be checked ** as the first three are invariant - assigned to an organisation. */ -static int get_hw_addr(struct device *dev) +static int +get_hw_addr(struct device *dev) { - u_long iobase = dev->base_addr; - int broken, i, k, tmp, status = 0; - u_short j, chksum; - struct bus_type *lp = &bus; - - broken = de4x5_bad_srom(lp); - - for (i = 0, k = 0, j = 0; j < 3; j++) { - k <<= 1; - if (k > 0xffff) - k -= 0xffff; - - if (lp->bus == PCI) { - if (lp->chipset == DC21040) { - while ((tmp = inl(DE4X5_APROM)) < 0); - k += (u_char) tmp; - dev->dev_addr[i++] = (u_char) tmp; - while ((tmp = inl(DE4X5_APROM)) < 0); - k += (u_short) (tmp << 8); - dev->dev_addr[i++] = (u_char) tmp; - } else if (!broken) { - dev->dev_addr[i] = (u_char) lp->srom.ieee_addr[i]; - i++; - dev->dev_addr[i] = (u_char) lp->srom.ieee_addr[i]; - i++; - } else if ((broken == SMC) || (broken == ACCTON)) { - dev->dev_addr[i] = *((u_char *) & lp->srom + i); - i++; - dev->dev_addr[i] = *((u_char *) & lp->srom + i); - i++; - } - } else { - k += (u_char) (tmp = inb(EISA_APROM)); - dev->dev_addr[i++] = (u_char) tmp; - k += (u_short) ((tmp = inb(EISA_APROM)) << 8); - dev->dev_addr[i++] = (u_char) tmp; - } - - if (k > 0xffff) - k -= 0xffff; - } - if (k == 0xffff) - k = 0; - + u_long iobase = dev->base_addr; + int broken, i, k, tmp, status = 0; + u_short j,chksum; + struct bus_type *lp = &bus; + + broken = de4x5_bad_srom(lp); + + for (i=0,k=0,j=0;j<3;j++) { + k <<= 1; + if (k > 0xffff) k-=0xffff; + if (lp->bus == PCI) { - if (lp->chipset == DC21040) { - while ((tmp = inl(DE4X5_APROM)) < 0); - chksum = (u_char) tmp; - while ((tmp = inl(DE4X5_APROM)) < 0); - chksum |= (u_short) (tmp << 8); - if ((k != chksum) && (dec_only)) - status = -1; - } + if (lp->chipset == DC21040) { + while ((tmp = inl(DE4X5_APROM)) < 0); + k += (u_char) tmp; + dev->dev_addr[i++] = (u_char) tmp; + while ((tmp = inl(DE4X5_APROM)) < 0); + k += (u_short) (tmp << 8); + dev->dev_addr[i++] = (u_char) tmp; + } else if (!broken) { + dev->dev_addr[i] = (u_char) lp->srom.ieee_addr[i]; i++; + dev->dev_addr[i] = (u_char) lp->srom.ieee_addr[i]; i++; + } else if ((broken == SMC) || (broken == ACCTON)) { + dev->dev_addr[i] = *((u_char *)&lp->srom + i); i++; + dev->dev_addr[i] = *((u_char *)&lp->srom + i); i++; + } } else { - chksum = (u_char) inb(EISA_APROM); - chksum |= (u_short) (inb(EISA_APROM) << 8); - if ((k != chksum) && (dec_only)) - status = -1; + k += (u_char) (tmp = inb(EISA_APROM)); + dev->dev_addr[i++] = (u_char) tmp; + k += (u_short) ((tmp = inb(EISA_APROM)) << 8); + dev->dev_addr[i++] = (u_char) tmp; } + + if (k > 0xffff) k-=0xffff; + } + if (k == 0xffff) k=0; + + if (lp->bus == PCI) { + if (lp->chipset == DC21040) { + while ((tmp = inl(DE4X5_APROM)) < 0); + chksum = (u_char) tmp; + while ((tmp = inl(DE4X5_APROM)) < 0); + chksum |= (u_short) (tmp << 8); + if ((k != chksum) && (dec_only)) status = -1; + } + } else { + chksum = (u_char) inb(EISA_APROM); + chksum |= (u_short) (inb(EISA_APROM) << 8); + if ((k != chksum) && (dec_only)) status = -1; + } - /* If possible, try to fix a broken card - SMC only so far */ - srom_repair(dev, broken); + /* If possible, try to fix a broken card - SMC only so far */ + srom_repair(dev, broken); - /* Test for a bad enet address */ - status = test_bad_enet(dev, status); + /* Test for a bad enet address */ + status = test_bad_enet(dev, status); - return status; + return status; } /* ** Test for enet addresses in the first 32 bytes. The built-in strncmp ** didn't seem to work here...? */ -static int de4x5_bad_srom(struct bus_type *lp) +static int +de4x5_bad_srom(struct bus_type *lp) { - int i, status = 0; + int i, status = 0; - for (i = 0; i < sizeof(enet_det) / ETH_ALEN; i++) { - if (!de4x5_strncmp((char *) &lp->srom, (char *) &enet_det[i], 3) && - !de4x5_strncmp((char *) &lp->srom + 0x10, (char *) &enet_det[i], 3)) { - if (i == 0) { - status = SMC; - } else if (i == 1) { - status = ACCTON; - } - break; - } + for (i=0; isrom, (char *)&enet_det[i], 3) && + !de4x5_strncmp((char *)&lp->srom+0x10, (char *)&enet_det[i], 3)) { + if (i == 0) { + status = SMC; + } else if (i == 1) { + status = ACCTON; + } + break; } + } - return status; + return status; } -static int de4x5_strncmp(char *a, char *b, int n) +static int +de4x5_strncmp(char *a, char *b, int n) { - int ret = 0; + int ret=0; - for (; n && !ret; n--) { - ret = *a++ - *b++; - } + for (;n && !ret;n--) { + ret = *a++ - *b++; + } - return ret; + return ret; } -static void srom_repair(struct device *dev, int card) +static void +srom_repair(struct device *dev, int card) { - struct bus_type *lp = &bus; + struct bus_type *lp = &bus; - switch (card) { - case SMC: - memset((char *) &bus.srom, 0, sizeof(struct de4x5_srom)); - memcpy(lp->srom.ieee_addr, (char *) dev->dev_addr, ETH_ALEN); - memcpy(lp->srom.info, (char *) &srom_repair_info[SMC - 1], 100); - useSROM = TRUE; - break; - } + switch(card) { + case SMC: + memset((char *)&bus.srom, 0, sizeof(struct de4x5_srom)); + memcpy(lp->srom.ieee_addr, (char *)dev->dev_addr, ETH_ALEN); + memcpy(lp->srom.info, (char *)&srom_repair_info[SMC-1], 100); + useSROM = TRUE; + break; + } - return; + return; } /* ** Assume that the irq's do not follow the PCI spec - this is seems ** to be true so far (2 for 2). */ -static int test_bad_enet(struct device *dev, int status) +static int +test_bad_enet(struct device *dev, int status) { - struct bus_type *lp = &bus; - int i, tmp; + struct bus_type *lp = &bus; + int i, tmp; - for (tmp = 0, i = 0; i < ETH_ALEN; i++) - tmp += (u_char) dev->dev_addr[i]; - if ((tmp == 0) || (tmp == 0x5fa)) { - if ((lp->chipset == last.chipset) && - (lp->bus_num == last.bus) && (lp->bus_num > 0)) { - for (i = 0; i < ETH_ALEN; i++) - dev->dev_addr[i] = last.addr[i]; - for (i = ETH_ALEN - 1; i > 2; --i) { - dev->dev_addr[i] += 1; - if (dev->dev_addr[i] != 0) - break; - } - for (i = 0; i < ETH_ALEN; i++) - last.addr[i] = dev->dev_addr[i]; - dev->irq = last.irq; + for (tmp=0,i=0; idev_addr[i]; + if ((tmp == 0) || (tmp == 0x5fa)) { + if ((lp->chipset == last.chipset) && + (lp->bus_num == last.bus) && (lp->bus_num > 0)) { + for (i=0; idev_addr[i] = last.addr[i]; + for (i=ETH_ALEN-1; i>2; --i) { + dev->dev_addr[i] += 1; + if (dev->dev_addr[i] != 0) break; + } + for (i=0; idev_addr[i]; + dev->irq = last.irq; + + status = 0; + } + } else if (!status) { + last.chipset = lp->chipset; + last.bus = lp->bus_num; + last.irq = dev->irq; + for (i=0; idev_addr[i]; + } - status = 0; - } - } else if (!status) { - last.chipset = lp->chipset; - last.bus = lp->bus_num; - last.irq = dev->irq; - for (i = 0; i < ETH_ALEN; i++) - last.addr[i] = dev->dev_addr[i]; - } - return status; + return status; } /* ** SROM Read */ -static short srom_rd(u_long addr, u_char offset) +static short +srom_rd(u_long addr, u_char offset) { - sendto_srom(SROM_RD | SROM_SR, addr); - - srom_latch(SROM_RD | SROM_SR | DT_CS, addr); - srom_command(SROM_RD | SROM_SR | DT_IN | DT_CS, addr); - srom_address(SROM_RD | SROM_SR | DT_CS, addr, offset); - - return srom_data(SROM_RD | SROM_SR | DT_CS, addr); + sendto_srom(SROM_RD | SROM_SR, addr); + + srom_latch(SROM_RD | SROM_SR | DT_CS, addr); + srom_command(SROM_RD | SROM_SR | DT_IN | DT_CS, addr); + srom_address(SROM_RD | SROM_SR | DT_CS, addr, offset); + + return srom_data(SROM_RD | SROM_SR | DT_CS, addr); } -static void srom_latch(u_int command, u_long addr) +static void +srom_latch(u_int command, u_long addr) { - sendto_srom(command, addr); - sendto_srom(command | DT_CLK, addr); - sendto_srom(command, addr); - - return; + sendto_srom(command, addr); + sendto_srom(command | DT_CLK, addr); + sendto_srom(command, addr); + + return; } -static void srom_command(u_int command, u_long addr) +static void +srom_command(u_int command, u_long addr) { - srom_latch(command, addr); - srom_latch(command, addr); - srom_latch((command & 0x0000ff00) | DT_CS, addr); - - return; + srom_latch(command, addr); + srom_latch(command, addr); + srom_latch((command & 0x0000ff00) | DT_CS, addr); + + return; } -static void srom_address(u_int command, u_long addr, u_char offset) +static void +srom_address(u_int command, u_long addr, u_char offset) { - int i; - char a; - - a = (char) (offset << 2); - for (i = 0; i < 6; i++, a <<= 1) { - srom_latch(command | ((a < 0) ? DT_IN : 0), addr); - } - de4x5_us_delay(1); - - i = (getfrom_srom(addr) >> 3) & 0x01; - return; + int i; + char a; + + a = (char)(offset << 2); + for (i=0; i<6; i++, a <<= 1) { + srom_latch(command | ((a < 0) ? DT_IN : 0), addr); + } + de4x5_us_delay(1); + + i = (getfrom_srom(addr) >> 3) & 0x01; + + return; } -static short srom_data(u_int command, u_long addr) +static short +srom_data(u_int command, u_long addr) { - int i; - short word = 0; - s32 tmp; - - for (i = 0; i < 16; i++) { - sendto_srom(command | DT_CLK, addr); - tmp = getfrom_srom(addr); - sendto_srom(command, addr); - - word = (word << 1) | ((tmp >> 3) & 0x01); - } - - sendto_srom(command & 0x0000ff00, addr); - - return word; + int i; + short word = 0; + s32 tmp; + + for (i=0; i<16; i++) { + sendto_srom(command | DT_CLK, addr); + tmp = getfrom_srom(addr); + sendto_srom(command, addr); + + word = (word << 1) | ((tmp >> 3) & 0x01); + } + + sendto_srom(command & 0x0000ff00, addr); + + return word; } /* - static void - srom_busy(u_int command, u_long addr) - { +static void +srom_busy(u_int command, u_long addr) +{ sendto_srom((command & 0x0000ff00) | DT_CS, addr); - + while (!((getfrom_srom(addr) >> 3) & 0x01)) { - de4x5_ms_delay(1); + de4x5_ms_delay(1); } - + sendto_srom(command & 0x0000ff00, addr); - + return; - } - */ +} +*/ -static void sendto_srom(u_int command, u_long addr) +static void +sendto_srom(u_int command, u_long addr) { - outl(command, addr); - udelay(1); - - return; + outl(command, addr); + udelay(1); + + return; } -static int getfrom_srom(u_long addr) +static int +getfrom_srom(u_long addr) { - s32 tmp; - - tmp = inl(addr); - udelay(1); - - return tmp; + s32 tmp; + + tmp = inl(addr); + udelay(1); + + return tmp; } -static int srom_infoleaf_info(struct device *dev) +static int +srom_infoleaf_info(struct device *dev) { - struct de4x5_private *lp = (struct de4x5_private *) dev->priv; - int i, count; - u_char *p; - - /* Find the infoleaf decoder function that matches this chipset */ - for (i = 0; i < INFOLEAF_SIZE; i++) { - if (lp->chipset == infoleaf_array[i].chipset) - break; - } - if (i == INFOLEAF_SIZE) { - lp->useSROM = FALSE; - printk("%s: Cannot find correct chipset for SROM decoding!\n", - dev->name); - return -ENXIO; + struct de4x5_private *lp = (struct de4x5_private *)dev->priv; + int i, count; + u_char *p; + + /* Find the infoleaf decoder function that matches this chipset */ + for (i=0; ichipset == infoleaf_array[i].chipset) break; + } + if (i == INFOLEAF_SIZE) { + lp->useSROM = FALSE; + printk("%s: Cannot find correct chipset for SROM decoding!\n", + dev->name); + return -ENXIO; + } + + lp->infoleaf_fn = infoleaf_array[i].fn; + + /* Find the information offset that this function should use */ + count = *((u_char *)&lp->srom + 19); + p = (u_char *)&lp->srom + 26; + + if (count > 1) { + for (i=count; i; --i, p+=3) { + if (lp->device == *p) break; + } + if (i == 0) { + lp->useSROM = FALSE; + printk("%s: Cannot find correct PCI device [%d] for SROM decoding!\n", + dev->name, lp->device); + return -ENXIO; } - lp->infoleaf_fn = infoleaf_array[i].fn; + } - /* Find the information offset that this function should use */ - count = *((u_char *) & lp->srom + 19); - p = (u_char *) & lp->srom + 26; - - if (count > 1) { - for (i = count; i; --i, p += 3) { - if (lp->device == *p) - break; - } - if (i == 0) { - lp->useSROM = FALSE; - printk("%s: Cannot find correct PCI device [%d] for SROM decoding!\n", - dev->name, lp->device); - return -ENXIO; - } - } - lp->infoleaf_offset = TWIDDLE(p + 1); + lp->infoleaf_offset = TWIDDLE(p+1); - return 0; + return 0; } /* @@ -4224,74 +4310,75 @@ ** The info for the MII devices will be valid since the index used ** will follow the discovery process from MII address 1-31 then 0. */ -static void srom_init(struct device *dev) +static void +srom_init(struct device *dev) { - struct de4x5_private *lp = (struct de4x5_private *) dev->priv; - u_char *p = (u_char *) & lp->srom + lp->infoleaf_offset; - u_char count; + struct de4x5_private *lp = (struct de4x5_private *)dev->priv; + u_char *p = (u_char *)&lp->srom + lp->infoleaf_offset; + u_char count; - p += 2; - if (lp->chipset == DC21140) { - lp->cache.gepc = (*p++ | GEP_CTRL); - gep_wr(lp->cache.gepc, dev); - } - /* Block count */ - count = *p++; + p+=2; + if (lp->chipset == DC21140) { + lp->cache.gepc = (*p++ | GEP_CTRL); + gep_wr(lp->cache.gepc, dev); + } - /* Jump the infoblocks to find types */ - for (; count; --count) { - if (*p < 128) { - p += COMPACT_LEN; - } else if (*(p + 1) == 5) { - type5_infoblock(dev, 1, p); - p += ((*p & BLOCK_LEN) + 1); - } else if (*(p+1) == 4) { - p += ((*p & BLOCK_LEN) + 1); - } else if (*(p + 1) == 3) { - type3_infoblock(dev, 1, p); - p += ((*p & BLOCK_LEN) + 1); - } else if (*(p+1) == 2) { - p += ((*p & BLOCK_LEN) + 1); - } else if (*(p + 1) == 1) { - type1_infoblock(dev, 1, p); - p += ((*p & BLOCK_LEN) + 1); - } else { - p += ((*p & BLOCK_LEN) + 1); - } + /* Block count */ + count = *p++; + + /* Jump the infoblocks to find types */ + for (;count; --count) { + if (*p < 128) { + p += COMPACT_LEN; + } else if (*(p+1) == 5) { + type5_infoblock(dev, 1, p); + p += ((*p & BLOCK_LEN) + 1); + } else if (*(p+1) == 4) { + p += ((*p & BLOCK_LEN) + 1); + } else if (*(p+1) == 3) { + type3_infoblock(dev, 1, p); + p += ((*p & BLOCK_LEN) + 1); + } else if (*(p+1) == 2) { + p += ((*p & BLOCK_LEN) + 1); + } else if (*(p+1) == 1) { + type1_infoblock(dev, 1, p); + p += ((*p & BLOCK_LEN) + 1); + } else { + p += ((*p & BLOCK_LEN) + 1); } + } - return; + return; } /* ** A generic routine that writes GEP control, data and reset information ** to the GEP register (21140) or csr15 GEP portion (2114[23]). */ -static void srom_exec(struct device *dev, u_char * p) +static void +srom_exec(struct device *dev, u_char *p) { - struct de4x5_private *lp = (struct de4x5_private *) dev->priv; - u_long iobase = dev->base_addr; - u_char count = (p ? *p++ : 0); - u_short *w = (u_short *)p; + struct de4x5_private *lp = (struct de4x5_private *)dev->priv; + u_long iobase = dev->base_addr; + u_char count = (p ? *p++ : 0); + u_short *w = (u_short *)p; - if (((lp->ibn != 1) && (lp->ibn != 3) && (lp->ibn != 5)) || !count) - return; + if (((lp->ibn != 1) && (lp->ibn != 3) && (lp->ibn != 5)) || !count) return; - if (lp->chipset != DC21140) - RESET_SIA; + if (lp->chipset != DC21140) RESET_SIA; - while (count--) { - gep_wr(((lp->chipset==DC21140) && (lp->ibn!=5) ? - *p++ : TWIDDLE(w++)), dev); - udelay(2000); /* 2ms per action */ - } + while (count--) { + gep_wr(((lp->chipset==DC21140) && (lp->ibn!=5) ? + *p++ : TWIDDLE(w++)), dev); + udelay(2000); /* 2ms per action */ + } + + if (lp->chipset != DC21140) { + outl(lp->cache.csr14, DE4X5_STRR); + outl(lp->cache.csr13, DE4X5_SICR); + } - if (lp->chipset != DC21140) { - outl(lp->cache.csr14, DE4X5_STRR); - outl(lp->cache.csr13, DE4X5_SICR); - } - - return; + return; } /* @@ -4299,944 +4386,1022 @@ ** unless I implement the DC21041 SROM functions. There's no need ** since the existing code will be satisfactory for all boards. */ -static int dc21041_infoleaf(struct device *dev) +static int +dc21041_infoleaf(struct device *dev) { - return DE4X5_AUTOSENSE_MS; + return DE4X5_AUTOSENSE_MS; } -static int dc21140_infoleaf(struct device *dev) +static int +dc21140_infoleaf(struct device *dev) { - struct de4x5_private *lp = (struct de4x5_private *) dev->priv; - u_char count = 0; - u_char *p = (u_char *) & lp->srom + lp->infoleaf_offset; - int next_tick = DE4X5_AUTOSENSE_MS; + struct de4x5_private *lp = (struct de4x5_private *)dev->priv; + u_char count = 0; + u_char *p = (u_char *)&lp->srom + lp->infoleaf_offset; + int next_tick = DE4X5_AUTOSENSE_MS; - /* Read the connection type */ - p += 2; + /* Read the connection type */ + p+=2; - /* GEP control */ - lp->cache.gepc = (*p++ | GEP_CTRL); + /* GEP control */ + lp->cache.gepc = (*p++ | GEP_CTRL); - /* Block count */ - count = *p++; + /* Block count */ + count = *p++; - /* Recursively figure out the info blocks */ - if (*p < 128) { - next_tick = dc_infoblock[COMPACT] (dev, count, p); - } else { - next_tick = dc_infoblock[*(p + 1)] (dev, count, p); - } + /* Recursively figure out the info blocks */ + if (*p < 128) { + next_tick = dc_infoblock[COMPACT](dev, count, p); + } else { + next_tick = dc_infoblock[*(p+1)](dev, count, p); + } - if (lp->tcount == count) { - lp->media = NC; - if (lp->media != lp->c_media) { - de4x5_dbg_media(dev); - lp->c_media = lp->media; - } - lp->media = INIT; - lp->tcount = 0; - lp->tx_enable = FALSE; + if (lp->tcount == count) { + lp->media = NC; + if (lp->media != lp->c_media) { + de4x5_dbg_media(dev); + lp->c_media = lp->media; } - return next_tick & ~TIMER_CB; + lp->media = INIT; + lp->tcount = 0; + lp->tx_enable = FALSE; + } + + return next_tick & ~TIMER_CB; } -static int dc21142_infoleaf(struct device *dev) +static int +dc21142_infoleaf(struct device *dev) { - struct de4x5_private *lp = (struct de4x5_private *)dev->priv; - u_char count = 0; - u_char *p = (u_char *)&lp->srom + lp->infoleaf_offset; - int next_tick = DE4X5_AUTOSENSE_MS; - - /* Read the connection type */ - p+=2; - - /* Block count */ - count = *p++; - - /* Recursively figure out the info blocks */ - if (*p < 128) { - next_tick = dc_infoblock[COMPACT](dev, count, p); - } else { - next_tick = dc_infoblock[*(p+1)](dev, count, p); - } - - if (lp->tcount == count) { - lp->media = NC; - if (lp->media != lp->c_media) { - de4x5_dbg_media(dev); - lp->c_media = lp->media; - } - lp->media = INIT; - lp->tcount = 0; - lp->tx_enable = FALSE; + struct de4x5_private *lp = (struct de4x5_private *)dev->priv; + u_char count = 0; + u_char *p = (u_char *)&lp->srom + lp->infoleaf_offset; + int next_tick = DE4X5_AUTOSENSE_MS; + + /* Read the connection type */ + p+=2; + + /* Block count */ + count = *p++; + + /* Recursively figure out the info blocks */ + if (*p < 128) { + next_tick = dc_infoblock[COMPACT](dev, count, p); + } else { + next_tick = dc_infoblock[*(p+1)](dev, count, p); + } + + if (lp->tcount == count) { + lp->media = NC; + if (lp->media != lp->c_media) { + de4x5_dbg_media(dev); + lp->c_media = lp->media; } + lp->media = INIT; + lp->tcount = 0; + lp->tx_enable = FALSE; + } - return next_tick & ~TIMER_CB; + return next_tick & ~TIMER_CB; } -static int dc21143_infoleaf(struct device *dev) +static int +dc21143_infoleaf(struct device *dev) { - struct de4x5_private *lp = (struct de4x5_private *)dev->priv; - u_char count = 0; - u_char *p = (u_char *)&lp->srom + lp->infoleaf_offset; - int next_tick = DE4X5_AUTOSENSE_MS; - - /* Read the connection type */ - p+=2; - - /* Block count */ - count = *p++; - - /* Recursively figure out the info blocks */ - if (*p < 128) { - next_tick = dc_infoblock[COMPACT](dev, count, p); - } else { - next_tick = dc_infoblock[*(p+1)](dev, count, p); - } - if (lp->tcount == count) { - lp->media = NC; - if (lp->media != lp->c_media) { - de4x5_dbg_media(dev); - lp->c_media = lp->media; - } - lp->media = INIT; - lp->tcount = 0; - lp->tx_enable = FALSE; + struct de4x5_private *lp = (struct de4x5_private *)dev->priv; + u_char count = 0; + u_char *p = (u_char *)&lp->srom + lp->infoleaf_offset; + int next_tick = DE4X5_AUTOSENSE_MS; + + /* Read the connection type */ + p+=2; + + /* Block count */ + count = *p++; + + /* Recursively figure out the info blocks */ + if (*p < 128) { + next_tick = dc_infoblock[COMPACT](dev, count, p); + } else { + next_tick = dc_infoblock[*(p+1)](dev, count, p); + } + if (lp->tcount == count) { + lp->media = NC; + if (lp->media != lp->c_media) { + de4x5_dbg_media(dev); + lp->c_media = lp->media; } + lp->media = INIT; + lp->tcount = 0; + lp->tx_enable = FALSE; + } - return next_tick & ~TIMER_CB; + return next_tick & ~TIMER_CB; } /* ** The compact infoblock is only designed for DC21140[A] chips, so ** we'll reuse the dc21140m_autoconf function. Non MII media only. */ -static int compact_infoblock(struct device *dev, u_char count, u_char * p) +static int +compact_infoblock(struct device *dev, u_char count, u_char *p) { - struct de4x5_private *lp = (struct de4x5_private *) dev->priv; - u_char flags, csr6; + struct de4x5_private *lp = (struct de4x5_private *)dev->priv; + u_char flags, csr6; - /* Recursively figure out the info blocks */ - if (--count > lp->tcount) { - if (*(p + COMPACT_LEN) < 128) { - return dc_infoblock[COMPACT] (dev, count, p + COMPACT_LEN); - } else { - return dc_infoblock[*(p + COMPACT_LEN + 1)] (dev, count, p + COMPACT_LEN); - } + /* Recursively figure out the info blocks */ + if (--count > lp->tcount) { + if (*(p+COMPACT_LEN) < 128) { + return dc_infoblock[COMPACT](dev, count, p+COMPACT_LEN); + } else { + return dc_infoblock[*(p+COMPACT_LEN+1)](dev, count, p+COMPACT_LEN); } - if ((lp->media == INIT) && (lp->timeout < 0)) { - lp->ibn = COMPACT; - lp->active = 0; - gep_wr(lp->cache.gepc, dev); - lp->infoblock_media = (*p++) & COMPACT_MC; - lp->cache.gep = *p++; - csr6 = *p++; - flags = *p++; - - lp->asBitValid = (flags & 0x80) ? 0 : -1; - lp->defMedium = (flags & 0x40) ? -1 : 0; - lp->asBit = 1 << ((csr6 >> 1) & 0x07); - lp->asPolarity = ((csr6 & 0x80) ? -1 : 0) & lp->asBit; - lp->infoblock_csr6 = OMR_DEF | ((csr6 & 0x71) << 18); - lp->useMII = FALSE; + } - de4x5_switch_mac_port(dev); - } - return dc21140m_autoconf(dev); + if ((lp->media == INIT) && (lp->timeout < 0)) { + lp->ibn = COMPACT; + lp->active = 0; + gep_wr(lp->cache.gepc, dev); + lp->infoblock_media = (*p++) & COMPACT_MC; + lp->cache.gep = *p++; + csr6 = *p++; + flags = *p++; + + lp->asBitValid = (flags & 0x80) ? 0 : -1; + lp->defMedium = (flags & 0x40) ? -1 : 0; + lp->asBit = 1 << ((csr6 >> 1) & 0x07); + lp->asPolarity = ((csr6 & 0x80) ? -1 : 0) & lp->asBit; + lp->infoblock_csr6 = OMR_DEF | ((csr6 & 0x71) << 18); + lp->useMII = FALSE; + + de4x5_switch_mac_port(dev); + } + + return dc21140m_autoconf(dev); } /* ** This block describes non MII media for the DC21140[A] only. */ -static int type0_infoblock(struct device *dev, u_char count, u_char * p) +static int +type0_infoblock(struct device *dev, u_char count, u_char *p) { - struct de4x5_private *lp = (struct de4x5_private *) dev->priv; - u_char flags, csr6, len = (*p & BLOCK_LEN) + 1; + struct de4x5_private *lp = (struct de4x5_private *)dev->priv; + u_char flags, csr6, len = (*p & BLOCK_LEN)+1; - /* Recursively figure out the info blocks */ - if (--count > lp->tcount) { - if (*(p + len) < 128) { - return dc_infoblock[COMPACT] (dev, count, p + len); - } else { - return dc_infoblock[*(p + len + 1)] (dev, count, p + len); - } + /* Recursively figure out the info blocks */ + if (--count > lp->tcount) { + if (*(p+len) < 128) { + return dc_infoblock[COMPACT](dev, count, p+len); + } else { + return dc_infoblock[*(p+len+1)](dev, count, p+len); } - if ((lp->media == INIT) && (lp->timeout < 0)) { - lp->ibn = 0; - lp->active = 0; - gep_wr(lp->cache.gepc, dev); - p += 2; - lp->infoblock_media = (*p++) & BLOCK0_MC; - lp->cache.gep = *p++; - csr6 = *p++; - flags = *p++; - - lp->asBitValid = (flags & 0x80) ? 0 : -1; - lp->defMedium = (flags & 0x40) ? -1 : 0; - lp->asBit = 1 << ((csr6 >> 1) & 0x07); - lp->asPolarity = ((csr6 & 0x80) ? -1 : 0) & lp->asBit; - lp->infoblock_csr6 = OMR_DEF | ((csr6 & 0x71) << 18); - lp->useMII = FALSE; + } - de4x5_switch_mac_port(dev); - } - return dc21140m_autoconf(dev); + if ((lp->media == INIT) && (lp->timeout < 0)) { + lp->ibn = 0; + lp->active = 0; + gep_wr(lp->cache.gepc, dev); + p+=2; + lp->infoblock_media = (*p++) & BLOCK0_MC; + lp->cache.gep = *p++; + csr6 = *p++; + flags = *p++; + + lp->asBitValid = (flags & 0x80) ? 0 : -1; + lp->defMedium = (flags & 0x40) ? -1 : 0; + lp->asBit = 1 << ((csr6 >> 1) & 0x07); + lp->asPolarity = ((csr6 & 0x80) ? -1 : 0) & lp->asBit; + lp->infoblock_csr6 = OMR_DEF | ((csr6 & 0x71) << 18); + lp->useMII = FALSE; + + de4x5_switch_mac_port(dev); + } + + return dc21140m_autoconf(dev); } /* These functions are under construction! */ -static int type1_infoblock(struct device *dev, u_char count, u_char * p) +static int +type1_infoblock(struct device *dev, u_char count, u_char *p) { - struct de4x5_private *lp = (struct de4x5_private *) dev->priv; - u_char len = (*p & BLOCK_LEN) + 1; + struct de4x5_private *lp = (struct de4x5_private *)dev->priv; + u_char len = (*p & BLOCK_LEN)+1; - /* Recursively figure out the info blocks */ - if (--count > lp->tcount) { - if (*(p + len) < 128) { - return dc_infoblock[COMPACT] (dev, count, p + len); - } else { - return dc_infoblock[*(p + len + 1)] (dev, count, p + len); - } - } - p += 2; - if (lp->state == INITIALISED) { - lp->active = *p++; - lp->phy[lp->active].gep = (*p ? p : 0); - p += (*p + 1); - lp->phy[lp->active].rst = (*p ? p : 0); - p += (*p + 1); - lp->phy[lp->active].mc = TWIDDLE(p); - p += 2; - lp->phy[lp->active].ana = TWIDDLE(p); - p += 2; - lp->phy[lp->active].fdx = TWIDDLE(p); - p += 2; - lp->phy[lp->active].ttm = TWIDDLE(p); - return 0; - } else if ((lp->media == INIT) && (lp->timeout < 0)) { - lp->ibn = 1; - lp->active = *p; - lp->infoblock_csr6 = OMR_MII_100; - lp->useMII = TRUE; - lp->infoblock_media = ANS; - lp->media = ANS; - de4x5_switch_mac_port(dev); + /* Recursively figure out the info blocks */ + if (--count > lp->tcount) { + if (*(p+len) < 128) { + return dc_infoblock[COMPACT](dev, count, p+len); + } else { + return dc_infoblock[*(p+len+1)](dev, count, p+len); } - return dc21140m_autoconf(dev); + } + + p += 2; + if (lp->state == INITIALISED) { + lp->active = *p++; + lp->phy[lp->active].gep = (*p ? p : 0); p += (*p + 1); + lp->phy[lp->active].rst = (*p ? p : 0); p += (*p + 1); + lp->phy[lp->active].mc = TWIDDLE(p); p += 2; + lp->phy[lp->active].ana = TWIDDLE(p); p += 2; + lp->phy[lp->active].fdx = TWIDDLE(p); p += 2; + lp->phy[lp->active].ttm = TWIDDLE(p); + return 0; + } else if ((lp->media == INIT) && (lp->timeout < 0)) { + lp->ibn = 1; + lp->active = *p; + lp->infoblock_csr6 = OMR_MII_100; + lp->useMII = TRUE; + lp->infoblock_media = ANS; + + de4x5_switch_mac_port(dev); + } + + return dc21140m_autoconf(dev); } -static int type2_infoblock(struct device *dev, u_char count, u_char * p) +static int +type2_infoblock(struct device *dev, u_char count, u_char *p) { - struct de4x5_private *lp = (struct de4x5_private *)dev->priv; - u_char len = (*p & BLOCK_LEN)+1; + struct de4x5_private *lp = (struct de4x5_private *)dev->priv; + u_char len = (*p & BLOCK_LEN)+1; - /* Recursively figure out the info blocks */ - if (--count > lp->tcount) { - if (*(p+len) < 128) { - return dc_infoblock[COMPACT](dev, count, p+len); - } else { - return dc_infoblock[*(p+len+1)](dev, count, p+len); - } + /* Recursively figure out the info blocks */ + if (--count > lp->tcount) { + if (*(p+len) < 128) { + return dc_infoblock[COMPACT](dev, count, p+len); + } else { + return dc_infoblock[*(p+len+1)](dev, count, p+len); } + } - if ((lp->media == INIT) && (lp->timeout < 0)) { - lp->ibn = 2; - lp->active = 0; - p += 2; - lp->infoblock_media = (*p) & MEDIA_CODE; - - if ((*p++) & EXT_FIELD) { - lp->cache.csr13 = TWIDDLE(p); p += 2; - lp->cache.csr14 = TWIDDLE(p); p += 2; - lp->cache.csr15 = TWIDDLE(p); p += 2; - } else { - lp->cache.csr13 = CSR13; - lp->cache.csr14 = CSR14; - lp->cache.csr15 = CSR15; - } - lp->cache.gepc = ((s32)(TWIDDLE(p)) << 16); p += 2; - lp->cache.gep = ((s32)(TWIDDLE(p)) << 16); - lp->infoblock_csr6 = OMR_SIA; - lp->useMII = FALSE; + if ((lp->media == INIT) && (lp->timeout < 0)) { + lp->ibn = 2; + lp->active = 0; + p += 2; + lp->infoblock_media = (*p) & MEDIA_CODE; - de4x5_switch_mac_port(dev); + if ((*p++) & EXT_FIELD) { + lp->cache.csr13 = TWIDDLE(p); p += 2; + lp->cache.csr14 = TWIDDLE(p); p += 2; + lp->cache.csr15 = TWIDDLE(p); p += 2; + } else { + lp->cache.csr13 = CSR13; + lp->cache.csr14 = CSR14; + lp->cache.csr15 = CSR15; } + lp->cache.gepc = ((s32)(TWIDDLE(p)) << 16); p += 2; + lp->cache.gep = ((s32)(TWIDDLE(p)) << 16); + lp->infoblock_csr6 = OMR_SIA; + lp->useMII = FALSE; + + de4x5_switch_mac_port(dev); + } - return dc2114x_autoconf(dev); + return dc2114x_autoconf(dev); } -static int type3_infoblock(struct device *dev, u_char count, u_char * p) +static int +type3_infoblock(struct device *dev, u_char count, u_char *p) { - struct de4x5_private *lp = (struct de4x5_private *) dev->priv; - u_char len = (*p & BLOCK_LEN)+1; + struct de4x5_private *lp = (struct de4x5_private *)dev->priv; + u_char len = (*p & BLOCK_LEN)+1; - /* Recursively figure out the info blocks */ - if (--count > lp->tcount) { - if (*(p + len) < 128) { - return dc_infoblock[COMPACT] (dev, count, p + len); - } else { - return dc_infoblock[*(p + len + 1)] (dev, count, p + len); - } + /* Recursively figure out the info blocks */ + if (--count > lp->tcount) { + if (*(p+len) < 128) { + return dc_infoblock[COMPACT](dev, count, p+len); + } else { + return dc_infoblock[*(p+len+1)](dev, count, p+len); } + } - p += 2; - if (lp->state == INITIALISED) { - lp->active = *p++; - lp->phy[lp->active].gep = (*p ? p : 0); - p += (2 * (*p) + 1); - lp->phy[lp->active].rst = (*p ? p : 0); - p += (2 * (*p) + 1); - lp->phy[lp->active].mc = TWIDDLE(p); - p += 2; - lp->phy[lp->active].ana = TWIDDLE(p); - p += 2; - lp->phy[lp->active].fdx = TWIDDLE(p); - p += 2; - lp->phy[lp->active].ttm = TWIDDLE(p); - p += 2; - lp->phy[lp->active].mci = *p; - return 0; - } else if ((lp->media == INIT) && (lp->timeout < 0)) { - lp->ibn = 3; - lp->active = *p; - lp->infoblock_csr6 = OMR_MII_100; - lp->useMII = TRUE; - lp->infoblock_media = ANS; - - de4x5_switch_mac_port(dev); - } - - return dc2114x_autoconf(dev); -} - -static int type4_infoblock(struct device *dev, u_char count, u_char *p) -{ - struct de4x5_private *lp = (struct de4x5_private *)dev->priv; - u_char flags, csr6, len = (*p & BLOCK_LEN)+1; - - /* Recursively figure out the info blocks */ - if (--count > lp->tcount) { - if (*(p+len) < 128) { - return dc_infoblock[COMPACT](dev, count, p+len); - } else { - return dc_infoblock[*(p+len+1)](dev, count, p+len); - } - } + p += 2; + if (lp->state == INITIALISED) { + lp->active = *p++; + lp->phy[lp->active].gep = (*p ? p : 0); p += (2 * (*p) + 1); + lp->phy[lp->active].rst = (*p ? p : 0); p += (2 * (*p) + 1); + lp->phy[lp->active].mc = TWIDDLE(p); p += 2; + lp->phy[lp->active].ana = TWIDDLE(p); p += 2; + lp->phy[lp->active].fdx = TWIDDLE(p); p += 2; + lp->phy[lp->active].ttm = TWIDDLE(p); p += 2; + lp->phy[lp->active].mci = *p; + return 0; + } else if ((lp->media == INIT) && (lp->timeout < 0)) { + lp->ibn = 3; + lp->active = *p; + lp->infoblock_csr6 = OMR_MII_100; + lp->useMII = TRUE; + lp->infoblock_media = ANS; + + de4x5_switch_mac_port(dev); + } + + return dc2114x_autoconf(dev); +} - if ((lp->media == INIT) && (lp->timeout < 0)) { - lp->ibn = 4; - lp->active = 0; - p += 2; - lp->infoblock_media = (*p++) & MEDIA_CODE; - lp->cache.csr13 = CSR13; /* Hard coded defaults */ - lp->cache.csr14 = CSR14; - lp->cache.csr15 = CSR15; - lp->cache.gepc = ((s32)(TWIDDLE(p)) << 16); p += 2; - lp->cache.gep = ((s32)(TWIDDLE(p)) << 16); p += 2; - csr6 = *p++; - flags = *p++; - - lp->asBitValid = (flags & 0x80) ? 0 : -1; - lp->defMedium = (flags & 0x40) ? -1 : 0; - lp->asBit = 1 << ((csr6 >> 1) & 0x07); - lp->asPolarity = ((csr6 & 0x80) ? -1 : 0) & lp->asBit; - lp->infoblock_csr6 = OMR_DEF | ((csr6 & 0x71) << 18); - lp->useMII = FALSE; +static int +type4_infoblock(struct device *dev, u_char count, u_char *p) +{ + struct de4x5_private *lp = (struct de4x5_private *)dev->priv; + u_char flags, csr6, len = (*p & BLOCK_LEN)+1; - de4x5_switch_mac_port(dev); + /* Recursively figure out the info blocks */ + if (--count > lp->tcount) { + if (*(p+len) < 128) { + return dc_infoblock[COMPACT](dev, count, p+len); + } else { + return dc_infoblock[*(p+len+1)](dev, count, p+len); } + } + + if ((lp->media == INIT) && (lp->timeout < 0)) { + lp->ibn = 4; + lp->active = 0; + p+=2; + lp->infoblock_media = (*p++) & MEDIA_CODE; + lp->cache.csr13 = CSR13; /* Hard coded defaults */ + lp->cache.csr14 = CSR14; + lp->cache.csr15 = CSR15; + lp->cache.gepc = ((s32)(TWIDDLE(p)) << 16); p += 2; + lp->cache.gep = ((s32)(TWIDDLE(p)) << 16); p += 2; + csr6 = *p++; + flags = *p++; + + lp->asBitValid = (flags & 0x80) ? 0 : -1; + lp->defMedium = (flags & 0x40) ? -1 : 0; + lp->asBit = 1 << ((csr6 >> 1) & 0x07); + lp->asPolarity = ((csr6 & 0x80) ? -1 : 0) & lp->asBit; + lp->infoblock_csr6 = OMR_DEF | ((csr6 & 0x71) << 18); + lp->useMII = FALSE; - return dc2114x_autoconf(dev); + de4x5_switch_mac_port(dev); + } + + return dc2114x_autoconf(dev); } /* ** This block type provides information for resetting external devices ** (chips) through the General Purpose Register. */ -static int type5_infoblock(struct device *dev, u_char count, u_char * p) +static int +type5_infoblock(struct device *dev, u_char count, u_char *p) { - struct de4x5_private *lp = (struct de4x5_private *) dev->priv; - u_char len = (*p & BLOCK_LEN)+1; + struct de4x5_private *lp = (struct de4x5_private *)dev->priv; + u_char len = (*p & BLOCK_LEN)+1; - /* Recursively figure out the info blocks */ - if (--count > lp->tcount) { - if (*(p + len) < 128) { - return dc_infoblock[COMPACT] (dev, count, p + len); - } else { - return dc_infoblock[*(p + len + 1)] (dev, count, p + len); - } - } - /* Must be initializing to run this code */ - if ((lp->state == INITIALISED) || (lp->media == INIT)) { - p += 2; - lp->rst = p; - srom_exec(dev, lp->rst); + /* Recursively figure out the info blocks */ + if (--count > lp->tcount) { + if (*(p+len) < 128) { + return dc_infoblock[COMPACT](dev, count, p+len); + } else { + return dc_infoblock[*(p+len+1)](dev, count, p+len); } - return DE4X5_AUTOSENSE_MS; + } + + /* Must be initializing to run this code */ + if ((lp->state == INITIALISED) || (lp->media == INIT)) { + p+=2; + lp->rst = p; + srom_exec(dev, lp->rst); + } + + return DE4X5_AUTOSENSE_MS; } /* ** MII Read/Write */ -static int mii_rd(u_char phyreg, u_char phyaddr, u_long ioaddr) +static int +mii_rd(u_char phyreg, u_char phyaddr, u_long ioaddr) { - mii_wdata(MII_PREAMBLE, 2, ioaddr); /* Start of 34 bit preamble... */ - mii_wdata(MII_PREAMBLE, 32, ioaddr); /* ...continued */ - mii_wdata(MII_STRD, 4, ioaddr); /* SFD and Read operation */ - mii_address(phyaddr, ioaddr); /* PHY address to be accessed */ - mii_address(phyreg, ioaddr); /* PHY Register to read */ - mii_ta(MII_STRD, ioaddr); /* Turn around time - 2 MDC */ - - return mii_rdata(ioaddr); /* Read data */ -} - -static void mii_wr(int data, u_char phyreg, u_char phyaddr, u_long ioaddr) -{ - mii_wdata(MII_PREAMBLE, 2, ioaddr); /* Start of 34 bit preamble... */ - mii_wdata(MII_PREAMBLE, 32, ioaddr); /* ...continued */ - mii_wdata(MII_STWR, 4, ioaddr); /* SFD and Write operation */ - mii_address(phyaddr, ioaddr); /* PHY address to be accessed */ - mii_address(phyreg, ioaddr); /* PHY Register to write */ - mii_ta(MII_STWR, ioaddr); /* Turn around time - 2 MDC */ - data = mii_swap(data, 16); /* Swap data bit ordering */ - mii_wdata(data, 16, ioaddr); /* Write data */ - - return; + mii_wdata(MII_PREAMBLE, 2, ioaddr); /* Start of 34 bit preamble... */ + mii_wdata(MII_PREAMBLE, 32, ioaddr); /* ...continued */ + mii_wdata(MII_STRD, 4, ioaddr); /* SFD and Read operation */ + mii_address(phyaddr, ioaddr); /* PHY address to be accessed */ + mii_address(phyreg, ioaddr); /* PHY Register to read */ + mii_ta(MII_STRD, ioaddr); /* Turn around time - 2 MDC */ + + return mii_rdata(ioaddr); /* Read data */ } -static int mii_rdata(u_long ioaddr) +static void +mii_wr(int data, u_char phyreg, u_char phyaddr, u_long ioaddr) { - int i; - s32 tmp = 0; - - for (i = 0; i < 16; i++) { - tmp <<= 1; - tmp |= getfrom_mii(MII_MRD | MII_RD, ioaddr); - } - - return tmp; + mii_wdata(MII_PREAMBLE, 2, ioaddr); /* Start of 34 bit preamble... */ + mii_wdata(MII_PREAMBLE, 32, ioaddr); /* ...continued */ + mii_wdata(MII_STWR, 4, ioaddr); /* SFD and Write operation */ + mii_address(phyaddr, ioaddr); /* PHY address to be accessed */ + mii_address(phyreg, ioaddr); /* PHY Register to write */ + mii_ta(MII_STWR, ioaddr); /* Turn around time - 2 MDC */ + data = mii_swap(data, 16); /* Swap data bit ordering */ + mii_wdata(data, 16, ioaddr); /* Write data */ + + return; } -static void mii_wdata(int data, int len, u_long ioaddr) +static int +mii_rdata(u_long ioaddr) { - int i; - - for (i = 0; i < len; i++) { - sendto_mii(MII_MWR | MII_WR, data, ioaddr); - data >>= 1; - } - - return; + int i; + s32 tmp = 0; + + for (i=0; i<16; i++) { + tmp <<= 1; + tmp |= getfrom_mii(MII_MRD | MII_RD, ioaddr); + } + + return tmp; } -static void mii_address(u_char addr, u_long ioaddr) +static void +mii_wdata(int data, int len, u_long ioaddr) { - int i; - - addr = mii_swap(addr, 5); - for (i = 0; i < 5; i++) { - sendto_mii(MII_MWR | MII_WR, addr, ioaddr); - addr >>= 1; - } - - return; + int i; + + for (i=0; i>= 1; + } + + return; } -static void mii_ta(u_long rw, u_long ioaddr) +static void +mii_address(u_char addr, u_long ioaddr) { - if (rw == MII_STWR) { - sendto_mii(MII_MWR | MII_WR, 1, ioaddr); - sendto_mii(MII_MWR | MII_WR, 0, ioaddr); - } else { - getfrom_mii(MII_MRD | MII_RD, ioaddr); /* Tri-state MDIO */ - } - - return; + int i; + + addr = mii_swap(addr, 5); + for (i=0; i<5; i++) { + sendto_mii(MII_MWR | MII_WR, addr, ioaddr); + addr >>= 1; + } + + return; } -static int mii_swap(int data, int len) +static void +mii_ta(u_long rw, u_long ioaddr) { - int i, tmp = 0; - - for (i = 0; i < len; i++) { - tmp <<= 1; - tmp |= (data & 1); - data >>= 1; - } - - return tmp; + if (rw == MII_STWR) { + sendto_mii(MII_MWR | MII_WR, 1, ioaddr); + sendto_mii(MII_MWR | MII_WR, 0, ioaddr); + } else { + getfrom_mii(MII_MRD | MII_RD, ioaddr); /* Tri-state MDIO */ + } + + return; } -static void sendto_mii(u32 command, int data, u_long ioaddr) +static int +mii_swap(int data, int len) { - u32 j; - - j = (data & 1) << 17; - outl(command | j, ioaddr); - udelay(1); - outl(command | MII_MDC | j, ioaddr); - udelay(1); - - return; + int i, tmp = 0; + + for (i=0; i>= 1; + } + + return tmp; } -static int getfrom_mii(u32 command, u_long ioaddr) +static void +sendto_mii(u32 command, int data, u_long ioaddr) { - outl(command, ioaddr); - udelay(1); - outl(command | MII_MDC, ioaddr); - udelay(1); + u32 j; + + j = (data & 1) << 17; + outl(command | j, ioaddr); + udelay(1); + outl(command | MII_MDC | j, ioaddr); + udelay(1); + + return; +} - return ((inl(ioaddr) >> 19) & 1); +static int +getfrom_mii(u32 command, u_long ioaddr) +{ + outl(command, ioaddr); + udelay(1); + outl(command | MII_MDC, ioaddr); + udelay(1); + + return ((inl(ioaddr) >> 19) & 1); } /* ** Here's 3 ways to calculate the OUI from the ID registers. */ -static int mii_get_oui(u_char phyaddr, u_long ioaddr) +static int +mii_get_oui(u_char phyaddr, u_long ioaddr) { /* - union { - u_short reg; - u_char breg[2]; - } a; - int i, r2, r3, ret=0; */ - int r2, r3; - - /* Read r2 and r3 */ - r2 = mii_rd(MII_ID0, phyaddr, ioaddr); - r3 = mii_rd(MII_ID1, phyaddr, ioaddr); - /* SEEQ and Cypress way * / - / * Shuffle r2 and r3 * / - a.reg=0; - r3 = ((r3>>10)|(r2<<6))&0x0ff; - r2 = ((r2>>2)&0x3fff); - - / * Bit reverse r3 * / - for (i=0;i<8;i++) { - ret<<=1; - ret |= (r3&1); - r3>>=1; - } - - / * Bit reverse r2 * / - for (i=0;i<16;i++) { - a.reg<<=1; - a.reg |= (r2&1); - r2>>=1; - } - - / * Swap r2 bytes * / - i=a.breg[0]; - a.breg[0]=a.breg[1]; - a.breg[1]=i; - - return ((a.reg<<8)|ret); *//* SEEQ and Cypress way */ - /* return ((r2<<6)|(u_int)(r3>>10)); *//* NATIONAL and BROADCOM way */ - return r2; /* (I did it) My way */ + union { + u_short reg; + u_char breg[2]; + } a; + int i, r2, r3, ret=0;*/ + int r2, r3; + + /* Read r2 and r3 */ + r2 = mii_rd(MII_ID0, phyaddr, ioaddr); + r3 = mii_rd(MII_ID1, phyaddr, ioaddr); + /* SEEQ and Cypress way * / + / * Shuffle r2 and r3 * / + a.reg=0; + r3 = ((r3>>10)|(r2<<6))&0x0ff; + r2 = ((r2>>2)&0x3fff); + + / * Bit reverse r3 * / + for (i=0;i<8;i++) { + ret<<=1; + ret |= (r3&1); + r3>>=1; + } + + / * Bit reverse r2 * / + for (i=0;i<16;i++) { + a.reg<<=1; + a.reg |= (r2&1); + r2>>=1; + } + + / * Swap r2 bytes * / + i=a.breg[0]; + a.breg[0]=a.breg[1]; + a.breg[1]=i; + + return ((a.reg<<8)|ret); */ /* SEEQ and Cypress way */ +/* return ((r2<<6)|(u_int)(r3>>10)); */ /* NATIONAL and BROADCOM way */ + return r2; /* (I did it) My way */ } /* ** The SROM spec forces us to search addresses [1-31 0]. Bummer. */ -static int mii_get_phy(struct device *dev) +static int +mii_get_phy(struct device *dev) { - struct de4x5_private *lp = (struct de4x5_private *) dev->priv; - u_long iobase = dev->base_addr; - int i, j, k, n, limit = sizeof(phy_info) / sizeof(struct phy_table); - int id; - - lp->active = 0; - lp->useMII = TRUE; + struct de4x5_private *lp = (struct de4x5_private *)dev->priv; + u_long iobase = dev->base_addr; + int i, j, k, n, limit=sizeof(phy_info)/sizeof(struct phy_table); + int id; + + lp->active = 0; + lp->useMII = TRUE; - /* Search the MII address space for possible PHY devices */ - for (n = 0, lp->mii_cnt = 0, i = 1; !((i == 1) && (n == 1)); i = (++i) % DE4X5_MAX_MII) { - lp->phy[lp->active].addr = i; - if (i == 0) - n++; /* Count cycles */ - while (de4x5_reset_phy(dev) < 0) - udelay(100); /* Wait for reset */ - id = mii_get_oui(i, DE4X5_MII); - if ((id == 0) || (id == 65535)) - continue; /* Valid ID? */ - for (j = 0; j < limit; j++) { /* Search PHY table */ - if (id != phy_info[j].id) - continue; /* ID match? */ - for (k = 0; lp->phy[k].id && (k < DE4X5_MAX_PHY); k++); - if (k < DE4X5_MAX_PHY) { - memcpy((char *) &lp->phy[k], - (char *) &phy_info[j], sizeof(struct phy_table)); - lp->phy[k].addr = i; - lp->mii_cnt++; - lp->active++; - } else { - goto purgatory; /* Stop the search */ - } - break; - } - if ((j == limit) && (i < DE4X5_MAX_MII)) { - printk("%s: Found MII device not currently supported. Please mail the following dump to\nthe author:\n", dev->name); - de4x5_debug |= DEBUG_MII; - de4x5_dbg_mii(dev, i); - printk("\n"); - } + /* Search the MII address space for possible PHY devices */ + for (n=0, lp->mii_cnt=0, i=1; !((i==1) && (n==1)); i=(++i)%DE4X5_MAX_MII) { + lp->phy[lp->active].addr = i; + if (i==0) n++; /* Count cycles */ + while (de4x5_reset_phy(dev)<0) udelay(100);/* Wait for reset */ + id = mii_get_oui(i, DE4X5_MII); + if ((id == 0) || (id == 65535)) continue; /* Valid ID? */ + for (j=0; jphy[k].id && (k < DE4X5_MAX_PHY); k++); + if (k < DE4X5_MAX_PHY) { + memcpy((char *)&lp->phy[k], + (char *)&phy_info[j], sizeof(struct phy_table)); + lp->phy[k].addr = i; + lp->mii_cnt++; + lp->active++; + } else { + goto purgatory; /* Stop the search */ + } + break; + } + if ((j == limit) && (i < DE4X5_MAX_MII)) { + for (k=0; lp->phy[k].id && (k < DE4X5_MAX_PHY); k++); + lp->phy[k].addr = i; + lp->phy[k].id = id; + lp->phy[k].spd.reg = GENERIC_REG; /* ANLPA register */ + lp->phy[k].spd.mask = GENERIC_MASK; /* 100Mb/s technologies */ + lp->phy[k].spd.value = GENERIC_VALUE; /* TX & T4, H/F Duplex */ + printk("%s: Found MII device not currently supported. Please mail the following dump to\nthe author:\n", dev->name); + j = de4x5_debug; + de4x5_debug |= DEBUG_MII; + de4x5_dbg_mii(dev, k); + de4x5_debug = j; + printk("\n"); } + } purgatory: - lp->active = 0; - if (lp->phy[0].id) { /* Reset the PHY devices */ - for (k = 0; lp->phy[k].id && (k < DE4X5_MAX_PHY); k++) { /*For each PHY */ - mii_wr(MII_CR_RST, MII_CR, lp->phy[k].addr, DE4X5_MII); - while (mii_rd(MII_CR, lp->phy[k].addr, DE4X5_MII) & MII_CR_RST); - - de4x5_dbg_mii(dev, k); - } + lp->active = 0; + if (lp->phy[0].id) { /* Reset the PHY devices */ + for (k=0; lp->phy[k].id && (k < DE4X5_MAX_PHY); k++) { /*For each PHY*/ + mii_wr(MII_CR_RST, MII_CR, lp->phy[k].addr, DE4X5_MII); + while (mii_rd(MII_CR, lp->phy[k].addr, DE4X5_MII) & MII_CR_RST); + + de4x5_dbg_mii(dev, k); } - if (!lp->mii_cnt) - lp->useMII = FALSE; + } + if (!lp->mii_cnt) lp->useMII = FALSE; - return lp->mii_cnt; + return lp->mii_cnt; } -static char *build_setup_frame(struct device *dev, int mode) +static char * +build_setup_frame(struct device *dev, int mode) { - struct de4x5_private *lp = (struct de4x5_private *) dev->priv; - int i; - char *pa = lp->setup_frame; - - /* Initialise the setup frame */ - if (mode == ALL) { - memset(lp->setup_frame, 0, SETUP_FRAME_LEN); - } - if (lp->setup_f == HASH_PERF) { - for (pa = lp->setup_frame + IMPERF_PA_OFFSET, i = 0; i < ETH_ALEN; i++) { - *(pa + i) = dev->dev_addr[i]; /* Host address */ - if (i & 0x01) - pa += 2; - } - *(lp->setup_frame + (HASH_TABLE_LEN >> 3) - 3) = 0x80; - } else { - for (i = 0; i < ETH_ALEN; i++) { /* Host address */ - *(pa + (i & 1)) = dev->dev_addr[i]; - if (i & 0x01) - pa += 4; - } - for (i = 0; i < ETH_ALEN; i++) { /* Broadcast address */ - *(pa + (i & 1)) = (char) 0xff; - if (i & 0x01) - pa += 4; - } + struct de4x5_private *lp = (struct de4x5_private *)dev->priv; + int i; + char *pa = lp->setup_frame; + + /* Initialise the setup frame */ + if (mode == ALL) { + memset(lp->setup_frame, 0, SETUP_FRAME_LEN); + } + + if (lp->setup_f == HASH_PERF) { + for (pa=lp->setup_frame+IMPERF_PA_OFFSET, i=0; idev_addr[i]; /* Host address */ + if (i & 0x01) pa += 2; + } + *(lp->setup_frame + (HASH_TABLE_LEN >> 3) - 3) = 0x80; + } else { + for (i=0; idev_addr[i]; + if (i & 0x01) pa += 4; + } + for (i=0; ipriv; - - del_timer(&lp->timer); - - return; + struct de4x5_private *lp = (struct de4x5_private *)dev->priv; + + del_timer(&lp->timer); + + return; } -static long de4x5_switch_mac_port(struct device *dev) +static long +de4x5_switch_mac_port(struct device *dev) { - struct de4x5_private *lp = (struct de4x5_private *) dev->priv; - u_long iobase = dev->base_addr; - s32 omr; + struct de4x5_private *lp = (struct de4x5_private *)dev->priv; + u_long iobase = dev->base_addr; + s32 omr; - STOP_DE4X5; - - /* Assert the OMR_PS bit in CSR6 */ - omr = (inl(DE4X5_OMR) & ~(OMR_PS | OMR_HBD | OMR_TTM | OMR_PCS | OMR_SCR | - OMR_FDX)); - omr |= lp->infoblock_csr6; - if (omr & OMR_PS) - omr |= OMR_HBD; - outl(omr, DE4X5_OMR); + STOP_DE4X5; - /* Soft Reset */ - RESET_DE4X5; + /* Assert the OMR_PS bit in CSR6 */ + omr = (inl(DE4X5_OMR) & ~(OMR_PS | OMR_HBD | OMR_TTM | OMR_PCS | OMR_SCR | + OMR_FDX)); + omr |= lp->infoblock_csr6; + if (omr & OMR_PS) omr |= OMR_HBD; + outl(omr, DE4X5_OMR); + + /* Soft Reset */ + RESET_DE4X5; + + /* Restore the GEP - especially for COMPACT and Type 0 Infoblocks */ + if (lp->chipset == DC21140) { + gep_wr(lp->cache.gepc, dev); + gep_wr(lp->cache.gep, dev); + } else if ((lp->chipset & ~0x0ff) == DC2114x) { + reset_init_sia(dev, lp->cache.csr13, lp->cache.csr14, lp->cache.csr15); + } - /* Restore the GEP - especially for COMPACT and Type 0 Infoblocks */ - if (lp->chipset == DC21140) { - gep_wr(lp->cache.gepc, dev); - gep_wr(lp->cache.gep, dev); - } else if ((lp->chipset & ~0x0ff) == DC2114x) { - reset_init_sia(dev, lp->cache.csr13, lp->cache.csr14, lp->cache.csr15); - } - /* Restore CSR6 */ - outl(omr, DE4X5_OMR); + /* Restore CSR6 */ + outl(omr, DE4X5_OMR); - /* Reset CSR8 */ - inl(DE4X5_MFC); + /* Reset CSR8 */ + inl(DE4X5_MFC); - return omr; + return omr; } -static void gep_wr(s32 data, struct device *dev) +static void +gep_wr(s32 data, struct device *dev) { - struct de4x5_private *lp = (struct de4x5_private *)dev->priv; - u_long iobase = dev->base_addr; + struct de4x5_private *lp = (struct de4x5_private *)dev->priv; + u_long iobase = dev->base_addr; - if (lp->chipset == DC21140) { - outl(data, DE4X5_GEP); - } else if ((lp->chipset & ~0x00ff) == DC2114x) { - outl((data<<16) | lp->cache.csr15, DE4X5_SIGR); - } + if (lp->chipset == DC21140) { + outl(data, DE4X5_GEP); + } else if ((lp->chipset & ~0x00ff) == DC2114x) { + outl((data<<16) | lp->cache.csr15, DE4X5_SIGR); + } - return; + return; } -static int gep_rd(struct device *dev) +static int +gep_rd(struct device *dev) { - struct de4x5_private *lp = (struct de4x5_private *)dev->priv; - u_long iobase = dev->base_addr; + struct de4x5_private *lp = (struct de4x5_private *)dev->priv; + u_long iobase = dev->base_addr; - if (lp->chipset == DC21140) { - return inl(DE4X5_GEP); - } else if ((lp->chipset & ~0x00ff) == DC2114x) { - return (inl(DE4X5_SIGR) & 0x000fffff); - } + if (lp->chipset == DC21140) { + return inl(DE4X5_GEP); + } else if ((lp->chipset & ~0x00ff) == DC2114x) { + return (inl(DE4X5_SIGR) & 0x000fffff); + } - return 0; + return 0; } -static void timeout(struct device *dev, void (*fn) (u_long data), u_long data, u_long msec) +static void +timeout(struct device *dev, void (*fn)(u_long data), u_long data, u_long msec) { - struct de4x5_private *lp = (struct de4x5_private *) dev->priv; - int dt; + struct de4x5_private *lp = (struct de4x5_private *)dev->priv; + int dt; + + /* First, cancel any pending timer events */ + del_timer(&lp->timer); + + /* Convert msec to ticks */ + dt = (msec * HZ) / 1000; + if (dt==0) dt=1; + + /* Set up timer */ + lp->timer.expires = jiffies + dt; + lp->timer.function = fn; + lp->timer.data = data; + add_timer(&lp->timer); + + return; +} - /* First, cancel any pending timer events */ - del_timer(&lp->timer); +static void +yawn(struct device *dev, int state) +{ + struct de4x5_private *lp = (struct de4x5_private *)dev->priv; + u_long iobase = dev->base_addr; - /* Convert msec to ticks */ - dt = (msec * HZ) / 1000; - if (dt == 0) - dt = 1; - - /* Set up timer */ - lp->timer.expires = jiffies + dt; - lp->timer.function = fn; - lp->timer.data = data; - add_timer(&lp->timer); + if ((lp->chipset == DC21040) || (lp->chipset == DC21140)) return; - return; -} + if(lp->bus == EISA) { + switch(state) { + case WAKEUP: + outb(WAKEUP, PCI_CFPM); + de4x5_ms_delay(10); + break; -static void yawn(struct device *dev, int state) -{ - struct de4x5_private *lp = (struct de4x5_private *) dev->priv; - u_long iobase = dev->base_addr; + case SNOOZE: + outb(SNOOZE, PCI_CFPM); + break; - if ((lp->chipset == DC21040) || (lp->chipset == DC21140)) - return; + case SLEEP: + outl(0, DE4X5_SICR); + outb(SLEEP, PCI_CFPM); + break; + } + } else { + switch(state) { + case WAKEUP: + pcibios_write_config_byte(lp->bus_num, lp->device << 3, + PCI_CFDA_PSM, WAKEUP); + de4x5_ms_delay(10); + break; - if (lp->bus == EISA) { - switch (state) { - case WAKEUP: - outb(WAKEUP, PCI_CFPM); - de4x5_ms_delay(10); - break; - - case SNOOZE: - outb(SNOOZE, PCI_CFPM); - break; - - case SLEEP: - outl(0, DE4X5_SICR); - outb(SLEEP, PCI_CFPM); - break; - } - } else { - switch (state) { - case WAKEUP: - pcibios_write_config_byte(lp->bus_num, lp->device << 3, - PCI_CFDA_PSM, WAKEUP); - de4x5_ms_delay(10); - break; - - case SNOOZE: - pcibios_write_config_byte(lp->bus_num, lp->device << 3, - PCI_CFDA_PSM, SNOOZE); - break; - - case SLEEP: - outl(0, DE4X5_SICR); - pcibios_write_config_byte(lp->bus_num, lp->device << 3, - PCI_CFDA_PSM, SLEEP); - break; - } + case SNOOZE: + pcibios_write_config_byte(lp->bus_num, lp->device << 3, + PCI_CFDA_PSM, SNOOZE); + break; + + case SLEEP: + outl(0, DE4X5_SICR); + pcibios_write_config_byte(lp->bus_num, lp->device << 3, + PCI_CFDA_PSM, SLEEP); + break; } + } - return; + return; } -static void de4x5_dbg_open(struct device *dev) +static void +de4x5_parse_params(struct device *dev) { - struct de4x5_private *lp = (struct de4x5_private *) dev->priv; - int i; + struct de4x5_private *lp = (struct de4x5_private *)dev->priv; + char *p, *q, t; - if (de4x5_debug & DEBUG_OPEN) { - printk("%s: de4x5 opening with irq %d\n", dev->name, dev->irq); - printk("\tphysical address: "); - for (i = 0; i < 6; i++) { - printk("%2.2x:", (short) dev->dev_addr[i]); - } - printk("\n"); - printk("Descriptor head addresses:\n"); - printk("\t0x%8.8lx 0x%8.8lx\n", (u_long) lp->rx_ring, (u_long) lp->tx_ring); - printk("Descriptor addresses:\nRX: "); - for (i = 0; i < lp->rxRingSize - 1; i++) { - if (i < 3) { - printk("0x%8.8lx ", (u_long) & lp->rx_ring[i].status); - } - } - printk("...0x%8.8lx\n", (u_long) & lp->rx_ring[i].status); - printk("TX: "); - for (i = 0; i < lp->txRingSize - 1; i++) { - if (i < 3) { - printk("0x%8.8lx ", (u_long) & lp->tx_ring[i].status); - } - } - printk("...0x%8.8lx\n", (u_long) & lp->tx_ring[i].status); - printk("Descriptor buffers:\nRX: "); - for (i = 0; i < lp->rxRingSize - 1; i++) { - if (i < 3) { - printk("0x%8.8x ", le32_to_cpu(lp->rx_ring[i].buf)); - } - } - printk("...0x%8.8x\n", le32_to_cpu(lp->rx_ring[i].buf)); - printk("TX: "); - for (i = 0; i < lp->txRingSize - 1; i++) { - if (i < 3) { - printk("0x%8.8x ", le32_to_cpu(lp->tx_ring[i].buf)); - } - } - printk("...0x%8.8x\n", le32_to_cpu(lp->tx_ring[i].buf)); - printk("Ring size: \nRX: %d\nTX: %d\n", - (short) lp->rxRingSize, - (short) lp->txRingSize); - } - return; -} + lp->params.fdx = 0; + lp->params.autosense = AUTO; -static void de4x5_dbg_mii(struct device *dev, int k) -{ - struct de4x5_private *lp = (struct de4x5_private *) dev->priv; - u_long iobase = dev->base_addr; + if (args == NULL) return; - if (de4x5_debug & DEBUG_MII) { - printk("\nMII CR: %x\n", mii_rd(MII_CR, lp->phy[k].addr, DE4X5_MII)); - printk("MII SR: %x\n", mii_rd(MII_SR, lp->phy[k].addr, DE4X5_MII)); - printk("MII ID0: %x\n", mii_rd(MII_ID0, lp->phy[k].addr, DE4X5_MII)); - printk("MII ID1: %x\n", mii_rd(MII_ID1, lp->phy[k].addr, DE4X5_MII)); - if (lp->phy[k].id != BROADCOM_T4) { - printk("MII ANA: %x\n", mii_rd(0x04, lp->phy[k].addr, DE4X5_MII)); - printk("MII ANC: %x\n", mii_rd(0x05, lp->phy[k].addr, DE4X5_MII)); - } - printk("MII 16: %x\n", mii_rd(0x10, lp->phy[k].addr, DE4X5_MII)); - if (lp->phy[k].id != BROADCOM_T4) { - printk("MII 17: %x\n", mii_rd(0x11, lp->phy[k].addr, DE4X5_MII)); - printk("MII 18: %x\n", mii_rd(0x12, lp->phy[k].addr, DE4X5_MII)); - } else { - printk("MII 20: %x\n", mii_rd(0x14, lp->phy[k].addr, DE4X5_MII)); - } + if ((p = strstr(args, dev->name))) { + if (!(q = strstr(p+strlen(dev->name), "eth"))) q = p + strlen(p); + t = *q; + *q = '\0'; + + if (strstr(p, "fdx") || strstr(p, "FDX")) lp->params.fdx = 1; + + if (strstr(p, "autosense") || strstr(p, "AUTOSENSE")) { + if (strstr(p, "TP")) { + lp->params.autosense = TP; + } else if (strstr(p, "TP_NW")) { + lp->params.autosense = TP_NW; + } else if (strstr(p, "BNC")) { + lp->params.autosense = BNC; + } else if (strstr(p, "AUI")) { + lp->params.autosense = AUI; + } else if (strstr(p, "BNC_AUI")) { + lp->params.autosense = BNC; + } else if (strstr(p, "10Mb")) { + lp->params.autosense = _10Mb; + } else if (strstr(p, "100Mb")) { + lp->params.autosense = _100Mb; + } else if (strstr(p, "AUTO")) { + lp->params.autosense = AUTO; + } } - return; + *q = t; + } + + return; } -static void de4x5_dbg_media(struct device *dev) +static void +de4x5_dbg_open(struct device *dev) { - struct de4x5_private *lp = (struct de4x5_private *) dev->priv; + struct de4x5_private *lp = (struct de4x5_private *)dev->priv; + int i; + + if (de4x5_debug & DEBUG_OPEN) { + printk("%s: de4x5 opening with irq %d\n",dev->name,dev->irq); + printk("\tphysical address: "); + for (i=0;i<6;i++) { + printk("%2.2x:",(short)dev->dev_addr[i]); + } + printk("\n"); + printk("Descriptor head addresses:\n"); + printk("\t0x%8.8lx 0x%8.8lx\n",(u_long)lp->rx_ring,(u_long)lp->tx_ring); + printk("Descriptor addresses:\nRX: "); + for (i=0;irxRingSize-1;i++){ + if (i < 3) { + printk("0x%8.8lx ",(u_long)&lp->rx_ring[i].status); + } + } + printk("...0x%8.8lx\n",(u_long)&lp->rx_ring[i].status); + printk("TX: "); + for (i=0;itxRingSize-1;i++){ + if (i < 3) { + printk("0x%8.8lx ", (u_long)&lp->tx_ring[i].status); + } + } + printk("...0x%8.8lx\n", (u_long)&lp->tx_ring[i].status); + printk("Descriptor buffers:\nRX: "); + for (i=0;irxRingSize-1;i++){ + if (i < 3) { + printk("0x%8.8x ",le32_to_cpu(lp->rx_ring[i].buf)); + } + } + printk("...0x%8.8x\n",le32_to_cpu(lp->rx_ring[i].buf)); + printk("TX: "); + for (i=0;itxRingSize-1;i++){ + if (i < 3) { + printk("0x%8.8x ", le32_to_cpu(lp->tx_ring[i].buf)); + } + } + printk("...0x%8.8x\n", le32_to_cpu(lp->tx_ring[i].buf)); + printk("Ring size: \nRX: %d\nTX: %d\n", + (short)lp->rxRingSize, + (short)lp->txRingSize); + } + + return; +} - if (lp->media != lp->c_media) { - if (de4x5_debug & DEBUG_MEDIA) { - if (lp->chipset != DC21140) { - printk("%s: media is %s%s\n", dev->name, - (lp->media == NC ? "unconnected, link down or incompatible connection" : - (lp->media == TP ? "TP" : - (lp->media == ANS ? "TP/Nway" : - (lp->media == BNC ? "BNC" : - (lp->media == AUI ? "AUI" : - (lp->media == BNC_AUI ? "BNC/AUI" : - (lp->media == EXT_SIA ? "EXT SIA" : - (lp->media == _100Mb ? "100Mb/s" : - (lp->media == _10Mb ? "10Mb/s" : - "???" - ))))))))), - (lp->fdx?" full duplex.":".")); - } - } - lp->c_media = lp->media; +static void +de4x5_dbg_mii(struct device *dev, int k) +{ + struct de4x5_private *lp = (struct de4x5_private *)dev->priv; + u_long iobase = dev->base_addr; + + if (de4x5_debug & DEBUG_MII) { + printk("\nMII device address: %d\n", lp->phy[k].addr); + printk("MII CR: %x\n",mii_rd(MII_CR,lp->phy[k].addr,DE4X5_MII)); + printk("MII SR: %x\n",mii_rd(MII_SR,lp->phy[k].addr,DE4X5_MII)); + printk("MII ID0: %x\n",mii_rd(MII_ID0,lp->phy[k].addr,DE4X5_MII)); + printk("MII ID1: %x\n",mii_rd(MII_ID1,lp->phy[k].addr,DE4X5_MII)); + if (lp->phy[k].id != BROADCOM_T4) { + printk("MII ANA: %x\n",mii_rd(0x04,lp->phy[k].addr,DE4X5_MII)); + printk("MII ANC: %x\n",mii_rd(0x05,lp->phy[k].addr,DE4X5_MII)); + } + printk("MII 16: %x\n",mii_rd(0x10,lp->phy[k].addr,DE4X5_MII)); + if (lp->phy[k].id != BROADCOM_T4) { + printk("MII 17: %x\n",mii_rd(0x11,lp->phy[k].addr,DE4X5_MII)); + printk("MII 18: %x\n",mii_rd(0x12,lp->phy[k].addr,DE4X5_MII)); + } else { + printk("MII 20: %x\n",mii_rd(0x14,lp->phy[k].addr,DE4X5_MII)); } - return; + } + + return; } -static void de4x5_dbg_srom(struct de4x5_srom *p) +static void +de4x5_dbg_media(struct device *dev) { - int i; - - if (de4x5_debug & DEBUG_SROM) { - printk("Sub-system Vendor ID: %04x\n", *((u_short *) p->sub_vendor_id)); - printk("Sub-system ID: %04x\n", *((u_short *) p->sub_system_id)); - printk("ID Block CRC: %02x\n", (u_char) (p->id_block_crc)); - printk("SROM version: %02x\n", (u_char) (p->version)); - printk("# controllers: %02x\n", (u_char) (p->num_controllers)); - - printk("Hardware Address: "); - for (i = 0; i < ETH_ALEN - 1; i++) { - printk("%02x:", (u_char) * (p->ieee_addr + i)); - } - printk("%02x\n", (u_char) * (p->ieee_addr + i)); - printk("CRC checksum: %04x\n", (u_short) (p->chksum)); - for (i = 0; i < 64; i++) { - printk("%3d %04x\n", i << 1, (u_short) * ((u_short *) p + i)); - } + struct de4x5_private *lp = (struct de4x5_private *)dev->priv; + + if (lp->media != lp->c_media) { + if (de4x5_debug & DEBUG_MEDIA) { + printk("%s: media is %s%s\n", dev->name, + (lp->media == NC ? "unconnected, link down or incompatible connection" : + (lp->media == TP ? "TP" : + (lp->media == ANS ? "TP/Nway" : + (lp->media == BNC ? "BNC" : + (lp->media == AUI ? "AUI" : + (lp->media == BNC_AUI ? "BNC/AUI" : + (lp->media == EXT_SIA ? "EXT SIA" : + (lp->media == _100Mb ? "100Mb/s" : + (lp->media == _10Mb ? "10Mb/s" : + "???" + ))))))))), (lp->fdx?" full duplex.":".")); } - return; + lp->c_media = lp->media; + } + + return; } -static void de4x5_dbg_rx(struct sk_buff *skb, int len) +static void +de4x5_dbg_srom(struct de4x5_srom *p) { - int i, j; + int i; + if (de4x5_debug & DEBUG_SROM) { + printk("Sub-system Vendor ID: %04x\n", *((u_short *)p->sub_vendor_id)); + printk("Sub-system ID: %04x\n", *((u_short *)p->sub_system_id)); + printk("ID Block CRC: %02x\n", (u_char)(p->id_block_crc)); + printk("SROM version: %02x\n", (u_char)(p->version)); + printk("# controllers: %02x\n", (u_char)(p->num_controllers)); + + printk("Hardware Address: "); + for (i=0;iieee_addr+i)); + } + printk("%02x\n", (u_char)*(p->ieee_addr+i)); + printk("CRC checksum: %04x\n", (u_short)(p->chksum)); + for (i=0; i<64; i++) { + printk("%3d %04x\n", i<<1, (u_short)*((u_short *)p+i)); + } + } + + return; +} + +static void +de4x5_dbg_rx(struct sk_buff *skb, int len) +{ + int i, j; + + if (de4x5_debug & DEBUG_RX) { + printk("R: %02x:%02x:%02x:%02x:%02x:%02x <- %02x:%02x:%02x:%02x:%02x:%02x len/SAP:%02x%02x [%d]\n", + (u_char)skb->data[0], + (u_char)skb->data[1], + (u_char)skb->data[2], + (u_char)skb->data[3], + (u_char)skb->data[4], + (u_char)skb->data[5], + (u_char)skb->data[6], + (u_char)skb->data[7], + (u_char)skb->data[8], + (u_char)skb->data[9], + (u_char)skb->data[10], + (u_char)skb->data[11], + (u_char)skb->data[12], + (u_char)skb->data[13], + len); if (de4x5_debug & DEBUG_RX) { - printk("R: %02x:%02x:%02x:%02x:%02x:%02x <- %02x:%02x:%02x:%02x:%02x:%02x len/SAP:%02x%02x [%d]\n", - (u_char) skb->data[0], - (u_char) skb->data[1], - (u_char) skb->data[2], - (u_char) skb->data[3], - (u_char) skb->data[4], - (u_char) skb->data[5], - (u_char) skb->data[6], - (u_char) skb->data[7], - (u_char) skb->data[8], - (u_char) skb->data[9], - (u_char) skb->data[10], - (u_char) skb->data[11], - (u_char) skb->data[12], - (u_char) skb->data[13], - len); - if (de4x5_debug & DEBUG_RX) { - for (j = 0; len > 0; j += 16, len -= 16) { - printk(" %03x: ", j); - for (i = 0; i < 16 && i < len; i++) { - printk("%02x ", (u_char) skb->data[i + j]); - } - printk("\n"); - } + for (j=0; len>0;j+=16, len-=16) { + printk(" %03x: ",j); + for (i=0; i<16 && idata[i+j]); } + printk("\n"); + } } - return; + } + + return; } /* @@ -5244,248 +5409,242 @@ ** effective uid is checked in those cases. In the normal course of events ** this function is only used for my testing. */ -static int de4x5_ioctl(struct device *dev, struct ifreq *rq, int cmd) +static int +de4x5_ioctl(struct device *dev, struct ifreq *rq, int cmd) { - struct de4x5_private *lp = (struct de4x5_private *) dev->priv; - struct de4x5_ioctl *ioc = (struct de4x5_ioctl *) &rq->ifr_data; - u_long iobase = dev->base_addr; - int i, j, status = 0; - s32 omr; - union { - u8 addr[144]; - u16 sval[72]; - u32 lval[36]; - } tmp; - - switch (ioc->cmd) { - case DE4X5_GET_HWADDR: /* Get the hardware address */ - ioc->len = ETH_ALEN; - status = verify_area(VERIFY_WRITE, (void *) ioc->data, ioc->len); - if (status) - break; - for (i = 0; i < ETH_ALEN; i++) { - tmp.addr[i] = dev->dev_addr[i]; - } - copy_to_user(ioc->data, tmp.addr, ioc->len); - - break; - case DE4X5_SET_HWADDR: /* Set the hardware address */ - status = verify_area(VERIFY_READ, (void *) ioc->data, ETH_ALEN); - if (status) - break; - status = -EPERM; - if (!suser()) - break; - status = 0; - copy_from_user(tmp.addr, ioc->data, ETH_ALEN); - for (i = 0; i < ETH_ALEN; i++) { - dev->dev_addr[i] = tmp.addr[i]; - } - build_setup_frame(dev, PHYS_ADDR_ONLY); - /* Set up the descriptor and give ownership to the card */ - while (test_and_set_bit(0, (void *)&dev->tbusy) != 0); - load_packet(dev, lp->setup_frame, TD_IC | PERFECT_F | TD_SET | - SETUP_FRAME_LEN, NULL); - lp->tx_new = (++lp->tx_new) % lp->txRingSize; - outl(POLL_DEMAND, DE4X5_TPD); /* Start the TX */ - dev->tbusy = 0; /* Unlock the TX ring */ - - break; - case DE4X5_SET_PROM: /* Set Promiscuous Mode */ - if (suser()) { - omr = inl(DE4X5_OMR); - omr |= OMR_PR; - outl(omr, DE4X5_OMR); - dev->flags |= IFF_PROMISC; - } else { - status = -EPERM; - } - - break; - case DE4X5_CLR_PROM: /* Clear Promiscuous Mode */ - if (suser()) { - omr = inl(DE4X5_OMR); - omr &= ~OMR_PR; - outb(omr, DE4X5_OMR); - dev->flags &= ~IFF_PROMISC; - } else { - status = -EPERM; - } - - break; - case DE4X5_SAY_BOO: /* Say "Boo!" to the kernel log file */ - printk("%s: Boo!\n", dev->name); - - break; - case DE4X5_MCA_EN: /* Enable pass all multicast addressing */ - if (suser()) { - omr = inl(DE4X5_OMR); - omr |= OMR_PM; - outl(omr, DE4X5_OMR); - } else { - status = -EPERM; - } - - break; - case DE4X5_GET_STATS: /* Get the driver statistics */ - ioc->len = sizeof(lp->pktStats); - status = verify_area(VERIFY_WRITE, (void *) ioc->data, ioc->len); - if (status) - break; - - cli(); - copy_to_user(ioc->data, &lp->pktStats, ioc->len); - sti(); - - break; - case DE4X5_CLR_STATS: /* Zero out the driver statistics */ - if (suser()) { - cli(); - memset(&lp->pktStats, 0, sizeof(lp->pktStats)); - sti(); - } else { - status = -EPERM; - } - - break; - case DE4X5_GET_OMR: /* Get the OMR Register contents */ - tmp.addr[0] = inl(DE4X5_OMR); - if (!(status = verify_area(VERIFY_WRITE, (void *) ioc->data, 1))) { - copy_to_user(ioc->data, tmp.addr, 1); - } - break; - case DE4X5_SET_OMR: /* Set the OMR Register contents */ - if (suser()) { - if (!(status = verify_area(VERIFY_READ, (void *) ioc->data, 1))) { - copy_from_user(tmp.addr, ioc->data, 1); - outl(tmp.addr[0], DE4X5_OMR); - } - } else { - status = -EPERM; - } - - break; - case DE4X5_GET_REG: /* Get the DE4X5 Registers */ - j = 0; - tmp.lval[0] = inl(DE4X5_STS); - j += 4; - tmp.lval[1] = inl(DE4X5_BMR); - j += 4; - tmp.lval[2] = inl(DE4X5_IMR); - j += 4; - tmp.lval[3] = inl(DE4X5_OMR); - j += 4; - tmp.lval[4] = inl(DE4X5_SISR); - j += 4; - tmp.lval[5] = inl(DE4X5_SICR); - j += 4; - tmp.lval[6] = inl(DE4X5_STRR); - j += 4; - tmp.lval[7] = inl(DE4X5_SIGR); - j += 4; - ioc->len = j; - if (!(status = verify_area(VERIFY_WRITE, (void *) ioc->data, ioc->len))) { - copy_to_user(ioc->data, tmp.addr, ioc->len); - } - break; - + struct de4x5_private *lp = (struct de4x5_private *)dev->priv; + struct de4x5_ioctl *ioc = (struct de4x5_ioctl *) &rq->ifr_data; + u_long iobase = dev->base_addr; + int i, j, status = 0; + s32 omr; + union { + u8 addr[144]; + u16 sval[72]; + u32 lval[36]; + } tmp; + + switch(ioc->cmd) { + case DE4X5_GET_HWADDR: /* Get the hardware address */ + ioc->len = ETH_ALEN; + status = verify_area(VERIFY_WRITE, (void *)ioc->data, ioc->len); + if (status) + break; + for (i=0; idev_addr[i]; + } + copy_to_user(ioc->data, tmp.addr, ioc->len); + + break; + case DE4X5_SET_HWADDR: /* Set the hardware address */ + status = verify_area(VERIFY_READ, (void *)ioc->data, ETH_ALEN); + if (status) + break; + status = -EPERM; + if (!suser()) + break; + status = 0; + copy_from_user(tmp.addr, ioc->data, ETH_ALEN); + for (i=0; idev_addr[i] = tmp.addr[i]; + } + build_setup_frame(dev, PHYS_ADDR_ONLY); + /* Set up the descriptor and give ownership to the card */ + while (test_and_set_bit(0, (void *)&dev->tbusy) != 0); + load_packet(dev, lp->setup_frame, TD_IC | PERFECT_F | TD_SET | + SETUP_FRAME_LEN, NULL); + lp->tx_new = (++lp->tx_new) % lp->txRingSize; + outl(POLL_DEMAND, DE4X5_TPD); /* Start the TX */ + dev->tbusy = 0; /* Unlock the TX ring */ + + break; + case DE4X5_SET_PROM: /* Set Promiscuous Mode */ + if (suser()) { + omr = inl(DE4X5_OMR); + omr |= OMR_PR; + outl(omr, DE4X5_OMR); + dev->flags |= IFF_PROMISC; + } else { + status = -EPERM; + } + + break; + case DE4X5_CLR_PROM: /* Clear Promiscuous Mode */ + if (suser()) { + omr = inl(DE4X5_OMR); + omr &= ~OMR_PR; + outb(omr, DE4X5_OMR); + dev->flags &= ~IFF_PROMISC; + } else { + status = -EPERM; + } + + break; + case DE4X5_SAY_BOO: /* Say "Boo!" to the kernel log file */ + printk("%s: Boo!\n", dev->name); + + break; + case DE4X5_MCA_EN: /* Enable pass all multicast addressing */ + if (suser()) { + omr = inl(DE4X5_OMR); + omr |= OMR_PM; + outl(omr, DE4X5_OMR); + } else { + status = -EPERM; + } + + break; + case DE4X5_GET_STATS: /* Get the driver statistics */ + ioc->len = sizeof(lp->pktStats); + status = verify_area(VERIFY_WRITE, (void *)ioc->data, ioc->len); + if (status) + break; + + cli(); + copy_to_user(ioc->data, &lp->pktStats, ioc->len); + sti(); + + break; + case DE4X5_CLR_STATS: /* Zero out the driver statistics */ + if (suser()) { + cli(); + memset(&lp->pktStats, 0, sizeof(lp->pktStats)); + sti(); + } else { + status = -EPERM; + } + + break; + case DE4X5_GET_OMR: /* Get the OMR Register contents */ + tmp.addr[0] = inl(DE4X5_OMR); + if (!(status = verify_area(VERIFY_WRITE, (void *)ioc->data, 1))) { + copy_to_user(ioc->data, tmp.addr, 1); + } + + break; + case DE4X5_SET_OMR: /* Set the OMR Register contents */ + if (suser()) { + if (!(status = verify_area(VERIFY_READ, (void *)ioc->data, 1))) { + copy_from_user(tmp.addr, ioc->data, 1); + outl(tmp.addr[0], DE4X5_OMR); + } + } else { + status = -EPERM; + } + + break; + case DE4X5_GET_REG: /* Get the DE4X5 Registers */ + j = 0; + tmp.lval[0] = inl(DE4X5_STS); j+=4; + tmp.lval[1] = inl(DE4X5_BMR); j+=4; + tmp.lval[2] = inl(DE4X5_IMR); j+=4; + tmp.lval[3] = inl(DE4X5_OMR); j+=4; + tmp.lval[4] = inl(DE4X5_SISR); j+=4; + tmp.lval[5] = inl(DE4X5_SICR); j+=4; + tmp.lval[6] = inl(DE4X5_STRR); j+=4; + tmp.lval[7] = inl(DE4X5_SIGR); j+=4; + ioc->len = j; + if (!(status = verify_area(VERIFY_WRITE, (void *)ioc->data, ioc->len))) { + copy_to_user(ioc->data, tmp.addr, ioc->len); + } + break; + #define DE4X5_DUMP 0x0f /* Dump the DE4X5 Status */ /* - case DE4X5_DUMP: - j = 0; - tmp.addr[j++] = dev->irq; - for (i=0; idev_addr[i]; - } - tmp.addr[j++] = lp->rxRingSize; - tmp.lval[j>>2] = (long)lp->rx_ring; j+=4; - tmp.lval[j>>2] = (long)lp->tx_ring; j+=4; - - for (i=0;irxRingSize-1;i++){ - if (i < 3) { - tmp.lval[j>>2] = (long)&lp->rx_ring[i].status; j+=4; - } - } - tmp.lval[j>>2] = (long)&lp->rx_ring[i].status; j+=4; - for (i=0;itxRingSize-1;i++){ - if (i < 3) { - tmp.lval[j>>2] = (long)&lp->tx_ring[i].status; j+=4; - } - } - tmp.lval[j>>2] = (long)&lp->tx_ring[i].status; j+=4; - - for (i=0;irxRingSize-1;i++){ - if (i < 3) { - tmp.lval[j>>2] = (s32)le32_to_cpu(lp->rx_ring[i].buf); j+=4; - } - } - tmp.lval[j>>2] = (s32)le32_to_cpu(lp->rx_ring[i].buf); j+=4; - for (i=0;itxRingSize-1;i++){ - if (i < 3) { - tmp.lval[j>>2] = (s32)le32_to_cpu(lp->tx_ring[i].buf); j+=4; - } - } - tmp.lval[j>>2] = (s32)le32_to_cpu(lp->tx_ring[i].buf); j+=4; - - for (i=0;irxRingSize;i++){ - tmp.lval[j>>2] = le32_to_cpu(lp->rx_ring[i].status); j+=4; - } - for (i=0;itxRingSize;i++){ - tmp.lval[j>>2] = le32_to_cpu(lp->tx_ring[i].status); j+=4; - } - - tmp.lval[j>>2] = inl(DE4X5_BMR); j+=4; - tmp.lval[j>>2] = inl(DE4X5_TPD); j+=4; - tmp.lval[j>>2] = inl(DE4X5_RPD); j+=4; - tmp.lval[j>>2] = inl(DE4X5_RRBA); j+=4; - tmp.lval[j>>2] = inl(DE4X5_TRBA); j+=4; - tmp.lval[j>>2] = inl(DE4X5_STS); j+=4; - tmp.lval[j>>2] = inl(DE4X5_OMR); j+=4; - tmp.lval[j>>2] = inl(DE4X5_IMR); j+=4; - tmp.lval[j>>2] = lp->chipset; j+=4; - if (lp->chipset == DC21140) { - tmp.lval[j>>2] = gep_rd(dev); j+=4; - } else { - tmp.lval[j>>2] = inl(DE4X5_SISR); j+=4; - tmp.lval[j>>2] = inl(DE4X5_SICR); j+=4; - tmp.lval[j>>2] = inl(DE4X5_STRR); j+=4; - tmp.lval[j>>2] = inl(DE4X5_SIGR); j+=4; - } - tmp.lval[j>>2] = lp->phy[lp->active].id; j+=4; - if (lp->phy[lp->active].id && (!lp->useSROM || lp->useMII)) { - tmp.lval[j>>2] = lp->active; j+=4; - tmp.lval[j>>2]=mii_rd(MII_CR,lp->phy[lp->active].addr,DE4X5_MII); j+=4; - tmp.lval[j>>2]=mii_rd(MII_SR,lp->phy[lp->active].addr,DE4X5_MII); j+=4; - tmp.lval[j>>2]=mii_rd(MII_ID0,lp->phy[lp->active].addr,DE4X5_MII); j+=4; - tmp.lval[j>>2]=mii_rd(MII_ID1,lp->phy[lp->active].addr,DE4X5_MII); j+=4; - if (lp->phy[lp->active].id != BROADCOM_T4) { - tmp.lval[j>>2]=mii_rd(MII_ANA,lp->phy[lp->active].addr,DE4X5_MII); j+=4; - tmp.lval[j>>2]=mii_rd(MII_ANLPA,lp->phy[lp->active].addr,DE4X5_MII); j+=4; - } - tmp.lval[j>>2]=mii_rd(0x10,lp->phy[lp->active].addr,DE4X5_MII); j+=4; - if (lp->phy[lp->active].id != BROADCOM_T4) { - tmp.lval[j>>2]=mii_rd(0x11,lp->phy[lp->active].addr,DE4X5_MII); j+=4; - tmp.lval[j>>2]=mii_rd(0x12,lp->phy[lp->active].addr,DE4X5_MII); j+=4; - } else { - tmp.lval[j>>2]=mii_rd(0x14,lp->phy[lp->active].addr,DE4X5_MII); j+=4; - } - } - - tmp.addr[j++] = lp->txRingSize; - tmp.addr[j++] = dev->tbusy; - - ioc->len = j; - if (!(status = verify_area(VERIFY_WRITE, (void *)ioc->data, ioc->len))) { - copy_to_user(ioc->data, tmp.addr, ioc->len); - } - - break; - */ - default: - status = -EOPNOTSUPP; + case DE4X5_DUMP: + j = 0; + tmp.addr[j++] = dev->irq; + for (i=0; idev_addr[i]; + } + tmp.addr[j++] = lp->rxRingSize; + tmp.lval[j>>2] = (long)lp->rx_ring; j+=4; + tmp.lval[j>>2] = (long)lp->tx_ring; j+=4; + + for (i=0;irxRingSize-1;i++){ + if (i < 3) { + tmp.lval[j>>2] = (long)&lp->rx_ring[i].status; j+=4; + } + } + tmp.lval[j>>2] = (long)&lp->rx_ring[i].status; j+=4; + for (i=0;itxRingSize-1;i++){ + if (i < 3) { + tmp.lval[j>>2] = (long)&lp->tx_ring[i].status; j+=4; + } } - - return status; + tmp.lval[j>>2] = (long)&lp->tx_ring[i].status; j+=4; + + for (i=0;irxRingSize-1;i++){ + if (i < 3) { + tmp.lval[j>>2] = (s32)le32_to_cpu(lp->rx_ring[i].buf); j+=4; + } + } + tmp.lval[j>>2] = (s32)le32_to_cpu(lp->rx_ring[i].buf); j+=4; + for (i=0;itxRingSize-1;i++){ + if (i < 3) { + tmp.lval[j>>2] = (s32)le32_to_cpu(lp->tx_ring[i].buf); j+=4; + } + } + tmp.lval[j>>2] = (s32)le32_to_cpu(lp->tx_ring[i].buf); j+=4; + + for (i=0;irxRingSize;i++){ + tmp.lval[j>>2] = le32_to_cpu(lp->rx_ring[i].status); j+=4; + } + for (i=0;itxRingSize;i++){ + tmp.lval[j>>2] = le32_to_cpu(lp->tx_ring[i].status); j+=4; + } + + tmp.lval[j>>2] = inl(DE4X5_BMR); j+=4; + tmp.lval[j>>2] = inl(DE4X5_TPD); j+=4; + tmp.lval[j>>2] = inl(DE4X5_RPD); j+=4; + tmp.lval[j>>2] = inl(DE4X5_RRBA); j+=4; + tmp.lval[j>>2] = inl(DE4X5_TRBA); j+=4; + tmp.lval[j>>2] = inl(DE4X5_STS); j+=4; + tmp.lval[j>>2] = inl(DE4X5_OMR); j+=4; + tmp.lval[j>>2] = inl(DE4X5_IMR); j+=4; + tmp.lval[j>>2] = lp->chipset; j+=4; + if (lp->chipset == DC21140) { + tmp.lval[j>>2] = gep_rd(dev); j+=4; + } else { + tmp.lval[j>>2] = inl(DE4X5_SISR); j+=4; + tmp.lval[j>>2] = inl(DE4X5_SICR); j+=4; + tmp.lval[j>>2] = inl(DE4X5_STRR); j+=4; + tmp.lval[j>>2] = inl(DE4X5_SIGR); j+=4; + } + tmp.lval[j>>2] = lp->phy[lp->active].id; j+=4; + if (lp->phy[lp->active].id && (!lp->useSROM || lp->useMII)) { + tmp.lval[j>>2] = lp->active; j+=4; + tmp.lval[j>>2]=mii_rd(MII_CR,lp->phy[lp->active].addr,DE4X5_MII); j+=4; + tmp.lval[j>>2]=mii_rd(MII_SR,lp->phy[lp->active].addr,DE4X5_MII); j+=4; + tmp.lval[j>>2]=mii_rd(MII_ID0,lp->phy[lp->active].addr,DE4X5_MII); j+=4; + tmp.lval[j>>2]=mii_rd(MII_ID1,lp->phy[lp->active].addr,DE4X5_MII); j+=4; + if (lp->phy[lp->active].id != BROADCOM_T4) { + tmp.lval[j>>2]=mii_rd(MII_ANA,lp->phy[lp->active].addr,DE4X5_MII); j+=4; + tmp.lval[j>>2]=mii_rd(MII_ANLPA,lp->phy[lp->active].addr,DE4X5_MII); j+=4; + } + tmp.lval[j>>2]=mii_rd(0x10,lp->phy[lp->active].addr,DE4X5_MII); j+=4; + if (lp->phy[lp->active].id != BROADCOM_T4) { + tmp.lval[j>>2]=mii_rd(0x11,lp->phy[lp->active].addr,DE4X5_MII); j+=4; + tmp.lval[j>>2]=mii_rd(0x12,lp->phy[lp->active].addr,DE4X5_MII); j+=4; + } else { + tmp.lval[j>>2]=mii_rd(0x14,lp->phy[lp->active].addr,DE4X5_MII); j+=4; + } + } + + tmp.addr[j++] = lp->txRingSize; + tmp.addr[j++] = dev->tbusy; + + ioc->len = j; + if (!(status = verify_area(VERIFY_WRITE, (void *)ioc->data, ioc->len))) { + copy_to_user(ioc->data, tmp.addr, ioc->len); + } + + break; +*/ + default: + status = -EOPNOTSUPP; + } + + return status; } #ifdef MODULE @@ -5496,100 +5655,100 @@ */ #define LP(a) ((struct de4x5_private *)(a)) static struct device *mdev = NULL; -static int io = 0x0; /* EDIT THIS LINE FOR YOUR CONFIGURATION IF NEEDED */ +static int io=0x0;/* EDIT THIS LINE FOR YOUR CONFIGURATION IF NEEDED */ #if LINUX_VERSION_CODE >= LinuxVersionCode(2,1,0) MODULE_PARM(io, "i"); #endif /* LINUX_VERSION_CODE */ -int init_module(void) +int +init_module(void) { - int i, num, status = -EIO; - struct device *p; + int i, num, status = -EIO; + struct device *p; - num = count_adapters(); + num = count_adapters(); - for (i=0; ipriv) { /* Private areas allocated? */ - struct de4x5_private *lp = (struct de4x5_private *) p->priv; + if (p->priv) { /* Private areas allocated? */ + struct de4x5_private *lp = (struct de4x5_private *)p->priv; - next = lp->next_module; - if (lp->cache.buf) { /* MAC buffers allocated? */ - kfree(lp->cache.buf); /* Free the MAC buffers */ - } - kfree(lp->cache.priv); /* Free the private area */ - release_region(p->base_addr, (lp->bus == PCI ? - DE4X5_PCI_TOTAL_SIZE : - DE4X5_EISA_TOTAL_SIZE)); + next = lp->next_module; + if (lp->cache.buf) { /* MAC buffers allocated? */ + kfree(lp->cache.buf); /* Free the MAC buffers */ } - unregister_netdev(p); - kfree(p); /* Free the device structure */ - - return next; + kfree(lp->cache.priv); /* Free the private area */ + release_region(p->base_addr, (lp->bus == PCI ? + DE4X5_PCI_TOTAL_SIZE : + DE4X5_EISA_TOTAL_SIZE)); + } + unregister_netdev(p); + kfree(p); /* Free the device structure */ + + return next; } -static int count_adapters(void) +static int +count_adapters(void) { - int i, j = 0; - char name[DE4X5_STRLEN]; - u_char pb, dev_fn, dev_num; - u_short dev_id, vendor; - u_int class = DE4X5_CLASS_CODE; - u_int device; + int i, j; + char name[DE4X5_STRLEN]; + u_char pb, dev_fn, dev_num; + u_short dev_id, vendor; + u_int class = DE4X5_CLASS_CODE; + u_int device; #ifndef __sparc_v9__ - u_int iobase = 0x1000; + u_long iobase = 0x1000; - for (i=1; iname = (char *)(new + 1); - new->base_addr = iobase; /* assign the io address */ - new->init = init; /* initialisation routine */ - } + new = (struct device *)kmalloc(sizeof(struct device)+8, GFP_KERNEL); + if (new == NULL) { + printk("de4x5.c: Device not initialised, insufficient memory\n"); + return NULL; + } else { + memset((char *)new, 0, sizeof(struct device)+8); + new->name = (char *)(new + 1); + new->base_addr = iobase; /* assign the io address */ + new->init = init; /* initialisation routine */ + } - return new; + return new; } -#endif /* MODULE */ - +#endif /* MODULE */ + /* * Local variables: * compile-command: "gcc -D__KERNEL__ -I/linux/include -Wall -Wstrict-prototypes -fomit-frame-pointer -fno-strength-reduce -malign-loops=2 -malign-jumps=2 -malign-functions=2 -O2 -m486 -c de4x5.c" @@ -5625,10 +5784,3 @@ * compile-command: "gcc -D__KERNEL__ -DMODULE -I/linux/include -Wall -Wstrict-prototypes -fomit-frame-pointer -fno-strength-reduce -malign-loops=2 -malign-jumps=2 -malign-functions=2 -O2 -m486 -c de4x5.c" * End: */ - - - - - - - diff -u --recursive --new-file v2.1.75/linux/drivers/net/de4x5.h linux/drivers/net/de4x5.h --- v2.1.75/linux/drivers/net/de4x5.h Sat Nov 29 11:25:09 1997 +++ linux/drivers/net/de4x5.h Sun Dec 21 22:37:32 1997 @@ -166,11 +166,7 @@ /* ** PCI Configuration Base I/O Address Register (PCI_CBIO) */ -#ifdef __sparc_v9__ -#define CBIO_MASK 0xffffffffffffff80 /* Base I/O Address Mask */ -#else -#define CBIO_MASK 0xffffff80 /* Base I/O Address Mask */ -#endif +#define CBIO_MASK -128 /* Base I/O Address Mask */ #define CBIO_IOSI 0x00000001 /* I/O Space Indicator (RO, value is 1) */ /* @@ -368,7 +364,7 @@ #define OMR_SIA (OMR_SDP | OMR_TTM) #define OMR_SYM (OMR_SDP | OMR_SCR | OMR_PCS | OMR_HBD | OMR_PS) #define OMR_MII_10 (OMR_SDP | OMR_TTM | OMR_PS) -#define OMR_MII_100 (OMR_SDP | OMR_SCR | OMR_HBD | OMR_PS) +#define OMR_MII_100 (OMR_SDP | OMR_HBD | OMR_PS) /* ** DC21040 Interrupt Mask Register (DE4X5_IMR) @@ -813,16 +809,22 @@ /* ** Media / mode state machine definitions +** User selectable: */ -#define NC 0x0000 /* No Connection */ #define TP 0x0001 /* 10Base-T */ #define TP_NW 0x0002 /* 10Base-T with Nway */ #define BNC 0x0004 /* Thinwire */ #define AUI 0x0008 /* Thickwire */ #define BNC_AUI 0x0010 /* BNC/AUI on DC21040 indistinguishable */ -#define ANS 0x0020 /* Intermediate AutoNegotiation State */ #define _10Mb 0x0040 /* 10Mb/s Ethernet */ #define _100Mb 0x0080 /* 100Mb/s Ethernet */ +#define AUTO 0x4000 /* Auto sense the media or speed */ + +/* +** Internal states +*/ +#define NC 0x0000 /* No Connection */ +#define ANS 0x0020 /* Intermediate AutoNegotiation State */ #define SPD_DET 0x0100 /* Parallel speed detection */ #define INIT 0x0200 /* Initial state */ #define EXT_SIA 0x0400 /* External SIA for motherboard chip */ @@ -834,7 +836,6 @@ #define AUI_SUSPECT 0x0807 /* Suspect the AUI port is down */ #define MII 0x1000 /* MII on the 21143 */ -#define AUTO 0x4000 /* Auto sense the media or speed */ #define TIMER_CB 0x80000000 /* Timer callback detection */ /* @@ -907,6 +908,7 @@ #define OPEN 2 /* Running */ /* +** Various wait times */ #define PDET_LINK_WAIT 1200 /* msecs to wait for link detect bits */ #define ANS_FINISH_WAIT 1000 /* msecs to wait for link detect bits */ @@ -936,12 +938,13 @@ } else if (lp->useSROM && !lp->useMII) {\ omr = (inl(DE4X5_OMR) & ~(OMR_PS | OMR_HBD | OMR_TTM | OMR_PCS | OMR_SCR | OMR_FDX));\ omr |= (lp->fdx ? OMR_FDX : 0);\ - outl(omr | lp->infoblock_csr6, DE4X5_OMR);\ + outl(omr | (lp->infoblock_csr6 & ~(OMR_SCR | OMR_HBD)), DE4X5_OMR);\ } else {\ omr = (inl(DE4X5_OMR) & ~(OMR_PS | OMR_HBD | OMR_TTM | OMR_PCS | OMR_SCR | OMR_FDX));\ omr |= (lp->fdx ? OMR_FDX : 0);\ - outl(omr | OMR_TTM, DE4X5_OMR);\ + outl(omr | OMR_SDP | OMR_TTM, DE4X5_OMR);\ lp->cache.gep = (lp->fdx ? 0 : GEP_FDXD);\ + gep_wr(lp->cache.gep, dev);\ }\ } @@ -964,12 +967,13 @@ } else if (lp->useSROM && !lp->useMII) {\ omr = (inl(DE4X5_OMR) & ~(OMR_PS | OMR_HBD | OMR_TTM | OMR_PCS | OMR_SCR | OMR_FDX));\ omr |= (lp->fdx ? OMR_FDX : 0);\ - outl(omr | (lp->infoblock_csr6 & ~(OMR_SCR | OMR_HBD)), DE4X5_OMR);\ + outl(omr | lp->infoblock_csr6, DE4X5_OMR);\ } else {\ omr = (inl(DE4X5_OMR) & ~(OMR_PS | OMR_HBD | OMR_TTM | OMR_PCS | OMR_SCR | OMR_FDX));\ omr |= (lp->fdx ? OMR_FDX : 0);\ - outl(omr | OMR_PS | OMR_HBD | OMR_PCS | OMR_SCR, DE4X5_OMR);\ + outl(omr | OMR_SDP | OMR_PS | OMR_HBD | OMR_PCS | OMR_SCR, DE4X5_OMR);\ lp->cache.gep = (lp->fdx ? 0 : GEP_FDXD) | GEP_MODE;\ + gep_wr(lp->cache.gep, dev);\ }\ } @@ -981,11 +985,12 @@ outl(omr, DE4X5_OMR);\ } else if (lp->useSROM && !lp->useMII) {\ omr = (inl(DE4X5_OMR) & ~(OMR_TTM | OMR_PCS | OMR_SCR | OMR_FDX));\ - outl(omr | lp->infoblock_csr6, DE4X5_OMR);\ + outl(omr, DE4X5_OMR);\ } else {\ omr = (inl(DE4X5_OMR) & ~(OMR_PS | OMR_HBD | OMR_TTM | OMR_PCS | OMR_SCR | OMR_FDX));\ - outl(omr | OMR_PS | OMR_HBD | OMR_PCS | OMR_SCR, DE4X5_OMR);\ + outl(omr | OMR_SDP | OMR_PS | OMR_HBD | OMR_PCS, DE4X5_OMR);\ lp->cache.gep = (GEP_FDXD | GEP_MODE);\ + gep_wr(lp->cache.gep, dev);\ }\ } diff -u --recursive --new-file v2.1.75/linux/drivers/net/ppp.c linux/drivers/net/ppp.c --- v2.1.75/linux/drivers/net/ppp.c Mon Dec 1 12:04:13 1997 +++ linux/drivers/net/ppp.c Tue Dec 23 10:57:31 1997 @@ -2,11 +2,12 @@ * * Michael Callahan * Al Longyear + * Paul Mackerras * * Dynamic PPP devices by Jim Freeman . * ppp_tty_receive ``noisy-raise-bug'' fixed by Ove Ewerlid * - * ==FILEVERSION 970126== + * ==FILEVERSION 971205== * * NOTE TO MAINTAINERS: * If you modify this file at all, please set the number above to the @@ -47,19 +48,8 @@ #define CHECK_CHARACTERS 1 #define PPP_COMPRESS 1 -#ifndef PPP_MAX_DEV -#define PPP_MAX_DEV 256 -#endif - -/* $Id: ppp.c,v 1.27 1997/01/26 07:13:29 davem Exp $ - * Added dynamic allocation of channels to eliminate - * compiled-in limits on the number of channels. - * - * Dynamic channel allocation code Copyright 1995 Caldera, Inc., - * released under the GNU General Public License Version 2. - */ +/* $Id: ppp.c,v 1.14 1997/11/27 06:04:45 paulus Exp $ */ -#include #include #include #include @@ -68,7 +58,6 @@ #include #include #include -#include #include #include #include @@ -102,14 +91,11 @@ #include #include #include - -#undef PACKETPTR -#define PACKETPTR 1 #include -#undef PACKETPTR -#define bsd_decompress (*ppp->sc_rcomp->decompress) -#define bsd_compress (*ppp->sc_xcomp->compress) +#ifdef CONFIG_KERNELD +#include +#endif #ifndef PPP_IPX #define PPP_IPX 0x2b /* IPX protocol over PPP */ @@ -129,7 +115,6 @@ static struct compressor *find_compressor (int type); static void ppp_init_ctrl_blk (register struct ppp *); static void ppp_kick_tty (struct ppp *, struct ppp_buffer *bfr); -static int ppp_doframe (struct ppp *); static struct ppp *ppp_alloc (void); static struct ppp *ppp_find (int pid_value); static void ppp_print_buffer (const __u8 *, const __u8 *, int); @@ -137,6 +122,8 @@ register struct ppp_buffer *buf, register __u8 chr); extern inline int lock_buffer (register struct ppp_buffer *buf); +static int ppp_dev_xmit_ip (struct ppp *ppp, struct ppp_buffer *buf, + __u8 *data, int len, enum NPmode npmode); static int rcv_proto_ip (struct ppp *, __u16, __u8 *, int); static int rcv_proto_ipx (struct ppp *, __u16, __u8 *, int); @@ -147,7 +134,6 @@ static void ppp_doframe_lower (struct ppp *, __u8 *, int); static int ppp_doframe (struct ppp *); -extern int ppp_bsd_compressor_init(void); static void ppp_proto_ccp (struct ppp *ppp, __u8 *dp, int len, int rcvd); static int rcv_proto_ccp (struct ppp *, __u16, __u8 *, int); @@ -157,19 +143,12 @@ #define OPTIMIZE_FLAG_TIME 0 #endif -#ifndef PPP_MAX_DEV -#define PPP_MAX_DEV 256 -#endif - /* * Parameters which may be changed via insmod. */ static int flag_time = OPTIMIZE_FLAG_TIME; -static int max_dev = PPP_MAX_DEV; - MODULE_PARM(flag_time, "i"); -MODULE_PARM(max_dev, "i"); /* * The "main" procedure to the ppp device @@ -196,8 +175,9 @@ static ssize_t ppp_tty_write (struct tty_struct *, struct file *, const __u8 *, size_t); static int ppp_tty_ioctl (struct tty_struct *, struct file *, unsigned int, - unsigned long); -static unsigned int ppp_tty_poll (struct tty_struct *tty, struct file *filp, poll_table * wait); + unsigned long); +static unsigned int ppp_tty_poll (struct tty_struct *tty, struct file *filp, + poll_table * wait); static int ppp_tty_open (struct tty_struct *); static void ppp_tty_close (struct tty_struct *); static int ppp_tty_room (struct tty_struct *tty); @@ -205,8 +185,25 @@ char *fp, int count); static void ppp_tty_wakeup (struct tty_struct *tty); -#define CHECK_PPP(a) if (!ppp->inuse) { printk (ppp_warning, __LINE__); return a;} -#define CHECK_PPP_VOID() if (!ppp->inuse) { printk (ppp_warning, __LINE__); return;} +#define CHECK_PPP_MAGIC(ppp) do { \ + if (ppp->magic != PPP_MAGIC) { \ + printk(KERN_WARNING "bad magic for ppp %p at %s:%d\n", \ + ppp, __FILE__, __LINE__); \ + } \ +} while (0) +#define CHECK_PPP(a) do { \ + CHECK_PPP_MAGIC(ppp); \ + if (!ppp->inuse) { \ + printk (ppp_warning, __LINE__); \ + return a; \ + } \ +} while (0) +#define CHECK_PPP_VOID() do { \ + CHECK_PPP_MAGIC(ppp); \ + if (!ppp->inuse) { \ + printk (ppp_warning, __LINE__); \ + } \ +} while (0) #define in_xmap(ppp,c) (ppp->xmit_async_map[(c) >> 5] & (1 << ((c) & 0x1f))) #define in_rmap(ppp,c) ((((unsigned int) (__u8) (c)) < 0x20) && \ @@ -214,31 +211,13 @@ #define bset(p,b) ((p)[(b) >> 5] |= (1 << ((b) & 0x1f))) -#define tty2ppp(tty) ((struct ppp *) (tty->disc_data)) -#define dev2ppp(dev) ((struct ppp *) (dev->priv)) -#define ppp2tty(ppp) ((struct tty_struct *) ppp->tty) -#define ppp2dev(ppp) ((struct device *) ppp->dev) - -struct ppp_hdr { - __u8 address; - __u8 control; - __u8 protocol[2]; -}; - -#define PPP_HARD_HDR_LEN (sizeof (struct ppp_hdr)) +#define tty2ppp(tty) ((struct ppp *) ((tty)->disc_data)) +#define dev2ppp(dev) ((struct ppp *) ((dev)->priv)) +#define ppp2tty(ppp) ((ppp)->tty) +#define ppp2dev(ppp) (&(ppp)->dev) -typedef struct ppp_ctrl { - struct ppp_ctrl *next; /* Next structure in the list */ - char name [8]; /* Name of the device */ - struct ppp ppp; /* PPP control table */ - struct device dev; /* Device information table */ -} ppp_ctrl_t; - -static ppp_ctrl_t *ppp_list = NULL; - -#define ctl2ppp(ctl) (struct ppp *) &ctl->ppp -#define ctl2dev(ctl) (struct device *) &ctl->dev -#undef PPP_NRUNIT +static struct ppp *ppp_list = NULL; +static struct ppp *ppp_last = NULL; /* Buffer types */ #define BUFFER_TYPE_DEV_RD 0 /* ppp read buffer */ @@ -343,7 +322,7 @@ int status; printk (KERN_INFO - "PPP: version %s (dynamic channel allocation)" + "PPP: version %s (demand dialling)" "\n", szVersion); #ifndef MODULE /* slhc module logic has its own copyright announcement */ @@ -352,9 +331,6 @@ "University of California\n"); #endif - printk (KERN_INFO - "PPP Dynamic channel allocation code copyright 1995 " - "Caldera, Inc.\n"); /* * Register the tty discipline */ @@ -389,7 +365,7 @@ static int ppp_init_dev (struct device *dev) { - dev->hard_header_len = PPP_HARD_HDR_LEN; + dev->hard_header_len = PPP_HDRLEN; /* device INFO */ dev->mtu = PPP_MTU; @@ -403,9 +379,9 @@ dev->type = ARPHRD_PPP; dev_init_buffers(dev); - + /* New-style flags */ - dev->flags = IFF_POINTOPOINT; + dev->flags = IFF_POINTOPOINT | IFF_NOARP | IFF_MULTICAST; return 0; } @@ -438,13 +414,11 @@ ppp->read_wait = NULL; ppp->write_wait = NULL; ppp->last_xmit = jiffies - flag_time; + ppp->last_recv = jiffies; /* clear statistics */ - memset (&ppp->stats, '\0', sizeof (struct pppstat)); - - /* Reset the demand dial information */ - ppp->ddinfo.xmit_idle= /* time since last NP packet sent */ - ppp->ddinfo.recv_idle=jiffies; /* time since last NP packet received */ + memset(&ppp->stats, 0, sizeof (struct pppstat)); + memset(&ppp->estats, 0, sizeof(ppp->estats)); /* PPP compression data */ ppp->sc_xc_state = @@ -474,6 +448,14 @@ } #endif +#define BUFFER_MAGIC 0x1d10 +#define CHECK_BUF_MAGIC(buf) do { \ + if (buf->magic != BUFFER_MAGIC) { \ + printk(KERN_WARNING "bad magic for ppp buffer %p at %s:%d\n", \ + buf, __FILE__, __LINE__); \ + } \ +} while (0) + /* * Routine to allocate a buffer for later use by the driver. */ @@ -494,7 +476,7 @@ buf->head = 0; buf->tail = 0; buf->fcs = PPP_INITFCS; - + buf->magic = BUFFER_MAGIC; } return (buf); } @@ -506,8 +488,10 @@ static void ppp_free_buf (struct ppp_buffer *ptr) { - if (ptr != NULL) + if (ptr != NULL) { + CHECK_BUF_MAGIC(ptr); kfree (ptr); + } } /* @@ -517,11 +501,12 @@ extern inline int lock_buffer (register struct ppp_buffer *buf) { - register long state; - int flags; + unsigned long state; + unsigned long flags; /* * Save the current state and if free then set it to the "busy" state */ + CHECK_BUF_MAGIC(buf); save_flags (flags); cli (); state = buf->locked; @@ -542,6 +527,7 @@ ppp_changedmtu (struct ppp *ppp, int new_mtu, int new_mru) { struct device *dev; + unsigned long flags; struct ppp_buffer *new_rbuf; struct ppp_buffer *new_wbuf; @@ -557,7 +543,11 @@ /* * Allocate the buffer from the kernel for the data */ + CHECK_PPP(0); dev = ppp2dev (ppp); + if (ppp->flags & SC_DEBUG) + printk(KERN_DEBUG "%s: changedmtu %d %d\n", ppp->name, + new_mtu, new_mru); mru = new_mru; /* allow for possible escaping of every character */ mtu = (new_mtu * 2) + 20; @@ -568,14 +558,10 @@ mru += 10; - if (ppp->flags & SC_DEBUG) - printk (KERN_INFO "ppp: channel %s mtu = %d, mru = %d\n", - dev->name, new_mtu, new_mru); - - new_wbuf = ppp_alloc_buf (mtu+PPP_HARD_HDR_LEN, BUFFER_TYPE_DEV_WR); + new_wbuf = ppp_alloc_buf (mtu+PPP_HDRLEN, BUFFER_TYPE_DEV_WR); new_tbuf = ppp_alloc_buf ((PPP_MTU * 2) + 24, BUFFER_TYPE_TTY_WR); new_rbuf = ppp_alloc_buf (mru + 84, BUFFER_TYPE_DEV_RD); - new_cbuf = ppp_alloc_buf (mru+PPP_HARD_HDR_LEN, BUFFER_TYPE_VJ); + new_cbuf = ppp_alloc_buf (mru+PPP_HDRLEN, BUFFER_TYPE_VJ); /* * If the buffers failed to allocate then complain and release the partial * allocations. @@ -595,6 +581,7 @@ /* * Update the pointers to the new buffer structures. */ + save_flags(flags); cli (); old_wbuf = ppp->wbuf; old_rbuf = ppp->rbuf; @@ -606,6 +593,9 @@ ppp->cbuf = new_cbuf; ppp->tbuf = new_tbuf; + if (old_wbuf) + new_wbuf->locked = old_wbuf->locked; + ppp->rbuf->size -= 80; /* reserve space for vj header expansion */ dev->mem_start = (unsigned long) buf_base (new_wbuf); @@ -629,7 +619,7 @@ ppp->tty->flags &= ~(1 << TTY_DO_WRITE_WAKEUP); ppp->flags &= ~SC_XMIT_BUSY; - sti (); + restore_flags(flags); /* * Release old buffer pointers */ @@ -647,6 +637,14 @@ static void ppp_ccp_closed (struct ppp *ppp) { + unsigned long flags; + + save_flags(flags); + cli(); + ppp->flags &= ~(SC_CCP_OPEN | SC_CCP_UP | SC_COMP_RUN | SC_DECOMP_RUN); + restore_flags(flags); + if (ppp->flags & SC_DEBUG) + printk(KERN_DEBUG "%s: ccp closed\n", ppp->name); if (ppp->sc_xc_state) { (*ppp->sc_xcomp->comp_free) (ppp->sc_xc_state); ppp->sc_xc_state = NULL; @@ -671,23 +669,27 @@ struct tty_struct *tty; struct device *dev; + CHECK_PPP_MAGIC(ppp); tty = ppp2tty (ppp); dev = ppp2dev (ppp); + if (ppp->flags & SC_DEBUG) + printk(KERN_DEBUG "%s released\n", ppp->name); + ppp_ccp_closed (ppp); - /* Ensure that the pppd process is not hanging on poll() */ - wake_up_interruptible (&ppp->read_wait); - wake_up_interruptible (&ppp->write_wait); + /* Ensure that the pppd process is not hanging on poll() */ + wake_up_interruptible (&ppp->read_wait); + wake_up_interruptible (&ppp->write_wait); if (tty != NULL && tty->disc_data == ppp) tty->disc_data = NULL; /* Break the tty->ppp link */ rtnl_lock(); /* Strong layering violation. */ - if (dev && dev->flags & IFF_UP) { - dev_close (dev); /* close the device properly */ - } + if (dev && dev->flags & IFF_UP) { + dev_close (dev); /* close the device properly */ + } rtnl_unlock(); ppp_free_buf (ppp->rbuf); @@ -712,16 +714,18 @@ ppp->inuse = 0; ppp->tty = NULL; + ppp->backup_tty = NULL; } /* - * Device callback. + * TTY callback. * - * Called when the PPP device goes down in response to an ifconfig request. + * Called when the line discipline is changed to something + * else, the tty is closed, or the tty detects a hangup. */ static void -ppp_tty_close_local (struct tty_struct *tty, int sc_xfer) +ppp_tty_close (struct tty_struct *tty) { struct ppp *ppp = tty2ppp (tty); @@ -730,24 +734,27 @@ if (ppp->flags & SC_DEBUG) printk (KERN_WARNING "ppp: trying to close unopened tty!\n"); + return; + } + CHECK_PPP_VOID(); + tty->disc_data = NULL; + if (tty == ppp->backup_tty) + ppp->backup_tty = 0; + if (tty != ppp->tty) + return; + if (ppp->backup_tty) { + ppp->tty = ppp->backup_tty; } else { - CHECK_PPP_VOID(); - ppp->sc_xfer = sc_xfer; + ppp->sc_xfer = 0; if (ppp->flags & SC_DEBUG) printk (KERN_INFO "ppp: channel %s closing.\n", - ppp2dev(ppp) -> name); + ppp2dev(ppp)->name); ppp_release (ppp); MOD_DEC_USE_COUNT; } } } -static void -ppp_tty_close (struct tty_struct *tty) -{ - ppp_tty_close_local (tty, 0); -} - /* * TTY callback. * @@ -774,70 +781,75 @@ * Allocate the structure from the system */ ppp = ppp_find(current->pid); - if (ppp == NULL) { - ppp = ppp_find(0); - if (ppp == NULL) - ppp = ppp_alloc(); - } + if (ppp != NULL) { + /* + * If we are taking over a ppp unit which is currently + * connected to a loopback pty, there's not much to do. + */ + CHECK_PPP(-EINVAL); + tty->disc_data = ppp; + ppp->tty = tty; - if (ppp == NULL) { - if (ppp->flags & SC_DEBUG) - printk (KERN_ERR - "ppp_tty_open: couldn't allocate ppp channel\n"); - return -ENFILE; - } + } else { + ppp = ppp_alloc(); + if (ppp == NULL) { + if (ppp->flags & SC_DEBUG) + printk (KERN_ERR "ppp_alloc failed\n"); + return -ENFILE; + } /* * Initialize the control block */ - ppp_init_ctrl_blk (ppp); - ppp->tty = tty; - tty->disc_data = ppp; -/* - * Flush any pending characters in the driver and discipline. - */ - if (tty->ldisc.flush_buffer) - tty->ldisc.flush_buffer (tty); - - if (tty->driver.flush_buffer) - tty->driver.flush_buffer (tty); + ppp_init_ctrl_blk (ppp); + tty->disc_data = ppp; + ppp->tty = tty; /* * Allocate space for the default VJ header compression slots */ - ppp->slcomp = slhc_init (16, 16); - if (ppp->slcomp == NULL) { - if (ppp->flags & SC_DEBUG) - printk (KERN_ERR - "ppp_tty_open: no space for compression buffers!\n"); - ppp_release (ppp); - return -ENOMEM; - } + ppp->slcomp = slhc_init (16, 16); + if (ppp->slcomp == NULL) { + if (ppp->flags & SC_DEBUG) + printk (KERN_ERR "ppp_tty_open: " + "no space for compression buffers!\n"); + ppp_release (ppp); + return -ENOMEM; + } /* * Allocate space for the MTU and MRU buffers */ - if (ppp_changedmtu (ppp, ppp2dev(ppp)->mtu, ppp->mru) == 0) { - ppp_release (ppp); - return -ENOMEM; - } + if (ppp_changedmtu (ppp, ppp2dev(ppp)->mtu, ppp->mru) == 0) { + ppp_release (ppp); + return -ENOMEM; + } /* * Allocate space for a user level buffer */ - ppp->ubuf = ppp_alloc_buf (RBUFSIZE, BUFFER_TYPE_TTY_RD); - if (ppp->ubuf == NULL) { + ppp->ubuf = ppp_alloc_buf (RBUFSIZE, BUFFER_TYPE_TTY_RD); + if (ppp->ubuf == NULL) { + if (ppp->flags & SC_DEBUG) + printk (KERN_ERR "ppp_tty_open: " + "no space for user receive buffer\n"); + ppp_release (ppp); + return -ENOMEM; + } + if (ppp->flags & SC_DEBUG) - printk (KERN_ERR - "ppp_tty_open: no space for user receive buffer\n"); - ppp_release (ppp); - return -ENOMEM; - } + printk (KERN_INFO "ppp: channel %s open\n", + ppp2dev(ppp)->name); - if (ppp->flags & SC_DEBUG) - printk (KERN_INFO "ppp: channel %s open\n", - ppp2dev(ppp)->name); + for (indx = 0; indx < NUM_NP; ++indx) + ppp->sc_npmode[indx] = NPMODE_PASS; - for (indx = 0; indx < NUM_NP; ++indx) - ppp->sc_npmode[indx] = NPMODE_PASS; + MOD_INC_USE_COUNT; + } +/* + * Flush any pending characters in the driver and discipline. + */ + if (tty->ldisc.flush_buffer) + tty->ldisc.flush_buffer (tty); - MOD_INC_USE_COUNT; + if (tty->driver.flush_buffer) + tty->driver.flush_buffer (tty); return (ppp->line); } @@ -857,16 +869,21 @@ struct ppp_buffer *xbuf) { register int count, actual; + unsigned long flags; + + CHECK_PPP_VOID(); + CHECK_BUF_MAGIC(xbuf); /* * Prevent re-entrancy by ensuring that this routine is called only once. */ + save_flags(flags); cli (); if (ppp->flags & SC_XMIT_BUSY) { - sti (); + restore_flags(flags); return; } ppp->flags |= SC_XMIT_BUSY; - sti (); + restore_flags(flags); /* * Send the next block of data to the modem */ @@ -901,11 +918,8 @@ * If the completed buffer came from the device write, then complete the * transmission block. */ - if (ppp2dev (ppp) -> flags & IFF_UP) { - if (xbuf->type == BUFFER_TYPE_DEV_WR) - ppp2dev (ppp)->tbusy = 0; - mark_bh (NET_BH); - } + ppp2dev (ppp)->tbusy = 0; + mark_bh (NET_BH); /* * Wake up the transmission queue for all completion events. */ @@ -913,6 +927,7 @@ /* * Look at the priorities. Choose a daemon write over the device driver. */ + save_flags(flags); cli(); xbuf = ppp->s1buf; ppp->s1buf = NULL; @@ -920,21 +935,25 @@ xbuf = ppp->s2buf; ppp->s2buf = NULL; } - sti(); /* * If there is a pending buffer then transmit it now. */ if (xbuf != NULL) { ppp->flags &= ~SC_XMIT_BUSY; ppp_kick_tty (ppp, xbuf); + restore_flags(flags); return; } + restore_flags(flags); } } /* * Clear the re-entry flag */ + save_flags(flags); /* &=~ may not be atomic */ + cli (); ppp->flags &= ~SC_XMIT_BUSY; + restore_flags(flags); } /* @@ -954,9 +973,12 @@ if (!ppp) return; + CHECK_PPP_VOID(); - if (ppp->magic != PPP_MAGIC) + if (tty != ppp->tty) { + tty->flags &= ~(1 << TTY_DO_WRITE_WAKEUP); return; + } /* * Ensure that there is a transmission pending. Clear the re-entry flag if * there is no pending buffer. Otherwise, send the buffer. @@ -977,7 +999,10 @@ static void ppp_kick_tty (struct ppp *ppp, struct ppp_buffer *xbuf) { - register int flags; + unsigned long flags; + + CHECK_PPP_VOID(); + CHECK_BUF_MAGIC(xbuf); /* * Hold interrupts. */ @@ -1036,7 +1061,6 @@ /* * Callback function when data is available at the tty driver. */ - static void ppp_tty_receive (struct tty_struct *tty, const __u8 * data, char *flags, int count) @@ -1044,12 +1068,18 @@ register struct ppp *ppp = tty2ppp (tty); register struct ppp_buffer *buf = NULL; __u8 chr; + + if (ppp != 0) + CHECK_PPP_VOID(); + /* + * This can happen if stuff comes in on the backup tty. + */ + if (ppp == 0 || tty != ppp->tty) + return; /* * Fetch the pointer to the buffer. Be careful about race conditions. */ - if (ppp != NULL) - buf = ppp->rbuf; - + buf = ppp->rbuf; if (buf == NULL) return; /* @@ -1059,7 +1089,7 @@ if (ppp->magic != PPP_MAGIC) { if (ppp->flags & SC_DEBUG) printk (KERN_DEBUG - "PPP: handler called but couldn't find " + "PPP: tty_receive called but couldn't find " "PPP struct.\n"); return; } @@ -1078,17 +1108,25 @@ ppp->bytes_rcvd++; chr = *data++; if (flags) { - if (*flags && ppp->toss == 0) + if (*flags && ppp->toss == 0) { ppp->toss = *flags; + switch (ppp->toss) { + case TTY_OVERRUN: + ++ppp->estats.rx_fifo_errors; + break; + case TTY_FRAME: + case TTY_BREAK: + ++ppp->estats.rx_frame_errors; + break; + } + } ++flags; } /* - * Set the flags for 8 data bits and no parity. - * - * Actually, it sets the flags for d7 being 0/1 and parity being even/odd - * so that the normal processing would have all flags set at the end of the - * session. A missing flag bit would denote an error condition. + * Set the flags for d7 being 0/1 and parity being even/odd so that + * the normal processing would have all flags set at the end of the + * session. A missing flag bit indicates an error condition. */ #ifdef CHECK_CHARACTERS @@ -1103,13 +1141,9 @@ ppp->flags |= SC_RCV_EVNP; #endif /* - * Branch on the character. Process the escape character. The sequence ESC ESC - * is defined to be ESC. + * Branch on the character. */ switch (chr) { - case PPP_ESCAPE: /* PPP_ESCAPE: invert bit in next character */ - ppp->escape = PPP_TRANS; - break; /* * FLAG. This is the end of the block. If the block terminated by ESC FLAG, * then the block is to be ignored. In addition, characters before the very @@ -1123,8 +1157,8 @@ * Process frames which are not to be ignored. If the processing failed, * then clean up the VJ tables. */ - if ((ppp->toss & 0x80) != 0 || - ppp_doframe (ppp) == 0) { + if (ppp_doframe (ppp) == 0) { + ++ppp->stats.ppp_ierrors; slhc_toss (ppp->slcomp); } /* @@ -1140,17 +1174,39 @@ * receive mask then ignore the character. */ default: + /* If we're tossing, look no further. */ + if (ppp->toss != 0) + break; + + /* If this is a control char to be ignored, do so */ if (in_rmap (ppp, chr)) break; -/* - * Adjust the character and if the frame is to be discarded then simply - * ignore the character until the ending FLAG is received. - */ - chr ^= ppp->escape; - ppp->escape = 0; - if (ppp->toss != 0) + /* + * Modify the next character if preceded by escape. + * The escape character (0x7d) could be an escaped + * 0x5d, if it follows an escape :-) + */ + if (ppp->escape) { + chr ^= PPP_TRANS; + ppp->escape = 0; + } else if (chr == PPP_ESCAPE) { + ppp->escape = PPP_TRANS; break; + } + + /* + * Decompress A/C and protocol compression here. + */ + if (buf->count == 0 && chr != PPP_ALLSTATIONS) { + buf_base(buf)[0] = PPP_ALLSTATIONS; + buf_base(buf)[1] = PPP_UI; + buf->count = 2; + } + if (buf->count == 2 && (chr & 1) != 0) { + buf_base(buf)[2] = 0; + buf->count = 3; + } /* * If the count sent is within reason then store the character, bump the * count, and update the FCS for the character. @@ -1164,13 +1220,169 @@ * The peer sent too much data. Set the flags to discard the current frame * and wait for the re-synchronization FLAG to be sent. */ - ppp->stats.ppp_ierrors++; + ++ppp->estats.rx_length_errors; ppp->toss |= 0xC0; break; } } } +/* on entry, a received frame is in ppp->rbuf.bufr + check it and dispose as appropriate */ + +static int +ppp_doframe (struct ppp *ppp) +{ + __u8 *data = buf_base (ppp->rbuf); + int count = ppp->rbuf->count; + int proto; + int new_count; + __u8 *new_data; + + CHECK_PPP(0); + CHECK_BUF_MAGIC(ppp->rbuf); + +/* + * If there is a pending error from the receiver then log it and discard + * the damaged frame. + */ + if (ppp->toss) { + if ((ppp->flags & SC_DEBUG) && count > 0) + printk (KERN_DEBUG + "ppp_toss: tossing frame, reason = %x\n", + ppp->toss); + return 0; + } +/* + * An empty frame is ignored. This occurs if the FLAG sequence precedes and + * follows each frame. + */ + if (count == 0) + return 1; +/* + * Generate an error if the frame is too small. + */ + if (count < PPP_HDRLEN + 2) { + if (ppp->flags & SC_DEBUG) + printk (KERN_DEBUG + "ppp: got runt ppp frame, %d chars\n", count); + ++ppp->estats.rx_length_errors; + return 0; + } +/* + * Verify the CRC of the frame and discard the CRC characters from the + * end of the buffer. + */ + if (ppp->rbuf->fcs != PPP_GOODFCS) { + if (ppp->flags & SC_DEBUG) { + printk (KERN_DEBUG + "ppp: frame with bad fcs, length = %d\n", + count); + ppp_print_buffer("bad frame", data, count); + } + ++ppp->estats.rx_crc_errors; + return 0; + } + count -= 2; /* ignore the fcs characters */ +/* + * Obtain the protocol from the frame + */ + proto = PPP_PROTOCOL(data); +/* + * Process the active decompressor. + */ + if ((ppp->sc_rc_state != (void *) 0) && + (ppp->flags & SC_DECOMP_RUN) && + ((ppp->flags & (SC_DC_FERROR | SC_DC_ERROR)) == 0)) { + if (proto == PPP_COMP) { +/* + * If the frame is compressed then decompress it. + */ + new_data = kmalloc (ppp->mru + PPP_HDRLEN, GFP_ATOMIC); + if (new_data == NULL) { + if (ppp->flags & SC_DEBUG) + printk (KERN_ERR + "ppp_doframe: no memory\n"); + new_count = DECOMP_ERROR; + } else { + new_count = (*ppp->sc_rcomp->decompress) + (ppp->sc_rc_state, data, count, + new_data, ppp->mru + PPP_HDRLEN); + } + switch (new_count) { + default: + ppp_doframe_lower (ppp, new_data, new_count); + kfree (new_data); + return 1; + + case DECOMP_ERROR: + ppp->flags |= SC_DC_ERROR; + break; + + case DECOMP_FATALERROR: + ppp->flags |= SC_DC_FERROR; + if (ppp->flags & SC_DEBUG) + printk(KERN_ERR "ppp: fatal decomp error\n"); + break; + } +/* + * Log the error condition and discard the frame. + */ + if (new_data != 0) + kfree (new_data); + slhc_toss (ppp->slcomp); + ++ppp->stats.ppp_ierrors; + } else { +/* + * The frame is not special. Pass it through the compressor without + * actually compressing the data + */ + (*ppp->sc_rcomp->incomp) (ppp->sc_rc_state, + data, count); + } + } +/* + * Process the uncompressed frame. + */ + ppp_doframe_lower (ppp, data, count); + return 1; +} + +static void ppp_doframe_lower (struct ppp *ppp, __u8 *data, int count) +{ + __u16 proto = PPP_PROTOCOL (data); + ppp_proto_type *proto_ptr; + + CHECK_PPP_VOID(); +/* + * Ignore empty frames + */ + if (count <= PPP_HDRLEN) + return; +/* + * Count the frame and print it + */ + ++ppp->stats.ppp_ipackets; + if (ppp->flags & SC_LOG_INPKT) + ppp_print_buffer ("receive frame", data, count); +/* + * Find the procedure to handle this protocol. The last one is marked + * as a protocol 0 which is the 'catch-all' to feed it to the pppd daemon. + */ + proto_ptr = proto_list; + while (proto_ptr->proto != 0 && proto_ptr->proto != proto) + ++proto_ptr; +/* + * Update the appropriate statistic counter. + */ + if ((*proto_ptr->func) (ppp, proto, + &data[PPP_HDRLEN], + count - PPP_HDRLEN)) + ppp->stats.ppp_ioctects += count; + else + ++ppp->stats.ppp_discards; +} + /* * Put the input frame into the networking system for the indicated protocol */ @@ -1199,7 +1411,7 @@ /* * Tag the frame and kick it to the proper receive routine */ - ppp->ddinfo.recv_idle = jiffies; + ppp->last_recv = jiffies; netif_rx (skb); return 1; } @@ -1211,6 +1423,7 @@ static int rcv_proto_ip (struct ppp *ppp, __u16 proto, __u8 * data, int count) { + CHECK_PPP(0); if ((ppp2dev (ppp)->flags & IFF_UP) && (count > 0)) if (ppp->sc_npmode[NP_IP] == NPMODE_PASS) return ppp_rcv_rx (ppp, htons (ETH_P_IP), data, count); @@ -1224,6 +1437,7 @@ static int rcv_proto_ipx (struct ppp *ppp, __u16 proto, __u8 * data, int count) { + CHECK_PPP(0); if (((ppp2dev (ppp)->flags & IFF_UP) != 0) && (count > 0)) return ppp_rcv_rx (ppp, htons (ETH_P_IPX), data, count); return 0; @@ -1237,6 +1451,7 @@ rcv_proto_vjc_comp (struct ppp *ppp, __u16 proto, __u8 *data, int count) { + CHECK_PPP(0); if ((ppp->flags & SC_REJ_COMP_TCP) == 0) { int new_count = slhc_uncompress (ppp->slcomp, data, count); if (new_count >= 0) { @@ -1257,6 +1472,7 @@ rcv_proto_vjc_uncomp (struct ppp *ppp, __u16 proto, __u8 *data, int count) { + CHECK_PPP(0); if ((ppp->flags & SC_REJ_COMP_TCP) == 0) { if (slhc_remember (ppp->slcomp, data, count) > 0) { return rcv_proto_ip (ppp, PPP_IP, data, count); @@ -1287,6 +1503,7 @@ goto failure; \ } + CHECK_PPP(0); /* * The total length includes the protocol data. * Lock the user information buffer. @@ -1294,8 +1511,9 @@ if (test_and_set_bit (0, &ppp->ubuf->locked)) { if (ppp->flags & SC_DEBUG) printk (KERN_DEBUG - "ppp_us_queue: can't get lock\n"); + "ppp: rcv_proto_unknown: can't get lock\n"); } else { + CHECK_BUF_MAGIC(ppp->ubuf); current_idx = ppp->ubuf->head; /* * Insert the buffer length (not counted), the protocol, and the data @@ -1323,11 +1541,6 @@ if (ppp->tty->fasync != NULL) kill_fasync (ppp->tty->fasync, SIGIO); - if (ppp->flags & SC_DEBUG) - printk (KERN_INFO - "ppp: successfully queued %d bytes, flags = %x\n", - len + 2, ppp->flags); - return 1; /* * The buffer is full. Unlock the header @@ -1335,16 +1548,15 @@ failure: clear_bit (0, &ppp->ubuf->locked); if (ppp->flags & SC_DEBUG) - printk (KERN_INFO - "ppp_us_queue: ran out of buffer space.\n"); + printk (KERN_DEBUG + "ppp: rcv_proto_unknown: buffer overflow\n"); } /* * Discard the frame. There are no takers for this protocol. */ if (ppp->flags & SC_DEBUG) - printk (KERN_WARNING - "ppp: dropping packet on the floor.\n"); - slhc_toss (ppp->slcomp); + printk (KERN_DEBUG + "ppp: rcv_proto_unknown: dropping packet\n"); return 0; } @@ -1361,10 +1573,12 @@ int slen = CCP_LENGTH(dp); __u8 *opt = dp + CCP_HDRLEN; int opt_len = slen - CCP_HDRLEN; + unsigned long flags; if (slen > len) return; + save_flags(flags); switch (CCP_CODE(dp)) { case CCP_CONFREQ: case CCP_TERMREQ: @@ -1373,6 +1587,7 @@ * CCP must be going down - disable compression */ if (ppp->flags & SC_CCP_UP) { + cli(); ppp->flags &= ~(SC_CCP_UP | SC_COMP_RUN | SC_DECOMP_RUN); @@ -1401,8 +1616,13 @@ opt_len, ppp2dev (ppp)->base_addr, 0, - ppp->flags)) + ppp->flags & SC_DEBUG)) { + if (ppp->flags & SC_DEBUG) + printk(KERN_DEBUG "%s: comp running\n", + ppp->name); + cli(); ppp->flags |= SC_COMP_RUN; + } break; } /* @@ -1418,34 +1638,48 @@ ppp2dev (ppp)->base_addr, 0, ppp->mru, - ppp->flags)) { - ppp->flags |= SC_DECOMP_RUN; + ppp->flags & SC_DEBUG)) { + if (ppp->flags & SC_DEBUG) + printk(KERN_DEBUG "%s: decomp running\n", + ppp->name); + cli(); + ppp->flags |= SC_DECOMP_RUN; ppp->flags &= ~(SC_DC_ERROR | SC_DC_FERROR); } break; /* - * The protocol sequence is complete at this end + * CCP Reset-ack resets compressors and decompressors as it passes through. */ case CCP_RESETACK: if ((ppp->flags & SC_CCP_UP) == 0) break; if (!rcvd) { - if (ppp->sc_xc_state && (ppp->flags & SC_COMP_RUN)) + if (ppp->sc_xc_state && (ppp->flags & SC_COMP_RUN)) { (*ppp->sc_xcomp->comp_reset)(ppp->sc_xc_state); + if (ppp->flags & SC_DEBUG) + printk(KERN_DEBUG "%s: comp reset\n", + ppp->name); + } } else { if (ppp->sc_rc_state && (ppp->flags & SC_DECOMP_RUN)) { (*ppp->sc_rcomp->decomp_reset)(ppp->sc_rc_state); - ppp->flags &= ~SC_DC_ERROR; + if (ppp->flags & SC_DEBUG) + printk(KERN_DEBUG "%s: decomp reset\n", + ppp->name); + cli(); + ppp->flags &= ~SC_DC_ERROR; } } break; } + restore_flags(flags); } static int rcv_proto_ccp (struct ppp *ppp, __u16 proto, __u8 *dp, int len) { + CHECK_PPP(0); ppp_proto_ccp (ppp, dp, len, 1); return rcv_proto_unknown (ppp, proto, dp, len); } @@ -1460,197 +1694,6 @@ return rcv_proto_unknown (ppp, proto, data, len); } -/* on entry, a received frame is in ppp->rbuf.bufr - check it and dispose as appropriate */ - -static void ppp_doframe_lower (struct ppp *ppp, __u8 *data, int count) -{ - __u16 proto = PPP_PROTOCOL (data); - ppp_proto_type *proto_ptr; - -/* - * Ignore empty frames - */ - if (count <= 4) - return; -/* - * Count the frame and print it - */ - ++ppp->stats.ppp_ipackets; - if (ppp->flags & SC_LOG_INPKT) - ppp_print_buffer ("receive frame", data, count); -/* - * Find the procedure to handle this protocol. The last one is marked - * as a protocol 0 which is the 'catch-all' to feed it to the pppd daemon. - */ - proto_ptr = proto_list; - while (proto_ptr->proto != 0 && proto_ptr->proto != proto) - ++proto_ptr; -/* - * Update the appropriate statistic counter. - */ - if ((*proto_ptr->func) (ppp, proto, - &data[PPP_HARD_HDR_LEN], - count - PPP_HARD_HDR_LEN)) - ppp->stats.ppp_ioctects += count; - else - ++ppp->stats.ppp_discards; -} - -/* on entry, a received frame is in ppp->rbuf.bufr - check it and dispose as appropriate */ - -static int -ppp_doframe (struct ppp *ppp) -{ - __u8 *data = buf_base (ppp->rbuf); - int count = ppp->rbuf->count; - int addr, ctrl, proto; - int new_count; - __u8 *new_data; - -/* - * If there is a pending error from the receiver then log it and discard - * the damaged frame. - */ - if (ppp->toss) { - if (ppp->flags & SC_DEBUG) - printk (KERN_WARNING - "ppp_toss: tossing frame, reason = %d\n", - ppp->toss); - ppp->stats.ppp_ierrors++; - return 0; - } -/* - * An empty frame is ignored. This occurs if the FLAG sequence precedes and - * follows each frame. - */ - if (count == 0) - return 1; -/* - * Generate an error if the frame is too small. - */ - if (count < PPP_HARD_HDR_LEN) { - if (ppp->flags & SC_DEBUG) - printk (KERN_WARNING - "ppp: got runt ppp frame, %d chars\n", count); - slhc_toss (ppp->slcomp); - ppp->stats.ppp_ierrors++; - return 1; - } -/* - * Verify the CRC of the frame and discard the CRC characters from the - * end of the buffer. - */ - if (ppp->rbuf->fcs != PPP_GOODFCS) { - if (ppp->flags & SC_DEBUG) - printk (KERN_WARNING - "ppp: frame with bad fcs, excess = %x\n", - ppp->rbuf->fcs ^ PPP_GOODFCS); - ppp->stats.ppp_ierrors++; - return 0; - } - count -= 2; /* ignore the fcs characters */ -/* - * Ignore the leading ADDRESS and CONTROL fields in the frame. - */ - addr = PPP_ALLSTATIONS; - ctrl = PPP_UI; - - if ((data[0] == PPP_ALLSTATIONS) && (data[1] == PPP_UI)) { - data += 2; - count -= 2; - } -/* - * Obtain the protocol from the frame - */ - proto = (__u16) *data++; - if ((proto & 1) == 0) { - proto = (proto << 8) | (__u16) *data++; - --count; - } -/* - * Rewrite the header with the full information. This may encroach upon - * the 'filler' area in the buffer header. This is the purpose for the - * filler. - */ - *(--data) = proto; - *(--data) = proto >> 8; - *(--data) = ctrl; - *(--data) = addr; - count += 3; -/* - * Process the active decompressor. - */ - if ((ppp->sc_rc_state != (void *) 0) && - (ppp->flags & SC_DECOMP_RUN) && - ((ppp->flags & (SC_DC_FERROR | SC_DC_ERROR)) == 0)) { - if (proto == PPP_COMP) { -/* - * If the frame is compressed then decompress it. - */ - new_data = kmalloc (ppp->mru + 4, GFP_ATOMIC); - if (new_data == NULL) { - if (ppp->flags & SC_DEBUG) - printk (KERN_ERR - "ppp_doframe: no memory\n"); - slhc_toss (ppp->slcomp); - (*ppp->sc_rcomp->incomp) (ppp->sc_rc_state, - data, - count); - return 1; - } -/* - * Decompress the frame - */ - new_count = bsd_decompress (ppp->sc_rc_state, - data, - count, - new_data, - ppp->mru + 4); - switch (new_count) { - default: - ppp_doframe_lower (ppp, new_data, new_count); - kfree (new_data); - return 1; - - case DECOMP_OK: - break; - - case DECOMP_ERROR: - ppp->flags |= SC_DC_ERROR; - break; - - case DECOMP_FATALERROR: - ppp->flags |= SC_DC_FERROR; - break; - } -/* - * Log the error condition and discard the frame. - */ - if (ppp->flags & SC_DEBUG) - printk (KERN_ERR - "ppp_proto_comp: " - "decompress err %d\n", new_count); - kfree (new_data); - slhc_toss (ppp->slcomp); - return 1; - } -/* - * The frame is not special. Pass it through the compressor without - * actually compressing the data - */ - (*ppp->sc_rcomp->incomp) (ppp->sc_rc_state, - data, - count); - } -/* - * Process the uncompressed frame. - */ - ppp_doframe_lower (ppp, data, count); - return 1; -} - /************************************************************* * LINE DISCIPLINE SUPPORT * The following functions form support user programs @@ -1668,7 +1711,8 @@ { struct ppp *ppp = tty2ppp (tty); __u8 c; - ssize_t len, indx; + int error; + ssize_t len, ret; #define GETC(c) \ { \ @@ -1682,28 +1726,34 @@ if (!ppp) return -EIO; - if (ppp->magic != PPP_MAGIC) - return -EIO; + /* if (ppp->magic != PPP_MAGIC) + return -EIO; */ CHECK_PPP (-ENXIO); - if (ppp->flags & SC_DEBUG) - printk (KERN_DEBUG - "ppp_tty_read: called buf=%p nr=%lu\n", - buf, (unsigned long)nr); +/* + * Before we attempt to write the frame to the user, ensure that the + * user has access to the pages for the total buffer length. + */ + error = verify_area (VERIFY_WRITE, buf, nr); + if (error != 0) + return (error); + /* * Acquire the read lock. */ for (;;) { ppp = tty2ppp (tty); - if (!ppp || ppp->magic != PPP_MAGIC || !ppp->inuse) + if (!ppp || ppp->magic != PPP_MAGIC || !ppp->inuse + || tty != ppp->tty) return 0; if (test_and_set_bit (0, &ppp->ubuf->locked) != 0) { +#if 0 if (ppp->flags & SC_DEBUG) printk (KERN_DEBUG "ppp_tty_read: sleeping(ubuf)\n"); - +#endif current->timeout = 0; current->state = TASK_INTERRUPTIBLE; schedule (); @@ -1712,13 +1762,7 @@ return -EINTR; continue; } -/* - * Before we attempt to write the frame to the user, ensure that the - * user has access to the pages for the total buffer length. - */ - indx = verify_area (VERIFY_WRITE, buf, nr); - if (indx != 0) - return (indx); + /* * Fetch the length of the buffer from the first two bytes. */ @@ -1729,90 +1773,77 @@ len = c << 8; GETC (c); len += c; + if (len) + break; } -/* - * If there is no length then wait for the data to arrive. - */ - if (len == 0) { - /* no data */ - clear_bit (0, &ppp->ubuf->locked); - if (file->f_flags & O_NONBLOCK) { - if (ppp->flags & SC_DEBUG) - printk (KERN_DEBUG - "ppp_tty_read: no data " - "(EAGAIN)\n"); - return -EAGAIN; - } - current->timeout = 0; - - if (ppp->flags & SC_DEBUG) - printk (KERN_DEBUG - "ppp_tty_read: sleeping(read_wait)\n"); - interruptible_sleep_on (&ppp->read_wait); - if (signal_pending(current)) - return -EINTR; - continue; - } /* - * Reset the time of the last read operation. + * If there is no length then wait for the data to arrive. */ + /* no data */ + clear_bit (0, &ppp->ubuf->locked); + if (file->f_flags & O_NONBLOCK) + return -EAGAIN; + current->timeout = 0; +#if 0 if (ppp->flags & SC_DEBUG) - printk (KERN_DEBUG "ppp_tty_read: len = %ld\n", - (long)len); + printk (KERN_DEBUG + "ppp_tty_read: sleeping(read_wait)\n"); +#endif + interruptible_sleep_on (&ppp->read_wait); + if (signal_pending(current)) + return -EINTR; + } + /* * Ensure that the frame will fit within the caller's buffer. If not, then * discard the frame from the input buffer. */ - if (len + 2 > nr) { - /* Can't copy it, update us_rbuff_head */ + if (len + 2 > nr) { + /* Can't copy it, update us_rbuff_head */ - if (ppp->flags & SC_DEBUG) - printk (KERN_DEBUG + if (ppp->flags & SC_DEBUG) + printk (KERN_DEBUG "ppp: read of %lu bytes too small for %ld " - "frame\n", (unsigned long)nr, (long)len + 2); - ppp->ubuf->tail += len; - ppp->ubuf->tail &= ppp->ubuf->size; - clear_bit (0, &ppp->ubuf->locked); - ppp->stats.ppp_ierrors++; - return -EOVERFLOW; - } -/* - * Before we attempt to write the frame to the user, ensure that the - * page tables are proper. - */ - indx = verify_area (VERIFY_WRITE, buf, len + 2); - if (indx != 0) { - ppp->ubuf->tail += len; - ppp->ubuf->tail &= ppp->ubuf->size; - clear_bit (0, &ppp->ubuf->locked); - return (indx); - } + "frame\n", (unsigned long) nr, (long) len + 2); + ppp->stats.ppp_ierrors++; + error = -EOVERFLOW; + goto out; + } + /* * Fake the insertion of the ADDRESS and CONTROL information because these * were not saved in the buffer. */ - put_user (PPP_ALLSTATIONS, buf++); - put_user (PPP_UI, buf++); + error = put_user((u_char) PPP_ALLSTATIONS, buf); + if (error) + goto out; + ++buf; + error = put_user((u_char) PPP_UI, buf); + if (error) + goto out; + ++buf; - indx = len; /* * Copy the received data from the buffer to the caller's area. */ - while (indx-- > 0) { - GETC (c); - put_user (c, buf); - ++buf; - } - - clear_bit (0, &ppp->ubuf->locked); - len += 2; /* Account for ADDRESS and CONTROL bytes */ - if (ppp->flags & SC_DEBUG) - printk (KERN_DEBUG - "ppp_tty_read: passing %ld bytes up\n", - (long) len); - return len; - } + ret = len + 2; /* Account for ADDRESS and CONTROL bytes */ + while (len-- > 0) { + GETC (c); + error = put_user(c, buf); + if (error) + goto out; + ++buf; + } + + clear_bit (0, &ppp->ubuf->locked); + return ret; + +out: + ppp->ubuf->tail += len; + ppp->ubuf->tail &= ppp->ubuf->size; + clear_bit (0, &ppp->ubuf->locked); + return error; #undef GETC } @@ -1829,7 +1860,7 @@ */ if (ppp->flags & SC_DEBUG) { if ((buf->count < 0) || (buf->count > 3000)) - printk (KERN_DEBUG "ppp_stuff_char: %x %d\n", + printk (KERN_DEBUG "ppp_stuff_char: %d %x\n", (unsigned int) buf->count, (unsigned int) chr); } @@ -1859,6 +1890,12 @@ __u16 write_fcs; int address, control; int proto; + + CHECK_PPP_VOID(); + CHECK_BUF_MAGIC(buf); + ++ppp->stats.ppp_opackets; + ppp->stats.ppp_ooctects += count; + /* * Insert the leading FLAG character */ @@ -1867,7 +1904,7 @@ if (non_ip || flag_time == 0) ins_char (buf, PPP_FLAG); else { - if (jiffies - ppp->last_xmit > flag_time) + if (jiffies - ppp->last_xmit >= flag_time) ins_char (buf, PPP_FLAG); } ppp->last_xmit = jiffies; @@ -1906,27 +1943,11 @@ write_fcs = buf->fcs ^ 0xFFFF; ppp_stuff_char (ppp, buf, write_fcs); ppp_stuff_char (ppp, buf, write_fcs >> 8); - - if (ppp->flags & SC_DEBUG) - printk (KERN_DEBUG "ppp_dev_xmit_lower: fcs is %hx\n", - write_fcs); /* * Add the trailing flag character */ ins_char (buf, PPP_FLAG); /* - * Print the buffer - */ - if (ppp->flags & SC_LOG_FLUSH) - ppp_print_buffer ("ppp flush", buf_base (buf), - buf->count); - else { - if (ppp->flags & SC_DEBUG) - printk (KERN_DEBUG - "ppp_dev_xmit: writing %d chars\n", - buf->count); - } -/* * Send the block to the tty driver. */ ppp->stats.ppp_obytes += buf->count; @@ -1934,7 +1955,7 @@ } /* - * Send an frame to the remote with the proper bsd compression. + * Compress and send an frame to the peer. * * Return 0 if frame was queued for transmission. * 1 if frame must be re-queued for later driver support. @@ -1948,6 +1969,9 @@ int address, control; __u8 *new_data; int new_count; + + CHECK_PPP(0); + CHECK_BUF_MAGIC(buf); /* * Print the buffer */ @@ -1967,7 +1991,7 @@ (control == PPP_UI) && (proto != PPP_LCP) && (proto != PPP_CCP)) { - new_data = kmalloc (count, GFP_ATOMIC); + new_data = kmalloc (ppp->mtu, GFP_ATOMIC); if (new_data == NULL) { if (ppp->flags & SC_DEBUG) printk (KERN_ERR @@ -1975,33 +1999,21 @@ return 1; } - new_count = bsd_compress (ppp->sc_xc_state, - data, - new_data, - count, - count); - - if (new_count > 0) { - ++ppp->stats.ppp_opackets; - ppp->stats.ppp_ooctects += new_count; + new_count = (*ppp->sc_xcomp->compress) + (ppp->sc_xc_state, data, new_data, count, ppp->mtu); - ppp_dev_xmit_lower (ppp, buf, new_data, - new_count, 0); + if (new_count > 0 && (ppp->flags & SC_CCP_UP)) { + ppp_dev_xmit_lower (ppp, buf, new_data, new_count, 0); kfree (new_data); return 0; } /* - * The frame could not be compressed. + * The frame could not be compressed, or it could not be sent in + * compressed form because CCP is not yet up. */ kfree (new_data); } /* - * The frame may not be compressed. Update the statistics before the - * count field is destroyed. The frame will be transmitted. - */ - ++ppp->stats.ppp_opackets; - ppp->stats.ppp_ooctects += count; -/* * Go to the escape encoding */ ppp_dev_xmit_lower (ppp, buf, data, count, !!(proto & 0xFF00)); @@ -2033,8 +2045,8 @@ */ case PPP_CCP: ppp_proto_ccp (ppp, - data + PPP_HARD_HDR_LEN, - len - PPP_HARD_HDR_LEN, + data + PPP_HDRLEN, + len - PPP_HDRLEN, 0); break; @@ -2056,7 +2068,8 @@ { struct ppp *ppp = tty2ppp (tty); __u8 *new_data; - ssize_t status; + int error; + /* * Verify the pointers. */ @@ -2070,13 +2083,13 @@ /* * Ensure that the caller does not wish to send too much. */ - if (count > PPP_MTU) { + if (count > PPP_MTU + PPP_HDRLEN) { if (ppp->flags & SC_DEBUG) printk (KERN_WARNING "ppp_tty_write: truncating user packet " - "from %lu to mtu %d\n", - (unsigned long) count, PPP_MTU); - count = PPP_MTU; + "from %lu to mtu %d\n", (unsigned long) count, + PPP_MTU + PPP_HDRLEN); + count = PPP_MTU + PPP_HDRLEN; } /* * Allocate a buffer for the data and fetch it from the user space. @@ -2089,17 +2102,28 @@ return 0; } /* + * Retrieve the user's buffer + */ + error = copy_from_user(new_data, data, count); + if (error) { + kfree (new_data); + return error; + } +/* * lock this PPP unit so we will be the only writer; * sleep if necessary */ while (lock_buffer (ppp->tbuf) != 0) { current->timeout = 0; +#if 0 if (ppp->flags & SC_DEBUG) printk (KERN_DEBUG "ppp_tty_write: sleeping\n"); +#endif interruptible_sleep_on (&ppp->write_wait); ppp = tty2ppp (tty); - if (!ppp || ppp->magic != PPP_MAGIC || !ppp->inuse) { + if (!ppp || ppp->magic != PPP_MAGIC || !ppp->inuse + || tty != ppp->tty) { kfree (new_data); return 0; } @@ -2110,24 +2134,25 @@ } } /* - * Ensure that the caller's buffer is valid. - */ - status = verify_area (VERIFY_READ, data, count); - if (status != 0) { - kfree (new_data); - ppp->tbuf->locked = 0; - return status; - } - - copy_from_user (new_data, data, count); -/* * Change the LQR frame */ count = send_revise_frame (ppp, new_data, count); /* * Send the data */ - ppp_dev_xmit_frame (ppp, ppp->tbuf, new_data, count); + if (PPP_PROTOCOL(new_data) == PPP_IP) { + /* + * IP frames can be sent by pppd when we're doing + * demand-dialling. We send them via ppp_dev_xmit_ip + * to make sure that VJ compression happens properly. + */ + ppp_dev_xmit_ip(ppp, ppp->tbuf, new_data + PPP_HDRLEN, + count - PPP_HDRLEN, NPMODE_PASS); + + } else { + ppp_dev_xmit_frame (ppp, ppp->tbuf, new_data, count); + } + kfree (new_data); return count; } @@ -2145,28 +2170,42 @@ int nb; __u8 *ptr; __u8 ccp_option[CCP_MAX_OPTION_LENGTH]; + unsigned long flags; + /* * Fetch the compression parameters */ - error = verify_area (VERIFY_READ, odp, sizeof (data)); - if (error == 0) { - copy_from_user (&data, odp, sizeof (data)); - nb = data.length; - ptr = data.ptr; - if ((__u32) nb >= (__u32)CCP_MAX_OPTION_LENGTH) - nb = CCP_MAX_OPTION_LENGTH; - - error = verify_area (VERIFY_READ, ptr, nb); - if(!error) - copy_from_user (ccp_option, ptr, nb); - } + error = copy_from_user(&data, odp, sizeof (data)); + if (error != 0) + return error; + + nb = data.length; + ptr = data.ptr; + if ((__u32) nb >= (__u32)CCP_MAX_OPTION_LENGTH) + nb = CCP_MAX_OPTION_LENGTH; + + error = copy_from_user(ccp_option, ptr, nb); if (error != 0) return error; if (ccp_option[1] < 2) /* preliminary check on the length byte */ return (-EINVAL); - cp = find_compressor ((int) (unsigned int) (__u8) ccp_option[0]); + save_flags(flags); + cli(); + ppp->flags &= ~(SC_COMP_RUN | SC_DECOMP_RUN); + restore_flags(flags); + + cp = find_compressor (ccp_option[0]); +#ifdef CONFIG_KERNELD + if (cp == NULL) { + char modname[32]; + sprintf(modname, "ppp-compress-%d", ccp_option[0]); + request_module(modname); + cp = find_compressor(ccp_option[0]); + } +#endif /* CONFIG_KERNELD */ + if (cp != (struct compressor *) 0) { /* * Found a handler for the protocol - try to allocate @@ -2182,11 +2221,14 @@ if (ppp->sc_xc_state == NULL) { if (ppp->flags & SC_DEBUG) - printk("ppp%ld: comp_alloc failed\n", - ppp2dev (ppp)->base_addr); + printk(KERN_DEBUG "%s: comp_alloc failed\n", + ppp->name); error = -ENOBUFS; + } else { + if (ppp->flags & SC_DEBUG) + printk(KERN_DEBUG "%s: comp_alloc -> %p\n", + ppp->name, ppp->sc_xc_state); } - ppp->flags &= ~SC_COMP_RUN; } else { if (ppp->sc_rc_state != NULL) (*ppp->sc_rcomp->decomp_free)(ppp->sc_rc_state); @@ -2194,18 +2236,21 @@ ppp->sc_rc_state = cp->decomp_alloc(ccp_option, nb); if (ppp->sc_rc_state == NULL) { if (ppp->flags & SC_DEBUG) - printk("ppp%ld: decomp_alloc failed\n", - ppp2dev (ppp)->base_addr); - error = ENOBUFS; + printk(KERN_DEBUG "%s: decomp_alloc failed\n", + ppp->name); + error = -ENOBUFS; + } else { + if (ppp->flags & SC_DEBUG) + printk(KERN_DEBUG "%s: decomp_alloc -> %p\n", + ppp->name, ppp->sc_rc_state); } - ppp->flags &= ~SC_DECOMP_RUN; } return (error); } if (ppp->flags & SC_DEBUG) - printk(KERN_DEBUG "ppp%ld: no compressor for [%x %x %x], %x\n", - ppp2dev (ppp)->base_addr, ccp_option[0], ccp_option[1], + printk(KERN_DEBUG "%s: no compressor for [%x %x %x], %x\n", + ppp->name, ccp_option[0], ccp_option[1], ccp_option[2], nb); return (-EINVAL); /* no handler found */ } @@ -2241,57 +2286,45 @@ */ switch (param2) { case PPPIOCSMRU: - error = verify_area (VERIFY_READ, (void *) param3, - sizeof (temp_i)); - if (error == 0) { - get_user (temp_i, (int *) param3); - if (ppp->flags & SC_DEBUG) - printk (KERN_INFO - "ppp_tty_ioctl: set mru to %x\n", temp_i); + error = get_user(temp_i, (int *) param3); + if (error != 0) + break; + if (ppp->flags & SC_DEBUG) + printk (KERN_INFO + "ppp_tty_ioctl: set mru to %x\n", temp_i); - if (ppp->mru != temp_i) - ppp_changedmtu (ppp, ppp2dev (ppp)->mtu, temp_i); - } + if (ppp->mru != temp_i) + ppp_changedmtu (ppp, ppp2dev (ppp)->mtu, temp_i); break; /* * Fetch the flags */ case PPPIOCGFLAGS: - error = verify_area (VERIFY_WRITE, (void *) param3, - sizeof (temp_i)); - if (error == 0) { - temp_i = (ppp->flags & SC_MASK); + temp_i = (ppp->flags & SC_MASK); #ifndef CHECK_CHARACTERS /* Don't generate errors if we don't check chars. */ - temp_i |= SC_RCV_B7_1 | SC_RCV_B7_0 | - SC_RCV_ODDP | SC_RCV_EVNP; + temp_i |= SC_RCV_B7_1 | SC_RCV_B7_0 | + SC_RCV_ODDP | SC_RCV_EVNP; #endif - put_user (temp_i, (int *) param3); - if (ppp->flags & SC_DEBUG) - printk (KERN_DEBUG - "ppp_tty_ioctl: get flags: addr %lx flags " - "%x\n", param3, temp_i); - } + error = put_user(temp_i, (int *) param3); break; /* * Set the flags for the various options */ case PPPIOCSFLAGS: - error = verify_area (VERIFY_READ, (void *) param3, - sizeof (temp_i)); - if (error == 0) { - get_user (temp_i, (int *) param3); - temp_i &= SC_MASK; - temp_i |= (ppp->flags & ~SC_MASK); - - if ((ppp->flags & SC_CCP_OPEN) && - (temp_i & SC_CCP_OPEN) == 0) - ppp_ccp_closed (ppp); - - if ((ppp->flags | temp_i) & SC_DEBUG) - printk (KERN_INFO - "ppp_tty_ioctl: set flags to %x\n", temp_i); - ppp->flags = temp_i; - } + error = get_user(temp_i, (int *) param3); + if (error != 0) + break; + temp_i &= SC_MASK; + temp_i |= (ppp->flags & ~SC_MASK); + + if ((ppp->flags & SC_CCP_OPEN) && + (temp_i & SC_CCP_OPEN) == 0) + ppp_ccp_closed (ppp); + + if ((ppp->flags | temp_i) & SC_DEBUG) + printk (KERN_INFO + "ppp_tty_ioctl: set flags to %x\n", temp_i); + ppp->flags = temp_i; break; /* * Set the compression mode @@ -2304,142 +2337,101 @@ * Retrieve the transmit async map */ case PPPIOCGASYNCMAP: - error = verify_area (VERIFY_WRITE, (void *) param3, - sizeof (temp_i)); - if (error == 0) { - put_user (ppp->xmit_async_map[0], (int *) param3); - if (ppp->flags & SC_DEBUG) - printk (KERN_INFO - "ppp_tty_ioctl: get asyncmap: addr " - "%lx asyncmap %x\n", - param3, - ppp->xmit_async_map[0]); - } + error = put_user(ppp->xmit_async_map[0], (int *) param3); break; /* * Set the transmit async map */ case PPPIOCSASYNCMAP: - error = verify_area (VERIFY_READ, (void *) param3, - sizeof (temp_i)); - if (error == 0) { - get_user (ppp->xmit_async_map[0],(int *) param3); - if (ppp->flags & SC_DEBUG) - printk (KERN_INFO - "ppp_tty_ioctl: set xmit asyncmap %x\n", - ppp->xmit_async_map[0]); - } + error = get_user(temp_i, (int *) param3); + if (error != 0) + break; + ppp->xmit_async_map[0] = temp_i; + if (ppp->flags & SC_DEBUG) + printk (KERN_INFO + "ppp_tty_ioctl: set xmit asyncmap %x\n", + ppp->xmit_async_map[0]); break; /* * Set the receive async map */ case PPPIOCSRASYNCMAP: - error = verify_area (VERIFY_READ, (void *) param3, - sizeof (temp_i)); - if (error == 0) { - get_user (ppp->recv_async_map,(int *) param3); - if (ppp->flags & SC_DEBUG) - printk (KERN_INFO - "ppp_tty_ioctl: set rcv asyncmap %x\n", - ppp->recv_async_map); - } + error = get_user(temp_i, (int *) param3); + if (error != 0) + break; + ppp->recv_async_map = temp_i; + if (ppp->flags & SC_DEBUG) + printk (KERN_INFO + "ppp_tty_ioctl: set rcv asyncmap %x\n", + ppp->recv_async_map); break; /* * Obtain the unit number for this device. */ case PPPIOCGUNIT: - error = verify_area (VERIFY_WRITE, (void *) param3, - sizeof (temp_i)); - if (error == 0) { - put_user (ppp2dev (ppp)->base_addr, (int *) param3); - if (ppp->flags & SC_DEBUG) - printk (KERN_INFO - "ppp_tty_ioctl: get unit: %ld", - ppp2dev (ppp)->base_addr); - } + error = put_user(ppp2dev (ppp)->base_addr, (int *) param3); + if (error != 0) + break; + if (ppp->flags & SC_DEBUG) + printk (KERN_INFO + "ppp_tty_ioctl: get unit: %ld\n", + ppp2dev (ppp)->base_addr); break; /* * Set the debug level */ case PPPIOCSDEBUG: - error = verify_area (VERIFY_READ, (void *) param3, - sizeof (temp_i)); - if (error == 0) { - get_user (temp_i, (int *) param3); - temp_i = (temp_i & 0x1F) << 16; - temp_i |= (ppp->flags & ~0x1F0000); - - if ((ppp->flags | temp_i) & SC_DEBUG) - printk (KERN_INFO - "ppp_tty_ioctl: set flags to %x\n", temp_i); - ppp->flags = temp_i; - } + error = get_user(temp_i, (int *) param3); + if (error != 0) + break; + temp_i = (temp_i & 0x1F) << 16; + temp_i |= (ppp->flags & ~0x1F0000); + + if ((ppp->flags | temp_i) & SC_DEBUG) + printk (KERN_INFO + "ppp_tty_ioctl: set flags to %x\n", temp_i); + ppp->flags = temp_i; break; /* * Get the debug level */ case PPPIOCGDEBUG: - error = verify_area (VERIFY_WRITE, (void *) param3, - sizeof (temp_i)); - if (error == 0) { - temp_i = (ppp->flags >> 16) & 0x1F; - put_user (temp_i, (int *) param3); - - if (ppp->flags & SC_DEBUG) - printk (KERN_INFO - "ppp_tty_ioctl: get debug level %d\n", - temp_i); - } + temp_i = (ppp->flags >> 16) & 0x1F; + error = put_user(temp_i, (int *) param3); break; /* * Get the times since the last send/receive frame operation */ case PPPIOCGIDLE: - error = verify_area (VERIFY_WRITE, (void *) param3, - sizeof (struct ppp_idle)); - if (error == 0) { + { struct ppp_idle cur_ddinfo; - unsigned long cur_jiffies = jiffies; /* change absolute times to relative times. */ - cur_ddinfo.xmit_idle = (cur_jiffies - ppp->ddinfo.xmit_idle) / HZ; - cur_ddinfo.recv_idle = (cur_jiffies - ppp->ddinfo.recv_idle) / HZ; - copy_to_user ((void *) param3, &cur_ddinfo, - sizeof (cur_ddinfo)); - if (ppp->flags & SC_DEBUG) - printk (KERN_INFO - "ppp_tty_ioctl: read demand dial info\n"); + cur_ddinfo.xmit_idle = (jiffies - ppp->last_xmit) / HZ; + cur_ddinfo.recv_idle = (jiffies - ppp->last_recv) / HZ; + error = copy_to_user((void *) param3, &cur_ddinfo, + sizeof (cur_ddinfo)); } break; /* * Retrieve the extended async map */ case PPPIOCGXASYNCMAP: - error = verify_area (VERIFY_WRITE, - (void *) param3, + error = copy_to_user((void *) param3, ppp->xmit_async_map, sizeof (ppp->xmit_async_map)); - if (error == 0) { - copy_to_user ((void *) param3, - ppp->xmit_async_map, - sizeof (ppp->xmit_async_map)); - - if (ppp->flags & SC_DEBUG) - printk (KERN_INFO - "ppp_tty_ioctl: get xasyncmap: addr %lx\n", - param3); - } break; /* * Set the async extended map */ case PPPIOCSXASYNCMAP: - error = verify_area (VERIFY_READ, (void *) param3, - sizeof (ppp->xmit_async_map)); - if (error == 0) { + { __u32 temp_tbl[8]; - copy_from_user (temp_tbl, (void *) param3, - sizeof (ppp->xmit_async_map)); + error = copy_from_user(temp_tbl, (void *) param3, + sizeof (temp_tbl)); + if (error != 0) + break; + temp_tbl[1] = 0x00000000; temp_tbl[2] &= ~0x40000000; temp_tbl[3] |= 0x60000000; @@ -2449,12 +2441,13 @@ (temp_tbl[6] & temp_tbl[7]) != 0) error = -EINVAL; else { - memcpy (ppp->xmit_async_map, temp_tbl, + memcpy (ppp->xmit_async_map, + temp_tbl, sizeof (ppp->xmit_async_map)); if (ppp->flags & SC_DEBUG) printk (KERN_INFO - "ppp_tty_ioctl: set xasyncmap\n"); + "ppp_tty_ioctl: set xasyncmap\n"); } } break; @@ -2462,48 +2455,50 @@ * Set the maximum VJ header compression slot number. */ case PPPIOCSMAXCID: - error = verify_area (VERIFY_READ, (void *) param3, - sizeof (temp_i)); - if (error == 0) { - get_user (temp_i, (int *) param3); - ++temp_i; - if (ppp->flags & SC_DEBUG) - printk (KERN_INFO - "ppp_tty_ioctl: set maxcid to %d\n", - temp_i); - if (ppp->slcomp != NULL) - slhc_free (ppp->slcomp); - ppp->slcomp = slhc_init (16, temp_i); + error = get_user(temp_i, (int *) param3); + if (error != 0) + break; + temp_i = (temp_i & 255) + 1; + if (ppp->flags & SC_DEBUG) + printk (KERN_INFO + "ppp_tty_ioctl: set maxcid to %d\n", + temp_i); + if (ppp->slcomp != NULL) + slhc_free (ppp->slcomp); + ppp->slcomp = slhc_init (16, temp_i); - if (ppp->slcomp == NULL) { - if (ppp->flags & SC_DEBUG) - printk (KERN_ERR + if (ppp->slcomp == NULL) { + if (ppp->flags & SC_DEBUG) + printk (KERN_ERR "ppp: no space for compression buffers!\n"); - ppp_release (ppp); - error = -ENOMEM; - } + ppp_release (ppp); + error = -ENOMEM; } break; case PPPIOCXFERUNIT: - ppp_tty_close_local (tty, current->pid); + ppp->backup_tty = tty; + ppp->sc_xfer = current->pid; break; case PPPIOCGNPMODE: case PPPIOCSNPMODE: - error = verify_area (VERIFY_READ, (void *) param3, - sizeof (struct npioctl)); - if (error == 0) { + { struct npioctl npi; - copy_from_user (&npi, - (void *) param3, - sizeof (npi)); + + error = copy_from_user(&npi, (void *) param3, + sizeof (npi)); + if (error != 0) + break; switch (npi.protocol) { case PPP_IP: npi.protocol = NP_IP; break; default: + if (ppp->flags & SC_DEBUG) + printk(KERN_DEBUG "pppioc[gs]npmode: " + "invalid proto %d\n", npi.protocol); error = -EINVAL; } @@ -2512,25 +2507,18 @@ if (param2 == PPPIOCGNPMODE) { npi.mode = ppp->sc_npmode[npi.protocol]; - error = verify_area (VERIFY_WRITE, - (void *) param3, - sizeof (npi)); - if (error != 0) - break; - copy_to_user ((void *) param3, - &npi, - sizeof (npi)); + error = copy_to_user((void *) param3, &npi, + sizeof (npi)); break; } - if (npi.mode != ppp->sc_npmode[npi.protocol]) { - ppp->sc_npmode[npi.protocol] = npi.mode; - if (npi.mode != NPMODE_QUEUE) { - /* ppp_requeue(ppp); maybe needed */ - ppp_tty_wakeup (ppp2tty(ppp)); - } - } + ppp->sc_npmode[npi.protocol] = npi.mode; + if (ppp->flags & SC_DEBUG) + printk(KERN_DEBUG "ppp: set np %d to %d\n", + npi.protocol, npi.mode); + ppp2dev(ppp)->tbusy = 0; + mark_bh(NET_BH); } break; /* @@ -2542,15 +2530,11 @@ break; case FIONREAD: - error = verify_area (VERIFY_WRITE, - (void *) param3, - sizeof (int)); - if (error == 0) { + { int count = ppp->ubuf->tail - ppp->ubuf->head; if (count < 0) count += (ppp->ubuf->size + 1); - - put_user (count, (int *) param3); + error = put_user(count, (int *) param3); } break; /* @@ -2581,13 +2565,14 @@ struct ppp *ppp = tty2ppp (tty); unsigned int mask = 0; - if(ppp && ppp->magic == PPP_MAGIC) { + if (ppp && ppp->magic == PPP_MAGIC && tty == ppp->tty) { CHECK_PPP (0); poll_wait(&ppp->read_wait, wait); poll_wait(&ppp->write_wait, wait); /* Must lock the user buffer area while checking. */ + CHECK_BUF_MAGIC(ppp->ubuf); if(test_and_set_bit(0, &ppp->ubuf->locked) == 0) { if(ppp->ubuf->head != ppp->ubuf->tail) mask |= POLLIN | POLLRDNORM; @@ -2647,10 +2632,6 @@ struct ppp *ppp = dev2ppp (dev); if (ppp2tty (ppp) == NULL) { - if (ppp->flags & SC_DEBUG) - printk (KERN_ERR - "ppp: %s not connected to a TTY! can't go down!\n", - dev->name); return -ENXIO; } /* @@ -2673,19 +2654,12 @@ ppp_dev_ioctl_version (struct ppp *ppp, struct ifreq *ifr) { int error; - int len; - char *result; -/* - * Must have write access to the buffer. - */ - result = (char *) ifr->ifr_ifru.ifru_data; - len = strlen (szVersion) + 1; - error = verify_area (VERIFY_WRITE, result, len); + char *result = (char *) ifr->ifr_ifru.ifru_data; + int len = strlen (szVersion) + 1; /* * Move the version data */ - if (error == 0) - copy_to_user (result, szVersion, len); + error = copy_to_user(result, szVersion, len); return error; } @@ -2700,18 +2674,11 @@ struct ppp_stats *result, temp; int error; /* - * Must have write access to the buffer. - */ - result = (struct ppp_stats *) ifr->ifr_ifru.ifru_data; - error = verify_area (VERIFY_WRITE, - result, - sizeof (temp)); -/* * Supply the information for the caller. First move the version data * then move the ppp stats; and finally the vj stats. */ memset (&temp, 0, sizeof(temp)); - if (error == 0 && dev->flags & IFF_UP) { + if (dev->flags & IFF_UP) { memcpy (&temp.p, &ppp->stats, sizeof (struct pppstat)); if (ppp->slcomp != NULL) { temp.vj.vjs_packets = ppp->slcomp->sls_o_compressed+ @@ -2726,8 +2693,10 @@ } } - if (error == 0) - copy_to_user (result, &temp, sizeof (temp)); + result = (struct ppp_stats *) ifr->ifr_ifru.ifru_data; + + error = copy_to_user(result, &temp, sizeof (temp)); + return error; } @@ -2741,17 +2710,10 @@ struct ppp_comp_stats *result, temp; int error; /* - * Must have write access to the buffer. - */ - result = (struct ppp_comp_stats *) ifr->ifr_ifru.ifru_data; - error = verify_area (VERIFY_WRITE, - result, - sizeof (temp)); -/* * Supply the information for the caller. */ memset (&temp, 0, sizeof(temp)); - if (error == 0 && dev->flags & IFF_UP) { + if (dev->flags & IFF_UP) { if (ppp->sc_xc_state != NULL) (*ppp->sc_xcomp->comp_stat) (ppp->sc_xc_state, &temp.c); @@ -2763,8 +2725,10 @@ /* * Move the data to the caller's buffer */ - if (error == 0) - copy_to_user (result, &temp, sizeof (temp)); + result = (struct ppp_comp_stats *) ifr->ifr_ifru.ifru_data; + + error = copy_to_user(result, &temp, sizeof (temp)); + return error; } @@ -2777,6 +2741,8 @@ { struct ppp *ppp = dev2ppp (dev); int error; + + CHECK_PPP_MAGIC(ppp); /* * Process the requests */ @@ -2805,102 +2771,56 @@ * * Return 0 if frame was queued for transmission. * 1 if frame must be re-queued for later driver support. + * -1 if frame should be dropped. */ static int -ppp_dev_xmit_ip (struct device *dev, struct ppp *ppp, __u8 *data) +ppp_dev_xmit_ip (struct ppp *ppp, struct ppp_buffer *buf, + __u8 *data, int len, enum NPmode npmode) { - int proto = PPP_IP; - int len; - struct ppp_hdr *hdr; - struct tty_struct *tty = ppp2tty (ppp); -/* - * Obtain the length from the IP header. - */ - len = ((struct iphdr *)data) -> tot_len; - len = ntohs (len); -/* - * Validate the tty interface - */ - if (tty == NULL) { - if (ppp->flags & SC_DEBUG) - printk (KERN_ERR - "ppp_dev_xmit: %s not connected to a TTY!\n", - dev->name); - return 0; - } -/* - * Ensure that the PPP device is still up - */ - if (!(dev->flags & IFF_UP)) { - if (ppp->flags & SC_DEBUG) - printk (KERN_WARNING - "ppp_dev_xmit: packet sent on interface %s," - " which is down for IP\n", - dev->name); - return 0; - } + int proto = PPP_IP; + __u8 *hdr; /* * Branch on the type of processing for the IP frame. */ - switch (ppp->sc_npmode[NP_IP]) { + switch (npmode) { case NPMODE_PASS: break; - case NPMODE_ERROR: + case NPMODE_QUEUE: + /* + * We may not send the packet now, so drop it. + * XXX It would be nice to be able to return it to the + * network system to be queued and retransmitted later. + */ if (ppp->flags & SC_DEBUG) - printk (KERN_WARNING - "ppp_dev_xmit: npmode = NPMODE_ERROR on %s\n", - dev->name); - return 0; + printk(KERN_DEBUG "%s: returning frame\n", + ppp->name); + return -1; + case NPMODE_ERROR: case NPMODE_DROP: if (ppp->flags & SC_DEBUG) - printk (KERN_WARNING - "ppp_dev_xmit: npmode = NPMODE_DROP on %s\n", - dev->name); - return 0; - - case NPMODE_QUEUE: - break; + printk (KERN_DEBUG + "ppp_dev_xmit: npmode = %d on %s\n", + ppp->sc_npmode[NP_IP], ppp->name); + return -1; default: if (ppp->flags & SC_DEBUG) printk (KERN_WARNING "ppp_dev_xmit: unknown npmode %d on %s\n", - ppp->sc_npmode[NP_IP], - dev->name); - return 0; - } -/* - * Detect a change in the transfer size - */ - if (ppp->mtu != ppp2dev (ppp)->mtu) { - ppp_changedmtu (ppp, - ppp2dev (ppp)->mtu, - ppp->mru); - } -/* - * Acquire the lock on the transmission buffer. If the buffer was busy then - * mark the device as busy. - */ - if (lock_buffer (ppp->wbuf) != 0) { - dev->tbusy = 1; - return 1; + ppp->sc_npmode[NP_IP], ppp->name); + return -1; } /* - * Print the frame being sent - */ - if (ppp->flags & SC_LOG_OUTPKT) - ppp_print_buffer ("ppp outpkt", data, len); -/* * At this point, the buffer will be transmitted. There is no other exit. * * Try to compress the header. */ if (ppp->flags & SC_COMP_TCP) { len = slhc_compress (ppp->slcomp, data, len, - buf_base (ppp->cbuf) + PPP_HARD_HDR_LEN, + buf_base (ppp->cbuf) + PPP_HDRLEN, &data, (ppp->flags & SC_NO_TCP_CCID) == 0); @@ -2916,83 +2836,40 @@ /* * Send the frame */ - len += PPP_HARD_HDR_LEN; - hdr = &((struct ppp_hdr *) data)[-1]; + len += PPP_HDRLEN; + hdr = data - PPP_HDRLEN; - hdr->address = PPP_ALLSTATIONS; - hdr->control = PPP_UI; - hdr->protocol[0] = 0; - hdr->protocol[1] = proto; + hdr[0] = PPP_ALLSTATIONS; + hdr[1] = PPP_UI; + hdr[2] = 0; + hdr[3] = proto; - return ppp_dev_xmit_frame (ppp, ppp->wbuf, (__u8 *) hdr, len); + return ppp_dev_xmit_frame (ppp, buf, hdr, len); } /* - * Send an IPX (or any other non-IP) frame to the remote. + * Send a non-IP data frame (such as an IPX frame) to the remote. * * Return 0 if frame was queued for transmission. * 1 if frame must be re-queued for later driver support. */ static int -ppp_dev_xmit_ipx (struct device *dev, struct ppp *ppp, +ppp_dev_xmit_other (struct device *dev, struct ppp *ppp, __u8 *data, int len, int proto) { - struct tty_struct *tty = ppp2tty (ppp); - struct ppp_hdr *hdr; -/* - * Validate the tty interface - */ - if (tty == NULL) { - if (ppp->flags & SC_DEBUG) - printk (KERN_ERR - "ppp_dev_xmit: %s not connected to a TTY!\n", - dev->name); - return 0; - } -/* - * Ensure that the PPP device is still up - */ - if (!(dev->flags & IFF_UP)) { - if (ppp->flags & SC_DEBUG) - printk (KERN_WARNING - "ppp_dev_xmit: packet sent on interface %s," - " which is down\n", - dev->name); - return 0; - } -/* - * Detect a change in the transfer size - */ - if (ppp->mtu != ppp2dev (ppp)->mtu) { - ppp_changedmtu (ppp, - ppp2dev (ppp)->mtu, - ppp->mru); - } -/* - * Acquire the lock on the transmission buffer. If the buffer was busy then - * mark the device as busy. - */ - if (lock_buffer (ppp->wbuf) != 0) { - dev->tbusy = 1; - return 1; - } -/* - * Print the frame being sent - */ - if (ppp->flags & SC_LOG_OUTPKT) - ppp_print_buffer ("ppp outpkt", data, len); + __u8 *hdr; /* * Send the frame */ - len += PPP_HARD_HDR_LEN; - hdr = &((struct ppp_hdr *) data)[-1]; + len += PPP_HDRLEN; + hdr = data - PPP_HDRLEN; - hdr->address = PPP_ALLSTATIONS; - hdr->control = PPP_UI; - hdr->protocol[0] = proto >> 8; - hdr->protocol[1] = proto; + hdr[0] = PPP_ALLSTATIONS; + hdr[1] = PPP_UI; + hdr[2] = proto >> 8; + hdr[3] = proto; - return ppp_dev_xmit_frame (ppp, ppp->wbuf, (__u8 *) hdr, len); + return ppp_dev_xmit_frame (ppp, ppp->wbuf, hdr, len); } /* @@ -3014,25 +2891,14 @@ printk (KERN_WARNING "ppp_dev_xmit: null packet!\n"); return 0; } - /* * Avoid timing problem should tty hangup while data is queued to be sent */ if (!ppp->inuse) { dev_kfree_skb (skb, FREE_WRITE); - printk(KERN_WARNING "ppp: I am dying to know, are you still alive?\n"); -#if 0 - dev_close (dev); -#endif return 0; } /* - * Validate the tty linkage - */ - if (ppp->flags & SC_DEBUG) - printk (KERN_DEBUG "ppp_dev_xmit [%s]: skb %p\n", - dev->name, skb); -/* * Validate the tty interface */ if (tty == NULL) { @@ -3048,25 +2914,49 @@ */ len = skb->len; data = skb_data(skb); -/* - * Bug trap for null data. Release the skb and bail out. - */ - if(data == NULL) { - printk("ppp_dev_xmit: data=NULL before ppp_dev_xmit_ip.\n"); + + if (data == (__u8 *) 0) { + if (ppp->flags & SC_DEBUG) + printk (KERN_CRIT "ppp_dev_xmit: %s Null skb data\n", + dev->name); dev_kfree_skb (skb, FREE_WRITE); return 0; } /* + * Detect a change in the transfer size + */ + if (ppp->mtu != ppp2dev (ppp)->mtu) { + ppp_changedmtu (ppp, + ppp2dev (ppp)->mtu, + ppp->mru); + } +/* + * Acquire the lock on the transmission buffer. If the buffer was busy then + * mark the device as busy. + * We also require that ppp->tbuf be unlocked, in order to serialize + * calls to ppp_dev_xmit_frame (which does compression) and the output + * of frames w.r.t. tty writes from pppd. + */ + CHECK_BUF_MAGIC(ppp->wbuf); + if (ppp->tbuf->locked || lock_buffer (ppp->wbuf) != 0) { + dev->tbusy = 1; + if (ppp->flags & SC_DEBUG) + printk(KERN_DEBUG "dev_xmit blocked, t=%lu w=%lu\n", + ppp->tbuf->locked, ppp->wbuf->locked); + return 1; + } +/* * Look at the protocol in the skb to determine the difference between * an IP frame and an IPX frame. */ switch (ntohs (skb->protocol)) { case ETH_P_IPX: - answer = ppp_dev_xmit_ipx (dev, ppp, data, len, PPP_IPX); + answer = ppp_dev_xmit_other (dev, ppp, data, len, PPP_IPX); break; case ETH_P_IP: - answer = ppp_dev_xmit_ip (dev, ppp, data); + answer = ppp_dev_xmit_ip (ppp, ppp->wbuf, data, len, + ppp->sc_npmode[NP_IP]); break; default: /* All others have no support at this time. */ @@ -3077,8 +2967,18 @@ * This is the end of the transmission. Release the buffer if it was sent. */ if (answer == 0) { + /* packet queued OK */ dev_kfree_skb (skb, FREE_WRITE); - ppp->ddinfo.xmit_idle = jiffies; + } else { + ppp->wbuf->locked = 0; + if (answer < 0) { + /* packet should be dropped */ + dev_kfree_skb (skb, FREE_WRITE); + answer = 0; + } else { + /* packet should be queued for later */ + dev->tbusy = 1; + } } return answer; } @@ -3091,29 +2991,15 @@ ppp_dev_stats (struct device *dev) { struct ppp *ppp = dev2ppp (dev); - static struct net_device_stats ppp_stats; - ppp_stats.rx_packets = ppp->stats.ppp_ipackets; - ppp_stats.rx_errors = ppp->stats.ppp_ierrors; - ppp_stats.rx_dropped = ppp->stats.ppp_ierrors; - ppp_stats.rx_fifo_errors = 0; - ppp_stats.rx_length_errors = 0; - ppp_stats.rx_over_errors = 0; - ppp_stats.rx_crc_errors = 0; - ppp_stats.rx_frame_errors = 0; - ppp_stats.tx_packets = ppp->stats.ppp_opackets; - ppp_stats.tx_errors = ppp->stats.ppp_oerrors; - ppp_stats.tx_dropped = 0; - ppp_stats.tx_fifo_errors = 0; - ppp_stats.collisions = 0; - ppp_stats.tx_carrier_errors = 0; - ppp_stats.tx_aborted_errors = 0; - ppp_stats.tx_window_errors = 0; - ppp_stats.tx_heartbeat_errors = 0; + ppp->estats.rx_packets = ppp->stats.ppp_ipackets; + ppp->estats.rx_errors = ppp->stats.ppp_ierrors; + ppp->estats.tx_packets = ppp->stats.ppp_opackets; + ppp->estats.tx_errors = ppp->stats.ppp_oerrors; + ppp->estats.rx_bytes = ppp->stats.ppp_ibytes; + ppp->estats.tx_bytes = ppp->stats.ppp_obytes; - if (ppp->flags & SC_DEBUG) - printk (KERN_INFO "ppp_dev_stats called"); - return &ppp_stats; + return &ppp->estats; } /************************************************************* @@ -3125,28 +3011,16 @@ static struct ppp * ppp_find (int pid_value) { - int if_num; - ppp_ctrl_t *ctl; struct ppp *ppp; - /* try to find the exact same free device which we had before */ - ctl = ppp_list; - if_num = 0; - - while (ctl) { - ppp = ctl2ppp (ctl); - if (!test_and_set_bit(0, &ppp->inuse)) { - if (ppp->sc_xfer == pid_value) { - ppp->sc_xfer = 0; - return (ppp); - } - clear_bit (0, &ppp->inuse); - } - ctl = ctl->next; - if (++if_num == max_dev) + /* try to find the device which this pid is already using */ + for (ppp = ppp_list; ppp != 0; ppp = ppp->next) { + if (ppp->inuse && ppp->sc_xfer == pid_value) { + ppp->sc_xfer = 0; break; + } } - return NULL; + return ppp; } /* allocate or create a PPP channel */ @@ -3155,65 +3029,58 @@ { int if_num; int status; - ppp_ctrl_t *ctl; struct device *dev; struct ppp *ppp; /* try to find an free device */ - ctl = ppp_list; - if_num = 0; - - while (ctl) { - ppp = ctl2ppp (ctl); + if_num = 0; + for (ppp = ppp_list; ppp != 0; ppp = ppp->next) { if (!test_and_set_bit(0, &ppp->inuse)) - return (ppp); - ctl = ctl->next; - if (++if_num == max_dev) - return (NULL); - } -/* - * There are no available items. Allocate a device from the system pool - */ - ctl = (ppp_ctrl_t *) kmalloc (sizeof(ppp_ctrl_t), GFP_KERNEL); - if (ctl) { - (void) memset(ctl, 0, sizeof(ppp_ctrl_t)); - ppp = ctl2ppp (ctl); - dev = ctl2dev (ctl); - - /* initialize channel control data */ - set_bit(0, &ppp->inuse); - - ppp->line = if_num; - ppp->tty = NULL; - ppp->dev = dev; - - dev->next = NULL; - dev->init = ppp_init_dev; - dev->name = ctl->name; - dev->base_addr = (__u32) if_num; - dev->priv = (void *) ppp; - - sprintf (dev->name, "ppp%d", if_num); - - /* link in the new channel */ - ctl->next = ppp_list; - ppp_list = ctl; - - /* register device so that we can be ifconfig'd */ - /* ppp_init_dev() will be called as a side-effect */ - - status = register_netdev (dev); - if (status == 0) { - printk (KERN_INFO "registered device %s\n", dev->name); - return (ppp); - } + return ppp; + ++if_num; + } +/* + * There are no available units, so make a new one. + */ + ppp = (struct ppp *) kmalloc (sizeof(struct ppp), GFP_KERNEL); + if (ppp == 0) + return 0; + memset(ppp, 0, sizeof(*ppp)); + + /* initialize channel control data */ + set_bit(0, &ppp->inuse); + ppp->line = if_num; + ppp->tty = NULL; + ppp->backup_tty = NULL; + if (ppp_last == 0) + ppp_list = ppp; + else + ppp_last->next = ppp; + ppp_last = ppp; + ppp->next = 0; + + dev = ppp2dev(ppp); + dev->next = NULL; + dev->init = ppp_init_dev; + dev->name = ppp->name; + sprintf(dev->name, "ppp%d", if_num); + dev->base_addr = (__u32) if_num; + dev->priv = (void *) ppp; + + /* register device so that we can be ifconfig'd */ + /* ppp_init_dev() will be called as a side-effect */ + status = register_netdev (dev); + if (status == 0) { + printk (KERN_INFO "registered device %s\n", dev->name); + } else { printk (KERN_ERR "ppp_alloc - register_netdev(%s) = %d failure.\n", dev->name, status); + ppp = NULL; /* This one will forever be busy as it is not initialized */ } - return (NULL); + return ppp; } /* @@ -3292,7 +3159,7 @@ static struct compressor *find_compressor (int type) { struct compressor_link *lnk; - __u32 flags; + unsigned long flags; save_flags(flags); cli(); @@ -3310,12 +3177,10 @@ return (struct compressor *) 0; } -#ifdef CONFIG_MODULES - static int ppp_register_compressor (struct compressor *cp) { struct compressor_link *new; - __u32 flags; + unsigned long flags; new = (struct compressor_link *) kmalloc (sizeof (struct compressor_link), GFP_KERNEL); @@ -3343,7 +3208,7 @@ { struct compressor_link *prev = (struct compressor_link *) 0; struct compressor_link *lnk; - __u32 flags; + unsigned long flags; save_flags(flags); cli(); @@ -3364,8 +3229,6 @@ restore_flags(flags); } -#endif - /************************************************************* * Module support routines *************************************************************/ @@ -3381,7 +3244,6 @@ if (status != 0) printk (KERN_INFO "PPP: ppp_init() failure %d\n", status); - return (status); } @@ -3389,27 +3251,23 @@ cleanup_module(void) { int status; - ppp_ctrl_t *ctl, *next_ctl; struct device *dev; - struct ppp *ppp; + struct ppp *ppp, *next_ppp; int busy_flag = 0; /* * Ensure that the devices are not in operation. */ - ctl = ppp_list; - while (ctl) { - ppp = ctl2ppp (ctl); + for (ppp = ppp_list; ppp != 0; ppp = ppp->next) { if (ppp->inuse && ppp->tty != NULL) { busy_flag = 1; break; } - dev = ctl2dev (ctl); + dev = ppp2dev (ppp); if (dev->start || dev->flags & IFF_UP) { busy_flag = 1; break; } - ctl = ctl->next; } /* * Ensure that there are no compressor modules registered @@ -3437,16 +3295,11 @@ /* * De-register the devices so that there is no problem with them */ - next_ctl = ppp_list; - while (next_ctl) { - ctl = next_ctl; - next_ctl = ctl->next; - ppp = ctl2ppp (ctl); - dev = ctl2dev (ctl); - - ppp_release (ppp); - unregister_netdev (dev); - kfree (ctl); + for (ppp = ppp_list; ppp != 0; ppp = next_ppp) { + next_ppp = ppp->next; + ppp_release (ppp); + unregister_netdev (&ppp->dev); + kfree (ppp); } } #endif diff -u --recursive --new-file v2.1.75/linux/drivers/net/ppp_deflate.c linux/drivers/net/ppp_deflate.c --- v2.1.75/linux/drivers/net/ppp_deflate.c Sat Nov 29 11:25:10 1997 +++ linux/drivers/net/ppp_deflate.c Tue Dec 23 10:57:31 1997 @@ -55,11 +55,7 @@ #include #include - -#undef PACKETPTR -#define PACKETPTR 1 #include -#undef PACKETPTR #include "zlib.c" diff -u --recursive --new-file v2.1.75/linux/drivers/net/zlib.c linux/drivers/net/zlib.c --- v2.1.75/linux/drivers/net/zlib.c Sat Nov 29 11:25:10 1997 +++ linux/drivers/net/zlib.c Tue Dec 23 10:57:31 1997 @@ -1,5 +1,5 @@ /* - * This file is derived from various .h and .c files from the zlib-0.95 + * This file is derived from various .h and .c files from the zlib-1.0.4 * distribution by Jean-loup Gailly and Mark Adler, with some additions * by Paul Mackerras to aid in implementing Deflate compression and * decompression for PPP packets. See zlib.h for conditions of @@ -8,15 +8,13 @@ * Changes that have been made include: * - added Z_PACKET_FLUSH (see zlib.h for details) * - added inflateIncomp and deflateOutputPending - * - changed DEBUG_ZLIB to DEBUG_ZLIB - * - use ZALLOC_INIT rather than ZALLOC for allocations during initialization * - allow strm->next_out to be NULL, meaning discard the output * - * $Id: zlib.c,v 1.2 1997/10/02 17:59:23 davem Exp $ + * $Id: zlib.c,v 1.3 1997/12/23 10:47:42 paulus Exp $ */ /* - * ==FILEVERSION 970501== + * ==FILEVERSION 971210== * * This marker is used by the Linux installation script to determine * whether an up-to-date version of this file is already installed. @@ -50,23 +48,20 @@ #include "zlib.h" #if defined(KERNEL) || defined(_KERNEL) -/* Assume this is a *BSD kernel */ +/* Assume this is a *BSD or SVR4 kernel */ #include #include #include # define HAVE_MEMCPY -# define zmemcpy(d, s, n) bcopy((s), (d), (n)) -# define zmemzero bzero -# define zmemcmp bcmp +# define memcpy(d, s, n) bcopy((s), (d), (n)) +# define memset(d, v, n) bzero((d), (n)) +# define memcmp bcmp #else #if defined(__KERNEL__) /* Assume this is a Linux kernel */ #include #define HAVE_MEMCPY -#define zmemcpy memcpy -#define zmemzero(dest, len) memset(dest, 0, len) -#define zmemcmp memcmp #else /* not kernel */ @@ -959,7 +954,7 @@ if (len > strm->avail_out) len = strm->avail_out; if (len == 0) return; - if (strm->next_out != NULL) { + if (strm->next_out != Z_NULL) { zmemcpy(strm->next_out, s->pending_out, len); strm->next_out += len; } @@ -4893,7 +4888,7 @@ z->adler = s->check = (*s->checkfn)(s->check, q, n); /* copy as far as end of window */ - if (p != NULL) { + if (p != Z_NULL) { zmemcpy(p, q, n); p += n; } @@ -4921,7 +4916,7 @@ z->adler = s->check = (*s->checkfn)(s->check, q, n); /* copy */ - if (p != NULL) { + if (p != Z_NULL) { zmemcpy(p, q, n); p += n; } diff -u --recursive --new-file v2.1.75/linux/drivers/net/zlib.h linux/drivers/net/zlib.h --- v2.1.75/linux/drivers/net/zlib.h Sat Nov 29 11:25:10 1997 +++ linux/drivers/net/zlib.h Tue Dec 23 10:57:31 1997 @@ -1,14 +1,14 @@ -/* $Id: zlib.h,v 1.1 1997/10/02 02:35:37 paulus Exp $ */ +/* $Id: zlib.h,v 1.2 1997/12/23 10:47:44 paulus Exp $ */ /* - * This file is derived from zlib.h and zconf.h from the zlib-0.95 + * This file is derived from zlib.h and zconf.h from the zlib-1.0.4 * distribution by Jean-loup Gailly and Mark Adler, with some additions * by Paul Mackerras to aid in implementing Deflate compression and * decompression for PPP packets. */ /* - * ==FILEVERSION 970501== + * ==FILEVERSION 971127== * * This marker is used by the Linux installation script to determine * whether an up-to-date version of this file is already installed. diff -u --recursive --new-file v2.1.75/linux/drivers/pci/pci.c linux/drivers/pci/pci.c --- v2.1.75/linux/drivers/pci/pci.c Sun Dec 21 22:36:13 1997 +++ linux/drivers/pci/pci.c Tue Dec 23 14:37:32 1997 @@ -50,11 +50,12 @@ DEVICE( NCR, NCR_53C895, "53c895"), DEVICE( NCR, NCR_53C885, "53c885"), DEVICE( NCR, NCR_53C875, "53c875"), - DEVICE( NCR, NCR_53C876, "53c876"), + DEVICE( NCR, NCR_53C875J, "53c875J"), DEVICE( ATI, ATI_68800, "68800AX"), DEVICE( ATI, ATI_215CT222, "215CT222"), DEVICE( ATI, ATI_210888CX, "210888CX"), DEVICE( ATI, ATI_215GB, "Mach64 GB"), + DEVICE( ATI, ATI_215GD, "Mach64 GD (Rage Pro)"), DEVICE( ATI, ATI_215GP, "Mach64 GP (Rage Pro)"), DEVICE( ATI, ATI_215GT, "Mach64 GT (Rage II)"), DEVICE( ATI, ATI_215GTB, "Mach64 GT (Rage II)"), @@ -110,7 +111,7 @@ DEVICE( AMD, AMD_SCSI, "53C974"), DEVICE( TRIDENT, TRIDENT_9420, "TG 9420"), DEVICE( TRIDENT, TRIDENT_9440, "TG 9440"), - DEVICE( TRIDENT, TRIDENT_9660, "TG 9660"), + DEVICE( TRIDENT, TRIDENT_9660, "TG 9660 / Cyber9385"), DEVICE( TRIDENT, TRIDENT_9750, "Image 975"), DEVICE( AI, AI_M1435, "M1435"), DEVICE( MATROX, MATROX_MGA_2, "Atlas PX2085"), @@ -186,6 +187,14 @@ DEVICE( NEXGEN, NEXGEN_82C501, "82C501"), DEVICE( QLOGIC, QLOGIC_ISP1020, "ISP1020"), DEVICE( QLOGIC, QLOGIC_ISP1022, "ISP1022"), + DEVICE( CYRIX, CYRIX_5510, "5510"), + DEVICE( CYRIX, CYRIX_PCI_MASTER,"PCI Master"), + DEVICE( CYRIX, CYRIX_5520, "5520"), + DEVICE( CYRIX, CYRIX_5530_LEGACY,"5530 Kahlua Legacy"), + DEVICE( CYRIX, CYRIX_5530_SMI, "5530 Kahlua SMI"), + DEVICE( CYRIX, CYRIX_5530_IDE, "5530 Kahlua IDE"), + DEVICE( CYRIX, CYRIX_5530_AUDIO,"5530 Kahlua Audio"), + DEVICE( CYRIX, CYRIX_5530_VIDEO,"5530 Kahlua Video"), DEVICE( LEADTEK, LEADTEK_805, "S3 805"), DEVICE( CONTAQ, CONTAQ_82C599, "82C599"), DEVICE( OLICOM, OLICOM_OC3136, "OC-3136/3137"), @@ -245,7 +254,8 @@ DEVICE( TEKRAM2, TEKRAM2_690c, "DC690c"), DEVICE( TUNDRA, TUNDRA_CA91C042,"CA91C042 Universe"), DEVICE( AMCC, AMCC_MYRINET, "Myrinet PCI (M2-PCI-32)"), - DEVICE( AMCC, AMCC_S5933, "S5933"), + DEVICE( AMCC, AMCC_S5933, "S5933 PCI44"), + DEVICE( AMCC, AMCC_S5933_HEPC3,"S5933 Traquair HEPC3"), DEVICE( INTERG, INTERG_1680, "IGA-1680"), DEVICE( INTERG, INTERG_1682, "IGA-1682"), DEVICE( REALTEK, REALTEK_8029, "8029"), @@ -311,6 +321,7 @@ DEVICE( DIGI, DIGI_RIGHTSWITCH, "RightSwitch SE-6"), DEVICE( MUTECH, MUTECH_MV1000, "MV-1000"), DEVICE( RENDITION, RENDITION_VERITE,"Verite 1000"), + DEVICE( RENDITION, RENDITION_VERITE2100,"Verite 2100"), DEVICE( TOSHIBA, TOSHIBA_601, "Laptop"), DEVICE( RICOH, RICOH_RL5C466, "RL5C466"), DEVICE( ZEITNET, ZEITNET_1221, "1221"), @@ -336,6 +347,9 @@ DEVICE( CYCLADES, CYCLOM_Z_Lo, "Cyclom-Z below 1Mbyte"), DEVICE( CYCLADES, CYCLOM_Z_Hi, "Cyclom-Z above 1Mbyte"), DEVICE( 3DFX, 3DFX_VOODOO, "Voodoo"), + DEVICE( STALLION, STALLION_ECHPCI832,"EasyConnection 8/32"), + DEVICE( STALLION, STALLION_ECHPCI864,"EasyConnection 8/64"), + DEVICE( STALLION, STALLION_EIOPCI,"EasyIO"), DEVICE( SIGMADES, SIGMADES_6425, "REALmagic64/GX"), DEVICE( OPTIBASE, OPTIBASE_FORGE, "MPEG Forge"), DEVICE( OPTIBASE, OPTIBASE_FUSION,"MPEG Fusion"), @@ -371,6 +385,9 @@ DEVICE( S3, S3_PLATO_PXG, "PLATO/PX (graphics)"), DEVICE( S3, S3_ViRGE_DXGX, "ViRGE/DX or /GX"), DEVICE( S3, S3_ViRGE_GX2, "ViRGE/GX2"), + DEVICE( S3, S3_ViRGE_MX, "ViRGE/MX"), + DEVICE( S3, S3_ViRGE_MXP, "ViRGE/MX+"), + DEVICE( S3, S3_ViRGE_MXPMV, "ViRGE/MX+MV"), DEVICE( INTEL, INTEL_82375, "82375EB"), DEVICE( INTEL, INTEL_82424, "82424ZX Saturn"), DEVICE( INTEL, INTEL_82378, "82378IB"), @@ -582,6 +599,7 @@ case PCI_VENDOR_ID_APPLE: return "Apple"; case PCI_VENDOR_ID_NEXGEN: return "Nexgen"; case PCI_VENDOR_ID_QLOGIC: return "Q Logic"; + case PCI_VENDOR_ID_CYRIX: return "Cyrix"; case PCI_VENDOR_ID_LEADTEK: return "Leadtek Research"; case PCI_VENDOR_ID_CONTAQ: return "Contaq"; case PCI_VENDOR_ID_FOREX: return "Forex"; @@ -637,6 +655,7 @@ case PCI_VENDOR_ID_RP: return "Comtrol"; case PCI_VENDOR_ID_CYCLADES: return "Cyclades"; case PCI_VENDOR_ID_3DFX: return "3Dfx"; + case PCI_VENDOR_ID_STALLION: return "Stallion Technologies"; case PCI_VENDOR_ID_SIGMADES: return "Sigma Designs"; case PCI_VENDOR_ID_OPTIBASE: return "Optibase"; case PCI_VENDOR_ID_ENSONIQ: return "Ensoniq"; diff -u --recursive --new-file v2.1.75/linux/drivers/scsi/ncr53c8xx.c linux/drivers/scsi/ncr53c8xx.c --- v2.1.75/linux/drivers/scsi/ncr53c8xx.c Wed Sep 24 20:05:47 1997 +++ linux/drivers/scsi/ncr53c8xx.c Sun Dec 21 22:39:38 1997 @@ -9359,8 +9359,7 @@ #if defined(__i386) && !defined(MODULE) if ((driver_setup.pci_fix_up & 1) && (chip->features & FE_CLSE) && cache_line_size == 0) { - extern char x86; - switch(x86) { + switch(boot_cpu_data.x86) { case 4: cache_line_size = 4; break; case 5: cache_line_size = 8; break; } diff -u --recursive --new-file v2.1.75/linux/drivers/scsi/st.c linux/drivers/scsi/st.c --- v2.1.75/linux/drivers/scsi/st.c Sun Dec 21 22:36:15 1997 +++ linux/drivers/scsi/st.c Mon Dec 22 13:47:24 1997 @@ -995,7 +995,6 @@ return -ENXIO; } - STp = &(scsi_tapes[dev]); if (STp->ready != ST_READY) { if (STp->ready == ST_NO_TAPE) return (-ENOMEDIUM); @@ -1510,7 +1509,6 @@ return -ENXIO; } - STp = &(scsi_tapes[dev]); if (STp->ready != ST_READY) { if (STp->ready == ST_NO_TAPE) return (-ENOMEDIUM); @@ -2298,10 +2296,9 @@ ioctl_result = (STp->buffer)->last_result_fatal; - scsi_release_command(SCpnt); - SCpnt = NULL; - if (!ioctl_result) { /* SCSI command successful */ + scsi_release_command(SCpnt); + SCpnt = NULL; STps->drv_block = blkno; STps->drv_file = fileno; STps->at_sm = at_sm; @@ -2349,7 +2346,8 @@ STp->partition = 0; } - } else { /* SCSI command was not completely successful */ + } else { /* SCSI command was not completely successful. Don't return + from this block without releasing the SCSI command block! */ if (SCpnt->sense_buffer[2] & 0x40) { if (cmd_in != MTBSF && cmd_in != MTBSFM && @@ -2430,6 +2428,9 @@ if (cmd_in == MTLOCK) STp->door_locked = ST_LOCK_FAILS; + + scsi_release_command(SCpnt); + SCpnt = NULL; } return ioctl_result; @@ -2591,7 +2592,6 @@ if (!SCpnt) return (-EBUSY); - SCpnt->request.rq_status = RQ_INACTIVE; /* Mark as not busy */ STps->drv_block = STps->drv_file = (-1); STps->eof = ST_NOEOF; if ((STp->buffer)->last_result_fatal != 0) { diff -u --recursive --new-file v2.1.75/linux/drivers/sound/.blurb linux/drivers/sound/.blurb --- v2.1.75/linux/drivers/sound/.blurb Fri Nov 15 00:14:57 1996 +++ linux/drivers/sound/.blurb Wed Dec 31 16:00:00 1969 @@ -1,10 +0,0 @@ -********************************************************* -* Readme.cards (this directory) contains some card * -* specific instructions. * -* See http://www.4front-tech.com/ossfree for most up * -* to date info. * -* (European mirror http://personal.eunet.fi/pp/voxware) * -* * -* DON'T USE PROGRAMS FROM snd-util PACKAGE EARLIER THAN * -* snd-util-3.5 WITH THIS SOUND DRIVER VERSION. * -********************************************************* diff -u --recursive --new-file v2.1.75/linux/drivers/sound/.objects linux/drivers/sound/.objects --- v2.1.75/linux/drivers/sound/.objects Sun Dec 21 22:36:15 1997 +++ linux/drivers/sound/.objects Wed Dec 31 16:00:00 1969 @@ -1,102 +0,0 @@ -OBJS= - -ifdef CONFIG_AD1848 - OBJS := $(OBJS) ad1848.o -endif - -ifdef CONFIG_YM3812 - OBJS := $(OBJS) adlib_card.o -endif - -ifdef CONFIG_AUDIO - OBJS := $(OBJS) audio.o -endif - -ifdef CONFIG_CS4232 - OBJS := $(OBJS) cs4232.o -endif - -ifdef CONFIG_AUDIO - OBJS := $(OBJS) dmabuf.o -endif - -ifdef CONFIG_GUSHW - OBJS := $(OBJS) gus_card.o gus_midi.o gus_vol.o gus_wave.o ics2101.o -endif - -ifdef CONFIG_MAD16 - OBJS := $(OBJS) mad16.o -endif - -ifdef CONFIG_MAUI - OBJS := $(OBJS) maui.o -endif - -ifdef CONFIG_MIDI - OBJS := $(OBJS) midi_synth.o midibuf.o -endif - -ifdef CONFIG_MPU401 - OBJS := $(OBJS) mpu401.o -else - ifdef CONFIG_MPU_EMU - OBJS := $(OBJS) mpu401.o - endif -endif - -ifdef CONFIG_YM3812 - OBJS := $(OBJS) opl3.o -endif - -ifdef CONFIG_PAS - OBJS := $(OBJS) pas2_card.o pas2_midi.o pas2_mixer.o pas2_pcm.o -endif - -ifdef CONFIG_PSS - OBJS := $(OBJS) pss.o -endif - -ifdef CONFIG_SBDSP - OBJS := $(OBJS) sb_card.o sb_common.o sb_audio.o sb_mixer.o sb_midi.o -endif - -ifdef CONFIG_SEQUENCER - OBJS := $(OBJS) sequencer.o -endif - - -ifdef CONFIG_SEQUENCER - OBJS := $(OBJS) sound_timer.o -endif - -ifdef CONFIG_SSCAPEHW - OBJS := $(OBJS) sscape.o -endif - -ifdef CONFIG_TRIX - OBJS := $(OBJS) trix.o -endif - -ifdef CONFIG_SEQUENCER - OBJS := $(OBJS) sys_timer.o -endif - -ifdef CONFIG_UART6850 - OBJS := $(OBJS) uart6850.o -endif - -ifdef CONFIG_UART401 - OBJS := $(OBJS) uart401.o -endif - -ifdef CONFIG_OPL3SA1 - OBJS := $(OBJS) opl3sa.o -endif - -ifdef CONFIG_SOFTOSS - OBJS := $(OBJS) softoss.o softoss_rs.o -endif - -ifdef CONFIG_VMIDI - OBJS := $(OBJS) v_midi.o -endif diff -u --recursive --new-file v2.1.75/linux/drivers/sound/Config.in linux/drivers/sound/Config.in --- v2.1.75/linux/drivers/sound/Config.in Sun Dec 21 22:36:15 1997 +++ linux/drivers/sound/Config.in Tue Dec 23 13:52:02 1997 @@ -1,28 +1,10 @@ dep_tristate 'ProAudioSpectrum 16 support' CONFIG_PAS $CONFIG_SOUND -dep_tristate '100% Sound Blaster compatibles (SB16/32/64, ESS, Jazz16) support' CONFIG_SB $CONFIG_SOUND -dep_tristate 'Generic OPL2/OPL3 FM synthesizer support' CONFIG_ADLIB $CONFIG_SOUND -dep_tristate 'Gravis Ultrasound support' CONFIG_GUS $CONFIG_SOUND -if [ "$CONFIG_GUS" != "n" ]; then - bool '16 bit sampling option of GUS (_NOT_ GUS MAX)' CONFIG_GUS16 - bool 'GUS MAX support' CONFIG_GUSMAX -fi -dep_tristate 'MPU-401 support (NOT for SB16)' CONFIG_MPU401 $CONFIG_SOUND -dep_tristate 'PSS (ECHO-ADI2111) support' CONFIG_PSS $CONFIG_SOUND -dep_tristate 'Microsoft Sound System support' CONFIG_MSS $CONFIG_SOUND -dep_tristate 'Ensoniq SoundScape support' CONFIG_SSCAPE $CONFIG_SOUND -dep_tristate 'MediaTrix AudioTrix Pro support' CONFIG_TRIX $CONFIG_SOUND -dep_tristate 'Support for OPTi MAD16 and/or Mozart based cards' CONFIG_MAD16 $CONFIG_SOUND -dep_tristate 'Support for Crystal CS4232 based (PnP) cards' CONFIG_CS4232 $CONFIG_SOUND -dep_tristate 'Support for Turtle Beach Wave Front (Maui, Tropez) synthesizers' CONFIG_MAUI $CONFIG_SOUND -dep_tristate 'Yamaha OPL3-SA1 audio controller' CONFIG_OPL3SA1 $CONFIG_SOUND -dep_tristate 'SoftOSS software wave table engine' CONFIG_SOFTOSS $CONFIG_SOUND -dep_tristate 'FM synthesizer (YM3812/OPL-3) support' CONFIG_YM3812 $CONFIG_SOUND -dep_tristate 'Loopback MIDI device support' CONFIG_VMIDI $CONFIG_VMIDI - -if [ "$CONFIG_AEDSP16" = "y" ]; then - hex 'I/O base for Audio Excel DSP 16 220 or 240' AEDSP16_BASE 220 +if [ "$CONFIG_PAS" = "y" ]; then + int 'PAS16 IRQ 3, 4, 5, 7, 9, 10, 11, 12, 14 or 15' PAS_IRQ 10 + int 'PAS16 DMA 0, 1, 3, 5, 6 or 7' PAS_DMA 3 fi +dep_tristate '100% Sound Blaster compatibles (SB16/32/64, ESS, Jazz16) support' CONFIG_SB $CONFIG_SOUND if [ "$CONFIG_SB" = "y" ]; then hex 'I/O base for SB Check from manual of the card' SBC_BASE 220 int 'Sound Blaster IRQ Check from manual of the card' SBC_IRQ 7 @@ -34,50 +16,46 @@ int 'SB MPU401 IRQ (Jazz16, SM Wave and ES1688) Check from manual of the card' SB_MPU_IRQ -1 fi -if [ "$CONFIG_PAS" = "y" ]; then - int 'PAS16 IRQ 3, 4, 5, 7, 9, 10, 11, 12, 14 or 15' PAS_IRQ 10 - int 'PAS16 DMA 0, 1, 3, 5, 6 or 7' PAS_DMA 3 -fi - -if [ "$CONFIG_GUS" = "y" ]; then - hex 'I/O base for GUS 210, 220, 230, 240, 250 or 260' GUS_BASE 220 - int 'GUS IRQ 3, 5, 7, 9, 11, 12 or 15' GUS_IRQ 15 - int 'GUS DMA 1, 3, 5, 6 or 7' GUS_DMA 6 - int 'Second DMA channel for GUS 1, 3, 5, 6 or 7' GUS_DMA2 -1 -fi +dep_tristate 'Generic OPL2/OPL3 FM synthesizer support' CONFIG_ADLIB $CONFIG_SOUND -if [ "$CONFIG_GUS16" = "y" ]; then - hex 'I/O base for the 16 bit daughtercard of GUS 530, 604, E80 or F40' GUS16_BASE 530 - int 'GUS 16 bit daughtercard IRQ 3, 4, 5, 7, or 9' GUS16_IRQ 7 - int 'GUS DMA 0, 1 or 3' GUS16_DMA 3 +dep_tristate 'Gravis Ultrasound support' CONFIG_GUS $CONFIG_SOUND +if [ "$CONFIG_GUS" != "n" ]; then + bool '16 bit sampling option of GUS (_NOT_ GUS MAX)' CONFIG_GUS16 + bool 'GUS MAX support' CONFIG_GUSMAX + if [ "$CONFIG_GUS" = "y" ]; then + hex 'I/O base for GUS 210, 220, 230, 240, 250 or 260' GUS_BASE 220 + int 'GUS IRQ 3, 5, 7, 9, 11, 12 or 15' GUS_IRQ 15 + int 'GUS DMA 1, 3, 5, 6 or 7' GUS_DMA 6 + int 'Second DMA channel for GUS 1, 3, 5, 6 or 7' GUS_DMA2 -1 + if [ "$CONFIG_GUS16" = "y" ]; then + hex 'I/O base for the 16 bit daughtercard of GUS 530, 604, E80 or F40' GUS16_BASE 530 + int 'GUS 16 bit daughtercard IRQ 3, 4, 5, 7, or 9' GUS16_IRQ 7 + int 'GUS DMA 0, 1 or 3' GUS16_DMA 3 + fi + fi fi +dep_tristate 'MPU-401 support (NOT for SB16)' CONFIG_MPU401 $CONFIG_SOUND if [ "$CONFIG_MPU401" = "y" ]; then hex 'I/O base for MPU401 Check from manual of the card' MPU_BASE 330 int 'MPU401 IRQ Check from manual of the card' MPU_IRQ 9 fi -if [ "$CONFIG_MAUI" = "y" ]; then - comment 'ERROR! You have to use old sound configuration method with Maui.' - hex 'I/O base for Maui 210, 230, 260, 290, 300, 320, 338 or 330' MAUI_BASE 330 - int 'Maui IRQ 5, 9, 12 or 15' MAUI_IRQ 9 -fi - -if [ "$CONFIG_UART6850" = "y" ]; then - hex 'I/O base for UART 6850 MIDI port (Unknown)' U6850_BASE 0 - int 'UART6850 IRQ (Unknown)' U6850_IRQ -1 -fi - +dep_tristate 'PSS (ECHO-ADI2111) support' CONFIG_PSS $CONFIG_SOUND if [ "$CONFIG_PSS" = "y" ]; then - comment 'ERROR! You have to use old sound configuration method with PSS cards.' hex 'PSS I/O base 220 or 240' PSS_BASE 220 hex 'PSS audio I/O base 530, 604, E80 or F40' PSS_MSS_BASE 530 int 'PSS audio IRQ 7, 9, 10 or 11' PSS_MSS_IRQ 11 int 'PSS audio DMA 0, 1 or 3' PSS_MSS_DMA 3 hex 'PSS MIDI I/O base ' PSS_MPU_BASE 330 int 'PSS MIDI IRQ 3, 4, 5, 7 or 9' PSS_MPU_IRQ 9 + bool ' Have DSPxxx.LD firmware file' PSS_HAVE_BOOT + if [ "$PSS_HAVE_BOOT" = "y" ]; then + string ' Full pathname of DSPxxx.LD firmware file' PSS_BOOT_FILE + fi fi +dep_tristate 'Microsoft Sound System support' CONFIG_MSS $CONFIG_SOUND if [ "$CONFIG_MSS" = "y" ]; then hex 'MSS/WSS I/O base 530, 604, E80 or F40' MSS_BASE 530 int 'MSS/WSS IRQ 7, 9, 10 or 11' MSS_IRQ 11 @@ -85,6 +63,7 @@ int 'MSS/WSS second DMA (if possible) 0, 1 or 3' MSS_DMA2 -1 fi +dep_tristate 'Ensoniq SoundScape support' CONFIG_SSCAPE $CONFIG_SOUND if [ "$CONFIG_SSCAPE" = "y" ]; then hex 'SoundScape MIDI I/O base 320, 330, 340 or 350' SSCAPE_BASE 330 int 'SoundScape MIDI IRQ ' SSCAPE_IRQ 9 @@ -93,8 +72,8 @@ int 'SoundScape audio IRQ 7, 9, 10 or 11' SSCAPE_MSS_IRQ 11 fi +dep_tristate 'MediaTrix AudioTrix Pro support' CONFIG_TRIX $CONFIG_SOUND if [ "$CONFIG_TRIX" = "y" ]; then - comment 'ERROR! You have to use old sound configuration method with OPL3-SA1.' hex 'OPL3-SA1 audio I/O base 530, 604, E80 or F40' TRIX_BASE 530 int 'OPL3-SA1 audio IRQ 7, 9, 10 or 11' TRIX_IRQ 11 int 'OPL3-SA1 audio DMA 0, 1 or 3' TRIX_DMA 0 @@ -104,17 +83,23 @@ hex 'OPL3-SA1 SB I/O base 220, 210, 230, 240, 250, 260 or 270' TRIX_SB_BASE 220 int 'OPL3-SA1 SB IRQ 3, 4, 5 or 7' TRIX_SB_IRQ 7 int 'OPL3-SA1 SB DMA 1 or 3' TRIX_SB_DMA 1 + bool ' Have TRXPRO.HEX firmware file' TRIX_HAVE_BOOT + if [ "$TRIX_HAVE_BOOT" = "y" ]; then + string ' Full pathname of TRXPRO.HEX firmware file' TRIX_BOOT_FILE + fi fi -if [ "$CONFIG_OPL3SA1" = "y" ]; then - hex 'OPL3-SA1 audio I/O base 530, 604, E80 or F40' OPL3SA1_BASE 530 - int 'OPL3-SA1 audio IRQ 7, 9, 10 or 11' OPL3SA1_IRQ 11 - int 'OPL3-SA1 audio DMA 0, 1 or 3' OPL3SA1_DMA 0 - int 'OPL3-SA1 second (duplex) DMA 0, 1 or 3' OPL3SA1_DMA2 3 - hex 'OPL3-SA1 MIDI I/O base 330, 370, 3B0 or 3F0' OPL3SA1_MPU_BASE 330 - int 'OPL3-SA1 MIDI IRQ 3, 4, 5, 7 or 9' OPL3SA1_MPU_IRQ 9 +dep_tristate 'Support for OPTi MAD16 and/or Mozart based cards' CONFIG_MAD16 $CONFIG_SOUND +if [ "$CONFIG_MAD16" = "y" ]; then + hex 'MAD16 audio I/O base 530, 604, E80 or F40' MAD16_BASE 530 + int 'MAD16 audio IRQ 7, 9, 10 or 11' MAD16_IRQ 11 + int 'MAD16 audio DMA 0, 1 or 3' MAD16_DMA 3 + int 'MAD16 second (duplex) DMA 0, 1 or 3' MAD16_DMA2 0 + hex 'MAD16 MIDI I/O base 300, 310, 320 or 330 (0 disables)' MAD16_MPU_BASE 330 + int 'MAD16 MIDI IRQ 5, 7, 9 or 10' MAD16_MPU_IRQ 9 fi +dep_tristate 'Support for Crystal CS4232 based (PnP) cards' CONFIG_CS4232 $CONFIG_SOUND if [ "$CONFIG_CS4232" = "y" ]; then hex 'CS4232 audio I/O base 530, 604, E80 or F40' CS4232_BASE 530 int 'CS4232 audio IRQ 5, 7, 9, 11, 12 or 15' CS4232_IRQ 11 @@ -124,28 +109,50 @@ int 'CS4232 MIDI IRQ 5, 7, 9, 11, 12 or 15' CS4232_MPU_IRQ 9 fi -if [ "$CONFIG_MAD16" = "y" ]; then - hex 'MAD16 audio I/O base 530, 604, E80 or F40' MAD16_BASE 530 - int 'MAD16 audio IRQ 7, 9, 10 or 11' MAD16_IRQ 11 - int 'MAD16 audio DMA 0, 1 or 3' MAD16_DMA 3 - int 'MAD16 second (duplex) DMA 0, 1 or 3' MAD16_DMA2 0 - hex 'MAD16 MIDI I/O base 300, 310, 320 or 330 (0 disables)' MAD16_MPU_BASE 330 - int 'MAD16 MIDI IRQ 5, 7, 9 or 10' MAD16_MPU_IRQ 9 +dep_tristate 'Support for Turtle Beach Wave Front (Maui, Tropez) synthesizers' CONFIG_MAUI $CONFIG_SOUND +if [ "$CONFIG_MAUI" = "y" ]; then + hex 'I/O base for Maui 210, 230, 260, 290, 300, 320, 338 or 330' MAUI_BASE 330 + int 'Maui IRQ 5, 9, 12 or 15' MAUI_IRQ 9 + bool ' Have OSWF.MOT firmware file' MAUI_HAVE_BOOT + if [ "$MAUI_HAVE_BOOT" = "y" ]; then + string ' Full pathname of OSWF.MOT firmware file' MAUI_BOOT_FILE + fi fi +dep_tristate 'Yamaha OPL3-SA1 audio controller' CONFIG_OPL3SA1 $CONFIG_SOUND +if [ "$CONFIG_OPL3SA1" = "y" ]; then + hex 'OPL3-SA1 audio I/O base 530, 604, E80 or F40' OPL3SA1_BASE 530 + int 'OPL3-SA1 audio IRQ 7, 9, 10 or 11' OPL3SA1_IRQ 11 + int 'OPL3-SA1 audio DMA 0, 1 or 3' OPL3SA1_DMA 0 + int 'OPL3-SA1 second (duplex) DMA 0, 1 or 3' OPL3SA1_DMA2 3 + hex 'OPL3-SA1 MIDI I/O base 330, 370, 3B0 or 3F0' OPL3SA1_MPU_BASE 330 + int 'OPL3-SA1 MIDI IRQ 3, 4, 5, 7 or 9' OPL3SA1_MPU_IRQ 9 +fi + +dep_tristate 'SoftOSS software wave table engine' CONFIG_SOFTOSS $CONFIG_SOUND if [ "$CONFIG_SOFTOSS" = "y" ]; then int 'Sampling rate for SoftOSS 8000 to 48000' SOFTOSS_RATE 22050 int 'Max # of concurrent voices for SoftOSS 4 to 32' SOFTOSS_VOICES 32 fi -# -$MAKE -C drivers/sound kernelconfig || exit 1 +dep_tristate 'FM synthesizer (YM3812/OPL-3) support' CONFIG_YM3812 $CONFIG_SOUND +dep_tristate 'Loopback MIDI device support' CONFIG_VMIDI $CONFIG_VMIDI + +if [ "$CONFIG_UART6850" = "y" ]; then + hex 'I/O base for UART 6850 MIDI port (Unknown)' U6850_BASE 0 + int 'UART6850 IRQ (Unknown)' U6850_IRQ -1 +fi + + bool 'Additional low level drivers' CONFIG_LOWLEVEL_SOUND if [ "$CONFIG_LOWLEVEL_SOUND" = "y" ]; then dep_tristate 'ACI mixer (miroPCM12)' CONFIG_ACI_MIXER $CONFIG_SOUND dep_tristate 'AWE32 synth' CONFIG_AWE32_SYNTH $CONFIG_SOUND bool 'Gallant Audio Cards (SC-6000 and SC-6600 based)' CONFIG_AEDSP16 + if [ "$CONFIG_AEDSP16" = "y" -o "$CONFIG_AEDSP16" = "m" ]; then + hex ' I/O base for Audio Excel DSP 16 220 or 240' AEDSP16_BASE 220 + fi if [ "$CONFIG_AEDSP16" = "y" ]; then comment 'SC-6600 Audio Cards have no jumper switches at all' diff -u --recursive --new-file v2.1.75/linux/drivers/sound/Config.std linux/drivers/sound/Config.std --- v2.1.75/linux/drivers/sound/Config.std Wed May 28 10:51:32 1997 +++ linux/drivers/sound/Config.std Wed Dec 31 16:00:00 1969 @@ -1,69 +0,0 @@ -# -# Sound driver configuration -# -#-------- -# There is another confic script which is compatible with rest of -# the kernel. It can be activated by running 'make mkscript' in this -# directory. Please note that this is an _experimental_ feature which -# doesn't work with all cards (PSS, SM Wave, AudioTriX Pro, Maui). -#-------- -# -$MAKE -C drivers/sound config || exit 1 - -bool 'Additional low level drivers' CONFIG_LOWLEVEL_SOUND - -if [ "$CONFIG_LOWLEVEL_SOUND" = "y" ]; then - bool 'ACI mixer (miroPCM12)' CONFIG_ACI_MIXER - bool 'AWE32 synth' CONFIG_AWE32_SYNTH - bool 'Gallant Audio Cards (SC-6000 and SC-6600 based)' CONFIG_AEDSP16 - - if [ "$CONFIG_AEDSP16" = "y" ]; then - comment 'SC-6600 Audio Cards have no jumper switches at all' - bool 'SC-6600 based audio cards (new Audio Excel DSP 16)' CONFIG_SC6600 - - if [ "$CONFIG_SB" = "y" -a "$CONFIG_AEDSP16_MSS" != "y" ]; then - bool 'Audio Excel DSP 16 (SBPro emulation)' CONFIG_AEDSP16_SBPRO - if [ "$CONFIG_AEDSP16_SBPRO" = "y" ]; then - comment 'Audio Excel DSP 16 [Sound Blaster Pro]' - hex 'I/O base for Audio Excel DSP 16 220 or 240' \ - AEDSP16_BASE $SBC_BASE - int 'Audio Excel DSP 16 IRQ 5, 7, 9, 10, 11' \ - AEDSP16_SBC_IRQ $SBC_IRQ - int 'Audio Excel DSP 16 DMA 0, 1 or 3' AEDSP16_SBC_DMA $SBC_DMA - fi - fi - - if [ "$CONFIG_MSS" = "y" -a "$CONFIG_AEDSP16_SBPRO" != "y" ]; then - bool 'Audio Excel DSP 16 (MSS emulation)' CONFIG_AEDSP16_MSS - if [ "$CONFIG_AEDSP16_MSS" = "y" ]; then - comment 'Audio Excel DSP 16 [Microsoft Sound System]' - hex 'I/O base for Audio Excel DSP 16 220 or 240' AEDSP16_BASE 220 - int 'Audio Excel DSP 16 IRQ 5, 7, 9, 10, 11' \ - AEDSP16_MSS_IRQ $MSS_IRQ - int 'Audio Excel DSP 16 DMA 0, 1 or 3' AEDSP16_MSS_DMA $MSS_DMA - fi - fi - - if [ "$CONFIG_MPU401" = "y" ]; then - bool 'Audio Excel DSP 16 (MPU401 emulation)' CONFIG_AEDSP16_MPU401 - if [ "$CONFIG_AEDSP16_MPU401" = "y" ]; then - comment 'Audio Excel DSP 16 [MPU-401]' - if [ "$CONFIG_AEDSP16_SBPRO" != "y" \ - -a "$CONFIG_AEDSP16_MSS" != "y" ]; then - hex 'I/O base for Audio Excel DSP 16 220 or 240' AEDSP16_BASE 220 - fi - int 'MPU401 IRQ for Audio Excel DSP 16 5, 7, 9, 10 or 0 (disable)' \ - AEDSP16_MPU_IRQ $MPU_IRQ - fi - fi - - if [ "$CONFIG_SC6600" = "y" ]; then - comment 'SC-6600 specific configuration' - bool 'Activate SC-6600 Joystick Interface' CONFIG_SC6600_JOY - int 'SC-6600 CDROM Interface (4=None, 3=IDE, 1=Panasonic, 0=?Sony?)' \ - CONFIG_SC6600_CDROM 4 - hex 'SC-6600 CDROM Interface I/O Address' CONFIG_SC6600_CDROMBASE 0 - fi - - fi -fi diff -u --recursive --new-file v2.1.75/linux/drivers/sound/Defines linux/drivers/sound/Defines --- v2.1.75/linux/drivers/sound/Defines Wed Dec 31 16:00:00 1969 +++ linux/drivers/sound/Defines Tue Dec 23 13:52:02 1997 @@ -0,0 +1,399 @@ +# This used to be a computer generated file, but it's not any more. +# Edit all you need! + +ifdef CONFIG_PSS +ifneq ($(CONFIG_MPU_EMU),Y) +CONFIG_MPU_EMU=y +endif +endif + +ifdef CONFIG_SSCAPE +ifneq ($(CONFIG_MPU_EMU),Y) +CONFIG_MPU_EMU=y +endif +endif + +ifdef CONFIG_CS4232 +ifneq ($(CONFIG_MPU_EMU),Y) +CONFIG_MPU_EMU=y +endif +endif + +ifdef CONFIG_MAUI +ifneq ($(CONFIG_MPU_EMU),Y) +CONFIG_MPU_EMU=y +endif +endif + +ifdef CONFIG_PSS +ifneq ($(CONFIG_AD1848),Y) +CONFIG_AD1848=y +endif +endif + +ifdef CONFIG_GUS16 +ifneq ($(CONFIG_AD1848),Y) +CONFIG_AD1848=y +endif +endif + +ifdef CONFIG_GUSMAX +ifneq ($(CONFIG_AD1848),Y) +CONFIG_AD1848=y +endif +endif + +ifdef CONFIG_MSS +ifneq ($(CONFIG_AD1848),Y) +CONFIG_AD1848=y +endif +endif + +ifdef CONFIG_SSCAPE +ifneq ($(CONFIG_AD1848),Y) +CONFIG_AD1848=y +endif +endif + +ifdef CONFIG_TRIX +ifneq ($(CONFIG_AD1848),Y) +CONFIG_AD1848=y +endif +endif + +ifdef CONFIG_MAD16 +ifneq ($(CONFIG_AD1848),Y) +CONFIG_AD1848=y +endif +endif + +ifdef CONFIG_CS4232 +ifneq ($(CONFIG_AD1848),Y) +CONFIG_AD1848=y +endif +endif + +ifdef CONFIG_OPL3SA1 +ifneq ($(CONFIG_AD1848),Y) +CONFIG_AD1848=y +endif +endif + +ifdef CONFIG_SB +ifneq ($(CONFIG_SBDSP),Y) +CONFIG_SBDSP=y +endif +endif + +ifdef CONFIG_TRIX +ifneq ($(CONFIG_SBDSP),Y) +CONFIG_SBDSP=y +endif +endif + +ifdef CONFIG_MAD16 +ifneq ($(CONFIG_SBDSP),Y) +CONFIG_SBDSP=y +endif +endif + +ifdef CONFIG_SB +ifneq ($(CONFIG_UART401),Y) +CONFIG_UART401=y +endif +endif + +ifdef CONFIG_TRIX +ifneq ($(CONFIG_UART401),Y) +CONFIG_UART401=y +endif +endif + +ifdef CONFIG_MAD16 +ifneq ($(CONFIG_UART401),Y) +CONFIG_UART401=y +endif +endif + +ifdef CONFIG_OPL3SA1 +ifneq ($(CONFIG_UART401),Y) +CONFIG_UART401=y +endif +endif + +ifdef CONFIG_GUS +ifneq ($(CONFIG_GUSHW),Y) +CONFIG_GUSHW=y +endif +endif + +ifdef CONFIG_SSCAPE +ifneq ($(CONFIG_SSCAPEHW),Y) +CONFIG_SSCAPEHW=y +endif +endif + +ifdef CONFIG_PAS +ifneq ($(CONFIG_SEQUENCER),Y) +CONFIG_SEQUENCER=y +endif +endif + +ifdef CONFIG_SB +ifneq ($(CONFIG_SEQUENCER),Y) +CONFIG_SEQUENCER=y +endif +endif + +ifdef CONFIG_ADLIB +ifneq ($(CONFIG_SEQUENCER),Y) +CONFIG_SEQUENCER=y +endif +endif + +ifdef CONFIG_GUS +ifneq ($(CONFIG_SEQUENCER),Y) +CONFIG_SEQUENCER=y +endif +endif + +ifdef CONFIG_MPU401 +ifneq ($(CONFIG_SEQUENCER),Y) +CONFIG_SEQUENCER=y +endif +endif + +ifdef CONFIG_PSS +ifneq ($(CONFIG_SEQUENCER),Y) +CONFIG_SEQUENCER=y +endif +endif + +ifdef CONFIG_GUS16 +ifneq ($(CONFIG_SEQUENCER),Y) +CONFIG_SEQUENCER=y +endif +endif + +ifdef CONFIG_GUSMAX +ifneq ($(CONFIG_SEQUENCER),Y) +CONFIG_SEQUENCER=y +endif +endif + +ifdef CONFIG_MSS +ifneq ($(CONFIG_SEQUENCER),Y) +CONFIG_SEQUENCER=y +endif +endif + +ifdef CONFIG_SSCAPE +ifneq ($(CONFIG_SEQUENCER),Y) +CONFIG_SEQUENCER=y +endif +endif + +ifdef CONFIG_TRIX +ifneq ($(CONFIG_SEQUENCER),Y) +CONFIG_SEQUENCER=y +endif +endif + +ifdef CONFIG_MAD16 +ifneq ($(CONFIG_SEQUENCER),Y) +CONFIG_SEQUENCER=y +endif +endif + +ifdef CONFIG_CS4232 +ifneq ($(CONFIG_SEQUENCER),Y) +CONFIG_SEQUENCER=y +endif +endif + +ifdef CONFIG_MAUI +ifneq ($(CONFIG_SEQUENCER),Y) +CONFIG_SEQUENCER=y +endif +endif + +ifdef CONFIG_OPL3SA1 +ifneq ($(CONFIG_SEQUENCER),Y) +CONFIG_SEQUENCER=y +endif +endif + +ifdef CONFIG_SOFTOSS +ifneq ($(CONFIG_SEQUENCER),Y) +CONFIG_SEQUENCER=y +endif +endif + +ifdef CONFIG_YM3812_AUTO +ifneq ($(CONFIG_SEQUENCER),Y) +CONFIG_SEQUENCER=y +endif +endif + +ifdef CONFIG_PAS +ifneq ($(CONFIG_AUDIO),Y) +CONFIG_AUDIO=y +endif +endif + +ifdef CONFIG_SB +ifneq ($(CONFIG_AUDIO),Y) +CONFIG_AUDIO=y +endif +endif + +ifdef CONFIG_GUS +ifneq ($(CONFIG_AUDIO),Y) +CONFIG_AUDIO=y +endif +endif + +ifdef CONFIG_PSS +ifneq ($(CONFIG_AUDIO),Y) +CONFIG_AUDIO=y +endif +endif + +ifdef CONFIG_GUS16 +ifneq ($(CONFIG_AUDIO),Y) +CONFIG_AUDIO=y +endif +endif + +ifdef CONFIG_GUSMAX +ifneq ($(CONFIG_AUDIO),Y) +CONFIG_AUDIO=y +endif +endif + +ifdef CONFIG_MSS +ifneq ($(CONFIG_AUDIO),Y) +CONFIG_AUDIO=y +endif +endif + +ifdef CONFIG_SSCAPE +ifneq ($(CONFIG_AUDIO),Y) +CONFIG_AUDIO=y +endif +endif + +ifdef CONFIG_TRIX +ifneq ($(CONFIG_AUDIO),Y) +CONFIG_AUDIO=y +endif +endif + +ifdef CONFIG_MAD16 +ifneq ($(CONFIG_AUDIO),Y) +CONFIG_AUDIO=y +endif +endif + +ifdef CONFIG_CS4232 +ifneq ($(CONFIG_AUDIO),Y) +CONFIG_AUDIO=y +endif +endif + +ifdef CONFIG_OPL3SA1 +ifneq ($(CONFIG_AUDIO),Y) +CONFIG_AUDIO=y +endif +endif + +ifdef CONFIG_SOFTOSS +ifneq ($(CONFIG_AUDIO),Y) +CONFIG_AUDIO=y +endif +endif + +ifdef CONFIG_PAS +ifneq ($(CONFIG_MIDI),Y) +CONFIG_MIDI=y +endif +endif + +ifdef CONFIG_SB +ifneq ($(CONFIG_MIDI),Y) +CONFIG_MIDI=y +endif +endif + +ifdef CONFIG_GUS +ifneq ($(CONFIG_MIDI),Y) +CONFIG_MIDI=y +endif +endif + +ifdef CONFIG_MPU401 +ifneq ($(CONFIG_MIDI),Y) +CONFIG_MIDI=y +endif +endif + +ifdef CONFIG_PSS +ifneq ($(CONFIG_MIDI),Y) +CONFIG_MIDI=y +endif +endif + +ifdef CONFIG_GUS16 +ifneq ($(CONFIG_MIDI),Y) +CONFIG_MIDI=y +endif +endif + +ifdef CONFIG_GUSMAX +ifneq ($(CONFIG_MIDI),Y) +CONFIG_MIDI=y +endif +endif + +ifdef CONFIG_SSCAPE +ifneq ($(CONFIG_MIDI),Y) +CONFIG_MIDI=y +endif +endif + +ifdef CONFIG_TRIX +ifneq ($(CONFIG_MIDI),Y) +CONFIG_MIDI=y +endif +endif + +ifdef CONFIG_MAD16 +ifneq ($(CONFIG_MIDI),Y) +CONFIG_MIDI=y +endif +endif + +ifdef CONFIG_CS4232 +ifneq ($(CONFIG_MIDI),Y) +CONFIG_MIDI=y +endif +endif + +ifdef CONFIG_MAUI +ifneq ($(CONFIG_MIDI),Y) +CONFIG_MIDI=y +endif +endif + +ifdef CONFIG_OPL3SA1 +ifneq ($(CONFIG_MIDI),Y) +CONFIG_MIDI=y +endif +endif + +ifdef CONFIG_SOFTOSS +ifneq ($(CONFIG_MIDI),Y) +CONFIG_MIDI=y +endif +endif + diff -u --recursive --new-file v2.1.75/linux/drivers/sound/Makefile linux/drivers/sound/Makefile --- v2.1.75/linux/drivers/sound/Makefile Sun Dec 21 22:36:15 1997 +++ linux/drivers/sound/Makefile Tue Dec 23 13:52:02 1997 @@ -24,21 +24,9 @@ clean: rm -f core *.o *.a *.s - # dummy rule to keep 'make xconfig' happy - mkscript: - -# More dummy targets for make [menu]config -mkscript: -kernelconfig: - else -ifeq (.defines,$(wildcard .defines)) -include .defines -#include .objects -endif - -TARGET_OS=linux +include Defines ifndef TOPDIR TOPDIR=/usr/src/linux @@ -92,7 +80,7 @@ ifeq ($(CONFIG_GUS),m) M_OBJS += gus.o endif - ifeq ($(CONFIG_GUSMAX),m) + ifeq ($(CONFIG_GUSMAX),y) ifneq ($(CONFIG_MSS),y) CONFIG_MSS = m endif @@ -259,33 +247,80 @@ gus.o: gus_card.o gus_midi.o gus_vol.o gus_wave.o ics2101.o ld -r -o gus.o gus_card.o gus_midi.o gus_vol.o gus_wave.o ics2101.o -kernelconfig: setup - rm -f configure - $(HOSTCC) -o configure configure.c - ./configure fixedlocal > local.h - ./configure fixeddefines > .defines - @echo \#define SOUND_CONFIG_DATE \"`date`\" >> local.h - @echo \#define SOUND_CONFIG_BY \"`whoami`\" >> local.h -# @echo \#define SOUND_CONFIG_HOST \"`hostname`\" >> local.h 2>/dev/null -# @echo \#define SOUND_CONFIG_DOMAIN \"`hostname -d`\" >> local.h 2>/dev/null - @echo \#define SOUND_UNAME_A \"`uname -a`\" >> local.h - -configure: configure.c - $(HOSTCC) -o configure configure.c - @cat .blurb - -setup: - @echo Compiling Sound Driver v $(VERSION) for Linux - -mkscript: - -config: configure - @$(MAKE) setup - @./configure > local.h - @echo \#define SOUND_CONFIG_DATE \"`date`\" >> local.h - @echo \#define SOUND_CONFIG_BY \"`whoami`\" >> local.h -# @echo \#define SOUND_CONFIG_HOST \"`hostname`\" >> local.h 2>/dev/null -# @echo \#define SOUND_CONFIG_DOMAIN \"`hostname -d`\" >> local.h 2>/dev/null - @echo \#define SOUND_UNAME_A \"`uname -a`\" >> local.h +# Firmware files that need translation +# +# The translated files are protected by a file that keeps track +# of what name was used to build them. If the name changes, they +# will be forced to be remade. + +bin2hex: bin2hex.c + $(HOSTCC) -o bin2hex bin2hex.c + +hex2hex: hex2hex.c + $(HOSTCC) -o hex2hex hex2hex.c + +ifeq ($(MAUI_HAVE_BOOT),y) + +MAUI_BOOT_FILE := $(patsubst "%", %, $(MAUI_BOOT_FILE)) + +maui.o: maui_boot.h + +maui_boot.h: $(MAUI_BOOT_FILE) bin2hex + bin2hex maui_os < "$(MAUI_BOOT_FILE)" > $@ + @ ( \ + echo 'ifeq ($(strip $(MAUI_BOOT_FILE)),$$(strip $$(MAUI_BOOT_FILE)))'; \ + echo 'FILES_BOOT_UP_TO_DATE += $@'; \ + echo 'endif' \ + ) > .$@.boot + +endif + +ifeq ($(PSS_HAVE_BOOT),y) + +PSS_BOOT_FILE := $(patsubst "%", %, $(PSS_BOOT_FILE)) + +pss.o: pss_boot.h +pss_boot.h: $(PSS_BOOT_FILE) bin2hex + bin2hex pss_synth < "$(PSS_BOOT_FILE)" > $@ + @ ( \ + echo 'ifeq ($(strip $(PSS_BOOT_FILE)),$$(strip $$(PSS_BOOT_FILE)))'; \ + echo 'FILES_BOOT_UP_TO_DATE += $@'; \ + echo 'endif' \ + ) > .$@.boot + +endif + +ifeq ($(TRIX_HAVE_BOOT),y) + +TRIX_BOOT_FILE := $(patsubst "%", %, $(TRIX_BOOT_FILE)) + +trix.o: trix_boot.h + +trix_boot.h: $(TRIX_BOOT_FILE) hex2hex + hex2hex trix_boot < "$(TRIX_BOOT_FILE)" > $@ + @ ( \ + echo 'ifeq ($(strip $(TRIX_BOOT_FILE)),$$(strip $$(strip $$(TRIX_BOOT_FILE)))'; \ + echo 'FILES_BOOT_UP_TO_DATE += $@'; \ + echo 'endif' \ + ) > .$@.boot + +endif + +# Find boot files whose source file names have changed and force rebuild. + +FILES_BOOT_UP_TO_DATE := + +FILES_BOOT_EXIST := $(wildcard .*.boot) +ifneq ($(FILES_BOOT_EXIST),) +include $(FILES_BOOT_EXIST) +endif + +FILES_BOOT_CHANGED := $(strip \ + $(filter-out $(FILES_BOOT_UP_TO_DATE), \ + maui_boot.h pss_boot.h trix_boot.h)) + +ifneq ($(FILES_BOOT_CHANGED),) +$(FILES_BOOT_CHANGED): dummy +endif endif diff -u --recursive --new-file v2.1.75/linux/drivers/sound/README.blurb linux/drivers/sound/README.blurb --- v2.1.75/linux/drivers/sound/README.blurb Wed Dec 31 16:00:00 1969 +++ linux/drivers/sound/README.blurb Tue Dec 23 13:52:02 1997 @@ -0,0 +1,10 @@ +********************************************************* +* Readme.cards (this directory) contains some card * +* specific instructions. * +* See http://www.4front-tech.com/ossfree for most up * +* to date info. * +* (European mirror http://personal.eunet.fi/pp/voxware) * +* * +* DON'T USE PROGRAMS FROM snd-util PACKAGE EARLIER THAN * +* snd-util-3.5 WITH THIS SOUND DRIVER VERSION. * +********************************************************* diff -u --recursive --new-file v2.1.75/linux/drivers/sound/Readme.cards linux/drivers/sound/Readme.cards --- v2.1.75/linux/drivers/sound/Readme.cards Wed Dec 10 11:12:44 1997 +++ linux/drivers/sound/Readme.cards Tue Dec 23 13:52:02 1997 @@ -18,32 +18,8 @@ http://www.opensound.com/ossfree for info about cards introduced recently. - The following covers mainly the "old" configuration - method (make config). Most of it is valid for the "new" - configuration (make menuconfig/xconfig) too. - - Cards having some kind of loadable "microcode" such as - PSS, SM Wave, AudioTrix Pro and Maui/Tropez must be - configured using the old method. The new one will not - work with them. The "old" method is used by default by - "make config". "make xconfig" will always use the "new" - method. "make menuconfig" will allow you to select which - method to use. After you have used the "new" method once - it will always be used when you use any of the config - programs. To return back to the "old" method you should - execute "cp Config.std Config.in" in linux/drivers/sound. - - The /etc/soundconf file (forget it if you don't know what - this file does) contains settings that are used only by - the "old" method. Don't ever think the "active" settings - are stored there (they really are _NOT_ stored - there). Don't try to edit /etc/soundconf or any other - kernel or sound driver config files manually. The _only_ - proper ways to change the settings are make config or - make menuconfig (the "old" method). - - When using make xconfig and/or make menuconfig, you should - carefully check each sound configuration option (particularly + When configuring the sound driver, you should carefully + check each sound configuration option (particularly "Support for /dev/dsp and /dev/audio"). The default values offered by these programs are not necessarily valid. @@ -377,9 +353,6 @@ chips. The OPL4 mode is supported by a microcontroller running a General MIDI emulator. There is also a SB 1.5 compatible playback mode. - NOTE! You will have to use the "old" config script when configuring - AudioTrix Pro. - Ensoniq SoundScape and compatibles Ensoniq has designed a soundcard architecture based on the OTTO synthesizer chip used in their professional MIDI synthesizers. @@ -411,8 +384,8 @@ Audio Excel DSP16 Support for this card was written by Riccardo Faccetti (riccardo@cdc8g5.cdc.polimi.it). The AEDSP16 driver included in - the lowlevel/ directory. To use it you should use the "new" config - script and to enable the "Additional low level drivers" option. + the lowlevel/ directory. To use it you should enable the + "Additional low level drivers" option. Crystal CS4232 and CS4236 based cards such as AcerMagic S23, TB Tropez _Plus_ and many PC motherboards (Compaq, HP, Intel, ...) @@ -431,8 +404,6 @@ described in the Maui/Tropez User's manual. There is now full initialization support too. The audio side of the Tropez is based on the MAD16 chip (see above). - NOTE! You will have to use the "old" config script when configuring - Maui or Tropez. NOTE! Tropez Plus is different card than Tropez "classic" and will not work fully in Linux. You can get audio features working by configuring the card as a CS4232 based card (above). @@ -529,29 +500,20 @@ The sound driver configuration dialog ------------------------------------- -All config information of the sound driver is written to file -linux/drivers/sound/local.h. You may save the old version is this file and -use it again in case you want to use the same config later. In this case -just answer n to each question made by the sound config program and put -the original local.h back before running "make dep". -Don't do this if the version number of the sound driver has changed. In this -case you have to enter the configuration information again. - If you already have the sound driver installed, consult printout of "cat /dev/sndstat" when configuring the driver again. It gives the I/O, IRQ and DMA settings you have used earlier. - -The sound config program (linux/drivers/sound/configure) starts by making -some yes/no questions. Be careful when answering to these questions since -answering y to a question may prevent some later ones from being asked. For -example don't answer y to the first question (PAS16) if you don't really -have a PAS16. Don't enable more cards than you really need since they -just consume memory. Also some drivers (like MPU401) may conflict with your -SCSI controller and prevent kernel from booting. If you card was in the list -of supported cards (above), please look at the card specific config -instructions (later in this file) before starting to configure. Some cards -must be configured in way which is not obvious. +Sound configuration starts by making some yes/no questions. Be careful +when answering to these questions since answering y to a question may +prevent some later ones from being asked. For example don't answer y to +the first question (PAS16) if you don't really have a PAS16. Don't enable +more cards than you really need since they just consume memory. Also +some drivers (like MPU401) may conflict with your SCSI controller and +prevent kernel from booting. If you card was in the list of supported +cards (above), please look at the card specific config instructions +(later in this file) before starting to configure. Some cards must be +configured in way which is not obvious. So here is the beginning of the config dialog. Answer 'y' or 'n' to these questions. The default answer is shown so that (y/n) means 'y' by default and @@ -688,9 +650,7 @@ I/O address, IRQ and DMA numbers are asked. With some cards the program asks for some files to be used during initialization of the card. For example many cards have a DSP chip or microprocessor which must be initialized by -downloading a program (microcode) file to the card. In some cases this file -is written to a .h file by the config program and then included to the driver -during compile. +downloading a program (microcode) file to the card. Instructions for answering these questions are given in the next section. @@ -1040,9 +1000,6 @@ Logitech Soundman Wave ---------------------- - -NOTE! You will have to use the "old" config script when configuring - SM Wave. Read the above MV Jazz specific instructions first. diff -u --recursive --new-file v2.1.75/linux/drivers/sound/bin2hex.c linux/drivers/sound/bin2hex.c --- v2.1.75/linux/drivers/sound/bin2hex.c Wed Dec 31 16:00:00 1969 +++ linux/drivers/sound/bin2hex.c Tue Dec 23 13:52:02 1997 @@ -0,0 +1,22 @@ +#include + +int main( int argc, const char * argv [] ) +{ + const char * varname = argv[1]; + int i = 0; + int c; + + printf( "/* automatically generated by bin2hex */\n" ); + printf( "static unsigned char %s [] =\n{\n", varname ); + + while ( ( c = getchar( ) ) != EOF ) + { + if ( i != 0 && i % 10 == 0 ) + printf( "\n" ); + printf( "0x%02lx,", c & 0xFFl ); + i++; + } + + printf( "};\n#define %sLen %d\n", varname, i ); + return 0; +} diff -u --recursive --new-file v2.1.75/linux/drivers/sound/configure.c linux/drivers/sound/configure.c --- v2.1.75/linux/drivers/sound/configure.c Sun Dec 21 22:36:15 1997 +++ linux/drivers/sound/configure.c Wed Dec 31 16:00:00 1969 @@ -1,1674 +0,0 @@ -/* - * PnP soundcard support is not included in this version. - * - * AESDP16 driver is now included in the lowlevel directory. - */ -#define DISABLED_OPTIONS (B(OPT_SPNP)|B(OPT_AEDSP16)|B(OPT_UNUSED1)|B(OPT_UNUSED2)|B(OPT_UNUSED3)|B(OPT_UNUSED4)|B(OPT_UNUSED5)|B(OPT_UART6850)) -/* - * sound/configure.c - Configuration program for the Linux Sound Driver - */ -/* - * Copyright (C) by Hannu Savolainen 1993-1997 - * - * OSS/Free for Linux is distributed under the GNU GENERAL PUBLIC LICENSE (GPL) - * Version 2 (June 1991). See the "COPYING" file distributed with this software - * for more info. - */ - - -#include -#include -#include -#include -#include - -#define B(x) (1 << (x)) - -/* - * Option numbers - */ - -#define OPT_PAS 0 -#define OPT_SB 1 -#define OPT_ADLIB 2 -#define OPT_LAST_MUTUAL 2 - -#define OPT_GUS 3 -#define OPT_MPU401 4 -#define OPT_UART6850 5 -#define OPT_PSS 6 -#define OPT_GUS16 7 -#define OPT_GUSMAX 8 -#define OPT_MSS 9 -#define OPT_SSCAPE 10 -#define OPT_TRIX 11 -#define OPT_MAD16 12 -#define OPT_CS4232 13 -#define OPT_MAUI 14 -#define OPT_SPNP 15 -#define OPT_OPL3SA1 16 -#define OPT_SOFTOSS 17 - -#define OPT_HIGHLEVEL 18 /* This must be same than the next one */ -#define OPT_UNUSED1 18 -#define OPT_UNUSED2 19 -#define OPT_AEDSP16 20 -#define OPT_UNUSED3 21 -#define OPT_UNUSED4 22 -#define OPT_UNUSED5 23 -#define OPT_YM3812_AUTO 24 -#define OPT_YM3812 25 -#define OPT_VMIDI 26 -#define OPT_LAST 27 /* Last defined OPT number */ - -#define DUMMY_OPTS (B(OPT_YM3812_AUTO)) - -#define ANY_DEVS (B(OPT_SB)|B(OPT_PAS)|B(OPT_GUS)| \ - B(OPT_MPU401)|B(OPT_PSS)|B(OPT_GUS16)|B(OPT_GUSMAX)| \ - B(OPT_MSS)|B(OPT_SSCAPE)|B(OPT_UART6850)|B(OPT_TRIX)| \ - B(OPT_MAD16)|B(OPT_CS4232)|B(OPT_MAUI)|B(OPT_ADLIB)| \ - B(OPT_SPNP)|B(OPT_OPL3SA1)|B(OPT_SOFTOSS)|B(OPT_VMIDI)) -#define MPU_DEVS (B(OPT_PSS)|\ - B(OPT_CS4232)|B(OPT_SPNP)|B(OPT_MAUI)|B(OPT_SSCAPE)) -#define UART401_DEVS (SBDSP_DEVS|B(OPT_TRIX)|B(OPT_MAD16)|B(OPT_SPNP)|\ - B(OPT_OPL3SA1)) -#define NON_AUDIO_CARDS (B(OPT_ADLIB)|B(OPT_MPU401)|B(OPT_UART6850)|B(OPT_MAUI)|B(OPT_VMIDI)) -#define AUDIO_CARDS (ANY_DEVS & ~NON_AUDIO_CARDS) -#define MIDI_CARDS (ANY_DEVS & ~(B(OPT_ADLIB)|B(OPT_MSS))) -#define AD1848_DEVS (B(OPT_GUS16)|B(OPT_MSS)|B(OPT_PSS)|B(OPT_GUSMAX)|\ - B(OPT_SSCAPE)|B(OPT_TRIX)|B(OPT_MAD16)|B(OPT_CS4232)|\ - B(OPT_SPNP)|B(OPT_OPL3SA1)) -#define SBDSP_DEVS (B(OPT_SB)|B(OPT_SPNP)|B(OPT_MAD16)|B(OPT_TRIX)) -#define SEQUENCER_DEVS 0x7fffffff -/* - * Options that have been disabled for some reason (incompletely implemented - * and/or tested). Don't remove from this list before looking at file - * experimental.txt for further info. - */ - -typedef struct - { - unsigned long conditions; - unsigned long exclusive_options; - char macro[20]; - int verify; - int alias; - int default_answ; - } - -hw_entry; - - -/* - * The rule table for the driver options. The first field defines a set of - * options which must be selected before this entry can be selected. The - * second field is a set of options which are not allowed with this one. If - * the fourth field is zero, the option is selected without asking - * confirmation from the user. - * - * With this version of the rule table it is possible to select just one type of - * hardware. - * - * NOTE! Keep the following table and the questions array in sync with the - * option numbering! - */ - -hw_entry hw_table[] = -{ -/* - * 0 - */ - {0, 0, "PAS", 1, 0, 0}, - {0, 0, "SB", 1, 0, 0}, - {0, B(OPT_PAS) | B(OPT_SB), "ADLIB", 1, 0, 0}, - - {0, 0, "GUS", 1, 0, 0}, - {0, 0, "MPU401", 1, 0, 0}, - {0, 0, "UART6850", 1, 0, 0}, - {0, 0, "PSS", 1, 0, 0}, - {B(OPT_GUS), 0, "GUS16", 1, 0, 0}, - {B(OPT_GUS), B(OPT_GUS16), "GUSMAX", 1, 0, 0}, - {0, 0, "MSS", 1, 0, 0}, - {0, 0, "SSCAPE", 1, 0, 0}, - {0, 0, "TRIX", 1, 0, 0}, - {0, 0, "MAD16", 1, 0, 0}, - {0, 0, "CS4232", 1, 0, 0}, - {0, 0, "MAUI", 1, 0, 0}, - {0, 0, "SPNP", 1, 0, 0}, - {0, 0, "OPL3SA1", 1, 0, 0}, - {0, 0, "SOFTOSS", 1, 0, 0}, - - {B(OPT_SB), B(OPT_PAS), "UNUSED1", 1, 0, 1}, - {B(OPT_SB) | B(OPT_UNUSED1), B(OPT_PAS), "UNUSED2", 1, 0, 1}, - {B(OPT_UNUSED1) | B(OPT_MSS) | B(OPT_MPU401), 0, "AEDSP16", 1, 0, 0}, - {AUDIO_CARDS, 0, "UNUSED3", 1, 0, 1}, - {B(OPT_MPU401) | B(OPT_MAUI), 0, "UNUSED4", 0, 0, 0}, - {MIDI_CARDS, 0, "UNUSED5", 1, 0, 1}, - {B(OPT_ADLIB), 0, "YM3812_AUTO", 0, OPT_YM3812, 0}, - {B(OPT_PSS) | B(OPT_SB) | B(OPT_PAS) | B(OPT_ADLIB) | B(OPT_MSS) | B(OPT_PSS), B(OPT_YM3812_AUTO), "YM3812", 1, 0, 1}, - {0, 0, "VMIDI", 1, 0, 0} -}; - -char *questions[] = -{ - "ProAudioSpectrum 16 support", - "100%% Sound Blaster compatibles (SB16/32/64, ESS, Jazz16) support", - "Generic OPL2/OPL3 FM synthesizer support", - "Gravis Ultrasound support", - "MPU-401 support (NOT for SB16)", - "6850 UART Midi support", - "PSS (ECHO-ADI2111) support", - "16 bit sampling option of GUS (_NOT_ GUS MAX)", - "GUS MAX support", - "Microsoft Sound System support", - "Ensoniq SoundScape support", - "MediaTrix AudioTrix Pro support", - "Support for OPTi MAD16 and/or Mozart based cards", - "Support for Crystal CS4232 based (PnP) cards", - "Support for Turtle Beach Wave Front (Maui, Tropez) synthesizers", - "Support for PnP sound cards (_EXPERIMENTAL_)", - "Yamaha OPL3-SA1 audio controller", - "SoftOSS software wave table engine", - - "*** Unused option 1 ***", - "*** Unused option 2 ***", - "Audio Excel DSP 16 initialization support", - "*** Unused option 3 ***", - "*** Unused option 4 ***", - "*** Unused option 5 ***", - "This should not be asked", - "FM synthesizer (YM3812/OPL-3) support", - "Loopback MIDI device support", - "Is the sky really falling" -}; - -/* help text for each option */ -char *help[] = -{ - "Enable this option only if you have a Pro Audio Spectrum 16,\n" - "Pro Audio Studio 16, or Logitech SoundMan 16. Don't enable this if\n" - "you have some other card made by MediaVision or Logitech as\n" - "they are not PAS16 compatible.\n", - - "Enable this if you have an original Sound Blaster card made by\n" - "Creative Labs or a 100%% hardware compatible clone. For an\n" - "unknown card you may want to try this if it claims to be\n" - "Sound Blaster compatible.\n", - - "Enable this option if your sound card has a Yamaha OPL2 or OPL3\n" - "FM synthesizer chip.\n", - - "Enable this option for any type of Gravis Ultrasound card\n" - "including the GUS or GUS MAX.\n", - -"The MPU401 interface is supported by almost all sound cards. However,\n" - "some natively supported cards have their own driver for\n" - "MPU401. Enabling the MPU401 option with these cards will cause a\n" -"conflict. Also enabling MPU401 on a system that doesn't really have a\n" - "MPU401 could cause some trouble. It's safe to enable this if you have a\n" - "true MPU401 MIDI interface card.\n", - - "This option enables support for MIDI interfaces based on the 6850\n" - "UART chip. This interface is rarely found on sound cards.\n", - -"Enable this option if you have an Orchid SW32, Cardinal DSP16 or other\n" -"sound card based on the PSS chipset (AD1848 codec, ADSP-2115 DSP chip,\n" - "and Echo ESC614 ASIC CHIP).\n", - -"Enable this if you have installed the 16-bit sampling daughtercard on\n" - "your GUS card. Do not use if you have a GUS MAX as enabling this option\n" - "disables GUS MAX support.\n", - - "Enable this option if you have a Gravis Ultrasound MAX sound\n" - "card\n", - - "Enable this option if you have the original Windows Sound System\n" - "card made by Microsoft or the Aztech SG 16 Pro or NX16 Pro.\n", - - "Enable this if you have a sound card based on the Ensoniq\n" - "SoundScape chipset. Such cards are being manufactured by Ensoniq,\n" - "Spea and Reveal (Reveal makes other cards as well).\n", - - "Enable this option if you have the AudioTrix Pro sound card\n" - "manufactured by MediaTrix.\n", - - "Enable this if your card has a Mozart (OAK OTI-601) or MAD16 (OPTi\n" - "82C928 or 82C929) audio interface chip. These chips are currently\n" - "quite common so it's possible that many no-name cards have one of\n" - "them. In addition the MAD16 chip is used in some cards made by known\n" -"manufacturers such as Turtle Beach (Tropez), Reveal (some models) and\n" - "Diamond (latest ones).\n", - -"Enable this if you have a card based on the Crystal CS4232 chip set.\n", - - "Enable this option if you have a Turtle Beach Wave Front, Maui,\n" - "or Tropez sound card.\n", - - "Use this option to enable experimental support for cards that\n" - "use the Plug and Play protocol.\n", - - "Use this option with Yamaha OPL3-SA1 (YMF701) chip.\n", - -"SoftOSS is a virtual wave table engine by 4Front Technologies. It can\n" - "be used together with any 16 bit stereo soundcard.\n" - - "Enable this option if your card is a Sound Blaster Pro or\n" - "Sound Blaster 16. It also works with many Sound Blaster Pro clones.\n", - - "Enable this if you have a Sound Blaster 16, including the AWE32.\n", - - "Enable this if you have an Audio Excel DSP16 card. See the file\n" - "Readme.aedsp16 for more information.\n", - - "This option enables the A/D and D/A converter (PCM) devices\n" - "supported by almost all sound cards.\n", - - "This should not be asked", - - "This enables the dev/midixx devices and access to any MIDI ports\n" - "using /dev/sequencer and /dev/music. This option also affects any\n" - "MPU401 and/or General MIDI compatible devices.\n", - - "This should not be asked", - - "This enables the Yamaha FM synthesizer chip used on many sound\n" - "cards.\n", - - "This enable Loopback virtual MIDI device\n", - - "Is the sky really falling" -}; - -struct kludge - { - char *name; - int mask; - } -extra_options[] = -{ - { - "MPU_EMU", MPU_DEVS - } - , - { - "AD1848", AD1848_DEVS - } - , - { - "SBDSP", SBDSP_DEVS - } - , - { - "UART401", UART401_DEVS - } - , - { - "GUSHW", B(OPT_GUS) | B(OPT_SPNP) - } - , - { - "SSCAPEHW", B(OPT_SSCAPE) | B(OPT_SPNP) - } - , - { - "SEQUENCER", SEQUENCER_DEVS - } - , - { - "AUDIO", AUDIO_CARDS - } - , - { - "MIDI", MIDI_CARDS - } - , - { - NULL, 0 - } -}; - -char *oldconf = "/etc/soundconf"; - -int old_config_used = 0; -int def_size, sb_base = 0; - -unsigned long selected_options = 0; -int sb_dma = 0; - -int dump_only = 0; - -void build_defines(void); - -#include "hex2hex.h" -int bin2hex(char *path, char *target, char *varname); - -int -can_select_option(int nr) -{ - - if (hw_table[nr].conditions) - if (!(hw_table[nr].conditions & selected_options)) - return 0; - - if (hw_table[nr].exclusive_options) - if (hw_table[nr].exclusive_options & selected_options) - return 0; - - if (DISABLED_OPTIONS & B(nr)) - return 0; - - return 1; -} - -int -think_positively(char *prompt, int def_answ, char *help) -{ - char answ[512]; - int len; - - response: - fprintf(stderr, prompt); - if (def_answ) - fprintf(stderr, " [Y/n/?] "); - else - fprintf(stderr, " [N/y/?] "); - - if ((len = read(0, answ, sizeof(answ))) < 1) - { - fprintf(stderr, "\n\nERROR! Cannot read stdin\n"); - - perror("stdin"); - printf("invalid_configuration__run_make_config_again\n"); - exit(-1); - } - if (len < 2) /* - * There is an additional LF at the end - */ - return def_answ; - - if (answ[0] == '?') - { /* display help message */ - fprintf(stderr, "\n"); - fprintf(stderr, help); - fprintf(stderr, "\n"); - goto response; - } - answ[len - 1] = 0; - - if (!strcmp(answ, "y") || !strcmp(answ, "Y")) - return 1; - - return 0; -} - -int -ask_value(char *format, int default_answer) -{ - char answ[512]; - int len, num; - - play_it_again_Sam: - - if ((len = read(0, answ, sizeof(answ))) < 1) - { - fprintf(stderr, "\n\nERROR! Cannot read stdin\n"); - - perror("stdin"); - printf("invalid_configuration__run_make_config_again\n"); - exit(-1); - } - if (len < 2) /* - * There is an additional LF at the end - */ - return default_answer; - - answ[len - 1] = 0; - - if (sscanf(answ, format, &num) != 1) - { - fprintf(stderr, "Illegal format. Try again: "); - goto play_it_again_Sam; - } - return num; -} - -#define FMT_HEX 1 -#define FMT_INT 2 - -void -show_comment(int mask, char *txt) -{ - int i; - - if (dump_only) - { - - for (i = 0; i < OPT_LAST; i++) - if (mask == B(i)) - { - printf("\n\nif [ \"$CONFIG_%s\" = \"y\" ]; then\n", - hw_table[i].macro); - printf("comment '%s'\n", txt); - printf("fi\n"); - } - } else - { - if (!(mask & selected_options)) - return; - - fprintf(stderr, "%s\n", txt); - } -} - -void -ask_int_choice(int mask, char *macro, - char *question, - int format, - int defa, - char *choices) -{ - int num, i; - - if (dump_only) - { - - for (i = 0; i < OPT_LAST; i++) - if (mask == B(i)) - { - unsigned int j; - - for (j = 0; j < strlen(choices); j++) - if (choices[j] == '\'') - choices[j] = '_'; - - printf("\nif [ \"$CONFIG_%s\" = \"y\" ]; then\n", - hw_table[i].macro); - if (format == FMT_INT) - printf("int '%s %s' %s %d\n", question, choices, macro, defa); - else - printf("hex '%s %s' %s %x\n", question, choices, macro, defa); - printf("fi\n"); - } - } else - { - if (!(mask & selected_options)) - return; - - fprintf(stderr, "\n%s\n", question); - if (strcmp(choices, "")) - fprintf(stderr, "Possible values are: %s\n", choices); - - if (format == FMT_INT) - { - if (defa == -1) - fprintf(stderr, "\t(-1 disables this feature)\n"); - fprintf(stderr, "The default value is %d\n", defa); - fprintf(stderr, "Enter the value: "); - num = ask_value("%d", defa); - if (num == -1) - return; - fprintf(stderr, "%s set to %d.\n", question, num); - printf("#define %s %d\n", macro, num); - } else - { - if (defa == 0) - fprintf(stderr, "\t(0 disables this feature)\n"); - fprintf(stderr, "The default value is %x\n", defa); - fprintf(stderr, "Enter the value: "); - num = ask_value("%x", defa); - if (num == 0) - return; - fprintf(stderr, "%s set to %x.\n", question, num); - printf("#define %s 0x%x\n", macro, num); - } - } -} - -void -rebuild_file(char *line) -{ - char *method, *next, *old, *var, *p; - - method = p = line; - - while (*p && *p != ' ') - p++; - *p++ = 0; - - old = p; - while (*p && *p != ' ') - p++; - *p++ = 0; - - next = p; - while (*p && *p != ' ') - p++; - *p++ = 0; - - var = p; - while (*p && *p != ' ') - p++; - *p++ = 0; - - fprintf(stderr, "Rebuilding file `%s' (%s %s)\n", next, method, old); - - if (strcmp(method, "bin2hex") == 0) - { - if (!bin2hex(old, next, var)) - { - fprintf(stderr, "Rebuild failed\n"); - exit(-1); - } - } else if (strcmp(method, "hex2hex") == 0) - { - if (!hex2hex(old, next, var)) - { - fprintf(stderr, "Rebuild failed\n"); - exit(-1); - } - } else - { - fprintf(stderr, "Failed to build `%s' - unknown method %s\n", - next, method); - exit(-1); - } -} - -int -use_old_config(char *filename) -{ - char buf[1024]; - int i = 0; - - FILE *oldf; - - fprintf(stderr, "Copying old configuration from `%s'\n", filename); - - if ((oldf = fopen(filename, "r")) == NULL) - { - fprintf(stderr, "Couldn't open previous configuration file\n"); - perror(filename); - return 0; - } - while (fgets(buf, 1024, oldf) != NULL) - { - char tmp[100]; - - if (buf[0] != '#') - { - printf("%s", buf); - - strncpy(tmp, buf, 8); - tmp[8] = 0; - - if (strcmp(tmp, "/*build ") == 0) - rebuild_file(&buf[8]); - - continue; - } - strncpy(tmp, buf, 8); - tmp[8] = 0; - - if (strcmp(tmp, "#define ") == 0) - { - char *id = &buf[8]; - - i = 0; - while (id[i] && id[i] != ' ' && - id[i] != '\t' && id[i] != '\n') - i++; - - strncpy(tmp, id, i); - tmp[i] = 0; - - if (strcmp(tmp, "SELECTED_SOUND_OPTIONS") == 0) - continue; - - if (strcmp(tmp, "KERNEL_SOUNDCARD") == 0) - continue; - - if (strcmp(tmp, "JAZZ_DMA16") == 0) /* Rename it (hack) */ - { - printf("#define SB_DMA2 %s\n", - &buf[18]); - continue; - } - if (strcmp(tmp, "SB16_DMA") == 0) /* Rename it (hack) */ - { - printf("#define SB_DMA2 %s\n", - &buf[16]); - continue; - } - tmp[8] = 0; /* Truncate the string */ - if (strcmp(tmp, "EXCLUDE_") == 0) - continue; /* Skip excludes */ - - strncpy(tmp, id, i); - tmp[7] = 0; /* Truncate the string */ - - if (strcmp(tmp, "CONFIG_") == 0) - { - strncpy(tmp, &id[7], i - 7); - tmp[i - 7] = 0; - - for (i = 0; i <= OPT_LAST; i++) - if (strcmp(hw_table[i].macro, tmp) == 0) - { - selected_options |= (1 << i); - break; - } - continue; - } - printf("%s", buf); - continue; - } - if (strcmp(tmp, "#undef ") == 0) - { - char *id = &buf[8]; - - i = 0; - while (id[i] && id[i] != ' ' && - id[i] != '\t' && id[i] != '\n') - i++; - - strncpy(tmp, id, i); - tmp[7] = 0; /* Truncate the string */ - if (strcmp(tmp, "CONFIG_") == 0) - continue; - - strncpy(tmp, id, i); - - tmp[8] = 0; /* Truncate the string */ - if (strcmp(tmp, "EXCLUDE_") != 0) - continue; /* Not a #undef EXCLUDE_ line */ - strncpy(tmp, &id[8], i - 8); - tmp[i - 8] = 0; - - for (i = 0; i <= OPT_LAST; i++) - if (strcmp(hw_table[i].macro, tmp) == 0) - { - selected_options |= (1 << i); - break; - } - continue; - } - printf("%s", buf); - } - fclose(oldf); - - for (i = 0; i <= OPT_LAST; i++) - if (!hw_table[i].alias) - if (selected_options & B(i)) - printf("#define CONFIG_%s\n", hw_table[i].macro); - else - printf("#undef CONFIG_%s\n", hw_table[i].macro); - - - printf("\n"); - - i = 0; - - while (extra_options[i].name != NULL) - { - if (selected_options & extra_options[i].mask) - printf("#define CONFIG_%s\n", extra_options[i].name); - else - printf("#undef CONFIG_%s\n", extra_options[i].name); - i++; - } - - printf("\n"); - - printf("#define SELECTED_SOUND_OPTIONS\t0x%08x\n", selected_options); - fprintf(stderr, "Old configuration copied.\n"); - - build_defines(); - old_config_used = 1; - return 1; -} - -void -build_defines(void) -{ - FILE *optf; - int i; - - if ((optf = fopen(".defines", "w")) == NULL) - { - perror(".defines"); - exit(-1); - } - for (i = 0; i <= OPT_LAST; i++) - if (!hw_table[i].alias) - if (selected_options & B(i)) - fprintf(optf, "CONFIG_%s=y\n", hw_table[i].macro); - - - fprintf(optf, "\n"); - - i = 0; - - while (extra_options[i].name != NULL) - { - if (selected_options & extra_options[i].mask) - fprintf(optf, "CONFIG_%s=y\n", extra_options[i].name); - i++; - } - - fprintf(optf, "\n"); - fclose(optf); -} - -void -ask_parameters(void) -{ - int num; - - build_defines(); - /* - * IRQ and DMA settings - */ - - ask_int_choice(B(OPT_AEDSP16), "AEDSP16_BASE", - "I/O base for Audio Excel DSP 16", - FMT_HEX, - 0x220, - "220 or 240"); - - ask_int_choice(B(OPT_SB), "SBC_BASE", - "I/O base for SB", - FMT_HEX, - 0x220, - "Check from manual of the card"); - - ask_int_choice(B(OPT_SB), "SBC_IRQ", - "Sound Blaster IRQ", - FMT_INT, - 7, - "Check from manual of the card"); - - ask_int_choice(B(OPT_SB), "SBC_DMA", - "Sound Blaster DMA", - FMT_INT, - 1, - "0, 1 or 3"); - - ask_int_choice(B(OPT_SB), "SB_DMA2", - "Sound Blaster 16 bit DMA (SB16, Jazz16, SMW)", - FMT_INT, - 5, - "5, 6 or 7 (use 1 for 8 bit cards)"); - - ask_int_choice(B(OPT_SB), "SB_MPU_BASE", - "MPU401 I/O base of SB16, Jazz16 and ES1688", - FMT_HEX, - 0x330, - "Check from manual of the card"); - - show_comment(B(OPT_SB), - "MPU401 IRQ is only required with Jazz16, SM Wave and ESS1688."); - show_comment(B(OPT_SB), - "Enter -1 to the following question if you have something else such as SB16/32."); - - ask_int_choice(B(OPT_SB), "SB_MPU_IRQ", - "SB MPU401 IRQ (Jazz16, SM Wave and ES1688)", - FMT_INT, - -1, - "Check from manual of the card"); - - ask_int_choice(B(OPT_PAS), "PAS_IRQ", - "PAS16 IRQ", - FMT_INT, - 10, - "3, 4, 5, 7, 9, 10, 11, 12, 14 or 15"); - - ask_int_choice(B(OPT_PAS), "PAS_DMA", - "PAS16 DMA", - FMT_INT, - 3, - "0, 1, 3, 5, 6 or 7"); - - if (selected_options & B(OPT_PAS)) - { - if (think_positively("Enable Joystick port on ProAudioSpectrum", 0, - "Enable this option if you want to use the joystick port provided\n" - "on the PAS sound card.\n")) - printf("#define PAS_JOYSTICK_ENABLE\n"); - - if (think_positively("Enable PAS16 bus clock option", 0, - "The PAS16 can be noisy with some motherboards. There is a command\n" - "line switch (:T?) in the DOS driver for PAS16 which solves this.\n" - "Don't enable this feature unless you have problems and have to use\n" - "this switch with DOS\n")) - printf("#define BROKEN_BUS_CLOCK\n"); - - if (think_positively("Disable SB mode of PAS16", 0, - "You should disable SB emulation of PAS16 if you want to use\n" - "Another SB compatible card in the same system\n")) - printf("#define DISABLE_SB_EMULATION\n"); - } - ask_int_choice(B(OPT_GUS), "GUS_BASE", - "I/O base for GUS", - FMT_HEX, - 0x220, - "210, 220, 230, 240, 250 or 260"); - - - ask_int_choice(B(OPT_GUS), "GUS_IRQ", - "GUS IRQ", - FMT_INT, - 15, - "3, 5, 7, 9, 11, 12 or 15"); - - ask_int_choice(B(OPT_GUS), "GUS_DMA", - "GUS DMA", - FMT_INT, - 6, - "1, 3, 5, 6 or 7"); - - ask_int_choice(B(OPT_GUS), "GUS_DMA2", - "Second DMA channel for GUS", - FMT_INT, - -1, - "1, 3, 5, 6 or 7"); - - ask_int_choice(B(OPT_GUS16), "GUS16_BASE", - "I/O base for the 16 bit daughtercard of GUS", - FMT_HEX, - 0x530, - "530, 604, E80 or F40"); - - - ask_int_choice(B(OPT_GUS16), "GUS16_IRQ", - "GUS 16 bit daughtercard IRQ", - FMT_INT, - 7, - "3, 4, 5, 7, or 9"); - - ask_int_choice(B(OPT_GUS16), "GUS16_DMA", - "GUS DMA", - FMT_INT, - 3, - "0, 1 or 3"); - - ask_int_choice(B(OPT_MPU401), "MPU_BASE", - "I/O base for MPU401", - FMT_HEX, - 0x330, - "Check from manual of the card"); - - ask_int_choice(B(OPT_MPU401), "MPU_IRQ", - "MPU401 IRQ", - FMT_INT, - 9, - "Check from manual of the card"); - - if (dump_only) - show_comment(B(OPT_MAUI), - "ERROR! You have to use old sound configuration method with Maui."); - - ask_int_choice(B(OPT_MAUI), "MAUI_BASE", - "I/O base for Maui", - FMT_HEX, - 0x330, - "210, 230, 260, 290, 300, 320, 338 or 330"); - - ask_int_choice(B(OPT_MAUI), "MAUI_IRQ", - "Maui IRQ", - FMT_INT, - 9, - "5, 9, 12 or 15"); - - ask_int_choice(B(OPT_UART6850), "U6850_BASE", - "I/O base for UART 6850 MIDI port", - FMT_HEX, - 0, - "(Unknown)"); - - ask_int_choice(B(OPT_UART6850), "U6850_IRQ", - "UART6850 IRQ", - FMT_INT, - -1, - "(Unknown)"); - - if (dump_only) - show_comment(B(OPT_PSS), - "ERROR! You have to use old sound configuration method with PSS cards."); - - ask_int_choice(B(OPT_PSS), "PSS_BASE", - "PSS I/O base", - FMT_HEX, - 0x220, - "220 or 240"); - - ask_int_choice(B(OPT_PSS), "PSS_MSS_BASE", - "PSS audio I/O base", - FMT_HEX, - 0x530, - "530, 604, E80 or F40"); - - ask_int_choice(B(OPT_PSS), "PSS_MSS_IRQ", - "PSS audio IRQ", - FMT_INT, - 11, - "7, 9, 10 or 11"); - - ask_int_choice(B(OPT_PSS), "PSS_MSS_DMA", - "PSS audio DMA", - FMT_INT, - 3, - "0, 1 or 3"); - - ask_int_choice(B(OPT_PSS), "PSS_MPU_BASE", - "PSS MIDI I/O base", - FMT_HEX, - 0x330, - ""); - - ask_int_choice(B(OPT_PSS), "PSS_MPU_IRQ", - "PSS MIDI IRQ", - FMT_INT, - 9, - "3, 4, 5, 7 or 9"); - - ask_int_choice(B(OPT_MSS), "MSS_BASE", - "MSS/WSS I/O base", - FMT_HEX, - 0x530, - "530, 604, E80 or F40"); - - ask_int_choice(B(OPT_MSS), "MSS_IRQ", - "MSS/WSS IRQ", - FMT_INT, - 11, - "7, 9, 10 or 11"); - - ask_int_choice(B(OPT_MSS), "MSS_DMA", - "MSS/WSS DMA", - FMT_INT, - 3, - "0, 1 or 3"); - - ask_int_choice(B(OPT_MSS), "MSS_DMA2", - "MSS/WSS second DMA (if possible)", - FMT_INT, - -1, - "0, 1 or 3"); - - ask_int_choice(B(OPT_SSCAPE), "SSCAPE_BASE", - "SoundScape MIDI I/O base", - FMT_HEX, - 0x330, - "320, 330, 340 or 350"); - - ask_int_choice(B(OPT_SSCAPE), "SSCAPE_IRQ", - "SoundScape MIDI IRQ", - FMT_INT, - 9, - ""); - - ask_int_choice(B(OPT_SSCAPE), "SSCAPE_DMA", - "SoundScape initialization DMA", - FMT_INT, - 3, - "0, 1 or 3"); - - ask_int_choice(B(OPT_SSCAPE), "SSCAPE_MSS_BASE", - "SoundScape audio I/O base", - FMT_HEX, - 0x534, - "534, 608, E84 or F44"); - - ask_int_choice(B(OPT_SSCAPE), "SSCAPE_MSS_IRQ", - "SoundScape audio IRQ", - FMT_INT, - 11, - "7, 9, 10 or 11"); - - - if (selected_options & B(OPT_SSCAPE)) - { - int reveal_spea; - - reveal_spea = think_positively( - "Is your SoundScape card made/marketed by Reveal or Spea", - 0, - "Enable if you have a SoundScape card with the Reveal or\n" - "Spea name on it.\n"); - if (reveal_spea) - printf("#define REVEAL_SPEA\n"); - - } - if (dump_only) - show_comment(B(OPT_TRIX), - "ERROR! You have to use old sound configuration method with OPL3-SA1."); - - ask_int_choice(B(OPT_TRIX), "TRIX_BASE", - "OPL3-SA1 audio I/O base", - FMT_HEX, - 0x530, - "530, 604, E80 or F40"); - - ask_int_choice(B(OPT_TRIX), "TRIX_IRQ", - "OPL3-SA1 audio IRQ", - FMT_INT, - 11, - "7, 9, 10 or 11"); - - ask_int_choice(B(OPT_TRIX), "TRIX_DMA", - "OPL3-SA1 audio DMA", - FMT_INT, - 0, - "0, 1 or 3"); - - ask_int_choice(B(OPT_TRIX), "TRIX_DMA2", - "OPL3-SA1 second (duplex) DMA", - FMT_INT, - 3, - "0, 1 or 3"); - - ask_int_choice(B(OPT_TRIX), "TRIX_MPU_BASE", - "OPL3-SA1 MIDI I/O base", - FMT_HEX, - 0x330, - "330, 370, 3B0 or 3F0"); - - ask_int_choice(B(OPT_TRIX), "TRIX_MPU_IRQ", - "OPL3-SA1 MIDI IRQ", - FMT_INT, - 9, - "3, 4, 5, 7 or 9"); - - ask_int_choice(B(OPT_TRIX), "TRIX_SB_BASE", - "OPL3-SA1 SB I/O base", - FMT_HEX, - 0x220, - "220, 210, 230, 240, 250, 260 or 270"); - - ask_int_choice(B(OPT_TRIX), "TRIX_SB_IRQ", - "OPL3-SA1 SB IRQ", - FMT_INT, - 7, - "3, 4, 5 or 7"); - - ask_int_choice(B(OPT_TRIX), "TRIX_SB_DMA", - "OPL3-SA1 SB DMA", - FMT_INT, - 1, - "1 or 3"); - - - ask_int_choice(B(OPT_OPL3SA1), "OPL3SA1_BASE", - "OPL3-SA1 audio I/O base", - FMT_HEX, - 0x530, - "530, 604, E80 or F40"); - - ask_int_choice(B(OPT_OPL3SA1), "OPL3SA1_IRQ", - "OPL3-SA1 audio IRQ", - FMT_INT, - 11, - "7, 9, 10 or 11"); - - ask_int_choice(B(OPT_OPL3SA1), "OPL3SA1_DMA", - "OPL3-SA1 audio DMA", - FMT_INT, - 0, - "0, 1 or 3"); - - ask_int_choice(B(OPT_OPL3SA1), "OPL3SA1_DMA2", - "OPL3-SA1 second (duplex) DMA", - FMT_INT, - 3, - "0, 1 or 3"); - - ask_int_choice(B(OPT_OPL3SA1), "OPL3SA1_MPU_BASE", - "OPL3-SA1 MIDI I/O base", - FMT_HEX, - 0x330, - "330, 370, 3B0 or 3F0"); - - ask_int_choice(B(OPT_OPL3SA1), "OPL3SA1_MPU_IRQ", - "OPL3-SA1 MIDI IRQ", - FMT_INT, - 9, - "3, 4, 5, 7 or 9"); - - ask_int_choice(B(OPT_CS4232), "CS4232_BASE", - "CS4232 audio I/O base", - FMT_HEX, - 0x534, - "534, 608, E84 or F44"); - - ask_int_choice(B(OPT_CS4232), "CS4232_IRQ", - "CS4232 audio IRQ", - FMT_INT, - 11, - "5, 7, 9, 11, 12 or 15"); - - ask_int_choice(B(OPT_CS4232), "CS4232_DMA", - "CS4232 audio DMA", - FMT_INT, - 0, - "0, 1 or 3"); - - ask_int_choice(B(OPT_CS4232), "CS4232_DMA2", - "CS4232 second (duplex) DMA", - FMT_INT, - 3, - "0, 1 or 3"); - - ask_int_choice(B(OPT_CS4232), "CS4232_MPU_BASE", - "CS4232 MIDI I/O base", - FMT_HEX, - 0x330, - "330, 370, 3B0 or 3F0"); - - ask_int_choice(B(OPT_CS4232), "CS4232_MPU_IRQ", - "CS4232 MIDI IRQ", - FMT_INT, - 9, - "5, 7, 9, 11, 12 or 15"); - - ask_int_choice(B(OPT_MAD16), "MAD16_BASE", - "MAD16 audio I/O base", - FMT_HEX, - 0x530, - "530, 604, E80 or F40"); - - ask_int_choice(B(OPT_MAD16), "MAD16_IRQ", - "MAD16 audio IRQ", - FMT_INT, - 11, - "7, 9, 10 or 11"); - - ask_int_choice(B(OPT_MAD16), "MAD16_DMA", - "MAD16 audio DMA", - FMT_INT, - 3, - "0, 1 or 3"); - - ask_int_choice(B(OPT_MAD16), "MAD16_DMA2", - "MAD16 second (duplex) DMA", - FMT_INT, - 0, - "0, 1 or 3"); - - ask_int_choice(B(OPT_MAD16), "MAD16_MPU_BASE", - "MAD16 MIDI I/O base", - FMT_HEX, - 0x330, - "300, 310, 320 or 330 (0 disables)"); - - ask_int_choice(B(OPT_MAD16), "MAD16_MPU_IRQ", - "MAD16 MIDI IRQ", - FMT_INT, - 9, - "5, 7, 9 or 10"); - ask_int_choice(B(OPT_SOFTOSS), "SOFTOSS_RATE", - "Sampling rate for SoftOSS", - FMT_INT, - 22050, - "8000 to 48000"); - ask_int_choice(B(OPT_SOFTOSS), "SOFTOSS_VOICES", - "Max # of concurrent voices for SoftOSS", - FMT_INT, - 32, - "4 to 32"); -} - -void -dump_script(void) -{ - int i; - - for (i = 0; i <= OPT_LAST; i++) - if (!(DUMMY_OPTS & B(i))) - if (!(DISABLED_OPTIONS & B(i))) - { - printf("bool '%s' CONFIG_%s\n", questions[i], hw_table[i].macro); - } -/* - * Some "hardcoded" options - */ - - dump_only = 1; - selected_options = 0; - ask_parameters(); - - printf("#\n$MAKE -C drivers/sound kernelconfig || exit 1\n"); -} - -void -dump_fixed_local(void) -{ - int i = 0; - - printf("/* Computer generated file. Please don't edit! */\n\n"); - printf("#define KERNEL_COMPATIBLE_CONFIG\n\n"); - printf("#define SELECTED_SOUND_OPTIONS\t0x%08x\n\n", selected_options); - - while (extra_options[i].name != NULL) - { - int n = 0, j; - - printf("#if "); - - for (j = 0; j < OPT_LAST; j++) - if (!(DISABLED_OPTIONS & B(j))) - if (extra_options[i].mask & B(j)) - { - if (n) - printf(" || "); - if (!(n++ % 2)) - printf("\\\n "); - - printf("defined(CONFIG_%s)", hw_table[j].macro); - } - printf("\n"); - printf("#\tdefine CONFIG_%s\n", extra_options[i].name); - printf("#endif\n\n"); - i++; - } -} - -void -dump_fixed_defines(void) -{ - int i = 0; - - printf("# Computer generated file. Please don't edit\n\n"); - - while (extra_options[i].name != NULL) - { - int j; - - for (j = 0; j < OPT_LAST; j++) - { - if (!(DISABLED_OPTIONS & B(j))) - { - if (extra_options[i].mask & B(j)) - { - printf("ifdef CONFIG_%s\n", hw_table[j].macro); - printf ("ifneq ($(CONFIG_%s),Y)\n", extra_options[i].name); - printf("CONFIG_%s=y\n", extra_options[i].name); - printf("endif\n"); - printf("endif\n\n"); - } - } - } - i++; - } -} - -int -main(int argc, char *argv[]) -{ - int i, full_driver = 1; - char old_config_file[200]; - - if (getuid() != 0) /* Not root */ - { - char *home; - - if ((home = getenv("HOME")) != NULL) - { - sprintf(old_config_file, "%s/.soundconf", home); - oldconf = old_config_file; - } - } - if (argc > 1) - { - if (strcmp(argv[1], "-o") == 0 && - use_old_config(oldconf)) - exit(0); - else if (strcmp(argv[1], "script") == 0) - { - dump_script(); - exit(0); - } else if (strcmp(argv[1], "fixedlocal") == 0) - { - dump_fixed_local(); - exit(0); - } else if (strcmp(argv[1], "fixeddefines") == 0) - { - dump_fixed_defines(); - exit(0); - } - } - fprintf(stderr, "\nConfiguring Sound Support\n\n"); - - if (access(oldconf, R_OK) == 0) - { - char str[255]; - - sprintf(str, "Old configuration exists in `%s'. Use it", oldconf); - if (think_positively(str, 1, - "Enable this option to load the previously saved configuration file\n" - "for all of the sound driver parameters.\n")) - if (use_old_config(oldconf)) - exit(0); - } - printf("/*\tGenerated by configure. Don't edit!!!!\t*/\n"); - printf("/*\tMaking changes to this file is not as simple as it may look.\t*/\n\n"); - printf("/*\tIf you change the CONFIG_ settings in local.h you\t*/\n"); - printf("/*\t_have_ to edit .defines too.\t*/\n\n"); - - { - /* - * Partial driver - */ - - full_driver = 0; - - for (i = 0; i <= OPT_LAST; i++) - if (can_select_option(i)) - { - if (!(selected_options & B(i))) /* - * Not selected yet - */ - if (!hw_table[i].verify) - { - if (hw_table[i].alias) - selected_options |= B(hw_table[i].alias); - else - selected_options |= B(i); - } else - { - int def_answ = hw_table[i].default_answ; - - if (think_positively(questions[i], def_answ, help[i])) - if (hw_table[i].alias) - selected_options |= B(hw_table[i].alias); - else - selected_options |= B(i); - } - } - } - - if (selected_options & B(OPT_SB)) - { - if (think_positively( - "Support for the SG NX Pro mixer", 0, - "Enable this if you want to support the additional mixer functions\n" - "provided on Sound Galaxy NX Pro sound cards.\n")) - printf("#define __SGNXPRO__\n"); - } - if (selected_options & B(OPT_SB)) - { - if (think_positively("Support for the MV Jazz16 (ProSonic etc.)", 0, - "Enable this if you have an MV Jazz16 or ProSonic sound card.\n")) - { - if (think_positively("Do you have SoundMan Wave", 0, - "Enable this option of you have the Logitech SoundMan Wave sound card.\n")) - { - printf("#define SM_WAVE\n"); - - midi0001_again: - if (think_positively( - "Do you have access to the MIDI0001.BIN file", 1, - "The Logitech SoundMan Wave has a microcontroller which must be\n" - "initialized before MIDI emulation works. This is possible only if the\n" - "microcode file is compiled into the driver.\n")) - { - char path[512]; - - fprintf(stderr, - "Enter full name of the MIDI0001.BIN file (pwd is sound): "); - scanf("%s", path); - fprintf(stderr, "including microcode file %s\n", path); - - if (!bin2hex(path, "smw-midi0001.h", "smw_ucode")) - { - fprintf(stderr, "Couldn't open file %s\n", - path); - if (think_positively("Try again with correct path", 1, - "The specified file could not be opened. Enter the correct path to the\n" - "file.\n")) - goto midi0001_again; - } else - { - printf("#define SMW_MIDI0001_INCLUDED\n"); - printf("/*build bin2hex %s smw-midi0001.h smw_ucode */\n", path); - } - } - } - } - } - if (selected_options & B(OPT_SB)) - { - if (think_positively("Do you have a Logitech SoundMan Games", 0, - "The Logitech SoundMan Games supports 44 kHz in stereo while the\n" - "standard SB Pro supports just 22 kHz stereo. You have the option of\n" - "enabling SM Games mode. However, enable it only if you are sure that\n" - "your card is an SM Games. Enabling this feature with a plain old SB\n" - "Pro will cause troubles with stereo mode.\n\n" - "DANGER! Read the above once again before answering 'y'\n" - "Answer 'n' if you are unsure what to do!\n")) - printf("#define SM_GAMES\n"); - } - if (selected_options & B(OPT_AEDSP16)) - { - int sel1 = 0; - - if (selected_options & B(OPT_SB)) - { - - if (think_positively( - "Do you want support for the Audio Excel Sound Blaster Pro mode", - 1, - "Enable this option if you want the Audio Excel sound card to operate\n" - "in Sound Blaster Pro mode.\n")) - { - printf("#define AEDSP16_SBPRO\n"); - sel1 = 1; - } - } - if ((selected_options & B(OPT_MSS)) && (sel1 == 0)) - { - - if (think_positively( - "Do you want support for the Audio Excel Microsoft Sound System mode", - 1, - "Enable this option if you want the Audio Excel sound card to operate\n" - "in Microsoft Sound System mode.\n")) - { - printf("#define AEDSP16_MSS\n"); - sel1 = 1; - } - } - if (sel1 == 0) - { - printf("invalid_configuration__run_make_config_again\n"); - fprintf(stderr, "ERROR!!!!!\nYou must select at least one mode when using Audio Excel!\n"); - exit(-1); - } - if (selected_options & B(OPT_MPU401)) - printf("#define AEDSP16_MPU401\n"); - } - if (selected_options & B(OPT_PSS)) - { - genld_again: - if (think_positively("Do you wish to include an LD file", 1, - "If you want to emulate the Sound Blaster card and you have a DSPxxx.LD\n" - "file then you must include the LD in the kernel.\n")) - { - char path[512]; - - fprintf(stderr, - "Enter the path to your LD file (pwd is sound): "); - scanf("%s", path); - fprintf(stderr, "including LD file %s\n", path); - - if (!bin2hex(path, "synth-ld.h", "pss_synth")) - { - fprintf(stderr, "couldn't open `%s' as the LD file\n", path); - if (think_positively("try again with correct path", 1, - "The given LD file could not opened.\n")) - goto genld_again; - } else - { - printf("#define PSS_HAVE_LD\n"); - printf("/*build bin2hex %s synth-ld.h pss_synth */\n", path); - } - } else - { - FILE *sf = fopen("synth-ld.h", "w"); - - fprintf(sf, "/* automatically generated by configure */\n"); - fprintf(sf, "unsigned char pss_synth[1];\n" - "#define pss_synthLen 0\n"); - fclose(sf); - } - } - if (selected_options & B(OPT_TRIX)) - { - hex2hex_again: - - if (think_positively("Do you want to include TRXPRO.HEX in your kernel", - 1, - "The MediaTrix AudioTrix Pro has an on-board microcontroller which\n" - "needs to be initialized by downloading the code from the file TRXPRO.HEX\n" - "in the DOS driver directory. If you don't have the TRXPRO.HEX file handy\n" - "you may skip this step. However, the SB and MPU-401 modes of AudioTrix\n" - "Pro will not work without this file!\n")) - { - char path[512]; - - fprintf(stderr, - "Enter the path to your TRXPRO.HEX file (pwd is sound): "); - scanf("%s", path); - fprintf(stderr, "including HEX file `%s'\n", path); - - if (!hex2hex(path, "trix_boot.h", "trix_boot")) - goto hex2hex_again; - printf("/*build hex2hex %s trix_boot.h trix_boot */\n", path); - printf("#define INCLUDE_TRIX_BOOT\n"); - } - } - if (selected_options & B(OPT_MSS)) - { - if (think_positively("Support for builtin sound of Compaq Deskpro XL", 0, - "Enable this if you have Compaq Deskpro XL.\n")) - { - printf("#define DESKPROXL\n"); - } - } - if (selected_options & B(OPT_MAUI)) - { - oswf_again: - if (think_positively( - "Do you have access to the OSWF.MOT file", 1, - "TB Maui and Tropez have a microcontroller which needs to be initialized\n" - "prior use. OSWF.MOT is a file distributed with card's DOS/Windows drivers\n" - "which is required during initialization\n")) - { - char path[512]; - - fprintf(stderr, - "Enter full name of the OSWF.MOT file (pwd is sound): "); - scanf("%s", path); - fprintf(stderr, "including microcode file %s\n", path); - - if (!bin2hex(path, "maui_boot.h", "maui_os")) - { - fprintf(stderr, "Couldn't open file %s\n", - path); - if (think_positively("Try again with correct path", 1, - "The specified file could not be opened. Enter the correct path to the\n" - "file.\n")) - goto oswf_again; - } else - { - printf("#define HAVE_MAUI_BOOT\n"); - printf("/*build bin2hex %s maui_boot.h maui_os */\n", path); - } - } - } - if (!(selected_options & ANY_DEVS)) - { - printf("invalid_configuration__run_make_config_again\n"); - fprintf(stderr, "\n*** This combination is useless. Sound driver disabled!!! ***\n*** You need to enable support for at least one device ***\n\n"); - exit(0); - } - for (i = 0; i <= OPT_LAST; i++) - if (!hw_table[i].alias) - if (selected_options & B(i)) - printf("#define CONFIG_%s\n", hw_table[i].macro); - else - printf("#undef CONFIG_%s\n", hw_table[i].macro); - - printf("\n"); - - i = 0; - - while (extra_options[i].name != NULL) - { - if (selected_options & extra_options[i].mask) - printf("#define CONFIG_%s\n", extra_options[i].name); - else - printf("#undef CONFIG_%s\n", extra_options[i].name); - i++; - } - - printf("\n"); - - ask_parameters(); - - printf("#define SELECTED_SOUND_OPTIONS\t0x%08lx\n", selected_options); - fprintf(stderr, "\nThe sound driver is now configured.\n"); - - if (!old_config_used) - { - char str[255]; - - sprintf(str, "Save copy of this configuration to `%s'", oldconf); - if (think_positively(str, 1, - "If you enable this option then the sound driver configuration is\n" - "saved to a file. If you later need to recompile the kernel you have\n" - "the option of using the saved configuration.\n")) - { - char cmd[200]; - - sprintf(cmd, "cp local.h %s", oldconf); - - fclose(stdout); - if (system(cmd) != 0) - perror(cmd); - } - } - exit(0); -} - -int -bin2hex(char *path, char *target, char *varname) -{ - int fd; - int count; - char c; - int i = 0; - - if ((fd = open(path, 0)) > 0) - { - FILE *sf = fopen(target, "w"); - - fprintf(sf, "/* automatically generated by configure */\n"); - fprintf(sf, "static unsigned char %s[] = {\n", varname); - while (1) - { - count = read(fd, &c, 1); - if (count == 0) - break; - if (i != 0 && (i % 10) == 0) - fprintf(sf, "\n"); - fprintf(sf, "0x%02lx,", c & 0xFFL); - i++; - } - fprintf(sf, "};\n" - "#define %sLen %d\n", varname, i); - fclose(sf); - close(fd); - return 1; - } - return 0; -} diff -u --recursive --new-file v2.1.75/linux/drivers/sound/dev_table.h linux/drivers/sound/dev_table.h --- v2.1.75/linux/drivers/sound/dev_table.h Sun Dec 21 22:36:15 1997 +++ linux/drivers/sound/dev_table.h Tue Dec 23 13:52:02 1997 @@ -15,6 +15,7 @@ #ifndef _DEV_TABLE_H_ #define _DEV_TABLE_H_ +#include /* * Sound card numbers 27 to 999. (1 to 26 are defined in soundcard.h) diff -u --recursive --new-file v2.1.75/linux/drivers/sound/hex2hex.c linux/drivers/sound/hex2hex.c --- v2.1.75/linux/drivers/sound/hex2hex.c Wed Dec 31 16:00:00 1969 +++ linux/drivers/sound/hex2hex.c Tue Dec 23 13:52:02 1997 @@ -0,0 +1,87 @@ +/* + * hex2hex reads stdin in Intel HEX format and produces an + * (unsigned char) array which contains the bytes and writes it + * to stdout using C syntax + */ + +#include +#include + +#define ABANDON(why) { fprintf(stderr, "%s\n", why); exit(1); } +#define MAX_SIZE (256*1024) +unsigned char buf[MAX_SIZE]; + +int loadhex(FILE *inf, unsigned char *buf) +{ + int l=0, c, i; + + while ((c=getc(inf))!=EOF) + { + if (c == ':') /* Sync with beginning of line */ + { + int n, check; + unsigned char sum; + int addr; + int linetype; + + if (fscanf(inf, "%02x", &n) != 1) + ABANDON("File format error"); + sum = n; + + if (fscanf(inf, "%04x", &addr) != 1) + ABANDON("File format error"); + sum += addr/256; + sum += addr%256; + + if (fscanf(inf, "%02x", &linetype) != 1) + ABANDON("File format error"); + sum += linetype; + + if (linetype != 0) + continue; + + for (i=0;i= MAX_SIZE) + ABANDON("File too large"); + buf[addr++] = c; + if (addr > l) + l = addr; + sum += c; + } + + if (fscanf(inf, "%02x", &check) != 1) + ABANDON("File format error"); + + sum = ~sum + 1; + if (check != sum) + ABANDON("Line checksum error"); + } + } + + return l; +} + +int main( int argc, const char * argv [] ) +{ + const char * varline = argv[1]; + int i,l; + + l = loadhex(stdin, buf); + + printf("/*\n *\t Computer generated file. Do not edit.\n */\n"); + printf("static int %s_len = %d;\n", varline, l); + printf("static unsigned char %s[] = {\n", varline); + + for (i=0;i= MAX_SIZE) - ABANDON("File too large"); - buf[addr++] = c; - if (addr > l) - l = addr; - sum += c; - } - - if (fscanf(inf, "%02x", &check) != 1) - ABANDON("File format error"); - - sum = ~sum + 1; - if (check != sum) - ABANDON("Line checksum error"); - } - } - - return l; -} - -int hex2hex(char *source, char *target, char *varline) -{ - FILE *inf, *outf; - - int i,l; - unsigned char buf[MAX_SIZE]; - - if ((inf=fopen(source, "r"))==NULL) - { - perror(source); - return 0; - } - - if ((outf=fopen(target, "w"))==NULL) - { - perror(target); - fclose(inf); - return 0; - } - - l=loadhex(inf, buf, source); - if (l<=0) - { - fclose(inf); - fclose(outf); - return l; - } - - - fprintf(outf, "/*\n *\t Computer generated file. Do not edit.\n */\n"); - fprintf(outf, "static int %s_len = %d;\n", varline, l); - fprintf(outf, "static unsigned char %s[] = {\n", varline); - - for (i=0;i + #define KERNEL_COMPATIBLE_CONFIG #define SELECTED_SOUND_OPTIONS 0x00000000 diff -u --recursive --new-file v2.1.75/linux/drivers/sound/maui.c linux/drivers/sound/maui.c --- v2.1.75/linux/drivers/sound/maui.c Tue Dec 2 09:49:39 1997 +++ linux/drivers/sound/maui.c Tue Dec 23 13:52:02 1997 @@ -41,12 +41,11 @@ static int (*orig_load_patch) (int dev, int format, const char *addr, int offs, int count, int pmgr_flag) = NULL; -#ifdef HAVE_MAUI_BOOT +#ifdef MAUI_HAVE_BOOT #include "maui_boot.h" #else static unsigned char *maui_os = NULL; -static int maui_osLen = 0; - +static int maui_osLen = 0; #endif static struct wait_queue *maui_sleeper = NULL; diff -u --recursive --new-file v2.1.75/linux/drivers/sound/opl3.c linux/drivers/sound/opl3.c --- v2.1.75/linux/drivers/sound/opl3.c Sat Nov 29 11:25:11 1997 +++ linux/drivers/sound/opl3.c Tue Dec 23 13:52:02 1997 @@ -1204,7 +1204,6 @@ { if (devc) { - vfree(devc); devc = NULL; sound_unload_synthdev(me); } diff -u --recursive --new-file v2.1.75/linux/drivers/sound/pss.c linux/drivers/sound/pss.c --- v2.1.75/linux/drivers/sound/pss.c Mon Dec 1 12:04:13 1997 +++ linux/drivers/sound/pss.c Tue Dec 23 13:52:02 1997 @@ -51,13 +51,11 @@ #include "coproc.h" -#ifdef PSS_HAVE_LD -#include "synth-ld.h" +#ifdef PSS_HAVE_BOOT +#include "pss_boot.h" #else -static int pss_synthLen = 0; -static unsigned char *pss_synth = -NULL; - +static unsigned char *pss_synth = NULL; +static int pss_synthLen = 0; #endif typedef struct pss_confdata diff -u --recursive --new-file v2.1.75/linux/drivers/sound/sb.h linux/drivers/sound/sb.h --- v2.1.75/linux/drivers/sound/sb.h Sat Nov 29 11:25:11 1997 +++ linux/drivers/sound/sb.h Tue Dec 23 13:52:02 1997 @@ -1,3 +1,5 @@ +#include + #ifdef CONFIG_SBDSP #define DSP_RESET (devc->base + 0x6) #define DSP_READ (devc->base + 0xA) diff -u --recursive --new-file v2.1.75/linux/drivers/sound/sb_mixer.h linux/drivers/sound/sb_mixer.h --- v2.1.75/linux/drivers/sound/sb_mixer.h Sat Nov 29 11:25:11 1997 +++ linux/drivers/sound/sb_mixer.h Tue Dec 23 13:52:02 1997 @@ -17,6 +17,8 @@ * Added defines for the Sound Galaxy NX Pro mixer. * */ +#include + #ifdef CONFIG_SBDSP #define SBPRO_RECORDING_DEVICES (SOUND_MASK_LINE | SOUND_MASK_MIC | SOUND_MASK_CD) diff -u --recursive --new-file v2.1.75/linux/drivers/sound/sound_syms.c linux/drivers/sound/sound_syms.c --- v2.1.75/linux/drivers/sound/sound_syms.c Sun Dec 21 22:36:15 1997 +++ linux/drivers/sound/sound_syms.c Tue Dec 23 13:52:02 1997 @@ -5,7 +5,6 @@ * (C) Copyright 1997 Alan Cox, Licensed under the GNU GPL */ -#include #include #include "sound_config.h" #define _MIDI_SYNTH_C_ diff -u --recursive --new-file v2.1.75/linux/drivers/sound/trix.c linux/drivers/sound/trix.c --- v2.1.75/linux/drivers/sound/trix.c Sat Nov 29 11:25:11 1997 +++ linux/drivers/sound/trix.c Tue Dec 23 13:52:02 1997 @@ -27,12 +27,11 @@ #endif #endif -#ifdef INCLUDE_TRIX_BOOT +#ifdef TRIX_HAVE_BOOT #include "trix_boot.h" #else static unsigned char *trix_boot = NULL; -static int trix_boot_len = 0; - +static int trix_boot_len = 0; #endif diff -u --recursive --new-file v2.1.75/linux/drivers/sound/uart401.c linux/drivers/sound/uart401.c --- v2.1.75/linux/drivers/sound/uart401.c Wed Dec 10 11:12:44 1997 +++ linux/drivers/sound/uart401.c Tue Dec 23 13:52:02 1997 @@ -452,8 +452,8 @@ if (!devc->share_irq) snd_release_irq(devc->irq); - if (!devc) - vfree(devc); + if (devc) + devc = NULL; sound_unload_mididev(hw_config->slots[4]); } diff -u --recursive --new-file v2.1.75/linux/fs/buffer.c linux/fs/buffer.c --- v2.1.75/linux/fs/buffer.c Sun Dec 21 22:36:15 1997 +++ linux/fs/buffer.c Mon Dec 22 14:28:40 1997 @@ -126,20 +126,22 @@ */ void __wait_on_buffer(struct buffer_head * bh) { - struct wait_queue wait = { current, NULL }; + struct task_struct *tsk = current; + struct wait_queue wait; bh->b_count++; + wait.task = tsk; add_wait_queue(&bh->b_wait, &wait); repeat: + tsk->state = TASK_UNINTERRUPTIBLE; run_task_queue(&tq_disk); - current->state = TASK_UNINTERRUPTIBLE; if (buffer_locked(bh)) { schedule(); goto repeat; } + tsk->state = TASK_RUNNING; remove_wait_queue(&bh->b_wait, &wait); bh->b_count--; - current->state = TASK_RUNNING; } /* Call sync_buffers with wait!=0 to ensure that the call does not @@ -561,7 +563,7 @@ } } -static inline struct buffer_head * find_buffer(kdev_t dev, int block, int size) +struct buffer_head * find_buffer(kdev_t dev, int block, int size) { struct buffer_head * next; @@ -579,11 +581,6 @@ return next; } -struct buffer_head *efind_buffer(kdev_t dev, int block, int size) -{ - return find_buffer(dev, block, size); -} - /* * Why like this, I hear you say... The reason is race-conditions. * As we don't lock buffers (unless we are reading them, that is), @@ -600,7 +597,7 @@ break; bh->b_count++; bh->b_lru_time = jiffies; - if (!test_bit(BH_Lock, &bh->b_state)) + if (!buffer_locked(bh)) break; __wait_on_buffer(bh); if (bh->b_dev == dev && diff -u --recursive --new-file v2.1.75/linux/fs/coda/cache.c linux/fs/coda/cache.c --- v2.1.75/linux/fs/coda/cache.c Wed Dec 31 16:00:00 1969 +++ linux/fs/coda/cache.c Mon Dec 22 08:40:49 1997 @@ -0,0 +1,329 @@ +/* + * Cache operations for Coda. + * For Linux 2.1: (C) 1997 Carnegie Mellon University + * + * Carnegie Mellon encourages users of this code to contribute improvements + * to the Coda project. Contact Peter Braam . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +/* Keep various stats */ +struct cfsnc_statistics cfsnc_stat; + + +/* we need to call INIT_LIST_HEAD on cnp->c_cnhead and sbi->sbi_cchead */ + +void coda_ccinsert(struct coda_cache *el, struct super_block *sb) +{ + struct coda_sb_info *sbi = coda_sbp(sb); +ENTRY; + if ( !sbi || !el) { + printk("coda_ccinsert: NULL sbi or el!\n"); + return ; + } + + list_add(&el->cc_cclist, &sbi->sbi_cchead); +} + +void coda_cninsert(struct coda_cache *el, struct cnode *cnp) +{ +ENTRY; + if ( !cnp || !el) { + printk("coda_cninsert: NULL cnp or el!\n"); + return ; + } + list_add(&el->cc_cnlist, &cnp->c_cnhead); +} + +void coda_ccremove(struct coda_cache *el) +{ +ENTRY; + list_del(&el->cc_cclist); +} + +void coda_cnremove(struct coda_cache *el) +{ +ENTRY; + list_del(&el->cc_cnlist); +} + + +void coda_cache_create(struct inode *inode, int mask) +{ + struct cnode *cnp = ITOC(inode); + struct super_block *sb = inode->i_sb; + struct coda_cache *cc = NULL; +ENTRY; + CODA_ALLOC(cc, struct coda_cache *, sizeof(*cc)); + + if ( !cc ) { + printk("Out of memory in coda_cache_enter!\n"); + return; + } + coda_load_creds(&cc->cc_cred); + cc->cc_mask = mask; + coda_cninsert(cc, cnp); + coda_ccinsert(cc, sb); +} + +struct coda_cache * coda_cache_find(struct inode *inode) +{ + struct cnode *cnp = ITOC(inode); + struct list_head *lh, *le; + struct coda_cache *cc = NULL; + + le = lh = &cnp->c_cnhead; + while( (le = le->next ) != lh ) { + /* compare name and creds */ + cc = list_entry(le, struct coda_cache, cc_cnlist); + if ( !coda_cred_ok(&cc->cc_cred) ) + continue; + CDEBUG(D_CACHE, "HIT for ino %ld\n", inode->i_ino ); + return cc; /* cache hit */ + } + return NULL; +} + +void coda_cache_enter(struct inode *inode, int mask) +{ + struct coda_cache *cc; + + cc = coda_cache_find(inode); + + if ( cc ) { + cc->cc_mask |= mask; + } else { + coda_cache_create(inode, mask); + } +} + +void coda_cache_clear_cnp(struct cnode *cnp) +{ + struct list_head *lh, *le; + struct coda_cache *cc; + + if ( !cnp ) { + printk("coda_cache_cnp_clear: NULL cnode\n"); + return; + } + + lh = le = &cnp->c_cnhead; + while ( (le = le->next ) != lh ) { + cc = list_entry(le, struct coda_cache, cc_cnlist); + coda_cnremove(cc); + coda_ccremove(cc); + CODA_FREE(cc, sizeof(*cc)); + } +} + +void coda_cache_clear_all(struct super_block *sb) +{ + struct list_head *lh, *le; + struct coda_cache *cc; + struct coda_sb_info *sbi = coda_sbp(sb); + + if ( !sbi ) { + printk("coda_cache_clear_all: NULL sbi\n"); + return; + } + + lh = le = &sbi->sbi_cchead; + while ( (le = le->next ) != lh ) { + cc = list_entry(le, struct coda_cache, cc_cclist); + coda_cnremove(cc); + coda_ccremove(cc); + CODA_FREE(cc, sizeof(*cc)); + } +} + +void coda_cache_clear_cred(struct super_block *sb, struct coda_cred *cred) +{ + struct list_head *lh, *le; + struct coda_cache *cc; + struct coda_sb_info *sbi = coda_sbp(sb); + + if ( !sbi ) { + printk("coda_cache_clear_all: NULL sbi\n"); + return; + } + + lh = le = &sbi->sbi_cchead; + while ( (le = le->next ) != lh ) { + cc = list_entry(le, struct coda_cache, cc_cclist); + if ( coda_cred_eq(&cc->cc_cred, cred)) { + coda_cnremove(cc); + coda_ccremove(cc); + CODA_FREE(cc, sizeof(*cc)); + } + } +} + + +int coda_cache_check(struct inode *inode, int mask) +{ + struct cnode *cnp = ITOC(inode); + struct list_head *lh, *le; + struct coda_cache *cc = NULL; + + le = lh = &cnp->c_cnhead; + while( (le = le->next ) != lh ) { + /* compare name and creds */ + cc = list_entry(le, struct coda_cache, cc_cnlist); + if ( (cc->cc_mask & mask) != mask ) + continue; + if ( !coda_cred_ok(&cc->cc_cred) ) + continue; + CDEBUG(D_CACHE, "HIT for ino %ld\n", inode->i_ino ); + return 1; /* cache hit */ + } + CDEBUG(D_CACHE, "MISS for ino %ld\n", inode->i_ino ); + return 0; +} + + +/* DENTRY related stuff */ + +/* when the dentry count falls to 0 this is called. If Venus has + asked for it to be flushed, we take it out of the dentry hash + table with d_drop */ + +static void coda_flag_children(struct dentry *parent) +{ + struct list_head *child; + struct cnode *cnp; + struct dentry *de; + char str[50]; + + child = parent->d_subdirs.next; + while ( child != &parent->d_subdirs ) { + de = list_entry(child, struct dentry, d_child); + cnp = ITOC(de->d_inode); + if (cnp) + cnp->c_flags |= C_ZAPFID; + CDEBUG(D_CACHE, "ZAPFID for %s\n", coda_f2s(&cnp->c_fid, str)); + + child = child->next; + } + return; +} + +/* flag dentry and possibly children of a dentry with C_ZAPFID */ +void coda_dentry_delete(struct dentry *dentry) +{ + struct inode *inode = dentry->d_inode; + struct cnode *cnp = NULL; + ENTRY; + + if (inode) { + cnp = ITOC(inode); + if ( cnp ) + CHECK_CNODE(cnp); + } else { + printk("No inode for dentry_delete!\n"); + return; + } + + + if ( !cnp ) { + printk("No cnode for dentry_delete!\n"); + return; + } + + if ( cnp->c_flags & (C_ZAPFID | C_ZAPDIR) ) + d_drop(dentry); + if ( (cnp->c_flags & C_ZAPDIR) && S_ISDIR(inode->i_mode) ) { + coda_flag_children(dentry); + } + return; +} + +/* the dache will notice the flags and drop entries (possibly with + children) the moment they are no longer in use */ +void coda_zapfid(struct ViceFid *fid, struct super_block *sb, int flag) +{ + struct inode *inode = NULL; + struct cnode *cnp; + + ENTRY; + + if ( !sb ) { + printk("coda_zapfid: no sb!\n"); + return; + } + + if ( !fid ) { + printk("coda_zapfid: no fid!\n"); + return; + } + + inode = coda_fid_to_inode(fid, sb); + if ( !inode ) { + printk("coda_zapfid: no inode!\n"); + return; + } + cnp = ITOC(inode); + CHECK_CNODE(cnp); + if ( !cnp ) { + printk("coda_zapfid: no cnode!\n"); + return; + } + cnp->c_flags |= flag; + coda_cache_clear_cnp(cnp); +} + + +int +cfsnc_nc_info(char *buffer, char **start, off_t offset, int length, int dummy) +{ + int len=0; + off_t begin; + + /* cfsnc_gather_stats(); */ + + /* this works as long as we are below 1024 characters! */ + len += sprintf(buffer,"Coda minicache statistics\n\n"); + len += sprintf(buffer+len, "cfsnc_hits : %d\n", cfsnc_stat.hits); + len += sprintf(buffer+len, "cfsnc_misses : %d\n", cfsnc_stat.misses); + len += sprintf(buffer+len, "cfsnc_enters : %d\n", cfsnc_stat.enters); + len += sprintf(buffer+len, "cfsnc_dbl_enters : %d\n", cfsnc_stat.dbl_enters); + len += sprintf(buffer+len, "cfsnc_long_name_enters : %d\n", cfsnc_stat.long_name_enters); + len += sprintf(buffer+len, "cfsnc_long_name_lookups : %d\n", cfsnc_stat.long_name_lookups); + len += sprintf(buffer+len, "cfsnc_long_remove : %d\n", cfsnc_stat.long_remove); + len += sprintf(buffer+len, "cfsnc_lru_rm : %d\n", cfsnc_stat.lru_rm); + len += sprintf(buffer+len, "cfsnc_zapPfids : %d\n", cfsnc_stat.zapPfids); + len += sprintf(buffer+len, "cfsnc_zapFids : %d\n", cfsnc_stat.zapFids); + len += sprintf(buffer+len, "cfsnc_zapFile : %d\n", cfsnc_stat.zapFile); + len += sprintf(buffer+len, "cfsnc_zapUsers : %d\n", cfsnc_stat.zapUsers); + len += sprintf(buffer+len, "cfsnc_Flushes : %d\n", cfsnc_stat.Flushes); + len += sprintf(buffer+len, "cfsnc_SumLen : %d\n", cfsnc_stat.Sum_bucket_len); + len += sprintf(buffer+len, "cfsnc_Sum2Len : %d\n", cfsnc_stat.Sum2_bucket_len); + len += sprintf(buffer+len, "cfsnc_# 0 len : %d\n", cfsnc_stat.Num_zero_len); + len += sprintf(buffer+len, "cfsnc_MaxLen : %d\n", cfsnc_stat.Max_bucket_len); + len += sprintf(buffer+len, "cfsnc_SearchLen : %d\n", cfsnc_stat.Search_len); + begin = offset; + *start = buffer + begin; + len -= begin; + + if(len>length) + len = length; + if (len< 0) + len = 0; + return len; +} diff -u --recursive --new-file v2.1.75/linux/fs/ncpfs/sock.c linux/fs/ncpfs/sock.c --- v2.1.75/linux/fs/ncpfs/sock.c Tue Dec 2 09:49:40 1997 +++ linux/fs/ncpfs/sock.c Tue Dec 23 13:52:02 1997 @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #include @@ -124,12 +125,12 @@ What if we've blocked it ourselves? What about alarms? Why, in fact, are we mucking with the sigmask at all? -- r~ */ - if (current->sig->action[SIGINT - 1].sa_handler == SIG_DFL) + if (current->sig->action[SIGINT - 1].sa.sa_handler == SIG_DFL) mask |= sigmask(SIGINT); - if (current->sig->action[SIGQUIT - 1].sa_handler == SIG_DFL) + if (current->sig->action[SIGQUIT - 1].sa.sa_handler == SIG_DFL) mask |= sigmask(SIGQUIT); } - siginitmaskinv(¤t->blocked, mask); + siginitsetinv(¤t->blocked, mask); recalc_sigpending(current); spin_unlock_irqrestore(¤t->sigmask_lock, flags); @@ -278,7 +279,7 @@ } spin_lock_irqsave(¤t->sigmask_lock, flags); - current->blocked = old_mask; + current->blocked = old_set; recalc_sigpending(current); spin_unlock_irqrestore(¤t->sigmask_lock, flags); diff -u --recursive --new-file v2.1.75/linux/fs/nfs/dir.c linux/fs/nfs/dir.c --- v2.1.75/linux/fs/nfs/dir.c Sun Dec 21 22:36:16 1997 +++ linux/fs/nfs/dir.c Tue Dec 23 15:38:02 1997 @@ -522,34 +522,6 @@ } /* - * Attempt to patch up certain errors following a create or - * mkdir operation. We clear the original error if the new - * lookup succeeds and has the correct mode. - */ -static int nfs_fixup(struct inode *dir, struct dentry *dentry, int mode, - struct nfs_fh *fhandle, struct nfs_fattr *fattr, int error) -{ - int newerr; - -#ifdef NFS_PARANOIA -printk("nfs_fixup: %s/%s, error=%d, mode=%x\n", -dentry->d_parent->d_name.name, dentry->d_name.name, error, mode); -#endif - if (error == -EEXIST) { - newerr = nfs_proc_lookup(NFS_SERVER(dir), NFS_FH(dir), - dentry->d_name.name, fhandle, fattr); - if (!newerr) { -#ifdef NFS_PARANOIA -printk("nfs_fixup: lookup OK, got mode=%x, want mode=%x\n", fattr->mode, mode); -#endif - if ((fattr->mode & S_IFMT) == (mode & S_IFMT)) - error = 0; - } - } - return error; -} - -/* * Code common to create, mkdir, and mknod. */ static int nfs_instantiate(struct dentry *dentry, struct nfs_fh *fhandle, @@ -608,8 +580,6 @@ nfs_invalidate_dircache(dir); error = nfs_proc_create(NFS_SERVER(dir), NFS_FH(dir), dentry->d_name.name, &sattr, &fhandle, &fattr); - if (error) - error = nfs_fixup(dir, dentry, mode, &fhandle, &fattr, error); if (!error) error = nfs_instantiate(dentry, &fhandle, &fattr); if (error) @@ -648,8 +618,6 @@ nfs_invalidate_dircache(dir); error = nfs_proc_create(NFS_SERVER(dir), NFS_FH(dir), dentry->d_name.name, &sattr, &fhandle, &fattr); - if (error) - error = nfs_fixup(dir, dentry, mode, &fhandle, &fattr, error); if (!error) error = nfs_instantiate(dentry, &fhandle, &fattr); if (error) @@ -688,8 +656,6 @@ nfs_invalidate_dircache(dir); error = nfs_proc_mkdir(NFS_SERVER(dir), NFS_FH(dir), dentry->d_name.name, &sattr, &fhandle, &fattr); - if (error) - error = nfs_fixup(dir, dentry, mode, &fhandle, &fattr, error); if (!error) { /* * Some AIX servers reportedly fail to fill out the fattr. diff -u --recursive --new-file v2.1.75/linux/fs/nfsd/vfs.c linux/fs/nfsd/vfs.c --- v2.1.75/linux/fs/nfsd/vfs.c Sun Dec 21 16:17:44 1997 +++ linux/fs/nfsd/vfs.c Mon Dec 22 08:35:06 1997 @@ -105,7 +105,7 @@ int len, struct svc_fh *resfh) { struct svc_export *exp; - struct dentry *dparent; + struct dentry *dparent, *dchild; int err; dprintk("nfsd: nfsd_lookup(fh %p, %s)\n", SVCFH_DENTRY(fhp), name); @@ -118,34 +118,48 @@ dparent = fhp->fh_dentry; exp = fhp->fh_export; - /* Fast path... */ err = nfsd_permission(exp, dparent, MAY_EXEC); - if ((err == 0) && - !fs_off_limits(dparent->d_inode->i_sb) && - !nfsd_iscovered(dparent, exp)) { - struct dentry *dchild; - - /* Lookup the name, but don't follow links */ - dchild = lookup_dentry(name, dget(dparent), 0); - err = PTR_ERR(dchild); - if (IS_ERR(dchild)) - return nfserrno(-err); - - /* - * Note: we compose the filehandle now, but as the - * dentry may be negative, it may need to be updated. - */ - fh_compose(resfh, exp, dchild); - return (dchild->d_inode ? 0 : nfserr_noent); + if (err) + goto out; + err = nfserr_noent; + if (fs_off_limits(dparent->d_sb)) + goto out; + err = nfserr_acces; + if (nfsd_iscovered(dparent, exp)) + goto out; + + /* Lookup the name, but don't follow links */ + dchild = lookup_dentry(name, dget(dparent), 0); + if (IS_ERR(dchild)) + goto out_nfserr; + /* + * Make sure we haven't crossed a mount point ... + */ + if (dchild->d_sb != dparent->d_sb) { +#ifdef NFSD_PARANOIA +printk("nfsd_lookup: %s/%s crossed mount point!\n", dparent->d_name.name, name); +#endif + goto out_dput; } - /* Slow path... */ - if (fs_off_limits(dparent->d_inode->i_sb)) - return nfserr_noent; - if (nfsd_iscovered(dparent, exp)) - return nfserr_acces; + /* + * Note: we compose the filehandle now, but as the + * dentry may be negative, it may need to be updated. + */ + fh_compose(resfh, exp, dchild); + err = nfserr_noent; + if (dchild->d_inode) + err = 0; out: return err; + +out_nfserr: + err = nfserrno(-PTR_ERR(dchild)); + goto out; +out_dput: + dput(dchild); + err = nfserr_acces; + goto out; } /* diff -u --recursive --new-file v2.1.75/linux/fs/vfat/namei.c linux/fs/vfat/namei.c --- v2.1.75/linux/fs/vfat/namei.c Sun Dec 21 22:36:16 1997 +++ linux/fs/vfat/namei.c Tue Dec 23 11:38:08 1997 @@ -649,29 +649,55 @@ qname.len=totlen; res = vfat_find(dir, &qname, 0, 0, 0, &sinfo); } - i = 0; - while (res > -1) { - /* Create the next shortname to try */ - i++; - if (i == 10000000) return -EEXIST; - sprintf(buf, "%d", i); - sz = strlen(buf); - if (sz + 1 > spaces) { - baselen = baselen - (sz + 1 - spaces); - spaces = sz + 1; - } - - strncpy(msdos_name, base, baselen); - msdos_name[baselen] = '~'; - strcpy(&msdos_name[baselen+1], buf); - msdos_name[baselen+sz+1] = '.'; - strcpy(&msdos_name[baselen+sz+2], ext); - totlen = baselen + sz + 1 + extlen + (extlen > 0); + if (res > -1) { + /* + * Try to find a unique extension. This used to + * iterate through all possibilities sequentially, + * but that gave extremely bad performance. Windows + * only tries a few cases before using random + * values for part of the base. + */ + + if (2 > spaces) { + baselen = baselen - (2 - spaces); + spaces = 2; + } + msdos_name[baselen] = '~'; + msdos_name[baselen+2] = '.'; + strcpy(&msdos_name[baselen+3], ext); + totlen = baselen + 2 + extlen + (extlen > 0); qname.name=msdos_name; qname.len=totlen; - res = vfat_find(dir, &qname, 0, 0, 0, &sinfo); + for (i = 1; res > -1 && i < 10; i++) { + strncpy(msdos_name, base, baselen); + msdos_name[baselen+1] = i + '0'; + res = vfat_find(dir, &qname, 0, 0, 0, &sinfo); + } } + if (res > -1) { + i = jiffies & 0xffff; + sz = (jiffies >> 16) & 0x7; + if (6 > spaces) { + baselen = baselen - (6 - spaces); + spaces = 6; + } + msdos_name[baselen+4] = '~'; + msdos_name[baselen+5] = '1' + sz; + msdos_name[baselen+6] = '.'; + strcpy(&msdos_name[baselen+7], ext); + totlen = baselen + 6 + extlen + (extlen > 0); + qname.name=msdos_name; + qname.len=totlen; + while (res > -1) { + sprintf(buf, "%04x", i); + memcpy(&msdos_name[baselen], buf, 4); + msdos_name[12] = 0; + res = vfat_find(dir, &qname, 0, 0, 0, &sinfo); + i -= 11; + } + } + res = vfat_format_name(msdos_name, totlen, name_res, 1, utf8); return res; } @@ -1082,7 +1108,6 @@ sinfo_out->shortname_offset = offset - sizeof(struct msdos_dir_slot); sinfo_out->longname_offset = offset - sizeof(struct msdos_dir_slot) * slots; res = 0; - return 0; } else { res = -ENOENT; } @@ -1584,7 +1609,7 @@ /* Is this the same file, different case? */ if (new_inode != old_inode) { PRINTK(("vfat_rename 9\n")); - res = vfat_unlinkx(new_dir,new_dentry,1); + res = vfat_unlink(new_dir,new_dentry); PRINTK(("vfat_rename 10\n")); if (res < 0) goto rename_done; } diff -u --recursive --new-file v2.1.75/linux/include/asm-alpha/unistd.h linux/include/asm-alpha/unistd.h --- v2.1.75/linux/include/asm-alpha/unistd.h Mon Dec 1 12:04:14 1997 +++ linux/include/asm-alpha/unistd.h Mon Dec 22 09:58:21 1997 @@ -386,6 +386,12 @@ return sys_close(fd); } +extern off_t sys_lseek(int, off_t, int); +static inline off_t lseek(int fd, off_t off, int whense) +{ + return sys_lseek(fd, off, whense); +} + extern int sys_exit(int); static inline int _exit(int value) { @@ -406,22 +412,12 @@ return sys_read(fd, buf, nr); } -extern int do_execve(char *, char **, char **, struct pt_regs *); -extern void ret_from_sys_call(void); +extern int __kernel_execve(char *, char **, char **, struct pt_regs *); static inline int execve(char * file, char ** argvp, char ** envp) { - int i; struct pt_regs regs; - memset(®s, 0, sizeof(regs)); - i = do_execve(file, argvp, envp, ®s); - if (!i) { - __asm__ __volatile__("bis %0,%0,$30\n\t" - "bis %1,%1,$26\n\t" - "ret $31,($26),1\n\t" - : :"r" (®s), "r" (ret_from_sys_call)); - } - return -1; + return __kernel_execve(file, argvp, envp, ®s); } extern int sys_setsid(void); diff -u --recursive --new-file v2.1.75/linux/include/asm-i386/bugs.h linux/include/asm-i386/bugs.h --- v2.1.75/linux/include/asm-i386/bugs.h Sun Dec 21 22:36:16 1997 +++ linux/include/asm-i386/bugs.h Tue Dec 23 15:51:43 1997 @@ -224,8 +224,8 @@ __initfunc(static void check_bugs(void)) { -#ifndef __SMP__ identify_cpu(&boot_cpu_data); +#ifndef __SMP__ printk("CPU: "); print_cpu_info(&boot_cpu_data); #endif diff -u --recursive --new-file v2.1.75/linux/include/linux/coda_cache.h linux/include/linux/coda_cache.h --- v2.1.75/linux/include/linux/coda_cache.h Wed Dec 31 16:00:00 1969 +++ linux/include/linux/coda_cache.h Mon Dec 22 08:40:59 1997 @@ -0,0 +1,80 @@ +/* Coda filesystem -- Linux Minicache + * + * Copyright (C) 1989 - 1997 Carnegie Mellon University + * + * Carnegie Mellon University encourages users of this software to + * contribute improvements to the Coda project. Contact Peter Braam + * + */ + +#ifndef _CFSNC_HEADER_ +#define _CFSNC_HEADER_ + +/* + * Structure for an element in the Coda Credential Cache. + */ + +struct coda_cache { + struct list_head cc_cclist; /* list of all cache entries */ + struct list_head cc_cnlist; /* list of cache entries/cnode */ + int cc_mask; + struct coda_cred cc_cred; +}; + +void coda_ccinsert(struct coda_cache *el, struct super_block *sb); +void coda_cninsert(struct coda_cache *el, struct cnode *cnp); +void coda_ccremove(struct coda_cache *el); +void coda_cnremove(struct coda_cache *el); +void coda_cache_create(struct inode *inode, int mask); +struct coda_cache *coda_cache_find(struct inode *inode); +void coda_cache_enter(struct inode *inode, int mask); +void coda_cache_clear_cnp(struct cnode *cnp); +void coda_cache_clear_all(struct super_block *sb); +void coda_cache_clear_cred(struct super_block *sb, struct coda_cred *cred); +int coda_cache_check(struct inode *inode, int mask); +void coda_dentry_delete(struct dentry *dentry); +void coda_zapfid(struct ViceFid *fid, struct super_block *sb, int flag); + + +/* + * Structure to contain statistics on the cache usage + */ + +struct cfsnc_statistics { + unsigned hits; + unsigned misses; + unsigned enters; + unsigned dbl_enters; + unsigned long_name_enters; + unsigned long_name_lookups; + unsigned long_remove; + unsigned lru_rm; + unsigned zapPfids; + unsigned zapFids; + unsigned zapFile; + unsigned zapUsers; + unsigned Flushes; + unsigned Sum_bucket_len; + unsigned Sum2_bucket_len; + unsigned Max_bucket_len; + unsigned Num_zero_len; + unsigned Search_len; +}; + + +#define CFSNC_FIND ((u_long) 1) +#define CFSNC_REMOVE ((u_long) 2) +#define CFSNC_INIT ((u_long) 3) +#define CFSNC_ENTER ((u_long) 4) +#define CFSNC_LOOKUP ((u_long) 5) +#define CFSNC_ZAPPFID ((u_long) 6) +#define CFSNC_ZAPFID ((u_long) 7) +#define CFSNC_ZAPVNODE ((u_long) 8) +#define CFSNC_ZAPFILE ((u_long) 9) +#define CFSNC_PURGEUSER ((u_long) 10) +#define CFSNC_FLUSH ((u_long) 11) +#define CFSNC_PRINTCFSNC ((u_long) 12) +#define CFSNC_PRINTSTATS ((u_long) 13) +#define CFSNC_REPLACE ((u_long) 14) + +#endif _CFSNC_HEADER_ diff -u --recursive --new-file v2.1.75/linux/include/linux/coda_opstats.h linux/include/linux/coda_opstats.h --- v2.1.75/linux/include/linux/coda_opstats.h Sun Dec 21 22:36:17 1997 +++ linux/include/linux/coda_opstats.h Mon Dec 22 09:26:12 1997 @@ -1,52 +1,14 @@ -#ifndef _BLURB_ -#define _BLURB_ -/* - - Coda: an Experimental Distributed File System - Release 3.1 - - Copyright (c) 1987-1996 Carnegie Mellon University - All Rights Reserved - -Permission to use, copy, modify and distribute this software and its -documentation is hereby granted, provided that both the copyright -notice and this permission notice appear in all copies of the -software, derivative works or modified versions, and any portions -thereof, and that both notices appear in supporting documentation, and -that credit is given to Carnegie Mellon University in all documents -and publicity pertaining to direct or indirect use of this code or its -derivatives. - -CODA IS AN EXPERIMENTAL SOFTWARE SYSTEM AND IS KNOWN TO HAVE BUGS, -SOME OF WHICH MAY HAVE SERIOUS CONSEQUENCES. CARNEGIE MELLON ALLOWS -FREE USE OF THIS SOFTWARE IN ITS "AS IS" CONDITION. CARNEGIE MELLON -DISCLAIMS ANY LIABILITY OF ANY KIND FOR ANY DAMAGES WHATSOEVER -RESULTING DIRECTLY OR INDIRECTLY FROM THE USE OF THIS SOFTWARE OR OF -ANY DERIVATIVE WORK. - -Carnegie Mellon encourages users of this software to return any -improvements or extensions that they make, and to grant Carnegie -Mellon the rights to redistribute these changes without encumbrance. -*/ - -static char *rcsid = "$Header: /afs/cs/project/coda-src/cvs/coda/kernel-src/vfs/linux21/linux/coda_opstats.h,v 1.1 1997/12/02 05:35:02 braam Exp $"; -#endif /*_BLURB_*/ - /* - * operation stats: what the minicache can intercept that - * *isn't* seen by venus. These stats are kept to augment - * the stats maintained by the Volume-Session mechanism. + * Operation statistics for Coda. + * Copyright (C) 1997 Carnegie Mellon University + * + * Carnegie Mellon University encourages users of this software + * to contribute improvements to the Coda project. Contact Peter Braam + * . */ -/* vfsops: - * mount: not currently bounced to Venus - * umount: nope - * root: only first call, rest is cached. - * statfs: none (bogus) - * sync: none (bogus) - * vget: all - */ + #define CFS_MOUNT_STATS 0 #define CFS_UMOUNT_STATS 1 diff -u --recursive --new-file v2.1.75/linux/include/linux/fs.h linux/include/linux/fs.h --- v2.1.75/linux/include/linux/fs.h Sun Dec 21 16:17:45 1997 +++ linux/include/linux/fs.h Tue Dec 23 15:51:43 1997 @@ -775,7 +775,7 @@ extern int close_fp(struct file *); extern struct buffer_head * get_hash_table(kdev_t, int, int); extern struct buffer_head * getblk(kdev_t, int, int); -extern struct buffer_head *efind_buffer(kdev_t dev, int block, int size); +extern struct buffer_head * find_buffer(kdev_t dev, int block, int size); extern void ll_rw_block(int, int, struct buffer_head * bh[]); extern void ll_rw_page(int, kdev_t, unsigned long, char *); extern void ll_rw_swap_file(int, kdev_t, unsigned int *, int, char *); diff -u --recursive --new-file v2.1.75/linux/include/linux/if_ppp.h linux/include/linux/if_ppp.h --- v2.1.75/linux/include/linux/if_ppp.h Thu Apr 11 23:49:46 1996 +++ linux/include/linux/if_ppp.h Tue Dec 23 10:57:31 1997 @@ -21,7 +21,7 @@ */ /* - * ==FILEVERSION 960109== + * ==FILEVERSION 971223== * * NOTE TO MAINTAINERS: * If you modify this file at all, please set the above date. @@ -47,7 +47,7 @@ #define PPP_MTU 1500 /* Default MTU (size of Info field) */ #define PPP_MAXMRU 65000 /* Largest MRU we allow */ -#define PPP_VERSION "2.2.0" +#define PPP_VERSION "2.3.3" #define PPP_MAGIC 0x5002 /* Magic value for the ppp structure */ #define PROTO_IPX 0x002b /* protocol numbers */ #define PROTO_DNA_RT 0x0027 /* DNA Routing */ diff -u --recursive --new-file v2.1.75/linux/include/linux/if_pppvar.h linux/include/linux/if_pppvar.h --- v2.1.75/linux/include/linux/if_pppvar.h Thu Sep 4 17:07:31 1997 +++ linux/include/linux/if_pppvar.h Tue Dec 23 10:57:31 1997 @@ -1,4 +1,4 @@ -/* $Id: if_pppvar.h,v 1.4 1997/09/03 11:55:06 ecd Exp $ */ +/* From: if_pppvar.h,v 1.2 1995/06/12 11:36:51 paulus Exp */ /* * if_pppvar.h - private structures and declarations for PPP. * @@ -42,7 +42,7 @@ */ /* - * ==FILEVERSION 960302== + * ==FILEVERSION 971001== * * NOTE TO MAINTAINERS: * If you modify this file at all, please set the above date. @@ -79,7 +79,7 @@ /* =2, daemon write buffer */ /* =3, daemon read buffer */ __u16 fcs; /* Frame Check Sequence (CRC) */ - __u8 filler[4]; /* Extra space if needed */ + __u16 magic; /* Extra space if needed */ }; /* Given a pointer to the ppp_buffer then return base address of buffer */ @@ -91,6 +91,7 @@ struct ppp { __s32 magic; /* magic value for structure */ + struct ppp *next; /* unit with next index */ /* Bitmapped flag fields. */ unsigned long inuse; /* are we allocated? */ @@ -104,27 +105,26 @@ __u32 recv_async_map; /* 1 bit means that given control character is ignored on input*/ - __s32 mtu; /* maximum xmit frame size */ - __s32 mru; /* maximum receive frame size */ + __s32 mtu; /* maximum xmit frame size */ + __s32 mru; /* maximum receive frame size */ /* Information about the current tty data */ - __s32 line; /* PPP channel number */ - struct tty_struct *tty; /* ptr to TTY structure */ - __s32 bytes_sent; /* Bytes sent on frame */ - __s32 bytes_rcvd; /* Bytes recvd on frame */ - - /* Interface to the network layer */ - struct device *dev; /* easy for intr handling */ + __s32 line; /* PPP channel number */ + struct tty_struct *tty; /* ptr to TTY structure */ + struct tty_struct *backup_tty; /* TTY to use if tty gets closed */ + __s32 bytes_sent; /* Bytes sent on frame */ + __s32 bytes_rcvd; /* Bytes recvd on frame */ /* VJ Header compression data */ - struct slcompress *slcomp; /* for header compression */ + struct slcompress *slcomp; /* for header compression */ /* Transmission information */ struct ppp_buffer *xbuf; /* Buffer currently being sent */ struct ppp_buffer *s1buf; /* Pointer to daemon buffer */ struct ppp_buffer *s2buf; /* Pointer to device buffer */ - __u32 last_xmit; /* time of last transmission */ + unsigned long last_xmit; /* time of last transmission */ + unsigned long last_recv; /* time last packet received */ /* These are pointers to the malloc()ed frame buffers. These buffers are used while processing a packet. If a packet @@ -142,8 +142,7 @@ struct wait_queue *read_wait; /* queue for writing processes */ /* Statistic information */ - struct pppstat stats; /* statistic information */ - struct ppp_idle ddinfo; /* demand dial information */ + struct pppstat stats; /* statistic information */ /* PPP compression protocol information */ __u32 sc_bytessent; /* count of octets sent */ @@ -154,4 +153,7 @@ struct compressor *sc_rcomp; /* receive decompressor */ void *sc_rc_state; /* receive decompressor state */ __s32 sc_xfer; /* PID of reserved PPP table */ + char name[8]; + struct device dev; /* net device structure */ + struct enet_statistics estats; /* more detailed stats */ }; diff -u --recursive --new-file v2.1.75/linux/include/linux/pci.h linux/include/linux/pci.h --- v2.1.75/linux/include/linux/pci.h Sun Dec 21 22:36:17 1997 +++ linux/include/linux/pci.h Tue Dec 23 14:37:32 1997 @@ -241,13 +241,14 @@ #define PCI_DEVICE_ID_NCR_53C895 0x000c #define PCI_DEVICE_ID_NCR_53C885 0x000d #define PCI_DEVICE_ID_NCR_53C875 0x000f -#define PCI_DEVICE_ID_NCR_53C876 0x008f +#define PCI_DEVICE_ID_NCR_53C875J 0x008f #define PCI_VENDOR_ID_ATI 0x1002 #define PCI_DEVICE_ID_ATI_68800 0x4158 #define PCI_DEVICE_ID_ATI_215CT222 0x4354 #define PCI_DEVICE_ID_ATI_210888CX 0x4358 #define PCI_DEVICE_ID_ATI_215GB 0x4742 +#define PCI_DEVICE_ID_ATI_215GD 0x4744 #define PCI_DEVICE_ID_ATI_215GP 0x4750 #define PCI_DEVICE_ID_ATI_215GT 0x4754 #define PCI_DEVICE_ID_ATI_215GTB 0x4755 @@ -372,9 +373,6 @@ #define PCI_DEVICE_ID_HP_J2585A 0x1030 #define PCI_DEVICE_ID_HP_J2585B 0x1031 -#define PCI_VENDOR_ID_HOLTEK 0x9412 -#define PCI_DEVICE_ID_HOLTEK_6565 0x6565 - #define PCI_VENDOR_ID_PCTECH 0x1042 #define PCI_DEVICE_ID_PCTECH_RZ1000 0x1000 #define PCI_DEVICE_ID_PCTECH_RZ1001 0x1001 @@ -456,6 +454,16 @@ #define PCI_DEVICE_ID_QLOGIC_ISP1020 0x1020 #define PCI_DEVICE_ID_QLOGIC_ISP1022 0x1022 +#define PCI_VENDOR_ID_CYRIX 0x1078 +#define PCI_DEVICE_ID_CYRIX_5510 0x0000 +#define PCI_DEVICE_ID_CYRIX_PCI_MASTER 0x0001 +#define PCI_DEVICE_ID_CYRIX_5520 0x0002 +#define PCI_DEVICE_ID_CYRIX_5530_LEGACY 0x0100 +#define PCI_DEVICE_ID_CYRIX_5530_SMI 0x0101 +#define PCI_DEVICE_ID_CYRIX_5530_IDE 0x0102 +#define PCI_DEVICE_ID_CYRIX_5530_AUDIO 0x0103 +#define PCI_DEVICE_ID_CYRIX_5530_VIDEO 0x0104 + #define PCI_VENDOR_ID_LEADTEK 0x107d #define PCI_DEVICE_ID_LEADTEK_805 0x0000 @@ -565,6 +573,7 @@ #define PCI_VENDOR_ID_AMCC 0x10e8 #define PCI_DEVICE_ID_AMCC_MYRINET 0x8043 #define PCI_DEVICE_ID_AMCC_S5933 0x807d +#define PCI_DEVICE_ID_AMCC_S5933_HEPC3 0x809c #define PCI_VENDOR_ID_INTERG 0x10ea #define PCI_DEVICE_ID_INTERG_1680 0x1680 @@ -662,6 +671,7 @@ #define PCI_VENDOR_ID_RENDITION 0x1163 #define PCI_DEVICE_ID_RENDITION_VERITE 0x0001 +#define PCI_DEVICE_ID_RENDITION_VERITE2100 0x2000 #define PCI_VENDOR_ID_TOSHIBA 0x1179 #define PCI_DEVICE_ID_TOSHIBA_601 0x0601 @@ -716,6 +726,11 @@ #define PCI_VENDOR_ID_3DFX 0x121a #define PCI_DEVICE_ID_3DFX_VOODOO 0x0001 +#define PCI_VENDOR_ID_STALLION 0x124d +#define PCI_DEVICE_ID_STALLION_ECHPCI832 0x0000 +#define PCI_DEVICE_ID_STALLION_ECHPCI864 0x0002 +#define PCI_DEVICE_ID_STALLION_EIOPCI 0x0003 + #define PCI_VENDOR_ID_SIGMADES 0x1236 #define PCI_DEVICE_ID_SIGMADES_6425 0x6401 @@ -772,6 +787,9 @@ #define PCI_DEVICE_ID_S3_PLATO_PXG 0x8902 #define PCI_DEVICE_ID_S3_ViRGE_DXGX 0x8a01 #define PCI_DEVICE_ID_S3_ViRGE_GX2 0x8a10 +#define PCI_DEVICE_ID_S3_ViRGE_MX 0x8c01 +#define PCI_DEVICE_ID_S3_ViRGE_MXP 0x8c02 +#define PCI_DEVICE_ID_S3_ViRGE_MXPMV 0x8c03 #define PCI_VENDOR_ID_INTEL 0x8086 #define PCI_DEVICE_ID_INTEL_82375 0x0482 @@ -829,6 +847,9 @@ #define PCI_VENDOR_ID_ATRONICS 0x907f #define PCI_DEVICE_ID_ATRONICS_2015 0x2015 + +#define PCI_VENDOR_ID_HOLTEK 0x9412 +#define PCI_DEVICE_ID_HOLTEK_6565 0x6565 #define PCI_VENDOR_ID_ARK 0xedd8 #define PCI_DEVICE_ID_ARK_STING 0xa091 diff -u --recursive --new-file v2.1.75/linux/include/linux/poll.h linux/include/linux/poll.h --- v2.1.75/linux/include/linux/poll.h Wed Dec 10 11:12:46 1997 +++ linux/include/linux/poll.h Tue Dec 23 15:52:13 1997 @@ -1,4 +1,5 @@ #ifndef _LINUX_POLL_H +#define _LINUX_POLL_H #include diff -u --recursive --new-file v2.1.75/linux/include/linux/ppp-comp.h linux/include/linux/ppp-comp.h --- v2.1.75/linux/include/linux/ppp-comp.h Sat Nov 29 11:25:12 1997 +++ linux/include/linux/ppp-comp.h Tue Dec 23 10:57:31 1997 @@ -28,7 +28,7 @@ */ /* - * ==FILEVERSION 970501== + * ==FILEVERSION 971024== * * NOTE TO MAINTAINERS: * If you modify this file at all, please set the above date. @@ -120,9 +120,8 @@ * Don't you just lurve software patents. */ -#define DECOMP_OK 0 /* no error occured */ -#define DECOMP_ERROR 1 /* error detected before decomp. */ -#define DECOMP_FATALERROR 2 /* error detected after decomp. */ +#define DECOMP_ERROR -1 /* error detected before decomp. */ +#define DECOMP_FATALERROR -2 /* error detected after decomp. */ /* * CCP codes. diff -u --recursive --new-file v2.1.75/linux/kernel/ksyms.c linux/kernel/ksyms.c --- v2.1.75/linux/kernel/ksyms.c Sun Dec 21 22:36:17 1997 +++ linux/kernel/ksyms.c Mon Dec 22 14:14:37 1997 @@ -238,7 +238,7 @@ EXPORT_SYMBOL(unplug_device); EXPORT_SYMBOL(make_request); EXPORT_SYMBOL(tq_disk); -EXPORT_SYMBOL(efind_buffer); +EXPORT_SYMBOL(find_buffer); EXPORT_SYMBOL(init_buffer); EXPORT_SYMBOL(max_sectors); EXPORT_SYMBOL(max_readahead); diff -u --recursive --new-file v2.1.75/linux/mm/filemap.c linux/mm/filemap.c --- v2.1.75/linux/mm/filemap.c Sun Dec 21 22:36:17 1997 +++ linux/mm/filemap.c Tue Dec 23 13:03:01 1997 @@ -299,18 +299,20 @@ */ void __wait_on_page(struct page *page) { - struct wait_queue wait = { current, NULL }; + struct task_struct *tsk = current; + struct wait_queue wait; + wait.task = tsk; add_wait_queue(&page->wait, &wait); repeat: + tsk->state = TASK_UNINTERRUPTIBLE; run_task_queue(&tq_disk); - current->state = TASK_UNINTERRUPTIBLE; if (PageLocked(page)) { schedule(); goto repeat; } + tsk->state = TASK_RUNNING; remove_wait_queue(&page->wait, &wait); - current->state = TASK_RUNNING; } #if 0 diff -u --recursive --new-file v2.1.75/linux/mm/vmscan.c linux/mm/vmscan.c --- v2.1.75/linux/mm/vmscan.c Mon Dec 1 12:04:15 1997 +++ linux/mm/vmscan.c Tue Dec 23 13:31:49 1997 @@ -99,8 +99,6 @@ if (vma->vm_ops->swapout(vma, address - vma->vm_start + vma->vm_offset, page_table)) kill_proc(pid, SIGBUS, 1); } else { - if (atomic_read(&page_map->count) != 1) - return 0; if (!(entry = get_swap_page())) return 0; vma->vm_mm->rss--; diff -u --recursive --new-file v2.1.75/linux/net/802/Makefile linux/net/802/Makefile --- v2.1.75/linux/net/802/Makefile Sat Nov 29 11:25:12 1997 +++ linux/net/802/Makefile Tue Dec 23 13:52:02 1997 @@ -17,7 +17,8 @@ ifeq ($(CONFIG_LLC),y) SUB_DIRS += transit O_OBJS += llc_sendpdu.o llc_utility.o cl2llc.o -OX_OBJS += llc_macinit.o p8022.o psnap.o p8022tr.o +OX_OBJS += llc_macinit.o +SNAP = y endif ifdef CONFIG_TR @@ -29,14 +30,17 @@ endif ifdef CONFIG_IPX -OX_OBJS += p8022.o psnap.o p8022tr.o + SNAP=y endif ifdef CONFIG_ATALK -ifndef CONFIG_IPX -OX_OBJS += p8022.o psnap.o p8022tr.o + SNAP=y endif + +ifeq ($(SNAP),y) +OX_OBJS += p8022.o psnap.o p8022tr.o endif + include $(TOPDIR)/Rules.make diff -u --recursive --new-file v2.1.75/linux/net/Config.in linux/net/Config.in --- v2.1.75/linux/net/Config.in Sun Dec 21 22:36:17 1997 +++ linux/net/Config.in Tue Dec 23 13:52:02 1997 @@ -10,11 +10,6 @@ tristate 'Netlink device emulation' CONFIG_NETLINK_DEV fi bool 'Network firewalls' CONFIG_FIREWALL -if [ "$CONFIG_FIREWALL" = "y" ]; then - if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then - bool 'Socket Security API Support (EXPERIMENTAL)' CONFIG_NET_SECURITY - fi -fi bool 'Network aliasing' CONFIG_NET_ALIAS bool 'Socket Filtering' CONFIG_FILTER tristate 'Unix domain sockets' CONFIG_UNIX diff -u --recursive --new-file v2.1.75/linux/net/core/dev.c linux/net/core/dev.c --- v2.1.75/linux/net/core/dev.c Wed Dec 10 11:12:46 1997 +++ linux/net/core/dev.c Tue Dec 23 14:49:37 1997 @@ -1127,7 +1127,7 @@ if (dev->flags^old_flags) { dev_mc_upload(dev); printk(KERN_INFO "device %s %s promiscuous mode\n", - dev->name, (dev->flags&IFF_PROMISC) ? "entered" : "leaved"); + dev->name, (dev->flags&IFF_PROMISC) ? "entered" : "left"); } } diff -u --recursive --new-file v2.1.75/linux/net/sunrpc/sched.c linux/net/sunrpc/sched.c --- v2.1.75/linux/net/sunrpc/sched.c Sun Dec 21 22:36:18 1997 +++ linux/net/sunrpc/sched.c Mon Dec 22 15:22:11 1997 @@ -92,7 +92,8 @@ } /* - * Remove request from queue + * Remove request from queue. + * Note: must be called with interrupts disabled. */ void rpc_remove_wait_queue(struct rpc_task *task) @@ -149,6 +150,9 @@ /* * Make an RPC task runnable. + * + * Note: If the task is ASYNC, this must be called with + * interrupts disabled to protect the wait queue operation. */ static inline void rpc_make_runnable(struct rpc_task *task) @@ -687,20 +691,26 @@ { struct rpc_task *task; - if (!(task = rpc_new_task(clnt, NULL, RPC_TASK_ASYNC|RPC_TASK_CHILD))) { - parent->tk_status = -ENOMEM; - return NULL; - } + task = rpc_new_task(clnt, NULL, RPC_TASK_ASYNC | RPC_TASK_CHILD); + if (!task) + goto fail; task->tk_exit = rpc_child_exit; task->tk_calldata = parent; - return task; + +fail: + parent->tk_status = -ENOMEM; + return NULL; } void rpc_run_child(struct rpc_task *task, struct rpc_task *child, rpc_action func) { + unsigned long oldflags; + + save_flags(oldflags); cli(); rpc_make_runnable(child); + restore_flags(oldflags); rpc_sleep_on(&childq, task, func, NULL); } diff -u --recursive --new-file v2.1.75/linux/scripts/Makefile linux/scripts/Makefile --- v2.1.75/linux/scripts/Makefile Fri Jun 7 01:58:11 1996 +++ linux/scripts/Makefile Tue Dec 23 13:52:02 1997 @@ -2,29 +2,21 @@ HEADER=header.tk TAIL=tail.tk -# We allow the Makefile in drivers/sound to decide when to rebuild its -# files, rather than trying to second-guess it like we did before. -# -soundscript: - make -C ${TOPDIR}/drivers/sound mkscript - @echo +# Previous versions always remade kconfig.tk because they always depended +# on soundscript. This runs fairly fast, and I can't find all the +# Config.in files to depend on anyways. So I'll force it to remake. -# There is probably a better way to decide when to rebuild kconfig.tk; this -# one won't catch every last change to the various Config.in files. However, -# the reliance on ${TOPDIR}/Makefile makes sure we at least rebuild when the -# kernel version number changes. -# -kconfig.tk: soundscript ${TOPDIR}/Makefile ${TOPDIR}/arch/${ARCH}/config.in \ +kconfig.tk: dummy + +kconfig.tk: ${TOPDIR}/Makefile ${TOPDIR}/arch/${ARCH}/config.in \ tkparse ${HEADER} ${TAIL} - ./tkparse < ../arch/${ARCH}/config.in > kconfig.tmp @if [ -f /usr/local/bin/wish ]; then \ echo '#!'"/usr/local/bin/wish -f" > kconfig.tk; \ else \ echo '#!'"/usr/bin/wish -f" > kconfig.tk; \ fi cat ${HEADER} >> ./kconfig.tk - cat kconfig.tmp >> kconfig.tk - rm -f kconfig.tmp + ./tkparse < ../arch/${ARCH}/config.in >> kconfig.tk echo "set defaults \"arch/${ARCH}/defconfig\"" >> kconfig.tk cat ${TAIL} >> kconfig.tk chmod 755 kconfig.tk diff -u --recursive --new-file v2.1.75/linux/scripts/Menuconfig linux/scripts/Menuconfig --- v2.1.75/linux/scripts/Menuconfig Sun Dec 21 22:36:18 1997 +++ linux/scripts/Menuconfig Tue Dec 23 13:52:02 1997 @@ -24,10 +24,14 @@ # 070497 Bernhard Kaindl (bkaindl@netway.at) - get default values for # new bool, tristate and dep_tristate parameters from the defconfig file. # new configuration parameters are marked with '(NEW)' as in make config. +# # 180697 Bernhard Kaindl (bkaindl@netway.at) - added the needed support # for string options. They are handled like the int and hex options. +# # 081297 Pavel Machek (pavel@atrey.karlin.mff.cuni.cz) - better error # handling +# +# 101297 Michael Chastain (mec@shout.net) - remove sound driver cruft. #---------------------------------------------------------------------------- @@ -326,23 +330,6 @@ } # -# Create a menu entry to handle the traditional sound configuration. -# -function soundcfg () { - echo -ne "'l_soundcfg' "\ - "'Old configuration script "\ - "(For: SM Wave, PSS & AudioTrix Pro) -->' " >>MCmenu -} - -# -# Startup the traditional sound configuration program. -# -function l_soundcfg () { - clear - $MAKE -C drivers/sound config -} - -# # Handle a boolean (Yes/No) option. # function l_bool () { @@ -629,11 +616,6 @@ printf("") >>menu } else if ($1 == "source") { - # Yuk! Blah! Phooey! - if ($2 ~ "drivers/sound") { - printf("soundcfg\n") >>menu - } - parser($2,menu) } else { @@ -662,9 +644,6 @@ printf("") >>menu } else if ($1 == "source") { - if ($2 ~ "drivers/sound") { - printf("soundcfg\n") >>menu - } parser($2,menu) } else { @@ -1121,25 +1100,11 @@ echo " */" >>$CONFIG_H echo "#define AUTOCONF_INCLUDED" >> $CONFIG_H - MAKE=: #To prevent sound Makefile from running. - echo -n "." if . $CONFIG_IN >>.menuconfig.log 2>&1 then if [ "$DEF_CONFIG" = ".config" ] then - # - # Create the sound driver's config files for cards - # Which are compatible with the new config method. - # - if [ "_$CONFIG_TRIX" != "_y" -a\ - "_$CONFIG_PSS" != "_y" -a\ - "_$CONFIG_SMWAVE" != "_y" ] - then - echo -n ", sound..." - make -C drivers/sound kernelconfig >>.menuconfig.log 2>&1 - fi - mv $CONFIG_H $DEF_CONFIG_H fi @@ -1231,7 +1196,7 @@ backtitle="Linux Kernel v$kernel_version Configuration" -trap "cleanup ; rm -f .menuconfig ; exit 1" 1 2 15 +trap "cleanup ; exit 1" 1 2 15 # @@ -1260,32 +1225,6 @@ >.menuconfig.log echo -n "Preparing configuration scripts: version" - -# -# Check kernel version of previous menuconfig build. -# If it's different then we should tell the sound driver -# to rebuild its Config.in file. -# -rebuildsound=TRUE -if [ -e .menuconfig ] -then - read x <.menuconfig - if [ "$x" = "# $kernel_version" ] - then - rebuildsound= - fi -fi - -if [ "$rebuildsound" ] -then - echo -n ", sound" - # Activate the Linux compatible sound configuration. - # This may not work for all sound cards. (See sound docs) - # - make -C drivers/sound mkscript kernelconfig >>.menuconfig.log 2>&1 - - echo "# $kernel_version" >.menuconfig -fi # Load the functions used by the config.in files. echo -n ", functions" diff -u --recursive --new-file v2.1.75/linux/scripts/header.tk linux/scripts/header.tk --- v2.1.75/linux/scripts/header.tk Mon Jun 16 16:36:02 1997 +++ linux/scripts/header.tk Tue Dec 23 13:52:02 1997 @@ -50,9 +50,6 @@ # Not used at the moment, but this runs a command in a subprocess and # displays the result in a window with a scrollbar. # -# For now, we just do external "make" commands to stdout with do_make, so -# this function is never called. -# proc do_cmd { w command } { catch {destroy $w} toplevel $w -class Dialog @@ -209,7 +206,7 @@ set cmd "global $var; set $var $value" eval $cmd } - if [regexp {([0-9A-Za-z_]+)="([0-9A-Za-z]+)"} $line foo var value] { + if [regexp {([0-9A-Za-z_]+)="([^"]*)"} $line foo var value] { set cmd "global $var; set $var $value" eval $cmd } @@ -349,11 +346,6 @@ #nothing done for comments now. } -proc do_make { command } { - exec sh -c $command <@stdin >@stdout 2>@stderr -# do_cmd .make_window "sh -c $command" -} - proc dohelp {w var } { catch {destroy $w} toplevel $w -class Dialog @@ -441,15 +433,6 @@ set winx [expr [winfo x .]+30]; set winy [expr [winfo y .]+30] wm geometry $w +$winx+$winy -} - -proc check_sound_config { num } { -#nothing for now. -} - -proc do_sound {w mnum line} { - message $w.x$line -width 400 -aspect 300 -text "Note: The sound drivers cannot as of yet be configured via the X-based interface" -relief raised - pack $w.x$line -side top -pady 10 } # diff -u --recursive --new-file v2.1.75/linux/scripts/tkcond.c linux/scripts/tkcond.c --- v2.1.75/linux/scripts/tkcond.c Sun Dec 21 22:36:18 1997 +++ linux/scripts/tkcond.c Tue Dec 23 13:52:02 1997 @@ -361,7 +361,6 @@ case tok_hex: case tok_string: case tok_choice: - case tok_make: /* * We need to duplicate the chain of conditions and attach them to * this token. diff -u --recursive --new-file v2.1.75/linux/scripts/tkgen.c linux/scripts/tkgen.c --- v2.1.75/linux/scripts/tkgen.c Mon Jun 16 16:36:02 1997 +++ linux/scripts/tkgen.c Tue Dec 23 13:52:02 1997 @@ -50,6 +50,9 @@ * Avery Pennarun - Reduced flicker when creating windows, even with "update * idletasks" hack. * + * 1997 12 08 + * Michael Chastain - Remove sound driver special cases. + * * TO DO: * - clean up - there are useless ifdef's everywhere. * - better comments throughout - C code generating tcl is really cryptic. @@ -492,9 +495,6 @@ printf("} then { write_string $cfg $autocfg %s $%s $notmod }\n", item->optionname, item->optionname); break; - case tok_make: - printf("} then { do_make {%s} }\n",item->value); - break; case tok_choose: case tok_choice: fprintf(stderr,"Fixme\n"); @@ -893,25 +893,6 @@ */ end_proc(menu_num); -#ifdef ERIC_DONT_DEF - /* - * Generate the code for configuring the sound driver. Right now this - * cannot be done from the X script, but we insert the menu anyways. - */ - start_proc("Configure sound driver", ++menu_num, TRUE); -#if 0 - printf("\tdo_make -C drivers/sound config\n"); - printf("\techo check_sound_config %d\n",menu_num); -#endif - printf("\tlabel $w.config.f.m0 -bitmap error\n"); - printf("\tmessage $w.config.f.m1 -width 400 -aspect 300 -text \"The sound drivers cannot as of yet be configured via the X-based interface\" -relief raised\n"); - printf("\tpack $w.config.f.m0 $w.config.f.m1 -side top -pady 10 -expand on\n"); - /* - * Close out the last menu. - */ - end_proc(menu_num); -#endif - /* * The top level menu also needs an update function. When we exit a * submenu, we may need to disable one or more of the submenus on @@ -1018,7 +999,6 @@ printf("\tglobal %s\n", cfg->optionname); } /* fall through */ - case tok_make: case tok_comment: if (cfg->cond != NULL ) generate_if_for_outfile(cfg, cfg->cond); @@ -1077,10 +1057,6 @@ printf("\twrite_string $cfg $autocfg %s $%s $notmod\n", cfg->optionname, cfg->optionname); - } - else if (cfg->tok == tok_make ) - { - printf("\tdo_make {%s}\n",cfg->value); } else { diff -u --recursive --new-file v2.1.75/linux/scripts/tkparse.c linux/scripts/tkparse.c --- v2.1.75/linux/scripts/tkparse.c Mon Jun 16 16:36:02 1997 +++ linux/scripts/tkparse.c Tue Dec 23 13:52:02 1997 @@ -326,10 +326,6 @@ tok = tok_menuoption; pnt += 15; } - else if (strncmp(pnt, "$MAKE ", 6) == 0) - { - tok = tok_make; - } else if (strncmp(pnt, "comment", 7) == 0) { tok = tok_comment; @@ -512,9 +508,6 @@ { pnt = get_qstring(pnt, &kcfg->label); } - break; - case tok_make: - kcfg->value=strdup(pnt); break; case tok_else: case tok_fi: diff -u --recursive --new-file v2.1.75/linux/scripts/tkparse.h linux/scripts/tkparse.h --- v2.1.75/linux/scripts/tkparse.h Mon Jun 16 16:36:02 1997 +++ linux/scripts/tkparse.h Tue Dec 23 13:52:02 1997 @@ -13,7 +13,6 @@ tok_int, tok_hex, tok_string, - tok_make, tok_define, tok_choose, tok_choice,