summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@athlon.transmeta.com>2002-02-04 20:21:29 -0800
committerLinus Torvalds <torvalds@athlon.transmeta.com>2002-02-04 20:21:29 -0800
commit4c7ed1860c0d21292284fb044c465ba00ce89b7f (patch)
tree390c0c69045bd62c643e2e2924315529dc564d95
parent6211a2d822e38a0202f3a395a96272400409d7af (diff)
v2.4.11 -> v2.4.12
- Greg KH: USB update (fix UHCI timeouts, serial unplug) - Christoph Rohland: shmem locking fixes - Al Viro: more mount cleanup - me: fix bad interaction with link_count handling - David Miller: Sparc updates, net cleanup - Tim Waugh: parport update - Jeff Garzik: net driver updates
-rw-r--r--Documentation/filesystems/devfs/ChangeLog12
-rw-r--r--Documentation/filesystems/devfs/README4
-rw-r--r--Makefile5
-rw-r--r--arch/sparc/kernel/process.c2
-rw-r--r--arch/sparc/kernel/systbls.S4
-rw-r--r--arch/sparc64/defconfig5
-rw-r--r--arch/sparc64/kernel/dtlb_backend.S22
-rw-r--r--arch/sparc64/kernel/dtlb_base.S28
-rw-r--r--arch/sparc64/kernel/pci.c74
-rw-r--r--arch/sparc64/kernel/process.c2
-rw-r--r--arch/sparc64/kernel/systbls.S6
-rw-r--r--drivers/net/acenic.c77
-rw-r--r--drivers/net/acenic.h11
-rw-r--r--drivers/net/aironet4500.h1
-rw-r--r--drivers/net/at1700.c2
-rw-r--r--drivers/net/macsonic.c11
-rw-r--r--drivers/net/sk98lin/skge.c2
-rw-r--r--drivers/net/sonic.c1047
-rw-r--r--drivers/net/sonic.h314
-rw-r--r--drivers/parport/ChangeLog20
-rw-r--r--drivers/parport/ieee1284_ops.c10
-rw-r--r--drivers/parport/parport_pc.c21
-rw-r--r--drivers/sbus/audio/audio.c7
-rw-r--r--drivers/sbus/audio/cs4231.c3
-rw-r--r--drivers/sbus/audio/dbri.c4
-rw-r--r--drivers/sbus/audio/dmy.c4
-rw-r--r--drivers/sbus/char/aurora.c3
-rw-r--r--drivers/sbus/char/bpp.c1
-rw-r--r--drivers/sbus/char/cpwatchdog.c1
-rw-r--r--drivers/sbus/char/display7seg.c3
-rw-r--r--drivers/sbus/char/envctrl.c3
-rw-r--r--drivers/sbus/char/flash.c3
-rw-r--r--drivers/sbus/char/jsflash.c1
-rw-r--r--drivers/sbus/char/openprom.c1
-rw-r--r--drivers/sbus/char/riowatchdog.c3
-rw-r--r--drivers/sbus/char/rtc.c3
-rw-r--r--drivers/sbus/char/sab82532.c6
-rw-r--r--drivers/sbus/char/uctrl.c3
-rw-r--r--drivers/scsi/aic7xxx_old.c2
-rw-r--r--drivers/usb/serial/belkin_sa.c25
-rw-r--r--drivers/usb/serial/cyberjack.c10
-rw-r--r--drivers/usb/serial/digi_acceleport.c94
-rw-r--r--drivers/usb/serial/empeg.c6
-rw-r--r--drivers/usb/serial/ftdi_sio.c48
-rw-r--r--drivers/usb/serial/io_edgeport.c57
-rw-r--r--drivers/usb/serial/ir-usb.c12
-rw-r--r--drivers/usb/serial/keyspan.c28
-rw-r--r--drivers/usb/serial/keyspan_pda.c16
-rw-r--r--drivers/usb/serial/mct_u232.c11
-rw-r--r--drivers/usb/serial/omninet.c11
-rw-r--r--drivers/usb/serial/pl2303.c51
-rw-r--r--drivers/usb/serial/usb-serial.h6
-rw-r--r--drivers/usb/serial/usbserial.c37
-rw-r--r--drivers/usb/serial/visor.c29
-rw-r--r--drivers/usb/uhci.c4
-rw-r--r--drivers/usb/usbvideo.c21
-rw-r--r--drivers/usb/usbvideo.h2
-rw-r--r--drivers/video/fbmem.c6
-rw-r--r--fs/devfs/base.c32
-rw-r--r--fs/ext2/inode.c60
-rw-r--r--fs/namei.c15
-rw-r--r--fs/namespace.c11
-rw-r--r--fs/proc/base.c25
-rw-r--r--fs/super.c120
-rw-r--r--include/asm-i386/smp.h2
-rw-r--r--include/asm-sparc/processor.h2
-rw-r--r--include/asm-sparc/unistd.h4
-rw-r--r--include/asm-sparc64/processor.h2
-rw-r--r--include/asm-sparc64/unistd.h4
-rw-r--r--include/linux/ext2_fs.h3
-rw-r--r--include/linux/fs.h1
-rw-r--r--include/linux/netdevice.h35
-rw-r--r--include/linux/parport.h3
-rw-r--r--include/linux/pci_ids.h5
-rw-r--r--include/linux/sched.h2
-rw-r--r--include/linux/shmem_fs.h18
-rw-r--r--mm/shmem.c640
-rw-r--r--net/ipv4/tcp.c4
78 files changed, 1753 insertions, 1440 deletions
diff --git a/Documentation/filesystems/devfs/ChangeLog b/Documentation/filesystems/devfs/ChangeLog
index 3951f6c432cd..78786b5f3254 100644
--- a/Documentation/filesystems/devfs/ChangeLog
+++ b/Documentation/filesystems/devfs/ChangeLog
@@ -1759,3 +1759,15 @@ Changes for patch v192
Changes for patch v193
- 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 --git a/Documentation/filesystems/devfs/README b/Documentation/filesystems/devfs/README
index 7acce6d97e69..a048bc669629 100644
--- a/Documentation/filesystems/devfs/README
+++ b/Documentation/filesystems/devfs/README
@@ -3,7 +3,7 @@ Devfs (Device File System) FAQ
Linux Devfs (Device File System) FAQ
Richard Gooch
-23-AUG-2001
+29-SEP-2001
-----------------------------------------------------------------------------
@@ -1753,7 +1753,7 @@ discusses the scsihosts= boot option
Douglas Gilbert has written yet another useful document at
-http://www.torque.net/scsi/linux_scsi_24/ which
+http://www.torque.net/scsi/SCSI-2.4-HOWTO/ which
discusses the Linux SCSI subsystem in 2.4.
diff --git a/Makefile b/Makefile
index 2139d3942738..09842c8bb95e 100644
--- a/Makefile
+++ b/Makefile
@@ -1,6 +1,6 @@
VERSION = 2
PATCHLEVEL = 4
-SUBLEVEL = 11
+SUBLEVEL = 12
EXTRAVERSION =
KERNELRELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)
@@ -300,7 +300,8 @@ $(TOPDIR)/include/linux/version.h: include/linux/version.h
$(TOPDIR)/include/linux/compile.h: include/linux/compile.h
newversion:
- . scripts/mkversion > .version
+ . scripts/mkversion > .tmpversion
+ @mv -f .tmpversion .version
include/linux/compile.h: $(CONFIGURATION) include/linux/version.h newversion
@echo -n \#define UTS_VERSION \"\#`cat .version` > .ver
diff --git a/arch/sparc/kernel/process.c b/arch/sparc/kernel/process.c
index fc07121c823e..8f5f8761613f 100644
--- a/arch/sparc/kernel/process.c
+++ b/arch/sparc/kernel/process.c
@@ -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 $
* linux/arch/sparc/kernel/process.c
*
* Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
diff --git a/arch/sparc/kernel/systbls.S b/arch/sparc/kernel/systbls.S
index 84daa1bd9621..4808a6a1a870 100644
--- a/arch/sparc/kernel/systbls.S
+++ b/arch/sparc/kernel/systbls.S
@@ -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 $
* systbls.S: System call entry point tables for OS compatibility.
* The native Linux system call table lives here also.
*
@@ -46,7 +46,7 @@ sys_call_table:
/*125*/ .long sys_nis_syscall, sys_setreuid16, sys_setregid16, sys_rename, sys_truncate
/*130*/ .long sys_ftruncate, sys_flock, sys_lstat64, sys_nis_syscall, sys_nis_syscall
/*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
/*145*/ .long sys_setrlimit, sys_pivot_root, sys_prctl, sys_pciconfig_read, sys_pciconfig_write
/*150*/ .long sys_nis_syscall, sys_nis_syscall, sys_nis_syscall, sys_poll, sys_getdents64
/*155*/ .long sys_fcntl64, sys_nis_syscall, sys_statfs, sys_fstatfs, sys_oldumount
diff --git a/arch/sparc64/defconfig b/arch/sparc64/defconfig
index a396f202be89..140f3741da03 100644
--- a/arch/sparc64/defconfig
+++ b/arch/sparc64/defconfig
@@ -567,6 +567,7 @@ CONFIG_MSDOS_FS=m
CONFIG_VFAT_FS=m
CONFIG_EFS_FS=m
# CONFIG_JFFS_FS is not set
+# CONFIG_JFFS2_FS is not set
CONFIG_CRAMFS=m
# CONFIG_TMPFS is not set
CONFIG_RAMFS=m
@@ -737,6 +738,7 @@ CONFIG_USB_DC2XX=m
CONFIG_USB_MDC800=m
CONFIG_USB_SCANNER=m
CONFIG_USB_MICROTEK=m
+CONFIG_USB_HPUSBSCSI=m
#
# USB Multimedia devices
@@ -773,11 +775,14 @@ CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m
CONFIG_USB_SERIAL_EMPEG=m
CONFIG_USB_SERIAL_FTDI_SIO=m
CONFIG_USB_SERIAL_VISOR=m
+# CONFIG_USB_SERIAL_IR is not set
CONFIG_USB_SERIAL_EDGEPORT=m
CONFIG_USB_SERIAL_KEYSPAN_PDA=m
CONFIG_USB_SERIAL_KEYSPAN=m
# CONFIG_USB_SERIAL_KEYSPAN_USA28 is not set
# CONFIG_USB_SERIAL_KEYSPAN_USA28X is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA28XA is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA28XB is not set
# CONFIG_USB_SERIAL_KEYSPAN_USA19 is not set
# CONFIG_USB_SERIAL_KEYSPAN_USA18X is not set
# CONFIG_USB_SERIAL_KEYSPAN_USA19W is not set
diff --git a/arch/sparc64/kernel/dtlb_backend.S b/arch/sparc64/kernel/dtlb_backend.S
index b74c15fce09e..62133f1facb6 100644
--- a/arch/sparc64/kernel/dtlb_backend.S
+++ b/arch/sparc64/kernel/dtlb_backend.S
@@ -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 $
* dtlb_backend.S: Back end to DTLB miss replacement strategy.
* This is included directly into the trap table.
*
@@ -41,23 +41,25 @@
ldxa [%g1 + %g1] ASI_DMMU, %g4 ! Get TAG_ACCESS
add %g3, %g3, %g5 ! Compute VPTE base
cmp %g4, %g5 ! VPTE miss?
- blu,pn %xcc, from_tl1_trap ! Fall to tl0 miss
+ bgeu,pt %xcc, 1f ! Continue here
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
/* TLB1 ** ICACHE line 2: Quick VPTE miss */
+ or %g4, %g5, %g4 ! Prepare TAG_ACCESS
+ mov TSB_REG, %g1 ! Grab TSB reg
ldxa [%g1] ASI_DMMU, %g5 ! Doing PGD caching?
srlx %g6, (TLB_PMD_SHIFT - 1), %g1 ! Position PMD offset
be,pn %xcc, sparc64_vpte_nucleus ! Is it from Nucleus?
and %g1, TLB_PMD_MASK, %g1 ! Mask PMD offset bits
brnz,pt %g5, sparc64_vpte_continue ! Yep, go like smoke
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
/* 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
lduwa [%g7 + %g5] ASI_PHYS_USE_EC, %g5! Load PGD
brz,pn %g5, vpte_noent ! Valid?
sparc64_kpte_continue:
@@ -66,18 +68,16 @@ sparc64_vpte_continue:
lduwa [%g5 + %g1] ASI_PHYS_USE_EC, %g5! Load PMD
sllx %g5, 11, %g5 ! Shift into place
brz,pn %g5, vpte_noent ! Valid?
+
+/* TLB1 ** ICACHE line 4: Quick VPTE miss */
FILL_VALID_SZ_BITS1(%g1) ! Put _PAGE_VALID into %g1
FILL_VALID_SZ_BITS2(%g1) ! Put _PAGE_VALID into %g1
or %g5, VPTE_BITS, %g5 ! Prepare VPTE data
-
-/* TLB1 ** ICACHE line 4: Quick VPTE miss */
or %g5, %g1, %g5 ! ...
mov TLB_SFSR, %g1 ! Restore %g1 value
stxa %g5, [%g0] ASI_DTLB_DATA_IN ! Load VPTE into TLB
stxa %g4, [%g1 + %g1] ASI_DMMU ! Restore previous TAG_ACCESS
retry ! Load PTE once again
- nop
- nop
FILL_VALID_SZ_BITS_NOP
#undef VPTE_SHIFT
diff --git a/arch/sparc64/kernel/dtlb_base.S b/arch/sparc64/kernel/dtlb_base.S
index c8761c6f9bcb..d0a35e7d9f3e 100644
--- a/arch/sparc64/kernel/dtlb_base.S
+++ b/arch/sparc64/kernel/dtlb_base.S
@@ -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 $
* dtlb_base.S: Front end to DTLB miss replacement strategy.
* This is included directly into the trap table.
*
@@ -65,27 +65,28 @@
/* DTLB ** ICACHE line 1: Quick user TLB misses */
ldxa [%g1 + %g1] ASI_DMMU, %g4 ! Get TAG_ACCESS
andcc %g4, TAG_CONTEXT_BITS, %g0 ! From Nucleus?
+ mov 1, %g5 ! For TL==3 test
from_tl1_trap:
CREATE_VPTE_OFFSET1(%g4, %g6) ! Create VPTE offset
be,pn %xcc, 3f ! Yep, special processing
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 */
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
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
9: stxa %g5, [%g0] ASI_DTLB_DATA_IN ! Reload TLB
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
/* DTLB ** ICACHE line 3: winfixups+real_faults */
+longpath:
+ rdpr %pstate, %g5 ! Move into alternate globals
wrpr %g5, PSTATE_AG|PSTATE_MG, %pstate
rdpr %tl, %g4 ! See where we came from.
cmp %g4, 1 ! Is etrap/rtrap window fault?
@@ -93,10 +94,9 @@ longpath:
ldxa [%g4] ASI_DMMU, %g5 ! Load faulting VA page
be,pt %xcc, sparc64_realfault_common ! Jump to normal fault handling
mov FAULT_CODE_DTLB, %g4 ! It was read from DTLB
- ba,a,pt %xcc, winfix_trampoline ! Call window fixup code
/* DTLB ** ICACHE line 4: Unused... */
- nop
+ ba,a,pt %xcc, winfix_trampoline ! Call window fixup code
nop
nop
nop
diff --git a/arch/sparc64/kernel/pci.c b/arch/sparc64/kernel/pci.c
index 2fa569043025..dd32b4d1f319 100644
--- a/arch/sparc64/kernel/pci.c
+++ b/arch/sparc64/kernel/pci.c
@@ -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 $
* pci.c: UltraSparc PCI controller support.
*
* Copyright (C) 1997, 1998, 1999 David S. Miller (davem@redhat.com)
@@ -317,6 +317,7 @@ static int __pci_mmap_make_offset_bus(struct pci_dev *pdev, struct vm_area_struc
{
struct pcidev_cookie *pcp = pdev->sysdata;
struct pci_pbm_info *pbm;
+ struct pci_controller_info *p;
unsigned long space_size, user_offset, user_size;
if (!pcp)
@@ -325,12 +326,44 @@ static int __pci_mmap_make_offset_bus(struct pci_dev *pdev, struct vm_area_struc
if (!pbm)
return -ENXIO;
- 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;
+ }
} 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;
+ }
}
/* Make sure the request is in range. */
@@ -341,12 +374,31 @@ static int __pci_mmap_make_offset_bus(struct pci_dev *pdev, struct vm_area_struc
(user_offset + user_size) > space_size)
return -EINVAL;
- 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;
} 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;
+ }
}
return 0;
diff --git a/arch/sparc64/kernel/process.c b/arch/sparc64/kernel/process.c
index 01ec3fe6c110..0c3f7b455177 100644
--- a/arch/sparc64/kernel/process.c
+++ b/arch/sparc64/kernel/process.c
@@ -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 $
* arch/sparc64/kernel/process.c
*
* Copyright (C) 1995, 1996 David S. Miller (davem@caip.rutgers.edu)
diff --git a/arch/sparc64/kernel/systbls.S b/arch/sparc64/kernel/systbls.S
index 335313796cc8..0cf604cb0dc0 100644
--- a/arch/sparc64/kernel/systbls.S
+++ b/arch/sparc64/kernel/systbls.S
@@ -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 $
* systbls.S: System call entry point tables for OS compatibility.
* The native Linux system call table lives here also.
*
@@ -47,7 +47,7 @@ sys_call_table32:
.word sys_nis_syscall, sys32_setreuid16, sys32_setregid16, sys_rename, sys_truncate
/*130*/ .word sys_ftruncate, sys_flock, sys_lstat64, sys_nis_syscall, sys_nis_syscall
.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
.word sys32_setrlimit, sys_pivot_root, sys32_prctl, sys32_pciconfig_read, sys32_pciconfig_write
/*150*/ .word sys_nis_syscall, sys_nis_syscall, sys_nis_syscall, sys_poll, sys_getdents64
.word sys32_fcntl64, sys_nis_syscall, sys32_statfs, sys32_fstatfs, sys_oldumount
@@ -106,7 +106,7 @@ sys_call_table:
.word sys_recvfrom, sys_setreuid, sys_setregid, sys_rename, sys_truncate
/*130*/ .word sys_ftruncate, sys_flock, sys_nis_syscall, sys_sendto, sys_shutdown
.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
.word sys_setrlimit, sys_pivot_root, sys_prctl, sys_pciconfig_read, sys_pciconfig_write
/*150*/ .word sys_getsockname, sys_nis_syscall, sys_nis_syscall, sys_poll, sys_getdents64
.word sys_nis_syscall, sys_nis_syscall, sys_statfs, sys_fstatfs, sys_oldumount
diff --git a/drivers/net/acenic.c b/drivers/net/acenic.c
index ca08e724a535..c1b35a48ef15 100644
--- a/drivers/net/acenic.c
+++ b/drivers/net/acenic.c
@@ -2,7 +2,7 @@
* acenic.c: Linux driver for the Alteon AceNIC Gigabit Ethernet card
* and other Tigon based cards.
*
- * Copyright 1998-2001 by Jes Sorensen, <jes@linuxcare.com>.
+ * Copyright 1998-2001 by Jes Sorensen, <jes@trained-monkey.org>.
*
* Thanks to Alteon and 3Com for providing hardware and documentation
* enabling me to write this driver.
@@ -145,6 +145,10 @@ MODULE_DEVICE_TABLE(pci, acenic_pci_tbl);
#endif
+#ifndef MODULE_LICENSE
+#define MODULE_LICENSE(a)
+#endif
+
#ifndef wmb
#define wmb() mb()
#endif
@@ -161,7 +165,7 @@ MODULE_DEVICE_TABLE(pci, acenic_pci_tbl);
#define SMP_CACHE_BYTES L1_CACHE_BYTES
#endif
-#if (BITS_PER_LONG == 64)
+#if (BITS_PER_LONG == 64) || defined(CONFIG_HIGHMEM)
#define ACE_64BIT_PTR 1
#endif
@@ -263,7 +267,6 @@ static inline void tasklet_init(struct tasklet_struct *tasklet,
#define pci_set_dma_mask(dev, mask) dev->dma_mask = mask;
#endif
-
#if (LINUX_VERSION_CODE >= 0x02031b)
#define NEW_NETINIT
#define ACE_PROBE_ARG void
@@ -271,6 +274,16 @@ static inline void tasklet_init(struct tasklet_struct *tasklet,
#define ACE_PROBE_ARG struct net_device *dev
#endif
+#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
+
#define ACE_MAX_MOD_PARMS 8
#define BOARD_IDX_STATIC 0
#define BOARD_IDX_OVERFLOW -1
@@ -514,7 +527,7 @@ static int tx_ratio[ACE_MAX_MOD_PARMS];
static int dis_pci_mem_inval[ACE_MAX_MOD_PARMS] = {1, 1, 1, 1, 1, 1, 1, 1};
static char version[] __initdata =
- "acenic.c: v0.81 04/20/2001 Jes Sorensen, linux-acenic@SunSITE.dk\n"
+ "acenic.c: v0.83 09/30/2001 Jes Sorensen, linux-acenic@SunSITE.dk\n"
" http://home.cern.ch/~jes/gige/acenic.html\n";
static struct net_device *root_dev;
@@ -746,15 +759,20 @@ int __devinit acenic_probe (ACE_PROBE_ARG)
#ifdef MODULE
MODULE_AUTHOR("Jes Sorensen <jes@trained-monkey.org>");
-MODULE_DESCRIPTION("AceNIC/3C985/GA620 Gigabit Ethernet driver");
MODULE_LICENSE("GPL");
-
+MODULE_DESCRIPTION("AceNIC/3C985/GA620 Gigabit Ethernet driver");
MODULE_PARM(link, "1-" __MODULE_STRING(8) "i");
MODULE_PARM(trace, "1-" __MODULE_STRING(8) "i");
MODULE_PARM(tx_coal_tick, "1-" __MODULE_STRING(8) "i");
MODULE_PARM(max_tx_desc, "1-" __MODULE_STRING(8) "i");
MODULE_PARM(rx_coal_tick, "1-" __MODULE_STRING(8) "i");
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");
#endif
@@ -795,14 +813,12 @@ static void __exit ace_module_cleanup(void)
struct sk_buff *skb = ap->skb->rx_std_skbuff[i].skb;
if (skb) {
-#ifndef DUMMY_PCI_UNMAP
dma_addr_t mapping;
mapping = ap->skb->rx_std_skbuff[i].mapping;
pci_unmap_single(ap->pdev, mapping,
ACE_STD_BUFSIZE - (2 + 16),
PCI_DMA_FROMDEVICE);
-#endif
ap->rx_std_ring[i].size = 0;
ap->skb->rx_std_skbuff[i].skb = NULL;
@@ -814,14 +830,13 @@ static void __exit ace_module_cleanup(void)
struct sk_buff *skb = ap->skb->rx_mini_skbuff[i].skb;
if (skb) {
-#ifndef DUMMY_PCI_UNMAP
dma_addr_t mapping;
mapping = ap->skb->rx_mini_skbuff[i].mapping;
pci_unmap_single(ap->pdev, mapping,
ACE_MINI_BUFSIZE - (2 + 16),
PCI_DMA_FROMDEVICE);
-#endif
+
ap->rx_mini_ring[i].size = 0;
ap->skb->rx_mini_skbuff[i].skb = NULL;
dev_kfree_skb(skb);
@@ -831,14 +846,12 @@ static void __exit ace_module_cleanup(void)
for (i = 0; i < RX_JUMBO_RING_ENTRIES; i++) {
struct sk_buff *skb = ap->skb->rx_jumbo_skbuff[i].skb;
if (skb) {
-#ifndef DUMMY_PCI_UNMAP
dma_addr_t mapping;
mapping = ap->skb->rx_jumbo_skbuff[i].mapping;
pci_unmap_single(ap->pdev, mapping,
ACE_JUMBO_BUFSIZE - (2 + 16),
PCI_DMA_FROMDEVICE);
-#endif
ap->rx_jumbo_ring[i].size = 0;
ap->skb->rx_jumbo_skbuff[i].skb = NULL;
@@ -1766,6 +1779,8 @@ static void ace_load_std_rx_ring(struct ace_private *ap, int nr_bufs)
regs = ap->regs;
+ prefetchw(&ap->cur_rx_bufs);
+
idx = ap->rx_std_skbprd;
for (i = 0; i < nr_bufs; i++) {
@@ -1785,9 +1800,7 @@ static void ace_load_std_rx_ring(struct ace_private *ap, int nr_bufs)
ACE_STD_BUFSIZE - (2 + 16),
PCI_DMA_FROMDEVICE);
ap->skb->rx_std_skbuff[idx].skb = skb;
-#ifndef DUMMY_PCI_UNMAP
ap->skb->rx_std_skbuff[idx].mapping = mapping;
-#endif
rd = &ap->rx_std_ring[idx];
set_aceaddr(&rd->addr, mapping);
@@ -1831,6 +1844,8 @@ static void ace_load_mini_rx_ring(struct ace_private *ap, int nr_bufs)
regs = ap->regs;
+ prefetchw(&ap->cur_mini_bufs);
+
idx = ap->rx_mini_skbprd;
for (i = 0; i < nr_bufs; i++) {
struct sk_buff *skb;
@@ -1849,9 +1864,7 @@ static void ace_load_mini_rx_ring(struct ace_private *ap, int nr_bufs)
ACE_MINI_BUFSIZE - (2 + 16),
PCI_DMA_FROMDEVICE);
ap->skb->rx_mini_skbuff[idx].skb = skb;
-#ifndef DUMMY_PCI_UNMAP
ap->skb->rx_mini_skbuff[idx].mapping = mapping;
-#endif
rd = &ap->rx_mini_ring[idx];
set_aceaddr(&rd->addr, mapping);
@@ -1910,9 +1923,7 @@ static void ace_load_jumbo_rx_ring(struct ace_private *ap, int nr_bufs)
ACE_JUMBO_BUFSIZE - (2 + 16),
PCI_DMA_FROMDEVICE);
ap->skb->rx_jumbo_skbuff[idx].skb = skb;
-#ifndef DUMMY_PCI_UNMAP
ap->skb->rx_jumbo_skbuff[idx].mapping = mapping;
-#endif
rd = &ap->rx_jumbo_ring[idx];
set_aceaddr(&rd->addr, mapping);
@@ -2067,6 +2078,9 @@ static void ace_rx_int(struct net_device *dev, u32 rxretprd, u32 rxretcsm)
idx = rxretcsm;
+ prefetchw(&ap->cur_rx_bufs);
+ prefetchw(&ap->cur_mini_bufs);
+
while (idx != rxretprd) {
struct ring_info *rip;
struct sk_buff *skb;
@@ -2115,15 +2129,9 @@ static void ace_rx_int(struct net_device *dev, u32 rxretprd, u32 rxretcsm)
skb = rip->skb;
rip->skb = NULL;
-#ifndef DUMMY_PCI_UNMAP
pci_unmap_single(ap->pdev, rip->mapping, mapsize,
PCI_DMA_FROMDEVICE);
-#endif
skb_put(skb, retdesc->size);
-#if 0
- /* unncessary */
- rxdesc->size = 0;
-#endif
/*
* Fly baby, fly!
@@ -2182,14 +2190,11 @@ static inline void ace_tx_int(struct net_device *dev,
do {
struct sk_buff *skb;
-#ifndef DUMMY_PCI_UNMAP
dma_addr_t mapping;
-#endif
struct tx_ring_info *info;
info = ap->skb->tx_skbuff + idx;
skb = info->skb;
-#ifndef DUMMY_PCI_UNMAP
mapping = info->mapping;
if (mapping) {
@@ -2197,7 +2202,7 @@ static inline void ace_tx_int(struct net_device *dev,
PCI_DMA_TODEVICE);
info->mapping = 0;
}
-#endif
+
if (skb) {
ap->stats.tx_packets++;
ap->stats.tx_bytes += skb->len;
@@ -2474,14 +2479,11 @@ static int ace_close(struct net_device *dev)
for (i = 0; i < TX_RING_ENTRIES; i++) {
struct sk_buff *skb;
-#ifndef DUMMY_PCI_UNMAP
dma_addr_t mapping;
-#endif
struct tx_ring_info *info;
info = ap->skb->tx_skbuff + i;
skb = info->skb;
-#ifndef DUMMY_PCI_UNMAP
mapping = info->mapping;
if (mapping) {
@@ -2490,7 +2492,7 @@ static int ace_close(struct net_device *dev)
PCI_DMA_TODEVICE);
info->mapping = 0;
}
-#endif
+
if (skb) {
dev_kfree_skb(skb);
info->skb = NULL;
@@ -2516,9 +2518,6 @@ static int ace_close(struct net_device *dev)
* For now, let it stay here.
*/
#if defined(CONFIG_HIGHMEM) && MAX_SKB_FRAGS
-#ifndef DUMMY_PCI_UNMAP
-#error Sorry, cannot DMA from high memory on this architecture.
-#endif
#if defined(CONFIG_X86)
#define DMAADDR_OFFSET 0
@@ -2565,10 +2564,9 @@ ace_map_tx_skb(struct ace_private *ap, struct sk_buff *skb,
info = ap->skb->tx_skbuff + idx;
info->skb = tail;
-#ifndef DUMMY_PCI_UNMAP
info->mapping = addr;
info->maplen = skb->len;
-#endif
+
return addr;
}
@@ -2673,10 +2671,9 @@ restart:
} else {
info->skb = NULL;
}
-#ifndef DUMMY_PCI_UNMAP
info->mapping = phys;
info->maplen = frag->size;
-#endif
+
ace_load_tx_bd(desc, phys, flagsize);
}
}
@@ -2998,7 +2995,7 @@ static void __init ace_copy(struct ace_regs *regs, void *src,
while (size > 0) {
tsize = min_t(u32, ((~dest & (ACE_WINDOW_SIZE - 1)) + 1),
- min_t(u32, size, ACE_WINDOW_SIZE));
+ min_t(u32, size, ACE_WINDOW_SIZE));
tdest = (unsigned long)&regs->Window +
(dest & (ACE_WINDOW_SIZE - 1));
writel(dest & ~(ACE_WINDOW_SIZE - 1), &regs->WinBase);
diff --git a/drivers/net/acenic.h b/drivers/net/acenic.h
index 61b2e9dcce58..6b108b4e6f6b 100644
--- a/drivers/net/acenic.h
+++ b/drivers/net/acenic.h
@@ -582,28 +582,21 @@ struct ace_info {
aceaddr stats2_ptr;
};
-#if defined(CONFIG_X86) || defined(CONFIG_PPC)
-/* Intel has null pci_unmap_single, no reasons to remember mapping. */
-#define DUMMY_PCI_UNMAP
-#endif
struct ring_info {
struct sk_buff *skb;
-#ifndef DUMMY_PCI_UNMAP
dma_addr_t mapping;
-#endif
};
-/* 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
* much slower. Hmm... is it because struct does not fit to one cacheline?
* So, split tx_ring_info.
*/
struct tx_ring_info {
struct sk_buff *skb;
-#ifndef DUMMY_PCI_UNMAP
dma_addr_t mapping;
int maplen;
-#endif
};
/*
diff --git a/drivers/net/aironet4500.h b/drivers/net/aironet4500.h
index 68245f9c690b..9f64d4ad3bf3 100644
--- a/drivers/net/aironet4500.h
+++ b/drivers/net/aironet4500.h
@@ -1531,7 +1531,6 @@ extern void awc_tx_timeout(struct net_device *dev);
extern int awc_start_xmit(struct sk_buff *, struct net_device *);
extern void awc_interrupt(int irq, void *dev_id, struct pt_regs *regs);
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);
extern void awc_set_multicast_list(struct net_device *dev);
extern int awc_change_mtu(struct net_device *dev, int new_mtu);
extern int awc_close(struct net_device *dev);
diff --git a/drivers/net/at1700.c b/drivers/net/at1700.c
index ad4dcf932c4a..5a9ad62ad6f2 100644
--- a/drivers/net/at1700.c
+++ b/drivers/net/at1700.c
@@ -158,7 +158,7 @@ struct net_local {
extern int at1700_probe(struct net_device *dev);
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);
static int net_open(struct net_device *dev);
static int net_send_packet(struct sk_buff *skb, struct net_device *dev);
static void net_interrupt(int irq, void *dev_id, struct pt_regs *regs);
diff --git a/drivers/net/macsonic.c b/drivers/net/macsonic.c
index dea26603a471..ef2705176acc 100644
--- a/drivers/net/macsonic.c
+++ b/drivers/net/macsonic.c
@@ -168,6 +168,8 @@ int __init macsonic_init(struct net_device* dev)
if ((lp->rba = (char *)
kmalloc(SONIC_NUM_RRS * SONIC_RBSIZE, GFP_KERNEL | GFP_DMA)) == NULL) {
printk(KERN_ERR "%s: couldn't allocate receive buffers\n", dev->name);
+ kfree(lp->sonic_desc);
+ lp->sonic_desc = NULL;
return -ENOMEM;
}
@@ -322,7 +324,7 @@ int __init mac_onboard_sonic_probe(struct net_device* dev)
/* methinks this will always be true but better safe than sorry */
if (dev->priv == NULL) {
dev->priv = kmalloc(sizeof(struct sonic_local), GFP_KERNEL);
- if (!dev->priv) /* FIXME: kfree dev if necessary */
+ if (!dev->priv)
return -ENOMEM;
}
} else {
@@ -518,9 +520,14 @@ int __init mac_nubus_sonic_probe(struct net_device* dev)
if (dev) {
dev = init_etherdev(dev, sizeof(struct sonic_local));
+ if (!dev)
+ return -ENOMEM;
/* methinks this will always be true but better safe than sorry */
- if (dev->priv == NULL)
+ if (dev->priv == NULL) {
dev->priv = kmalloc(sizeof(struct sonic_local), GFP_KERNEL);
+ if (!dev->priv) /* FIXME: kfree dev if necessary */
+ return -ENOMEM;
+ }
} else {
dev = init_etherdev(NULL, sizeof(struct sonic_local));
}
diff --git a/drivers/net/sk98lin/skge.c b/drivers/net/sk98lin/skge.c
index a2708e7e8a6d..a5dc41bc77fe 100644
--- a/drivers/net/sk98lin/skge.c
+++ b/drivers/net/sk98lin/skge.c
@@ -228,7 +228,7 @@
* <linux/string.h>
* <linux/errno.h>
* <linux/ioport.h>
- * <linux/malloc.h>
+ * <linux/slab.h>
* <linux/interrupt.h>
* <linux/pci.h>
* <asm/byteorder.h>
diff --git a/drivers/net/sonic.c b/drivers/net/sonic.c
index a99ef3a71ee5..0f39f8e9fc07 100644
--- a/drivers/net/sonic.c
+++ b/drivers/net/sonic.c
@@ -28,13 +28,13 @@
*/
static int sonic_open(struct net_device *dev)
{
- 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.
+ */
/*
* XXX Horrible work around: We install sonic_interrupt as fast interrupt.
* This means that during execution of the handler interrupt are disabled
@@ -42,335 +42,339 @@ static int sonic_open(struct net_device *dev)
* this glue works ok under all situations.
*/
// 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;
}
/*
* Close the SONIC device
*/
-static int
-sonic_close(struct net_device *dev)
+static int sonic_close(struct net_device *dev)
{
- 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);
-
- sonic_free_irq(dev->irq, dev); /* release the IRQ */
-
- return 0;
+ 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);
+
+ sonic_free_irq(dev->irq, dev); /* release the IRQ */
+
+ return 0;
}
+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);
+}
/*
* transmit packet
*/
static int sonic_send_packet(struct sk_buff *skb, struct net_device *dev)
{
- 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);
+
dev->trans_start = jiffies;
- }
-
- /*
- * 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;
}
-
/*
* The typical workload of the driver:
* Handle the network interface interrupts.
*/
-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)
{
- 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 {
- 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++;
+ 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 (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);
+
+ 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++;
}
-
- 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;
+
+ /* 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);
}
/*
* We have a good packet(s), get it/them out of the buffers.
*/
-static void
-sonic_rx(struct net_device *dev)
+static void sonic_rx(struct net_device *dev)
{
- 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++;
+ 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);
}
-
- 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;
+ /*
+ * 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.
+ */
}
@@ -378,68 +382,71 @@ sonic_rx(struct net_device *dev)
* Get the current statistics.
* This may be called with the device open or closed.
*/
-static struct net_device_stats *
-sonic_get_stats(struct net_device *dev)
+static struct net_device_stats *sonic_get_stats(struct net_device *dev)
{
- 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);
-
- return &lp->stats;
+ 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);
+
+ return &lp->stats;
}
/*
* Set or clear the multicast filter for this adaptor.
*/
-static void
-sonic_multicast_list(struct net_device *dev)
+static void sonic_multicast_list(struct net_device *dev)
{
- 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;
} 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 ((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);
+
+ if (sonic_debug > 2)
+ printk("sonic_multicast_list: setting RCR=%x\n", rcr);
+
+ SONIC_WRITE(SONIC_RCR, rcr);
}
@@ -448,168 +455,168 @@ sonic_multicast_list(struct net_device *dev)
*/
static int sonic_init(struct net_device *dev)
{
- 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);
-
- if (sonic_debug > 2)
- printk("sonic_init: new status=%x\n",SONIC_READ(SONIC_CMD));
-
- return(0);
-}
+ 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;
+ }
-
-/*
- * 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:
- */
+ /* 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);
+
+ if (sonic_debug > 2)
+ printk("sonic_init: new status=%x\n",
+ SONIC_READ(SONIC_CMD));
+
+ return 0;
+}
diff --git a/drivers/net/sonic.h b/drivers/net/sonic.h
index 5ef7689ef525..73191126b681 100644
--- a/drivers/net/sonic.h
+++ b/drivers/net/sonic.h
@@ -13,7 +13,6 @@
* see CONFIG_MACSONIC branch below.
*
*/
-
#ifndef SONIC_H
#define SONIC_H
@@ -22,7 +21,7 @@
/*
* SONIC register offsets
*/
-
+
#define SONIC_CMD 0x00
#define SONIC_DCR 0x01
#define SONIC_RCR 0x02
@@ -219,16 +218,16 @@
#ifdef CONFIG_MACSONIC
-/* Big endian like structures on Mac
- * (680x0)
+/*
+ * Big endian like structures on 680x0 Macs
*/
typedef struct {
- u32 rx_bufadr_l; /* receive buffer ptr */
- u32 rx_bufadr_h;
+ u32 rx_bufadr_l; /* receive buffer ptr */
+ u32 rx_bufadr_h;
- 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;
} sonic_rr_t;
/*
@@ -237,35 +236,35 @@ typedef struct {
*/
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;
-
- caddr_t rda_next; /* pointer to next RD */
+ 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;
+
+ caddr_t rda_next; /* pointer to next RD */
} sonic_rd_t;
@@ -273,24 +272,24 @@ typedef struct {
* Describes a Transmit Descriptor
*/
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 */
} sonic_td_t;
@@ -299,37 +298,37 @@ typedef struct {
*/
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;
} sonic_cd_t;
#define CAM_DESCRIPTORS 16
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;
} sonic_cda_t;
-#else /* original declarations, little endian 32 bit */
+#else /* original declarations, little endian 32 bit */
/*
* structure definitions
*/
typedef struct {
- u32 rx_bufadr_l; /* receive buffer ptr */
- u32 rx_bufadr_h;
+ u32 rx_bufadr_l; /* receive buffer ptr */
+ u32 rx_bufadr_h;
- 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;
} sonic_rr_t;
/*
@@ -338,35 +337,35 @@ typedef struct {
*/
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);
-
- caddr_t rda_next; /* pointer to next RD */
+ 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);
+
+ caddr_t rda_next; /* pointer to next RD */
} sonic_rd_t;
@@ -374,24 +373,24 @@ typedef struct {
* Describes a Transmit Descriptor
*/
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);
} sonic_td_t;
@@ -400,25 +399,25 @@ typedef struct {
*/
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);
} sonic_cd_t;
#define CAM_DESCRIPTORS 16
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);
} sonic_cda_t;
-#endif /* endianness */
+#endif /* endianness */
/*
* Some tunables for the buffer areas. Power of 2 is required
@@ -427,15 +426,15 @@ typedef struct {
* MSch: use more buffer space for the slow m68k Macs!
*/
#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 */
#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 */
#endif
-#define SONIC_RBSIZE 1520 /* size of one resource buffer */
+#define SONIC_RBSIZE 1520 /* size of one resource buffer */
#define SONIC_RDS_MASK (SONIC_NUM_RDS-1)
#define SONIC_TDS_MASK (SONIC_NUM_TDS-1)
@@ -443,26 +442,28 @@ typedef struct {
/* Information that need to be kept for each board. */
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;
};
+#define TX_TIMEOUT 6
+
/* Index to functions, as function prototypes. */
static int sonic_open(struct net_device *dev);
@@ -473,8 +474,9 @@ static int sonic_close(struct net_device *dev);
static struct net_device_stats *sonic_get_stats(struct net_device *dev);
static void sonic_multicast_list(struct net_device *dev);
static int sonic_init(struct net_device *dev);
+static void sonic_tx_timeout(struct net_device *dev);
static const char *version =
- "sonic.c:v0.92 20.9.98 tsbogend@alpha.franken.de\n";
+ "sonic.c:v0.92 20.9.98 tsbogend@alpha.franken.de\n";
#endif /* SONIC_H */
diff --git a/drivers/parport/ChangeLog b/drivers/parport/ChangeLog
index ac337fde6abe..333d8a26463e 100644
--- a/drivers/parport/ChangeLog
+++ b/drivers/parport/ChangeLog
@@ -1,3 +1,23 @@
+2001-10-10 Tim Waugh <twaugh@redhat.com>
+
+ * parport_pc.c: Support for OX16PCI954 PCI card.
+
+2001-10-10 Tim Waugh <twaugh@redhat.com>
+
+ * parport_pc.c: Support for OX12PCI840 PCI card (reported by
+ mk@daveg.com). Lock-ups diagnosed by Ronnie Arosa (and now we
+ just don't trust its ECR).
+
+2001-10-10 Gunther Mayer <gunther.mayer@braunschweig.okersurf.de>
+
+ * parport_pc.c: Support for AVLAB cards.
+
+2001-10-10 Tim Waugh <twaugh@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.
+
2001-10-08 David C. Hansen <haveblue@us.ibm.com>
* share.c: Make driverlist_lock and parportlist_lock static.
diff --git a/drivers/parport/ieee1284_ops.c b/drivers/parport/ieee1284_ops.c
index a2b0d270fbdf..b5c802c889a7 100644
--- a/drivers/parport/ieee1284_ops.c
+++ b/drivers/parport/ieee1284_ops.c
@@ -359,6 +359,10 @@ int ecp_forward_to_reverse (struct parport *port)
DPRINTK (KERN_DEBUG "%s: ECP direction: reverse\n",
port->name);
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;
}
return retval;
@@ -386,8 +390,14 @@ int ecp_reverse_to_forward (struct parport *port)
DPRINTK (KERN_DEBUG "%s: ECP direction: forward\n",
port->name);
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;
}
+
return retval;
}
diff --git a/drivers/parport/parport_pc.c b/drivers/parport/parport_pc.c
index 5526a125a924..349d1bc6454b 100644
--- a/drivers/parport/parport_pc.c
+++ b/drivers/parport/parport_pc.c
@@ -2528,7 +2528,6 @@ enum parport_pc_pci_cards {
lava_parallel_dual_b,
boca_ioppar,
plx_9050,
- afavlab_tk9902,
timedia_4078a,
timedia_4079h,
timedia_4085h,
@@ -2556,6 +2555,10 @@ enum parport_pc_pci_cards {
syba_1p_ecp,
titan_010l,
titan_1284p2,
+ avlab_1p,
+ avlab_2p,
+ oxsemi_954,
+ oxsemi_840,
};
@@ -2594,7 +2597,6 @@ static struct parport_pc_pci {
/* lava_parallel_dual_b */ { 1, { { 0, -1 }, } },
/* boca_ioppar */ { 1, { { 0, -1 }, } },
/* plx_9050 */ { 2, { { 4, -1 }, { 5, -1 }, } },
- /* afavlab_tk9902 */ { 1, { { 0, 1 }, } },
/* timedia_4078a */ { 1, { { 2, -1 }, } },
/* timedia_4079h */ { 1, { { 2, 3 }, } },
/* timedia_4085h */ { 2, { { 2, -1 }, { 4, -1 }, } },
@@ -2624,6 +2626,12 @@ static struct parport_pc_pci {
/* syba_1p_ecp W83787 */ { 1, { { 0, 0x078 }, } },
/* titan_010l */ { 1, { { 3, -1 }, } },
/* 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 }, } },
};
static struct pci_device_id parport_pc_pci_tbl[] __devinitdata = {
@@ -2679,8 +2687,6 @@ static struct pci_device_id parport_pc_pci_tbl[] __devinitdata = {
PCI_ANY_ID, PCI_ANY_ID, 0, 0, boca_ioppar },
{ PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9050,
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 },
/* PCI_VENDOR_ID_TIMEDIA/SUNIX has many differing cards ...*/
{ 0x1409, 0x7168, 0x1409, 0x4078, 0, 0, timedia_4078a },
{ 0x1409, 0x7168, 0x1409, 0x4079, 0, 0, timedia_4079h },
@@ -2712,6 +2718,13 @@ static struct pci_device_id parport_pc_pci_tbl[] __devinitdata = {
{ PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_010L,
PCI_ANY_ID, PCI_ANY_ID, 0, 0, titan_010l },
{ 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 },
{ 0, } /* terminate list */
};
MODULE_DEVICE_TABLE(pci,parport_pc_pci_tbl);
diff --git a/drivers/sbus/audio/audio.c b/drivers/sbus/audio/audio.c
index e8d9daca2de7..cbf93b31b2de 100644
--- a/drivers/sbus/audio/audio.c
+++ b/drivers/sbus/audio/audio.c
@@ -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 $
* drivers/sbus/audio/audio.c
*
* Copyright 1996 Thomas K. Dyas (tdyas@noc.rutgers.edu)
@@ -2138,8 +2138,9 @@ static void __exit sparcaudio_exit(void)
devfs_unregister (devfs_handle);
}
-module_init(sparcaudio_init)
-module_exit(sparcaudio_exit)
+module_init(sparcaudio_init);
+module_exit(sparcaudio_exit);
+MODULE_LICENSE("GPL");
/*
* Code from Linux Streams, Copyright 1995 by
diff --git a/drivers/sbus/audio/cs4231.c b/drivers/sbus/audio/cs4231.c
index 8c7443ac6d8e..1ec3880f5da8 100644
--- a/drivers/sbus/audio/cs4231.c
+++ b/drivers/sbus/audio/cs4231.c
@@ -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 $
* drivers/sbus/audio/cs4231.c
*
* Copyright 1996, 1997, 1998, 1999 Derrick J Brashear (shadow@andrew.cmu.edu)
@@ -2443,6 +2443,7 @@ static void __exit cs4231_exit(void)
module_init(cs4231_init);
module_exit(cs4231_exit);
+MODULE_LICENSE("GPL");
/*
* Overrides for Emacs so that we follow Linus's tabbing style.
* Emacs will notice this stuff at the end of the file and automatically
diff --git a/drivers/sbus/audio/dbri.c b/drivers/sbus/audio/dbri.c
index 5777dc2608dd..29300ab127fd 100644
--- a/drivers/sbus/audio/dbri.c
+++ b/drivers/sbus/audio/dbri.c
@@ -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 $
* drivers/sbus/audio/dbri.c
*
* Copyright (C) 1997 Rudolf Koenig (rfkoenig@immd4.informatik.uni-erlangen.de)
@@ -2377,6 +2377,8 @@ static void __exit dbri_exit(void)
module_init(dbri_init);
module_exit(dbri_exit);
+MODULE_LICENSE("GPL");
+
/*
* Overrides for Emacs so that we follow Linus's tabbing style.
* Emacs will notice this stuff at the end of the file and automatically
diff --git a/drivers/sbus/audio/dmy.c b/drivers/sbus/audio/dmy.c
index 444e447325c9..a7ded7975609 100644
--- a/drivers/sbus/audio/dmy.c
+++ b/drivers/sbus/audio/dmy.c
@@ -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 $
* drivers/sbus/audio/dummy.c
*
* Copyright 1998 Derrick J Brashear (shadow@andrew.cmu.edu)
@@ -783,6 +783,8 @@ static void __exit dummy_exit(void)
module_init(dummy_init);
module_exit(dummy_exit);
+MODULE_LICENSE("GPL");
+
/*
* Overrides for Emacs so that we follow Linus's tabbing style.
* Emacs will notice this stuff at the end of the file and automatically
diff --git a/drivers/sbus/char/aurora.c b/drivers/sbus/char/aurora.c
index 1e43c35111b8..a4730d2a5e88 100644
--- a/drivers/sbus/char/aurora.c
+++ b/drivers/sbus/char/aurora.c
@@ -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 $
* linux/drivers/sbus/char/aurora.c -- Aurora multiport driver
*
* Copyright (c) 1999 by Oliver Aldulea (oli at bv dot ro)
@@ -2482,3 +2482,4 @@ printk("cleanup_module: aurora_release_drivers\n");
module_init(aurora_init);
module_exit(aurora_cleanup);
+MODULE_LICENSE("GPL");
diff --git a/drivers/sbus/char/bpp.c b/drivers/sbus/char/bpp.c
index 2be051503e11..8af67283634b 100644
--- a/drivers/sbus/char/bpp.c
+++ b/drivers/sbus/char/bpp.c
@@ -1073,3 +1073,4 @@ static void __exit bpp_cleanup(void)
module_init(bpp_init);
module_exit(bpp_cleanup);
+MODULE_LICENSE("GPL");
diff --git a/drivers/sbus/char/cpwatchdog.c b/drivers/sbus/char/cpwatchdog.c
index 8e02809a7992..f5ed491fb464 100644
--- a/drivers/sbus/char/cpwatchdog.c
+++ b/drivers/sbus/char/cpwatchdog.c
@@ -193,6 +193,7 @@ MODULE_AUTHOR
("Eric Brower <ebrower@usa.net>");
MODULE_DESCRIPTION
("Hardware watchdog driver for Sun Microsystems CP1400/1500");
+MODULE_LICENSE("GPL");
MODULE_SUPPORTED_DEVICE
("watchdog");
#endif /* ifdef MODULE */
diff --git a/drivers/sbus/char/display7seg.c b/drivers/sbus/char/display7seg.c
index 091152a1c65f..ea2430ec0ad2 100644
--- a/drivers/sbus/char/display7seg.c
+++ b/drivers/sbus/char/display7seg.c
@@ -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 $
*
* display7seg - Driver implementation for the 7-segment display
* present on Sun Microsystems CP1400 and CP1500
@@ -55,6 +55,7 @@ MODULE_AUTHOR
("Eric Brower <ebrower@usa.net>");
MODULE_DESCRIPTION
("7-Segment Display driver for Sun Microsystems CP1400/1500");
+MODULE_LICENSE("GPL");
MODULE_SUPPORTED_DEVICE
("d7s");
#endif /* ifdef MODULE */
diff --git a/drivers/sbus/char/envctrl.c b/drivers/sbus/char/envctrl.c
index a612eaa6730b..da0b0c78e55a 100644
--- a/drivers/sbus/char/envctrl.c
+++ b/drivers/sbus/char/envctrl.c
@@ -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 $
* envctrl.c: Temperature and Fan monitoring on Machines providing it.
*
* Copyright (C) 1998 Eddie C. Dost (ecd@skynet.be)
@@ -1175,3 +1175,4 @@ static void __exit envctrl_cleanup(void)
module_init(envctrl_init);
module_exit(envctrl_cleanup);
+MODULE_LICENSE("GPL");
diff --git a/drivers/sbus/char/flash.c b/drivers/sbus/char/flash.c
index f002bc4af63e..29c258514b72 100644
--- a/drivers/sbus/char/flash.c
+++ b/drivers/sbus/char/flash.c
@@ -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 $
* flash.c: Allow mmap access to the OBP Flash, for OBP updates.
*
* Copyright (C) 1997 Eddie C. Dost (ecd@skynet.be)
@@ -247,3 +247,4 @@ static void __exit flash_cleanup(void)
module_init(flash_init);
module_exit(flash_cleanup);
+MODULE_LICENSE("GPL");
diff --git a/drivers/sbus/char/jsflash.c b/drivers/sbus/char/jsflash.c
index f0107ea38285..ae552e793a46 100644
--- a/drivers/sbus/char/jsflash.c
+++ b/drivers/sbus/char/jsflash.c
@@ -682,6 +682,7 @@ int jsfd_init(void) {
}
#ifdef MODULE
+MODULE_LICENSE("GPL");
int init_module(void) {
int rc;
diff --git a/drivers/sbus/char/openprom.c b/drivers/sbus/char/openprom.c
index 50b5ea42fc6d..1b0d8d71fdd1 100644
--- a/drivers/sbus/char/openprom.c
+++ b/drivers/sbus/char/openprom.c
@@ -653,3 +653,4 @@ static void __exit openprom_cleanup(void)
module_init(openprom_init);
module_exit(openprom_cleanup);
+MODULE_LICENSE("GPL");
diff --git a/drivers/sbus/char/riowatchdog.c b/drivers/sbus/char/riowatchdog.c
index b5204ef4a369..fd77b2f036da 100644
--- a/drivers/sbus/char/riowatchdog.c
+++ b/drivers/sbus/char/riowatchdog.c
@@ -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 $
* riowatchdog.c - driver for hw watchdog inside Super I/O of RIO
*
* Copyright (C) 2001 David S. Miller (davem@redhat.com)
@@ -47,6 +47,7 @@
MODULE_AUTHOR("David S. Miller <davem@redhat.com>");
MODULE_DESCRIPTION("Hardware watchdog driver for Sun RIO");
MODULE_SUPPORTED_DEVICE("watchdog");
+MODULE_LICENSE("GPL");
#define RIOWD_NAME "pmc"
#define RIOWD_MINOR 215
diff --git a/drivers/sbus/char/rtc.c b/drivers/sbus/char/rtc.c
index 37fd2110a0f5..118a6f2c5d93 100644
--- a/drivers/sbus/char/rtc.c
+++ b/drivers/sbus/char/rtc.c
@@ -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 $
*
* Linux/SPARC Real Time Clock Driver
* Copyright (C) 1996 Thomas K. Dyas (tdyas@eden.rutgers.edu)
@@ -174,3 +174,4 @@ static void __exit rtc_sun_cleanup(void)
module_init(rtc_sun_init);
module_exit(rtc_sun_cleanup);
+MODULE_LICENSE("GPL");
diff --git a/drivers/sbus/char/sab82532.c b/drivers/sbus/char/sab82532.c
index 4b6668bed13d..893b2d2871fa 100644
--- a/drivers/sbus/char/sab82532.c
+++ b/drivers/sbus/char/sab82532.c
@@ -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 $
* sab82532.c: ASYNC Driver for the SIEMENS SAB82532 DUSCC.
*
* Copyright (C) 1997 Eddie C. Dost (ecd@skynet.be)
@@ -2205,7 +2205,7 @@ static void __init sab82532_kgdb_hook(int line)
static inline void __init show_serial_version(void)
{
- char *revision = "$Revision: 1.63 $";
+ char *revision = "$Revision: 1.64 $";
char *version, *p;
version = strchr(revision, ' ');
@@ -2427,6 +2427,8 @@ found:
}
#ifdef MODULE
+MODULE_LICENSE("GPL");
+
int init_module(void)
{
if (get_sab82532(0))
diff --git a/drivers/sbus/char/uctrl.c b/drivers/sbus/char/uctrl.c
index 3a12bbe10031..f3a2713d8fa1 100644
--- a/drivers/sbus/char/uctrl.c
+++ b/drivers/sbus/char/uctrl.c
@@ -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 $
* uctrl.c: TS102 Microcontroller interface on Tadpole Sparcbook 3
*
* Copyright 1999 Derrick J Brashear (shadow@dementia.org)
@@ -424,3 +424,4 @@ static void __exit ts102_uctrl_cleanup(void)
module_init(ts102_uctrl_init);
module_exit(ts102_uctrl_cleanup);
+MODULE_LICENSE("GPL");
diff --git a/drivers/scsi/aic7xxx_old.c b/drivers/scsi/aic7xxx_old.c
index 20fbe31d85a5..ce4992aad337 100644
--- a/drivers/scsi/aic7xxx_old.c
+++ b/drivers/scsi/aic7xxx_old.c
@@ -219,9 +219,7 @@
* #define AIC7XXX_VERBOSE_DEBUGGING
*/
-#if defined(MODULE) || defined(PCMCIA)
#include <linux/module.h>
-#endif
#if defined(PCMCIA)
# undef MODULE
diff --git a/drivers/usb/serial/belkin_sa.c b/drivers/usb/serial/belkin_sa.c
index a2b68fa36b85..5bfa8be90cfe 100644
--- a/drivers/usb/serial/belkin_sa.c
+++ b/drivers/usb/serial/belkin_sa.c
@@ -23,8 +23,8 @@
* framework in, but haven't analyzed the "tty_flip" interface yet.
* -- Add support for flush commands
* -- Add everything that is missing :)
- *
- * (30-May-2001 gkh
+ *
+ * 30-May-2001 gkh
* switched from using spinlock to a semaphore, which fixes lots of problems.
*
* 08-Apr-2001 gb
@@ -350,6 +350,15 @@ exit:
static void belkin_sa_close (struct usb_serial_port *port, struct file *filp)
{
+ struct usb_serial *serial;
+
+ if (port_paranoia_check (port, __FUNCTION__))
+ return;
+
+ serial = get_usb_serial (port, __FUNCTION__);
+ if (!serial)
+ return;
+
dbg(__FUNCTION__" port %d", port->number);
down (&port->sem);
@@ -357,10 +366,12 @@ static void belkin_sa_close (struct usb_serial_port *port, struct file *filp)
--port->open_count;
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);
+ }
port->active = 0;
}
@@ -636,7 +647,7 @@ static int __init belkin_sa_init (void)
usb_serial_register (&belkin_old_device);
usb_serial_register (&peracom_device);
usb_serial_register (&gocom232_device);
- info(DRIVER_VERSION ":" DRIVER_DESC);
+ info(DRIVER_DESC " " DRIVER_VERSION);
return 0;
}
diff --git a/drivers/usb/serial/cyberjack.c b/drivers/usb/serial/cyberjack.c
index 65b633b656cc..c0250574185f 100644
--- a/drivers/usb/serial/cyberjack.c
+++ b/drivers/usb/serial/cyberjack.c
@@ -198,10 +198,12 @@ static void cyberjack_close (struct usb_serial_port *port, struct file *filp)
--port->open_count;
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);
+ }
port->active = 0;
port->open_count = 0;
diff --git a/drivers/usb/serial/digi_acceleport.c b/drivers/usb/serial/digi_acceleport.c
index 0abba02960ae..c974e428ee13 100644
--- a/drivers/usb/serial/digi_acceleport.c
+++ b/drivers/usb/serial/digi_acceleport.c
@@ -1591,53 +1591,55 @@ dbg( "digi_close: TOP: port=%d, active=%d, open_count=%d", priv->dp_port_num, po
if( tty->ldisc.flush_buffer )
tty->ldisc.flush_buffer( tty );
- /* 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 );
+ if (port->serial->dev) {
+ /* wait for transmit idle */
+ if( (filp->f_flags&(O_NDELAY|O_NONBLOCK)) == 0 ) {
+ digi_transmit_idle( port, DIGI_CLOSE_TIMEOUT );
+ }
- /* shutdown any outstanding bulk writes */
- usb_unlink_urb (port->write_urb);
+ /* 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 );
+
+ /* shutdown any outstanding bulk writes */
+ usb_unlink_urb (port->write_urb);
+ }
tty->closing = 0;
diff --git a/drivers/usb/serial/empeg.c b/drivers/usb/serial/empeg.c
index c83337d72d16..b9799c000d33 100644
--- a/drivers/usb/serial/empeg.c
+++ b/drivers/usb/serial/empeg.c
@@ -217,8 +217,10 @@ static void empeg_close (struct usb_serial_port *port, struct file * filp)
--port->open_count;
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);
+ }
port->active = 0;
port->open_count = 0;
}
diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c
index 91a814bd3b0b..640ca9e0e947 100644
--- a/drivers/usb/serial/ftdi_sio.c
+++ b/drivers/usb/serial/ftdi_sio.c
@@ -371,29 +371,31 @@ static void ftdi_sio_close (struct usb_serial_port *port, struct file *filp)
--port->open_count;
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");
- }
-
- /* 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 */
-
- /* shutdown our bulk reads and writes */
- usb_unlink_urb (port->write_urb);
- usb_unlink_urb (port->read_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");
+ }
+
+ /* 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 */
+
+ /* shutdown our bulk reads and writes */
+ usb_unlink_urb (port->write_urb);
+ usb_unlink_urb (port->read_urb);
+ }
port->active = 0;
port->open_count = 0;
} else {
diff --git a/drivers/usb/serial/io_edgeport.c b/drivers/usb/serial/io_edgeport.c
index 8b2bbdedbe0b..fa08f724f547 100644
--- a/drivers/usb/serial/io_edgeport.c
+++ b/drivers/usb/serial/io_edgeport.c
@@ -1241,42 +1241,45 @@ static void edge_close (struct usb_serial_port *port, struct file * filp)
--port->open_count;
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);
+ }
}
- /* 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) {
/* if this urb had a transfer buffer already (old transfer) free it */
if (edge_port->write_urb->transfer_buffer != NULL) {
kfree(edge_port->write_urb->transfer_buffer);
}
-
- usb_unlink_urb (edge_port->write_urb);
usb_free_urb (edge_port->write_urb);
}
-
if (edge_port->txfifo.fifo) {
kfree(edge_port->txfifo.fifo);
}
diff --git a/drivers/usb/serial/ir-usb.c b/drivers/usb/serial/ir-usb.c
index da55e7f933f9..0b30bf1a6d15 100644
--- a/drivers/usb/serial/ir-usb.c
+++ b/drivers/usb/serial/ir-usb.c
@@ -14,6 +14,10 @@
* please use the usb-irda driver, as it contains the proper error checking and
* other goodness of a full IrDA stack.
*
+ * Portions of this driver were taken from drivers/net/irda/irda-usb.c, which
+ * was written by Roman Weissgaerber <weissg@vienna.at>, Dag Brattli
+ * <dag@brattli.net>, and Jean Tourrilhes <jt@hpl.hp.com>
+
* See Documentation/usb/usb-serial.txt for more information on using this driver
*
* 2001_Oct_07 greg kh
@@ -112,7 +116,7 @@ static inline void irda_usb_dump_class_desc(struct irda_class_desc *desc)
* offer to us, describing their IrDA characteristics. We will use that in
* irda_usb_init_qos()
*/
-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)
{
struct usb_interface_descriptor *interface;
struct irda_class_desc *desc;
@@ -229,8 +233,10 @@ static void ir_close (struct usb_serial_port *port, struct file * filp)
--port->open_count;
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);
+ }
port->active = 0;
port->open_count = 0;
diff --git a/drivers/usb/serial/keyspan.c b/drivers/usb/serial/keyspan.c
index 63b97c00b3a0..412d3d01eac4 100644
--- a/drivers/usb/serial/keyspan.c
+++ b/drivers/usb/serial/keyspan.c
@@ -920,10 +920,14 @@ static inline void stop_urb(urb_t *urb)
static void keyspan_close(struct usb_serial_port *port, struct file *filp)
{
int i;
- struct usb_serial *serial = port->serial; /* FIXME should so sanity check */
+ struct usb_serial *serial;
struct keyspan_serial_private *s_priv;
struct keyspan_port_private *p_priv;
+ serial = get_usb_serial (port, __FUNCTION__);
+ if (!serial)
+ return;
+
dbg("keyspan_close called\n");
s_priv = (struct keyspan_serial_private *)(serial->private);
p_priv = (struct keyspan_port_private *)(port->private);
@@ -931,7 +935,8 @@ static void keyspan_close(struct usb_serial_port *port, struct file *filp)
p_priv->rts_state = 0;
p_priv->dtr_state = 0;
- keyspan_send_setup(port, 1);
+ if (serial->dev)
+ keyspan_send_setup(port, 1);
/*while (p_priv->outcont_urb->status == -EINPROGRESS) {
dbg("close - urb in progress\n");
@@ -944,18 +949,15 @@ static void keyspan_close(struct usb_serial_port *port, struct file *filp)
if (--port->open_count <= 0) {
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]);
+ }
}
- /* 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);
- } */
}
port->active = 0;
port->open_count = 0;
diff --git a/drivers/usb/serial/keyspan_pda.c b/drivers/usb/serial/keyspan_pda.c
index 353e51f68f6b..d333c8cc05e6 100644
--- a/drivers/usb/serial/keyspan_pda.c
+++ b/drivers/usb/serial/keyspan_pda.c
@@ -743,13 +743,15 @@ static void keyspan_pda_close(struct usb_serial_port *port, struct file *filp)
--port->open_count;
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);
-
- /* shutdown our bulk reads and writes */
- usb_unlink_urb (port->write_urb);
- usb_unlink_urb (port->interrupt_in_urb);
+ 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);
+
+ /* shutdown our bulk reads and writes */
+ usb_unlink_urb (port->write_urb);
+ usb_unlink_urb (port->interrupt_in_urb);
+ }
port->active = 0;
port->open_count = 0;
}
diff --git a/drivers/usb/serial/mct_u232.c b/drivers/usb/serial/mct_u232.c
index 811a6ee37177..51e73015e61b 100644
--- a/drivers/usb/serial/mct_u232.c
+++ b/drivers/usb/serial/mct_u232.c
@@ -475,11 +475,12 @@ static void mct_u232_close (struct usb_serial_port *port, struct file *filp)
--port->open_count;
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);
+ }
port->active = 0;
}
diff --git a/drivers/usb/serial/omninet.c b/drivers/usb/serial/omninet.c
index 0e006b11ed3d..0a73ea0b144b 100644
--- a/drivers/usb/serial/omninet.c
+++ b/drivers/usb/serial/omninet.c
@@ -216,14 +216,15 @@ static void omninet_close (struct usb_serial_port *port, struct file * filp)
--port->open_count;
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);
+ }
port->active = 0;
port->open_count = 0;
+ od = (struct omninet_data *)port->private;
if (od)
kfree(od);
}
diff --git a/drivers/usb/serial/pl2303.c b/drivers/usb/serial/pl2303.c
index 4714a5a9f5ac..85ff19b6b0e7 100644
--- a/drivers/usb/serial/pl2303.c
+++ b/drivers/usb/serial/pl2303.c
@@ -434,40 +434,53 @@ static int pl2303_open (struct usb_serial_port *port, struct file *filp)
static void pl2303_close (struct usb_serial_port *port, struct file *filp)
{
+ struct usb_serial *serial;
struct pl2303_private *priv;
unsigned int c_cflag;
int result;
if (port_paranoia_check (port, __FUNCTION__))
return;
-
+ serial = get_usb_serial (port, __FUNCTION__);
+ if (!serial)
+ return;
+
dbg (__FUNCTION__ " - port %d", port->number);
down (&port->sem);
--port->open_count;
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);
+ /* 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->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);
+ result = usb_unlink_urb (port->interrupt_in_urb);
+ if (result)
+ dbg (__FUNCTION__ " - usb_unlink_urb "
+ "(interrupt_in_urb) failed with reason: %d",
+ result);
+ }
port->active = 0;
port->open_count = 0;
diff --git a/drivers/usb/serial/usb-serial.h b/drivers/usb/serial/usb-serial.h
index f79b2c0630fe..5d40a8d519aa 100644
--- a/drivers/usb/serial/usb-serial.h
+++ b/drivers/usb/serial/usb-serial.h
@@ -11,6 +11,10 @@
*
* See Documentation/usb/usb-serial.txt for more information on using this driver
*
+ * (10/10/2001) gkh
+ * added vendor and product to serial structure. Needed to determine device
+ * owner when the device is disconnected.
+ *
* (05/30/2001) gkh
* added sem to port structure and removed port_lock
*
@@ -96,6 +100,8 @@ struct usb_serial {
char num_interrupt_in; /* number of interrupt in endpoints we have */
char num_bulk_in; /* number of bulk in endpoints we have */
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 */
struct usb_serial_port port[MAX_NUM_PORTS];
void * private; /* data private to the specific driver */
diff --git a/drivers/usb/serial/usbserial.c b/drivers/usb/serial/usbserial.c
index 3d46afd72a67..41655a9566b7 100644
--- a/drivers/usb/serial/usbserial.c
+++ b/drivers/usb/serial/usbserial.c
@@ -14,7 +14,12 @@
* based on a driver by Brad Keryan)
*
* 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.
+ *
* (09/13/2001) gkh
* Moved generic driver initialize after we have registered with the USB
* core. Thanks to Randy Dunlap for pointing this problem out.
@@ -344,9 +349,9 @@ static struct usb_serial_device_type generic_device = {
shutdown: generic_shutdown,
};
-#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
#else
#define if_generic_do(x)
@@ -462,10 +467,15 @@ static void return_serial (struct usb_serial *serial)
int ezusb_writememory (struct usb_serial *serial, int address, unsigned char *data, int length, __u8 bRequest)
{
int result;
- unsigned char *transfer_buffer = kmalloc (length, GFP_KERNEL);
+ unsigned char *transfer_buffer;
-// 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;
+ }
+ transfer_buffer = kmalloc (length, GFP_KERNEL);
if (!transfer_buffer) {
err(__FUNCTION__ " - kmalloc(%d) failed.", length);
return -ENOMEM;
@@ -821,11 +831,13 @@ static void generic_close (struct usb_serial_port *port, struct file * filp)
--port->open_count;
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);
+ }
port->active = 0;
port->open_count = 0;
@@ -1186,6 +1198,8 @@ static void * usb_serial_probe(struct usb_device *dev, unsigned int ifnum,
serial->num_bulk_in = num_bulk_in;
serial->num_bulk_out = num_bulk_out;
serial->num_interrupt_in = num_interrupt_in;
+ serial->vendor = dev->descriptor.idVendor;
+ serial->product = dev->descriptor.idProduct;
/* if this device type has a startup function, call it */
if (type->startup) {
@@ -1338,6 +1352,7 @@ static void usb_serial_disconnect(struct usb_device *dev, void *ptr)
serial->port[i].tty->driver_data = NULL;
}
+ serial->dev = NULL;
serial_shutdown (serial);
for (i = 0; i < serial->num_ports; ++i)
diff --git a/drivers/usb/serial/visor.c b/drivers/usb/serial/visor.c
index 6ddb0dff64a1..8dc10bd95873 100644
--- a/drivers/usb/serial/visor.c
+++ b/drivers/usb/serial/visor.c
@@ -380,21 +380,26 @@ static void visor_close (struct usb_serial_port *port, struct file * filp)
--port->open_count;
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);
}
-
- /* shutdown our bulk read */
- usb_unlink_urb (port->read_urb);
port->active = 0;
port->open_count = 0;
-
}
up (&port->sem);
diff --git a/drivers/usb/uhci.c b/drivers/usb/uhci.c
index d75713383dde..b94676cf945c 100644
--- a/drivers/usb/uhci.c
+++ b/drivers/usb/uhci.c
@@ -1594,9 +1594,7 @@ out:
}
uhci_unlink_generic(uhci, urb);
- uhci_destroy_urb_priv(urb);
-
- usb_dec_dev_use(urb->dev);
+ uhci_call_completion(urb);
return ret;
}
diff --git a/drivers/usb/usbvideo.c b/drivers/usb/usbvideo.c
index 3c09474b476c..c40e6c5795ac 100644
--- a/drivers/usb/usbvideo.c
+++ b/drivers/usb/usbvideo.c
@@ -84,27 +84,6 @@ unsigned long usbvideo_uvirt_to_kva(pgd_t *pgd, unsigned long adr)
return ret;
}
-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;
-}
-
/*
* Here we want the physical address of the memory.
* This is used when initializing the contents of the
diff --git a/drivers/usb/usbvideo.h b/drivers/usb/usbvideo.h
index cca31f5950db..b37a9f82671d 100644
--- a/drivers/usb/usbvideo.h
+++ b/drivers/usb/usbvideo.h
@@ -329,8 +329,6 @@ void usbvideo_VideosizeToString(char *buf, int bufLen, videosize_t vs);
/* Memory allocation routines */
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);
unsigned long usbvideo_kvirt_to_pa(unsigned long adr);
void *usbvideo_rvmalloc(unsigned long size);
void usbvideo_rvfree(void *mem, unsigned long size);
diff --git a/drivers/video/fbmem.c b/drivers/video/fbmem.c
index 461ac8740b26..e5080d25f3ab 100644
--- a/drivers/video/fbmem.c
+++ b/drivers/video/fbmem.c
@@ -124,6 +124,8 @@ extern int e1355fb_init(void);
extern int e1355fb_setup(char*);
extern int pvr2fb_init(void);
extern int pvr2fb_setup(char*);
+extern int sstfb_init(void);
+extern int sstfb_setup(char*);
static struct {
const char *name;
@@ -274,7 +276,9 @@ static struct {
#ifdef CONFIG_FB_PVR2
{ "pvr2", pvr2fb_init, pvr2fb_setup },
#endif
-
+#ifdef CONFIG_FB_VOODOO1
+ { "sst", sstfb_init, sstfb_setup },
+#endif
/*
* Generic drivers that don't use resource management (yet)
*/
diff --git a/fs/devfs/base.c b/fs/devfs/base.c
index db7a1c777802..b25dbb434bd1 100644
--- a/fs/devfs/base.c
+++ b/fs/devfs/base.c
@@ -548,6 +548,13 @@
20010927 Richard Gooch <rgooch@atnf.csiro.au>
Went back to global rwsem for symlinks (refcount scheme no good)
v0.117
+ 20011008 Richard Gooch <rgooch@atnf.csiro.au>
+ Fixed overrun in <devfs_link> by removing function (not needed).
+ v0.118
+ 20011009 Richard Gooch <rgooch@atnf.csiro.au>
+ Fixed buffer underrun in <try_modload>.
+ Moved down_read() from <search_for_entry_in_dir> to <find_entry>
+ v0.119
*/
#include <linux/types.h>
#include <linux/errno.h>
@@ -580,7 +587,7 @@
#include <asm/bitops.h>
#include <asm/atomic.h>
-#define DEVFS_VERSION "0.117 (20010927)"
+#define DEVFS_VERSION "0.119 (20011009)"
#define DEVFS_NAME "devfs"
@@ -810,12 +817,10 @@ static struct devfs_entry *search_for_entry_in_dir (struct devfs_entry *parent,
if (curr == NULL) return NULL;
if (!S_ISLNK (curr->mode) || !traverse_symlink) return curr;
/* Need to follow the link: this is a stack chomper */
- down_read (&symlink_rwsem);
retval = curr->registered ?
search_for_entry (parent, curr->u.symlink.linkname,
curr->u.symlink.length, FALSE, FALSE, NULL,
TRUE) : NULL;
- up_read (&symlink_rwsem);
return retval;
} /* End Function search_for_entry_in_dir */
@@ -1085,8 +1090,10 @@ static struct devfs_entry *find_entry (devfs_handle_t dir,
++name;
--namelen;
}
+ if (traverse_symlink) down_read (&symlink_rwsem);
entry = search_for_entry (dir, name, namelen, FALSE, FALSE, NULL,
traverse_symlink);
+ if (traverse_symlink) up_read (&symlink_rwsem);
if (entry != NULL) return entry;
}
/* Have to search by major and minor: slow */
@@ -1647,8 +1654,7 @@ devfs_handle_t devfs_find_handle (devfs_handle_t dir, const char *name,
devfs_handle_t de;
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);
if (de == NULL) return NULL;
if (!de->registered) return NULL;
return de;
@@ -2138,7 +2144,7 @@ static int try_modload (struct devfs_entry *parent, struct fs_info *fs_info,
if ( !( fs_info->devfsd_event_mask & (1 << DEVFSD_NOTIFY_LOOKUP) ) )
return -ENOENT;
if ( is_devfsd_or_child (fs_info) ) return -ENOENT;
- if (namelen >= STRING_LENGTH) return -ENAMETOOLONG;
+ if (namelen >= STRING_LENGTH - 1) return -ENAMETOOLONG;
memcpy (buf + pos, name, namelen);
buf[STRING_LENGTH - 1] = '\0';
if (parent->parent != NULL) pos = devfs_generate_path (parent, buf, pos);
@@ -2781,19 +2787,6 @@ static struct dentry *devfs_lookup (struct inode *dir, struct dentry *dentry)
return NULL;
} /* End Function devfs_lookup */
-static int devfs_link (struct dentry *old_dentry, struct inode *dir,
- 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 */
-
static int devfs_unlink (struct inode *dir, struct dentry *dentry)
{
struct devfs_entry *de;
@@ -3054,7 +3047,6 @@ static struct inode_operations devfs_iops =
static struct inode_operations devfs_dir_iops =
{
lookup: devfs_lookup,
- link: devfs_link,
unlink: devfs_unlink,
symlink: devfs_symlink,
mkdir: devfs_mkdir,
diff --git a/fs/ext2/inode.c b/fs/ext2/inode.c
index eb01965acd19..271cbd15b733 100644
--- a/fs/ext2/inode.c
+++ b/fs/ext2/inode.c
@@ -1148,63 +1148,3 @@ int ext2_sync_inode (struct inode *inode)
{
return ext2_update_inode (inode, 1);
}
-
-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 --git a/fs/namei.c b/fs/namei.c
index 6bec13d2e273..42bbfef9b116 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -325,9 +325,7 @@ static struct dentry * real_lookup(struct dentry * parent, struct qstr * name, i
}
/*
- * 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
* limiting consecutive symlinks to 40.
*
* Without that kind of total limit, nasty chains of consecutive
@@ -336,16 +334,19 @@ static struct dentry * real_lookup(struct dentry * parent, struct qstr * name, i
static inline int do_follow_link(struct dentry *dentry, struct nameidata *nd)
{
int err;
- if (current->link_count >= 40)
+ if (current->link_count >= 5)
+ goto loop;
+ if (current->total_link_count >= 40)
goto loop;
if (current->need_resched) {
current->state = TASK_RUNNING;
schedule();
}
- current->link_count += 5;
+ current->link_count++;
+ current->total_link_count++;
UPDATE_ATIME(dentry->d_inode);
err = dentry->d_inode->i_op->follow_link(dentry, nd);
- current->link_count -= 4;
+ current->link_count--;
return err;
loop:
path_release(nd);
@@ -636,7 +637,7 @@ return_err:
int path_walk(const char * name, struct nameidata *nd)
{
- current->link_count = 0;
+ current->total_link_count = 0;
return link_path_walk(name, nd);
}
diff --git a/fs/namespace.c b/fs/namespace.c
index 1f51ca049993..d1101b4438ef 100644
--- a/fs/namespace.c
+++ b/fs/namespace.c
@@ -336,9 +336,6 @@ void umount_tree(struct vfsmount *mnt)
struct vfsmount *p;
LIST_HEAD(kill);
- if (list_empty(&mnt->mnt_list))
- return;
-
for (p = mnt; p; p = next_mnt(p, mnt)) {
list_del(&p->mnt_list);
list_add(&p->mnt_list, &kill);
@@ -418,7 +415,8 @@ static int do_umount(struct vfsmount *mnt, int flags)
}
retval = -EBUSY;
if (atomic_read(&mnt->mnt_count) == 2 || flags & MNT_DETACH) {
- umount_tree(mnt);
+ if (!list_empty(&mnt->mnt_list))
+ umount_tree(mnt);
retval = 0;
}
spin_unlock(&dcache_lock);
@@ -592,9 +590,10 @@ static int do_loopback(struct nameidata *nd, char *old_name, int recurse)
if (mnt) {
err = graft_tree(mnt, nd);
- if (err && recurse)
+ if (err)
umount_tree(mnt);
- mntput(mnt);
+ else
+ mntput(mnt);
}
up(&mount_sem);
diff --git a/fs/proc/base.c b/fs/proc/base.c
index edae3acee910..5331c73d7912 100644
--- a/fs/proc/base.c
+++ b/fs/proc/base.c
@@ -184,29 +184,6 @@ static int proc_pid_cmdline(struct task_struct *task, char * buffer)
/* permission checks */
-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;
-}
-
static int proc_check_root(struct inode *inode)
{
struct dentry *de, *base, *root;
@@ -249,7 +226,7 @@ out:
static int proc_permission(struct inode *inode, int mask)
{
- if (standard_permission(inode, mask) != 0)
+ if (vfs_permission(inode, mask) != 0)
return -EACCES;
return proc_check_root(inode);
}
diff --git a/fs/super.c b/fs/super.c
index d6b12cf1e5ba..04a94d8598c9 100644
--- a/fs/super.c
+++ b/fs/super.c
@@ -443,7 +443,7 @@ static struct super_block *alloc_super(void)
static struct super_block * read_super(kdev_t dev, struct block_device *bdev,
struct file_system_type *type, int flags,
- void *data, int silent)
+ void *data)
{
struct super_block * s;
s = alloc_super();
@@ -460,7 +460,7 @@ static struct super_block * read_super(kdev_t dev, struct block_device *bdev,
spin_unlock(&sb_lock);
down_write(&s->s_umount);
lock_super(s);
- if (!type->read_super(s, data, silent))
+ if (!type->read_super(s, data, flags & MS_VERBOSE ? 1 : 0))
goto out_fail;
unlock_super(s);
/* tell bdcache that we are going to keep this one */
@@ -612,7 +612,7 @@ restart:
error = -EINVAL;
lock_super(s);
- if (!fs_type->read_super(s, data, 0))
+ if (!fs_type->read_super(s, data, flags & MS_VERBOSE ? 1 : 0))
goto out_fail;
unlock_super(s);
get_filesystem(fs_type);
@@ -646,7 +646,7 @@ static struct super_block *get_sb_nodev(struct file_system_type *fs_type,
if (dev) {
struct super_block * sb;
error = -EINVAL;
- sb = read_super(dev, NULL, fs_type, flags, data, 0);
+ sb = read_super(dev, NULL, fs_type, flags, data);
if (sb) {
get_filesystem(fs_type);
return sb;
@@ -692,7 +692,7 @@ retry:
s->s_count += S_BIAS;
spin_unlock(&sb_lock);
lock_super(s);
- if (!fs_type->read_super(s, data, 0))
+ if (!fs_type->read_super(s, data, flags & MS_VERBOSE ? 1 : 0))
goto out_fail;
unlock_super(s);
get_filesystem(fs_type);
@@ -865,10 +865,45 @@ struct vfsmount *kern_mount(struct file_system_type *type)
return do_kern_mount((char *)type->name, 0, (char *)type->name, NULL);
}
+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';
+}
+
void __init mount_root(void)
{
struct nameidata root_nd;
- struct file_system_type * fs_type;
struct super_block * sb;
struct vfsmount *vfsmnt;
struct block_device *bdev = NULL;
@@ -878,36 +913,24 @@ void __init mount_root(void)
char path[64];
int path_start = -1;
char *name = "/dev/root";
-
+ char *fs_names, *p;
#ifdef CONFIG_ROOT_NFS
void *data;
+#endif
+ root_mountflags |= MS_VERBOSE;
+
+#ifdef CONFIG_ROOT_NFS
if (MAJOR(ROOT_DEV) != UNNAMED_MAJOR)
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;
data = nfs_root_data();
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;
+ }
no_nfs:
printk(KERN_ERR "VFS: Unable to mount root fs via NFS, trying floppy.\n");
ROOT_DEV = MKDEV(FLOPPY_MAJOR, 0);
@@ -936,6 +959,9 @@ skip_nfs:
}
#endif
+ fs_names = __getname();
+ get_fs_names(fs_names);
+
devfs_make_root (root_device_name);
handle = devfs_find_handle (NULL, ROOT_DEVICE_NAME,
MAJOR (ROOT_DEV), MINOR (ROOT_DEV),
@@ -985,35 +1011,30 @@ retry:
sb = get_super(ROOT_DEV);
if (sb) {
/* FIXME */
- fs_type = sb->s_type;
+ p = (char *)sb->s_type->name;
atomic_inc(&sb->s_active);
up_read(&sb->s_umount);
down_write(&sb->s_umount);
goto mount_it;
}
- 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)
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);
if (sb)
goto mount_it;
- read_lock(&file_systems_lock);
put_filesystem(fs_type);
}
- read_unlock(&file_systems_lock);
panic("VFS: Unable to mount root fs on %s", kdevname(ROOT_DEV));
mount_it:
/* FIXME */
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,
(sb->s_flags & MS_RDONLY) ? " readonly" : "");
+ putname(fs_names);
if (path_start >= 0) {
name = path + path_start;
devfs_mk_symlink (NULL, "root", DEVFS_FL_DEFAULT,
@@ -1027,18 +1048,15 @@ mount_it:
set_devname(vfsmnt, name);
vfsmnt->mnt_sb = sb;
vfsmnt->mnt_root = dget(sb->s_root);
+ bdput(bdev); /* sb holds a reference */
+attach_it:
root_nd.mnt = root_vfsmnt;
root_nd.dentry = root_vfsmnt->mnt_sb->s_root;
graft_tree(vfsmnt, &root_nd);
- mntput(vfsmnt);
- /* 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);
}
diff --git a/include/asm-i386/smp.h b/include/asm-i386/smp.h
index f841e428c3f3..24c22c40cd6c 100644
--- a/include/asm-i386/smp.h
+++ b/include/asm-i386/smp.h
@@ -31,7 +31,7 @@
# define INT_DELIVERY_MODE 1 /* logical delivery broadcast to all procs */
# endif
#else
-# define INT_DELIVERY_MODE 0 /* physical delivery on LOCAL quad */
+# define INT_DELIVERY_MODE 1 /* logical delivery */
# define TARGET_CPUS 0x01
#endif
diff --git a/include/asm-sparc/processor.h b/include/asm-sparc/processor.h
index f33f8346a3de..bdf40ecf37b7 100644
--- a/include/asm-sparc/processor.h
+++ b/include/asm-sparc/processor.h
@@ -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 $
* include/asm-sparc/processor.h
*
* Copyright (C) 1994 David S. Miller (davem@caip.rutgers.edu)
diff --git a/include/asm-sparc/unistd.h b/include/asm-sparc/unistd.h
index 741949c5e4e2..7fff6e2176be 100644
--- a/include/asm-sparc/unistd.h
+++ b/include/asm-sparc/unistd.h
@@ -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 $ */
#ifndef _SPARC_UNISTD_H
#define _SPARC_UNISTD_H
@@ -158,7 +158,7 @@
/* #define __NR_adjtime 140 SunOS Specific */
#define __NR_getpeername 141 /* Common */
/* #define __NR_gethostid 142 SunOS Specific */
-/* #define __NR_ni_syscall 143 ENOSYS under SunOS */
+#define __NR_gettid 143 /* ENOSYS under SunOS */
#define __NR_getrlimit 144 /* Common */
#define __NR_setrlimit 145 /* Common */
#define __NR_pivot_root 146 /* Linux Specific, killpg under SunOS */
diff --git a/include/asm-sparc64/processor.h b/include/asm-sparc64/processor.h
index a75aecfed402..c026b640a103 100644
--- a/include/asm-sparc64/processor.h
+++ b/include/asm-sparc64/processor.h
@@ -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 $
* include/asm-sparc64/processor.h
*
* Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu)
diff --git a/include/asm-sparc64/unistd.h b/include/asm-sparc64/unistd.h
index f89c5d50a196..a9b7cd162fe5 100644
--- a/include/asm-sparc64/unistd.h
+++ b/include/asm-sparc64/unistd.h
@@ -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 $ */
#ifndef _SPARC64_UNISTD_H
#define _SPARC64_UNISTD_H
@@ -158,7 +158,7 @@
/* #define __NR_adjtime 140 SunOS Specific */
#define __NR_getpeername 141 /* Common */
/* #define __NR_gethostid 142 SunOS Specific */
-/* #define __NR_ni_syscall 143 ENOSYS under SunOS */
+#define __NR_gettid 143 /* ENOSYS under SunOS */
#define __NR_getrlimit 144 /* Common */
#define __NR_setrlimit 145 /* Common */
#define __NR_pivot_root 146 /* Linux Specific, killpg under SunOS */
diff --git a/include/linux/ext2_fs.h b/include/linux/ext2_fs.h
index 3351936bc1b3..79d82d2ac6d8 100644
--- a/include/linux/ext2_fs.h
+++ b/include/linux/ext2_fs.h
@@ -545,9 +545,6 @@ enum {
# define ATTRIB_NORET __attribute__((noreturn))
# define NORET_AND noreturn,
-/* acl.c */
-extern int ext2_permission (struct inode *, int);
-
/* balloc.c */
extern int ext2_bg_has_super(struct super_block *sb, int group);
extern unsigned long ext2_bg_num_gdb(struct super_block *sb, int group);
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 25b027edda36..d1327ef61f97 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -109,6 +109,7 @@ extern int leases_enable, dir_notify_enable, lease_break_time;
#define MS_NODIRATIME 2048 /* Do not update directory access times */
#define MS_BIND 4096
#define MS_REC 16384
+#define MS_VERBOSE 32768
#define MS_NOUSER (1<<31)
/*
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index c6d1f405f728..456e9db29d97 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -636,6 +636,41 @@ static inline void netif_device_attach(struct net_device *dev)
}
}
+/*
+ * 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)
+
/* These functions live elsewhere (drivers/net/net_init.c, but related) */
extern void ether_setup(struct net_device *dev);
diff --git a/include/linux/parport.h b/include/linux/parport.h
index f0659c771ff3..07a9ac6ae9a3 100644
--- a/include/linux/parport.h
+++ b/include/linux/parport.h
@@ -251,7 +251,8 @@ enum ieee1284_phase {
IEEE1284_PH_REV_DATA,
IEEE1284_PH_ECP_SETUP,
IEEE1284_PH_ECP_FWD_TO_REV,
- IEEE1284_PH_ECP_REV_TO_FWD
+ IEEE1284_PH_ECP_REV_TO_FWD,
+ IEEE1284_PH_ECP_DIR_UNKNOWN,
};
struct ieee1284_info {
int mode;
diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h
index 3998ff150d9d..bc3d02f4d249 100644
--- a/include/linux/pci_ids.h
+++ b/include/linux/pci_ids.h
@@ -1437,9 +1437,11 @@
#define PCI_DEVICE_ID_TIMEDIA_1889 0x7168
#define PCI_VENDOR_ID_OXSEMI 0x1415
+#define PCI_DEVICE_ID_OXSEMI_12PCI840 0x8403
#define PCI_DEVICE_ID_OXSEMI_16PCI954 0x9501
#define PCI_DEVICE_ID_OXSEMI_16PCI952 0x950A
#define PCI_DEVICE_ID_OXSEMI_16PCI95N 0x9511
+#define PCI_DEVICE_ID_OXSEMI_16PCI954PP 0x9513
#define PCI_VENDOR_ID_AIRONET 0x14b9
#define PCI_DEVICE_ID_AIRONET_4800_1 0x0001
@@ -1463,9 +1465,6 @@
#define PCI_DEVICE_ID_PANACOM_QUADMODEM 0x0400
#define PCI_DEVICE_ID_PANACOM_DUALMODEM 0x0402
-#define PCI_VENDOR_ID_AFAVLAB 0x14db
-#define PCI_DEVICE_ID_AFAVLAB_TK9902 0x2120
-
#define PCI_VENDOR_ID_BROADCOM 0x14e4
#define PCI_DEVICE_ID_TIGON3 0x1644
diff --git a/include/linux/sched.h b/include/linux/sched.h
index 45ab381f26aa..564fb7b3e371 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -369,7 +369,7 @@ struct task_struct {
unsigned short used_math;
char comm[16];
/* file system info */
- int link_count;
+ int link_count, total_link_count;
struct tty_struct *tty; /* NULL if no tty */
unsigned int locks; /* How many file locks are being held */
/* ipc stuff */
diff --git a/include/linux/shmem_fs.h b/include/linux/shmem_fs.h
index e1f2c56e39fc..fbcfce81e110 100644
--- a/include/linux/shmem_fs.h
+++ b/include/linux/shmem_fs.h
@@ -17,14 +17,18 @@ typedef struct {
unsigned long val;
} swp_entry_t;
+extern atomic_t shmem_nrpages;
+
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 */
struct list_head list;
+ struct inode *inode;
};
struct shmem_sb_info {
@@ -35,4 +39,6 @@ struct shmem_sb_info {
spinlock_t stat_lock;
};
+#define SHMEM_I(inode) (&inode->u.shmem_i)
+
#endif
diff --git a/mm/shmem.c b/mm/shmem.c
index 05f06b79b4ca..d4d4a59e9f7d 100644
--- a/mm/shmem.c
+++ b/mm/shmem.c
@@ -26,15 +26,16 @@
#include <linux/pagemap.h>
#include <linux/string.h>
#include <linux/locks.h>
-#include <asm/smplock.h>
+#include <linux/smp_lock.h>
#include <asm/uaccess.h>
/* This magic number is used in glibc for posix shared memory */
#define TMPFS_MAGIC 0x01021994
-#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)
static struct super_operations shmem_ops;
static struct address_space_operations shmem_aops;
@@ -42,18 +43,19 @@ static struct file_operations shmem_file_operations;
static struct inode_operations shmem_inode_operations;
static struct file_operations shmem_dir_operations;
static struct inode_operations shmem_dir_inode_operations;
-static struct inode_operations shmem_symlink_inode_operations;
static struct vm_operations_struct shmem_vm_ops;
LIST_HEAD (shmem_inodes);
static spinlock_t shmem_ilock = SPIN_LOCK_UNLOCKED;
+atomic_t shmem_nrpages = ATOMIC_INIT(0); /* Not used right now */
-#define BLOCKS_PER_PAGE (PAGE_SIZE/512)
+#define BLOCKS_PER_PAGE (PAGE_CACHE_SIZE/512)
/*
* shmem_recalc_inode - recalculate the size of an inode
*
* @inode: inode to recalc
+ * @swap: additional swap pages freed externally
*
* We have to calculate the free blocks since the mm can drop pages
* behind our back
@@ -64,7 +66,7 @@ static spinlock_t shmem_ilock = SPIN_LOCK_UNLOCKED;
*
* So the mm freed
* inodes->i_blocks/BLOCKS_PER_PAGE -
- * (inode->i_mapping->nrpages + info->swapped)
+ * (inode->i_mapping->nrpages + info->swapped)
*
* It has to be called with the spinlock held.
*/
@@ -74,19 +76,63 @@ static void shmem_recalc_inode(struct inode * inode)
unsigned long freed;
freed = (inode->i_blocks/BLOCKS_PER_PAGE) -
- (inode->i_mapping->nrpages + inode->u.shmem_i.swapped);
+ (inode->i_mapping->nrpages + SHMEM_I(inode)->swapped);
if (freed){
- struct shmem_sb_info * info = &inode->i_sb->u.shmem_sb;
+ struct shmem_sb_info * sbinfo = SHMEM_SB(inode->i_sb);
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);
}
}
-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)
{
unsigned long offset;
+ void **dir;
if (index < SHMEM_NR_DIRECT)
return info->i_direct+index;
@@ -95,23 +141,66 @@ static swp_entry_t * shmem_swp_entry (struct shmem_inode_info *info, unsigned lo
offset = index % ENTRIES_PER_PAGE;
index /= ENTRIES_PER_PAGE;
- if (index >= ENTRIES_PER_PAGE)
- return ERR_PTR(-EFBIG);
-
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 */
return ERR_PTR(-ENOMEM);
+ }
+ dir = ((void **)*dir) + index;
}
- 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)
return ERR_PTR(-ENOMEM);
+ *dir = (void *)page;
}
-
- return info->i_indirect[index]+offset;
+ return ((swp_entry_t *)*dir) + offset;
+}
+
+/*
+ * 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
+ */
static int shmem_free_swp(swp_entry_t *dir, unsigned int count)
{
swp_entry_t *ptr, entry;
@@ -131,95 +220,197 @@ static int shmem_free_swp(swp_entry_t *dir, unsigned int count)
}
/*
- * shmem_truncate_part - free a bunch of swap entries
- *
- * @dir: pointer to swp_entries
- * @size: number of entries in dir
- * @start: offset to start from
- * @freed: counter for freed pages
+ * shmem_truncate_direct - free the swap entries of a whole doubly
+ * indirect block
*
- * It frees the swap entries from dir+start til dir+size
+ * @dir: pointer to the pointer to the block
+ * @start: offset to start from (in pages)
+ * @len: how many pages are stored in this block
*
- * returns 0 if it truncated something, else (offset-size)
+ * Returns the number of freed swap entries.
*/
-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;
+ }
+ }
- 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);
}
static void shmem_truncate (struct inode * inode)
{
- int clear_base;
- unsigned long index, start;
+ unsigned long index;
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);
+ down(&info->sem);
inode->i_ctime = inode->i_mtime = CURRENT_TIME;
spin_lock (&info->lock);
index = (inode->i_size + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT;
- if (index > info->max_index)
- goto out;
- start = shmem_truncate_part (info->i_direct, SHMEM_NR_DIRECT, index, &freed);
+ while (index < info->next_index)
+ freed += shmem_truncate_indirect(info, index);
- if (!(base = info->i_indirect))
- goto out;
+ info->swapped -= freed;
+ shmem_recalc_inode(inode);
+ spin_unlock (&info->lock);
+ up(&info->sem);
+}
- 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);
}
+ spin_lock (&sbinfo->stat_lock);
+ sbinfo->free_inodes++;
+ spin_unlock (&sbinfo->stat_lock);
+ clear_inode(inode);
+}
- if (clear_base) {
- free_page ((unsigned long)base);
- info->i_indirect = 0;
+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;
+}
-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;
+ }
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;
}
-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)
{
- struct shmem_sb_info *info = &inode->i_sb->u.shmem_sb;
+ struct list_head *p;
+ struct shmem_inode_info * info;
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;
+ }
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);
}
/*
@@ -244,7 +435,7 @@ static int shmem_writepage(struct page * page)
mapping = page->mapping;
index = page->index;
inode = mapping->host;
- info = &inode->u.shmem_i;
+ info = SHMEM_I(inode);
getswap:
swap = get_swap_page();
if (!swap.val) {
@@ -255,7 +446,7 @@ getswap:
}
spin_lock(&info->lock);
- entry = shmem_swp_entry(info, index);
+ entry = shmem_swp_entry(info, index, 0);
if (IS_ERR(entry)) /* this had been allocated on page allocation */
BUG();
shmem_recalc_inode(inode);
@@ -300,27 +491,25 @@ out:
* still need to guard against racing with shm_writepage(), which might
* be trying to move the page to the swap cache as we run.
*/
-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)
{
struct address_space * mapping = inode->i_mapping;
- struct shmem_inode_info *info;
+ struct shmem_sb_info *sbinfo;
struct page * page;
swp_entry_t *entry;
- info = &inode->u.shmem_i;
-
repeat:
page = find_lock_page(mapping, idx);
if (page)
return page;
- entry = shmem_swp_entry (info, idx);
+ entry = shmem_alloc_entry (info, idx);
if (IS_ERR(entry))
return (void *)entry;
spin_lock (&info->lock);
- /* The shmem_swp_entry() call may have blocked, and
+ /* The shmem_alloc_entry() call may have blocked, and
* shmem_writepage may have been moving a page between the page
* cache and swap cache. We need to recheck the page cache
* under the protection of the info->lock spinlock. */
@@ -370,18 +559,19 @@ repeat:
swap_free(*entry);
*entry = (swp_entry_t) {0};
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));
page->flags = flags | (1 << PG_dirty);
add_to_page_cache_locked(page, mapping, idx);
info->swapped--;
spin_unlock (&info->lock);
} else {
+ sbinfo = SHMEM_SB(inode->i_sb);
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)
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);
/* Ok, get a new page. We don't have to worry about the
* info->lock spinlock here: we cannot race against
@@ -404,7 +594,7 @@ repeat:
page_cache_get(page);
return page;
no_space:
- spin_unlock (&inode->i_sb->u.shmem_sb.stat_lock);
+ spin_unlock (&sbinfo->stat_lock);
return ERR_PTR(-ENOSPC);
wait_retry:
@@ -416,28 +606,28 @@ wait_retry:
static int shmem_getpage(struct inode * inode, unsigned long idx, struct page **ptr)
{
+ struct shmem_inode_info *info = SHMEM_I(inode);
int error;
- down (&inode->i_sem);
+ down (&info->sem);
+ *ptr = ERR_PTR(-EFAULT);
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);
if (IS_ERR (*ptr))
goto failed;
+
UnlockPage(*ptr);
- up (&inode->i_sem);
+ up (&info->sem);
return 0;
failed:
- up (&inode->i_sem);
+ up (&info->sem);
error = PTR_ERR(*ptr);
- *ptr = NOPAGE_OOM;
- if (error != -EFBIG)
- *ptr = NOPAGE_SIGBUS;
- return error;
-sigbus:
- up (&inode->i_sem);
*ptr = NOPAGE_SIGBUS;
- return -EFAULT;
+ if (error == -ENOMEM)
+ *ptr = NOPAGE_OOM;
+ return error;
}
struct page * shmem_nopage(struct vm_area_struct * vma, unsigned long address, int no_share)
@@ -446,7 +636,7 @@ struct page * shmem_nopage(struct vm_area_struct * vma, unsigned long address, i
unsigned int idx;
struct inode * inode = vma->vm_file->f_dentry->d_inode;
- idx = (address - vma->vm_start) >> PAGE_SHIFT;
+ idx = (address - vma->vm_start) >> PAGE_CACHE_SHIFT;
idx += vma->vm_pgoff;
if (shmem_getpage(inode, idx, &page))
@@ -471,13 +661,13 @@ struct page * shmem_nopage(struct vm_area_struct * vma, unsigned long address, i
void shmem_lock(struct file * file, int lock)
{
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);
struct page * page;
unsigned long idx, size;
- if (info->locked == lock)
- return;
- down(&inode->i_sem);
+ down(&info->sem);
+ if (info->locked == lock)
+ goto out;
info->locked = lock;
size = (inode->i_size + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT;
for (idx = 0; idx < size; idx++) {
@@ -491,7 +681,8 @@ void shmem_lock(struct file * file, int lock)
}
UnlockPage(page);
}
- up(&inode->i_sem);
+out:
+ up(&info->sem);
}
static int shmem_mmap(struct file * file, struct vm_area_struct * vma)
@@ -510,14 +701,16 @@ static int shmem_mmap(struct file * file, struct vm_area_struct * vma)
struct inode *shmem_get_inode(struct super_block *sb, int mode, int dev)
{
struct inode * inode;
+ struct shmem_inode_info *info;
+ struct shmem_sb_info *sbinfo = SHMEM_SB(sb);
- 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);
return NULL;
}
- sb->u.shmem_sb.free_inodes--;
- spin_unlock (&sb->u.shmem_sb.stat_lock);
+ sbinfo->free_inodes--;
+ spin_unlock (&sbinfo->stat_lock);
inode = new_inode(sb);
if (inode) {
@@ -529,7 +722,10 @@ struct inode *shmem_get_inode(struct super_block *sb, int mode, int dev)
inode->i_rdev = NODEV;
inode->i_mapping->a_ops = &shmem_aops;
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);
switch (mode & S_IFMT) {
default:
init_special_inode(inode, mode, dev);
@@ -537,6 +733,9 @@ struct inode *shmem_get_inode(struct super_block *sb, int mode, int dev)
case S_IFREG:
inode->i_op = &shmem_inode_operations;
inode->i_fop = &shmem_file_operations;
+ spin_lock (&shmem_ilock);
+ list_add (&SHMEM_I(inode)->list, &shmem_inodes);
+ spin_unlock (&shmem_ilock);
break;
case S_IFDIR:
inode->i_nlink++;
@@ -544,12 +743,8 @@ struct inode *shmem_get_inode(struct super_block *sb, int mode, int dev)
inode->i_fop = &shmem_dir_operations;
break;
case S_IFLNK:
- inode->i_op = &shmem_symlink_inode_operations;
break;
}
- spin_lock (&shmem_ilock);
- list_add (&inode->u.shmem_i.list, &shmem_inodes);
- spin_unlock (&shmem_ilock);
}
return inode;
}
@@ -579,10 +774,15 @@ out:
}
#ifdef CONFIG_TMPFS
+
+static struct inode_operations shmem_symlink_inode_operations;
+static struct inode_operations shmem_symlink_inline_operations;
+
static ssize_t
shmem_file_write(struct file *file,const char *buf,size_t count,loff_t *ppos)
{
struct inode *inode = file->f_dentry->d_inode;
+ struct shmem_inode_info *info;
unsigned long limit = current->rlim[RLIMIT_FSIZE].rlim_cur;
loff_t pos;
struct page *page;
@@ -658,7 +858,11 @@ shmem_file_write(struct file *file,const char *buf,size_t count,loff_t *ppos)
__get_user(dummy, buf+bytes-1);
}
- page = shmem_getpage_locked(inode, index);
+ info = SHMEM_I(inode);
+ down (&info->sem);
+ page = shmem_getpage_locked(info, inode, index);
+ up (&info->sem);
+
status = PTR_ERR(page);
if (IS_ERR(page))
break;
@@ -669,7 +873,6 @@ shmem_file_write(struct file *file,const char *buf,size_t count,loff_t *ppos)
}
kaddr = kmap(page);
-// can this do a truncated write? cr
status = copy_from_user(kaddr+offset, buf, bytes);
kunmap(page);
if (status)
@@ -684,9 +887,6 @@ shmem_file_write(struct file *file,const char *buf,size_t count,loff_t *ppos)
buf += bytes;
if (pos > inode->i_size)
inode->i_size = pos;
- if (inode->u.shmem_i.max_index <= index)
- inode->u.shmem_i.max_index = index+1;
-
}
unlock:
/* Mark it unlocked again and drop the page.. */
@@ -792,14 +992,16 @@ static ssize_t shmem_file_read(struct file * filp, char * buf, size_t count, lof
static int shmem_statfs(struct super_block *sb, struct statfs *buf)
{
+ struct shmem_sb_info *sbinfo = SHMEM_SB(sb);
+
buf->f_type = TMPFS_MAGIC;
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);
buf->f_namelen = 255;
return 0;
}
@@ -945,33 +1147,54 @@ static int shmem_symlink(struct inode * dir, struct dentry *dentry, const char *
struct inode *inode;
struct page *page;
char *kaddr;
+ struct shmem_inode_info * info;
error = shmem_mknod(dir, dentry, S_IFLNK | S_IRWXUGO, 0);
if (error)
return error;
- len = strlen(symname);
- if (len > PAGE_SIZE)
+ len = strlen(symname) + 1;
+ if (len > PAGE_CACHE_SIZE)
return -ENAMETOOLONG;
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);
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;
+ }
dir->i_ctime = dir->i_mtime = CURRENT_TIME;
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));
}
static int shmem_readlink(struct dentry *dentry, char *buffer, int buflen)
@@ -1001,6 +1224,17 @@ static int shmem_follow_link(struct dentry *dentry, struct nameidata *nd)
return res;
}
+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,
+};
+
static int shmem_parse_options(char *options, int *mode, unsigned long * blocks, unsigned long *inodes)
{
char *this_char, *value;
@@ -1046,13 +1280,13 @@ static int shmem_parse_options(char *options, int *mode, unsigned long * blocks,
static int shmem_remount_fs (struct super_block *sb, int *flags, char *data)
{
- 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;
if (shmem_parse_options (data, NULL, &max_blocks, &max_inodes))
return -EINVAL;
- return shmem_set_size(info, max_blocks, max_inodes);
+ return shmem_set_size(sbinfo, max_blocks, max_inodes);
}
int shmem_sync_file(struct file * file, struct dentry *dentry, int datasync)
@@ -1067,6 +1301,7 @@ static struct super_block *shmem_read_super(struct super_block * sb, void * data
struct dentry * root;
unsigned long blocks, inodes;
int mode = S_IRWXUGO | S_ISVTX;
+ struct shmem_sb_info *sbinfo = SHMEM_SB(sb);
struct sysinfo si;
/*
@@ -1083,12 +1318,12 @@ static struct super_block *shmem_read_super(struct super_block * sb, void * data
}
#endif
- 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;
sb->s_blocksize = PAGE_CACHE_SIZE;
sb->s_blocksize_bits = PAGE_CACHE_SHIFT;
sb->s_magic = TMPFS_MAGIC;
@@ -1109,7 +1344,7 @@ static struct super_block *shmem_read_super(struct super_block * sb, void * data
static struct address_space_operations shmem_aops = {
- writepage: shmem_writepage
+ writepage: shmem_writepage,
};
static struct file_operations shmem_file_operations = {
@@ -1125,14 +1360,6 @@ static struct inode_operations shmem_inode_operations = {
truncate: shmem_truncate,
};
-static struct inode_operations shmem_symlink_inode_operations = {
- truncate: shmem_truncate,
-#ifdef CONFIG_TMPFS
- readlink: shmem_readlink,
- follow_link: shmem_follow_link,
-#endif
-};
-
static struct file_operations shmem_dir_operations = {
read: generic_read_dir,
readdir: dcache_readdir,
@@ -1202,7 +1429,7 @@ static int __init init_shmem_fs(void)
shm_mnt = res;
/* 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)))
printk (KERN_ERR "could not set limits on internal tmpfs\n");
return 0;
@@ -1220,73 +1447,6 @@ static void __exit exit_shmem_fs(void)
module_init(init_shmem_fs)
module_exit(exit_shmem_fs)
-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);
-}
-
-
/*
* shmem_file_setup - get an unlinked file living in shmem fs
*
@@ -1306,7 +1466,7 @@ struct file *shmem_file_setup(char * name, loff_t size)
if (size > (unsigned long long) SHMEM_MAX_BLOCKS << PAGE_CACHE_SHIFT)
return ERR_PTR(-EINVAL);
- if (!vm_enough_memory((size) >> PAGE_SHIFT))
+ if (!vm_enough_memory((size) >> PAGE_CACHE_SHIFT))
return ERR_PTR(-ENOMEM);
this.name = name;
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
index 21c7328091e4..a761ccb03492 100644
--- a/net/ipv4/tcp.c
+++ b/net/ipv4/tcp.c
@@ -5,7 +5,7 @@
*
* Implementation of the Transmission Control Protocol(TCP).
*
- * 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 $
*
* Authors: Ross Biro, <bir7@leland.Stanford.Edu>
* Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
@@ -852,7 +852,7 @@ ssize_t do_tcp_sendpages(struct sock *sk, struct page **pages, int poffset, size
page = pages[poffset/PAGE_SIZE];
offset = poffset % PAGE_SIZE;
- size = min(psize, PAGE_SIZE-offset);
+ size = min_t(size_t, psize, PAGE_SIZE-offset);
if (tp->send_head==NULL || (copy = mss_now - skb->len) <= 0) {
new_segment: