diff -u --recursive --new-file v2.1.30/linux/Documentation/Changes linux/Documentation/Changes --- v2.1.30/linux/Documentation/Changes Tue Mar 4 10:25:22 1997 +++ linux/Documentation/Changes Wed Apr 2 14:58:57 1997 @@ -26,7 +26,7 @@ http://www.datanet.hu/generations/linux/Changes2.html is an English-language HTML version. -Last updated: February 27, 1997. +Last updated: April 1, 1997. Current Author: Chris Ricker (gt1355b@prism.gatech.edu). Current Minimal Requirements @@ -35,14 +35,13 @@ Upgrade to at *least* these software revisions before thinking you've encountered a bug! -- Kernel modules modutils-2.1.23 +- Kernel modules modutils-2.1.29-970320 - Gnu C 2.7.2.1 -- Binutils 2.7.0.3 +- Binutils 2.7.0.9 - Linux C Library 5.4.23 - Dynamic Linker (ld.so) 1.8.5 - Linux C++ Library 2.7.2.1 - Procps 1.01 -- SysVinit 2.69 - Mount 2.5p - Net-tools 1.32-alpha - Kbd 0.91 @@ -84,7 +83,14 @@ Modules ======= - You need to upgrade to modutils-2.1.23 for kernels 2.1.18 and later. + You need to upgrade to modutils-2.1.29-970320 for kernels 2.1.29 and +later. + +Binutils +======== + + If you upgrade binutils, please read its accompanying release notes +to find out the proper way to upgrade it. Gnu C ===== @@ -113,6 +119,12 @@ in some standard tools. Check in /proc/net/rt_local to verify their presence. + To turn on IP forwarding, issue the following command: echo 1 > +/proc/sys/net/ipv4/ip_forwarding + + To run bootpd, you'll need to issue the following command: echo 1 +>/proc/sys/net/ipv4/ip_boot_agent + RPM === @@ -123,7 +135,7 @@ ====== A new "stable" version of DOSEMU is available for 2.1.x kernels. -Upgrade to 0.64.3 or later. +Upgrade to 0.66.1 or later. Loadlin ======= @@ -163,12 +175,12 @@ Binutils ======== -The 2.7.0.3 release: -ftp://tsx-11.mit.edu/pub/linux/packages/GCC/binutils-2.7.0.3.bin.tar.gz -ftp://sunsite.unc.edu/pub/Linux/GCC/binutils-2.7.0.3.bin.tar.gz +The 2.7.0.9 release: +ftp://tsx-11.mit.edu/pub/linux/packages/GCC/binutils-2.7.0.9.bin.tar.gz +ftp://sunsite.unc.edu/pub/Linux/GCC/binutils-2.7.0.9.bin.tar.gz Installation notes: -ftp://tsx-11.mit.edu/pub/linux/packages/GCC/release.binutils-2.7.0.3 -ftp://sunsite.unc.edu/pub/Linux/GCC/release.binutils-2.7.0.3 +ftp://tsx-11.mit.edu/pub/linux/packages/GCC/release.binutils-2.7.0.9 +ftp://sunsite.unc.edu/pub/Linux/GCC/release.binutils-2.7.0.9 Gnu C ===== @@ -210,9 +222,8 @@ Modules utilities ================= -The 2.1.23 release: -ftp://tsx-11.mit.edu/pub/linux/sources/system/v2.1/modutils-2.1.23.tar.gz -ftp://sunsite.unc.edu/pub/Linux/kernel/v2.1/modutils-2.1.23.tar.gz +The 2.1.29-970320 release: +ftp://ftp.redhat.com/pub/alphabits/modutils-2.1.29-970320.tar.gz Procps utilities ================ @@ -237,9 +248,9 @@ DOSEMU ====== -The 0.64.3.1 release: -ftp://tsx-11.mit.edu/pub/linux/ALPHA/dosemu/dosemu0.64.3.1.tgz -ftp://sunsite.unc.edu/pub/Linux/system/emulators/dosemu0.64.3.1.tgz +The 0.66.1 release: +ftp://tsx-11.mit.edu/pub/linux/ALPHA/dosemu/dosemu0.66.1.tgz +ftp://sunsite.unc.edu/pub/Linux/system/emulators/dosemu0.66.1.tgz Loadlin ======= diff -u --recursive --new-file v2.1.30/linux/Documentation/Configure.help linux/Documentation/Configure.help --- v2.1.30/linux/Documentation/Configure.help Thu Mar 27 14:39:58 1997 +++ linux/Documentation/Configure.help Wed Apr 2 14:57:17 1997 @@ -600,13 +600,6 @@ have access to a machine on the Internet that has one of the programs lynx, netscape or Mosaic). -Echo console messages on /dev/ttyS1 -CONFIG_SERIAL_ECHO - If you say Y here, all kernel messages that would usually go - to the console will also be sent to the device /dev/ttyS1 which - corresponds to a serial port; this could be useful if you attached - a terminal or printer to that port. - Non-standard serial port support CONFIG_SERIAL_NONSTANDARD Say Y here if you have any non-standard serial boards --- boards @@ -1533,11 +1526,12 @@ Probe all LUNs on each SCSI device CONFIG_SCSI_MULTI_LUN If you have a SCSI device that supports more than one LUN (Logical - Unit Number), e.g. a CD jukebox, you should say Y here so that all - will be found by the SCSI driver. An SCSI device with multiple LUNs - acts logically like multiple SCSI devices. The vast majority of SCSI - devices have only one LUN, and so most people can say N here and - should in fact do so, because it is safer. + Unit Number), e.g. a CD jukebox, and only one LUN is detected, you + can say Y here to force the SCSI driver to probe for multiple LUNs. + A SCSI device with multiple LUNs acts logically like multiple SCSI + devices. The vast majority of SCSI devices have only one LUN, and + so most people can say N here and should in fact do so, because it + is safer. Verbose SCSI error reporting (kernel size +=12K) CONFIG_SCSI_CONSTANTS @@ -1886,6 +1880,12 @@ whenever you want). The module will be called ibmmca.o. If you want to compile it as a module, say M here and read Documentation/modules.txt. + Normally, all IBM MCA SCSI adapters are automatically detected. You + can completely override auto-detection by specifying + "ibmmcascsi=io1,io2,..." at the boot loader's command prompt or + "io_port=io1,io2,... scsi_id=id1,id2,..." as a parameter of insmod. + "io" and "id" are the I/O base address and the SCSI ID of each + adapter, respectively. Always IN2000 SCSI support CONFIG_SCSI_IN2000 @@ -3820,6 +3820,17 @@ Documentation/modules.txt. The module will be called sysv.o. If you haven't heard about all of this before, it's safe to say N. +Kernel automounter support (experimental) +CONFIG_AUTOFS_FS + The automounter is a tool to automatically mount remote filesystems + on demand. This implementation is partially kernel-based to reduce + overhead in the already-mounted case; this is unlike the BSD + automounter (amd), which is only in user space. To use the + automounter you also need the user-space tools from + ftp.kernel.org:/pub/linux/daemons/autofs. If you are not a part of + a fairly large, distributed network, you probably do not need an + automounter, and can say N here. + BSD UFS filesystem support (read only) CONFIG_UFS_FS BSD and derivate versions of Unix (such as SunOS, FreeBSD, NetBSD @@ -3935,6 +3946,19 @@ and read Documentation/modules.txt. If you don't know whether you need it, then you don't need it: say N. +Virtual terminal +CONFIG_VT + This includes support for a terminal device using display and + keyboard devices. Only people using embedded systems want to say N + here. Most say Y here. + +Console on virtual terminal +CONFIG_VT_CONSOLE + If you enable this option, all kernel messages will be sent to the + device /dev/tty which corresponds to the virtual terminal you have + visible on your display. You should say Y here if you have no other + console device. + Standard/generic serial support CONFIG_SERIAL This selects whether you want to include the driver for the standard @@ -3953,6 +3977,16 @@ system, try running gpm first. Most people will say Y or M here, so that they can use serial mice, modems and similar devices connecting to the standard serial ports. + +Console on serial port +CONFIG_SERIAL_CONSOLE + If you enable this option, all kernel messages will be sent to the + device /dev/ttyS1 which corresponds to a serial port; this could be + useful if you attached a terminal or printer to that port. You can + use this in combination with console on virtual terminal, in which + case you get the output on both serial and display. Most people say + N here so that they can use the serial port for modem, mouse or some + other device. Digiboard PC/Xx Support CONFIG_DIGI diff -u --recursive --new-file v2.1.30/linux/MAINTAINERS linux/MAINTAINERS --- v2.1.30/linux/MAINTAINERS Thu Mar 27 14:39:58 1997 +++ linux/MAINTAINERS Fri Mar 28 14:31:00 1997 @@ -418,6 +418,18 @@ M: jam@acm.org S: Maintained +KERNEL AUTOMOUNTER (AUTOFS) +P: H. Peter Anvin +M: hpa@zytor.com +L: linux-kernel@vger.rutgers.edu +S: Maintained + +DEVICE NUMBER REGISTRY +P: H. Peter Anvin +M: hpa@zytor.com +L: linux-kernel@vger.rutgers.edu +S: Maintained + REST: P: Linus Torvalds S: Buried alive in diapers diff -u --recursive --new-file v2.1.30/linux/Makefile linux/Makefile --- v2.1.30/linux/Makefile Thu Mar 27 14:39:58 1997 +++ linux/Makefile Wed Apr 2 17:51:04 1997 @@ -1,6 +1,6 @@ VERSION = 2 PATCHLEVEL = 1 -SUBLEVEL = 30 +SUBLEVEL = 31 ARCH = i386 diff -u --recursive --new-file v2.1.30/linux/Rules.make linux/Rules.make --- v2.1.30/linux/Rules.make Thu Mar 27 14:39:59 1997 +++ linux/Rules.make Mon Mar 31 10:26:12 1997 @@ -44,6 +44,9 @@ %.s: %.c $(CC) $(CFLAGS) $(EXTRA_CFLAGS) -S $< -o $@ +%.i: %.c + $(CC) $(CFLAGS) $(EXTRA_CFLAGS) -E $< > $@ + %.o: %.c $(CC) $(CFLAGS) $(EXTRA_CFLAGS) -c -o $@ $< diff -u --recursive --new-file v2.1.30/linux/arch/alpha/config.in linux/arch/alpha/config.in --- v2.1.30/linux/arch/alpha/config.in Sun Aug 4 03:38:59 1996 +++ linux/arch/alpha/config.in Thu Mar 27 14:36:38 1997 @@ -83,7 +83,6 @@ define_bool CONFIG_ALPHA_AVANTI y fi -bool 'Echo console messages on /dev/ttyS0 (COM1)' CONFIG_SERIAL_ECHO if [ "$CONFIG_PCI" = "y" ]; then bool 'TGA Console Support' CONFIG_TGA_CONSOLE if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then diff -u --recursive --new-file v2.1.30/linux/arch/alpha/defconfig linux/arch/alpha/defconfig --- v2.1.30/linux/arch/alpha/defconfig Tue Jan 14 16:46:07 1997 +++ linux/arch/alpha/defconfig Thu Mar 27 14:36:38 1997 @@ -36,7 +36,6 @@ CONFIG_ALPHA_EV5=y CONFIG_ALPHA_CIA=y CONFIG_ALPHA_SRM=y -# CONFIG_SERIAL_ECHO is not set CONFIG_TGA_CONSOLE=y CONFIG_NET=y CONFIG_SYSVIPC=y @@ -203,6 +202,8 @@ # # Character devices # +CONFIG_VT=y +CONFIG_VT_CONSOLE=y CONFIG_SERIAL=y # CONFIG_DIGI is not set # CONFIG_CYCLADES is not set diff -u --recursive --new-file v2.1.30/linux/arch/i386/boot/compressed/misc.c linux/arch/i386/boot/compressed/misc.c --- v2.1.30/linux/arch/i386/boot/compressed/misc.c Mon Jan 27 01:24:21 1997 +++ linux/arch/i386/boot/compressed/misc.c Fri Mar 28 13:49:35 1997 @@ -74,24 +74,6 @@ static void gzip_release(void **); /* - * These are set up by the setup-routine at boot-time: - */ - -struct screen_info { - unsigned char orig_x; - unsigned char orig_y; - unsigned char unused1[2]; - unsigned short orig_video_page; - unsigned char orig_video_mode; - unsigned char orig_video_cols; - unsigned short unused2; - unsigned short orig_video_ega_bx; - unsigned short unused3; - unsigned char orig_video_lines; - unsigned char orig_video_isVGA; -}; - -/* * This is set up by the setup-routine at boot-time */ #define EXT_MEM_K (*(unsigned short *)0x90002) Binary files v2.1.30/linux/arch/i386/boot/map and linux/arch/i386/boot/map differ diff -u --recursive --new-file v2.1.30/linux/arch/i386/defconfig linux/arch/i386/defconfig --- v2.1.30/linux/arch/i386/defconfig Thu Mar 27 14:39:59 1997 +++ linux/arch/i386/defconfig Mon Mar 31 13:26:35 1997 @@ -167,6 +167,7 @@ # CONFIG_SLIP is not set # CONFIG_TR is not set # CONFIG_LAPBETHER is not set +# CONFIG_X25_ASY is not set # # ISDN subsystem @@ -197,11 +198,14 @@ # CONFIG_SYSV_FS is not set # CONFIG_AFFS_FS is not set # CONFIG_ROMFS_FS is not set +CONFIG_AUTOFS_FS=y # CONFIG_UFS_FS is not set # # Character devices # +CONFIG_VT=y +CONFIG_VT_CONSOLE=y CONFIG_SERIAL=y # CONFIG_SERIAL_EXTENDED is not set # CONFIG_SERIAL_NONSTANDARD is not set diff -u --recursive --new-file v2.1.30/linux/arch/i386/kernel/bios32.c linux/arch/i386/kernel/bios32.c --- v2.1.30/linux/arch/i386/kernel/bios32.c Mon Dec 23 09:25:31 1996 +++ linux/arch/i386/kernel/bios32.c Mon Mar 31 12:52:24 1997 @@ -49,6 +49,9 @@ * Dec 7, 1996 : Added support for direct configuration access of boards * with Intel compatible access schemes (tsbogend@alpha.franken.de) * + * Feb 3, 1997 : Set internal functions to static, save/restore flags + * avoid dead locks reading broken PCI BIOS, werner@suse.de + * */ #include @@ -59,6 +62,7 @@ #include #include +#include #include #define PCIBIOS_PCI_FUNCTION_ID 0xb1XX @@ -137,7 +141,7 @@ /* * pointer to selected PCI access function table */ -struct pci_access *access_pci = NULL; +static struct pci_access *access_pci = NULL; @@ -151,7 +155,9 @@ unsigned long address; /* %ebx */ unsigned long length; /* %ecx */ unsigned long entry; /* %edx */ + unsigned long flags; + save_flags(flags); __asm__("lcall (%%edi)" : "=a" (return_code), "=b" (address), @@ -160,6 +166,7 @@ : "0" (service), "1" (0), "D" (&bios32_indirect)); + restore_flags(flags); switch (return_code) { case 0: @@ -187,11 +194,13 @@ unsigned char present_status; unsigned char major_revision; unsigned char minor_revision; + unsigned long flags; int pack; if ((pcibios_entry = bios32_service(PCI_SERVICE))) { pci_indirect.address = pcibios_entry | PAGE_OFFSET; + save_flags(flags); __asm__("lcall (%%edi)\n\t" "jc 1f\n\t" "xor %%ah, %%ah\n" @@ -202,6 +211,7 @@ : "1" (PCIBIOS_PCI_BIOS_PRESENT), "D" (&pci_indirect) : "bx", "cx"); + restore_flags(flags); present_status = (pack >> 16) & 0xff; major_revision = (pack >> 8) & 0xff; @@ -227,12 +237,14 @@ } -int pci_bios_find_class (unsigned int class_code, unsigned short index, +static int pci_bios_find_class (unsigned int class_code, unsigned short index, unsigned char *bus, unsigned char *device_fn) { unsigned long bx; unsigned long ret; + unsigned long flags; + save_flags(flags); __asm__ ("lcall (%%edi)\n\t" "jc 1f\n\t" "xor %%ah, %%ah\n" @@ -243,18 +255,21 @@ "c" (class_code), "S" ((int) index), "D" (&pci_indirect)); + restore_flags(flags); *bus = (bx >> 8) & 0xff; *device_fn = bx & 0xff; return (int) (ret & 0xff00) >> 8; } -int pci_bios_find_device (unsigned short vendor, unsigned short device_id, +static int pci_bios_find_device (unsigned short vendor, unsigned short device_id, unsigned short index, unsigned char *bus, unsigned char *device_fn) { unsigned short bx; unsigned short ret; + unsigned long flags; + save_flags(flags); __asm__("lcall (%%edi)\n\t" "jc 1f\n\t" "xor %%ah, %%ah\n" @@ -266,17 +281,20 @@ "d" (vendor), "S" ((int) index), "D" (&pci_indirect)); + restore_flags(flags); *bus = (bx >> 8) & 0xff; *device_fn = bx & 0xff; return (int) (ret & 0xff00) >> 8; } -int pci_bios_read_config_byte(unsigned char bus, +static int pci_bios_read_config_byte(unsigned char bus, unsigned char device_fn, unsigned char where, unsigned char *value) { unsigned long ret; unsigned long bx = (bus << 8) | device_fn; + unsigned long flags; + save_flags(flags); __asm__("lcall (%%esi)\n\t" "jc 1f\n\t" "xor %%ah, %%ah\n" @@ -287,15 +305,18 @@ "b" (bx), "D" ((long) where), "S" (&pci_indirect)); + restore_flags(flags); return (int) (ret & 0xff00) >> 8; } -int pci_bios_read_config_word (unsigned char bus, +static int pci_bios_read_config_word (unsigned char bus, unsigned char device_fn, unsigned char where, unsigned short *value) { unsigned long ret; unsigned long bx = (bus << 8) | device_fn; + unsigned long flags; + save_flags(flags); __asm__("lcall (%%esi)\n\t" "jc 1f\n\t" "xor %%ah, %%ah\n" @@ -306,15 +327,18 @@ "b" (bx), "D" ((long) where), "S" (&pci_indirect)); + restore_flags(flags); return (int) (ret & 0xff00) >> 8; } -int pci_bios_read_config_dword (unsigned char bus, +static int pci_bios_read_config_dword (unsigned char bus, unsigned char device_fn, unsigned char where, unsigned int *value) { unsigned long ret; unsigned long bx = (bus << 8) | device_fn; + unsigned long flags; + save_flags(flags); __asm__("lcall (%%esi)\n\t" "jc 1f\n\t" "xor %%ah, %%ah\n" @@ -325,15 +349,18 @@ "b" (bx), "D" ((long) where), "S" (&pci_indirect)); + restore_flags(flags); return (int) (ret & 0xff00) >> 8; } -int pci_bios_write_config_byte (unsigned char bus, +static int pci_bios_write_config_byte (unsigned char bus, unsigned char device_fn, unsigned char where, unsigned char value) { unsigned long ret; unsigned long bx = (bus << 8) | device_fn; + unsigned long flags; + save_flags(flags); __asm__("lcall (%%esi)\n\t" "jc 1f\n\t" "xor %%ah, %%ah\n" @@ -344,15 +371,18 @@ "b" (bx), "D" ((long) where), "S" (&pci_indirect)); + restore_flags(flags); return (int) (ret & 0xff00) >> 8; } -int pci_bios_write_config_word (unsigned char bus, +static int pci_bios_write_config_word (unsigned char bus, unsigned char device_fn, unsigned char where, unsigned short value) { unsigned long ret; unsigned long bx = (bus << 8) | device_fn; + unsigned long flags; + save_flags(flags); __asm__("lcall (%%esi)\n\t" "jc 1f\n\t" "xor %%ah, %%ah\n" @@ -363,15 +393,18 @@ "b" (bx), "D" ((long) where), "S" (&pci_indirect)); + restore_flags(flags); return (int) (ret & 0xff00) >> 8; } -int pci_bios_write_config_dword (unsigned char bus, +static int pci_bios_write_config_dword (unsigned char bus, unsigned char device_fn, unsigned char where, unsigned int value) { unsigned long ret; unsigned long bx = (bus << 8) | device_fn; + unsigned long flags; + save_flags(flags); __asm__("lcall (%%esi)\n\t" "jc 1f\n\t" "xor %%ah, %%ah\n" @@ -382,13 +415,14 @@ "b" (bx), "D" ((long) where), "S" (&pci_indirect)); + restore_flags(flags); return (int) (ret & 0xff00) >> 8; } /* * function table for BIOS32 access */ -struct pci_access pci_bios_access = { +static struct pci_access pci_bios_access = { pci_bios_find_device, pci_bios_find_class, pci_bios_read_config_byte, @@ -405,23 +439,27 @@ * Given the vendor and device ids, find the n'th instance of that device * in the system. */ -int pci_direct_find_device (unsigned short vendor, unsigned short device_id, +static int pci_direct_find_device (unsigned short vendor, unsigned short device_id, unsigned short index, unsigned char *bus, unsigned char *devfn) { unsigned int curr = 0; struct pci_dev *dev; + unsigned long flags; + save_flags(flags); for (dev = pci_devices; dev; dev = dev->next) { if (dev->vendor == vendor && dev->device == device_id) { if (curr == index) { *devfn = dev->devfn; *bus = dev->bus->number; + restore_flags(flags); return PCIBIOS_SUCCESSFUL; } ++curr; } } + restore_flags(flags); return PCIBIOS_DEVICE_NOT_FOUND; } @@ -430,22 +468,26 @@ * Given the class, find the n'th instance of that device * in the system. */ -int pci_direct_find_class (unsigned int class_code, unsigned short index, +static int pci_direct_find_class (unsigned int class_code, unsigned short index, unsigned char *bus, unsigned char *devfn) { unsigned int curr = 0; struct pci_dev *dev; + unsigned long flags; + save_flags(flags); for (dev = pci_devices; dev; dev = dev->next) { if (dev->class == class_code) { if (curr == index) { *devfn = dev->devfn; *bus = dev->bus->number; + restore_flags(flags); return PCIBIOS_SUCCESSFUL; } ++curr; } } + restore_flags(flags); return PCIBIOS_DEVICE_NOT_FOUND; } @@ -454,9 +496,12 @@ */ #define CONFIG_CMD(bus, device_fn, where) (0x80000000 | (bus << 16) | (device_fn << 8) | (where & ~3)) -int pci_conf1_read_config_byte(unsigned char bus, unsigned char device_fn, +static int pci_conf1_read_config_byte(unsigned char bus, unsigned char device_fn, unsigned char where, unsigned char *value) { + unsigned long flags; + + save_flags(flags); outl(CONFIG_CMD(bus,device_fn,where), 0xCF8); switch (where & 3) { case 0: *value = inb(0xCFC); @@ -468,49 +513,70 @@ case 3: *value = inb(0xCFF); break; } + restore_flags(flags); return PCIBIOS_SUCCESSFUL; } -int pci_conf1_read_config_word (unsigned char bus, +static int pci_conf1_read_config_word (unsigned char bus, unsigned char device_fn, unsigned char where, unsigned short *value) { + unsigned long flags; + + save_flags(flags); outl(CONFIG_CMD(bus,device_fn,where), 0xCF8); if (where & 2) *value = inw(0xCFE); else *value = inw(0xCFC); + restore_flags(flags); return PCIBIOS_SUCCESSFUL; } -int pci_conf1_read_config_dword (unsigned char bus, unsigned char device_fn, +static int pci_conf1_read_config_dword (unsigned char bus, unsigned char device_fn, unsigned char where, unsigned int *value) { + unsigned long flags; + + save_flags(flags); outl(CONFIG_CMD(bus,device_fn,where), 0xCF8); *value = inl(0xCFC); + restore_flags(flags); return PCIBIOS_SUCCESSFUL; } -int pci_conf1_write_config_byte (unsigned char bus, unsigned char device_fn, +static int pci_conf1_write_config_byte (unsigned char bus, unsigned char device_fn, unsigned char where, unsigned char value) { + unsigned long flags; + + save_flags(flags); outl(CONFIG_CMD(bus,device_fn,where), 0xCF8); outb(value, 0xCFC); + restore_flags(flags); return PCIBIOS_SUCCESSFUL; } -int pci_conf1_write_config_word (unsigned char bus, unsigned char device_fn, +static int pci_conf1_write_config_word (unsigned char bus, unsigned char device_fn, unsigned char where, unsigned short value) { + unsigned long flags; + + save_flags(flags); outl(CONFIG_CMD(bus,device_fn,where), 0xCF8); outw(value, 0xCFC); + restore_flags(flags); return PCIBIOS_SUCCESSFUL; } -int pci_conf1_write_config_dword (unsigned char bus, unsigned char device_fn, +static int pci_conf1_write_config_dword (unsigned char bus, unsigned char device_fn, unsigned char where, unsigned int value) { + unsigned long flags; + + save_flags(flags); outl(CONFIG_CMD(bus,device_fn,where), 0xCF8); outl(value, 0xCFC); + restore_flags(flags); return PCIBIOS_SUCCESSFUL; } @@ -519,7 +585,7 @@ /* * functiontable for type 1 */ -struct pci_access pci_direct_conf1 = { +static struct pci_access pci_direct_conf1 = { pci_direct_find_device, pci_direct_find_class, pci_conf1_read_config_byte, @@ -536,69 +602,93 @@ #define IOADDR(devfn, where) ((0xC000 | ((devfn & 0x78) << 5)) + where) #define FUNC(devfn) (((devfn & 7) << 1) | 0xf0) -int pci_conf2_read_config_byte(unsigned char bus, unsigned char device_fn, +static int pci_conf2_read_config_byte(unsigned char bus, unsigned char device_fn, unsigned char where, unsigned char *value) { + unsigned long flags; + if (device_fn & 0x80) return PCIBIOS_DEVICE_NOT_FOUND; + save_flags(flags); outb (FUNC(device_fn), 0xCF8); outb (bus, 0xCFA); *value = inb(IOADDR(device_fn,where)); outb (0, 0xCF8); + restore_flags(flags); return PCIBIOS_SUCCESSFUL; } -int pci_conf2_read_config_word (unsigned char bus, unsigned char device_fn, +static int pci_conf2_read_config_word (unsigned char bus, unsigned char device_fn, unsigned char where, unsigned short *value) { + unsigned long flags; + if (device_fn & 0x80) return PCIBIOS_DEVICE_NOT_FOUND; + save_flags(flags); outb (FUNC(device_fn), 0xCF8); outb (bus, 0xCFA); *value = inw(IOADDR(device_fn,where)); - outb (0, 0xCF8); + outb (0, 0xCF8); + restore_flags(flags); return PCIBIOS_SUCCESSFUL; } -int pci_conf2_read_config_dword (unsigned char bus, unsigned char device_fn, +static int pci_conf2_read_config_dword (unsigned char bus, unsigned char device_fn, unsigned char where, unsigned int *value) { + unsigned long flags; + if (device_fn & 0x80) return PCIBIOS_DEVICE_NOT_FOUND; + save_flags(flags); outb (FUNC(device_fn), 0xCF8); outb (bus, 0xCFA); *value = inl (IOADDR(device_fn,where)); outb (0, 0xCF8); + restore_flags(flags); return PCIBIOS_SUCCESSFUL; } -int pci_conf2_write_config_byte (unsigned char bus, unsigned char device_fn, +static int pci_conf2_write_config_byte (unsigned char bus, unsigned char device_fn, unsigned char where, unsigned char value) { + unsigned long flags; + + save_flags(flags); outb (FUNC(device_fn), 0xCF8); outb (bus, 0xCFA); outb (value, IOADDR(device_fn,where)); outb (0, 0xCF8); + restore_flags(flags); return PCIBIOS_SUCCESSFUL; } -int pci_conf2_write_config_word (unsigned char bus, unsigned char device_fn, +static int pci_conf2_write_config_word (unsigned char bus, unsigned char device_fn, unsigned char where, unsigned short value) { + unsigned long flags; + + save_flags(flags); outb (FUNC(device_fn), 0xCF8); outb (bus, 0xCFA); outw (value, IOADDR(device_fn,where)); outb (0, 0xCF8); + restore_flags(flags); return PCIBIOS_SUCCESSFUL; } -int pci_conf2_write_config_dword (unsigned char bus, unsigned char device_fn, +static int pci_conf2_write_config_dword (unsigned char bus, unsigned char device_fn, unsigned char where, unsigned int value) { + unsigned long flags; + + save_flags(flags); outb (FUNC(device_fn), 0xCF8); outb (bus, 0xCFA); outl (value, IOADDR(device_fn,where)); outb (0, 0xCF8); + restore_flags(flags); return PCIBIOS_SUCCESSFUL; } @@ -608,7 +698,7 @@ /* * functiontable for type 2 */ -struct pci_access pci_direct_conf2 = { +static struct pci_access pci_direct_conf2 = { pci_direct_find_device, pci_direct_find_class, pci_conf2_read_config_byte, @@ -620,9 +710,12 @@ }; -struct pci_access *check_direct_pci(void) +static struct pci_access *check_direct_pci(void) { unsigned int tmp; + unsigned long flags; + + save_flags(flags); /* * check if configuration type 1 works @@ -632,6 +725,7 @@ outl (0x80000000, 0xCF8); if (inl (0xCF8) == 0x80000000) { outl (tmp, 0xCF8); + restore_flags(flags); printk("pcibios_init: Using configuration type 1\n"); return &pci_direct_conf1; } @@ -644,9 +738,11 @@ outb (0x00, 0xCF8); outb (0x00, 0xCFA); if (inb (0xCF8) == 0x00 && inb (0xCFC) == 0x00) { + restore_flags(flags); printk("pcibios_init: Using configuration type 2\n"); return &pci_direct_conf2; } + restore_flags(flags); printk("pcibios_init: Not supported chipset for direct PCI access !\n"); return NULL; } diff -u --recursive --new-file v2.1.30/linux/arch/i386/kernel/i386_ksyms.c linux/arch/i386/kernel/i386_ksyms.c --- v2.1.30/linux/arch/i386/kernel/i386_ksyms.c Thu Mar 27 14:39:59 1997 +++ linux/arch/i386/kernel/i386_ksyms.c Mon Mar 31 13:25:25 1997 @@ -24,7 +24,7 @@ EXPORT_SYMBOL(__verify_write); EXPORT_SYMBOL(dump_thread); EXPORT_SYMBOL(dump_fpu); -EXPORT_SYMBOL(ioremap); +EXPORT_SYMBOL(__ioremap); EXPORT_SYMBOL(iounmap); EXPORT_SYMBOL_NOVERS(__down_failed); EXPORT_SYMBOL_NOVERS(__down_failed_interruptible); @@ -44,6 +44,7 @@ #ifdef CONFIG_MCA /* Adapter probing and info methods. */ +EXPORT_SYMBOL(mca_find_adapter); EXPORT_SYMBOL(mca_write_pos); EXPORT_SYMBOL(mca_read_pos); EXPORT_SYMBOL(mca_read_stored_pos); diff -u --recursive --new-file v2.1.30/linux/arch/i386/kernel/irq.c linux/arch/i386/kernel/irq.c --- v2.1.30/linux/arch/i386/kernel/irq.c Thu Mar 27 14:39:59 1997 +++ linux/arch/i386/kernel/irq.c Mon Mar 31 12:52:24 1997 @@ -334,11 +334,6 @@ #define irq_active(cpu) \ (global_irq_count != local_irq_count[cpu]) -#define INIT_STUCK 10000000 - -#define STUCK(x) \ -if (!--stuck) {printk(#x " stuck at %08lx, waiting for %08lx\n", where, previous); stuck = INIT_STUCK;} - /* * "global_cli()" is a special case, in that it can hold the * interrupts disabled for a longish time, and also because @@ -355,31 +350,19 @@ } } -static inline void get_irqlock(int cpu, unsigned long where) +static unsigned long previous_irqholder; + +#undef INIT_STUCK +#define INIT_STUCK 10000000 + +#undef STUCK +#define STUCK \ +if (!--stuck) {printk("wait_on_irq stuck at %08lx, waiting for %08lx (local=%d, global=%d)\n", where, previous_irqholder, local_count, global_irq_count); stuck = INIT_STUCK;} + +static inline void wait_on_irq(int cpu, unsigned long where) { -static unsigned long previous; - int local_count; int stuck = INIT_STUCK; - - if (set_bit(0,&global_irq_lock)) { - /* do we already hold the lock? */ - if ((unsigned char) cpu == global_irq_holder) - return; - /* Uhhuh.. Somebody else got it. Wait.. */ - do { - do { - STUCK(irqlock1); - check_smp_invalidate(cpu); - } while (test_bit(0,&global_irq_lock)); - } while (set_bit(0,&global_irq_lock)); - } - /* - * Ok, we got the lock bit. - * But that's actually just the easy part.. Now - * we need to make sure that nobody else is running - * in an interrupt context. - */ - local_count = local_irq_count[cpu]; + int local_count = local_irq_count[cpu]; /* Are we the only one in an interrupt context? */ while (local_count != global_irq_count) { @@ -397,7 +380,7 @@ * their things before trying to get the lock again. */ for (;;) { - STUCK(irqlock2); + STUCK; check_smp_invalidate(cpu); if (global_irq_count) continue; @@ -408,12 +391,44 @@ } atomic_add(local_count, &global_irq_count); } +} + +#undef INIT_STUCK +#define INIT_STUCK 10000000 + +#undef STUCK +#define STUCK \ +if (!--stuck) {printk("get_irqlock stuck at %08lx, waiting for %08lx\n", where, previous_irqholder); stuck = INIT_STUCK;} + +static inline void get_irqlock(int cpu, unsigned long where) +{ + int stuck = INIT_STUCK; + + if (set_bit(0,&global_irq_lock)) { + /* do we already hold the lock? */ + if ((unsigned char) cpu == global_irq_holder) + return; + /* Uhhuh.. Somebody else got it. Wait.. */ + do { + do { + STUCK; + check_smp_invalidate(cpu); + } while (test_bit(0,&global_irq_lock)); + } while (set_bit(0,&global_irq_lock)); + } + /* + * Ok, we got the lock bit. + * But that's actually just the easy part.. Now + * we need to make sure that nobody else is running + * in an interrupt context. + */ + wait_on_irq(cpu, where); /* * Finally. */ global_irq_holder = cpu; - previous = where; + previous_irqholder = where; } void __global_cli(void) @@ -485,8 +500,8 @@ #else -#define irq_enter(cpu, irq) do { } while (0) -#define irq_exit(cpu, irq) do { } while (0) +#define irq_enter(cpu, irq) (++intr_count) +#define irq_exit(cpu, irq) (--intr_count) #endif diff -u --recursive --new-file v2.1.30/linux/arch/i386/kernel/process.c linux/arch/i386/kernel/process.c --- v2.1.30/linux/arch/i386/kernel/process.c Thu Mar 27 14:39:59 1997 +++ linux/arch/i386/kernel/process.c Mon Mar 31 10:26:12 1997 @@ -149,7 +149,15 @@ { if(cpu_data[smp_processor_id()].hlt_works_ok && !hlt_counter && !need_resched) __asm("hlt"); - run_task_queue(&tq_scheduler); + /* + * tq_scheduler currently assumes we're running in a process + * context (ie that we hold the kernel lock..) + */ + if (tq_scheduler) { + lock_kernel(); + run_task_queue(&tq_scheduler); + unlock_kernel(); + } schedule(); } } @@ -203,7 +211,7 @@ doesn't work with at least one type of 486 motherboard. It is easy to stop this code working; hence the copious comments. */ -unsigned long long +static unsigned long long real_mode_gdt_entries [3] = { 0x0000000000000000ULL, /* Null descriptor */ @@ -211,7 +219,7 @@ 0x000092000100ffffULL /* 16-bit real-mode 64k data at 0x00000100 */ }; -struct +static struct { unsigned short size __attribute__ ((packed)); unsigned long long * base __attribute__ ((packed)); @@ -238,7 +246,7 @@ More could be done here to set up the registers as if a CPU reset had occurred; hopefully real BIOSes don't assume much. */ -unsigned char real_mode_switch [] = +static unsigned char real_mode_switch [] = { 0x66, 0x0f, 0x20, 0xc0, /* movl %cr0,%eax */ 0x66, 0x83, 0xe0, 0x11, /* andl $0x00000011,%eax */ diff -u --recursive --new-file v2.1.30/linux/arch/i386/kernel/time.c linux/arch/i386/kernel/time.c --- v2.1.30/linux/arch/i386/kernel/time.c Thu Mar 27 14:39:59 1997 +++ linux/arch/i386/kernel/time.c Mon Mar 31 10:26:12 1997 @@ -245,7 +245,7 @@ /* * this is only used if we have fast gettimeoffset: */ -void do_x86_get_fast_time(struct timeval * tv) +static void do_x86_get_fast_time(struct timeval * tv) { do_gettimeofday(tv); } @@ -454,7 +454,7 @@ )*60 + sec; /* finally seconds */ } -unsigned long get_cmos_time(void) +static unsigned long get_cmos_time(void) { unsigned int year, mon, day, hour, min, sec; int i; diff -u --recursive --new-file v2.1.30/linux/arch/i386/mm/ioremap.c linux/arch/i386/mm/ioremap.c --- v2.1.30/linux/arch/i386/mm/ioremap.c Wed Sep 25 02:12:50 1996 +++ linux/arch/i386/mm/ioremap.c Fri Mar 28 10:49:40 1997 @@ -9,11 +9,10 @@ */ #include - #include static inline void remap_area_pte(pte_t * pte, unsigned long address, unsigned long size, - unsigned long phys_addr) + unsigned long phys_addr, unsigned long flags) { unsigned long end; @@ -24,7 +23,8 @@ do { if (!pte_none(*pte)) printk("remap_area_pte: page already exists\n"); - set_pte(pte, mk_pte_phys(phys_addr, PAGE_KERNEL)); + set_pte(pte, mk_pte_phys(phys_addr, __pgprot(_PAGE_PRESENT | _PAGE_RW | + _PAGE_DIRTY | _PAGE_ACCESSED | flags))); address += PAGE_SIZE; phys_addr += PAGE_SIZE; pte++; @@ -32,7 +32,7 @@ } static inline int remap_area_pmd(pmd_t * pmd, unsigned long address, unsigned long size, - unsigned long phys_addr) + unsigned long phys_addr, unsigned long flags) { unsigned long end; @@ -45,14 +45,15 @@ pte_t * pte = pte_alloc_kernel(pmd, address); if (!pte) return -ENOMEM; - remap_area_pte(pte, address, end - address, address + phys_addr); + remap_area_pte(pte, address, end - address, address + phys_addr, flags); address = (address + PMD_SIZE) & PMD_MASK; pmd++; } while (address < end); return 0; } -static int remap_area_pages(unsigned long address, unsigned long phys_addr, unsigned long size) +static int remap_area_pages(unsigned long address, unsigned long phys_addr, + unsigned long size, unsigned long flags) { pgd_t * dir; unsigned long end = address + size; @@ -64,7 +65,8 @@ pmd_t *pmd = pmd_alloc_kernel(dir, address); if (!pmd) return -ENOMEM; - if (remap_area_pmd(pmd, address, end - address, phys_addr + address)) + if (remap_area_pmd(pmd, address, end - address, + phys_addr + address, flags)) return -ENOMEM; set_pgdir(address, *dir); address = (address + PGDIR_SIZE) & PGDIR_MASK; @@ -75,11 +77,15 @@ } /* + * Generic mapping function (not visible outside): + */ + +/* * Remap an arbitrary physical address space into the kernel virtual * address space. Needed when the kernel wants to access high addresses * directly. */ -void * ioremap(unsigned long phys_addr, unsigned long size) +void * __ioremap(unsigned long phys_addr, unsigned long size, unsigned long flags) { void * addr; struct vm_struct * area; @@ -95,7 +101,7 @@ if (!area) return NULL; addr = area->addr; - if (remap_area_pages(VMALLOC_VMADDR(addr), phys_addr, size)) { + if (remap_area_pages(VMALLOC_VMADDR(addr), phys_addr, size, flags)) { vfree(addr); return NULL; } diff -u --recursive --new-file v2.1.30/linux/arch/m68k/Makefile linux/arch/m68k/Makefile --- v2.1.30/linux/arch/m68k/Makefile Fri Dec 20 01:19:57 1996 +++ linux/arch/m68k/Makefile Thu Mar 27 14:36:38 1997 @@ -48,7 +48,7 @@ HEAD := arch/m68k/kernel/head.o -SUBDIRS += arch/m68k/kernel arch/m68k/mm arch/m68k/console arch/m68k/lib +SUBDIRS += arch/m68k/kernel arch/m68k/mm arch/m68k/lib ARCHIVES := arch/m68k/kernel/kernel.o arch/m68k/mm/mm.o $(ARCHIVES) LIBS += arch/m68k/lib/lib.a @@ -67,8 +67,11 @@ SUBDIRS := $(SUBDIRS) arch/m68k/mac endif +ifdef CONFIG_VT # add in console.a after {amiga,atari}.o that need it ARCHIVES := $(ARCHIVES) arch/m68k/console/console.a +SUBDIRS := $(SUBDIRS) arch/m68k/console +endif ifdef CONFIG_M68040 ARCHIVES := $(ARCHIVES) arch/m68k/fpsp040/fpsp.o diff -u --recursive --new-file v2.1.30/linux/arch/m68k/atari/joystick.c linux/arch/m68k/atari/joystick.c --- v2.1.30/linux/arch/m68k/atari/joystick.c Fri Nov 22 05:56:34 1996 +++ linux/arch/m68k/atari/joystick.c Wed Apr 2 17:43:19 1997 @@ -54,7 +54,7 @@ /* ikbd_joystick_event_on(); */ } -static void release_joystick(struct inode *inode, struct file *file) +static int release_joystick(struct inode *inode, struct file *file) { int minor = DEVICE_NR(inode->i_rdev); @@ -63,6 +63,7 @@ if ((joystick[0].active == 0) && (joystick[1].active == 0)) ikbd_joystick_disable(); + return 0; } static int open_joystick(struct inode *inode, struct file *file) diff -u --recursive --new-file v2.1.30/linux/arch/m68k/config.in linux/arch/m68k/config.in --- v2.1.30/linux/arch/m68k/config.in Fri Dec 20 01:19:58 1996 +++ linux/arch/m68k/config.in Thu Mar 27 14:36:38 1997 @@ -199,6 +199,9 @@ mainmenu_option next_comment comment 'Character devices' +define_bool CONFIG_VT y +define_bool CONFIG_VT_CONSOLE y + tristate 'Parallel printer support' CONFIG_PRINTER if [ "$CONFIG_AMIGA" = "y" ]; then dep_tristate 'Multiface Card III parallel support' CONFIG_MULTIFACE_III_LP $CONFIG_PRINTER diff -u --recursive --new-file v2.1.30/linux/arch/m68k/defconfig linux/arch/m68k/defconfig --- v2.1.30/linux/arch/m68k/defconfig Tue Jan 14 02:59:10 1997 +++ linux/arch/m68k/defconfig Thu Mar 27 14:36:38 1997 @@ -168,6 +168,8 @@ # # Character devices # +CONFIG_VT=y +CONFIG_VT_CONSOLE=y # CONFIG_PRINTER is not set CONFIG_AMIGAMOUSE=y CONFIG_ATARIMOUSE=y diff -u --recursive --new-file v2.1.30/linux/arch/m68k/kernel/Makefile linux/arch/m68k/kernel/Makefile --- v2.1.30/linux/arch/m68k/kernel/Makefile Fri Jan 3 01:33:25 1997 +++ linux/arch/m68k/kernel/Makefile Thu Mar 27 14:36:38 1997 @@ -13,7 +13,10 @@ all: kernel.o head.o O_TARGET := kernel.o O_OBJS := entry.o process.o traps.o ints.o signal.o ptrace.o \ - setup.o bios32.o sys_m68k.o console.o time.o + setup.o bios32.o sys_m68k.o time.o +ifdef CONFIG_VT +O_OBJS += console.o +endif OX_OBJS := m68k_ksyms.o head.o: head.S diff -u --recursive --new-file v2.1.30/linux/arch/m68k/kernel/console.c linux/arch/m68k/kernel/console.c --- v2.1.30/linux/arch/m68k/kernel/console.c Fri Dec 20 01:19:58 1996 +++ linux/arch/m68k/kernel/console.c Thu Mar 27 14:36:38 1997 @@ -178,6 +178,17 @@ static int vesa_off_interval = 0; static int vesa_blank_mode = 0; /* 0:none 1:suspendV 2:suspendH 3:powerdown */ +/* + * fg_console is the current virtual console, + * last_console is the last used one, + * want_console is the console we want to switch to, + * kmsg_redirect is the console for kernel messages, + */ +int fg_console = 0; +int last_console = 0; +int want_console = -1; +int kmsg_redirect = 0; + static struct vc { struct vc_data *d; @@ -1003,6 +1014,56 @@ int currcons = fg_console; return report_mouse; +} + +int tioclinux(struct tty_struct *tty, unsigned long arg) +{ + char type, data; + + if (tty->driver.type != TTY_DRIVER_TYPE_CONSOLE) + return -EINVAL; + if (current->tty != tty && !suser()) + return -EPERM; + if (get_user(type, (char *)arg)) + return -EFAULT; + switch (type) + { + case 2: + return set_selection(arg, tty, 1); + case 3: + return paste_selection(tty); + case 4: + do_unblank_screen(); + return 0; + case 5: + return sel_loadlut(arg); + case 6: + + /* + * Make it possible to react to Shift+Mousebutton. + * Note that 'shift_state' is an undocumented + * kernel-internal variable; programs not closely + * related to the kernel should not use this. + */ + data = shift_state; + return put_user(data, (char *) arg); + case 7: + data = mouse_reporting(); + return put_user(data, (char *) arg); + case 10: + set_vesa_blanking(arg); + return 0; + case 11: /* set kmsg redirect */ + if (!suser()) + return -EPERM; + if (get_user(data, (char *)arg+1)) + return -EFAULT; + kmsg_redirect = data; + return 0; + case 12: /* get fg_console */ + return fg_console; + } + return -EINVAL; } static inline unsigned short *screenpos(int currcons, int offset, int viewed) diff -u --recursive --new-file v2.1.30/linux/arch/mips/defconfig linux/arch/mips/defconfig --- v2.1.30/linux/arch/mips/defconfig Tue Jan 14 02:59:10 1997 +++ linux/arch/mips/defconfig Thu Mar 27 14:36:38 1997 @@ -64,6 +64,8 @@ # # character devices # +CONFIG_VT=y +CONFIG_VT_CONSOLE=y # CONFIG_CYCLADES is not set # CONFIG_STALDRV is not set # CONFIG_PRINTER is not set diff -u --recursive --new-file v2.1.30/linux/arch/sparc/config.in linux/arch/sparc/config.in --- v2.1.30/linux/arch/sparc/config.in Mon Mar 17 14:54:20 1997 +++ linux/arch/sparc/config.in Thu Mar 27 14:36:38 1997 @@ -21,6 +21,9 @@ mainmenu_option next_comment comment 'General setup' +define_bool CONFIG_VT y +define_bool CONFIG_VT_CONSOLE y + bool 'Support for AP1000 multicomputer' CONFIG_AP1000 if [ "$CONFIG_AP1000" = "y" ]; then diff -u --recursive --new-file v2.1.30/linux/arch/sparc/defconfig linux/arch/sparc/defconfig --- v2.1.30/linux/arch/sparc/defconfig Thu Mar 27 14:39:59 1997 +++ linux/arch/sparc/defconfig Thu Mar 27 14:36:38 1997 @@ -17,6 +17,8 @@ # # General setup # +CONFIG_VT=y +CONFIG_VT_CONSOLE=y # CONFIG_AP1000 is not set CONFIG_SBUS=y CONFIG_SBUSCHAR=y diff -u --recursive --new-file v2.1.30/linux/arch/sparc64/config.in linux/arch/sparc64/config.in --- v2.1.30/linux/arch/sparc64/config.in Mon Dec 30 01:59:59 1996 +++ linux/arch/sparc64/config.in Thu Mar 27 14:36:39 1997 @@ -21,6 +21,9 @@ mainmenu_option next_comment comment 'General setup' +define_bool CONFIG_VT y +define_bool CONFIG_VT_CONSOLE y + bool 'Support for AP1000 multicomputer' CONFIG_AP1000 if [ "$CONFIG_AP1000" = "y" ]; then diff -u --recursive --new-file v2.1.30/linux/arch/sparc64/defconfig linux/arch/sparc64/defconfig --- v2.1.30/linux/arch/sparc64/defconfig Thu Mar 27 14:40:00 1997 +++ linux/arch/sparc64/defconfig Thu Mar 27 14:36:39 1997 @@ -17,6 +17,8 @@ # # General setup # +CONFIG_VT=y +CONFIG_VT_CONSOLE=y # CONFIG_AP1000 is not set CONFIG_SBUS=y CONFIG_SBUSCHAR=y diff -u --recursive --new-file v2.1.30/linux/drivers/block/amiflop.c linux/drivers/block/amiflop.c --- v2.1.30/linux/drivers/block/amiflop.c Fri Dec 20 01:20:00 1996 +++ linux/drivers/block/amiflop.c Wed Apr 2 17:43:19 1997 @@ -1779,7 +1779,7 @@ return 0; } -static void floppy_release(struct inode * inode, struct file * filp) +static int floppy_release(struct inode * inode, struct file * filp) { unsigned long flags; @@ -1803,6 +1803,7 @@ /* the mod_use counter is handled this way */ floppy_off (inode->i_rdev & 3); #endif + return 0; } void amiga_floppy_setup (char *str, int *ints) diff -u --recursive --new-file v2.1.30/linux/drivers/block/ataflop.c linux/drivers/block/ataflop.c --- v2.1.30/linux/drivers/block/ataflop.c Fri Dec 20 01:20:00 1996 +++ linux/drivers/block/ataflop.c Wed Apr 2 17:43:19 1997 @@ -1946,7 +1946,7 @@ } -static void floppy_release( struct inode * inode, struct file * filp ) +static int floppy_release( struct inode * inode, struct file * filp ) { int drive; @@ -1966,6 +1966,7 @@ } MOD_DEC_USE_COUNT; + return 0; } static struct file_operations floppy_fops = { diff -u --recursive --new-file v2.1.30/linux/drivers/block/floppy.c linux/drivers/block/floppy.c --- v2.1.30/linux/drivers/block/floppy.c Thu Mar 27 14:40:02 1997 +++ linux/drivers/block/floppy.c Wed Apr 2 17:43:19 1997 @@ -3493,7 +3493,7 @@ return ret; } -static void floppy_release(struct inode * inode, struct file * filp) +static int floppy_release(struct inode * inode, struct file * filp) { int drive; @@ -3511,6 +3511,7 @@ UDRS->fd_ref = 0; } floppy_release_irq_and_dma(); + return 0; } /* diff -u --recursive --new-file v2.1.30/linux/drivers/block/genhd.c linux/drivers/block/genhd.c --- v2.1.30/linux/drivers/block/genhd.c Mon Dec 30 02:06:22 1996 +++ linux/drivers/block/genhd.c Thu Mar 27 14:36:39 1997 @@ -733,7 +733,9 @@ #ifdef CONFIG_INET net_dev_init(); #endif +#ifdef CONFIG_VT console_map_init(); +#endif for (p = gendisk_head ; p ; p=p->next) { setup_dev(p); diff -u --recursive --new-file v2.1.30/linux/drivers/block/hd.c linux/drivers/block/hd.c --- v2.1.30/linux/drivers/block/hd.c Sun Jan 26 02:07:10 1997 +++ linux/drivers/block/hd.c Wed Apr 2 17:43:19 1997 @@ -656,14 +656,14 @@ * Releasing a block device means we sync() it, so that it can safely * be forgotten about... */ -static void hd_release(struct inode * inode, struct file * file) +static int hd_release(struct inode * inode, struct file * file) { int target; sync_dev(inode->i_rdev); target = DEVICE_NR(inode->i_rdev); access_count[target]--; - + return 0; } static void hd_geninit(struct gendisk *); diff -u --recursive --new-file v2.1.30/linux/drivers/block/ide-tape.c linux/drivers/block/ide-tape.c --- v2.1.30/linux/drivers/block/ide-tape.c Thu Mar 27 14:40:02 1997 +++ linux/drivers/block/ide-tape.c Wed Apr 2 17:43:20 1997 @@ -3271,7 +3271,7 @@ /* * Our character device release function. */ -static void idetape_chrdev_release (struct inode *inode, struct file *filp) +static int idetape_chrdev_release (struct inode *inode, struct file *filp) { ide_drive_t *drive = get_drive_ptr (inode->i_rdev); idetape_tape_t *tape = drive->driver_data; @@ -3310,6 +3310,7 @@ clear_bit (IDETAPE_BUSY, &tape->flags); if (tape->chrdev_direction == idetape_direction_none) MOD_DEC_USE_COUNT; + return 0; } /* diff -u --recursive --new-file v2.1.30/linux/drivers/block/ide.c linux/drivers/block/ide.c --- v2.1.30/linux/drivers/block/ide.c Thu Mar 27 14:40:02 1997 +++ linux/drivers/block/ide.c Wed Apr 2 17:53:11 1997 @@ -1710,7 +1710,7 @@ * Releasing a block device means we sync() it, so that it can safely * be forgotten about... */ -static void ide_release(struct inode * inode, struct file * file) +static int ide_release(struct inode * inode, struct file * file) { ide_drive_t *drive; @@ -1721,6 +1721,7 @@ DRIVER(drive)->release(inode, file, drive); MOD_DEC_USE_COUNT; } + return 0; } void ide_unregister (unsigned int index) diff -u --recursive --new-file v2.1.30/linux/drivers/block/loop.c linux/drivers/block/loop.c --- v2.1.30/linux/drivers/block/loop.c Sun Jan 26 02:07:10 1997 +++ linux/drivers/block/loop.c Wed Apr 2 17:43:20 1997 @@ -12,6 +12,8 @@ * Modularized and updated for 1.1.16 kernel - Mitch Dsouza 28th May 1994 * * Adapted for 1.3.59 kernel - Andries Brouwer, 1 Feb 1996 + * + * Fixed do_loop_request() re-entrancy - Mar 20, 1997 */ #include @@ -181,12 +183,15 @@ char *dest_addr; struct loop_device *lo; struct buffer_head *bh; + struct request *current_request; repeat: INIT_REQUEST; - if (MINOR(CURRENT->rq_dev) >= MAX_LOOP) + current_request=CURRENT; + CURRENT=current_request->next; + if (MINOR(current_request->rq_dev) >= MAX_LOOP) goto error_out; - lo = &loop_dev[MINOR(CURRENT->rq_dev)]; + lo = &loop_dev[MINOR(current_request->rq_dev)]; if (!lo->lo_inode || !lo->transfer) goto error_out; @@ -197,14 +202,14 @@ blksize = BLOCK_SIZE; } - dest_addr = CURRENT->buffer; + dest_addr = current_request->buffer; if (blksize < 512) { - block = CURRENT->sector * (512/blksize); + block = current_request->sector * (512/blksize); offset = 0; } else { - block = CURRENT->sector / (blksize >> 9); - offset = (CURRENT->sector % (blksize >> 9)) << 9; + block = current_request->sector / (blksize >> 9); + offset = (current_request->sector % (blksize >> 9)) << 9; } block += lo->lo_offset / blksize; offset += lo->lo_offset % blksize; @@ -212,13 +217,13 @@ block++; offset -= blksize; } - len = CURRENT->current_nr_sectors << 9; + len = current_request->current_nr_sectors << 9; - if (CURRENT->cmd == WRITE) { + if (current_request->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); + } else if (current_request->cmd != READ) { + printk("unknown loop device command (%d)?!?", current_request->cmd); goto error_out; } while (len > 0) { @@ -237,7 +242,7 @@ block, blksize); goto error_out; } - if (!buffer_uptodate(bh) && ((CURRENT->cmd == READ) || + if (!buffer_uptodate(bh) && ((current_request->cmd == READ) || (offset || (len < blksize)))) { ll_rw_block(READ, 1, &bh); wait_on_buffer(bh); @@ -250,13 +255,13 @@ if (size > len) size = len; - if ((lo->transfer)(lo, CURRENT->cmd, bh->b_data + offset, + if ((lo->transfer)(lo, current_request->cmd, bh->b_data + offset, dest_addr, size)) { printk("loop: transfer error block %d\n", block); brelse(bh); goto error_out; } - if (CURRENT->cmd == WRITE) { + if (current_request->cmd == WRITE) { mark_buffer_uptodate(bh, 1); mark_buffer_dirty(bh, 1); } @@ -266,9 +271,13 @@ offset = 0; block++; } + current_request->next=CURRENT; + CURRENT=current_request; end_request(1); goto repeat; error_out: + current_request->next=CURRENT; + CURRENT=current_request; end_request(0); goto repeat; } @@ -484,20 +493,20 @@ return 0; } -static void lo_release(struct inode *inode, struct file *file) +static int lo_release(struct inode *inode, struct file *file) { struct loop_device *lo; int dev; if (!inode) - return; + return 0; if (MAJOR(inode->i_rdev) != MAJOR_NR) { printk("lo_release: pseudo-major != %d\n", MAJOR_NR); - return; + return 0; } dev = MINOR(inode->i_rdev); if (dev >= MAX_LOOP) - return; + return 0; fsync_dev(inode->i_rdev); lo = &loop_dev[dev]; if (lo->lo_refcnt <= 0) @@ -506,6 +515,7 @@ lo->lo_refcnt--; MOD_DEC_USE_COUNT; } + return 0; } static struct file_operations lo_fops = { diff -u --recursive --new-file v2.1.30/linux/drivers/block/md.c linux/drivers/block/md.c --- v2.1.30/linux/drivers/block/md.c Fri Dec 27 02:03:20 1996 +++ linux/drivers/block/md.c Wed Apr 2 17:43:20 1997 @@ -362,12 +362,13 @@ } -static void md_release (struct inode *inode, struct file *file) +static int md_release (struct inode *inode, struct file *file) { int minor=MINOR(inode->i_rdev); sync_dev (inode->i_rdev); md_dev[minor].busy--; + return 0; } diff -u --recursive --new-file v2.1.30/linux/drivers/block/ps2esdi.c linux/drivers/block/ps2esdi.c --- v2.1.30/linux/drivers/block/ps2esdi.c Sun Jan 26 02:07:11 1997 +++ linux/drivers/block/ps2esdi.c Wed Apr 2 17:43:20 1997 @@ -89,7 +89,7 @@ static int ps2esdi_open(struct inode *inode, struct file *file); -static void ps2esdi_release(struct inode *inode, struct file *file); +static int ps2esdi_release(struct inode *inode, struct file *file); static int ps2esdi_ioctl(struct inode *inode, struct file *file, u_int cmd, u_long arg); @@ -1060,7 +1060,7 @@ -static void ps2esdi_release(struct inode *inode, struct file *file) +static int ps2esdi_release(struct inode *inode, struct file *file) { int dev = DEVICE_NR(MINOR(inode->i_rdev)); @@ -1068,6 +1068,7 @@ sync_dev(dev); access_count[dev]--; } + return 0; } diff -u --recursive --new-file v2.1.30/linux/drivers/block/rd.c linux/drivers/block/rd.c --- v2.1.30/linux/drivers/block/rd.c Sun Jan 26 02:07:11 1997 +++ linux/drivers/block/rd.c Wed Apr 2 17:43:20 1997 @@ -196,7 +196,7 @@ } -static void initrd_release(struct inode *inode,struct file *file) +static int initrd_release(struct inode *inode,struct file *file) { unsigned long i; @@ -204,6 +204,7 @@ for (i = initrd_start; i < initrd_end; i += PAGE_SIZE) free_page(i); initrd_start = 0; + return 0; } @@ -243,9 +244,10 @@ } #ifdef MODULE -static void rd_release(struct inode * inode, struct file * filp) +static int rd_release(struct inode * inode, struct file * filp) { MOD_DEC_USE_COUNT; + return 0; } #endif diff -u --recursive --new-file v2.1.30/linux/drivers/block/triton.c linux/drivers/block/triton.c --- v2.1.30/linux/drivers/block/triton.c Thu Mar 27 14:40:02 1997 +++ linux/drivers/block/triton.c Thu Mar 27 13:08:54 1997 @@ -443,7 +443,10 @@ const char *chipset = "ide"; piix_timing_t timings[2]; - if (pcibios_read_config_word(piix_pci_bus, piix_pci_fn, 0x02, &devid)) + piix_pci_bus = bus; + piix_pci_fn = fn; + + if (pcibios_read_config_word(bus, fn, 0x02, &devid)) goto quit; chipset = (devid == PCI_DEVICE_ID_INTEL_82371SB_1) ? "PIIX3" : "PIIX"; @@ -462,14 +465,11 @@ goto quit; if ((rc = pcibios_read_config_word(bus, fn, 0x42, (short *)&timings[1]))) goto quit; - if ((!timings[0].ports_enabled) || (!timings[1].ports_enabled)) { + if ((!timings[0].ports_enabled) && (!timings[1].ports_enabled)) { printk("%s: neither IDE port is enabled\n", chipset); goto quit; } - piix_pci_bus = bus; - piix_pci_fn = fn; - /* * See if Bus-Mastered DMA is enabled */ @@ -534,7 +534,7 @@ byte recovery = 4 - timing.recovery; if (devid == PCI_DEVICE_ID_INTEL_82371SB_1 && timing.sidetim_enabled - && !pcibios_read_config_byte(piix_pci_bus, piix_pci_fn, 0x44, (byte *) &sidetim)) + && !pcibios_read_config_byte(bus, fn, 0x44, (byte *) &sidetim)) slave = ""; /* PIIX3 */ else slave = "/slave"; /* PIIX, or PIIX3 in compatibility mode */ diff -u --recursive --new-file v2.1.30/linux/drivers/block/xd.c linux/drivers/block/xd.c --- v2.1.30/linux/drivers/block/xd.c Sun Jan 26 02:07:11 1997 +++ linux/drivers/block/xd.c Wed Apr 2 17:43:20 1997 @@ -294,7 +294,7 @@ } /* xd_release: release the device */ -static void xd_release (struct inode *inode, struct file *file) +static int xd_release (struct inode *inode, struct file *file) { int target; @@ -303,6 +303,7 @@ sync_dev(inode->i_rdev); xd_access[target]--; } + return 0; } /* xd_reread_partitions: rereads the partition table from a drive */ diff -u --recursive --new-file v2.1.30/linux/drivers/cdrom/aztcd.c linux/drivers/cdrom/aztcd.c --- v2.1.30/linux/drivers/cdrom/aztcd.c Sun Jan 26 02:07:11 1997 +++ linux/drivers/cdrom/aztcd.c Wed Apr 2 17:43:20 1997 @@ -330,7 +330,7 @@ static void do_aztcd_request(void); static void azt_invalidate_buffers(void); int aztcd_open(struct inode *ip, struct file *fp); -static void aztcd_release(struct inode * inode, struct file * file); +static int aztcd_release(struct inode * inode, struct file * file); int aztcd_init(void); #ifdef MODULE int init_module(void); @@ -1542,7 +1542,7 @@ /* * On close, we flush all azt blocks from the buffer cache. */ -static void aztcd_release(struct inode * inode, struct file * file) +static int aztcd_release(struct inode * inode, struct file * file) { #ifdef AZT_DEBUG printk("aztcd: executing aztcd_release\n"); @@ -1558,7 +1558,7 @@ aztSendCmd(ACMD_EJECT); CLEAR_TIMER; } - return; + return 0; } diff -u --recursive --new-file v2.1.30/linux/drivers/cdrom/cdrom.c linux/drivers/cdrom/cdrom.c --- v2.1.30/linux/drivers/cdrom/cdrom.c Sun Jan 26 02:07:11 1997 +++ linux/drivers/cdrom/cdrom.c Wed Apr 2 17:43:20 1997 @@ -27,7 +27,7 @@ /* Not-exported routines. */ static int cdrom_open(struct inode *ip, struct file *fp); -static void cdrom_release(struct inode *ip, struct file *fp); +static int cdrom_release(struct inode *ip, struct file *fp); static int cdrom_ioctl(struct inode *ip, struct file *fp, unsigned int cmd, unsigned long arg); static int cdrom_media_changed(kdev_t dev); @@ -196,14 +196,14 @@ /* Admittedly, the logic below could be performed in a nicer way. */ static -void cdrom_release(struct inode *ip, struct file *fp) +int cdrom_release(struct inode *ip, struct file *fp) { kdev_t dev = ip->i_rdev; struct cdrom_device_info *cdi = cdrom_find_device (dev); struct cdrom_device_ops *cdo; if (cdi == NULL) - return; + return 0; cdo = cdi->ops; if (cdi->use_count == 1 && /* last process that closes dev*/ cdi->options & CDO_LOCK && @@ -218,6 +218,7 @@ cdo->capability & ~cdi->mask & CDC_OPEN_TRAY) cdo->tray_move(cdi, 1); } + return 0; } /* We want to make media_changed accessible to the user through an diff -u --recursive --new-file v2.1.30/linux/drivers/cdrom/cdu31a.c linux/drivers/cdrom/cdu31a.c --- v2.1.30/linux/drivers/cdrom/cdu31a.c Sun Jan 26 02:07:11 1997 +++ linux/drivers/cdrom/cdu31a.c Wed Apr 2 17:43:20 1997 @@ -171,6 +171,8 @@ * still here, if the eject button is pushed while the * drive light is flashing, the drive will return a bad * status and be reset. It recovers, though. + * + * 03/07/97 - Fixed a problem with timers. */ #include @@ -933,6 +935,9 @@ volatile int val; +#if DEBUG + printk("Entering handle_sony_cd_attention\n"); +#endif if (is_attention()) { if (num_consecutive_attentions > CDU31A_MAX_CONSECUTIVE_ATTENTIONS) @@ -940,6 +945,9 @@ printk("cdu31a: Too many consecutive attentions: %d\n", num_consecutive_attentions); num_consecutive_attentions = 0; +#if DEBUG + printk("Leaving handle_sony_cd_attention at %d\n", __LINE__); +#endif return(0); } @@ -982,6 +990,9 @@ } num_consecutive_attentions++; +#if DEBUG + printk("Leaving handle_sony_cd_attention at %d\n", __LINE__); +#endif return(1); } else if (abort_read_started) @@ -998,10 +1009,16 @@ val = read_data_register(); } abort_read_started = 0; +#if DEBUG + printk("Leaving handle_sony_cd_attention at %d\n", __LINE__); +#endif return(1); } num_consecutive_attentions = 0; +#if DEBUG + printk("Leaving handle_sony_cd_attention at %d\n", __LINE__); +#endif return(0); } @@ -1090,6 +1107,9 @@ unsigned int retry_count; +#if DEBUG + printk("Entering start_request\n"); +#endif log_to_msf(sector, params); /* If requested, read exactly what was asked. */ if (read_nsect_only) @@ -1130,6 +1150,9 @@ if (is_busy()) { printk("CDU31A: Timeout while waiting to issue command\n"); +#if DEBUG + printk("Leaving start_request at %d\n", __LINE__); +#endif return(1); } else @@ -1145,8 +1168,14 @@ sony_next_block = sector * 4; readahead_dataleft = 0; readahead_bad = 0; +#if DEBUG + printk("Leaving start_request at %d\n", __LINE__); +#endif return(0); } +#if DEBUG + printk("Leaving start_request at %d\n", __LINE__); +#endif } /* Abort a pending read operation. Clear all the drive status and @@ -1188,6 +1217,13 @@ static void handle_abort_timeout(unsigned long data) { + unsigned long flags; + +#if DEBUG + printk("Entering handle_abort_timeout\n"); +#endif + save_flags(flags); + cli(); /* If it is in use, ignore it. */ if (!sony_inuse) { @@ -1204,6 +1240,10 @@ readahead_bad = 0; abort_read_started = 1; } + restore_flags(flags); +#if DEBUG + printk("Leaving handle_abort_timeout\n"); +#endif } /* Actually get data and status from the drive. */ @@ -1218,6 +1258,9 @@ volatile unsigned char val; +#if DEBUG + printk("Entering input_data\n"); +#endif /* If an XA disk on a CDU31A, skip the first 12 bytes of data from the disk. The real data is after that. */ if (sony_xa_mode) @@ -1266,6 +1309,9 @@ val = read_data_register(); } } +#if DEBUG + printk("Leaving input_data at %d\n", __LINE__); +#endif } /* read data from the drive. Note the nsect must be <= 4. */ @@ -1282,6 +1328,10 @@ unsigned int skip; +#if DEBUG + printk("Entering read_data_block\n"); +#endif + res_reg[0] = 0; res_reg[1] = 0; *res_size = 0; @@ -1347,6 +1397,9 @@ { get_result(res_reg, res_size); } +#if DEBUG + printk("Leaving read_data_block at %d\n", __LINE__); +#endif return; } } @@ -1466,6 +1519,9 @@ } } } +#if DEBUG + printk("Leaving read_data_block at %d\n", __LINE__); +#endif } /* @@ -1486,6 +1542,10 @@ unsigned long flags; +#if DEBUG + printk("Entering do_cdu31a_request\n"); +#endif + /* * Make sure no one else is using the driver; wait for them * to finish if it is so. @@ -1503,6 +1563,9 @@ end_request(0); } restore_flags(flags); +#if DEBUG + printk("Leaving do_cdu31a_request at %d\n", __LINE__); +#endif return; } } @@ -1518,11 +1581,8 @@ sti(); - /* If the timer is running, cancel it. */ - if (cdu31a_abort_timer.next != NULL) - { - del_timer(&cdu31a_abort_timer); - } + /* Make sure the timer is cancelled. */ + del_timer(&cdu31a_abort_timer); while (1) { @@ -1694,6 +1754,7 @@ } end_do_cdu31a_request: + cli(); #if 0 /* After finished, cancel any pending operations. */ abort_read(); @@ -1708,6 +1769,9 @@ sony_inuse = 0; wake_up_interruptible(&sony_wait); restore_flags(flags); +#if DEBUG + printk("Leaving do_cdu31a_request at %d\n", __LINE__); +#endif } /* Copy overlapping buffers. */ @@ -2852,7 +2916,7 @@ * Close the drive. Spin it down if no task is using it. The spin * down will fail if playing audio, so audio play is OK. */ -static void +static int scd_release(struct inode *inode, struct file *filp) { @@ -2877,6 +2941,7 @@ sony_spun_up = 0; } + return 0; } @@ -3141,8 +3206,7 @@ /* use 'mount -o block=2048' */ blksize_size[MAJOR_NR] = &cdu31a_block_size; - cdu31a_abort_timer.next = NULL; - cdu31a_abort_timer.prev = NULL; + init_timer(&cdu31a_abort_timer); cdu31a_abort_timer.function = handle_abort_timeout; } diff -u --recursive --new-file v2.1.30/linux/drivers/cdrom/gscd.c linux/drivers/cdrom/gscd.c --- v2.1.30/linux/drivers/cdrom/gscd.c Sun Jan 26 02:07:11 1997 +++ linux/drivers/cdrom/gscd.c Wed Apr 2 17:43:20 1997 @@ -87,7 +87,7 @@ static void do_gscd_request (void); static int gscd_ioctl (struct inode *, struct file *, unsigned int, unsigned long); static int gscd_open (struct inode *, struct file *); -static void gscd_release (struct inode *, struct file *); +static int gscd_release (struct inode *, struct file *); static int check_gscd_med_chg (kdev_t); /* GoldStar Funktionen */ @@ -394,7 +394,7 @@ * On close, we flush all gscd blocks from the buffer cache. */ -static void gscd_release (struct inode * inode, struct file * file) +static int gscd_release (struct inode * inode, struct file * file) { #ifdef GSCD_DEBUG @@ -406,6 +406,7 @@ invalidate_buffers(inode -> i_rdev); MOD_DEC_USE_COUNT; + return 0; } diff -u --recursive --new-file v2.1.30/linux/drivers/cdrom/mcd.c linux/drivers/cdrom/mcd.c --- v2.1.30/linux/drivers/cdrom/mcd.c Sun Jan 26 02:07:11 1997 +++ linux/drivers/cdrom/mcd.c Wed Apr 2 17:43:20 1997 @@ -1142,7 +1142,7 @@ * On close, we flush all mcd blocks from the buffer cache. */ -static void +static int mcd_release(struct inode * inode, struct file * file) { MOD_DEC_USE_COUNT; if (!--mcd_open_count) { @@ -1150,6 +1150,7 @@ sync_dev(inode->i_rdev); invalidate_buffers(inode -> i_rdev); } + return 0; } diff -u --recursive --new-file v2.1.30/linux/drivers/cdrom/mcdx.c linux/drivers/cdrom/mcdx.c --- v2.1.30/linux/drivers/cdrom/mcdx.c Sun Jan 26 02:07:11 1997 +++ linux/drivers/cdrom/mcdx.c Wed Apr 2 17:43:20 1997 @@ -227,7 +227,7 @@ /* exported by file_ops */ static int mcdx_open(struct inode*, struct file*); -static void mcdx_close(struct inode*, struct file*); +static int mcdx_close(struct inode*, struct file*); static int mcdx_ioctl(struct inode*, struct file*, unsigned int, unsigned long); /* misc internal support functions */ @@ -860,7 +860,7 @@ } -static void +static int mcdx_close(struct inode *ip, struct file *fp) { struct s_drive_stuff *stuffp; @@ -889,7 +889,7 @@ } MOD_DEC_USE_COUNT; - return; + return 0; } int check_mcdx_media_change(kdev_t full_dev) diff -u --recursive --new-file v2.1.30/linux/drivers/cdrom/optcd.c linux/drivers/cdrom/optcd.c --- v2.1.30/linux/drivers/cdrom/optcd.c Sun Jan 26 02:07:11 1997 +++ linux/drivers/cdrom/optcd.c Wed Apr 2 17:43:20 1997 @@ -1914,7 +1914,7 @@ /* Release device special file; flush all blocks from the buffer cache */ -static void opt_release(struct inode *ip, struct file *fp) +static int opt_release(struct inode *ip, struct file *fp) { int status; @@ -1939,6 +1939,7 @@ CLEAR_REQ_TIMER; } MOD_DEC_USE_COUNT; + return 0; } diff -u --recursive --new-file v2.1.30/linux/drivers/cdrom/sbpcd.c linux/drivers/cdrom/sbpcd.c --- v2.1.30/linux/drivers/cdrom/sbpcd.c Sun Jan 26 02:07:11 1997 +++ linux/drivers/cdrom/sbpcd.c Wed Apr 2 17:43:20 1997 @@ -5200,7 +5200,7 @@ /* * On close, we flush all sbp blocks from the buffer cache. */ -static void sbpcd_release(struct inode * ip, struct file * file) +static int sbpcd_release(struct inode * ip, struct file * file) { int i; @@ -5208,7 +5208,7 @@ if ((i<0) || (i>=NR_SBPCD) || (D_S[i].drv_id==-1)) { msg(DBG_INF, "release: bad device: %04X\n", ip->i_rdev); - return; + return 0; } down(&ioctl_read_sem); switch_drive(i); @@ -5236,6 +5236,7 @@ } } up(&ioctl_read_sem); + return 0; } /*==========================================================================*/ /* diff -u --recursive --new-file v2.1.30/linux/drivers/cdrom/sjcd.c linux/drivers/cdrom/sjcd.c --- v2.1.30/linux/drivers/cdrom/sjcd.c Sun Feb 2 05:18:30 1997 +++ linux/drivers/cdrom/sjcd.c Wed Apr 2 17:43:21 1997 @@ -1385,7 +1385,7 @@ /* * On close, we flush all sjcd blocks from the buffer cache. */ -static void sjcd_release( struct inode *inode, struct file *file ){ +static int sjcd_release( struct inode *inode, struct file *file ){ int s; #if defined( SJCD_TRACE ) @@ -1413,6 +1413,7 @@ } } } + return 0; } /* diff -u --recursive --new-file v2.1.30/linux/drivers/cdrom/sonycd535.c linux/drivers/cdrom/sonycd535.c --- v2.1.30/linux/drivers/cdrom/sonycd535.c Sun Jan 26 02:07:12 1997 +++ linux/drivers/cdrom/sonycd535.c Wed Apr 2 17:43:21 1997 @@ -1434,7 +1434,7 @@ * Close the drive. Spin it down if no task is using it. The spin * down will fail if playing audio, so audio play is OK. */ -static void +static int cdu_release(struct inode *inode, struct file *filp) { @@ -1460,6 +1460,7 @@ do_sony_cmd(&cmd_no, 1, status, NULL, 0, 0); #endif } + return 0; } diff -u --recursive --new-file v2.1.30/linux/drivers/char/Config.in linux/drivers/char/Config.in --- v2.1.30/linux/drivers/char/Config.in Tue Mar 4 10:25:23 1997 +++ linux/drivers/char/Config.in Thu Mar 27 14:36:39 1997 @@ -4,6 +4,10 @@ mainmenu_option next_comment comment 'Character devices' +bool 'Virtual terminal' CONFIG_VT +if [ "$CONFIG_VT" = "y" ]; then + bool 'Console on virtual terminal' CONFIG_VT_CONSOLE +fi tristate 'Standard/generic (dumb) serial support' CONFIG_SERIAL bool 'Extended dumb serial driver options' CONFIG_SERIAL_EXTENDED if [ "$CONFIG_SERIAL_EXTENDED" = "y" ]; then @@ -11,6 +15,7 @@ bool ' Support for sharing serial interrupts' CONFIG_SERIAL_SHARE_IRQ bool ' Support special multiport boards' CONFIG_SERIAL_MULTIPORT bool ' Support the Bell Technologies HUB6 card' CONFIG_HUB6 + bool ' Console on serial port' CONFIG_SERIAL_CONSOLE fi bool 'Non-standard serial port support' CONFIG_SERIAL_NONSTANDARD if [ "$CONFIG_SERIAL_NONSTANDARD" = "y" ]; then diff -u --recursive --new-file v2.1.30/linux/drivers/char/Makefile linux/drivers/char/Makefile --- v2.1.30/linux/drivers/char/Makefile Tue Dec 31 06:27:23 1996 +++ linux/drivers/char/Makefile Thu Mar 27 14:36:39 1997 @@ -20,9 +20,12 @@ L_TARGET := char.a M_OBJS := -L_OBJS := tty_io.o n_tty.o console.o \ - tty_ioctl.o pty.o vt.o mem.o vc_screen.o random.o \ - consolemap.o selection.o +L_OBJS := tty_io.o n_tty.o tty_ioctl.o pty.o mem.o random.o + +ifdef CONFIG_VT +L_OBJS += console.o vt.o vc_screen.o consolemap.o +LX_OBJS += selection.o +endif ifeq ($(CONFIG_SERIAL),y) ifndef CONFIG_SUN_SERIAL @@ -35,8 +38,10 @@ endif ifndef CONFIG_SUN_KEYBOARD +ifdef CONFIG_VT L_OBJS += keyboard.o defkeymap.o endif +endif ifeq ($(CONFIG_DIGI),y) L_OBJS += pcxx.o @@ -235,13 +240,15 @@ MX_OBJS += misc.o endif endif - -ifdef CONFIG_TGA_CONSOLE -L_OBJS += tga.o -else - ifndef CONFIG_SUN_CONSOLE - L_OBJS += vga.o vesa_blank.o - endif + +ifdef CONFIG_VT + ifdef CONFIG_TGA_CONSOLE + L_OBJS += tga.o + else + ifndef CONFIG_SUN_CONSOLE + L_OBJS += vga.o vesa_blank.o + endif + endif endif include $(TOPDIR)/Rules.make diff -u --recursive --new-file v2.1.30/linux/drivers/char/amigamouse.c linux/drivers/char/amigamouse.c --- v2.1.30/linux/drivers/char/amigamouse.c Sat Jan 25 13:46:13 1997 +++ linux/drivers/char/amigamouse.c Wed Apr 2 17:43:21 1997 @@ -172,7 +172,7 @@ * close access to the mouse */ -static void close_mouse(struct inode * inode, struct file * file) +static int close_mouse(struct inode * inode, struct file * file) { fasync_mouse(inode, file, 0); if (--mouse.active) @@ -180,6 +180,7 @@ free_irq(IRQ_AMIGA_VERTB, mouse_interrupt); MSE_INT_OFF(); MOD_DEC_USE_COUNT; + return 0; } /* diff -u --recursive --new-file v2.1.30/linux/drivers/char/apm_bios.c linux/drivers/char/apm_bios.c --- v2.1.30/linux/drivers/char/apm_bios.c Mon Mar 17 14:54:24 1997 +++ linux/drivers/char/apm_bios.c Wed Apr 2 17:43:21 1997 @@ -301,7 +301,7 @@ static void do_apm_timer(unsigned long); static int do_open(struct inode *, struct file *); -static void do_release(struct inode *, struct file *); +static int do_release(struct inode *, struct file *); static long do_read(struct inode *, struct file *, char *, unsigned long); static unsigned int do_poll(struct file *, poll_table *); static int do_ioctl(struct inode *, struct file *, u_int, u_long); @@ -911,14 +911,14 @@ return 0; } -static void do_release(struct inode * inode, struct file * filp) +static int do_release(struct inode * inode, struct file * filp) { struct apm_bios_struct * as; as = filp->private_data; filp->private_data = NULL; if (check_apm_bios_struct(as, "release")) - return; + return 0; if (as->standbys_pending > 0) { standbys_pending -= as->standbys_pending; if (standbys_pending <= 0) @@ -944,6 +944,7 @@ as1->next = as->next; } kfree_s(as, sizeof(*as)); + return 0; } static int do_open(struct inode * inode, struct file * filp) diff -u --recursive --new-file v2.1.30/linux/drivers/char/atarimouse.c linux/drivers/char/atarimouse.c --- v2.1.30/linux/drivers/char/atarimouse.c Sun Jan 26 02:07:12 1997 +++ linux/drivers/char/atarimouse.c Wed Apr 2 17:43:21 1997 @@ -62,15 +62,16 @@ return 0; } -static void release_mouse(struct inode *inode, struct file *file) +static int release_mouse(struct inode *inode, struct file *file) { fasync_mouse(inode, file, 0); if (--mouse.active) - return; + return 0; ikbd_mouse_disable(); atari_mouse_interrupt_hook = NULL; MOD_DEC_USE_COUNT; + return 0; } static int open_mouse(struct inode *inode, struct file *file) diff -u --recursive --new-file v2.1.30/linux/drivers/char/atixlmouse.c linux/drivers/char/atixlmouse.c --- v2.1.30/linux/drivers/char/atixlmouse.c Sun Jan 26 02:07:12 1997 +++ linux/drivers/char/atixlmouse.c Wed Apr 2 17:43:21 1997 @@ -104,15 +104,16 @@ return 0; } -static void release_mouse(struct inode * inode, struct file * file) +static int release_mouse(struct inode * inode, struct file * file) { fasync_mouse(inode, file, 0); if (--mouse.active) - return; + return 0; ATIXL_MSE_INT_OFF(); /* Interrupts are really shut down here */ mouse.ready = 0; free_irq(ATIXL_MOUSE_IRQ, NULL); MOD_DEC_USE_COUNT; + return 0; } static int open_mouse(struct inode * inode, struct file * file) diff -u --recursive --new-file v2.1.30/linux/drivers/char/busmouse.c linux/drivers/char/busmouse.c --- v2.1.30/linux/drivers/char/busmouse.c Sun Jan 26 02:07:14 1997 +++ linux/drivers/char/busmouse.c Wed Apr 2 17:43:21 1997 @@ -119,14 +119,15 @@ * close access to the mouse */ -static void close_mouse(struct inode * inode, struct file * file) +static int close_mouse(struct inode * inode, struct file * file) { fasync_mouse(inode, file, 0); if (--mouse.active) - return; + return 0; MSE_INT_OFF(); free_irq(mouse_irq, NULL); MOD_DEC_USE_COUNT; + return 0; } /* diff -u --recursive --new-file v2.1.30/linux/drivers/char/console.c linux/drivers/char/console.c --- v2.1.30/linux/drivers/char/console.c Sun Feb 2 05:52:22 1997 +++ linux/drivers/char/console.c Mon Mar 31 10:47:28 1997 @@ -18,7 +18,7 @@ * 'unsigned long con_init(unsigned long)' * 'int con_open(struct tty_struct *tty, struct file * filp)' * 'void con_write(struct tty_struct * tty)' - * 'void console_print(const char * b)' + * 'void vt_console_print(const char * b)' * 'void update_screen(int new_console)' * * 'void do_blank_screen(int)' @@ -91,6 +91,7 @@ #include #include #include +#include #include #include #include @@ -131,6 +132,7 @@ unsigned short *vc_scrbuf[MAX_NR_CONSOLES]; struct vc vc_cons [MAX_NR_CONSOLES]; +static int con_open(struct tty_struct *, struct file *); static void con_setsize(unsigned long rows, unsigned long cols); static void vc_init(unsigned int console, unsigned long rows, unsigned long cols, int do_clear); @@ -148,7 +150,7 @@ static void reset_terminal(int currcons, int do_clear); extern void reset_vc(unsigned int new_console); extern void vt_init(void); -extern void register_console(void (*proc)(const char *)); +extern void set_vesa_blanking(unsigned long arg); extern void vesa_blank(void); extern void vesa_unblank(void); extern void vesa_powerdown(void); @@ -178,7 +180,7 @@ int video_mode_512ch = 0; /* 512-character mode */ unsigned long video_font_height; /* Height of current screen font */ unsigned long video_scan_lines; /* Number of scan lines on screen */ -unsigned long default_font_height; /* Height of default screen font */ +static unsigned long default_font_height; /* Height of default screen font */ int video_font_is_default = 1; static unsigned short console_charmask = 0x0ff; @@ -189,121 +191,16 @@ static int vesa_off_interval = 0; static long blank_origin, blank__origin, unblank_origin; - -#ifdef CONFIG_SERIAL_ECHO - -#include - -extern int serial_echo_init (int base); -extern int serial_echo_print (const char *s); - /* - * this defines the address for the port to which printk echoing is done - * when CONFIG_SERIAL_ECHO is defined + * fg_console is the current virtual console, + * last_console is the last used one, + * want_console is the console we want to switch to, + * kmsg_redirect is the console for kernel messages, */ -#define SERIAL_ECHO_PORT 0x3f8 /* COM1 */ - -static int serial_echo_port = 0; - -#define serial_echo_outb(v,a) outb((v),(a)+serial_echo_port) -#define serial_echo_inb(a) inb((a)+serial_echo_port) - -#define BOTH_EMPTY (UART_LSR_TEMT | UART_LSR_THRE) - -/* Wait for transmitter & holding register to empty */ -#define WAIT_FOR_XMITR \ - do { \ - lsr = serial_echo_inb(UART_LSR); \ - } while ((lsr & BOTH_EMPTY) != BOTH_EMPTY) - -/* These two functions abstract the actual communications with the - * debug port. This is so we can change the underlying communications - * mechanism without modifying the rest of the code. - */ -int -serial_echo_print(const char *s) -{ - int lsr, ier; - int i; - - if (!serial_echo_port) return (0); - - /* - * First save the IER then disable the interrupts - */ - ier = serial_echo_inb(UART_IER); - serial_echo_outb(0x00, UART_IER); - - /* - * Now, do each character - */ - for (i = 0; *s; i++, s++) { - WAIT_FOR_XMITR; - - /* Send the character out. */ - serial_echo_outb(*s, UART_TX); - - /* if a LF, also do CR... */ - if (*s == 10) { - WAIT_FOR_XMITR; - serial_echo_outb(13, UART_TX); - } - } - - /* - * Finally, Wait for transmitter & holding register to empty - * and restore the IER - */ - do { - lsr = serial_echo_inb(UART_LSR); - } while ((lsr & BOTH_EMPTY) != BOTH_EMPTY); - serial_echo_outb(ier, UART_IER); - - return (0); -} - - -int -serial_echo_init(int base) -{ - int comstat, hi, lo; - - if (base != 0x2f8 && base != 0x3f8) { - serial_echo_port = 0; - return (0); - } else - serial_echo_port = base; - - /* - * read the Divisor Latch - */ - comstat = serial_echo_inb(UART_LCR); - serial_echo_outb(comstat | UART_LCR_DLAB, UART_LCR); - hi = serial_echo_inb(UART_DLM); - lo = serial_echo_inb(UART_DLL); - serial_echo_outb(comstat, UART_LCR); - - /* - * now do hardwired init - */ - serial_echo_outb(0x03, UART_LCR); /* No parity, 8 data bits, 1 stop */ - serial_echo_outb(0x83, UART_LCR); /* Access divisor latch */ - serial_echo_outb(0x00, UART_DLM); /* 9600 baud */ - serial_echo_outb(0x0c, UART_DLL); - serial_echo_outb(0x03, UART_LCR); /* Done with divisor */ - - /* Prior to disabling interrupts, read the LSR and RBR - * registers - */ - comstat = serial_echo_inb(UART_LSR); /* COM? LSR */ - comstat = serial_echo_inb(UART_RX); /* COM? RBR */ - serial_echo_outb(0x00, UART_IER); /* Disable all interrupts */ - - return(0); -} - -#endif /* CONFIG_SERIAL_ECHO */ - +int fg_console = 0; +int last_console = 0; +int want_console = -1; +int kmsg_redirect = 0; int vc_cons_allocated(unsigned int i) { @@ -599,7 +496,7 @@ __set_origin(__real_origin); } -void scrup(int currcons, unsigned int t, unsigned int b) +static void scrup(int currcons, unsigned int t, unsigned int b) { int hardscroll = hardscroll_enabled; @@ -653,7 +550,7 @@ } } -void +static void scrdown(int currcons, unsigned int t, unsigned int b) { unsigned short *s; @@ -949,7 +846,7 @@ respond_string(buf, tty); } -/* invoked via ioctl(TIOCLINUX) */ +/* invoked via ioctl(TIOCLINUX) and through set_selection */ int mouse_reporting(void) { int currcons = fg_console; @@ -957,6 +854,56 @@ return report_mouse; } +int tioclinux(struct tty_struct *tty, unsigned long arg) +{ + char type, data; + + if (tty->driver.type != TTY_DRIVER_TYPE_CONSOLE) + return -EINVAL; + if (current->tty != tty && !suser()) + return -EPERM; + if (get_user(type, (char *)arg)) + return -EFAULT; + switch (type) + { + case 2: + return set_selection(arg, tty, 1); + case 3: + return paste_selection(tty); + case 4: + do_unblank_screen(); + return 0; + case 5: + return sel_loadlut(arg); + case 6: + + /* + * Make it possible to react to Shift+Mousebutton. + * Note that 'shift_state' is an undocumented + * kernel-internal variable; programs not closely + * related to the kernel should not use this. + */ + data = shift_state; + return put_user(data, (char *) arg); + case 7: + data = mouse_reporting(); + return put_user(data, (char *) arg); + case 10: + set_vesa_blanking(arg); + return 0; + case 11: /* set kmsg redirect */ + if (!suser()) + return -EPERM; + if (get_user(data, (char *)arg+1)) + return -EFAULT; + kmsg_redirect = data; + return 0; + case 12: /* get fg_console */ + return fg_console; + } + return -EINVAL; +} + static inline unsigned short *screenpos(int currcons, int offset, int viewed) { unsigned short *p = (unsigned short *)(origin + offset); @@ -1877,7 +1824,8 @@ } } -void console_print(const char * b) +#ifdef CONFIG_VT_CONSOLE +void vt_console_print(const char * b, unsigned count) { int currcons = fg_console; unsigned char c; @@ -1896,15 +1844,12 @@ if (!vc_cons_allocated(currcons)) { /* impossible */ - printk("console_print: tty %d not allocated ??\n", currcons+1); + printk("vt_console_print: tty %d not allocated ??\n", currcons+1); return; } -#ifdef CONFIG_SERIAL_ECHO - serial_echo_print(b); -#endif /* CONFIG_SERIAL_ECHO */ - - while ((c = *(b++)) != 0) { + while (count-- > 0) { + c = *(b++); if (c == 10 || c == 13 || need_wrap) { if (c != 13) lf(currcons); @@ -1929,6 +1874,19 @@ printing = 0; } +static int vt_console_device(void) +{ + return MKDEV(TTY_MAJOR, fg_console + 1); +} + +extern void keyboard_wait_for_keypress(void); + +struct console vt_console_driver = { + vt_console_print, do_unblank_screen, + keyboard_wait_for_keypress, vt_console_device +}; +#endif + /* * con_throttle and con_unthrottle are only used for * paste_selection(), which has to stuff in a large number of @@ -2129,10 +2087,6 @@ /* This may be suboptimal but is a safe bet - go with it */ video_scan_lines = video_font_height * video_num_lines; -#ifdef CONFIG_SERIAL_ECHO - serial_echo_init(SERIAL_ECHO_PORT); -#endif /* CONFIG_SERIAL_ECHO */ - printk("Console: %ld point font, %ld scans\n", video_font_height, video_scan_lines); } @@ -2151,8 +2105,10 @@ * initialization and register_console() event from * within the bus probing code... :-( */ +#ifdef CONFIG_VT_CONSOLE if (video_type != VIDEO_TYPE_TGAC) - register_console(console_print); + register_console(&vt_console_driver); +#endif init_bh(CONSOLE_BH, console_bh); return kmem_start; @@ -2295,7 +2251,7 @@ /* * Allocate the console screen memory. */ -int con_open(struct tty_struct *tty, struct file * filp) +static int con_open(struct tty_struct *tty, struct file * filp) { unsigned int idx; int i; diff -u --recursive --new-file v2.1.30/linux/drivers/char/esp.c linux/drivers/char/esp.c --- v2.1.30/linux/drivers/char/esp.c Wed Feb 5 03:49:56 1997 +++ linux/drivers/char/esp.c Mon Mar 31 12:52:29 1997 @@ -290,7 +290,7 @@ int event) { info->event |= 1 << event; - queue_task_irq_off(&info->tqueue, &tq_esp); + queue_task(&info->tqueue, &tq_esp); mark_bh(ESP_BH); } @@ -354,13 +354,13 @@ memmove(info->tty_buf->char_buf, info->tty_buf->char_buf + x_bytes, info->tty_buf->count); - queue_task_irq_off(&info->tty_buf->tqueue, + queue_task(&info->tty_buf->tqueue, &tq_timer); } - queue_task_irq_off(&tty->flip.tqueue, &tq_timer); + queue_task(&tty->flip.tqueue, &tq_timer); } else { - queue_task_irq_off(&info->tty_buf->tqueue, &tq_timer); + queue_task(&info->tty_buf->tqueue, &tq_timer); } restore_flags(flags); @@ -429,9 +429,9 @@ buffer->flag_buf_ptr++; if (buffer == info->tty_buf) - queue_task_irq_off(&info->tty_buf->tqueue, &tq_timer); + queue_task(&info->tty_buf->tqueue, &tq_timer); - queue_task_irq_off(&tty->flip.tqueue, &tq_timer); + queue_task(&tty->flip.tqueue, &tq_timer); } if (dma_bytes != num_bytes) { @@ -560,7 +560,7 @@ #ifdef SERIAL_DEBUG_OPEN printk("scheduling hangup..."); #endif - queue_task_irq_off(&info->tqueue_hangup, + queue_task(&info->tqueue_hangup, &tq_scheduler); } } diff -u --recursive --new-file v2.1.30/linux/drivers/char/fbmem.c linux/drivers/char/fbmem.c --- v2.1.30/linux/drivers/char/fbmem.c Sun Jan 26 02:07:16 1997 +++ linux/drivers/char/fbmem.c Wed Apr 2 17:43:21 1997 @@ -247,15 +247,16 @@ return 0; } -static void +static int fb_release(struct inode *inode, struct file *file) { int fbidx=GET_FB_IDX(inode->i_rdev); int vidx=GET_FB_VAR_IDX(inode->i_rdev); if (! vidx) - return; + return 0; if (! (--fb_open_count[fbidx])) fb_curr_open[fbidx]=0; + return 0; } static struct file_operations fb_fops = { diff -u --recursive --new-file v2.1.30/linux/drivers/char/ftape/kernel-interface.c linux/drivers/char/ftape/kernel-interface.c --- v2.1.30/linux/drivers/char/ftape/kernel-interface.c Sun Jan 26 02:07:16 1997 +++ linux/drivers/char/ftape/kernel-interface.c Wed Apr 2 17:43:21 1997 @@ -58,7 +58,7 @@ static int old_sigmask; static int ftape_open(struct inode *ino, struct file *filep); -static void ftape_close(struct inode *ino, struct file *filep); +static int ftape_close(struct inode *ino, struct file *filep); static int ftape_ioctl(struct inode *ino, struct file *filep, unsigned int command, unsigned long arg); static long ftape_read(struct inode *ino, struct file *fp, @@ -260,7 +260,7 @@ /* Close ftape device */ -static void ftape_close(struct inode *ino, struct file *filep) +static int ftape_close(struct inode *ino, struct file *filep) { TRACE_FUN(4, "ftape_close"); int result; @@ -268,7 +268,7 @@ if (!busy_flag || MINOR(ino->i_rdev) != ftape_unit) { TRACE(1, "failed: not busy or wrong unit"); TRACE_EXIT; - return; /* keep busy_flag !(?) */ + return 0; /* keep busy_flag !(?) */ } current->blocked = _BLOCK_ALL; result = _ftape_close(); @@ -281,6 +281,7 @@ current->blocked = old_sigmask; /* restore before open state */ TRACE_EXIT; MOD_DEC_USE_COUNT; /* unlock module in memory */ + return 0; } /* Ioctl for ftape device diff -u --recursive --new-file v2.1.30/linux/drivers/char/keyb_m68k.c linux/drivers/char/keyb_m68k.c --- v2.1.30/linux/drivers/char/keyb_m68k.c Thu Nov 7 01:25:56 1996 +++ linux/drivers/char/keyb_m68k.c Thu Mar 27 14:36:39 1997 @@ -77,6 +77,13 @@ unsigned char kbd_read_mask = 0x01; /* modified by psaux.c */ +struct wait_queue * keypress_wait = NULL; + +void keyboard_wait_for_keypress(void) +{ + sleep_on(&keypress_wait); +} + /* * global state includes the following, and various static variables * in this module: prev_scancode, shift_state, diacr, npadch, dead_key_next. diff -u --recursive --new-file v2.1.30/linux/drivers/char/keyboard.c linux/drivers/char/keyboard.c --- v2.1.30/linux/drivers/char/keyboard.c Thu Mar 27 14:40:03 1997 +++ linux/drivers/char/keyboard.c Thu Mar 27 14:36:39 1997 @@ -71,13 +71,19 @@ #include #include -extern void poke_blanked_console(void); extern void ctrl_alt_del(void); extern void reset_vc(unsigned int new_console); extern void scrollback(int); extern void scrollfront(int); unsigned char kbd_read_mask = 0x01; /* modified by psaux.c */ + +struct wait_queue * keypress_wait = NULL; + +void keyboard_wait_for_keypress(void) +{ + sleep_on(&keypress_wait); +} /* * global state includes the following, and various static variables diff -u --recursive --new-file v2.1.30/linux/drivers/char/lp.c linux/drivers/char/lp.c --- v2.1.30/linux/drivers/char/lp.c Thu Feb 27 10:57:29 1997 +++ linux/drivers/char/lp.c Wed Apr 2 17:43:21 1997 @@ -485,7 +485,7 @@ return 0; } -static void lp_release(struct inode * inode, struct file * file) +static int lp_release(struct inode * inode, struct file * file) { unsigned int minor = MINOR(inode->i_rdev); unsigned int irq; @@ -498,6 +498,7 @@ LP_F(minor) &= ~LP_BUSY; MOD_DEC_USE_COUNT; + return 0; } diff -u --recursive --new-file v2.1.30/linux/drivers/char/lp_m68k.c linux/drivers/char/lp_m68k.c --- v2.1.30/linux/drivers/char/lp_m68k.c Sun Jan 26 02:07:16 1997 +++ linux/drivers/char/lp_m68k.c Wed Apr 2 17:43:21 1997 @@ -392,13 +392,14 @@ return 0; } -static void lp_release(struct inode *inode, struct file *file) +static int lp_release(struct inode *inode, struct file *file) { int dev =MINOR(inode->i_rdev); lp_table[dev]->flags &= ~LP_BUSY; lp_table[dev]->lp_release(); MOD_DEC_USE_COUNT; + return 0; } diff -u --recursive --new-file v2.1.30/linux/drivers/char/misc.c linux/drivers/char/misc.c --- v2.1.30/linux/drivers/char/misc.c Thu Mar 27 14:40:03 1997 +++ linux/drivers/char/misc.c Thu Mar 27 14:36:39 1997 @@ -179,10 +179,6 @@ EXPORT_SYMBOL(misc_register); EXPORT_SYMBOL(misc_deregister); -#ifndef MODULE -EXPORT_SYMBOL(set_selection); /* used by the kmouse module, can only */ -EXPORT_SYMBOL(paste_selection); /* be exported if misc.c is in linked in */ -#endif #if defined(CONFIG_PROC_FS) && !defined(MODULE) static struct proc_dir_entry *proc_misc; diff -u --recursive --new-file v2.1.30/linux/drivers/char/msbusmouse.c linux/drivers/char/msbusmouse.c --- v2.1.30/linux/drivers/char/msbusmouse.c Sun Jan 26 02:07:16 1997 +++ linux/drivers/char/msbusmouse.c Wed Apr 2 17:43:21 1997 @@ -98,15 +98,16 @@ return 0; } -static void release_mouse(struct inode * inode, struct file * file) +static int release_mouse(struct inode * inode, struct file * file) { fasync_mouse(inode, file, 0); if (--mouse.active) - return; + return 0; MS_MSE_INT_OFF(); mouse.ready = 0; free_irq(mouse_irq, NULL); MOD_DEC_USE_COUNT; + return 0; } static int open_mouse(struct inode * inode, struct file * file) diff -u --recursive --new-file v2.1.30/linux/drivers/char/pcwd.c linux/drivers/char/pcwd.c --- v2.1.30/linux/drivers/char/pcwd.c Sun Jan 19 05:47:24 1997 +++ linux/drivers/char/pcwd.c Wed Apr 2 17:43:21 1997 @@ -394,9 +394,10 @@ } } -static void pcwd_close(struct inode *ino, struct file *filep) +static int pcwd_close(struct inode *ino, struct file *filep) { MOD_DEC_USE_COUNT; + return 0; } static void get_support(void) diff -u --recursive --new-file v2.1.30/linux/drivers/char/psaux.c linux/drivers/char/psaux.c --- v2.1.30/linux/drivers/char/psaux.c Sat Jan 25 13:46:13 1997 +++ linux/drivers/char/psaux.c Wed Apr 2 17:54:00 1997 @@ -258,11 +258,11 @@ #endif -static void release_aux(struct inode * inode, struct file * file) +static int release_aux(struct inode * inode, struct file * file) { fasync_aux(inode, file, 0); if (--aux_count) - return; + return 0; /* disable kbd bh to avoid mixing of cmd bytes */ disable_bh(KEYBOARD_BH); aux_write_cmd(AUX_INTS_OFF); /* disable controller ints */ @@ -277,24 +277,26 @@ free_irq(AUX_IRQ, NULL); #endif MOD_DEC_USE_COUNT; + return 0; } #ifdef CONFIG_82C710_MOUSE -static void release_qp(struct inode * inode, struct file * file) +static int release_qp(struct inode * inode, struct file * file) { unsigned char status; fasync_aux(inode, file, 0); - if (--qp_count) - return; - if (!poll_qp_status()) - printk("Warning: Mouse device busy in release_qp()\n"); - status = inb_p(qp_status); - outb_p(status & ~(QP_ENABLE|QP_INTS_ON), qp_status); - if (!poll_qp_status()) - printk("Warning: Mouse device busy in release_qp()\n"); - free_irq(QP_IRQ, NULL); - MOD_DEC_USE_COUNT; + if (!--qp_count) { + if (!poll_qp_status()) + printk("Warning: Mouse device busy in release_qp()\n"); + status = inb_p(qp_status); + outb_p(status & ~(QP_ENABLE|QP_INTS_ON), qp_status); + if (!poll_qp_status()) + printk("Warning: Mouse device busy in release_qp()\n"); + free_irq(QP_IRQ, NULL); + MOD_DEC_USE_COUNT; + } + return 0; } #endif @@ -544,7 +546,9 @@ if (aux_device_present == 0xaa) { printk(KERN_INFO "PS/2 auxiliary pointing device detected -- driver installed.\n"); aux_present = 1; +#ifdef CONFIG_VT kbd_read_mask = AUX_OBUF_FULL; +#endif } else { return -EIO; } diff -u --recursive --new-file v2.1.30/linux/drivers/char/rtc.c linux/drivers/char/rtc.c --- v2.1.30/linux/drivers/char/rtc.c Mon Jan 27 01:24:28 1997 +++ linux/drivers/char/rtc.c Wed Apr 2 17:43:21 1997 @@ -462,7 +462,7 @@ return 0; } -static void rtc_release(struct inode *inode, struct file *file) +static int rtc_release(struct inode *inode, struct file *file) { /* @@ -490,6 +490,7 @@ rtc_irq_data = 0; rtc_status &= ~RTC_IS_OPEN; + return 0; } static unsigned int rtc_poll(struct file *file, poll_table *wait) diff -u --recursive --new-file v2.1.30/linux/drivers/char/selection.c linux/drivers/char/selection.c --- v2.1.30/linux/drivers/char/selection.c Mon Oct 28 13:49:41 1996 +++ linux/drivers/char/selection.c Thu Mar 27 14:36:39 1997 @@ -11,6 +11,8 @@ * Now that /dev/vcs exists, most of this can disappear again. */ +#include +#include #include #include #include @@ -306,3 +308,6 @@ current->state = TASK_RUNNING; return 0; } + +EXPORT_SYMBOL(set_selection); +EXPORT_SYMBOL(paste_selection); diff -u --recursive --new-file v2.1.30/linux/drivers/char/serial.c linux/drivers/char/serial.c --- v2.1.30/linux/drivers/char/serial.c Thu Mar 27 14:40:03 1997 +++ linux/drivers/char/serial.c Thu Mar 27 14:36:39 1997 @@ -3429,3 +3429,137 @@ } #endif /* MODULE */ + +/* + * ------------------------------------------------------------ + * Serial console driver + * ------------------------------------------------------------ + */ +#ifdef CONFIG_SERIAL_CONSOLE + +#include + +/* + * this defines the index into rs_table for the port to use + */ +#ifndef CONFIG_SERIAL_CONSOLE_PORT +#define CONFIG_SERIAL_CONSOLE_PORT 0 +#endif + +#define BOTH_EMPTY (UART_LSR_TEMT | UART_LSR_THRE) + +/* Wait for transmitter & holding register to empty */ +static inline void wait_for_xmitr(struct serial_state *ser) +{ + int lsr; + do { + lsr = inb(ser->port + UART_LSR); + } while ((lsr & BOTH_EMPTY) != BOTH_EMPTY); +} + +/* + * Print a string to the serial port trying not to disturb any possible + * real use of the port... + */ +static int serial_console_write(const char *s, unsigned count) +{ + struct serial_state *ser; + int ier; + unsigned i; + + ser = rs_table + CONFIG_SERIAL_CONSOLE_PORT; + /* + * First save the IER then disable the interrupts + */ + ier = inb(ser->port + UART_IER); + outb(0x00, ser->port + UART_IER); + + /* + * Now, do each character + */ + for (i = 0; i < count; i++, s++) { + wait_for_xmitr(ser); + + /* Send the character out. */ + outb(*s, ser->port + UART_TX); + + /* if a LF, also do CR... */ + if (*s == 10) { + wait_for_xmitr(ser); + outb(13, ser->port + UART_TX); + } + } + + /* + * Finally, Wait for transmitter & holding register to empty + * and restore the IER + */ + wait_for_xmitr(ser); + outb(ier, ser->port + UART_IER); + + return (0); +} + +/* + * Receive character from the serial port + */ +static int serial_console_wait_key(void) +{ + struct serial_state *ser; + int ier; + int lsr; + int c; + + ser = rs_table + CONFIG_SERIAL_CONSOLE_PORT; + + /* + * First save the IER then disable the interrupts so + * that the real driver for the port does not get the + * character. + */ + ier = inb(ser->port + UART_IER); + outb(0x00, ser->port + UART_IER); + + do { + lsr = inb(ser->port + UART_LSR); + } while (!(lsr & UART_LSR_DR)); + c = inb(ser->port + UART_RX); + + /* Restore the interrupts */ + outb(ier, ser->port + UART_IER); + + return c; +} + +static int serial_console_device(void) +{ + return MKDEV(TTYAUX_MAJOR, 64 + CONFIG_SERIAL_CONSOLE_PORT); +} + +long serial_console_init(long kmem_start, long kmem_end) +{ + static struct console console = { + serial_console_write, 0, + serial_console_wait_key, serial_console_device + }; + struct serial_state *ser; + + ser = rs_table + CONFIG_SERIAL_CONSOLE_PORT; + + /* Disable all interrupts, it works in polled mode */ + outb(0x00, ser->port + UART_IER); + + /* + * now do hardwired init + */ + outb(0x03, ser->port + UART_LCR); /* No parity, 8 data bits, 1 stop */ + outb(0x83, ser->port + UART_LCR); /* Access divisor latch */ + outb(0x00, ser->port + UART_DLM); /* 9600 baud */ + outb(0x0c, ser->port + UART_DLL); + outb(0x03, ser->port + UART_LCR); /* Done with divisor */ + + register_console(&console); + return kmem_start; +} + +#endif diff -u --recursive --new-file v2.1.30/linux/drivers/char/softdog.c linux/drivers/char/softdog.c --- v2.1.30/linux/drivers/char/softdog.c Thu Mar 27 14:40:03 1997 +++ linux/drivers/char/softdog.c Wed Apr 2 17:43:21 1997 @@ -83,7 +83,7 @@ return 0; } -static void softdog_release(struct inode *inode, struct file *file) +static int softdog_release(struct inode *inode, struct file *file) { /* * Shut off the timer. @@ -94,6 +94,7 @@ MOD_DEC_USE_COUNT; #endif timer_alive=0; + return 0; } static void softdog_ping(void) diff -u --recursive --new-file v2.1.30/linux/drivers/char/tga.c linux/drivers/char/tga.c --- v2.1.30/linux/drivers/char/tga.c Sun Feb 2 05:51:11 1997 +++ linux/drivers/char/tga.c Thu Mar 27 14:36:39 1997 @@ -37,8 +37,7 @@ #include "selection.h" #include "console_struct.h" -extern void register_console(void (*proc)(const char *)); -extern void console_print(const char *); +extern struct console vt_console_driver; /* TGA hardware description (minimal) */ /* @@ -485,7 +484,9 @@ /* * FINALLY, we can register TGA as console (whew!) */ - register_console(console_print); +#ifdef CONFIG_VT_CONSOLE + register_console(&vt_console_driver); +#endif } unsigned char PLLbits[7] = { 0x80, 0x04, 0x00, 0x24, 0x44, 0x80, 0xb8 }; diff -u --recursive --new-file v2.1.30/linux/drivers/char/tpqic02.c linux/drivers/char/tpqic02.c --- v2.1.30/linux/drivers/char/tpqic02.c Sun Jan 26 02:07:17 1997 +++ linux/drivers/char/tpqic02.c Wed Apr 2 17:43:21 1997 @@ -2387,7 +2387,7 @@ } /* qic02_tape_open */ -static void qic02_tape_release(struct inode * inode, struct file * filp) +static int qic02_tape_release(struct inode * inode, struct file * filp) { kdev_t dev = inode->i_rdev; @@ -2420,7 +2420,7 @@ #ifdef MODULE MOD_DEC_USE_COUNT; #endif - return; + return 0; } /* qic02_tape_release */ diff -u --recursive --new-file v2.1.30/linux/drivers/char/tty_io.c linux/drivers/char/tty_io.c --- v2.1.30/linux/drivers/char/tty_io.c Thu Mar 27 14:40:03 1997 +++ linux/drivers/char/tty_io.c Wed Apr 2 17:43:21 1997 @@ -56,6 +56,7 @@ #include #include #include +#include #include #include #include @@ -87,28 +88,15 @@ #define TTY_PARANOIA_CHECK #define CHECK_TTY_COUNT -extern void do_blank_screen(int nopowersave); -extern void set_vesa_blanking(const unsigned long arg); - struct termios tty_std_termios; /* for the benefit of tty drivers */ struct tty_driver *tty_drivers = NULL; /* linked list of tty drivers */ struct tty_ldisc ldiscs[NR_LDISCS]; /* line disc dispatch table */ /* - * fg_console is the current virtual console, - * last_console is the last used one, - * want_console is the console we want to switch to, - * kmsg_redirect is the console for kernel messages, * redirect is the pseudo-tty that console output * is redirected to if asked by TIOCCONS. */ -int fg_console = 0; -int last_console = 0; -int want_console = -1; -int kmsg_redirect = 0; struct tty_struct * redirect = NULL; -struct wait_queue * keypress_wait = NULL; -char vt_dont_switch = 0; static void initialize_tty_struct(struct tty_struct *tty); @@ -116,14 +104,11 @@ static long tty_write(struct inode *, struct file *, const char *, unsigned long); static unsigned int tty_poll(struct file *, poll_table *); static int tty_open(struct inode *, struct file *); -static void tty_release(struct inode *, struct file *); +static int tty_release(struct inode *, struct file *); static int tty_ioctl(struct inode * inode, struct file * file, unsigned int cmd, unsigned long arg); static int tty_fasync(struct inode * inode, struct file * filp, int on); -extern void reset_palette(int currcons) ; -extern void set_palette(void) ; - #ifndef MIN #define MIN(a,b) ((a) < (b) ? (a) : (b)) #endif @@ -509,221 +494,12 @@ p->tty = NULL; } -/* - * Sometimes we want to wait until a particular VT has been activated. We - * do it in a very simple manner. Everybody waits on a single queue and - * get woken up at once. Those that are satisfied go on with their business, - * while those not ready go back to sleep. Seems overkill to add a wait - * to each vt just for this - usually this does nothing! - */ -static struct wait_queue *vt_activate_queue = NULL; - -/* - * Sleeps until a vt is activated, or the task is interrupted. Returns - * 0 if activation, -EINTR if interrupted. - */ -int vt_waitactive(int vt) -{ - int retval; - struct wait_queue wait = { current, NULL }; - - add_wait_queue(&vt_activate_queue, &wait); - for (;;) { - current->state = TASK_INTERRUPTIBLE; - retval = 0; - if (vt == fg_console) - break; - retval = -EINTR; - if (current->signal & ~current->blocked) - break; - schedule(); - } - remove_wait_queue(&vt_activate_queue, &wait); - current->state = TASK_RUNNING; - return retval; -} - -#define vt_wake_waitactive() wake_up(&vt_activate_queue) - -void reset_vc(unsigned int new_console) -{ - vt_cons[new_console]->vc_mode = KD_TEXT; - kbd_table[new_console].kbdmode = VC_XLATE; - vt_cons[new_console]->vt_mode.mode = VT_AUTO; - vt_cons[new_console]->vt_mode.waitv = 0; - vt_cons[new_console]->vt_mode.relsig = 0; - vt_cons[new_console]->vt_mode.acqsig = 0; - vt_cons[new_console]->vt_mode.frsig = 0; - vt_cons[new_console]->vt_pid = -1; - vt_cons[new_console]->vt_newvt = -1; - reset_palette (new_console) ; -} - -/* - * Performs the back end of a vt switch - */ -void complete_change_console(unsigned int new_console) -{ - unsigned char old_vc_mode; - - if ((new_console == fg_console) || (vt_dont_switch)) - return; - if (!vc_cons_allocated(new_console)) - return; - last_console = fg_console; - - /* - * If we're switching, we could be going from KD_GRAPHICS to - * KD_TEXT mode or vice versa, which means we need to blank or - * unblank the screen later. - */ - old_vc_mode = vt_cons[fg_console]->vc_mode; - update_screen(new_console); - - /* - * If this new console is under process control, send it a signal - * telling it that it has acquired. Also check if it has died and - * clean up (similar to logic employed in change_console()) - */ - if (vt_cons[new_console]->vt_mode.mode == VT_PROCESS) - { - /* - * Send the signal as privileged - kill_proc() will - * tell us if the process has gone or something else - * is awry - */ - if (kill_proc(vt_cons[new_console]->vt_pid, - vt_cons[new_console]->vt_mode.acqsig, - 1) != 0) - { - /* - * The controlling process has died, so we revert back to - * normal operation. In this case, we'll also change back - * to KD_TEXT mode. I'm not sure if this is strictly correct - * but it saves the agony when the X server dies and the screen - * remains blanked due to KD_GRAPHICS! It would be nice to do - * this outside of VT_PROCESS but there is no single process - * to account for and tracking tty count may be undesirable. - */ - reset_vc(new_console); - } - } - - /* - * We do this here because the controlling process above may have - * gone, and so there is now a new vc_mode - */ - if (old_vc_mode != vt_cons[new_console]->vc_mode) - { - if (vt_cons[new_console]->vc_mode == KD_TEXT) - do_unblank_screen(); - else - do_blank_screen(1); - } - - /* Set the colour palette for this VT */ - if (vt_cons[new_console]->vc_mode == KD_TEXT) - set_palette() ; - -#ifdef CONFIG_SUN_CONSOLE - if (old_vc_mode != vt_cons[new_console]->vc_mode) - { - extern void set_cursor(int currcons); - extern void hide_cursor(void); - - if (old_vc_mode == KD_GRAPHICS) - { - extern void sun_clear_margin(void); - extern void render_screen(void); - - sun_clear_margin(); - render_screen(); - set_cursor(fg_console); - } - else - hide_cursor(); - } -#endif - /* - * Wake anyone waiting for their VT to activate - */ - vt_wake_waitactive(); - return; -} - -/* - * Performs the front-end of a vt switch - */ -void change_console(unsigned int new_console) -{ - if ((new_console == fg_console) || (vt_dont_switch)) - return; - if (!vc_cons_allocated(new_console)) - return; - - /* - * If this vt is in process mode, then we need to handshake with - * that process before switching. Essentially, we store where that - * vt wants to switch to and wait for it to tell us when it's done - * (via VT_RELDISP ioctl). - * - * We also check to see if the controlling process still exists. - * If it doesn't, we reset this vt to auto mode and continue. - * This is a cheap way to track process control. The worst thing - * that can happen is: we send a signal to a process, it dies, and - * the switch gets "lost" waiting for a response; hopefully, the - * user will try again, we'll detect the process is gone (unless - * the user waits just the right amount of time :-) and revert the - * vt to auto control. - */ - if (vt_cons[fg_console]->vt_mode.mode == VT_PROCESS) - { - /* - * Send the signal as privileged - kill_proc() will - * tell us if the process has gone or something else - * is awry - */ - if (kill_proc(vt_cons[fg_console]->vt_pid, - vt_cons[fg_console]->vt_mode.relsig, - 1) == 0) - { - /* - * It worked. Mark the vt to switch to and - * return. The process needs to send us a - * VT_RELDISP ioctl to complete the switch. - */ - vt_cons[fg_console]->vt_newvt = new_console; - return; - } - - /* - * The controlling process has died, so we revert back to - * normal operation. In this case, we'll also change back - * to KD_TEXT mode. I'm not sure if this is strictly correct - * but it saves the agony when the X server dies and the screen - * remains blanked due to KD_GRAPHICS! It would be nice to do - * this outside of VT_PROCESS but there is no single process - * to account for and tracking tty count may be undesirable. - */ - reset_vc(fg_console); - - /* - * Fall through to normal (VT_AUTO) handling of the switch... - */ - } - - /* - * Ignore all switches in KD_GRAPHICS+VT_AUTO mode - */ - if (vt_cons[fg_console]->vc_mode == KD_GRAPHICS) - return; - - complete_change_console(new_console); -} - void wait_for_keypress(void) { - sleep_on(&keypress_wait); + struct console *c = console_drivers; + while(c && !c->wait_key) + c = c->next; + if (c) c->wait_key(); } void stop_tty(struct tty_struct *tty) @@ -1283,11 +1059,16 @@ /* noctty = 1; */ } if (device == CONSOLE_DEV) { - device = MKDEV(TTY_MAJOR, fg_console+1); + struct console *c = console_drivers; + while(c && !c->device) + c = c->next; + if (!c) + return -ENODEV; + device = c->device(); noctty = 1; } minor = MINOR(device); - + retval = init_dev(device, &tty); if (retval) return retval; @@ -1342,9 +1123,10 @@ * we have to make the redirection checks after that and on both * sides of a pty. */ -static void tty_release(struct inode * inode, struct file * filp) +static int tty_release(struct inode * inode, struct file * filp) { release_dev(filp); + return 0; } static unsigned int tty_poll(struct file * filp, poll_table * wait) @@ -1597,56 +1379,6 @@ return 0; } -static int tioclinux(struct tty_struct *tty, unsigned long arg) -{ - char type, data; - - if (tty->driver.type != TTY_DRIVER_TYPE_CONSOLE) - return -EINVAL; - if (current->tty != tty && !suser()) - return -EPERM; - if (get_user(type, (char *)arg)) - return -EFAULT; - switch (type) - { - case 2: - return set_selection(arg, tty, 1); - case 3: - return paste_selection(tty); - case 4: - do_unblank_screen(); - return 0; - case 5: - return sel_loadlut(arg); - case 6: - - /* - * Make it possible to react to Shift+Mousebutton. - * Note that 'shift_state' is an undocumented - * kernel-internal variable; programs not closely - * related to the kernel should not use this. - */ - data = shift_state; - return put_user(data, (char *) arg); - case 7: - data = mouse_reporting(); - return put_user(data, (char *) arg); - case 10: - set_vesa_blanking(arg); - return 0; - case 11: /* set kmsg redirect */ - if (!suser()) - return -EPERM; - if (get_user(data, (char *)arg+1)) - return -EFAULT; - kmsg_redirect = data; - return 0; - case 12: /* get fg_console */ - return fg_console; - } - return -EINVAL; -} - static int tiocttygstruct(struct tty_struct *tty, struct tty_struct *arg) { if (copy_to_user(arg, tty, sizeof(*arg))) @@ -1718,8 +1450,10 @@ return put_user(tty->ldisc.num, (int *) arg); case TIOCSETD: return tiocsetd(tty, (int *) arg); +#ifdef CONFIG_VT case TIOCLINUX: return tioclinux(tty, arg); +#endif case TIOCTTYGSTRUCT: return tiocttygstruct(tty, (struct tty_struct *) arg); } @@ -1951,7 +1685,13 @@ * set up the console device so that later boot sequences can * inform about problems etc.. */ - return con_init(kmem_start); +#ifdef CONFIG_SERIAL_CONSOLE + kmem_start = serial_console_init(kmem_start, kmem_end); +#endif +#ifdef CONFIG_VT + kmem_start = con_init(kmem_start); +#endif + return kmem_start; } static struct tty_driver dev_tty_driver, dev_console_driver; @@ -1976,7 +1716,7 @@ dev_tty_driver.driver_name = "/dev/tty"; dev_tty_driver.name = dev_tty_driver.driver_name + 5; dev_tty_driver.name_base = 0; - dev_tty_driver.major = TTY_MAJOR; + dev_tty_driver.major = TTYAUX_MAJOR; dev_tty_driver.minor_start = 0; dev_tty_driver.num = 1; dev_tty_driver.type = TTY_DRIVER_TYPE_SYSTEM; @@ -1988,14 +1728,14 @@ dev_console_driver = dev_tty_driver; dev_console_driver.driver_name = "/dev/console"; dev_console_driver.name = dev_console_driver.driver_name + 5; - dev_console_driver.major = TTYAUX_MAJOR; + dev_console_driver.major = TTY_MAJOR; dev_console_driver.type = TTY_DRIVER_TYPE_SYSTEM; dev_console_driver.subtype = SYSTEM_TYPE_CONSOLE; if (tty_register_driver(&dev_console_driver)) panic("Couldn't register /dev/console driver\n"); - -#if !CONFIG_NO_KEYBOARD + +#ifdef CONFIG_VT kbd_init(); #endif #ifdef CONFIG_ESPSERIAL /* init ESP before rs, so rs doesn't see the port */ @@ -2020,7 +1760,9 @@ riscom8_init(); #endif pty_init(); +#ifdef CONFIG_VT vcs_init(); +#endif return 0; } diff -u --recursive --new-file v2.1.30/linux/drivers/char/vt.c linux/drivers/char/vt.c --- v2.1.30/linux/drivers/char/vt.c Thu Mar 27 14:40:03 1997 +++ linux/drivers/char/vt.c Thu Mar 27 14:36:39 1997 @@ -29,7 +29,7 @@ #include "diacr.h" #include "selection.h" -extern char vt_dont_switch; +char vt_dont_switch = 0; extern struct tty_driver console_driver; #define VT_IS_IN_USE(i) (console_driver.table[i] && console_driver.table[i]->count) @@ -80,6 +80,7 @@ extern int con_set_cmap(unsigned char *cmap); extern int con_get_cmap(unsigned char *cmap); extern void reset_palette(int currcons); +extern void set_palette(void) ; extern int con_adjust_height(unsigned long fontheight); extern int video_mode_512ch; @@ -1143,3 +1144,216 @@ return -ENOIOCTLCMD; } } + +/* + * Sometimes we want to wait until a particular VT has been activated. We + * do it in a very simple manner. Everybody waits on a single queue and + * get woken up at once. Those that are satisfied go on with their business, + * while those not ready go back to sleep. Seems overkill to add a wait + * to each vt just for this - usually this does nothing! + */ +static struct wait_queue *vt_activate_queue = NULL; + +/* + * Sleeps until a vt is activated, or the task is interrupted. Returns + * 0 if activation, -EINTR if interrupted. + */ +int vt_waitactive(int vt) +{ + int retval; + struct wait_queue wait = { current, NULL }; + + add_wait_queue(&vt_activate_queue, &wait); + for (;;) { + current->state = TASK_INTERRUPTIBLE; + retval = 0; + if (vt == fg_console) + break; + retval = -EINTR; + if (current->signal & ~current->blocked) + break; + schedule(); + } + remove_wait_queue(&vt_activate_queue, &wait); + current->state = TASK_RUNNING; + return retval; +} + +#define vt_wake_waitactive() wake_up(&vt_activate_queue) + +void reset_vc(unsigned int new_console) +{ + vt_cons[new_console]->vc_mode = KD_TEXT; + kbd_table[new_console].kbdmode = VC_XLATE; + vt_cons[new_console]->vt_mode.mode = VT_AUTO; + vt_cons[new_console]->vt_mode.waitv = 0; + vt_cons[new_console]->vt_mode.relsig = 0; + vt_cons[new_console]->vt_mode.acqsig = 0; + vt_cons[new_console]->vt_mode.frsig = 0; + vt_cons[new_console]->vt_pid = -1; + vt_cons[new_console]->vt_newvt = -1; + reset_palette (new_console) ; +} + +/* + * Performs the back end of a vt switch + */ +void complete_change_console(unsigned int new_console) +{ + unsigned char old_vc_mode; + + if ((new_console == fg_console) || (vt_dont_switch)) + return; + if (!vc_cons_allocated(new_console)) + return; + last_console = fg_console; + + /* + * If we're switching, we could be going from KD_GRAPHICS to + * KD_TEXT mode or vice versa, which means we need to blank or + * unblank the screen later. + */ + old_vc_mode = vt_cons[fg_console]->vc_mode; + update_screen(new_console); + + /* + * If this new console is under process control, send it a signal + * telling it that it has acquired. Also check if it has died and + * clean up (similar to logic employed in change_console()) + */ + if (vt_cons[new_console]->vt_mode.mode == VT_PROCESS) + { + /* + * Send the signal as privileged - kill_proc() will + * tell us if the process has gone or something else + * is awry + */ + if (kill_proc(vt_cons[new_console]->vt_pid, + vt_cons[new_console]->vt_mode.acqsig, + 1) != 0) + { + /* + * The controlling process has died, so we revert back to + * normal operation. In this case, we'll also change back + * to KD_TEXT mode. I'm not sure if this is strictly correct + * but it saves the agony when the X server dies and the screen + * remains blanked due to KD_GRAPHICS! It would be nice to do + * this outside of VT_PROCESS but there is no single process + * to account for and tracking tty count may be undesirable. + */ + reset_vc(new_console); + } + } + + /* + * We do this here because the controlling process above may have + * gone, and so there is now a new vc_mode + */ + if (old_vc_mode != vt_cons[new_console]->vc_mode) + { + if (vt_cons[new_console]->vc_mode == KD_TEXT) + do_unblank_screen(); + else + do_blank_screen(1); + } + + /* Set the colour palette for this VT */ + if (vt_cons[new_console]->vc_mode == KD_TEXT) + set_palette() ; + +#ifdef CONFIG_SUN_CONSOLE + if (old_vc_mode != vt_cons[new_console]->vc_mode) + { + extern void set_cursor(int currcons); + extern void hide_cursor(void); + + if (old_vc_mode == KD_GRAPHICS) + { + extern void sun_clear_margin(void); + extern void render_screen(void); + + sun_clear_margin(); + render_screen(); + set_cursor(fg_console); + } + else + hide_cursor(); + } +#endif + /* + * Wake anyone waiting for their VT to activate + */ + vt_wake_waitactive(); + return; +} + +/* + * Performs the front-end of a vt switch + */ +void change_console(unsigned int new_console) +{ + if ((new_console == fg_console) || (vt_dont_switch)) + return; + if (!vc_cons_allocated(new_console)) + return; + + /* + * If this vt is in process mode, then we need to handshake with + * that process before switching. Essentially, we store where that + * vt wants to switch to and wait for it to tell us when it's done + * (via VT_RELDISP ioctl). + * + * We also check to see if the controlling process still exists. + * If it doesn't, we reset this vt to auto mode and continue. + * This is a cheap way to track process control. The worst thing + * that can happen is: we send a signal to a process, it dies, and + * the switch gets "lost" waiting for a response; hopefully, the + * user will try again, we'll detect the process is gone (unless + * the user waits just the right amount of time :-) and revert the + * vt to auto control. + */ + if (vt_cons[fg_console]->vt_mode.mode == VT_PROCESS) + { + /* + * Send the signal as privileged - kill_proc() will + * tell us if the process has gone or something else + * is awry + */ + if (kill_proc(vt_cons[fg_console]->vt_pid, + vt_cons[fg_console]->vt_mode.relsig, + 1) == 0) + { + /* + * It worked. Mark the vt to switch to and + * return. The process needs to send us a + * VT_RELDISP ioctl to complete the switch. + */ + vt_cons[fg_console]->vt_newvt = new_console; + return; + } + + /* + * The controlling process has died, so we revert back to + * normal operation. In this case, we'll also change back + * to KD_TEXT mode. I'm not sure if this is strictly correct + * but it saves the agony when the X server dies and the screen + * remains blanked due to KD_GRAPHICS! It would be nice to do + * this outside of VT_PROCESS but there is no single process + * to account for and tracking tty count may be undesirable. + */ + reset_vc(fg_console); + + /* + * Fall through to normal (VT_AUTO) handling of the switch... + */ + } + + /* + * Ignore all switches in KD_GRAPHICS+VT_AUTO mode + */ + if (vt_cons[fg_console]->vc_mode == KD_GRAPHICS) + return; + + complete_change_console(new_console); +} + diff -u --recursive --new-file v2.1.30/linux/drivers/char/wdt.c linux/drivers/char/wdt.c --- v2.1.30/linux/drivers/char/wdt.c Thu Mar 27 14:40:03 1997 +++ linux/drivers/char/wdt.c Wed Apr 2 17:43:21 1997 @@ -275,7 +275,7 @@ } } -static void wdt_release(struct inode *inode, struct file *file) +static int wdt_release(struct inode *inode, struct file *file) { if(MINOR(inode->i_rdev)==WATCHDOG_MINOR) { @@ -286,6 +286,7 @@ wdt_is_open=0; } MOD_DEC_USE_COUNT; + return 0; } /* diff -u --recursive --new-file v2.1.30/linux/drivers/isdn/isdn_common.c linux/drivers/isdn/isdn_common.c --- v2.1.30/linux/drivers/isdn/isdn_common.c Thu Feb 27 10:57:29 1997 +++ linux/drivers/isdn/isdn_common.c Wed Apr 2 17:43:21 1997 @@ -1790,7 +1790,7 @@ return -ENODEV; } -static void +static int isdn_close(struct inode *ino, struct file *filep) { uint minor = MINOR(ino->i_rdev); @@ -1807,13 +1807,13 @@ q->next = p->next; else dev->infochain = (infostruct *) (p->next); - return; + return 0; } q = p; p = (infostruct *) (p->next); } printk(KERN_WARNING "isdn: No private data while closing isdnctrl\n"); - return; + return 0; } if (minor < ISDN_MINOR_CTRL) { drvidx = isdn_minor2drv(minor); @@ -1822,23 +1822,24 @@ c.command = ISDN_CMD_UNLOCK; c.driver = drvidx; (void) dev->drv[drvidx]->interface->command(&c); - return; + return 0; } if (minor <= ISDN_MINOR_CTRLMAX) { drvidx = isdn_minor2drv(minor - ISDN_MINOR_CTRL); if (drvidx < 0) - return; + return 0; if (dev->profd == current) dev->profd = NULL; c.command = ISDN_CMD_UNLOCK; c.driver = drvidx; (void) dev->drv[drvidx]->interface->command(&c); - return; + return 0; } #ifdef CONFIG_ISDN_PPP if (minor <= ISDN_MINOR_PPPMAX) isdn_ppp_release(minor - ISDN_MINOR_PPP, filep); #endif + return 0; } static struct file_operations isdn_fops = diff -u --recursive --new-file v2.1.30/linux/drivers/net/3c501.c linux/drivers/net/3c501.c --- v2.1.30/linux/drivers/net/3c501.c Sun Feb 2 05:18:35 1997 +++ linux/drivers/net/3c501.c Mon Mar 31 12:52:29 1997 @@ -714,6 +714,7 @@ skb->protocol=eth_type_trans(skb,dev); netif_rx(skb); lp->stats.rx_packets++; + lp->stats.rx_bytes+=pkt_len; } return; } diff -u --recursive --new-file v2.1.30/linux/drivers/net/3c507.c linux/drivers/net/3c507.c --- v2.1.30/linux/drivers/net/3c507.c Sun Feb 2 05:18:35 1997 +++ linux/drivers/net/3c507.c Mon Mar 31 10:26:12 1997 @@ -229,7 +229,7 @@ */ -unsigned short init_words[] = { +static unsigned short init_words[] = { /* System Configuration Pointer (SCP). */ 0x0000, /* Set bus size to 16 bits. */ 0,0, /* pad words. */ @@ -286,7 +286,7 @@ static struct net_device_stats *el16_get_stats(struct device *dev); static void hardware_send_packet(struct device *dev, void *buf, short length); -void init_82586_mem(struct device *dev); +static void init_82586_mem(struct device *dev); #ifdef HAVE_DEVLIST @@ -687,7 +687,7 @@ } -void init_82586_mem(struct device *dev) +static void init_82586_mem(struct device *dev) { struct net_local *lp = (struct net_local *)dev->priv; short ioaddr = dev->base_addr; diff -u --recursive --new-file v2.1.30/linux/drivers/net/3c509.c linux/drivers/net/3c509.c --- v2.1.30/linux/drivers/net/3c509.c Thu Mar 27 14:40:03 1997 +++ linux/drivers/net/3c509.c Mon Mar 31 12:52:29 1997 @@ -667,7 +667,9 @@ skb->protocol=eth_type_trans(skb,dev); netif_rx(skb); outw(RxDiscard, ioaddr + EL3_CMD); /* Pop top Rx packet. */ + lp->stats.rx_bytes+=skb->len; lp->stats.rx_packets++; + lp->stats.rx_bytes+=pkt_len; continue; } else if (el3_debug) printk("%s: Couldn't allocate a sk_buff of size %d.\n", diff -u --recursive --new-file v2.1.30/linux/drivers/net/3c523.c linux/drivers/net/3c523.c --- v2.1.30/linux/drivers/net/3c523.c Sun Feb 2 05:18:35 1997 +++ linux/drivers/net/3c523.c Mon Mar 31 12:52:29 1997 @@ -982,6 +982,7 @@ skb->protocol=eth_type_trans(skb,dev); netif_rx(skb); p->stats.rx_packets++; + p->stats.rx_bytes+=totlen; } else { p->stats.rx_dropped++; } diff -u --recursive --new-file v2.1.30/linux/drivers/net/8390.c linux/drivers/net/8390.c --- v2.1.30/linux/drivers/net/8390.c Sun Feb 2 05:18:35 1997 +++ linux/drivers/net/8390.c Mon Mar 31 12:52:30 1997 @@ -32,6 +32,7 @@ Paul Gortmaker : rewrite Rx overrun handling as per NS specs. Alexey Kuznetsov : use the 8390's six bit hash multicast filter. Paul Gortmaker : tweak ANK's above multicast changes a bit. + Paul Gortmaker : update packet statistics for v2.1.x Sources: @@ -152,6 +153,7 @@ if (tickssofar < TX_TIMEOUT || (tickssofar < (TX_TIMEOUT+5) && ! (txsr & ENTSR_PTX))) { return 1; } + ei_local->stat.tx_errors++; isr = inb(e8390_base+EN0_ISR); if (dev->start == 0) { printk("%s: xmit on stopped card\n", dev->name); @@ -160,8 +162,8 @@ /* * Note that if the Tx posted a TX_ERR interrupt, then the - * error will have been handled from the interrupt handler. - * and not here. + * error will have been handled from the interrupt handler + * and not here. Error statistics are handled there as well. */ printk(KERN_DEBUG "%s: Tx timed out, %s TSR=%#2x, ISR=%#2x, t=%d.\n", @@ -186,13 +188,12 @@ if (dev->interrupt) { printk("%s: Tx request while isr active.\n",dev->name); outb_p(ENISR_ALL, e8390_base + EN0_IMR); + ei_local->stat.tx_errors++; return 1; } ei_local->irqlock = 1; send_length = ETH_ZLEN < length ? length : ETH_ZLEN; - - ei_local->stat.tx_bytes+=send_length; #ifdef EI_PINGPONG @@ -223,6 +224,7 @@ ei_local->irqlock = 0; dev->tbusy = 1; outb_p(ENISR_ALL, e8390_base + EN0_IMR); + ei_local->stat.tx_errors++; return 1; } @@ -270,6 +272,7 @@ outb_p(ENISR_ALL, e8390_base + EN0_IMR); dev_kfree_skb (skb, FREE_WRITE); + ei_local->stat.tx_bytes += send_length; return 0; } @@ -393,14 +396,12 @@ if (tx_was_aborted) ei_tx_intr(dev); - - /* - * Note: NCR reads zero on 16 collisions so we add them - * in by hand. Somebody might care... - */ - if (txsr & ENTSR_ABT) - ei_local->stat.collisions += 16; - + else { + ei_local->stat.tx_errors++; + if (txsr & ENTSR_CRS) ei_local->stat.tx_carrier_errors++; + if (txsr & ENTSR_CDH) ei_local->stat.tx_heartbeat_errors++; + if (txsr & ENTSR_OWC) ei_local->stat.tx_window_errors++; + } } /* We have finished a transmit: check for errors and then trigger the next @@ -467,7 +468,10 @@ ei_local->stat.tx_packets++; else { ei_local->stat.tx_errors++; - if (status & ENTSR_ABT) ei_local->stat.tx_aborted_errors++; + if (status & ENTSR_ABT) { + ei_local->stat.tx_aborted_errors++; + ei_local->stat.collisions += 16; + } if (status & ENTSR_CRS) ei_local->stat.tx_carrier_errors++; if (status & ENTSR_FU) ei_local->stat.tx_fifo_errors++; if (status & ENTSR_CDH) ei_local->stat.tx_heartbeat_errors++; @@ -490,7 +494,7 @@ int num_rx_pages = ei_local->stop_page-ei_local->rx_start_page; while (++rx_pkt_count < 10) { - int pkt_len; + int pkt_len, pkt_stat; /* Get the rx page (incoming packet pointer). */ outb_p(E8390_NODMA+E8390_PAGE1, e8390_base + E8390_CMD); @@ -515,6 +519,7 @@ ei_get_8390_hdr(dev, &rx_frame, this_frame); pkt_len = rx_frame.count - sizeof(struct e8390_pkt_hdr); + pkt_stat = rx_frame.status; next_frame = this_frame + 1 + ((pkt_len+4)>>8); @@ -537,7 +542,8 @@ dev->name, rx_frame.count, rx_frame.status, rx_frame.next); ei_local->stat.rx_errors++; - } else if ((rx_frame.status & 0x0F) == ENRSR_RXOK) { + ei_local->stat.rx_length_errors++; + } else if ((pkt_stat & 0x0F) == ENRSR_RXOK) { struct sk_buff *skb; skb = dev_alloc_skb(pkt_len+2); @@ -552,18 +558,21 @@ skb->dev = dev; skb_put(skb, pkt_len); /* Make room */ ei_block_input(dev, pkt_len, skb, current_offset + sizeof(rx_frame)); - ei_local->stat.rx_bytes+=skb->len; skb->protocol=eth_type_trans(skb,dev); netif_rx(skb); ei_local->stat.rx_packets++; + ei_local->stat.rx_bytes += pkt_len; + if (pkt_stat & ENRSR_PHY) + ei_local->stat.multicast++; } } else { - int errs = rx_frame.status; if (ei_debug) printk("%s: bogus packet: status=%#2x nxpg=%#2x size=%d\n", dev->name, rx_frame.status, rx_frame.next, rx_frame.count); - if (errs & ENRSR_FO) + ei_local->stat.rx_errors++; + /* NB: The NIC counts CRC, frame and missed errors. */ + if (pkt_stat & ENRSR_FO) ei_local->stat.rx_fifo_errors++; } next_frame = rx_frame.next; diff -u --recursive --new-file v2.1.30/linux/drivers/net/Config.in linux/drivers/net/Config.in --- v2.1.30/linux/drivers/net/Config.in Thu Mar 27 14:40:03 1997 +++ linux/drivers/net/Config.in Mon Mar 31 12:52:30 1997 @@ -180,5 +180,6 @@ if [ "$CONFIG_X25" != "n" ]; then tristate 'LAPB over Ethernet driver' CONFIG_LAPBETHER + tristate 'X.25 async driver' CONFIG_X25_ASY fi diff -u --recursive --new-file v2.1.30/linux/drivers/net/Makefile linux/drivers/net/Makefile --- v2.1.30/linux/drivers/net/Makefile Thu Mar 27 14:40:03 1997 +++ linux/drivers/net/Makefile Mon Mar 31 12:52:30 1997 @@ -690,6 +690,14 @@ endif endif +ifeq ($(CONFIG_X25_ASY),y) +L_OBJS += x25_asy.o +else + ifeq ($(CONFIG_X25_ASY),m) + M_OBJS += x25_asy.o + endif +endif + include $(TOPDIR)/Rules.make clean: diff -u --recursive --new-file v2.1.30/linux/drivers/net/Space.c linux/drivers/net/Space.c --- v2.1.30/linux/drivers/net/Space.c Thu Mar 27 14:40:03 1997 +++ linux/drivers/net/Space.c Mon Mar 31 12:52:30 1997 @@ -348,6 +348,16 @@ #undef NEXT_DEV #define NEXT_DEV (&slip_bootstrap) #endif /* SLIP */ + +#if defined(X25_ASY) || defined(CONFIG_X25_ASY) + /* To be exact, this node just hooks the initialization + routines to the device structures. */ +extern int x25_asy_init_ctrl_dev(struct device *); +static struct device x25_asy_bootstrap = { + "x25_proto", 0x0, 0x0, 0x0, 0x0, 0, 0, 0, 0, 0, NEXT_DEV, x25_asy_init_ctrl_dev, }; +#undef NEXT_DEV +#define NEXT_DEV (&x25_asy_bootstrap) +#endif /* X25_ASY */ #if defined(CONFIG_MKISS) /* To be exact, this node just hooks the initialization diff -u --recursive --new-file v2.1.30/linux/drivers/net/a2065.c linux/drivers/net/a2065.c --- v2.1.30/linux/drivers/net/a2065.c Sun Feb 2 05:18:36 1997 +++ linux/drivers/net/a2065.c Mon Mar 31 12:52:30 1997 @@ -582,16 +582,6 @@ return status; } - if (skb == NULL) { - dev_tint (dev); - printk ("skb is NULL\n"); - return 0; - } - - if (skb->len <= 0) { - printk ("skb len is %id\n", skb->len); - return 0; - } /* Block a timer-based transmit from overlapping. */ #ifdef OLD_METHOD dev->tbusy = 1; diff -u --recursive --new-file v2.1.30/linux/drivers/net/apricot.c linux/drivers/net/apricot.c --- v2.1.30/linux/drivers/net/apricot.c Sun Feb 2 05:18:36 1997 +++ linux/drivers/net/apricot.c Mon Mar 31 12:52:30 1997 @@ -240,7 +240,7 @@ do { lp->scb.rfd = rfd->next; - kfree_s(rfd, sizeof(struct i596_rfd)); + kfree(rfd); rfd = lp->scb.rfd; } while (rfd != lp->rx_tail); @@ -354,6 +354,7 @@ skb->protocol=eth_type_trans(skb,dev); netif_rx(skb); lp->stats.rx_packets++; + lp->stats.rx_bytes+=pkt_len; if (i596_debug > 4) print_eth(skb->data); } @@ -411,15 +412,13 @@ lp->stats.tx_aborted_errors++; ptr->next = (struct i596_cmd * ) I596_NULL; - kfree_s((unsigned char *)tx_cmd, (sizeof (struct tx_cmd) + sizeof (struct i596_tbd))); + kfree(tx_cmd); break; } case CmdMulticastList: { - unsigned short count = *((unsigned short *) (ptr + 1)); - ptr->next = (struct i596_cmd * ) I596_NULL; - kfree_s((unsigned char *)ptr, (sizeof (struct i596_cmd) + count + 2)); + kfree(ptr); break; } default: @@ -650,6 +649,7 @@ i596_add_cmd(dev, (struct i596_cmd *)tx_cmd); lp->stats.tx_packets++; + lp->stats.tx_bytes+=length; } } @@ -821,7 +821,7 @@ ptr->next = (struct i596_cmd * ) I596_NULL; - kfree_s((unsigned char *)tx_cmd, (sizeof (struct tx_cmd) + sizeof (struct i596_tbd))); + kfree(tx_cmd); break; } case CmdMulticastList: @@ -829,7 +829,7 @@ unsigned short count = *((unsigned short *) (ptr + 1)); ptr->next = (struct i596_cmd * ) I596_NULL; - kfree_s((unsigned char *)ptr, (sizeof (struct i596_cmd) + count + 2)); + kfree(ptr); break; } case CmdTDR: @@ -1032,7 +1032,7 @@ cleanup_module(void) { unregister_netdev(&dev_apricot); - kfree_s((void *)dev_apricot.mem_start, sizeof(struct i596_private) + 0xf); + kfree(dev_apricot.mem_start); dev_apricot.priv = NULL; /* If we don't do this, we can't re-insmod it later. */ diff -u --recursive --new-file v2.1.30/linux/drivers/net/arcnet.c linux/drivers/net/arcnet.c --- v2.1.30/linux/drivers/net/arcnet.c Sun Feb 2 05:18:36 1997 +++ linux/drivers/net/arcnet.c Mon Mar 31 12:52:30 1997 @@ -1568,17 +1568,6 @@ return 1; } - /* If some higher layer thinks we've missed a tx-done interrupt - we are passed NULL. Caution: dev_tint() handles the cli()/sti() - itself. */ - if (skb == NULL) { - BUGMSG(D_NORMAL,"tx passed null skb (status=%Xh, inTX=%d, tickssofar=%ld)\n", - ARCSTATUS,lp->intx,jiffies-dev->trans_start); - lp->stats.tx_errors++; - dev_tint(dev); - return 0; - } - if (lp->txready) /* transmit already in progress! */ { BUGMSG(D_NORMAL,"trying to start new packet while busy! (status=%Xh)\n", diff -u --recursive --new-file v2.1.30/linux/drivers/net/ariadne.c linux/drivers/net/ariadne.c --- v2.1.30/linux/drivers/net/ariadne.c Sun Feb 2 05:18:36 1997 +++ linux/drivers/net/ariadne.c Mon Mar 31 12:52:30 1997 @@ -581,14 +581,6 @@ return(0); } - if (skb == NULL) { - dev_tint(dev); - return(0); - } - - if (skb->len <= 0) - return(0); - #if 0 if (ariadne_debug > 3) { board->Lance.RAP = CSR0; /* PCnet-ISA Controller Status */ diff -u --recursive --new-file v2.1.30/linux/drivers/net/at1700.c linux/drivers/net/at1700.c --- v2.1.30/linux/drivers/net/at1700.c Sun Feb 2 05:18:36 1997 +++ linux/drivers/net/at1700.c Mon Mar 31 12:52:30 1997 @@ -265,8 +265,8 @@ dev->open = net_open; dev->stop = net_close; - dev->hard_start_xmit = net_send_packet; - dev->get_stats = net_get_stats; + dev->hard_start_xmit = net_send_packet; + dev->get_stats = net_get_stats; dev->set_multicast_list = &set_multicast_list; /* Fill in the fields of 'dev' with ethernet-generic values. */ @@ -390,14 +390,6 @@ lp->tx_started = 0; lp->tx_queue = 0; lp->tx_queue_len = 0; - } - - /* 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; } /* Block a timer-based transmit from overlapping. This could better be diff -u --recursive --new-file v2.1.30/linux/drivers/net/atari_bionet.c linux/drivers/net/atari_bionet.c --- v2.1.30/linux/drivers/net/atari_bionet.c Sun Feb 2 05:18:36 1997 +++ linux/drivers/net/atari_bionet.c Mon Mar 31 12:52:30 1997 @@ -436,13 +436,6 @@ struct net_local *lp = (struct net_local *)dev->priv; unsigned long flags; - /* 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; - } /* Block a timer-based transmit from overlapping. This could better be * done with atomic_swap(1, dev->tbusy), but set_bit() works as well. */ @@ -473,12 +466,11 @@ dev->trans_start = jiffies; dev->tbusy = 0; + lp->stats.tx_packets++; + lp->stats.tx_bytes+=length; } dev_kfree_skb(skb, FREE_WRITE); - /* You might need to clean up and record Tx statistics here. - */ - lp->stats.tx_packets++; return 0; } @@ -539,6 +531,7 @@ memcpy(skb->data, nic_packet->buffer, pkt_len); netif_rx(skb); lp->stats.rx_packets++; + lp->stats.rx_bytes+=pkt_len; } } @@ -612,9 +605,10 @@ #undef NEXT_DEV #define NEXT_DEV (&bio_dev) +static char bio_name[16]; static struct device bio_dev = { - " ", /* filled in by register_netdev() */ + bio_name, /* filled in by register_netdev() */ 0, 0, 0, 0, /* memory */ 0, 0, /* base, irq */ 0, 0, 0, NEXT_DEV, bionet_probe, diff -u --recursive --new-file v2.1.30/linux/drivers/net/atari_pamsnet.c linux/drivers/net/atari_pamsnet.c --- v2.1.30/linux/drivers/net/atari_pamsnet.c Sun Feb 2 05:18:36 1997 +++ linux/drivers/net/atari_pamsnet.c Mon Mar 31 12:52:30 1997 @@ -699,13 +699,6 @@ struct net_local *lp = (struct net_local *)dev->priv; unsigned long flags; - /* 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; - } /* Block a timer-based transmit from overlapping. This could better be * done with atomic_swap(1, dev->tbusy), but set_bit() works as well. */ @@ -738,12 +731,11 @@ dev->trans_start = jiffies; dev->tbusy = 0; + lp->stats.tx_packets++; + lp->stats.tx_bytes+=length; } dev_kfree_skb(skb, FREE_WRITE); - /* You might need to clean up and record Tx statistics here. - */ - lp->stats.tx_packets++; return 0; } @@ -806,6 +798,7 @@ memcpy(skb->data, nic_packet->buffer, pkt_len); netif_rx(skb); lp->stats.rx_packets++; + lp->stats.rx_bytes+=pkt_len; } } diff -u --recursive --new-file v2.1.30/linux/drivers/net/atp.c linux/drivers/net/atp.c --- v2.1.30/linux/drivers/net/atp.c Sun Feb 2 05:18:36 1997 +++ linux/drivers/net/atp.c Mon Mar 31 12:52:30 1997 @@ -434,14 +434,6 @@ dev->trans_start = jiffies; } - /* 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; - } - /* Block a timer-based transmit from overlapping. This could better be done with atomic_swap(1, dev->tbusy), but set_bit() works as well. */ if (set_bit(0, (void*)&dev->tbusy) != 0) diff -u --recursive --new-file v2.1.30/linux/drivers/net/bpqether.c linux/drivers/net/bpqether.c --- v2.1.30/linux/drivers/net/bpqether.c Thu Mar 27 14:40:03 1997 +++ linux/drivers/net/bpqether.c Mon Mar 31 12:52:30 1997 @@ -241,13 +241,14 @@ return 0; } - ((struct bpqdev *)dev->priv)->stats.rx_packets++; - len = skb->data[0] + skb->data[1] * 256 - 5; skb_pull(skb, 2); /* Remove the length bytes */ skb_trim(skb, len); /* Set the length of the data */ + ((struct bpqdev *)dev->priv)->stats.rx_packets++; + ((struct bpqdev *)dev->priv)->stats.rx_bytes+=len; + ptr = skb_push(skb, 1); *ptr = 0; @@ -314,7 +315,6 @@ *ptr++ = (size + 5) / 256; bpq = (struct bpqdev *)dev->priv; - bpq->stats.tx_packets++; if ((dev = bpq_get_ether_dev(dev)) == NULL) { bpq->stats.tx_dropped++; @@ -324,7 +324,9 @@ skb->dev = dev; dev->hard_header(skb, dev, ETH_P_BPQ, bpq->dest_addr, NULL, 0); - + bpq->stats.tx_packets++; + bpq->stats.tx_bytes+=skb->len; + dev_queue_xmit(skb); return 0; diff -u --recursive --new-file v2.1.30/linux/drivers/net/cs89x0.c linux/drivers/net/cs89x0.c --- v2.1.30/linux/drivers/net/cs89x0.c Thu Feb 27 10:57:30 1997 +++ linux/drivers/net/cs89x0.c Mon Mar 31 12:52:30 1997 @@ -25,6 +25,8 @@ : as an example. Disabled autoprobing in init_module(), : not a good thing to do to other devices while Linux : is running from all accounts. + + Alan Cox : Removed 1.2 support, added 2.1 extra counters. */ static char *version = @@ -32,10 +34,6 @@ /* ======================= configure the driver here ======================= */ -/* we also support 1.2.13 */ -#define SUPPORTS_1_2_13 0 - - /* use 0 for production, 1 for verification, >2 for debug */ #ifndef NET_DEBUG #define NET_DEBUG 2 @@ -120,13 +118,8 @@ static int cs89x0_probe1(struct device *dev, int ioaddr); static int net_open(struct device *dev); static int net_send_packet(struct sk_buff *skb, struct device *dev); -#if SUPPORTS_1_2_13 -static void net_interrupt(int irq, struct pt_regs *regs); -static void set_multicast_list(struct device *dev, int num_addrs, void *addrs); -#else static void net_interrupt(int irq, void *dev_id, struct pt_regs *regs); static void set_multicast_list(struct device *dev); -#endif static void net_rx(struct device *dev); static int net_close(struct device *dev); static struct net_device_stats *net_get_stats(struct device *dev); @@ -175,14 +168,14 @@ } #endif -int inline +static int inline readreg(struct device *dev, int portno) { outw(portno, dev->base_addr + ADD_PORT); return inw(dev->base_addr + DATA_PORT); } -void inline +static void inline writereg(struct device *dev, int portno, int value) { outw(portno, dev->base_addr + ADD_PORT); @@ -190,19 +183,19 @@ } -int inline +static int inline readword(struct device *dev, int portno) { return inw(dev->base_addr + portno); } -void inline +static void inline writeword(struct device *dev, int portno, int value) { outw(value, dev->base_addr + portno); } -int +static int wait_eeprom_ready(struct device *dev) { int timeout = jiffies; @@ -430,7 +423,7 @@ } -void +static void control_dc_dc(struct device *dev, int on_not_off) { struct net_local *lp = (struct net_local *)dev->priv; @@ -496,7 +489,7 @@ } /* send a test packet - return true if carrier bits are ok */ -int +static int send_test_pkt(struct device *dev) { int ioaddr = dev->base_addr; @@ -541,7 +534,7 @@ } -int +static int detect_aui(struct device *dev) { struct net_local *lp = (struct net_local *)dev->priv; @@ -557,7 +550,7 @@ return 0; } -int +static int detect_bnc(struct device *dev) { struct net_local *lp = (struct net_local *)dev->priv; @@ -574,7 +567,7 @@ } -void +static void write_irq(struct device *dev, int chip_type, int irq) { int i; @@ -611,29 +604,11 @@ /* Allow interrupts to be generated by the chip */ writereg(dev, PP_BusCTL, ENABLE_IRQ | MEMORY_ON); for (i = 2; i < CS8920_NO_INTS; i++) if ((1 << dev->irq) & lp->irq_map) { -#if SUPPORTS_1_2_13 - if (request_irq (i, NULL, 0, "bogus") != -EBUSY) { -#else - if (request_irq (i, NULL, 0, "bogus", NULL) != -EBUSY) { -#endif -#if 0 - /* Twinkle the interrupt, and check if it's seen. */ - autoirq_setup(0); - write_irq(dev, lp->chip_type, i); - writereg(dev, PP_BufCFG, GENERATE_SW_INTERRUPT); - if (i == autoirq_report(0) /* It's a good IRQ line! */ - && request_irq (dev->irq = i, &net_interrupt, 0, "cs89x0") == 0) - break; -#else + if (request_irq (i, NULL, 0, "cs8920", NULL) != -EBUSY) { write_irq(dev, lp->chip_type, i); writereg(dev, PP_BufCFG, GENERATE_SW_INTERRUPT); -#if SUPPORTS_1_2_13 - if (request_irq (dev->irq = i, &net_interrupt, 0, "cs89x0") == 0) -#else if (request_irq (dev->irq = i, &net_interrupt, 0, "cs89x0", NULL) == 0) -#endif break; -#endif } } @@ -650,11 +625,7 @@ } writereg(dev, PP_BusCTL, ENABLE_IRQ | MEMORY_ON); write_irq(dev, lp->chip_type, dev->irq); -#if SUPPORTS_1_2_13 - if (request_irq(dev->irq, &net_interrupt, 0, "cs89x0")) { -#else if (request_irq(dev->irq, &net_interrupt, 0, "cs89x0", NULL)) { -#endif return -EAGAIN; } } @@ -685,11 +656,7 @@ printk("%s: EEPROM is configured for unavailable media\n", dev->name); release_irq: writereg(dev, PP_LineCTL, readreg(dev, PP_LineCTL) & ~(SERIAL_TX_ON | SERIAL_RX_ON)); -#if SUPPORTS_1_2_13 - free_irq(dev->irq); -#else free_irq(dev->irq, NULL); -#endif irq2dev_map[dev->irq] = 0; return -EAGAIN; } @@ -782,14 +749,6 @@ dev->trans_start = jiffies; } - /* 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; - } - /* Block a timer-based transmit from overlapping. This could better be done with atomic_swap(1, dev->tbusy), but set_bit() works as well. */ if (set_bit(0, (void*)&dev->tbusy) != 0) @@ -832,12 +791,7 @@ /* The typical workload of the driver: Handle the network interface interrupts. */ -static void -#if SUPPORTS_1_2_13 -net_interrupt(int irq, struct pt_regs * regs) -#else -net_interrupt(int irq, void *dev_id, struct pt_regs * regs) -#endif +static void net_interrupt(int irq, void *dev_id, struct pt_regs * regs) { struct device *dev = (struct device *)(irq2dev_map[irq]); struct net_local *lp; @@ -946,11 +900,11 @@ if (net_debug > 3)printk("%s: received %d byte packet of type %x\n", dev->name, length, (skb->data[ETH_ALEN+ETH_ALEN] << 8) | skb->data[ETH_ALEN+ETH_ALEN+1]); -#if !SUPPORTS_1_2_13 + skb->protocol=eth_type_trans(skb,dev); -#endif netif_rx(skb); lp->stats.rx_packets++; + lp->stats.rx_bytes+=skb->len; return; } @@ -966,11 +920,7 @@ dev->start = 0; -#if SUPPORTS_1_2_13 - free_irq(dev->irq); -#else free_irq(dev->irq, NULL); -#endif irq2dev_map[dev->irq] = 0; @@ -997,33 +947,6 @@ return &lp->stats; } -#if SUPPORTS_1_2_13 -/* Set or clear the multicast filter for this adaptor. - num_addrs == -1 Promiscuous mode, receive all packets - num_addrs == 0 Normal mode, clear multicast list - num_addrs > 0 Multicast mode, receive normal and MC packets, and do - best-effort filtering. - */ -static void -set_multicast_list(struct device *dev, int num_addrs, void *addrs) -{ - struct net_local *lp = (struct net_local *)dev->priv; - - if (num_addrs == 0) - lp->rx_mode = 0; - else if (num_addrs > 0) - lp->rx_mode = RX_MULTCAST_ACCEPT; - else if (num_addrs == -1) - lp->rx_mode = RX_ALL_ACCEPT; - - writereg(dev, PP_RxCTL, DEF_RX_ACCEPT | lp->rx_mode); - - /* in promiscuous mode, we accept errored packets, so we have to enable interrupts on them also */ - writereg(dev, PP_RxCFG, lp->curr_rx_cfg | - (lp->rx_mode == RX_ALL_ACCEPT? (RX_CRC_ERROR_ENBL|RX_RUNT_ENBL|RX_EXTRA_DATA_ENBL) : 0)); - -} -#else static void set_multicast_list(struct device *dev) { struct net_local *lp = (struct net_local *)dev->priv; @@ -1047,11 +970,9 @@ writereg(dev, PP_RxCFG, lp->curr_rx_cfg | (lp->rx_mode == RX_ALL_ACCEPT? (RX_CRC_ERROR_ENBL|RX_RUNT_ENBL|RX_EXTRA_DATA_ENBL) : 0)); } -#endif -static int -set_mac_address(struct device *dev, void *addr) +static int set_mac_address(struct device *dev, void *addr) { int i; if (dev->start) @@ -1066,10 +987,9 @@ return 0; } + #ifdef MODULE -#if SUPPORTS_1_2_13 -char kernel_version[] = UTS_RELEASE; -#endif + static char namespace[16] = ""; static struct device dev_cs89x0 = { NULL, diff -u --recursive --new-file v2.1.30/linux/drivers/net/de4x5.c linux/drivers/net/de4x5.c --- v2.1.30/linux/drivers/net/de4x5.c Thu Mar 27 14:40:03 1997 +++ linux/drivers/net/de4x5.c Mon Mar 31 12:52:30 1997 @@ -353,6 +353,7 @@ 0x00,0x18,} }; +#undef DE4X5_VERBOSE /* define to get more verbose startup messages */ #ifdef DE4X5_DEBUG static int de4x5_debug = DE4X5_DEBUG; @@ -645,7 +646,7 @@ ** Also have to save the irq for those cards whose hardware designers ** can't follow the PCI to PCI Bridge Architecture spec. */ -struct { +static struct { int chipset; int bus; int irq; @@ -768,7 +769,9 @@ static void yawn(struct device *dev, int state); static int de4x5_dev_index(char *s); static void link_modules(struct device *dev, struct device *tmp); +#ifdef MODULE static struct device *unlink_modules(struct device *p); +#endif static void de4x5_dbg_open(struct device *dev); static void de4x5_dbg_mii(struct device *dev, int k); static void de4x5_dbg_media(struct device *dev); @@ -807,7 +810,7 @@ int chipset; int (*fn)(struct device *); }; -struct InfoLeaf infoleaf_array[] = { +static struct InfoLeaf infoleaf_array[] = { {DC21041, dc21041_infoleaf}, {DC21140, dc21140_infoleaf}, {DC21142, dc21142_infoleaf}, @@ -1068,7 +1071,10 @@ printk(" and requires IRQ%d (provided by %s).\n", dev->irq, ((lp->bus == PCI) ? "PCI BIOS" : "EISA CNFG")); - printk("INFOLEAF_SIZE: %d\nCOMPACT: %d\n", INFOLEAF_SIZE, COMPACT); +#ifdef DE4X5_VERBOSE + printk("%s: INFOLEAF_SIZE: %ld, COMPACT: %ld\n", dev->name, + INFOLEAF_SIZE, COMPACT); +#endif } if (de4x5_debug & DEBUG_VERSION) { @@ -1293,6 +1299,9 @@ printk("%s: transmit busy, lost media or stale skb found:\n STS:%08x\n tbusy:%ld\n IMR:%08x\n OMR:%08x\n Stale skb: %s\n",dev->name, inl(DE4X5_STS), dev->tbusy, inl(DE4X5_IMR), inl(DE4X5_OMR), (lp->tx_skb[lp->tx_new] ? "YES" : "NO")); } } else if (skb->len > 0) { + /* Update the byte counter */ + lp->stats.tx_bytes += skb->len; + /* If we already have stuff queued locally, use that first */ if (lp->cache.skb && !dev->interrupt) { de4x5_put_cache(dev, skb); @@ -1316,7 +1325,7 @@ } if (skb) de4x5_putb_cache(dev, skb); } - + lp->cache.lock = 0; return status; @@ -1452,6 +1461,7 @@ /* Update stats */ lp->stats.rx_packets++; + lp->stats.rx_bytes += pkt_len; de4x5_local_stats(dev, skb->data, pkt_len); } @@ -2081,6 +2091,7 @@ return; } +#ifdef MODULE static struct device * unlink_modules(struct device *p) { @@ -2103,6 +2114,7 @@ return next; } +#endif /* ** Auto configure the media here rather than setting the port at compile @@ -4660,12 +4672,18 @@ u_long iobase = dev->base_addr; int i, j, status = 0; s32 omr; - union { - u8 addr[(HASH_TABLE_LEN * ETH_ALEN)]; - u16 sval[(HASH_TABLE_LEN * ETH_ALEN) >> 1]; - u32 lval[(HASH_TABLE_LEN * ETH_ALEN) >> 2]; + struct { + u8 *addr; + u16 *sval; + u32 *lval; } tmp; - + + tmp.addr = tmp.sval = tmp.lval = kmalloc(HASH_TABLE_LEN * ETH_ALEN, GFP_KERNEL); + if (!tmp.addr){ + printk("%s ioctl: memory squeeze.\n", dev->name); + return -ENOMEM; + } + switch(ioc->cmd) { case DE4X5_GET_HWADDR: /* Get the hardware address */ ioc->len = ETH_ALEN; @@ -4916,7 +4934,9 @@ default: status = -EOPNOTSUPP; } - + + kfree(tmp.addr); + return status; } diff -u --recursive --new-file v2.1.30/linux/drivers/net/de600.c linux/drivers/net/de600.c --- v2.1.30/linux/drivers/net/de600.c Sun Feb 2 05:18:37 1997 +++ linux/drivers/net/de600.c Mon Mar 31 12:52:30 1997 @@ -109,7 +109,7 @@ #include #include -unsigned int de600_debug = DE600_DEBUG; +static unsigned int de600_debug = DE600_DEBUG; MODULE_PARM(de600_debug, "i"); #ifdef FAKE_SMALL_MAX @@ -401,17 +401,6 @@ int len; int tickssofar; byte *buffer = skb->data; - - /* - * If some higher layer thinks we've missed a - * tx-done interrupt we are passed NULL. - * Caution: dev_tint() handles the cli()/sti() itself. - */ - - if (skb == NULL) { - dev_tint(dev); - return 0; - } if (free_tx_pages <= 0) { /* Do timeouts, to avoid hangs. */ tickssofar = jiffies - dev->trans_start; diff -u --recursive --new-file v2.1.30/linux/drivers/net/de620.c linux/drivers/net/de620.c --- v2.1.30/linux/drivers/net/de620.c Sun Feb 2 05:18:38 1997 +++ linux/drivers/net/de620.c Mon Mar 31 12:52:30 1997 @@ -521,17 +521,6 @@ byte *buffer = skb->data; byte using_txbuf; - /* - * If some higher layer thinks we've missed a - * tx-done interrupt we are passed NULL. - * Caution: dev_tint() handles the cli()/sti() itself. - */ - - if (skb == NULL) { - dev_tint(dev); - return 0; - } - using_txbuf = de620_tx_buffs(dev); /* Peek at the adapter */ dev->tbusy = (using_txbuf == (TXBF0 | TXBF1)); /* Boolean! */ diff -u --recursive --new-file v2.1.30/linux/drivers/net/dummy.c linux/drivers/net/dummy.c --- v2.1.30/linux/drivers/net/dummy.c Sun Feb 2 05:18:39 1997 +++ linux/drivers/net/dummy.c Mon Mar 31 12:52:30 1997 @@ -29,7 +29,6 @@ */ /* To have statistics (just packets sent) define this */ -#undef DUMMY_STATS #include @@ -54,9 +53,7 @@ #include static int dummy_xmit(struct sk_buff *skb, struct device *dev); -#ifdef DUMMY_STATS static struct net_device_stats *dummy_get_stats(struct device *dev); -#endif static int dummy_open(struct device *dev) { @@ -70,26 +67,25 @@ return 0; } +/* fake multicast ability */ +static void set_multicast_list(struct device *dev) +{ +} int dummy_init(struct device *dev) { -/* I commented this out as bootup is noisy enough anyway and this driver - seems pretty reliable 8) 8) 8) */ -/* printk ( KERN_INFO "Dummy net driver (94/05/27 v1.0)\n" ); */ - /* Initialize the device structure. */ dev->hard_start_xmit = dummy_xmit; -#if DUMMY_STATS dev->priv = kmalloc(sizeof(struct net_device_stats), GFP_KERNEL); if (dev->priv == NULL) return -ENOMEM; memset(dev->priv, 0, sizeof(struct net_device_stats)); dev->get_stats = dummy_get_stats; -#endif dev->open = dummy_open; dev->stop = dummy_close; + dev->set_multicast_list = set_multicast_list; /* Fill in the fields of the device structure with ethernet-generic values. */ ether_setup(dev); @@ -99,29 +95,23 @@ return 0; } -static int -dummy_xmit(struct sk_buff *skb, struct device *dev) +static int dummy_xmit(struct sk_buff *skb, struct device *dev) { -#if DUMMY_STATS struct net_device_stats *stats; -#endif dev_kfree_skb(skb, FREE_WRITE); -#if DUMMY_STATS stats = (struct net_device_stats *)dev->priv; stats->tx_packets++; -#endif + stats->tx_bytes+=skb->len; return 0; } -#if DUMMY_STATS static struct net_device_stats *dummy_get_stats(struct device *dev) { struct net_device_stats *stats = (struct net_device_stats *) dev->priv; return stats; } -#endif #ifdef MODULE @@ -131,8 +121,10 @@ return 0; } +static char dummy_name[16]; + static struct device dev_dummy = { - "dummy0\0 ", + dummy_name, /* Needs to be writeable */ 0, 0, 0, 0, 0x0, 0, 0, 0, 0, NULL, dummy_probe }; @@ -140,16 +132,9 @@ int init_module(void) { /* Find a name for this unit */ - int ct= 1; - - while(dev_get(dev_dummy.name)!=NULL && ct<100) - { - sprintf(dev_dummy.name,"dummy%d",ct); - ct++; - } - if(ct==100) - return -ENFILE; - + int err=dev_alloc_name(&dev_dummy,"dummy%d"); + if(err) + return err; if (register_netdev(&dev_dummy) != 0) return -EIO; return 0; diff -u --recursive --new-file v2.1.30/linux/drivers/net/eepro.c linux/drivers/net/eepro.c --- v2.1.30/linux/drivers/net/eepro.c Sun Feb 2 05:18:39 1997 +++ linux/drivers/net/eepro.c Mon Mar 31 12:52:30 1997 @@ -712,14 +712,6 @@ } - /* 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; - } - /* Block a timer-based transmit from overlapping. */ if (set_bit(0, (void*)&dev->tbusy) != 0) printk("%s: Transmitter access conflict.\n", dev->name); diff -u --recursive --new-file v2.1.30/linux/drivers/net/eexpress.c linux/drivers/net/eexpress.c --- v2.1.30/linux/drivers/net/eexpress.c Sun Feb 2 05:18:39 1997 +++ linux/drivers/net/eexpress.c Mon Mar 31 12:52:30 1997 @@ -467,25 +467,6 @@ if (dev->tbusy) unstick_cu(dev); - if (buf==NULL) - { - /* Some higher layer thinks we might have missed a - * tx-done interrupt. Does this ever actually happen? - */ - unsigned short status = scb_status(dev); - unsigned short txstatus = eexp_hw_lasttxstat(dev); - if (SCB_CUdead(status)) - { - printk(KERN_WARNING "%s: CU has died! status %04x %04x, attempting to restart...\n", - dev->name, status, txstatus); - lp->stats.tx_errors++; - eexp_hw_txrestart(dev); - } - dev_tint(dev); - outb(SIRQ_en|irqrmap[dev->irq],dev->base_addr+SET_IRQ); - return 0; - } - if (set_bit(0,(void *)&dev->tbusy)) { lp->stats.tx_dropped++; diff -u --recursive --new-file v2.1.30/linux/drivers/net/fmv18x.c linux/drivers/net/fmv18x.c --- v2.1.30/linux/drivers/net/fmv18x.c Sun Feb 2 05:18:40 1997 +++ linux/drivers/net/fmv18x.c Mon Mar 31 12:52:30 1997 @@ -345,14 +345,6 @@ sti(); } - /* 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; - } - /* Block a timer-based transmit from overlapping. This could better be done with atomic_swap(1, dev->tbusy), but set_bit() works as well. */ if (set_bit(0, (void*)&dev->tbusy) != 0) diff -u --recursive --new-file v2.1.30/linux/drivers/net/hp100.c linux/drivers/net/hp100.c --- v2.1.30/linux/drivers/net/hp100.c Sun Feb 2 05:18:40 1997 +++ linux/drivers/net/hp100.c Mon Mar 31 10:26:12 1997 @@ -180,8 +180,8 @@ { 0x01030103c, "HP J2585", HP100_BUS_PCI }, }; -int hp100_rx_ratio = HP100_DEFAULT_RX_RATIO; -int hp100_priority_tx = HP100_DEFAULT_PRIORITY_TX; +static int hp100_rx_ratio = HP100_DEFAULT_RX_RATIO; +static int hp100_priority_tx = HP100_DEFAULT_PRIORITY_TX; /* * prototypes diff -u --recursive --new-file v2.1.30/linux/drivers/net/ibmtr.c linux/drivers/net/ibmtr.c --- v2.1.30/linux/drivers/net/ibmtr.c Fri Feb 7 05:54:54 1997 +++ linux/drivers/net/ibmtr.c Mon Mar 31 12:52:30 1997 @@ -53,7 +53,9 @@ * from being rudely overwritten before the transmit cycle is * complete. (August 15 1996) * + completed multiple adapter support. (November 20 1996) - */ + * + implemented csum_partial_copy in tr_rx and increased receive + * buffer size and count. Minor fixes. (March 15, 1997) +*/ #ifdef PCMCIA #define MODULE @@ -79,13 +81,10 @@ /* some 95 OS send many non UI frame; this allow removing the warning */ #define TR_FILTERNONUI 1 -/* use memcpy to read/write frame data instead of for-loop */ -#define USE_MEMCPY 1 - /* version and credits */ static char *version = "ibmtr.c: v1.3.57 8/ 7/94 Peter De Schrijver and Mark Swanson\n" -" v2.1.10 11/20/96 Paul Norton \n"; +" v2.1.29 3/15/97 Paul Norton \n"; static char pcchannelid[] = { 0x05, 0x00, 0x04, 0x09, @@ -120,6 +119,7 @@ #include #include #include +#include #include #include @@ -178,8 +178,6 @@ void ibmtr_readlog(struct device *dev); void ibmtr_reset_timer(struct timer_list *tmr, struct device *dev); -static struct timer_list tr_timer; - static unsigned int ibmtr_portlist[] = { 0xa20, 0xa24, 0 }; @@ -858,7 +856,7 @@ open_ret_code); if (ti->open_status != FAILURE) { - ibmtr_reset_timer(&tr_timer, dev); + ibmtr_reset_timer(&(ti->tr_timer), dev); } } @@ -872,7 +870,7 @@ 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))); - ibmtr_reset_timer(&tr_timer, dev); + ibmtr_reset_timer(&(ti->tr_timer), dev); } else { ti->exsap_station_id= readw(ti->srb+offsetof(struct dlc_open_sap, station_id)); @@ -983,7 +981,7 @@ DPRINTK("Signal loss/Lobe fault\n"); DPRINTK("We try to reopen the adapter.\n"); - ibmtr_reset_timer(&tr_timer, dev); + ibmtr_reset_timer(&(ti->tr_timer), dev); } else if (ring_status & (HARD_ERROR | XMIT_BEACON | AUTO_REMOVAL | REMOVE_RECV | RING_RECOVER)) DPRINTK("New ring status: %02X\n", ring_status); @@ -1297,27 +1295,16 @@ /* header length including rif is computed above, now move the data and set fields appropriately. */ -#if USE_MEMCPY memcpy_toio(dhb, ti->current_skb->data, hdr_len); -#else - for (i=0; icurrent_skb->data +i), dhb++); -#endif 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 */ -#if USE_MEMCPY memcpy_toio(dhb + hdr_len, ti->current_skb->data + sizeof(struct trh_hdr), ti->current_skb->len - sizeof(struct trh_hdr)); -#else - 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); -#endif writeb(RESP_IN_ASB, ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD); dev->tbusy=0; @@ -1329,20 +1316,20 @@ static void tr_rx(struct device *dev) { - int i; struct tok_info *ti=(struct tok_info *) dev->priv; - __u32 rbuffer; + __u32 rbuffer, rbufdata; __u32 llc; unsigned char *data; - unsigned int rbuffer_len, lan_hdr_len; + unsigned int rbuffer_len, lan_hdr_len, hdr_len; unsigned int arb_frame_len; struct sk_buff *skb; unsigned int skb_size = 0; int is8022 = 0; + unsigned int chksum = 0; rbuffer=(ti->sram - +ntohs(readw(ti->arb + offsetof(struct arb_rec_req, rec_buf_addr)))); - + +ntohs(readw(ti->arb + offsetof(struct arb_rec_req, rec_buf_addr))))+2; + if(readb(ti->asb + offsetof(struct asb_rec, ret_code))!=0xFF) DPRINTK("ASB not free !!!\n"); @@ -1354,7 +1341,7 @@ 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 @@ -1367,128 +1354,123 @@ "ethertype: %04X\n", (int)readb(llc + offsetof(struct trllc, dsap)), (int)readb(llc + offsetof(struct trllc, ssap)), + (int)readb(llc + offsetof(struct trllc, llc)), (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 (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 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 ((readb(llc + offsetof(struct trllc, dsap))!=0xAA) || - (readb(llc + offsetof(struct trllc, ssap))!=0xAA)) { - is8022 = 1; - } - -#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 - - arb_frame_len=ntohs(readw(ti->arb+offsetof(struct arb_rec_req, frame_len))); - skb_size = arb_frame_len-lan_hdr_len+sizeof(struct trh_hdr); - if (is8022) { - skb_size += sizeof(struct trllc); - } - - if (!(skb=dev_alloc_skb(skb_size))) { - 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, skb_size); - skb->dev=dev; - - data=skb->data; -#if USE_MEMCPY - memcpy_fromio(data, rbuffer + offsetof(struct rec_buf, data), lan_hdr_len); -#else - for (i=0; iethertype = htons(ETH_P_TR_802_2); - data += sizeof(struct trllc); - } + if ((readb(llc + offsetof(struct trllc, dsap))!=0xAA) || + (readb(llc + offsetof(struct trllc, ssap))!=0xAA)) { + is8022 = 1; + } #if TR_VERBOSE - DPRINTK("rbuffer_len: %d, data: %p\n", rbuffer_len, data); -#endif -#if USE_MEMCPY - memcpy_fromio(data, rbuffer + offsetof(struct rec_buf, data) + lan_hdr_len, rbuffer_len); -#else - 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)); + 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 + + arb_frame_len=ntohs(readw(ti->arb+offsetof(struct arb_rec_req, frame_len))); + skb_size = arb_frame_len-lan_hdr_len+sizeof(struct trh_hdr); + if (is8022) { + skb_size += sizeof(struct trllc); + } + + if (!(skb=dev_alloc_skb(skb_size))) { + 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, skb_size); + skb->dev=dev; + + data=skb->data; + + /* Copy the 802.5 MAC header */ + memcpy_fromio(data, rbuffer + offsetof(struct rec_buf, data), lan_hdr_len); + + if (lan_hdr_lenethertype = htons(ETH_P_TR_802_2); + hdr_len = sizeof(struct trllc); + } else { + /* Copy the LLC header and the IPv4 header */ + hdr_len = sizeof(struct trllc) + sizeof(struct iphdr); + memcpy_fromio(data, rbuffer+offsetof(struct rec_buf, data)+lan_hdr_len,hdr_len); + } + data += hdr_len; + lan_hdr_len += hdr_len; + rbuffer_len -= hdr_len; + rbufdata = rbuffer + offsetof(struct rec_buf,data) + lan_hdr_len; + + /* Copy the payload... */ + for (;;) { + if (is8022) + memcpy_fromio(data, rbufdata, rbuffer_len); + else + chksum = csum_partial_copy(bus_to_virt(rbufdata), data, rbuffer_len, chksum); + rbuffer = ntohs(readw(rbuffer)); + if (!rbuffer) + break; + data += rbuffer_len; + rbuffer += ti->sram; + rbuffer_len = ntohs(readw(rbuffer + offsetof(struct rec_buf, buf_len))); + rbufdata = rbuffer + offsetof(struct rec_buf, data); + } - writeb(RESP_IN_ASB, ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD); + writeb(0, ti->asb + offsetof(struct asb_rec, ret_code)); - ti->tr_stats.rx_packets++; + writeb(RESP_IN_ASB, ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD); - skb->protocol=tr_type_trans(skb,dev); - netif_rx(skb); + ti->tr_stats.rx_packets++; + skb->protocol = tr_type_trans(skb,dev); + if (!is8022){ + skb->csum = chksum; + skb->ip_summed = 1; } + netif_rx(skb); +} static int tok_send_packet(struct sk_buff *skb, struct device *dev) { diff -u --recursive --new-file v2.1.30/linux/drivers/net/ibmtr.h linux/drivers/net/ibmtr.h --- v2.1.30/linux/drivers/net/ibmtr.h Sat Dec 21 03:16:57 1996 +++ linux/drivers/net/ibmtr.h Mon Mar 31 12:52:30 1997 @@ -200,11 +200,13 @@ unsigned short exsap_station_id; unsigned short global_int_enable; struct sk_buff *current_skb; - struct tr_statistics tr_stats; + struct net_device_stats tr_stats; unsigned char auto_ringspeedsave; open_state open_status; unsigned char readlog_pending; unsigned short adapter_int_enable; /* Adapter-specific int enable */ + struct timer_list tr_timer; + __u32 func_addr; }; /* token ring adapter commands */ @@ -213,7 +215,7 @@ #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_SET_FUNC_ADDR 0x07 /* struct srb_set_funct_addr */ #define DIR_READ_LOG 0x08 /* struct srb_read_log */ #define DLC_OPEN_SAP 0x15 /* struct dlc_open_sap */ #define DLC_CLOSE_SAP 0x16 @@ -225,8 +227,8 @@ /* DIR_OPEN_ADAPTER options */ #define OPEN_PASS_BCON_MAC 0x0100 -#define NUM_RCV_BUF 16 -#define RCV_BUF_LEN 136 +#define NUM_RCV_BUF 3 +#define RCV_BUF_LEN 1024 #define DHB_LENGTH 2048 #define NUM_DHB 2 #define DLC_MAX_SAP 2 @@ -396,7 +398,7 @@ }; struct rec_buf { - unsigned char reserved1[2]; + /* unsigned char reserved1[2]; */ __u16 buf_ptr; unsigned char reserved2; __u16 buf_len; @@ -424,5 +426,13 @@ unsigned char command; unsigned char reserved1; unsigned char ret_code; +}; + +struct srb_set_funct_addr { + unsigned char command; + unsigned char reserved1; + unsigned char ret_code; + unsigned char reserved2[3]; + __u32 funct_address; }; diff -u --recursive --new-file v2.1.30/linux/drivers/net/loopback.c linux/drivers/net/loopback.c --- v2.1.30/linux/drivers/net/loopback.c Sun Feb 2 05:18:40 1997 +++ linux/drivers/net/loopback.c Mon Mar 31 12:52:30 1997 @@ -93,7 +93,9 @@ skb->ip_summed = CHECKSUM_UNNECESSARY; #endif netif_rx(skb); - + + stats->rx_bytes+=skb->len; + stats->tx_bytes+=skb->len; stats->rx_packets++; stats->tx_packets++; diff -u --recursive --new-file v2.1.30/linux/drivers/net/ltpc.c linux/drivers/net/ltpc.c --- v2.1.30/linux/drivers/net/ltpc.c Thu Mar 27 14:40:04 1997 +++ linux/drivers/net/ltpc.c Mon Mar 31 12:52:30 1997 @@ -690,7 +690,7 @@ int dnode, snode, llaptype, len; int sklen; struct sk_buff *skb; - struct enet_statistics *stats = (struct enet_statistics *)dev->priv; + struct net_device_stats *stats = (struct enet_statistics *)dev->priv; struct lt_rcvlap *ltc = (struct lt_rcvlap *) ltdmacbuf; if (ltc->command != LT_RCVLAP) { @@ -742,9 +742,11 @@ skb->h.raw = skb->data; + stats->rx_packets++; + stats->rx_bytes+=skb->len; + /* toss it onwards */ netif_rx(skb); - stats->rx_packets++; return 0; } @@ -939,16 +941,16 @@ printk("\n"); } - dev_kfree_skb(skb, FREE_WRITE); - stats->tx_packets++; + stats->tx_bytes+=skb->len; + dev_kfree_skb(skb, FREE_WRITE); return 0; } static struct net_device_stats *ltpc_get_stats(struct device *dev) { - struct enet_statistics *stats = (struct enet_statistics*) dev->priv; + struct net_device_stats *stats = (struct net_device_stats *) dev->priv; return stats; } @@ -1211,8 +1213,11 @@ } #ifdef MODULE + +static char dev_name[8]; + static struct device dev_ltpc = { - "ltalk0\0 ", + dev_name, 0, 0, 0, 0, 0x0, 0, 0, 0, 0, NULL, ltpc_probe }; @@ -1220,16 +1225,11 @@ int init_module(void) { /* Find a name for this unit */ - int ct= 1; - - while(dev_get(dev_ltpc.name)!=NULL && ct<100) - { - sprintf(dev_ltpc.name,"ltpc%d",ct); - ct++; - } - if(ct==100) - return -ENFILE; + int err=dev_alloc_name(&dev_ltpc,"lt%d"); + if(err<0) + return err; + if (register_netdev(&dev_ltpc) != 0) { if(debug&DEBUG_VERBOSE) printk("EIO from register_netdev\n"); return -EIO; diff -u --recursive --new-file v2.1.30/linux/drivers/net/pcnet32.c linux/drivers/net/pcnet32.c --- v2.1.30/linux/drivers/net/pcnet32.c Thu Mar 27 14:40:04 1997 +++ linux/drivers/net/pcnet32.c Mon Mar 31 10:26:12 1997 @@ -37,9 +37,9 @@ static unsigned int pcnet32_portlist[] = {0x300, 0x320, 0x340, 0x360, 0}; #ifdef PCNET32_DEBUG -int pcnet32_debug = PCNET32_DEBUG; +static int pcnet32_debug = PCNET32_DEBUG; #else -int pcnet32_debug = 1; +static int pcnet32_debug = 1; #endif /* diff -u --recursive --new-file v2.1.30/linux/drivers/net/pi2.c linux/drivers/net/pi2.c --- v2.1.30/linux/drivers/net/pi2.c Thu Mar 27 14:40:04 1997 +++ linux/drivers/net/pi2.c Mon Mar 31 12:52:30 1997 @@ -1482,13 +1482,6 @@ { struct pi_local *lp = (struct pi_local *) dev->priv; - /* 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; - } hardware_send_packet(lp, skb); dev->trans_start = jiffies; diff -u --recursive --new-file v2.1.30/linux/drivers/net/plip.c linux/drivers/net/plip.c --- v2.1.30/linux/drivers/net/plip.c Sun Feb 2 05:18:41 1997 +++ linux/drivers/net/plip.c Mon Mar 31 12:52:30 1997 @@ -885,14 +885,6 @@ 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; diff -u --recursive --new-file v2.1.30/linux/drivers/net/pt.c linux/drivers/net/pt.c --- v2.1.30/linux/drivers/net/pt.c Thu Mar 27 14:40:04 1997 +++ linux/drivers/net/pt.c Mon Mar 31 12:52:31 1997 @@ -947,13 +947,6 @@ #ifdef PT_DEBUG printk(KERN_DEBUG "PT: pt_send_packet(): (%d)\n", lp->base & CHANA); #endif - /* 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; - } hardware_send_packet(lp, skb); dev->trans_start = jiffies; diff -u --recursive --new-file v2.1.30/linux/drivers/net/sdla_fr.c linux/drivers/net/sdla_fr.c --- v2.1.30/linux/drivers/net/sdla_fr.c Sun Feb 2 06:42:57 1997 +++ linux/drivers/net/sdla_fr.c Mon Mar 31 12:52:31 1997 @@ -573,20 +573,6 @@ sdla_t* card = chan->card; int retry = 0; - if (skb == NULL) - { - /* If we get here, some higher layer thinks we've missed an - * tx-done interrupt. - */ -#ifdef _DEBUG_ - printk(KERN_INFO "%s: interface %s got kicked!\n", - card->devname, dev->name) - ; -#endif - dev_tint(dev); - return 0; - } - if (set_bit(0, (void*)&card->wandev.critical)) { #ifdef _DEBUG_ diff -u --recursive --new-file v2.1.30/linux/drivers/net/sdla_ppp.c linux/drivers/net/sdla_ppp.c --- v2.1.30/linux/drivers/net/sdla_ppp.c Sun Feb 2 06:43:08 1997 +++ linux/drivers/net/sdla_ppp.c Mon Mar 31 12:52:31 1997 @@ -440,20 +440,6 @@ sdla_t* card = dev->priv; int retry = 0; - if (skb == NULL) - { - /* If we get here, some higher layer thinks we've missed an - * tx-done interrupt. - */ -#ifdef _DEBUG_ - printk(KERN_INFO "%s: interface %s got kicked!\n", - card->devname, dev->name) - ; -#endif - dev_tint(dev); - return 0; - } - if (set_bit(0, (void*)&card->wandev.critical)) { #ifdef _DEBUG_ diff -u --recursive --new-file v2.1.30/linux/drivers/net/sdla_x25.c linux/drivers/net/sdla_x25.c --- v2.1.30/linux/drivers/net/sdla_x25.c Sun Feb 2 06:43:19 1997 +++ linux/drivers/net/sdla_x25.c Mon Mar 31 12:52:31 1997 @@ -589,20 +589,6 @@ sdla_t* card = chan->card; int retry = 0, queued = 0; - if (skb == NULL) - { - /* If we get here, some higher layer thinks we've missed a - * tx-done interrupt. - */ -#ifdef _DEBUG_ - printk(KERN_INFO "%s: interface %s got kicked!\n", - card->devname, dev->name) - ; -#endif - dev_tint(dev); - return 0; - } - if (set_bit(0, (void*)&card->wandev.critical)) { #ifdef _DEBUG_ diff -u --recursive --new-file v2.1.30/linux/drivers/net/seeq8005.c linux/drivers/net/seeq8005.c --- v2.1.30/linux/drivers/net/seeq8005.c Fri Feb 7 05:54:54 1997 +++ linux/drivers/net/seeq8005.c Mon Mar 31 12:52:31 1997 @@ -89,9 +89,9 @@ /* Example routines you must write ;->. */ #define tx_done(dev) (inw(SEEQ_STATUS) & SEEQSTAT_TX_ON) -extern void hardware_send_packet(struct device *dev, char *buf, int length); +static void hardware_send_packet(struct device *dev, char *buf, int length); extern void seeq8005_init(struct device *dev, int startp); -inline void wait_for_buffer(struct device *dev); +static inline void wait_for_buffer(struct device *dev); /* Check for a network adaptor of this type, and return '0' iff one exists. @@ -389,14 +389,6 @@ dev->trans_start = jiffies; } - /* 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; - } - /* Block a timer-based transmit from overlapping. This could better be done with atomic_swap(1, dev->tbusy), but set_bit() works as well. */ if (set_bit(0, (void*)&dev->tbusy) != 0) @@ -689,7 +681,7 @@ } -void hardware_send_packet(struct device * dev, char *buf, int length) +static void hardware_send_packet(struct device * dev, char *buf, int length) { int ioaddr = dev->base_addr; int status = inw(SEEQ_STATUS); diff -u --recursive --new-file v2.1.30/linux/drivers/net/shaper.c linux/drivers/net/shaper.c --- v2.1.30/linux/drivers/net/shaper.c Sun Feb 2 05:18:41 1997 +++ linux/drivers/net/shaper.c Mon Mar 31 12:52:31 1997 @@ -610,18 +610,11 @@ int init_module(void) { - int i; - for(i=0;i<99;i++) - { - sprintf(devicename,"shaper%d",i); - if(dev_get(devicename)==NULL) - break; - } - if(i==100) - return -ENFILE; - + int err=dev_alloc_name(&dev_shape,"shaper%d"); + if(err<0) + return err; printk(SHAPER_BANNER); - if (register_netdev(&dev_shape) != 0) + if (register_netdev(dev) != 0) return -EIO; printk("Traffic shaper initialised.\n"); return 0; diff -u --recursive --new-file v2.1.30/linux/drivers/net/sk_g16.c linux/drivers/net/sk_g16.c --- v2.1.30/linux/drivers/net/sk_g16.c Thu Mar 27 14:40:04 1997 +++ linux/drivers/net/sk_g16.c Mon Mar 31 12:52:31 1997 @@ -40,9 +40,6 @@ * M. Hipp (mhipp@student.uni-tuebingen.de) * R. Bolz (Schneider & Koch, Germany) * - * See README.sk_g16 for details about limitations and bugs for the - * current version. - * * To Do: * - Support of SK_G8 and other SK Network Cards. * - Autoset memory mapped RAM. Check for free memory and then @@ -322,20 +319,6 @@ #define ETHERCARD_TOTAL_SIZE SK_POS_SIZE /* - * Portreserve is there to mark the Card I/O Port region as used. - * Check_region is to check if the region at ioaddr with the size "size" - * is free or not. - * Snarf_region allocates the I/O Port region. - */ - -#ifndef HAVE_PORTRESERVE - -#define check_region(ioaddr, size) 0 -#define request_region(ioaddr, size,name) do ; while (0) - -#endif - -/* * SK_DEBUG * * Here you can choose what level of debugging wanted. @@ -1028,6 +1011,7 @@ static int SK_lance_init(struct device *dev, unsigned short mode) { int i; + unsigned long flags; struct priv *p = (struct priv *) dev->priv; struct tmd *tmdp; struct rmd *rmdp; @@ -1046,10 +1030,10 @@ { tmdp = p->tmdhead + i; - tmdp->u.buffer = (unsigned long) p->tmdbufs[i]; /* assign buffer */ + writel((unsigned long) p->tmdbufs[i], tmdp->u.buffer); /* assign buffer */ /* Mark TMD as start and end of packet */ - tmdp->u.s.status = TX_STP | TX_ENP; + writeb(TX_STP | TX_ENP, tmdp->u.s.status); } @@ -1062,42 +1046,43 @@ rmdp = p->rmdhead + i; - rmdp->u.buffer = (unsigned long) p->rmdbufs[i]; /* assign buffer */ + writel((unsigned long) p->rmdbufs[i], rmdp->u.buffer); /* assign buffer */ /* * LANCE must be owner at beginning so that he can fill in * receiving packets, set status and release RMD */ - rmdp->u.s.status = RX_OWN; + writeb(RX_OWN, rmdp->u.s.status); - rmdp->blen = -PKT_BUF_SZ; /* Buffer Size in a two's complement */ + writew(-PKT_BUF_SZ, rmdp->blen); /* Buffer Size (two's complement) */ - rmdp->mlen = 0; /* init message length */ + writeb(0, rmdp->mlen); /* init message length */ } /* Fill LANCE Initialize Block */ - (p->ram)->ib.mode = mode; /* Set operation mode */ + writew(mode, (p->ram)->ib.mode); /* Set operation mode */ for (i = 0; i < ETH_ALEN; i++) /* Set physical address */ { - (p->ram)->ib.paddr[i] = dev->dev_addr[i]; + writeb(dev->dev_addr[i], (p->ram)->ib.paddr[i]); } for (i = 0; i < 8; i++) /* Set multicast, logical address */ { - (p->ram)->ib.laddr[i] = 0; /* We do not use logical addressing */ + writeb(0, (p->ram)->ib.laddr[i]); /* We do not use logical addressing */ } /* Set ring descriptor pointers and set number of descriptors */ - (p->ram)->ib.rdrp = (int) p->rmdhead | RMDNUMMASK; - (p->ram)->ib.tdrp = (int) p->tmdhead | TMDNUMMASK; + writel((int)p->rmdhead | RMDNUMMASK, (p->ram)->ib.rdrp); + writel((int)p->tmdhead | TMDNUMMASK, (p->ram)->ib.tdrp); /* Prepare LANCE Control and Status Registers */ + save_flags(flags); cli(); SK_write_reg(CSR3, CSR3_ACON); /* Ale Control !!!THIS MUST BE SET!!!! */ @@ -1133,7 +1118,7 @@ SK_write_reg(CSR0, CSR0_INIT); - sti(); + restore_flags(flags); /* Wait until LANCE finished initialization */ @@ -1216,22 +1201,6 @@ } - /* - * If some upper Layer thinks we missed a transmit done interrupt - * we are passed NULL. - * (dev_queue_xmit net/inet/dev.c - */ - - if (skb == NULL) - { - /* - * Dequeue packets from transmit queue and send them. - */ - dev_tint(dev); - - return 0; - } - PRINTK2(("## %s: SK_send_packet() called, CSR0 %#04x.\n", SK_NAME, SK_read_reg(CSR0))); @@ -1258,7 +1227,7 @@ memcpy_toio((tmdp->u.buffer & 0x00ffffff), skb->data, skb->len); - tmdp->blen = -len; /* set length to transmit */ + writew(-len, tmdp->blen); /* set length to transmit */ /* * Packet start and end is always set because we use the maximum @@ -1266,7 +1235,7 @@ * Relinquish ownership to LANCE */ - tmdp->u.s.status = TX_OWN | TX_STP | TX_ENP; + writeb(TX_OWN | TX_STP | TX_ENP, tmdp->u.s.status); /* Start Demand Transmission */ SK_write_reg(CSR0, CSR0_TDMD | CSR0_INEA); @@ -1278,7 +1247,7 @@ p->tmdnum &= TMDNUM-1; /* Do we own the next transmit buffer ? */ - if (! ((p->tmdhead + p->tmdnum)->u.s.status & TX_OWN) ) + if (! (readb((p->tmdhead + p->tmdnum)->u.s.status) & TX_OWN) ) { /* * We own next buffer and are ready to transmit, so @@ -1400,7 +1369,7 @@ p->tmdlast++; p->tmdlast &= TMDNUM-1; - tmdstat = tmdp->u.s.status & 0xff00; /* filter out status bits 15:08 */ + tmdstat = readb(tmdp->u.s.status); /* * We check status of transmitted packet. @@ -1408,21 +1377,22 @@ */ if (tmdstat & TX_ERR) /* Error occurred */ { - printk("%s: TX error: %04x %04x\n", dev->name, (int) tmdstat, - (int) tmdp->status2); + int stat2 = readw(tmdp->status2); + + printk("%s: TX error: %04x %04x\n", dev->name, tmdstat, stat2); - if (tmdp->status2 & TX_TDR) /* TDR problems? */ + if (stat2 & TX_TDR) /* TDR problems? */ { printk("%s: tdr-problems \n", dev->name); } - if (tmdp->status2 & TX_RTRY) /* Failed in 16 attempts to transmit ? */ + if (stat2 & TX_RTRY) /* Failed in 16 attempts to transmit ? */ p->stats.tx_aborted_errors++; - if (tmdp->status2 & TX_LCOL) /* Late collision ? */ + if (stat2 & TX_LCOL) /* Late collision ? */ p->stats.tx_window_errors++; - if (tmdp->status2 & TX_LCAR) /* Loss of Carrier ? */ + if (stat2 & TX_LCAR) /* Loss of Carrier ? */ p->stats.tx_carrier_errors++; - if (tmdp->status2 & TX_UFLO) /* Underflow error ? */ + if (stat2 & TX_UFLO) /* Underflow error ? */ { p->stats.tx_fifo_errors++; @@ -1436,7 +1406,7 @@ p->stats.tx_errors++; - tmdp->status2 = 0; /* Clear error flags */ + writew(0, tmdp->status2); /* Clear error flags */ } else if (tmdstat & TX_MORE) /* Collisions occurred ? */ { @@ -1449,7 +1419,7 @@ * First I did not have this in but then I thought at minimum * we see that something was not ok. * If anyone knows something better than this to handle this - * please report it. (see Email addresses in the README file) + * please report it. */ p->stats.collisions++; @@ -1519,7 +1489,7 @@ * it up to higher layer */ - while (!( (rmdstat = rmdp->u.s.status) & RX_OWN)) + while (!( (rmdstat = readb(rmdp->u.s.status)) & RX_OWN)) { /* * Start and end of packet must be set, because we use @@ -1549,7 +1519,7 @@ * packets. */ - rmdp->u.s.status = RX_OWN; /* Relinquish ownership to LANCE */ + writeb(RX_OWN, rmdp->u.s.status); /* Relinquish ownership to LANCE */ } else if (rmdstat & RX_ERR) /* Receive Error ? */ @@ -1561,13 +1531,13 @@ if (rmdstat & RX_FRAM) p->stats.rx_frame_errors++; if (rmdstat & RX_CRC) p->stats.rx_crc_errors++; - rmdp->u.s.status = RX_OWN; /* Relinquish ownership to LANCE */ + writeb(RX_OWN, rmdp->u.s.status); /* Relinquish ownership to LANCE */ } else /* We have a packet which can be queued for the upper layers */ { - int len = (rmdp->mlen & 0x0fff); /* extract message length from receive buffer */ + int len = readw(rmdp->mlen) & 0x0fff; /* extract message length from receive buffer */ struct sk_buff *skb; skb = dev_alloc_skb(len+2); /* allocate socket buffer */ @@ -1580,7 +1550,7 @@ * to Lance, update statistics and go ahead. */ - rmdp->u.s.status = RX_OWN; /* Relinquish ownership to LANCE */ + writeb(RX_OWN, rmdp->u.s.status); /* Relinquish ownership to LANCE */ printk("%s: Couldn't allocate sk_buff, deferring packet.\n", dev->name); p->stats.rx_dropped++; @@ -1618,7 +1588,7 @@ * free our descriptor and update statistics */ - rmdp->u.s.status = RX_OWN; + writeb(RX_OWN, rmdp->u.s.status); p->stats.rx_packets++; diff -u --recursive --new-file v2.1.30/linux/drivers/net/slip.c linux/drivers/net/slip.c --- v2.1.30/linux/drivers/net/slip.c Tue Mar 4 10:25:23 1997 +++ linux/drivers/net/slip.c Mon Mar 31 12:52:31 1997 @@ -312,7 +312,7 @@ } -/* Set the "sending" flag. This must be atomic, hence the ASM. */ +/* Set the "sending" flag. This must be atomic hence the set_bit. */ static inline void sl_lock(struct slip *sl) { diff -u --recursive --new-file v2.1.30/linux/drivers/net/smc9194.c linux/drivers/net/smc9194.c --- v2.1.30/linux/drivers/net/smc9194.c Fri Feb 7 05:54:54 1997 +++ linux/drivers/net/smc9194.c Mon Mar 31 12:52:31 1997 @@ -1242,14 +1242,6 @@ ((struct smc_local *)dev->priv)->saved_skb = NULL; } - /* 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; - } - /* Block a timer-based transmit from overlapping. This could better be done with atomic_swap(1, dev->tbusy), but set_bit() works as well. */ if (set_bit(0, (void*)&dev->tbusy) != 0) { diff -u --recursive --new-file v2.1.30/linux/drivers/net/soundmodem/sm.c linux/drivers/net/soundmodem/sm.c --- v2.1.30/linux/drivers/net/soundmodem/sm.c Thu Mar 27 14:40:04 1997 +++ linux/drivers/net/soundmodem/sm.c Mon Mar 31 12:52:31 1997 @@ -235,6 +235,11 @@ * the same behaviour as par96_check_lpt in baycom.c */ +/* + * returns 0 if ok and != 0 on error; + * the same behaviour as par96_check_lpt in baycom.c + */ + static int check_lpt(unsigned int iobase) { unsigned char b1,b2; diff -u --recursive --new-file v2.1.30/linux/drivers/net/tunnel.c linux/drivers/net/tunnel.c --- v2.1.30/linux/drivers/net/tunnel.c Sun Feb 2 05:18:42 1997 +++ linux/drivers/net/tunnel.c Mon Mar 31 12:52:31 1997 @@ -268,30 +268,23 @@ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #ifdef MODULE -static int tunnel_probe(struct device *dev) -{ - tunnel_init(dev); - return 0; -} + +static char tunnel_name[16]; static struct device dev_tunnel = { - "tunl0\0 ", + tunnel_name, 0, 0, 0, 0, 0x0, 0, - 0, 0, 0, NULL, tunnel_probe + 0, 0, 0, NULL, tunnel_init }; int init_module(void) { /* Find a name for this unit */ - int ct= 1; - - while(dev_get(dev_tunnel.name)!=NULL && ct<100) - { - sprintf(dev_tunnel.name,"tunl%d",ct); - ct++; - } + int err=dev_alloc_name(&dev_tunnel, "tunl%d"); + if(err<0) + return err; #ifdef TUNNEL_DEBUG printk("tunnel: registering device %s\n", dev_tunnel.name); diff -u --recursive --new-file v2.1.30/linux/drivers/net/wavelan.c linux/drivers/net/wavelan.c --- v2.1.30/linux/drivers/net/wavelan.c Mon Mar 17 14:54:26 1997 +++ linux/drivers/net/wavelan.c Mon Mar 31 12:52:31 1997 @@ -2354,6 +2354,7 @@ netif_rx(skb); lp->stats.rx_packets++; + lp->stats.rx_bytes+=sksize; #ifdef DEBUG_RX_TRACE printk(KERN_DEBUG "%s: <-wv_packet_read()\n", dev->name); diff -u --recursive --new-file v2.1.30/linux/drivers/net/x25_asy.c linux/drivers/net/x25_asy.c --- v2.1.30/linux/drivers/net/x25_asy.c Wed Dec 31 16:00:00 1969 +++ linux/drivers/net/x25_asy.c Mon Mar 31 12:52:31 1997 @@ -0,0 +1,940 @@ +/* + * Things to sort out: + * + * o tbusy handling + * o allow users to set the parameters + * o sync/async switching ? + */ + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "x25_asy.h" + +typedef struct x25_ctrl { + char if_name[8]; /* "xasy0\0" .. "xasy99999\0" */ + struct x25_asy ctrl; /* X.25 things */ + struct device dev; /* the device */ +} x25_asy_ctrl_t; + +static x25_asy_ctrl_t **x25_asy_ctrls = NULL; + +int x25_asy_maxdev = SL_NRUNIT; /* Can be overridden with insmod! */ +MODULE_PARM(x25_asy_maxdev, "i"); + +static struct tty_ldisc x25_ldisc; + +static int x25_asy_esc(unsigned char *p, unsigned char *d, int len); +static void x25_asy_unesc(struct x25_asy *sl, unsigned char c); + +/* Find a free X.25 channel, and link in this `tty' line. */ +static inline struct x25_asy *x25_asy_alloc(void) +{ + x25_asy_ctrl_t *slp = NULL; + int i; + + if (x25_asy_ctrls == NULL) + return NULL; /* Master array missing ! */ + + for (i = 0; i < x25_asy_maxdev; i++) + { + slp = x25_asy_ctrls[i]; + /* Not allocated ? */ + if (slp == NULL) + break; + /* Not in use ? */ + if (!set_bit(SLF_INUSE, &slp->ctrl.flags)) + break; + } + /* SLP is set.. */ + + /* Sorry, too many, all slots in use */ + if (i >= x25_asy_maxdev) + return NULL; + + /* If no channels are available, allocate one */ + if (!slp && + (x25_asy_ctrls[i] = (x25_asy_ctrl_t *)kmalloc(sizeof(x25_asy_ctrl_t), + GFP_KERNEL)) != NULL) { + slp = x25_asy_ctrls[i]; + memset(slp, 0, sizeof(x25_asy_ctrl_t)); + + /* Initialize channel control data */ + set_bit(SLF_INUSE, &slp->ctrl.flags); + slp->ctrl.tty = NULL; + sprintf(slp->if_name, "x25asy%d", i); + slp->dev.name = slp->if_name; + slp->dev.base_addr = i; + slp->dev.priv = (void*)&(slp->ctrl); + slp->dev.next = NULL; + slp->dev.init = x25_asy_init; + } + if (slp != NULL) + { + + /* register device so that it can be ifconfig'ed */ + /* x25_asy_init() will be called as a side-effect */ + /* SIDE-EFFECT WARNING: x25_asy_init() CLEARS slp->ctrl ! */ + + if (register_netdev(&(slp->dev)) == 0) + { + /* (Re-)Set the INUSE bit. Very Important! */ + set_bit(SLF_INUSE, &slp->ctrl.flags); + slp->ctrl.dev = &(slp->dev); + slp->dev.priv = (void*)&(slp->ctrl); + return (&(slp->ctrl)); + } + else + { + clear_bit(SLF_INUSE,&(slp->ctrl.flags)); + printk("x25_asy_alloc() - register_netdev() failure.\n"); + } + } + return NULL; +} + + +/* Free an X.25 channel. */ + +static inline void x25_asy_free(struct x25_asy *sl) +{ + /* Free all X.25 frame buffers. */ + if (sl->rbuff) { + kfree(sl->rbuff); + } + sl->rbuff = NULL; + if (sl->xbuff) { + kfree(sl->xbuff); + } + sl->xbuff = NULL; + + if (!clear_bit(SLF_INUSE, &sl->flags)) { + printk("%s: x25_asy_free for already free unit.\n", sl->dev->name); + } +} + +/* MTU has been changed by the IP layer. Unfortunately we are not told + about this, but we spot it ourselves and fix things up. We could be + in an upcall from the tty driver, or in an ip packet queue. */ + +static void x25_asy_changed_mtu(struct x25_asy *sl) +{ + struct device *dev = sl->dev; + unsigned char *xbuff, *rbuff, *oxbuff, *orbuff; + int len; + unsigned long flags; + + len = dev->mtu * 2; + + xbuff = (unsigned char *) kmalloc (len + 4, GFP_ATOMIC); + rbuff = (unsigned char *) kmalloc (len + 4, GFP_ATOMIC); + + if (xbuff == NULL || rbuff == NULL) + { + printk("%s: unable to grow X.25 buffers, MTU change cancelled.\n", + sl->dev->name); + dev->mtu = sl->mtu; + if (xbuff != NULL) + kfree(xbuff); + if (rbuff != NULL) + kfree(rbuff); + return; + } + + save_flags(flags); + cli(); + + oxbuff = sl->xbuff; + sl->xbuff = xbuff; + orbuff = sl->rbuff; + sl->rbuff = rbuff; + + if (sl->xleft) { + if (sl->xleft <= len) { + memcpy(sl->xbuff, sl->xhead, sl->xleft); + } else { + sl->xleft = 0; + sl->tx_dropped++; + } + } + sl->xhead = sl->xbuff; + + if (sl->rcount) { + if (sl->rcount <= len) { + memcpy(sl->rbuff, orbuff, sl->rcount); + } else { + sl->rcount = 0; + sl->rx_over_errors++; + set_bit(SLF_ERROR, &sl->flags); + } + } + sl->mtu = dev->mtu; + + sl->buffsize = len; + + restore_flags(flags); + + if (oxbuff != NULL) + kfree(oxbuff); + if (orbuff != NULL) + kfree(orbuff); +} + + +/* Set the "sending" flag. This must be atomic, hence the ASM. */ + +static inline void x25_asy_lock(struct x25_asy *sl) +{ + if (set_bit(0, (void *) &sl->dev->tbusy)) + printk("%s: trying to lock already locked device!\n", sl->dev->name); +} + + +/* Clear the "sending" flag. This must be atomic, hence the ASM. */ + +static inline void x25_asy_unlock(struct x25_asy *sl) +{ + if (!clear_bit(0, (void *)&sl->dev->tbusy)) + printk("%s: trying to unlock already unlocked device!\n", sl->dev->name); +} + +/* Send one completely decapsulated IP datagram to the IP layer. */ + +static void x25_asy_bump(struct x25_asy *sl) +{ + struct sk_buff *skb; + int count; + int err; + + count = sl->rcount; + sl->rx_bytes+=count; + + skb = dev_alloc_skb(count+1); + if (skb == NULL) + { + printk("%s: memory squeeze, dropping packet.\n", sl->dev->name); + sl->rx_dropped++; + return; + } + skb_push(skb,1); /* LAPB internal control */ + skb->dev = sl->dev; + memcpy(skb_put(skb,count), sl->rbuff, count); + skb->mac.raw=skb->data; + skb->protocol=htons(ETH_P_X25); + if((err=lapb_data_received(sl,skb))!=LAPB_OK) + { + kfree_skb(skb, FREE_READ); + printk(KERN_DEBUG "x25_asy: data received err - %d\n",err); + } + else + { + netif_rx(skb); + sl->rx_packets++; + } +} + +/* Encapsulate one IP datagram and stuff into a TTY queue. */ +static void x25_asy_encaps(struct x25_asy *sl, unsigned char *icp, int len) +{ + unsigned char *p; + int actual, count; + + + if (sl->mtu != sl->dev->mtu) { /* Someone has been ifconfigging */ + + x25_asy_changed_mtu(sl); + } + + if (len > sl->mtu) + { /* Sigh, shouldn't occur BUT ... */ + len = sl->mtu; + printk ("%s: truncating oversized transmit packet!\n", sl->dev->name); + sl->tx_dropped++; + x25_asy_unlock(sl); + return; + } + + p = icp; + count = x25_asy_esc(p, (unsigned char *) sl->xbuff, len); + + /* Order of next two lines is *very* important. + * When we are sending a little amount of data, + * the transfer may be completed inside driver.write() + * routine, because it's running with interrupts enabled. + * In this case we *never* got WRITE_WAKEUP event, + * if we did not request it before write operation. + * 14 Oct 1994 Dmitry Gorodchanin. + */ + sl->tty->flags |= (1 << TTY_DO_WRITE_WAKEUP); + actual = sl->tty->driver.write(sl->tty, 0, sl->xbuff, count); + sl->xleft = count - actual; + sl->xhead = sl->xbuff + actual; + /* VSV */ + clear_bit(SLF_OUTWAIT, &sl->flags); /* reset outfill flag */ +} + +/* + * Called by the driver when there's room for more data. If we have + * more packets to send, we send them here. + */ +static void x25_asy_write_wakeup(struct tty_struct *tty) +{ + int actual; + struct x25_asy *sl = (struct x25_asy *) tty->disc_data; + + /* First make sure we're connected. */ + if (!sl || sl->magic != X25_ASY_MAGIC || !sl->dev->start) + return; + + if (sl->xleft <= 0) + { + /* Now serial buffer is almost free & we can start + * transmission of another packet */ + sl->tx_packets++; + tty->flags &= ~(1 << TTY_DO_WRITE_WAKEUP); + x25_asy_unlock(sl); + mark_bh(NET_BH); + return; + } + + actual = tty->driver.write(tty, 0, sl->xhead, sl->xleft); + sl->xleft -= actual; + sl->xhead += actual; +} + +/* Encapsulate an IP datagram and kick it into a TTY queue. */ + +static int x25_asy_xmit(struct sk_buff *skb, struct device *dev) +{ + struct x25_asy *sl = (struct x25_asy*)(dev->priv); + int err; + + if (!dev->start) + { + printk("%s: xmit call when iface is down\n", dev->name); + return 1; + } + + switch(skb->data[0]) + { + case 0x00:break; + case 0x01: /* Connection request .. do nothing */ + if((err=lapb_connect_request(sl))!=LAPB_OK) + printk(KERN_ERR "x25_asy: lapb_connect_request error - %d\n", err); + kfree_skb(skb, FREE_WRITE); + return 0; + case 0x02: /* Disconnect request .. do nothing - hang up ?? */ + if((err=lapb_disconnect_request(sl))!=LAPB_OK) + printk(KERN_ERR "x25_asy: lapb_disconnect_request error - %d\n", err); + default: + kfree_skb(skb, FREE_WRITE); + return 0; + } + skb_pull(skb,1); /* Remove control byte */ + /* + * If we are busy already- too bad. We ought to be able + * to queue things at this point, to allow for a little + * frame buffer. Oh well... + * ----------------------------------------------------- + * I hate queues in X.25 driver. May be it's efficient, + * but for me latency is more important. ;) + * So, no queues ! + * 14 Oct 1994 Dmitry Gorodchanin. + */ + if (dev->tbusy) { + /* May be we must check transmitter timeout here ? + * 14 Oct 1994 Dmitry Gorodchanin. + */ +#ifdef SL_CHECK_TRANSMIT + if (jiffies - dev->trans_start < 20 * HZ) { + /* 20 sec timeout not reached */ + return 1; + } + printk("%s: transmit timed out, %s?\n", dev->name, + (sl->tty->driver.chars_in_buffer(sl->tty) || sl->xleft) ? + "bad line quality" : "driver error"); + sl->xleft = 0; + sl->tty->flags &= ~(1 << TTY_DO_WRITE_WAKEUP); + x25_asy_unlock(sl); +#else + return 1; +#endif + } + + if((err=lapb_data_request(sl,skb))!=LAPB_OK) + { + printk(KERN_ERR "lapbeth: lapb_data_request error - %d\n", err); + kfree_skb(skb, FREE_WRITE); + return 0; + } + return 0; +} + + +/* + * LAPB interface boilerplate + */ + +/* + * Called when I frame data arrives. We did the work above - throw it + * at the net layer. + */ + +static void x25_asy_data_indication(void *token, struct sk_buff *skb) +{ + netif_rx(skb); +} + +/* + * Data has emerged from the LAPB protocol machine. We don't handle + * busy cases too well. Its tricky to see how to do this nicely - + * perhaps lapb should allow us to bounce this ? + */ + +static void x25_asy_data_transmit(void *token, struct sk_buff *skb) +{ + struct x25_asy *sl=token; + if(sl->dev->tbusy) + { + printk(KERN_ERR "x25_asy: tbusy drop\n"); + kfree_skb(skb, FREE_WRITE); + return; + } + /* We were not busy, so we are now... :-) */ + if (skb != NULL) + { + x25_asy_lock(sl); + sl->tx_bytes+=skb->len; + x25_asy_encaps(sl, skb->data, skb->len); + dev_kfree_skb(skb, FREE_WRITE); + } +} + +/* + * LAPB connection establish/down information. + */ + +static void x25_asy_connected(void *token, int reason) +{ + struct x25_asy *sl = token; + struct sk_buff *skb; + unsigned char *ptr; + + if ((skb = dev_alloc_skb(1)) == NULL) { + printk(KERN_ERR "lapbeth: out of memory\n"); + return; + } + + ptr = skb_put(skb, 1); + *ptr = 0x01; + + skb->dev = sl->dev; + skb->protocol = htons(ETH_P_X25); + skb->mac.raw = skb->data; + skb->pkt_type = PACKET_HOST; + + netif_rx(skb); +} + +static void x25_asy_disconnected(void *token, int reason) +{ + struct x25_asy *sl = token; + struct sk_buff *skb; + unsigned char *ptr; + + if ((skb = dev_alloc_skb(1)) == NULL) { + printk(KERN_ERR "x25_asy: out of memory\n"); + return; + } + + ptr = skb_put(skb, 1); + *ptr = 0x02; + + skb->dev = sl->dev; + skb->protocol = htons(ETH_P_X25); + skb->mac.raw = skb->data; + skb->pkt_type = PACKET_HOST; + + netif_rx(skb); +} + + +/* Open the low-level part of the X.25 channel. Easy! */ + +static int x25_asy_open(struct device *dev) +{ + struct lapb_register_struct x25_asy_callbacks; + struct x25_asy *sl = (struct x25_asy*)(dev->priv); + unsigned long len; + int err; + + if (sl->tty == NULL) + return -ENODEV; + + /* + * Allocate the X.25 frame buffers: + * + * rbuff Receive buffer. + * xbuff Transmit buffer. + */ + + len = dev->mtu * 2; + + sl->rbuff = (unsigned char *) kmalloc(len + 4, GFP_KERNEL); + if (sl->rbuff == NULL) { + goto norbuff; + } + sl->xbuff = (unsigned char *) kmalloc(len + 4, GFP_KERNEL); + if (sl->xbuff == NULL) { + goto noxbuff; + } + sl->mtu = dev->mtu; + sl->buffsize = len; + sl->rcount = 0; + sl->xleft = 0; + sl->flags &= (1 << SLF_INUSE); /* Clear ESCAPE & ERROR flags */ + + dev->tbusy = 0; +/* dev->flags |= IFF_UP; */ + dev->start = 1; + + /* + * Now attach LAPB + */ + + x25_asy_callbacks.connect_confirmation=x25_asy_connected; + x25_asy_callbacks.connect_indication=x25_asy_connected; + x25_asy_callbacks.disconnect_confirmation=x25_asy_disconnected; + x25_asy_callbacks.disconnect_indication=x25_asy_disconnected; + x25_asy_callbacks.data_indication=x25_asy_data_indication; + x25_asy_callbacks.data_transmit=x25_asy_data_transmit; + + if((err=lapb_register(sl, &x25_asy_callbacks))==LAPB_OK) + return 0; + + /* Cleanup */ + kfree(sl->xbuff); +noxbuff: + kfree(sl->rbuff); +norbuff: + return -ENOMEM; +} + + +/* Close the low-level part of the X.25 channel. Easy! */ +static int x25_asy_close(struct device *dev) +{ + struct x25_asy *sl = (struct x25_asy*)(dev->priv); + int err; + + if (sl->tty == NULL) + return -EBUSY; + + sl->tty->flags &= ~(1 << TTY_DO_WRITE_WAKEUP); + dev->tbusy = 1; + dev->start = 0; + if((err=lapb_unregister(sl))!=LAPB_OK) + printk(KERN_ERR "x25_asy_close: lapb_unregister error -%d\n",err); + +/* dev->flags &= ~IFF_UP; */ + return 0; +} + +static int x25_asy_receive_room(struct tty_struct *tty) +{ + return 65536; /* We can handle an infinite amount of data. :-) */ +} + +/* + * Handle the 'receiver data ready' interrupt. + * This function is called by the 'tty_io' module in the kernel when + * a block of X.25 data has been received, which can now be decapsulated + * and sent on to some IP layer for further processing. + */ + +static void x25_asy_receive_buf(struct tty_struct *tty, const unsigned char *cp, char *fp, int count) +{ + struct x25_asy *sl = (struct x25_asy *) tty->disc_data; + + if (!sl || sl->magic != X25_ASY_MAGIC || !sl->dev->start) + return; + + /* + * Argh! mtu change time! - costs us the packet part received + * at the change + */ + if (sl->mtu != sl->dev->mtu) { + + x25_asy_changed_mtu(sl); + } + + /* Read the characters out of the buffer */ + while (count--) { + if (fp && *fp++) { + if (!set_bit(SLF_ERROR, &sl->flags)) { + sl->rx_errors++; + } + cp++; + continue; + } + x25_asy_unesc(sl, *cp++); + } +} + +/* + * Open the high-level part of the X.25 channel. + * This function is called by the TTY module when the + * X.25 line discipline is called for. Because we are + * sure the tty line exists, we only have to link it to + * a free X.25 channel... + */ + +static int x25_asy_open_tty(struct tty_struct *tty) +{ + struct x25_asy *sl = (struct x25_asy *) tty->disc_data; + int err; + + /* First make sure we're not already connected. */ + if (sl && sl->magic == X25_ASY_MAGIC) { + return -EEXIST; + } + + /* OK. Find a free X.25 channel to use. */ + if ((sl = x25_asy_alloc()) == NULL) { + return -ENFILE; + } + + sl->tty = tty; + tty->disc_data = sl; + if (tty->driver.flush_buffer) { + tty->driver.flush_buffer(tty); + } + if (tty->ldisc.flush_buffer) { + tty->ldisc.flush_buffer(tty); + } + + /* Restore default settings */ + sl->dev->type = ARPHRD_X25; + + /* Perform the low-level X.25 async init */ + if ((err = x25_asy_open(sl->dev))) + return err; + + MOD_INC_USE_COUNT; + + /* Done. We have linked the TTY line to a channel. */ + return sl->dev->base_addr; +} + + +/* + * Close down an X.25 channel. + * This means flushing out any pending queues, and then restoring the + * TTY line discipline to what it was before it got hooked to X.25 + * (which usually is TTY again). + */ +static void x25_asy_close_tty(struct tty_struct *tty) +{ + struct x25_asy *sl = (struct x25_asy *) tty->disc_data; + + /* First make sure we're connected. */ + if (!sl || sl->magic != X25_ASY_MAGIC) + return; + + (void) dev_close(sl->dev); + + tty->disc_data = 0; + sl->tty = NULL; + x25_asy_free(sl); + unregister_netdev(sl->dev); + MOD_DEC_USE_COUNT; +} + + +static struct net_device_stats *x25_asy_get_stats(struct device *dev) +{ + static struct net_device_stats stats; + struct x25_asy *sl = (struct x25_asy*)(dev->priv); + + memset(&stats, 0, sizeof(struct net_device_stats)); + + stats.rx_packets = sl->rx_packets; + stats.tx_packets = sl->tx_packets; + stats.rx_bytes = sl->rx_bytes; + stats.tx_bytes = sl->tx_bytes; + stats.rx_dropped = sl->rx_dropped; + stats.tx_dropped = sl->tx_dropped; + stats.tx_errors = sl->tx_errors; + stats.rx_errors = sl->rx_errors; + stats.rx_over_errors = sl->rx_over_errors; + return (&stats); +} + + + /************************************************************************ + * STANDARD X.25 ENCAPSULATION * + ************************************************************************/ + +int x25_asy_esc(unsigned char *s, unsigned char *d, int len) +{ + unsigned char *ptr = d; + unsigned char c; + + /* + * Send an initial END character to flush out any + * data that may have accumulated in the receiver + * due to line noise. + */ + + *ptr++ = X25_END; /* Send 10111110 bit seq */ + + /* + * For each byte in the packet, send the appropriate + * character sequence, according to the X.25 protocol. + */ + + while (len-- > 0) + { + switch(c = *s++) + { + case X25_END: + *ptr++ = X25_ESC; + *ptr++ = X25_ESCAPE(X25_END); + break; + case X25_ESC: + *ptr++ = X25_ESC; + *ptr++ = X25_ESCAPE(X25_ESC); + break; + default: + *ptr++ = c; + break; + } + } + *ptr++ = X25_END; + return (ptr - d); +} + +static void x25_asy_unesc(struct x25_asy *sl, unsigned char s) +{ + + switch(s) + { + case X25_END: + if (!clear_bit(SLF_ERROR, &sl->flags) && (sl->rcount > 2)) + { + x25_asy_bump(sl); + } + clear_bit(SLF_ESCAPE, &sl->flags); + sl->rcount = 0; + return; + + case X25_ESC: + set_bit(SLF_ESCAPE, &sl->flags); + return; + + case X25_ESCAPE(X25_ESC): + case X25_ESCAPE(X25_END): + if (clear_bit(SLF_ESCAPE, &sl->flags)) + s = X25_UNESCAPE(s); + break; + } + if (!test_bit(SLF_ERROR, &sl->flags)) + { + if (sl->rcount < sl->buffsize) + { + sl->rbuff[sl->rcount++] = s; + return; + } + sl->rx_over_errors++; + set_bit(SLF_ERROR, &sl->flags); + } +} + + +/* Perform I/O control on an active X.25 channel. */ +static int x25_asy_ioctl(struct tty_struct *tty, void *file, int cmd, void *arg) +{ + struct x25_asy *sl = (struct x25_asy *) tty->disc_data; + + /* First make sure we're connected. */ + if (!sl || sl->magic != X25_ASY_MAGIC) { + return -EINVAL; + } + + switch(cmd) + { + case SIOCGIFNAME: + if(copy_to_user(arg, sl->dev->name, strlen(sl->dev->name) + 1)) + return -EFAULT; + return 0; + + case SIOCSIFHWADDR: + return -EINVAL; + + /* Allow stty to read, but not set, the serial port */ + case TCGETS: + case TCGETA: + return n_tty_ioctl(tty, (struct file *) file, cmd, (unsigned long) arg); + + default: + return -ENOIOCTLCMD; + } +} + +static int x25_asy_open_dev(struct device *dev) +{ + struct x25_asy *sl = (struct x25_asy*)(dev->priv); + if(sl->tty==NULL) + return -ENODEV; + return 0; +} + +/* Initialize X.25 control device -- register X.25 line discipline */ +#ifdef MODULE +static int x25_asy_init_ctrl_dev(void) +#else /* !MODULE */ +int x25_asy_init_ctrl_dev(struct device *dummy) +#endif /* !MODULE */ +{ + int status; + + if (x25_asy_maxdev < 4) x25_asy_maxdev = 4; /* Sanity */ + + printk(KERN_INFO "X.25 async: version 0.00 ALPHA (dynamic channels, max=%d).\n", + x25_asy_maxdev ); + x25_asy_ctrls = (x25_asy_ctrl_t **) kmalloc(sizeof(void*)*x25_asy_maxdev, GFP_KERNEL); + if (x25_asy_ctrls == NULL) + { + printk("X25 async: Can't allocate x25_asy_ctrls[] array! Uaargh! (-> No X.25 available)\n"); + return -ENOMEM; + } + + /* Clear the pointer array, we allocate devices when we need them */ + memset(x25_asy_ctrls, 0, sizeof(void*)*x25_asy_maxdev); /* Pointers */ + + /* Fill in our line protocol discipline, and register it */ + memset(&x25_ldisc, 0, sizeof(x25_ldisc)); + x25_ldisc.magic = TTY_LDISC_MAGIC; + x25_ldisc.name = "X.25"; + x25_ldisc.flags = 0; + x25_ldisc.open = x25_asy_open_tty; + x25_ldisc.close = x25_asy_close_tty; + x25_ldisc.read = NULL; + x25_ldisc.write = NULL; + x25_ldisc.ioctl = (int (*)(struct tty_struct *, struct file *, + unsigned int, unsigned long)) x25_asy_ioctl; + x25_ldisc.poll = NULL; + x25_ldisc.receive_buf = x25_asy_receive_buf; + x25_ldisc.receive_room = x25_asy_receive_room; + x25_ldisc.write_wakeup = x25_asy_write_wakeup; + if ((status = tty_register_ldisc(N_X25, &x25_ldisc)) != 0) { + printk("X.25 async: can't register line discipline (err = %d)\n", status); + } + +#ifdef MODULE + return status; +#else + /* Return "not found", so that dev_init() will unlink + * the placeholder device entry for us. + */ + return ENODEV; +#endif + } + + +/* Initialise the X.25 driver. Called by the device init code */ + +int x25_asy_init(struct device *dev) +{ + struct x25_asy *sl = (struct x25_asy*)(dev->priv); + + if (sl == NULL) /* Allocation failed ?? */ + return -ENODEV; + + /* Set up the control block. (And clear statistics) */ + + memset(sl, 0, sizeof (struct x25_asy)); + sl->magic = X25_ASY_MAGIC; + sl->dev = dev; + + /* + * Finish setting up the DEVICE info. + */ + + dev->mtu = SL_MTU; + dev->hard_start_xmit = x25_asy_xmit; + dev->open = x25_asy_open_dev; + dev->stop = x25_asy_close; + dev->get_stats = x25_asy_get_stats; + dev->hard_header_len = 0; + dev->addr_len = 0; + dev->type = ARPHRD_X25; + dev->tx_queue_len = 10; + + dev_init_buffers(dev); + + /* New-style flags. */ + dev->flags = IFF_NOARP; + dev->family = AF_X25; + dev->pa_addr = 0; + dev->pa_brdaddr = 0; + dev->pa_mask = 0; + dev->pa_alen = 4; + + return 0; +} +#ifdef MODULE + +int +init_module(void) +{ + return x25_asy_init_ctrl_dev(); +} + +void +cleanup_module(void) +{ + int i; + + if (x25_asy_ctrls != NULL) + { + for (i = 0; i < x25_asy_maxdev; i++) + { + if (x25_asy_ctrls[i]) + { + /* + * VSV = if dev->start==0, then device + * unregistered while close proc. + */ + if (x25_asy_ctrls[i]->dev.start) + unregister_netdev(&(x25_asy_ctrls[i]->dev)); + + kfree(x25_asy_ctrls[i]); + x25_asy_ctrls[i] = NULL; + } + } + kfree(x25_asy_ctrls); + x25_asy_ctrls = NULL; + } + if ((i = tty_register_ldisc(N_X25, NULL))) + { + printk("X.25 async: can't unregister line discipline (err = %d)\n", i); + } +} +#endif /* MODULE */ + diff -u --recursive --new-file v2.1.30/linux/drivers/net/x25_asy.h linux/drivers/net/x25_asy.h --- v2.1.30/linux/drivers/net/x25_asy.h Wed Dec 31 16:00:00 1969 +++ linux/drivers/net/x25_asy.h Mon Mar 31 12:52:31 1997 @@ -0,0 +1,58 @@ +#ifndef _LINUX_X25_ASY_H +#define _LINUX_X25_ASY_H + +/* X.25 asy configuration. */ +#define SL_NRUNIT 256 /* MAX number of X.25 channels; + This can be overridden with + insmod -ox25_asy_maxdev=nnn */ +#define SL_MTU 256 + +/* X25 async protocol characters. */ +#define X25_END 0x7E /* indicates end of frame */ +#define X25_ESC 0x7D /* indicates byte stuffing */ +#define X25_ESCAPE(x) ((x)^0x20) +#define X25_UNESCAPE(x) ((x)^0x20) + + +struct x25_asy { + int magic; + + /* Various fields. */ + struct tty_struct *tty; /* ptr to TTY structure */ + struct device *dev; /* easy for intr handling */ + + /* These are pointers to the malloc()ed frame buffers. */ + unsigned char *rbuff; /* receiver buffer */ + int rcount; /* received chars counter */ + unsigned char *xbuff; /* transmitter buffer */ + unsigned char *xhead; /* pointer to next byte to XMIT */ + int xleft; /* bytes left in XMIT queue */ + + /* X.25 interface statistics. */ + unsigned long rx_packets; /* inbound frames counter */ + unsigned long tx_packets; /* outbound frames counter */ + unsigned long rx_bytes; /* inbound byte counte */ + unsigned long tx_bytes; /* outbound byte counter */ + unsigned long rx_errors; /* Parity, etc. errors */ + unsigned long tx_errors; /* Planned stuff */ + unsigned long rx_dropped; /* No memory for skb */ + unsigned long tx_dropped; /* When MTU change */ + unsigned long rx_over_errors; /* Frame bigger then X.25 buf. */ + + int mtu; /* Our mtu (to spot changes!) */ + int buffsize; /* Max buffers sizes */ + + unsigned int flags; /* Flag values/ mode etc */ +#define SLF_INUSE 0 /* Channel in use */ +#define SLF_ESCAPE 1 /* ESC received */ +#define SLF_ERROR 2 /* Parity, etc. error */ +#define SLF_OUTWAIT 4 /* Waiting for output */ +}; + + + +#define X25_ASY_MAGIC 0x5303 + +extern int x25_asy_init(struct device *dev); + +#endif /* _LINUX_X25_ASY.H */ diff -u --recursive --new-file v2.1.30/linux/drivers/pci/pci.c linux/drivers/pci/pci.c --- v2.1.30/linux/drivers/pci/pci.c Mon Mar 17 14:54:27 1997 +++ linux/drivers/pci/pci.c Mon Mar 31 12:52:31 1997 @@ -94,7 +94,8 @@ DEVICE( TRIDENT, TRIDENT_9660, "TG 9660"), DEVICE( AI, AI_M1435, "M1435"), DEVICE( MATROX, MATROX_MGA_2, "Atlas PX2085"), - DEVICE( MATROX, MATROX_MIL ,"Millennium"), + DEVICE( MATROX, MATROX_MIL, "Millennium"), + DEVICE( MATROX, MATROX_MYS, "Mystique"), DEVICE( MATROX, MATROX_MGA_IMP, "MGA Impression"), DEVICE( CT, CT_65545, "65545"), DEVICE( CT, CT_65548, "65548"), diff -u --recursive --new-file v2.1.30/linux/drivers/sbus/char/openprom.c linux/drivers/sbus/char/openprom.c --- v2.1.30/linux/drivers/sbus/char/openprom.c Mon Mar 17 14:54:28 1997 +++ linux/drivers/sbus/char/openprom.c Wed Apr 2 17:43:21 1997 @@ -549,10 +549,11 @@ return 0; } -static void openprom_release(struct inode * inode, struct file * file) +static int openprom_release(struct inode * inode, struct file * file) { kfree_s(file->private_data, sizeof(DATA)); MOD_DEC_USE_COUNT; + return 0; } static struct file_operations openprom_fops = { diff -u --recursive --new-file v2.1.30/linux/drivers/sbus/char/rtc.c linux/drivers/sbus/char/rtc.c --- v2.1.30/linux/drivers/sbus/char/rtc.c Sun Jan 26 02:07:18 1997 +++ linux/drivers/sbus/char/rtc.c Wed Apr 2 17:43:21 1997 @@ -118,10 +118,11 @@ return 0; } -static void rtc_release(struct inode *inode, struct file *file) +static int rtc_release(struct inode *inode, struct file *file) { MOD_DEC_USE_COUNT; rtc_busy = 0; + return 0; } static struct file_operations rtc_fops = { diff -u --recursive --new-file v2.1.30/linux/drivers/sbus/char/sunfb.c linux/drivers/sbus/char/sunfb.c --- v2.1.30/linux/drivers/sbus/char/sunfb.c Thu Mar 27 14:40:05 1997 +++ linux/drivers/sbus/char/sunfb.c Wed Apr 2 17:43:21 1997 @@ -301,7 +301,6 @@ fb_ioctl, fb_mmap, fb_open, /* open */ - (void(*)(struct inode *, struct file *)) fb_close, /* close */ }; diff -u --recursive --new-file v2.1.30/linux/drivers/sbus/char/sunkbd.c linux/drivers/sbus/char/sunkbd.c --- v2.1.30/linux/drivers/sbus/char/sunkbd.c Thu Mar 27 14:40:05 1997 +++ linux/drivers/sbus/char/sunkbd.c Wed Apr 2 17:43:21 1997 @@ -66,6 +66,13 @@ unsigned char kbd_read_mask = 0x01; /* modified by psaux.c */ unsigned char aux_device_present = 0x00; /* To make kernel/ksyms.c happy */ +struct wait_queue * keypress_wait = NULL; + +void keyboard_wait_for_keypress(void) +{ + sleep_on(&keypress_wait); +} + /* * global state includes the following, and various static variables * in this module: prev_scancode, shift_state, diacr, npadch, dead_key_next. @@ -1382,7 +1389,7 @@ return 0; } -static void +static int kbd_close (struct inode *i, struct file *f) { if (--kbd_active) @@ -1395,6 +1402,7 @@ kbd_opened = 0; kbd_fasync (i, f, 0); + return 0; } static struct diff -u --recursive --new-file v2.1.30/linux/drivers/sbus/char/sunmouse.c linux/drivers/sbus/char/sunmouse.c --- v2.1.30/linux/drivers/sbus/char/sunmouse.c Mon Mar 17 14:54:28 1997 +++ linux/drivers/sbus/char/sunmouse.c Wed Apr 2 17:43:21 1997 @@ -337,13 +337,14 @@ return 0; } -static void +static int sun_mouse_close(struct inode *inode, struct file *file) { sun_mouse_fasync (inode, file, 0); if (--sunmouse.active) - return; + return 0; sunmouse.ready = 0; + return 0; } static long diff -u --recursive --new-file v2.1.30/linux/drivers/scsi/BusLogic.c linux/drivers/scsi/BusLogic.c --- v2.1.30/linux/drivers/scsi/BusLogic.c Thu Mar 27 14:40:05 1997 +++ linux/drivers/scsi/BusLogic.c Sat Mar 29 09:01:00 1997 @@ -27,8 +27,8 @@ */ -#define BusLogic_DriverVersion "2.0.8" -#define BusLogic_DriverDate "17 March 1997" +#define BusLogic_DriverVersion "2.0.9" +#define BusLogic_DriverDate "29 March 1997" #include @@ -295,15 +295,16 @@ CCB->NextAll = HostAdapter->All_CCBs; HostAdapter->Free_CCBs = CCB; HostAdapter->All_CCBs = CCB; + HostAdapter->AllocatedCCBs++; return true; } /* - BusLogic_CreateCCBs allocates the initial CCBs for Host Adapter. + BusLogic_CreateInitialCCBs allocates the initial CCBs for Host Adapter. */ -static boolean BusLogic_CreateCCBs(BusLogic_HostAdapter_T *HostAdapter) +static boolean BusLogic_CreateInitialCCBs(BusLogic_HostAdapter_T *HostAdapter) { int Allocated; for (Allocated = 0; Allocated < HostAdapter->InitialCCBs; Allocated++) @@ -335,6 +336,32 @@ /* + BusLogic_CreateAdditionalCCBs allocates Additional CCBs for Host Adapter. If + allocation fails and there are no remaining CCBs available, the Driver Queue + Depth is decreased to a known safe value to avoid potential deadlocks when + multiple host adapters share the same IRQ Channel. +*/ + +static void BusLogic_CreateAdditionalCCBs(BusLogic_HostAdapter_T *HostAdapter, + int AdditionalCCBs, + boolean SuccessMessageP) +{ + int Allocated; + if (AdditionalCCBs <= 0) return; + for (Allocated = 0; Allocated < AdditionalCCBs; Allocated++) + if (!BusLogic_CreateCCB(HostAdapter)) break; + if (Allocated > 0 && SuccessMessageP) + BusLogic_Notice("Allocated %d additional CCBs (total now %d)\n", + HostAdapter, Allocated, HostAdapter->AllocatedCCBs); + if (Allocated > 0) return; + BusLogic_Notice("Failed to allocate additional CCBs\n", HostAdapter); + HostAdapter->DriverQueueDepth = + HostAdapter->AllocatedCCBs - (HostAdapter->MaxTargetDevices - 1); + HostAdapter->SCSI_Host->can_queue = HostAdapter->DriverQueueDepth; +} + + +/* BusLogic_AllocateCCB allocates a CCB from Host Adapter's free list, allocating more memory from the Kernel if necessary. The Host Adapter's Lock should already have been acquired by the caller. @@ -345,24 +372,23 @@ { static unsigned long SerialNumber = 0; BusLogic_CCB_T *CCB; - int Allocated; CCB = HostAdapter->Free_CCBs; if (CCB != NULL) { CCB->SerialNumber = ++SerialNumber; HostAdapter->Free_CCBs = CCB->Next; CCB->Next = NULL; + if (HostAdapter->Free_CCBs == NULL) + BusLogic_CreateAdditionalCCBs(HostAdapter, + HostAdapter->IncrementalCCBs, + true); return CCB; } - for (Allocated = 0; Allocated < HostAdapter->IncrementalCCBs; Allocated++) - if (!BusLogic_CreateCCB(HostAdapter)) break; + BusLogic_CreateAdditionalCCBs(HostAdapter, + HostAdapter->IncrementalCCBs, + true); CCB = HostAdapter->Free_CCBs; - if (CCB == NULL) - { - BusLogic_Notice("Failed to allocate additional CCBs\n", HostAdapter); - return NULL; - } - BusLogic_Notice("Allocated %d additional CCBs\n", HostAdapter, Allocated); + if (CCB == NULL) return NULL; CCB->SerialNumber = ++SerialNumber; HostAdapter->Free_CCBs = CCB->Next; CCB->Next = NULL; @@ -1514,7 +1540,7 @@ HostAdapter->MaxTargetDevices = (HostAdapter->HostWideSCSI ? 16 : 8); HostAdapter->MaxLogicalUnits = 32; HostAdapter->InitialCCBs = 64; - HostAdapter->IncrementalCCBs = 32; + HostAdapter->IncrementalCCBs = 16; HostAdapter->DriverQueueDepth = 255; HostAdapter->HostAdapterQueueDepth = HostAdapter->DriverQueueDepth; HostAdapter->SynchronousPermitted = FlashPointInfo->SynchronousPermitted; @@ -1833,14 +1859,14 @@ HostAdapter->StrictRoundRobinModeSupport = true; HostAdapter->MailboxCount = 255; HostAdapter->InitialCCBs = 64; - HostAdapter->IncrementalCCBs = 32; + HostAdapter->IncrementalCCBs = 16; } else { HostAdapter->StrictRoundRobinModeSupport = false; HostAdapter->MailboxCount = 32; HostAdapter->InitialCCBs = 32; - HostAdapter->IncrementalCCBs = 4; + HostAdapter->IncrementalCCBs = 8; } HostAdapter->DriverQueueDepth = HostAdapter->MailboxCount; /* @@ -2604,6 +2630,7 @@ int TaggedQueueDepth = HostAdapter->TaggedQueueDepth; int UntaggedQueueDepth = HostAdapter->UntaggedQueueDepth; int TaggedDeviceCount = 0, UntaggedDeviceCount = 0; + int DesiredCCBs = HostAdapter->MaxTargetDevices - 1; SCSI_Device_T *Device; for (Device = DeviceList; Device != NULL; Device = Device->next) if (Device->host == Host) @@ -2630,7 +2657,11 @@ Device->queue_depth = TaggedQueueDepth; else Device->queue_depth = UntaggedQueueDepth; HostAdapter->QueueDepth[Device->id] = Device->queue_depth; + DesiredCCBs += Device->queue_depth; } + BusLogic_CreateAdditionalCCBs(HostAdapter, + DesiredCCBs - HostAdapter->AllocatedCCBs, + false); } @@ -2744,16 +2775,16 @@ /* Read the Host Adapter Configuration, Configure the Host Adapter, Acquire the System Resources necessary to use the Host Adapter, - then Test Interrupts, Create the Mailboxes, CCBs, and Target - Device Statistics, Initialize the Host Adapter, and finally - perform Target Device Inquiry. + then Test Interrupts, Create the Mailboxes, Initial CCBs, and + Target Device Statistics, Initialize the Host Adapter, and + finally perform Target Device Inquiry. */ if (BusLogic_ReadHostAdapterConfiguration(HostAdapter) && BusLogic_ReportHostAdapterConfiguration(HostAdapter) && BusLogic_AcquireResources(HostAdapter) && BusLogic_TestInterrupts(HostAdapter) && BusLogic_CreateMailboxes(HostAdapter) && - BusLogic_CreateCCBs(HostAdapter) && + BusLogic_CreateInitialCCBs(HostAdapter) && BusLogic_CreateTargetDeviceStatistics(HostAdapter) && BusLogic_InitializeHostAdapter(HostAdapter) && BusLogic_TargetDeviceInquiry(HostAdapter)) @@ -4133,6 +4164,11 @@ TargetDeviceStatistics = HostAdapter->TargetDeviceStatistics; Buffer = HostAdapter->MessageBuffer; Length = HostAdapter->MessageBufferLength; + Length += sprintf(&Buffer[Length], "\n\ +Current Driver Queue Depth: %d\n\ +Currently Allocated CCBs: %d\n", + HostAdapter->DriverQueueDepth, + HostAdapter->AllocatedCCBs); Length += sprintf(&Buffer[Length], "\n\n\ DATA TRANSFER STATISTICS\n\ \n\ diff -u --recursive --new-file v2.1.30/linux/drivers/scsi/BusLogic.h linux/drivers/scsi/BusLogic.h --- v2.1.30/linux/drivers/scsi/BusLogic.h Thu Mar 27 14:40:05 1997 +++ linux/drivers/scsi/BusLogic.h Sat Mar 29 09:01:00 1997 @@ -145,7 +145,7 @@ */ #define BusLogic_LineBufferSize 100 -#define BusLogic_MessageBufferSize 8900 +#define BusLogic_MessageBufferSize 9900 /* @@ -1311,6 +1311,7 @@ unsigned short MailboxCount; unsigned short InitialCCBs; unsigned short IncrementalCCBs; + unsigned short AllocatedCCBs; unsigned short DriverQueueDepth; unsigned short HostAdapterQueueDepth; unsigned short TaggedQueueDepth; diff -u --recursive --new-file v2.1.30/linux/drivers/scsi/Config.in linux/drivers/scsi/Config.in --- v2.1.30/linux/drivers/scsi/Config.in Mon Mar 17 14:54:29 1997 +++ linux/drivers/scsi/Config.in Mon Mar 31 13:25:24 1997 @@ -71,7 +71,7 @@ fi fi if [ "$CONFIG_MCA" = "y" ]; then - bool 'IBMMCA SCSI support' CONFIG_SCSI_IBMMCA + dep_tristate 'IBMMCA SCSI support' CONFIG_SCSI_IBMMCA $CONFIG_SCSI fi dep_tristate 'IOMEGA Parallel Port ZIP drive SCSI support' CONFIG_SCSI_PPA $CONFIG_SCSI dep_tristate 'PAS16 SCSI support' CONFIG_SCSI_PAS16 $CONFIG_SCSI diff -u --recursive --new-file v2.1.30/linux/drivers/scsi/README.BusLogic linux/drivers/scsi/README.BusLogic --- v2.1.30/linux/drivers/scsi/README.BusLogic Thu Mar 27 14:40:05 1997 +++ linux/drivers/scsi/README.BusLogic Sat Mar 29 09:01:00 1997 @@ -1,10 +1,10 @@ BusLogic MultiMaster and FlashPoint SCSI Driver for Linux - Version 2.0.8 for Linux 2.0 + Version 2.0.9 for Linux 2.0 PRODUCTION RELEASE - 17 March 1997 + 29 March 1997 Leonard N. Zubkoff Dandelion Digital @@ -37,11 +37,10 @@ Linux kernel command line, allowing individual installations to tune driver performance and error recovery to their particular needs. -The most recent versions of this driver will always be available from my Linux -Home Page at URL "http://www.dandelion.com/Linux/" and by anonymous FTP from -ftp.dandelion.com. While only limited FTP directory listings are permitted, -the introductory banner displayed on anonymous FTP login will provide a list of -the driver versions and any other files that are available for retrieval. +The latest information on Linux support for BusLogic SCSI Host Adapters, as +well as the most recent release of this driver and the latest firmware for the +BT-948/958/958D, will always be available from my Linux Home Page at URL +"http://www.dandelion.com/Linux/". Bug reports should be sent via electronic mail to "lnz@dandelion.com". Please include with the bug report the complete configuration messages reported by the @@ -189,45 +188,45 @@ FlashPoint Series PCI Host Adapters: -FlashPoint LT (BT-930) Ultra Fast Single-ended SCSI-2 -FlashPoint DL (BT-932) Dual Channel Ultra Fast Single-ended SCSI-2 -FlashPoint LW (BT-950) Ultra Wide Single-ended SCSI-2 -FlashPoint DW (BT-952) Dual Channel Ultra Wide Single-ended SCSI-2 +FlashPoint LT (BT-930) Ultra SCSI-2 +FlashPoint DL (BT-932) Dual Channel Ultra SCSI-2 +FlashPoint LW (BT-950) Wide Ultra SCSI-2 +FlashPoint DW (BT-952) Dual Channel Wide Ultra SCSI-2 MultiMaster "W" Series Host Adapters: -BT-948 PCI Ultra Fast Single-ended SCSI-2 -BT-958 PCI Ultra Wide Single-ended SCSI-2 -BT-958D PCI Ultra Wide Differential SCSI-2 +BT-948 PCI Ultra SCSI-2 +BT-958 PCI Wide Ultra SCSI-2 +BT-958D PCI Wide Differential Ultra SCSI-2 MultiMaster "C" Series Host Adapters: -BT-946C PCI Fast Single-ended SCSI-2 -BT-956C PCI Fast Wide Single-ended SCSI-2 -BT-956CD PCI Fast Wide Differential SCSI-2 -BT-445C VLB Fast Single-ended SCSI-2 -BT-747C EISA Fast Single-ended SCSI-2 -BT-757C EISA Fast Wide Single-ended SCSI-2 -BT-757CD EISA Fast Wide Differential SCSI-2 -BT-545C ISA Fast Single-ended SCSI-2 -BT-540CF ISA Fast Single-ended SCSI-2 +BT-946C PCI Fast SCSI-2 +BT-956C PCI Wide Fast SCSI-2 +BT-956CD PCI Wide Differential Fast SCSI-2 +BT-445C VLB Fast SCSI-2 +BT-747C EISA Fast SCSI-2 +BT-757C EISA Wide Fast SCSI-2 +BT-757CD EISA Wide Differential Fast SCSI-2 +BT-545C ISA Fast SCSI-2 +BT-540CF ISA Fast SCSI-2 MultiMaster "S" Series Host Adapters: -BT-445S VLB Fast Single-ended SCSI-2 -BT-747S EISA Fast Single-ended SCSI-2 -BT-747D EISA Fast Differential SCSI-2 -BT-757S EISA Fast Wide Single-ended SCSI-2 -BT-757D EISA Fast Wide Differential SCSI-2 -BT-545S ISA Fast Single-ended SCSI-2 -BT-542D ISA Fast Differential SCSI-2 -BT-742A EISA Single-ended SCSI-2 (742A revision H) -BT-542B ISA Single-ended SCSI-2 (542B revision H) +BT-445S VLB Fast SCSI-2 +BT-747S EISA Fast SCSI-2 +BT-747D EISA Differential Fast SCSI-2 +BT-757S EISA Wide Fast SCSI-2 +BT-757D EISA Wide Differential Fast SCSI-2 +BT-545S ISA Fast SCSI-2 +BT-542D ISA Differential Fast SCSI-2 +BT-742A EISA SCSI-2 (742A revision H) +BT-542B ISA SCSI-2 (542B revision H) MultiMaster "A" Series Host Adapters: -BT-742A EISA Single-ended SCSI-2 (742A revisions A - G) -BT-542B ISA Single-ended SCSI-2 (542B revisions A - G) +BT-742A EISA SCSI-2 (742A revisions A - G) +BT-542B ISA SCSI-2 (542B revisions A - G) AMI FastDisk Host Adapters that are true BusLogic MultiMaster clones are also supported by this driver. @@ -380,7 +379,7 @@ replacing "/usr/src" with wherever you keep your Linux kernel source tree: cd /usr/src - tar -xvzf BusLogic-2.0.8.tar.gz + tar -xvzf BusLogic-2.0.9.tar.gz mv README.* LICENSE.* BusLogic.[ch] FlashPoint.c linux/drivers/scsi patch -p < BusLogic.patch cd linux diff -u --recursive --new-file v2.1.30/linux/drivers/scsi/README.FlashPoint linux/drivers/scsi/README.FlashPoint --- v2.1.30/linux/drivers/scsi/README.FlashPoint Tue Mar 4 10:25:24 1997 +++ linux/drivers/scsi/README.FlashPoint Sat Mar 29 09:01:00 1997 @@ -1,5 +1,6 @@ -The BusLogic FlashPoint SCSI Host Adapters are now supported on Linux. The -upgrade program described below will remain available through March 1997. +The BusLogic FlashPoint SCSI Host Adapters are now fully supported on Linux. +The upgrade program described below has been officially terminated effective +31 March 1997 since it is no longer needed. diff -u --recursive --new-file v2.1.30/linux/drivers/scsi/aha152x.c linux/drivers/scsi/aha152x.c --- v2.1.30/linux/drivers/scsi/aha152x.c Sat Sep 28 01:37:41 1996 +++ linux/drivers/scsi/aha152x.c Mon Mar 31 12:52:31 1997 @@ -432,9 +432,13 @@ #if defined(DEBUG_AHA152X) int aha152x[] = { 0, 11, 7, 1, 1, 0, DELAY_DEFAULT, 0, DEBUG_DEFAULT }; int aha152x1[] = { 0, 11, 7, 1, 1, 0, DELAY_DEFAULT, 0, DEBUG_DEFAULT }; +MODULE_PARM(aha152x, "1-9i"); +MODULE_PARM(aha152x1, "1-9i"); #else int aha152x[] = { 0, 11, 7, 1, 1, 0, DELAY_DEFAULT, 0 }; int aha152x1[] = { 0, 11, 7, 1, 1, 0, DELAY_DEFAULT, 0 }; +MODULE_PARM(aha152x, "1-8i"); +MODULE_PARM(aha152x1, "1-8i"); #endif #endif diff -u --recursive --new-file v2.1.30/linux/drivers/scsi/g_NCR5380.c linux/drivers/scsi/g_NCR5380.c --- v2.1.30/linux/drivers/scsi/g_NCR5380.c Fri Nov 22 02:06:21 1996 +++ linux/drivers/scsi/g_NCR5380.c Mon Mar 31 10:26:12 1997 @@ -330,7 +330,6 @@ { int blocks = len / 128; int start = 0; - int i; int bl; NCR5380_local_declare(); diff -u --recursive --new-file v2.1.30/linux/drivers/scsi/ibmmca.c linux/drivers/scsi/ibmmca.c --- v2.1.30/linux/drivers/scsi/ibmmca.c Wed Dec 18 01:48:52 1996 +++ linux/drivers/scsi/ibmmca.c Mon Mar 31 13:25:25 1997 @@ -38,8 +38,14 @@ Aug 21 1996: Modified the code which maps ldns to (pun,0). It was insufficient for those of us with CD-ROM changers. - Chris Beauregard + + Mar 16 1997: Modified driver to run as a module and to support + multiple adapters. + - Klaus Kudielka */ +#include + #include #include #include @@ -64,16 +70,10 @@ Driver Description (A) Subsystem Detection - This is done in find_adapter() function and is easy, since + This is done in the ibmmca_detect() function and is easy, since the information about MCA integrated subsystems and plug-in adapters is readily available in structure *mca_info. - In case you have more than one SCSI subsystem, only one can be used, - and its I/O port addresses should be standard 0x3540-7. To use more - than one adapter, the sharing of interrupt 14 would have to be - supported in Linux (it is not at present, but could be, since MCA - interrupts are level-triggered). - (B) Physical Units, Logical Units, and Logical Devices There can be up to 56 devices on SCSI bus (besides the adapter): there are up to 7 "physical units" (each identified by physical unit @@ -136,7 +136,7 @@ 100% sure that it is correct for larger disks. (F) Kernel Boot Option - The function ibmmca_scsi_setup() is called if option ibmmcascsi=n + The function ibmmca_scsi_setup() is called if option ibmmcascsi=... is passed to the kernel. See file linux/init/main.c for details. */ @@ -153,12 +153,25 @@ * keyboard controller, serial port controller, VGA, and XGA. */ -/*addresses of hardware registers on the subsystem */ -#define IM_CMD_REG 0x3540 /*Command Interface, (4 bytes long) */ -#define IM_ATTN_REG 0x3544 /*Attention (1 byte) */ -#define IM_CTR_REG 0x3545 /*Basic Control (1 byte) */ -#define IM_INTR_REG 0x3546 /*Interrupt Status (1 byte, read only) */ -#define IM_STAT_REG 0x3547 /*Basic Status (1 byte, read only) */ +/* driver configuration */ +#define IM_MAX_HOSTS 8 /* maximum number of host adapters */ +#define IM_RESET_DELAY 10 /* seconds allowed for a reset */ + +/* driver debugging - #undef all for normal operation */ +#undef IM_DEBUG_TIMEOUT 50 /* if defined: count interrupts + and ignore this special one */ +#undef IM_DEBUG_INT /* verbose interrupt */ +#undef IM_DEBUG_CMD /* verbose queuecommand */ + +/* addresses of hardware registers on the subsystem */ +#define IM_CMD_REG (shpnt->io_port) /*Command Interface, (4 bytes long) */ +#define IM_ATTN_REG (shpnt->io_port+4) /*Attention (1 byte) */ +#define IM_CTR_REG (shpnt->io_port+5) /*Basic Control (1 byte) */ +#define IM_INTR_REG (shpnt->io_port+6) /*Interrupt Status (1 byte, r/o) */ +#define IM_STAT_REG (shpnt->io_port+7) /*Basic Status (1 byte, read only) */ + +#define IM_IO_PORT 0x3540 +#define IM_N_IO_PORT 8 /*requests going into the upper nibble of the Attention register */ /*note: the lower nibble specifies the device(0-14), or subsystem(15) */ @@ -314,40 +327,67 @@ int is_disk; int block_length; }; -static struct logical_device ld[MAX_LOG_DEV]; -/*if this is nonzero, ibmmcascsi option has been passed to the kernel */ -static int setup_called = 0; +/* data structure for each host adapter */ +struct ibmmca_hostdata + { + /* array of logical devices */ + struct logical_device _ld[MAX_LOG_DEV]; + /* array to convert (pun, lun) into logical device number */ + unsigned char _get_ldn[8][8]; + /* used only when checking logical devices */ + int _local_checking_phase_flag; + int _got_interrupt; + int _stat_result; + /* reset status (used only when doing reset) */ + int _reset_status; + }; -/*scsi id (physical unit number) of subsystem (set during detect) */ -static int subsystem_pun; +/* reset status values */ +#define IM_RESET_NOT_IN_PROGRESS 0 +#define IM_RESET_IN_PROGRESS 1 +#define IM_RESET_FINISHED_OK 2 +#define IM_RESET_FINISHED_FAIL 3 -/*array to convert (pun, lun) into logical device number */ -static unsigned char get_ldn[8][8]; +/* macros to access host data structure */ +#define HOSTDATA(shpnt) ((struct ibmmca_hostdata *) shpnt->hostdata) +#define subsystem_pun (shpnt->this_id) +#define ld (HOSTDATA(shpnt)->_ld) +#define get_ldn (HOSTDATA(shpnt)->_get_ldn) +#define local_checking_phase_flag (HOSTDATA(shpnt)->_local_checking_phase_flag) +#define got_interrupt (HOSTDATA(shpnt)->_got_interrupt) +#define stat_result (HOSTDATA(shpnt)->_stat_result) +#define reset_status (HOSTDATA(shpnt)->_reset_status) + +/*--------------------------------------------------------------------*/ + +/* if this is nonzero, ibmmcascsi option has been passed to the kernel */ +static int io_port[IM_MAX_HOSTS] = { 0 }; +static int scsi_id[IM_MAX_HOSTS] = { 7 }; + +MODULE_PARM(io_port, "1-" __MODULE_STRING(IM_MAX_HOSTS) "i"); +MODULE_PARM(scsi_id, "1-" __MODULE_STRING(IM_MAX_HOSTS) "i"); /*counter of concurrent disk read/writes, to turn on/off disk led */ -static int disk_rw_in_progress; +static int disk_rw_in_progress = 0; -/*used only when checking logical devices */ -static int local_checking_phase_flag; -static int got_interrupt; -static int stat_result; +/* host information */ +static int found = 0; +static struct Scsi_Host *hosts[IM_MAX_HOSTS+1] = { NULL }; -/*reset status and its values (used only when doing reset) */ -static int reset_status; -#define IM_RESET_NOT_IN_PROGRESS 0 -#define IM_RESET_IN_PROGRESS 1 -#define IM_RESET_FINISHED_OK 2 -#define IM_RESET_FINISHED_FAIL 3 +/*--------------------------------------------------------------------*/ /*local functions */ static void interrupt_handler (int irq, void *dev_id, struct pt_regs *regs); -static void issue_cmd (unsigned long cmd_reg, unsigned char attn_reg); +static void issue_cmd (struct Scsi_Host *shpnt, unsigned long cmd_reg, + unsigned char attn_reg); static void internal_done (Scsi_Cmnd * cmd); -static int find_subsystem (void); -static void check_devices (void); -static int device_exists (int ldn, int *is_disk, int *block_length); +static void check_devices (struct Scsi_Host *shpnt); +static int device_exists (struct Scsi_Host *shpnt, int ldn, int *is_disk, + int *block_length); +static struct Scsi_Host *ibmmca_register(Scsi_Host_Template * template, + int port, int id); /*--------------------------------------------------------------------*/ @@ -355,16 +395,20 @@ interrupt_handler (int irq, void *dev_id, struct pt_regs *regs) { - /*get command result and logical device */ - unsigned int intr_reg = inb (IM_INTR_REG); - unsigned int cmd_result = intr_reg & 0xf0; - unsigned int ldn = intr_reg & 0x0f; + int i = 0; + struct Scsi_Host *shpnt; + unsigned int intr_reg; + unsigned int cmd_result; + unsigned int ldn; - if (!inb (IM_STAT_REG) & IM_INTR_REQUEST) - { - printk ("ibmmca SCSI: spurious/shared interrupt?\n"); - return; - } + do shpnt = hosts[i++]; + while (shpnt && !(inb(IM_STAT_REG) & IM_INTR_REQUEST)); + if (!shpnt) return; + + /*get command result and logical device */ + intr_reg = inb(IM_INTR_REG); + cmd_result = intr_reg & 0xf0; + ldn = intr_reg & 0x0f; /*must wait for attention reg not busy, then send EOI to subsystem */ while (1) @@ -409,9 +453,6 @@ } else { - /*reset disk led counter, turn of disk led */ - disk_rw_in_progress = 0; - PS2_DISK_LED_OFF (); reset_status = IM_RESET_FINISHED_OK; } return; @@ -420,16 +461,29 @@ panic ("IBM MCA SCSI: invalid logical device number.\n"); } +#ifdef IM_DEBUG_TIMEOUT + { + static int count = 0; + + if (++count == IM_DEBUG_TIMEOUT) { + printk("IBM MCA SCSI: Ignoring interrupt.\n"); + return; + } + } +#endif + /*if no command structure, just return, else clear cmd */ cmd = ld[ldn].cmd; if (!cmd) return; ld[ldn].cmd = 0; - /* printk("cmd=%02x ireg=%02x ds=%02x cs=%02x de=%02x ce=%02x\n", - cmd->cmnd[0], intr_reg, - ld[ldn].tsb.dev_status, ld[ldn].tsb.cmd_status, - ld[ldn].tsb.dev_error, ld[ldn].tsb.cmd_error); */ +#ifdef IM_DEBUG_INT + printk("cmd=%02x ireg=%02x ds=%02x cs=%02x de=%02x ce=%02x\n", + cmd->cmnd[0], intr_reg, + ld[ldn].tsb.dev_status, ld[ldn].tsb.cmd_status, + ld[ldn].tsb.dev_error, ld[ldn].tsb.cmd_error); +#endif /*if this is end of disk read/write, may turn off PS/2 disk led */ if (ld[ldn].is_disk) @@ -457,7 +511,8 @@ /*--------------------------------------------------------------------*/ static void -issue_cmd (unsigned long cmd_reg, unsigned char attn_reg) +issue_cmd (struct Scsi_Host *shpnt, unsigned long cmd_reg, + unsigned char attn_reg) { /*must wait for attention reg not busy */ while (1) @@ -487,83 +542,29 @@ static int ibmmca_getinfo (char *buf, int slot, void *dev) { + struct Scsi_Host *shpnt = dev; int len = 0; len += sprintf (buf + len, "Subsystem PUN: %d\n", subsystem_pun); - len += sprintf (buf + len, "Detected at boot: %s\n", - setup_called ? "No" : "Yes"); + len += sprintf (buf + len, "I/O base address: 0x%x\n", shpnt->io_port); return len; } -static int -find_subsystem (void) -{ - int j, list_size, slot; - unsigned char pos2, pos3; - - /*if this is not MCA machine, return "nothing found" */ - if (!MCA_bus) - return 0; - - /*if ibmmcascsi setup option was passed to kernel, return "found" */ - if (setup_called) - { - printk ("IBM MCA SCSI: forced detection, scsi id=%d.\n", - subsystem_pun); - return 1; - } - - /*first look for the SCSI integrated on the motherboard */ - pos2 = mca_read_stored_pos (MCA_INTEGSCSI, 2); - if ((pos2 & 1) == 0) - { - pos3 = mca_read_stored_pos (MCA_INTEGSCSI, 3); - subsystem_pun = (pos3 & 0xe0) >> 5; - printk ("IBM MCA SCSI: integrated SCSI found, scsi id=%d.\n", - subsystem_pun); - mca_set_adapter_name (MCA_INTEGSCSI, "PS/2 Integrated SCSI"); - mca_set_adapter_procfn (MCA_INTEGSCSI, (MCA_ProcFn) ibmmca_getinfo, - NULL); - return 1; - } - - list_size = sizeof (subsys_list) / sizeof (struct subsys_list_struct); - for (j = 0; j < list_size; j += 1) - { - if ((slot = mca_find_adapter (subsys_list[j].mca_id, 0)) != MCA_NOTFOUND) - { - pos3 = mca_read_stored_pos (slot, 3); - subsystem_pun = (pos3 & 0xe0) >> 5; - printk ("IBM MCA SCSI: %s found in slot %d, scsi id=%d.\n", - subsys_list[j].description, slot + 1, subsystem_pun); - - mca_set_adapter_name (slot, subsys_list[j].description); - mca_set_adapter_procfn (slot, (MCA_ProcFn) ibmmca_getinfo, - NULL); - - return 1; - } - } - - /*return "nothing found" */ - return 0; -} - /*--------------------------------------------------------------------*/ static void -check_devices (void) +check_devices(struct Scsi_Host *shpnt) { int is_disk, block_length; int ldn; int num_ldn = 0; - /*check ldn's from 0 to MAX_LOG_DEV to find which devices exist */ + /* check ldn's from 0 to MAX_LOG_DEV to find which devices exist */ for (ldn = 0; ldn < MAX_LOG_DEV; ldn++) { - if (device_exists (ldn, &is_disk, &block_length)) + if (device_exists(shpnt, ldn, &is_disk, &block_length)) { - printk ("IBM MCA SCSI: logical device found at ldn=%d.\n", ldn); + printk("IBM MCA SCSI: logical device found at ldn=%d.\n", ldn); ld[ldn].is_disk = is_disk; ld[ldn].block_length = block_length; get_ldn[num_ldn / 8][num_ldn % 8] = ldn; @@ -577,7 +578,8 @@ /*--------------------------------------------------------------------*/ static int -device_exists (int ldn, int *is_disk, int *block_length) +device_exists(struct Scsi_Host *shpnt, int ldn, int *is_disk, + int *block_length) { struct im_scb scb; struct im_tsb tsb; @@ -596,7 +598,7 @@ /*issue scb to passed ldn, and busy wait for interrupt */ got_interrupt = 0; - issue_cmd (virt_to_bus(&scb), IM_SCB | ldn); + issue_cmd (shpnt, virt_to_bus(&scb), IM_SCB | ldn); while (!got_interrupt) barrier (); @@ -633,7 +635,7 @@ /*issue scb to passed ldn, and busy wait for interrupt */ got_interrupt = 0; - issue_cmd (virt_to_bus(&scb), IM_SCB | ldn); + issue_cmd (shpnt, virt_to_bus(&scb), IM_SCB | ldn); while (!got_interrupt) barrier (); @@ -656,47 +658,154 @@ /*--------------------------------------------------------------------*/ +#ifdef CONFIG_SCSI_IBMMCA + void ibmmca_scsi_setup (char *str, int *ints) { - /*verify that one value (between 0 and 7) was specified */ - if (setup_called++ || ints[0] != 1 || ints[1] < 0 || ints[1] >= 8) + int i; + + for (i = 0; i < IM_MAX_HOSTS && i < ints[0]; i++) { - printk ("IBM MCA SCSI: usage: ibmmcascsi=\n"); - return; + io_port[i] = ints[i+1]; } - subsystem_pun = ints[1]; } +#endif + /*--------------------------------------------------------------------*/ int ibmmca_detect (Scsi_Host_Template * template) { - /*initialize local data */ - memset (ld, 0, sizeof ld); - memset (get_ldn, 0xff, sizeof get_ldn); - disk_rw_in_progress = 0; - reset_status = IM_RESET_NOT_IN_PROGRESS; + struct Scsi_Host *shpnt; + int port, id, i, list_size, slot; + unsigned pos2, pos3; - /*search for the subsystem, return 0 if not found */ - if (!find_subsystem ()) + /* if this is not MCA machine, return "nothing found" */ + if (!MCA_bus) return 0; - /*get interrupt request level */ - if (request_irq (IM_IRQ, interrupt_handler, SA_SHIRQ, "ibmmca", 0)) + /* get interrupt request level */ + if (request_irq (IM_IRQ, interrupt_handler, SA_SHIRQ, "ibmmca", hosts)) { - printk ("IBM MCA SCSI: Unable to get IRQ %d.\n", IM_IRQ); + printk("IBM MCA SCSI: Unable to get IRQ %d.\n", IM_IRQ); return 0; } - /*check which logical devices exist */ + /* if ibmmcascsi setup option was passed to kernel, return "found" */ + for (i = 0; i < IM_MAX_HOSTS; i++) + if (io_port[i] > 0 && scsi_id[i] >= 0 && scsi_id[i] < 8) + { + printk("IBM MCA SCSI: forced detection, io=0x%x, scsi id=%d.\n", + io_port[i], scsi_id[i]); + ibmmca_register(template, io_port[i], scsi_id[i]); + } + if (found) return found; + + /* first look for the SCSI integrated on the motherboard */ + pos2 = mca_read_stored_pos(MCA_INTEGSCSI, 2); + if ((pos2 & 1) == 0) + { + pos3 = mca_read_stored_pos(MCA_INTEGSCSI, 3); + port = IM_IO_PORT + ((pos2 & 0x0e) << 2); + id = (pos3 & 0xe0) >> 5; + printk("IBM MCA SCSI: integrated SCSI found, io=0x%x, scsi id=%d.\n", + port, id); + if ((shpnt = ibmmca_register(template, port, id))) + { + mca_set_adapter_name(MCA_INTEGSCSI, "PS/2 Integrated SCSI"); + mca_set_adapter_procfn(MCA_INTEGSCSI, (MCA_ProcFn) ibmmca_getinfo, + shpnt); + } + } + + /* now look for other adapters */ + list_size = sizeof(subsys_list) / sizeof(struct subsys_list_struct); + for (i = 0; i < list_size; i++) + { + slot = 0; + while ((slot = mca_find_adapter(subsys_list[i].mca_id, slot)) + != MCA_NOTFOUND) + { + pos2 = mca_read_stored_pos(slot, 2); + pos3 = mca_read_stored_pos(slot, 3); + port = IM_IO_PORT + ((pos2 & 0x0e) << 2); + id = (pos3 & 0xe0) >> 5; + printk ("IBM MCA SCSI: %s found in slot %d, io=0x%x, scsi id=%d.\n", + subsys_list[i].description, slot + 1, port, id); + if ((shpnt = ibmmca_register(template, port, id))) + { + mca_set_adapter_name (slot, subsys_list[i].description); + mca_set_adapter_procfn (slot, (MCA_ProcFn) ibmmca_getinfo, + shpnt); + } + slot++; + } + } + + if (!found) { + free_irq (IM_IRQ, hosts); + printk("IBM MCA SCSI: No adapter attached.\n"); + } + + return found; +} + +/*--------------------------------------------------------------------*/ + +static struct Scsi_Host * +ibmmca_register(Scsi_Host_Template * template, int port, int id) +{ + struct Scsi_Host *shpnt; + int i, j; + + /* check I/O region */ + if (check_region(port, IM_N_IO_PORT)) + { + printk("IBM MCA SCSI: Unable to get I/O region 0x%x-0x%x.\n", + port, port + IM_N_IO_PORT); + return NULL; + } + + /* register host */ + shpnt = scsi_register(template, sizeof(struct ibmmca_hostdata)); + if (!shpnt) + { + printk("IBM MCA SCSI: Unable to register host.\n"); + return NULL; + } + + /* request I/O region */ + request_region(port, IM_N_IO_PORT, "ibmmca"); + + hosts[found++] = shpnt; + shpnt->irq = IM_IRQ; + shpnt->io_port = port; + shpnt->n_io_port = IM_N_IO_PORT; + shpnt->this_id = id; + for (i = 0; i < 8; i++) + for (j = 0; j < 8; j++) + get_ldn[i][j] = MAX_LOG_DEV; + + /* check which logical devices exist */ local_checking_phase_flag = 1; - check_devices (); + check_devices(shpnt); local_checking_phase_flag = 0; - /*if got here, one ibm mca subsystem has been detected */ - return 1; + /* an ibm mca subsystem has been detected */ + return shpnt; +} + +/*--------------------------------------------------------------------*/ + +int +ibmmca_release(struct Scsi_Host *shpnt) +{ + release_region(shpnt->io_port, shpnt->n_io_port); + if (!(--found)) + free_irq(shpnt->irq, hosts); + return 0; } /*--------------------------------------------------------------------*/ @@ -719,6 +828,7 @@ unsigned int ldn; unsigned int scsi_cmd; struct im_scb *scb; + struct Scsi_Host *shpnt = cmd->host; /*if (target,lun) unassigned, return error */ ldn = get_ldn[cmd->target][cmd->lun]; @@ -764,7 +874,9 @@ /*fill scb information dependent on scsi command */ scsi_cmd = cmd->cmnd[0]; - /* printk("issue scsi cmd=%02x to ldn=%d\n", scsi_cmd, ldn); */ +#ifdef IM_DEBUG_CMD + printk("issue scsi cmd=%02x to ldn=%d\n", scsi_cmd, ldn); +#endif switch (scsi_cmd) { case READ_6: @@ -833,7 +945,7 @@ } /*issue scb command, and return */ - issue_cmd (virt_to_bus(scb), IM_SCB | ldn); + issue_cmd (shpnt, virt_to_bus(scb), IM_SCB | ldn); return 0; } @@ -842,10 +954,13 @@ int ibmmca_abort (Scsi_Cmnd * cmd) { -/*do a reset instead, since abort does not work well for me at present */ - return ibmmca_reset (cmd); + /* The code below doesn't work right now, so we tell the upper layer + that we can't abort. This eventually causes a reset. + */ + return SCSI_ABORT_SNOOZE; #if 0 + struct Scsi_Host *shpnt = cmd->host; unsigned int ldn; void (*saved_done) (Scsi_Cmnd *); @@ -870,7 +985,7 @@ saved_done = cmd->scsi_done; cmd->scsi_done = internal_done; cmd->SCp.Status = 0; - issue_cmd (IM_ABORT_IMM_CMD, IM_IMM_CMD | ldn); + issue_cmd (shpnt, IM_ABORT_IMM_CMD, IM_IMM_CMD | ldn); while (!cmd->SCp.Status) barrier (); @@ -889,22 +1004,42 @@ /*--------------------------------------------------------------------*/ int -ibmmca_reset (Scsi_Cmnd * cmd) +ibmmca_reset (Scsi_Cmnd * cmd, unsigned int reset_flags) { - /*issue reset immediate command to subsystem, and wait for interrupt */ - printk ("IBM MCA SCSI: resetting all devices.\n"); + struct Scsi_Host *shpnt = cmd->host; + int ticks = IM_RESET_DELAY*HZ; + + if (local_checking_phase_flag) { + printk("IBM MCA SCSI: unable to reset while checking devices.\n"); + return SCSI_RESET_SNOOZE; + } + + /* issue reset immediate command to subsystem, and wait for interrupt */ + printk("IBM MCA SCSI: resetting all devices.\n"); cli (); reset_status = IM_RESET_IN_PROGRESS; - issue_cmd (IM_RESET_IMM_CMD, IM_IMM_CMD | 0xf); - while (reset_status == IM_RESET_IN_PROGRESS) - barrier (); + issue_cmd (shpnt, IM_RESET_IMM_CMD, IM_IMM_CMD | 0xf); + while (reset_status == IM_RESET_IN_PROGRESS && --ticks) { + udelay(1000000/HZ); + barrier(); + } - /*if reset failed, just return error */ - if (reset_status == IM_RESET_FINISHED_FAIL) + /* if reset did not complete, just return an error*/ + if (!ticks) { + printk("IBM MCA SCSI: reset did not complete within %d seconds.\n", + IM_RESET_DELAY); + reset_status = IM_RESET_FINISHED_FAIL; return SCSI_RESET_ERROR; + } + + /* if reset failed, just return an error */ + if (reset_status == IM_RESET_FINISHED_FAIL) { + printk("IBM MCA SCSI: reset failed.\n"); + return SCSI_RESET_ERROR; + } - /*so reset finished ok - call outstanding done's, and return success */ - printk ("IBM MCA SCSI: reset finished well.\n"); + /* so reset finished ok - call outstanding done's, and return success */ + printk ("IBM MCA SCSI: reset completed without error.\n"); { int i; for (i = 0; i < MAX_LOG_DEV; i++) @@ -947,3 +1082,11 @@ } /*--------------------------------------------------------------------*/ + +#ifdef MODULE +/* Eventually this will go into an include file, but this will be later */ +Scsi_Host_Template driver_template = IBMMCA; + +#include "scsi_module.c" +#endif + diff -u --recursive --new-file v2.1.30/linux/drivers/scsi/ibmmca.h linux/drivers/scsi/ibmmca.h --- v2.1.30/linux/drivers/scsi/ibmmca.h Sun Jan 26 02:07:18 1997 +++ linux/drivers/scsi/ibmmca.h Mon Mar 31 13:25:25 1997 @@ -8,10 +8,11 @@ /*services provided to the higher level of Linux SCSI driver */ int ibmmca_detect (Scsi_Host_Template *); +int ibmmca_release (struct Scsi_Host *); int ibmmca_command (Scsi_Cmnd *); int ibmmca_queuecommand (Scsi_Cmnd *, void (*done) (Scsi_Cmnd *)); int ibmmca_abort (Scsi_Cmnd *); -int ibmmca_reset (Scsi_Cmnd *); +int ibmmca_reset (Scsi_Cmnd *, unsigned int); int ibmmca_biosparam (Disk *, kdev_t, int *); /*structure for /proc filesystem */ @@ -25,7 +26,7 @@ NULL, /*proc info fn*/ \ "IBMMCA", /*name*/ \ ibmmca_detect, /*detect fn*/ \ - NULL, /*release fn*/ \ + ibmmca_release, /*release fn*/ \ NULL, /*info fn*/ \ ibmmca_command, /*command fn*/ \ ibmmca_queuecommand, /*queuecommand fn*/ \ diff -u --recursive --new-file v2.1.30/linux/drivers/scsi/in2000.c linux/drivers/scsi/in2000.c --- v2.1.30/linux/drivers/scsi/in2000.c Mon Oct 14 23:39:48 1996 +++ linux/drivers/scsi/in2000.c Mon Mar 31 10:26:12 1997 @@ -127,6 +127,7 @@ #include #endif +#define uchar unsigned char #define IN2000_VERSION "1.30" #define IN2000_DATE "14/Oct/1996" @@ -199,16 +200,296 @@ static struct Scsi_Host *instance_list = 0; #ifdef PROC_INTERFACE -unsigned long disc_allowed_total; -unsigned long disc_taken_total; +static unsigned long disc_allowed_total; +static unsigned long disc_taken_total; #endif +/* IN2000 io_port offsets */ +#define IO_WD_ASR 0x00 /* R - 3393 auxstat reg */ +#define ASR_INT 0x80 +#define ASR_LCI 0x40 +#define ASR_BSY 0x20 +#define ASR_CIP 0x10 +#define ASR_PE 0x02 +#define ASR_DBR 0x01 +#define IO_WD_ADDR 0x00 /* W - 3393 address reg */ +#define IO_WD_DATA 0x01 /* R/W - rest of 3393 regs */ +#define IO_FIFO 0x02 /* R/W - in2000 dual-port fifo (16 bits) */ +#define IN2000_FIFO_SIZE 2048 /* fifo capacity in bytes */ +#define IO_CARD_RESET 0x03 /* W - in2000 start master reset */ +#define IO_FIFO_COUNT 0x04 /* R - in2000 fifo counter */ +#define IO_FIFO_WRITE 0x05 /* W - clear fifo counter, start write */ +#define IO_FIFO_READ 0x07 /* W - start fifo read */ +#define IO_LED_OFF 0x08 /* W - turn off in2000 activity LED */ +#define IO_SWITCHES 0x08 /* R - read in2000 dip switch */ +#define SW_ADDR0 0x01 /* bit 0 = bit 0 of index to io addr */ +#define SW_ADDR1 0x02 /* bit 1 = bit 1 of index io addr */ +#define SW_DISINT 0x04 /* bit 2 true if ints disabled */ +#define SW_INT0 0x08 /* bit 3 = bit 0 of index to interrupt */ +#define SW_INT1 0x10 /* bit 4 = bit 1 of index to interrupt */ +#define SW_INT_SHIFT 3 /* shift right this amount to right justify int bits */ +#define SW_SYNC_DOS5 0x20 /* bit 5 used by Always BIOS */ +#define SW_FLOPPY 0x40 /* bit 6 true if floppy enabled */ +#define SW_BIT7 0x80 /* bit 7 hardwired true (ground) */ +#define IO_LED_ON 0x09 /* W - turn on in2000 activity LED */ +#define IO_HARDWARE 0x0a /* R - read in2000 hardware rev, stop reset */ +#define IO_INTR_MASK 0x0c /* W - in2000 interrupt mask reg */ +#define IMASK_WD 0x01 /* WD33c93 interrupt mask */ +#define IMASK_FIFO 0x02 /* FIFO interrupt mask */ + +/* wd register names */ +#define WD_OWN_ID 0x00 +#define WD_CONTROL 0x01 +#define WD_TIMEOUT_PERIOD 0x02 +#define WD_CDB_1 0x03 +#define WD_CDB_2 0x04 +#define WD_CDB_3 0x05 +#define WD_CDB_4 0x06 +#define WD_CDB_5 0x07 +#define WD_CDB_6 0x08 +#define WD_CDB_7 0x09 +#define WD_CDB_8 0x0a +#define WD_CDB_9 0x0b +#define WD_CDB_10 0x0c +#define WD_CDB_11 0x0d +#define WD_CDB_12 0x0e +#define WD_TARGET_LUN 0x0f +#define WD_COMMAND_PHASE 0x10 +#define WD_SYNCHRONOUS_TRANSFER 0x11 +#define WD_TRANSFER_COUNT_MSB 0x12 +#define WD_TRANSFER_COUNT 0x13 +#define WD_TRANSFER_COUNT_LSB 0x14 +#define WD_DESTINATION_ID 0x15 +#define WD_SOURCE_ID 0x16 +#define WD_SCSI_STATUS 0x17 +#define WD_COMMAND 0x18 +#define WD_DATA 0x19 +#define WD_QUEUE_TAG 0x1a +#define WD_AUXILIARY_STATUS 0x1f + +/* WD commands */ +#define WD_CMD_RESET 0x00 +#define WD_CMD_ABORT 0x01 +#define WD_CMD_ASSERT_ATN 0x02 +#define WD_CMD_NEGATE_ACK 0x03 +#define WD_CMD_DISCONNECT 0x04 +#define WD_CMD_RESELECT 0x05 +#define WD_CMD_SEL_ATN 0x06 +#define WD_CMD_SEL 0x07 +#define WD_CMD_SEL_ATN_XFER 0x08 +#define WD_CMD_SEL_XFER 0x09 +#define WD_CMD_RESEL_RECEIVE 0x0a +#define WD_CMD_RESEL_SEND 0x0b +#define WD_CMD_WAIT_SEL_RECEIVE 0x0c +#define WD_CMD_TRANS_ADDR 0x18 +#define WD_CMD_TRANS_INFO 0x20 +#define WD_CMD_TRANSFER_PAD 0x21 +#define WD_CMD_SBT_MODE 0x80 + +/* SCSI Bus Phases */ +#define PHS_DATA_OUT 0x00 +#define PHS_DATA_IN 0x01 +#define PHS_COMMAND 0x02 +#define PHS_STATUS 0x03 +#define PHS_MESS_OUT 0x06 +#define PHS_MESS_IN 0x07 + +/* Command Status Register definitions */ + + /* reset state interrupts */ +#define CSR_RESET 0x00 +#define CSR_RESET_AF 0x01 + + /* successful completion interrupts */ +#define CSR_RESELECT 0x10 +#define CSR_SELECT 0x11 +#define CSR_SEL_XFER_DONE 0x16 +#define CSR_XFER_DONE 0x18 + + /* paused or aborted interrupts */ +#define CSR_MSGIN 0x20 +#define CSR_SDP 0x21 +#define CSR_SEL_ABORT 0x22 +#define CSR_RESEL_ABORT 0x25 +#define CSR_RESEL_ABORT_AM 0x27 +#define CSR_ABORT 0x28 + + /* terminated interrupts */ +#define CSR_INVALID 0x40 +#define CSR_UNEXP_DISC 0x41 +#define CSR_TIMEOUT 0x42 +#define CSR_PARITY 0x43 +#define CSR_PARITY_ATN 0x44 +#define CSR_BAD_STATUS 0x45 +#define CSR_UNEXP 0x48 + + /* service required interrupts */ +#define CSR_RESEL 0x80 +#define CSR_RESEL_AM 0x81 +#define CSR_DISC 0x85 +#define CSR_SRV_REQ 0x88 + + /* Own ID/CDB Size register */ +#define OWNID_EAF 0x08 +#define OWNID_EHP 0x10 +#define OWNID_RAF 0x20 +#define OWNID_FS_8 0x00 +#define OWNID_FS_12 0x40 +#define OWNID_FS_16 0x80 + + /* Control register */ +#define CTRL_HSP 0x01 +#define CTRL_HA 0x02 +#define CTRL_IDI 0x04 +#define CTRL_EDI 0x08 +#define CTRL_HHP 0x10 +#define CTRL_POLLED 0x00 +#define CTRL_BURST 0x20 +#define CTRL_BUS 0x40 +#define CTRL_DMA 0x80 + + /* Timeout Period register */ +#define TIMEOUT_PERIOD_VALUE 20 /* results in 200 ms. */ + + /* Synchronous Transfer Register */ +#define STR_FSS 0x80 + + /* Destination ID register */ +#define DSTID_DPD 0x40 +#define DATA_OUT_DIR 0 +#define DATA_IN_DIR 1 +#define DSTID_SCC 0x80 + + /* Source ID register */ +#define SRCID_MASK 0x07 +#define SRCID_SIV 0x08 +#define SRCID_DSP 0x20 +#define SRCID_ES 0x40 +#define SRCID_ER 0x80 + + + +#define DEFAULT_SX_PER 500 /* (ns) fairly safe */ +#define DEFAULT_SX_OFF 0 /* aka async */ + +#define OPTIMUM_SX_PER 252 /* (ns) best we can do (mult-of-4) */ +#define OPTIMUM_SX_OFF 12 /* size of in2000 fifo */ + + +/* defines for hostdata->chip */ + +#define C_WD33C93 0 +#define C_WD33C93A 1 +#define C_WD33C93B 2 +#define C_UNKNOWN_CHIP 100 + +/* defines for hostdata->state */ + +#define S_UNCONNECTED 0 +#define S_SELECTING 1 +#define S_RUNNING_LEVEL2 2 +#define S_CONNECTED 3 +#define S_PRE_TMP_DISC 4 +#define S_PRE_CMP_DISC 5 + +/* defines for hostdata->fifo */ + +#define FI_FIFO_UNUSED 0 +#define FI_FIFO_READING 1 +#define FI_FIFO_WRITING 2 + +/* defines for hostdata->level2 */ +/* NOTE: only the first 3 are trustworthy at this point - + * having trouble when more than 1 device is reading/writing + * at the same time... + */ + +#define L2_NONE 0 /* no combination commands - we get lots of ints */ +#define L2_SELECT 1 /* start with SEL_ATN_XFER, but never resume it */ +#define L2_BASIC 2 /* resume after STATUS ints & RDP messages */ +#define L2_DATA 3 /* resume after DATA_IN/OUT ints */ +#define L2_MOST 4 /* resume after anything except a RESELECT int */ +#define L2_RESELECT 5 /* resume after everything, including RESELECT ints */ +#define L2_ALL 6 /* always resume */ + +/* defines for hostdata->disconnect */ + +#define DIS_NEVER 0 +#define DIS_ADAPTIVE 1 +#define DIS_ALWAYS 2 + +/* defines for hostdata->args */ + +#define DB_TEST 1<<0 +#define DB_FIFO 1<<1 +#define DB_QUEUE_COMMAND 1<<2 +#define DB_EXECUTE 1<<3 +#define DB_INTR 1<<4 +#define DB_TRANSFER 1<<5 +#define DB_MASK 0x3f + +#define A_NO_SCSI_RESET 1<<15 + + +/* defines for hostdata->sync_xfer[] */ + +#define SS_UNSET 0 +#define SS_FIRST 1 +#define SS_WAITING 2 +#define SS_SET 3 + +/* defines for hostdata->proc */ + +#define PR_VERSION 1<<0 +#define PR_INFO 1<<1 +#define PR_TOTALS 1<<2 +#define PR_CONNECTED 1<<3 +#define PR_INPUTQ 1<<4 +#define PR_DISCQ 1<<5 +#define PR_TEST 1<<6 +#define PR_STOP 1<<7 + #define read1_io(a) (inb(hostdata->io_base+(a))) #define read2_io(a) (inw(hostdata->io_base+(a))) #define write1_io(b,a) (outb((b),hostdata->io_base+(a))) #define write2_io(w,a) (outw((w),hostdata->io_base+(a))) + +struct sx_period { + unsigned int period_ns; + uchar reg_value; + }; + + +struct IN2000_hostdata { + struct Scsi_Host *next; + uchar chip; /* what kind of wd33c93 chip? */ + uchar microcode; /* microcode rev if 'B' */ + unsigned short io_base; /* IO port base */ + unsigned int dip_switch; /* dip switch settings */ + unsigned int hrev; /* hardware revision of card */ + volatile uchar busy[8]; /* index = target, bit = lun */ + volatile Scsi_Cmnd *input_Q; /* commands waiting to be started */ + volatile Scsi_Cmnd *selecting; /* trying to select this command */ + volatile Scsi_Cmnd *connected; /* currently connected command */ + volatile Scsi_Cmnd *disconnected_Q;/* commands waiting for reconnect */ + uchar state; /* what we are currently doing */ + uchar fifo; /* what the FIFO is up to */ + uchar level2; /* extent to which Level-2 commands are used */ + uchar disconnect; /* disconnect/reselect policy */ + unsigned int args; /* set from command-line argument */ + uchar incoming_msg[8]; /* filled during message_in phase */ + int incoming_ptr; /* mainly used with EXTENDED messages */ + uchar outgoing_msg[8]; /* send this during next message_out */ + int outgoing_len; /* length of outgoing message */ + unsigned int default_sx_per; /* default transfer period for SCSI bus */ + uchar sync_xfer[8]; /* sync_xfer reg settings per target */ + uchar sync_stat[8]; /* status of sync negotiation per target */ + uchar sync_off; /* bit mask: don't use sync with these targets */ + uchar proc; /* bit mask: what's in proc output */ + }; + /* These inline assembly defines are derived from a patch * sent to me by Bill Earnest. He's done a lot of very * valuable thinking, testing, and coding during his effort @@ -243,7 +524,7 @@ : "edx", "ecx", "esi" ) /* trashed */ -inline uchar read_3393(struct IN2000_hostdata *hostdata, uchar reg_num) +static inline uchar read_3393(struct IN2000_hostdata *hostdata, uchar reg_num) { write1_io(reg_num,IO_WD_ADDR); return read1_io(IO_WD_DATA); @@ -253,14 +534,14 @@ #define READ_AUX_STAT() read1_io(IO_WD_ASR) -inline void write_3393(struct IN2000_hostdata *hostdata, uchar reg_num, uchar value) +static inline void write_3393(struct IN2000_hostdata *hostdata, uchar reg_num, uchar value) { write1_io(reg_num,IO_WD_ADDR); write1_io(value,IO_WD_DATA); } -inline void write_3393_cmd(struct IN2000_hostdata *hostdata, uchar cmd) +static inline void write_3393_cmd(struct IN2000_hostdata *hostdata, uchar cmd) { /* while (READ_AUX_STAT() & ASR_CIP) printk("|");*/ @@ -269,7 +550,7 @@ } -uchar read_1_byte(struct IN2000_hostdata *hostdata) +static uchar read_1_byte(struct IN2000_hostdata *hostdata) { uchar asr, x = 0; @@ -284,7 +565,7 @@ } -void write_3393_count(struct IN2000_hostdata *hostdata, unsigned long value) +static void write_3393_count(struct IN2000_hostdata *hostdata, unsigned long value) { write1_io(WD_TRANSFER_COUNT_MSB,IO_WD_ADDR); write1_io((value >> 16),IO_WD_DATA); @@ -293,7 +574,7 @@ } -unsigned long read_3393_count(struct IN2000_hostdata *hostdata) +static unsigned long read_3393_count(struct IN2000_hostdata *hostdata) { unsigned long value; @@ -356,7 +637,7 @@ return 7; } -uchar calc_sync_xfer(unsigned int period, unsigned int offset) +static uchar calc_sync_xfer(unsigned int period, unsigned int offset) { uchar result; @@ -368,7 +649,7 @@ -void in2000_execute(struct Scsi_Host *instance); +static void in2000_execute(struct Scsi_Host *instance); int in2000_queuecommand (Scsi_Cmnd *cmd, void (*done)(Scsi_Cmnd *)) { @@ -466,7 +747,7 @@ * the input_Q, using the first command we find that's intended * for a currently non-busy target/lun. */ -void in2000_execute (struct Scsi_Host *instance) +static void in2000_execute (struct Scsi_Host *instance) { struct IN2000_hostdata *hostdata; Scsi_Cmnd *cmd, *prev; @@ -740,7 +1021,7 @@ -void transfer_pio(uchar *buf, int cnt, +static void transfer_pio(uchar *buf, int cnt, int data_in_dir, struct IN2000_hostdata *hostdata) { uchar asr; @@ -776,7 +1057,7 @@ -void transfer_bytes(Scsi_Cmnd *cmd, int data_in_dir) +static void transfer_bytes(Scsi_Cmnd *cmd, int data_in_dir) { struct IN2000_hostdata *hostdata; unsigned short *sp; @@ -869,7 +1150,7 @@ * re-think the multiple card capability.... */ -void in2000_intr (int irqnum, void * dev_id, struct pt_regs *ptregs) +static void in2000_intr (int irqnum, void * dev_id, struct pt_regs *ptregs) { struct Scsi_Host *instance; struct IN2000_hostdata *hostdata; @@ -1655,7 +1936,7 @@ #define RESET_CARD_AND_BUS 1 #define B_FLAG 0x80 -int reset_hardware(struct Scsi_Host *instance, int type) +static int reset_hardware(struct Scsi_Host *instance, int type) { struct IN2000_hostdata *hostdata; int qt,x; @@ -1913,7 +2194,7 @@ /* check_setup_strings() returns index if key found, 0 if not */ -int check_setup_strings(char *key, int *flags, int *val, char *buf) +static int check_setup_strings(char *key, int *flags, int *val, char *buf) { int x; char *cp; @@ -1951,21 +2232,21 @@ * special macros declared in 'asm/io.h'. We use readb() and * readl() when reading from the card's BIOS area in in2000_detect(). */ -const unsigned int *bios_tab[] = { +static const unsigned int *bios_tab[] = { (unsigned int *)0xc8000, (unsigned int *)0xd0000, (unsigned int *)0xd8000, 0 }; -const unsigned short base_tab[] = { +static const unsigned short base_tab[] = { 0x220, 0x200, 0x110, 0x100, }; -const int int_tab[] = { +static const int int_tab[] = { 15, 14, 11, diff -u --recursive --new-file v2.1.30/linux/drivers/scsi/in2000.h linux/drivers/scsi/in2000.h --- v2.1.30/linux/drivers/scsi/in2000.h Sun Jan 26 02:07:18 1997 +++ linux/drivers/scsi/in2000.h Mon Mar 31 10:26:12 1997 @@ -23,298 +23,13 @@ #ifndef IN2000_H #define IN2000_H -#include - - -#define uchar unsigned char - - -/* IN2000 io_port offsets */ -#define IO_WD_ASR 0x00 /* R - 3393 auxstat reg */ -#define ASR_INT 0x80 -#define ASR_LCI 0x40 -#define ASR_BSY 0x20 -#define ASR_CIP 0x10 -#define ASR_PE 0x02 -#define ASR_DBR 0x01 -#define IO_WD_ADDR 0x00 /* W - 3393 address reg */ -#define IO_WD_DATA 0x01 /* R/W - rest of 3393 regs */ -#define IO_FIFO 0x02 /* R/W - in2000 dual-port fifo (16 bits) */ -#define IN2000_FIFO_SIZE 2048 /* fifo capacity in bytes */ -#define IO_CARD_RESET 0x03 /* W - in2000 start master reset */ -#define IO_FIFO_COUNT 0x04 /* R - in2000 fifo counter */ -#define IO_FIFO_WRITE 0x05 /* W - clear fifo counter, start write */ -#define IO_FIFO_READ 0x07 /* W - start fifo read */ -#define IO_LED_OFF 0x08 /* W - turn off in2000 activity LED */ -#define IO_SWITCHES 0x08 /* R - read in2000 dip switch */ -#define SW_ADDR0 0x01 /* bit 0 = bit 0 of index to io addr */ -#define SW_ADDR1 0x02 /* bit 1 = bit 1 of index io addr */ -#define SW_DISINT 0x04 /* bit 2 true if ints disabled */ -#define SW_INT0 0x08 /* bit 3 = bit 0 of index to interrupt */ -#define SW_INT1 0x10 /* bit 4 = bit 1 of index to interrupt */ -#define SW_INT_SHIFT 3 /* shift right this amount to right justify int bits */ -#define SW_SYNC_DOS5 0x20 /* bit 5 used by Always BIOS */ -#define SW_FLOPPY 0x40 /* bit 6 true if floppy enabled */ -#define SW_BIT7 0x80 /* bit 7 hardwired true (ground) */ -#define IO_LED_ON 0x09 /* W - turn on in2000 activity LED */ -#define IO_HARDWARE 0x0a /* R - read in2000 hardware rev, stop reset */ -#define IO_INTR_MASK 0x0c /* W - in2000 interrupt mask reg */ -#define IMASK_WD 0x01 /* WD33c93 interrupt mask */ -#define IMASK_FIFO 0x02 /* FIFO interrupt mask */ - -/* wd register names */ -#define WD_OWN_ID 0x00 -#define WD_CONTROL 0x01 -#define WD_TIMEOUT_PERIOD 0x02 -#define WD_CDB_1 0x03 -#define WD_CDB_2 0x04 -#define WD_CDB_3 0x05 -#define WD_CDB_4 0x06 -#define WD_CDB_5 0x07 -#define WD_CDB_6 0x08 -#define WD_CDB_7 0x09 -#define WD_CDB_8 0x0a -#define WD_CDB_9 0x0b -#define WD_CDB_10 0x0c -#define WD_CDB_11 0x0d -#define WD_CDB_12 0x0e -#define WD_TARGET_LUN 0x0f -#define WD_COMMAND_PHASE 0x10 -#define WD_SYNCHRONOUS_TRANSFER 0x11 -#define WD_TRANSFER_COUNT_MSB 0x12 -#define WD_TRANSFER_COUNT 0x13 -#define WD_TRANSFER_COUNT_LSB 0x14 -#define WD_DESTINATION_ID 0x15 -#define WD_SOURCE_ID 0x16 -#define WD_SCSI_STATUS 0x17 -#define WD_COMMAND 0x18 -#define WD_DATA 0x19 -#define WD_QUEUE_TAG 0x1a -#define WD_AUXILIARY_STATUS 0x1f - -/* WD commands */ -#define WD_CMD_RESET 0x00 -#define WD_CMD_ABORT 0x01 -#define WD_CMD_ASSERT_ATN 0x02 -#define WD_CMD_NEGATE_ACK 0x03 -#define WD_CMD_DISCONNECT 0x04 -#define WD_CMD_RESELECT 0x05 -#define WD_CMD_SEL_ATN 0x06 -#define WD_CMD_SEL 0x07 -#define WD_CMD_SEL_ATN_XFER 0x08 -#define WD_CMD_SEL_XFER 0x09 -#define WD_CMD_RESEL_RECEIVE 0x0a -#define WD_CMD_RESEL_SEND 0x0b -#define WD_CMD_WAIT_SEL_RECEIVE 0x0c -#define WD_CMD_TRANS_ADDR 0x18 -#define WD_CMD_TRANS_INFO 0x20 -#define WD_CMD_TRANSFER_PAD 0x21 -#define WD_CMD_SBT_MODE 0x80 - -/* SCSI Bus Phases */ -#define PHS_DATA_OUT 0x00 -#define PHS_DATA_IN 0x01 -#define PHS_COMMAND 0x02 -#define PHS_STATUS 0x03 -#define PHS_MESS_OUT 0x06 -#define PHS_MESS_IN 0x07 - -/* Command Status Register definitions */ - - /* reset state interrupts */ -#define CSR_RESET 0x00 -#define CSR_RESET_AF 0x01 - - /* successful completion interrupts */ -#define CSR_RESELECT 0x10 -#define CSR_SELECT 0x11 -#define CSR_SEL_XFER_DONE 0x16 -#define CSR_XFER_DONE 0x18 - - /* paused or aborted interrupts */ -#define CSR_MSGIN 0x20 -#define CSR_SDP 0x21 -#define CSR_SEL_ABORT 0x22 -#define CSR_RESEL_ABORT 0x25 -#define CSR_RESEL_ABORT_AM 0x27 -#define CSR_ABORT 0x28 - - /* terminated interrupts */ -#define CSR_INVALID 0x40 -#define CSR_UNEXP_DISC 0x41 -#define CSR_TIMEOUT 0x42 -#define CSR_PARITY 0x43 -#define CSR_PARITY_ATN 0x44 -#define CSR_BAD_STATUS 0x45 -#define CSR_UNEXP 0x48 - - /* service required interrupts */ -#define CSR_RESEL 0x80 -#define CSR_RESEL_AM 0x81 -#define CSR_DISC 0x85 -#define CSR_SRV_REQ 0x88 - - /* Own ID/CDB Size register */ -#define OWNID_EAF 0x08 -#define OWNID_EHP 0x10 -#define OWNID_RAF 0x20 -#define OWNID_FS_8 0x00 -#define OWNID_FS_12 0x40 -#define OWNID_FS_16 0x80 - - /* Control register */ -#define CTRL_HSP 0x01 -#define CTRL_HA 0x02 -#define CTRL_IDI 0x04 -#define CTRL_EDI 0x08 -#define CTRL_HHP 0x10 -#define CTRL_POLLED 0x00 -#define CTRL_BURST 0x20 -#define CTRL_BUS 0x40 -#define CTRL_DMA 0x80 - - /* Timeout Period register */ -#define TIMEOUT_PERIOD_VALUE 20 /* results in 200 ms. */ - - /* Synchronous Transfer Register */ -#define STR_FSS 0x80 - - /* Destination ID register */ -#define DSTID_DPD 0x40 -#define DATA_OUT_DIR 0 -#define DATA_IN_DIR 1 -#define DSTID_SCC 0x80 - - /* Source ID register */ -#define SRCID_MASK 0x07 -#define SRCID_SIV 0x08 -#define SRCID_DSP 0x20 -#define SRCID_ES 0x40 -#define SRCID_ER 0x80 - - - -#define DEFAULT_SX_PER 500 /* (ns) fairly safe */ -#define DEFAULT_SX_OFF 0 /* aka async */ - -#define OPTIMUM_SX_PER 252 /* (ns) best we can do (mult-of-4) */ -#define OPTIMUM_SX_OFF 12 /* size of in2000 fifo */ - -struct sx_period { - unsigned int period_ns; - uchar reg_value; - }; - - -struct IN2000_hostdata { - struct Scsi_Host *next; - uchar chip; /* what kind of wd33c93 chip? */ - uchar microcode; /* microcode rev if 'B' */ - unsigned short io_base; /* IO port base */ - unsigned int dip_switch; /* dip switch settings */ - unsigned int hrev; /* hardware revision of card */ - volatile uchar busy[8]; /* index = target, bit = lun */ - volatile Scsi_Cmnd *input_Q; /* commands waiting to be started */ - volatile Scsi_Cmnd *selecting; /* trying to select this command */ - volatile Scsi_Cmnd *connected; /* currently connected command */ - volatile Scsi_Cmnd *disconnected_Q;/* commands waiting for reconnect */ - uchar state; /* what we are currently doing */ - uchar fifo; /* what the FIFO is up to */ - uchar level2; /* extent to which Level-2 commands are used */ - uchar disconnect; /* disconnect/reselect policy */ - unsigned int args; /* set from command-line argument */ - uchar incoming_msg[8]; /* filled during message_in phase */ - int incoming_ptr; /* mainly used with EXTENDED messages */ - uchar outgoing_msg[8]; /* send this during next message_out */ - int outgoing_len; /* length of outgoing message */ - unsigned int default_sx_per; /* default transfer period for SCSI bus */ - uchar sync_xfer[8]; /* sync_xfer reg settings per target */ - uchar sync_stat[8]; /* status of sync negotiation per target */ - uchar sync_off; /* bit mask: don't use sync with these targets */ - uchar proc; /* bit mask: what's in proc output */ - }; - - -/* defines for hostdata->chip */ - -#define C_WD33C93 0 -#define C_WD33C93A 1 -#define C_WD33C93B 2 -#define C_UNKNOWN_CHIP 100 - -/* defines for hostdata->state */ - -#define S_UNCONNECTED 0 -#define S_SELECTING 1 -#define S_RUNNING_LEVEL2 2 -#define S_CONNECTED 3 -#define S_PRE_TMP_DISC 4 -#define S_PRE_CMP_DISC 5 - -/* defines for hostdata->fifo */ - -#define FI_FIFO_UNUSED 0 -#define FI_FIFO_READING 1 -#define FI_FIFO_WRITING 2 - -/* defines for hostdata->level2 */ -/* NOTE: only the first 3 are trustworthy at this point - - * having trouble when more than 1 device is reading/writing - * at the same time... - */ - -#define L2_NONE 0 /* no combination commands - we get lots of ints */ -#define L2_SELECT 1 /* start with SEL_ATN_XFER, but never resume it */ -#define L2_BASIC 2 /* resume after STATUS ints & RDP messages */ -#define L2_DATA 3 /* resume after DATA_IN/OUT ints */ -#define L2_MOST 4 /* resume after anything except a RESELECT int */ -#define L2_RESELECT 5 /* resume after everything, including RESELECT ints */ -#define L2_ALL 6 /* always resume */ - -/* defines for hostdata->disconnect */ - -#define DIS_NEVER 0 -#define DIS_ADAPTIVE 1 -#define DIS_ALWAYS 2 - -/* defines for hostdata->args */ - -#define DB_TEST 1<<0 -#define DB_FIFO 1<<1 -#define DB_QUEUE_COMMAND 1<<2 -#define DB_EXECUTE 1<<3 -#define DB_INTR 1<<4 -#define DB_TRANSFER 1<<5 -#define DB_MASK 0x3f - -#define A_NO_SCSI_RESET 1<<15 - - -/* defines for hostdata->sync_xfer[] */ - -#define SS_UNSET 0 -#define SS_FIRST 1 -#define SS_WAITING 2 -#define SS_SET 3 - -/* defines for hostdata->proc */ - -#define PR_VERSION 1<<0 -#define PR_INFO 1<<1 -#define PR_TOTALS 1<<2 -#define PR_CONNECTED 1<<3 -#define PR_INPUTQ 1<<4 -#define PR_DISCQ 1<<5 -#define PR_TEST 1<<6 -#define PR_STOP 1<<7 - +extern struct proc_dir_entry proc_scsi_in2000; int in2000_detect(Scsi_Host_Template *); int in2000_queuecommand(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *)); int in2000_abort(Scsi_Cmnd *); void in2000_setup(char *, int *); int in2000_proc_info(char *, char **, off_t, int, int, int); -struct proc_dir_entry proc_scsi_in2000; int in2000_biosparam(struct scsi_disk *, kdev_t, int *); int in2000_reset(Scsi_Cmnd *, unsigned int); diff -u --recursive --new-file v2.1.30/linux/drivers/scsi/scsi.c linux/drivers/scsi/scsi.c --- v2.1.30/linux/drivers/scsi/scsi.c Mon Mar 17 14:54:30 1997 +++ linux/drivers/scsi/scsi.c Mon Mar 31 13:27:27 1997 @@ -277,11 +277,14 @@ {"INSITE","Floptical F*8I","*", BLIST_KEY}, {"INSITE","I325VM","*", BLIST_KEY}, {"NRC","MBR-7","*", BLIST_FORCELUN | BLIST_SINGLELUN}, +{"NRC","MBR-7.4","*", BLIST_FORCELUN | BLIST_SINGLELUN}, +{"NAKAMICH","MJ-4.8S","*", BLIST_FORCELUN | BLIST_SINGLELUN}, {"PIONEER","CD-ROM DRM-602X","*", BLIST_FORCELUN | BLIST_SINGLELUN}, {"PIONEER","CD-ROM DRM-604X","*", BLIST_FORCELUN | BLIST_SINGLELUN}, {"EMULEX","MD21/S2 ESDI","*", BLIST_SINGLELUN}, {"CANON","IPUBJD","*", BLIST_SPARSELUN}, {"MATSHITA","PD","*", BLIST_FORCELUN | BLIST_SINGLELUN}, +{"YAMAHA","CDR100","1.00", BLIST_NOLUN}, /* Locks up if polled for lun != 0 */ {"YAMAHA","CDR102","1.00", BLIST_NOLUN}, /* Locks up if polled for lun != 0 */ /* * Must be at end of list... @@ -1028,7 +1031,7 @@ host = device->host; - if (intr_count && SCSI_BLOCK(host)) return NULL; + if (in_interrupt() && SCSI_BLOCK(host)) return NULL; while (1==1){ if (!device->single_lun) { @@ -1243,12 +1246,12 @@ * interrupt. */ - if(!intr_count && SCpnt->host->irq) + if(!in_interrupt() && SCpnt->host->irq) disable_irq(SCpnt->host->irq); host->hostt->queuecommand (SCpnt, scsi_done); - if(!intr_count && SCpnt->host->irq) + if(!in_interrupt() && SCpnt->host->irq) enable_irq(SCpnt->host->irq); } else @@ -2897,7 +2900,9 @@ if (SDpnt->type == TYPE_WORM || SDpnt->type == TYPE_ROM) new_dma_sectors += (2048 >> 9) * SDpnt->queue_depth; } - else if (SDpnt->type == TYPE_SCANNER || SDpnt->type == TYPE_PROCESSOR) { + else if (SDpnt->type == TYPE_SCANNER || + SDpnt->type == TYPE_PROCESSOR || + SDpnt->type == TYPE_MEDIUM_CHANGER) { new_dma_sectors += (4096 >> 9) * SDpnt->queue_depth; } else { diff -u --recursive --new-file v2.1.30/linux/drivers/scsi/scsi.h linux/drivers/scsi/scsi.h --- v2.1.30/linux/drivers/scsi/scsi.h Mon Dec 30 03:01:10 1996 +++ linux/drivers/scsi/scsi.h Wed Apr 2 17:53:20 1997 @@ -550,7 +550,7 @@ for(;;) { \ current->state = TASK_UNINTERRUPTIBLE; \ if (CONDITION) { \ - if (intr_count) \ + if (in_interrupt()) \ panic("scsi: trying to call schedule() in interrupt" \ ", file %s, line %d.\n", __FILE__, __LINE__); \ schedule(); \ diff -u --recursive --new-file v2.1.30/linux/drivers/scsi/sd.c linux/drivers/scsi/sd.c --- v2.1.30/linux/drivers/scsi/sd.c Tue Mar 4 10:25:24 1997 +++ linux/drivers/scsi/sd.c Wed Apr 2 17:43:21 1997 @@ -147,7 +147,7 @@ return 0; } -static void sd_release(struct inode * inode, struct file * file) +static int sd_release(struct inode * inode, struct file * file) { int target; fsync_dev(inode->i_rdev); @@ -165,6 +165,7 @@ __MOD_DEC_USE_COUNT(rscsi_disks[target].device->host->hostt->module); if(sd_template.module) __MOD_DEC_USE_COUNT(sd_template.module); + return 0; } static void sd_geninit(struct gendisk *); @@ -491,7 +492,7 @@ * from user space, since we do not want to * sleep from an interrupt. */ - if( SDev->removable && !intr_count ) + if( SDev->removable && !in_interrupt() ) { scsi_ioctl(SDev, SCSI_IOCTL_DOORLOCK, 0); /* scsi_ioctl may allow CURRENT to change, so start over. */ diff -u --recursive --new-file v2.1.30/linux/drivers/scsi/sg.c linux/drivers/scsi/sg.c --- v2.1.30/linux/drivers/scsi/sg.c Sun Jan 26 02:07:21 1997 +++ linux/drivers/scsi/sg.c Wed Apr 2 17:43:21 1997 @@ -149,7 +149,7 @@ return 0; } -static void sg_close(struct inode * inode, struct file * filp) +static int sg_close(struct inode * inode, struct file * filp) { int dev=MINOR(inode->i_rdev); scsi_generics[dev].users--; @@ -159,6 +159,7 @@ __MOD_DEC_USE_COUNT(sg_template.module); scsi_generics[dev].exclude=0; wake_up(&scsi_generics[dev].generic_wait); + return 0; } static char *sg_malloc(int size) diff -u --recursive --new-file v2.1.30/linux/drivers/scsi/sr.c linux/drivers/scsi/sr.c --- v2.1.30/linux/drivers/scsi/sr.c Sun Jan 26 02:07:21 1997 +++ linux/drivers/scsi/sr.c Mon Mar 31 10:27:58 1997 @@ -423,7 +423,7 @@ * from user space, since we do not want to * sleep from an interrupt. */ - if( SDev->removable && !intr_count ) + if( SDev->removable && !in_interrupt() ) { scsi_ioctl(SDev, SCSI_IOCTL_DOORLOCK, 0); } diff -u --recursive --new-file v2.1.30/linux/drivers/scsi/st.c linux/drivers/scsi/st.c --- v2.1.30/linux/drivers/scsi/st.c Tue Mar 4 10:25:24 1997 +++ linux/drivers/scsi/st.c Wed Apr 2 17:43:22 1997 @@ -804,7 +804,7 @@ /* Close the device*/ - static void + static int scsi_tape_close(struct inode * inode, struct file * filp) { int result; @@ -923,7 +923,7 @@ if(st_template.module) __MOD_DEC_USE_COUNT(st_template.module); - return; + return 0; } @@ -2008,7 +2008,7 @@ arg - MT_ST_HPLOADER_OFFSET); } #endif - cmd[3] = arg; /* MediaID field of C1553A */ + cmd[3] = arg - MT_ST_HPLOADER_OFFSET; /* MediaID field of C1553A */ } #if ST_NOWAIT cmd[1] = 1; /* Don't wait for completion */ @@ -2975,6 +2975,7 @@ } +#ifndef MODULE /* Set the boot options. Syntax: st=xxx,yyy where xxx is buffer size in 1024 byte blocks and yyy is write threshold in 1024 byte blocks. */ @@ -2991,6 +2992,7 @@ if (ints[0] > 2 && ints[3] > 0) st_max_buffers = ints[3]; } +#endif static struct file_operations st_fops = { diff -u --recursive --new-file v2.1.30/linux/drivers/sound/soundcard.c linux/drivers/sound/soundcard.c --- v2.1.30/linux/drivers/sound/soundcard.c Tue Mar 4 10:25:25 1997 +++ linux/drivers/sound/soundcard.c Wed Apr 2 17:43:22 1997 @@ -127,7 +127,7 @@ return retval; } -static void +static int sound_release (struct inode *inode, struct file *file) { int dev; @@ -140,6 +140,7 @@ #ifdef MODULE MOD_DEC_USE_COUNT; #endif + return 0; } static int diff -u --recursive --new-file v2.1.30/linux/fs/Config.in linux/fs/Config.in --- v2.1.30/linux/fs/Config.in Tue Jan 14 02:59:10 1997 +++ linux/fs/Config.in Fri Mar 28 14:13:29 1997 @@ -37,6 +37,7 @@ tristate 'System V and Coherent filesystem support' CONFIG_SYSV_FS tristate 'Amiga FFS filesystem support' CONFIG_AFFS_FS tristate 'ROM filesystem support' CONFIG_ROMFS_FS +tristate 'Kernel automounter support (experimental)' CONFIG_AUTOFS_FS if [ "$CONFIG_AFFS_FS" != "n" ]; then define_bool CONFIG_AMIGA_PARTITION y fi diff -u --recursive --new-file v2.1.30/linux/fs/Makefile linux/fs/Makefile --- v2.1.30/linux/fs/Makefile Tue Jan 14 03:00:18 1997 +++ linux/fs/Makefile Fri Mar 28 15:07:55 1997 @@ -17,7 +17,7 @@ MOD_LIST_NAME := FS_MODULES ALL_SUB_DIRS = minix ext2 fat msdos vfat proc isofs nfs umsdos \ - hpfs sysv smbfs ncpfs ufs affs romfs + hpfs sysv smbfs ncpfs ufs affs romfs autofs ifeq ($(CONFIG_QUOTA),y) O_OBJS += dquot.o @@ -150,6 +150,14 @@ else ifeq ($(CONFIG_ROMFS_FS),m) MOD_SUB_DIRS += romfs + endif +endif + +ifeq ($(CONFIG_AUTOFS_FS),y) +SUB_DIRS += autofs +else + ifeq ($(CONFIG_AUTOFS_FS),m) + MOD_SUB_DIRS += autofs endif endif diff -u --recursive --new-file v2.1.30/linux/fs/affs/file.c linux/fs/affs/file.c --- v2.1.30/linux/fs/affs/file.c Sun Jan 26 02:07:24 1997 +++ linux/fs/affs/file.c Wed Apr 2 17:43:22 1997 @@ -42,7 +42,7 @@ static long affs_file_write_ofs(struct inode *inode, struct file *filp, const char *buf, unsigned long count); static int affs_open_file(struct inode *inode, struct file *filp); -static void affs_release_file(struct inode *inode, struct file *filp); +static int affs_release_file(struct inode *inode, struct file *filp); static struct file_operations affs_file_operations = { NULL, /* lseek - default */ @@ -883,7 +883,7 @@ return error; } -static void +static int affs_release_file(struct inode *inode, struct file *filp) { struct affs_zone *zone; @@ -913,4 +913,5 @@ } } unlock_super(inode->i_sb); + return 0; } diff -u --recursive --new-file v2.1.30/linux/fs/autofs/Makefile linux/fs/autofs/Makefile --- v2.1.30/linux/fs/autofs/Makefile Wed Dec 31 16:00:00 1969 +++ linux/fs/autofs/Makefile Fri Mar 28 14:12:45 1997 @@ -0,0 +1,16 @@ +# +# Makefile for the linux autofs-filesystem routines. +# +# Note! Dependencies are done automagically by 'make dep', which also +# removes any old dependencies. DON'T put your own dependencies here +# unless it's something special (ie not a .c file). +# +# Note 2! The CFLAGS definitions are now in the main makefile... +# + +O_TARGET := autofs.o +O_OBJS := dir.o dirhash.o init.o inode.o root.o symlink.o waitq.o + +M_OBJS := $(O_TARGET) + +include $(TOPDIR)/Rules.make diff -u --recursive --new-file v2.1.30/linux/fs/autofs/dir.c linux/fs/autofs/dir.c --- v2.1.30/linux/fs/autofs/dir.c Wed Dec 31 16:00:00 1969 +++ linux/fs/autofs/dir.c Fri Mar 28 14:12:45 1997 @@ -0,0 +1,91 @@ +/* -*- linux-c -*- --------------------------------------------------------- * + * + * linux/fs/autofs/dir.c + * + * Copyright 1997 Transmeta Corporation -- All Rights Reserved + * + * This file is part of the Linux kernel and is made available under + * the terms of the GNU General Public License, version 2, or at your + * option, any later version, incorporated herein by reference. + * + * ------------------------------------------------------------------------- */ + +#include +#include + +static int autofs_dir_readdir(struct inode *inode, struct file *filp, + void *dirent, filldir_t filldir) +{ + if (!inode || !S_ISDIR(inode->i_mode)) + return -ENOTDIR; + + switch((unsigned long) filp->f_pos) + { + case 0: + if (filldir(dirent, ".", 1, 0, inode->i_ino) < 0) + return 0; + filp->f_pos++; + /* fall through */ + case 1: + if (filldir(dirent, "..", 2, 1, AUTOFS_ROOT_INO) < 0) + return 0; + filp->f_pos++; + /* fall through */ + } + return 1; +} + +static int autofs_dir_lookup(struct inode *dir, const char *name, int len, + struct inode **result) +{ + *result = dir; + if (!len) + return 0; + if (name[0] == '.') { + if (len == 1) + return 0; + if (name[1] == '.' && len == 2) { + /* Return the root directory */ + *result = iget(dir->i_sb,AUTOFS_ROOT_INO); + iput(dir); + return 0; + } + } + *result = NULL; + iput(dir); + return -ENOENT; /* No other entries */ +} + +static struct file_operations autofs_dir_operations = { + NULL, /* lseek */ + NULL, /* read */ + NULL, /* write */ + autofs_dir_readdir, /* readdir */ + NULL, /* select */ + NULL, /* ioctl */ + NULL, /* mmap */ + NULL, /* open */ + NULL, /* release */ + NULL /* fsync */ +}; + +struct inode_operations autofs_dir_inode_operations = { + &autofs_dir_operations, /* file operations */ + NULL, /* create */ + autofs_dir_lookup, /* lookup */ + NULL, /* link */ + NULL, /* unlink */ + NULL, /* symlink */ + NULL, /* mkdir */ + NULL, /* rmdir */ + NULL, /* mknod */ + NULL, /* rename */ + NULL, /* readlink */ + NULL, /* follow_link */ + NULL, /* read_page */ + NULL, /* writepage */ + NULL, /* bmap */ + NULL, /* truncate */ + NULL /* permission */ +}; + diff -u --recursive --new-file v2.1.30/linux/fs/autofs/dirhash.c linux/fs/autofs/dirhash.c --- v2.1.30/linux/fs/autofs/dirhash.c Wed Dec 31 16:00:00 1969 +++ linux/fs/autofs/dirhash.c Fri Mar 28 14:12:45 1997 @@ -0,0 +1,130 @@ +/* -*- linux-c -*- --------------------------------------------------------- * + * + * linux/fs/autofs/dirhash.c + * + * Copyright 1997 Transmeta Corporation -- All Rights Reserved + * + * This file is part of the Linux kernel and is made available under + * the terms of the GNU General Public License, version 2, or at your + * option, any later version, incorporated herein by reference. + * + * ------------------------------------------------------------------------- */ + +#include +#include +#include +#include + +/* Adapted from the Dragon Book, page 436 */ +/* This particular hashing algorithm requires autofs_hash_t == u32 */ +autofs_hash_t autofs_hash(const char *name, int len) +{ + autofs_hash_t h = 0; + while ( len-- ) { + h = (h << 4) + (unsigned char) (*name++); + h ^= ((h & 0xf0000000) >> 24); + } + return h; +} + +void autofs_initialize_hash(struct autofs_dirhash *dh) { + memset(&dh->h, 0, AUTOFS_HASH_SIZE*sizeof(struct autofs_dir_ent *)); +} + +struct autofs_dir_ent *autofs_hash_lookup(const struct autofs_dirhash *dh, autofs_hash_t hash, const char *name, int len) +{ + struct autofs_dir_ent *dhn; + + DPRINTK(("autofs_hash_lookup: hash = 0x%08x, name = ", hash)); + autofs_say(name,len); + + for ( dhn = dh->h[hash % AUTOFS_HASH_SIZE] ; dhn ; dhn = dhn->next ) { + if ( hash == dhn->hash && + len == dhn->len && + !memcmp(name, dhn->name, len) ) + break; + } + + return dhn; +} + +void autofs_hash_insert(struct autofs_dirhash *dh, struct autofs_dir_ent *ent) +{ + struct autofs_dir_ent **dhnp; + + DPRINTK(("autofs_hash_insert: hash = 0x%08x, name = ", ent->hash)); + autofs_say(ent->name,ent->len); + + dhnp = &dh->h[ent->hash % AUTOFS_HASH_SIZE]; + ent->next = *dhnp; + ent->back = dhnp; + *dhnp = ent; +} + +void autofs_hash_delete(struct autofs_dir_ent *ent) +{ + *(ent->back) = ent->next; + kfree(ent->name); + kfree(ent); +} + +/* + * Used by readdir(). We must validate "ptr", so we can't simply make it + * a pointer. Values below 0xffff are reserved; calling with any value + * <= 0x10000 will return the first entry found. + */ +struct autofs_dir_ent *autofs_hash_enum(const struct autofs_dirhash *dh, off_t *ptr) +{ + int bucket, ecount, i; + struct autofs_dir_ent *ent; + + bucket = (*ptr >> 16) - 1; + ecount = *ptr & 0xffff; + + if ( bucket < 0 ) { + bucket = ecount = 0; + } + + DPRINTK(("autofs_hash_enum: bucket %d, entry %d\n", bucket, ecount)); + + ent = NULL; + + while ( bucket < AUTOFS_HASH_SIZE ) { + ent = dh->h[bucket]; + for ( i = ecount ; ent && i ; i-- ) + ent = ent->next; + + if (ent) { + ecount++; /* Point to *next* entry */ + break; + } + + bucket++; ecount = 0; + } + +#ifdef DEBUG + if ( !ent ) + printk("autofs_hash_enum: nothing found\n"); + else { + printk("autofs_hash_enum: found hash %08x, name", ent->hash); + autofs_say(ent->name,ent->len); + } +#endif + + *ptr = ((bucket+1) << 16) + ecount; + return ent; +} + +void autofs_hash_nuke(struct autofs_dirhash *dh) +{ + int i; + struct autofs_dir_ent *ent, *nent; + + for ( i = 0 ; i < AUTOFS_HASH_SIZE ; i++ ) { + for ( ent = dh->h[i] ; ent ; ent = nent ) { + nent = ent->next; + kfree(ent->name); + kfree(ent); + } + } +} diff -u --recursive --new-file v2.1.30/linux/fs/autofs/init.c linux/fs/autofs/init.c --- v2.1.30/linux/fs/autofs/init.c Wed Dec 31 16:00:00 1969 +++ linux/fs/autofs/init.c Fri Mar 28 15:12:16 1997 @@ -0,0 +1,50 @@ +/* -*- linux-c -*- --------------------------------------------------------- * + * + * linux/fs/autofs/init.c + * + * Copyright 1997 Transmeta Corporation -- All Rights Reserved + * + * This file is part of the Linux kernel and is made available under + * the terms of the GNU General Public License, version 2, or at your + * option, any later version, incorporated herein by reference. + * + * ------------------------------------------------------------------------- */ + +#include +#include +#include + +struct file_system_type autofs_fs_type = { + autofs_read_super, "autofs", 0, NULL +}; + +int init_autofs_fs(void) +{ + return register_filesystem(&autofs_fs_type); +} + +#ifdef MODULE +int init_module(void) +{ + int status; + + if ((status = init_autofs_fs()) == 0) + register_symtab(0); + return status; +} + +void cleanup_module(void) +{ + unregister_filesystem(&autofs_fs_type); +} +#endif + +#ifdef DEBUG +void autofs_say(const char *name, int len) +{ + printk("(%d: ", len); + while ( len-- ) + printk("%c", *name++); + printk(")\n"); +} +#endif diff -u --recursive --new-file v2.1.30/linux/fs/autofs/inode.c linux/fs/autofs/inode.c --- v2.1.30/linux/fs/autofs/inode.c Wed Dec 31 16:00:00 1969 +++ linux/fs/autofs/inode.c Fri Mar 28 14:12:45 1997 @@ -0,0 +1,273 @@ +/* -*- linux-c -*- --------------------------------------------------------- * + * + * linux/fs/autofs/inode.c + * + * Copyright 1997 Transmeta Corporation -- All Rights Reserved + * + * This file is part of the Linux kernel and is made available under + * the terms of the GNU General Public License, version 2, or at your + * option, any later version, incorporated herein by reference. + * + * ------------------------------------------------------------------------- */ + +#include +#include +#include +#include +#include +#include +#include +#define __NO_VERSION__ +#include + +static void autofs_put_inode(struct inode *inode) +{ + if (inode->i_nlink) + return; + inode->i_size = 0; +} + +static void autofs_put_super(struct super_block *sb) +{ + struct autofs_sb_info *sbi; + unsigned int n; + + lock_super(sb); + sbi = (struct autofs_sb_info *) sb->u.generic_sbp; + autofs_hash_nuke(&sbi->dirhash); + for ( n = 0 ; n < AUTOFS_MAX_SYMLINKS ; n++ ) { + if ( test_bit(n, sbi->symlink_bitmap) ) + kfree(sbi->symlink[n].data); + } + fput(sbi->pipe, sbi->pipe->f_inode); + + sb->s_dev = 0; + kfree(sb->u.generic_sbp); + unlock_super(sb); + + DPRINTK(("autofs: shutting down\n")); + +#ifdef MODULE + MOD_DEC_USE_COUNT; +#endif +} + +static void autofs_statfs(struct super_block *sb, struct statfs *buf, int bufsiz); +static void autofs_read_inode(struct inode *inode); +static void autofs_write_inode(struct inode *inode); + +static struct super_operations autofs_sops = { + autofs_read_inode, + NULL, + autofs_write_inode, + autofs_put_inode, + autofs_put_super, + NULL, + autofs_statfs, + NULL +}; + +static int parse_options(char *options, int *pipefd, uid_t *uid, gid_t *gid, pid_t *pgrp, int *minproto, int *maxproto) +{ + char *this_char, *value; + + *uid = current->uid; + *gid = current->gid; + *pgrp = current->pgrp; + + *minproto = *maxproto = AUTOFS_PROTO_VERSION; + + *pipefd = -1; + + if ( !options ) return 1; + for (this_char = strtok(options,","); this_char; this_char = strtok(NULL,",")) { + if ((value = strchr(this_char,'=')) != NULL) + *value++ = 0; + if (!strcmp(this_char,"fd")) { + if (!value || !*value) + return 1; + *pipefd = simple_strtoul(value,&value,0); + if (*value) + return 1; + } + else if (!strcmp(this_char,"uid")) { + if (!value || !*value) + return 1; + *uid = simple_strtoul(value,&value,0); + if (*value) + return 1; + } + else if (!strcmp(this_char,"gid")) { + if (!value || !*value) + return 1; + *gid = simple_strtoul(value,&value,0); + if (*value) + return 1; + } + else if (!strcmp(this_char,"pgrp")) { + if (!value || !*value) + return 1; + *pgrp = simple_strtoul(value,&value,0); + if (*value) + return 1; + } + else if (!strcmp(this_char,"minproto")) { + if (!value || !*value) + return 1; + *minproto = simple_strtoul(value,&value,0); + if (*value) + return 1; + } + else if (!strcmp(this_char,"maxproto")) { + if (!value || !*value) + return 1; + *maxproto = simple_strtoul(value,&value,0); + if (*value) + return 1; + } + else break; + } + return (*pipefd < 0); +} + +struct super_block *autofs_read_super(struct super_block *s, void *data, + int silent) +{ + int pipefd; + struct autofs_sb_info *sbi; + int minproto, maxproto; + + MOD_INC_USE_COUNT; + + lock_super(s); + sbi = (struct autofs_sb_info *) kmalloc(sizeof(struct autofs_sb_info), GFP_KERNEL); + if ( !sbi ) { + s->s_dev = 0; + return NULL; + } + DPRINTK(("autofs: starting up, sbi = %p\n",sbi)); + + s->u.generic_sbp = sbi; + sbi->catatonic = 0; + sbi->oz_pgrp = current->pgrp; + autofs_initialize_hash(&sbi->dirhash); + sbi->queues = NULL; + memset(sbi->symlink_bitmap, 0, sizeof(u32)*AUTOFS_SYMLINK_BITMAP_LEN); + sbi->next_dir_ino = AUTOFS_FIRST_DIR_INO; + s->s_blocksize = 1024; + s->s_blocksize_bits = 10; + s->s_magic = AUTOFS_SUPER_MAGIC; + s->s_op = &autofs_sops; + unlock_super(s); + if (!(s->s_mounted = iget(s, AUTOFS_ROOT_INO))) { + s->s_dev = 0; + kfree(sbi); + printk("autofs: get root inode failed\n"); + MOD_DEC_USE_COUNT; + return NULL; + } + + if ( parse_options(data,&pipefd,&s->s_mounted->i_uid,&s->s_mounted->i_gid,&sbi->oz_pgrp,&minproto,&maxproto) ) { + iput(s->s_mounted); + s->s_dev = 0; + kfree(sbi); + printk("autofs: called with bogus options\n"); + MOD_DEC_USE_COUNT; + return NULL; + } + + if ( minproto > AUTOFS_PROTO_VERSION || maxproto < AUTOFS_PROTO_VERSION ) { + iput(s->s_mounted); + s->s_dev = 0; + kfree(sbi); + printk("autofs: kernel does not match daemon version\n"); + MOD_DEC_USE_COUNT; + return NULL; + } + + DPRINTK(("autofs: pipe fd = %d, pgrp = %u\n", pipefd, sbi->oz_pgrp)); + sbi->pipe = fget(pipefd); + if ( !sbi->pipe || !sbi->pipe->f_op || !sbi->pipe->f_op->write ) { + if ( sbi->pipe ) { + fput(sbi->pipe, sbi->pipe->f_inode); + printk("autofs: pipe file descriptor does not contain proper ops\n"); + } else { + printk("autofs: could not open pipe file descriptor\n"); + } + iput(s->s_mounted); + s->s_dev = 0; + kfree(sbi); + MOD_DEC_USE_COUNT; + return NULL; + } + return s; +} + +static void autofs_statfs(struct super_block *sb, struct statfs *buf, int bufsiz) +{ + struct statfs tmp; + + tmp.f_type = AUTOFS_SUPER_MAGIC; + tmp.f_bsize = PAGE_SIZE/sizeof(long); + tmp.f_blocks = 0; + tmp.f_bfree = 0; + tmp.f_bavail = 0; + tmp.f_files = 0; + tmp.f_ffree = 0; + tmp.f_namelen = NAME_MAX; + copy_to_user(buf, &tmp, bufsiz); +} + +static void autofs_read_inode(struct inode *inode) +{ + ino_t ino = inode->i_ino; + unsigned int n; + struct autofs_sb_info *sbi = + (struct autofs_sb_info *) inode->i_sb->u.generic_sbp; + + inode->i_op = NULL; + inode->i_mode = 0; + inode->i_nlink = 2; + inode->i_size = 0; + inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME; + inode->i_blocks = 0; + inode->i_blksize = 1024; + + if ( ino == AUTOFS_ROOT_INO ) { + inode->i_mode = S_IFDIR | S_IRUGO | S_IXUGO | S_IWUSR; + inode->i_op = &autofs_root_inode_operations; + inode->i_uid = inode->i_gid = 0; /* Changed in read_super */ + return; + } + + inode->i_uid = inode->i_sb->s_mounted->i_uid; + inode->i_gid = inode->i_sb->s_mounted->i_gid; + + if ( ino >= AUTOFS_FIRST_SYMLINK && ino < AUTOFS_FIRST_DIR_INO ) { + /* Symlink inode - should be in symlink list */ + struct autofs_symlink *sl; + + n = ino - AUTOFS_FIRST_SYMLINK; + if ( n >= AUTOFS_MAX_SYMLINKS || !test_bit(n,sbi->symlink_bitmap)) { + printk("autofs: Looking for bad symlink inode 0x%08x\n", (unsigned int) ino); + return; + } + + inode->i_op = &autofs_symlink_inode_operations; + sl = &sbi->symlink[n]; + inode->u.generic_ip = sl; + inode->i_mode = S_IFLNK | S_IRWXUGO; + inode->i_mtime = inode->i_ctime = sl->mtime; + inode->i_size = sl->len; + inode->i_nlink = 1; + } else { + /* All non-root directory inodes look the same */ + inode->i_op = &autofs_dir_inode_operations; + inode->i_mode = S_IFDIR | S_IRUGO | S_IXUGO; + } +} + +static void autofs_write_inode(struct inode *inode) +{ + inode->i_dirt = 0; +} diff -u --recursive --new-file v2.1.30/linux/fs/autofs/root.c linux/fs/autofs/root.c --- v2.1.30/linux/fs/autofs/root.c Wed Dec 31 16:00:00 1969 +++ linux/fs/autofs/root.c Fri Mar 28 14:12:45 1997 @@ -0,0 +1,363 @@ +/* -*- linux-c -*- --------------------------------------------------------- * + * + * linux/fs/autofs/root.c + * + * Copyright 1997 Transmeta Corporation -- All Rights Reserved + * + * This file is part of the Linux kernel and is made available under + * the terms of the GNU General Public License, version 2, or at your + * option, any later version, incorporated herein by reference. + * + * ------------------------------------------------------------------------- */ + +#include +#include +#include +#include +#include +#include + +static int autofs_root_readdir(struct inode *,struct file *,void *,filldir_t); +static int autofs_root_lookup(struct inode *,const char *,int,struct inode **); +static int autofs_root_symlink(struct inode *,const char *,int,const char *); +static int autofs_root_unlink(struct inode *,const char *,int); +static int autofs_root_rmdir(struct inode *,const char *,int); +static int autofs_root_mkdir(struct inode *,const char *,int,int); +static int autofs_root_ioctl(struct inode *, struct file *,unsigned int,unsigned long); + +static struct file_operations autofs_root_operations = { + NULL, /* lseek */ + NULL, /* read */ + NULL, /* write */ + autofs_root_readdir, /* readdir */ + NULL, /* select */ + autofs_root_ioctl, /* ioctl */ + NULL, /* mmap */ + NULL, /* open */ + NULL, /* release */ + NULL /* fsync */ +}; + +struct inode_operations autofs_root_inode_operations = { + &autofs_root_operations, /* file operations */ + NULL, /* create */ + autofs_root_lookup, /* lookup */ + NULL, /* link */ + autofs_root_unlink, /* unlink */ + autofs_root_symlink, /* symlink */ + autofs_root_mkdir, /* mkdir */ + autofs_root_rmdir, /* rmdir */ + NULL, /* mknod */ + NULL, /* rename */ + NULL, /* readlink */ + NULL, /* follow_link */ + NULL, /* readpage */ + NULL, /* writepage */ + NULL, /* bmap */ + NULL, /* truncate */ + NULL /* permission */ +}; + +static int autofs_root_readdir(struct inode *inode, struct file *filp, + void *dirent, filldir_t filldir) +{ + struct autofs_dir_ent *ent; + struct autofs_dirhash *dirhash; + off_t onr, nr; + + if (!inode || !S_ISDIR(inode->i_mode)) + return -ENOTDIR; + + dirhash = &((struct autofs_sb_info *)inode->i_sb->u.generic_sbp)->dirhash; + nr = filp->f_pos; + + switch(nr) + { + case 0: + if (filldir(dirent, ".", 1, nr, inode->i_ino) < 0) + return 0; + filp->f_pos = ++nr; + /* fall through */ + case 1: + if (filldir(dirent, "..", 2, nr, inode->i_ino) < 0) + return 0; + filp->f_pos = ++nr; + /* fall through */ + default: + while ( onr = nr, ent = autofs_hash_enum(dirhash,&nr) ) { + if (filldir(dirent,ent->name,ent->len,onr,ent->ino) < 0) + return 0; + filp->f_pos = nr; + } + break; + } + + return 0; +} + +static int autofs_root_lookup(struct inode *dir, const char *name, int len, + struct inode **result) +{ + struct autofs_sb_info *sbi; + struct autofs_dir_ent *ent; + struct inode *res; + autofs_hash_t hash; + int status, oz_mode; + + DPRINTK(("autofs_root_lookup: name = ")); + autofs_say(name,len); + + *result = NULL; + if (!dir) + return -ENOENT; + if (!S_ISDIR(dir->i_mode)) { + iput(dir); + return -ENOTDIR; + } + + /* Handle special cases: . and ..; since this is a root directory, + they both point to the inode itself */ + *result = dir; + if (!len) + return 0; + if (name[0] == '.') { + if (len == 1) + return 0; + if (name[1] == '.' && len == 2) + return 0; + } + + *result = res = NULL; + sbi = (struct autofs_sb_info *) dir->i_sb->u.generic_sbp; + + hash = autofs_hash(name,len); + + oz_mode = autofs_oz_mode(sbi); + DPRINTK(("autofs_lookup: pid = %u, pgrp = %u, catatonic = %d, oz_mode = %d\n", current->pid, current->pgrp, sbi->catatonic, oz_mode)); + + do { + while ( !(ent = autofs_hash_lookup(&sbi->dirhash,hash,name,len)) ) { + DPRINTK(("lookup failed, pid = %u, pgrp = %u\n", current->pid, current->pgrp)); + + if ( oz_mode ) { + iput(dir); + return -ENOENT; + } else { + status = autofs_wait(sbi,hash,name,len); + DPRINTK(("autofs_wait returned %d\n", status)); + if ( status ) { + iput(dir); + return status; + } + } + } + + DPRINTK(("lookup successful, inode = %08x\n", (unsigned int)ent->ino)); + + if (!(res = iget(dir->i_sb,ent->ino))) { + printk("autofs: iget returned null!\n"); + iput(dir); + return -EACCES; + } + + if ( !oz_mode && S_ISDIR(res->i_mode) && res->i_sb == dir->i_sb ) { + /* Not a mount point yet, call 1-800-DAEMON */ + DPRINTK(("autofs: waiting on non-mountpoint dir, inode = %lu, pid = %u, pgrp = %u\n", res->i_ino, current->pid, current->pgrp)); + iput(res); + res = NULL; + status = autofs_wait(sbi,hash,name,len); + if ( status ) { + iput(dir); + return status; + } + } + } while(!res); + + *result = res; + iput(dir); + return 0; +} + +static int autofs_root_symlink(struct inode *dir, const char *name, int len, const char *symname) +{ + struct autofs_sb_info *sbi = (struct autofs_sb_info *) dir->i_sb->u.generic_sbp; + struct autofs_dirhash *dh = &sbi->dirhash; + autofs_hash_t hash = autofs_hash(name,len); + struct autofs_dir_ent *ent; + unsigned int n; + int slsize; + struct autofs_symlink *sl; + + DPRINTK(("autofs_root_symlink: %s <- ", symname)); + autofs_say(name,len); + + iput(dir); + + if ( !autofs_oz_mode(sbi) ) + return -EPERM; + + if ( autofs_hash_lookup(dh,hash,name,len) ) + return -EEXIST; + + n = find_first_zero_bit(sbi->symlink_bitmap,AUTOFS_MAX_SYMLINKS); + if ( n >= AUTOFS_MAX_SYMLINKS ) + return -ENOSPC; + + set_bit(n,sbi->symlink_bitmap); + sl = &sbi->symlink[n]; + sl->len = strlen(symname); + sl->data = kmalloc(slsize = sl->len+1, GFP_KERNEL); + if ( !sl->data ) { + clear_bit(n,sbi->symlink_bitmap); + return -ENOSPC; + } + ent = kmalloc(sizeof(struct autofs_dir_ent), GFP_KERNEL); + if ( !ent ) { + kfree(sl->data); + clear_bit(n,sbi->symlink_bitmap); + return -ENOSPC; + } + ent->name = kmalloc(len, GFP_KERNEL); + if ( !ent->name ) { + kfree(sl->data); + kfree(ent); + clear_bit(n,sbi->symlink_bitmap); + return -ENOSPC; + } + memcpy(sl->data,symname,slsize); + sl->mtime = CURRENT_TIME; + + ent->ino = AUTOFS_FIRST_SYMLINK + n; + ent->hash = hash; + memcpy(ent->name,name,ent->len = len); + ent->expiry = END_OF_TIME; + + autofs_hash_insert(dh,ent); + + return 0; +} + +static int autofs_root_unlink(struct inode *dir, const char *name, int len) +{ + struct autofs_sb_info *sbi = (struct autofs_sb_info *) dir->i_sb->u.generic_sbp; + struct autofs_dirhash *dh = &sbi->dirhash; + autofs_hash_t hash = autofs_hash(name,len); + struct autofs_dir_ent *ent; + unsigned int n; + + if ( !autofs_oz_mode(sbi) ) + return -EPERM; + + ent = autofs_hash_lookup(dh,hash,name,len); + if ( !ent ) + return -ENOENT; + n = ent->ino - AUTOFS_FIRST_SYMLINK; + if ( n >= AUTOFS_MAX_SYMLINKS || !test_bit(n,sbi->symlink_bitmap) ) + return -EINVAL; /* Not a symlink inode, can't unlink */ + autofs_hash_delete(ent); + clear_bit(n,sbi->symlink_bitmap); + kfree(sbi->symlink[n].data); + + return 0; +} + +static int autofs_root_rmdir(struct inode *dir, const char *name, int len) +{ + struct autofs_sb_info *sbi = (struct autofs_sb_info *) dir->i_sb->u.generic_sbp; + struct autofs_dirhash *dh = &sbi->dirhash; + autofs_hash_t hash = autofs_hash(name,len); + struct autofs_dir_ent *ent; + + if ( !autofs_oz_mode(sbi) ) { + iput(dir); + return -EPERM; + } + ent = autofs_hash_lookup(dh,hash,name,len); + if ( !ent ) { + iput(dir); + return -ENOENT; + } + if ( (unsigned int)ent->ino < AUTOFS_FIRST_DIR_INO ) { + iput(dir); + return -ENOTDIR; /* Not a directory */ + } + autofs_hash_delete(ent); + dir->i_nlink--; + iput(dir); + + return 0; +} + +static int autofs_root_mkdir(struct inode *dir, const char *name, int len, int mode) +{ + struct autofs_sb_info *sbi = (struct autofs_sb_info *) dir->i_sb->u.generic_sbp; + struct autofs_dirhash *dh = &sbi->dirhash; + autofs_hash_t hash = autofs_hash(name,len); + struct autofs_dir_ent *ent; + + if ( !autofs_oz_mode(sbi) ) { + iput(dir); + return -EPERM; + } + ent = autofs_hash_lookup(dh,hash,name,len); + if ( ent ) { + iput(dir); + return -EEXIST; + } + if ( sbi->next_dir_ino < AUTOFS_FIRST_DIR_INO ) { + printk("autofs: Out of inode numbers -- what the heck did you do??\n"); + iput(dir); + return -ENOSPC; + } + ent = kmalloc(sizeof(struct autofs_dir_ent), GFP_KERNEL); + if ( !ent ) { + iput(dir); + return -ENOSPC; + } + ent->name = kmalloc(len, GFP_KERNEL); + if ( !ent->name ) { + kfree(ent); + iput(dir); + return -ENOSPC; + } + ent->hash = hash; + memcpy(ent->name, name, ent->len = len); + ent->ino = sbi->next_dir_ino++; + ent->expiry = END_OF_TIME; + autofs_hash_insert(dh,ent); + dir->i_nlink++; + iput(dir); + + return 0; +} + +/* + * ioctl()'s on the root directory is the chief method for the daemon to + * generate kernel reactions + */ +static int autofs_root_ioctl(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg) +{ + struct autofs_sb_info *sbi = (struct autofs_sb_info *)inode->i_sb->u.generic_sbp; + + DPRINTK(("autofs_ioctl: cmd = %04x, arg = 0x%08lx, sbi = %p, pgrp = %u\n",cmd,arg,sbi,current->pgrp)); + + switch(cmd) { + case AUTOFS_IOC_READY: /* Wait queue: go ahead and retry */ + if ( !autofs_oz_mode(sbi) && !fsuser() ) + return -EPERM; + return autofs_wait_release(sbi,arg,0); + case AUTOFS_IOC_FAIL: /* Wait queue: fail with ENOENT */ + /* Optional: add to failure cache */ + if ( !autofs_oz_mode(sbi) && !fsuser() ) + return -EPERM; + return autofs_wait_release(sbi,arg,-ENOENT); + case AUTOFS_IOC_CATATONIC: /* Enter catatonic mode (daemon shutdown) */ + if ( !autofs_oz_mode(sbi) && !fsuser() ) + return -EPERM; + autofs_catatonic_mode(sbi); + return 0; + default: + return -ENOTTY; /* Should this be ENOSYS? */ + } +} diff -u --recursive --new-file v2.1.30/linux/fs/autofs/symlink.c linux/fs/autofs/symlink.c --- v2.1.30/linux/fs/autofs/symlink.c Wed Dec 31 16:00:00 1969 +++ linux/fs/autofs/symlink.c Fri Mar 28 14:12:45 1997 @@ -0,0 +1,86 @@ +/* -*- linux-c -*- --------------------------------------------------------- * + * + * linux/fs/autofs/symlink.c + * + * Copyright 1997 Transmeta Corporation -- All Rights Reserved + * + * This file is part of the Linux kernel and is made available under + * the terms of the GNU General Public License, version 2, or at your + * option, any later version, incorporated herein by reference. + * + * ------------------------------------------------------------------------- */ + +#include +#include +#include +#include + +static int autofs_follow_link(struct inode *dir, struct inode *inode, + int flag, int mode, struct inode **res_inode) +{ + int error; + char *link; + + *res_inode = NULL; + if (!dir) { + dir = current->fs->root; + dir->i_count++; + } + if (!inode) { + iput(dir); + return -ENOENT; + } + if (!S_ISLNK(inode->i_mode)) { + iput(dir); + *res_inode = inode; + return 0; + } + if (current->link_count > 5) { + iput(dir); + iput(inode); + return -ELOOP; + } + link = ((struct autofs_symlink *)inode->u.generic_ip)->data; + current->link_count++; + error = open_namei(link,flag,mode,res_inode,dir); + current->link_count--; + iput(inode); + return error; +} + +static int autofs_readlink(struct inode *inode, char *buffer, int buflen) +{ + struct autofs_symlink *sl; + int len; + + if (!S_ISLNK(inode->i_mode)) { + iput(inode); + return -EINVAL; + } + sl = (struct autofs_symlink *)inode->u.generic_ip; + len = sl->len; + if (len > buflen) len = buflen; + copy_to_user(buffer,sl->data,len); + iput(inode); + return len; +} + +struct inode_operations autofs_symlink_inode_operations = { + NULL, /* file operations */ + NULL, /* create */ + NULL, /* lookup */ + NULL, /* link */ + NULL, /* unlink */ + NULL, /* symlink */ + NULL, /* mkdir */ + NULL, /* rmdir */ + NULL, /* mknod */ + NULL, /* rename */ + autofs_readlink, /* readlink */ + autofs_follow_link, /* follow_link */ + NULL, /* readpage */ + NULL, /* writepage */ + NULL, /* bmap */ + NULL, /* truncate */ + NULL /* permission */ +}; diff -u --recursive --new-file v2.1.30/linux/fs/autofs/waitq.c linux/fs/autofs/waitq.c --- v2.1.30/linux/fs/autofs/waitq.c Wed Dec 31 16:00:00 1969 +++ linux/fs/autofs/waitq.c Fri Mar 28 14:12:45 1997 @@ -0,0 +1,152 @@ +/* -*- linux-c -*- --------------------------------------------------------- * + * + * linux/fs/autofs/waitq.c + * + * Copyright 1997 Transmeta Corporation -- All Rights Reserved + * + * This file is part of the Linux kernel and is made available under + * the terms of the GNU General Public License, version 2, or at your + * option, any later version, incorporated herein by reference. + * + * ------------------------------------------------------------------------- */ + +#include +#include +#include + +/* We make this a static variable rather than a part of the superblock; it + is better if we don't reassign numbers easily even across filesystems */ +static int autofs_next_wait_queue = 1; + +void autofs_catatonic_mode(struct autofs_sb_info *sbi) +{ + struct autofs_wait_queue *wq, *nwq; + + DPRINTK(("autofs: entering catatonic mode\n")); + + sbi->catatonic = 1; + wq = sbi->queues; + sbi->queues = NULL; /* Erase all wait queues */ + while ( wq ) { + nwq = wq->next; + wq->status = -ENOENT; /* Magic is gone - report failure */ + kfree(wq->name); + wq->name = NULL; + wake_up(&wq->queue); + wq = nwq; + } +} + +static int autofs_write(struct file *file, const void *addr, int bytes) +{ + unsigned short fs; + const char *data = (const char *)addr; + int written; + + /** WARNING: this is not safe for writing more than PIPE_BUF bytes! **/ + + /* Save pointer to user space and point back to kernel space */ + fs = get_fs(); + set_fs(KERNEL_DS); + + while ( bytes && (written = file->f_op->write(file->f_inode,file,data,bytes)) > 0 ) { + data += written; + bytes -= written; + } + set_fs(fs); + + return (bytes > 0); +} + +static void autofs_notify_daemon(struct autofs_sb_info *sbi, struct autofs_wait_queue *wq) +{ + struct autofs_packet_missing pkt; + + DPRINTK(("autofs_wait: wait id = 0x%08lx, name = ", wq->wait_queue_token)); + autofs_say(wq->name,wq->len); + + pkt.hdr.proto_version = AUTOFS_PROTO_VERSION; + pkt.hdr.type = autofs_ptype_missing; + pkt.wait_queue_token = wq->wait_queue_token; + pkt.len = wq->len; + memcpy(pkt.name, wq->name, pkt.len); + pkt.name[pkt.len] = '\0'; + + if ( autofs_write(sbi->pipe,&pkt,sizeof(struct autofs_packet_missing)) ) + autofs_catatonic_mode(sbi); +} + +int autofs_wait(struct autofs_sb_info *sbi, autofs_hash_t hash, const char *name, int len) +{ + struct autofs_wait_queue *wq; + int status; + + for ( wq = sbi->queues ; wq ; wq = wq->next ) { + if ( wq->hash == hash && + wq->len == len && + !memcmp(wq->name,name,len) ) + break; + } + + if ( !wq ) { + /* Create a new wait queue */ + wq = kmalloc(sizeof(struct autofs_wait_queue),GFP_KERNEL); + if ( !wq ) + return -ENOMEM; + + wq->name = kmalloc(len,GFP_KERNEL); + if ( !wq->name ) { + kfree(wq); + return -ENOMEM; + } + wq->wait_queue_token = autofs_next_wait_queue++; + init_waitqueue(&wq->queue); + wq->hash = hash; + wq->len = len; + memcpy(wq->name, name, len); + wq->next = sbi->queues; + sbi->queues = wq; + + /* autofs_notify_daemon() may block */ + wq->wait_ctr++; + autofs_notify_daemon(sbi,wq); + } else + wq->wait_ctr++; + + if ( wq->name ) { + /* wq->name is NULL if and only if the lock is released */ + interruptible_sleep_on(&wq->queue); + } else { + DPRINTK(("autofs_wait: skipped sleeping\n")); + } + + status = (current->signal & ~current->blocked) ? -EINTR : wq->status; + if ( ! --wq->wait_ctr ) /* Are we the last process to need status? */ + kfree(wq); + + return status; +} + + +int autofs_wait_release(struct autofs_sb_info *sbi, unsigned long wait_queue_token, int status) +{ + struct autofs_wait_queue *wq, **wql; + + for ( wql = &sbi->queues ; (wq = *wql) ; wql = &wq->next ) { + if ( wq->wait_queue_token == wait_queue_token ) + break; + } + if ( !wq ) + return -EINVAL; + + *wql = wq->next; /* Unlink from chain */ + kfree(wq->name); + wq->name = NULL; /* Do not wait on this queue */ + + wq->status = status; + + wake_up(&wq->queue); + + return 0; +} + diff -u --recursive --new-file v2.1.30/linux/fs/devices.c linux/fs/devices.c --- v2.1.30/linux/fs/devices.c Sat Jan 25 13:46:13 1997 +++ linux/fs/devices.c Wed Apr 2 17:43:22 1997 @@ -235,11 +235,12 @@ return ret; } -void blkdev_release(struct inode * inode) +int blkdev_release(struct inode * inode) { struct file_operations *fops = get_blkfops(MAJOR(inode->i_rdev)); if (fops && fops->release) - fops->release(inode,NULL); + return fops->release(inode,NULL); + return 0; } diff -u --recursive --new-file v2.1.30/linux/fs/ext2/file.c linux/fs/ext2/file.c --- v2.1.30/linux/fs/ext2/file.c Sun Jan 26 02:07:43 1997 +++ linux/fs/ext2/file.c Wed Apr 2 17:43:22 1997 @@ -38,7 +38,7 @@ static long long ext2_file_lseek(struct inode *, struct file *, long long, int); static long ext2_file_write (struct inode *, struct file *, const char *, unsigned long); -static void ext2_release_file (struct inode *, struct file *); +static int ext2_release_file (struct inode *, struct file *); /* * We have mostly NULL's here: the current defaults are ok for @@ -260,8 +260,9 @@ * from ext2_open: open gets called at every open, but release * gets called only when /all/ the files are closed. */ -static void ext2_release_file (struct inode * inode, struct file * filp) +static int ext2_release_file (struct inode * inode, struct file * filp) { if (filp->f_mode & 2) ext2_discard_prealloc (inode); + return 0; } diff -u --recursive --new-file v2.1.30/linux/fs/ext2/fsync.c linux/fs/ext2/fsync.c --- v2.1.30/linux/fs/ext2/fsync.c Thu Nov 14 00:27:37 1996 +++ linux/fs/ext2/fsync.c Mon Mar 31 12:52:31 1997 @@ -13,10 +13,15 @@ * * Big-endian to little-endian byte-swapping/bitmaps by * David S. Miller (davem@caip.rutgers.edu), 1995 + * + * Removed unnecessary code duplication for little endian machines + * and excessive __inline__s. + * Andi Kleen, 1997 */ #include #include +#include #include #include @@ -30,7 +35,7 @@ #define blocksize (EXT2_BLOCK_SIZE(inode->i_sb)) #define addr_per_block (EXT2_ADDR_PER_BLOCK(inode->i_sb)) -static __inline__ int sync_block (struct inode * inode, u32 * block, int wait) +static int sync_block (struct inode * inode, u32 * block, int wait) { struct buffer_head * bh; int tmp; @@ -58,7 +63,8 @@ return 0; } -static __inline__ int sync_block_swab32 (struct inode * inode, u32 * block, int wait) +#ifndef __LITTLE_ENDIAN +static int sync_block_swab32 (struct inode * inode, u32 * block, int wait) { struct buffer_head * bh; int tmp; @@ -85,8 +91,12 @@ bh->b_count--; return 0; } +#else +#define sync_block_swab32 sync_block +#endif -static __inline__ int sync_iblock (struct inode * inode, u32 * iblock, + +static int sync_iblock (struct inode * inode, u32 * iblock, struct buffer_head ** bh, int wait) { int rc, tmp; @@ -109,7 +119,8 @@ return 0; } -static __inline__ int sync_iblock_swab32 (struct inode * inode, u32 * iblock, +#ifndef __LITTLE_ENDIAN +static int sync_iblock_swab32 (struct inode * inode, u32 * iblock, struct buffer_head ** bh, int wait) { int rc, tmp; @@ -131,9 +142,11 @@ return -1; return 0; } +#else +#define sync_iblock_swab32 sync_iblock +#endif - -static __inline__ int sync_direct (struct inode * inode, int wait) +static int sync_direct (struct inode * inode, int wait) { int i; int rc, err = 0; @@ -148,7 +161,7 @@ return err; } -static __inline__ int sync_indirect (struct inode * inode, u32 * iblock, int wait) +static int sync_indirect (struct inode * inode, u32 * iblock, int wait) { int i; struct buffer_head * ind_bh; @@ -171,6 +184,7 @@ return err; } +#ifndef __LITTLE_ENDIAN static __inline__ int sync_indirect_swab32 (struct inode * inode, u32 * iblock, int wait) { int i; @@ -193,8 +207,11 @@ brelse (ind_bh); return err; } +#else +#define sync_indirect_swab32 sync_indirect +#endif -static __inline__ int sync_dindirect (struct inode * inode, u32 * diblock, int wait) +static int sync_dindirect (struct inode * inode, u32 * diblock, int wait) { int i; struct buffer_head * dind_bh; @@ -217,6 +234,7 @@ return err; } +#ifndef __LITTLE_ENDIAN static __inline__ int sync_dindirect_swab32 (struct inode * inode, u32 * diblock, int wait) { int i; @@ -239,8 +257,11 @@ brelse (dind_bh); return err; } +#else +#define sync_dindirect_swab32 sync_dindirect +#endif -static __inline__ int sync_tindirect (struct inode * inode, u32 * tiblock, int wait) +static int sync_tindirect (struct inode * inode, u32 * tiblock, int wait) { int i; struct buffer_head * tind_bh; diff -u --recursive --new-file v2.1.30/linux/fs/filesystems.c linux/fs/filesystems.c --- v2.1.30/linux/fs/filesystems.c Thu Feb 27 10:57:31 1997 +++ linux/fs/filesystems.c Fri Mar 28 15:10:39 1997 @@ -23,6 +23,7 @@ #include #include #include +#include #include #include #include @@ -108,6 +109,10 @@ #ifdef CONFIG_UFS_FS init_ufs_fs(); +#endif + +#ifdef CONFIG_AUTOFS_FS + init_autofs_fs(); #endif mount_root(); diff -u --recursive --new-file v2.1.30/linux/fs/locks.c linux/fs/locks.c --- v2.1.30/linux/fs/locks.c Sun Jan 26 02:07:44 1997 +++ linux/fs/locks.c Wed Apr 2 17:43:22 1997 @@ -97,6 +97,9 @@ * Made mandatory locking a mount option. Default is not to allow mandatory * locking. * Andy Walker (andy@lysaker.kvaerner.no), Oct 04, 1996. + * + * Some adaptations for NFS support. + * Olaf Kirch (okir@monad.swb.de), Dec 1996, */ #include @@ -123,10 +126,8 @@ static int locks_conflict(struct file_lock *caller_fl, struct file_lock *sys_fl); static int flock_lock_file(struct file *filp, struct file_lock *caller, unsigned int wait); -static int posix_lock_file(struct file *filp, struct file_lock *caller, - unsigned int wait); -static int posix_locks_deadlock(struct task_struct *my_task, - struct task_struct *blocked_task); +static int posix_locks_deadlock(struct file_lock *caller, + struct file_lock *blocker); static struct file_lock *locks_alloc_lock(struct file_lock *fl); static void locks_insert_lock(struct file_lock **pos, struct file_lock *fl); @@ -137,7 +138,7 @@ static void locks_delete_block(struct file_lock *blocker, struct file_lock *waiter); static void locks_wake_up_blocks(struct file_lock *blocker, unsigned int wait); -static struct file_lock *file_lock_table = NULL; +struct file_lock *file_lock_table = NULL; /* Free lock not inserted in any queue. */ @@ -161,6 +162,15 @@ (fl2->fl_end >= fl1->fl_start)); } +/* Check whether two locks have the same owner + */ +static inline int +locks_same_owner(struct file_lock *fl1, struct file_lock *fl2) +{ + return (fl1->fl_owner == fl2->fl_owner) && + (fl1->fl_pid == fl2->fl_pid); +} + /* Insert waiter into blocker's block list. * We use a circular list so that processes can be easily woken up in * the order they blocked. The documentation doesn't require this but @@ -211,6 +221,21 @@ return; } +/* The following two are for the benefit of lockd. + */ +void +posix_block_lock(struct file_lock *blocker, struct file_lock *waiter) +{ + locks_insert_block(blocker, waiter); +} + +void +posix_unblock_lock(struct file_lock *waiter) +{ + if (waiter->fl_prevblock) + locks_delete_block(waiter->fl_prevblock, waiter); +} + /* Wake up processes blocked waiting for blocker. * If told to wait then schedule the processes until the block list * is empty, otherwise empty the block list ourselves. @@ -220,6 +245,8 @@ struct file_lock *waiter; while ((waiter = blocker->fl_nextblock) != NULL) { + if (waiter->fl_notify) + waiter->fl_notify(waiter); wake_up(&waiter->fl_wait); if (wait) /* Let the blocked process remove waiter from the @@ -266,6 +293,7 @@ struct flock flock; struct file *filp; struct file_lock *fl,file_lock; + int error; if ((fd >= NR_OPEN) || !(filp = current->files->fd[fd])) return (-EBADF); @@ -278,21 +306,28 @@ if (!filp->f_inode || !posix_make_lock(filp, &file_lock, &flock)) return (-EINVAL); - for (fl = filp->f_inode->i_flock; fl != NULL; fl = fl->fl_next) { - if (!(fl->fl_flags & FL_POSIX)) - continue; - if (posix_locks_conflict(&file_lock, fl)) { - flock.l_pid = fl->fl_owner->pid; - flock.l_start = fl->fl_start; - flock.l_len = fl->fl_end == OFFSET_MAX ? 0 : - fl->fl_end - fl->fl_start + 1; - flock.l_whence = 0; - flock.l_type = fl->fl_type; - return copy_to_user(l, &flock, sizeof(flock)) ? -EFAULT : 0; - } - } - - flock.l_type = F_UNLCK; /* no conflict found */ + if (filp->f_op->lock) { + error = filp->f_op->lock(filp->f_inode, filp, + F_GETLK, &file_lock); + if (error < 0) + return error; + fl = &file_lock; + } else { + fl = posix_test_lock(filp, &file_lock); + } + + if (fl != NULL) { + flock.l_pid = fl->fl_pid; + flock.l_start = fl->fl_start; + flock.l_len = fl->fl_end == OFFSET_MAX ? 0 : + fl->fl_end - fl->fl_start + 1; + flock.l_whence = 0; + flock.l_type = fl->fl_type; + return copy_to_user(l, &flock, sizeof(flock)) ? -EFAULT : 0; + } else { + flock.l_type = F_UNLCK; + } + return copy_to_user(l, &flock, sizeof(flock)) ? -EFAULT : 0; } @@ -305,6 +340,7 @@ struct file_lock file_lock; struct flock flock; struct inode *inode; + int error; /* Get arguments and validate them ... */ @@ -365,7 +401,13 @@ default: return -EINVAL; } - + + if (filp->f_op->lock != NULL) { + error = filp->f_op->lock(filp->f_inode, filp, cmd, &file_lock); + if (error < 0) + return error; + } + return (posix_lock_file(filp, &file_lock, cmd == F_SETLKW)); } @@ -373,7 +415,7 @@ */ void locks_remove_locks(struct task_struct *task, struct file *filp) { - struct file_lock *fl; + struct file_lock file_lock, *fl; struct file_lock **before; /* For POSIX locks we free all locks on this file for the given task. @@ -385,15 +427,39 @@ while ((fl = *before) != NULL) { if (((fl->fl_flags & FL_POSIX) && (fl->fl_owner == task)) || ((fl->fl_flags & FL_FLOCK) && (fl->fl_file == filp) && - (filp->f_count == 1))) + (filp->f_count == 1))) { + file_lock = *fl; locks_delete_lock(before, 0); - else + if (filp->f_op->lock) { + file_lock.fl_type = F_UNLCK; + filp->f_op->lock(filp->f_inode, filp, + F_SETLK, &file_lock); + /* List may have changed: */ + before = &filp->f_inode->i_flock; + } + } else { before = &fl->fl_next; + } } return; } +struct file_lock * +posix_test_lock(struct file *filp, struct file_lock *fl) +{ + struct file_lock *cfl; + + for (cfl = filp->f_inode->i_flock; cfl; cfl = cfl->fl_next) { + if (!(cfl->fl_flags & FL_POSIX)) + continue; + if (posix_locks_conflict(cfl, fl)) + break; + } + + return cfl; +} + int locks_verify_locked(struct inode *inode) { /* Candidates for mandatory locking have the setgid bit set @@ -445,6 +511,7 @@ tfl.fl_file = filp; tfl.fl_flags = FL_POSIX | FL_ACCESS; tfl.fl_owner = current; + tfl.fl_pid = current->pid; tfl.fl_type = (read_write == FLOCK_VERIFY_WRITE) ? F_WRLCK : F_RDLCK; tfl.fl_start = offset; tfl.fl_end = offset + count - 1; @@ -464,7 +531,7 @@ return (-EAGAIN); if (current->signal & ~current->blocked) return (-ERESTARTSYS); - if (posix_locks_deadlock(current, fl->fl_owner)) + if (posix_locks_deadlock(&tfl, fl)) return (-EDEADLK); locks_insert_block(fl, &tfl); @@ -528,6 +595,7 @@ fl->fl_file = filp; fl->fl_owner = current; + fl->fl_pid = current->pid; return (1); } @@ -575,7 +643,7 @@ * each other. */ if (!(sys_fl->fl_flags & FL_POSIX) || - (caller_fl->fl_owner == sys_fl->fl_owner)) + locks_same_owner(caller_fl, sys_fl)) return (0); return (locks_conflict(caller_fl, sys_fl)); @@ -628,25 +696,39 @@ * at a time. When we find blocked_task on a wait queue we can re-search * with blocked_task equal to that queue's owner, until either blocked_task * isn't found, or blocked_task is found on a queue owned by my_task. + * + * Note: the above assumption may not be true when handling lock requests + * from a broken NFS client. But broken NFS clients have a lot more to + * worry about than proper deadlock detection anyway... --okir */ -static int posix_locks_deadlock(struct task_struct *my_task, - struct task_struct *blocked_task) +static int posix_locks_deadlock(struct file_lock *caller_fl, + struct file_lock *block_fl) { struct file_lock *fl; struct file_lock *bfl; + void *caller_owner, *blocked_owner; + unsigned int caller_pid, blocked_pid; + + caller_owner = caller_fl->fl_owner; + caller_pid = caller_fl->fl_pid; + blocked_owner = block_fl->fl_owner; + blocked_pid = block_fl->fl_pid; next_task: - if (my_task == blocked_task) + if (caller_owner == blocked_owner && caller_pid == blocked_pid) return (1); for (fl = file_lock_table; fl != NULL; fl = fl->fl_nextlink) { if (fl->fl_owner == NULL || fl->fl_nextblock == NULL) continue; for (bfl = fl->fl_nextblock; bfl != fl; bfl = bfl->fl_nextblock) { - if (bfl->fl_owner == blocked_task) { - if (fl->fl_owner == my_task) { + if (bfl->fl_owner == blocked_owner && + bfl->fl_pid == blocked_pid) { + if (fl->fl_owner == caller_owner && + fl->fl_pid == caller_pid) { return (1); } - blocked_task = fl->fl_owner; + blocked_owner = fl->fl_owner; + blocked_pid = fl->fl_pid; goto next_task; } } @@ -731,7 +813,7 @@ * To all purists: Yes, I use a few goto's. Just pass on to the next function. */ -static int posix_lock_file(struct file *filp, struct file_lock *caller, +int posix_lock_file(struct file *filp, struct file_lock *caller, unsigned int wait) { struct file_lock *fl; @@ -752,7 +834,7 @@ return (-EAGAIN); if (current->signal & ~current->blocked) return (-ERESTARTSYS); - if (posix_locks_deadlock(caller->fl_owner, fl->fl_owner)) + if (posix_locks_deadlock(caller, fl)) return (-EDEADLK); locks_insert_block(fl, caller); interruptible_sleep_on(&caller->fl_wait); @@ -771,13 +853,13 @@ /* First skip locks owned by other processes. */ while ((fl = *before) && (!(fl->fl_flags & FL_POSIX) || - (caller->fl_owner != fl->fl_owner))) { + !locks_same_owner(caller, fl))) { before = &fl->fl_next; } /* Process locks with this owner. */ - while ((fl = *before) && (caller->fl_owner == fl->fl_owner)) { + while ((fl = *before) && locks_same_owner(caller, fl)) { /* Detect adjacent or overlapping regions (if same lock type) */ if (caller->fl_type == fl->fl_type) { @@ -845,6 +927,7 @@ fl->fl_start = caller->fl_start; fl->fl_end = caller->fl_end; fl->fl_type = caller->fl_type; + fl->fl_u = caller->fl_u; caller = fl; added = 1; } @@ -902,10 +985,13 @@ tmp->fl_flags = fl->fl_flags; tmp->fl_owner = fl->fl_owner; + tmp->fl_pid = fl->fl_pid; tmp->fl_file = fl->fl_file; tmp->fl_type = fl->fl_type; tmp->fl_start = fl->fl_start; tmp->fl_end = fl->fl_end; + tmp->fl_notify = fl->fl_notify; + tmp->fl_u = fl->fl_u; return (tmp); } @@ -977,7 +1063,7 @@ } p += sprintf(p, "%s ", (fl->fl_type == F_RDLCK) ? "READ " : "WRITE"); p += sprintf(p, "%d %s:%ld %ld %ld ", - fl->fl_owner ? fl->fl_owner->pid : 0, + fl->fl_pid, kdevname(inode->i_dev), inode->i_ino, fl->fl_start, fl->fl_end); p += sprintf(p, "%08lx %08lx %08lx %08lx %08lx\n", diff -u --recursive --new-file v2.1.30/linux/fs/ncpfs/dir.c linux/fs/ncpfs/dir.c --- v2.1.30/linux/fs/ncpfs/dir.c Sun Jan 26 02:07:44 1997 +++ linux/fs/ncpfs/dir.c Fri Mar 28 10:42:22 1997 @@ -23,95 +23,88 @@ struct ncp_dirent { struct nw_info_struct i; - struct nw_search_sequence s; /* given back for i */ + struct nw_search_sequence s; /* given back for i */ unsigned long f_pos; }; static long -ncp_dir_read(struct inode *inode, struct file *filp, char *buf, unsigned long count); + ncp_dir_read(struct inode *inode, struct file *filp, char *buf, unsigned long count); -static int -ncp_readdir(struct inode *inode, struct file *filp, - void *dirent, filldir_t filldir); +static int + ncp_readdir(struct inode *inode, struct file *filp, + void *dirent, filldir_t filldir); static int -ncp_read_volume_list(struct ncp_server *server, int start_with, - int cache_size); + ncp_read_volume_list(struct ncp_server *server, int start_with, + int cache_size); static int -ncp_do_readdir(struct ncp_server *server, struct inode *dir, int fpos, - int cache_size, struct ncp_dirent *entry); + ncp_do_readdir(struct ncp_server *server, struct inode *dir, int fpos, + int cache_size, struct ncp_dirent *entry); static struct inode * -ncp_iget(struct inode *dir, struct nw_file_info *finfo); + ncp_iget(struct inode *dir, struct nw_file_info *finfo); static struct ncp_inode_info * -ncp_find_dir_inode(struct inode *dir, const char *name); + ncp_find_dir_inode(struct inode *dir, const char *name); static int -ncp_lookup(struct inode *dir, const char *__name, - int len, struct inode **result); + ncp_lookup(struct inode *dir, const char *__name, + int len, struct inode **result); -static int -ncp_create(struct inode *dir, const char *name, int len, int mode, - struct inode **result); +static int + ncp_create(struct inode *dir, const char *name, int len, int mode, + struct inode **result); -static int -ncp_mkdir(struct inode *dir, const char *name, int len, int mode); +static int + ncp_mkdir(struct inode *dir, const char *name, int len, int mode); -static int -ncp_rmdir(struct inode *dir, const char *name, int len); +static int + ncp_rmdir(struct inode *dir, const char *name, int len); static int -ncp_unlink(struct inode *dir, const char *name, int len); + ncp_unlink(struct inode *dir, const char *name, int len); static int -ncp_rename(struct inode *old_dir, const char *old_name, int old_len, - struct inode *new_dir, const char *new_name, int new_len, - int must_be_dir); - -static inline void -str_upper(char *name) -{ - while (*name) - { - if (*name >= 'a' && *name <= 'z') - { + ncp_rename(struct inode *old_dir, const char *old_name, int old_len, + struct inode *new_dir, const char *new_name, int new_len, + int must_be_dir); + +static inline void str_upper(char *name) +{ + while (*name) { + if (*name >= 'a' && *name <= 'z') { *name -= ('a' - 'A'); } name++; } } -static inline void -str_lower(char *name) +static inline void str_lower(char *name) { - while (*name) - { - if (*name >= 'A' && *name <= 'Z') - { + while (*name) { + if (*name >= 'A' && *name <= 'Z') { *name += ('a' - 'A'); } - name ++; + name++; } } -static inline int -ncp_namespace(struct inode *i) +static inline int ncp_namespace(struct inode *i) { - struct ncp_server *server = NCP_SERVER(i); + struct ncp_server *server = NCP_SERVER(i); struct nw_info_struct *info = NCP_ISTRUCT(i); return server->name_space[info->volNumber]; } -static inline int -ncp_preserve_case(struct inode *i) +static inline int ncp_preserve_case(struct inode *i) { return (ncp_namespace(i) == NW_NS_OS2); } -static struct file_operations ncp_dir_operations = { - NULL, /* lseek - default */ +static struct file_operations ncp_dir_operations = +{ + NULL, /* lseek - default */ ncp_dir_read, /* read - bad */ NULL, /* write - bad */ ncp_readdir, /* readdir */ @@ -123,23 +116,24 @@ NULL /* fsync */ }; -struct inode_operations ncp_dir_inode_operations = { +struct inode_operations ncp_dir_inode_operations = +{ &ncp_dir_operations, /* default directory file ops */ ncp_create, /* create */ - ncp_lookup, /* lookup */ + ncp_lookup, /* lookup */ NULL, /* link */ - ncp_unlink, /* unlink */ + ncp_unlink, /* unlink */ NULL, /* symlink */ - ncp_mkdir, /* mkdir */ - ncp_rmdir, /* rmdir */ + ncp_mkdir, /* mkdir */ + ncp_rmdir, /* rmdir */ NULL, /* mknod */ - ncp_rename, /* rename */ + ncp_rename, /* rename */ NULL, /* readlink */ NULL, /* follow_link */ NULL, /* bmap */ NULL, /* truncate */ NULL, /* permission */ - NULL /* smap */ + NULL /* smap */ }; @@ -151,223 +145,181 @@ * enable the NFS exportability of a ncpfs-mounted volume. */ -static inline int -ncp_single_volume(struct ncp_server *server) +static inline int ncp_single_volume(struct ncp_server *server) { return (server->m.mounted_vol[0] != '\0'); } inline ino_t -ncp_info_ino(struct ncp_server *server, struct ncp_inode_info *info) + ncp_info_ino(struct ncp_server * server, struct ncp_inode_info * info) { return ncp_single_volume(server) - ? info->finfo.i.dirEntNum : (ino_t)info; + ? info->finfo.i.dirEntNum : (ino_t) info; } -static inline int -ncp_is_server_root(struct inode *inode) +static inline int ncp_is_server_root(struct inode *inode) { struct ncp_server *s = NCP_SERVER(inode); - return ( (!ncp_single_volume(s)) + return ((!ncp_single_volume(s)) && (inode->i_ino == ncp_info_ino(s, &(s->root)))); } struct ncp_inode_info * -ncp_find_inode(struct inode *inode) + ncp_find_inode(struct inode *inode) { struct ncp_server *server = NCP_SERVER(inode); - struct ncp_inode_info *root = &(server->root); - struct ncp_inode_info *this = root; + struct ncp_inode_info *root = &(server->root); + struct ncp_inode_info *this = root; ino_t ino = inode->i_ino; - do - { - if (ino == ncp_info_ino(server, this)) - { + do { + if (ino == ncp_info_ino(server, this)) { return this; } this = this->next; - } + } while (this != root); return NULL; } - -static long -ncp_dir_read(struct inode *inode, struct file *filp, char *buf, unsigned long count) + +static long ncp_dir_read(struct inode *inode, struct file *filp, char *buf, unsigned long count) { return -EISDIR; } -static kdev_t c_dev = 0; -static unsigned long c_ino = 0; -static int c_size; -static int c_seen_eof; -static int c_last_returned_index; -static struct ncp_dirent* c_entry = NULL; -static int c_lock = 0; +static kdev_t c_dev = 0; +static unsigned long c_ino = 0; +static int c_size; +static int c_seen_eof; +static int c_last_returned_index; +static struct ncp_dirent *c_entry = NULL; +static int c_lock = 0; static struct wait_queue *c_wait = NULL; -static inline void -ncp_lock_dircache(void) +static inline void ncp_lock_dircache(void) { while (c_lock) sleep_on(&c_wait); c_lock = 1; } -static inline void -ncp_unlock_dircache(void) +static inline void ncp_unlock_dircache(void) { c_lock = 0; wake_up(&c_wait); } -static int -ncp_readdir(struct inode *inode, struct file *filp, - void *dirent, filldir_t filldir) +static int ncp_readdir(struct inode *inode, struct file *filp, + void *dirent, filldir_t filldir) { int result = 0; int i = 0; - int index = 0; + int index = 0; struct ncp_dirent *entry = NULL; - struct ncp_server *server = NCP_SERVER(inode); + struct ncp_server *server = NCP_SERVER(inode); struct ncp_inode_info *dir = NCP_INOP(inode); - DDPRINTK("ncp_readdir: filp->f_pos = %d\n", (int)filp->f_pos); + DDPRINTK("ncp_readdir: filp->f_pos = %d\n", (int) filp->f_pos); DDPRINTK("ncp_readdir: inode->i_ino = %ld, c_ino = %ld\n", inode->i_ino, c_ino); - if (!inode || !S_ISDIR(inode->i_mode)) - { + if (!inode || !S_ISDIR(inode->i_mode)) { printk("ncp_readdir: inode is NULL or not a directory\n"); return -EBADF; } - - if (!ncp_conn_valid(server)) - { + if (!ncp_conn_valid(server)) { return -EIO; } - ncp_lock_dircache(); - if (c_entry == NULL) - { - i = sizeof (struct ncp_dirent) * NCP_READDIR_CACHE_SIZE; + if (c_entry == NULL) { + i = sizeof(struct ncp_dirent) * NCP_READDIR_CACHE_SIZE; c_entry = (struct ncp_dirent *) vmalloc(i); - if (c_entry == NULL) - { + if (c_entry == NULL) { printk("ncp_readdir: no MEMORY for cache\n"); result = -ENOMEM; goto finished; } } - - if (filp->f_pos == 0) - { - ncp_invalid_dir_cache(inode); - if (filldir(dirent,".",1, filp->f_pos, - ncp_info_ino(server, dir)) < 0) - { + if (filp->f_pos == 0) { + ncp_invalid_dir_cache(inode); + if (filldir(dirent, ".", 1, filp->f_pos, + ncp_info_ino(server, dir)) < 0) { goto finished; } filp->f_pos += 1; - } - - if (filp->f_pos == 1) - { - if (filldir(dirent,"..",2, filp->f_pos, - ncp_info_ino(server, dir->dir)) < 0) - { + } + if (filp->f_pos == 1) { + if (filldir(dirent, "..", 2, filp->f_pos, + ncp_info_ino(server, dir->dir)) < 0) { goto finished; } filp->f_pos += 1; } - - if ((inode->i_dev == c_dev) && (inode->i_ino == c_ino)) - { - for (i = 0; i < c_size; i++) - { - if (filp->f_pos == c_entry[i].f_pos) - { - entry = &c_entry[i]; - c_last_returned_index = i; - index = i; - break; + if ((inode->i_dev == c_dev) && (inode->i_ino == c_ino)) { + for (i = 0; i < c_size; i++) { + if (filp->f_pos == c_entry[i].f_pos) { + entry = &c_entry[i]; + c_last_returned_index = i; + index = i; + break; } } - if ((entry == NULL) && c_seen_eof) - { + if ((entry == NULL) && c_seen_eof) { goto finished; } } - - if (entry == NULL) - { + if (entry == NULL) { int entries; DDPRINTK("ncp_readdir: Not found in cache.\n"); - if (ncp_is_server_root(inode)) - { + if (ncp_is_server_root(inode)) { entries = ncp_read_volume_list(server, filp->f_pos, - NCP_READDIR_CACHE_SIZE); + NCP_READDIR_CACHE_SIZE); DPRINTK("ncp_read_volume_list returned %d\n", entries); - } - else - { + } else { entries = ncp_do_readdir(server, inode, filp->f_pos, NCP_READDIR_CACHE_SIZE, c_entry); DPRINTK("ncp_readdir returned %d\n", entries); } - if (entries < 0) - { + if (entries < 0) { c_dev = 0; c_ino = 0; result = entries; goto finished; } - - if (entries > 0) - { - c_seen_eof = (entries < NCP_READDIR_CACHE_SIZE); - c_dev = inode->i_dev; - c_ino = inode->i_ino; + if (entries > 0) { + c_seen_eof = (entries < NCP_READDIR_CACHE_SIZE); + c_dev = inode->i_dev; + c_ino = inode->i_ino; c_size = entries; entry = c_entry; - c_last_returned_index = 0; - index = 0; + c_last_returned_index = 0; + index = 0; - if (!ncp_preserve_case(inode)) - { - for (i = 0; i < c_size; i++) - { + if (!ncp_preserve_case(inode)) { + for (i = 0; i < c_size; i++) { str_lower(c_entry[i].i.entryName); } } } } - - if (entry == NULL) - { - /* Nothing found, even from a ncp call */ + if (entry == NULL) { + /* Nothing found, even from a ncp call */ goto finished; - } - - while (index < c_size) - { + } + while (index < c_size) { ino_t ino; - if (ncp_single_volume(server)) - { - ino = (ino_t)(entry->i.dirEntNum); - } - else - { + if (ncp_single_volume(server)) { + ino = (ino_t) (entry->i.dirEntNum); + } else { /* For getwd() we have to return the correct * inode in d_ino if the inode is currently in * use. Otherwise the inode number does not @@ -379,41 +331,36 @@ /* Some programs seem to be confused about a * zero inode number, so we set it to one. * Thanks to Gordon Chaffee for this one. */ - if (ino_info == NULL) - { + if (ino_info == NULL) { ino_info = (struct ncp_inode_info *) 1; } - ino = (ino_t)(ino_info); + ino = (ino_t) (ino_info); } DDPRINTK("ncp_readdir: entry->path= %s\n", entry->i.entryName); DDPRINTK("ncp_readdir: entry->f_pos = %ld\n", entry->f_pos); - if (filldir(dirent, entry->i.entryName, entry->i.nameLen, - entry->f_pos, ino) < 0) - { + if (filldir(dirent, entry->i.entryName, entry->i.nameLen, + entry->f_pos, ino) < 0) { break; - } - - if ( (inode->i_dev != c_dev) + } + if ((inode->i_dev != c_dev) || (inode->i_ino != c_ino) - || (entry->f_pos != filp->f_pos)) - { + || (entry->f_pos != filp->f_pos)) { /* Someone has destroyed the cache while we slept in filldir */ break; } - filp->f_pos += 1; - index += 1; - entry += 1; + filp->f_pos += 1; + index += 1; + entry += 1; } - finished: + finished: ncp_unlock_dircache(); return result; } -static int -ncp_read_volume_list(struct ncp_server *server, int fpos, int cache_size) +static int ncp_read_volume_list(struct ncp_server *server, int fpos, int cache_size) { struct ncp_dirent *entry = c_entry; @@ -421,47 +368,35 @@ int i; #if 1 - if (fpos < 2) - { + if (fpos < 2) { printk("OOPS, we expect fpos >= 2"); fpos = 2; } #endif - for (i=0; i 0) - { - if (total_count < fpos) - { + if (strlen(info.volume_name) > 0) { + if (total_count < fpos) { DPRINTK("ncp_read_volumes: skipped vol: %s\n", info.volume_name); - } - else if (total_count >= fpos + cache_size) - { + } else if (total_count >= fpos + cache_size) { return (total_count - fpos); - } - else - { + } else { DPRINTK("ncp_read_volumes: found vol: %s\n", info.volume_name); if (ncp_lookup_volume(server, info.volume_name, - &(entry->i)) != 0) - { + &(entry->i)) != 0) { DPRINTK("ncpfs: could not lookup vol " "%s\n", info.volume_name); continue; } - entry->f_pos = total_count; entry += 1; } @@ -471,59 +406,46 @@ return (total_count - fpos); } -static int -ncp_do_readdir(struct ncp_server *server, struct inode *dir, int fpos, - int cache_size, struct ncp_dirent *entry) +static int ncp_do_readdir(struct ncp_server *server, struct inode *dir, int fpos, + int cache_size, struct ncp_dirent *entry) { static struct nw_search_sequence seq; static struct inode *last_dir; static int total_count; #if 1 - if (fpos < 2) - { + if (fpos < 2) { printk("OOPS, we expect fpos >= 2"); fpos = 2; } #endif DPRINTK("ncp_do_readdir: fpos = %d\n", fpos); - if (fpos == 2) - { + if (fpos == 2) { last_dir = NULL; total_count = 2; } - - if ((fpos != total_count) || (dir != last_dir)) - { + if ((fpos != total_count) || (dir != last_dir)) { total_count = 2; last_dir = dir; DPRINTK("ncp_do_readdir: re-used seq for %s\n", NCP_ISTRUCT(dir)->entryName); - if (ncp_initialize_search(server, NCP_ISTRUCT(dir), &seq)!=0) - { + if (ncp_initialize_search(server, NCP_ISTRUCT(dir), &seq) != 0) { DPRINTK("ncp_init_search failed\n"); return total_count - fpos; } } - - while (total_count < fpos + cache_size) - { + while (total_count < fpos + cache_size) { if (ncp_search_for_file_or_subdir(server, &seq, - &(entry->i)) != 0) - { + &(entry->i)) != 0) { return total_count - fpos; } - - if (total_count < fpos) - { + if (total_count < fpos) { DPRINTK("ncp_do_readdir: skipped file: %s\n", entry->i.entryName); - } - else - { + } else { DDPRINTK("ncp_do_r: file: %s, f_pos=%d,total_count=%d", entry->i.entryName, fpos, total_count); entry->s = seq; @@ -535,143 +457,124 @@ return (total_count - fpos); } -void -ncp_init_dir_cache(void) +void ncp_init_dir_cache(void) { - c_dev = 0; - c_ino = 0; - c_entry = NULL; + c_dev = 0; + c_ino = 0; + c_entry = NULL; } -void -ncp_invalid_dir_cache(struct inode *ino) +void ncp_invalid_dir_cache(struct inode *ino) { - if ((ino->i_dev == c_dev) && (ino->i_ino == c_ino)) - { + if ((ino->i_dev == c_dev) && (ino->i_ino == c_ino)) { c_dev = 0; - c_ino = 0; - c_seen_eof = 0; - } + c_ino = 0; + c_seen_eof = 0; + } } -void -ncp_free_dir_cache(void) -{ - DPRINTK("ncp_free_dir_cache: enter\n"); - - if (c_entry == NULL) - { - return; - } +void ncp_free_dir_cache(void) +{ + DPRINTK("ncp_free_dir_cache: enter\n"); + if (c_entry == NULL) { + return; + } vfree(c_entry); c_entry = NULL; - DPRINTK("ncp_free_dir_cache: exit\n"); + DPRINTK("ncp_free_dir_cache: exit\n"); } static struct inode * -ncp_iget(struct inode *dir, struct nw_file_info *finfo) + ncp_iget(struct inode *dir, struct nw_file_info *finfo) { struct inode *inode; - struct ncp_inode_info *new_inode_info; - struct ncp_inode_info *root; + struct ncp_inode_info *new_inode_info; + struct ncp_inode_info *root; - if (dir == NULL) - { + if (dir == NULL) { printk("ncp_iget: dir is NULL\n"); return NULL; } - - if (finfo == NULL) - { + if (finfo == NULL) { printk("ncp_iget: finfo is NULL\n"); return NULL; } + new_inode_info = ncp_kmalloc(sizeof(struct ncp_inode_info), + GFP_KERNEL); - new_inode_info = ncp_kmalloc(sizeof(struct ncp_inode_info), - GFP_KERNEL); - - if (new_inode_info == NULL) - { - printk("ncp_iget: could not alloc mem for %s\n", + if (new_inode_info == NULL) { + printk("ncp_iget: could not alloc mem for %s\n", finfo->i.entryName); - return NULL; - } + return NULL; + } + new_inode_info->state = NCP_INODE_LOOKED_UP; + new_inode_info->nused = 0; + new_inode_info->dir = NCP_INOP(dir); + new_inode_info->finfo = *finfo; + + NCP_INOP(dir)->nused += 1; + + /* We have to link the new inode_info into the doubly linked + list of inode_infos to make a complete linear search + possible. */ + + root = &(NCP_SERVER(dir)->root); + + new_inode_info->prev = root; + new_inode_info->next = root->next; + root->next->prev = new_inode_info; + root->next = new_inode_info; - new_inode_info->state = NCP_INODE_LOOKED_UP; - new_inode_info->nused = 0; - new_inode_info->dir = NCP_INOP(dir); - new_inode_info->finfo = *finfo; - - NCP_INOP(dir)->nused += 1; - - /* We have to link the new inode_info into the doubly linked - list of inode_infos to make a complete linear search - possible. */ - - root = &(NCP_SERVER(dir)->root); - - new_inode_info->prev = root; - new_inode_info->next = root->next; - root->next->prev = new_inode_info; - root->next = new_inode_info; - if (!(inode = iget(dir->i_sb, ncp_info_ino(NCP_SERVER(dir), - new_inode_info)))) - { + new_inode_info)))) { printk("ncp_iget: iget failed!"); return NULL; } - return inode; } -void -ncp_free_inode_info(struct ncp_inode_info *i) +void ncp_free_inode_info(struct ncp_inode_info *i) { - if (i == NULL) - { - printk("ncp_free_inode: i == NULL\n"); - return; - } - - i->state = NCP_INODE_CACHED; - while ((i->nused == 0) && (i->state == NCP_INODE_CACHED)) - { - struct ncp_inode_info *dir = i->dir; + if (i == NULL) { + printk("ncp_free_inode: i == NULL\n"); + return; + } + i->state = NCP_INODE_CACHED; + while ((i->nused == 0) && (i->state == NCP_INODE_CACHED)) { + struct ncp_inode_info *dir = i->dir; - i->next->prev = i->prev; - i->prev->next = i->next; + i->next->prev = i->prev; + i->prev->next = i->next; DDPRINTK("ncp_free_inode_info: freeing %s\n", i->finfo.i.entryName); - ncp_kfree_s(i, sizeof(struct ncp_inode_info)); + ncp_kfree_s(i, sizeof(struct ncp_inode_info)); - if (dir == i) return; + if (dir == i) + return; - (dir->nused)--; - i = dir; - } + (dir->nused)--; + i = dir; + } } - -void -ncp_init_root(struct ncp_server *server) + +void ncp_init_root(struct ncp_server *server) { - struct ncp_inode_info *root = &(server->root); + struct ncp_inode_info *root = &(server->root); struct nw_info_struct *i = &(root->finfo.i); unsigned short dummy; - DPRINTK("ncp_init_root: server %s\n", server->m.server_name); - DPRINTK("ncp_init_root: i = %x\n", (int)i); + DPRINTK("ncp_init_root: i = %x\n", (int) i); - root->finfo.opened = 0; - i->attributes = aDIR; + root->finfo.opened = 0; + i->attributes = aDIR; i->dataStreamSize = 1024; i->dirEntNum = i->DosDirNum = 0; - i->volNumber = NCP_NUMBER_OF_VOLUMES+1; /* illegal volnum */ + i->volNumber = NCP_NUMBER_OF_VOLUMES + 1; /* illegal volnum */ ncp_date_unix2dos(0, &(i->creationTime), &(i->creationDate)); ncp_date_unix2dos(0, &(i->modifyTime), &(i->modifyDate)); ncp_date_unix2dos(0, &dummy, &(i->lastAccessDate)); @@ -683,25 +586,21 @@ i->nameLen = 0; i->entryName[0] = '\0'; - root->state = NCP_INODE_LOOKED_UP; - root->nused = 1; - root->dir = root; - root->next = root->prev = root; - return; + root->state = NCP_INODE_LOOKED_UP; + root->nused = 1; + root->dir = root; + root->next = root->prev = root; + return; } -int -ncp_conn_logged_in(struct ncp_server *server) +int ncp_conn_logged_in(struct ncp_server *server) { - if (server->m.mounted_vol[0] == '\0') - { + if (server->m.mounted_vol[0] == '\0') { return 0; } - str_upper(server->m.mounted_vol); if (ncp_lookup_volume(server, server->m.mounted_vol, - &(server->root.finfo.i)) != 0) - { + &(server->root.finfo.i)) != 0) { return -ENOENT; } str_lower(server->root.finfo.i.entryName); @@ -709,202 +608,166 @@ return 0; } -void -ncp_free_all_inodes(struct ncp_server *server) +void ncp_free_all_inodes(struct ncp_server *server) { - /* Here nothing should be to do. I do not know whether it's - better to leave some memory allocated or be stuck in an - endless loop */ + /* Here nothing should be to do. I do not know whether it's + better to leave some memory allocated or be stuck in an + endless loop */ #if 1 - struct ncp_inode_info *root = &(server->root); + struct ncp_inode_info *root = &(server->root); - if (root->next != root) - { - printk("ncp_free_all_inodes: INODES LEFT!!!\n"); - } - - while (root->next != root) - { - printk("ncp_free_all_inodes: freeing inode\n"); - ncp_free_inode_info(root->next); - /* In case we have an endless loop.. */ - schedule(); - } -#endif - - return; + if (root->next != root) { + printk("ncp_free_all_inodes: INODES LEFT!!!\n"); + } + while (root->next != root) { + printk("ncp_free_all_inodes: freeing inode\n"); + ncp_free_inode_info(root->next); + /* In case we have an endless loop.. */ + schedule(); + } +#endif + + return; } /* We will search the inode that belongs to this name, currently by a complete linear search through the inodes belonging to this filesystem. This has to be fixed. */ static struct ncp_inode_info * -ncp_find_dir_inode(struct inode *dir, const char *name) + ncp_find_dir_inode(struct inode *dir, const char *name) { struct ncp_server *server = NCP_SERVER(dir); struct nw_info_struct *dir_info = NCP_ISTRUCT(dir); - struct ncp_inode_info *result = &(server->root); + struct ncp_inode_info *result = &(server->root); - if (name == NULL) - { - return NULL; + if (name == NULL) { + return NULL; } - - do - { - if ( (result->dir->finfo.i.dirEntNum == dir_info->dirEntNum) - && (result->dir->finfo.i.volNumber == dir_info->volNumber) + do { + if ((result->dir->finfo.i.dirEntNum == dir_info->dirEntNum) + && (result->dir->finfo.i.volNumber == dir_info->volNumber) && (strcmp(result->finfo.i.entryName, name) == 0) - /* The root dir is never looked up using this - * routine. Without the following test a root - * directory 'sys' in a volume named 'sys' could - * never be looked up, because - * server->root->dir==server->root. */ - && (result != &(server->root))) - { - return result; + /* The root dir is never looked up using this + * routine. Without the following test a root + * directory 'sys' in a volume named 'sys' could + * never be looked up, because + * server->root->dir==server->root. */ + && (result != &(server->root))) { + return result; } - result = result->next; + result = result->next; - } + } while (result != &(server->root)); - return NULL; + return NULL; } -static int -ncp_lookup(struct inode *dir, const char *__name, int len, - struct inode **result) +static int ncp_lookup(struct inode *dir, const char *__name, int len, + struct inode **result) { struct nw_file_info finfo; struct ncp_server *server; struct ncp_inode_info *result_info; int found_in_cache; int down_case = 0; - char name[len+1]; + char name[len + 1]; *result = NULL; - if (!dir || !S_ISDIR(dir->i_mode)) - { + if (!dir || !S_ISDIR(dir->i_mode)) { printk("ncp_lookup: inode is NULL or not a directory.\n"); iput(dir); return -ENOENT; } - server = NCP_SERVER(dir); - if (!ncp_conn_valid(server)) - { + if (!ncp_conn_valid(server)) { iput(dir); return -EIO; } - DPRINTK("ncp_lookup: %s, len %d\n", __name, len); /* Fast cheat for . */ - if (len == 0 || (len == 1 && __name[0] == '.')) - { + if (len == 0 || (len == 1 && __name[0] == '.')) { *result = dir; return 0; } - /* ..and for .. */ - if (len == 2 && __name[0] == '.' && __name[1] == '.') - { + if (len == 2 && __name[0] == '.' && __name[1] == '.') { struct ncp_inode_info *parent = NCP_INOP(dir)->dir; - if (parent->state == NCP_INODE_CACHED) - { + if (parent->state == NCP_INODE_CACHED) { parent->state = NCP_INODE_LOOKED_UP; } - *result = iget(dir->i_sb, ncp_info_ino(server, parent)); iput(dir); - if (*result == 0) - { + if (*result == 0) { return -EACCES; - } - else - { + } else { return 0; } } - memcpy(name, __name, len); name[len] = 0; lock_super(dir->i_sb); result_info = ncp_find_dir_inode(dir, name); - if (result_info != 0) - { - if (result_info->state == NCP_INODE_CACHED) - { - result_info->state = NCP_INODE_LOOKED_UP; + if (result_info != 0) { + if (result_info->state == NCP_INODE_CACHED) { + result_info->state = NCP_INODE_LOOKED_UP; } + /* Here we convert the inode_info address into an + inode number */ - /* Here we convert the inode_info address into an - inode number */ - - *result = iget(dir->i_sb, ncp_info_ino(server, result_info)); + *result = iget(dir->i_sb, ncp_info_ino(server, result_info)); unlock_super(dir->i_sb); - iput(dir); - - if (*result == NULL) - { - return -EACCES; - } + iput(dir); + if (*result == NULL) { + return -EACCES; + } return 0; - } - - /* If the file is in the dir cache, we do not have to ask the - server. */ + } + /* If the file is in the dir cache, we do not have to ask the + server. */ - found_in_cache = 0; + found_in_cache = 0; ncp_lock_dircache(); - if ((dir->i_dev == c_dev) && (dir->i_ino == c_ino)) - { - int first = c_last_returned_index; - int i; - - i = first; - do - { - DDPRINTK("ncp_lookup: trying index: %d, name: %s\n", + if ((dir->i_dev == c_dev) && (dir->i_ino == c_ino)) { + int first = c_last_returned_index; + int i; + + i = first; + do { + DDPRINTK("ncp_lookup: trying index: %d, name: %s\n", i, c_entry[i].i.entryName); - if (strcmp(c_entry[i].i.entryName, name) == 0) - { - DPRINTK("ncp_lookup: found in cache!\n"); + if (strcmp(c_entry[i].i.entryName, name) == 0) { + DPRINTK("ncp_lookup: found in cache!\n"); finfo.i = c_entry[i].i; found_in_cache = 1; break; - } - i = (i + 1) % c_size; - } + } + i = (i + 1) % c_size; + } while (i != first); - } + } ncp_unlock_dircache(); - if (found_in_cache == 0) - { + if (found_in_cache == 0) { int res; DDPRINTK("ncp_lookup: do_lookup on %s/%s\n", NCP_ISTRUCT(dir)->entryName, name); - if (ncp_is_server_root(dir)) - { + if (ncp_is_server_root(dir)) { str_upper(name); down_case = 1; res = ncp_lookup_volume(server, name, &(finfo.i)); - } - else - { - if (!ncp_preserve_case(dir)) - { + } else { + if (!ncp_preserve_case(dir)) { str_upper(name); down_case = 1; } @@ -913,313 +776,246 @@ NCP_ISTRUCT(dir)->dirEntNum, name, &(finfo.i)); } - if (res != 0) - { + if (res != 0) { unlock_super(dir->i_sb); - iput(dir); - return -ENOENT; - } - } - + iput(dir); + return -ENOENT; + } + } finfo.opened = 0; - if (down_case != 0) - { + if (down_case != 0) { str_lower(finfo.i.entryName); } - - if (!(*result = ncp_iget(dir, &finfo))) - { + if (!(*result = ncp_iget(dir, &finfo))) { unlock_super(dir->i_sb); iput(dir); return -EACCES; } - unlock_super(dir->i_sb); iput(dir); return 0; } -static int -ncp_create(struct inode *dir, const char *name, int len, int mode, - struct inode **result) +static int ncp_create(struct inode *dir, const char *name, int len, int mode, + struct inode **result) { struct nw_file_info finfo; - __u8 _name[len+1]; + __u8 _name[len + 1]; *result = NULL; - if (!dir || !S_ISDIR(dir->i_mode)) - { + if (!dir || !S_ISDIR(dir->i_mode)) { printk("ncp_create: inode is NULL or not a directory\n"); iput(dir); return -ENOENT; } - if (!ncp_conn_valid(NCP_SERVER(dir))) - { + if (!ncp_conn_valid(NCP_SERVER(dir))) { iput(dir); return -EIO; } - strncpy(_name, name, len); _name[len] = '\0'; - if (!ncp_preserve_case(dir)) - { + if (!ncp_preserve_case(dir)) { str_upper(_name); } - lock_super(dir->i_sb); if (ncp_open_create_file_or_subdir(NCP_SERVER(dir), NCP_ISTRUCT(dir), _name, - OC_MODE_CREATE|OC_MODE_OPEN| + OC_MODE_CREATE | OC_MODE_OPEN | OC_MODE_REPLACE, - 0, AR_READ|AR_WRITE, - &finfo) != 0) - { + 0, AR_READ | AR_WRITE, + &finfo) != 0) { unlock_super(dir->i_sb); iput(dir); return -EACCES; } - ncp_invalid_dir_cache(dir); - if (!ncp_preserve_case(dir)) - { + if (!ncp_preserve_case(dir)) { str_lower(finfo.i.entryName); } - finfo.access = O_RDWR; - if (!(*result = ncp_iget(dir, &finfo)) < 0) - { + if (!(*result = ncp_iget(dir, &finfo)) < 0) { ncp_close_file(NCP_SERVER(dir), finfo.file_handle); unlock_super(dir->i_sb); iput(dir); return -EINVAL; } - unlock_super(dir->i_sb); iput(dir); - return 0; + return 0; } -static int -ncp_mkdir(struct inode *dir, const char *name, int len, int mode) +static int ncp_mkdir(struct inode *dir, const char *name, int len, int mode) { int error; struct nw_file_info new_dir; - __u8 _name[len+1]; + __u8 _name[len + 1]; - if ( (name[0] == '.') - && ( (len == 1) - || ( (len == 2) - && (name[1] == '.')))) - { + if ((name[0] == '.') + && ((len == 1) + || ((len == 2) + && (name[1] == '.')))) { iput(dir); return -EEXIST; } - strncpy(_name, name, len); _name[len] = '\0'; - if (!ncp_preserve_case(dir)) - { + if (!ncp_preserve_case(dir)) { str_upper(_name); } - - if (!dir || !S_ISDIR(dir->i_mode)) - { + if (!dir || !S_ISDIR(dir->i_mode)) { printk("ncp_mkdir: inode is NULL or not a directory\n"); iput(dir); return -ENOENT; } - if (!ncp_conn_valid(NCP_SERVER(dir))) - { + if (!ncp_conn_valid(NCP_SERVER(dir))) { iput(dir); return -EIO; } - if (ncp_open_create_file_or_subdir(NCP_SERVER(dir), NCP_ISTRUCT(dir), _name, OC_MODE_CREATE, aDIR, 0xffff, - &new_dir) != 0) - { + &new_dir) != 0) { error = -EACCES; - } - else - { + } else { error = 0; - ncp_invalid_dir_cache(dir); - } + ncp_invalid_dir_cache(dir); + } iput(dir); return error; } -static int -ncp_rmdir(struct inode *dir, const char *name, int len) +static int ncp_rmdir(struct inode *dir, const char *name, int len) { int error; - __u8 _name[len+1]; + __u8 _name[len + 1]; - if (!dir || !S_ISDIR(dir->i_mode)) - { + if (!dir || !S_ISDIR(dir->i_mode)) { printk("ncp_rmdir: inode is NULL or not a directory\n"); iput(dir); return -ENOENT; } - if (!ncp_conn_valid(NCP_SERVER(dir))) - { + if (!ncp_conn_valid(NCP_SERVER(dir))) { iput(dir); return -EIO; } - if (ncp_find_dir_inode(dir, name) != NULL) - { + if (ncp_find_dir_inode(dir, name) != NULL) { iput(dir); - error = -EBUSY; - } - else - { + error = -EBUSY; + } else { strncpy(_name, name, len); _name[len] = '\0'; - if (!ncp_preserve_case(dir)) - { + if (!ncp_preserve_case(dir)) { str_upper(_name); } - - if ((error = ncp_del_file_or_subdir(NCP_SERVER(dir), + if ((error = ncp_del_file_or_subdir(NCP_SERVER(dir), NCP_ISTRUCT(dir), - _name)) == 0) - { - ncp_invalid_dir_cache(dir); - } - else - { + _name)) == 0) { + ncp_invalid_dir_cache(dir); + } else { error = -EACCES; } - } + } iput(dir); return error; } -static int -ncp_unlink(struct inode *dir, const char *name, int len) +static int ncp_unlink(struct inode *dir, const char *name, int len) { int error; - __u8 _name[len+1]; + __u8 _name[len + 1]; - if (!dir || !S_ISDIR(dir->i_mode)) - { + if (!dir || !S_ISDIR(dir->i_mode)) { printk("ncp_unlink: inode is NULL or not a directory\n"); iput(dir); return -ENOENT; } - if (!ncp_conn_valid(NCP_SERVER(dir))) - { + if (!ncp_conn_valid(NCP_SERVER(dir))) { iput(dir); return -EIO; } - if (ncp_find_dir_inode(dir, name) != NULL) - { + if (ncp_find_dir_inode(dir, name) != NULL) { iput(dir); - error = -EBUSY; - } - else - { + error = -EBUSY; + } else { strncpy(_name, name, len); _name[len] = '\0'; - if (!ncp_preserve_case(dir)) - { + if (!ncp_preserve_case(dir)) { str_upper(_name); } - - if ((error = ncp_del_file_or_subdir(NCP_SERVER(dir), + if ((error = ncp_del_file_or_subdir(NCP_SERVER(dir), NCP_ISTRUCT(dir), - _name)) == 0) - { - ncp_invalid_dir_cache(dir); - } - else - { + _name)) == 0) { + ncp_invalid_dir_cache(dir); + } else { error = -EACCES; } - } + } iput(dir); return error; } -static int -ncp_rename(struct inode *old_dir, const char *old_name, int old_len, - struct inode *new_dir, const char *new_name, int new_len, - int must_be_dir) +static int ncp_rename(struct inode *old_dir, const char *old_name, int old_len, + struct inode *new_dir, const char *new_name, int new_len, + int must_be_dir) { int res; - char _old_name[old_len+1]; - char _new_name[new_len+1]; + char _old_name[old_len + 1]; + char _new_name[new_len + 1]; - if (!old_dir || !S_ISDIR(old_dir->i_mode)) - { + if (!old_dir || !S_ISDIR(old_dir->i_mode)) { printk("ncp_rename: old inode is NULL or not a directory\n"); - res = -ENOENT; - goto finished; + res = -ENOENT; + goto finished; } - - if (!ncp_conn_valid(NCP_SERVER(old_dir))) - { + if (!ncp_conn_valid(NCP_SERVER(old_dir))) { res = -EIO; goto finished; } - - if (!new_dir || !S_ISDIR(new_dir->i_mode)) - { + if (!new_dir || !S_ISDIR(new_dir->i_mode)) { printk("ncp_rename: new inode is NULL or not a directory\n"); - res = -ENOENT; - goto finished; + res = -ENOENT; + goto finished; + } + if ((ncp_find_dir_inode(old_dir, old_name) != NULL) + || (ncp_find_dir_inode(new_dir, new_name) != NULL)) { + res = -EBUSY; + goto finished; } - - if ( (ncp_find_dir_inode(old_dir, old_name) != NULL) - || (ncp_find_dir_inode(new_dir, new_name) != NULL)) - { - res = -EBUSY; - goto finished; - } - strncpy(_old_name, old_name, old_len); _old_name[old_len] = '\0'; - if (!ncp_preserve_case(old_dir)) - { + if (!ncp_preserve_case(old_dir)) { str_upper(_old_name); } - strncpy(_new_name, new_name, new_len); _new_name[new_len] = '\0'; - if (!ncp_preserve_case(new_dir)) - { + if (!ncp_preserve_case(new_dir)) { str_upper(_new_name); } - res = ncp_ren_or_mov_file_or_subdir(NCP_SERVER(old_dir), - NCP_ISTRUCT(old_dir), _old_name, - NCP_ISTRUCT(new_dir), _new_name); + NCP_ISTRUCT(old_dir), _old_name, + NCP_ISTRUCT(new_dir), _new_name); - if (res == 0) - { - ncp_invalid_dir_cache(old_dir); - ncp_invalid_dir_cache(new_dir); - } - else - { + if (res == 0) { + ncp_invalid_dir_cache(old_dir); + ncp_invalid_dir_cache(new_dir); + } else { res = -EACCES; } - - finished: - iput(old_dir); + + finished: + iput(old_dir); iput(new_dir); return res; } @@ -1228,64 +1024,62 @@ /* Linear day numbers of the respective 1sts in non-leap years. */ -static int day_n[] = { 0,31,59,90,120,151,181,212,243,273,304,334,0,0,0,0 }; +static int day_n[] = +{0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 0, 0, 0, 0}; /* JanFebMarApr May Jun Jul Aug Sep Oct Nov Dec */ extern struct timezone sys_tz; -static int -utc2local(int time) +static int utc2local(int time) { - return time - sys_tz.tz_minuteswest*60 + + return time - sys_tz.tz_minuteswest * 60 + (sys_tz.tz_dsttime ? 3600 : 0); } -static int -local2utc(int time) +static int local2utc(int time) { - return time + sys_tz.tz_minuteswest*60 - + return time + sys_tz.tz_minuteswest * 60 - (sys_tz.tz_dsttime ? 3600 : 0); } /* Convert a MS-DOS time/date pair to a UNIX date (seconds since 1 1 70). */ -int -ncp_date_dos2unix(unsigned short time,unsigned short date) +int ncp_date_dos2unix(unsigned short time, unsigned short date) { - int month,year,secs; + int month, year, secs; - month = ((date >> 5) & 15)-1; + month = ((date >> 5) & 15) - 1; year = date >> 9; - secs = (time & 31)*2+60*((time >> 5) & 63)+(time >> 11)*3600+86400* - ((date & 31)-1+day_n[month]+(year/4)+year*365-((year & 3) == 0 && - month < 2 ? 1 : 0)+3653); - /* days since 1.1.70 plus 80's leap day */ + secs = (time & 31) * 2 + 60 * ((time >> 5) & 63) + (time >> 11) * 3600 + 86400 * + ((date & 31) - 1 + day_n[month] + (year / 4) + year * 365 - ((year & 3) == 0 && + month < 2 ? 1 : 0) + 3653); + /* days since 1.1.70 plus 80's leap day */ return local2utc(secs); } /* Convert linear UNIX date to a MS-DOS time/date pair. */ -void -ncp_date_unix2dos(int unix_date,unsigned short *time, unsigned short *date) +void ncp_date_unix2dos(int unix_date, unsigned short *time, unsigned short *date) { - int day,year,nl_day,month; + int day, year, nl_day, month; unix_date = utc2local(unix_date); - *time = (unix_date % 60)/2+(((unix_date/60) % 60) << 5)+ - (((unix_date/3600) % 24) << 11); - day = unix_date/86400-3652; - year = day/365; - if ((year+3)/4+365*year > day) year--; - day -= (year+3)/4+365*year; + *time = (unix_date % 60) / 2 + (((unix_date / 60) % 60) << 5) + + (((unix_date / 3600) % 24) << 11); + day = unix_date / 86400 - 3652; + year = day / 365; + if ((year + 3) / 4 + 365 * year > day) + year--; + day -= (year + 3) / 4 + 365 * year; if (day == 59 && !(year & 3)) { nl_day = day; month = 2; - } - else { - nl_day = (year & 3) || day <= 59 ? day : day-1; + } else { + nl_day = (year & 3) || day <= 59 ? day : day - 1; for (month = 0; month < 12; month++) - if (day_n[month] > nl_day) break; + if (day_n[month] > nl_day) + break; } - *date = nl_day-day_n[month-1]+1+(month << 5)+(year << 9); + *date = nl_day - day_n[month - 1] + 1 + (month << 5) + (year << 9); } diff -u --recursive --new-file v2.1.30/linux/fs/ncpfs/file.c linux/fs/ncpfs/file.c --- v2.1.30/linux/fs/ncpfs/file.c Sun Jan 26 02:07:44 1997 +++ linux/fs/ncpfs/file.c Fri Mar 28 10:42:22 1997 @@ -21,215 +21,172 @@ static inline int min(int a, int b) { - return aopened = %d\n", finfo->opened); + DPRINTK("ncp_make_open: dirent->opened = %d\n", finfo->opened); lock_super(i->i_sb); - if (finfo->opened == 0) - { + if (finfo->opened == 0) { finfo->access = -1; - /* tries max. rights */ + /* tries max. rights */ if (ncp_open_create_file_or_subdir(NCP_SERVER(i), NULL, NULL, OC_MODE_OPEN, 0, AR_READ | AR_WRITE, - finfo) == 0) - { + finfo) == 0) { finfo->access = O_RDWR; - } - else if (ncp_open_create_file_or_subdir(NCP_SERVER(i), - NULL, NULL, - OC_MODE_OPEN, 0, - AR_READ, - finfo) == 0) - { + } else if (ncp_open_create_file_or_subdir(NCP_SERVER(i), + NULL, NULL, + OC_MODE_OPEN, 0, + AR_READ, + finfo) == 0) { finfo->access = O_RDONLY; } - } - + } unlock_super(i->i_sb); - if ( ((right == O_RDONLY) && ( (finfo->access == O_RDONLY) - || (finfo->access == O_RDWR))) - || ((right == O_WRONLY) && ( (finfo->access == O_WRONLY) - || (finfo->access == O_RDWR))) - || ((right == O_RDWR) && (finfo->access == O_RDWR))) - return 0; + if (((right == O_RDONLY) && ((finfo->access == O_RDONLY) + || (finfo->access == O_RDWR))) + || ((right == O_WRONLY) && ((finfo->access == O_WRONLY) + || (finfo->access == O_RDWR))) + || ((right == O_RDWR) && (finfo->access == O_RDWR))) + return 0; - return -EACCES; + return -EACCES; } -static long -ncp_file_read(struct inode *inode, struct file *file, char *buf, unsigned long count) +static long ncp_file_read(struct inode *inode, struct file *file, char *buf, unsigned long count) { int bufsize, already_read; off_t pos; - int errno; + int errno; - DPRINTK("ncp_file_read: enter %s\n", NCP_ISTRUCT(inode)->entryName); - - if (inode == NULL) - { + DPRINTK("ncp_file_read: enter %s\n", NCP_ISTRUCT(inode)->entryName); + + if (inode == NULL) { DPRINTK("ncp_file_read: inode = NULL\n"); return -EINVAL; } - if (!ncp_conn_valid(NCP_SERVER(inode))) - { + if (!ncp_conn_valid(NCP_SERVER(inode))) { return -EIO; } - - if (!S_ISREG(inode->i_mode)) - { + if (!S_ISREG(inode->i_mode)) { DPRINTK("ncp_file_read: read from non-file, mode %07o\n", - inode->i_mode); + inode->i_mode); return -EINVAL; } - pos = file->f_pos; - if (pos + count > inode->i_size) - { + if (pos + count > inode->i_size) { count = inode->i_size - pos; } - - if (count <= 0) - { + if (count <= 0) { return 0; } - - if ((errno = ncp_make_open(inode, O_RDONLY)) != 0) - { - return errno; + if ((errno = ncp_make_open(inode, O_RDONLY)) != 0) { + return errno; } - bufsize = NCP_SERVER(inode)->buffer_size; - already_read = 0; + already_read = 0; /* First read in as much as possible for each bufsize. */ - while (already_read < count) - { + while (already_read < count) { int read_this_time; int to_read = min(bufsize - (pos % bufsize), count - already_read); if (ncp_read(NCP_SERVER(inode), NCP_FINFO(inode)->file_handle, - pos, to_read, buf, &read_this_time) != 0) - { - return -EIO; /* This is not exact, i know.. */ + pos, to_read, buf, &read_this_time) != 0) { + return -EIO; /* This is not exact, i know.. */ } - pos += read_this_time; buf += read_this_time; - already_read += read_this_time; + already_read += read_this_time; - if (read_this_time < to_read) - { - break; + if (read_this_time < to_read) { + break; } } - file->f_pos = pos; + file->f_pos = pos; - if (!IS_RDONLY(inode)) - { + if (!IS_RDONLY(inode)) { inode->i_atime = CURRENT_TIME; } - inode->i_dirt = 1; - DPRINTK("ncp_file_read: exit %s\n", NCP_ISTRUCT(inode)->entryName); + DPRINTK("ncp_file_read: exit %s\n", NCP_ISTRUCT(inode)->entryName); - return already_read; + return already_read; } -static long -ncp_file_write(struct inode *inode, struct file *file, const char *buf, - unsigned long count) +static long ncp_file_write(struct inode *inode, struct file *file, const char *buf, + unsigned long count) { int bufsize, already_written; - off_t pos; - int errno; - - if (inode == NULL) - { + off_t pos; + int errno; + + if (inode == NULL) { DPRINTK("ncp_file_write: inode = NULL\n"); return -EINVAL; } - if (!ncp_conn_valid(NCP_SERVER(inode))) - { + if (!ncp_conn_valid(NCP_SERVER(inode))) { return -EIO; } - - if (!S_ISREG(inode->i_mode)) - { + if (!S_ISREG(inode->i_mode)) { DPRINTK("ncp_file_write: write to non-file, mode %07o\n", - inode->i_mode); + inode->i_mode); return -EINVAL; } + DPRINTK("ncp_file_write: enter %s\n", NCP_ISTRUCT(inode)->entryName); - DPRINTK("ncp_file_write: enter %s\n", NCP_ISTRUCT(inode)->entryName); - - if (count <= 0) - { + if (count <= 0) { return 0; } - - if ((errno = ncp_make_open(inode, O_RDWR)) != 0) - { - return errno; + if ((errno = ncp_make_open(inode, O_RDWR)) != 0) { + return errno; } - pos = file->f_pos; - if (file->f_flags & O_APPEND) - { + if (file->f_flags & O_APPEND) { pos = inode->i_size; } - bufsize = NCP_SERVER(inode)->buffer_size; - already_written = 0; + already_written = 0; - while (already_written < count) - { + while (already_written < count) { int written_this_time; int to_write = min(bufsize - (pos % bufsize), count - already_written); if (ncp_write(NCP_SERVER(inode), NCP_FINFO(inode)->file_handle, - pos, to_write, buf, &written_this_time) != 0) - { + pos, to_write, buf, &written_this_time) != 0) { return -EIO; - } - + } pos += written_this_time; buf += written_this_time; already_written += written_this_time; - if (written_this_time < to_write) - { + if (written_this_time < to_write) { break; } } @@ -239,18 +196,17 @@ file->f_pos = pos; - if (pos > inode->i_size) - { - inode->i_size = pos; + if (pos > inode->i_size) { + inode->i_size = pos; ncp_invalid_dir_cache(NCP_INOP(inode)->dir->inode); - } - - DPRINTK("ncp_file_write: exit %s\n", NCP_ISTRUCT(inode)->entryName); + } + DPRINTK("ncp_file_write: exit %s\n", NCP_ISTRUCT(inode)->entryName); return already_written; } -static struct file_operations ncp_file_operations = { +static struct file_operations ncp_file_operations = +{ NULL, /* lseek - default */ ncp_file_read, /* read */ ncp_file_write, /* write */ @@ -258,12 +214,13 @@ NULL, /* poll - default */ ncp_ioctl, /* ioctl */ ncp_mmap, /* mmap */ - NULL, /* open */ - NULL, /* release */ + NULL, /* open */ + NULL, /* release */ ncp_fsync, /* fsync */ }; -struct inode_operations ncp_file_inode_operations = { +struct inode_operations ncp_file_inode_operations = +{ &ncp_file_operations, /* default file operations */ NULL, /* create */ NULL, /* lookup */ diff -u --recursive --new-file v2.1.30/linux/fs/ncpfs/inode.c linux/fs/ncpfs/inode.c --- v2.1.30/linux/fs/ncpfs/inode.c Sun Jan 19 05:47:26 1997 +++ linux/fs/ncpfs/inode.c Fri Mar 28 10:42:22 1997 @@ -36,8 +36,9 @@ static void ncp_statfs(struct super_block *sb, struct statfs *buf, int bufsiz); static int ncp_notify_change(struct inode *inode, struct iattr *attr); -static struct super_operations ncp_sops = { - ncp_read_inode, /* read inode */ +static struct super_operations ncp_sops = +{ + ncp_read_inode, /* read inode */ ncp_notify_change, /* notify change */ NULL, /* write inode */ ncp_put_inode, /* put inode */ @@ -51,202 +52,150 @@ ncp_inode_info's and initializes the inode from the data found there. It does not allocate or deallocate anything. */ -static void -ncp_read_inode(struct inode *inode) +static void ncp_read_inode(struct inode *inode) { - /* Our task should be extremely simple here. We only have to - look up the information somebody else (ncp_iget) put into - the inode tree. The address of this information is the - inode->i_ino. Just to make sure everything went well, we - check it's there. */ + /* Our task should be extremely simple here. We only have to + look up the information somebody else (ncp_iget) put into + the inode tree. The address of this information is the + inode->i_ino. Just to make sure everything went well, we + check it's there. */ - struct ncp_inode_info *inode_info = ncp_find_inode(inode); + struct ncp_inode_info *inode_info = ncp_find_inode(inode); - if (inode_info == NULL) - { + if (inode_info == NULL) { /* Ok, now we're in trouble. The inode info is not there. What should we do now??? */ printk("ncp_read_inode: inode info not found\n"); return; } + inode_info->state = NCP_INODE_VALID; - inode_info->state = NCP_INODE_VALID; - - NCP_INOP(inode) = inode_info; + NCP_INOP(inode) = inode_info; inode_info->inode = inode; - if (NCP_ISTRUCT(inode)->attributes & aDIR) - { - inode->i_mode = NCP_SERVER(inode)->m.dir_mode; + if (NCP_ISTRUCT(inode)->attributes & aDIR) { + inode->i_mode = NCP_SERVER(inode)->m.dir_mode; /* for directories dataStreamSize seems to be some Object ID ??? */ inode->i_size = 512; - } - else - { - inode->i_mode = NCP_SERVER(inode)->m.file_mode; + } else { + inode->i_mode = NCP_SERVER(inode)->m.file_mode; inode->i_size = le32_to_cpu(NCP_ISTRUCT(inode)->dataStreamSize); } - DDPRINTK("ncp_read_inode: inode->i_mode = %u\n", inode->i_mode); + DDPRINTK("ncp_read_inode: inode->i_mode = %u\n", inode->i_mode); - inode->i_nlink = 1; - inode->i_uid = NCP_SERVER(inode)->m.uid; - inode->i_gid = NCP_SERVER(inode)->m.gid; - inode->i_blksize = 512; - inode->i_rdev = 0; - - if ((inode->i_blksize != 0) && (inode->i_size != 0)) - { - inode->i_blocks = - (inode->i_size - 1) / inode->i_blksize + 1; - } - else - { - inode->i_blocks = 0; + inode->i_nlink = 1; + inode->i_uid = NCP_SERVER(inode)->m.uid; + inode->i_gid = NCP_SERVER(inode)->m.gid; + inode->i_blksize = 512; + inode->i_rdev = 0; + + if ((inode->i_blksize != 0) && (inode->i_size != 0)) { + inode->i_blocks = + (inode->i_size - 1) / inode->i_blksize + 1; + } else { + inode->i_blocks = 0; } inode->i_mtime = ncp_date_dos2unix(le16_to_cpu(NCP_ISTRUCT(inode)->modifyTime), - le16_to_cpu(NCP_ISTRUCT(inode)->modifyDate)); + le16_to_cpu(NCP_ISTRUCT(inode)->modifyDate)); inode->i_ctime = ncp_date_dos2unix(le16_to_cpu(NCP_ISTRUCT(inode)->creationTime), - le16_to_cpu(NCP_ISTRUCT(inode)->creationDate)); + le16_to_cpu(NCP_ISTRUCT(inode)->creationDate)); inode->i_atime = ncp_date_dos2unix(0, - le16_to_cpu(NCP_ISTRUCT(inode)->lastAccessDate)); + le16_to_cpu(NCP_ISTRUCT(inode)->lastAccessDate)); - if (S_ISREG(inode->i_mode)) - { - inode->i_op = &ncp_file_inode_operations; - } - else if (S_ISDIR(inode->i_mode)) - { - inode->i_op = &ncp_dir_inode_operations; - } - else - { - inode->i_op = NULL; + if (S_ISREG(inode->i_mode)) { + inode->i_op = &ncp_file_inode_operations; + } else if (S_ISDIR(inode->i_mode)) { + inode->i_op = &ncp_dir_inode_operations; + } else { + inode->i_op = NULL; } } -static void -ncp_put_inode(struct inode *inode) +static void ncp_put_inode(struct inode *inode) { - struct nw_file_info *finfo = NCP_FINFO(inode); + struct nw_file_info *finfo = NCP_FINFO(inode); struct super_block *sb = inode->i_sb; lock_super(sb); - if (finfo->opened != 0) - { - if (ncp_close_file(NCP_SERVER(inode), finfo->file_handle)!=0) - { - /* We can't do anything but complain. */ - printk("ncp_put_inode: could not close\n"); - } - } - + if (finfo->opened != 0) { + if (ncp_close_file(NCP_SERVER(inode), finfo->file_handle) != 0) { + /* We can't do anything but complain. */ + printk("ncp_put_inode: could not close\n"); + } + } DDPRINTK("ncp_put_inode: put %s\n", - finfo->i.entryName); + finfo->i.entryName); - ncp_free_inode_info(NCP_INOP(inode)); + ncp_free_inode_info(NCP_INOP(inode)); - if (S_ISDIR(inode->i_mode)) - { - DDPRINTK("ncp_put_inode: put directory %ld\n", + if (S_ISDIR(inode->i_mode)) { + DDPRINTK("ncp_put_inode: put directory %ld\n", inode->i_ino); - ncp_invalid_dir_cache(inode); - } - + ncp_invalid_dir_cache(inode); + } clear_inode(inode); unlock_super(sb); } struct super_block * -ncp_read_super(struct super_block *sb, void *raw_data, int silent) + ncp_read_super(struct super_block *sb, void *raw_data, int silent) { struct ncp_mount_data *data = (struct ncp_mount_data *) raw_data; - struct ncp_server *server; + struct ncp_server *server; struct file *ncp_filp; - struct file *wdog_filp; - struct file *msg_filp; kdev_t dev = sb->s_dev; int error; - if (data == NULL) - { + if (data == NULL) { printk("ncp_read_super: missing data argument\n"); sb->s_dev = 0; return NULL; } - - if (data->version != NCP_MOUNT_VERSION) - { + if (data->version != NCP_MOUNT_VERSION) { printk("ncp warning: mount version %s than kernel\n", (data->version < NCP_MOUNT_VERSION) ? - "older" : "newer"); + "older" : "newer"); sb->s_dev = 0; return NULL; } - - if ( (data->ncp_fd >= NR_OPEN) + if ((data->ncp_fd >= NR_OPEN) || ((ncp_filp = current->files->fd[data->ncp_fd]) == NULL) - || (!S_ISSOCK(ncp_filp->f_inode->i_mode))) - { + || (!S_ISSOCK(ncp_filp->f_inode->i_mode))) { printk("ncp_read_super: invalid ncp socket\n"); sb->s_dev = 0; return NULL; } + /* We must malloc our own super-block info */ + server = (struct ncp_server *) ncp_kmalloc(sizeof(struct ncp_server), + GFP_KERNEL); - if ( (data->wdog_fd >= NR_OPEN) - || ((wdog_filp = current->files->fd[data->wdog_fd]) == NULL) - || (!S_ISSOCK(wdog_filp->f_inode->i_mode))) - { - printk("ncp_read_super: invalid wdog socket\n"); - sb->s_dev = 0; + if (server == NULL) { + printk("ncp_read_super: could not alloc ncp_server\n"); return NULL; } - - if ( (data->message_fd >= NR_OPEN) - || ((msg_filp = current->files->fd[data->message_fd]) == NULL) - || (!S_ISSOCK(msg_filp->f_inode->i_mode))) - { - printk("ncp_read_super: invalid wdog socket\n"); - sb->s_dev = 0; - return NULL; - } - - /* We must malloc our own super-block info */ - server = (struct ncp_server *)ncp_kmalloc(sizeof(struct ncp_server), - GFP_KERNEL); - - if (server == NULL) - { - printk("ncp_read_super: could not alloc ncp_server\n"); - return NULL; - } - ncp_filp->f_count += 1; - wdog_filp->f_count += 1; - msg_filp->f_count += 1; lock_super(sb); - NCP_SBP(sb) = server; + NCP_SBP(sb) = server; - sb->s_blocksize = 1024; /* Eh... Is this correct? */ + sb->s_blocksize = 1024; /* Eh... Is this correct? */ sb->s_blocksize_bits = 10; sb->s_magic = NCP_SUPER_MAGIC; sb->s_dev = dev; sb->s_op = &ncp_sops; - server->ncp_filp = ncp_filp; - server->wdog_filp = wdog_filp; - server->msg_filp = msg_filp; - server->lock = 0; - server->wait = NULL; - server->packet = NULL; + server->ncp_filp = ncp_filp; + server->lock = 0; + server->wait = NULL; + server->packet = NULL; server->buffer_size = 0; server->conn_status = 0; - server->m = *data; + server->m = *data; /* Althought anything producing this is buggy, it happens now because of PATH_MAX changes.. */ if (server->m.time_out < 10) { @@ -254,166 +203,98 @@ printk("You need to recompile your ncpfs utils..\n"); } server->m.file_mode = (server->m.file_mode & - (S_IRWXU|S_IRWXG|S_IRWXO)) | S_IFREG; - server->m.dir_mode = (server->m.dir_mode & - (S_IRWXU|S_IRWXG|S_IRWXO)) | S_IFDIR; - - /* protect against invalid mount points */ - server->m.mount_point[sizeof(server->m.mount_point)-1] = '\0'; + (S_IRWXU | S_IRWXG | S_IRWXO)) | S_IFREG; + server->m.dir_mode = (server->m.dir_mode & + (S_IRWXU | S_IRWXG | S_IRWXO)) | S_IFDIR; server->packet_size = NCP_PACKET_SIZE; - server->packet = ncp_kmalloc(NCP_PACKET_SIZE, GFP_KERNEL); + server->packet = ncp_kmalloc(NCP_PACKET_SIZE, GFP_KERNEL); - if (server->packet == NULL) - { + if (server->packet == NULL) { printk("ncpfs: could not alloc packet\n"); error = -ENOMEM; unlock_super(sb); goto fail; } - - /* - * Make the connection to the server - */ - - if (ncp_catch_watchdog(server) != 0) - { - printk("ncp_read_super: Could not catch watchdog\n"); - error = -EINVAL; - unlock_super(sb); - goto fail; - } - - if (ncp_catch_message(server) != 0) - { - printk("ncp_read_super: Could not catch messages\n"); - ncp_dont_catch_watchdog(server); - error = -EINVAL; - unlock_super(sb); - goto fail; - } - ncp_lock_server(server); error = ncp_connect(server); ncp_unlock_server(server); unlock_super(sb); - if (error < 0) - { + if (error < 0) { sb->s_dev = 0; printk("ncp_read_super: Failed connection, bailing out " - "(error = %d).\n", -error); - ncp_kfree_s(server->packet, server->packet_size); - ncp_dont_catch_watchdog(server); - goto fail; + "(error = %d).\n", -error); + ncp_kfree_s(server->packet, server->packet_size); + goto fail; } - - DPRINTK("ncp_read_super: NCP_SBP(sb) = %x\n", (int)NCP_SBP(sb)); + DPRINTK("ncp_read_super: NCP_SBP(sb) = %x\n", (int) NCP_SBP(sb)); ncp_init_root(server); - if (!(sb->s_mounted = iget(sb, ncp_info_ino(server, &(server->root))))) - { + if (!(sb->s_mounted = iget(sb, ncp_info_ino(server, + &(server->root))))) { sb->s_dev = 0; printk("ncp_read_super: get root inode failed\n"); - goto disconnect; + goto disconnect; } - if (ncp_negotiate_buffersize(server, NCP_DEFAULT_BUFSIZE, - &(server->buffer_size)) != 0) - { + &(server->buffer_size)) != 0) { sb->s_dev = 0; printk("ncp_read_super: could not get bufsize\n"); goto disconnect; } - DPRINTK("ncpfs: bufsize = %d\n", server->buffer_size); - MOD_INC_USE_COUNT; + MOD_INC_USE_COUNT; return sb; - disconnect: + disconnect: ncp_lock_server(server); ncp_disconnect(server); ncp_unlock_server(server); ncp_kfree_s(server->packet, server->packet_size); - ncp_dont_catch_watchdog(server); - fail: + fail: ncp_filp->f_count -= 1; - wdog_filp->f_count -= 1; - msg_filp->f_count -= 1; - ncp_kfree_s(NCP_SBP(sb), sizeof(struct ncp_server)); - return NULL; + ncp_kfree_s(NCP_SBP(sb), sizeof(struct ncp_server)); + return NULL; } -static void -ncp_put_super(struct super_block *sb) +static void ncp_put_super(struct super_block *sb) { - struct ncp_server *server = NCP_SBP(sb); + struct ncp_server *server = NCP_SBP(sb); lock_super(sb); ncp_lock_server(server); - ncp_disconnect(server); + ncp_disconnect(server); ncp_unlock_server(server); close_fp(server->ncp_filp); + kill_proc(server->m.wdog_pid, SIGTERM, 0); - ncp_dont_catch_watchdog(server); - close_fp(server->wdog_filp); - close_fp(server->msg_filp); - - ncp_free_all_inodes(server); + ncp_free_all_inodes(server); - ncp_kfree_s(server->packet, server->packet_size); + ncp_kfree_s(server->packet, server->packet_size); sb->s_dev = 0; - ncp_kfree_s(NCP_SBP(sb), sizeof(struct ncp_server)); + ncp_kfree_s(NCP_SBP(sb), sizeof(struct ncp_server)); NCP_SBP(sb) = NULL; unlock_super(sb); - MOD_DEC_USE_COUNT; + MOD_DEC_USE_COUNT; } -/* This routine is called from an interrupt in ncp_msg_data_ready. So - * we have to be careful NOT to sleep here! */ -void -ncp_trigger_message(struct ncp_server *server) -{ -#ifdef CONFIG_KERNELD - char command[ sizeof(server->m.mount_point) - + sizeof(NCP_MSG_COMMAND) + 2]; -#endif - - if (server == NULL) - { - printk("ncp_trigger_message: invalid server!\n"); - return; - } - - DPRINTK("ncp_trigger_message: on %s\n", - server->m.mount_point); - -#ifdef CONFIG_KERNELD - strcpy(command, NCP_MSG_COMMAND); - strcat(command, " "); - strcat(command, server->m.mount_point); - DPRINTK("ksystem: %s\n", command); - ksystem(command, KERNELD_NOWAIT); -#endif -} - -static void -ncp_statfs(struct super_block *sb, struct statfs *buf, int bufsiz) +static void ncp_statfs(struct super_block *sb, struct statfs *buf, int bufsiz) { struct statfs tmp; /* We cannot say how much disk space is left on a mounted - NetWare Server, because free space is distributed over - volumes, and the current user might have disk quotas. So - free space is not that simple to determine. Our decision - here is to err conservatively. */ + NetWare Server, because free space is distributed over + volumes, and the current user might have disk quotas. So + free space is not that simple to determine. Our decision + here is to err conservatively. */ tmp.f_type = NCP_SUPER_MAGIC; tmp.f_bsize = 512; @@ -426,18 +307,15 @@ copy_to_user(buf, &tmp, bufsiz); } -static int -ncp_notify_change(struct inode *inode, struct iattr *attr) +static int ncp_notify_change(struct inode *inode, struct iattr *attr) { int result = 0; int info_mask; struct nw_modify_dos_info info; - if (!ncp_conn_valid(NCP_SERVER(inode))) - { + if (!ncp_conn_valid(NCP_SERVER(inode))) { return -EIO; } - if ((result = inode_change_ok(inode, attr)) < 0) return result; @@ -447,7 +325,7 @@ if (((attr->ia_valid & ATTR_GID) && (attr->ia_uid != NCP_SERVER(inode)->m.gid))) - return -EPERM; + return -EPERM; if (((attr->ia_valid & ATTR_MODE) && (attr->ia_mode & @@ -457,67 +335,54 @@ info_mask = 0; memset(&info, 0, sizeof(info)); - if ((attr->ia_valid & ATTR_CTIME) != 0) - { - info_mask |= (DM_CREATE_TIME|DM_CREATE_DATE); + if ((attr->ia_valid & ATTR_CTIME) != 0) { + info_mask |= (DM_CREATE_TIME | DM_CREATE_DATE); ncp_date_unix2dos(attr->ia_ctime, - &(info.creationTime), &(info.creationDate)); + &(info.creationTime), &(info.creationDate)); info.creationTime = le16_to_cpu(info.creationTime); info.creationDate = le16_to_cpu(info.creationDate); } - - if ((attr->ia_valid & ATTR_MTIME) != 0) - { - info_mask |= (DM_MODIFY_TIME|DM_MODIFY_DATE); + if ((attr->ia_valid & ATTR_MTIME) != 0) { + info_mask |= (DM_MODIFY_TIME | DM_MODIFY_DATE); ncp_date_unix2dos(attr->ia_mtime, &(info.modifyTime), &(info.modifyDate)); info.modifyTime = le16_to_cpu(info.modifyTime); info.modifyDate = le16_to_cpu(info.modifyDate); } - - if ((attr->ia_valid & ATTR_ATIME) != 0) - { + if ((attr->ia_valid & ATTR_ATIME) != 0) { __u16 dummy; info_mask |= (DM_LAST_ACCESS_DATE); ncp_date_unix2dos(attr->ia_ctime, &(dummy), &(info.lastAccessDate)); info.lastAccessDate = le16_to_cpu(info.lastAccessDate); } - - if (info_mask != 0) - { + if (info_mask != 0) { if ((result = ncp_modify_file_or_subdir_dos_info(NCP_SERVER(inode), - NCP_ISTRUCT(inode), + NCP_ISTRUCT(inode), info_mask, - &info)) != 0) - { + &info)) != 0) { result = -EACCES; - if (info_mask == (DM_CREATE_TIME|DM_CREATE_DATE)) - { + if (info_mask == (DM_CREATE_TIME | DM_CREATE_DATE)) { /* NetWare seems not to allow this. I - do not know why. So, just tell the - user everything went fine. This is - a terrible hack, but I do not know - how to do this correctly. */ + do not know why. So, just tell the + user everything went fine. This is + a terrible hack, but I do not know + how to do this correctly. */ result = 0; } } } - - if ((attr->ia_valid & ATTR_SIZE) != 0) - { + if ((attr->ia_valid & ATTR_SIZE) != 0) { int written; DPRINTK("ncpfs: trying to change size of %s to %ld\n", NCP_ISTRUCT(inode)->entryName, attr->ia_size); - if ((result = ncp_make_open(inode, O_RDWR)) < 0) - { + if ((result = ncp_make_open(inode, O_RDWR)) < 0) { return -EACCES; } - ncp_write(NCP_SERVER(inode), NCP_FINFO(inode)->file_handle, attr->ia_size, 0, "", &written); @@ -529,8 +394,7 @@ result = 0; } - - ncp_invalid_dir_cache(NCP_INOP(inode)->dir->inode); + ncp_invalid_dir_cache(NCP_INOP(inode)->dir->inode); return result; } @@ -540,40 +404,40 @@ int ncp_current_malloced; #endif -static struct file_system_type ncp_fs_type = { - ncp_read_super, "ncpfs", 0, NULL - }; +static struct file_system_type ncp_fs_type = +{ + ncp_read_super, "ncpfs", 0, NULL +}; int init_ncp_fs(void) { - return register_filesystem(&ncp_fs_type); + return register_filesystem(&ncp_fs_type); } #ifdef MODULE EXPORT_NO_SYMBOLS; -int init_module( void) +int init_module(void) { - DPRINTK("ncpfs: init_module called\n"); + DPRINTK("ncpfs: init_module called\n"); #ifdef DEBUG_NCP_MALLOC - ncp_malloced = 0; - ncp_current_malloced = 0; + ncp_malloced = 0; + ncp_current_malloced = 0; #endif - ncp_init_dir_cache(); + ncp_init_dir_cache(); return init_ncp_fs(); } -void -cleanup_module(void) +void cleanup_module(void) { - DPRINTK("ncpfs: cleanup_module called\n"); - ncp_free_dir_cache(); - unregister_filesystem(&ncp_fs_type); + DPRINTK("ncpfs: cleanup_module called\n"); + ncp_free_dir_cache(); + unregister_filesystem(&ncp_fs_type); #ifdef DEBUG_NCP_MALLOC - printk("ncp_malloced: %d\n", ncp_malloced); - printk("ncp_current_malloced: %d\n", ncp_current_malloced); + printk("ncp_malloced: %d\n", ncp_malloced); + printk("ncp_current_malloced: %d\n", ncp_current_malloced); #endif } diff -u --recursive --new-file v2.1.30/linux/fs/ncpfs/ioctl.c linux/fs/ncpfs/ioctl.c --- v2.1.30/linux/fs/ncpfs/ioctl.c Mon Oct 28 04:29:26 1996 +++ linux/fs/ncpfs/ioctl.c Fri Mar 28 10:42:22 1997 @@ -14,70 +14,41 @@ #include #include -int -ncp_ioctl (struct inode * inode, struct file * filp, - unsigned int cmd, unsigned long arg) +int ncp_ioctl(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg) { int result; struct ncp_ioctl_request request; 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) { + switch (cmd) { case NCP_IOC_NCPREQUEST: - if ( (permission(inode, MAY_WRITE) != 0) - && (current->uid != server->m.mounted_uid)) - { + if ((permission(inode, MAY_WRITE) != 0) + && (current->uid != server->m.mounted_uid)) { return -EACCES; } - - if ((result = verify_area(VERIFY_READ, (char *)arg, - sizeof(request))) != 0) - { + if ((result = verify_area(VERIFY_READ, (char *) arg, + sizeof(request))) != 0) { return result; } + copy_from_user(&request, (struct ncp_ioctl_request *) arg, + sizeof(request)); - copy_from_user(&request, (struct ncp_ioctl_request *)arg, - sizeof(request)); - - if ( (request.function > 255) + if ((request.function > 255) || (request.size > - NCP_PACKET_SIZE - sizeof(struct ncp_request_header))) - { + NCP_PACKET_SIZE - sizeof(struct ncp_request_header))) { return -EINVAL; } - - if ((result = verify_area(VERIFY_WRITE, (char *)request.data, - NCP_PACKET_SIZE)) != 0) - { + if ((result = verify_area(VERIFY_WRITE, (char *) request.data, + NCP_PACKET_SIZE)) != 0) { return result; } - ncp_lock_server(server); /* FIXME: We hack around in the server's structures - here to be able to use ncp_request */ + here to be able to use ncp_request */ server->has_subfunction = 0; server->current_size = request.size; @@ -95,66 +66,55 @@ case NCP_IOC_CONN_LOGGED_IN: - if ( (permission(inode, MAY_WRITE) != 0) - && (current->uid != server->m.mounted_uid)) - { + if ((permission(inode, MAY_WRITE) != 0) + && (current->uid != server->m.mounted_uid)) { return -EACCES; } - return ncp_conn_logged_in(server); - + case NCP_IOC_GET_FS_INFO: - if ( (permission(inode, MAY_WRITE) != 0) - && (current->uid != server->m.mounted_uid)) - { + if ((permission(inode, MAY_WRITE) != 0) + && (current->uid != server->m.mounted_uid)) { return -EACCES; } - - if ((result = verify_area(VERIFY_WRITE, (char *)arg, - sizeof(info))) != 0) - { + if ((result = verify_area(VERIFY_WRITE, (char *) arg, + sizeof(info))) != 0) { return result; } + copy_from_user(&info, (struct ncp_fs_info *) arg, + sizeof(info)); - copy_from_user(&info, (struct ncp_fs_info *)arg, - sizeof(info)); - - if (info.version != NCP_GET_FS_INFO_VERSION) - { + if (info.version != NCP_GET_FS_INFO_VERSION) { DPRINTK("info.version invalid: %d\n", info.version); 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; + /* TODO: 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; + info.directory_id = NCP_ISTRUCT(inode)->DosDirNum; - copy_to_user((struct ncp_fs_info *)arg, &info, sizeof(info)); - return 0; + copy_to_user((struct ncp_fs_info *) arg, &info, sizeof(info)); + return 0; - case NCP_IOC_GETMOUNTUID: + case NCP_IOC_GETMOUNTUID: - if ( (permission(inode, MAY_READ) != 0) - && (current->uid != server->m.mounted_uid)) - { + if ((permission(inode, MAY_READ) != 0) + && (current->uid != server->m.mounted_uid)) { return -EACCES; } - - if ((result = verify_area(VERIFY_WRITE, (uid_t*) arg, - sizeof(uid_t))) != 0) - { - return result; - } - put_user(server->m.mounted_uid, (uid_t *) arg); - return 0; + if ((result = verify_area(VERIFY_WRITE, (uid_t *) arg, + sizeof(uid_t))) != 0) { + return result; + } + put_user(server->m.mounted_uid, (uid_t *) arg); + return 0; default: return -EINVAL; } - + return -EINVAL; } diff -u --recursive --new-file v2.1.30/linux/fs/ncpfs/mmap.c linux/fs/ncpfs/mmap.c --- v2.1.30/linux/fs/ncpfs/mmap.c Mon Oct 28 04:29:26 1996 +++ linux/fs/ncpfs/mmap.c Fri Mar 28 10:42:22 1997 @@ -23,17 +23,16 @@ static inline int min(int a, int b) { - return avm_inode; + struct inode *inode = area->vm_inode; unsigned long page; unsigned int clear; unsigned long tmp; @@ -48,37 +47,28 @@ pos = address - area->vm_start + area->vm_offset; clear = 0; - if (address + PAGE_SIZE > area->vm_end) - { + if (address + PAGE_SIZE > area->vm_end) { clear = address + PAGE_SIZE - area->vm_end; } - - /* what we can read in one go */ + /* what we can read in one go */ bufsize = NCP_SERVER(inode)->buffer_size; fs = get_fs(); set_fs(get_ds()); - if (ncp_make_open(inode, O_RDONLY) < 0) - { - clear = PAGE_SIZE; - } - else - { + if (ncp_make_open(inode, O_RDONLY) < 0) { + clear = PAGE_SIZE; + } else { int already_read = 0; int count = PAGE_SIZE - clear; int to_read; - while (already_read < count) - { + while (already_read < count) { int read_this_time; - if ((pos % bufsize) != 0) - { + if ((pos % bufsize) != 0) { to_read = bufsize - (pos % bufsize); - } - else - { + } else { to_read = bufsize; } @@ -87,33 +77,31 @@ if (ncp_read(NCP_SERVER(inode), NCP_FINFO(inode)->file_handle, pos, to_read, - (char *)(page + already_read), - &read_this_time) != 0) - { - read_this_time = 0; + (char *) (page + already_read), + &read_this_time) != 0) { + read_this_time = 0; } - pos += read_this_time; already_read += read_this_time; - if (read_this_time < to_read) - { + if (read_this_time < to_read) { break; } } - } + } set_fs(fs); tmp = page + PAGE_SIZE; while (clear--) { - *(char *)--tmp = 0; + *(char *) --tmp = 0; } return page; } -struct vm_operations_struct ncp_file_mmap = { +struct vm_operations_struct ncp_file_mmap = +{ NULL, /* open */ NULL, /* close */ NULL, /* unmap */ @@ -128,18 +116,15 @@ /* This is used for a general mmap of a ncp file */ -int -ncp_mmap(struct inode * inode, struct file * file, struct vm_area_struct * vma) +int ncp_mmap(struct inode *inode, struct file *file, struct vm_area_struct *vma) { - DPRINTK("ncp_mmap: called\n"); + DPRINTK("ncp_mmap: called\n"); - if (!ncp_conn_valid(NCP_SERVER(inode))) - { + if (!ncp_conn_valid(NCP_SERVER(inode))) { return -EIO; } - - /* only PAGE_COW or read-only supported now */ - if (vma->vm_flags & VM_SHARED) + /* only PAGE_COW or read-only supported now */ + if (vma->vm_flags & VM_SHARED) return -EINVAL; if (!inode->i_sb || !S_ISREG(inode->i_mode)) return -EACCES; @@ -147,7 +132,6 @@ inode->i_atime = CURRENT_TIME; inode->i_dirt = 1; } - vma->vm_inode = inode; inode->i_count++; vma->vm_ops = &ncp_file_mmap; diff -u --recursive --new-file v2.1.30/linux/fs/ncpfs/ncplib_kernel.c linux/fs/ncpfs/ncplib_kernel.c --- v2.1.30/linux/fs/ncpfs/ncplib_kernel.c Mon Dec 30 02:03:22 1996 +++ linux/fs/ncpfs/ncplib_kernel.c Fri Mar 28 10:42:22 1997 @@ -8,53 +8,43 @@ #include "ncplib_kernel.h" -typedef __u8 byte; -typedef __u16 word; -typedef __u32 dword; - static inline int min(int a, int b) { - return alock == 0) - { + if (server->lock == 0) { DPRINTK("ncpfs: server not locked!\n"); } } -static void -ncp_add_byte(struct ncp_server *server, byte x) +static void ncp_add_byte(struct ncp_server *server, __u8 x) { assert_server_locked(server); - *(byte *)(&(server->packet[server->current_size])) = x; + *(__u8 *) (&(server->packet[server->current_size])) = x; server->current_size += 1; return; } -static void -ncp_add_word(struct ncp_server *server, word x) +static void ncp_add_word(struct ncp_server *server, __u16 x) { assert_server_locked(server); - put_unaligned(x, (word *)(&(server->packet[server->current_size]))); + put_unaligned(x, (__u16 *) (&(server->packet[server->current_size]))); server->current_size += 2; return; } -static void -ncp_add_dword(struct ncp_server *server, dword x) +static void ncp_add_dword(struct ncp_server *server, __u32 x) { assert_server_locked(server); - put_unaligned(x, (dword *)(&(server->packet[server->current_size]))); + put_unaligned(x, (__u32 *) (&(server->packet[server->current_size]))); server->current_size += 4; return; } -static void -ncp_add_mem(struct ncp_server *server, const void *source, int size) +static void ncp_add_mem(struct ncp_server *server, const void *source, int size) { assert_server_locked(server); memcpy(&(server->packet[server->current_size]), source, size); @@ -62,8 +52,7 @@ return; } -static void -ncp_add_mem_fromfs(struct ncp_server *server, const char *source, int size) +static void ncp_add_mem_fromfs(struct ncp_server *server, const char *source, int size) { assert_server_locked(server); copy_from_user(&(server->packet[server->current_size]), source, size); @@ -71,13 +60,11 @@ return; } -static void -ncp_add_pstring(struct ncp_server *server, const char *s) +static void ncp_add_pstring(struct ncp_server *server, const char *s) { int len = strlen(s); assert_server_locked(server); - if (len > 255) - { + if (len > 255) { DPRINTK("ncpfs: string too long: %s\n", s); len = 255; } @@ -86,8 +73,7 @@ return; } -static void -ncp_init_request(struct ncp_server *server) +static void ncp_init_request(struct ncp_server *server) { ncp_lock_server(server); @@ -95,11 +81,10 @@ server->has_subfunction = 0; } -static void -ncp_init_request_s(struct ncp_server *server, int subfunction) +static void ncp_init_request_s(struct ncp_server *server, int subfunction) { ncp_init_request(server); - ncp_add_word(server, 0); /* preliminary size */ + ncp_add_word(server, 0); /* preliminary size */ ncp_add_byte(server, subfunction); @@ -107,53 +92,49 @@ } static char * -ncp_reply_data(struct ncp_server *server, int offset) + ncp_reply_data(struct ncp_server *server, int offset) { return &(server->packet[sizeof(struct ncp_reply_header) + offset]); } -static byte -ncp_reply_byte(struct ncp_server *server, int offset) +static __u8 + ncp_reply_byte(struct ncp_server *server, int offset) { - return *(byte *)(ncp_reply_data(server, offset)); + return get_unaligned((__u8 *) ncp_reply_data(server, offset)); } -static word -ncp_reply_word(struct ncp_server *server, int offset) +static __u16 + ncp_reply_word(struct ncp_server *server, int offset) { - return *(word *)(ncp_reply_data(server, offset)); + return get_unaligned((__u16 *) ncp_reply_data(server, offset)); } -static dword -ncp_reply_dword(struct ncp_server *server, int offset) +static __u32 + ncp_reply_dword(struct ncp_server *server, int offset) { - return *(dword *)(ncp_reply_data(server, offset)); + return get_unaligned((__u32 *) ncp_reply_data(server, offset)); } -int -ncp_negotiate_buffersize(struct ncp_server *server, - int size, int *target) +int ncp_negotiate_buffersize(struct ncp_server *server, + int size, int *target) { int result; ncp_init_request(server); ncp_add_word(server, htons(size)); - - if ((result = ncp_request(server, 33)) != 0) - { + + if ((result = ncp_request(server, 33)) != 0) { ncp_unlock_server(server); return result; } - - *target =min(ntohs(ncp_reply_word(server, 0)), size); + *target = min(ntohs(ncp_reply_word(server, 0)), size); ncp_unlock_server(server); return 0; } -int -ncp_get_volume_info_with_number(struct ncp_server *server, int n, - struct ncp_volume_info *target) +int ncp_get_volume_info_with_number(struct ncp_server *server, int n, + struct ncp_volume_info *target) { int result; int len; @@ -161,14 +142,12 @@ ncp_init_request_s(server, 44); ncp_add_byte(server, n); - if ((result = ncp_request(server, 22)) != 0) - { + if ((result = ncp_request(server, 22)) != 0) { ncp_unlock_server(server); return result; } - target->total_blocks = ncp_reply_dword(server, 0); - target->free_blocks = ncp_reply_dword(server, 4); + target->free_blocks = ncp_reply_dword(server, 4); target->purgeable_blocks = ncp_reply_dword(server, 8); target->not_yet_purgeable_blocks = ncp_reply_dword(server, 12); target->total_dir_entries = ncp_reply_dword(server, 16); @@ -178,20 +157,17 @@ memset(&(target->volume_name), 0, sizeof(target->volume_name)); len = ncp_reply_byte(server, 29); - if (len > NCP_VOLNAME_LEN) - { + if (len > NCP_VOLNAME_LEN) { DPRINTK("ncpfs: volume name too long: %d\n", len); ncp_unlock_server(server); return -EIO; } - memcpy(&(target->volume_name), ncp_reply_data(server, 30), len); ncp_unlock_server(server); return 0; } -int -ncp_close_file(struct ncp_server *server, const char *file_id) +int ncp_close_file(struct ncp_server *server, const char *file_id) { int result; @@ -204,35 +180,27 @@ return result; } -static void -ncp_add_handle_path(struct ncp_server *server, - __u8 vol_num, - __u32 dir_base, int have_dir_base, - char *path) +static void ncp_add_handle_path(struct ncp_server *server, + __u8 vol_num, + __u32 dir_base, int have_dir_base, + char *path) { ncp_add_byte(server, vol_num); ncp_add_dword(server, dir_base); - if (have_dir_base != 0) - { - ncp_add_byte(server, 1); /* dir_base */ - } - else - { - ncp_add_byte(server, 0xff); /* no handle */ - } - if (path != NULL) - { - ncp_add_byte(server, 1); /* 1 component */ - ncp_add_pstring(server, path); + if (have_dir_base != 0) { + ncp_add_byte(server, 1); /* dir_base */ + } else { + ncp_add_byte(server, 0xff); /* no handle */ } - else - { + if (path != NULL) { + ncp_add_byte(server, 1); /* 1 component */ + ncp_add_pstring(server, path); + } else { ncp_add_byte(server, 0); } } -static void -ncp_extract_file_info(void *structure, struct nw_info_struct *target) +static void ncp_extract_file_info(void *structure, struct nw_info_struct *target) { __u8 *name_len; const int info_struct_size = sizeof(struct nw_info_struct) - 257; @@ -240,70 +208,60 @@ memcpy(target, structure, info_struct_size); name_len = structure + info_struct_size; target->nameLen = *name_len; - strncpy(target->entryName, name_len+1, *name_len); + strncpy(target->entryName, name_len + 1, *name_len); target->entryName[*name_len] = '\0'; return; } -int -ncp_obtain_info(struct ncp_server *server, - __u8 vol_num, __u32 dir_base, - char *path, /* At most 1 component */ - struct nw_info_struct *target) +int ncp_obtain_info(struct ncp_server *server, + __u8 vol_num, __u32 dir_base, + char *path, /* At most 1 component */ + struct nw_info_struct *target) { int result; - if (target == NULL) - { + if (target == NULL) { return -EINVAL; } - ncp_init_request(server); - ncp_add_byte(server, 6); /* subfunction */ + ncp_add_byte(server, 6); /* subfunction */ ncp_add_byte(server, server->name_space[vol_num]); ncp_add_byte(server, server->name_space[vol_num]); - ncp_add_word(server, htons(0xff00)); /* get all */ + ncp_add_word(server, htons(0xff00)); /* get all */ ncp_add_dword(server, RIM_ALL); ncp_add_handle_path(server, vol_num, dir_base, 1, path); - if ((result = ncp_request(server, 87)) != 0) - { + if ((result = ncp_request(server, 87)) != 0) { ncp_unlock_server(server); return result; } - ncp_extract_file_info(ncp_reply_data(server, 0), target); ncp_unlock_server(server); return 0; } -static inline int -ncp_has_os2_namespace(struct ncp_server *server, __u8 volume) +static inline int ncp_has_os2_namespace(struct ncp_server *server, __u8 volume) { int result; __u8 *namespace; __u16 no_namespaces; ncp_init_request(server); - ncp_add_byte(server, 24); /* Subfunction: Get Name Spaces Loaded */ + ncp_add_byte(server, 24); /* Subfunction: Get Name Spaces Loaded */ ncp_add_word(server, 0); ncp_add_byte(server, volume); - if ((result = ncp_request(server, 87)) != 0) - { + if ((result = ncp_request(server, 87)) != 0) { ncp_unlock_server(server); return 0; } - no_namespaces = ncp_reply_word(server, 0); namespace = ncp_reply_data(server, 2); - while (no_namespaces > 0) - { - DPRINTK("get_namespaces: found %d on %d\n", *namespace,volume); + while (no_namespaces > 0) { + DPRINTK("get_namespaces: found %d on %d\n", *namespace, volume); - if (*namespace == 4) - { + if (*namespace == 4) { DPRINTK("get_namespaces: found OS2\n"); ncp_unlock_server(server); return 1; @@ -315,10 +273,9 @@ return 0; } -int -ncp_lookup_volume(struct ncp_server *server, - char *volname, - struct nw_info_struct *target) +int ncp_lookup_volume(struct ncp_server *server, + char *volname, + struct nw_info_struct *target) { int result; int volnum; @@ -326,30 +283,28 @@ DPRINTK("ncp_lookup_volume: looking up vol %s\n", volname); ncp_init_request(server); - ncp_add_byte(server, 22); /* Subfunction: Generate dir handle */ - ncp_add_byte(server, 0); /* DOS namespace */ - ncp_add_byte(server, 0); /* reserved */ - ncp_add_byte(server, 0); /* reserved */ - ncp_add_byte(server, 0); /* reserved */ - - ncp_add_byte(server, 0); /* faked volume number */ - ncp_add_dword(server, 0); /* faked dir_base */ - ncp_add_byte(server, 0xff); /* Don't have a dir_base */ - ncp_add_byte(server, 1); /* 1 path component */ + ncp_add_byte(server, 22); /* Subfunction: Generate dir handle */ + ncp_add_byte(server, 0); /* DOS namespace */ + ncp_add_byte(server, 0); /* reserved */ + ncp_add_byte(server, 0); /* reserved */ + ncp_add_byte(server, 0); /* reserved */ + + ncp_add_byte(server, 0); /* faked volume number */ + ncp_add_dword(server, 0); /* faked dir_base */ + ncp_add_byte(server, 0xff); /* Don't have a dir_base */ + ncp_add_byte(server, 1); /* 1 path component */ ncp_add_pstring(server, volname); - if ((result = ncp_request(server, 87)) != 0) - { + if ((result = ncp_request(server, 87)) != 0) { ncp_unlock_server(server); return result; } - memset(target, 0, sizeof(*target)); target->DosDirNum = target->dirEntNum = ncp_reply_dword(server, 4); target->volNumber = volnum = ncp_reply_byte(server, 8); ncp_unlock_server(server); - server->name_space[volnum] = ncp_has_os2_namespace(server,volnum)?4:0; + server->name_space[volnum] = ncp_has_os2_namespace(server, volnum) ? 4 : 0; DPRINTK("lookup_vol: namespace[%d] = %d\n", volnum, server->name_space[volnum]); @@ -360,19 +315,18 @@ return 0; } -int -ncp_modify_file_or_subdir_dos_info(struct ncp_server *server, - struct nw_info_struct *file, - __u32 info_mask, - struct nw_modify_dos_info *info) +int ncp_modify_file_or_subdir_dos_info(struct ncp_server *server, + struct nw_info_struct *file, + __u32 info_mask, + struct nw_modify_dos_info *info) { int result; ncp_init_request(server); - ncp_add_byte(server, 7); /* subfunction */ + ncp_add_byte(server, 7); /* subfunction */ ncp_add_byte(server, server->name_space[file->volNumber]); - ncp_add_byte(server, 0); /* reserved */ - ncp_add_word(server, htons(0x0680)); /* search attribs: all */ + ncp_add_byte(server, 0); /* reserved */ + ncp_add_word(server, htons(0x0680)); /* search attribs: all */ ncp_add_dword(server, info_mask); ncp_add_mem(server, info, sizeof(*info)); @@ -384,55 +338,50 @@ return result; } -int -ncp_del_file_or_subdir(struct ncp_server *server, - struct nw_info_struct *dir, char *name) +int ncp_del_file_or_subdir(struct ncp_server *server, + struct nw_info_struct *dir, char *name) { int result; ncp_init_request(server); - ncp_add_byte(server, 8); /* subfunction */ + ncp_add_byte(server, 8); /* subfunction */ ncp_add_byte(server, server->name_space[dir->volNumber]); - ncp_add_byte(server, 0); /* reserved */ - ncp_add_word(server, ntohs(0x0680)); /* search attribs: all */ + ncp_add_byte(server, 0); /* reserved */ + ncp_add_word(server, ntohs(0x0680)); /* search attribs: all */ ncp_add_handle_path(server, dir->volNumber, dir->dirEntNum, 1, name); - + result = ncp_request(server, 87); ncp_unlock_server(server); return result; } -static inline void -ConvertToNWfromDWORD ( __u32 sfd , __u8 ret[6] ) +static inline void ConvertToNWfromDWORD(__u32 sfd, __u8 ret[6]) { - __u16 *dest = (__u16 *) ret; - memcpy (ret + 2, &sfd, 4); - dest[0] = cpu_to_le16((le16_to_cpu(dest[1]) + le16_to_cpu(1))); - return; + __u16 *dest = (__u16 *) ret; + memcpy(ret + 2, &sfd, 4); + dest[0] = cpu_to_le16((le16_to_cpu(dest[1]) + le16_to_cpu(1))); + return; } /* If both dir and name are NULL, then in target there's already a looked-up entry that wants to be opened. */ -int -ncp_open_create_file_or_subdir(struct ncp_server *server, - struct nw_info_struct *dir, char *name, - int open_create_mode, - __u32 create_attributes, - int desired_acc_rights, - struct nw_file_info *target) +int ncp_open_create_file_or_subdir(struct ncp_server *server, + struct nw_info_struct *dir, char *name, + int open_create_mode, + __u32 create_attributes, + int desired_acc_rights, + struct nw_file_info *target) { int result; __u16 search_attribs = ntohs(0x0600); __u8 volume = (dir != NULL) ? dir->volNumber : target->i.volNumber; - if ((create_attributes & aDIR) != 0) - { - search_attribs |= ntohs(0x0080); + if ((create_attributes & aDIR) != 0) { + search_attribs |= ntohs(0x0080); } - ncp_init_request(server); - ncp_add_byte(server, 1); /* subfunction */ + ncp_add_byte(server, 1); /* subfunction */ ncp_add_byte(server, server->name_space[volume]); ncp_add_byte(server, open_create_mode); ncp_add_word(server, search_attribs); @@ -442,89 +391,76 @@ for directories */ ncp_add_word(server, desired_acc_rights); - if (dir != NULL) - { + if (dir != NULL) { ncp_add_handle_path(server, volume, dir->dirEntNum, 1, name); - } - else - { + } else { ncp_add_handle_path(server, volume, target->i.dirEntNum, 1, NULL); - } + } - if ((result = ncp_request(server, 87)) != 0) - { + if ((result = ncp_request(server, 87)) != 0) { ncp_unlock_server(server); return result; } - target->opened = 1; target->server_file_handle = ncp_reply_dword(server, 0); target->open_create_action = ncp_reply_byte(server, 4); - if (dir != NULL) - { + if (dir != NULL) { /* in target there's a new finfo to fill */ ncp_extract_file_info(ncp_reply_data(server, 5), &(target->i)); } - ConvertToNWfromDWORD(target->server_file_handle, target->file_handle); ncp_unlock_server(server); return 0; } - -int -ncp_initialize_search(struct ncp_server *server, - struct nw_info_struct *dir, - struct nw_search_sequence *target) + +int ncp_initialize_search(struct ncp_server *server, + struct nw_info_struct *dir, + struct nw_search_sequence *target) { int result; ncp_init_request(server); - ncp_add_byte(server, 2); /* subfunction */ + ncp_add_byte(server, 2); /* subfunction */ ncp_add_byte(server, server->name_space[dir->volNumber]); - ncp_add_byte(server, 0); /* reserved */ + ncp_add_byte(server, 0); /* reserved */ ncp_add_handle_path(server, dir->volNumber, dir->dirEntNum, 1, NULL); - - if ((result = ncp_request(server, 87)) != 0) - { + + if ((result = ncp_request(server, 87)) != 0) { ncp_unlock_server(server); return result; } - memcpy(target, ncp_reply_data(server, 0), sizeof(*target)); ncp_unlock_server(server); return 0; } - + /* Search for everything */ -int -ncp_search_for_file_or_subdir(struct ncp_server *server, - struct nw_search_sequence *seq, - struct nw_info_struct *target) +int ncp_search_for_file_or_subdir(struct ncp_server *server, + struct nw_search_sequence *seq, + struct nw_info_struct *target) { int result; ncp_init_request(server); - ncp_add_byte(server, 3); /* subfunction */ + ncp_add_byte(server, 3); /* subfunction */ ncp_add_byte(server, server->name_space[seq->volNumber]); - ncp_add_byte(server, 0); /* data stream (???) */ - ncp_add_word(server, 0xffff); /* Search attribs */ - ncp_add_dword(server, RIM_ALL); /* return info mask */ + ncp_add_byte(server, 0); /* data stream (???) */ + ncp_add_word(server, 0xffff); /* Search attribs */ + ncp_add_dword(server, RIM_ALL); /* return info mask */ ncp_add_mem(server, seq, 9); - ncp_add_byte(server, 2); /* 2 byte pattern */ - ncp_add_byte(server, 0xff); /* following is a wildcard */ + ncp_add_byte(server, 2); /* 2 byte pattern */ + ncp_add_byte(server, 0xff); /* following is a wildcard */ ncp_add_byte(server, '*'); - - if ((result = ncp_request(server, 87)) != 0) - { + + if ((result = ncp_request(server, 87)) != 0) { ncp_unlock_server(server); return result; } - memcpy(seq, ncp_reply_data(server, 0), sizeof(*seq)); ncp_extract_file_info(ncp_reply_data(server, 10), target); @@ -532,34 +468,33 @@ return 0; } -int -ncp_ren_or_mov_file_or_subdir(struct ncp_server *server, - struct nw_info_struct *old_dir, char *old_name, - struct nw_info_struct *new_dir, char *new_name) +int ncp_ren_or_mov_file_or_subdir(struct ncp_server *server, + struct nw_info_struct *old_dir, char *old_name, + struct nw_info_struct *new_dir, char *new_name) { int result; - if ( (old_dir == NULL) || (old_name == NULL) + if ((old_dir == NULL) || (old_name == NULL) || (new_dir == NULL) || (new_name == NULL)) return -EINVAL; - + ncp_init_request(server); - ncp_add_byte(server, 4); /* subfunction */ + ncp_add_byte(server, 4); /* subfunction */ ncp_add_byte(server, server->name_space[old_dir->volNumber]); - ncp_add_byte(server, 1); /* rename flag */ - ncp_add_word(server, ntohs (0x0680)); /* search attributes */ + ncp_add_byte(server, 1); /* rename flag */ + ncp_add_word(server, ntohs(0x0680)); /* search attributes */ /* source Handle Path */ ncp_add_byte(server, old_dir->volNumber); ncp_add_dword(server, old_dir->dirEntNum); ncp_add_byte(server, 1); - ncp_add_byte(server, 1); /* 1 source component */ + ncp_add_byte(server, 1); /* 1 source component */ /* dest Handle Path */ ncp_add_byte(server, new_dir->volNumber); ncp_add_dword(server, new_dir->dirEntNum); ncp_add_byte(server, 1); - ncp_add_byte(server, 1); /* 1 destination component */ + ncp_add_byte(server, 1); /* 1 destination component */ /* source path string */ ncp_add_pstring(server, old_name); @@ -570,13 +505,12 @@ ncp_unlock_server(server); return result; } - + /* We have to transfer to/from user space */ -int -ncp_read(struct ncp_server *server, const char *file_id, - __u32 offset, __u16 to_read, - char *target, int *bytes_read) +int ncp_read(struct ncp_server *server, const char *file_id, + __u32 offset, __u16 to_read, + char *target, int *bytes_read) { int result; @@ -586,24 +520,21 @@ ncp_add_dword(server, htonl(offset)); ncp_add_word(server, htons(to_read)); - if ((result = ncp_request(server, 72)) != 0) - { + if ((result = ncp_request(server, 72)) != 0) { ncp_unlock_server(server); return result; } - *bytes_read = ntohs(ncp_reply_word(server, 0)); - copy_to_user(target, ncp_reply_data(server, 2+(offset&1)), *bytes_read); + copy_to_user(target, ncp_reply_data(server, 2 + (offset & 1)), *bytes_read); ncp_unlock_server(server); return 0; } -int -ncp_write(struct ncp_server *server, const char *file_id, - __u32 offset, __u16 to_write, - const char *source, int *bytes_written) +int ncp_write(struct ncp_server *server, const char *file_id, + __u32 offset, __u16 to_write, + const char *source, int *bytes_written) { int result; @@ -614,15 +545,12 @@ ncp_add_word(server, htons(to_write)); ncp_add_mem_fromfs(server, source, to_write); - if ((result = ncp_request(server, 73)) != 0) - { + if ((result = ncp_request(server, 73)) != 0) { ncp_unlock_server(server); return result; } - *bytes_written = to_write; ncp_unlock_server(server); return 0; } - diff -u --recursive --new-file v2.1.30/linux/fs/ncpfs/ncplib_kernel.h linux/fs/ncpfs/ncplib_kernel.h --- v2.1.30/linux/fs/ncpfs/ncplib_kernel.h Mon Dec 30 02:03:22 1996 +++ linux/fs/ncpfs/ncplib_kernel.h Fri Mar 28 10:42:22 1997 @@ -29,89 +29,11 @@ ncp_negotiate_buffersize(struct ncp_server *server, int size, int *target); int -ncp_get_encryption_key(struct ncp_server *server, - char *target); -int -ncp_get_bindery_object_id(struct ncp_server *server, - int object_type, char *object_name, - struct ncp_bindery_object *target); -int -ncp_login_encrypted(struct ncp_server *server, - struct ncp_bindery_object *object, - unsigned char *key, - unsigned char *passwd); -int -ncp_login_user(struct ncp_server *server, - unsigned char *username, - unsigned char *password); -int ncp_get_volume_info_with_number(struct ncp_server *server, int n, struct ncp_volume_info *target); int -ncp_get_volume_number(struct ncp_server *server, const char *name, - int *target); - -int -ncp_file_search_init(struct ncp_server *server, - int dir_handle, const char *path, - struct ncp_filesearch_info *target); - -int -ncp_file_search_continue(struct ncp_server *server, - struct ncp_filesearch_info *fsinfo, - int attributes, const char *path, - struct ncp_file_info *target); - -int -ncp_get_finfo(struct ncp_server *server, - int dir_handle, const char *path, const char *name, - struct ncp_file_info *target); - -int -ncp_open_file(struct ncp_server *server, - int dir_handle, const char *path, - int attr, int access, - struct ncp_file_info *target); -int ncp_close_file(struct ncp_server *server, const char *file_id); - -int -ncp_create_newfile(struct ncp_server *server, - int dir_handle, const char *path, - int attr, - struct ncp_file_info *target); - -int -ncp_create_file(struct ncp_server *server, - int dir_handle, const char *path, - int attr, - struct ncp_file_info *target); - -int -ncp_erase_file(struct ncp_server *server, - int dir_handle, const char *path, - int attr); - -int -ncp_rename_file(struct ncp_server *server, - int old_handle, const char *old_path, - int attr, - int new_handle, const char *new_path); - -int -ncp_create_directory(struct ncp_server *server, - int dir_handle, const char *path, - int inherit_mask); - -int -ncp_delete_directory(struct ncp_server *server, - int dir_handle, const char *path); - -int -ncp_rename_directory(struct ncp_server *server, - int dir_handle, - const char *old_path, const char *new_path); int ncp_read(struct ncp_server *server, const char *file_id, diff -u --recursive --new-file v2.1.30/linux/fs/ncpfs/sock.c linux/fs/ncpfs/sock.c --- v2.1.30/linux/fs/ncpfs/sock.c Sun Jan 26 02:07:44 1997 +++ linux/fs/ncpfs/sock.c Fri Mar 28 10:42:22 1997 @@ -25,315 +25,59 @@ #include #include #include +#include - -#define _S(nr) (1<<((nr)-1)) -static int _recvfrom(struct socket *sock, unsigned char *ubuf, - int size, int noblock, unsigned flags, - struct sockaddr_ipx *sa) +static int _recv(struct socket *sock, unsigned char *ubuf, int size, + unsigned flags) { - struct iovec iov; - struct msghdr msg; + struct iovec iov; + struct msghdr msg; struct scm_cookie scm; memset(&scm, 0, sizeof(scm)); - iov.iov_base = ubuf; - iov.iov_len = size; - - msg.msg_name = (void *)sa; - msg.msg_namelen = 0; - if (sa) - msg.msg_namelen = sizeof(struct sockaddr_ipx); - msg.msg_control = NULL; - msg.msg_iov = &iov; - msg.msg_iovlen = 1; - if (noblock) { - flags |= MSG_DONTWAIT; - } + iov.iov_base = ubuf; + iov.iov_len = size; - return sock->ops->recvmsg(sock, &msg, size, flags, &scm); + msg.msg_name = NULL; + msg.msg_namelen = 0; + msg.msg_control = NULL; + msg.msg_iov = &iov; + msg.msg_iovlen = 1; + return sock->ops->recvmsg(sock, &msg, size, flags, &scm); } -static int _sendto(struct socket *sock, const void *buff, - int len, int noblock, unsigned flags, - struct sockaddr_ipx *sa) - +static int _send(struct socket *sock, const void *buff, int len) { - struct iovec iov; - struct msghdr msg; + struct iovec iov; + struct msghdr msg; struct scm_cookie scm; int err; - iov.iov_base = (void *)buff; - iov.iov_len = len; - - msg.msg_name = (void *)sa; - msg.msg_namelen = sizeof(struct sockaddr_ipx); - msg.msg_control = NULL; - msg.msg_iov = &iov; - msg.msg_iovlen = 1; + iov.iov_base = (void *) buff; + iov.iov_len = len; - if (noblock) { - flags |= MSG_DONTWAIT; - } - - msg.msg_flags = flags; + msg.msg_name = NULL; + msg.msg_namelen = 0; + msg.msg_control = NULL; + msg.msg_iov = &iov; + msg.msg_iovlen = 1; + msg.msg_flags = 0; err = scm_send(sock, &msg, &scm); - if (err < 0) + if (err < 0) { return err; - err = sock->ops->sendmsg(sock, &msg, len, &scm); + } + err = sock->ops->sendmsg(sock, &msg, len, &scm); scm_destroy(&scm); return err; } - -static void -ncp_wdog_data_ready(struct sock *sk, int len) -{ - struct socket *sock = sk->socket; - - if (!sk->dead) - { - unsigned char packet_buf[2]; - struct sockaddr_ipx sender; - int result; - unsigned short fs; - - fs = get_fs(); - set_fs(get_ds()); - - result = _recvfrom(sock, (void *)packet_buf, 2, 1, 0, - &sender); - - if ( (result != 2) - || (packet_buf[1] != '?') - /* How to check connection number here? */ - ) - { - printk("ncpfs: got strange packet on watchdog " - "socket\n"); - } - else - { - int result; - DDPRINTK("ncpfs: got watchdog from:\n"); - DDPRINTK("ncpfs: %08lX:%02X%02X%02X%02X%02X%02X:%04X," - " conn:%02X,type:%c\n", - htonl(sender.sipx_network), - sender.sipx_node[0], sender.sipx_node[1], - sender.sipx_node[2], sender.sipx_node[3], - sender.sipx_node[4], sender.sipx_node[5], - ntohs(sender.sipx_port), - packet_buf[0], packet_buf[1]); - - packet_buf[1] = 'Y'; - result = _sendto(sock, (void *)packet_buf, 2, 1, 0, - &sender); - DDPRINTK("send result: %d\n", result); - } - set_fs(fs); - } -} - -int -ncp_catch_watchdog(struct ncp_server *server) -{ - struct file *file; - struct inode *inode; - struct socket *sock; - struct sock *sk; - - if ( (server == NULL) - || ((file = server->wdog_filp) == NULL) - || ((inode = file->f_inode) == NULL) - || (!S_ISSOCK(inode->i_mode))) - { - printk("ncp_catch_watchdog: did not get valid server!\n"); - server->data_ready = NULL; - return -EINVAL; - } - - sock = &(inode->u.socket_i); - - if (sock->type != SOCK_DGRAM) - { - printk("ncp_catch_watchdog: did not get SOCK_DGRAM\n"); - server->data_ready = NULL; - return -EINVAL; - } - - sk = sock->sk; - - if (sk == NULL) - { - printk("ncp_catch_watchdog: sk == NULL"); - server->data_ready = NULL; - return -EINVAL; - } - - DDPRINTK("ncp_catch_watchdog: sk->d_r = %x, server->d_r = %x\n", - (unsigned int)(sk->data_ready), - (unsigned int)(server->data_ready)); - - if (sk->data_ready == ncp_wdog_data_ready) - { - printk("ncp_catch_watchdog: already done\n"); - return -EINVAL; - } - - server->data_ready = sk->data_ready; - sk->data_ready = ncp_wdog_data_ready; - sk->allocation = GFP_ATOMIC; - return 0; -} - -int -ncp_dont_catch_watchdog(struct ncp_server *server) -{ - struct file *file; - struct inode *inode; - struct socket *sock; - struct sock *sk; - - if ( (server == NULL) - || ((file = server->wdog_filp) == NULL) - || ((inode = file->f_inode) == NULL) - || (!S_ISSOCK(inode->i_mode))) - { - printk("ncp_dont_catch_watchdog: " - "did not get valid server!\n"); - return -EINVAL; - } - - sock = &(inode->u.socket_i); - - if (sock->type != SOCK_DGRAM) - { - printk("ncp_dont_catch_watchdog: did not get SOCK_DGRAM\n"); - return -EINVAL; - } - - sk = sock->sk; - - if (sk == NULL) - { - printk("ncp_dont_catch_watchdog: sk == NULL"); - return -EINVAL; - } - - if (server->data_ready == NULL) - { - printk("ncp_dont_catch_watchdog: " - "server->data_ready == NULL\n"); - return -EINVAL; - } - - if (sk->data_ready != ncp_wdog_data_ready) - { - printk("ncp_dont_catch_watchdog: " - "sk->data_callback != ncp_data_callback\n"); - return -EINVAL; - } - - DDPRINTK("ncp_dont_catch_watchdog: sk->d_r = %x, server->d_r = %x\n", - (unsigned int)(sk->data_ready), - (unsigned int)(server->data_ready)); - - sk->data_ready = server->data_ready; - sk->allocation = GFP_KERNEL; - server->data_ready = NULL; - return 0; -} - -static void -ncp_msg_data_ready(struct sock *sk, int len) -{ - struct socket *sock = sk->socket; - - if (!sk->dead) - { - unsigned char packet_buf[2]; - struct sockaddr_ipx sender; - int result; - unsigned short fs; - - fs = get_fs(); - set_fs(get_ds()); - - result = _recvfrom(sock, (void *)packet_buf, 2, 1, 0, - &sender); - - DPRINTK("ncpfs: got message of size %d from:\n", result); - DPRINTK("ncpfs: %08lX:%02X%02X%02X%02X%02X%02X:%04X," - " conn:%02X,type:%c\n", - htonl(sender.sipx_network), - sender.sipx_node[0], sender.sipx_node[1], - sender.sipx_node[2], sender.sipx_node[3], - sender.sipx_node[4], sender.sipx_node[5], - ntohs(sender.sipx_port), - packet_buf[0], packet_buf[1]); - - ncp_trigger_message(sk->protinfo.af_ipx.ncp_server); - - set_fs(fs); - } -} - -int -ncp_catch_message(struct ncp_server *server) -{ - struct file *file; - struct inode *inode; - struct socket *sock; - struct sock *sk; - - if ( (server == NULL) - || ((file = server->msg_filp) == NULL) - || ((inode = file->f_inode) == NULL) - || (!S_ISSOCK(inode->i_mode))) - { - printk("ncp_catch_message: did not get valid server!\n"); - return -EINVAL; - } - - sock = &(inode->u.socket_i); - - if (sock->type != SOCK_DGRAM) - { - printk("ncp_catch_message: did not get SOCK_DGRAM\n"); - return -EINVAL; - } - - sk = sock->sk; - - if (sk == NULL) - { - printk("ncp_catch_message: sk == NULL"); - return -EINVAL; - } - - DDPRINTK("ncp_catch_message: sk->d_r = %x\n", - (unsigned int)(sk->data_ready)); - - if (sk->data_ready == ncp_msg_data_ready) - { - printk("ncp_catch_message: already done\n"); - return -EINVAL; - } - - sk->data_ready = ncp_msg_data_ready; - sk->protinfo.af_ipx.ncp_server = server; - return 0; -} - #define NCP_SLACK_SPACE 1024 #define _S(nr) (1<<((nr)-1)) -static int -do_ncp_rpc_call(struct ncp_server *server, int size) +static int do_ncp_rpc_call(struct ncp_server *server, int size) { struct file *file; struct inode *inode; @@ -343,29 +87,24 @@ char *start = server->packet; poll_table wait_table; struct poll_table_entry entry; - int (*select) (struct inode *, poll_table *); int init_timeout, max_timeout; int timeout; int retrans; int major_timeout_seen; int acknowledge_seen; - char *server_name; int n; unsigned long old_mask; /* We have to check the result, so store the complete header */ struct ncp_request_header request = - *((struct ncp_request_header *)(server->packet)); - - struct ncp_reply_header reply; + *((struct ncp_request_header *) (server->packet)); + struct ncp_reply_header reply; file = server->ncp_filp; inode = file->f_inode; - select = file->f_op->poll; sock = &inode->u.socket_i; - if (!sock) - { + if (!sock) { printk("ncp_rpc_call: socki_lookup failed\n"); return -EBADF; } @@ -374,61 +113,53 @@ retrans = server->m.retry_count; major_timeout_seen = 0; acknowledge_seen = 0; - server_name = server->m.server_name; old_mask = current->blocked; current->blocked |= ~(_S(SIGKILL) #if 0 - | _S(SIGSTOP) + | _S(SIGSTOP) #endif - | ((server->m.flags & NCP_MOUNT_INTR) - ? ((current->sig->action[SIGINT - 1].sa_handler == SIG_DFL - ? _S(SIGINT) : 0) - | (current->sig->action[SIGQUIT - 1].sa_handler == SIG_DFL - ? _S(SIGQUIT) : 0)) - : 0)); + | ((server->m.flags & NCP_MOUNT_INTR) + ? ((current->sig->action[SIGINT - 1].sa_handler == SIG_DFL + ? _S(SIGINT) : 0) + | (current->sig->action[SIGQUIT - 1].sa_handler == SIG_DFL + ? _S(SIGQUIT) : 0)) + : 0)); fs = get_fs(); set_fs(get_ds()); - for (n = 0, timeout = init_timeout; ; n++, timeout <<= 1) - { + for (n = 0, timeout = init_timeout;; n++, timeout <<= 1) { DDPRINTK("ncpfs: %08lX:%02X%02X%02X%02X%02X%02X:%04X\n", - htonl(server->m.serv_addr.sipx_network), - server->m.serv_addr.sipx_node[0], - server->m.serv_addr.sipx_node[1], - server->m.serv_addr.sipx_node[2], - server->m.serv_addr.sipx_node[3], - server->m.serv_addr.sipx_node[4], - server->m.serv_addr.sipx_node[5], - ntohs(server->m.serv_addr.sipx_port)); + htonl(server->m.serv_addr.sipx_network), + server->m.serv_addr.sipx_node[0], + server->m.serv_addr.sipx_node[1], + server->m.serv_addr.sipx_node[2], + server->m.serv_addr.sipx_node[3], + server->m.serv_addr.sipx_node[4], + server->m.serv_addr.sipx_node[5], + ntohs(server->m.serv_addr.sipx_port)); DDPRINTK("ncpfs: req.typ: %04X, con: %d, " - "seq: %d", - request.type, - (request.conn_high << 8) + request.conn_low, - request.sequence); + "seq: %d", + request.type, + (request.conn_high << 8) + request.conn_low, + request.sequence); DDPRINTK(" func: %d\n", request.function); - result = _sendto(sock, (void *) start, size, 0, 0, - &(server->m.serv_addr)); - if (result < 0) - { + result = _send(sock, (void *) start, size); + if (result < 0) { printk("ncp_rpc_call: send error = %d\n", result); break; } - re_select: + re_select: wait_table.nr = 0; wait_table.entry = &entry; current->state = TASK_INTERRUPTIBLE; - if (!select(inode, &wait_table)) - { - if (timeout > max_timeout) - { + if (!(file->f_op->poll(file, &wait_table) & POLLIN)) { + if (timeout > max_timeout) { /* JEJB/JSP 2/7/94 * This is useful to see if the system is * hanging */ - if (acknowledge_seen == 0) - { - printk("NCP max timeout reached on " - "%s\n", server_name); + if (acknowledge_seen == 0) { + printk("NCP max timeout\n"); } timeout = max_timeout; } @@ -436,102 +167,87 @@ schedule(); remove_wait_queue(entry.wait_address, &entry.wait); current->state = TASK_RUNNING; - if (current->signal & ~current->blocked) - { + if (current->signal & ~current->blocked) { current->timeout = 0; result = -ERESTARTSYS; break; } - if (!current->timeout) - { + if (!current->timeout) { if (n < retrans) continue; - if (server->m.flags & NCP_MOUNT_SOFT) - { - printk("NCP server %s not responding, " - "timed out\n", server_name); + if (server->m.flags & NCP_MOUNT_SOFT) { + printk("NCP server not responding\n"); result = -EIO; break; } n = 0; timeout = init_timeout; init_timeout <<= 1; - if (!major_timeout_seen) - { - printk("NCP server %s not responding, " - "still trying\n", server_name); + if (!major_timeout_seen) { + printk("NCP server not responding\n"); } major_timeout_seen = 1; continue; - } - else + } else current->timeout = 0; - } - else if (wait_table.nr) + } else if (wait_table.nr) remove_wait_queue(entry.wait_address, &entry.wait); current->state = TASK_RUNNING; /* Get the header from the next packet using a peek, so keep it * on the recv queue. If it is wrong, it will be some reply * we don't now need, so discard it */ - result = _recvfrom(sock, (void *)&reply, - sizeof(reply), 1, MSG_PEEK, NULL); - if (result < 0) - { - if (result == -EAGAIN) - { + result = _recv(sock, (void *) &reply, sizeof(reply), + MSG_PEEK | MSG_DONTWAIT); + if (result < 0) { + if (result == -EAGAIN) { DPRINTK("ncp_rpc_call: bad select ready\n"); goto re_select; } - if (result == -ECONNREFUSED) - { + if (result == -ECONNREFUSED) { DPRINTK("ncp_rpc_call: server playing coy\n"); goto re_select; } - if (result != -ERESTARTSYS) - { + if (result != -ERESTARTSYS) { printk("ncp_rpc_call: recv error = %d\n", - -result); + -result); } break; } - if ( (result == sizeof(reply)) - && (reply.type == NCP_POSITIVE_ACK)) - { + if ((result == sizeof(reply)) + && (reply.type == NCP_POSITIVE_ACK)) { /* Throw away the packet */ DPRINTK("ncp_rpc_call: got positive acknowledge\n"); - _recvfrom(sock, (void *)&reply, sizeof(reply), 1, 0, - NULL); + _recv(sock, (void *) &reply, sizeof(reply), + MSG_DONTWAIT); n = 0; timeout = max_timeout; acknowledge_seen = 1; goto re_select; } - DDPRINTK("ncpfs: rep.typ: %04X, con: %d, tsk: %d," - "seq: %d\n", - reply.type, - (reply.conn_high << 8) + reply.conn_low, - reply.task, - reply.sequence); - - if ( (result >= sizeof(reply)) - && (reply.type == NCP_REPLY) - && ( (request.type == NCP_ALLOC_SLOT_REQUEST) - || ( (reply.sequence == request.sequence) - && (reply.conn_low == request.conn_low) -/* seem to get wrong task from NW311 && (reply.task == request.task)*/ - && (reply.conn_high == request.conn_high)))) - { + "seq: %d\n", + reply.type, + (reply.conn_high << 8) + reply.conn_low, + reply.task, + reply.sequence); + + if ((result >= sizeof(reply)) + && (reply.type == NCP_REPLY) + && ((request.type == NCP_ALLOC_SLOT_REQUEST) + || ((reply.sequence == request.sequence) + && (reply.conn_low == request.conn_low) +/* seem to get wrong task from NW311 && (reply.task == request.task) */ + && (reply.conn_high == request.conn_high)))) { if (major_timeout_seen) - printk("NCP server %s OK\n", server_name); + printk("NCP server OK\n"); break; } /* JEJB/JSP 2/7/94 * we have xid mismatch, so discard the packet and start * again. What a hack! but I can't call recvfrom with * a null buffer yet. */ - _recvfrom(sock, (void *)&reply, sizeof(reply), 1, 0, NULL); + _recv(sock, (void *) &reply, sizeof(reply), MSG_DONTWAIT); DPRINTK("ncp_rpc_call: reply mismatch\n"); goto re_select; @@ -540,54 +256,42 @@ * we have the correct reply, so read into the correct place and * return it */ - result = _recvfrom(sock, (void *)start, server->packet_size, - 1, 0, NULL); - if (result < 0) - { + result = _recv(sock, (void *) start, server->packet_size, MSG_DONTWAIT); + if (result < 0) { printk("NCP: notice message: result=%d\n", result); - } - else if (result < sizeof(struct ncp_reply_header)) - { + } else if (result < sizeof(struct ncp_reply_header)) { printk("NCP: just caught a too small read memory size..., " "email to NET channel\n"); printk("NCP: result=%d\n", result); result = -EIO; } - current->blocked = old_mask; set_fs(fs); return result; } - /* * We need the server to be locked here, so check! */ -static int -ncp_do_request(struct ncp_server *server, int size) +static int ncp_do_request(struct ncp_server *server, int size) { int result; - if (server->lock == 0) - { + if (server->lock == 0) { printk("ncpfs: Server not locked!\n"); return -EIO; } - - if (!ncp_conn_valid(server)) - { + if (!ncp_conn_valid(server)) { return -EIO; } - result = do_ncp_rpc_call(server, size); DDPRINTK("do_ncp_rpc_call returned %d\n", result); - if (result < 0) - { + if (result < 0) { /* There was a problem with I/O, so the connections is - * no longer usable. */ + * no longer usable. */ ncp_invalidate_conn(server); } return result; @@ -596,121 +300,105 @@ /* ncp_do_request assures that at least a complete reply header is * received. It assumes that server->current_size contains the ncp * request size */ -int -ncp_request(struct ncp_server *server, int function) +int ncp_request(struct ncp_server *server, int function) { struct ncp_request_header *h - = (struct ncp_request_header *)(server->packet); + = (struct ncp_request_header *) (server->packet); struct ncp_reply_header *reply - = (struct ncp_reply_header *)(server->packet); + = (struct ncp_reply_header *) (server->packet); int request_size = server->current_size - - sizeof(struct ncp_request_header); + - sizeof(struct ncp_request_header); int result; - if (server->has_subfunction != 0) - { - *(__u16 *)&(h->data[0]) = htons(request_size - 2); + if (server->has_subfunction != 0) { + *(__u16 *) & (h->data[0]) = htons(request_size - 2); } - h->type = NCP_REQUEST; - + server->sequence += 1; - h->sequence = server->sequence; - h->conn_low = (server->connection) & 0xff; + h->sequence = server->sequence; + h->conn_low = (server->connection) & 0xff; h->conn_high = ((server->connection) & 0xff00) >> 8; - h->task = (current->pid) & 0xff; - h->function = function; + h->task = (current->pid) & 0xff; + h->function = function; - if ((result = ncp_do_request(server, request_size + sizeof(*h))) < 0) - { + if ((result = ncp_do_request(server, request_size + sizeof(*h))) < 0) { DPRINTK("ncp_request_error: %d\n", result); return result; } - - server->completion = reply->completion_code; + server->completion = reply->completion_code; server->conn_status = reply->connection_state; - server->reply_size = result; + server->reply_size = result; server->ncp_reply_size = result - sizeof(struct ncp_reply_header); result = reply->completion_code; - if (result != 0) - { + if (result != 0) { DPRINTK("ncp_completion_code: %x\n", result); } - return result; + return result; } -int -ncp_connect(struct ncp_server *server) +int ncp_connect(struct ncp_server *server) { struct ncp_request_header *h - = (struct ncp_request_header *)(server->packet); + = (struct ncp_request_header *) (server->packet); int result; h->type = NCP_ALLOC_SLOT_REQUEST; - + server->sequence = 0; - h->sequence = server->sequence; - h->conn_low = 0xff; + h->sequence = server->sequence; + h->conn_low = 0xff; h->conn_high = 0xff; - h->task = (current->pid) & 0xff; - h->function = 0; + h->task = (current->pid) & 0xff; + h->function = 0; - if ((result = ncp_do_request(server, sizeof(*h))) < 0) - { + if ((result = ncp_do_request(server, sizeof(*h))) < 0) { return result; } - server->sequence = 0; server->connection = h->conn_low + (h->conn_high * 256); return 0; } - -int -ncp_disconnect(struct ncp_server *server) + +int ncp_disconnect(struct ncp_server *server) { struct ncp_request_header *h - = (struct ncp_request_header *)(server->packet); + = (struct ncp_request_header *) (server->packet); h->type = NCP_DEALLOC_SLOT_REQUEST; - + server->sequence += 1; - h->sequence = server->sequence; - h->conn_low = (server->connection) & 0xff; + h->sequence = server->sequence; + h->conn_low = (server->connection) & 0xff; h->conn_high = ((server->connection) & 0xff00) >> 8; - h->task = (current->pid) & 0xff; - h->function = 0; + h->task = (current->pid) & 0xff; + h->function = 0; return ncp_do_request(server, sizeof(*h)); } -void -ncp_lock_server(struct ncp_server *server) +void ncp_lock_server(struct ncp_server *server) { #if 0 /* For testing, only 1 process */ - if (server->lock != 0) - { + if (server->lock != 0) { DPRINTK("ncpfs: server locked!!!\n"); } #endif - while (server->lock) + while (server->lock) sleep_on(&server->wait); server->lock = 1; } -void -ncp_unlock_server(struct ncp_server *server) +void ncp_unlock_server(struct ncp_server *server) { - if (server->lock != 1) - { - printk("ncp_unlock_server: was not locked!\n"); - } - - server->lock = 0; - wake_up(&server->wait); + if (server->lock != 1) { + printk("ncp_unlock_server: was not locked!\n"); + } + server->lock = 0; + wake_up(&server->wait); } - diff -u --recursive --new-file v2.1.30/linux/fs/open.c linux/fs/open.c --- v2.1.30/linux/fs/open.c Sun Jan 26 02:07:44 1997 +++ linux/fs/open.c Wed Apr 2 17:43:22 1997 @@ -675,14 +675,17 @@ #endif -void __fput(struct file *filp, struct inode *inode) +int __fput(struct file *filp, struct inode *inode) { + int error = 0; + if (filp->f_op && filp->f_op->release) - filp->f_op->release(inode,filp); + error = filp->f_op->release(inode,filp); filp->f_inode = NULL; if (filp->f_mode & FMODE_WRITE) put_write_access(inode); iput(inode); + return error; } int close_fp(struct file *filp) @@ -696,8 +699,7 @@ inode = filp->f_inode; if (inode) locks_remove_locks(current, filp); - fput(filp, inode); - return 0; + return fput(filp, inode); } asmlinkage int sys_close(unsigned int fd) diff -u --recursive --new-file v2.1.30/linux/fs/pipe.c linux/fs/pipe.c --- v2.1.30/linux/fs/pipe.c Sat Jan 25 13:46:13 1997 +++ linux/fs/pipe.c Wed Apr 2 17:43:22 1997 @@ -228,25 +228,28 @@ return POLLOUT | POLLWRNORM; } -static void pipe_read_release(struct inode * inode, struct file * filp) +static int pipe_read_release(struct inode * inode, struct file * filp) { PIPE_READERS(*inode)--; wake_up_interruptible(&PIPE_WAIT(*inode)); + return 0; } -static void pipe_write_release(struct inode * inode, struct file * filp) +static int pipe_write_release(struct inode * inode, struct file * filp) { PIPE_WRITERS(*inode)--; wake_up_interruptible(&PIPE_WAIT(*inode)); + return 0; } -static void pipe_rdwr_release(struct inode * inode, struct file * filp) +static int pipe_rdwr_release(struct inode * inode, struct file * filp) { if (filp->f_mode & FMODE_READ) PIPE_READERS(*inode)--; if (filp->f_mode & FMODE_WRITE) PIPE_WRITERS(*inode)--; wake_up_interruptible(&PIPE_WAIT(*inode)); + return 0; } static int pipe_read_open(struct inode * inode, struct file * filp) diff -u --recursive --new-file v2.1.30/linux/fs/proc/kmsg.c linux/fs/proc/kmsg.c --- v2.1.30/linux/fs/proc/kmsg.c Sat Jan 25 13:46:13 1997 +++ linux/fs/proc/kmsg.c Wed Apr 2 17:43:22 1997 @@ -24,9 +24,10 @@ return sys_syslog(1,NULL,0); } -static void kmsg_release(struct inode * inode, struct file * file) +static int kmsg_release(struct inode * inode, struct file * file) { (void) sys_syslog(0,NULL,0); + return 0; } static long kmsg_read(struct inode * inode, struct file * file, diff -u --recursive --new-file v2.1.30/linux/fs/proc/openpromfs.c linux/fs/proc/openpromfs.c --- v2.1.30/linux/fs/proc/openpromfs.c Sun Jan 26 02:07:45 1997 +++ linux/fs/proc/openpromfs.c Wed Apr 2 17:43:22 1997 @@ -405,7 +405,7 @@ return filp->f_pos - k; } -void property_release (struct inode *inode, struct file *filp) +int property_release (struct inode *inode, struct file *filp) { openprom_property *op = (openprom_property *)filp->private_data; unsigned long flags; @@ -413,7 +413,7 @@ u32 node; if (!op) - return; + return 0; node = nodes[(u16)((uint)inode->u.generic_ip)].node; if ((u16)((uint)inode->u.generic_ip) == aliases) { if ((op->flag & OPP_DIRTY) && (op->flag & OPP_STRING)) { @@ -456,6 +456,7 @@ } } kfree (filp->private_data); + return 0; } static struct file_operations openpromfs_prop_ops = { diff -u --recursive --new-file v2.1.30/linux/fs/stat.c linux/fs/stat.c --- v2.1.30/linux/fs/stat.c Sun Jan 26 02:07:45 1997 +++ linux/fs/stat.c Wed Apr 2 17:43:22 1997 @@ -16,6 +16,18 @@ #include +/* + * Revalidate the inode. This is required for proper NFS attribute caching. + */ +static __inline__ int +do_revalidate(struct inode *inode) +{ + if (inode->i_op && inode->i_op->revalidate) + return inode->i_op->revalidate(inode); + return 0; +} + + #if !defined(__alpha__) && !defined(__sparc__) /* @@ -118,7 +130,8 @@ error = namei(filename,&inode); if (error) goto out; - error = cp_old_stat(inode,statbuf); + if ((error = do_revalidate(inode)) == 0) + error = cp_old_stat(inode,statbuf); iput(inode); out: unlock_kernel(); @@ -135,7 +148,8 @@ error = namei(filename,&inode); if (error) goto out; - error = cp_new_stat(inode,statbuf); + if ((error = do_revalidate(inode)) == 0) + error = cp_new_stat(inode,statbuf); iput(inode); out: unlock_kernel(); @@ -157,7 +171,8 @@ error = lnamei(filename,&inode); if (error) goto out; - error = cp_old_stat(inode,statbuf); + if ((error = do_revalidate(inode)) == 0) + error = cp_old_stat(inode,statbuf); iput(inode); out: unlock_kernel(); @@ -175,7 +190,8 @@ error = lnamei(filename,&inode); if (error) goto out; - error = cp_new_stat(inode,statbuf); + if ((error = do_revalidate(inode)) == 0) + error = cp_new_stat(inode,statbuf); iput(inode); out: unlock_kernel(); @@ -197,7 +213,8 @@ lock_kernel(); if (fd >= NR_OPEN || !(f=current->files->fd[fd]) || !(inode=f->f_inode)) goto out; - ret = cp_old_stat(inode,statbuf); + if ((ret = do_revalidate(inode)) == 0) + ret = cp_old_stat(inode,statbuf); out: unlock_kernel(); return ret; @@ -214,7 +231,8 @@ lock_kernel(); if (fd >= NR_OPEN || !(f=current->files->fd[fd]) || !(inode=f->f_inode)) goto out; - err = cp_new_stat(inode,statbuf); + if ((err = do_revalidate(inode)) == 0) + err = cp_new_stat(inode,statbuf); out: unlock_kernel(); return err; @@ -235,7 +253,8 @@ if (error) goto out; error = -EINVAL; - if (!inode->i_op || !inode->i_op->readlink) { + if (!inode->i_op || !inode->i_op->readlink + || (error = do_revalidate(inode)) < 0) { iput(inode); goto out; } diff -u --recursive --new-file v2.1.30/linux/fs/super.c linux/fs/super.c --- v2.1.30/linux/fs/super.c Thu Mar 27 14:40:06 1997 +++ linux/fs/super.c Wed Apr 2 17:43:22 1997 @@ -48,7 +48,6 @@ extern void wait_for_keypress(void); extern struct file_operations * get_blkfops(unsigned int major); -extern void blkdev_release (struct inode *); extern int root_mountflags; diff -u --recursive --new-file v2.1.30/linux/include/asm-alpha/atomic.h linux/include/asm-alpha/atomic.h --- v2.1.30/linux/include/asm-alpha/atomic.h Wed Sep 11 11:41:51 1996 +++ linux/include/asm-alpha/atomic.h Fri Mar 28 10:52:25 1997 @@ -1,14 +1,16 @@ -#ifndef __ARCH_ALPHA_ATOMIC__ -#define __ARCH_ALPHA_ATOMIC__ +#ifndef _ALPHA_ATOMIC_H +#define _ALPHA_ATOMIC_H /* * Atomic operations that C can't guarantee us. Useful for * resource counting etc... * - * But use these as seldom as possible since they are much more slower + * But use these as seldom as possible since they are much slower * than regular operations. */ +typedef int atomic_t; + /* * Make sure gcc doesn't try to be clever and move things around * on us. We need to use _exactly_ the address the user gave us, @@ -16,38 +18,40 @@ */ #define __atomic_fool_gcc(x) (*(struct { int a[100]; } *)x) -typedef int atomic_t; +/* + * To get proper branch prediction for the main line, we must branch + * forward to code at the end of this object's .text section, then + * branch back to restart the operation. + */ extern __inline__ void atomic_add(atomic_t i, atomic_t * v) { unsigned long temp; __asm__ __volatile__( - "\n1:\t" - "ldl_l %0,%1\n\t" - "addl %0,%2,%0\n\t" - "stl_c %0,%1\n\t" - "beq %0,1b\n" - "2:" - :"=&r" (temp), - "=m" (__atomic_fool_gcc(v)) - :"Ir" (i), - "m" (__atomic_fool_gcc(v))); + "1: ldl_l %0,%1\n" + " addl %0,%2,%0\n" + " stl_c %0,%1\n" + " beq %0,2f\n" + ".text 2\n" + "2: br 1b\n" + ".text" + :"=&r" (temp), "=m" (__atomic_fool_gcc(v)) + :"Ir" (i), "m" (__atomic_fool_gcc(v))); } extern __inline__ void atomic_sub(atomic_t i, atomic_t * v) { unsigned long temp; __asm__ __volatile__( - "\n1:\t" - "ldl_l %0,%1\n\t" - "subl %0,%2,%0\n\t" - "stl_c %0,%1\n\t" - "beq %0,1b\n" - "2:" - :"=&r" (temp), - "=m" (__atomic_fool_gcc(v)) - :"Ir" (i), - "m" (__atomic_fool_gcc(v))); + "1: ldl_l %0,%1\n" + " subl %0,%2,%0\n" + " stl_c %0,%1\n" + " beq %0,2f\n" + ".text 2\n" + "2: br 1b\n" + ".text" + :"=&r" (temp), "=m" (__atomic_fool_gcc(v)) + :"Ir" (i), "m" (__atomic_fool_gcc(v))); } /* @@ -57,18 +61,16 @@ { long temp, result; __asm__ __volatile__( - "\n1:\t" - "ldl_l %0,%1\n\t" - "addl %0,%3,%0\n\t" - "bis %0,%0,%2\n\t" - "stl_c %0,%1\n\t" - "beq %0,1b\n" - "2:" - :"=&r" (temp), - "=m" (__atomic_fool_gcc(v)), - "=&r" (result) - :"Ir" (i), - "m" (__atomic_fool_gcc(v))); + "1: ldl_l %0,%1\n" + " addl %0,%3,%0\n" + " mov %0,%2\n" + " stl_c %0,%1\n" + " beq %0,2f\n" + ".text 2\n" + "2: br 1b\n" + ".text" + :"=&r" (temp), "=m" (__atomic_fool_gcc(v)), "=&r" (result) + :"Ir" (i), "m" (__atomic_fool_gcc(v))); return result; } @@ -76,18 +78,16 @@ { long temp, result; __asm__ __volatile__( - "\n1:\t" - "ldl_l %0,%1\n\t" - "subl %0,%3,%0\n\t" - "bis %0,%0,%2\n\t" - "stl_c %0,%1\n\t" - "beq %0,1b\n" - "2:" - :"=&r" (temp), - "=m" (__atomic_fool_gcc(v)), - "=&r" (result) - :"Ir" (i), - "m" (__atomic_fool_gcc(v))); + "1: ldl_l %0,%1\n" + " subl %0,%3,%0\n" + " mov %0,%2\n" + " stl_c %0,%1\n" + " beq %0,2f\n" + ".text 2\n" + "2: br 1b\n" + ".text" + :"=&r" (temp), "=m" (__atomic_fool_gcc(v)), "=&r" (result) + :"Ir" (i), "m" (__atomic_fool_gcc(v))); return result; } @@ -100,4 +100,4 @@ #define atomic_inc(v) atomic_add(1,(v)) #define atomic_dec(v) atomic_sub(1,(v)) -#endif +#endif /* _ALPHA_ATOMIC_H */ diff -u --recursive --new-file v2.1.30/linux/include/asm-alpha/bitops.h linux/include/asm-alpha/bitops.h --- v2.1.30/linux/include/asm-alpha/bitops.h Fri Dec 20 01:24:38 1996 +++ linux/include/asm-alpha/bitops.h Fri Mar 28 10:52:25 1997 @@ -10,6 +10,10 @@ * is guaranteed to be atomic. All bit operations return 0 if the bit * was cleared before the operation and != 0 if it was not. * + * To get proper branch prediction for the main line, we must branch + * forward to code at the end of this object's .text section, then + * branch back to restart the operation. + * * bit 0 is the LSB of addr; bit 64 is the LSB of (addr+1). */ @@ -20,19 +24,19 @@ unsigned int * m = ((unsigned int *) addr) + (nr >> 5); __asm__ __volatile__( - "\n1:\t" - "ldl_l %0,%1\n\t" - "and %0,%3,%2\n\t" - "bne %2,2f\n\t" - "xor %0,%3,%0\n\t" - "stl_c %0,%1\n\t" - "beq %0,1b\n" - "2:" - :"=&r" (temp), - "=m" (*m), - "=&r" (oldbit) - :"Ir" (1UL << (nr & 31)), - "m" (*m)); + "1: ldl_l %0,%1\n" + " and %0,%3,%2\n" + " bne %2,2f\n" + " xor %0,%3,%0\n" + " stl_c %0,%1\n" + " beq %0,3f\n" + "2:\n" + ".text 2\n" + "3: br 1b\n" + ".text" + :"=&r" (temp), "=m" (*m), "=&r" (oldbit) + :"Ir" (1UL << (nr & 31)), "m" (*m)); + return oldbit != 0; } @@ -43,19 +47,19 @@ unsigned int * m = ((unsigned int *) addr) + (nr >> 5); __asm__ __volatile__( - "\n1:\t" - "ldl_l %0,%1\n\t" - "and %0,%3,%2\n\t" - "beq %2,2f\n\t" - "xor %0,%3,%0\n\t" - "stl_c %0,%1\n\t" - "beq %0,1b\n" - "2:" - :"=&r" (temp), - "=m" (*m), - "=&r" (oldbit) - :"Ir" (1UL << (nr & 31)), - "m" (*m)); + "1: ldl_l %0,%1\n" + " and %0,%3,%2\n\t" + " beq %2,2f\n\t" + " xor %0,%3,%0\n\t" + " stl_c %0,%1\n\t" + " beq %0,3f\n" + "2:\n" + ".text 2\n" + "3: br 1b\n" + ".text" + :"=&r" (temp), "=m" (*m), "=&r" (oldbit) + :"Ir" (1UL << (nr & 31)), "m" (*m)); + return oldbit != 0; } @@ -66,17 +70,17 @@ unsigned int * m = ((unsigned int *) addr) + (nr >> 5); __asm__ __volatile__( - "\n1:\t" - "ldl_l %0,%1\n\t" - "and %0,%3,%2\n\t" - "xor %0,%3,%0\n\t" - "stl_c %0,%1\n\t" - "beq %0,1b\n" - :"=&r" (temp), - "=m" (*m), - "=&r" (oldbit) - :"Ir" (1UL << (nr & 31)), - "m" (*m)); + "1: ldl_l %0,%1\n" + " and %0,%3,%2\n\t" + " xor %0,%3,%0\n\t" + " stl_c %0,%1\n\t" + " beq %0,3f\n" + ".text 2\n" + "3: br 1b\n" + ".text" + :"=&r" (temp), "=m" (*m), "=&r" (oldbit) + :"Ir" (1UL << (nr & 31)), "m" (*m)); + return oldbit != 0; } diff -u --recursive --new-file v2.1.30/linux/include/asm-alpha/hardirq.h linux/include/asm-alpha/hardirq.h --- v2.1.30/linux/include/asm-alpha/hardirq.h Wed Dec 31 16:00:00 1969 +++ linux/include/asm-alpha/hardirq.h Fri Mar 28 11:14:41 1997 @@ -0,0 +1,20 @@ +#ifndef _ALPHA_HARDIRQ_H +#define _ALPHA_HARDIRQ_H + +extern unsigned int local_irq_count[NR_CPUS]; +#define in_interrupt() (local_irq_count[smp_processor_id()] != 0) + +#ifndef __SMP__ + +#define hardirq_trylock(cpu) ((cpu) == 0) +#define hardirq_endlock(cpu) do { } while (0) + +#define hardirq_enter(cpu) (local_irq_count[cpu]++) +#define hardirq_exit(cpu) (local_irq_count[cpu]--) + +#else + +#error FIXME + +#endif /* __SMP__ */ +#endif /* _ALPHA_HARDIRQ_H */ diff -u --recursive --new-file v2.1.30/linux/include/asm-alpha/smp_lock.h linux/include/asm-alpha/smp_lock.h --- v2.1.30/linux/include/asm-alpha/smp_lock.h Sun Jan 26 03:40:46 1997 +++ linux/include/asm-alpha/smp_lock.h Fri Mar 28 11:03:25 1997 @@ -3,8 +3,10 @@ #ifndef __SMP__ -#define lock_kernel() do { } while(0) -#define unlock_kernel() do { } while(0) +#define lock_kernel() do { } while(0) +#define unlock_kernel() do { } while(0) +#define release_kernel_lock(task, cpu, depth) ((depth) = 1) +#define reaquire_kernel_lock(task, cpu, depth) do { } while (0) #else diff -u --recursive --new-file v2.1.30/linux/include/asm-alpha/softirq.h linux/include/asm-alpha/softirq.h --- v2.1.30/linux/include/asm-alpha/softirq.h Wed Dec 31 16:00:00 1969 +++ linux/include/asm-alpha/softirq.h Fri Mar 28 11:16:22 1997 @@ -0,0 +1,35 @@ +#ifndef _ALPHA_SOFTIRQ_H +#define _ALPHA_SOFTIRQ_H + +/* + * Software interrupts.. + */ +#define get_active_bhs() (bh_mask & bh_active) + +static inline void clear_active_bhs(unsigned long x) +{ + unsigned long temp; + __asm__ __volatile__( + "1: ldq_l %0,%1\n" + " and %0,%2,%0\n" + " stq_c %0,%1\n" + " beq %0,2f\n" + ".text 2\n" + "2: br 1b\n" + ".text" + :"=&r" (temp), "=m" (bh_active) + :"Ir" (x), "m" (bh_active)); +} + +#ifndef __SMP__ + +/* These are for the irq's testing the lock */ +#define softirq_trylock() (intr_count ? 0 : ((intr_count=1),1)) +#define softirq_endlock() (intr_count = 0) + +#else + +#error FIXME + +#endif /* __SMP__ */ +#endif /* _ALPHA_SOFTIRQ_H */ diff -u --recursive --new-file v2.1.30/linux/include/asm-alpha/spinlock.h linux/include/asm-alpha/spinlock.h --- v2.1.30/linux/include/asm-alpha/spinlock.h Wed Dec 31 16:00:00 1969 +++ linux/include/asm-alpha/spinlock.h Fri Mar 28 11:13:21 1997 @@ -0,0 +1,92 @@ +#ifndef _ALPHA_SPINLOCK_H +#define _ALPHA_SPINLOCK_H + +#ifndef __SMP__ + +typedef struct { } spinlock_t; +#define SPIN_LOCK_UNLOCKED { } + +#define spin_lock_init(lock) do { } while(0) +#define spin_lock(lock) do { } while(0) +#define spin_trylock(lock) do { } while(0) +#define spin_unlock(lock) do { } while(0) +#define spin_lock_irq(lock) setipl(7) +#define spin_unlock_irq(lock) setipl(0) + +#define spin_lock_irqsave(lock, flags) swpipl(flags,7) +#define spin_unlock_irqrestore(lock, flags) setipl(flags) + +#else + +/* Simple spin lock operations. There are two variants, one clears IRQ's + * on the local processor, one does not. + * + * We make no fairness assumptions. They have a cost. + */ + +typedef struct { + volatile unsigned long lock; + unsigned long previous; +} spinlock_t; + +#define SPIN_LOCK_UNLOCKED { 0, 0 } + +typedef struct { unsigned long a[100]; } __dummy_lock_t; +#define __dummy_lock(lock) (*(__dummy_lock_t *)(lock)) + +#define spin_unlock(lock) \ + __asm__ __volatile__( \ + "mb; stq $31,%0" \ + :"=m" (__dummy_lock(lock))) + +static inline void spin_lock(spinlock_t * lock) +{ + __label__ l1; + long tmp; + long stuck = 0x100000000; +l1: + /* Use sub-sections to put the actual loop at the end + of this object file's text section so as to perfect + branch prediction. */ + __asm__ __volatile__( + "1: ldq_l %0,%1\n" + " subq %2,1,%2\n" + " blbs %0,2f\n" + " or %0,1,%0\n" + " stq_c %0,%1\n" + " beq %0,3f\n" + "4: mb\n" + ".text 2\n" + "2: ldq %0,%1\n" + " subq %2,1,%2\n" + "3: blt %2,4b\n" + " blbs %0,2b\n" + " br 1b\n" + ".text" + : "=r" (tmp), + "=m" (__dummy_lock(lock)), + "=r" (stuck) + : "2" (stuck)); + + if (stuck < 0) + printk("spinlock stuck at %p (%lx)\n",&&l1,lock->previous); + else + lock->previous = (unsigned long) &&l1; +} + +#define spin_trylock(lock) (!set_bit(0,(lock))) + +#define spin_lock_irq(lock) \ + do { __cli(); spin_lock(lock); } while (0) + +#define spin_unlock_irq(lock) \ + do { spin_unlock(lock); __sti(); } while (0) + +#define spin_lock_irqsave(lock, flags) \ + do { swpipl(flags,7); spin_lock(lock); } while (0) + +#define spin_unlock_irqrestore(lock, flags) \ + do { spin_unlock(lock); setipl(flags); } while (0) + +#endif /* SMP */ +#endif /* _ALPHA_SPINLOCK_H */ diff -u --recursive --new-file v2.1.30/linux/include/asm-alpha/system.h linux/include/asm-alpha/system.h --- v2.1.30/linux/include/asm-alpha/system.h Thu Feb 6 04:42:35 1997 +++ linux/include/asm-alpha/system.h Fri Mar 28 11:13:21 1997 @@ -70,14 +70,12 @@ #define draina() \ __asm__ __volatile__ ("call_pal %0" : : "i" (PAL_draina) : "memory") -#define getipl() \ -({ unsigned long __old_ipl; \ +#define getipl(__old_ipl) \ __asm__ __volatile__( \ "call_pal 54\n\t" \ "bis $0,$0,%0" \ : "=r" (__old_ipl) \ - : : "$0", "$1", "$16", "$22", "$23", "$24", "$25"); \ -__old_ipl; }) + : : "$0", "$1", "$16", "$22", "$23", "$24", "$25") #define setipl(__new_ipl) \ __asm__ __volatile__( \ @@ -86,20 +84,23 @@ : : "r" (__new_ipl) \ : "$0", "$1", "$16", "$22", "$23", "$24", "$25", "memory") -#define swpipl(__new_ipl) \ -({ unsigned long __old_ipl; \ +#define swpipl(__old_ipl,__new_ipl) \ __asm__ __volatile__( \ "bis %1,%1,$16\n\t" \ "call_pal 53\n\t" \ "bis $0,$0,%0" \ : "=r" (__old_ipl) \ : "r" (__new_ipl) \ - : "$0", "$1", "$16", "$22", "$23", "$24", "$25", "memory"); \ -__old_ipl; }) + : "$0", "$1", "$16", "$22", "$23", "$24", "$25", "memory") + +#define __cli() setipl(7) +#define __sti() setipl(0) +#define __save_flags(flags) getipl(flags) +#define __restore_flags(flags) setipl(flags) #define cli() setipl(7) #define sti() setipl(0) -#define save_flags(flags) do { flags = getipl(); } while (0) +#define save_flags(flags) getipl(flags) #define restore_flags(flags) setipl(flags) /* @@ -122,28 +123,36 @@ extern __inline__ unsigned long xchg_u32(volatile int * m, unsigned long val) { unsigned long dummy; + __asm__ __volatile__( - "\n1:\t" - "ldl_l %0,%2\n\t" - "bis %3,%3,%1\n\t" - "stl_c %1,%2\n\t" - "beq %1,1b\n" - : "=&r" (val), "=&r" (dummy), "=m" (*m) - : "r" (val), "m" (*m)); + "1: ldl_l %0,%2\n" + " bis %3,%3,%1\n" + " stl_c %1,%2\n" + " beq %1,2f\n" + ".text 2\n" + "2: br 1b\n" + ".text" + : "=&r" (val), "=&r" (dummy), "=m" (*m) + : "r" (val), "m" (*m)); + return val; } extern __inline__ unsigned long xchg_u64(volatile long * m, unsigned long val) { unsigned long dummy; + __asm__ __volatile__( - "\n1:\t" - "ldq_l %0,%2\n\t" - "bis %3,%3,%1\n\t" - "stq_c %1,%2\n\t" - "beq %1,1b\n" - : "=&r" (val), "=&r" (dummy), "=m" (*m) - : "r" (val), "m" (*m)); + "1: ldq_l %0,%2\n" + " bis %3,%3,%1\n" + " stq_c %1,%2\n" + " beq %1,2f\n" + ".text 2\n" + "2: br 1b\n" + ".text" + : "=&r" (val), "=&r" (dummy), "=m" (*m) + : "r" (val), "m" (*m)); + return val; } diff -u --recursive --new-file v2.1.30/linux/include/asm-alpha/termios.h linux/include/asm-alpha/termios.h --- v2.1.30/linux/include/asm-alpha/termios.h Mon Dec 30 02:48:07 1996 +++ linux/include/asm-alpha/termios.h Fri Mar 28 11:02:43 1997 @@ -85,58 +85,68 @@ /* * Translate a "termio" structure into a "termios". Ugh. */ -#define SET_LOW_TERMIOS_BITS(termios, termio, x) { \ - unsigned short __tmp; \ - get_user(__tmp,&(termio)->x); \ - *(unsigned short *) &(termios)->x = __tmp; \ -} -#define user_termio_to_kernel_termios(termios, termio) \ -do { \ - SET_LOW_TERMIOS_BITS(termios, termio, c_iflag); \ - SET_LOW_TERMIOS_BITS(termios, termio, c_oflag); \ - SET_LOW_TERMIOS_BITS(termios, termio, c_cflag); \ - SET_LOW_TERMIOS_BITS(termios, termio, c_lflag); \ - get_user((termios)->c_cc[VINTR], &(termio)->c_cc[_VINTR]); \ - get_user((termios)->c_cc[VQUIT], &(termio)->c_cc[_VQUIT]); \ - get_user((termios)->c_cc[VERASE], &(termio)->c_cc[_VERASE]); \ - get_user((termios)->c_cc[VKILL], &(termio)->c_cc[_VKILL]); \ - get_user((termios)->c_cc[VEOF], &(termio)->c_cc[_VEOF]); \ - get_user((termios)->c_cc[VMIN], &(termio)->c_cc[_VMIN]); \ - get_user((termios)->c_cc[VEOL], &(termio)->c_cc[_VEOL]); \ - get_user((termios)->c_cc[VTIME], &(termio)->c_cc[_VTIME]); \ - get_user((termios)->c_cc[VEOL2], &(termio)->c_cc[_VEOL2]); \ - get_user((termios)->c_cc[VSWTC], &(termio)->c_cc[_VSWTC]); \ -} while(0) +#define user_termio_to_kernel_termios(a_termios, u_termio) \ +({ \ + struct termios *k_termios = (a_termios); \ + struct termio k_termio; \ + int canon, ret; \ + \ + ret = copy_from_user(&k_termio, u_termio, sizeof(k_termio)); \ + if (!ret) { \ + /* Overwrite only the low bits. */ \ + *(unsigned short *)&k_termios->c_iflag = k_termio.c_iflag; \ + *(unsigned short *)&k_termios->c_oflag = k_termio.c_oflag; \ + *(unsigned short *)&k_termios->c_cflag = k_termio.c_cflag; \ + *(unsigned short *)&k_termios->c_lflag = k_termio.c_lflag; \ + canon = k_termio.c_lflag & ICANON; \ + \ + k_termios->c_cc[VINTR] = k_termio.c_cc[_VINTR]; \ + k_termios->c_cc[VQUIT] = k_termio.c_cc[_VQUIT]; \ + k_termios->c_cc[VERASE] = k_termio.c_cc[_VERASE]; \ + k_termios->c_cc[VKILL] = k_termio.c_cc[_VKILL]; \ + k_termios->c_cc[VEOL2] = k_termio.c_cc[_VEOL2]; \ + k_termios->c_cc[VSWTC] = k_termio.c_cc[_VSWTC]; \ + k_termios->c_cc[canon ? VEOF : VMIN] = k_termio.c_cc[_VEOF]; \ + k_termios->c_cc[canon ? VEOL : VTIME] = k_termio.c_cc[_VEOL]; \ + } \ + ret; \ +}) /* * Translate a "termios" structure into a "termio". Ugh. * * Note the "fun" _VMIN overloading. */ -#define kernel_termios_to_user_termio(termio, termios) \ -do { \ - put_user((termios)->c_iflag, &(termio)->c_iflag); \ - put_user((termios)->c_oflag, &(termio)->c_oflag); \ - put_user((termios)->c_cflag, &(termio)->c_cflag); \ - put_user((termios)->c_lflag, &(termio)->c_lflag); \ - put_user((termios)->c_line, &(termio)->c_line); \ - put_user((termios)->c_cc[VINTR], &(termio)->c_cc[_VINTR]); \ - put_user((termios)->c_cc[VQUIT], &(termio)->c_cc[_VQUIT]); \ - put_user((termios)->c_cc[VERASE], &(termio)->c_cc[_VERASE]); \ - put_user((termios)->c_cc[VKILL], &(termio)->c_cc[_VKILL]); \ - put_user((termios)->c_cc[VEOF], &(termio)->c_cc[_VEOF]); \ - put_user((termios)->c_cc[VEOL], &(termio)->c_cc[_VEOL]); \ - put_user((termios)->c_cc[VEOL2], &(termio)->c_cc[_VEOL2]); \ - put_user((termios)->c_cc[VSWTC], &(termio)->c_cc[_VSWTC]); \ - if (!((termios)->c_lflag & ICANON)) { \ - put_user((termios)->c_cc[VMIN], &(termio)->c_cc[_VMIN]); \ - put_user((termios)->c_cc[VTIME], &(termio)->c_cc[_VTIME]); \ - } \ -} while(0) +#define kernel_termios_to_user_termio(u_termio, a_termios) \ +({ \ + struct termios *k_termios = (a_termios); \ + struct termio k_termio; \ + int canon; \ + \ + k_termio.c_iflag = k_termios->c_iflag; \ + k_termio.c_oflag = k_termios->c_oflag; \ + k_termio.c_cflag = k_termios->c_cflag; \ + canon = (k_termio.c_lflag = k_termios->c_lflag) & ICANON; \ + \ + k_termio.c_line = k_termios->c_line; \ + k_termio.c_cc[_VINTR] = k_termios->c_cc[VINTR]; \ + k_termio.c_cc[_VQUIT] = k_termios->c_cc[VQUIT]; \ + k_termio.c_cc[_VERASE] = k_termios->c_cc[VERASE]; \ + k_termio.c_cc[_VKILL] = k_termios->c_cc[VKILL]; \ + k_termio.c_cc[_VEOF] = k_termios->c_cc[canon ? VEOF : VMIN]; \ + k_termio.c_cc[_VEOL] = k_termios->c_cc[canon ? VEOL : VTIME]; \ + k_termio.c_cc[_VEOL2] = k_termios->c_cc[VEOL2]; \ + k_termio.c_cc[_VSWTC] = k_termios->c_cc[VSWTC]; \ + \ + copy_to_user(u_termio, &k_termio, sizeof(k_termio)); \ +}) -#define user_termios_to_kernel_termios(k, u) copy_from_user(k, u, sizeof(struct termios)) -#define kernel_termios_to_user_termios(u, k) copy_to_user(u, k, sizeof(struct termios)) +#define user_termios_to_kernel_termios(k, u) \ + copy_from_user(k, u, sizeof(struct termios)) + +#define kernel_termios_to_user_termios(u, k) \ + copy_to_user(u, k, sizeof(struct termios)) #endif /* __KERNEL__ */ diff -u --recursive --new-file v2.1.30/linux/include/asm-alpha/unistd.h linux/include/asm-alpha/unistd.h --- v2.1.30/linux/include/asm-alpha/unistd.h Thu Jan 23 11:01:28 1997 +++ linux/include/asm-alpha/unistd.h Wed Apr 2 17:43:22 1997 @@ -279,7 +279,7 @@ #define __NR_uname 339 #define __NR_nanosleep 340 #define __NR_mremap 341 -#define __NR_nfsctl 342 +#define __NR_nfsservctl 342 #define __NR_setresuid 343 #define __NR_getresuid 344 #define __NR_pciconfig_read 345 diff -u --recursive --new-file v2.1.30/linux/include/asm-i386/io.h linux/include/asm-i386/io.h --- v2.1.30/linux/include/asm-i386/io.h Mon Oct 14 23:31:45 1996 +++ linux/include/asm-i386/io.h Wed Apr 2 17:51:57 1997 @@ -1,6 +1,8 @@ #ifndef _ASM_IO_H #define _ASM_IO_H +#include + /* * This file contains the definitions for the x86 IO instructions * inb/inw/inl/outb/outw/outl and the "string versions" of the same @@ -184,7 +186,23 @@ return __io_virt(address); } -extern void * ioremap(unsigned long offset, unsigned long size); +extern void * __ioremap(unsigned long offset, unsigned long size, unsigned long flags); + +extern inline void * ioremap (unsigned long offset, unsigned long size) +{ + return __ioremap(offset, size, 0); +} + +/* + * This one maps high address device memory and turns off caching for that area. + * it's useful if some control registers are in such an area and write combining + * or read caching is not desirable: + */ +extern inline void * ioremap_nocache (unsigned long offset, unsigned long size) +{ + return __ioremap(offset, size, _PAGE_PCD); +} + extern void iounmap(void *addr); /* diff -u --recursive --new-file v2.1.30/linux/include/asm-i386/smp_lock.h linux/include/asm-i386/smp_lock.h --- v2.1.30/linux/include/asm-i386/smp_lock.h Thu Mar 27 14:40:06 1997 +++ linux/include/asm-i386/smp_lock.h Mon Mar 31 12:52:31 1997 @@ -1,6 +1,8 @@ #ifndef __I386_SMPLOCK_H #define __I386_SMPLOCK_H +#define __STR(x) #x + #ifndef __SMP__ #define lock_kernel() do { } while(0) @@ -77,9 +79,9 @@ cli decl %0 jnz 1f - movb %1, active_kernel_processor + movb %1, " __STR(active_kernel_processor) " lock - btrl $0, kernel_flag + btrl $0, " __STR(kernel_flag) " 1: popfl " : /* no outputs */ diff -u --recursive --new-file v2.1.30/linux/include/asm-i386/termios.h linux/include/asm-i386/termios.h --- v2.1.30/linux/include/asm-i386/termios.h Thu Mar 27 14:40:06 1997 +++ linux/include/asm-i386/termios.h Mon Mar 31 12:52:31 1997 @@ -45,6 +45,7 @@ #define N_PPP 3 #define N_STRIP 4 #define N_AX25 5 +#define N_X25 6 /* X.25 async */ #ifdef __KERNEL__ diff -u --recursive --new-file v2.1.30/linux/include/asm-i386/unistd.h linux/include/asm-i386/unistd.h --- v2.1.30/linux/include/asm-i386/unistd.h Thu Jan 23 11:01:28 1997 +++ linux/include/asm-i386/unistd.h Wed Apr 2 17:43:22 1997 @@ -174,6 +174,7 @@ #define __NR_vm86 166 #define __NR_query_module 167 #define __NR_poll 168 +#define __NR_nfsservctl 169 /* user-visible error numbers are in the range -1 - -122: see */ diff -u --recursive --new-file v2.1.30/linux/include/asm-m68k/unistd.h linux/include/asm-m68k/unistd.h --- v2.1.30/linux/include/asm-m68k/unistd.h Fri Nov 22 05:56:36 1996 +++ linux/include/asm-m68k/unistd.h Wed Apr 2 17:43:22 1997 @@ -171,6 +171,7 @@ #define __NR_mremap 163 #define __NR_setresuid 164 #define __NR_getresuid 165 +#define __NR_nfsservctl 166 /* user-visible error numbers are in the range -1 - -122: see */ diff -u --recursive --new-file v2.1.30/linux/include/asm-mips/unistd.h linux/include/asm-mips/unistd.h --- v2.1.30/linux/include/asm-mips/unistd.h Wed Dec 13 02:39:47 1995 +++ linux/include/asm-mips/unistd.h Wed Apr 2 17:43:22 1997 @@ -1143,6 +1143,7 @@ #define __NR_munlock (__NR_Linux + 155) #define __NR_mlockall (__NR_Linux + 156) #define __NR_munlockall (__NR_Linux + 157) +#define __NR_nfsservctl (__NR_Linux + 158) /* diff -u --recursive --new-file v2.1.30/linux/include/asm-ppc/unistd.h linux/include/asm-ppc/unistd.h --- v2.1.30/linux/include/asm-ppc/unistd.h Wed Dec 18 00:54:10 1996 +++ linux/include/asm-ppc/unistd.h Wed Apr 2 17:43:22 1997 @@ -175,6 +175,7 @@ #define __NR_mremap 163 #define __NR_setresuid 164 #define __NR_getresuid 165 +#define __NR_nfsservctl 166 /* XXX - _foo needs to be __foo, while __NR_bar could be _NR_bar. */ #define _syscall0(type,name) \ diff -u --recursive --new-file v2.1.30/linux/include/asm-sparc/unistd.h linux/include/asm-sparc/unistd.h --- v2.1.30/linux/include/asm-sparc/unistd.h Mon Mar 17 14:54:33 1997 +++ linux/include/asm-sparc/unistd.h Wed Apr 2 17:43:22 1997 @@ -270,7 +270,7 @@ #define __NR__sysctl 251 #define __NR_getsid 252 #define __NR_fdatasync 253 -#define __NR_nfsctl 254 +#define __NR_nfsservctl 254 #define __NR_aplib 255 #define _syscall0(type,name) \ diff -u --recursive --new-file v2.1.30/linux/include/linux/auto_fs.h linux/include/linux/auto_fs.h --- v2.1.30/linux/include/linux/auto_fs.h Wed Dec 31 16:00:00 1969 +++ linux/include/linux/auto_fs.h Wed Apr 2 17:55:03 1997 @@ -0,0 +1,177 @@ +/* -*- linux-c -*- --------------------------------------------------------- * + * + * linux/include/linux/auto_fs.h + * + * Copyright 1997 Transmeta Corporation -- All Rights Reserved + * + * This file is part of the Linux kernel and is made available under + * the terms of the GNU General Public License, version 2, or at your + * option, any later version, incorporated herein by reference. + * + * ------------------------------------------------------------------------- */ + + +#ifndef _LINUX_AUTO_FS_H +#define _LINUX_AUTO_FS_H + +#include +#include +#include +#include +#include + +#define AUTOFS_PROTO_VERSION 2 + +enum autofs_packet_type { + autofs_ptype_missing, /* Missing entry (create wait queue) */ + /* ...need more in the future... */ +}; + +struct autofs_packet_hdr { + int proto_version; /* Protocol version */ + enum autofs_packet_type type; /* Type of packet */ +}; + +struct autofs_packet_missing { + struct autofs_packet_hdr hdr; + unsigned long wait_queue_token; + int len; + char name[NAME_MAX+1]; +}; + +#define AUTOFS_IOC_READY _IO(0x93,0x60) +#define AUTOFS_IOC_FAIL _IO(0x93,0x61) +#define AUTOFS_IOC_CATATONIC _IO(0x93,0x62) + +#ifdef __KERNEL__ + +#include +#include + +#if LINUX_VERSION_CODE < 0x20100 + +#include +#define copy_to_user memcpy_tofs +#define copy_from_user memcpy_fromfs + +#else + +#include +#define register_symtab(x) do { } while (0) + +#endif + +#ifndef DPRINTK +#ifdef DEBUG +#define DPRINTK(D) printk D; +#else +#define DPRINTK(D) +#endif +#endif + +#define AUTOFS_SUPER_MAGIC 0x0187 + +/* Structures associated with the root directory hash */ + +#define AUTOFS_HASH_SIZE 67 + +typedef u32 autofs_hash_t; /* Type returned by autofs_hash() */ + +struct autofs_dir_ent { + autofs_hash_t hash; + struct autofs_dir_ent *next; + struct autofs_dir_ent **back; + char *name; + int len; + ino_t ino; + time_t expiry; /* Reserved for use in failed-lookup cache */ +}; + +struct autofs_dirhash { + struct autofs_dir_ent *h[AUTOFS_HASH_SIZE]; +}; + +struct autofs_wait_queue { + unsigned long wait_queue_token; + struct wait_queue *queue; + struct autofs_wait_queue *next; + /* We use the following to see what we are waiting for */ + autofs_hash_t hash; + int len; + char *name; + /* This is for status reporting upon return */ + int status; + int wait_ctr; +}; + +struct autofs_symlink { + int len; + char *data; + time_t mtime; +}; + +#define AUTOFS_MAX_SYMLINKS 256 + +#define AUTOFS_ROOT_INO 1 +#define AUTOFS_FIRST_SYMLINK 2 +#define AUTOFS_FIRST_DIR_INO (AUTOFS_FIRST_SYMLINK+AUTOFS_MAX_SYMLINKS) + +#define AUTOFS_SYMLINK_BITMAP_LEN ((AUTOFS_MAX_SYMLINKS+31)/32) + +#ifndef END_OF_TIME +#define END_OF_TIME ((time_t)((unsigned long)((time_t)(~0UL)) >> 1)) +#endif + +struct autofs_sb_info { + struct file *pipe; + pid_t oz_pgrp; + int catatonic; + ino_t next_dir_ino; + struct autofs_wait_queue *queues; /* Wait queue pointer */ + struct autofs_dirhash dirhash; /* Root directory hash */ + struct autofs_symlink symlink[AUTOFS_MAX_SYMLINKS]; + u32 symlink_bitmap[AUTOFS_SYMLINK_BITMAP_LEN]; +}; + +/* autofs_oz_mode(): do we see the man behind the curtain? */ +static inline int autofs_oz_mode(struct autofs_sb_info *sbi) { + return sbi->catatonic || current->pgrp == sbi->oz_pgrp; +} + +/* Init function */ +int init_autofs_fs(void); + +/* Hash operations */ + +autofs_hash_t autofs_hash(const char *,int); +void autofs_initialize_hash(struct autofs_dirhash *); +struct autofs_dir_ent *autofs_hash_lookup(const struct autofs_dirhash *,autofs_hash_t,const char *,int); +void autofs_hash_insert(struct autofs_dirhash *,struct autofs_dir_ent *); +void autofs_hash_delete(struct autofs_dir_ent *); +struct autofs_dir_ent *autofs_hash_enum(const struct autofs_dirhash *,off_t *); +void autofs_hash_nuke(struct autofs_dirhash *); + +/* Operations structures */ + +extern struct inode_operations autofs_root_inode_operations; +extern struct inode_operations autofs_symlink_inode_operations; +extern struct inode_operations autofs_dir_inode_operations; + +/* Initializing function */ + +struct super_block *autofs_read_super(struct super_block *, void *,int); + +/* Queue management functions */ + +int autofs_wait(struct autofs_sb_info *,autofs_hash_t,const char *,int); +int autofs_wait_release(struct autofs_sb_info *,unsigned long,int); +void autofs_catatonic_mode(struct autofs_sb_info *); + +#ifdef DEBUG +void autofs_say(const char *name, int len); +#else +#define autofs_say(n,l) +#endif + +#endif /* __KERNEL__ */ +#endif /* _LINUX_AUTO_FS_H */ diff -u --recursive --new-file v2.1.30/linux/include/linux/console.h linux/include/linux/console.h --- v2.1.30/linux/include/linux/console.h Sun May 19 21:54:29 1996 +++ linux/include/linux/console.h Thu Mar 27 14:36:39 1997 @@ -16,70 +16,7 @@ #define NPAR 16 -struct vc_data { - unsigned long vc_screenbuf_size; - unsigned short vc_num; /* Console number */ - unsigned short vc_video_erase_char; /* Background erase character */ - unsigned char vc_attr; /* Current attributes */ - unsigned char vc_def_color; /* Default colors */ - unsigned char vc_color; /* Foreground & background */ - unsigned char vc_s_color; /* Saved foreground & background */ - unsigned char vc_ulcolor; /* Colour for underline mode */ - unsigned char vc_halfcolor; /* Colour for half intensity mode */ - unsigned long vc_origin; /* Used for EGA/VGA fast scroll */ - unsigned long vc_scr_end; /* Used for EGA/VGA fast scroll */ - unsigned short *vc_pos; - unsigned long vc_x,vc_y; - unsigned long vc_top,vc_bottom; - unsigned long vc_rows,vc_cols; - unsigned long vc_size_row; - unsigned long vc_state; - unsigned long vc_npar,vc_par[NPAR]; - unsigned short *vc_video_mem_start; - unsigned long vc_video_mem_end; /* End of video RAM (sort of) */ - unsigned long vc_saved_x; - unsigned long vc_saved_y; - /* mode flags */ - unsigned long vc_charset : 1; /* Character set G0 / G1 */ - unsigned long vc_s_charset : 1; /* Saved character set */ - unsigned long vc_disp_ctrl : 1; /* Display chars < 32? */ - unsigned long vc_toggle_meta : 1; /* Toggle high bit? */ - unsigned long vc_decscnm : 1; /* Screen Mode */ - unsigned long vc_decom : 1; /* Origin Mode */ - unsigned long vc_decawm : 1; /* Autowrap Mode */ - unsigned long vc_deccm : 1; /* Cursor Visible */ - unsigned long vc_decim : 1; /* Insert Mode */ - unsigned long vc_deccolm : 1; /* 80/132 Column Mode */ - /* attribute flags */ - unsigned long vc_intensity : 2; /* 0=half-bright, 1=normal, 2=bold */ - unsigned long vc_underline : 1; - unsigned long vc_blink : 1; - unsigned long vc_reverse : 1; - unsigned long vc_s_intensity : 2; /* saved rendition */ - unsigned long vc_s_underline : 1; - unsigned long vc_s_blink : 1; - unsigned long vc_s_reverse : 1; - /* misc */ - unsigned long vc_ques : 1; - unsigned long vc_need_wrap : 1; - unsigned long vc_can_do_color : 1; - unsigned long vc_has_scrolled : 1; /* Info for unblank_screen */ - unsigned long vc_kmalloced : 1; /* kfree_s() needed */ - unsigned long vc_report_mouse : 2; - unsigned char vc_utf : 1; /* Unicode UTF-8 encoding */ - unsigned char vc_utf_count; - unsigned long vc_utf_char; - unsigned long vc_tab_stop[5]; /* Tab stops. 160 columns. */ - unsigned short *vc_translate; - unsigned char vc_G0_charset; - unsigned char vc_G1_charset; - unsigned char vc_saved_G0; - unsigned char vc_saved_G1; - unsigned int vc_bell_pitch; /* Console bell pitch */ - unsigned int vc_bell_duration; /* Console bell duration */ - struct consw *vc_sw; - /* additional information is in vt_kern.h */ -}; +struct vc_data; /* * this is what the terminal answers to a ESC-Z or csi0c query. @@ -120,5 +57,43 @@ #define CM_DRAW (1) #define CM_ERASE (2) #define CM_MOVE (3) + +struct tty_struct; +int tioclinux(struct tty_struct *tty, unsigned long arg); + +/* The interface for /dev/console(s) and printk output */ + +struct console +{ + /* + * This function should not return before the string is written. + */ + void (*write)(const char*, unsigned); + + /* To unblank the console in case of panic */ + void (*unblank)(void); + + /* + * Only the console that was registered last with wait_key != + * NULL will be used. This blocks until there is a character + * to give back, it does not schedule. + */ + void (*wait_key)(void); + + /* + * Return the device to use when opening /dev/console. Only the + * last registered console will do. + */ + int (*device)(void); + + /* + * For a linked list of consoles for multiple output. Any console + * not at the head of the list is used only for output. + */ + struct console *next; +}; + +extern void register_console(struct console *); +extern struct console *console_drivers; #endif /* linux/console.h */ diff -u --recursive --new-file v2.1.30/linux/include/linux/file.h linux/include/linux/file.h --- v2.1.30/linux/include/linux/file.h Tue Aug 20 02:14:31 1996 +++ linux/include/linux/file.h Wed Apr 2 17:43:22 1997 @@ -12,14 +12,17 @@ return file; } -extern void __fput(struct file *, struct inode *); +extern int __fput(struct file *, struct inode *); -extern inline void fput(struct file *file, struct inode *inode) +extern inline int fput(struct file *file, struct inode *inode) { int count = file->f_count-1; + int error = 0; + if (!count) - __fput(file, inode); + error = __fput(file, inode); file->f_count = count; + return error; } #endif diff -u --recursive --new-file v2.1.30/linux/include/linux/fs.h linux/include/linux/fs.h --- v2.1.30/linux/include/linux/fs.h Thu Feb 6 02:53:33 1997 +++ linux/include/linux/fs.h Wed Apr 2 17:51:57 1997 @@ -342,6 +342,7 @@ #define FL_FLOCK 2 #define FL_BROKEN 4 /* broken flock() emulation */ #define FL_ACCESS 8 /* for processes suspended by mandatory locking */ +#define FL_LOCKD 16 /* lock held by rpc.lockd */ struct file_lock { struct file_lock *fl_next; /* singly linked list for this inode */ @@ -349,20 +350,33 @@ struct file_lock *fl_prevlink; /* used to simplify lock removal */ struct file_lock *fl_nextblock; /* circular list of blocked processes */ struct file_lock *fl_prevblock; - struct task_struct *fl_owner; + void *fl_owner; /* usu. the process' task_struct */ + unsigned int fl_pid; struct wait_queue *fl_wait; struct file *fl_file; unsigned char fl_flags; unsigned char fl_type; off_t fl_start; off_t fl_end; + + void (*fl_notify)(struct file_lock *); /* unblock callback */ + + union { + struct nfs_lock_info nfs_fl; + } fl_u; }; +extern struct file_lock *file_lock_table; + #include extern int fcntl_getlk(unsigned int fd, struct flock *l); extern int fcntl_setlk(unsigned int fd, unsigned int cmd, struct flock *l); extern void locks_remove_locks(struct task_struct *task, struct file *filp); +extern struct file_lock *posix_test_lock(struct file *, struct file_lock *); +extern int posix_lock_file(struct file *, struct file_lock *, unsigned int); +extern void posix_block_lock(struct file_lock *, struct file_lock *); +extern void posix_unblock_lock(struct file_lock *); #include @@ -467,11 +481,12 @@ int (*ioctl) (struct inode *, struct file *, unsigned int, unsigned long); int (*mmap) (struct inode *, struct file *, struct vm_area_struct *); int (*open) (struct inode *, struct file *); - void (*release) (struct inode *, struct file *); + int (*release) (struct inode *, struct file *); int (*fsync) (struct inode *, struct file *); int (*fasync) (struct inode *, struct file *, int); int (*check_media_change) (kdev_t dev); int (*revalidate) (kdev_t dev); + int (*lock) (struct inode *, struct file *, int, struct file_lock *); }; struct inode_operations { @@ -493,6 +508,9 @@ void (*truncate) (struct inode *); int (*permission) (struct inode *, int); int (*smap) (struct inode *,int); + int (*updatepage) (struct inode *, struct page *, const char *, + unsigned long, unsigned int, int); + int (*revalidate) (struct inode *); }; struct super_operations { @@ -537,7 +555,7 @@ 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 int blkdev_release (struct inode * inode); extern struct file_operations def_blk_fops; extern struct inode_operations blkdev_inode_operations; @@ -658,6 +676,7 @@ extern int generic_readpage(struct inode *, struct page *); extern int generic_file_mmap(struct inode *, struct file *, struct vm_area_struct *); extern long generic_file_read(struct inode *, struct file *, char *, unsigned long); +extern long generic_file_write(struct inode *, struct file *, const char *, unsigned long); extern void put_super(kdev_t dev); unsigned long generate_cluster(kdev_t dev, int b[], int size); diff -u --recursive --new-file v2.1.30/linux/include/linux/interrupt.h linux/include/linux/interrupt.h --- v2.1.30/linux/include/linux/interrupt.h Thu Mar 27 14:40:10 1997 +++ linux/include/linux/interrupt.h Mon Mar 31 11:10:41 1997 @@ -3,8 +3,10 @@ #define _LINUX_INTERRUPT_H #include + #include #include +#include struct irqaction { void (*handler)(int, void *, struct pt_regs *); @@ -77,15 +79,24 @@ */ extern inline void start_bh_atomic(void) { +#ifdef __SMP__ cli(); atomic_inc(&intr_count); sti(); +#else + intr_count++; + barrier(); +#endif } extern inline void end_bh_atomic(void) { - barrier(); +#ifdef __SMP__ atomic_dec(&intr_count); +#else + barrier(); + intr_count--; +#endif } /* diff -u --recursive --new-file v2.1.30/linux/include/linux/ipx.h linux/include/linux/ipx.h --- v2.1.30/linux/include/linux/ipx.h Thu Dec 12 07:14:38 1996 +++ linux/include/linux/ipx.h Fri Mar 28 10:42:22 1997 @@ -1,6 +1,7 @@ #ifndef _IPX_H_ #define _IPX_H_ #include +#include #define IPX_NODE_LEN 6 #define IPX_MTU 576 diff -u --recursive --new-file v2.1.30/linux/include/linux/keyboard.h linux/include/linux/keyboard.h --- v2.1.30/linux/include/linux/keyboard.h Thu Nov 7 01:25:56 1996 +++ linux/include/linux/keyboard.h Thu Mar 27 14:36:39 1997 @@ -19,10 +19,13 @@ may increase the number of keymaps beyond MAX_NR_OF_USER_KEYMAPS. */ #define MAX_NR_OF_USER_KEYMAPS 256 /* should be at least 7 */ +#ifdef __KERNEL__ extern const int NR_TYPES; extern const int max_vals[]; extern unsigned short *key_maps[MAX_NR_KEYMAPS]; extern unsigned short plain_map[NR_KEYS]; +extern struct wait_queue * keypress_wait; +#endif #define MAX_NR_FUNC 256 /* max nr of strings assigned to keys */ diff -u --recursive --new-file v2.1.30/linux/include/linux/ncp.h linux/include/linux/ncp.h --- v2.1.30/linux/include/linux/ncp.h Thu Feb 6 02:58:49 1997 +++ linux/include/linux/ncp.h Fri Mar 28 10:42:23 1997 @@ -20,78 +20,42 @@ #define NCP_DEALLOC_SLOT_REQUEST (0x5555) struct ncp_request_header { - __u16 type __attribute__ ((packed)); - __u8 sequence __attribute__ ((packed)); - __u8 conn_low __attribute__ ((packed)); - __u8 task __attribute__ ((packed)); - __u8 conn_high __attribute__ ((packed)); - __u8 function __attribute__ ((packed)); - __u8 data[0] __attribute__ ((packed)); + __u16 type __attribute__((packed)); + __u8 sequence __attribute__((packed)); + __u8 conn_low __attribute__((packed)); + __u8 task __attribute__((packed)); + __u8 conn_high __attribute__((packed)); + __u8 function __attribute__((packed)); + __u8 data[0] __attribute__((packed)); }; #define NCP_REPLY (0x3333) #define NCP_POSITIVE_ACK (0x9999) struct ncp_reply_header { - __u16 type __attribute__ ((packed)); - __u8 sequence __attribute__ ((packed)); - __u8 conn_low __attribute__ ((packed)); - __u8 task __attribute__ ((packed)); - __u8 conn_high __attribute__ ((packed)); - __u8 completion_code __attribute__ ((packed)); - __u8 connection_state __attribute__ ((packed)); - __u8 data[0] __attribute__ ((packed)); -}; - - -#define NCP_BINDERY_USER (0x0001) -#define NCP_BINDERY_UGROUP (0x0002) -#define NCP_BINDERY_PQUEUE (0x0003) -#define NCP_BINDERY_FSERVER (0x0004) -#define NCP_BINDERY_NAME_LEN (48) -struct ncp_bindery_object { - __u32 object_id; - __u16 object_type; - __u8 object_name[NCP_BINDERY_NAME_LEN]; - __u8 object_flags; - __u8 object_security; - __u8 object_has_prop; -}; - -struct nw_property { - __u8 value[128]; - __u8 more_flag; - __u8 property_flag; -}; - -struct prop_net_address { - __u32 network __attribute__ ((packed)); - __u8 node[IPX_NODE_LEN] __attribute__ ((packed)); - __u16 port __attribute__ ((packed)); + __u16 type __attribute__((packed)); + __u8 sequence __attribute__((packed)); + __u8 conn_low __attribute__((packed)); + __u8 task __attribute__((packed)); + __u8 conn_high __attribute__((packed)); + __u8 completion_code __attribute__((packed)); + __u8 connection_state __attribute__((packed)); + __u8 data[0] __attribute__((packed)); }; #define NCP_VOLNAME_LEN (16) #define NCP_NUMBER_OF_VOLUMES (64) struct ncp_volume_info { - __u32 total_blocks; - __u32 free_blocks; - __u32 purgeable_blocks; - __u32 not_yet_purgeable_blocks; - __u32 total_dir_entries; - __u32 available_dir_entries; - __u8 sectors_per_block; - char volume_name[NCP_VOLNAME_LEN+1]; -}; - -struct ncp_filesearch_info { - __u8 volume_number; - __u16 directory_id; - __u16 sequence_no; - __u8 access_rights; + __u32 total_blocks; + __u32 free_blocks; + __u32 purgeable_blocks; + __u32 not_yet_purgeable_blocks; + __u32 total_dir_entries; + __u32 available_dir_entries; + __u8 sectors_per_block; + char volume_name[NCP_VOLNAME_LEN + 1]; }; -#define NCP_MAX_FILENAME 14 - /* these define the attribute byte as seen by NCP */ #define aRONLY (ntohl(0x01000000)) #define aHIDDEN (ntohl(0x02000000)) @@ -105,17 +69,6 @@ #define AR_EXCLUSIVE (ntohs(0x2000)) #define NCP_FILE_ID_LEN 6 -struct ncp_file_info { - __u8 file_id[NCP_FILE_ID_LEN]; - char file_name[NCP_MAX_FILENAME+1]; - __u8 file_attributes; - __u8 file_mode; - __u32 file_length; - __u16 creation_date; - __u16 access_date; - __u16 update_date; - __u16 update_time; -}; /* Defines for Name Spaces */ #define NW_NS_DOS 0 @@ -164,34 +117,33 @@ #define AR_OPEN_COMPRESSED 0x0100 #endif -struct nw_info_struct -{ - __u32 spaceAlloc __attribute__ ((packed)); - __u32 attributes __attribute__ ((packed)); - __u16 flags __attribute__ ((packed)); - __u32 dataStreamSize __attribute__ ((packed)); - __u32 totalStreamSize __attribute__ ((packed)); - __u16 numberOfStreams __attribute__ ((packed)); - __u16 creationTime __attribute__ ((packed)); - __u16 creationDate __attribute__ ((packed)); - __u32 creatorID __attribute__ ((packed)); - __u16 modifyTime __attribute__ ((packed)); - __u16 modifyDate __attribute__ ((packed)); - __u32 modifierID __attribute__ ((packed)); - __u16 lastAccessDate __attribute__ ((packed)); - __u16 archiveTime __attribute__ ((packed)); - __u16 archiveDate __attribute__ ((packed)); - __u32 archiverID __attribute__ ((packed)); - __u16 inheritedRightsMask __attribute__ ((packed)); - __u32 dirEntNum __attribute__ ((packed)); - __u32 DosDirNum __attribute__ ((packed)); - __u32 volNumber __attribute__ ((packed)); - __u32 EADataSize __attribute__ ((packed)); - __u32 EAKeyCount __attribute__ ((packed)); - __u32 EAKeySize __attribute__ ((packed)); - __u32 NSCreator __attribute__ ((packed)); - __u8 nameLen __attribute__ ((packed)); - __u8 entryName[256] __attribute__ ((packed)); +struct nw_info_struct { + __u32 spaceAlloc __attribute__((packed)); + __u32 attributes __attribute__((packed)); + __u16 flags __attribute__((packed)); + __u32 dataStreamSize __attribute__((packed)); + __u32 totalStreamSize __attribute__((packed)); + __u16 numberOfStreams __attribute__((packed)); + __u16 creationTime __attribute__((packed)); + __u16 creationDate __attribute__((packed)); + __u32 creatorID __attribute__((packed)); + __u16 modifyTime __attribute__((packed)); + __u16 modifyDate __attribute__((packed)); + __u32 modifierID __attribute__((packed)); + __u16 lastAccessDate __attribute__((packed)); + __u16 archiveTime __attribute__((packed)); + __u16 archiveDate __attribute__((packed)); + __u32 archiverID __attribute__((packed)); + __u16 inheritedRightsMask __attribute__((packed)); + __u32 dirEntNum __attribute__((packed)); + __u32 DosDirNum __attribute__((packed)); + __u32 volNumber __attribute__((packed)); + __u32 EADataSize __attribute__((packed)); + __u32 EAKeyCount __attribute__((packed)); + __u32 EAKeySize __attribute__((packed)); + __u32 NSCreator __attribute__((packed)); + __u8 nameLen __attribute__((packed)); + __u8 entryName[256] __attribute__((packed)); }; /* modify mask - use with MODIFY_DOS_INFO structure */ @@ -209,97 +161,36 @@ #define DM_INHERITED_RIGHTS_MASK (ntohl(0x00100000L)) #define DM_MAXIMUM_SPACE (ntohl(0x00200000L)) -struct nw_modify_dos_info -{ - __u32 attributes __attribute__ ((packed)); - __u16 creationDate __attribute__ ((packed)); - __u16 creationTime __attribute__ ((packed)); - __u32 creatorID __attribute__ ((packed)); - __u16 modifyDate __attribute__ ((packed)); - __u16 modifyTime __attribute__ ((packed)); - __u32 modifierID __attribute__ ((packed)); - __u16 archiveDate __attribute__ ((packed)); - __u16 archiveTime __attribute__ ((packed)); - __u32 archiverID __attribute__ ((packed)); - __u16 lastAccessDate __attribute__ ((packed)); - __u16 inheritanceGrantMask __attribute__ ((packed)); - __u16 inheritanceRevokeMask __attribute__ ((packed)); - __u32 maximumSpace __attribute__ ((packed)); +struct nw_modify_dos_info { + __u32 attributes __attribute__((packed)); + __u16 creationDate __attribute__((packed)); + __u16 creationTime __attribute__((packed)); + __u32 creatorID __attribute__((packed)); + __u16 modifyDate __attribute__((packed)); + __u16 modifyTime __attribute__((packed)); + __u32 modifierID __attribute__((packed)); + __u16 archiveDate __attribute__((packed)); + __u16 archiveTime __attribute__((packed)); + __u32 archiverID __attribute__((packed)); + __u16 lastAccessDate __attribute__((packed)); + __u16 inheritanceGrantMask __attribute__((packed)); + __u16 inheritanceRevokeMask __attribute__((packed)); + __u32 maximumSpace __attribute__((packed)); }; struct nw_file_info { struct nw_info_struct i; - int opened; - int access; - __u32 server_file_handle __attribute__ ((packed)); - __u8 open_create_action __attribute__ ((packed)); - __u8 file_handle[6] __attribute__ ((packed)); + int opened; + int access; + __u32 server_file_handle __attribute__((packed)); + __u8 open_create_action __attribute__((packed)); + __u8 file_handle[6] __attribute__((packed)); }; struct nw_search_sequence { - __u8 volNumber __attribute__ ((packed)); - __u32 dirBase __attribute__ ((packed)); - __u32 sequence __attribute__ ((packed)); + __u8 volNumber __attribute__((packed)); + __u32 dirBase __attribute__((packed)); + __u32 sequence __attribute__((packed)); }; -struct nw_queue_job_entry { - __u16 InUse __attribute__ ((packed)); - __u32 prev __attribute__ ((packed)); - __u32 next __attribute__ ((packed)); - __u32 ClientStation __attribute__ ((packed)); - __u32 ClientTask __attribute__ ((packed)); - __u32 ClientObjectID __attribute__ ((packed)); - __u32 TargetServerID __attribute__ ((packed)); - __u8 TargetExecTime[6] __attribute__ ((packed)); - __u8 JobEntryTime[6] __attribute__ ((packed)); - __u32 JobNumber __attribute__ ((packed)); - __u16 JobType __attribute__ ((packed)); - __u16 JobPosition __attribute__ ((packed)); - __u16 JobControlFlags __attribute__ ((packed)); - __u8 FileNameLen __attribute__ ((packed)); - char JobFileName[13] __attribute__ ((packed)); - __u32 JobFileHandle __attribute__ ((packed)); - __u32 ServerStation __attribute__ ((packed)); - __u32 ServerTaskNumber __attribute__ ((packed)); - __u32 ServerObjectID __attribute__ ((packed)); - char JobTextDescription[50] __attribute__ ((packed)); - char ClientRecordArea[152] __attribute__ ((packed)); -}; - -struct queue_job { - struct nw_queue_job_entry j; - __u8 file_handle[6]; -}; - -#define QJE_OPER_HOLD 0x80 -#define QJE_USER_HOLD 0x40 -#define QJE_ENTRYOPEN 0x20 -#define QJE_SERV_RESTART 0x10 -#define QJE_SERV_AUTO 0x08 - -/* ClientRecordArea for print jobs */ - -#define KEEP_ON 0x0400 -#define NO_FORM_FEED 0x0800 -#define NOTIFICATION 0x1000 -#define DELETE_FILE 0x2000 -#define EXPAND_TABS 0x4000 -#define PRINT_BANNER 0x8000 - -struct print_job_record { - __u8 Version __attribute__ ((packed)); - __u8 TabSize __attribute__ ((packed)); - __u16 Copies __attribute__ ((packed)); - __u16 CtrlFlags __attribute__ ((packed)); - __u16 Lines __attribute__ ((packed)); - __u16 Rows __attribute__ ((packed)); - char FormName[16] __attribute__ ((packed)); - __u8 Reserved[6] __attribute__ ((packed)); - char BannerName[13] __attribute__ ((packed)); - char FnameBanner[13] __attribute__ ((packed)); - char FnameHeader[14] __attribute__ ((packed)); - char Path[80] __attribute__ ((packed)); -}; - - -#endif /* _LINUX_NCP_H */ +#endif /* _LINUX_NCP_H */ diff -u --recursive --new-file v2.1.30/linux/include/linux/ncp_fs.h linux/include/linux/ncp_fs.h --- v2.1.30/linux/include/linux/ncp_fs.h Thu Feb 6 02:58:49 1997 +++ linux/include/linux/ncp_fs.h Wed Apr 2 17:55:28 1997 @@ -21,22 +21,22 @@ */ struct ncp_ioctl_request { - unsigned int function; - unsigned int size; - char *data; + unsigned int function; + unsigned int size; + char *data; }; struct ncp_fs_info { - int version; + int version; struct sockaddr_ipx addr; - uid_t mounted_uid; - int connection; /* Connection number the server assigned us */ - int buffer_size; /* The negotiated buffer size, to be + uid_t mounted_uid; + int connection; /* Connection number the server assigned us */ + int buffer_size; /* The negotiated buffer size, to be used for read/write requests! */ - int volume_number; - __u32 directory_id; -}; + int volume_number; + __u32 directory_id; +}; #define NCP_IOC_NCPREQUEST _IOR('n', 1, struct ncp_ioctl_request) #define NCP_IOC_GETMOUNTUID _IOW('n', 2, uid_t) @@ -53,8 +53,6 @@ #define NCP_MAXPATHLEN 255 #define NCP_MAXNAMELEN 14 -#define NCP_MSG_COMMAND "/sbin/nwmsg" - #ifdef __KERNEL__ /* The readdir cache size controls how many directory entries are @@ -62,7 +60,6 @@ */ #define NCP_READDIR_CACHE_SIZE 64 - #define NCP_MAX_RPC_TIMEOUT (6*HZ) /* Guess, what 0x564c is :-) */ @@ -84,26 +81,25 @@ extern int ncp_current_malloced; static inline void * -ncp_kmalloc(unsigned int size, int priority) + ncp_kmalloc(unsigned int size, int priority) { - ncp_malloced += 1; - ncp_current_malloced += 1; - return kmalloc(size, priority); + ncp_malloced += 1; + ncp_current_malloced += 1; + return kmalloc(size, priority); } -static inline void -ncp_kfree_s(void *obj, int size) +static inline void ncp_kfree_s(void *obj, int size) { - ncp_current_malloced -= 1; - kfree_s(obj, size); + ncp_current_malloced -= 1; + kfree_s(obj, size); } -#else /* DEBUG_NCP_MALLOC */ +#else /* DEBUG_NCP_MALLOC */ #define ncp_kmalloc(s,p) kmalloc(s,p) #define ncp_kfree_s(o,s) kfree_s(o,s) -#endif /* DEBUG_NCP_MALLOC */ +#endif /* DEBUG_NCP_MALLOC */ #if DEBUG_NCP > 0 #define DPRINTK(format, args...) printk(format , ## args) @@ -127,39 +123,35 @@ void ncp_free_inode_info(struct ncp_inode_info *i); void ncp_free_all_inodes(struct ncp_server *server); void ncp_init_root(struct ncp_server *server); -int ncp_conn_logged_in(struct ncp_server *server); +int ncp_conn_logged_in(struct ncp_server *server); void ncp_init_dir_cache(void); void ncp_invalid_dir_cache(struct inode *ino); struct ncp_inode_info *ncp_find_inode(struct inode *inode); ino_t ncp_info_ino(struct ncp_server *server, struct ncp_inode_info *info); void ncp_free_dir_cache(void); -int ncp_date_dos2unix(__u16 time, __u16 date); -void ncp_date_unix2dos(int unix_date, __u16 *time, __u16 *date); +int ncp_date_dos2unix(__u16 time, __u16 date); +void ncp_date_unix2dos(int unix_date, __u16 * time, __u16 * date); /* linux/fs/ncpfs/ioctl.c */ -int ncp_ioctl (struct inode * inode, struct file * filp, - unsigned int cmd, unsigned long arg); +int ncp_ioctl(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg); /* linux/fs/ncpfs/inode.c */ struct super_block *ncp_read_super(struct super_block *sb, - void *raw_data, int silent); + void *raw_data, int silent); extern int init_ncp_fs(void); -void ncp_trigger_message(struct ncp_server *server); /* linux/fs/ncpfs/sock.c */ int ncp_request(struct ncp_server *server, int function); int ncp_connect(struct ncp_server *server); int ncp_disconnect(struct ncp_server *server); -int ncp_catch_watchdog(struct ncp_server *server); -int ncp_dont_catch_watchdog(struct ncp_server *server); -int ncp_catch_message(struct ncp_server *server); void ncp_lock_server(struct ncp_server *server); void ncp_unlock_server(struct ncp_server *server); /* linux/fs/ncpfs/mmap.c */ -int ncp_mmap(struct inode * inode, struct file * file, struct vm_area_struct * vma); +int ncp_mmap(struct inode *inode, struct file *file, struct vm_area_struct *vma); -#endif /* __KERNEL__ */ +#endif /* __KERNEL__ */ -#endif /* _LINUX_NCP_FS_H */ +#endif /* _LINUX_NCP_FS_H */ diff -u --recursive --new-file v2.1.30/linux/include/linux/ncp_fs_i.h linux/include/linux/ncp_fs_i.h --- v2.1.30/linux/include/linux/ncp_fs_i.h Thu Feb 6 02:58:49 1997 +++ linux/include/linux/ncp_fs_i.h Fri Mar 28 10:42:23 1997 @@ -13,21 +13,21 @@ #ifdef __KERNEL__ enum ncp_inode_state { - NCP_INODE_VALID = 19, /* Inode currently in use */ - NCP_INODE_LOOKED_UP, /* directly before iget */ - NCP_INODE_CACHED, /* in a path to an inode which is in use */ - NCP_INODE_INVALID + NCP_INODE_VALID = 19, /* Inode currently in use */ + NCP_INODE_LOOKED_UP, /* directly before iget */ + NCP_INODE_CACHED, /* in a path to an inode which is in use */ + NCP_INODE_INVALID }; /* * ncp fs inode data (in memory only) */ struct ncp_inode_info { - enum ncp_inode_state state; - int nused; /* for directories: - number of references in memory */ - struct ncp_inode_info *dir; - struct ncp_inode_info *next, *prev; + enum ncp_inode_state state; + int nused; /* for directories: + number of references in memory */ + struct ncp_inode_info *dir; + struct ncp_inode_info *next, *prev; struct inode *inode; struct nw_file_info finfo; }; diff -u --recursive --new-file v2.1.30/linux/include/linux/ncp_fs_sb.h linux/include/linux/ncp_fs_sb.h --- v2.1.30/linux/include/linux/ncp_fs_sb.h Thu Feb 6 02:58:49 1997 +++ linux/include/linux/ncp_fs_sb.h Fri Mar 28 10:42:23 1997 @@ -17,60 +17,52 @@ struct ncp_server { - struct ncp_mount_data m; /* Nearly all of the mount data is of - interest for us later, so we store - it completely. */ + struct ncp_mount_data m; /* Nearly all of the mount data is of + interest for us later, so we store + it completely. */ __u8 name_space[NCP_NUMBER_OF_VOLUMES]; struct file *ncp_filp; /* File pointer to ncp socket */ - struct file *wdog_filp; /* File pointer to wdog socket */ - struct file *msg_filp; /* File pointer to message socket */ - void *data_ready; /* The wdog socket gets a new - data_ready callback. We store the - old one for checking purposes and - to reset it on unmounting. */ - - u8 sequence; - u8 task; - u16 connection; /* Remote connection number */ - u8 completion; /* Status message from server */ - u8 conn_status; /* Bit 4 = 1 ==> Server going down, no + u8 sequence; + u8 task; + u16 connection; /* Remote connection number */ + + u8 completion; /* Status message from server */ + u8 conn_status; /* Bit 4 = 1 ==> Server going down, no requests allowed anymore. Bit 0 = 1 ==> Server is down. */ - int buffer_size; /* Negotiated bufsize */ + int buffer_size; /* Negotiated bufsize */ - int reply_size; /* Size of last reply */ + int reply_size; /* Size of last reply */ - int packet_size; + int packet_size; unsigned char *packet; /* Here we prepare requests and receive replies */ - int lock; /* To prevent mismatch in protocols. */ + int lock; /* To prevent mismatch in protocols. */ struct wait_queue *wait; - int current_size; /* for packet preparation */ - int has_subfunction; - int ncp_reply_size; + int current_size; /* for packet preparation */ + int has_subfunction; + int ncp_reply_size; - struct ncp_inode_info root; - char root_path; /* '\0' */ + struct ncp_inode_info root; + char root_path; /* '\0' */ }; -static inline int -ncp_conn_valid(struct ncp_server *server) +static inline int ncp_conn_valid(struct ncp_server *server) { return ((server->conn_status & 0x11) == 0); } -static inline void -ncp_invalidate_conn(struct ncp_server *server) +static inline void ncp_invalidate_conn(struct ncp_server *server) { server->conn_status |= 0x01; } -#endif /* __KERNEL__ */ +#endif /* __KERNEL__ */ #endif diff -u --recursive --new-file v2.1.30/linux/include/linux/ncp_mount.h linux/include/linux/ncp_mount.h --- v2.1.30/linux/include/linux/ncp_mount.h Thu Feb 6 02:58:49 1997 +++ linux/include/linux/ncp_mount.h Fri Mar 28 10:42:23 1997 @@ -13,40 +13,28 @@ #include #include -#define NCP_MOUNT_VERSION 2 - -#define NCP_USERNAME_LEN (NCP_BINDERY_NAME_LEN) -#define NCP_PASSWORD_LEN 20 +#define NCP_MOUNT_VERSION 3 /* Values for flags */ #define NCP_MOUNT_SOFT 0x0001 #define NCP_MOUNT_INTR 0x0002 -/* Gosh... */ -#define NCP_PATH_MAX 1024 - struct ncp_mount_data { int version; unsigned int ncp_fd; /* The socket to the ncp port */ - unsigned int wdog_fd; /* Watchdog packets come here */ - unsigned int message_fd; /* Message notifications come here */ - uid_t mounted_uid; /* Who may umount() this filesystem? */ - - struct sockaddr_ipx serv_addr; - unsigned char server_name[NCP_BINDERY_NAME_LEN]; - - unsigned char mount_point[NCP_PATH_MAX+1]; - unsigned char mounted_vol[NCP_VOLNAME_LEN+1]; + uid_t mounted_uid; /* Who may umount() this filesystem? */ + pid_t wdog_pid; /* Who cares for our watchdog packets? */ + unsigned char mounted_vol[NCP_VOLNAME_LEN + 1]; unsigned int time_out; /* How long should I wait after sending a NCP request? */ - unsigned int retry_count; /* And how often should I retry? */ + unsigned int retry_count; /* And how often should I retry? */ unsigned int flags; - uid_t uid; - gid_t gid; - mode_t file_mode; - mode_t dir_mode; + uid_t uid; + gid_t gid; + mode_t file_mode; + mode_t dir_mode; }; #endif diff -u --recursive --new-file v2.1.30/linux/include/linux/net.h linux/include/linux/net.h --- v2.1.30/linux/include/linux/net.h Thu Mar 27 14:40:10 1997 +++ linux/include/linux/net.h Wed Apr 2 17:43:22 1997 @@ -130,6 +130,7 @@ extern int sock_register(struct net_proto_family *fam); extern int sock_unregister(int family); extern struct socket *sock_alloc(void); +extern int sock_create(int family, int type, int proto, struct socket **); extern void sock_release(struct socket *); extern int sock_sendmsg(struct socket *, struct msghdr *m, int len); extern int sock_recvmsg(struct socket *, struct msghdr *m, int len, int flags); diff -u --recursive --new-file v2.1.30/linux/include/linux/netdevice.h linux/include/linux/netdevice.h --- v2.1.30/linux/include/linux/netdevice.h Thu Mar 27 14:40:10 1997 +++ linux/include/linux/netdevice.h Wed Apr 2 17:53:04 1997 @@ -309,6 +309,8 @@ extern void dev_add_pack(struct packet_type *pt); extern void dev_remove_pack(struct packet_type *pt); extern struct device *dev_get(const char *name); +extern struct device *dev_alloc(const char *name, int *err); +extern int dev_alloc_name(struct device *dev, const char *name); extern int dev_open(struct device *dev); extern int dev_close(struct device *dev); extern int dev_queue_xmit(struct sk_buff *skb); diff -u --recursive --new-file v2.1.30/linux/include/linux/nfs_fs_i.h linux/include/linux/nfs_fs_i.h --- v2.1.30/linux/include/linux/nfs_fs_i.h Fri Jul 19 22:56:51 1996 +++ linux/include/linux/nfs_fs_i.h Wed Apr 2 17:43:22 1997 @@ -34,4 +34,9 @@ unsigned long attrtimeo; }; +struct nfs_lock_info { + u32 state; + unsigned int flags; +}; + #endif diff -u --recursive --new-file v2.1.30/linux/include/linux/notifier.h linux/include/linux/notifier.h --- v2.1.30/linux/include/linux/notifier.h Thu Mar 27 14:40:10 1997 +++ linux/include/linux/notifier.h Thu Mar 27 14:29:43 1997 @@ -13,7 +13,7 @@ struct notifier_block { - int (*notifier_call)(struct notifier_block *this, unsigned long, void *); + int (*notifier_call)(struct notifier_block *self, unsigned long, void *); struct notifier_block *next; int priority; }; diff -u --recursive --new-file v2.1.30/linux/include/linux/pci.h linux/include/linux/pci.h --- v2.1.30/linux/include/linux/pci.h Mon Mar 17 14:54:35 1997 +++ linux/include/linux/pci.h Mon Mar 31 12:52:31 1997 @@ -304,6 +304,7 @@ #define PCI_VENDOR_ID_MATROX 0x102B #define PCI_DEVICE_ID_MATROX_MGA_2 0x0518 #define PCI_DEVICE_ID_MATROX_MIL 0x0519 +#define PCI_DEVICE_ID_MATROX_MYS 0x051A #define PCI_DEVICE_ID_MATROX_MGA_IMP 0x0d10 #define PCI_VENDOR_ID_CT 0x102c diff -u --recursive --new-file v2.1.30/linux/include/linux/personality.h linux/include/linux/personality.h --- v2.1.30/linux/include/linux/personality.h Sun Jan 26 02:07:48 1997 +++ linux/include/linux/personality.h Thu Mar 27 14:29:43 1997 @@ -23,7 +23,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 -u --recursive --new-file v2.1.30/linux/include/linux/skbuff.h linux/include/linux/skbuff.h --- v2.1.30/linux/include/linux/skbuff.h Thu Mar 27 14:40:11 1997 +++ linux/include/linux/skbuff.h Wed Apr 2 17:51:58 1997 @@ -448,7 +448,7 @@ { __label__ here; panic(skb_put_errstr,&&here,len); -here: +here: ; } return tmp; } @@ -462,7 +462,7 @@ { __label__ here; panic(skb_push_errstr, &&here,len); -here: +here: ; } return skb->data; } @@ -538,7 +538,6 @@ #endif -extern struct sk_buff * skb_realloc_headroom(struct sk_buff *skb, int newheadroom); extern struct sk_buff * skb_recv_datagram(struct sock *sk,unsigned flags,int noblock, int *err); extern unsigned int datagram_poll(struct socket *sock, poll_table *wait); extern int skb_copy_datagram(struct sk_buff *from, int offset, char *to,int size); diff -u --recursive --new-file v2.1.30/linux/include/linux/tty.h linux/include/linux/tty.h --- v2.1.30/linux/include/linux/tty.h Tue Mar 4 10:25:26 1997 +++ linux/include/linux/tty.h Wed Apr 2 17:51:57 1997 @@ -280,7 +280,6 @@ extern int fg_console, last_console, want_console; extern int kmsg_redirect; -extern struct wait_queue * keypress_wait; extern unsigned long con_init(unsigned long); @@ -328,14 +327,20 @@ extern int n_tty_ioctl(struct tty_struct * tty, struct file * file, unsigned int cmd, unsigned long arg); +/* serial.c */ + +extern long serial_console_init(long kmem_start, long kmem_end); + /* pcxx.c */ extern int pcxe_open(struct tty_struct *tty, struct file *filp); /* console.c */ -extern int con_open(struct tty_struct * tty, struct file * filp); extern void update_screen(int new_console); + +/* printk.c */ + extern void console_print(const char *); /* vt.c */ diff -u --recursive --new-file v2.1.30/linux/include/net/sock.h linux/include/net/sock.h --- v2.1.30/linux/include/net/sock.h Thu Mar 27 14:40:12 1997 +++ linux/include/net/sock.h Wed Apr 2 17:53:07 1997 @@ -500,6 +500,11 @@ */ struct socket *socket; + + /* + * RPC layer private data + */ + void *user_data; /* * Callbacks diff -u --recursive --new-file v2.1.30/linux/include/scsi/scsi.h linux/include/scsi/scsi.h --- v2.1.30/linux/include/scsi/scsi.h Fri Feb 7 04:34:19 1997 +++ linux/include/scsi/scsi.h Mon Mar 31 13:27:27 1997 @@ -132,6 +132,7 @@ #define TYPE_SCANNER 0x06 #define TYPE_MOD 0x07 /* Magneto-optical disk - * - treated as TYPE_DISK */ +#define TYPE_MEDIUM_CHANGER 0x08 #define TYPE_NO_LUN 0x7f diff -u --recursive --new-file v2.1.30/linux/init/main.c linux/init/main.c --- v2.1.30/linux/init/main.c Thu Mar 27 14:40:12 1997 +++ linux/init/main.c Thu Mar 27 14:36:39 1997 @@ -298,7 +298,9 @@ { "swap=", swap_setup }, { "buff=", buff_setup }, { "panic=", panic_setup }, +#ifdef CONFIG_VT { "no-scroll", no_scroll }, +#endif #ifdef CONFIG_BUGi386 { "no-hlt", no_halt }, { "no387", no_387 }, @@ -1014,17 +1016,9 @@ } #endif -#ifdef __sparc__ - if (serial_console == 1) { - (void) open("/dev/cua0", O_RDWR, 0); - } else if (serial_console == 2) { - (void) open("/dev/cua1", O_RDWR, 0); - } else { -#endif - (void) open("/dev/tty1", O_RDWR, 0); -#ifdef __sparc__ - } -#endif + if (open("/dev/console",O_RDWR,0) < 0) + printk("Unable to open an initial console.\n"); + (void) dup(0); (void) dup(0); diff -u --recursive --new-file v2.1.30/linux/kernel/fork.c linux/kernel/fork.c --- v2.1.30/linux/kernel/fork.c Sun Jan 26 03:40:46 1997 +++ linux/kernel/fork.c Mon Mar 31 12:52:31 1997 @@ -292,7 +292,16 @@ /* ok, now we should be set up.. */ p->swappable = 1; p->exit_signal = clone_flags & CSIGNAL; - p->counter = current->counter >> 1; + + /* + * "share" dynamic priority between parent and child, thus the + * total amount of dynamic priorities in the system doesnt change, + * more scheduling fairness. This is only important in the first + * timeslice, on the long run the scheduling behaviour is unchanged. + */ + current->counter >>= 1; + p->counter = current->counter; + if(p->pid) { wake_up_process(p); /* do this last, just in case */ } else { diff -u --recursive --new-file v2.1.30/linux/kernel/info.c linux/kernel/info.c --- v2.1.30/linux/kernel/info.c Sun Jan 26 02:07:49 1997 +++ linux/kernel/info.c Mon Mar 31 12:52:31 1997 @@ -20,11 +20,10 @@ asmlinkage int sys_sysinfo(struct sysinfo *info) { struct sysinfo val; - int err; - lock_kernel(); memset((char *)&val, 0, sizeof(struct sysinfo)); + lock_kernel(); val.uptime = jiffies / HZ; val.loads[0] = avenrun[0] << (SI_LOAD_SHIFT - FSHIFT); @@ -35,11 +34,9 @@ si_meminfo(&val); si_swapinfo(&val); + unlock_kernel(); if (copy_to_user(info, &val, sizeof(struct sysinfo))) - err = -EFAULT; - else - err = 0; - unlock_kernel(); - return err; + return -EFAULT; + return 0; } diff -u --recursive --new-file v2.1.30/linux/kernel/ksyms.c linux/kernel/ksyms.c --- v2.1.30/linux/kernel/ksyms.c Thu Mar 27 14:40:12 1997 +++ linux/kernel/ksyms.c Wed Apr 2 17:43:23 1997 @@ -49,6 +49,7 @@ #include #include #include +#include #if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_HD) || defined(CONFIG_BLK_DEV_IDE_MODULE) || defined(CONFIG_BLK_DEV_HD_MODULE) extern struct drive_info_struct drive_info; @@ -74,7 +75,7 @@ extern char *get_options(char *str, int *ints); extern void set_device_ro(int dev,int flag); extern struct file_operations * get_blkfops(unsigned int); -extern void blkdev_release(struct inode * inode); +extern int blkdev_release(struct inode * inode); extern void *sys_call_table; @@ -114,6 +115,7 @@ EXPORT_SYMBOL(do_mmap); EXPORT_SYMBOL(do_munmap); EXPORT_SYMBOL(exit_mm); +EXPORT_SYMBOL(exit_files); /* internal kernel memory management */ EXPORT_SYMBOL(__get_free_pages); @@ -132,6 +134,7 @@ /* filesystem internal functions */ EXPORT_SYMBOL(getname); EXPORT_SYMBOL(putname); +EXPORT_SYMBOL(__fput); EXPORT_SYMBOL(__iget); EXPORT_SYMBOL(iput); EXPORT_SYMBOL(namei); @@ -161,8 +164,14 @@ EXPORT_SYMBOL(dcache_add); EXPORT_SYMBOL(add_blkdev_randomness); EXPORT_SYMBOL(generic_file_read); +EXPORT_SYMBOL(generic_file_write); EXPORT_SYMBOL(generic_file_mmap); EXPORT_SYMBOL(generic_readpage); +EXPORT_SYMBOL(file_lock_table); +EXPORT_SYMBOL(posix_lock_file); +EXPORT_SYMBOL(posix_test_lock); +EXPORT_SYMBOL(posix_block_lock); +EXPORT_SYMBOL(posix_unblock_lock); /* device registration */ EXPORT_SYMBOL(register_chrdev); @@ -308,6 +317,7 @@ EXPORT_SYMBOL(unregister_reboot_notifier); EXPORT_SYMBOL(_ctype); EXPORT_SYMBOL(secure_tcp_sequence_number); +EXPORT_SYMBOL(get_random_bytes); /* Signal interfaces */ EXPORT_SYMBOL(send_sig); @@ -352,7 +362,9 @@ /* psaux mouse */ EXPORT_SYMBOL(aux_device_present); +#ifdef CONFIG_VT EXPORT_SYMBOL(kbd_read_mask); +#endif #ifdef CONFIG_BLK_DEV_MD EXPORT_SYMBOL(disk_name); /* for md.c */ diff -u --recursive --new-file v2.1.30/linux/kernel/module.c linux/kernel/module.c --- v2.1.30/linux/kernel/module.c Wed Jan 29 03:40:34 1997 +++ linux/kernel/module.c Fri Mar 28 10:53:02 1997 @@ -65,10 +65,7 @@ kernel_module.nsyms = __stop___ksymtab - __start___ksymtab; #ifdef __alpha__ - { - register unsigned long gp __asm__("$29"); - kernel_module.gp = gp; - } + __asm__("stq $29,%0" : "=m"(kernel_module.gp)); #endif } diff -u --recursive --new-file v2.1.30/linux/kernel/panic.c linux/kernel/panic.c --- v2.1.30/linux/kernel/panic.c Thu Mar 27 14:40:12 1997 +++ linux/kernel/panic.c Thu Mar 27 14:36:39 1997 @@ -17,7 +17,7 @@ #include asmlinkage void sys_sync(void); /* it's really int */ -extern void do_unblank_screen(void); +extern void unblank_console(void); extern int C_A_D; int panic_timeout = 0; @@ -43,7 +43,7 @@ else sys_sync(); - do_unblank_screen(); + unblank_console(); #ifdef __SMP__ smp_message_pass(MSG_ALL_BUT_SELF, MSG_STOP_CPU, 0, 0); diff -u --recursive --new-file v2.1.30/linux/kernel/printk.c linux/kernel/printk.c --- v2.1.30/linux/kernel/printk.c Thu Mar 27 14:40:12 1997 +++ linux/kernel/printk.c Thu Mar 27 14:36:39 1997 @@ -23,6 +23,7 @@ #include #include #include +#include #include @@ -30,8 +31,6 @@ static char buf[1024]; -extern void console_print(const char *); - /* printk's without a loglevel use this.. */ #define DEFAULT_MESSAGE_LOGLEVEL 4 /* KERN_WARNING */ @@ -43,7 +42,7 @@ struct wait_queue * log_wait = NULL; int console_loglevel = DEFAULT_CONSOLE_LOGLEVEL; -static void (*console_print_proc)(const char *) = 0; +struct console *console_drivers = NULL; static char log_buf[LOG_BUF_LEN]; static unsigned long log_start = 0; static unsigned long logged_chars = 0; @@ -209,11 +208,13 @@ if (*p == '\n') break; } - if (msg_level < console_loglevel && console_print_proc) { - char tmp = p[1]; - p[1] = '\0'; - (*console_print_proc)(msg); - p[1] = tmp; + if (msg_level < console_loglevel && console_drivers) { + struct console *c = console_drivers; + while(c) { + if (c->write) + c->write(msg, p - msg + 1); + c = c->next; + } } if (*p == '\n') msg_level = -1; @@ -223,21 +224,43 @@ return i; } +void console_print(const char *s) +{ + struct console *c = console_drivers; + int len = strlen(s); + while(c) { + if (c->write) + c->write(s, len); + c = c->next; + } +} + +void unblank_console(void) +{ + struct console *c = console_drivers; + while(c) { + if (c->unblank) + c->unblank(); + c = c->next; + } +} + /* * The console driver calls this routine during kernel initialization * to register the console printing procedure with printk() and to * print any messages that were printed by the kernel before the * console driver was initialized. */ -void register_console(void (*proc)(const char *)) +void register_console(struct console * console) { - int i,j; + int i,j,len; int p = log_start; char buf[16]; signed char msg_level = -1; char *q; - console_print_proc = proc; + console->next = console_drivers; + console_drivers = console; for (i=0,j=0; i < log_size; i++) { buf[j++] = log_buf[p]; @@ -246,12 +269,14 @@ continue; buf[j] = 0; q = buf; + len = j; if (msg_level < 0) { msg_level = buf[1] - '0'; q = buf + 3; + len -= 3; } if (msg_level < console_loglevel) - (*proc)(q); + console->write(q, len); if (buf[j-1] == '\n') msg_level = -1; j = 0; diff -u --recursive --new-file v2.1.30/linux/kernel/sched.c linux/kernel/sched.c --- v2.1.30/linux/kernel/sched.c Thu Mar 27 14:40:12 1997 +++ linux/kernel/sched.c Mon Mar 31 12:52:31 1997 @@ -1553,11 +1553,11 @@ asmlinkage int sys_sched_yield(void) { - spin_unlock(&scheduler_lock); + spin_lock(&scheduler_lock); spin_lock_irq(&runqueue_lock); move_last_runqueue(current); spin_unlock_irq(&runqueue_lock); - spin_lock(&scheduler_lock); + spin_unlock(&scheduler_lock); need_resched = 1; return 0; } @@ -1629,48 +1629,46 @@ asmlinkage int sys_nanosleep(struct timespec *rqtp, struct timespec *rmtp) { - int error = -EFAULT; struct timespec t; unsigned long expire; - lock_kernel(); if(copy_from_user(&t, rqtp, sizeof(struct timespec))) - goto out; + return -EFAULT; - error = -EINVAL; if (t.tv_nsec >= 1000000000L || t.tv_nsec < 0 || t.tv_sec < 0) - goto out; + return -EINVAL; + if (t.tv_sec == 0 && t.tv_nsec <= 2000000L && - current->policy != SCHED_OTHER) { + current->policy != SCHED_OTHER) + { /* * Short delay requests up to 2 ms will be handled with * high precision by a busy wait for all real-time processes. + * + * Its important on SMP not to do this holding locks. */ udelay((t.tv_nsec + 999) / 1000); - error = 0; - goto out; + return 0; } expire = timespectojiffies(&t) + (t.tv_sec || t.tv_nsec) + jiffies; + lock_kernel(); current->timeout = expire; current->state = TASK_INTERRUPTIBLE; schedule(); + unlock_kernel(); - error = 0; if (expire > jiffies) { if (rmtp) { jiffiestotimespec(expire - jiffies - (expire > jiffies + 1), &t); - error = -EFAULT; if (copy_to_user(rmtp, &t, sizeof(struct timespec))) - goto out; + return -EFAULT; } - error = -EINTR; + return -EINTR; } -out: - unlock_kernel(); - return error; + return 0; } static void show_task(int nr,struct task_struct * p) diff -u --recursive --new-file v2.1.30/linux/kernel/sys.c linux/kernel/sys.c --- v2.1.30/linux/kernel/sys.c Thu Mar 27 14:40:12 1997 +++ linux/kernel/sys.c Mon Mar 31 12:52:31 1997 @@ -893,14 +893,13 @@ gid_t *groups = current->groups; do { if (*groups == grp) - goto out; + break; groups++; i--; } while (i); } return 0; } -out: return 1; } diff -u --recursive --new-file v2.1.30/linux/kernel/sysctl.c linux/kernel/sysctl.c --- v2.1.30/linux/kernel/sysctl.c Mon Mar 17 14:54:35 1997 +++ linux/kernel/sysctl.c Mon Mar 31 12:52:32 1997 @@ -197,25 +197,17 @@ if (nlen == 0 || nlen >= CTL_MAXNAME) return -ENOTDIR; - error = verify_area(VERIFY_READ,name,nlen*sizeof(int)); - if (error) return error; - if (oldval) { + if (oldval) + { int old_len; if (!oldlenp) return -EFAULT; - error = verify_area(VERIFY_WRITE,oldlenp,sizeof(size_t)); - if (error) return error; - get_user(old_len, oldlenp); - error = verify_area(VERIFY_WRITE,oldval,old_len); - if (error) return error; - } - if (newval) { - error = verify_area(VERIFY_READ,newval,newlen); - if (error) return error; + if(get_user(old_len, oldlenp)) + return -EFAULT; } tmp = &root_table_header; do { - context = 0; + context = NULL; error = parse_table(name, nlen, oldval, oldlenp, newval, newlen, tmp->ctl_table, &context); if (context) @@ -232,14 +224,12 @@ struct __sysctl_args tmp; int error; + if(copy_from_user(&tmp, args, sizeof(tmp))) + return -EFAULT; + lock_kernel(); - error = verify_area(VERIFY_READ, args, sizeof(*args)); - if (error) - goto out; - copy_from_user(&tmp, args, sizeof(tmp)); error = do_sysctl(tmp.name, tmp.nlen, tmp.oldval, tmp.oldlenp, tmp.newval, tmp.newlen); -out: unlock_kernel(); return error; } @@ -266,6 +256,7 @@ /* ctl_perm does NOT grant the superuser all rights automatically, because some sysctl variables are readonly even to root. */ + static int test_perm(int mode, int op) { if (!current->euid) @@ -276,6 +267,7 @@ return 0; return -EACCES; } + static inline int ctl_perm(ctl_table *table, int op) { return test_perm(table->mode, op); @@ -293,7 +285,8 @@ for ( ; table->ctl_name; table++) { int n; - get_user(n,name); + if(get_user(n,name)) + return -EFAULT; if (n == table->ctl_name || table->ctl_name == CTL_ANY) { if (table->child) { @@ -353,15 +346,18 @@ if (len) { if (len > table->maxlen) len = table->maxlen; - copy_to_user(oldval, table->data, len); - put_user(len, oldlenp); + if(copy_to_user(oldval, table->data, len)) + return -EFAULT; + if(put_user(len, oldlenp)) + return -EFAULT; } } if (newval && newlen) { len = newlen; if (len > table->maxlen) len = table->maxlen; - copy_from_user(table->data, newval, len); + if(copy_from_user(table->data, newval, len)) + return -EFAULT; } } return 0; @@ -382,7 +378,8 @@ if (newval && newlen) { if (newlen != sizeof (int)) return -EINVAL; - copy_from_user (&level, newval, newlen); + if(copy_from_user (&level, newval, newlen)) + return -EFAULT; if (level < securelevel && current->pid != 1) return -EPERM; } @@ -499,10 +496,6 @@ size_t res; long error; - error = verify_area(write ? VERIFY_READ : VERIFY_WRITE, buf, count); - if (error) - return error; - de = (struct proc_dir_entry*) inode->u.generic_ip; if (!de || !de->data) return -ENOTDIR; @@ -553,14 +546,16 @@ len = 0; p = buffer; while (len < *lenp) { - get_user(c, p++); + if(get_user(c, p++)) + return -EFAULT; if (c == 0 || c == '\n') break; len++; } if (len >= table->maxlen) len = table->maxlen-1; - copy_from_user(table->data, buffer, len); + if(copy_from_user(table->data, buffer, len)) + return -EFAULT; ((char *) table->data)[len] = 0; filp->f_pos += *lenp; } else { @@ -570,9 +565,11 @@ if (len > *lenp) len = *lenp; if (len) - copy_to_user(buffer, table->data, len); + if(copy_to_user(buffer, table->data, len)) + return -EFAULT; if (len < *lenp) { - put_user('\n', ((char *) buffer) + len); + if(put_user('\n', ((char *) buffer) + len)) + return -EFAULT; len++; } *lenp = len; @@ -602,7 +599,8 @@ if (write) { while (left) { char c; - get_user(c,(char *) buffer); + if(get_user(c,(char *) buffer)) + return -EFAULT; if (!isspace(c)) break; left--; @@ -614,7 +612,8 @@ len = left; if (len > TMPBUFLEN-1) len = TMPBUFLEN-1; - copy_from_user(buf, buffer, len); + if(copy_from_user(buf, buffer, len)) + return -EFAULT; buf[len] = 0; p = buf; if (*p == '-' && left > 1) { @@ -640,21 +639,24 @@ len = strlen(buf); if (len > left) len = left; - copy_to_user(buffer, buf, len); + if(copy_to_user(buffer, buf, len)) + return -EFAULT; left -= len; buffer += len; } } if (!write && !first && left) { - put_user('\n', (char *) buffer); + if(put_user('\n', (char *) buffer)) + return -EFAULT; left--, buffer++; } if (write) { p = (char *) buffer; while (left) { char c; - get_user(c, p++); + if(get_user(c, p++)) + return -EFAULT; if (!isspace(c)) break; left--; @@ -690,7 +692,8 @@ if (write) { while (left) { char c; - get_user(c, (char *) buffer); + if(get_user(c, (char *) buffer)) + return -EFAULT; if (!isspace(c)) break; left--; @@ -702,7 +705,8 @@ len = left; if (len > TMPBUFLEN-1) len = TMPBUFLEN-1; - copy_from_user(buf, buffer, len); + if(copy_from_user(buf, buffer, len)) + return -EFAULT; buf[len] = 0; p = buf; if (*p == '-' && left > 1) { @@ -733,21 +737,24 @@ len = strlen(buf); if (len > left) len = left; - copy_to_user(buffer, buf, len); + if(copy_to_user(buffer, buf, len)) + return -EFAULT; left -= len; buffer += len; } } if (!write && !first && left) { - put_user('\n', (char *) buffer); + if(put_user('\n', (char *) buffer)) + return -EFAULT; left--, buffer++; } if (write) { p = (char *) buffer; while (left) { char c; - get_user(c, p++); + if(get_user(c, p++)) + return -EFAULT; if (!isspace(c)) break; left--; @@ -798,22 +805,27 @@ return -ENOTDIR; if (oldval && oldlenp) { - get_user(len, oldlenp); + if(get_user(len, oldlenp)) + return -EFAULT; if (len) { l = strlen(table->data); if (len > l) len = l; if (len >= table->maxlen) len = table->maxlen; - copy_to_user(oldval, table->data, len); - put_user(0, ((char *) oldval) + len); - put_user(len, oldlenp); + if(copy_to_user(oldval, table->data, len)) + return -EFAULT; + if(put_user(0, ((char *) oldval) + len)) + return -EFAULT; + if(put_user(len, oldlenp)) + return -EFAULT; } } if (newval && newlen) { len = newlen; if (len > table->maxlen) len = table->maxlen; - copy_from_user(table->data, newval, len); + if(copy_from_user(table->data, newval, len)) + return -EFAULT; if (len == table->maxlen) len--; ((char *) table->data)[len] = 0; @@ -870,14 +882,16 @@ return -EINVAL; if (oldval) { int old_l; - get_user(old_l, oldlenp); + if(get_user(old_l, oldlenp)) + return -EFAULT; if (l > old_l) return -ENOMEM; - put_user(l, oldlenp); - copy_to_user(oldval, data, l); + if(put_user(l, oldlenp) || copy_to_user(oldval, data, l)) + return -EFAULT; } if (newval) { - copy_from_user(data, newval, newlen); + if(copy_from_user(data, newval, newlen)) + return -EFAULT; data[newlen] = 0; } return 0; @@ -893,14 +907,16 @@ return -EINVAL; if (oldval) { int old_l; - get_user(old_l, oldlenp); + if(get_user(old_l, oldlenp)) + return -EFAULT; if (old_l < sizeof(int)) return -ENOMEM; - put_user(sizeof(int), oldlenp); - copy_to_user(oldval, data, sizeof(int)); + if(put_user(sizeof(int), oldlenp)||copy_to_user(oldval, data, sizeof(int))) + return -EFAULT; } if (newval) - copy_from_user(data, newval, sizeof(int)); + if(copy_from_user(data, newval, sizeof(int))) + return -EFAULT; return 0; } @@ -914,14 +930,16 @@ return -EINVAL; if (oldval) { int old_l; - get_user(old_l, oldlenp); + if(get_user(old_l, oldlenp)) + return -EFAULT; if (old_l < len) return -ENOMEM; - put_user(len, oldlenp); - copy_to_user(oldval, data, len); + if(put_user(len, oldlenp) || copy_to_user(oldval, data, len)) + return -EFAULT; } if (newval) - copy_from_user(data, newval, len); + if(copy_from_user(data, newval, len)) + return -EFAULT; return 0; } diff -u --recursive --new-file v2.1.30/linux/kernel/time.c linux/kernel/time.c --- v2.1.30/linux/kernel/time.c Thu Mar 27 14:40:12 1997 +++ linux/kernel/time.c Mon Mar 31 12:52:32 1997 @@ -156,32 +156,33 @@ static int firsttime = 1; struct timeval new_tv; struct timezone new_tz; - int err = -EPERM; - lock_kernel(); if (!suser()) - goto out; - err = -EFAULT; + return -EPERM; + if (tv) { if (copy_from_user(&new_tv, tv, sizeof(*tv))) - goto out; + return -EFAULT; } if (tz) { if (copy_from_user(&new_tz, tz, sizeof(*tz))) - goto out; + return -EFAULT; + lock_kernel(); sys_tz = new_tz; if (firsttime) { firsttime = 0; if (!tv) warp_clock(); } + unlock_kernel(); } if (tv) + { + lock_kernel(); do_settimeofday(&new_tv); - err = 0; -out: - unlock_kernel(); - return err; + unlock_kernel(); + } + return 0; } long pps_offset = 0; /* pps time offset (us) */ @@ -208,33 +209,32 @@ asmlinkage int sys_adjtimex(struct timex *txc_p) { long ltemp, mtemp, save_adjust; - int error = -EFAULT; struct timex txc; /* Local copy of parameter */ - lock_kernel(); /* Copy the user data space into the kernel copy * structure. But bear in mind that the structures * may change */ if(copy_from_user(&txc, txc_p, sizeof(struct timex))) - goto out; + return -EFAULT; /* In order to modify anything, you gotta be super-user! */ - error = -EPERM; if (txc.modes && !suser()) - goto out; - + return -EPERM; + /* Now we validate the data before disabling interrupts */ - error = -EINVAL; + if (txc.modes != ADJ_OFFSET_SINGLESHOT && (txc.modes & ADJ_OFFSET)) /* adjustment Offset limited to +- .512 seconds */ - if (txc.offset <= - MAXPHASE || txc.offset >= MAXPHASE ) - goto out; + if (txc.offset <= - MAXPHASE || txc.offset >= MAXPHASE ) + return -EINVAL; /* if the quartz is off by more than 10% something is VERY wrong ! */ if (txc.modes & ADJ_TICK) - if (txc.tick < 900000/HZ || txc.tick > 1100000/HZ) - goto out; + if (txc.tick < 900000/HZ || txc.tick > 1100000/HZ) + return -EINVAL; + + lock_kernel(); cli(); @@ -351,9 +351,6 @@ txc.stbcnt = pps_stbcnt; sti(); - - error = copy_to_user(txc_p, &txc, sizeof(struct timex)) ? -EFAULT : time_state; -out: unlock_kernel(); - return error; + return copy_to_user(txc_p, &txc, sizeof(struct timex)) ? -EFAULT : time_state; } diff -u --recursive --new-file v2.1.30/linux/mm/filemap.c linux/mm/filemap.c --- v2.1.30/linux/mm/filemap.c Thu Mar 27 14:40:12 1997 +++ linux/mm/filemap.c Wed Apr 2 17:43:23 1997 @@ -1275,3 +1275,118 @@ unlock_kernel(); return error; } + +/* + * Write to a file through the page cache. This is mainly for the + * benefit of NFS and possibly other network-based file systems. + * + * We currently put everything into the page cache prior to writing it. + * This is not a problem when writing full pages. With partial pages, + * however, we first have to read the data into the cache, then + * dirty the page, and finally schedule it for writing. Alternatively, we + * could write-through just the portion of data that would go into that + * page, but that would kill performance for applications that write data + * line by line, and it's prone to race conditions. + * + * Note that this routine doesn't try to keep track of dirty pages. Each + * file system has to do this all by itself, unfortunately. + * okir@monad.swb.de + */ +long +generic_file_write(struct inode *inode, struct file *file, const char *buf, unsigned long count) +{ + struct page *page, **hash; + unsigned long page_cache = 0; + unsigned long ppos, offset; + unsigned int bytes, written; + unsigned long pos; + int status, sync, didread = 0; + + if (!inode->i_op || !inode->i_op->updatepage) + return -EIO; + + sync = file->f_flags & O_SYNC; + pos = file->f_pos; + written = 0; + status = 0; + + if (file->f_flags & O_APPEND) + pos = inode->i_size; + + while (count) { + /* + * Try to find the page in the cache. If it isn't there, + * allocate a free page. + */ + offset = (pos & ~PAGE_MASK); + ppos = pos & PAGE_MASK; + + if ((bytes = PAGE_SIZE - offset) > count) + bytes = count; + + hash = page_hash(inode, ppos); + if (!(page = __find_page(inode, ppos, *hash))) { + if (!page_cache) { + page_cache = __get_free_page(GFP_KERNEL); + if (!page_cache) { + status = -ENOMEM; + break; + } + continue; + } + page = mem_map + MAP_NR(page_cache); + add_to_page_cache(page, inode, ppos, hash); + page_cache = 0; + } + +lockit: + while (set_bit(PG_locked, &page->flags)) + wait_on_page(page); + + /* + * If the page is not uptodate, and we're writing less + * than a full page of data, we may have to read it first. + * However, don't bother with reading the page when it's + * after the current end of file. + */ + if (!PageUptodate(page)) { + /* Already tried to read it twice... too bad */ + if (didread > 1) { + status = -EIO; + break; + } + if (bytes < PAGE_SIZE && ppos < inode->i_size) { + /* readpage implicitly unlocks the page */ + status = inode->i_op->readpage(inode, page); + if (status < 0) + break; + didread++; + goto lockit; + } + set_bit(PG_uptodate, &page->flags); + } + didread = 0; + + /* Alright, the page is there, and we've locked it. Now + * update it. */ + status = inode->i_op->updatepage(inode, page, buf, + offset, bytes, sync); + free_page(page_address(page)); + if (status < 0) + break; + + written += status; + count -= status; + pos += status; + buf += status; + } + file->f_pos = pos; + if (pos > inode->i_size) + inode->i_size = pos; + + if (page_cache) + free_page(page_cache); + if (written) + return written; + return status; +} diff -u --recursive --new-file v2.1.30/linux/net/802/fddi.c linux/net/802/fddi.c --- v2.1.30/linux/net/802/fddi.c Thu Feb 27 10:57:32 1997 +++ linux/net/802/fddi.c Mon Mar 31 12:52:32 1997 @@ -132,7 +132,7 @@ if(fddi->hdr.llc_8022_1.dsap==0xe0) { skb_pull(skb, FDDI_K_8022_HLEN-3); - type=htons(ETH_P_8022); + type=htons(ETH_P_802_2); } else { diff -u --recursive --new-file v2.1.30/linux/net/appletalk/ddp.c linux/net/appletalk/ddp.c --- v2.1.30/linux/net/appletalk/ddp.c Thu Mar 27 14:40:13 1997 +++ linux/net/appletalk/ddp.c Mon Mar 31 12:52:32 1997 @@ -259,6 +259,7 @@ else iface = &tmp->next; } + MOD_DEC_USE_COUNT; } static struct atalk_iface *atif_add_device(struct device *dev, struct at_addr *sa) @@ -277,6 +278,7 @@ iface->next=atalk_iface_list; atalk_iface_list=iface; restore_flags(flags); + MOD_INC_USE_COUNT; return iface; } @@ -705,6 +707,8 @@ else { atif=atif_add_device(dev, &sa->sat_addr); + if (atif == NULL) + return -ENOMEM; } atif->nets= *nr; diff -u --recursive --new-file v2.1.30/linux/net/core/dev.c linux/net/core/dev.c --- v2.1.30/linux/net/core/dev.c Sun Feb 2 05:18:49 1997 +++ linux/net/core/dev.c Mon Mar 31 12:52:32 1997 @@ -250,7 +250,46 @@ } return(NULL); } - + +/* + * Passed a format string - eg "lt%d" it will try and find a suitable + * id. Not efficient for many devices, not called a lot.. + */ + +int dev_alloc_name(struct device *dev, const char *name) +{ + int i; + /* + * If you need over 100 please also fix the algorithm... + */ + for(i=0;i<100;i++) + { + sprintf(dev->name,name,i); + if(dev_get(dev->name)==NULL) + return i; + } + return -ENFILE; /* Over 100 of the things .. bail out! */ +} + +struct device *dev_alloc(const char *name, int *err) +{ + struct device *dev=kmalloc(sizeof(struct device)+16, GFP_KERNEL); + if(dev==NULL) + { + *err=-ENOBUFS; + return NULL; + } + dev->name=(char *)(dev+1); /* Name string space */ + *err=dev_alloc_name(dev,name); + if(*err<0) + { + kfree(dev); + return NULL; + } + return dev; +} + + /* * Find and possibly load an interface. */ @@ -560,7 +599,7 @@ } } else - printk("%s: !skb->arp & !rebuild_header!\n", dev->name); + printk(KERN_DEBUG "%s: !skb->arp & !rebuild_header!\n", dev->name); } /* @@ -592,7 +631,7 @@ skb_pull(newskb, newskb->nh.raw - newskb->data); newskb->ip_summed = CHECKSUM_UNNECESSARY; if (newskb->dst==NULL) - printk("BUG: packet without dst looped back 1\n"); + printk(KERN_DEBUG "BUG: packet without dst looped back 1\n"); netif_rx(newskb); } @@ -880,7 +919,7 @@ */ if (net_alias_is(dev)) { - printk("net alias %s transmits\n", dev->name); + printk(KERN_DEBUG "net alias %s transmits\n", dev->name); return; } @@ -1010,7 +1049,7 @@ int size; if (stats) - size = sprintf(buffer, "%6s:%8ld %7ld %4ld %4ld %4ld %4ld %8ld %8ld %4ld %4ld %4ld %5ld %4ld\n", + size = sprintf(buffer, "%6s:%8lu %7lu %4lu %4lu %4lu %4lu %8lu %8lu %4lu %4lu %4lu %5lu %4lu\n", dev->name, stats->rx_bytes, stats->rx_packets, stats->rx_errors, diff -u --recursive --new-file v2.1.30/linux/net/core/sock.c linux/net/core/sock.c --- v2.1.30/linux/net/core/sock.c Thu Mar 27 14:40:15 1997 +++ linux/net/core/sock.c Wed Apr 2 17:43:23 1997 @@ -322,9 +322,15 @@ char *optval, int *optlen) { struct sock *sk = sock->sk; - int val; - struct linger ling; - int len; + + union + { + int val; + struct linger ling; + struct timeval tm; + } v; + + int lv=sizeof(int),len; if(get_user(len,optlen)) return -EFAULT; @@ -332,119 +338,110 @@ switch(optname) { case SO_DEBUG: - val = sk->debug; + v.val = sk->debug; break; case SO_DONTROUTE: - val = sk->localroute; + v.val = sk->localroute; break; case SO_BROADCAST: - val= sk->broadcast; + v.val= sk->broadcast; break; case SO_SNDBUF: - val=sk->sndbuf; + v.val=sk->sndbuf; break; case SO_RCVBUF: - val =sk->rcvbuf; + v.val =sk->rcvbuf; break; case SO_REUSEADDR: - val = sk->reuse; + v.val = sk->reuse; break; case SO_KEEPALIVE: - val = sk->keepopen; + v.val = sk->keepopen; break; case SO_TYPE: - val = sk->type; + v.val = sk->type; break; case SO_ERROR: - val = -sock_error(sk); - if(val==0) - val=xchg(&sk->err_soft,0); + v.val = -sock_error(sk); + if(v.val==0) + v.val=xchg(&sk->err_soft,0); break; case SO_OOBINLINE: - val = sk->urginline; + v.val = sk->urginline; break; case SO_NO_CHECK: - val = sk->no_check; + v.val = sk->no_check; break; case SO_PRIORITY: - val = sk->priority; + v.val = sk->priority; break; case SO_LINGER: - { - len=min(len,sizeof(ling)); - if (put_user(len, optlen)) - return -EFAULT; - ling.l_onoff=sk->linger; - ling.l_linger=sk->lingertime; - if (copy_to_user(optval,&ling,len)) - return -EFAULT; - return 0; - } - + lv=sizeof(v.ling); + v.ling.l_onoff=sk->linger; + v.ling.l_linger=sk->lingertime; + break; + case SO_BSDCOMPAT: - val = sk->bsdism; + v.val = sk->bsdism; break; case SO_RCVTIMEO: case SO_SNDTIMEO: - { - static struct timeval tm={0,0}; - len=min(len, sizeof(struct timeval)); - if(put_user(len,optlen)) - return -EFAULT; - if(copy_to_user(optval,&tm,len)) - return -EFAULT; - return 0; - } + lv=sizeof(struct timeval); + v.tm.tv_sec=0; + v.tm.tv_usec=0; + break; + case SO_RCVLOWAT: case SO_SNDLOWAT: - val=1; + v.val=1; case SO_PASSCRED: - val = sock->passcred; + v.val = sock->passcred; break; case SO_PEERCRED: - len=min(len, sizeof(sk->peercred)); - if(put_user(len, optlen)) - return -EFAULT; + lv=sizeof(sk->peercred); + len=min(len, lv); if(copy_to_user((void*)optval, &sk->peercred, len)) return -EFAULT; - return 0; + goto lenout; + +#ifdef CONFIG_NET_SECURITY case SO_SECURITY_AUTHENTICATION: - val = sk->authentication; + v.val = sk->authentication; break; case SO_SECURITY_ENCRYPTION_TRANSPORT: - val = sk->encryption; + v.val = sk->encryption; break; case SO_SECURITY_ENCRYPTION_NETWORK: - val = sk->encrypt_net; + v.val = sk->encrypt_net; break; - +#endif default: return(-ENOPROTOOPT); } - len=min(len,sizeof(int)); + len=min(len,lv); + if(copy_to_user(optval,&v,len)) + return -EFAULT; +lenout: if(put_user(len, optlen)) return -EFAULT; - if(copy_to_user(optval,&val,len)) - return -EFAULT; - return 0; } @@ -487,7 +484,7 @@ #endif #if 1 if (!sk) { - printk("sock_wfree: sk==NULL\n"); + printk(KERN_DEBUG "sock_wfree: sk==NULL\n"); return; } #endif @@ -505,7 +502,7 @@ #endif #if 1 if (!sk) { - printk("sock_rfree: sk==NULL\n"); + printk(KERN_DEBUG "sock_rfree: sk==NULL\n"); return; } #endif @@ -581,17 +578,12 @@ struct sk_buff *sock_alloc_send_skb(struct sock *sk, unsigned long size, unsigned long fallback, int noblock, int *errcode) { struct sk_buff *skb; - int err; do { if(sk->err!=0) { - cli(); - err= -sk->err; - sk->err=0; - sti(); - *errcode=err; + *errcode=xchg(&sk->err,0); return NULL; } diff -u --recursive --new-file v2.1.30/linux/net/ipv4/af_inet.c linux/net/ipv4/af_inet.c --- v2.1.30/linux/net/ipv4/af_inet.c Tue Mar 4 10:25:26 1997 +++ linux/net/ipv4/af_inet.c Mon Mar 31 12:52:32 1997 @@ -183,7 +183,7 @@ * [PR] */ - printk("Socket destroy delayed (r=%d w=%d)\n", + printk(KERN_DEBUG "Socket destroy delayed (r=%d w=%d)\n", sk->rmem_alloc, sk->wmem_alloc); sk->destroy = 1; @@ -1067,7 +1067,7 @@ struct sk_buff *dummy_skb; struct inet_protocol *p; - printk("Swansea University Computer Society TCP/IP for NET3.037\n"); + printk(KERN_INFO "Swansea University Computer Society TCP/IP for NET3.037\n"); if (sizeof(struct inet_skb_parm) > sizeof(dummy_skb->cb)) { @@ -1087,7 +1087,7 @@ * Add all the protocols. */ - printk("IP Protocols: "); + printk(KERN_INFO "IP Protocols: "); for(p = inet_protocol_base; p != NULL;) { struct inet_protocol *tmp = (struct inet_protocol *) p->next; diff -u --recursive --new-file v2.1.30/linux/net/ipv4/arp.c linux/net/ipv4/arp.c --- v2.1.30/linux/net/ipv4/arp.c Thu Mar 27 14:40:15 1997 +++ linux/net/ipv4/arp.c Mon Mar 31 12:52:32 1997 @@ -348,7 +348,7 @@ return; } -static void __inline__ arp_free(struct arp_table **entryp) +static void arp_free(struct arp_table **entryp) { struct arp_table *entry = *entryp; *entryp = entry->u.next; @@ -802,7 +802,7 @@ if (how > 1 && arp_unres_size >= ARP_MAX_UNRES) { arp_unres_expire(); if (arp_unres_size >= ARP_MAX_UNRES) { - printk("arp_unres_size=%d\n", arp_unres_size); + printk(KERN_DEBUG "arp_unres_size=%d\n", arp_unres_size); return NULL; } } @@ -1817,16 +1817,6 @@ if (err) return -EFAULT; break; - case OLD_SIOCDARP: - case OLD_SIOCSARP: - if (!suser()) - return -EPERM; - case OLD_SIOCGARP: - err = copy_from_user(&r, arg, sizeof(struct arpreq_old)); - if (err) - return -EFAULT; - memset(&r.arp_dev, 0, sizeof(r.arp_dev)); - break; default: return -EINVAL; } @@ -1857,46 +1847,10 @@ return arp_req_delete(&r, dev); case SIOCSARP: return arp_req_set(&r, dev); - case OLD_SIOCDARP: - /* old SIOCDARP destroys both - * normal and proxy mappings - */ - r.arp_flags &= ~ATF_PUBL; - err = arp_req_delete(&r, dev); - r.arp_flags |= ATF_PUBL; - if (!err) - arp_req_delete(&r, dev); - else - err = arp_req_delete(&r, dev); - return err; - case OLD_SIOCSARP: - err = arp_req_set(&r, dev); - /* old SIOCSARP works so funny, - * that its behaviour can be emulated - * only approximately 8). - * It should work. --ANK - */ - if (r.arp_flags & ATF_PUBL) - { - r.arp_flags &= ~ATF_PUBL; - arp_req_delete(&r, dev); - } - return err; case SIOCGARP: err = arp_req_get(&r, dev); if (!err) err = copy_to_user(arg, &r, sizeof(r)); - return err; - case OLD_SIOCGARP: - r.arp_flags &= ~ATF_PUBL; - err = arp_req_get(&r, dev); - if (err < 0) - { - r.arp_flags |= ATF_PUBL; - err = arp_req_get(&r, dev); - } - if (!err) - err = copy_to_user(arg, &r, sizeof(struct arpreq_old)); return err; } /*NOTREACHED*/ diff -u --recursive --new-file v2.1.30/linux/net/ipv4/fib.c linux/net/ipv4/fib.c --- v2.1.30/linux/net/ipv4/fib.c Sun Feb 2 05:18:49 1997 +++ linux/net/ipv4/fib.c Mon Mar 31 12:52:32 1997 @@ -1600,7 +1600,7 @@ } else { u32 mask = ((struct sockaddr_in*)&r.rt_genmask)->sin_addr.s_addr; if (r.rt_genmask.sa_family != AF_INET) { - printk(KERN_WARNING "%s forgot to specify route netmask.\n", current->comm); + printk(KERN_DEBUG "%s forgot to specify route netmask.\n", current->comm); if (r.rt_genmask.sa_family) return -EAFNOSUPPORT; } diff -u --recursive --new-file v2.1.30/linux/net/ipv4/igmp.c linux/net/ipv4/igmp.c --- v2.1.30/linux/net/ipv4/igmp.c Thu Feb 27 10:57:32 1997 +++ linux/net/ipv4/igmp.c Mon Mar 31 12:52:32 1997 @@ -210,7 +210,7 @@ im->tm_running=0; } else - printk(KERN_ERR "igmp_stop_timer() called with timer not running by %p\n",__builtin_return_address(0)); + printk(KERN_DEBUG "igmp_stop_timer() called with timer not running by %p\n",__builtin_return_address(0)); } extern __inline__ unsigned int random(void) diff -u --recursive --new-file v2.1.30/linux/net/ipv4/ip_forward.c linux/net/ipv4/ip_forward.c --- v2.1.30/linux/net/ipv4/ip_forward.c Thu Mar 27 14:40:15 1997 +++ linux/net/ipv4/ip_forward.c Mon Mar 31 12:52:32 1997 @@ -218,7 +218,7 @@ kfree_skb(skb, FREE_WRITE); if (skb2 == NULL) { - NETDEBUG(printk("\nIP: No memory available for IP forward\n")); + NETDEBUG(printk(KERN_ERR "\nIP: No memory available for IP forward\n")); return -1; } skb = skb2; diff -u --recursive --new-file v2.1.30/linux/net/ipv4/ip_fragment.c linux/net/ipv4/ip_fragment.c --- v2.1.30/linux/net/ipv4/ip_fragment.c Thu Mar 27 14:40:15 1997 +++ linux/net/ipv4/ip_fragment.c Mon Mar 31 12:52:32 1997 @@ -87,7 +87,7 @@ fp = (struct ipfrag *) frag_kmalloc(sizeof(struct ipfrag), GFP_ATOMIC); if (fp == NULL) { - NETDEBUG(printk("IP: frag_create: no memory left !\n")); + NETDEBUG(printk(KERN_ERR "IP: frag_create: no memory left !\n")); return(NULL); } memset(fp, 0, sizeof(struct ipfrag)); @@ -249,7 +249,7 @@ qp = (struct ipq *) frag_kmalloc(sizeof(struct ipq), GFP_ATOMIC); if (qp == NULL) { - NETDEBUG(printk("IP: create: no memory left !\n")); + NETDEBUG(printk(KERN_ERR "IP: create: no memory left !\n")); return(NULL); } memset(qp, 0, sizeof(struct ipq)); @@ -262,7 +262,7 @@ qp->iph = (struct iphdr *) frag_kmalloc(64 + 8, GFP_ATOMIC); if (qp->iph == NULL) { - NETDEBUG(printk("IP: create: no memory left !\n")); + NETDEBUG(printk(KERN_ERR "IP: create: no memory left !\n")); frag_kfree_s(qp, sizeof(struct ipq)); return(NULL); } @@ -343,7 +343,7 @@ if(len>65535) { - printk("Oversized IP packet from %s.\n", in_ntoa(qp->iph->saddr)); + printk(KERN_INFO "Oversized IP packet from %s.\n", in_ntoa(qp->iph->saddr)); ip_statistics.IpReasmFails++; ip_free(qp); return NULL; @@ -352,7 +352,7 @@ if ((skb = dev_alloc_skb(len)) == NULL) { ip_statistics.IpReasmFails++; - NETDEBUG(printk("IP: queue_glue: no memory for gluing queue %p\n", qp)); + NETDEBUG(printk(KERN_ERR "IP: queue_glue: no memory for gluing queue %p\n", qp)); ip_free(qp); return(NULL); } @@ -373,7 +373,7 @@ { if(count+fp->len > skb->len) { - NETDEBUG(printk("Invalid fragment list: Fragment over size.\n")); + NETDEBUG(printk(KERN_ERR "Invalid fragment list: Fragment over size.\n")); ip_free(qp); kfree_skb(skb,FREE_WRITE); ip_statistics.IpReasmFails++; @@ -485,7 +485,7 @@ if(ntohs(iph->tot_len)+(int)offset>65535) { - printk("Oversized packet received from %s\n",in_ntoa(iph->saddr)); + printk(KERN_INFO "Oversized packet received from %s\n",in_ntoa(iph->saddr)); frag_kfree_skb(skb, FREE_READ); ip_statistics.IpReasmFails++; return NULL; diff -u --recursive --new-file v2.1.30/linux/net/ipv4/ip_masq.c linux/net/ipv4/ip_masq.c --- v2.1.30/linux/net/ipv4/ip_masq.c Fri Dec 27 02:04:49 1996 +++ linux/net/ipv4/ip_masq.c Mon Mar 31 12:52:32 1997 @@ -122,7 +122,7 @@ unsigned hash; if (ms->flags & IP_MASQ_F_HASHED) { - printk("ip_masq_hash(): request for already hashed\n"); + printk(KERN_INFO "ip_masq_hash(): request for already hashed\n"); return 0; } /* @@ -155,7 +155,7 @@ unsigned hash; struct ip_masq ** ms_p; if (!(ms->flags & IP_MASQ_F_HASHED)) { - printk("ip_masq_unhash(): request for unhash flagged\n"); + printk(KERN_INFO "ip_masq_unhash(): request for unhash flagged\n"); return 0; } /* @@ -349,14 +349,14 @@ if (*free_ports_p == 0) { if (++n_fails < 5) - printk("ip_masq_new(proto=%s): no free ports.\n", + printk(KERN_ERR "ip_masq_new(proto=%s): no free ports.\n", masq_proto_name(proto)); return NULL; } ms = (struct ip_masq *) kmalloc(sizeof(struct ip_masq), GFP_ATOMIC); if (ms == NULL) { if (++n_fails < 5) - printk("ip_masq_new(proto=%s): no memory available.\n", + printk(KERN_ERR "ip_masq_new(proto=%s): no memory available.\n", masq_proto_name(proto)); return NULL; } @@ -416,7 +416,7 @@ } if (++n_fails < 5) - printk("ip_masq_new(proto=%s): could not get free masq entry (free=%d).\n", + printk(KERN_ERR "ip_masq_new(proto=%s): could not get free masq entry (free=%d).\n", masq_proto_name(ms->protocol), *free_ports_p); kfree_s(ms, sizeof(*ms)); return NULL; diff -u --recursive --new-file v2.1.30/linux/net/ipv4/ip_masq_app.c linux/net/ipv4/ip_masq_app.c --- v2.1.30/linux/net/ipv4/ip_masq_app.c Fri Dec 27 02:04:49 1996 +++ linux/net/ipv4/ip_masq_app.c Mon Mar 31 12:52:32 1997 @@ -73,7 +73,7 @@ unsigned long flags; unsigned hash; if (!mapp) { - printk("register_ip_masq_app(): NULL arg\n"); + printk(KERN_ERR "register_ip_masq_app(): NULL arg\n"); return -EINVAL; } mapp->type = IP_MASQ_APP_TYPE(proto, port); @@ -99,14 +99,14 @@ unsigned hash; unsigned long flags; if (!mapp) { - printk("unregister_ip_masq_app(): NULL arg\n"); + printk(KERN_ERR "unregister_ip_masq_app(): NULL arg\n"); return -EINVAL; } /* * only allow unregistration if it has no attachments */ if (mapp->n_attach) { - printk("unregister_ip_masq_app(): has %d attachments. failed\n", + printk(KERN_ERR "unregister_ip_masq_app(): has %d attachments. failed\n", mapp->n_attach); return -EINVAL; } @@ -122,7 +122,7 @@ } restore_flags(flags); - printk("unregister_ip_masq_app(proto=%s,port=%u): not hashed!\n", + printk(KERN_ERR "unregister_ip_masq_app(proto=%s,port=%u): not hashed!\n", masq_proto_name(IP_MASQ_APP_PROTO(mapp->type)), IP_MASQ_APP_PORT(mapp->type)); return -EINVAL; } @@ -164,7 +164,7 @@ n_at = mapp->n_attach + delta; if (n_at < 0) { restore_flags(flags); - printk("ip_masq_app: tried to set n_attach < 0 for (proto=%s,port==%d) ip_masq_app object.\n", + printk(KERN_ERR "ip_masq_app: tried to set n_attach < 0 for (proto=%s,port==%d) ip_masq_app object.\n", masq_proto_name(IP_MASQ_APP_PROTO(mapp->type)), IP_MASQ_APP_PORT(mapp->type)); return -1; @@ -189,7 +189,7 @@ */ if (ms->app != NULL) { - printk("ip_masq_bind_app() called for already bound object.\n"); + printk(KERN_ERR "ip_masq_bind_app() called for already bound object.\n"); return ms->app; } @@ -528,7 +528,7 @@ n_skb = alloc_skb(MAX_HEADER + skb->len + diff, pri); if (n_skb == NULL) { - printk("skb_replace(): no room left (from %p)\n", + printk(KERN_ERR "skb_replace(): no room left (from %p)\n", __builtin_return_address(0)); return skb; diff -u --recursive --new-file v2.1.30/linux/net/ipv4/ip_masq_ftp.c linux/net/ipv4/ip_masq_ftp.c --- v2.1.30/linux/net/ipv4/ip_masq_ftp.c Fri Jan 3 01:33:27 1997 +++ linux/net/ipv4/ip_masq_ftp.c Mon Mar 31 12:52:32 1997 @@ -214,7 +214,7 @@ void cleanup_module(void) { if (ip_masq_ftp_done() != 0) - printk("ip_masq_ftp: can't remove module"); + printk(KERN_INFO "ip_masq_ftp: can't remove module"); } #endif /* MODULE */ diff -u --recursive --new-file v2.1.30/linux/net/ipv4/ip_masq_irc.c linux/net/ipv4/ip_masq_irc.c --- v2.1.30/linux/net/ipv4/ip_masq_irc.c Fri Jan 3 01:33:27 1997 +++ linux/net/ipv4/ip_masq_irc.c Mon Mar 31 12:52:32 1997 @@ -265,7 +265,7 @@ void cleanup_module(void) { if (ip_masq_irc_done() != 0) - printk("ip_masq_irc: can't remove module"); + printk(KERN_INFO "ip_masq_irc: can't remove module"); } #endif /* MODULE */ diff -u --recursive --new-file v2.1.30/linux/net/ipv4/ip_masq_raudio.c linux/net/ipv4/ip_masq_raudio.c --- v2.1.30/linux/net/ipv4/ip_masq_raudio.c Fri Jan 3 01:33:27 1997 +++ linux/net/ipv4/ip_masq_raudio.c Mon Mar 31 12:52:32 1997 @@ -227,7 +227,7 @@ void cleanup_module(void) { if (ip_masq_raudio_done() != 0) - printk("ip_masq_raudio: can't remove module"); + printk(KERN_INFO "ip_masq_raudio: can't remove module"); } #endif /* MODULE */ diff -u --recursive --new-file v2.1.30/linux/net/ipv4/ip_output.c linux/net/ipv4/ip_output.c --- v2.1.30/linux/net/ipv4/ip_output.c Thu Mar 27 14:40:15 1997 +++ linux/net/ipv4/ip_output.c Mon Mar 31 12:52:32 1997 @@ -836,7 +836,7 @@ */ if ((skb2 = alloc_skb(len+hlen+15,GFP_ATOMIC)) == NULL) { - NETDEBUG(printk("IP: frag: no memory for new fragment!\n")); + NETDEBUG(printk(KERN_INFO "IP: frag: no memory for new fragment!\n")); ip_statistics.IpFragFails++; kfree_skb(skb, FREE_WRITE); return; diff -u --recursive --new-file v2.1.30/linux/net/ipv4/ipmr.c linux/net/ipv4/ipmr.c --- v2.1.30/linux/net/ipv4/ipmr.c Thu Feb 27 10:57:32 1997 +++ linux/net/ipv4/ipmr.c Mon Mar 31 12:52:32 1997 @@ -17,6 +17,9 @@ * Malcolm Beattie : Buffer handling fixes. * Alexey Kuznetsov : Double buffer free and other fixes. * SVR Anand : Fixed several multicast bugs and problems. + * Alexey Kuznetsov : Status, optimisations and more. + * Brad Parker : Better behaviour on mrouted upcall + * overflow. * * Status: * Cache manager under test. Forwarding in vague test mode @@ -264,15 +267,16 @@ * expects the following bizarre scheme.. */ -static void ipmr_cache_report(struct sk_buff *pkt, vifi_t vifi, int assert) +static int ipmr_cache_report(struct sk_buff *pkt, vifi_t vifi, int assert) { struct sk_buff *skb = alloc_skb(128, GFP_ATOMIC); int ihl = pkt->nh.iph->ihl<<2; struct igmphdr *igmp; struct igmpmsg *msg; + int ret; if(!skb) - return; + return -ENOMEM; /* * Copy the IP header @@ -299,9 +303,16 @@ /* * Deliver to mrouted */ - if(sock_queue_rcv_skb(mroute_socket,skb)<0) + if((ret=sock_queue_rcv_skb(mroute_socket,skb))<0) { + static unsigned long last_warn; + if(jiffies-last_warn>10*HZ) + { + last_warn=jiffies; + printk("mroute: pending queue full, dropping entries.\n"); + } kfree_skb(skb, FREE_READ); + return ret; } } @@ -342,7 +353,12 @@ * Reflect first query at mrouted. */ if(mroute_socket) - ipmr_cache_report(skb, vifi, 0); + { + /* If the report failed throw the cache entry + out - Brad Parker */ + if(ipmr_cache_report(skb, vifi, 0)<0) + impr_cache_delete(cache); + } } /* * See if we can append the packet diff -u --recursive --new-file v2.1.30/linux/net/ipv4/raw.c linux/net/ipv4/raw.c --- v2.1.30/linux/net/ipv4/raw.c Thu Mar 27 14:40:15 1997 +++ linux/net/ipv4/raw.c Mon Mar 31 12:52:32 1997 @@ -285,7 +285,7 @@ if (usin->sin_family != AF_INET) { static int complained; if (!complained++) - printk("%s forgot to set AF_INET in raw sendmsg. Fix it!\n", current->comm); + printk(KERN_INFO "%s forgot to set AF_INET in raw sendmsg. Fix it!\n", current->comm); if (usin->sin_family) return -EINVAL; } diff -u --recursive --new-file v2.1.30/linux/net/ipv4/tcp.c linux/net/ipv4/tcp.c --- v2.1.30/linux/net/ipv4/tcp.c Thu Mar 27 14:40:15 1997 +++ linux/net/ipv4/tcp.c Mon Mar 31 12:52:32 1997 @@ -1290,7 +1290,7 @@ * shouldn't happen */ if (before(*seq, skb->seq)) { - printk("recvmsg bug: copied %X seq %X\n", + printk(KERN_INFO "recvmsg bug: copied %X seq %X\n", *seq, skb->seq); break; } diff -u --recursive --new-file v2.1.30/linux/net/ipv4/tcp_ipv4.c linux/net/ipv4/tcp_ipv4.c --- v2.1.30/linux/net/ipv4/tcp_ipv4.c Thu Mar 27 14:40:15 1997 +++ linux/net/ipv4/tcp_ipv4.c Mon Mar 31 12:52:32 1997 @@ -1284,7 +1284,7 @@ case CHECKSUM_HW: if (tcp_v4_check(th,len,saddr,daddr,skb->csum)) { struct iphdr * iph = skb->nh.iph; - printk("TCPv4 bad checksum from %08x:%04x to %08x:%04x, len=%d/%d/%d\n", + printk(KERN_DEBUG "TCPv4 bad checksum from %08x:%04x to %08x:%04x, len=%d/%d/%d\n", saddr, ntohs(th->source), daddr, ntohs(th->dest), len, skb->len, ntohs(iph->tot_len)); goto discard_it; diff -u --recursive --new-file v2.1.30/linux/net/ipv4/tcp_output.c linux/net/ipv4/tcp_output.c --- v2.1.30/linux/net/ipv4/tcp_output.c Thu Mar 27 14:40:16 1997 +++ linux/net/ipv4/tcp_output.c Mon Mar 31 12:52:32 1997 @@ -112,7 +112,7 @@ if (size < sizeof(struct tcphdr) || size > skb->len) { - printk("tcp_send_skb: bad skb (skb = %p, data = %p, th = %p, len = %u)\n", + printk(KERN_DEBUG "tcp_send_skb: bad skb (skb = %p, data = %p, th = %p, len = %u)\n", skb, skb->data, th, skb->len); kfree_skb(skb, FREE_WRITE); return 0; @@ -130,7 +130,7 @@ */ if(!th->syn && !th->fin) { - printk("tcp_send_skb: attempt to queue a bogon.\n"); + printk(KERN_DEBUG "tcp_send_skb: attempt to queue a bogon.\n"); kfree_skb(skb,FREE_WRITE); return 0; } @@ -770,7 +770,7 @@ if (buff == NULL) { /* This is a disaster if it occurs */ - printk("tcp_send_fin: Impossible malloc failure"); + printk(KERN_INFO "tcp_send_fin: Impossible malloc failure"); return; } diff -u --recursive --new-file v2.1.30/linux/net/ipv4/tcp_timer.c linux/net/ipv4/tcp_timer.c --- v2.1.30/linux/net/ipv4/tcp_timer.c Thu Mar 27 14:40:16 1997 +++ linux/net/ipv4/tcp_timer.c Mon Mar 31 12:52:32 1997 @@ -69,7 +69,7 @@ if((long)when <= 0) { - printk("xmit_timer <= 0 - timer:%d when:%lx\n", what, when); + printk(KERN_DEBUG "xmit_timer <= 0 - timer:%d when:%lx\n", what, when); when=HZ/50; } @@ -100,11 +100,11 @@ break; case TIME_WRITE: - printk("bug: tcp_reset_xmit_timer TIME_WRITE\n"); + printk(KERN_DEBUG "bug: tcp_reset_xmit_timer TIME_WRITE\n"); break; default: - printk("bug: unknown timer value\n"); + printk(KERN_DEBUG "bug: unknown timer value\n"); } } @@ -123,7 +123,7 @@ del_timer(&tp->probe_timer); break; default: - printk("bug: unknown timer value\n"); + printk(KERN_DEBUG "bug: unknown timer value\n"); } } @@ -142,7 +142,7 @@ return tp->probe_timer.next != NULL; break; default: - printk("bug: unknown timer value\n"); + printk(KERN_DEBUG "bug: unknown timer value\n"); } return 0; } diff -u --recursive --new-file v2.1.30/linux/net/ipv4/timer.c linux/net/ipv4/timer.c --- v2.1.30/linux/net/ipv4/timer.c Thu Mar 27 14:40:16 1997 +++ linux/net/ipv4/timer.c Mon Mar 31 12:52:32 1997 @@ -122,7 +122,7 @@ if (sk->state != TCP_CLOSE) { - printk ("non CLOSE socket in time_done\n"); + printk (KERN_DEBUG "non CLOSE socket in time_done\n"); break; } destroy_sock (sk); @@ -148,7 +148,7 @@ break; default: - printk ("net_timer: timer expired - reason %d is unknown\n", why); + printk (KERN_DEBUG "net_timer: timer expired - reason %d is unknown\n", why); break; } } diff -u --recursive --new-file v2.1.30/linux/net/ipv4/udp.c linux/net/ipv4/udp.c --- v2.1.30/linux/net/ipv4/udp.c Thu Mar 27 14:40:16 1997 +++ linux/net/ipv4/udp.c Wed Apr 2 17:45:33 1997 @@ -52,6 +52,7 @@ * David S. Miller : New socket lookup architecture. * Last socket cache retained as it * does have a high hit rate. + * Olaf Kirch : Don't linearise iovec on sendmsg. * * * This program is free software; you can redistribute it and/or @@ -505,7 +506,8 @@ u32 saddr; u32 daddr; u32 other; - const char *from; + struct iovec *iov; + int nriov; u32 wcheck; }; @@ -519,20 +521,36 @@ static int udp_getfrag(const void *p, char * to, unsigned int offset, unsigned int fraglen) { struct udpfakehdr *ufh = (struct udpfakehdr *)p; - const char *src; - char *dst; + struct iovec *iov; + char *src; + char *dst = to; unsigned int len; - if (offset) { - len = fraglen; - src = ufh->from+(offset-sizeof(struct udphdr)); - dst = to; - } else { - len = fraglen-sizeof(struct udphdr); - src = ufh->from; - dst = to+sizeof(struct udphdr); + if (offset == 0) { + fraglen -= sizeof(struct udphdr); + dst += sizeof(struct udphdr); } - ufh->wcheck = csum_partial_copy_fromuser(src, dst, len, ufh->wcheck); + + iov = ufh->iov; + do { + if ((len = iov->iov_len) > fraglen) + len = fraglen; + src = (char *) iov->iov_base + iov->iov_len - len; + ufh->wcheck = csum_partial_copy_fromuser(src, + dst + fraglen - len, len, + ufh->wcheck); + if ((iov->iov_len -= len) == 0) { + if (--(ufh->nriov) < 0) { + printk(KERN_NOTICE "udp_getfrag: nriov = %d\n", + ufh->nriov); + return -EINVAL; + } + iov--; + } + fraglen -= len; + } while (fraglen); + ufh->iov = iov; + if (offset == 0) { ufh->wcheck = csum_partial((char *)ufh, sizeof(struct udphdr), ufh->wcheck); @@ -556,29 +574,42 @@ static int udp_getfrag_nosum(const void *p, char * to, unsigned int offset, unsigned int fraglen) { struct udpfakehdr *ufh = (struct udpfakehdr *)p; - const char *src; - char *dst; + struct iovec *iov; + char *src; + char *dst = to; int err; unsigned int len; - if (offset) { - len = fraglen; - src = ufh->from+(offset-sizeof(struct udphdr)); - dst = to; - } else { - len = fraglen-sizeof(struct udphdr); - src = ufh->from; - dst = to+sizeof(struct udphdr); + if (offset == 0) { + fraglen -= sizeof(struct udphdr); + dst += sizeof(struct udphdr); } - err = copy_from_user(dst,src,len); + + iov = ufh->iov; + do { + if ((len = iov->iov_len) > fraglen) + len = fraglen; + src = (char *) iov->iov_base + iov->iov_len - len; + err = copy_from_user(dst + fraglen - len, src, len); + fraglen -= len; + if ((iov->iov_len -= len) == 0) { + if (--(ufh->nriov) < 0) { + printk(KERN_NOTICE "udp_getfrag: nriov = %d\n", + ufh->nriov); + return -EINVAL; + } + iov--; + } + } while (fraglen && err >= 0); + ufh->iov = iov; + if (offset == 0) memcpy(to, ufh, sizeof(struct udphdr)); return err; } -static int udp_sendto(struct sock *sk, const unsigned char *from, int len, - struct msghdr *msg) +int udp_sendmsg(struct sock *sk, struct msghdr *msg, int len) { int ulen = len + sizeof(struct udphdr); struct device *dev = NULL; @@ -675,7 +706,8 @@ ufh.uh.len = htons(ulen); ufh.uh.check = 0; ufh.other = (htons(ulen) << 16) + IPPROTO_UDP*256; - ufh.from = from; + ufh.iov = msg->msg_iov + msg->msg_iovlen - 1; + ufh.nriov = msg->msg_iovlen; ufh.wcheck = 0; /* RFC1122: OK. Provides the checksumming facility (MUST) as per */ @@ -703,44 +735,6 @@ } /* - * Temporary - */ - -int udp_sendmsg(struct sock *sk, struct msghdr *msg, int len) -{ - if(msg->msg_iovlen==1) - return udp_sendto(sk,msg->msg_iov[0].iov_base,len, msg); - else { - /* - * For awkward cases we linearise the buffer first. In theory this is only frames - * whose iovec's don't split on 4 byte boundaries, and soon encrypted stuff (to keep - * skip happy). We are a bit more general about it. - */ - - unsigned char *buf; - int fs; - int err; - if(len>65515) - return -EMSGSIZE; - buf=kmalloc(len, GFP_KERNEL); - if(buf==NULL) - return -ENOBUFS; - err = memcpy_fromiovec(buf, msg->msg_iov, len); - if (err) - err = -EFAULT; - if (!err) - { - fs=get_fs(); - set_fs(get_ds()); - err=udp_sendto(sk,buf,len, msg); - set_fs(fs); - } - kfree_s(buf,len); - return err; - } -} - -/* * IOCTL requests applicable to the UDP protocol */ @@ -1063,7 +1057,7 @@ ulen = ntohs(uh->len); if (ulen > len || len < sizeof(*uh) || ulen < sizeof(*uh)) { - NETDEBUG(printk("UDP: short packet: %d/%d\n", ulen, len)); + NETDEBUG(printk(KERN_DEBUG "UDP: short packet: %d/%d\n", ulen, len)); udp_statistics.UdpInErrors++; kfree_skb(skb, FREE_WRITE); return(0); @@ -1086,7 +1080,7 @@ /* RFC1122: OK. Discards the bad packet silently (as far as */ /* the network is concerned, anyway) as per 4.1.3.4 (MUST). */ - NETDEBUG(printk("UDP: bad checksum. From %08lX:%d to %08lX:%d ulen %d\n", + NETDEBUG(printk(KERN_DEBUG "UDP: bad checksum. From %08lX:%d to %08lX:%d ulen %d\n", ntohl(saddr),ntohs(uh->source), ntohl(daddr),ntohs(uh->dest), ulen)); diff -u --recursive --new-file v2.1.30/linux/net/netlink.c linux/net/netlink.c --- v2.1.30/linux/net/netlink.c Sat Jan 25 13:46:14 1997 +++ linux/net/netlink.c Wed Apr 2 17:43:23 1997 @@ -151,12 +151,13 @@ return -EUNATCH; } -static void netlink_release(struct inode * inode, struct file * file) +static int netlink_release(struct inode * inode, struct file * file) { unsigned int minor = MINOR(inode->i_rdev); if (file->f_mode & FMODE_READ) open_map&=~(1<=NPROTO) - goto out; + return -EINVAL; #if defined(CONFIG_KERNELD) && defined(CONFIG_NET) /* Attempt to load a protocol module if the find failed. @@ -591,7 +589,7 @@ #endif if (net_families[family]==NULL) - goto out; + return -EINVAL; /* * Check that this is a type that we know how to manipulate and @@ -602,7 +600,7 @@ if ((type != SOCK_STREAM && type != SOCK_DGRAM && type != SOCK_SEQPACKET && type != SOCK_RAW && type != SOCK_PACKET) || protocol < 0) - goto out; + return -EINVAL; /* * Allocate the socket and allow the family to set things up. if @@ -610,11 +608,10 @@ * default. */ - err = -ENFILE; if (!(sock = sock_alloc())) { printk(KERN_WARNING "socket: no more sockets\n"); - goto out; /* Not exactly a match, but its the + return -ENFILE; /* Not exactly a match, but its the closest posix thing */ } @@ -623,9 +620,24 @@ if ((i = net_families[family]->create(sock, protocol)) < 0) { sock_release(sock); - err = i; + return i; } - else if ((fd = get_fd(sock->inode)) < 0) + + *res = sock; + return 0; +} + +asmlinkage int sys_socket(int family, int type, int protocol) +{ + int fd, err; + struct socket *sock; + + lock_kernel(); + + if ((err = sock_create(family, type, protocol, &sock)) < 0) + goto out; + + if ((fd = get_fd(sock->inode)) < 0) { sock_release(sock); err = -EINVAL; @@ -635,6 +647,7 @@ sock->file = current->files->fd[fd]; err = fd; } + out: unlock_kernel(); return err; @@ -988,35 +1001,6 @@ } -/* - * Receive a datagram from a socket. Call the protocol recvmsg method - */ - -asmlinkage int sys_recv(int fd, void * ubuf, size_t size, unsigned flags) -{ - struct iovec iov; - struct msghdr msg; - struct socket *sock; - int err; - - lock_kernel(); - if ((sock = sockfd_lookup(fd, &err))!=NULL) - { - msg.msg_name=NULL; - msg.msg_iov=&iov; - msg.msg_iovlen=1; - msg.msg_control=NULL; - msg.msg_controllen=0; - iov.iov_base=ubuf; - iov.iov_len=size; - - err=sock_recvmsg(sock, &msg, size, - (current->files->fd[fd]->f_flags & O_NONBLOCK) ? flags | MSG_DONTWAIT : flags); - sockfd_put(sock); - } - unlock_kernel(); - return err; -} /* * Receive a frame from the socket and optionally record the address of the @@ -1059,6 +1043,15 @@ } /* + * Receive a datagram from a socket. + */ + +asmlinkage int sys_recv(int fd, void * ubuf, size_t size, unsigned flags) +{ + return sys_recvfrom(fd,ubuf,size,flags, NULL, NULL); +} + +/* * Set a socket option. Because we don't know the option lengths we have * to pass the user mode parameter for the protocols to sort out. */ @@ -1289,13 +1282,7 @@ /* - * System call vectors. Since I (RIB) want to rewrite sockets as streams, - * we have this level of indirection. Not a lot of overhead, since more of - * the work is done via read/write/poll directly. - * - * I'm now expanding this up to a higher level to separate the assorted - * kernel/user space manipulations and global assumptions from the protocol - * layers proper - AC. + * System call vectors. * * Argument checking cleaned up. Saved 20% in size. */ @@ -1434,7 +1421,7 @@ { int i; - printk(KERN_INFO "Swansea University Computer Society NET3.038 for Linux 2.1\n"); + printk(KERN_INFO "Swansea University Computer Society NET3.039 for Linux 2.1\n"); /* * Initialize all address (protocol) families. diff -u --recursive --new-file v2.1.30/linux/scripts/mkdep.c linux/scripts/mkdep.c --- v2.1.30/linux/scripts/mkdep.c Thu Mar 27 14:40:18 1997 +++ linux/scripts/mkdep.c Fri Mar 28 10:53:15 1997 @@ -1,6 +1,7 @@ #include #include +#include #include #include #include