From 24747a70c81a376046a1ad00422142a6bb8ed7e9 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Fri, 23 Nov 2007 15:10:43 -0500 Subject: [PATCH] Import 1.3.78 --- CREDITS | 10 + Documentation/Configure.help | 20 + Documentation/cdrom/optcd | 2 +- Documentation/devices.tex | 2 +- Documentation/devices.txt | 2 +- Documentation/framerelay.txt | 33 + MAGIC | 1 + MAINTAINERS | 14 + Makefile | 2 +- arch/alpha/config.in | 5 +- arch/alpha/defconfig | 2 +- arch/alpha/kernel/time.c | 58 +- arch/alpha/math-emu/fp-emul.c | 2 +- arch/alpha/math-emu/ieee-math.c | 14 +- arch/i386/boot/setup.S | 6 +- arch/i386/defconfig | 2 + arch/i386/kernel/entry.S | 1 + arch/i386/kernel/smp.c | 146 ++- arch/i386/mm/init.c | 16 +- drivers/block/floppy.c | 2 +- drivers/block/ide.c | 2 + drivers/block/ll_rw_blk.c | 47 +- drivers/block/loop.c | 24 +- drivers/block/md.c | 45 +- drivers/cdrom/cdu31a.c | 2 +- drivers/cdrom/mcdx.c | 12 +- drivers/cdrom/optcd_isp16.h | 337 ----- drivers/char/cyclades.c | 2 +- drivers/char/lp.c | 2 + drivers/char/pty.c | 10 +- drivers/char/tga.c | 1 - drivers/net/Config.in | 8 + drivers/net/Makefile | 21 + drivers/net/Space.c | 18 +- drivers/net/bsd_comp.c | 8 +- drivers/net/de4x5.c | 26 +- drivers/net/dlci.c | 609 +++++++++ drivers/net/ibmtr.c | 2144 ++++++++++++++++--------------- drivers/net/ibmtr.h | 423 +++--- drivers/net/loopback.c | 8 +- drivers/net/net_init.c | 2 +- drivers/net/new_tunnel.c | 20 +- drivers/net/sdla.c | 1639 +++++++++++++++++++++++ drivers/pci/pci.c | 19 +- drivers/scsi/NCR5380.c | 2 +- drivers/scsi/README.g_NCR5380 | 2 +- drivers/scsi/fdomain.c | 3 + drivers/scsi/scsi.c | 5 +- drivers/scsi/scsi.h | 2 +- drivers/scsi/sd_ioctl.c | 1 + drivers/sound/.version | 2 +- drivers/sound/CHANGELOG | 4 +- drivers/sound/Makefile | 2 + drivers/sound/Readme | 4 +- drivers/sound/Readme.cards | 6 +- drivers/sound/ad1848.c | 16 +- drivers/sound/audio.c | 24 +- drivers/sound/configure.c | 237 ++-- drivers/sound/dev_table.h | 6 +- drivers/sound/dmabuf.c | 14 +- drivers/sound/gus_wave.c | 4 +- drivers/sound/mad16.c | 144 ++- drivers/sound/midibuf.c | 2 + drivers/sound/sb16_dsp.c | 8 +- drivers/sound/sb_dsp.c | 10 +- drivers/sound/sequencer.c | 4 +- drivers/sound/sound_config.h | 1 + drivers/sound/sound_switch.c | 9 +- drivers/sound/soundcard.c | 14 +- drivers/sound/soundvers.h | 2 +- drivers/sound/sscape.c | 2 +- fs/binfmt_script.c | 15 +- fs/dcache.c | 41 +- fs/isofs/inode.c | 36 +- fs/ncpfs/ioctl.c | 30 +- fs/ncpfs/ncplib_kernel.c | 27 +- fs/nfs/inode.c | 4 +- fs/super.c | 7 + fs/umsdos/ioctl.c | 5 +- include/asm-alpha/apecs.h | 82 +- include/asm-alpha/atomic.h | 9 +- include/asm-alpha/ioctl.h | 4 +- include/asm-alpha/ioctls.h | 102 ++ include/asm-alpha/param.h | 14 +- include/asm-alpha/posix_types.h | 94 ++ include/asm-alpha/socket.h | 11 +- include/asm-alpha/sockios.h | 15 + include/asm-alpha/statfs.h | 12 +- include/asm-alpha/termbits.h | 176 +++ include/asm-alpha/termios.h | 285 +--- include/asm-alpha/types.h | 93 +- include/asm-i386/ioctls.h | 74 ++ include/asm-i386/posix_types.h | 51 + include/asm-i386/smp.h | 3 +- include/asm-i386/socket.h | 8 +- include/asm-i386/sockios.h | 12 + include/asm-i386/string.h | 4 + include/asm-i386/termbits.h | 159 +++ include/asm-i386/termios.h | 220 +--- include/asm-i386/types.h | 59 - include/asm-i386/unistd.h | 1 + include/linux/atalk.h | 4 + include/linux/binfmts.h | 1 + include/linux/blk.h | 4 +- include/linux/blkdev.h | 4 + include/linux/fs.h | 1 + include/linux/if_arp.h | 26 +- include/linux/if_ether.h | 78 +- include/linux/if_frad.h | 168 +++ include/linux/if_tr.h | 46 +- include/linux/kd.h | 28 +- include/linux/kerneld.h | 1 + include/linux/loop.h | 5 + include/linux/mcdx.h | 2 +- include/linux/ncp_fs.h | 10 +- include/linux/net.h | 1 + include/linux/netdevice.h | 2 + include/linux/optcd.h | 2 +- include/linux/pci.h | 31 +- include/linux/posix_types.h | 59 + include/linux/sched.h | 4 +- include/linux/sdla.h | 327 +++++ include/linux/smp.h | 2 - include/linux/socket.h | 3 + include/linux/sockios.h | 2 + include/linux/tty.h | 15 +- include/linux/types.h | 118 +- include/linux/vt.h | 24 +- include/net/af_unix.h | 8 +- include/net/gc.h | 46 + include/net/ipx.h | 1 + include/net/p8022.h | 7 +- include/net/psnap.h | 7 +- include/net/sock.h | 17 +- init/main.c | 31 +- kernel/exit.c | 4 +- kernel/fork.c | 2 +- kernel/ksyms.c | 122 +- kernel/module.c | 2 +- kernel/sched.c | 17 +- kernel/sys.c | 7 +- mm/Makefile | 2 +- mm/memory.c | 25 +- mm/mmap.c | 26 +- mm/mremap.c | 219 ++++ net/802/Makefile | 4 +- net/802/p8022.c | 31 + net/802/p8023.c | 6 + net/802/psnap.c | 37 + net/Config.in | 6 +- net/Makefile | 13 + net/appletalk/Makefile | 1 + net/appletalk/aarp.c | 48 +- net/appletalk/ddp.c | 111 +- net/ax25/af_ax25.c | 6 +- net/core/dev.c | 19 +- net/ethernet/pe2.c | 5 + net/ipv4/Config.in | 3 + net/ipv4/af_inet.c | 2 +- net/ipv4/arp.c | 227 +++- net/ipv4/ip_alias.c | 127 +- net/ipv4/ip_forward.c | 7 +- net/ipv4/ip_fragment.c | 2 +- net/ipv4/ip_input.c | 22 +- net/ipv4/proc.c | 10 +- net/ipx/Makefile | 1 + net/ipx/af_ipx.c | 160 ++- net/netrom/af_netrom.c | 4 +- net/netrom/nr_dev.c | 2 +- net/netsyms.c | 173 +++ net/protocols.c | 11 +- net/socket.c | 52 +- net/unix/af_unix.c | 28 +- net/unix/garbage.c | 250 +++- scripts/Configure | 6 +- scripts/Menuconfig | 546 +++++--- scripts/README.Menuconfig | 16 + scripts/lxdialog/inputbox.c | 21 +- scripts/lxdialog/menubox.c | 6 +- 179 files changed, 7904 insertions(+), 3522 deletions(-) create mode 100644 Documentation/framerelay.txt delete mode 100644 drivers/cdrom/optcd_isp16.h create mode 100644 drivers/net/dlci.c create mode 100644 drivers/net/sdla.c create mode 100644 include/asm-alpha/ioctls.h create mode 100644 include/asm-alpha/posix_types.h create mode 100644 include/asm-alpha/sockios.h create mode 100644 include/asm-alpha/termbits.h create mode 100644 include/asm-i386/ioctls.h create mode 100644 include/asm-i386/posix_types.h create mode 100644 include/asm-i386/sockios.h create mode 100644 include/asm-i386/termbits.h create mode 100644 include/linux/if_frad.h create mode 100644 include/linux/posix_types.h create mode 100644 include/linux/sdla.h create mode 100644 include/net/gc.h create mode 100644 mm/mremap.c create mode 100644 net/netsyms.c diff --git a/CREDITS b/CREDITS index 8a9c36f2f994..72202f8afff4 100644 --- a/CREDITS +++ b/CREDITS @@ -298,6 +298,7 @@ S: USA N: Bjorn Ekwall E: bj0rn@blox.se +W: http://www.pi.se/blox/ D: Extended support for loadable modules D: D-Link pocket adapter drivers S: Myrstuguv. 83 @@ -736,6 +737,15 @@ D: XF86_Mach8 D: XF86_8514 D: cfdisk (curses based disk partitioning program) +N: Mike McLagan +E: mike.mclagan@linux.org +W: http://www.invlogic.com/~mmclagan +S: Innovative Logic Corp +S: P.O. Box 1068 +S: Laurel, MD 20732 +S: USA +D: DLCI/FRAD drivers for Sangoma SDLAs + N: Bradley McLean E: brad@bradpc.gaylord.com D: Device driver hacker diff --git a/Documentation/Configure.help b/Documentation/Configure.help index ef32aa1cf939..8bbde9342fea 100644 --- a/Documentation/Configure.help +++ b/Documentation/Configure.help @@ -654,6 +654,26 @@ CONFIG_KERNELD later on, such as a user level "beeper" and a generic screen blanker. The "kerneld" daemon is included in "modules-1.2.8" and later. +ARP daemon support +CONFIG_ARPD + Normally, the kernel maintains an internal cache which maps IP + addresses to hardware addresses on the local network, so that + Ethernet/Token Ring/ etc. frames are sent to the proper address + on the physical networking layer. For small networks having + a few hundred directly connected hosts or less, keeping this + address resolution cache (ARP) inside the kernel works well. + However, maintaining an internal ARP cache does not work well for + very large switched networks, and will use a lot of kernel memory + if TCP/IP connections are made to many machines on the network. + By enabling this option, the kernel's internal ARP cache will + never grow to more than 256 entries (the oldest entries are + expired in a LIFO manner) and communication will be attempted + with an external ARP daemon, arpd, via the kerneld message + queue. This code is still experimental. If you do enable + arpd support, you should obtain a copy of arpd from + http://www.loran.com/~layes/arpd/index.html. If unsure, + say N. + TCP/IP networking CONFIG_INET These are the protocols used on the Internet and on most local diff --git a/Documentation/cdrom/optcd b/Documentation/cdrom/optcd index 2d66a7301bfc..23fcae349e35 100644 --- a/Documentation/cdrom/optcd +++ b/Documentation/cdrom/optcd @@ -7,7 +7,7 @@ works with this driver, and that doesn't report itself as DOLPHIN, please drop me a mail. The support for multisession CDs is in ALPHA stage. If you use it, -please mail me your experiences. Multisession support can be disables +please mail me your experiences. Multisession support can be disabled at compile time. You can find some older versions of the driver at diff --git a/Documentation/devices.tex b/Documentation/devices.tex index 88bad215fec2..073bd83943fa 100644 --- a/Documentation/devices.tex +++ b/Documentation/devices.tex @@ -416,7 +416,7 @@ physical disks. \noindent The loopback devices are used to mount filesystems not associated with block devices. The binding to the loopback devices is usually handled -by mount(1). +by mount(8). \begin{devicelist} \major{11}{}{char }{Raw keyboard device} diff --git a/Documentation/devices.txt b/Documentation/devices.txt index c2ffd63ad7b7..4e1b0ac38173 100644 --- a/Documentation/devices.txt +++ b/Documentation/devices.txt @@ -194,7 +194,7 @@ an unreasonable effort. The loopback devices are used to mount filesystems not associated with block devices. The binding to the - loopback devices is usually handled by mount(1). + loopback devices is usually handled by mount(8). 8 block SCSI disk devices 0 = /dev/sda First SCSI disk whole disk diff --git a/Documentation/framerelay.txt b/Documentation/framerelay.txt new file mode 100644 index 000000000000..a623957f0c97 --- /dev/null +++ b/Documentation/framerelay.txt @@ -0,0 +1,33 @@ +Frame Relay (FR) support for linux is built into a two tiered system of device +drivers. The upper layer implements RFC1490 FR specification, and uses the +Data Link Connection Identifier (DLCI) as it's hardware address. Usually these +are assigned by your network supplier, they give you the number/numbers of +the Virtual Connections (VC) assigned to you. + +Each DLCI is a point-to-point link between your machine and a remote one. +As such, a seperate device is needed to accomodate the routing. Within the +net-tools archives is 'dlcicfg'. This program will communicate with the +base "DLCI" device, and create new net devices named 'dlci00', 'dlci01'... +The configuration script will ask you how many DLCI's you need, as well as +how many DLCI's you want to assign to each Frame Relay Access Device (FRAD). + +The DLCI uses a number of function calls to communicate with the FRAD, all +of which are stored in the FRAD's private data area. assoc/deassoc, +activate/deactivate and dlci_config. The DLCI supplies a receive function +to the FRAD to accept incoming packets. + +With this initial offering, only 1 FRAD driver is available. With many thanks +to Sangoma Technologies, David Mandelstam & Gene Kozin, the S502A, S502E & +S508 are supported. This driver is currently set up for only FR, but as +Sangoma makes more firmware modules available, it can be updated to provide +them as well. + +Configuration of the FRAD makes use of another net-tools program, 'fradcfg'. +This program makes use of a configuration file (which dlcicfg can also read) +to specify the types of boards to be configured as FRADs, as well as perform +any board specific configuration. The Sangoma module of fradcfg loads the +FR firmware into the card, sets the irq/port/memory information, and provides +an initial configuration. + +Additional FRAD device drivers can be added as hardware is available. + diff --git a/MAGIC b/MAGIC index 157941bcf5a7..ff1bde3af0eb 100644 --- a/MAGIC +++ b/MAGIC @@ -94,6 +94,7 @@ Ioctl Include File Comments 'f' linux/ext2_fs.h 'm' linux/mtio.h conflict! 'm' linux/soundcard.h conflict! +'n' linux/ncp_fs.h 's' linux/cdk.h 't' linux/if_ppp.h 'u' linux/smb_fs.h diff --git a/MAINTAINERS b/MAINTAINERS index 048ed2fd47d8..ae96e6262862 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -48,6 +48,7 @@ Maintainers List (try to look for most precise areas first) P: Person M: Mail patches to L: Mailing list that is relevant to this area +W: Web-page with status/info S: Status Supported: Someone is actually paid to look after this (wildly improbable). @@ -89,6 +90,12 @@ M: Leonard N. Zubkoff L: None S: Maintained +FRAME RELAY DLCI/FRAD (Sangoma drivers too) +P: Mike McLagan +M: mike.mclagan@linux.org +L: linux-net@vger.rutgers.edu +S: Maintained + FUTURE DOMAIN TMC-16x0 SCSI DRIVER (16-bit) P: Rik Faith M: faith@cs.unc.edu @@ -122,9 +129,16 @@ S: Maintained MODULE SUPPORT [GENERAL], KERNELD P: Bjorn Ekwall M: bj0rn@blox.se +W: http://www.pi.se/blox/modules/ L: linux-kernel@vger.rutgers.edu S: Maintained +ARPD SUPPORT +P: Jonathan Layes +M: layes@loran.com +L: linux-net@vger.rutgers.edu +S: Maintained + NCP FILESYSTEM: P: Volker Lendecke M: lendecke@namu01.gwdg.de diff --git a/Makefile b/Makefile index d003e690d281..d6dd788d15b6 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ VERSION = 1 PATCHLEVEL = 3 -SUBLEVEL = 77 +SUBLEVEL = 78 ARCH = i386 diff --git a/arch/alpha/config.in b/arch/alpha/config.in index bcf455feb802..5f6be1c58510 100644 --- a/arch/alpha/config.in +++ b/arch/alpha/config.in @@ -55,6 +55,9 @@ then define_bool CONFIG_PCI y define_bool CONFIG_ALPHA_EV5 y define_bool CONFIG_ALPHA_ALCOR y +else + # EV5 and newer supports all rounding modes in hw: + define_bool CONFIG_ALPHA_NEED_ROUNDING_EMULATION y fi if [ "$CONFIG_ALPHA_JENSEN" = "y" ] @@ -62,8 +65,6 @@ then bool 'Using SRM as bootloader' CONFIG_ALPHA_SRM fi -define_bool CONFIG_ALPHA_NEED_ROUNDING_EMULATION y - bool 'Echo console messages on /dev/ttyS1' CONFIG_SERIAL_ECHO if [ "$CONFIG_PCI" = "y" ]; then bool 'TGA Console Support' CONFIG_TGA_CONSOLE diff --git a/arch/alpha/defconfig b/arch/alpha/defconfig index 06290a597399..eb8348157226 100644 --- a/arch/alpha/defconfig +++ b/arch/alpha/defconfig @@ -24,7 +24,6 @@ CONFIG_ALPHA_EB164=y CONFIG_PCI=y CONFIG_ALPHA_EV5=y CONFIG_ALPHA_ALCOR=y -CONFIG_ALPHA_NEED_ROUNDING_EMULATION=y # CONFIG_SERIAL_ECHO is not set # CONFIG_TGA_CONSOLE is not set CONFIG_PCI_OPTIMIZE=y @@ -134,6 +133,7 @@ CONFIG_DUMMY=m # CONFIG_SCC is not set # CONFIG_PLIP is not set # CONFIG_EQUALIZER is not set +# CONFIG_FRAD is not set # CONFIG_NET_ALPHA is not set # CONFIG_NET_VENDOR_SMC is not set # CONFIG_LANCE is not set diff --git a/arch/alpha/kernel/time.c b/arch/alpha/kernel/time.c index 7352a6cd347f..87b51e81f4c0 100644 --- a/arch/alpha/kernel/time.c +++ b/arch/alpha/kernel/time.c @@ -20,23 +20,62 @@ #include #include +#include #include #include #define TIMER_IRQ 0 +extern struct hwrpb_struct *hwrpb; + static int set_rtc_mmss(unsigned long); + +/* + * Shift amount by which scaled_ticks_per_cycle is scaled. Shifting + * by 48 gives us 16 bits for HZ while keeping the accuracy good even + * for large CPU clock rates. + */ +#define FIX_SHIFT 48 + +/* lump static variables together for more efficient access: */ +static struct { + __u32 last_time; /* cycle counter last time it got invoked */ + __u32 max_cycles_per_tick; /* more makes us think we lost an interrupt */ + unsigned long scaled_ticks_per_cycle; /* ticks/cycle * 2^48 */ + long last_rtc_update; /* last time the cmos clock got updated */ +} state; + + +static inline __u32 rpcc(void) +{ + __u32 result; + + asm volatile ("rpcc %0" : "r="(result)); + return result; +} + + /* * timer_interrupt() needs to keep up the real-time clock, * as well as call the "do_timer()" routine every clocktick */ void timer_interrupt(struct pt_regs * regs) { - /* last time the cmos clock got updated */ - static long last_rtc_update=0; + __u32 delta, now; + + now = rpcc(); + delta = now - state.last_time; + state.last_time = now; + if (delta > state.max_cycles_per_tick) { + int i, missed_ticks; + missed_ticks = ((delta * state.scaled_ticks_per_cycle) >> FIX_SHIFT) - 1; + for (i = 0; i < missed_ticks; ++i) { + do_timer(regs); + } + } do_timer(regs); /* @@ -44,13 +83,13 @@ void timer_interrupt(struct pt_regs * regs) * CMOS clock accordingly every ~11 minutes. Set_rtc_mmss() has to be * called as close as possible to 500 ms before the new second starts. */ - if (time_state != TIME_BAD && xtime.tv_sec > last_rtc_update + 660 && + if (time_state != TIME_BAD && xtime.tv_sec > state.last_rtc_update + 660 && xtime.tv_usec > 500000 - (tick >> 1) && xtime.tv_usec < 500000 + (tick >> 1)) if (set_rtc_mmss(xtime.tv_sec) == 0) - last_rtc_update = xtime.tv_sec; + state.last_rtc_update = xtime.tv_sec; else - last_rtc_update = xtime.tv_sec - 600; /* do it again in 60 s */ + state.last_rtc_update = xtime.tv_sec - 600; /* do it again in 60 s */ } /* Converts Gregorian date to seconds since 1970-01-01 00:00:00. @@ -130,6 +169,15 @@ void time_init(void) year += 100; xtime.tv_sec = mktime(year, mon, day, hour, min, sec); xtime.tv_usec = 0; + + if (HZ > (1<<16)) { + extern void __you_loose (void); + __you_loose(); + } + state.last_time = rpcc(); + state.scaled_ticks_per_cycle = ((unsigned long) HZ << FIX_SHIFT) / hwrpb->cycle_freq; + state.max_cycles_per_tick = (2 * hwrpb->cycle_freq) / HZ; + state.last_rtc_update = 0; } /* diff --git a/arch/alpha/math-emu/fp-emul.c b/arch/alpha/math-emu/fp-emul.c index 0c0a5ac08b03..c7125f5c5e20 100644 --- a/arch/alpha/math-emu/fp-emul.c +++ b/arch/alpha/math-emu/fp-emul.c @@ -175,7 +175,7 @@ alpha_fp_emul (unsigned long pc) insn = get_user((__u32*)pc); fc = (insn >> 0) & 0x1f; /* destination register */ - func = (insn >> 5) & 0x3ff; + func = (insn >> 5) & 0x7ff; fb = (insn >> 16) & 0x1f; fa = (insn >> 21) & 0x1f; opcode = insn >> 26; diff --git a/arch/alpha/math-emu/ieee-math.c b/arch/alpha/math-emu/ieee-math.c index 4f823f7d00f1..51305b5a115e 100644 --- a/arch/alpha/math-emu/ieee-math.c +++ b/arch/alpha/math-emu/ieee-math.c @@ -501,7 +501,7 @@ round_s_ieee (int f, EXTENDED *a, unsigned long *b) static unsigned long -round_t_ieee (EXTENDED *a, unsigned long *b, int f) +round_t_ieee (int f, EXTENDED *a, unsigned long *b) { unsigned long diff1, diff2, res; EXTENDED z1, z2; @@ -626,7 +626,7 @@ ieee_CVTST (int f, unsigned long a, unsigned long *b) } return 0; } - return round_s_ieee(f, &temp, b); + return round_t_ieee(f, &temp, b); } @@ -717,7 +717,7 @@ ieee_CVTQT (int f, unsigned long a, unsigned long *b) } op_b.e = 55; normalize(&op_b); - return round_t_ieee(&op_b, b, f); + return round_t_ieee(f, &op_b, b); } @@ -993,7 +993,7 @@ ieee_ADDT (int f, unsigned long a, unsigned long b, unsigned long *c) if (a_type == ZERO && b_type == ZERO) op_c.s = op_a.s && op_b.s; - return round_t_ieee(&op_c, c, f); + return round_t_ieee(f, &op_c, c); } @@ -1093,7 +1093,7 @@ ieee_SUBT (int f, unsigned long a, unsigned long b, unsigned long *c) if (a_type == ZERO && b_type == ZERO) op_c.s = op_a.s && op_b.s; - return round_t_ieee(&op_c, c, f); + return round_t_ieee(f, &op_c, c); } @@ -1206,7 +1206,7 @@ ieee_MULT (int f, unsigned long a, unsigned long b, unsigned long *c) normalize(&op_c); op_c.e -= 55; /* drop the 55 original bits. */ - return round_t_ieee(&op_c, c, f); + return round_t_ieee(f, &op_c, c); } @@ -1339,5 +1339,5 @@ ieee_DIVT (int f, unsigned long a, unsigned long b, unsigned long *c) op_c.f[0] |= STICKY_T; normalize(&op_c); op_c.e -= 9; /* remove excess exp from original shift */ - return round_t_ieee(&op_c, c, f); + return round_t_ieee(f, &op_c, c); } diff --git a/arch/i386/boot/setup.S b/arch/i386/boot/setup.S index 4041d4acb2bd..9f3bdd0eb5f7 100644 --- a/arch/i386/boot/setup.S +++ b/arch/i386/boot/setup.S @@ -74,8 +74,10 @@ type_of_loader: .byte 0 ! = 0, old one (LILO, Loadlin, ! Bootlin, SYSLX, bootsect...) ! else it is set by the loader: ! 0xTV: T=0 for LILO - ! T=1 for Loadlin - ! T=2 for bootsect-loader + ! T=1 for Loadlin + ! T=2 for bootsect-loader + ! T=3 for SYSLX + ! T=4 for ETHERBOOT ! V = version loadflags: .byte 0 ! unused bits =0 (reserved for future development) LOADED_HIGH = 1 ! bit within loadflags, diff --git a/arch/i386/defconfig b/arch/i386/defconfig index c9f2464554ee..5775aa4d394b 100644 --- a/arch/i386/defconfig +++ b/arch/i386/defconfig @@ -47,6 +47,7 @@ CONFIG_BLK_DEV_RZ1000=y # CONFIG_BLK_DEV_LOOP is not set # CONFIG_BLK_DEV_XD is not set # CONFIG_BLK_DEV_MD is not set + # # Networking options # @@ -90,6 +91,7 @@ CONFIG_DUMMY=m # CONFIG_SCC is not set # CONFIG_PLIP is not set # CONFIG_EQUALIZER is not set +# CONFIG_FRAD is not set # CONFIG_NET_ALPHA is not set # CONFIG_NET_VENDOR_SMC is not set # CONFIG_LANCE is not set diff --git a/arch/i386/kernel/entry.S b/arch/i386/kernel/entry.S index dbfc1921d837..df6f7361d9ef 100644 --- a/arch/i386/kernel/entry.S +++ b/arch/i386/kernel/entry.S @@ -688,4 +688,5 @@ ENTRY(sys_call_table) .long SYMBOL_NAME(sys_sched_get_priority_min) /* 160 */ .long SYMBOL_NAME(sys_sched_rr_get_interval) .long SYMBOL_NAME(sys_nanosleep) + .long SYMBOL_NAME(sys_mremap) .space (NR_syscalls-163)*4 diff --git a/arch/i386/kernel/smp.c b/arch/i386/kernel/smp.c index 3b06b61b0f04..9e416bf3c057 100644 --- a/arch/i386/kernel/smp.c +++ b/arch/i386/kernel/smp.c @@ -51,14 +51,14 @@ extern __inline int max(int a,int b) int smp_found_config=0; /* Have we found an SMP box */ unsigned long cpu_present_map = 0; /* Bitmask of existing CPU's */ -int smp_num_cpus; /* Total count of live CPU's */ +int smp_num_cpus = 1; /* Total count of live CPU's */ int smp_threads_ready=0; /* Set when the idlers are all forked */ volatile int cpu_number_map[NR_CPUS]; /* which CPU maps to which logical number */ +volatile int cpu_logical_map[NR_CPUS]; /* which logical number maps to which CPU */ volatile unsigned long cpu_callin_map[NR_CPUS] = {0,}; /* We always use 0 the rest is ready for parallel delivery */ volatile unsigned long smp_invalidate_needed; /* Used for the invalidate map thats also checked in the spinlock */ struct cpuinfo_x86 cpu_data[NR_CPUS]; /* Per cpu bogomips and other parameters */ static unsigned int num_processors = 1; /* Internal processor count */ -int smp_top_cpu = 0; /* Highest used APIC id */ static unsigned long io_apic_addr = 0xFEC00000; /* Address of the I/O apic (not yet used) */ unsigned char boot_cpu_id = 0; /* Processor that is doing the boot up */ static unsigned char *kstack_base,*kstack_end; /* Kernel stack list pointers */ @@ -220,7 +220,6 @@ static int smp_read_mpc(struct mp_config_table *mpc) { SMP_PRINTK((" Bootup CPU\n")); boot_cpu_id=m->mpc_apicid; - nlong = boot_cpu_id<<24; /* Dummy 'self' for bootup */ } else /* Boot CPU already counted */ num_processors++; @@ -294,7 +293,7 @@ static int smp_read_mpc(struct mp_config_table *mpc) * Scan the memory blocks for an SMP configuration block. */ -void smp_scan_config(unsigned long base, unsigned long length) +int smp_scan_config(unsigned long base, unsigned long length) { unsigned long *bp=(unsigned long *)base; struct intel_mp_floating *mpf; @@ -324,55 +323,19 @@ void smp_scan_config(unsigned long base, unsigned long length) * Now see if we need to read further. */ if(mpf->mpf_feature1!=0) - { - num_processors=2; - printk("I/O APIC at 0xFEC00000.\n"); - printk("Bus#0 is "); - } - switch(mpf->mpf_feature1) - { - case 1: - case 5: - printk("ISA\n"); - break; - case 2: - printk("EISA with no IRQ8 chaining\n"); - break; - case 6: - case 3: - printk("EISA\n"); - break; - case 4: - case 7: - printk("MCA\n"); - break; - case 0: - break; - default: - printk("???\nUnknown standard configuration %d\n", - mpf->mpf_feature1); - return; - } - if(mpf->mpf_feature1>4) - printk("Bus #1 is PCI\n"); - /* - * Read the physical hardware table. - */ - if(mpf->mpf_physptr) - smp_read_mpc((void *)mpf->mpf_physptr); - else { unsigned long cfg; /* - * If no table present, determine - * what the CPU mapping is. + * We need to know what the local + * APIC id of the boot CPU is! */ /* * * HACK HACK HACK HACK HACK HACK HACK HACK HACK HACK HACK HACK HACK * + * It's not just a crazy hack... ;-) */ /* * Standard page mapping @@ -386,7 +349,6 @@ void smp_scan_config(unsigned long base, unsigned long length) local_invalidate(); boot_cpu_id = GET_APIC_ID(*((volatile unsigned long *) APIC_ID)); - nlong = boot_cpu_id<<24; /* Dummy 'self' for bootup */ /* * Give it back @@ -400,26 +362,79 @@ void smp_scan_config(unsigned long base, unsigned long length) * END OF HACK END OF HACK END OF HACK END OF HACK END OF HACK * */ + /* + * 2 CPUs, numbered 0 & 1. + */ + cpu_present_map=3; + num_processors=2; + printk("I/O APIC at 0xFEC00000.\n"); + printk("Bus#0 is "); + } + switch(mpf->mpf_feature1) + { + case 1: + case 5: + printk("ISA\n"); + break; + case 2: + printk("EISA with no IRQ8 chaining\n"); + break; + case 6: + case 3: + printk("EISA\n"); + break; + case 4: + case 7: + printk("MCA\n"); + break; + case 0: + break; + default: + printk("???\nUnknown standard configuration %d\n", + mpf->mpf_feature1); + return 1; + } + if(mpf->mpf_feature1>4) + { + printk("Bus #1 is PCI\n"); /* - * If boot CPU != 0, other CPU - * is 0, else other CPU is 1. + * Set local APIC version to + * the integrated form. + * It's initialized to zero + * otherwise, representing + * a discrete 82489DX. */ - if (boot_cpu_id) - cpu_present_map=1 | (1 << boot_cpu_id); - else - cpu_present_map=3; + apic_version[0] = 0x10; + apic_version[1] = 0x10; } + /* + * Read the physical hardware table. + * Anything here will override the + * defaults. + */ + if(mpf->mpf_physptr) + smp_read_mpc((void *)mpf->mpf_physptr); + + /* + * Now that the boot CPU id is known, + * set some other information about it. + */ + nlong = boot_cpu_id<<24; /* Dummy 'self' for bootup */ + cpu_logical_map[0] = boot_cpu_id; + printk("Processors: %d\n", num_processors); /* - * Only use the first one found. + * Only use the first configuration found. */ - return; + return 1; } } bp+=4; length-=16; } + + return 0; } /* @@ -565,7 +580,7 @@ void smp_callin(void) void smp_boot_cpus(void) { - int i,j; + int i; int cpucount=0; unsigned long cfg; void *stack; @@ -667,15 +682,12 @@ void smp_boot_cpus(void) * Don't even attempt to start the boot CPU! */ if (i == boot_cpu_id) - { - smp_top_cpu=max(smp_top_cpu,i); continue; - } if (cpu_present_map & (1 << i)) { unsigned long send_status, accept_status; - int timeout, num_starts; + int timeout, num_starts, j; /* * We need a kernel stack for each processor. @@ -719,8 +731,11 @@ void smp_boot_cpus(void) * Be paranoid about clearing APIC errors. */ - apic_write(APIC_ESR, 0); - accept_status = (apic_read(APIC_ESR) & 0xEF); + if ( apic_version[i] & 0xF0 ) + { + apic_write(APIC_ESR, 0); + accept_status = (apic_read(APIC_ESR) & 0xEF); + } /* * Status is now clean @@ -777,8 +792,8 @@ void smp_boot_cpus(void) * Run STARTUP IPI loop. */ - for (j = 0; !(send_status || accept_status) - && (j < num_starts) ; j++) + for (j = 1; !(send_status || accept_status) + && (j <= num_starts) ; j++) { SMP_PRINTK(("Sending STARTUP #%d.\n",j)); @@ -826,8 +841,7 @@ void smp_boot_cpus(void) cpucount++; /* number CPUs logically, starting from 1 (BSP is 0) */ cpu_number_map[i] = cpucount; - smp_top_cpu=max(smp_top_cpu,i); - + cpu_logical_map[cpucount] = i; } else { @@ -951,10 +965,12 @@ void smp_message_pass(int target, int msg, unsigned long data, int wait) /* * Sanity check we don't re-enter this across CPU's. Only the kernel * lock holder may send messages. For a STOP_CPU we are bringing the - * entire box to the fastest halt we can.. + * entire box to the fastest halt we can.. A reschedule carries + * no data and can occur during an invalidate.. guess what panic + * I got to notice this bug... */ - if(message_cpu!=NO_PROC_ID && msg!=MSG_STOP_CPU) + if(message_cpu!=NO_PROC_ID && msg!=MSG_STOP_CPU && msg!=MSG_RESCHEDULE) { panic("CPU #%d: Message pass %d but pass in progress by %d of %d\n", smp_processor_id(),msg,message_cpu, smp_msg_id); diff --git a/arch/i386/mm/init.c b/arch/i386/mm/init.c index 7ce2c3ce5aae..0b598463c7e8 100644 --- a/arch/i386/mm/init.c +++ b/arch/i386/mm/init.c @@ -128,13 +128,15 @@ unsigned long paging_init(unsigned long start_mem, unsigned long end_mem) memset((void *) 0, 0, PAGE_SIZE); #endif #ifdef __SMP__ - smp_scan_config(0x0,0x400); /* Scan the bottom 1K for a signature */ - /* - * FIXME: Linux assumes you have 640K of base ram.. this continues - * the error... - */ - smp_scan_config(639*0x400,0x400); /* Scan the top 1K of base RAM */ - smp_scan_config(0xF0000,0x10000); /* Scan the 64K of bios */ + if (!smp_scan_config(0x0,0x400)) /* Scan the bottom 1K for a signature */ + { + /* + * FIXME: Linux assumes you have 640K of base ram.. this continues + * the error... + */ + if (!smp_scan_config(639*0x400,0x400)) /* Scan the top 1K of base RAM */ + smp_scan_config(0xF0000,0x10000); /* Scan the 64K of bios */ + } /* * If it is an SMP machine we should know now, unless the configuration * is in an EISA/MCA bus machine with an extended bios data area. I don't diff --git a/drivers/block/floppy.c b/drivers/block/floppy.c index 1468b011fd6f..4f1c9d2e3d0b 100644 --- a/drivers/block/floppy.c +++ b/drivers/block/floppy.c @@ -2597,7 +2597,7 @@ static void redo_fd_request(void) } while(1){ - if (!CURRENT) { + if (!CURRENT || CURRENT_PLUGGED) { CLEAR_INTR; unlock_fdc(); return; diff --git a/drivers/block/ide.c b/drivers/block/ide.c index ab406fcbd783..a714dda023ef 100644 --- a/drivers/block/ide.c +++ b/drivers/block/ide.c @@ -1469,6 +1469,8 @@ void ide_do_request (ide_hwgroup_t *hwgroup) */ hwif = hwgroup->next_hwif; do { + if (IS_PLUGGED(blk_dev + hwif->major)) + continue; rq = blk_dev[hwif->major].current_request; if (rq != NULL && rq->rq_status != RQ_INACTIVE) goto got_rq; diff --git a/drivers/block/ll_rw_blk.c b/drivers/block/ll_rw_blk.c index 946b59ec9c3e..3c066a8a0ddc 100644 --- a/drivers/block/ll_rw_blk.c +++ b/drivers/block/ll_rw_blk.c @@ -76,40 +76,30 @@ int * blksize_size[MAX_BLKDEV] = { NULL, NULL, }; int * hardsect_size[MAX_BLKDEV] = { NULL, NULL, }; /* - * "plug" the device if there are no outstanding requests: this will - * force the transfer to start only after we have put all the requests - * on the list. + * remove the plug and let it rip.. */ -static inline void plug_device(struct blk_dev_struct * dev, struct request * plug) +static void unplug_device(void * data) { + struct blk_dev_struct * dev = (struct blk_dev_struct *) data; unsigned long flags; - plug->rq_status = RQ_INACTIVE; - plug->cmd = -1; - plug->next = NULL; save_flags(flags); cli(); - if (!dev->current_request) - dev->current_request = plug; + if (dev->current_request) + (dev->request_fn)(); restore_flags(flags); } /* - * remove the plug and let it rip.. + * "plug" the device if there are no outstanding requests: this will + * force the transfer to start only after we have put all the requests + * on the list. */ -static inline void unplug_device(struct blk_dev_struct * dev) +static inline void plug_device(struct blk_dev_struct * dev) { - struct request * req; - unsigned long flags; - - save_flags(flags); - cli(); - req = dev->current_request; - if (req && req->rq_status == RQ_INACTIVE && req->cmd == -1) { - dev->current_request = req->next; - (dev->request_fn)(); + if (!dev->current_request && !IS_PLUGGED(dev)) { + queue_task_irq_off(&dev->plug_tq, &tq_scheduler); } - restore_flags(flags); } /* @@ -154,7 +144,6 @@ static struct request * __get_request_wait(int n, kdev_t dev) add_wait_queue(&wait_for_request, &wait); for (;;) { - unplug_device(MAJOR(dev)+blk_dev); current->state = TASK_UNINTERRUPTIBLE; cli(); req = get_request(n, dev); @@ -261,7 +250,8 @@ void add_request(struct blk_dev_struct * dev, struct request * req) if (!(tmp = dev->current_request)) { dev->current_request = req; up (&request_lock); - (dev->request_fn)(); + if (!IS_PLUGGED(dev)) + (dev->request_fn)(); sti(); return; } @@ -276,7 +266,7 @@ void add_request(struct blk_dev_struct * dev, struct request * req) up (&request_lock); /* for SCSI devices, call request_fn unconditionally */ - if (scsi_major(MAJOR(req->rq_dev)) && MAJOR(req->rq_dev)!=MD_MAJOR) + if (!IS_PLUGGED(dev) && scsi_major(MAJOR(req->rq_dev)) && MAJOR(req->rq_dev)!=MD_MAJOR) (dev->request_fn)(); sti(); @@ -340,8 +330,8 @@ static void make_request(int major,int rw, struct buffer_head * bh) } /* look for a free request. */ - cli(); down (&request_lock); + cli(); /* The scsi disk and cdrom drivers completely remove the request * from the queue when they start processing an entry. For this reason @@ -479,7 +469,6 @@ void ll_rw_page(int rw, kdev_t dev, unsigned long page, char * buffer) void ll_rw_block(int rw, int nr, struct buffer_head * bh[]) { unsigned int major; - struct request plug; int correct_size; struct blk_dev_struct * dev; int i; @@ -531,8 +520,7 @@ void ll_rw_block(int rw, int nr, struct buffer_head * bh[]) from starting until we have shoved all of the blocks into the queue, and then we let it rip. */ - if (nr > 1) - plug_device(dev, &plug); + plug_device(dev); for (i = 0; i < nr; i++) { if (bh[i]) { set_bit(BH_Req, &bh[i]->b_state); @@ -543,7 +531,6 @@ void ll_rw_block(int rw, int nr, struct buffer_head * bh[]) make_request(major, rw, bh[i]); } } - unplug_device(dev); return; sorry: @@ -622,6 +609,8 @@ int blk_dev_init(void) for (dev = blk_dev + MAX_BLKDEV; dev-- != blk_dev;) { dev->request_fn = NULL; dev->current_request = NULL; + dev->plug_tq.routine = &unplug_device; + dev->plug_tq.data = dev; } req = all_requests + NR_REQUEST; diff --git a/drivers/block/loop.c b/drivers/block/loop.c index c96be91cbbe3..1f32436a3f7b 100644 --- a/drivers/block/loop.c +++ b/drivers/block/loop.c @@ -181,7 +181,10 @@ repeat: offset -= blksize; } len = CURRENT->current_nr_sectors << 9; - if ((CURRENT->cmd != WRITE) && (CURRENT->cmd != READ)) { + if (CURRENT->cmd == WRITE) { + if (lo->lo_flags & LO_FLAGS_READ_ONLY) + goto error_out; + } else if (CURRENT->cmd != READ) { printk("unknown loop device command (%d)?!?", CURRENT->cmd); goto error_out; } @@ -235,11 +238,11 @@ error_out: goto repeat; } -static int loop_set_fd(struct loop_device *lo, unsigned int arg) +static int loop_set_fd(struct loop_device *lo, kdev_t dev, unsigned int arg) { struct file *file; struct inode *inode; - + if (arg >= NR_OPEN || !(file = current->files->fd[arg])) return -EBADF; if (lo->lo_inode) @@ -261,7 +264,14 @@ static int loop_set_fd(struct loop_device *lo, unsigned int arg) } else return -EINVAL; - invalidate_inode_pages (inode); + if (IS_RDONLY (inode) || is_read_only(lo->lo_device)) { + lo->lo_flags |= LO_FLAGS_READ_ONLY; + set_device_ro(dev, 1); + } else { + invalidate_inode_pages (inode); + set_device_ro(dev, 0); + } + lo->lo_inode = inode; lo->lo_inode->i_count++; lo->transfer = NULL; @@ -274,7 +284,7 @@ static int loop_clr_fd(struct loop_device *lo, kdev_t dev) { if (!lo->lo_inode) return -ENXIO; - if (lo->lo_refcnt > 1) + if (lo->lo_refcnt > 1) /* we needed one fd for the ioctl */ return -EBUSY; if (S_ISBLK(lo->lo_inode->i_mode)) blkdev_release (lo->lo_inode); @@ -378,7 +388,7 @@ static int lo_ioctl(struct inode * inode, struct file * file, lo = &loop_dev[dev]; switch (cmd) { case LOOP_SET_FD: - return loop_set_fd(lo, arg); + return loop_set_fd(lo, inode->i_rdev, arg); case LOOP_CLR_FD: return loop_clr_fd(lo, inode->i_rdev); case LOOP_SET_STATUS: @@ -442,8 +452,6 @@ static void lo_release(struct inode *inode, struct file *file) lo->lo_refcnt--; MOD_DEC_USE_COUNT; } - - return; } static struct file_operations lo_fops = { diff --git a/drivers/block/md.c b/drivers/block/md.c index 78931f15b2b8..0476402f1b82 100644 --- a/drivers/block/md.c +++ b/drivers/block/md.c @@ -7,6 +7,8 @@ A lot of inspiration came from hd.c ... + kerneld support by Boris Tobotras + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) @@ -29,6 +31,9 @@ #include #include #include +#ifdef CONFIG_KERNELD +#include +#endif #include #define MAJOR_NR MD_MAJOR @@ -92,14 +97,14 @@ static struct gendisk *find_gendisk (kdev_t dev) /* Picked up from genhd.c */ char *partition_name (kdev_t dev) { - static char name[10]; /* This should be long + static char name[40]; /* This should be long enough for a device name ! */ - struct gendisk *hd=find_gendisk (dev); + struct gendisk *hd = find_gendisk (dev); if (!hd) { - printk ("No gendisk entry for dev %04x\n", dev); - sprintf (name, "dev %04x", dev); + printk ("No gendisk entry for dev %s\n", kdevname(dev)); + sprintf (name, "dev %s", kdevname(dev)); return (name); } @@ -197,10 +202,20 @@ static int md_ioctl (struct inode *inode, struct file *file, md_dev[minor].repartition=(int) arg; if ((index=PERSONALITY(md_dev+minor) >> (PERSONALITY_SHIFT)) - >= MAX_PERSONALITY || - !pers[index]) + >= MAX_PERSONALITY) return -EINVAL; + if (!pers[index]) + { +#ifdef CONFIG_KERNELD + char module_name[80]; + sprintf (module_name, "md-personality-%d", index); + request_module (module_name); + if (!pers[index]) +#endif + return -EINVAL; + } + md_dev[minor].pers=pers[index]; if ((err=md_dev[minor].pers->run (minor, md_dev+minor))) @@ -404,7 +419,7 @@ static void do_md_request (void) minor = MINOR(req->rq_dev); if ((MAJOR(req->rq_dev) != MD_MAJOR) || (minor >= MAX_REAL)) { - printk("md: bad device number: 0x%04x\n", req->rq_dev); + printk("md: bad device: %s\n", kdevname(req->rq_dev)); end_request(0, req); continue; } @@ -437,16 +452,17 @@ void make_md_request (struct request *pending, int n) kdev_t dev; struct buffer_head *bh; struct request *req; + long flags; down (&request_lock); + save_flags (flags); + cli(); for (i=0; irq_status!=RQ_INACTIVE && req->rq_status!=RQ_ACTIVE) + if (req->rq_status!=RQ_ACTIVE) printk ("Saw bad status request !\n"); if (req->rq_dev == dev && @@ -494,7 +510,7 @@ void make_md_request (struct request *pending, int n) (req->nr_sectors + pending[i].nr_sectors) < 245) { req->nr_sectors += pending[i].nr_sectors; - bh->b_reqnext = req->bh; + pending[i].bhtail->b_reqnext = req->bh; req->buffer = bh->b_data; req->current_nr_sectors = bh->b_size >> 9; req->sector = pending[i].sector; @@ -511,6 +527,7 @@ void make_md_request (struct request *pending, int n) continue; up (&request_lock); + sti (); req=get_md_request (max_req, dev); /* Build it up... */ @@ -530,9 +547,11 @@ void make_md_request (struct request *pending, int n) add_request (blk_dev + MAJOR(dev), req); down (&request_lock); + cli (); } up (&request_lock); + restore_flags (flags); for (j=0; jstatus (page+sz, i, md_dev+i); } - + return (sz); } diff --git a/drivers/cdrom/cdu31a.c b/drivers/cdrom/cdu31a.c index b20f1dda9484..ad5d3ce546ed 100644 --- a/drivers/cdrom/cdu31a.c +++ b/drivers/cdrom/cdu31a.c @@ -1525,7 +1525,7 @@ cdu31a_request_startover: * The beginning here is stolen from the hard disk driver. I hope * it's right. */ - if (!(CURRENT) || CURRENT->rq_status == RQ_INACTIVE) + if (!(CURRENT) || CURRENT_PLUGGED || CURRENT->rq_status == RQ_INACTIVE) { goto end_do_cdu31a_request; } diff --git a/drivers/cdrom/mcdx.c b/drivers/cdrom/mcdx.c index 80f08337af84..790819937b2d 100644 --- a/drivers/cdrom/mcdx.c +++ b/drivers/cdrom/mcdx.c @@ -1,7 +1,7 @@ /* * The Mitsumi CDROM interface * Copyright (C) 1995 Heiko Schlittermann - * VERSION: 1.8 + * VERSION: 1.9 * ****************** H E L P ********************************* * If you ever plan to update your CD ROM drive and perhaps @@ -44,7 +44,7 @@ #if RCS static const char *mcdx_c_version - = "$Id: mcdx.c,v 1.39 1996/03/15 00:00:59 heiko Exp $"; + = "mcdx.c,v 1.2 1996/03/22 01:14:59 heiko Exp"; #endif #include @@ -850,7 +850,7 @@ static void mcdx_delay(struct s_drive_stuff *stuff, long jifs) I wanna make this independend of cpu speed. [1 jiffie is 1/HZ] sec */ { unsigned long tout = jiffies + jifs; - if (jifs < 0) printk ("********\n"); + if (jifs < 0) return; /* TRACE((INIT, "mcdx_delay %d\n", jifs)); */ @@ -1102,12 +1102,12 @@ int mcdx_init(void) int drive; #ifdef MODULE - WARN(("Version 1.8 for %s\n", kernel_version)); + WARN(("Version 1.9 for %s\n", kernel_version)); #else - WARN(("Version 1.8\n")); + WARN(("Version 1.9\n")); #endif - WARN(("$Id: mcdx.c,v 1.39 1996/03/15 00:00:59 heiko Exp $\n")); + WARN(("mcdx.c,v 1.2 1996/03/22 01:14:59 heiko Exp\n")); /* zero the pointer array */ for (drive = 0; drive < MCDX_NDRIVES; drive++) diff --git a/drivers/cdrom/optcd_isp16.h b/drivers/cdrom/optcd_isp16.h deleted file mode 100644 index f6bb76d431d6..000000000000 --- a/drivers/cdrom/optcd_isp16.h +++ /dev/null @@ -1,337 +0,0 @@ -/* linux/drivers/cdrom/optcd_isp16.h - ISP16 CDROM interface configuration - $Id: optcd_isp16.h,v 1.3 1996/01/15 18:43:11 root Exp root $ - - Extracts from linux/drivers/cdrom/sjcd.c - For copyrights see linux/drivers/cdrom/optcd.c -*/ - - -/* Some (Media)Magic */ -/* define types of drive the interface on an ISP16 card may be looking at */ -#define ISP16_DRIVE_X 0x00 -#define ISP16_SONY 0x02 -#define ISP16_PANASONIC0 0x02 -#define ISP16_SANYO0 0x02 -#define ISP16_MITSUMI 0x04 -#define ISP16_PANASONIC1 0x06 -#define ISP16_SANYO1 0x06 -#define ISP16_DRIVE_NOT_USED 0x08 /* not used */ -#define ISP16_DRIVE_SET_MASK 0xF1 /* don't change 0-bit or 4-7-bits*/ -/* ...for port */ -#define ISP16_DRIVE_SET_PORT 0xF8D -/* set io parameters */ -#define ISP16_BASE_340 0x00 -#define ISP16_BASE_330 0x40 -#define ISP16_BASE_360 0x80 -#define ISP16_BASE_320 0xC0 -#define ISP16_IRQ_X 0x00 -#define ISP16_IRQ_5 0x04 /* shouldn't be used due to soundcard conflicts */ -#define ISP16_IRQ_7 0x08 /* shouldn't be used due to soundcard conflicts */ -#define ISP16_IRQ_3 0x0C -#define ISP16_IRQ_9 0x10 -#define ISP16_IRQ_10 0x14 -#define ISP16_IRQ_11 0x18 -#define ISP16_DMA_X 0x03 -#define ISP16_DMA_3 0x00 -#define ISP16_DMA_5 0x00 -#define ISP16_DMA_6 0x01 -#define ISP16_DMA_7 0x02 -#define ISP16_IO_SET_MASK 0x20 /* don't change 5-bit */ -/* ...for port */ -#define ISP16_IO_SET_PORT 0xF8E -/* enable the card */ -#define ISP16_C928__ENABLE_PORT 0xF90 /* ISP16 with OPTi 82C928 chip */ -#define ISP16_C929__ENABLE_PORT 0xF91 /* ISP16 with OPTi 82C929 chip */ -#define ISP16_ENABLE_CDROM 0x80 /* seven bit */ - -/* the magic stuff */ -#define ISP16_CTRL_PORT 0xF8F -#define ISP16_C928__CTRL 0xE2 /* ISP16 with OPTi 82C928 chip */ -#define ISP16_C929__CTRL 0xE3 /* ISP16 with OPTi 82C929 chip */ - -static short isp16_detect(void); -static short isp16_c928__detect(void); -static short isp16_c929__detect(void); -static short isp16_cdi_config( int base, u_char drive_type, int irq, int dma ); -static void isp16_sound_config( void ); -static short isp16_type; /* dependent on type of interface card */ -static u_char isp16_ctrl; -static u_short isp16_enable_port; - -/*static int sjcd_present = 0;*/ -static u_char special_mask = 0; - -static unsigned char defaults[ 16 ] = { - 0xA8, 0xA8, 0x18, 0x18, 0x18, 0x18, 0x8E, 0x8E, - 0x03, 0x00, 0x02, 0x00, 0x0A, 0x00, 0x00, 0x00 -}; -/* ------------- */ -/* - * -- ISP16 detection and configuration - * - * Copyright (c) 1995, Eric van der Maarel - * - * Version 0.5 - * - * Detect cdrom interface on ISP16 soundcard. - * Configure cdrom interface. - * Configure sound interface. - * - * Algorithm for the card with OPTi 82C928 taken - * from the CDSETUP.SYS driver for MSDOS, - * by OPTi Computers, version 2.03. - * Algorithm for the card with OPTi 82C929 as communicated - * to me by Vadim Model and Leo Spiekman. - * - * Use, modifification or redistribution of this software is - * allowed under the terms of the GPL. - * - */ - - -#define ISP16_IN(p) (outb(isp16_ctrl,ISP16_CTRL_PORT), inb(p)) -#define ISP16_OUT(p,b) (outb(isp16_ctrl,ISP16_CTRL_PORT), outb(b,p)) - -static short -isp16_detect(void) -{ - - if ( !( isp16_c929__detect() < 0 ) ) - return(2); - else - return( isp16_c928__detect() ); -} - -static short -isp16_c928__detect(void) -{ - u_char ctrl; - u_char enable_cdrom; - u_char io; - short i = -1; - - isp16_ctrl = ISP16_C928__CTRL; - isp16_enable_port = ISP16_C928__ENABLE_PORT; - - /* read' and write' are a special read and write, respectively */ - - /* read' ISP16_CTRL_PORT, clear last two bits and write' back the result */ - ctrl = ISP16_IN( ISP16_CTRL_PORT ) & 0xFC; - ISP16_OUT( ISP16_CTRL_PORT, ctrl ); - - /* read' 3,4 and 5-bit from the cdrom enable port */ - enable_cdrom = ISP16_IN( ISP16_C928__ENABLE_PORT ) & 0x38; - - if ( !(enable_cdrom & 0x20) ) { /* 5-bit not set */ - /* read' last 2 bits of ISP16_IO_SET_PORT */ - io = ISP16_IN( ISP16_IO_SET_PORT ) & 0x03; - if ( ((io&0x01)<<1) == (io&0x02) ) { /* bits are the same */ - if ( io == 0 ) { /* ...the same and 0 */ - i = 0; - enable_cdrom |= 0x20; - } - else { /* ...the same and 1 */ /* my card, first time 'round */ - i = 1; - enable_cdrom |= 0x28; - } - ISP16_OUT( ISP16_C928__ENABLE_PORT, enable_cdrom ); - } - else { /* bits are not the same */ - ISP16_OUT( ISP16_CTRL_PORT, ctrl ); - return(i); /* -> not detected: possibly incorrect conclusion */ - } - } - else if ( enable_cdrom == 0x20 ) - i = 0; - else if ( enable_cdrom == 0x28 ) /* my card, already initialised */ - i = 1; - - ISP16_OUT( ISP16_CTRL_PORT, ctrl ); - - return(i); -} - -static short -isp16_c929__detect(void) -{ - u_char ctrl; - u_char tmp; - - isp16_ctrl = ISP16_C929__CTRL; - isp16_enable_port = ISP16_C929__ENABLE_PORT; - - /* read' and write' are a special read and write, respectively */ - - /* read' ISP16_CTRL_PORT and save */ - ctrl = ISP16_IN( ISP16_CTRL_PORT ); - - /* write' zero to the ctrl port and get response */ - ISP16_OUT( ISP16_CTRL_PORT, 0 ); - tmp = ISP16_IN( ISP16_CTRL_PORT ); - - if ( tmp != 2 ) /* isp16 with 82C929 not detected */ - return(-1); - - /* restore ctrl port value */ - ISP16_OUT( ISP16_CTRL_PORT, ctrl ); - - return(2); -} - -static short -isp16_cdi_config( int base, u_char drive_type, int irq, int dma ) -{ - u_char base_code; - u_char irq_code; - u_char dma_code; - u_char i; - - if ( (drive_type == ISP16_MITSUMI) && (dma != 0) ) - printk( "Mitsumi cdrom drive has no dma support.\n" ); - - switch (base) { - case 0x340: base_code = ISP16_BASE_340; break; - case 0x330: base_code = ISP16_BASE_330; break; - case 0x360: base_code = ISP16_BASE_360; break; - case 0x320: base_code = ISP16_BASE_320; break; - default: - printk( "Base address 0x%03X not supported by cdrom interface on ISP16.\n", base ); - return(-1); - } - switch (irq) { - case 0: irq_code = ISP16_IRQ_X; break; /* disable irq */ - case 5: irq_code = ISP16_IRQ_5; - printk( "Irq 5 shouldn't be used by cdrom interface on ISP16," - " due to possible conflicts with the soundcard.\n"); - break; - case 7: irq_code = ISP16_IRQ_7; - printk( "Irq 7 shouldn't be used by cdrom interface on ISP16," - " due to possible conflicts with the soundcard.\n"); - break; - case 3: irq_code = ISP16_IRQ_3; break; - case 9: irq_code = ISP16_IRQ_9; break; - case 10: irq_code = ISP16_IRQ_10; break; - case 11: irq_code = ISP16_IRQ_11; break; - default: - printk( "Irq %d not supported by cdrom interface on ISP16.\n", irq ); - return(-1); - } - switch (dma) { - case 0: dma_code = ISP16_DMA_X; break; /* disable dma */ - case 1: printk( "Dma 1 cannot be used by cdrom interface on ISP16," - " due to conflict with the soundcard.\n"); - return(-1); break; - case 3: dma_code = ISP16_DMA_3; break; - case 5: dma_code = ISP16_DMA_5; break; - case 6: dma_code = ISP16_DMA_6; break; - case 7: dma_code = ISP16_DMA_7; break; - default: - printk( "Dma %d not supported by cdrom interface on ISP16.\n", dma ); - return(-1); - } - - if ( drive_type != ISP16_SONY && drive_type != ISP16_PANASONIC0 && - drive_type != ISP16_PANASONIC1 && drive_type != ISP16_SANYO0 && - drive_type != ISP16_SANYO1 && drive_type != ISP16_MITSUMI && - drive_type != ISP16_DRIVE_X ) { - printk( "Drive type (code 0x%02X) not supported by cdrom" - " interface on ISP16.\n", drive_type ); - return(-1); - } - - /* set type of interface */ - i = ISP16_IN(ISP16_DRIVE_SET_PORT) & ISP16_DRIVE_SET_MASK; /* clear some bits */ - ISP16_OUT( ISP16_DRIVE_SET_PORT, i|drive_type ); - - /* enable cdrom on interface with 82C929 chip */ - if ( isp16_type > 1 ) - ISP16_OUT( isp16_enable_port, ISP16_ENABLE_CDROM ); - - /* set base address, irq and dma */ - i = ISP16_IN(ISP16_IO_SET_PORT) & ISP16_IO_SET_MASK; /* keep some bits */ - ISP16_OUT( ISP16_IO_SET_PORT, i|base_code|irq_code|dma_code ); - - return(0); -} - -static void isp16_sound_config( void ) -{ - int i; - u_char saved; - - saved = ISP16_IN( 0xF8D ) & 0x8F; - - ISP16_OUT( 0xF8D, 0x40 ); - - /* - * Now we should wait for a while... - */ - for( i = 16*1024; i--; ); - - ISP16_OUT( 0xF8D, saved ); - - ISP16_OUT( 0xF91, 0x1B ); - - for( i = 5*64*1024; i != 0; i-- ) - if( !( inb( 0x534 ) & 0x80 ) ) break; - - if( i > 0 ) { - saved = ( inb( 0x534 ) & 0xE0 ) | 0x0A; - outb( saved, 0x534 ); - - special_mask = ( inb( 0x535 ) >> 4 ) & 0x08; - - saved = ( inb( 0x534 ) & 0xE0 ) | 0x0C; - outb( saved, 0x534 ); - - switch( inb( 0x535 ) ) { - case 0x09: - case 0x0A: - special_mask |= 0x05; - break; - case 0x8A: - special_mask = 0x0F; - break; - default: - i = 0; - } - } - if ( i == 0 ) { - printk( "Strange MediaMagic, but\n" ); - } - else { - printk( "Conf:" ); - saved = inb( 0x534 ) & 0xE0; - for( i = 0; i < 16; i++ ) { - outb( 0x20 | ( u_char )i, 0x534 ); - outb( defaults[i], 0x535 ); - } - for ( i = 0; i < 16; i++ ) { - outb( 0x20 | ( u_char )i, 0x534 ); - saved = inb( 0x535 ); - printk( " %02X", saved ); - } - printk( "\n" ); - } - - ISP16_OUT( 0xF91, 0xA0 | special_mask ); - - /* - * The following have no explaination yet. - */ - ISP16_OUT( 0xF90, 0xA2 ); - ISP16_OUT( 0xF92, 0x03 ); - - /* - * Turn general sound on and set total volume. - */ - ISP16_OUT( 0xF93, 0x0A ); - -/* - outb( 0x04, 0x224 ); - saved = inb( 0x225 ); - outb( 0x04, 0x224 ); - outb( saved, 0x225 ); -*/ - -} diff --git a/drivers/char/cyclades.c b/drivers/char/cyclades.c index 2258ae1a5e63..21dfc2e2f16a 100644 --- a/drivers/char/cyclades.c +++ b/drivers/char/cyclades.c @@ -2376,7 +2376,7 @@ cy_close(struct tty_struct * tty, struct file * filp) if (info->flags & ASYNC_CALLOUT_ACTIVE) info->callout_termios = *tty->termios; if (info->flags & ASYNC_INITIALIZED) - tty_wait_until_sent(tty, 3000); /* 30 seconds timeout */ + tty_wait_until_sent(tty, 30*HZ); /* 30 seconds timeout */ shutdown(info); if (tty->driver.flush_buffer) tty->driver.flush_buffer(tty); diff --git a/drivers/char/lp.c b/drivers/char/lp.c index 96a8532adbba..8ddd95d53067 100644 --- a/drivers/char/lp.c +++ b/drivers/char/lp.c @@ -602,7 +602,9 @@ int lp_init(void) { int offset = 0; int count = 0; +#ifdef MODULE int failed = 0; +#endif if (register_chrdev(LP_MAJOR,"lp",&lp_fops)) { printk("lp: unable to get major %d\n", LP_MAJOR); diff --git a/drivers/char/pty.c b/drivers/char/pty.c index e798ebc7e435..79e0d0bc916c 100644 --- a/drivers/char/pty.c +++ b/drivers/char/pty.c @@ -195,9 +195,13 @@ int pty_open(struct tty_struct *tty, struct file * filp) tty->driver_data = pty; if (!tmp_buf) { - tmp_buf = (unsigned char *) get_free_page(GFP_KERNEL); - if (!tmp_buf) - return -ENOMEM; + unsigned long page = get_free_page(GFP_KERNEL); + if (!tmp_buf) { + if (!page) + return -ENOMEM; + tmp_buf = (unsigned char *) page; + } else + free_page(page); } if (tty->driver.subtype == PTY_TYPE_SLAVE) diff --git a/drivers/char/tga.c b/drivers/char/tga.c index f8ba50b12363..9556fb45b74d 100644 --- a/drivers/char/tga.c +++ b/drivers/char/tga.c @@ -328,7 +328,6 @@ get_scrmem(int currcons) { memcpyw((unsigned short *)vc_scrbuf[currcons], (unsigned short *)origin, video_screen_size); - __scrollback_mode = 0 ; origin = video_mem_start = (unsigned long)vc_scrbuf[currcons]; scr_end = video_mem_end = video_mem_start + video_screen_size; pos = origin + y*video_size_row + (x<<1); diff --git a/drivers/net/Config.in b/drivers/net/Config.in index 6160448c73e3..cb843d30f771 100644 --- a/drivers/net/Config.in +++ b/drivers/net/Config.in @@ -14,6 +14,14 @@ fi tristate 'Z8530 SCC kiss emulation driver for AX.25' CONFIG_SCC tristate 'PLIP (parallel port) support' CONFIG_PLIP tristate 'EQL (serial line load balancing) support' CONFIG_EQUALIZER + +tristate 'FRAD (Frame Relay Access Device) support' CONFIG_FRAD +if [ "$CONFIG_FRAD" = "y" -o "$CONFIG_FRAD" = "m" ]; then + int ' Max open DLCI' CONFIG_DLCI_COUNT 24 + int ' Max DLCI per device' CONFIG_DLCI_MAX 8 + tristate ' Sangoma S502A FRAD support' CONFIG_SDLA +fi + bool 'Do you want to be offered ALPHA test drivers' CONFIG_NET_ALPHA bool 'Western Digital/SMC cards' CONFIG_NET_VENDOR_SMC if [ "$CONFIG_NET_VENDOR_SMC" = "y" ]; then diff --git a/drivers/net/Makefile b/drivers/net/Makefile index b5c15b9d4da8..be097cb21c6f 100644 --- a/drivers/net/Makefile +++ b/drivers/net/Makefile @@ -419,6 +419,22 @@ else endif endif +ifeq ($(CONFIG_SDLA),y) +L_OBJS += sdla.o +else + ifeq ($(CONFIG_SDLA),m) + M_OBJS += sdla.o + endif +endif + +ifeq ($(CONFIG_FRAD),y) +L_OBJS += dlci.o +else + ifeq ($(CONFIG_FRAD),m) + M_OBJS += dlci.o + endif +endif + include $(TOPDIR)/Rules.make clean: @@ -475,3 +491,8 @@ lance.o: lance.c CONFIG $(CC) $(CPPFLAGS) $(CFLAGS) $(LANCE_OPTS) -c $< 8390.o: 8390.c 8390.h CONFIG + +sdla.o: sdla.c CONFIG + +dlci.o: dlci.c CONFIG + diff --git a/drivers/net/Space.c b/drivers/net/Space.c index f6a7c17dd91b..1da81e785862 100644 --- a/drivers/net/Space.c +++ b/drivers/net/Space.c @@ -188,6 +188,22 @@ ethif_probe(struct device *dev) return 0; } +#ifdef CONFIG_SDLA + extern int sdla_init(struct device *); + static struct device sdla0_dev = { "sdla0", 0, 0, 0, 0, 0, 0, 0, 0, 0, NEXT_DEV, sdla_init, }; + +# undef NEXT_DEV +# define NEXT_DEV (&sdla0_dev) +#endif + +/* This must be AFTER the various FRADs so it initializes FIRST! */ + +#ifdef CONFIG_FRAD + extern int dlci_init(struct device *); + static struct device dlci_dev = { "dlci", 0, 0, 0, 0, 0, 0, 0, 0, 0, NEXT_DEV, dlci_init, }; +# undef NEXT_DEV +# define NEXT_DEV (&dlci_dev) +#endif #ifdef CONFIG_NETROM extern int nr_init(struct device *); @@ -366,7 +382,7 @@ struct device eql_dev = { #endif #endif - + extern int loopback_init(struct device *dev); struct device loopback_dev = { "lo", /* Software Loopback interface */ diff --git a/drivers/net/bsd_comp.c b/drivers/net/bsd_comp.c index 9aa8785e0dc2..0ed43d905d42 100644 --- a/drivers/net/bsd_comp.c +++ b/drivers/net/bsd_comp.c @@ -78,7 +78,7 @@ #include #include -#include +#include #include #include @@ -92,9 +92,9 @@ #include #endif -#include -#include -#include +#include +#include +#include #undef PACKETPTR #define PACKETPTR 1 diff --git a/drivers/net/de4x5.c b/drivers/net/de4x5.c index e446f8e929d5..6c2578385c6e 100644 --- a/drivers/net/de4x5.c +++ b/drivers/net/de4x5.c @@ -176,11 +176,17 @@ Changed driver to autprobe 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. ========================================================================= */ -static const char *version = "de4x5.c:v0.40 96/3/5 davies@wanton.lkg.dec.com\n"; +static const char *version = "de4x5.c:v0.41 96/3/21 davies@wanton.lkg.dec.com\n"; #include @@ -255,7 +261,7 @@ static struct phy_table phy_info[] = { ** Define special SROM detection cases */ static c_char enet_det[][ETH_ALEN] = { - {0x00, 0x00, 0x0c, 0x00, 0x00, 0x00} + {0x00, 0x00, 0xc0, 0x00, 0x00, 0x00} }; #define SMC 1 @@ -897,7 +903,8 @@ de4x5_open(struct device *dev) de4x5_dbg_open(dev); - if (request_irq(dev->irq, (void *)de4x5_interrupt, 0, lp->adapter_name, dev)) { + if (request_irq(dev->irq, (void *)de4x5_interrupt, SA_SHIRQ, + lp->adapter_name, dev)) { printk("de4x5_open(): Requested IRQ%d is busy\n",dev->irq); status = -EAGAIN; } else { @@ -1577,7 +1584,7 @@ static void pci_probe(struct device *dev, u_long ioaddr) u_int iobase; struct bus_type *lp = &bus; - if (!ioaddr && autoprobed) return; /* Been here before ! */ + if ((!ioaddr || !loading_module) && autoprobed) return; if (!pcibios_present()) return; /* No PCI bus in this machine! */ @@ -2811,8 +2818,11 @@ static int PCI_signature(char *name, struct bus_type *lp) if (i == siglen) { if (dec_only) { *name = '\0'; - } else { - strcpy(name, "UNKNOWN"); + } else { /* Use chip name to avoid confusion */ + strcpy(name, (((lp->chipset == DC21040) ? "DC21040" : + ((lp->chipset == DC21041) ? "DC21041" : + ((lp->chipset == DC21140) ? "DC21140" : "UNKNOWN" + ))))); } } @@ -2885,12 +2895,12 @@ static int get_hw_addr(struct device *dev) chksum = (u_char) tmp; while ((tmp = inl(DE4X5_APROM)) < 0); chksum |= (u_short) (tmp << 8); - if (k != chksum) status = -1; + if ((k != chksum) && (dec_only)) status = -1; } } else { chksum = (u_char) inb(EISA_APROM); chksum |= (u_short) (inb(EISA_APROM) << 8); - if (k != chksum) status = -1; + if ((k != chksum) && (dec_only)) status = -1; } return status; diff --git a/drivers/net/dlci.c b/drivers/net/dlci.c new file mode 100644 index 000000000000..94213bdf9eaa --- /dev/null +++ b/drivers/net/dlci.c @@ -0,0 +1,609 @@ +/* + * DLCI Implementation of Frame Relay protocol for Linux, according to + * RFC 1490. This generic device provides en/decapsulation for an + * underlying hardware driver. Routes & IPs are assigned to these + * interfaces. Requires 'dlcicfg' program to create usable + * interfaces, the initial one, 'dlci' is for IOCTL use only. + * + * Version: @(#)dlci.c 0.10 23 Mar 1996 + * + * Author: Mike McLagan + * + * 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. + */ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include + +static const char *devname = "dlci"; +static const char *version = "DLCI driver v0.10, 23 Mar 1996, mike.mclagan@linux.org"; + +static struct device *open_dev[CONFIG_DLCI_COUNT]; + +static char *basename[16]; + +int dlci_init(struct device *dev); + +/* allow FRAD's to register their name as a valid FRAD */ +int register_frad(const char *name) +{ + int i; + + if (!name) + return(-EINVAL); + + for (i=0;ipriv; + + hdr.control = FRAD_I_UI; + switch(type) + { + case ETH_P_IP: + hdr.pad = FRAD_P_IP; + hlen = sizeof(hdr.control) + sizeof(hdr.pad); + break; + + /* feel free to add other types, if necessary */ + + default: + hdr.pad = FRAD_P_PADDING; + hdr.NLPID = FRAD_P_SNAP; + memset(hdr.OUI, 0, sizeof(hdr.OUI)); + hdr.PID = type; + hlen = sizeof(hdr); + break; + } + + dest = skb_push(skb, hlen); + if (!dest) + return(0); + + memcpy(dest, &hdr, hlen); + + return(hlen); +} + +static void dlci_receive(struct sk_buff *skb, struct device *dev) +{ + struct dlci_local *dlp; + struct fradhdr *hdr; + int process, header; + + dlp = dev->priv; + hdr = (struct fradhdr *) skb->data; + process = 0; + header = 0; + skb->dev = dev; + + if (hdr->control != FRAD_I_UI) + { + printk(KERN_NOTICE "%s: Invalid header flag 0x%02X.\n", dev->name, hdr->control); + dlp->stats.rx_errors++; + } + else + switch(hdr->pad) + { + case FRAD_P_PADDING: + if (hdr->NLPID != FRAD_P_SNAP) + { + printk(KERN_NOTICE "%s: Unsupported NLPID 0x%02X.\n", dev->name, hdr->NLPID); + dlp->stats.rx_errors++; + break; + } + + if (hdr->OUI[0] + hdr->OUI[1] + hdr->OUI[2] != 0) + { + printk(KERN_NOTICE "%s: Unsupported organizationally unique identifier 0x%02X-%02X-%02X.\n", dev->name, hdr->OUI[0], hdr->OUI[1], hdr->OUI[2]); + dlp->stats.rx_errors++; + break; + } + + /* at this point, it's an EtherType frame */ + header = sizeof(struct fradhdr); + skb->protocol = htons(hdr->PID); + process = 1; + break; + + case FRAD_P_IP: + header = sizeof(hdr->control) + sizeof(hdr->pad); + skb->protocol = htons(ETH_P_IP); + process = 1; + break; + + case FRAD_P_SNAP: + case FRAD_P_Q933: + case FRAD_P_CLNP: + printk(KERN_NOTICE "%s: Unsupported NLPID 0x%02X.\n", dev->name, hdr->pad); + dlp->stats.rx_errors++; + break; + + default: + printk(KERN_NOTICE "%s: Invalid pad byte 0x%02X.\n", dev->name, hdr->pad); + dlp->stats.rx_errors++; + break; + } + + if (process) + { + /* we've set up the protocol, so discard the header */ + skb->mac.raw = skb->data; + skb_pull(skb, header); + netif_rx(skb); + dlp->stats.rx_packets++; + } + else + dev_kfree_skb(skb, FREE_WRITE); +} + +static int dlci_transmit(struct sk_buff *skb, struct device *dev) +{ + struct dlci_local *dlp; + int ret; + + ret = 0; + + if (!skb || !dev) + return(0); + + if (dev->tbusy) + return(1); + + dlp = dev->priv; + + if (set_bit(0, (void*)&dev->tbusy) != 0) + printk(KERN_WARNING "%s: transmitter access conflict.\n", dev->name); + else + { + ret = dlp->slave->hard_start_xmit(skb, dlp->slave); + if (ret) + dlp->stats.tx_errors++; + else + dlp->stats.tx_packets++; + + /* per Alan Cox, always return 0, let the slave free the packet */ + ret = 0; + dev->tbusy = 0; + } + + return(ret); +} + +int dlci_add(struct dlci_add *new) +{ + struct device *master, *slave; + struct dlci_local *dlp; + struct frad_local *flp; + struct dlci_add dlci; + int err, i; + char buf[10]; + + err = verify_area(VERIFY_READ, new, sizeof(*new)); + if (err) + return(err); + + memcpy_fromfs(&dlci, new, sizeof(dlci)); + + /* validate slave device */ + slave = dev_get(dlci.devname); + if (!slave) + return(-ENODEV); + + if (slave->type != ARPHRD_FRAD) + return(-EINVAL); + + /* check for registration */ + for (i=0;i strlen(basename[i]))) + break; + + if (i == sizeof(basename) / sizeof(char *)) + return(-EINVAL); + + /* check for too many open devices : should this be dynamic ? */ + for(i=0;iname = kmalloc(strlen(buf), GFP_KERNEL); + + if (!master->name) + { + kfree(master); + return(-ENOMEM); + } + + strcpy(master->name, buf); + master->init = dlci_init; + master->flags = 0; + + err = register_netdev(master); + if (err < 0) + { + kfree(master->name); + kfree(master); + return(err); + } + + *(short *)(master->dev_addr) = dlci.dlci; + + dlp = (struct dlci_local *) master->priv; + dlp->slave = slave; + + flp = slave->priv; + err = flp ? (*flp->assoc)(slave, master) : -EINVAL; + if (err < 0) + { + unregister_netdev(master); + kfree(master->priv); + kfree(master->name); + kfree(master); + return(err); + } + + memcpy_tofs(new->devname, buf, strlen(buf) + 1); + open_dev[i] = master; + + MOD_INC_USE_COUNT; + + return(0); +} + +int dlci_del(struct device *master) +{ + struct dlci_local *dlp; + struct frad_local *flp; + struct device *slave; + int i, err; + + if (master->start) + return(-EBUSY); + + dlp = master->priv; + slave = dlp->slave; + flp = slave->priv; + + err = (*flp->deassoc)(slave, master); + if (err) + return(err); + + unregister_netdev(master); + + for(i=0;ipriv); + kfree(master->name); + kfree(master); + + MOD_DEC_USE_COUNT; + + return(0); +} + +int dlci_config(struct device *dev, struct dlci_conf *conf, int get) +{ + struct dlci_conf config; + struct dlci_local *dlp; + struct frad_local *flp; + int err; + + dlp = dev->priv; + + flp = dlp->slave->priv; + + if (!get) + { + memcpy_fromfs(&config, conf, sizeof(struct dlci_conf)); + if (config.flags & ~DLCI_VALID_FLAGS) + return(-EINVAL); + memcpy(&dlp->config, &config, sizeof(struct dlci_conf)); + dlp->configured = 1; + } + + err = (*flp->dlci_conf)(dlp->slave, dev, get); + if (err) + return(err); + + if (get) + memcpy_tofs(conf, &dlp->config, sizeof(struct dlci_conf)); + + return(0); +} + +int dlci_ioctl(struct device *dev, struct ifreq *ifr, int cmd) +{ + struct dlci_local *dlp; + + if (!suser()) + return(-EPERM); + + dlp = dev->priv; + + switch(cmd) + { + case DLCI_GET_SLAVE: + if (!*(short *)(dev->dev_addr)) + return(-EINVAL); + + strcpy(ifr->ifr_slave, dlp->slave->name); + break; + + case DLCI_DEVADD: + /* can only add on the primary device */ + if (*(short *)(dev->dev_addr)) + return(-EINVAL); + + return(dlci_add((struct dlci_add *) ifr->ifr_data)); + break; + + case DLCI_DEVDEL: + /* can't delete the primary device */ + if (!*(short *)(dev->dev_addr)) + return(-EINVAL); + + if (dev->start) + return(-EBUSY); + + return(dlci_del(dev)); + break; + + case DLCI_GET_CONF: + case DLCI_SET_CONF: + if (!*(short *)(dev->dev_addr)) + return(-EINVAL); + + return(dlci_config(dev, (struct dlci_conf *) ifr->ifr_data, cmd == DLCI_GET_CONF)); + break; + + default: + return(-EOPNOTSUPP); + } + return(0); +} + +static int dlci_change_mtu(struct device *dev, int new_mtu) +{ + struct dlci_local *dlp; + + dlp = dev->priv; + + return((*dlp->slave->change_mtu)(dlp->slave, new_mtu)); +} + +static int dlci_open(struct device *dev) +{ + struct dlci_local *dlp; + struct frad_local *flp; + int err; + + dlp = dev->priv; + + if (!*(short *)(dev->dev_addr)) + return(-EINVAL); + + if (!dlp->slave->start) + return(-ENOTCONN); + + dev->flags = 0; + dev->tbusy = 0; + dev->interrupt = 0; + dev->start = 1; + + flp = dlp->slave->priv; + err = (*flp->activate)(dlp->slave, dev); + if (err) + return(err); + + return 0; +} + +static int dlci_close(struct device *dev) +{ + struct dlci_local *dlp; + struct frad_local *flp; + int err; + + dlp = dev->priv; + + flp = dlp->slave->priv; + err = (*flp->deactivate)(dlp->slave, dev); + + dev->start = 0; + + return 0; +} + +static struct enet_statistics *dlci_get_stats(struct device *dev) +{ + struct dlci_local *dlp; + + dlp = dev->priv; + + return(&dlp->stats); +} + +int dlci_init(struct device *dev) +{ + struct dlci_local *dlp; + int i; + + dev->priv = kmalloc(sizeof(struct dlci_local), GFP_KERNEL); + if (!dev->priv) + return(-ENOMEM); + + memset(dev->priv, 0, sizeof(struct dlci_local)); + dlp = dev->priv; + + dev->flags = 0; + dev->open = dlci_open; + dev->stop = dlci_close; + dev->do_ioctl = dlci_ioctl; + dev->hard_start_xmit = dlci_transmit; + dev->hard_header = dlci_header; + dev->get_stats = dlci_get_stats; + dev->change_mtu = dlci_change_mtu; + + dlp->receive = dlci_receive; + + dev->type = ARPHRD_DLCI; + dev->family = AF_INET; + dev->hard_header_len = sizeof(struct fradhdr); + dev->pa_alen = sizeof(unsigned long); + + memset(dev->dev_addr, 0, sizeof(dev->dev_addr)); + + for (i = 0; i < DEV_NUMBUFFS; i++) + skb_queue_head_init(&dev->buffs[i]); + + return(0); +} + +int dlci_setup(void) +{ + int i; + + printk("%s.\n", version); + + for(i=0;ipriv; + flp = open_dev[i]->slave->priv; + + if (open_dev[i]->start) + { + if (flp->deactivate) + (*flp->deactivate)(open_dev[i]->slave, open_dev[i]); + open_dev[i]->start = 0; + } + + (*flp->deassoc)(open_dev[i]->slave, open_dev[i]); + kfree(open_dev[i]->priv); + kfree(open_dev[i]->name); + kfree(open_dev[i]); + open_dev[i] = NULL; + } + + if (dlci.priv) + kfree(dlci.priv); +} +#endif /* MODULE */ diff --git a/drivers/net/ibmtr.c b/drivers/net/ibmtr.c index 34842d335ce8..ebed939d70e0 100644 --- a/drivers/net/ibmtr.c +++ b/drivers/net/ibmtr.c @@ -1,14 +1,14 @@ /* ibmtr.c: A shared-memory IBM Token Ring 16/4 driver for linux */ /* - Written 1993 by Mark Swanson and Peter De Schrijver. - This software may be used and distributed according to the terms - of the GNU Public License, incorporated herein by reference. + Written 1993 by Mark Swanson and Peter De Schrijver. + This software may be used and distributed according to the terms + of the GNU Public License, incorporated herein by reference. - This device driver should work with Any IBM Token Ring Card that does - not use DMA. + This device driver should work with Any IBM Token Ring Card that does + not use DMA. - I used Donald Becker's (becker@super.org) device driver work - as a base for most of my initial work. + I used Donald Becker's (becker@super.org) device driver work + as a base for most of my initial work. */ /* @@ -34,6 +34,12 @@ - removed redundant information display - some code reworking + Changes by Michel Lespinasse (walken@via.ecp.fr), + Yann Doussot (doussot@via.ecp.fr) and Pascal Andre (andre@via.ecp.fr) + (February 18, 1996) : + - modified shared memory and mmio access port the driver to + alpha platform (structure access -> readb/writeb) + Chagnes by Steve Kipisz (bungy@ibm.net or kipisz@vnet.ibm.com) (January 18 1996): - swapped WWOR and WWCR in ibmtr.h @@ -69,26 +75,29 @@ /* changes the output format of driver initialisation */ #define TR_NEWFORMAT 1 +#define TR_VERBOSE 0 /* some 95 OS send many non UI frame; this allow removing the warning */ #define TR_FILTERNONUI 1 /* version and credits */ -static const char *version = "ibmtr.c: v1.3.24 8/7/94 Peter De Schrijver and Mark Swanson\n" -" modified 10/3/94 DW Morris, 3/9/95 F Farid and P Andre, 9/7/95 P Andre\n"; - +static const char *version = +"ibmtr.c: v1.3.57 8/7/94 Peter De Schrijver and Mark Swanson\n" +" modified 10/3/94 DW Morris, modified at VIA, ECP, France\n" +" (3/9/95 F Farid and P Andre, 9/7/95 PA and 2/20/95 ML/PA/YD)\n"; + static char pcchannelid[]={0x05, 0x00, 0x04, 0x09, - 0x04, 0x03, 0x04, 0x0f, - 0x03, 0x06, 0x03, 0x01, - 0x03, 0x01, 0x03, 0x00, - 0x03, 0x09, 0x03, 0x09, - 0x03, 0x00, 0x02, 0x00}; + 0x04, 0x03, 0x04, 0x0f, + 0x03, 0x06, 0x03, 0x01, + 0x03, 0x01, 0x03, 0x00, + 0x03, 0x09, 0x03, 0x09, + 0x03, 0x00, 0x02, 0x00}; static char mcchannelid[]={0x04, 0x0d, 0x04, 0x01, - 0x05, 0x02, 0x05, 0x03, - 0x03, 0x06, 0x03, 0x03, - 0x05, 0x08, 0x03, 0x04, - 0x03, 0x05, 0x03, 0x01, - 0x03, 0x08, 0x02, 0x00}; + 0x05, 0x02, 0x05, 0x03, + 0x03, 0x06, 0x03, 0x03, + 0x05, 0x08, 0x03, 0x04, + 0x03, 0x05, 0x03, 0x01, + 0x03, 0x08, 0x02, 0x00}; #include #include @@ -114,29 +123,21 @@ static char mcchannelid[]={0x04, 0x0d, 0x04, 0x01, #define DPRINTK(format, args...) printk("%s: " format, dev->name , ## args) #define DPRINTD(format, args...) DummyCall("%s: " format, dev->name , ## args) -#ifdef TR_NEWFORMAT +#if TR_NEWFORMAT /* this allows displaying full adapter information */ const char *channel_def[] = { "ISA", "MCA", "ISA P&P" }; + char *adapter_def(char type) { - switch (type) - { - case 0xF : return "Adapter/A"; - case 0xE : return "16/4 Adapter/II"; - default : return "adapter"; - }; + switch (type) { + case 0xF : return "Adapter/A"; + case 0xE : return "16/4 Adapter/II"; + default : return "adapter"; + }; }; #endif -#if 0 -struct tok_info tok_info1; /* WARNING: this area must be replicated - or 'malloced' to support > 1 adapter */ - -static struct wait_queue *wait_for_tok_int=NULL, *wait_for_reset; -void (*do_tok_int)(struct device *dev)=NULL; -#endif - -#ifndef TR_NEWFORMAT +#if !TR_NEWFORMAT unsigned char ibmtr_debug_trace=1; /* Patch or otherwise alter to control tokenring tracing. */ #else @@ -145,8 +146,8 @@ unsigned char ibmtr_debug_trace=0; #define TRC_INIT 0x01 /* Trace initialization & PROBEs */ #define TRC_INITV 0x02 /* verbose init trace points */ -static short TokBaseAddrs[]={MMIOStartLocP, /* Addr-s to scan */ - MMIOStartLocA}; +/* addresses to scan */ +static short TokBaseAddrs[] = { MMIOStartLocP, MMIOStartLocA }; int tok_probe(struct device *dev); @@ -170,17 +171,29 @@ static struct enet_statistics * tok_get_stats(struct device *dev); static struct timer_list tr_timer={NULL,NULL,0,0L,tok_open_adapter}; +#if 0 int DummyCallCount=0; /* This routine combined with the #DEFINE DPRINTD serves to workaround the gcc apparent bug. in tr_tx() */ -static void DummyCall(const char * fmt,...) {DummyCallCount++;return;} +static void DummyCall(const char * fmt,...) +{ DummyCallCount++; return; } +#endif static void PrtChanID(char *pcid, short stride) { - short i, j; - for (i=0,j=0;i<24;i++,j=j+stride) printk("%1x",((int) pcid[j])&0x0f); - printk("\n"); + short i, j; + for (i=0, j=0; i<24; i++, j+=stride) + printk("%1x", ((int) pcid[j]) & 0x0f); + printk("\n"); +} + +static void HWPrtChanID (__u32 pcid, short stride) +{ + short i, j; + for (i=0, j=0; i<24; i++, j+=stride) + printk("%1x", ((int)readb(pcid + j)) & 0x0f); + printk("\n"); } /* tok_probe(): Routine specified in the network device structure @@ -196,1147 +209,1232 @@ static void PrtChanID(char *pcid, short stride) { int tok_probe(struct device *dev) { + unsigned char segment=0, intr=0, irq=0, i=0, j=0, cardpresent=NOTOK,temp=0; + __u32 t_mmio=0; + short PIOaddr=0, iAddr; + struct tok_info *ti=0; + static struct tok_info *badti=0; /* if fail after kmalloc, reuse */ + + static unsigned char Shared_Ram_Base = IBMTR_SHARED_RAM_BASE; + + /* this is the major adapter probe loop. For each call to tok_probe, + we try each remaining entry in TokBaseAddrs[] as a possible + adapter. Once an entry is rejected or assigned, we zero it to + avoid duplicate use or worthless trial for the tok probe call*/ + + for (iAddr=0; + iAddr < (sizeof(TokBaseAddrs)/sizeof(short))&&PIOaddr==0; iAddr++) { + + __u32 cd_chanid; + unsigned char *tchanid, ctemp; + + PIOaddr=TokBaseAddrs[iAddr]; /* address to try */ + TokBaseAddrs[iAddr] = 0; /* (and marked already used */ + if (PIOaddr == 0) continue; /* already tried this addr */ + + /* Make sure PIO address not already assigned + elsewhere before we muck with IO address */ + if (check_region(PIOaddr,TR_IO_EXTENT)) { + if (ibmtr_debug_trace & TRC_INIT) + DPRINTK("check_region(%4hx,%d) failed.\n", PIOaddr, TR_IO_EXTENT); + PIOaddr = 0; + continue; /* clear to flag fail and try next */ + } + /* Query the adapter PIO base port which will return + indication of where MMIO was placed (per tech ref + this assignment is done by BIOS - what is rational for + where it is?). We also have a coded interrupt address. */ + + segment = inb(PIOaddr); + /* out of range values so we'll assume non-existant IO device */ + if (segment < 0x40 || segment > 0xe0) { + PIOaddr = 0; + continue; /* clear to flag fail and try next */ + } + + /* Compute the linear base address of the MMIO area + as LINUX doesn't care about segments */ + t_mmio=(((__u32)(segment & 0xfc) << 11) + 0x80000); + intr = segment & 0x03; /* low bits is coded interrupt # */ + if (ibmtr_debug_trace & TRC_INIT) + DPRINTK("PIOaddr: %4hx seg/intr: %2x mmio base: %08X intr: %d\n", PIOaddr, (int)segment, t_mmio, (int)intr); + + /* Now we will compare expected 'channelid' strings with + what we is there to learn of ISA/MCA or not TR card */ + /* !!!WARNING:!!!! It seems pretty silly to blunder ahead + w/o verification that the mmio address we have found + is valid storage -- perhaps this is tolerable for current + hardware state??? */ + + cd_chanid = (CHANNEL_ID + t_mmio); /* for efficiency */ + tchanid=pcchannelid; + cardpresent=TR_ISA; /* try ISA */ + + /* suboptimize knowing first byte different */ + ctemp = readb(cd_chanid) & 0x0f; + if (ctemp != *tchanid) { /* NOT ISA card, try MCA */ + tchanid=mcchannelid; + cardpresent=TR_MCA; + if (ctemp != *tchanid) /* Neither ISA nor MCA */ + cardpresent=NOTOK; + } + + if (cardpresent != NOTOK) { /* know presumed type, try rest of ID */ + for (i=2,j=1; i<=46; i=i+2,j++) { + if ((readb(cd_chanid+i) & 0x0f) != tchanid[j]) { + cardpresent=NOTOK; /* match failed, not TR card */ + break; + } + } + } + + /* If we have an ISA board check for the ISA P&P version, + as it has different IRQ settings */ + if (cardpresent == TR_ISA && (readb(AIPFID + t_mmio)==0x0e)) + cardpresent=TR_ISAPNP; + + if (cardpresent == NOTOK) { /* "channel_id" did not match, report */ + if (ibmtr_debug_trace & TRC_INIT) { + DPRINTK("Channel ID string not found for PIOaddr: %4hx\n", PIOaddr); + DPRINTK("Expected for ISA: "); PrtChanID(pcchannelid,1); + DPRINTK(" found: "); HWPrtChanID(cd_chanid,2); + DPRINTK("Expected for MCA: "); PrtChanID(mcchannelid,1); + } + PIOaddr = 0; /* all to know not found yet */ + continue; + } + + /* !!!! we could tighten validation by checking the HW Address + against the 1-s complement.. Move the get HW logic to here */ + + } + + /* The search loop has either completed with a presumed TR adapter + or none found. Check situation ... march on if possible */ + + if (PIOaddr == 0) { /* failed to find a valid TR adapter */ + if (ibmtr_debug_trace & TRC_INIT) + DPRINTK("Unable to assign adapter to device.\n"); + return ENODEV; + } + + /*?? Now, allocate some of the pl0 buffers for this driver.. */ + + if (!badti) { + ti = (struct tok_info *)kmalloc(sizeof(struct tok_info), GFP_KERNEL); + if (ti == NULL) return -ENOMEM; + } else { + ti = badti; + badti = NULL; + } /*?? dev->priv = kmalloc(sizeof(struct net_local), GFP_KERNEL); */ + + memset(ti, 0, sizeof(struct tok_info)); - unsigned char segment=0, intr=0, irq=0, i=0, j=0, - cardpresent=NOTOK,temp=0; - unsigned char *t_mmio=0; - short PIOaddr=0, iAddr; - struct tok_info *ti=0; - static struct tok_info *badti=0; /* if fail after kmalloc, reuse */ - - static unsigned char Shared_Ram_Base = IBMTR_SHARED_RAM_BASE; - - /* this is the major adapter probe loop. For each call to tok_probe, - we try each remaining entry in TokBaseAddrs[] as a possible - adapter. Once an entry is rejected or assigned, we zero it to - avoid duplicate use or worthless trial for the tok probe call*/ - - for (iAddr=0; - iAddr < (sizeof(TokBaseAddrs)/sizeof(short))&&PIOaddr==0; - iAddr++) { char *tchanid, *cd_chanid, ctemp; - PIOaddr=TokBaseAddrs[iAddr]; /* address to try */ - TokBaseAddrs[iAddr] = 0; /* (and marked already used */ - if (PIOaddr == 0) continue; /* already tried this addr */ - if ( check_region(PIOaddr,TR_IO_EXTENT) ) { /* Make sure PIO address not - already assigned elsewhere - before we muck with I/O - addresses */ - if (ibmtr_debug_trace & TRC_INIT) - DPRINTK("check_region(%4hx,%d) failed.\n",PIOaddr, TR_IO_EXTENT); - PIOaddr = 0; continue; /* clear to flag fail and try next */ - } - /* Query the adapter PIO base port which will return - indication of where MMIO was placed (per tech ref - this assignment is done by BIOS - what is rational for - where it is?). We also have a coded interrupt address.*/ - - segment = inb(PIOaddr); - if (segment < 0x40 || segment > 0xe0) { /* out of range values - so we will assume non-existant IO dev */ - PIOaddr = 0; continue; /* clear to flag fail and try next */ - } - - /* Compute the linear base address of the MMIO area - as LINUX doesn't care about segments */ - t_mmio=(char *) (((segment & 0xfc) << 11) + 0x80000); - intr = segment & 0x03; /* low bits is coded interrupt # */ - if (ibmtr_debug_trace & TRC_INIT) - DPRINTK("PIOaddr: %4hx seg/intr: %2x mmio base: %p intr: %d\n", - PIOaddr, (int) segment,t_mmio,(int) intr); - /* Now we will compare expected 'channelid' strings with - what we is there to learn of ISA/MCA or not TR card */ - /* !!!WARNING:!!!! It seems pretty silly to blunder ahead - w/o verification that the mmio address we have found - is valid storage -- perhaps this is tolerable for current - hardware state??? */ - cd_chanid = (char *)(CHANNEL_ID + t_mmio); /* for efficiency */ - tchanid=pcchannelid; cardpresent=TR_ISA; /* try ISA ? */ - /* suboptimize knowing first byte different */ - ctemp = (* cd_chanid) & 0x0f; - if ( ctemp != *tchanid) { /* NOT ISA card, try MCA */ - tchanid=mcchannelid; cardpresent=TR_MCA; - if ( ctemp != *tchanid) /* Neither ISA nor MCA */ - cardpresent=NOTOK; - } - if (cardpresent != NOTOK) { /* know presumed type, try rest of ID */ - for (i=2,j=1; i<=46; i=i+2,j++) { - if ( (cd_chanid[i] & 0x0f) != tchanid[j]) { - cardpresent=NOTOK; /* match failed, not TR card */ - break; - } - } - } - - /* If we have an ISA board check for the ISA P&P version, as it has - different IRQ settings */ - if (cardpresent == TR_ISA && (*(AIPFID + t_mmio)==0x0e)) - cardpresent=TR_ISAPNP; - - if (cardpresent == NOTOK) { /* "channel_id" did not match, report */ - if (ibmtr_debug_trace & TRC_INIT) { - DPRINTK("Channel ID string not found for PIOaddr: %4hx\n", - PIOaddr); - DPRINTK("Expected for ISA: "); PrtChanID(pcchannelid,1); - DPRINTK(" found: "); PrtChanID(cd_chanid,2); - DPRINTK("Expected for MCA: "); PrtChanID(mcchannelid,1); - } - PIOaddr = 0; /* all to know not found yet */ - continue; - } - - /* !!!! we could tighten validation by checking the HW Address - against the 1-s complement.. Move the get HW logic to here */ - - } - - /* The search loop has either completed with a presumed TR adapter - or none found. Check situation ... march on if possible */ - - if (PIOaddr == 0) { /* failed to find a valid TR adapter */ - if (ibmtr_debug_trace & TRC_INIT) - DPRINTK("Unable to assign adapter to device.\n"); - return ENODEV; - } - - /*?? Now, allocate some of the pl0 buffers for this driver.. */ - - if (!badti) { - ti = (struct tok_info *)kmalloc(sizeof(struct tok_info), GFP_KERNEL); - if (ti == NULL) - return -ENOMEM; - } else { - ti = badti; badti = NULL; - }/*?? dev->priv = kmalloc(sizeof(struct net_local), GFP_KERNEL); */ - - memset(ti,0,sizeof(struct tok_info)); - - ti->mmio= t_mmio; - - dev->priv = ti; /* this seems like the logical use of the + ti->mmio= t_mmio; + + dev->priv = ti; /* this seems like the logical use of the field ... lets try some empirical tests using the token-info structure -- that should fit with out future hope of multiple adapter support as well /dwm */ - switch (cardpresent) { - case TR_ISA: - if (intr==0) irq=9; /* irq2 really is irq9 */ - if (intr==1) irq=3; - if (intr==2) irq=6; - if (intr==3) irq=7; - ti->global_int_enable=GLOBAL_INT_ENABLE+((irq==9) ? 2 : irq); - ti->sram=NULL; -#ifndef TR_NEWFORMAT - DPRINTK("ti->global_int_enable: %04X\n",ti->global_int_enable); + switch (cardpresent) { + case TR_ISA: + if (intr==0) irq=9; /* irq2 really is irq9 */ + if (intr==1) irq=3; + if (intr==2) irq=6; + if (intr==3) irq=7; + ti->global_int_enable=GLOBAL_INT_ENABLE+((irq==9) ? 2 : irq); + ti->sram=0; +#if !TR_NEWFORMAT + DPRINTK("ti->global_int_enable: %04X\n",ti->global_int_enable); #endif - break; - case TR_MCA: - if (intr==0) irq=9; - if (intr==1) irq=3; - if (intr==2) irq=10; - if (intr==3) irq=11; - ti->global_int_enable=0; - ti->sram=(unsigned char *)((inb(PIOaddr+ADAPTRESETREL) & 0xfe) - << 12); - break; - case TR_ISAPNP: - if (intr==0) irq=9; - if (intr==1) irq=3; - if (intr==2) irq=10; - if (intr==3) irq=11; - while(!(ti->mmio + ACA_OFFSET + ACA_RW + RRR_EVEN)); - ti->sram=(unsigned char *)((unsigned long)(*(ti->mmio + ACA_OFFSET + ACA_RW + RRR_EVEN)) <<12); - ti->global_int_enable=PIOaddr+ADAPTINTREL; - break; + break; + case TR_MCA: + if (intr==0) irq=9; + if (intr==1) irq=3; + if (intr==2) irq=10; + if (intr==3) irq=11; + ti->global_int_enable=0; + ti->sram=((__u32)(inb(PIOaddr+ADAPTRESETREL) & 0xfe) << 12); + break; + case TR_ISAPNP: + if (intr==0) irq=9; + if (intr==1) irq=3; + if (intr==2) irq=10; + if (intr==3) irq=11; + while(!readb(ti->mmio + ACA_OFFSET + ACA_RW + RRR_EVEN)); + ti->sram=((__u32)readb(ti->mmio + ACA_OFFSET + ACA_RW + RRR_EVEN)<<12); + ti->global_int_enable=PIOaddr+ADAPTINTREL; + break; - } - - if (ibmtr_debug_trace & TRC_INIT) { /* just report int */ - DPRINTK("irq=%d",irq); - if (ibmtr_debug_trace & TRC_INITV) { /* full chat in verbose only */ - DPRINTK(", ti->mmio=%p",ti->mmio); - printk(", segment=%02X",segment); - } - printk(".\n"); - } - - /* Get hw address of token ring card */ -#ifndef TR_NEWFORMAT - DPRINTK("hw address: "); + } + + if (ibmtr_debug_trace & TRC_INIT) { /* just report int */ + DPRINTK("irq=%d",irq); + if (ibmtr_debug_trace & TRC_INITV) { /* full chat in verbose only */ + DPRINTK(", ti->mmio=%08X",ti->mmio); + printk(", segment=%02X",segment); + } + printk(".\n"); + } + + /* Get hw address of token ring card */ +#if !TR_NEWFORMAT + DPRINTK("hw address: "); #endif - j=0; - for (i=0; i<0x18; i=i+2) { - temp = *(char *)((ulong)AIP + (ulong)i + ti->mmio) & 0x0f; /* Tech ref states must do this */ -#ifndef TR_NEWFORMAT - printk("%1X",ti->hw_address[j]=temp); + j=0; + for (i=0; i<0x18; i=i+2) { + /* technical reference states to do this */ + temp = readb(ti->mmio + AIP + i) & 0x0f; +#if !TR_NEWFORMAT + printk("%1X",ti->hw_address[j]=temp); #else - ti->hw_address[j]=temp; + ti->hw_address[j]=temp; #endif - if(j&1) - dev->dev_addr[(j/2)]=ti->hw_address[j]+(ti->hw_address[j-1]<<4); - ++j; - } + if(j&1) + dev->dev_addr[(j/2)]=ti->hw_address[j]+(ti->hw_address[j-1]<<4); + ++j; + } #ifndef TR_NEWFORMAT - printk("\n"); + printk("\n"); #endif + /* get Adapter type: 'F' = Adapter/A, 'E' = 16/4 Adapter II,...*/ + ti->adapter_type = readb(ti->mmio + AIPADAPTYPE); - /* get Adapter type: 'F' = Adapter/A, 'E' = 16/4 Adapter II,...*/ - ti->adapter_type = *(char *)(ti->mmio + AIPADAPTYPE); - - /* get Data Rate: F=4Mb, E=16Mb, D=4Mb & 16Mb ?? */ - ti->data_rate = *(char *)(ti->mmio + AIPDATARATE); + /* get Data Rate: F=4Mb, E=16Mb, D=4Mb & 16Mb ?? */ + ti->data_rate = readb(ti->mmio + AIPDATARATE); - /* Get Early Token Release support?: F=no, E=4Mb, D=16Mb, C=4&16Mb */ - ti->token_release = *(char *)(ti->mmio + AIPEARLYTOKEN); + /* Get Early Token Release support?: F=no, E=4Mb, D=16Mb, C=4&16Mb */ + ti->token_release = readb(ti->mmio + AIPEARLYTOKEN); - /* How much shared RAM is on adapter ? */ - ti->avail_shared_ram = get_sram_size(ti); + /* How much shared RAM is on adapter ? */ + ti->avail_shared_ram = get_sram_size(ti); - /* We need to set or do a bunch of work here based on previous results.. */ - /* Support paging? What sizes?: F=no, E=16k, D=32k, C=16 & 32k */ - ti->shared_ram_paging = *(char *)(ti->mmio + AIPSHRAMPAGE); + /* We need to set or do a bunch of work here based on previous results.. */ + /* Support paging? What sizes?: F=no, E=16k, D=32k, C=16 & 32k */ + ti->shared_ram_paging = readb(ti->mmio + AIPSHRAMPAGE); /* Available DHB 4Mb size: F=2048, E=4096, D=4464 */ - ti->dhb_size4mb = *(char *) (ti->mmio + AIP4MBDHB); + ti->dhb_size4mb = readb(ti->mmio + AIP4MBDHB); - /* Available DHB 16Mb size: F=2048, E=4096, D=8192, C=16384, B=17960 */ - ti->dhb_size16mb = *(char *)(ti->mmio + AIP16MBDHB); + /* Available DHB 16Mb size: F=2048, E=4096, D=8192, C=16384, B=17960 */ + ti->dhb_size16mb = readb(ti->mmio + AIP16MBDHB); -#ifndef TR_NEWFORMAT - DPRINTK("atype=%x, drate=%x, trel=%x, asram=%dK, srp=%x, dhb(4mb=%x, 16mb=%x)\n",ti->adapter_type, - ti->data_rate, ti->token_release, ti->avail_shared_ram/2, ti->shared_ram_paging, - ti->dhb_size4mb, ti->dhb_size16mb); +#if !TR_NEWFORMAT + DPRINTK("atype=%x, drate=%x, trel=%x, asram=%dK, srp=%x, " + "dhb(4mb=%x, 16mb=%x)\n",ti->adapter_type, + ti->data_rate, ti->token_release, ti->avail_shared_ram/2, + ti->shared_ram_paging, ti->dhb_size4mb, ti->dhb_size16mb); #endif - /* We must figure out how much shared memory space this adapter - will occupy so that if there are two adapters we can fit both - in. Given a choice, we will limit this adapter to 32K. The - maximum space will will use for two adapters is 64K so if the - adapter we are working on demands 64K (it also doesn't support - paging), then only one adapter can be supported. */ - - /* determine how much of total RAM is mapped into PC space */ - ti->mapped_ram_size=1<<(((*(unsigned char *) - (ti->mmio+ ACA_OFFSET + ACA_RW + RRR_ODD))>>2)+4); - ti->page_mask=0; - if (ti->shared_ram_paging == 0xf) { /* No paging in adapter */ - ti->mapped_ram_size = ti->avail_shared_ram; - } else { + /* We must figure out how much shared memory space this adapter + will occupy so that if there are two adapters we can fit both + in. Given a choice, we will limit this adapter to 32K. The + maximum space will will use for two adapters is 64K so if the + adapter we are working on demands 64K (it also doesn't support + paging), then only one adapter can be supported. */ + + /* determine how much of total RAM is mapped into PC space */ + ti->mapped_ram_size=1<<(((readb(ti->mmio+ ACA_OFFSET + ACA_RW + RRR_ODD)) >>2) +4); + ti->page_mask=0; + if (ti->shared_ram_paging == 0xf) { /* No paging in adapter */ + ti->mapped_ram_size = ti->avail_shared_ram; + } else { #ifdef ENABLE_PAGING - unsigned char pg_size; + unsigned char pg_size; #endif -#ifndef TR_NEWFORMAT - DPRINTK("shared ram page size: %dK\n",ti->mapped_ram_size/2); +#if !TR_NEWFORMAT + DPRINTK("shared ram page size: %dK\n",ti->mapped_ram_size/2); #endif #ifdef ENABLE_PAGING - switch(ti->shared_ram_paging) { - case 0xf: - break; - case 0xe: - ti->page_mask=(ti->mapped_ram_size==32) ? 0xc0 : 0; - pg_size=32; /* 16KB page size */ - break; - case 0xd: - ti->page_mask=(ti->mapped_ram_size==64) ? 0x80 : 0; - pg_size=64; /* 32KB page size */ - break; - case 0xc: - ti->page_mask=(ti->mapped_ram_size==32) ? 0xc0 : 0; - ti->page_mask=(ti->mapped_ram_size==64) ? 0x80 : 0; - DPRINTK("Dual size shared RAM page (code=0xC), don't support it!\n"); - /* nb/dwm: I did this because RRR (3,2) bits are documented as - * R/O and I can't find how to select which page size - * Also, the above conditional statement sequence is invalid - * as page_mask will always be set by the second stmt - */ - badti=ti; - break; - default: - DPRINTK("Unknown shared ram paging info %01X\n",ti->shared_ram_paging); - badti=ti; /* bail out if bad code */ - break; - } - if(ti->page_mask) { - if(pg_size > ti->mapped_ram_size) { - DPRINTK("Page size (%d) > mapped ram window (%d), can't page.\n", - pg_size, ti->mapped_ram_size); - ti->page_mask = 0; /* reset paging */ - } else { - ti->mapped_ram_size=ti->avail_shared_ram; /****** ?????????? *******/ - DPRINTK("Shared RAM paging enabled. Page size : %uK\n",((ti->page_mask^ 0xff)+1)>>2); - } - } -#else -#endif - } - - if (cardpresent==TR_ISA) { /* finish figuring the shared RAM address */ - static unsigned char ram_bndry_mask[]={0xfe, 0xfc, 0xf8, 0xf0}; - unsigned char new_base, rrr_32, chk_base, rbm; - rrr_32 = (*(unsigned char *) - (ti->mmio+ ACA_OFFSET + ACA_RW + RRR_ODD))>>2; - rbm = ram_bndry_mask[rrr_32]; - new_base = (Shared_Ram_Base + (~rbm)) & rbm; /* up to boundary */ - chk_base = new_base + (ti->mapped_ram_size>>3); - if (chk_base > (IBMTR_SHARED_RAM_BASE+IBMTR_SHARED_RAM_SIZE)) { - DPRINTK("Shared RAM for this adapter (%05x) exceeds driver" - " limit (%05x), adapter not started.\n", - chk_base<<12, (IBMTR_SHARED_RAM_BASE+ - IBMTR_SHARED_RAM_SIZE)<<12); - badti=ti; - } else { /* seems cool, record what we have figured out */ - ti->sram_base = new_base; - Shared_Ram_Base = new_base; - } - } - - /* dwm: irq and other final setup moved here so if we find other - unrecognized values OR shared ram conflicts, we can still - bail out in a rather benign fashion. */ - - if (badti) return ENODEV; -#ifndef TR_NEWFORMAT - DPRINTK("Using %dK shared RAM\n",ti->mapped_ram_size/2); + switch(ti->shared_ram_paging) { + case 0xf: + break; + case 0xe: + ti->page_mask=(ti->mapped_ram_size==32) ? 0xc0 : 0; + pg_size=32; /* 16KB page size */ + break; + case 0xd: + ti->page_mask=(ti->mapped_ram_size==64) ? 0x80 : 0; + pg_size=64; /* 32KB page size */ + break; + case 0xc: + ti->page_mask=(ti->mapped_ram_size==32) ? 0xc0 : 0; + ti->page_mask=(ti->mapped_ram_size==64) ? 0x80 : 0; + DPRINTK("Dual size shared RAM page (code=0xC), don't support it!\n"); + /* nb/dwm: I did this because RRR (3,2) bits are documented as + R/O and I can't find how to select which page size + Also, the above conditional statement sequence is invalid + as page_mask will always be set by the second stmt */ + badti=ti; + break; + default: + DPRINTK("Unknown shared ram paging info %01X\n",ti->shared_ram_paging); + badti=ti; /* bail out if bad code */ + break; + } + if (ti->page_mask) { + if (pg_size > ti->mapped_ram_size) { + DPRINTK("Page size (%d) > mapped ram window (%d), can't page.\n", + pg_size, ti->mapped_ram_size); + ti->page_mask = 0; /* reset paging */ + } else { + ti->mapped_ram_size=ti->avail_shared_ram; + DPRINTK("Shared RAM paging enabled. Page size : %uK\n", + ((ti->page_mask^ 0xff)+1)>>2); + } #endif + } + + /* finish figuring the shared RAM address */ + if (cardpresent==TR_ISA) { + static unsigned char ram_bndry_mask[]={0xfe, 0xfc, 0xf8, 0xf0}; + unsigned char new_base, rrr_32, chk_base, rbm; + rrr_32 = (readb(ti->mmio+ ACA_OFFSET + ACA_RW + RRR_ODD))>>2; + rbm = ram_bndry_mask[rrr_32]; + new_base = (Shared_Ram_Base + (~rbm)) & rbm; /* up to boundary */ + chk_base = new_base + (ti->mapped_ram_size>>3); + if (chk_base > (IBMTR_SHARED_RAM_BASE+IBMTR_SHARED_RAM_SIZE)) { + DPRINTK("Shared RAM for this adapter (%05x) exceeds driver" + " limit (%05x), adapter not started.\n", + chk_base<<12, (IBMTR_SHARED_RAM_BASE+ + IBMTR_SHARED_RAM_SIZE)<<12); + badti=ti; + } else { /* seems cool, record what we have figured out */ + ti->sram_base = new_base; + Shared_Ram_Base = new_base; + } + } - if (request_irq (dev->irq = irq, &tok_interrupt,0,"IBM TR", NULL) != 0) { - DPRINTK("Could not grab irq %d. Halting Token Ring driver.\n",irq); - badti = ti; /* keep track of unused tok_info */ - return ENODEV; - } - irq2dev_map[irq]=dev; + /* dwm: irq and other final setup moved here so if we find other + unrecognized values OR shared ram conflicts, we can still + bail out in a rather benign fashion. */ - /*?? Now, allocate some of the PIO PORTs for this driver.. */ - request_region(PIOaddr,TR_IO_EXTENT,"ibmtr"); /* record PIOaddr range - as busy */ -#ifndef TR_NEWFORMAT - DPRINTK("%s",version); /* As we have passed card identification, - let the world know we're here! */ -#else - printk("%s",version); - DPRINTK("%s %s found using irq %d, PIOaddr %4hx, %dK shared RAM.\n", - channel_def[cardpresent-1], adapter_def(ti->adapter_type), irq, - PIOaddr, ti->mapped_ram_size/2); - DPRINTK("Hardware address : %02X:%02X:%02X:%02X:%02X:%02X\n", - dev->dev_addr[0], dev->dev_addr[1], dev->dev_addr[2], - dev->dev_addr[3], dev->dev_addr[4], dev->dev_addr[5]); + if (badti) return ENODEV; +#if !TR_NEWFORMAT + DPRINTK("Using %dK shared RAM\n",ti->mapped_ram_size/2); #endif - dev->base_addr=PIOaddr; /* set the value for device */ - - trdev_init(dev); - tok_init_card(dev); + if (request_irq (dev->irq = irq, &tok_interrupt,0,"IBM TR", NULL) != 0) { + DPRINTK("Could not grab irq %d. Halting Token Ring driver.\n",irq); + badti = ti; /* keep track of unused tok_info */ + return ENODEV; + } + irq2dev_map[irq]=dev; + + /*?? Now, allocate some of the PIO PORTs for this driver.. */ + request_region(PIOaddr,TR_IO_EXTENT,"ibmtr"); /* record PIOaddr range + as busy */ +#if !TR_NEWFORMAT + DPRINTK("%s",version); /* As we have passed card identification, + let the world know we're here! */ +#else + printk("%s",version); + DPRINTK("%s %s found using irq %d, PIOaddr %4hx, %dK shared RAM.\n", + channel_def[cardpresent-1], adapter_def(ti->adapter_type), irq, + PIOaddr, ti->mapped_ram_size/2); + DPRINTK("Hardware address : %02X:%02X:%02X:%02X:%02X:%02X\n", + dev->dev_addr[0], dev->dev_addr[1], dev->dev_addr[2], + dev->dev_addr[3], dev->dev_addr[4], dev->dev_addr[5]); +#endif - return 0; /* Return 0 to indicate we have found a Token Ring card. */ + dev->base_addr=PIOaddr; /* set the value for device */ + + dev->open=tok_open; + dev->stop=tok_close; + dev->hard_start_xmit=tok_send_packet; + dev->get_stats = NULL; + dev->get_stats = tok_get_stats; + dev->set_multicast_list = NULL; + tr_setup(dev); + tok_init_card((unsigned long)dev); + + return 0; /* Return 0 to indicate we have found a Token Ring card. */ } /* query the adapter for the size of shared RAM */ -unsigned char get_sram_size(struct tok_info *adapt_info) { - +unsigned char get_sram_size(struct tok_info *adapt_info) +{ + unsigned char avail_sram_code; static unsigned char size_code[]={ 0,16,32,64,127,128 }; - - /* Adapter gives - 'F' -- use RRR bits 3,2 - 'E' -- 8kb 'D' -- 16kb - 'C' -- 32kb 'A' -- 64KB - 'B' - 64KB less 512 bytes at top - (WARNING ... must zero top bytes in INIT */ - - avail_sram_code=0xf-*(adapt_info->mmio + AIPAVAILSHRAM); - if(avail_sram_code) + + /* Adapter gives + 'F' -- use RRR bits 3,2 + 'E' -- 8kb 'D' -- 16kb + 'C' -- 32kb 'A' -- 64KB + 'B' - 64KB less 512 bytes at top + (WARNING ... must zero top bytes in INIT */ + + avail_sram_code=0xf-readb(adapt_info->mmio + AIPAVAILSHRAM); + if (avail_sram_code) return size_code[avail_sram_code]; else /* for code 'F', must compute size from RRR(3,2) bits */ - - return 1<<(((*(unsigned char *) - (adapt_info->mmio+ ACA_OFFSET + ACA_RW + RRR_ODD))>>2)+4); + return 1<<((readb(adapt_info->mmio+ ACA_OFFSET + ACA_RW + RRR_ODD)>>2)+4); } - -int trdev_init(struct device *dev) +static int tok_open(struct device *dev) { - struct tok_info *ti=(struct tok_info *)dev->priv; - - ti->open_status=CLOSED; - - dev->init=tok_init_card; - dev->open=tok_open; - dev->stop=tok_close; - dev->hard_start_xmit=tok_send_packet; - dev->get_stats = NULL; - dev->get_stats = tok_get_stats; - dev->set_multicast_list = NULL; - tr_setup(dev); - - return 0; -} - - -static int tok_open(struct device *dev) { - - struct tok_info *ti=(struct tok_info *)dev->priv; - - if(ti->open_status==CLOSED) { - tok_init_card(dev); - } - - if(ti->open_status==IN_PROGRESS) { - sleep_on(&ti->wait_for_reset); - } + struct tok_info *ti=(struct tok_info *)dev->priv; + + if (ti->open_status==CLOSED) tok_init_card((unsigned long)dev); + + if (ti->open_status==IN_PROGRESS) sleep_on(&ti->wait_for_reset); + + if (ti->open_status==SUCCES) { + dev->tbusy=0; + dev->interrupt=0; + dev->start=1; + /* NEED to see smem size *AND* reset high 512 bytes if needed */ + + MOD_INC_USE_COUNT; + + return 0; + } else return -EAGAIN; - if(ti->open_status==SUCCES) { - dev->tbusy=0; - dev->interrupt=0; - dev->start=1; - /* NEED to see smem size *AND* reset high 512 bytes if - needed */ - - MOD_INC_USE_COUNT; - - return 0; - } - else - return -EAGAIN; - } -static int tok_close(struct device *dev) { - - struct tok_info *ti=(struct tok_info *) dev->priv; - - struct srb_close_adapter *close_adapter=(struct srb_close_adapter *)ti->srb; - - close_adapter->command=DIR_CLOSE_ADAPTER; - *(unsigned char *)(ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD)=CMD_IN_SRB; - - ti->open_status=CLOSED; - +static int tok_close(struct device *dev) +{ + + struct tok_info *ti=(struct tok_info *) dev->priv; + + writeb(DIR_CLOSE_ADAPTER, + ti->srb + offsetof(struct srb_close_adapter, command)); + writeb(CMD_IN_SRB, ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD); + + ti->open_status=CLOSED; + sleep_on(&ti->wait_for_tok_int); - - if(close_adapter->ret_code) - DPRINTK("close adapter failed: %02X\n",close_adapter->ret_code); + if (readb(ti->srb + offsetof(struct srb_close_adapter, ret_code))) + DPRINTK("close adapter failed: %02X\n", + (int)readb(ti->srb + offsetof(struct srb_close_adapter, ret_code))); + MOD_DEC_USE_COUNT; - + return 0; } void tok_interrupt (int irq, void *dev_id, struct pt_regs *regs) { - unsigned char status; - struct tok_info *ti; -/* int irq = -(((struct pt_regs *)reg_ptr)->orig_eax+2); */ - struct device *dev = (struct device *)(irq2dev_map[irq]); -#if 0 - DPRINTK("Int from tok_driver, dev : %p\n",dev); -#endif - ti=(struct tok_info *) dev->priv; - - switch (ti->do_tok_int) { - case NOT_FIRST: - - /* Begin the regular interrupt handler HERE inline to avoid - the extra levels of logic and call depth for the - original solution. */ - - - dev->interrupt=1; - - /* Disable interrupts till processing is finished */ - *(unsigned char *)(ti->mmio + ACA_OFFSET + ACA_RESET + ISRP_EVEN)=(~INT_ENABLE); - - /* Reset interrupt for ISA boards */ - if(ti->global_int_enable) - outb(0,ti->global_int_enable); + struct tok_info *ti; + struct device *dev = (struct device *)(irq2dev_map[irq]); - status=*(unsigned char *)(ti->mmio + ACA_OFFSET + ACA_RW + ISRP_ODD); - -#ifdef PCMCIA - /* Check if the PCMCIA card was pulled. */ - if (status == 0xFF) - { - DPRINTK("PCMCIA card removed.\n"); - dev->interrupt = 0; - return; - } - - /* Check ISRP EVEN too. */ - if ( *(unsigned char *)(ti->mmio + ACA_OFFSET + ACA_RW + ISRP_EVEN) == 0xFF) - { - DPRINTK("PCMCIA card removed.\n"); - dev->interrupt = 0; - return; - } +#if TR_VERBOSE + DPRINTK("Int from tok_driver, dev : %p\n",dev); #endif - - if(status & ADAP_CHK_INT) { - int i; - unsigned char *check_reason=ti->sram + ntohs(*(unsigned short *)(ti->mmio + ACA_OFFSET + ACA_RW +WWCR_EVEN)); - - DPRINTK("adapter check interrupt\n"); - - DPRINTK("8 reason bytes follow: "); - for(i=0;i< 8;i++,check_reason++) - printk("%02X ",*check_reason); - printk("\n"); - - *(unsigned char *)(ti->mmio + ACA_OFFSET + ACA_RESET + ISRP_ODD)=(~ADAP_CHK_INT); - *(unsigned char *)(ti->mmio + ACA_OFFSET + ACA_SET + ISRP_EVEN)=INT_ENABLE; - dev->interrupt=0; - } - - else if((*(unsigned char *)(ti->mmio + ACA_OFFSET + ACA_RW + ISRP_EVEN)) & (TCR_INT + ERR_INT + ACCESS_INT)) { - - DPRINTK("adapter error: ISRP_EVEN : %02x\n", - *(unsigned char *)(ti->mmio + ACA_OFFSET + ACA_RW + ISRP_EVEN)); + + ti=(struct tok_info *) dev->priv; + + switch (ti->do_tok_int) { + + case NOT_FIRST: + + /* Begin the regular interrupt handler HERE inline to avoid + the extra levels of logic and call depth for the + original solution. */ + + dev->interrupt=1; + + /* Disable interrupts till processing is finished */ + writeb((~INT_ENABLE), ti->mmio + ACA_OFFSET + ACA_RESET + ISRP_EVEN); + + /* Reset interrupt for ISA boards */ + if (ti->global_int_enable) + outb(0, ti->global_int_enable); + + status=readb(ti->mmio + ACA_OFFSET + ACA_RW + ISRP_ODD); + + if (status & ADAP_CHK_INT) { + + int i; + __u32 check_reason; + + check_reason=ti->mmio + ntohs(readw(ti->mmio + ACA_OFFSET + ACA_RW +WWCR_EVEN)); + + DPRINTK("Adapter check interrupt\n"); + DPRINTK("8 reason bytes follow: "); + for(i=0; i<8; i++, check_reason++) + printk("%02X ", (int)readb(check_reason)); + printk("\n"); + + writeb((~ADAP_CHK_INT), ti->mmio + ACA_OFFSET + ACA_RESET + ISRP_ODD); + writeb(INT_ENABLE, ti->mmio + ACA_OFFSET + ACA_SET + ISRP_EVEN); + dev->interrupt=0; + + } else if (readb(ti->mmio + ACA_OFFSET + ACA_RW + ISRP_EVEN) + & (TCR_INT | ERR_INT | ACCESS_INT)) { + + DPRINTK("adapter error: ISRP_EVEN : %02x\n", + (int)readb(ti->mmio + ACA_OFFSET + ACA_RW + ISRP_EVEN)); + writeb(~(TCR_INT | ERR_INT | ACCESS_INT), + ti->mmio + ACA_OFFSET + ACA_RESET + ISRP_EVEN); + writeb(INT_ENABLE, ti->mmio + ACA_OFFSET + ACA_SET + ISRP_EVEN); + dev->interrupt=0; + + } else if (status + & (SRB_RESP_INT | ASB_FREE_INT | ARB_CMD_INT | SSB_RESP_INT)) { + /* SRB, ASB, ARB or SSB response */ + + if (status & SRB_RESP_INT) { /* SRB response */ - *(unsigned char *)(ti->mmio + ACA_OFFSET + ACA_RESET + ISRP_EVEN)=~(TCR_INT + ERR_INT + ACCESS_INT); - *(unsigned char *)(ti->mmio + ACA_OFFSET + ACA_SET + ISRP_EVEN)=INT_ENABLE; - dev->interrupt=0; - } + switch(readb(ti->srb)) { /* SRB command check */ - else if(status & (SRB_RESP_INT + ASB_FREE_INT + ARB_CMD_INT + SSB_RESP_INT)) { - - if(status & SRB_RESP_INT) { - switch(*ti->srb) { - case XMIT_DIR_FRAME: { - struct srb_xmit *xmit=(struct srb_xmit *)(ti->srb); - if(xmit->ret_code!=0xff) { - DPRINTK("error on xmit_dir_frame request: %02X\n",xmit->ret_code); - if(ti->current_skb) { - dev_kfree_skb(ti->current_skb, FREE_WRITE); - ti->current_skb=NULL; - } - dev->tbusy=0; - } - } - break; - - case XMIT_UI_FRAME: { - struct srb_xmit *xmit=(struct srb_xmit *)(ti->srb); - if(xmit->ret_code!=0xff) { - DPRINTK("error on xmit_ui_frame request: %02X\n",xmit->ret_code); - if(ti->current_skb) { - dev_kfree_skb(ti->current_skb, FREE_WRITE); - ti->current_skb=NULL; - } - dev->tbusy=0; - } - } - break; - - case DIR_OPEN_ADAPTER: { - struct srb_open_response *open_response=(struct srb_open_response *)(ti->init_srb); - - ti->srb=ti->sram+ntohs(open_response->srb_addr); - ti->ssb=ti->sram+ntohs(open_response->ssb_addr); - ti->arb=ti->sram+ntohs(open_response->arb_addr); - ti->asb=ti->sram+ntohs(open_response->asb_addr); - ti->current_skb=NULL; - - if(open_response->ret_code==7) { - if(!ti->auto_ringspeedsave && (open_response->error_code==0x24)) { - DPRINTK("open failed: Adapter speed must match ring speed if Automatic Ring Speed Save is disabled\n"); - ti->open_status=FAILURE; - wake_up(&ti->wait_for_reset); - } - else if(open_response->error_code==0x24) - DPRINTK("retrying open to adjust to ring speed\n"); - - else if((open_response->error_code==0x2d) && ti->auto_ringspeedsave) - DPRINTK("No signal detected for Auto Speed Detection\n"); - else DPRINTK("Unrecoverable error: error code = %02X\n",open_response->error_code); - } - else if(!open_response->ret_code) { -#ifndef TR_NEWFORMAT - DPRINTK("board opened...\n"); + case XMIT_DIR_FRAME: { + unsigned char xmit_ret_code; + + xmit_ret_code=readb(ti->srb + offsetof(struct srb_xmit, ret_code)); + if (xmit_ret_code != 0xff) { + DPRINTK("error on xmit_dir_frame request: %02X\n", + xmit_ret_code); + if (ti->current_skb) { + dev_kfree_skb(ti->current_skb, FREE_WRITE); + ti->current_skb=NULL; + } + dev->tbusy=0; + } + } + break; + + case XMIT_UI_FRAME: { + unsigned char xmit_ret_code; + + xmit_ret_code=readb(ti->srb + offsetof(struct srb_xmit, ret_code)); + if (xmit_ret_code != 0xff) { + DPRINTK("error on xmit_ui_frame request: %02X\n", + xmit_ret_code); + if (ti->current_skb) { + dev_kfree_skb(ti->current_skb, FREE_WRITE); + ti->current_skb=NULL; + } + dev->tbusy=0; + } + } + break; + + case DIR_OPEN_ADAPTER: { + unsigned char open_ret_code; + __u16 open_error_code; + + ti->srb=ti->sram+ntohs(readw(ti->init_srb +offsetof(struct srb_open_response, srb_addr))); + ti->ssb=ti->sram+ntohs(readw(ti->init_srb +offsetof(struct srb_open_response, ssb_addr))); + ti->arb=ti->sram+ntohs(readw(ti->init_srb +offsetof(struct srb_open_response, arb_addr))); + ti->asb=ti->sram+ntohs(readw(ti->init_srb +offsetof(struct srb_open_response, asb_addr))); + ti->current_skb=NULL; + + open_ret_code = readb(ti->init_srb +offsetof(struct srb_open_response, ret_code)); + open_error_code = readw(ti->init_srb +offsetof(struct srb_open_response, error_code)); + + if (open_ret_code==7) { + + if (!ti->auto_ringspeedsave && (open_error_code==0x24)) { + DPRINTK("open failed: Adapter speed must match ring " + "speed if Automatic Ring Speed Save is disabled\n"); + ti->open_status=FAILURE; + wake_up(&ti->wait_for_reset); + } else if (open_error_code==0x24) + DPRINTK("retrying open to adjust to ring speed\n"); + else if ((open_error_code==0x2d) && ti->auto_ringspeedsave) + DPRINTK("No signal detected for Auto Speed Detection\n"); + else DPRINTK("Unrecoverable error: error code = %02X\n", + open_error_code); + + } else if (!open_ret_code) { +#if !TR_NEWFORMAT + DPRINTK("board opened...\n"); #else - DPRINTK("Adapter initialized and opened.\n"); + DPRINTK("Adapter initialized and opened.\n"); #endif - *(unsigned char *)(ti->mmio + ACA_OFFSET + ACA_RESET + ISRP_ODD)=~(SRB_RESP_INT); - *(unsigned char *)(ti->mmio + ACA_OFFSET + ACA_RESET + ISRA_ODD)=~(CMD_IN_SRB); - open_sap(EXTENDED_SAP,dev); -/* YdW probably hates me */ - goto skip_reset; - } - else { - DPRINTK("open failed: ret_code = %02X, retrying\n",open_response->ret_code); - } - if(ti->open_status!=FAILURE) { - tr_timer.expires=jiffies+TR_RETRY_INTERVAL; - tr_timer.data=(unsigned long)dev; - tr_timer.next=tr_timer.prev=NULL; - add_timer(&tr_timer); - } - } - break; - - case DIR_CLOSE_ADAPTER: + writeb(~(SRB_RESP_INT), + ti->mmio + ACA_OFFSET + ACA_RESET + ISRP_ODD); + writeb(~(CMD_IN_SRB), + ti->mmio + ACA_OFFSET + ACA_RESET + ISRA_ODD); + open_sap(EXTENDED_SAP,dev); + + /* YdW probably hates me */ + goto skip_reset; + } else + DPRINTK("open failed: ret_code = %02X, retrying\n", + open_ret_code); + + if (ti->open_status != FAILURE) { + tr_timer.expires=jiffies+TR_RETRY_INTERVAL; + tr_timer.data=(unsigned long)dev; + tr_timer.next=tr_timer.prev=NULL; + add_timer(&tr_timer); + } + + } + break; + + case DIR_CLOSE_ADAPTER: wake_up(&ti->wait_for_tok_int); break; - case DLC_OPEN_SAP: { - struct dlc_open_sap *open_sap=(struct dlc_open_sap *)ti->srb; - if(open_sap->ret_code) { - DPRINTK("open_sap failed: ret_code = %02X,retrying\n",open_sap->ret_code); + + case DLC_OPEN_SAP: + if (readb(ti->srb+offsetof(struct dlc_open_sap, ret_code))) { + DPRINTK("open_sap failed: ret_code = %02X,retrying\n", + (int)readb(ti->srb+offsetof(struct dlc_open_sap, ret_code))); tr_timer.expires=jiffies+TR_RETRY_INTERVAL; tr_timer.data=(unsigned long)dev; tr_timer.next=tr_timer.prev=NULL; add_timer(&tr_timer); - } - else { - ti->exsap_station_id=open_sap->station_id; + } else { + ti->exsap_station_id= + readw(ti->srb+offsetof(struct dlc_open_sap, station_id)); ti->open_status=SUCCES; /* TR adapter is now available */ wake_up(&ti->wait_for_reset); } - } - break; - - case DIR_INTERRUPT: - case DIR_MOD_OPEN_PARAMS: - case DIR_SET_GRP_ADDR: - case DIR_SET_FUNC_ADDR: - case DLC_CLOSE_SAP: { - struct srb_interrupt *intr=(struct srb_interrupt *)(ti->srb); - if(intr->ret_code) - DPRINTK("error on %02X: %02X\n",intr->command,intr->ret_code); - } - break; - - case DIR_READ_LOG: { - struct srb_read_log *read_log=(struct srb_read_log *)(ti->srb); - if(read_log->ret_code) - DPRINTK("error on dir_read_log: %02X\n",read_log->ret_code); - else { - DPRINTK("Line errors %02X, Internal errors %02X, Burst errors %02X\n", - read_log->line_errors,read_log->internal_errors,read_log->burst_errors); - DPRINTK("A/C errors %02X, Abort delimiters %02X, Lost frames %02X\n", - read_log->A_C_errors,read_log->abort_delimiters,read_log->lost_frames); - DPRINTK("Receive congestion count %02X, Frame copied errors %02X, Frequency errors %02X\n", - read_log->recv_congest_count,read_log->frame_copied_errors,read_log->frequency_errors); - DPRINTK("Token errors %02X\n",read_log->token_errors); - } + break; + + case DIR_INTERRUPT: + case DIR_MOD_OPEN_PARAMS: + case DIR_SET_GRP_ADDR: + case DIR_SET_FUNC_ADDR: + case DLC_CLOSE_SAP: + if (readb(ti->srb+offsetof(struct srb_interrupt, ret_code))) + DPRINTK("error on %02X: %02X\n", + (int)readb(ti->srb+offsetof(struct srb_interrupt, command)), + (int)readb(ti->srb+offsetof(struct srb_interrupt, ret_code))); + break; + + case DIR_READ_LOG: + if (readb(ti->srb+offsetof(struct srb_read_log, ret_code))) + DPRINTK("error on dir_read_log: %02X\n", + (int)readb(ti->srb+offsetof(struct srb_read_log, ret_code))); + else + DPRINTK( + "Line errors %02X, Internal errors %02X, Burst errors %02X\n" + "A/C errors %02X, Abort delimiters %02X, Lost frames %02X\n" + "Receive congestion count %02X, Frame copied errors %02X\n" + "Frequency errors %02X, Token errors %02X\n", + (int)readb(ti->srb+offsetof(struct srb_read_log, + line_errors)), + (int)readb(ti->srb+offsetof(struct srb_read_log, + internal_errors)), + (int)readb(ti->srb+offsetof(struct srb_read_log, + burst_errors)), + (int)readb(ti->srb+offsetof(struct srb_read_log, A_C_errors)), + (int)readb(ti->srb+offsetof(struct srb_read_log, + abort_delimiters)), + (int)readb(ti->srb+offsetof(struct srb_read_log, + lost_frames)), + (int)readb(ti->srb+offsetof(struct srb_read_log, + recv_congest_count)), + (int)readb(ti->srb+offsetof(struct srb_read_log, + frame_copied_errors)), + (int)readb(ti->srb+offsetof(struct srb_read_log, + frequency_errors)), + (int)readb(ti->srb+offsetof(struct srb_read_log, + token_errors))); dev->tbusy=0; - } - break; - - default: - DPRINTK("Unknown command %02X encountered\n",*(ti->srb)); - } - *(unsigned char *)(ti->mmio + ACA_OFFSET + ACA_RESET + ISRA_ODD)=~(CMD_IN_SRB); - *(unsigned char *)(ti->mmio + ACA_OFFSET + ACA_RESET + ISRP_ODD)=~(SRB_RESP_INT); -skip_reset: - } - - if(status & ASB_FREE_INT) { - switch(*ti->asb) { - case REC_DATA: - case XMIT_UI_FRAME: - case XMIT_DIR_FRAME: - if(*(ti->asb+2)!=0xff) - DPRINTK("ASB error %02X in cmd %02X\n", *(ti->asb+2),*(ti->asb)); break; - default: - DPRINTK("unknown command in asb %02X\n",*ti->asb); - } - *(unsigned char *)(ti->mmio + ACA_OFFSET + ACA_RESET + ISRP_ODD)=~(ASB_FREE_INT); - } - - if(status & ARB_CMD_INT) { - switch(*ti->arb) { - case DLC_STATUS: { - struct arb_dlc_status *dlc_status=(struct arb_dlc_status *)(ti->arb); - DPRINTK("DLC_STATUS new status: %02X on station %02X\n",ntohs(dlc_status->status),ntohs(dlc_status->station_id)); - } - break; - - case REC_DATA: + + default: + DPRINTK("Unknown command %02X encountered\n", + (int)readb(ti->srb)); + + } /* SRB command check */ + + writeb(~CMD_IN_SRB, ti->mmio + ACA_OFFSET + ACA_RESET + ISRA_ODD); + writeb(~SRB_RESP_INT, ti->mmio + ACA_OFFSET + ACA_RESET + ISRP_ODD); + + skip_reset: + } /* SRB response */ + + if (status & ASB_FREE_INT) { /* ASB response */ + + switch(readb(ti->asb)) { /* ASB command check */ + + case REC_DATA: + case XMIT_UI_FRAME: + case XMIT_DIR_FRAME: + if (readb(ti->asb+2)!=0xff) /* checks ret_code */ + DPRINTK("ASB error %02X in cmd %02X\n", + (int)readb(ti->asb+2), + (int)readb(ti->asb)); + break; + + default: + DPRINTK("unknown command in asb %02X\n", + (int)readb(ti->asb)); + + } /* ASB command check */ + + writeb(~ASB_FREE_INT, ti->mmio + ACA_OFFSET + ACA_RESET + ISRP_ODD); + + } /* ASB response */ + + if (status & ARB_CMD_INT) { /* ARB response */ + + switch (readb(ti->arb)) { /* ARB command check */ + + case DLC_STATUS: + DPRINTK("DLC_STATUS new status: %02X on station %02X\n", + ntohs(readw(ti->arb + offsetof(struct arb_dlc_status, status))), + ntohs(readw(ti->arb + +offsetof(struct arb_dlc_status, station_id)))); + break; + + case REC_DATA: tr_rx(dev); break; - - case RING_STAT_CHANGE: { - struct arb_ring_stat_change *ring_stat_change=(struct arb_ring_stat_change *)(ti->arb); - unsigned short ring_status=ntohs(ring_stat_change->ring_status); - - if(ring_status & (SIGNAL_LOSS + LOBE_FAULT)) { - DPRINTK("Signal loss/Lobe fault\n"); - DPRINTK("We try to reopen the adapter.\n"); - tr_timer.expires=jiffies+TR_RETRY_INTERVAL; - tr_timer.data=(unsigned long)dev; - tr_timer.next=tr_timer.prev=NULL; - add_timer(&tr_timer); - } else if (ring_status & (HARD_ERROR + XMIT_BEACON + - AUTO_REMOVAL + REMOVE_RECV + RING_RECOVER)) - DPRINTK("New ring status: %02X\n",ring_status); - - if(ring_status & LOG_OVERFLOW) { - *(ti->srb)=DIR_READ_LOG; - *(unsigned char *)(ti->mmio + ACA_OFFSET + ACA_SET + ISRP_EVEN)=INT_ENABLE; - *(unsigned char *)(ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD)=CMD_IN_SRB; - dev->tbusy=1; /* really srb busy... */ - } - } - break; - - case XMIT_DATA_REQ: + + case RING_STAT_CHANGE: { + unsigned short ring_status; + + ring_status=ntohs(readw(ti->arb + +offsetof(struct arb_ring_stat_change, ring_status))); + + if (ring_status & (SIGNAL_LOSS | LOBE_FAULT)) { + + DPRINTK("Signal loss/Lobe fault\n"); + DPRINTK("We try to reopen the adapter.\n"); + tr_timer.expires=jiffies+TR_RETRY_INTERVAL; + tr_timer.data=(unsigned long)dev; + tr_timer.next=tr_timer.prev=NULL; + add_timer(&tr_timer); + + } else if (ring_status & (HARD_ERROR | XMIT_BEACON + | AUTO_REMOVAL | REMOVE_RECV | RING_RECOVER)) + DPRINTK("New ring status: %02X\n", ring_status); + + if (ring_status & LOG_OVERFLOW) { + + writeb(DIR_READ_LOG, ti->srb); + writeb(INT_ENABLE, + ti->mmio + ACA_OFFSET + ACA_SET + ISRP_EVEN); + writeb(CMD_IN_SRB, + ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD); + dev->tbusy=1; /* really srb busy... */ + + } + } + break; + + case XMIT_DATA_REQ: tr_tx(dev); break; - - default: - DPRINTK("Unknown command %02X in arb\n",*(ti->arb)); + + default: + DPRINTK("Unknown command %02X in arb\n", + (int)readb(ti->arb)); break; - } - *(unsigned char *)(ti->mmio + ACA_OFFSET + ACA_RESET + ISRP_ODD)=~(ARB_CMD_INT); - *(unsigned char *)(ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD)=ARB_FREE; - } - - if(status & SSB_RESP_INT) { - switch(*ti->ssb) { - case XMIT_DIR_FRAME: - case XMIT_UI_FRAME: - if(*(ti->ssb+2)) - DPRINTK("xmit ret_code: %02X xmit error code: %02X\n",*(ti->ssb+2),*(ti->ssb+6)); - else - ti->tr_stats.tx_packets++; + + } /* ARB command check */ + + writeb(~ARB_CMD_INT, ti->mmio + ACA_OFFSET + ACA_RESET + ISRP_ODD); + writeb(ARB_FREE, ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD); + + } /* ARB response */ + + if (status & SSB_RESP_INT) { /* SSB response */ + + switch (readb(ti->ssb)) { /* SSB command check */ + + case XMIT_DIR_FRAME: + case XMIT_UI_FRAME: + if (readb(ti->ssb+2)) /* checks ret_code */ + DPRINTK("xmit ret_code: %02X xmit error code: %02X\n", + (int)readb(ti->ssb+2), (int)readb(ti->ssb+6)); + else ti->tr_stats.tx_packets++; break; + + case XMIT_XID_CMD: + DPRINTK("xmit xid ret_code: %02X\n", (int)readb(ti->ssb+2)); + + default: + DPRINTK("Unknown command %02X in ssb\n", (int)readb(ti->ssb)); + + } /* SSB command check */ - case XMIT_XID_CMD: - DPRINTK("xmit xid ret_code: %02X\n",*(ti->ssb+2)); + writeb(~SSB_RESP_INT, ti->mmio + ACA_OFFSET + ACA_RESET + ISRP_ODD); + writeb(SSB_FREE, ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD); - default: - DPRINTK("Unknown command %02X in ssb\n",*(ti->ssb)); - } - *(unsigned char *)(ti->mmio + ACA_OFFSET + ACA_RESET + ISRP_ODD)=~(SSB_RESP_INT); - *(unsigned char *)(ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD)=SSB_FREE; - } - } - - dev->interrupt=0; - *(unsigned char *)(ti->mmio + ACA_OFFSET + ACA_SET + ISRP_EVEN)=INT_ENABLE; - - return; + } /* SSB response */ + + } /* SRB, ARB, ASB or SSB response */ + + dev->interrupt=0; + writeb(INT_ENABLE, ti->mmio + ACA_OFFSET + ACA_SET + ISRP_EVEN); + break; - break; - case FIRST_INT: - initial_tok_int(dev); - break; - default: - DPRINTK("Unexpected interrupt from tr adapter\n"); - } + case FIRST_INT: + initial_tok_int(dev); + break; + + default: + DPRINTK("Unexpected interrupt from tr adapter\n"); + } } -static void initial_tok_int(struct device *dev) { - -#ifndef TR_NEWFORMAT - int i; -#endif - unsigned char *encoded_addr; - struct tok_info *ti; - - ti=(struct tok_info *) dev->priv; +static void initial_tok_int(struct device *dev) +{ - *(unsigned char *)(ti->mmio + ACA_OFFSET + ACA_RESET + ISRP_EVEN)=(~INT_ENABLE); + __u32 encoded_addr; + __u32 hw_encoded_addr; + struct tok_info *ti; + + ti=(struct tok_info *) dev->priv; + + writeb(~INT_ENABLE, ti->mmio + ACA_OFFSET + ACA_RESET + ISRP_EVEN); /* Reset interrupt for ISA boards */ - if(ti->global_int_enable) - outb(0,ti->global_int_enable); - + if (ti->global_int_enable) outb(0,ti->global_int_enable); + ti->do_tok_int=NOT_FIRST; - + #ifndef TR_NEWFORMAT DPRINTK("Initial tok int received\n"); #endif - if(!ti->sram) { /* we assign the address for ISA devices */ - /* set RRR even to D000 for shared ram address */ - *(unsigned char *)(ti->mmio + ACA_OFFSET + ACA_RW + RRR_EVEN)= - ti->sram_base; - ti->sram=(char *)(ti->sram_base << 12); + /* we assign the address for ISA devices; set RRR even to D000 for + shared RAM address */ + if(!ti->sram) { + writeb(ti->sram_base, ti->mmio + ACA_OFFSET + ACA_RW + RRR_EVEN); + ti->sram=((__u32)ti->sram_base << 12); + } + ti->init_srb=ti->sram + +ntohs((unsigned short)readw(ti->mmio+ ACA_OFFSET + WRBR_EVEN)); + SET_PAGE(ntohs((unsigned short)readw(ti->mmio+ACA_OFFSET + WRBR_EVEN))); + +#if TR_VERBOSE + { + int i; + DPRINTK("init_srb(%p):", ti->init_srb); + for (i=0;i<17;i++) printk("%02X ", (int)readb(ti->init_srb+i)); + printk("\n"); } - ti->init_srb=ti->sram+ntohs(*(unsigned short *)(ti->mmio+ ACA_OFFSET + WRBR_EVEN)); - SET_PAGE(ntohs(*(unsigned short *)(ti->mmio+ ACA_OFFSET + WRBR_EVEN))); - -#if 0 - DPRINTK("init_srb(%p):",ti->init_srb); - for(i=0;i<17;i++) - printk("%02X ",*(ti->init_srb+i)); - printk("\n"); #endif - -#ifndef TR_NEWFORMAT - DPRINTK("srb_init_response->encoded_address: %04X\n",((struct srb_init_response *)ti->init_srb)->encoded_address); - DPRINTK("ntohs(srb_init_response->encoded_address): %04X\n",ntohs(((struct srb_init_response *)ti->init_srb)->encoded_address)); + + hw_encoded_addr = readw(ti->init_srb + + offsetof(struct srb_init_response, encoded_address)); + +#if !TR_NEWFORMAT + DPRINTK("srb_init_response->encoded_address: %04X\n", hw_encoded_addr); + DPRINTK("ntohs(srb_init_response->encoded_address): %04X\n", + ntohs(hw_encoded_addr)); #endif - encoded_addr=(unsigned char *)(ti->sram + ntohs(((struct srb_init_response *)ti->init_srb)->encoded_address)); - -#ifndef TR_NEWFORMAT - DPRINTK("encoded addr (%04X,%04X,%p): ", - ((struct srb_init_response *)ti->init_srb)->encoded_address, - ntohs(((struct srb_init_response *)ti->init_srb)->encoded_address), - encoded_addr); + + encoded_addr=(ti->sram + ntohs(hw_encoded_addr)); + +#if !TR_NEWFORMAT + DPRINTK("encoded addr (%04X,%04X,%08X): ", hw_encoded_addr, + ntohs(hw_encoded_addr), encoded_addr); #else - DPRINTK("Initial interrupt : shared RAM located at %p.\n", encoded_addr); -#endif - ti->auto_ringspeedsave=((struct srb_init_response *)ti->init_srb)->init_status_2 & 0x4 ? TRUE : FALSE; - -#ifndef TR_NEWFORMAT - for(i=0;idev_addr[i]=encoded_addr[i],(i==TR_ALEN-1) ? "" : ":" ); + DPRINTK("Initial interrupt : shared RAM located at %08X.\n", encoded_addr); +#endif + + ti->auto_ringspeedsave=readb(ti->init_srb + +offsetof(struct srb_init_response, init_status_2)) & 0x4 ? TRUE : FALSE; + +#if !TR_NEWFORMAT + for(i=0;idev_addr[i]=readb(encoded_addr + i); + printk("%02X%s", dev->dev_addr[i], (i==TR_ALEN-1) ? "" : ":" ); + } printk("\n"); #endif - + tok_open_adapter((unsigned long)dev); - } -static int tok_init_card(struct device *dev) { - - struct tok_info *ti; +static void tok_init_card(unsigned long dev_addr) +{ + struct tok_info *ti; short PIOaddr; - PIOaddr = dev->base_addr; - ti=(struct tok_info *) dev->priv; - - /* Special processing for first interrupt after reset */ + int i; + struct device *dev=(struct device *)dev_addr; + PIOaddr = dev->base_addr; + ti=(struct tok_info *) dev->priv; + + /* Special processing for first interrupt after reset */ ti->do_tok_int=FIRST_INT; - + /* Reset adapter */ - dev->tbusy=1; /* nothing can be done before reset and open completed */ - + #ifdef ENABLE_PAGING - if(ti->page_mask) { - *(unsigned char *)(ti->mmio + ACA_OFFSET + ACA_RW + SRPR_EVEN)=SRPR_ENABLE_PAGING; - } + if(ti->page_mask) + writeb(SRPR_ENABLE_PAGING, ti->mmio + ACA_OFFSET + ACA_RW + SRPR_EVEN); #endif - - *(unsigned char *)(ti->mmio + ACA_OFFSET + ACA_RESET + ISRP_EVEN)=~(INT_ENABLE); -#ifndef TR_NEWFORMAT + + writeb(~INT_ENABLE, ti->mmio + ACA_OFFSET + ACA_RESET + ISRP_EVEN); + +#if !TR_NEWFORMAT DPRINTK("resetting card\n"); #endif - outb(0,PIOaddr+ADAPTRESET); - udelay(50000); + + outb(0, PIOaddr+ADAPTRESET); + for (i=jiffies+TR_RESET_INTERVAL; jiffies<=i;); /* wait 50ms */ outb(0,PIOaddr+ADAPTRESETREL); -#ifndef TR_NEWFORMAT + +#if !TR_NEWFORMAT DPRINTK("card reset\n"); #endif - - ti->open_status=IN_PROGRESS; - - *(unsigned char *)(ti->mmio + ACA_OFFSET + ACA_SET + ISRP_EVEN)=INT_ENABLE; - return 0; + + ti->open_status=IN_PROGRESS; + writeb(INT_ENABLE, ti->mmio + ACA_OFFSET + ACA_SET + ISRP_EVEN); + } -static void open_sap(unsigned char type,struct device *dev) { - - struct tok_info *ti=(struct tok_info *) dev->priv; - struct dlc_open_sap *open_sap=(struct dlc_open_sap *)ti->srb; - +static void open_sap(unsigned char type,struct device *dev) +{ + int i; + struct tok_info *ti=(struct tok_info *) dev->priv; + SET_PAGE(ti->srb); - memset(open_sap,0,sizeof(struct dlc_open_sap)); - - open_sap->command=DLC_OPEN_SAP; - open_sap->max_i_field=htons(MAX_I_FIELD); - open_sap->sap_options=SAP_OPEN_IND_SAP | SAP_OPEN_PRIORITY; - open_sap->station_count=SAP_OPEN_STATION_CNT; - open_sap->sap_value=type; - - *(unsigned char *)(ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD)=CMD_IN_SRB; + for (i=0; isrb+i); + + writeb(DLC_OPEN_SAP, ti->srb + offsetof(struct dlc_open_sap, command)); + writew(htons(MAX_I_FIELD), + ti->srb + offsetof(struct dlc_open_sap, max_i_field)); + writeb(SAP_OPEN_IND_SAP | SAP_OPEN_PRIORITY, + ti->srb + offsetof(struct dlc_open_sap, sap_options)); + writeb(SAP_OPEN_STATION_CNT, + ti->srb + offsetof(struct dlc_open_sap, station_count)); + writeb(type, ti->srb + offsetof(struct dlc_open_sap, sap_value)); + + writeb(CMD_IN_SRB, ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD); } -void tok_open_adapter(unsigned long dev_addr) { - +void tok_open_adapter(unsigned long dev_addr) +{ + struct device *dev=(struct device *)dev_addr; - struct dir_open_adapter *open_adapter; - struct tok_info *ti; - ti=(struct tok_info *) dev->priv; - -#ifndef TR_NEWFORMAT + struct tok_info *ti; + int i; + + ti=(struct tok_info *) dev->priv; + +#if !TR_NEWFORMAT DPRINTK("now opening the board...\n"); #endif - - *(unsigned char *)(ti->mmio + ACA_OFFSET + ACA_RESET + ISRP_ODD)=~(SRB_RESP_INT); - *(unsigned char *)(ti->mmio + ACA_OFFSET + ACA_RESET + ISRA_ODD)=~(CMD_IN_SRB); - - open_adapter=(struct dir_open_adapter *)(ti->init_srb); - memset(open_adapter,0,sizeof(struct dir_open_adapter)); - - open_adapter->command=DIR_OPEN_ADAPTER; - open_adapter->open_options=htons(OPEN_PASS_BCON_MAC); - open_adapter->num_rcv_buf=htons(NUM_RCV_BUF); - open_adapter->rcv_buf_len=htons(RCV_BUF_LEN); - open_adapter->dhb_length=htons(DHB_LENGTH); - open_adapter->num_dhb=NUM_DHB; - open_adapter->dlc_max_sap=DLC_MAX_SAP; - open_adapter->dlc_max_sta=DLC_MAX_STA; - + + writeb(~SRB_RESP_INT, ti->mmio + ACA_OFFSET + ACA_RESET + ISRP_ODD); + writeb(~CMD_IN_SRB, ti->mmio + ACA_OFFSET + ACA_RESET + ISRA_ODD); + + for (i=0; iinit_srb+i); + + writeb(DIR_OPEN_ADAPTER, + ti->init_srb + offsetof(struct dir_open_adapter, command)); + writew(htons(OPEN_PASS_BCON_MAC), + ti->init_srb + offsetof(struct dir_open_adapter, open_options)); + writew(htons(NUM_RCV_BUF), + ti->init_srb + offsetof(struct dir_open_adapter, num_rcv_buf)); + writew(htons(RCV_BUF_LEN), + ti->init_srb + offsetof(struct dir_open_adapter, rcv_buf_len)); + writew(htons(DHB_LENGTH), + ti->init_srb + offsetof(struct dir_open_adapter, dhb_length)); + writeb(NUM_DHB, + ti->init_srb + offsetof(struct dir_open_adapter, num_dhb)); + writeb(DLC_MAX_SAP, + ti->init_srb + offsetof(struct dir_open_adapter, dlc_max_sap)); + writeb(DLC_MAX_STA, + ti->init_srb + offsetof(struct dir_open_adapter, dlc_max_sta)); + ti->srb=ti->init_srb; /* We use this one in the interrupt handler */ - - *(unsigned char *)(ti->mmio + ACA_OFFSET + ACA_SET + ISRP_EVEN)=INT_ENABLE; - *(unsigned char *)(ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD)=CMD_IN_SRB; - + + writeb(INT_ENABLE, ti->mmio + ACA_OFFSET + ACA_SET + ISRP_EVEN); + writeb(CMD_IN_SRB, ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD); + } -static void tr_tx(struct device *dev) { - - struct tok_info *ti=(struct tok_info *) dev->priv; - struct asb_xmit_resp *xmit_resp=(struct asb_xmit_resp *)ti->asb; - struct arb_xmit_req *xmit_req=(struct arb_xmit_req *)ti->arb; - struct srb_xmit *xmit=(struct srb_xmit *)ti->srb; +static void tr_tx(struct device *dev) +{ + struct tok_info *ti=(struct tok_info *) dev->priv; struct trh_hdr *trhdr=(struct trh_hdr *)ti->current_skb->data; unsigned int hdr_len; - unsigned char *dhb; - -/* */ - DPRINTD("ti=%p asb=(%p,%p) arb=(%p,%p) srb=(%p,%p)\n", - ti , ti->asb, xmit_resp, ti->arb, xmit_req, ti->srb, xmit); -/* */ - -#if 0 -DPRINTK("transmitting...\n"); -#endif - - if(xmit_resp->ret_code!=0xff) DPRINTK("ASB not free !!!\n"); - - /* in providing the transmit interrupts, - is telling us it is ready for data and - providing a shared memory address for us - to stuff with data. Here we compute the - effective address where we will place data.*/ - dhb=ti->sram+ntohs(xmit_req->dhb_address); - - xmit_resp->command=xmit->command; - xmit_resp->station_id=xmit_req->station_id; - xmit_resp->rsap_value=EXTENDED_SAP; - xmit_resp->cmd_corr=xmit_req->cmd_corr; - xmit_resp->ret_code=0; - - if((xmit->command==XMIT_XID_CMD) || (xmit->command==XMIT_TEST_CMD)) { - xmit_resp->frame_length=htons(0x11); - xmit_resp->hdr_length=0x0e; - dhb[0]=AC; - dhb[1]=LLC_FRAME; - memset(dhb+2,(int)0x0ff,TR_ALEN); - memset(dhb+2+TR_ALEN,0,TR_ALEN); - *(unsigned char *)(ti->mmio + ACA_OFFSET + ACA_SET - + ISRA_ODD)=RESP_IN_ASB; + __u32 dhb; + unsigned char xmit_command; + int i; + + if (readb(ti->asb + offsetof(struct asb_xmit_resp, ret_code))!=0xFF) + DPRINTK("ASB not free !!!\n"); + + /* in providing the transmit interrupts, + is telling us it is ready for data and + providing a shared memory address for us + to stuff with data. Here we compute the + effective address where we will place data.*/ + dhb=ti->sram + +ntohs(readw(ti->arb + offsetof(struct arb_xmit_req, dhb_address))); + + xmit_command = readb(ti->srb + offsetof(struct srb_xmit, command)); + + writeb(xmit_command, ti->asb + offsetof(struct asb_xmit_resp, command)); + writew(readb(ti->srb + offsetof(struct srb_xmit, station_id)), + ti->asb + offsetof(struct asb_xmit_resp, station_id)); + writeb(EXTENDED_SAP, ti->asb + offsetof(struct asb_xmit_resp, rsap_value)); + writeb(readb(ti->srb + offsetof(struct srb_xmit, cmd_corr)), + ti->asb + offsetof(struct asb_xmit_resp, cmd_corr)); + writeb(0, ti->asb + offsetof(struct asb_xmit_resp, ret_code)); + + if ((xmit_command==XMIT_XID_CMD) || (xmit_command==XMIT_TEST_CMD)) { + + writew(htons(0x11), + ti->asb + offsetof(struct asb_xmit_resp, frame_length)); + writeb(0x0e, ti->asb + offsetof(struct asb_xmit_resp, hdr_length)); + writeb(AC, dhb); + writeb(LLC_FRAME, dhb+1); + + for (i=0; immio + ACA_OFFSET + ACA_SET + ISRA_ODD); return; + } - - /* the token ring packet is copied from sk_buff to the adapter - buffer identified in the command data received with the - interrupt. The sk_buff area was set up with a maximum - sized route information field so here we must compress - out the extra (all) rif fields. */ - /* nb/dwm .... I re-arranged code here to avoid copy of extra - bytes, ended up with fewer statements as well */ - - /* TR arch. identifies if RIF present by high bit of source - address. So here we check if RIF present */ - if(!(trhdr->saddr[0] & 0x80)) { - hdr_len=sizeof(struct trh_hdr)-18; -#if 0 -DPRINTK(("hdr_length: %d, frame length: %ld\n",hdr_len, - ti->current_skb->len-18)); -#endif - } /* TR packet includes RIF data ... preserve it */ - else { - hdr_len=((ntohs(trhdr->rcf) - & TR_RCF_LEN_MASK)>>8)+sizeof(struct trh_hdr)-18; -#if 0 -/* rework the following if activated, hdr_len <> rif_len */ -DPRINTK("rcf: %02X rif_len: %d\n", trhdr->rcf,wrk_len); -DPRINTK("hdr_length: %d, frame length: %ld\n",sizeof(struct trh_hdr)-18+hdr_len, - ti->current_skb->len-18+hdr_len); + + /* the token ring packet is copied from sk_buff to the adapter + buffer identified in the command data received with the + interrupt. The sk_buff area was set up with a maximum + sized route information field so here we must compress + out the extra (all) rif fields. */ + /* nb/dwm .... I re-arranged code here to avoid copy of extra + bytes, ended up with fewer statements as well. */ + + /* TR arch. identifies if RIF present by high bit of source + address. So here we check if RIF present */ + + if (!(trhdr->saddr[0] & 0x80)) { /* RIF present : preserve it */ + hdr_len=sizeof(struct trh_hdr)-18; + +#if TR_VERBOSE + DPRINTK("hdr_length: %d, frame length: %ld\n", hdr_len, + ti->current_skb->len-18); #endif - } - - /* header length including rif is computed above, now move the data - and set fields appropriately. */ - - memcpy(dhb,ti->current_skb->data,hdr_len); - dhb+=hdr_len; - xmit_resp->hdr_length= hdr_len; - xmit_resp->frame_length=htons(ti->current_skb->len - -sizeof(struct trh_hdr)+hdr_len); - - /* now copy the actual packet data next to hdr */ - memcpy(dhb,ti->current_skb->data+sizeof(struct trh_hdr), - ti->current_skb->len-sizeof(struct trh_hdr)); - - *(unsigned char *)(ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD) - =RESP_IN_ASB; - dev->tbusy=0; - dev_kfree_skb(ti->current_skb,FREE_WRITE); - ti->current_skb=NULL; - mark_bh(NET_BH); + } else hdr_len=((ntohs(trhdr->rcf) & TR_RCF_LEN_MASK)>>8) + +sizeof(struct trh_hdr)-18; + + /* header length including rif is computed above, now move the data + and set fields appropriately. */ + for (i=0; icurrent_skb->data +i), dhb++); + + writeb(hdr_len, ti->asb + offsetof(struct asb_xmit_resp, hdr_length)); + writew(htons(ti->current_skb->len-sizeof(struct trh_hdr)+hdr_len), + ti->asb + offsetof(struct asb_xmit_resp, frame_length)); + + /* now copy the actual packet data next to hdr */ + for (i=0; icurrent_skb->len-sizeof(struct trh_hdr); i++) + writeb(*(unsigned char *)(ti->current_skb->data +sizeof(struct trh_hdr)+i), + dhb+i); + + writeb(RESP_IN_ASB, ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD); + dev->tbusy=0; + dev_kfree_skb(ti->current_skb,FREE_WRITE); + ti->current_skb=NULL; + mark_bh(NET_BH); } -static void tr_rx(struct device *dev) { - - struct tok_info *ti=(struct tok_info *) dev->priv; - - struct arb_rec_req *rec_req=(struct arb_rec_req *)ti->arb; - struct asb_rec *rec_resp=(struct asb_rec *)ti->asb; - struct rec_buf *rbuffer; - struct trllc *llc; +static void tr_rx(struct device *dev) +{ + int i; + struct tok_info *ti=(struct tok_info *) dev->priv; + __u32 rbuffer; + __u32 llc; unsigned char *data; - unsigned int rbuffer_len,lan_hdr_len; + unsigned int rbuffer_len, lan_hdr_len; + unsigned int arb_frame_len; struct sk_buff *skb; - - rbuffer=(struct rec_buf *)(ti->sram+ntohs(rec_req->rec_buf_addr)); - - if(rec_resp->ret_code!=0xff) DPRINTK("ASB not free !!!\n"); - - rec_resp->command=REC_DATA; - rec_resp->station_id=rec_req->station_id; - rec_resp->rec_buf_addr=rec_req->rec_buf_addr; - - lan_hdr_len=rec_req->lan_hdr_len; - - llc=(struct trllc *)((unsigned char *)rbuffer+offsetof(struct rec_buf,data)+lan_hdr_len); - -#if 0 -DPRINTK("offsetof data: %02X lan_hdr_len: %02X\n",offsetof(struct rec_buf,data),lan_hdr_len); -DPRINTK("llc: %p rec_buf_addr: %04X ti->sram: %p\n",llc,ntohs(rec_req->rec_buf_addr),ti->sram); -DPRINTK("dsap: %02X, ssap: %02X, llc: %02X, protid: %02X%02X%02X, ethertype: %04X\n", - llc->dsap,llc->ssap,llc->llc,llc->protid[0],llc->protid[1],llc->protid[2],llc->ethertype); -#endif - - if(llc->llc!=UI_CMD) { -#ifndef TR_FILTERNONUI - DPRINTK("non-UI frame arrived. dropped. llc= %02X\n",llc->llc); -#endif - rec_resp->ret_code=DATA_LOST; - ti->tr_stats.rx_dropped++; - *(unsigned char *)(ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD)=RESP_IN_ASB; - return; - } - -#if 0 - if((llc->dsap!=0xaa) || (llc->ssap!=0xaa)) { - - struct trh_hdr *trhdr=(struct trh_hdr *)((unsigned char *)rbuffer+offsetof(struct rec_buf,data)); - -DPRINTK("Probably non-IP frame received.\n"); -DPRINTK("ssap: %02X dsap: %02X saddr: %02X:%02X:%02X:%02X:%02X:%02X daddr: %02X:%02X:%02X:%02X:%02X:%02X\n", - llc->ssap,llc->dsap,trhdr->saddr[0],trhdr->saddr[1],trhdr->saddr[2],trhdr->saddr[3],trhdr->saddr[4],trhdr->saddr[5], - trhdr->daddr[0],trhdr->daddr[1],trhdr->daddr[2],trhdr->daddr[3],trhdr->daddr[4],trhdr->daddr[5]); - } + + rbuffer=(ti->sram + +ntohs(readw(ti->arb + offsetof(struct arb_rec_req, rec_buf_addr)))); + + if(readb(ti->asb + offsetof(struct asb_rec, ret_code))!=0xFF) + DPRINTK("ASB not free !!!\n"); + + writeb(REC_DATA, + ti->asb + offsetof(struct asb_rec, command)); + writew(readw(ti->arb + offsetof(struct arb_rec_req, station_id)), + ti->asb + offsetof(struct asb_rec, station_id)); + writew(readw(ti->arb + offsetof(struct arb_rec_req, rec_buf_addr)), + ti->asb + offsetof(struct asb_rec, rec_buf_addr)); + + lan_hdr_len=readb(ti->arb + offsetof(struct arb_rec_req, lan_hdr_len)); + + llc=(rbuffer+offsetof(struct rec_buf, data) + lan_hdr_len); + +#if TR_VERBOSE + DPRINTK("offsetof data: %02X lan_hdr_len: %02X\n", + (unsigned int)offsetof(struct rec_buf,data), (unsigned int)lan_hdr_len); + DPRINTK("llc: %08X rec_buf_addr: %04X ti->sram: %p\n", llc, + ntohs(readw(ti->arb + offsetof(struct arb_rec_req, rec_buf_addr))), + ti->sram); + DPRINTK("dsap: %02X, ssap: %02X, llc: %02X, protid: %02X%02X%02X, " + "ethertype: %04X\n", + (int)readb(llc + offsetof(struct trllc, dsap)), + (int)readb(llc + offsetof(struct trllc, ssap)), + (int)readb(llc + offsetof(struct trllc, protid)), + (int)readb(llc + offsetof(struct trllc, protid)+1), + (int)readb(llc + offsetof(struct trllc, protid)+2), + (int)readw(llc + offsetof(struct trllc, ethertype))); #endif - - - if(!(skb=dev_alloc_skb(ntohs(rec_req->frame_len)-lan_hdr_len+sizeof(struct trh_hdr)))) { - DPRINTK("out of memory. frame dropped.\n"); - ti->tr_stats.rx_dropped++; - rec_resp->ret_code=DATA_LOST; - *(unsigned char *)(ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD)=RESP_IN_ASB; - return; - } - - skb_put(skb,ntohs(rec_req->frame_len)-lan_hdr_len+sizeof(struct trh_hdr)); - skb->dev=dev; - -#if 0 -DPRINTK("Now copying data...\n"); + + if (readb(llc + offsetof(struct trllc, llc))!=UI_CMD) { +#if !TR_FILTERNONUI + DPRINTK("non-UI frame arrived. dropped. llc= %02X\n", + (int)readb(llc + offsetof(struct trllc, llc)) #endif - - - data=skb->data; - memcpy(data,&(rbuffer->data),lan_hdr_len); - - - if(lan_hdr_lenbuf_len)-lan_hdr_len; -#if 0 -DPRINTK("rbuffer_len: %d, data: %p\n",rbuffer_len,data); + writeb(DATA_LOST, ti->asb + offsetof(struct asb_rec, ret_code)); + ti->tr_stats.rx_dropped++; + writeb(RESP_IN_ASB, ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD); + return; + } + +#if TR_VERBOSE + if ((readb(llc + offsetof(struct trllc, dsap))!=0xAA) || + (readb(llc + offsetof(struct trllc, ssap))!=0xAA)) { + + __u32 trhhdr; + + trhhdr=(rbuffer+offsetof(struct rec_buf,data)); + + DPRINTK("Probably non-IP frame received.\n"); + DPRINTK("ssap: %02X dsap: %02X saddr: %02X:%02X:%02X:%02X:%02X:%02X " + "daddr: %02X:%02X:%02X:%02X:%02X:%02X\n", + (int)readb(llc + offsetof(struct trllc, ssap)), + (int)readb(llc + offsetof(struct trllc, dsap)), + (int)readb(trhhdr + offsetof(struct trh_hdr, saddr)), + (int)readb(trhhdr + offsetof(struct trh_hdr, saddr)+1), + (int)readb(trhhdr + offsetof(struct trh_hdr, saddr)+2), + (int)readb(trhhdr + offsetof(struct trh_hdr, saddr)+3), + (int)readb(trhhdr + offsetof(struct trh_hdr, saddr)+4), + (int)readb(trhhdr + offsetof(struct trh_hdr, saddr)+5), + (int)readb(trhhdr + offsetof(struct trh_hdr, daddr)), + (int)readb(trhhdr + offsetof(struct trh_hdr, daddr)+1), + (int)readb(trhhdr + offsetof(struct trh_hdr, daddr)+2), + (int)readb(trhhdr + offsetof(struct trh_hdr, daddr)+3), + (int)readb(trhhdr + offsetof(struct trh_hdr, daddr)+4), + (int)readb(trhhdr + offsetof(struct trh_hdr, daddr)+5)); + } #endif - memcpy(data,(unsigned char *)(&(rbuffer->data))+lan_hdr_len,rbuffer_len); - data+=rbuffer_len; - - - if(rbuffer->buf_ptr) - for(rbuffer=(struct rec_buf *)(ti->sram+ntohs(rbuffer->buf_ptr)-2); - memcpy(data,&(rbuffer->data),rbuffer_len=ntohs(rbuffer->buf_len)),rbuffer->buf_ptr; - data+=rbuffer_len,rbuffer=(struct rec_buf *)(ti->sram+ntohs(rbuffer->buf_ptr)-2)) -#if 0 - DPRINTK("buf_ptr: %d,data =%p\n",ntohs(rbuffer->buf_ptr),data); + + arb_frame_len=ntohs(readw(ti->arb+offsetof(struct arb_rec_req, frame_len))); + + if (!(skb=dev_alloc_skb(arb_frame_len-lan_hdr_len+sizeof(struct trh_hdr)))) { + DPRINTK("out of memory. frame dropped.\n"); + ti->tr_stats.rx_dropped++; + writeb(DATA_LOST, ti->asb + offsetof(struct asb_rec, ret_code)); + writeb(RESP_IN_ASB, ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD); + return; + } + + skb_put(skb, arb_frame_len-lan_hdr_len+sizeof(struct trh_hdr)); + skb->dev=dev; + + data=skb->data; + for (i=0; iret_code=0; - - *(unsigned char *)(ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD)=RESP_IN_ASB; - - ti->tr_stats.rx_packets++; - - skb->protocol=tr_type_trans(skb,dev); - netif_rx(skb); - - return; -} - -static int tok_send_packet(struct sk_buff *skb, struct device *dev) { - - struct tok_info *ti=(struct tok_info *) dev->priv; - -#if 0 -DPRINTK("tada: sending packet...\n"); + + for (i=0; isram + +ntohs(readw(rbuffer + offsetof(struct rec_buf, buf_ptr)))-2); + rbuffer_len=ntohs(readw(rbuffer + offsetof(struct rec_buf, buf_len))); + for (i=0; iasb + offsetof(struct asb_rec, ret_code)); + + writeb(RESP_IN_ASB, ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD); + + ti->tr_stats.rx_packets++; + + skb->protocol=tr_type_trans(skb,dev); + netif_rx(skb); + + } +static int tok_send_packet(struct sk_buff *skb, struct device *dev) +{ + struct tok_info *ti; + ti=(struct tok_info *) dev->priv; + if (dev->tbusy) { - int ticks_waited=jiffies - dev->trans_start; - if(ticks_waitedtrans_start; + if (ticks_waitedtrans_start+=5; /* we fake the transmission start time... */ return 1; } - + /* Donald does this, so we do too. */ - - if(skb==NULL) { + if (skb==NULL) { dev_tint(dev); return 0; } - - if(set_bit(0,(void *)&dev->tbusy)!=0) + + if (set_bit(0,(void *)&dev->tbusy)!=0) DPRINTK("Transmitter access conflict\n"); else { - struct srb_xmit *xmit=(struct srb_xmit *)ti->srb; - - ti->current_skb=skb; /* save skb. We will need it when the adapter - asks for the data */ - xmit->command=XMIT_UI_FRAME; - xmit->station_id=ti->exsap_station_id; - *(unsigned char *)(ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD)=CMD_IN_SRB; + /* Save skb; we'll need it when the adapter asks for the data */ + ti->current_skb=skb; + writeb(XMIT_UI_FRAME, ti->srb + offsetof(struct srb_xmit, command)); + writew(ti->exsap_station_id, ti->srb + +offsetof(struct srb_xmit, station_id)); + writeb(CMD_IN_SRB, (ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD)); dev->trans_start=jiffies; } - + return 0; } /* tok_get_stats(): Basically a scaffold routine which will return - the address of the tr_statistics structure associated with - this device -- the tr.... structure is a ethnet look-alike - so at least for this iteration may suffice. */ + the address of the tr_statistics structure associated with + this device -- the tr.... structure is a ethnet look-alike + so at least for this iteration may suffice. */ static struct enet_statistics * tok_get_stats(struct device *dev) { - struct tok_info *toki; - toki=(struct tok_info *) dev->priv; - return (struct enet_statistics *) &toki->tr_stats; + struct tok_info *toki; + toki=(struct tok_info *) dev->priv; + return (struct enet_statistics *) &toki->tr_stats; } #ifdef MODULE + + static char devicename[9] = { 0, }; static struct device dev_ibmtr = { devicename, /* device name is inserted by linux/drivers/net/net_init.c */ @@ -1348,10 +1446,11 @@ static int io = 0xa20; int init_module(void) { - if (io == 0) + if (io == 0) printk("ibmtr: You should not use auto-probing with insmod!\n"); dev_ibmtr.base_addr = io; dev_ibmtr.irq = 0; + if (register_netdev(&dev_ibmtr) != 0) { printk("ibmtr: register_netdev() returned non-zero.\n"); return -EIO; @@ -1359,11 +1458,10 @@ int init_module(void) return 0; } -void -cleanup_module(void) +void cleanup_module(void) { unregister_netdev(&dev_ibmtr); - + /* If we don't do this, we can't re-insmod it later. */ free_irq(dev_ibmtr.irq, NULL); irq2dev_map[dev_ibmtr.irq] = NULL; diff --git a/drivers/net/ibmtr.h b/drivers/net/ibmtr.h index b92146835e0a..9c7d02e54a3e 100644 --- a/drivers/net/ibmtr.h +++ b/drivers/net/ibmtr.h @@ -1,23 +1,18 @@ /* Definitions for an IBM Token Ring card. */ /* This file is distributed under the GNU GPL */ -#define TR_RETRY_INTERVAL 500 +/* ported to the Alpha architecture 02/20/96 (just used the HZ macro) */ + +#define TR_RETRY_INTERVAL (5*HZ) /* 500 on PC = 5 s */ +#define TR_RESET_INTERVAL (HZ/20) /* 5 on PC = 50 ms */ +#define TR_BUSY_INTERVAL (HZ/5) /* 5 on PC = 200 ms */ + #define TR_ISA 1 #define TR_MCA 2 #define TR_ISAPNP 3 #define NOTOK 0 #define TOKDEBUG 1 -/* Mike Eckhoff -- 96/02/08 */ -/* This defines the minimum timeout. If a transmission takes */ -/* longer then TX_TIMEOUT to send, we will wait and retry. */ -/* On large networks, this value may need to be increased. */ -/* We will start at .2s because that is what most drivers seem to be doing */ -/* now and the original value of .05s was not nearly enough for large nets. */ - -#define TX_TIMEOUT (HZ/5) - - #ifndef IBMTR_SHARED_RAM_BASE #define IBMTR_SHARED_RAM_BASE 0xD0 #define IBMTR_SHARED_RAM_SIZE 0x10 @@ -168,105 +163,68 @@ #define ACA_RW 0x00 #ifdef ENABLE_PAGING -#define SET_PAGE(x) (*(unsigned char *) \ - (ti->mmio + ACA_OFFSET + ACA_RW + SRPR_EVEN)\ - = (x>>8)&ti.page_mask) +#define SET_PAGE(x) (writeb(((x>>8)&ti.page_mask), \ + ti->mmio + ACA_OFFSET + ACA_RW + SRPR_EVEN)) #else #define SET_PAGE(x) #endif typedef enum { IN_PROGRESS, SUCCES, FAILURE, CLOSED } open_state; -struct tok_info { - unsigned char irq; - unsigned char *mmio; - unsigned char hw_address[32]; - unsigned char adapter_type; - unsigned char data_rate; - unsigned char token_release; - unsigned char avail_shared_ram; - unsigned char shared_ram_paging; - unsigned char dhb_size4mb; - unsigned char dhb_size16mb; -/* Additions by David Morris */ - unsigned char do_tok_int; +/* do_tok_int possible values */ #define FIRST_INT 1 #define NOT_FIRST 2 - struct wait_queue *wait_for_tok_int; - struct wait_queue *wait_for_reset; - unsigned char sram_base; -/* Additions by Peter De Schrijver */ - unsigned char page_mask; /* mask to select RAM page to Map*/ - unsigned char mapped_ram_size; /* size of RAM page */ - unsigned char *sram; /* Shared memory base address */ - unsigned char *init_srb; /* Initial System Request Block address */ - unsigned char *srb; /* System Request Block address */ - unsigned char *ssb; /* System Status Block address */ - unsigned char *arb; /* Adapter Request Block address */ - unsigned char *asb; /* Adapter Status Block address */ - unsigned short exsap_station_id; - unsigned short global_int_enable; - struct sk_buff *current_skb; - struct tr_statistics tr_stats; - unsigned char auto_ringspeedsave; - open_state open_status; - -}; -struct srb_init_response { - unsigned char command; - unsigned char init_status; - unsigned char init_status_2; - unsigned char reserved[3]; - unsigned short bring_up_code; - unsigned short encoded_address; - unsigned short level_address; - unsigned short adapter_address; - unsigned short parms_address; - unsigned short mac_address; -}; - -#define DIR_OPEN_ADAPTER 0x03 - -struct dir_open_adapter { - unsigned char command; - char reserved[7]; - unsigned short open_options; - unsigned char node_address[6]; - unsigned char group_address[4]; - unsigned char funct_address[4]; - unsigned short num_rcv_buf; - unsigned short rcv_buf_len; - unsigned short dhb_length; - unsigned char num_dhb; - char reserved2; - unsigned char dlc_max_sap; - unsigned char dlc_max_sta; - unsigned char dlc_max_gsap; - unsigned char dlc_max_gmem; - unsigned char dlc_t1_tick_1; - unsigned char dlc_t2_tick_1; - unsigned char dlc_ti_tick_1; - unsigned char dlc_t1_tick_2; - unsigned char dlc_t2_tick_2; - unsigned char dlc_ti_tick_2; - unsigned char product_id[18]; +struct tok_info { + unsigned char irq; + __u32 mmio; + unsigned char hw_address[32]; + unsigned char adapter_type; + unsigned char data_rate; + unsigned char token_release; + unsigned char avail_shared_ram; + unsigned char shared_ram_paging; + unsigned char dhb_size4mb; + unsigned char dhb_size16mb; + /* Additions by David Morris */ + unsigned char do_tok_int; + struct wait_queue *wait_for_tok_int; + struct wait_queue *wait_for_reset; + unsigned char sram_base; + /* Additions by Peter De Schrijver */ + unsigned char page_mask; /* mask to select RAM page to Map*/ + unsigned char mapped_ram_size; /* size of RAM page */ + __u32 sram; /* Shared memory base address */ + __u32 init_srb; /* Initial System Request Block address */ + __u32 srb; /* System Request Block address */ + __u32 ssb; /* System Status Block address */ + __u32 arb; /* Adapter Request Block address */ + __u32 asb; /* Adapter Status Block address */ + unsigned short exsap_station_id; + unsigned short global_int_enable; + struct sk_buff *current_skb; + struct tr_statistics tr_stats; + unsigned char auto_ringspeedsave; + open_state open_status; }; -struct srb_open_response { - unsigned char command; - unsigned char reserved1; - unsigned char ret_code; - unsigned char reserved2[3]; - unsigned short error_code; - unsigned short asb_addr; - unsigned short srb_addr; - unsigned short arb_addr; - unsigned short ssb_addr; -}; +/* token ring adapter commands */ +#define DIR_INTERRUPT 0x00 /* struct srb_interrupt */ +#define DIR_MOD_OPEN_PARAMS 0x01 +#define DIR_OPEN_ADAPTER 0x03 /* struct dir_open_adapter */ +#define DIR_CLOSE_ADAPTER 0x04 +#define DIR_SET_GRP_ADDR 0x06 +#define DIR_SET_FUNC_ADDR 0x07 +#define DIR_READ_LOG 0x08 /* struct srb_read_log */ +#define DLC_OPEN_SAP 0x15 /* struct dlc_open_sap */ +#define DLC_CLOSE_SAP 0x16 +#define DATA_LOST 0x20 /* struct asb_rec */ +#define REC_DATA 0x81 /* struct arb_rec_req */ +#define XMIT_DATA_REQ 0x82 /* struct arb_xmit_req */ +#define DLC_STATUS 0x83 /* struct arb_dlc_status */ +#define RING_STAT_CHANGE 0x84 /* struct dlc_open_sap ??? */ /* DIR_OPEN_ADAPTER options */ - #define OPEN_PASS_BCON_MAC 0x0100 #define NUM_RCV_BUF 16 #define RCV_BUF_LEN 136 @@ -275,164 +233,197 @@ struct srb_open_response { #define DLC_MAX_SAP 2 #define DLC_MAX_STA 1 -#define DLC_OPEN_SAP 0x15 - -struct dlc_open_sap { - unsigned char command; - unsigned char reserved1; - unsigned char ret_code; - unsigned char reserved2; - unsigned short station_id; - unsigned char timer_t1; - unsigned char timer_t2; - unsigned char timer_ti; - unsigned char maxout; - unsigned char maxin; - unsigned char maxout_incr; - unsigned char max_retry_count; - unsigned char gsap_max_mem; - unsigned short max_i_field; - unsigned char sap_value; - unsigned char sap_options; - unsigned char station_count; - unsigned char sap_gsap_mem; - unsigned char gsap[0]; -}; - /* DLC_OPEN_SAP options */ - #define MAX_I_FIELD 0x0088 #define SAP_OPEN_IND_SAP 0x04 #define SAP_OPEN_PRIORITY 0x20 #define SAP_OPEN_STATION_CNT 0x1 - -#define XMIT_DIR_FRAME 0x0a +#define XMIT_DIR_FRAME 0x0A #define XMIT_UI_FRAME 0x0d #define XMIT_XID_CMD 0x0e #define XMIT_TEST_CMD 0x11 +/* srb close return code */ +#define SIGNAL_LOSS 0x8000 +#define HARD_ERROR 0x4000 +#define XMIT_BEACON 0x1000 +#define LOBE_FAULT 0x0800 +#define AUTO_REMOVAL 0x0400 +#define REMOVE_RECV 0x0100 +#define LOG_OVERFLOW 0x0080 +#define RING_RECOVER 0x0020 + +struct srb_init_response { + unsigned char command; + unsigned char init_status; + unsigned char init_status_2; + unsigned char reserved[3]; + __u16 bring_up_code; + __u16 encoded_address; + __u16 level_address; + __u16 adapter_address; + __u16 parms_address; + __u16 mac_address; +}; + +struct dir_open_adapter { + unsigned char command; + char reserved[7]; + __u16 open_options; + unsigned char node_address[6]; + unsigned char group_address[4]; + unsigned char funct_address[4]; + __u16 num_rcv_buf; + __u16 rcv_buf_len; + __u16 dhb_length; + unsigned char num_dhb; + char reserved2; + unsigned char dlc_max_sap; + unsigned char dlc_max_sta; + unsigned char dlc_max_gsap; + unsigned char dlc_max_gmem; + unsigned char dlc_t1_tick_1; + unsigned char dlc_t2_tick_1; + unsigned char dlc_ti_tick_1; + unsigned char dlc_t1_tick_2; + unsigned char dlc_t2_tick_2; + unsigned char dlc_ti_tick_2; + unsigned char product_id[18]; +}; + +struct srb_open_response { + unsigned char command; + unsigned char reserved1; + unsigned char ret_code; + unsigned char reserved2[3]; + __u16 error_code; + __u16 asb_addr; + __u16 srb_addr; + __u16 arb_addr; + __u16 ssb_addr; +}; + +struct dlc_open_sap { + unsigned char command; + unsigned char reserved1; + unsigned char ret_code; + unsigned char reserved2; + __u16 station_id; + unsigned char timer_t1; + unsigned char timer_t2; + unsigned char timer_ti; + unsigned char maxout; + unsigned char maxin; + unsigned char maxout_incr; + unsigned char max_retry_count; + unsigned char gsap_max_mem; + __u16 max_i_field; + unsigned char sap_value; + unsigned char sap_options; + unsigned char station_count; + unsigned char sap_gsap_mem; + unsigned char gsap[0]; +}; + struct srb_xmit { - unsigned char command; - unsigned char cmd_corr; - unsigned char ret_code; - unsigned char reserved1; - unsigned short station_id; + unsigned char command; + unsigned char cmd_corr; + unsigned char ret_code; + unsigned char reserved1; + __u16 station_id; }; -#define DIR_INTERRUPT 0x00 struct srb_interrupt { - unsigned char command; - unsigned char cmd_corr; - unsigned char ret_code; + unsigned char command; + unsigned char cmd_corr; + unsigned char ret_code; }; -#define DIR_READ_LOG 0x08 struct srb_read_log { - unsigned char command; - unsigned char reserved1; - unsigned char ret_code; - unsigned char reserved2; - unsigned char line_errors; - unsigned char internal_errors; - unsigned char burst_errors; - unsigned char A_C_errors; - unsigned char abort_delimiters; - unsigned char reserved3; - unsigned char lost_frames; - unsigned char recv_congest_count; - unsigned char frame_copied_errors; - unsigned char frequency_errors; - unsigned char token_errors; + unsigned char command; + unsigned char reserved1; + unsigned char ret_code; + unsigned char reserved2; + unsigned char line_errors; + unsigned char internal_errors; + unsigned char burst_errors; + unsigned char A_C_errors; + unsigned char abort_delimiters; + unsigned char reserved3; + unsigned char lost_frames; + unsigned char recv_congest_count; + unsigned char frame_copied_errors; + unsigned char frequency_errors; + unsigned char token_errors; }; struct asb_xmit_resp { - unsigned char command; - unsigned char cmd_corr; - unsigned char ret_code; - unsigned char reserved; - unsigned short station_id; - unsigned short frame_length; - unsigned char hdr_length; - unsigned char rsap_value; + unsigned char command; + unsigned char cmd_corr; + unsigned char ret_code; + unsigned char reserved; + __u16 station_id; + __u16 frame_length; + unsigned char hdr_length; + unsigned char rsap_value; }; -#define XMIT_DATA_REQ 0x82 struct arb_xmit_req { - unsigned char command; - unsigned char cmd_corr; - unsigned char reserved1[2]; - unsigned short station_id; - unsigned short dhb_address; + unsigned char command; + unsigned char cmd_corr; + unsigned char reserved1[2]; + __u16 station_id; + __u16 dhb_address; }; -#define REC_DATA 0x81 struct arb_rec_req { - unsigned char command; - unsigned char reserved1[3]; - unsigned short station_id; - unsigned short rec_buf_addr; - unsigned char lan_hdr_len; - unsigned char dlc_hdr_len; - unsigned short frame_len; - unsigned char msg_type; + unsigned char command; + unsigned char reserved1[3]; + __u16 station_id; + __u16 rec_buf_addr; + unsigned char lan_hdr_len; + unsigned char dlc_hdr_len; + __u16 frame_len; + unsigned char msg_type; }; -#define DATA_LOST 0x20 struct asb_rec { - unsigned char command; - unsigned char reserved1; - unsigned char ret_code; - unsigned char reserved2; - unsigned short station_id; - unsigned short rec_buf_addr; + unsigned char command; + unsigned char reserved1; + unsigned char ret_code; + unsigned char reserved2; + __u16 station_id; + __u16 rec_buf_addr; }; struct rec_buf { - unsigned char reserved1[2]; - unsigned short buf_ptr; - unsigned char reserved2; - unsigned short buf_len; - unsigned char data[0]; + unsigned char reserved1[2]; + __u16 buf_ptr; + unsigned char reserved2; + __u16 buf_len; + unsigned char data[0]; }; -#define DLC_STATUS 0x83 struct arb_dlc_status { - unsigned char command; - unsigned char reserved1[3]; - unsigned short station_id; - unsigned short status; - unsigned char frmr_data[5]; - unsigned char access_prio; - unsigned char rem_addr[TR_ALEN]; - unsigned char rsap_value; + unsigned char command; + unsigned char reserved1[3]; + __u16 station_id; + __u16 status; + unsigned char frmr_data[5]; + unsigned char access_prio; + unsigned char rem_addr[TR_ALEN]; + unsigned char rsap_value; }; -#define RING_STAT_CHANGE 0x84 struct arb_ring_stat_change { - unsigned char command; - unsigned char reserved1[5]; - unsigned short ring_status; + unsigned char command; + unsigned char reserved1[5]; + __u16 ring_status; }; -#define DIR_CLOSE_ADAPTER 0x04 struct srb_close_adapter { - unsigned char command; - unsigned char reserved1; - unsigned char ret_code; + unsigned char command; + unsigned char reserved1; + unsigned char ret_code; }; -#define DIR_MOD_OPEN_PARAMS 0x01 -#define DIR_SET_GRP_ADDR 0x06 -#define DIR_SET_FUNC_ADDR 0x07 -#define DLC_CLOSE_SAP 0x16 - - -#define SIGNAL_LOSS 0x8000 -#define HARD_ERROR 0x4000 -#define XMIT_BEACON 0x1000 -#define LOBE_FAULT 0x0800 -#define AUTO_REMOVAL 0x0400 -#define REMOVE_RECV 0x0100 -#define LOG_OVERFLOW 0x0080 -#define RING_RECOVER 0x0020 - diff --git a/drivers/net/loopback.c b/drivers/net/loopback.c index d96a6e2a6a6e..b709ff40c851 100644 --- a/drivers/net/loopback.c +++ b/drivers/net/loopback.c @@ -34,8 +34,6 @@ #include #include #include -#include /* For the statistics structure. */ -#include /* For ARPHRD_ETHER */ #include #include @@ -46,6 +44,8 @@ #include #include #include +#include /* For the statistics structure. */ +#include /* For ARPHRD_ETHER */ #define LOOPBACK_MTU (PAGE_SIZE*7/8) @@ -72,7 +72,7 @@ static int loopback_xmit(struct sk_buff *skb, struct device *dev) skb=skb_clone(skb, GFP_ATOMIC); /* Clone the buffer */ if(skb==NULL) return 1; - dev_kfree_skb(skb2, FREE_READ); + dev_kfree_skb(skb2, FREE_WRITE); unlock=0; } else if(skb->sk) @@ -81,7 +81,7 @@ static int loopback_xmit(struct sk_buff *skb, struct device *dev) * Packet sent but looped back around. Cease to charge * the socket for the frame. */ - skb->sk->wmem_alloc-=skb->truesize; + atomic_sub(skb->truesize, &skb->sk->wmem_alloc); skb->sk->write_space(skb->sk); } diff --git a/drivers/net/net_init.c b/drivers/net/net_init.c index b6745841b9f8..41009984f342 100644 --- a/drivers/net/net_init.c +++ b/drivers/net/net_init.c @@ -29,11 +29,11 @@ #include #include #include -#include #include #include #include #include +#include #ifdef CONFIG_NET_ALIAS #include #endif diff --git a/drivers/net/new_tunnel.c b/drivers/net/new_tunnel.c index 434476d7def7..62b15f52b561 100644 --- a/drivers/net/new_tunnel.c +++ b/drivers/net/new_tunnel.c @@ -273,8 +273,9 @@ printk("Required room: %d, Tunnel hlen: %d\n", max_headroom, TUNL_HLEN); /* * Push down and install the IPIP header. */ - iph = skb->h.iph; - iph->version = 4; + + iph = skb->h.iph; + iph->version = 4; iph->tos = skb->ip_hdr->tos; iph->ttl = skb->ip_hdr->ttl; iph->frag_off = 0; @@ -285,8 +286,8 @@ printk("Required room: %d, Tunnel hlen: %d\n", max_headroom, TUNL_HLEN); iph->tot_len = htons(skb->len); iph->id = htons(ip_id_count++); /* Race condition here? */ ip_send_check(iph); - skb->ip_hdr = skb->h.iph; - + skb->ip_hdr = skb->h.iph; + skb->protocol = htons(ETH_P_IP); #ifdef TUNNEL_DEBUG printk("New IP Header....\n"); print_ip(iph); @@ -317,8 +318,7 @@ printk("Required room: %d, Tunnel hlen: %d\n", max_headroom, TUNL_HLEN); return 0; } -static struct enet_statistics * -tunnel_get_stats(struct device *dev) +static struct enet_statistics *tunnel_get_stats(struct device *dev) { return((struct enet_statistics*) dev->priv); } @@ -336,7 +336,7 @@ int tunnel_init(struct device *dev) static int tun_msg=0; if(!tun_msg) { - printk ( KERN_INFO "tunnel: version v0.2b\n" ); + printk ( KERN_INFO "tunnel: version v0.2b2\n" ); tun_msg=1; } @@ -393,11 +393,13 @@ static int tunnel_probe(struct device *dev) return 0; } -static struct device dev_tunnel = { +static struct device dev_tunnel = +{ "tunl0\0 ", 0, 0, 0, 0, 0x0, 0, - 0, 0, 0, NULL, tunnel_probe }; + 0, 0, 0, NULL, tunnel_probe + }; int init_module(void) { diff --git a/drivers/net/sdla.c b/drivers/net/sdla.c new file mode 100644 index 000000000000..c85a30762340 --- /dev/null +++ b/drivers/net/sdla.c @@ -0,0 +1,1639 @@ +/* + * SDLA An implementation of a driver for the Sangoma S502/S508 series + * multi-protocol PC interface card. Initial offering is with + * the DLCI driver, providing Frame Relay support for linux. + * + * Global definitions for the Frame relay interface. + * + * Version: @(#)sdla.c 0.10 23 Mar 1996 + * + * Credits: Sangoma Technologies, for the use of 2 cards for an extended + * period of time. + * David Mandelstam for getting me started on + * this project, and incentive to complete it. + * Gene Kozen <74604.152@compuserve.com> for providing me with + * important information about the cards. + * + * Author: Mike McLagan + * + * 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. + */ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include + +#include + +static const char* version = "SDLA driver v0.10, 23 Mar 1996, mike.mclagan@linux.org"; + +static const char* devname = "sdla"; + +static unsigned int valid_port[] = { 0x250, 0x270, 0x280, 0x300, 0x350, 0x360, 0x380, 0x390}; + +static unsigned int valid_mem[] = {0xA0000, 0xA2000, 0xA4000, 0xA6000, 0xA8000, 0xAA000, 0xAC000, 0xAE000, + 0xB0000, 0xB2000, 0xB4000, 0xB6000, 0xB8000, 0xBA000, 0xBC000, 0xBE000, + 0xC0000, 0xC2000, 0xC4000, 0xC6000, 0xC8000, 0xCA000, 0xCC000, 0xCE000, + 0xD0000, 0xD2000, 0xD4000, 0xD6000, 0xD8000, 0xDA000, 0xDC000, 0xDE000, + 0xE0000, 0xE2000, 0xE4000, 0xE6000, 0xE8000, 0xEA000, 0xEC000, 0xEE000}; + +/********************************************************* + * + * these are the core routines that access the card itself + * + *********************************************************/ + +#define SDLA_WINDOW(dev,addr) outb((((addr) >> 13) & 0x1F), (dev)->base_addr + SDLA_REG_Z80_WINDOW) + +static void sdla_read(struct device *dev, int addr, void *buf, short len) +{ + unsigned long flags; + char *temp, *base; + int offset, bytes; + + temp = buf; + while(len) + { + offset = addr & 0x1FFF; + if (offset + len > 0x2000) + bytes = 0x2000 - offset; + else + bytes = len; + + base = (void *) dev->mem_start; + base += offset; + + save_flags(flags); + cli(); + SDLA_WINDOW(dev, addr); + memcpy(temp, base, bytes); + restore_flags(flags); + + addr += bytes; + temp += bytes; + len -= bytes; + } +} + +static void sdla_write(struct device *dev, int addr, void *buf, short len) +{ + unsigned long flags; + char *temp, *base; + int offset, bytes; + + temp = buf; + while(len) + { + offset = addr & 0x1FFF; + if (offset + len > 0x2000) + bytes = 0x2000 - offset; + else + bytes = len; + + base = (void *) dev->mem_start; + base += offset; + + save_flags(flags); + cli(); + SDLA_WINDOW(dev, addr); + memcpy(base, temp, bytes); + restore_flags(flags); + + addr += bytes; + temp += bytes; + len -= bytes; + } +} + +static void sdla_clear(struct device *dev) +{ + unsigned long flags; + char *base; + int offset, len, addr, bytes; + + len = 65536; + addr = 0; + while(len) + { + offset = addr & 0x1FFF; + if (offset + len > 0x2000) + bytes = offset + len - 0x2000; + else + bytes = len; + + base = (void *) dev->mem_start; + base += offset; + + save_flags(flags); + cli(); + SDLA_WINDOW(dev, addr); + memset(base, 0, bytes); + restore_flags(flags); + + addr += bytes; + len -= bytes; + } +} + +static char sdla_byte(struct device *dev, int addr) +{ + unsigned long flags; + char byte, *temp; + + temp = (void *) dev->mem_start; + temp += addr & 0x1FFF; + + save_flags(flags); + cli(); + SDLA_WINDOW(dev, addr); + byte = *temp; + restore_flags(flags); + + return(byte); +} + +void sdla_stop(struct device *dev) +{ + struct frad_local *flp; + + flp = dev->priv; + switch(flp->type) + { + case SDLA_S502A: + outb(SDLA_S502A_HALT, dev->base_addr + SDLA_REG_CONTROL); + flp->state = SDLA_HALT; + break; + case SDLA_S502E: + outb(SDLA_HALT, dev->base_addr + SDLA_REG_Z80_CONTROL); + outb(SDLA_S502E_ENABLE, dev->base_addr + SDLA_REG_CONTROL); + flp->state = SDLA_S502E_ENABLE; + break; + case SDLA_S507: + flp->state &= ~SDLA_CPUEN; + outb(flp->state, dev->base_addr + SDLA_REG_CONTROL); + break; + case SDLA_S508: + flp->state &= ~SDLA_CPUEN; + outb(flp->state, dev->base_addr + SDLA_REG_CONTROL); + break; + } +} + +void sdla_start(struct device *dev) +{ + struct frad_local *flp; + + flp = dev->priv; + switch(flp->type) + { + case SDLA_S502A: + outb(SDLA_S502A_NMI, dev->base_addr + SDLA_REG_CONTROL); + outb(SDLA_S502A_START, dev->base_addr + SDLA_REG_CONTROL); + flp->state = SDLA_S502A_START; + break; + case SDLA_S502E: + outb(SDLA_S502E_CPUEN, dev->base_addr + SDLA_REG_Z80_CONTROL); + outb(0x00, dev->base_addr + SDLA_REG_CONTROL); + flp->state = 0; + break; + case SDLA_S507: + flp->state |= SDLA_CPUEN; + outb(flp->state, dev->base_addr + SDLA_REG_CONTROL); + break; + case SDLA_S508: + flp->state |= SDLA_CPUEN; + outb(flp->state, dev->base_addr + SDLA_REG_CONTROL); + break; + } +} + +/**************************************************** + * + * this is used for the S502A/E cards to determine + * the speed of the onboard CPU. Calibration is + * necessary for the Frame Relay code uploaded + * later. Incorrect results cause timing problems + * with link checks & status messages + * + ***************************************************/ + +int sdla_z80_poll(struct device *dev, int z80_addr, int jiffs, char resp1, char resp2) +{ + unsigned long start, done, now; + char resp, *temp; + + start = now = jiffies; + done = jiffies + jiffs; + + temp = (void *)dev->mem_start; + temp += z80_addr & 0x1FFF; + + resp = ~resp1; + while ((jiffies < done) && (resp != resp1) && (!resp2 || (resp != resp2))) + { + if (jiffies != now) + { + SDLA_WINDOW(dev, z80_addr); + now = jiffies; + resp = *temp; + } + } + return(jiffies < done ? jiffies - start : -1); +} + +/* constants for Z80 CPU speed */ +#define Z80_READY '1' /* Z80 is ready to begin */ +#define LOADER_READY '2' /* driver is ready to begin */ +#define Z80_SCC_OK '3' /* SCC is on board */ +#define Z80_SCC_BAD '4' /* SCC was not found */ + +static int sdla_cpuspeed(struct device *dev, struct ifreq *ifr) +{ + int jiffs; + char data; + + sdla_start(dev); + if (sdla_z80_poll(dev, 0, 3*HZ, Z80_READY, 0) < 0) + return(-EIO); + + data = LOADER_READY; + sdla_write(dev, 0, &data, 1); + + if ((jiffs = sdla_z80_poll(dev, 0, 8*HZ, Z80_SCC_OK, Z80_SCC_BAD)) < 0) + return(-EIO); + + sdla_stop(dev); + sdla_read(dev, 0, &data, 1); + + if (data == Z80_SCC_BAD) + return(-EIO); + + if (data != Z80_SCC_OK) + return(-EINVAL); + + if (jiffs < 165) + ifr->ifr_mtu = SDLA_CPU_16M; + else + if (jiffs < 220) + ifr->ifr_mtu = SDLA_CPU_10M; + else + if (jiffs < 258) + ifr->ifr_mtu = SDLA_CPU_8M; + else + if (jiffs < 357) + ifr->ifr_mtu = SDLA_CPU_7M; + else + if (jiffs < 467) + ifr->ifr_mtu = SDLA_CPU_5M; + else + ifr->ifr_mtu = SDLA_CPU_3M; + + return(0); +} + +/************************************************ + * + * Direct interaction with the Frame Relay code + * starts here. + * + ************************************************/ + +struct _dlci_stat { + short dlci __attribute__((packed)); + char flags __attribute__((packed)); +}; + +struct _frad_stat { + char flags; + struct _dlci_stat dlcis[SDLA_MAX_DLCI]; +}; + +static void sdla_errors(struct device *dev, int cmd, int dlci, int ret, int len, void *data) +{ + struct _dlci_stat *pstatus; + short *pdlci; + int i; + char *state; + + switch (ret) + { + case SDLA_RET_MODEM: + state = data; + if (*state & SDLA_MODEM_DCD_LOW) + printk(KERN_NOTICE "%s: Modem DCD unexpectedly low!\n", dev->name); + if (*state & SDLA_MODEM_CTS_LOW) + printk(KERN_NOTICE "%s: Modem CTS unexpectedly low!\n", dev->name); +/* I should probably do something about this! */ + break; + + case SDLA_RET_CHANNEL_OFF: + printk(KERN_NOTICE "%s: Channel became inoperative!\n", dev->name); +/* same here */ + break; + + case SDLA_RET_CHANNEL_ON: + printk(KERN_NOTICE "%s: Channel became operative!\n", dev->name); +/* same here */ + break; + + case SDLA_RET_DLCI_STATUS: + printk(KERN_NOTICE "%s: Status change reported by Access Node.\n", dev->name); + len /= sizeof(struct _dlci_stat); + for(pstatus = data, i=0;i < len;i++,pstatus++) + { + if (pstatus->flags & SDLA_DLCI_NEW) + state = "new"; + else + if (pstatus->flags & SDLA_DLCI_DELETED) + state = "deleted"; + else + if (pstatus->flags & SDLA_DLCI_ACTIVE) + state = "active"; + else + state = "unknown status"; + + printk(KERN_NOTICE "%s: DLCI %i: %s.\n", dev->name, pstatus->dlci, state); +/* same here */ + } + break; + + case SDLA_RET_DLCI_UNKNOWN: + printk(KERN_DEBUG "%s: Received unknown DLCIs:", dev->name); + len /= 2; + for(pdlci = data,i=0;i < len;i++,pdlci++) + printk(" %i", *pdlci); + printk("\n"); + break; + + case SDLA_RET_TIMEOUT: + printk(KERN_ERR "%s: Command timed out!\n", dev->name); + break; + + default: + /* + * Further processing could be done here + * printk(KERN_DEBUG "%s: Unhandled return code 0x%2.2X\n", dev->name, ret); + * + */ + } +} + +static int sdla_cmd(struct device *dev, int cmd, short dlci, short flags, + void *inbuf, short inlen, void *outbuf, short *outlen) +{ + static struct _frad_stat status; + struct frad_local *flp; + struct sdla_cmd *cmd_buf; + unsigned long pflags; + int jiffs, ret, waiting, len; + long temp, window; + + flp = dev->priv; + + window = flp->type == SDLA_S508 ? SDLA_508_CMD_BUF : SDLA_502_CMD_BUF; + temp = (int) dev->mem_start; + temp += window & 0x1FFF; + cmd_buf = (struct sdla_cmd *)temp; + ret = 0; + jiffs = jiffies + HZ / 2; /* 1/2 second timeout */ + save_flags(pflags); + cli(); + SDLA_WINDOW(dev, window); + cmd_buf->cmd = cmd; + cmd_buf->dlci = dlci; + cmd_buf->flags = flags; + + if (inbuf) + memcpy(cmd_buf->data, inbuf, inlen); + + cmd_buf->length = inlen; + + cmd_buf->opp_flag = 1; + restore_flags(pflags); + + waiting = 1; + len = 0; + while (waiting && (jiffies <= jiffs)) + { + if (waiting++ % 4) + { + save_flags(pflags); + cli(); + SDLA_WINDOW(dev, window); + waiting = ((volatile)(cmd_buf->opp_flag)); + restore_flags(pflags); + } + } + + if (!waiting) + { + save_flags(pflags); + cli(); + SDLA_WINDOW(dev, window); + ret = cmd_buf->retval; + len = cmd_buf->length; + if (outbuf && len) + { + *outlen = *outlen >= len ? len : *outlen; + memcpy(outbuf, cmd_buf->data, *outlen); + } + if (ret) + memcpy(&status, cmd_buf->data, len); + restore_flags(pflags); + } + else + ret = SDLA_RET_TIMEOUT; + + if (ret != SDLA_RET_OK) + sdla_errors(dev, cmd, dlci, ret, len, &status); + + return(ret); +} + +/*********************************************** + * + * these functions are called by the DLCI driver + * + ***********************************************/ + +static int sdla_reconfig(struct device *dev); + +int sdla_activate(struct device *slave, struct device *master) +{ + struct frad_local *flp; + int i; + + flp = slave->priv; + + for(i=0;imaster[i] == master) + break; + + if (i == CONFIG_DLCI_MAX) + return(-ENODEV); + + flp->dlci[i] = abs(flp->dlci[i]); + + if (slave->start && (flp->config.station == FRAD_STATION_NODE)) + sdla_cmd(slave, SDLA_ACTIVATE_DLCI, 0, 0, &flp->dlci[i], sizeof(short), NULL, NULL); + + return(0); +} + +int sdla_deactivate(struct device *slave, struct device *master) +{ + struct frad_local *flp; + int i; + + flp = slave->priv; + + for(i=0;imaster[i] == master) + break; + + flp->dlci[i] = -abs(flp->dlci[i]); + + if (slave->start && (flp->config.station == FRAD_STATION_NODE)) + sdla_cmd(slave, SDLA_DEACTIVATE_DLCI, 0, 0, &flp->dlci[i], sizeof(short), NULL, NULL); + + return(0); +} + +int sdla_assoc(struct device *slave, struct device *master) +{ + struct frad_local *flp; + int i; + + if (master->type != ARPHRD_DLCI) + return(-EINVAL); + + flp = slave->priv; + + for(i=0;imaster[i]) + break; + if (abs(flp->dlci[i]) == *(short *)(master->dev_addr)) + return(-EADDRINUSE); + } + + if (i == CONFIG_DLCI_MAX) + return(-EMLINK); /* #### Alan: Comments on this ?? */ + + MOD_INC_USE_COUNT; + + flp->master[i] = master; + flp->dlci[i] = -*(short *)(master->dev_addr); + master->mtu = slave->mtu; + + if (slave->start) + if (flp->config.station == FRAD_STATION_CPE) + sdla_reconfig(slave); + else + sdla_cmd(slave, SDLA_ADD_DLCI, 0, 0, master->dev_addr, sizeof(short), NULL, NULL); + + return(0); +} + +int sdla_deassoc(struct device *slave, struct device *master) +{ + struct frad_local *flp; + int i; + + flp = slave->priv; + + for(i=0;imaster[i] == master) + break; + + if (i == CONFIG_DLCI_MAX) + return(-ENODEV); + + flp->master[i] = NULL; + flp->dlci[i] = 0; + + MOD_DEC_USE_COUNT; + + if (slave->start) + if (flp->config.station == FRAD_STATION_CPE) + sdla_reconfig(slave); + else + sdla_cmd(slave, SDLA_DELETE_DLCI, 0, 0, master->dev_addr, sizeof(short), NULL, NULL); + + return(0); +} + +int sdla_dlci_conf(struct device *slave, struct device *master, int get) +{ + struct frad_local *flp; + struct frad_local *dlp; + int i; + + flp = slave->priv; + + for(i=0;imaster[i] == master) + break; + + if (i == CONFIG_DLCI_MAX) + return(-ENODEV); + + dlp = master->priv; + if (slave->start) + sdla_cmd(slave, SDLA_SET_DLCI_CONFIGURATION, flp->dlci[i], 0, + &dlp->config, sizeof(struct dlci_conf) - 4 * sizeof(short), NULL, NULL); + + return(0); +} + +/************************** + * + * now for the Linux driver + * + **************************/ + +static int sdla_transmit(struct sk_buff *skb, struct device *dev) +{ + struct frad_local *flp; + int ret, addr; + short size; + unsigned long flags; + struct buf_entry *pbuf; + + flp = dev->priv; + ret = 0; + + if (dev->tbusy) + return(1); + + if (skb == NULL) + return(0); + + if (set_bit(0, (void*)&dev->tbusy) != 0) + printk(KERN_WARNING "%s: transmitter access conflict.\n", dev->name); + else + { + switch (flp->type) + { + case SDLA_S502A: + case SDLA_S502E: + ret = sdla_cmd(dev, SDLA_INFORMATION_WRITE, *(short *)(skb->dev->dev_addr), 0, skb->data, skb->len, NULL, NULL); + break; + + case SDLA_S508: + size = sizeof(addr); + ret = sdla_cmd(dev, SDLA_INFORMATION_WRITE, *(short *)(skb->dev->dev_addr), 0, NULL, skb->len, &addr, &size); + if (ret == SDLA_RET_OK) + { + save_flags(flags); + cli(); + SDLA_WINDOW(dev, addr); + pbuf = (void *)(((int) dev->mem_start) + (addr & 0x1FFF)); + + sdla_write(dev, pbuf->buf_addr, skb->data, skb->len); + + SDLA_WINDOW(dev, addr); + pbuf->opp_flag = 1; + restore_flags(flags); + } + break; + } + + switch (ret) + { + case SDLA_RET_OK: + flp->stats.tx_packets++; + ret = 0; + break; + + default: + flp->stats.tx_errors++; + ret = 1; + } + + /* per Alan Cox, we can drop the packet on the floor if it doesn't go */ + dev_kfree_skb(skb, FREE_WRITE); + + dev->tbusy = 0; + } + return(ret); +} + +static void sdla_receive(struct device *dev) +{ + struct device *master; + struct frad_local *flp; + struct dlci_local *dlp; + struct sk_buff *skb; + + struct sdla_cmd *cmd; + struct buf_info *pbufi; + struct buf_entry *pbuf; + + unsigned long flags; + int i, received, success, addr; + short dlci, len, split; + char bogus; + + flp = dev->priv; + bogus = 0; + success = 0; + received = 0; + addr = 0; + skb = NULL; + master = NULL; + + save_flags(flags); + cli(); + + switch (flp->type) + { + case SDLA_S502A: + case SDLA_S502E: + cmd = (void *) (dev->mem_start + (SDLA_502_RCV_BUF & 0x1FFF)); + SDLA_WINDOW(dev, SDLA_502_RCV_BUF); + if (!cmd->opp_flag) + break; + + dlci = cmd->dlci; + len = cmd->length; + + for (i=0;idlci[i] == dlci) + break; + + if (i == CONFIG_DLCI_MAX) + { + printk(KERN_NOTICE "%s: Recieved packet from invalid DLCI %i, ignoring.", dev->name, dlci); + flp->stats.rx_errors++; + cmd->opp_flag = 0; + break; + } + + master = flp->master[i]; + skb = dev_alloc_skb(len); + if (skb == NULL) + { + printk(KERN_NOTICE "%s: Memory squeeze, dropping packet.\n", dev->name); + flp->stats.rx_dropped++; + cmd->opp_flag = 0; + break; + } + + /* pick up the data */ + sdla_read(dev, dev->mem_start + ((SDLA_502_RCV_BUF + SDLA_502_DATA_OFS) & 0x1FFF), skb_put(skb,len), len); + cmd->opp_flag = 0; + success = 1; + break; + + case SDLA_S508: + pbufi = (void *) (dev->mem_start + (SDLA_508_RXBUF_INFO & 0x1FFF)); + SDLA_WINDOW(dev, SDLA_508_RXBUF_INFO); + pbuf = (void *) (dev->mem_start + ((pbufi->rse_base + flp->buffer * sizeof(struct buf_entry)) & 0x1FFF)); + if (!pbuf->opp_flag) + break; + + dlci = pbuf->dlci; + len = pbuf->length; + addr = pbuf->buf_addr; + + for (i=0;idlci[i] == dlci) + break; + + if (i == CONFIG_DLCI_MAX) + { + printk(KERN_NOTICE "%s: Recieved packet from invalid DLCI %i, ignoring.", dev->name, dlci); + flp->stats.rx_errors++; + pbuf->opp_flag = 0; + break; + } + + master = flp->master[i]; + skb = dev_alloc_skb(len); + if (skb == NULL) + { + printk(KERN_NOTICE "%s: Memory squeeze, dropping packet.\n", dev->name); + flp->stats.rx_dropped++; + pbuf->opp_flag = 0; + break; + } + + /* is this buffer split off the end of the internal ring buffer */ + split = addr + len > pbufi->buf_top + 1 ? pbufi->buf_top - addr + 1 : 0; + len -= split; + + /* lets get the data */ + sdla_read(dev, addr, skb_put(skb, len), len); + if (split) + { + SDLA_WINDOW(dev, SDLA_508_RXBUF_INFO); + sdla_read(dev, pbufi->buf_base, skb_put(skb, split), split); + } + + SDLA_WINDOW(dev, SDLA_508_RXBUF_INFO); + pbuf->opp_flag = 0; + success = 1; + + /* increment the buffer we're looking at */ + flp->buffer = (flp->buffer + 1) % pbufi->rse_num; + break; + } + + if (success) + { + flp->stats.rx_packets++; + dlp = master->priv; + (*dlp->receive)(skb, master); + } + + restore_flags(flags); +} + +static void sdla_isr(int irq, void *dev_id, struct pt_regs * regs) +{ + struct device *dev; + struct frad_local *flp; + char byte; + + dev = irq2dev_map[irq]; + + if (dev == NULL) + { + printk(KERN_WARNING "sdla_isr(): irq %d for unknown device.\n", irq); + return; + } + + flp = dev->priv; + + if (!flp->initialized) + { + printk(KERN_WARNING "%s: irq %d for unintialiazed device.\n", dev->name, irq); + return; + } + + dev->interrupt = 1; + byte = sdla_byte(dev, flp->type == SDLA_S508 ? SDLA_508_IRQ_INTERFACE : SDLA_502_IRQ_INTERFACE); + switch (byte) + { + case SDLA_INTR_RX: + sdla_receive(dev); + break; + + /* the command will get an error return, which is processed above */ + case SDLA_INTR_MODEM: + case SDLA_INTR_STATUS: + sdla_cmd(dev, SDLA_READ_DLC_STATUS, 0, 0, NULL, 0, NULL, NULL); + break; + + case SDLA_INTR_TX: + case SDLA_INTR_COMPLETE: + case SDLA_INTR_TIMER: + printk(KERN_WARNING "%s: invalid irq flag 0x%02X.\n", dev->name, byte); + break; + } + + /* the S502E requires a manual acknowledgement of the interrupt */ + if (flp->type == SDLA_S502E) + { + flp->state &= ~SDLA_S502E_INTACK; + outb(flp->state, dev->base_addr + SDLA_REG_CONTROL); + flp->state |= SDLA_S502E_INTACK; + outb(flp->state, dev->base_addr + SDLA_REG_CONTROL); + } + + dev->interrupt = 0; + /* this clears the byte, informing the Z80 we're done */ + byte = 0; + sdla_write(dev, flp->type == SDLA_S508 ? SDLA_508_IRQ_INTERFACE : SDLA_502_IRQ_INTERFACE, &byte, sizeof(byte)); +} + +static void sdla_poll(unsigned long device) +{ + struct device *dev; + struct frad_local *flp; + + dev = (struct device *) device; + flp = dev->priv; + + if (sdla_byte(dev, SDLA_502_RCV_BUF)) + sdla_receive(dev); + + flp->timer.expires = 1; + add_timer(&flp->timer); +} + +static int sdla_close(struct device *dev) +{ + struct frad_local *flp; + struct intr_info intr; + int len, i; + short dlcis[CONFIG_DLCI_MAX]; + + flp = dev->priv; + + len = 0; + for(i=0;idlci[i]) + dlcis[len++] = abs(flp->dlci[i]); + len *= 2; + + if (flp->config.station == FRAD_STATION_NODE) + { + for(i=0;idlci[i] > 0) + sdla_cmd(dev, SDLA_DEACTIVATE_DLCI, 0, 0, dlcis, len, NULL, NULL); + sdla_cmd(dev, SDLA_DELETE_DLCI, 0, 0, &flp->dlci[i], sizeof(flp->dlci[i]), NULL, NULL); + } + + memset(&intr, 0, sizeof(intr)); + /* lets start up the reception */ + switch(flp->type) + { + case SDLA_S502A: + del_timer(&flp->timer); + break; + + case SDLA_S502E: + sdla_cmd(dev, SDLA_SET_IRQ_TRIGGER, 0, 0, &intr, sizeof(char) + sizeof(short), NULL, NULL); + flp->state &= ~SDLA_S502E_INTACK; + outb(flp->state, dev->base_addr + SDLA_REG_CONTROL); + break; + + case SDLA_S507: + break; + + case SDLA_S508: + sdla_cmd(dev, SDLA_SET_IRQ_TRIGGER, 0, 0, &intr, sizeof(struct intr_info), NULL, NULL); + flp->state &= ~SDLA_S508_INTEN; + outb(flp->state, dev->base_addr + SDLA_REG_CONTROL); + break; + } + + sdla_cmd(dev, SDLA_DISABLE_COMMUNICATIONS, 0, 0, NULL, 0, NULL, NULL); + sdla_stop(dev); + + dev->tbusy = 1; + dev->start = 0; + + MOD_DEC_USE_COUNT; + + return(0); +} + +struct conf_data { + struct frad_conf config; + short dlci[CONFIG_DLCI_MAX]; +}; + +static int sdla_open(struct device *dev) +{ + struct frad_local *flp; + struct dlci_local *dlp; + struct conf_data data; + struct intr_info intr; + int len, i; + char byte; + + flp = dev->priv; + + if (!flp->initialized) + return(-EPERM); + + if (!flp->configured) + return(-EPERM); + + /* off to the races! */ + sdla_start(dev); + + /* time to send in the configuration */ + len = 0; + for(i=0;idlci[i]) + data.dlci[len++] = abs(flp->dlci[i]); + len *= 2; + + memcpy(&data.config, &flp->config, sizeof(struct frad_conf)); + len += sizeof(struct frad_conf); + + sdla_cmd(dev, SDLA_DISABLE_COMMUNICATIONS, 0, 0, NULL, 0, NULL, NULL); + sdla_cmd(dev, SDLA_SET_DLCI_CONFIGURATION, 0, 0, &data, len, NULL, NULL); + + if (flp->type == SDLA_S508) + flp->buffer = 0; + + sdla_cmd(dev, SDLA_ENABLE_COMMUNICATIONS, 0, 0, NULL, 0, NULL, NULL); + + /* lets start up the reception */ + memset(&intr, 0, sizeof(intr)); + switch(flp->type) + { + case SDLA_S502A: + flp->timer.expires = 1; + add_timer(&flp->timer); + break; + + case SDLA_S502E: + flp->state |= SDLA_S502E_ENABLE; + outb(flp->state, dev->base_addr + SDLA_REG_CONTROL); + flp->state |= SDLA_S502E_INTACK; + outb(flp->state, dev->base_addr + SDLA_REG_CONTROL); + byte = 0; + sdla_write(dev, SDLA_502_IRQ_INTERFACE, &byte, sizeof(byte)); + intr.flags = SDLA_INTR_RX | SDLA_INTR_STATUS | SDLA_INTR_MODEM; + sdla_cmd(dev, SDLA_SET_IRQ_TRIGGER, 0, 0, &intr, sizeof(char) + sizeof(short), NULL, NULL); + break; + + case SDLA_S507: + break; + + case SDLA_S508: + flp->state |= SDLA_S508_INTEN; + outb(flp->state, dev->base_addr + SDLA_REG_CONTROL); + byte = 0; + sdla_write(dev, SDLA_508_IRQ_INTERFACE, &byte, sizeof(byte)); + intr.flags = SDLA_INTR_RX | SDLA_INTR_STATUS | SDLA_INTR_MODEM; + intr.irq = dev->irq; + sdla_cmd(dev, SDLA_SET_IRQ_TRIGGER, 0, 0, &intr, sizeof(struct intr_info), NULL, NULL); + break; + } + + if (flp->config.station == FRAD_STATION_CPE) + { + byte = SDLA_ICS_STATUS_ENQ; + sdla_cmd(dev, SDLA_ISSUE_IN_CHANNEL_SIGNAL, 0, 0, &byte, sizeof(byte), NULL, NULL); + } + else + { + sdla_cmd(dev, SDLA_ADD_DLCI, 0, 0, data.dlci, len - sizeof(struct frad_conf), NULL, NULL); + for(i=0;idlci[i] > 0) + sdla_cmd(dev, SDLA_ACTIVATE_DLCI, 0, 0, &flp->dlci[i], 2*sizeof(flp->dlci[i]), NULL, NULL); + } + + /* configure any specific DLCI settings */ + for(i=0;idlci[i]) + { + dlp = flp->master[i]->priv; + if (dlp->configured) + sdla_cmd(dev, SDLA_SET_DLCI_CONFIGURATION, abs(flp->dlci[i]), 0, &dlp->config, sizeof(struct dlci_conf), NULL, NULL); + } + + dev->tbusy = 0; + dev->interrupt = 0; + dev->start = 1; + + MOD_INC_USE_COUNT; + + return(0); +} + +static int sdla_config(struct device *dev, struct frad_conf *conf, int get) +{ + struct frad_local *flp; + struct conf_data data; + int i, err; + + if (dev->type == 0xFFFF) + return(-EUNATCH); + + flp = dev->priv; + + if (!get) + { + if (dev->start) + return(-EBUSY); + + err = verify_area(VERIFY_READ, conf, sizeof(struct frad_conf)); + if (err) + return(err); + + memcpy_fromfs(&data.config, conf, sizeof(struct frad_conf)); + + if (data.config.station & ~FRAD_STATION_NODE) + return(-EINVAL); + + if (data.config.flags & ~FRAD_VALID_FLAGS) + return(-EINVAL); + + if ((data.config.kbaud < 0) || + ((data.config.kbaud > 128) && (flp->type != SDLA_S508))) + return(-EINVAL); + + if (data.config.clocking & ~(FRAD_CLOCK_INT | SDLA_S508_PORT_RS232)) + return(-EINVAL); + + if ((data.config.mtu < 0) || (data.config.mtu > SDLA_MAX_MTU)) + return(-EINVAL); + + if ((data.config.T391 < 5) || (data.config.T391 > 30)) + return(-EINVAL); + + if ((data.config.T392 < 5) || (data.config.T392 > 30)) + return(-EINVAL); + + if ((data.config.N391 < 1) || (data.config.N391 > 255)) + return(-EINVAL); + + if ((data.config.N392 < 1) || (data.config.N392 > 10)) + return(-EINVAL); + + if ((data.config.N393 < 1) || (data.config.N393 > 10)) + return(-EINVAL); + + memcpy(&flp->config, &data.config, sizeof(struct frad_conf)); + flp->config.flags |= SDLA_DIRECT_RECV; + + if (dev->mtu != flp->config.mtu) + { + /* this is required to change the MTU */ + dev->mtu = flp->config.mtu; + for(i=0;imaster[i]) + flp->master[i]->mtu = flp->config.mtu; + } + + flp->config.mtu += sizeof(struct fradhdr); + flp->configured = 1; + } + else + { + err = verify_area(VERIFY_WRITE, conf, sizeof(struct frad_conf)); + if (err) + return(err); + + sdla_cmd(dev, SDLA_READ_DLCI_CONFIGURATION, 0, 0, &data, sizeof(data), NULL, NULL); + memcpy(&flp->config, &data.config, sizeof(struct frad_conf)); + + data.config.flags &= ~SDLA_DIRECT_RECV; + data.config.mtu -= sizeof(struct fradhdr); + memcpy_tofs(conf, &data.config, sizeof(struct frad_conf)); + } + + return(0); +} + +static int sdla_xfer(struct device *dev, struct sdla_mem *info, int read) +{ + struct sdla_mem mem; + int err; + char *temp; + + err = verify_area(VERIFY_READ, info, sizeof(struct sdla_mem)); + if (err) + return(err); + + memcpy_fromfs(&mem, info, sizeof(mem)); + if (read) + { + err = verify_area(VERIFY_WRITE, mem.data, mem.len); + if (err) + return(err); + + temp = kmalloc(mem.len, GFP_KERNEL); + if (!temp) + return(-ENOMEM); + sdla_read(dev, mem.addr, temp, mem.len); + memcpy_tofs(mem.data, temp, mem.len); + kfree(temp); + } + else + { + err = verify_area(VERIFY_READ, mem.data, mem.len); + if (err) + return(err); + + temp = kmalloc(mem.len, GFP_KERNEL); + if (!temp) + return(-ENOMEM); + memcpy_fromfs(temp, mem.data, mem.len); + sdla_write(dev, mem.addr, temp, mem.len); + kfree(temp); + } + return(0); +} + +static int sdla_reconfig(struct device *dev) +{ + struct frad_local *flp; + struct conf_data data; + int i, len; + + flp = dev->priv; + + memcpy(&data, &flp->config, sizeof(struct frad_conf)); + + len = 0; + for(i=0;idlci[i]) + data.dlci[len++] = flp->dlci[i]; + len *= 2; + len += sizeof(struct frad_conf); + + sdla_cmd(dev, SDLA_DISABLE_COMMUNICATIONS, 0, 0, NULL, 0, NULL, NULL); + sdla_cmd(dev, SDLA_SET_DLCI_CONFIGURATION, 0, 0, &data, len, NULL, NULL); + sdla_cmd(dev, SDLA_ENABLE_COMMUNICATIONS, 0, 0, NULL, 0, NULL, NULL); + + return(0); +} + +static int sdla_ioctl(struct device *dev, struct ifreq *ifr, int cmd) +{ + struct frad_local *flp; + + flp = dev->priv; + + if (!flp->initialized) + return(-EPERM); + + switch (cmd) + { + case FRAD_GET_CONF: + case FRAD_SET_CONF: + return(sdla_config(dev, (struct frad_conf *)ifr->ifr_data, cmd == FRAD_GET_CONF)); + + case SDLA_IDENTIFY: + ifr->ifr_flags = flp->type; + break; + + case SDLA_CPUSPEED: + return(sdla_cpuspeed(dev, ifr)); + +/* ========================================================== +NOTE: This is rather a useless action right now, as the + driver does not support protocols other than FR right + now. However, Sangoma has modules for a number of + other protocols. +============================================================*/ + case SDLA_PROTOCOL: + if (flp->configured) + return(-EALREADY); + + switch (ifr->ifr_flags) + { + case ARPHRD_FRAD: + dev->type = ifr->ifr_flags; + dev->family = AF_UNSPEC; + break; + + default: + return(-ENOPROTOOPT); + } + break; + + case SDLA_CLEARMEM: + sdla_clear(dev); + break; + + case SDLA_WRITEMEM: + case SDLA_READMEM: + return(sdla_xfer(dev, (struct sdla_mem *)ifr->ifr_data, cmd == SDLA_READMEM)); + + case SDLA_START: + sdla_start(dev); + break; + + case SDLA_STOP: + sdla_stop(dev); + break; + + default: + return(-EOPNOTSUPP); + } + return(0); +} + +int sdla_change_mtu(struct device *dev, int new_mtu) +{ + struct frad_local *flp; + + flp = dev->priv; + + if (dev->start) + return(-EBUSY); + + /* for now, you can't change the MTU! */ + return(-EACCES); +} + +int sdla_set_config(struct device *dev, struct ifmap *map) +{ + struct frad_local *flp; + int i; + char byte; + + flp = dev->priv; + + if (flp->initialized) + return(-EINVAL); + + for(i=0;i < sizeof(valid_port) / sizeof (int) ; i++) + if (valid_port[i] == map->base_addr) + break; + + if (i == sizeof(valid_port) / sizeof(int)) + return(-EINVAL); + + dev->base_addr = map->base_addr; + request_region(dev->base_addr, SDLA_IO_EXTENTS, dev->name); + + /* test for card types, S502A, S502E, S507, S508 */ + /* these tests shut down the card completely, so clear the state */ + flp->type = SDLA_UNKNOWN; + flp->state = 0; + + for(i=1;ibase_addr + i) != 0xFF) + break; + + if (i == SDLA_IO_EXTENTS) + { + outb(SDLA_HALT, dev->base_addr + SDLA_REG_Z80_CONTROL); + if ((inb(dev->base_addr + SDLA_S502_STS) & 0x0F) == 0x08) + { + outb(SDLA_S502E_INTACK, dev->base_addr + SDLA_REG_CONTROL); + if ((inb(dev->base_addr + SDLA_S502_STS) & 0x0F) == 0x0C) + { + outb(SDLA_HALT, dev->base_addr + SDLA_REG_CONTROL); + flp->type = SDLA_S502E; + } + } + } + + if (flp->type == SDLA_UNKNOWN) + { + for(byte=inb(dev->base_addr),i=0;ibase_addr + i) != byte) + break; + + if (i == SDLA_IO_EXTENTS) + { + outb(SDLA_HALT, dev->base_addr + SDLA_REG_CONTROL); + if ((inb(dev->base_addr + SDLA_S502_STS) & 0x7E) == 0x30) + { + outb(SDLA_S507_ENABLE, dev->base_addr + SDLA_REG_CONTROL); + if ((inb(dev->base_addr + SDLA_S502_STS) & 0x7E) == 0x32) + { + outb(SDLA_HALT, dev->base_addr + SDLA_REG_CONTROL); + flp->type = SDLA_S507; + } + } + } + } + + if (flp->type == SDLA_UNKNOWN) + { + outb(SDLA_HALT, dev->base_addr + SDLA_REG_CONTROL); + if ((inb(dev->base_addr + SDLA_S508_STS) & 0x3F) == 0x00) + { + outb(SDLA_S508_INTEN, dev->base_addr + SDLA_REG_CONTROL); + if ((inb(dev->base_addr + SDLA_S508_STS) & 0x3F) == 0x10) + { + outb(SDLA_HALT, dev->base_addr + SDLA_REG_CONTROL); + flp->type = SDLA_S508; + } + } + } + + if (flp->type == SDLA_UNKNOWN) + { + outb(SDLA_S502A_HALT, dev->base_addr + SDLA_REG_CONTROL); + if (inb(dev->base_addr + SDLA_S502_STS) == 0x40) + { + outb(SDLA_S502A_START, dev->base_addr + SDLA_REG_CONTROL); + if (inb(dev->base_addr + SDLA_S502_STS) == 0x40) + { + outb(SDLA_S502A_INTEN, dev->base_addr + SDLA_REG_CONTROL); + if (inb(dev->base_addr + SDLA_S502_STS) == 0x44) + { + outb(SDLA_S502A_START, dev->base_addr + SDLA_REG_CONTROL); + flp->type = SDLA_S502A; + } + } + } + } + + if (flp->type == SDLA_UNKNOWN) + { + printk(KERN_NOTICE "%s: Unknown card type\n", dev->name); + return(-ENODEV); + } + + switch(dev->base_addr) + { + case 0x270: + case 0x280: + case 0x380: + case 0x390: + if ((flp->type != SDLA_S508) && (flp->type != SDLA_S507)) + return(-EINVAL); + } + + switch (map->irq) + { + case 2: + if (flp->type != SDLA_S502E) + return(-EINVAL); + break; + + case 10: + case 11: + case 12: + case 15: + case 4: + if ((flp->type != SDLA_S508) && (flp->type != SDLA_S507)) + return(-EINVAL); + + case 3: + case 5: + case 7: + if (flp->type == SDLA_S502A) + return(-EINVAL); + break; + + default: + return(-EINVAL); + } + dev->irq = map->irq; + + if (request_irq(dev->irq, &sdla_isr, 0, dev->name, NULL)) + return(-EADDRINUSE); + + irq2dev_map[dev->irq] = dev; + + if (flp->type == SDLA_S507) + { + switch(dev->irq) + { + case 3: + flp->state = SDLA_S507_IRQ3; + break; + case 4: + flp->state = SDLA_S507_IRQ4; + break; + case 5: + flp->state = SDLA_S507_IRQ5; + break; + case 7: + flp->state = SDLA_S507_IRQ7; + break; + case 10: + flp->state = SDLA_S507_IRQ10; + break; + case 11: + flp->state = SDLA_S507_IRQ11; + break; + case 12: + flp->state = SDLA_S507_IRQ12; + break; + case 15: + flp->state = SDLA_S507_IRQ15; + break; + } + } + + for(i=0;i < sizeof(valid_mem) / sizeof (int) ; i++) + if (valid_mem[i] == map->mem_start) + break; + + if (i == sizeof(valid_mem) / sizeof(int)) + return(-EINVAL); + + if ((flp->type == SDLA_S502A) && (((map->mem_start & 0xF000) >> 12) == 0x0E)) + return(-EINVAL); + + if ((flp->type != SDLA_S507) && ((map->mem_start >> 16) == 0x0B)) + return(-EINVAL); + + if ((flp->type == SDLA_S507) && ((map->mem_start >> 16) == 0x0D)) + return(-EINVAL); + + dev->mem_start = map->mem_start; + dev->mem_end = dev->mem_start + 0x2000; + + byte = flp->type != SDLA_S508 ? SDLA_8K_WINDOW : 0; + byte |= (map->mem_start & 0xF000) >> (12 + (flp->type == SDLA_S508 ? 1 : 0)); + switch(flp->type) + { + case SDLA_S502A: + case SDLA_S502E: + switch (map->mem_start >> 16) + { + case 0x0A: + byte |= SDLA_S502_SEG_A; + break; + case 0x0C: + byte |= SDLA_S502_SEG_C; + break; + case 0x0D: + byte |= SDLA_S502_SEG_D; + break; + case 0x0E: + byte |= SDLA_S502_SEG_E; + break; + } + break; + case SDLA_S507: + switch (map->mem_start >> 16) + { + case 0x0A: + byte |= SDLA_S507_SEG_A; + break; + case 0x0B: + byte |= SDLA_S507_SEG_B; + break; + case 0x0C: + byte |= SDLA_S507_SEG_C; + break; + case 0x0E: + byte |= SDLA_S507_SEG_E; + break; + } + break; + case SDLA_S508: + switch (map->mem_start >> 16) + { + case 0x0A: + byte |= SDLA_S508_SEG_A; + break; + case 0x0C: + byte |= SDLA_S508_SEG_C; + break; + case 0x0D: + byte |= SDLA_S508_SEG_D; + break; + case 0x0E: + byte |= SDLA_S508_SEG_E; + break; + } + break; + } + + /* set the memory bits, and enable access */ + outb(byte, dev->base_addr + SDLA_REG_PC_WINDOW); + switch(flp->type) + { + case SDLA_S502E: + flp->state = SDLA_S502E_ENABLE; + break; + case SDLA_S507: + flp->state |= SDLA_MEMEN; + break; + case SDLA_S508: + flp->state = SDLA_MEMEN; + break; + } + outb(flp->state, dev->base_addr + SDLA_REG_CONTROL); + + flp->initialized = 1; + return(0); +} + +static struct enet_statistics *sdla_stats(struct device *dev) +{ + struct frad_local *flp; + + flp = dev->priv; + + return(&flp->stats); +} + +int sdla_init(struct device *dev) +{ + struct frad_local *flp; + int i; + + /* allocate the private data structure */ + flp = kmalloc(sizeof(struct frad_local), GFP_KERNEL); + if (!flp) + return(-ENOMEM); + + memset(flp, 0, sizeof(struct frad_local)); + dev->priv = flp; + + dev->flags = 0; + dev->open = sdla_open; + dev->stop = sdla_close; + dev->do_ioctl = sdla_ioctl; + dev->set_config = sdla_set_config; + dev->get_stats = sdla_stats; + dev->hard_start_xmit = sdla_transmit; + dev->change_mtu = sdla_change_mtu; + + dev->type = 0xFFFF; + dev->family = AF_UNSPEC; + dev->pa_alen = sizeof(unsigned long); + dev->hard_header_len = 0; + dev->mtu = SDLA_MAX_MTU; + + for (i = 0; i < DEV_NUMBUFFS; i++) + skb_queue_head_init(&dev->buffs[i]); + + flp->activate = sdla_activate; + flp->deactivate = sdla_deactivate; + flp->assoc = sdla_assoc; + flp->deassoc = sdla_deassoc; + flp->dlci_conf = sdla_dlci_conf; + + init_timer(&flp->timer); + flp->timer.expires = 1; + flp->timer.data = (unsigned long) dev; + flp->timer.function = sdla_poll; + + return(0); +} + +void sdla_setup(void) +{ + printk("%s.\n", version); + register_frad(devname); +} + +#ifdef MODULE +static struct device sdla0 = {"sdla0", 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, sdla_init}; + +int init_module(void) +{ + int result; + + sdla_setup(); + if ((result = register_netdev(&sdla0)) != 0) + return result; + + return 0; +} + +void cleanup_module(void) +{ + unregister_netdev(&sdla0); + if (sdla0.priv) + kfree(sdla0.priv); + if (sdla0.irq) + free_irq(sdla0.irq, NULL); +} +#endif /* MODULE */ diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 99403e8afb47..555d6b3a7e7b 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -73,7 +73,6 @@ struct pci_dev_info dev_info[] = { DEVICE( CIRRUS, CIRRUS_5434_4, "GD 5434"), DEVICE( CIRRUS, CIRRUS_5434_8, "GD 5434"), DEVICE( CIRRUS, CIRRUS_5436, "GD 5436"), - DEVICE( CIRRUS, CIRRUS_6205, "GD 6205"), DEVICE( CIRRUS, CIRRUS_6729, "CL 6729"), DEVICE( CIRRUS, CIRRUS_7542, "CL 7542"), DEVICE( CIRRUS, CIRRUS_7543, "CL 7543"), @@ -90,9 +89,11 @@ struct pci_dev_info dev_info[] = { DEVICE( MATROX, MATROX_MGA_IMP, "MGA Impression"), DEVICE( CT, CT_65545, "65545"), DEVICE( CT, CT_65548, "65548"), + DEVICE( MIRO, MIRO_36050, "ZR36050"), DEVICE( FD, FD_36C70, "TMC-18C30"), DEVICE( SI, SI_6201, "6201"), DEVICE( SI, SI_6202, "6202"), + DEVICE( SI, SI_6205, "6205"), DEVICE( SI, SI_503, "85C503"), DEVICE( SI, SI_501, "85C501"), DEVICE( SI, SI_496, "85C496"), @@ -163,11 +164,25 @@ struct pci_dev_info dev_info[] = { DEVICE( VIA, VIA_82C561, "VT 82C561"), DEVICE( VIA, VIA_82C576, "VT 82C576 3V"), DEVICE( VIA, VIA_82C416, "VT 82C416MV"), - DEVICE( VORTEX, VORTEX_GDT, "GDT 6000b"), + DEVICE( VORTEX, VORTEX_GDT60x0, "GDT 60x0"), + DEVICE( VORTEX, VORTEX_GDT6000B,"GDT 6000b"), + DEVICE( VORTEX, VORTEX_GDT6x10, "GDT 6110/6510"), + DEVICE( VORTEX, VORTEX_GDT6x20, "GDT 6120/6520"), + DEVICE( VORTEX, VORTEX_GDT6530, "GDT 6530"), + DEVICE( VORTEX, VORTEX_GDT6550, "GDT 6550"), + DEVICE( VORTEX, VORTEX_GDT6x17, "GDT 6117/6517"), + DEVICE( VORTEX, VORTEX_GDT6x27, "GDT 6127/6527"), + DEVICE( VORTEX, VORTEX_GDT6537, "GDT 6537"), + DEVICE( VORTEX, VORTEX_GDT6557, "GDT 6557"), + DEVICE( VORTEX, VORTEX_GDT6x15, "GDT 6115/6515"), + DEVICE( VORTEX, VORTEX_GDT6x25, "GDT 6125/6525"), + DEVICE( VORTEX, VORTEX_GDT6535, "GDT 6535"), + DEVICE( VORTEX, VORTEX_GDT6555, "GDT 6555"), DEVICE( EF, EF_ATM_FPGA, "155P-MF1 (FPGA)"), DEVICE( EF, EF_ATM_ASIC, "155P-MF1 (ASIC)"), DEVICE( IMAGINGTECH, IMAGINGTECH_ICPCI, "MVC IC-PCI"), DEVICE( FORE, FORE_PCA200PC, "PCA-200PC"), + DEVICE( FORE, FORE_PCA200E, "PCA-200E"), DEVICE( PLX, PLX_9060, "PCI9060 i960 bridge"), DEVICE( ALLIANCE, ALLIANCE_PROMOTIO, "Promotion-6410"), DEVICE( ALLIANCE, ALLIANCE_PROVIDEO, "Provideo"), diff --git a/drivers/scsi/NCR5380.c b/drivers/scsi/NCR5380.c index 6d3e3ef03e81..945606028599 100644 --- a/drivers/scsi/NCR5380.c +++ b/drivers/scsi/NCR5380.c @@ -2185,7 +2185,7 @@ static int NCR5380_transfer_dma (struct Scsi_Host *instance, *data = d + c; *count = 0; - *phase = (NCR5380_read(STATUS_REG & PHASE_MASK)); + *phase = NCR5380_read(STATUS_REG) & PHASE_MASK; #if 0 NCR5380_print_phase(instance); #endif diff --git a/drivers/scsi/README.g_NCR5380 b/drivers/scsi/README.g_NCR5380 index 632093e69849..7c196409db6f 100644 --- a/drivers/scsi/README.g_NCR5380 +++ b/drivers/scsi/README.g_NCR5380 @@ -1,4 +1,4 @@ -REAME file for the Linux g_NCR5380 driver. +README file for the Linux g_NCR5380 driver. (c) 1993 Drew Eckhard NCR53c400 extensions (c) 1994,1995,1996 Kevin Lentin diff --git a/drivers/scsi/fdomain.c b/drivers/scsi/fdomain.c index 713c8d0509d1..9a83e7200206 100644 --- a/drivers/scsi/fdomain.c +++ b/drivers/scsi/fdomain.c @@ -982,6 +982,9 @@ int fdomain_16x0_detect( Scsi_Host_Template *tpnt ) get resources. */ shpnt = scsi_register( tpnt, 0 ); + shpnt->irq = interrupt_level; + shpnt->io_port = port_base; + shpnt->n_io_port = 0x10; print_banner( shpnt ); /* Log IRQ with kernel */ diff --git a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c index f1258585fd6c..ea1d67e77b2c 100644 --- a/drivers/scsi/scsi.c +++ b/drivers/scsi/scsi.c @@ -2153,7 +2153,7 @@ static int update_timeout(Scsi_Cmnd * SCset, int timeout) if(SCset){ oldto = SCset->timeout - used; - SCset->timeout = timeout + used; + SCset->timeout = timeout; } least = 0xffffffff; @@ -2161,7 +2161,8 @@ static int update_timeout(Scsi_Cmnd * SCset, int timeout) for(host = scsi_hostlist; host; host = host->next) for(SCpnt = host->host_queue; SCpnt; SCpnt = SCpnt->next) if (SCpnt->timeout > 0) { - SCpnt->timeout -= used; + if (SCpnt != SCset) + SCpnt->timeout -= used; if(SCpnt->timeout <= 0) SCpnt->timeout = -1; if(SCpnt->timeout > 0 && SCpnt->timeout < least) least = SCpnt->timeout; diff --git a/drivers/scsi/scsi.h b/drivers/scsi/scsi.h index a4e569424048..6e73b9e97338 100644 --- a/drivers/scsi/scsi.h +++ b/drivers/scsi/scsi.h @@ -514,7 +514,7 @@ static Scsi_Cmnd * end_scsi_request(Scsi_Cmnd * SCpnt, int uptodate, int sectors * turned off */ #define INIT_SCSI_REQUEST \ - if (!CURRENT) { \ + if (!CURRENT || CURRENT_PLUGGED) { \ CLEAR_INTR; \ restore_flags(flags); \ return; \ diff --git a/drivers/scsi/sd_ioctl.c b/drivers/scsi/sd_ioctl.c index 1f5155addc2e..5359c33411d0 100644 --- a/drivers/scsi/sd_ioctl.c +++ b/drivers/scsi/sd_ioctl.c @@ -19,6 +19,7 @@ #include "scsi_ioctl.h" #include "hosts.h" #include "sd.h" +#include /* must follow "hosts.h" */ int sd_ioctl(struct inode * inode, struct file * file, unsigned int cmd, unsigned long arg) { diff --git a/drivers/sound/.version b/drivers/sound/.version index 8a3d0c91117f..5caf251b060c 100644 --- a/drivers/sound/.version +++ b/drivers/sound/.version @@ -1,2 +1,2 @@ -3.5 +3.5.1 0x030500 diff --git a/drivers/sound/CHANGELOG b/drivers/sound/CHANGELOG index 421c2719c575..2574a3e7f9bd 100644 --- a/drivers/sound/CHANGELOG +++ b/drivers/sound/CHANGELOG @@ -1,5 +1,5 @@ -Changelog for version 3.5 -------------------------- +Changelog for version 3.5.1 +--------------------------- Since 3.5 - Improved handling of playback underrunt situations. diff --git a/drivers/sound/Makefile b/drivers/sound/Makefile index c9d1fec52f81..225fadc2ab1d 100644 --- a/drivers/sound/Makefile +++ b/drivers/sound/Makefile @@ -30,6 +30,7 @@ TOPDIR=/usr/src/linux endif +ifndef HOSTCC build: @echo Compiling modularized sound driver @make sound.o @@ -37,6 +38,7 @@ build: install: sound.o cp sound.o $(MODULEDIR) +endif .c.o: $(CC) $(CFLAGS) -c $< diff --git a/drivers/sound/Readme b/drivers/sound/Readme index 1c65fb427ab6..6c8c07635bb5 100644 --- a/drivers/sound/Readme +++ b/drivers/sound/Readme @@ -1,5 +1,5 @@ -Version 3.5-beta11 release notes --------------------------------- +Version 3.5.1 release notes +--------------------------- Most up to date information about this driver is available from http://personal.eunet.fi/pp/voxware. diff --git a/drivers/sound/Readme.cards b/drivers/sound/Readme.cards index 17f58e2f2635..93eaacb93743 100644 --- a/drivers/sound/Readme.cards +++ b/drivers/sound/Readme.cards @@ -601,8 +601,7 @@ the file when configuring the driver. The easiest way is to mount the DOS partition containing the file with Linux. It's possible to load your own DSP algorithms and run them with the card. -Look at the directory pss_test of snd-util-3.0.tar.gz for more info.§ -package. +Look at the directory pss_test of snd-util-3.0.tar.gz for more info. AudioTriX Pro ------------- @@ -689,9 +688,6 @@ are terrible), just modify ssinit.c to use another microcode file and try again. It's possible to use an earlier version of sndscape.co[01] but it may sound wierd. -Btw, The driver may complain something about "sscapeintr()" after -running ssinit. You should just ignore these messages. - MAD16 (Pro) and Mozart ---------------------- diff --git a/drivers/sound/ad1848.c b/drivers/sound/ad1848.c index 0939d8de3172..bb5fc70776f0 100644 --- a/drivers/sound/ad1848.c +++ b/drivers/sound/ad1848.c @@ -1152,9 +1152,9 @@ ad1848_detect (int io_base, int *ad_flags, int *osp) { unsigned char tmp; - int i; ad1848_info *devc = &dev_info[nr_ad1848_devs]; unsigned char tmp1 = 0xff, tmp2 = 0xff; + int i; DDB (printk ("ad1848_detect(%x)\n", io_base)); @@ -1201,6 +1201,11 @@ ad1848_detect (int io_base, int *ad_flags, int *osp) return 0; } + DDB (printk ("ad1848: regs: ")); + for (i = 0; i < 32; i++) + DDB (printk ("%02x ", ad_read (devc, i))); + DDB (printk ("\n")); + /* * Test if it's possible to change contents of the indirect registers. * Registers 0 and 1 are ADC volume registers. The bit 0x10 is read only @@ -1254,15 +1259,6 @@ ad1848_detect (int io_base, int *ad_flags, int *osp) * with CS4231. */ - DDB (printk ("ad1848_detect() - step F\n")); - ad_write (devc, 12, 0); /* Mode2=disabled */ - - for (i = 0; i < 16; i++) - if ((tmp1 = ad_read (devc, i)) != (tmp2 = ad_read (devc, i + 16))) - { - DDB (printk ("ad1848 detect error - step F(%d/%x/%x)\n", i, tmp1, tmp2)); - return 0; - } /* * Try to switch the chip to mode2 (CS4231) by setting the MODE2 bit (0x40). diff --git a/drivers/sound/audio.c b/drivers/sound/audio.c index 4a7a8d925100..ef6dba813d2c 100644 --- a/drivers/sound/audio.c +++ b/drivers/sound/audio.c @@ -51,7 +51,7 @@ static int audio_format[MAX_AUDIO_DEV]; static int local_conversion[MAX_AUDIO_DEV]; static int -set_format (int dev, int fmt) +set_format (int dev, long fmt) { if (fmt != AFMT_QUERY) { @@ -80,7 +80,7 @@ int audio_open (int dev, struct fileinfo *file) { int ret; - int bits; + long bits; int dev_type = dev & 0x0f; int mode = file->mode & O_ACCMODE; @@ -128,13 +128,31 @@ audio_open (int dev, struct fileinfo *file) void sync_output (int dev) { - int buf_no, buf_ptr, buf_size; + int buf_no, buf_ptr, buf_size, p, i; char *dma_buf; + struct dma_buffparms *dmap = audio_devs[dev]->dmap_out; if (DMAbuf_get_curr_buffer (dev, &buf_no, &dma_buf, &buf_ptr, &buf_size) >= 0) { DMAbuf_start_output (dev, buf_no, buf_ptr); } + +/* + * Clean all unused buffer fragments. + */ + + p = dmap->qtail; + + for (i = dmap->qlen; i < dmap->nbufs; i++) + { + memset (dmap->raw_buf + p * dmap->fragment_size, + dmap->neutral_byte, + dmap->fragment_size); + + p = (p + 1) % dmap->nbufs; + } + + dmap->flags |= DMA_CLEAN; } void diff --git a/drivers/sound/configure.c b/drivers/sound/configure.c index 170da9214a6d..41321eb0a61d 100644 --- a/drivers/sound/configure.c +++ b/drivers/sound/configure.c @@ -1,13 +1,36 @@ /* - * PnP soundcard support is not included in this version. + * PnP soundcard support is not included in this version. * - * AEDSP16 will not work without significant changes. + * AEDSP16 will not work without significant changes. */ #define DISABLED_OPTIONS (B(OPT_SPNP)|B(OPT_AEDSP16)|B(OPT_UNUSED1)|B(OPT_UNUSED2)) /* * sound/configure.c - Configuration program for the Linux Sound Driver */ -#define COPYING2 +/* + * Copyright by Hannu Savolainen 1993-1996 + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. 2. + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + #include #include @@ -56,7 +79,7 @@ #define ANY_DEVS (B(OPT_AUDIO)|B(OPT_MIDI)|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_MAD16)|B(OPT_CS4232)|B(OPT_MAUI)|B(OPT_ADLIB)) #define AUDIO_CARDS (B (OPT_PSS) | B (OPT_SB) | B (OPT_PAS) | B (OPT_GUS) | \ B (OPT_MSS) | B (OPT_GUS16) | B (OPT_GUSMAX) | B (OPT_TRIX) | \ B (OPT_SSCAPE)| B(OPT_MAD16) | B(OPT_CS4232)) @@ -221,7 +244,7 @@ char *help[] = "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" @@ -246,7 +269,7 @@ char *help[] = "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" @@ -297,21 +320,6 @@ int bin2hex (char *path, char *target, char *varname); int can_select_option (int nr) { -#if 0 - switch (nr) - { - case OPT_LAST_MUTUAL + 1: - fprintf (stderr, "\nThe following cards should work with any other cards.\n" - "CAUTION! Don't enable MPU-401 if you don't have it.\n"); - break; - - case OPT_HIGHLEVEL: - fprintf (stderr, "\nSelect one or more of the following options\n"); - break; - - - } -#endif if (hw_table[nr].conditions) if (!(hw_table[nr].conditions & selected_options)) @@ -333,12 +341,12 @@ think_positively (char *prompt, int def_answ, char *help) char answ[512]; int len; - response: - fprintf(stderr, prompt); +response: + fprintf (stderr, prompt); if (def_answ) - fprintf(stderr, " [Y/n/?] "); + fprintf (stderr, " [Y/n/?] "); else - fprintf(stderr, " [N/y/?] "); + fprintf (stderr, " [N/y/?] "); if ((len = read (0, answ, sizeof (answ))) < 1) { @@ -354,12 +362,13 @@ think_positively (char *prompt, int def_answ, char *help) */ return def_answ; - if (answ[0] == '?') { /* display help message */ - fprintf(stderr, "\n"); - fprintf(stderr, help); - fprintf(stderr, "\n"); - goto response; - } + if (answ[0] == '?') + { /* display help message */ + fprintf (stderr, "\n"); + fprintf (stderr, help); + fprintf (stderr, "\n"); + goto response; + } answ[len - 1] = 0; @@ -420,7 +429,7 @@ ask_int_choice (int mask, char *macro, for (i = 0; i < OPT_LAST; i++) if (mask == B (i)) { - unsigned int j; + unsigned int j; for (j = 0; j < strlen (choices); j++) if (choices[j] == '\'') @@ -441,7 +450,7 @@ ask_int_choice (int mask, char *macro, return; fprintf (stderr, "\n%s\n", question); - if (strcmp(choices, "")) + if (strcmp (choices, "")) fprintf (stderr, "Possible values are: %s\n", choices); if (format == FMT_INT) @@ -579,18 +588,18 @@ use_old_config (char *filename) continue; if (strcmp (tmp, "JAZZ_DMA16") == 0) /* Rename it (hack) */ - { - printf("#define SB_DMA2 %s\n", - &buf[18]); - continue; - } + { + 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; - } + { + printf ("#define SB_DMA2 %s\n", + &buf[16]); + continue; + } tmp[8] = 0; /* Truncate the string */ if (strcmp (tmp, "EXCLUDE_") == 0) @@ -678,14 +687,11 @@ use_old_config (char *filename) printf ("#define SELECTED_SOUND_OPTIONS\t0x%08x\n", selected_options); fprintf (stderr, "Old configuration copied.\n"); -#ifdef linux build_defines (); -#endif old_config_used = 1; return 1; } -#ifdef linux void build_defines (void) { @@ -703,10 +709,6 @@ build_defines (void) if (!hw_table[i].alias) if (selected_options & B (i)) fprintf (optf, "CONFIG_%s=y\n", hw_table[i].macro); -#if 0 - else - fprintf (optf, "CONFIG_%s=n\n", hw_table[i].macro); -#endif fprintf (optf, "\n"); @@ -717,22 +719,16 @@ build_defines (void) { if (selected_options & extra_options[i].mask) fprintf (optf, "CONFIG_%s=y\n", extra_options[i].name); -#if 0 - else - fprintf (optf, "CONFIG_%s=n\n", extra_options[i].name); -#endif i++; } fprintf (optf, "\n"); fclose (optf); } -#endif void ask_parameters (void) { -#ifdef linux int num; build_defines (); @@ -765,7 +761,7 @@ ask_parameters (void) "0, 1 or 3"); ask_int_choice (B (OPT_SB), "SB_DMA2", - "SoundBlaster 16 bit DMA (_REQUIRED_for SB16, Jazz16, SMW)", + "SoundBlaster 16 bit DMA (_REQUIRED_for SB16, Jazz16, SMW)", FMT_INT, 5, "5, 6 or 7"); @@ -797,21 +793,21 @@ ask_parameters (void) 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"); + "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" + "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")) + "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"); + "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", @@ -989,10 +985,10 @@ ask_parameters (void) 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"); + "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"); @@ -1123,7 +1119,6 @@ ask_parameters (void) FMT_INT, 9, "5, 7, 9 or 10"); -#endif ask_int_choice (B (OPT_AUDIO), "DSP_BUFFSIZE", "Audio DMA buffer size", FMT_INT, @@ -1152,9 +1147,7 @@ dump_script (void) selected_options = 0; ask_parameters (); -#if 1 printf ("#\n$MAKE -C drivers/sound kernelconfig || exit 1\n"); -#endif } void @@ -1258,11 +1251,12 @@ main (int argc, char *argv[]) if (access (oldconf, R_OK) == 0) { - char str[255]; - sprintf(str, "Old configuration exists in `%s'. Use it", oldconf); + 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")) + "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); } @@ -1308,28 +1302,28 @@ main (int argc, char *argv[]) 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")) + "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")) + "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")) + "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")) + "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]; @@ -1343,8 +1337,8 @@ main (int argc, char *argv[]) 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")) + "The specified file could not be opened. Enter the correct path to the\n" + "file.\n")) goto midi0001_again; } else @@ -1360,13 +1354,13 @@ main (int argc, char *argv[]) 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")) + "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"); } @@ -1378,10 +1372,10 @@ main (int argc, char *argv[]) { if (think_positively ( -"Do you want support for the Audio Excel SoundBlaster Pro mode", -1, -"Enable this option if you want the Audio Excel sound card to operate\n" -"in SoundBlaster Pro mode.\n")) + "Do you want support for the Audio Excel SoundBlaster Pro mode", + 1, + "Enable this option if you want the Audio Excel sound card to operate\n" + "in SoundBlaster Pro mode.\n")) { printf ("#define AEDSP16_SBPRO\n"); sel1 = 1; @@ -1390,12 +1384,12 @@ main (int argc, char *argv[]) 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")) + "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; @@ -1416,8 +1410,8 @@ main (int argc, char *argv[]) { genld_again: if (think_positively ("Do you wish to include an LD file", 1, - "If you want to emulate the SoundBlaster card and you have a DSPxxx.LD\n" - "file then you must include the LD in the kernel.\n")) + "If you want to emulate the SoundBlaster card and you have a DSPxxx.LD\n" + "file then you must include the LD in the kernel.\n")) { char path[512]; @@ -1428,9 +1422,9 @@ main (int argc, char *argv[]) if (!bin2hex (path, "synth-ld.h", "pss_synth")) { - fprintf (stderr, "couldn't open `%s' as the LD file\n", path); + 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")) + "The given LD file could not opened.\n")) goto genld_again; } else @@ -1455,12 +1449,12 @@ main (int argc, char *argv[]) hex2hex_again: if (think_positively ("Do you want to include TRXPRO.HEX in your kernel", - 1, -"The MediaTriX AudioTrix Pro has an onboard 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")) + 1, + "The MediaTriX AudioTrix Pro has an onboard 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]; @@ -1479,7 +1473,7 @@ main (int argc, char *argv[]) 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"); + 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); } @@ -1516,12 +1510,13 @@ main (int argc, char *argv[]) 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 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]; diff --git a/drivers/sound/dev_table.h b/drivers/sound/dev_table.h index a27876e22c25..317d5730f31f 100644 --- a/drivers/sound/dev_table.h +++ b/drivers/sound/dev_table.h @@ -71,8 +71,8 @@ typedef struct pnp_sounddev #define MAX_SUB_BUFFERS (32*MAX_REALTIME_FACTOR) #define DMODE_NONE 0 -#define DMODE_OUTPUT 1 -#define DMODE_INPUT 2 +#define DMODE_OUTPUT PCM_ENABLE_OUTPUT +#define DMODE_INPUT PCM_ENABLE_INPUT struct dma_buffparms { int dma_mode; /* DMODE_INPUT, DMODE_OUTPUT or DMODE_NONE */ @@ -96,6 +96,8 @@ struct dma_buffparms { #define DMA_STARTED 0x00000008 #define DMA_EMPTY 0x00000010 #define DMA_ALLOC_DONE 0x00000020 +#define DMA_SYNCING 0x00000040 +#define DMA_CLEAN 0x00000080 int open_mode; diff --git a/drivers/sound/dmabuf.c b/drivers/sound/dmabuf.c index a26eb8264854..85d5179b6d54 100644 --- a/drivers/sound/dmabuf.c +++ b/drivers/sound/dmabuf.c @@ -360,6 +360,8 @@ dma_sync (int dev) save_flags (flags); cli (); + audio_devs[dev]->flags |= DMA_SYNCING; + audio_devs[dev]->dmap_out->underrun_count = 0; while (!current_got_fatal_signal () && audio_devs[dev]->dmap_out->qlen @@ -384,10 +386,12 @@ dma_sync (int dev) }; if ((out_sleep_flag[dev].mode & WK_TIMEOUT)) { + audio_devs[dev]->flags &= ~DMA_SYNCING; restore_flags (flags); return audio_devs[dev]->dmap_out->qlen; } } + audio_devs[dev]->flags &= ~DMA_SYNCING; restore_flags (flags); /* @@ -1023,6 +1027,8 @@ DMAbuf_getwrbuffer (int dev, char **buf, int *size, int dontblock) int abort, err = EIO; struct dma_buffparms *dmap = audio_devs[dev]->dmap_out; + dmap->flags &= ~DMA_CLEAN; + if (audio_devs[dev]->dmap_out->mapping_flags & DMA_MAP_MAPPED) { printk ("Sound: Can't write to mmapped device (3)\n"); @@ -1165,6 +1171,7 @@ DMAbuf_start_output (int dev, int buff_no, int l) struct dma_buffparms *dmap = audio_devs[dev]->dmap_out; dmap->cfrag = -1; + /* * Bypass buffering if using mmaped access */ @@ -1401,7 +1408,8 @@ DMAbuf_outputintr (int dev, int event_type) { dmap->underrun_count++; - if (dmap->underrun_count > 5 || dmap->flags & DMA_EMPTY) + if (!(dmap->flags & DMA_CLEAN) && + (audio_devs[dev]->flags & DMA_SYNCING || dmap->underrun_count > 5 || dmap->flags & DMA_EMPTY)) { dmap->qlen = 0; force_restart (dev, dmap); @@ -1624,6 +1632,7 @@ DMAbuf_select (int dev, struct fileinfo *file, int sel_type, select_table_handle save_flags (flags); cli (); + in_sleep_flag[dev].mode = WK_SLEEP; module_select_wait (&in_sleeper[dev], wait); restore_flags (flags); @@ -1650,6 +1659,7 @@ DMAbuf_select (int dev, struct fileinfo *file, int sel_type, select_table_handle { save_flags (flags); cli (); + in_sleep_flag[dev].mode = WK_SLEEP; module_select_wait (&in_sleeper[dev], wait); restore_flags (flags); @@ -1668,6 +1678,7 @@ DMAbuf_select (int dev, struct fileinfo *file, int sel_type, select_table_handle save_flags (flags); cli (); + out_sleep_flag[dev].mode = WK_SLEEP; module_select_wait (&out_sleeper[dev], wait); restore_flags (flags); @@ -1688,6 +1699,7 @@ DMAbuf_select (int dev, struct fileinfo *file, int sel_type, select_table_handle { save_flags (flags); cli (); + out_sleep_flag[dev].mode = WK_SLEEP; module_select_wait (&out_sleeper[dev], wait); restore_flags (flags); diff --git a/drivers/sound/gus_wave.c b/drivers/sound/gus_wave.c index 06849f1c07d8..13e479dcefbe 100644 --- a/drivers/sound/gus_wave.c +++ b/drivers/sound/gus_wave.c @@ -768,7 +768,7 @@ gus_initialize (void) irq_image = 0; tmp = gus_irq_map[gus_irq]; - if (!tmp) + if (!gus_pnp_flag && !tmp) printk ("Warning! GUS IRQ not selected\n"); irq_image |= tmp; irq_image |= 0x40; /* Combine IRQ1 (GF1) and IRQ2 (Midi) */ @@ -1658,7 +1658,7 @@ guswave_load_patch (int dev, int format, const char *addr, blk_sz = blk_end - target; } - if (gus_no_dma) + if (gus_pnp_flag || gus_no_dma) { /* * For some reason the DMA is not possible. We have to use PIO. diff --git a/drivers/sound/mad16.c b/drivers/sound/mad16.c index 4053de89916c..df977ff28aee 100644 --- a/drivers/sound/mad16.c +++ b/drivers/sound/mad16.c @@ -23,7 +23,6 @@ */ #include - /* * sound/mad16.c * @@ -32,6 +31,7 @@ * OPTi 82C928 MAD16 (replaced by C929) * OAK OTI-601D Mozart * OPTi 82C929 MAD16 Pro + * OPTi 82C930 (Not supported yet) * * These audio interface chips don't prduce sound themselves. They just * connect some other components (OPL-[234] and a WSS compatible codec) @@ -82,6 +82,7 @@ static int already_initialized = 0; #define C928 1 #define MOZART 2 #define C929 3 +#define C930 4 /* * Registers @@ -92,6 +93,7 @@ static int already_initialized = 0; * only until the next I/O read or write. */ +#define MC0_PORT 0xf8c /* Dummy port */ #define MC1_PORT 0xf8d /* SB address, CDROM interface type, joystick */ #define MC2_PORT 0xf8e /* CDROM address, IRQ, DMA, plus OPL4 bit */ #define MC3_PORT 0xf8f @@ -100,6 +102,11 @@ static int already_initialized = 0; #define MC5_PORT 0xf91 #define MC6_PORT 0xf92 #define MC7_PORT 0xf93 +#define MC8_PORT 0xf94 +#define MC9_PORT 0xf95 +#define MC10_PORT 0xf96 +#define MC11_PORT 0xf97 +#define MC12_PORT 0xf98 static int board_type = C928; @@ -128,6 +135,7 @@ mad_read (int port) case C929: outb (0xE3, PASSWD_REG); break; + } tmp = inb (port); @@ -154,6 +162,7 @@ mad_write (int port, int value) case C929: outb (0xE3, PASSWD_REG); break; + } outb ((unsigned char) (value & 0xff), port); @@ -164,6 +173,7 @@ static int detect_mad16 (void) { unsigned char tmp, tmp2; + int i; /* * Check that reading a register doesn't return bus float (0xff) @@ -176,6 +186,10 @@ detect_mad16 (void) DDB (printk ("MC1_PORT returned 0xff\n")); return 0; } + + for (i = 0xf8d; i <= 0xf98; i++) + DDB (printk ("Port %0x (init value) = %0x\n", i, mad_read (i))); + /* * Now check that the gate is closed on first I/O after writing * the password. (This is how a MAD16 compatible card works). @@ -188,7 +202,6 @@ detect_mad16 (void) } mad_write (MC1_PORT, tmp ^ 0x80); /* Togge a bit */ - if ((tmp2 = mad_read (MC1_PORT)) != (tmp ^ 0x80)) /* Compare the bit */ { mad_write (MC1_PORT, tmp); /* Restore */ @@ -201,6 +214,67 @@ detect_mad16 (void) } +static int +wss_init (struct address_info *hw_config) +{ + int ad_flags = 0; + +/* + * Verify the WSS parameters + */ + + if (check_region (hw_config->io_base, 8)) + { + printk ("MSS: I/O port conflict\n"); + return 0; + } + + if (!ad1848_detect (hw_config->io_base + 4, &ad_flags, mad16_osp)) + return 0; + /* + * Check if the IO port returns valid signature. The original MS Sound + * system returns 0x04 while some cards (AudioTriX Pro for example) + * return 0x00. + */ + + if ((inb (hw_config->io_base + 3) & 0x3f) != 0x04 && + (inb (hw_config->io_base + 3) & 0x3f) != 0x00) + { + DDB (printk ("No MSS signature detected on port 0x%x (0x%x)\n", + hw_config->io_base, inb (hw_config->io_base + 3))); + return 0; + } + + if (hw_config->irq > 11) + { + printk ("MSS: Bad IRQ %d\n", hw_config->irq); + return 0; + } + + if (hw_config->dma != 0 && hw_config->dma != 1 && hw_config->dma != 3) + { + printk ("MSS: Bad DMA %d\n", hw_config->dma); + return 0; + } + + /* + * Check that DMA0 is not in use with a 8 bit board. + */ + + if (hw_config->dma == 0 && inb (hw_config->io_base + 3) & 0x80) + { + printk ("MSS: Can't use DMA0 with a 8 bit card/slot\n"); + return 0; + } + + if (hw_config->irq > 7 && hw_config->irq != 9 && inb (hw_config->io_base + 3) & 0x80) + { + printk ("MSS: Can't use IRQ%d with a 8 bit card/slot\n", hw_config->irq); + } + + return 1; +} + int probe_mad16 (struct address_info *hw_config) { @@ -238,9 +312,13 @@ probe_mad16 (struct address_info *hw_config) DDB (printk ("Detect using password = 0xE3\n")); if (!detect_mad16 ()) - return 0; - - DDB (printk ("mad16.c: 82C929 detected\n")); + { + return 0; + } + else + { + DDB (printk ("mad16.c: 82C929 detected\n")); + } } else { @@ -259,7 +337,7 @@ probe_mad16 (struct address_info *hw_config) } for (i = 0xf8d; i <= 0xf93; i++) - DDB (printk ("port %03x = %03x\n", i, mad_read (i))); + DDB (printk ("port %03x = %02x\n", i, mad_read (i))); /* * Set the WSS address @@ -323,59 +401,9 @@ probe_mad16 (struct address_info *hw_config) } for (i = 0xf8d; i <= 0xf93; i++) - DDB (printk ("port %03x after init = %03x\n", i, mad_read (i))); - -/* - * Verify the WSS parameters - */ - - if (check_region (hw_config->io_base, 8)) - { - printk ("MSS: I/O port conflict\n"); - return 0; - } - - /* - * Check if the IO port returns valid signature. The original MS Sound - * system returns 0x04 while some cards (AudioTriX Pro for example) - * return 0x00. - */ - - if ((inb (hw_config->io_base + 3) & 0x3f) != 0x04 && - (inb (hw_config->io_base + 3) & 0x3f) != 0x00) - { - DDB (printk ("No MSS signature detected on port 0x%x (0x%x)\n", - hw_config->io_base, inb (hw_config->io_base + 3))); - return 0; - } - - if (hw_config->irq > 11) - { - printk ("MSS: Bad IRQ %d\n", hw_config->irq); - return 0; - } - - if (hw_config->dma != 0 && hw_config->dma != 1 && hw_config->dma != 3) - { - printk ("MSS: Bad DMA %d\n", hw_config->dma); - return 0; - } + DDB (printk ("port %03x after init = %02x\n", i, mad_read (i))); - /* - * Check that DMA0 is not in use with a 8 bit board. - */ - - if (hw_config->dma == 0 && inb (hw_config->io_base + 3) & 0x80) - { - printk ("MSS: Can't use DMA0 with a 8 bit card/slot\n"); - return 0; - } - - if (hw_config->irq > 7 && hw_config->irq != 9 && inb (hw_config->io_base + 3) & 0x80) - { - printk ("MSS: Can't use IRQ%d with a 8 bit card/slot\n", hw_config->irq); - return 0; - } + wss_init (hw_config); return 1; } diff --git a/drivers/sound/midibuf.c b/drivers/sound/midibuf.c index 89681a117fd2..c6f4e8b084e7 100644 --- a/drivers/sound/midibuf.c +++ b/drivers/sound/midibuf.c @@ -513,6 +513,7 @@ MIDIbuf_select (int dev, struct fileinfo *file, int sel_type, select_table_handl case SEL_IN: if (!DATA_AVAIL (midi_in_buf[dev])) { + input_sleep_flag[dev].mode = WK_SLEEP; module_select_wait (&input_sleeper[dev], wait); return 0; @@ -523,6 +524,7 @@ MIDIbuf_select (int dev, struct fileinfo *file, int sel_type, select_table_handl case SEL_OUT: if (SPACE_AVAIL (midi_out_buf[dev])) { + midi_sleep_flag[dev].mode = WK_SLEEP; module_select_wait (&midi_sleeper[dev], wait); return 0; diff --git a/drivers/sound/sb16_dsp.c b/drivers/sound/sb16_dsp.c index 0106b40e261b..09234c69c811 100644 --- a/drivers/sound/sb16_dsp.c +++ b/drivers/sound/sb16_dsp.c @@ -157,7 +157,7 @@ sb16_dsp_ioctl (int dev, unsigned int cmd, caddr_t arg, int local) { case SOUND_PCM_WRITE_RATE: if (local) - return dsp_set_speed ((int) arg); + return dsp_set_speed ((long) arg); return snd_ioctl_return ((int *) arg, dsp_set_speed (get_fs_long ((long *) arg))); case SOUND_PCM_READ_RATE: @@ -167,12 +167,12 @@ sb16_dsp_ioctl (int dev, unsigned int cmd, caddr_t arg, int local) case SNDCTL_DSP_STEREO: if (local) - return dsp_set_stereo ((int) arg); + return dsp_set_stereo ((long) arg); return snd_ioctl_return ((int *) arg, dsp_set_stereo (get_fs_long ((long *) arg))); case SOUND_PCM_WRITE_CHANNELS: if (local) - return dsp_set_stereo ((int) arg - 1) + 1; + return dsp_set_stereo ((long) arg - 1) + 1; return snd_ioctl_return ((int *) arg, dsp_set_stereo (get_fs_long ((long *) arg) - 1) + 1); case SOUND_PCM_READ_CHANNELS: @@ -182,7 +182,7 @@ sb16_dsp_ioctl (int dev, unsigned int cmd, caddr_t arg, int local) case SNDCTL_DSP_SETFMT: if (local) - return dsp_set_bits ((int) arg); + return dsp_set_bits ((long) arg); return snd_ioctl_return ((int *) arg, dsp_set_bits (get_fs_long ((long *) arg))); case SOUND_PCM_READ_BITS: diff --git a/drivers/sound/sb_dsp.c b/drivers/sound/sb_dsp.c index de8c532c3fb1..1ddc82b47df1 100644 --- a/drivers/sound/sb_dsp.c +++ b/drivers/sound/sb_dsp.c @@ -834,7 +834,7 @@ sb_dsp_open (int dev, int mode) if (sb_intr_active || (sb_midi_busy && sb_midi_mode == UART_MIDI)) { - printk ("SB: Audio device or MIDI already in use\n"); + printk ("SB: Audio device or MIDI already in use.\n"); return -EBUSY; } @@ -938,7 +938,7 @@ sb_dsp_ioctl (int dev, unsigned int cmd, caddr_t arg, int local) { case SOUND_PCM_WRITE_RATE: if (local) - return dsp_speed ((int) arg); + return dsp_speed ((long) arg); return snd_ioctl_return ((int *) arg, dsp_speed (get_fs_long ((long *) arg))); break; @@ -950,7 +950,7 @@ sb_dsp_ioctl (int dev, unsigned int cmd, caddr_t arg, int local) case SOUND_PCM_WRITE_CHANNELS: if (local) - return dsp_set_stereo ((int) arg - 1) + 1; + return dsp_set_stereo ((long) arg - 1) + 1; return snd_ioctl_return ((int *) arg, dsp_set_stereo (get_fs_long ((long *) arg) - 1) + 1); break; @@ -962,7 +962,7 @@ sb_dsp_ioctl (int dev, unsigned int cmd, caddr_t arg, int local) case SNDCTL_DSP_STEREO: if (local) - return dsp_set_stereo ((int) arg); + return dsp_set_stereo ((long) arg); return snd_ioctl_return ((int *) arg, dsp_set_stereo (get_fs_long ((long *) arg))); break; @@ -971,7 +971,7 @@ sb_dsp_ioctl (int dev, unsigned int cmd, caddr_t arg, int local) */ case SNDCTL_DSP_SETFMT: if (local) - return dsp_set_bits ((int) arg); + return dsp_set_bits ((long) arg); return snd_ioctl_return ((int *) arg, dsp_set_bits (get_fs_long ((long *) arg))); break; diff --git a/drivers/sound/sequencer.c b/drivers/sound/sequencer.c index e52627305eee..7af949de5518 100644 --- a/drivers/sound/sequencer.c +++ b/drivers/sound/sequencer.c @@ -1908,12 +1908,12 @@ sequencer_select (int dev, struct fileinfo *file, int sel_type, select_table_han cli (); if (!iqlen) { + midi_sleep_flag.mode = WK_SLEEP; module_select_wait (&midi_sleeper, wait); restore_flags (flags); return 0; } - midi_sleep_flag.mode &= ~WK_SLEEP; restore_flags (flags); return 1; break; @@ -1923,12 +1923,12 @@ sequencer_select (int dev, struct fileinfo *file, int sel_type, select_table_han cli (); if ((SEQ_MAX_QUEUE - qlen) < output_treshold) { + seq_sleep_flag.mode = WK_SLEEP; module_select_wait (&seq_sleeper, wait); restore_flags (flags); return 0; } - seq_sleep_flag.mode &= ~WK_SLEEP; restore_flags (flags); return 1; break; diff --git a/drivers/sound/sound_config.h b/drivers/sound/sound_config.h index e49f4b002bdc..18ea3258d31f 100644 --- a/drivers/sound/sound_config.h +++ b/drivers/sound/sound_config.h @@ -172,6 +172,7 @@ struct channel_info { #define WK_TIMEOUT 0x02 #define WK_SIGNAL 0x04 #define WK_SLEEP 0x08 +#define WK_SELECT 0x10 #define OPEN_READ PCM_ENABLE_INPUT #define OPEN_WRITE PCM_ENABLE_OUTPUT diff --git a/drivers/sound/sound_switch.c b/drivers/sound/sound_switch.c index 3e1a24f8a598..413724a72f43 100644 --- a/drivers/sound/sound_switch.c +++ b/drivers/sound/sound_switch.c @@ -523,12 +523,12 @@ sound_ioctl_sw (int dev, struct fileinfo *file, if (((cmd >> 8) & 0xff) == 'M' && num_mixers > 0) /* Mixer ioctl */ if ((dev & 0x0f) != SND_DEV_CTL) { +#ifdef CONFIG_AUDIO int dtype = dev & 0x0f; int mixdev; switch (dtype) { -#ifdef CONFIG_AUDIO case SND_DEV_DSP: case SND_DEV_DSP16: case SND_DEV_AUDIO: @@ -536,12 +536,9 @@ sound_ioctl_sw (int dev, struct fileinfo *file, if (mixdev < 0 || mixdev >= num_mixers) return -ENXIO; return mixer_devs[mixdev]->ioctl (mixdev, cmd, arg); - break; -#endif - - default: - return mixer_devs[0]->ioctl (0, cmd, arg); } +#endif + return mixer_devs[0]->ioctl (0, cmd, arg); } switch (dev & 0x0f) diff --git a/drivers/sound/soundcard.c b/drivers/sound/soundcard.c index 9da8c50d0455..8ab6f7c62a4c 100644 --- a/drivers/sound/soundcard.c +++ b/drivers/sound/soundcard.c @@ -389,8 +389,6 @@ char kernel_version[] = UTS_RELEASE; #endif -static int debugmem = 0; /* switched off by default */ - static int sound[20] = {0}; @@ -442,6 +440,11 @@ cleanup_module (void) { int i; + if (MOD_IN_USE) + { + return; + } + if (chrdev_registered) module_unregister_chrdev (sound_major, "sound"); @@ -461,6 +464,7 @@ cleanup_module (void) printk ("Sound: Hmm, DMA%d was left allocated - fixed\n", i); sound_free_dma (i); } + } #endif @@ -599,6 +603,8 @@ sound_stop_timer (void) fatal_error__This_version_is_not_compatible_with_this_kernel; #endif +static int debugmem = 0; /* switched off by default */ + static int dma_buffsize = DSP_BUFFSIZE; int @@ -647,7 +653,7 @@ sound_alloc_dmap (int dev, struct dma_buffparms *dmap, int chan) audio_devs[dev]->buffsize = PAGE_SIZE * (1 << sz); - if ((start_addr = (char *) __get_free_pages (GFP_ATOMIC, sz, 1)) == NULL) + if ((start_addr = (char *) __get_free_pages (GFP_ATOMIC, sz, MAX_DMA_ADDRESS)) == NULL) audio_devs[dev]->buffsize /= 2; } @@ -726,6 +732,7 @@ soud_map_buffer (int dev, struct dma_buffparms *dmap, buffmem_desc * info) printk ("Exited sound_map_buffer()\n"); return -EINVAL; } +#endif void conf_printf (char *name, struct address_info *hw_config) @@ -768,4 +775,3 @@ conf_printf2 (char *name, int base, int irq, int dma, int dma2) printk ("\n"); } -#endif diff --git a/drivers/sound/soundvers.h b/drivers/sound/soundvers.h index 67e3554faa1a..0bdf900a7cd2 100644 --- a/drivers/sound/soundvers.h +++ b/drivers/sound/soundvers.h @@ -1,2 +1,2 @@ -#define SOUND_VERSION_STRING "3.5-960313" +#define SOUND_VERSION_STRING "3.5.1-960324" #define SOUND_INTERNAL_VERSION 0x030500 diff --git a/drivers/sound/sscape.c b/drivers/sound/sscape.c index 064ee22fce7d..2635166577cb 100644 --- a/drivers/sound/sscape.c +++ b/drivers/sound/sscape.c @@ -306,7 +306,7 @@ sscapeintr (int irq, void *dev_id, struct pt_regs *dummy) unsigned char bits, tmp; static int debug = 0; - printk ("sscapeintr(0x%02x)\n", (bits = sscape_read (devc, GA_INTSTAT_REG))); + bits = sscape_read (devc, GA_INTSTAT_REG); if ((sscape_sleep_flag.mode & WK_SLEEP)) { { diff --git a/fs/binfmt_script.c b/fs/binfmt_script.c index 57ecef53c655..4e347c49f014 100644 --- a/fs/binfmt_script.c +++ b/fs/binfmt_script.c @@ -13,8 +13,8 @@ static int do_load_script(struct linux_binprm *bprm,struct pt_regs *regs) { - char *cp, *interp, *i_name, *i_arg, *page; - int retval, offset; + char *cp, *interp, *i_name, *i_arg; + int retval; if ((bprm->buf[0] != '#') || (bprm->buf[1] != '!') || (bprm->sh_bang)) return -ENOEXEC; /* @@ -60,16 +60,7 @@ static int do_load_script(struct linux_binprm *bprm,struct pt_regs *regs) * This is done in reverse order, because of how the * user environment and arguments are stored. */ - if (bprm->argc) { - offset = bprm->p % PAGE_SIZE; - page = (char*)bprm->page[bprm->p/PAGE_SIZE]; - while(bprm->p++,*(page+offset++)) - if(offset==PAGE_SIZE){ - offset=0; - page = (char*)bprm->page[bprm->p/PAGE_SIZE]; - } - bprm->argc--; - } + remove_arg_zero(bprm); bprm->p = copy_strings(1, &bprm->filename, bprm->page, bprm->p, 2); bprm->argc++; if (i_arg) { diff --git a/fs/dcache.c b/fs/dcache.c index ec1629ea5246..809c21528833 100644 --- a/fs/dcache.c +++ b/fs/dcache.c @@ -18,8 +18,6 @@ * string-hash computed over the name. */ -#include - #include #include @@ -51,9 +49,11 @@ struct dir_cache_entry { struct dir_cache_entry * next_lru, * prev_lru; }; +#define dcache_offset(x) ((unsigned long)&((struct dir_cache_entry*)0)->x) +#define dcache_datalen (dcache_offset(lru_head) - dcache_offset(dc_dev)) + #define COPYDATA(de, newde) \ -memcpy((void *) &newde->dc_dev, (void *) &de->dc_dev, \ -sizeof(kdev_t) + 3*sizeof(unsigned long) + 1 + DCACHE_NAME_LEN) +memcpy((void *) &newde->dc_dev, (void *) &de->dc_dev, dcache_datalen) static struct dir_cache_entry level1_cache[DCACHE_SIZE]; static struct dir_cache_entry level2_cache[DCACHE_SIZE]; @@ -69,22 +69,27 @@ static struct dir_cache_entry * level2_head; * The hash-queues are also doubly-linked circular lists, but the head is * itself on the doubly-linked list, not just a pointer to the first entry. */ -#define DCACHE_HASH_QUEUES 19 +#define DCACHE_HASH_QUEUES 32 #define hash_fn(dev,dir,namehash) ((HASHDEV(dev) ^ (dir) ^ (namehash)) % DCACHE_HASH_QUEUES) static struct hash_list hash_table[DCACHE_HASH_QUEUES]; static inline void remove_lru(struct dir_cache_entry * de) { - de->next_lru->prev_lru = de->prev_lru; - de->prev_lru->next_lru = de->next_lru; + struct dir_cache_entry * next = de->next_lru; + struct dir_cache_entry * prev = de->prev_lru; + + next->prev_lru = prev; + prev->next_lru = next; } static inline void add_lru(struct dir_cache_entry * de, struct dir_cache_entry *head) { + struct dir_cache_entry * prev = head->prev_lru; + de->next_lru = head; - de->prev_lru = head->prev_lru; - de->prev_lru->next_lru = de; + de->prev_lru = prev; + prev->next_lru = de; head->prev_lru = de; } @@ -104,7 +109,9 @@ static inline void update_lru(struct dir_cache_entry * de) */ static inline unsigned long namehash(const char * name, int len) { - return len * *(const unsigned char *) name; + return len + + ((const unsigned char *) name)[0]+ + ((const unsigned char *) name)[len-1]; } /* @@ -112,18 +119,22 @@ static inline unsigned long namehash(const char * name, int len) */ static inline void remove_hash(struct dir_cache_entry * de) { - if (de->h.next) { - de->h.next->h.prev = de->h.prev; - de->h.prev->h.next = de->h.next; + struct dir_cache_entry * next = de->h.next; + + if (next) { + struct dir_cache_entry * prev = de->h.prev; + next->h.prev = prev; + prev->h.next = next; de->h.next = NULL; } } static inline void add_hash(struct dir_cache_entry * de, struct hash_list * hash) { - de->h.next = hash->next; + struct dir_cache_entry * next = hash->next; + de->h.next = next; de->h.prev = (struct dir_cache_entry *) hash; - hash->next->h.prev = de; + next->h.prev = de; hash->next = de; } diff --git a/fs/isofs/inode.c b/fs/isofs/inode.c index 7288e316dd4f..bb4d32eb5831 100644 --- a/fs/isofs/inode.c +++ b/fs/isofs/inode.c @@ -137,7 +137,9 @@ static int parse_options(char *options, struct iso9660_options * popt) if (*vpnt) return 0; switch(*this_char) { case 'b': - if (ivalue != 1024 && ivalue != 2048) return 0; + if ( ivalue != 512 + && ivalue != 1024 + && ivalue != 2048) return 0; popt->blocksize = ivalue; break; case 'u': @@ -200,6 +202,7 @@ struct super_block *isofs_read_super(struct super_block *s,void *data, int high_sierra; kdev_t dev = s->s_dev; unsigned int vol_desc_start; + int orig_zonesize; struct iso_volume_descriptor *vdp; struct hs_volume_descriptor *hdp; @@ -324,6 +327,7 @@ struct super_block *isofs_read_super(struct super_block *s,void *data, /* RDE: convert log zone size to bit shift */ + orig_zonesize = s -> u.isofs_sb.s_log_zone_size; switch (s -> u.isofs_sb.s_log_zone_size) { case 512: s -> u.isofs_sb.s_log_zone_size = 9; break; case 1024: s -> u.isofs_sb.s_log_zone_size = 10; break; @@ -336,7 +340,8 @@ struct super_block *isofs_read_super(struct super_block *s,void *data, /* RDE: data zone now byte offset! */ - s->u.isofs_sb.s_firstdatazone = (isonum_733( rootp->extent) + s->u.isofs_sb.s_firstdatazone = ((isonum_733 (rootp->extent) + + isonum_711 (rootp->ext_attr_length)) << s -> u.isofs_sb.s_log_zone_size); s->s_magic = ISOFS_SUPER_MAGIC; @@ -354,11 +359,32 @@ struct super_block *isofs_read_super(struct super_block *s,void *data, 1UL << s->u.isofs_sb.s_log_zone_size); printk(KERN_DEBUG "First datazone:%ld Root inode number %d\n", s->u.isofs_sb.s_firstdatazone >> s -> u.isofs_sb.s_log_zone_size, - isonum_733 (rootp->extent) << s -> u.isofs_sb.s_log_zone_size); + (isonum_733(rootp->extent) + isonum_711(rootp->ext_attr_length)) + << s -> u.isofs_sb.s_log_zone_size); if(high_sierra) printk(KERN_DEBUG "Disc in High Sierra format.\n"); unlock_super(s); /* set up enough so that it can read an inode */ + /* + * Force the blocksize to 512 for 512 byte sectors. The file + * read primitives really get it wrong in a bad way if we don't + * do this. + */ + if( orig_zonesize < opt.blocksize ) + { + opt.blocksize = orig_zonesize; + blocksize_bits = 0; + { + int i = opt.blocksize; + while (i != 1){ + blocksize_bits++; + i >>=1; + } + } + set_blocksize(dev, opt.blocksize); + printk(KERN_DEBUG "Forcing new log zone size:%d\n", opt.blocksize); + } + s->s_dev = dev; s->s_op = &isofs_sops; s->u.isofs_sb.s_mapping = opt.map; @@ -376,7 +402,9 @@ struct super_block *isofs_read_super(struct super_block *s,void *data, s->u.isofs_sb.s_mode = opt.mode & 0777; s->s_blocksize = opt.blocksize; s->s_blocksize_bits = blocksize_bits; - s->s_mounted = iget(s, isonum_733 (rootp->extent) << s -> u.isofs_sb.s_log_zone_size); + s->s_mounted = iget(s, (isonum_733(rootp->extent) + + isonum_711(rootp->ext_attr_length)) + << s -> u.isofs_sb.s_log_zone_size); unlock_super(s); if (!(s->s_mounted)) { diff --git a/fs/ncpfs/ioctl.c b/fs/ncpfs/ioctl.c index eb1c4b394fd3..4350fdd6561a 100644 --- a/fs/ncpfs/ioctl.c +++ b/fs/ncpfs/ioctl.c @@ -23,6 +23,26 @@ ncp_ioctl (struct inode * inode, struct file * filp, struct ncp_fs_info info; struct ncp_server *server = NCP_SERVER(inode); + /* + * Binary compatible with 1.3.XX releases. + * Take this out in 2.1.0 development series. + * 12 Mar 1996 + */ + switch(cmd) { + case _IOR('n', 1, unsigned char *): + cmd = NCP_IOC_NCPREQUEST; + break; + case _IOR('u', 1, uid_t): + cmd = NCP_IOC_GETMOUNTUID; + break; + case _IO('l', 1): + cmd = NCP_IOC_CONN_LOGGED_IN; + break; + case _IOWR('i', 1, unsigned char *): + cmd = NCP_IOC_GET_FS_INFO; + break; + } + switch(cmd) { case NCP_IOC_NCPREQUEST: @@ -106,10 +126,12 @@ ncp_ioctl (struct inode * inode, struct file * filp, return -EINVAL; } - info.addr = server->m.serv_addr; - info.mounted_uid = server->m.mounted_uid; - info.connection = server->connection; - info.buffer_size = server->buffer_size; + info.addr = server->m.serv_addr; + info.mounted_uid = server->m.mounted_uid; + info.connection = server->connection; + info.buffer_size = server->buffer_size; + info.volume_number = NCP_ISTRUCT(inode)->volNumber; + info.directory_id = NCP_ISTRUCT(inode)->DosDirNum; memcpy_tofs((struct ncp_fs_info *)arg, &info, sizeof(info)); return 0; diff --git a/fs/ncpfs/ncplib_kernel.c b/fs/ncpfs/ncplib_kernel.c index 5dcf153c1e0a..b4a090c076f0 100644 --- a/fs/ncpfs/ncplib_kernel.c +++ b/fs/ncpfs/ncplib_kernel.c @@ -217,14 +217,9 @@ ncp_close_file(struct ncp_server *server, const char *file_id) ncp_add_byte(server, 0); ncp_add_mem(server, file_id, 6); - if ((result = ncp_request(server, 66)) != 0) - { - ncp_unlock_server(server); - return result; - } - + result = ncp_request(server, 66); ncp_unlock_server(server); - return 0; + return result; } static void @@ -366,14 +361,9 @@ ncp_modify_file_or_subdir_dos_info(struct ncp_server *server, ncp_add_handle_path(server, file->volNumber, file->DosDirNum, 1, NULL); - if ((result = ncp_request(server, 87)) != 0) - { - ncp_unlock_server(server); - return result; - } - + result = ncp_request(server, 87); ncp_unlock_server(server); - return 0; + return result; } int @@ -390,14 +380,9 @@ ncp_del_file_or_subdir(struct ncp_server *server, ncp_add_handle_path(server, dir->volNumber, dir->DosDirNum, 1, name); - if ((result = ncp_request(server, 87)) != 0) - { - ncp_unlock_server(server); - return result; - } - + result = ncp_request(server, 87); ncp_unlock_server(server); - return 0; + return result; } static inline void diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c index f00da29861fb..9996f1a9af74 100644 --- a/fs/nfs/inode.c +++ b/fs/nfs/inode.c @@ -80,7 +80,7 @@ void nfs_put_super(struct super_block *sb) * The way this works is that the mount process passes a structure * in the data argument which contains an open socket to the NFS * server and the root file handle obtained from the server's mount - * daemon. We stash theses away in the private superblock fields. + * daemon. We stash these away in the private superblock fields. * Later we can add other mount parameters like caching values. */ @@ -169,7 +169,7 @@ struct super_block *nfs_read_super(struct super_block *sb, void *raw_data, sock->ops->getname(sock, &(server->toaddr), &dummylen, 1) ; } } else { - /* printk("NFS: coppying passed addr to server->toaddr\n") ;*/ + /* printk("NFS: copying passed addr to server->toaddr\n") ;*/ memcpy((char *)&(server->toaddr),(char *)(&data->addr),sizeof(server->toaddr)); } /* End of JSP NFS patch */ diff --git a/fs/super.c b/fs/super.c index d1b6d56a8f94..b5882d64bc26 100644 --- a/fs/super.c +++ b/fs/super.c @@ -612,6 +612,9 @@ int do_mount(kdev_t dev, const char * dev_name, const char * dir_name, const cha struct vfsmount *vfsmnt; int error; + if (!(flags & MS_RDONLY) && dev && is_read_only(dev)) + return -EACCES; + /*flags |= MS_RDONLY;*/ error = namei(dir_name, &dir_i); if (error) return error; @@ -656,6 +659,7 @@ int do_mount(kdev_t dev, const char * dev_name, const char * dir_name, const cha static int do_remount_sb(struct super_block *sb, int flags, char *data) { int retval; + struct vfsmount *vfsmnt; if (!(flags & MS_RDONLY) && sb->s_dev && is_read_only(sb->s_dev)) return -EACCES; @@ -671,6 +675,9 @@ static int do_remount_sb(struct super_block *sb, int flags, char *data) } sb->s_flags = (sb->s_flags & ~MS_RMT_MASK) | (flags & MS_RMT_MASK); + vfsmnt = lookup_vfsmnt(sb->s_dev); + if (vfsmnt) + vfsmnt->mnt_flags = sb->s_flags; return 0; } diff --git a/fs/umsdos/ioctl.c b/fs/umsdos/ioctl.c index 804f65e5e66e..bdf2331f744e 100644 --- a/fs/umsdos/ioctl.c +++ b/fs/umsdos/ioctl.c @@ -65,8 +65,9 @@ int UMSDOS_ioctl_dir ( in UMSDOS. EPERM is returned for other user. */ /* - Well, not all case require write access, but it simplify the code - and let's face it, there is only one client (umssync) for all this + Well, not all cases require write access, but it simplifies + the code, and let's face it, there is only one client (umssync) + for all this. */ if ((err = verify_area(VERIFY_WRITE,(void*)data,sizeof(struct umsdos_ioctl))) < 0) { ret = err; diff --git a/include/asm-alpha/apecs.h b/include/asm-alpha/apecs.h index 96215f628626..e0043b264721 100644 --- a/include/asm-alpha/apecs.h +++ b/include/asm-alpha/apecs.h @@ -334,47 +334,47 @@ extern unsigned long apecs_init (unsigned long mem_start, * Data structure for handling APECS machine checks: */ struct el_apecs_sysdata_mcheck { - u_long coma_gcr; - u_long coma_edsr; - u_long coma_ter; - u_long coma_elar; - u_long coma_ehar; - u_long coma_ldlr; - u_long coma_ldhr; - u_long coma_base0; - u_long coma_base1; - u_long coma_base2; - u_long coma_cnfg0; - u_long coma_cnfg1; - u_long coma_cnfg2; - u_long epic_dcsr; - u_long epic_pear; - u_long epic_sear; - u_long epic_tbr1; - u_long epic_tbr2; - u_long epic_pbr1; - u_long epic_pbr2; - u_long epic_pmr1; - u_long epic_pmr2; - u_long epic_harx1; - u_long epic_harx2; - u_long epic_pmlt; - u_long epic_tag0; - u_long epic_tag1; - u_long epic_tag2; - u_long epic_tag3; - u_long epic_tag4; - u_long epic_tag5; - u_long epic_tag6; - u_long epic_tag7; - u_long epic_data0; - u_long epic_data1; - u_long epic_data2; - u_long epic_data3; - u_long epic_data4; - u_long epic_data5; - u_long epic_data6; - u_long epic_data7; + unsigned long coma_gcr; + unsigned long coma_edsr; + unsigned long coma_ter; + unsigned long coma_elar; + unsigned long coma_ehar; + unsigned long coma_ldlr; + unsigned long coma_ldhr; + unsigned long coma_base0; + unsigned long coma_base1; + unsigned long coma_base2; + unsigned long coma_cnfg0; + unsigned long coma_cnfg1; + unsigned long coma_cnfg2; + unsigned long epic_dcsr; + unsigned long epic_pear; + unsigned long epic_sear; + unsigned long epic_tbr1; + unsigned long epic_tbr2; + unsigned long epic_pbr1; + unsigned long epic_pbr2; + unsigned long epic_pmr1; + unsigned long epic_pmr2; + unsigned long epic_harx1; + unsigned long epic_harx2; + unsigned long epic_pmlt; + unsigned long epic_tag0; + unsigned long epic_tag1; + unsigned long epic_tag2; + unsigned long epic_tag3; + unsigned long epic_tag4; + unsigned long epic_tag5; + unsigned long epic_tag6; + unsigned long epic_tag7; + unsigned long epic_data0; + unsigned long epic_data1; + unsigned long epic_data2; + unsigned long epic_data3; + unsigned long epic_data4; + unsigned long epic_data5; + unsigned long epic_data6; + unsigned long epic_data7; }; #define RTC_PORT(x) (0x70 + (x)) diff --git a/include/asm-alpha/atomic.h b/include/asm-alpha/atomic.h index 32b193855e6a..d816b7099846 100644 --- a/include/asm-alpha/atomic.h +++ b/include/asm-alpha/atomic.h @@ -1,9 +1,12 @@ -#ifndef __ARCH_I386_ATOMIC__ -#define __ARCH_I386_ATOMIC__ +#ifndef __ARCH_ALPHA_ATOMIC__ +#define __ARCH_ALPHA_ATOMIC__ /* * Atomic operations that C can't guarantee us. Useful for - * resource counting etc.. + * resource counting etc... + * + * But use these as seldom as possible since they are much more slower + * than regular operations. */ /* diff --git a/include/asm-alpha/ioctl.h b/include/asm-alpha/ioctl.h index 80e6a4b42214..fc63727f4178 100644 --- a/include/asm-alpha/ioctl.h +++ b/include/asm-alpha/ioctl.h @@ -37,7 +37,7 @@ #define _IOC_WRITE 4U #define _IOC(dir,type,nr,size) \ - ((__u32) \ + ((unsigned int) \ (((dir) << _IOC_DIRSHIFT) | \ ((type) << _IOC_TYPESHIFT) | \ ((nr) << _IOC_NRSHIFT) | \ @@ -63,4 +63,4 @@ #define IOCSIZE_MASK (_IOC_SIZEMASK << _IOC_SIZESHIFT) #define IOCSIZE_SHIFT (_IOC_SIZESHIFT) -#endif +#endif /* _ALPHA_IOCTL_H */ diff --git a/include/asm-alpha/ioctls.h b/include/asm-alpha/ioctls.h new file mode 100644 index 000000000000..bb4f71de877e --- /dev/null +++ b/include/asm-alpha/ioctls.h @@ -0,0 +1,102 @@ +#ifndef _ASM_ALPHA_IOCTLS_H +#define _ASM_ALPHA_IOCTLS_H + +#include + +#define FIOCLEX _IO('f', 1) +#define FIONCLEX _IO('f', 2) +#define FIOASYNC _IOW('f', 125, int) +#define FIONBIO _IOW('f', 126, int) +#define FIONREAD _IOR('f', 127, int) +#define TIOCINQ FIONREAD + +#define TIOCGETP _IOR('t', 8, struct sgttyb) +#define TIOCSETP _IOW('t', 9, struct sgttyb) +#define TIOCSETN _IOW('t', 10, struct sgttyb) /* TIOCSETP wo flush */ + +#define TIOCSETC _IOW('t', 17, struct tchars) +#define TIOCGETC _IOR('t', 18, struct tchars) +#define TCGETS _IOR('t', 19, struct termios) +#define TCSETS _IOW('t', 20, struct termios) +#define TCSETSW _IOW('t', 21, struct termios) +#define TCSETSF _IOW('t', 22, struct termios) + +#define TCGETA _IOR('t', 23, struct termio) +#define TCSETA _IOW('t', 24, struct termio) +#define TCSETAW _IOW('t', 25, struct termio) +#define TCSETAF _IOW('t', 28, struct termio) + +#define TCSBRK _IO('t', 29) +#define TCXONC _IO('t', 30) +#define TCFLSH _IO('t', 31) + +#define TIOCSWINSZ _IOW('t', 103, struct winsize) +#define TIOCGWINSZ _IOR('t', 104, struct winsize) +#define TIOCSTART _IO('t', 110) /* start output, like ^Q */ +#define TIOCSTOP _IO('t', 111) /* stop output, like ^S */ +#define TIOCOUTQ _IOR('t', 115, int) /* output queue size */ + +#define TIOCGLTC _IOR('t', 116, struct ltchars) +#define TIOCSLTC _IOW('t', 117, struct ltchars) +#define TIOCSPGRP _IOW('t', 118, int) +#define TIOCGPGRP _IOR('t', 119, int) + +#define TIOCEXCL 0x540C +#define TIOCNXCL 0x540D +#define TIOCSCTTY 0x540E + +#define TIOCSTI 0x5412 +#define TIOCMGET 0x5415 +#define TIOCMBIS 0x5416 +#define TIOCMBIC 0x5417 +#define TIOCMSET 0x5418 +# define TIOCM_LE 0x001 +# define TIOCM_DTR 0x002 +# define TIOCM_RTS 0x004 +# define TIOCM_ST 0x008 +# define TIOCM_SR 0x010 +# define TIOCM_CTS 0x020 +# define TIOCM_CAR 0x040 +# define TIOCM_RNG 0x080 +# define TIOCM_DSR 0x100 +# define TIOCM_CD TIOCM_CAR +# define TIOCM_RI TIOCM_RNG + +#define TIOCGSOFTCAR 0x5419 +#define TIOCSSOFTCAR 0x541A +#define TIOCLINUX 0x541C +#define TIOCCONS 0x541D +#define TIOCGSERIAL 0x541E +#define TIOCSSERIAL 0x541F +#define TIOCPKT 0x5420 +# define TIOCPKT_DATA 0 +# define TIOCPKT_FLUSHREAD 1 +# define TIOCPKT_FLUSHWRITE 2 +# define TIOCPKT_STOP 4 +# define TIOCPKT_START 8 +# define TIOCPKT_NOSTOP 16 +# define TIOCPKT_DOSTOP 32 + + +#define TIOCNOTTY 0x5422 +#define TIOCSETD 0x5423 +#define TIOCGETD 0x5424 +#define TCSBRKP 0x5425 /* Needed for POSIX tcsendbreak() */ +#define TIOCTTYGSTRUCT 0x5426 /* For debugging only */ + +#define TIOCSERCONFIG 0x5453 +#define TIOCSERGWILD 0x5454 +#define TIOCSERSWILD 0x5455 +#define TIOCGLCKTRMIOS 0x5456 +#define TIOCSLCKTRMIOS 0x5457 +#define TIOCSERGSTRUCT 0x5458 /* For debugging only */ +#define TIOCSERGETLSR 0x5459 /* Get line status register */ + /* ioctl (fd, TIOCSERGETLSR, &result) where result may be as below */ +# define TIOCSER_TEMT 0x01 /* Transmitter physically empty */ +#define TIOCSERGETMULTI 0x545A /* Get multiport config */ +#define TIOCSERSETMULTI 0x545B /* Set multiport config */ + +#define TIOCMIWAIT 0x545C /* wait for a change on serial input line(s) */ +#define TIOCGICOUNT 0x545D /* read serial port inline interrupt counts */ + +#endif /* _ASM_ALPHA_IOCTLS_H */ diff --git a/include/asm-alpha/param.h b/include/asm-alpha/param.h index 3498d77c135d..07382f5f1580 100644 --- a/include/asm-alpha/param.h +++ b/include/asm-alpha/param.h @@ -1,14 +1,8 @@ -#ifndef _ASMAXP_PARAM_H -#define _ASMAXP_PARAM_H - -#include +#ifndef _ASM_ALPHA_PARAM_H +#define _ASM_ALPHA_PARAM_H #ifndef HZ -# if defined(CONFIG_ALPHA_EB66) || defined(CONFIG_ALPHA_EB66P) -# define HZ 977 /* Evaluation Boards seem to be a little odd */ -# else -# define HZ 1024 /* normal value for Alpha systems */ -# endif +# define HZ 1024 #endif #define EXEC_PAGESIZE 8192 @@ -23,4 +17,4 @@ #define MAXHOSTNAMELEN 64 /* max length of hostname */ -#endif +#endif /* _ASM_ALPHA_PARAM_H */ diff --git a/include/asm-alpha/posix_types.h b/include/asm-alpha/posix_types.h new file mode 100644 index 000000000000..ee5b31d68db0 --- /dev/null +++ b/include/asm-alpha/posix_types.h @@ -0,0 +1,94 @@ +#ifndef _ALPHA_POSIX_TYPES_H +#define _ALPHA_POSIX_TYPES_H + +/* + * This file is generally used by user-level software, so you need to + * be a little careful about namespace pollution etc. Also, we cannot + * assume GCC is being used. + */ + +typedef unsigned int __dev_t; +typedef unsigned int __ino_t; +typedef unsigned int __mode_t; +typedef unsigned short __nlink_t; +typedef long __off_t; +typedef int __pid_t; +typedef unsigned int __uid_t; +typedef unsigned int __gid_t; +typedef unsigned long __size_t; +typedef long __ssize_t; +typedef long __ptrdiff_t; +typedef long __time_t; +typedef long __clock_t; +typedef int __daddr_t; +typedef char * __caddr_t; + +typedef struct { + int val[2]; +} __fsid_t; + +#ifndef __GNUC__ + +#define __FD_SET(d, set) ((set)->fds_bits[__FDELT(d)] |= __FDMASK(d)) +#define __FD_CLR(d, set) ((set)->fds_bits[__FDELT(d)] &= ~__FDMASK(d)) +#define __FD_ISSET(d, set) ((set)->fds_bits[__FDELT(d)] & __FDMASK(d)) +#define __FD_ZERO(set) \ + ((void) memset ((__ptr_t) (set), 0, sizeof (__fd_set))) + +#else /* __GNUC__ */ + +/* With GNU C, use inline functions instead so args are evaluated only once: */ + +#undef __FD_SET +static __inline__ void __FD_SET(unsigned long fd, __fd_set *fdsetp) +{ + unsigned long _tmp = fd / __NFDBITS; + unsigned long _rem = fd % __NFDBITS; + fdsetp->fds_bits[_tmp] |= (1UL<<_rem); +} + +#undef __FD_CLR +static __inline__ void __FD_CLR(unsigned long fd, __fd_set *fdsetp) +{ + unsigned long _tmp = fd / __NFDBITS; + unsigned long _rem = fd % __NFDBITS; + fdsetp->fds_bits[_tmp] &= ~(1UL<<_rem); +} + +#undef __FD_ISSET +static __inline__ int __FD_ISSET(unsigned long fd, __fd_set *p) +{ + unsigned long _tmp = fd / __NFDBITS; + unsigned long _rem = fd % __NFDBITS; + return (p->fds_bits[_tmp] & (1UL<<_rem)) != 0; +} + +/* + * This will unroll the loop for the normal constant case (8 ints, + * for a 256-bit fd_set) + */ +#undef __FD_ZERO +static __inline__ void __FD_ZERO(__fd_set *p) +{ + unsigned int *tmp = p->fds_bits; + int i; + + if (__builtin_constant_p(__FDSET_INTS)) { + switch (__FDSET_INTS) { + case 8: + tmp[0] = 0; tmp[1] = 0; tmp[2] = 0; tmp[3] = 0; + tmp[4] = 0; tmp[5] = 0; tmp[6] = 0; tmp[7] = 0; + return; + } + } + i = __FDSET_INTS; + while (i) { + i--; + *tmp = 0; + tmp++; + } +} + +#endif /* __GNUC__ */ + +#endif /* _ALPHA_POSIX_TYPES_H */ diff --git a/include/asm-alpha/socket.h b/include/asm-alpha/socket.h index 20ca49a4fee5..47bdbf7ce818 100644 --- a/include/asm-alpha/socket.h +++ b/include/asm-alpha/socket.h @@ -3,16 +3,7 @@ #include #include - -/* Socket-level I/O control calls. */ -#define FIOGETOWN _IOR('f', 123, int) -#define FIOSETOWN _IOW('f', 124, int) - -#define SIOCATMARK _IOR('s', 7, int) -#define SIOCSPGRP _IOW('s', 8, pid_t) -#define SIOCGPGRP _IOR('s', 9, pid_t) - -#define SIOCGSTAMP 0x8906 /* Get stamp - linux-specific */ +#include /* For setsockoptions(2) */ /* diff --git a/include/asm-alpha/sockios.h b/include/asm-alpha/sockios.h new file mode 100644 index 000000000000..e4961a740e5f --- /dev/null +++ b/include/asm-alpha/sockios.h @@ -0,0 +1,15 @@ +#ifndef _ASM_ALPHA_SOCKIOS_H +#define _ASM_ALPHA_SOCKIOS_H + +/* Socket-level I/O control calls. */ + +#define FIOGETOWN _IOR('f', 123, int) +#define FIOSETOWN _IOW('f', 124, int) + +#define SIOCATMARK _IOR('s', 7, int) +#define SIOCSPGRP _IOW('s', 8, pid_t) +#define SIOCGPGRP _IOR('s', 9, pid_t) + +#define SIOCGSTAMP 0x8906 /* Get stamp - linux-specific */ + +#endif /* _ASM_ALPHA_SOCKIOS_H */ diff --git a/include/asm-alpha/statfs.h b/include/asm-alpha/statfs.h index b2cd89057e1e..1f399b493d2c 100644 --- a/include/asm-alpha/statfs.h +++ b/include/asm-alpha/statfs.h @@ -1,9 +1,13 @@ #ifndef _ALPHA_STATFS_H #define _ALPHA_STATFS_H -typedef struct { - int val[2]; -} fsid_t; +#ifndef _LINUX_TYPES_DONT_EXPORT + +#include + +typedef __fsid_t fsid_t; + +#endif /* * The OSF/1 statfs structure is much larger, but this should @@ -19,7 +23,7 @@ struct statfs { int f_bavail; int f_files; int f_ffree; - fsid_t f_fsid; + __fsid_t f_fsid; /* linux-specific entries start here.. */ int f_namelen; }; diff --git a/include/asm-alpha/termbits.h b/include/asm-alpha/termbits.h new file mode 100644 index 000000000000..354a7adeada4 --- /dev/null +++ b/include/asm-alpha/termbits.h @@ -0,0 +1,176 @@ +#ifndef _ALPHA_TERMBITS_H +#define _ALPHA_TERMBITS_H + +#include + +typedef unsigned char cc_t; +typedef unsigned int speed_t; +typedef unsigned int tcflag_t; + +/* + * termios type and macro definitions. Be careful about adding stuff + * to this file since it's used in GNU libc and there are strict rules + * concerning namespace pollution. + */ + +#define NCCS 19 +struct termios { + tcflag_t c_iflag; /* input mode flags */ + tcflag_t c_oflag; /* output mode flags */ + tcflag_t c_cflag; /* control mode flags */ + tcflag_t c_lflag; /* local mode flags */ + cc_t c_cc[NCCS]; /* control characters */ + cc_t c_line; /* line discipline (== c_cc[19]) */ + speed_t c_ispeed; /* input speed */ + speed_t c_ospeed; /* output speed */ +}; + +/* c_cc characters */ +#define VEOF 0 +#define VEOL 1 +#define VEOL2 2 +#define VERASE 3 +#define VWERASE 4 +#define VKILL 5 +#define VREPRINT 6 +#define VSWTC 7 +#define VINTR 8 +#define VQUIT 9 +#define VSUSP 10 +#define VSTART 12 +#define VSTOP 13 +#define VLNEXT 14 +#define VDISCARD 15 +#define VMIN 16 +#define VTIME 17 + +/* c_iflag bits */ +#define IGNBRK 0000001 +#define BRKINT 0000002 +#define IGNPAR 0000004 +#define PARMRK 0000010 +#define INPCK 0000020 +#define ISTRIP 0000040 +#define INLCR 0000100 +#define IGNCR 0000200 +#define ICRNL 0000400 +#define IXON 0001000 +#define IXOFF 0002000 +#if !defined(KERNEL) || defined(__USE_BSD) + /* POSIX.1 doesn't want these... */ +# define IXANY 0004000 +# define IUCLC 0010000 +# define IMAXBEL 0020000 +#endif + +/* c_oflag bits */ +#define OPOST 0000001 +#define ONLCR 0000002 +#define OLCUC 0000004 + +#define OCRNL 0000010 +#define ONOCR 0000020 +#define ONLRET 0000040 + +#define OFILL 00000100 +#define OFDEL 00000200 +#define NLDLY 00001400 +#define NL0 00000000 +#define NL1 00000400 +#define NL2 00001000 +#define NL3 00001400 +#define TABDLY 00006000 +#define TAB0 00000000 +#define TAB1 00002000 +#define TAB2 00004000 +#define TAB3 00006000 +#define CRDLY 00030000 +#define CR0 00000000 +#define CR1 00010000 +#define CR2 00020000 +#define CR3 00030000 +#define FFDLY 00040000 +#define FF0 00000000 +#define FF1 00040000 +#define BSDLY 00100000 +#define BS0 00000000 +#define BS1 00100000 +#define VTDLY 00200000 +#define VT0 00000000 +#define VT1 00200000 +#define XTABS 01000000 /* Hmm.. Linux/i386 considers this part of TABDLY.. */ + +/* c_cflag bit meaning */ +#define CBAUD 0000017 +#define B0 0000000 /* hang up */ +#define B50 0000001 +#define B75 0000002 +#define B110 0000003 +#define B134 0000004 +#define B150 0000005 +#define B200 0000006 +#define B300 0000007 +#define B600 0000010 +#define B1200 0000011 +#define B1800 0000012 +#define B2400 0000013 +#define B4800 0000014 +#define B9600 0000015 +#define B19200 0000016 +#define B38400 0000017 +#define EXTA B19200 +#define EXTB B38400 +#define CBAUDEX 0000020 +#define B57600 00020 +#define B115200 00021 +#define B230400 00022 + +#define CSIZE 00001400 +#define CS5 00000000 +#define CS6 00000400 +#define CS7 00001000 +#define CS8 00001400 + +#define CSTOPB 00002000 +#define CREAD 00004000 +#define PARENB 00010000 +#define PARODD 00020000 +#define HUPCL 00040000 + +#define CLOCAL 00100000 +#define CRTSCTS 020000000000 /* flow control */ + +/* c_lflag bits */ +#define ISIG 0x00000080 +#define ICANON 0x00000100 +#define XCASE 0x00004000 +#define ECHO 0x00000008 +#define ECHOE 0x00000002 +#define ECHOK 0x00000004 +#define ECHONL 0x00000010 +#define NOFLSH 0x80000000 +#define TOSTOP 0x00400000 +#define ECHOCTL 0x00000040 +#define ECHOPRT 0x00000020 +#define ECHOKE 0x00000001 +#define FLUSHO 0x00800000 +#define PENDIN 0x20000000 +#define IEXTEN 0x00000400 + +/* Values for the ACTION argument to `tcflow'. */ +#define TCOOFF 0 +#define TCOON 1 +#define TCIOFF 2 +#define TCION 3 + +/* Values for the QUEUE_SELECTOR argument to `tcflush'. */ +#define TCIFLUSH 0 +#define TCOFLUSH 1 +#define TCIOFLUSH 2 + +/* Values for the OPTIONAL_ACTIONS argument to `tcsetattr'. */ +#define TCSANOW 0 +#define TCSADRAIN 1 +#define TCSAFLUSH 2 + +#endif /* _ALPHA_TERMBITS_H */ diff --git a/include/asm-alpha/termios.h b/include/asm-alpha/termios.h index 9074112da11e..37a3333bd0ea 100644 --- a/include/asm-alpha/termios.h +++ b/include/asm-alpha/termios.h @@ -1,9 +1,8 @@ #ifndef _ALPHA_TERMIOS_H #define _ALPHA_TERMIOS_H -#include - -#include +#include +#include struct sgttyb { char sg_ispeed; @@ -31,89 +30,6 @@ struct ltchars { char t_lnextc; }; -#define FIOCLEX _IO('f', 1) -#define FIONCLEX _IO('f', 2) -#define FIOASYNC _IOW('f', 125, int) -#define FIONBIO _IOW('f', 126, int) -#define FIONREAD _IOR('f', 127, int) -#define TIOCINQ FIONREAD - -#define TIOCGETP _IOR('t', 8, struct sgttyb) -#define TIOCSETP _IOW('t', 9, struct sgttyb) -#define TIOCSETN _IOW('t', 10, struct sgttyb) /* TIOCSETP wo flush */ - -#define TIOCSETC _IOW('t', 17, struct tchars) -#define TIOCGETC _IOR('t', 18, struct tchars) -#define TCGETS _IOR('t', 19, struct termios) -#define TCSETS _IOW('t', 20, struct termios) -#define TCSETSW _IOW('t', 21, struct termios) -#define TCSETSF _IOW('t', 22, struct termios) - -#define TCGETA _IOR('t', 23, struct termio) -#define TCSETA _IOW('t', 24, struct termio) -#define TCSETAW _IOW('t', 25, struct termio) -#define TCSETAF _IOW('t', 28, struct termio) - -#define TCSBRK _IO('t', 29) -#define TCXONC _IO('t', 30) -#define TCFLSH _IO('t', 31) - -#define TIOCSWINSZ _IOW('t', 103, struct winsize) -#define TIOCGWINSZ _IOR('t', 104, struct winsize) -#define TIOCSTART _IO('t', 110) /* start output, like ^Q */ -#define TIOCSTOP _IO('t', 111) /* stop output, like ^S */ -#define TIOCOUTQ _IOR('t', 115, int) /* output queue size */ - -#define TIOCGLTC _IOR('t', 116, struct ltchars) -#define TIOCSLTC _IOW('t', 117, struct ltchars) -#define TIOCSPGRP _IOW('t', 118, int) -#define TIOCGPGRP _IOR('t', 119, int) - -#define TIOCEXCL 0x540C -#define TIOCNXCL 0x540D -#define TIOCSCTTY 0x540E - -#define TIOCSTI 0x5412 -#define TIOCMGET 0x5415 -#define TIOCMBIS 0x5416 -#define TIOCMBIC 0x5417 -#define TIOCMSET 0x5418 -#define TIOCGSOFTCAR 0x5419 -#define TIOCSSOFTCAR 0x541A -#define TIOCLINUX 0x541C -#define TIOCCONS 0x541D -#define TIOCGSERIAL 0x541E -#define TIOCSSERIAL 0x541F -#define TIOCPKT 0x5420 - -#define TIOCNOTTY 0x5422 -#define TIOCSETD 0x5423 -#define TIOCGETD 0x5424 -#define TCSBRKP 0x5425 /* Needed for POSIX tcsendbreak() */ -#define TIOCTTYGSTRUCT 0x5426 /* For debugging only */ - -#define TIOCSERCONFIG 0x5453 -#define TIOCSERGWILD 0x5454 -#define TIOCSERSWILD 0x5455 -#define TIOCGLCKTRMIOS 0x5456 -#define TIOCSLCKTRMIOS 0x5457 -#define TIOCSERGSTRUCT 0x5458 /* For debugging only */ -#define TIOCSERGETLSR 0x5459 /* Get line status register */ -#define TIOCSERGETMULTI 0x545A /* Get multiport config */ -#define TIOCSERSETMULTI 0x545B /* Set multiport config */ - -#define TIOCMIWAIT 0x545C /* wait for a change on serial input line(s) */ -#define TIOCGICOUNT 0x545D /* read serial port inline interrupt counts */ - -/* Used for packet mode */ -#define TIOCPKT_DATA 0 -#define TIOCPKT_FLUSHREAD 1 -#define TIOCPKT_FLUSHWRITE 2 -#define TIOCPKT_STOP 4 -#define TIOCPKT_START 8 -#define TIOCPKT_NOSTOP 16 -#define TIOCPKT_DOSTOP 32 - struct winsize { unsigned short ws_row; unsigned short ws_col; @@ -131,40 +47,13 @@ struct termio { unsigned char c_cc[NCC]; /* control characters */ }; -#define NCCS 19 -struct termios { - tcflag_t c_iflag; /* input mode flags */ - tcflag_t c_oflag; /* output mode flags */ - tcflag_t c_cflag; /* control mode flags */ - tcflag_t c_lflag; /* local mode flags */ - cc_t c_cc[NCCS]; /* control characters */ - cc_t c_line; /* line discipline (== c_cc[19]) */ - int c_ispeed; /* input speed */ - int c_ospeed; /* output speed */ -}; - -/* c_cc characters */ -#define VEOF 0 -#define VEOL 1 -#define VEOL2 2 -#define VERASE 3 -#define VWERASE 4 -#define VKILL 5 -#define VREPRINT 6 -#define VSWTC 7 -#define VINTR 8 -#define VQUIT 9 -#define VSUSP 10 -#define VSTART 12 -#define VSTOP 13 -#define VLNEXT 14 -#define VDISCARD 15 -#define VMIN 16 -#define VTIME 17 - /* - * ..and the same for c_cc in the termio structure.. - * Oh, how I love being backwardly compatible. + * c_cc characters in the termio structure. Oh, how I love being + * backwardly compatible. Notice that character 4 and 5 are + * interpreted differently depending on whether ICANON is set in + * c_lflag. If it's set, they are used as _VEOF and _VEOL, otherwise + * as _VMIN and V_TIME. This is for compatibility with OSF/1 (which + * is compatible with sysV)... */ #define _VINTR 0 #define _VQUIT 1 @@ -177,6 +66,12 @@ struct termios { #define _VEOL2 6 #define _VSWTC 7 +/* line disciplines */ +#define N_TTY 0 +#define N_SLIP 1 +#define N_MOUSE 2 +#define N_PPP 3 + #ifdef __KERNEL__ /* eof=^D eol=\0 eol2=\0 erase=del werase=^W kill=^U reprint=^R sxtc=\0 @@ -185,158 +80,6 @@ struct termios { vmin=\1 vtime=\0 */ #define INIT_C_CC "\004\000\000\177\027\025\022\000\003\034\032\000\021\023\026\025\001\000" -#endif - -/* c_iflag bits */ -#define IGNBRK 0000001 -#define BRKINT 0000002 -#define IGNPAR 0000004 -#define PARMRK 0000010 -#define INPCK 0000020 -#define ISTRIP 0000040 -#define INLCR 0000100 -#define IGNCR 0000200 -#define ICRNL 0000400 -#define IXON 0001000 -#define IXOFF 0002000 -#define IXANY 0004000 -#define IUCLC 0010000 -#define IMAXBEL 0020000 - -/* c_oflag bits */ -#define OPOST 0000001 -#define ONLCR 0000002 -#define OLCUC 0000004 - -#define OCRNL 0000010 -#define ONOCR 0000020 -#define ONLRET 0000040 - -#define OFILL 00000100 -#define OFDEL 00000200 -#define NLDLY 00001400 -#define NL0 00000000 -#define NL1 00000400 -#define NL2 00001000 -#define NL3 00001400 -#define TABDLY 00006000 -#define TAB0 00000000 -#define TAB1 00002000 -#define TAB2 00004000 -#define TAB3 00006000 -#define CRDLY 00030000 -#define CR0 00000000 -#define CR1 00010000 -#define CR2 00020000 -#define CR3 00030000 -#define FFDLY 00040000 -#define FF0 00000000 -#define FF1 00040000 -#define BSDLY 00100000 -#define BS0 00000000 -#define BS1 00100000 -#define VTDLY 00200000 -#define VT0 00000000 -#define VT1 00200000 -#define XTABS 01000000 /* Hmm.. Linux/i386 considers this part of TABDLY.. */ - -/* c_cflag bit meaning */ -#define CBAUD 0000017 -#define B0 0000000 /* hang up */ -#define B50 0000001 -#define B75 0000002 -#define B110 0000003 -#define B134 0000004 -#define B150 0000005 -#define B200 0000006 -#define B300 0000007 -#define B600 0000010 -#define B1200 0000011 -#define B1800 0000012 -#define B2400 0000013 -#define B4800 0000014 -#define B9600 0000015 -#define B19200 0000016 -#define B38400 0000017 -#define EXTA B19200 -#define EXTB B38400 -#define CBAUDEX 0000020 -#define B57600 00020 -#define B115200 00021 -#define B230400 00022 - -#define CSIZE 00001400 -#define CS5 00000000 -#define CS6 00000400 -#define CS7 00001000 -#define CS8 00001400 - -#define CSTOPB 00002000 -#define CREAD 00004000 -#define PARENB 00010000 -#define PARODD 00020000 -#define HUPCL 00040000 - -#define CLOCAL 00100000 -#define CRTSCTS 020000000000 /* flow control */ - -/* c_lflag bits */ -#define ISIG 0x00000080 -#define ICANON 0x00000100 -#define XCASE 0x00004000 -#define ECHO 0x00000008 -#define ECHOE 0x00000002 -#define ECHOK 0x00000004 -#define ECHONL 0x00000010 -#define NOFLSH 0x80000000 -#define TOSTOP 0x00400000 -#define ECHOCTL 0x00000040 -#define ECHOPRT 0x00000020 -#define ECHOKE 0x00000001 -#define FLUSHO 0x00800000 -#define PENDIN 0x20000000 -#define IEXTEN 0x00000400 - -/* modem lines */ -#define TIOCM_LE 0x001 -#define TIOCM_DTR 0x002 -#define TIOCM_RTS 0x004 -#define TIOCM_ST 0x008 -#define TIOCM_SR 0x010 -#define TIOCM_CTS 0x020 -#define TIOCM_CAR 0x040 -#define TIOCM_RNG 0x080 -#define TIOCM_DSR 0x100 -#define TIOCM_CD TIOCM_CAR -#define TIOCM_RI TIOCM_RNG - -/* ioctl (fd, TIOCSERGETLSR, &result) where result may be as below */ -#define TIOCSER_TEMT 0x01 /* Transmitter physically empty */ - - -/* tcflow() and TCXONC use these */ -#define TCOOFF 0 -#define TCOON 1 -#define TCIOFF 2 -#define TCION 3 - -/* tcflush() and TCFLSH use these */ -#define TCIFLUSH 0 -#define TCOFLUSH 1 -#define TCIOFLUSH 2 - -/* tcsetattr uses these */ -#define TCSANOW 0 -#define TCSADRAIN 1 -#define TCSAFLUSH 2 - -/* line disciplines */ -#define N_TTY 0 -#define N_SLIP 1 -#define N_MOUSE 2 -#define N_PPP 3 - -#ifdef __KERNEL__ /* * Translate a "termio" structure into a "termios". Ugh. diff --git a/include/asm-alpha/types.h b/include/asm-alpha/types.h index 4276f2f2626f..28e5d487de08 100644 --- a/include/asm-alpha/types.h +++ b/include/asm-alpha/types.h @@ -1,41 +1,15 @@ #ifndef _ALPHA_TYPES_H #define _ALPHA_TYPES_H -#ifndef _SIZE_T -#define _SIZE_T -typedef unsigned long size_t; -#endif - -#ifndef _SSIZE_T -#define _SSIZE_T -typedef long ssize_t; -#endif - -#ifndef _PTRDIFF_T -#define _PTRDIFF_T -typedef long ptrdiff_t; -#endif - -#ifndef _TIME_T -#define _TIME_T -typedef long time_t; -#endif - -#ifndef _CLOCK_T -#define _CLOCK_T -typedef long clock_t; -#endif +/* + * This file is never included by application software unless + * explicitly requested (e.g., via linux/types.h) in which case the + * application is Linux specific so (user-) name space pollution is + * not a major issue. However, for interoperability, libraries still + * need to be careful to avoid a name clashes. + */ -typedef int pid_t; -typedef unsigned int uid_t; -typedef unsigned int gid_t; -typedef unsigned int dev_t; -typedef unsigned int ino_t; -typedef unsigned int mode_t; typedef unsigned int umode_t; -typedef unsigned short nlink_t; -typedef int daddr_t; -typedef long off_t; /* * __xx is ok: it doesn't pollute the POSIX namespace. Use these in the @@ -98,55 +72,4 @@ typedef unsigned long u64; #endif #endif /* __KERNEL__ */ - -#undef __FD_SET -static __inline__ void __FD_SET(unsigned long fd, fd_set *fdsetp) -{ - unsigned long _tmp = fd / __NFDBITS; - unsigned long _rem = fd % __NFDBITS; - fdsetp->fds_bits[_tmp] |= (1UL<<_rem); -} - -#undef __FD_CLR -static __inline__ void __FD_CLR(unsigned long fd, fd_set *fdsetp) -{ - unsigned long _tmp = fd / __NFDBITS; - unsigned long _rem = fd % __NFDBITS; - fdsetp->fds_bits[_tmp] &= ~(1UL<<_rem); -} - -#undef __FD_ISSET -static __inline__ int __FD_ISSET(unsigned long fd, fd_set *p) -{ - unsigned long _tmp = fd / __NFDBITS; - unsigned long _rem = fd % __NFDBITS; - return (p->fds_bits[_tmp] & (1UL<<_rem)) != 0; -} - -/* - * This will unroll the loop for the normal constant case (8 ints, - * for a 256-bit fd_set) - */ -#undef __FD_ZERO -static __inline__ void __FD_ZERO(fd_set *p) -{ - unsigned int *tmp = p->fds_bits; - int i; - - if (__builtin_constant_p(__FDSET_INTS)) { - switch (__FDSET_INTS) { - case 8: - tmp[0] = 0; tmp[1] = 0; tmp[2] = 0; tmp[3] = 0; - tmp[4] = 0; tmp[5] = 0; tmp[6] = 0; tmp[7] = 0; - return; - } - } - i = __FDSET_INTS; - while (i) { - i--; - *tmp = 0; - tmp++; - } -} - -#endif +#endif /* _ALPHA_TYPES_H */ diff --git a/include/asm-i386/ioctls.h b/include/asm-i386/ioctls.h new file mode 100644 index 000000000000..60e0806e54e5 --- /dev/null +++ b/include/asm-i386/ioctls.h @@ -0,0 +1,74 @@ +#ifndef __ARCH_I386_IOCTLS_H__ +#define __ARCH_I386_IOCTLS_H__ + +#include + +/* 0x54 is just a magic number to make these relatively unique ('T') */ + +#define TCGETS 0x5401 +#define TCSETS 0x5402 +#define TCSETSW 0x5403 +#define TCSETSF 0x5404 +#define TCGETA 0x5405 +#define TCSETA 0x5406 +#define TCSETAW 0x5407 +#define TCSETAF 0x5408 +#define TCSBRK 0x5409 +#define TCXONC 0x540A +#define TCFLSH 0x540B +#define TIOCEXCL 0x540C +#define TIOCNXCL 0x540D +#define TIOCSCTTY 0x540E +#define TIOCGPGRP 0x540F +#define TIOCSPGRP 0x5410 +#define TIOCOUTQ 0x5411 +#define TIOCSTI 0x5412 +#define TIOCGWINSZ 0x5413 +#define TIOCSWINSZ 0x5414 +#define TIOCMGET 0x5415 +#define TIOCMBIS 0x5416 +#define TIOCMBIC 0x5417 +#define TIOCMSET 0x5418 +#define TIOCGSOFTCAR 0x5419 +#define TIOCSSOFTCAR 0x541A +#define FIONREAD 0x541B +#define TIOCINQ FIONREAD +#define TIOCLINUX 0x541C +#define TIOCCONS 0x541D +#define TIOCGSERIAL 0x541E +#define TIOCSSERIAL 0x541F +#define TIOCPKT 0x5420 +#define FIONBIO 0x5421 +#define TIOCNOTTY 0x5422 +#define TIOCSETD 0x5423 +#define TIOCGETD 0x5424 +#define TCSBRKP 0x5425 /* Needed for POSIX tcsendbreak() */ +#define TIOCTTYGSTRUCT 0x5426 /* For debugging only */ +#define FIONCLEX 0x5450 /* these numbers need to be adjusted. */ +#define FIOCLEX 0x5451 +#define FIOASYNC 0x5452 +#define TIOCSERCONFIG 0x5453 +#define TIOCSERGWILD 0x5454 +#define TIOCSERSWILD 0x5455 +#define TIOCGLCKTRMIOS 0x5456 +#define TIOCSLCKTRMIOS 0x5457 +#define TIOCSERGSTRUCT 0x5458 /* For debugging only */ +#define TIOCSERGETLSR 0x5459 /* Get line status register */ +#define TIOCSERGETMULTI 0x545A /* Get multiport config */ +#define TIOCSERSETMULTI 0x545B /* Set multiport config */ + +#define TIOCMIWAIT 0x545C /* wait for a change on serial input line(s) */ +#define TIOCGICOUNT 0x545D /* read serial port inline interrupt counts */ + +/* Used for packet mode */ +#define TIOCPKT_DATA 0 +#define TIOCPKT_FLUSHREAD 1 +#define TIOCPKT_FLUSHWRITE 2 +#define TIOCPKT_STOP 4 +#define TIOCPKT_START 8 +#define TIOCPKT_NOSTOP 16 +#define TIOCPKT_DOSTOP 32 + +#define TIOCSER_TEMT 0x01 /* Transmitter physically empty */ + +#endif diff --git a/include/asm-i386/posix_types.h b/include/asm-i386/posix_types.h new file mode 100644 index 000000000000..f2d86823f089 --- /dev/null +++ b/include/asm-i386/posix_types.h @@ -0,0 +1,51 @@ +#ifndef __ARCH_I386_POSIX_TYPES_H +#define __ARCH_I386_POSIX_TYPES_H + +/* + * This file is generally used by user-level software, so you need to + * be a little careful about namespace pollution etc. Also, we cannot + * assume GCC is being used. + */ + +typedef unsigned short __dev_t; +typedef unsigned long __ino_t; +typedef unsigned short __mode_t; +typedef unsigned short __nlink_t; +typedef long __off_t; +typedef int __pid_t; +typedef unsigned short __uid_t; +typedef unsigned short __gid_t; +typedef unsigned int __size_t; +typedef int __ssize_t; +typedef int __ptrdiff_t; +typedef long __time_t; +typedef long __clock_t; +typedef int __daddr_t; +typedef char * __caddr_t; + +#undef __FD_SET +#define __FD_SET(fd,fdsetp) \ + __asm__ __volatile__("btsl %1,%0": \ + "=m" (*(fd_set *) (fdsetp)):"r" ((int) (fd))) + +#undef __FD_CLR +#define __FD_CLR(fd,fdsetp) \ + __asm__ __volatile__("btrl %1,%0": \ + "=m" (*(fd_set *) (fdsetp)):"r" ((int) (fd))) + +#undef __FD_ISSET +#define __FD_ISSET(fd,fdsetp) (__extension__ ({ \ + unsigned char __result; \ + __asm__ __volatile__("btl %1,%2 ; setb %0" \ + :"=q" (__result) :"r" ((int) (fd)), \ + "m" (*(fd_set *) (fdsetp))); \ + __result; })) + +#undef __FD_ZERO +#define __FD_ZERO(fdsetp) \ + __asm__ __volatile__("cld ; rep ; stosl" \ + :"=m" (*(fd_set *) (fdsetp)) \ + :"a" (0), "c" (__FDSET_INTS), \ + "D" ((fd_set *) (fdsetp)) :"cx","di") + +#endif diff --git a/include/asm-i386/smp.h b/include/asm-i386/smp.h index c2e40d685517..e8986470e09d 100644 --- a/include/asm-i386/smp.h +++ b/include/asm-i386/smp.h @@ -175,13 +175,14 @@ extern struct cpuinfo_x86 cpu_data[NR_CPUS]; */ extern int smp_found_config; -extern void smp_scan_config(unsigned long, unsigned long); +extern int smp_scan_config(unsigned long, unsigned long); extern unsigned long smp_alloc_memory(unsigned long mem_base); extern unsigned char *apic_reg; extern unsigned char *kernel_stacks[NR_CPUS]; extern unsigned char boot_cpu_id; extern unsigned long cpu_present_map; extern volatile int cpu_number_map[NR_CPUS]; +extern volatile int cpu_logical_map[NR_CPUS]; extern volatile unsigned long smp_invalidate_needed; extern void smp_invalidate(void); extern volatile unsigned long kernel_flag, kernel_counter; diff --git a/include/asm-i386/socket.h b/include/asm-i386/socket.h index dc9230061f01..529a3ffefa6f 100644 --- a/include/asm-i386/socket.h +++ b/include/asm-i386/socket.h @@ -1,13 +1,7 @@ #ifndef _ASM_SOCKET_H #define _ASM_SOCKET_H -/* Socket-level I/O control calls. */ -#define FIOSETOWN 0x8901 -#define SIOCSPGRP 0x8902 -#define FIOGETOWN 0x8903 -#define SIOCGPGRP 0x8904 -#define SIOCATMARK 0x8905 -#define SIOCGSTAMP 0x8906 /* Get stamp */ +#include /* For setsockoptions(2) */ #define SOL_SOCKET 1 diff --git a/include/asm-i386/sockios.h b/include/asm-i386/sockios.h new file mode 100644 index 000000000000..6b747f8e228b --- /dev/null +++ b/include/asm-i386/sockios.h @@ -0,0 +1,12 @@ +#ifndef __ARCH_I386_SOCKIOS__ +#define __ARCH_I386_SOCKIOS__ + +/* Socket-level I/O control calls. */ +#define FIOSETOWN 0x8901 +#define SIOCSPGRP 0x8902 +#define FIOGETOWN 0x8903 +#define SIOCGPGRP 0x8904 +#define SIOCATMARK 0x8905 +#define SIOCGSTAMP 0x8906 /* Get stamp */ + +#endif diff --git a/include/asm-i386/string.h b/include/asm-i386/string.h index e79720e5dd8f..1d067077e3b6 100644 --- a/include/asm-i386/string.h +++ b/include/asm-i386/string.h @@ -402,6 +402,10 @@ extern inline void * __constant_memcpy(void * to, const void * from, size_t n) case 4: *(unsigned long *)to = *(const unsigned long *)from; return to; + case 8: + *(unsigned long *)to = *(const unsigned long *)from; + *(1+(unsigned long *)to) = *(1+(const unsigned long *)from); + return to; } #define COMMON(x) \ __asm__("cld\n\t" \ diff --git a/include/asm-i386/termbits.h b/include/asm-i386/termbits.h new file mode 100644 index 000000000000..3633f6750ae4 --- /dev/null +++ b/include/asm-i386/termbits.h @@ -0,0 +1,159 @@ +#ifndef __ARCH_I386_TERMBITS_H__ +#define __ARCH_I386_TERMBITS_H__ + +#include + +typedef unsigned char cc_t; +typedef unsigned int speed_t; +typedef unsigned int tcflag_t; + +#define NCCS 19 +struct termios { + tcflag_t c_iflag; /* input mode flags */ + tcflag_t c_oflag; /* output mode flags */ + tcflag_t c_cflag; /* control mode flags */ + tcflag_t c_lflag; /* local mode flags */ + cc_t c_line; /* line discipline */ + cc_t c_cc[NCCS]; /* control characters */ +}; + +/* c_cc characters */ +#define VINTR 0 +#define VQUIT 1 +#define VERASE 2 +#define VKILL 3 +#define VEOF 4 +#define VTIME 5 +#define VMIN 6 +#define VSWTC 7 +#define VSTART 8 +#define VSTOP 9 +#define VSUSP 10 +#define VEOL 11 +#define VREPRINT 12 +#define VDISCARD 13 +#define VWERASE 14 +#define VLNEXT 15 +#define VEOL2 16 + +/* c_iflag bits */ +#define IGNBRK 0000001 +#define BRKINT 0000002 +#define IGNPAR 0000004 +#define PARMRK 0000010 +#define INPCK 0000020 +#define ISTRIP 0000040 +#define INLCR 0000100 +#define IGNCR 0000200 +#define ICRNL 0000400 +#define IUCLC 0001000 +#define IXON 0002000 +#define IXANY 0004000 +#define IXOFF 0010000 +#define IMAXBEL 0020000 + +/* c_oflag bits */ +#define OPOST 0000001 +#define OLCUC 0000002 +#define ONLCR 0000004 +#define OCRNL 0000010 +#define ONOCR 0000020 +#define ONLRET 0000040 +#define OFILL 0000100 +#define OFDEL 0000200 +#define NLDLY 0000400 +#define NL0 0000000 +#define NL1 0000400 +#define CRDLY 0003000 +#define CR0 0000000 +#define CR1 0001000 +#define CR2 0002000 +#define CR3 0003000 +#define TABDLY 0014000 +#define TAB0 0000000 +#define TAB1 0004000 +#define TAB2 0010000 +#define TAB3 0014000 +#define XTABS 0014000 +#define BSDLY 0020000 +#define BS0 0000000 +#define BS1 0020000 +#define VTDLY 0040000 +#define VT0 0000000 +#define VT1 0040000 +#define FFDLY 0100000 +#define FF0 0000000 +#define FF1 0100000 + +/* c_cflag bit meaning */ +#define CBAUD 0010017 +#define B0 0000000 /* hang up */ +#define B50 0000001 +#define B75 0000002 +#define B110 0000003 +#define B134 0000004 +#define B150 0000005 +#define B200 0000006 +#define B300 0000007 +#define B600 0000010 +#define B1200 0000011 +#define B1800 0000012 +#define B2400 0000013 +#define B4800 0000014 +#define B9600 0000015 +#define B19200 0000016 +#define B38400 0000017 +#define EXTA B19200 +#define EXTB B38400 +#define CSIZE 0000060 +#define CS5 0000000 +#define CS6 0000020 +#define CS7 0000040 +#define CS8 0000060 +#define CSTOPB 0000100 +#define CREAD 0000200 +#define PARENB 0000400 +#define PARODD 0001000 +#define HUPCL 0002000 +#define CLOCAL 0004000 +#define CBAUDEX 0010000 +#define B57600 0010001 +#define B115200 0010002 +#define B230400 0010003 +#define CIBAUD 002003600000 /* input baud rate (not used) */ +#define CRTSCTS 020000000000 /* flow control */ + +/* c_lflag bits */ +#define ISIG 0000001 +#define ICANON 0000002 +#define XCASE 0000004 +#define ECHO 0000010 +#define ECHOE 0000020 +#define ECHOK 0000040 +#define ECHONL 0000100 +#define NOFLSH 0000200 +#define TOSTOP 0000400 +#define ECHOCTL 0001000 +#define ECHOPRT 0002000 +#define ECHOKE 0004000 +#define FLUSHO 0010000 +#define PENDIN 0040000 +#define IEXTEN 0100000 + +/* tcflow() and TCXONC use these */ +#define TCOOFF 0 +#define TCOON 1 +#define TCIOFF 2 +#define TCION 3 + +/* tcflush() and TCFLSH use these */ +#define TCIFLUSH 0 +#define TCOFLUSH 1 +#define TCIOFLUSH 2 + +/* tcsetattr uses these */ +#define TCSANOW 0 +#define TCSADRAIN 1 +#define TCSAFLUSH 2 + +#endif diff --git a/include/asm-i386/termios.h b/include/asm-i386/termios.h index de03be1f09fa..07f949172edd 100644 --- a/include/asm-i386/termios.h +++ b/include/asm-i386/termios.h @@ -1,71 +1,8 @@ #ifndef _I386_TERMIOS_H #define _I386_TERMIOS_H -/* 0x54 is just a magic number to make these relatively unique ('T') */ - -#define TCGETS 0x5401 -#define TCSETS 0x5402 -#define TCSETSW 0x5403 -#define TCSETSF 0x5404 -#define TCGETA 0x5405 -#define TCSETA 0x5406 -#define TCSETAW 0x5407 -#define TCSETAF 0x5408 -#define TCSBRK 0x5409 -#define TCXONC 0x540A -#define TCFLSH 0x540B -#define TIOCEXCL 0x540C -#define TIOCNXCL 0x540D -#define TIOCSCTTY 0x540E -#define TIOCGPGRP 0x540F -#define TIOCSPGRP 0x5410 -#define TIOCOUTQ 0x5411 -#define TIOCSTI 0x5412 -#define TIOCGWINSZ 0x5413 -#define TIOCSWINSZ 0x5414 -#define TIOCMGET 0x5415 -#define TIOCMBIS 0x5416 -#define TIOCMBIC 0x5417 -#define TIOCMSET 0x5418 -#define TIOCGSOFTCAR 0x5419 -#define TIOCSSOFTCAR 0x541A -#define FIONREAD 0x541B -#define TIOCINQ FIONREAD -#define TIOCLINUX 0x541C -#define TIOCCONS 0x541D -#define TIOCGSERIAL 0x541E -#define TIOCSSERIAL 0x541F -#define TIOCPKT 0x5420 -#define FIONBIO 0x5421 -#define TIOCNOTTY 0x5422 -#define TIOCSETD 0x5423 -#define TIOCGETD 0x5424 -#define TCSBRKP 0x5425 /* Needed for POSIX tcsendbreak() */ -#define TIOCTTYGSTRUCT 0x5426 /* For debugging only */ -#define FIONCLEX 0x5450 /* these numbers need to be adjusted. */ -#define FIOCLEX 0x5451 -#define FIOASYNC 0x5452 -#define TIOCSERCONFIG 0x5453 -#define TIOCSERGWILD 0x5454 -#define TIOCSERSWILD 0x5455 -#define TIOCGLCKTRMIOS 0x5456 -#define TIOCSLCKTRMIOS 0x5457 -#define TIOCSERGSTRUCT 0x5458 /* For debugging only */ -#define TIOCSERGETLSR 0x5459 /* Get line status register */ -#define TIOCSERGETMULTI 0x545A /* Get multiport config */ -#define TIOCSERSETMULTI 0x545B /* Set multiport config */ - -#define TIOCMIWAIT 0x545C /* wait for a change on serial input line(s) */ -#define TIOCGICOUNT 0x545D /* read serial port inline interrupt counts */ - -/* Used for packet mode */ -#define TIOCPKT_DATA 0 -#define TIOCPKT_FLUSHREAD 1 -#define TIOCPKT_FLUSHWRITE 2 -#define TIOCPKT_STOP 4 -#define TIOCPKT_START 8 -#define TIOCPKT_NOSTOP 16 -#define TIOCPKT_DOSTOP 32 +#include +#include struct winsize { unsigned short ws_row; @@ -84,35 +21,6 @@ struct termio { unsigned char c_cc[NCC]; /* control characters */ }; -#define NCCS 19 -struct termios { - tcflag_t c_iflag; /* input mode flags */ - tcflag_t c_oflag; /* output mode flags */ - tcflag_t c_cflag; /* control mode flags */ - tcflag_t c_lflag; /* local mode flags */ - cc_t c_line; /* line discipline */ - cc_t c_cc[NCCS]; /* control characters */ -}; - -/* c_cc characters */ -#define VINTR 0 -#define VQUIT 1 -#define VERASE 2 -#define VKILL 3 -#define VEOF 4 -#define VTIME 5 -#define VMIN 6 -#define VSWTC 7 -#define VSTART 8 -#define VSTOP 9 -#define VSUSP 10 -#define VEOL 11 -#define VREPRINT 12 -#define VDISCARD 13 -#define VWERASE 14 -#define VLNEXT 15 -#define VEOL2 16 - #ifdef __KERNEL__ /* intr=^C quit=^\ erase=del kill=^U eof=^D vtime=\0 vmin=\1 sxtc=\0 @@ -123,110 +31,6 @@ struct termios { #define INIT_C_CC "\003\034\177\025\004\0\1\0\021\023\032\0\022\017\027\026\0" #endif -/* c_iflag bits */ -#define IGNBRK 0000001 -#define BRKINT 0000002 -#define IGNPAR 0000004 -#define PARMRK 0000010 -#define INPCK 0000020 -#define ISTRIP 0000040 -#define INLCR 0000100 -#define IGNCR 0000200 -#define ICRNL 0000400 -#define IUCLC 0001000 -#define IXON 0002000 -#define IXANY 0004000 -#define IXOFF 0010000 -#define IMAXBEL 0020000 - -/* c_oflag bits */ -#define OPOST 0000001 -#define OLCUC 0000002 -#define ONLCR 0000004 -#define OCRNL 0000010 -#define ONOCR 0000020 -#define ONLRET 0000040 -#define OFILL 0000100 -#define OFDEL 0000200 -#define NLDLY 0000400 -#define NL0 0000000 -#define NL1 0000400 -#define CRDLY 0003000 -#define CR0 0000000 -#define CR1 0001000 -#define CR2 0002000 -#define CR3 0003000 -#define TABDLY 0014000 -#define TAB0 0000000 -#define TAB1 0004000 -#define TAB2 0010000 -#define TAB3 0014000 -#define XTABS 0014000 -#define BSDLY 0020000 -#define BS0 0000000 -#define BS1 0020000 -#define VTDLY 0040000 -#define VT0 0000000 -#define VT1 0040000 -#define FFDLY 0100000 -#define FF0 0000000 -#define FF1 0100000 - -/* c_cflag bit meaning */ -#define CBAUD 0010017 -#define B0 0000000 /* hang up */ -#define B50 0000001 -#define B75 0000002 -#define B110 0000003 -#define B134 0000004 -#define B150 0000005 -#define B200 0000006 -#define B300 0000007 -#define B600 0000010 -#define B1200 0000011 -#define B1800 0000012 -#define B2400 0000013 -#define B4800 0000014 -#define B9600 0000015 -#define B19200 0000016 -#define B38400 0000017 -#define EXTA B19200 -#define EXTB B38400 -#define CSIZE 0000060 -#define CS5 0000000 -#define CS6 0000020 -#define CS7 0000040 -#define CS8 0000060 -#define CSTOPB 0000100 -#define CREAD 0000200 -#define PARENB 0000400 -#define PARODD 0001000 -#define HUPCL 0002000 -#define CLOCAL 0004000 -#define CBAUDEX 0010000 -#define B57600 0010001 -#define B115200 0010002 -#define B230400 0010003 -#define CIBAUD 002003600000 /* input baud rate (not used) */ -#define CRTSCTS 020000000000 /* flow control */ - -/* c_lflag bits */ -#define ISIG 0000001 -#define ICANON 0000002 -#define XCASE 0000004 -#define ECHO 0000010 -#define ECHOE 0000020 -#define ECHOK 0000040 -#define ECHONL 0000100 -#define NOFLSH 0000200 -#define TOSTOP 0000400 -#define ECHOCTL 0001000 -#define ECHOPRT 0002000 -#define ECHOKE 0004000 -#define FLUSHO 0010000 -#define PENDIN 0040000 -#define IEXTEN 0100000 - /* modem lines */ #define TIOCM_LE 0x001 #define TIOCM_DTR 0x002 @@ -241,24 +45,6 @@ struct termios { #define TIOCM_RI TIOCM_RNG /* ioctl (fd, TIOCSERGETLSR, &result) where result may be as below */ -#define TIOCSER_TEMT 0x01 /* Transmitter physically empty */ - - -/* tcflow() and TCXONC use these */ -#define TCOOFF 0 -#define TCOON 1 -#define TCIOFF 2 -#define TCION 3 - -/* tcflush() and TCFLSH use these */ -#define TCIFLUSH 0 -#define TCOFLUSH 1 -#define TCIOFLUSH 2 - -/* tcsetattr uses these */ -#define TCSANOW 0 -#define TCSADRAIN 1 -#define TCSAFLUSH 2 /* line disciplines */ #define N_TTY 0 @@ -276,7 +62,7 @@ struct termios { extern inline void trans_from_termio(struct termio * termio, struct termios * termios) { -#define SET_LOW_BITS(x,y) ((x) = (0xffff0000 & (x)) | (y)) +#define SET_LOW_BITS(x,y) (*(unsigned short *)(&x) = (y)) SET_LOW_BITS(termios->c_iflag, termio->c_iflag); SET_LOW_BITS(termios->c_oflag, termio->c_oflag); SET_LOW_BITS(termios->c_cflag, termio->c_cflag); diff --git a/include/asm-i386/types.h b/include/asm-i386/types.h index ec3df86ef18d..71309ac823de 100644 --- a/include/asm-i386/types.h +++ b/include/asm-i386/types.h @@ -1,41 +1,7 @@ #ifndef _I386_TYPES_H #define _I386_TYPES_H -#ifndef _SIZE_T -#define _SIZE_T -typedef unsigned int size_t; -#endif - -#ifndef _SSIZE_T -#define _SSIZE_T -typedef int ssize_t; -#endif - -#ifndef _PTRDIFF_T -#define _PTRDIFF_T -typedef int ptrdiff_t; -#endif - -#ifndef _TIME_T -#define _TIME_T -typedef long time_t; -#endif - -#ifndef _CLOCK_T -#define _CLOCK_T -typedef long clock_t; -#endif - -typedef int pid_t; -typedef unsigned short uid_t; -typedef unsigned short gid_t; -typedef unsigned short dev_t; -typedef unsigned long ino_t; -typedef unsigned short mode_t; typedef unsigned short umode_t; -typedef unsigned short nlink_t; -typedef int daddr_t; -typedef long off_t; /* * __xx is ok: it doesn't pollute the POSIX namespace. Use these in the @@ -75,29 +41,4 @@ typedef unsigned long long u64; #endif /* __KERNEL__ */ -#undef __FD_SET -#define __FD_SET(fd,fdsetp) \ - __asm__ __volatile__("btsl %1,%0": \ - "=m" (*(fd_set *) (fdsetp)):"r" ((int) (fd))) - -#undef __FD_CLR -#define __FD_CLR(fd,fdsetp) \ - __asm__ __volatile__("btrl %1,%0": \ - "=m" (*(fd_set *) (fdsetp)):"r" ((int) (fd))) - -#undef __FD_ISSET -#define __FD_ISSET(fd,fdsetp) (__extension__ ({ \ - unsigned char __result; \ - __asm__ __volatile__("btl %1,%2 ; setb %0" \ - :"=q" (__result) :"r" ((int) (fd)), \ - "m" (*(fd_set *) (fdsetp))); \ - __result; })) - -#undef __FD_ZERO -#define __FD_ZERO(fdsetp) \ - __asm__ __volatile__("cld ; rep ; stosl" \ - :"=m" (*(fd_set *) (fdsetp)) \ - :"a" (0), "c" (__FDSET_INTS), \ - "D" ((fd_set *) (fdsetp)) :"cx","di") - #endif diff --git a/include/asm-i386/unistd.h b/include/asm-i386/unistd.h index 1837f210fa0b..3d8ca8fbd435 100644 --- a/include/asm-i386/unistd.h +++ b/include/asm-i386/unistd.h @@ -168,6 +168,7 @@ #define __NR_sched_get_priority_min 160 #define __NR_sched_rr_get_interval 161 #define __NR_nanosleep 162 +#define __NR_mremap 163 /* XXX - _foo needs to be __foo, while __NR_bar could be _NR_bar. */ #define _syscall0(type,name) \ diff --git a/include/linux/atalk.h b/include/linux/atalk.h index b5234136871e..c70d0577b698 100644 --- a/include/linux/atalk.h +++ b/include/linux/atalk.h @@ -140,5 +140,9 @@ extern struct atalk_iface *atalk_find_dev(struct device *dev); extern struct at_addr *atalk_find_dev_addr(struct device *dev); extern int aarp_send_ddp(struct device *dev,struct sk_buff *skb, struct at_addr *sa, void *hwaddr); extern void aarp_send_probe(struct device *dev, struct at_addr *addr); +#ifdef MODULE +extern void aarp_cleanup_module(void); +#endif + #endif #endif diff --git a/include/linux/binfmts.h b/include/linux/binfmts.h index 49d65750d0c1..4ab606c10cec 100644 --- a/include/linux/binfmts.h +++ b/include/linux/binfmts.h @@ -51,6 +51,7 @@ extern int init_aout_binfmt(void); extern int init_script_binfmt(void); extern int prepare_binprm(struct linux_binprm *); +extern void remove_arg_zero(struct linux_binprm *); extern int search_binary_handler(struct linux_binprm *,struct pt_regs *); extern void flush_old_exec(struct linux_binprm * bprm); extern unsigned long setup_arg_pages(unsigned long p, struct linux_binprm * bprm); diff --git a/include/linux/blk.h b/include/linux/blk.h index 04d1c88f9ad6..4685165fd721 100644 --- a/include/linux/blk.h +++ b/include/linux/blk.h @@ -319,6 +319,8 @@ static void floppy_off(unsigned int nr); #define CURRENT (blk_dev[MAJOR_NR].current_request) #endif +#define CURRENT_PLUGGED IS_PLUGGED(blk_dev+MAJOR_NR) + #define CURRENT_DEV DEVICE_NR(CURRENT->rq_dev) #ifdef DEVICE_INTR @@ -356,7 +358,7 @@ static void (DEVICE_REQUEST)(void); #endif #define INIT_REQUEST \ - if (!CURRENT) {\ + if (!CURRENT || CURRENT_PLUGGED) {\ CLEAR_INTR; \ return; \ } \ diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index 65287871b749..f261aca324ba 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h @@ -4,6 +4,7 @@ #include #include #include +#include /* * Ok, this is an expanded form so that we can use the same @@ -35,8 +36,11 @@ struct request { struct blk_dev_struct { void (*request_fn)(void); struct request * current_request; + struct tq_struct plug_tq; }; +#define IS_PLUGGED(dev) ((dev)->plug_tq.sync) + struct sec_size { unsigned block_size; unsigned block_size_bits; diff --git a/include/linux/fs.h b/include/linux/fs.h index 0fa1186fa25a..1487ae79e532 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -480,6 +480,7 @@ extern int do_truncate(struct inode *, unsigned long); extern int register_blkdev(unsigned int, const char *, struct file_operations *); extern int unregister_blkdev(unsigned int major, const char * name); extern int blkdev_open(struct inode * inode, struct file * filp); +extern void blkdev_release (struct inode * inode); extern struct file_operations def_blk_fops; extern struct inode_operations blkdev_inode_operations; diff --git a/include/linux/if_arp.h b/include/linux/if_arp.h index e107ae1d28ea..59ed69c08117 100644 --- a/include/linux/if_arp.h +++ b/include/linux/if_arp.h @@ -11,7 +11,8 @@ * Portions taken from the KA9Q/NOS (v2.00m PA0GRI) source. * Ross Biro, * Fred N. van Kempen, - * Florian La Roche. + * Florian La Roche, + * Jonathan Layes * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -31,6 +32,8 @@ #define ARPHRD_IEEE802 6 /* IEEE 802.2 Ethernet/TR/TB */ #define ARPHRD_ARCNET 7 /* ARCnet */ #define ARPHRD_APPLETLK 8 /* APPLEtalk */ +#define ARPHRD_DLCI 15 /* Frame Relay DLCI */ + /* Dummy types for non ARP hardware */ #define ARPHRD_SLIP 256 #define ARPHRD_CSLIP 257 @@ -39,9 +42,10 @@ #define ARPHRD_RSRVD 260 /* Notional KISS type */ #define ARPHRD_ADAPT 264 #define ARPHRD_PPP 512 + #define ARPHRD_TUNNEL 768 /* IPIP tunnel */ #define ARPHRD_TUNNEL6 769 /* IPIP6 tunnel */ -#define ARPHRD_FRAD 770 /* Frame Relay */ +#define ARPHRD_FRAD 770 /* Frame Relay Access Device */ #define ARPHRD_SKIP 771 /* SKIP vif */ #define ARPHRD_LOOPBACK 772 /* Loopback device */ #define ARPHRD_LOCALTLK 773 /* Localtalk device */ @@ -101,4 +105,22 @@ struct arphdr }; +/* Support for the user space arp daemon, arpd */ + +#define ARPD_UPDATE 0x01 +#define ARPD_LOOKUP 0x02 + +struct arpd_request +{ + unsigned short req; /* request type */ + __u32 ip; /* ip address of entry */ + __u32 mask; /* netmask - used for proxy */ + unsigned char ha[MAX_ADDR_LEN]; /* Hardware address */ + unsigned long last_used; /* For expiry */ + unsigned long last_updated; /* For expiry */ + unsigned int flags; /* Control status */ + struct device *dev; /* Device entry is tied to */ + int loc; /* Debugging call location */ +}; + #endif /* _LINUX_IF_ARP_H */ diff --git a/include/linux/if_ether.h b/include/linux/if_ether.h index 3b9f60e43939..5673f6e30b23 100644 --- a/include/linux/if_ether.h +++ b/include/linux/if_ether.h @@ -17,19 +17,25 @@ * as published by the Free Software Foundation; either version * 2 of the License, or (at your option) any later version. */ + #ifndef _LINUX_IF_ETHER_H #define _LINUX_IF_ETHER_H -/* IEEE 802.3 Ethernet magic constants. The frame sizes omit the preamble - and FCS/CRC (frame check sequence). */ +/* + * IEEE 802.3 Ethernet magic constants. The frame sizes omit the preamble + * and FCS/CRC (frame check sequence). + */ + #define ETH_ALEN 6 /* Octets in one ethernet addr */ #define ETH_HLEN 14 /* Total octets in header. */ #define ETH_ZLEN 60 /* Min. octets in frame sans FCS */ #define ETH_DATA_LEN 1500 /* Max. octets in payload */ #define ETH_FRAME_LEN 1514 /* Max. octets in frame sans FCS */ +/* + * These are the defined Ethernet Protocol ID's. + */ -/* These are the defined Ethernet Protocol ID's. */ #define ETH_P_LOOP 0x0060 /* Ethernet Loopback packet */ #define ETH_P_ECHO 0x0200 /* Ethernet Echo packet */ #define ETH_P_PUP 0x0400 /* Xerox PUP packet */ @@ -64,39 +70,49 @@ #define ETH_P_WAN_PPP 0x0007 /* Dummy type for WAN PPP frames*/ #define ETH_P_PPP_MP 0x0008 /* Dummy type for PPP MP frames */ #define ETH_P_LOCALTALK 0x0009 /* Localtalk pseudeo type */ +#define ETH_P_PPPTALK 0x0010 /* Dummy type for Atalk over PPP*/ -/* This is an Ethernet frame header. */ -struct ethhdr { - unsigned char h_dest[ETH_ALEN]; /* destination eth addr */ - unsigned char h_source[ETH_ALEN]; /* source ether addr */ - unsigned short h_proto; /* packet type ID field */ +/* + * This is an Ethernet frame header. + */ + +struct ethhdr +{ + unsigned char h_dest[ETH_ALEN]; /* destination eth addr */ + unsigned char h_source[ETH_ALEN]; /* source ether addr */ + unsigned short h_proto; /* packet type ID field */ }; -/* Ethernet statistics collection data. */ -struct enet_statistics{ - int rx_packets; /* total packets received */ - int tx_packets; /* total packets transmitted */ - int rx_errors; /* bad packets received */ - int tx_errors; /* packet transmit problems */ - int rx_dropped; /* no space in linux buffers */ - int tx_dropped; /* no space available in linux */ - int multicast; /* multicast packets received */ - int collisions; +/* + * Ethernet statistics collection data. + */ + +struct enet_statistics +{ + int rx_packets; /* total packets received */ + int tx_packets; /* total packets transmitted */ + int rx_errors; /* bad packets received */ + int tx_errors; /* packet transmit problems */ + int rx_dropped; /* no space in linux buffers */ + int tx_dropped; /* no space available in linux */ + int multicast; /* multicast packets received */ + int collisions; - /* detailed rx_errors: */ - int rx_length_errors; - int rx_over_errors; /* receiver ring buff overflow */ - int rx_crc_errors; /* recved pkt with crc error */ - int rx_frame_errors; /* recv'd frame alignment error */ - int rx_fifo_errors; /* recv'r fifo overrun */ - int rx_missed_errors; /* receiver missed packet */ + /* detailed rx_errors: */ + int rx_length_errors; + int rx_over_errors; /* receiver ring buff overflow */ + int rx_crc_errors; /* recved pkt with crc error */ + int rx_frame_errors; /* recv'd frame alignment error */ + int rx_fifo_errors; /* recv'r fifo overrun */ + int rx_missed_errors; /* receiver missed packet */ - /* detailed tx_errors */ - int tx_aborted_errors; - int tx_carrier_errors; - int tx_fifo_errors; - int tx_heartbeat_errors; - int tx_window_errors; + /* detailed tx_errors */ + int tx_aborted_errors; + int tx_carrier_errors; + int tx_fifo_errors; + int tx_heartbeat_errors; + int tx_window_errors; }; + #endif /* _LINUX_IF_ETHER_H */ diff --git a/include/linux/if_frad.h b/include/linux/if_frad.h new file mode 100644 index 000000000000..25e9abe107af --- /dev/null +++ b/include/linux/if_frad.h @@ -0,0 +1,168 @@ +/* + * DLCI/FRAD Definitions for Frame Relay Access Devices. DLCI devices are + * created for each DLCI associated with a FRAD. The FRAD driver + * is not truely a network device, but the lower level device + * handler. This allows other FRAD manufacturers to use the DLCI + * code, including it's RFC1490 encapsulation along side the current + * implementation for the Sangoma cards. + * + * Version: @(#)if_ifrad.h 0.10 23 Mar 96 + * + * Author: Mike McLagan + * + * 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. + */ + +#ifndef _FRAD_H_ +#define _FRAD_H_ + +/* Stuctures and constants associated with the DLCI device driver */ + +#define DLCI_DEVADD (SIOCDEVPRIVATE) +#define DLCI_DEVDEL (SIOCDEVPRIVATE + 1) + +struct dlci_add +{ + char devname[IFNAMSIZ]; + short dlci; +}; + +#define DLCI_GET_CONF (SIOCDEVPRIVATE + 2) +#define DLCI_SET_CONF (SIOCDEVPRIVATE + 3) + +/* These are related to the Sangoma FRAD */ +struct dlci_conf { + short flags; + short CIR_fwd; + short Bc_fwd; + short Be_fwd; + short CIR_bwd; + short Bc_bwd; + short Be_bwd; + +/* these are part of the status read */ + short Tc_fwd; + short Tc_bwd; + short Tf_max; + short Tb_max; +}; + +#define DLCI_GET_SLAVE (SIOCDEVPRIVATE + 4) + +/* configuration flags for DLCI */ +#define DLCI_IGNORE_CIR_OUT 0x0001 +#define DLCI_ACCOUNT_CIR_IN 0x0002 +#define DLCI_BUFFER_IF 0x0008 + +#define DLCI_VALID_FLAGS 0x000B + + +/* defines for the actual Frame Relay hardware */ +#define FRAD_GET_CONF (SIOCDEVPRIVATE) +#define FRAD_SET_CONF (SIOCDEVPRIVATE + 1) + +#define FRAD_LAST_IOCTL FRAD_SET_CONF + +struct frad_conf +{ + short station; + short flags; + short kbaud; + short clocking; + short mtu; + short T391; + short T392; + short N391; + short N392; + short N393; + short CIR_fwd; + short Bc_fwd; + short Be_fwd; + short CIR_bwd; + short Bc_bwd; + short Be_bwd; + +/* Add new fields here, above is a mirror of the sangoma_conf */ + +}; + +#define FRAD_STATION_CPE 0x0000 +#define FRAD_STATION_NODE 0x0001 + +#define FRAD_TX_IGNORE_CIR 0x0001 +#define FRAD_RX_ACCOUNT_CIR 0x0002 +#define FRAD_DROP_ABORTED 0x0004 +#define FRAD_BUFFERIF 0x0008 +#define FRAD_STATS 0x0010 +#define FRAD_MCI 0x0100 +#define FRAD_AUTODLCI 0x8000 +#define FRAD_VALID_FLAGS 0x811F + +#define FRAD_CLOCK_INT 0x0001 +#define FRAD_CLOCK_EXT 0x0000 + +#ifdef __KERNEL__ + +struct fradhdr +{ + /* these are the fields of an RFC 1490 header */ + unsigned char control; + unsigned char pad; /* for IP packets, this can be the NLPID */ + unsigned char NLPID; + unsigned char OUI[3]; + unsigned short PID; +}; + +/* see RFC 1490 for the definition of the following */ +#define FRAD_I_UI 0x03 + +#define FRAD_P_PADDING 0x00 +#define FRAD_P_Q933 0x08 +#define FRAD_P_SNAP 0x80 +#define FRAD_P_CLNP 0x81 +#define FRAD_P_IP 0xCC + +struct dlci_local +{ + struct enet_statistics stats; + struct device *slave; + struct dlci_conf config; + int configured; + + /* callback function */ + void (*receive)(struct sk_buff *skb, struct device *); +}; + +struct frad_local +{ + struct enet_statistics stats; + struct timer_list timer; + + /* devices which this FRAD is slaved to */ + struct device *master[CONFIG_DLCI_MAX]; + short dlci[CONFIG_DLCI_MAX]; + + /* callback functions */ + int (*activate)(struct device *, struct device *); + int (*deactivate)(struct device *, struct device *); + int (*assoc)(struct device *, struct device *); + int (*deassoc)(struct device *, struct device *); + int (*dlci_conf)(struct device *, struct device *, int get); + + int initialized; /* mem_start, port, irq set ? */ + int configured; /* has this device been configured */ + int type; /* adapter type */ + int state; /* state of the S502/8 control latch */ + int buffer; /* current buffer for S508 firmware */ + struct frad_conf config; +}; + +int register_frad(const char *name); +int unregister_frad(const char *name); + +#endif __KERNEL__ + +#endif diff --git a/include/linux/if_tr.h b/include/linux/if_tr.h index 61629332b90f..545f1b7f07a8 100644 --- a/include/linux/if_tr.h +++ b/include/linux/if_tr.h @@ -45,37 +45,36 @@ /* This is an Token-Ring frame header. */ struct trh_hdr { - unsigned char ac; /* access control field */ - unsigned char fc; /* frame control field */ - unsigned char daddr[TR_ALEN]; /* destination address */ - unsigned char saddr[TR_ALEN]; /* source address */ - unsigned short rcf; /* route control field */ - unsigned short rseg[8];/* routing registers */ + __u8 ac; /* access control field */ + __u8 fc; /* frame control field */ + __u8 daddr[TR_ALEN]; /* destination address */ + __u8 saddr[TR_ALEN]; /* source address */ + __u16 rcf; /* route control field */ + __u16 rseg[8]; /* routing registers */ }; /* This is an Token-Ring LLC structure */ struct trllc { - unsigned char dsap; /* destination SAP */ - unsigned char ssap; /* source SAP */ - unsigned char llc; /* LLC control field */ - unsigned char protid[3]; /* protocol id */ - unsigned short ethertype; /* ether type field */ + __u8 dsap; /* destination SAP */ + __u8 ssap; /* source SAP */ + __u8 llc; /* LLC control field */ + __u8 protid[3]; /* protocol id */ + __u16 ethertype; /* ether type field */ }; - /* Token-Ring statistics collection data. */ -struct tr_statistics{ - int rx_packets; /* total packets received */ - int tx_packets; /* total packets transmitted */ - int rx_errors; /* bad packets received */ - int tx_errors; /* packet transmit problems */ - int rx_dropped; /* no space in linux buffers */ - int tx_dropped; /* no space available in linux */ - int multicast; /* multicast packets received */ - int transmit_collision; +struct tr_statistics { + int rx_packets; /* total packets received */ + int tx_packets; /* total packets transmitted */ + int rx_errors; /* bad packets received */ + int tx_errors; /* packet transmit problems */ + int rx_dropped; /* no space in linux buffers */ + int tx_dropped; /* no space available in linux */ + int multicast; /* multicast packets received */ + int transmit_collision; - /* detailed Token-Ring errors. See IBM Token-Ring Network Architecture - for more info */ + /* detailed Token-Ring errors. See IBM Token-Ring Network + Architecture for more info */ int line_errors; int internal_errors; @@ -88,7 +87,6 @@ struct tr_statistics{ int frequency_errors; int token_errors; int dummy1; - }; /* source routing stuff */ diff --git a/include/linux/kd.h b/include/linux/kd.h index d10deaa975ed..68c9b34582ee 100644 --- a/include/linux/kd.h +++ b/include/linux/kd.h @@ -10,8 +10,8 @@ #define GIO_FONTX 0x4B6B /* get font using struct consolefontdesc */ #define PIO_FONTX 0x4B6C /* set font using struct consolefontdesc */ struct consolefontdesc { - u_short charcount; /* characters in font (256 or 512) */ - u_short charheight; /* scan lines per character (1-32) */ + unsigned short charcount; /* characters in font (256 or 512) */ + unsigned short charheight; /* scan lines per character (1-32) */ char *chardata; /* font data in expanded form */ }; @@ -58,19 +58,19 @@ typedef char scrnmap_t; #define GIO_UNIMAP 0x4B66 /* get unicode-to-font mapping from kernel */ struct unipair { - u_short unicode; - u_short fontpos; + unsigned short unicode; + unsigned short fontpos; }; struct unimapdesc { - u_short entry_ct; + unsigned short entry_ct; struct unipair *entries; }; #define PIO_UNIMAP 0x4B67 /* put unicode-to-font mapping in kernel */ #define PIO_UNIMAPCLR 0x4B68 /* clear table, possibly advise hash algorithm */ struct unimapinit { - u_short advised_hashsize; /* 0 if no opinion */ - u_short advised_hashstep; /* 0 if no opinion */ - u_short advised_hashlevel; /* 0 if no opinion */ + unsigned short advised_hashsize; /* 0 if no opinion */ + unsigned short advised_hashstep; /* 0 if no opinion */ + unsigned short advised_hashlevel; /* 0 if no opinion */ }; #define UNI_DIRECT_BASE 0xF000 /* start of Direct Font Region */ @@ -95,9 +95,9 @@ struct unimapinit { #define KDSKBLED 0x4B65 /* set led flags (not lights) */ struct kbentry { - u_char kb_table; - u_char kb_index; - u_short kb_value; + unsigned char kb_table; + unsigned char kb_index; + unsigned short kb_value; }; #define K_NORMTAB 0x00 #define K_SHIFTTAB 0x01 @@ -108,14 +108,14 @@ struct kbentry { #define KDSKBENT 0x4B47 /* sets one entry in translation table */ struct kbsentry { - u_char kb_func; - u_char kb_string[512]; + unsigned char kb_func; + unsigned char kb_string[512]; }; #define KDGKBSENT 0x4B48 /* gets one function key string entry */ #define KDSKBSENT 0x4B49 /* sets one function key string entry */ struct kbdiacr { - u_char diacr, base, result; + unsigned char diacr, base, result; }; struct kbdiacrs { unsigned int kb_cnt; /* number of entries in following array */ diff --git a/include/linux/kerneld.h b/include/linux/kerneld.h index c6769c1ffb78..49719cc76f66 100644 --- a/include/linux/kerneld.h +++ b/include/linux/kerneld.h @@ -8,6 +8,7 @@ #define KERNELD_CANCEL_RELEASE_MODULE 5 /* "rmmod" */ #define KERNELD_REQUEST_ROUTE 6 /* from net/ipv4/route.c */ #define KERNELD_BLANKER 7 /* from drivers/char/console.c */ +#define KERNELD_ARP 256 /* from net/ipv4/arp.c */ #define IPC_KERNELD 00040000 /* use the kerneld message channel */ #define KERNELD_MAXCMD 0x7ffeffff diff --git a/include/linux/loop.h b/include/linux/loop.h index 3724bb0e9800..1e75b4cab724 100644 --- a/include/linux/loop.h +++ b/include/linux/loop.h @@ -12,6 +12,8 @@ #define LO_NAME_SIZE 64 #define LO_KEY_SIZE 32 + +#ifdef __KERNEL__ struct loop_device { int lo_number; @@ -39,6 +41,9 @@ typedef int (* transfer_proc_t)(struct loop_device *, int cmd, * Loop flags */ #define LO_FLAGS_DO_BMAP 0x00000001 +#define LO_FLAGS_READ_ONLY 0x00000002 + +#endif /* __KERNEL__ */ struct loop_info { int lo_number; /* ioctl r/o */ diff --git a/include/linux/mcdx.h b/include/linux/mcdx.h index 8cc90a1aa1f8..53c683c04d4e 100644 --- a/include/linux/mcdx.h +++ b/include/linux/mcdx.h @@ -1,7 +1,7 @@ /* * Definitions for the Mitsumi CDROM interface * Copyright (C) 1995 Heiko Schlittermann - * VERSION: 1.8 + * VERSION: 1.9 * * 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 diff --git a/include/linux/ncp_fs.h b/include/linux/ncp_fs.h index 4db2ca25dee8..1cdbc6902a9f 100644 --- a/include/linux/ncp_fs.h +++ b/include/linux/ncp_fs.h @@ -34,18 +34,16 @@ struct ncp_fs_info { int buffer_size; /* The negotiated buffer size, to be used for read/write requests! */ - /* Not used yet, but here some day the namespace numbers will be - stored. */ int volume_number; __u32 directory_id; }; -#define NCP_IOC_NCPREQUEST _IOR('n', 1, unsigned char *) -#define NCP_IOC_GETMOUNTUID _IOR('u', 1, uid_t) -#define NCP_IOC_CONN_LOGGED_IN _IO('l', 1) +#define NCP_IOC_NCPREQUEST _IOR('n', 1, struct ncp_ioctl_request) +#define NCP_IOC_GETMOUNTUID _IOW('n', 2, uid_t) +#define NCP_IOC_CONN_LOGGED_IN _IO('n', 3) #define NCP_GET_FS_INFO_VERSION (1) -#define NCP_IOC_GET_FS_INFO _IOWR('i', 1, unsigned char *) +#define NCP_IOC_GET_FS_INFO _IOWR('n', 4, struct ncp_fs_info) /* * The packet size to allocate. One page should be enough. diff --git a/include/linux/net.h b/include/linux/net.h index 1fbe98a0f04b..68e9158680a0 100644 --- a/include/linux/net.h +++ b/include/linux/net.h @@ -83,6 +83,7 @@ struct socket { struct wait_queue **wait; /* ptr to place to wait on */ struct inode *inode; struct fasync_struct *fasync_list; /* Asynchronous wake up list */ + struct file *file; /* File back pointer for gc */ }; #define SOCK_INODE(S) ((S)->inode) diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index 8685ff0eda87..c93eb5465dca 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -187,6 +187,8 @@ struct device #define HAVE_HEADER_CACHE void (*header_cache_bind)(struct hh_cache **hhp, struct device *dev, unsigned short htype, __u32 daddr); void (*header_cache_update)(struct hh_cache *hh, struct device *dev, unsigned char * haddr); +#define HAVE_CHANGE_MTU + int (*change_mtu)(struct device *dev, int new_mtu); }; diff --git a/include/linux/optcd.h b/include/linux/optcd.h index 448734bfc4c6..79f03ce804b5 100644 --- a/include/linux/optcd.h +++ b/include/linux/optcd.h @@ -43,7 +43,7 @@ #define STOP_TIMEOUT 1000 /* for poll wait */ #define RESET_WAIT 1000 /* busy wait at drive reset */ -/* # of buffer for block size conversion. 6 is optimal for my setup (P75), +/* # of buffers for block size conversion. 6 is optimal for my setup (P75), giving 280 kb/s, with 0.4% CPU usage. Experiment to find your optimal setting */ #define N_BUFS 6 diff --git a/include/linux/pci.h b/include/linux/pci.h index 6994f359d0d2..d9298113ed5c 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -31,10 +31,14 @@ * PCI-CPU bridge or PCI-ISA bridge. * - If you can't find the actual information in your hardware * booklet, try to read the references of the chip on the board. - * - Send all that, with the word PCIPROBE in the subject, - * to frederic@cao-vlsi.ibp.fr, and I'll add your device to - * the list as soon as possible - * fred. + * - Send all that to linux-pcisupport@cao-vlsi.ibp.fr, + * and I'll add your device to the list as soon as possible + * + * BEFORE you send a mail, please check the latest linux releases + * to be sure it has not been recently added. + * + * Thanks + * Frederic Potter. */ @@ -266,7 +270,6 @@ #define PCI_DEVICE_ID_CIRRUS_5434_4 0x00a4 #define PCI_DEVICE_ID_CIRRUS_5434_8 0x00a8 #define PCI_DEVICE_ID_CIRRUS_5436 0x00ac -#define PCI_DEVICE_ID_CIRRUS_6205 0x0205 #define PCI_DEVICE_ID_CIRRUS_6729 0x1100 #define PCI_DEVICE_ID_CIRRUS_7542 0x1200 #define PCI_DEVICE_ID_CIRRUS_7543 0x1202 @@ -299,6 +302,7 @@ #define PCI_DEVICE_ID_CT_65548 0x00dc #define PCI_VENDOR_ID_MIRO 0x1031 +#define PCI_DEVICE_ID_MIRO_36050 0x5601 #define PCI_VENDOR_ID_FD 0x1036 #define PCI_DEVICE_ID_FD_36C70 0x0000 @@ -306,6 +310,7 @@ #define PCI_VENDOR_ID_SI 0x1039 #define PCI_DEVICE_ID_SI_6201 0x0001 #define PCI_DEVICE_ID_SI_6202 0x0002 +#define PCI_DEVICE_ID_SI_6205 0x0205 #define PCI_DEVICE_ID_SI_503 0x0008 #define PCI_DEVICE_ID_SI_501 0x0406 #define PCI_DEVICE_ID_SI_496 0x0496 @@ -442,7 +447,20 @@ #define PCI_DEVICE_ID_VIA_82C416 0x1571 #define PCI_VENDOR_ID_VORTEX 0x1119 -#define PCI_DEVICE_ID_VORTEX_GDT 0x0001 +#define PCI_DEVICE_ID_VORTEX_GDT60x0 0x0000 +#define PCI_DEVICE_ID_VORTEX_GDT6000B 0x0001 +#define PCI_DEVICE_ID_VORTEX_GDT6x10 0x0002 +#define PCI_DEVICE_ID_VORTEX_GDT6x20 0x0003 +#define PCI_DEVICE_ID_VORTEX_GDT6530 0x0004 +#define PCI_DEVICE_ID_VORTEX_GDT6550 0x0005 +#define PCI_DEVICE_ID_VORTEX_GDT6x17 0x0006 +#define PCI_DEVICE_ID_VORTEX_GDT6x27 0x0007 +#define PCI_DEVICE_ID_VORTEX_GDT6537 0x0008 +#define PCI_DEVICE_ID_VORTEX_GDT6557 0x0009 +#define PCI_DEVICE_ID_VORTEX_GDT6x15 0x000a +#define PCI_DEVICE_ID_VORTEX_GDT6x25 0x000b +#define PCI_DEVICE_ID_VORTEX_GDT6535 0x000c +#define PCI_DEVICE_ID_VORTEX_GDT6555 0x000d #define PCI_VENDOR_ID_EF 0x111a #define PCI_DEVICE_ID_EF_ATM_FPGA 0x0000 @@ -450,6 +468,7 @@ #define PCI_VENDOR_ID_FORE 0x1127 #define PCI_DEVICE_ID_FORE_PCA200PC 0x0210 +#define PCI_DEVICE_ID_FORE_PCA200E 0x0300 #define PCI_VENDOR_ID_IMAGINGTECH 0x112f #define PCI_DEVICE_ID_IMAGINGTECH_ICPCI 0x0000 diff --git a/include/linux/posix_types.h b/include/linux/posix_types.h new file mode 100644 index 000000000000..87c17c701316 --- /dev/null +++ b/include/linux/posix_types.h @@ -0,0 +1,59 @@ +#ifndef _LINUX_POSIX_TYPES_H +#define _LINUX_POSIX_TYPES_H + +#define _GNU_TYPES_H + +/* + * This file is generally used by user-level software, so you need to + * be a little careful about namespace pollution etc. Also, we cannot + * assume GCC is being used. + */ + +#ifndef NULL +# define NULL ((void *) 0) +#endif + +/* + * This allows for 256 file descriptors: if NR_OPEN is ever grown + * beyond that you'll have to change this too. But 256 fd's seem to be + * enough even for such "real" unices like SunOS, so hopefully this is + * one limit that doesn't have to be changed. + * + * Note that POSIX wants the FD_CLEAR(fd,fdsetp) defines to be in + * (and thus ) - but this is a more logical + * place for them. Solved by having dummy defines in . + */ + +/* + * Those macros may have been defined in . But we always + * use the ones here. + */ +#undef __NFDBITS +#define __NFDBITS (8 * sizeof(unsigned int)) + +#undef __FD_SETSIZE +#define __FD_SETSIZE 256 + +#undef __FDSET_INTS +#define __FDSET_INTS (__FD_SETSIZE/__NFDBITS) + +#undef __FDELT +#define __FDELT(d) ((d) / __NFDBITS) + +#undef __FDMASK +#define __FDMASK(d) (1 << ((d) % __NFDBITS)) + +typedef struct fd_set { + unsigned int fds_bits [__FDSET_INTS]; +} __fd_set; + +#include + +/* bsd */ + +typedef unsigned char __u_char; +typedef unsigned short __u_short; +typedef unsigned int __u_int; +typedef unsigned long __u_long; + +#endif /* _LINUX_POSIX_TYPES_H */ diff --git a/include/linux/sched.h b/include/linux/sched.h index 86cfa94604ac..cb51539ff9f3 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -260,7 +260,7 @@ struct task_struct { #define PF_PTRACED 0x00000010 /* set if ptrace (0) has been called. */ #define PF_TRACESYS 0x00000020 /* tracing system calls */ #define PF_FORKNOEXEC 0x00000040 /* forked but didn't exec */ -#define PF_SUPERPREV 0x00000100 /* used super-user privileges */ +#define PF_SUPERPRIV 0x00000100 /* used super-user privileges */ #define PF_DUMPCORE 0x00000200 /* dumped core */ #define PF_SIGNALED 0x00000400 /* killed by a signal */ @@ -362,7 +362,7 @@ extern void free_irq(unsigned int irq, void *dev_id); extern inline int suser(void) { if (current->euid == 0) - current->flags |= PF_SUPERPREV; + current->flags |= PF_SUPERPRIV; return (current->euid == 0); } diff --git a/include/linux/sdla.h b/include/linux/sdla.h new file mode 100644 index 000000000000..26fcd8c3cb6f --- /dev/null +++ b/include/linux/sdla.h @@ -0,0 +1,327 @@ +/* + * INET An implementation of the TCP/IP protocol suite for the LINUX + * operating system. INET is implemented using the BSD Socket + * interface as the means of communication with the user level. + * + * Global definitions for the Frame relay interface. + * + * Version: @(#)if_ifrad.h 0.10 23 Mar 96 + * + * Author: Mike McLagan + * + * 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. + */ + +#ifndef SDLA_H +#define SDLA_H + +/* adapter type */ +#define SDLA_TYPES +#define SDLA_S502A 5020 +#define SDLA_S502E 5021 +#define SDLA_S503 5030 +#define SDLA_S507 5070 +#define SDLA_S508 5080 +#define SDLA_S509 5090 +#define SDLA_UNKNOWN -1 + +/* port selection flags for the S508 */ +#define SDLA_S508_PORT_V35 0x00 +#define SDLA_S508_PORT_RS232 0x02 + +/* Z80 CPU speeds */ +#define SDLA_CPU_3M 0x00 +#define SDLA_CPU_5M 0x01 +#define SDLA_CPU_7M 0x02 +#define SDLA_CPU_8M 0x03 +#define SDLA_CPU_10M 0x04 +#define SDLA_CPU_16M 0x05 +#define SDLA_CPU_12M 0x06 + +/* some private IOCTLs */ +#define SDLA_IDENTIFY (FRAD_LAST_IOCTL + 1) +#define SDLA_CPUSPEED (FRAD_LAST_IOCTL + 2) +#define SDLA_PROTOCOL (FRAD_LAST_IOCTL + 3) + +#define SDLA_CLEARMEM (FRAD_LAST_IOCTL + 4) +#define SDLA_WRITEMEM (FRAD_LAST_IOCTL + 5) +#define SDLA_READMEM (FRAD_LAST_IOCTL + 6) + +struct sdla_mem { + int addr; + int len; + void *data; +}; + +#define SDLA_START (FRAD_LAST_IOCTL + 7) +#define SDLA_STOP (FRAD_LAST_IOCTL + 8) + +/* some offsets in the Z80's memory space */ +#define SDLA_NMIADDR 0x0000 +#define SDLA_CONF_ADDR 0x0010 +#define SDLA_S502A_NMIADDR 0x0066 +#define SDLA_CODE_BASEADDR 0x0100 + +/* largest handlable block of data */ +#define SDLA_MAX_DATA 4080 +#define SDLA_MAX_MTU 4072 /* MAX_DATA - sizeof(fradhdr) */ +#define SDLA_MAX_DLCI 24 + +struct sdla_conf { + short station; + short config; + short kbaud; + short clocking; + short max_frm; + short T391; + short T392; + short N391; + short N392; + short N393; + short CIR_fwd; + short Bc_fwd; + short Be_fwd; + short CIR_bwd; + short Bc_bwd; + short Be_bwd; +}; + +struct sdla_dlci { + short config; + short CIR_fwd; + short Bc_fwd; + short Be_fwd; + short CIR_bwd; + short Bc_bwd; + short Be_bwd; + +/* these are part of the status READ */ + short Tc_fwd; + short Tc_bwd; + short Tf_max; + short Tb_max; +}; + +#ifndef __KERNEL__ + +void sdla(void *cfg_info, char *dev, struct frad_conf *conf, int quiet); + +#else + +/* important Z80 window addresses */ +#define SDLA_CONTROL_WND 0xE000 + +#define SDLA_502_CMD_BUF 0xEF60 +#define SDLA_502_RCV_BUF 0xA900 +#define SDLA_502_TXN_AVAIL 0xFFF1 +#define SDLA_502_RCV_AVAIL 0xFFF2 +#define SDLA_502_EVENT_FLAGS 0xFFF3 +#define SDLA_502_MDM_STATUS 0xFFF4 +#define SDLA_502_IRQ_INTERFACE 0xFFFD +#define SDLA_502_IRQ_PERMISSION 0xFFFE +#define SDLA_502_DATA_OFS 0x0010 + +#define SDLA_508_CMD_BUF 0xE000 +#define SDLA_508_TXBUF_INFO 0xF100 +#define SDLA_508_RXBUF_INFO 0xF120 +#define SDLA_508_EVENT_FLAGS 0xF003 +#define SDLA_508_MDM_STATUS 0xF004 +#define SDLA_508_IRQ_INTERFACE 0xF010 +#define SDLA_508_IRQ_PERMISSION 0xF011 +#define SDLA_508_TSE_OFFSET 0xF012 + +/* Event flags */ +#define SDLA_EVENT_STATUS 0x01 +#define SDLA_EVENT_DLCI_STATUS 0x02 +#define SDLA_EVENT_BAD_DLCI 0x04 +#define SDLA_EVENT_LINK_DOWN 0x40 + +/* IRQ Trigger flags */ +#define SDLA_INTR_RX 0x01 +#define SDLA_INTR_TX 0x02 +#define SDLA_INTR_MODEM 0x04 +#define SDLA_INTR_COMPLETE 0x08 +#define SDLA_INTR_STATUS 0x10 +#define SDLA_INTR_TIMER 0x20 + +/* DLCI status bits */ +#define SDLA_DLCI_DELETED 0x01 +#define SDLA_DLCI_ACTIVE 0x02 +#define SDLA_DLCI_WAITING 0x04 +#define SDLA_DLCI_NEW 0x08 +#define SDLA_DLCI_INCLUDED 0x40 + +/* valid command codes */ +#define SDLA_INFORMATION_WRITE 0x01 +#define SDLA_INFORMATION_READ 0x02 +#define SDLA_ISSUE_IN_CHANNEL_SIGNAL 0x03 +#define SDLA_SET_DLCI_CONFIGURATION 0x10 +#define SDLA_READ_DLCI_CONFIGURATION 0x11 +#define SDLA_DISABLE_COMMUNICATIONS 0x12 +#define SDLA_ENABLE_COMMUNICATIONS 0x13 +#define SDLA_READ_DLC_STATUS 0x14 +#define SDLA_READ_DLC_STATISTICS 0x15 +#define SDLA_FLUSH_DLC_STATISTICS 0x16 +#define SDLA_LIST_ACTIVE_DLCI 0x17 +#define SDLA_FLUSH_INFORMATION_BUFFERS 0x18 +#define SDLA_ADD_DLCI 0x20 +#define SDLA_DELETE_DLCI 0x21 +#define SDLA_ACTIVATE_DLCI 0x22 +#define SDLA_DEACTIVATE_DLCI 0x23 +#define SDLA_READ_MODEM_STATUS 0x30 +#define SDLA_SET_MODEM_STATUS 0x31 +#define SDLA_READ_COMMS_ERR_STATS 0x32 +#define SDLA_FLUSH_COMMS_ERR_STATS 0x33 +#define SDLA_READ_CODE_VERSION 0x40 +#define SDLA_SET_IRQ_TRIGGER 0x50 +#define SDLA_GET_IRQ_TRIGGER 0x51 + +/* In channel signal types */ +#define SDLA_ICS_LINK_VERIFY 0x02 +#define SDLA_ICS_STATUS_ENQ 0x03 + +/* modem status flags */ +#define SDLA_MODEM_DTR_HIGH 0x01 +#define SDLA_MODEM_RTS_HIGH 0x02 +#define SDLA_MODEM_DCD_HIGH 0x08 +#define SDLA_MODEM_CTS_HIGH 0x20 + +/* used for RET_MODEM interpretation */ +#define SDLA_MODEM_DCD_LOW 0x01 +#define SDLA_MODEM_CTS_LOW 0x02 + +/* return codes */ +#define SDLA_RET_OK 0x00 +#define SDLA_RET_COMMUNICATIONS 0x01 +#define SDLA_RET_CHANNEL_INACTIVE 0x02 +#define SDLA_RET_DLCI_INACTIVE 0x03 +#define SDLA_RET_DLCI_CONFIG 0x04 +#define SDLA_RET_BUF_TOO_BIG 0x05 +#define SDLA_RET_NO_DATA 0x05 +#define SDLA_RET_BUF_OVERSIZE 0x06 +#define SDLA_RET_CIR_OVERFLOW 0x07 +#define SDLA_RET_NO_BUFF 0x08 +#define SDLA_RET_TIMEOUT 0x0A +#define SDLA_RET_MODEM 0x10 +#define SDLA_RET_CHANNEL_OFF 0x11 +#define SDLA_RET_CHANNEL_ON 0x12 +#define SDLA_RET_DLCI_STATUS 0x13 +#define SDLA_RET_DLCI_UNKNOWN 0x14 +#define SDLA_RET_COMMAND_INVALID 0x1F + +/* Configuration flags */ +#define SDLA_DIRECT_RECV 0x0080 + +/* IRQ selection flags */ +#define SDLA_IRQ_RECEIVE 0x01 +#define SDLA_IRQ_TRANSMIT 0x02 +#define SDLA_IRQ_MODEM_STAT 0x04 +#define SDLA_IRQ_COMMAND 0x08 +#define SDLA_IRQ_CHANNEL 0x10 +#define SDLA_IRQ_TIMER 0x20 + +/* definitions for PC memory mapping */ +#define SDLA_8K_WINDOW 0x01 +#define SDLA_S502_SEG_A 0x10 +#define SDLA_S502_SEG_C 0x20 +#define SDLA_S502_SEG_D 0x00 +#define SDLA_S502_SEG_E 0x30 +#define SDLA_S507_SEG_A 0x00 +#define SDLA_S507_SEG_B 0x40 +#define SDLA_S507_SEG_C 0x80 +#define SDLA_S507_SEG_E 0xC0 +#define SDLA_S508_SEG_A 0x00 +#define SDLA_S508_SEG_C 0x10 +#define SDLA_S508_SEG_D 0x08 +#define SDLA_S508_SEG_E 0x18 + +/* SDLA adapter port constants */ +#define SDLA_IO_EXTENTS 0x04 + +#define SDLA_REG_CONTROL 0x00 +#define SDLA_REG_PC_WINDOW 0x01 /* offset for PC window select latch */ +#define SDLA_REG_Z80_WINDOW 0x02 /* offset for Z80 window select latch */ +#define SDLA_REG_Z80_CONTROL 0x03 /* offset for Z80 control latch */ + +#define SDLA_S502_STS 0x00 /* status reg for 502, 502E, 507 */ +#define SDLA_S508_GNRL 0x00 /* general purp. reg for 508 */ +#define SDLA_S508_STS 0x01 /* status reg for 508 */ +#define SDLA_S508_IDR 0x02 /* ID reg for 508 */ + +/* control register flags */ +#define SDLA_S502A_START 0x00 /* start the CPU */ +#define SDLA_S502A_INTREQ 0x02 +#define SDLA_S502A_INTEN 0x04 +#define SDLA_S502A_HALT 0x08 /* halt the CPU */ +#define SDLA_S502A_NMI 0x10 /* issue an NMI to the CPU */ + +#define SDLA_S502E_CPUEN 0x01 +#define SDLA_S502E_ENABLE 0x02 +#define SDLA_S502E_INTACK 0x04 + +#define SDLA_S507_ENABLE 0x01 +#define SDLA_S507_IRQ3 0x00 +#define SDLA_S507_IRQ4 0x20 +#define SDLA_S507_IRQ5 0x40 +#define SDLA_S507_IRQ7 0x60 +#define SDLA_S507_IRQ10 0x80 +#define SDLA_S507_IRQ11 0xA0 +#define SDLA_S507_IRQ12 0xC0 +#define SDLA_S507_IRQ15 0xE0 + +#define SDLA_HALT 0x00 +#define SDLA_CPUEN 0x02 +#define SDLA_MEMEN 0x04 +#define SDLA_S507_EPROMWR 0x08 +#define SDLA_S507_EPROMCLK 0x10 +#define SDLA_S508_INTRQ 0x08 +#define SDLA_S508_INTEN 0x10 + +struct sdla_cmd { + char opp_flag __attribute__((packed)); + char cmd __attribute__((packed)); + short length __attribute__((packed)); + char retval __attribute__((packed)); + short dlci __attribute__((packed)); + char flags __attribute__((packed)); + short rxlost_int __attribute__((packed)); + long rxlost_app __attribute__((packed)); + char reserve[2] __attribute__((packed)); + char data[SDLA_MAX_DATA] __attribute__((packed)); /* transfer data buffer */ +}; + +struct intr_info { + char flags __attribute__((packed)); + short txlen __attribute__((packed)); + char irq __attribute__((packed)); + char flags2 __attribute__((packed)); + short timeout __attribute__((packed)); +}; + +/* found in the 508's control window at RXBUF_INFO */ +struct buf_info { + unsigned short rse_num __attribute__((packed)); + unsigned long rse_base __attribute__((packed)); + unsigned long rse_next __attribute__((packed)); + unsigned long buf_base __attribute__((packed)); + unsigned short reserved __attribute__((packed)); + unsigned long buf_top __attribute__((packed)); +}; + +/* structure pointed to by rse_base in RXBUF_INFO struct */ +struct buf_entry { + char opp_flag __attribute__((packed)); + short length __attribute__((packed)); + short dlci __attribute__((packed)); + char flags __attribute__((packed)); + short timestamp __attribute__((packed)); + short reserved[2] __attribute__((packed)); + long buf_addr __attribute__((packed)); +}; + +#endif + +#endif diff --git a/include/linux/smp.h b/include/linux/smp.h index 539366034649..72984f1541c6 100644 --- a/include/linux/smp.h +++ b/include/linux/smp.h @@ -14,7 +14,6 @@ extern void smp_boot_cpus(void); /* Boot processor call to load the other CPU's extern void smp_callin(void); /* Processor call in. Must hold processors until .. */ extern void smp_commence(void); /* Multiprocessors may now schedule */ extern int smp_num_cpus; -extern int smp_top_cpu; /* Top CPU number */ extern int smp_threads_ready; /* True once the per process idle is forked */ #ifdef __SMP_PROF__ extern volatile unsigned long smp_spins[NR_CPUS]; /* count of interrupt spins */ @@ -48,7 +47,6 @@ extern volatile int smp_msg_id; #define smp_num_cpus 1 #define smp_processor_id() 0 -#define smp_top_cpu 0 #define smp_message_pass(t,m,d,w) #define smp_threads_ready 1 #define kernel_lock() diff --git a/include/linux/socket.h b/include/linux/socket.h index bbea1e1527b9..31f96f821f31 100644 --- a/include/linux/socket.h +++ b/include/linux/socket.h @@ -96,6 +96,8 @@ struct msghdr #define SOL_TCP 6 #define SOL_UDP 17 +#ifdef __KERNEL__ + /* IP options */ #define IP_TOS 1 #define IPTOS_LOWDELAY 0x10 @@ -111,6 +113,7 @@ struct msghdr #define IP_ADD_MEMBERSHIP 35 #define IP_DROP_MEMBERSHIP 36 +#endif /* __KERNEL__ */ /* These need to appear somewhere around here */ #define IP_DEFAULT_MULTICAST_TTL 1 diff --git a/include/linux/sockios.h b/include/linux/sockios.h index ee20a0b12ad4..b03c12bc5ed7 100644 --- a/include/linux/sockios.h +++ b/include/linux/sockios.h @@ -18,6 +18,8 @@ #ifndef _LINUX_SOCKIOS_H #define _LINUX_SOCKIOS_H +#include + /* Routing table calls. */ #define SIOCADDRT 0x890B /* add routing table entry */ #define SIOCDELRT 0x890C /* delete routing table entry */ diff --git a/include/linux/tty.h b/include/linux/tty.h index 6e1bc50a8aa9..9c0519feaa35 100644 --- a/include/linux/tty.h +++ b/include/linux/tty.h @@ -5,6 +5,16 @@ * 'tty.h' defines some structures used by tty_io.c and some defines. */ +/* + * These constants are also useful for user-level apps (e.g., VC + * resizing). + */ +#define MIN_NR_CONSOLES 1 /* must be at least 1 */ +#define MAX_NR_CONSOLES 63 /* serial lines start at 64 */ +#define MAX_NR_USER_CONSOLES 63 /* must be root to allocate above this */ + /* Note: the ioctl VT_GETSTATE does not work for + consoles 16 and higher (since it returns a short) */ + #ifdef __KERNEL__ #include #include @@ -21,11 +31,6 @@ * (Note: the *_driver.minor_start values 1, 64, 128, 192 are * hardcoded at present.) */ -#define MIN_NR_CONSOLES 1 /* must be at least 1 */ -#define MAX_NR_CONSOLES 63 /* serial lines start at 64 */ -#define MAX_NR_USER_CONSOLES 63 /* must be root to allocate above this */ - /* Note: the ioctl VT_GETSTATE does not work for - consoles 16 and higher (since it returns a short) */ #define NR_PTYS 256 #define NR_LDISCS 16 diff --git a/include/linux/types.h b/include/linux/types.h index 43c04a5e02e7..b4a73da50bc4 100644 --- a/include/linux/types.h +++ b/include/linux/types.h @@ -1,68 +1,92 @@ #ifndef _LINUX_TYPES_H #define _LINUX_TYPES_H -/* - * This allows for 256 file descriptors: if NR_OPEN is ever grown beyond that - * you'll have to change this too. But 256 fd's seem to be enough even for such - * "real" unices like SunOS, so hopefully this is one limit that doesn't have - * to be changed. - * - * Note that POSIX wants the FD_CLEAR(fd,fdsetp) defines to be in - * (and thus ) - but this is a more logical place for them. Solved - * by having dummy defines in . - */ +#include +#include -/* - * Those macros may have been defined in . But we always - * use the ones here. - */ -#undef __NFDBITS -#define __NFDBITS (8 * sizeof(unsigned int)) +#ifndef _LINUX_TYPES_DONT_EXPORT -#undef __FD_SETSIZE -#define __FD_SETSIZE 256 +typedef __fd_set fd_set; +typedef __dev_t dev_t; +typedef __ino_t ino_t; +typedef __mode_t mode_t; +typedef __nlink_t nlink_t; +typedef __off_t off_t; +typedef __pid_t pid_t; +typedef __uid_t uid_t; +typedef __gid_t gid_t; +typedef __daddr_t daddr_t; -#undef __FDSET_INTS -#define __FDSET_INTS (__FD_SETSIZE/__NFDBITS) +/* bsd */ -typedef struct fd_set { - unsigned int fds_bits [__FDSET_INTS]; -} fd_set; +typedef __u_char u_char; +typedef __u_short u_short; +typedef __u_int u_int; +typedef __u_long u_long; -#include +/* + * The following typedefs are also protected by individual ifdefs for + * historical reasons: + */ +#ifndef _SIZE_T +#define _SIZE_T +typedef __size_t size_t; +#endif -#ifndef NULL -#define NULL ((void *) 0) +#ifndef _SSIZE_T +#define _SSIZE_T +typedef __ssize_t ssize_t; #endif -#if defined(__GNUC__) && !defined(__STRICT_ANSI__) -#define _LOFF_T -typedef long long loff_t; +#ifndef _PTRDIFF_T +#define _PTRDIFF_T +typedef __ptrdiff_t ptrdiff_t; #endif -/* bsd */ -typedef unsigned char u_char; -typedef unsigned short u_short; -typedef unsigned int u_int; -typedef unsigned long u_long; +#ifndef _TIME_T +#define _TIME_T +typedef __time_t time_t; +#endif + +#ifndef _CLOCK_T +#define _CLOCK_T +typedef __clock_t clock_t; +#endif + +#ifndef _CADDR_T +#define _CADDR_T +typedef __caddr_t caddr_t; +#endif /* sysv */ -typedef unsigned char unchar; -typedef unsigned short ushort; -typedef unsigned int uint; -typedef unsigned long ulong; +typedef unsigned char unchar; +typedef unsigned short ushort; +typedef unsigned int uint; +typedef unsigned long ulong; + +#endif /* _LINUX_TYPES_DONT_EXPORT */ + +/* + * Below are truly Linux-specific types that should never collide with + * any application/library that wants linux/types.h. + */ -typedef char *caddr_t; +#if defined(__GNUC__) && !defined(__STRICT_ANSI__) + +typedef long long __loff_t; -typedef unsigned char cc_t; -typedef unsigned int speed_t; -typedef unsigned int tcflag_t; +#ifndef _LINUX_TYPES_DONT_EXPORT +#define _LOFF_T +typedef __loff_t loff_t; +#endif + +#endif struct ustat { - daddr_t f_tfree; - ino_t f_tinode; - char f_fname[6]; - char f_fpack[6]; + __daddr_t f_tfree; + __ino_t f_tinode; + char f_fname[6]; + char f_fpack[6]; }; -#endif +#endif /* _LINUX_TYPES_H */ diff --git a/include/linux/vt.h b/include/linux/vt.h index 768a6b80475a..9f95b0bea5b3 100644 --- a/include/linux/vt.h +++ b/include/linux/vt.h @@ -19,9 +19,9 @@ struct vt_mode { #define VT_ACKACQ 0x02 /* acknowledge switch */ struct vt_stat { - ushort v_active; /* active vt */ - ushort v_signal; /* signal to send */ - ushort v_state; /* vt bitmask */ + unsigned short v_active; /* active vt */ + unsigned short v_signal; /* signal to send */ + unsigned short v_state; /* vt bitmask */ }; #define VT_GETSTATE 0x5603 /* get global vt state info */ #define VT_SENDSIG 0x5604 /* signal to send to bitmask of vts */ @@ -33,19 +33,19 @@ struct vt_stat { #define VT_DISALLOCATE 0x5608 /* free memory associated to vt */ struct vt_sizes { - ushort v_rows; /* number of rows */ - ushort v_cols; /* number of columns */ - ushort v_scrollsize; /* number of lines of scrollback */ + unsigned short v_rows; /* number of rows */ + unsigned short v_cols; /* number of columns */ + unsigned short v_scrollsize; /* number of lines of scrollback */ }; #define VT_RESIZE 0x5609 /* set kernel's idea of screensize */ struct vt_consize { - ushort v_rows; /* number of rows */ - ushort v_cols; /* number of columns */ - ushort v_vlin; /* number of pixel rows on screen */ - ushort v_clin; /* number of pixel rows per character */ - ushort v_vcol; /* number of pixel columns on screen */ - ushort v_ccol; /* number of pixel columns per character */ + unsigned short v_rows; /* number of rows */ + unsigned short v_cols; /* number of columns */ + unsigned short v_vlin; /* number of pixel rows on screen */ + unsigned short v_clin; /* number of pixel rows per character */ + unsigned short v_vcol; /* number of pixel columns on screen */ + unsigned short v_ccol; /* number of pixel columns per character */ }; #define VT_RESIZEX 0x560A /* set kernel's idea of screensize + more */ #define VT_LOCKSWITCH 0x560B /* disallow vt switching */ diff --git a/include/net/af_unix.h b/include/net/af_unix.h index d79ebcc09b1d..93f4c0a7adb9 100644 --- a/include/net/af_unix.h +++ b/include/net/af_unix.h @@ -1,9 +1,9 @@ extern void unix_proto_init(struct net_proto *pro); - +extern struct proto_ops unix_proto_ops; +extern void unix_inflight(struct file *fp); +extern void unix_notinflight(struct file *fp); typedef struct sock unix_socket; -extern int unix_gc_free; -extern void unix_gc_add(struct sock *sk, struct file *fp); -extern void unix_gc_remove(struct file *fp); +unix_socket *unix_socket_list; #define UNIX_MAX_FD 8 diff --git a/include/net/gc.h b/include/net/gc.h new file mode 100644 index 000000000000..0b28c098ec4d --- /dev/null +++ b/include/net/gc.h @@ -0,0 +1,46 @@ +/* + * Interface routines assumed by gc() + * + * Copyright (C) Barak A. Pearlmutter. + * Released under the GPL version 2 or later. + * + */ + +typedef struct object *pobj; /* pointer to a guy of the type we gc */ + +/* + * How to mark and unmark objects + */ + +extern void gc_mark(pobj); +extern void gc_unmark(pobj); +extern int gc_marked(pobj); + +/* + * How to count and access an object's children + */ + +extern int n_children(pobj); /* how many children */ +extern pobj child_n(pobj, int); /* child i, numbered 0..n-1 */ + +/* + * How to access the root set + */ + +extern int root_size(void); /* number of things in root set */ +extern pobj root_elt(int); /* element i of root set, numbered 0..n-1 */ + +/* + * How to access the free list + */ + +extern void clear_freelist(void); +extern void add_to_free_list(pobj); + +/* + * How to iterate through all objects in memory + */ + +extern int N_OBJS; +extern pobj obj_number(int); + diff --git a/include/net/ipx.h b/include/net/ipx.h index 96c624053336..9b8ba7a0b2c0 100644 --- a/include/net/ipx.h +++ b/include/net/ipx.h @@ -11,6 +11,7 @@ #ifndef _NET_INET_IPX_H_ #define _NET_INET_IPX_H_ +#include #include #include #include diff --git a/include/net/p8022.h b/include/net/p8022.h index 52c676be27b9..03d7c3d6611f 100644 --- a/include/net/p8022.h +++ b/include/net/p8022.h @@ -1,2 +1,7 @@ -struct datalink_proto *register_8022_client(unsigned char type, int (*rcvfunc)(struct sk_buff *, struct device *, struct packet_type *)); +#ifndef _NET_P8022_H +#define _NET_P8022_H +extern struct datalink_proto *register_8022_client(unsigned char type, int (*rcvfunc)(struct sk_buff *, struct device *, struct packet_type *)); +extern void unregister_8022_client(unsigned char type); + +#endif diff --git a/include/net/psnap.h b/include/net/psnap.h index b69859dbd20c..49a68f7e9b12 100644 --- a/include/net/psnap.h +++ b/include/net/psnap.h @@ -1,2 +1,7 @@ -struct datalink_proto *register_snap_client(unsigned char *desc, int (*rcvfunc)(struct sk_buff *, struct device *, struct packet_type *)); +#ifndef _NET_PSNAP_H +#define _NET_PSNAP_H +extern struct datalink_proto *register_snap_client(unsigned char *desc, int (*rcvfunc)(struct sk_buff *, struct device *, struct packet_type *)); +extern void unregister_snap_client(unsigned char *desc); + +#endif diff --git a/include/net/sock.h b/include/net/sock.h index 81252107b76e..3cb02ae91bde 100644 --- a/include/net/sock.h +++ b/include/net/sock.h @@ -46,10 +46,12 @@ #include #endif #endif -#ifdef CONFIG_IPX + +#if defined(CONFIG_IPX) || defined(CONFIG_IPX_MODULE) #include #endif -#ifdef CONFIG_ATALK + +#if defined(CONFIG_ATALK) || defined(CONFIG_ATALK_MODULE) #include #endif @@ -73,6 +75,9 @@ struct unix_opt struct inode * inode; struct semaphore readsem; struct sock * other; + int marksweep; +#define MARKED 1 + int inflight; }; /* @@ -92,7 +97,7 @@ struct inet_packet_opt * Once the IPX ncpd patches are in these are going into protinfo */ -#ifdef CONFIG_IPX +#if defined(CONFIG_IPX) || defined(CONFIG_IPX_MODULE) struct ipx_opt { ipx_address dest_addr; @@ -261,12 +266,12 @@ struct sock union { struct unix_opt af_unix; -#ifdef CONFIG_ATALK +#if defined(CONFIG_ATALK) || defined(CONFIG_ATALK_MODULE) struct atalk_sock af_at; #endif -#ifdef CONFIG_IPX +#if defined(CONFIG_IPX) || defined(CONFIG_IPX_MODULE) struct ipx_opt af_ipx; -#endif +#endif #ifdef CONFIG_INET struct inet_packet_opt af_packet; #ifdef CONFIG_NUTCP diff --git a/init/main.c b/init/main.c index e63493ffd22d..e8179846ff6a 100644 --- a/init/main.c +++ b/init/main.c @@ -586,32 +586,29 @@ asmlinkage void start_secondary(void) static void smp_init(void) { - int i=0; + int i, j; smp_boot_cpus(); /* * Create the slave init tasks as sharing pid 0. + * + * This should only happen if we have virtual CPU numbers + * higher than 0. */ - for (i=0; i 0) - { - /* - * We use kernel_thread for the idlers which are - * unlocked tasks running in kernel space. - */ - kernel_thread(cpu_idle, NULL, CLONE_PID); - /* - * Don't assume linear processor numbering - */ - current_set[i]=task[cpu_number_map[i]]; - current_set[i]->processor=i; - } + kernel_thread(cpu_idle, NULL, CLONE_PID); + /* + * Don't assume linear processor numbering + */ + current_set[j]=task[i]; + current_set[j]->processor=j; } } diff --git a/kernel/exit.c b/kernel/exit.c index 01c085766b77..2b8e6d13ba1f 100644 --- a/kernel/exit.c +++ b/kernel/exit.c @@ -49,7 +49,9 @@ int send_sig(unsigned long sig,struct task_struct * p,int priv) if (!p || sig > 32) return -EINVAL; if (!priv && ((sig != SIGCONT) || (current->session != p->session)) && - (current->euid != p->euid) && (current->euid != p->uid) && !suser()) + (current->euid ^ p->euid) && (current->euid ^ p->uid) && + (current->uid ^ p->euid) && (current->uid ^ p->uid) && + !suser()) return -EPERM; if (!sig) return 0; diff --git a/kernel/fork.c b/kernel/fork.c index e02b6b7fb136..16ed1d1a1b68 100644 --- a/kernel/fork.c +++ b/kernel/fork.c @@ -227,7 +227,7 @@ int do_fork(unsigned long clone_flags, unsigned long usp, struct pt_regs *regs) p->kernel_stack_page = new_stack; *(unsigned long *) p->kernel_stack_page = STACK_MAGIC; p->state = TASK_UNINTERRUPTIBLE; - p->flags &= ~(PF_PTRACED|PF_TRACESYS|PF_SUPERPREV); + p->flags &= ~(PF_PTRACED|PF_TRACESYS|PF_SUPERPRIV); p->flags |= PF_FORKNOEXEC; p->pid = get_pid(clone_flags); p->next_run = NULL; diff --git a/kernel/ksyms.c b/kernel/ksyms.c index e4c80aad2d68..29c7883648d8 100644 --- a/kernel/ksyms.c +++ b/kernel/ksyms.c @@ -48,32 +48,6 @@ extern unsigned char aux_device_present, kbd_read_mask; -#ifdef CONFIG_NET -#include -#include -#include -#include -#include - -#ifdef CONFIG_AX25 -#include -#endif -#ifdef CONFIG_INET -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#endif -#ifdef CONFIG_NET_ALIAS -#include -#endif -#endif #ifdef CONFIG_PCI #include #include @@ -96,17 +70,9 @@ extern void blkdev_release(struct inode * inode); extern void *sys_call_table; -#if defined(CONFIG_ULTRA) || defined(CONFIG_WD80x3) || \ - defined(CONFIG_EL2) || defined(CONFIG_NE2000) || \ - defined(CONFIG_E2100) || defined(CONFIG_HPLAN_PLUS) || \ - defined(CONFIG_HPLAN) || defined(CONFIG_AC3200) -#include "../drivers/net/8390.h" -#endif - extern int sys_tz; extern int request_dma(unsigned int dmanr, char * deviceID); extern void free_dma(unsigned int dmanr); -extern int (*rarp_ioctl_hook)(int,void*); struct symbol_table symbol_table = { #include @@ -251,6 +217,7 @@ struct symbol_table symbol_table = { X(unregister_binfmt), X(search_binary_handler), X(prepare_binprm), + X(remove_arg_zero), /* execution environment registration */ X(lookup_exec_domain), @@ -339,94 +306,7 @@ struct symbol_table symbol_table = { /* Miscellaneous access points */ X(si_meminfo), -#ifdef CONFIG_NET - /* Socket layer registration */ - X(sock_register), - X(sock_unregister), - /* Socket layer support routines */ - X(skb_recv_datagram), - X(skb_free_datagram), - X(skb_copy_datagram), - X(skb_copy_datagram_iovec), - X(datagram_select), -#ifdef CONFIG_FIREWALL - /* Firewall registration */ - X(register_firewall), - X(unregister_firewall), -#endif -#ifdef CONFIG_INET - /* Internet layer registration */ - X(inet_add_protocol), - X(inet_del_protocol), - X(rarp_ioctl_hook), - X(init_etherdev), - X(ip_rt_route), - X(icmp_send), - X(ip_options_compile), - X(ip_rt_put), - X(arp_send), -#ifdef CONFIG_IP_FORWARD - X(ip_forward), -#endif -#if defined(CONFIG_ULTRA) || defined(CONFIG_WD80x3) || \ - defined(CONFIG_EL2) || defined(CONFIG_NE2000) || \ - defined(CONFIG_E2100) || defined(CONFIG_HPLAN_PLUS) || \ - defined(CONFIG_HPLAN) || defined(CONFIG_AC3200) - /* If 8390 NIC support is built in, we will need these. */ - X(ei_open), - X(ei_close), - X(ei_debug), - X(ei_interrupt), - X(ethdev_init), - X(NS8390_init), -#endif -#ifdef CONFIG_NET_ALIAS -#include -#endif -#endif - /* Device callback registration */ - X(register_netdevice_notifier), - X(unregister_netdevice_notifier), -#ifdef CONFIG_NET_ALIAS - X(register_net_alias_type), - X(unregister_net_alias_type), -#endif -#endif - /* support for loadable net drivers */ -#ifdef CONFIG_AX25 - X(ax25_encapsulate), - X(ax25_rebuild_header), -#endif -#ifdef CONFIG_INET - X(register_netdev), - X(unregister_netdev), - X(ether_setup), - X(eth_type_trans), - X(eth_copy_and_sum), - X(alloc_skb), - X(kfree_skb), - X(skb_clone), - X(dev_alloc_skb), - X(dev_kfree_skb), - X(netif_rx), - X(dev_tint), - X(irq2dev_map), - X(dev_add_pack), - X(dev_remove_pack), - X(dev_get), - X(dev_ioctl), - X(dev_queue_xmit), - X(dev_base), - X(dev_close), - X(arp_find), - X(n_tty_ioctl), - X(tty_register_ldisc), - X(kill_fasync), -#ifdef CONFIG_FIREWALL - X(call_in_firewall), -#endif -#endif #ifndef CONFIG_SCSI /* * With no scsi configured, we still need to export a few diff --git a/kernel/module.c b/kernel/module.c index 992b2d23e2c2..e9f6eeff2703 100644 --- a/kernel/module.c +++ b/kernel/module.c @@ -38,7 +38,7 @@ * * On 1-Aug-95: altered code to use same style as * do /proc/net/XXX "files". Namely allow more than 4kB - * (or what the block size if) output. + * (or what the block size is) output. * * - Use dummy syscall functions for users who disable all * module support. Similar to kernel/sys.c (Paul Gortmaker) diff --git a/kernel/sched.c b/kernel/sched.c index 932affd97ce2..0a2e656a1a0f 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -7,7 +7,7 @@ /* * 'sched.c' is the main kernel file. It contains scheduling primitives * (sleep_on, wakeup, schedule etc) as well as a number of simple system - * call functions (type getpid(), which just extracts a field from + * call functions (type getpid()), which just extract a field from * current-task */ @@ -136,13 +136,11 @@ static inline void add_to_runqueue(struct task_struct * p) if ((0!=p->pid) && smp_threads_ready) { int i; - for (i=0;i<=smp_top_cpu;i++) + for (i=0;ipid) + if (0==current_set[cpu_logical_map[i]]->pid) { - smp_message_pass(i, MSG_RESCHEDULE, 0L, 0); + smp_message_pass(cpu_logical_map[i], MSG_RESCHEDULE, 0L, 0); break; } } @@ -929,14 +927,13 @@ static void update_process_times(unsigned long ticks, unsigned long system) update_one_process(p, ticks, ticks-system, system); } #else - int cpu,i; + int cpu,j; cpu = smp_processor_id(); - for (i=0;i<=smp_top_cpu;i++) + for (j=0;j #include #include -#include #include #include @@ -297,12 +296,12 @@ int acct_process(long exitcode) ac.ac_etime = CURRENT_TIME - ac.ac_btime; ac.ac_uid = current->uid; ac.ac_gid = current->gid; - ac.ac_tty = (current)->tty == NULL ? -1 : - makedev (4, current->tty->device); + ac.ac_tty = (current)->tty == NULL ? -1 : + MKDEV(4, current->tty->device); ac.ac_flag = 0; if (current->flags & PF_FORKNOEXEC) ac.ac_flag |= AFORK; - if (current->flags & PF_SUPERPREV) + if (current->flags & PF_SUPERPRIV) ac.ac_flag |= ASU; if (current->flags & PF_DUMPCORE) ac.ac_flag |= ACORE; diff --git a/mm/Makefile b/mm/Makefile index 60c2659d1701..19552c98fd5c 100644 --- a/mm/Makefile +++ b/mm/Makefile @@ -8,7 +8,7 @@ # Note 2! The CFLAGS definition is now in the main makefile... O_TARGET := mm.o -O_OBJS := memory.o mmap.o filemap.o mprotect.o mlock.o \ +O_OBJS := memory.o mmap.o filemap.o mprotect.o mlock.o mremap.o \ kmalloc.o vmalloc.o \ swap.o vmscan.o page_io.o page_alloc.o swap_state.o swapfile.o diff --git a/mm/memory.c b/mm/memory.c index 82965a7ff6be..e561177b977f 100644 --- a/mm/memory.c +++ b/mm/memory.c @@ -734,16 +734,23 @@ bad_area: return -EFAULT; } -static inline void get_empty_page(struct task_struct * tsk, struct vm_area_struct * vma, pte_t * page_table) +static inline void get_empty_page(struct task_struct * tsk, struct vm_area_struct * vma, + pte_t * page_table, int write_access) { - unsigned long tmp; + pte_t pte; - if (!(tmp = get_free_page(GFP_KERNEL))) { - oom(tsk); - put_page(page_table, BAD_PAGE); - return; + pte = pte_wrprotect(mk_pte(ZERO_PAGE, vma->vm_page_prot)); + if (write_access) { + unsigned long page = get_free_page(GFP_KERNEL); + pte = pte_mkwrite(mk_pte(page, vma->vm_page_prot)); + vma->vm_mm->rss++; + tsk->min_flt++; + if (!page) { + oom(tsk); + pte = BAD_PAGE; + } } - put_page(page_table, pte_mkwrite(mk_pte(tmp, vma->vm_page_prot))); + put_page(page_table, pte); } /* @@ -894,9 +901,7 @@ void do_no_page(struct task_struct * tsk, struct vm_area_struct * vma, } address &= PAGE_MASK; if (!vma->vm_ops || !vma->vm_ops->nopage) { - ++vma->vm_mm->rss; - ++tsk->min_flt; - get_empty_page(tsk, vma, page_table); + get_empty_page(tsk, vma, page_table, write_access); return; } ++tsk->maj_flt; diff --git a/mm/mmap.c b/mm/mmap.c index af307e5ba3a9..e350aa3dea33 100644 --- a/mm/mmap.c +++ b/mm/mmap.c @@ -17,17 +17,6 @@ #include #include -/* - * Map memory not associated with any file into a process - * address space. Adjacent memory is merged. - */ -static inline int anon_map(struct inode *ino, struct file * file, struct vm_area_struct * vma) -{ - if (zeromap_page_range(vma->vm_start, vma->vm_end - vma->vm_start, vma->vm_page_prot)) - return -ENOMEM; - return 0; -} - /* * description of effects of mapping type and prot in current implementation. * this is due to the limited x86 page protection hardware. The expected @@ -53,7 +42,6 @@ pgprot_t protection_map[16] = { unsigned long do_mmap(struct file * file, unsigned long addr, unsigned long len, unsigned long prot, unsigned long flags, unsigned long off) { - int error; struct vm_area_struct * vma; if ((len = PAGE_ALIGN(len)) == 0) @@ -165,15 +153,15 @@ unsigned long do_mmap(struct file * file, unsigned long addr, unsigned long len, do_munmap(addr, len); /* Clear old maps */ - if (file) - error = file->f_op->mmap(file->f_inode, file, vma); - else - error = anon_map(NULL, NULL, vma); + if (file) { + int error = file->f_op->mmap(file->f_inode, file, vma); - if (error) { - kfree(vma); - return error; + if (error) { + kfree(vma); + return error; + } } + flags = vma->vm_flags; insert_vm_struct(current, vma); merge_segments(current, vma->vm_start, vma->vm_end); diff --git a/mm/mremap.c b/mm/mremap.c new file mode 100644 index 000000000000..70d91bd79dbb --- /dev/null +++ b/mm/mremap.c @@ -0,0 +1,219 @@ +/* + * linux/mm/remap.c + * + * (C) Copyright 1996 Linus Torvalds + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +static inline pte_t *get_one_pte(struct mm_struct *mm, unsigned long addr) +{ + pgd_t * pgd; + pmd_t * pmd; + pte_t * pte = NULL; + + pgd = pgd_offset(mm, addr); + if (pgd_none(*pgd)) + goto end; + if (pgd_bad(*pgd)) { + printk("move_one_page: bad source pgd (%08lx)\n", pgd_val(*pgd)); + pgd_clear(pgd); + goto end; + } + + pmd = pmd_offset(pgd, addr); + if (pmd_none(*pmd)) + goto end; + if (pmd_bad(*pmd)) { + printk("move_one_page: bad source pmd (%08lx)\n", pmd_val(*pmd)); + pmd_clear(pmd); + goto end; + } + + pte = pte_offset(pmd, addr); + if (pte_none(*pte)) + pte = NULL; +end: + return pte; +} + +static inline pte_t *alloc_one_pte(struct mm_struct *mm, unsigned long addr) +{ + pmd_t * pmd; + pte_t * pte = NULL; + + pmd = pmd_alloc(pgd_offset(mm, addr), addr); + if (pmd) + pte = pte_alloc(pmd, addr); + return pte; +} + +static inline int copy_one_pte(pte_t * src, pte_t * dst) +{ + int error = 0; + pte_t pte = *src; + + if (!pte_none(pte)) { + error++; + if (dst) { + pte_clear(src); + set_pte(dst, pte); + error--; + } + } + return error; +} + +static int move_one_page(struct mm_struct *mm, unsigned long old_addr, unsigned long new_addr) +{ + int error = 0; + pte_t * src; + + src = get_one_pte(mm, old_addr); + if (src) + error = copy_one_pte(src, alloc_one_pte(mm, new_addr)); + return error; +} + +static int move_page_tables(struct mm_struct * mm, + unsigned long new_addr, unsigned long old_addr, unsigned long len) +{ + unsigned long offset = len; + + invalidate_range(mm, old_addr, old_addr + len); + + /* + * This is not the clever way to do this, but we're taking the + * easy way out on the assumption that most remappings will be + * only a few pages.. This also makes error recovery easier. + */ + while (offset) { + offset -= PAGE_SIZE; + if (move_one_page(mm, old_addr + offset, new_addr + offset)) + goto oops_we_failed; + } + return 0; + + /* + * Ok, the move failed because we didn't have enough pages for + * the new page table tree. This is unlikely, but we have to + * take the possibility into account. In that case we just move + * all the pages back (this will work, because we still have + * the old page tables) + */ +oops_we_failed: + while ((offset += PAGE_SIZE) < len) + move_one_page(mm, new_addr + offset, old_addr + offset); + invalidate_range(mm, new_addr, new_addr + len); + zap_page_range(mm, new_addr, new_addr + len); + return -1; +} + +static inline unsigned long move_vma(struct vm_area_struct * vma, + unsigned long addr, unsigned long old_len, unsigned long new_len) +{ + struct vm_area_struct * new_vma; + + new_vma = (struct vm_area_struct *) + kmalloc(sizeof(struct vm_area_struct), GFP_KERNEL); + if (new_vma) { + unsigned long new_addr = get_unmapped_area(addr, new_len); + + if (new_addr && !move_page_tables(current->mm, new_addr, addr, old_len)) { + *new_vma = *vma; + new_vma->vm_start = new_addr; + new_vma->vm_end = new_addr+new_len; + new_vma->vm_offset = vma->vm_offset + (addr - vma->vm_start); + if (new_vma->vm_inode) + new_vma->vm_inode->i_count++; + if (new_vma->vm_ops && new_vma->vm_ops->open) + new_vma->vm_ops->open(new_vma); + insert_vm_struct(current, new_vma); + merge_segments(current, new_vma->vm_start, new_vma->vm_end); + do_munmap(addr, old_len); + return new_addr; + } + kfree(new_vma); + } + return -ENOMEM; +} + +/* + * Expand (or shrink) an existing mapping, potentially moving it at the + * same time (controlled by the "may_move" flag and available VM space) + */ +asmlinkage unsigned long sys_mremap(unsigned long addr, + unsigned long old_len, unsigned long new_len, + int may_move) +{ + struct vm_area_struct *vma; + + if (addr & ~PAGE_MASK) + return -EINVAL; + old_len = PAGE_ALIGN(old_len); + new_len = PAGE_ALIGN(new_len); + if (old_len == new_len) + return addr; + + /* + * Always allow a shrinking remap: that just unmaps + * the unnecessary pages.. + */ + if (old_len > new_len) { + do_munmap(addr+new_len, old_len - new_len); + return addr; + } + + /* + * Ok, we need to grow.. + */ + vma = find_vma(current, addr); + if (!vma || vma->vm_start > addr) + return -EFAULT; + /* We can't remap across vm area boundaries */ + if (old_len > vma->vm_end - addr) + return -EFAULT; + if (vma->vm_flags & VM_LOCKED) { + unsigned long locked = current->mm->locked_vm << PAGE_SHIFT; + locked += new_len - old_len; + if (locked > current->rlim[RLIMIT_MEMLOCK].rlim_cur) + return -EAGAIN; + } + + /* old_len exactly to the end of the area.. */ + if (old_len == vma->vm_end - addr) { + unsigned long max_addr = TASK_SIZE; + if (vma->vm_next) + max_addr = vma->vm_next->vm_start; + /* can we just expand the current mapping? */ + if (max_addr - addr >= new_len) { + int pages = (new_len - old_len) >> PAGE_SHIFT; + vma->vm_end = addr + new_len; + current->mm->total_vm += pages; + if (vma->vm_flags & VM_LOCKED) + current->mm->locked_vm += pages; + return addr; + } + } + + /* + * We weren't able to just expand or shrink the area, + * we need to create a new one and move it.. + */ + if (!may_move) + return -ENOMEM; + return move_vma(vma, addr, old_len, new_len); +} diff --git a/net/802/Makefile b/net/802/Makefile index ad6590d282c2..550ac3826623 100644 --- a/net/802/Makefile +++ b/net/802/Makefile @@ -15,12 +15,12 @@ O_OBJS += tr.o endif ifdef CONFIG_IPX -O_OBJS += p8022.o psnap.o +OX_OBJS += p8022.o psnap.o endif ifdef CONFIG_ATALK ifndef CONFIG_IPX -O_OBJS += p8022.o psnap.o +OX_OBJS += p8022.o psnap.o endif endif diff --git a/net/802/p8022.c b/net/802/p8022.c index 198591eee282..f8754e5c0650 100644 --- a/net/802/p8022.c +++ b/net/802/p8022.c @@ -1,8 +1,10 @@ +#include #include #include #include #include #include +#include static struct datalink_proto *p8022_list = NULL; @@ -65,12 +67,20 @@ static struct packet_type p8022_packet_type = NULL, NULL, }; + +static struct symbol_table p8022_proto_syms = { +#include + X(register_8022_client), + X(unregister_8022_client), +#include +}; void p8022_proto_init(struct net_proto *pro) { p8022_packet_type.type=htons(ETH_P_802_2); dev_add_pack(&p8022_packet_type); + register_symtab(&p8022_proto_syms); } struct datalink_proto * @@ -96,3 +106,24 @@ register_8022_client(unsigned char type, int (*rcvfunc)(struct sk_buff *, struct return proto; } +void unregister_8022_client(unsigned char type) +{ + struct datalink_proto *tmp, **clients = &p8022_list; + unsigned long flags; + + save_flags(flags); + cli(); + + while ((tmp = *clients) != NULL) + { + if (tmp->type[0] == type) { + *clients = tmp->next; + kfree_s(tmp, sizeof(struct datalink_proto)); + break; + } else { + clients = &tmp->next; + } + } + + restore_flags(flags); +} diff --git a/net/802/p8023.c b/net/802/p8023.c index 4015fb7e49e0..57bd6a74a10a 100644 --- a/net/802/p8023.c +++ b/net/802/p8023.c @@ -29,3 +29,9 @@ make_8023_client(void) return proto; } +void destroy_8023_client(struct datalink_proto *dl) +{ + if (dl) + kfree_s(dl,sizeof(struct datalink_proto)); +} + diff --git a/net/802/psnap.c b/net/802/psnap.c index 619c05c94333..4f17352ab586 100644 --- a/net/802/psnap.c +++ b/net/802/psnap.c @@ -10,6 +10,7 @@ * 2 of the License, or (at your option) any later version. */ +#include #include #include #include @@ -81,12 +82,20 @@ static void snap_datalink_header(struct datalink_proto *dl, struct sk_buff *skb, /* * Set up the SNAP layer */ + +static struct symbol_table snap_proto_syms = { +#include + X(register_snap_client), + X(unregister_snap_client), +#include +}; void snap_proto_init(struct net_proto *pro) { snap_dl=register_8022_client(0xAA, snap_rcv); if(snap_dl==NULL) printk("SNAP - unable to register with 802.2\n"); + register_symtab(&snap_proto_syms); } /* @@ -116,3 +125,31 @@ struct datalink_proto *register_snap_client(unsigned char *desc, int (*rcvfunc)( return proto; } +/* + * Unregister SNAP clients. Protocols no longer want to play with us ... + */ + +void unregister_snap_client(unsigned char *desc) +{ + struct datalink_proto **clients = &snap_list; + struct datalink_proto *tmp; + unsigned long flags; + + save_flags(flags); + cli(); + + while ((tmp = *clients) != NULL) + { + if (memcmp(tmp->type,desc,5) == 0) + { + *clients = tmp->next; + kfree_s(tmp, sizeof(struct datalink_proto)); + break; + } + else + clients = &tmp->next; + } + + restore_flags(flags); +} + diff --git a/net/Config.in b/net/Config.in index 4dc4f28be7ce..ae21864c095a 100644 --- a/net/Config.in +++ b/net/Config.in @@ -10,11 +10,11 @@ if [ "$CONFIG_INET" = "y" ]; then source net/ipv4/Config.in fi comment ' ' -bool 'The IPX protocol' CONFIG_IPX -if [ "$CONFIG_IPX" = "y" ]; then +tristate 'The IPX protocol' CONFIG_IPX +if [ ! "$CONFIG_IPX" = "n" ]; then bool 'Full internal IPX network' CONFIG_IPX_INTERN fi -bool 'Appletalk DDP' CONFIG_ATALK +tristate 'Appletalk DDP' CONFIG_ATALK bool 'Amateur Radio AX.25 Level 2' CONFIG_AX25 if [ "$CONFIG_AX25" = "y" ]; then bool 'AX.25 over Ethernet' CONFIG_BPQETHER diff --git a/net/Makefile b/net/Makefile index e971b0525d12..5cca88018813 100644 --- a/net/Makefile +++ b/net/Makefile @@ -10,6 +10,7 @@ MOD_SUB_DIRS := ipv4 ALL_SUB_DIRS := 802 ax25 core ethernet ipv4 ipx unix appletalk netrom SUB_DIRS := 802 core ethernet unix +MOD_LIST_NAME := NET_MISC_MODULES ifeq ($(CONFIG_INET),y) SUB_DIRS += ipv4 @@ -17,10 +18,18 @@ endif ifeq ($(CONFIG_IPX),y) SUB_DIRS += ipx +else + ifeq ($(CONFIG_IPX),m) + MOD_SUB_DIRS += ipx + endif endif ifeq ($(CONFIG_ATALK),y) SUB_DIRS += appletalk +else + ifeq ($(CONFIG_ATALK),m) + MOD_SUB_DIRS += appletalk + endif endif ifeq ($(CONFIG_NETROM),y) @@ -33,6 +42,10 @@ endif L_TARGET := network.a L_OBJS := socket.o protocols.o $(join $(SUB_DIRS),$(SUB_DIRS:%=/%.o)) +ifeq ($(CONFIG_MODULES),y) +LX_OBJS = netsyms.o +endif + M_OBJS := ifeq ($(CONFIG_NETLINK),y) diff --git a/net/appletalk/Makefile b/net/appletalk/Makefile index 8bfe8f721ee0..3980cd9e4cb5 100644 --- a/net/appletalk/Makefile +++ b/net/appletalk/Makefile @@ -9,6 +9,7 @@ O_TARGET := appletalk.o O_OBJS := aarp.o ddp.o +M_OBJS := $(O_TARGET) include $(TOPDIR)/Rules.make diff --git a/net/appletalk/aarp.c b/net/appletalk/aarp.c index ce7acc2b4c39..bd138e0859e7 100644 --- a/net/appletalk/aarp.c +++ b/net/appletalk/aarp.c @@ -26,7 +26,6 @@ #include #include #include -#include #include #include #include @@ -38,18 +37,17 @@ #include #include #include -#include #include #include #include #include +#include #include #include #include #include #include -#ifdef CONFIG_ATALK /* * Lists of aarp entries */ @@ -790,10 +788,11 @@ static struct notifier_block aarp_notifier={ 0 }; +static char aarp_snap_id[]={0x00,0x00,0x00,0x80,0xF3}; + void aarp_proto_init(void) { - static char aarp_snap_id[]={0x00,0x00,0x00,0x80,0xF3}; if((aarp_dl=register_snap_client(aarp_snap_id, aarp_rcv))==NULL) printk("Unable to register AARP with SNAP.\n"); init_timer(&aarp_timer); @@ -803,4 +802,43 @@ void aarp_proto_init(void) add_timer(&aarp_timer); register_netdevice_notifier(&aarp_notifier); } -#endif + + +#ifdef MODULE + +/* Free all the entries in an aarp list. Caller should turn off interrupts. */ +static void free_entry_list(struct aarp_entry *list) +{ + struct aarp_entry *tmp; + + while (list != NULL) + { + tmp = list->next; + aarp_expire(list); + list = tmp; + } +} + +/* General module cleanup. Called from cleanup_module() in ddp.c. */ +void aarp_cleanup_module(void) +{ + unsigned long flags; + int i; + + save_flags(flags); + cli(); + + del_timer(&aarp_timer); + unregister_netdevice_notifier(&aarp_notifier); + unregister_snap_client(aarp_snap_id); + + for (i = 0; i < AARP_HASH_SIZE; i++) + { + free_entry_list(resolved[i]); + free_entry_list(unresolved[i]); + } + + restore_flags(flags); +} + +#endif /* MODULE */ diff --git a/net/appletalk/ddp.c b/net/appletalk/ddp.c index 29b72bb79939..de582793f97e 100644 --- a/net/appletalk/ddp.c +++ b/net/appletalk/ddp.c @@ -20,6 +20,9 @@ * Alan Cox : Supports new ARPHRD_LOOPBACK * Christer Weinigel : Routing and /proc fixes. * Bradford Johnson : Locatalk. + * Tom Dyas : Module support. + * Alan Cox : Hooks for PPP (based on the + * localtalk hook). * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -30,10 +33,11 @@ * ASYNC I/O */ +#include +#include #include #include #include -#include #include #include #include @@ -45,12 +49,12 @@ #include #include #include -#include #include #include #include #include #include +#include #include #include /* For TIOCOUTQ/INQ */ #include @@ -62,7 +66,6 @@ #include #include -#ifdef CONFIG_ATALK #undef APPLETALK_DEBUG @@ -214,7 +217,10 @@ static void atalk_destroy_socket(atalk_socket *sk) } if(sk->wmem_alloc == 0 && sk->rmem_alloc == 0 && sk->dead) + { kfree_s(sk,sizeof(*sk)); + MOD_DEC_USE_COUNT; + } else { /* @@ -256,7 +262,7 @@ int atalk_get_info(char *buffer, char **start, off_t offset, int length, int dum ntohs(s->protinfo.af_at.dest_net), s->protinfo.af_at.dest_node, s->protinfo.af_at.dest_port); - len += sprintf (buffer+len,"%08lX:%08lX ", s->wmem_alloc, s->rmem_alloc); + len += sprintf (buffer+len,"%08X:%08X ", s->wmem_alloc, s->rmem_alloc); len += sprintf (buffer+len,"%02X %d\n", s->state, SOCK_INODE(s->socket)->i_uid); /* Are we still dumping unwanted data then discard the record */ @@ -359,8 +365,8 @@ static int atif_probe_device(struct atalk_iface *atif) * now for the 1.4 release as is. * */ - if(atif->dev->type == ARPHRD_LOCALTLK && - atif->dev->do_ioctl) + if((atif->dev->type == ARPHRD_LOCALTLK || atif->dev->type == ARPHRD_PPP) + && atif->dev->do_ioctl) { /* fake up the request and pass it down */ sa = (struct sockaddr_at*)&atreq.ifr_addr; @@ -753,7 +759,7 @@ int atif_ioctl(int cmd, void *arg) if(sa->sat_family!=AF_APPLETALK) return -EINVAL; if(dev->type!=ARPHRD_ETHER&&dev->type!=ARPHRD_LOOPBACK - &&dev->type!=ARPHRD_LOCALTLK) + &&dev->type!=ARPHRD_LOCALTLK && dev->type!=ARPHRD_PPP) return -EPROTONOSUPPORT; nr=(struct netrange *)&sa->sat_zero[0]; /* @@ -1133,6 +1139,9 @@ static int atalk_create(struct socket *sock, int protocol) kfree_s((void *)sk,sizeof(*sk)); return(-ESOCKTNOSUPPORT); } + + MOD_INC_USE_COUNT; + sk->dead=0; sk->next=NULL; sk->broadcast=0; @@ -1400,7 +1409,8 @@ static int atalk_getname(struct socket *sock, struct sockaddr *uaddr, /* * Receive a packet (in skb) from device dev. This has come from the SNAP decoder, and on entry * skb->h.raw is the DDP header, skb->len is the DDP length. The physical headers have been - * extracted. + * extracted. PPP should probably pass frames marked as for this layer + * [ie ARPHRD_ETHERTALK] */ static int atalk_rcv(struct sk_buff *skb, struct device *dev, struct packet_type *pt) @@ -2005,11 +2015,22 @@ struct packet_type ltalk_packet_type= NULL }; +struct packet_type ppptalk_packet_type= +{ + 0, + NULL, + atalk_rcv, + NULL, + NULL +}; + +static char ddp_snap_id[]={0x08,0x00,0x07,0x80,0x9B}; + + /* Called by proto.c on kernel start up */ void atalk_proto_init(struct net_proto *pro) { - static char ddp_snap_id[]={0x08,0x00,0x07,0x80,0x9B}; (void) sock_register(atalk_proto_ops.family, &atalk_proto_ops); if ((ddp_dl = register_snap_client(ddp_snap_id, atalk_rcv)) == NULL) printk("Unable to register DDP with SNAP.\n"); @@ -2017,6 +2038,9 @@ void atalk_proto_init(struct net_proto *pro) ltalk_packet_type.type=htons(ETH_P_LOCALTALK); dev_add_pack(<alk_packet_type); + ppptalk_packet_type.type=htons(ETH_P_PPPTALK); + dev_add_pack(&ppptalk_packet_type); + register_netdevice_notifier(&ddp_notifier); aarp_proto_init(); @@ -2039,6 +2063,71 @@ void atalk_proto_init(struct net_proto *pro) atalk_if_get_info }); - printk("Appletalk 0.16 for Linux NET3.033\n"); + printk("Appletalk 0.17 for Linux NET3.034\n"); } -#endif + +#ifdef MODULE + +int init_module(void) +{ + atalk_proto_init(NULL); + register_symtab(0); + return 0; +} + +/* + * FIX THIS: If there are any routes/devices configured + * for appletalk we must not be unloaded. + */ + +/* Remove all route entries. Interrupts must be off. */ +extern inline void free_route_list(void) +{ + struct atalk_route *list = atalk_router_list, *tmp; + + while (list != NULL) + { + tmp = list->next; + kfree_s(list, sizeof(struct atalk_route)); + list = tmp; + } +} + +/* Remove all interface entries. Interrupts must be off. */ +extern inline void free_interface_list(void) +{ + struct atalk_iface *list = atalk_iface_list, *tmp; + + while (list != NULL) + { + tmp = list->next; + kfree_s(list, sizeof(struct atalk_iface)); + list = tmp; + } +} + +void cleanup_module(void) +{ + unsigned long flags; + + save_flags(flags); + cli(); + + aarp_cleanup_module(); + + proc_net_unregister(PROC_NET_ATALK); + proc_net_unregister(PROC_NET_AT_ROUTE); + proc_net_unregister(PROC_NET_ATIF); + unregister_netdevice_notifier(&ddp_notifier); + dev_remove_pack(<alk_packet_type); + dev_remove_pack(&ppptalk_packet_type); + unregister_snap_client(ddp_snap_id); + sock_unregister(atalk_proto_ops.family); + + free_route_list(); + free_interface_list(); + + restore_flags(flags); +} + +#endif /* MODULE */ diff --git a/net/ax25/af_ax25.c b/net/ax25/af_ax25.c index b38a53d1588b..e000000f5ff4 100644 --- a/net/ax25/af_ax25.c +++ b/net/ax25/af_ax25.c @@ -2310,7 +2310,7 @@ static int ax25_get_info(char *buffer, char **start, off_t offset, int length, i len += sprintf(buffer + len, " %s", ax25->dama_slave? " slave" : " no"); if (ax25->sk != NULL) { - len += sprintf(buffer + len, " %5ld %5ld\n", + len += sprintf(buffer + len, " %5d %5d\n", ax25->sk->wmem_alloc, ax25->sk->rmem_alloc); } else { @@ -2419,7 +2419,7 @@ void ax25_proto_init(struct net_proto *pro) ax25_cs_get_info }); - printk("G4KLX/GW4PTS AX.25 for Linux. Version 0.31 BETA for Linux NET3.032 (Linux 1.3.53)\n"); + printk("G4KLX/GW4PTS AX.25 for Linux. Version 0.32 BETA for Linux NET3.034 (Linux 1.3.77)\n"); #ifdef CONFIG_BPQETHER proc_net_register(&(struct proc_dir_entry) { @@ -2584,7 +2584,7 @@ int ax25_rebuild_header(unsigned char *bp, struct device *dev, unsigned long des * freeing it). */ struct sk_buff *ourskb=skb_clone(skb, GFP_ATOMIC); - dev_kfree_skb(skb, FREE_READ); + dev_kfree_skb(skb, FREE_WRITE); if(ourskb==NULL) return 1; skb_pull(ourskb, AX25_HEADER_LEN - 1); /* Keep PID */ diff --git a/net/core/dev.c b/net/core/dev.c index b91328db9f7f..4c0b1473c67b 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -655,7 +655,6 @@ void net_bh(void) else kfree_skb(skb, FREE_WRITE); - /* * Again, see if we can transmit anything now. * [Ought to take this out judging by tests it slows @@ -1142,8 +1141,14 @@ static int dev_ifsioc(void *arg, unsigned int getset) if(ifr.ifr_mtu<68) return -EINVAL; - dev->mtu = ifr.ifr_mtu; - ret = 0; + + if (dev->change_mtu) + ret = (*dev->change_mtu)(dev, ifr.ifr_mtu); + else + { + dev->mtu = ifr.ifr_mtu; + ret = 0; + } break; case SIOCGIFMEM: /* Get the per device memory space. We can add this but currently @@ -1301,6 +1306,8 @@ extern int lance_init(void); extern int ni65_init(void); extern int pi_init(void); extern int dec21040_init(void); +extern void sdla_setup(void); +extern void dlci_setup(void); int net_dev_init(void) { @@ -1332,6 +1339,12 @@ int net_dev_init(void) #if defined(CONFIG_DEC_ELCP) dec21040_init(); #endif +#if defined(CONFIG_DLCI) + dlci_setup(); +#endif +#if defined(CONFIG_SDLA) + sdla_setup(); +#endif /* * SLHC if present needs attaching so other people see it * even if not opened. diff --git a/net/ethernet/pe2.c b/net/ethernet/pe2.c index 5ed5c841be59..812d35864399 100644 --- a/net/ethernet/pe2.c +++ b/net/ethernet/pe2.c @@ -30,3 +30,8 @@ make_EII_client(void) return proto; } +void destroy_EII_client(struct datalink_proto *dl) +{ + if (dl) + kfree_s(dl, sizeof(struct datalink_proto)); +} diff --git a/net/ipv4/Config.in b/net/ipv4/Config.in index be359c2c4c70..66a64e0fcfe4 100644 --- a/net/ipv4/Config.in +++ b/net/ipv4/Config.in @@ -21,6 +21,9 @@ fi if [ "$CONFIG_NET_ALIAS" = "y" ]; then tristate 'IP: aliasing support' CONFIG_IP_ALIAS fi +if [ "$CONFIG_KERNELD" = "y" ]; then + bool 'IP: ARP daemon support (experimental)' CONFIG_ARPD +fi comment '(it is safe to leave these untouched)' bool 'IP: PC/TCP compatibility mode' CONFIG_INET_PCTCP tristate 'IP: Reverse ARP' CONFIG_INET_RARP diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c index c0ee24fc614b..b14563efe063 100644 --- a/net/ipv4/af_inet.c +++ b/net/ipv4/af_inet.c @@ -1463,7 +1463,7 @@ void inet_proto_init(struct net_proto *pro) int i; - printk("Swansea University Computer Society TCP/IP for NET3.033\n"); + printk("Swansea University Computer Society TCP/IP for NET3.034\n"); /* * Tell SOCKET that we are alive... diff --git a/net/ipv4/arp.c b/net/ipv4/arp.c index 0a6ee986dda2..cbd42960417c 100644 --- a/net/ipv4/arp.c +++ b/net/ipv4/arp.c @@ -18,7 +18,6 @@ * as published by the Free Software Foundation; either version * 2 of the License, or (at your option) any later version. * - * * Fixes: * Alan Cox : Removed the ethernet assumptions in Florian's code * Alan Cox : Fixed some small errors in the ARP logic @@ -53,6 +52,8 @@ * Eckes : ARP ioctl control errors. * Alexey Kuznetsov: Arp free fix. * Manuel Rodriguez: Gratutious ARP. + * Jonathan Layes : Added arpd support through kerneld + * message queue (960314) */ /* RFC1122 Status: @@ -74,12 +75,12 @@ #include #include #include -#include #include #include #include #include #include +#include #include #include #include @@ -101,6 +102,9 @@ #ifdef CONFIG_NET_ALIAS #include #endif +#ifdef CONFIG_ARPD +#include +#endif /* CONFIG_ARPD */ #include #include @@ -189,6 +193,14 @@ static unsigned int arp_bh_mask; static struct arp_table *arp_backlog; +/* If we have arpd configured, assume that we will be running arpd and keep + the internal cache small */ +#ifdef CONFIG_ARPD +#define ARP_MAXSIZE 256 +#endif /* CONFIG_ARPD */ + +static unsigned int arp_size = 0; + static void arp_run_bh(void); static void arp_check_expire (unsigned long); @@ -340,6 +352,7 @@ static void arp_free_entry(struct arp_table *entry) restore_flags(flags); kfree_s(entry, sizeof(struct arp_table)); + --arp_size; return; } @@ -368,6 +381,179 @@ static __inline__ int arp_count_hhs(struct arp_table * entry) return count; } + +/* + * Force the expiry of an entry in the internal cache so the memory + * can be used for a new request or for loading a query from arpd. + * I'm not really sure what the best algorithm should be, so I just + * search for the oldest. NOTE: make sure the cache is locked before + * jumping into this function! If someone wants to do something + * other than searching the whole cache, by all means do so! + */ + +#ifdef CONFIG_ARPD +static int arp_force_expire(void) +{ + int i; + struct arp_table *entry = NULL; + struct arp_table **pentry = NULL; + struct arp_table **oldest_entry = NULL, **last_resort = NULL; + unsigned long oldest_used = ~0; + +#if RT_CACHE_DEBUG >= 2 + printk("Looking for something to force expire.\n"); +#endif + for (i = 0; i < ARP_TABLE_SIZE; i++) + { + pentry = &arp_tables[i]; + + while ((entry = *pentry) != NULL) + { + if (entry->last_used < oldest_used) + { + if (arp_count_hhs(entry) == 0) + { + oldest_entry = pentry; + } + last_resort = pentry; + oldest_used = entry->last_used; + } + pentry = &entry->next; /* go to next entry */ + } + } + if (oldest_entry == NULL) + { + if (last_resort == NULL) + return -1; + oldest_entry = last_resort; + } + + entry = *oldest_entry; + *oldest_entry = (*oldest_entry)->next; +#if RT_CACHE_DEBUG >= 2 + printk("Force expiring %08x\n", entry->ip); +#endif + arp_free_entry(entry); + return 0; +} +#endif /* CONFIG_ARPD */ + + +static void arpd_update(struct arp_table * entry, int loc) +{ +#ifdef CONFIG_ARPD + static struct arpd_request arpreq; + + arpreq.req = ARPD_UPDATE; + arpreq.ip = entry->ip; + arpreq.mask = entry->mask; + memcpy (arpreq.ha, entry->ha, MAX_ADDR_LEN); + arpreq.loc = loc; + arpreq.last_used = entry->last_used; + arpreq.last_updated = entry->last_updated; + arpreq.flags = entry->flags; + arpreq.dev = entry->dev; + + kerneld_send(KERNELD_ARP, 0, sizeof(arpreq), + (char *) &arpreq, NULL); +#endif /* CONFIG_ARPD */ +} + +/* + * Allocate memory for a new entry. If we are at the maximum limit + * of the internal ARP cache, arp_force_expire() an entry. NOTE: + * arp_force_expire() needs the cache to be locked, so therefore + * arp_add_entry() should only be called with the cache locked too! + */ + +static struct arp_table * arp_add_entry(void) +{ + struct arp_table * entry; + +#ifdef CONFIG_ARPD + if (arp_size >= ARP_MAXSIZE) + { + if (arp_force_expire() < 0) + return NULL; + } +#endif /* CONFIG_ARPD */ + + entry = (struct arp_table *) + kmalloc(sizeof(struct arp_table),GFP_ATOMIC); + + if (entry != NULL) + ++arp_size; + return entry; +} + + +/* + * Lookup ARP entry by (addr, dev) pair in the arpd. + */ + +static struct arp_table * arpd_lookup(u32 addr, unsigned short flags, + struct device * dev, + int loc) +{ +#ifdef CONFIG_ARPD + static struct arpd_request arpreq, retreq; + struct arp_table * entry; + int rv, i; + + arpreq.req = ARPD_LOOKUP; + arpreq.ip = addr; + arpreq.loc = loc; + + rv = kerneld_send(KERNELD_ARP, + sizeof(retreq) | KERNELD_WAIT, + sizeof(arpreq), + (char *) &arpreq, + (char *) &retreq); + /* don't worry about rv != 0 too much, it's probably + because arpd isn't running or an entry couldn't + be found */ + + if (rv != 0) + return NULL; + if (dev != retreq.dev) + return NULL; + if (! memcmp (retreq.ha, "\0\0\0\0\0\0", 6)) + return NULL; + + arp_fast_lock(); + entry = arp_add_entry(); + arp_unlock(); + + if (entry == NULL) + return NULL; + + entry->next = NULL; + entry->last_used = retreq.last_used; + entry->last_updated = retreq.last_updated; + entry->flags = retreq.flags; + entry->ip = retreq.ip; + entry->mask = retreq.mask; + memcpy (entry->ha, retreq.ha, MAX_ADDR_LEN); + arpreq.dev = entry->dev; + + skb_queue_head_init(&entry->skb); + entry->hh = NULL; + entry->retries = 0; + +#if RT_CACHE_DEBUG >= 2 + printk("Inserting arpd entry %08x\n in local cache.", entry->ip); +#endif + i = HASH(entry->ip); + arp_fast_lock(); + entry->next = arp_tables[i]->next; + arp_tables[i]->next = entry; + arp_unlock(); + return entry; +#endif /* CONFIG_ARPD */ + return NULL; +} + + /* * Invalidate all hh's, so that higher level will not try to use it. */ @@ -1015,6 +1201,7 @@ gratuitous: if (!(entry->flags & ATF_PERM)) { memcpy(entry->ha, sha, dev->addr_len); entry->last_updated = jiffies; + arpd_update(entry, __LINE__); } if (!(entry->flags & ATF_COM)) { @@ -1042,11 +1229,13 @@ gratuitous: if (grat) goto end; - entry = (struct arp_table *)kmalloc(sizeof(struct arp_table),GFP_ATOMIC); + entry = arp_add_entry(); if(entry == NULL) { arp_unlock(); +#if RT_CACHE_DEBUG >= 2 printk("ARP: no memory for new arp entry\n"); +#endif kfree_skb(skb, FREE_READ); return 0; } @@ -1060,6 +1249,7 @@ gratuitous: entry->timer.data = (unsigned long)entry; memcpy(entry->ha, sha, dev->addr_len); entry->last_updated = entry->last_used = jiffies; + arpd_update(entry, __LINE__); /* * make entry point to 'correct' device */ @@ -1077,7 +1267,7 @@ gratuitous: } else { -#if RT_CACHE_DEBUG >= 1 +#if RT_CACHE_DEBUG >= 2 printk("arp_rcv: %08x backlogged\n", entry->ip); #endif arp_enqueue(&arp_backlog, entry); @@ -1142,6 +1332,8 @@ int arp_query(unsigned char *haddr, u32 paddr, struct device * dev) arp_fast_lock(); entry = arp_lookup(paddr, 0, dev); + if (entry == NULL) + entry = arpd_lookup(paddr, 0, dev, __LINE__); if (entry != NULL) { @@ -1149,10 +1341,12 @@ int arp_query(unsigned char *haddr, u32 paddr, struct device * dev) if (entry->flags & ATF_COM) { memcpy(haddr, entry->ha, dev->addr_len); + arpd_update(entry, __LINE__); arp_unlock(); return 1; } } + arpd_update(entry, __LINE__); arp_unlock(); return 0; } @@ -1218,6 +1412,8 @@ int arp_find(unsigned char *haddr, u32 paddr, struct device *dev, * Find an entry */ entry = arp_lookup(paddr, 0, dev); + if (entry == NULL) + entry = arpd_lookup(paddr, 0, dev, __LINE__); if (entry != NULL) /* It exists */ { @@ -1267,6 +1463,7 @@ int arp_find(unsigned char *haddr, u32 paddr, struct device *dev, entry->last_used = jiffies; memcpy(haddr, entry->ha, dev->addr_len); + arpd_update(entry, __LINE__); if (skb) skb->arp = 1; arp_unlock(); @@ -1277,8 +1474,7 @@ int arp_find(unsigned char *haddr, u32 paddr, struct device *dev, * Create a new unresolved entry. */ - entry = (struct arp_table *) kmalloc(sizeof(struct arp_table), - GFP_ATOMIC); + entry = arp_add_entry(); if (entry != NULL) { entry->last_updated = entry->last_used = jiffies; @@ -1288,6 +1484,7 @@ int arp_find(unsigned char *haddr, u32 paddr, struct device *dev, memset(entry->ha, 0, dev->addr_len); entry->dev = dev; entry->hh = NULL; + arpd_update(entry, __LINE__); init_timer(&entry->timer); entry->timer.function = arp_expire_request; entry->timer.data = (unsigned long)entry; @@ -1307,7 +1504,7 @@ int arp_find(unsigned char *haddr, u32 paddr, struct device *dev, } else { -#if RT_CACHE_DEBUG >= 1 +#if RT_CACHE_DEBUG >= 2 printk("arp_find: %08x backlogged\n", entry->ip); #endif arp_enqueue(&arp_backlog, entry); @@ -1457,6 +1654,8 @@ int arp_bind_cache(struct hh_cache ** hhp, struct device *dev, unsigned short ht arp_fast_lock(); entry = arp_lookup(paddr, 0, dev); + if (entry == NULL) + entry = arpd_lookup(paddr, 0, dev, __LINE__); if (entry) { @@ -1498,6 +1697,7 @@ int arp_bind_cache(struct hh_cache ** hhp, struct device *dev, unsigned short ht hh->hh_refcnt++; restore_flags(flags); entry->last_used = jiffies; + arpd_update(entry, __LINE__); arp_unlock(); return 0; } @@ -1507,8 +1707,7 @@ int arp_bind_cache(struct hh_cache ** hhp, struct device *dev, unsigned short ht * Create a new unresolved entry. */ - entry = (struct arp_table *) kmalloc(sizeof(struct arp_table), - GFP_ATOMIC); + entry = arp_add_entry(); if (entry == NULL) { kfree_s(hh, sizeof(struct hh_cache)); @@ -1523,6 +1722,7 @@ int arp_bind_cache(struct hh_cache ** hhp, struct device *dev, unsigned short ht memset(entry->ha, 0, dev->addr_len); entry->dev = dev; entry->hh = hh; + arpd_update(entry, __LINE__); ATOMIC_INCR(&hh->hh_refcnt); init_timer(&entry->timer); entry->timer.function = arp_expire_request; @@ -1731,6 +1931,8 @@ static int arp_req_set(struct arpreq *r, struct device * dev) */ entry = arp_lookup(ip, r->arp_flags & ~ATF_NETMASK, dev); + if (entry == NULL) + entry = arpd_lookup(ip, r->arp_flags & ~ATF_NETMASK, dev, __LINE__); if (entry) { @@ -1744,8 +1946,7 @@ static int arp_req_set(struct arpreq *r, struct device * dev) if (entry == NULL) { - entry = (struct arp_table *) kmalloc(sizeof(struct arp_table), - GFP_ATOMIC); + entry = arp_add_entry(); if (entry == NULL) { arp_unlock(); @@ -1782,6 +1983,7 @@ static int arp_req_set(struct arpreq *r, struct device * dev) ha = dev->dev_addr; memcpy(entry->ha, ha, dev->addr_len); entry->last_updated = entry->last_used = jiffies; + arpd_update(entry, __LINE__); entry->flags = r->arp_flags | ATF_COM; if ((entry->flags & ATF_PUBL) && (entry->flags & ATF_NETMASK)) { @@ -1816,6 +2018,9 @@ static int arp_req_get(struct arpreq *r, struct device *dev) arp_fast_lock(); entry = arp_lookup(si->sin_addr.s_addr, r->arp_flags|ATF_NETMASK, dev); + if (entry == NULL) + entry = arpd_lookup(si->sin_addr.s_addr, + r->arp_flags|ATF_NETMASK, dev, __LINE__); if (entry == NULL) { diff --git a/net/ipv4/ip_alias.c b/net/ipv4/ip_alias.c index 18339851638d..e9507c99d126 100644 --- a/net/ipv4/ip_alias.c +++ b/net/ipv4/ip_alias.c @@ -38,74 +38,77 @@ #include /* - * AF_INET alias init + * AF_INET alias init */ -static int -ip_alias_init_1(struct net_alias_type *this, struct net_alias *alias, struct sockaddr *sa) + +static int ip_alias_init_1(struct net_alias_type *this, struct net_alias *alias, struct sockaddr *sa) { #ifdef ALIAS_USER_LAND_DEBUG - printk("alias_init(%s) called.\n", alias->name); + printk("alias_init(%s) called.\n", alias->name); #endif - MOD_INC_USE_COUNT; - return 0; + MOD_INC_USE_COUNT; + return 0; } /* - * AF_INET alias done + * AF_INET alias done */ -static int -ip_alias_done_1(struct net_alias_type *this, struct net_alias *alias) + +static int ip_alias_done_1(struct net_alias_type *this, struct net_alias *alias) { #ifdef ALIAS_USER_LAND_DEBUG - printk("alias_done(%s) called.\n", alias->name); + printk("alias_done(%s) called.\n", alias->name); #endif - MOD_DEC_USE_COUNT; - return 0; + MOD_DEC_USE_COUNT; + return 0; } /* - * print alias address info + * Print alias address info */ -int -ip_alias_print_1(struct net_alias_type *this, struct net_alias *alias, char *buf, int len) +int ip_alias_print_1(struct net_alias_type *this, struct net_alias *alias, char *buf, int len) { - char *p; + char *p; - p = (char *) &alias->dev.pa_addr; - return sprintf(buf, "%d.%d.%d.%d", - (p[0] & 255), (p[1] & 255), (p[2] & 255), (p[3] & 255)); + p = (char *) &alias->dev.pa_addr; + return sprintf(buf, "%d.%d.%d.%d", + (p[0] & 255), (p[1] & 255), (p[2] & 255), (p[3] & 255)); } -struct device * -ip_alias_dev_select(struct net_alias_type *this, struct device *main_dev, struct sockaddr *sa) +struct device *ip_alias_dev_select(struct net_alias_type *this, struct device *main_dev, struct sockaddr *sa) { - __u32 addr; - struct rtable *rt; + __u32 addr; + struct rtable *rt; + struct device *dev=NULL; - /* - * defensive... - */ + /* + * Defensive... + */ - if (main_dev == NULL) return NULL; - - /* - * get u32 address. - */ - - addr = (sa)? (*(struct sockaddr_in *)sa).sin_addr.s_addr : 0; - - if (addr == 0) return NULL; - - /* - * find 'closest' device to address given. any other suggestions? ... - * net_alias module will check if returned device is main_dev's alias - */ - - rt = ip_rt_route(addr, 0); - - return (rt)? rt->rt_dev : NULL; - + if (main_dev == NULL) + return NULL; + + /* + * Get u32 address. + */ + + addr = (sa)? (*(struct sockaddr_in *)sa).sin_addr.s_addr : 0; + if (addr == 0) + return NULL; + + /* + * Find 'closest' device to address given. any other suggestions? ... + * net_alias module will check if returned device is main_dev's alias + */ + + rt = ip_rt_route(addr, 0); + if(rt) + { + dev=rt->rt_dev; + ip_rt_put(rt); + } + return dev; } /* @@ -114,16 +117,16 @@ ip_alias_dev_select(struct net_alias_type *this, struct device *main_dev, struct struct net_alias_type ip_alias_type = { - AF_INET, /* type */ - 0, /* n_attach */ - "ip", /* name */ - NULL, /* get_addr32() */ - NULL, /* dev_addr_chk() */ - ip_alias_dev_select, /* dev_select() */ - ip_alias_init_1, /* alias_init_1() */ - ip_alias_done_1, /* alias_done_1() */ - ip_alias_print_1, /* alias_print_1() */ - NULL /* next */ + AF_INET, /* type */ + 0, /* n_attach */ + "ip", /* name */ + NULL, /* get_addr32() */ + NULL, /* dev_addr_chk() */ + ip_alias_dev_select, /* dev_select() */ + ip_alias_init_1, /* alias_init_1() */ + ip_alias_done_1, /* alias_done_1() */ + ip_alias_print_1, /* alias_print_1() */ + NULL /* next */ }; /* @@ -132,7 +135,7 @@ struct net_alias_type ip_alias_type = int ip_alias_init(void) { - return register_net_alias_type(&ip_alias_type, AF_INET); + return register_net_alias_type(&ip_alias_type, AF_INET); } /* @@ -141,22 +144,22 @@ int ip_alias_init(void) int ip_alias_done(void) { - return unregister_net_alias_type(&ip_alias_type); + return unregister_net_alias_type(&ip_alias_type); } #ifdef MODULE int init_module(void) { - if (ip_alias_init() != 0) - return -EIO; - return 0; + if (ip_alias_init() != 0) + return -EIO; + return 0; } void cleanup_module(void) { - if (ip_alias_done() != 0) - printk("ip_alias: can't remove module"); + if (ip_alias_done() != 0) + printk("ip_alias: can't remove module"); } #endif /* MODULE */ diff --git a/net/ipv4/ip_forward.c b/net/ipv4/ip_forward.c index 16afa1c168f7..ab80ea0bc2d5 100644 --- a/net/ipv4/ip_forward.c +++ b/net/ipv4/ip_forward.c @@ -208,9 +208,10 @@ int ip_forward(struct sk_buff *skb, struct device *dev, int is_frag, * we calculated. */ #ifndef CONFIG_IP_NO_ICMP_REDIRECT - if (dev == dev2 && !((iph->saddr^iph->daddr)&dev->pa_mask) && - (rt->rt_flags&RTF_MODIFIED) && !opt->srr) - icmp_send(skb, ICMP_REDIRECT, ICMP_REDIR_HOST, raddr, dev); + if (dev == dev2 && + !((iph->saddr^dev->pa_addr)&dev->pa_mask) && + (rt->rt_flags&RTF_MODIFIED) && !opt->srr) + icmp_send(skb, ICMP_REDIRECT, ICMP_REDIR_HOST, raddr, dev); #endif #ifdef CONFIG_IP_MROUTE } diff --git a/net/ipv4/ip_fragment.c b/net/ipv4/ip_fragment.c index 2797f3abab8e..741c235084a3 100644 --- a/net/ipv4/ip_fragment.c +++ b/net/ipv4/ip_fragment.c @@ -641,7 +641,7 @@ void ip_fragment(struct sock *sk, struct sk_buff *skb, struct device *dev, int i if (ntohs(iph->frag_off) & IP_DF) { ip_statistics.IpFragFails++; - printk("ip_queue_xmit: frag needed\n"); + NETDEBUG(printk("ip_queue_xmit: frag needed\n")); return; } diff --git a/net/ipv4/ip_input.c b/net/ipv4/ip_input.c index 7bb3a71bed43..33516afee24d 100644 --- a/net/ipv4/ip_input.c +++ b/net/ipv4/ip_input.c @@ -260,6 +260,17 @@ int ip_rcv(struct sk_buff *skb, struct device *dev, struct packet_type *pt) skb_trim(skb,ntohs(iph->tot_len)); + /* + * Try to select closest alias device, if any. + * net_alias_dev_rcv_sel32 returns main device if it + * fails to found other. + */ + +#ifdef CONFIG_NET_ALIAS + if (iph->daddr != skb->dev->pa_addr && net_alias_has(skb->dev)) + skb->dev = dev = net_alias_dev_rcv_sel32(skb->dev, AF_INET, iph->saddr, iph->daddr); +#endif + if (iph->ihl > 5) { skb->ip_summed = 0; @@ -275,17 +286,6 @@ int ip_rcv(struct sk_buff *skb, struct device *dev, struct packet_type *pt) #endif } - /* - * Try to select closest alias device, if any. - * net_alias_dev_rcv_sel32 returns main device if it - * fails to found other. - */ - -#ifdef CONFIG_NET_ALIAS - if (iph->daddr != skb->dev->pa_addr && net_alias_has(skb->dev)) - skb->dev = dev = net_alias_dev_rcv_sel32(skb->dev, AF_INET, iph->saddr, iph->daddr); -#endif - /* * Account for the packet (even if the packet is * not accepted by the firewall!). diff --git a/net/ipv4/proc.c b/net/ipv4/proc.c index e0aa0a1a83ea..13e61b24fee4 100644 --- a/net/ipv4/proc.c +++ b/net/ipv4/proc.c @@ -71,7 +71,8 @@ get__netinfo(struct proto *pro, char *buffer, int format, char **start, off_t of off_t begin=0; s_array = pro->sock_array; - len += sprintf(buffer, "sl local_address rem_address st tx_queue rx_queue tr tm->when uid\n"); + len += sprintf(buffer, "sl local_address rem_address st tx_queue " + "rx_queue tr tm->when uid inode\n"); /* * This was very pretty but didn't work when a socket is destroyed * at the wrong moment (eg a syn recv socket getting a reset), or @@ -108,13 +109,16 @@ get__netinfo(struct proto *pro, char *buffer, int format, char **start, off_t of timer_active=timer_active2; timer_expires=sp->timer.expires; } - len += sprintf(buffer+len, "%2d: %08lX:%04X %08lX:%04X %02X %08X:%08X %02X:%08lX %08X %d %d\n", + len += sprintf(buffer+len, "%2d: %08lX:%04X %08lX:%04X" + " %02X %08X:%08X %02X:%08lX %08X %d %d %ld\n", i, src, srcp, dest, destp, sp->state, format==0?sp->write_seq-sp->rcv_ack_seq:sp->wmem_alloc, format==0?sp->acked_seq-sp->copied_seq:sp->rmem_alloc, timer_active, timer_expires-jiffies, (unsigned) sp->retransmits, (sp->socket&&SOCK_INODE(sp->socket))?SOCK_INODE(sp->socket)->i_uid:0, - timer_active?sp->timeout:0); + timer_active?sp->timeout:0, + sp->socket && SOCK_INODE(sp->socket) ? + SOCK_INODE(sp->socket)->i_ino : 0); if (timer_active1) add_timer(&sp->retransmit_timer); if (timer_active2) add_timer(&sp->timer); /* diff --git a/net/ipx/Makefile b/net/ipx/Makefile index 61af728280ad..a63f7d01a3dd 100644 --- a/net/ipx/Makefile +++ b/net/ipx/Makefile @@ -9,6 +9,7 @@ O_TARGET := ipx.o O_OBJS := af_ipx.o +M_OBJS := $(O_TARGET) include $(TOPDIR)/Rules.make diff --git a/net/ipx/af_ipx.c b/net/ipx/af_ipx.c index efffa1821161..1da11e794e3a 100644 --- a/net/ipx/af_ipx.c +++ b/net/ipx/af_ipx.c @@ -41,13 +41,16 @@ * Supports sendmsg/recvmsg * Revision 0.33: Internal network support, routing changes, uses a * protocol private area for ipx data. + * Revision 0.34: Module support. * * Portions Copyright (c) 1995 Caldera, Inc. * Neither Greg Page nor Caldera, Inc. admit liability nor provide * warranty for any of this software. This material is provided * "AS-IS" and at no charge. */ - + +#include + #include #include #include @@ -59,11 +62,10 @@ #include #include #include -#include -#include #include +#include +#include #include -#include #include #include #include @@ -77,7 +79,10 @@ #include #include -#ifdef CONFIG_IPX +#ifdef MODULE +static void ipx_proto_finito(void); +#endif /* def MODULE */ + /* Configuration Variables */ static unsigned char ipxcfg_max_hops = 16; static char ipxcfg_auto_select_primary = 0; @@ -89,10 +94,10 @@ static struct datalink_proto *pEII_datalink = NULL; static struct datalink_proto *p8023_datalink = NULL; static struct datalink_proto *pSNAP_datalink = NULL; -static ipx_interface *ipx_interfaces = NULL; static ipx_route *ipx_routes = NULL; -static ipx_interface *ipx_internal_net = NULL; +static ipx_interface *ipx_interfaces = NULL; static ipx_interface *ipx_primary_net = NULL; +static ipx_interface *ipx_internal_net = NULL; static int ipxcfg_set_auto_create(char val) @@ -187,6 +192,7 @@ ipx_destroy_socket(ipx_socket *sk) } kfree_s(sk,sizeof(*sk)); + MOD_DEC_USE_COUNT; } /* The following code is used to support IPX Interfaces (IPXITF). An @@ -194,7 +200,7 @@ ipx_destroy_socket(ipx_socket *sk) */ static ipx_route * ipxrtr_lookup(unsigned long); - + static void ipxitf_clear_primary_net(void) { @@ -324,6 +330,10 @@ ipxitf_down(ipx_interface *intrfc) ipx_internal_net = NULL; kfree_s(intrfc, sizeof(*intrfc)); + /* sockets still dangling + * - must be closed from user space + */ + return; } static int @@ -790,6 +800,7 @@ ipxitf_insert(ipx_interface *intrfc) if (ipxcfg_auto_select_primary && (ipx_primary_net == NULL)) ipx_primary_net = intrfc; + return; } static int @@ -1155,7 +1166,7 @@ ipxrtr_delete(long net) /* * Route an outgoing frame from a socket. */ - + static int ipxrtr_route_packet(ipx_socket *sk, struct sockaddr_ipx *usipx, struct iovec *iov, int len) { struct sk_buff *skb; @@ -1259,7 +1270,7 @@ ipxrtr_route_skb(struct sk_buff *skb) /* * We use a normal struct rtentry for route handling */ - + static int ipxrtr_ioctl(unsigned int cmd, void *arg) { int err; @@ -1483,7 +1494,7 @@ static int ipx_rt_get_info(char *buffer, char **start, off_t offset, * Handling for system calls applied via the various interfaces to an IPX socket object * * * \*******************************************************************************************************************/ - + static int ipx_fcntl(struct socket *sock, unsigned int cmd, unsigned long arg) { switch(cmd) @@ -1642,6 +1653,7 @@ ipx_create(struct socket *sock, int protocol) sk->error_report=def_callback1; sk->zapped=1; + MOD_INC_USE_COUNT; return 0; } @@ -1830,8 +1842,10 @@ static int ipx_socketpair(struct socket *sock1, struct socket *sock2) static int ipx_accept(struct socket *sock, struct socket *newsock, int flags) { - if(newsock->data) + if(newsock->data) { kfree_s(newsock->data,sizeof(ipx_socket)); + MOD_DEC_USE_COUNT; + } return -EOPNOTSUPP; } @@ -2187,7 +2201,7 @@ static struct packet_type ipx_8023_packet_type = NULL, NULL, }; - + static struct packet_type ipx_dix_packet_type = { 0, /* MUTTER ntohs(ETH_P_IPX),*/ @@ -2196,7 +2210,7 @@ static struct packet_type ipx_dix_packet_type = NULL, NULL, }; - + static struct notifier_block ipx_dev_notifier={ ipxitf_device_event, NULL, @@ -2206,12 +2220,30 @@ static struct notifier_block ipx_dev_notifier={ extern struct datalink_proto *make_EII_client(void); extern struct datalink_proto *make_8023_client(void); +extern void destroy_EII_client(struct datalink_proto *); +extern void destroy_8023_client(struct datalink_proto *); -void ipx_proto_init(struct net_proto *pro) -{ - unsigned char val = 0xE0; - unsigned char snapval[5] = { 0x0, 0x0, 0x0, 0x81, 0x37 }; +struct proc_dir_entry ipx_procinfo = { + PROC_NET_IPX, 3, "ipx", S_IFREG | S_IRUGO, + 1, 0, 0, 0, &proc_net_inode_operations, ipx_get_info +}; +struct proc_dir_entry ipx_if_procinfo = { + PROC_NET_IPX_INTERFACE, 13, "ipx_interface", S_IFREG | S_IRUGO, + 1, 0, 0, 0, &proc_net_inode_operations, ipx_interface_get_info +}; + +struct proc_dir_entry ipx_rt_procinfo = { + PROC_NET_IPX_ROUTE, 9, "ipx_route", S_IFREG | S_IRUGO, + 1, 0, 0, 0, &proc_net_inode_operations, ipx_rt_get_info +}; + +static unsigned char ipx_8022_type = 0xE0; +static unsigned char ipx_snap_id[5] = { 0x0, 0x0, 0x0, 0x81, 0x37 }; + +void +ipx_proto_init(struct net_proto *pro) +{ (void) sock_register(ipx_proto_ops.family, &ipx_proto_ops); pEII_datalink = make_EII_client(); @@ -2222,34 +2254,82 @@ void ipx_proto_init(struct net_proto *pro) ipx_8023_packet_type.type=htons(ETH_P_802_3); dev_add_pack(&ipx_8023_packet_type); - if ((p8022_datalink = register_8022_client(val, ipx_rcv)) == NULL) + if ((p8022_datalink = register_8022_client(ipx_8022_type, ipx_rcv)) == NULL) printk("IPX: Unable to register with 802.2\n"); - if ((pSNAP_datalink = register_snap_client(snapval, ipx_rcv)) == NULL) + if ((pSNAP_datalink = register_snap_client(ipx_snap_id, ipx_rcv)) == NULL) printk("IPX: Unable to register with SNAP\n"); register_netdevice_notifier(&ipx_dev_notifier); - proc_net_register(&(struct proc_dir_entry) { - PROC_NET_IPX, 3, "ipx", - S_IFREG | S_IRUGO, 1, 0, 0, - 0, &proc_net_inode_operations, - ipx_get_info - }); - proc_net_register(&(struct proc_dir_entry) { - PROC_NET_IPX_INTERFACE, 13, "ipx_interface", - S_IFREG | S_IRUGO, 1, 0, 0, - 0, &proc_net_inode_operations, - ipx_interface_get_info - }); - proc_net_register(&(struct proc_dir_entry) { - PROC_NET_IPX_ROUTE, 9, "ipx_route", - S_IFREG | S_IRUGO, 1, 0, 0, - 0, &proc_net_inode_operations, - ipx_rt_get_info - }); + proc_net_register(&ipx_procinfo); + proc_net_register(&ipx_if_procinfo); + proc_net_register(&ipx_rt_procinfo); - printk("Swansea University Computer Society IPX 0.33 for NET3.032\n"); + printk("Swansea University Computer Society IPX 0.34 for NET3.034\n"); printk("IPX Portions Copyright (c) 1995 Caldera, Inc.\n"); } -#endif + +#ifdef MODULE +/* Note on MOD_{INC,DEC}_USE_COUNT: + * + * Use counts are incremented/decremented when + * sockets are created/deleted. + * + * Routes are always associated with an interface, and + * allocs/frees will remain properly accounted for by + * their associated interfaces. + * + * Ergo, before the ipx module can be removed, all IPX + * sockets be closed from user space. + */ + +static void +ipx_proto_finito(void) +{ ipx_interface *ifc; + + while (ipx_interfaces) { + ifc = ipx_interfaces; + ipx_interfaces = ifc->if_next; + ifc->if_next = NULL; + ipxitf_down(ifc); + } + + proc_net_unregister(PROC_NET_IPX_ROUTE); + proc_net_unregister(PROC_NET_IPX_INTERFACE); + proc_net_unregister(PROC_NET_IPX); + + unregister_netdevice_notifier(&ipx_dev_notifier); + + unregister_snap_client(ipx_snap_id); + pSNAP_datalink = NULL; + + unregister_8022_client(ipx_8022_type); + p8022_datalink = NULL; + + dev_remove_pack(&ipx_8023_packet_type); + destroy_8023_client(p8023_datalink); + p8023_datalink = NULL; + + dev_remove_pack(&ipx_dix_packet_type); + destroy_EII_client(pEII_datalink); + pEII_datalink = NULL; + + (void) sock_unregister(ipx_proto_ops.family); + + return; +} + +int init_module(void) +{ + ipx_proto_init(NULL); + register_symtab(0); + return 0; +} + +void cleanup_module(void) +{ + ipx_proto_finito(); + return; +} +#endif /* def MODULE */ diff --git a/net/netrom/af_netrom.c b/net/netrom/af_netrom.c index fc0057a2aa97..d527040f0344 100644 --- a/net/netrom/af_netrom.c +++ b/net/netrom/af_netrom.c @@ -1274,7 +1274,7 @@ static int nr_get_info(char *buffer, char **start, off_t offset, int length, int ax2asc(&s->nr->user_addr)); len += sprintf(buffer + len, "%-9s ", ax2asc(&s->nr->dest_addr)); - len += sprintf(buffer + len, "%-9s %-3s %02X/%02X %02X/%02X %2d %2d %2d %2d %3d/%03d %2d/%02d %2d/%02d %3d %3d %5ld %5ld\n", + len += sprintf(buffer + len, "%-9s %-3s %02X/%02X %02X/%02X %2d %2d %2d %2d %3d/%03d %2d/%02d %2d/%02d %3d %3d %5d %5d\n", ax2asc(&s->nr->source_addr), devname, s->nr->my_index, s->nr->my_id, s->nr->your_index, s->nr->your_id, @@ -1341,7 +1341,7 @@ void nr_proto_init(struct net_proto *pro) { sock_register(nr_proto_ops.family, &nr_proto_ops); register_netdevice_notifier(&nr_dev_notifier); - printk("G4KLX NET/ROM for Linux. Version 0.4 ALPHA for AX25.030 Linux 1.3.45\n"); + printk("G4KLX NET/ROM for Linux. Version 0.4 ALPHA for AX25.032 Linux 1.3.77\n"); nr_default.quality = NR_DEFAULT_QUAL; nr_default.obs_count = NR_DEFAULT_OBS; diff --git a/net/netrom/nr_dev.c b/net/netrom/nr_dev.c index d2ae23be3ae7..f8529b3fe2f0 100644 --- a/net/netrom/nr_dev.c +++ b/net/netrom/nr_dev.c @@ -30,7 +30,6 @@ #include #include #include /* For the statistics structure. */ -#include #include #include @@ -39,6 +38,7 @@ #include #include #include +#include #include #include diff --git a/net/netsyms.c b/net/netsyms.c new file mode 100644 index 000000000000..c781152fb449 --- /dev/null +++ b/net/netsyms.c @@ -0,0 +1,173 @@ +/* + * linux/net/netsyms.c + * + * Symbol table for the linux networking subsystem. Moved here to + * make life simpler in ksyms.c. + */ + +#include +#include + +#include +#include +#include +#include +#include +#include + +#ifdef CONFIG_AX25 +#include +#endif + +#ifdef CONFIG_INET +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#endif + +#ifdef CONFIG_NET_ALIAS +#include +#endif + +#if defined(CONFIG_ULTRA) || defined(CONFIG_WD80x3) || \ + defined(CONFIG_EL2) || defined(CONFIG_NE2000) || \ + defined(CONFIG_E2100) || defined(CONFIG_HPLAN_PLUS) || \ + defined(CONFIG_HPLAN) || defined(CONFIG_AC3200) +#include "../drivers/net/8390.h" +#endif + +extern int (*rarp_ioctl_hook)(int,void*); + +#ifdef CONFIG_IPX_MODULE +extern struct datalink_proto *make_EII_client(void); +extern struct datalink_proto *make_8023_client(void); +extern void destroy_EII_client(struct datalink_proto *); +extern void destroy_8023_client(struct datalink_proto *); +#endif + + +static struct symbol_table net_syms = { +#include + + /* Socket layer registration */ + X(sock_register), + X(sock_unregister), + + /* Socket layer support routines */ + X(memcpy_fromiovec), + X(sock_setsockopt), + X(sock_getsockopt), + X(sock_wake_async), + X(sock_alloc_send_skb), + X(skb_recv_datagram), + X(skb_free_datagram), + X(skb_copy_datagram), + X(skb_copy_datagram_iovec), + X(datagram_select), + +#ifdef CONFIG_IPX_MODULE + X(make_8023_client), + X(destroy_8023_client), + X(make_EII_client), + X(destroy_EII_client), +#endif + +#ifdef CONFIG_FIREWALL + /* Firewall registration */ + X(register_firewall), + X(unregister_firewall), +#endif + +#ifdef CONFIG_INET + /* Internet layer registration */ + X(inet_add_protocol), + X(inet_del_protocol), + X(rarp_ioctl_hook), + X(init_etherdev), + X(ip_rt_route), + X(icmp_send), + X(ip_options_compile), + X(ip_rt_put), + X(arp_send), +#ifdef CONFIG_IP_FORWARD + X(ip_forward), +#endif + +#if defined(CONFIG_ULTRA) || defined(CONFIG_WD80x3) || \ + defined(CONFIG_EL2) || defined(CONFIG_NE2000) || \ + defined(CONFIG_E2100) || defined(CONFIG_HPLAN_PLUS) || \ + defined(CONFIG_HPLAN) || defined(CONFIG_AC3200) + /* If 8390 NIC support is built in, we will need these. */ + X(ei_open), + X(ei_close), + X(ei_debug), + X(ei_interrupt), + X(ethdev_init), + X(NS8390_init), +#endif + +#ifdef CONFIG_NET_ALIAS +#include +#endif + +#endif /* CONFIG_INET */ + + /* Device callback registration */ + X(register_netdevice_notifier), + X(unregister_netdevice_notifier), + +#ifdef CONFIG_NET_ALIAS + X(register_net_alias_type), + X(unregister_net_alias_type), +#endif + + /* support for loadable net drivers */ +#ifdef CONFIG_AX25 + X(ax25_encapsulate), + X(ax25_rebuild_header), +#endif +#ifdef CONFIG_INET + X(register_netdev), + X(unregister_netdev), + X(ether_setup), + X(eth_type_trans), + X(eth_copy_and_sum), + X(alloc_skb), + X(kfree_skb), + X(skb_clone), + X(dev_alloc_skb), + X(dev_kfree_skb), + X(netif_rx), + X(dev_tint), + X(irq2dev_map), + X(dev_add_pack), + X(dev_remove_pack), + X(dev_get), + X(dev_ioctl), + X(dev_queue_xmit), + X(dev_base), + X(dev_close), + X(dev_mc_add), + X(arp_find), + X(n_tty_ioctl), + X(tty_register_ldisc), + X(kill_fasync), +#ifdef CONFIG_FIREWALL + X(call_in_firewall), +#endif +#endif /* CONFIG_INET */ + +#include +}; + +void export_net_symbols(void) +{ + register_symtab(&net_syms); +} diff --git a/net/protocols.c b/net/protocols.c index 93f06ccbff96..ea8c28f63fce 100644 --- a/net/protocols.c +++ b/net/protocols.c @@ -18,7 +18,7 @@ #ifdef CONFIG_INET #include #endif -#ifdef CONFIG_IPX +#if defined(CONFIG_IPX) || defined(CONFIG_IPX_MODULE) #include #include #endif @@ -28,8 +28,8 @@ #include #endif #endif -#ifdef CONFIG_ATALK -#ifndef CONFIG_IPX +#if defined(CONFIG_ATALK) || defined(CONFIG_ATALK_MODULE) +#if ! ( defined(CONFIG_IPX) || defined(CONFIG_IPX_MODULE) ) #include #endif #include @@ -48,7 +48,8 @@ struct net_proto protocols[] = { #ifdef CONFIG_UNIX { "UNIX", unix_proto_init }, /* Unix domain socket family */ #endif -#if defined(CONFIG_IPX)||defined(CONFIG_ATALK) +#if defined(CONFIG_IPX) || defined(CONFIG_IPX_MODULE) || \ + defined(CONFIG_ATALK) || defined(CONFIG_ATALK_MODULE) { "802.2", p8022_proto_init }, /* 802.2 demultiplexor */ { "SNAP", snap_proto_init }, /* SNAP demultiplexor */ #endif @@ -72,5 +73,3 @@ struct net_proto protocols[] = { #endif { NULL, NULL } /* End marker */ }; - - diff --git a/net/socket.c b/net/socket.c index 367537a06243..50e1deee3fe1 100644 --- a/net/socket.c +++ b/net/socket.c @@ -33,6 +33,7 @@ * for NetROM and future kernel nfsd type * stuff. * Alan Cox : sendmsg/recvmsg basics. + * Tom Dyas : Export net symbols. * * * This program is free software; you can redistribute it and/or @@ -64,12 +65,17 @@ #include #include #include +#include #include #include #include +#ifdef CONFIG_MODULES +extern void export_net_symbols(void); +#endif + static int sock_lseek(struct inode *inode, struct file *file, off_t offset, int whence); static int sock_read(struct inode *inode, struct file *file, char *buf, @@ -255,6 +261,7 @@ struct socket *sock_alloc(void) sock->conn = NULL; sock->iconn = NULL; sock->next = NULL; + sock->file = NULL; sock->wait = &inode->i_wait; sock->inode = inode; /* "backlink": we could use pointer arithmetic instead */ sock->fasync_list = NULL; @@ -302,6 +309,7 @@ void sock_release(struct socket *sock) if (peersock) sock_release_peer(peersock); --sockets_in_use; /* Bookkeeping.. */ + sock->file=NULL; iput(SOCK_INODE(sock)); } @@ -506,6 +514,19 @@ int sock_wake_async(struct socket *sock, int how) * family, then create a fresh socket. */ +static int find_protocol_family(int family) +{ + register int i; + for (i = 0; i < NPROTO; i++) + { + if (pops[i] == NULL) + continue; + if (pops[i]->family == family) + return i; + } + return -1; +} + asmlinkage int sys_socket(int family, int type, int protocol) { int i, fd; @@ -513,14 +534,20 @@ asmlinkage int sys_socket(int family, int type, int protocol) struct proto_ops *ops; /* Locate the correct protocol family. */ - for (i = 0; i < NPROTO; ++i) + i = find_protocol_family(family); + +#ifdef CONFIG_KERNELD + /* Attempt to load a protocol module if the find failed. */ + if (i < 0) { - if (pops[i] == NULL) continue; - if (pops[i]->family == family) - break; + char module_name[30]; + sprintf(module_name,"net-pf-%d",family); + request_module(module_name); + i = find_protocol_family(family); } +#endif - if (i == NPROTO) + if (i < 0) { return -EINVAL; } @@ -565,6 +592,8 @@ asmlinkage int sys_socket(int family, int type, int protocol) return(-EINVAL); } + sock->file=current->files->fd[fd]; + return(fd); } @@ -745,7 +774,8 @@ asmlinkage int sys_accept(int fd, struct sockaddr *upeer_sockaddr, int *upeer_ad sock_release(newsock); return(-EINVAL); } - + sock->file=current->files->fd[fd]; + if (upeer_sockaddr) { newsock->ops->getname(newsock, (struct sockaddr *)address, &len, 1); @@ -1347,7 +1377,7 @@ void sock_init(void) { int i; - printk("Swansea University Computer Society NET3.033 for Linux 1.3.50\n"); + printk("Swansea University Computer Society NET3.034 for Linux 1.3.77\n"); /* * Initialize all address (protocol) families. @@ -1383,6 +1413,14 @@ void sock_init(void) */ proto_init(); + + /* + * Export networking symbols to the world. + */ + +#ifdef CONFIG_MODULES + export_net_symbols(); +#endif } int socket_get_info(char *buffer, char **start, off_t offset, int length) diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c index e8932fc0adc5..0ecfd096ce73 100644 --- a/net/unix/af_unix.c +++ b/net/unix/af_unix.c @@ -26,6 +26,7 @@ * Mike Shaver's work. * Marty Leisner : Fixes to fd passing * Nick Nevin : recvmsg bugfix. + * Alan Cox : Started proper garbage collector * * Known differences from reference BSD that was tested: * @@ -69,7 +70,7 @@ #include #include -static unix_socket *unix_socket_list=NULL; +unix_socket *unix_socket_list=NULL; #define min(a,b) (((a)<(b))?(a):(b)) @@ -745,19 +746,12 @@ static int unix_fd_copy(struct sock *sk, struct cmsghdr *cmsg, struct file **fp) return -EBADF; } - /* - * Make sure the garbage collector can cope. - */ - - if(unix_gc_freefiles->fd[fdp[i]]; fp[i]->f_count++; - unix_gc_add(sk, fp[i]); + unix_inflight(fp[i]); } return num; @@ -773,7 +767,7 @@ static void unix_fd_free(struct sock *sk, struct file **fp, int num) for(i=0;ifiles->close_on_exec); - unix_gc_remove(fp[i]); + unix_notinflight(fp[i]); } /* * Dump those that don't @@ -859,7 +853,7 @@ static void unix_detach_fds(struct sk_buff *skb, struct cmsghdr *cmsg) for(;ih.filp); skb->h.filp=NULL; @@ -1265,17 +1259,19 @@ static int unix_get_info(char *buffer, char **start, off_t offset, int length, i int len=0; unix_socket *s=unix_socket_list; - len+= sprintf(buffer,"Num RefCount Protocol Flags Type St Path\n"); + len+= sprintf(buffer,"Num RefCount Protocol Flags Type St " + "Inode Path\n"); while(s!=NULL) { - len+=sprintf(buffer+len,"%p: %08X %08X %08lX %04X %02X", + len+=sprintf(buffer+len,"%p: %08X %08X %08lX %04X %02X %5ld", s, s->protinfo.af_unix.locks, 0, s->socket->flags, s->socket->type, - s->socket->state); + s->socket->state, + s->socket->inode ? s->socket->inode->i_ino : 0); if(s->protinfo.af_unix.name!=NULL) len+=sprintf(buffer+len, " %s\n", s->protinfo.af_unix.name); else @@ -1299,7 +1295,7 @@ static int unix_get_info(char *buffer, char **start, off_t offset, int length, i } #endif -static struct proto_ops unix_proto_ops = { +struct proto_ops unix_proto_ops = { AF_UNIX, unix_create, diff --git a/net/unix/garbage.c b/net/unix/garbage.c index 67d9e06c9c27..70bf274759a7 100644 --- a/net/unix/garbage.c +++ b/net/unix/garbage.c @@ -1,13 +1,38 @@ /* - * NET3: Garbage Collector For AF_UNIX sockets (STUB) + * NET3: Garbage Collector For AF_UNIX sockets (STUBS) * - * Authors: + * Garbage Collector: + * Copyright (C) Barak A. Pearlmutter. + * Released under the GPL version 2 or later. * - * 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. - * Fixes: + * NOTE: + * We don't actually call this yet. I'm finishing some tests before I + * enable it. The bold can add it in themselves. + * + * Chopped about by Alan Cox 22/3/96 to make it fit the AF_UNIX socket problem. + * If it doesnt work blame me, it worked when Barak sent it. + * + * Assumptions: + * + * - object w/ a bit + * - free list + * + * Current optimizations: + * + * - explicit stack instead of recursion + * - tail recurse on first born instead of immediate push/pop + * + * Future optimizations: + * + * - don't just push entire root set; process in place + * - use linked list for internal stack + * + * 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. + * + * Fixes: * */ @@ -35,19 +60,218 @@ #include #include #include + +/* Internal data structures and random procedures: */ + +#define MAX_STACK 1000 /* Maximum depth of tree (about 1 page) */ +static unix_socket **stack; /* stack of objects to mark */ +static int in_stack = 0; /* first free entry in stack */ + + +extern inline unix_socket *unix_get_socket(struct file *filp) +{ + struct socket *s; + /* + * Socket ? + */ + if(filp->f_inode->i_mode!=S_IFSOCK) + return NULL; + s=&(filp->f_inode->u.socket_i); + /* + * AF_UNIX ? + */ + if(s->ops!=&unix_proto_ops) + return NULL; + /* + * Got one. + */ + return s->data; +} + +/* + * Keep the number of times in flight count for the file + * descriptor if it is for an AF_UNIX socket. + */ + +void unix_inflight(struct file *fp) +{ + unix_socket *s=unix_get_socket(fp); + if(s) + s->protinfo.af_unix.inflight++; +} + +void unix_notinflight(struct file *fp) +{ + unix_socket *s=unix_get_socket(fp); + if(s) + s->protinfo.af_unix.inflight--; +} + + /* - * Garbage Collector Stubs + * Garbage Collector Support Functions */ +extern inline void push_stack(unix_socket *x) +{ + if (in_stack == MAX_STACK) + panic("can't push onto full stack"); + stack[in_stack++] = x; +} -int unix_gc_free=128; /* GC slots free */ +extern inline unix_socket *pop_stack(void) +{ + if (in_stack == 0) + panic("can't pop empty gc stack"); + return stack[--in_stack]; +} + +extern inline int empty_stack(void) +{ + return in_stack == 0; +} -void unix_gc_remove(struct file *fp) +extern inline void maybe_mark_and_push(unix_socket *x) { - ; + if (x->protinfo.af_unix.marksweep&MARKED) + return; + x->protinfo.af_unix.marksweep|=MARKED; + push_stack(x); } -void unix_gc_add(struct sock *sk, struct file *fp) + +/* The external entry point: unix_gc() */ + +void unix_gc(void) { - ; + static int in_unix_gc=0; + unix_socket *s; + unix_socket *next; + + /* + * Avoid a recursive GC. + */ + + if(in_unix_gc) + return; + in_unix_gc=1; + + stack=(unix_socket **)get_free_page(GFP_KERNEL); + + /* + * Assume everything is now unmarked + */ + + /* Invariant to be maintained: + - everything marked is either: + -- (a) on the stack, or + -- (b) has all of its children marked + - everything on the stack is always marked + - nothing is ever pushed onto the stack twice, because: + -- nothing previously marked is ever pushed on the stack + */ + + /* + * Push root set + */ + + for(s=unix_socket_list;s!=NULL;s=s->next) + { + /* + * If all instances of the descriptor are not + * in flight we are in use. + */ + if(s->socket && s->socket->file && s->socket->file->f_count > s->protinfo.af_unix.inflight) + maybe_mark_and_push(s); + } + + /* + * Mark phase + */ + + while (!empty_stack()) + { + unix_socket *x = pop_stack(); + unix_socket *f=NULL,*sk; + struct sk_buff *skb; +tail: + skb=skb_peek(&x->receive_queue); + + /* + * Loop through all but first born + */ + + while(skb && skb != (struct sk_buff *)&x->receive_queue) + { + /* + * Do we have file descriptors ? + */ + if(skb->h.filp) + { + /* + * Process the descriptors of this socket + */ + int nfd=*(int *)skb->h.filp; + struct file **fp=(struct file **)(skb->h.filp+sizeof(int)); + while(nfd--) + { + /* + * Get the socket the fd matches if + * it indeed does so + */ + if((sk=unix_get_socket(*fp++))!=NULL) + { + /* + * Remember the first, mark the + * rest. + */ + if(f==NULL) + f=sk; + else + maybe_mark_and_push(sk); + } + } + } + skb=skb->next; + } + /* + * Handle first born specially + */ + + if (f) + { + if (!(f->protinfo.af_unix.marksweep&MARKED)) + { + f->protinfo.af_unix.marksweep|=MARKED; + x=f; + f=NULL; + goto tail; + } + } + } + + /* + * Sweep phase. NOTE: this part dominates the time complexity + */ + + for(s=unix_socket_list;s!=NULL;s=next) + { + next=s->next; + if (!(s->protinfo.af_unix.marksweep&MARKED)) + { + /* + * We exist only in the passing tree of sockets + * that is no longer connected to active descriptors + * Time to die.. + */ + if(s->socket && s->socket->file) + close_fp(s->socket->file); + } + else + s->protinfo.af_unix.marksweep&=~MARKED; /* unmark everything for next collection */ + } + + in_unix_gc=0; + + free_page((long)stack); } diff --git a/scripts/Configure b/scripts/Configure index 16cb97798ceb..f037bd04b8b5 100644 --- a/scripts/Configure +++ b/scripts/Configure @@ -9,7 +9,7 @@ # # Please send comments / questions / bug fixes to raymondc@microsoft.com. # -# ***** IMPORTANT COMPATABILITY NOTE **** +# ***** IMPORTANT COMPATIBILITY NOTE **** # If configuration changes are made which might adversely effect # Menuconfig or xconfig, please notify the respective authors so that # those utilities can be updated in parallel. @@ -39,6 +39,9 @@ # # 150296 Dick Streefland (dicks@tasking.nl) - report new configuration # items and ask for a value even when doing a "make oldconfig" +# +# 200396 Tom Dyas (tdyas@eden.rutgers.edu) - when the module option is +# chosen for an item, define the macro _MODULE # # Make sure we're really running bash. @@ -141,6 +144,7 @@ function define_bool () { "m") echo "$1=m" >>$CONFIG echo "#undef $1" >>$CONFIG_H + echo "#define $1_MODULE 1" >>$CONFIG_H ;; "n") diff --git a/scripts/Menuconfig b/scripts/Menuconfig index 8aa31eaf9189..bc64da1d298f 100644 --- a/scripts/Menuconfig +++ b/scripts/Menuconfig @@ -40,6 +40,180 @@ single_menu_mode= # set -h + + + + +# +# Load the functions used by the config.in files. +# +# I do this because these functions must be redefined depending +# on whether they are being called for interactive use or for +# saving a configuration to a file. +# +# Thank the heavens bash supports nesting function definitions. +# +load_functions () { + +# +# Additional comments +# +function comment () { + comment_ctr=$[ comment_ctr + 1 ] + echo -ne "': $comment_ctr' '--- $1' " >>MCmenu +} + +# +# Don't need this yet, but we don't want to puke either. +# +function define_bool () { + : +} + +# +# Create a boolean (Yes/No) function for our current menu +# which calls our local bool function. +# +function bool () { + eval $2=\${$2:-'n'} x=\$$2 + + case $x in + y|m) yes='ON' no='OFF' flag="*" + ;; + n) yes='OFF' no='ON' flag=" " + ;; + esac + + echo -ne "'$2' '($flag) $1' " >>MCmenu + + echo -e "function $2 () { l_bool '$1' '$yes' '$no' '$2' }\n" \ + >>MCradiolists +} + +# +# Create a tristate (Yes/No/Module) radiolist function +# which calls our local tristate function. +# +# Collapses to a boolean (Yes/No) if module support is disabled. +# +function tristate () { + if [ "$CONFIG_MODULES" != "y" ] + then + bool "$1" "$2" + else + eval $2=\${$2:-'n'} x=\$$2 + + case $x in + y) yes='ON' no='OFF' module='OFF' flag="*" + ;; + m) yes='OFF' no='OFF' module='ON' flag="M" + ;; + *) yes='OFF' no='ON' module='OFF' flag=" " + ;; + esac + + echo -ne "'$2' '<$flag> $1' " >>MCmenu + + echo -e " + function $2 () { \ + l_tristate '$1' '$yes' '$no' '$module' '$2' + }" >>MCradiolists + fi +} + +# +# Create a tristate radiolist function which is dependent on +# another kernel configuration option. +# +# Quote from the original configure script: +# +# If the option we depend upon is a module, +# then the only allowable options are M or N. If Y, then +# this is a normal tristate. This is used in cases where modules +# are nested, and one module requires the presence of something +# else in the kernel. +# +function dep_tristate () { + if [ "$CONFIG_MODULES" != "y" ] + then + bool "$1" "$2" + else + if eval [ "_$3" != "_m" ] + then + tristate "$1" "$2" $3 + else + mod_bool "$1" "$2" + fi + fi +} + +# +# Add a menu item which will call our local int function. +# +function int () { + eval $2=\${$2:-"$3"} x=\$$2 + + echo -ne "'$2' '($x) $1' " >>MCmenu + + echo -e "function $2 () { l_int '$1' '$2' '$3' '$x' }\n" >>MCradiolists +} + +# +# Add a menu item which will call our local int function. +# +function hex () { + eval $2=\${$2:-"$3"} x=\${$2##*[x,X]} + + echo -ne "'$2' '($x) $1' " >>MCmenu + + echo -e "function $2 () { l_hex '$1' '$2' '$3' '$x' }\n" >>MCradiolists +} + +# +# Add a menu item which will call our local One-of-Many choice list. +# +function choice () { + # + # Need to remember params cause the're gonna get reset. + # + title=$1 + choices=$2 + default=$3 + current= + + # + # Find out if one of the choices is already set. + # If it's not then make it the default. + # + set -- $choices + firstchoice=$2 + + while [ -n "$2" ] + do + if eval [ "_\$$2" = "_y" ] + then + current=$1 + break + fi + shift ; shift + done + + : ${current:=$default} + + echo -ne "'$firstchoice' '($current) $title' " >>MCmenu + + echo -e " + function $firstchoice () { + l_choice '$title' \"$choices\" $current + }\n" >>MCradiolists +} + +} # END load_functions() + + + + + # # Extract available help for an option from Configure.help # and send it to standard output. @@ -107,21 +281,6 @@ function menu_name () { >MCradiolists } -# -# Additional comments -# -function comment () { - comment_ctr=$[ comment_ctr + 1 ] - echo -ne "': $comment_ctr' '--- $1' " >>MCmenu -} - -# -# Don't need this yet, but we don't want to puke either. -# -function define_bool () { - : -} - # # Add a submenu option to the menu currently under construction. # @@ -146,27 +305,6 @@ function l_soundcfg () { $MAKE -C drivers/sound config } - -# -# Create a boolean (Yes/No) function for our current menu -# which calls our local bool function. -# -function bool () { - eval $2=\${$2:-'n'} x=\$$2 - - case $x in - y|m) yes='ON' no='OFF' flag="*" - ;; - n) yes='OFF' no='ON' flag=" " - ;; - esac - - echo -ne "'$2' '($flag) $1' " >>MCmenu - - echo -e "function $2 () { l_bool '$1' '$yes' '$no' '$2' }\n" \ - >>MCradiolists -} - # # Handle a boolean (Yes/No) option. # @@ -202,7 +340,7 @@ function mod_bool () { ;; esac - echo -ne "'$2' '($flag) $1' " >>MCmenu + echo -ne "'$2' '<$flag> $1' " >>MCmenu echo -e "function $2 () { l_mod_bool '$1' '$module' '$no' '$2' }\n" \ >>MCradiolists @@ -231,37 +369,6 @@ function l_mod_bool() { done } -# -# Create a tristate (Yes/No/Module) radiolist function -# which calls our local tristate function. -# -# Collapses to a boolean (Yes/No) if module support is disabled. -# -function tristate () { - if [ "$CONFIG_MODULES" != "y" ] - then - bool "$1" "$2" - else - eval $2=\${$2:-'n'} x=\$$2 - - case $x in - y) yes='ON' no='OFF' module='OFF' flag="*" - ;; - m) yes='OFF' no='OFF' module='ON' flag="M" - ;; - *) yes='OFF' no='ON' module='OFF' flag=" " - ;; - esac - - echo -ne "'$2' '($flag) $1' " >>MCmenu - - echo -e " - function $2 () { \ - l_tristate '$1' '$yes' '$no' '$module' '$2' - }" >>MCradiolists - fi -} - # # Handle a tristate (Yes/No/Module) option. # @@ -285,43 +392,6 @@ function l_tristate () { done } -# -# Create a tristate radiolist function which is dependent on -# another kernel configuration option. -# -# Quote from the original configure script: -# -# If the option we depend upon is a module, -# then the only allowable options are M or N. If Y, then -# this is a normal tristate. This is used in cases where modules -# are nested, and one module requires the presence of something -# else in the kernel. -# -function dep_tristate () { - if [ "$CONFIG_MODULES" != "y" ] - then - bool "$1" "$2" - else - if eval [ "_$3" != "_m" ] - then - tristate "$1" "$2" $3 - else - mod_bool "$1" "$2" - fi - fi -} - -# -# Add a menu item which will call our local int function. -# -function int () { - eval $2=\${$2:-"$3"} x=\$$2 - - echo -ne "'$2' '($x) $1' " >>MCmenu - - echo -e "function $2 () { l_int '$1' '$2' '$3' '$x' }\n" >>MCradiolists -} - # # Create a dialog for entering an integer into a kernel option. # @@ -354,18 +424,6 @@ function l_int () { done } - -# -# Add a menu item which will call our local int function. -# -function hex () { - eval $2=\${$2:-"$3"} x=\${$2##*[x,X]} - - echo -ne "'$2' '($x) $1' " >>MCmenu - - echo -e "function $2 () { l_hex '$1' '$2' '$3' '$x' }\n" >>MCradiolists -} - # # Create a dialog for entering a hexidecimal into a kernel option. # @@ -400,45 +458,8 @@ function l_hex () { } # -# Add a menu item which will call our local One-of-Many choice list. +# Handle a on-of-many choice list. # -function choice () { - # - # Need to remember params cause the're gonna get reset. - # - title=$1 - choices=$2 - default=$3 - current= - - # - # Find out if one of the choices is already set. - # If it's not then make it the default. - # - set -- $choices - firstchoice=$2 - - while [ -n "$2" ] - do - if eval [ "_\$$2" = "_y" ] - then - current=$1 - break - fi - shift ; shift - done - - : ${current:=$default} - - echo -ne "'$firstchoice' '($current) $title' " >>MCmenu - - echo -e " - function $firstchoice () { - l_choice '$title' \"$choices\" $current - }\n" >>MCradiolists -} - - function l_choice () { # # Need to remember params cause the're gonna get reset. @@ -590,7 +611,6 @@ function parse_config_files () { echo 'default=$1' >>MCmenu0 echo "menu_name 'Main Menu'" >>MCmenu0 - if [ "_$single_menu_mode" = "_TRUE" ] then parser2 @@ -598,6 +618,10 @@ function parse_config_files () { parser1 fi + echo "comment ''" >>MCmenu0 + echo "g_alt_config" >>MCmenu0 + echo "s_alt_config" >>MCmenu0 + echo "}" >>MCmenu0 # @@ -644,7 +668,8 @@ function activate_menu () { default="${selection%% *}" case "$selection" in - *"-->"*) show_readme ;; + *"-->"*|\ + *"alt_config"*) show_readme ;; *) eval help $selection ;; esac ;; @@ -655,17 +680,156 @@ function activate_menu () { done } +# +# Create a menu item to load an alternate configuration file. +# +g_alt_config () { + echo -n "get_alt_config 'Load an Alternate Configuration File' "\ + >>MCmenu +} + +# +# Get alternate config file name and load the +# configuration from it. +# +get_alt_config () { + while true + do + ALT_CONFIG="${ALT_CONFIG:-$DEFAULTS}" + + $DIALOG --backtitle "$backtitle" \ + --inputbox "\ +Enter the name of the configuration file you wish to load. \ +Accept the name shown to restore the configuration you \ +last retrieved. Leave blank to abort."\ + 11 55 "$ALT_CONFIG" 2>MCdialog.out + + if [ "$?" = "0" ] + then + ALT_CONFIG=`cat MCdialog.out` + + [ "_" = "_$ALT_CONFIG" ] && break + + if [ -r "$ALT_CONFIG" ] + then + load_config_file "$ALT_CONFIG" + break + else + echo -ne "\007" + $DIALOG --backtitle "$backtitle" \ + --infobox "File does not exit!" 3 38 + sleep 2 + fi + else + cat <help.out + +For various reasons, one may wish to keep several different kernel +configurations available on a single machine. + +If you have saved a previous configuration in a file other than the +kernel's default, entering the name of the file here will allow you +to modify that configuration. + +If you are uncertain, then you have probably never used alternate +configuration files. You should therefor leave this blank to abort. + +EOM + $DIALOG --backtitle "$backtitle"\ + --title "Load Alternate Configuration"\ + --textbox help.out $LINES $COLS + fi + done + + rm -f help.out MCdialog.out +} + +# +# Create a menu item to store an alternate config file. +# +s_alt_config () { + echo -n "save_alt_config 'Store an Alternate Configuration File' "\ + >>MCmenu +} + +# +# Get an alternate config file name and save the current +# configuration to it. +# +save_alt_config () { + while true + do + $DIALOG --backtitle "$backtitle" \ + --inputbox "\ +Enter a filename to which this configuration should be saved \ +as an alternate. Leave blank to abort."\ + 10 55 "$ALT_CONFIG" 2>MCdialog.out + + if [ "$?" = "0" ] + then + ALT_CONFIG=`cat MCdialog.out` + + [ "_" = "_$ALT_CONFIG" ] && break + + if touch $ALT_CONFIG 2>/dev/null + then + save_configuration $ALT_CONFIG + load_functions ## RELOAD + break + else + echo -ne "\007" + $DIALOG --backtitle "$backtitle" \ + --infobox "Can't create file! Probably a nonexistent directory." 3 60 + sleep 2 + fi + else + cat <help.out + +For various reasons, one may wish to keep different kernel +configurations available on a single machine. + +Entering a file name here will allow you to later retrieve, modify +and use the current configuration as an alternate to whatever +configuration options you have selected at that time. + +If you are uncertain what all this means then you should probably +leave this blank. +EOM + $DIALOG --backtitle "$backtitle"\ + --title "Store Alternate Configuration"\ + --textbox help.out $LINES $COLS + fi + done + + rm -f help.out MCdialog.out +} + +# +# Load config options from a file. +# Converts all "# OPTION is not set" lines to "OPTION=" lines +# +function load_config_file () { + awk ' + /# .* is not set.*/ { printf("%s=\n", $2) } + ! /# .* is not set.*/ { print } + ' $1 >.tmpconfig + + source .tmpconfig + rm -f .tmpconfig +} + # # Just what it says. # save_configuration () { ${DIALOG} --backtitle "$backtitle" \ - --infobox "Saving your new kernel configuration..." 3 43 + --infobox "Saving your kernel configuration..." 3 40 # # Now, let's redefine the configuration functions for final # output to the config files. # + # Nested function definitions, YIPEE! + # function bool () { eval define_bool "$2" "\${$2:-n}" } @@ -721,7 +885,7 @@ save_configuration () { ;; n) - echo "# $1 is not set" >>$CONFIG + echo "# $1 is not set" >>$CONFIG echo "#undef $1" >>$CONFIG_H ;; esac @@ -787,6 +951,9 @@ save_configuration () { fi } + DEF_CONFIG="${1:-.config}" + DEF_CONFIG_H="include/linux/autoconf.h" + CONFIG=.tmpconfig CONFIG_H=.tmpconfig.h @@ -802,24 +969,30 @@ save_configuration () { if . $CONFIG_IN >>.menuconfig.log 2>&1 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" ] + if [ "$DEF_CONFIG" = ".config" ] then - make -C drivers/sound kernelconfig >>.menuconfig.log 2>&1 + # + # 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 + make -C drivers/sound kernelconfig >>.menuconfig.log 2>&1 + fi + + mv $CONFIG_H $DEF_CONFIG_H fi - if [ -f .config ] + if [ -f "$DEF_CONFIG" ] then - rm -f .config.old - mv .config .config.old + rm -f ${DEF_CONFIG}.old + mv $DEF_CONFIG ${DEF_CONFIG}.old fi - mv .tmpconfig .config - mv .tmpconfig.h include/linux/autoconf.h + + mv $CONFIG $DEF_CONFIG + return 0 else return 1 @@ -856,18 +1029,20 @@ esac menu_instructions="\ -Arrow keys navigate the menu. \ +The Arrow keys navigate the menu. \ Highlighted letters are hotkeys. \ -Select an item with or . \ -When finished press or . \ -A (*) marks an option to be compiled into the kernel. \ -An (M) marks an option to be compiled as a module." +Press the to select an item. \ +Press to exit. \ +Press for Help. \ +(*) options will be compiled into the kernel. \ +(M) options will be modules. \ +< > marks module capable options." radiolist_instructions="\ Use the arrow keys to navigate this window or \ press the hotkey of the item you wish to select \ followed by the . -Press for additional information about this option." +Press for additional information about this option." inputbox_instructions_int="\ Please enter a decimal value between 1 and 9999. \ @@ -886,15 +1061,10 @@ kernel_version="${VERSION}.${PATCHLEVEL}.${SUBLEVEL}" trap "cleanup ; rm -f .menuconfig ; exit 1" 1 2 15 + # # Locate default files. # -DEFAULT="" -if [ "$1" = "-d" ] ; then - DEFAULT="-d" - shift -fi - CONFIG_IN=./config.in if [ "$1" != "" ] ; then CONFIG_IN=$1 @@ -905,7 +1075,8 @@ if [ -f .config ]; then DEFAULTS=.config fi -if [ -f $DEFAULTS ]; then +if [ -f $DEFAULTS ] +then echo "#" echo "# Using defaults found in" $DEFAULTS echo "#" @@ -916,10 +1087,10 @@ else echo "#" fi + # Fresh new log. >.menuconfig.log - $DIALOG --backtitle "$backtitle" \ --infobox "Preparing configuration scripts..." 3 40 @@ -948,6 +1119,9 @@ then echo "# $kernel_version" >.menuconfig fi +# Load the functions used by the config.in files. +load_functions + # # Read config.in files and parse them into one shell function per menu. # diff --git a/scripts/README.Menuconfig b/scripts/README.Menuconfig index bb4d36c395c9..6d880bef1092 100644 --- a/scripts/README.Menuconfig +++ b/scripts/README.Menuconfig @@ -78,6 +78,22 @@ If Menuconfig quits with an error while saving your configuration, you may look in the file /usr/src/linux/.menuconfig.log for information which may help you determine the cause. +Alternate Configuration Files +----------------------------- +Menuconfig supports the use of alternate configuration files for +those who, for various reasons, find it necessary to switch +between different kernel configurations. + +At the end of the main menu you will find two options. One is +for saving the current configuration to a file of your choosing. +The other option is for loading a previously saved alternate +configuration. + +Even if you don't use alternate configuration files, but you +find during a Menuconfig session that you have completely messed +up your settings, you may use the "Load Alternate..." option to +restore your previously saved settings from ".config" without +restarting Menuconfig. Other information ----------------- diff --git a/scripts/lxdialog/inputbox.c b/scripts/lxdialog/inputbox.c index 1b5b250f492d..1d0200fa4681 100644 --- a/scripts/lxdialog/inputbox.c +++ b/scripts/lxdialog/inputbox.c @@ -27,14 +27,15 @@ unsigned char dialog_input_result[MAX_LEN + 1]; * Print the termination buttons */ static void -print_buttons(WINDOW *dialog, int height, int width, int okval, int cancelval) +print_buttons(WINDOW *dialog, int height, int width, int selected) { int x = width / 2 - 11; int y = height - 2; - print_button (dialog, " Ok ", y, x, okval); - print_button (dialog, " Help ", y, x + 14, cancelval); + print_button (dialog, " Ok ", y, x, selected==0); + print_button (dialog, " Help ", y, x + 14, selected==1); + wmove(dialog, y, x+1+14*selected); wrefresh(dialog); } @@ -86,7 +87,7 @@ dialog_inputbox (const char *title, const char *prompt, int height, int width, draw_box (dialog, y + 1, box_x - 1, 3, box_width + 2, border_attr, dialog_attr); - print_buttons(dialog, height, width, TRUE, FALSE); + print_buttons(dialog, height, width, 0); /* Set up the initial value */ wmove (dialog, box_y, box_x); @@ -180,17 +181,17 @@ dialog_inputbox (const char *title, const char *prompt, int height, int width, switch (button) { case -1: button = 1; /* Indicates "Cancel" button is selected */ - print_buttons(dialog, height, width, FALSE, TRUE); + print_buttons(dialog, height, width, 1); break; case 0: button = -1; /* Indicates input box is selected */ - print_buttons(dialog, height, width, TRUE, FALSE); + print_buttons(dialog, height, width, 0); wmove (dialog, box_y, box_x + input_x); wrefresh (dialog); break; case 1: button = 0; /* Indicates "OK" button is selected */ - print_buttons(dialog, height, width, TRUE, FALSE); + print_buttons(dialog, height, width, 0); break; } break; @@ -200,15 +201,15 @@ dialog_inputbox (const char *title, const char *prompt, int height, int width, switch (button) { case -1: button = 0; /* Indicates "OK" button is selected */ - print_buttons(dialog, height, width, TRUE, FALSE); + print_buttons(dialog, height, width, 0); break; case 0: button = 1; /* Indicates "Cancel" button is selected */ - print_buttons(dialog, height, width, FALSE, TRUE); + print_buttons(dialog, height, width, 1); break; case 1: button = -1; /* Indicates input box is selected */ - print_buttons(dialog, height, width, TRUE, FALSE); + print_buttons(dialog, height, width, 0); wmove (dialog, box_y, box_x + input_x); wrefresh (dialog); break; diff --git a/scripts/lxdialog/menubox.c b/scripts/lxdialog/menubox.c index 915271507ad9..0e6f1111ab4b 100644 --- a/scripts/lxdialog/menubox.c +++ b/scripts/lxdialog/menubox.c @@ -220,7 +220,7 @@ dialog_menu (const char *title, const char *prompt, int height, int width, (items[(scroll+choice)*2][0] != ':')); if (key == KEY_UP || key == '-') { - if (choice < 6 && scroll) { + if (choice < 2 && scroll) { /* Scroll menu down */ scrollok (menu, TRUE); wscrl (menu, -1); @@ -238,7 +238,9 @@ dialog_menu (const char *title, const char *prompt, int height, int width, print_item (menu, items[(scroll+choice)*2+1], choice, FALSE, (items[(scroll+choice)*2][0] != ':')); - if ((choice > 4) && (scroll + max_choice < item_no)) { + if ((choice > max_choice-3) && + (scroll + max_choice < item_no) + ) { /* Scroll menu up */ scrollok (menu, TRUE); scroll (menu); -- 2.39.5