From f9c236003a159e33785323808ded913374988d57 Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Fri, 23 Nov 2007 15:11:57 -0500 Subject: [PATCH] Linux 2.0.36pre7 This doesn't fix the icmp or threaded socket handling stuff that does eventually need curing. It does however fix all sorts of other fun things. With this release the Cyclades should be happy and the Cyrix detect/AMD detect shoul work properly, including the old AMD bug detect. Consider this your last chance to scream about 2.0.36 bugs --- CREDITS | 4 +- Documentation/networking/arcnet.txt | 9 +- Documentation/networking/shaper.txt | 49 + Makefile | 3 + arch/alpha/boot/bootp.c | 1 - arch/i386/boot/compressed/head.S | 1 - arch/i386/boot/tools/build.c | 3 +- arch/i386/kernel/entry.S | 11 +- arch/m68k/amiga/cyberfb.c | 1 - arch/m68k/atari/atasound.c | 1 - arch/m68k/atari/ksyms.c | 1 - arch/m68k/kernel/sys_m68k.c | 1 - arch/ppc/kernel/mk_defs.c | 1 - arch/ppc/kernel/pci.c | 1 - arch/ppc/kernel/time.c | 1 - arch/ppc/mm/fault.c | 1 - arch/sparc/kernel/ksyms.c | 1 - arch/sparc/kernel/sys_sunos.c | 1 - drivers/block/floppy.c | 15 +- drivers/block/ide.c | 2 +- drivers/block/md.c | 1 - drivers/char/cyclades.c | 16 +- drivers/char/tga.c | 1 + drivers/isdn/hisax/elsa_ser.c | 1 + drivers/isdn/icn/icn.c | 1 + drivers/isdn/isdn_common.h | 1 + drivers/isdn/isdn_syms.c | 2 +- drivers/isdn/isdnloop/isdnloop.h | 1 - drivers/net/3c515.c | 1 - drivers/net/Config.in | 1 - drivers/net/Makefile | 8 - drivers/net/Space.c | 9 + drivers/net/eepro100.c | 1 - drivers/net/epic100.c | 1 - drivers/net/lance.c | 2 +- drivers/net/ne2k-pci.c | 1 - drivers/net/pcnet32.c | 1 - drivers/net/rtl8139.c | 1 - drivers/net/strip.c | 2 - drivers/net/wic.c | 1459 --------------------------- drivers/scsi/hosts.c | 14 +- drivers/scsi/ppa.h | 1 + drivers/sound/sb_common.c | 2 + drivers/sound/sequencer.c | 5 +- fs/fat/fatfs_syms.c | 1 - fs/isofs/joliet.c | 8 +- fs/nfs/dir.c | 4 +- fs/read_write.c | 11 +- fs/select.c | 12 +- fs/vfat/namei.c | 1 - include/asm-alpha/lca.h | 1 + include/asm-i386/bugs.h | 177 ++++ include/asm-i386/unistd.h | 3 + include/linux/fs.h | 2 + include/linux/isdn_ppp.h | 2 + include/linux/msdos_fs.h | 1 - include/linux/personality.h | 2 +- include/linux/shm.h | 1 + include/net/sock.h | 3 +- ipc/shm.c | 63 ++ kernel/ksyms.c | 7 + mm/swapfile.c | 2 + net/ipv4/ip_masq_quake.c | 1 - net/ipv4/tcp.c | 9 +- net/ipv4/tcp_input.c | 17 + scripts/checkconfig.pl | 53 + 66 files changed, 493 insertions(+), 1529 deletions(-) create mode 100644 Documentation/networking/shaper.txt delete mode 100644 drivers/net/wic.c create mode 100644 scripts/checkconfig.pl diff --git a/CREDITS b/CREDITS index eb38b247c948..ee96380c88f3 100644 --- a/CREDITS +++ b/CREDITS @@ -37,9 +37,11 @@ S: USA N: Andrea Arcangeli E: arcangeli@mbox.queen.it -W: http://www.cs.unibo.it/~arcangel/ +W: http://e-mind.com/~andrea/ P: 1024/CB4660B9 CC A0 71 81 F4 A0 63 AC C0 4B 81 1D 8C 15 C8 E5 D: Fixed a 2.0.33 mm bug that corrupts memory in linux/mm/vmalloc.c +D: Author of lil (Linux Interrupt Latency benchmark) +D: Fixed the shm swap deallocation at swapoff time S: Via Ciaclini 26 S: Imola 40026 S: Italy diff --git a/Documentation/networking/arcnet.txt b/Documentation/networking/arcnet.txt index f496e383fb9c..ae6f9989c0cb 100644 --- a/Documentation/networking/arcnet.txt +++ b/Documentation/networking/arcnet.txt @@ -329,11 +329,10 @@ can set up your network then: ifconfig arc0 insight route add insight arc0 route add freedom arc0 /* I would use the subnet here (like I said - to to in "single protocol" above), - but the rest of the subnet - unfortunately lies across the PPP - link on freedom, which confuses - things. */ + in "single protocol" above), but the + rest of the subnet unfortunately + lies across the PPP link on freedom, + which confuses things. */ route add default gw freedom And freedom gets configured like so: diff --git a/Documentation/networking/shaper.txt b/Documentation/networking/shaper.txt new file mode 100644 index 000000000000..53ff5aefff4d --- /dev/null +++ b/Documentation/networking/shaper.txt @@ -0,0 +1,49 @@ +Traffic Shaper For Linux + +This is the current ALPHA release of the traffic shaper for Linux. It works +within the following limits: + +o Minimum shaping speed is currently about 9600 baud (it can only +shape down to 1 byte per clock tick) + +o Maximum is about 256K, it will go above this but get a bit blocky. + +o If you ifconfig the master device that a shaper is attached to down +then your machine will follow. + +o The shaper must be a module. + + +Setup: + + A shaper device is configured using the shapeconfig program. +Typically you will do something like this + +shapecfg attach shaper0 eth1 +shapecfg speed shaper0 64000 +ifconfig shaper0 myhost netmask 255.255.255.240 broadcast 1.2.3.4.255 up +route add -net some.network netmask a.b.c.d dev shaper0 + +The shaper should have the same IP address as the device it is attached to +for normal use. + +Gotchas: + + The shaper shapes transmitted traffic. It's rather impossible to +shape received traffic except at the end (or a router) transmitting it. + + Gated/routed/rwhod/mrouted all see the shaper as an additional device +and will treat it as such unless patched. Note that for mrouted you can run +mrouted tunnels via a traffic shaper to control bandwidth usage. + + The shaper is device/route based. This makes it very easy to use +with any setup BUT less flexible. You may well want to combine this patch +with Mike McLagan 's patch to allow routes to be +specified by source/destination pairs. + + There is no "borrowing" or "sharing" scheme. This is a simple +traffic limiter. I'd like to implement Van Jacobson and Sally Floyd's CBQ +architecture into Linux one day (maybe in 2.1 sometime) and do this with +style. + +Alan diff --git a/Makefile b/Makefile index 92eaa470144b..f88e7d9bc4cf 100644 --- a/Makefile +++ b/Makefile @@ -368,6 +368,9 @@ endif depend dep: dep-files $(MODVERFILE) +checkconfig: + perl -w scripts/checkconfig.pl `find * -name '*.[hcS]' -print | sort` + ifdef CONFIGURATION ..$(CONFIGURATION): @echo diff --git a/arch/alpha/boot/bootp.c b/arch/alpha/boot/bootp.c index 53425035713a..cb99ffbaaa15 100644 --- a/arch/alpha/boot/bootp.c +++ b/arch/alpha/boot/bootp.c @@ -11,7 +11,6 @@ #include #include #include -#include #include #include diff --git a/arch/i386/boot/compressed/head.S b/arch/i386/boot/compressed/head.S index 6f68a92d4a37..6152881f0e96 100644 --- a/arch/i386/boot/compressed/head.S +++ b/arch/i386/boot/compressed/head.S @@ -28,7 +28,6 @@ .text #define __ASSEMBLY__ -#include #include #include diff --git a/arch/i386/boot/tools/build.c b/arch/i386/boot/tools/build.c index a7e9d063fef7..4e2567a0e95a 100644 --- a/arch/i386/boot/tools/build.c +++ b/arch/i386/boot/tools/build.c @@ -30,10 +30,11 @@ #include #include /* contains read/write */ #include -#include #include +#include #include + #define MINIX_HEADER 32 #define N_MAGIC_OFFSET 1024 diff --git a/arch/i386/kernel/entry.S b/arch/i386/kernel/entry.S index 6e21f9706961..78493d997ba8 100644 --- a/arch/i386/kernel/entry.S +++ b/arch/i386/kernel/entry.S @@ -699,5 +699,12 @@ ENTRY(sys_call_table) .long SYMBOL_NAME(sys_nanosleep) .long SYMBOL_NAME(sys_mremap) .long 0,0 - .long SYMBOL_NAME(sys_vm86) - .space (NR_syscalls-166)*4 + .long SYMBOL_NAME(sys_vm86) /* 166 */ + .long 0 /* 167 */ + .long 0 /* 168 STREAMS poll */ + .long 0 /* 169 */ + .long 0,0,0,0,0,0,0,0,0,0 /* 170 - 179 */ + .long 0,0,0,0,0,0,0,0 /* 180 - 187 */ + .long 0 /* 188 STREAMS getpmsg */ + .long 0 /* 189 STREAMS putpmsg */ + .space (NR_syscalls-189)*4 diff --git a/arch/m68k/amiga/cyberfb.c b/arch/m68k/amiga/cyberfb.c index 9d24b2278372..e83ebe712192 100644 --- a/arch/m68k/amiga/cyberfb.c +++ b/arch/m68k/amiga/cyberfb.c @@ -29,7 +29,6 @@ #include #include #include -#include #include #include #include diff --git a/arch/m68k/atari/atasound.c b/arch/m68k/atari/atasound.c index 59755fff8153..54af31248f82 100644 --- a/arch/m68k/atari/atasound.c +++ b/arch/m68k/atari/atasound.c @@ -17,7 +17,6 @@ for more details. #include #include #include -#include #include #include #include diff --git a/arch/m68k/atari/ksyms.c b/arch/m68k/atari/ksyms.c index 65fd526d34e2..c022ce717ea1 100644 --- a/arch/m68k/atari/ksyms.c +++ b/arch/m68k/atari/ksyms.c @@ -1,4 +1,3 @@ -#include #include #include #include diff --git a/arch/m68k/kernel/sys_m68k.c b/arch/m68k/kernel/sys_m68k.c index 9d330c2237ad..d825bbdafe0b 100644 --- a/arch/m68k/kernel/sys_m68k.c +++ b/arch/m68k/kernel/sys_m68k.c @@ -6,7 +6,6 @@ * platform. */ -#include #include #include #include diff --git a/arch/ppc/kernel/mk_defs.c b/arch/ppc/kernel/mk_defs.c index e63e5c04a516..71dd63d42723 100644 --- a/arch/ppc/kernel/mk_defs.c +++ b/arch/ppc/kernel/mk_defs.c @@ -5,7 +5,6 @@ #define MK_DEFS #include -#include #include #include #include diff --git a/arch/ppc/kernel/pci.c b/arch/ppc/kernel/pci.c index ff50a6c5e644..7135ef08f1b9 100644 --- a/arch/ppc/kernel/pci.c +++ b/arch/ppc/kernel/pci.c @@ -6,7 +6,6 @@ * be worked out to handle the differences. */ -#include #include #include #include diff --git a/arch/ppc/kernel/time.c b/arch/ppc/kernel/time.c index a0e2e05341f8..334df770c0dd 100644 --- a/arch/ppc/kernel/time.c +++ b/arch/ppc/kernel/time.c @@ -26,7 +26,6 @@ #include #include -#include extern int isBeBox[]; diff --git a/arch/ppc/mm/fault.c b/arch/ppc/mm/fault.c index ff7e0b9a8ed2..6d7f274019d0 100644 --- a/arch/ppc/mm/fault.c +++ b/arch/ppc/mm/fault.c @@ -5,7 +5,6 @@ * Ported to PPC by Gary Thomas */ -#include #include #include #include diff --git a/arch/sparc/kernel/ksyms.c b/arch/sparc/kernel/ksyms.c index ee30edf21f21..4704734e23b7 100644 --- a/arch/sparc/kernel/ksyms.c +++ b/arch/sparc/kernel/ksyms.c @@ -4,7 +4,6 @@ * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu) */ -#include #include #include diff --git a/arch/sparc/kernel/sys_sunos.c b/arch/sparc/kernel/sys_sunos.c index af9a480d0ca2..b217a0a9ffdc 100644 --- a/arch/sparc/kernel/sys_sunos.c +++ b/arch/sparc/kernel/sys_sunos.c @@ -26,7 +26,6 @@ * to do the inverse mapping. */ -#include #include #include #include diff --git a/drivers/block/floppy.c b/drivers/block/floppy.c index 6bccc19e18ab..7221187dbeab 100644 --- a/drivers/block/floppy.c +++ b/drivers/block/floppy.c @@ -328,7 +328,7 @@ static struct { 0, { 1, 0, 0, 0, 0, 0, 0, 0}, 3*HZ/2, 1 }, "360K PC" }, /*5 1/4 360 KB PC*/ {{2, 500, 16, 16, 6000, 4*HZ/10, 3*HZ, 14, SEL_DLY, 6, 83, 3*HZ, 17, {3,1,2,0,2}, 0, - 0, { 2, 5, 6,23,10,20,11, 0}, 3*HZ/2, 2 }, "1.2M" }, /*5 1/4 HD AT*/ + 0, { 2, 5, 6,23,10,20,12, 0}, 3*HZ/2, 2 }, "1.2M" }, /*5 1/4 HD AT*/ {{3, 250, 16, 16, 3000, 1*HZ, 3*HZ, 0, SEL_DLY, 5, 83, 3*HZ, 20, {3,1,2,0,2}, 0, 0, { 4,22,21,30, 3, 0, 0, 0}, 3*HZ/2, 4 }, "720k" }, /*3 1/2 DD*/ @@ -3989,6 +3989,8 @@ int floppy_init(void) #endif if (floppy_grab_irq_and_dma()){ + del_timer(&fd_timeout); + blk_dev[MAJOR_NR].request_fn = NULL; unregister_blkdev(MAJOR_NR,"fd"); return -EBUSY; } @@ -4042,6 +4044,17 @@ int floppy_init(void) initialising=0; if (have_no_fdc) { DPRINT("no floppy controllers found\n"); + request_tq.routine = (void *)(void *) empty; + /* + * When we return we may be unloaded. This little + * trick forces the immediate_bh handler to have run + * before we unload it, lest we cause bad things. + */ + mark_bh(IMMEDIATE_BH); + schedule(); + if (usage_count) + floppy_release_irq_and_dma(); + blk_dev[MAJOR_NR].request_fn = NULL; unregister_blkdev(MAJOR_NR,"fd"); } return have_no_fdc; diff --git a/drivers/block/ide.c b/drivers/block/ide.c index bb0f9cabe23f..bb547454aa3a 100644 --- a/drivers/block/ide.c +++ b/drivers/block/ide.c @@ -980,7 +980,7 @@ byte ide_dump_status (ide_drive_t *drive, const char *msg, byte stat) #if FANCY_STATUS_DUMPS if (drive->media == ide_disk) { printk(" { "); - if (err & BBD_ERR) printk("BadSector "); + if (err & ICRC_ERR) printk((err & ABRT_ERR) ? "BadCRC " : "BadSector "); if (err & ECC_ERR) printk("UncorrectableError "); if (err & ID_ERR) printk("SectorIdNotFound "); if (err & ABRT_ERR) printk("DriveStatusError "); diff --git a/drivers/block/md.c b/drivers/block/md.c index 98ffe3a7e12c..3083c59de9dc 100644 --- a/drivers/block/md.c +++ b/drivers/block/md.c @@ -543,7 +543,6 @@ static int md_ioctl (struct inode *inode, struct file *file, RO_IOCTLS(inode->i_rdev,arg); default: - printk ("Unknown md_ioctl %d\n", cmd); return -EINVAL; } diff --git a/drivers/char/cyclades.c b/drivers/char/cyclades.c index 7c5f94efce05..e466469a573e 100644 --- a/drivers/char/cyclades.c +++ b/drivers/char/cyclades.c @@ -1,7 +1,7 @@ #define BLOCKMOVE #define Z_WAKE static char rcsid[] = -"$Revision: 2.1.1.7 $$Date: 1998/08/10 17:01:45 $"; +"$Revision: 2.1.1.8 $$Date: 1998/08/20 17:04:54 $"; /* * linux/drivers/char/cyclades.c @@ -31,6 +31,11 @@ static char rcsid[] = * void cleanup_module(void); * * $Log: cyclades.c,v $ + * Revision 2.1.1.8 1998/08/20 17:04:54 ivan + * Fixed bug in cy_close function, which causes malfunction + * of one of the first 4 ports when a higher port is closed + * (Cyclom-Y only). + * * Revision 2.1.1.7 1998/08/10 17:01:45 ivan * Fixed Cyclom-4Yo hardware detection bug. * @@ -2731,9 +2736,11 @@ cy_close(struct tty_struct * tty, struct file * filp) tty_wait_until_sent(tty, info->closing_wait); if (!IS_CYC_Z(cy_card[info->card])) { - unsigned char *base_addr = (unsigned char *) - cy_card[info->card].base_addr; - int index = cy_card[info->card].bus_index; + int channel = info->line - cy_card[info->card].first_line; + int index = cy_card[info->card].bus_index; + unsigned char *base_addr = (unsigned char *) + (cy_card[info->card].base_addr + + (cy_chip_offset[channel>>2] <comm_baud); if (info->tty){ clear_bit(TTY_IO_ERROR, &info->tty->flags); diff --git a/drivers/char/tga.c b/drivers/char/tga.c index dc6ebb67c7d4..607b908a9788 100644 --- a/drivers/char/tga.c +++ b/drivers/char/tga.c @@ -10,6 +10,7 @@ * This module exports the console io support for DEC's TGA */ +#include /* CONFIG_VGA_CONSOLE */ #include #include #include diff --git a/drivers/isdn/hisax/elsa_ser.c b/drivers/isdn/hisax/elsa_ser.c index f5d96ccdeb37..49b1dc1b3701 100644 --- a/drivers/isdn/hisax/elsa_ser.c +++ b/drivers/isdn/hisax/elsa_ser.c @@ -1,3 +1,4 @@ +#include /* CONFIG_SERIAL_NOPAUSE_IO */ #include #include diff --git a/drivers/isdn/icn/icn.c b/drivers/isdn/icn/icn.c index 81cf94a5ddd7..dd9ad7336ab1 100644 --- a/drivers/isdn/icn/icn.c +++ b/drivers/isdn/icn/icn.c @@ -199,6 +199,7 @@ * */ +#include /* CONFIG_ISDN_WITH_ABC */ #include "icn.h" /* diff --git a/drivers/isdn/isdn_common.h b/drivers/isdn/isdn_common.h index b90d879f7a36..cf668dfff8e2 100644 --- a/drivers/isdn/isdn_common.h +++ b/drivers/isdn/isdn_common.h @@ -47,6 +47,7 @@ * */ +#include /* CONFIG_ISDN_TIMEOUT_RULES */ #undef ISDN_DEBUG_MODEM_OPEN #undef ISDN_DEBUG_MODEM_IOCTL #undef ISDN_DEBUG_MODEM_WAITSENT diff --git a/drivers/isdn/isdn_syms.c b/drivers/isdn/isdn_syms.c index 567f8dda95bf..e0561aa74474 100644 --- a/drivers/isdn/isdn_syms.c +++ b/drivers/isdn/isdn_syms.c @@ -21,7 +21,7 @@ * Added GPL-Header, Id and Log * */ -#include + #include #include diff --git a/drivers/isdn/isdnloop/isdnloop.h b/drivers/isdn/isdnloop/isdnloop.h index 3dbd3fba0dec..987431ef1d31 100644 --- a/drivers/isdn/isdnloop/isdnloop.h +++ b/drivers/isdn/isdnloop/isdnloop.h @@ -48,7 +48,6 @@ typedef struct isdnloop_sdef { #ifdef __KERNEL__ /* Kernel includes */ -#include #include #include #include diff --git a/drivers/net/3c515.c b/drivers/net/3c515.c index 634941c935b9..a283babdef7f 100644 --- a/drivers/net/3c515.c +++ b/drivers/net/3c515.c @@ -39,7 +39,6 @@ static int max_interrupt_work = 20; #define RX_RING_SIZE 16 #define PKT_BUF_SZ 1536 /* Size of each temporary Rx buffer.*/ -#include #ifdef MODULE #ifdef MODVERSIONS #include diff --git a/drivers/net/Config.in b/drivers/net/Config.in index 4f317160d503..512c03243b53 100644 --- a/drivers/net/Config.in +++ b/drivers/net/Config.in @@ -46,7 +46,6 @@ if [ "$CONFIG_NET_RADIO" != "n" ]; then tristate 'Z8530 SCC KISS emulation driver for AX.25' CONFIG_SCC tristate 'STRIP (Metricom starmode radio IP)' CONFIG_STRIP tristate 'AT&T WaveLAN & DEC RoamAbout DS support' CONFIG_WAVELAN - tristate 'WIC Radio IP bridge (EXPERIMENTAL)' CONFIG_WIC fi # # Ethernet diff --git a/drivers/net/Makefile b/drivers/net/Makefile index 986ec3120aef..a5760632c353 100644 --- a/drivers/net/Makefile +++ b/drivers/net/Makefile @@ -81,14 +81,6 @@ else endif endif -ifeq ($(CONFIG_WIC),y) -L_OBJS += wic.o -else - ifeq ($(CONFIG_WIC),m) - M_OBJS += wic.o - endif -endif - ifeq ($(CONFIG_SMC9194),y) L_OBJS += smc9194.o else diff --git a/drivers/net/Space.c b/drivers/net/Space.c index 680c253c0dd6..04a259118375 100644 --- a/drivers/net/Space.c +++ b/drivers/net/Space.c @@ -92,6 +92,8 @@ extern int lance_probe(struct device *); extern int atp_init(struct device *); extern int de600_probe(struct device *); extern int de620_probe(struct device *); +/* The shaper hook */ +extern int shaper_probe(struct device *); static int ethif_probe(struct device *dev) @@ -360,6 +362,13 @@ static struct device strip_bootstrap = { #define NEXT_DEV (&strip_bootstrap) #endif /* STRIP */ +#if defined(CONFIG_SHAPER) +static struct device shaper_bootstrap = { + "shaper", 0x0, 0x0, 0x0, 0x0, 0, 0, 0, 0, 0, NEXT_DEV, shaper_probe, }; +#undef NEXT_DEV +#define NEXT_DEV (&shaper_bootstrap) +#endif /* STRIP */ + #if defined(CONFIG_PPP) extern int ppp_init(struct device *); static struct device ppp_bootstrap = { diff --git a/drivers/net/eepro100.c b/drivers/net/eepro100.c index d4f10d83b67e..a6f8b3adc5ec 100644 --- a/drivers/net/eepro100.c +++ b/drivers/net/eepro100.c @@ -41,7 +41,6 @@ static int max_interrupt_work = 20; /* Maximum number of multicast addresses to filter (vs. rx-all-multicast) */ static int multicast_filter_limit = 64; -#include #ifdef MODULE #ifdef MODVERSIONS #include diff --git a/drivers/net/epic100.c b/drivers/net/epic100.c index 2d0f8b4f11e0..3cdf668a4a5c 100644 --- a/drivers/net/epic100.c +++ b/drivers/net/epic100.c @@ -46,7 +46,6 @@ static int max_interrupt_work = 10; #define TX_FIFO_THRESH 128 /* Rounded down to 4 byte units. */ #define RX_FIFO_THRESH 1 /* 0-3, 0==32, 64,96, or 3==128 bytes */ -#include #ifdef MODULE #ifdef MODVERSIONS #include diff --git a/drivers/net/lance.c b/drivers/net/lance.c index ac5f0aef6654..d64ebf5eb058 100644 --- a/drivers/net/lance.c +++ b/drivers/net/lance.c @@ -360,7 +360,7 @@ cleanup_module(void) if (dev->priv != NULL) { kfree(dev->priv); dev->priv = NULL; - free_irq(dev->irq, NULL); + free_dma(dev->dma); release_region(dev->base_addr, LANCE_TOTAL_SIZE); unregister_netdev(dev); } diff --git a/drivers/net/ne2k-pci.c b/drivers/net/ne2k-pci.c index b2113e0c4b5f..3aa556fdf17e 100644 --- a/drivers/net/ne2k-pci.c +++ b/drivers/net/ne2k-pci.c @@ -30,7 +30,6 @@ static const char *version = #include #endif #include -#include #include #include #include diff --git a/drivers/net/pcnet32.c b/drivers/net/pcnet32.c index 85e6711d4837..64828b323135 100644 --- a/drivers/net/pcnet32.c +++ b/drivers/net/pcnet32.c @@ -27,7 +27,6 @@ static int max_interrupt_work = 20; #define PCNET_LOG_TX_BUFFERS 4 #define PCNET_LOG_RX_BUFFERS 4 -#include #ifdef MODULE #ifdef MODVERSIONS #include diff --git a/drivers/net/rtl8139.c b/drivers/net/rtl8139.c index 936ae91d7e63..b5c355bdb7d5 100644 --- a/drivers/net/rtl8139.c +++ b/drivers/net/rtl8139.c @@ -45,7 +45,6 @@ static int max_interrupt_work = 10; /* Time in jiffies before concluding the transmitter is hung. */ #define TX_TIMEOUT ((4000*HZ)/1000) -#include #ifdef MODULE #ifdef MODVERSIONS #include diff --git a/drivers/net/strip.c b/drivers/net/strip.c index 834035151ca4..f4df05bf77aa 100644 --- a/drivers/net/strip.c +++ b/drivers/net/strip.c @@ -81,8 +81,6 @@ static const char StripVersion[] = "1.3-STUART.CHESHIRE"; /************************************************************************/ /* Header files */ -#include - #ifdef MODULE #include #include diff --git a/drivers/net/wic.c b/drivers/net/wic.c deleted file mode 100644 index 5530b3694ce9..000000000000 --- a/drivers/net/wic.c +++ /dev/null @@ -1,1459 +0,0 @@ -/* $Id: wic.c,v 1.3.2.1 1997/03/09 02:14:40 davem Exp $ */ -/* WIC: A parallel port "network" driver for Linux. */ -/* based on the plip network driver */ -/* Modified for Linux 1.3.x by Alan Cox */ - -char *version = "NET3 WIC version 0.9 hayes@netplumbing.com"; - -/* - Sources: - Ideas and protocols came from Russ Nelson's - "parallel.asm" parallel port packet driver and from the plip.c - parallel networking linux driver from the 1.2.13 Linux - distribution. - - The packet is encapsulated as if it were ethernet. - -*/ - -#ifdef MODULE -#include -#include -#else -#define MOD_INC_USE_COUNT -#define MOD_DEC_USE_COUNT -#endif - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#define NET_DEBUG 1 -/* Use 0 for production, 1 for verification, >2 for debug */ -#ifndef NET_DEBUG -#define NET_DEBUG 1 -#endif -unsigned int net_debug = NET_DEBUG; - -/* Connection time out = WIC_TRIGGER_WAIT * WIC_DELAY_UNIT usec */ -#define WIC_TRIGGER_WAIT 500 - -/* Nibble time out = WIC_NIBBLE_WAIT * WIC_DELAY_UNIT usec */ -#define WIC_NIBBLE_WAIT 3000 - -#define PAR_DATA(dev) ((dev)->base_addr+0) -#define PAR_STATUS(dev) ((dev)->base_addr+1) -#define PAR_CONTROL(dev) ((dev)->base_addr+2) - -/* Bottom halfs */ -void wic_kick_bh(struct device *dev); -void wic_bh(struct device *dev); - -/* Interrupt handler */ -void wic_interrupt(int irq, void *dev_ptr, struct pt_regs *regs); - -/* Functions for DEV methods */ -int wic_rebuild_header(void *buff, struct device *dev, - unsigned long raddr, struct sk_buff *skb); -int wic_tx_packet(struct sk_buff *skb, struct device *dev); -int wic_open(struct device *dev); -int wic_close(struct device *dev); -struct enet_statistics *wic_get_stats(struct device *dev); -int wic_config(struct device *dev, struct ifmap *map); -int wic_ioctl(struct device *dev, struct ifreq *ifr, int cmd); -int send_cmd(struct device *dev, unsigned char *cmd, char len); -int recv_cmd_resp(struct device *dev, unsigned char *cmd); -int send_byte(struct device *dev, unsigned char c); -int get_byte(struct device *dev, unsigned char *c); -int ack_resp(struct device *dev); -int check_bfr(struct device *dev); -void wic_reset(struct device *dev); -void wic_set_multicast_list(struct device *dev); - -#define LOOPCNT 30000 -unsigned char tog = 3; -unsigned char save = 0; - -enum wic_connection_state { - WIC_CN_NONE=0, - WIC_CN_RECEIVE, - WIC_CN_SEND, - WIC_CN_CLOSING, - WIC_CN_ERROR -}; - -enum wic_packet_state { - WIC_PK_DONE=0, - WIC_PK_TRIGGER, - WIC_PK_LENGTH_LSB, - WIC_PK_LENGTH_MSB, - WIC_PK_DATA, - WIC_PK_CHECKSUM -}; - -enum wic_nibble_state { - WIC_NB_BEGIN, - WIC_NB_1, - WIC_NB_2, -}; - -struct wic_local { - enum wic_packet_state state; - enum wic_nibble_state nibble; - union { - struct { -#if defined(__LITTLE_ENDIAN) - unsigned char lsb; - unsigned char msb; -#elif defined(__BIG_ENDIAN) - unsigned char msb; - unsigned char lsb; -#else -#error "Please fix the endianness defines in " -#endif - } b; - unsigned short h; - } length; - unsigned short byte; - unsigned char checksum; - unsigned char data; - struct sk_buff *skb; -}; - -struct net_local { - struct enet_statistics enet_stats; - struct tq_struct immediate; - struct tq_struct deferred; - struct wic_local snd_data; - struct wic_local rcv_data; - unsigned long trigger; - unsigned long nibble; - enum wic_connection_state connection; - unsigned short timeout_count; - char is_deferred; - int (*orig_rebuild_header)(void *eth, struct device *dev, - unsigned long raddr, struct sk_buff *skb); -}; - -/* Entry point of WIC driver. - Probe the hardware, and register/initialize the driver. */ -int -wic_init(struct device *dev) -{ - struct net_local *nl; - struct wicconf wc; - int i; - - /* Check region before the probe */ - if (check_region(PAR_DATA(dev), 3) < 0) - return -ENODEV; - - /* Check that there is something at base_addr. */ - outb(0, PAR_DATA(dev)); - udelay(1000); - if (inb(PAR_DATA(dev)) != 0) - return -ENODEV; - - printk("%s\n",version); - printk("%s: Parallel port at %#3lx, ", dev->name, dev->base_addr); - if (dev->irq) { - printk("using assigned IRQ %d.\n", dev->irq); - } else { - int irq = 0; -#ifdef MODULE - /* dev->irq==0 means autoprobe, but we don't try to do so - with module. We can change it by ifconfig */ -#else - unsigned int irqs = probe_irq_on(); - - outb(0x00, PAR_CONTROL(dev)); - udelay(1000); - udelay(1000); - irq = probe_irq_off(irqs); -#endif - if (irq > 0) { - dev->irq = irq; - printk("using probed IRQ %d.\n", dev->irq); - } else - printk("failed to detect IRQ(%d) --" - " Please set IRQ by ifconfig.\n", irq); - } - - request_region(PAR_DATA(dev), 3, dev->name); - - /* Fill in the generic fields of the device structure. */ - ether_setup(dev); - - /* Then, override parts of it */ - dev->hard_start_xmit = wic_tx_packet; - dev->open = wic_open; - dev->stop = wic_close; - dev->get_stats = wic_get_stats; - dev->set_config = wic_config; - dev->do_ioctl = wic_ioctl; - dev->mtu = 1514; - dev->set_multicast_list = wic_set_multicast_list; - dev->flags = IFF_BROADCAST | IFF_RUNNING | IFF_NOTRAILERS; - - /* get the MAC address from the controller */ - wc.len = 1; - wc.pcmd = WIC_GETNET; - check_bfr(dev); - send_cmd(dev, (unsigned char *)&wc, 1); - wc.len = recv_cmd_resp(dev, (unsigned char *)&wc.data); - while ((wc.len == 1) && (wc.data[0] == 0x7)) /* controller int */ - wc.len = recv_cmd_resp(dev, (unsigned char *)&wc.data); - - printk("%s:MAC address: ",dev->name); - for (i=0; i < ETH_ALEN ; i++) { - dev->dev_addr[i] = wc.data[i]; - printk("%2x ",dev->dev_addr[i]); - } - printk("\n"); - - /* Set the private structure */ - dev->priv = kmalloc(sizeof (struct net_local), GFP_KERNEL); - if (dev->priv == NULL) - return EAGAIN; - memset(dev->priv, 0, sizeof(struct net_local)); - nl = (struct net_local *) dev->priv; - - nl->orig_rebuild_header = dev->rebuild_header; - dev->rebuild_header = wic_rebuild_header; - - /* Initialize constants */ - nl->trigger = WIC_TRIGGER_WAIT; - nl->nibble = WIC_NIBBLE_WAIT; - - /* Initialize task queue structures */ - nl->immediate.next = NULL; - nl->immediate.sync = 0; - nl->immediate.routine = (void *)(void *)wic_bh; - nl->immediate.data = dev; - - nl->deferred.next = NULL; - nl->deferred.sync = 0; - nl->deferred.routine = (void *)(void *)wic_kick_bh; - nl->deferred.data = dev; - - return 0; -} - -/* Bottom half handler for the delayed request. - This routine is kicked by do_timer(). - Request `wic_bh' to be invoked. */ -void -wic_kick_bh(struct device *dev) -{ - struct net_local *nl = (struct net_local *)dev->priv; - - if (nl->is_deferred) { - queue_task(&nl->immediate, &tq_immediate); - mark_bh(IMMEDIATE_BH); - } -} - -/* Forward declarations of internal routines */ -int wic_none(struct device *, struct net_local *, - struct wic_local *, struct wic_local *); -int wic_receive_packet(struct device *, struct net_local *, - struct wic_local *, struct wic_local *); -int wic_send_packet(struct device *, struct net_local *, - struct wic_local *, struct wic_local *); -int wic_connection_close(struct device *, struct net_local *, - struct wic_local *, struct wic_local *); -int wic_error(struct device *, struct net_local *, - struct wic_local *, struct wic_local *); -int wic_bh_timeout_error(struct device *dev, struct net_local *nl, - struct wic_local *snd, - struct wic_local *rcv, - int error); - -#define OK 0 -#define TIMEOUT 1 -#define ERROR 2 - -typedef int (*wic_func)(struct device *dev, struct net_local *nl, - struct wic_local *snd, struct wic_local *rcv); - -wic_func connection_state_table[] = -{ - wic_none, - wic_receive_packet, - wic_send_packet, - wic_connection_close, - wic_error -}; - -void -wic_set_multicast_list(struct device *dev) -{ - struct wicconf wc; - struct wic_net *wn; - - disable_irq(dev->irq); - save &= 0xef; /* disable */ - outb(save, PAR_CONTROL(dev)); - - wc.len = 1; - wc.pcmd = WIC_GETNET; - check_bfr(dev); - tog = 3; - send_cmd(dev, (unsigned char *)&wc, 1); - wc.len = recv_cmd_resp(dev, (unsigned char *)&wc.data); - while ((wc.len == 1) && (wc.data[0] == 0x7)) /* controller int */ - wc.len = recv_cmd_resp(dev, (unsigned char *)&wc.data); - wn = (struct wic_net *)&wc.data; - if(dev->flags&IFF_PROMISC) - { - /* promiscuous mode */ - wn->mode |= (NET_MODE_ME | NET_MODE_BCAST | - NET_MODE_MCAST | NET_MODE_PROM); - printk("%s: Setting promiscuous mode\n", dev->name); - } - else if((dev->flags&IFF_ALLMULTI) || dev->mc_count) - { - wn->mode &= ~NET_MODE_PROM; - wn->mode |= (NET_MODE_MCAST | NET_MODE_ME | NET_MODE_BCAST); - } - else - { - wn->mode &= ~(NET_MODE_PROM | NET_MODE_MCAST); - wn->mode |= (NET_MODE_ME | NET_MODE_BCAST); - } - wc.len = 23; - wc.pcmd = WIC_SETNET; - check_bfr(dev); - tog = 3; - send_cmd(dev, (unsigned char *)&wc, wc.len); - - save |= 0x10; /* enable */ - outb(save, PAR_CONTROL(dev)); - enable_irq(dev->irq); - return; -} - -/* Bottom half handler of WIC. */ -void -wic_bh(struct device *dev) -{ - struct net_local *nl = (struct net_local *)dev->priv; - struct wic_local *snd = &nl->snd_data; - struct wic_local *rcv = &nl->rcv_data; - wic_func f; - int r; - - nl->is_deferred = 0; - f = connection_state_table[nl->connection]; - if ((r = (*f)(dev, nl, snd, rcv)) != OK - && (r = wic_bh_timeout_error(dev, nl, snd, rcv, r)) != OK) { - nl->is_deferred = 1; - queue_task(&nl->deferred, &tq_timer); - } -} - -int -wic_bh_timeout_error(struct device *dev, struct net_local *nl, - struct wic_local *snd, struct wic_local *rcv, - int error) -{ - unsigned char c0; - unsigned long flags; - - save_flags(flags); - cli(); - if (nl->connection == WIC_CN_SEND) { - - if (error != ERROR) { /* Timeout */ - nl->timeout_count++; - if ((snd->state == WIC_PK_TRIGGER - && nl->timeout_count <= 10) - || nl->timeout_count <= 3) { - restore_flags(flags); - /* Try again later */ - return TIMEOUT; - } - c0 = inb(PAR_STATUS(dev)); - printk("%s: transmit timeout(%d,%02x)\n", - dev->name, snd->state, c0); - } - nl->enet_stats.tx_errors++; - nl->enet_stats.tx_aborted_errors++; - } else if (nl->connection == WIC_CN_RECEIVE) { - if (rcv->state == WIC_PK_TRIGGER) { - /* Transmission was interrupted. */ - restore_flags(flags); - return OK; - } - if (error != ERROR) { /* Timeout */ - if (++nl->timeout_count <= 3) { - restore_flags(flags); - /* Try again later */ - return TIMEOUT; - } - c0 = inb(PAR_STATUS(dev)); - printk("%s: receive timeout(%d,%02x)\n", - dev->name, rcv->state, c0); - } - nl->enet_stats.rx_dropped++; - } - rcv->state = WIC_PK_DONE; - if (rcv->skb) { - rcv->skb->free = 1; - kfree_skb(rcv->skb, FREE_READ); - rcv->skb = NULL; - } - snd->state = WIC_PK_DONE; - if (snd->skb) { - snd->skb->free = 1; - dev_kfree_skb(snd->skb, FREE_WRITE); - snd->skb = NULL; - } -#if (0) - disable_irq(dev->irq); - save &= 0xef; /* disable */ - outb(save, PAR_CONTROL(dev)); - dev->tbusy = 1; - outb(0x00, PAR_DATA(dev)); -#endif /* (0) */ - nl->connection = WIC_CN_ERROR; - restore_flags(flags); - - return TIMEOUT; -} - -int -wic_none(struct device *dev, struct net_local *nl, - struct wic_local *snd, struct wic_local *rcv) -{ - return OK; -} - -/* WIC_RECEIVE --- receive a byte(two nibbles) - Returns OK on success, TIMEOUT on timeout */ -inline int -wic_receive(unsigned short nibble_timeout, unsigned short status_addr, - enum wic_nibble_state *ns_p, unsigned char *data_p) -{ -unsigned int cx; - - cx = LOOPCNT; - while ((inb(status_addr) & 0x08) != ((tog<<3) & 0x08)) { - if (--cx == 0) { - return TIMEOUT; - } - } - *data_p = inb(status_addr-1); - tog ^= 0x01; - outb(tog| save, status_addr+1); - return OK; -} - -/* WIC_RECEIVE_PACKET --- receive a packet */ -int -wic_receive_packet(struct device *dev, struct net_local *nl, - struct wic_local *snd, struct wic_local *rcv) -{ - unsigned short status_addr = PAR_STATUS(dev); - unsigned short nibble_timeout = nl->nibble; - unsigned char *lbuf; - unsigned char junk; - unsigned long flags; - - save_flags(flags); - cli(); - switch (rcv->state) { - case WIC_PK_TRIGGER: - disable_irq(dev->irq); - save &= 0xef; /* disable */ - outb(save, PAR_CONTROL(dev)); - - dev->interrupt = 0; - - tog &= 0xfe; - ack_resp(dev); - if (net_debug > 2) - printk("%s: receive start\n", dev->name); - rcv->state = WIC_PK_LENGTH_LSB; - rcv->nibble = WIC_NB_BEGIN; - - case WIC_PK_LENGTH_LSB: - if (net_debug > 2) - printk("%s: WIC_PK_LENGTH_LSB\n", dev->name); - if (snd->state != WIC_PK_DONE) { - if (wic_receive(nl->trigger, status_addr, - &rcv->nibble, &rcv->length.b.lsb)) { - /* collision, here dev->tbusy == 1 */ - rcv->state = WIC_PK_DONE; - nl->is_deferred = 1; - nl->connection = WIC_CN_SEND; - restore_flags(flags); - queue_task(&nl->deferred, &tq_timer); - save |= 0x10; /* enable */ - outb(save, PAR_CONTROL(dev)); - enable_irq(dev->irq); - return OK; - } - } else { - if (wic_receive(nibble_timeout, status_addr, - &rcv->nibble, &rcv->length.b.lsb)) { - restore_flags(flags); - return TIMEOUT; - } - } - rcv->state = WIC_PK_LENGTH_MSB; - - case WIC_PK_LENGTH_MSB: - if (net_debug > 2) - printk("%s: WIC_PK_LENGTH_MSB\n", dev->name); - if (wic_receive(nibble_timeout, status_addr, - &rcv->nibble, &rcv->length.b.msb)) { - restore_flags(flags); - return TIMEOUT; - } - if (rcv->length.h > dev->mtu || rcv->length.h < 8) { - printk("%s: bad packet size %d.\n", dev->name, rcv->length.h); - restore_flags(flags); - return ERROR; - } - /* Malloc up new buffer. */ - rcv->skb = dev_alloc_skb(rcv->length.h); - if (rcv->skb == NULL) { - printk("%s: Memory squeeze.\n", dev->name); - restore_flags(flags); - return ERROR; - } - skb_put(rcv->skb,rcv->length.h); - rcv->skb->dev = dev; - - rcv->state = WIC_PK_DATA; - rcv->byte = 0; - rcv->checksum = 0; - - /* sequence numbers */ - if (net_debug > 2) - printk("%s: WIC_PK_SEQ\n", dev->name); - if (wic_receive(nibble_timeout, status_addr, - &rcv->nibble, &junk)) { - restore_flags(flags); - return TIMEOUT; - } - if (wic_receive(nibble_timeout, status_addr, - &rcv->nibble, &junk)) { - restore_flags(flags); - return TIMEOUT; - } - - case WIC_PK_DATA: - if (net_debug > 2) - printk("%s: WIC_PK_DATA: length %i\n", dev->name, - rcv->length.h); - lbuf = rcv->skb->data; - do { - if (wic_receive(nibble_timeout, status_addr, - &rcv->nibble, &lbuf[rcv->byte])) { - restore_flags(flags); - return TIMEOUT; - } - } while (++rcv->byte < (rcv->length.h - 4)); - - /* receive pad byte */ - if (rcv->length.h & 0x01) - wic_receive(nibble_timeout, status_addr, - &rcv->nibble, &lbuf[rcv->byte]); - - do { - rcv->checksum += lbuf[--rcv->byte]; - } while (rcv->byte); - - rcv->state = WIC_PK_CHECKSUM; - - case WIC_PK_CHECKSUM: - if (net_debug > 2) - printk("%s: WIC_PK_CHECKSUM\n", dev->name); - if (wic_receive(nibble_timeout, status_addr, - &rcv->nibble, &junk)) { - restore_flags(flags); - return TIMEOUT; - } - outb(0, PAR_DATA(dev)); - rcv->state = WIC_PK_DONE; - - case WIC_PK_DONE: - if (net_debug > 2) - printk("%s: WIC_PK_DONE\n", dev->name); - /* Inform the upper layer for the arrival of a packet. */ - netif_rx(rcv->skb); - nl->enet_stats.rx_packets++; - rcv->skb = NULL; - if (net_debug > 2) - printk("%s: receive end\n", dev->name); - - /* Close the connection. */ - if (snd->state != WIC_PK_DONE) { - nl->connection = WIC_CN_SEND; - restore_flags(flags); - queue_task(&nl->immediate, &tq_immediate); - save |= 0x10; /* enable */ - outb(save, PAR_CONTROL(dev)); - enable_irq(dev->irq); - return OK; - } else { - nl->connection = WIC_CN_NONE; - restore_flags(flags); - save |= 0x10; /* enable */ - outb(save, PAR_CONTROL(dev)); - enable_irq(dev->irq); - return OK; - } - } - restore_flags(flags); - return OK; -} - -/* WIC_SEND --- send a byte (two nibbles) - Returns OK on success, TIMEOUT when timeout */ -inline int -wic_send(unsigned short nibble_timeout, unsigned short data_addr, - enum wic_nibble_state *ns_p, unsigned char data) -{ -unsigned int cx; - - cx = LOOPCNT; - while ((inb(data_addr+1) & 0x80) == ((tog<<7) & 0x80)) { - if (--cx == 0) { - return -TIMEOUT; - } - } - outb(data, data_addr); - outb(tog | save, data_addr+2); - tog ^= 0x01; - return OK; -} - -/* WIC_SEND_PACKET --- send a packet */ -int -wic_send_packet(struct device *dev, struct net_local *nl, - struct wic_local *snd, struct wic_local *rcv) -{ - unsigned short data_addr = PAR_DATA(dev); - unsigned short nibble_timeout = nl->nibble; - unsigned char *lbuf; - unsigned int cx; - unsigned int pad = 2; - unsigned long flags; - - if (snd->skb == NULL || (lbuf = snd->skb->data) == NULL) { - printk("%s: send skb lost\n", dev->name); - snd->state = WIC_PK_DONE; - snd->skb = NULL; - save |= 0x10; /* enable */ - outb(save, PAR_CONTROL(dev)); - enable_irq(dev->irq); - return ERROR; - } - - save_flags(flags); - cli(); - switch (snd->state) { - case WIC_PK_TRIGGER: - - if (nl->connection == WIC_CN_RECEIVE) { - /* interrupted */ - nl->enet_stats.collisions++; - restore_flags(flags); - if (net_debug > 1) - printk("%s: collision.\n", dev->name); - save |= 0x10; /* enable */ - outb(save, PAR_CONTROL(dev)); - enable_irq(dev->irq); - return OK; - } - - disable_irq(dev->irq); - save &= 0xef; /* disable */ - outb(save, PAR_CONTROL(dev)); - - /* interrupt controller */ - tog = 3; - outb(0x06 | save, PAR_CONTROL(dev)); - - cx = LOOPCNT; - while ((inb(PAR_STATUS(dev)) & 0xe8) != 0xc0) { - if (--cx == 0) { - restore_flags(flags); - return TIMEOUT; - } - if (cx == 10) - outb(0x02, PAR_CONTROL(dev)); - } - - if (net_debug > 2) - printk("%s: send start\n", dev->name); - snd->state = WIC_PK_LENGTH_LSB; - snd->nibble = WIC_NB_BEGIN; - nl->timeout_count = 0; - - case WIC_PK_LENGTH_LSB: - if (snd->length.h & 0x01) - pad = 3; - else - pad = 2; - snd->length.h += (4 + pad); /* len + seq + data + pad */ - if (net_debug > 2) - printk("%s: WIC_PK_LENGTH_LSB: length = %i\n", - dev->name, snd->length.h); - - if (wic_send(nibble_timeout, data_addr, - &snd->nibble, snd->length.b.lsb)) { - restore_flags(flags); - return TIMEOUT; - } - snd->state = WIC_PK_LENGTH_MSB; - - case WIC_PK_LENGTH_MSB: - if (net_debug > 2) - printk("%s: WIC_PK_LENGTH_MSB\n", dev->name); - if (wic_send(nibble_timeout, data_addr, - &snd->nibble, snd->length.b.msb)) { - restore_flags(flags); - return TIMEOUT; - } - snd->state = WIC_PK_DATA; - snd->byte = 0; - snd->checksum = 0; - - case WIC_PK_DATA: - /* adjust length back to data only */ - snd->length.h -= (4 + pad); /* len + seq + data + pad */ - /* send 2 byte sequence number */ - if (net_debug > 2) - printk("%s: WIC_SEQ\n", dev->name); - if (wic_send(nibble_timeout, data_addr, - &snd->nibble, 0)) { - restore_flags(flags); - return TIMEOUT; - } - if (wic_send(nibble_timeout, data_addr, - &snd->nibble, 0)) { - restore_flags(flags); - return TIMEOUT; - } - if (net_debug > 2) - printk("%s: WIC_PK_DATA\n", dev->name); - - do { - if (wic_send(nibble_timeout, data_addr, - &snd->nibble, lbuf[snd->byte])) { - restore_flags(flags); - return TIMEOUT; - } - } - while (++snd->byte < snd->length.h); - - do - snd->checksum += lbuf[--snd->byte]; - while (snd->byte); - - snd->state = WIC_PK_CHECKSUM; - - case WIC_PK_CHECKSUM: - /* send pad bytes */ - if (net_debug > 2) - printk("%s: WIC_PK_PAD: %i bytes\n", - dev->name, pad); - while(pad--) - if (wic_send(nibble_timeout, data_addr, - &snd->nibble, 0)) { - restore_flags(flags); - return TIMEOUT; - } - dev_kfree_skb(snd->skb, FREE_WRITE); - nl->enet_stats.tx_packets++; - snd->state = WIC_PK_DONE; - - case WIC_PK_DONE: - if (net_debug > 2) - printk("%s: WIC_PK_DONE\n", dev->name); - /* Close the connection */ - outb (0x00, PAR_DATA(dev)); - outb(save, PAR_CONTROL(dev)); - - snd->skb = NULL; - if (net_debug > 2) - printk("%s: send end\n", dev->name); - nl->connection = WIC_CN_CLOSING; - nl->is_deferred = 1; - restore_flags(flags); - queue_task(&nl->deferred, &tq_timer); - save |= 0x10; /* enable */ - outb(save, PAR_CONTROL(dev)); - enable_irq(dev->irq); - return OK; - } - restore_flags(flags); - return OK; -} - -int -wic_connection_close(struct device *dev, struct net_local *nl, - struct wic_local *snd, struct wic_local *rcv) -{ -unsigned long flags; - - save_flags(flags); - cli(); - if (nl->connection == WIC_CN_CLOSING) { - nl->connection = WIC_CN_NONE; - dev->tbusy = 0; - mark_bh(NET_BH); - } - restore_flags(flags); - return OK; -} - -/* WIC_ERROR --- wait till other end settled */ -int -wic_error(struct device *dev, struct net_local *nl, - struct wic_local *snd, struct wic_local *rcv) -{ - unsigned char status; - - status = inb(PAR_STATUS(dev)); - if ((status & 0xf8) == 0x80) { - if (net_debug > 2) - printk("%s: reset interface.\n", dev->name); - nl->connection = WIC_CN_NONE; - dev->tbusy = 0; - dev->interrupt = 0; - save |= 0x10; /* enable */ - outb(save, PAR_CONTROL(dev)); - enable_irq(dev->irq); - mark_bh(NET_BH); - } else { - nl->is_deferred = 1; - queue_task(&nl->deferred, &tq_timer); - } - - return OK; -} - -/* Handle the parallel port interrupts. */ -void -wic_interrupt(int irq, void *dev_ptr, struct pt_regs * regs) -{ - struct device *dev = (struct device *) irq2dev_map[irq]; - struct net_local *nl = (struct net_local *)dev->priv; - struct wic_local *rcv = &nl->rcv_data; - unsigned long flags; - - if (dev == NULL) { - printk ("wic_interrupt: irq %d for unknown device.\n", irq); - return; - } - - if (dev->interrupt) { - return; - } - - if (check_bfr(dev) < 0) { - return; - } - - dev->interrupt = 1; - if (net_debug > 3) - printk("%s: interrupt.\n", dev->name); - - save_flags(flags); - cli(); - switch (nl->connection) { - case WIC_CN_CLOSING: - dev->tbusy = 0; - case WIC_CN_NONE: - case WIC_CN_SEND: - dev->last_rx = jiffies; - rcv->state = WIC_PK_TRIGGER; - nl->connection = WIC_CN_RECEIVE; - nl->timeout_count = 0; - restore_flags(flags); - queue_task(&nl->immediate, &tq_immediate); - mark_bh(IMMEDIATE_BH); - break; - - case WIC_CN_RECEIVE: - printk("%s: receive interrupt when receiving packet\n", dev->name); - restore_flags(flags); - break; - - case WIC_CN_ERROR: - printk("%s: receive interrupt in error state\n", dev->name); - restore_flags(flags); - break; - } -} - -int -wic_rebuild_header(void *buff, struct device *dev, unsigned long dst, - struct sk_buff *skb) -{ - struct net_local *nl = (struct net_local *)dev->priv; - struct ethhdr *eth = (struct ethhdr *)buff; - int i; - - if ((dev->flags & IFF_NOARP)==0) - return nl->orig_rebuild_header(buff, dev, dst, skb); - - if (eth->h_proto != htons(ETH_P_IP)) { - printk("wic_rebuild_header: Don't know how to resolve type %d addresses?\n", (int)eth->h_proto); - memcpy(eth->h_source, dev->dev_addr, dev->addr_len); - return 0; - } - - for (i=0; i < ETH_ALEN - sizeof(unsigned long); i++) - eth->h_dest[i] = 0xfc; - memcpy(&(eth->h_dest[i]), &dst, sizeof(unsigned long)); - return 0; -} - -int -wic_tx_packet(struct sk_buff *skb, struct device *dev) -{ - struct net_local *nl = (struct net_local *)dev->priv; - struct wic_local *snd = &nl->snd_data; - unsigned long flags; - - if (dev->tbusy) - return 1; - - /* If some higher layer thinks we've missed an tx-done interrupt - we are passed NULL. Caution: dev_tint() handles the cli()/sti() - itself. */ - if (skb == NULL) { - dev_tint(dev); - return 0; - } - - if (set_bit(0, (void*)&dev->tbusy) != 0) { - printk("%s: Transmitter access conflict.\n", dev->name); - return 1; - } - - if (skb->len > dev->mtu) { - printk("%s: packet too big, %d.\n", dev->name, (int)skb->len); - dev->tbusy = 0; - dev_kfree_skb(skb, FREE_WRITE); - return 0; - } - - if (net_debug > 2) - printk("%s: send request\n", dev->name); - - save_flags(flags); - cli(); - dev->trans_start = jiffies; - snd->skb = skb; - snd->length.h = skb->len; - snd->state = WIC_PK_TRIGGER; - if (nl->connection == WIC_CN_NONE) { - nl->connection = WIC_CN_SEND; - nl->timeout_count = 0; - } - restore_flags(flags); - queue_task(&nl->immediate, &tq_immediate); - mark_bh(IMMEDIATE_BH); - - return 0; -} - -/* Open/initialize the board. This is called (in the current kernel) - sometime after booting when the 'ifconfig' program is run. - - This routine gets exclusive access to the parallel port by allocating - its IRQ line. - */ -int -wic_open(struct device *dev) -{ - struct net_local *nl = (struct net_local *)dev->priv; - unsigned long flags; - - if (dev->irq == 0) { - printk("%s: IRQ is not set. Please set it by ifconfig.\n", dev->name); - return -EAGAIN; - } - save_flags(flags); - cli(); - check_bfr(dev); - if (request_irq(dev->irq , wic_interrupt, 0, dev->name, NULL) != 0) { - sti(); - printk("%s: couldn't get IRQ %d.\n", dev->name, dev->irq); - return -EAGAIN; - } - irq2dev_map[dev->irq] = dev; - restore_flags(flags); - - save |= 0x10; /* enable */ - outb(save, PAR_CONTROL(dev)); - /* Initialize the state machine. */ - nl->rcv_data.state = nl->snd_data.state = WIC_PK_DONE; - nl->rcv_data.skb = nl->snd_data.skb = NULL; - nl->connection = WIC_CN_NONE; - nl->is_deferred = 0; - - dev->interrupt = 0; - dev->start = 1; - dev->tbusy = 0; - MOD_INC_USE_COUNT; - return 0; -} - -/* The inverse routine to wic_open (). */ -int -wic_close(struct device *dev) -{ - struct net_local *nl = (struct net_local *)dev->priv; - struct wic_local *snd = &nl->snd_data; - struct wic_local *rcv = &nl->rcv_data; - - dev->tbusy = 1; - dev->start = 0; - cli(); - free_irq(dev->irq, NULL); - irq2dev_map[dev->irq] = NULL; - nl->is_deferred = 0; - nl->connection = WIC_CN_NONE; - sti(); - outb(0x00, PAR_DATA(dev)); - - snd->state = WIC_PK_DONE; - if (snd->skb) { - snd->skb->free = 1; - dev_kfree_skb(snd->skb, FREE_WRITE); - snd->skb = NULL; - } - rcv->state = WIC_PK_DONE; - if (rcv->skb) { - rcv->skb->free = 1; - kfree_skb(rcv->skb, FREE_READ); - rcv->skb = NULL; - } - - MOD_DEC_USE_COUNT; - return 0; -} - -struct enet_statistics * -wic_get_stats(struct device *dev) -{ - struct net_local *nl = (struct net_local *)dev->priv; - struct enet_statistics *r = &nl->enet_stats; - - return r; -} - -int -wic_config(struct device *dev, struct ifmap *map) -{ - if (dev->flags & IFF_UP) - return -EBUSY; - - if (map->base_addr != (unsigned long)-1 - && map->base_addr != dev->base_addr) - printk("%s: You cannot change base_addr of this interface (ignored).\n", dev->name); - - if (map->irq != (unsigned char)-1) - dev->irq = map->irq; - return 0; -} - -int -wic_ioctl(struct device *dev, struct ifreq *rq, int cmd) -{ - struct wicconf wc; - int err; - char len = 0; - unsigned long flags; - - err=verify_area(VERIFY_WRITE, rq->ifr_data, sizeof(struct wicconf)); - if (err) - return err; - memcpy_fromfs(&wc, rq->ifr_data, sizeof(struct wicconf)); - switch(wc.pcmd) { - case WIC_AYT: - strcpy(wc.data, version); - wc.len = strlen(wc.data); - memcpy_tofs(rq->ifr_data, &wc, sizeof(struct wicconf)); - /* return 0; */ - break; - case WIC_RESET: - wic_reset(dev); - return(0); - /* break; */ - case WIC_SETSN: - len = 17; - break; - case WIC_SETPS: - len = 3; - break; - case WIC_SETAF: - case WIC_SETGPF: - len = 2; - break; - case WIC_SETNET: - len = 23; - break; - case WIC_SETSYS: - len = 15; - break; - case WIC_GETVERH: - case WIC_GETNL: - case WIC_GETSN: - case WIC_CLRSTATS: - case WIC_GETSTATS: - case WIC_GETVERM: - case WIC_GETNET: - case WIC_GETSYS: - len = 1; - break; - default: - return -EOPNOTSUPP; - } - - /* Wait for lock to free */ - while (set_bit(0, (void *)&dev->tbusy) != 0); - save_flags(flags); - cli(); - - disable_irq(dev->irq); - save &= 0xef; /* disable */ - outb(save, PAR_CONTROL(dev)); - err = check_bfr(dev); - tog = 3; - err = send_cmd(dev, (unsigned char *)&wc, len); - - if (wc.pcmd & 0x40) { /* response */ - len = (char)recv_cmd_resp(dev, wc.data); - while ((len == 1) && (wc.data[0] == 0x7)) { /* controller int */ - len = (char)recv_cmd_resp(dev, wc.data); - } - save |= 0x10; /* enable */ - outb(save, PAR_CONTROL(dev)); - enable_irq(dev->irq); - wc.len = (len <0) ? 0 : len; - memcpy_tofs(rq->ifr_data, &wc, sizeof(struct wicconf)); - } else { - save |= 0x10; /* enable */ - outb(save, PAR_CONTROL(dev)); - enable_irq(dev->irq); - } - restore_flags(flags); - - outb(0, PAR_DATA(dev)); - dev->tbusy = 0; - return 0; -} - -int -get_byte(struct device *dev, unsigned char *c) -{ -unsigned int cx; - - cx = LOOPCNT; - while ((inb(PAR_STATUS(dev)) & 0x08) != ((tog << 3)&0x08)) { - if (--cx == 0) { - return(-TIMEOUT); - } - } - /* receive a byte of data */ - *c = inb(PAR_DATA(dev)); - tog ^= 0x01; - /* ack reception of data */ - outb(tog| save, PAR_CONTROL(dev)); - return OK; -} - -int -ack_resp(struct device *dev) -{ -unsigned int cx; - - outb(save | 0x27, PAR_CONTROL(dev)); - - /* wait for controller to remove interrupt [Ack(low), Busy(low)] */ - cx = LOOPCNT; - while ((inb(PAR_STATUS(dev)) & 0xc0) != 0x80) { - if (--cx == 0) { - return -TIMEOUT; - } - } - - outb(save | 0x22, PAR_CONTROL(dev)); - cx = LOOPCNT; - while ((inb(PAR_STATUS(dev)) & 0x08) == 0x08) { - if (--cx == 0) { - return TIMEOUT; - } - } - tog |= 0x20; - tog &= 0xfe; - return OK; -} - -void -wic_reset(struct device *dev) -{ -unsigned char stat; - - stat = inb(PAR_CONTROL(dev)); - outb(0, PAR_DATA(dev)); - outb(stat | 0x08, PAR_CONTROL(dev)); - outb(stat & 0xf7, PAR_CONTROL(dev)); - dev->tbusy = 0; - dev->interrupt = 0; - tog = 3; - save = 0; - return; -} - -int -check_bfr(struct device *dev) -{ -unsigned char c0, l; - - if ((inb(PAR_STATUS(dev)) & 0xc8) == 0x48) { - save |= 0x80; - outb(0x23| save, PAR_CONTROL(dev)); - ack_resp(dev); - get_byte(dev, &l); /* len */ - while (l--) { - get_byte(dev, &c0); - } - get_byte(dev, &c0); - save &=0x7f; - outb(0, PAR_DATA(dev)); - return -l; - } else - return (0); -} - - -int -recv_cmd_resp(struct device *dev, unsigned char *buf) -{ -unsigned char cksum = 0; -int err; -unsigned char c0 = 0; -int len; -int savelen; -unsigned int cx; -int i; - - tog &= 0xfe; - cx = LOOPCNT; - while ((inb(PAR_STATUS(dev)) & 0xc8) != 0x48) { - if (--cx == 0) { - /* clear Busy */ - outb(0, PAR_DATA(dev)); - printk("rcv_cmd_resp: timeout\n"); - return -TIMEOUT; - } - } - - /* acknowledge the interrupt */ - i = ack_resp(dev); - - /* get length */ - err = get_byte(dev, &c0); - if (err < 0) { - printk("get_byte1: failed\n"); - return(err); - } - len = c0; - savelen = len; - - /* get data */ - while(len--) { - err = get_byte(dev, &c0); - if (err < 0) { - printk("get_byte2: failed\n"); - return(err); - } - outb(0, PAR_DATA(dev)); - *buf = c0; - cksum += c0; - buf++; - } - /* get cksum */ - err = get_byte(dev, &c0); - if (err < 0) { - printk("get_byte3: failed\n"); - return(err); - } - if (cksum != c0) { - printk("cksum failed\n"); - return(-3); - } - /* get trailing byte, if any... */ - get_byte(dev, &c0); - return(savelen); -} - -int -send_byte(struct device *dev, unsigned char c) -{ -unsigned int cx; - - cx = LOOPCNT; - while ((inb(PAR_STATUS(dev)) & 0x80) == ((tog<<7) & 0x80)) { - if (--cx == 0) { - return(-TIMEOUT); - } - } - outb(c, PAR_DATA(dev)); - outb(save |tog, PAR_CONTROL(dev)); - tog ^= 0x01; - return OK; -} - - -int -send_cmd(struct device *dev, unsigned char *cmd, char len) -{ -unsigned char cksum = 0; -int err = 0; -unsigned int cx; - - /* interrupt controller */ - outb(save | 0x04, PAR_CONTROL(dev)); - /* wait for ACK */ - cx = LOOPCNT; - while ((inb(PAR_STATUS(dev)) & 0xe8) != 0xc0) { - if (--cx == 0) - return -TIMEOUT; - if (cx == 10) - outb(0x02, PAR_CONTROL(dev)); - } - /* cmd coming... */ - outb(save | 0x02, PAR_CONTROL(dev)); - /* send length byte */ - err = send_byte(dev, (unsigned char)len); - - /* send data */ - while (len--) { - err = send_byte(dev, *cmd); - if (err < 0) { - return err; - } - cksum += *cmd; - cmd++; - } - - /* send cksum byte */ - err = send_byte(dev, cksum); - if (err < 0) - return err; - - cx = LOOPCNT; - while ((inb(PAR_STATUS(dev)) & 0x80) == ((tog <<7)&0x80)) { - if (--cx == 0) - return -TIMEOUT; - } - save |= 0x80; - outb(save | 0x23, PAR_CONTROL(dev)); - outb(0, PAR_DATA(dev)); - return OK; -} - -#ifdef MODULE -struct device dev_wic0 = -{ - "wic0" /*"wic"*/, - 0, 0, 0, 0, /* memory */ - 0x3BC, 5, /* base, irq */ - 0, 0, 0, NULL, wic_init -}; - -struct device dev_wic1 = -{ - "wic1" /*"wic"*/, - 0, 0, 0, 0, /* memory */ - 0x378, 7, /* base, irq */ - 0, 0, 0, NULL, wic_init -}; - -struct device dev_wic2 = -{ - "wic2" /*"wic"*/, - 0, 0, 0, 0, /* memory */ - 0x278, 2, /* base, irq */ - 0, 0, 0, NULL, wic_init -}; - -int -init_module(void) -{ - int devices=0; - - if (register_netdev(&dev_wic0) != 0) - devices++; - if (register_netdev(&dev_wic1) != 0) - devices++; - if (register_netdev(&dev_wic2) != 0) - devices++; - if (devices == 0) - return -EIO; - return 0; -} - -void -cleanup_module(void) -{ - if (dev_wic0.priv) { - unregister_netdev(&dev_wic0); - release_region(PAR_DATA(&dev_wic0), 3); - kfree_s(dev_wic0.priv, sizeof(struct net_local)); - dev_wic0.priv = NULL; - } - if (dev_wic1.priv) { - unregister_netdev(&dev_wic1); - release_region(PAR_DATA(&dev_wic1), 3); - kfree_s(dev_wic1.priv, sizeof(struct net_local)); - dev_wic1.priv = NULL; - } - if (dev_wic2.priv) { - unregister_netdev(&dev_wic2); - release_region(PAR_DATA(&dev_wic2), 3); - kfree_s(dev_wic2.priv, sizeof(struct net_local)); - dev_wic2.priv = NULL; - } -} -#endif /* MODULE */ - -/* - * Local variables: - * compile-command: "gcc -DMODULE -DCONFIG_MODVERSIONS -D__KERNEL__ -Wall -Wstrict-prototypes -O2 -g -fomit-frame-pointer -pipe -m486 -c wic.c" - * End: - */ diff --git a/drivers/scsi/hosts.c b/drivers/scsi/hosts.c index 4bb75865b34b..65c28f9b2e18 100644 --- a/drivers/scsi/hosts.c +++ b/drivers/scsi/hosts.c @@ -357,10 +357,18 @@ scsi_unregister(struct Scsi_Host * sh){ /* If we are removing the last host registered, it is safe to reuse * its host number (this avoids "holes" at boot time) (DB) + * It is also safe to reuse those of numbers directly below which have + * been released earlier (to avoid some holes in numbering). */ - if (max_scsi_hosts == next_scsi_host) - max_scsi_hosts--; - + if(sh->host_no == max_scsi_hosts - 1) { + while(--max_scsi_hosts >= next_scsi_host) { + shpnt = scsi_hostlist; + while(shpnt && shpnt->host_no != max_scsi_hosts - 1) + shpnt = shpnt->next; + if(shpnt) + break; + } + } next_scsi_host--; scsi_init_free((char *) sh, sizeof(struct Scsi_Host) + sh->extra_bytes); } diff --git a/drivers/scsi/ppa.h b/drivers/scsi/ppa.h index 03a740563c41..8909125eddec 100644 --- a/drivers/scsi/ppa.h +++ b/drivers/scsi/ppa.h @@ -7,6 +7,7 @@ * All comments to David. */ +#include /* CONFIG_SCSI_PPA_HAVE_PEDANTIC */ #ifndef _PPA_H #define _PPA_H diff --git a/drivers/sound/sb_common.c b/drivers/sound/sb_common.c index 828a6f96ff39..24d3d32336d5 100644 --- a/drivers/sound/sb_common.c +++ b/drivers/sound/sb_common.c @@ -1201,6 +1201,8 @@ probe_sbmpu (struct address_info *hw_config) } hw_config->name = "Sound Blaster 16"; hw_config->irq = -devc->irq; + hw_config->dma = -1; + hw_config->dma2 = -1; sb16_set_mpu_port(devc, hw_config); break; diff --git a/drivers/sound/sequencer.c b/drivers/sound/sequencer.c index 6e42e5431a31..38a343c212ee 100644 --- a/drivers/sound/sequencer.c +++ b/drivers/sound/sequencer.c @@ -1149,7 +1149,10 @@ sequencer_open (int dev, struct fileinfo *file) } if (!max_synthdev && !max_mididev) - return -(ENXIO); + { + sequencer_busy = 0; + return -(ENXIO); + } synth_open_mask = 0; diff --git a/fs/fat/fatfs_syms.c b/fs/fat/fatfs_syms.c index e74ff7cd278f..6f9c7d419c5d 100644 --- a/fs/fat/fatfs_syms.c +++ b/fs/fat/fatfs_syms.c @@ -6,7 +6,6 @@ */ #define ASC_LINUX_VERSION(V, P, S) (((V) * 65536) + ((P) * 256) + (S)) #include -#include #include #include diff --git a/fs/isofs/joliet.c b/fs/isofs/joliet.c index 1b1f26ab315a..39695413f397 100644 --- a/fs/isofs/joliet.c +++ b/fs/isofs/joliet.c @@ -7,7 +7,6 @@ */ #include -#include #include #include #include @@ -97,6 +96,13 @@ get_joliet_filename(struct iso_directory_record * de, struct inode * inode, len -= 2; } + /* + * Windows doesn't like periods at the end of a name + */ + while (len >= 2 && (outname[len-1] == '.')) { + len--; + } + if (inode->i_sb->u.isofs_sb.s_name_check == 'r') { for (i = 0; i < len; i++) { c = outname[i]; diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c index ef27572b8ddb..4c994f5652f1 100644 --- a/fs/nfs/dir.c +++ b/fs/nfs/dir.c @@ -448,7 +448,7 @@ static int nfs_mknod(struct inode *dir, const char *name, int len, iput(dir); return -ENAMETOOLONG; } - if (mode & S_IFIFO) + if (S_ISFIFO(mode)) sattr.mode = (mode & ~S_IFMT) | S_IFCHR; else sattr.mode = mode; @@ -460,7 +460,7 @@ static int nfs_mknod(struct inode *dir, const char *name, int len, sattr.atime.seconds = sattr.mtime.seconds = (unsigned) -1; error = nfs_proc_create(NFS_SERVER(dir), NFS_FH(dir), name, &sattr, &fhandle, &fattr); - if (error == -EINVAL && (mode & S_IFIFO)) { + if (error == -EINVAL && (S_ISFIFO(mode))) { sattr.mode = mode; error = nfs_proc_create(NFS_SERVER(dir), NFS_FH(dir), name, &sattr, &fhandle, &fattr); diff --git a/fs/read_write.c b/fs/read_write.c index 05ec1470cfd0..c55210d0aef8 100644 --- a/fs/read_write.c +++ b/fs/read_write.c @@ -155,7 +155,12 @@ asmlinkage int sys_write(unsigned int fd,char * buf,unsigned int count) if (!file->f_op || !file->f_op->write) goto out; error = 0; - if (!count) + /* + * If this was a development kernel we'd just drop the test + * its not so we do this for stricter compatibility both to + * applications and drivers. + */ + if (!count && !IS_ZERO_WR(inode)) goto out; error = locks_verify_area(FLOCK_VERIFY_WRITE,inode,file,file->f_pos,count); if (error) @@ -268,6 +273,10 @@ static int do_readv_writev(int type, struct inode * inode, struct file * file, fn = file->f_op->read; if (type == VERIFY_READ) fn = (IO_fn_t) file->f_op->write; + + if(fn==NULL) + return -EOPNOTSUPP; + vector = iov; while (count > 0) { void * base; diff --git a/fs/select.c b/fs/select.c index 479f08b0832c..ccdbc6564491 100644 --- a/fs/select.c +++ b/fs/select.c @@ -46,7 +46,7 @@ * Linus noticed. -- jrs */ -static void free_wait(select_table * p) +void select_free_wait(select_table * p) { struct select_table_entry * entry = p->entry + p->nr; @@ -96,7 +96,7 @@ static void unlock_fd_bits(int n, int x) * and we aren't going to sleep on the select_table. -- jrs */ -static int check(int flag, select_table * wait, struct file * file) +int select_check(int flag, select_table * wait, struct file * file) { struct inode * inode; struct file_operations *fops; @@ -180,17 +180,17 @@ repeat: struct file * file = current->files->fd[i]; if (!file) continue; - if (FD_ISSET(i,in) && check(SEL_IN,wait,file)) { + if (FD_ISSET(i,in) && select_check(SEL_IN,wait,file)) { FD_SET(i, res_in); count++; wait = NULL; } - if (FD_ISSET(i,out) && check(SEL_OUT,wait,file)) { + if (FD_ISSET(i,out) && select_check(SEL_OUT,wait,file)) { FD_SET(i, res_out); count++; wait = NULL; } - if (FD_ISSET(i,ex) && check(SEL_EX,wait,file)) { + if (FD_ISSET(i,ex) && select_check(SEL_EX,wait,file)) { FD_SET(i, res_ex); count++; wait = NULL; @@ -201,7 +201,7 @@ repeat: schedule(); goto repeat; } - free_wait(&wait_table); + select_free_wait(&wait_table); free_page((unsigned long) entry); current->state = TASK_RUNNING; bale: diff --git a/fs/vfat/namei.c b/fs/vfat/namei.c index 76d2b570a7fb..30db04cc7447 100644 --- a/fs/vfat/namei.c +++ b/fs/vfat/namei.c @@ -10,7 +10,6 @@ * the problem, send a script that demonstrates it. */ -#include #define __NO_VERSION__ #include diff --git a/include/asm-alpha/lca.h b/include/asm-alpha/lca.h index 9ea03dd9b4ae..03bc5fe5ae60 100644 --- a/include/asm-alpha/lca.h +++ b/include/asm-alpha/lca.h @@ -1,3 +1,4 @@ +#include /* CONFIG_ALPHA_SRM_SETUP */ #ifndef __ALPHA_LCA__H__ #define __ALPHA_LCA__H__ diff --git a/include/asm-i386/bugs.h b/include/asm-i386/bugs.h index 4f27db694e33..4acccddc5525 100644 --- a/include/asm-i386/bugs.h +++ b/include/asm-i386/bugs.h @@ -145,9 +145,186 @@ static void check_pentium_f00f(void) } } +/* + * B step AMD K6 before B 9730xxxx have hardware bugs that can cause + * misexecution of code under Linux. Owners of such processors should + * contact AMD for precise details and a (free) CPU exchange. + * + * See http://www.chorus.com/~poulot/k6bug.html (broken link!) + * http://www.amd.com/K6/k6docs/revgd.html + * + * The following test is erm... interesting. AMD neglected to up + * the chip stepping when fixing the bug but they also tweaked some + * performance at the same time... + */ + +extern void vide(void); +__asm__(".align 4\nvide: ret"); + +static void check_k6_bug(void) +{ + + if ((strcmp(x86_vendor_id, "AuthenticAMD") == 0) && + (x86_model == 6) && (x86_mask == 1)) + { + int n; + void (*f_vide)(void); + unsigned long d, d2; + + printk(KERN_INFO "AMD K6 stepping B detected - "); + +#define K6_BUG_LOOP 1000000 + + /* + * It looks like AMD fixed the 2.6.2 bug and improved indirect + * calls at the same time. + */ + + n = K6_BUG_LOOP; + f_vide = vide; + __asm__ ("rdtsc" : "=a" (d)); + while (n--) + f_vide(); + __asm__ ("rdtsc" : "=a" (d2)); + d = d2-d; + + if (d > 20*K6_BUG_LOOP) { + printk("system stability may be impaired when more than 32 MB are used.\n"); + } + else + printk("probably OK (after B9730xxxx).\n"); + } +} + +/* Cyrix stuff from this point on */ + +/* Cyrix 5/2 test (return 0x200 if it's a Cyrix) */ +static inline int test_cyrix_52div(void) +{ + int test; + + __asm__ __volatile__("xor %%eax,%%eax\n\t" + "sahf\n\t" + "movb $5,%%al\n\t" + "movb $2,%%bl\n\t" + "div %%bl\n\t" + "lahf\n\t" + "andl $0xff00,%%eax": "=eax" (test) : : "bx"); + + return test; +} + +/* test for CCR3 bit 7 r/w */ +static char test_cyrix_cr3rw(void) +{ + char temp, test; + + temp = getCx86(CX86_CCR3); /* get current CCR3 value */ + setCx86(CX86_CCR3, temp ^ 0x80); /* toggle test bit and write */ + getCx86(0xc0); /* dummy to change bus */ + test = temp - getCx86(CX86_CCR3); /* != 0 if ccr3 r/w */ + setCx86(CX86_CCR3, temp); /* return CCR3 to original value */ + + return test; +} + +/* redo the cpuid test in head.S, so that those 6x86(L) now get + detected properly (0 == no cpuid) */ +static inline int test_cpuid(void) +{ + int test; + + __asm__("pushfl\n\t" + "popl %%eax\n\t" + "movl %%eax,%%ecx\n\t" + "xorl $0x200000,%%eax\n\t" + "pushl %%eax\n\t" + "popfl\n\t" + "pushfl\n\t" + "popl %%eax\n\t" + "xorl %%ecx,%%eax\n\t" + "pushl %%ecx\n\t" + "popfl" : "=eax" (test) : : "cx"); + + return test; +} + +/* All Cyrix 6x86 and 6x86L need the SLOP bit reset so that the udelay loop + * calibration works well. + * This routine must be called with MAPEN enabled, otherwise we don't + * have access to CCR5. + */ + +static void check_6x86_slop(void) +{ + if (x86_model == 2) /* if 6x86 or 6x86L */ + setCx86(CX86_CCR5, getCx86(CX86_CCR5) & 0xfd); /* reset SLOP */ +} + +/* Cyrix CPUs without cpuid or with cpuid not yet enabled can be detected + * by the fact that they preserve the flags across the division of 5/2. + * PII and PPro exhibit this behavior too, but they have cpuid available. + */ + +static void check_cyrix_various(void) +{ + if ((x86 == 4) && (test_cyrix_52div()==0x200)) + { + /* if it's a Cyrix */ + + unsigned long flags; + + /* default to an "old" Cx486 */ + strcpy(x86_vendor_id, "CyrixInstead"); + x86_model = -1; + x86_mask = 0; + + /* Disable interrupts */ + save_flags(flags); + cli(); + + /* First check for very old CX486 models */ + /* that did not have DIR0/DIR1. */ + if (test_cyrix_cr3rw()) + { /* if has DIR0/DIR1 */ + + char ccr3; + x86_model = 0; + + /* Enable MAPEN */ + ccr3 = getCx86(CX86_CCR3); + setCx86(CX86_CCR3, (ccr3 & 0x0f) | 0x10); + + /* try enabling cpuid */ + setCx86(CX86_CCR4, getCx86(CX86_CCR4) | 0x80); + + if (test_cpuid()) + { + int eax, dummy; + + /* get processor info */ + + cpuid(1, &eax, &dummy, &dummy, + &x86_capability); + + have_cpuid = 1; + x86_model = (eax >> 4) & 0xf; + x86 = (eax >> 8) & 0xf; + check_6x86_slop(); + } + /* disable MAPEN */ + setCx86(CX86_CCR3, ccr3); + } /* endif has DIR0/DIR1 */ + restore_flags(flags); /* restore interrupt state */ + } /* endif it's a Cyrix */ +} + +/* Check various processor bugs */ static void check_bugs(void) { + check_cyrix_various(); + check_k6_bug(); check_tlb(); check_fpu(); check_hlt(); diff --git a/include/asm-i386/unistd.h b/include/asm-i386/unistd.h index d28097262843..c5f8f3a6177a 100644 --- a/include/asm-i386/unistd.h +++ b/include/asm-i386/unistd.h @@ -169,6 +169,9 @@ #define __NR_sched_rr_get_interval 161 #define __NR_nanosleep 162 #define __NR_mremap 163 +#define __NR_poll 168 +#define __NR_getpmsg 188 +#define __NR_putpmsg 189 /* XXX - _foo needs to be __foo, while __NR_bar could be _NR_bar. */ #define _syscall0(type,name) \ diff --git a/include/linux/fs.h b/include/linux/fs.h index 511c101139f6..b698b3fcf379 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -75,6 +75,7 @@ extern int max_files, nr_files; #define S_IMMUTABLE 512 /* Immutable file */ #define MS_NOATIME 1024 /* Do not update access times. */ #define S_BAD_INODE 2048 /* Marker for unreadable inodes */ +#define S_ZERO_WR 4096 /* Device accepts 0 length writes */ /* * Flags that can be altered by MS_REMOUNT @@ -106,6 +107,7 @@ extern int max_files, nr_files; #define IS_APPEND(inode) ((inode)->i_flags & S_APPEND) #define IS_IMMUTABLE(inode) ((inode)->i_flags & S_IMMUTABLE) #define IS_NOATIME(inode) ((inode)->i_flags & MS_NOATIME) +#define IS_ZERO_WR(inode) ((inode)->i_flags & S_ZERO_WR) #define UPDATE_ATIME(inode) \ if (!IS_NOATIME(inode) && !IS_RDONLY(inode)) { \ diff --git a/include/linux/isdn_ppp.h b/include/linux/isdn_ppp.h index 177646520470..e87a6b0e101d 100644 --- a/include/linux/isdn_ppp.h +++ b/include/linux/isdn_ppp.h @@ -8,6 +8,8 @@ extern int isdn_ppp_hangup_slave(char *); #define CALLTYPE_OUTGOING 0x2 #define CALLTYPE_CALLBACK 0x4 +#define IPPP_VERSION "2.2.0" /* For now */ + struct pppcallinfo { int calltype; diff --git a/include/linux/msdos_fs.h b/include/linux/msdos_fs.h index 33d11fcf1531..4e76138c46a1 100644 --- a/include/linux/msdos_fs.h +++ b/include/linux/msdos_fs.h @@ -7,7 +7,6 @@ #include #include #include -#include #include #define MSDOS_ROOT_INO 1 /* == MINIX_ROOT_INO */ diff --git a/include/linux/personality.h b/include/linux/personality.h index 14df1888dca4..aa09f4611dcc 100644 --- a/include/linux/personality.h +++ b/include/linux/personality.h @@ -27,7 +27,7 @@ #define PER_XENIX (0x0007 | STICKY_TIMEOUTS) /* Prototype for an lcall7 syscall handler. */ -typedef asmlinkage void (*lcall7_func)(struct pt_regs *); +typedef void (*lcall7_func)(struct pt_regs *); /* Description of an execution domain - personality range supported, diff --git a/include/linux/shm.h b/include/linux/shm.h index 042c54106f90..c6a7e39167fc 100644 --- a/include/linux/shm.h +++ b/include/linux/shm.h @@ -63,6 +63,7 @@ asmlinkage int sys_shmget (key_t key, int size, int flag); asmlinkage int sys_shmat (int shmid, char *shmaddr, int shmflg, ulong *addr); asmlinkage int sys_shmdt (char *shmaddr); asmlinkage int sys_shmctl (int shmid, int cmd, struct shmid_ds *buf); +extern void shm_unuse(unsigned int type); #endif /* __KERNEL__ */ diff --git a/include/net/sock.h b/include/net/sock.h index 34f5c417f7f5..7a3ec03f087c 100644 --- a/include/net/sock.h +++ b/include/net/sock.h @@ -350,7 +350,8 @@ struct sock * Moved solely for 2.0 to keep binary module compatibility stuff straight. */ - unsigned short max_ack_backlog; + unsigned short max_ack_backlog; + struct sock *listening; }; /* diff --git a/ipc/shm.c b/ipc/shm.c index 8436259468b1..a648cec6086f 100644 --- a/ipc/shm.c +++ b/ipc/shm.c @@ -3,6 +3,7 @@ * Copyright (C) 1992, 1993 Krishna Balasubramanian * Many improvements/fixes by Bruno Haible. * Replaced `struct shm_desc' by `struct vm_area_struct', July 1994. + * Fixed the shm swap deallocation (shm_unuse()), August 1998 Andrea Arcangeli. */ #include @@ -804,3 +805,65 @@ int shm_swap (int prio, int dma) shm_rss--; return 1; } + +/* + * Free the swap entry and set the new pte for the shm page. + */ +static void shm_unuse_page(struct shmid_ds *shp, unsigned long idx, + unsigned long type) +{ + pte_t pte = __pte(shp->shm_pages[idx]); + unsigned long page, entry = shp->shm_pages[idx]; + + if (pte_none(pte)) + return; + if (pte_present(pte)) + { + /* + * Security check. Should be not needed... + */ + unsigned long page_nr = MAP_NR(pte_page(pte)); + if (page_nr >= MAP_NR(high_memory)) + { + printk("shm page mapped in virtual memory\n"); + return; + } + if (!in_swap_cache(page_nr)) + return; + if (SWP_TYPE(in_swap_cache(page_nr)) != type) + return; + printk("shm page in swap cache, trying to remove it!\n"); + delete_from_swap_cache(page_nr); + + shp->shm_pages[idx] = pte_val(pte_mkdirty(pte)); + return; + } + + if (SWP_TYPE(pte_val(pte)) != type) + return; + + /* + * Here we must swapin the pte and free the swap. + */ + page = get_free_page(GFP_KERNEL); + read_swap_page(pte_val(pte), (char *) page); + pte = pte_mkdirty(mk_pte(page, PAGE_SHARED)); + shp->shm_pages[idx] = pte_val(pte); + shm_rss++; + + swap_free(entry); + shm_swp--; +} + +/* + * unuse_shm() search for an eventually swapped out shm page. + */ +void shm_unuse(unsigned int type) +{ + int i, n; + + for (i = 0; i < SHMMNI; i++) + if (shm_segs[i] != IPC_UNUSED && shm_segs[i] != IPC_NOID) + for (n = 0; n < shm_segs[i]->shm_npages; n++) + shm_unuse_page(shm_segs[i], n, type); +} diff --git a/kernel/ksyms.c b/kernel/ksyms.c index 10b3849f4908..4fa02bad6b9f 100644 --- a/kernel/ksyms.c +++ b/kernel/ksyms.c @@ -78,6 +78,9 @@ extern void free_dma(unsigned int dmanr); extern void hard_reset_now(void); +extern void select_free_wait(select_table * p); +extern int select_check(int flag, select_table * wait, struct file * file); + struct symbol_table symbol_table = { #include #ifdef MODVERSIONS @@ -160,6 +163,10 @@ struct symbol_table symbol_table = { X(getblk), X(bread), X(breada), + + X(select_check), + X(select_free_wait), + X(__brelse), X(__bforget), X(ll_rw_block), diff --git a/mm/swapfile.c b/mm/swapfile.c index 15384cc8bb70..7c7e1c0ad43f 100644 --- a/mm/swapfile.c +++ b/mm/swapfile.c @@ -17,6 +17,7 @@ #include #include #include /* for blk_size */ +#include #include #include /* for cli()/sti() */ @@ -313,6 +314,7 @@ static int try_to_unuse(unsigned int type) nr++; } free_page(page); + shm_unuse(type); return 0; } diff --git a/net/ipv4/ip_masq_quake.c b/net/ipv4/ip_masq_quake.c index d64aeae0c771..942b7290252a 100644 --- a/net/ipv4/ip_masq_quake.c +++ b/net/ipv4/ip_masq_quake.c @@ -20,7 +20,6 @@ * */ -#include #include #include diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index 65a38c542cbc..8ac1c36a3309 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c @@ -1976,8 +1976,15 @@ static void tcp_close(struct sock *sk, unsigned long timeout) if(sk->state == TCP_LISTEN) { - /* Special case */ + /* + * Special case + */ tcp_set_state(sk, TCP_CLOSE); + /* + * Our children must die before we do now that + * sk->listening exists. It was right anyway but + * dont break this assumption. + */ tcp_close_pending(sk); release_sock(sk); sk->dead = 1; diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index db65786bc02e..22ae4bfc45cc 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c @@ -44,6 +44,8 @@ * then use it for ToS is even more * broken. * + * George Baeslack : SIGIO delivery on accept() bug that + * affected sun jdk. */ #include @@ -772,6 +774,7 @@ static void tcp_conn_request(struct sock *sk, struct sk_buff *skb, newsk->acked_seq = skb->seq + 1; newsk->copied_seq = skb->seq + 1; newsk->socket = NULL; + newsk->listening = sk; /* * Grab the ttl and tos values and use them @@ -1032,6 +1035,7 @@ static int tcp_conn_request_fake(struct sock *sk, struct sk_buff *skb, newsk->acked_seq = skb->seq; newsk->copied_seq = skb->seq; newsk->socket = NULL; + newsk->listening = sk; /* * Grab the ttl and tos values and use them @@ -1663,6 +1667,19 @@ static int tcp_ack(struct sock *sk, struct tcphdr *th, u32 ack, int len) if (sk->state==TCP_SYN_RECV) { tcp_set_state(sk, TCP_ESTABLISHED); + + /* + * We have a listening socket owning us. Wake it for + * the accept. + */ + + if ( sk->listening ) + { + /* The listener may be sk->dead. Dont worry + data_ready traps this */ + sk->data_ready(sk->listening,0); + sk->listening = NULL; + } /* Must check for peer advertising zero sized window * or else we get a sk->{mtu,mss} of zero and thus bomb out diff --git a/scripts/checkconfig.pl b/scripts/checkconfig.pl new file mode 100644 index 000000000000..b82aa1a8bde0 --- /dev/null +++ b/scripts/checkconfig.pl @@ -0,0 +1,53 @@ +#! /usr/bin/perl +# +# checkconfig: find uses of CONFIG_* names without matching definitions. +# Copyright abandoned, 1998, Michael Elizabeth Chastain . + +use integer; + +$| = 1; + +foreach $file (@ARGV) +{ + # Open this file. + open(FILE, $file) || die "Can't open $file: $!\n"; + + # Initialize variables. + my $fInComment = 0; + my $fUseConfig = 0; + my $iLinuxConfig = 0; + my %configList = (); + + LINE: while ( ) + { + # Strip comments. + $fInComment && (s+^.*?\*/+ +o ? ($fInComment = 0) : next); + m+/\*+o && (s+/\*.*?\*/+ +go, (s+/\*.*$+ +o && ($fInComment = 1))); + + # Pick up definitions. + if ( m/^#/o ) + { + $iLinuxConfig = $. if m/^#\s*include\s*/o; + $configList{uc $1} = 1 if m/^#\s*include\s*/o; + $configList{$1} = 1 if m/^#\s*define\s+CONFIG_(\w*)/o; + $configList{$1} = 1 if m/^#\s*undef\s+CONFIG_(\w*)/o; + } + + # Look for usages. + next unless m/CONFIG_/o; + WORD: while ( m/\bCONFIG_(\w+)/og ) + { + $fUseConfig = 1; + last LINE if $iLinuxConfig; + next WORD if exists $configList{$1}; + print "$file: $.: need CONFIG_$1.\n"; + $configList{$1} = 0; + } + } + + # Report superfluous includes. + if ( $iLinuxConfig && ! $fUseConfig ) + { print "$file: $iLinuxConfig: not needed.\n"; } + + close(FILE); +} -- 2.39.5