Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Linux Kernel Patch v2.4, patch-2.4.12 (0/3)

2 views
Skip to first unread message

Thomas Kobienia

unread,
Oct 11, 2001, 8:00:29 PM10/11/01
to
Archive-name: v2.4/patch-2.4.12/part0

lines added deleted
linux/Documentation/filesystems/devfs/ChangeLog : 15 12 0
linux/Documentation/filesystems/devfs/README : 17 2 2
linux/Makefile : 17 3 2
linux/arch/sparc/kernel/process.c : 5 1 1
linux/arch/sparc/kernel/systbls.S : 14 2 2
linux/arch/sparc64/defconfig : 30 5 0
linux/arch/sparc64/kernel/dtlb_backend.S : 58 11 11
linux/arch/sparc64/kernel/dtlb_base.S : 57 14 14
linux/arch/sparc64/kernel/pci.c : 100 63 11
linux/arch/sparc64/kernel/process.c : 5 1 1
linux/arch/sparc64/kernel/systbls.S : 23 3 3
linux/drivers/net/acenic.c : 296 37 40
linux/drivers/net/acenic.h : 30 2 9
linux/drivers/net/aironet4500.h : 7 0 1
linux/drivers/net/at1700.c : 8 1 1
linux/drivers/net/macsonic.c : 33 9 2
linux/drivers/net/sk98lin/skge.c : 8 1 1
linux/drivers/net/sonic.c : 1111 524 517
linux/drivers/net/sonic.h : 426 156 154
linux/drivers/parport/ChangeLog : 23 20 0
linux/drivers/parport/ieee1284_ops.c : 24 10 0
linux/drivers/parport/parport_pc.c : 62 17 4
linux/drivers/sbus/audio/audio.c : 17 4 3
linux/drivers/sbus/audio/cs4231.c : 13 2 1
linux/drivers/sbus/audio/dbri.c : 14 3 1
linux/drivers/sbus/audio/dmy.c : 14 3 1
linux/drivers/sbus/char/aurora.c : 10 2 1
linux/drivers/sbus/char/bpp.c : 4 1 0
linux/drivers/sbus/char/cpwatchdog.c : 7 1 0
linux/drivers/sbus/char/display7seg.c : 13 2 1
linux/drivers/sbus/char/envctrl.c : 10 2 1
linux/drivers/sbus/char/flash.c : 10 2 1
linux/drivers/sbus/char/jsflash.c : 7 1 0
linux/drivers/sbus/char/openprom.c : 4 1 0
linux/drivers/sbus/char/riowatchdog.c : 13 2 1
linux/drivers/sbus/char/rtc.c : 10 2 1
linux/drivers/sbus/char/sab82532.c : 23 4 2
linux/drivers/sbus/char/uctrl.c : 10 2 1
linux/drivers/scsi/aic7xxx_old.c : 9 0 2
linux/drivers/usb/serial/belkin_sa.c : 52 18 7
linux/drivers/usb/serial/cyberjack.c : 16 6 4
linux/drivers/usb/serial/digi_acceleport.c : 101 48 46
linux/drivers/usb/serial/empeg.c : 12 4 2
linux/drivers/usb/serial/ftdi_sio.c : 52 23 21
linux/drivers/usb/serial/io_edgeport.c : 72 30 27
linux/drivers/usb/serial/ir-usb.c : 32 9 3
linux/drivers/usb/serial/keyspan.c : 52 15 13
linux/drivers/usb/serial/keyspan_pda.c : 21 8 6
linux/drivers/usb/serial/mct_u232.c : 17 6 5
linux/drivers/usb/serial/omninet.c : 20 6 5
linux/drivers/usb/serial/pl2303.c : 74 34 21
linux/drivers/usb/serial/usb-serial.h : 19 6 0
linux/drivers/usb/serial/usbserial.c : 80 26 11
linux/drivers/usb/serial/visor.c : 38 17 12
linux/drivers/usb/uhci.c : 10 1 3
linux/drivers/usb/usbvideo.c : 27 0 21
linux/drivers/usb/usbvideo.h : 8 0 2
linux/drivers/video/fbmem.c : 19 5 1
linux/fs/devfs/base.c : 93 12 20
linux/fs/ext2/inode.c : 63 0 60
linux/fs/namei.c : 42 8 7
linux/fs/namespace.c : 32 5 6
linux/fs/proc/base.c : 38 1 24
linux/fs/super.c : 218 69 51
linux/include/asm-i386/smp.h : 8 1 1
linux/include/asm-sparc/processor.h : 5 1 1
linux/include/asm-sparc/unistd.h : 14 2 2
linux/include/asm-sparc64/processor.h : 5 1 1
linux/include/asm-sparc64/unistd.h : 14 2 2
linux/include/linux/ext2_fs.h : 9 0 3
linux/include/linux/fs.h : 7 1 0
linux/include/linux/netdevice.h : 41 35 0
linux/include/linux/parport.h : 9 2 1
linux/include/linux/pci_ids.h : 21 2 3
linux/include/linux/sched.h : 8 1 1
linux/include/linux/shmem_fs.h : 32 12 6
linux/mm/shmem.c : 995 400 240
linux/net/ipv4/tcp.c : 17 2 2

Thomas Kobienia

unread,
Oct 11, 2001, 8:00:30 PM10/11/01
to
Archive-name: v2.4/patch-2.4.12/part1

#!/bin/sh -x
# This is a shell archive
# To extract the files from this archive, save it to a file, remove
# everything above the "!/bin/sh" line above, and type "sh file_name".
# existing files will NOT be overwritten unless -c is specified
#
# This is part 1 of a 3 - part archive
# do not concatenate these parts, unpack them in order with /bin/sh
#
if test -r _shar_seq_.tmp; then
echo "Must unpack archives in sequence!"
echo "Please unpack part `cat _shar_seq_.tmp` next"
exit 1
fi
# ============= patch-2.4.12 ==============
if test -f 'patch-2.4.12' -a X"$1" != X"-c"; then
echo 'x - skipping patch-2.4.12 (File already exists)'
rm -f _shar_wnt_.tmp;
else
> _shar_wnt_.tmp;
echo 'x - extracting patch-2.4.12 (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'patch-2.4.12' &&
diff -u --recursive --new-file v2.4.11/linux/Documentation/filesystems/devfs/ChangeLog linux/Documentation/filesystems/devfs/ChangeLog
--- v2.4.11/linux/Documentation/filesystems/devfs/ChangeLog Tue Oct 9 17:06:51 2001
+++ linux/Documentation/filesystems/devfs/ChangeLog Wed Oct 10 23:23:24 2001
@@ -1759,3 +1759,15 @@
X Changes for patch v193
X
X - Went back to global rwsem for symlinks (refcount scheme no good)
+===============================================================================
+Changes for patch v194
+
+- Fixed overrun in <devfs_link> by removing function (not needed)
+
+- Updated README from master HTML file
+===============================================================================
+Changes for patch v195
+
+- Fixed buffer underrun in <try_modload>
+
+- Moved down_read() from <search_for_entry_in_dir> to <find_entry>
diff -u --recursive --new-file v2.4.11/linux/Documentation/filesystems/devfs/README linux/Documentation/filesystems/devfs/README
--- v2.4.11/linux/Documentation/filesystems/devfs/README Sun Sep 23 11:40:54 2001
+++ linux/Documentation/filesystems/devfs/README Wed Oct 10 23:23:24 2001
@@ -3,7 +3,7 @@
X
X Linux Devfs (Device File System) FAQ
X Richard Gooch
-23-AUG-2001
+29-SEP-2001
X
X -----------------------------------------------------------------------------
X
@@ -1753,7 +1753,7 @@
X
X Douglas Gilbert has written yet another useful document at
X
-http://www.torque.net/scsi/linux_scsi_24/ which
+http://www.torque.net/scsi/SCSI-2.4-HOWTO/ which
X discusses the Linux SCSI subsystem in 2.4.
X
X
diff -u --recursive --new-file v2.4.11/linux/Makefile linux/Makefile
--- v2.4.11/linux/Makefile Tue Oct 9 17:06:51 2001
+++ linux/Makefile Wed Oct 10 23:42:46 2001
@@ -1,6 +1,6 @@
X VERSION = 2
X PATCHLEVEL = 4
-SUBLEVEL = 11
+SUBLEVEL = 12
X EXTRAVERSION =
X
X KERNELRELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)
@@ -300,7 +300,8 @@
X $(TOPDIR)/include/linux/compile.h: include/linux/compile.h
X
X newversion:
- . scripts/mkversion > .version
+ . scripts/mkversion > .tmpversion
+ @mv -f .tmpversion .version
X
X include/linux/compile.h: $(CONFIGURATION) include/linux/version.h newversion
X @echo -n \#define UTS_VERSION \"\#`cat .version` > .ver
diff -u --recursive --new-file v2.4.11/linux/arch/sparc/kernel/process.c linux/arch/sparc/kernel/process.c
--- v2.4.11/linux/arch/sparc/kernel/process.c Tue Oct 9 17:06:51 2001
+++ linux/arch/sparc/kernel/process.c Wed Oct 10 23:42:46 2001
@@ -1,4 +1,4 @@
-/* $Id: process.c,v 1.155 2001/02/13 01:16:43 davem Exp $
+/* $Id: process.c,v 1.156 2001/10/02 02:22:26 davem Exp $
X * linux/arch/sparc/kernel/process.c
X *
X * Copyright (C) 1995 David S. Miller (da...@caip.rutgers.edu)
diff -u --recursive --new-file v2.4.11/linux/arch/sparc/kernel/systbls.S linux/arch/sparc/kernel/systbls.S
--- v2.4.11/linux/arch/sparc/kernel/systbls.S Sun Aug 13 12:01:54 2000
+++ linux/arch/sparc/kernel/systbls.S Wed Oct 10 23:42:46 2001
@@ -1,4 +1,4 @@
-/* $Id: systbls.S,v 1.99 2000/08/12 20:49:49 jj Exp $
+/* $Id: systbls.S,v 1.100 2001/10/09 10:54:38 davem Exp $
X * systbls.S: System call entry point tables for OS compatibility.
X * The native Linux system call table lives here also.
X *
@@ -46,7 +46,7 @@
X /*125*/ .long sys_nis_syscall, sys_setreuid16, sys_setregid16, sys_rename, sys_truncate
X /*130*/ .long sys_ftruncate, sys_flock, sys_lstat64, sys_nis_syscall, sys_nis_syscall
X /*135*/ .long sys_nis_syscall, sys_mkdir, sys_rmdir, sys_utimes, sys_stat64
-/*140*/ .long sys_nis_syscall, sys_nis_syscall, sys_nis_syscall, sys_nis_syscall, sys_getrlimit
+/*140*/ .long sys_nis_syscall, sys_nis_syscall, sys_nis_syscall, sys_gettid, sys_getrlimit
X /*145*/ .long sys_setrlimit, sys_pivot_root, sys_prctl, sys_pciconfig_read, sys_pciconfig_write
X /*150*/ .long sys_nis_syscall, sys_nis_syscall, sys_nis_syscall, sys_poll, sys_getdents64
X /*155*/ .long sys_fcntl64, sys_nis_syscall, sys_statfs, sys_fstatfs, sys_oldumount
diff -u --recursive --new-file v2.4.11/linux/arch/sparc64/defconfig linux/arch/sparc64/defconfig
--- v2.4.11/linux/arch/sparc64/defconfig Tue Oct 9 17:06:51 2001
+++ linux/arch/sparc64/defconfig Wed Oct 10 23:42:46 2001
@@ -567,6 +567,7 @@
X CONFIG_VFAT_FS=m
X CONFIG_EFS_FS=m
X # CONFIG_JFFS_FS is not set
+# CONFIG_JFFS2_FS is not set
X CONFIG_CRAMFS=m
X # CONFIG_TMPFS is not set
X CONFIG_RAMFS=m
@@ -737,6 +738,7 @@
X CONFIG_USB_MDC800=m
X CONFIG_USB_SCANNER=m
X CONFIG_USB_MICROTEK=m
+CONFIG_USB_HPUSBSCSI=m
X
X #
X # USB Multimedia devices
@@ -773,11 +775,14 @@
X CONFIG_USB_SERIAL_EMPEG=m
X CONFIG_USB_SERIAL_FTDI_SIO=m
X CONFIG_USB_SERIAL_VISOR=m
+# CONFIG_USB_SERIAL_IR is not set
X CONFIG_USB_SERIAL_EDGEPORT=m
X CONFIG_USB_SERIAL_KEYSPAN_PDA=m
X CONFIG_USB_SERIAL_KEYSPAN=m
X # CONFIG_USB_SERIAL_KEYSPAN_USA28 is not set
X # CONFIG_USB_SERIAL_KEYSPAN_USA28X is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA28XA is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA28XB is not set
X # CONFIG_USB_SERIAL_KEYSPAN_USA19 is not set
X # CONFIG_USB_SERIAL_KEYSPAN_USA18X is not set
X # CONFIG_USB_SERIAL_KEYSPAN_USA19W is not set
diff -u --recursive --new-file v2.4.11/linux/arch/sparc64/kernel/dtlb_backend.S linux/arch/sparc64/kernel/dtlb_backend.S
--- v2.4.11/linux/arch/sparc64/kernel/dtlb_backend.S Tue Oct 9 17:06:51 2001
+++ linux/arch/sparc64/kernel/dtlb_backend.S Wed Oct 10 23:42:46 2001
@@ -1,4 +1,4 @@
-/* $Id: dtlb_backend.S,v 1.15 2001/09/24 21:54:09 davem Exp $
+/* $Id: dtlb_backend.S,v 1.16 2001/10/09 04:02:11 davem Exp $
X * dtlb_backend.S: Back end to DTLB miss replacement strategy.
X * This is included directly into the trap table.
X *
@@ -41,23 +41,25 @@
X ldxa [%g1 + %g1] ASI_DMMU, %g4 ! Get TAG_ACCESS
X add %g3, %g3, %g5 ! Compute VPTE base
X cmp %g4, %g5 ! VPTE miss?
- blu,pn %xcc, from_tl1_trap ! Fall to tl0 miss
+ bgeu,pt %xcc, 1f ! Continue here
X andcc %g4, TAG_CONTEXT_BITS, %g5 ! From Nucleus? (for tl0 miss)
- sllx %g6, VPTE_SHIFT, %g4 ! Position TAG_ACCESS
- or %g4, %g5, %g4 ! Prepare TAG_ACCESS
- mov TSB_REG, %g1 ! Grab TSB reg
+ ba,pt %xcc, from_tl1_trap ! Fall to tl0 miss
+ rdpr %tl, %g5 ! For tl0 miss TL==3 test
+1: sllx %g6, VPTE_SHIFT, %g4 ! Position TAG_ACCESS
X
X /* TLB1 ** ICACHE line 2: Quick VPTE miss */
+ or %g4, %g5, %g4 ! Prepare TAG_ACCESS
+ mov TSB_REG, %g1 ! Grab TSB reg
X ldxa [%g1] ASI_DMMU, %g5 ! Doing PGD caching?
X srlx %g6, (TLB_PMD_SHIFT - 1), %g1 ! Position PMD offset
X be,pn %xcc, sparc64_vpte_nucleus ! Is it from Nucleus?
X and %g1, TLB_PMD_MASK, %g1 ! Mask PMD offset bits
X brnz,pt %g5, sparc64_vpte_continue ! Yep, go like smoke
X add %g1, %g1, %g1 ! Position PMD offset some more
- srlx %g6, (TLB_PGD_SHIFT - 2), %g5 ! Position PGD offset
- and %g5, TLB_PGD_MASK, %g5 ! Mask PGD offset
X
X /* TLB1 ** ICACHE line 3: Quick VPTE miss */
+ srlx %g6, (TLB_PGD_SHIFT - 2), %g5 ! Position PGD offset
+ and %g5, TLB_PGD_MASK, %g5 ! Mask PGD offset
X lduwa [%g7 + %g5] ASI_PHYS_USE_EC, %g5! Load PGD
X brz,pn %g5, vpte_noent ! Valid?
X sparc64_kpte_continue:
@@ -66,18 +68,16 @@
X lduwa [%g5 + %g1] ASI_PHYS_USE_EC, %g5! Load PMD
X sllx %g5, 11, %g5 ! Shift into place
X brz,pn %g5, vpte_noent ! Valid?
+
+/* TLB1 ** ICACHE line 4: Quick VPTE miss */
X FILL_VALID_SZ_BITS1(%g1) ! Put _PAGE_VALID into %g1
X FILL_VALID_SZ_BITS2(%g1) ! Put _PAGE_VALID into %g1
X or %g5, VPTE_BITS, %g5 ! Prepare VPTE data
-
-/* TLB1 ** ICACHE line 4: Quick VPTE miss */
X or %g5, %g1, %g5 ! ...
X mov TLB_SFSR, %g1 ! Restore %g1 value
X stxa %g5, [%g0] ASI_DTLB_DATA_IN ! Load VPTE into TLB
X stxa %g4, [%g1 + %g1] ASI_DMMU ! Restore previous TAG_ACCESS
X retry ! Load PTE once again
- nop
- nop
X FILL_VALID_SZ_BITS_NOP
X
X #undef VPTE_SHIFT
diff -u --recursive --new-file v2.4.11/linux/arch/sparc64/kernel/dtlb_base.S linux/arch/sparc64/kernel/dtlb_base.S
--- v2.4.11/linux/arch/sparc64/kernel/dtlb_base.S Sun Sep 23 11:40:56 2001
+++ linux/arch/sparc64/kernel/dtlb_base.S Wed Oct 10 23:42:46 2001
@@ -1,4 +1,4 @@
-/* $Id: dtlb_base.S,v 1.14 2001/09/11 02:20:23 kanoj Exp $
+/* $Id: dtlb_base.S,v 1.16 2001/10/09 04:02:11 davem Exp $
X * dtlb_base.S: Front end to DTLB miss replacement strategy.
X * This is included directly into the trap table.
X *
@@ -65,27 +65,28 @@
X /* DTLB ** ICACHE line 1: Quick user TLB misses */
X ldxa [%g1 + %g1] ASI_DMMU, %g4 ! Get TAG_ACCESS
X andcc %g4, TAG_CONTEXT_BITS, %g0 ! From Nucleus?
+ mov 1, %g5 ! For TL==3 test
X from_tl1_trap:
X CREATE_VPTE_OFFSET1(%g4, %g6) ! Create VPTE offset
X be,pn %xcc, 3f ! Yep, special processing
X CREATE_VPTE_OFFSET2(%g4, %g6) ! Create VPTE offset
+ cmp %g5, 3 ! Last trap level?
+ be,a,pn %xcc, 1f ! Yep, use non-faulting load
+ ldxa [%g3 + %g6] ASI_SNF, %g5 ! Load VPTE (no-VPTE-fault)
+
+/* DTLB ** ICACHE line 2: User finish + quick kernel TLB misses */
X ldxa [%g3 + %g6] ASI_S, %g5 ! Load VPTE
-1: brlz,pt %g5, 9f ! Valid, load into TLB
+1: brgez,pn %g5, longpath ! Invalid, branch out
X nop ! Delay-slot
- ba,a,pt %xcc, longpath ! Invalid, branch out
-
-/* DTLB ** ICACHE line 2: Quick kernel TLB misses */
-3: brlz,pt %g4, 9f ! Kernel virtual map?
- xor %g2, %g4, %g5 ! Finish bit twiddles
- ba,pt %xcc, kvmap ! Yep, go check for obp/vmalloc
- nop
- nop
X 9: stxa %g5, [%g0] ASI_DTLB_DATA_IN ! Reload TLB
X retry ! Trap return
-longpath:
- rdpr %pstate, %g5 ! Move into alternate globals
+3: brlz,pt %g4, 9b ! Kernel virtual map?
+ xor %g2, %g4, %g5 ! Finish bit twiddles
+ ba,a,pt %xcc, kvmap ! Yep, go check for obp/vmalloc
X
X /* DTLB ** ICACHE line 3: winfixups+real_faults */
+longpath:
+ rdpr %pstate, %g5 ! Move into alternate globals
X wrpr %g5, PSTATE_AG|PSTATE_MG, %pstate
X rdpr %tl, %g4 ! See where we came from.
X cmp %g4, 1 ! Is etrap/rtrap window fault?
@@ -93,10 +94,9 @@
X ldxa [%g4] ASI_DMMU, %g5 ! Load faulting VA page
X be,pt %xcc, sparc64_realfault_common ! Jump to normal fault handling
X mov FAULT_CODE_DTLB, %g4 ! It was read from DTLB
- ba,a,pt %xcc, winfix_trampoline ! Call window fixup code
X
X /* DTLB ** ICACHE line 4: Unused... */
- nop
+ ba,a,pt %xcc, winfix_trampoline ! Call window fixup code
X nop
X nop
X nop
diff -u --recursive --new-file v2.4.11/linux/arch/sparc64/kernel/pci.c linux/arch/sparc64/kernel/pci.c
--- v2.4.11/linux/arch/sparc64/kernel/pci.c Tue Jul 3 17:08:19 2001
+++ linux/arch/sparc64/kernel/pci.c Wed Oct 10 23:42:46 2001
@@ -1,4 +1,4 @@
-/* $Id: pci.c,v 1.35 2001/06/13 06:34:30 davem Exp $
+/* $Id: pci.c,v 1.36 2001/10/06 00:38:25 davem Exp $
X * pci.c: UltraSparc PCI controller support.
X *
X * Copyright (C) 1997, 1998, 1999 David S. Miller (da...@redhat.com)
@@ -317,6 +317,7 @@
X {
X struct pcidev_cookie *pcp = pdev->sysdata;
X struct pci_pbm_info *pbm;
+ struct pci_controller_info *p;
X unsigned long space_size, user_offset, user_size;
X
X if (!pcp)
@@ -325,12 +326,44 @@
X if (!pbm)
X return -ENXIO;
X
- if (mmap_state == pci_mmap_io) {
- space_size = (pbm->io_space.end -
- pbm->io_space.start) + 1;
+ p = pbm->parent;
+ if (p->pbms_same_domain) {
+ unsigned long lowest, highest;
+
+ lowest = ~0UL; highest = 0UL;
+ if (mmap_state == pci_mmap_io) {
+ if (p->pbm_A.io_space.flags) {
+ lowest = p->pbm_A.io_space.start;
+ highest = p->pbm_A.io_space.end + 1;
+ }
+ if (p->pbm_B.io_space.flags) {
+ if (lowest > p->pbm_B.io_space.start)
+ lowest = p->pbm_B.io_space.start;
+ if (highest < p->pbm_B.io_space.end + 1)
+ highest = p->pbm_B.io_space.end + 1;
+ }
+ space_size = highest - lowest;
+ } else {
+ if (p->pbm_A.mem_space.flags) {
+ lowest = p->pbm_A.mem_space.start;
+ highest = p->pbm_A.mem_space.end + 1;
+ }
+ if (p->pbm_B.mem_space.flags) {
+ if (lowest > p->pbm_B.mem_space.start)
+ lowest = p->pbm_B.mem_space.start;
+ if (highest < p->pbm_B.mem_space.end + 1)
+ highest = p->pbm_B.mem_space.end + 1;
+ }
+ space_size = highest - lowest;
+ }
X } else {
- space_size = (pbm->mem_space.end -
- pbm->mem_space.start) + 1;
+ if (mmap_state == pci_mmap_io) {
+ space_size = (pbm->io_space.end -
+ pbm->io_space.start) + 1;
+ } else {
+ space_size = (pbm->mem_space.end -
+ pbm->mem_space.start) + 1;
+ }
X }
X
X /* Make sure the request is in range. */
@@ -341,12 +374,31 @@
X (user_offset + user_size) > space_size)
X return -EINVAL;
X
- if (mmap_state == pci_mmap_io) {
- vma->vm_pgoff = (pbm->io_space.start +
- user_offset) >> PAGE_SHIFT;
+ if (p->pbms_same_domain) {
+ unsigned long lowest = ~0UL;
+
+ if (mmap_state == pci_mmap_io) {
+ if (p->pbm_A.io_space.flags)
+ lowest = p->pbm_A.io_space.start;
+ if (p->pbm_B.io_space.flags &&
+ lowest > p->pbm_B.io_space.start)
+ lowest = p->pbm_B.io_space.start;
+ } else {
+ if (p->pbm_A.mem_space.flags)
+ lowest = p->pbm_A.mem_space.start;
+ if (p->pbm_B.mem_space.flags &&
+ lowest > p->pbm_B.mem_space.start)
+ lowest = p->pbm_B.mem_space.start;
+ }
+ vma->vm_pgoff = (lowest + user_offset) >> PAGE_SHIFT;
X } else {
- vma->vm_pgoff = (pbm->mem_space.start +
- user_offset) >> PAGE_SHIFT;
+ if (mmap_state == pci_mmap_io) {
+ vma->vm_pgoff = (pbm->io_space.start +
+ user_offset) >> PAGE_SHIFT;
+ } else {
+ vma->vm_pgoff = (pbm->mem_space.start +
+ user_offset) >> PAGE_SHIFT;
+ }
X }
X
X return 0;
diff -u --recursive --new-file v2.4.11/linux/arch/sparc64/kernel/process.c linux/arch/sparc64/kernel/process.c
--- v2.4.11/linux/arch/sparc64/kernel/process.c Tue Oct 9 17:06:51 2001
+++ linux/arch/sparc64/kernel/process.c Wed Oct 10 23:42:46 2001
@@ -1,4 +1,4 @@
-/* $Id: process.c,v 1.119 2001/09/07 21:04:40 kanoj Exp $
+/* $Id: process.c,v 1.120 2001/10/02 02:22:26 davem Exp $
X * arch/sparc64/kernel/process.c
X *
X * Copyright (C) 1995, 1996 David S. Miller (da...@caip.rutgers.edu)
diff -u --recursive --new-file v2.4.11/linux/arch/sparc64/kernel/systbls.S linux/arch/sparc64/kernel/systbls.S
--- v2.4.11/linux/arch/sparc64/kernel/systbls.S Wed Aug 23 09:30:13 2000
+++ linux/arch/sparc64/kernel/systbls.S Wed Oct 10 23:42:46 2001
@@ -1,4 +1,4 @@
-/* $Id: systbls.S,v 1.77 2000/08/22 10:09:10 jj Exp $
+/* $Id: systbls.S,v 1.78 2001/10/09 10:54:38 davem Exp $
X * systbls.S: System call entry point tables for OS compatibility.
X * The native Linux system call table lives here also.
X *
@@ -47,7 +47,7 @@
X .word sys_nis_syscall, sys32_setreuid16, sys32_setregid16, sys_rename, sys_truncate
X /*130*/ .word sys_ftruncate, sys_flock, sys_lstat64, sys_nis_syscall, sys_nis_syscall
X .word sys_nis_syscall, sys_mkdir, sys_rmdir, sys32_utimes, sys_stat64
-/*140*/ .word sys_nis_syscall, sys_nis_syscall, sys_nis_syscall, sys_nis_syscall, sys32_getrlimit
+/*140*/ .word sys_nis_syscall, sys_nis_syscall, sys_nis_syscall, sys_gettid, sys32_getrlimit
X .word sys32_setrlimit, sys_pivot_root, sys32_prctl, sys32_pciconfig_read, sys32_pciconfig_write
X /*150*/ .word sys_nis_syscall, sys_nis_syscall, sys_nis_syscall, sys_poll, sys_getdents64
X .word sys32_fcntl64, sys_nis_syscall, sys32_statfs, sys32_fstatfs, sys_oldumount
@@ -106,7 +106,7 @@
X .word sys_recvfrom, sys_setreuid, sys_setregid, sys_rename, sys_truncate
X /*130*/ .word sys_ftruncate, sys_flock, sys_nis_syscall, sys_sendto, sys_shutdown
X .word sys_socketpair, sys_mkdir, sys_rmdir, sys_utimes, sys_nis_syscall
-/*140*/ .word sys_nis_syscall, sys_getpeername, sys_nis_syscall, sys_nis_syscall, sys_getrlimit
+/*140*/ .word sys_nis_syscall, sys_getpeername, sys_nis_syscall, sys_gettid, sys_getrlimit
X .word sys_setrlimit, sys_pivot_root, sys_prctl, sys_pciconfig_read, sys_pciconfig_write
X /*150*/ .word sys_getsockname, sys_nis_syscall, sys_nis_syscall, sys_poll, sys_getdents64
X .word sys_nis_syscall, sys_nis_syscall, sys_statfs, sys_fstatfs, sys_oldumount
diff -u --recursive --new-file v2.4.11/linux/drivers/net/acenic.c linux/drivers/net/acenic.c
--- v2.4.11/linux/drivers/net/acenic.c Tue Oct 9 17:06:51 2001
+++ linux/drivers/net/acenic.c Wed Oct 10 23:23:24 2001
@@ -2,7 +2,7 @@
X * acenic.c: Linux driver for the Alteon AceNIC Gigabit Ethernet card
X * and other Tigon based cards.
X *
- * Copyright 1998-2001 by Jes Sorensen, <j...@linuxcare.com>.
+ * Copyright 1998-2001 by Jes Sorensen, <j...@trained-monkey.org>.
X *
X * Thanks to Alteon and 3Com for providing hardware and documentation
X * enabling me to write this driver.
@@ -145,6 +145,10 @@
X #endif
X
X
+#ifndef MODULE_LICENSE
+#define MODULE_LICENSE(a)
+#endif
+
X #ifndef wmb
X #define wmb() mb()
X #endif
@@ -161,7 +165,7 @@
X #define SMP_CACHE_BYTES L1_CACHE_BYTES
X #endif
X
-#if (BITS_PER_LONG == 64)
+#if (BITS_PER_LONG == 64) || defined(CONFIG_HIGHMEM)
X #define ACE_64BIT_PTR 1
X #endif
X
@@ -263,7 +267,6 @@
X #define pci_set_dma_mask(dev, mask) dev->dma_mask = mask;
X #endif
X
-
X #if (LINUX_VERSION_CODE >= 0x02031b)
X #define NEW_NETINIT
X #define ACE_PROBE_ARG void
@@ -271,6 +274,16 @@
X #define ACE_PROBE_ARG struct net_device *dev
X #endif
X
+#ifndef min_t
+#define min_t(type,a,b) (((a)<(b))?(a):(b))
+#endif
+
+#ifndef ARCH_HAS_PREFETCHW
+#ifndef prefetchw
+#define prefetchw(x) {do{} while(0);}
+#endif
+#endif
+
X #define ACE_MAX_MOD_PARMS 8
X #define BOARD_IDX_STATIC 0
X #define BOARD_IDX_OVERFLOW -1
@@ -514,7 +527,7 @@
X static int dis_pci_mem_inval[ACE_MAX_MOD_PARMS] = {1, 1, 1, 1, 1, 1, 1, 1};
X
X static char version[] __initdata =
- "acenic.c: v0.81 04/20/2001 Jes Sorensen, linux-...@SunSITE.dk\n"
+ "acenic.c: v0.83 09/30/2001 Jes Sorensen, linux-...@SunSITE.dk\n"
X " http://home.cern.ch/~jes/gige/acenic.html\n";
X
X static struct net_device *root_dev;
@@ -746,15 +759,20 @@
X
X #ifdef MODULE
X MODULE_AUTHOR("Jes Sorensen <j...@trained-monkey.org>");
-MODULE_DESCRIPTION("AceNIC/3C985/GA620 Gigabit Ethernet driver");
X MODULE_LICENSE("GPL");
-
+MODULE_DESCRIPTION("AceNIC/3C985/GA620 Gigabit Ethernet driver");
X MODULE_PARM(link, "1-" __MODULE_STRING(8) "i");
X MODULE_PARM(trace, "1-" __MODULE_STRING(8) "i");
X MODULE_PARM(tx_coal_tick, "1-" __MODULE_STRING(8) "i");
X MODULE_PARM(max_tx_desc, "1-" __MODULE_STRING(8) "i");
X MODULE_PARM(rx_coal_tick, "1-" __MODULE_STRING(8) "i");
X MODULE_PARM(max_rx_desc, "1-" __MODULE_STRING(8) "i");
+MODULE_PARM_DESC(link, "Acenic/3C985/NetGear link state");
+MODULE_PARM_DESC(trace, "Acenic/3C985/NetGear firmware trace level");
+MODULE_PARM_DESC(tx_coal_tick, "AceNIC/3C985/GA620 max clock ticks to wait from first tx descriptor arrives");
+MODULE_PARM_DESC(max_tx_desc, "AceNIC/3C985/GA620 max number of transmit descriptors to wait");
+MODULE_PARM_DESC(rx_coal_tick, "AceNIC/3C985/GA620 max clock ticks to wait from first rx descriptor arrives");
+MODULE_PARM_DESC(max_rx_desc, "AceNIC/3C985/GA620 max number of receive descriptors to wait");
X #endif
X
X
@@ -795,14 +813,12 @@
X struct sk_buff *skb = ap->skb->rx_std_skbuff[i].skb;
X
X if (skb) {
-#ifndef DUMMY_PCI_UNMAP
X dma_addr_t mapping;
X
X mapping = ap->skb->rx_std_skbuff[i].mapping;
X pci_unmap_single(ap->pdev, mapping,
X ACE_STD_BUFSIZE - (2 + 16),
X PCI_DMA_FROMDEVICE);
-#endif
X
X ap->rx_std_ring[i].size = 0;
X ap->skb->rx_std_skbuff[i].skb = NULL;
@@ -814,14 +830,13 @@
X struct sk_buff *skb = ap->skb->rx_mini_skbuff[i].skb;
X
X if (skb) {
-#ifndef DUMMY_PCI_UNMAP
X dma_addr_t mapping;
X
X mapping = ap->skb->rx_mini_skbuff[i].mapping;
X pci_unmap_single(ap->pdev, mapping,
X ACE_MINI_BUFSIZE - (2 + 16),
X PCI_DMA_FROMDEVICE);
-#endif
+
X ap->rx_mini_ring[i].size = 0;
X ap->skb->rx_mini_skbuff[i].skb = NULL;
X dev_kfree_skb(skb);
@@ -831,14 +846,12 @@
X for (i = 0; i < RX_JUMBO_RING_ENTRIES; i++) {
X struct sk_buff *skb = ap->skb->rx_jumbo_skbuff[i].skb;
X if (skb) {
-#ifndef DUMMY_PCI_UNMAP
X dma_addr_t mapping;
X
X mapping = ap->skb->rx_jumbo_skbuff[i].mapping;
X pci_unmap_single(ap->pdev, mapping,
X ACE_JUMBO_BUFSIZE - (2 + 16),
X PCI_DMA_FROMDEVICE);
-#endif
X
X ap->rx_jumbo_ring[i].size = 0;
X ap->skb->rx_jumbo_skbuff[i].skb = NULL;
@@ -1766,6 +1779,8 @@
X
X regs = ap->regs;
X
+ prefetchw(&ap->cur_rx_bufs);
+
X idx = ap->rx_std_skbprd;
X
X for (i = 0; i < nr_bufs; i++) {
@@ -1785,9 +1800,7 @@
X ACE_STD_BUFSIZE - (2 + 16),
X PCI_DMA_FROMDEVICE);
X ap->skb->rx_std_skbuff[idx].skb = skb;
-#ifndef DUMMY_PCI_UNMAP
X ap->skb->rx_std_skbuff[idx].mapping = mapping;
-#endif
X
X rd = &ap->rx_std_ring[idx];
X set_aceaddr(&rd->addr, mapping);
@@ -1831,6 +1844,8 @@
X
X regs = ap->regs;
X
+ prefetchw(&ap->cur_mini_bufs);
+
X idx = ap->rx_mini_skbprd;
X for (i = 0; i < nr_bufs; i++) {
X struct sk_buff *skb;
@@ -1849,9 +1864,7 @@
X ACE_MINI_BUFSIZE - (2 + 16),
X PCI_DMA_FROMDEVICE);
X ap->skb->rx_mini_skbuff[idx].skb = skb;
-#ifndef DUMMY_PCI_UNMAP
X ap->skb->rx_mini_skbuff[idx].mapping = mapping;
-#endif
X
X rd = &ap->rx_mini_ring[idx];
X set_aceaddr(&rd->addr, mapping);
@@ -1910,9 +1923,7 @@
X ACE_JUMBO_BUFSIZE - (2 + 16),
X PCI_DMA_FROMDEVICE);
X ap->skb->rx_jumbo_skbuff[idx].skb = skb;
-#ifndef DUMMY_PCI_UNMAP
X ap->skb->rx_jumbo_skbuff[idx].mapping = mapping;
-#endif
X
X rd = &ap->rx_jumbo_ring[idx];
X set_aceaddr(&rd->addr, mapping);
@@ -2067,6 +2078,9 @@
X
X idx = rxretcsm;
X
+ prefetchw(&ap->cur_rx_bufs);
+ prefetchw(&ap->cur_mini_bufs);
+
X while (idx != rxretprd) {
X struct ring_info *rip;
X struct sk_buff *skb;
@@ -2115,15 +2129,9 @@
X
X skb = rip->skb;
X rip->skb = NULL;
-#ifndef DUMMY_PCI_UNMAP
X pci_unmap_single(ap->pdev, rip->mapping, mapsize,
X PCI_DMA_FROMDEVICE);
-#endif
X skb_put(skb, retdesc->size);
-#if 0
- /* unncessary */
- rxdesc->size = 0;
-#endif
X
X /*
X * Fly baby, fly!
@@ -2182,14 +2190,11 @@
X
X do {
X struct sk_buff *skb;
-#ifndef DUMMY_PCI_UNMAP
X dma_addr_t mapping;
-#endif
X struct tx_ring_info *info;
X
X info = ap->skb->tx_skbuff + idx;
X skb = info->skb;
-#ifndef DUMMY_PCI_UNMAP
X mapping = info->mapping;
X
X if (mapping) {
@@ -2197,7 +2202,7 @@
X PCI_DMA_TODEVICE);
X info->mapping = 0;
X }
-#endif
+
X if (skb) {
X ap->stats.tx_packets++;
X ap->stats.tx_bytes += skb->len;
@@ -2474,14 +2479,11 @@
X
X for (i = 0; i < TX_RING_ENTRIES; i++) {
X struct sk_buff *skb;
-#ifndef DUMMY_PCI_UNMAP
X dma_addr_t mapping;
-#endif
X struct tx_ring_info *info;
X
X info = ap->skb->tx_skbuff + i;
X skb = info->skb;
-#ifndef DUMMY_PCI_UNMAP
X mapping = info->mapping;
X
X if (mapping) {
@@ -2490,7 +2492,7 @@
X PCI_DMA_TODEVICE);
X info->mapping = 0;
X }
-#endif
+
X if (skb) {
X dev_kfree_skb(skb);
X info->skb = NULL;
@@ -2516,9 +2518,6 @@
X * For now, let it stay here.
X */
X #if defined(CONFIG_HIGHMEM) && MAX_SKB_FRAGS
-#ifndef DUMMY_PCI_UNMAP
-#error Sorry, cannot DMA from high memory on this architecture.
-#endif
X
X #if defined(CONFIG_X86)
X #define DMAADDR_OFFSET 0
@@ -2565,10 +2564,9 @@
X
X info = ap->skb->tx_skbuff + idx;
X info->skb = tail;
-#ifndef DUMMY_PCI_UNMAP
X info->mapping = addr;
X info->maplen = skb->len;
-#endif
+
X return addr;
X }
X
@@ -2673,10 +2671,9 @@
X } else {
X info->skb = NULL;
X }
-#ifndef DUMMY_PCI_UNMAP
X info->mapping = phys;
X info->maplen = frag->size;
-#endif
+
X ace_load_tx_bd(desc, phys, flagsize);
X }
X }
@@ -2998,7 +2995,7 @@
X
X while (size > 0) {
X tsize = min_t(u32, ((~dest & (ACE_WINDOW_SIZE - 1)) + 1),
- min_t(u32, size, ACE_WINDOW_SIZE));
+ min_t(u32, size, ACE_WINDOW_SIZE));
X tdest = (unsigned long)&regs->Window +
X (dest & (ACE_WINDOW_SIZE - 1));
X writel(dest & ~(ACE_WINDOW_SIZE - 1), &regs->WinBase);
diff -u --recursive --new-file v2.4.11/linux/drivers/net/acenic.h linux/drivers/net/acenic.h
--- v2.4.11/linux/drivers/net/acenic.h Tue Jul 3 17:08:20 2001
+++ linux/drivers/net/acenic.h Wed Oct 10 23:23:24 2001
@@ -582,28 +582,21 @@
X aceaddr stats2_ptr;
X };
X
-#if defined(CONFIG_X86) || defined(CONFIG_PPC)
-/* Intel has null pci_unmap_single, no reasons to remember mapping. */
-#define DUMMY_PCI_UNMAP
-#endif
X
X struct ring_info {
X struct sk_buff *skb;
-#ifndef DUMMY_PCI_UNMAP
X dma_addr_t mapping;
-#endif
X };
X
-/* Funny... As soon as we add maplen on alpha, it starts to work
+/*
+ * Funny... As soon as we add maplen on alpha, it starts to work
X * much slower. Hmm... is it because struct does not fit to one cacheline?
X * So, split tx_ring_info.
X */
X struct tx_ring_info {
X struct sk_buff *skb;
-#ifndef DUMMY_PCI_UNMAP
X dma_addr_t mapping;
X int maplen;
-#endif
X };
X
X /*
diff -u --recursive --new-file v2.4.11/linux/drivers/net/aironet4500.h linux/drivers/net/aironet4500.h
--- v2.4.11/linux/drivers/net/aironet4500.h Wed Jul 25 17:10:21 2001
+++ linux/drivers/net/aironet4500.h Wed Oct 10 23:23:24 2001
@@ -1531,7 +1531,6 @@
X extern int awc_start_xmit(struct sk_buff *, struct net_device *);
X extern void awc_interrupt(int irq, void *dev_id, struct pt_regs *regs);
X extern struct net_device_stats * awc_get_stats(struct net_device *dev);
-extern int awc_rx(struct net_device *dev, struct awc_fid * rx_fid);
X extern void awc_set_multicast_list(struct net_device *dev);
X extern int awc_change_mtu(struct net_device *dev, int new_mtu);
X extern int awc_close(struct net_device *dev);
diff -u --recursive --new-file v2.4.11/linux/drivers/net/at1700.c linux/drivers/net/at1700.c
--- v2.4.11/linux/drivers/net/at1700.c Tue Oct 9 17:06:51 2001
+++ linux/drivers/net/at1700.c Wed Oct 10 23:24:09 2001
@@ -158,7 +158,7 @@
X extern int at1700_probe(struct net_device *dev);
X
X static int at1700_probe1(struct net_device *dev, int ioaddr);
-static int read_eeprom(int ioaddr, int location);
+static int read_eeprom(long ioaddr, int location);
X static int net_open(struct net_device *dev);
X static int net_send_packet(struct sk_buff *skb, struct net_device *dev);
X static void net_interrupt(int irq, void *dev_id, struct pt_regs *regs);
diff -u --recursive --new-file v2.4.11/linux/drivers/net/macsonic.c linux/drivers/net/macsonic.c
--- v2.4.11/linux/drivers/net/macsonic.c Sun Sep 23 11:40:58 2001
+++ linux/drivers/net/macsonic.c Wed Oct 10 23:23:24 2001
@@ -168,6 +168,8 @@
X if ((lp->rba = (char *)
X kmalloc(SONIC_NUM_RRS * SONIC_RBSIZE, GFP_KERNEL | GFP_DMA)) == NULL) {
X printk(KERN_ERR "%s: couldn't allocate receive buffers\n", dev->name);
+ kfree(lp->sonic_desc);
+ lp->sonic_desc = NULL;
X return -ENOMEM;
X }
X
@@ -322,7 +324,7 @@
X /* methinks this will always be true but better safe than sorry */
X if (dev->priv == NULL) {
X dev->priv = kmalloc(sizeof(struct sonic_local), GFP_KERNEL);
- if (!dev->priv) /* FIXME: kfree dev if necessary */
+ if (!dev->priv)
X return -ENOMEM;
X }
X } else {
@@ -518,9 +520,14 @@
X
X if (dev) {
X dev = init_etherdev(dev, sizeof(struct sonic_local));
+ if (!dev)
+ return -ENOMEM;
X /* methinks this will always be true but better safe than sorry */
- if (dev->priv == NULL)
+ if (dev->priv == NULL) {
X dev->priv = kmalloc(sizeof(struct sonic_local), GFP_KERNEL);
+ if (!dev->priv) /* FIXME: kfree dev if necessary */
+ return -ENOMEM;
+ }
X } else {
X dev = init_etherdev(NULL, sizeof(struct sonic_local));
X }
diff -u --recursive --new-file v2.4.11/linux/drivers/net/sk98lin/skge.c linux/drivers/net/sk98lin/skge.c
--- v2.4.11/linux/drivers/net/sk98lin/skge.c Tue Oct 9 17:06:52 2001
+++ linux/drivers/net/sk98lin/skge.c Wed Oct 10 23:23:24 2001
@@ -228,7 +228,7 @@
X * <linux/string.h>
X * <linux/errno.h>
X * <linux/ioport.h>
- * <linux/malloc.h>
+ * <linux/slab.h>
X * <linux/interrupt.h>
X * <linux/pci.h>
X * <asm/byteorder.h>
diff -u --recursive --new-file v2.4.11/linux/drivers/net/sonic.c linux/drivers/net/sonic.c
--- v2.4.11/linux/drivers/net/sonic.c Tue Feb 13 13:15:05 2001
+++ linux/drivers/net/sonic.c Wed Oct 10 23:23:24 2001
@@ -28,13 +28,13 @@
X */
X static int sonic_open(struct net_device *dev)
X {
- if (sonic_debug > 2)
- printk("sonic_open: initializing sonic driver.\n");
-
- /*
- * We don't need to deal with auto-irq stuff since we
- * hardwire the sonic interrupt.
- */
+ if (sonic_debug > 2)
+ printk("sonic_open: initializing sonic driver.\n");
+
+ /*
+ * We don't need to deal with auto-irq stuff since we
+ * hardwire the sonic interrupt.
+ */
X /*
X * XXX Horrible work around: We install sonic_interrupt as fast interrupt.
X * This means that during execution of the handler interrupt are disabled
@@ -42,335 +42,339 @@
X * this glue works ok under all situations.
X */
X // if (sonic_request_irq(dev->irq, &sonic_interrupt, 0, "sonic", dev)) {
- if (sonic_request_irq(dev->irq, &sonic_interrupt, SA_INTERRUPT, "sonic", dev)) {
- printk ("\n%s: unable to get IRQ %d .\n", dev->name, dev->irq);
- return -EAGAIN;
- }
-
- /*
- * Initialize the SONIC
- */
- sonic_init(dev);
-
- dev->tbusy = 0;
- dev->interrupt = 0;
- dev->start = 1;
-
- if (sonic_debug > 2)
- printk("sonic_open: Initialization done.\n");
-
- return 0;
+ if (sonic_request_irq(dev->irq, &sonic_interrupt, SA_INTERRUPT,
+ "sonic", dev)) {
+ printk("\n%s: unable to get IRQ %d .\n", dev->name, dev->irq);
+ return -EAGAIN;
+ }
+
+ /*
+ * Initialize the SONIC
+ */
+ sonic_init(dev);
+
+ netif_start_queue(dev);
+
+ if (sonic_debug > 2)
+ printk("sonic_open: Initialization done.\n");
+
+ return 0;
X }
X
X
X /*
X * Close the SONIC device
X */
-static int
-sonic_close(struct net_device *dev)
+static int sonic_close(struct net_device *dev)
X {
- unsigned int base_addr = dev->base_addr;
-
- if (sonic_debug > 2)
- printk ("sonic_close\n");
-
- dev->tbusy = 1;
- dev->start = 0;
-
- /*
- * stop the SONIC, disable interrupts
- */
- SONIC_WRITE(SONIC_ISR,0x7fff);
- SONIC_WRITE(SONIC_IMR,0);
- SONIC_WRITE(SONIC_CMD,SONIC_CR_RST);
+ unsigned int base_addr = dev->base_addr;
+
+ if (sonic_debug > 2)
+ printk("sonic_close\n");
+
+ netif_stop_queue(dev);
+
+ /*
+ * stop the SONIC, disable interrupts
+ */
+ SONIC_WRITE(SONIC_ISR, 0x7fff);
+ SONIC_WRITE(SONIC_IMR, 0);
+ SONIC_WRITE(SONIC_CMD, SONIC_CR_RST);
X
- sonic_free_irq(dev->irq, dev); /* release the IRQ */
+ sonic_free_irq(dev->irq, dev); /* release the IRQ */
X
- return 0;
+ return 0;
X }
X
+static void sonic_tx_timeout(struct net_device *dev)
+{
+ struct sonic_local *lp = (struct sonic_local *) dev->priv;
+ printk("%s: transmit timed out.\n", dev->name);
+
+ /* Try to restart the adaptor. */
+ sonic_init(dev);
+ lp->stats.tx_errors++;
+ dev->trans_start = jiffies;
+ netif_wake_queue(dev);
+}
X
X /*
X * transmit packet
X */
X static int sonic_send_packet(struct sk_buff *skb, struct net_device *dev)
X {
- struct sonic_local *lp = (struct sonic_local *)dev->priv;
- unsigned int base_addr = dev->base_addr;
- unsigned int laddr;
- int entry,length;
-
- if (sonic_debug > 2)
- printk("sonic_send_packet: skb=%p, dev=%p\n",skb,dev);
-
- if (dev->tbusy) {
- int tickssofar = jiffies - dev->trans_start;
-
- /* If we get here, some higher level has decided we are broken.
- There should really be a "kick me" function call instead. */
-
- if (sonic_debug > 1)
- printk("sonic_send_packet: called with dev->tbusy = 1 !\n");
-
- if (tickssofar < 5)
- return 1;
-
- printk("%s: transmit timed out.\n", dev->name);
-
- /* Try to restart the adaptor. */
- sonic_init(dev);
- dev->tbusy=0;
+ struct sonic_local *lp = (struct sonic_local *) dev->priv;
+ unsigned int base_addr = dev->base_addr;
+ unsigned int laddr;
+ int entry, length;
+
+ netif_stop_queue(dev);
+
+ if (sonic_debug > 2)
+ printk("sonic_send_packet: skb=%p, dev=%p\n", skb, dev);
+
+ /*
+ * 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 (test_and_set_bit(0, (void *) &dev->tbusy) != 0) {
+ printk("%s: Transmitter access conflict.\n", dev->name);
+ return 1;
+ }
+
+ /*
+ * Map the packet data into the logical DMA address space
+ */
+ if ((laddr = vdma_alloc(PHYSADDR(skb->data), skb->len)) == ~0UL) {
+ printk("%s: no VDMA entry for transmit available.\n",
+ dev->name);
+ dev_kfree_skb(skb);
+ netif_start_queue(dev);
+ return 1;
+ }
+ entry = lp->cur_tx & SONIC_TDS_MASK;
+ lp->tx_laddr[entry] = laddr;
+ lp->tx_skb[entry] = skb;
+
+ length = (skb->len < ETH_ZLEN) ? ETH_ZLEN : skb->len;
+ flush_cache_all();
+
+ /*
+ * Setup the transmit descriptor and issue the transmit command.
+ */
+ lp->tda[entry].tx_status = 0; /* clear status */
+ lp->tda[entry].tx_frag_count = 1; /* single fragment */
+ lp->tda[entry].tx_pktsize = length; /* length of packet */
+ lp->tda[entry].tx_frag_ptr_l = laddr & 0xffff;
+ lp->tda[entry].tx_frag_ptr_h = laddr >> 16;
+ lp->tda[entry].tx_frag_size = length;
+ lp->cur_tx++;
+ lp->stats.tx_bytes += length;
+
+ if (sonic_debug > 2)
+ printk("sonic_send_packet: issueing Tx command\n");
+
+ SONIC_WRITE(SONIC_CMD, SONIC_CR_TXP);
+
X dev->trans_start = jiffies;
- }
X
- /*
- * 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 (test_and_set_bit(0, (void*)&dev->tbusy) != 0) {
- printk("%s: Transmitter access conflict.\n", dev->name);
- return 1;
- }
-
- /*
- * Map the packet data into the logical DMA address space
- */
- if ((laddr = vdma_alloc(PHYSADDR(skb->data),skb->len)) == ~0UL) {
- printk("%s: no VDMA entry for transmit available.\n",dev->name);
- dev_kfree_skb(skb);
- dev->tbusy = 0;
- return 1;
- }
- entry = lp->cur_tx & SONIC_TDS_MASK;
- lp->tx_laddr[entry] = laddr;
- lp->tx_skb[entry] = skb;
-
- length = (skb->len < ETH_ZLEN) ? ETH_ZLEN : skb->len;
- flush_cache_all();
-
- /*
- * Setup the transmit descriptor and issue the transmit command.
- */
- lp->tda[entry].tx_status = 0; /* clear status */
- lp->tda[entry].tx_frag_count = 1; /* single fragment */
- lp->tda[entry].tx_pktsize = length; /* length of packet */
- lp->tda[entry].tx_frag_ptr_l = laddr & 0xffff;
- lp->tda[entry].tx_frag_ptr_h = laddr >> 16;
- lp->tda[entry].tx_frag_size = length;
- lp->cur_tx++;
- lp->stats.tx_bytes += length;
-
- if (sonic_debug > 2)
- printk("sonic_send_packet: issueing Tx command\n");
-
- SONIC_WRITE(SONIC_CMD,SONIC_CR_TXP);
-
- dev->trans_start = jiffies;
-
- if (lp->cur_tx < lp->dirty_tx + SONIC_NUM_TDS)
- dev->tbusy = 0;
- else
- lp->tx_full = 1;
-
- return 0;
+ if (lp->cur_tx < lp->dirty_tx + SONIC_NUM_TDS)
+ netif_start_queue(dev);
+ else
+ lp->tx_full = 1;
+
+ return 0;
X }
X
-
X /*
X * The typical workload of the driver:
X * Handle the network interface interrupts.
X */
-static void
-sonic_interrupt(int irq, void *dev_id, struct pt_regs * regs)
+static void sonic_interrupt(int irq, void *dev_id, struct pt_regs *regs)
X {
- struct net_device *dev = (struct net_device *)dev_id;
- unsigned int base_addr = dev->base_addr;
- struct sonic_local *lp;
- int status;
-
- if (dev == NULL) {
- printk ("sonic_interrupt: irq %d for unknown device.\n", irq);
- return;
- }
- dev->interrupt = 1;
- lp = (struct sonic_local *)dev->priv;
-
- status = SONIC_READ(SONIC_ISR);
- SONIC_WRITE(SONIC_ISR,0x7fff); /* clear all bits */
-
- if (sonic_debug > 2)
- printk("sonic_interrupt: ISR=%x\n",status);
-
- if (status & SONIC_INT_PKTRX) {
- sonic_rx(dev); /* got packet(s) */
- }
-
- if (status & SONIC_INT_TXDN) {
- int dirty_tx = lp->dirty_tx;
-
- while (dirty_tx < lp->cur_tx) {
- int entry = dirty_tx & SONIC_TDS_MASK;
- int status = lp->tda[entry].tx_status;
-
- if (sonic_debug > 3)
- printk ("sonic_interrupt: status %d, cur_tx %d, dirty_tx %d\n",
- status,lp->cur_tx,lp->dirty_tx);
-
- if (status == 0) {
- /* It still hasn't been Txed, kick the sonic again */
- SONIC_WRITE(SONIC_CMD,SONIC_CR_TXP);
- break;
- }
-
- /* put back EOL and free descriptor */
- lp->tda[entry].tx_frag_count = 0;
- lp->tda[entry].tx_status = 0;
-
- if (status & 0x0001)
- lp->stats.tx_packets++;
- else {
+ struct net_device *dev = (struct net_device *) dev_id;
+ unsigned int base_addr = dev->base_addr;
+ struct sonic_local *lp;
+ int status;
+
+ if (dev == NULL) {
+ printk("sonic_interrupt: irq %d for unknown device.\n", irq);
+ return;
+ }
+
+ lp = (struct sonic_local *) dev->priv;
+
+ status = SONIC_READ(SONIC_ISR);
+ SONIC_WRITE(SONIC_ISR, 0x7fff); /* clear all bits */
+
+ if (sonic_debug > 2)
+ printk("sonic_interrupt: ISR=%x\n", status);
+
+ if (status & SONIC_INT_PKTRX) {
+ sonic_rx(dev); /* got packet(s) */
+ }
+
+ if (status & SONIC_INT_TXDN) {
+ int dirty_tx = lp->dirty_tx;
+
+ while (dirty_tx < lp->cur_tx) {
+ int entry = dirty_tx & SONIC_TDS_MASK;
+ int status = lp->tda[entry].tx_status;
+
+ if (sonic_debug > 3)
+ printk
+ ("sonic_interrupt: status %d, cur_tx %d, dirty_tx %d\n",
+ status, lp->cur_tx, lp->dirty_tx);
+
+ if (status == 0) {
+ /* It still hasn't been Txed, kick the sonic again */
+ SONIC_WRITE(SONIC_CMD, SONIC_CR_TXP);
+ break;
+ }
+
+ /* put back EOL and free descriptor */
+ lp->tda[entry].tx_frag_count = 0;
+ lp->tda[entry].tx_status = 0;
+
+ if (status & 0x0001)
+ lp->stats.tx_packets++;
+ else {
+ lp->stats.tx_errors++;
+ if (status & 0x0642)
+ lp->stats.tx_aborted_errors++;
+ if (status & 0x0180)
+ lp->stats.tx_carrier_errors++;
+ if (status & 0x0020)
+ lp->stats.tx_window_errors++;
+ if (status & 0x0004)
+ lp->stats.tx_fifo_errors++;
+ }
+
+ /* We must free the original skb */
+ if (lp->tx_skb[entry]) {
+ dev_kfree_skb(lp->tx_skb[entry]);
+ lp->tx_skb[entry] = 0;
+ }
+ /* and the VDMA address */
+ vdma_free(lp->tx_laddr[entry]);
+ dirty_tx++;
+ }
+
+ if (lp->tx_full
+ && dirty_tx + SONIC_NUM_TDS > lp->cur_tx + 2) {
+ /* The ring is no longer full, clear tbusy. */
+ lp->tx_full = 0;
+ netif_wake_queue(dev);
+ }
+
+ lp->dirty_tx = dirty_tx;
+ }
+
+ /*
+ * check error conditions
+ */
+ if (status & SONIC_INT_RFO) {
+ printk("%s: receive fifo underrun\n", dev->name);
+ lp->stats.rx_fifo_errors++;
+ }
+ if (status & SONIC_INT_RDE) {
+ printk("%s: receive descriptors exhausted\n", dev->name);
+ lp->stats.rx_dropped++;
+ }
+ if (status & SONIC_INT_RBE) {
+ printk("%s: receive buffer exhausted\n", dev->name);
+ lp->stats.rx_dropped++;
+ }
+ if (status & SONIC_INT_RBAE) {
+ printk("%s: receive buffer area exhausted\n", dev->name);
+ lp->stats.rx_dropped++;
+ }
+
+ /* counter overruns; all counters are 16bit wide */
+ if (status & SONIC_INT_FAE)
+ lp->stats.rx_frame_errors += 65536;
+ if (status & SONIC_INT_CRC)
+ lp->stats.rx_crc_errors += 65536;
+ if (status & SONIC_INT_MP)
+ lp->stats.rx_missed_errors += 65536;
+
+ /* transmit error */
+ if (status & SONIC_INT_TXER)
X lp->stats.tx_errors++;
- if (status & 0x0642) lp->stats.tx_aborted_errors++;
- if (status & 0x0180) lp->stats.tx_carrier_errors++;
- if (status & 0x0020) lp->stats.tx_window_errors++;
- if (status & 0x0004) lp->stats.tx_fifo_errors++;
- }
-
- /* We must free the original skb */
- if (lp->tx_skb[entry]) {
- dev_kfree_skb(lp->tx_skb[entry]);
- lp->tx_skb[entry] = 0;
- }
- /* and the VDMA address */
- vdma_free(lp->tx_laddr[entry]);
- dirty_tx++;
- }
-
- if (lp->tx_full && dev->tbusy
- && dirty_tx + SONIC_NUM_TDS > lp->cur_tx + 2) {
- /* The ring is no longer full, clear tbusy. */
- lp->tx_full = 0;
- dev->tbusy = 0;
- mark_bh(NET_BH);
- }
-
- lp->dirty_tx = dirty_tx;
- }
-
- /*
- * check error conditions
- */
- if (status & SONIC_INT_RFO) {
- printk ("%s: receive fifo underrun\n",dev->name);
- lp->stats.rx_fifo_errors++;
- }
- if (status & SONIC_INT_RDE) {
- printk ("%s: receive descriptors exhausted\n",dev->name);
- lp->stats.rx_dropped++;
- }
- if (status & SONIC_INT_RBE) {
- printk ("%s: receive buffer exhausted\n",dev->name);
- lp->stats.rx_dropped++;
- }
- if (status & SONIC_INT_RBAE) {
- printk ("%s: receive buffer area exhausted\n",dev->name);
- lp->stats.rx_dropped++;
- }
-
- /* counter overruns; all counters are 16bit wide */
- if (status & SONIC_INT_FAE)
- lp->stats.rx_frame_errors += 65536;
- if (status & SONIC_INT_CRC)
- lp->stats.rx_crc_errors += 65536;
- if (status & SONIC_INT_MP)
- lp->stats.rx_missed_errors += 65536;
-
- /* transmit error */
- if (status & SONIC_INT_TXER)
- lp->stats.tx_errors++;
-
- /*
- * clear interrupt bits and return
- */
- SONIC_WRITE(SONIC_ISR,status);
- dev->interrupt = 0;
- return;
+
+ /*
+ * clear interrupt bits and return
+ */
+ SONIC_WRITE(SONIC_ISR, status);
X }
X
X /*
X * We have a good packet(s), get it/them out of the buffers.
X */
-static void
-sonic_rx(struct net_device *dev)
+static void sonic_rx(struct net_device *dev)
X {
- unsigned int base_addr = dev->base_addr;
- struct sonic_local *lp = (struct sonic_local *)dev->priv;
- sonic_rd_t *rd = &lp->rda[lp->cur_rx & SONIC_RDS_MASK];
- int status;
-
- while (rd->in_use == 0) {
- struct sk_buff *skb;
- int pkt_len;
- unsigned char *pkt_ptr;
-
- status = rd->rx_status;
- if (sonic_debug > 3)
- printk ("status %x, cur_rx %d, cur_rra %x\n",status,lp->cur_rx,lp->cur_rra);
- if (status & SONIC_RCR_PRX) {
- pkt_len = rd->rx_pktlen;
- pkt_ptr = (char *)sonic_chiptomem((rd->rx_pktptr_h << 16) +
- rd->rx_pktptr_l);
-
- if (sonic_debug > 3)
- printk ("pktptr %p (rba %p) h:%x l:%x, bsize h:%x l:%x\n", pkt_ptr,lp->rba,
- rd->rx_pktptr_h,rd->rx_pktptr_l,
- SONIC_READ(SONIC_RBWC1),SONIC_READ(SONIC_RBWC0));
-
- /* Malloc up new buffer. */
- skb = dev_alloc_skb(pkt_len+2);
- if (skb == NULL) {
- printk("%s: Memory squeeze, dropping packet.\n", dev->name);
- lp->stats.rx_dropped++;
- break;
- }
- skb->dev = dev;
- skb_reserve(skb,2); /* 16 byte align */
- skb_put(skb,pkt_len); /* Make room */
- eth_copy_and_sum(skb, pkt_ptr, pkt_len, 0);
- skb->protocol=eth_type_trans(skb,dev);
- netif_rx(skb); /* pass the packet to upper layers */
- dev->last_rx = jiffies;
- lp->stats.rx_packets++;
- lp->stats.rx_bytes += pkt_len;
-
- } else {
- /* This should only happen, if we enable accepting broken packets. */
- lp->stats.rx_errors++;
- if (status & SONIC_RCR_FAER) lp->stats.rx_frame_errors++;
- if (status & SONIC_RCR_CRCR) lp->stats.rx_crc_errors++;
- }
-
- rd->in_use = 1;
- rd = &lp->rda[(++lp->cur_rx) & SONIC_RDS_MASK];
- /* now give back the buffer to the receive buffer area */
- if (status & SONIC_RCR_LPKT) {
- /*
- * this was the last packet out of the current receice buffer
- * give the buffer back to the SONIC
- */
- lp->cur_rra += sizeof(sonic_rr_t);
- if (lp->cur_rra > (lp->rra_laddr + (SONIC_NUM_RRS-1) * sizeof(sonic_rr_t)))
- lp->cur_rra = lp->rra_laddr;
- SONIC_WRITE(SONIC_RWP, lp->cur_rra & 0xffff);
- } else
- printk ("%s: rx desc without RCR_LPKT. Shouldn't happen !?\n",dev->name);
- }
- /*
- * If any worth-while packets have been received, dev_rint()
- * has done a mark_bh(NET_BH) for us and will work on them
- * when we get to the bottom-half routine.
- */
- return;
+ unsigned int base_addr = dev->base_addr;
+ struct sonic_local *lp = (struct sonic_local *) dev->priv;
+ sonic_rd_t *rd = &lp->rda[lp->cur_rx & SONIC_RDS_MASK];
+ int status;
+
+ while (rd->in_use == 0) {
+ struct sk_buff *skb;
+ int pkt_len;
+ unsigned char *pkt_ptr;
+
+ status = rd->rx_status;
+ if (sonic_debug > 3)
+ printk("status %x, cur_rx %d, cur_rra %x\n",
+ status, lp->cur_rx, lp->cur_rra);
+ if (status & SONIC_RCR_PRX) {
+ pkt_len = rd->rx_pktlen;
+ pkt_ptr =
+ (char *)
+ sonic_chiptomem((rd->rx_pktptr_h << 16) +
+ rd->rx_pktptr_l);
+
+ if (sonic_debug > 3)
+ printk
+ ("pktptr %p (rba %p) h:%x l:%x, bsize h:%x l:%x\n",
+ pkt_ptr, lp->rba, rd->rx_pktptr_h,
+ rd->rx_pktptr_l,
+ SONIC_READ(SONIC_RBWC1),
+ SONIC_READ(SONIC_RBWC0));
+
+ /* Malloc up new buffer. */
+ skb = dev_alloc_skb(pkt_len + 2);
+ if (skb == NULL) {
+ printk
+ ("%s: Memory squeeze, dropping packet.\n",
+ dev->name);
+ lp->stats.rx_dropped++;
+ break;
+ }
+ skb->dev = dev;
+ skb_reserve(skb, 2); /* 16 byte align */
+ skb_put(skb, pkt_len); /* Make room */
+ eth_copy_and_sum(skb, pkt_ptr, pkt_len, 0);
+ skb->protocol = eth_type_trans(skb, dev);
+ netif_rx(skb); /* pass the packet to upper layers */
+ dev->last_rx = jiffies;
+ lp->stats.rx_packets++;
+ lp->stats.rx_bytes += pkt_len;
+
+ } else {
+ /* This should only happen, if we enable accepting broken packets. */
+ lp->stats.rx_errors++;
+ if (status & SONIC_RCR_FAER)
+ lp->stats.rx_frame_errors++;
+ if (status & SONIC_RCR_CRCR)
+ lp->stats.rx_crc_errors++;
+ }
+
+ rd->in_use = 1;
+ rd = &lp->rda[(++lp->cur_rx) & SONIC_RDS_MASK];
+ /* now give back the buffer to the receive buffer area */
+ if (status & SONIC_RCR_LPKT) {
+ /*
+ * this was the last packet out of the current receice buffer
+ * give the buffer back to the SONIC
+ */
+ lp->cur_rra += sizeof(sonic_rr_t);
+ if (lp->cur_rra >
+ (lp->rra_laddr +
+ (SONIC_NUM_RRS -
+ 1) * sizeof(sonic_rr_t))) lp->cur_rra =
+ lp->rra_laddr;
+ SONIC_WRITE(SONIC_RWP, lp->cur_rra & 0xffff);
+ } else
+ printk
+ ("%s: rx desc without RCR_LPKT. Shouldn't happen !?\n",
+ dev->name);
+ }
+ /*
+ * If any worth-while packets have been received, dev_rint()
+ * has done a mark_bh(NET_BH) for us and will work on them
+ * when we get to the bottom-half routine.
+ */
X }
X
X
@@ -378,68 +382,71 @@
X * Get the current statistics.
X * This may be called with the device open or closed.
X */
-static struct net_device_stats *
-sonic_get_stats(struct net_device *dev)
+static struct net_device_stats *sonic_get_stats(struct net_device *dev)
X {
- struct sonic_local *lp = (struct sonic_local *)dev->priv;
- unsigned int base_addr = dev->base_addr;
+ struct sonic_local *lp = (struct sonic_local *) dev->priv;
+ unsigned int base_addr = dev->base_addr;
+
+ /* read the tally counter from the SONIC and reset them */
+ lp->stats.rx_crc_errors += SONIC_READ(SONIC_CRCT);
+ SONIC_WRITE(SONIC_CRCT, 0xffff);
+ lp->stats.rx_frame_errors += SONIC_READ(SONIC_FAET);
+ SONIC_WRITE(SONIC_FAET, 0xffff);
+ lp->stats.rx_missed_errors += SONIC_READ(SONIC_MPT);
+ SONIC_WRITE(SONIC_MPT, 0xffff);
X
- /* read the tally counter from the SONIC and reset them */
- lp->stats.rx_crc_errors += SONIC_READ(SONIC_CRCT);
- SONIC_WRITE(SONIC_CRCT,0xffff);
- lp->stats.rx_frame_errors += SONIC_READ(SONIC_FAET);
- SONIC_WRITE(SONIC_FAET,0xffff);
- lp->stats.rx_missed_errors += SONIC_READ(SONIC_MPT);
- SONIC_WRITE(SONIC_MPT,0xffff);
-
- return &lp->stats;
+ return &lp->stats;
X }
X
X
X /*
X * Set or clear the multicast filter for this adaptor.
X */
-static void
-sonic_multicast_list(struct net_device *dev)
+static void sonic_multicast_list(struct net_device *dev)
X {
- struct sonic_local *lp = (struct sonic_local *)dev->priv;
- unsigned int base_addr = dev->base_addr;
- unsigned int rcr;
- struct dev_mc_list *dmi = dev->mc_list;
- unsigned char *addr;
- int i;
-
- rcr = SONIC_READ(SONIC_RCR) & ~(SONIC_RCR_PRO | SONIC_RCR_AMC);
- rcr |= SONIC_RCR_BRD; /* accept broadcast packets */
-
- if (dev->flags & IFF_PROMISC) { /* set promiscuous mode */
- rcr |= SONIC_RCR_PRO;
- } else {
- if ((dev->flags & IFF_ALLMULTI) || (dev->mc_count > 15)) {
- rcr |= SONIC_RCR_AMC;
+ struct sonic_local *lp = (struct sonic_local *) dev->priv;
+ unsigned int base_addr = dev->base_addr;
+ unsigned int rcr;
+ struct dev_mc_list *dmi = dev->mc_list;
+ unsigned char *addr;
+ int i;
+
+ rcr = SONIC_READ(SONIC_RCR) & ~(SONIC_RCR_PRO | SONIC_RCR_AMC);
+ rcr |= SONIC_RCR_BRD; /* accept broadcast packets */
+
+ if (dev->flags & IFF_PROMISC) { /* set promiscuous mode */
+ rcr |= SONIC_RCR_PRO;
X } else {
- if (sonic_debug > 2)
- printk ("sonic_multicast_list: mc_count %d\n",dev->mc_count);
- lp->cda.cam_enable = 1; /* always enable our own address */
- for (i = 1; i <= dev->mc_count; i++) {
- addr = dmi->dmi_addr;
- dmi = dmi->next;
- lp->cda.cam_desc[i].cam_cap0 = addr[1] << 8 | addr[0];
- lp->cda.cam_desc[i].cam_cap1 = addr[3] << 8 | addr[2];
- lp->cda.cam_desc[i].cam_cap2 = addr[5] << 8 | addr[4];
- lp->cda.cam_enable |= (1 << i);
- }
- SONIC_WRITE(SONIC_CDC,16);
- /* issue Load CAM command */
- SONIC_WRITE(SONIC_CDP, lp->cda_laddr & 0xffff);
- SONIC_WRITE(SONIC_CMD,SONIC_CR_LCAM);
- }
- }
-
- if (sonic_debug > 2)
- printk("sonic_multicast_list: setting RCR=%x\n",rcr);
-
- SONIC_WRITE(SONIC_RCR,rcr);
+ if ((dev->flags & IFF_ALLMULTI) || (dev->mc_count > 15)) {
+ rcr |= SONIC_RCR_AMC;
+ } else {
+ if (sonic_debug > 2)
+ printk
+ ("sonic_multicast_list: mc_count %d\n",
+ dev->mc_count);
+ lp->cda.cam_enable = 1; /* always enable our own address */
+ for (i = 1; i <= dev->mc_count; i++) {
+ addr = dmi->dmi_addr;
+ dmi = dmi->next;
+ lp->cda.cam_desc[i].cam_cap0 =
+ addr[1] << 8 | addr[0];
+ lp->cda.cam_desc[i].cam_cap1 =
+ addr[3] << 8 | addr[2];
+ lp->cda.cam_desc[i].cam_cap2 =
+ addr[5] << 8 | addr[4];
+ lp->cda.cam_enable |= (1 << i);
+ }
+ SONIC_WRITE(SONIC_CDC, 16);
+ /* issue Load CAM command */
+ SONIC_WRITE(SONIC_CDP, lp->cda_laddr & 0xffff);
+ SONIC_WRITE(SONIC_CMD, SONIC_CR_LCAM);
+ }
+ }
+
+ if (sonic_debug > 2)
+ printk("sonic_multicast_list: setting RCR=%x\n", rcr);
+
+ SONIC_WRITE(SONIC_RCR, rcr);
X }
X
X
@@ -448,168 +455,168 @@
X */
X static int sonic_init(struct net_device *dev)
X {
- unsigned int base_addr = dev->base_addr;
- unsigned int cmd;
- struct sonic_local *lp = (struct sonic_local *)dev->priv;
- unsigned int rra_start;
- unsigned int rra_end;
- int i;
-
- /*
- * put the Sonic into software-reset mode and
- * disable all interrupts
- */
- SONIC_WRITE(SONIC_ISR,0x7fff);
- SONIC_WRITE(SONIC_IMR,0);
- SONIC_WRITE(SONIC_CMD,SONIC_CR_RST);
-
- /*
- * clear software reset flag, disable receiver, clear and
- * enable interrupts, then completely initialize the SONIC
- */
- SONIC_WRITE(SONIC_CMD,0);
- SONIC_WRITE(SONIC_CMD,SONIC_CR_RXDIS);
-
- /*
- * initialize the receive resource area
- */
- if (sonic_debug > 2)
- printk ("sonic_init: initialize receive resource area\n");
-
- rra_start = lp->rra_laddr & 0xffff;
- rra_end = (rra_start + (SONIC_NUM_RRS * sizeof(sonic_rr_t))) & 0xffff;
-
- for (i = 0; i < SONIC_NUM_RRS; i++) {
- lp->rra[i].rx_bufadr_l = (lp->rba_laddr + i * SONIC_RBSIZE) & 0xffff;
- lp->rra[i].rx_bufadr_h = (lp->rba_laddr + i * SONIC_RBSIZE) >> 16;
- lp->rra[i].rx_bufsize_l = SONIC_RBSIZE >> 1;
- lp->rra[i].rx_bufsize_h = 0;
- }
-
- /* initialize all RRA registers */
- SONIC_WRITE(SONIC_RSA,rra_start);
- SONIC_WRITE(SONIC_REA,rra_end);
- SONIC_WRITE(SONIC_RRP,rra_start);
- SONIC_WRITE(SONIC_RWP,rra_end);
- SONIC_WRITE(SONIC_URRA,lp->rra_laddr >> 16);
- SONIC_WRITE(SONIC_EOBC,(SONIC_RBSIZE-2) >> 1);
-
- lp->cur_rra = lp->rra_laddr + (SONIC_NUM_RRS-1) * sizeof(sonic_rr_t);
-
- /* load the resource pointers */
- if (sonic_debug > 3)
- printk("sonic_init: issueing RRRA command\n");
-
- SONIC_WRITE(SONIC_CMD,SONIC_CR_RRRA);
- i = 0;
- while (i++ < 100) {
- if (SONIC_READ(SONIC_CMD) & SONIC_CR_RRRA)
- break;
- }
-
- if (sonic_debug > 2)
- printk("sonic_init: status=%x\n",SONIC_READ(SONIC_CMD));
-
- /*
- * Initialize the receive descriptors so that they
- * become a circular linked list, ie. let the last
- * descriptor point to the first again.
- */
- if (sonic_debug > 2)
- printk ("sonic_init: initialize receive descriptors\n");
- for (i=0; i<SONIC_NUM_RDS; i++) {
- lp->rda[i].rx_status = 0;
- lp->rda[i].rx_pktlen = 0;
- lp->rda[i].rx_pktptr_l = 0;
- lp->rda[i].rx_pktptr_h = 0;
- lp->rda[i].rx_seqno = 0;
- lp->rda[i].in_use = 1;
- lp->rda[i].link = lp->rda_laddr + (i+1) * sizeof (sonic_rd_t);
- }
- /* fix last descriptor */
- lp->rda[SONIC_NUM_RDS-1].link = lp->rda_laddr;
- lp->cur_rx = 0;
- SONIC_WRITE(SONIC_URDA,lp->rda_laddr >> 16);
- SONIC_WRITE(SONIC_CRDA,lp->rda_laddr & 0xffff);
-
- /*
- * initialize transmit descriptors
- */
- if (sonic_debug > 2)
- printk ("sonic_init: initialize transmit descriptors\n");
- for (i = 0; i < SONIC_NUM_TDS; i++) {
- lp->tda[i].tx_status = 0;
- lp->tda[i].tx_config = 0;
- lp->tda[i].tx_pktsize = 0;
- lp->tda[i].tx_frag_count = 0;
- lp->tda[i].link = (lp->tda_laddr + (i+1) * sizeof (sonic_td_t)) | SONIC_END_OF_LINKS;
- }
- lp->tda[SONIC_NUM_TDS-1].link = (lp->tda_laddr & 0xffff) | SONIC_END_OF_LINKS;
-
- SONIC_WRITE(SONIC_UTDA,lp->tda_laddr >> 16);
- SONIC_WRITE(SONIC_CTDA,lp->tda_laddr & 0xffff);
- lp->cur_tx = lp->dirty_tx = 0;
-
- /*
- * put our own address to CAM desc[0]
- */
- lp->cda.cam_desc[0].cam_cap0 = dev->dev_addr[1] << 8 | dev->dev_addr[0];
- lp->cda.cam_desc[0].cam_cap1 = dev->dev_addr[3] << 8 | dev->dev_addr[2];
- lp->cda.cam_desc[0].cam_cap2 = dev->dev_addr[5] << 8 | dev->dev_addr[4];
- lp->cda.cam_enable = 1;
-
- for (i=0; i < 16; i++)
- lp->cda.cam_desc[i].cam_entry_pointer = i;
-
- /*
- * initialize CAM registers
- */
- SONIC_WRITE(SONIC_CDP, lp->cda_laddr & 0xffff);
- SONIC_WRITE(SONIC_CDC,16);
-
- /*
- * load the CAM
- */
- SONIC_WRITE(SONIC_CMD,SONIC_CR_LCAM);
-
- i = 0;
- while (i++ < 100) {
- if (SONIC_READ(SONIC_ISR) & SONIC_INT_LCD)
- break;
- }
- if (sonic_debug > 2) {
- printk("sonic_init: CMD=%x, ISR=%x\n",
- SONIC_READ(SONIC_CMD),
- SONIC_READ(SONIC_ISR));
- }
-
- /*
- * enable receiver, disable loopback
- * and enable all interrupts
- */
- SONIC_WRITE(SONIC_CMD,SONIC_CR_RXEN | SONIC_CR_STP);
- SONIC_WRITE(SONIC_RCR,SONIC_RCR_DEFAULT);
- SONIC_WRITE(SONIC_TCR,SONIC_TCR_DEFAULT);
- SONIC_WRITE(SONIC_ISR,0x7fff);
- SONIC_WRITE(SONIC_IMR,SONIC_IMR_DEFAULT);
-
- cmd = SONIC_READ(SONIC_CMD);
- if ((cmd & SONIC_CR_RXEN) == 0 ||
- (cmd & SONIC_CR_STP) == 0)
- printk("sonic_init: failed, status=%x\n",cmd);
+ unsigned int base_addr = dev->base_addr;
+ unsigned int cmd;
+ struct sonic_local *lp = (struct sonic_local *) dev->priv;
+ unsigned int rra_start;
+ unsigned int rra_end;
+ int i;
+
+ /*
+ * put the Sonic into software-reset mode and
+ * disable all interrupts
+ */
+ SONIC_WRITE(SONIC_ISR, 0x7fff);
+ SONIC_WRITE(SONIC_IMR, 0);
+ SONIC_WRITE(SONIC_CMD, SONIC_CR_RST);
+
+ /*
+ * clear software reset flag, disable receiver, clear and
+ * enable interrupts, then completely initialize the SONIC
+ */
+ SONIC_WRITE(SONIC_CMD, 0);
+ SONIC_WRITE(SONIC_CMD, SONIC_CR_RXDIS);
+
+ /*
+ * initialize the receive resource area
+ */
+ if (sonic_debug > 2)
+ printk("sonic_init: initialize receive resource area\n");
+
+ rra_start = lp->rra_laddr & 0xffff;
+ rra_end =
+ (rra_start + (SONIC_NUM_RRS * sizeof(sonic_rr_t))) & 0xffff;
+
+ for (i = 0; i < SONIC_NUM_RRS; i++) {
+ lp->rra[i].rx_bufadr_l =
+ (lp->rba_laddr + i * SONIC_RBSIZE) & 0xffff;
+ lp->rra[i].rx_bufadr_h =
+ (lp->rba_laddr + i * SONIC_RBSIZE) >> 16;
+ lp->rra[i].rx_bufsize_l = SONIC_RBSIZE >> 1;
+ lp->rra[i].rx_bufsize_h = 0;
+ }
X
- if (sonic_debug > 2)
- printk("sonic_init: new status=%x\n",SONIC_READ(SONIC_CMD));
+ /* initialize all RRA registers */
+ SONIC_WRITE(SONIC_RSA, rra_start);
+ SONIC_WRITE(SONIC_REA, rra_end);
+ SONIC_WRITE(SONIC_RRP, rra_start);
+ SONIC_WRITE(SONIC_RWP, rra_end);
+ SONIC_WRITE(SONIC_URRA, lp->rra_laddr >> 16);
+ SONIC_WRITE(SONIC_EOBC, (SONIC_RBSIZE - 2) >> 1);
X
- return(0);
-}
+ lp->cur_rra =
+ lp->rra_laddr + (SONIC_NUM_RRS - 1) * sizeof(sonic_rr_t);
X
-
-/*
- * Local variables:
- * compile-command: "mipsel-linux-gcc -D__KERNEL__ -D__mips64 -I/usr/src/linux/net/inet -Wall -Wstrict-prototypes -O2 -mcpu=r4000 -c sonic.c"
- * version-control: t
- * kept-new-versions: 5
- * tab-width: 4
- * End:
- */
+ /* load the resource pointers */
+ if (sonic_debug > 3)
+ printk("sonic_init: issueing RRRA command\n");
+
+ SONIC_WRITE(SONIC_CMD, SONIC_CR_RRRA);
+ i = 0;
+ while (i++ < 100) {
+ if (SONIC_READ(SONIC_CMD) & SONIC_CR_RRRA)
+ break;
+ }
+
+ if (sonic_debug > 2)
+ printk("sonic_init: status=%x\n", SONIC_READ(SONIC_CMD));
+
+ /*
+ * Initialize the receive descriptors so that they
+ * become a circular linked list, ie. let the last
+ * descriptor point to the first again.
+ */
+ if (sonic_debug > 2)
+ printk("sonic_init: initialize receive descriptors\n");
+ for (i = 0; i < SONIC_NUM_RDS; i++) {
+ lp->rda[i].rx_status = 0;
+ lp->rda[i].rx_pktlen = 0;
+ lp->rda[i].rx_pktptr_l = 0;
+ lp->rda[i].rx_pktptr_h = 0;
+ lp->rda[i].rx_seqno = 0;
+ lp->rda[i].in_use = 1;
+ lp->rda[i].link =
+ lp->rda_laddr + (i + 1) * sizeof(sonic_rd_t);
+ }
+ /* fix last descriptor */
+ lp->rda[SONIC_NUM_RDS - 1].link = lp->rda_laddr;
SHAR_EOF
true || echo 'restore of patch-2.4.12 failed'
fi
echo 'End of part 1'
echo 'File patch-2.4.12 is continued in part 2'
echo "2" > _shar_seq_.tmp
exit 0

Thomas Kobienia

unread,
Oct 11, 2001, 8:00:32 PM10/11/01
to
Archive-name: v2.4/patch-2.4.12/part3

#!/bin/sh -x
# this is part 3 of a 3 - part archive


# do not concatenate these parts, unpack them in order with /bin/sh

# file patch-2.4.12 continued
if test ! -r _shar_seq_.tmp; then
echo 'Please unpack part 1 first!'
exit 1
fi
(read Scheck
if test "$Scheck" != 3; then
echo "Please unpack part $Scheck next!"
exit 1
else
exit 0
fi
) < _shar_seq_.tmp || exit 1
if test ! -f _shar_wnt_.tmp; then
echo 'x - still skipping patch-2.4.12'
else
echo 'x - continuing with patch-2.4.12'


sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.4.12' &&

- struct dentry *dentry)
-{
- /*struct inode *inode = old_dentry->d_inode;*/
- char txt[STRING_LENGTH];
-
- memset (txt, 0, STRING_LENGTH);
- memcpy (txt, old_dentry->d_name.name, old_dentry->d_name.len);
- txt[STRING_LENGTH - 1] = '\0';
- printk ("%s: link of \"%s\"\n", DEVFS_NAME, txt);
- return -EPERM;
-} /* End Function devfs_link */
-
X static int devfs_unlink (struct inode *dir, struct dentry *dentry)
X {
X struct devfs_entry *de;
@@ -3054,7 +3047,6 @@
X static struct inode_operations devfs_dir_iops =
X {
X lookup: devfs_lookup,
- link: devfs_link,
X unlink: devfs_unlink,
X symlink: devfs_symlink,
X mkdir: devfs_mkdir,
diff -u --recursive --new-file v2.4.11/linux/fs/ext2/inode.c linux/fs/ext2/inode.c
--- v2.4.11/linux/fs/ext2/inode.c Tue Oct 9 17:06:53 2001
+++ linux/fs/ext2/inode.c Wed Oct 10 23:42:47 2001
@@ -1148,63 +1148,3 @@
X {
X return ext2_update_inode (inode, 1);
X }
-
-int ext2_notify_change(struct dentry *dentry, struct iattr *iattr)
-{
- struct inode *inode = dentry->d_inode;
- int retval;
- unsigned int flags;
-
- retval = -EPERM;
- if (iattr->ia_valid & ATTR_ATTR_FLAG &&
- ((!(iattr->ia_attr_flags & ATTR_FLAG_APPEND) !=
- !(inode->u.ext2_i.i_flags & EXT2_APPEND_FL)) ||
- (!(iattr->ia_attr_flags & ATTR_FLAG_IMMUTABLE) !=
- !(inode->u.ext2_i.i_flags & EXT2_IMMUTABLE_FL)))) {
- if (!capable(CAP_LINUX_IMMUTABLE))
- goto out;
- } else if ((current->fsuid != inode->i_uid) && !capable(CAP_FOWNER))
- goto out;
-
- retval = inode_change_ok(inode, iattr);
- if (retval != 0 || (((iattr->ia_valid & ATTR_UID && iattr->ia_uid != inode->i_uid) ||
- (iattr->ia_valid & ATTR_GID && iattr->ia_gid != inode->i_gid)) &&
- DQUOT_TRANSFER(inode, iattr)))
- goto out;
-
- inode_setattr(inode, iattr);
-
- flags = iattr->ia_attr_flags;
- if (flags & ATTR_FLAG_SYNCRONOUS) {
- inode->i_flags |= S_SYNC;
- inode->u.ext2_i.i_flags |= EXT2_SYNC_FL;
- } else {
- inode->i_flags &= ~S_SYNC;
- inode->u.ext2_i.i_flags &= ~EXT2_SYNC_FL;
- }
- if (flags & ATTR_FLAG_NOATIME) {
- inode->i_flags |= S_NOATIME;
- inode->u.ext2_i.i_flags |= EXT2_NOATIME_FL;
- } else {
- inode->i_flags &= ~S_NOATIME;
- inode->u.ext2_i.i_flags &= ~EXT2_NOATIME_FL;
- }
- if (flags & ATTR_FLAG_APPEND) {
- inode->i_flags |= S_APPEND;
- inode->u.ext2_i.i_flags |= EXT2_APPEND_FL;
- } else {
- inode->i_flags &= ~S_APPEND;
- inode->u.ext2_i.i_flags &= ~EXT2_APPEND_FL;
- }
- if (flags & ATTR_FLAG_IMMUTABLE) {
- inode->i_flags |= S_IMMUTABLE;
- inode->u.ext2_i.i_flags |= EXT2_IMMUTABLE_FL;
- } else {
- inode->i_flags &= ~S_IMMUTABLE;
- inode->u.ext2_i.i_flags &= ~EXT2_IMMUTABLE_FL;
- }
- mark_inode_dirty(inode);
-out:
- return retval;
-}
-
diff -u --recursive --new-file v2.4.11/linux/fs/namei.c linux/fs/namei.c
--- v2.4.11/linux/fs/namei.c Tue Oct 9 17:06:53 2001
+++ linux/fs/namei.c Wed Oct 10 23:15:49 2001
@@ -325,9 +325,7 @@
X }
X
X /*
- * Yes, this really increments the link_count by 5, and
- * decrements it by 4. Together with checking against 40,
- * this limits recursive symlink follows to 8, while
+ * This limits recursive symlink follows to 8, while
X * limiting consecutive symlinks to 40.
X *
X * Without that kind of total limit, nasty chains of consecutive
@@ -336,16 +334,19 @@
X static inline int do_follow_link(struct dentry *dentry, struct nameidata *nd)
X {
X int err;
- if (current->link_count >= 40)
+ if (current->link_count >= 5)
+ goto loop;
+ if (current->total_link_count >= 40)
X goto loop;
X if (current->need_resched) {
X current->state = TASK_RUNNING;
X schedule();
X }
- current->link_count += 5;
+ current->link_count++;
+ current->total_link_count++;
X UPDATE_ATIME(dentry->d_inode);
X err = dentry->d_inode->i_op->follow_link(dentry, nd);
- current->link_count -= 4;
+ current->link_count--;
X return err;
X loop:
X path_release(nd);
@@ -636,7 +637,7 @@
X
X int path_walk(const char * name, struct nameidata *nd)
X {
- current->link_count = 0;
+ current->total_link_count = 0;
X return link_path_walk(name, nd);
X }
X
diff -u --recursive --new-file v2.4.11/linux/fs/namespace.c linux/fs/namespace.c
--- v2.4.11/linux/fs/namespace.c Tue Oct 9 17:06:53 2001
+++ linux/fs/namespace.c Wed Oct 10 15:39:04 2001
@@ -336,9 +336,6 @@
X struct vfsmount *p;
X LIST_HEAD(kill);
X
- if (list_empty(&mnt->mnt_list))
- return;
-
X for (p = mnt; p; p = next_mnt(p, mnt)) {
X list_del(&p->mnt_list);
X list_add(&p->mnt_list, &kill);
@@ -418,7 +415,8 @@
X }
X retval = -EBUSY;
X if (atomic_read(&mnt->mnt_count) == 2 || flags & MNT_DETACH) {
- umount_tree(mnt);
+ if (!list_empty(&mnt->mnt_list))
+ umount_tree(mnt);
X retval = 0;
X }
X spin_unlock(&dcache_lock);
@@ -592,9 +590,10 @@
X
X if (mnt) {
X err = graft_tree(mnt, nd);
- if (err && recurse)
+ if (err)
X umount_tree(mnt);
- mntput(mnt);
+ else
+ mntput(mnt);
X }
X
X up(&mount_sem);
diff -u --recursive --new-file v2.4.11/linux/fs/proc/base.c linux/fs/proc/base.c
--- v2.4.11/linux/fs/proc/base.c Wed Jul 25 17:10:24 2001
+++ linux/fs/proc/base.c Wed Oct 10 23:42:47 2001
@@ -184,29 +184,6 @@
X
X /* permission checks */
X
-static int standard_permission(struct inode *inode, int mask)
-{
- int mode = inode->i_mode;
-
- if ((mask & S_IWOTH) && IS_RDONLY(inode) &&
- (S_ISREG(mode) || S_ISDIR(mode) || S_ISLNK(mode)))
- return -EROFS; /* Nobody gets write access to a read-only fs */
- else if ((mask & S_IWOTH) && IS_IMMUTABLE(inode))
- return -EACCES; /* Nobody gets write access to an immutable file */
- else if (current->fsuid == inode->i_uid)
- mode >>= 6;
- else if (in_group_p(inode->i_gid))
- mode >>= 3;
- if (((mode & mask & S_IRWXO) == mask) || capable(CAP_DAC_OVERRIDE))
- return 0;
- /* read and search access */
- if ((mask == S_IROTH) ||
- (S_ISDIR(mode) && !(mask & ~(S_IROTH | S_IXOTH))))
- if (capable(CAP_DAC_READ_SEARCH))
- return 0;
- return -EACCES;
-}
-
X static int proc_check_root(struct inode *inode)
X {
X struct dentry *de, *base, *root;
@@ -249,7 +226,7 @@
X
X static int proc_permission(struct inode *inode, int mask)
X {
- if (standard_permission(inode, mask) != 0)
+ if (vfs_permission(inode, mask) != 0)
X return -EACCES;
X return proc_check_root(inode);
X }
diff -u --recursive --new-file v2.4.11/linux/fs/super.c linux/fs/super.c
--- v2.4.11/linux/fs/super.c Tue Oct 9 17:06:53 2001
+++ linux/fs/super.c Wed Oct 10 15:39:04 2001
@@ -443,7 +443,7 @@
X
X static struct super_block * read_super(kdev_t dev, struct block_device *bdev,
X struct file_system_type *type, int flags,
- void *data, int silent)
+ void *data)
X {
X struct super_block * s;
X s = alloc_super();
@@ -460,7 +460,7 @@
X spin_unlock(&sb_lock);
X down_write(&s->s_umount);
X lock_super(s);
- if (!type->read_super(s, data, silent))
+ if (!type->read_super(s, data, flags & MS_VERBOSE ? 1 : 0))
X goto out_fail;
X unlock_super(s);
X /* tell bdcache that we are going to keep this one */
@@ -612,7 +612,7 @@
X
X error = -EINVAL;
X lock_super(s);
- if (!fs_type->read_super(s, data, 0))
+ if (!fs_type->read_super(s, data, flags & MS_VERBOSE ? 1 : 0))
X goto out_fail;
X unlock_super(s);
X get_filesystem(fs_type);
@@ -646,7 +646,7 @@
X if (dev) {
X struct super_block * sb;
X error = -EINVAL;
- sb = read_super(dev, NULL, fs_type, flags, data, 0);
+ sb = read_super(dev, NULL, fs_type, flags, data);
X if (sb) {
X get_filesystem(fs_type);
X return sb;
@@ -692,7 +692,7 @@
X s->s_count += S_BIAS;
X spin_unlock(&sb_lock);
X lock_super(s);
- if (!fs_type->read_super(s, data, 0))
+ if (!fs_type->read_super(s, data, flags & MS_VERBOSE ? 1 : 0))
X goto out_fail;
X unlock_super(s);
X get_filesystem(fs_type);
@@ -865,10 +865,45 @@
X return do_kern_mount((char *)type->name, 0, (char *)type->name, NULL);
X }
X
+static char * __initdata root_fs_names;
+static int __init fs_names_setup(char *str)
+{
+ root_fs_names = str;
+ return 0;
+}
+
+__setup("rootfstype=", fs_names_setup);
+
+static void __init get_fs_names(char *page)
+{
+ char *s = page;
+
+ if (root_fs_names) {
+ strcpy(page, root_fs_names);
+ while (*s++) {
+ if (s[-1] == ',')
+ s[-1] = '\0';
+ }
+ } else {
+ int len = get_filesystem_list(page);
+ char *p, *next;
+
+ page[len] = '\0';
+ for (p = page-1; p; p = next) {
+ next = strchr(++p, '\n');
+ if (*p++ != '\t')
+ continue;
+ while ((*s++ = *p++) != '\n')
+ ;
+ s[-1] = '\0';
+ }
+ }
+ *s = '\0';
+}
+
X void __init mount_root(void)
X {
X struct nameidata root_nd;
- struct file_system_type * fs_type;
X struct super_block * sb;
X struct vfsmount *vfsmnt;
X struct block_device *bdev = NULL;
@@ -878,36 +913,24 @@
X char path[64];
X int path_start = -1;
X char *name = "/dev/root";
-
+ char *fs_names, *p;
X #ifdef CONFIG_ROOT_NFS
X void *data;
+#endif
+ root_mountflags |= MS_VERBOSE;
+
+#ifdef CONFIG_ROOT_NFS
X if (MAJOR(ROOT_DEV) != UNNAMED_MAJOR)
X goto skip_nfs;
- fs_type = get_fs_type("nfs");
- if (!fs_type)
- goto no_nfs;
- ROOT_DEV = get_unnamed_dev();
- if (!ROOT_DEV)
- /*
- * Your /linuxrc sucks worse than MSExchange - that's the
- * only way you could run out of anon devices at that point.
- */
- goto no_anon;
X data = nfs_root_data();
X if (!data)
- goto no_server;
- sb = read_super(ROOT_DEV, NULL, fs_type, root_mountflags, data, 1);
- if (sb)
- /*
- * We _can_ fail there, but if that will happen we have no
- * chance anyway (no memory for vfsmnt and we _will_ need it,
- * no matter which fs we try to mount).
- */
- goto mount_it;
-no_server:
- put_unnamed_dev(ROOT_DEV);
-no_anon:
- put_filesystem(fs_type);
+ goto no_nfs;
+ vfsmnt = do_kern_mount("nfs", root_mountflags, "/dev/root", data);
+ if (!IS_ERR(vfsmnt)) {
+ printk ("VFS: Mounted root (%s filesystem).\n", "nfs");
+ ROOT_DEV = vfsmnt->mnt_sb->s_dev;
+ goto attach_it;
+ }
X no_nfs:
X printk(KERN_ERR "VFS: Unable to mount root fs via NFS, trying floppy.\n");
X ROOT_DEV = MKDEV(FLOPPY_MAJOR, 0);
@@ -936,6 +959,9 @@
X }
X #endif
X
+ fs_names = __getname();
+ get_fs_names(fs_names);
+
X devfs_make_root (root_device_name);
X handle = devfs_find_handle (NULL, ROOT_DEVICE_NAME,
X MAJOR (ROOT_DEV), MINOR (ROOT_DEV),
@@ -985,35 +1011,30 @@
X sb = get_super(ROOT_DEV);
X if (sb) {
X /* FIXME */
- fs_type = sb->s_type;
+ p = (char *)sb->s_type->name;
X atomic_inc(&sb->s_active);
X up_read(&sb->s_umount);
X down_write(&sb->s_umount);
X goto mount_it;
X }
X
- read_lock(&file_systems_lock);
- for (fs_type = file_systems ; fs_type ; fs_type = fs_type->next) {
- if (!(fs_type->fs_flags & FS_REQUIRES_DEV))
+ for (p = fs_names; *p; p += strlen(p)+1) {
+ struct file_system_type * fs_type = get_fs_type(p);
+ if (!fs_type)
X continue;
- if (!try_inc_mod_count(fs_type->owner))
- continue;
- read_unlock(&file_systems_lock);
- sb = read_super(ROOT_DEV,bdev,fs_type,root_mountflags,NULL,1);
+ sb = read_super(ROOT_DEV,bdev,fs_type,root_mountflags,NULL);
X if (sb)
X goto mount_it;
- read_lock(&file_systems_lock);
X put_filesystem(fs_type);
X }
- read_unlock(&file_systems_lock);
X panic("VFS: Unable to mount root fs on %s", kdevname(ROOT_DEV));
X
X mount_it:
X /* FIXME */
X up_write(&sb->s_umount);
- printk ("VFS: Mounted root (%s filesystem)%s.\n",
- fs_type->name,
+ printk ("VFS: Mounted root (%s filesystem)%s.\n", p,
X (sb->s_flags & MS_RDONLY) ? " readonly" : "");
+ putname(fs_names);
X if (path_start >= 0) {
X name = path + path_start;
X devfs_mk_symlink (NULL, "root", DEVFS_FL_DEFAULT,
@@ -1027,18 +1048,15 @@
X set_devname(vfsmnt, name);
X vfsmnt->mnt_sb = sb;
X vfsmnt->mnt_root = dget(sb->s_root);
+ bdput(bdev); /* sb holds a reference */
X
+attach_it:
X root_nd.mnt = root_vfsmnt;
X root_nd.dentry = root_vfsmnt->mnt_sb->s_root;
X graft_tree(vfsmnt, &root_nd);
- mntput(vfsmnt);
X
- /* FIXME: if something will try to umount us right now... */
- if (vfsmnt) {
- set_fs_root(current->fs, vfsmnt, sb->s_root);
- set_fs_pwd(current->fs, vfsmnt, sb->s_root);
- if (bdev)
- bdput(bdev); /* sb holds a reference */
- return;
- }
+ set_fs_root(current->fs, vfsmnt, vfsmnt->mnt_root);
+ set_fs_pwd(current->fs, vfsmnt, vfsmnt->mnt_root);
+
+ mntput(vfsmnt);
X }
diff -u --recursive --new-file v2.4.11/linux/include/asm-i386/smp.h linux/include/asm-i386/smp.h
--- v2.4.11/linux/include/asm-i386/smp.h Tue Oct 9 17:06:53 2001
+++ linux/include/asm-i386/smp.h Thu Oct 11 00:50:24 2001
@@ -31,7 +31,7 @@
X # define INT_DELIVERY_MODE 1 /* logical delivery broadcast to all procs */
X # endif
X #else
-# define INT_DELIVERY_MODE 0 /* physical delivery on LOCAL quad */
+# define INT_DELIVERY_MODE 1 /* logical delivery */
X # define TARGET_CPUS 0x01
X #endif
X
diff -u --recursive --new-file v2.4.11/linux/include/asm-sparc/processor.h linux/include/asm-sparc/processor.h
--- v2.4.11/linux/include/asm-sparc/processor.h Tue Oct 9 17:06:53 2001
+++ linux/include/asm-sparc/processor.h Wed Oct 10 23:42:47 2001
@@ -1,4 +1,4 @@
-/* $Id: processor.h,v 1.82 2001/09/20 00:35:34 davem Exp $
+/* $Id: processor.h,v 1.83 2001/10/08 09:32:13 davem Exp $
X * include/asm-sparc/processor.h
X *
X * Copyright (C) 1994 David S. Miller (da...@caip.rutgers.edu)
diff -u --recursive --new-file v2.4.11/linux/include/asm-sparc/unistd.h linux/include/asm-sparc/unistd.h
--- v2.4.11/linux/include/asm-sparc/unistd.h Mon Aug 14 13:09:07 2000
+++ linux/include/asm-sparc/unistd.h Wed Oct 10 23:42:47 2001
@@ -1,4 +1,4 @@
-/* $Id: unistd.h,v 1.70 2000/08/14 05:39:07 jj Exp $ */
+/* $Id: unistd.h,v 1.71 2001/10/09 10:54:39 davem Exp $ */
X #ifndef _SPARC_UNISTD_H
X #define _SPARC_UNISTD_H
X
@@ -158,7 +158,7 @@
X /* #define __NR_adjtime 140 SunOS Specific */
X #define __NR_getpeername 141 /* Common */
X /* #define __NR_gethostid 142 SunOS Specific */
-/* #define __NR_ni_syscall 143 ENOSYS under SunOS */
+#define __NR_gettid 143 /* ENOSYS under SunOS */
X #define __NR_getrlimit 144 /* Common */
X #define __NR_setrlimit 145 /* Common */
X #define __NR_pivot_root 146 /* Linux Specific, killpg under SunOS */
diff -u --recursive --new-file v2.4.11/linux/include/asm-sparc64/processor.h linux/include/asm-sparc64/processor.h
--- v2.4.11/linux/include/asm-sparc64/processor.h Tue Oct 9 17:06:53 2001
+++ linux/include/asm-sparc64/processor.h Wed Oct 10 23:42:47 2001
@@ -1,4 +1,4 @@
-/* $Id: processor.h,v 1.75 2001/09/20 00:35:34 davem Exp $
+/* $Id: processor.h,v 1.76 2001/10/08 09:32:13 davem Exp $
X * include/asm-sparc64/processor.h
X *
X * Copyright (C) 1996 David S. Miller (da...@caip.rutgers.edu)
diff -u --recursive --new-file v2.4.11/linux/include/asm-sparc64/unistd.h linux/include/asm-sparc64/unistd.h
--- v2.4.11/linux/include/asm-sparc64/unistd.h Mon Aug 14 13:09:08 2000
+++ linux/include/asm-sparc64/unistd.h Wed Oct 10 23:42:47 2001
@@ -1,4 +1,4 @@
-/* $Id: unistd.h,v 1.47 2000/08/14 05:39:07 jj Exp $ */
+/* $Id: unistd.h,v 1.48 2001/10/09 10:54:39 davem Exp $ */
X #ifndef _SPARC64_UNISTD_H
X #define _SPARC64_UNISTD_H
X
@@ -158,7 +158,7 @@
X /* #define __NR_adjtime 140 SunOS Specific */
X #define __NR_getpeername 141 /* Common */
X /* #define __NR_gethostid 142 SunOS Specific */
-/* #define __NR_ni_syscall 143 ENOSYS under SunOS */
+#define __NR_gettid 143 /* ENOSYS under SunOS */
X #define __NR_getrlimit 144 /* Common */
X #define __NR_setrlimit 145 /* Common */
X #define __NR_pivot_root 146 /* Linux Specific, killpg under SunOS */
diff -u --recursive --new-file v2.4.11/linux/include/linux/ext2_fs.h linux/include/linux/ext2_fs.h
--- v2.4.11/linux/include/linux/ext2_fs.h Tue Oct 9 17:06:53 2001
+++ linux/include/linux/ext2_fs.h Wed Oct 10 23:45:08 2001
@@ -545,9 +545,6 @@
X # define ATTRIB_NORET __attribute__((noreturn))
X # define NORET_AND noreturn,
X
-/* acl.c */
-extern int ext2_permission (struct inode *, int);
-
X /* balloc.c */
X extern int ext2_bg_has_super(struct super_block *sb, int group);
X extern unsigned long ext2_bg_num_gdb(struct super_block *sb, int group);
diff -u --recursive --new-file v2.4.11/linux/include/linux/fs.h linux/include/linux/fs.h
--- v2.4.11/linux/include/linux/fs.h Tue Oct 9 17:06:53 2001
+++ linux/include/linux/fs.h Wed Oct 10 23:44:34 2001
@@ -109,6 +109,7 @@
X #define MS_NODIRATIME 2048 /* Do not update directory access times */
X #define MS_BIND 4096
X #define MS_REC 16384
+#define MS_VERBOSE 32768
X #define MS_NOUSER (1<<31)
X
X /*
diff -u --recursive --new-file v2.4.11/linux/include/linux/netdevice.h linux/include/linux/netdevice.h
--- v2.4.11/linux/include/linux/netdevice.h Mon Aug 27 12:41:48 2001
+++ linux/include/linux/netdevice.h Wed Oct 10 23:44:52 2001
@@ -636,6 +636,41 @@
X }
X }
X
+/*
+ * Network interface message level settings
+ */
+#define HAVE_NETIF_MSG 1
+
+enum {
+ NETIF_MSG_DRV = 0x0001,
+ NETIF_MSG_PROBE = 0x0002,
+ NETIF_MSG_LINK = 0x0004,
+ NETIF_MSG_TIMER = 0x0008,
+ NETIF_MSG_IFDOWN = 0x0010,
+ NETIF_MSG_IFUP = 0x0020,
+ NETIF_MSG_RX_ERR = 0x0040,
+ NETIF_MSG_TX_ERR = 0x0080,
+ NETIF_MSG_TX_QUEUED = 0x0100,
+ NETIF_MSG_INTR = 0x0200,
+ NETIF_MSG_TX_DONE = 0x0400,
+ NETIF_MSG_RX_STATUS = 0x0800,
+ NETIF_MSG_PKTDATA = 0x1000,
+};
+
+#define netif_msg_drv(p) ((p)->msg_enable & NETIF_MSG_DRV)
+#define netif_msg_probe(p) ((p)->msg_enable & NETIF_MSG_PROBE)
+#define netif_msg_link(p) ((p)->msg_enable & NETIF_MSG_LINK)
+#define netif_msg_timer(p) ((p)->msg_enable & NETIF_MSG_TIMER)
+#define netif_msg_ifdown(p) ((p)->msg_enable & NETIF_MSG_IFDOWN)
+#define netif_msg_ifup(p) ((p)->msg_enable & NETIF_MSG_IFUP)
+#define netif_msg_rx_err(p) ((p)->msg_enable & NETIF_MSG_RX_ERR)
+#define netif_msg_tx_err(p) ((p)->msg_enable & NETIF_MSG_TX_ERR)
+#define netif_msg_tx_queued(p) ((p)->msg_enable & NETIF_MSG_TX_QUEUED)
+#define netif_msg_intr(p) ((p)->msg_enable & NETIF_MSG_INTR)
+#define netif_msg_tx_done(p) ((p)->msg_enable & NETIF_MSG_TX_DONE)
+#define netif_msg_rx_status(p) ((p)->msg_enable & NETIF_MSG_RX_STATUS)
+#define netif_msg_pktdata(p) ((p)->msg_enable & NETIF_MSG_PKTDATA)
+
X /* These functions live elsewhere (drivers/net/net_init.c, but related) */
X
X extern void ether_setup(struct net_device *dev);
diff -u --recursive --new-file v2.4.11/linux/include/linux/parport.h linux/include/linux/parport.h
--- v2.4.11/linux/include/linux/parport.h Sun Aug 12 13:28:01 2001
+++ linux/include/linux/parport.h Wed Oct 10 23:19:30 2001
@@ -251,7 +251,8 @@
X IEEE1284_PH_REV_DATA,
X IEEE1284_PH_ECP_SETUP,
X IEEE1284_PH_ECP_FWD_TO_REV,
- IEEE1284_PH_ECP_REV_TO_FWD
+ IEEE1284_PH_ECP_REV_TO_FWD,
+ IEEE1284_PH_ECP_DIR_UNKNOWN,
X };
X struct ieee1284_info {
X int mode;
diff -u --recursive --new-file v2.4.11/linux/include/linux/pci_ids.h linux/include/linux/pci_ids.h
--- v2.4.11/linux/include/linux/pci_ids.h Tue Oct 9 17:06:53 2001
+++ linux/include/linux/pci_ids.h Wed Oct 10 23:19:30 2001
@@ -1437,9 +1437,11 @@
X #define PCI_DEVICE_ID_TIMEDIA_1889 0x7168
X
X #define PCI_VENDOR_ID_OXSEMI 0x1415
+#define PCI_DEVICE_ID_OXSEMI_12PCI840 0x8403
X #define PCI_DEVICE_ID_OXSEMI_16PCI954 0x9501
X #define PCI_DEVICE_ID_OXSEMI_16PCI952 0x950A
X #define PCI_DEVICE_ID_OXSEMI_16PCI95N 0x9511
+#define PCI_DEVICE_ID_OXSEMI_16PCI954PP 0x9513
X
X #define PCI_VENDOR_ID_AIRONET 0x14b9
X #define PCI_DEVICE_ID_AIRONET_4800_1 0x0001
@@ -1462,9 +1464,6 @@
X #define PCI_VENDOR_ID_PANACOM 0x14d4
X #define PCI_DEVICE_ID_PANACOM_QUADMODEM 0x0400
X #define PCI_DEVICE_ID_PANACOM_DUALMODEM 0x0402
-
-#define PCI_VENDOR_ID_AFAVLAB 0x14db
-#define PCI_DEVICE_ID_AFAVLAB_TK9902 0x2120
X
X #define PCI_VENDOR_ID_BROADCOM 0x14e4
X #define PCI_DEVICE_ID_TIGON3 0x1644
diff -u --recursive --new-file v2.4.11/linux/include/linux/sched.h linux/include/linux/sched.h
--- v2.4.11/linux/include/linux/sched.h Sun Sep 23 11:41:01 2001
+++ linux/include/linux/sched.h Wed Oct 10 23:44:34 2001
@@ -369,7 +369,7 @@
X unsigned short used_math;
X char comm[16];
X /* file system info */
- int link_count;
+ int link_count, total_link_count;
X struct tty_struct *tty; /* NULL if no tty */
X unsigned int locks; /* How many file locks are being held */
X /* ipc stuff */
diff -u --recursive --new-file v2.4.11/linux/include/linux/shmem_fs.h linux/include/linux/shmem_fs.h
--- v2.4.11/linux/include/linux/shmem_fs.h Thu Apr 12 12:25:53 2001
+++ linux/include/linux/shmem_fs.h Wed Oct 10 07:53:57 2001
@@ -17,14 +17,18 @@
X unsigned long val;
X } swp_entry_t;
X
+extern atomic_t shmem_nrpages;
+
X struct shmem_inode_info {
- spinlock_t lock;
- unsigned long max_index;
- swp_entry_t i_direct[SHMEM_NR_DIRECT]; /* for the first blocks */
- swp_entry_t **i_indirect; /* doubly indirect blocks */
- unsigned long swapped;
- int locked; /* into memory */
+ spinlock_t lock;
+ struct semaphore sem;
+ unsigned long next_index;
+ swp_entry_t i_direct[SHMEM_NR_DIRECT]; /* for the first blocks */
+ void **i_indirect; /* indirect blocks */
+ unsigned long swapped;
+ int locked; /* into memory */
X struct list_head list;
+ struct inode *inode;
X };
X
X struct shmem_sb_info {
@@ -34,5 +38,7 @@
X unsigned long free_inodes; /* How many are left for allocation */
X spinlock_t stat_lock;
X };
+
+#define SHMEM_I(inode) (&inode->u.shmem_i)
X
X #endif
diff -u --recursive --new-file v2.4.11/linux/mm/shmem.c linux/mm/shmem.c
--- v2.4.11/linux/mm/shmem.c Tue Oct 9 17:06:53 2001
+++ linux/mm/shmem.c Wed Oct 10 07:53:57 2001
@@ -26,15 +26,16 @@
X #include <linux/pagemap.h>
X #include <linux/string.h>
X #include <linux/locks.h>
-#include <asm/smplock.h>
+#include <linux/smp_lock.h>
X
X #include <asm/uaccess.h>
X
X /* This magic number is used in glibc for posix shared memory */
X #define TMPFS_MAGIC 0x01021994
X
-#define ENTRIES_PER_PAGE (PAGE_SIZE/sizeof(unsigned long))
-#define SHMEM_MAX_BLOCKS (SHMEM_NR_DIRECT + ENTRIES_PER_PAGE*ENTRIES_PER_PAGE)
+#define ENTRIES_PER_PAGE (PAGE_CACHE_SIZE/sizeof(unsigned long))
+
+#define SHMEM_SB(sb) (&sb->u.shmem_sb)
X
X static struct super_operations shmem_ops;
X static struct address_space_operations shmem_aops;
@@ -42,18 +43,19 @@
X static struct inode_operations shmem_inode_operations;
X static struct file_operations shmem_dir_operations;
X static struct inode_operations shmem_dir_inode_operations;
-static struct inode_operations shmem_symlink_inode_operations;
X static struct vm_operations_struct shmem_vm_ops;
X
X LIST_HEAD (shmem_inodes);
X static spinlock_t shmem_ilock = SPIN_LOCK_UNLOCKED;
+atomic_t shmem_nrpages = ATOMIC_INIT(0); /* Not used right now */
X
-#define BLOCKS_PER_PAGE (PAGE_SIZE/512)
+#define BLOCKS_PER_PAGE (PAGE_CACHE_SIZE/512)
X
X /*
X * shmem_recalc_inode - recalculate the size of an inode
X *
X * @inode: inode to recalc
+ * @swap: additional swap pages freed externally
X *
X * We have to calculate the free blocks since the mm can drop pages
X * behind our back
@@ -64,7 +66,7 @@
X *
X * So the mm freed
X * inodes->i_blocks/BLOCKS_PER_PAGE -
- * (inode->i_mapping->nrpages + info->swapped)
+ * (inode->i_mapping->nrpages + info->swapped)
X *
X * It has to be called with the spinlock held.
X */
@@ -74,19 +76,63 @@
X unsigned long freed;
X
X freed = (inode->i_blocks/BLOCKS_PER_PAGE) -
- (inode->i_mapping->nrpages + inode->u.shmem_i.swapped);
+ (inode->i_mapping->nrpages + SHMEM_I(inode)->swapped);
X if (freed){
- struct shmem_sb_info * info = &inode->i_sb->u.shmem_sb;
+ struct shmem_sb_info * sbinfo = SHMEM_SB(inode->i_sb);
X inode->i_blocks -= freed*BLOCKS_PER_PAGE;
- spin_lock (&info->stat_lock);
- info->free_blocks += freed;
- spin_unlock (&info->stat_lock);
+ spin_lock (&sbinfo->stat_lock);
+ sbinfo->free_blocks += freed;
+ spin_unlock (&sbinfo->stat_lock);
X }
X }
X
-static swp_entry_t * shmem_swp_entry (struct shmem_inode_info *info, unsigned long index)
+/*
+ * shmem_swp_entry - find the swap vector position in the info structure
+ *
+ * @info: info structure for the inode
+ * @index: index of the page to find
+ * @page: optional page to add to the structure. Has to be preset to
+ * all zeros
+ *
+ * If there is no space allocated yet it will return -ENOMEM when
+ * page == 0 else it will use the page for the needed block.
+ *
+ * returns -EFBIG if the index is too big.
+ *
+ *
+ * The swap vector is organized the following way:
+ *
+ * There are SHMEM_NR_DIRECT entries directly stored in the
+ * shmem_inode_info structure. So small files do not need an addional
+ * allocation.
+ *
+ * For pages with index > SHMEM_NR_DIRECT there is the pointer
+ * i_indirect which points to a page which holds in the first half
+ * doubly indirect blocks, in the second half triple indirect blocks:
+ *
+ * For an artificial ENTRIES_PER_PAGE = 4 this would lead to the
+ * following layout (for SHMEM_NR_DIRECT == 16):
+ *
+ * i_indirect -> dir --> 16-19
+ * | +-> 20-23
+ * |
+ * +-->dir2 --> 24-27
+ * | +-> 28-31
+ * | +-> 32-35
+ * | +-> 36-39
+ * |
+ * +-->dir3 --> 40-43
+ * +-> 44-47
+ * +-> 48-51
+ * +-> 52-55
+ */
+
+#define SHMEM_MAX_BLOCKS (SHMEM_NR_DIRECT + ENTRIES_PER_PAGE * ENTRIES_PER_PAGE/2*(ENTRIES_PER_PAGE+1))
+
+static swp_entry_t * shmem_swp_entry (struct shmem_inode_info *info, unsigned long index, unsigned long page)
X {
X unsigned long offset;
+ void **dir;
X
X if (index < SHMEM_NR_DIRECT)
X return info->i_direct+index;
@@ -95,23 +141,66 @@
X offset = index % ENTRIES_PER_PAGE;
X index /= ENTRIES_PER_PAGE;
X
- if (index >= ENTRIES_PER_PAGE)
- return ERR_PTR(-EFBIG);
-
X if (!info->i_indirect) {
- info->i_indirect = (swp_entry_t **) get_zeroed_page(GFP_USER);
- if (!info->i_indirect)
+ info->i_indirect = (void *) page;
+ return ERR_PTR(-ENOMEM);
+ }
+
+ dir = info->i_indirect + index;
+ if (index >= ENTRIES_PER_PAGE/2) {
+ index -= ENTRIES_PER_PAGE/2;
+ dir = info->i_indirect + ENTRIES_PER_PAGE/2
+ + index/ENTRIES_PER_PAGE;
+ index %= ENTRIES_PER_PAGE;
+
+ if(!*dir) {
+ *dir = (void *) page;
+ /* We return since we will need another page
+ in the next step */
X return ERR_PTR(-ENOMEM);
+ }
+ dir = ((void **)*dir) + index;
X }
- if(!(info->i_indirect[index])) {
- info->i_indirect[index] = (swp_entry_t *) get_zeroed_page(GFP_USER);
- if (!info->i_indirect[index])
+ if (!*dir) {
+ if (!page)
X return ERR_PTR(-ENOMEM);
+ *dir = (void *)page;
X }
-
- return info->i_indirect[index]+offset;
+ return ((swp_entry_t *)*dir) + offset;
X }
X
+/*
+ * shmem_alloc_entry - get the position of the swap entry for the
+ * page. If it does not exist allocate the entry
+ *
+ * @info: info structure for the inode
+ * @index: index of the page to find
+ */
+static inline swp_entry_t * shmem_alloc_entry (struct shmem_inode_info *info, unsigned long index)
+{
+ unsigned long page = 0;
+ swp_entry_t * res;
+
+ if (index >= SHMEM_MAX_BLOCKS)
+ return ERR_PTR(-EFBIG);
+
+ if (info->next_index <= index)
+ info->next_index = index + 1;
+
+ while ((res = shmem_swp_entry(info,index,page)) == ERR_PTR(-ENOMEM)) {
+ page = get_zeroed_page(GFP_USER);
+ if (!page)
+ break;
+ }
+ return res;
+}
+
+/*
+ * shmem_free_swp - free some swap entries in a directory
+ *
+ * @dir: pointer to the directory
+ * @count: number of entries to scan
+ */
X static int shmem_free_swp(swp_entry_t *dir, unsigned int count)
X {
X swp_entry_t *ptr, entry;
@@ -131,95 +220,197 @@
X }
X
X /*
- * shmem_truncate_part - free a bunch of swap entries
+ * shmem_truncate_direct - free the swap entries of a whole doubly
+ * indirect block
X *
- * @dir: pointer to swp_entries
- * @size: number of entries in dir
- * @start: offset to start from
- * @freed: counter for freed pages
+ * @dir: pointer to the pointer to the block
+ * @start: offset to start from (in pages)
+ * @len: how many pages are stored in this block
X *
- * It frees the swap entries from dir+start til dir+size
- *
- * returns 0 if it truncated something, else (offset-size)
+ * Returns the number of freed swap entries.
X */
X
-static unsigned long
-shmem_truncate_part (swp_entry_t * dir, unsigned long size,
- unsigned long start, unsigned long *freed) {
- if (start > size)
- return start - size;
- if (dir)
- *freed += shmem_free_swp (dir+start, size-start);
+static inline unsigned long
+shmem_truncate_direct(swp_entry_t *** dir, unsigned long start, unsigned long len) {
+ swp_entry_t **last, **ptr;
+ unsigned long off, freed = 0;
+
+ if (!*dir)
+ return 0;
+
+ last = *dir + (len + ENTRIES_PER_PAGE-1) / ENTRIES_PER_PAGE;
+ off = start % ENTRIES_PER_PAGE;
+
+ for (ptr = *dir + start/ENTRIES_PER_PAGE; ptr < last; ptr++) {
+ if (!*ptr) {
+ off = 0;
+ continue;
+ }
+
+ if (!off) {
+ freed += shmem_free_swp(*ptr, ENTRIES_PER_PAGE);
+ free_page ((unsigned long) *ptr);
+ *ptr = 0;
+ } else {
+ freed += shmem_free_swp(*ptr+off,ENTRIES_PER_PAGE-off);
+ off = 0;
+ }
+ }
X
- return 0;
+ if (!start) {
+ free_page((unsigned long) *dir);
+ *dir = 0;
+ }
+ return freed;
+}
+
+/*
+ * shmem_truncate_indirect - truncate an inode
+ *
+ * @info: the info structure of the inode
+ * @index: the index to truncate
+ *
+ * This function locates the last doubly indirect block and calls
+ * then shmem_truncate_direct to do the real work
+ */
+static inline unsigned long
+shmem_truncate_indirect(struct shmem_inode_info *info, unsigned long index)
+{
+ swp_entry_t ***base;
+ unsigned long baseidx, len, start;
+ unsigned long max = info->next_index-1;
+
+ if (max < SHMEM_NR_DIRECT) {
+ info->next_index = index;
+ return shmem_free_swp(info->i_direct + index,
+ SHMEM_NR_DIRECT - index);
+ }
+
+ if (max < ENTRIES_PER_PAGE * ENTRIES_PER_PAGE/2 + SHMEM_NR_DIRECT) {
+ max -= SHMEM_NR_DIRECT;
+ base = (swp_entry_t ***) &info->i_indirect;
+ baseidx = SHMEM_NR_DIRECT;
+ len = max+1;
+ } else {
+ max -= ENTRIES_PER_PAGE*ENTRIES_PER_PAGE/2+SHMEM_NR_DIRECT;
+ if (max >= ENTRIES_PER_PAGE*ENTRIES_PER_PAGE*ENTRIES_PER_PAGE/2)
+ BUG();
+
+ baseidx = max & ~(ENTRIES_PER_PAGE*ENTRIES_PER_PAGE-1);
+ base = (swp_entry_t ***) info->i_indirect + ENTRIES_PER_PAGE/2 + baseidx/ENTRIES_PER_PAGE/ENTRIES_PER_PAGE ;
+ len = max - baseidx + 1;
+ baseidx += ENTRIES_PER_PAGE*ENTRIES_PER_PAGE/2+SHMEM_NR_DIRECT;
+ }
+
+ if (index > baseidx) {
+ info->next_index = index;
+ start = index - baseidx;
+ } else {
+ info->next_index = baseidx;
+ start = 0;
+ }
+ return shmem_truncate_direct(base, start, len);
X }
X
X static void shmem_truncate (struct inode * inode)
X {
- int clear_base;
- unsigned long index, start;
+ unsigned long index;
X unsigned long freed = 0;
- swp_entry_t **base, **ptr, **last;
- struct shmem_inode_info * info = &inode->u.shmem_i;
+ struct shmem_inode_info * info = SHMEM_I(inode);
X
+ down(&info->sem);
X inode->i_ctime = inode->i_mtime = CURRENT_TIME;
X spin_lock (&info->lock);
X index = (inode->i_size + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT;
- if (index > info->max_index)
- goto out;
X
- start = shmem_truncate_part (info->i_direct, SHMEM_NR_DIRECT, index, &freed);
+ while (index < info->next_index)
+ freed += shmem_truncate_indirect(info, index);
X
- if (!(base = info->i_indirect))
- goto out;
+ info->swapped -= freed;
+ shmem_recalc_inode(inode);
+ spin_unlock (&info->lock);
+ up(&info->sem);
+}
X
- clear_base = 1;
- last = base + ((info->max_index - SHMEM_NR_DIRECT + ENTRIES_PER_PAGE - 1) / ENTRIES_PER_PAGE);
- for (ptr = base; ptr < last; ptr++) {
- if (!start) {
- if (!*ptr)
- continue;
- freed += shmem_free_swp (*ptr, ENTRIES_PER_PAGE);
- free_page ((unsigned long) *ptr);
- *ptr = 0;
- continue;
- }
- clear_base = 0;
- start = shmem_truncate_part (*ptr, ENTRIES_PER_PAGE, start, &freed);
+static void shmem_delete_inode(struct inode * inode)
+{
+ struct shmem_sb_info *sbinfo = SHMEM_SB(inode->i_sb);
+
+ inode->i_size = 0;
+ if (inode->i_op->truncate == shmem_truncate){
+ spin_lock (&shmem_ilock);
+ list_del (&SHMEM_I(inode)->list);
+ spin_unlock (&shmem_ilock);
+ shmem_truncate (inode);
X }
+ spin_lock (&sbinfo->stat_lock);
+ sbinfo->free_inodes++;
+ spin_unlock (&sbinfo->stat_lock);
+ clear_inode(inode);
+}
+
+static int shmem_clear_swp (swp_entry_t entry, swp_entry_t *ptr, int size) {
+ swp_entry_t *test;
X
- if (clear_base) {
- free_page ((unsigned long)base);
- info->i_indirect = 0;
+ for (test = ptr; test < ptr + size; test++) {
+ if (test->val == entry.val) {
+ swap_free (entry);
+ *test = (swp_entry_t) {0};
+ return test - ptr;
+ }
X }
+ return -1;
+}
X
-out:
- /*
- * We have no chance to give an error, so we limit it to max
- * size here and the application will fail later
- */
- if (index > SHMEM_MAX_BLOCKS)
- info->max_index = SHMEM_MAX_BLOCKS;
- else
- info->max_index = index;
- info->swapped -= freed;
- shmem_recalc_inode(inode);
+static int shmem_unuse_inode (struct shmem_inode_info *info, swp_entry_t entry, struct page *page)
+{
+ swp_entry_t *ptr;
+ unsigned long idx;
+ int offset;
+
+ idx = 0;
+ spin_lock (&info->lock);
+ offset = shmem_clear_swp (entry, info->i_direct, SHMEM_NR_DIRECT);
+ if (offset >= 0)
+ goto found;
+
+ for (idx = SHMEM_NR_DIRECT; idx < info->next_index;
+ idx += ENTRIES_PER_PAGE) {
+ ptr = shmem_swp_entry(info, idx, 0);
+ if (IS_ERR(ptr))
+ continue;
+ offset = shmem_clear_swp (entry, ptr, ENTRIES_PER_PAGE);
+ if (offset >= 0)
+ goto found;
+ }
X spin_unlock (&info->lock);
+ return 0;
+found:
+ add_to_page_cache(page, info->inode->i_mapping, offset + idx);
+ SetPageDirty(page);
+ SetPageUptodate(page);
+ UnlockPage(page);
+ info->swapped--;
+ spin_unlock(&info->lock);
+ return 1;
X }
X
-static void shmem_delete_inode(struct inode * inode)
+/*
+ * unuse_shmem() search for an eventually swapped out shmem page.
+ */
+void shmem_unuse(swp_entry_t entry, struct page *page)
X {
- struct shmem_sb_info *info = &inode->i_sb->u.shmem_sb;
+ struct list_head *p;
+ struct shmem_inode_info * info;
X
X spin_lock (&shmem_ilock);
- list_del (&inode->u.shmem_i.list);
+ list_for_each(p, &shmem_inodes) {
+ info = list_entry(p, struct shmem_inode_info, list);
+
+ if (shmem_unuse_inode(info, entry, page))
+ break;
+ }
X spin_unlock (&shmem_ilock);
- inode->i_size = 0;
- shmem_truncate (inode);
- spin_lock (&info->stat_lock);
- info->free_inodes++;
- spin_unlock (&info->stat_lock);
- clear_inode(inode);
X }
X
X /*
@@ -244,7 +435,7 @@
X mapping = page->mapping;
X index = page->index;
X inode = mapping->host;
- info = &inode->u.shmem_i;
+ info = SHMEM_I(inode);
X getswap:
X swap = get_swap_page();
X if (!swap.val) {
@@ -255,7 +446,7 @@
X }
X
X spin_lock(&info->lock);
- entry = shmem_swp_entry(info, index);
+ entry = shmem_swp_entry(info, index, 0);
X if (IS_ERR(entry)) /* this had been allocated on page allocation */
X BUG();
X shmem_recalc_inode(inode);
@@ -300,27 +491,25 @@
X * still need to guard against racing with shm_writepage(), which might
X * be trying to move the page to the swap cache as we run.
X */
-static struct page * shmem_getpage_locked(struct inode * inode, unsigned long idx)
+static struct page * shmem_getpage_locked(struct shmem_inode_info *info, struct inode * inode, unsigned long idx)
X {
X struct address_space * mapping = inode->i_mapping;
- struct shmem_inode_info *info;
+ struct shmem_sb_info *sbinfo;
X struct page * page;
X swp_entry_t *entry;
X
- info = &inode->u.shmem_i;
-
X repeat:
X page = find_lock_page(mapping, idx);
X if (page)
X return page;
X
- entry = shmem_swp_entry (info, idx);
+ entry = shmem_alloc_entry (info, idx);
X if (IS_ERR(entry))
X return (void *)entry;
X
X spin_lock (&info->lock);
X
- /* The shmem_swp_entry() call may have blocked, and
+ /* The shmem_alloc_entry() call may have blocked, and
X * shmem_writepage may have been moving a page between the page
X * cache and swap cache. We need to recheck the page cache
X * under the protection of the info->lock spinlock. */
@@ -370,18 +559,19 @@
X swap_free(*entry);
X *entry = (swp_entry_t) {0};
X delete_from_swap_cache(page);
- flags = page->flags & ~(1 << PG_uptodate | 1 << PG_error | 1 << PG_referenced | 1 << PG_arch_1);
+ flags = page->flags & ~((1 << PG_uptodate) | (1 << PG_error) | (1 << PG_referenced) | (1 << PG_arch_1));
X page->flags = flags | (1 << PG_dirty);
X add_to_page_cache_locked(page, mapping, idx);
X info->swapped--;
X spin_unlock (&info->lock);
X } else {
+ sbinfo = SHMEM_SB(inode->i_sb);
X spin_unlock (&info->lock);
- spin_lock (&inode->i_sb->u.shmem_sb.stat_lock);
- if (inode->i_sb->u.shmem_sb.free_blocks == 0)
+ spin_lock (&sbinfo->stat_lock);
+ if (sbinfo->free_blocks == 0)
X goto no_space;
- inode->i_sb->u.shmem_sb.free_blocks--;
- spin_unlock (&inode->i_sb->u.shmem_sb.stat_lock);
+ sbinfo->free_blocks--;
+ spin_unlock (&sbinfo->stat_lock);
X
X /* Ok, get a new page. We don't have to worry about the
X * info->lock spinlock here: we cannot race against
@@ -404,7 +594,7 @@
X page_cache_get(page);
X return page;
X no_space:
- spin_unlock (&inode->i_sb->u.shmem_sb.stat_lock);
+ spin_unlock (&sbinfo->stat_lock);
X return ERR_PTR(-ENOSPC);
X
X wait_retry:
@@ -416,28 +606,28 @@
X
X static int shmem_getpage(struct inode * inode, unsigned long idx, struct page **ptr)
X {
+ struct shmem_inode_info *info = SHMEM_I(inode);
X int error;
X
- down (&inode->i_sem);
+ down (&info->sem);
+ *ptr = ERR_PTR(-EFAULT);
X if (inode->i_size <= (loff_t) idx * PAGE_CACHE_SIZE)
- goto sigbus;
- *ptr = shmem_getpage_locked(inode, idx);
+ goto failed;
+
+ *ptr = shmem_getpage_locked(info, inode, idx);
X if (IS_ERR (*ptr))
X goto failed;
+
X UnlockPage(*ptr);
- up (&inode->i_sem);
+ up (&info->sem);
X return 0;
X failed:
- up (&inode->i_sem);
+ up (&info->sem);
X error = PTR_ERR(*ptr);
- *ptr = NOPAGE_OOM;
- if (error != -EFBIG)
- *ptr = NOPAGE_SIGBUS;
- return error;
-sigbus:
- up (&inode->i_sem);
X *ptr = NOPAGE_SIGBUS;
- return -EFAULT;
+ if (error == -ENOMEM)
+ *ptr = NOPAGE_OOM;
+ return error;
X }
X
X struct page * shmem_nopage(struct vm_area_struct * vma, unsigned long address, int no_share)
@@ -446,7 +636,7 @@
X unsigned int idx;
X struct inode * inode = vma->vm_file->f_dentry->d_inode;
X
- idx = (address - vma->vm_start) >> PAGE_SHIFT;
+ idx = (address - vma->vm_start) >> PAGE_CACHE_SHIFT;
X idx += vma->vm_pgoff;
X
X if (shmem_getpage(inode, idx, &page))
@@ -471,13 +661,13 @@
X void shmem_lock(struct file * file, int lock)
X {
X struct inode * inode = file->f_dentry->d_inode;
- struct shmem_inode_info * info = &inode->u.shmem_i;
+ struct shmem_inode_info * info = SHMEM_I(inode);
X struct page * page;
X unsigned long idx, size;
X
- if (info->locked == lock)
- return;
- down(&inode->i_sem);
+ down(&info->sem);
+ if (info->locked == lock)
+ goto out;
X info->locked = lock;
X size = (inode->i_size + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT;
X for (idx = 0; idx < size; idx++) {
@@ -491,7 +681,8 @@
X }
X UnlockPage(page);
X }
- up(&inode->i_sem);
+out:
+ up(&info->sem);
X }
X
X static int shmem_mmap(struct file * file, struct vm_area_struct * vma)
@@ -510,14 +701,16 @@
X struct inode *shmem_get_inode(struct super_block *sb, int mode, int dev)
X {
X struct inode * inode;
+ struct shmem_inode_info *info;
+ struct shmem_sb_info *sbinfo = SHMEM_SB(sb);
X
- spin_lock (&sb->u.shmem_sb.stat_lock);
- if (!sb->u.shmem_sb.free_inodes) {
- spin_unlock (&sb->u.shmem_sb.stat_lock);
+ spin_lock (&sbinfo->stat_lock);
+ if (!sbinfo->free_inodes) {
+ spin_unlock (&sbinfo->stat_lock);
X return NULL;
X }
- sb->u.shmem_sb.free_inodes--;
- spin_unlock (&sb->u.shmem_sb.stat_lock);
+ sbinfo->free_inodes--;
+ spin_unlock (&sbinfo->stat_lock);
X
X inode = new_inode(sb);
X if (inode) {
@@ -529,7 +722,10 @@
X inode->i_rdev = NODEV;
X inode->i_mapping->a_ops = &shmem_aops;
X inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
- spin_lock_init (&inode->u.shmem_i.lock);
+ info = SHMEM_I(inode);
+ info->inode = inode;
+ spin_lock_init (&info->lock);
+ sema_init (&info->sem, 1);
X switch (mode & S_IFMT) {
X default:
X init_special_inode(inode, mode, dev);
@@ -537,6 +733,9 @@
X case S_IFREG:
X inode->i_op = &shmem_inode_operations;
X inode->i_fop = &shmem_file_operations;
+ spin_lock (&shmem_ilock);
+ list_add (&SHMEM_I(inode)->list, &shmem_inodes);
+ spin_unlock (&shmem_ilock);
X break;
X case S_IFDIR:
X inode->i_nlink++;
@@ -544,12 +743,8 @@
X inode->i_fop = &shmem_dir_operations;
X break;
X case S_IFLNK:
- inode->i_op = &shmem_symlink_inode_operations;
X break;
X }
- spin_lock (&shmem_ilock);
- list_add (&inode->u.shmem_i.list, &shmem_inodes);
- spin_unlock (&shmem_ilock);
X }
X return inode;
X }
@@ -579,10 +774,15 @@
X }
X
X #ifdef CONFIG_TMPFS
+
+static struct inode_operations shmem_symlink_inode_operations;
+static struct inode_operations shmem_symlink_inline_operations;
+
X static ssize_t
X shmem_file_write(struct file *file,const char *buf,size_t count,loff_t *ppos)
X {
X struct inode *inode = file->f_dentry->d_inode;
+ struct shmem_inode_info *info;
X unsigned long limit = current->rlim[RLIMIT_FSIZE].rlim_cur;
X loff_t pos;
X struct page *page;
@@ -658,7 +858,11 @@
X __get_user(dummy, buf+bytes-1);
X }
X
- page = shmem_getpage_locked(inode, index);
+ info = SHMEM_I(inode);
+ down (&info->sem);
+ page = shmem_getpage_locked(info, inode, index);
+ up (&info->sem);
+
X status = PTR_ERR(page);
X if (IS_ERR(page))
X break;
@@ -669,7 +873,6 @@
X }
X
X kaddr = kmap(page);
-// can this do a truncated write? cr
X status = copy_from_user(kaddr+offset, buf, bytes);
X kunmap(page);
X if (status)
@@ -684,9 +887,6 @@
X buf += bytes;
X if (pos > inode->i_size)
X inode->i_size = pos;
- if (inode->u.shmem_i.max_index <= index)
- inode->u.shmem_i.max_index = index+1;
-
X }
X unlock:
X /* Mark it unlocked again and drop the page.. */
@@ -792,14 +992,16 @@
X
X static int shmem_statfs(struct super_block *sb, struct statfs *buf)
X {
+ struct shmem_sb_info *sbinfo = SHMEM_SB(sb);
+
X buf->f_type = TMPFS_MAGIC;
X buf->f_bsize = PAGE_CACHE_SIZE;
- spin_lock (&sb->u.shmem_sb.stat_lock);
- buf->f_blocks = sb->u.shmem_sb.max_blocks;
- buf->f_bavail = buf->f_bfree = sb->u.shmem_sb.free_blocks;
- buf->f_files = sb->u.shmem_sb.max_inodes;
- buf->f_ffree = sb->u.shmem_sb.free_inodes;
- spin_unlock (&sb->u.shmem_sb.stat_lock);
+ spin_lock (&sbinfo->stat_lock);
+ buf->f_blocks = sbinfo->max_blocks;
+ buf->f_bavail = buf->f_bfree = sbinfo->free_blocks;
+ buf->f_files = sbinfo->max_inodes;
+ buf->f_ffree = sbinfo->free_inodes;
+ spin_unlock (&sbinfo->stat_lock);
X buf->f_namelen = 255;
X return 0;
X }
@@ -945,33 +1147,54 @@
X struct inode *inode;
X struct page *page;
X char *kaddr;
+ struct shmem_inode_info * info;
X
X error = shmem_mknod(dir, dentry, S_IFLNK | S_IRWXUGO, 0);
X if (error)
X return error;
X
- len = strlen(symname);
- if (len > PAGE_SIZE)
+ len = strlen(symname) + 1;
+ if (len > PAGE_CACHE_SIZE)
X return -ENAMETOOLONG;
X
X inode = dentry->d_inode;
- down(&inode->i_sem);
- page = shmem_getpage_locked(inode, 0);
- if (IS_ERR(page))
- goto fail;
- kaddr = kmap(page);
- memcpy(kaddr, symname, len);
- kunmap(page);
+ info = SHMEM_I(inode);
X inode->i_size = len;
- SetPageDirty(page);
- UnlockPage(page);
- page_cache_release(page);
- up(&inode->i_sem);
+ if (len <= sizeof(struct shmem_inode_info)) {
+ /* do it inline */
+ memcpy(info, symname, len);
+ inode->i_op = &shmem_symlink_inline_operations;
+ } else {
+ spin_lock (&shmem_ilock);
+ list_add (&info->list, &shmem_inodes);
+ spin_unlock (&shmem_ilock);
+ down(&info->sem);
+ page = shmem_getpage_locked(info, inode, 0);
+ if (IS_ERR(page)) {
+ up(&info->sem);
+ return PTR_ERR(page);
+ }
+ kaddr = kmap(page);
+ memcpy(kaddr, symname, len);
+ kunmap(page);
+ SetPageDirty(page);
+ UnlockPage(page);
+ page_cache_release(page);
+ up(&info->sem);
+ inode->i_op = &shmem_symlink_inode_operations;
+ }
X dir->i_ctime = dir->i_mtime = CURRENT_TIME;
X return 0;
-fail:
- up(&inode->i_sem);
- return PTR_ERR(page);
+}
+
+static int shmem_readlink_inline(struct dentry *dentry, char *buffer, int buflen)
+{
+ return vfs_readlink(dentry,buffer,buflen, (const char *)SHMEM_I(dentry->d_inode));
+}
+
+static int shmem_follow_link_inline(struct dentry *dentry, struct nameidata *nd)
+{
+ return vfs_follow_link(nd, (const char *)SHMEM_I(dentry->d_inode));
X }
X
X static int shmem_readlink(struct dentry *dentry, char *buffer, int buflen)
@@ -1001,6 +1224,17 @@
X return res;
X }
X
+static struct inode_operations shmem_symlink_inline_operations = {
+ readlink: shmem_readlink_inline,
+ follow_link: shmem_follow_link_inline,
+};
+
+static struct inode_operations shmem_symlink_inode_operations = {
+ truncate: shmem_truncate,
+ readlink: shmem_readlink,
+ follow_link: shmem_follow_link,
+};
+
X static int shmem_parse_options(char *options, int *mode, unsigned long * blocks, unsigned long *inodes)
X {
X char *this_char, *value;
@@ -1046,13 +1280,13 @@
X
X static int shmem_remount_fs (struct super_block *sb, int *flags, char *data)
X {
- struct shmem_sb_info *info = &sb->u.shmem_sb;
- unsigned long max_blocks = info->max_blocks;
- unsigned long max_inodes = info->max_inodes;
+ struct shmem_sb_info *sbinfo = &sb->u.shmem_sb;
+ unsigned long max_blocks = sbinfo->max_blocks;
+ unsigned long max_inodes = sbinfo->max_inodes;
X
X if (shmem_parse_options (data, NULL, &max_blocks, &max_inodes))
X return -EINVAL;
- return shmem_set_size(info, max_blocks, max_inodes);
+ return shmem_set_size(sbinfo, max_blocks, max_inodes);
X }
X
X int shmem_sync_file(struct file * file, struct dentry *dentry, int datasync)
@@ -1067,6 +1301,7 @@
X struct dentry * root;
X unsigned long blocks, inodes;
X int mode = S_IRWXUGO | S_ISVTX;
+ struct shmem_sb_info *sbinfo = SHMEM_SB(sb);
X struct sysinfo si;
X
X /*
@@ -1083,12 +1318,12 @@
X }
X #endif
X
- spin_lock_init (&sb->u.shmem_sb.stat_lock);
- sb->u.shmem_sb.max_blocks = blocks;
- sb->u.shmem_sb.free_blocks = blocks;
- sb->u.shmem_sb.max_inodes = inodes;
- sb->u.shmem_sb.free_inodes = inodes;
- sb->s_maxbytes = (unsigned long long)SHMEM_MAX_BLOCKS << PAGE_CACHE_SHIFT;
+ spin_lock_init (&sbinfo->stat_lock);
+ sbinfo->max_blocks = blocks;
+ sbinfo->free_blocks = blocks;
+ sbinfo->max_inodes = inodes;
+ sbinfo->free_inodes = inodes;
+ sb->s_maxbytes = (unsigned long long) SHMEM_MAX_BLOCKS << PAGE_CACHE_SHIFT;
X sb->s_blocksize = PAGE_CACHE_SIZE;
X sb->s_blocksize_bits = PAGE_CACHE_SHIFT;
X sb->s_magic = TMPFS_MAGIC;
@@ -1109,7 +1344,7 @@
X
X
X static struct address_space_operations shmem_aops = {
- writepage: shmem_writepage
+ writepage: shmem_writepage,
X };
X
X static struct file_operations shmem_file_operations = {
@@ -1125,14 +1360,6 @@
X truncate: shmem_truncate,
X };
X
-static struct inode_operations shmem_symlink_inode_operations = {
- truncate: shmem_truncate,
-#ifdef CONFIG_TMPFS
- readlink: shmem_readlink,
- follow_link: shmem_follow_link,
-#endif
-};
-
X static struct file_operations shmem_dir_operations = {
X read: generic_read_dir,
X readdir: dcache_readdir,
@@ -1202,7 +1429,7 @@
X shm_mnt = res;
X
X /* The internal instance should not do size checking */
- if ((error = shmem_set_size(&res->mnt_sb->u.shmem_sb, ULONG_MAX, ULONG_MAX)))
+ if ((error = shmem_set_size(SHMEM_SB(res->mnt_sb), ULONG_MAX, ULONG_MAX)))
X printk (KERN_ERR "could not set limits on internal tmpfs\n");
X
X return 0;
@@ -1220,73 +1447,6 @@
X module_init(init_shmem_fs)
X module_exit(exit_shmem_fs)
X
-static int shmem_clear_swp (swp_entry_t entry, swp_entry_t *ptr, int size) {
- swp_entry_t *test;
-
- for (test = ptr; test < ptr + size; test++) {
- if (test->val == entry.val) {
- swap_free (entry);
- *test = (swp_entry_t) {0};
- return test - ptr;
- }
- }
- return -1;
-}
-
-static int shmem_unuse_inode (struct inode *inode, swp_entry_t entry, struct page *page)
-{
- swp_entry_t **base, **ptr;
- unsigned long idx;
- int offset;
- struct shmem_inode_info *info = &inode->u.shmem_i;
-
- idx = 0;
- spin_lock (&info->lock);
- if ((offset = shmem_clear_swp (entry,info->i_direct, SHMEM_NR_DIRECT)) >= 0)
- goto found;
-
- idx = SHMEM_NR_DIRECT;
- if (!(base = info->i_indirect))
- goto out;
-
- for (ptr = base; ptr < base + ENTRIES_PER_PAGE; ptr++) {
- if (*ptr &&
- (offset = shmem_clear_swp (entry, *ptr, ENTRIES_PER_PAGE)) >= 0)
- goto found;
- idx += ENTRIES_PER_PAGE;
- }
-out:
- spin_unlock (&info->lock);
- return 0;
-found:
- add_to_page_cache(page, inode->i_mapping, offset + idx);
- SetPageDirty(page);
- SetPageUptodate(page);
- UnlockPage(page);
- info->swapped--;
- spin_unlock(&info->lock);


- return 1;
-}
-

-/*
- * unuse_shmem() search for an eventually swapped out shmem page.
- */
-void shmem_unuse(swp_entry_t entry, struct page *page)
-{
- struct list_head *p;
- struct inode * inode;
-
- spin_lock (&shmem_ilock);
- list_for_each(p, &shmem_inodes) {
- inode = list_entry(p, struct inode, u.shmem_i.list);
-
- if (shmem_unuse_inode(inode, entry, page))
- break;
- }
- spin_unlock (&shmem_ilock);
-}
-
-
X /*
X * shmem_file_setup - get an unlinked file living in shmem fs
X *
@@ -1306,7 +1466,7 @@
X if (size > (unsigned long long) SHMEM_MAX_BLOCKS << PAGE_CACHE_SHIFT)
X return ERR_PTR(-EINVAL);
X
- if (!vm_enough_memory((size) >> PAGE_SHIFT))
+ if (!vm_enough_memory((size) >> PAGE_CACHE_SHIFT))
X return ERR_PTR(-ENOMEM);
X
X this.name = name;
diff -u --recursive --new-file v2.4.11/linux/net/ipv4/tcp.c linux/net/ipv4/tcp.c
--- v2.4.11/linux/net/ipv4/tcp.c Tue Oct 9 17:06:53 2001
+++ linux/net/ipv4/tcp.c Wed Oct 10 23:42:47 2001
@@ -5,7 +5,7 @@
X *
X * Implementation of the Transmission Control Protocol(TCP).
X *
- * Version: $Id: tcp.c,v 1.212 2001/09/21 21:27:34 davem Exp $
+ * Version: $Id: tcp.c,v 1.213 2001/10/10 23:54:50 davem Exp $
X *
X * Authors: Ross Biro, <bi...@leland.Stanford.Edu>
X * Fred N. van Kempen, <wal...@uWalt.NL.Mugnet.ORG>
@@ -852,7 +852,7 @@
X
X page = pages[poffset/PAGE_SIZE];
X offset = poffset % PAGE_SIZE;
- size = min(psize, PAGE_SIZE-offset);
+ size = min_t(size_t, psize, PAGE_SIZE-offset);
X
X if (tp->send_head==NULL || (copy = mss_now - skb->len) <= 0) {
X new_segment:


SHAR_EOF
true || echo 'restore of patch-2.4.12 failed'

echo 'File patch-2.4.12 is complete' &&
chmod 644 patch-2.4.12 ||


echo 'restore of patch-2.4.12 failed'

Cksum="`cksum < 'patch-2.4.12'`"
if ! test "1915046491 165413" = "$Cksum" ; then
echo 'patch-2.4.12: original Checksum 1915046491 165413, current one' "$Cksum"
rm -f _shar_wnt_.tmp
rm -f _shar_seq_.tmp
exit 1
fi
rm -f _shar_wnt_.tmp
fi
rm -f _shar_seq_.tmp
echo 'You have unpacked the last part.'
exit 0

Thomas Kobienia

unread,
Oct 11, 2001, 8:00:31 PM10/11/01
to
Archive-name: v2.4/patch-2.4.12/part2

#!/bin/sh -x
# this is part 2 of a 3 - part archive


# do not concatenate these parts, unpack them in order with /bin/sh

# file patch-2.4.12 continued
if test ! -r _shar_seq_.tmp; then
echo 'Please unpack part 1 first!'
exit 1
fi
(read Scheck

if test "$Scheck" != 2; then


echo "Please unpack part $Scheck next!"
exit 1
else
exit 0
fi
) < _shar_seq_.tmp || exit 1
if test ! -f _shar_wnt_.tmp; then
echo 'x - still skipping patch-2.4.12'
else
echo 'x - continuing with patch-2.4.12'

sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.4.12' &&

+ lp->cur_rx = 0;
+ SONIC_WRITE(SONIC_URDA, lp->rda_laddr >> 16);
+ SONIC_WRITE(SONIC_CRDA, lp->rda_laddr & 0xffff);
+
+ /*
+ * initialize transmit descriptors


+ */
+ if (sonic_debug > 2)

+ printk("sonic_init: initialize transmit descriptors\n");
+ for (i = 0; i < SONIC_NUM_TDS; i++) {
+ lp->tda[i].tx_status = 0;
+ lp->tda[i].tx_config = 0;
+ lp->tda[i].tx_pktsize = 0;
+ lp->tda[i].tx_frag_count = 0;
+ lp->tda[i].link =
+ (lp->tda_laddr +
+ (i + 1) * sizeof(sonic_td_t)) | SONIC_END_OF_LINKS;
+ }
+ lp->tda[SONIC_NUM_TDS - 1].link =
+ (lp->tda_laddr & 0xffff) | SONIC_END_OF_LINKS;
+
+ SONIC_WRITE(SONIC_UTDA, lp->tda_laddr >> 16);
+ SONIC_WRITE(SONIC_CTDA, lp->tda_laddr & 0xffff);
+ lp->cur_tx = lp->dirty_tx = 0;
+
+ /*
+ * put our own address to CAM desc[0]
+ */
+ lp->cda.cam_desc[0].cam_cap0 =
+ dev->dev_addr[1] << 8 | dev->dev_addr[0];
+ lp->cda.cam_desc[0].cam_cap1 =
+ dev->dev_addr[3] << 8 | dev->dev_addr[2];
+ lp->cda.cam_desc[0].cam_cap2 =
+ dev->dev_addr[5] << 8 | dev->dev_addr[4];


+ lp->cda.cam_enable = 1;

+
+ for (i = 0; i < 16; i++)
+ lp->cda.cam_desc[i].cam_entry_pointer = i;
+
+ /*
+ * initialize CAM registers
+ */


+ SONIC_WRITE(SONIC_CDP, lp->cda_laddr & 0xffff);

+ SONIC_WRITE(SONIC_CDC, 16);
+
+ /*
+ * load the CAM
+ */
+ SONIC_WRITE(SONIC_CMD, SONIC_CR_LCAM);
+


+ i = 0;
+ while (i++ < 100) {

+ if (SONIC_READ(SONIC_ISR) & SONIC_INT_LCD)
+ break;


+ }
+ if (sonic_debug > 2) {

+ printk("sonic_init: CMD=%x, ISR=%x\n",
+ SONIC_READ(SONIC_CMD), SONIC_READ(SONIC_ISR));
+ }
+
+ /*
+ * enable receiver, disable loopback
+ * and enable all interrupts
+ */
+ SONIC_WRITE(SONIC_CMD, SONIC_CR_RXEN | SONIC_CR_STP);
+ SONIC_WRITE(SONIC_RCR, SONIC_RCR_DEFAULT);
+ SONIC_WRITE(SONIC_TCR, SONIC_TCR_DEFAULT);
+ SONIC_WRITE(SONIC_ISR, 0x7fff);
+ SONIC_WRITE(SONIC_IMR, SONIC_IMR_DEFAULT);
+
+ cmd = SONIC_READ(SONIC_CMD);
+ if ((cmd & SONIC_CR_RXEN) == 0 || (cmd & SONIC_CR_STP) == 0)
+ printk("sonic_init: failed, status=%x\n", cmd);


+
+ if (sonic_debug > 2)

+ printk("sonic_init: new status=%x\n",
+ SONIC_READ(SONIC_CMD));
+
+ return 0;
+}
diff -u --recursive --new-file v2.4.11/linux/drivers/net/sonic.h linux/drivers/net/sonic.h
--- v2.4.11/linux/drivers/net/sonic.h Sat Mar 3 10:55:47 2001
+++ linux/drivers/net/sonic.h Wed Oct 10 23:23:24 2001
@@ -13,7 +13,6 @@
X * see CONFIG_MACSONIC branch below.
X *
X */
-
X #ifndef SONIC_H
X #define SONIC_H
X
@@ -22,7 +21,7 @@
X /*
X * SONIC register offsets
X */
-
+
X #define SONIC_CMD 0x00
X #define SONIC_DCR 0x01
X #define SONIC_RCR 0x02
@@ -219,16 +218,16 @@
X
X
X #ifdef CONFIG_MACSONIC
-/* Big endian like structures on Mac
- * (680x0)
+/*
+ * Big endian like structures on 680x0 Macs
X */
X
X typedef struct {
- u32 rx_bufadr_l; /* receive buffer ptr */
- u32 rx_bufadr_h;
+ u32 rx_bufadr_l; /* receive buffer ptr */
+ u32 rx_bufadr_h;
X
- u32 rx_bufsize_l; /* no. of words in the receive buffer */
- u32 rx_bufsize_h;
+ u32 rx_bufsize_l; /* no. of words in the receive buffer */
+ u32 rx_bufsize_h;
X } sonic_rr_t;
X
X /*
@@ -237,35 +236,35 @@
X */
X
X typedef struct {
- SREGS_PAD(pad0);
- u16 rx_status; /* status after reception of a packet */
- SREGS_PAD(pad1);
- u16 rx_pktlen; /* length of the packet incl. CRC */
-
- /*
- * Pointers to the location in the receive buffer area (RBA)
- * where the packet resides. A packet is always received into
- * a contiguous piece of memory.
- */
- SREGS_PAD(pad2);
- u16 rx_pktptr_l;
- SREGS_PAD(pad3);
- u16 rx_pktptr_h;
-
- SREGS_PAD(pad4);
- u16 rx_seqno; /* sequence no. */
-
- SREGS_PAD(pad5);
- u16 link; /* link to next RDD (end if EOL bit set) */
-
- /*
- * Owner of this descriptor, 0= driver, 1=sonic
- */
-
- SREGS_PAD(pad6);
- u16 in_use;
+ SREGS_PAD(pad0);
+ u16 rx_status; /* status after reception of a packet */
+ SREGS_PAD(pad1);
+ u16 rx_pktlen; /* length of the packet incl. CRC */
+
+ /*
+ * Pointers to the location in the receive buffer area (RBA)
+ * where the packet resides. A packet is always received into
+ * a contiguous piece of memory.
+ */
+ SREGS_PAD(pad2);
+ u16 rx_pktptr_l;
+ SREGS_PAD(pad3);
+ u16 rx_pktptr_h;
+
+ SREGS_PAD(pad4);
+ u16 rx_seqno; /* sequence no. */
+
+ SREGS_PAD(pad5);
+ u16 link; /* link to next RDD (end if EOL bit set) */
+
+ /*
+ * Owner of this descriptor, 0= driver, 1=sonic
+ */
+
+ SREGS_PAD(pad6);
+ u16 in_use;
X
- caddr_t rda_next; /* pointer to next RD */
+ caddr_t rda_next; /* pointer to next RD */
X } sonic_rd_t;
X
X
@@ -273,24 +272,24 @@
X * Describes a Transmit Descriptor
X */
X typedef struct {
- SREGS_PAD(pad0);
- u16 tx_status; /* status after transmission of a packet */
- SREGS_PAD(pad1);
- u16 tx_config; /* transmit configuration for this packet */
- SREGS_PAD(pad2);
- u16 tx_pktsize; /* size of the packet to be transmitted */
- SREGS_PAD(pad3);
- u16 tx_frag_count; /* no. of fragments */
-
- SREGS_PAD(pad4);
- u16 tx_frag_ptr_l;
- SREGS_PAD(pad5);
- u16 tx_frag_ptr_h;
- SREGS_PAD(pad6);
- u16 tx_frag_size;
-
- SREGS_PAD(pad7);
- u16 link; /* ptr to next descriptor */
+ SREGS_PAD(pad0);
+ u16 tx_status; /* status after transmission of a packet */
+ SREGS_PAD(pad1);
+ u16 tx_config; /* transmit configuration for this packet */
+ SREGS_PAD(pad2);
+ u16 tx_pktsize; /* size of the packet to be transmitted */
+ SREGS_PAD(pad3);
+ u16 tx_frag_count; /* no. of fragments */
+
+ SREGS_PAD(pad4);
+ u16 tx_frag_ptr_l;
+ SREGS_PAD(pad5);
+ u16 tx_frag_ptr_h;
+ SREGS_PAD(pad6);
+ u16 tx_frag_size;
+
+ SREGS_PAD(pad7);
+ u16 link; /* ptr to next descriptor */
X } sonic_td_t;
X
X
@@ -299,37 +298,37 @@
X */
X
X typedef struct {
- SREGS_PAD(pad0);
- u16 cam_entry_pointer;
- SREGS_PAD(pad1);
- u16 cam_cap0;
- SREGS_PAD(pad2);
- u16 cam_cap1;
- SREGS_PAD(pad3);
- u16 cam_cap2;
+ SREGS_PAD(pad0);
+ u16 cam_entry_pointer;
+ SREGS_PAD(pad1);
+ u16 cam_cap0;
+ SREGS_PAD(pad2);
+ u16 cam_cap1;
+ SREGS_PAD(pad3);
+ u16 cam_cap2;
X } sonic_cd_t;
X
X #define CAM_DESCRIPTORS 16
X
X
X typedef struct {
- sonic_cd_t cam_desc[CAM_DESCRIPTORS];
- SREGS_PAD(pad);
- u16 cam_enable;
+ sonic_cd_t cam_desc[CAM_DESCRIPTORS];
+ SREGS_PAD(pad);
+ u16 cam_enable;
X } sonic_cda_t;
X
-#else /* original declarations, little endian 32 bit */
+#else /* original declarations, little endian 32 bit */
X
X /*
X * structure definitions
X */
X
X typedef struct {
- u32 rx_bufadr_l; /* receive buffer ptr */
- u32 rx_bufadr_h;
+ u32 rx_bufadr_l; /* receive buffer ptr */
+ u32 rx_bufadr_h;
X
- u32 rx_bufsize_l; /* no. of words in the receive buffer */
- u32 rx_bufsize_h;
+ u32 rx_bufsize_l; /* no. of words in the receive buffer */
+ u32 rx_bufsize_h;
X } sonic_rr_t;
X
X /*
@@ -338,35 +337,35 @@
X */
X
X typedef struct {
- u16 rx_status; /* status after reception of a packet */
- SREGS_PAD(pad0);
- u16 rx_pktlen; /* length of the packet incl. CRC */
- SREGS_PAD(pad1);
-
- /*
- * Pointers to the location in the receive buffer area (RBA)
- * where the packet resides. A packet is always received into
- * a contiguous piece of memory.
- */
- u16 rx_pktptr_l;
- SREGS_PAD(pad2);
- u16 rx_pktptr_h;
- SREGS_PAD(pad3);
-
- u16 rx_seqno; /* sequence no. */
- SREGS_PAD(pad4);
-
- u16 link; /* link to next RDD (end if EOL bit set) */
- SREGS_PAD(pad5);
-
- /*
- * Owner of this descriptor, 0= driver, 1=sonic
- */
-
- u16 in_use;
- SREGS_PAD(pad6);
+ u16 rx_status; /* status after reception of a packet */
+ SREGS_PAD(pad0);
+ u16 rx_pktlen; /* length of the packet incl. CRC */
+ SREGS_PAD(pad1);
+
+ /*
+ * Pointers to the location in the receive buffer area (RBA)
+ * where the packet resides. A packet is always received into
+ * a contiguous piece of memory.
+ */
+ u16 rx_pktptr_l;
+ SREGS_PAD(pad2);
+ u16 rx_pktptr_h;
+ SREGS_PAD(pad3);
+
+ u16 rx_seqno; /* sequence no. */
+ SREGS_PAD(pad4);
+
+ u16 link; /* link to next RDD (end if EOL bit set) */
+ SREGS_PAD(pad5);
+
+ /*
+ * Owner of this descriptor, 0= driver, 1=sonic
+ */
+
+ u16 in_use;
+ SREGS_PAD(pad6);
X
- caddr_t rda_next; /* pointer to next RD */
+ caddr_t rda_next; /* pointer to next RD */
X } sonic_rd_t;
X
X
@@ -374,24 +373,24 @@
X * Describes a Transmit Descriptor
X */
X typedef struct {
- u16 tx_status; /* status after transmission of a packet */
- SREGS_PAD(pad0);
- u16 tx_config; /* transmit configuration for this packet */
- SREGS_PAD(pad1);
- u16 tx_pktsize; /* size of the packet to be transmitted */
- SREGS_PAD(pad2);
- u16 tx_frag_count; /* no. of fragments */
- SREGS_PAD(pad3);
-
- u16 tx_frag_ptr_l;
- SREGS_PAD(pad4);
- u16 tx_frag_ptr_h;
- SREGS_PAD(pad5);
- u16 tx_frag_size;
- SREGS_PAD(pad6);
-
- u16 link; /* ptr to next descriptor */
- SREGS_PAD(pad7);
+ u16 tx_status; /* status after transmission of a packet */
+ SREGS_PAD(pad0);
+ u16 tx_config; /* transmit configuration for this packet */
+ SREGS_PAD(pad1);
+ u16 tx_pktsize; /* size of the packet to be transmitted */
+ SREGS_PAD(pad2);
+ u16 tx_frag_count; /* no. of fragments */
+ SREGS_PAD(pad3);
+
+ u16 tx_frag_ptr_l;
+ SREGS_PAD(pad4);
+ u16 tx_frag_ptr_h;
+ SREGS_PAD(pad5);
+ u16 tx_frag_size;
+ SREGS_PAD(pad6);
+
+ u16 link; /* ptr to next descriptor */
+ SREGS_PAD(pad7);
X } sonic_td_t;
X
X
@@ -400,25 +399,25 @@
X */
X
X typedef struct {
- u16 cam_entry_pointer;
- SREGS_PAD(pad0);
- u16 cam_cap0;
- SREGS_PAD(pad1);
- u16 cam_cap1;
- SREGS_PAD(pad2);
- u16 cam_cap2;
- SREGS_PAD(pad3);
+ u16 cam_entry_pointer;
+ SREGS_PAD(pad0);
+ u16 cam_cap0;
+ SREGS_PAD(pad1);
+ u16 cam_cap1;
+ SREGS_PAD(pad2);
+ u16 cam_cap2;
+ SREGS_PAD(pad3);
X } sonic_cd_t;
X
X #define CAM_DESCRIPTORS 16
X
X
X typedef struct {
- sonic_cd_t cam_desc[CAM_DESCRIPTORS];
- u16 cam_enable;
- SREGS_PAD(pad);
+ sonic_cd_t cam_desc[CAM_DESCRIPTORS];
+ u16 cam_enable;
+ SREGS_PAD(pad);
X } sonic_cda_t;
-#endif /* endianness */
+#endif /* endianness */
X
X /*
X * Some tunables for the buffer areas. Power of 2 is required
@@ -427,15 +426,15 @@
X * MSch: use more buffer space for the slow m68k Macs!
X */
X #ifdef CONFIG_MACSONIC
-#define SONIC_NUM_RRS 32 /* number of receive resources */
-#define SONIC_NUM_RDS SONIC_NUM_RRS /* number of receive descriptors */
-#define SONIC_NUM_TDS 32 /* number of transmit descriptors */
+#define SONIC_NUM_RRS 32 /* number of receive resources */
+#define SONIC_NUM_RDS SONIC_NUM_RRS /* number of receive descriptors */
+#define SONIC_NUM_TDS 32 /* number of transmit descriptors */
X #else
-#define SONIC_NUM_RRS 16 /* number of receive resources */
-#define SONIC_NUM_RDS SONIC_NUM_RRS /* number of receive descriptors */
-#define SONIC_NUM_TDS 16 /* number of transmit descriptors */
+#define SONIC_NUM_RRS 16 /* number of receive resources */
+#define SONIC_NUM_RDS SONIC_NUM_RRS /* number of receive descriptors */
+#define SONIC_NUM_TDS 16 /* number of transmit descriptors */
X #endif
-#define SONIC_RBSIZE 1520 /* size of one resource buffer */
+#define SONIC_RBSIZE 1520 /* size of one resource buffer */
X
X #define SONIC_RDS_MASK (SONIC_NUM_RDS-1)
X #define SONIC_TDS_MASK (SONIC_NUM_TDS-1)
@@ -443,26 +442,28 @@
X
X /* Information that need to be kept for each board. */
X struct sonic_local {
- sonic_cda_t cda; /* virtual CPU address of CDA */
- sonic_td_t tda[SONIC_NUM_TDS]; /* transmit descriptor area */
- sonic_rr_t rra[SONIC_NUM_RRS]; /* receive resource area */
- sonic_rd_t rda[SONIC_NUM_RDS]; /* receive descriptor area */
- struct sk_buff* tx_skb[SONIC_NUM_TDS]; /* skbuffs for packets to transmit */
- unsigned int tx_laddr[SONIC_NUM_TDS]; /* logical DMA address fro skbuffs */
- unsigned char *rba; /* start of receive buffer areas */
- unsigned int cda_laddr; /* logical DMA address of CDA */
- unsigned int tda_laddr; /* logical DMA address of TDA */
- unsigned int rra_laddr; /* logical DMA address of RRA */
- unsigned int rda_laddr; /* logical DMA address of RDA */
- unsigned int rba_laddr; /* logical DMA address of RBA */
- unsigned int cur_rra; /* current indexes to resource areas */
- unsigned int cur_rx;
- unsigned int cur_tx;
- unsigned int dirty_tx; /* last unacked transmit packet */
- char tx_full;
- struct net_device_stats stats;
+ sonic_cda_t cda; /* virtual CPU address of CDA */
+ sonic_td_t tda[SONIC_NUM_TDS]; /* transmit descriptor area */
+ sonic_rr_t rra[SONIC_NUM_RRS]; /* receive resource area */
+ sonic_rd_t rda[SONIC_NUM_RDS]; /* receive descriptor area */
+ struct sk_buff *tx_skb[SONIC_NUM_TDS]; /* skbuffs for packets to transmit */
+ unsigned int tx_laddr[SONIC_NUM_TDS]; /* logical DMA address fro skbuffs */
+ unsigned char *rba; /* start of receive buffer areas */
+ unsigned int cda_laddr; /* logical DMA address of CDA */
+ unsigned int tda_laddr; /* logical DMA address of TDA */
+ unsigned int rra_laddr; /* logical DMA address of RRA */
+ unsigned int rda_laddr; /* logical DMA address of RDA */
+ unsigned int rba_laddr; /* logical DMA address of RBA */
+ unsigned int cur_rra; /* current indexes to resource areas */
+ unsigned int cur_rx;
+ unsigned int cur_tx;
+ unsigned int dirty_tx; /* last unacked transmit packet */
+ char tx_full;
+ struct net_device_stats stats;
X };
X
+#define TX_TIMEOUT 6
+
X /* Index to functions, as function prototypes. */
X
X static int sonic_open(struct net_device *dev);
@@ -473,8 +474,9 @@
X static struct net_device_stats *sonic_get_stats(struct net_device *dev);
X static void sonic_multicast_list(struct net_device *dev);
X static int sonic_init(struct net_device *dev);
+static void sonic_tx_timeout(struct net_device *dev);
X
X static const char *version =
- "sonic.c:v0.92 20.9.98 tsbo...@alpha.franken.de\n";
+ "sonic.c:v0.92 20.9.98 tsbo...@alpha.franken.de\n";
X
X #endif /* SONIC_H */
diff -u --recursive --new-file v2.4.11/linux/drivers/parport/ChangeLog linux/drivers/parport/ChangeLog
--- v2.4.11/linux/drivers/parport/ChangeLog Tue Oct 9 17:06:52 2001
+++ linux/drivers/parport/ChangeLog Wed Oct 10 23:19:30 2001
@@ -1,3 +1,23 @@
+2001-10-10 Tim Waugh <twa...@redhat.com>
+
+ * parport_pc.c: Support for OX16PCI954 PCI card.
+
+2001-10-10 Tim Waugh <twa...@redhat.com>
+
+ * parport_pc.c: Support for OX12PCI840 PCI card (reported by
+ m...@daveg.com). Lock-ups diagnosed by Ronnie Arosa (and now we
+ just don't trust its ECR).
+
+2001-10-10 Gunther Mayer <gunthe...@braunschweig.okersurf.de>
+
+ * parport_pc.c: Support for AVLAB cards.
+
+2001-10-10 Tim Waugh <twa...@redhat.com>
+
+ * ieee1284_ops.c (ecp_forward_to_reverse, ecp_reverse_to_forward):
+ Remember to retry direction switch if it fails. Patch from David
+ Lambert.
+
X 2001-10-08 David C. Hansen <have...@us.ibm.com>
X
X * share.c: Make driverlist_lock and parportlist_lock static.
diff -u --recursive --new-file v2.4.11/linux/drivers/parport/ieee1284_ops.c linux/drivers/parport/ieee1284_ops.c
--- v2.4.11/linux/drivers/parport/ieee1284_ops.c Sat May 19 18:07:04 2001
+++ linux/drivers/parport/ieee1284_ops.c Wed Oct 10 23:19:30 2001
@@ -359,6 +359,10 @@
X DPRINTK (KERN_DEBUG "%s: ECP direction: reverse\n",
X port->name);
X port->ieee1284.phase = IEEE1284_PH_REV_IDLE;
+ } else {
+ DPRINTK (KERN_DEBUG "%s: ECP direction: failed to reverse\n",
+ port->name);
+ port->ieee1284.phase = IEEE1284_PH_DIR_UNKNOWN;
X }
X
X return retval;
@@ -386,7 +390,13 @@
X DPRINTK (KERN_DEBUG "%s: ECP direction: forward\n",
X port->name);
X port->ieee1284.phase = IEEE1284_PH_FWD_IDLE;
+ } else {
+ DPRINTK (KERN_DEBUG
+ "%s: ECP direction: failed to switch forward\n",
+ port->name);
+ port->ieee1284.phase = IEEE1284_PH_DIR_UNKNOWN;
X }
+
X
X return retval;
X }
diff -u --recursive --new-file v2.4.11/linux/drivers/parport/parport_pc.c linux/drivers/parport/parport_pc.c
--- v2.4.11/linux/drivers/parport/parport_pc.c Tue Oct 9 17:06:52 2001
+++ linux/drivers/parport/parport_pc.c Wed Oct 10 23:19:30 2001
@@ -2528,7 +2528,6 @@
X lava_parallel_dual_b,
X boca_ioppar,
X plx_9050,
- afavlab_tk9902,
X timedia_4078a,
X timedia_4079h,
X timedia_4085h,
@@ -2556,6 +2555,10 @@
X syba_1p_ecp,
X titan_010l,
X titan_1284p2,
+ avlab_1p,
+ avlab_2p,
+ oxsemi_954,
+ oxsemi_840,
X };
X
X
@@ -2594,7 +2597,6 @@
X /* lava_parallel_dual_b */ { 1, { { 0, -1 }, } },
X /* boca_ioppar */ { 1, { { 0, -1 }, } },
X /* plx_9050 */ { 2, { { 4, -1 }, { 5, -1 }, } },
- /* afavlab_tk9902 */ { 1, { { 0, 1 }, } },
X /* timedia_4078a */ { 1, { { 2, -1 }, } },
X /* timedia_4079h */ { 1, { { 2, 3 }, } },
X /* timedia_4085h */ { 2, { { 2, -1 }, { 4, -1 }, } },
@@ -2624,6 +2626,12 @@
X /* syba_1p_ecp W83787 */ { 1, { { 0, 0x078 }, } },
X /* titan_010l */ { 1, { { 3, -1 }, } },
X /* titan_1284p2 */ { 2, { { 0, 1 }, { 2, 3 }, } },
+ /* avlab_1p */ { 1, { { 0, 1}, } },
+ /* avlab_2p */ { 2, { { 0, 1}, { 2, 3 },} },
+ /* The Oxford Semi cards are unusual: 954 doesn't support ECP,
+ * and 840 locks up if you write 1 to bit 2! */
+ /* oxsemi_954 */ { 1, { { 0, -1 }, } },
+ /* oxsemi_840 */ { 1, { { 0, -1 }, } },
X };
X
X static struct pci_device_id parport_pc_pci_tbl[] __devinitdata = {
@@ -2679,8 +2687,6 @@
X PCI_ANY_ID, PCI_ANY_ID, 0, 0, boca_ioppar },
X { PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9050,
X PCI_SUBVENDOR_ID_EXSYS, PCI_SUBDEVICE_ID_EXSYS_4014, 0,0, plx_9050 },
- { PCI_VENDOR_ID_AFAVLAB, PCI_DEVICE_ID_AFAVLAB_TK9902,
- PCI_ANY_ID, PCI_ANY_ID, 0, 0, afavlab_tk9902 },
X /* PCI_VENDOR_ID_TIMEDIA/SUNIX has many differing cards ...*/
X { 0x1409, 0x7168, 0x1409, 0x4078, 0, 0, timedia_4078a },
X { 0x1409, 0x7168, 0x1409, 0x4079, 0, 0, timedia_4079h },
@@ -2712,6 +2718,13 @@
X { PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_010L,
X PCI_ANY_ID, PCI_ANY_ID, 0, 0, titan_010l },
X { 0x9710, 0x9815, 0x1000, 0x0020, 0, 0, titan_1284p2 },
+ /* PCI_VENDOR_ID_AVLAB/Intek21 has another bunch of cards ...*/
+ { 0x14db, 0x2120, PCI_ANY_ID, PCI_ANY_ID, 0, 0, avlab_1p}, /* AFAVLAB_TK9902 */
+ { 0x14db, 0x2121, PCI_ANY_ID, PCI_ANY_ID, 0, 0, avlab_2p},
+ { PCI_VENDOR_ID_OXSEMI, PCI_DEVICE_ID_OXSEMI_16PCI954PP,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0, oxsemi_954 },
+ { PCI_VENDOR_ID_OXSEMI, PCI_DEVICE_ID_OXSEMI_12PCI840,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0, oxsemi_840 },
X { 0, } /* terminate list */
X };
X MODULE_DEVICE_TABLE(pci,parport_pc_pci_tbl);
diff -u --recursive --new-file v2.4.11/linux/drivers/sbus/audio/audio.c linux/drivers/sbus/audio/audio.c
--- v2.4.11/linux/drivers/sbus/audio/audio.c Mon Aug 27 12:41:44 2001
+++ linux/drivers/sbus/audio/audio.c Wed Oct 10 23:42:46 2001
@@ -1,4 +1,4 @@
-/* $Id: audio.c,v 1.61 2001/08/13 14:40:12 davem Exp $
+/* $Id: audio.c,v 1.62 2001/10/08 22:19:50 davem Exp $
X * drivers/sbus/audio/audio.c
X *
X * Copyright 1996 Thomas K. Dyas (td...@noc.rutgers.edu)
@@ -2138,8 +2138,9 @@
X devfs_unregister (devfs_handle);
X }
X
-module_init(sparcaudio_init)
-module_exit(sparcaudio_exit)
+module_init(sparcaudio_init);
+module_exit(sparcaudio_exit);
+MODULE_LICENSE("GPL");
X
X /*
X * Code from Linux Streams, Copyright 1995 by
diff -u --recursive --new-file v2.4.11/linux/drivers/sbus/audio/cs4231.c linux/drivers/sbus/audio/cs4231.c
--- v2.4.11/linux/drivers/sbus/audio/cs4231.c Tue Jul 3 17:08:20 2001
+++ linux/drivers/sbus/audio/cs4231.c Wed Oct 10 23:42:46 2001
@@ -1,4 +1,4 @@
-/* $Id: cs4231.c,v 1.46 2001/05/21 01:25:22 davem Exp $
+/* $Id: cs4231.c,v 1.47 2001/10/08 22:19:50 davem Exp $
X * drivers/sbus/audio/cs4231.c
X *
X * Copyright 1996, 1997, 1998, 1999 Derrick J Brashear (sha...@andrew.cmu.edu)
@@ -2443,6 +2443,7 @@
X
X module_init(cs4231_init);
X module_exit(cs4231_exit);
+MODULE_LICENSE("GPL");
X /*
X * Overrides for Emacs so that we follow Linus's tabbing style.
X * Emacs will notice this stuff at the end of the file and automatically
diff -u --recursive --new-file v2.4.11/linux/drivers/sbus/audio/dbri.c linux/drivers/sbus/audio/dbri.c
--- v2.4.11/linux/drivers/sbus/audio/dbri.c Tue Jul 3 17:08:20 2001
+++ linux/drivers/sbus/audio/dbri.c Wed Oct 10 23:42:46 2001
@@ -1,4 +1,4 @@
-/* $Id: dbri.c,v 1.26 2001/05/21 01:25:22 davem Exp $
+/* $Id: dbri.c,v 1.27 2001/10/08 22:19:50 davem Exp $
X * drivers/sbus/audio/dbri.c
X *
X * Copyright (C) 1997 Rudolf Koenig (rfko...@immd4.informatik.uni-erlangen.de)
@@ -2377,6 +2377,8 @@
X
X module_init(dbri_init);
X module_exit(dbri_exit);
+MODULE_LICENSE("GPL");
+
X /*
X * Overrides for Emacs so that we follow Linus's tabbing style.
X * Emacs will notice this stuff at the end of the file and automatically
diff -u --recursive --new-file v2.4.11/linux/drivers/sbus/audio/dmy.c linux/drivers/sbus/audio/dmy.c
--- v2.4.11/linux/drivers/sbus/audio/dmy.c Tue Jul 3 17:08:20 2001
+++ linux/drivers/sbus/audio/dmy.c Wed Oct 10 23:42:46 2001
@@ -1,4 +1,4 @@
-/* $Id: dmy.c,v 1.9 2001/05/22 23:16:10 davem Exp $
+/* $Id: dmy.c,v 1.10 2001/10/08 22:19:50 davem Exp $
X * drivers/sbus/audio/dummy.c
X *
X * Copyright 1998 Derrick J Brashear (sha...@andrew.cmu.edu)
@@ -783,6 +783,8 @@
X
X module_init(dummy_init);
X module_exit(dummy_exit);
+MODULE_LICENSE("GPL");
+
X /*
X * Overrides for Emacs so that we follow Linus's tabbing style.
X * Emacs will notice this stuff at the end of the file and automatically
diff -u --recursive --new-file v2.4.11/linux/drivers/sbus/char/aurora.c linux/drivers/sbus/char/aurora.c
--- v2.4.11/linux/drivers/sbus/char/aurora.c Mon Aug 27 12:41:44 2001
+++ linux/drivers/sbus/char/aurora.c Wed Oct 10 23:42:47 2001
@@ -1,4 +1,4 @@
-/* $Id: aurora.c,v 1.15 2001/08/13 14:40:08 davem Exp $
+/* $Id: aurora.c,v 1.16 2001/10/08 22:19:51 davem Exp $
X * linux/drivers/sbus/char/aurora.c -- Aurora multiport driver
X *
X * Copyright (c) 1999 by Oliver Aldulea (oli at bv dot ro)
@@ -2482,3 +2482,4 @@
X
X module_init(aurora_init);
X module_exit(aurora_cleanup);
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.11/linux/drivers/sbus/char/bpp.c linux/drivers/sbus/char/bpp.c
--- v2.4.11/linux/drivers/sbus/char/bpp.c Mon Jan 22 13:30:20 2001
+++ linux/drivers/sbus/char/bpp.c Wed Oct 10 23:42:47 2001


@@ -1073,3 +1073,4 @@
X

X module_init(bpp_init);
X module_exit(bpp_cleanup);
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.11/linux/drivers/sbus/char/cpwatchdog.c linux/drivers/sbus/char/cpwatchdog.c
--- v2.4.11/linux/drivers/sbus/char/cpwatchdog.c Thu Apr 12 12:10:25 2001
+++ linux/drivers/sbus/char/cpwatchdog.c Wed Oct 10 23:42:47 2001
@@ -193,6 +193,7 @@
X ("Eric Brower <ebr...@usa.net>");
X MODULE_DESCRIPTION
X ("Hardware watchdog driver for Sun Microsystems CP1400/1500");
+MODULE_LICENSE("GPL");
X MODULE_SUPPORTED_DEVICE
X ("watchdog");
X #endif /* ifdef MODULE */
diff -u --recursive --new-file v2.4.11/linux/drivers/sbus/char/display7seg.c linux/drivers/sbus/char/display7seg.c
--- v2.4.11/linux/drivers/sbus/char/display7seg.c Thu Nov 9 15:57:41 2000
+++ linux/drivers/sbus/char/display7seg.c Wed Oct 10 23:42:47 2001
@@ -1,4 +1,4 @@
-/* $Id: display7seg.c,v 1.4 2000/11/08 05:08:23 davem Exp $
+/* $Id: display7seg.c,v 1.5 2001/10/08 22:19:51 davem Exp $
X *
X * display7seg - Driver implementation for the 7-segment display
X * present on Sun Microsystems CP1400 and CP1500
@@ -55,6 +55,7 @@
X ("Eric Brower <ebr...@usa.net>");
X MODULE_DESCRIPTION
X ("7-Segment Display driver for Sun Microsystems CP1400/1500");
+MODULE_LICENSE("GPL");
X MODULE_SUPPORTED_DEVICE
X ("d7s");
X #endif /* ifdef MODULE */
diff -u --recursive --new-file v2.4.11/linux/drivers/sbus/char/envctrl.c linux/drivers/sbus/char/envctrl.c
--- v2.4.11/linux/drivers/sbus/char/envctrl.c Mon Aug 27 12:41:44 2001
+++ linux/drivers/sbus/char/envctrl.c Wed Oct 10 23:42:47 2001
@@ -1,4 +1,4 @@
-/* $Id: envctrl.c,v 1.23 2001/08/09 23:42:09 davem Exp $
+/* $Id: envctrl.c,v 1.24 2001/10/08 22:19:51 davem Exp $
X * envctrl.c: Temperature and Fan monitoring on Machines providing it.
X *
X * Copyright (C) 1998 Eddie C. Dost (e...@skynet.be)
@@ -1175,3 +1175,4 @@
X
X module_init(envctrl_init);
X module_exit(envctrl_cleanup);
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.11/linux/drivers/sbus/char/flash.c linux/drivers/sbus/char/flash.c
--- v2.4.11/linux/drivers/sbus/char/flash.c Tue Mar 6 22:44:16 2001
+++ linux/drivers/sbus/char/flash.c Wed Oct 10 23:42:47 2001
@@ -1,4 +1,4 @@
-/* $Id: flash.c,v 1.23 2001/03/02 06:32:40 davem Exp $
+/* $Id: flash.c,v 1.24 2001/10/08 22:19:51 davem Exp $
X * flash.c: Allow mmap access to the OBP Flash, for OBP updates.
X *
X * Copyright (C) 1997 Eddie C. Dost (e...@skynet.be)
@@ -247,3 +247,4 @@
X
X module_init(flash_init);
X module_exit(flash_cleanup);
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.11/linux/drivers/sbus/char/jsflash.c linux/drivers/sbus/char/jsflash.c
--- v2.4.11/linux/drivers/sbus/char/jsflash.c Sun Sep 23 11:40:59 2001
+++ linux/drivers/sbus/char/jsflash.c Wed Oct 10 23:42:47 2001
@@ -682,6 +682,7 @@
X }
X
X #ifdef MODULE
+MODULE_LICENSE("GPL");
X
X int init_module(void) {
X int rc;
diff -u --recursive --new-file v2.4.11/linux/drivers/sbus/char/openprom.c linux/drivers/sbus/char/openprom.c
--- v2.4.11/linux/drivers/sbus/char/openprom.c Mon Aug 27 12:41:44 2001
+++ linux/drivers/sbus/char/openprom.c Wed Oct 10 23:42:47 2001
@@ -653,3 +653,4 @@
X
X module_init(openprom_init);
X module_exit(openprom_cleanup);
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.11/linux/drivers/sbus/char/riowatchdog.c linux/drivers/sbus/char/riowatchdog.c
--- v2.4.11/linux/drivers/sbus/char/riowatchdog.c Thu Apr 12 12:10:25 2001
+++ linux/drivers/sbus/char/riowatchdog.c Wed Oct 10 23:42:47 2001
@@ -1,4 +1,4 @@
-/* $Id: riowatchdog.c,v 1.2 2001/03/26 23:47:18 davem Exp $
+/* $Id: riowatchdog.c,v 1.3 2001/10/08 22:19:51 davem Exp $
X * riowatchdog.c - driver for hw watchdog inside Super I/O of RIO
X *
X * Copyright (C) 2001 David S. Miller (da...@redhat.com)
@@ -47,6 +47,7 @@
X MODULE_AUTHOR("David S. Miller <da...@redhat.com>");
X MODULE_DESCRIPTION("Hardware watchdog driver for Sun RIO");
X MODULE_SUPPORTED_DEVICE("watchdog");
+MODULE_LICENSE("GPL");
X
X #define RIOWD_NAME "pmc"
X #define RIOWD_MINOR 215
diff -u --recursive --new-file v2.4.11/linux/drivers/sbus/char/rtc.c linux/drivers/sbus/char/rtc.c
--- v2.4.11/linux/drivers/sbus/char/rtc.c Mon Aug 27 12:41:44 2001
+++ linux/drivers/sbus/char/rtc.c Wed Oct 10 23:42:47 2001
@@ -1,4 +1,4 @@
-/* $Id: rtc.c,v 1.27 2001/08/13 14:40:08 davem Exp $
+/* $Id: rtc.c,v 1.28 2001/10/08 22:19:51 davem Exp $
X *
X * Linux/SPARC Real Time Clock Driver
X * Copyright (C) 1996 Thomas K. Dyas (td...@eden.rutgers.edu)
@@ -174,3 +174,4 @@
X
X module_init(rtc_sun_init);
X module_exit(rtc_sun_cleanup);
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.11/linux/drivers/sbus/char/sab82532.c linux/drivers/sbus/char/sab82532.c
--- v2.4.11/linux/drivers/sbus/char/sab82532.c Tue Jul 3 17:08:20 2001
+++ linux/drivers/sbus/char/sab82532.c Wed Oct 10 23:42:47 2001
@@ -1,4 +1,4 @@
-/* $Id: sab82532.c,v 1.63 2001/06/29 21:23:44 davem Exp $
+/* $Id: sab82532.c,v 1.64 2001/10/08 22:19:51 davem Exp $
X * sab82532.c: ASYNC Driver for the SIEMENS SAB82532 DUSCC.
X *
X * Copyright (C) 1997 Eddie C. Dost (e...@skynet.be)
@@ -2205,7 +2205,7 @@
X
X static inline void __init show_serial_version(void)
X {
- char *revision = "$Revision: 1.63 $";
+ char *revision = "$Revision: 1.64 $";
X char *version, *p;
X
X version = strchr(revision, ' ');
@@ -2427,6 +2427,8 @@
X }
X
X #ifdef MODULE
+MODULE_LICENSE("GPL");
+
X int init_module(void)
X {
X if (get_sab82532(0))
diff -u --recursive --new-file v2.4.11/linux/drivers/sbus/char/uctrl.c linux/drivers/sbus/char/uctrl.c
--- v2.4.11/linux/drivers/sbus/char/uctrl.c Mon Aug 27 12:41:44 2001
+++ linux/drivers/sbus/char/uctrl.c Wed Oct 10 23:42:47 2001
@@ -1,4 +1,4 @@
-/* $Id: uctrl.c,v 1.11 2001/08/13 14:40:08 davem Exp $
+/* $Id: uctrl.c,v 1.12 2001/10/08 22:19:51 davem Exp $
X * uctrl.c: TS102 Microcontroller interface on Tadpole Sparcbook 3
X *
X * Copyright 1999 Derrick J Brashear (sha...@dementia.org)
@@ -424,3 +424,4 @@
X
X module_init(ts102_uctrl_init);
X module_exit(ts102_uctrl_cleanup);
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.11/linux/drivers/scsi/aic7xxx_old.c linux/drivers/scsi/aic7xxx_old.c
--- v2.4.11/linux/drivers/scsi/aic7xxx_old.c Tue Oct 9 17:06:52 2001
+++ linux/drivers/scsi/aic7xxx_old.c Wed Oct 10 09:31:46 2001
@@ -219,9 +219,7 @@
X * #define AIC7XXX_VERBOSE_DEBUGGING
X */
X
-#if defined(MODULE) || defined(PCMCIA)
X #include <linux/module.h>
-#endif
X
X #if defined(PCMCIA)
X # undef MODULE
diff -u --recursive --new-file v2.4.11/linux/drivers/usb/serial/belkin_sa.c linux/drivers/usb/serial/belkin_sa.c
--- v2.4.11/linux/drivers/usb/serial/belkin_sa.c Tue Oct 9 17:06:52 2001
+++ linux/drivers/usb/serial/belkin_sa.c Wed Oct 10 23:42:47 2001
@@ -23,8 +23,8 @@
X * framework in, but haven't analyzed the "tty_flip" interface yet.
X * -- Add support for flush commands
X * -- Add everything that is missing :)
- *
- * (30-May-2001 gkh
+ *
+ * 30-May-2001 gkh
X * switched from using spinlock to a semaphore, which fixes lots of problems.
X *
X * 08-Apr-2001 gb
@@ -350,6 +350,15 @@
X
X static void belkin_sa_close (struct usb_serial_port *port, struct file *filp)
X {
+ struct usb_serial *serial;
+
+ if (port_paranoia_check (port, __FUNCTION__))
+ return;
+
+ serial = get_usb_serial (port, __FUNCTION__);
+ if (!serial)
+ return;
+
X dbg(__FUNCTION__" port %d", port->number);
X
X down (&port->sem);
@@ -357,10 +366,12 @@
X --port->open_count;
X
X if (port->open_count <= 0) {
- /* shutdown our bulk reads and writes */
- usb_unlink_urb (port->write_urb);
- usb_unlink_urb (port->read_urb);
- usb_unlink_urb (port->interrupt_in_urb); /* wgg - do I need this? I think so. */
+ if (serial->dev) {
+ /* shutdown our bulk reads and writes */
+ usb_unlink_urb (port->write_urb);
+ usb_unlink_urb (port->read_urb);
+ usb_unlink_urb (port->interrupt_in_urb);
+ }
X port->active = 0;
X }
X
@@ -636,7 +647,7 @@
X usb_serial_register (&belkin_old_device);
X usb_serial_register (&peracom_device);
X usb_serial_register (&gocom232_device);
- info(DRIVER_VERSION ":" DRIVER_DESC);
+ info(DRIVER_DESC " " DRIVER_VERSION);
X return 0;
X }
X
diff -u --recursive --new-file v2.4.11/linux/drivers/usb/serial/cyberjack.c linux/drivers/usb/serial/cyberjack.c
--- v2.4.11/linux/drivers/usb/serial/cyberjack.c Tue Oct 9 17:06:52 2001
+++ linux/drivers/usb/serial/cyberjack.c Wed Oct 10 23:42:47 2001
@@ -198,10 +198,12 @@
X --port->open_count;
X
X if (port->open_count <= 0) {
- /* shutdown any bulk reads that might be going on */
- usb_unlink_urb (port->write_urb);
- usb_unlink_urb (port->read_urb);
- usb_unlink_urb (port->interrupt_in_urb);
+ if (port->serial->dev) {
+ /* shutdown any bulk reads that might be going on */
+ usb_unlink_urb (port->write_urb);
+ usb_unlink_urb (port->read_urb);
+ usb_unlink_urb (port->interrupt_in_urb);
+ }
X
X port->active = 0;
X port->open_count = 0;
diff -u --recursive --new-file v2.4.11/linux/drivers/usb/serial/digi_acceleport.c linux/drivers/usb/serial/digi_acceleport.c
--- v2.4.11/linux/drivers/usb/serial/digi_acceleport.c Sun Sep 23 11:41:00 2001
+++ linux/drivers/usb/serial/digi_acceleport.c Wed Oct 10 23:42:47 2001
@@ -1591,53 +1591,55 @@
X if( tty->ldisc.flush_buffer )
X tty->ldisc.flush_buffer( tty );
X
- /* wait for transmit idle */
- if( (filp->f_flags&(O_NDELAY|O_NONBLOCK)) == 0 ) {
- digi_transmit_idle( port, DIGI_CLOSE_TIMEOUT );
- }
-
- /* drop DTR and RTS */
- digi_set_modem_signals( port, 0, 0 );
+ if (port->serial->dev) {
+ /* wait for transmit idle */
+ if( (filp->f_flags&(O_NDELAY|O_NONBLOCK)) == 0 ) {
+ digi_transmit_idle( port, DIGI_CLOSE_TIMEOUT );
+ }
+
+ /* drop DTR and RTS */
+ digi_set_modem_signals( port, 0, 0 );
+
+ /* disable input flow control */
+ buf[0] = DIGI_CMD_SET_INPUT_FLOW_CONTROL;
+ buf[1] = priv->dp_port_num;
+ buf[2] = DIGI_DISABLE;
+ buf[3] = 0;
+
+ /* disable output flow control */
+ buf[4] = DIGI_CMD_SET_OUTPUT_FLOW_CONTROL;
+ buf[5] = priv->dp_port_num;
+ buf[6] = DIGI_DISABLE;
+ buf[7] = 0;
+
+ /* disable reading modem signals automatically */
+ buf[8] = DIGI_CMD_READ_INPUT_SIGNALS;
+ buf[9] = priv->dp_port_num;
+ buf[10] = DIGI_DISABLE;
+ buf[11] = 0;
+
+ /* disable receive */
+ buf[12] = DIGI_CMD_RECEIVE_ENABLE;
+ buf[13] = priv->dp_port_num;
+ buf[14] = DIGI_DISABLE;
+ buf[15] = 0;
+
+ /* flush fifos */
+ buf[16] = DIGI_CMD_IFLUSH_FIFO;
+ buf[17] = priv->dp_port_num;
+ buf[18] = DIGI_FLUSH_TX | DIGI_FLUSH_RX;
+ buf[19] = 0;
+
+ if( (ret=digi_write_oob_command( port, buf, 20, 0 )) != 0 )
+ dbg( "digi_close: write oob failed, ret=%d", ret );
+
+ /* wait for final commands on oob port to complete */
+ interruptible_sleep_on_timeout( &priv->dp_flush_wait,
+ DIGI_CLOSE_TIMEOUT );
X
- /* disable input flow control */
- buf[0] = DIGI_CMD_SET_INPUT_FLOW_CONTROL;
- buf[1] = priv->dp_port_num;
- buf[2] = DIGI_DISABLE;
- buf[3] = 0;
-
- /* disable output flow control */
- buf[4] = DIGI_CMD_SET_OUTPUT_FLOW_CONTROL;
- buf[5] = priv->dp_port_num;
- buf[6] = DIGI_DISABLE;
- buf[7] = 0;
-
- /* disable reading modem signals automatically */
- buf[8] = DIGI_CMD_READ_INPUT_SIGNALS;
- buf[9] = priv->dp_port_num;
- buf[10] = DIGI_DISABLE;
- buf[11] = 0;
-
- /* disable receive */
- buf[12] = DIGI_CMD_RECEIVE_ENABLE;
- buf[13] = priv->dp_port_num;
- buf[14] = DIGI_DISABLE;
- buf[15] = 0;
-
- /* flush fifos */
- buf[16] = DIGI_CMD_IFLUSH_FIFO;
- buf[17] = priv->dp_port_num;
- buf[18] = DIGI_FLUSH_TX | DIGI_FLUSH_RX;
- buf[19] = 0;
-
- if( (ret=digi_write_oob_command( port, buf, 20, 0 )) != 0 )
- dbg( "digi_close: write oob failed, ret=%d", ret );
-
- /* wait for final commands on oob port to complete */
- interruptible_sleep_on_timeout( &priv->dp_flush_wait,
- DIGI_CLOSE_TIMEOUT );
-
- /* shutdown any outstanding bulk writes */
- usb_unlink_urb (port->write_urb);
+ /* shutdown any outstanding bulk writes */
+ usb_unlink_urb (port->write_urb);
+ }
X
X tty->closing = 0;
X
diff -u --recursive --new-file v2.4.11/linux/drivers/usb/serial/empeg.c linux/drivers/usb/serial/empeg.c
--- v2.4.11/linux/drivers/usb/serial/empeg.c Sun Sep 23 11:41:00 2001
+++ linux/drivers/usb/serial/empeg.c Wed Oct 10 23:42:47 2001
@@ -217,8 +217,10 @@
X --port->open_count;
X
X if (port->open_count <= 0) {
- /* shutdown our bulk read */
- usb_unlink_urb (port->read_urb);
+ if (serial->dev) {
+ /* shutdown our bulk read */
+ usb_unlink_urb (port->read_urb);
+ }
X port->active = 0;
X port->open_count = 0;
X }
diff -u --recursive --new-file v2.4.11/linux/drivers/usb/serial/ftdi_sio.c linux/drivers/usb/serial/ftdi_sio.c
--- v2.4.11/linux/drivers/usb/serial/ftdi_sio.c Sun Sep 23 11:41:00 2001
+++ linux/drivers/usb/serial/ftdi_sio.c Wed Oct 10 23:42:47 2001
@@ -371,29 +371,31 @@
X --port->open_count;
X
X if (port->open_count <= 0) {
- if (c_cflag & HUPCL){
- /* Disable flow control */
- if (usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
- FTDI_SIO_SET_FLOW_CTRL_REQUEST,
- FTDI_SIO_SET_FLOW_CTRL_REQUEST_TYPE,
- 0, 0,
- buf, 0, WDR_TIMEOUT) < 0) {
- err("error from flowcontrol urb");
- }
+ if (serial->dev) {
+ if (c_cflag & HUPCL){
+ /* Disable flow control */
+ if (usb_control_msg(serial->dev,
+ usb_sndctrlpipe(serial->dev, 0),
+ FTDI_SIO_SET_FLOW_CTRL_REQUEST,
+ FTDI_SIO_SET_FLOW_CTRL_REQUEST_TYPE,
+ 0, 0, buf, 0, WDR_TIMEOUT) < 0) {
+ err("error from flowcontrol urb");
+ }
X
- /* drop DTR */
- if (set_dtr(serial->dev, usb_sndctrlpipe(serial->dev, 0), LOW) < 0){
- err("Error from DTR LOW urb");
- }
- /* drop RTS */
- if (set_rts(serial->dev, usb_sndctrlpipe(serial->dev, 0),LOW) < 0) {
- err("Error from RTS LOW urb");
- }
- } /* Note change no line is hupcl is off */
+ /* drop DTR */
+ if (set_dtr(serial->dev, usb_sndctrlpipe(serial->dev, 0), LOW) < 0){
+ err("Error from DTR LOW urb");
+ }
+ /* drop RTS */
+ if (set_rts(serial->dev, usb_sndctrlpipe(serial->dev, 0),LOW) < 0) {
+ err("Error from RTS LOW urb");
+ }
+ } /* Note change no line is hupcl is off */
X
- /* shutdown our bulk reads and writes */
- usb_unlink_urb (port->write_urb);
- usb_unlink_urb (port->read_urb);
+ /* shutdown our bulk reads and writes */
+ usb_unlink_urb (port->write_urb);
+ usb_unlink_urb (port->read_urb);
+ }
X port->active = 0;
X port->open_count = 0;
X } else {
diff -u --recursive --new-file v2.4.11/linux/drivers/usb/serial/io_edgeport.c linux/drivers/usb/serial/io_edgeport.c
--- v2.4.11/linux/drivers/usb/serial/io_edgeport.c Tue Oct 9 17:06:52 2001
+++ linux/drivers/usb/serial/io_edgeport.c Wed Oct 10 23:42:47 2001
@@ -1241,42 +1241,45 @@
X --port->open_count;
X
X if (port->open_count <= 0) {
- // block until tx is empty
- block_until_tx_empty(edge_port);
-
- edge_port->closePending = TRUE;
-
- /* flush and chase */
- edge_port->chaseResponsePending = TRUE;
-
- dbg(__FUNCTION__" - Sending IOSP_CMD_CHASE_PORT");
- status = send_iosp_ext_cmd (edge_port, IOSP_CMD_CHASE_PORT, 0);


- if (status == 0) {

- // block until chase finished
- block_until_chase_response(edge_port);
- } else {
- edge_port->chaseResponsePending = FALSE;
+ if (serial->dev) {
+ // block until tx is empty
+ block_until_tx_empty(edge_port);
+
+ edge_port->closePending = TRUE;
+
+ /* flush and chase */
+ edge_port->chaseResponsePending = TRUE;
+
+ dbg(__FUNCTION__" - Sending IOSP_CMD_CHASE_PORT");
+ status = send_iosp_ext_cmd (edge_port, IOSP_CMD_CHASE_PORT, 0);
+ if (status == 0) {
+ // block until chase finished
+ block_until_chase_response(edge_port);
+ } else {
+ edge_port->chaseResponsePending = FALSE;
+ }
+
+ /* close the port */
+ dbg(__FUNCTION__" - Sending IOSP_CMD_CLOSE_PORT");
+ send_iosp_ext_cmd (edge_port, IOSP_CMD_CLOSE_PORT, 0);
+
+ //port->close = TRUE;
+ edge_port->closePending = FALSE;
+ edge_port->open = FALSE;
+ edge_port->openPending = FALSE;
+
+ if (edge_port->write_urb) {
+ usb_unlink_urb (edge_port->write_urb);
+ }
X }
X
- /* close the port */
- dbg(__FUNCTION__" - Sending IOSP_CMD_CLOSE_PORT");
- send_iosp_ext_cmd (edge_port, IOSP_CMD_CLOSE_PORT, 0);
-
- //port->close = TRUE;
- edge_port->closePending = FALSE;
- edge_port->open = FALSE;
- edge_port->openPending = FALSE;
-
X if (edge_port->write_urb) {
X /* if this urb had a transfer buffer already (old transfer) free it */
X if (edge_port->write_urb->transfer_buffer != NULL) {
X kfree(edge_port->write_urb->transfer_buffer);
X }
-
- usb_unlink_urb (edge_port->write_urb);
X usb_free_urb (edge_port->write_urb);
X }
-
X if (edge_port->txfifo.fifo) {
X kfree(edge_port->txfifo.fifo);
X }
diff -u --recursive --new-file v2.4.11/linux/drivers/usb/serial/ir-usb.c linux/drivers/usb/serial/ir-usb.c
--- v2.4.11/linux/drivers/usb/serial/ir-usb.c Tue Oct 9 17:06:52 2001
+++ linux/drivers/usb/serial/ir-usb.c Wed Oct 10 23:42:47 2001
@@ -14,6 +14,10 @@
X * please use the usb-irda driver, as it contains the proper error checking and
X * other goodness of a full IrDA stack.
X *
+ * Portions of this driver were taken from drivers/net/irda/irda-usb.c, which
+ * was written by Roman Weissgaerber <wei...@vienna.at>, Dag Brattli
+ * <d...@brattli.net>, and Jean Tourrilhes <j...@hpl.hp.com>
+
X * See Documentation/usb/usb-serial.txt for more information on using this driver
X *
X * 2001_Oct_07 greg kh
@@ -112,7 +116,7 @@
X * offer to us, describing their IrDA characteristics. We will use that in
X * irda_usb_init_qos()
X */
-static inline struct irda_class_desc *irda_usb_find_class_desc(struct usb_device *dev, unsigned int ifnum)
+static struct irda_class_desc *irda_usb_find_class_desc(struct usb_device *dev, unsigned int ifnum)
X {
X struct usb_interface_descriptor *interface;
X struct irda_class_desc *desc;
@@ -229,8 +233,10 @@
X --port->open_count;
X
X if (port->open_count <= 0) {
- /* shutdown our bulk read */
- usb_unlink_urb (port->read_urb);
+ if (serial->dev) {
+ /* shutdown our bulk read */
+ usb_unlink_urb (port->read_urb);
+ }
X port->active = 0;
X port->open_count = 0;
X
diff -u --recursive --new-file v2.4.11/linux/drivers/usb/serial/keyspan.c linux/drivers/usb/serial/keyspan.c
--- v2.4.11/linux/drivers/usb/serial/keyspan.c Tue Oct 9 17:06:52 2001
+++ linux/drivers/usb/serial/keyspan.c Wed Oct 10 23:42:47 2001
@@ -920,10 +920,14 @@
X static void keyspan_close(struct usb_serial_port *port, struct file *filp)
X {
X int i;
- struct usb_serial *serial = port->serial; /* FIXME should so sanity check */
+ struct usb_serial *serial;
X struct keyspan_serial_private *s_priv;
X struct keyspan_port_private *p_priv;
X
+ serial = get_usb_serial (port, __FUNCTION__);
+ if (!serial)
+ return;
+
X dbg("keyspan_close called\n");
X s_priv = (struct keyspan_serial_private *)(serial->private);
X p_priv = (struct keyspan_port_private *)(port->private);
@@ -931,7 +935,8 @@
X p_priv->rts_state = 0;
X p_priv->dtr_state = 0;
X
- keyspan_send_setup(port, 1);
+ if (serial->dev)
+ keyspan_send_setup(port, 1);
X
X /*while (p_priv->outcont_urb->status == -EINPROGRESS) {
X dbg("close - urb in progress\n");
@@ -944,18 +949,15 @@
X
X if (--port->open_count <= 0) {
X if (port->active) {
- /* Stop reading/writing urbs */
- stop_urb(p_priv->inack_urb);
- stop_urb(p_priv->outcont_urb);
- for (i = 0; i < 2; i++) {
- stop_urb(p_priv->in_urbs[i]);
- stop_urb(p_priv->out_urbs[i]);
+ if (serial->dev) {
+ /* Stop reading/writing urbs */
+ stop_urb(p_priv->inack_urb);
+ stop_urb(p_priv->outcont_urb);
+ for (i = 0; i < 2; i++) {
+ stop_urb(p_priv->in_urbs[i]);
+ stop_urb(p_priv->out_urbs[i]);
+ }
X }
- /* Now done in shutdown
- if (atomic_dec_return(&s_priv->active_count) <= 0) {
- stop_urb(s_priv->instat_urb);
- stop_urb(s_priv->glocont_urb);
- } */
X }
X port->active = 0;
X port->open_count = 0;
diff -u --recursive --new-file v2.4.11/linux/drivers/usb/serial/keyspan_pda.c linux/drivers/usb/serial/keyspan_pda.c
--- v2.4.11/linux/drivers/usb/serial/keyspan_pda.c Sun Sep 23 11:41:00 2001
+++ linux/drivers/usb/serial/keyspan_pda.c Wed Oct 10 23:42:47 2001
@@ -743,13 +743,15 @@
X --port->open_count;
X
X if (port->open_count <= 0) {
- /* the normal serial device seems to always shut off DTR and RTS now */
- if (port->tty->termios->c_cflag & HUPCL)
- keyspan_pda_set_modem_info(serial, 0);
+ if (serial->dev) {
+ /* the normal serial device seems to always shut off DTR and RTS now */
+ if (port->tty->termios->c_cflag & HUPCL)
+ keyspan_pda_set_modem_info(serial, 0);
X
- /* shutdown our bulk reads and writes */
- usb_unlink_urb (port->write_urb);
- usb_unlink_urb (port->interrupt_in_urb);
+ /* shutdown our bulk reads and writes */
+ usb_unlink_urb (port->write_urb);
+ usb_unlink_urb (port->interrupt_in_urb);
+ }
X port->active = 0;
X port->open_count = 0;
X }
diff -u --recursive --new-file v2.4.11/linux/drivers/usb/serial/mct_u232.c linux/drivers/usb/serial/mct_u232.c
--- v2.4.11/linux/drivers/usb/serial/mct_u232.c Sun Sep 23 11:41:00 2001
+++ linux/drivers/usb/serial/mct_u232.c Wed Oct 10 23:42:47 2001
@@ -475,11 +475,12 @@
X --port->open_count;
X
X if (port->open_count <= 0) {
- /* shutdown our bulk reads and writes */
- usb_unlink_urb (port->write_urb);
- usb_unlink_urb (port->read_urb);
- /* wgg - do I need this? I think so. */
- usb_unlink_urb (port->interrupt_in_urb);
+ if (port->serial->dev) {
+ /* shutdown our urbs */
+ usb_unlink_urb (port->write_urb);
+ usb_unlink_urb (port->read_urb);
+ usb_unlink_urb (port->interrupt_in_urb);
+ }
X port->active = 0;
X }
X
diff -u --recursive --new-file v2.4.11/linux/drivers/usb/serial/omninet.c linux/drivers/usb/serial/omninet.c
--- v2.4.11/linux/drivers/usb/serial/omninet.c Sun Sep 23 11:41:00 2001
+++ linux/drivers/usb/serial/omninet.c Wed Oct 10 23:42:47 2001
@@ -216,14 +216,15 @@
X --port->open_count;
X
X if (port->open_count <= 0) {
- od = (struct omninet_data *)port->private;
- wport = &serial->port[1];
-
- usb_unlink_urb (wport->write_urb);
- usb_unlink_urb (port->read_urb);
+ if (serial->dev) {
+ wport = &serial->port[1];
+ usb_unlink_urb (wport->write_urb);
+ usb_unlink_urb (port->read_urb);
+ }
X
X port->active = 0;
X port->open_count = 0;
+ od = (struct omninet_data *)port->private;
X if (od)
X kfree(od);
X }
diff -u --recursive --new-file v2.4.11/linux/drivers/usb/serial/pl2303.c linux/drivers/usb/serial/pl2303.c
--- v2.4.11/linux/drivers/usb/serial/pl2303.c Tue Oct 9 17:06:53 2001
+++ linux/drivers/usb/serial/pl2303.c Wed Oct 10 23:42:47 2001
@@ -434,40 +434,53 @@
X
X static void pl2303_close (struct usb_serial_port *port, struct file *filp)
X {
+ struct usb_serial *serial;
X struct pl2303_private *priv;
X unsigned int c_cflag;
X int result;
X
X if (port_paranoia_check (port, __FUNCTION__))
X return;
-
+ serial = get_usb_serial (port, __FUNCTION__);
+ if (!serial)
+ return;
+
X dbg (__FUNCTION__ " - port %d", port->number);
X
X down (&port->sem);
X
X --port->open_count;
X if (port->open_count <= 0) {
- c_cflag = port->tty->termios->c_cflag;
- if (c_cflag & HUPCL) {
- /* drop DTR and RTS */
- priv = port->private;
- priv->line_control = 0;
- set_control_lines (port->serial->dev, priv->line_control);
+ if (serial->dev) {
+ c_cflag = port->tty->termios->c_cflag;
+ if (c_cflag & HUPCL) {
+ /* drop DTR and RTS */
+ priv = port->private;
+ priv->line_control = 0;
+ set_control_lines (port->serial->dev,
+ priv->line_control);
+ }
+
+ /* shutdown our urbs */
+ dbg (__FUNCTION__ " - shutting down urbs");
+ result = usb_unlink_urb (port->write_urb);
+ if (result)
+ dbg (__FUNCTION__ " - usb_unlink_urb "
+ "(write_urb) failed with reason: %d",
+ result);
+
+ result = usb_unlink_urb (port->read_urb);
+ if (result)
+ dbg (__FUNCTION__ " - usb_unlink_urb "
+ "(read_urb) failed with reason: %d",
+ result);
+
+ result = usb_unlink_urb (port->interrupt_in_urb);
+ if (result)
+ dbg (__FUNCTION__ " - usb_unlink_urb "
+ "(interrupt_in_urb) failed with reason: %d",
+ result);
X }
-
- /* shutdown our urbs */
- dbg (__FUNCTION__ " - shutting down urbs");
- result = usb_unlink_urb (port->write_urb);
- if (result)
- dbg (__FUNCTION__ " - usb_unlink_urb (write_urb) failed with reason: %d", result);
-
- result = usb_unlink_urb (port->read_urb);
- if (result)
- dbg (__FUNCTION__ " - usb_unlink_urb (read_urb) failed with reason: %d", result);
-
- result = usb_unlink_urb (port->interrupt_in_urb);
- if (result)
- dbg (__FUNCTION__ " - usb_unlink_urb (interrupt_in_urb) failed with reason: %d", result);
X
X port->active = 0;
X port->open_count = 0;
diff -u --recursive --new-file v2.4.11/linux/drivers/usb/serial/usb-serial.h linux/drivers/usb/serial/usb-serial.h
--- v2.4.11/linux/drivers/usb/serial/usb-serial.h Sun Sep 23 11:41:00 2001
+++ linux/drivers/usb/serial/usb-serial.h Wed Oct 10 23:42:47 2001
@@ -11,6 +11,10 @@
X *
X * See Documentation/usb/usb-serial.txt for more information on using this driver
X *
+ * (10/10/2001) gkh
+ * added vendor and product to serial structure. Needed to determine device
+ * owner when the device is disconnected.
+ *
X * (05/30/2001) gkh
X * added sem to port structure and removed port_lock
X *
@@ -96,6 +100,8 @@
X char num_interrupt_in; /* number of interrupt in endpoints we have */
X char num_bulk_in; /* number of bulk in endpoints we have */
X char num_bulk_out; /* number of bulk out endpoints we have */
+ __u16 vendor; /* vendor id of this device */
+ __u16 product; /* product id of this device */
X struct usb_serial_port port[MAX_NUM_PORTS];
X
X void * private; /* data private to the specific driver */
diff -u --recursive --new-file v2.4.11/linux/drivers/usb/serial/usbserial.c linux/drivers/usb/serial/usbserial.c
--- v2.4.11/linux/drivers/usb/serial/usbserial.c Tue Oct 9 17:06:53 2001
+++ linux/drivers/usb/serial/usbserial.c Wed Oct 10 23:42:47 2001
@@ -14,7 +14,12 @@
X * based on a driver by Brad Keryan)
X *
X * See Documentation/usb/usb-serial.txt for more information on using this driver
- *
+ *
+ * (10/10/2001) gkh
+ * usb_serial_disconnect() now sets the serial->dev pointer is to NULL to
+ * help prevent child drivers from accessing the device since it is now
+ * gone.
+ *
X * (09/13/2001) gkh
X * Moved generic driver initialize after we have registered with the USB
X * core. Thanks to Randy Dunlap for pointing this problem out.
@@ -344,9 +349,9 @@
X shutdown: generic_shutdown,
X };
X
-#define if_generic_do(x) \
- if ((serial->dev->descriptor.idVendor == vendor) && \
- (serial->dev->descriptor.idProduct == product)) \
+#define if_generic_do(x) \
+ if ((serial->vendor == vendor) && \
+ (serial->product == product)) \
X x
X #else
X #define if_generic_do(x)
@@ -462,10 +467,15 @@
X int ezusb_writememory (struct usb_serial *serial, int address, unsigned char *data, int length, __u8 bRequest)
X {
X int result;
- unsigned char *transfer_buffer = kmalloc (length, GFP_KERNEL);
+ unsigned char *transfer_buffer;
X
-// dbg("ezusb_writememory %x, %d", address, length);
+ /* dbg("ezusb_writememory %x, %d", address, length); */
+ if (!serial->dev) {
+ dbg(__FUNCTION__ " - no physical device present, failing.");
+ return -ENODEV;
+ }
X
+ transfer_buffer = kmalloc (length, GFP_KERNEL);
X if (!transfer_buffer) {
X err(__FUNCTION__ " - kmalloc(%d) failed.", length);
X return -ENOMEM;
@@ -821,11 +831,13 @@
X --port->open_count;
X
X if (port->open_count <= 0) {
- /* shutdown any bulk reads that might be going on */
- if (serial->num_bulk_out)
- usb_unlink_urb (port->write_urb);
- if (serial->num_bulk_in)
- usb_unlink_urb (port->read_urb);
+ if (serial->dev) {
+ /* shutdown any bulk reads that might be going on */
+ if (serial->num_bulk_out)
+ usb_unlink_urb (port->write_urb);
+ if (serial->num_bulk_in)
+ usb_unlink_urb (port->read_urb);
+ }
X
X port->active = 0;
X port->open_count = 0;
@@ -1186,6 +1198,8 @@
X serial->num_bulk_in = num_bulk_in;
X serial->num_bulk_out = num_bulk_out;
X serial->num_interrupt_in = num_interrupt_in;
+ serial->vendor = dev->descriptor.idVendor;
+ serial->product = dev->descriptor.idProduct;
X
X /* if this device type has a startup function, call it */
X if (type->startup) {
@@ -1338,6 +1352,7 @@
X serial->port[i].tty->driver_data = NULL;
X }
X
+ serial->dev = NULL;
X serial_shutdown (serial);
X
X for (i = 0; i < serial->num_ports; ++i)
diff -u --recursive --new-file v2.4.11/linux/drivers/usb/serial/visor.c linux/drivers/usb/serial/visor.c
--- v2.4.11/linux/drivers/usb/serial/visor.c Sun Sep 23 11:41:00 2001
+++ linux/drivers/usb/serial/visor.c Wed Oct 10 23:42:47 2001
@@ -380,21 +380,26 @@
X --port->open_count;
X
X if (port->open_count <= 0) {
- transfer_buffer = kmalloc (0x12, GFP_KERNEL);
- if (!transfer_buffer) {
- err(__FUNCTION__ " - kmalloc(%d) failed.", 0x12);
- } else {
- /* send a shutdown message to the device */
- usb_control_msg (serial->dev, usb_rcvctrlpipe(serial->dev, 0), VISOR_CLOSE_NOTIFICATION,
- 0xc2, 0x0000, 0x0000, transfer_buffer, 0x12, 300);
- kfree (transfer_buffer);
+ if (serial->dev) {
+ /* only send a shutdown message if the
+ * device is still here */
+ transfer_buffer = kmalloc (0x12, GFP_KERNEL);
+ if (!transfer_buffer) {
+ err(__FUNCTION__ " - kmalloc(%d) failed.", 0x12);
+ } else {
+ /* send a shutdown message to the device */
+ usb_control_msg (serial->dev,
+ usb_rcvctrlpipe(serial->dev, 0),
+ VISOR_CLOSE_NOTIFICATION, 0xc2,
+ 0x0000, 0x0000,
+ transfer_buffer, 0x12, 300);
+ kfree (transfer_buffer);
+ }
+ /* shutdown our bulk read */
+ usb_unlink_urb (port->read_urb);
X }
-
- /* shutdown our bulk read */
- usb_unlink_urb (port->read_urb);
X port->active = 0;
X port->open_count = 0;
-
X }
X up (&port->sem);
X
diff -u --recursive --new-file v2.4.11/linux/drivers/usb/uhci.c linux/drivers/usb/uhci.c
--- v2.4.11/linux/drivers/usb/uhci.c Tue Oct 9 17:06:53 2001
+++ linux/drivers/usb/uhci.c Wed Oct 10 01:23:09 2001
@@ -1594,9 +1594,7 @@
X }
X
X uhci_unlink_generic(uhci, urb);
- uhci_destroy_urb_priv(urb);
-
- usb_dec_dev_use(urb->dev);
+ uhci_call_completion(urb);
X
X return ret;
X }
diff -u --recursive --new-file v2.4.11/linux/drivers/usb/usbvideo.c linux/drivers/usb/usbvideo.c
--- v2.4.11/linux/drivers/usb/usbvideo.c Tue Oct 9 17:06:53 2001
+++ linux/drivers/usb/usbvideo.c Wed Oct 10 23:42:46 2001
@@ -84,27 +84,6 @@
X return ret;
X }
X
-unsigned long usbvideo_uvirt_to_bus(unsigned long adr)
-{
- unsigned long kva, ret;
-
- kva = usbvideo_uvirt_to_kva(pgd_offset(current->mm, adr), adr);
- ret = virt_to_bus((void *)kva);
- MDEBUG(printk("uv2b(%lx-->%lx)", adr, ret));
- return ret;
-}
-
-unsigned long usbvideo_kvirt_to_bus(unsigned long adr)
-{
- unsigned long va, kva, ret;
-
- va = VMALLOC_VMADDR(adr);
- kva = usbvideo_uvirt_to_kva(pgd_offset_k(va), va);
- ret = virt_to_bus((void *)kva);
- MDEBUG(printk("kv2b(%lx-->%lx)", adr, ret));
- return ret;
-}
-
X /*
X * Here we want the physical address of the memory.
X * This is used when initializing the contents of the
diff -u --recursive --new-file v2.4.11/linux/drivers/usb/usbvideo.h linux/drivers/usb/usbvideo.h
--- v2.4.11/linux/drivers/usb/usbvideo.h Tue Oct 9 17:06:53 2001
+++ linux/drivers/usb/usbvideo.h Wed Oct 10 23:42:46 2001
@@ -329,8 +329,6 @@
X
X /* Memory allocation routines */
X unsigned long usbvideo_uvirt_to_kva(pgd_t *pgd, unsigned long adr);
-unsigned long usbvideo_uvirt_to_bus(unsigned long adr);
-unsigned long usbvideo_kvirt_to_bus(unsigned long adr);
X unsigned long usbvideo_kvirt_to_pa(unsigned long adr);
X void *usbvideo_rvmalloc(unsigned long size);
X void usbvideo_rvfree(void *mem, unsigned long size);
diff -u --recursive --new-file v2.4.11/linux/drivers/video/fbmem.c linux/drivers/video/fbmem.c
--- v2.4.11/linux/drivers/video/fbmem.c Sun Sep 23 11:41:00 2001
+++ linux/drivers/video/fbmem.c Wed Oct 10 15:47:16 2001
@@ -124,6 +124,8 @@
X extern int e1355fb_setup(char*);
X extern int pvr2fb_init(void);
X extern int pvr2fb_setup(char*);
+extern int sstfb_init(void);
+extern int sstfb_setup(char*);
X
X static struct {
X const char *name;
@@ -274,7 +276,9 @@
X #ifdef CONFIG_FB_PVR2
X { "pvr2", pvr2fb_init, pvr2fb_setup },
X #endif
-
+#ifdef CONFIG_FB_VOODOO1
+ { "sst", sstfb_init, sstfb_setup },
+#endif
X /*
X * Generic drivers that don't use resource management (yet)
X */
diff -u --recursive --new-file v2.4.11/linux/fs/devfs/base.c linux/fs/devfs/base.c
--- v2.4.11/linux/fs/devfs/base.c Tue Oct 9 17:06:53 2001
+++ linux/fs/devfs/base.c Wed Oct 10 23:23:24 2001
@@ -548,6 +548,13 @@
X 20010927 Richard Gooch <rgo...@atnf.csiro.au>
X Went back to global rwsem for symlinks (refcount scheme no good)
X v0.117
+ 20011008 Richard Gooch <rgo...@atnf.csiro.au>
+ Fixed overrun in <devfs_link> by removing function (not needed).
+ v0.118
+ 20011009 Richard Gooch <rgo...@atnf.csiro.au>
+ Fixed buffer underrun in <try_modload>.
+ Moved down_read() from <search_for_entry_in_dir> to <find_entry>
+ v0.119
X */
X #include <linux/types.h>
X #include <linux/errno.h>
@@ -580,7 +587,7 @@
X #include <asm/bitops.h>
X #include <asm/atomic.h>
X
-#define DEVFS_VERSION "0.117 (20010927)"
+#define DEVFS_VERSION "0.119 (20011009)"
X
X #define DEVFS_NAME "devfs"
X
@@ -810,12 +817,10 @@
X if (curr == NULL) return NULL;
X if (!S_ISLNK (curr->mode) || !traverse_symlink) return curr;
X /* Need to follow the link: this is a stack chomper */
- down_read (&symlink_rwsem);
X retval = curr->registered ?
X search_for_entry (parent, curr->u.symlink.linkname,
X curr->u.symlink.length, FALSE, FALSE, NULL,
X TRUE) : NULL;
- up_read (&symlink_rwsem);
X return retval;
X } /* End Function search_for_entry_in_dir */
X
@@ -1085,8 +1090,10 @@
X ++name;
X --namelen;
X }
+ if (traverse_symlink) down_read (&symlink_rwsem);
X entry = search_for_entry (dir, name, namelen, FALSE, FALSE, NULL,
X traverse_symlink);
+ if (traverse_symlink) up_read (&symlink_rwsem);
X if (entry != NULL) return entry;
X }
X /* Have to search by major and minor: slow */
@@ -1647,8 +1654,7 @@
X devfs_handle_t de;
X
X if ( (name != NULL) && (name[0] == '\0') ) name = NULL;
- de = find_entry (dir, name, 0, major, minor, type,
- traverse_symlinks);
+ de = find_entry (dir, name, 0, major, minor, type, traverse_symlinks);
X if (de == NULL) return NULL;
X if (!de->registered) return NULL;
X return de;
@@ -2138,7 +2144,7 @@
X if ( !( fs_info->devfsd_event_mask & (1 << DEVFSD_NOTIFY_LOOKUP) ) )
X return -ENOENT;
X if ( is_devfsd_or_child (fs_info) ) return -ENOENT;
- if (namelen >= STRING_LENGTH) return -ENAMETOOLONG;
+ if (namelen >= STRING_LENGTH - 1) return -ENAMETOOLONG;
X memcpy (buf + pos, name, namelen);
X buf[STRING_LENGTH - 1] = '\0';
X if (parent->parent != NULL) pos = devfs_generate_path (parent, buf, pos);
@@ -2781,19 +2787,6 @@
X return NULL;
X } /* End Function devfs_lookup */
X
-static int devfs_link (struct dentry *old_dentry, struct inode *dir,


SHAR_EOF
true || echo 'restore of patch-2.4.12 failed'
fi

echo 'End of part 2'
echo 'File patch-2.4.12 is continued in part 3'
echo "3" > _shar_seq_.tmp
exit 0

0 new messages