From 02947070b658af5e0d8abdc7ad8486423a143553 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Mon, 4 Feb 2002 18:16:22 -0800 Subject: [PATCH] v2.4.4.2 -> v2.4.4.3 - Al Viro: sanity-check user arguments, zero-terminated strings etc. - Urban Widmark: smbfs update (server/client cache coherency etc) - Rik van Riel, Marcelo Tosatti: VM updates - Cort Dougan: PPC updates - Neil Brown: raid1/5 failed drive fixups, NULL ptr checking, md error cleanup - Neil Brown: knfsd fix for 64-bit architectures, and filehandle resolveir - Ken Brownfield: workaround for menuconfig CPU selection glitch - David Miller: sparc64 MM setup fix, arpfilter forward port - Keith Owens: Remove obsolete IPv6 provider based addressing - Jari Ruusu: block_write error case cleanup fix - Jeff Garzik: netdriver update --- CREDITS | 9 +- Documentation/Configure.help | 28 +- Documentation/networking/cops.txt | 2 +- Documentation/networking/ethertap.txt | 2 +- Documentation/networking/filter.txt | 2 +- Documentation/networking/ip-sysctl.txt | 115 +- Documentation/networking/ipddp.txt | 4 +- Documentation/networking/smctr.txt | 4 +- Documentation/networking/tms380tr.txt | 2 +- MAINTAINERS | 16 +- Makefile | 4 +- arch/arm/def-configs/ebsa110 | 2 - arch/i386/config.in | 2 +- arch/i386/defconfig | 1 + arch/i386/kernel/i386_ksyms.c | 1 + arch/i386/kernel/pci-irq.c | 6 +- arch/ppc/8xx_io/Config.in | 10 +- arch/ppc/8xx_io/uart.c | 16 +- arch/ppc/Makefile | 5 +- arch/ppc/boot/Makefile | 52 +- arch/ppc/boot/mksimage.c | 124 ++ arch/ppc/boot/sioffset | 4 + arch/ppc/boot/sisize | 4 + arch/ppc/coffboot/chrpmain.c | 12 +- arch/ppc/coffboot/start.c | 19 + arch/ppc/config.in | 6 +- arch/ppc/configs/IVMS8_defconfig | 67 +- arch/ppc/configs/SM850_defconfig | 69 +- arch/ppc/configs/SPD823TS_defconfig | 70 +- arch/ppc/configs/TQM823L_defconfig | 70 +- arch/ppc/configs/TQM850L_defconfig | 70 +- arch/ppc/configs/TQM860L_defconfig | 70 +- arch/ppc/configs/apus_defconfig | 23 +- arch/ppc/configs/bseip_defconfig | 24 +- arch/ppc/configs/common_defconfig | 38 +- arch/ppc/configs/est8260_defconfig | 8 +- arch/ppc/configs/gemini_defconfig | 510 +++++++ arch/ppc/configs/ibmchrp_defconfig | 51 +- arch/ppc/configs/mbx_defconfig | 25 +- arch/ppc/configs/oak_defconfig | 8 +- arch/ppc/configs/power3_defconfig | 52 +- arch/ppc/configs/rpxcllf_defconfig | 26 +- arch/ppc/configs/rpxlite_defconfig | 21 +- arch/ppc/configs/walnut_defconfig | 8 +- arch/ppc/defconfig | 36 +- arch/ppc/kernel/Makefile | 14 +- arch/ppc/kernel/apus_setup.c | 64 +- arch/ppc/kernel/bitops.c | 48 +- arch/ppc/kernel/chrp_pci.c | 89 +- arch/ppc/kernel/chrp_setup.c | 82 +- arch/ppc/kernel/chrp_time.c | 4 + arch/ppc/kernel/entry.S | 39 +- arch/ppc/kernel/feature.c | 646 +++++++-- arch/ppc/kernel/gemini_pci.c | 121 ++ arch/ppc/kernel/gemini_prom.S | 96 ++ arch/ppc/kernel/gemini_setup.c | 537 +++++++ arch/ppc/kernel/hashtable.S | 6 - arch/ppc/kernel/head.S | 94 +- arch/ppc/kernel/head_8xx.S | 9 +- arch/ppc/kernel/idle.c | 1 + arch/ppc/kernel/irq.c | 82 +- arch/ppc/kernel/m8260_setup.c | 29 +- arch/ppc/kernel/m8xx_setup.c | 34 +- arch/ppc/kernel/misc.S | 157 ++- arch/ppc/kernel/mol.h | 68 - arch/ppc/kernel/open_pic.c | 10 +- arch/ppc/kernel/pci.c | 99 +- arch/ppc/kernel/pmac_pci.c | 84 +- arch/ppc/kernel/pmac_pic.c | 8 +- arch/ppc/kernel/pmac_setup.c | 91 +- arch/ppc/kernel/ppc8260_pic.h | 3 +- arch/ppc/kernel/ppc8xx_pic.c | 13 +- arch/ppc/kernel/ppc8xx_pic.h | 3 +- arch/ppc/kernel/ppc_asm.h | 19 + arch/ppc/kernel/ppc_ksyms.c | 36 +- arch/ppc/kernel/prep_pci.c | 4 +- arch/ppc/kernel/prep_setup.c | 44 +- arch/ppc/kernel/prep_time.c | 7 +- arch/ppc/kernel/process.c | 40 - arch/ppc/kernel/prom.c | 78 +- arch/ppc/kernel/semaphore.c | 195 ++- arch/ppc/kernel/setup.c | 18 +- arch/ppc/kernel/sleep.S | 2 +- arch/ppc/kernel/smp.c | 116 +- arch/ppc/kernel/syscalls.c | 30 +- arch/ppc/kernel/time.c | 23 +- arch/ppc/lib/Makefile | 3 +- arch/ppc/mm/init.c | 379 +---- arch/ppc/xmon/start.c | 49 +- arch/ppc/xmon/start_8xx.c | 2 +- arch/ppc/xmon/xmon.c | 8 +- arch/sparc/defconfig | 1 - arch/sparc64/config.in | 11 +- arch/sparc64/defconfig | 27 +- arch/sparc64/kernel/Makefile | 4 +- arch/sparc64/kernel/ioctl32.c | 33 +- arch/sparc64/kernel/isa.c | 269 ++++ arch/sparc64/kernel/pci.c | 147 +- arch/sparc64/kernel/pci_common.c | 30 +- arch/sparc64/kernel/pci_impl.h | 3 +- arch/sparc64/kernel/pci_psycho.c | 17 +- arch/sparc64/kernel/pci_sabre.c | 33 +- arch/sparc64/kernel/pci_schizo.c | 17 +- arch/sparc64/kernel/sparc64_ksyms.c | 4 +- arch/sparc64/mm/init.c | 14 +- drivers/Makefile | 2 +- drivers/atm/eni.c | 1 + drivers/block/genhd.c | 6 - drivers/char/Makefile | 2 +- drivers/char/agp/agpgart_fe.c | 3 + drivers/char/mem.c | 2 + drivers/char/moxa.c | 24 +- drivers/char/mxser.c | 63 +- drivers/char/riscom8.c | 64 +- drivers/char/serial167.c | 70 +- drivers/char/specialix.c | 63 +- drivers/md/md.c | 6 +- drivers/md/raid1.c | 95 +- drivers/md/raid5.c | 97 +- drivers/net/8390.c | 2 + drivers/net/Config.in | 4 + drivers/net/Makefile | 1 + drivers/net/appletalk/cops.c | 4 +- drivers/net/appletalk/cops.h | 2 +- drivers/net/appletalk/cops_ffdrv.h | 2 +- drivers/net/appletalk/cops_ltdrv.h | 2 +- drivers/net/appletalk/ipddp.c | 6 +- drivers/net/bmac.c | 139 +- drivers/net/fealnx.c | 1777 ++++++++++++++++++++++++ drivers/net/gmac.c | 312 ++++- drivers/net/gmac.h | 20 +- drivers/net/hp100.h | 382 +++-- drivers/net/ioc3-eth.c | 10 +- drivers/net/mace.c | 24 +- drivers/net/natsemi.c | 2 + drivers/net/net_init.c | 5 +- drivers/net/pppoe.c | 21 +- drivers/net/sunhme.c | 14 +- drivers/net/tokenring/ibmtr.h | 454 ------ drivers/net/tokenring/smctr.c | 6 +- drivers/net/tokenring/smctr.h | 2 +- drivers/net/tokenring/smctr_firmware.h | 2 +- drivers/net/tokenring/tms380tr.c | 2 +- drivers/net/tulip/21142.c | 36 +- drivers/net/tulip/ChangeLog | 162 ++- drivers/net/tulip/eeprom.c | 5 +- drivers/net/tulip/media.c | 189 ++- drivers/net/tulip/pnic.c | 60 +- drivers/net/tulip/tulip.h | 48 +- drivers/net/tulip/tulip_core.c | 295 ++-- drivers/net/wan/comx-hw-comx.c | 11 +- drivers/net/wan/comx.c | 11 +- drivers/net/yellowfin.c | 25 +- drivers/parport/init.c | 2 + drivers/pci/pci.c | 11 +- drivers/pci/proc.c | 102 +- drivers/pci/quirks.c | 30 + drivers/pci/setup-res.c | 3 +- drivers/s390/block/dasd.c | 2 +- drivers/sbus/char/aurora.c | 64 +- drivers/sbus/char/pcikbd.c | 70 +- drivers/sbus/char/su.c | 23 +- drivers/sbus/char/zs.c | 63 +- drivers/scsi/scsi.c | 5 + drivers/scsi/scsi_proc.c | 1 + drivers/sound/trident.c | 58 +- drivers/sound/ymfpci.h | 2 + drivers/telephony/ixj.c | 3 +- drivers/usb/usb-uhci-debug.h | 21 +- drivers/usb/usb-uhci.c | 384 ++--- drivers/usb/usb-uhci.h | 9 +- drivers/video/aty.h | 1 + drivers/video/atyfb.c | 94 +- fs/block_dev.c | 34 +- fs/ext2/super.c | 3 - fs/nfsd/nfsctl.c | 4 +- fs/nfsd/nfsfh.c | 5 + fs/reiserfs/prints.c | 2 - fs/select.c | 5 +- fs/smbfs/ChangeLog | 25 + fs/smbfs/dir.c | 14 +- fs/smbfs/file.c | 30 +- fs/smbfs/inode.c | 66 +- fs/smbfs/ioctl.c | 7 +- fs/smbfs/proc.c | 113 +- fs/smbfs/sock.c | 4 +- fs/super.c | 41 +- fs/ufs/super.c | 3 - include/asm-alpha/pci.h | 11 + include/asm-arm/pci.h | 3 + include/asm-i386/pci.h | 6 + include/asm-ia64/pci.h | 3 + include/asm-m68k/pci.h | 3 + include/asm-mips/pci.h | 3 + include/asm-mips64/pci.h | 3 + include/asm-parisc/pci.h | 3 + include/asm-ppc/atomic.h | 22 + include/asm-ppc/bitops.h | 48 +- include/asm-ppc/bseip.h | 2 + include/asm-ppc/checksum.h | 8 +- include/asm-ppc/elf.h | 37 +- include/asm-ppc/fads.h | 47 +- include/asm-ppc/feature.h | 17 +- include/asm-ppc/gemini.h | 168 +++ include/asm-ppc/gemini_serial.h | 41 + include/asm-ppc/heathrow.h | 11 +- include/asm-ppc/hw_irq.h | 25 +- include/asm-ppc/ide.h | 7 +- include/asm-ppc/keylargo.h | 73 +- include/asm-ppc/machdep.h | 7 +- include/asm-ppc/mbx.h | 10 +- include/asm-ppc/mmu_context.h | 16 + include/asm-ppc/mpc8xx.h | 4 + include/asm-ppc/oak.h | 5 + include/asm-ppc/pci-bridge.h | 5 + include/asm-ppc/pci.h | 3 + include/asm-ppc/pgtable.h | 10 +- include/asm-ppc/ppc4xx.h | 282 ++++ include/asm-ppc/ppc4xx_serial.h | 101 ++ include/asm-ppc/processor.h | 164 +-- include/asm-ppc/prom.h | 13 +- include/asm-ppc/rpxclassic.h | 27 +- include/asm-ppc/rpxhiox.h | 42 + include/asm-ppc/rpxlite.h | 26 +- include/asm-ppc/rwsem.h | 134 ++ include/asm-ppc/semaphore-helper.h | 109 -- include/asm-ppc/semaphore.h | 72 +- include/asm-ppc/serial.h | 7 + include/asm-ppc/smp.h | 12 +- include/asm-ppc/system.h | 21 +- include/asm-ppc/time.h | 20 +- include/asm-ppc/uninorth.h | 12 +- include/asm-ppc/walnut.h | 42 +- include/asm-sh/pci.h | 3 +- include/asm-sparc/pci.h | 3 + include/asm-sparc64/floppy.h | 94 +- include/asm-sparc64/isa.h | 47 + include/asm-sparc64/parport.h | 42 +- include/asm-sparc64/pbm.h | 5 +- include/asm-sparc64/pci.h | 17 + include/linux/fs.h | 4 +- include/linux/inetdevice.h | 3 + include/linux/locks.h | 19 +- include/linux/mii.h | 181 +++ include/linux/nfsd/nfsfh.h | 4 +- include/linux/pci.h | 13 + include/linux/pci_ids.h | 4 + include/linux/raid/md.h | 2 +- include/linux/raid/md_k.h | 36 +- include/linux/smb.h | 17 +- include/linux/smb_fs.h | 34 +- include/linux/smb_fs_i.h | 1 - include/linux/smb_fs_sb.h | 13 + include/linux/sysctl.h | 3 +- include/net/addrconf.h | 12 +- include/net/snmp.h | 3 +- kernel/ksyms.c | 2 +- mm/filemap.c | 45 +- mm/slab.c | 3 +- mm/vmscan.c | 123 +- net/README | 5 +- net/atm/mpoa_proc.c | 2 +- net/core/dev.c | 2 +- net/core/filter.c | 9 +- net/ipv4/arp.c | 25 +- net/ipv4/devinet.c | 7 +- net/ipv4/fib_frontend.c | 14 +- net/ipv4/icmp.c | 3 +- net/ipv4/ip_gre.c | 1 + net/ipv4/ipip.c | 1 + net/ipv4/netfilter/ip_nat_core.c | 5 +- net/ipv4/netfilter/ip_tables.c | 1 + net/ipv4/proc.c | 4 +- net/ipv4/raw.c | 220 +-- net/ipv4/route.c | 895 +++++++----- net/ipv4/syncookies.c | 90 +- net/ipv4/tcp.c | 4 +- net/ipv4/tcp_input.c | 8 +- net/ipv6/Config.in | 4 - net/ipv6/addrconf.c | 51 +- net/ipv6/ndisc.c | 162 ++- net/ipv6/netfilter/ip6_tables.c | 1 + net/ipv6/route.c | 9 +- net/ipv6/sit.c | 1 + net/ipx/af_ipx.c | 744 +++++----- net/ipx/af_spx.c | 2 +- net/ipx/sysctl_net_ipx.c | 15 +- 287 files changed, 11634 insertions(+), 4800 deletions(-) create mode 100644 arch/ppc/boot/mksimage.c create mode 100644 arch/ppc/boot/sioffset create mode 100644 arch/ppc/boot/sisize create mode 100644 arch/ppc/configs/gemini_defconfig create mode 100644 arch/ppc/kernel/gemini_pci.c create mode 100644 arch/ppc/kernel/gemini_prom.S create mode 100644 arch/ppc/kernel/gemini_setup.c delete mode 100644 arch/ppc/kernel/mol.h create mode 100644 arch/sparc64/kernel/isa.c create mode 100644 drivers/net/fealnx.c delete mode 100644 drivers/net/tokenring/ibmtr.h create mode 100644 include/asm-ppc/gemini.h create mode 100644 include/asm-ppc/gemini_serial.h create mode 100644 include/asm-ppc/ppc4xx.h create mode 100644 include/asm-ppc/ppc4xx_serial.h create mode 100644 include/asm-ppc/rpxhiox.h create mode 100644 include/asm-ppc/rwsem.h delete mode 100644 include/asm-ppc/semaphore-helper.h create mode 100644 include/asm-sparc64/isa.h create mode 100644 include/linux/mii.h diff --git a/CREDITS b/CREDITS index b222fe09a466..87d67b894e61 100644 --- a/CREDITS +++ b/CREDITS @@ -1869,10 +1869,13 @@ S: Germany N: Arnaldo Carvalho de Melo E: acme@conectiva.com.br -W: http://www.conectiva.com.br/~acme +E: acme@gnu.org +W: http://bazar.conectiva.com.br/~acme +W: http://advogato.org/person/acme +P: 1024D/9224DF01 D5DF E3BB E3C8 BCBB F8AD 841A B6AB 4681 9224 DF01 D: wanrouter hacking -D: USB hacking -D: miscellaneous Makefile & Config.in fixes +D: misc Makefile, Config.in, drivers and network stacks fixes +D: IPX Maintainer D: Cyclom 2X synchronous card driver D: i18n for minicom, net-tools, util-linux, fetchmail, etc S: Conectiva S.A. diff --git a/Documentation/Configure.help b/Documentation/Configure.help index 6fa1ac125a0c..7b5fb726e92a 100644 --- a/Documentation/Configure.help +++ b/Documentation/Configure.help @@ -4170,22 +4170,6 @@ CONFIG_IPV6 It is safe to say N here for now. -IPv6: enable EUI-64 token format -CONFIG_IPV6_EUI64 - 6bone, the network of computers using the IPv6 protocol, is moving - to a new aggregatable address format and a new link local address - assignment (EUI-64). Say Y if your site has upgraded already, or - has started to upgrade. - -IPv6: disable provider based addresses -CONFIG_IPV6_NO_PB - Linux tries to operate correctly when your site has moved to EUI-64 - only partially. Unfortunately, the two address formats (old: - "provider based" and new: "aggregatable") are incompatible. Say Y if - your site finished the upgrade to EUI-64, and/or you encountered - some problems caused by the presence of two link-local addresses on - an interface. - IPv6: routing messages via old netlink CONFIG_IPV6_NETLINK You can say Y here to receive routing messages from the IPv6 code @@ -7188,7 +7172,7 @@ CONFIG_PPPOE This driver requires a specially patched pppd daemon. The patch to pppd, along with binaries of a patched pppd package can be found at: - http://www.math.uwaterloo.ca/~mostrows + http://www.shoshin.uwaterloo.ca/~mostrows Wireless LAN (non-hamradio) CONFIG_NET_RADIO @@ -12081,10 +12065,7 @@ CONFIG_SMB_NLS_DEFAULT The nls settings can be changed at mount time, if your smbmount supports that, using the codepage and iocharset parameters. - Currently no smbmount distributed with samba supports this, it is - assumed future versions will. In the meantime you can get an - unofficial patch for samba 2.0.7 from: - http://www.hojdpunkten.ac.se/054/samba/index.html + smbmount from samba 2.2.0 or later supports this. nls support setting CONFIG_SMB_NLS_REMOTE @@ -12096,10 +12077,7 @@ CONFIG_SMB_NLS_REMOTE The nls settings can be changed at mount time, if your smbmount supports that, using the codepage and iocharset parameters. - Currently no smbmount distributed with samba supports this, it is - assumed future versions will. In the meantime you can get an - unofficial patch for samba 2.0.7 from: - http://www.hojdpunkten.ac.se/054/samba/index.html + smbmount from samba 2.2.0 or later supports this. Coda file system support (advanced network fs) CONFIG_CODA_FS diff --git a/Documentation/networking/cops.txt b/Documentation/networking/cops.txt index b7e06c55fc5f..3e344b448e07 100644 --- a/Documentation/networking/cops.txt +++ b/Documentation/networking/cops.txt @@ -1,5 +1,5 @@ Text File for the COPS LocalTalk Linux driver (cops.c). - By Jay Schulist + By Jay Schulist This driver has two modes and they are: Dayna mode and Tangent mode. Each mode corresponds with the type of card. It has been found diff --git a/Documentation/networking/ethertap.txt b/Documentation/networking/ethertap.txt index ba37dd3db10b..7f3b52955a0b 100644 --- a/Documentation/networking/ethertap.txt +++ b/Documentation/networking/ethertap.txt @@ -7,7 +7,7 @@ NOTE: Ethertap is now an obsolete facility, and is scheduled Ethertap programming mini-HOWTO ------------------------------- -The ethertap driver was written by Jay Schulist , +The ethertap driver was written by Jay Schulist , you should contact him for further information. This document was written by bert hubert . Updates are welcome. diff --git a/Documentation/networking/filter.txt b/Documentation/networking/filter.txt index 76ee08458934..bbf2005270b5 100644 --- a/Documentation/networking/filter.txt +++ b/Documentation/networking/filter.txt @@ -1,5 +1,5 @@ filter.txt: Linux Socket Filtering -Written by: Jay Schulist +Written by: Jay Schulist Introduction ============ diff --git a/Documentation/networking/ip-sysctl.txt b/Documentation/networking/ip-sysctl.txt index ae171c4b3642..9d5454939b7c 100644 --- a/Documentation/networking/ip-sysctl.txt +++ b/Documentation/networking/ip-sysctl.txt @@ -398,4 +398,117 @@ kuznet@ms2.inr.ac.ru Updated by: Andi Kleen ak@muc.de -$Id: ip-sysctl.txt,v 1.18 2001/03/16 06:49:20 davem Exp $ + + + + + + +/proc/sys/net/ipv6/* Variables: + +IPv6 has no global variables such as tcp_*. tcp_* settings under ipv4/ also +apply to IPv6 [XXX?]. + +conf/default/*: + Change the interface-specific default settings. + + +conf/all/*: + Change all the interface-specific settings. + + [XXX: Other special features than forwarding?] + +conf/all/forwarding - BOOLEAN + Enable global IPv6 forwarding between all interfaces. + + IPv4 and IPv6 work differently here; e.g. netfilter must be used + to control which interfaces may forward packets and which not. + + This also sets all interfaces' Host/Router setting + 'forwarding' to the specified value. See below for details. + + This referred to as global forwarding. + +conf/interface/*: + Change special settings per interface. + + The functional behaviour for certain settings is different + depending on whether local forwarding is enabled or not. + +accept_ra - BOOLEAN + Accept Router Advertisements; autoconfigure using them. + + Functional default: enabled if local forwarding is disabled. + disabled if local forwarding is enabled. + +accept_redirects - BOOLEAN + Accept Redirects. + + Functional default: enabled if local forwarding is disabled. + disabled if local forwarding is enabled. + +autoconf - BOOLEAN + Configure link-local addresses using L2 hardware addresses. + + Default: TRUE + +dad_transmits - INTEGER + The amount of Duplicate Address Detection probes to send. + Default: 1 + +forwarding - BOOLEAN + Configure interface-specific Host/Router behaviour. + + Note: It is recommended to have the same setting on all + interfaces; mixed router/host scenarios are rather uncommon. + + FALSE: + + By default, Host behaviour is assumed. This means: + + 1. IsRouter flag is not set in Neighbour Advertisements. + 2. Router Solicitations are being sent when necessary. + 3. If accept_ra is TRUE (default), accept Router + Advertisements (and do autoconfiguration). + 4. If accept_redirects is TRUE (default), accept Redirects. + + TRUE: + + If local forwarding is enabled, Router behaviour is assumed. + This means exactly the reverse from the above: + + 1. IsRouter flag is set in Neighbour Advertisements. + 2. Router Solicitations are not sent. + 3. Router Advertisements are ignored. + 4. Redirects are ignored. + + Default: FALSE if global forwarding is disabled (default), + otherwise TRUE. + +hop_limit - INTEGER + Default Hop Limit to set. + Default: 64 + +mtu - INTEGER + Default Maximum Transfer Unit + Default: 1280 (IPv6 required minimum) + +router_solicitation_delay - INTEGER + Number of seconds to wait after interface is brought up + before sending Router Solicitations. + Default: 1 + +router_solicitation_interval - INTEGER + Number of seconds to wait between Router Solicitations. + Default: 4 + +router_solicitations - INTEGER + Number of Router Solicitations to send until assuming no + routers are present. + Default: 3 + +IPv6 Update by: +Pekka Savola +pekkas@netcore.fi + +$Id: ip-sysctl.txt,v 1.19 2001/05/16 17:11:04 davem Exp $ diff --git a/Documentation/networking/ipddp.txt b/Documentation/networking/ipddp.txt index 5fb6c3c744e8..661a5558dd8e 100644 --- a/Documentation/networking/ipddp.txt +++ b/Documentation/networking/ipddp.txt @@ -1,7 +1,7 @@ Text file for ipddp.c: AppleTalk-IP Decapsulation and AppleTalk-IP Encapsulation -This text file is written by Jay Schulist +This text file is written by Jay Schulist Introduction ------------ @@ -72,7 +72,7 @@ EtherTalk only network. Further Assistance ------------------- -You can contact me (Jay Schulist ) with any +You can contact me (Jay Schulist ) with any questions regarding decapsulation or encapsulation. Bradford W. Johnson originally wrote the ipddp.c driver for IP encapsulation in AppleTalk. diff --git a/Documentation/networking/smctr.txt b/Documentation/networking/smctr.txt index a393133a403a..4c866f5a0ee4 100644 --- a/Documentation/networking/smctr.txt +++ b/Documentation/networking/smctr.txt @@ -1,5 +1,5 @@ Text File for the SMC TokenCard TokenRing Linux driver (smctr.c). - By Jay Schulist + By Jay Schulist The Linux SMC Token Ring driver works with the SMC TokenCard Elite (8115T) ISA and SMC TokenCard Elite/A (8115T/A) MCA adapters. @@ -22,7 +22,7 @@ Load the driver either by lilo/loadlin or as a module. When a module using the following command will suffice for most: # modprobe smctr -smctr.c: v1.00 12/6/99 by jschlst@turbolinux.com +smctr.c: v1.00 12/6/99 by jschlst@samba.org tr0: SMC TokenCard 8115T at Io 0x300, Irq 10, Rom 0xd8000, Ram 0xcc000. Now just setup the device via ifconfig and set and routes you may have. After diff --git a/Documentation/networking/tms380tr.txt b/Documentation/networking/tms380tr.txt index 7ae835331fb5..179e527b9da1 100644 --- a/Documentation/networking/tms380tr.txt +++ b/Documentation/networking/tms380tr.txt @@ -1,5 +1,5 @@ Text file for the Linux SysKonnect Token Ring ISA/PCI Adapter Driver. - Text file by: Jay Schulist + Text file by: Jay Schulist The Linux SysKonnect Token Ring driver works with the SysKonnect TR4/16(+) ISA, SysKonnect TR4/16(+) PCI, SysKonnect TR4/16 PCI, and older revisions of the diff --git a/MAINTAINERS b/MAINTAINERS index a2af486874f3..119a34ae227e 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -160,7 +160,7 @@ S: Supported APPLETALK NETWORK LAYER P: Jay Schulist -M: jschlst@turbolinux.com +M: jschlst@samba.org L: linux-atalk@lists.netspace.org S: Maintained @@ -682,9 +682,9 @@ P: Juanjo Ciarlante M: jjciarla@raiz.uncu.edu.ar S: Maintained -IPX/SPX NETWORK LAYER -P: Jay Schulist -M: jschlst@turbolinux.com +IPX NETWORK LAYER +P: Arnaldo Carvalho de Melo +M: acme@conectiva.com.br L: linux-net@vger.kernel.org S: Maintained @@ -931,6 +931,8 @@ P: Andi Kleen M: ak@muc.de P: Alexey Kuznetsov M: kuznet@ms2.inr.ac.ru +P: Pekka Savola (ipv6) +M: pekkas@netcore.fi L: netdev@oss.sgi.com S: Maintained @@ -1175,7 +1177,7 @@ S: Supported SMB FILESYSTEM P: Urban Widmark -M: urban@svenskatest.se +M: urban@teststation.com W: http://samba.org/ L: samba@samba.org S: Maintained @@ -1226,13 +1228,13 @@ S: Supported SPX NETWORK LAYER P: Jay Schulist -M: jschlst@turbolinux.com +M: jschlst@samba.org L: linux-net@vger.kernel.org S: Supported SNA NETWORK LAYER P: Jay Schulist -M: jschlst@turbolinux.com +M: jschlst@samba.org L: linux-sna@turbolinux.com W: http://www.linux-sna.org S: Supported diff --git a/Makefile b/Makefile index f40648b04a72..e2941e21bfae 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ VERSION = 2 PATCHLEVEL = 4 SUBLEVEL = 5 -EXTRAVERSION =-pre2 +EXTRAVERSION =-pre3 KERNELRELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION) @@ -415,7 +415,7 @@ mrproper: clean archmrproper distclean: mrproper rm -f core `find . \( -name '*.orig' -o -name '*.rej' -o -name '*~' \ -o -name '*.bak' -o -name '#*#' -o -name '.*.orig' \ - -o -name '.*.rej' -o -name '.SUMS' -o -size 0 \) -print` TAGS tags + -o -name '.*.rej' -o -name '.SUMS' -o -size 0 \) -type f -print` TAGS tags backup: mrproper cd .. && tar cf - linux/ | gzip -9 > backup.gz diff --git a/arch/arm/def-configs/ebsa110 b/arch/arm/def-configs/ebsa110 index 8f7981934bc6..4a5cd45f0f6a 100644 --- a/arch/arm/def-configs/ebsa110 +++ b/arch/arm/def-configs/ebsa110 @@ -192,8 +192,6 @@ CONFIG_IP_NF_COMPAT_IPCHAINS=m CONFIG_IP_NF_NAT_NEEDED=y # CONFIG_IP_NF_COMPAT_IPFWADM is not set CONFIG_IPV6=m -CONFIG_IPV6_EUI64=y -# CONFIG_IPV6_NO_PB is not set # # IPv6: Netfilter Configuration diff --git a/arch/i386/config.in b/arch/i386/config.in index a6b167b17b31..dbc054855acd 100644 --- a/arch/i386/config.in +++ b/arch/i386/config.in @@ -33,7 +33,7 @@ choice 'Processor family' \ Pentium-Classic CONFIG_M586TSC \ Pentium-MMX CONFIG_M586MMX \ Pentium-Pro/Celeron/Pentium-II CONFIG_M686 \ - Pentium-III/Celeron(Coppermine) CONFIG_MPENTIUMIII \ + Pentium-III/Celeron-Coppermine CONFIG_MPENTIUMIII \ Pentium-4 CONFIG_MPENTIUM4 \ K6/K6-II/K6-III CONFIG_MK6 \ Athlon/Duron/K7 CONFIG_MK7 \ diff --git a/arch/i386/defconfig b/arch/i386/defconfig index 99c1d85c90f2..0a5be11b3d9d 100644 --- a/arch/i386/defconfig +++ b/arch/i386/defconfig @@ -382,6 +382,7 @@ CONFIG_NET_PCI=y CONFIG_EEPRO100=y # CONFIG_EEPRO100_PM is not set # CONFIG_LNE390 is not set +# CONFIG_FEALNX is not set # CONFIG_NATSEMI is not set # CONFIG_NE2K_PCI is not set # CONFIG_NE3210 is not set diff --git a/arch/i386/kernel/i386_ksyms.c b/arch/i386/kernel/i386_ksyms.c index 61ca1a1d4a80..4dbb196a9c1d 100644 --- a/arch/i386/kernel/i386_ksyms.c +++ b/arch/i386/kernel/i386_ksyms.c @@ -112,6 +112,7 @@ EXPORT_SYMBOL(pci_free_consistent); #ifdef CONFIG_PCI EXPORT_SYMBOL(pcibios_penalize_isa_irq); +EXPORT_SYMBOL(pci_mem_start); #endif #ifdef CONFIG_X86_USE_3DNOW diff --git a/arch/i386/kernel/pci-irq.c b/arch/i386/kernel/pci-irq.c index c22dda5e74b2..4f1ab622ead7 100644 --- a/arch/i386/kernel/pci-irq.c +++ b/arch/i386/kernel/pci-irq.c @@ -445,8 +445,12 @@ static void __init pirq_find_router(void) return; } #endif + + DBG("PCI: Attempting to find IRQ router for %04x:%04x\n", + rt->rtr_vendor, rt->rtr_device); + /* fall back to default router if nothing else found */ - pirq_router = pirq_routers + sizeof(pirq_routers) / sizeof(pirq_routers[0]) - 1; + pirq_router = &pirq_routers[ARRAY_SIZE(pirq_routers) - 1]; pirq_router_dev = pci_find_slot(rt->rtr_bus, rt->rtr_devfn); if (!pirq_router_dev) { diff --git a/arch/ppc/8xx_io/Config.in b/arch/ppc/8xx_io/Config.in index 7ca7892884d8..756dbe3235ed 100644 --- a/arch/ppc/8xx_io/Config.in +++ b/arch/ppc/8xx_io/Config.in @@ -18,12 +18,12 @@ if [ "$CONFIG_NET_ETHERNET" = "y" ]; then fi bool 'Use Big CPM Ethernet Buffers' CONFIG_ENET_BIG_BUFFERS fi -bool 'Use SMC2 for UART' CONFIG_8xxSMC2 -if [ "$CONFIG_8xxSMC2" = "y" ]; then - bool 'Use Alternate SMC2 I/O (823/850)' CONFIG_8xx_ALTSMC2 - bool 'Use SMC2 for Console' CONFIG_8xx_CONS_SMC2 +bool 'Use SMC2 for UART' CONFIG_SMC2_UART +if [ "$CONFIG_SMC2_UART" = "y" ]; then + bool 'Use Alternate SMC2 I/O (823/850)' CONFIG_ALTSMC2 + bool 'Use SMC2 for Console' CONFIG_CONS_SMC2 fi -bool 'Enable SCC2 and SCC3 for UART' CONFIG_8xxSCC +bool 'Enable SCC2 and SCC3 for UART' CONFIG_USE_SCC_IO # This doesn't really belong here, but it is convenient to ask # 8xx specific questions. diff --git a/arch/ppc/8xx_io/uart.c b/arch/ppc/8xx_io/uart.c index 1f426ae10ff5..41e47c597bb9 100644 --- a/arch/ppc/8xx_io/uart.c +++ b/arch/ppc/8xx_io/uart.c @@ -55,17 +55,17 @@ extern int kgdb_output_string (const char* s, unsigned int count); */ # ifndef CONFIG_SERIAL_CONSOLE_PORT # ifdef CONFIG_SCC3_ENET -# ifdef CONFIG_8xx_CONS_SMC2 +# ifdef CONFIG_CONS_SMC2 # define CONFIG_SERIAL_CONSOLE_PORT 0 /* Console on SMC2 is 1st port */ # else # error "Can't use SMC1 for console with Ethernet on SCC3" # endif # else /* ! CONFIG_SCC3_ENET */ -# ifdef CONFIG_8xx_CONS_SMC2 /* Console on SMC2 */ +# ifdef CONFIG_CONS_SMC2 /* Console on SMC2 */ # define CONFIG_SERIAL_CONSOLE_PORT 1 # else /* Console on SMC1 */ # define CONFIG_SERIAL_CONSOLE_PORT 0 -# endif /* CONFIG_8xx_CONS_SMC2 */ +# endif /* CONFIG_CONS_SMC2 */ # endif /* CONFIG_SCC3_ENET */ # endif /* CONFIG_SERIAL_CONSOLE_PORT */ #endif /* CONFIG_SERIAL_CONSOLE */ @@ -134,15 +134,15 @@ static struct serial_state rs_table[] = { { 0, 0, PROFF_SMC1, CPMVEC_SMC1, 0, 0 }, /* SMC1 ttyS0 */ #endif #if !defined(CONFIG_USB_MPC8xx) && !defined(CONFIG_USB_CLIENT_MPC8xx) -# ifdef CONFIG_8xxSMC2 +# ifdef CONFIG_SMC2_UART { 0, 0, PROFF_SMC2, CPMVEC_SMC2, 0, 1 }, /* SMC2 ttyS1 */ # endif -# ifdef CONFIG_8xxSCC +# ifdef CONFIG_USE_SCC_IO { 0, 0, PROFF_SCC2, CPMVEC_SCC2, 0, (NUM_IS_SCC | 1) }, /* SCC2 ttyS2 */ { 0, 0, PROFF_SCC3, CPMVEC_SCC3, 0, (NUM_IS_SCC | 2) }, /* SCC3 ttyS3 */ # endif #else /* CONFIG_USB_xxx */ -# ifdef CONFIG_8xxSCC +# ifdef CONFIG_USE_SCC_IO { 0, 0, PROFF_SCC3, CPMVEC_SCC3, 0, (NUM_IS_SCC | 2) }, /* SCC3 ttyS3 */ # endif #endif /* CONFIG_USB_xxx */ @@ -2533,7 +2533,7 @@ int __init rs_8xx_init(void) /* Configure SCC2, SCC3, and SCC4 instead of port A parallel I/O. */ -#ifdef CONFIG_8xxSCC +#ifdef CONFIG_USE_SCC_IO #ifndef CONFIG_MBX /* The "standard" configuration through the 860. */ @@ -2747,7 +2747,7 @@ int __init rs_8xx_init(void) * parallel I/O. On 823/850 these are on * port A for SMC2. */ -#ifndef CONFIG_8xx_ALTSMC2 +#ifndef CONFIG_ALTSMC2 iobits = 0xc0 << (idx * 4); cp->cp_pbpar |= iobits; cp->cp_pbdir &= ~iobits; diff --git a/arch/ppc/Makefile b/arch/ppc/Makefile index 488766003a16..01f625746f17 100644 --- a/arch/ppc/Makefile +++ b/arch/ppc/Makefile @@ -31,7 +31,7 @@ CFLAGS := $(CFLAGS) -mcpu=403 endif ifdef CONFIG_8xx -CFLAGS := $(CFLAGS) -mcpu=860 -I../8xx_io +CFLAGS := $(CFLAGS) -mcpu=860 endif ifdef CONFIG_PPC64BRIDGE @@ -145,6 +145,9 @@ endif clean_config: rm -f .config arch/ppc/defconfig +gemini_config: clean_config + cp -f arch/ppc/configs/gemini_defconfig arch/ppc/defconfig + pmac_config: clean_config cp -f arch/ppc/configs/pmac_defconfig arch/ppc/defconfig diff --git a/arch/ppc/boot/Makefile b/arch/ppc/boot/Makefile index 32c2926a141f..0ce99dc00d34 100644 --- a/arch/ppc/boot/Makefile +++ b/arch/ppc/boot/Makefile @@ -31,6 +31,12 @@ else TFTPIMAGE=/tftpboot/zImage.prep$(MSIZE) endif +ifeq ($(CONFIG_SMP),y) +TFTPSIMAGE=/tftpboot/sImage.smp +else +TFTPSIMAGE=/tftpboot/sImage +endif + ifeq ($(CONFIG_PPC64BRIDGE),y) MSIZE=.64 else @@ -70,8 +76,24 @@ zvmlinux.initrd: zvmlinux --add-section=image=../coffboot/vmlinux.gz \ zvmlinux.initrd.tmp $@ rm zvmlinux.initrd.tmp +ifdef CONFIG_GEMINI + $(LD) $(ZLINKFLAGS) -o zvmlinux.initrd.tmp $(OBJECTS) + $(OBJCOPY) -I elf32-powerpc -O binary zvmlinux.initrd.tmp svmlinux.initrd.tmp + ./mksimage svmlinux.initrd.tmp ../coffboot/vmlinux.gz ramdisk.image.gz \ + -o svmlinux.initrd > sImage.map + $(CC) $(CFLAGS) -DINITRD_OFFSET=`sh sioffset initrd` \ + -DINITRD_SIZE=`sh sisize initrd` \ + -DZIMAGE_OFFSET=`sh sioffset zimage` \ + -DZIMAGE_SIZE=`sh sisize zimage` \ + -c -o misc.o misc.c + $(LD) $(ZLINKFLAGS) -o zvmlinux.initrd.tmp $(OBJECTS) + $(OBJCOPY) -I elf32-powerpc -O binary zvmlinux.initrd.tmp svmlinux.initrd.tmp + ./mksimage svmlinux.initrd.tmp ../coffboot/vmlinux.gz ramdisk.image.gz \ + -o svmlinux.initrd > /dev/null + rm svmlinux.initrd.tmp zvmlinux.initrd.tmp sImage.map +endif -zImage: zvmlinux mkprep +zImage: zvmlinux mkprep sImage mksimage ifdef CONFIG_ALL_PPC ./mkprep -pbp zvmlinux zImage endif @@ -80,12 +102,17 @@ ifdef CONFIG_APUS gzip $(GZIP_FLAGS) vmapus endif +sImage: ../../../vmlinux +ifdef CONFIG_GEMINI + $(OBJCOPY) -I elf32-powerpc -O binary ../../../vmlinux sImage +endif + zImage.initrd: zvmlinux.initrd mkprep ifdef CONFIG_ALL_PPC ./mkprep -pbp zvmlinux.initrd zImage.initrd endif -zvmlinux: $(OBJECTS) ../coffboot/vmlinux.gz +zvmlinux: $(OBJECTS) ../coffboot/vmlinux.gz mksimage # # build the boot loader image and then compute the offset into it # for the kernel image @@ -105,6 +132,19 @@ zvmlinux: $(OBJECTS) ../coffboot/vmlinux.gz $(OBJCOPY) $(OBJCOPY_ARGS) -R .comment --add-section=image=../coffboot/vmlinux.gz \ zvmlinux.tmp $@ rm zvmlinux.tmp +ifdef CONFIG_GEMINI + $(LD) $(ZLINKFLAGS) -o zvmlinux.tmp $(OBJECTS) + $(OBJCOPY) -I elf32-powerpc -O binary zvmlinux.tmp svmlinux.tmp + ./mksimage svmlinux.tmp ../coffboot/vmlinux.gz -o svmlinux > sImage.map + $(CC) $(CFLAGS) -DINITRD_OFFSET=0 -DINITRD_SIZE=0 \ + -DZIMAGE_OFFSET=`sh sioffset zimage` \ + -DZIMAGE_SIZE=`sh sisize zimage` \ + -c -o misc.o misc.c + $(LD) $(ZLINKFLAGS) -o zvmlinux.tmp $(OBJECTS) + $(OBJCOPY) -I elf32-powerpc -O binary zvmlinux.tmp svmlinux.tmp + ./mksimage svmlinux.tmp ../coffboot/vmlinux.gz -o svmlinux > /dev/null + rm svmlinux.tmp sImage.map zvmlinux.tmp +endif floppy: $(TOPDIR)/vmlinux zImage dd if=zImage of=/dev/fd0H1440 bs=64b @@ -112,16 +152,22 @@ floppy: $(TOPDIR)/vmlinux zImage mkprep : mkprep.c $(HOSTCC) -o mkprep mkprep.c +mksimage: mksimage.c + $(HOSTCC) -o mksimage mksimage.c + znetboot : zImage ifdef CONFIG_ALL_PPC cp zImage $(TFTPIMAGE) endif +ifdef CONFIG_GEMINI + cp sImage $(TFTPSIMAGE) +endif znetboot.initrd : zImage.initrd cp zImage.initrd $(TFTPIMAGE) clean: - rm -f vmlinux* zvmlinux* mkprep zImage* + rm -f vmlinux* zvmlinux* mkprep zImage* sImage* mksimage fastdep: $(TOPDIR)/scripts/mkdep *.[Sch] > .depend diff --git a/arch/ppc/boot/mksimage.c b/arch/ppc/boot/mksimage.c new file mode 100644 index 000000000000..6caf70063db0 --- /dev/null +++ b/arch/ppc/boot/mksimage.c @@ -0,0 +1,124 @@ +/* + * + * + * + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include + + +#define SIZE 1024 +#define BLOCK_ALIGN(x) (((x)+SIZE-1)&(~(SIZE-1))) + +static void +die(const char *fmt, ...) +{ + va_list args; + va_start(args, fmt); + vfprintf(stderr, fmt, args); + fputc('\n', stderr); + exit(1); +} + +static void +usage(void) +{ + printf("Usage: mkbinimg -o \n"); + exit(1); +} + +static int +copy_blocks(int ifd, int ofd, unsigned long *offset, unsigned long *size) +{ + off_t cur; + int amt; + unsigned long len = 0; + char buffer[SIZE]; + + cur = lseek(ofd, 0, SEEK_CUR); + + if (cur % SIZE) { + cur = BLOCK_ALIGN(cur); + cur = lseek(ofd, cur, SEEK_SET); + } + + *offset = (unsigned long) cur; + while((amt = read(ifd, buffer, SIZE)) > 0) { + write(ofd, buffer, amt); + len += amt; + } + *size = len; + return 0; +} + + +int +main(int argc, char *argv[]) +{ + char *kernel, *loader, *rdimage = NULL; + unsigned long ld_off, kern_off, rd_off; + unsigned long ld_size, kern_size, rd_size; + int fd, ofd, len; + char buffer[500]; + + if (argc < 5 && !strcmp(argv[argc-2], "-o")) + usage(); + + if (argc > 5) + rdimage = argv[3]; + + kernel = argv[2]; + loader = argv[1]; + + ofd = open(argv[argc-1], (O_RDWR|O_CREAT), 0755); + if (ofd < 0) { + die("can't open %s: %s", argv[5], strerror(errno)); + } + + ld_off = kern_off = rd_off = 0; + ld_size = kern_size = rd_size = 0; + memset(buffer, 0, 500); + len = 0; + + fd = open(loader, O_RDONLY); + if (fd < 0) + die("can't open loader: %s", strerror(errno)); + + copy_blocks(fd, ofd, &ld_off, &ld_size); + len = sprintf(buffer, "bootloader: %x %x\n", ld_off, ld_size); + close(fd); + + fd = open(kernel, O_RDONLY); + if (fd < 0) + die("can't open kernel: %s", strerror(errno)); + + copy_blocks(fd, ofd, &kern_off, &kern_size); + len += sprintf(buffer+len, "zimage: %x %x\n", kern_off, kern_size); + close(fd); + + if (rdimage) { + fd = open(rdimage, O_RDONLY); + if (fd < 0) + die("can't get ramdisk: %s", strerror(errno)); + + copy_blocks(fd, ofd, &rd_off, &rd_size); + close(fd); + } + + len += sprintf(buffer+len, "initrd: %x %x", rd_off, rd_size); + + close(ofd); + + printf("%s\n", buffer); + + return 0; +} + diff --git a/arch/ppc/boot/sioffset b/arch/ppc/boot/sioffset new file mode 100644 index 000000000000..b5245be6c7b1 --- /dev/null +++ b/arch/ppc/boot/sioffset @@ -0,0 +1,4 @@ +#!/bin/bash + +OFFSET=`grep $1 sImage.map | awk '{print $2}'` +echo "0x"$OFFSET diff --git a/arch/ppc/boot/sisize b/arch/ppc/boot/sisize new file mode 100644 index 000000000000..7e8180125dd4 --- /dev/null +++ b/arch/ppc/boot/sisize @@ -0,0 +1,4 @@ +#!/bin/bash + +OFFSET=`grep $1 sImage.map | awk '{print $3}'` +echo "0x"$OFFSET diff --git a/arch/ppc/coffboot/chrpmain.c b/arch/ppc/coffboot/chrpmain.c index 08b238b16156..c2912bc61f84 100644 --- a/arch/ppc/coffboot/chrpmain.c +++ b/arch/ppc/coffboot/chrpmain.c @@ -14,6 +14,8 @@ extern void *finddevice(const char *); extern int getprop(void *, const char *, void *, int); +extern void *claim(unsigned int, unsigned int, unsigned int); +extern void release(void *ptr, unsigned int len); void make_bi_recs(unsigned long); void gunzip(void *, int, unsigned char *, int *); void stop_imac_ethernet(void); @@ -78,6 +80,7 @@ boot(int a1, int a2, void *prom) printf("done %u bytes\n", len); printf("%u bytes of heap consumed, max in use %u\n", avail_high - begin_avail, heap_max); + release(begin_avail, SCRATCH_SIZE); } else { memmove(dst, im, len); } @@ -98,8 +101,13 @@ boot(int a1, int a2, void *prom) void make_bi_recs(unsigned long addr) { struct bi_record *rec; - rec = (struct bi_record *)_ALIGN((unsigned long)addr+(1<<20)-1,(1<<20)); - + + /* leave a 1MB gap then align to the next 1MB boundary */ + addr = _ALIGN(addr+ (1<<20) - 1, (1<<20)); + if (addr >= PROG_START + PROG_SIZE) + claim(addr, 0x1000, 0); + + rec = (struct bi_record *)addr; rec->tag = BI_FIRST; rec->size = sizeof(struct bi_record); rec = (struct bi_record *)((unsigned long)rec + rec->size); diff --git a/arch/ppc/coffboot/start.c b/arch/ppc/coffboot/start.c index 6fc1fc1fbcdc..e9d9f3a6f5ca 100644 --- a/arch/ppc/coffboot/start.c +++ b/arch/ppc/coffboot/start.c @@ -172,6 +172,25 @@ claim(unsigned int virt, unsigned int size, unsigned int align) return args.ret; } +void +release(void *virt, unsigned int size) +{ + struct prom_args { + char *service; + int nargs; + int nret; + void *virt; + unsigned int size; + } args; + + args.service = "release"; + args.nargs = 2; + args.nret = 0; + args.virt = virt; + args.size = size; + (*prom)(&args); +} + int getprop(void *phandle, const char *name, void *buf, int buflen) { diff --git a/arch/ppc/config.in b/arch/ppc/config.in index b2338d2c250b..3f90b90d8dd5 100644 --- a/arch/ppc/config.in +++ b/arch/ppc/config.in @@ -3,8 +3,8 @@ # see Documentation/kbuild/config-language.txt. # define_bool CONFIG_UID16 n -define_bool CONFIG_RWSEM_GENERIC_SPINLOCK y -define_bool CONFIG_RWSEM_XCHGADD_ALGORITHM n +define_bool CONFIG_RWSEM_GENERIC_SPINLOCK n +define_bool CONFIG_RWSEM_XCHGADD_ALGORITHM y mainmenu_name "Linux/PowerPC Kernel Configuration" @@ -84,6 +84,7 @@ fi if [ "$CONFIG_6xx" = "y" -a "$CONFIG_8260" = "n" ]; then choice 'Machine Type' \ "PowerMac/PReP/MTX/CHRP CONFIG_ALL_PPC \ + Gemini CONFIG_GEMINI \ APUS CONFIG_APUS" PowerMac/PReP/MTX/CHRP fi @@ -118,7 +119,6 @@ mainmenu_option next_comment comment 'General setup' bool 'High memory support (experimental)' CONFIG_HIGHMEM -bool 'Mac-on-Linux support' CONFIG_MOL define_bool CONFIG_ISA n define_bool CONFIG_EISA n diff --git a/arch/ppc/configs/IVMS8_defconfig b/arch/ppc/configs/IVMS8_defconfig index f73b69efcb8d..66abcb461b87 100644 --- a/arch/ppc/configs/IVMS8_defconfig +++ b/arch/ppc/configs/IVMS8_defconfig @@ -2,6 +2,8 @@ # Automatically generated make config: don't edit # # CONFIG_UID16 is not set +# CONFIG_RWSEM_GENERIC_SPINLOCK is not set +CONFIG_RWSEM_XCHGADD_ALGORITHM=y # # Code maturity level options @@ -23,7 +25,6 @@ CONFIG_PPC=y # CONFIG_4xx is not set # CONFIG_POWER3 is not set # CONFIG_POWER4 is not set -# CONFIG_8260 is not set CONFIG_8xx=y CONFIG_SERIAL_CONSOLE=y # CONFIG_RPXLITE is not set @@ -40,6 +41,7 @@ CONFIG_IVMS8=y # CONFIG_SM850 is not set # CONFIG_MBX is not set # CONFIG_WINCEPT is not set +# CONFIG_PPC601_SYNC_FIX is not set # CONFIG_ALL_PPC is not set # CONFIG_SMP is not set CONFIG_MACH_SPECIFIC=y @@ -50,8 +52,12 @@ CONFIG_SASH_PATH="/bin/sash" # # General setup # +# CONFIG_HIGHMEM is not set # CONFIG_ISA is not set +# CONFIG_EISA is not set # CONFIG_SBUS is not set +# CONFIG_MCA is not set +# CONFIG_PCI_QSPAN is not set # CONFIG_PCI is not set CONFIG_NET=y CONFIG_SYSCTL=y @@ -87,17 +93,23 @@ CONFIG_KERNEL_ELF=y # CONFIG_BLK_DEV_XD is not set # CONFIG_PARIDE is not set # CONFIG_BLK_CPQ_DA is not set +# CONFIG_BLK_CPQ_CISS_DA is not set # CONFIG_BLK_DEV_DAC960 is not set # CONFIG_BLK_DEV_LOOP is not set # CONFIG_BLK_DEV_NBD is not set -# CONFIG_BLK_DEV_LVM is not set +# CONFIG_BLK_DEV_RAM is not set +# CONFIG_BLK_DEV_INITRD is not set + +# +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set # CONFIG_BLK_DEV_MD is not set # CONFIG_MD_LINEAR is not set # CONFIG_MD_RAID0 is not set # CONFIG_MD_RAID1 is not set # CONFIG_MD_RAID5 is not set -# CONFIG_BLK_DEV_RAM is not set -# CONFIG_BLK_DEV_INITRD is not set +# CONFIG_BLK_DEV_LVM is not set # # Networking options @@ -116,10 +128,8 @@ CONFIG_INET=y CONFIG_IP_PNP=y # CONFIG_IP_PNP_BOOTP is not set # CONFIG_IP_PNP_RARP is not set -# CONFIG_IP_ROUTER is not set # CONFIG_NET_IPIP is not set # CONFIG_NET_IPGRE is not set -# CONFIG_IP_ALIAS is not set # CONFIG_INET_ECN is not set # CONFIG_SYN_COOKIES is not set # CONFIG_IPV6 is not set @@ -136,6 +146,7 @@ CONFIG_IP_PNP=y # CONFIG_X25 is not set # CONFIG_LAPB is not set # CONFIG_LLC is not set +# CONFIG_NET_DIVERT is not set # CONFIG_ECONET is not set # CONFIG_WAN_ROUTER is not set # CONFIG_NET_FASTROUTE is not set @@ -184,11 +195,10 @@ CONFIG_BLK_DEV_IDECD=y # CONFIG_BLK_DEV_CMD640 is not set # CONFIG_BLK_DEV_CMD640_ENHANCED is not set # CONFIG_BLK_DEV_ISAPNP is not set -CONFIG_BLK_DEV_MPC8xx_IDE=y # CONFIG_IDE_CHIPSETS is not set # CONFIG_IDEDMA_AUTO is not set # CONFIG_DMA_NONPCI is not set -CONFIG_BLK_DEV_IDE_MODES=y +# CONFIG_BLK_DEV_IDE_MODES is not set # # SCSI support @@ -207,6 +217,7 @@ CONFIG_NETDEVICES=y # CONFIG_DUMMY is not set # CONFIG_BONDING is not set # CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set # CONFIG_ETHERTAP is not set # CONFIG_NET_SB1000 is not set @@ -232,8 +243,9 @@ CONFIG_NET_ETHERNET=y # # Ethernet (1000 Mbit) # -# CONFIG_YELLOWFIN is not set # CONFIG_ACENIC is not set +# CONFIG_HAMACHI is not set +# CONFIG_YELLOWFIN is not set # CONFIG_SK98LIN is not set # CONFIG_FDDI is not set # CONFIG_HIPPI is not set @@ -287,6 +299,15 @@ CONFIG_NET_ETHERNET=y # # CONFIG_FB is not set +# +# Input core support +# +# CONFIG_INPUT is not set + +# +# Macintosh device drivers +# + # # Character devices # @@ -312,6 +333,10 @@ CONFIG_UNIX98_PTY_COUNT=32 # Joysticks # # CONFIG_JOYSTICK is not set + +# +# Input core support is needed for joysticks +# # CONFIG_QIC02_TAPE is not set # @@ -321,12 +346,6 @@ CONFIG_UNIX98_PTY_COUNT=32 # CONFIG_INTEL_RNG is not set # CONFIG_NVRAM is not set # CONFIG_RTC is not set -# CONFIG_FLASH is not set - -# -# Video For Linux -# -# CONFIG_VIDEO_DEV is not set # CONFIG_DTLK is not set # CONFIG_R3964 is not set # CONFIG_APPLICOM is not set @@ -335,8 +354,13 @@ CONFIG_UNIX98_PTY_COUNT=32 # Ftape, the floppy tape device driver # # CONFIG_FTAPE is not set -# CONFIG_DRM is not set # CONFIG_AGP is not set +# CONFIG_DRM is not set + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set # # File systems @@ -344,6 +368,8 @@ CONFIG_UNIX98_PTY_COUNT=32 # CONFIG_QUOTA is not set # CONFIG_AUTOFS_FS is not set # CONFIG_AUTOFS4_FS is not set +# CONFIG_REISERFS_FS is not set +# CONFIG_REISERFS_CHECK is not set # CONFIG_ADFS_FS is not set # CONFIG_ADFS_FS_RW is not set # CONFIG_AFFS_FS is not set @@ -356,6 +382,7 @@ CONFIG_UNIX98_PTY_COUNT=32 # CONFIG_EFS_FS is not set # CONFIG_JFFS_FS is not set # CONFIG_CRAMFS is not set +CONFIG_TMPFS=y # CONFIG_RAMFS is not set CONFIG_ISO9660_FS=y # CONFIG_JOLIET is not set @@ -398,8 +425,6 @@ CONFIG_LOCKD=y # CONFIG_NCPFS_NFS_NS is not set # CONFIG_NCPFS_OS2_NS is not set # CONFIG_NCPFS_SMALLDOS is not set -# CONFIG_NCPFS_MOUNT_SUBDIR is not set -# CONFIG_NCPFS_NDS_DOMAINS is not set # CONFIG_NCPFS_NLS is not set # CONFIG_NCPFS_EXTRAS is not set @@ -416,6 +441,7 @@ CONFIG_MAC_PARTITION=y # CONFIG_SGI_PARTITION is not set # CONFIG_ULTRIX_PARTITION is not set # CONFIG_SUN_PARTITION is not set +# CONFIG_SMB_NLS is not set # CONFIG_NLS is not set # @@ -430,14 +456,15 @@ CONFIG_MAC_PARTITION=y CONFIG_FEC_ENET=y CONFIG_USE_MDIO=y CONFIG_ENET_BIG_BUFFERS=y -# CONFIG_8xxSMC2 is not set -# CONFIG_8xxSCC is not set +# CONFIG_SMC2_UART is not set +# CONFIG_USE_SCC_IO is not set # # Generic MPC8xx Options # CONFIG_8xx_COPYBACK=y # CONFIG_8xx_CPU6 is not set +CONFIG_BLK_DEV_MPC8xx_IDE=y # # USB support diff --git a/arch/ppc/configs/SM850_defconfig b/arch/ppc/configs/SM850_defconfig index bab9ddd55234..172d749231a9 100644 --- a/arch/ppc/configs/SM850_defconfig +++ b/arch/ppc/configs/SM850_defconfig @@ -2,6 +2,8 @@ # Automatically generated make config: don't edit # # CONFIG_UID16 is not set +# CONFIG_RWSEM_GENERIC_SPINLOCK is not set +CONFIG_RWSEM_XCHGADD_ALGORITHM=y # # Code maturity level options @@ -23,7 +25,6 @@ CONFIG_PPC=y # CONFIG_4xx is not set # CONFIG_POWER3 is not set # CONFIG_POWER4 is not set -# CONFIG_8260 is not set CONFIG_8xx=y CONFIG_SERIAL_CONSOLE=y # CONFIG_RPXLITE is not set @@ -36,10 +37,12 @@ CONFIG_SERIAL_CONSOLE=y # CONFIG_FPS850L is not set # CONFIG_TQM860 is not set # CONFIG_SPD823TS is not set +# CONFIG_IVMS8 is not set CONFIG_SM850=y # CONFIG_MBX is not set # CONFIG_WINCEPT is not set CONFIG_TQM8xxL=y +# CONFIG_PPC601_SYNC_FIX is not set # CONFIG_ALL_PPC is not set # CONFIG_SMP is not set CONFIG_MACH_SPECIFIC=y @@ -50,8 +53,12 @@ CONFIG_SASH_PATH="/bin/sash" # # General setup # +# CONFIG_HIGHMEM is not set # CONFIG_ISA is not set +# CONFIG_EISA is not set # CONFIG_SBUS is not set +# CONFIG_MCA is not set +# CONFIG_PCI_QSPAN is not set # CONFIG_PCI is not set CONFIG_NET=y CONFIG_SYSCTL=y @@ -87,17 +94,23 @@ CONFIG_KERNEL_ELF=y # CONFIG_BLK_DEV_XD is not set # CONFIG_PARIDE is not set # CONFIG_BLK_CPQ_DA is not set +# CONFIG_BLK_CPQ_CISS_DA is not set # CONFIG_BLK_DEV_DAC960 is not set # CONFIG_BLK_DEV_LOOP is not set # CONFIG_BLK_DEV_NBD is not set -# CONFIG_BLK_DEV_LVM is not set +# CONFIG_BLK_DEV_RAM is not set +# CONFIG_BLK_DEV_INITRD is not set + +# +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set # CONFIG_BLK_DEV_MD is not set # CONFIG_MD_LINEAR is not set # CONFIG_MD_RAID0 is not set # CONFIG_MD_RAID1 is not set # CONFIG_MD_RAID5 is not set -# CONFIG_BLK_DEV_RAM is not set -# CONFIG_BLK_DEV_INITRD is not set +# CONFIG_BLK_DEV_LVM is not set # # Networking options @@ -116,10 +129,8 @@ CONFIG_INET=y CONFIG_IP_PNP=y # CONFIG_IP_PNP_BOOTP is not set # CONFIG_IP_PNP_RARP is not set -# CONFIG_IP_ROUTER is not set # CONFIG_NET_IPIP is not set # CONFIG_NET_IPGRE is not set -# CONFIG_IP_ALIAS is not set # CONFIG_INET_ECN is not set # CONFIG_SYN_COOKIES is not set # CONFIG_IPV6 is not set @@ -136,6 +147,7 @@ CONFIG_IP_PNP=y # CONFIG_X25 is not set # CONFIG_LAPB is not set # CONFIG_LLC is not set +# CONFIG_NET_DIVERT is not set # CONFIG_ECONET is not set # CONFIG_WAN_ROUTER is not set # CONFIG_NET_FASTROUTE is not set @@ -170,6 +182,7 @@ CONFIG_NETDEVICES=y # CONFIG_DUMMY is not set # CONFIG_BONDING is not set # CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set # CONFIG_ETHERTAP is not set # CONFIG_NET_SB1000 is not set @@ -195,8 +208,9 @@ CONFIG_NET_ETHERNET=y # # Ethernet (1000 Mbit) # -# CONFIG_YELLOWFIN is not set # CONFIG_ACENIC is not set +# CONFIG_HAMACHI is not set +# CONFIG_YELLOWFIN is not set # CONFIG_SK98LIN is not set # CONFIG_FDDI is not set # CONFIG_HIPPI is not set @@ -250,6 +264,15 @@ CONFIG_NET_ETHERNET=y # # CONFIG_FB is not set +# +# Input core support +# +# CONFIG_INPUT is not set + +# +# Macintosh device drivers +# + # # Character devices # @@ -275,6 +298,10 @@ CONFIG_UNIX98_PTY_COUNT=32 # Joysticks # # CONFIG_JOYSTICK is not set + +# +# Input core support is needed for joysticks +# # CONFIG_QIC02_TAPE is not set # @@ -284,13 +311,6 @@ CONFIG_UNIX98_PTY_COUNT=32 # CONFIG_INTEL_RNG is not set # CONFIG_NVRAM is not set # CONFIG_RTC is not set -CONFIG_FLASH=y -CONFIG_AMD_FLASH=y - -# -# Video For Linux -# -# CONFIG_VIDEO_DEV is not set # CONFIG_DTLK is not set # CONFIG_R3964 is not set # CONFIG_APPLICOM is not set @@ -299,8 +319,13 @@ CONFIG_AMD_FLASH=y # Ftape, the floppy tape device driver # # CONFIG_FTAPE is not set -# CONFIG_DRM is not set # CONFIG_AGP is not set +# CONFIG_DRM is not set + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set # # File systems @@ -308,6 +333,8 @@ CONFIG_AMD_FLASH=y # CONFIG_QUOTA is not set # CONFIG_AUTOFS_FS is not set # CONFIG_AUTOFS4_FS is not set +# CONFIG_REISERFS_FS is not set +# CONFIG_REISERFS_CHECK is not set # CONFIG_ADFS_FS is not set # CONFIG_ADFS_FS_RW is not set # CONFIG_AFFS_FS is not set @@ -320,6 +347,7 @@ CONFIG_AMD_FLASH=y # CONFIG_EFS_FS is not set # CONFIG_JFFS_FS is not set # CONFIG_CRAMFS is not set +CONFIG_TMPFS=y # CONFIG_RAMFS is not set # CONFIG_ISO9660_FS is not set # CONFIG_JOLIET is not set @@ -362,8 +390,6 @@ CONFIG_LOCKD=y # CONFIG_NCPFS_NFS_NS is not set # CONFIG_NCPFS_OS2_NS is not set # CONFIG_NCPFS_SMALLDOS is not set -# CONFIG_NCPFS_MOUNT_SUBDIR is not set -# CONFIG_NCPFS_NDS_DOMAINS is not set # CONFIG_NCPFS_NLS is not set # CONFIG_NCPFS_EXTRAS is not set @@ -380,6 +406,7 @@ CONFIG_PARTITION_ADVANCED=y # CONFIG_SGI_PARTITION is not set # CONFIG_ULTRIX_PARTITION is not set # CONFIG_SUN_PARTITION is not set +# CONFIG_SMB_NLS is not set # CONFIG_NLS is not set # @@ -396,10 +423,10 @@ CONFIG_SCC_ENET=y CONFIG_SCC3_ENET=y # CONFIG_FEC_ENET is not set CONFIG_ENET_BIG_BUFFERS=y -CONFIG_8xxSMC2=y -CONFIG_8xx_ALTSMC2=y -CONFIG_8xx_CONS_SMC2=y -# CONFIG_8xxSCC is not set +CONFIG_SMC2_UART=y +CONFIG_ALTSMC2=y +CONFIG_CONS_SMC2=y +# CONFIG_USE_SCC_IO is not set # # Generic MPC8xx Options diff --git a/arch/ppc/configs/SPD823TS_defconfig b/arch/ppc/configs/SPD823TS_defconfig index 899b294361ff..5e279c39562f 100644 --- a/arch/ppc/configs/SPD823TS_defconfig +++ b/arch/ppc/configs/SPD823TS_defconfig @@ -2,6 +2,8 @@ # Automatically generated make config: don't edit # # CONFIG_UID16 is not set +# CONFIG_RWSEM_GENERIC_SPINLOCK is not set +CONFIG_RWSEM_XCHGADD_ALGORITHM=y # # Code maturity level options @@ -23,7 +25,6 @@ CONFIG_PPC=y # CONFIG_4xx is not set # CONFIG_POWER3 is not set # CONFIG_POWER4 is not set -# CONFIG_8260 is not set CONFIG_8xx=y CONFIG_SERIAL_CONSOLE=y # CONFIG_RPXLITE is not set @@ -36,8 +37,11 @@ CONFIG_SERIAL_CONSOLE=y # CONFIG_FPS850L is not set # CONFIG_TQM860 is not set CONFIG_SPD823TS=y +# CONFIG_IVMS8 is not set +# CONFIG_SM850 is not set # CONFIG_MBX is not set # CONFIG_WINCEPT is not set +# CONFIG_PPC601_SYNC_FIX is not set # CONFIG_ALL_PPC is not set # CONFIG_SMP is not set CONFIG_MACH_SPECIFIC=y @@ -48,8 +52,12 @@ CONFIG_SASH_PATH="/bin/sash" # # General setup # +# CONFIG_HIGHMEM is not set # CONFIG_ISA is not set +# CONFIG_EISA is not set # CONFIG_SBUS is not set +# CONFIG_MCA is not set +# CONFIG_PCI_QSPAN is not set # CONFIG_PCI is not set CONFIG_NET=y CONFIG_SYSCTL=y @@ -85,17 +93,23 @@ CONFIG_KERNEL_ELF=y # CONFIG_BLK_DEV_XD is not set # CONFIG_PARIDE is not set # CONFIG_BLK_CPQ_DA is not set +# CONFIG_BLK_CPQ_CISS_DA is not set # CONFIG_BLK_DEV_DAC960 is not set # CONFIG_BLK_DEV_LOOP is not set # CONFIG_BLK_DEV_NBD is not set -# CONFIG_BLK_DEV_LVM is not set +# CONFIG_BLK_DEV_RAM is not set +# CONFIG_BLK_DEV_INITRD is not set + +# +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set # CONFIG_BLK_DEV_MD is not set # CONFIG_MD_LINEAR is not set # CONFIG_MD_RAID0 is not set # CONFIG_MD_RAID1 is not set # CONFIG_MD_RAID5 is not set -# CONFIG_BLK_DEV_RAM is not set -# CONFIG_BLK_DEV_INITRD is not set +# CONFIG_BLK_DEV_LVM is not set # # Networking options @@ -114,10 +128,8 @@ CONFIG_INET=y CONFIG_IP_PNP=y # CONFIG_IP_PNP_BOOTP is not set # CONFIG_IP_PNP_RARP is not set -# CONFIG_IP_ROUTER is not set # CONFIG_NET_IPIP is not set # CONFIG_NET_IPGRE is not set -# CONFIG_IP_ALIAS is not set # CONFIG_INET_ECN is not set # CONFIG_SYN_COOKIES is not set # CONFIG_IPV6 is not set @@ -134,6 +146,7 @@ CONFIG_IP_PNP=y # CONFIG_X25 is not set # CONFIG_LAPB is not set # CONFIG_LLC is not set +# CONFIG_NET_DIVERT is not set # CONFIG_ECONET is not set # CONFIG_WAN_ROUTER is not set # CONFIG_NET_FASTROUTE is not set @@ -168,6 +181,7 @@ CONFIG_NETDEVICES=y # CONFIG_DUMMY is not set # CONFIG_BONDING is not set # CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set # CONFIG_ETHERTAP is not set # CONFIG_NET_SB1000 is not set @@ -193,8 +207,9 @@ CONFIG_NET_ETHERNET=y # # Ethernet (1000 Mbit) # -# CONFIG_YELLOWFIN is not set # CONFIG_ACENIC is not set +# CONFIG_HAMACHI is not set +# CONFIG_YELLOWFIN is not set # CONFIG_SK98LIN is not set # CONFIG_FDDI is not set # CONFIG_HIPPI is not set @@ -248,6 +263,15 @@ CONFIG_NET_ETHERNET=y # # CONFIG_FB is not set +# +# Input core support +# +# CONFIG_INPUT is not set + +# +# Macintosh device drivers +# + # # Character devices # @@ -273,6 +297,10 @@ CONFIG_UNIX98_PTY_COUNT=32 # Joysticks # # CONFIG_JOYSTICK is not set + +# +# Input core support is needed for joysticks +# # CONFIG_QIC02_TAPE is not set # @@ -282,12 +310,6 @@ CONFIG_UNIX98_PTY_COUNT=32 # CONFIG_INTEL_RNG is not set # CONFIG_NVRAM is not set # CONFIG_RTC is not set -# CONFIG_FLASH is not set - -# -# Video For Linux -# -# CONFIG_VIDEO_DEV is not set # CONFIG_DTLK is not set # CONFIG_R3964 is not set # CONFIG_APPLICOM is not set @@ -296,8 +318,13 @@ CONFIG_UNIX98_PTY_COUNT=32 # Ftape, the floppy tape device driver # # CONFIG_FTAPE is not set -# CONFIG_DRM is not set # CONFIG_AGP is not set +# CONFIG_DRM is not set + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set # # File systems @@ -305,6 +332,8 @@ CONFIG_UNIX98_PTY_COUNT=32 # CONFIG_QUOTA is not set # CONFIG_AUTOFS_FS is not set # CONFIG_AUTOFS4_FS is not set +# CONFIG_REISERFS_FS is not set +# CONFIG_REISERFS_CHECK is not set # CONFIG_ADFS_FS is not set # CONFIG_ADFS_FS_RW is not set # CONFIG_AFFS_FS is not set @@ -317,6 +346,7 @@ CONFIG_UNIX98_PTY_COUNT=32 # CONFIG_EFS_FS is not set # CONFIG_JFFS_FS is not set # CONFIG_CRAMFS is not set +CONFIG_TMPFS=y # CONFIG_RAMFS is not set # CONFIG_ISO9660_FS is not set # CONFIG_JOLIET is not set @@ -359,8 +389,6 @@ CONFIG_LOCKD=y # CONFIG_NCPFS_NFS_NS is not set # CONFIG_NCPFS_OS2_NS is not set # CONFIG_NCPFS_SMALLDOS is not set -# CONFIG_NCPFS_MOUNT_SUBDIR is not set -# CONFIG_NCPFS_NDS_DOMAINS is not set # CONFIG_NCPFS_NLS is not set # CONFIG_NCPFS_EXTRAS is not set @@ -377,6 +405,7 @@ CONFIG_PARTITION_ADVANCED=y # CONFIG_SGI_PARTITION is not set # CONFIG_ULTRIX_PARTITION is not set # CONFIG_SUN_PARTITION is not set +# CONFIG_SMB_NLS is not set # CONFIG_NLS is not set # @@ -390,12 +419,13 @@ CONFIG_PARTITION_ADVANCED=y CONFIG_SCC_ENET=y # CONFIG_SCC1_ENET is not set CONFIG_SCC2_ENET=y +# CONFIG_SCC3_ENET is not set # CONFIG_FEC_ENET is not set CONFIG_ENET_BIG_BUFFERS=y -CONFIG_8xxSMC2=y -CONFIG_8xx_ALTSMC2=y -# CONFIG_8xx_CONS_SMC2 is not set -# CONFIG_8xxSCC is not set +CONFIG_SMC2_UART=y +CONFIG_ALTSMC2=y +# CONFIG_CONS_SMC2 is not set +# CONFIG_USE_SCC_IO is not set # # Generic MPC8xx Options diff --git a/arch/ppc/configs/TQM823L_defconfig b/arch/ppc/configs/TQM823L_defconfig index 9724fd901977..aa4806e0c723 100644 --- a/arch/ppc/configs/TQM823L_defconfig +++ b/arch/ppc/configs/TQM823L_defconfig @@ -2,6 +2,8 @@ # Automatically generated make config: don't edit # # CONFIG_UID16 is not set +# CONFIG_RWSEM_GENERIC_SPINLOCK is not set +CONFIG_RWSEM_XCHGADD_ALGORITHM=y # # Code maturity level options @@ -23,7 +25,6 @@ CONFIG_PPC=y # CONFIG_4xx is not set # CONFIG_POWER3 is not set # CONFIG_POWER4 is not set -# CONFIG_8260 is not set CONFIG_8xx=y CONFIG_SERIAL_CONSOLE=y # CONFIG_RPXLITE is not set @@ -36,9 +37,12 @@ CONFIG_TQM823L=y # CONFIG_FPS850L is not set # CONFIG_TQM860 is not set # CONFIG_SPD823TS is not set +# CONFIG_IVMS8 is not set +# CONFIG_SM850 is not set # CONFIG_MBX is not set # CONFIG_WINCEPT is not set CONFIG_TQM8xxL=y +# CONFIG_PPC601_SYNC_FIX is not set # CONFIG_ALL_PPC is not set # CONFIG_SMP is not set CONFIG_MACH_SPECIFIC=y @@ -49,8 +53,12 @@ CONFIG_SASH_PATH="/bin/sash" # # General setup # +# CONFIG_HIGHMEM is not set # CONFIG_ISA is not set +# CONFIG_EISA is not set # CONFIG_SBUS is not set +# CONFIG_MCA is not set +# CONFIG_PCI_QSPAN is not set # CONFIG_PCI is not set CONFIG_NET=y CONFIG_SYSCTL=y @@ -86,17 +94,23 @@ CONFIG_KERNEL_ELF=y # CONFIG_BLK_DEV_XD is not set # CONFIG_PARIDE is not set # CONFIG_BLK_CPQ_DA is not set +# CONFIG_BLK_CPQ_CISS_DA is not set # CONFIG_BLK_DEV_DAC960 is not set # CONFIG_BLK_DEV_LOOP is not set # CONFIG_BLK_DEV_NBD is not set -# CONFIG_BLK_DEV_LVM is not set +# CONFIG_BLK_DEV_RAM is not set +# CONFIG_BLK_DEV_INITRD is not set + +# +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set # CONFIG_BLK_DEV_MD is not set # CONFIG_MD_LINEAR is not set # CONFIG_MD_RAID0 is not set # CONFIG_MD_RAID1 is not set # CONFIG_MD_RAID5 is not set -# CONFIG_BLK_DEV_RAM is not set -# CONFIG_BLK_DEV_INITRD is not set +# CONFIG_BLK_DEV_LVM is not set # # Networking options @@ -115,10 +129,8 @@ CONFIG_INET=y CONFIG_IP_PNP=y # CONFIG_IP_PNP_BOOTP is not set # CONFIG_IP_PNP_RARP is not set -# CONFIG_IP_ROUTER is not set # CONFIG_NET_IPIP is not set # CONFIG_NET_IPGRE is not set -# CONFIG_IP_ALIAS is not set # CONFIG_INET_ECN is not set # CONFIG_SYN_COOKIES is not set # CONFIG_IPV6 is not set @@ -135,6 +147,7 @@ CONFIG_IP_PNP=y # CONFIG_X25 is not set # CONFIG_LAPB is not set # CONFIG_LLC is not set +# CONFIG_NET_DIVERT is not set # CONFIG_ECONET is not set # CONFIG_WAN_ROUTER is not set # CONFIG_NET_FASTROUTE is not set @@ -169,6 +182,7 @@ CONFIG_NETDEVICES=y # CONFIG_DUMMY is not set # CONFIG_BONDING is not set # CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set # CONFIG_ETHERTAP is not set # CONFIG_NET_SB1000 is not set @@ -194,8 +208,9 @@ CONFIG_NET_ETHERNET=y # # Ethernet (1000 Mbit) # -# CONFIG_YELLOWFIN is not set # CONFIG_ACENIC is not set +# CONFIG_HAMACHI is not set +# CONFIG_YELLOWFIN is not set # CONFIG_SK98LIN is not set # CONFIG_FDDI is not set # CONFIG_HIPPI is not set @@ -249,6 +264,15 @@ CONFIG_NET_ETHERNET=y # # CONFIG_FB is not set +# +# Input core support +# +# CONFIG_INPUT is not set + +# +# Macintosh device drivers +# + # # Character devices # @@ -274,6 +298,10 @@ CONFIG_UNIX98_PTY_COUNT=32 # Joysticks # # CONFIG_JOYSTICK is not set + +# +# Input core support is needed for joysticks +# # CONFIG_QIC02_TAPE is not set # @@ -283,13 +311,6 @@ CONFIG_UNIX98_PTY_COUNT=32 # CONFIG_INTEL_RNG is not set # CONFIG_NVRAM is not set # CONFIG_RTC is not set -CONFIG_FLASH=y -CONFIG_AMD_FLASH=y - -# -# Video For Linux -# -# CONFIG_VIDEO_DEV is not set # CONFIG_DTLK is not set # CONFIG_R3964 is not set # CONFIG_APPLICOM is not set @@ -298,8 +319,13 @@ CONFIG_AMD_FLASH=y # Ftape, the floppy tape device driver # # CONFIG_FTAPE is not set -# CONFIG_DRM is not set # CONFIG_AGP is not set +# CONFIG_DRM is not set + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set # # File systems @@ -307,6 +333,8 @@ CONFIG_AMD_FLASH=y # CONFIG_QUOTA is not set # CONFIG_AUTOFS_FS is not set # CONFIG_AUTOFS4_FS is not set +# CONFIG_REISERFS_FS is not set +# CONFIG_REISERFS_CHECK is not set # CONFIG_ADFS_FS is not set # CONFIG_ADFS_FS_RW is not set # CONFIG_AFFS_FS is not set @@ -319,6 +347,7 @@ CONFIG_AMD_FLASH=y # CONFIG_EFS_FS is not set # CONFIG_JFFS_FS is not set # CONFIG_CRAMFS is not set +CONFIG_TMPFS=y # CONFIG_RAMFS is not set # CONFIG_ISO9660_FS is not set # CONFIG_JOLIET is not set @@ -361,8 +390,6 @@ CONFIG_LOCKD=y # CONFIG_NCPFS_NFS_NS is not set # CONFIG_NCPFS_OS2_NS is not set # CONFIG_NCPFS_SMALLDOS is not set -# CONFIG_NCPFS_MOUNT_SUBDIR is not set -# CONFIG_NCPFS_NDS_DOMAINS is not set # CONFIG_NCPFS_NLS is not set # CONFIG_NCPFS_EXTRAS is not set @@ -379,6 +406,7 @@ CONFIG_PARTITION_ADVANCED=y # CONFIG_SGI_PARTITION is not set # CONFIG_ULTRIX_PARTITION is not set # CONFIG_SUN_PARTITION is not set +# CONFIG_SMB_NLS is not set # CONFIG_NLS is not set # @@ -395,10 +423,10 @@ CONFIG_SCC2_ENET=y # CONFIG_SCC3_ENET is not set # CONFIG_FEC_ENET is not set CONFIG_ENET_BIG_BUFFERS=y -CONFIG_8xxSMC2=y -CONFIG_8xx_ALTSMC2=y -# CONFIG_8xx_CONS_SMC2 is not set -# CONFIG_8xxSCC is not set +CONFIG_SMC2_UART=y +CONFIG_ALTSMC2=y +# CONFIG_CONS_SMC2 is not set +# CONFIG_USE_SCC_IO is not set # # Generic MPC8xx Options diff --git a/arch/ppc/configs/TQM850L_defconfig b/arch/ppc/configs/TQM850L_defconfig index eb1e130ad933..e3f23c7b63e2 100644 --- a/arch/ppc/configs/TQM850L_defconfig +++ b/arch/ppc/configs/TQM850L_defconfig @@ -2,6 +2,8 @@ # Automatically generated make config: don't edit # # CONFIG_UID16 is not set +# CONFIG_RWSEM_GENERIC_SPINLOCK is not set +CONFIG_RWSEM_XCHGADD_ALGORITHM=y # # Code maturity level options @@ -23,7 +25,6 @@ CONFIG_PPC=y # CONFIG_4xx is not set # CONFIG_POWER3 is not set # CONFIG_POWER4 is not set -# CONFIG_8260 is not set CONFIG_8xx=y CONFIG_SERIAL_CONSOLE=y # CONFIG_RPXLITE is not set @@ -36,9 +37,12 @@ CONFIG_TQM850L=y # CONFIG_FPS850L is not set # CONFIG_TQM860 is not set # CONFIG_SPD823TS is not set +# CONFIG_IVMS8 is not set +# CONFIG_SM850 is not set # CONFIG_MBX is not set # CONFIG_WINCEPT is not set CONFIG_TQM8xxL=y +# CONFIG_PPC601_SYNC_FIX is not set # CONFIG_ALL_PPC is not set # CONFIG_SMP is not set CONFIG_MACH_SPECIFIC=y @@ -49,8 +53,12 @@ CONFIG_SASH_PATH="/bin/sash" # # General setup # +# CONFIG_HIGHMEM is not set # CONFIG_ISA is not set +# CONFIG_EISA is not set # CONFIG_SBUS is not set +# CONFIG_MCA is not set +# CONFIG_PCI_QSPAN is not set # CONFIG_PCI is not set CONFIG_NET=y CONFIG_SYSCTL=y @@ -86,17 +94,23 @@ CONFIG_KERNEL_ELF=y # CONFIG_BLK_DEV_XD is not set # CONFIG_PARIDE is not set # CONFIG_BLK_CPQ_DA is not set +# CONFIG_BLK_CPQ_CISS_DA is not set # CONFIG_BLK_DEV_DAC960 is not set # CONFIG_BLK_DEV_LOOP is not set # CONFIG_BLK_DEV_NBD is not set -# CONFIG_BLK_DEV_LVM is not set +# CONFIG_BLK_DEV_RAM is not set +# CONFIG_BLK_DEV_INITRD is not set + +# +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set # CONFIG_BLK_DEV_MD is not set # CONFIG_MD_LINEAR is not set # CONFIG_MD_RAID0 is not set # CONFIG_MD_RAID1 is not set # CONFIG_MD_RAID5 is not set -# CONFIG_BLK_DEV_RAM is not set -# CONFIG_BLK_DEV_INITRD is not set +# CONFIG_BLK_DEV_LVM is not set # # Networking options @@ -115,10 +129,8 @@ CONFIG_INET=y CONFIG_IP_PNP=y # CONFIG_IP_PNP_BOOTP is not set # CONFIG_IP_PNP_RARP is not set -# CONFIG_IP_ROUTER is not set # CONFIG_NET_IPIP is not set # CONFIG_NET_IPGRE is not set -# CONFIG_IP_ALIAS is not set # CONFIG_INET_ECN is not set # CONFIG_SYN_COOKIES is not set # CONFIG_IPV6 is not set @@ -135,6 +147,7 @@ CONFIG_IP_PNP=y # CONFIG_X25 is not set # CONFIG_LAPB is not set # CONFIG_LLC is not set +# CONFIG_NET_DIVERT is not set # CONFIG_ECONET is not set # CONFIG_WAN_ROUTER is not set # CONFIG_NET_FASTROUTE is not set @@ -169,6 +182,7 @@ CONFIG_NETDEVICES=y # CONFIG_DUMMY is not set # CONFIG_BONDING is not set # CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set # CONFIG_ETHERTAP is not set # CONFIG_NET_SB1000 is not set @@ -194,8 +208,9 @@ CONFIG_NET_ETHERNET=y # # Ethernet (1000 Mbit) # -# CONFIG_YELLOWFIN is not set # CONFIG_ACENIC is not set +# CONFIG_HAMACHI is not set +# CONFIG_YELLOWFIN is not set # CONFIG_SK98LIN is not set # CONFIG_FDDI is not set # CONFIG_HIPPI is not set @@ -249,6 +264,15 @@ CONFIG_NET_ETHERNET=y # # CONFIG_FB is not set +# +# Input core support +# +# CONFIG_INPUT is not set + +# +# Macintosh device drivers +# + # # Character devices # @@ -274,6 +298,10 @@ CONFIG_UNIX98_PTY_COUNT=32 # Joysticks # # CONFIG_JOYSTICK is not set + +# +# Input core support is needed for joysticks +# # CONFIG_QIC02_TAPE is not set # @@ -283,13 +311,6 @@ CONFIG_UNIX98_PTY_COUNT=32 # CONFIG_INTEL_RNG is not set # CONFIG_NVRAM is not set # CONFIG_RTC is not set -CONFIG_FLASH=y -CONFIG_AMD_FLASH=y - -# -# Video For Linux -# -# CONFIG_VIDEO_DEV is not set # CONFIG_DTLK is not set # CONFIG_R3964 is not set # CONFIG_APPLICOM is not set @@ -298,8 +319,13 @@ CONFIG_AMD_FLASH=y # Ftape, the floppy tape device driver # # CONFIG_FTAPE is not set -# CONFIG_DRM is not set # CONFIG_AGP is not set +# CONFIG_DRM is not set + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set # # File systems @@ -307,6 +333,8 @@ CONFIG_AMD_FLASH=y # CONFIG_QUOTA is not set # CONFIG_AUTOFS_FS is not set # CONFIG_AUTOFS4_FS is not set +# CONFIG_REISERFS_FS is not set +# CONFIG_REISERFS_CHECK is not set # CONFIG_ADFS_FS is not set # CONFIG_ADFS_FS_RW is not set # CONFIG_AFFS_FS is not set @@ -319,6 +347,7 @@ CONFIG_AMD_FLASH=y # CONFIG_EFS_FS is not set # CONFIG_JFFS_FS is not set # CONFIG_CRAMFS is not set +CONFIG_TMPFS=y # CONFIG_RAMFS is not set # CONFIG_ISO9660_FS is not set # CONFIG_JOLIET is not set @@ -361,8 +390,6 @@ CONFIG_LOCKD=y # CONFIG_NCPFS_NFS_NS is not set # CONFIG_NCPFS_OS2_NS is not set # CONFIG_NCPFS_SMALLDOS is not set -# CONFIG_NCPFS_MOUNT_SUBDIR is not set -# CONFIG_NCPFS_NDS_DOMAINS is not set # CONFIG_NCPFS_NLS is not set # CONFIG_NCPFS_EXTRAS is not set @@ -379,6 +406,7 @@ CONFIG_PARTITION_ADVANCED=y # CONFIG_SGI_PARTITION is not set # CONFIG_ULTRIX_PARTITION is not set # CONFIG_SUN_PARTITION is not set +# CONFIG_SMB_NLS is not set # CONFIG_NLS is not set # @@ -395,10 +423,10 @@ CONFIG_SCC2_ENET=y # CONFIG_SCC3_ENET is not set # CONFIG_FEC_ENET is not set CONFIG_ENET_BIG_BUFFERS=y -CONFIG_8xxSMC2=y -CONFIG_8xx_ALTSMC2=y -# CONFIG_8xx_CONS_SMC2 is not set -# CONFIG_8xxSCC is not set +CONFIG_SMC2_UART=y +CONFIG_ALTSMC2=y +# CONFIG_CONS_SMC2 is not set +# CONFIG_USE_SCC_IO is not set # # Generic MPC8xx Options diff --git a/arch/ppc/configs/TQM860L_defconfig b/arch/ppc/configs/TQM860L_defconfig index ebe47c109619..e624f66c119f 100644 --- a/arch/ppc/configs/TQM860L_defconfig +++ b/arch/ppc/configs/TQM860L_defconfig @@ -2,6 +2,8 @@ # Automatically generated make config: don't edit # # CONFIG_UID16 is not set +# CONFIG_RWSEM_GENERIC_SPINLOCK is not set +CONFIG_RWSEM_XCHGADD_ALGORITHM=y # # Code maturity level options @@ -23,7 +25,6 @@ CONFIG_PPC=y # CONFIG_4xx is not set # CONFIG_POWER3 is not set # CONFIG_POWER4 is not set -# CONFIG_8260 is not set CONFIG_8xx=y CONFIG_SERIAL_CONSOLE=y # CONFIG_RPXLITE is not set @@ -36,9 +37,12 @@ CONFIG_TQM860L=y # CONFIG_FPS850L is not set # CONFIG_TQM860 is not set # CONFIG_SPD823TS is not set +# CONFIG_IVMS8 is not set +# CONFIG_SM850 is not set # CONFIG_MBX is not set # CONFIG_WINCEPT is not set CONFIG_TQM8xxL=y +# CONFIG_PPC601_SYNC_FIX is not set # CONFIG_ALL_PPC is not set # CONFIG_SMP is not set CONFIG_MACH_SPECIFIC=y @@ -49,8 +53,12 @@ CONFIG_SASH_PATH="/bin/sash" # # General setup # +# CONFIG_HIGHMEM is not set # CONFIG_ISA is not set +# CONFIG_EISA is not set # CONFIG_SBUS is not set +# CONFIG_MCA is not set +# CONFIG_PCI_QSPAN is not set # CONFIG_PCI is not set CONFIG_NET=y CONFIG_SYSCTL=y @@ -86,17 +94,23 @@ CONFIG_KERNEL_ELF=y # CONFIG_BLK_DEV_XD is not set # CONFIG_PARIDE is not set # CONFIG_BLK_CPQ_DA is not set +# CONFIG_BLK_CPQ_CISS_DA is not set # CONFIG_BLK_DEV_DAC960 is not set # CONFIG_BLK_DEV_LOOP is not set # CONFIG_BLK_DEV_NBD is not set -# CONFIG_BLK_DEV_LVM is not set +# CONFIG_BLK_DEV_RAM is not set +# CONFIG_BLK_DEV_INITRD is not set + +# +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set # CONFIG_BLK_DEV_MD is not set # CONFIG_MD_LINEAR is not set # CONFIG_MD_RAID0 is not set # CONFIG_MD_RAID1 is not set # CONFIG_MD_RAID5 is not set -# CONFIG_BLK_DEV_RAM is not set -# CONFIG_BLK_DEV_INITRD is not set +# CONFIG_BLK_DEV_LVM is not set # # Networking options @@ -115,10 +129,8 @@ CONFIG_INET=y CONFIG_IP_PNP=y # CONFIG_IP_PNP_BOOTP is not set # CONFIG_IP_PNP_RARP is not set -# CONFIG_IP_ROUTER is not set # CONFIG_NET_IPIP is not set # CONFIG_NET_IPGRE is not set -# CONFIG_IP_ALIAS is not set # CONFIG_INET_ECN is not set # CONFIG_SYN_COOKIES is not set # CONFIG_IPV6 is not set @@ -135,6 +147,7 @@ CONFIG_IP_PNP=y # CONFIG_X25 is not set # CONFIG_LAPB is not set # CONFIG_LLC is not set +# CONFIG_NET_DIVERT is not set # CONFIG_ECONET is not set # CONFIG_WAN_ROUTER is not set # CONFIG_NET_FASTROUTE is not set @@ -169,6 +182,7 @@ CONFIG_NETDEVICES=y # CONFIG_DUMMY is not set # CONFIG_BONDING is not set # CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set # CONFIG_ETHERTAP is not set # CONFIG_NET_SB1000 is not set @@ -194,8 +208,9 @@ CONFIG_NET_ETHERNET=y # # Ethernet (1000 Mbit) # -# CONFIG_YELLOWFIN is not set # CONFIG_ACENIC is not set +# CONFIG_HAMACHI is not set +# CONFIG_YELLOWFIN is not set # CONFIG_SK98LIN is not set # CONFIG_FDDI is not set # CONFIG_HIPPI is not set @@ -249,6 +264,15 @@ CONFIG_NET_ETHERNET=y # # CONFIG_FB is not set +# +# Input core support +# +# CONFIG_INPUT is not set + +# +# Macintosh device drivers +# + # # Character devices # @@ -274,6 +298,10 @@ CONFIG_UNIX98_PTY_COUNT=32 # Joysticks # # CONFIG_JOYSTICK is not set + +# +# Input core support is needed for joysticks +# # CONFIG_QIC02_TAPE is not set # @@ -283,13 +311,6 @@ CONFIG_UNIX98_PTY_COUNT=32 # CONFIG_INTEL_RNG is not set # CONFIG_NVRAM is not set # CONFIG_RTC is not set -CONFIG_FLASH=y -CONFIG_AMD_FLASH=y - -# -# Video For Linux -# -# CONFIG_VIDEO_DEV is not set # CONFIG_DTLK is not set # CONFIG_R3964 is not set # CONFIG_APPLICOM is not set @@ -298,8 +319,13 @@ CONFIG_AMD_FLASH=y # Ftape, the floppy tape device driver # # CONFIG_FTAPE is not set -# CONFIG_DRM is not set # CONFIG_AGP is not set +# CONFIG_DRM is not set + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set # # File systems @@ -307,6 +333,8 @@ CONFIG_AMD_FLASH=y # CONFIG_QUOTA is not set # CONFIG_AUTOFS_FS is not set # CONFIG_AUTOFS4_FS is not set +# CONFIG_REISERFS_FS is not set +# CONFIG_REISERFS_CHECK is not set # CONFIG_ADFS_FS is not set # CONFIG_ADFS_FS_RW is not set # CONFIG_AFFS_FS is not set @@ -319,6 +347,7 @@ CONFIG_AMD_FLASH=y # CONFIG_EFS_FS is not set # CONFIG_JFFS_FS is not set # CONFIG_CRAMFS is not set +CONFIG_TMPFS=y # CONFIG_RAMFS is not set # CONFIG_ISO9660_FS is not set # CONFIG_JOLIET is not set @@ -361,8 +390,6 @@ CONFIG_LOCKD=y # CONFIG_NCPFS_NFS_NS is not set # CONFIG_NCPFS_OS2_NS is not set # CONFIG_NCPFS_SMALLDOS is not set -# CONFIG_NCPFS_MOUNT_SUBDIR is not set -# CONFIG_NCPFS_NDS_DOMAINS is not set # CONFIG_NCPFS_NLS is not set # CONFIG_NCPFS_EXTRAS is not set @@ -379,6 +406,7 @@ CONFIG_PARTITION_ADVANCED=y # CONFIG_SGI_PARTITION is not set # CONFIG_ULTRIX_PARTITION is not set # CONFIG_SUN_PARTITION is not set +# CONFIG_SMB_NLS is not set # CONFIG_NLS is not set # @@ -395,10 +423,10 @@ CONFIG_SCC1_ENET=y # CONFIG_SCC3_ENET is not set # CONFIG_FEC_ENET is not set CONFIG_ENET_BIG_BUFFERS=y -CONFIG_8xxSMC2=y -# CONFIG_8xx_ALTSMC2 is not set -# CONFIG_8xx_CONS_SMC2 is not set -# CONFIG_8xxSCC is not set +CONFIG_SMC2_UART=y +# CONFIG_ALTSMC2 is not set +# CONFIG_CONS_SMC2 is not set +# CONFIG_USE_SCC_IO is not set # # Generic MPC8xx Options diff --git a/arch/ppc/configs/apus_defconfig b/arch/ppc/configs/apus_defconfig index 69e25a9b3849..21045e4e2a23 100644 --- a/arch/ppc/configs/apus_defconfig +++ b/arch/ppc/configs/apus_defconfig @@ -2,6 +2,8 @@ # Automatically generated make config: don't edit # # CONFIG_UID16 is not set +# CONFIG_RWSEM_GENERIC_SPINLOCK is not set +CONFIG_RWSEM_XCHGADD_ALGORITHM=y # # Code maturity level options @@ -24,6 +26,7 @@ CONFIG_6xx=y # CONFIG_8xx is not set # CONFIG_8260 is not set # CONFIG_ALL_PPC is not set +# CONFIG_GEMINI is not set CONFIG_APUS=y CONFIG_PPC601_SYNC_FIX=y # CONFIG_SMP is not set @@ -34,7 +37,6 @@ CONFIG_MACH_SPECIFIC=y # General setup # # CONFIG_HIGHMEM is not set -# CONFIG_MOL is not set # CONFIG_ISA is not set # CONFIG_EISA is not set # CONFIG_SBUS is not set @@ -115,7 +117,6 @@ CONFIG_BLK_DEV_INITRD=y # CONFIG_MD_RAID1 is not set # CONFIG_MD_RAID5 is not set # CONFIG_BLK_DEV_LVM is not set -# CONFIG_LVM_PROC_FS is not set # # Networking options @@ -238,6 +239,7 @@ CONFIG_SR_EXTRA_DEVS=2 # CONFIG_SCSI_AHA1542 is not set # CONFIG_SCSI_AHA1740 is not set # CONFIG_SCSI_AIC7XXX is not set +# CONFIG_SCSI_AIC7XXX_OLD is not set # CONFIG_SCSI_ADVANSYS is not set # CONFIG_SCSI_IN2000 is not set # CONFIG_SCSI_AM53C974 is not set @@ -290,6 +292,7 @@ CONFIG_NET_ETHERNET=y # CONFIG_MACE is not set # CONFIG_BMAC is not set # CONFIG_GMAC is not set +# CONFIG_NCR885E is not set # CONFIG_OAKNET is not set CONFIG_ARIADNE=y # CONFIG_NE2K_ZORRO is not set @@ -316,6 +319,7 @@ CONFIG_HYDRA=y # CONFIG_HIPPI is not set CONFIG_PPP=y CONFIG_PPP_MULTILINK=y +# CONFIG_PPP_FILTER is not set CONFIG_PPP_ASYNC=y CONFIG_PPP_SYNC_TTY=y CONFIG_PPP_DEFLATE=y @@ -394,6 +398,7 @@ CONFIG_FB_RETINAZ3=y # CONFIG_FB_IMSTT is not set # CONFIG_FB_S3TRIO is not set # CONFIG_FB_VGA16 is not set +# CONFIG_FB_E1355 is not set # CONFIG_FB_VIRTUAL is not set # CONFIG_FBCON_ADVANCED is not set CONFIG_FBCON_MFB=y @@ -479,6 +484,8 @@ CONFIG_SERIAL=y # CONFIG_QUOTA is not set # CONFIG_AUTOFS_FS is not set # CONFIG_AUTOFS4_FS is not set +# CONFIG_REISERFS_FS is not set +# CONFIG_REISERFS_CHECK is not set # CONFIG_ADFS_FS is not set # CONFIG_ADFS_FS_RW is not set CONFIG_AFFS_FS=y @@ -491,6 +498,7 @@ CONFIG_VFAT_FS=y # CONFIG_EFS_FS is not set # CONFIG_JFFS_FS is not set # CONFIG_CRAMFS is not set +CONFIG_TMPFS=y # CONFIG_RAMFS is not set CONFIG_ISO9660_FS=y # CONFIG_JOLIET is not set @@ -563,11 +571,13 @@ CONFIG_NLS_DEFAULT="iso8859-1" # CONFIG_NLS_CODEPAGE_865 is not set # CONFIG_NLS_CODEPAGE_866 is not set # CONFIG_NLS_CODEPAGE_869 is not set -# CONFIG_NLS_CODEPAGE_874 is not set -# CONFIG_NLS_CODEPAGE_932 is not set # CONFIG_NLS_CODEPAGE_936 is not set -# CONFIG_NLS_CODEPAGE_949 is not set # CONFIG_NLS_CODEPAGE_950 is not set +# CONFIG_NLS_CODEPAGE_932 is not set +# CONFIG_NLS_CODEPAGE_949 is not set +# CONFIG_NLS_CODEPAGE_874 is not set +# CONFIG_NLS_ISO8859_8 is not set +# CONFIG_NLS_CODEPAGE_1251 is not set CONFIG_NLS_ISO8859_1=y # CONFIG_NLS_ISO8859_2 is not set # CONFIG_NLS_ISO8859_3 is not set @@ -575,11 +585,12 @@ CONFIG_NLS_ISO8859_1=y # CONFIG_NLS_ISO8859_5 is not set # CONFIG_NLS_ISO8859_6 is not set # CONFIG_NLS_ISO8859_7 is not set -# CONFIG_NLS_ISO8859_8 is not set # CONFIG_NLS_ISO8859_9 is not set +# CONFIG_NLS_ISO8859_13 is not set # CONFIG_NLS_ISO8859_14 is not set # CONFIG_NLS_ISO8859_15 is not set # CONFIG_NLS_KOI8_R is not set +# CONFIG_NLS_KOI8_U is not set # CONFIG_NLS_UTF8 is not set # diff --git a/arch/ppc/configs/bseip_defconfig b/arch/ppc/configs/bseip_defconfig index 82b7174bdc1c..3ffa7e38bcbc 100644 --- a/arch/ppc/configs/bseip_defconfig +++ b/arch/ppc/configs/bseip_defconfig @@ -2,6 +2,8 @@ # Automatically generated make config: don't edit # # CONFIG_UID16 is not set +# CONFIG_RWSEM_GENERIC_SPINLOCK is not set +CONFIG_RWSEM_XCHGADD_ALGORITHM=y # # Code maturity level options @@ -26,9 +28,15 @@ CONFIG_SERIAL_CONSOLE=y # CONFIG_RPXLITE is not set # CONFIG_RPXCLASSIC is not set CONFIG_BSEIP=y -# CONFIG_TQM8xxL is not set +# CONFIG_TQM823L is not set +# CONFIG_TQM850L is not set +# CONFIG_TQM855L is not set # CONFIG_TQM860L is not set +# CONFIG_FPS850L is not set # CONFIG_TQM860 is not set +# CONFIG_SPD823TS is not set +# CONFIG_IVMS8 is not set +# CONFIG_SM850 is not set # CONFIG_MBX is not set # CONFIG_WINCEPT is not set CONFIG_PPC601_SYNC_FIX=y @@ -41,7 +49,6 @@ CONFIG_MATH_EMULATION=y # General setup # # CONFIG_HIGHMEM is not set -# CONFIG_MOL is not set # CONFIG_ISA is not set # CONFIG_EISA is not set # CONFIG_SBUS is not set @@ -100,7 +107,6 @@ CONFIG_BLK_DEV_INITRD=y # CONFIG_MD_RAID1 is not set # CONFIG_MD_RAID5 is not set # CONFIG_BLK_DEV_LVM is not set -# CONFIG_LVM_PROC_FS is not set # # Networking options @@ -184,6 +190,7 @@ CONFIG_NET_ETHERNET=y # CONFIG_MACE is not set # CONFIG_BMAC is not set # CONFIG_GMAC is not set +# CONFIG_NCR885E is not set # CONFIG_OAKNET is not set # CONFIG_NET_VENDOR_3COM is not set # CONFIG_LANCE is not set @@ -323,6 +330,8 @@ CONFIG_UNIX98_PTY_COUNT=256 # CONFIG_QUOTA is not set # CONFIG_AUTOFS_FS is not set # CONFIG_AUTOFS4_FS is not set +# CONFIG_REISERFS_FS is not set +# CONFIG_REISERFS_CHECK is not set # CONFIG_ADFS_FS is not set # CONFIG_ADFS_FS_RW is not set # CONFIG_AFFS_FS is not set @@ -335,6 +344,7 @@ CONFIG_UNIX98_PTY_COUNT=256 # CONFIG_EFS_FS is not set # CONFIG_JFFS_FS is not set # CONFIG_CRAMFS is not set +CONFIG_TMPFS=y # CONFIG_RAMFS is not set # CONFIG_ISO9660_FS is not set # CONFIG_JOLIET is not set @@ -407,11 +417,13 @@ CONFIG_PARTITION_ADVANCED=y CONFIG_SCC_ENET=y # CONFIG_SCC1_ENET is not set CONFIG_SCC2_ENET=y +# CONFIG_SCC3_ENET is not set # CONFIG_FEC_ENET is not set # CONFIG_ENET_BIG_BUFFERS is not set -CONFIG_8xxSMC2=y -# CONFIG_8xx_ALTSMC2 is not set -# CONFIG_8xxSCC is not set +CONFIG_SMC2_UART=y +# CONFIG_ALTSMC2 is not set +# CONFIG_CONS_SMC2 is not set +# CONFIG_USE_SCC_IO is not set # # Generic MPC8xx Options diff --git a/arch/ppc/configs/common_defconfig b/arch/ppc/configs/common_defconfig index 6017c8a1ce8b..95bd3c36215e 100644 --- a/arch/ppc/configs/common_defconfig +++ b/arch/ppc/configs/common_defconfig @@ -2,6 +2,8 @@ # Automatically generated make config: don't edit # # CONFIG_UID16 is not set +# CONFIG_RWSEM_GENERIC_SPINLOCK is not set +CONFIG_RWSEM_XCHGADD_ALGORITHM=y # # Code maturity level options @@ -26,6 +28,7 @@ CONFIG_6xx=y # CONFIG_8xx is not set # CONFIG_8260 is not set CONFIG_ALL_PPC=y +# CONFIG_GEMINI is not set # CONFIG_APUS is not set CONFIG_PPC601_SYNC_FIX=y # CONFIG_SMP is not set @@ -35,7 +38,6 @@ CONFIG_ALTIVEC=y # General setup # # CONFIG_HIGHMEM is not set -CONFIG_MOL=y # CONFIG_ISA is not set # CONFIG_EISA is not set # CONFIG_SBUS is not set @@ -105,7 +107,6 @@ CONFIG_BLK_DEV_INITRD=y # CONFIG_MD_RAID1 is not set # CONFIG_MD_RAID5 is not set # CONFIG_BLK_DEV_LVM is not set -# CONFIG_LVM_PROC_FS is not set # # Networking options @@ -141,6 +142,7 @@ CONFIG_IP_NF_MATCH_MAC=m CONFIG_IP_NF_MATCH_MARK=m CONFIG_IP_NF_MATCH_MULTIPORT=m CONFIG_IP_NF_MATCH_TOS=m +CONFIG_IP_NF_MATCH_TCPMSS=m CONFIG_IP_NF_MATCH_STATE=m CONFIG_IP_NF_MATCH_UNCLEAN=m CONFIG_IP_NF_MATCH_OWNER=m @@ -151,8 +153,10 @@ CONFIG_IP_NF_NAT=m CONFIG_IP_NF_NAT_NEEDED=y CONFIG_IP_NF_TARGET_MASQUERADE=m CONFIG_IP_NF_TARGET_REDIRECT=m +CONFIG_IP_NF_NAT_FTP=m # CONFIG_IP_NF_MANGLE is not set # CONFIG_IP_NF_TARGET_LOG is not set +CONFIG_IP_NF_TARGET_TCPMSS=m CONFIG_IP_NF_COMPAT_IPCHAINS=m CONFIG_IP_NF_NAT_NEEDED=y # CONFIG_IP_NF_COMPAT_IPFWADM is not set @@ -296,6 +300,8 @@ CONFIG_SCSI_CONSTANTS=y # CONFIG_SCSI_AHA1542 is not set # CONFIG_SCSI_AHA1740 is not set CONFIG_SCSI_AIC7XXX=m +CONFIG_AIC7XXX_CMDS_PER_DEVICE=253 +CONFIG_AIC7XXX_RESET_DELAY=5000 CONFIG_SCSI_AIC7XXX_OLD=m # CONFIG_AIC7XXX_OLD_TCQ_ON_BY_DEFAULT is not set CONFIG_AIC7XXX_OLD_CMDS_PER_DEVICE=8 @@ -376,8 +382,10 @@ CONFIG_NETDEVICES=y # CONFIG_NET_ETHERNET=y CONFIG_MACE=y +# CONFIG_MACE_AAUI_PORT is not set CONFIG_BMAC=y CONFIG_GMAC=y +# CONFIG_NCR885E is not set # CONFIG_OAKNET is not set # CONFIG_NET_VENDOR_3COM is not set # CONFIG_LANCE is not set @@ -404,7 +412,9 @@ CONFIG_DE4X5=m # CONFIG_NE3210 is not set # CONFIG_ES3210 is not set # CONFIG_8139TOO is not set -# CONFIG_RTL8129 is not set +# CONFIG_8139TOO_PIO is not set +# CONFIG_8139TOO_TUNE_TWISTER is not set +# CONFIG_8139TOO_8129 is not set # CONFIG_SIS900 is not set # CONFIG_EPIC100 is not set # CONFIG_SUNDANCE is not set @@ -425,6 +435,7 @@ CONFIG_DE4X5=m # CONFIG_HIPPI is not set CONFIG_PPP=y CONFIG_PPP_MULTILINK=y +# CONFIG_PPP_FILTER is not set CONFIG_PPP_ASYNC=y # CONFIG_PPP_SYNC_TTY is not set CONFIG_PPP_DEFLATE=y @@ -492,6 +503,7 @@ CONFIG_FB_CT65550=y CONFIG_FB_IMSTT=y # CONFIG_FB_S3TRIO is not set # CONFIG_FB_VGA16 is not set +# CONFIG_FB_E1355 is not set CONFIG_FB_MATROX=y CONFIG_FB_MATROX_MILLENIUM=y CONFIG_FB_MATROX_MYSTIQUE=y @@ -544,6 +556,7 @@ CONFIG_ADB_MACIO=y CONFIG_INPUT_ADBHID=y CONFIG_MAC_ADBKEYCODES=y CONFIG_MAC_EMUMOUSEBTN=y +CONFIG_MAC_HID=y # # Character devices @@ -612,6 +625,8 @@ CONFIG_NVRAM=y # CONFIG_QUOTA is not set # CONFIG_AUTOFS_FS is not set # CONFIG_AUTOFS4_FS is not set +# CONFIG_REISERFS_FS is not set +# CONFIG_REISERFS_CHECK is not set # CONFIG_ADFS_FS is not set # CONFIG_ADFS_FS_RW is not set # CONFIG_AFFS_FS is not set @@ -624,6 +639,7 @@ CONFIG_VFAT_FS=m # CONFIG_EFS_FS is not set # CONFIG_JFFS_FS is not set # CONFIG_CRAMFS is not set +CONFIG_TMPFS=y # CONFIG_RAMFS is not set CONFIG_ISO9660_FS=y # CONFIG_JOLIET is not set @@ -680,6 +696,7 @@ CONFIG_PARTITION_ADVANCED=y CONFIG_MAC_PARTITION=y CONFIG_MSDOS_PARTITION=y # CONFIG_BSD_DISKLABEL is not set +# CONFIG_MINIX_SUBPARTITION is not set # CONFIG_SOLARIS_X86_PARTITION is not set # CONFIG_UNIXWARE_DISKLABEL is not set # CONFIG_SGI_PARTITION is not set @@ -707,11 +724,13 @@ CONFIG_NLS_DEFAULT="iso8859-1" # CONFIG_NLS_CODEPAGE_865 is not set # CONFIG_NLS_CODEPAGE_866 is not set # CONFIG_NLS_CODEPAGE_869 is not set -# CONFIG_NLS_CODEPAGE_874 is not set -# CONFIG_NLS_CODEPAGE_932 is not set # CONFIG_NLS_CODEPAGE_936 is not set -# CONFIG_NLS_CODEPAGE_949 is not set # CONFIG_NLS_CODEPAGE_950 is not set +# CONFIG_NLS_CODEPAGE_932 is not set +# CONFIG_NLS_CODEPAGE_949 is not set +# CONFIG_NLS_CODEPAGE_874 is not set +# CONFIG_NLS_ISO8859_8 is not set +# CONFIG_NLS_CODEPAGE_1251 is not set CONFIG_NLS_ISO8859_1=m # CONFIG_NLS_ISO8859_2 is not set # CONFIG_NLS_ISO8859_3 is not set @@ -719,11 +738,12 @@ CONFIG_NLS_ISO8859_1=m # CONFIG_NLS_ISO8859_5 is not set # CONFIG_NLS_ISO8859_6 is not set # CONFIG_NLS_ISO8859_7 is not set -# CONFIG_NLS_ISO8859_8 is not set # CONFIG_NLS_ISO8859_9 is not set +# CONFIG_NLS_ISO8859_13 is not set # CONFIG_NLS_ISO8859_14 is not set # CONFIG_NLS_ISO8859_15 is not set # CONFIG_NLS_KOI8_R is not set +# CONFIG_NLS_KOI8_U is not set # CONFIG_NLS_UTF8 is not set # @@ -740,6 +760,8 @@ CONFIG_DMASOUND=m # CONFIG_SOUND_ES1371 is not set # CONFIG_SOUND_ESSSOLO1 is not set # CONFIG_SOUND_MAESTRO is not set +# CONFIG_SOUND_MAESTRO3 is not set +# CONFIG_SOUND_ICH is not set # CONFIG_SOUND_SONICVIBES is not set # CONFIG_SOUND_TRIDENT is not set # CONFIG_SOUND_MSNDCLAS is not set @@ -814,7 +836,6 @@ CONFIG_USB_HID=y # USB Serial Converter support # CONFIG_USB_SERIAL=m -# CONFIG_USB_SERIAL_DEBUG is not set # CONFIG_USB_SERIAL_GENERIC is not set # CONFIG_USB_SERIAL_BELKIN is not set # CONFIG_USB_SERIAL_WHITEHEAT is not set @@ -822,6 +843,7 @@ CONFIG_USB_SERIAL=m # CONFIG_USB_SERIAL_EMPEG is not set # CONFIG_USB_SERIAL_FTDI_SIO is not set CONFIG_USB_SERIAL_VISOR=m +# CONFIG_USB_SERIAL_EDGEPORT is not set # CONFIG_USB_SERIAL_KEYSPAN_PDA is not set # CONFIG_USB_SERIAL_KEYSPAN is not set # CONFIG_USB_SERIAL_MCT_U232 is not set diff --git a/arch/ppc/configs/est8260_defconfig b/arch/ppc/configs/est8260_defconfig index a4a44f0abdb2..6fa23e195315 100644 --- a/arch/ppc/configs/est8260_defconfig +++ b/arch/ppc/configs/est8260_defconfig @@ -2,6 +2,8 @@ # Automatically generated make config: don't edit # # CONFIG_UID16 is not set +# CONFIG_RWSEM_GENERIC_SPINLOCK is not set +CONFIG_RWSEM_XCHGADD_ALGORITHM=y # # Code maturity level options @@ -34,7 +36,6 @@ CONFIG_MACH_SPECIFIC=y # General setup # # CONFIG_HIGHMEM is not set -# CONFIG_MOL is not set # CONFIG_ISA is not set # CONFIG_EISA is not set # CONFIG_SBUS is not set @@ -93,7 +94,6 @@ CONFIG_BLK_DEV_INITRD=y # CONFIG_MD_RAID1 is not set # CONFIG_MD_RAID5 is not set # CONFIG_BLK_DEV_LVM is not set -# CONFIG_LVM_PROC_FS is not set # # Networking options @@ -177,6 +177,7 @@ CONFIG_NET_ETHERNET=y # CONFIG_MACE is not set # CONFIG_BMAC is not set # CONFIG_GMAC is not set +# CONFIG_NCR885E is not set # CONFIG_OAKNET is not set # CONFIG_NET_VENDOR_3COM is not set # CONFIG_LANCE is not set @@ -317,6 +318,8 @@ CONFIG_UNIX98_PTY_COUNT=256 # CONFIG_QUOTA is not set # CONFIG_AUTOFS_FS is not set # CONFIG_AUTOFS4_FS is not set +# CONFIG_REISERFS_FS is not set +# CONFIG_REISERFS_CHECK is not set # CONFIG_ADFS_FS is not set # CONFIG_ADFS_FS_RW is not set # CONFIG_AFFS_FS is not set @@ -329,6 +332,7 @@ CONFIG_UNIX98_PTY_COUNT=256 # CONFIG_EFS_FS is not set # CONFIG_JFFS_FS is not set # CONFIG_CRAMFS is not set +CONFIG_TMPFS=y # CONFIG_RAMFS is not set # CONFIG_ISO9660_FS is not set # CONFIG_JOLIET is not set diff --git a/arch/ppc/configs/gemini_defconfig b/arch/ppc/configs/gemini_defconfig new file mode 100644 index 000000000000..e2dc5ad72b6d --- /dev/null +++ b/arch/ppc/configs/gemini_defconfig @@ -0,0 +1,510 @@ +# +# Automatically generated make config: don't edit +# +# CONFIG_UID16 is not set +# CONFIG_RWSEM_GENERIC_SPINLOCK is not set +CONFIG_RWSEM_XCHGADD_ALGORITHM=y + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y + +# +# Loadable module support +# +CONFIG_MODULES=y +# CONFIG_MODVERSIONS is not set +CONFIG_KMOD=y + +# +# Platform support +# +CONFIG_PPC=y +CONFIG_6xx=y +# CONFIG_4xx is not set +# CONFIG_POWER3 is not set +# CONFIG_POWER4 is not set +# CONFIG_8xx is not set +# CONFIG_8260 is not set +# CONFIG_ALL_PPC is not set +CONFIG_GEMINI=y +# CONFIG_APUS is not set +# CONFIG_PPC601_SYNC_FIX is not set +# CONFIG_SMP is not set +CONFIG_ALTIVEC=y +CONFIG_MACH_SPECIFIC=y + +# +# General setup +# +# CONFIG_HIGHMEM is not set +# CONFIG_ISA is not set +# CONFIG_EISA is not set +# CONFIG_SBUS is not set +# CONFIG_MCA is not set +CONFIG_PCI=y +CONFIG_NET=y +CONFIG_SYSCTL=y +CONFIG_SYSVIPC=y +# CONFIG_BSD_PROCESS_ACCT is not set +CONFIG_KCORE_ELF=y +CONFIG_BINFMT_ELF=y +CONFIG_KERNEL_ELF=y +# CONFIG_BINFMT_MISC is not set +CONFIG_PCI_NAMES=y +# CONFIG_HOTPLUG is not set +# CONFIG_PCMCIA is not set + +# +# Parallel port support +# +# CONFIG_PARPORT is not set +# CONFIG_PPC_RTC is not set + +# +# Memory Technology Devices (MTD) +# +# CONFIG_MTD is not set + +# +# Plug and Play configuration +# +# CONFIG_PNP is not set +# CONFIG_ISAPNP is not set + +# +# Block devices +# +# CONFIG_BLK_DEV_FD is not set +# CONFIG_BLK_DEV_XD is not set +# CONFIG_PARIDE is not set +# CONFIG_BLK_CPQ_DA is not set +# CONFIG_BLK_CPQ_CISS_DA is not set +# CONFIG_BLK_DEV_DAC960 is not set +# CONFIG_BLK_DEV_LOOP is not set +# CONFIG_BLK_DEV_NBD is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_SIZE=4096 +CONFIG_BLK_DEV_INITRD=y + +# +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set +# CONFIG_BLK_DEV_MD is not set +# CONFIG_MD_LINEAR is not set +# CONFIG_MD_RAID0 is not set +# CONFIG_MD_RAID1 is not set +# CONFIG_MD_RAID5 is not set +# CONFIG_BLK_DEV_LVM is not set + +# +# Networking options +# +CONFIG_PACKET=y +# CONFIG_PACKET_MMAP is not set +CONFIG_NETLINK=y +# CONFIG_RTNETLINK is not set +# CONFIG_NETLINK_DEV is not set +CONFIG_NETFILTER=y +# CONFIG_NETFILTER_DEBUG is not set +# CONFIG_FILTER is not set +CONFIG_UNIX=y +CONFIG_INET=y +# CONFIG_IP_MULTICAST is not set +# CONFIG_IP_ADVANCED_ROUTER is not set +# CONFIG_IP_PNP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_INET_ECN is not set +# CONFIG_SYN_COOKIES is not set + +# +# IP: Netfilter Configuration +# +# CONFIG_IP_NF_CONNTRACK is not set +# CONFIG_IP_NF_QUEUE is not set +# CONFIG_IP_NF_IPTABLES is not set +# CONFIG_IP_NF_COMPAT_IPCHAINS is not set +# CONFIG_IP_NF_COMPAT_IPFWADM is not set +# CONFIG_IPV6 is not set +# CONFIG_KHTTPD is not set +# CONFIG_ATM is not set + +# +# +# +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_DECNET is not set +# CONFIG_BRIDGE is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_LLC is not set +# CONFIG_NET_DIVERT is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set +# CONFIG_NET_FASTROUTE is not set +# CONFIG_NET_HW_FLOWCONTROL is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set + +# +# ATA/IDE/MFM/RLL support +# +# CONFIG_IDE is not set +# CONFIG_BLK_DEV_IDE_MODES is not set +# CONFIG_BLK_DEV_HD is not set + +# +# SCSI support +# +CONFIG_SCSI=y + +# +# SCSI support type (disk, tape, CD-ROM) +# +CONFIG_BLK_DEV_SD=y +CONFIG_SD_EXTRA_DEVS=40 +# CONFIG_CHR_DEV_ST is not set +# CONFIG_CHR_DEV_OSST is not set +CONFIG_BLK_DEV_SR=y +CONFIG_BLK_DEV_SR_VENDOR=y +CONFIG_SR_EXTRA_DEVS=2 +CONFIG_CHR_DEV_SG=y + +# +# Some SCSI devices (e.g. CD jukebox) support multiple LUNs +# +# CONFIG_SCSI_DEBUG_QUEUES is not set +# CONFIG_SCSI_MULTI_LUN is not set +CONFIG_SCSI_CONSTANTS=y +# CONFIG_SCSI_LOGGING is not set + +# +# SCSI low-level drivers +# +# CONFIG_BLK_DEV_3W_XXXX_RAID is not set +# CONFIG_SCSI_7000FASST is not set +# CONFIG_SCSI_ACARD is not set +# CONFIG_SCSI_AHA152X is not set +# CONFIG_SCSI_AHA1542 is not set +# CONFIG_SCSI_AHA1740 is not set +# CONFIG_SCSI_AIC7XXX is not set +# CONFIG_SCSI_AIC7XXX_OLD is not set +# CONFIG_SCSI_ADVANSYS is not set +# CONFIG_SCSI_IN2000 is not set +# CONFIG_SCSI_AM53C974 is not set +# CONFIG_SCSI_MEGARAID is not set +# CONFIG_SCSI_BUSLOGIC is not set +# CONFIG_SCSI_CPQFCTS is not set +# CONFIG_SCSI_DMX3191D is not set +# CONFIG_SCSI_DTC3280 is not set +# CONFIG_SCSI_EATA is not set +# CONFIG_SCSI_EATA_DMA is not set +# CONFIG_SCSI_EATA_PIO is not set +# CONFIG_SCSI_FUTURE_DOMAIN is not set +# CONFIG_SCSI_GDTH is not set +# CONFIG_SCSI_GENERIC_NCR5380 is not set +# CONFIG_SCSI_INITIO is not set +# CONFIG_SCSI_INIA100 is not set +# CONFIG_SCSI_NCR53C406A is not set +# CONFIG_SCSI_NCR53C7xx is not set +# CONFIG_SCSI_NCR53C8XX is not set +CONFIG_SCSI_SYM53C8XX=y +CONFIG_SCSI_NCR53C8XX_DEFAULT_TAGS=8 +CONFIG_SCSI_NCR53C8XX_MAX_TAGS=32 +CONFIG_SCSI_NCR53C8XX_SYNC=20 +# CONFIG_SCSI_NCR53C8XX_PROFILE is not set +# CONFIG_SCSI_NCR53C8XX_IOMAPPED is not set +# CONFIG_SCSI_NCR53C8XX_PQS_PDS is not set +# CONFIG_SCSI_NCR53C8XX_SYMBIOS_COMPAT is not set +# CONFIG_SCSI_PAS16 is not set +# CONFIG_SCSI_PCI2000 is not set +# CONFIG_SCSI_PCI2220I is not set +# CONFIG_SCSI_PSI240I is not set +# CONFIG_SCSI_QLOGIC_FAS is not set +# CONFIG_SCSI_QLOGIC_ISP is not set +# CONFIG_SCSI_QLOGIC_FC is not set +# CONFIG_SCSI_QLOGIC_1280 is not set +# CONFIG_SCSI_SIM710 is not set +# CONFIG_SCSI_SYM53C416 is not set +# CONFIG_SCSI_DC390T is not set +# CONFIG_SCSI_T128 is not set +# CONFIG_SCSI_U14_34F is not set +# CONFIG_SCSI_DEBUG is not set +# CONFIG_SCSI_MESH is not set +# CONFIG_SCSI_MAC53C94 is not set + +# +# IEEE 1394 (FireWire) support +# +# CONFIG_IEEE1394 is not set + +# +# Network device support +# +CONFIG_NETDEVICES=y + +# +# ARCnet devices +# +# CONFIG_ARCNET is not set +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set +# CONFIG_ETHERTAP is not set +# CONFIG_NET_SB1000 is not set + +# +# Ethernet (10 or 100Mbit) +# +CONFIG_NET_ETHERNET=y +# CONFIG_MACE is not set +# CONFIG_BMAC is not set +# CONFIG_GMAC is not set +CONFIG_NCR885E=y +# CONFIG_OAKNET is not set +# CONFIG_NET_VENDOR_3COM is not set +# CONFIG_LANCE is not set +# CONFIG_NET_VENDOR_SMC is not set +# CONFIG_NET_VENDOR_RACAL is not set +# CONFIG_AT1700 is not set +# CONFIG_DEPCA is not set +# CONFIG_HP100 is not set +# CONFIG_NET_ISA is not set +# CONFIG_NET_PCI is not set +# CONFIG_NET_POCKET is not set + +# +# Ethernet (1000 Mbit) +# +# CONFIG_ACENIC is not set +# CONFIG_HAMACHI is not set +# CONFIG_YELLOWFIN is not set +# CONFIG_SK98LIN is not set +# CONFIG_FDDI is not set +# CONFIG_HIPPI is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set + +# +# Wireless LAN (non-hamradio) +# +# CONFIG_NET_RADIO is not set + +# +# Token Ring devices +# +# CONFIG_TR is not set +# CONFIG_NET_FC is not set +# CONFIG_RCPCI is not set +# CONFIG_SHAPER is not set + +# +# Wan interfaces +# +# CONFIG_WAN is not set + +# +# Amateur Radio support +# +# CONFIG_HAMRADIO is not set + +# +# IrDA (infrared) support +# +# CONFIG_IRDA is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN is not set + +# +# Old CD-ROM drivers (not SCSI, not IDE) +# +# CONFIG_CD_NO_IDESCSI is not set + +# +# Console drivers +# +# CONFIG_VGA_CONSOLE is not set + +# +# Frame-buffer support +# +# CONFIG_FB is not set + +# +# Input core support +# +# CONFIG_INPUT is not set + +# +# Macintosh device drivers +# + +# +# Character devices +# +CONFIG_VT=y +CONFIG_VT_CONSOLE=y +CONFIG_SERIAL=y +CONFIG_SERIAL_CONSOLE=y +# CONFIG_SERIAL_EXTENDED is not set +# CONFIG_SERIAL_NONSTANDARD is not set +CONFIG_UNIX98_PTYS=y +CONFIG_UNIX98_PTY_COUNT=256 + +# +# I2C support +# +# CONFIG_I2C is not set + +# +# Mice +# +# CONFIG_BUSMOUSE is not set +# CONFIG_MOUSE is not set + +# +# Joysticks +# +# CONFIG_JOYSTICK is not set + +# +# Input core support is needed for joysticks +# +# CONFIG_QIC02_TAPE is not set + +# +# Watchdog Cards +# +# CONFIG_WATCHDOG is not set +# CONFIG_INTEL_RNG is not set +# CONFIG_NVRAM is not set +# CONFIG_RTC is not set +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set +# CONFIG_APPLICOM is not set + +# +# Ftape, the floppy tape device driver +# +# CONFIG_FTAPE is not set +# CONFIG_AGP is not set +# CONFIG_DRM is not set + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# File systems +# +# CONFIG_QUOTA is not set +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set +# CONFIG_REISERFS_FS is not set +# CONFIG_REISERFS_CHECK is not set +# CONFIG_ADFS_FS is not set +# CONFIG_ADFS_FS_RW is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_FAT_FS is not set +# CONFIG_MSDOS_FS is not set +# CONFIG_UMSDOS_FS is not set +# CONFIG_VFAT_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_JFFS_FS is not set +# CONFIG_CRAMFS is not set +CONFIG_TMPFS=y +# CONFIG_RAMFS is not set +CONFIG_ISO9660_FS=y +# CONFIG_JOLIET is not set +# CONFIG_MINIX_FS is not set +# CONFIG_NTFS_FS is not set +# CONFIG_NTFS_RW is not set +# CONFIG_HPFS_FS is not set +CONFIG_PROC_FS=y +CONFIG_DEVFS_FS=y +# CONFIG_DEVFS_MOUNT is not set +# CONFIG_DEVFS_DEBUG is not set +CONFIG_DEVPTS_FS=y +# CONFIG_QNX4FS_FS is not set +# CONFIG_QNX4FS_RW is not set +# CONFIG_ROMFS_FS is not set +CONFIG_EXT2_FS=y +# CONFIG_SYSV_FS is not set +# CONFIG_SYSV_FS_WRITE is not set +# CONFIG_UDF_FS is not set +# CONFIG_UDF_RW is not set +# CONFIG_UFS_FS is not set +# CONFIG_UFS_FS_WRITE is not set + +# +# Network File Systems +# +# CONFIG_CODA_FS is not set +CONFIG_NFS_FS=y +# CONFIG_NFS_V3 is not set +# CONFIG_ROOT_NFS is not set +CONFIG_NFSD=y +# CONFIG_NFSD_V3 is not set +CONFIG_SUNRPC=y +CONFIG_LOCKD=y +# CONFIG_SMB_FS is not set +# CONFIG_NCP_FS is not set +# CONFIG_NCPFS_PACKET_SIGNING is not set +# CONFIG_NCPFS_IOCTL_LOCKING is not set +# CONFIG_NCPFS_STRONG is not set +# CONFIG_NCPFS_NFS_NS is not set +# CONFIG_NCPFS_OS2_NS is not set +# CONFIG_NCPFS_SMALLDOS is not set +# CONFIG_NCPFS_NLS is not set +# CONFIG_NCPFS_EXTRAS is not set + +# +# Partition Types +# +CONFIG_PARTITION_ADVANCED=y +# CONFIG_ACORN_PARTITION is not set +# CONFIG_OSF_PARTITION is not set +# CONFIG_AMIGA_PARTITION is not set +# CONFIG_ATARI_PARTITION is not set +# CONFIG_MAC_PARTITION is not set +CONFIG_MSDOS_PARTITION=y +# CONFIG_BSD_DISKLABEL is not set +# CONFIG_MINIX_SUBPARTITION is not set +CONFIG_SOLARIS_X86_PARTITION=y +# CONFIG_UNIXWARE_DISKLABEL is not set +# CONFIG_SGI_PARTITION is not set +# CONFIG_ULTRIX_PARTITION is not set +# CONFIG_SUN_PARTITION is not set +# CONFIG_SMB_NLS is not set +# CONFIG_NLS is not set + +# +# Sound +# +# CONFIG_SOUND is not set + +# +# USB support +# +# CONFIG_USB is not set + +# +# Kernel hacking +# +CONFIG_MAGIC_SYSRQ=y +# CONFIG_KGDB is not set +CONFIG_XMON=y diff --git a/arch/ppc/configs/ibmchrp_defconfig b/arch/ppc/configs/ibmchrp_defconfig index 652b94209823..f9b88286e944 100644 --- a/arch/ppc/configs/ibmchrp_defconfig +++ b/arch/ppc/configs/ibmchrp_defconfig @@ -1,7 +1,9 @@ # -# Automatically generated by make menuconfig: don't edit +# Automatically generated make config: don't edit # # CONFIG_UID16 is not set +# CONFIG_RWSEM_GENERIC_SPINLOCK is not set +CONFIG_RWSEM_XCHGADD_ALGORITHM=y # # Code maturity level options @@ -23,8 +25,8 @@ CONFIG_6xx=y # CONFIG_4xx is not set # CONFIG_POWER3 is not set # CONFIG_POWER4 is not set -# CONFIG_8260 is not set # CONFIG_8xx is not set +# CONFIG_8260 is not set CONFIG_ALL_PPC=y # CONFIG_GEMINI is not set # CONFIG_APUS is not set @@ -36,7 +38,6 @@ CONFIG_ALL_PPC=y # General setup # CONFIG_HIGHMEM=y -# CONFIG_MOL is not set # CONFIG_ISA is not set # CONFIG_EISA is not set # CONFIG_SBUS is not set @@ -101,7 +102,6 @@ CONFIG_BLK_DEV_INITRD=y # CONFIG_MD_RAID1 is not set # CONFIG_MD_RAID5 is not set # CONFIG_BLK_DEV_LVM is not set -# CONFIG_LVM_PROC_FS is not set # # Networking options @@ -137,6 +137,7 @@ CONFIG_IP_NF_MATCH_MAC=m CONFIG_IP_NF_MATCH_MARK=m CONFIG_IP_NF_MATCH_MULTIPORT=m CONFIG_IP_NF_MATCH_TOS=m +CONFIG_IP_NF_MATCH_TCPMSS=m CONFIG_IP_NF_MATCH_STATE=m CONFIG_IP_NF_MATCH_UNCLEAN=m CONFIG_IP_NF_MATCH_OWNER=m @@ -147,14 +148,20 @@ CONFIG_IP_NF_NAT=m CONFIG_IP_NF_NAT_NEEDED=y CONFIG_IP_NF_TARGET_MASQUERADE=m CONFIG_IP_NF_TARGET_REDIRECT=m +CONFIG_IP_NF_NAT_FTP=m # CONFIG_IP_NF_MANGLE is not set # CONFIG_IP_NF_TARGET_LOG is not set +CONFIG_IP_NF_TARGET_TCPMSS=m CONFIG_IP_NF_COMPAT_IPCHAINS=m CONFIG_IP_NF_NAT_NEEDED=y # CONFIG_IP_NF_COMPAT_IPFWADM is not set # CONFIG_IPV6 is not set # CONFIG_KHTTPD is not set # CONFIG_ATM is not set + +# +# +# # CONFIG_IPX is not set # CONFIG_ATALK is not set # CONFIG_DECNET is not set @@ -184,6 +191,10 @@ CONFIG_IP_NF_NAT_NEEDED=y # SCSI support # CONFIG_SCSI=y + +# +# SCSI support type (disk, tape, CD-ROM) +# CONFIG_BLK_DEV_SD=y CONFIG_SD_EXTRA_DEVS=40 CONFIG_CHR_DEV_ST=y @@ -192,6 +203,10 @@ CONFIG_BLK_DEV_SR=y CONFIG_BLK_DEV_SR_VENDOR=y CONFIG_SR_EXTRA_DEVS=2 CONFIG_CHR_DEV_SG=y + +# +# Some SCSI devices (e.g. CD jukebox) support multiple LUNs +# # CONFIG_SCSI_DEBUG_QUEUES is not set # CONFIG_SCSI_MULTI_LUN is not set CONFIG_SCSI_CONSTANTS=y @@ -207,6 +222,7 @@ CONFIG_SCSI_CONSTANTS=y # CONFIG_SCSI_AHA1542 is not set # CONFIG_SCSI_AHA1740 is not set # CONFIG_SCSI_AIC7XXX is not set +# CONFIG_SCSI_AIC7XXX_OLD is not set # CONFIG_SCSI_ADVANSYS is not set # CONFIG_SCSI_IN2000 is not set # CONFIG_SCSI_AM53C974 is not set @@ -306,7 +322,9 @@ CONFIG_DE4X5=y # CONFIG_NE3210 is not set # CONFIG_ES3210 is not set # CONFIG_8139TOO is not set -# CONFIG_RTL8129 is not set +# CONFIG_8139TOO_PIO is not set +# CONFIG_8139TOO_TUNE_TWISTER is not set +# CONFIG_8139TOO_8129 is not set # CONFIG_SIS900 is not set # CONFIG_EPIC100 is not set # CONFIG_SUNDANCE is not set @@ -337,11 +355,9 @@ CONFIG_DE4X5=y # Token Ring devices # CONFIG_TR=y -# CONFIG_IBMTR is not set CONFIG_IBMOL=y # CONFIG_IBMLS is not set # CONFIG_TMS380TR is not set -# CONFIG_SMCTR is not set # CONFIG_NET_FC is not set # CONFIG_RCPCI is not set # CONFIG_SHAPER is not set @@ -393,6 +409,7 @@ CONFIG_FB_OF=y # CONFIG_FB_IMSTT is not set # CONFIG_FB_S3TRIO is not set # CONFIG_FB_VGA16 is not set +# CONFIG_FB_E1355 is not set CONFIG_FB_MATROX=y CONFIG_FB_MATROX_MILLENIUM=y CONFIG_FB_MATROX_MYSTIQUE=y @@ -439,6 +456,7 @@ CONFIG_INPUT_EVDEV=y # CONFIG_MAC_FLOPPY is not set # CONFIG_MAC_SERIAL is not set # CONFIG_ADB is not set +CONFIG_MAC_HID=y # # Character devices @@ -473,6 +491,10 @@ CONFIG_PSMOUSE=y # Joysticks # # CONFIG_JOYSTICK is not set + +# +# Input core support is needed for joysticks +# # CONFIG_QIC02_TAPE is not set # @@ -504,6 +526,8 @@ CONFIG_RTC=y # CONFIG_QUOTA is not set # CONFIG_AUTOFS_FS is not set # CONFIG_AUTOFS4_FS is not set +# CONFIG_REISERFS_FS is not set +# CONFIG_REISERFS_CHECK is not set # CONFIG_ADFS_FS is not set # CONFIG_ADFS_FS_RW is not set # CONFIG_AFFS_FS is not set @@ -516,6 +540,7 @@ CONFIG_VFAT_FS=m # CONFIG_EFS_FS is not set # CONFIG_JFFS_FS is not set # CONFIG_CRAMFS is not set +CONFIG_TMPFS=y # CONFIG_RAMFS is not set CONFIG_ISO9660_FS=y # CONFIG_JOLIET is not set @@ -572,6 +597,7 @@ CONFIG_PARTITION_ADVANCED=y CONFIG_MAC_PARTITION=y CONFIG_MSDOS_PARTITION=y # CONFIG_BSD_DISKLABEL is not set +# CONFIG_MINIX_SUBPARTITION is not set # CONFIG_SOLARIS_X86_PARTITION is not set # CONFIG_UNIXWARE_DISKLABEL is not set # CONFIG_SGI_PARTITION is not set @@ -599,11 +625,13 @@ CONFIG_NLS_DEFAULT="iso8859-1" # CONFIG_NLS_CODEPAGE_865 is not set # CONFIG_NLS_CODEPAGE_866 is not set # CONFIG_NLS_CODEPAGE_869 is not set -# CONFIG_NLS_CODEPAGE_874 is not set -# CONFIG_NLS_CODEPAGE_932 is not set # CONFIG_NLS_CODEPAGE_936 is not set -# CONFIG_NLS_CODEPAGE_949 is not set # CONFIG_NLS_CODEPAGE_950 is not set +# CONFIG_NLS_CODEPAGE_932 is not set +# CONFIG_NLS_CODEPAGE_949 is not set +# CONFIG_NLS_CODEPAGE_874 is not set +# CONFIG_NLS_ISO8859_8 is not set +# CONFIG_NLS_CODEPAGE_1251 is not set # CONFIG_NLS_ISO8859_1 is not set # CONFIG_NLS_ISO8859_2 is not set # CONFIG_NLS_ISO8859_3 is not set @@ -611,11 +639,12 @@ CONFIG_NLS_DEFAULT="iso8859-1" # CONFIG_NLS_ISO8859_5 is not set # CONFIG_NLS_ISO8859_6 is not set # CONFIG_NLS_ISO8859_7 is not set -# CONFIG_NLS_ISO8859_8 is not set # CONFIG_NLS_ISO8859_9 is not set +# CONFIG_NLS_ISO8859_13 is not set # CONFIG_NLS_ISO8859_14 is not set # CONFIG_NLS_ISO8859_15 is not set # CONFIG_NLS_KOI8_R is not set +# CONFIG_NLS_KOI8_U is not set # CONFIG_NLS_UTF8 is not set # diff --git a/arch/ppc/configs/mbx_defconfig b/arch/ppc/configs/mbx_defconfig index 81829327a3ad..b98e1df70e23 100644 --- a/arch/ppc/configs/mbx_defconfig +++ b/arch/ppc/configs/mbx_defconfig @@ -2,6 +2,8 @@ # Automatically generated make config: don't edit # # CONFIG_UID16 is not set +# CONFIG_RWSEM_GENERIC_SPINLOCK is not set +CONFIG_RWSEM_XCHGADD_ALGORITHM=y # # Code maturity level options @@ -26,9 +28,15 @@ CONFIG_SERIAL_CONSOLE=y # CONFIG_RPXLITE is not set # CONFIG_RPXCLASSIC is not set # CONFIG_BSEIP is not set -# CONFIG_TQM8xxL is not set +# CONFIG_TQM823L is not set +# CONFIG_TQM850L is not set +# CONFIG_TQM855L is not set # CONFIG_TQM860L is not set +# CONFIG_FPS850L is not set # CONFIG_TQM860 is not set +# CONFIG_SPD823TS is not set +# CONFIG_IVMS8 is not set +# CONFIG_SM850 is not set CONFIG_MBX=y # CONFIG_WINCEPT is not set CONFIG_PPC601_SYNC_FIX=y @@ -41,7 +49,6 @@ CONFIG_MATH_EMULATION=y # General setup # # CONFIG_HIGHMEM is not set -# CONFIG_MOL is not set # CONFIG_ISA is not set # CONFIG_EISA is not set # CONFIG_SBUS is not set @@ -99,7 +106,6 @@ CONFIG_KERNEL_ELF=y # CONFIG_MD_RAID1 is not set # CONFIG_MD_RAID5 is not set # CONFIG_BLK_DEV_LVM is not set -# CONFIG_LVM_PROC_FS is not set # # Networking options @@ -178,6 +184,7 @@ CONFIG_NET_ETHERNET=y # CONFIG_MACE is not set # CONFIG_BMAC is not set # CONFIG_GMAC is not set +# CONFIG_NCR885E is not set # CONFIG_OAKNET is not set # CONFIG_NET_VENDOR_3COM is not set # CONFIG_LANCE is not set @@ -316,6 +323,8 @@ CONFIG_NET_ETHERNET=y # CONFIG_QUOTA is not set # CONFIG_AUTOFS_FS is not set # CONFIG_AUTOFS4_FS is not set +# CONFIG_REISERFS_FS is not set +# CONFIG_REISERFS_CHECK is not set # CONFIG_ADFS_FS is not set # CONFIG_ADFS_FS_RW is not set # CONFIG_AFFS_FS is not set @@ -328,6 +337,7 @@ CONFIG_NET_ETHERNET=y # CONFIG_EFS_FS is not set # CONFIG_JFFS_FS is not set # CONFIG_CRAMFS is not set +CONFIG_TMPFS=y # CONFIG_RAMFS is not set # CONFIG_ISO9660_FS is not set # CONFIG_JOLIET is not set @@ -399,11 +409,14 @@ CONFIG_PARTITION_ADVANCED=y # CONFIG_SCC_ENET=y CONFIG_SCC1_ENET=y +# CONFIG_SCC2_ENET is not set +# CONFIG_SCC3_ENET is not set # CONFIG_FEC_ENET is not set CONFIG_ENET_BIG_BUFFERS=y -CONFIG_8xxSMC2=y -# CONFIG_8xx_ALTSMC2 is not set -CONFIG_8xxSCC=y +CONFIG_SMC2_UART=y +# CONFIG_ALTSMC2 is not set +# CONFIG_CONS_SMC2 is not set +CONFIG_USE_SCC_IO=y # # Generic MPC8xx Options diff --git a/arch/ppc/configs/oak_defconfig b/arch/ppc/configs/oak_defconfig index d8f39c36e220..11fb7069a809 100644 --- a/arch/ppc/configs/oak_defconfig +++ b/arch/ppc/configs/oak_defconfig @@ -2,6 +2,8 @@ # Automatically generated make config: don't edit # # CONFIG_UID16 is not set +# CONFIG_RWSEM_GENERIC_SPINLOCK is not set +CONFIG_RWSEM_XCHGADD_ALGORITHM=y # # Code maturity level options @@ -35,7 +37,6 @@ CONFIG_MACH_SPECIFIC=y # General setup # # CONFIG_HIGHMEM is not set -# CONFIG_MOL is not set # CONFIG_ISA is not set # CONFIG_EISA is not set # CONFIG_SBUS is not set @@ -93,7 +94,6 @@ CONFIG_BLK_DEV_INITRD=y # CONFIG_MD_RAID1 is not set # CONFIG_MD_RAID5 is not set # CONFIG_BLK_DEV_LVM is not set -# CONFIG_LVM_PROC_FS is not set # # Networking options @@ -173,6 +173,7 @@ CONFIG_NET_ETHERNET=y # CONFIG_MACE is not set # CONFIG_BMAC is not set # CONFIG_GMAC is not set +# CONFIG_NCR885E is not set CONFIG_OAKNET=y # CONFIG_NET_VENDOR_3COM is not set # CONFIG_LANCE is not set @@ -312,6 +313,8 @@ CONFIG_SERIAL_CONSOLE=y # CONFIG_QUOTA is not set # CONFIG_AUTOFS_FS is not set # CONFIG_AUTOFS4_FS is not set +# CONFIG_REISERFS_FS is not set +# CONFIG_REISERFS_CHECK is not set # CONFIG_ADFS_FS is not set # CONFIG_ADFS_FS_RW is not set # CONFIG_AFFS_FS is not set @@ -324,6 +327,7 @@ CONFIG_SERIAL_CONSOLE=y # CONFIG_EFS_FS is not set # CONFIG_JFFS_FS is not set # CONFIG_CRAMFS is not set +CONFIG_TMPFS=y # CONFIG_RAMFS is not set # CONFIG_ISO9660_FS is not set # CONFIG_JOLIET is not set diff --git a/arch/ppc/configs/power3_defconfig b/arch/ppc/configs/power3_defconfig index 0deb9b5e8862..14439715abca 100644 --- a/arch/ppc/configs/power3_defconfig +++ b/arch/ppc/configs/power3_defconfig @@ -1,7 +1,9 @@ # -# Automatically generated by make menuconfig: don't edit +# Automatically generated make config: don't edit # # CONFIG_UID16 is not set +# CONFIG_RWSEM_GENERIC_SPINLOCK is not set +CONFIG_RWSEM_XCHGADD_ALGORITHM=y # # Code maturity level options @@ -27,12 +29,12 @@ CONFIG_POWER3=y CONFIG_PPC64BRIDGE=y CONFIG_ALL_PPC=y CONFIG_SMP=y +# CONFIG_IRQ_ALL_CPUS is not set # # General setup # CONFIG_HIGHMEM=y -# CONFIG_MOL is not set # CONFIG_ISA is not set # CONFIG_EISA is not set # CONFIG_SBUS is not set @@ -105,10 +107,7 @@ CONFIG_MD_LINEAR=y CONFIG_MD_RAID0=y CONFIG_MD_RAID1=y CONFIG_MD_RAID5=y -# CONFIG_MD_BOOT is not set -# CONFIG_AUTODETECT_RAID is not set CONFIG_BLK_DEV_LVM=y -CONFIG_LVM_PROC_FS=y # # Networking options @@ -133,6 +132,10 @@ CONFIG_SYN_COOKIES=y # CONFIG_IPV6 is not set # CONFIG_KHTTPD is not set # CONFIG_ATM is not set + +# +# +# # CONFIG_IPX is not set # CONFIG_ATALK is not set # CONFIG_DECNET is not set @@ -162,6 +165,10 @@ CONFIG_SYN_COOKIES=y # SCSI support # CONFIG_SCSI=y + +# +# SCSI support type (disk, tape, CD-ROM) +# CONFIG_BLK_DEV_SD=y CONFIG_SD_EXTRA_DEVS=40 CONFIG_CHR_DEV_ST=y @@ -170,6 +177,10 @@ CONFIG_BLK_DEV_SR=y CONFIG_BLK_DEV_SR_VENDOR=y CONFIG_SR_EXTRA_DEVS=2 CONFIG_CHR_DEV_SG=y + +# +# Some SCSI devices (e.g. CD jukebox) support multiple LUNs +# # CONFIG_SCSI_DEBUG_QUEUES is not set # CONFIG_SCSI_MULTI_LUN is not set CONFIG_SCSI_CONSTANTS=y @@ -185,6 +196,7 @@ CONFIG_SCSI_LOGGING=y # CONFIG_SCSI_AHA1542 is not set # CONFIG_SCSI_AHA1740 is not set # CONFIG_SCSI_AIC7XXX is not set +# CONFIG_SCSI_AIC7XXX_OLD is not set # CONFIG_SCSI_ADVANSYS is not set # CONFIG_SCSI_IN2000 is not set # CONFIG_SCSI_AM53C974 is not set @@ -259,6 +271,7 @@ CONFIG_NET_ETHERNET=y # CONFIG_MACE is not set # CONFIG_BMAC is not set # CONFIG_GMAC is not set +# CONFIG_NCR885E is not set # CONFIG_OAKNET is not set # CONFIG_NET_VENDOR_3COM is not set # CONFIG_LANCE is not set @@ -285,7 +298,9 @@ CONFIG_PCNET32=y # CONFIG_NE3210 is not set # CONFIG_ES3210 is not set # CONFIG_8139TOO is not set -# CONFIG_RTL8129 is not set +# CONFIG_8139TOO_PIO is not set +# CONFIG_8139TOO_TUNE_TWISTER is not set +# CONFIG_8139TOO_8129 is not set # CONFIG_SIS900 is not set # CONFIG_EPIC100 is not set # CONFIG_SUNDANCE is not set @@ -317,11 +332,9 @@ CONFIG_PCNET32=y # Token Ring devices # CONFIG_TR=y -# CONFIG_IBMTR is not set CONFIG_IBMOL=y # CONFIG_IBMLS is not set # CONFIG_TMS380TR is not set -# CONFIG_SMCTR is not set # CONFIG_NET_FC is not set # CONFIG_RCPCI is not set # CONFIG_SHAPER is not set @@ -373,6 +386,7 @@ CONFIG_FB_OF=y # CONFIG_FB_IMSTT is not set # CONFIG_FB_S3TRIO is not set # CONFIG_FB_VGA16 is not set +# CONFIG_FB_E1355 is not set CONFIG_FB_MATROX=y CONFIG_FB_MATROX_MILLENIUM=y CONFIG_FB_MATROX_MYSTIQUE=y @@ -421,6 +435,7 @@ CONFIG_INPUT_EVDEV=y # CONFIG_MAC_FLOPPY is not set # CONFIG_MAC_SERIAL is not set # CONFIG_ADB is not set +CONFIG_MAC_HID=y # # Character devices @@ -462,6 +477,10 @@ CONFIG_PSMOUSE=y # Joysticks # # CONFIG_JOYSTICK is not set + +# +# Input core support is needed for joysticks +# # CONFIG_QIC02_TAPE is not set # @@ -507,6 +526,7 @@ CONFIG_VFAT_FS=y # CONFIG_EFS_FS is not set # CONFIG_JFFS_FS is not set # CONFIG_CRAMFS is not set +CONFIG_TMPFS=y # CONFIG_RAMFS is not set CONFIG_ISO9660_FS=y CONFIG_JOLIET=y @@ -579,11 +599,13 @@ CONFIG_NLS_CODEPAGE_437=y # CONFIG_NLS_CODEPAGE_865 is not set # CONFIG_NLS_CODEPAGE_866 is not set # CONFIG_NLS_CODEPAGE_869 is not set -# CONFIG_NLS_CODEPAGE_874 is not set -# CONFIG_NLS_CODEPAGE_932 is not set # CONFIG_NLS_CODEPAGE_936 is not set -# CONFIG_NLS_CODEPAGE_949 is not set # CONFIG_NLS_CODEPAGE_950 is not set +# CONFIG_NLS_CODEPAGE_932 is not set +# CONFIG_NLS_CODEPAGE_949 is not set +# CONFIG_NLS_CODEPAGE_874 is not set +# CONFIG_NLS_ISO8859_8 is not set +# CONFIG_NLS_CODEPAGE_1251 is not set CONFIG_NLS_ISO8859_1=y # CONFIG_NLS_ISO8859_2 is not set # CONFIG_NLS_ISO8859_3 is not set @@ -591,11 +613,12 @@ CONFIG_NLS_ISO8859_1=y # CONFIG_NLS_ISO8859_5 is not set # CONFIG_NLS_ISO8859_6 is not set # CONFIG_NLS_ISO8859_7 is not set -# CONFIG_NLS_ISO8859_8 is not set # CONFIG_NLS_ISO8859_9 is not set +# CONFIG_NLS_ISO8859_13 is not set # CONFIG_NLS_ISO8859_14 is not set # CONFIG_NLS_ISO8859_15 is not set # CONFIG_NLS_KOI8_R is not set +# CONFIG_NLS_KOI8_U is not set # CONFIG_NLS_UTF8 is not set # @@ -611,6 +634,8 @@ CONFIG_SOUND=y # CONFIG_SOUND_ES1371 is not set # CONFIG_SOUND_ESSSOLO1 is not set # CONFIG_SOUND_MAESTRO is not set +# CONFIG_SOUND_MAESTRO3 is not set +# CONFIG_SOUND_ICH is not set # CONFIG_SOUND_SONICVIBES is not set # CONFIG_SOUND_TRIDENT is not set # CONFIG_SOUND_MSNDCLAS is not set @@ -626,7 +651,6 @@ CONFIG_SOUND_TRACEINIT=y CONFIG_SOUND_CS4232=m # CONFIG_SOUND_SSCAPE is not set # CONFIG_SOUND_GUS is not set -# CONFIG_SOUND_ICH is not set # CONFIG_SOUND_VMIDI is not set # CONFIG_SOUND_TRIX is not set CONFIG_SOUND_MSS=m @@ -643,8 +667,8 @@ CONFIG_SOUND_MSS=m # CONFIG_SOUND_YM3812 is not set # CONFIG_SOUND_OPL3SA1 is not set # CONFIG_SOUND_OPL3SA2 is not set -# CONFIG_SOUND_YMPCI is not set # CONFIG_SOUND_YMFPCI is not set +# CONFIG_SOUND_YMFPCI_LEGACY is not set # CONFIG_SOUND_UART6850 is not set # CONFIG_SOUND_AEDSP16 is not set CONFIG_SOUND_TVMIXER=y diff --git a/arch/ppc/configs/rpxcllf_defconfig b/arch/ppc/configs/rpxcllf_defconfig index 258d3e79ffe0..3e7d6b7e869c 100644 --- a/arch/ppc/configs/rpxcllf_defconfig +++ b/arch/ppc/configs/rpxcllf_defconfig @@ -2,6 +2,8 @@ # Automatically generated make config: don't edit # # CONFIG_UID16 is not set +# CONFIG_RWSEM_GENERIC_SPINLOCK is not set +CONFIG_RWSEM_XCHGADD_ALGORITHM=y # # Code maturity level options @@ -26,9 +28,15 @@ CONFIG_SERIAL_CONSOLE=y # CONFIG_RPXLITE is not set CONFIG_RPXCLASSIC=y # CONFIG_BSEIP is not set -# CONFIG_TQM8xxL is not set +# CONFIG_TQM823L is not set +# CONFIG_TQM850L is not set +# CONFIG_TQM855L is not set # CONFIG_TQM860L is not set +# CONFIG_FPS850L is not set # CONFIG_TQM860 is not set +# CONFIG_SPD823TS is not set +# CONFIG_IVMS8 is not set +# CONFIG_SM850 is not set # CONFIG_MBX is not set # CONFIG_WINCEPT is not set CONFIG_PPC601_SYNC_FIX=y @@ -41,7 +49,6 @@ CONFIG_MATH_EMULATION=y # General setup # # CONFIG_HIGHMEM is not set -# CONFIG_MOL is not set # CONFIG_ISA is not set # CONFIG_EISA is not set # CONFIG_SBUS is not set @@ -100,7 +107,6 @@ CONFIG_BLK_DEV_INITRD=y # CONFIG_MD_RAID1 is not set # CONFIG_MD_RAID5 is not set # CONFIG_BLK_DEV_LVM is not set -# CONFIG_LVM_PROC_FS is not set # # Networking options @@ -184,6 +190,7 @@ CONFIG_NET_ETHERNET=y # CONFIG_MACE is not set # CONFIG_BMAC is not set # CONFIG_GMAC is not set +# CONFIG_NCR885E is not set # CONFIG_OAKNET is not set # CONFIG_NET_VENDOR_3COM is not set # CONFIG_LANCE is not set @@ -323,6 +330,8 @@ CONFIG_UNIX98_PTY_COUNT=256 # CONFIG_QUOTA is not set # CONFIG_AUTOFS_FS is not set # CONFIG_AUTOFS4_FS is not set +# CONFIG_REISERFS_FS is not set +# CONFIG_REISERFS_CHECK is not set # CONFIG_ADFS_FS is not set # CONFIG_ADFS_FS_RW is not set # CONFIG_AFFS_FS is not set @@ -335,6 +344,7 @@ CONFIG_UNIX98_PTY_COUNT=256 # CONFIG_EFS_FS is not set # CONFIG_JFFS_FS is not set # CONFIG_CRAMFS is not set +CONFIG_TMPFS=y # CONFIG_RAMFS is not set # CONFIG_ISO9660_FS is not set # CONFIG_JOLIET is not set @@ -406,11 +416,15 @@ CONFIG_PARTITION_ADVANCED=y # CONFIG_SCC_ENET=y CONFIG_SCC1_ENET=y +# CONFIG_SCC2_ENET is not set +# CONFIG_SCC3_ENET is not set CONFIG_FEC_ENET=y +# CONFIG_USE_MDIO is not set CONFIG_ENET_BIG_BUFFERS=y -CONFIG_8xxSMC2=y -# CONFIG_8xx_ALTSMC2 is not set -CONFIG_8xxSCC=y +CONFIG_SMC2_UART=y +# CONFIG_ALTSMC2 is not set +# CONFIG_CONS_SMC2 is not set +CONFIG_USE_SCC_IO=y # # Generic MPC8xx Options diff --git a/arch/ppc/configs/rpxlite_defconfig b/arch/ppc/configs/rpxlite_defconfig index df00f5acee75..af1dfa5ebd5e 100644 --- a/arch/ppc/configs/rpxlite_defconfig +++ b/arch/ppc/configs/rpxlite_defconfig @@ -2,6 +2,8 @@ # Automatically generated make config: don't edit # # CONFIG_UID16 is not set +# CONFIG_RWSEM_GENERIC_SPINLOCK is not set +CONFIG_RWSEM_XCHGADD_ALGORITHM=y # # Code maturity level options @@ -26,9 +28,15 @@ CONFIG_SERIAL_CONSOLE=y CONFIG_RPXLITE=y # CONFIG_RPXCLASSIC is not set # CONFIG_BSEIP is not set -# CONFIG_TQM8xxL is not set +# CONFIG_TQM823L is not set +# CONFIG_TQM850L is not set +# CONFIG_TQM855L is not set # CONFIG_TQM860L is not set +# CONFIG_FPS850L is not set # CONFIG_TQM860 is not set +# CONFIG_SPD823TS is not set +# CONFIG_IVMS8 is not set +# CONFIG_SM850 is not set # CONFIG_MBX is not set # CONFIG_WINCEPT is not set CONFIG_PPC601_SYNC_FIX=y @@ -41,7 +49,6 @@ CONFIG_MATH_EMULATION=y # General setup # # CONFIG_HIGHMEM is not set -# CONFIG_MOL is not set # CONFIG_ISA is not set # CONFIG_EISA is not set # CONFIG_SBUS is not set @@ -100,7 +107,6 @@ CONFIG_BLK_DEV_INITRD=y # CONFIG_MD_RAID1 is not set # CONFIG_MD_RAID5 is not set # CONFIG_BLK_DEV_LVM is not set -# CONFIG_LVM_PROC_FS is not set # # Networking options @@ -184,6 +190,7 @@ CONFIG_NET_ETHERNET=y # CONFIG_MACE is not set # CONFIG_BMAC is not set # CONFIG_GMAC is not set +# CONFIG_NCR885E is not set # CONFIG_OAKNET is not set # CONFIG_NET_VENDOR_3COM is not set # CONFIG_LANCE is not set @@ -323,6 +330,8 @@ CONFIG_UNIX98_PTY_COUNT=256 # CONFIG_QUOTA is not set # CONFIG_AUTOFS_FS is not set # CONFIG_AUTOFS4_FS is not set +# CONFIG_REISERFS_FS is not set +# CONFIG_REISERFS_CHECK is not set # CONFIG_ADFS_FS is not set # CONFIG_ADFS_FS_RW is not set # CONFIG_AFFS_FS is not set @@ -335,6 +344,7 @@ CONFIG_UNIX98_PTY_COUNT=256 # CONFIG_EFS_FS is not set # CONFIG_JFFS_FS is not set # CONFIG_CRAMFS is not set +CONFIG_TMPFS=y # CONFIG_RAMFS is not set # CONFIG_ISO9660_FS is not set # CONFIG_JOLIET is not set @@ -407,10 +417,11 @@ CONFIG_PARTITION_ADVANCED=y CONFIG_SCC_ENET=y # CONFIG_SCC1_ENET is not set CONFIG_SCC2_ENET=y +# CONFIG_SCC3_ENET is not set # CONFIG_FEC_ENET is not set # CONFIG_ENET_BIG_BUFFERS is not set -# CONFIG_8xxSMC2 is not set -# CONFIG_8xxSCC is not set +# CONFIG_SMC2_UART is not set +# CONFIG_USE_SCC_IO is not set # # Generic MPC8xx Options diff --git a/arch/ppc/configs/walnut_defconfig b/arch/ppc/configs/walnut_defconfig index eef439fc24e1..df7dab35a6b9 100644 --- a/arch/ppc/configs/walnut_defconfig +++ b/arch/ppc/configs/walnut_defconfig @@ -2,6 +2,8 @@ # Automatically generated make config: don't edit # # CONFIG_UID16 is not set +# CONFIG_RWSEM_GENERIC_SPINLOCK is not set +CONFIG_RWSEM_XCHGADD_ALGORITHM=y # # Code maturity level options @@ -35,7 +37,6 @@ CONFIG_MACH_SPECIFIC=y # General setup # # CONFIG_HIGHMEM is not set -# CONFIG_MOL is not set # CONFIG_ISA is not set # CONFIG_EISA is not set # CONFIG_SBUS is not set @@ -93,7 +94,6 @@ CONFIG_BLK_DEV_INITRD=y # CONFIG_MD_RAID1 is not set # CONFIG_MD_RAID5 is not set # CONFIG_BLK_DEV_LVM is not set -# CONFIG_LVM_PROC_FS is not set # # Networking options @@ -173,6 +173,7 @@ CONFIG_NET_ETHERNET=y # CONFIG_MACE is not set # CONFIG_BMAC is not set # CONFIG_GMAC is not set +# CONFIG_NCR885E is not set # CONFIG_OAKNET is not set # CONFIG_NET_VENDOR_3COM is not set # CONFIG_LANCE is not set @@ -315,6 +316,8 @@ CONFIG_I2C=y # CONFIG_QUOTA is not set # CONFIG_AUTOFS_FS is not set # CONFIG_AUTOFS4_FS is not set +# CONFIG_REISERFS_FS is not set +# CONFIG_REISERFS_CHECK is not set # CONFIG_ADFS_FS is not set # CONFIG_ADFS_FS_RW is not set # CONFIG_AFFS_FS is not set @@ -327,6 +330,7 @@ CONFIG_I2C=y # CONFIG_EFS_FS is not set # CONFIG_JFFS_FS is not set # CONFIG_CRAMFS is not set +CONFIG_TMPFS=y # CONFIG_RAMFS is not set # CONFIG_ISO9660_FS is not set # CONFIG_JOLIET is not set diff --git a/arch/ppc/defconfig b/arch/ppc/defconfig index b04451fe3250..87524bf4dd82 100644 --- a/arch/ppc/defconfig +++ b/arch/ppc/defconfig @@ -2,6 +2,8 @@ # Automatically generated make config: don't edit # # CONFIG_UID16 is not set +# CONFIG_RWSEM_GENERIC_SPINLOCK is not set +CONFIG_RWSEM_XCHGADD_ALGORITHM=y # # Code maturity level options @@ -26,6 +28,7 @@ CONFIG_6xx=y # CONFIG_8xx is not set # CONFIG_8260 is not set CONFIG_ALL_PPC=y +# CONFIG_GEMINI is not set # CONFIG_APUS is not set CONFIG_PPC601_SYNC_FIX=y # CONFIG_SMP is not set @@ -35,7 +38,6 @@ CONFIG_ALTIVEC=y # General setup # # CONFIG_HIGHMEM is not set -CONFIG_MOL=y # CONFIG_ISA is not set # CONFIG_EISA is not set # CONFIG_SBUS is not set @@ -105,7 +107,6 @@ CONFIG_BLK_DEV_INITRD=y # CONFIG_MD_RAID1 is not set # CONFIG_MD_RAID5 is not set # CONFIG_BLK_DEV_LVM is not set -# CONFIG_LVM_PROC_FS is not set # # Networking options @@ -141,6 +142,7 @@ CONFIG_IP_NF_MATCH_MAC=m CONFIG_IP_NF_MATCH_MARK=m CONFIG_IP_NF_MATCH_MULTIPORT=m CONFIG_IP_NF_MATCH_TOS=m +CONFIG_IP_NF_MATCH_TCPMSS=m CONFIG_IP_NF_MATCH_STATE=m CONFIG_IP_NF_MATCH_UNCLEAN=m CONFIG_IP_NF_MATCH_OWNER=m @@ -151,8 +153,10 @@ CONFIG_IP_NF_NAT=m CONFIG_IP_NF_NAT_NEEDED=y CONFIG_IP_NF_TARGET_MASQUERADE=m CONFIG_IP_NF_TARGET_REDIRECT=m +CONFIG_IP_NF_NAT_FTP=m # CONFIG_IP_NF_MANGLE is not set # CONFIG_IP_NF_TARGET_LOG is not set +CONFIG_IP_NF_TARGET_TCPMSS=m CONFIG_IP_NF_COMPAT_IPCHAINS=m CONFIG_IP_NF_NAT_NEEDED=y # CONFIG_IP_NF_COMPAT_IPFWADM is not set @@ -375,8 +379,10 @@ CONFIG_NETDEVICES=y # CONFIG_NET_ETHERNET=y CONFIG_MACE=y +# CONFIG_MACE_AAUI_PORT is not set CONFIG_BMAC=y CONFIG_GMAC=y +# CONFIG_NCR885E is not set # CONFIG_OAKNET is not set # CONFIG_NET_VENDOR_3COM is not set # CONFIG_LANCE is not set @@ -403,7 +409,9 @@ CONFIG_DE4X5=m # CONFIG_NE3210 is not set # CONFIG_ES3210 is not set # CONFIG_8139TOO is not set -# CONFIG_RTL8129 is not set +# CONFIG_8139TOO_PIO is not set +# CONFIG_8139TOO_TUNE_TWISTER is not set +# CONFIG_8139TOO_8129 is not set # CONFIG_SIS900 is not set # CONFIG_EPIC100 is not set # CONFIG_SUNDANCE is not set @@ -424,6 +432,7 @@ CONFIG_DE4X5=m # CONFIG_HIPPI is not set CONFIG_PPP=y CONFIG_PPP_MULTILINK=y +# CONFIG_PPP_FILTER is not set CONFIG_PPP_ASYNC=y # CONFIG_PPP_SYNC_TTY is not set CONFIG_PPP_DEFLATE=y @@ -491,6 +500,7 @@ CONFIG_FB_CT65550=y CONFIG_FB_IMSTT=y # CONFIG_FB_S3TRIO is not set # CONFIG_FB_VGA16 is not set +# CONFIG_FB_E1355 is not set CONFIG_FB_MATROX=y CONFIG_FB_MATROX_MILLENIUM=y CONFIG_FB_MATROX_MYSTIQUE=y @@ -543,6 +553,7 @@ CONFIG_ADB_MACIO=y CONFIG_INPUT_ADBHID=y CONFIG_MAC_ADBKEYCODES=y CONFIG_MAC_EMUMOUSEBTN=y +CONFIG_MAC_HID=y # # Character devices @@ -611,6 +622,8 @@ CONFIG_NVRAM=y # CONFIG_QUOTA is not set # CONFIG_AUTOFS_FS is not set # CONFIG_AUTOFS4_FS is not set +# CONFIG_REISERFS_FS is not set +# CONFIG_REISERFS_CHECK is not set # CONFIG_ADFS_FS is not set # CONFIG_ADFS_FS_RW is not set # CONFIG_AFFS_FS is not set @@ -623,6 +636,7 @@ CONFIG_VFAT_FS=m # CONFIG_EFS_FS is not set # CONFIG_JFFS_FS is not set # CONFIG_CRAMFS is not set +CONFIG_TMPFS=y # CONFIG_RAMFS is not set CONFIG_ISO9660_FS=y # CONFIG_JOLIET is not set @@ -679,6 +693,7 @@ CONFIG_PARTITION_ADVANCED=y CONFIG_MAC_PARTITION=y CONFIG_MSDOS_PARTITION=y # CONFIG_BSD_DISKLABEL is not set +# CONFIG_MINIX_SUBPARTITION is not set # CONFIG_SOLARIS_X86_PARTITION is not set # CONFIG_UNIXWARE_DISKLABEL is not set # CONFIG_SGI_PARTITION is not set @@ -706,11 +721,13 @@ CONFIG_NLS_DEFAULT="iso8859-1" # CONFIG_NLS_CODEPAGE_865 is not set # CONFIG_NLS_CODEPAGE_866 is not set # CONFIG_NLS_CODEPAGE_869 is not set -# CONFIG_NLS_CODEPAGE_874 is not set -# CONFIG_NLS_CODEPAGE_932 is not set # CONFIG_NLS_CODEPAGE_936 is not set -# CONFIG_NLS_CODEPAGE_949 is not set # CONFIG_NLS_CODEPAGE_950 is not set +# CONFIG_NLS_CODEPAGE_932 is not set +# CONFIG_NLS_CODEPAGE_949 is not set +# CONFIG_NLS_CODEPAGE_874 is not set +# CONFIG_NLS_ISO8859_8 is not set +# CONFIG_NLS_CODEPAGE_1251 is not set CONFIG_NLS_ISO8859_1=m # CONFIG_NLS_ISO8859_2 is not set # CONFIG_NLS_ISO8859_3 is not set @@ -718,11 +735,12 @@ CONFIG_NLS_ISO8859_1=m # CONFIG_NLS_ISO8859_5 is not set # CONFIG_NLS_ISO8859_6 is not set # CONFIG_NLS_ISO8859_7 is not set -# CONFIG_NLS_ISO8859_8 is not set # CONFIG_NLS_ISO8859_9 is not set +# CONFIG_NLS_ISO8859_13 is not set # CONFIG_NLS_ISO8859_14 is not set # CONFIG_NLS_ISO8859_15 is not set # CONFIG_NLS_KOI8_R is not set +# CONFIG_NLS_KOI8_U is not set # CONFIG_NLS_UTF8 is not set # @@ -739,6 +757,8 @@ CONFIG_DMASOUND=m # CONFIG_SOUND_ES1371 is not set # CONFIG_SOUND_ESSSOLO1 is not set # CONFIG_SOUND_MAESTRO is not set +# CONFIG_SOUND_MAESTRO3 is not set +# CONFIG_SOUND_ICH is not set # CONFIG_SOUND_SONICVIBES is not set # CONFIG_SOUND_TRIDENT is not set # CONFIG_SOUND_MSNDCLAS is not set @@ -813,7 +833,6 @@ CONFIG_USB_HID=y # USB Serial Converter support # CONFIG_USB_SERIAL=m -# CONFIG_USB_SERIAL_DEBUG is not set # CONFIG_USB_SERIAL_GENERIC is not set # CONFIG_USB_SERIAL_BELKIN is not set # CONFIG_USB_SERIAL_WHITEHEAT is not set @@ -821,6 +840,7 @@ CONFIG_USB_SERIAL=m # CONFIG_USB_SERIAL_EMPEG is not set # CONFIG_USB_SERIAL_FTDI_SIO is not set CONFIG_USB_SERIAL_VISOR=m +# CONFIG_USB_SERIAL_EDGEPORT is not set # CONFIG_USB_SERIAL_KEYSPAN_PDA is not set # CONFIG_USB_SERIAL_KEYSPAN is not set # CONFIG_USB_SERIAL_MCT_U232 is not set diff --git a/arch/ppc/kernel/Makefile b/arch/ppc/kernel/Makefile index c9bc4e23f397..cd66d9cd1896 100644 --- a/arch/ppc/kernel/Makefile +++ b/arch/ppc/kernel/Makefile @@ -7,12 +7,10 @@ # # Note 2! The CFLAGS definitions are now in the main makefile... +USE_STANDARD_AS_RULE := true + ifdef CONFIG_PPC64BRIDGE -.S.o: - $(CC) $(CFLAGS) -D__ASSEMBLY__ -mppc64bridge -c $< -o $*.o -else -.S.o: - $(CC) $(CFLAGS) -D__ASSEMBLY__ -c $< -o $*.o +EXTRA_AFLAGS := -Wa,-mppc64bridge endif ifeq ($(CONFIG_4xx),y) @@ -31,7 +29,7 @@ O_TARGET := kernel.o export-objs := ppc_ksyms.o prep_setup.o -obj-$(CONFIG_PPC) := entry.o traps.o irq.o idle.o time.o misc.o \ +obj-y := entry.o traps.o irq.o idle.o time.o misc.o \ process.o signal.o bitops.o ptrace.o \ ppc_htab.o semaphore.o syscalls.o \ align.o setup.o @@ -54,7 +52,7 @@ obj-$(CONFIG_8xx) += m8xx_setup.o ppc8xx_pic.o ifeq ($(CONFIG_8xx),y) obj-$(CONFIG_PCI) += qspan_pci.c else -obj-$(CONFIG_PPC) += hashtable.o +obj-y += hashtable.o endif obj-$(CONFIG_MATH_EMULATION) += softemu8xx.o obj-$(CONFIG_MBX) += i8259.o @@ -65,6 +63,8 @@ obj-$(CONFIG_ALL_PPC) += pmac_pic.o pmac_setup.o pmac_time.o prom.o \ indirect_pci.o i8259.o prep_pci.o \ prep_time.o prep_nvram.o prep_setup.o obj-$(CONFIG_PMAC_BACKLIGHT) += pmac_backlight.o +obj-$(CONFIG_GEMINI) += gemini_prom.o gemini_pci.o gemini_setup.o \ + open_pic.o obj-$(CONFIG_8260) += m8260_setup.o ppc8260_pic.o diff --git a/arch/ppc/kernel/apus_setup.c b/arch/ppc/kernel/apus_setup.c index 70a683d20087..b2f565d01a07 100644 --- a/arch/ppc/kernel/apus_setup.c +++ b/arch/ppc/kernel/apus_setup.c @@ -1017,6 +1017,59 @@ struct hw_interrupt_type amiga_irqctrl = { 0 }; +#define HARDWARE_MAPPED_SIZE (512*1024) +unsigned long __init apus_find_end_of_memory(void) +{ + int shadow = 0; + unsigned long total; + + /* The memory size reported by ADOS excludes the 512KB + reserved for PPC exception registers and possibly 512KB + containing a shadow of the ADOS ROM. */ + { + unsigned long size = memory[0].size; + + /* If 2MB aligned, size was probably user + specified. We can't tell anything about shadowing + in this case so skip shadow assignment. */ + if (0 != (size & 0x1fffff)){ + /* Align to 512KB to ensure correct handling + of both memfile and system specified + sizes. */ + size = ((size+0x0007ffff) & 0xfff80000); + /* If memory is 1MB aligned, assume + shadowing. */ + shadow = !(size & 0x80000); + } + + /* Add the chunk that ADOS does not see. by aligning + the size to the nearest 2MB limit upwards. */ + memory[0].size = ((size+0x001fffff) & 0xffe00000); + } + + total = memory[0].size; + + /* Remove the memory chunks that are controlled by special + Phase5 hardware. */ + + /* Remove the upper 512KB if it contains a shadow of + the ADOS ROM. FIXME: It might be possible to + disable this shadow HW. Check the booter + (ppc_boot.c) */ + if (shadow) + total -= HARDWARE_MAPPED_SIZE; + + /* Remove the upper 512KB where the PPC exception + vectors are mapped. */ + total -= HARDWARE_MAPPED_SIZE; + + /* Linux/APUS only handles one block of memory -- the one on + the PowerUP board. Other system memory is horrible slow in + comparison. The user can use other memory for swapping + using the z2ram device. */ + ram_phys_base = memory[0].addr; + return total; +} __init void apus_init_IRQ(void) @@ -1037,10 +1090,6 @@ void apus_init_IRQ(void) amiga_init_IRQ(); - int_control.int_sti = __no_use_sti; - int_control.int_cli = __no_use_cli; - int_control.int_save_flags = __no_use_save_flags; - int_control.int_restore_flags = __no_use_restore_flags; } __init @@ -1072,7 +1121,10 @@ void apus_init(unsigned long r3, unsigned long r4, unsigned long r5, ppc_md.irq_cannonicalize = apus_irq_cannonicalize; ppc_md.init_IRQ = apus_init_IRQ; ppc_md.get_irq = apus_get_irq; - ppc_md.post_irq = apus_post_irq; + +#error Should use the ->end() member of irq_desc[x]. -- Cort + /*ppc_md.post_irq = apus_post_irq;*/ + #ifdef CONFIG_HEARTBEAT ppc_md.heartbeat = apus_heartbeat; ppc_md.heartbeat_count = 1; @@ -1092,6 +1144,8 @@ void apus_init(unsigned long r3, unsigned long r4, unsigned long r5, ppc_md.get_rtc_time = apus_get_rtc_time; ppc_md.calibrate_decr = apus_calibrate_decr; + ppc_md.find_end_of_memory = apus_find_end_of_memory; + ppc_md.nvram_read_val = NULL; ppc_md.nvram_write_val = NULL; diff --git a/arch/ppc/kernel/bitops.c b/arch/ppc/kernel/bitops.c index 69e07057a689..527b69bd32a4 100644 --- a/arch/ppc/kernel/bitops.c +++ b/arch/ppc/kernel/bitops.c @@ -16,10 +16,10 @@ void set_bit(int nr, volatile void * addr) unsigned long mask = 1 << (nr & 0x1f); unsigned long *p = ((unsigned long *)addr) + (nr >> 5); - __asm__ __volatile__(SMP_WMB "\ -1: lwarx %0,0,%3 - or %0,%0,%2 - stwcx. %0,0,%3 + __asm__ __volatile__(SMP_WMB "\n\ +1: lwarx %0,0,%3 \n\ + or %0,%0,%2 \n\ + stwcx. %0,0,%3 \n\ bne 1b" SMP_MB : "=&r" (old), "=m" (*p) @@ -33,10 +33,10 @@ void clear_bit(int nr, volatile void *addr) unsigned long mask = 1 << (nr & 0x1f); unsigned long *p = ((unsigned long *)addr) + (nr >> 5); - __asm__ __volatile__(SMP_WMB "\ -1: lwarx %0,0,%3 - andc %0,%0,%2 - stwcx. %0,0,%3 + __asm__ __volatile__(SMP_WMB "\n\ +1: lwarx %0,0,%3 \n\ + andc %0,%0,%2 \n\ + stwcx. %0,0,%3 \n\ bne 1b" SMP_MB : "=&r" (old), "=m" (*p) @@ -50,10 +50,10 @@ void change_bit(int nr, volatile void *addr) unsigned long mask = 1 << (nr & 0x1f); unsigned long *p = ((unsigned long *)addr) + (nr >> 5); - __asm__ __volatile__(SMP_WMB "\ -1: lwarx %0,0,%3 - xor %0,%0,%2 - stwcx. %0,0,%3 + __asm__ __volatile__(SMP_WMB "\n\ +1: lwarx %0,0,%3 \n\ + xor %0,%0,%2 \n\ + stwcx. %0,0,%3 \n\ bne 1b" SMP_MB : "=&r" (old), "=m" (*p) @@ -67,10 +67,10 @@ int test_and_set_bit(int nr, volatile void *addr) unsigned int mask = 1 << (nr & 0x1f); volatile unsigned int *p = ((volatile unsigned int *)addr) + (nr >> 5); - __asm__ __volatile__(SMP_WMB "\ -1: lwarx %0,0,%4 - or %1,%0,%3 - stwcx. %1,0,%4 + __asm__ __volatile__(SMP_WMB "\n\ +1: lwarx %0,0,%4 \n\ + or %1,%0,%3 \n\ + stwcx. %1,0,%4 \n\ bne 1b" SMP_MB : "=&r" (old), "=&r" (t), "=m" (*p) @@ -86,10 +86,10 @@ int test_and_clear_bit(int nr, volatile void *addr) unsigned int mask = 1 << (nr & 0x1f); volatile unsigned int *p = ((volatile unsigned int *)addr) + (nr >> 5); - __asm__ __volatile__(SMP_WMB "\ -1: lwarx %0,0,%4 - andc %1,%0,%3 - stwcx. %1,0,%4 + __asm__ __volatile__(SMP_WMB "\n\ +1: lwarx %0,0,%4 \n\ + andc %1,%0,%3 \n\ + stwcx. %1,0,%4 \n\ bne 1b" SMP_MB : "=&r" (old), "=&r" (t), "=m" (*p) @@ -105,10 +105,10 @@ int test_and_change_bit(int nr, volatile void *addr) unsigned int mask = 1 << (nr & 0x1f); volatile unsigned int *p = ((volatile unsigned int *)addr) + (nr >> 5); - __asm__ __volatile__(SMP_WMB "\ -1: lwarx %0,0,%4 - xor %1,%0,%3 - stwcx. %1,0,%4 + __asm__ __volatile__(SMP_WMB "\n\ +1: lwarx %0,0,%4 \n\ + xor %1,%0,%3 \n\ + stwcx. %1,0,%4 \n\ bne 1b" SMP_MB : "=&r" (old), "=&r" (t), "=m" (*p) diff --git a/arch/ppc/kernel/chrp_pci.c b/arch/ppc/kernel/chrp_pci.c index 684b1889a40d..d771d644cc6e 100644 --- a/arch/ppc/kernel/chrp_pci.c +++ b/arch/ppc/kernel/chrp_pci.c @@ -264,6 +264,7 @@ chrp_pcibios_fixup(void) } } +#if 0 static struct { /* parent is iomem */ struct resource ram, pci_mem, isa_mem, pci_io, pci_cfg, rom_exp, flash; @@ -297,62 +298,7 @@ static void __init gg2_pcibios_fixup_bus(struct pci_bus *bus) { bus->resource[1] = &gg2_resources.pci_mem; } - -/* this is used by the pmac_pci code too... - paulus */ -void process_bridge_ranges(struct pci_controller *hose, - struct device_node *dev, int primary) -{ - unsigned int *ranges; - int rlen = 0; - int memno = 0; - struct resource *res; - - hose->io_base_phys = 0; - ranges = (unsigned int *) get_property(dev, "ranges", &rlen); - while ((rlen -= 6 * sizeof(unsigned int)) >= 0) { - res = NULL; - switch (ranges[0] >> 24) { - case 1: /* I/O space */ - if (ranges[2] != 0) - break; - hose->io_base_phys = ranges[3]; - hose->io_base_virt = ioremap(ranges[3], ranges[5]); - if (primary) - isa_io_base = (unsigned long) hose->io_base_virt; - res = &hose->io_resource; - res->flags = IORESOURCE_IO; - res->start = ranges[2]; - break; - case 2: /* memory space */ - memno = 0; - if (ranges[1] == 0 && ranges[2] == 0 - && ranges[5] <= (16 << 20)) { - /* 1st 16MB, i.e. ISA memory area */ - if (primary) - isa_mem_base = ranges[3]; - memno = 1; - } - while (memno < 3 && hose->mem_resources[memno].flags) - ++memno; - if (memno == 0) - hose->pci_mem_offset = ranges[3] - ranges[2]; - if (memno < 3) { - res = &hose->mem_resources[memno]; - res->flags = IORESOURCE_MEM; - res->start = ranges[3]; - } - break; - } - if (res != NULL) { - res->name = dev->full_name; - res->end = res->start + ranges[5] - 1; - res->parent = NULL; - res->sibling = NULL; - res->child = NULL; - } - ranges += 6; - } -} +#endif /* 0 */ /* this is largely modeled and stolen after the pmac_pci code -- tgall */ @@ -366,8 +312,10 @@ ibm_add_bridges(struct device_node *dev) volatile unsigned char *cfg; unsigned int *dma; #ifdef CONFIG_POWER3 - unsigned long *opprop = (unsigned long *) - get_property(find_path_device("/"), "platform-open-pic", NULL); + struct device_node *root = find_path_device("/"); + unsigned int *opprop = (unsigned int *) + get_property(root, "platform-open-pic", NULL); + int i; #endif for(; dev != NULL; dev = dev->next, ++index) { @@ -405,10 +353,11 @@ ibm_add_bridges(struct device_node *dev) hose->cfg_addr = (volatile unsigned int *) cfg; hose->cfg_data = cfg + 0x10; - process_bridge_ranges(hose, dev, index == 0); + pci_process_bridge_OF_ranges(hose, dev, index == 0); #ifdef CONFIG_POWER3 - openpic_setup_ISU(index, opprop[index+1]); + i = prom_n_addr_cells(root) * (index + 2) - 1; + openpic_setup_ISU(index, opprop[i]); #endif /* CONFIG_POWER3 */ /* check the first bridge for a property that we can @@ -442,7 +391,7 @@ power4_add_bridge(void) void __init chrp_find_bridges(void) { - struct device_node *py; + struct device_node *py, *dev; char *model, *name; struct pci_controller* hose; @@ -453,7 +402,7 @@ chrp_find_bridges(void) #else /* CONFIG_POWER4 */ model = get_property(find_path_device("/"), "model", NULL); if (!strncmp("MOT", model, 3)) { - struct pci_controller* hose; + struct pci_controller *hose; hose = pcibios_alloc_controller(); if (!hose) @@ -463,8 +412,9 @@ chrp_find_bridges(void) /* Check that please. This must be the root of the OF * PCI tree (the root host bridge */ - hose->arch_data = find_devices("pci"); + hose->arch_data = dev = find_devices("pci"); setup_grackle(hose, 0x20000); + pci_process_bridge_OF_ranges(hose, dev, 1); return; } @@ -485,25 +435,22 @@ chrp_find_bridges(void) /* Check that please. This must be the root of the OF * PCI tree (the root host bridge */ - hose->arch_data = find_devices("pci"); + hose->arch_data = dev = find_devices("pci"); name = get_property(find_path_device("/"), "name", NULL); if (!strncmp("IBM,7043-150", name, 12) || !strncmp("IBM,7046-155", name, 12) || !strncmp("IBM,7046-B50", name, 12) ) { setup_grackle(hose, 0x01000000); - isa_mem_base = 0x80000000; + pci_process_bridge_OF_ranges(hose, dev, 1); return; } /* LongTrail */ hose->ops = &gg2_pci_ops; pci_dram_offset = 0; - isa_mem_base = 0xf7000000; - hose->io_base_phys = (unsigned long) 0xf8000000; - hose->io_base_virt = ioremap(hose->io_base_phys, 0x10000); - isa_io_base = (unsigned long) hose->io_base_virt; - ppc_md.pcibios_fixup = gg2_pcibios_fixup; - ppc_md.pcibios_fixup_bus = gg2_pcibios_fixup_bus; + pci_process_bridge_OF_ranges(hose, find_devices("pci"), 1); +// ppc_md.pcibios_fixup = gg2_pcibios_fixup; +// ppc_md.pcibios_fixup_bus = gg2_pcibios_fixup_bus; #endif /* CONFIG_POWER4 */ } diff --git a/arch/ppc/kernel/chrp_setup.c b/arch/ppc/kernel/chrp_setup.c index 0ba0c6c68873..8842ab9829ff 100644 --- a/arch/ppc/kernel/chrp_setup.c +++ b/arch/ppc/kernel/chrp_setup.c @@ -67,6 +67,7 @@ void rtas_display_progress(char *, unsigned short); void rtas_indicator_progress(char *, unsigned short); void bootx_text_progress(char *, unsigned short); +extern unsigned long pmac_find_end_of_memory(void); extern int pckbd_setkeycode(unsigned int scancode, unsigned int keycode); extern int pckbd_getkeycode(unsigned int scancode); extern int pckbd_translate(unsigned char scancode, unsigned char *keycode, @@ -194,37 +195,36 @@ static void __init sio_fixup_irq(const char *name, u8 device, u8 level, u8 type) { u8 level0, type0, active; - struct device_node *root; - - root = find_path_device("/"); - if (root && - !strncmp(get_property(root, "model", NULL), "IBM,LongTrail", 13 ) ) - { - /* select logical device */ - sio_write(device, 0x07); - active = sio_read(0x30); - level0 = sio_read(0x70); - type0 = sio_read(0x71); - printk("sio: %s irq level %d, type %d, %sactive: ", name, level0, type0, - !active ? "in" : ""); - if (level0 == level && type0 == type && active) - printk("OK\n"); - else { - printk("remapping to level %d, type %d, active\n", level, type); - sio_write(0x01, 0x30); - sio_write(level, 0x70); - sio_write(type, 0x71); - } - } + /* select logical device */ + sio_write(device, 0x07); + active = sio_read(0x30); + level0 = sio_read(0x70); + type0 = sio_read(0x71); + printk("sio: %s irq level %d, type %d, %sactive: ", name, level0, + type0, !active ? "in" : ""); + if (level0 == level && type0 == type && active) + printk("OK\n"); + else { + printk("remapping to level %d, type %d, active\n", level, + type); + sio_write(0x01, 0x30); + sio_write(level, 0x70); + sio_write(type, 0x71); + } } static void __init sio_init(void) { - /* logical device 0 (KBC/Keyboard) */ - sio_fixup_irq("keyboard", 0, 1, 2); - /* select logical device 1 (KBC/Mouse) */ - sio_fixup_irq("mouse", 1, 12, 2); + struct device_node *root; + + if ((root = find_path_device("/")) && + !strncmp(get_property(root, "model", NULL), "IBM,LongTrail", 13)) { + /* logical device 0 (KBC/Keyboard) */ + sio_fixup_irq("keyboard", 0, 1, 2); + /* select logical device 1 (KBC/Mouse) */ + sio_fixup_irq("mouse", 1, 12, 2); + } } @@ -263,16 +263,19 @@ chrp_setup_arch(void) #ifndef CONFIG_POWER4 /* Some IBM machines don't have the hydra -- Cort */ - if ( !OpenPIC_Addr ) - { + if (!OpenPIC_Addr) { + struct device_node *root; unsigned long *opprop; + int n; - opprop = (unsigned long *)get_property(find_path_device("/"), - "platform-open-pic", NULL); + root = find_path_device("/"); + opprop = (unsigned long *) get_property + (root, "platform-open-pic", NULL); + n = prom_n_addr_cells(root); if (opprop != 0) { printk("OpenPIC addrs: %lx %lx %lx\n", - opprop[0], opprop[1], opprop[2]); - OpenPIC_Addr = ioremap(opprop[0], 0x40000); + opprop[n-1], opprop[2*n-1], opprop[3*n-1]); + OpenPIC_Addr = ioremap(opprop[n-1], 0x40000); } } #endif @@ -281,6 +284,10 @@ chrp_setup_arch(void) * Fix the Super I/O configuration */ sio_init(); + + /* + * Setup the console operations + */ #ifdef CONFIG_DUMMY_CONSOLE conswitchp = &dummy_con; #endif @@ -356,7 +363,7 @@ void __init chrp_init_IRQ(void) { struct device_node *np; int i; - unsigned long *addrp; + unsigned int *addrp; unsigned char* chrp_int_ack_special = 0; unsigned char init_senses[NR_IRQS - NUM_8259_INTERRUPTS]; int nmi_irq = -1; @@ -365,11 +372,12 @@ void __init chrp_init_IRQ(void) #endif if (!(np = find_devices("pci")) - || !(addrp = (unsigned long *) + || !(addrp = (unsigned int *) get_property(np, "8259-interrupt-acknowledge", NULL))) printk("Cannot find pci to get ack address\n"); else - chrp_int_ack_special = (unsigned char *)ioremap(*addrp, 1); + chrp_int_ack_special = (unsigned char *) + ioremap(addrp[prom_n_addr_cells(np)-1], 1); /* hydra still sets OpenPIC_InitSenses to a static set of values */ if (OpenPIC_InitSenses == NULL) { prom_get_irq_senses(init_senses, NUM_8259_INTERRUPTS, NR_IRQS); @@ -553,11 +561,9 @@ void __init #ifndef CONFIG_POWER4 ppc_md.init_IRQ = chrp_init_IRQ; ppc_md.get_irq = openpic_get_irq; - ppc_md.post_irq = NULL; #else ppc_md.init_IRQ = xics_init_IRQ; ppc_md.get_irq = xics_get_irq; - ppc_md.post_irq = NULL; #endif /* CONFIG_POWER4 */ ppc_md.init = chrp_init2; @@ -571,6 +577,8 @@ void __init ppc_md.get_rtc_time = chrp_get_rtc_time; ppc_md.calibrate_decr = chrp_calibrate_decr; + ppc_md.find_end_of_memory = pmac_find_end_of_memory; + #ifdef CONFIG_VT /* these are adjusted in chrp_init2 if we have an ADB keyboard */ ppc_md.kbd_setkeycode = pckbd_setkeycode; diff --git a/arch/ppc/kernel/chrp_time.c b/arch/ppc/kernel/chrp_time.c index 67325c685e49..44528597c8ec 100644 --- a/arch/ppc/kernel/chrp_time.c +++ b/arch/ppc/kernel/chrp_time.c @@ -29,6 +29,8 @@ #include #include +extern spinlock_t rtc_lock; + static int nvram_as1 = NVRAM_AS1; static int nvram_as0 = NVRAM_AS0; static int nvram_data = NVRAM_DATA; @@ -74,6 +76,7 @@ int __chrp chrp_set_rtc_time(unsigned long nowtime) unsigned char save_control, save_freq_select; struct rtc_time tm; + spin_lock(&rtc_lock); to_tm(nowtime, &tm); save_control = chrp_cmos_clock_read(RTC_CONTROL); /* tell the clock it's being set */ @@ -112,6 +115,7 @@ int __chrp chrp_set_rtc_time(unsigned long nowtime) if ( (time_state == TIME_ERROR) || (time_state == TIME_BAD) ) time_state = TIME_OK; + spin_unlock(&rtc_lock); return 0; } diff --git a/arch/ppc/kernel/entry.S b/arch/ppc/kernel/entry.S index 93bb8ca00b16..a276f33c9e92 100644 --- a/arch/ppc/kernel/entry.S +++ b/arch/ppc/kernel/entry.S @@ -30,7 +30,6 @@ #include #include #include -#include "mol.h" #undef SHOW_SYSCALLS #undef SHOW_SYSCALLS_TASK @@ -315,21 +314,12 @@ ret_from_except: lwz r5,_MSR(r1) andi. r5,r5,MSR_EE beq 2f - .globl lost_irq_ret -lost_irq_ret: -3: lis r4,ppc_n_lost_interrupts@ha - lwz r4,ppc_n_lost_interrupts@l(r4) - cmpi 0,r4,0 - beq+ 1f - addi r3,r1,STACK_FRAME_OVERHEAD - bl do_IRQ - b 3b -1: lis r4,irq_stat@ha /* &softirq_active for cpu 0 */ + lis r4,irq_stat@ha /* &softirq_active for cpu 0 */ addi r4,r4,irq_stat@l #ifdef CONFIG_SMP /* get processor # */ lwz r3,PROCESSOR(r2) - slwi r3,r3,5 + slwi r3,r3,LG_CACHE_LINE_SIZE add r4,r4,r3 #endif /* CONFIG_SMP */ lwz r5,0(r4) /* softirq_active */ @@ -351,7 +341,6 @@ do_bottom_half_ret: beq+ do_signal_ret li r3,0 addi r4,r1,STACK_FRAME_OVERHEAD - MOL_HOOK_MMU(8,r8) bl do_signal .globl do_signal_ret do_signal_ret: @@ -391,7 +380,6 @@ restore: stw r0,THREAD+KSP(r2) /* save kernel stack pointer */ tophys(r8,r1) CLR_TOP32(r8) - MOL_HOOK_MMU(9, r4) /* mod. r0,r2-r7, lr, ctr */ mtspr SPRG2,r8 /* phys exception stack pointer */ 1: lwz r3,_CTR(r1) @@ -413,29 +401,6 @@ restore: SYNC RFI -/* - * Fake an interrupt from kernel mode. - * This is used when enable_irq loses an interrupt. - * We only fill in the stack frame minimally. - */ -_GLOBAL(fake_interrupt) - mflr r0 - stw r0,4(r1) - stwu r1,-INT_FRAME_SIZE(r1) - stw r0,_NIP(r1) - stw r0,_LINK(r1) - mfmsr r3 - stw r3,_MSR(r1) - li r0,0x0fac - stw r0,TRAP(r1) - addi r3,r1,STACK_FRAME_OVERHEAD - li r4,1 - bl do_IRQ - addi r1,r1,INT_FRAME_SIZE - lwz r0,4(r1) - mtlr r0 - blr - /* * PROM code for specific machines follows. Put it diff --git a/arch/ppc/kernel/feature.c b/arch/ppc/kernel/feature.c index f22f4b1639e3..02133a70f102 100644 --- a/arch/ppc/kernel/feature.c +++ b/arch/ppc/kernel/feature.c @@ -2,17 +2,13 @@ * arch/ppc/kernel/feature.c * * Copyright (C) 1996 Paul Mackerras (paulus@cs.anu.edu.au) - * Ben. Herrenschmidt (bh40@calva.net) + * Ben. Herrenschmidt (benh@kernel.crashing.org) * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version * 2 of the License, or (at your option) any later version. * - * BenH: Changed implementation to work on multiple registers - * polarity is also taken into account. Removed delay (now - * responsibility of the caller). Added spinlocks. - * */ #include #include @@ -29,11 +25,12 @@ #include #include #include +#include +#include #undef DEBUG_FEATURE #define MAX_FEATURE_CONTROLLERS 2 -#define MAX_FEATURE_OFFSET 0x100 #define FREG(c,r) (&(((c)->reg)[(r)>>2])) /* Keylargo reg. access. */ @@ -56,9 +53,7 @@ typedef struct feature_bit { unsigned int mask; /* bit mask */ } fbit; -/* I don't have an OHare machine to test with, so I left those as they - * were. Someone with such a machine chould check out what OF says and - * try too see if they match the heathrow ones and should be changed too +/* Those features concern for OHare-based PowerBooks (2400, 3400, 3500) */ static fbit feature_bits_ohare_pbook[] = { {0x38,0,0}, /* FEATURE_null */ @@ -159,11 +154,12 @@ static fbit feature_bits_wallstreet[] = { /* * Those bits are from a 1999 G3 PowerBook, with a paddington chip. - * Mostly the same as the heathrow. + * Mostly the same as the heathrow. They are used on both PowerBooks + * and desktop machines using the paddington chip */ static fbit feature_bits_paddington[] = { {0x38,0,0}, /* FEATURE_null */ - {0x38,0,0}, /* FEATURE_Serial_reset */ + {0x38,0,PADD_RESET_SCC}, /* FEATURE_Serial_reset */ {0x38,0,HRW_SCC_ENABLE}, /* FEATURE_Serial_enable */ {0x38,0,HRW_SCCA_IO}, /* FEATURE_Serial_IO_A */ {0x38,0,HRW_SCCB_IO}, /* FEATURE_Serial_IO_B */ @@ -192,6 +188,7 @@ static fbit feature_bits_paddington[] = { }; /* Those bits are for Core99 machines (iBook,G4,iMacSL/DV,Pismo,...). + * Note: Different sets may be needed for iBook, especially for sound */ static fbit feature_bits_keylargo[] = { {0x38,0,0}, /* FEATURE_null */ @@ -201,13 +198,13 @@ static fbit feature_bits_keylargo[] = { {0x38,0,KL0_SCC_B_INTF_ENABLE}, /* FEATURE_Serial_IO_B */ {0x38,0,0}, /* FEATURE_SWIM3_enable */ {0x38,0,0}, /* FEATURE_MESH_enable */ - {0x3c,0,0}, /* FEATURE_IDE0_enable */ + {0x3c,0,KL1_EIDE0_ENABLE}, /* FEATURE_IDE0_enable */ {0x3c,1,KL1_EIDE0_RESET_N}, /* FEATURE_IDE0_reset */ {0x38,0,0}, /* FEATURE_IOBUS_enable */ - {0x34,1,0x00000200}, /* FEATURE_Mediabay_reset */ - {0x34,1,0x00000400}, /* FEATURE_Mediabay_power */ + {0x34,1,KL_MBCR_MB0_DEV_RESET}, /* FEATURE_Mediabay_reset */ + {0x34,1,KL_MBCR_MB0_DEV_POWER}, /* FEATURE_Mediabay_power */ {0x38,0,0}, /* FEATURE_Mediabay_PCI_enable */ - {0x3c,0,0x0}, /* FEATURE_IDE1_enable */ + {0x3c,0,KL1_EIDE1_ENABLE}, /* FEATURE_IDE1_enable */ {0x3c,1,KL1_EIDE1_RESET_N}, /* FEATURE_IDE1_reset */ {0x38,0,0}, /* FEATURE_Mediabay_floppy_enable */ {0x38,0,0}, /* FEATURE_BMac_reset */ @@ -216,10 +213,10 @@ static fbit feature_bits_keylargo[] = { {0x38,0,0}, /* FEATURE_Slow_SCC_PCLK */ {0x38,0,0}, /* FEATURE_Sound_Power */ {0x38,0,0}, /* FEATURE_Sound_CLK_Enable */ - {0x38,0,0}, /* FEATURE_IDE2_enable */ + {0x3c,0,KL1_UIDE_ENABLE}, /* FEATURE_IDE2_enable */ {0x3c,1,KL1_UIDE_RESET_N}, /* FEATURE_IDE2_reset */ - {0x34,0,KL_MBCR_MBDEV_ENABLE}, /* FEATURE_Mediabay_IDE_switch */ - {0x34,0,0x00000100}, /* FEATURE_Mediabay_content */ + {0x34,0,KL_MBCR_MB0_DEV_ENABLE},/* FEATURE_Mediabay_IDE_switch */ + {0x34,0,KL_MBCR_MB0_ENABLE}, /* FEATURE_Mediabay_content */ {0x40,1,KL2_AIRPORT_RESET_N}, /* FEATURE_Airport_reset */ }; @@ -238,6 +235,8 @@ feature_add_controller(struct device_node *controller_device, fbit* bits); static struct feature_controller* feature_lookup_controller(struct device_node *device); +static void uninorth_init(void); +static void keylargo_init(void); #ifdef CONFIG_PMAC_PBOOK static void heathrow_prepare_for_sleep(struct feature_controller* ctrler); static void heathrow_wakeup(struct feature_controller* ctrler); @@ -245,32 +244,80 @@ static void core99_prepare_for_sleep(struct feature_controller* ctrler); static void core99_wake_up(struct feature_controller* ctrler); #endif /* CONFIG_PMAC_PBOOK */ -static void keylargo_init(void); -static void uninorth_init(void); - /* static variables */ static struct feature_controller controllers[MAX_FEATURE_CONTROLLERS]; static int controller_count = 0; /* Core99 stuffs */ -static volatile u32* uninorth_base = NULL; -static volatile u32* keylargo_base = NULL; +/*static*/ volatile u32* uninorth_base; +static volatile u32* keylargo_base; +static struct feature_controller* keylargo; static int uninorth_rev; static int keylargo_rev; +static u32 board_features; +static u8 airport_pwr_regs[5]; +static int airport_pwr_state; +static struct device_node* airport_dev; + +#define FTR_NEED_OPENPIC_TWEAK 0x00000001 +#define FTR_CAN_NAP 0x00000002 +#define FTR_HAS_FW_POWER 0x00000004 +#define FTR_CAN_SLEEP 0x00000008 + +static struct board_features_t { + char* compatible; + u32 features; +} board_features_datas[] __init = +{ + { "AAPL,PowerMac G3", 0 }, /* Beige G3 */ + { "iMac,1", 0 }, /* First iMac (gossamer) */ + { "PowerMac1,1", 0 }, /* B&W G3 / Yikes */ + { "PowerMac1,2", 0 }, /* B&W G3 / Yikes */ + { "PowerMac2,1", FTR_CAN_SLEEP }, /* r128 based iMac */ + { "PowerMac2,2", FTR_HAS_FW_POWER|FTR_CAN_SLEEP }, /* Summer 2000 iMac */ + { "PowerMac4,1", FTR_CAN_SLEEP }, /* iMac "Flower Power" */ + { "PowerMac3,1", FTR_NEED_OPENPIC_TWEAK }, /* Sawtooth (G4) */ + { "PowerMac3,2", 0 }, /* G4/Dual G4 */ + { "PowerMac3,3", FTR_NEED_OPENPIC_TWEAK }, /* G4/Dual G4 */ + { "PowerMac5,1", 0 }, /* Cube */ + { "AAPL,3400/2400", FTR_CAN_SLEEP }, /* 2400/3400 PowerBook */ + { "AAPL,3500", FTR_CAN_SLEEP }, /* 3500 PowerBook (G3) */ + { "AAPL,PowerBook1998", FTR_CAN_SLEEP }, /* Wallstreet PowerBook */ + { "PowerBook1,1", FTR_CAN_SLEEP }, /* 101 (Lombard) PowerBook */ + { "PowerBook2,1", FTR_CAN_SLEEP }, /* iBook */ + { "PowerBook2,2", FTR_CAN_SLEEP /*| FTR_CAN_NAP*/ }, /* iBook FireWire */ + { "PowerBook3,1", FTR_CAN_SLEEP|FTR_CAN_NAP| /* PowerBook 2000 (Pismo) */ + FTR_HAS_FW_POWER }, + { "PowerBook3,2", FTR_CAN_NAP|FTR_CAN_SLEEP }, /* PowerBook Titanium */ + { "PowerBook4,1", FTR_CAN_NAP|FTR_CAN_SLEEP }, /* New polycarbonate iBook */ + { NULL, 0 } +}; + +extern unsigned long powersave_nap; -/* - * WARNING ! This function is called early in setup_arch, neither the IO base - * nor the udelay calibration have been done yet - */ void feature_init(void) { struct device_node *np; u32 *rev; - + int i; + if (_machine != _MACH_Pmac) return; + /* Figure out motherboard type & options */ + for(i=0;board_features_datas[i].compatible;i++) { + if (machine_is_compatible(board_features_datas[i].compatible)) { + board_features = board_features_datas[i].features; + break; + } + } + + /* Set default value of powersave_nap on machines that support it */ + if (board_features & FTR_CAN_NAP) + powersave_nap = 1; + + /* Track those poor mac-io's */ np = find_devices("mac-io"); while (np != NULL) { /* KeyLargo contains several (5 ?) FCR registers in mac-io, @@ -280,13 +327,25 @@ feature_init(void) struct feature_controller* ctrler = feature_add_controller(np, feature_bits_keylargo); if (ctrler) { + keylargo = ctrler; keylargo_base = ctrler->reg; rev = (u32 *)get_property(ctrler->device, "revision-id", NULL); if (rev) keylargo_rev = *rev; + + rev = (u32 *)get_property(ctrler->device, "device-id", NULL); + if (rev && (*rev) == 0x0025) + keylargo_rev |= KL_PANGEA_REV; } } else if (device_is_compatible(np, "paddington")) { feature_add_controller(np, feature_bits_paddington); + /* We disable the modem power bit on Yikes as it can + * do bad things (it's the nvram power) + */ + if (machine_is_compatible("PowerMac1,1") || + machine_is_compatible("PowerMac1,2")) { + feature_bits_paddington[FEATURE_Modem_power].mask = 0; + } } else if (machine_is_compatible("AAPL,PowerBook1998")) { feature_add_controller(np, feature_bits_wallstreet); } else { @@ -311,11 +370,12 @@ feature_init(void) } } - /* Handle core99 Uni-N */ + /* Locate core99 Uni-N */ np = find_devices("uni-n"); if (np && np->n_addrs > 0) { uninorth_base = ioremap(np->addrs[0].address, 0x1000); uninorth_rev = in_be32(UN_REG(UNI_N_VERSION)); + printk("Uninorth at 0x%08x\n", np->addrs[0].address); } if (uninorth_base && keylargo_base) printk("Uni-N revision: %d, KeyLargo revision: %d\n", @@ -360,8 +420,12 @@ feature_add_controller(struct device_node *controller_device, fbit* bits) return NULL; } + /* We remap the entire mac-io here. Normally, this will just + * give us back our already existing BAT mapping + */ controller->reg = (volatile u32 *)ioremap( - controller_device->addrs[0].address, MAX_FEATURE_OFFSET); + controller_device->addrs[0].address, + controller_device->addrs[0].size); if (bits == NULL) { printk(KERN_INFO "Twiddling the magic ohare bits\n"); @@ -495,6 +559,12 @@ feature_test(struct device_node* device, enum system_feature f) return bit->polarity ? (value == 0) : (value == bit->mask); } +int +feature_can_sleep(void) +{ + return ((board_features & FTR_CAN_SLEEP) != 0); +} + /* * Core99 functions * @@ -506,53 +576,220 @@ feature_test(struct device_node* device, enum system_feature f) void feature_set_gmac_power(struct device_node* device, int power) { - if (!uninorth_base) + unsigned long flags; + + if (!uninorth_base || !keylargo) return; + + /* TODO: Handle save/restore of PCI config space here + */ + + spin_lock_irqsave(&keylargo->lock, flags); if (power) UN_BIS(UNI_N_CLOCK_CNTL, UNI_N_CLOCK_CNTL_GMAC); else UN_BIC(UNI_N_CLOCK_CNTL, UNI_N_CLOCK_CNTL_GMAC); + spin_unlock_irqrestore(&keylargo->lock, flags); udelay(20); } void -feature_set_gmac_phy_reset(struct device_node* device, int reset) +feature_gmac_phy_reset(struct device_node* device) { - if (!keylargo_base) + unsigned long flags; + + if (!keylargo_base || !keylargo) return; - out_8((volatile u8 *)KL_FCR(KL_GPIO_ETH_PHY_RESET), reset); + + spin_lock_irqsave(&keylargo->lock, flags); + out_8((volatile u8 *)KL_FCR(KL_GPIO_ETH_PHY_RESET), + KEYLARGO_GPIO_OUTPUT_ENABLE); + (void)in_8((volatile u8 *)KL_FCR(KL_GPIO_ETH_PHY_RESET)); + spin_unlock_irqrestore(&keylargo->lock, flags); + mdelay(10); + spin_lock_irqsave(&keylargo->lock, flags); + out_8((volatile u8 *)KL_FCR(KL_GPIO_ETH_PHY_RESET), + KEYLARGO_GPIO_OUTPUT_ENABLE | KEYLARGO_GPIO_OUTOUT_DATA); (void)in_8((volatile u8 *)KL_FCR(KL_GPIO_ETH_PHY_RESET)); + spin_unlock_irqrestore(&keylargo->lock, flags); + mdelay(10); } /* Pass the node of the correct controller, please */ void feature_set_usb_power(struct device_node* device, int power) { + char* prop; + int number; + u32 reg; + + unsigned long flags; + + if (!keylargo_base || !keylargo) + return; + + prop = (char *)get_property(device, "AAPL,clock-id", NULL); + if (!prop) + return; + if (strncmp(prop, "usb0u048", strlen("usb0u048")) == 0) + number = 0; + else if (strncmp(prop, "usb1u148", strlen("usb1u148")) == 0) + number = 2; + else + return; + + spin_lock_irqsave(&keylargo->lock, flags); + if (power) { + /* Turn ON */ + + if (number == 0) { + KL_BIC(KEYLARGO_FCR0, (KL0_USB0_PAD_SUSPEND0 | KL0_USB0_PAD_SUSPEND1)); + mdelay(1); + KL_BIS(KEYLARGO_FCR0, KL0_USB0_CELL_ENABLE); + } else { + KL_BIC(KEYLARGO_FCR0, (KL0_USB1_PAD_SUSPEND0 | KL0_USB1_PAD_SUSPEND1)); + mdelay(1); + KL_BIS(KEYLARGO_FCR0, KL0_USB1_CELL_ENABLE); + } + reg = KL_IN(KEYLARGO_FCR4); + reg &= ~(KL4_SET_PORT_ENABLE(number) | KL4_SET_PORT_RESUME(number) | + KL4_SET_PORT_CONNECT(number) | KL4_SET_PORT_DISCONNECT(number)); + reg &= ~(KL4_SET_PORT_ENABLE(number+1) | KL4_SET_PORT_RESUME(number+1) | + KL4_SET_PORT_CONNECT(number+1) | KL4_SET_PORT_DISCONNECT(number+1)); + KL_OUT(KEYLARGO_FCR4, reg); + (void)KL_IN(KEYLARGO_FCR4); + udelay(10); + } else { + /* Turn OFF */ + + reg = KL_IN(KEYLARGO_FCR4); + reg |= KL4_SET_PORT_ENABLE(number) | KL4_SET_PORT_RESUME(number) | + KL4_SET_PORT_CONNECT(number) | KL4_SET_PORT_DISCONNECT(number); + reg |= KL4_SET_PORT_ENABLE(number+1) | KL4_SET_PORT_RESUME(number+1) | + KL4_SET_PORT_CONNECT(number+1) | KL4_SET_PORT_DISCONNECT(number+1); + KL_OUT(KEYLARGO_FCR4, reg); + (void)KL_IN(KEYLARGO_FCR4); + udelay(1); + if (number == 0) { + KL_BIC(KEYLARGO_FCR0, KL0_USB0_CELL_ENABLE); + (void)KL_IN(KEYLARGO_FCR0); + udelay(1); + KL_BIS(KEYLARGO_FCR0, (KL0_USB0_PAD_SUSPEND0 | KL0_USB0_PAD_SUSPEND1)); + (void)KL_IN(KEYLARGO_FCR0); + } else { + KL_BIC(KEYLARGO_FCR0, KL0_USB1_CELL_ENABLE); + (void)KL_IN(KEYLARGO_FCR0); + udelay(1); + KL_BIS(KEYLARGO_FCR0, (KL0_USB1_PAD_SUSPEND0 | KL0_USB1_PAD_SUSPEND1)); + (void)KL_IN(KEYLARGO_FCR0); + } + udelay(1); + } + spin_unlock_irqrestore(&keylargo->lock, flags); } -/* Not yet implemented */ void feature_set_firewire_power(struct device_node* device, int power) { + unsigned long flags; + + /* TODO: Handle save/restore of PCI config space here + */ + if (!uninorth_base) return; + spin_lock_irqsave(&keylargo->lock, flags); if (power) UN_BIS(UNI_N_CLOCK_CNTL, UNI_N_CLOCK_CNTL_FW); else UN_BIC(UNI_N_CLOCK_CNTL, UNI_N_CLOCK_CNTL_FW); udelay(20); + spin_unlock_irqrestore(&keylargo->lock, flags); +} + +/* Warning: will kill the PHY.. */ +void +feature_set_firewire_cable_power(struct device_node* device, int power) +{ + unsigned long flags; + u8 gpioValue = power ? 0 : 4; + + if (!keylargo_base || !(board_features & FTR_HAS_FW_POWER)) + return; + spin_lock_irqsave(&keylargo->lock, flags); + out_8((volatile u8 *)KL_FCR(KL_GPIO_FW_CABLE_POWER), gpioValue); + (void)in_8((volatile u8 *)KL_FCR(KL_GPIO_FW_CABLE_POWER)); + spin_unlock_irqrestore(&keylargo->lock, flags); } #ifdef CONFIG_SMP void -feature_core99_kick_cpu1(void) +feature_core99_kick_cpu(int cpu_nr) { - out_8((volatile u8 *)KL_FCR(KL_GPIO_KICK_CPU1), KL_GPIO_KICK_CPU1_UP); +#if 1 /* New way */ + const int reset_lines[] = { KL_GPIO_RESET_CPU0, + KL_GPIO_RESET_CPU1, + KL_GPIO_RESET_CPU2, + KL_GPIO_RESET_CPU3 }; + volatile u8* reset_io; + + if (!keylargo_base || cpu_nr > 3) + return; + reset_io = (volatile u8*)KL_FCR(reset_lines[cpu_nr]); + out_8(reset_io, KEYLARGO_GPIO_OUTPUT_ENABLE); + udelay(1); + out_8(reset_io, KEYLARGO_GPIO_OUTPUT_ENABLE | KEYLARGO_GPIO_OUTOUT_DATA); +#else + out_8((volatile u8 *)KL_FCR(KL_GPIO_EXTINT_CPU1), KL_GPIO_EXTINT_CPU1_ASSERT); udelay(1); - out_8((volatile u8 *)KL_FCR(KL_GPIO_KICK_CPU1), KL_GPIO_KICK_CPU1_DOWN); + out_8((volatile u8 *)KL_FCR(KL_GPIO_EXTINT_CPU1), KL_GPIO_EXTINT_CPU1_RELEASE); +#endif } #endif /* CONFIG_SMP */ +void +feature_set_airport_power(struct device_node* device, int power) +{ + if (!keylargo_base || !airport_dev || airport_dev != device) + return; + if (airport_pwr_state == power) + return; + if (power) { + /* Some if this is from Darwin code, some is from tracing of + * MacOS driver with Macsbug. Some real bit definitions would + * really help here... + */ + out_8((volatile u8*)KL_FCR(KL_GPIO_AIRPORT_0), airport_pwr_regs[0]); + out_8((volatile u8*)KL_FCR(KL_GPIO_AIRPORT_1), airport_pwr_regs[1]); + out_8((volatile u8*)KL_FCR(KL_GPIO_AIRPORT_2), airport_pwr_regs[2]); + out_8((volatile u8*)KL_FCR(KL_GPIO_AIRPORT_3), airport_pwr_regs[3]); + out_8((volatile u8*)KL_FCR(KL_GPIO_AIRPORT_4), airport_pwr_regs[4]); + udelay(20); + out_8((volatile u8*)KL_FCR(KL_GPIO_AIRPORT_4), 5); + udelay(20); + out_8((volatile u8*)KL_FCR(KL_GPIO_AIRPORT_4), 4); + mdelay(20); + KL_BIC(KEYLARGO_FCR2, KL2_AIRPORT_RESET_N); + udelay(10); + out_8((volatile u8*)KL_FCR(0x1a3e0), 0x41); + udelay(10); + KL_BIS(KEYLARGO_FCR2, KL2_AIRPORT_RESET_N); + udelay(10); + } else { + airport_pwr_regs[0] = in_8((volatile u8*)KL_FCR(KL_GPIO_AIRPORT_0)); + airport_pwr_regs[1] = in_8((volatile u8*)KL_FCR(KL_GPIO_AIRPORT_1)); + airport_pwr_regs[2] = in_8((volatile u8*)KL_FCR(KL_GPIO_AIRPORT_2)); + airport_pwr_regs[3] = in_8((volatile u8*)KL_FCR(KL_GPIO_AIRPORT_3)); + airport_pwr_regs[4] = in_8((volatile u8*)KL_FCR(KL_GPIO_AIRPORT_4)); + out_8((volatile u8*)KL_FCR(KL_GPIO_AIRPORT_0), 0); + out_8((volatile u8*)KL_FCR(KL_GPIO_AIRPORT_1), 0); + out_8((volatile u8*)KL_FCR(KL_GPIO_AIRPORT_2), 0); + out_8((volatile u8*)KL_FCR(KL_GPIO_AIRPORT_3), 0); + out_8((volatile u8*)KL_FCR(KL_GPIO_AIRPORT_4), 0); + } + airport_pwr_state = power; +} + /* Initialize the Core99 UniNorth host bridge and memory controller */ static void @@ -563,51 +800,106 @@ uninorth_init(void) /* Set the arbitrer QAck delay according to what Apple does */ - actrl = in_be32(UN_REG(UNI_N_ARB_CTRL)) & ~UNI_N_ARB_CTRL_QACK_DELAY_MASK; - actrl |= ((uninorth_rev < 3) ? UNI_N_ARB_CTRL_QACK_DELAY105 : UNI_N_ARB_CTRL_QACK_DELAY) - << UNI_N_ARB_CTRL_QACK_DELAY_SHIFT; - UN_OUT(UNI_N_ARB_CTRL, actrl); + if (uninorth_rev < 0x10) { + actrl = UN_IN(UNI_N_ARB_CTRL) & ~UNI_N_ARB_CTRL_QACK_DELAY_MASK; + actrl |= ((uninorth_rev < 3) ? UNI_N_ARB_CTRL_QACK_DELAY105 : + UNI_N_ARB_CTRL_QACK_DELAY) << UNI_N_ARB_CTRL_QACK_DELAY_SHIFT; + UN_OUT(UNI_N_ARB_CTRL, actrl); + } - /* - * Turns OFF the gmac clock. The gmac driver will turn - * it back ON when the interface is enabled. This save - * power on portables. - * - * Note: We could also try to turn OFF the PHY. Since this - * has to be done by both the gmac driver and this code, - * I'll probably end-up moving some of this out of the - * modular gmac driver into a non-modular stub containing - * some basic PHY management and power management stuffs + /* Enable GMAC for now for PCI probing. It will be disabled + * later on after PCI probe */ gmac = find_devices("ethernet"); - while(gmac) { if (device_is_compatible(gmac, "gmac")) break; gmac = gmac->next; } if (gmac) - feature_set_gmac_power(gmac, 0); + feature_set_gmac_power(gmac, 1); - /* Kludge (enable FW before PCI probe) */ + /* Enable FW before PCI probe. Will be disabled later on + */ fw = find_devices("firewire"); if (fw && device_is_compatible(fw, "pci106b,18")) feature_set_firewire_power(fw, 1); } -/* Initialize the Core99 KeyLargo ASIC. Currently, we just make sure - * OpenPIC is enabled +/* Initialize the Core99 KeyLargo ASIC. */ static void keylargo_init(void) { + struct device_node* np; + KL_BIS(KEYLARGO_FCR2, KL2_MPIC_ENABLE); + + /* Lookup for an airport card, and disable it if found + * to save power (will be re-enabled by driver if used) + */ + np = find_devices("radio"); + if (np && np->parent == keylargo->device) + airport_dev = np; + + if (airport_dev) { + airport_pwr_state = 1; + feature_set_airport_power(airport_dev, 0); + } + } #ifdef CONFIG_PMAC_PBOOK +void +feature_prepare_for_sleep(void) +{ + /* We assume gatwick is second */ + struct feature_controller* ctrler = &controllers[0]; + + if (controller_count > 1 && + device_is_compatible(ctrler->device, "gatwick")) + ctrler = &controllers[1]; + + if (ctrler->bits == feature_bits_heathrow || + ctrler->bits == feature_bits_paddington) { + heathrow_prepare_for_sleep(ctrler); + return; + } + if (ctrler->bits == feature_bits_keylargo) { + core99_prepare_for_sleep(ctrler); + return; + } +} + + +void +feature_wake_up(void) +{ + struct feature_controller* ctrler = &controllers[0]; + + if (controller_count > 1 && + device_is_compatible(ctrler->device, "gatwick")) + ctrler = &controllers[1]; + + if (ctrler->bits == feature_bits_heathrow || + ctrler->bits == feature_bits_paddington) { + heathrow_wakeup(ctrler); + return; + } + if (ctrler->bits == feature_bits_keylargo) { + core99_wake_up(ctrler); + return; + } +} static u32 save_fcr[5]; static u32 save_mbcr; +static u32 save_gpio_levels[2]; +static u8 save_gpio_extint[KEYLARGO_GPIO_EXTINT_CNT]; +static u8 save_gpio_normal[KEYLARGO_GPIO_CNT]; +static u32 save_unin_clock_ctl; +static struct dbdma_regs save_dbdma[13]; + static void heathrow_prepare_for_sleep(struct feature_controller* ctrler) @@ -631,60 +923,226 @@ heathrow_wakeup(struct feature_controller* ctrler) } static void -core99_prepare_for_sleep(struct feature_controller* ctrler) +turn_off_keylargo(void) { - /* Not yet implemented */ + u32 temp; + + /* For now, suspending the USB ref cause the machine to die on + * wakeup -- BenH + */ +#if 0 + mdelay(1); + KL_BIS(KEYLARGO_FCR0, KL0_USB_REF_SUSPEND); + (void)KL_IN(KEYLARGO_FCR0); + mdelay(1500); +#endif + + KL_BIC(KEYLARGO_FCR0, KL0_SCCA_ENABLE | KL0_SCCB_ENABLE | + KL0_SCC_CELL_ENABLE | + KL0_IRDA_ENABLE | KL0_IRDA_CLK32_ENABLE | + KL0_IRDA_CLK19_ENABLE); + + (void)KL_IN(KEYLARGO_FCR0); udelay(10); + KL_BIS(KEYLARGO_MBCR, KL_MBCR_MB0_DEV_ENABLE); + (void)KL_IN(KEYLARGO_MBCR); udelay(10); + + KL_BIC(KEYLARGO_FCR1, + KL1_AUDIO_SEL_22MCLK | KL1_AUDIO_CLK_ENABLE_BIT | + KL1_AUDIO_CLK_OUT_ENABLE | KL1_AUDIO_CELL_ENABLE | + KL1_I2S0_CELL_ENABLE | KL1_I2S0_CLK_ENABLE_BIT | + KL1_I2S0_ENABLE | KL1_I2S1_CELL_ENABLE | + KL1_I2S1_CLK_ENABLE_BIT | KL1_I2S1_ENABLE | + KL1_EIDE0_ENABLE | KL1_EIDE0_RESET_N | + KL1_EIDE1_ENABLE | KL1_EIDE1_RESET_N | + KL1_UIDE_ENABLE); + (void)KL_IN(KEYLARGO_FCR1); udelay(10); + + KL_BIS(KEYLARGO_FCR2, KL2_MODEM_POWER_N); + udelay(10); + KL_BIC(KEYLARGO_FCR2, KL2_IOBUS_ENABLE); + udelay(10); + temp = KL_IN(KEYLARGO_FCR3); + if (keylargo_rev >= 2) + temp |= (KL3_SHUTDOWN_PLL2X | KL3_SHUTDOWN_PLL_TOTAL); + + temp |= KL3_SHUTDOWN_PLLKW6 | KL3_SHUTDOWN_PLLKW4 | + KL3_SHUTDOWN_PLLKW35 | KL3_SHUTDOWN_PLLKW12; + temp &= ~(KL3_CLK66_ENABLE | KL3_CLK49_ENABLE | KL3_CLK45_ENABLE + | KL3_CLK31_ENABLE | KL3_TIMER_CLK18_ENABLE | KL3_I2S1_CLK18_ENABLE + | KL3_I2S0_CLK18_ENABLE | KL3_VIA_CLK16_ENABLE); + KL_OUT(KEYLARGO_FCR3, temp); + (void)KL_IN(KEYLARGO_FCR3); udelay(10); } static void -core99_wake_up(struct feature_controller* ctrler) +turn_off_pangea(void) { - /* Not yet implemented */ + u32 temp; + + KL_BIC(KEYLARGO_FCR0, KL0_SCCA_ENABLE | KL0_SCCB_ENABLE | + KL0_SCC_CELL_ENABLE | + KL0_USB0_CELL_ENABLE | KL0_USB1_CELL_ENABLE); + + (void)KL_IN(KEYLARGO_FCR0); udelay(10); + KL_BIS(KEYLARGO_MBCR, KL_MBCR_MB0_DEV_ENABLE); + (void)KL_IN(KEYLARGO_MBCR); udelay(10); + + KL_BIC(KEYLARGO_FCR1, + KL1_AUDIO_SEL_22MCLK | KL1_AUDIO_CLK_ENABLE_BIT | + KL1_AUDIO_CLK_OUT_ENABLE | KL1_AUDIO_CELL_ENABLE | + KL1_I2S0_CELL_ENABLE | KL1_I2S0_CLK_ENABLE_BIT | + KL1_I2S0_ENABLE | KL1_I2S1_CELL_ENABLE | + KL1_I2S1_CLK_ENABLE_BIT | KL1_I2S1_ENABLE | + KL1_UIDE_ENABLE); + (void)KL_IN(KEYLARGO_FCR1); udelay(10); + + KL_BIS(KEYLARGO_FCR2, KL2_MODEM_POWER_N); + udelay(10); + temp = KL_IN(KEYLARGO_FCR3); + temp |= KL3_SHUTDOWN_PLLKW6 | KL3_SHUTDOWN_PLLKW4 | + KL3_SHUTDOWN_PLLKW35; + temp &= ~(KL3_CLK49_ENABLE | KL3_CLK45_ENABLE + | KL3_CLK31_ENABLE | KL3_TIMER_CLK18_ENABLE | KL3_I2S1_CLK18_ENABLE + | KL3_I2S0_CLK18_ENABLE | KL3_VIA_CLK16_ENABLE); + KL_OUT(KEYLARGO_FCR3, temp); + (void)KL_IN(KEYLARGO_FCR3); udelay(10); } -void -feature_prepare_for_sleep(void) +static void +core99_prepare_for_sleep(struct feature_controller* ctrler) { - /* We assume gatwick is second */ - struct feature_controller* ctrler = &controllers[0]; - - if (!ctrler) - return; - if (controller_count > 1 && - device_is_compatible(ctrler->device, "gatwick")) - ctrler = &controllers[1]; + int i; + u8* base8; + + /* + * Save various bits of KeyLargo + */ - if (ctrler->bits == feature_bits_heathrow || - ctrler->bits == feature_bits_paddington) { - heathrow_prepare_for_sleep(ctrler); - return; + /* We power off the wireless slot in case it was not done + * by the driver. We don't power it on automatically however + */ + feature_set_airport_power(airport_dev, 0); + + /* We power off the FW cable. Should be done by the driver... */ + feature_set_firewire_cable_power(NULL, 0); + + /* Save the state of the various GPIOs */ + save_gpio_levels[0] = KL_IN(KEYLARGO_GPIO_LEVELS0); + save_gpio_levels[1] = KL_IN(KEYLARGO_GPIO_LEVELS1); + base8 = (u8 *)KL_FCR(KEYLARGO_GPIO_EXTINT_0); + for (i=0; i>2)); + save_dbdma[i].cmdptr_hi = in_le32(&chan->cmdptr_hi); + save_dbdma[i].cmdptr = in_le32(&chan->cmdptr); + save_dbdma[i].intr_sel = in_le32(&chan->intr_sel); + save_dbdma[i].br_sel = in_le32(&chan->br_sel); + save_dbdma[i].wait_sel = in_le32(&chan->wait_sel); } - if (ctrler->bits == feature_bits_keylargo) { - core99_prepare_for_sleep(ctrler); - return; + + /* + * Turn off as much as we can + */ + if (keylargo_rev & KL_PANGEA_REV) + turn_off_pangea(); + else + turn_off_keylargo(); + + /* + * Put the host bridge to sleep + */ + + save_unin_clock_ctl = UN_IN(UNI_N_CLOCK_CNTL); + UN_OUT(UNI_N_CLOCK_CNTL, save_unin_clock_ctl & + ~(UNI_N_CLOCK_CNTL_GMAC|UNI_N_CLOCK_CNTL_FW/*|UNI_N_CLOCK_CNTL_PCI*/)); + udelay(100); + UN_OUT(UNI_N_HWINIT_STATE, UNI_N_HWINIT_STATE_SLEEPING); + UN_OUT(UNI_N_POWER_MGT, UNI_N_POWER_MGT_SLEEP); + + /* + * FIXME: A bit of black magic with OpenPIC (don't ask me why) + */ + if (board_features & FTR_NEED_OPENPIC_TWEAK) { + KL_BIS(0x506e0, 0x00400000); + KL_BIS(0x506e0, 0x80000000); } } -void -feature_wake_up(void) +static void +core99_wake_up(struct feature_controller* ctrler) { - struct feature_controller* ctrler = &controllers[0]; + int i; + u8* base8; - if (!ctrler) - return; - if (controller_count > 1 && - device_is_compatible(ctrler->device, "gatwick")) - ctrler = &controllers[1]; + /* + * Wakeup the host bridge + */ + UN_OUT(UNI_N_POWER_MGT, UNI_N_POWER_MGT_NORMAL); + udelay(10); + UN_OUT(UNI_N_HWINIT_STATE, UNI_N_HWINIT_STATE_RUNNING); + udelay(10); - if (ctrler->bits == feature_bits_heathrow || - ctrler->bits == feature_bits_paddington) { - heathrow_wakeup(ctrler); - return; + /* + * Restore KeyLargo + */ + + KL_OUT(KEYLARGO_MBCR, save_mbcr); + (void)KL_IN(KEYLARGO_MBCR); udelay(10); + KL_OUT(KEYLARGO_FCR0, save_fcr[0]); + (void)KL_IN(KEYLARGO_FCR0); udelay(10); + KL_OUT(KEYLARGO_FCR1, save_fcr[1]); + (void)KL_IN(KEYLARGO_FCR1); udelay(10); + KL_OUT(KEYLARGO_FCR2, save_fcr[2]); + (void)KL_IN(KEYLARGO_FCR2); udelay(10); + KL_OUT(KEYLARGO_FCR3, save_fcr[3]); + (void)KL_IN(KEYLARGO_FCR3); udelay(10); + KL_OUT(KEYLARGO_FCR4, save_fcr[4]); + (void)KL_IN(KEYLARGO_FCR4); udelay(10); + + for (i=0; i<13; i++) { + volatile struct dbdma_regs* chan = (volatile struct dbdma_regs*) + (keylargo_base + ((0x8000+i*0x100)>>2)); + out_le32(&chan->control, (ACTIVE|DEAD|WAKE|FLUSH|PAUSE|RUN)<<16); + while (in_le32(&chan->status) & ACTIVE) + mb(); + out_le32(&chan->cmdptr_hi, save_dbdma[i].cmdptr_hi); + out_le32(&chan->cmdptr, save_dbdma[i].cmdptr); + out_le32(&chan->intr_sel, save_dbdma[i].intr_sel); + out_le32(&chan->br_sel, save_dbdma[i].br_sel); + out_le32(&chan->wait_sel, save_dbdma[i].wait_sel); } - if (ctrler->bits == feature_bits_keylargo) { - core99_wake_up(ctrler); - return; + + KL_OUT(KEYLARGO_GPIO_LEVELS0, save_gpio_levels[0]); + KL_OUT(KEYLARGO_GPIO_LEVELS1, save_gpio_levels[1]); + base8 = (u8 *)KL_FCR(KEYLARGO_GPIO_EXTINT_0); + for (i=0; i +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "pci.h" + +#define pci_config_addr(bus,dev,offset) \ + (0x80000000 | (bus<<16) | (dev<<8) | offset) + + +int +gemini_pcibios_read_config_byte(struct pci_dev *dev, int offset, u8 *val) +{ + unsigned long reg; + reg = grackle_read(pci_config_addr(dev->bus->number, dev->devfn, + (offset & ~(0x3)))); + *val = ((reg >> ((offset & 0x3) << 3)) & 0xff); + return PCIBIOS_SUCCESSFUL; +} + +int +gemini_pcibios_read_config_word(struct pci_dev *dev, int offset, u16 *val) +{ + unsigned long reg; + reg = grackle_read(pci_config_addr(dev->bus->number, dev->devfn, + (offset & ~(0x3)))); + *val = ((reg >> ((offset & 0x3) << 3)) & 0xffff); + return PCIBIOS_SUCCESSFUL; +} + +int +gemini_pcibios_read_config_dword(struct pci_dev *dev, int offset, u32 *val) +{ + *val = grackle_read(pci_config_addr(dev->bus->number, dev->devfn, + (offset & ~(0x3)))); + return PCIBIOS_SUCCESSFUL; +} + +int +gemini_pcibios_write_config_byte(struct pci_dev *dev, int offset, u8 val) +{ + unsigned long reg; + int shifts = offset & 0x3; + unsigned int addr = pci_config_addr(dev->bus->number, dev->devfn, + (offset & ~(0x3))); + + reg = grackle_read(addr); + reg = (reg & ~(0xff << (shifts << 3))) | (val << (shifts << 3)); + grackle_write(addr, reg ); + return PCIBIOS_SUCCESSFUL; +} + +int +gemini_pcibios_write_config_word(struct pci_dev *dev, int offset, u16 val) +{ + unsigned long reg; + int shifts = offset & 0x3; + unsigned int addr = pci_config_addr(dev->bus->number, dev->devfn, + (offset & ~(0x3))); + + reg = grackle_read(addr); + reg = (reg & ~(0xffff << (shifts << 3))) | (val << (shifts << 3)); + grackle_write(addr, reg ); + return PCIBIOS_SUCCESSFUL; +} + +int +gemini_pcibios_write_config_dword(struct pci_dev *dev, int offset, u32 val) +{ + grackle_write(pci_config_addr(dev->bus->number, dev->devfn, + (offset & ~(0x3))), val); + return PCIBIOS_SUCCESSFUL; +} + +static struct pci_ops gemini_pci_ops = +{ + gemini_pcibios_read_config_byte, + gemini_pcibios_read_config_word, + gemini_pcibios_read_config_dword, + gemini_pcibios_write_config_byte, + gemini_pcibios_write_config_word, + gemini_pcibios_write_config_dword +}; + +void __init gemini_pcibios_fixup(void) +{ + int i; + struct pci_dev *dev; + + pci_for_each_dev(dev) { + for(i = 0; i < 6; i++) { + if (dev->resource[i].flags & IORESOURCE_IO) { + dev->resource[i].start |= (0xfe << 24); + dev->resource[i].end |= (0xfe << 24); + } + } + } +} + + +/* The "bootloader" for Synergy boards does none of this for us, so we need to + lay it all out ourselves... --Dan */ +void __init gemini_find_bridges(void) +{ + struct pci_controller* hose; + + ppc_md.pcibios_fixup = gemini_pcibios_fixup; + + hose = pcibios_alloc_controller(); + if (!hose) + return; + hose->ops = &gemini_pci_ops; +} diff --git a/arch/ppc/kernel/gemini_prom.S b/arch/ppc/kernel/gemini_prom.S new file mode 100644 index 000000000000..271c6ddcfe17 --- /dev/null +++ b/arch/ppc/kernel/gemini_prom.S @@ -0,0 +1,96 @@ +/* + * arch/ppc/kernel/gemini_prom.S + * + * Not really prom support code (yet), but sort of anti-prom code. The current + * bootloader does a number of things it shouldn't and doesn't do things that it + * should. The stuff in here is mainly a hodge-podge collection of setup code + * to get the board up and running. + * ---Dan + */ + +#include "ppc_asm.tmpl" +#include "ppc_defs.h" +#include +#include +#include +#include + +#define HID0_ABE (1<<3) + +/* + * On 750's the MMU is on when Linux is booted, so we need to clear out the + * bootloader's BAT settings, make sure we're in supervisor state (gotcha!), + * and turn off the MMU. + * + */ + +_GLOBAL(gemini_prom_init) +#ifdef CONFIG_SMP + /* Since the MMU's on, get stuff in rom space that we'll need */ + lis r4,GEMINI_CPUSTAT@h + ori r4,r4,GEMINI_CPUSTAT@l + lbz r5,0(r4) + andi. r5,r5,3 + mr r24,r5 /* cpu # used later on */ +#endif + mfmsr r4 + li r3,MSR_PR /* ensure supervisor! */ + ori r3,r3,MSR_IR|MSR_DR + andc r4,r4,r3 + mtmsr r4 + isync +#if 0 + /* zero out the bats now that the MMU is off */ +prom_no_mmu: + li r3,0 + mtspr IBAT0U,r3 + mtspr IBAT0L,r3 + mtspr IBAT1U,r3 + mtspr IBAT1L,r3 + mtspr IBAT2U,r3 + mtspr IBAT2L,r3 + mtspr IBAT3U,r3 + mtspr IBAT3L,r3 + + mtspr DBAT0U,r3 + mtspr DBAT0L,r3 + mtspr DBAT1U,r3 + mtspr DBAT1L,r3 + mtspr DBAT2U,r3 + mtspr DBAT2L,r3 + mtspr DBAT3U,r3 + mtspr DBAT3L,r3 +#endif + + /* the bootloader (as far as I'm currently aware) doesn't mess with page + tables, but since we're already here, might as well zap these, too */ + li r4,0 + mtspr SDR1,r4 + + li r4,16 + mtctr r4 + li r3,0 + li r4,0 +3: mtsrin r3,r4 + addi r3,r3,1 + bdnz 3b + +#ifdef CONFIG_SMP + /* The 750 book (and Mot/IBM support) says that this will "assist" snooping + when in SMP. Not sure yet whether this should stay or leave... */ + mfspr r4,HID0 + ori r4,r4,HID0_ABE + mtspr HID0,r4 + sync +#endif /* CONFIG_SMP */ + blr + +/* apparently, SMon doesn't pay attention to HID0[SRST]. Disable the MMU and + branch to 0xfff00100 */ +_GLOBAL(_gemini_reboot) + lis r5,GEMINI_BOOT_INIT@h + ori r5,r5,GEMINI_BOOT_INIT@l + li r6,MSR_IP + mtspr SRR0,r5 + mtspr SRR1,r6 + rfi diff --git a/arch/ppc/kernel/gemini_setup.c b/arch/ppc/kernel/gemini_setup.c new file mode 100644 index 000000000000..0a66b3756ba5 --- /dev/null +++ b/arch/ppc/kernel/gemini_setup.c @@ -0,0 +1,537 @@ +/* + * linux/arch/ppc/kernel/setup.c + * + * Copyright (C) 1995 Linus Torvalds + * Adapted from 'alpha' version by Gary Thomas + * Modified by Cort Dougan (cort@cs.nmt.edu) + * Synergy Microsystems board support by Dan Cox (dan@synergymicro.com) + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "local_irq.h" +#include "open_pic.h" + +void gemini_find_bridges(void); +static int gemini_get_clock_speed(void); +extern void gemini_pcibios_fixup(void); + +static char *gemini_board_families[] = { + "VGM", "VSS", "KGM", "VGR", "VCM", "VCS", "KCM", "VCR" +}; +static int gemini_board_count = sizeof(gemini_board_families) / + sizeof(gemini_board_families[0]); + +static unsigned int cpu_7xx[16] = { + 0, 15, 14, 0, 0, 13, 5, 9, 6, 11, 8, 10, 16, 12, 7, 0 +}; +static unsigned int cpu_6xx[16] = { + 0, 0, 14, 0, 0, 13, 5, 9, 6, 11, 8, 10, 0, 12, 7, 0 +}; + +int chrp_get_irq(struct pt_regs *); +void chrp_post_irq(struct pt_regs* regs, int); + +static inline unsigned long _get_HID1(void) +{ + unsigned long val; + + __asm__ __volatile__("mfspr %0,1009" : "=r" (val)); + return val; +} + +/* + * prom_init is the Gemini version of prom.c:prom_init. We only need + * the BSS clearing code, so I copied that out of prom.c. This is a + * lot simpler than hacking prom.c so it will build with Gemini. -VAL + */ + +#define PTRRELOC(x) ((typeof(x))((unsigned long)(x) + offset)) + +unsigned long +prom_init(void) +{ + unsigned long offset = reloc_offset(); + unsigned long phys; + extern char __bss_start, _end; + + /* First zero the BSS -- use memset, some arches don't have + * caches on yet */ + memset_io(PTRRELOC(&__bss_start),0 , &_end - &__bss_start); + + /* Default */ + phys = offset + KERNELBASE; + + gemini_prom_init(); + + return phys; +} + +int +gemini_get_cpuinfo(char *buffer) +{ + int len; + unsigned char reg, rev; + char *family; + unsigned int type; + + reg = readb(GEMINI_FEAT); + family = gemini_board_families[((reg>>4) & 0xf)]; + if (((reg>>4) & 0xf) > gemini_board_count) + printk(KERN_ERR "cpuinfo(): unable to determine board family\n"); + + reg = readb(GEMINI_BREV); + type = (reg>>4) & 0xf; + rev = reg & 0xf; + + reg = readb(GEMINI_BECO); + + len = sprintf( buffer, "machine\t\t: Gemini %s%d, rev %c, eco %d\n", + family, type, (rev + 'A'), (reg & 0xf)); + + len = sprintf(buffer, "board\t\t: Gemini %s", family); + if (type > 9) + len += sprintf(buffer+len, "%c", (type - 10) + 'A'); + else + len += sprintf(buffer+len, "%d", type); + + len += sprintf(buffer+len, ", rev %c, eco %d\n", + (rev + 'A'), (reg & 0xf)); + + len += sprintf(buffer+len, "clock\t\t: %dMhz\n", + gemini_get_clock_speed()); + + return len; +} + +static u_char gemini_openpic_initsenses[] = { + 1, + 1, + 1, + 1, + 0, + 0, + 1, /* remainder are level-triggered */ +}; + +#define GEMINI_MPIC_ADDR (0xfcfc0000) +#define GEMINI_MPIC_PCI_CFG (0x80005800) + +void __init gemini_openpic_init(void) +{ + + OpenPIC_Addr = (volatile struct OpenPIC *) + grackle_read(GEMINI_MPIC_PCI_CFG + 0x10); + OpenPIC_InitSenses = gemini_openpic_initsenses; + OpenPIC_NumInitSenses = sizeof( gemini_openpic_initsenses ); + + ioremap( GEMINI_MPIC_ADDR, OPENPIC_SIZE); +} + + +extern unsigned long loops_per_jiffy; +extern int root_mountflags; +extern char cmd_line[]; + +void +gemini_heartbeat(void) +{ + static unsigned long led = GEMINI_LEDBASE+(4*8); + static char direction = 8; + *(char *)led = 0; + if ( (led + direction) > (GEMINI_LEDBASE+(7*8)) || + (led + direction) < (GEMINI_LEDBASE+(4*8)) ) + direction *= -1; + led += direction; + *(char *)led = 0xff; + ppc_md.heartbeat_count = ppc_md.heartbeat_reset; +} + +void __init gemini_setup_arch(void) +{ + extern char cmd_line[]; + + + loops_per_jiffy = 50000000/HZ; + +#ifdef CONFIG_BLK_DEV_INITRD + /* bootable off CDROM */ + if (initrd_start) + ROOT_DEV = MKDEV(SCSI_CDROM_MAJOR, 0); + else +#endif + ROOT_DEV = to_kdev_t(0x0801); + + /* nothing but serial consoles... */ + sprintf(cmd_line, "%s console=ttyS0", cmd_line); + + printk("Boot arguments: %s\n", cmd_line); + + ppc_md.heartbeat = gemini_heartbeat; + ppc_md.heartbeat_reset = HZ/8; + ppc_md.heartbeat_count = 1; + + /* Lookup PCI hosts */ + gemini_find_bridges(); + /* take special pains to map the MPIC, since it isn't mapped yet */ + gemini_openpic_init(); + /* start the L2 */ + gemini_init_l2(); +} + + +int +gemini_get_clock_speed(void) +{ + unsigned long hid1, pvr = _get_PVR(); + int clock; + + hid1 = (_get_HID1() >> 28) & 0xf; + if (PVR_VER(pvr) == 8 || + PVR_VER(pvr) == 12) + hid1 = cpu_7xx[hid1]; + else + hid1 = cpu_6xx[hid1]; + + switch((readb(GEMINI_BSTAT) & 0xc) >> 2) { + + case 0: + default: + clock = (hid1*100)/3; + break; + + case 1: + clock = (hid1*125)/3; + break; + + case 2: + clock = (hid1*50); + break; + } + + return clock; +} + +void __init gemini_init_l2(void) +{ + unsigned char reg, brev, fam, creg; + unsigned long cache; + unsigned long pvr = _get_PVR(); + + reg = readb(GEMINI_L2CFG); + brev = readb(GEMINI_BREV); + fam = readb(GEMINI_FEAT); + + switch(PVR_VER(pvr)) { + + case 8: + if (reg & 0xc0) + cache = (((reg >> 6) & 0x3) << 28); + else + cache = 0x3 << 28; + +#ifdef CONFIG_SMP + /* Pre-3.0 processor revs had snooping errata. Leave + their L2's disabled with SMP. -- Dan */ + if (PVR_CFG(pvr) < 3) { + printk("Pre-3.0 750; L2 left disabled!\n"); + return; + } +#endif /* CONFIG_SMP */ + + /* Special case: VGM5-B's came before L2 ratios were set on + the board. Processor speed shouldn't be too high, so + set L2 ratio to 1:1.5. */ + if ((brev == 0x51) && ((fam & 0xa0) >> 4) == 0) + reg |= 1; + + /* determine best cache ratio based upon what the board + tells us (which sometimes _may_ not be true) and + the processor speed. */ + else { + if (gemini_get_clock_speed() > 250) + reg = 2; + } + break; + case 12: + { + static unsigned long l2_size_val = 0; + + if (!l2_size_val) + l2_size_val = _get_L2CR(); + cache = l2_size_val; + break; + } + case 4: + case 9: + creg = readb(GEMINI_CPUSTAT); + if (((creg & 0xc) >> 2) != 1) + printk("Dual-604 boards don't support the use of L2\n"); + else + writeb(1, GEMINI_L2CFG); + return; + default: + printk("Unknown processor; L2 left disabled\n"); + return; + } + + cache |= ((1<>2)&0x3) { + case 0: + default: + freq = 66667; + break; + case 1: + freq = 83000; + break; + case 2: + freq = 100000; + break; + } + + freq *= 1000; + divisor = 4; + tb_ticks_per_jiffy = freq / HZ / divisor; + tb_to_us = mulhwu_scale_factor(freq/divisor, 1000000); +} + +unsigned long __init gemini_find_end_of_memory(void) +{ + unsigned long total; + unsigned char reg; + + reg = readb(GEMINI_MEMCFG); + total = ((1<<((reg & 0x7) - 1)) * + (8<<((reg >> 3) & 0x7))); + total *= (1024*1024); + return total; +} + +void __init gemini_init(unsigned long r3, unsigned long r4, unsigned long r5, + unsigned long r6, unsigned long r7) +{ + int i; + int chrp_get_irq( struct pt_regs * ); + + for(i = 0; i < GEMINI_LEDS; i++) + gemini_led_off(i); + + ISA_DMA_THRESHOLD = 0; + DMA_MODE_READ = 0; + DMA_MODE_WRITE = 0; + +#ifdef CONFIG_BLK_DEV_INITRD + if ( r4 ) + { + initrd_start = r4 + KERNELBASE; + initrd_end = r5 + KERNELBASE; + } +#endif + + ppc_md.setup_arch = gemini_setup_arch; + ppc_md.setup_residual = NULL; + ppc_md.get_cpuinfo = gemini_get_cpuinfo; + ppc_md.irq_cannonicalize = NULL; + ppc_md.init_IRQ = gemini_init_IRQ; + ppc_md.get_irq = openpic_get_irq; + ppc_md.init = NULL; + + ppc_md.restart = gemini_restart; + ppc_md.power_off = gemini_power_off; + ppc_md.halt = gemini_halt; + + ppc_md.time_init = gemini_time_init; + ppc_md.set_rtc_time = gemini_set_rtc_time; + ppc_md.get_rtc_time = gemini_get_rtc_time; + ppc_md.calibrate_decr = gemini_calibrate_decr; + + ppc_md.find_end_of_memory = gemini_find_end_of_memory; + + /* no keyboard/mouse/video stuff yet.. */ + ppc_md.kbd_setkeycode = NULL; + ppc_md.kbd_getkeycode = NULL; + ppc_md.kbd_translate = NULL; + ppc_md.kbd_unexpected_up = NULL; + ppc_md.kbd_leds = NULL; + ppc_md.kbd_init_hw = NULL; +#ifdef CONFIG_MAGIC_SYSRQ + ppc_md.ppc_kbd_sysrq_xlate = NULL; +#endif + ppc_md.pcibios_fixup_bus = gemini_pcibios_fixup; +} diff --git a/arch/ppc/kernel/hashtable.S b/arch/ppc/kernel/hashtable.S index 8ea3cdc7a7dc..f2e7603f91ba 100644 --- a/arch/ppc/kernel/hashtable.S +++ b/arch/ppc/kernel/hashtable.S @@ -27,7 +27,6 @@ #include #include #include -#include "mol.h" /* * Load a PTE into the hash table, if possible. @@ -609,11 +608,6 @@ _GLOBAL(flush_hash_segments) * flush_hash_page(unsigned context, unsigned long va) */ _GLOBAL(flush_hash_page) -#ifdef CONFIG_MOL - mflr r10 - MOL_HOOK_MMU(10, r6) - mtlr r10 -#endif lis r6,Hash@ha lwz r6,Hash@l(r6) /* hash table base */ cmpwi 0,r6,0 /* hash table in use? */ diff --git a/arch/ppc/kernel/head.S b/arch/ppc/kernel/head.S index 89f5b6d68d38..84b3ff640f6d 100644 --- a/arch/ppc/kernel/head.S +++ b/arch/ppc/kernel/head.S @@ -31,24 +31,11 @@ #include #include #include -#include "mol.h" #ifdef CONFIG_APUS #include #endif -#ifndef CONFIG_PPC64BRIDGE -CACHELINE_BYTES = 32 -LG_CACHELINE_BYTES = 5 -CACHELINE_MASK = 0x1f -CACHELINE_WORDS = 8 -#else -CACHELINE_BYTES = 128 -LG_CACHELINE_BYTES = 7 -CACHELINE_MASK = 0x7f -CACHELINE_WORDS = 32 -#endif /* CONFIG_PPC64BRIDGE */ - #ifdef CONFIG_PPC64BRIDGE #define LOAD_BAT(n, reg, RA, RB) \ ld RA,(n*32)+0(reg); \ @@ -161,6 +148,7 @@ __start: bl fix_mem_constants #endif /* CONFIG_APUS */ +#ifndef CONFIG_GEMINI /* Switch MMU off, clear BATs and flush TLB. At this point, r3 contains * the physical address we are running at, returned by prom_init() */ @@ -168,6 +156,7 @@ __start: __after_mmu_off: bl clear_bats bl flush_tlbs +#endif #ifndef CONFIG_POWER4 /* POWER4 doesn't have BATs */ @@ -294,21 +283,14 @@ i##n: \ .long hdlr; \ .long ret_from_except -#define STD_MOL_EXCEPTION(n, label, hdlr, hook) \ - . = n; \ -label: \ - EXCEPTION_PROLOG; \ - MOL_HOOK(hook); \ - addi r3,r1,STACK_FRAME_OVERHEAD; \ - li r20,MSR_KERNEL; \ - bl transfer_to_handler; \ -i##n: \ - .long hdlr; \ - .long ret_from_except - /* System reset */ -#ifdef CONFIG_SMP /* MVME/MTX start the secondary here */ +#ifdef CONFIG_SMP /* MVME/MTX and gemini start the secondary here */ +#ifdef CONFIG_GEMINI + . = 0x100 + b __secondary_start_gemini +#else /* CONFIG_GEMINI */ STD_EXCEPTION(0x100, Reset, __secondary_start_psurge) +#endif /* CONFIG_GEMINI */ #else STD_EXCEPTION(0x100, Reset, UnknownException) #endif @@ -325,7 +307,6 @@ DataAccessCont: DataAccess: EXCEPTION_PROLOG #endif /* CONFIG_PPC64BRIDGE */ - MOL_HOOK(0) mfspr r20,DSISR andis. r0,r20,0xa470 /* weird error? */ bne 1f /* if not, try to put a PTE */ @@ -369,7 +350,6 @@ InstructionAccessCont: InstructionAccess: EXCEPTION_PROLOG #endif /* CONFIG_PPC64BRIDGE */ - MOL_HOOK(1) andis. r0,r23,0x4000 /* no pte found? */ beq 1f /* if so, try to put a PTE */ mr r3,r22 /* into the hash table */ @@ -436,7 +416,6 @@ i0x600: . = 0x700 ProgramCheck: EXCEPTION_PROLOG - MOL_HOOK(2) addi r3,r1,STACK_FRAME_OVERHEAD li r20,MSR_KERNEL rlwimi r20,r23,0,16,16 /* copy EE bit from saved MSR */ @@ -449,7 +428,6 @@ i0x700: . = 0x800 FPUnavailable: EXCEPTION_PROLOG - MOL_HOOK_RESTORE(3) bne load_up_fpu /* if from user, just load it up */ li r20,MSR_KERNEL bl transfer_to_handler /* if from kernel, take a trap */ @@ -460,7 +438,6 @@ i0x800: . = 0x900 Decrementer: EXCEPTION_PROLOG - MOL_HOOK(4) addi r3,r1,STACK_FRAME_OVERHEAD li r20,MSR_KERNEL bl transfer_to_handler @@ -484,7 +461,7 @@ SystemCall: .long ret_from_except /* Single step - not used on 601 */ - STD_MOL_EXCEPTION(0xd00, SingleStep, SingleStepException, 5) + STD_EXCEPTION(0xd00, SingleStep, SingleStepException) STD_EXCEPTION(0xe00, Trap_0e, UnknownException) /* @@ -514,7 +491,6 @@ Trap_0f: */ . = 0x1000 InstructionTLBMiss: - MOL_HOOK_TLBMISS( 14 ) /* * r0: stored ctr * r1: linux style pte ( later becomes ppc hardware pte ) @@ -586,7 +562,6 @@ InstructionAddressInvalid: */ . = 0x1100 DataLoadTLBMiss: - MOL_HOOK_TLBMISS( 15 ) /* * r0: stored ctr * r1: linux style pte ( later becomes ppc hardware pte ) @@ -657,7 +632,6 @@ DataAddressInvalid: */ . = 0x1200 DataStoreTLBMiss: - MOL_HOOK_TLBMISS( 16 ) /* * r0: stored ctr * r1: linux style pte ( later becomes ppc hardware pte ) @@ -704,7 +678,7 @@ DataStoreTLBMiss: mtcrf 0x80,r3 rfi - STD_MOL_EXCEPTION(0x1300, Trap_13, InstructionBreakpoint, 11) + STD_EXCEPTION(0x1300, Trap_13, InstructionBreakpoint) STD_EXCEPTION(0x1400, SMI, SMIException) STD_EXCEPTION(0x1500, Trap_15, UnknownException) STD_EXCEPTION(0x1600, Trap_16, UnknownException) @@ -717,7 +691,7 @@ DataStoreTLBMiss: STD_EXCEPTION(0x1d00, Trap_1d, UnknownException) STD_EXCEPTION(0x1e00, Trap_1e, UnknownException) STD_EXCEPTION(0x1f00, Trap_1f, UnknownException) - STD_MOL_EXCEPTION(0x2000, RunMode, RunModeException, 5) + STD_EXCEPTION(0x2000, RunMode, RunModeException) STD_EXCEPTION(0x2100, Trap_21, UnknownException) STD_EXCEPTION(0x2200, Trap_22, UnknownException) STD_EXCEPTION(0x2300, Trap_23, UnknownException) @@ -739,7 +713,6 @@ DataStoreTLBMiss: #ifdef CONFIG_ALTIVEC AltiVecUnavailable: EXCEPTION_PROLOG - MOL_HOOK_RESTORE(12) bne load_up_altivec /* if from user, just load it up */ li r20,MSR_KERNEL bl transfer_to_handler /* if from kernel, take a trap */ @@ -805,7 +778,6 @@ transfer_to_handler: lwz r24,0(r23) /* virtual address of handler */ lwz r23,4(r23) /* where to go when done */ FIX_SRR1(r20,r22) - MOL_HOOK(6) mtspr SRR0,r24 mtspr SRR1,r20 mtlr r23 @@ -1016,11 +988,6 @@ KernelAltiVec: .globl giveup_altivec giveup_altivec: -#ifdef CONFIG_MOL - mflr r4 - MOL_HOOK_MMU(13, r5) - mtlr r4 -#endif mfmsr r5 oris r5,r5,MSR_VEC@h SYNC @@ -1057,11 +1024,6 @@ giveup_altivec: */ .globl giveup_fpu giveup_fpu: -#ifdef CONFIG_MOL - mflr r4 - MOL_HOOK_MMU(7, r5) - mtlr r4 -#endif mfmsr r5 ori r5,r5,MSR_FP SYNC @@ -1116,7 +1078,7 @@ relocate_kernel: copy_and_flush: addi r5,r5,-4 addi r6,r6,-4 -4: li r0,CACHELINE_WORDS +4: li r0,CACHE_LINE_SIZE/4 mtctr r0 3: addi r6,r6,4 /* copy a cache line */ lwzx r0,r6,r4 @@ -1127,6 +1089,7 @@ copy_and_flush: icbi r6,r3 /* flush the icache line */ cmplw 0,r6,r5 blt 4b + sync /* additional sync needed on g4 */ isync addi r5,r5,4 addi r6,r6,4 @@ -1165,6 +1128,7 @@ fix_mem_constants: icbi r0,r14 /* flush the icache line */ cmpw r12,r13 bne 1b + sync /* additional sync needed on g4 */ isync /* @@ -1199,6 +1163,7 @@ fix_mem_constants: cmpw r12,r13 bne 1b + sync /* additional sync needed on g4 */ isync /* No speculative loading until now */ blr @@ -1266,6 +1231,20 @@ apus_interrupt_entry: #endif /* CONFIG_APUS */ #ifdef CONFIG_SMP +#ifdef CONFIG_GEMINI + .globl __secondary_start_gemini +__secondary_start_gemini: + mfspr r4,HID0 + ori r4,r4,HID0_ICFI + li r3,0 + ori r3,r3,HID0_ICE + andc r4,r4,r3 + mtspr HID0,r4 + sync + bl prom_init + b __secondary_start +#endif /* CONFIG_GEMINI */ + .globl __secondary_start_psurge __secondary_start_psurge: li r24,1 /* cpu # */ @@ -1536,6 +1515,7 @@ _GLOBAL(set_context) * -- Cort */ clear_bats: +#if !defined(CONFIG_GEMINI) li r20,0 mfspr r9,PVR rlwinm r9,r9,16,16,31 /* r9 = 1 for 601, 4 for 604 */ @@ -1559,8 +1539,10 @@ clear_bats: mtspr IBAT2L,r20 mtspr IBAT3U,r20 mtspr IBAT3L,r20 +#endif /* !defined(CONFIG_GEMINI) */ blr +#ifndef CONFIG_GEMINI flush_tlbs: lis r20, 0x40 1: addic. r20, r20, -0x1000 @@ -1579,6 +1561,7 @@ mmu_off: mtspr SRR1,r3 sync RFI +#endif #ifndef CONFIG_POWER4 /* @@ -1690,17 +1673,6 @@ m8260_gorom: blr #endif -#ifdef CONFIG_MOL -/* - * Mac-on-linux hook_table. Don't put this in the data section - - * the base address must be within the first 32KB of RAM. - */ - .globl mol_interface -mol_interface: - .long MOL_INTERFACE_VERSION - .fill 24,4,0 /* space for 24 hooks */ -#endif - /* * We put a few things here that have to be page-aligned. diff --git a/arch/ppc/kernel/head_8xx.S b/arch/ppc/kernel/head_8xx.S index 3bdf141e8494..80eddadadf44 100644 --- a/arch/ppc/kernel/head_8xx.S +++ b/arch/ppc/kernel/head_8xx.S @@ -30,13 +30,6 @@ #include #include #include - -/* XXX need definitions here for 16 byte cachelines on some/all 8xx - -- paulus */ -CACHELINE_BYTES = 32 -LG_CACHELINE_BYTES = 5 -CACHELINE_MASK = 0x1f -CACHELINE_WORDS = 8 .text .globl _stext @@ -757,7 +750,7 @@ relocate_kernel: copy_and_flush: addi r5,r5,-4 addi r6,r6,-4 -4: li r0,CACHELINE_WORDS +4: li r0,CACHE_LINE_SIZE/4 mtctr r0 3: addi r6,r6,4 /* copy a cache line */ lwzx r0,r6,r4 diff --git a/arch/ppc/kernel/idle.c b/arch/ppc/kernel/idle.c index 5aaabccfa5c2..e2a8ac0cc4d5 100644 --- a/arch/ppc/kernel/idle.c +++ b/arch/ppc/kernel/idle.c @@ -56,6 +56,7 @@ int idled(void) case 7: /* 603ev */ case 8: /* 750 */ case 12: /* 7400 */ + case 0x800c: /* 7410 */ do_power_save = 1; } diff --git a/arch/ppc/kernel/irq.c b/arch/ppc/kernel/irq.c index 6609ecda2357..385b12102be1 100644 --- a/arch/ppc/kernel/irq.c +++ b/arch/ppc/kernel/irq.c @@ -176,9 +176,19 @@ setup_irq(unsigned int irq, struct irqaction * new) return 0; } -/* This could be promoted to a real free_irq() ... */ -static int -do_free_irq(int irq, void* dev_id) +#if (defined(CONFIG_8xx) || defined(CONFIG_8260)) +/* Name change so we can catch standard drivers that potentially mess up + * the internal interrupt controller on 8xx and 8260. Just bear with me, + * I don't like this either and I am searching a better solution. For + * now, this is what I need. -- Dan + */ +#define request_irq request_8xxirq +#elif defined(CONFIG_APUS) +#define request_irq request_sysirq +#define free_irq sys_free_irq +#endif + +void free_irq(unsigned int irq, void* dev_id) { irq_desc_t *desc; struct irqaction **p; @@ -209,27 +219,15 @@ do_free_irq(int irq, void* dev_id) barrier(); #endif irq_kfree(action); - return 0; + return; } printk("Trying to free free IRQ%d\n",irq); spin_unlock_irqrestore(&desc->lock,flags); break; } - return -ENOENT; + return; } -#if (defined(CONFIG_8xx) || defined(CONFIG_8260)) -/* Name change so we can catch standard drivers that potentially mess up - * the internal interrupt controller on 8xx and 8260. Just bear with me, - * I don't like this either and I am searching a better solution. For - * now, this is what I need. -- Dan - */ -#define request_irq request_8xxirq -#elif defined(CONFIG_APUS) -#define request_irq request_sysirq -#define free_irq sys_free_irq -#endif - int request_irq(unsigned int irq, void (*handler)(int, void *, struct pt_regs *), unsigned long irqflags, const char * devname, void *dev_id) { @@ -239,8 +237,17 @@ int request_irq(unsigned int irq, void (*handler)(int, void *, struct pt_regs *) if (irq >= NR_IRQS) return -EINVAL; if (!handler) - /* We could implement really free_irq() instead of that... */ - return do_free_irq(irq, dev_id); + { + /* + * free_irq() used to be implemented as a call to + * request_irq() with handler being NULL. Now we have + * a real free_irq() but need to allow the old behavior + * for old code that hasn't caught up yet. + * -- Cort + */ + free_irq(irq, dev_id); + return 0; + } action = (struct irqaction *) irq_kmalloc(sizeof(struct irqaction), GFP_KERNEL); @@ -266,11 +273,6 @@ int request_irq(unsigned int irq, void (*handler)(int, void *, struct pt_regs *) return 0; } -void free_irq(unsigned int irq, void *dev_id) -{ - request_irq(irq, NULL, 0, NULL, dev_id); -} - /* * Generic enable/disable code: this just calls * down into the PIC-specific version for the actual @@ -524,7 +526,7 @@ out: spin_unlock(&desc->lock); } -int do_IRQ(struct pt_regs *regs, int isfake) +int do_IRQ(struct pt_regs *regs) { int cpu = smp_processor_id(); int irq; @@ -546,10 +548,7 @@ int do_IRQ(struct pt_regs *regs, int isfake) goto out; } ppc_irq_dispatch_handler( regs, irq ); - if (ppc_md.post_irq) - ppc_md.post_irq( regs, irq ); - - out: +out: hardirq_exit( cpu ); return 1; /* lets ret_from_int know we can do checks */ } @@ -851,15 +850,18 @@ void __global_restore_flags(unsigned long flags) } #endif /* CONFIG_SMP */ -static struct proc_dir_entry * root_irq_dir; -static struct proc_dir_entry * irq_dir [NR_IRQS]; -static struct proc_dir_entry * smp_affinity_entry [NR_IRQS]; +static struct proc_dir_entry *root_irq_dir; +static struct proc_dir_entry *irq_dir[NR_IRQS]; +static struct proc_dir_entry *smp_affinity_entry[NR_IRQS]; #ifdef CONFIG_IRQ_ALL_CPUS -unsigned int irq_affinity [NR_IRQS] = { [0 ... NR_IRQS-1] = 0xffffffff}; -#else /* CONFIG_IRQ_ALL_CPUS */ -unsigned int irq_affinity [NR_IRQS] = { [0 ... NR_IRQS-1] = 0x00000000}; -#endif /* CONFIG_IRQ_ALL_CPUS */ +#define DEFAULT_CPU_AFFINITY 0xffffffff +#else +#define DEFAULT_CPU_AFFINITY 0x00000001 +#endif + +unsigned int irq_affinity [NR_IRQS] = + { [0 ... NR_IRQS-1] = DEFAULT_CPU_AFFINITY }; #define HEX_DIGITS 8 @@ -919,16 +921,18 @@ static int irq_affinity_write_proc (struct file *file, const char *buffer, err = parse_hex_value(buffer, count, &new_value); -/* Why is this disabled ? --BenH */ -#if 0/*CONFIG_SMP*/ /* * Do not allow disabling IRQs completely - it's a too easy * way to make the system unusable accidentally :-) At least * one online CPU still has to be targeted. + * + * We assume a 1-1 logical<->physical cpu mapping here. If + * we assume that the cpu indices in /proc/irq/../smp_affinity + * are actually logical cpu #'s then we have no problem. + * -- Cort */ if (!(new_value & cpu_online_map)) return -EINVAL; -#endif irq_affinity[irq] = new_value; irq_desc[irq].handler->set_affinity(irq, new_value); diff --git a/arch/ppc/kernel/m8260_setup.c b/arch/ppc/kernel/m8260_setup.c index 5b4f8e85a386..8200e867dddd 100644 --- a/arch/ppc/kernel/m8260_setup.c +++ b/arch/ppc/kernel/m8260_setup.c @@ -119,7 +119,7 @@ m8260_set_rtc_time(unsigned long time) return(0); } -unsigned long __init +unsigned long m8260_get_rtc_time(void) { @@ -206,6 +206,18 @@ m8260_init_IRQ(void) } +/* + * Same hack as 8xx + */ +unsigned long __init m8260_find_end_of_memory(void) +{ + bd_t *binfo; + extern unsigned char __res[]; + + binfo = (bd_t *)__res; + + return binfo->bi_memsize; +} void __init m8260_init(unsigned long r3, unsigned long r4, unsigned long r5, @@ -248,18 +260,8 @@ m8260_init(unsigned long r3, unsigned long r4, unsigned long r5, ppc_md.get_rtc_time = m8260_get_rtc_time; ppc_md.calibrate_decr = m8260_calibrate_decr; -#if 0 - ppc_md.kbd_setkeycode = pckbd_setkeycode; - ppc_md.kbd_getkeycode = pckbd_getkeycode; - ppc_md.kbd_pretranslate = pckbd_pretranslate; - ppc_md.kbd_translate = pckbd_translate; - ppc_md.kbd_unexpected_up = pckbd_unexpected_up; - ppc_md.kbd_leds = pckbd_leds; - ppc_md.kbd_init_hw = pckbd_init_hw; -#ifdef CONFIG_MAGIC_SYSRQ - ppc_md.kbd_sysrq_xlate = pckbd_sysrq_xlate; -#endif -#else + ppc_md.find_end_of_memory = m8260_find_end_of_memory; + ppc_md.kbd_setkeycode = NULL; ppc_md.kbd_getkeycode = NULL; ppc_md.kbd_translate = NULL; @@ -269,7 +271,6 @@ m8260_init(unsigned long r3, unsigned long r4, unsigned long r5, #ifdef CONFIG_MAGIC_SYSRQ ppc_md.kbd_sysrq_xlate = NULL; #endif -#endif #if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE) ppc_ide_md.insw = m8xx_ide_insw; diff --git a/arch/ppc/kernel/m8xx_setup.c b/arch/ppc/kernel/m8xx_setup.c index 9cbce65ac609..40ab288a87f1 100644 --- a/arch/ppc/kernel/m8xx_setup.c +++ b/arch/ppc/kernel/m8xx_setup.c @@ -584,6 +584,25 @@ void ide_interrupt_handler (void *dev) /* -------------------------------------------------------------------- */ +/* + * This is a big hack right now, but it may turn into something real + * someday. + * + * For the 8xx boards (at this time anyway), there is nothing to initialize + * associated the PROM. Rather than include all of the prom.c + * functions in the image just to get prom_init, all we really need right + * now is the initialization of the physical memory region. + */ +unsigned long __init m8xx_find_end_of_memory(void) +{ + bd_t *binfo; + extern unsigned char __res[]; + + binfo = (bd_t *)__res; + + return binfo->bi_memsize; +} + void __init m8xx_init(unsigned long r3, unsigned long r4, unsigned long r5, unsigned long r6, unsigned long r7) @@ -629,18 +648,8 @@ m8xx_init(unsigned long r3, unsigned long r4, unsigned long r5, ppc_md.get_rtc_time = m8xx_get_rtc_time; ppc_md.calibrate_decr = m8xx_calibrate_decr; -#if 0 - ppc_md.kbd_setkeycode = pckbd_setkeycode; - ppc_md.kbd_getkeycode = pckbd_getkeycode; - ppc_md.kbd_pretranslate = pckbd_pretranslate; - ppc_md.kbd_translate = pckbd_translate; - ppc_md.kbd_unexpected_up = pckbd_unexpected_up; - ppc_md.kbd_leds = pckbd_leds; - ppc_md.kbd_init_hw = pckbd_init_hw; -#ifdef CONFIG_MAGIC_SYSRQ - ppc_md.kbd_sysrq_xlate = pckbd_sysrq_xlate; -#endif -#else + ppc_md.find_end_of_memory = m8xx_find_end_of_memory; + ppc_md.kbd_setkeycode = NULL; ppc_md.kbd_getkeycode = NULL; ppc_md.kbd_translate = NULL; @@ -650,7 +659,6 @@ m8xx_init(unsigned long r3, unsigned long r4, unsigned long r5, #ifdef CONFIG_MAGIC_SYSRQ ppc_md.kbd_sysrq_xlate = NULL; #endif -#endif #if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE) ppc_ide_md.insw = m8xx_ide_insw; diff --git a/arch/ppc/kernel/misc.S b/arch/ppc/kernel/misc.S index 3f54003c7182..7958a85ec8f3 100644 --- a/arch/ppc/kernel/misc.S +++ b/arch/ppc/kernel/misc.S @@ -21,20 +21,6 @@ #include #include "ppc_asm.h" -#if defined(CONFIG_4xx) || defined(CONFIG_8xx) -#define CACHE_LINE_SIZE 16 -#define LG_CACHE_LINE_SIZE 4 -#define MAX_COPY_PREFETCH 1 -#elif !defined(CONFIG_PPC64BRIDGE) -#define CACHE_LINE_SIZE 32 -#define LG_CACHE_LINE_SIZE 5 -#define MAX_COPY_PREFETCH 4 -#else -#define CACHE_LINE_SIZE 128 -#define LG_CACHE_LINE_SIZE 7 -#define MAX_COPY_PREFETCH 1 -#endif /* CONFIG_4xx || CONFIG_8xx */ - .text .align 5 @@ -60,14 +46,37 @@ _GLOBAL(reloc_offset) mtlr r0 blr -/* void __no_use_save_flags(unsigned long *flags) */ -_GLOBAL(__no_use_save_flags) +/* void __save_flags_ptr(unsigned long *flags) */ +_GLOBAL(__save_flags_ptr) mfmsr r4 stw r4,0(r3) blr - -/* void __no_use_restore_flags(unsigned long flags) */ -_GLOBAL(__no_use_restore_flags) + /* + * Need these nops here for taking over save/restore to + * handle lost intrs + * -- Cort + */ + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop +_GLOBAL(__save_flags_ptr_end) + +/* void __restore_flags(unsigned long flags) */ +_GLOBAL(__restore_flags) /* * Just set/clear the MSR_EE bit through restore/flags but do not * change anything else. This is needed by the RT system and makes @@ -82,66 +91,95 @@ _GLOBAL(__no_use_restore_flags) /* Check if things are setup the way we want _already_. */ cmpw 0,r3,r4 beqlr - /* are we enabling interrupts? */ - rlwinm. r0,r3,0,16,16 - beq 1f - /* if so, check if there are any lost interrupts */ - lis r7,ppc_n_lost_interrupts@ha - lwz r7,ppc_n_lost_interrupts@l(r7) - cmpi 0,r7,0 /* lost interrupts to process first? */ - bne- do_lost_interrupts 1: SYNC mtmsr r3 SYNC blr - -_GLOBAL(__no_use_cli) + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop +_GLOBAL(__restore_flags_end) + +_GLOBAL(__cli) mfmsr r0 /* Get current interrupt state */ rlwinm r3,r0,16+1,32-1,31 /* Extract old value of 'EE' */ rlwinm r0,r0,0,17,15 /* clear MSR_EE in r0 */ SYNC /* Some chip revs have problems here... */ mtmsr r0 /* Update machine state */ blr /* Done */ - -_GLOBAL(__no_use_sti) - lis r4,ppc_n_lost_interrupts@ha - lwz r4,ppc_n_lost_interrupts@l(r4) + /* + * Need these nops here for taking over save/restore to + * handle lost intrs + * -- Cort + */ + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop +_GLOBAL(__cli_end) + +_GLOBAL(__sti) mfmsr r3 /* Get current state */ ori r3,r3,MSR_EE /* Turn on 'EE' bit */ - cmpi 0,r4,0 /* lost interrupts to process first? */ - bne- do_lost_interrupts SYNC /* Some chip revs have problems here... */ mtmsr r3 /* Update machine state */ blr - -/* - * We were about to enable interrupts but we have to simulate - * some interrupts that were lost by enable_irq first. - */ -_GLOBAL(do_lost_interrupts) - stwu r1,-16(r1) - mflr r0 - stw r0,20(r1) - stw r3,8(r1) -1: bl fake_interrupt - lis r4,ppc_n_lost_interrupts@ha - lwz r4,ppc_n_lost_interrupts@l(r4) - cmpi 0,r4,0 - bne- 1b - lwz r3,8(r1) - SYNC - mtmsr r3 - lwz r0,20(r1) - mtlr r0 - addi r1,r1,16 - blr + /* + * Need these nops here for taking over save/restore to + * handle lost intrs + * -- Cort + */ + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop +_GLOBAL(__sti_end) /* * complement mask on the msr then "or" some values on. * _nmask_and_or_msr(nmask, value_to_or) */ - _GLOBAL(_nmask_and_or_msr) +_GLOBAL(_nmask_and_or_msr) mfmsr r0 /* Get current msr */ andc r0,r0,r3 /* And off the bits set in r3 (first parm) */ or r0,r0,r4 /* Or on the bits in r4 (second parm) */ @@ -267,6 +305,7 @@ _GLOBAL(flush_icache_range) 2: icbi 0,r6 addi r6,r6,CACHE_LINE_SIZE bdnz 2b + sync /* additional sync needed on g4 */ isync blr @@ -1283,7 +1322,7 @@ _GLOBAL(sys_call_table) .long sys_vfork .long sys_getrlimit /* 190 */ .long sys_ni_syscall /* 191 */ /* Unused */ - .long sys_ni_syscall /* 192 - reserved - mmap2 */ + .long sys_mmap2 /* 192 */ .long sys_truncate64 /* 193 */ .long sys_ftruncate64 /* 194 */ .long sys_stat64 /* 195 */ diff --git a/arch/ppc/kernel/mol.h b/arch/ppc/kernel/mol.h deleted file mode 100644 index 6105867e1c22..000000000000 --- a/arch/ppc/kernel/mol.h +++ /dev/null @@ -1,68 +0,0 @@ -/* - * arch/ppc/kernel/mol.h - * - * - * - * Mac-on-Linux hook macros - * - * - * Copyright (C) 2000 Samuel Rydh (samuel@ibrium.se) - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation - * - */ - -#ifndef _PPC_KERNEL_MOL -#define _PPC_KERNEL_MOL - -#include - -#ifdef CONFIG_MOL -#define MOL_INTERFACE_VERSION 3 - -#define MOL_HOOK(hook_num) \ - lwz r0,(mol_interface + 4 * hook_num + 4)@l(0); \ - cmpwi cr1,r0,0; \ - beq+ cr1,777f; \ - mtctr r0; \ - bctrl; \ -777: lwz r0,GPR0(r21) - -#define MOL_HOOK_RESTORE(hook_num) \ - mfcr r2; \ - MOL_HOOK(hook_num); \ - mtcrf 0x80,r2; \ - lwz r2,_CTR(r21); \ - mtctr r2; \ - lwz r2,GPR2(r21) - -#define MOL_HOOK_MMU(hook_num, scr) \ - lis scr,(mol_interface + 4 * hook_num + 4)@ha; \ - lwz scr,(mol_interface + 4 * hook_num + 4)@l(scr); \ - cmpwi cr1,scr,0; \ - beq+ cr1,778f; \ - mtctr scr; \ - bctrl; \ -778: - -#define MOL_HOOK_TLBMISS(hook_num) \ - lwz r0,(mol_interface + 4 * hook_num + 4)@l(0); \ - cmpwi r0,0; \ - beq+ 779f; \ - mflr r3; \ - mtlr r0; \ - blrl; \ - mtlr r3; \ -779: - -#else -#define MOL_HOOK(num) -#define MOL_HOOK_RESTORE(num) -#define MOL_HOOK_MMU(num, scr) -#define MOL_HOOK_TLBMISS(num) -#endif - - -#endif /* _PPC_KERNEL_MOL */ diff --git a/arch/ppc/kernel/open_pic.c b/arch/ppc/kernel/open_pic.c index 919cb57ebc8f..4da044feda8b 100644 --- a/arch/ppc/kernel/open_pic.c +++ b/arch/ppc/kernel/open_pic.c @@ -775,11 +775,17 @@ static void openpic_ipi_action(int cpl, void *dev_id, struct pt_regs *regs) int openpic_get_irq(struct pt_regs *regs) { +/* + * Clean up needed. -VAL + */ +#ifndef CONFIG_GEMINI extern int i8259_irq(int cpu); - +#endif int irq = openpic_irq(); /* Management of the cascade should be moved out of here */ + + /* Yep - because openpic !=> i8259, for one thing. -VAL */ if (open_pic_irq_offset && irq == open_pic_irq_offset) { /* @@ -787,8 +793,10 @@ openpic_get_irq(struct pt_regs *regs) */ if ( chrp_int_ack_special ) irq = *chrp_int_ack_special; +#ifndef CONFIG_GEMINI else irq = i8259_irq( smp_processor_id() ); +#endif openpic_eoi(); } if (irq == OPENPIC_VEC_SPURIOUS + open_pic_irq_offset) { diff --git a/arch/ppc/kernel/pci.c b/arch/ppc/kernel/pci.c index 56a724bc019f..2d32d02cffe0 100644 --- a/arch/ppc/kernel/pci.c +++ b/arch/ppc/kernel/pci.c @@ -399,6 +399,10 @@ pcibios_alloc_controller(void) return hose; } +#ifdef CONFIG_ALL_PPC +/* + * Functions below are used on OpenFirmware machines. + */ static void make_one_node_map(struct device_node* node, u8 pci_bus) { @@ -578,6 +582,95 @@ pci_device_from_OF_node(struct device_node* node, u8* bus, u8* devfn) return 0; } +void __init +pci_process_bridge_OF_ranges(struct pci_controller *hose, + struct device_node *dev, int primary) +{ + unsigned int *ranges, *prev; + int rlen = 0; + int memno = 0; + struct resource *res; + int np, na = prom_n_addr_cells(dev); + np = na + 5; + + /* First we try to merge ranges to fix a problem with some pmacs + * that can have more than 3 ranges, fortunately using contiguous + * addresses -- BenH + */ + ranges = (unsigned int *) get_property(dev, "ranges", &rlen); + prev = NULL; + while ((rlen -= np * sizeof(unsigned int)) >= 0) { + if (prev) { + if (prev[0] == ranges[0] && prev[1] == ranges[1] && + (prev[2] + prev[na+4]) == ranges[2] && + (prev[na+2] + prev[na+4]) == ranges[na+2]) { + prev[na+4] += ranges[na+4]; + ranges[0] = 0; + ranges += np; + continue; + } + } + prev = ranges; + ranges += np; + } + + /* + * The ranges property is laid out as an array of elements, + * each of which comprises: + * cells 0 - 2: a PCI address + * cells 3 or 3+4: a CPU physical address + * (size depending on dev->n_addr_cells) + * cells 4+5 or 5+6: the size of the range + */ + rlen = 0; + hose->io_base_phys = 0; + ranges = (unsigned int *) get_property(dev, "ranges", &rlen); + while ((rlen -= np * sizeof(unsigned int)) >= 0) { + res = NULL; + switch (ranges[0] >> 24) { + case 1: /* I/O space */ + if (ranges[2] != 0) + break; + hose->io_base_phys = ranges[na+2]; + hose->io_base_virt = ioremap(ranges[na+2], ranges[na+4]); + if (primary) + isa_io_base = (unsigned long) hose->io_base_virt; + res = &hose->io_resource; + res->flags = IORESOURCE_IO; + res->start = ranges[2]; + break; + case 2: /* memory space */ + memno = 0; + if (ranges[1] == 0 && ranges[2] == 0 + && ranges[na+4] <= (16 << 20)) { + /* 1st 16MB, i.e. ISA memory area */ + if (primary) + isa_mem_base = ranges[na+2]; + memno = 1; + } + while (memno < 3 && hose->mem_resources[memno].flags) + ++memno; + if (memno == 0) + hose->pci_mem_offset = ranges[na+2] - ranges[2]; + if (memno < 3) { + res = &hose->mem_resources[memno]; + res->flags = IORESOURCE_MEM; + res->start = ranges[na+2]; + } + break; + } + if (res != NULL) { + res->name = dev->full_name; + res->end = res->start + ranges[na+4] - 1; + res->parent = NULL; + res->sibling = NULL; + res->child = NULL; + } + ranges += np; + } +} +#endif /* CONFIG_ALL_PPC */ + void __init pcibios_init(void) { @@ -632,9 +725,6 @@ pcibios_init(void) /* OF fails to initialize IDE controllers on macs * (and maybe other machines) * - * This late fixup is done here since I want it to happen after - * resource assignement, and there's no "late-init" arch hook - * * Ideally, this should be moved to the IDE layer, but we need * to check specifically with Andre Hedrick how to do it cleanly * since the common IDE code seem to care about the fact that the @@ -651,6 +741,9 @@ pcibios_init(void) } } #endif /* CONFIG_BLK_DEV_IDE */ + + if (ppc_md.pcibios_after_init) + ppc_md.pcibios_after_init(); } int __init diff --git a/arch/ppc/kernel/pmac_pci.c b/arch/ppc/kernel/pmac_pci.c index 597f4417a3ac..4a79b7f9164c 100644 --- a/arch/ppc/kernel/pmac_pci.c +++ b/arch/ppc/kernel/pmac_pci.c @@ -24,13 +24,12 @@ #include #include #include +#include #include "pci.h" #undef DEBUG -extern void process_bridge_ranges(struct pci_controller *hose, - struct device_node *dev, int primary); static void add_bridges(struct device_node *dev); /* XXX Could be per-controller, but I don't think we risk anything by @@ -382,17 +381,6 @@ setup_uninorth(struct pci_controller* hose, struct reg_property* addr) hose->ops = ¯isc_pci_ops; hose->cfg_addr = ioremap(addr->address + 0x800000, 0x1000); hose->cfg_data = ioremap(addr->address + 0xc00000, 0x1000); -#if 0 /* done in process_bridge_ranges now - paulus */ - hose->io_base_phys = addr->address; - /* is 0x10000 enough for io space ? */ - hose->io_base_virt = (void *)ioremap(addr->address, 0x10000); - - /* XXX This is the bridge with the PCI expansion bus. We route - * legacy IOs to it. - */ - if (addr->address == 0xf2000000) - isa_io_base = (unsigned long)hose->io_base_virt; -#endif /* We "know" that the bridge at f2000000 has the PCI slots. */ return addr->address == 0xf2000000; } @@ -405,10 +393,6 @@ setup_bandit(struct pci_controller* hose, struct reg_property* addr) ioremap(addr->address + 0x800000, 0x1000); hose->cfg_data = (volatile unsigned char *) ioremap(addr->address + 0xc00000, 0x1000); -#if 0 /* done in process_bridge_ranges now - paulus */ - hose->io_base_phys = addr->address; - hose->io_base_virt = (void *) ioremap(addr->address, 0x10000); -#endif init_bandit(hose); } @@ -421,23 +405,12 @@ setup_chaos(struct pci_controller* hose, struct reg_property* addr) ioremap(addr->address + 0x800000, 0x1000); hose->cfg_data = (volatile unsigned char *) ioremap(addr->address + 0xc00000, 0x1000); -#if 0 /* done in process_bridge_ranges now - paulus */ - hose->io_base_phys = addr->address; - hose->io_base_virt = (void *) ioremap(addr->address, 0x10000); -#endif } void __init setup_grackle(struct pci_controller *hose, unsigned io_space_size) { setup_indirect_pci(hose, 0xfec00000, 0xfee00000); -#if 0 /* done in process_bridge_ranges now - paulus */ - hose->io_base_phys = 0xfe000000; - hose->io_base_virt = (void *) ioremap(0xfe000000, io_space_size); - pci_dram_offset = 0; - isa_mem_base = 0xfd000000; - isa_io_base = (unsigned long) hose->io_base_virt; -#endif if (machine_is_compatible("AAPL,PowerBook1998")) grackle_set_loop_snoop(hose, 1); #if 0 /* Disabled for now, HW problems ??? */ @@ -505,7 +478,7 @@ static void __init add_bridges(struct device_node *dev) /* Interpret the "ranges" property */ /* This also maps the I/O region and sets isa_io/mem_base */ - process_bridge_ranges(hose, dev, primary); + pci_process_bridge_OF_ranges(hose, dev, primary); /* Fixup "bus-range" OF property */ fixup_bus_range(dev); @@ -557,19 +530,56 @@ pmac_pcibios_fixup(void) pcibios_fixup_OF_interrupts(); } -/* We don't want to enable USB controllers absent from the OF tree - * (iBook second controller) - */ int pmac_pci_enable_device_hook(struct pci_dev *dev, int initial) { + struct device_node* node; + + node = pci_device_to_OF_node(dev); + + /* We don't want to enable USB controllers absent from the OF tree + * (iBook second controller) + */ if (dev->vendor == PCI_VENDOR_ID_APPLE - && dev->device == PCI_DEVICE_ID_APPLE_KL_USB) { - struct device_node* node; - node = pci_device_to_OF_node(dev); - if (!node) - return -EINVAL; + && dev->device == PCI_DEVICE_ID_APPLE_KL_USB && !node) + return -EINVAL; + + /* Firewire was disabled after PCI probe, the driver is claiming it, + * so we must re-enable it now, at least until the driver can do it + * itself. + */ + if (node && !strcmp(node->name, "firewire") && + device_is_compatible(node, "pci106b,18")) { + feature_set_firewire_cable_power(node, 1); + feature_set_firewire_power(node, 1); } + return 0; } +/* We power down some devices after they have been probed. They'll + * be powered back on later on + */ +void +pmac_pcibios_after_init(void) +{ + struct device_node* nd; + + nd = find_devices("firewire"); + while (nd) { + if (nd->parent && device_is_compatible(nd, "pci106b,18") + && device_is_compatible(nd->parent, "uni-north")) { + feature_set_firewire_power(nd, 0); + feature_set_firewire_cable_power(nd, 0); + } + nd = nd->next; + } + nd = find_devices("ethernet"); + while (nd) { + if (nd->parent && device_is_compatible(nd, "gmac") + && device_is_compatible(nd->parent, "uni-north")) + feature_set_gmac_power(nd, 0); + nd = nd->next; + } +} + diff --git a/arch/ppc/kernel/pmac_pic.c b/arch/ppc/kernel/pmac_pic.c index 1593b3b1cb81..7b0d50ba6d6d 100644 --- a/arch/ppc/kernel/pmac_pic.c +++ b/arch/ppc/kernel/pmac_pic.c @@ -10,6 +10,7 @@ #include #include #include +#include #include "pmac_pic.h" #include "open_pic.h" @@ -44,10 +45,12 @@ static struct interrupt_info gatwick_int_pool[GATWICK_IRQ_POOL_SIZE]; * since it can lose interrupts (see pmac_set_irq_mask). * -- Cort */ -void __pmac __no_use_set_lost(unsigned long irq_nr) +void __pmac __set_lost(unsigned long irq_nr) { - if (!test_and_set_bit(irq_nr, ppc_lost_interrupts)) + if (!test_and_set_bit(irq_nr, ppc_lost_interrupts)) { atomic_inc(&ppc_n_lost_interrupts); + set_dec(1); + } } static void __pmac pmac_mask_and_ack_irq(unsigned int irq_nr) @@ -373,7 +376,6 @@ pmac_pic_init(void) irqctrler = NULL; } - int_control.int_set_lost = __no_use_set_lost; /* * G3 powermacs and 1999 G3 PowerBooks have 64 interrupts, * 1998 G3 Series PowerBooks have 128, diff --git a/arch/ppc/kernel/pmac_setup.c b/arch/ppc/kernel/pmac_setup.c index 0251a36e3ba0..bd4203c19529 100644 --- a/arch/ppc/kernel/pmac_setup.c +++ b/arch/ppc/kernel/pmac_setup.c @@ -66,6 +66,7 @@ #include #include "local_irq.h" #include "pmac_pic.h" +#include "../mm/mem_pieces.h" #undef SHOW_GATWICK_IRQS @@ -102,6 +103,9 @@ extern int keyboard_sends_linux_keycodes; extern void pmac_nvram_update(void); extern int pmac_pci_enable_device_hook(struct pci_dev *dev, int initial); +extern void pmac_pcibios_after_init(void); + +struct device_node *memory_node; unsigned char drive_info; @@ -470,7 +474,7 @@ void note_bootable_part(kdev_t dev, int part, int goodness) char *p; /* Do nothing if the root has been set already. */ - if ((goodness < current_root_goodness) && + if ((goodness <= current_root_goodness) && (ROOT_DEV != to_kdev_t(DEFAULT_ROOT_DEVICE))) return; p = strstr(saved_command_line, "root="); @@ -635,6 +639,88 @@ void pmac_ide_init_hwif_ports(hw_regs_t *hw, ide_ioreg_t data_port, ide_ioreg_t #endif #endif +/* + * Read in a property describing some pieces of memory. + */ + +static void __init get_mem_prop(char *name, struct mem_pieces *mp) +{ + struct reg_property *rp; + int i, s; + unsigned int *ip; + int nac = prom_n_addr_cells(memory_node); + int nsc = prom_n_size_cells(memory_node); + + ip = (unsigned int *) get_property(memory_node, name, &s); + if (ip == NULL) { + printk(KERN_ERR "error: couldn't get %s property on /memory\n", + name); + abort(); + } + s /= (nsc + nac) * 4; + rp = mp->regions; + for (i = 0; i < s; ++i, ip += nac+nsc) { + if (nac >= 2 && ip[nac-2] != 0) + continue; + rp->address = ip[nac-1]; + if (nsc >= 2 && ip[nac+nsc-2] != 0) + rp->size = ~0U; + else + rp->size = ip[nac+nsc-1]; + ++rp; + } + mp->n_regions = rp - mp->regions; + + /* Make sure the pieces are sorted. */ + mem_pieces_sort(mp); + mem_pieces_coalesce(mp); +} + +/* + * On systems with Open Firmware, collect information about + * physical RAM and which pieces are already in use. + * At this point, we have (at least) the first 8MB mapped with a BAT. + * Our text, data, bss use something over 1MB, starting at 0. + * Open Firmware may be using 1MB at the 4MB point. + */ +unsigned long __init pmac_find_end_of_memory(void) +{ + unsigned long a, total; + struct mem_pieces phys_mem; + + memory_node = find_devices("memory"); + if (memory_node == NULL) { + printk(KERN_ERR "can't find memory node\n"); + abort(); + } + + /* + * Find out where physical memory is, and check that it + * starts at 0 and is contiguous. It seems that RAM is + * always physically contiguous on Power Macintoshes. + * + * Supporting discontiguous physical memory isn't hard, + * it just makes the virtual <-> physical mapping functions + * more complicated (or else you end up wasting space + * in mem_map). + */ + get_mem_prop("reg", &phys_mem); + if (phys_mem.n_regions == 0) + panic("No RAM??"); + a = phys_mem.regions[0].address; + if (a != 0) + panic("RAM doesn't start at physical address 0"); + total = phys_mem.regions[0].size; + + if (phys_mem.n_regions > 1) { + printk("RAM starting at 0x%x is not contiguous\n", + phys_mem.regions[1].address); + printk("Using RAM from 0 to 0x%lx\n", total-1); + } + + return total; +} + void __init pmac_init(unsigned long r3, unsigned long r4, unsigned long r5, unsigned long r6, unsigned long r7) @@ -656,6 +742,7 @@ pmac_init(unsigned long r3, unsigned long r4, unsigned long r5, ppc_md.pcibios_fixup = pmac_pcibios_fixup; ppc_md.pcibios_enable_device_hook = pmac_pci_enable_device_hook; + ppc_md.pcibios_after_init = pmac_pcibios_after_init; ppc_md.restart = pmac_restart; ppc_md.power_off = pmac_power_off; @@ -666,6 +753,8 @@ pmac_init(unsigned long r3, unsigned long r4, unsigned long r5, ppc_md.get_rtc_time = pmac_get_rtc_time; ppc_md.calibrate_decr = pmac_calibrate_decr; + ppc_md.find_end_of_memory = pmac_find_end_of_memory; + #ifdef CONFIG_VT #ifdef CONFIG_INPUT ppc_md.kbd_init_hw = mac_hid_init_hw; diff --git a/arch/ppc/kernel/ppc8260_pic.h b/arch/ppc/kernel/ppc8260_pic.h index b073dbe6b51c..8ec12fe7b867 100644 --- a/arch/ppc/kernel/ppc8260_pic.h +++ b/arch/ppc/kernel/ppc8260_pic.h @@ -8,8 +8,7 @@ extern struct hw_interrupt_type ppc8260_pic; void m8260_pic_init(void); void m8260_do_IRQ(struct pt_regs *regs, - int cpu, - int isfake); + int cpu); int m8260_get_irq(struct pt_regs *regs); #endif /* _PPC_KERNEL_PPC8260_H */ diff --git a/arch/ppc/kernel/ppc8xx_pic.c b/arch/ppc/kernel/ppc8xx_pic.c index 0ec85e541294..a673eb5acdbc 100644 --- a/arch/ppc/kernel/ppc8xx_pic.c +++ b/arch/ppc/kernel/ppc8xx_pic.c @@ -67,8 +67,7 @@ struct hw_interrupt_type ppc8xx_pic = { #if 0 void m8xx_do_IRQ(struct pt_regs *regs, - int cpu, - int isfake) + int cpu) { int irq; unsigned long bits = 0; @@ -158,13 +157,15 @@ int request_irq(unsigned int irq, void (*handler)(int, void *, struct pt_regs *) */ switch (irq) { #ifdef IDE0_INTERRUPT - case IDE0_INTERRUPT: /* fall through */ + case IDE0_INTERRUPT: /* IDE0 */ + return (request_8xxirq(irq, handler, irqflags, devname, + dev_id)); #endif #ifdef IDE1_INTERRUPT - case IDE1_INTERRUPT: /* fall through */ + case IDE1_INTERRUPT: /* IDE1 */ + return (request_8xxirq(irq, handler, irqflags, devname, + dev_id)); #endif - return (request_8xxirq(irq, handler, irqflags, devname, dev_id)); - default: /* unknown IRQ -> panic */ panic("request_irq"); } diff --git a/arch/ppc/kernel/ppc8xx_pic.h b/arch/ppc/kernel/ppc8xx_pic.h index 13518bb0650f..ad90c0bfe973 100644 --- a/arch/ppc/kernel/ppc8xx_pic.h +++ b/arch/ppc/kernel/ppc8xx_pic.h @@ -8,8 +8,7 @@ extern struct hw_interrupt_type ppc8xx_pic; void m8xx_pic_init(void); void m8xx_do_IRQ(struct pt_regs *regs, - int cpu, - int isfake); + int cpu); int m8xx_get_irq(struct pt_regs *regs); #ifdef CONFIG_MBX diff --git a/arch/ppc/kernel/ppc_asm.h b/arch/ppc/kernel/ppc_asm.h index 59c377c4d419..479edfa4be90 100644 --- a/arch/ppc/kernel/ppc_asm.h +++ b/arch/ppc/kernel/ppc_asm.h @@ -130,3 +130,22 @@ #define MTMSRD(r) mtmsr r #define CLR_TOP32(r) #endif /* CONFIG_PPC64BRIDGE */ + +/* + * Defines for cache-line size etc. + */ +#if defined(CONFIG_4xx) || defined(CONFIG_8xx) +#define CACHE_LINE_SIZE 16 +#define LG_CACHE_LINE_SIZE 4 +#define MAX_COPY_PREFETCH 1 + +#elif !defined(CONFIG_PPC64BRIDGE) +#define CACHE_LINE_SIZE 32 +#define LG_CACHE_LINE_SIZE 5 +#define MAX_COPY_PREFETCH 4 + +#else +#define CACHE_LINE_SIZE 128 +#define LG_CACHE_LINE_SIZE 7 +#define MAX_COPY_PREFETCH 1 +#endif /* CONFIG_4xx || CONFIG_8xx */ diff --git a/arch/ppc/kernel/ppc_ksyms.c b/arch/ppc/kernel/ppc_ksyms.c index 3ffecdb674e0..f32a2881ed2e 100644 --- a/arch/ppc/kernel/ppc_ksyms.c +++ b/arch/ppc/kernel/ppc_ksyms.c @@ -55,12 +55,11 @@ extern void transfer_to_handler(void); extern void syscall_trace(void); -extern void do_IRQ(struct pt_regs *regs, int isfake); +extern void do_IRQ(struct pt_regs *regs); extern void MachineCheckException(struct pt_regs *regs); extern void AlignmentException(struct pt_regs *regs); extern void ProgramCheckException(struct pt_regs *regs); extern void SingleStepException(struct pt_regs *regs); -extern void do_lost_interrupts(unsigned long); extern int do_signal(sigset_t *, struct pt_regs *); extern int pmac_newworld; extern int sys_sigreturn(struct pt_regs *regs); @@ -83,7 +82,6 @@ EXPORT_SYMBOL(SingleStepException); EXPORT_SYMBOL(sys_sigreturn); EXPORT_SYMBOL(ppc_n_lost_interrupts); EXPORT_SYMBOL(ppc_lost_interrupts); -EXPORT_SYMBOL(do_lost_interrupts); EXPORT_SYMBOL(enable_irq); EXPORT_SYMBOL(disable_irq); EXPORT_SYMBOL(disable_irq_nosync); @@ -277,9 +275,11 @@ EXPORT_SYMBOL(feature_set); EXPORT_SYMBOL(feature_clear); EXPORT_SYMBOL(feature_test); EXPORT_SYMBOL(feature_set_gmac_power); -EXPORT_SYMBOL(feature_set_gmac_phy_reset); +EXPORT_SYMBOL(feature_gmac_phy_reset); EXPORT_SYMBOL(feature_set_usb_power); EXPORT_SYMBOL(feature_set_firewire_power); +EXPORT_SYMBOL(feature_set_firewire_cable_power); +EXPORT_SYMBOL(feature_set_airport_power); #endif /* defined(CONFIG_ALL_PPC) */ #if defined(CONFIG_BOOTX_TEXT) EXPORT_SYMBOL(bootx_update_display); @@ -314,7 +314,14 @@ EXPORT_SYMBOL(screen_info); #endif EXPORT_SYMBOL(__delay); -EXPORT_SYMBOL(int_control); +EXPORT_SYMBOL(__sti); +EXPORT_SYMBOL(__sti_end); +EXPORT_SYMBOL(__cli); +EXPORT_SYMBOL(__cli_end); +EXPORT_SYMBOL(__save_flags_ptr); +EXPORT_SYMBOL(__save_flags_ptr_end); +EXPORT_SYMBOL(__restore_flags); +EXPORT_SYMBOL(__restore_flags_end); EXPORT_SYMBOL(timer_interrupt_intercept); EXPORT_SYMBOL(timer_interrupt); EXPORT_SYMBOL(do_IRQ_intercept); @@ -331,9 +338,6 @@ EXPORT_SYMBOL(xmon); EXPORT_SYMBOL(__up); EXPORT_SYMBOL(__down); EXPORT_SYMBOL(__down_interruptible); -EXPORT_SYMBOL(__down_trylock); -EXPORT_SYMBOL(down_read_failed); -EXPORT_SYMBOL(down_write_failed); #if defined(CONFIG_KGDB) || defined(CONFIG_XMON) extern void (*debugger)(struct pt_regs *regs); @@ -362,6 +366,8 @@ EXPORT_SYMBOL(do_softirq); EXPORT_SYMBOL(next_mmu_context); EXPORT_SYMBOL(set_context); EXPORT_SYMBOL(mmu_context_overflow); +EXPORT_SYMBOL(flush_hash_page); /* For MOL */ +EXPORT_SYMBOL(handle_mm_fault); /* For MOL */ EXPORT_SYMBOL_NOVERS(disarm_decr); #if !defined(CONFIG_8xx) && !defined(CONFIG_4xx) extern long *intercept_table; @@ -369,17 +375,3 @@ EXPORT_SYMBOL(intercept_table); #endif extern long *ret_from_intercept; EXPORT_SYMBOL(ret_from_intercept); - -#ifdef CONFIG_MOL -extern ulong mol_interface[]; -extern PTE *Hash; -extern unsigned long Hash_mask; -extern void (*ret_from_except)(void); -extern struct task_struct *last_task_used_altivec; -EXPORT_SYMBOL_NOVERS(mol_interface); -EXPORT_SYMBOL(Hash); -EXPORT_SYMBOL(Hash_mask); -EXPORT_SYMBOL(handle_mm_fault); -EXPORT_SYMBOL(last_task_used_math); -EXPORT_SYMBOL(ret_from_except); -#endif /* CONFIG_MOL */ diff --git a/arch/ppc/kernel/prep_pci.c b/arch/ppc/kernel/prep_pci.c index 369e8c47cef6..4e0f3f64d70f 100644 --- a/arch/ppc/kernel/prep_pci.c +++ b/arch/ppc/kernel/prep_pci.c @@ -437,8 +437,8 @@ static char ibm8xx_pci_IRQ_map[23] __prepdata = { static char ibm8xx_pci_IRQ_routes[] __prepdata = { 0, /* Line 0 - unused */ - 13, /* Line 1 */ - 10, /* Line 2 */ + 15, /* Line 1 */ + 15, /* Line 2 */ 15, /* Line 3 */ 15, /* Line 4 */ }; diff --git a/arch/ppc/kernel/prep_setup.c b/arch/ppc/kernel/prep_setup.c index cf6edf78e556..498ffe64b955 100644 --- a/arch/ppc/kernel/prep_setup.c +++ b/arch/ppc/kernel/prep_setup.c @@ -312,7 +312,9 @@ prep_setup_arch(void) /* remap the VGA memory */ vgacon_remap_base = 0xf0000000; /*vgacon_remap_base = ioremap(0xc0000000, 0xba000);*/ - conswitchp = &vga_con; + conswitchp = &vga_con; +#else + conswitchp = &dummy_con; #endif } @@ -504,8 +506,8 @@ prep_direct_restart(char *cmd) __cli(); __asm__ __volatile__("\n\ - mtspr 26, %1 /* SRR0 */ - mtspr 27, %0 /* SRR1 */ + mtspr 26, %1 /* SRR0 */ \n\ + mtspr 27, %0 /* SRR1 */ \n\ rfi" : : "r" (defaultmsr), "r" (jumpaddr)); @@ -575,7 +577,7 @@ prep_irq_cannonicalize(u_int irq) #if 0 void __prep -prep_do_IRQ(struct pt_regs *regs, int cpu, int isfake) +prep_do_IRQ(struct pt_regs *regs, int cpu) { int irq; @@ -691,6 +693,35 @@ prep_ide_init_hwif_ports (hw_regs_t *hw, ide_ioreg_t data_port, ide_ioreg_t ctrl } #endif +/* + * This finds the amount of physical ram and does necessary + * setup for prep. This is pretty architecture specific so + * this will likely stay separate from the pmac. + * -- Cort + */ +unsigned long __init prep_find_end_of_memory(void) +{ + unsigned long total; +#ifdef CONFIG_PREP_RESIDUAL + total = res->TotalMemory; +#else + total = 0; +#endif + + if (total == 0 ) + { + /* + * I need a way to probe the amount of memory if the residual + * data doesn't contain it. -- Cort + */ + printk("Ramsize from residual data was 0 -- Probing for value\n"); + total = 0x02000000; + printk("Ramsize default to be %ldM\n", total>>20); + } + + return (total); +} + unsigned long *MotSave_SmpIar; unsigned char *MotSave_CpusState[2]; @@ -750,7 +781,8 @@ prep_init(unsigned long r3, unsigned long r4, unsigned long r5, { if ( !strncmp(res->VitalProductData.PrintableModel,"IBM",3) ) _prep_type = _PREP_IBM; - _prep_type = _PREP_Motorola; + else + _prep_type = _PREP_Motorola; } else /* assume motorola if no residual (netboot?) */ #endif @@ -784,6 +816,8 @@ prep_init(unsigned long r3, unsigned long r4, unsigned long r5, ppc_md.time_init = mk48t59_init; } + ppc_md.find_end_of_memory = prep_find_end_of_memory; + #if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE) ppc_ide_md.insw = prep_ide_insw; ppc_ide_md.outsw = prep_ide_outsw; diff --git a/arch/ppc/kernel/prep_time.c b/arch/ppc/kernel/prep_time.c index 78634c6e2591..3b6c435b6843 100644 --- a/arch/ppc/kernel/prep_time.c +++ b/arch/ppc/kernel/prep_time.c @@ -30,6 +30,8 @@ #include +extern spinlock_t rtc_lock; + /* * The motorola uses the m48t18 rtc (includes DS1643) whose registers * are at a higher end of nvram (1ff8-1fff) than the ibm mc146818 @@ -55,6 +57,7 @@ int mc146818_set_rtc_time(unsigned long nowtime) unsigned char save_control, save_freq_select; struct rtc_time tm; + spin_lock(&rtc_lock); to_tm(nowtime, &tm); /* tell the clock it's being set */ @@ -92,6 +95,7 @@ int mc146818_set_rtc_time(unsigned long nowtime) */ CMOS_WRITE(save_control, RTC_CONTROL); CMOS_WRITE(save_freq_select, RTC_FREQ_SELECT); + spin_unlock(&rtc_lock); return 0; } @@ -149,7 +153,7 @@ int mk48t59_set_rtc_time(unsigned long nowtime) unsigned char save_control; struct rtc_time tm; - + spin_lock(&rtc_lock); to_tm(nowtime, &tm); /* tell the clock it's being written */ @@ -175,6 +179,7 @@ int mk48t59_set_rtc_time(unsigned long nowtime) /* Turn off the write bit. */ ppc_md.nvram_write_val(MK48T59_RTC_CONTROLA, save_control); + spin_unlock(&rtc_lock); return 0; } diff --git a/arch/ppc/kernel/process.c b/arch/ppc/kernel/process.c index 259481bcdc0e..462f16790ae2 100644 --- a/arch/ppc/kernel/process.c +++ b/arch/ppc/kernel/process.c @@ -377,45 +377,6 @@ copy_thread(int nr, unsigned long clone_flags, unsigned long usp, return 0; } -/* - * XXX ld.so expects the auxiliary table to start on - * a 16-byte boundary, so we have to find it and - * move it up. :-( - */ -static inline void shove_aux_table(unsigned long sp) -{ - int argc; - char *p; - unsigned long e; - unsigned long aux_start, offset; - - if (__get_user(argc, (int *)sp)) - return; - sp += sizeof(int) + (argc + 1) * sizeof(char *); - /* skip over the environment pointers */ - do { - if (__get_user(p, (char **)sp)) - return; - sp += sizeof(char *); - } while (p != NULL); - aux_start = sp; - /* skip to the end of the auxiliary table */ - do { - if (__get_user(e, (unsigned long *)sp)) - return; - sp += 2 * sizeof(unsigned long); - } while (e != AT_NULL); - offset = ((aux_start + 15) & ~15) - aux_start; - if (offset != 0) { - do { - sp -= sizeof(unsigned long); - if (__get_user(e, (unsigned long *)sp) - || __put_user(e, (unsigned long *)(sp + offset))) - return; - } while (sp > aux_start); - } -} - /* * Set up a thread for executing a new program */ @@ -425,7 +386,6 @@ void start_thread(struct pt_regs *regs, unsigned long nip, unsigned long sp) regs->nip = nip; regs->gpr[1] = sp; regs->msr = MSR_USER; - shove_aux_table(sp); if (last_task_used_math == current) last_task_used_math = 0; if (last_task_used_altivec == current) diff --git a/arch/ppc/kernel/prom.c b/arch/ppc/kernel/prom.c index f8eb0729df99..0d75b86aba55 100644 --- a/arch/ppc/kernel/prom.c +++ b/arch/ppc/kernel/prom.c @@ -757,14 +757,9 @@ prom_init(int r3, int r4, prom_entry pp) setup_disp_fake_bi(RELOC(prom_disp_node)); #endif - /* If pmac, then use quiesce call. We can't rely on prom_version - * since some old iMacs appear to have an incorrect /openprom/model - * entry in the device tree - */ - if (!chrp) { - prom_print(RELOC("Calling quiesce ...\n")); - call_prom(RELOC("quiesce"), 0, 0); - } + /* Use quiesce call to get OF to shut down any devices it's using */ + prom_print(RELOC("Calling quiesce ...\n")); + call_prom(RELOC("quiesce"), 0, 0); #ifdef CONFIG_BOOTX_TEXT if (!chrp && RELOC(disp_bi)) { @@ -839,7 +834,7 @@ prom_welcome(boot_infos_t* bi, unsigned long phys) __asm__ __volatile__ ("mfspr %0, 1008" : "=r" (flags)); prom_drawhex(flags); } - if (pvr == 8 || pvr == 12) { + if (pvr == 8 || pvr == 12 || pvr == 0x800c) { prom_drawstring(RELOC("\nICTC : 0x")); __asm__ __volatile__ ("mfspr %0, 1019" : "=r" (flags)); prom_drawhex(flags); @@ -986,9 +981,11 @@ check_display(unsigned long mem) prom_print(RELOC("... failed\n")); } else { prom_print(RELOC("... ok\n")); - - /* Setup a useable color table when the appropriate - * method is available. Should update this to set-colors */ + /* + * Setup a usable color table when the appropriate + * method is available. + * Should update this to use set-colors. + */ for (i = 0; i < 32; i++) if (prom_set_color(ih, i, RELOC(default_colors)[i*3], RELOC(default_colors)[i*3+1], @@ -1267,7 +1264,10 @@ finish_node(struct device_node *np, unsigned long mem_start, np->name = get_property(np, "name", 0); np->type = get_property(np, "device_type", 0); - +#if 0 + np->n_addr_cells = naddrc; + np->n_size_cells = nsizec; +#endif /* get the device addresses and interrupts */ if (ifunc != NULL) { mem_start = ifunc(np, mem_start, naddrc, nsizec); @@ -1283,6 +1283,16 @@ finish_node(struct device_node *np, unsigned long mem_start, ip = (int *) get_property(np, "#size-cells", 0); if (ip != NULL) nsizec = *ip; +#if 0 + if (np->parent == NULL) { + /* + * Set the n_addr/size_cells on the root to its + * own values, rather than 0. + */ + np->n_addr_cells = naddrc; + np->n_size_cells = nsizec; + } +#endif /* the f50 sets the name to 'display' and 'compatible' to what we * expect for the name -- Cort @@ -1497,6 +1507,34 @@ void relocate_nodes(void) } } +int +prom_n_addr_cells(struct device_node* np) +{ + int* ip; + do { + if (np->parent) + np = np->parent; + ip = (int *) get_property(np, "#address-cells", 0); + if (ip != NULL) + return *ip; + } while(np->parent); + return 0; +} + +int +prom_n_size_cells(struct device_node* np) +{ + int* ip; + do { + if (np->parent) + np = np->parent; + ip = (int *) get_property(np, "#size-cells", 0); + if (ip != NULL) + return *ip; + } while(np->parent); + return 0; +} + __init static unsigned long interpret_pci_props(struct device_node *np, unsigned long mem_start, @@ -1566,6 +1604,8 @@ interpret_pci_props(struct device_node *np, unsigned long mem_start, } ip = (int *) get_property(np, "AAPL,interrupts", &l); + if (ip == 0 && np->parent) + ip = (int *) get_property(np->parent, "AAPL,interrupts", &l); if (ip == 0) ip = (int *) get_property(np, "interrupts", &l); if (ip != 0) { @@ -1761,7 +1801,7 @@ interpret_root_props(struct device_node *np, unsigned long mem_start, i = 0; adr = (struct address_range *) mem_start; while ((l -= rpsize) >= 0) { - adr[i].space = 0; + adr[i].space = (naddrc >= 2? rp[naddrc-2]: 0); adr[i].address = rp[naddrc - 1]; adr[i].size = rp[naddrc + nsizec - 1]; ++i; @@ -1978,12 +2018,13 @@ get_property(struct device_node *np, const char *name, int *lenp) { struct property *pp; - for (pp = np->properties; pp != 0; pp = pp->next) - if (strcmp(pp->name, name) == 0) { + for (pp = np->properties; pp != 0; pp = pp->next) { + if (name && strcmp(pp->name, name) == 0) { if (lenp != 0) *lenp = pp->length; return pp->value; } + } return 0; } @@ -2161,9 +2202,10 @@ bootx_update_display(unsigned long phys, int width, int height, { if (disp_bi == 0) return; - /* check it's the same frame buffer (within 16MB) */ - if ((phys ^ (unsigned long)disp_bi->dispDeviceBase) & 0xff000000) + /* check it's the same frame buffer (within 64MB) */ + if ((phys ^ (unsigned long)disp_bi->dispDeviceBase) & 0xfc000000) { return; + } disp_bi->dispDeviceBase = (__u8 *) phys; disp_bi->dispDeviceRect[0] = 0; diff --git a/arch/ppc/kernel/semaphore.c b/arch/ppc/kernel/semaphore.c index d630c80dca31..f3e195a1aef7 100644 --- a/arch/ppc/kernel/semaphore.c +++ b/arch/ppc/kernel/semaphore.c @@ -9,131 +9,122 @@ * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version * 2 of the License, or (at your option) any later version. + * + * April 2001 - Reworked by Paul Mackerras + * to eliminate the SMP races in the old version between the updates + * of `count' and `waking'. Now we use negative `count' values to + * indicate that some process(es) are waiting for the semaphore. */ #include - +#include #include -#include /* - * Semaphores are implemented using a two-way counter: - * The "count" variable is decremented for each process - * that tries to sleep, while the "waking" variable is - * incremented when the "up()" code goes to wake up waiting - * processes. - * - * Notably, the inline "up()" and "down()" functions can - * efficiently test if they need to do any extra work (up - * needs to do something only if count was negative before - * the increment operation. - * - * waking_non_zero() (from asm/semaphore.h) must execute - * atomically. + * Atomically update sem->count. + * This does the equivalent of the following: * - * When __up() is called, the count was negative before - * incrementing it, and we need to wake up somebody. - * - * This routine adds one to the count of processes that need to - * wake up and exit. ALL waiting processes actually wake up but - * only the one that gets to the "waking" field first will gate - * through and acquire the semaphore. The others will go back - * to sleep. - * - * Note that these functions are only called when there is - * contention on the lock, and as such all this is the - * "non-critical" part of the whole semaphore business. The - * critical part is the inline stuff in - * where we want to avoid any extra jumps and calls. + * old_count = sem->count; + * tmp = MAX(old_count, 0) + incr; + * sem->count = tmp; + * return old_count; */ +static inline int __sem_update_count(struct semaphore *sem, int incr) +{ + int old_count, tmp; + + __asm__ __volatile__("\n" +"1: lwarx %0,0,%3\n" +" srawi %1,%0,31\n" +" andc %1,%0,%1\n" +" add %1,%1,%4\n" +" stwcx. %1,0,%3\n" +" bne 1b" + : "=&r" (old_count), "=&r" (tmp), "=m" (sem->count) + : "r" (&sem->count), "r" (incr), "m" (sem->count) + : "cc"); + + return old_count; +} + void __up(struct semaphore *sem) { - wake_one_more(sem); + /* + * Note that we incremented count in up() before we came here, + * but that was ineffective since the result was <= 0, and + * any negative value of count is equivalent to 0. + * This ends up setting count to 1, unless count is now > 0 + * (i.e. because some other cpu has called up() in the meantime), + * in which case we just increment count. + */ + __sem_update_count(sem, 1); wake_up(&sem->wait); } /* - * Perform the "down" function. Return zero for semaphore acquired, - * return negative for signalled out of the function. - * - * If called from __down, the return is ignored and the wait loop is - * not interruptible. This means that a task waiting on a semaphore - * using "down()" cannot be killed until someone does an "up()" on - * the semaphore. - * - * If called from __down_interruptible, the return value gets checked - * upon return. If the return value is negative then the task continues - * with the negative value in the return register (it can be tested by - * the caller). - * - * Either form may be used in conjunction with "up()". - * + * Note that when we come in to __down or __down_interruptible, + * we have already decremented count, but that decrement was + * ineffective since the result was < 0, and any negative value + * of count is equivalent to 0. + * Thus it is only when we decrement count from some value > 0 + * that we have actually got the semaphore. */ +void __down(struct semaphore *sem) +{ + struct task_struct *tsk = current; + DECLARE_WAITQUEUE(wait, tsk); -#define DOWN_VAR \ - struct task_struct *tsk = current; \ - wait_queue_t wait; \ - init_waitqueue_entry(&wait, tsk); - -#define DOWN_HEAD(task_state) \ - \ - \ - tsk->state = (task_state); \ - add_wait_queue(&sem->wait, &wait); \ - \ - /* \ - * Ok, we're set up. sem->count is known to be less than zero \ - * so we must wait. \ - * \ - * We can let go the lock for purposes of waiting. \ - * We re-acquire it after awaking so as to protect \ - * all semaphore operations. \ - * \ - * If "up()" is called before we call waking_non_zero() then \ - * we will catch it right away. If it is called later then \ - * we will have to go through a wakeup cycle to catch it. \ - * \ - * Multiple waiters contend for the semaphore lock to see \ - * who gets to gate through and who has to wait some more. \ - */ \ - for (;;) { + tsk->state = TASK_UNINTERRUPTIBLE; + add_wait_queue_exclusive(&sem->wait, &wait); + smp_wmb(); -#define DOWN_TAIL(task_state) \ - tsk->state = (task_state); \ - } \ - tsk->state = TASK_RUNNING; \ + /* + * Try to get the semaphore. If the count is > 0, then we've + * got the semaphore; we decrement count and exit the loop. + * If the count is 0 or negative, we set it to -1, indicating + * that we are asleep, and then sleep. + */ + while (__sem_update_count(sem, -1) <= 0) { + schedule(); + tsk->state = TASK_UNINTERRUPTIBLE; + } remove_wait_queue(&sem->wait, &wait); + tsk->state = TASK_RUNNING; -void __down(struct semaphore * sem) -{ - DOWN_VAR - DOWN_HEAD(TASK_UNINTERRUPTIBLE) - if (waking_non_zero(sem)) - break; - schedule(); - DOWN_TAIL(TASK_UNINTERRUPTIBLE) + /* + * If there are any more sleepers, wake one of them up so + * that it can either get the semaphore, or set count to -1 + * indicating that there are still processes sleeping. + */ + wake_up(&sem->wait); } int __down_interruptible(struct semaphore * sem) { - int ret = 0; - DOWN_VAR - DOWN_HEAD(TASK_INTERRUPTIBLE) + int retval = 0; + struct task_struct *tsk = current; + DECLARE_WAITQUEUE(wait, tsk); - ret = waking_non_zero_interruptible(sem, tsk); - if (ret) - { - if (ret == 1) - /* ret != 0 only if we get interrupted -arca */ - ret = 0; - break; - } - schedule(); - DOWN_TAIL(TASK_INTERRUPTIBLE) - return ret; -} + tsk->state = TASK_INTERRUPTIBLE; + add_wait_queue_exclusive(&sem->wait, &wait); + smp_wmb(); -int __down_trylock(struct semaphore * sem) -{ - return waking_non_zero_trylock(sem); + while (__sem_update_count(sem, -1) <= 0) { + if (signal_pending(current)) { + /* + * A signal is pending - give up trying. + * Set sem->count to 0 if it is negative, + * since we are no longer sleeping. + */ + __sem_update_count(sem, 0); + retval = -EINTR; + break; + } + schedule(); + tsk->state = TASK_INTERRUPTIBLE; + } + tsk->state = TASK_RUNNING; + remove_wait_queue(&sem->wait, &wait); + wake_up(&sem->wait); + return retval; } diff --git a/arch/ppc/kernel/setup.c b/arch/ppc/kernel/setup.c index 5ad504503551..be4c051f6f6b 100644 --- a/arch/ppc/kernel/setup.c +++ b/arch/ppc/kernel/setup.c @@ -73,6 +73,12 @@ extern void apus_init(unsigned long r3, unsigned long r6, unsigned long r7); +extern void gemini_init(unsigned long r3, + unsigned long r4, + unsigned long r5, + unsigned long r6, + unsigned long r7); + #ifdef CONFIG_XMON extern void xmon_map_scc(void); #endif @@ -80,13 +86,6 @@ extern void xmon_map_scc(void); extern boot_infos_t *boot_infos; char saved_command_line[256]; unsigned char aux_device_present; -struct int_control_struct int_control = -{ - __no_use_cli, - __no_use_sti, - __no_use_restore_flags, - __no_use_save_flags -}; struct ide_machdep_calls ppc_ide_md; int parse_bootinfo(void); @@ -548,6 +547,11 @@ identify_machine(unsigned long r3, unsigned long r4, unsigned long r5, case _MACH_apus: apus_init(r3, r4, r5, r6, r7); break; +#endif +#ifdef CONFIG_GEMINI + case _MACH_gemini: + gemini_init(r3, r4, r5, r6, r7); + break; #endif default: printk("Unknown machine type in identify_machine!\n"); diff --git a/arch/ppc/kernel/sleep.S b/arch/ppc/kernel/sleep.S index b73acd6ce156..38bb720ad9ba 100644 --- a/arch/ppc/kernel/sleep.S +++ b/arch/ppc/kernel/sleep.S @@ -1,6 +1,6 @@ /* * This file contains sleep low-level functions for PowerBook G3. - * Copyright (C) 1999 Benjamin Herrenschmidt (bh40@calva.net) + * Copyright (C) 1999 Benjamin Herrenschmidt (benh@kernel.crashing.org) * and Paul Mackerras (paulus@cs.anu.edu.au). * * This program is free software; you can redistribute it and/or diff --git a/arch/ppc/kernel/smp.c b/arch/ppc/kernel/smp.c index 29166ba775df..7fba1479277c 100644 --- a/arch/ppc/kernel/smp.c +++ b/arch/ppc/kernel/smp.c @@ -40,6 +40,7 @@ #include #include #include +#include #include "open_pic.h" int smp_threads_ready; @@ -55,7 +56,7 @@ unsigned int prof_multiplier[NR_CPUS]; unsigned int prof_counter[NR_CPUS]; cycles_t cacheflush_time; static int max_cpus __initdata = NR_CPUS; - +unsigned long cpu_online_map; int smp_hw_index[NR_CPUS]; /* all cpu mappings are 1-1 -- Cort */ @@ -452,32 +453,48 @@ smp_core99_probe(void) static void smp_core99_kick_cpu(int nr) { - unsigned long save_int; + unsigned long save_vector, new_vector; unsigned long flags; +#if 1 /* New way... */ + volatile unsigned long *vector + = ((volatile unsigned long *)(KERNELBASE+0x100)); + if (nr < 1 || nr > 3) + return; +#else volatile unsigned long *vector = ((volatile unsigned long *)(KERNELBASE+0x500)); - if (nr != 1) return; +#endif if (ppc_md.progress) ppc_md.progress("smp_core99_kick_cpu", 0x346); local_irq_save(flags); local_irq_disable(); - /* Save EE vector */ - save_int = *vector; + /* Save reset vector */ + save_vector = *vector; - /* Setup fake EE vector that does + /* Setup fake reset vector that does * b __secondary_start_psurge - KERNELBASE - */ - *vector = 0x48000002 + - ((unsigned long)__secondary_start_psurge - KERNELBASE); + */ + switch(nr) { + case 1: + new_vector = (unsigned long)__secondary_start_psurge; + break; + case 2: + new_vector = (unsigned long)__secondary_start_psurge2; + break; + case 3: + new_vector = (unsigned long)__secondary_start_psurge3; + break; + } + *vector = 0x48000002 + new_vector - KERNELBASE; /* flush data cache and inval instruction cache */ flush_icache_range((unsigned long) vector, (unsigned long) vector + 4); /* Put some life in our friend */ - feature_core99_kick_cpu1(); + feature_core99_kick_cpu(nr); /* FIXME: We wait a bit for the CPU to take the exception, I should * instead wait for the entry code to set something for me. Well, @@ -487,11 +504,11 @@ smp_core99_kick_cpu(int nr) mdelay(1); /* Restore our exception vector */ - *vector = save_int; + *vector = save_vector; flush_icache_range((unsigned long) vector, (unsigned long) vector + 4); local_irq_restore(flags); - if (ppc_md.progress) ppc_md.progress("smp_core99_probe done", 0x347); + if (ppc_md.progress) ppc_md.progress("smp_core99_kick_cpu done", 0x347); } static void @@ -628,6 +645,43 @@ smp_prep_setup_cpu(int cpu_nr) do_openpic_setup_cpu(); } +#ifdef CONFIG_GEMINI +static int +smp_gemini_probe(void) +{ + int i, nr; + + nr = (readb(GEMINI_CPUSTAT) & GEMINI_CPU_COUNT_MASK) >> 2; + if (nr == 0) + nr = 4; + + if (nr > 1) { + openpic_request_IPIs(); + for (i = 1; i < nr; ++i) + smp_hw_index[i] = i; + } + + return nr; +} + +static void +smp_gemini_kick_cpu(int nr) +{ + openpic_init_processor( 1< 0) + gemini_init_l2(); +} +#endif /* CONFIG_GEMINI */ + + static struct smp_ops_t { void (*message_pass)(int target, int msg, unsigned long data, int wait); int (*probe)(void); @@ -685,6 +739,16 @@ static struct smp_ops_t prep_smp_ops = { smp_prep_setup_cpu, }; +#ifdef CONFIG_GEMINI +/* Gemini */ +static struct smp_ops_t gemini_smp_ops = { + smp_openpic_message_pass, + smp_gemini_probe, + smp_gemini_kick_cpu, + smp_gemini_setup_cpu, +}; +#endif /* CONFIG_GEMINI */ + /* * Common functions */ @@ -925,6 +989,11 @@ void __init smp_boot_cpus(void) case _MACH_prep: smp_ops = &prep_smp_ops; break; +#ifdef CONFIG_GEMINI + case _MACH_gemini: + smp_ops = &gemini_smp_ops; + break; +#endif /* CONFIG_GEMINI */ default: printk("SMP not supported on this machine.\n"); return; @@ -946,6 +1015,19 @@ void __init smp_boot_cpus(void) /* create a process for the processor */ /* we don't care about the values in regs since we'll never reschedule the forked task. */ + /* We DO care about one bit in the pt_regs we + pass to do_fork. That is the MSR_FP bit in + regs.msr. If that bit is on, then do_fork + (via copy_thread) will call giveup_fpu. + giveup_fpu will get a pointer to our (current's) + last register savearea via current->thread.regs + and using that pointer will turn off the MSR_FP, + MSR_FE0 and MSR_FE1 bits. At this point, this + pointer is pointing to some arbitrary point within + our stack. */ + + memset(®s, 0, sizeof(struct pt_regs)); + if (do_fork(CLONE_VM|CLONE_PID, 0, ®s, 0) < 0) panic("failed fork for CPU %d", i); p = init_task.prev_task; @@ -1114,8 +1196,18 @@ void __init smp_callin(void) init_idle(); + /* + * This cpu is now "online". Only set them online + * before they enter the loop below since write access + * to the below variable is _not_ guaranteed to be + * atomic. + * -- Cort + */ + cpu_online_map |= 1UL << smp_processor_id(); + while(!smp_commenced) barrier(); + /* see smp_commence for more info */ if (!smp_tb_synchronized && smp_num_cpus == 2) { smp_software_tb_sync(cpu); diff --git a/arch/ppc/kernel/syscalls.c b/arch/ppc/kernel/syscalls.c index f4ed98698d3f..2b93f59790b1 100644 --- a/arch/ppc/kernel/syscalls.c +++ b/arch/ppc/kernel/syscalls.c @@ -185,9 +185,10 @@ int sys_pipe(int *fildes) return error; } -unsigned long sys_mmap(unsigned long addr, size_t len, - unsigned long prot, unsigned long flags, - unsigned long fd, off_t offset) +static inline unsigned long +do_mmap2(unsigned long addr, size_t len, + unsigned long prot, unsigned long flags, + unsigned long fd, unsigned long pgoff) { struct file * file = NULL; int ret = -EBADF; @@ -199,7 +200,7 @@ unsigned long sys_mmap(unsigned long addr, size_t len, } down_write(¤t->mm->mmap_sem); - ret = do_mmap(file, addr, len, prot, flags, offset); + ret = do_mmap_pgoff(file, addr, len, prot, flags, pgoff); up_write(¤t->mm->mmap_sem); if (file) fput(file); @@ -207,6 +208,27 @@ out: return ret; } +unsigned long sys_mmap2(unsigned long addr, size_t len, + unsigned long prot, unsigned long flags, + unsigned long fd, unsigned long pgoff) +{ + return do_mmap2(addr, len, prot, flags, fd, pgoff); +} + +unsigned long sys_mmap(unsigned long addr, size_t len, + unsigned long prot, unsigned long flags, + unsigned long fd, off_t offset) +{ + int err = -EINVAL; + + if (offset & ~PAGE_MASK) + goto out; + + err = do_mmap2(addr, len, prot, flags, fd, offset >> PAGE_SHIFT); +out: + return err; +} + extern int sys_select(int, fd_set *, fd_set *, fd_set *, struct timeval *); /* diff --git a/arch/ppc/kernel/time.c b/arch/ppc/kernel/time.c index 76a5502140ca..d86d6feb1923 100644 --- a/arch/ppc/kernel/time.c +++ b/arch/ppc/kernel/time.c @@ -50,6 +50,7 @@ #include #include #include +#include #include #include #include @@ -91,6 +92,10 @@ extern unsigned long wall_jiffies; static long time_offset; +spinlock_t rtc_lock = SPIN_LOCK_UNLOCKED; + +EXPORT_SYMBOL(rtc_lock); + /* Timer interrupt helper function */ static inline int tb_delta(unsigned *jiffy_stamp) { int delta; @@ -144,14 +149,20 @@ int timer_interrupt(struct pt_regs * regs) int next_dec; unsigned long cpu = smp_processor_id(); unsigned jiffy_stamp = last_jiffy_stamp(cpu); + extern void do_IRQ(struct pt_regs *); + + if (atomic_read(&ppc_n_lost_interrupts) != 0) + do_IRQ(regs); hardirq_enter(cpu); - if (!user_mode(regs)) - ppc_do_profile(instruction_pointer(regs)); - do { + while ((next_dec = tb_ticks_per_jiffy - tb_delta(&jiffy_stamp)) < 0) { jiffy_stamp += tb_ticks_per_jiffy; - if (smp_processor_id()) continue; + if (!user_mode(regs)) + ppc_do_profile(instruction_pointer(regs)); + if (smp_processor_id()) + continue; + /* We are in an interrupt, no need to save/restore flags */ write_lock(&xtime_lock); tb_last_stamp = jiffy_stamp; @@ -184,7 +195,7 @@ int timer_interrupt(struct pt_regs * regs) last_rtc_update += 60; } write_unlock(&xtime_lock); - } while((next_dec = tb_ticks_per_jiffy - tb_delta(&jiffy_stamp)) < 0); + } if ( !disarm_decr[smp_processor_id()] ) set_dec(next_dec); last_jiffy_stamp(cpu) = jiffy_stamp; @@ -337,6 +348,8 @@ void __init time_init(void) tz.tz_dsttime = 0; do_sys_settimeofday(NULL, &tz); } + + do_get_fast_time = do_gettimeofday; } #define TICK_SIZE tick diff --git a/arch/ppc/lib/Makefile b/arch/ppc/lib/Makefile index b6f99174baa6..84eb6bd06d77 100644 --- a/arch/ppc/lib/Makefile +++ b/arch/ppc/lib/Makefile @@ -2,8 +2,7 @@ # Makefile for ppc-specific library files.. # -.S.o: - $(CC) $(AFLAGS) -c $< -o $*.o +USE_STANDARD_AS_RULE := true O_TARGET := lib.o diff --git a/arch/ppc/mm/init.c b/arch/ppc/mm/init.c index 5b9cac931ffa..b2f8eac2e171 100644 --- a/arch/ppc/mm/init.c +++ b/arch/ppc/mm/init.c @@ -46,7 +46,6 @@ #include #include #include -#include #include #ifdef CONFIG_8xx #include @@ -61,6 +60,7 @@ #include #include #include +#include #include "mem_pieces.h" @@ -93,7 +93,6 @@ extern char __chrp_begin, __chrp_end; extern char __pmac_begin, __pmac_end; extern char __apus_begin, __apus_end; extern char __openfirmware_begin, __openfirmware_end; -struct device_node *memory_node; unsigned long ioremap_base; unsigned long ioremap_bot; unsigned long avail_start; @@ -111,19 +110,6 @@ pgprot_t kmap_prot; void MMU_init(void); void *early_get_page(void); -unsigned long prep_find_end_of_memory(void); -unsigned long pmac_find_end_of_memory(void); -unsigned long apus_find_end_of_memory(void); -extern unsigned long find_end_of_memory(void); -#ifdef CONFIG_8xx -unsigned long m8xx_find_end_of_memory(void); -#endif /* CONFIG_8xx */ -#ifdef CONFIG_4xx -unsigned long oak_find_end_of_memory(void); -#endif -#ifdef CONFIG_8260 -unsigned long m8260_find_end_of_memory(void); -#endif /* CONFIG_8260 */ static void mapin_ram(void); int map_page(unsigned long va, unsigned long pa, int flags); void set_phys_avail(unsigned long total_ram); @@ -436,11 +422,9 @@ __ioremap(unsigned long addr, unsigned long size, unsigned long flags) * Should check if it is a candidate for a BAT mapping */ - spin_lock(&init_mm.page_table_lock); err = 0; for (i = 0; i < size && err == 0; i += PAGE_SIZE) err = map_page(v+i, p+i, flags); - spin_unlock(&init_mm.page_table_lock); if (err) { if (mem_init_done) vfree((void *)v); @@ -487,17 +471,21 @@ map_page(unsigned long va, unsigned long pa, int flags) { pmd_t *pd; pte_t *pg; + int err = -ENOMEM; + spin_lock(&init_mm.page_table_lock); /* Use upper 10 bits of VA to index the first level map */ pd = pmd_offset(pgd_offset_k(va), va); /* Use middle 10 bits of VA to index the second-level map */ pg = pte_alloc(&init_mm, pd, va); - if (pg == 0) - return -ENOMEM; - set_pte(pg, mk_pte_phys(pa & PAGE_MASK, __pgprot(flags))); - if (mem_init_done) - flush_hash_page(0, va); - return 0; + if (pg != 0) { + err = 0; + set_pte(pg, mk_pte_phys(pa & PAGE_MASK, __pgprot(flags))); + if (mem_init_done) + flush_hash_page(0, va); + } + spin_unlock(&init_mm.page_table_lock); + return err; } #ifndef CONFIG_8xx @@ -668,33 +656,6 @@ void flush_page_to_ram(struct page *page) } #if !defined(CONFIG_4xx) && !defined(CONFIG_8xx) -static void get_mem_prop(char *, struct mem_pieces *); - -#if defined(CONFIG_ALL_PPC) -/* - * Read in a property describing some pieces of memory. - */ - -static void __init get_mem_prop(char *name, struct mem_pieces *mp) -{ - struct reg_property *rp; - int s; - - rp = (struct reg_property *) get_property(memory_node, name, &s); - if (rp == NULL) { - printk(KERN_ERR "error: couldn't get %s property on /memory\n", - name); - abort(); - } - mp->n_regions = s / sizeof(mp->regions[0]); - memcpy(mp->regions, rp, s); - - /* Make sure the pieces are sorted. */ - mem_pieces_sort(mp); - mem_pieces_coalesce(mp); -} -#endif /* CONFIG_ALL_PPC */ - /* * Set up one of the I/D BAT (block address translation) register pairs. * The parameters are not checked; in particular size must be a power @@ -877,14 +838,13 @@ void free_initmem(void) #ifdef CONFIG_BLK_DEV_INITRD void free_initrd_mem(unsigned long start, unsigned long end) { - printk ("Freeing initrd memory: %ldk freed\n", (end - start) >> 10); - for (; start < end; start += PAGE_SIZE) { ClearPageReserved(virt_to_page(start)); set_page_count(virt_to_page(start), 1); free_page(start); totalram_pages++; } + printk ("Freeing initrd memory: %ldk freed\n", (end - start) >> 10); } #endif @@ -904,27 +864,28 @@ MMU_init(void) /* * The Zone Protection Register (ZPR) defines how protection will * be applied to every page which is a member of a given zone. At - * present, we utilize only two of the 4xx's zones. The first, zone - * 0, is set at '00b and only allows access in supervisor-mode based - * on the EX and WR bits. No user-mode access is allowed. The second, - * zone 1, is set at '10b and in supervisor-mode allows access - * without regard to the EX and WR bits. In user-mode, access is - * allowed based on the EX and WR bits. + * present, we utilize only two of the 4xx's zones. + * The zone index bits (of ZSEL) in the PTE are used for software + * indicators, except the LSB. For user access, zone 15 is used, + * for kernel access, zone 14 is used. We set all but zone 15 + * to zero, allowing only kernel access as indicated in the PTE. + * For zone 15, we set a 10 binary (I guess a 01 would work too) + * to allow user access as indicated in the PTE. This also allows + * kernel access as indicated in the PTE. */ - mtspr(SPRN_ZPR, 0x2aaaaaaa); + mtspr(SPRN_ZPR, 0x00000002); - /* Hardwire any TLB entries necessary here. */ - - PPC4xx_tlb_pin(KERNELBASE, 0, TLB_PAGESZ(PAGESZ_16M), 1); + flush_instruction_cache(); /* * Find the top of physical memory and map all of it in starting * at KERNELBASE. */ - total_memory = total_lowmem = oak_find_end_of_memory(); - end_of_DRAM = __va(total_memory); + total_memory = total_lowmem = ppc_md.find_end_of_memory(); + end_of_DRAM = __va(total_lowmem); + set_phys_avail(total_lowmem); mapin_ram(); /* @@ -943,70 +904,13 @@ MMU_init(void) mtspr(SPRN_ICCR, 0x80000000); /* 128 MB of instr. space at 0x0. */ } -#elif defined(CONFIG_8xx) +#else /* !CONFIG_4xx */ void __init MMU_init(void) { if ( ppc_md.progress ) ppc_md.progress("MMU:enter", 0x111); - total_memory = total_lowmem = m8xx_find_end_of_memory(); -#ifdef CONFIG_HIGHMEM - if (total_lowmem > MAX_LOW_MEM) { - total_lowmem = MAX_LOW_MEM; - mem_pieces_remove(&phys_avail, total_lowmem, - total_memory - total_lowmem, 0); - } -#endif /* CONFIG_HIGHMEM */ - end_of_DRAM = __va(total_lowmem); - set_phys_avail(total_lowmem); - - /* Map in all of RAM starting at KERNELBASE */ - mapin_ram(); + total_memory = ppc_md.find_end_of_memory(); - /* Now map in some of the I/O space that is generically needed - * or shared with multiple devices. - * All of this fits into the same 4Mbyte region, so it only - * requires one page table page. - */ - ioremap(IMAP_ADDR, IMAP_SIZE); -#ifdef CONFIG_MBX - ioremap(NVRAM_ADDR, NVRAM_SIZE); - ioremap(MBX_CSR_ADDR, MBX_CSR_SIZE); - ioremap(PCI_CSR_ADDR, PCI_CSR_SIZE); - - /* Map some of the PCI/ISA I/O space to get the IDE interface. - */ - ioremap(PCI_ISA_IO_ADDR, 0x4000); - ioremap(PCI_IDE_ADDR, 0x4000); -#endif -#ifdef CONFIG_RPXLITE - ioremap(RPX_CSR_ADDR, RPX_CSR_SIZE); - ioremap(HIOX_CSR_ADDR, HIOX_CSR_SIZE); -#endif -#ifdef CONFIG_RPXCLASSIC - ioremap(PCI_CSR_ADDR, PCI_CSR_SIZE); - ioremap(RPX_CSR_ADDR, RPX_CSR_SIZE); -#endif - if ( ppc_md.progress ) ppc_md.progress("MMU:exit", 0x211); -} - -#else /* not 4xx or 8xx */ -void __init MMU_init(void) -{ - if ( ppc_md.progress ) ppc_md.progress("MMU:enter", 0x111); - - if (have_of) - total_memory = pmac_find_end_of_memory(); -#ifdef CONFIG_APUS - else if (_machine == _MACH_apus ) - total_memory = apus_find_end_of_memory(); -#endif -#if defined(CONFIG_8260) - else - total_memory = m8260_find_end_of_memory(); -#else - else /* prep */ - total_memory = prep_find_end_of_memory(); -#endif if (__max_memory && total_memory > __max_memory) total_memory = __max_memory; total_lowmem = total_memory; @@ -1019,6 +923,7 @@ void __init MMU_init(void) end_of_DRAM = __va(total_lowmem); set_phys_avail(total_lowmem); +#if !defined(CONFIG_8xx) if ( ppc_md.progress ) ppc_md.progress("MMU:hash init", 0x300); hash_init(); #ifndef CONFIG_PPC64BRIDGE @@ -1026,16 +931,49 @@ void __init MMU_init(void) #endif ioremap_base = 0xf8000000; +#endif /* CONFIG_8xx */ if ( ppc_md.progress ) ppc_md.progress("MMU:mapin", 0x301); /* Map in all of RAM starting at KERNELBASE */ mapin_ram(); -#ifdef CONFIG_POWER4 +#if defined(CONFIG_POWER4) ioremap_base = ioremap_bot = 0xfffff000; isa_io_base = (unsigned long) ioremap(0xffd00000, 0x200000) + 0x100000; -#else /* CONFIG_POWER4 */ +#elif defined(CONFIG_8xx) + /* Now map in some of the I/O space that is generically needed + * or shared with multiple devices. + * All of this fits into the same 4Mbyte region, so it only + * requires one page table page. + */ + ioremap(IMAP_ADDR, IMAP_SIZE); +#ifdef CONFIG_MBX + ioremap(NVRAM_ADDR, NVRAM_SIZE); + ioremap(MBX_CSR_ADDR, MBX_CSR_SIZE); + ioremap(PCI_CSR_ADDR, PCI_CSR_SIZE); + + /* Map some of the PCI/ISA I/O space to get the IDE interface. + */ + ioremap(PCI_ISA_IO_ADDR, 0x4000); + ioremap(PCI_IDE_ADDR, 0x4000); +#endif +#if defined(CONFIG_RPXLITE) || defined(CONFIG_RPXCLASSIC) + ioremap(RPX_CSR_ADDR, RPX_CSR_SIZE); +#if !defined(CONFIG_PCI) + ioremap(_IO_BASE,_IO_BASE_SIZE); +#endif +#endif +#ifdef CONFIG_HTDMSOUND + ioremap(HIOX_CSR_ADDR, HIOX_CSR_SIZE); +#endif +#ifdef CONFIG_FADS + ioremap(BCSR_ADDR, BCSR_SIZE); +#endif +#ifdef CONFIG_PCI + ioremap(PCI_CSR_ADDR, PCI_CSR_SIZE); +#endif +#else /* !CONFIG_POWER4 && !CONFIG_8xx */ /* * Setup the bat mappings we're going to load that cover * the io areas. RAM was mapped by mapin_ram(). @@ -1069,6 +1007,10 @@ void __init MMU_init(void) /* Map chip and ZorroII memory */ setbat(1, zTwoBase, 0x00000000, 0x01000000, IO_PAGE); break; + case _MACH_gemini: + setbat(0, 0xf0000000, 0xf0000000, 0x10000000, IO_PAGE); + setbat(1, 0x80000000, 0x80000000, 0x10000000, IO_PAGE); + break; case _MACH_8260: /* Map the IMMR, plus anything else we can cover * in that upper space according to the memory controller @@ -1081,7 +1023,7 @@ void __init MMU_init(void) break; } ioremap_bot = ioremap_base; -#endif /* CONFIG_POWER4 */ +#endif /* CONFIG_POWER4 || CONFIG_8xx */ if ( ppc_md.progress ) ppc_md.progress("MMU:exit", 0x211); #ifdef CONFIG_BOOTX_TEXT @@ -1257,155 +1199,6 @@ void __init mem_init(void) } #if !defined(CONFIG_4xx) && !defined(CONFIG_8xx) -#if defined(CONFIG_ALL_PPC) -/* - * On systems with Open Firmware, collect information about - * physical RAM and which pieces are already in use. - * At this point, we have (at least) the first 8MB mapped with a BAT. - * Our text, data, bss use something over 1MB, starting at 0. - * Open Firmware may be using 1MB at the 4MB point. - */ -unsigned long __init pmac_find_end_of_memory(void) -{ - unsigned long a, total; - struct mem_pieces phys_mem; - - memory_node = find_devices("memory"); - if (memory_node == NULL) { - printk(KERN_ERR "can't find memory node\n"); - abort(); - } - - /* - * Find out where physical memory is, and check that it - * starts at 0 and is contiguous. It seems that RAM is - * always physically contiguous on Power Macintoshes. - * - * Supporting discontiguous physical memory isn't hard, - * it just makes the virtual <-> physical mapping functions - * more complicated (or else you end up wasting space - * in mem_map). - */ - get_mem_prop("reg", &phys_mem); - if (phys_mem.n_regions == 0) - panic("No RAM??"); - a = phys_mem.regions[0].address; - if (a != 0) - panic("RAM doesn't start at physical address 0"); - total = phys_mem.regions[0].size; - - if (phys_mem.n_regions > 1) { - printk("RAM starting at 0x%x is not contiguous\n", - phys_mem.regions[1].address); - printk("Using RAM from 0 to 0x%lx\n", total-1); - } - - return total; -} -#endif /* CONFIG_ALL_PPC */ - -#if defined(CONFIG_ALL_PPC) -/* - * This finds the amount of physical ram and does necessary - * setup for prep. This is pretty architecture specific so - * this will likely stay separate from the pmac. - * -- Cort - */ -unsigned long __init prep_find_end_of_memory(void) -{ - unsigned long total; -#ifdef CONFIG_PREP_RESIDUAL - total = res->TotalMemory; -#else - total = 0; -#endif - - if (total == 0 ) - { - /* - * I need a way to probe the amount of memory if the residual - * data doesn't contain it. -- Cort - */ - printk("Ramsize from residual data was 0 -- Probing for value\n"); - total = 0x02000000; - printk("Ramsize default to be %ldM\n", total>>20); - } - - return (total); -} -#endif /* defined(CONFIG_ALL_PPC) */ - -#ifdef CONFIG_8260 -/* - * Same hack as 8xx. - */ -unsigned long __init m8260_find_end_of_memory(void) -{ - bd_t *binfo; - extern unsigned char __res[]; - - binfo = (bd_t *)__res; - - return binfo->bi_memsize; -} -#endif /* CONFIG_8260 */ - -#ifdef CONFIG_APUS -#define HARDWARE_MAPPED_SIZE (512*1024) -unsigned long __init apus_find_end_of_memory(void) -{ - int shadow = 0; - unsigned long total; - - /* The memory size reported by ADOS excludes the 512KB - reserved for PPC exception registers and possibly 512KB - containing a shadow of the ADOS ROM. */ - { - unsigned long size = memory[0].size; - - /* If 2MB aligned, size was probably user - specified. We can't tell anything about shadowing - in this case so skip shadow assignment. */ - if (0 != (size & 0x1fffff)){ - /* Align to 512KB to ensure correct handling - of both memfile and system specified - sizes. */ - size = ((size+0x0007ffff) & 0xfff80000); - /* If memory is 1MB aligned, assume - shadowing. */ - shadow = !(size & 0x80000); - } - - /* Add the chunk that ADOS does not see. by aligning - the size to the nearest 2MB limit upwards. */ - memory[0].size = ((size+0x001fffff) & 0xffe00000); - } - - total = memory[0].size; - - /* Remove the memory chunks that are controlled by special - Phase5 hardware. */ - - /* Remove the upper 512KB if it contains a shadow of - the ADOS ROM. FIXME: It might be possible to - disable this shadow HW. Check the booter - (ppc_boot.c) */ - if (shadow) - total -= HARDWARE_MAPPED_SIZE; - - /* Remove the upper 512KB where the PPC exception - vectors are mapped. */ - total -= HARDWARE_MAPPED_SIZE; - - /* Linux/APUS only handles one block of memory -- the one on - the PowerUP board. Other system memory is horrible slow in - comparison. The user can use other memory for swapping - using the z2ram device. */ - ram_phys_base = memory[0].addr; - return total; -} -#endif /* CONFIG_APUS */ - /* * Initialize the hash table and patch the instructions in head.S. */ @@ -1514,44 +1307,8 @@ static void __init hash_init(void) } if ( ppc_md.progress ) ppc_md.progress("hash:done", 0x205); } -#elif defined(CONFIG_8xx) -/* - * This is a big hack right now, but it may turn into something real - * someday. - * - * For the 8xx boards (at this time anyway), there is nothing to initialize - * associated the PROM. Rather than include all of the prom.c - * functions in the image just to get prom_init, all we really need right - * now is the initialization of the physical memory region. - */ -unsigned long __init m8xx_find_end_of_memory(void) -{ - bd_t *binfo; - extern unsigned char __res[]; - - binfo = (bd_t *)__res; - - return binfo->bi_memsize; -} #endif /* !CONFIG_4xx && !CONFIG_8xx */ -#ifdef CONFIG_OAK -/* - * Return the virtual address representing the top of physical RAM - * on the Oak board. - */ -unsigned long __init -oak_find_end_of_memory(void) -{ - extern unsigned char __res[]; - - unsigned long *ret; - bd_t *bip = (bd_t *)__res; - - return bip->bi_memsize; -} -#endif - /* * Set phys_avail to the amount of physical memory, * less the kernel text/data/bss. diff --git a/arch/ppc/xmon/start.c b/arch/ppc/xmon/start.c index 611b1e069fe0..b74b8184d7fd 100644 --- a/arch/ppc/xmon/start.c +++ b/arch/ppc/xmon/start.c @@ -61,27 +61,37 @@ xmon_map_scc(void) struct device_node *np; unsigned long addr; #ifdef CONFIG_BOOTX_TEXT - extern boot_infos_t *disp_bi; - - /* see if there is a keyboard in the device tree - with a parent of type "adb" */ - for (np = find_devices("keyboard"); np; np = np->next) - if (np->parent && np->parent->type - && strcmp(np->parent->type, "adb") == 0) - break; + if (!machine_is_compatible("iMac")) { + extern boot_infos_t *disp_bi; + + /* see if there is a keyboard in the device tree + with a parent of type "adb" */ + for (np = find_devices("keyboard"); np; np = np->next) + if (np->parent && np->parent->type + && strcmp(np->parent->type, "adb") == 0) + break; - /* needs to be hacked if xmon_printk is to be used - from within find_via_pmu() */ + /* needs to be hacked if xmon_printk is to be used + from within find_via_pmu() */ #ifdef CONFIG_ADB_PMU - if (np != NULL && disp_bi && find_via_pmu()) - use_screen = 1; + if (np != NULL && disp_bi && find_via_pmu()) + use_screen = 1; #endif #ifdef CONFIG_ADB_CUDA - if (np != NULL && disp_bi && find_via_cuda()) - use_screen = 1; + if (np != NULL && disp_bi && find_via_cuda()) + use_screen = 1; #endif + } + prom_drawstring("xmon uses "); if (use_screen) - prom_drawstring("xmon uses screen and keyboard\n"); + prom_drawstring("screen and keyboard\n"); + else { + if (via_modem) + prom_drawstring("modem on "); + prom_drawstring(xmon_use_sccb? "printer": "modem"); + prom_drawstring(" port\n"); + } + #endif /* CONFIG_BOOTX_TEXT */ #ifdef CHRP_ESCC @@ -101,6 +111,15 @@ xmon_map_scc(void) sccc = base + (addr & ~PAGE_MASK); sccd = sccc + 0x10; } + else if ( _machine & _MACH_gemini ) + { + /* should already be mapped by the kernel boot */ + sccc = (volatile unsigned char *) 0xffeffb0d; + sccd = (volatile unsigned char *) 0xffeffb08; + TXRDY = 0x20; + RXRDY = 1; + console = 1; + } else { /* should already be mapped by the kernel boot */ diff --git a/arch/ppc/xmon/start_8xx.c b/arch/ppc/xmon/start_8xx.c index e698d9575ac7..12ddc24c05f8 100644 --- a/arch/ppc/xmon/start_8xx.c +++ b/arch/ppc/xmon/start_8xx.c @@ -15,7 +15,7 @@ #include #include #include -#include "commproc.h" +#include "../8xx_io/commproc.h" extern void xmon_printf(const char *fmt, ...); extern int xmon_8xx_write(char *str, int nb); diff --git a/arch/ppc/xmon/xmon.c b/arch/ppc/xmon/xmon.c index 65082d458607..c7a7f1e18581 100644 --- a/arch/ppc/xmon/xmon.c +++ b/arch/ppc/xmon/xmon.c @@ -208,10 +208,11 @@ void xmon_irq(int irq, void *d, struct pt_regs *regs) { unsigned long flags; - save_flags(flags);cli(); + __save_flags(flags); + __cli(); printf("Keyboard interrupt\n"); xmon(regs); - restore_flags(flags); + __restore_flags(flags); } int @@ -657,7 +658,7 @@ backtrace(struct pt_regs *excp) unsigned stack[2]; struct pt_regs regs; extern char ret_from_intercept, ret_from_syscall_1, ret_from_syscall_2; - extern char lost_irq_ret, do_bottom_half_ret, do_signal_ret; + extern char do_bottom_half_ret, do_signal_ret; extern char ret_from_except; printf("backtrace:\n"); @@ -676,7 +677,6 @@ backtrace(struct pt_regs *excp) || stack[1] == (unsigned) &ret_from_except || stack[1] == (unsigned) &ret_from_syscall_1 || stack[1] == (unsigned) &ret_from_syscall_2 - || stack[1] == (unsigned) &lost_irq_ret || stack[1] == (unsigned) &do_bottom_half_ret || stack[1] == (unsigned) &do_signal_ret) { if (mread(sp+16, ®s, sizeof(regs)) != sizeof(regs)) diff --git a/arch/sparc/defconfig b/arch/sparc/defconfig index 79e281b96c17..ed61982c4808 100644 --- a/arch/sparc/defconfig +++ b/arch/sparc/defconfig @@ -148,7 +148,6 @@ CONFIG_INET=y # CONFIG_INET_ECN is not set # CONFIG_SYN_COOKIES is not set CONFIG_IPV6=m -# CONFIG_IPV6_EUI64 is not set # CONFIG_KHTTPD is not set # CONFIG_ATM is not set diff --git a/arch/sparc64/config.in b/arch/sparc64/config.in index f2948d2ed1fd..dd6cd84435b9 100644 --- a/arch/sparc64/config.in +++ b/arch/sparc64/config.in @@ -1,4 +1,4 @@ -# $Id: config.in,v 1.141 2001/04/19 01:52:04 davem Exp $ +# $Id: config.in,v 1.142 2001/05/05 07:46:04 davem Exp $ # For a description of the syntax of this configuration file, # see the Configure script. # @@ -338,6 +338,15 @@ source drivers/input/Config.in source fs/Config.in +mainmenu_option next_comment +comment 'Sound' + +tristate 'Sound card support' CONFIG_SOUND +if [ "$CONFIG_SOUND" != "n" ]; then + source drivers/sound/Config.in +fi +endmenu + source drivers/usb/Config.in mainmenu_option next_comment diff --git a/arch/sparc64/defconfig b/arch/sparc64/defconfig index 14555c39210c..e82fe472e025 100644 --- a/arch/sparc64/defconfig +++ b/arch/sparc64/defconfig @@ -178,7 +178,6 @@ CONFIG_INET=y CONFIG_INET_ECN=y # CONFIG_SYN_COOKIES is not set CONFIG_IPV6=m -# CONFIG_IPV6_EUI64 is not set # CONFIG_KHTTPD is not set # CONFIG_ATM is not set @@ -312,6 +311,7 @@ CONFIG_SCSI_QLOGICPTI=m CONFIG_SCSI_AIC7XXX=m CONFIG_AIC7XXX_CMDS_PER_DEVICE=253 CONFIG_AIC7XXX_RESET_DELAY_MS=5000 +# CONFIG_AIC7XXX_BUILD_FIRMWARE is not set CONFIG_SCSI_AIC7XXX_OLD=m CONFIG_AIC7XXX_OLD_TCQ_ON_BY_DEFAULT=y CONFIG_AIC7XXX_OLD_CMDS_PER_DEVICE=8 @@ -546,6 +546,28 @@ CONFIG_NLS_DEFAULT="iso8859-1" # CONFIG_NLS_KOI8_U is not set # CONFIG_NLS_UTF8 is not set +# +# Sound +# +CONFIG_SOUND=m +# CONFIG_SOUND_CMPCI is not set +# CONFIG_SOUND_EMU10K1 is not set +# CONFIG_SOUND_FUSION is not set +# CONFIG_SOUND_CS4281 is not set +# CONFIG_SOUND_ES1370 is not set +CONFIG_SOUND_ES1371=m +# CONFIG_SOUND_ESSSOLO1 is not set +# CONFIG_SOUND_MAESTRO is not set +# CONFIG_SOUND_MAESTRO3 is not set +# CONFIG_SOUND_ICH is not set +# CONFIG_SOUND_SONICVIBES is not set +CONFIG_SOUND_TRIDENT=m +# CONFIG_SOUND_MSNDCLAS is not set +# CONFIG_SOUND_MSNDPIN is not set +# CONFIG_SOUND_VIA82CXXX is not set +# CONFIG_SOUND_OSS is not set +# CONFIG_SOUND_TVMIXER is not set + # # USB support # @@ -561,8 +583,7 @@ CONFIG_USB_DEVICEFS=y # # USB Controllers # -# CONFIG_USB_UHCI is not set -# CONFIG_USB_UHCI_ALT is not set +CONFIG_USB_UHCI=y CONFIG_USB_OHCI=y # diff --git a/arch/sparc64/kernel/Makefile b/arch/sparc64/kernel/Makefile index 64ac62338d70..f80dcd0c9ed7 100644 --- a/arch/sparc64/kernel/Makefile +++ b/arch/sparc64/kernel/Makefile @@ -1,4 +1,4 @@ -# $Id: Makefile,v 1.66 2001/04/03 12:29:38 davem Exp $ +# $Id: Makefile,v 1.67 2001/05/11 04:31:55 davem Exp $ # Makefile for the linux kernel. # # Note! Dependencies are done automagically by 'make dep', which also @@ -26,7 +26,7 @@ obj-y := process.o setup.o cpu.o idprom.o \ unaligned.o central.o pci.o starfire.o semaphore.o \ power.o sbus.o iommu_common.o sparc64_ksyms.o chmc.o -obj-$(CONFIG_PCI) += ebus.o pci_common.o pci_iommu.o \ +obj-$(CONFIG_PCI) += ebus.o isa.o pci_common.o pci_iommu.o \ pci_psycho.o pci_sabre.o pci_schizo.o obj-$(CONFIG_SMP) += smp.o trampoline.o obj-$(CONFIG_SPARC32_COMPAT) += sys32.o sys_sparc32.o signal32.o ioctl32.o diff --git a/arch/sparc64/kernel/ioctl32.c b/arch/sparc64/kernel/ioctl32.c index faf36cfbf36e..65eda5174979 100644 --- a/arch/sparc64/kernel/ioctl32.c +++ b/arch/sparc64/kernel/ioctl32.c @@ -1,4 +1,4 @@ -/* $Id: ioctl32.c,v 1.111 2001/03/27 07:28:43 davem Exp $ +/* $Id: ioctl32.c,v 1.115 2001/05/12 06:41:58 davem Exp $ * ioctl32.c: Conversion between 32bit and 64bit native ioctls. * * Copyright (C) 1997-2000 Jakub Jelinek (jakub@redhat.com) @@ -49,6 +49,7 @@ #include #include #include +#include #if defined(CONFIG_BLK_DEV_LVM) || defined(CONFIG_BLK_DEV_LVM_MODULE) /* Ugh. This header really is not clean */ #define min min @@ -514,10 +515,19 @@ static inline int dev_ifconf(unsigned int fd, unsigned int cmd, unsigned long ar } } if (!err) { - if (i <= ifc32.ifc_len) + if (ifc32.ifcbuf == 0) { + /* Translate from 64-bit structure multiple to + * a 32-bit one. + */ + i = ifc.ifc_len; + i = ((i / sizeof(struct ifreq)) * sizeof(struct ifreq32)); ifc32.ifc_len = i; - else - ifc32.ifc_len = i - sizeof (struct ifreq32); + } else { + if (i <= ifc32.ifc_len) + ifc32.ifc_len = i; + else + ifc32.ifc_len = i - sizeof (struct ifreq32); + } if (copy_to_user((struct ifconf32 *)arg, &ifc32, sizeof(struct ifconf32))) err = -EFAULT; } @@ -3369,11 +3379,6 @@ COMPATIBLE_IOCTL(SIOCGIFBR) COMPATIBLE_IOCTL(SIOCSARP) COMPATIBLE_IOCTL(SIOCGARP) COMPATIBLE_IOCTL(SIOCDARP) -#if 0 /* XXX No longer exist in new routing code. XXX */ -COMPATIBLE_IOCTL(OLD_SIOCSARP) -COMPATIBLE_IOCTL(OLD_SIOCGARP) -COMPATIBLE_IOCTL(OLD_SIOCDARP) -#endif COMPATIBLE_IOCTL(SIOCSRARP) COMPATIBLE_IOCTL(SIOCGRARP) COMPATIBLE_IOCTL(SIOCDRARP) @@ -3714,6 +3719,13 @@ COMPATIBLE_IOCTL(WDIOC_KEEPALIVE) COMPATIBLE_IOCTL(WIOCSTART) COMPATIBLE_IOCTL(WIOCSTOP) COMPATIBLE_IOCTL(WIOCGSTAT) +/* Misc. */ +COMPATIBLE_IOCTL(0x41545900) /* ATYIO_CLKR */ +COMPATIBLE_IOCTL(0x41545901) /* ATYIO_CLKW */ +COMPATIBLE_IOCTL(PCIIOC_CONTROLLER) +COMPATIBLE_IOCTL(PCIIOC_MMAP_IS_IO) +COMPATIBLE_IOCTL(PCIIOC_MMAP_IS_MEM) +COMPATIBLE_IOCTL(PCIIOC_WRITE_COMBINE) /* And these ioctls need translation */ HANDLE_IOCTL(SIOCGIFNAME, dev_ifname32) HANDLE_IOCTL(SIOCGIFCONF, dev_ifconf) @@ -3991,8 +4003,9 @@ asmlinkage int sys32_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg) } else { static int count = 0; if (++count <= 20) - printk("sys32_ioctl: Unknown cmd fd(%d) " + printk("sys32_ioctl(%s:%d): Unknown cmd fd(%d) " "cmd(%08x) arg(%08x)\n", + current->comm, current->pid, (int)fd, (unsigned int)cmd, (unsigned int)arg); error = -EINVAL; } diff --git a/arch/sparc64/kernel/isa.c b/arch/sparc64/kernel/isa.c new file mode 100644 index 000000000000..99a47e17b83c --- /dev/null +++ b/arch/sparc64/kernel/isa.c @@ -0,0 +1,269 @@ +#include +#include +#include +#include +#include +#include + +struct isa_bridge *isa_chain; + +static void __init fatal_err(const char *reason) +{ + prom_printf("ISA: fatal error, %s.\n", reason); +} + +static void __init report_dev(struct isa_device *isa_dev, int child) +{ + if (child) + printk(" (%s)", isa_dev->prom_name); + else + printk(" [%s", isa_dev->prom_name); +} + +static void __init isa_dev_get_resource(struct isa_device *isa_dev) +{ + struct linux_prom_registers regs[PROMREG_MAX]; + unsigned long base, len; + int prop_len; + + prop_len = prom_getproperty(isa_dev->prom_node, "reg", + (char *) regs, sizeof(regs)); + + if (prop_len <= 0) + return; + + /* Only the first one is interesting. */ + len = regs[0].reg_size; + base = (((unsigned long)regs[0].which_io << 32) | + (unsigned long)regs[0].phys_addr); + base += isa_dev->bus->parent->io_space.start; + + isa_dev->resource.start = base; + isa_dev->resource.end = (base + len - 1UL); + isa_dev->resource.flags = IORESOURCE_IO; + isa_dev->resource.name = isa_dev->prom_name; + + request_resource(&isa_dev->bus->parent->io_space, + &isa_dev->resource); +} + +/* I can't believe they didn't put a real INO in the isa device + * interrupts property. The whole point of the OBP properties + * is to shield the kernel from IRQ routing details. + * + * The P1275 standard for ISA devices seems to also have been + * totally ignored. + */ +static struct { + int obp_irq; + int pci_ino; +} grover_irq_table[] = { + { 1, 0x00 }, /* dma, unknown ino at this point */ + { 2, 0x27 }, /* floppy */ + { 3, 0x22 }, /* parallel */ + { 4, 0x2b }, /* serial */ + { 5, 0x25 }, /* acpi power management */ + + { 0, 0x00 } /* end of table */ +}; + +static void __init isa_dev_get_irq(struct isa_device *isa_dev) +{ + int irq_prop; + + irq_prop = prom_getintdefault(isa_dev->prom_node, + "interrupts", -1); + if (irq_prop <= 0) { + isa_dev->irq = 0; + } else { + int i; + + for (i = 0; grover_irq_table[i].obp_irq != 0; i++) { + if (grover_irq_table[i].obp_irq == irq_prop) { + struct pci_controller_info *pcic; + struct pci_pbm_info *pbm; + int ino = grover_irq_table[i].pci_ino; + + if (ino == 0) { + isa_dev->irq = 0; + } else { + pbm = isa_dev->bus->parent; + pcic = pbm->parent; + isa_dev->irq = pcic->irq_build(pbm, NULL, ino); + } + } + } + } +} + +static void __init isa_fill_children(struct isa_device *parent_isa_dev) +{ + int node = prom_getchild(parent_isa_dev->prom_node); + + if (node == 0) + return; + + printk(" ->"); + while (node != 0) { + struct isa_device *isa_dev; + int prop_len; + + isa_dev = kmalloc(sizeof(*isa_dev), GFP_KERNEL); + if (!isa_dev) { + fatal_err("cannot allocate child isa_dev"); + prom_halt(); + } + + memset(isa_dev, 0, sizeof(*isa_dev)); + + /* Link it in to parent. */ + isa_dev->next = parent_isa_dev->child; + parent_isa_dev->child = isa_dev; + + isa_dev->bus = parent_isa_dev->bus; + isa_dev->prom_node = node; + prop_len = prom_getproperty(node, "name", + (char *) isa_dev->prom_name, + sizeof(isa_dev->prom_name)); + if (prop_len <= 0) { + fatal_err("cannot get child isa_dev OBP node name"); + prom_halt(); + } + + prop_len = prom_getproperty(node, "compatible", + (char *) isa_dev->compatible, + sizeof(isa_dev->compatible)); + + /* Not having this is OK. */ + if (prop_len <= 0) + isa_dev->compatible[0] = '\0'; + + isa_dev_get_resource(isa_dev); + isa_dev_get_irq(isa_dev); + + report_dev(isa_dev, 1); + + node = prom_getsibling(node); + } +} + +static void __init isa_fill_devices(struct isa_bridge *isa_br) +{ + int node = prom_getchild(isa_br->prom_node); + + while (node != 0) { + struct isa_device *isa_dev; + int prop_len; + + isa_dev = kmalloc(sizeof(*isa_dev), GFP_KERNEL); + if (!isa_dev) { + fatal_err("cannot allocate isa_dev"); + prom_halt(); + } + + memset(isa_dev, 0, sizeof(*isa_dev)); + + /* Link it in. */ + isa_dev->next = NULL; + if (isa_br->devices == NULL) { + isa_br->devices = isa_dev; + } else { + struct isa_device *tmp = isa_br->devices; + + while (tmp->next) + tmp = tmp->next; + + tmp->next = isa_dev; + } + + isa_dev->bus = isa_br; + isa_dev->prom_node = node; + prop_len = prom_getproperty(node, "name", + (char *) isa_dev->prom_name, + sizeof(isa_dev->prom_name)); + if (prop_len <= 0) { + fatal_err("cannot get isa_dev OBP node name"); + prom_halt(); + } + + prop_len = prom_getproperty(node, "compatible", + (char *) isa_dev->compatible, + sizeof(isa_dev->compatible)); + + /* Not having this is OK. */ + if (prop_len <= 0) + isa_dev->compatible[0] = '\0'; + + isa_dev_get_resource(isa_dev); + isa_dev_get_irq(isa_dev); + + report_dev(isa_dev, 0); + + isa_fill_children(isa_dev); + + printk("]"); + + node = prom_getsibling(node); + } +} + +void __init isa_init(void) +{ + struct pci_dev *pdev; + unsigned short vendor, device; + int index = 0; + + vendor = PCI_VENDOR_ID_AL; + device = PCI_DEVICE_ID_AL_M1533; + + pdev = NULL; + while ((pdev = pci_find_device(vendor, device, pdev)) != NULL) { + struct pcidev_cookie *pdev_cookie; + struct pci_pbm_info *pbm; + struct isa_bridge *isa_br; + int prop_len; + + pdev_cookie = pdev->sysdata; + if (!pdev_cookie) { + printk("ISA: Warning, ISA bridge ignored due to " + "lack of OBP data.\n"); + continue; + } + pbm = pdev_cookie->pbm; + + isa_br = kmalloc(sizeof(*isa_br), GFP_KERNEL); + if (!isa_br) { + fatal_err("cannot allocate isa_bridge"); + prom_halt(); + } + + memset(isa_br, 0, sizeof(*isa_br)); + + /* Link it in. */ + isa_br->next = isa_chain; + isa_chain = isa_br; + + isa_br->parent = pbm; + isa_br->self = pdev; + isa_br->index = index++; + isa_br->prom_node = pdev_cookie->prom_node; + strncpy(isa_br->prom_name, pdev_cookie->prom_name, + sizeof(isa_br->prom_name)); + + prop_len = prom_getproperty(isa_br->prom_node, + "ranges", + (char *) isa_br->isa_ranges, + sizeof(isa_br->isa_ranges)); + if (prop_len <= 0) + isa_br->num_isa_ranges = 0; + else + isa_br->num_isa_ranges = + (prop_len / sizeof(struct linux_prom_isa_ranges)); + + printk("isa%d:", isa_br->index); + + isa_fill_devices(isa_br); + + printk("\n"); + } +} diff --git a/arch/sparc64/kernel/pci.c b/arch/sparc64/kernel/pci.c index f342bacb55b0..66408deb008c 100644 --- a/arch/sparc64/kernel/pci.c +++ b/arch/sparc64/kernel/pci.c @@ -1,4 +1,4 @@ -/* $Id: pci.c,v 1.25 2001/05/02 00:27:27 davem Exp $ +/* $Id: pci.c,v 1.29 2001/05/15 08:54:30 davem Exp $ * pci.c: UltraSparc PCI controller support. * * Copyright (C) 1997, 1998, 1999 David S. Miller (davem@redhat.com) @@ -19,6 +19,7 @@ #include #include #include +#include unsigned long pci_memspace_mask = 0xffffffffUL; @@ -187,6 +188,7 @@ void __init pcibios_init(void) if (pci_device_reorder) pci_reorder_devs(); + isa_init(); ebus_init(); } @@ -234,4 +236,147 @@ char * __init pcibios_setup(char *str) return str; } +/* Platform support for /proc/bus/pci/X/Y mmap()s. */ + +/* Adjust vm_pgoff of VMA such that it is the physical page offset corresponding + * to the 32-bit pci bus offset for DEV requested by the user. + * + * Basically, the user finds the base address for his device which he wishes + * to mmap. They read the 32-bit value from the config space base register, + * add whatever PAGE_SIZE multiple offset they wish, and feed this into the + * offset parameter of mmap on /proc/bus/pci/XXX for that device. + * + * Returns negative error code on failure, zero on success. + */ +static __inline__ int __pci_mmap_make_offset(struct pci_dev *dev, struct vm_area_struct *vma, + enum pci_mmap_state mmap_state) +{ + unsigned long user_offset = vma->vm_pgoff << PAGE_SHIFT; + unsigned long user32 = user_offset & 0xffffffffUL; + unsigned long largest_base, this_base, addr32; + int i; + + /* Figure out which base address this is for. */ + largest_base = 0UL; + for (i = 0; i <= PCI_ROM_RESOURCE; i++) { + struct resource *rp = &dev->resource[i]; + + /* Active? */ + if (!rp->flags) + continue; + + /* Same type? */ + if (i == PCI_ROM_RESOURCE) { + if (mmap_state != pci_mmap_mem) + continue; + } else { + if ((mmap_state == pci_mmap_io && + (rp->flags & IORESOURCE_IO) == 0) || + (mmap_state == pci_mmap_mem && + (rp->flags & IORESOURCE_MEM) == 0)) + continue; + } + + this_base = rp->start; + + addr32 = (this_base & PAGE_MASK) & 0xffffffffUL; + + if (mmap_state == pci_mmap_io) + addr32 &= 0xffffff; + + if (addr32 <= user32 && this_base > largest_base) + largest_base = this_base; + } + + if (largest_base == 0UL) + return -EINVAL; + + /* Now construct the final physical address. */ + if (mmap_state == pci_mmap_io) + vma->vm_pgoff = (((largest_base & ~0xffffffUL) | user32) >> PAGE_SHIFT); + else + vma->vm_pgoff = (((largest_base & ~0xffffffffUL) | user32) >> PAGE_SHIFT); + + return 0; +} + +/* Set vm_flags of VMA, as appropriate for this architecture, for a pci device + * mapping. + */ +static __inline__ void __pci_mmap_set_flags(struct pci_dev *dev, struct vm_area_struct *vma, + enum pci_mmap_state mmap_state) +{ + vma->vm_flags |= (VM_SHM | VM_LOCKED); +} + +/* Set vm_page_prot of VMA, as appropriate for this architecture, for a pci + * device mapping. + */ +static __inline__ void __pci_mmap_set_pgprot(struct pci_dev *dev, struct vm_area_struct *vma, + enum pci_mmap_state mmap_state) +{ + /* Our io_remap_page_range takes care of this, do nothing. */ +} + +extern int io_remap_page_range(unsigned long from, unsigned long offset, + unsigned long size, pgprot_t prot, int space); + +/* Perform the actual remap of the pages for a PCI device mapping, as appropriate + * for this architecture. The region in the process to map is described by vm_start + * and vm_end members of VMA, the base physical address is found in vm_pgoff. + * The pci device structure is provided so that architectures may make mapping + * decisions on a per-device or per-bus basis. + * + * Returns a negative error code on failure, zero on success. + */ +int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma, + enum pci_mmap_state mmap_state, + int write_combine) +{ + int ret; + + ret = __pci_mmap_make_offset(dev, vma, mmap_state); + if (ret < 0) + return ret; + + __pci_mmap_set_flags(dev, vma, mmap_state); + __pci_mmap_set_pgprot(dev, vma, mmap_state); + + ret = io_remap_page_range(vma->vm_start, + (vma->vm_pgoff << PAGE_SHIFT | + (write_combine ? 0x1UL : 0x0UL)), + vma->vm_end - vma->vm_start, vma->vm_page_prot, 0); + if (ret) + return ret; + + vma->vm_flags |= VM_IO; + return 0; +} + +/* Return the index of the PCI controller for device PDEV. */ + +int pci_controller_num(struct pci_dev *pdev) +{ + struct pcidev_cookie *cookie = pdev->sysdata; + int ret; + + if (cookie != NULL) { + struct pci_pbm_info *pbm = cookie->pbm; + if (pbm == NULL || pbm->parent == NULL) { + ret = -ENXIO; + } else { + struct pci_controller_info *p = pbm->parent; + + ret = p->index; + if (p->pbms_same_domain == 0) + ret = ((ret << 1) + + ((pbm == &pbm->parent->pbm_B) ? 1 : 0)); + } + } else { + ret = -ENXIO; + } + + return ret; +} + #endif /* !(CONFIG_PCI) */ diff --git a/arch/sparc64/kernel/pci_common.c b/arch/sparc64/kernel/pci_common.c index bcf950ee0e09..3fdc02a02a08 100644 --- a/arch/sparc64/kernel/pci_common.c +++ b/arch/sparc64/kernel/pci_common.c @@ -1,4 +1,4 @@ -/* $Id: pci_common.c,v 1.14 2001/02/28 03:28:55 davem Exp $ +/* $Id: pci_common.c,v 1.17 2001/05/15 12:32:52 davem Exp $ * pci_common.c: PCI controller common support. * * Copyright (C) 1999 David S. Miller (davem@redhat.com) @@ -10,6 +10,29 @@ #include +/* Fix self device of BUS and hook it into BUS->self. + * The pci_scan_bus does not do this for the host bridge. + */ +void __init pci_fixup_host_bridge_self(struct pci_bus *pbus) +{ + struct list_head *walk = &pbus->devices; + + walk = walk->next; + while (walk != &pbus->devices) { + struct pci_dev *pdev = pci_dev_b(walk); + + if (pdev->class >> 8 == PCI_CLASS_BRIDGE_HOST) { + pbus->self = pdev; + return; + } + + walk = walk->next; + } + + prom_printf("PCI: Critical error, cannot find host bridge PDEV.\n"); + prom_halt(); +} + /* Find the OBP PROM device tree node for a PCI device. * Return zero if not found. */ @@ -29,7 +52,10 @@ static int __init find_device_prom_node(struct pci_pbm_info *pbm, */ if ((pdev->bus->number == pbm->pci_bus->number) && (pdev->devfn == 0) && (pdev->vendor == PCI_VENDOR_ID_SUN) && - (pdev->device == PCI_DEVICE_ID_SUN_PBM)) { + (pdev->device == PCI_DEVICE_ID_SUN_PBM || + pdev->device == PCI_DEVICE_ID_SUN_SCHIZO || + pdev->device == PCI_DEVICE_ID_SUN_SABRE || + pdev->device == PCI_DEVICE_ID_SUN_HUMMINGBIRD)) { *nregs = 0; return bus_prom_node; } diff --git a/arch/sparc64/kernel/pci_impl.h b/arch/sparc64/kernel/pci_impl.h index 415af23fd89f..fc54cbc2b085 100644 --- a/arch/sparc64/kernel/pci_impl.h +++ b/arch/sparc64/kernel/pci_impl.h @@ -1,4 +1,4 @@ -/* $Id: pci_impl.h,v 1.7 2001/03/28 10:56:34 davem Exp $ +/* $Id: pci_impl.h,v 1.8 2001/05/15 08:54:30 davem Exp $ * pci_impl.h: Helper definitions for PCI controller support. * * Copyright (C) 1999 David S. Miller (davem@redhat.com) @@ -19,6 +19,7 @@ extern unsigned char pci_highest_busnum; extern int pci_num_controllers; /* PCI bus scanning and fixup support. */ +extern void pci_fixup_host_bridge_self(struct pci_bus *pbus); extern void pci_fill_in_pbm_cookies(struct pci_bus *pbus, struct pci_pbm_info *pbm, int prom_node); diff --git a/arch/sparc64/kernel/pci_psycho.c b/arch/sparc64/kernel/pci_psycho.c index b1d9d28c9c1d..f99817b4bd7a 100644 --- a/arch/sparc64/kernel/pci_psycho.c +++ b/arch/sparc64/kernel/pci_psycho.c @@ -1,4 +1,4 @@ -/* $Id: pci_psycho.c,v 1.23 2001/05/02 00:27:27 davem Exp $ +/* $Id: pci_psycho.c,v 1.24 2001/05/15 08:54:30 davem Exp $ * pci_psycho.c: PSYCHO/U2P specific PCI controller support. * * Copyright (C) 1997, 1998, 1999 David S. Miller (davem@caipfs.rutgers.edu) @@ -1235,9 +1235,23 @@ static void __init pbm_config_busmastering(struct pci_pbm_info *pbm) static void __init pbm_scan_bus(struct pci_controller_info *p, struct pci_pbm_info *pbm) { + struct pcidev_cookie *cookie = kmalloc(sizeof(*cookie), GFP_KERNEL); + + if (!cookie) { + prom_printf("PSYCHO: Critical allocation failure.\n"); + prom_halt(); + } + + /* All we care about is the PBM. */ + memset(cookie, 0, sizeof(*cookie)); + cookie->pbm = pbm; + pbm->pci_bus = pci_scan_bus(pbm->pci_first_busno, p->pci_ops, pbm); + pci_fixup_host_bridge_self(pbm->pci_bus); + pbm->pci_bus->self->sysdata = cookie; + pci_fill_in_pbm_cookies(pbm->pci_bus, pbm, pbm->prom_node); pci_record_assignments(pbm, pbm->pci_bus); pci_assign_unassigned(pbm, pbm->pci_bus); @@ -1564,6 +1578,7 @@ void __init psycho_init(int node, char *model_name) p->portid = upa_portid; p->index = pci_num_controllers++; + p->pbms_same_domain = 0; p->scan_bus = psycho_scan_bus; p->irq_build = psycho_irq_build; p->base_address_update = psycho_base_address_update; diff --git a/arch/sparc64/kernel/pci_sabre.c b/arch/sparc64/kernel/pci_sabre.c index d247d801b1b8..da8117cc660b 100644 --- a/arch/sparc64/kernel/pci_sabre.c +++ b/arch/sparc64/kernel/pci_sabre.c @@ -1,4 +1,4 @@ -/* $Id: pci_sabre.c,v 1.29 2001/05/02 00:32:56 davem Exp $ +/* $Id: pci_sabre.c,v 1.32 2001/05/15 11:10:01 davem Exp $ * pci_sabre.c: Sabre specific PCI controller support. * * Copyright (C) 1997, 1998, 1999 David S. Miller (davem@caipfs.rutgers.edu) @@ -1112,11 +1112,28 @@ static void __init apb_init(struct pci_controller_info *p, struct pci_bus *sabre } } +static struct pcidev_cookie *alloc_bridge_cookie(struct pci_pbm_info *pbm) +{ + struct pcidev_cookie *cookie = kmalloc(sizeof(*cookie), GFP_KERNEL); + + if (!cookie) { + prom_printf("SABRE: Critical allocation failure.\n"); + prom_halt(); + } + + /* All we care about is the PBM. */ + memset(cookie, 0, sizeof(*cookie)); + cookie->pbm = pbm; + + return cookie; +} + static void __init sabre_scan_bus(struct pci_controller_info *p) { static int once = 0; struct pci_bus *sabre_bus; struct pci_pbm_info *pbm; + struct pcidev_cookie *cookie; struct list_head *walk; int sabres_scanned; @@ -1142,10 +1159,15 @@ static void __init sabre_scan_bus(struct pci_controller_info *p) } once++; + cookie = alloc_bridge_cookie(&p->pbm_A); + /* The pci_bus2pbm table has already been setup in sabre_init. */ sabre_bus = pci_scan_bus(p->pci_first_busno, p->pci_ops, &p->pbm_A); + pci_fixup_host_bridge_self(sabre_bus); + sabre_bus->self->sysdata = cookie; + apb_init(p, sabre_bus); sabres_scanned = 0; @@ -1161,6 +1183,9 @@ static void __init sabre_scan_bus(struct pci_controller_info *p) } else continue; + cookie = alloc_bridge_cookie(pbm); + pbus->self->sysdata = cookie; + sabres_scanned++; pbus->sysdata = pbm; @@ -1444,6 +1469,11 @@ static void __init sabre_pbm_init(struct pci_controller_info *p, int sabre_node, memset(&pbm->pbm_intmask, 0, sizeof(pbm->pbm_intmask)); } + + sprintf(pbm->name, "SABRE%d PBM%c", p->index, + (pbm == &p->pbm_A ? 'A' : 'B')); + pbm->io_space.name = pbm->mem_space.name = pbm->name; + /* Hack up top-level resources. */ pbm->io_space.start = p->controller_regs + SABRE_IOSPACE; pbm->io_space.end = pbm->io_space.start + (1UL << 16) - 1UL; @@ -1512,6 +1542,7 @@ void __init sabre_init(int pnode, char *model_name) p->portid = upa_portid; p->index = pci_num_controllers++; + p->pbms_same_domain = 1; p->scan_bus = sabre_scan_bus; p->irq_build = sabre_irq_build; p->base_address_update = sabre_base_address_update; diff --git a/arch/sparc64/kernel/pci_schizo.c b/arch/sparc64/kernel/pci_schizo.c index c0fe3b6f02a2..3f9c4a1eba15 100644 --- a/arch/sparc64/kernel/pci_schizo.c +++ b/arch/sparc64/kernel/pci_schizo.c @@ -1,4 +1,4 @@ -/* $Id: pci_schizo.c,v 1.15 2001/05/02 00:27:27 davem Exp $ +/* $Id: pci_schizo.c,v 1.16 2001/05/15 08:54:30 davem Exp $ * pci_schizo.c: SCHIZO specific PCI controller support. * * Copyright (C) 2001 David S. Miller (davem@redhat.com) @@ -1328,9 +1328,23 @@ static void __init pbm_config_busmastering(struct pci_pbm_info *pbm) static void __init pbm_scan_bus(struct pci_controller_info *p, struct pci_pbm_info *pbm) { + struct pcidev_cookie *cookie = kmalloc(sizeof(*cookie), GFP_KERNEL); + + if (!cookie) { + prom_printf("SCHIZO: Critical allocation failure.\n"); + prom_halt(); + } + + /* All we care about is the PBM. */ + memset(cookie, 0, sizeof(*cookie)); + cookie->pbm = pbm; + pbm->pci_bus = pci_scan_bus(pbm->pci_first_busno, p->pci_ops, pbm); + pci_fixup_host_bridge_self(pbm->pci_bus); + pbm->pci_bus->self->sysdata = cookie; + pci_fill_in_pbm_cookies(pbm->pci_bus, pbm, pbm->prom_node); pci_record_assignments(pbm, pbm->pci_bus); pci_assign_unassigned(pbm, pbm->pci_bus); @@ -1761,6 +1775,7 @@ void __init schizo_init(int node, char *model_name) p->portid = portid; p->index = pci_num_controllers++; + p->pbms_same_domain = 0; p->scan_bus = schizo_scan_bus; p->irq_build = schizo_irq_build; p->base_address_update = schizo_base_address_update; diff --git a/arch/sparc64/kernel/sparc64_ksyms.c b/arch/sparc64/kernel/sparc64_ksyms.c index bfe896f00fe5..341f43e6ace3 100644 --- a/arch/sparc64/kernel/sparc64_ksyms.c +++ b/arch/sparc64/kernel/sparc64_ksyms.c @@ -1,4 +1,4 @@ -/* $Id: sparc64_ksyms.c,v 1.105 2001/04/14 01:12:02 davem Exp $ +/* $Id: sparc64_ksyms.c,v 1.106 2001/05/11 07:46:28 davem Exp $ * arch/sparc64/kernel/sparc64_ksyms.c: Sparc64 specific ksyms support. * * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu) @@ -47,6 +47,7 @@ #endif #ifdef CONFIG_PCI #include +#include #endif #include @@ -199,6 +200,7 @@ EXPORT_SYMBOL(sbus_dma_sync_sg); #endif #ifdef CONFIG_PCI EXPORT_SYMBOL(ebus_chain); +EXPORT_SYMBOL(isa_chain); EXPORT_SYMBOL(pci_memspace_mask); EXPORT_SYMBOL(empty_zero_page); EXPORT_SYMBOL(outsb); diff --git a/arch/sparc64/mm/init.c b/arch/sparc64/mm/init.c index 818521fb20fb..91d0870ca5a6 100644 --- a/arch/sparc64/mm/init.c +++ b/arch/sparc64/mm/init.c @@ -1,4 +1,4 @@ -/* $Id: init.c,v 1.175 2001/04/24 01:09:12 davem Exp $ +/* $Id: init.c,v 1.176 2001/05/16 15:07:11 davem Exp $ * arch/sparc64/mm/init.c * * Copyright (C) 1996-1999 David S. Miller (davem@caip.rutgers.edu) @@ -1139,8 +1139,16 @@ void __init paging_init(void) unsigned long second_alias_page = 0; unsigned long pt, flags, end_pfn, pages_avail; unsigned long shift = alias_base - ((unsigned long)&empty_zero_page); + unsigned long real_end; set_bit(0, mmu_context_bmap); + + real_end = (unsigned long)&_end; +#ifdef CONFIG_BLK_DEV_INITRD + if (sparc_ramdisk_image) + real_end = (PAGE_ALIGN(real_end) + PAGE_ALIGN(sparc_ramdisk_size)); +#endif + /* We assume physical memory starts at some 4mb multiple, * if this were not true we wouldn't boot up to this point * anyways. @@ -1161,7 +1169,7 @@ void __init paging_init(void) : "r" (TLB_TAG_ACCESS), "r" (alias_base), "r" (pt), "i" (ASI_DMMU), "i" (ASI_DTLB_DATA_ACCESS), "r" (61 << 3) : "memory"); - if (((unsigned long)&_end) >= KERNBASE + 0x340000) { + if (real_end >= KERNBASE + 0x340000) { second_alias_page = alias_base + 0x400000; __asm__ __volatile__( " stxa %1, [%0] %3\n" @@ -1189,7 +1197,7 @@ void __init paging_init(void) : "r" (TLB_TAG_ACCESS), "r" (alias_base), "r" (pt), "i" (ASI_DMMU), "i" (ASI_DTLB_DATA_ACCESS), "r" ((0<<16) | (13<<3)) : "memory"); - if (((unsigned long)&_end) >= KERNBASE + 0x340000) { + if (real_end >= KERNBASE + 0x340000) { second_alias_page = alias_base + 0x400000; __asm__ __volatile__( " stxa %1, [%0] %3\n" diff --git a/drivers/Makefile b/drivers/Makefile index b8ee715c80eb..43896790e5da 100644 --- a/drivers/Makefile +++ b/drivers/Makefile @@ -9,7 +9,7 @@ mod-subdirs := dio mtd sbus video macintosh usb input telephony sgi i2o ide \ scsi md ieee1394 pnp isdn atm fc4 net/hamradio i2c acpi -subdir-y := block char net parport sound misc media cdrom +subdir-y := parport char block net sound misc media cdrom subdir-m := $(subdir-y) diff --git a/drivers/atm/eni.c b/drivers/atm/eni.c index 174873f72da2..16661c3ef692 100644 --- a/drivers/atm/eni.c +++ b/drivers/atm/eni.c @@ -1796,6 +1796,7 @@ static int __devinit eni_start(struct atm_dev *dev) return -EAGAIN; } /* @@@ should release IRQ on error */ + pci_set_master(eni_dev->pci_dev); if ((error = pci_write_config_word(eni_dev->pci_dev,PCI_COMMAND, PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER | (eni_dev->asic ? PCI_COMMAND_PARITY | PCI_COMMAND_SERR : 0)))) { diff --git a/drivers/block/genhd.c b/drivers/block/genhd.c index 2cc319e200bd..9e7dc6ca7449 100644 --- a/drivers/block/genhd.c +++ b/drivers/block/genhd.c @@ -17,8 +17,6 @@ #include #include -extern int parport_init(void); -extern int chr_dev_init(void); extern int blk_dev_init(void); #ifdef CONFIG_BLK_DEV_DAC960 extern void DAC960_Initialize(void); @@ -33,10 +31,6 @@ extern void ieee1394_init(void); void __init device_init(void) { -#ifdef CONFIG_PARPORT - parport_init(); -#endif - chr_dev_init(); blk_dev_init(); sti(); #ifdef CONFIG_I2O diff --git a/drivers/char/Makefile b/drivers/char/Makefile index 1e73a22ee908..6aa94907cc43 100644 --- a/drivers/char/Makefile +++ b/drivers/char/Makefile @@ -16,7 +16,7 @@ FONTMAPFILE = cp437.uni O_TARGET := char.o -obj-y += tty_io.o n_tty.o tty_ioctl.o mem.o raw.o pty.o misc.o random.o +obj-y += mem.o tty_io.o n_tty.o tty_ioctl.o raw.o pty.o misc.o random.o # All of the (potential) objects that export symbols. # This list comes from 'grep -l EXPORT_SYMBOL *.[hc]'. diff --git a/drivers/char/agp/agpgart_fe.c b/drivers/char/agp/agpgart_fe.c index df42dabc5db4..6703254ada6c 100644 --- a/drivers/char/agp/agpgart_fe.c +++ b/drivers/char/agp/agpgart_fe.c @@ -852,6 +852,9 @@ static int agpioc_reserve_wrap(agp_file_private * priv, unsigned long arg) if (copy_from_user(&reserve, (void *) arg, sizeof(agp_region))) { return -EFAULT; } + if ((unsigned) reserve.seg_count >= ~0U/sizeof(agp_segment)) + return -EFAULT; + client = agp_find_client_by_pid(reserve.pid); if (reserve.seg_count == 0) { diff --git a/drivers/char/mem.c b/drivers/char/mem.c index a0bfe6c1231e..158ce8c72494 100644 --- a/drivers/char/mem.c +++ b/drivers/char/mem.c @@ -653,3 +653,5 @@ int __init chr_dev_init(void) #endif return 0; } + +__initcall(chr_dev_init); diff --git a/drivers/char/moxa.c b/drivers/char/moxa.c index d002c2e44b74..115313e54a5f 100644 --- a/drivers/char/moxa.c +++ b/drivers/char/moxa.c @@ -705,14 +705,24 @@ static int moxa_write(struct tty_struct *tty, int from_user, return (0); port = ch->port; save_flags(flags); - cli(); if (from_user) { - copy_from_user(moxaXmitBuff, buf, count); - temp = moxaXmitBuff; - } else - temp = (unsigned char *) buf; - len = MoxaPortWriteData(port, temp, count); - restore_flags(flags); + down(&moxaBuffSem); + if (copy_from_user(moxaXmitBuff, buf, count)) { + len = -EFAULT; + } else { + cli(); + len = MoxaPortWriteData(port, moxaXmitBuff, count); + restore_flags(flags); + } + up(&moxaBuffSem); + if (len < 0) + return len; + } else { + cli(); + len = MoxaPortWriteData(port, (unsigned char *) buf, count); + restore_flags(flags); + } + /********************************************* if ( !(ch->statusflags & LOWWAIT) && ((len != count) || (MoxaPortTxFree(port) <= 100)) ) diff --git a/drivers/char/mxser.c b/drivers/char/mxser.c index 51b3acc8dbe0..7c10b0ce1758 100644 --- a/drivers/char/mxser.c +++ b/drivers/char/mxser.c @@ -887,29 +887,56 @@ static int mxser_write(struct tty_struct *tty, int from_user, if (from_user) down(&mxvar_tmp_buf_sem); save_flags(flags); - while (1) { - cli(); - c = MIN(count, MIN(SERIAL_XMIT_SIZE - info->xmit_cnt - 1, - SERIAL_XMIT_SIZE - info->xmit_head)); - if (c <= 0) - break; + if (from_user) { + down(&mxvar_tmp_buf_sem); + while (1) { + c = MIN(count, MIN(SERIAL_XMIT_SIZE - info->xmit_cnt - 1, + SERIAL_XMIT_SIZE - info->xmit_head)); + if (c <= 0) + break; - if (from_user) { - copy_from_user(mxvar_tmp_buf, buf, c); + c -= copy_from_user(mxvar_tmp_buf, buf, c); + if (!c) { + if (!total) + total = -EFAULT; + break; + } + + cli(); c = MIN(c, MIN(SERIAL_XMIT_SIZE - info->xmit_cnt - 1, - SERIAL_XMIT_SIZE - info->xmit_head)); + SERIAL_XMIT_SIZE - info->xmit_head)); memcpy(info->xmit_buf + info->xmit_head, mxvar_tmp_buf, c); - } else + info->xmit_head = (info->xmit_head + c) & (SERIAL_XMIT_SIZE - 1); + info->xmit_cnt += c; + restore_flags(flags); + + buf += c; + count -= c; + total += c; + } + up(&mxvar_tmp_buf_sem); + } else { + while (1) { + cli(); + c = MIN(count, MIN(SERIAL_XMIT_SIZE - info->xmit_cnt - 1, + SERIAL_XMIT_SIZE - info->xmit_head)); + if (c <= 0) { + restore_flags(flags); + break; + } + memcpy(info->xmit_buf + info->xmit_head, buf, c); - info->xmit_head = (info->xmit_head + c) & (SERIAL_XMIT_SIZE - 1); - info->xmit_cnt += c; - restore_flags(flags); - buf += c; - count -= c; - total += c; + info->xmit_head = (info->xmit_head + c) & (SERIAL_XMIT_SIZE - 1); + info->xmit_cnt += c; + restore_flags(flags); + + buf += c; + count -= c; + total += c; + } } - if (from_user) - up(&mxvar_tmp_buf_sem); + + cli(); if (info->xmit_cnt && !tty->stopped && !tty->hw_stopped && !(info->IER & UART_IER_THRI)) { info->IER |= UART_IER_THRI; diff --git a/drivers/char/riscom8.c b/drivers/char/riscom8.c index ed93c297227f..f2b15ce66cc4 100644 --- a/drivers/char/riscom8.c +++ b/drivers/char/riscom8.c @@ -1217,33 +1217,58 @@ static int rc_write(struct tty_struct * tty, int from_user, if (!tty || !port->xmit_buf || !tmp_buf) return 0; - if (from_user) + save_flags(flags); + if (from_user) { down(&tmp_buf_sem); + while (1) { + cli(); + c = MIN(count, MIN(SERIAL_XMIT_SIZE - port->xmit_cnt - 1, + SERIAL_XMIT_SIZE - port->xmit_head)); + if (c <= 0) + break; - save_flags(flags); - while (1) { - cli(); - c = MIN(count, MIN(SERIAL_XMIT_SIZE - port->xmit_cnt - 1, - SERIAL_XMIT_SIZE - port->xmit_head)); - if (c <= 0) - break; + c -= copy_from_user(tmp_buf, buf, c); + if (!c) { + if (!total) + total = -EFAULT; + break; + } - if (from_user) { - copy_from_user(tmp_buf, buf, c); + cli(); c = MIN(c, MIN(SERIAL_XMIT_SIZE - port->xmit_cnt - 1, SERIAL_XMIT_SIZE - port->xmit_head)); memcpy(port->xmit_buf + port->xmit_head, tmp_buf, c); - } else + port->xmit_head = (port->xmit_head + c) & (SERIAL_XMIT_SIZE-1); + port->xmit_cnt += c; + restore_flags(flags); + + buf += c; + count -= c; + total += c; + } + up(&tmp_buf_sem); + } else { + while (1) { + cli(); + c = MIN(count, MIN(SERIAL_XMIT_SIZE - port->xmit_cnt - 1, + SERIAL_XMIT_SIZE - port->xmit_head)); + if (c <= 0) { + restore_flags(flags); + break; + } + memcpy(port->xmit_buf + port->xmit_head, buf, c); - port->xmit_head = (port->xmit_head + c) & (SERIAL_XMIT_SIZE-1); - port->xmit_cnt += c; - restore_flags(flags); - buf += c; - count -= c; - total += c; + port->xmit_head = (port->xmit_head + c) & (SERIAL_XMIT_SIZE-1); + port->xmit_cnt += c; + restore_flags(flags); + + buf += c; + count -= c; + total += c; + } } - if (from_user) - up(&tmp_buf_sem); + + cli(); if (port->xmit_cnt && !tty->stopped && !tty->hw_stopped && !(port->IER & IER_TXRDY)) { port->IER |= IER_TXRDY; @@ -1251,6 +1276,7 @@ static int rc_write(struct tty_struct * tty, int from_user, rc_out(bp, CD180_IER, port->IER); } restore_flags(flags); + return total; } diff --git a/drivers/char/serial167.c b/drivers/char/serial167.c index a7ccb1d75ef9..55b98cde3bff 100644 --- a/drivers/char/serial167.c +++ b/drivers/char/serial167.c @@ -1247,36 +1247,54 @@ cy_write(struct tty_struct * tty, int from_user, return 0; } - while (1) { - save_flags(flags); cli(); - c = MIN(count, MIN(SERIAL_XMIT_SIZE - info->xmit_cnt - 1, - SERIAL_XMIT_SIZE - info->xmit_head)); - if (c <= 0){ - restore_flags(flags); - break; - } - - if (from_user) { + if (from_user) { down(&tmp_buf_sem); - if (copy_from_user(tmp_buf, buf, c)) { - up(&tmp_buf_sem); - restore_flags(flags); - return 0; + while (1) { + c = MIN(count, MIN(SERIAL_XMIT_SIZE - info->xmit_cnt - 1, + SERIAL_XMIT_SIZE - info->xmit_head)); + if (c <= 0) + break; + + c -= copy_from_user(tmp_buf, buf, c); + if (!c) { + if (!total) + total = -EFAULT; + break; + } + + cli(); + c = MIN(c, MIN(SERIAL_XMIT_SIZE - info->xmit_cnt - 1, + SERIAL_XMIT_SIZE - info->xmit_head)); + memcpy(info->xmit_buf + info->xmit_head, tmp_buf, c); + info->xmit_head = (info->xmit_head + c) & (SERIAL_XMIT_SIZE-1); + info->xmit_cnt += c; + restore_flags(flags); + + buf += c; + count -= c; + total += c; } - c = MIN(c, MIN(SERIAL_XMIT_SIZE - info->xmit_cnt - 1, - SERIAL_XMIT_SIZE - info->xmit_head)); - memcpy(info->xmit_buf + info->xmit_head, tmp_buf, c); up(&tmp_buf_sem); - } else - memcpy(info->xmit_buf + info->xmit_head, buf, c); - info->xmit_head = (info->xmit_head + c) & (SERIAL_XMIT_SIZE-1); - info->xmit_cnt += c; - restore_flags(flags); - buf += c; - count -= c; - total += c; - } + } else { + while (1) { + cli(); + c = MIN(count, MIN(SERIAL_XMIT_SIZE - info->xmit_cnt - 1, + SERIAL_XMIT_SIZE - info->xmit_head)); + if (c <= 0) { + restore_flags(flags); + break; + } + memcpy(info->xmit_buf + info->xmit_head, buf, c); + info->xmit_head = (info->xmit_head + c) & (SERIAL_XMIT_SIZE-1); + info->xmit_cnt += c; + restore_flags(flags); + + buf += c; + count -= c; + total += c; + } + } if (info->xmit_cnt && !tty->stopped diff --git a/drivers/char/specialix.c b/drivers/char/specialix.c index a08de5cad365..3f2e5fe15fe9 100644 --- a/drivers/char/specialix.c +++ b/drivers/char/specialix.c @@ -1611,33 +1611,56 @@ static int sx_write(struct tty_struct * tty, int from_user, if (!tty || !port->xmit_buf || !tmp_buf) return 0; - if (from_user) + save_flags(flags); + if (from_user) { down(&tmp_buf_sem); + while (1) { + c = MIN(count, MIN(SERIAL_XMIT_SIZE - port->xmit_cnt - 1, + SERIAL_XMIT_SIZE - port->xmit_head)); + if (c <= 0) + break; - save_flags(flags); - while (1) { - cli(); - c = MIN(count, MIN(SERIAL_XMIT_SIZE - port->xmit_cnt - 1, - SERIAL_XMIT_SIZE - port->xmit_head)); - if (c <= 0) - break; + c -= copy_from_user(tmp_buf, buf, c); + if (!c) { + if (!total) + total = -EFAULT; + break; + } - if (from_user) { - copy_from_user(tmp_buf, buf, c); + cli(); c = MIN(c, MIN(SERIAL_XMIT_SIZE - port->xmit_cnt - 1, - SERIAL_XMIT_SIZE - port->xmit_head)); + SERIAL_XMIT_SIZE - port->xmit_head)); memcpy(port->xmit_buf + port->xmit_head, tmp_buf, c); - } else + port->xmit_head = (port->xmit_head + c) & (SERIAL_XMIT_SIZE-1); + port->xmit_cnt += c; + restore_flags(flags); + + buf += c; + count -= c; + total += c; + } + up(&tmp_buf_sem); + } else { + while (1) { + cli(); + c = MIN(count, MIN(SERIAL_XMIT_SIZE - port->xmit_cnt - 1, + SERIAL_XMIT_SIZE - port->xmit_head)); + if (c <= 0) { + restore_flags(flags); + break; + } memcpy(port->xmit_buf + port->xmit_head, buf, c); - port->xmit_head = (port->xmit_head + c) & (SERIAL_XMIT_SIZE-1); - port->xmit_cnt += c; - restore_flags(flags); - buf += c; - count -= c; - total += c; + port->xmit_head = (port->xmit_head + c) & (SERIAL_XMIT_SIZE-1); + port->xmit_cnt += c; + restore_flags(flags); + + buf += c; + count -= c; + total += c; + } } - if (from_user) - up(&tmp_buf_sem); + + cli(); if (port->xmit_cnt && !tty->stopped && !tty->hw_stopped && !(port->IER & IER_TXRDY)) { port->IER |= IER_TXRDY; diff --git a/drivers/md/md.c b/drivers/md/md.c index 64804406d414..9bb3227b11e4 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -2464,7 +2464,7 @@ static int set_disk_faulty (mddev_t *mddev, kdev_t dev) int ret; fsync_dev(mddev_to_kdev(mddev)); - ret = md_error(mddev_to_kdev(mddev), dev); + ret = md_error(mddev, dev); return ret; } @@ -2938,13 +2938,11 @@ void md_recover_arrays (void) } -int md_error (kdev_t dev, kdev_t rdev) +int md_error (mddev_t *mddev, kdev_t rdev) { - mddev_t *mddev; mdk_rdev_t * rrdev; int rc; - mddev = kdev_to_mddev(dev); /* printk("md_error dev:(%d:%d), rdev:(%d:%d), (caller: %p,%p,%p,%p).\n",MAJOR(dev),MINOR(dev),MAJOR(rdev),MINOR(rdev), __builtin_return_address(0),__builtin_return_address(1),__builtin_return_address(2),__builtin_return_address(3)); */ if (!mddev) { diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c index 358cb7caca5c..0d3037784382 100644 --- a/drivers/md/raid1.c +++ b/drivers/md/raid1.c @@ -388,7 +388,7 @@ void raid1_end_request (struct buffer_head *bh, int uptodate) * this branch is our 'one mirror IO has finished' event handler: */ if (!uptodate) - md_error (mddev_to_kdev(r1_bh->mddev), bh->b_dev); + md_error (r1_bh->mddev, bh->b_dev); else /* * Set R1BH_Uptodate in our master buffer_head, so that @@ -832,6 +832,7 @@ static int raid1_diskop(mddev_t *mddev, mdp_disk_t **d, int state) struct mirror_info *tmp, *sdisk, *fdisk, *rdisk, *adisk; mdp_super_t *sb = mddev->sb; mdp_disk_t *failed_desc, *spare_desc, *added_desc; + mdk_rdev_t *spare_rdev, *failed_rdev; print_raid1_conf(conf); md_spin_lock_irq(&conf->device_lock); @@ -989,6 +990,16 @@ static int raid1_diskop(mddev_t *mddev, mdp_disk_t **d, int state) /* * do the switch finally */ + spare_rdev = find_rdev_nr(mddev, spare_desc->number); + failed_rdev = find_rdev_nr(mddev, failed_desc->number); + + /* There must be a spare_rdev, but there may not be a + * failed_rdev. That slot might be empty... + */ + spare_rdev->desc_nr = failed_desc->number; + if (failed_rdev) + failed_rdev->desc_nr = spare_desc->number; + xchg_values(*spare_desc, *failed_desc); xchg_values(*fdisk, *sdisk); @@ -1415,7 +1426,7 @@ static void end_sync_read(struct buffer_head *bh, int uptodate) * We don't do much here, just schedule handling by raid1d */ if (!uptodate) - md_error (mddev_to_kdev(r1_bh->mddev), bh->b_dev); + md_error (r1_bh->mddev, bh->b_dev); else set_bit(R1BH_Uptodate, &r1_bh->state); raid1_reschedule_retry(r1_bh); @@ -1426,7 +1437,7 @@ static void end_sync_write(struct buffer_head *bh, int uptodate) struct raid1_bh * r1_bh = (struct raid1_bh *)(bh->b_private); if (!uptodate) - md_error (mddev_to_kdev(r1_bh->mddev), bh->b_dev); + md_error (r1_bh->mddev, bh->b_dev); if (atomic_dec_and_test(&r1_bh->remaining)) { mddev_t *mddev = r1_bh->mddev; unsigned long sect = bh->b_blocknr * (bh->b_size>>9); @@ -1437,69 +1448,6 @@ static void end_sync_write(struct buffer_head *bh, int uptodate) } } -/* - * This will catch the scenario in which one of the mirrors was - * mounted as a normal device rather than as a part of a raid set. - * - * check_consistency is very personality-dependent, eg. RAID5 cannot - * do this check, it uses another method. - */ -static int __check_consistency (mddev_t *mddev, int row) -{ - raid1_conf_t *conf = mddev_to_conf(mddev); - int disks = MD_SB_DISKS; - kdev_t dev; - struct buffer_head *bh = NULL; - int i, rc = 0; - char *buffer = NULL; - - for (i = 0; i < disks; i++) { - printk("(checking disk %d)\n",i); - if (!conf->mirrors[i].operational) - continue; - printk("(really checking disk %d)\n",i); - dev = conf->mirrors[i].dev; - set_blocksize(dev, 4096); - if ((bh = bread(dev, row / 4, 4096)) == NULL) - break; - if (!buffer) { - buffer = (char *) __get_free_page(GFP_KERNEL); - if (!buffer) - break; - memcpy(buffer, bh->b_data, 4096); - } else if (memcmp(buffer, bh->b_data, 4096)) { - rc = 1; - break; - } - bforget(bh); - fsync_dev(dev); - invalidate_buffers(dev); - bh = NULL; - } - if (buffer) - free_page((unsigned long) buffer); - if (bh) { - dev = bh->b_dev; - bforget(bh); - fsync_dev(dev); - invalidate_buffers(dev); - } - return rc; -} - -static int check_consistency (mddev_t *mddev) -{ - if (__check_consistency(mddev, 0)) -/* - * we do not do this currently, as it's perfectly possible to - * have an inconsistent array when it's freshly created. Only - * newly written data has to be consistent. - */ - return 0; - - return 0; -} - #define INVALID_LEVEL KERN_WARNING \ "raid1: md%d: raid level not set to mirroring (%d)\n" @@ -1530,9 +1478,6 @@ static int check_consistency (mddev_t *mddev) #define NONE_OPERATIONAL KERN_ERR \ "raid1: no operational mirrors for md%d\n" -#define RUNNING_CKRAID KERN_ERR \ -"raid1: detected mirror differences -- running resync\n" - #define ARRAY_IS_ACTIVE KERN_INFO \ "raid1: raid set md%d active with %d out of %d mirrors\n" @@ -1714,17 +1659,6 @@ static int raid1_run (mddev_t *mddev) start_recovery = 1; } - if (!start_recovery && (sb->state & (1 << MD_SB_CLEAN))) { - /* - * we do sanity checks even if the device says - * it's clean ... - */ - if (check_consistency(mddev)) { - printk(RUNNING_CKRAID); - sb->state &= ~(1 << MD_SB_CLEAN); - } - } - { const char * name = "raid1d"; @@ -1794,7 +1728,6 @@ out: #undef OPERATIONAL #undef SPARE #undef NONE_OPERATIONAL -#undef RUNNING_CKRAID #undef ARRAY_IS_ACTIVE static int raid1_stop_resync (mddev_t *mddev) diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c index d00cda6d480c..8ec00dbbaab3 100644 --- a/drivers/md/raid5.c +++ b/drivers/md/raid5.c @@ -156,9 +156,9 @@ static int grow_buffers(struct stripe_head *sh, int num, int b_size, int priorit return 1; memset(bh, 0, sizeof (struct buffer_head)); init_waitqueue_head(&bh->b_wait); - page = alloc_page(priority); - bh->b_data = page_address(page); - if (!bh->b_data) { + if ((page = alloc_page(priority))) + bh->b_data = page_address(page); + else { kfree(bh); return 1; } @@ -412,7 +412,7 @@ static void raid5_end_read_request (struct buffer_head * bh, int uptodate) spin_lock_irqsave(&conf->device_lock, flags); } } else { - md_error(mddev_to_kdev(conf->mddev), bh->b_dev); + md_error(conf->mddev, bh->b_dev); clear_bit(BH_Uptodate, &bh->b_state); } clear_bit(BH_Lock, &bh->b_state); @@ -440,7 +440,7 @@ static void raid5_end_write_request (struct buffer_head *bh, int uptodate) md_spin_lock_irqsave(&conf->device_lock, flags); if (!uptodate) - md_error(mddev_to_kdev(conf->mddev), bh->b_dev); + md_error(conf->mddev, bh->b_dev); clear_bit(BH_Lock, &bh->b_state); set_bit(STRIPE_HANDLE, &sh->state); __release_stripe(conf, sh); @@ -1256,76 +1256,6 @@ static void raid5syncd (void *data) printk("raid5: resync finished.\n"); } -static int __check_consistency (mddev_t *mddev, int row) -{ - raid5_conf_t *conf = mddev->private; - kdev_t dev; - struct buffer_head *bh[MD_SB_DISKS], *tmp = NULL; - int i, ret = 0, nr = 0, count; - struct buffer_head *bh_ptr[MAX_XOR_BLOCKS]; - - if (conf->working_disks != conf->raid_disks) - goto out; - tmp = kmalloc(sizeof(*tmp), GFP_KERNEL); - tmp->b_size = 4096; - tmp->b_page = alloc_page(GFP_KERNEL); - tmp->b_data = page_address(tmp->b_page); - if (!tmp->b_data) - goto out; - md_clear_page(tmp->b_data); - memset(bh, 0, MD_SB_DISKS * sizeof(struct buffer_head *)); - for (i = 0; i < conf->raid_disks; i++) { - dev = conf->disks[i].dev; - set_blocksize(dev, 4096); - bh[i] = bread(dev, row / 4, 4096); - if (!bh[i]) - break; - nr++; - } - if (nr == conf->raid_disks) { - bh_ptr[0] = tmp; - count = 1; - for (i = 1; i < nr; i++) { - bh_ptr[count++] = bh[i]; - if (count == MAX_XOR_BLOCKS) { - xor_block(count, &bh_ptr[0]); - count = 1; - } - } - if (count != 1) { - xor_block(count, &bh_ptr[0]); - } - if (memcmp(tmp->b_data, bh[0]->b_data, 4096)) - ret = 1; - } - for (i = 0; i < conf->raid_disks; i++) { - dev = conf->disks[i].dev; - if (bh[i]) { - bforget(bh[i]); - bh[i] = NULL; - } - fsync_dev(dev); - invalidate_buffers(dev); - } - free_page((unsigned long) tmp->b_data); -out: - if (tmp) - kfree(tmp); - return ret; -} - -static int check_consistency (mddev_t *mddev) -{ - if (__check_consistency(mddev, 0)) -/* - * We are not checking this currently, as it's legitimate to have - * an inconsistent array, at creation time. - */ - return 0; - - return 0; -} - static int raid5_run (mddev_t *mddev) { raid5_conf_t *conf; @@ -1485,12 +1415,6 @@ static int raid5_run (mddev_t *mddev) start_recovery = 1; } - if (!start_recovery && (sb->state & (1 << MD_SB_CLEAN)) && - check_consistency(mddev)) { - printk(KERN_ERR "raid5: detected raid-5 superblock xor inconsistency -- running resync\n"); - sb->state &= ~(1 << MD_SB_CLEAN); - } - { const char * name = "raid5d"; @@ -1704,6 +1628,7 @@ static int raid5_diskop(mddev_t *mddev, mdp_disk_t **d, int state) struct disk_info *tmp, *sdisk, *fdisk, *rdisk, *adisk; mdp_super_t *sb = mddev->sb; mdp_disk_t *failed_desc, *spare_desc, *added_desc; + mdk_rdev_t *spare_rdev, *failed_rdev; print_raid5_conf(conf); md_spin_lock_irq(&conf->device_lock); @@ -1875,6 +1800,16 @@ static int raid5_diskop(mddev_t *mddev, mdp_disk_t **d, int state) /* * do the switch finally */ + spare_rdev = find_rdev_nr(mddev, spare_desc->number); + failed_rdev = find_rdev_nr(mddev, failed_desc->number); + + /* There must be a spare_rdev, but there may not be a + * failed_rdev. That slot might be empty... + */ + spare_rdev->desc_nr = failed_desc->number; + if (failed_rdev) + failed_rdev->desc_nr = spare_desc->number; + xchg_values(*spare_desc, *failed_desc); xchg_values(*fdisk, *sdisk); diff --git a/drivers/net/8390.c b/drivers/net/8390.c index 48396e904433..491333add53a 100644 --- a/drivers/net/8390.c +++ b/drivers/net/8390.c @@ -453,6 +453,8 @@ void ei_interrupt(int irq, void *dev_id, struct pt_regs * regs) { if (!netif_running(dev)) { printk(KERN_WARNING "%s: interrupt from stopped card\n", dev->name); + /* rmk - acknowledge the interrupts */ + outb_p(interrupts, e8390_base + EN0_ISR); interrupts = 0; break; } diff --git a/drivers/net/Config.in b/drivers/net/Config.in index 954410adb5bb..c4c3ec594c0d 100644 --- a/drivers/net/Config.in +++ b/drivers/net/Config.in @@ -35,6 +35,9 @@ if [ "$CONFIG_NET_ETHERNET" = "y" ]; then fi if [ "$CONFIG_PPC" = "y" ]; then tristate ' MACE (Power Mac ethernet) support' CONFIG_MACE + if [ "$CONFIG_MACE" != "n" ]; then + bool ' Use AAUI port instead of TP by default' CONFIG_MACE_AAUI_PORT + fi tristate ' BMAC (G3 ethernet) support' CONFIG_BMAC tristate ' GMAC (G4/iBook ethernet) support' CONFIG_GMAC tristate ' Symbios 53c885 (Synergy ethernet) support' CONFIG_NCR885E @@ -147,6 +150,7 @@ if [ "$CONFIG_NET_ETHERNET" = "y" ]; then dep_tristate ' EtherExpressPro/100 support' CONFIG_EEPRO100 $CONFIG_PCI dep_mbool ' Enable Power Management (EXPERIMENTAL)' CONFIG_EEPRO100_PM $CONFIG_EEPRO100 $CONFIG_EXPERIMENTAL dep_tristate ' Mylex EISA LNE390A/B support (EXPERIMENTAL)' CONFIG_LNE390 $CONFIG_EISA $CONFIG_EXPERIMENTAL + dep_tristate ' Myson MTD-8xx PCI Ethernet support' CONFIG_FEALNX $CONFIG_PCI dep_tristate ' National Semiconductor DP8381x series PCI Ethernet support' CONFIG_NATSEMI $CONFIG_PCI dep_tristate ' PCI NE2000 and clones support (see help)' CONFIG_NE2K_PCI $CONFIG_PCI dep_tristate ' Novell/Eagle/Microdyne NE3210 EISA support (EXPERIMENTAL)' CONFIG_NE3210 $CONFIG_EISA $CONFIG_EXPERIMENTAL diff --git a/drivers/net/Makefile b/drivers/net/Makefile index 598557d7e410..ee2d35a70eb9 100644 --- a/drivers/net/Makefile +++ b/drivers/net/Makefile @@ -76,6 +76,7 @@ obj-$(CONFIG_YELLOWFIN) += yellowfin.o obj-$(CONFIG_ACENIC) += acenic.o obj-$(CONFIG_NATSEMI) += natsemi.o obj-$(CONFIG_STNIC) += stnic.o 8390.o +obj-$(CONFIG_FEALNX) += fealnx.o ifeq ($(CONFIG_SK98LIN),y) obj-y += sk98lin/sk98lin.o diff --git a/drivers/net/appletalk/cops.c b/drivers/net/appletalk/cops.c index 48f746d0b691..a82d4dcb0f71 100644 --- a/drivers/net/appletalk/cops.c +++ b/drivers/net/appletalk/cops.c @@ -1,7 +1,7 @@ /* cops.c: LocalTalk driver for Linux. * * Authors: - * - Jay Schulist + * - Jay Schulist * * With more than a little help from; * - Alan Cox @@ -34,7 +34,7 @@ */ static const char *version = -"cops.c:v0.04 6/7/98 Jay Schulist \n"; +"cops.c:v0.04 6/7/98 Jay Schulist \n"; /* * Sources: * COPS Localtalk SDK. This provides almost all of the information diff --git a/drivers/net/appletalk/cops.h b/drivers/net/appletalk/cops.h index 43863491222a..c68ba9c2ef46 100644 --- a/drivers/net/appletalk/cops.h +++ b/drivers/net/appletalk/cops.h @@ -1,7 +1,7 @@ /* cops.h: LocalTalk driver for Linux. * * Authors: - * - Jay Schulist + * - Jay Schulist */ #ifndef __LINUX_COPSLTALK_H diff --git a/drivers/net/appletalk/cops_ffdrv.h b/drivers/net/appletalk/cops_ffdrv.h index 3a20437b59a2..4131b4a7a65b 100644 --- a/drivers/net/appletalk/cops_ffdrv.h +++ b/drivers/net/appletalk/cops_ffdrv.h @@ -21,7 +21,7 @@ /* cops_ffdrv.h: LocalTalk driver firmware dump for Linux. * * Authors: - * - Jay Schulist + * - Jay Schulist */ #include diff --git a/drivers/net/appletalk/cops_ltdrv.h b/drivers/net/appletalk/cops_ltdrv.h index e3e850c3148f..05de66dd9206 100644 --- a/drivers/net/appletalk/cops_ltdrv.h +++ b/drivers/net/appletalk/cops_ltdrv.h @@ -20,7 +20,7 @@ /* cops_ltdrv.h: LocalTalk driver firmware dump for Linux. * * Authors: - * - Jay Schulist + * - Jay Schulist */ #include diff --git a/drivers/net/appletalk/ipddp.c b/drivers/net/appletalk/ipddp.c index d3384b9c9e5e..89f33cc04781 100644 --- a/drivers/net/appletalk/ipddp.c +++ b/drivers/net/appletalk/ipddp.c @@ -4,7 +4,7 @@ * * Authors: * - DDP-IP Encap by: Bradford W. Johnson - * - DDP-IP Decap by: Jay Schulist + * - DDP-IP Decap by: Jay Schulist * * Derived from: * - Almost all code already existed in net/appletalk/ddp.c I just @@ -14,7 +14,7 @@ * Written 1993-94 by Donald Becker. * - dummy.c: A dummy net driver. By Nick Holloway. * - MacGate: A user space Daemon for Appletalk-IP Decap for - * Linux by Jay Schulist + * Linux by Jay Schulist * * Copyright 1993 United States Government as represented by the * Director, National Security Agency. @@ -69,7 +69,7 @@ static int __init ipddp_init(struct net_device *dev) printk("%s: Appletalk-IP Encap. mode by Bradford W. Johnson \n", dev->name); if(ipddp_mode == IPDDP_DECAP) - printk("%s: Appletalk-IP Decap. mode by Jay Schulist \n", + printk("%s: Appletalk-IP Decap. mode by Jay Schulist \n", dev->name); /* Fill in the device structure with ethernet-generic values. */ diff --git a/drivers/net/bmac.c b/drivers/net/bmac.c index 5dab3e39520a..84d91cb4e6c3 100644 --- a/drivers/net/bmac.c +++ b/drivers/net/bmac.c @@ -76,9 +76,6 @@ struct bmac_data { struct net_device_stats stats; struct timer_list tx_timeout; int timeout_active; - int reset_and_enabled; - int rx_allocated; - int tx_allocated; unsigned short hash_use_count[64]; unsigned short hash_table_mask[4]; struct net_device *next_bmac; @@ -126,6 +123,7 @@ static bmac_reg_entry_t reg_entries[N_REG_ENTRIES] = { }; static struct net_device *bmac_devs; +static unsigned char *bmac_emergency_rxbuf; #ifdef CONFIG_PMAC_PBOOK static int bmac_sleep_notify(struct pmu_sleep_notifier *self, int when); @@ -151,9 +149,9 @@ static int bmac_close(struct net_device *dev); static int bmac_transmit_packet(struct sk_buff *skb, struct net_device *dev); static struct net_device_stats *bmac_stats(struct net_device *dev); static void bmac_set_multicast(struct net_device *dev); -static int bmac_reset_and_enable(struct net_device *dev, int enable); +static void bmac_reset_and_enable(struct net_device *dev); static void bmac_start_chip(struct net_device *dev); -static int bmac_init_chip(struct net_device *dev); +static void bmac_init_chip(struct net_device *dev); static void bmac_init_registers(struct net_device *dev); static void bmac_reset_chip(struct net_device *dev); static int bmac_set_address(struct net_device *dev, void *addr); @@ -184,17 +182,6 @@ dbdma_ld32(volatile unsigned long *a) return swap; } -static void -dbdma_stop(volatile struct dbdma_regs *dmap) -{ - dbdma_st32((volatile unsigned long *)&dmap->control, - DBDMA_CLEAR(RUN) | DBDMA_SET(FLUSH)); - eieio(); - - while (dbdma_ld32((volatile unsigned long *)&dmap->status) & (ACTIVE|FLUSH)) - eieio(); -} - static void dbdma_continue(volatile struct dbdma_regs *dmap) { @@ -467,12 +454,11 @@ bmac_init_phy(struct net_device *dev) } } -static int +static void bmac_init_chip(struct net_device *dev) { bmac_init_phy(dev); bmac_init_registers(dev); - return 1; } #ifdef CONFIG_PMAC_PBOOK @@ -503,7 +489,7 @@ bmac_sleep_notify(struct pmu_sleep_notifier *self, int when) break; case PBOOK_WAKE: /* see if this is enough */ - bmac_reset_and_enable(bmac_devs, 1); + bmac_reset_and_enable(bmac_devs); enable_irq(bmac_devs->irq); enable_irq(bp->tx_dma_intr); enable_irq(bp->rx_dma_intr); @@ -569,9 +555,12 @@ bmac_construct_xmt(struct sk_buff *skb, volatile struct dbdma_cmd *cp) } static void -bmac_construct_rxbuff(unsigned char *addr, volatile struct dbdma_cmd *cp) +bmac_construct_rxbuff(struct sk_buff *skb, volatile struct dbdma_cmd *cp) { - dbdma_setcmd(cp, (INPUT_LAST | INTR_ALWAYS), RX_BUFLEN, virt_to_bus(addr), 0); + unsigned char *addr = skb? skb->data: bmac_emergency_rxbuf; + + dbdma_setcmd(cp, (INPUT_LAST | INTR_ALWAYS), RX_BUFLEN, + virt_to_bus(addr), 0); } /* Bit-reverse one byte of an ethernet hardware address. */ @@ -586,7 +575,7 @@ bitrev(unsigned char b) } -static int +static void bmac_init_tx_ring(struct bmac_data *bp) { volatile struct dbdma_regs *td = bp->tx_dma; @@ -605,9 +594,6 @@ bmac_init_tx_ring(struct bmac_data *bp) dbdma_reset(td); out_le32(&td->wait_sel, 0x00200020); out_le32(&td->cmdptr, virt_to_bus(bp->tx_cmds)); - - return 1; - } static int @@ -615,22 +601,20 @@ bmac_init_rx_ring(struct bmac_data *bp) { volatile struct dbdma_regs *rd = bp->rx_dma; int i; + struct sk_buff *skb; /* initialize list of sk_buffs for receiving and set up recv dma */ - if (!bp->rx_allocated) { - for (i = 0; i < N_RX_RING; i++) { - bp->rx_bufs[i] = dev_alloc_skb(RX_BUFLEN+2); - if (bp->rx_bufs[i] == NULL) - return 0; - skb_reserve(bp->rx_bufs[i], 2); + memset((char *)bp->rx_cmds, 0, + (N_RX_RING + 1) * sizeof(struct dbdma_cmd)); + for (i = 0; i < N_RX_RING; i++) { + if ((skb = bp->rx_bufs[i]) == NULL) { + bp->rx_bufs[i] = skb = dev_alloc_skb(RX_BUFLEN+2); + if (skb != NULL) + skb_reserve(skb, 2); } - bp->rx_allocated = 1; + bmac_construct_rxbuff(skb, &bp->rx_cmds[i]); } - memset((char *)bp->rx_cmds, 0, (N_RX_RING+1) * sizeof(struct dbdma_cmd)); - for (i = 0; i < N_RX_RING; i++) - bmac_construct_rxbuff(bp->rx_bufs[i]->data, &bp->rx_cmds[i]); - bp->rx_empty = 0; bp->rx_fill = i; @@ -706,27 +690,36 @@ static void bmac_rxdma_intr(int irq, void *dev_id, struct pt_regs *regs) cp = &bp->rx_cmds[i]; stat = ld_le16(&cp->xfer_status); residual = ld_le16(&cp->res_count); - if ((stat & ACTIVE) == 0) break; + if ((stat & ACTIVE) == 0) + break; nb = RX_BUFLEN - residual - 2; if (nb < (ETHERMINPACKET - ETHERCRC)) { skb = NULL; bp->stats.rx_length_errors++; bp->stats.rx_errors++; - } else skb = bp->rx_bufs[i]; + } else { + skb = bp->rx_bufs[i]; + bp->rx_bufs[i] = NULL; + } if (skb != NULL) { nb -= ETHERCRC; skb_put(skb, nb); skb->dev = dev; skb->protocol = eth_type_trans(skb, dev); netif_rx(skb); - bp->rx_bufs[i] = dev_alloc_skb(RX_BUFLEN+2); - skb_reserve(bp->rx_bufs[i], 2); - bmac_construct_rxbuff(bp->rx_bufs[i]->data, &bp->rx_cmds[i]); + dev->last_rx = jiffies; ++bp->stats.rx_packets; bp->stats.rx_bytes += nb; } else { ++bp->stats.rx_dropped; } + dev->last_rx = jiffies; + if ((skb = bp->rx_bufs[i]) == NULL) { + bp->rx_bufs[i] = skb = dev_alloc_skb(RX_BUFLEN+2); + if (skb != NULL) + skb_reserve(bp->rx_bufs[i], 2); + } + bmac_construct_rxbuff(skb, &bp->rx_cmds[i]); st_le16(&cp->res_count, 0); st_le16(&cp->xfer_status, 0); last = i; @@ -772,7 +765,13 @@ static void bmac_txdma_intr(int irq, void *dev_id, struct pt_regs *regs) if (txintcount < 10) { XXDEBUG(("bmac_txdma_xfer_stat=%#0x\n", stat)); } - if (!(stat & ACTIVE)) break; + if (!(stat & ACTIVE)) { + /* + * status field might not have been filled by DBDMA + */ + if (cp == bus_to_virt(in_le32(&bp->tx_dma->cmdptr))) + break; + } if (bp->tx_bufs[bp->tx_empty]) { ++bp->stats.tx_packets; @@ -1215,7 +1214,7 @@ bmac_get_station_address(struct net_device *dev, unsigned char *ea) } } -static int bmac_reset_and_enable(struct net_device *dev, int enable) +static void bmac_reset_and_enable(struct net_device *dev) { struct bmac_data *bp = dev->priv; unsigned long flags; @@ -1223,22 +1222,19 @@ static int bmac_reset_and_enable(struct net_device *dev, int enable) unsigned char *data; save_flags(flags); cli(); - bp->reset_and_enabled = 0; bmac_reset_chip(dev); - if (enable) { - if (!bmac_init_tx_ring(bp) || !bmac_init_rx_ring(bp)) - return 0; - if (!bmac_init_chip(dev)) - return 0; - bmac_start_chip(dev); - bmwrite(dev, INTDISABLE, EnableNormal); - bp->reset_and_enabled = 1; - - /* - * It seems that the bmac can't receive until it's transmitted - * a packet. So we give it a dummy packet to transmit. - */ - skb = dev_alloc_skb(ETHERMINPACKET); + bmac_init_tx_ring(bp); + bmac_init_rx_ring(bp); + bmac_init_chip(dev); + bmac_start_chip(dev); + bmwrite(dev, INTDISABLE, EnableNormal); + + /* + * It seems that the bmac can't receive until it's transmitted + * a packet. So we give it a dummy packet to transmit. + */ + skb = dev_alloc_skb(ETHERMINPACKET); + if (skb != NULL) { data = skb_put(skb, ETHERMINPACKET); memset(data, 0, ETHERMINPACKET); memcpy(data, dev->dev_addr, 6); @@ -1246,13 +1242,14 @@ static int bmac_reset_and_enable(struct net_device *dev, int enable) bmac_transmit_packet(skb, dev); } restore_flags(flags); - return 1; } static int __init bmac_probe(void) { struct device_node *bmac; + MOD_INC_USE_COUNT; + for (bmac = find_devices("bmac"); bmac != 0; bmac = bmac->next) bmac_probe1(bmac, 0); for (bmac = find_compatible_devices("network", "bmac+"); bmac != 0; @@ -1265,7 +1262,10 @@ static int __init bmac_probe(void) pmu_register_sleep_notifier(&bmac_sleep_notifier); #endif } - return 0; + + MOD_DEC_USE_COUNT; + + return bmac_devs? 0: -ENODEV; } static void __init bmac_probe1(struct device_node *bmac, int is_bmac_plus) @@ -1290,6 +1290,14 @@ static void __init bmac_probe1(struct device_node *bmac, int is_bmac_plus) } } + if (bmac_emergency_rxbuf == NULL) { + bmac_emergency_rxbuf = kmalloc(RX_BUFLEN, GFP_KERNEL); + if (bmac_emergency_rxbuf == NULL) { + printk(KERN_ERR "BMAC: can't allocate emergency RX buffer\n"); + return; + } + } + dev = init_etherdev(NULL, PRIV_BYTES); if (!dev) { printk(KERN_ERR "init_etherdev failed, out of memory for BMAC %s\n", @@ -1390,9 +1398,7 @@ static int bmac_open(struct net_device *dev) { /* XXDEBUG(("bmac: enter open\n")); */ /* reset the chip */ - if (!bmac_reset_and_enable(dev, 1)) - return -ENOMEM; - + bmac_reset_and_enable(dev); dev->flags |= IFF_RUNNING; return 0; } @@ -1428,7 +1434,6 @@ static int bmac_close(struct net_device *dev) bp->rx_bufs[i] = NULL; } } - bp->rx_allocated = 0; XXDEBUG(("bmac: free tx bufs\n")); for (i = 0; itx_bufs[i] != NULL) { @@ -1436,7 +1441,6 @@ static int bmac_close(struct net_device *dev) bp->tx_bufs[i] = NULL; } } - bp->reset_and_enabled = 0; XXDEBUG(("bmac: all bufs freed\n")); return 0; @@ -1608,6 +1612,11 @@ static void __exit bmac_cleanup (void) struct bmac_data *bp; struct net_device *dev; + if (bmac_emergency_rxbuf != NULL) { + kfree(bmac_emergency_rxbuf); + bmac_emergency_rxbuf = NULL; + } + if (bmac_devs == 0) return; #ifdef CONFIG_PMAC_PBOOK diff --git a/drivers/net/fealnx.c b/drivers/net/fealnx.c new file mode 100644 index 000000000000..074f2709be96 --- /dev/null +++ b/drivers/net/fealnx.c @@ -0,0 +1,1777 @@ +/* + Written 1998-2000 by Donald Becker. + + This software may be used and distributed according to the terms of + the GNU General Public License (GPL), incorporated herein by reference. + Drivers based on or derived from this code fall under the GPL and must + retain the authorship, copyright and license notice. This file is not + a complete program and may only be used when the entire operating + system is licensed under the GPL. + + The author may be reached as becker@scyld.com, or C/O + Scyld Computing Corporation + 410 Severn Ave., Suite 210 + Annapolis MD 21403 + + Support information and updates available at + http://www.scyld.com/network/pci-skeleton.html +*/ + +static int debug = 0; /* 1-> print debug message */ +static int max_interrupt_work = 20; + +/* Maximum number of multicast addresses to filter (vs. Rx-all-multicast). */ +static int multicast_filter_limit = 32; + +/* Set the copy breakpoint for the copy-only-tiny-frames scheme. */ +/* Setting to > 1518 effectively disables this feature. */ +static int rx_copybreak = 0; + +/* Used to pass the media type, etc. */ +/* Both 'options[]' and 'full_duplex[]' should exist for driver */ +/* interoperability. */ +/* The media type is usually passed in 'options[]'. */ +#define MAX_UNITS 8 /* More are supported, limit only on options */ +static int options[MAX_UNITS] = { -1, -1, -1, -1, -1, -1, -1, -1 }; +static int full_duplex[MAX_UNITS] = { -1, -1, -1, -1, -1, -1, -1, -1 }; + +/* Operational parameters that are set at compile time. */ +/* Keep the ring sizes a power of two for compile efficiency. */ +/* The compiler will convert '%'<2^N> into a bit mask. */ +/* Making the Tx ring too large decreases the effectiveness of channel */ +/* bonding and packet priority. */ +/* There are no ill effects from too-large receive rings. */ +// 88-12-9 modify, +// #define TX_RING_SIZE 16 +// #define RX_RING_SIZE 32 +#define TX_RING_SIZE 6 +#define RX_RING_SIZE 12 + +/* Operational parameters that usually are not changed. */ +/* Time in jiffies before concluding the transmitter is hung. */ +#define TX_TIMEOUT (2*HZ) + +#define PKT_BUF_SZ 1536 /* Size of each temporary Rx buffer. */ + + +/* Include files, designed to support most kernel versions 2.0.0 and later. */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include /* Processor type for cache alignment. */ +#include +#include + +/* These identify the driver base version and may not be removed. */ +static char version[] __devinitdata = +KERN_INFO "fealnx.c:v2.50 1/17/2001\n"; + + +/* This driver was written to use PCI memory space, however some x86 systems + work only with I/O space accesses. */ +#ifndef __alpha__ +#define USE_IO_OPS +#endif + +#ifdef USE_IO_OPS +#undef readb +#undef readw +#undef readl +#undef writeb +#undef writew +#undef writel +#define readb inb +#define readw inw +#define readl inl +#define writeb outb +#define writew outw +#define writel outl +#endif + +/* Kernel compatibility defines, some common to David Hinds' PCMCIA package. */ +/* This is only in the support-all-kernels source code. */ + +#define RUN_AT(x) (jiffies + (x)) + +MODULE_AUTHOR("Myson or whoever"); +MODULE_DESCRIPTION("Myson MTD-8xx 100/10M Ethernet PCI Adapter Driver"); +MODULE_PARM(max_interrupt_work, "i"); +MODULE_PARM(min_pci_latency, "i"); +MODULE_PARM(debug, "i"); +MODULE_PARM(rx_copybreak, "i"); +MODULE_PARM(multicast_filter_limit, "i"); +MODULE_PARM(options, "1-" __MODULE_STRING(MAX_UNITS) "i"); +MODULE_PARM(full_duplex, "1-" __MODULE_STRING(MAX_UNITS) "i"); + +#define MIN_REGION_SIZE 136 + +enum pci_flags_bit { + PCI_USES_IO = 1, + PCI_USES_MEM = 2, + PCI_USES_MASTER = 4, + PCI_ADDR0 = 0x10 << 0, + PCI_ADDR1 = 0x10 << 1, + PCI_ADDR2 = 0x10 << 2, + PCI_ADDR3 = 0x10 << 3, +}; + +/* A chip capabilities table, matching the entries in pci_tbl[] above. */ +enum chip_capability_flags { + HAS_MII_XCVR, + HAS_CHIP_XCVR, +}; + +/* 89/6/13 add, */ +/* for different PHY */ +enum phy_type_flags { + MysonPHY = 1, + AhdocPHY = 2, + SeeqPHY = 3, + MarvellPHY = 4, + Myson981 = 5, + LevelOnePHY = 6, + OtherPHY = 10, +}; + +struct chip_info { + char *chip_name; + int io_size; + int flags; +}; + +static struct chip_info skel_netdrv_tbl[] = { + {"100/10M Ethernet PCI Adapter", 136, HAS_MII_XCVR}, + {"100/10M Ethernet PCI Adapter", 136, HAS_CHIP_XCVR}, + {"1000/100/10M Ethernet PCI Adapter", 136, HAS_MII_XCVR}, +}; + +/* Offsets to the Command and Status Registers. */ +enum fealnx_offsets { + PAR0 = 0x0, /* physical address 0-3 */ + PAR1 = 0x04, /* physical address 4-5 */ + MAR0 = 0x08, /* multicast address 0-3 */ + MAR1 = 0x0C, /* multicast address 4-7 */ + FAR0 = 0x10, /* flow-control address 0-3 */ + FAR1 = 0x14, /* flow-control address 4-5 */ + TCRRCR = 0x18, /* receive & transmit configuration */ + BCR = 0x1C, /* bus command */ + TXPDR = 0x20, /* transmit polling demand */ + RXPDR = 0x24, /* receive polling demand */ + RXCWP = 0x28, /* receive current word pointer */ + TXLBA = 0x2C, /* transmit list base address */ + RXLBA = 0x30, /* receive list base address */ + ISR = 0x34, /* interrupt status */ + IMR = 0x38, /* interrupt mask */ + FTH = 0x3C, /* flow control high/low threshold */ + MANAGEMENT = 0x40, /* bootrom/eeprom and mii management */ + TALLY = 0x44, /* tally counters for crc and mpa */ + TSR = 0x48, /* tally counter for transmit status */ + BMCRSR = 0x4c, /* basic mode control and status */ + PHYIDENTIFIER = 0x50, /* phy identifier */ + ANARANLPAR = 0x54, /* auto-negotiation advertisement and link + partner ability */ + ANEROCR = 0x58, /* auto-negotiation expansion and pci conf. */ + BPREMRPSR = 0x5c, /* bypass & receive error mask and phy status */ +}; + +/* Bits in the interrupt status/enable registers. */ +/* The bits in the Intr Status/Enable registers, mostly interrupt sources. */ +enum intr_status_bits { + RFCON = 0x00020000, /* receive flow control xon packet */ + RFCOFF = 0x00010000, /* receive flow control xoff packet */ + LSCStatus = 0x00008000, /* link status change */ + ANCStatus = 0x00004000, /* autonegotiation completed */ + FBE = 0x00002000, /* fatal bus error */ + FBEMask = 0x00001800, /* mask bit12-11 */ + ParityErr = 0x00000000, /* parity error */ + TargetErr = 0x00001000, /* target abort */ + MasterErr = 0x00000800, /* master error */ + TUNF = 0x00000400, /* transmit underflow */ + ROVF = 0x00000200, /* receive overflow */ + ETI = 0x00000100, /* transmit early int */ + ERI = 0x00000080, /* receive early int */ + CNTOVF = 0x00000040, /* counter overflow */ + RBU = 0x00000020, /* receive buffer unavailable */ + TBU = 0x00000010, /* transmit buffer unavilable */ + TI = 0x00000008, /* transmit interrupt */ + RI = 0x00000004, /* receive interrupt */ + RxErr = 0x00000002, /* receive error */ +}; + +/* Bits in the NetworkConfig register. */ +enum rx_mode_bits { + RxModeMask = 0xe0, + PROM = 0x80, /* promiscuous mode */ + AB = 0x40, /* accept broadcast */ + AM = 0x20, /* accept mutlicast */ + ARP = 0x08, /* receive runt pkt */ + ALP = 0x04, /* receive long pkt */ + SEP = 0x02, /* receive error pkt */ +}; + +/* The Tulip Rx and Tx buffer descriptors. */ +struct fealnx_desc { + s32 status; + s32 control; + u32 buffer; + u32 next_desc; + struct fealnx_desc *next_desc_logical; + struct sk_buff *skbuff; + u32 reserved1; + u32 reserved2; +}; + +/* Bits in network_desc.status */ +enum rx_desc_status_bits { + RXOWN = 0x80000000, /* own bit */ + FLNGMASK = 0x0fff0000, /* frame length */ + FLNGShift = 16, + MARSTATUS = 0x00004000, /* multicast address received */ + BARSTATUS = 0x00002000, /* broadcast address received */ + PHYSTATUS = 0x00001000, /* physical address received */ + RXFSD = 0x00000800, /* first descriptor */ + RXLSD = 0x00000400, /* last descriptor */ + ErrorSummary = 0x80, /* error summary */ + RUNT = 0x40, /* runt packet received */ + LONG = 0x20, /* long packet received */ + FAE = 0x10, /* frame align error */ + CRC = 0x08, /* crc error */ + RXER = 0x04, /* receive error */ +}; + +enum rx_desc_control_bits { + RXIC = 0x00800000, /* interrupt control */ + RBSShift = 0, +}; + +enum tx_desc_status_bits { + TXOWN = 0x80000000, /* own bit */ + JABTO = 0x00004000, /* jabber timeout */ + CSL = 0x00002000, /* carrier sense lost */ + LC = 0x00001000, /* late collision */ + EC = 0x00000800, /* excessive collision */ + UDF = 0x00000400, /* fifo underflow */ + DFR = 0x00000200, /* deferred */ + HF = 0x00000100, /* heartbeat fail */ + NCRMask = 0x000000ff, /* collision retry count */ + NCRShift = 0, +}; + +enum tx_desc_control_bits { + TXIC = 0x80000000, /* interrupt control */ + ETIControl = 0x40000000, /* early transmit interrupt */ + TXLD = 0x20000000, /* last descriptor */ + TXFD = 0x10000000, /* first descriptor */ + CRCEnable = 0x08000000, /* crc control */ + PADEnable = 0x04000000, /* padding control */ + RetryTxLC = 0x02000000, /* retry late collision */ + PKTSMask = 0x3ff800, /* packet size bit21-11 */ + PKTSShift = 11, + TBSMask = 0x000007ff, /* transmit buffer bit 10-0 */ + TBSShift = 0, +}; + +/* BootROM/EEPROM/MII Management Register */ +#define MASK_MIIR_MII_READ 0x00000000 +#define MASK_MIIR_MII_WRITE 0x00000008 +#define MASK_MIIR_MII_MDO 0x00000004 +#define MASK_MIIR_MII_MDI 0x00000002 +#define MASK_MIIR_MII_MDC 0x00000001 + +/* ST+OP+PHYAD+REGAD+TA */ +#define OP_READ 0x6000 /* ST:01+OP:10+PHYAD+REGAD+TA:Z0 */ +#define OP_WRITE 0x5002 /* ST:01+OP:01+PHYAD+REGAD+TA:10 */ + +/* ------------------------------------------------------------------------- */ +/* Constants for Myson PHY */ +/* ------------------------------------------------------------------------- */ +#define MysonPHYID 0xd0000302 +/* 89-7-27 add, (begin) */ +#define MysonPHYID0 0x0302 +#define StatusRegister 18 +#define SPEED100 0x0400 // bit10 +#define FULLMODE 0x0800 // bit11 +/* 89-7-27 add, (end) */ + +/* ------------------------------------------------------------------------- */ +/* Constants for Seeq 80225 PHY */ +/* ------------------------------------------------------------------------- */ +#define SeeqPHYID0 0x0016 + +#define MIIRegister18 18 +#define SPD_DET_100 0x80 +#define DPLX_DET_FULL 0x40 + +/* ------------------------------------------------------------------------- */ +/* Constants for Ahdoc 101 PHY */ +/* ------------------------------------------------------------------------- */ +#define AhdocPHYID0 0x0022 + +#define DiagnosticReg 18 +#define DPLX_FULL 0x0800 +#define Speed_100 0x0400 + +/* 89/6/13 add, */ +/* -------------------------------------------------------------------------- */ +/* Constants */ +/* -------------------------------------------------------------------------- */ +#define MarvellPHYID0 0x0141 +#define LevelOnePHYID0 0x0013 + +#define MII1000BaseTControlReg 9 +#define MII1000BaseTStatusReg 10 +#define SpecificReg 17 + +/* for 1000BaseT Control Register */ +#define PHYAbletoPerform1000FullDuplex 0x0200 +#define PHYAbletoPerform1000HalfDuplex 0x0100 +#define PHY1000AbilityMask 0x300 + +// for phy specific status register, marvell phy. +#define SpeedMask 0x0c000 +#define Speed_1000M 0x08000 +#define Speed_100M 0x4000 +#define Speed_10M 0 +#define Full_Duplex 0x2000 + +// 89/12/29 add, for phy specific status register, levelone phy, (begin) +#define LXT1000_100M 0x08000 +#define LXT1000_1000M 0x0c000 +#define LXT1000_Full 0x200 +// 89/12/29 add, for phy specific status register, levelone phy, (end) + +/* for 3-in-1 case */ +#define PS10 0x00080000 +#define FD 0x00100000 +#define PS1000 0x00010000 +#define LinkIsUp2 0x00040000 + +/* for PHY */ +#define LinkIsUp 0x0004 + + +struct netdev_private { + /* Descriptor rings first for alignment. */ + struct fealnx_desc rx_ring[RX_RING_SIZE]; + struct fealnx_desc tx_ring[TX_RING_SIZE]; + + struct net_device_stats stats; + + /* Media monitoring timer. */ + struct timer_list timer; + + /* Frequently used values: keep some adjacent for cache effect. */ + int flags; + struct pci_dev *pci_dev; + unsigned long crvalue; + unsigned long bcrvalue; + unsigned long imrvalue; + struct fealnx_desc *cur_rx; + struct fealnx_desc *lack_rxbuf; + int really_rx_count; + struct fealnx_desc *cur_tx; + struct fealnx_desc *cur_tx_copy; + int really_tx_count; + int free_tx_count; + unsigned int rx_buf_sz; /* Based on MTU+slack. */ + + /* These values are keep track of the transceiver/media in use. */ + unsigned int linkok; + unsigned int line_speed; + unsigned int duplexmode; + unsigned int full_duplex:1; /* Full-duplex operation requested. */ + unsigned int duplex_lock:1; + unsigned int medialock:1; /* Do not sense media. */ + unsigned int default_port:4; /* Last dev->if_port value. */ + unsigned int PHYType; + + /* MII transceiver section. */ + int mii_cnt; /* MII device addresses. */ + unsigned char phys[2]; /* MII device addresses. */ +}; + + +static unsigned int mdio_read(struct net_device *dev, int phy_id, int location); +static void mdio_write(struct net_device *dev, int phy_id, int location, int value); +static int netdev_open(struct net_device *dev); +static void getlinktype(struct net_device *dev); +static void getlinkstatus(struct net_device *dev); +static void netdev_timer(unsigned long data); +static void tx_timeout(struct net_device *dev); +static void init_ring(struct net_device *dev); +static int start_tx(struct sk_buff *skb, struct net_device *dev); +static void intr_handler(int irq, void *dev_instance, struct pt_regs *regs); +static int netdev_rx(struct net_device *dev); +static inline unsigned ether_crc(int length, unsigned char *data); +static void set_rx_mode(struct net_device *dev); +static struct net_device_stats *get_stats(struct net_device *dev); +static int mii_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); +static int netdev_close(struct net_device *dev); + + +void stop_nic_tx(long ioaddr, long crvalue) +{ + writel(crvalue & (~0x40000), ioaddr + TCRRCR); + + /* wait for tx stop */ + { + int i = 0, delay = 0x1000; + + while ((!(readl(ioaddr + TCRRCR) & 0x04000000)) && (i < delay)) { + ++i; + } + } +} + + +void stop_nic_rx(long ioaddr, long crvalue) +{ + writel(crvalue & (~0x1), ioaddr + TCRRCR); + + /* wait for rx stop */ + { + int i = 0, delay = 0x1000; + + while ((!(readl(ioaddr + TCRRCR) & 0x00008000)) && (i < delay)) { + ++i; + } + } +} + + + +static int __devinit fealnx_init_one(struct pci_dev *pdev, + const struct pci_device_id *ent) +{ + struct netdev_private *np; + int i, option, err, irq; + static int card_idx = -1; + char boardname[12]; + long ioaddr; + unsigned int chip_id = ent->driver_data; + struct net_device *dev; + +/* when built into the kernel, we only print version if device is found */ +#ifndef MODULE + static int printed_version; + if (!printed_version++) + printk (version); +#endif + + card_idx++; + sprintf(boardname, "fealnx%d", card_idx); + + option = card_idx < MAX_UNITS ? options[card_idx] : 0; + + i = pci_enable_device(pdev); + if (i) return i; + pci_set_master(pdev); + +#ifdef USE_IO_OPS + ioaddr = pci_resource_len(pdev, 0); +#else + ioaddr = pci_resource_len(pdev, 1); +#endif + if (ioaddr < MIN_REGION_SIZE) { + printk(KERN_ERR "%s: region size %ld too small, aborting\n", + boardname, ioaddr); + return -ENODEV; + } + + i = pci_request_regions(pdev, boardname); + if (i) return i; + + irq = pdev->irq; + +#ifdef USE_IO_OPS + ioaddr = pci_resource_start(pdev, 0); +#else + ioaddr = (long) ioremap(pci_resource_start(pdev, 1), + pci_resource_len(pdev, 1)); + if (!ioaddr) { + err = -ENOMEM; + goto err_out_res; + } +#endif + + dev = alloc_etherdev(sizeof(struct netdev_private)); + if (!dev) { + err = -ENOMEM; + goto err_out_unmap; + } + SET_MODULE_OWNER(dev); + + /* read ethernet id */ + for (i = 0; i < 6; ++i) + dev->dev_addr[i] = readb(ioaddr + PAR0 + i); + + /* Reset the chip to erase previous misconfiguration. */ + writel(0x00000001, ioaddr + BCR); + + dev->base_addr = ioaddr; + dev->irq = irq; + + /* Make certain the descriptor lists are aligned. */ + np = dev->priv; + np->pci_dev = pdev; + np->flags = skel_netdrv_tbl[chip_id].flags; + pci_set_drvdata(pdev, dev); + + /* find the connected MII xcvrs */ + if (np->flags == HAS_MII_XCVR) { + int phy, phy_idx = 0; + + for (phy = 1; phy < 32 && phy_idx < 4; phy++) { + int mii_status = mdio_read(dev, phy, 1); + + if (mii_status != 0xffff && mii_status != 0x0000) { + np->phys[phy_idx++] = phy; + printk(KERN_INFO + "%s: MII PHY found at address %d, status " + "0x%4.4x.\n", dev->name, phy, mii_status); + /* get phy type */ + { + unsigned int data; + + data = mdio_read(dev, np->phys[0], 2); + if (data == SeeqPHYID0) + np->PHYType = SeeqPHY; + else if (data == AhdocPHYID0) + np->PHYType = AhdocPHY; + else if (data == MarvellPHYID0) + np->PHYType = MarvellPHY; + else if (data == MysonPHYID0) + np->PHYType = Myson981; + else if (data == LevelOnePHYID0) + np->PHYType = LevelOnePHY; + else + np->PHYType = OtherPHY; + } + } + } + + np->mii_cnt = phy_idx; + if (phy_idx == 0) { + printk(KERN_WARNING "%s: MII PHY not found -- this device may " + "not operate correctly.\n", dev->name); + } + } else { + np->phys[0] = 32; +/* 89/6/23 add, (begin) */ + /* get phy type */ + if (readl(dev->base_addr + PHYIDENTIFIER) == MysonPHYID) + np->PHYType = MysonPHY; + else + np->PHYType = OtherPHY; + } + + if (dev->mem_start) + option = dev->mem_start; + + /* The lower four bits are the media type. */ + if (option > 0) { + if (option & 0x200) + np->full_duplex = 1; + np->default_port = option & 15; + + if (np->default_port) + np->medialock = 1; + } + + if (card_idx < MAX_UNITS && full_duplex[card_idx] > 0) + np->full_duplex = full_duplex[card_idx]; + + if (np->full_duplex) { + printk(KERN_INFO "%s: Media type forced to Full Duplex.\n", dev->name); +/* 89/6/13 add, (begin) */ +// if (np->PHYType==MarvellPHY) + if ((np->PHYType == MarvellPHY) || (np->PHYType == LevelOnePHY)) { + unsigned int data; + + data = mdio_read(dev, np->phys[0], 9); + data = (data & 0xfcff) | 0x0200; + mdio_write(dev, np->phys[0], 9, data); + } +/* 89/6/13 add, (end) */ + if (np->flags == HAS_MII_XCVR) + mdio_write(dev, np->phys[0], 4, 0x141); + else + writel(0x141, dev->base_addr + ANARANLPAR); + np->duplex_lock = 1; + } + + /* The chip-specific entries in the device structure. */ + dev->open = &netdev_open; + dev->hard_start_xmit = &start_tx; + dev->stop = &netdev_close; + dev->get_stats = &get_stats; + dev->set_multicast_list = &set_rx_mode; + dev->do_ioctl = &mii_ioctl; + dev->tx_timeout = tx_timeout; + dev->watchdog_timeo = TX_TIMEOUT; + + err = register_netdev(dev); + if (err) + goto err_out_free; + + printk(KERN_INFO "%s: %s at 0x%lx, ", + dev->name, skel_netdrv_tbl[chip_id].chip_name, ioaddr); + for (i = 0; i < 5; i++) + printk("%2.2x:", dev->dev_addr[i]); + printk("%2.2x, IRQ %d.\n", dev->dev_addr[i], irq); + + return 0; + +err_out_free: + kfree(dev); +err_out_unmap: +#ifndef USE_IO_OPS + iounmap((void *)ioaddr); +err_out_res: +#endif + pci_release_regions(pdev); + return err; +} + +static void __devexit fealnx_remove_one(struct pci_dev *pdev) +{ + struct net_device *dev = pci_get_drvdata(pdev); + if (dev) { + unregister_netdev(dev); +#ifndef USE_IO_OPS + iounmap((void *)dev->base_addr); +#endif + kfree(dev); + pci_release_regions(pdev); + pci_set_drvdata(pdev, NULL); + } else + printk(KERN_ERR "fealnx: remove for unknown device\n"); +} + +unsigned int m80x_read_tick(void) +/* function: Reads the Timer tick count register which decrements by 2 from */ +/* 65536 to 0 every 1/36.414 of a second. Each 2 decrements of the *//* count represents 838 nsec's. */ +/* input : none. */ +/* output : none. */ +{ + unsigned char tmp; + int value; + + writeb((char) 0x06, 0x43); // Command 8254 to latch T0's count + + // now read the count. + tmp = (unsigned char) readb(0x40); + value = ((int) tmp) << 8; + tmp = (unsigned char) readb(0x40); + value |= (((int) tmp) & 0xff); + return (value); +} + + +void m80x_delay(unsigned int interval) +/* function: to wait for a specified time. */ +/* input : interval ... the specified time. */ +/* output : none. */ +{ + unsigned int interval1, interval2, i = 0; + + interval1 = m80x_read_tick(); // get initial value + do { + interval2 = m80x_read_tick(); + if (interval1 < interval2) + interval1 = interval2; + ++i; + } while (((interval1 - interval2) < (ushort) interval) && (i < 65535)); +} + + +static ulong m80x_send_cmd_to_phy(long miiport, int opcode, int phyad, int regad) +{ + ulong miir; + int i; + unsigned int mask, data; + + /* enable MII output */ + miir = (ulong) readl(miiport); + miir &= 0xfffffff0; + + miir |= MASK_MIIR_MII_WRITE + MASK_MIIR_MII_MDO; + + /* send 32 1's preamble */ + for (i = 0; i < 32; i++) { + /* low MDC; MDO is already high (miir) */ + miir &= ~MASK_MIIR_MII_MDC; + writel(miir, miiport); + + /* high MDC */ + miir |= MASK_MIIR_MII_MDC; + writel(miir, miiport); + } + + /* calculate ST+OP+PHYAD+REGAD+TA */ + data = opcode | (phyad << 7) | (regad << 2); + + /* sent out */ + mask = 0x8000; + while (mask) { + /* low MDC, prepare MDO */ + miir &= ~(MASK_MIIR_MII_MDC + MASK_MIIR_MII_MDO); + if (mask & data) + miir |= MASK_MIIR_MII_MDO; + + writel(miir, miiport); + /* high MDC */ + miir |= MASK_MIIR_MII_MDC; + writel(miir, miiport); + m80x_delay(30); + + /* next */ + mask >>= 1; + if (mask == 0x2 && opcode == OP_READ) + miir &= ~MASK_MIIR_MII_WRITE; + } + return miir; +} + + +static unsigned int mdio_read(struct net_device *dev, int phyad, int regad) +{ + long miiport = dev->base_addr + MANAGEMENT; + ulong miir; + unsigned int mask, data; + + miir = m80x_send_cmd_to_phy(miiport, OP_READ, phyad, regad); + + /* read data */ + mask = 0x8000; + data = 0; + while (mask) { + /* low MDC */ + miir &= ~MASK_MIIR_MII_MDC; + writel(miir, miiport); + + /* read MDI */ + miir = readl(miiport); + if (miir & MASK_MIIR_MII_MDI) + data |= mask; + + /* high MDC, and wait */ + miir |= MASK_MIIR_MII_MDC; + writel(miir, miiport); + m80x_delay((int) 30); + + /* next */ + mask >>= 1; + } + + /* low MDC */ + miir &= ~MASK_MIIR_MII_MDC; + writel(miir, miiport); + + return data; +} + + +static void mdio_write(struct net_device *dev, int phyad, int regad, int data) +{ + long miiport = dev->base_addr + MANAGEMENT; + ulong miir; + unsigned int mask; + + miir = m80x_send_cmd_to_phy(miiport, OP_WRITE, phyad, regad); + + /* write data */ + mask = 0x8000; + while (mask) { + /* low MDC, prepare MDO */ + miir &= ~(MASK_MIIR_MII_MDC + MASK_MIIR_MII_MDO); + if (mask & data) + miir |= MASK_MIIR_MII_MDO; + writel(miir, miiport); + + /* high MDC */ + miir |= MASK_MIIR_MII_MDC; + writel(miir, miiport); + + /* next */ + mask >>= 1; + } + + /* low MDC */ + miir &= ~MASK_MIIR_MII_MDC; + writel(miir, miiport); + + return; +} + + +static int netdev_open(struct net_device *dev) +{ + struct netdev_private *np = dev->priv; + long ioaddr = dev->base_addr; + + writel(0x00000001, ioaddr + BCR); /* Reset */ + + if (request_irq(dev->irq, &intr_handler, SA_SHIRQ, dev->name, dev)) + return -EAGAIN; + + init_ring(dev); + + writel(virt_to_bus(np->rx_ring), ioaddr + RXLBA); + writel(virt_to_bus(np->tx_ring), ioaddr + TXLBA); + + /* Initialize other registers. */ + /* Configure the PCI bus bursts and FIFO thresholds. + 486: Set 8 longword burst. + 586: no burst limit. + Burst length 5:3 + 0 0 0 1 + 0 0 1 4 + 0 1 0 8 + 0 1 1 16 + 1 0 0 32 + 1 0 1 64 + 1 1 0 128 + 1 1 1 256 + Wait the specified 50 PCI cycles after a reset by initializing + Tx and Rx queues and the address filter list. */ +#if defined(__powerpc__) +// 89/9/1 modify, +// np->bcrvalue=0x04 | 0x0x38; /* big-endian, 256 burst length */ + np->bcrvalue = 0x04 | 0x0 x10; /* big-endian, tx 8 burst length */ + a np->cralue = 0xe00; /* rx 128 burst length */ +#elif defined(__alpha__) +// 89/9/1 modify, +// np->bcrvalue=0x38; /* little-endian, 256 burst length */ + np->bcrvalue = 0x10; /* little-endian, 8 burst length */ + np->cralue = 0xe00; /* rx 128 burst length */ +#elif defined(__i386__) +#if defined(MODULE) +// 89/9/1 modify, +// np->bcrvalue=0x38; /* little-endian, 256 burst length */ + np->bcrvalue = 0x10; /* little-endian, 8 burst length */ + np->crvalue = 0xe00; /* rx 128 burst length */ +#else + /* When not a module we can work around broken '486 PCI boards. */ +#define x86 boot_cpu_data.x86 +// 89/9/1 modify, +// np->bcrvalue=(x86 <= 4 ? 0x10 : 0x38); + np->bcrvalue = 0x10; + np->crvalue = (x86 <= 4 ? 0xa00 : 0xe00); + if (x86 <= 4) + printk(KERN_INFO "%s: This is a 386/486 PCI system, setting burst " + "length to %x.\n", dev->name, (x86 <= 4 ? 0x10 : 0x38)); +#endif +#else +// 89/9/1 modify, +// np->bcrvalue=0x38; + np->bcrvalue = 0x10; + np->cralue = 0xe00; /* rx 128 burst length */ +#warning Processor architecture undefined! +#endif +// 89/12/29 add, +// 90/1/16 modify, +// np->imrvalue=FBE|TUNF|CNTOVF|RBU|TI|RI; + np->imrvalue = TUNF | CNTOVF | RBU | TI | RI; + if (np->pci_dev->device == 0x891) { + np->bcrvalue |= 0x200; /* set PROG bit */ + np->crvalue |= 0x02000000; /* set enhanced bit */ + np->imrvalue |= ETI; + } + writel(np->bcrvalue, ioaddr + BCR); + + if (dev->if_port == 0) + dev->if_port = np->default_port; + + writel(0, dev->base_addr + RXPDR); +// 89/9/1 modify, +// np->crvalue = 0x00e40001; /* tx store and forward, tx/rx enable */ + np->crvalue |= 0x00e40001; /* tx store and forward, tx/rx enable */ + np->full_duplex = np->duplex_lock; + getlinkstatus(dev); + if (np->linkok) + getlinktype(dev); + set_rx_mode(dev); + + netif_start_queue(dev); + + /* Clear and Enable interrupts by setting the interrupt mask. */ + writel(FBE | TUNF | CNTOVF | RBU | TI | RI, ioaddr + ISR); + writel(np->imrvalue, ioaddr + IMR); + + if (debug) + printk(KERN_DEBUG "%s: Done netdev_open().\n", dev->name); + + /* Set the timer to check for link beat. */ + init_timer(&np->timer); + np->timer.expires = RUN_AT(3 * HZ); + np->timer.data = (unsigned long) dev; + np->timer.function = &netdev_timer; + + /* timer handler */ + add_timer(&np->timer); + + return 0; +} + + +static void getlinkstatus(struct net_device *dev) +/* function: Routine will read MII Status Register to get link status. */ +/* input : dev... pointer to the adapter block. */ +/* output : none. */ +{ + struct netdev_private *np = dev->priv; + unsigned int i, DelayTime = 0x1000; + + np->linkok = 0; + + if (np->PHYType == MysonPHY) { + for (i = 0; i < DelayTime; ++i) { + if (readl(dev->base_addr + BMCRSR) & LinkIsUp2) { + np->linkok = 1; + return; + } + // delay + m80x_delay(100); + } + } else { + for (i = 0; i < DelayTime; ++i) { + if (mdio_read(dev, np->phys[0], 1) & 0x4) { + np->linkok = 1; + return; + } + // delay + m80x_delay(100); + } + } +} + + +static void getlinktype(struct net_device *dev) +{ + struct netdev_private *np = dev->priv; + + if (np->PHYType == MysonPHY) { /* 3-in-1 case */ + if (readl(dev->base_addr + TCRRCR) & FD) + np->duplexmode = 2; /* full duplex */ + else + np->duplexmode = 1; /* half duplex */ + if (readl(dev->base_addr + TCRRCR) & PS10) + np->line_speed = 1; /* 10M */ + else + np->line_speed = 2; /* 100M */ + } else { + if (np->PHYType == SeeqPHY) { /* this PHY is SEEQ 80225 */ + unsigned int data; + + data = mdio_read(dev, np->phys[0], MIIRegister18); + if (data & SPD_DET_100) + np->line_speed = 2; /* 100M */ + else + np->line_speed = 1; /* 10M */ + if (data & DPLX_DET_FULL) + np->duplexmode = 2; /* full duplex mode */ + else + np->duplexmode = 1; /* half duplex mode */ + } else if (np->PHYType == AhdocPHY) { + unsigned int data; + + data = mdio_read(dev, np->phys[0], DiagnosticReg); + if (data & Speed_100) + np->line_speed = 2; /* 100M */ + else + np->line_speed = 1; /* 10M */ + if (data & DPLX_FULL) + np->duplexmode = 2; /* full duplex mode */ + else + np->duplexmode = 1; /* half duplex mode */ + } +/* 89/6/13 add, (begin) */ + else if (np->PHYType == MarvellPHY) { + unsigned int data; + + data = mdio_read(dev, np->phys[0], SpecificReg); + if (data & Full_Duplex) + np->duplexmode = 2; /* full duplex mode */ + else + np->duplexmode = 1; /* half duplex mode */ + data &= SpeedMask; + if (data == Speed_1000M) + np->line_speed = 3; /* 1000M */ + else if (data == Speed_100M) + np->line_speed = 2; /* 100M */ + else + np->line_speed = 1; /* 10M */ + } +/* 89/6/13 add, (end) */ +/* 89/7/27 add, (begin) */ + else if (np->PHYType == Myson981) { + unsigned int data; + + data = mdio_read(dev, np->phys[0], StatusRegister); + + if (data & SPEED100) + np->line_speed = 2; + else + np->line_speed = 1; + + if (data & FULLMODE) + np->duplexmode = 2; + else + np->duplexmode = 1; + } +/* 89/7/27 add, (end) */ +/* 89/12/29 add */ + else if (np->PHYType == LevelOnePHY) { + unsigned int data; + + data = mdio_read(dev, np->phys[0], SpecificReg); + if (data & LXT1000_Full) + np->duplexmode = 2; /* full duplex mode */ + else + np->duplexmode = 1; /* half duplex mode */ + data &= SpeedMask; + if (data == LXT1000_1000M) + np->line_speed = 3; /* 1000M */ + else if (data == LXT1000_100M) + np->line_speed = 2; /* 100M */ + else + np->line_speed = 1; /* 10M */ + } + // chage crvalue + // np->crvalue&=(~PS10)&(~FD); + np->crvalue &= (~PS10) & (~FD) & (~PS1000); + if (np->line_speed == 1) + np->crvalue |= PS10; + else if (np->line_speed == 3) + np->crvalue |= PS1000; + if (np->duplexmode == 2) + np->crvalue |= FD; + } +} + + +static void allocate_rx_buffers(struct net_device *dev) +{ + struct netdev_private *np = dev->priv; + + /* allocate skb for rx buffers */ + while (np->really_rx_count != RX_RING_SIZE) { + struct sk_buff *skb; + + skb = dev_alloc_skb(np->rx_buf_sz); + np->lack_rxbuf->skbuff = skb; + + if (skb == NULL) + break; /* Better luck next round. */ + + skb->dev = dev; /* Mark as being used by this device. */ + np->lack_rxbuf->buffer = virt_to_bus(skb->tail); + np->lack_rxbuf = np->lack_rxbuf->next_desc_logical; + ++np->really_rx_count; + } +} + + +static void netdev_timer(unsigned long data) +{ + struct net_device *dev = (struct net_device *) data; + struct netdev_private *np = dev->priv; + long ioaddr = dev->base_addr; + int next_tick = 10 * HZ; + int old_crvalue = np->crvalue; + unsigned int old_linkok = np->linkok; + + if (debug) + printk(KERN_DEBUG "%s: Media selection timer tick, status %8.8x " + "config %8.8x.\n", dev->name, readl(ioaddr + ISR), + readl(ioaddr + TCRRCR)); + + if (np->flags == HAS_MII_XCVR) { + getlinkstatus(dev); + if ((old_linkok == 0) && (np->linkok == 1)) { /* we need to detect the media type again */ + getlinktype(dev); + if (np->crvalue != old_crvalue) { + stop_nic_tx(ioaddr, np->crvalue); + stop_nic_rx(ioaddr, np->crvalue & (~0x40000)); + writel(np->crvalue, ioaddr + TCRRCR); + } + } + } + + allocate_rx_buffers(dev); + + np->timer.expires = RUN_AT(next_tick); + add_timer(&np->timer); +} + + +static void tx_timeout(struct net_device *dev) +{ + struct netdev_private *np = dev->priv; + long ioaddr = dev->base_addr; + + printk(KERN_WARNING "%s: Transmit timed out, status %8.8x," + " resetting...\n", dev->name, readl(ioaddr + ISR)); + +#ifndef __alpha__ + { + int i; + + printk(KERN_DEBUG " Rx ring %8.8x: ", (int) np->rx_ring); + for (i = 0; i < RX_RING_SIZE; i++) + printk(" %8.8x", (unsigned int) np->rx_ring[i].status); + printk("\n" KERN_DEBUG " Tx ring %8.8x: ", (int) np->tx_ring); + for (i = 0; i < TX_RING_SIZE; i++) + printk(" %4.4x", np->tx_ring[i].status); + printk("\n"); + } +#endif + + /* Perhaps we should reinitialize the hardware here. Just trigger a + Tx demand for now. */ + writel(0, dev->base_addr + TXPDR); + dev->if_port = 0; + + /* Stop and restart the chip's Tx processes . */ + dev->trans_start = jiffies; + np->stats.tx_errors++; + + return; +} + + +/* Initialize the Rx and Tx rings, along with various 'dev' bits. */ +static void init_ring(struct net_device *dev) +{ + struct netdev_private *np = dev->priv; + int i; + + /* initialize rx variables */ + np->rx_buf_sz = (dev->mtu <= 1500 ? PKT_BUF_SZ : dev->mtu + 32); + np->cur_rx = &np->rx_ring[0]; + np->lack_rxbuf = NULL; + np->really_rx_count = 0; + + /* initial rx descriptors. */ + for (i = 0; i < RX_RING_SIZE; i++) { + np->rx_ring[i].status = 0; + np->rx_ring[i].control = np->rx_buf_sz << RBSShift; + np->rx_ring[i].next_desc = virt_to_bus(&np->rx_ring[i + 1]); + np->rx_ring[i].next_desc_logical = &np->rx_ring[i + 1]; + np->rx_ring[i].skbuff = NULL; + } + + /* for the last rx descriptor */ + np->rx_ring[i - 1].next_desc = virt_to_bus(&np->rx_ring[0]); + np->rx_ring[i - 1].next_desc_logical = &np->rx_ring[0]; + + /* allocate skb for rx buffers */ + for (i = 0; i < RX_RING_SIZE; i++) { + struct sk_buff *skb = dev_alloc_skb(np->rx_buf_sz); + + if (skb == NULL) { + np->lack_rxbuf = &np->rx_ring[i]; + break; + } + + ++np->really_rx_count; + np->rx_ring[i].skbuff = skb; + skb->dev = dev; /* Mark as being used by this device. */ + np->rx_ring[i].buffer = virt_to_bus(skb->tail); + np->rx_ring[i].status = RXOWN; + np->rx_ring[i].control |= RXIC; + } + + /* initialize tx variables */ + np->cur_tx = &np->tx_ring[0]; + np->cur_tx_copy = &np->tx_ring[0]; + np->really_tx_count = 0; + np->free_tx_count = TX_RING_SIZE; + + for (i = 0; i < TX_RING_SIZE; i++) { + np->tx_ring[i].status = 0; + np->tx_ring[i].next_desc = virt_to_bus(&np->tx_ring[i + 1]); + np->tx_ring[i].next_desc_logical = &np->tx_ring[i + 1]; + np->tx_ring[i].skbuff = NULL; + } + + /* for the last tx descriptor */ + np->tx_ring[i - 1].next_desc = virt_to_bus(&np->tx_ring[0]); + np->tx_ring[i - 1].next_desc_logical = &np->tx_ring[0]; + + return; +} + + +static int start_tx(struct sk_buff *skb, struct net_device *dev) +{ + struct netdev_private *np = dev->priv; + + np->cur_tx_copy->skbuff = skb; + np->cur_tx_copy->buffer = virt_to_bus(skb->data); + +#define one_buffer +#define BPT 1022 +#if defined(one_buffer) + np->cur_tx_copy->control = TXIC | TXLD | TXFD | CRCEnable | PADEnable; + np->cur_tx_copy->control |= (skb->len << PKTSShift); /* pkt size */ + np->cur_tx_copy->control |= (skb->len << TBSShift); /* buffer size */ +// 89/12/29 add, + if (np->pci_dev->device == 0x891) + np->cur_tx_copy->control |= ETIControl | RetryTxLC; + np->cur_tx_copy->status = TXOWN; + np->cur_tx_copy = np->cur_tx_copy->next_desc_logical; + --np->free_tx_count; +#elif defined(two_buffer) + if (skb->len > BPT) { + struct fealnx_desc *next; + + /* for the first descriptor */ + np->cur_tx_copy->control = TXIC | TXFD | CRCEnable | PADEnable; + np->cur_tx_copy->control |= (skb->len << PKTSShift); /* pkt size */ + np->cur_tx_copy->control |= (BPT << TBSShift); /* buffer size */ + + /* for the last descriptor */ + next = (struct fealnx *) np->cur_tx_copy.next_desc_logical; + next->skbuff = skb; + next->control = TXIC | TXLD | CRCEnable | PADEnable; + next->control |= (skb->len << PKTSShift); /* pkt size */ + next->control |= ((skb->len - BPT) << TBSShift); /* buf size */ +// 89/12/29 add, + if (np->pci_dev->device == 0x891) + np->cur_tx_copy->control |= ETIControl | RetryTxLC; + next->buffer = virt_to_bus(skb->data) + BPT; + + next->status = TXOWN; + np->cur_tx_copy->status = TXOWN; + + np->cur_tx_copy = next->next_desc_logical; + np->free_tx_count -= 2; + } else { + np->cur_tx_copy->control = TXIC | TXLD | TXFD | CRCEnable | PADEnable; + np->cur_tx_copy->control |= (skb->len << PKTSShift); /* pkt size */ + np->cur_tx_copy->control |= (skb->len << TBSShift); /* buffer size */ +// 89/12/29 add, + if (np->pci_dev->device == 0x891) + np->cur_tx_copy->control |= ETIControl | RetryTxLC; + np->cur_tx_copy->status = TXOWN; + np->cur_tx_copy = np->cur_tx_copy->next_desc_logical; + --np->free_tx_count; + } +#endif + + if (np->free_tx_count < 2) + netif_stop_queue(dev); + ++np->really_tx_count; + writel(0, dev->base_addr + TXPDR); + dev->trans_start = jiffies; + + return 0; +} + + +void free_one_rx_descriptor(struct netdev_private *np) +{ + if (np->really_rx_count == RX_RING_SIZE) + np->cur_rx->status = RXOWN; + else { + np->lack_rxbuf->skbuff = np->cur_rx->skbuff; + np->lack_rxbuf->buffer = np->cur_rx->buffer; + np->lack_rxbuf->status = RXOWN; + ++np->really_rx_count; + np->lack_rxbuf = np->lack_rxbuf->next_desc_logical; + } + np->cur_rx = np->cur_rx->next_desc_logical; +} + + +void reset_rx_descriptors(struct net_device *dev) +{ + struct netdev_private *np = dev->priv; + + stop_nic_rx(dev->base_addr, np->crvalue); + + while (!(np->cur_rx->status & RXOWN)) + free_one_rx_descriptor(np); + + allocate_rx_buffers(dev); + + writel(virt_to_bus(np->cur_rx), dev->base_addr + RXLBA); + writel(np->crvalue, dev->base_addr + TCRRCR); +} + + +/* The interrupt handler does all of the Rx thread work and cleans up + after the Tx thread. */ +static void intr_handler(int irq, void *dev_instance, struct pt_regs *rgs) +{ + struct net_device *dev = (struct net_device *) dev_instance; + struct netdev_private *np = dev->priv; + long ioaddr, boguscnt = max_interrupt_work; + unsigned int num_tx = 0; + + writel(0, dev->base_addr + IMR); + + ioaddr = dev->base_addr; + np = (struct netdev_private *) dev->priv; + + do { + u32 intr_status = readl(ioaddr + ISR); + + /* Acknowledge all of the current interrupt sources ASAP. */ + writel(intr_status, ioaddr + ISR); + + if (debug) + printk(KERN_DEBUG "%s: Interrupt, status %4.4x.\n", dev->name, + intr_status); + + if (!(intr_status & np->imrvalue)) + break; + +// 90/1/16 delete, +// +// if (intr_status & FBE) +// { /* fatal error */ +// stop_nic_tx(ioaddr, 0); +// stop_nic_rx(ioaddr, 0); +// break; +// }; + + if (intr_status & TUNF) + writel(0, ioaddr + TXPDR); + + if (intr_status & CNTOVF) { + /* missed pkts */ + np->stats.rx_missed_errors += readl(ioaddr + TALLY) & 0x7fff; + + /* crc error */ + np->stats.rx_crc_errors += + (readl(ioaddr + TALLY) & 0x7fff0000) >> 16; + } + + if (intr_status & (RI | RBU)) { + if (intr_status & RI) + netdev_rx(dev); + else + reset_rx_descriptors(dev); + } + + while (np->really_tx_count) { + long tx_status = np->cur_tx->status; + long tx_control = np->cur_tx->control; + + if (!(tx_control & TXLD)) { /* this pkt is combined by two tx descriptors */ + struct fealnx_desc *next; + + next = np->cur_tx->next_desc_logical; + tx_status = next->status; + tx_control = next->control; + } + + if (tx_status & TXOWN) + break; + + if (!(np->crvalue & 0x02000000)) { + if (tx_status & (CSL | LC | EC | UDF | HF)) { + np->stats.tx_errors++; + if (tx_status & EC) + np->stats.tx_aborted_errors++; + if (tx_status & CSL) + np->stats.tx_carrier_errors++; + if (tx_status & LC) + np->stats.tx_window_errors++; + if (tx_status & UDF) + np->stats.tx_fifo_errors++; + if ((tx_status & HF) && np->full_duplex == 0) + np->stats.tx_heartbeat_errors++; + +#ifdef ETHER_STATS + if (tx_status & EC) + np->stats.collisions16++; +#endif + } else { +#ifdef ETHER_STATS + if (tx_status & DFR) + np->stats.tx_deferred++; +#endif + + np->stats.tx_bytes += + ((tx_control & PKTSMask) >> PKTSShift); + + np->stats.collisions += + ((tx_status & NCRMask) >> NCRShift); + np->stats.tx_packets++; + } + } else { + np->stats.tx_bytes += + ((tx_control & PKTSMask) >> PKTSShift); + np->stats.tx_packets++; + } + + /* Free the original skb. */ + dev_kfree_skb_irq(np->cur_tx->skbuff); + np->cur_tx->skbuff = NULL; + --np->really_tx_count; + if (np->cur_tx->control & TXLD) { + np->cur_tx = np->cur_tx->next_desc_logical; + ++np->free_tx_count; + } else { + np->cur_tx = np->cur_tx->next_desc_logical; + np->cur_tx = np->cur_tx->next_desc_logical; + np->free_tx_count += 2; + } + num_tx++; + } /* end of for loop */ + + if (num_tx && np->free_tx_count >= 2) + netif_wake_queue(dev); + + /* read transmit status for enhanced mode only */ + if (np->crvalue & 0x02000000) { + long data; + + data = readl(ioaddr + TSR); + np->stats.tx_errors += (data & 0xff000000) >> 24; + np->stats.tx_aborted_errors += (data & 0xff000000) >> 24; + np->stats.tx_window_errors += (data & 0x00ff0000) >> 16; +#ifdef ETHER_STATS + np->stats.collisions16 += (data & 0xff000000) >> 24; +#endif + np->stats.collisions += (data & 0x0000ffff); + } + + if (--boguscnt < 0) { + printk(KERN_WARNING "%s: Too much work at interrupt, " + "status=0x%4.4x.\n", dev->name, intr_status); + break; + } + } while (1); + + /* read the tally counters */ + /* missed pkts */ + np->stats.rx_missed_errors += readl(ioaddr + TALLY) & 0x7fff; + + /* crc error */ + np->stats.rx_crc_errors += (readl(ioaddr + TALLY) & 0x7fff0000) >> 16; + + if (debug) + printk(KERN_DEBUG "%s: exiting interrupt, status=%#4.4x.\n", + dev->name, readl(ioaddr + ISR)); + + writel(np->imrvalue, ioaddr + IMR); + + return; +} + + +/* This routine is logically part of the interrupt handler, but seperated + for clarity and better register allocation. */ +static int netdev_rx(struct net_device *dev) +{ + struct netdev_private *np = dev->priv; + + /* If EOP is set on the next entry, it's a new packet. Send it up. */ + while (!(np->cur_rx->status & RXOWN)) { + s32 rx_status = np->cur_rx->status; + + if (np->really_rx_count == 0) + break; + + if (debug) + printk(KERN_DEBUG " netdev_rx() status was %8.8x.\n", rx_status); + + if ((!((rx_status & RXFSD) && (rx_status & RXLSD))) + || (rx_status & ErrorSummary)) { + if (rx_status & ErrorSummary) { /* there was a fatal error */ + if (debug) + printk(KERN_DEBUG + "%s: Receive error, Rx status %8.8x.\n", + dev->name, rx_status); + + np->stats.rx_errors++; /* end of a packet. */ + if (rx_status & (LONG | RUNT)) + np->stats.rx_length_errors++; + if (rx_status & RXER) + np->stats.rx_frame_errors++; + if (rx_status & CRC) + np->stats.rx_crc_errors++; + } else { + int need_to_reset = 0; + int desno = 0; + + if (rx_status & RXFSD) { /* this pkt is too long, over one rx buffer */ + struct fealnx_desc *cur; + + /* check this packet is received completely? */ + cur = np->cur_rx; + while (desno <= np->really_rx_count) { + ++desno; + if ((!(cur->status & RXOWN)) + && (cur->status & RXLSD)) + break; + /* goto next rx descriptor */ + cur = cur->next_desc_logical; + } + if (desno > np->really_rx_count) + need_to_reset = 1; + } else /* RXLSD did not find, something error */ + need_to_reset = 1; + + if (need_to_reset == 0) { + int i; + + np->stats.rx_length_errors++; + + /* free all rx descriptors related this long pkt */ + for (i = 0; i < desno; ++i) + free_one_rx_descriptor(np); + continue; + } else { /* something error, need to reset this chip */ + reset_rx_descriptors(dev); + } + break; /* exit the while loop */ + } + } else { /* this received pkt is ok */ + + struct sk_buff *skb; + /* Omit the four octet CRC from the length. */ + short pkt_len = ((rx_status & FLNGMASK) >> FLNGShift) - 4; + +#ifndef final_version + if (debug) + printk(KERN_DEBUG " netdev_rx() normal Rx pkt length %d" + " status %x.\n", pkt_len, rx_status); +#endif + + /* Check if the packet is long enough to accept without copying + to a minimally-sized skbuff. */ + if (pkt_len < rx_copybreak && + (skb = dev_alloc_skb(pkt_len + 2)) != NULL) { + skb->dev = dev; + skb_reserve(skb, 2); /* 16 byte align the IP header */ + /* Call copy + cksum if available. */ + +#if ! defined(__alpha__) + eth_copy_and_sum(skb, bus_to_virt(np->cur_rx->buffer), + pkt_len, 0); + skb_put(skb, pkt_len); +#else + memcpy(skb_put(skb, pkt_len), + bus_to_virt(np->cur_rx->buffer), pkt_len); +#endif + } else { + skb_put(skb = np->cur_rx->skbuff, pkt_len); + np->cur_rx->skbuff = NULL; + if (np->really_rx_count == RX_RING_SIZE) + np->lack_rxbuf = np->cur_rx; + --np->really_rx_count; + } + skb->protocol = eth_type_trans(skb, dev); + netif_rx(skb); + dev->last_rx = jiffies; + np->stats.rx_packets++; + np->stats.rx_bytes += pkt_len; + } + + if (np->cur_rx->skbuff == NULL) { + struct sk_buff *skb; + + skb = dev_alloc_skb(np->rx_buf_sz); + + if (skb != NULL) { + skb->dev = dev; /* Mark as being used by this device. */ + np->cur_rx->buffer = virt_to_bus(skb->tail); + np->cur_rx->skbuff = skb; + ++np->really_rx_count; + } + } + + if (np->cur_rx->skbuff != NULL) + free_one_rx_descriptor(np); + } /* end of while loop */ + + /* allocate skb for rx buffers */ + allocate_rx_buffers(dev); + + return 0; +} + + +static struct net_device_stats *get_stats(struct net_device *dev) +{ + long ioaddr = dev->base_addr; + struct netdev_private *np = dev->priv; + + /* The chip only need report frame silently dropped. */ + if (netif_running(dev)) { + np->stats.rx_missed_errors += readl(ioaddr + TALLY) & 0x7fff; + np->stats.rx_crc_errors += (readl(ioaddr + TALLY) & 0x7fff0000) >> 16; + } + + return &np->stats; +} + + +static unsigned const ethernet_polynomial = 0x04c11db7U; +static inline u32 ether_crc(int length, unsigned char *data) +{ + int crc = -1; + + while (--length >= 0) { + unsigned char current_octet = *data++; + int bit; + + for (bit = 0; bit < 8; bit++, current_octet >>= 1) { + crc = (crc << 1) ^ + ((crc < 0) ^ (current_octet & 1) ? ethernet_polynomial : 0); + } + } + + return crc; +} + + +static void set_rx_mode(struct net_device *dev) +{ + struct netdev_private *np = dev->priv; + long ioaddr = dev->base_addr; + u32 mc_filter[2]; /* Multicast hash filter */ + u32 rx_mode; + + if (dev->flags & IFF_PROMISC) { /* Set promiscuous. */ + /* Unconditionally log net taps. */ + printk(KERN_NOTICE "%s: Promiscuous mode enabled.\n", dev->name); + memset(mc_filter, 0xff, sizeof(mc_filter)); + rx_mode = PROM | AB | AM; + } else if ((dev->mc_count > multicast_filter_limit) + || (dev->flags & IFF_ALLMULTI)) { + /* Too many to match, or accept all multicasts. */ + memset(mc_filter, 0xff, sizeof(mc_filter)); + rx_mode = AB | AM; + } else { + struct dev_mc_list *mclist; + int i; + + memset(mc_filter, 0, sizeof(mc_filter)); + for (i = 0, mclist = dev->mc_list; mclist && i < dev->mc_count; + i++, mclist = mclist->next) { + set_bit((ether_crc(ETH_ALEN, mclist->dmi_addr) >> 26) ^ 0x3F, + mc_filter); + } + rx_mode = AB | AM; + } + + stop_nic_tx(ioaddr, np->crvalue); + stop_nic_rx(ioaddr, np->crvalue & (~0x40000)); + + writel(mc_filter[0], ioaddr + MAR0); + writel(mc_filter[1], ioaddr + MAR1); + np->crvalue &= ~RxModeMask; + np->crvalue |= rx_mode; + writel(np->crvalue, ioaddr + TCRRCR); +} + + +static int mii_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) +{ + u16 *data = (u16 *) & rq->ifr_data; + + switch (cmd) { + case SIOCDEVPRIVATE: /* Get the address of the PHY in use. */ + data[0] = ((struct netdev_private *) dev->priv)->phys[0] & 0x1f; + /* Fall Through */ + case SIOCDEVPRIVATE + 1: /* Read the specified MII register. */ + data[3] = mdio_read(dev, data[0] & 0x1f, data[1] & 0x1f); + return 0; + case SIOCDEVPRIVATE + 2: /* Write the specified MII register */ + if (!suser()) + return -EPERM; + mdio_write(dev, data[0] & 0x1f, data[1] & 0x1f, data[2]); + return 0; + default: + return -EOPNOTSUPP; + } +} + + +static int netdev_close(struct net_device *dev) +{ + long ioaddr = dev->base_addr; + struct netdev_private *np = dev->priv; + int i; + + netif_stop_queue(dev); + + /* Disable interrupts by clearing the interrupt mask. */ + writel(0x0000, ioaddr + IMR); + + /* Stop the chip's Tx and Rx processes. */ + stop_nic_tx(ioaddr, 0); + stop_nic_rx(ioaddr, 0); + + del_timer_sync(&np->timer); + + free_irq(dev->irq, dev); + + /* Free all the skbuffs in the Rx queue. */ + for (i = 0; i < RX_RING_SIZE; i++) { + np->rx_ring[i].status = 0; + if (np->rx_ring[i].skbuff) + dev_kfree_skb(np->rx_ring[i].skbuff); + np->rx_ring[i].skbuff = NULL; + } + + for (i = 0; i < TX_RING_SIZE; i++) { + if (np->tx_ring[i].skbuff) + dev_kfree_skb(np->tx_ring[i].skbuff); + np->tx_ring[i].skbuff = NULL; + } + + return 0; +} + +static struct pci_device_id fealnx_pci_tbl[] = __devinitdata { + {0x1516, 0x0800, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, + {0x1516, 0x0803, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 1}, + {0x1516, 0x0891, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 2}, + {} /* terminate list */ +}; +MODULE_DEVICE_TABLE(pci, fealnx_pci_tbl); + + +static struct pci_driver fealnx_driver = { + name: "fealnx", + id_table: fealnx_pci_tbl, + probe: fealnx_init_one, + remove: fealnx_remove_one, +}; + +static int __init fealnx_init(void) +{ +/* when a module, this is printed whether or not devices are found in probe */ +#ifdef MODULE + printk (version); +#endif + + return pci_module_init(&fealnx_driver); +} + +static void __exit fealnx_exit(void) +{ + pci_unregister_driver(&fealnx_driver); +} + +module_init(fealnx_init); +module_exit(fealnx_exit); diff --git a/drivers/net/gmac.c b/drivers/net/gmac.c index e5086e993c7e..9f9a6b9f1e25 100644 --- a/drivers/net/gmac.c +++ b/drivers/net/gmac.c @@ -9,7 +9,7 @@ * Changes: * Arnaldo Carvalho de Melo - 08/06/2000 * - check init_etherdev return in gmac_probe1 - * BenH - 03/09/2000 + * BenH - 03/09/2000 * - Add support for new PHYs * - Add some PowerBook sleep code * @@ -47,10 +47,11 @@ #define DEBUG_PHY /* Driver version 1.3, kernel 2.4.x */ -#define GMAC_VERSION "v1.3k4" +#define GMAC_VERSION "v1.4k4" -static unsigned char dummy_buf[RX_BUF_ALLOC_SIZE + RX_OFFSET + GMAC_BUFFER_ALIGN]; -static struct net_device *gmacs = NULL; +#define DUMMY_BUF_LEN RX_BUF_ALLOC_SIZE + RX_OFFSET + GMAC_BUFFER_ALIGN +static unsigned char *dummy_buf; +static struct net_device *gmacs; /* Prototypes */ static int mii_read(struct gmac *gm, int phy, int r); @@ -62,6 +63,7 @@ static int mii_lookup_and_reset(struct gmac *gm); static void mii_setup_phy(struct gmac *gm); static int mii_do_reset_phy(struct gmac *gm, int phy_addr); static void mii_init_BCM5400(struct gmac *gm); +static void mii_init_BCM5401(struct gmac *gm); static void gmac_set_power(struct gmac *gm, int power_up); static int gmac_powerup_and_reset(struct net_device *dev); @@ -211,10 +213,12 @@ mii_interrupt(struct gmac *gm) int link_100 = 0; int gigabit = 0; #ifdef DEBUG_PHY - printk("Link state change, phy_status: 0x%04x\n", phy_status); + printk("%s: Link state change, phy_status: 0x%04x\n", + gm->dev->name, phy_status); #endif gm->phy_status = phy_status; + /* Should we enable that in generic mode ? */ lpar_ability = mii_read(gm, gm->phy_addr, MII_ANLPA); if (lpar_ability & MII_ANLPA_PAUS) GM_BIS(GM_MAC_CTRL_CONFIG, GM_MAC_CTRL_CONF_SND_PAUSE_EN); @@ -249,6 +253,9 @@ mii_interrupt(struct gmac *gm) #endif full_duplex = ((stat2 & MII_LXT971_STATUS2_FULLDUPLEX) != 0); link_100 = ((stat2 & MII_LXT971_STATUS2_SPEED) != 0); + } else { + full_duplex = (lpar_ability & MII_ANLPA_FDAM) != 0; + link_100 = (lpar_ability & MII_ANLPA_100M) != 0; } #ifdef DEBUG_PHY printk(" full_duplex: %d, speed: %s\n", full_duplex, @@ -274,6 +281,144 @@ mii_interrupt(struct gmac *gm) } } +/* Power management: stop PHY chip for suspend mode + */ +static void +gmac_suspend(struct gmac* gm) +{ + int data, timeout; + unsigned long flags; + + gm->sleeping = 1; + netif_stop_queue(gm->dev); + + + spin_lock_irqsave(&gm->lock, flags); + if (gm->opened) { + disable_irq(gm->dev->irq); + /* Stop polling PHY */ + mii_poll_stop(gm); + } + /* Mask out all chips interrupts */ + GM_OUT(GM_IRQ_MASK, 0xffffffff); + spin_unlock_irqrestore(&gm->lock, flags); + + if (gm->opened) { + int i; + /* Empty Tx ring of any remaining gremlins */ + gmac_tx_cleanup(gm->dev, 1); + + /* Empty Rx ring of any remaining gremlins */ + for (i = 0; i < NRX; ++i) { + if (gm->rx_buff[i] != 0) { + dev_kfree_skb_irq(gm->rx_buff[i]); + gm->rx_buff[i] = 0; + } + } + } + + /* Clear interrupts on 5201 */ + if (gm->phy_type == PHY_B5201) + mii_write(gm, gm->phy_addr, MII_BCM5201_INTERRUPT, 0); + + /* Drive MDIO high */ + GM_OUT(GM_MIF_CFG, 0); + + /* Unchanged, don't ask me why */ + data = mii_read(gm, gm->phy_addr, MII_ANLPA); + mii_write(gm, gm->phy_addr, MII_ANLPA, data); + + /* Put MDIO in sane state */ + GM_OUT(GM_MIF_CFG, GM_MIF_CFGBB); + GM_OUT(GM_MIF_BB_CLOCK, 0); + GM_OUT(GM_MIF_BB_DATA, 0); + GM_OUT(GM_MIF_BB_OUT_ENABLE, 0); + + /* Stop everything */ + GM_OUT(GM_MAC_RX_CONFIG, 0); + GM_OUT(GM_MAC_TX_CONFIG, 0); + GM_OUT(GM_MAC_XIF_CONFIG, 0); + GM_OUT(GM_TX_CONF, 0); + GM_OUT(GM_RX_CONF, 0); + + /* Set reset state */ + GM_OUT(GM_RESET, GM_RESET_TX | GM_RESET_RX); + for (timeout = 100; timeout > 0; --timeout) { + mdelay(10); + if ((GM_IN(GM_RESET) & (GM_RESET_TX | GM_RESET_RX)) == 0) + break; + } + GM_OUT(GM_MAC_TX_RESET, GM_MAC_TX_RESET_NOW); + GM_OUT(GM_MAC_RX_RESET, GM_MAC_RX_RESET_NOW); + + /* Superisolate PHY */ + if (gm->phy_type == PHY_B5201) + mii_write(gm, gm->phy_addr, MII_BCM5201_MULTIPHY, + MII_BCM5201_MULTIPHY_SUPERISOLATE); + + /* Unclock chip */ + gmac_set_power(gm, 0); +} + +static void +gmac_resume(struct gmac *gm) +{ + int data; + + if (gmac_powerup_and_reset(gm->dev)) { + printk(KERN_ERR "%s: Couldn't revive gmac ethernet !\n", gm->dev->name); + return; + } + + gm->sleeping = 0; + + if (gm->opened) { + /* Create fresh rings */ + gmac_init_rings(gm, 1); + /* re-initialize the MAC */ + gmac_mac_init(gm, gm->dev->dev_addr); + /* re-initialize the multicast tables & promisc mode if any */ + gmac_set_multicast(gm->dev); + } + + /* Early enable Tx and Rx so that we are clocked */ + GM_BIS(GM_TX_CONF, GM_TX_CONF_DMA_EN); + mdelay(20); + GM_BIS(GM_RX_CONF, GM_RX_CONF_DMA_EN); + mdelay(20); + GM_BIS(GM_MAC_TX_CONFIG, GM_MAC_TX_CONF_ENABLE); + mdelay(20); + GM_BIS(GM_MAC_RX_CONFIG, GM_MAC_RX_CONF_ENABLE); + mdelay(20); + if (gm->phy_type == PHY_B5201) { + data = mii_read(gm, gm->phy_addr, MII_BCM5201_MULTIPHY); + mii_write(gm, gm->phy_addr, MII_BCM5201_MULTIPHY, + data & ~MII_BCM5201_MULTIPHY_SUPERISOLATE); + } + mdelay(1); + + if (gm->opened) { + /* restart polling PHY */ + mii_interrupt(gm); + /* restart DMA operations */ + gmac_start_dma(gm); + netif_start_queue(gm->dev); + enable_irq(gm->dev->irq); + } else { + /* Driver not opened, just leave things off. Note that + * we could be smart and superisolate the PHY when the + * driver is closed, but I won't do that unless I have + * a better understanding of some electrical issues with + * this PHY chip --BenH + */ + GM_OUT(GM_MAC_RX_CONFIG, 0); + GM_OUT(GM_MAC_TX_CONFIG, 0); + GM_OUT(GM_MAC_XIF_CONFIG, 0); + GM_OUT(GM_TX_CONF, 0); + GM_OUT(GM_RX_CONF, 0); + } +} + static int mii_do_reset_phy(struct gmac *gm, int phy_addr) { @@ -326,6 +471,40 @@ mii_init_BCM5400(struct gmac *gm) mii_write(gm, gm->phy_addr, MII_BCM5400_AUXCONTROL, data); } +static void +mii_init_BCM5401(struct gmac *gm) +{ + int data; + int rev; + + rev = mii_read(gm, gm->phy_addr, MII_ID1) & 0x000f; + if (rev == 0 || rev == 3) { + /* A bit of black magic from Apple */ + mii_write(gm, gm->phy_addr, 0x18, 0x0c20); + mii_write(gm, gm->phy_addr, 0x17, 0x0012); + mii_write(gm, gm->phy_addr, 0x15, 0x1804); + mii_write(gm, gm->phy_addr, 0x17, 0x0013); + mii_write(gm, gm->phy_addr, 0x15, 0x1204); + mii_write(gm, gm->phy_addr, 0x17, 0x8006); + mii_write(gm, gm->phy_addr, 0x15, 0x0132); + mii_write(gm, gm->phy_addr, 0x17, 0x8006); + mii_write(gm, gm->phy_addr, 0x15, 0x0232); + mii_write(gm, gm->phy_addr, 0x17, 0x201f); + mii_write(gm, gm->phy_addr, 0x15, 0x0a20); + } + + data = mii_read(gm, gm->phy_addr, MII_BCM5400_GB_CONTROL); + data |= MII_BCM5400_GB_CONTROL_FULLDUPLEXCAP; + mii_write(gm, gm->phy_addr, MII_BCM5400_GB_CONTROL, data); + + mdelay(10); + mii_do_reset_phy(gm, 0x1f); + + data = mii_read(gm, 0x1f, MII_BCM5201_MULTIPHY); + data |= MII_BCM5201_MULTIPHY_SERIALMODE; + mii_write(gm, 0x1f, MII_BCM5201_MULTIPHY, data); +} + static int mii_lookup_and_reset(struct gmac *gm) { @@ -335,10 +514,7 @@ mii_lookup_and_reset(struct gmac *gm) gm->phy_type = PHY_UNKNOWN; /* Hard reset the PHY */ - feature_set_gmac_phy_reset(gm->of_node, KL_GPIO_ETH_PHY_RESET_ASSERT); - mdelay(10); - feature_set_gmac_phy_reset(gm->of_node, KL_GPIO_ETH_PHY_RESET_RELEASE); - mdelay(10); + feature_gmac_phy_reset(gm->of_node); /* Find the PHY */ for(i=0; i<=31; i++) { @@ -367,14 +543,22 @@ mii_lookup_and_reset(struct gmac *gm) printk(KERN_ERR "%s Found Broadcom BCM5400 PHY (Gigabit)\n", gm->dev->name); mii_init_BCM5400(gm); + } else if ((gm->phy_id & MII_BCM5401_MASK) == MII_BCM5401_ID) { + gm->phy_type = PHY_B5401; + printk(KERN_ERR "%s Found Broadcom BCM5401 PHY (Gigabit)\n", + gm->dev->name); + mii_init_BCM5401(gm); } else if ((gm->phy_id & MII_BCM5201_MASK) == MII_BCM5201_ID) { gm->phy_type = PHY_B5201; printk(KERN_INFO "%s Found Broadcom BCM5201 PHY\n", gm->dev->name); + } else if ((gm->phy_id & MII_BCM5221_MASK) == MII_BCM5221_ID) { + gm->phy_type = PHY_B5201; /* Same as 5201 for now */ + printk(KERN_INFO "%s Found Broadcom BCM5221 PHY\n", gm->dev->name); } else if ((gm->phy_id & MII_LXT971_MASK) == MII_LXT971_ID) { gm->phy_type = PHY_LXT971; printk(KERN_INFO "%s Found LevelOne LX971 PHY\n", gm->dev->name); } else { - printk(KERN_ERR "%s: Warning ! Unknown PHY ID 0x%08x !\n", + printk(KERN_ERR "%s: Warning ! Unknown PHY ID 0x%08x, using generic mode...\n", gm->dev->name, gm->phy_id); } @@ -448,8 +632,6 @@ gmac_set_power(struct gmac *gm, int power_up) PCI_CACHE_LINE_SIZE, 8); } } else { - /* FIXME: Add PHY power down */ - gm->phy_type = 0; feature_set_gmac_power(gm->of_node, 0); } } @@ -472,11 +654,14 @@ gmac_powerup_and_reset(struct net_device *dev) if ((GM_IN(GM_RESET) & (GM_RESET_TX | GM_RESET_RX)) == 0) { /* Mask out all chips interrupts */ GM_OUT(GM_IRQ_MASK, 0xffffffff); + GM_OUT(GM_MAC_TX_RESET, GM_MAC_TX_RESET_NOW); + GM_OUT(GM_MAC_RX_RESET, GM_MAC_RX_RESET_NOW); return 0; } } printk(KERN_ERR "%s reset failed!\n", dev->name); gmac_set_power(gm, 0); + gm->phy_type = 0; return -1; } @@ -747,7 +932,9 @@ gmac_set_multicast(struct net_device *dev) int multicast_hash = 0; int multicast_all = 0; int promisc = 0; - + + if (gm->sleeping) + return; /* Lock out others. */ netif_stop_queue(dev); @@ -881,6 +1068,7 @@ gmac_close(struct net_device *dev) /* Shut down chip */ gmac_set_power(gm, 0); + gm->phy_type = 0; /* Empty rings of any remaining gremlins */ for (i = 0; i < NRX; ++i) { @@ -904,7 +1092,6 @@ int gmac_sleep_notify(struct pmu_sleep_notifier *self, int when) { struct gmac *gm; - int i; /* XXX should handle more than one */ if (gmacs == NULL) @@ -920,38 +1107,10 @@ gmac_sleep_notify(struct pmu_sleep_notifier *self, int when) case PBOOK_SLEEP_REJECT: break; case PBOOK_SLEEP_NOW: - disable_irq(gm->dev->irq); - netif_stop_queue(gm->dev); - gmac_stop_dma(gm); - mii_poll_stop(gm); - gmac_set_power(gm, 0); - for (i = 0; i < NRX; ++i) { - if (gm->rx_buff[i] != 0) { - dev_kfree_skb(gm->rx_buff[i]); - gm->rx_buff[i] = 0; - } - } - for (i = 0; i < NTX; ++i) { - if (gm->tx_buff[i] != 0) { - dev_kfree_skb(gm->tx_buff[i]); - gm->tx_buff[i] = 0; - } - } + gmac_suspend(gm); break; case PBOOK_WAKE: - /* see if this is enough */ - gmac_powerup_and_reset(gm->dev); - gm->full_duplex = 0; - gm->phy_status = 0; - mii_lookup_and_reset(gm); - mii_setup_phy(gm); - gmac_init_rings(gm, 0); - gmac_mac_init(gm, gm->dev->dev_addr); - gmac_set_multicast(gm->dev); - mii_interrupt(gm); - gmac_start_dma(gm); - netif_start_queue(gm->dev); - enable_irq(gm->dev->irq); + gmac_resume(gm); break; } return PBOOK_SLEEP_OK; @@ -967,7 +1126,10 @@ gmac_tx_timeout(struct net_device *dev) struct gmac *gm = (struct gmac *) dev->priv; int i, timeout; unsigned long flags; - + + if (gm->sleeping) + return; + printk (KERN_ERR "%s: transmit timed out, resetting\n", dev->name); spin_lock_irqsave(&gm->lock, flags); @@ -990,6 +1152,8 @@ gmac_tx_timeout(struct net_device *dev) if ((GM_IN(GM_RESET) & (GM_RESET_TX | GM_RESET_RX)) == 0) { /* Mask out all chips interrupts */ GM_OUT(GM_IRQ_MASK, 0xffffffff); + GM_OUT(GM_MAC_TX_RESET, GM_MAC_TX_RESET_NOW); + GM_OUT(GM_MAC_RX_RESET, GM_MAC_RX_RESET_NOW); break; } } @@ -1022,6 +1186,9 @@ gmac_xmit_start(struct sk_buff *skb, struct net_device *dev) unsigned long flags; int i; + if (gm->sleeping) + return 1; + spin_lock_irqsave(&gm->lock, flags); i = gm->next_tx; @@ -1274,7 +1441,7 @@ gmac_stats(struct net_device *dev) struct gmac *gm = (struct gmac *) dev->priv; struct net_device_stats *stats = &gm->stats; - if (gm && gm->opened) { + if (gm && gm->opened && !gm->sleeping) { stats->rx_crc_errors += GM_IN(GM_MAC_RX_CRC_ERR_CTR); GM_OUT(GM_MAC_RX_CRC_ERR_CTR, 0); @@ -1315,10 +1482,14 @@ gmac_probe(void) gmac = gmac->next) gmac_probe1(gmac); +#ifdef CONFIG_PMAC_PBOOK + if (gmacs) + pmu_register_sleep_notifier(&gmac_sleep_notifier); +#endif MOD_DEC_USE_COUNT; - return 0; + return gmacs? 0: -ENODEV; } static void @@ -1343,6 +1514,14 @@ gmac_probe1(struct device_node *gmac) return; } + if (dummy_buf == NULL) { + dummy_buf = kmalloc(DUMMY_BUF_LEN, GFP_KERNEL); + if (dummy_buf == NULL) { + printk(KERN_ERR "GMAC: failed to allocated dummy buffer\n"); + return; + } + } + tx_descpage = get_free_page(GFP_KERNEL); if (tx_descpage == 0) { printk(KERN_ERR "GMAC: can't get a page for tx descriptors\n"); @@ -1351,17 +1530,13 @@ gmac_probe1(struct device_node *gmac) rx_descpage = get_free_page(GFP_KERNEL); if (rx_descpage == 0) { printk(KERN_ERR "GMAC: can't get a page for rx descriptors\n"); - free_page(tx_descpage); - return; + goto out_txdesc; } dev = init_etherdev(NULL, sizeof(struct gmac)); - if (!dev) { printk(KERN_ERR "GMAC: init_etherdev failed, out of memory\n"); - free_page(tx_descpage); - free_page(rx_descpage); - return; + goto out_rxdesc; } SET_MODULE_OWNER(dev); @@ -1369,6 +1544,10 @@ gmac_probe1(struct device_node *gmac) dev->base_addr = gmac->addrs[0].address; gm->regs = (volatile unsigned int *) ioremap(gmac->addrs[0].address, 0x10000); + if (!gm->regs) { + printk(KERN_ERR "GMAC: unable to map I/O registers\n"); + goto out_unreg; + } dev->irq = gmac->intrs[0].line; gm->dev = dev; gm->of_node = gmac; @@ -1394,6 +1573,7 @@ gmac_probe1(struct device_node *gmac) gm->phy_addr = 0; gm->opened = 0; + gm->sleeping = 0; dev->open = gmac_open; dev->stop = gmac_close; @@ -1404,13 +1584,18 @@ gmac_probe1(struct device_node *gmac) dev->watchdog_timeo = 5*HZ; ether_setup(dev); - + gm->next_gmac = gmacs; gmacs = dev; - -#ifdef CONFIG_PMAC_PBOOK - pmu_register_sleep_notifier(&gmac_sleep_notifier); -#endif + return; + +out_unreg: + unregister_netdev(dev); + kfree(dev); +out_rxdesc: + free_page(rx_descpage); +out_txdesc: + free_page(tx_descpage); } MODULE_AUTHOR("Paul Mackerras/Ben Herrenschmidt"); @@ -1421,16 +1606,25 @@ static void __exit gmac_cleanup_module(void) struct gmac *gm; struct net_device *dev; +#ifdef CONFIG_PMAC_PBOOK + if (gmacs) + pmu_unregister_sleep_notifier(&gmac_sleep_notifier); +#endif + while ((dev = gmacs) != NULL) { gm = (struct gmac *) dev->priv; unregister_netdev(dev); + iounmap((void *) gm->regs); free_page(gm->tx_desc_page); free_page(gm->rx_desc_page); gmacs = gm->next_gmac; kfree(dev); } + if (dummy_buf != NULL) { + kfree(dummy_buf); + dummy_buf = NULL; + } } module_init(gmac_probe); module_exit(gmac_cleanup_module); - diff --git a/drivers/net/gmac.h b/drivers/net/gmac.h index 4148c7db862e..f4ab8481b4f4 100644 --- a/drivers/net/gmac.h +++ b/drivers/net/gmac.h @@ -722,6 +722,13 @@ #define MII_ANLPA_CSMA 0x0001 /* CSMA-CD Capable */ #define MII_ANLPA_PAUS 0x0400 +/* Generic PHYs + * + * These GENERIC values assumes that the PHY devices follow 802.3u and + * allow parallel detection to set the link partner ability register. + * Detection of 100Base-TX [H/F Duplex] and 100Base-T4 is supported. + */ + /* * Model-specific PHY registers * @@ -731,6 +738,7 @@ /* Supported PHYs (phy_type field ) */ #define PHY_B5400 0x5400 +#define PHY_B5401 0x5401 #define PHY_B5201 0x5201 #define PHY_LXT971 0x0971 #define PHY_UNKNOWN 0 @@ -741,11 +749,21 @@ #define MII_BCM5201_REV 0x01 #define MII_BCM5201_ID ((MII_BCM5201_OUI << 10) | (MII_BCM5201_MODEL << 4)) #define MII_BCM5201_MASK 0xfffffff0 +#define MII_BCM5221_OUI 0x001018 +#define MII_BCM5221_MODEL 0x1e +#define MII_BCM5221_REV 0x00 +#define MII_BCM5221_ID ((MII_BCM5221_OUI << 10) | (MII_BCM5221_MODEL << 4)) +#define MII_BCM5221_MASK 0xfffffff0 #define MII_BCM5400_OUI 0x000818 #define MII_BCM5400_MODEL 0x04 #define MII_BCM5400_REV 0x01 #define MII_BCM5400_ID ((MII_BCM5400_OUI << 10) | (MII_BCM5400_MODEL << 4)) #define MII_BCM5400_MASK 0xfffffff0 +#define MII_BCM5401_OUI 0x000818 +#define MII_BCM5401_MODEL 0x05 +#define MII_BCM5401_REV 0x01 +#define MII_BCM5401_ID ((MII_BCM5401_OUI << 10) | (MII_BCM5401_MODEL << 4)) +#define MII_BCM5401_MASK 0xfffffff0 #define MII_LXT971_OUI 0x0004de #define MII_LXT971_MODEL 0x0e #define MII_LXT971_REV 0x00 @@ -791,7 +809,6 @@ #define MII_LXT971_STATUS2_AUTONEG_COMPLETE 0x0080 - /* * DMA descriptors */ @@ -877,6 +894,7 @@ struct gmac { u8 pci_devfn; spinlock_t lock; int opened; + int sleeping; struct net_device *next_gmac; }; diff --git a/drivers/net/hp100.h b/drivers/net/hp100.h index 9b05f837b807..9bc2de4c14e5 100644 --- a/drivers/net/hp100.h +++ b/drivers/net/hp100.h @@ -38,10 +38,10 @@ #define HP100_REG_HW_ID 0x00 /* R: (16) Unique card ID */ #define HP100_REG_TRACE 0x00 /* W: (16) Used for debug output */ #define HP100_REG_PAGING 0x02 /* R: (16),15:4 Card ID */ - /* W: (16),3:0 Switch pages */ + /* W: (16),3:0 Switch pages */ #define HP100_REG_OPTION_LSW 0x04 /* RW: (16) Select card functions */ #define HP100_REG_OPTION_MSW 0x06 /* RW: (16) Select card functions */ - + /* Page 0 - Performance */ #define HP100_REG_IRQ_STATUS 0x08 /* RW: (16) Which ints are pending */ @@ -53,27 +53,27 @@ #define HP100_REG_DATA32 0x10 /* RW: (32) I/O mode data port */ #define HP100_REG_DATA16 0x12 /* RW: WORDs must be read from here */ #define HP100_REG_TX_MEM_FREE 0x14 /* RD: (32) Amount of free Tx mem */ -#define HP100_REG_TX_PDA_L 0x14 /* W: (32) BM: Ptr to PDL, Low Pri */ -#define HP100_REG_TX_PDA_H 0x1c /* W: (32) BM: Ptr to PDL, High Pri */ +#define HP100_REG_TX_PDA_L 0x14 /* W: (32) BM: Ptr to PDL, Low Pri */ +#define HP100_REG_TX_PDA_H 0x1c /* W: (32) BM: Ptr to PDL, High Pri */ #define HP100_REG_RX_PKT_CNT 0x18 /* RD: (8) Rx count of pkts on card */ #define HP100_REG_TX_PKT_CNT 0x19 /* RD: (8) Tx count of pkts on card */ -#define HP100_REG_RX_PDL 0x1a /* R: (8) BM: # rx pdl not executed */ -#define HP100_REG_TX_PDL 0x1b /* R: (8) BM: # tx pdl not executed */ -#define HP100_REG_RX_PDA 0x18 /* W: (32) BM: Up to 31 addresses */ - /* which point to a PDL */ -#define HP100_REG_SL_EARLY 0x1c /* (32) Enhanced Slave Early Rx */ -#define HP100_REG_STAT_DROPPED 0x20 /* R (12) Dropped Packet Counter */ -#define HP100_REG_STAT_ERRORED 0x22 /* R (8) Errored Packet Counter */ -#define HP100_REG_STAT_ABORT 0x23 /* R (8) Abort Counter/OW Coll. Flag */ -#define HP100_REG_RX_RING 0x24 /* W (32) Slave: RX Ring Pointers */ -#define HP100_REG_32_FRAGMENT_LEN 0x28 /* W (13) Slave: Fragment Length Reg */ -#define HP100_REG_32_OFFSET 0x2c /* W (16) Slave: Offset Register */ +#define HP100_REG_RX_PDL 0x1a /* R: (8) BM: # rx pdl not executed */ +#define HP100_REG_TX_PDL 0x1b /* R: (8) BM: # tx pdl not executed */ +#define HP100_REG_RX_PDA 0x18 /* W: (32) BM: Up to 31 addresses */ + /* which point to a PDL */ +#define HP100_REG_SL_EARLY 0x1c /* (32) Enhanced Slave Early Rx */ +#define HP100_REG_STAT_DROPPED 0x20 /* R (12) Dropped Packet Counter */ +#define HP100_REG_STAT_ERRORED 0x22 /* R (8) Errored Packet Counter */ +#define HP100_REG_STAT_ABORT 0x23 /* R (8) Abort Counter/OW Coll. Flag */ +#define HP100_REG_RX_RING 0x24 /* W (32) Slave: RX Ring Pointers */ +#define HP100_REG_32_FRAGMENT_LEN 0x28 /* W (13) Slave: Fragment Length Reg */ +#define HP100_REG_32_OFFSET 0x2c /* W (16) Slave: Offset Register */ /* Page 1 - MAC Address/Hash Table */ -#define HP100_REG_MAC_ADDR 0x08 /* RW: (8) Cards MAC address */ +#define HP100_REG_MAC_ADDR 0x08 /* RW: (8) Cards MAC address */ #define HP100_REG_HASH_BYTE0 0x10 /* RW: (8) Cards multicast filter */ - + /* Page 2 - Hardware Mapping */ #define HP100_REG_MEM_MAP_LSW 0x08 /* RW: (16) LSW of cards mem addr */ @@ -84,44 +84,44 @@ #define HP100_REG_BM 0x0f /* RW: (8) Controls BM functions */ /* New on Page 2 for ETR chips: */ -#define HP100_REG_MODECTRL1 0x10 /* RW: (8) Mode Control 1 */ -#define HP100_REG_MODECTRL2 0x11 /* RW: (8) Mode Control 2 */ -#define HP100_REG_PCICTRL1 0x12 /* RW: (8) PCI Cfg 1 */ -#define HP100_REG_PCICTRL2 0x13 /* RW: (8) PCI Cfg 2 */ -#define HP100_REG_PCIBUSMLAT 0x15 /* RW: (8) PCI Bus Master Latency */ -#define HP100_REG_EARLYTXCFG 0x16 /* RW: (16) Early TX Cfg/Cntrl Reg */ -#define HP100_REG_EARLYRXCFG 0x18 /* RW: (8) Early RX Cfg/Cntrl Reg */ -#define HP100_REG_ISAPNPCFG1 0x1a /* RW: (8) ISA PnP Cfg/Cntrl Reg 1 */ -#define HP100_REG_ISAPNPCFG2 0x1b /* RW: (8) ISA PnP Cfg/Cntrl Reg 2 */ - +#define HP100_REG_MODECTRL1 0x10 /* RW: (8) Mode Control 1 */ +#define HP100_REG_MODECTRL2 0x11 /* RW: (8) Mode Control 2 */ +#define HP100_REG_PCICTRL1 0x12 /* RW: (8) PCI Cfg 1 */ +#define HP100_REG_PCICTRL2 0x13 /* RW: (8) PCI Cfg 2 */ +#define HP100_REG_PCIBUSMLAT 0x15 /* RW: (8) PCI Bus Master Latency */ +#define HP100_REG_EARLYTXCFG 0x16 /* RW: (16) Early TX Cfg/Cntrl Reg */ +#define HP100_REG_EARLYRXCFG 0x18 /* RW: (8) Early RX Cfg/Cntrl Reg */ +#define HP100_REG_ISAPNPCFG1 0x1a /* RW: (8) ISA PnP Cfg/Cntrl Reg 1 */ +#define HP100_REG_ISAPNPCFG2 0x1b /* RW: (8) ISA PnP Cfg/Cntrl Reg 2 */ + /* Page 3 - EEPROM/Boot ROM */ #define HP100_REG_EEPROM_CTRL 0x08 /* RW: (16) Used to load EEPROM */ #define HP100_REG_BOOTROM_CTRL 0x0a - + /* Page 4 - LAN Configuration (MAC_CTRL) */ #define HP100_REG_10_LAN_CFG_1 0x08 /* RW: (8) Set 10M XCVR functions */ -#define HP100_REG_10_LAN_CFG_2 0x09 /* RW: (8) 10M XCVR functions */ +#define HP100_REG_10_LAN_CFG_2 0x09 /* RW: (8) 10M XCVR functions */ #define HP100_REG_VG_LAN_CFG_1 0x0a /* RW: (8) Set 100M XCVR functions */ -#define HP100_REG_VG_LAN_CFG_2 0x0b /* RW: (8) 100M LAN Training cfgregs */ +#define HP100_REG_VG_LAN_CFG_2 0x0b /* RW: (8) 100M LAN Training cfgregs */ #define HP100_REG_MAC_CFG_1 0x0c /* RW: (8) Types of pkts to accept */ #define HP100_REG_MAC_CFG_2 0x0d /* RW: (8) Misc MAC functions */ -#define HP100_REG_MAC_CFG_3 0x0e /* RW: (8) Misc MAC functions */ -#define HP100_REG_MAC_CFG_4 0x0f /* R: (8) Misc MAC states */ -#define HP100_REG_DROPPED 0x10 /* R: (16),11:0 Pkts cant fit in mem*/ +#define HP100_REG_MAC_CFG_3 0x0e /* RW: (8) Misc MAC functions */ +#define HP100_REG_MAC_CFG_4 0x0f /* R: (8) Misc MAC states */ +#define HP100_REG_DROPPED 0x10 /* R: (16),11:0 Pkts cant fit in mem */ #define HP100_REG_CRC 0x12 /* R: (8) Pkts with CRC */ #define HP100_REG_ABORT 0x13 /* R: (8) Aborted Tx pkts */ -#define HP100_REG_TRAIN_REQUEST 0x14 /* RW: (16) Endnode MAC register.*/ -#define HP100_REG_TRAIN_ALLOW 0x16 /* R: (16) Hub allowed register */ - +#define HP100_REG_TRAIN_REQUEST 0x14 /* RW: (16) Endnode MAC register. */ +#define HP100_REG_TRAIN_ALLOW 0x16 /* R: (16) Hub allowed register */ + /* Page 5 - MMU */ #define HP100_REG_RX_MEM_STOP 0x0c /* RW: (16) End of Rx ring addr */ #define HP100_REG_TX_MEM_STOP 0x0e /* RW: (16) End of Tx ring addr */ -#define HP100_REG_PDL_MEM_STOP 0x10 /* Not used by 802.12 devices */ -#define HP100_REG_ECB_MEM_STOP 0x14 /* I've no idea what this is */ - +#define HP100_REG_PDL_MEM_STOP 0x10 /* Not used by 802.12 devices */ +#define HP100_REG_ECB_MEM_STOP 0x14 /* I've no idea what this is */ + /* Page 6 - Card ID/Physical LAN Address */ #define HP100_REG_BOARD_ID 0x08 /* R: (8) EISA/ISA card ID */ @@ -129,7 +129,7 @@ #define HP100_REG_SOFT_MODEL 0x0d /* R: (8) Config program defined */ #define HP100_REG_LAN_ADDR 0x10 /* R: (8) MAC addr of card */ #define HP100_REG_LAN_ADDR_CHCK 0x16 /* R: (8) Added to addr to get FFh */ - + /* Page 7 - MMU Current Pointers */ #define HP100_REG_PTR_RXSTART 0x08 /* R: (16) Current begin of Rx ring */ @@ -146,7 +146,7 @@ /* * Hardware ID Register I (Always available, HW_ID, Offset 0x00) */ -#define HP100_HW_ID_CASCADE 0x4850 /* Identifies Cascade Chip */ +#define HP100_HW_ID_CASCADE 0x4850 /* Identifies Cascade Chip */ /* * Hardware ID Register 2 & Paging Register @@ -154,12 +154,12 @@ * Bits 15:4 are for the Chip ID */ #define HP100_CHIPID_MASK 0xFFF0 -#define HP100_CHIPID_SHASTA 0x5350 /* Not 802.12 compliant */ - /* EISA BM/SL, MCA16/32 SL, ISA SL */ -#define HP100_CHIPID_RAINIER 0x5360 /* Not 802.12 compliant EISA BM,*/ - /* PCI SL, MCA16/32 SL, ISA SL */ -#define HP100_CHIPID_LASSEN 0x5370 /* 802.12 compliant PCI BM, PCI SL */ - /* LRF supported */ +#define HP100_CHIPID_SHASTA 0x5350 /* Not 802.12 compliant */ + /* EISA BM/SL, MCA16/32 SL, ISA SL */ +#define HP100_CHIPID_RAINIER 0x5360 /* Not 802.12 compliant EISA BM, */ + /* PCI SL, MCA16/32 SL, ISA SL */ +#define HP100_CHIPID_LASSEN 0x5370 /* 802.12 compliant PCI BM, PCI SL */ + /* LRF supported */ /* * Option Registers I and II @@ -167,24 +167,24 @@ */ #define HP100_DEBUG_EN 0x8000 /* 0:Dis., 1:Enable Debug Dump Ptr. */ #define HP100_RX_HDR 0x4000 /* 0:Dis., 1:Enable putting pkt into */ - /* system mem. before Rx interrupt */ + /* system mem. before Rx interrupt */ #define HP100_MMAP_DIS 0x2000 /* 0:Enable, 1:Disable mem.mapping. */ - /* MMAP_DIS must be 0 and MEM_EN */ - /* must be 1 for memory-mapped */ - /* mode to be enabled */ + /* MMAP_DIS must be 0 and MEM_EN */ + /* must be 1 for memory-mapped */ + /* mode to be enabled */ #define HP100_EE_EN 0x1000 /* 0:Disable,1:Enable EEPROM writing */ #define HP100_BM_WRITE 0x0800 /* 0:Slave, 1:Bus Master for Tx data */ #define HP100_BM_READ 0x0400 /* 0:Slave, 1:Bus Master for Rx data */ #define HP100_TRI_INT 0x0200 /* 0:Don't, 1:Do tri-state the int */ #define HP100_MEM_EN 0x0040 /* Config program set this to */ - /* 0:Disable, 1:Enable mem map. */ - /* See MMAP_DIS. */ + /* 0:Disable, 1:Enable mem map. */ + /* See MMAP_DIS. */ #define HP100_IO_EN 0x0020 /* 1:Enable I/O transfers */ #define HP100_BOOT_EN 0x0010 /* 1:Enable boot ROM access */ #define HP100_FAKE_INT 0x0008 /* 1:int */ #define HP100_INT_EN 0x0004 /* 1:Enable ints from card */ #define HP100_HW_RST 0x0002 /* 0:Reset, 1:Out of reset */ - /* NIC reset on 0 to 1 transition */ + /* NIC reset on 0 to 1 transition */ /* * Option Register III @@ -193,9 +193,9 @@ #define HP100_PRIORITY_TX 0x0080 /* 1:Do all Tx pkts as priority */ #define HP100_EE_LOAD 0x0040 /* 1:EEPROM loading, 0 when done */ #define HP100_ADV_NXT_PKT 0x0004 /* 1:Advance to next pkt in Rx queue */ - /* h/w will set to 0 when done */ + /* h/w will set to 0 when done */ #define HP100_TX_CMD 0x0002 /* 1:Tell h/w download done, h/w */ - /* will set to 0 when done */ + /* will set to 0 when done */ /* * Interrupt Status Registers I and II @@ -208,10 +208,10 @@ #define HP100_RX_PDL_FILL_COMPL 0x0800 #define HP100_RX_PACKET 0x0400 /* 0:No, 1:Yes pkt has been Rx */ #define HP100_RX_ERROR 0x0200 /* 0:No, 1:Yes Rx pkt had error */ -#define HP100_TX_PDA_ZERO 0x0020 /* 1 when PDA count goes to zero */ +#define HP100_TX_PDA_ZERO 0x0020 /* 1 when PDA count goes to zero */ #define HP100_TX_SPACE_AVAIL 0x0010 /* 0:<8192, 1:>=8192 Tx free bytes */ #define HP100_TX_COMPLETE 0x0008 /* 0:No, 1:Yes a Tx has completed */ -#define HP100_MISC_ERROR 0x0004 /* 0:No, 1:Lan Link down or bus error*/ +#define HP100_MISC_ERROR 0x0004 /* 0:No, 1:Lan Link down or bus error */ #define HP100_TX_ERROR 0x0002 /* 0:No, 1:Yes Tx pkt had error */ /* @@ -229,7 +229,7 @@ #define HP100_IRQ_SCRAMBLE 0x40 #define HP100_BOND_HP 0x20 #define HP100_LEVEL_IRQ 0x10 /* 0:Edge, 1:Level type interrupts. */ - /* (Only valid on EISA cards) */ + /* (Only valid on EISA cards) */ #define HP100_IRQMASK 0x0F /* Isolate the IRQ bits */ /* @@ -237,20 +237,20 @@ * (Page HW_MAP, SRAM, Offset 0x0e) */ #define HP100_RAM_SIZE_MASK 0xe0 /* AND to get SRAM size index */ -#define HP100_RAM_SIZE_SHIFT 0x05 /* Shift count(put index in lwr bits)*/ +#define HP100_RAM_SIZE_SHIFT 0x05 /* Shift count(put index in lwr bits) */ /* * Bus Master Register * (Page HW_MAP, BM, Offset 0x0f) */ -#define HP100_BM_BURST_RD 0x01 /* EISA only: 1=Use burst trans. fm system */ - /* memory to chip (tx) */ -#define HP100_BM_BURST_WR 0x02 /* EISA only: 1=Use burst trans. fm system */ - /* memory to chip (rx) */ +#define HP100_BM_BURST_RD 0x01 /* EISA only: 1=Use burst trans. fm system */ + /* memory to chip (tx) */ +#define HP100_BM_BURST_WR 0x02 /* EISA only: 1=Use burst trans. fm system */ + /* memory to chip (rx) */ #define HP100_BM_MASTER 0x04 /* 0:Slave, 1:BM mode */ -#define HP100_BM_PAGE_CK 0x08 /* This bit should be set whenever in*/ - /* an EISA system */ -#define HP100_BM_PCI_8CLK 0x40 /* ... cycles 8 clocks apart */ +#define HP100_BM_PAGE_CK 0x08 /* This bit should be set whenever in */ + /* an EISA system */ +#define HP100_BM_PCI_8CLK 0x40 /* ... cycles 8 clocks apart */ /* @@ -258,82 +258,82 @@ * (Page HW_MAP, MODECTRL1, Offset0x10) */ #define HP100_TX_DUALQ 0x10 - /* If set and BM -> dual tx pda queues*/ -#define HP100_ISR_CLRMODE 0x02 /* If set ISR will clear all pending */ - /* interrupts on read (etr only?) */ -#define HP100_EE_NOLOAD 0x04 /* Status whether res will be loaded */ - /* from the eeprom */ -#define HP100_TX_CNT_FLG 0x08 /* Controls Early TX Reg Cnt Field */ -#define HP100_PDL_USE3 0x10 /* If set BM engine will read only */ - /* first three data elements of a PDL */ - /* on the first access. */ -#define HP100_BUSTYPE_MASK 0xe0 /* Three bit bus type info */ + /* If set and BM -> dual tx pda queues */ +#define HP100_ISR_CLRMODE 0x02 /* If set ISR will clear all pending */ + /* interrupts on read (etr only?) */ +#define HP100_EE_NOLOAD 0x04 /* Status whether res will be loaded */ + /* from the eeprom */ +#define HP100_TX_CNT_FLG 0x08 /* Controls Early TX Reg Cnt Field */ +#define HP100_PDL_USE3 0x10 /* If set BM engine will read only */ + /* first three data elements of a PDL */ + /* on the first access. */ +#define HP100_BUSTYPE_MASK 0xe0 /* Three bit bus type info */ /* * Mode Control Register II * (Page HW_MAP, MODECTRL2, Offset0x11) */ -#define HP100_EE_MASK 0x0f /* Tell EEPROM circuit not to load */ - /* certain resources */ -#define HP100_DIS_CANCEL 0x20 /* For tx dualq mode operation */ -#define HP100_EN_PDL_WB 0x40 /* 1: Status of PDL completion may be */ - /* written back to system mem */ -#define HP100_EN_BUS_FAIL 0x80 /* Enables bus-fail portion of misc */ - /* interrupt */ +#define HP100_EE_MASK 0x0f /* Tell EEPROM circuit not to load */ + /* certain resources */ +#define HP100_DIS_CANCEL 0x20 /* For tx dualq mode operation */ +#define HP100_EN_PDL_WB 0x40 /* 1: Status of PDL completion may be */ + /* written back to system mem */ +#define HP100_EN_BUS_FAIL 0x80 /* Enables bus-fail portion of misc */ + /* interrupt */ /* * PCI Configuration and Control Register I * (Page HW_MAP, PCICTRL1, Offset 0x12) */ -#define HP100_LO_MEM 0x01 /* 1: Mapped Mem requested below 1MB */ -#define HP100_NO_MEM 0x02 /* 1: Disables Req for sysmem to PCI */ - /* bios */ -#define HP100_USE_ISA 0x04 /* 1: isa type decodes will occur */ - /* simultaneously with PCI decodes */ -#define HP100_IRQ_HI_MASK 0xf0 /* pgmed by pci bios */ -#define HP100_PCI_IRQ_HI_MASK 0x78 /* Isolate 4 bits for PCI IRQ */ - +#define HP100_LO_MEM 0x01 /* 1: Mapped Mem requested below 1MB */ +#define HP100_NO_MEM 0x02 /* 1: Disables Req for sysmem to PCI */ + /* bios */ +#define HP100_USE_ISA 0x04 /* 1: isa type decodes will occur */ + /* simultaneously with PCI decodes */ +#define HP100_IRQ_HI_MASK 0xf0 /* pgmed by pci bios */ +#define HP100_PCI_IRQ_HI_MASK 0x78 /* Isolate 4 bits for PCI IRQ */ + /* * PCI Configuration and Control Register II * (Page HW_MAP, PCICTRL2, Offset 0x13) */ -#define HP100_RD_LINE_PDL 0x01 /* 1: PCI command Memory Read Line en */ -#define HP100_RD_TX_DATA_MASK 0x06 /* choose PCI memread cmds for TX */ -#define HP100_MWI 0x08 /* 1: en. PCI memory write invalidate */ -#define HP100_ARB_MODE 0x10 /* Select PCI arbitor type */ -#define HP100_STOP_EN 0x20 /* Enables PCI state machine to issue */ - /* pci stop if cascade not ready */ -#define HP100_IGNORE_PAR 0x40 /* 1: PCI state machine ignores parity*/ -#define HP100_PCI_RESET 0x80 /* 0->1: Reset PCI block */ +#define HP100_RD_LINE_PDL 0x01 /* 1: PCI command Memory Read Line en */ +#define HP100_RD_TX_DATA_MASK 0x06 /* choose PCI memread cmds for TX */ +#define HP100_MWI 0x08 /* 1: en. PCI memory write invalidate */ +#define HP100_ARB_MODE 0x10 /* Select PCI arbitor type */ +#define HP100_STOP_EN 0x20 /* Enables PCI state machine to issue */ + /* pci stop if cascade not ready */ +#define HP100_IGNORE_PAR 0x40 /* 1: PCI state machine ignores parity */ +#define HP100_PCI_RESET 0x80 /* 0->1: Reset PCI block */ /* * Early TX Configuration and Control Register * (Page HW_MAP, EARLYTXCFG, Offset 0x16) */ -#define HP100_EN_EARLY_TX 0x8000 /* 1=Enable Early TX */ -#define HP100_EN_ADAPTIVE 0x4000 /* 1=Enable adaptive mode */ -#define HP100_EN_TX_UR_IRQ 0x2000 /* reserved, must be 0 */ -#define HP100_EN_LOW_TX 0x1000 /* reserved, must be 0 */ -#define HP100_ET_CNT_MASK 0x0fff /* bits 11..0: ET counters */ +#define HP100_EN_EARLY_TX 0x8000 /* 1=Enable Early TX */ +#define HP100_EN_ADAPTIVE 0x4000 /* 1=Enable adaptive mode */ +#define HP100_EN_TX_UR_IRQ 0x2000 /* reserved, must be 0 */ +#define HP100_EN_LOW_TX 0x1000 /* reserved, must be 0 */ +#define HP100_ET_CNT_MASK 0x0fff /* bits 11..0: ET counters */ /* * Early RX Configuration and Control Register * (Page HW_MAP, EARLYRXCFG, Offset 0x18) */ -#define HP100_EN_EARLY_RX 0x80 /* 1=Enable Early RX */ -#define HP100_EN_LOW_RX 0x40 /* reserved, must be 0 */ -#define HP100_RX_TRIP_MASK 0x1f /* bits 4..0: threshold at which the - * early rx circuit will start the - * dma of received packet into system - * memory for BM */ +#define HP100_EN_EARLY_RX 0x80 /* 1=Enable Early RX */ +#define HP100_EN_LOW_RX 0x40 /* reserved, must be 0 */ +#define HP100_RX_TRIP_MASK 0x1f /* bits 4..0: threshold at which the + * early rx circuit will start the + * dma of received packet into system + * memory for BM */ /* * Serial Devices Control Register * (Page EEPROM_CTRL, EEPROM_CTRL, Offset 0x08) */ #define HP100_EEPROM_LOAD 0x0001 /* 0->1 loads EEPROM into registers. */ - /* When it goes back to 0, load is */ - /* complete. This should take ~600us.*/ + /* When it goes back to 0, load is */ + /* complete. This should take ~600us. */ /* * 10MB LAN Control and Configuration Register I @@ -345,7 +345,7 @@ #define HP100_LINK_BEAT_DIS 0x08 /* 0:Enable, 1:Disable link beat */ #define HP100_LINK_BEAT_ST 0x04 /* 0:No, 1:Yes link beat being Rx */ #define HP100_R_ROL_ST 0x02 /* 0:No, 1:Yes Rx twisted pair has */ - /* been reversed */ + /* been reversed */ #define HP100_AUI_ST 0x01 /* 0:No, 1:Yes use AUI on TP card */ /* @@ -353,9 +353,9 @@ * (Page MAC_CTRL, 10_LAN_CFG_2, Offset 0x09) */ #define HP100_SQU_ST 0x01 /* 0:No, 1:Yes collision signal sent */ - /* after Tx.Only used for AUI. */ -#define HP100_FULLDUP 0x02 /* 1: LXT901 XCVR fullduplx enabled */ -#define HP100_DOT3_MAC 0x04 /* 1: DOT 3 Mac sel. unless Autosel */ + /* after Tx.Only used for AUI. */ +#define HP100_FULLDUP 0x02 /* 1: LXT901 XCVR fullduplx enabled */ +#define HP100_DOT3_MAC 0x04 /* 1: DOT 3 Mac sel. unless Autosel */ /* * MAC Selection, use with MAC10_SEL bits @@ -372,9 +372,9 @@ #define HP100_FRAME_FORMAT 0x08 /* 0:802.3, 1:802.5 frames */ #define HP100_BRIDGE 0x04 /* 0:No, 1:Yes tell hub i am a bridge */ #define HP100_PROM_MODE 0x02 /* 0:No, 1:Yes tell hub card is */ - /* promiscuous */ + /* promiscuous */ #define HP100_REPEATER 0x01 /* 0:No, 1:Yes tell hub MAC wants to */ - /* be a cascaded repeater */ + /* be a cascaded repeater */ /* * 100MB LAN Control and Configuration Register @@ -383,16 +383,16 @@ #define HP100_VG_SEL 0x80 /* 0:No, 1:Yes use 100 Mbit MAC */ #define HP100_LINK_UP_ST 0x40 /* 0:No, 1:Yes endnode logged in */ #define HP100_LINK_CABLE_ST 0x20 /* 0:No, 1:Yes cable can hear tones */ - /* from hub */ + /* from hub */ #define HP100_LOAD_ADDR 0x10 /* 0->1 card addr will be sent */ - /* 100ms later the link status */ - /* bits are valid */ + /* 100ms later the link status */ + /* bits are valid */ #define HP100_LINK_CMD 0x08 /* 0->1 link will attempt to log in. */ - /* 100ms later the link status */ - /* bits are valid */ -#define HP100_TRN_DONE 0x04 /* NEW ETR-Chips only: Will be reset */ - /* after LinkUp Cmd is given and set */ - /* when training has completed. */ + /* 100ms later the link status */ + /* bits are valid */ +#define HP100_TRN_DONE 0x04 /* NEW ETR-Chips only: Will be reset */ + /* after LinkUp Cmd is given and set */ + /* when training has completed. */ #define HP100_LINK_GOOD_ST 0x02 /* 0:No, 1:Yes cable passed training */ #define HP100_VG_RESET 0x01 /* 0:Yes, 1:No reset the 100VG MAC */ @@ -414,7 +414,7 @@ #define HP100_MAC1MODE2 0x00 #define HP100_MAC1MODE3 HP100_MAC1MODE2 | HP100_ACC_BC #define HP100_MAC1MODE4 HP100_MAC1MODE3 | HP100_ACC_MC -#define HP100_MAC1MODE5 HP100_MAC1MODE4 /* set mc hash to all ones also */ +#define HP100_MAC1MODE5 HP100_MAC1MODE4 /* set mc hash to all ones also */ #define HP100_MAC1MODE6 HP100_MAC1MODE5 | HP100_ACC_PHY /* Promiscuous */ /* Note MODE6 will receive all GOOD packets on the LAN. This really needs a mode 7 defined to be LAN Analyzer mode, which will receive errored and @@ -428,14 +428,14 @@ #define HP100_TR_MODE 0x80 /* 0:No, 1:Yes support Token Ring formats */ #define HP100_TX_SAME 0x40 /* 0:No, 1:Yes Tx same packet continuous */ #define HP100_LBK_XCVR 0x20 /* 0:No, 1:Yes loopback through MAC & */ - /* transceiver */ + /* transceiver */ #define HP100_LBK_MAC 0x10 /* 0:No, 1:Yes loopback through MAC */ #define HP100_CRC_I 0x08 /* 0:No, 1:Yes inhibit CRC on Tx packets */ -#define HP100_ACCNA 0x04 /* 1: For 802.5: Accept only token ring +#define HP100_ACCNA 0x04 /* 1: For 802.5: Accept only token ring * group addr that maches NA mask */ #define HP100_KEEP_CRC 0x02 /* 0:No, 1:Yes keep CRC on Rx packets. */ - /* The length will reflect this. */ -#define HP100_ACCFA 0x01 /* 1: For 802.5: Accept only functional + /* The length will reflect this. */ +#define HP100_ACCFA 0x01 /* 1: For 802.5: Accept only functional * addrs that match FA mask (page1) */ #define HP100_MAC2MODEMASK 0x02 #define HP100_MAC2MODE1 0x00 @@ -450,58 +450,58 @@ * MAC Configuration Register III * (Page MAC_CTRL, MAC_CFG_3, Offset 0x0e) */ -#define HP100_PACKET_PACE 0x03 /* Packet Pacing: - * 00: No packet pacing - * 01: 8 to 16 uS delay - * 10: 16 to 32 uS delay - * 11: 32 to 64 uS delay - */ -#define HP100_LRF_EN 0x04 /* 1: External LAN Rcv Filter and - * TCP/IP Checksumming enabled. */ -#define HP100_AUTO_MODE 0x10 /* 1: AutoSelect between 10/100 */ +#define HP100_PACKET_PACE 0x03 /* Packet Pacing: + * 00: No packet pacing + * 01: 8 to 16 uS delay + * 10: 16 to 32 uS delay + * 11: 32 to 64 uS delay + */ +#define HP100_LRF_EN 0x04 /* 1: External LAN Rcv Filter and + * TCP/IP Checksumming enabled. */ +#define HP100_AUTO_MODE 0x10 /* 1: AutoSelect between 10/100 */ /* * MAC Configuration Register IV * (Page MAC_CTRL, MAC_CFG_4, Offset 0x0f) */ -#define HP100_MAC_SEL_ST 0x01 /* (R): Status of external VGSEL - * Signal, 1=100VG, 0=10Mbit sel. */ -#define HP100_LINK_FAIL_ST 0x02 /* (R): Status of Link Fail portion - * of the Misc. Interrupt */ +#define HP100_MAC_SEL_ST 0x01 /* (R): Status of external VGSEL + * Signal, 1=100VG, 0=10Mbit sel. */ +#define HP100_LINK_FAIL_ST 0x02 /* (R): Status of Link Fail portion + * of the Misc. Interrupt */ /* * 100 MB LAN Training Request/Allowed Registers * (Page MAC_CTRL, TRAIN_REQUEST and TRAIN_ALLOW, Offset 0x14-0x16)(ETR parts only) */ -#define HP100_MACRQ_REPEATER 0x0001 /* 1: MAC tells HUB it wants to be - * a cascaded repeater - * 0: ... wants to be a DTE */ -#define HP100_MACRQ_PROMSC 0x0006 /* 2 bits: Promiscious mode - * 00: Rcv only unicast packets - * specifically addr to this - * endnode - * 10: Rcv all pckts fwded by - * the local repeater */ -#define HP100_MACRQ_FRAMEFMT_EITHER 0x0018 /* 11: either format allowed */ -#define HP100_MACRQ_FRAMEFMT_802_3 0x0000 /* 00: 802.3 is requested */ -#define HP100_MACRQ_FRAMEFMT_802_5 0x0010 /* 10: 802.5 format is requested */ -#define HP100_CARD_MACVER 0xe000 /* R: 3 bit Cards 100VG MAC version */ -#define HP100_MALLOW_REPEATER 0x0001 /* If reset, requested access as an - * end node is allowed */ -#define HP100_MALLOW_PROMSC 0x0004 /* 2 bits: Promiscious mode - * 00: Rcv only unicast packets - * specifically addr to this - * endnode - * 10: Rcv all pckts fwded by - * the local repeater */ -#define HP100_MALLOW_FRAMEFMT 0x00e0 /* 2 bits: Frame Format - * 00: 802.3 format will be used - * 10: 802.5 format will be used */ -#define HP100_MALLOW_ACCDENIED 0x0400 /* N bit */ -#define HP100_MALLOW_CONFIGURE 0x0f00 /* C bit */ -#define HP100_MALLOW_DUPADDR 0x1000 /* D bit */ -#define HP100_HUB_MACVER 0xe000 /* R: 3 bit 802.12 MAC/RMAC training */ - /* protocol of repeater */ +#define HP100_MACRQ_REPEATER 0x0001 /* 1: MAC tells HUB it wants to be + * a cascaded repeater + * 0: ... wants to be a DTE */ +#define HP100_MACRQ_PROMSC 0x0006 /* 2 bits: Promiscious mode + * 00: Rcv only unicast packets + * specifically addr to this + * endnode + * 10: Rcv all pckts fwded by + * the local repeater */ +#define HP100_MACRQ_FRAMEFMT_EITHER 0x0018 /* 11: either format allowed */ +#define HP100_MACRQ_FRAMEFMT_802_3 0x0000 /* 00: 802.3 is requested */ +#define HP100_MACRQ_FRAMEFMT_802_5 0x0010 /* 10: 802.5 format is requested */ +#define HP100_CARD_MACVER 0xe000 /* R: 3 bit Cards 100VG MAC version */ +#define HP100_MALLOW_REPEATER 0x0001 /* If reset, requested access as an + * end node is allowed */ +#define HP100_MALLOW_PROMSC 0x0004 /* 2 bits: Promiscious mode + * 00: Rcv only unicast packets + * specifically addr to this + * endnode + * 10: Rcv all pckts fwded by + * the local repeater */ +#define HP100_MALLOW_FRAMEFMT 0x00e0 /* 2 bits: Frame Format + * 00: 802.3 format will be used + * 10: 802.5 format will be used */ +#define HP100_MALLOW_ACCDENIED 0x0400 /* N bit */ +#define HP100_MALLOW_CONFIGURE 0x0f00 /* C bit */ +#define HP100_MALLOW_DUPADDR 0x1000 /* D bit */ +#define HP100_HUB_MACVER 0xe000 /* R: 3 bit 802.12 MAC/RMAC training */ + /* protocol of repeater */ /* ****************************************************************************** */ @@ -516,7 +516,7 @@ /* * Misc. Constants */ -#define HP100_LAN_100 100 /* lan_type value for VG */ +#define HP100_LAN_100 100 /* lan_type value for VG */ #define HP100_LAN_10 10 /* lan_type value for 10BaseT */ #define HP100_LAN_ERR (-1) /* lan_type value for link down */ @@ -528,10 +528,10 @@ * Bus Master Data Structures ---------------------------------------------- */ -#define MAX_RX_PDL 30 /* Card limit = 31 */ -#define MAX_RX_FRAG 2 /* Don't need more... */ +#define MAX_RX_PDL 30 /* Card limit = 31 */ +#define MAX_RX_FRAG 2 /* Don't need more... */ #define MAX_TX_PDL 29 -#define MAX_TX_FRAG 2 /* Limit = 31 */ +#define MAX_TX_FRAG 2 /* Limit = 31 */ /* Define total PDL area size in bytes (should be 4096) */ /* This is the size of kernel (dma) memory that will be allocated. */ @@ -539,16 +539,16 @@ /* Ethernet Packet Sizes */ #define MIN_ETHER_SIZE 60 -#define MAX_ETHER_SIZE 1514 /* Needed for preallocation of */ - /* skb buffer when busmastering */ +#define MAX_ETHER_SIZE 1514 /* Needed for preallocation of */ + /* skb buffer when busmastering */ /* Tx or Rx Ring Entry */ typedef struct hp100_ring { - u_int *pdl; /* Address of PDLs PDH, dword before - * this address is used for rx hdr */ - u_int pdl_paddr; /* Physical address of PDL */ - struct sk_buff *skb; - struct hp100_ring *next; + u_int *pdl; /* Address of PDLs PDH, dword before + * this address is used for rx hdr */ + u_int pdl_paddr; /* Physical address of PDL */ + struct sk_buff *skb; + struct hp100_ring *next; } hp100_ring_t; @@ -564,12 +564,12 @@ typedef struct hp100_ring { #define HP100_SKEW_ERR 0x2000 /* 0:No, 1:Yes skew out of range */ #define HP100_BAD_SYMBOL_ERR 0x1000 /* 0:No, 1:Yes invalid symbol received */ #define HP100_RCV_IPM_ERR 0x0800 /* 0:No, 1:Yes pkt had an invalid packet */ - /* marker */ + /* marker */ #define HP100_SYMBOL_BAL_ERR 0x0400 /* 0:No, 1:Yes symbol balance error */ #define HP100_VG_ALN_ERR 0x0200 /* 0:No, 1:Yes non-octet received */ #define HP100_TRUNC_ERR 0x0100 /* 0:No, 1:Yes the packet was truncated */ #define HP100_RUNT_ERR 0x0040 /* 0:No, 1:Yes pkt length < Min Pkt */ - /* Length Reg. */ + /* Length Reg. */ #define HP100_ALN_ERR 0x0010 /* 0:No, 1:Yes align error. */ #define HP100_CRC_ERR 0x0008 /* 0:No, 1:Yes CRC occurred. */ @@ -616,11 +616,3 @@ typedef struct hp100_ring { outw( HP100_MMAP_DIS | HP100_RESET_HB, ioaddr + HP100_REG_OPTION_LSW ) #define hp100_mem_map_disable() \ outw( HP100_MMAP_DIS | HP100_SET_HB, ioaddr + HP100_REG_OPTION_LSW ) - - -/* - * Local variables: - * c-indent-level: 2 - * tab-width: 8 - * End: -*/ diff --git a/drivers/net/ioc3-eth.c b/drivers/net/ioc3-eth.c index ba6fe0fded40..4b6ce5687657 100644 --- a/drivers/net/ioc3-eth.c +++ b/drivers/net/ioc3-eth.c @@ -402,7 +402,7 @@ static int ioc3_mii_init(struct net_device *dev, struct ioc3_private *ip, static struct net_device_stats *ioc3_get_stats(struct net_device *dev) { - struct ioc3_private *ip = (struct ioc3_private *) dev->priv; + struct ioc3_private *ip = dev->priv; struct ioc3 *ioc3 = ip->regs; ip->stats.collisions += (ioc3->etcdc & ETCDC_COLLCNT_MASK); @@ -566,7 +566,7 @@ ioc3_error(struct net_device *dev, struct ioc3_private *ip, after the Tx thread. */ static void ioc3_interrupt(int irq, void *_dev, struct pt_regs *regs) { - struct net_device *dev = (struct net_device *)_dev; + struct net_device *dev = _dev; struct ioc3_private *ip = dev->priv; struct ioc3 *ioc3 = ip->regs; const u32 enabled = EISR_RXTIMERINT | EISR_RXOFLO | EISR_RXBUFOFLO | @@ -595,7 +595,7 @@ static void ioc3_interrupt(int irq, void *_dev, struct pt_regs *regs) static void negotiate(unsigned long data) { struct net_device *dev = (struct net_device *) data; - struct ioc3_private *ip = (struct ioc3_private *) dev->priv; + struct ioc3_private *ip = dev->priv; struct ioc3 *ioc3 = ip->regs; mod_timer(&ip->negtimer, jiffies + 20 * HZ); @@ -864,7 +864,7 @@ ioc3_open(struct net_device *dev) return -EAGAIN; } - ip = (struct ioc3_private *) dev->priv; + ip = dev->priv; ip->ehar_h = 0; ip->ehar_l = 0; @@ -1131,7 +1131,7 @@ ioc3_hash(const unsigned char *addr) /* Provide ioctl() calls to examine the MII xcvr state. */ static int ioc3_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) { - struct ioc3_private *ip = (struct ioc3_private *) dev->priv; + struct ioc3_private *ip = dev->priv; u16 *data = (u16 *)&rq->ifr_data; struct ioc3 *ioc3 = ip->regs; int phy = ip->phy; diff --git a/drivers/net/mace.c b/drivers/net/mace.c index 7d8c592a01ff..11794cefb1e1 100644 --- a/drivers/net/mace.c +++ b/drivers/net/mace.c @@ -21,6 +21,9 @@ #include "mace.h" static struct net_device *mace_devs; +static int port_aaui = -1; + +MODULE_PARM(port_aaui, "i"); #define N_RX_RING 8 #define N_TX_RING 6 @@ -53,6 +56,7 @@ struct mace_data { struct net_device_stats stats; struct timer_list tx_timeout; int timeout_active; + int port_aaui; struct net_device *next_mace; }; @@ -178,6 +182,21 @@ static void __init mace_probe1(struct device_node *mace) init_timer(&mp->tx_timeout); mp->timeout_active = 0; + if (port_aaui >= 0) + mp->port_aaui = port_aaui; + else { + /* Apple Network Server uses the AAUI port */ + if (machine_is_compatible("AAPL,ShinerESB")) + mp->port_aaui = 1; + else { +#ifdef CONFIG_MACE_AAUI_PORT + mp->port_aaui = 1; +#else + mp->port_aaui = 0; +#endif + } + } + dev->open = mace_open; dev->stop = mace_close; dev->hard_start_xmit = mace_xmit_start; @@ -261,7 +280,10 @@ static void mace_reset(struct net_device *dev) /* done changing address */ out_8(&mb->iac, 0); - out_8(&mb->plscc, PORTSEL_GPSI + ENPLSIO); + if (mp->port_aaui) + out_8(&mb->plscc, PORTSEL_AUI + ENPLSIO); + else + out_8(&mb->plscc, PORTSEL_GPSI + ENPLSIO); } static void __mace_set_address(struct net_device *dev, void *addr) diff --git a/drivers/net/natsemi.c b/drivers/net/natsemi.c index 1019d48b7217..4562ca42e676 100644 --- a/drivers/net/natsemi.c +++ b/drivers/net/natsemi.c @@ -92,6 +92,8 @@ static int full_duplex[MAX_UNITS] = {-1, -1, -1, -1, -1, -1, -1, -1}; #define PKT_BUF_SZ 1536 /* Size of each temporary Rx buffer.*/ +#define final_version + #if !defined(__OPTIMIZE__) #warning You must compile this file with the correct options! #warning See the last lines of the source file. diff --git a/drivers/net/net_init.c b/drivers/net/net_init.c index 3bebd1e6716e..7ac7692be51b 100644 --- a/drivers/net/net_init.c +++ b/drivers/net/net_init.c @@ -205,11 +205,12 @@ struct net_device *init_etherdev(struct net_device *dev, int sizeof_priv) } /** - * alloc_etherdev - Register ethernet device + * alloc_etherdev - Allocates and sets up an ethernet device * @sizeof_priv: Size of additional driver-private structure to be allocated * for this ethernet device * - * Fill in the fields of the device structure with ethernet-generic values. + * Fill in the fields of the device structure with ethernet-generic + * values. Basically does everything except registering the device. * * Constructs a new net device, complete with a private data area of * size @sizeof_priv. A 32-byte (not bit) alignment is enforced for diff --git a/drivers/net/pppoe.c b/drivers/net/pppoe.c index 490a402584fe..6018d6637afa 100644 --- a/drivers/net/pppoe.c +++ b/drivers/net/pppoe.c @@ -5,7 +5,7 @@ * PPPoE --- PPP over Ethernet (RFC 2516) * * - * Version: 0.6.5 + * Version: 0.6.6 * * 030700 : Fixed connect logic to allow for disconnect. * 270700 : Fixed potential SMP problems; we must protect against @@ -19,6 +19,7 @@ * 051000 : Initialization cleanup. * 111100 : Fix recvmsg. * 050101 : Fix PADT procesing. + * 140501 : Use pppoe_rcv_core to handle all backlog. (Alexey) * * Author: Michal Ostrowski * Contributors: @@ -376,22 +377,6 @@ static int pppoe_rcv(struct sk_buff *skb, return ret; } - -/************************************************************************ - * - * Receive wrapper called in process context. - * - ***********************************************************************/ -int pppoe_backlog_rcv(struct sock *sk, struct sk_buff *skb) -{ - lock_sock(sk); - pppoe_rcv_core(sk, skb); - release_sock(sk); - return 0; -} - - - /************************************************************************ * * Receive a PPPoE Discovery frame. @@ -481,7 +466,7 @@ static int pppoe_create(struct socket *sock) sk->protocol = PX_PROTO_OE; sk->family = PF_PPPOX; - sk->backlog_rcv = pppoe_backlog_rcv; + sk->backlog_rcv = pppoe_rcv_core; sk->next = NULL; sk->pprev = NULL; sk->state = PPPOX_NONE; diff --git a/drivers/net/sunhme.c b/drivers/net/sunhme.c index ff358baddff1..645f1c9e5470 100644 --- a/drivers/net/sunhme.c +++ b/drivers/net/sunhme.c @@ -1,4 +1,4 @@ -/* $Id: sunhme.c,v 1.117 2001/04/19 22:32:41 davem Exp $ +/* $Id: sunhme.c,v 1.118 2001/05/11 02:09:30 davem Exp $ * sunhme.c: Sparc HME/BigMac 10/100baseT half/full duplex auto switching, * auto carrier detecting ethernet driver. Also known as the * "Happy Meal Ethernet" found on SunSwift SBUS cards. @@ -2206,6 +2206,7 @@ static void quattro_sbus_interrupt(int irq, void *cookie, struct pt_regs *ptregs static int happy_meal_open(struct net_device *dev) { struct happy_meal *hp = dev->priv; + int res; HMD(("happy_meal_open: ")); @@ -2229,7 +2230,10 @@ static int happy_meal_open(struct net_device *dev) } HMD(("to happy_meal_init\n")); - return happy_meal_init(hp, 0); + res = happy_meal_init(hp, 0); + if (res && ((hp->happy_flags & (HFLAG_QUATTRO|HFLAG_PCI)) != HFLAG_QUATTRO)) + free_irq(dev->irq, dev); + return res; } static int happy_meal_close(struct net_device *dev) @@ -2441,7 +2445,7 @@ static int happy_meal_ioctl(struct net_device *dev, if (copy_from_user(&ecmd, ep_user, sizeof(ecmd))) return -EFAULT; - if (ecmd.cmd == SPARC_ETH_GSET) { + if (ecmd.cmd == ETHTOOL_GSET) { ecmd.supported = (SUPPORTED_10baseT_Half | SUPPORTED_10baseT_Full | SUPPORTED_100baseT_Half | SUPPORTED_100baseT_Full | @@ -2480,7 +2484,7 @@ static int happy_meal_ioctl(struct net_device *dev, if (copy_to_user(ep_user, &ecmd, sizeof(ecmd))) return -EFAULT; return 0; - } else if (ecmd.cmd == SPARC_ETH_SSET) { + } else if (ecmd.cmd == ETHTOOL_SSET) { if (!capable(CAP_NET_ADMIN)) return -EPERM; @@ -2864,7 +2868,7 @@ static int __init happy_meal_pci_init(struct pci_dev *pdev) prom_getstring(node, "name", prom_name, sizeof(prom_name)); #else -#warning This needs to be corrected... -DaveM +/* This needs to be corrected... -DaveM */ strcpy(prom_name, "qfe"); #endif diff --git a/drivers/net/tokenring/ibmtr.h b/drivers/net/tokenring/ibmtr.h deleted file mode 100644 index 3e341078b0eb..000000000000 --- a/drivers/net/tokenring/ibmtr.h +++ /dev/null @@ -1,454 +0,0 @@ -/* Definitions for an IBM Token Ring card. */ -/* This file is distributed under the GNU GPL */ - -/* ported to the Alpha architecture 02/20/96 (just used the HZ macro) */ - -#define TR_RETRY_INTERVAL (5*HZ) /* 500 on PC = 5 s */ -#define TR_RESET_INTERVAL (HZ/20) /* 5 on PC = 50 ms */ -#define TR_BUSY_INTERVAL (HZ/5) /* 5 on PC = 200 ms */ -#define TR_SPIN_INTERVAL (3*HZ) /* 3 seconds before init timeout */ -#define TR_RETRIES 6 /* number of open retries */ - -#define TR_ISA 1 -#define TR_MCA 2 -#define TR_ISAPNP 3 -#define NOTOK 0 -#define TOKDEBUG 1 - -#define IBMTR_SHARED_RAM_SIZE 0x10000 -#define IBMTR_IO_EXTENT 4 -#define IBMTR_MAX_ADAPTERS 2 - -#define CHANNEL_ID 0X1F30 -#define AIP 0X1F00 -#define AIPCHKSUM1 0X1F60 -#define AIPCHKSUM2 0X1FF0 -#define AIPADAPTYPE 0X1FA0 -#define AIPDATARATE 0X1FA2 -#define AIPEARLYTOKEN 0X1FA4 -#define AIPAVAILSHRAM 0X1FA6 -#define AIPSHRAMPAGE 0X1FA8 -#define AIP4MBDHB 0X1FAA -#define AIP16MBDHB 0X1FAC -#define AIPFID 0X1FBA - -/* Note, 0xA20 == 0x220 since motherboard decodes 10 bits. I left everything - the way my documentation had it, ie: 0x0A20. */ -#define ADAPTINTCNTRL 0x02f0 /* Adapter interrupt control */ -#define ADAPTRESET 0x1 /* Control Adapter reset (add to base) */ -#define ADAPTRESETREL 0x2 /* Release Adapter from reset ( """) */ -#define ADAPTINTREL 0x3 /* Adapter interrupt release */ - -#define MMIOStartLocP 0x0a20 /* Primary adapter's starting MMIO area */ -#define MMIOStartLocA 0x0a24 /* Alternate adapter's starting MMIO area */ - -#define GLOBAL_INT_ENABLE 0x02f0 - -/* MMIO bits 0-4 select register */ -#define RRR_EVEN 0x00 /* Shared RAM relocation registers - even and odd */ -/* Used to set the starting address of shared RAM */ -/* Bits 1 through 7 of this register map to bits 13 through 19 of the shared RAM address.*/ -/* ie: 0x02 sets RAM address to ...ato! issy su wazzoo !! GODZILLA!!! */ -#define RRR_ODD 0x01 -/* Bits 2 and 3 of this register can be read to determine shared RAM size */ -/* 00 for 8k, 01 for 16k, 10 for 32k, 11 for 64k */ -#define WRBR_EVEN 0x02 /* Write region base registers - even and odd */ -#define WRBR_ODD 0x03 -#define WWOR_EVEN 0x04 /* Write window open registers - even and odd */ -#define WWOR_ODD 0x05 -#define WWCR_EVEN 0x06 /* Write window close registers - even and odd */ -#define WWCR_ODD 0x07 - -/* Interrupt status registers - PC system - even and odd */ -#define ISRP_EVEN 0x08 - -#define TCR_INT 0x10 /* Bit 4 - Timer interrupt. The TVR_EVEN timer has - expired. */ -#define ERR_INT 0x08 /* Bit 3 - Error interrupt. The adapter has had an - internal error. */ -#define ACCESS_INT 0x04 /* Bit 2 - Access interrupt. You have attempted to - write to an invalid area of shared RAM or an invalid - register within the MMIO. */ -/* In addition, the following bits within ISRP_EVEN can be turned on or off by you */ -/* to control the interrupt processing: */ -#define INT_IRQ 0x80 /* Bit 7 - If 0 the adapter will issue a CHCK, if 1 and - IRQ. This should normally be set (by you) to 1. */ -#define INT_ENABLE 0x40 /* Bit 6 - Interrupt enable. If 0, no interrupts will - occur. If 1, interrupts will occur normally. - Normally set to 1. */ -/* Bit 0 - Primary or alternate adapter. Set to zero if this adapter is the primary adapter,*/ -/* 1 if this adapter is the alternate adapter. */ - - -#define ISRP_ODD 0x09 - -#define ADAP_CHK_INT 0x40 /* Bit 6 - Adapter check. the adapter has - encountered a serious problem and has closed - itself. Whoa. */ -#define SRB_RESP_INT 0x20 /* Bit 5 - SRB response. The adapter has accepted - an SRB request and set the return code within - the SRB. */ -#define ASB_FREE_INT 0x10 /* Bit 4 - ASB free. The adapter has read the ASB - and this area can be safely reused. This interrupt - is only used if your application has set the ASB - free request bit in ISRA_ODD or if an error was - detected in your response. */ -#define ARB_CMD_INT 0x08 /* Bit 3 - ARB command. The adapter has given you a - command for action. The command is located in the - ARB area of shared memory. */ -#define SSB_RESP_INT 0x04 /* Bit 2 - SSB response. The adapter has posted a - response to your SRB (the response is located in - the SSB area of shared memory). */ -/* Bit 1 - Bridge frame forward complete. */ - - - -#define ISRA_EVEN 0x0A /* Interrupt status registers - adapter - even and odd */ -/* Bit 7 - Internal parity error (on adapter's internal bus) */ -/* Bit 6 - Timer interrupt pending */ -/* Bit 5 - Access interrupt (attempt by adapter to access illegal address) */ -/* Bit 4 - Adapter microcode problem (microcode dead-man timer expired) */ -/* Bit 3 - Adapter processor check status */ -/* Bit 2 - Reserved */ -/* Bit 1 - Adapter hardware interrupt mask (prevents internal interrupts) */ -/* Bit 0 - Adapter software interrupt mask (prevents internal software interrupts) */ - -#define ISRA_ODD 0x0B -#define CMD_IN_SRB 0x20 /* Bit 5 - Indicates that you have placed a new - command in the SRB and are ready for the adapter to - process the command. */ -#define RESP_IN_ASB 0x10 /* Bit 4 - Indicates that you have placed a response - (an ASB) in the shared RAM which is available for - the adapter's use. */ -/* Bit 3 - Indicates that you are ready to put an SRB in the shared RAM, but that a previous */ -/* command is still pending. The adapter will then interrupt you when the previous */ -/* command is completed */ -/* Bit 2 - Indicates that you are ready to put an ASB in the shared RAM, but that a previous */ -/* ASB is still pending. The adapter will then interrupt you when the previous ASB */ -/* is copied. */ -#define ARB_FREE 0x2 -#define SSB_FREE 0x1 - -#define TCR_EVEN 0x0C /* Timer control registers - even and odd */ -#define TCR_ODD 0x0D -#define TVR_EVEN 0x0E /* Timer value registers - even and odd */ -#define TVR_ODD 0x0F -#define SRPR_EVEN 0x18 /* Shared RAM paging registers - even and odd */ -#define SRPR_ENABLE_PAGING 0xc0 -#define SRPR_ODD 0x19 /* Not used. */ -#define TOKREAD 0x60 -#define TOKOR 0x40 -#define TOKAND 0x20 -#define TOKWRITE 0x00 - -/* MMIO bits 5-6 select operation */ -/* 00 is used to write to a register */ -/* 01 is used to bitwise AND a byte with a register */ -/* 10 is used to bitwise OR a byte with a register */ -/* 11 is used to read from a register */ - -/* MMIO bits 7-8 select area of interest.. see below */ -/* 00 selects attachment control area. */ -/* 01 is reserved. */ -/* 10 selects adapter identification area A containing the adapter encoded address. */ -/* 11 selects the adapter identification area B containing test patterns. */ - -#define PCCHANNELID 5049434F3631313039393020 -#define MCCHANNELID 4D4152533633583435313820 - -#define ACA_OFFSET 0x1e00 -#define ACA_SET 0x40 -#define ACA_RESET 0x20 -#define ACA_RW 0x00 - -#ifdef ENABLE_PAGING -#define SET_PAGE(x) (isa_writeb((x), \ - ti->mmio + ACA_OFFSET + ACA_RW + SRPR_EVEN)) -#else -#define SET_PAGE(x) -#endif - -typedef enum { IN_PROGRESS, SUCCESS, FAILURE, CLOSED } open_state; - -/* do_tok_int possible values */ -#define FIRST_INT 1 -#define NOT_FIRST 2 - -struct tok_info { - unsigned char irq; - __u32 mmio; - unsigned char hw_address[32]; - unsigned char adapter_type; - unsigned char data_rate; - unsigned char token_release; - unsigned char avail_shared_ram; - unsigned char shared_ram_paging; - unsigned short dhb_size4mb; - unsigned short rbuf_len4; - unsigned short rbuf_cnt4; - unsigned short maxmtu4; - unsigned short dhb_size16mb; - unsigned short rbuf_len16; - unsigned short rbuf_cnt16; - unsigned short maxmtu16; - /* Additions by David Morris */ - unsigned char do_tok_int; - wait_queue_head_t wait_for_tok_int; - wait_queue_head_t wait_for_reset; - unsigned char sram_base; - /* Additions by Peter De Schrijver */ - unsigned char page_mask; /* mask to select RAM page to Map*/ - unsigned char mapped_ram_size; /* size of RAM page */ - __u32 sram; /* Shared memory base address */ - __u32 init_srb; /* Initial System Request Block address */ - __u32 srb; /* System Request Block address */ - __u32 ssb; /* System Status Block address */ - __u32 arb; /* Adapter Request Block address */ - __u32 asb; /* Adapter Status Block address */ - __u8 init_srb_page; - __u8 srb_page; - __u8 ssb_page; - __u8 arb_page; - __u8 asb_page; - unsigned short exsap_station_id; - unsigned short global_int_enable; - struct sk_buff *current_skb; - struct net_device_stats tr_stats; - unsigned char auto_ringspeedsave; - open_state open_status; - unsigned char readlog_pending; - unsigned short adapter_int_enable; /* Adapter-specific int enable */ - struct timer_list tr_timer; - unsigned char ring_speed; - __u32 func_addr; - unsigned int retry_count; - spinlock_t lock; /* SMP protection */ -}; - -/* token ring adapter commands */ -#define DIR_INTERRUPT 0x00 /* struct srb_interrupt */ -#define DIR_MOD_OPEN_PARAMS 0x01 -#define DIR_OPEN_ADAPTER 0x03 /* struct dir_open_adapter */ -#define DIR_CLOSE_ADAPTER 0x04 -#define DIR_SET_GRP_ADDR 0x06 -#define DIR_SET_FUNC_ADDR 0x07 /* struct srb_set_funct_addr */ -#define DIR_READ_LOG 0x08 /* struct srb_read_log */ -#define DLC_OPEN_SAP 0x15 /* struct dlc_open_sap */ -#define DLC_CLOSE_SAP 0x16 -#define DATA_LOST 0x20 /* struct asb_rec */ -#define REC_DATA 0x81 /* struct arb_rec_req */ -#define XMIT_DATA_REQ 0x82 /* struct arb_xmit_req */ -#define DLC_STATUS 0x83 /* struct arb_dlc_status */ -#define RING_STAT_CHANGE 0x84 /* struct dlc_open_sap ??? */ - -/* DIR_OPEN_ADAPTER options */ -#define OPEN_PASS_BCON_MAC 0x0100 -#define NUM_RCV_BUF 2 -#define RCV_BUF_LEN 1024 -#define DHB_LENGTH 2048 -#define NUM_DHB 2 -#define DLC_MAX_SAP 2 -#define DLC_MAX_STA 1 - -/* DLC_OPEN_SAP options */ -#define MAX_I_FIELD 0x0088 -#define SAP_OPEN_IND_SAP 0x04 -#define SAP_OPEN_PRIORITY 0x20 -#define SAP_OPEN_STATION_CNT 0x1 -#define XMIT_DIR_FRAME 0x0A -#define XMIT_UI_FRAME 0x0d -#define XMIT_XID_CMD 0x0e -#define XMIT_TEST_CMD 0x11 - -/* srb close return code */ -#define SIGNAL_LOSS 0x8000 -#define HARD_ERROR 0x4000 -#define XMIT_BEACON 0x1000 -#define LOBE_FAULT 0x0800 -#define AUTO_REMOVAL 0x0400 -#define REMOVE_RECV 0x0100 -#define LOG_OVERFLOW 0x0080 -#define RING_RECOVER 0x0020 - -struct srb_init_response { - unsigned char command; - unsigned char init_status; - unsigned char init_status_2; - unsigned char reserved[3]; - __u16 bring_up_code; - __u16 encoded_address; - __u16 level_address; - __u16 adapter_address; - __u16 parms_address; - __u16 mac_address; -}; - -struct dir_open_adapter { - unsigned char command; - char reserved[7]; - __u16 open_options; - unsigned char node_address[6]; - unsigned char group_address[4]; - unsigned char funct_address[4]; - __u16 num_rcv_buf; - __u16 rcv_buf_len; - __u16 dhb_length; - unsigned char num_dhb; - char reserved2; - unsigned char dlc_max_sap; - unsigned char dlc_max_sta; - unsigned char dlc_max_gsap; - unsigned char dlc_max_gmem; - unsigned char dlc_t1_tick_1; - unsigned char dlc_t2_tick_1; - unsigned char dlc_ti_tick_1; - unsigned char dlc_t1_tick_2; - unsigned char dlc_t2_tick_2; - unsigned char dlc_ti_tick_2; - unsigned char product_id[18]; -}; - -struct srb_open_response { - unsigned char command; - unsigned char reserved1; - unsigned char ret_code; - unsigned char reserved2[3]; - __u16 error_code; - __u16 asb_addr; - __u16 srb_addr; - __u16 arb_addr; - __u16 ssb_addr; -}; - -struct dlc_open_sap { - unsigned char command; - unsigned char reserved1; - unsigned char ret_code; - unsigned char reserved2; - __u16 station_id; - unsigned char timer_t1; - unsigned char timer_t2; - unsigned char timer_ti; - unsigned char maxout; - unsigned char maxin; - unsigned char maxout_incr; - unsigned char max_retry_count; - unsigned char gsap_max_mem; - __u16 max_i_field; - unsigned char sap_value; - unsigned char sap_options; - unsigned char station_count; - unsigned char sap_gsap_mem; - unsigned char gsap[0]; -}; - -struct srb_xmit { - unsigned char command; - unsigned char cmd_corr; - unsigned char ret_code; - unsigned char reserved1; - __u16 station_id; -}; - -struct srb_interrupt { - unsigned char command; - unsigned char cmd_corr; - unsigned char ret_code; -}; - -struct srb_read_log { - unsigned char command; - unsigned char reserved1; - unsigned char ret_code; - unsigned char reserved2; - unsigned char line_errors; - unsigned char internal_errors; - unsigned char burst_errors; - unsigned char A_C_errors; - unsigned char abort_delimiters; - unsigned char reserved3; - unsigned char lost_frames; - unsigned char recv_congest_count; - unsigned char frame_copied_errors; - unsigned char frequency_errors; - unsigned char token_errors; -}; - -struct asb_xmit_resp { - unsigned char command; - unsigned char cmd_corr; - unsigned char ret_code; - unsigned char reserved; - __u16 station_id; - __u16 frame_length; - unsigned char hdr_length; - unsigned char rsap_value; -}; - -struct arb_xmit_req { - unsigned char command; - unsigned char cmd_corr; - unsigned char reserved1[2]; - __u16 station_id; - __u16 dhb_address; -}; - -struct arb_rec_req { - unsigned char command; - unsigned char reserved1[3]; - __u16 station_id; - __u16 rec_buf_addr; - unsigned char lan_hdr_len; - unsigned char dlc_hdr_len; - __u16 frame_len; - unsigned char msg_type; -}; - -struct asb_rec { - unsigned char command; - unsigned char reserved1; - unsigned char ret_code; - unsigned char reserved2; - __u16 station_id; - __u16 rec_buf_addr; -}; - -struct rec_buf { - /* unsigned char reserved1[2]; */ - __u16 buf_ptr; - unsigned char reserved2; - __u16 buf_len; - unsigned char data[0]; -}; - -struct arb_dlc_status { - unsigned char command; - unsigned char reserved1[3]; - __u16 station_id; - __u16 status; - unsigned char frmr_data[5]; - unsigned char access_prio; - unsigned char rem_addr[TR_ALEN]; - unsigned char rsap_value; -}; - -struct arb_ring_stat_change { - unsigned char command; - unsigned char reserved1[5]; - __u16 ring_status; -}; - -struct srb_close_adapter { - unsigned char command; - unsigned char reserved1; - unsigned char ret_code; -}; - -struct srb_set_funct_addr { - unsigned char command; - unsigned char reserved1; - unsigned char ret_code; - unsigned char reserved2[3]; - unsigned char funct_address[4]; -}; - diff --git a/drivers/net/tokenring/smctr.c b/drivers/net/tokenring/smctr.c index 5ae76445b6c6..797e6e485a89 100644 --- a/drivers/net/tokenring/smctr.c +++ b/drivers/net/tokenring/smctr.c @@ -1,7 +1,7 @@ /* * smctr.c: A network driver for the SMC Token Ring Adapters. * - * Written by Jay Schulist + * Written by Jay Schulist * * This software may be used and distributed according to the terms * of the GNU General Public License, incorporated herein by reference. @@ -14,7 +14,7 @@ * - SMC TokenCard SDK. * * Maintainer(s): - * JS Jay Schulist + * JS Jay Schulist * * Changes: * 07102000 JS Fixed a timing problem in smctr_wait_cmd(); @@ -62,7 +62,7 @@ #include "smctr.h" /* Our Stuff */ #include "smctr_firmware.h" /* SMC adapter firmware */ -static char version[] __initdata = KERN_INFO "smctr.c: v1.4 7/12/00 by jschlst@turbolinux.com\n"; +static char version[] __initdata = KERN_INFO "smctr.c: v1.4 7/12/00 by jschlst@samba.org\n"; static const char cardname[] = "smctr"; diff --git a/drivers/net/tokenring/smctr.h b/drivers/net/tokenring/smctr.h index 5d506258982e..5865e55c9c74 100644 --- a/drivers/net/tokenring/smctr.h +++ b/drivers/net/tokenring/smctr.h @@ -1,7 +1,7 @@ /* smctr.h: SMC Token Ring driver header for Linux * * Authors: - * - Jay Schulist + * - Jay Schulist */ #ifndef __LINUX_SMCTR_H diff --git a/drivers/net/tokenring/smctr_firmware.h b/drivers/net/tokenring/smctr_firmware.h index 8bfbc51b1eac..dadf94daa5b1 100644 --- a/drivers/net/tokenring/smctr_firmware.h +++ b/drivers/net/tokenring/smctr_firmware.h @@ -14,7 +14,7 @@ * - This is an 8K binary image. (MCT.BIN v6.3C1 03/01/95) * * Authors: - * - Jay Schulist + * - Jay Schulist */ #include diff --git a/drivers/net/tokenring/tms380tr.c b/drivers/net/tokenring/tms380tr.c index f3ae48a3df60..7a34a2f405e0 100644 --- a/drivers/net/tokenring/tms380tr.c +++ b/drivers/net/tokenring/tms380tr.c @@ -28,7 +28,7 @@ * - Various Madge employees * * Maintainer(s): - * JS Jay Schulist jschlst@turbolinux.com + * JS Jay Schulist jschlst@samba.org * CG Christoph Goos cgoos@syskonnect.de * AF Adam Fritzler mid@auk.cx * MLP Mike Phillips phillim@amtrak.com diff --git a/drivers/net/tulip/21142.c b/drivers/net/tulip/21142.c index 2f33c051c2eb..ac4f48752971 100644 --- a/drivers/net/tulip/21142.c +++ b/drivers/net/tulip/21142.c @@ -100,16 +100,14 @@ void t21142_start_nway(struct net_device *dev) { struct tulip_private *tp = (struct tulip_private *)dev->priv; long ioaddr = dev->base_addr; - int csr14 = ((tp->to_advertise & 0x0780) << 9) | - ((tp->to_advertise&0x0020)<<1) | 0xffbf; - - DPRINTK("ENTER\n"); + int csr14 = ((tp->sym_advertise & 0x0780) << 9) | + ((tp->sym_advertise & 0x0020) << 1) | 0xffbf; dev->if_port = 0; tp->nway = tp->mediasense = 1; tp->nwayset = tp->lpar = 0; if (tp->chip_id == PNIC2) { - tp->csr6 = 0x01000000 | (tp->to_advertise & 0x0040 ? FullDuplex : 0); + tp->csr6 = 0x01000000 | (tp->sym_advertise & 0x0040 ? FullDuplex : 0); return; } if (tulip_debug > 1) @@ -118,7 +116,7 @@ void t21142_start_nway(struct net_device *dev) outl(0x0001, ioaddr + CSR13); udelay(100); outl(csr14, ioaddr + CSR14); - tp->csr6 = 0x82420000 | (tp->to_advertise & 0x0040 ? FullDuplex : 0); + tp->csr6 = 0x82420000 | (tp->sym_advertise & 0x0040 ? FullDuplex : 0); tulip_outl_csr(tp, tp->csr6, CSR6); if (tp->mtable && tp->mtable->csr15dir) { outl(tp->mtable->csr15dir, ioaddr + CSR15); @@ -129,6 +127,24 @@ void t21142_start_nway(struct net_device *dev) } +void pnic2_lnk_change(struct net_device *dev, int csr5) +{ + struct tulip_private *tp = (struct tulip_private *)dev->priv; + long ioaddr = dev->base_addr; + int csr12 = inl(ioaddr + CSR12); + + if (tulip_debug > 1) + printk(KERN_INFO"%s: PNIC-2 link status changed, CSR5/12/14 %8.8x" + " %8.8x, %8.8x.\n", + dev->name, csr12, csr5, (int)inl(ioaddr + CSR14)); + dev->if_port = 5; + tp->lpar = csr12 >> 16; + tp->nwayset = 1; + tp->csr6 = 0x01000000 | (tp->csr6 & 0xffff); + outl(tp->csr6, ioaddr + CSR6); + +} + void t21142_lnk_change(struct net_device *dev, int csr5) { struct tulip_private *tp = (struct tulip_private *)dev->priv; @@ -142,7 +158,7 @@ void t21142_lnk_change(struct net_device *dev, int csr5) /* If NWay finished and we have a negotiated partner capability. */ if (tp->nway && !tp->nwayset && (csr12 & 0x7000) == 0x5000) { int setup_done = 0; - int negotiated = tp->to_advertise & (csr12 >> 16); + int negotiated = tp->sym_advertise & (csr12 >> 16); tp->lpar = csr12 >> 16; tp->nwayset = 1; if (negotiated & 0x0100) dev->if_port = 5; @@ -151,7 +167,7 @@ void t21142_lnk_change(struct net_device *dev, int csr5) else if (negotiated & 0x0020) dev->if_port = 0; else { tp->nwayset = 0; - if ((csr12 & 2) == 0 && (tp->to_advertise & 0x0180)) + if ((csr12 & 2) == 0 && (tp->sym_advertise & 0x0180)) dev->if_port = 3; } tp->full_duplex = (tulip_media_cap[dev->if_port] & MediaAlwaysFD) ? 1:0; @@ -160,7 +176,7 @@ void t21142_lnk_change(struct net_device *dev, int csr5) if (tp->nwayset) printk(KERN_INFO "%s: Switching to %s based on link " "negotiation %4.4x & %4.4x = %4.4x.\n", - dev->name, medianame[dev->if_port], tp->to_advertise, + dev->name, medianame[dev->if_port], tp->sym_advertise, tp->lpar, negotiated); else printk(KERN_INFO "%s: Autonegotiation failed, using %s," @@ -173,7 +189,7 @@ void t21142_lnk_change(struct net_device *dev, int csr5) for (i = 0; i < tp->mtable->leafcount; i++) if (tp->mtable->mleaf[i].media == dev->if_port) { tp->cur_index = i; - tulip_select_media(dev, 0); + tulip_select_media(dev, 1); setup_done = 1; break; } diff --git a/drivers/net/tulip/ChangeLog b/drivers/net/tulip/ChangeLog index 6adb876c0066..e8012087ce7d 100644 --- a/drivers/net/tulip/ChangeLog +++ b/drivers/net/tulip/ChangeLog @@ -1,3 +1,163 @@ +2001-05-13 Jeff Garzik + + * tulip_core.c: Remove HAS_PCI_MWI flag from Comet, untested. + +2001-05-12 Jeff Garzik + + * tulip_core.c, tulip.h: Remove Conexant PCI id, no chip + docs are available to fix problems with support. + +2001-05-12 Jeff Garzik + + * tulip_core.c (tulip_init_one): Do not call + unregister_netdev in error cleanup. Remnant of old + usage of init_etherdev. + +2001-05-12 Jeff Garzik + + * media.c (tulip_find_mii): Simple write the updated BMCR + twice, as it seems the best thing to do for both broken and + sane chips. + If the mii_advert value, as read from MII_ADVERTISE, is zero, + then generate a value we should advertise from the capability + bits in BMSR. + Fill in tp->advertising for all cases. + Just to be safe, clear all unwanted bits. + +2001-05-12 Jeff Garzik + + * tulip_core.c (private_ioctl): Fill in tp->advertising + when advertising value is changed by the user. + +2001-05-12 Jeff Garzik + + * tulip_core.c: Mark Comet chips as needed the updated MWI + csr0 configuration. + +2001-05-12 Jeff Garzik + + * media.c, tulip_core.c: Move MII scan into + from inlined inside tulip_init_one to new function + tulip_find_mii in media.c. + +2001-05-12 Jeff Garzik + + * media.c (tulip_check_duplex): + Only restart Rx/Tx engines if they are active + (and csr6 changes) + +2001-05-12 Jeff Garzik + + * tulip_core.c (tulip_mwi_config): + Clamp values read from PCI cache line size register to + values acceptable to tulip chip. Done for safety and + -almost- certainly unneeded. + +2001-05-11 Jeff Garzik + + * tulip_core.c (tulip_init_one): + Instead of unconditionally enabling autonegotiation, disable + autonegotiation if not using the default port. Further, + flip the nway bit immediately, and then update the + speed/duplex in a separate MII transaction. We do this + because some boards require that nway be disabled separately, + before media selection is forced. + + TODO: Investigate if we can simply write the same value + to BMCR twice, to avoid setting unnecessarily changing + phy settings. + +2001-05-11 Jeff Garzik + + * tulip.h, tulip_core.c: If HAS_PCI_MWI is set for a + given chip, adjust the csr0 values not according to + provided values but according to system cache line size. + Currently cache alignment is matched as closely to cache + line size as possible. Currently programmable burst limit + is set (ie. never unlimited), and always equal to cache + alignment and system cache size. Currently MWI bit is set + only if the MWI bit is present in the PCI command register. + +2001-05-11 Jeff Garzik + + * media.c (tulip_select_media): + For media types 1 and 3, only use the provided eeprom + advertising value if it is non-zero. + (tulip_check_duplex): + Do not exit ASAP if full_duplex_lock is set. This + ensures that the csr6 value is written if an update + is needed. + +2001-05-10 Jeff Garzik + + Merge PNIC-II-specific stuff from Becker's tulip.c: + + * tulip.h, 21142.c (pnic2_lnk_change): new function + * tulip_core.c (tulip_init_one): use it + + * tulip_core.c (tulip_tx_timeout): Add specific + debugging for PNIC2. + +2001-05-10 Jeff Garzik + + * tulip_core.c (tulip_init_one): Print out + tulip%d instead of PCI device number, for + consistency. + +2001-05-10 Jeff Garzik + + * Merge changes from Becker's tulip.c: + Fix bugs in ioctl. + Fix several bugs by distinguishing between MII + and SYM advertising values. + Set CSR14 autonegotiation bit for media types 2 and 4, + where the SIA CSR setup values are not provided. + +2001-05-10 Jeff Garzik + + * media.c (tulip_select_media): Only update MII + advertising value if startup arg < 2. + + * tulip.h: Do not enable CSR13/14/15 autoconfiguration + for 21041. + + * tulip_core.c: + 21041: add specific code for reset, and do not set CAC bit + When resetting media, for media table type 11 media, pass + value 2 as 'startup' arg to select_media, to avoid updating + MII advertising value. + +2001-05-10 Jeff Garzik + + * pnic.c (pnic_check_duplex): remove + pnic.c (pnic_lnk_change, pnic_timer): use + tulip_check_duplex not pnic_check_duplex. + + * media.c (tulip_check_duplex): + Clean up to use symbolic names instead of numeric constants. + Set TxThreshold mode as necessary as well as clearing it. + Update csr6 if csr6 changes, not simply if duplex changes. + + (found by Manfred Spraul) + +2001-05-10 Jeff Garzik + + * 21142.c, eeprom.c, tulip.h, tulip_core.c: + Remove DPRINTK as another, better method of + debug message printing is available. + +2001-05-09 Jeff Garzik + + * 21142.c (t21142_lnk_change): Pass arg startup==1 + to tulip_select_media, in order to force csr13 to be + zeroed out prior to going to full duplex mode. Fixes + autonegotiation on a quad-port Znyx card. + (from Stephen Dengler) + +2001-05-09 Russell King + + * interrupt.c: Better PCI bus error reporting. + 2001-04-03 Jeff Garzik * tulip_core.c: Now that dev->name is only available late @@ -29,7 +189,7 @@ the following defines existed. These defines were never used by normal users in practice: TULIP_FULL_DUPLEX, TULIP_DEFAULT_MEDIA, and TULIP_NO_MEDIA_SWITCH. - + * tulip.h, eeprom.c: Move EE_* constants from tulip.h to eeprom.c. * tulip.h, media.c: Move MDIO_* constants from tulip.h to media.c. diff --git a/drivers/net/tulip/eeprom.c b/drivers/net/tulip/eeprom.c index 556f07adfb25..3bee3b574fc2 100644 --- a/drivers/net/tulip/eeprom.c +++ b/drivers/net/tulip/eeprom.c @@ -167,7 +167,8 @@ subsequent_board: /* there is no phy information, don't even try to build mtable */ if (count == 0) { - DPRINTK("no phy info, aborting mtable build\n"); + if (tulip_debug > 0) + printk(KERN_WARNING "%s: no phy info, aborting mtable build\n", dev->name); return; } @@ -259,7 +260,7 @@ subsequent_board: leaf->type); } if (new_advertise) - tp->to_advertise = new_advertise; + tp->sym_advertise = new_advertise; } } /* Reading a serial EEPROM is a "bit" grungy, but we work our way through:->.*/ diff --git a/drivers/net/tulip/media.c b/drivers/net/tulip/media.c index 89f6b0137174..4621164d7d8a 100644 --- a/drivers/net/tulip/media.c +++ b/drivers/net/tulip/media.c @@ -14,6 +14,10 @@ */ +#include +#include +#include +#include #include "tulip.h" @@ -228,7 +232,7 @@ void tulip_select_media(struct net_device *dev, int startup) outl(csr13val, ioaddr + CSR13); } else { csr13val = 1; - csr14val = 0x0003FF7F; + csr14val = 0x0003FFFF; csr15dir = (setup[0]<<16) | 0x0008; csr15val = (setup[1]<<16) | 0x0008; if (dev->if_port <= 4) @@ -253,8 +257,7 @@ void tulip_select_media(struct net_device *dev, int startup) case 1: case 3: { int phy_num = p[0]; int init_length = p[1]; - u16 *misc_info; - u16 to_advertise; + u16 *misc_info, tmp_info; dev->if_port = 11; new_csr6 = 0x020E0000; @@ -281,13 +284,17 @@ void tulip_select_media(struct net_device *dev, int startup) for (i = 0; i < init_length; i++) outl(init_sequence[i], ioaddr + CSR12); } - to_advertise = (get_u16(&misc_info[1]) & tp->to_advertise) | 1; - tp->advertising[phy_num] = to_advertise; - if (tulip_debug > 1) - printk(KERN_DEBUG "%s: Advertising %4.4x on PHY %d (%d).\n", - dev->name, to_advertise, phy_num, tp->phys[phy_num]); - /* Bogus: put in by a committee? */ - tulip_mdio_write(dev, tp->phys[phy_num], 4, to_advertise); + tmp_info = get_u16(&misc_info[1]); + if (tmp_info) + tp->advertising[phy_num] = tmp_info | 1; + if (tmp_info && startup < 2) { + if (tp->mii_advertise == 0) + tp->mii_advertise = tp->advertising[phy_num]; + if (tulip_debug > 1) + printk(KERN_DEBUG "%s: Advertising %4.4x on MII %d.\n", + dev->name, tp->mii_advertise, tp->phys[phy_num]); + tulip_mdio_write(dev, tp->phys[phy_num], 4, tp->mii_advertise); + } break; } case 5: case 6: { @@ -397,52 +404,164 @@ void tulip_select_media(struct net_device *dev, int startup) } /* - Check the MII negotiated duplex, and change the CSR6 setting if + Check the MII negotiated duplex and change the CSR6 setting if required. Return 0 if everything is OK. Return < 0 if the transceiver is missing or has no link beat. */ int tulip_check_duplex(struct net_device *dev) { - struct tulip_private *tp = (struct tulip_private *)dev->priv; - int mii_reg1, mii_reg5, negotiated, duplex; + long ioaddr = dev->base_addr; + struct tulip_private *tp = dev->priv; + unsigned int bmsr, lpa, negotiated, new_csr6; - if (tp->full_duplex_lock) - return 0; - mii_reg1 = tulip_mdio_read(dev, tp->phys[0], 1); - mii_reg5 = tulip_mdio_read(dev, tp->phys[0], 5); + bmsr = tulip_mdio_read(dev, tp->phys[0], MII_BMSR); + lpa = tulip_mdio_read(dev, tp->phys[0], MII_LPA); if (tulip_debug > 1) printk(KERN_INFO "%s: MII status %4.4x, Link partner report " - "%4.4x.\n", dev->name, mii_reg1, mii_reg5); - if (mii_reg1 == 0xffff) + "%4.4x.\n", dev->name, bmsr, lpa); + if (bmsr == 0xffff) return -2; - if ((mii_reg1 & 0x0004) == 0) { - int new_reg1 = tulip_mdio_read(dev, tp->phys[0], 1); - if ((new_reg1 & 0x0004) == 0) { + if ((bmsr & BMSR_LSTATUS) == 0) { + int new_bmsr = tulip_mdio_read(dev, tp->phys[0], MII_BMSR); + if ((new_bmsr & BMSR_LSTATUS) == 0) { if (tulip_debug > 1) printk(KERN_INFO "%s: No link beat on the MII interface," - " status %4.4x.\n", dev->name, new_reg1); + " status %4.4x.\n", dev->name, new_bmsr); return -1; } } - negotiated = mii_reg5 & tp->advertising[0]; - duplex = ((negotiated & 0x0300) == 0x0100 - || (negotiated & 0x00C0) == 0x0040); - /* 100baseTx-FD or 10T-FD, but not 100-HD */ - if (tp->full_duplex != duplex) { - tp->full_duplex = duplex; - if (negotiated & 0x038) /* 100mbps. */ - tp->csr6 &= ~0x00400000; - if (tp->full_duplex) tp->csr6 |= 0x0200; - else tp->csr6 &= ~0x0200; - tulip_restart_rxtx(tp, tp->csr6); + negotiated = lpa & tp->advertising[0]; + tp->full_duplex = mii_duplex(tp->full_duplex_lock, negotiated); + + new_csr6 = tp->csr6; + + if (negotiated & LPA_100) new_csr6 &= ~TxThreshold; + else new_csr6 |= TxThreshold; + if (tp->full_duplex) new_csr6 |= FullDuplex; + else new_csr6 &= ~FullDuplex; + + if (new_csr6 != tp->csr6) { + if (inl(ioaddr + CSR6) & (csr6_st | csr6_sr)) + tulip_restart_rxtx(tp, new_csr6); + else + outl(new_csr6, ioaddr + CSR6); + tp->csr6 = new_csr6; + if (tulip_debug > 0) printk(KERN_INFO "%s: Setting %s-duplex based on MII" "#%d link partner capability of %4.4x.\n", dev->name, tp->full_duplex ? "full" : "half", - tp->phys[0], mii_reg5); + tp->phys[0], lpa); return 1; } + return 0; } +void __devinit tulip_find_mii (struct net_device *dev, int board_idx) +{ + struct tulip_private *tp = dev->priv; + int phyn, phy_idx = 0; + int mii_reg0; + int mii_advert; + unsigned int to_advert, new_bmcr, ane_switch; + + /* Find the connected MII xcvrs. + Doing this in open() would allow detecting external xcvrs later, + but takes much time. */ + for (phyn = 1; phyn <= 32 && phy_idx < sizeof (tp->phys); phyn++) { + int phy = phyn & 0x1f; + int mii_status = tulip_mdio_read (dev, phy, MII_BMSR); + if ((mii_status & 0x8301) == 0x8001 || + ((mii_status & BMSR_100BASE4) == 0 + && (mii_status & 0x7800) != 0)) { + /* preserve Becker logic, gain indentation level */ + } else { + continue; + } + + mii_reg0 = tulip_mdio_read (dev, phy, MII_BMCR); + mii_advert = tulip_mdio_read (dev, phy, MII_ADVERTISE); + ane_switch = 0; + + /* if not advertising at all, gen an + * advertising value from the capability + * bits in BMSR + */ + if ((mii_advert & ADVERTISE_ALL) == 0) { + unsigned int tmpadv = tulip_mdio_read (dev, phy, MII_BMSR); + mii_advert = ((tmpadv >> 6) & 0x3e0) | 1; + } + + if (tp->mii_advertise) { + tp->advertising[phy_idx] = + to_advert = tp->mii_advertise; + } else if (tp->advertising[phy_idx]) { + to_advert = tp->advertising[phy_idx]; + } else { + tp->advertising[phy_idx] = + tp->mii_advertise = + to_advert = mii_advert; + } + + tp->phys[phy_idx++] = phy; + + printk (KERN_INFO "tulip%d: MII transceiver #%d " + "config %4.4x status %4.4x advertising %4.4x.\n", + board_idx, phy, mii_reg0, mii_status, mii_advert); + + /* Fixup for DLink with miswired PHY. */ + if (mii_advert != to_advert) { + printk (KERN_DEBUG "tulip%d: Advertising %4.4x on PHY %d," + " previously advertising %4.4x.\n", + board_idx, to_advert, phy, mii_advert); + tulip_mdio_write (dev, phy, 4, to_advert); + } + + /* Enable autonegotiation: some boards default to off. */ + if (tp->default_port == 0) { + new_bmcr = mii_reg0 | BMCR_ANENABLE; + if (new_bmcr != mii_reg0) { + new_bmcr |= BMCR_ANRESTART; + ane_switch = 1; + } + } + /* ...or disable nway, if forcing media */ + else { + new_bmcr = mii_reg0 & ~BMCR_ANENABLE; + if (new_bmcr != mii_reg0) + ane_switch = 1; + } + + /* clear out bits we never want at this point */ + new_bmcr &= ~(BMCR_CTST | BMCR_FULLDPLX | BMCR_ISOLATE | + BMCR_PDOWN | BMCR_SPEED100 | BMCR_LOOPBACK | + BMCR_RESET); + + if (tp->full_duplex) + new_bmcr |= BMCR_FULLDPLX; + if (tulip_media_cap[tp->default_port] & MediaIs100) + new_bmcr |= BMCR_SPEED100; + + if (new_bmcr != mii_reg0) { + /* some phys need the ANE switch to + * happen before forced media settings + * will "take." However, we write the + * same value twice in order not to + * confuse the sane phys. + */ + if (ane_switch) { + tulip_mdio_write (dev, phy, MII_BMCR, new_bmcr); + udelay (10); + } + tulip_mdio_write (dev, phy, MII_BMCR, new_bmcr); + } + } + tp->mii_cnt = phy_idx; + if (tp->mtable && tp->mtable->has_mii && phy_idx == 0) { + printk (KERN_INFO "tulip%d: ***WARNING***: No MII transceiver found!\n", + board_idx); + tp->phys[0] = 1; + } +} diff --git a/drivers/net/tulip/pnic.c b/drivers/net/tulip/pnic.c index 119b612c447b..61d439ed9143 100644 --- a/drivers/net/tulip/pnic.c +++ b/drivers/net/tulip/pnic.c @@ -51,62 +51,6 @@ void pnic_do_nway(struct net_device *dev) } } -/* Modified version of tulip_check_duplex: - * Always update the 100mbps bit, even if the - * full duplex bit didn't change. - * Manfred Spraul - */ -int pnic_check_duplex(struct net_device *dev) -{ - struct tulip_private *tp = (struct tulip_private *)dev->priv; - int mii_reg1, mii_reg5, negotiated, duplex; - int new_csr6; - - mii_reg1 = tulip_mdio_read(dev, tp->phys[0], 1); - mii_reg5 = tulip_mdio_read(dev, tp->phys[0], 5); - if (tulip_debug > 1) - printk(KERN_INFO "%s: MII status %4.4x, Link partner report " - "%4.4x.\n", dev->name, mii_reg1, mii_reg5); - if (mii_reg1 == 0xffff) - return -2; - if ((mii_reg1 & 0x0004) == 0) { - int new_reg1 = tulip_mdio_read(dev, tp->phys[0], 1); - if ((new_reg1 & 0x0004) == 0) { - if (tulip_debug > 1) - printk(KERN_INFO "%s: No link beat on the MII interface," - " status %4.4x.\n", dev->name, new_reg1); - return -1; - } - } - negotiated = mii_reg5 & tp->advertising[0]; - /* 100baseTx-FD or 10T-FD, but not 100-HD */ - duplex = ((negotiated & 0x0300) == 0x0100 - || (negotiated & 0x00C0) == 0x0040) || - tp->full_duplex_lock; - - new_csr6 = tp->csr6; - if (negotiated & 0x0380) /* 100mbps. */ - new_csr6 &= ~0x00400000; - else - new_csr6 |= 0x00400000; - if (duplex) - new_csr6 |= 0x0200; - else - new_csr6 &= ~0x0200; - if (new_csr6 != tp->csr6) { - tp->full_duplex = duplex; - tp->csr6 = new_csr6; - if (tulip_debug > 0) - printk(KERN_INFO "%s: Setting %s-duplex based on MII" - "#%d link partner capability of %4.4x.\n", - dev->name, tp->full_duplex ? "full" : "half", - tp->phys[0], mii_reg5); - tulip_restart_rxtx(tp, tp->csr6); - return 1; - } - return 0; -} - void pnic_lnk_change(struct net_device *dev, int csr5) { struct tulip_private *tp = (struct tulip_private *)dev->priv; @@ -133,7 +77,7 @@ void pnic_lnk_change(struct net_device *dev, int csr5) } else if (inl(ioaddr + CSR5) & TPLnkPass) { if (tulip_media_cap[dev->if_port] & MediaIsMII) { spin_lock(&tp->lock); - pnic_check_duplex(dev); + tulip_check_duplex(dev); spin_unlock(&tp->lock); } else { pnic_do_nway(dev); @@ -162,7 +106,7 @@ void pnic_timer(unsigned long data) if (tulip_media_cap[dev->if_port] & MediaIsMII) { spin_lock_irq(&tp->lock); - if (pnic_check_duplex(dev) > 0) + if (tulip_check_duplex(dev) > 0) next_tick = 3*HZ; spin_unlock_irq(&tp->lock); } else { diff --git a/drivers/net/tulip/tulip.h b/drivers/net/tulip/tulip.h index 5d5456549e80..9158a21fe02b 100644 --- a/drivers/net/tulip/tulip.h +++ b/drivers/net/tulip/tulip.h @@ -27,17 +27,7 @@ /* undefine, or define to various debugging levels (>4 == obscene levels) */ -#undef TULIP_DEBUG - - -#ifdef TULIP_DEBUG -/* note: prints function name for you */ -#define DPRINTK(fmt, args...) printk(KERN_DEBUG "%s: " fmt, __FUNCTION__ , ## args) -#else -#define DPRINTK(fmt, args...) -#endif - - +#define TULIP_DEBUG 1 struct tulip_chip_table { @@ -62,6 +52,7 @@ enum tbl_flag { IS_ASIX = 0x0200, HAS_8023X = 0x0400, COMET_MAC_ADDR = 0x0800, + HAS_PCI_MWI = 0x1000, }; @@ -83,7 +74,6 @@ enum chips { COMPEX9881, I21145, DM910X, - CONEXANT, }; @@ -145,8 +135,9 @@ enum status_bits { }; -enum tulip_rx_modes { - FullDuplex = 0x0200, +enum tulip_mode_bits { + TxThreshold = (1 << 22), + FullDuplex = (1 << 9), AcceptBroadcast = 0x0100, AcceptAllMulticast = 0x0080, AcceptAllPhys = 0x0040, @@ -154,6 +145,15 @@ enum tulip_rx_modes { }; +enum tulip_busconfig_bits { + MWI = (1 << 24), + MRL = (1 << 23), + MRM = (1 << 21), + CALShift = 14, + BurstLenShift = 8, +}; + + /* The Tulip Rx and Tx buffer descriptors. */ struct tulip_rx_desc { s32 status; @@ -184,8 +184,8 @@ enum t21041_csr13_bits { csr13_cac = (1<<2), /* CSR13/14/15 autoconfiguration */ csr13_srl = (1<<0), /* When reset, resets all SIA functions, machines */ - csr13_mask_auibnc = (csr13_eng | csr13_aui | csr13_cac | csr13_srl), - csr13_mask_10bt = (csr13_eng | csr13_cac | csr13_srl), + csr13_mask_auibnc = (csr13_eng | csr13_aui | csr13_srl), + csr13_mask_10bt = (csr13_eng | csr13_srl), }; enum t21143_csr6_bits { @@ -255,6 +255,18 @@ enum t21143_csr6_bits { #define PKT_BUF_SZ 1536 /* Size of each temporary Rx buffer. */ +#define TULIP_MIN_CACHE_LINE 8 /* in units of 32-bit words */ + +#if defined(__sparc__) || defined(__hppa__) +/* The UltraSparc PCI controllers will disconnect at every 64-byte + * crossing anyways so it makes no sense to tell Tulip to burst + * any more than that. + */ +#define TULIP_MAX_CACHE_LINE 16 /* in units of 32-bit words */ +#else +#define TULIP_MAX_CACHE_LINE 32 /* in units of 32-bit words */ +#endif + /* Ring-wrap flag in length field, use for last ring entry. 0x01000000 means chain on buffer2 address, @@ -345,7 +357,7 @@ struct tulip_private { unsigned int csr6; /* Current CSR6 control settings. */ unsigned char eeprom[EEPROM_SIZE]; /* Serial EEPROM contents. */ void (*link_change) (struct net_device * dev, int csr5); - u16 to_advertise; /* NWay capabilities advertised. */ + u16 sym_advertise, mii_advertise; /* NWay capabilities advertised. */ u16 lpar; /* 21143 Link partner ability. */ u16 advertising[4]; signed char phys[4], mii_cnt; /* MII device addresses. */ @@ -375,6 +387,7 @@ extern u16 t21142_csr14[]; void t21142_timer(unsigned long data); void t21142_start_nway(struct net_device *dev); void t21142_lnk_change(struct net_device *dev, int csr5); +void pnic2_lnk_change(struct net_device *dev, int csr5); /* eeprom.c */ void tulip_parse_eeprom(struct net_device *dev); @@ -390,6 +403,7 @@ int tulip_mdio_read(struct net_device *dev, int phy_id, int location); void tulip_mdio_write(struct net_device *dev, int phy_id, int location, int value); void tulip_select_media(struct net_device *dev, int startup); int tulip_check_duplex(struct net_device *dev); +void tulip_find_mii (struct net_device *dev, int board_idx); /* pnic.c */ void pnic_do_nway(struct net_device *dev); diff --git a/drivers/net/tulip/tulip_core.c b/drivers/net/tulip/tulip_core.c index 9f22c9b4d2ef..d25f9f901dee 100644 --- a/drivers/net/tulip/tulip_core.c +++ b/drivers/net/tulip/tulip_core.c @@ -20,10 +20,11 @@ #include #include #include +#include #include static char version[] __devinitdata = - "Linux Tulip driver version 0.9.14e (April 20, 2001)\n"; + "Linux Tulip driver version 0.9.15-pre1 (May 12, 2001)\n"; /* A few user-configurable values. */ @@ -127,12 +128,12 @@ struct tulip_chip_table tulip_tbl[] = { /* DC21140 */ { "Digital DS21140 Tulip", 128, 0x0001ebef, - HAS_MII | HAS_MEDIA_TABLE | CSR12_IN_SROM, tulip_timer }, + HAS_MII | HAS_MEDIA_TABLE | CSR12_IN_SROM | HAS_PCI_MWI, tulip_timer }, /* DC21142, DC21143 */ { "Digital DS21143 Tulip", 128, 0x0801fbff, HAS_MII | HAS_MEDIA_TABLE | ALWAYS_CHECK_MII | HAS_ACPI | HAS_NWAY - | HAS_INTR_MITIGATION, t21142_timer }, + | HAS_INTR_MITIGATION | HAS_PCI_MWI, t21142_timer }, /* LC82C168 */ { "Lite-On 82c168 PNIC", 256, 0x0001fbef, @@ -152,11 +153,12 @@ struct tulip_chip_table tulip_tbl[] = { /* AX88140 */ { "ASIX AX88140", 128, 0x0001fbff, - HAS_MII | HAS_MEDIA_TABLE | CSR12_IN_SROM | MC_HASH_ONLY | IS_ASIX, tulip_timer }, + HAS_MII | HAS_MEDIA_TABLE | CSR12_IN_SROM | MC_HASH_ONLY + | IS_ASIX, tulip_timer }, /* PNIC2 */ { "Lite-On PNIC-II", 256, 0x0801fbff, - HAS_MII | HAS_NWAY | HAS_8023X, t21142_timer }, + HAS_MII | HAS_NWAY | HAS_8023X | HAS_PCI_MWI, t21142_timer }, /* COMET */ { "ADMtek Comet", 256, 0x0001abef, @@ -168,18 +170,13 @@ struct tulip_chip_table tulip_tbl[] = { /* I21145 */ { "Intel DS21145 Tulip", 128, 0x0801fbff, - HAS_MII | HAS_MEDIA_TABLE | ALWAYS_CHECK_MII | HAS_ACPI | HAS_NWAY, - t21142_timer }, + HAS_MII | HAS_MEDIA_TABLE | ALWAYS_CHECK_MII | HAS_ACPI + | HAS_NWAY | HAS_PCI_MWI, t21142_timer }, /* DM910X */ { "Davicom DM9102/DM9102A", 128, 0x0001ebef, HAS_MII | HAS_MEDIA_TABLE | CSR12_IN_SROM | HAS_ACPI, tulip_timer }, - - /* CONEXANT */ - { "Conexant LANfinity", 0x100, 0x0001ebef, - HAS_MII | HAS_ACPI, - tulip_timer }, }; @@ -208,7 +205,6 @@ static struct pci_device_id tulip_pci_tbl[] __devinitdata = { { 0x1113, 0x1216, PCI_ANY_ID, PCI_ANY_ID, 0, 0, COMET }, { 0x1113, 0x1217, PCI_ANY_ID, PCI_ANY_ID, 0, 0, MX98715 }, { 0x1113, 0x9511, PCI_ANY_ID, PCI_ANY_ID, 0, 0, COMET }, - { 0x14f1, 0x1803, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CONEXANT }, { } /* terminate list */ }; MODULE_DEVICE_TABLE(pci, tulip_pci_tbl); @@ -269,8 +265,6 @@ static void tulip_up(struct net_device *dev) int next_tick = 3*HZ; int i; - DPRINTK("ENTER\n"); - /* Wake the chip from sleep/snooze mode. */ tulip_set_power_state (tp, 0, 0); @@ -379,10 +373,30 @@ media_picked: tp->csr6 = 0; tp->cur_index = i; tp->nwayset = 0; - if (dev->if_port == 0 && tp->chip_id == DC21041) - tp->nway = 1; - if (dev->if_port == 0 && tp->chip_id == DC21142) { + if (dev->if_port) { + if (tp->chip_id == DC21143 && + (tulip_media_cap[dev->if_port] & MediaIsMII)) { + /* We must reset the media CSRs when we force-select MII mode. */ + outl(0x0000, ioaddr + CSR13); + outl(0x0000, ioaddr + CSR14); + outl(0x0008, ioaddr + CSR15); + } + tulip_select_media(dev, 1); + } else if (tp->chip_id == DC21041) { + dev->if_port = 0; + tp->nway = tp->mediasense = 1; + tp->nwayset = tp->lpar = 0; + outl(0x00000000, ioaddr + CSR13); + outl(0xFFFFFFFF, ioaddr + CSR14); + outl(0x00000008, ioaddr + CSR15); /* Listen on AUI also. */ + tp->csr6 = 0x80020000; + if (tp->sym_advertise & 0x0040) + tp->csr6 |= FullDuplex; + outl(tp->csr6, ioaddr + CSR6); + outl(0x0000EF01, ioaddr + CSR13); + + } else if (tp->chip_id == DC21142) { if (tp->mii_cnt) { tulip_select_media(dev, 1); if (tulip_debug > 1) @@ -424,12 +438,6 @@ media_picked: tp->csr6 = 0x01a80200; outl(0x0f370000 | inw(ioaddr + 0x80), ioaddr + 0x80); outl(0x11000 | inw(ioaddr + 0xa0), ioaddr + 0xa0); - } else if (tp->chip_id == DC21143 && - tulip_media_cap[dev->if_port] & MediaIsMII) { - /* We must reset the media CSRs when we force-select MII mode. */ - outl(0x0000, ioaddr + CSR13); - outl(0x0000, ioaddr + CSR14); - outl(0x0008, ioaddr + CSR15); } else if (tp->chip_id == COMET) { /* Enable automatic Tx underrun recovery. */ outl(inl(ioaddr + 0x88) | 1, ioaddr + 0x88); @@ -492,8 +500,6 @@ static void tulip_tx_timeout(struct net_device *dev) long ioaddr = dev->base_addr; unsigned long flags; - DPRINTK("ENTER\n"); - spin_lock_irqsave (&tp->lock, flags); if (tulip_media_cap[dev->if_port] & MediaIsMII) { @@ -549,6 +555,11 @@ static void tulip_tx_timeout(struct net_device *dev) printk(KERN_WARNING "%s: transmit timed out, switching to %s " "media.\n", dev->name, medianame[dev->if_port]); } + } else if (tp->chip_id == PNIC2) { + printk(KERN_WARNING "%s: PNIC2 transmit timed out, status %8.8x, " + "CSR6/7 %8.8x / %8.8x CSR12 %8.8x, resetting...\n", + dev->name, (int)inl(ioaddr + CSR5), (int)inl(ioaddr + CSR6), + (int)inl(ioaddr + CSR7), (int)inl(ioaddr + CSR12)); } else { printk(KERN_WARNING "%s: Transmit timed out, status %8.8x, CSR12 " "%8.8x, resetting...\n", @@ -603,8 +614,6 @@ static void tulip_init_ring(struct net_device *dev) struct tulip_private *tp = (struct tulip_private *)dev->priv; int i; - DPRINTK("ENTER\n"); - tp->cur_rx = tp->cur_tx = 0; tp->dirty_rx = tp->dirty_tx = 0; tp->susp_rx = 0; @@ -809,7 +818,8 @@ static int private_ioctl (struct net_device *dev, struct ifreq *rq, int cmd) struct tulip_private *tp = dev->priv; long ioaddr = dev->base_addr; u16 *data = (u16 *) & rq->ifr_data; - int phy = tp->phys[0] & 0x1f; + const unsigned int phy_idx = 0; + int phy = tp->phys[phy_idx] & 0x1f; unsigned int regnum = data[1]; switch (cmd) { @@ -828,26 +838,31 @@ static int private_ioctl (struct net_device *dev, struct ifreq *rq, int cmd) int csr14 = inl (ioaddr + CSR14); switch (regnum) { case 0: - data[3] = (csr14 << 5) & 0x1000; + if (((csr14<<5) & 0x1000) || + (dev->if_port == 5 && tp->nwayset)) + data[3] = 0x1000; + else + data[3] = (tulip_media_cap[dev->if_port]&MediaIs100 ? 0x2000 : 0) + | (tulip_media_cap[dev->if_port]&MediaIsFD ? 0x0100 : 0); break; case 1: - data[3] = - 0x7848 + - ((csr12 & 0x7000) == 0x5000 ? 0x20 : 0) + - (csr12 & 0x06 ? 0x04 : 0); + data[3] = + 0x1848 + + ((csr12&0x7000) == 0x5000 ? 0x20 : 0) + + ((csr12&0x06) == 6 ? 0 : 4); + if (tp->chip_id != DC21041) + data[3] |= 0x6048; break; case 4: - data[3] = - ((csr14 >> 9) & 0x07C0) + - ((inl (ioaddr + CSR6) >> 3) & 0x0040) + - ((csr14 >> 1) & 0x20) + 1; - break; - case 5: - data[3] = csr12 >> 16; - break; - default: - data[3] = 0; + /* Advertised value, bogus 10baseTx-FD value from CSR6. */ + data[3] = + ((inl(ioaddr + CSR6) >> 3) & 0x0040) + + ((csr14 >> 1) & 0x20) + 1; + if (tp->chip_id != DC21041) + data[3] |= ((csr14 >> 9) & 0x03C0); break; + case 5: data[3] = tp->lpar; break; + default: data[3] = 0; break; } } else { data[3] = tulip_mdio_read (dev, data[0] & 0x1f, regnum); @@ -867,7 +882,8 @@ static int private_ioctl (struct net_device *dev, struct ifreq *rq, int cmd) tp->full_duplex = (value & 0x0100) ? 1 : 0; break; case 4: - tp->to_advertise = data[2]; + tp->advertising[phy_idx] = + tp->mii_advertise = data[2]; break; } } @@ -877,7 +893,7 @@ static int private_ioctl (struct net_device *dev, struct ifreq *rq, int cmd) if ((value & 0x1200) == 0x1200) t21142_start_nway (dev); } else if (regnum == 4) - tp->to_advertise = value; + tp->sym_advertise = value; } else { tulip_mdio_write (dev, data[0] & 0x1f, regnum, data[2]); } @@ -998,8 +1014,6 @@ static void set_rx_mode(struct net_device *dev) long ioaddr = dev->base_addr; int csr6; - DPRINTK("ENTER\n"); - csr6 = inl(ioaddr + CSR6) & ~0x00D5; tp->csr6 &= ~0x00D5; @@ -1119,6 +1133,91 @@ static void set_rx_mode(struct net_device *dev) tulip_outl_csr(tp, csr6 | 0x0000, CSR6); } +static void __devinit tulip_mwi_config (struct pci_dev *pdev, + struct net_device *dev) +{ + struct tulip_private *tp = dev->priv; + u8 pci_cacheline; + u16 pci_command, new_command; + unsigned mwi = 1; + + if (tulip_debug > 3) + printk(KERN_DEBUG "%s: tulip_mwi_config()\n", pdev->slot_name); + + /* get a sane cache line size, if possible */ + pci_read_config_byte(pdev, PCI_CACHE_LINE_SIZE, &pci_cacheline); + if (pci_cacheline < (SMP_CACHE_BYTES / 4)) + pci_cacheline = SMP_CACHE_BYTES / 4; + if (pci_cacheline > TULIP_MAX_CACHE_LINE) + pci_cacheline = TULIP_MAX_CACHE_LINE; + switch (pci_cacheline) { + case 8: + case 16: + case 32: break; + default: pci_cacheline = TULIP_MIN_CACHE_LINE; break; + } + pci_write_config_byte(pdev, PCI_CACHE_LINE_SIZE, pci_cacheline); + + /* read back the result. if zero, or if a buggy chip rev, + * disable MWI + */ + pci_read_config_byte(pdev, PCI_CACHE_LINE_SIZE, &pci_cacheline); + if (!pci_cacheline || (tp->chip_id == DC21143 && tp->revision == 65)) + mwi = 0; + + /* re-clamp cache line values to ones supported by tulip */ + /* From this point forward, 'pci_cacheline' is really + * the value used for csr0 cache alignment and + * csr0 programmable burst length + */ + switch (pci_cacheline) { + case 0: + case 8: + case 16: + case 32: break; + default: pci_cacheline = TULIP_MIN_CACHE_LINE; break; + } + + /* set or disable MWI in the standard PCI command bit. + * Check for the case where mwi is desired but not available + */ + pci_read_config_word(pdev, PCI_COMMAND, &pci_command); + if (mwi) new_command = pci_command | PCI_COMMAND_INVALIDATE; + else new_command = pci_command & ~PCI_COMMAND_INVALIDATE; + if (new_command != pci_command) { + pci_write_config_word(pdev, PCI_COMMAND, new_command); + pci_read_config_word(pdev, PCI_COMMAND, &pci_command); + if ((new_command != pci_command) && mwi && + ((pci_command & PCI_COMMAND_INVALIDATE) == 0)) + mwi = 0; + } + + tp->csr0 = MRL | MRM; + + /* if no PCI cache line size, bail out with minimal + * burst size and cache alignment of 8 dwords. + * We always want to have some sort of limit. + */ + if (!pci_cacheline) { + tp->csr0 |= (8 << BurstLenShift) | (1 << CALShift); + goto out; + } + + /* finally, build the csr0 value */ + if (mwi) + tp->csr0 |= MWI; + tp->csr0 |= (pci_cacheline << BurstLenShift); + switch (pci_cacheline) { + case 8: tp->csr0 |= (1 << CALShift); + case 16: tp->csr0 |= (2 << CALShift); + case 32: tp->csr0 |= (3 << CALShift); + } + +out: + if (tulip_debug > 2) + printk(KERN_DEBUG "%s: MWI config mwi=%d, cacheline=%d, csr0=%08x\n", + pdev->slot_name, mwi, pci_cacheline, tp->csr0); +} static int __devinit tulip_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) @@ -1136,8 +1235,9 @@ static int __devinit tulip_init_one (struct pci_dev *pdev, long ioaddr; static int board_idx = -1; int chip_idx = ent->driver_data; - int t2104x_mode = 0; - int eeprom_missing = 0; + unsigned int t2104x_mode = 0; + unsigned int eeprom_missing = 0; + unsigned int force_csr0 = 0; #ifndef MODULE static int did_version; /* Already printed version info. */ @@ -1183,12 +1283,26 @@ static int __devinit tulip_init_one (struct pci_dev *pdev, thankfully its an old 486 chipset. */ - if (pci_find_device(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82424, NULL)) - csr0 = 0x00A04800; + if (pci_find_device(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82424, NULL)) { + csr0 = MRL | MRM | (8 << BurstLenShift) | (1 << CALShift); + force_csr0 = 1; + } /* The dreaded SiS496 486 chipset. Same workaround as above. */ - if (pci_find_device(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_496, NULL)) - csr0 = 0x00A04800; + if (pci_find_device(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_496, NULL)) { + csr0 = MRL | MRM | (8 << BurstLenShift) | (1 << CALShift); + force_csr0 = 1; + } + /* bugfix: the ASIX must have a burst limit or horrible things happen. */ + if (chip_idx == AX88140) { + if ((csr0 & 0x3f00) == 0) + csr0 |= 0x2000; + } + + /* PNIC doesn't have MWI/MRL/MRM... */ + if (chip_idx == LC82C168) + csr0 &= ~0xfff10000; /* zero reserved bits 31:20, 16 */ + /* * And back to business */ @@ -1255,13 +1369,8 @@ static int __devinit tulip_init_one (struct pci_dev *pdev, dev->base_addr = ioaddr; dev->irq = irq; - /* bugfix: the ASIX must have a burst limit or horrible things happen. */ - if (chip_idx == AX88140) { - if ((tp->csr0 & 0x3f00) == 0) - tp->csr0 |= 0x2000; - } - else if (chip_idx == DC21143 && chip_rev == 65) - tp->csr0 &= ~0x01000000; + if (!force_csr0 && (tp->flags & HAS_PCI_MWI)) + tulip_mwi_config (pdev, dev); /* Stop the chip's Tx and Rx processes. */ tulip_stop_rxtx(tp, inl(ioaddr + CSR6)); @@ -1373,8 +1482,8 @@ static int __devinit tulip_init_one (struct pci_dev *pdev, if (dev->mem_start & MEDIA_MASK) tp->default_port = dev->mem_start & MEDIA_MASK; if (tp->default_port) { - printk(KERN_INFO "%s: Transceiver selection forced to %s.\n", - pdev->slot_name, medianame[tp->default_port & MEDIA_MASK]); + printk(KERN_INFO "tulip%d: Transceiver selection forced to %s.\n", + board_idx, medianame[tp->default_port & MEDIA_MASK]); tp->medialock = 1; if (tulip_media_cap[tp->default_port] & MediaAlwaysFD) tp->full_duplex = 1; @@ -1384,11 +1493,9 @@ static int __devinit tulip_init_one (struct pci_dev *pdev, if (tulip_media_cap[tp->default_port] & MediaIsMII) { u16 media2advert[] = { 0x20, 0x40, 0x03e0, 0x60, 0x80, 0x100, 0x200 }; - tp->to_advertise = media2advert[tp->default_port - 9]; - } else if (tp->flags & HAS_8023X) - tp->to_advertise = 0x05e1; - else - tp->to_advertise = 0x01e1; + tp->mii_advertise = media2advert[tp->default_port - 9]; + tp->mii_advertise |= (tp->flags & HAS_8023X); /* Matching bits! */ + } if (tp->flags & HAS_MEDIA_TABLE) { memcpy(tp->eeprom, ee_data, sizeof(tp->eeprom)); @@ -1401,55 +1508,21 @@ static int __devinit tulip_init_one (struct pci_dev *pdev, if ((tp->flags & ALWAYS_CHECK_MII) || (tp->mtable && tp->mtable->has_mii) || ( ! tp->mtable && (tp->flags & HAS_MII))) { - int phyn, phy_idx = 0; if (tp->mtable && tp->mtable->has_mii) { for (i = 0; i < tp->mtable->leafcount; i++) if (tp->mtable->mleaf[i].media == 11) { tp->cur_index = i; tp->saved_if_port = dev->if_port; - tulip_select_media(dev, 1); + tulip_select_media(dev, 2); dev->if_port = tp->saved_if_port; break; } } + /* Find the connected MII xcvrs. - Doing this in open() would allow detecting external xcvrs later, - but takes much time. */ - for (phyn = 1; phyn <= 32 && phy_idx < sizeof(tp->phys); phyn++) { - int phy = phyn & 0x1f; - int mii_status = tulip_mdio_read(dev, phy, 1); - if ((mii_status & 0x8301) == 0x8001 || - ((mii_status & 0x8000) == 0 && (mii_status & 0x7800) != 0)) { - int mii_reg0 = tulip_mdio_read(dev, phy, 0); - int mii_advert = tulip_mdio_read(dev, phy, 4); - int reg4 = ((mii_status>>6) & tp->to_advertise) | 1; - tp->phys[phy_idx] = phy; - tp->advertising[phy_idx++] = reg4; - printk(KERN_INFO "%s: MII transceiver #%d " - "config %4.4x status %4.4x advertising %4.4x.\n", - pdev->slot_name, phy, mii_reg0, mii_status, mii_advert); - /* Fixup for DLink with miswired PHY. */ - if (mii_advert != reg4) { - printk(KERN_DEBUG "%s: Advertising %4.4x on PHY %d," - " previously advertising %4.4x.\n", - pdev->slot_name, reg4, phy, mii_advert); - printk(KERN_DEBUG "%s: Advertising %4.4x (to advertise" - " is %4.4x).\n", - pdev->slot_name, reg4, tp->to_advertise); - tulip_mdio_write(dev, phy, 4, reg4); - } - /* Enable autonegotiation: some boards default to off. */ - tulip_mdio_write(dev, phy, 0, mii_reg0 | - (tp->full_duplex ? 0x1100 : 0x1000) | - (tulip_media_cap[tp->default_port]&MediaIs100 ? 0x2000:0)); - } - } - tp->mii_cnt = phy_idx; - if (tp->mtable && tp->mtable->has_mii && phy_idx == 0) { - printk(KERN_INFO "%s: ***WARNING***: No MII transceiver found!\n", - pdev->slot_name); - tp->phys[0] = 1; - } + Doing this in open() would allow detecting external xcvrs + later, but takes much time. */ + tulip_find_mii (dev, board_idx); } /* The Tulip-specific entries in the device structure. */ @@ -1481,18 +1554,21 @@ static int __devinit tulip_init_one (struct pci_dev *pdev, if ((tp->flags & HAS_NWAY) || tp->chip_id == DC21041) tp->link_change = t21142_lnk_change; + else if (tp->chip_id == PNIC2) + tp->link_change = pnic2_lnk_change; else if (tp->flags & HAS_PNICNWAY) tp->link_change = pnic_lnk_change; /* Reset the xcvr interface and turn on heartbeat. */ switch (chip_idx) { case DC21041: - tp->to_advertise = 0x0061; + if (tp->sym_advertise == 0) + tp->sym_advertise = 0x0061; outl(0x00000000, ioaddr + CSR13); outl(0xFFFFFFFF, ioaddr + CSR14); outl(0x00000008, ioaddr + CSR15); /* Listen on AUI also. */ tulip_outl_csr(tp, inl(ioaddr + CSR6) | csr6_fd, CSR6); - outl(0x0000EF05, ioaddr + CSR13); + outl(0x0000EF01, ioaddr + CSR13); break; case DC21040: outl(0x00000000, ioaddr + CSR13); @@ -1552,7 +1628,6 @@ err_out_mtable: err_out_free_res: pci_release_regions (pdev); err_out_free_netdev: - unregister_netdev (dev); kfree (dev); return -ENODEV; } diff --git a/drivers/net/wan/comx-hw-comx.c b/drivers/net/wan/comx-hw-comx.c index 8ace26d886a6..6ddbb86423fd 100644 --- a/drivers/net/wan/comx-hw-comx.c +++ b/drivers/net/wan/comx-hw-comx.c @@ -1045,8 +1045,13 @@ static int comxhw_write_proc(struct file *file, const char *buffer, return -ENOMEM; } copy_from_user(page, buffer, count = (min(count, PAGE_SIZE))); - if (*(page + count - 1) == '\n') { - *(page + count - 1) = 0; + if (page[count-1] == '\n') + page[count-1] = '\0'; + else if (count < PAGE_SIZE) + page[count] = '\0'; + else if (page[count]) { + count = -EINVAL; + goto out; } } else { byte *tmp; @@ -1140,7 +1145,7 @@ static int comxhw_write_proc(struct file *file, const char *buffer, hw->clock = kbps ? COMX_CLOCK_CONST/kbps : 0; } } - +out: free_page((unsigned long)page); return count; } diff --git a/drivers/net/wan/comx.c b/drivers/net/wan/comx.c index 3382498d6fd4..ed1500cd4ceb 100644 --- a/drivers/net/wan/comx.c +++ b/drivers/net/wan/comx.c @@ -623,7 +623,14 @@ static int comx_write_proc(struct file *file, const char *buffer, u_long count, copy_from_user(page, buffer, count); - if (*(page + count - 1) == '\n') *(page + count - 1) = 0; + if (page[count-1] == '\n') + page[count-1] = '\0'; + else if (count < PAGE_SIZE) + page[count] = '\0'; + else if (page[count]) { + count = -EINVAL; + goto out; + } if (strcmp(entry->name, FILENAME_DEBUG) == 0) { int i; @@ -764,7 +771,7 @@ static int comx_write_proc(struct file *file, const char *buffer, u_long count, } } } - +out: free_page((unsigned long)page); return count; } diff --git a/drivers/net/yellowfin.c b/drivers/net/yellowfin.c index 7d8d725da4ea..1ef6104e6269 100644 --- a/drivers/net/yellowfin.c +++ b/drivers/net/yellowfin.c @@ -29,6 +29,11 @@ LK1.1.2 (jgarzik): * Merge in becker version 1.05 + LK1.1.3 (jgarzik): + * Various cleanups + * Update yellowfin_timer to correctly calculate duplex. + (suggested by Manfred Spraul) + */ /* The user-configurable values. @@ -99,6 +104,7 @@ static int gx_fix; #include #include #include +#include #include #include #include @@ -111,7 +117,7 @@ static int gx_fix; static char version[] __devinitdata = KERN_INFO "yellowfin.c:v1.05 1/09/2001 Written by Donald Becker \n" KERN_INFO " http://www.scyld.com/network/yellowfin.html\n" -KERN_INFO " (unofficial 2.4.x port, LK1.1.2, January 11, 2001)\n"; +KERN_INFO " (unofficial 2.4.x port, LK1.1.3, May 10, 2001)\n"; /* Condensed operations for readability. */ #define virt_to_le32desc(addr) cpu_to_le32(virt_to_bus(addr)) @@ -652,22 +658,19 @@ static void yellowfin_timer(unsigned long data) } if (yp->mii_cnt) { - int mii_reg1 = mdio_read(ioaddr, yp->phys[0], 1); - int mii_reg5 = mdio_read(ioaddr, yp->phys[0], 5); - int negotiated = mii_reg5 & yp->advertising; + int bmsr = mdio_read(ioaddr, yp->phys[0], MII_BMSR); + int lpa = mdio_read(ioaddr, yp->phys[0], MII_LPA); + int negotiated = lpa & yp->advertising; if (yellowfin_debug > 1) printk(KERN_DEBUG "%s: MII #%d status register is %4.4x, " "link partner capability %4.4x.\n", - dev->name, yp->phys[0], mii_reg1, mii_reg5); + dev->name, yp->phys[0], bmsr, lpa); - if ( ! yp->duplex_lock && - ((negotiated & 0x0300) == 0x0100 - || (negotiated & 0x00C0) == 0x0040)) { - yp->full_duplex = 1; - } + yp->full_duplex = mii_duplex(yp->duplex_lock, negotiated); + outw(0x101C | (yp->full_duplex ? 2 : 0), ioaddr + Cnfg); - if (mii_reg1 & 0x0004) + if (bmsr & BMSR_LSTATUS) next_tick = 60*HZ; else next_tick = 3*HZ; diff --git a/drivers/parport/init.c b/drivers/parport/init.c index c7efbe5f4f32..bbada430e0ef 100644 --- a/drivers/parport/init.c +++ b/drivers/parport/init.c @@ -165,6 +165,8 @@ int __init parport_init (void) return 0; } +__initcall(parport_init); + #endif /* Exported symbols for modules. */ diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index e010799ccc8b..f2cd4204378b 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -1484,7 +1484,7 @@ pool_alloc_page (struct pci_pool *pool, int mem_flags) page->vaddr = pci_alloc_consistent (pool->dev, pool->allocation, &page->dma); if (page->vaddr) { - memset (page->bitmap, ~0, mapsize); // bit set == free + memset (page->bitmap, 0xff, mapsize); // bit set == free if (pool->flags & SLAB_POISON) memset (page->vaddr, POOL_POISON_BYTE, pool->allocation); list_add (&page->page_list, &pool->page_list); @@ -1500,7 +1500,7 @@ static inline int is_page_busy (int blocks, unsigned long *bitmap) { while (blocks > 0) { - if (*bitmap++ != ~0) + if (*bitmap++ != ~0UL) return 1; blocks -= BITS_PER_LONG; } @@ -1589,9 +1589,8 @@ restart: i += BITS_PER_LONG, map++) { if (page->bitmap [map] == 0) continue; - block = ffs (page->bitmap [map]); - if ((i + block) <= pool->blocks_per_page) { - block--; + block = ffz (~ page->bitmap [map]); + if ((i + block) < pool->blocks_per_page) { clear_bit (block, &page->bitmap [map]); offset = (BITS_PER_LONG * map) + block; offset *= pool->size; @@ -1687,7 +1686,7 @@ pci_pool_free (struct pci_pool *pool, void *vaddr, dma_addr_t dma) block %= BITS_PER_LONG; #ifdef CONFIG_PCIPOOL_DEBUG - if (page->bitmap [map] & (1 << block)) { + if (page->bitmap [map] & (1UL << block)) { printk (KERN_ERR "pci_pool_free %s/%s, dma %x already free\n", pool->dev ? pool->dev->slot_name : NULL, pool->name, dma); diff --git a/drivers/pci/proc.c b/drivers/pci/proc.c index 049cdcf35456..cc0953516a4f 100644 --- a/drivers/pci/proc.c +++ b/drivers/pci/proc.c @@ -191,10 +191,106 @@ proc_bus_pci_write(struct file *file, const char *buf, size_t nbytes, loff_t *pp return nbytes; } +struct pci_filp_private { + enum pci_mmap_state mmap_state; + int write_combine; +}; + +static int proc_bus_pci_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) +{ + const struct proc_dir_entry *dp = inode->u.generic_ip; + struct pci_dev *dev = dp->data; +#ifdef HAVE_PCI_MMAP + struct pci_filp_private *fpriv = file->private_data; +#endif /* HAVE_PCI_MMAP */ + int ret = 0; + + switch (cmd) { + case PCIIOC_CONTROLLER: + ret = pci_controller_num(dev); + break; + +#ifdef HAVE_PCI_MMAP + case PCIIOC_MMAP_IS_IO: + fpriv->mmap_state = pci_mmap_io; + break; + + case PCIIOC_MMAP_IS_MEM: + fpriv->mmap_state = pci_mmap_mem; + break; + + case PCIIOC_WRITE_COMBINE: + if (arg) + fpriv->write_combine = 1; + else + fpriv->write_combine = 0; + break; + +#endif /* HAVE_PCI_MMAP */ + + default: + ret = -EINVAL; + break; + }; + + return ret; +} + +#ifdef HAVE_PCI_MMAP +static int proc_bus_pci_mmap(struct file *file, struct vm_area_struct *vma) +{ + struct inode *inode = file->f_dentry->d_inode; + const struct proc_dir_entry *dp = inode->u.generic_ip; + struct pci_dev *dev = dp->data; + struct pci_filp_private *fpriv = file->private_data; + int ret; + + ret = pci_mmap_page_range(dev, vma, + fpriv->mmap_state, + fpriv->write_combine); + if (ret < 0) + return ret; + + return 0; +} + +static int proc_bus_pci_open(struct inode *inode, struct file *file) +{ + struct pci_filp_private *fpriv = kmalloc(sizeof(*fpriv), GFP_KERNEL); + + if (!fpriv) + return -ENOMEM; + + fpriv->mmap_state = pci_mmap_io; + fpriv->write_combine = 0; + + file->private_data = fpriv; + + return 0; +} + +static int proc_bus_pci_release(struct inode *inode, struct file *file) +{ + kfree(file->private_data); + file->private_data = NULL; + + return 0; +} +#endif /* HAVE_PCI_MMAP */ + static struct file_operations proc_bus_pci_operations = { - llseek: proc_bus_pci_lseek, - read: proc_bus_pci_read, - write: proc_bus_pci_write, + llseek: proc_bus_pci_lseek, + read: proc_bus_pci_read, + write: proc_bus_pci_write, + ioctl: proc_bus_pci_ioctl, +#ifdef HAVE_PCI_MMAP + open: proc_bus_pci_open, + release: proc_bus_pci_release, + mmap: proc_bus_pci_mmap, +#ifdef HAVE_ARCH_PCI_GET_UNMAPPED_AREA + get_unmapped_area: get_pci_unmapped_area, +#endif /* HAVE_ARCH_PCI_GET_UNMAPPED_AREA */ +#endif /* HAVE_PCI_MMAP */ }; #if BITS_PER_LONG == 32 diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index bf9c064702c0..26bb34023056 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c @@ -12,6 +12,7 @@ * use the PowerTweak utility (see http://powertweak.sourceforge.net). */ +#include #include #include #include @@ -238,6 +239,30 @@ static void __init quirk_vt82c686_acpi(struct pci_dev *dev) quirk_io_region(dev, smb, 16, PCI_BRIDGE_RESOURCES + 2); } + +#ifdef CONFIG_X86_IO_APIC +extern int nr_ioapics; + +/* + * VIA 686A/B: If an IO-APIC is active, we need to route all on-chip + * devices to the external APIC. + */ +static void __init quirk_via_ioapic(struct pci_dev *dev) +{ + u8 tmp; + + if (nr_ioapics < 1) + tmp = 0; /* nothing routed to external APIC */ + else + tmp = 0x1f; /* all known bits (4-0) routed to external APIC */ + + /* Offset 0x58: External APIC IRQ output control */ + pci_write_config_byte (dev, 0x58, tmp); +} + +#endif /* CONFIG_X86_IO_APIC */ + + /* * PIIX3 USB: We have to disable USB interrupts that are * hardwired to PIRQD# and may be shared with an @@ -322,6 +347,11 @@ static struct pci_fixup pci_fixups[] __initdata = { { PCI_FIXUP_HEADER, PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371SB_2, quirk_piix3_usb }, { PCI_FIXUP_HEADER, PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371AB_2, quirk_piix3_usb }, { PCI_FIXUP_FINAL, PCI_ANY_ID, PCI_ANY_ID, quirk_cardbus_legacy }, + +#ifdef CONFIG_X86_IO_APIC + { PCI_FIXUP_FINAL, PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686, quirk_via_ioapic }, +#endif + { 0 } }; diff --git a/drivers/pci/setup-res.c b/drivers/pci/setup-res.c index 5b6acd99a852..1f2830811bfb 100644 --- a/drivers/pci/setup-res.c +++ b/drivers/pci/setup-res.c @@ -115,7 +115,8 @@ pci_assign_resource(struct pci_dev *dev, int i) * window (it will just not perform as well). */ if (!(res->flags & IORESOURCE_PREFETCH) || pci_assign_bus_resource(bus, dev, res, size, min, 0, i) < 0) { - printk(KERN_ERR "PCI: Failed to allocate resource %d for %s\n", i, dev->name); + printk(KERN_ERR "PCI: Failed to allocate resource %d(%lx-%lx) for %s\n", + i, res->start, res->end, dev->slot_name); return -EBUSY; } } diff --git a/drivers/s390/block/dasd.c b/drivers/s390/block/dasd.c index 25abc7c45690..8aeceaab7ffa 100644 --- a/drivers/s390/block/dasd.c +++ b/drivers/s390/block/dasd.c @@ -2892,7 +2892,7 @@ dasd_devices_read (struct file *file, char *user_buf, size_t user_len, loff_t * static ssize_t dasd_devices_write (struct file *file, const char *user_buf, size_t user_len, loff_t * offset) { - char *buffer = vmalloc (user_len); + char *buffer = vmalloc (user_len+1); int off = 0; char *temp; int irq; diff --git a/drivers/sbus/char/aurora.c b/drivers/sbus/char/aurora.c index 669d157b4252..ed9abb541e51 100644 --- a/drivers/sbus/char/aurora.c +++ b/drivers/sbus/char/aurora.c @@ -1,4 +1,4 @@ -/* $Id: aurora.c,v 1.11 2001/03/08 01:43:30 davem Exp $ +/* $Id: aurora.c,v 1.13 2001/05/10 01:45:38 davem Exp $ * linux/drivers/sbus/char/aurora.c -- Aurora multiport driver * * Copyright (c) 1999 by Oliver Aldulea (oli@bv.ro) @@ -1632,33 +1632,55 @@ static int aurora_write(struct tty_struct * tty, int from_user, if (!tty || !port->xmit_buf || !tmp_buf) return 0; - if (from_user) - down(&tmp_buf_sem); - save_flags(flags); - while (1) { - cli(); - c = MIN(count, MIN(SERIAL_XMIT_SIZE - port->xmit_cnt - 1, - SERIAL_XMIT_SIZE - port->xmit_head)); - if (c <= 0) - break; + if (from_user) { + down(&tmp_buf_sem); + while (1) { + c = MIN(count, MIN(SERIAL_XMIT_SIZE - port->xmit_cnt - 1, + SERIAL_XMIT_SIZE - port->xmit_head)); + if (c <= 0) + break; - if (from_user) { - copy_from_user(tmp_buf, buf, c); + c -= copy_from_user(tmp_buf, buf, c); + if (!c) { + if (!total) + total = -EFAULT; + break; + } + cli(); c = MIN(c, MIN(SERIAL_XMIT_SIZE - port->xmit_cnt - 1, SERIAL_XMIT_SIZE - port->xmit_head)); memcpy(port->xmit_buf + port->xmit_head, tmp_buf, c); - } else + port->xmit_head = (port->xmit_head + c) & (SERIAL_XMIT_SIZE-1); + port->xmit_cnt += c; + restore_flags(flags); + + buf += c; + count -= c; + total += c; + } + up(&tmp_buf_sem); + } else { + while (1) { + cli(); + c = MIN(count, MIN(SERIAL_XMIT_SIZE - port->xmit_cnt - 1, + SERIAL_XMIT_SIZE - port->xmit_head)); + if (c <= 0) { + restore_flags(flags); + break; + } memcpy(port->xmit_buf + port->xmit_head, buf, c); - port->xmit_head = (port->xmit_head + c) & (SERIAL_XMIT_SIZE-1); - port->xmit_cnt += c; - restore_flags(flags); - buf += c; - count -= c; - total += c; + port->xmit_head = (port->xmit_head + c) & (SERIAL_XMIT_SIZE-1); + port->xmit_cnt += c; + restore_flags(flags); + + buf += c; + count -= c; + total += c; + } } - if (from_user) - up(&tmp_buf_sem); + + cli(); if (port->xmit_cnt && !tty->stopped && !tty->hw_stopped && !(port->SRER & SRER_TXRDY)) { port->SRER |= SRER_TXRDY; diff --git a/drivers/sbus/char/pcikbd.c b/drivers/sbus/char/pcikbd.c index 5513053dc27d..b6a01efff596 100644 --- a/drivers/sbus/char/pcikbd.c +++ b/drivers/sbus/char/pcikbd.c @@ -1,4 +1,4 @@ -/* $Id: pcikbd.c,v 1.53 2001/03/21 00:28:33 davem Exp $ +/* $Id: pcikbd.c,v 1.54 2001/05/11 07:46:28 davem Exp $ * pcikbd.c: Ultra/AX PC keyboard support. * * Copyright (C) 1997 Eddie C. Dost (ecd@skynet.be) @@ -28,6 +28,9 @@ #include #include +#if defined(CONFIG_USB) && defined(CONFIG_SPARC64) +#include +#endif #include #include #include @@ -451,6 +454,47 @@ static void pcikbd_kd_mksound(unsigned int hz, unsigned int ticks) } restore_flags(flags); } + +#if defined(CONFIG_USB) && defined(CONFIG_SPARC64) +static void isa_kd_nosound(unsigned long __unused) +{ + /* disable counter 2 */ + outb(inb(pcibeep_iobase + 0x61)&0xFC, pcibeep_iobase + 0x61); + return; +} + +static void isa_kd_mksound(unsigned int hz, unsigned int ticks) +{ + static struct timer_list sound_timer = { function: isa_kd_nosound }; + unsigned int count = 0; + unsigned long flags; + + if (hz > 20 && hz < 32767) + count = 1193180 / hz; + + save_flags(flags); + cli(); + del_timer(&sound_timer); + if (count) { + /* enable counter 2 */ + outb(inb(pcibeep_iobase + 0x61)|3, pcibeep_iobase + 0x61); + /* set command for counter 2, 2 byte write */ + outb(0xB6, pcibeep_iobase + 0x43); + /* select desired HZ */ + outb(count & 0xff, pcibeep_iobase + 0x42); + outb((count >> 8) & 0xff, pcibeep_iobase + 0x42); + + if (ticks) { + sound_timer.expires = jiffies+ticks; + add_timer(&sound_timer); + } + } else + isa_kd_nosound(0); + restore_flags(flags); + return; +} +#endif + #endif static void nop_kd_mksound(unsigned int hz, unsigned int ticks) @@ -551,6 +595,30 @@ void __init pcikbd_init_hw(void) } } +#ifdef CONFIG_SPARC64 + /* Maybe we have one inside the ALI southbridge? */ + { + struct isa_bridge *isa_br; + struct isa_device *isa_dev; + for_each_isa(isa_br) { + for_each_isadev(isa_dev, isa_br) { + /* This is a hack, the 'dma' device node has + * the base of the I/O port space for that PBM + * as it's resource, so we use that. -DaveM + */ + if (!strcmp(isa_dev->prom_name, "dma")) { + pcibeep_iobase = isa_dev->resource.start; + kd_mksound = isa_kd_mksound; + printk("isa(speaker): iobase[%016lx:%016lx]\n", + pcibeep_iobase + 0x42, + pcibeep_iobase + 0x61); + return; + } + } + } + } +#endif + /* No beeper found, ok complain. */ #endif printk("pcikbd_init_hw: no 8042 found\n"); diff --git a/drivers/sbus/char/su.c b/drivers/sbus/char/su.c index 91a55e96ef48..c1d9d97c2087 100644 --- a/drivers/sbus/char/su.c +++ b/drivers/sbus/char/su.c @@ -1,4 +1,4 @@ -/* $Id: su.c,v 1.48 2001/04/27 07:02:42 davem Exp $ +/* $Id: su.c,v 1.49 2001/05/11 05:35:02 davem Exp $ * su.c: Small serial driver for keyboard/mouse interface on sparc32/PCI * * Copyright (C) 1997 Eddie C. Dost (ecd@skynet.be) @@ -75,6 +75,9 @@ do { \ #include #include #include +#ifdef CONFIG_SPARC64 +#include +#endif #include #include #include @@ -2220,7 +2223,7 @@ done: */ static __inline__ void __init show_su_version(void) { - char *revision = "$Revision: 1.48 $"; + char *revision = "$Revision: 1.49 $"; char *version, *p; version = strchr(revision, ' '); @@ -2243,6 +2246,10 @@ autoconfig(struct su_struct *info) unsigned char status1, status2, scratch, scratch2; struct linux_ebus_device *dev = 0; struct linux_ebus *ebus; +#ifdef CONFIG_SPARC64 + struct isa_bridge *isa_br; + struct isa_device *isa_dev; +#endif #ifndef __sparc_v9__ struct linux_prom_registers reg0; #endif @@ -2264,6 +2271,18 @@ autoconfig(struct su_struct *info) } } +#ifdef CONFIG_SPARC64 + for_each_isa(isa_br) { + for_each_isadev(isa_dev, isa_br) { + if (isa_dev->prom_node == info->port_node) { + info->port = isa_dev->resource.start; + info->irq = isa_dev->irq; + goto ebus_done; + } + } + } +#endif + #ifdef __sparc_v9__ /* * Not on Ebus, bailing. diff --git a/drivers/sbus/char/zs.c b/drivers/sbus/char/zs.c index 35c61eef2113..29df2aa97ee1 100644 --- a/drivers/sbus/char/zs.c +++ b/drivers/sbus/char/zs.c @@ -1,4 +1,4 @@ -/* $Id: zs.c,v 1.64 2001/04/27 07:02:42 davem Exp $ +/* $Id: zs.c,v 1.65 2001/05/09 07:00:10 davem Exp $ * zs.c: Zilog serial port driver for the Sparc. * * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) @@ -1156,28 +1156,51 @@ static int zs_write(struct tty_struct * tty, int from_user, return 0; save_flags(flags); - while (1) { - cli(); - c = MIN(count, MIN(SERIAL_XMIT_SIZE - info->xmit_cnt - 1, - SERIAL_XMIT_SIZE - info->xmit_head)); - if (c <= 0) - break; - - if (from_user) { - down(&tmp_buf_sem); - copy_from_user(tmp_buf, buf, c); + if (from_user) { + down(&tmp_buf_sem); + while (1) { + c = MIN(count, MIN(SERIAL_XMIT_SIZE - info->xmit_cnt - 1, + SERIAL_XMIT_SIZE - info->xmit_head)); + if (c <= 0) + break; + c -= copy_from_user(tmp_buf, buf, c); + if (!c) { + if (!total) + total = -EFAULT; + break; + } + cli(); c = MIN(c, MIN(SERIAL_XMIT_SIZE - info->xmit_cnt - 1, SERIAL_XMIT_SIZE - info->xmit_head)); memcpy(info->xmit_buf + info->xmit_head, tmp_buf, c); - up(&tmp_buf_sem); - } else + info->xmit_head = ((info->xmit_head + c) & + (SERIAL_XMIT_SIZE - 1)); + info->xmit_cnt += c; + restore_flags(flags); + + buf += c; + count -= c; + total += c; + } + up(&tmp_buf_sem); + } else { + while (1) { + cli(); + c = MIN(count, MIN(SERIAL_XMIT_SIZE - info->xmit_cnt - 1, + SERIAL_XMIT_SIZE - info->xmit_head)); + if (c <= 0) { + restore_flags(flags); + break; + } memcpy(info->xmit_buf + info->xmit_head, buf, c); - info->xmit_head = (info->xmit_head + c) & (SERIAL_XMIT_SIZE-1); - info->xmit_cnt += c; - restore_flags(flags); - buf += c; - count -= c; - total += c; + info->xmit_head = ((info->xmit_head + c) & + (SERIAL_XMIT_SIZE - 1)); + info->xmit_cnt += c; + restore_flags(flags); + buf += c; + count -= c; + total += c; + } } cli(); @@ -1922,7 +1945,7 @@ int zs_open(struct tty_struct *tty, struct file * filp) static void show_serial_version(void) { - char *revision = "$Revision: 1.64 $"; + char *revision = "$Revision: 1.65 $"; char *version, *p; version = strchr(revision, ' '); diff --git a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c index fdb4f2ce8820..9e50202f7beb 100644 --- a/drivers/scsi/scsi.c +++ b/drivers/scsi/scsi.c @@ -1572,6 +1572,11 @@ static int proc_scsi_gen_write(struct file * file, const char * buf, copy_from_user(buffer, buf, length); err = -EINVAL; + if (length < PAGE_SIZE) + buffer[length] ='\0'; + else if (buffer[length]) + goto out; + if (length < 11 || strncmp("scsi", buffer, 4)) goto out; diff --git a/drivers/scsi/scsi_proc.c b/drivers/scsi/scsi_proc.c index b486119b171e..acacecda4364 100644 --- a/drivers/scsi/scsi_proc.c +++ b/drivers/scsi/scsi_proc.c @@ -105,6 +105,7 @@ static int proc_scsi_write(struct file * file, const char * buf, if (!(page = (char *) __get_free_page(GFP_KERNEL))) return -ENOMEM; copy_from_user(page, buf, count); + page[count] = '\0'; if (hpnt->hostt->proc_info == NULL) ret = -ENOSYS; diff --git a/drivers/sound/trident.c b/drivers/sound/trident.c index 283dd8235360..3d80f8e5e291 100644 --- a/drivers/sound/trident.c +++ b/drivers/sound/trident.c @@ -732,7 +732,7 @@ static void trident_play_setup(struct trident_state *state) struct dmabuf *dmabuf = &state->dmabuf; struct trident_channel *channel = dmabuf->channel; - channel->lba = virt_to_bus(dmabuf->rawbuf); + channel->lba = dmabuf->dma_handle; channel->delta = compute_rate_play(dmabuf->rate); channel->eso = dmabuf->dmasize >> sample_shift[dmabuf->fmt]; @@ -808,7 +808,7 @@ static void trident_rec_setup(struct trident_state *state) return; } - channel->lba = virt_to_bus(dmabuf->rawbuf); + channel->lba = dmabuf->dma_handle; channel->delta = compute_rate_rec(dmabuf->rate); if ((card->pci_id == PCI_DEVICE_ID_ALI_5451) && (channel->num == ALI_SPDIF_IN_CHANNEL)) { rate = ali_get_spdif_in_rate(card); @@ -1074,14 +1074,21 @@ static int prog_dmabuf(struct trident_state *state, unsigned rec) } } else { - if ((order = state->dmabuf.buforder - 1) >= DMABUF_MINORDER) - dmabuf->rawbuf = (void *)__get_free_pages(GFP_KERNEL | GFP_DMA, order); + if ((order = state->dmabuf.buforder - 1) >= DMABUF_MINORDER) { + dmabuf->rawbuf = pci_alloc_consistent(state->card->pci_dev, + PAGE_SIZE << order, + &dmabuf->dma_handle); + } if (!dmabuf->rawbuf) { free_pages((unsigned long)state->dmabuf.rawbuf, state->dmabuf.buforder); state->dmabuf.rawbuf = NULL; i-=2; - for (; i >= 0; i--) - free_pages((unsigned long)state->other_states[i]->dmabuf.rawbuf, state->other_states[i]->dmabuf.buforder); + for (; i >= 0; i--) { + pci_free_consistent(state->card->pci_dev, + PAGE_SIZE << state->other_states[i]->dmabuf.buforder, + state->other_states[i]->dmabuf.rawbuf, + state->other_states[i]->dmabuf.dma_handle); + } unlock_set_fmt(state); return -ENOMEM; } @@ -3157,20 +3164,34 @@ static int ali_write_proc(struct file *file, const char *buffer, unsigned long c { struct trident_card *card = (struct trident_card *)data; unsigned long flags; + char c; + + if (count<0) + return -EINVAL; + if (count == 0) + return 0; + if (get_user(&c, buffer)) + return -EFAULT; spin_lock_irqsave(&card->lock, flags); - if (*buffer == '0') { //default + switch (c) { + case '0': ali_setup_spdif_out(card, ALI_PCM_TO_SPDIF_OUT); ali_disable_special_channel(card, ALI_SPDIF_OUT_CHANNEL); - } - else if (*buffer == '1') + break; + case '1': ali_setup_spdif_out(card, ALI_SPDIF_OUT_TO_SPDIF_OUT|ALI_SPDIF_OUT_PCM); - else if (*buffer == '2') //AC3 data + break; + case '2': ali_setup_spdif_out(card, ALI_SPDIF_OUT_TO_SPDIF_OUT|ALI_SPDIF_OUT_NON_PCM); - else if (*buffer == '3') + break; + case '3': ali_disable_spdif_in(card); //default - else if (*buffer == '4') + break; + case '4': ali_setup_spdif_in(card); + break; + } spin_unlock_irqrestore(&card->lock, flags); return count; @@ -3307,14 +3328,23 @@ static int __init trident_probe(struct pci_dev *pci_dev, const struct pci_device { unsigned long iobase; struct trident_card *card; + dma_addr_t mask; + int bits; u8 revision; if (pci_enable_device(pci_dev)) return -ENODEV; - if (pci_set_dma_mask(pci_dev, TRIDENT_DMA_MASK)) { + if (pci_dev->device == PCI_DEVICE_ID_ALI_5451) { + mask = 0xffffffff; + bits = 32; + } else { + mask = TRIDENT_DMA_MASK; + bits = 30; + } + if (pci_set_dma_mask(pci_dev, mask)) { printk(KERN_ERR "trident: architecture does not support" - " 30bit PCI busmaster DMA\n"); + " %dbit PCI busmaster DMA\n", bits); return -ENODEV; } pci_read_config_byte(pci_dev, PCI_CLASS_REVISION, &revision); diff --git a/drivers/sound/ymfpci.h b/drivers/sound/ymfpci.h index bd2f4c2a309c..9fac68a4530d 100644 --- a/drivers/sound/ymfpci.h +++ b/drivers/sound/ymfpci.h @@ -135,6 +135,8 @@ #define PCIR_LEGCTRL 0x40 #define PCIR_ELEGCTRL 0x42 #define PCIR_DSXGCTRL 0x48 +#define PCIR_DSXPWRCTRL1 0x4a +#define PCIR_DSXPWRCTRL2 0x4e #define PCIR_OPLADR 0x60 #define PCIR_SBADR 0x62 #define PCIR_MPUADR 0x64 diff --git a/drivers/telephony/ixj.c b/drivers/telephony/ixj.c index 26cde9475601..aa39a3ca4ce7 100644 --- a/drivers/telephony/ixj.c +++ b/drivers/telephony/ixj.c @@ -4434,7 +4434,8 @@ static int ixj_build_cadence(IXJ *j, IXJ_CADENCE * cp) lcp = kmalloc(sizeof(IXJ_CADENCE), GFP_KERNEL); if (lcp == NULL) return -ENOMEM; - if (copy_from_user(lcp, (char *) cp, sizeof(IXJ_CADENCE))) + if (copy_from_user(lcp, (char *) cp, sizeof(IXJ_CADENCE)) || + (unsigned)lcp->elements_used >= ~0U/sizeof(IXJ_CADENCE) ) { kfree(lcp); return -EFAULT; diff --git a/drivers/usb/usb-uhci-debug.h b/drivers/usb/usb-uhci-debug.h index d1c0ca83d8a5..5ee2a5e37e99 100644 --- a/drivers/usb/usb-uhci-debug.h +++ b/drivers/usb/usb-uhci-debug.h @@ -5,7 +5,7 @@ static void __attribute__((__unused__)) uhci_show_qh (puhci_desc_t qh) dbg("qh has not QH_TYPE"); return; } - dbg("QH @ %p/%08lX:", qh, virt_to_bus (qh)); + dbg("QH @ %p/%08X:", qh, qh->dma_addr); if (qh->hw.qh.head & UHCI_PTR_TERM) dbg(" Head Terminate"); @@ -23,6 +23,7 @@ static void __attribute__((__unused__)) uhci_show_qh (puhci_desc_t qh) } #endif +#if 0 static void uhci_show_td (puhci_desc_t td) { char *spid; @@ -42,8 +43,8 @@ static void uhci_show_td (puhci_desc_t td) break; } - warn(" TD @ %p/%08lX, MaxLen=%02x DT%d EP=%x Dev=%x PID=(%s) buf=%08x", - td, virt_to_bus (td), + warn(" TD @ %p/%08X, MaxLen=%02x DT%d EP=%x Dev=%x PID=(%s) buf=%08x", + td, td->dma_addr, td->hw.td.info >> 21, ((td->hw.td.info >> 19) & 1), (td->hw.td.info >> 15) & 15, @@ -74,10 +75,15 @@ static void uhci_show_td (puhci_desc_t td) td->hw.td.link & ~UHCI_PTR_BITS, (td->hw.td.link & UHCI_PTR_DEPTH ? "Depth first" : "Breadth first")); } +#endif + #ifdef DEBUG static void __attribute__((__unused__)) uhci_show_td_queue (puhci_desc_t td) { - //dbg("uhci_show_td_queue %p (%08lX):", td, virt_to_bus (td)); + //dbg("uhci_show_td_queue %p (%08lX):", td, td->dma_addr); +#if 1 + return; +#else while (1) { uhci_show_td (td); if (td->hw.td.link & UHCI_PTR_TERM) @@ -89,13 +95,19 @@ static void __attribute__((__unused__)) uhci_show_td_queue (puhci_desc_t td) break; } } +#endif } static void __attribute__((__unused__)) uhci_show_queue (puhci_desc_t qh) { +#if 0 uhci_desc_t *start_qh=qh; +#endif dbg("uhci_show_queue %p:", qh); +#if 1 + return; +#else while (1) { uhci_show_qh (qh); @@ -117,6 +129,7 @@ static void __attribute__((__unused__)) uhci_show_queue (puhci_desc_t qh) break; } } +#endif } static void __attribute__((__unused__)) uhci_show_sc (int port, unsigned short status) diff --git a/drivers/usb/usb-uhci.c b/drivers/usb/usb-uhci.c index 8f1e806332c9..2438c79f6832 100644 --- a/drivers/usb/usb-uhci.c +++ b/drivers/usb/usb-uhci.c @@ -75,7 +75,6 @@ #define async_dbg dbg //err #ifdef DEBUG_SLAB - static kmem_cache_t *uhci_desc_kmem; static kmem_cache_t *urb_priv_kmem; #endif @@ -128,17 +127,17 @@ _static void uhci_switch_timer_int(uhci_t *s) { if (!list_empty(&s->urb_unlinked)) { - s->td1ms->hw.td.status |= TD_CTRL_IOC; + s->td1ms->hw.td.status |= cpu_to_le32(TD_CTRL_IOC); } else { - s->td1ms->hw.td.status &= ~TD_CTRL_IOC; + s->td1ms->hw.td.status &= cpu_to_le32(~TD_CTRL_IOC); } if (s->timeout_urbs) { - s->td32ms->hw.td.status |= TD_CTRL_IOC; + s->td32ms->hw.td.status |= cpu_to_le32(TD_CTRL_IOC); } else { - s->td32ms->hw.td.status &= ~TD_CTRL_IOC; + s->td32ms->hw.td.status &= cpu_to_le32(~TD_CTRL_IOC); } wmb(); @@ -153,7 +152,7 @@ _static void enable_desc_loop(uhci_t *s, urb_t *urb) return; spin_lock_irqsave (&s->qh_lock, flags); - s->chain_end->hw.qh.head&=~UHCI_PTR_TERM; + s->chain_end->hw.qh.head&=cpu_to_le32(~UHCI_PTR_TERM); mb(); s->loop_usage++; ((urb_priv_t*)urb->hcpriv)->use_loop=1; @@ -172,7 +171,7 @@ _static void disable_desc_loop(uhci_t *s, urb_t *urb) s->loop_usage--; if (!s->loop_usage) { - s->chain_end->hw.qh.head|=UHCI_PTR_TERM; + s->chain_end->hw.qh.head|=cpu_to_le32(UHCI_PTR_TERM); mb(); } ((urb_priv_t*)urb->hcpriv)->use_loop=0; @@ -226,17 +225,16 @@ _static void dequeue_urb (uhci_t *s, urb_t *urb) } /*-------------------------------------------------------------------*/ -_static int alloc_td (uhci_desc_t ** new, int flags) +_static int alloc_td (uhci_t *s, uhci_desc_t ** new, int flags) { -#ifdef DEBUG_SLAB - *new= kmem_cache_alloc(uhci_desc_kmem, SLAB_FLAG); -#else - *new = (uhci_desc_t *) kmalloc (sizeof (uhci_desc_t), KMALLOC_FLAG); -#endif + dma_addr_t dma_handle; + + *new = pci_pool_alloc(s->desc_pool, GFP_DMA | GFP_ATOMIC, &dma_handle); if (!*new) return -ENOMEM; - memset (*new, 0, sizeof (uhci_desc_t)); - (*new)->hw.td.link = UHCI_PTR_TERM | (flags & UHCI_PTR_BITS); // last by default + memset (*new, 0, sizeof (uhci_desc_t)); + (*new)->dma_addr = dma_handle; + (*new)->hw.td.link = cpu_to_le32(UHCI_PTR_TERM | (flags & UHCI_PTR_BITS)); // last by default (*new)->type = TD_TYPE; mb(); INIT_LIST_HEAD (&(*new)->vertical); @@ -252,7 +250,7 @@ _static void append_qh(uhci_t *s, uhci_desc_t *td, uhci_desc_t* qh, int flags) spin_lock_irqsave (&s->td_lock, xxx); - td->hw.td.link = virt_to_bus (qh) | (flags & UHCI_PTR_DEPTH) | UHCI_PTR_QH; + td->hw.td.link = cpu_to_le32(qh->dma_addr | (flags & UHCI_PTR_DEPTH) | UHCI_PTR_QH); mb(); spin_unlock_irqrestore (&s->td_lock, xxx); @@ -272,11 +270,11 @@ _static int insert_td (uhci_t *s, uhci_desc_t *qh, uhci_desc_t* new, int flags) if (qh == prev ) { // virgin qh without any tds - qh->hw.qh.element = virt_to_bus (new) | UHCI_PTR_TERM; + qh->hw.qh.element = cpu_to_le32(new->dma_addr | UHCI_PTR_TERM); } else { // already tds inserted, implicitely remove TERM bit of prev - prev->hw.td.link = virt_to_bus (new) | (flags & UHCI_PTR_DEPTH); + prev->hw.td.link = cpu_to_le32(new->dma_addr | (flags & UHCI_PTR_DEPTH)); } mb(); spin_unlock_irqrestore (&s->td_lock, xxx); @@ -295,7 +293,7 @@ _static int insert_td_horizontal (uhci_t *s, uhci_desc_t *td, uhci_desc_t* new) next = list_entry (td->horizontal.next, uhci_desc_t, horizontal); list_add (&new->horizontal, &td->horizontal); new->hw.td.link = td->hw.td.link; - td->hw.td.link = virt_to_bus (new); + td->hw.td.link = cpu_to_le32(new->dma_addr); mb(); spin_unlock_irqrestore (&s->td_lock, flags); @@ -340,29 +338,24 @@ _static int unlink_td (uhci_t *s, uhci_desc_t *element, int phys_unlink) } /*-------------------------------------------------------------------*/ -_static int delete_desc (uhci_desc_t *element) +_static int delete_desc (uhci_t *s, uhci_desc_t *element) { -#ifdef DEBUG_SLAB - kmem_cache_free(uhci_desc_kmem, element); -#else - kfree (element); -#endif + pci_pool_free(s->desc_pool, element, element->dma_addr); return 0; } /*-------------------------------------------------------------------*/ // Allocates qh element -_static int alloc_qh (uhci_desc_t ** new) +_static int alloc_qh (uhci_t *s, uhci_desc_t ** new) { -#ifdef DEBUG_SLAB - *new= kmem_cache_alloc(uhci_desc_kmem, SLAB_FLAG); -#else - *new = (uhci_desc_t *) kmalloc (sizeof (uhci_desc_t), KMALLOC_FLAG); -#endif + dma_addr_t dma_handle; + + *new = pci_pool_alloc(s->desc_pool, GFP_DMA | GFP_ATOMIC, &dma_handle); if (!*new) return -ENOMEM; memset (*new, 0, sizeof (uhci_desc_t)); - (*new)->hw.qh.head = UHCI_PTR_TERM; - (*new)->hw.qh.element = UHCI_PTR_TERM; + (*new)->dma_addr = dma_handle; + (*new)->hw.qh.head = cpu_to_le32(UHCI_PTR_TERM); + (*new)->hw.qh.element = cpu_to_le32(UHCI_PTR_TERM); (*new)->type = QH_TYPE; mb(); @@ -387,16 +380,16 @@ _static int insert_qh (uhci_t *s, uhci_desc_t *pos, uhci_desc_t *new, int order) // (OLD) (POS) -> (OLD) (NEW) (POS) old = list_entry (pos->horizontal.prev, uhci_desc_t, horizontal); list_add_tail (&new->horizontal, &pos->horizontal); - new->hw.qh.head = MAKE_QH_ADDR (pos) ; - if (!(old->hw.qh.head & UHCI_PTR_TERM)) - old->hw.qh.head = MAKE_QH_ADDR (new) ; + new->hw.qh.head = cpu_to_le32(MAKE_QH_ADDR (pos)) ; + if (!(old->hw.qh.head & cpu_to_le32(UHCI_PTR_TERM))) + old->hw.qh.head = cpu_to_le32(MAKE_QH_ADDR (new)) ; } else { // (POS) (OLD) -> (POS) (NEW) (OLD) old = list_entry (pos->horizontal.next, uhci_desc_t, horizontal); list_add (&new->horizontal, &pos->horizontal); - new->hw.qh.head = MAKE_QH_ADDR (old); - pos->hw.qh.head = MAKE_QH_ADDR (new) ; + new->hw.qh.head = cpu_to_le32(MAKE_QH_ADDR (old)); + pos->hw.qh.head = cpu_to_le32(MAKE_QH_ADDR (new)) ; } mb (); @@ -418,7 +411,7 @@ _static int unlink_qh (uhci_t *s, uhci_desc_t *element) prev->hw.qh.head = element->hw.qh.head; dbg("unlink qh %p, pqh %p, nxqh %p, to %08x", element, prev, - list_entry (element->horizontal.next, uhci_desc_t, horizontal),element->hw.qh.head &~15); + list_entry (element->horizontal.next, uhci_desc_t, horizontal),le32_to_cpu(element->hw.qh.head) &~15); list_del(&element->horizontal); @@ -439,15 +432,15 @@ _static int delete_qh (uhci_t *s, uhci_desc_t *qh) td = list_entry (p, uhci_desc_t, vertical); dbg("unlink td @ %p",td); unlink_td (s, td, 0); // no physical unlink - delete_desc (td); + delete_desc (s, td); } - delete_desc (qh); + delete_desc (s, qh); return 0; } /*-------------------------------------------------------------------*/ -_static void clean_td_chain (uhci_desc_t *td) +_static void clean_td_chain (uhci_t *s, uhci_desc_t *td) { struct list_head *p; uhci_desc_t *td1; @@ -457,18 +450,18 @@ _static void clean_td_chain (uhci_desc_t *td) while ((p = td->horizontal.next) != &td->horizontal) { td1 = list_entry (p, uhci_desc_t, horizontal); - delete_desc (td1); + delete_desc (s, td1); } - delete_desc (td); + delete_desc (s, td); } /*-------------------------------------------------------------------*/ _static void fill_td (uhci_desc_t *td, int status, int info, __u32 buffer) { - td->hw.td.status = status; - td->hw.td.info = info; - td->hw.td.buffer = buffer; + td->hw.td.status = cpu_to_le32(status); + td->hw.td.info = cpu_to_le32(info); + td->hw.td.buffer = cpu_to_le32(buffer); } /*-------------------------------------------------------------------*/ // Removes ALL qhs in chain (paranoia!) @@ -485,24 +478,25 @@ _static void cleanup_skel (uhci_t *s) if (s->td32ms) { unlink_td(s,s->td32ms,1); - delete_desc(s->td32ms); + delete_desc(s, s->td32ms); } for (n = 0; n < 8; n++) { td = s->int_chain[n]; - clean_td_chain (td); + clean_td_chain (s, td); } if (s->iso_td) { for (n = 0; n < 1024; n++) { td = s->iso_td[n]; - clean_td_chain (td); + clean_td_chain (s, td); } kfree (s->iso_td); } if (s->framelist) - free_page ((unsigned long) s->framelist); + pci_free_consistent(s->uhci_pci, PAGE_SIZE, + s->framelist, s->framelist_dma); if (s->control_chain) { // completed init_skel? @@ -519,14 +513,20 @@ _static void cleanup_skel (uhci_t *s) } else { if (s->ls_control_chain) - delete_desc (s->ls_control_chain); + delete_desc (s, s->ls_control_chain); if (s->control_chain) - delete_desc(s->control_chain); + delete_desc(s, s->control_chain); if (s->bulk_chain) - delete_desc (s->bulk_chain); + delete_desc (s, s->bulk_chain); if (s->chain_end) - delete_desc (s->chain_end); + delete_desc (s, s->chain_end); } + + if (s->desc_pool) { + pci_pool_destroy(s->desc_pool); + s->desc_pool = NULL; + } + dbg("cleanup_skel finished"); } /*-------------------------------------------------------------------*/ @@ -539,13 +539,22 @@ _static int init_skel (uhci_t *s) dbg("init_skel"); - s->framelist = (__u32 *) get_free_page (GFP_KERNEL); + s->framelist = pci_alloc_consistent(s->uhci_pci, PAGE_SIZE, + &s->framelist_dma); if (!s->framelist) return -ENOMEM; memset (s->framelist, 0, 4096); + dbg("creating descriptor pci_pool"); + + s->desc_pool = pci_pool_create("uhci_desc", s->uhci_pci, + sizeof(uhci_desc_t), 16, 0, + GFP_DMA | GFP_ATOMIC); + if (!s->desc_pool) + goto init_skel_cleanup; + dbg("allocating iso desc pointer list"); s->iso_td = (uhci_desc_t **) kmalloc (1024 * sizeof (uhci_desc_t*), GFP_KERNEL); @@ -560,33 +569,33 @@ _static int init_skel (uhci_t *s) dbg("allocating iso descs"); for (n = 0; n < 1024; n++) { // allocate skeleton iso/irq-tds - ret = alloc_td (&td, 0); + ret = alloc_td (s, &td, 0); if (ret) goto init_skel_cleanup; s->iso_td[n] = td; - s->framelist[n] = ((__u32) virt_to_bus (td)); + s->framelist[n] = cpu_to_le32((__u32) td->dma_addr); } dbg("allocating qh: chain_end"); - ret = alloc_qh (&qh); + ret = alloc_qh (s, &qh); if (ret) goto init_skel_cleanup; s->chain_end = qh; - ret = alloc_td (&td, 0); + ret = alloc_td (s, &td, 0); if (ret) goto init_skel_cleanup; fill_td (td, 0 * TD_CTRL_IOC, 0, 0); // generate 1ms interrupt (enabled on demand) insert_td (s, qh, td, 0); - qh->hw.qh.element &= ~UHCI_PTR_TERM; // remove TERM bit + qh->hw.qh.element &= cpu_to_le32(~UHCI_PTR_TERM); // remove TERM bit s->td1ms=td; dbg("allocating qh: bulk_chain"); - ret = alloc_qh (&qh); + ret = alloc_qh (s, &qh); if (ret) goto init_skel_cleanup; @@ -594,7 +603,7 @@ _static int init_skel (uhci_t *s) s->bulk_chain = qh; dbg("allocating qh: control_chain"); - ret = alloc_qh (&qh); + ret = alloc_qh (s, &qh); if (ret) goto init_skel_cleanup; @@ -603,11 +612,11 @@ _static int init_skel (uhci_t *s) #ifdef CONFIG_USB_UHCI_HIGH_BANDWIDTH // disabled reclamation loop - s->chain_end->hw.qh.head=virt_to_bus(s->control_chain) | UHCI_PTR_QH | UHCI_PTR_TERM; + s->chain_end->hw.qh.head = cpu_to_le32(s->control_chain->dma_addr | UHCI_PTR_QH | UHCI_PTR_TERM); #endif dbg("allocating qh: ls_control_chain"); - ret = alloc_qh (&qh); + ret = alloc_qh (s, &qh); if (ret) goto init_skel_cleanup; @@ -622,15 +631,15 @@ _static int init_skel (uhci_t *s) for (n = 0; n < 8; n++) { uhci_desc_t *td; - alloc_td (&td, 0); + alloc_td (s, &td, 0); if (!td) goto init_skel_cleanup; s->int_chain[n] = td; if (n == 0) { - s->int_chain[0]->hw.td.link = virt_to_bus (s->ls_control_chain) | UHCI_PTR_QH; + s->int_chain[0]->hw.td.link = cpu_to_le32(s->ls_control_chain->dma_addr | UHCI_PTR_QH); } else { - s->int_chain[n]->hw.td.link = virt_to_bus (s->int_chain[0]); + s->int_chain[n]->hw.td.link = cpu_to_le32(s->int_chain[0]->dma_addr); } } @@ -639,16 +648,17 @@ _static int init_skel (uhci_t *s) for (n = 0; n < 1024; n++) { // link all iso-tds to the interrupt chains int m, o; - dbg("framelist[%i]=%x",n,s->framelist[n]); + dbg("framelist[%i]=%x",n,le32_to_cpu(s->framelist[n])); if ((n&127)==127) - ((uhci_desc_t*) s->iso_td[n])->hw.td.link = virt_to_bus(s->int_chain[0]); + ((uhci_desc_t*) s->iso_td[n])->hw.td.link = cpu_to_le32(s->int_chain[0]->dma_addr); else for (o = 1, m = 2; m <= 128; o++, m += m) if ((n & (m - 1)) == ((m - 1) / 2)) - ((uhci_desc_t*) s->iso_td[n])->hw.td.link = virt_to_bus (s->int_chain[o]); + ((uhci_desc_t*) s->iso_td[n])->hw.td.link = + cpu_to_le32(s->int_chain[o]->dma_addr); } - ret = alloc_td (&td, 0); + ret = alloc_td (s, &td, 0); if (ret) goto init_skel_cleanup; @@ -689,12 +699,12 @@ _static int uhci_submit_control_urb (urb_t *urb) } dbg("uhci_submit_control start"); - alloc_qh (&qh); // alloc qh for this request + alloc_qh (s, &qh); // alloc qh for this request if (!qh) return -ENOMEM; - alloc_td (&td, UHCI_PTR_DEPTH * depth_first); // get td for setup stage + alloc_td (s, &td, UHCI_PTR_DEPTH * depth_first); // get td for setup stage if (!td) { delete_qh (s, qh); @@ -709,7 +719,7 @@ _static int uhci_submit_control_urb (urb_t *urb) (urb->transfer_flags & USB_DISABLE_SPD ? 0 : TD_CTRL_SPD) | (3 << 27); /* Build the TD for the control request, try forever, 8 bytes of data */ - fill_td (td, status, destination | (7 << 21), virt_to_bus (urb->setup_packet)); + fill_td (td, status, destination | (7 << 21), urb_priv->setup_packet_dma); insert_td (s, qh, td, 0); // queue 'setup stage'-td in qh #if 0 @@ -732,19 +742,18 @@ _static int uhci_submit_control_urb (urb_t *urb) while (len > 0) { int pktsze = len; - alloc_td (&td, UHCI_PTR_DEPTH * depth_first); - if (!td) { - delete_qh (s, qh); - return -ENOMEM; - } + alloc_td (s, &td, UHCI_PTR_DEPTH * depth_first); + if (!td) + goto fail_unmap_enomem; if (pktsze > maxsze) pktsze = maxsze; destination ^= 1 << TD_TOKEN_TOGGLE; // toggle DATA0/1 + // Status, pktsze bytes of data fill_td (td, status, destination | ((pktsze - 1) << 21), - virt_to_bus (data)); // Status, pktsze bytes of data + urb_priv->transfer_buffer_dma + (data - (char *)urb->transfer_buffer)); insert_td (s, qh, td, UHCI_PTR_DEPTH * depth_first); // queue 'data stage'-td in qh @@ -764,12 +773,11 @@ _static int uhci_submit_control_urb (urb_t *urb) destination |= 1 << TD_TOKEN_TOGGLE; /* End in Data1 */ - alloc_td (&td, UHCI_PTR_DEPTH); + alloc_td (s, &td, UHCI_PTR_DEPTH); - if (!td) { - delete_qh (s, qh); - return -ENOMEM; - } + if (!td) + goto fail_unmap_enomem; + status &=~TD_CTRL_SPD; /* no limit on errors on final packet , 0 bytes of data */ @@ -783,7 +791,7 @@ _static int uhci_submit_control_urb (urb_t *urb) urb->status = -EINPROGRESS; queue_urb (s, urb); // queue before inserting in desc chain - qh->hw.qh.element &= ~UHCI_PTR_TERM; + qh->hw.qh.element &= cpu_to_le32(~UHCI_PTR_TERM); //uhci_show_queue(qh); /* Start it up... put low speed first */ @@ -794,6 +802,10 @@ _static int uhci_submit_control_urb (urb_t *urb) dbg("uhci_submit_control end"); return 0; + +fail_unmap_enomem: + delete_qh(s, qh); + return -ENOMEM; } /*-------------------------------------------------------------------*/ // For queued bulk transfers, two additional QH helpers are allocated (nqh, bqh) @@ -829,15 +841,15 @@ _static int uhci_submit_bulk_urb (urb_t *urb, urb_t *bulk_urb) upriv = (urb_priv_t*)urb->hcpriv; if (!bulk_urb) { - alloc_qh (&qh); // get qh for this request + alloc_qh (s, &qh); // get qh for this request if (!qh) return -ENOMEM; if (urb->transfer_flags & USB_QUEUE_BULK) { - alloc_qh(&nqh); // placeholder for clean unlink + alloc_qh(s, &nqh); // placeholder for clean unlink if (!nqh) { - delete_desc (qh); + delete_desc (s, qh); return -ENOMEM; } upriv->next_qh = nqh; @@ -853,17 +865,17 @@ _static int uhci_submit_bulk_urb (urb_t *urb, urb_t *bulk_urb) } if (urb->transfer_flags & USB_QUEUE_BULK) { - alloc_qh (&bqh); // "bottom" QH, + alloc_qh (s, &bqh); // "bottom" QH, if (!bqh) { if (!bulk_urb) { - delete_desc(qh); - delete_desc(nqh); + delete_desc(s, qh); + delete_desc(s, nqh); } return -ENOMEM; } - bqh->hw.qh.element = UHCI_PTR_TERM; - bqh->hw.qh.head = virt_to_bus(nqh) | UHCI_PTR_QH; // element + bqh->hw.qh.element = cpu_to_le32(UHCI_PTR_TERM); + bqh->hw.qh.head = cpu_to_le32(nqh->dma_addr | UHCI_PTR_QH); // element upriv->bottom_qh = bqh; } queue_dbg("uhci_submit_bulk: qh %p bqh %p nqh %p",qh, bqh, nqh); @@ -882,7 +894,7 @@ _static int uhci_submit_bulk_urb (urb_t *urb, urb_t *bulk_urb) do { // TBD: Really allow zero-length packets? int pktsze = len; - alloc_td (&td, UHCI_PTR_DEPTH * depth_first); + alloc_td (s, &td, UHCI_PTR_DEPTH * depth_first); if (!td) { delete_qh (s, qh); @@ -896,7 +908,8 @@ _static int uhci_submit_bulk_urb (urb_t *urb, urb_t *bulk_urb) info = destination | (((pktsze - 1)&UHCI_NULL_DATA_SIZE) << 21) | (usb_gettoggle (urb->dev, usb_pipeendpoint (pipe), usb_pipeout (pipe)) << TD_TOKEN_TOGGLE); - fill_td (td, status, info, virt_to_bus (data)); + fill_td (td, status, info, + urb_priv->transfer_buffer_dma + (data - (char *)urb->transfer_buffer)); data += pktsze; len -= pktsze; @@ -904,7 +917,7 @@ _static int uhci_submit_bulk_urb (urb_t *urb, urb_t *bulk_urb) last = (len == 0 && (usb_pipein(pipe) || pktsze < maxsze || !(urb->transfer_flags & USB_ZERO_PACKET))); if (last) - td->hw.td.status |= TD_CTRL_IOC; // last one generates INT + td->hw.td.status |= cpu_to_le32(TD_CTRL_IOC); // last one generates INT insert_td (s, qh, td, UHCI_PTR_DEPTH * depth_first); if (!first_td) @@ -925,9 +938,9 @@ _static int uhci_submit_bulk_urb (urb_t *urb, urb_t *bulk_urb) queue_urb_unlocked (s, urb); if (urb->transfer_flags & USB_QUEUE_BULK) - qh->hw.qh.element = virt_to_bus (first_td); + qh->hw.qh.element = cpu_to_le32(first_td->dma_addr); else - qh->hw.qh.element &= ~UHCI_PTR_TERM; // arm QH + qh->hw.qh.element &= cpu_to_le32(~UHCI_PTR_TERM); // arm QH if (!bulk_urb) { // new bulk queue if (urb->transfer_flags & USB_QUEUE_BULK) { @@ -964,7 +977,7 @@ _static void uhci_clean_iso_step2(uhci_t *s, urb_priv_t *urb_priv) while ((p = urb_priv->desc_list.next) != &urb_priv->desc_list) { td = list_entry (p, uhci_desc_t, desc_list); list_del (p); - delete_desc (td); + delete_desc (s, td); } } /*-------------------------------------------------------------------*/ @@ -996,7 +1009,7 @@ _static void uhci_clean_transfer (uhci_t *s, urb_t *urb, uhci_desc_t *qh, int mo spin_lock_irqsave (&s->qh_lock, flags); prevqh = list_entry (ppriv->desc_list.next, uhci_desc_t, desc_list); prevtd = list_entry (prevqh->vertical.prev, uhci_desc_t, vertical); - prevtd->hw.td.link = virt_to_bus(priv->bottom_qh) | UHCI_PTR_QH; // skip current qh + prevtd->hw.td.link = cpu_to_le32(priv->bottom_qh->dma_addr | UHCI_PTR_QH); // skip current qh mb(); queue_dbg("uhci_clean_transfer: relink pqh %p, ptd %p",prevqh, prevtd); spin_unlock_irqrestore (&s->qh_lock, flags); @@ -1039,7 +1052,7 @@ _static void uhci_clean_transfer (uhci_t *s, urb_t *urb, uhci_desc_t *qh, int mo if (!priv->prev_queued_urb) { // top QH prevqh = list_entry (qh->horizontal.prev, uhci_desc_t, horizontal); - prevqh->hw.qh.head = virt_to_bus(bqh) | UHCI_PTR_QH; + prevqh->hw.qh.head = cpu_to_le32(bqh->dma_addr | UHCI_PTR_QH); list_del (&qh->horizontal); // remove this qh form horizontal chain list_add (&bqh->horizontal, &prevqh->horizontal); // insert next bqh in horizontal chain } @@ -1052,7 +1065,7 @@ _static void uhci_clean_transfer (uhci_t *s, urb_t *urb, uhci_desc_t *qh, int mo ppriv->bottom_qh = bnqh; ppriv->next_queued_urb = nurb; prevqh = list_entry (ppriv->desc_list.next, uhci_desc_t, desc_list); - prevqh->hw.qh.head = virt_to_bus(bqh) | UHCI_PTR_QH; + prevqh->hw.qh.head = cpu_to_le32(bqh->dma_addr | UHCI_PTR_QH); } mb(); @@ -1083,6 +1096,38 @@ _static void uhci_release_bandwidth(urb_t *urb) } } } + +_static void uhci_urb_dma_sync(uhci_t *s, urb_t *urb, urb_priv_t *urb_priv) +{ + if (urb_priv->setup_packet_dma) + pci_dma_sync_single(s->uhci_pci, urb_priv->setup_packet_dma, + sizeof(devrequest), PCI_DMA_TODEVICE); + + if (urb_priv->transfer_buffer_dma) + pci_dma_sync_single(s->uhci_pci, urb_priv->transfer_buffer_dma, + urb->transfer_buffer_length, + usb_pipein(urb->pipe) ? + PCI_DMA_FROMDEVICE : + PCI_DMA_TODEVICE); +} + +_static void uhci_urb_dma_unmap(uhci_t *s, urb_t *urb, urb_priv_t *urb_priv) +{ + if (urb_priv->setup_packet_dma) { + pci_unmap_single(s->uhci_pci, urb_priv->setup_packet_dma, + sizeof(devrequest), PCI_DMA_TODEVICE); + urb_priv->setup_packet_dma = 0; + } + if (urb_priv->transfer_buffer_dma) { + pci_unmap_single(s->uhci_pci, urb_priv->transfer_buffer_dma, + urb->transfer_buffer_length, + usb_pipein(urb->pipe) ? + PCI_DMA_FROMDEVICE : + PCI_DMA_TODEVICE); + urb_priv->transfer_buffer_dma = 0; + } +} + /*-------------------------------------------------------------------*/ // unlinks an urb by dequeuing its qh, waits some frames and forgets it _static int uhci_unlink_urb_sync (uhci_t *s, urb_t *urb) @@ -1133,6 +1178,8 @@ _static int uhci_unlink_urb_sync (uhci_t *s, urb_t *urb) uhci_wait_ms(1); } + uhci_urb_dma_unmap(s, urb, urb->hcpriv); + #ifdef DEBUG_SLAB kmem_cache_free (urb_priv_kmem, urb->hcpriv); #else @@ -1210,6 +1257,7 @@ _static void uhci_cleanup_unlink(uhci_t *s, int force) urb_priv = urb->hcpriv; list_del (&urb->urb_list); + uhci_urb_dma_sync(s, urb, urb_priv); if (urb->complete) { spin_unlock(&s->urb_list_lock); urb->dev = NULL; @@ -1226,6 +1274,8 @@ _static void uhci_cleanup_unlink(uhci_t *s, int force) break; } + uhci_urb_dma_unmap(s, urb, urb_priv); + usb_dec_dev_use (dev); #ifdef DEBUG_SLAB kmem_cache_free (urb_priv_kmem, urb_priv); @@ -1452,7 +1502,7 @@ _static int uhci_submit_int_urb (urb_t *urb) if (urb->transfer_buffer_length > usb_maxpacket (urb->dev, pipe, usb_pipeout (pipe))) return -EINVAL; - ret = alloc_td (&td, UHCI_PTR_DEPTH); + ret = alloc_td (s, &td, UHCI_PTR_DEPTH); if (ret) return -ENOMEM; @@ -1466,7 +1516,7 @@ _static int uhci_submit_int_urb (urb_t *urb) info = destination | (usb_gettoggle (urb->dev, usb_pipeendpoint (pipe), usb_pipeout (pipe)) << TD_TOKEN_TOGGLE); - fill_td (td, status, info, virt_to_bus (urb->transfer_buffer)); + fill_td (td, status, info, urb_priv->transfer_buffer_dma); list_add_tail (&td->desc_list, &urb_priv->desc_list); urb->status = -EINPROGRESS; @@ -1524,14 +1574,14 @@ _static int uhci_submit_iso_urb (urb_t *urb) } else #endif - ret = alloc_td (&td, UHCI_PTR_DEPTH); + ret = alloc_td (s, &td, UHCI_PTR_DEPTH); if (ret) { int i; // Cleanup allocated TDs for (i = 0; i < n; n++) if (tdm[i]) - delete_desc(tdm[i]); + delete_desc(s, tdm[i]); kfree (tdm); goto err; } @@ -1554,7 +1604,7 @@ _static int uhci_submit_iso_urb (urb_t *urb) status |= TD_CTRL_IOC; fill_td (td, status, destination | (((urb->iso_frame_desc[n].length - 1) & 0x7ff) << 21), - virt_to_bus (urb->transfer_buffer + urb->iso_frame_desc[n].offset)); + urb_priv->transfer_buffer_dma + urb->iso_frame_desc[n].offset); list_add_tail (&td->desc_list, &urb_priv->desc_list); if (n == last) { @@ -1663,6 +1713,22 @@ _static int uhci_submit_urb (urb_t *urb) urb_priv->bottom_qh = NULL; urb_priv->next_qh = NULL; + if (usb_pipetype (urb->pipe) == PIPE_CONTROL) + urb_priv->setup_packet_dma = pci_map_single(s->uhci_pci, urb->setup_packet, + sizeof(devrequest), PCI_DMA_TODEVICE); + else + urb_priv->setup_packet_dma = 0; + + if (urb->transfer_buffer_length) + urb_priv->transfer_buffer_dma = pci_map_single(s->uhci_pci, + urb->transfer_buffer, + urb->transfer_buffer_length, + usb_pipein(urb->pipe) ? + PCI_DMA_FROMDEVICE : + PCI_DMA_TODEVICE); + else + urb_priv->transfer_buffer_dma = 0; + if (usb_pipetype (urb->pipe) == PIPE_BULK) { if (queued_urb) { @@ -1724,6 +1790,7 @@ _static int uhci_submit_urb (urb_t *urb) dbg("submit_urb: scheduled with ret: %d", ret); if (ret != 0) { + uhci_urb_dma_unmap(s, urb, urb_priv); usb_dec_dev_use (urb->dev); #ifdef DEBUG_SLAB kmem_cache_free(urb_priv_kmem, urb_priv); @@ -2277,7 +2344,7 @@ _static int process_transfer (uhci_t *s, urb_t *urb, int mode) */ if (urb_priv->flags && - ((qh->hw.qh.element == UHCI_PTR_TERM) ||(!(last_desc->hw.td.status & TD_CTRL_ACTIVE)))) + ((qh->hw.qh.element == cpu_to_le32(UHCI_PTR_TERM)) ||(!(last_desc->hw.td.status & cpu_to_le32(TD_CTRL_ACTIVE))))) goto transfer_finished; urb->actual_length=0; @@ -2285,15 +2352,15 @@ _static int process_transfer (uhci_t *s, urb_t *urb, int mode) for (; p != &qh->vertical; p = p->next) { desc = list_entry (p, uhci_desc_t, vertical); - if (desc->hw.td.status & TD_CTRL_ACTIVE) { // do not process active TDs + if (desc->hw.td.status & cpu_to_le32(TD_CTRL_ACTIVE)) { // do not process active TDs if (mode==2) // if called from async_unlink uhci_clean_transfer(s, urb, qh, mode); return ret; } - actual_length = (desc->hw.td.status + 1) & 0x7ff; // extract transfer parameters from TD - maxlength = (((desc->hw.td.info >> 21) & 0x7ff) + 1) & 0x7ff; - status = uhci_map_status (uhci_status_bits (desc->hw.td.status), usb_pipeout (urb->pipe)); + actual_length = (le32_to_cpu(desc->hw.td.status) + 1) & 0x7ff; // extract transfer parameters from TD + maxlength = (((le32_to_cpu(desc->hw.td.info) >> 21) & 0x7ff) + 1) & 0x7ff; + status = uhci_map_status (uhci_status_bits (le32_to_cpu(desc->hw.td.status)), usb_pipeout (urb->pipe)); if (status == -EPIPE) { // see if EP is stalled // set up stalled condition @@ -2307,7 +2374,7 @@ _static int process_transfer (uhci_t *s, urb_t *urb, int mode) urb->error_count++; break; } - else if ((desc->hw.td.info & 0xff) != USB_PID_SETUP) + else if ((le32_to_cpu(desc->hw.td.info) & 0xff) != USB_PID_SETUP) urb->actual_length += actual_length; // got less data than requested @@ -2320,9 +2387,9 @@ _static int process_transfer (uhci_t *s, urb_t *urb, int mode) // short read during control-IN: re-start status stage if ((usb_pipetype (urb->pipe) == PIPE_CONTROL)) { - if (uhci_packetid(last_desc->hw.td.info) == USB_PID_OUT) { + if (uhci_packetid(le32_to_cpu(last_desc->hw.td.info)) == USB_PID_OUT) { - qh->hw.qh.element = virt_to_bus (last_desc); // re-trigger status stage + qh->hw.qh.element = cpu_to_le32(last_desc->dma_addr); // re-trigger status stage dbg("short packet during control transfer, retrigger status stage @ %p",last_desc); //uhci_show_td (desc); //uhci_show_td (last_desc); @@ -2331,14 +2398,14 @@ _static int process_transfer (uhci_t *s, urb_t *urb, int mode) } } // all other cases: short read is OK - data_toggle = uhci_toggle (desc->hw.td.info); + data_toggle = uhci_toggle (le32_to_cpu(desc->hw.td.info)); break; } else if (status) goto is_error; - data_toggle = uhci_toggle (desc->hw.td.info); - queue_dbg("process_transfer: len:%d status:%x mapped:%x toggle:%d", actual_length, desc->hw.td.status,status, data_toggle); + data_toggle = uhci_toggle (le32_to_cpu(desc->hw.td.info)); + queue_dbg("process_transfer: len:%d status:%x mapped:%x toggle:%d", actual_length, le32_to_cpu(desc->hw.td.status),status, data_toggle); } @@ -2375,20 +2442,20 @@ _static int process_interrupt (uhci_t *s, urb_t *urb) { desc = list_entry (p, uhci_desc_t, desc_list); - if (desc->hw.td.status & TD_CTRL_ACTIVE) { + if (desc->hw.td.status & cpu_to_le32(TD_CTRL_ACTIVE)) { // do not process active TDs - //dbg("TD ACT Status @%p %08x",desc,desc->hw.td.status); + //dbg("TD ACT Status @%p %08x",desc,le32_to_cpu(desc->hw.td.status)); break; } - if (!desc->hw.td.status & TD_CTRL_IOC) { + if (!desc->hw.td.status & cpu_to_le32(TD_CTRL_IOC)) { // do not process one-shot TDs, no recycling break; } // extract transfer parameters from TD - actual_length = (desc->hw.td.status + 1) & 0x7ff; - status = uhci_map_status (uhci_status_bits (desc->hw.td.status), usb_pipeout (urb->pipe)); + actual_length = (le32_to_cpu(desc->hw.td.status) + 1) & 0x7ff; + status = uhci_map_status (uhci_status_bits (le32_to_cpu(desc->hw.td.status)), usb_pipeout (urb->pipe)); // see if EP is stalled if (status == -EPIPE) { @@ -2406,6 +2473,7 @@ _static int process_interrupt (uhci_t *s, urb_t *urb) urb->actual_length = actual_length; recycle: + uhci_urb_dma_sync(s, urb, urb->hcpriv); if (urb->complete) { //dbg("process_interrupt: calling completion, status %i",status); urb->status = status; @@ -2428,23 +2496,23 @@ _static int process_interrupt (uhci_t *s, urb_t *urb) // Recycle INT-TD if interval!=0, else mark TD as one-shot if (urb->interval) { - desc->hw.td.info &= ~(1 << TD_TOKEN_TOGGLE); + desc->hw.td.info &= cpu_to_le32(~(1 << TD_TOKEN_TOGGLE)); if (status==0) { ((urb_priv_t*)urb->hcpriv)->started=jiffies; - desc->hw.td.info |= (usb_gettoggle (urb->dev, usb_pipeendpoint (urb->pipe), - usb_pipeout (urb->pipe)) << TD_TOKEN_TOGGLE); + desc->hw.td.info |= cpu_to_le32((usb_gettoggle (urb->dev, usb_pipeendpoint (urb->pipe), + usb_pipeout (urb->pipe)) << TD_TOKEN_TOGGLE)); usb_dotoggle (urb->dev, usb_pipeendpoint (urb->pipe), usb_pipeout (urb->pipe)); } else { - desc->hw.td.info |= (!usb_gettoggle (urb->dev, usb_pipeendpoint (urb->pipe), - usb_pipeout (urb->pipe)) << TD_TOKEN_TOGGLE); + desc->hw.td.info |= cpu_to_le32((!usb_gettoggle (urb->dev, usb_pipeendpoint (urb->pipe), + usb_pipeout (urb->pipe)) << TD_TOKEN_TOGGLE)); } - desc->hw.td.status= (urb->pipe & TD_CTRL_LS) | TD_CTRL_ACTIVE | TD_CTRL_IOC | - (urb->transfer_flags & USB_DISABLE_SPD ? 0 : TD_CTRL_SPD) | (3 << 27); + desc->hw.td.status= cpu_to_le32((urb->pipe & TD_CTRL_LS) | TD_CTRL_ACTIVE | TD_CTRL_IOC | + (urb->transfer_flags & USB_DISABLE_SPD ? 0 : TD_CTRL_SPD) | (3 << 27)); mb(); } else { uhci_unlink_urb_async(s, urb); - desc->hw.td.status &= ~TD_CTRL_IOC; // inactivate TD + desc->hw.td.status &= cpu_to_le32(~TD_CTRL_IOC); // inactivate TD } } } @@ -2462,23 +2530,23 @@ _static int process_iso (uhci_t *s, urb_t *urb, int mode) uhci_desc_t *desc = list_entry (urb_priv->desc_list.prev, uhci_desc_t, desc_list); dbg("urb contains iso request"); - if ((desc->hw.td.status & TD_CTRL_ACTIVE) && !mode) + if ((desc->hw.td.status & cpu_to_le32(TD_CTRL_ACTIVE)) && !mode) return -EXDEV; // last TD not finished urb->error_count = 0; urb->actual_length = 0; urb->status = 0; dbg("process iso urb %p, %li, %i, %i, %i %08x",urb,jiffies,UHCI_GET_CURRENT_FRAME(s), - urb->number_of_packets,mode,desc->hw.td.status); + urb->number_of_packets,mode,le32_to_cpu(desc->hw.td.status)); for (i = 0; p != &urb_priv->desc_list; i++) { desc = list_entry (p, uhci_desc_t, desc_list); //uhci_show_td(desc); - if (desc->hw.td.status & TD_CTRL_ACTIVE) { + if (desc->hw.td.status & cpu_to_le32(TD_CTRL_ACTIVE)) { // means we have completed the last TD, but not the TDs before - desc->hw.td.status &= ~TD_CTRL_ACTIVE; - dbg("TD still active (%x)- grrr. paranoia!", desc->hw.td.status); + desc->hw.td.status &= cpu_to_le32(~TD_CTRL_ACTIVE); + dbg("TD still active (%x)- grrr. paranoia!", le32_to_cpu(desc->hw.td.status)); ret = -EXDEV; urb->iso_frame_desc[i].status = ret; unlink_td (s, desc, 1); @@ -2495,15 +2563,8 @@ _static int process_iso (uhci_t *s, urb_t *urb, int mode) goto err; } - if (urb->iso_frame_desc[i].offset + urb->transfer_buffer != bus_to_virt (desc->hw.td.buffer)) { - // Hm, something really weird is going on - dbg("Pointer Paranoia: %p!=%p", urb->iso_frame_desc[i].offset + urb->transfer_buffer, bus_to_virt (desc->hw.td.buffer)); - ret = -EINVAL; - urb->iso_frame_desc[i].status = ret; - goto err; - } - urb->iso_frame_desc[i].actual_length = (desc->hw.td.status + 1) & 0x7ff; - urb->iso_frame_desc[i].status = uhci_map_status (uhci_status_bits (desc->hw.td.status), usb_pipeout (urb->pipe)); + urb->iso_frame_desc[i].actual_length = (le32_to_cpu(desc->hw.td.status) + 1) & 0x7ff; + urb->iso_frame_desc[i].status = uhci_map_status (uhci_status_bits (le32_to_cpu(desc->hw.td.status)), usb_pipeout (urb->pipe)); urb->actual_length += urb->iso_frame_desc[i].actual_length; err: @@ -2513,11 +2574,11 @@ _static int process_iso (uhci_t *s, urb_t *urb, int mode) urb->status = urb->iso_frame_desc[i].status; } dbg("process_iso: %i: len:%d %08x status:%x", - i, urb->iso_frame_desc[i].actual_length, desc->hw.td.status,urb->iso_frame_desc[i].status); + i, urb->iso_frame_desc[i].actual_length, le32_to_cpu(desc->hw.td.status),urb->iso_frame_desc[i].status); list_del (p); p = p->next; - delete_desc (desc); + delete_desc (s, desc); } dbg("process_iso: exit %i (%d), actual_len %i", i, ret,urb->actual_length); @@ -2552,6 +2613,7 @@ _static int process_urb (uhci_t *s, struct list_head *p) } if (urb->status != -EINPROGRESS) { + urb_priv_t *urb_priv; struct usb_device *usb_dev; usb_dev=urb->dev; @@ -2567,10 +2629,14 @@ _static int process_urb (uhci_t *s, struct list_head *p) dbg("dequeued urb: %p", urb); dequeue_urb (s, urb); + urb_priv = urb->hcpriv; + + uhci_urb_dma_unmap(s, urb, urb_priv); + #ifdef DEBUG_SLAB - kmem_cache_free(urb_priv_kmem, urb->hcpriv); + kmem_cache_free(urb_priv_kmem, urb_priv); #else - kfree (urb->hcpriv); + kfree (urb_priv); #endif if ((usb_pipetype (urb->pipe) != PIPE_INTERRUPT)) { // process_interrupt does completion on its own @@ -2769,7 +2835,7 @@ _static void start_hc (uhci_t *s) /* Start at frame 0 */ outw (0, io_addr + USBFRNUM); - outl (virt_to_bus (s->framelist), io_addr + USBFLBASEADD); + outl (s->framelist_dma, io_addr + USBFLBASEADD); /* Run and mark it configured with a 64-byte max packet */ outw (USBCMD_RS | USBCMD_CF | USBCMD_MAXP, io_addr + USBCMD); @@ -3012,19 +3078,10 @@ static int __init uhci_hcd_init (void) int retval; #ifdef DEBUG_SLAB - - uhci_desc_kmem = kmem_cache_create("uhci_desc", sizeof(uhci_desc_t), 0, SLAB_HWCACHE_ALIGN, NULL, NULL); - - if(!uhci_desc_kmem) { - err("kmem_cache_create for uhci_desc failed (out of memory)"); - return -ENOMEM; - } - urb_priv_kmem = kmem_cache_create("urb_priv", sizeof(urb_priv_t), 0, SLAB_HWCACHE_ALIGN, NULL, NULL); if(!urb_priv_kmem) { err("kmem_cache_create for urb_priv_t failed (out of memory)"); - kmem_cache_destroy(uhci_desc_kmem); return -ENOMEM; } #endif @@ -3040,8 +3097,6 @@ static int __init uhci_hcd_init (void) if (retval < 0 ) { if (kmem_cache_destroy(urb_priv_kmem)) err("urb_priv_kmem remained"); - if (kmem_cache_destroy(uhci_desc_kmem)) - err("uhci_desc_kmem remained"); } #endif @@ -3053,9 +3108,6 @@ static void __exit uhci_hcd_cleanup (void) pci_unregister_driver (&uhci_pci_driver); #ifdef DEBUG_SLAB - if(kmem_cache_destroy(uhci_desc_kmem)) - err("uhci_desc_kmem remained"); - if(kmem_cache_destroy(urb_priv_kmem)) err("urb_priv_kmem remained"); #endif diff --git a/drivers/usb/usb-uhci.h b/drivers/usb/usb-uhci.h index 67eb4d210cbf..84b47949c769 100644 --- a/drivers/usb/usb-uhci.h +++ b/drivers/usb/usb-uhci.h @@ -146,6 +146,7 @@ typedef struct { uhci_qh_t qh; } hw; uhci_desc_type_t type; + dma_addr_t dma_addr; struct list_head horizontal; struct list_head vertical; struct list_head desc_list; @@ -154,6 +155,8 @@ typedef struct { typedef struct { struct list_head desc_list; // list pointer to all corresponding TDs/QHs associated with this request + dma_addr_t setup_packet_dma; + dma_addr_t transfer_buffer_dma; unsigned long started; urb_t *next_queued_urb; // next queued urb for this EP urb_t *prev_queued_urb; @@ -195,6 +198,7 @@ typedef struct uhci { struct usb_bus *bus; // our bus __u32 *framelist; + dma_addr_t framelist_dma; uhci_desc_t **iso_td; uhci_desc_t *int_chain[8]; uhci_desc_t *ls_control_chain; @@ -213,11 +217,12 @@ typedef struct uhci { long timeout_check; int timeout_urbs; struct pci_dev *uhci_pci; + struct pci_pool *desc_pool; } uhci_t, *puhci_t; -#define MAKE_TD_ADDR(a) (virt_to_bus(a)&~UHCI_PTR_QH) -#define MAKE_QH_ADDR(a) (virt_to_bus(a)|UHCI_PTR_QH) +#define MAKE_TD_ADDR(a) ((a)->dma_addr&~UHCI_PTR_QH) +#define MAKE_QH_ADDR(a) ((a)->dma_addr|UHCI_PTR_QH) #define UHCI_GET_CURRENT_FRAME(uhci) (inw ((uhci)->io_addr + USBFRNUM)) /* ------------------------------------------------------------------------------------ diff --git a/drivers/video/aty.h b/drivers/video/aty.h index 938ba185716c..d9c673d26394 100644 --- a/drivers/video/aty.h +++ b/drivers/video/aty.h @@ -738,6 +738,7 @@ #define LI_CHIP_ID 0x4c49 /* RAGE LT PRO */ #define LP_CHIP_ID 0x4c50 /* RAGE LT PRO */ #define LT_CHIP_ID 0x4c54 /* RAGE LT */ +#define XL_CHIP_ID 0x4752 /* RAGE (XL) */ #define GT_CHIP_ID 0x4754 /* RAGE (GT) */ #define GU_CHIP_ID 0x4755 /* RAGE II/II+ (GTB) */ #define GV_CHIP_ID 0x4756 /* RAGE IIC, PCI */ diff --git a/drivers/video/atyfb.c b/drivers/video/atyfb.c index a24847591c2e..0c00935b45ef 100644 --- a/drivers/video/atyfb.c +++ b/drivers/video/atyfb.c @@ -561,6 +561,7 @@ static struct aty_features { { 0x4c49, 0x4c49, "3D RAGE LT PRO" }, { 0x4c50, 0x4c50, "3D RAGE LT PRO" }, { 0x4c54, 0x4c54, "3D RAGE LT" }, + { 0x4752, 0x4752, "3D RAGE (XL)" }, { 0x4754, 0x4754, "3D RAGE (GT)" }, { 0x4755, 0x4755, "3D RAGE II+ (GTB)" }, { 0x4756, 0x4756, "3D RAGE IIC (PCI)" }, @@ -722,7 +723,7 @@ static void init_engine(const struct atyfb_par *par, struct fb_info_aty *info) if (Gx == LB_CHIP_ID || Gx == LD_CHIP_ID || Gx == LI_CHIP_ID || Gx == LP_CHIP_ID || Gx == GB_CHIP_ID || Gx == GD_CHIP_ID || Gx == GI_CHIP_ID || Gx == GP_CHIP_ID || Gx == GQ_CHIP_ID || - Gx == LM_CHIP_ID || Gx == LN_CHIP_ID) + Gx == LM_CHIP_ID || Gx == LN_CHIP_ID || Gx == XL_CHIP_ID) reset_GTC_3D_engine(info); /* Reset engine, enable, and clear any engine errors */ @@ -2209,10 +2210,14 @@ static void aty_set_pll_ct(const struct fb_info_aty *info, if (!(Gx == GX_CHIP_ID || Gx == CX_CHIP_ID || Gx == CT_CHIP_ID || Gx == ET_CHIP_ID || ((Gx == VT_CHIP_ID || Gx == GT_CHIP_ID) && !(Rev & 0x07)))) { - if (info->ram_type >= SDRAM) - aty_st_pll(DLL_CNTL, 0xa6, info); - else - aty_st_pll(DLL_CNTL, 0xa0, info); + if (Gx == XL_CHIP_ID) { + aty_st_pll(DLL_CNTL, 0x80, info); + } else { + if (info->ram_type >= SDRAM) + aty_st_pll(DLL_CNTL, 0xa6, info); + else + aty_st_pll(DLL_CNTL, 0xa0, info); + } aty_st_pll(VFC_CNTL, 0x1b, info); aty_st_le32(DSP_CONFIG, pll->dsp_config, info); aty_st_le32(DSP_ON_OFF, pll->dsp_on_off, info); @@ -2334,6 +2339,7 @@ static void aty_calc_pll_ct(const struct fb_info_aty *info, struct pll_ct *pll) (Gx == GV_CHIP_ID) || (Gx == GW_CHIP_ID) || (Gx == GZ_CHIP_ID) || (Gx == LG_CHIP_ID) || (Gx == GB_CHIP_ID) || (Gx == GD_CHIP_ID) || (Gx == GI_CHIP_ID) || (Gx == GP_CHIP_ID) || (Gx == GQ_CHIP_ID) || + (Gx == XL_CHIP_ID) || (Gx == VU_CHIP_ID)) && (info->ram_type >= SDRAM)) pll->pll_gen_cntl = 0x04; else @@ -3214,7 +3220,7 @@ static void atyfb_save_palette(struct fb_info *fb, int enter) if (Gx == GT_CHIP_ID || Gx == GU_CHIP_ID || Gx == GV_CHIP_ID || Gx == GW_CHIP_ID || Gx == GZ_CHIP_ID || Gx == LG_CHIP_ID || Gx == GB_CHIP_ID || Gx == GD_CHIP_ID || Gx == GI_CHIP_ID || - Gx == GP_CHIP_ID || Gx == GQ_CHIP_ID) + Gx == GP_CHIP_ID || Gx == GQ_CHIP_ID || Gx == XL_CHIP_ID) tmp |= 0x2; aty_st_8(DAC_CNTL, tmp, info); aty_st_8(DAC_MASK, 0xff, info); @@ -3367,6 +3373,9 @@ static int __init aty_init(struct fb_info_aty *info, const char *name) /* RAGE PRO or LT PRO */ pll = 230; mclk = 100; + } else if (Gx == XL_CHIP_ID) { + pll = 230; + mclk = 120; } else if (Gx == LG_CHIP_ID) { /* Rage LT */ pll = 230; @@ -3801,34 +3810,36 @@ int __init atyfb_init(void) j++; } - /* - * Fix PROMs idea of MEM_CNTL settings... - */ - mem = aty_ld_le32(MEM_CNTL, info); - chip_id = aty_ld_le32(CONFIG_CHIP_ID, info); - if (((chip_id & CFG_CHIP_TYPE) == VT_CHIP_ID) && - !((chip_id >> 24) & 1)) { - switch (mem & 0x0f) { - case 3: - mem = (mem & ~(0x0f)) | 2; - break; - case 7: - mem = (mem & ~(0x0f)) | 3; - break; - case 9: - mem = (mem & ~(0x0f)) | 4; - break; - case 11: - mem = (mem & ~(0x0f)) | 5; - break; - default: - break; - } - if ((aty_ld_le32(CONFIG_STAT0, info) & 7) >= SDRAM) - mem &= ~(0x00700000); + if (pdev->device != XL_CHIP_ID) { + /* + * Fix PROMs idea of MEM_CNTL settings... + */ + mem = aty_ld_le32(MEM_CNTL, info); + chip_id = aty_ld_le32(CONFIG_CHIP_ID, info); + if (((chip_id & CFG_CHIP_TYPE) == VT_CHIP_ID) && + !((chip_id >> 24) & 1)) { + switch (mem & 0x0f) { + case 3: + mem = (mem & ~(0x0f)) | 2; + break; + case 7: + mem = (mem & ~(0x0f)) | 3; + break; + case 9: + mem = (mem & ~(0x0f)) | 4; + break; + case 11: + mem = (mem & ~(0x0f)) | 5; + break; + default: + break; + } + if ((aty_ld_le32(CONFIG_STAT0, info) & 7) >= SDRAM) + mem &= ~(0x00700000); + } + mem &= ~(0xcf80e000); /* Turn off all undocumented bits. */ + aty_st_le32(MEM_CNTL, mem, info); } - mem &= ~(0xcf80e000); /* Turn off all undocumented bits. */ - aty_st_le32(MEM_CNTL, mem, info); /* * If this is the console device, we will set default video @@ -3850,7 +3861,7 @@ int __init atyfb_init(void) if (node == pcp->prom_node) { struct fb_var_screeninfo *var = &default_var; - unsigned int N, P, Q, M, T; + unsigned int N, P, Q, M, T, R; u32 v_total, h_total; struct crtc crtc; u8 pll_regs[16]; @@ -3891,7 +3902,7 @@ int __init atyfb_init(void) N = pll_regs[7 + (clock_cntl & 3)]; /* - * PLL Post Devider P (Dependant on CLOCK_CNTL): + * PLL Post Divider P (Dependant on CLOCK_CNTL): */ P = 1 << (pll_regs[6] >> ((clock_cntl & 3) << 1)); @@ -3907,13 +3918,17 @@ int __init atyfb_init(void) * Q = ------- * 2 * R * - * where R is XTALIN (= 14318 kHz). + * where R is XTALIN (= 14318 or 29498 kHz). */ - T = 2 * Q * 14318 / M; + if (pdev->device == XL_CHIP_ID) + R = 29498; + else + R = 14318; + + T = 2 * Q * R / M; default_var.pixclock = 1000000000 / T; } - #else /* __sparc__ */ info->ati_regbase_phys = 0x7ff000 + addr; @@ -4297,7 +4312,8 @@ static int atyfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue, if (Gx == GT_CHIP_ID || Gx == GU_CHIP_ID || Gx == GV_CHIP_ID || Gx == GW_CHIP_ID || Gx == GZ_CHIP_ID || Gx == LG_CHIP_ID || Gx == GB_CHIP_ID || Gx == GD_CHIP_ID || Gx == GI_CHIP_ID || - Gx == GP_CHIP_ID || Gx == GQ_CHIP_ID || Gx == LI_CHIP_ID) + Gx == GP_CHIP_ID || Gx == GQ_CHIP_ID || Gx == LI_CHIP_ID || + Gx == XL_CHIP_ID) i |= 0x2; /*DAC_CNTL|0x2 turns off the extra brightness for gt*/ aty_st_8(DAC_CNTL, i, info); aty_st_8(DAC_MASK, 0xff, info); diff --git a/fs/block_dev.c b/fs/block_dev.c index 22cb71b9fff7..1432d3e3f993 100644 --- a/fs/block_dev.c +++ b/fs/block_dev.c @@ -31,7 +31,7 @@ ssize_t block_write(struct file * filp, const char * buf, ssize_t block, blocks; loff_t offset; ssize_t chars; - ssize_t written; + ssize_t written, retval; struct buffer_head * bhlist[NBUF]; size_t size; kdev_t dev = inode->i_rdev; @@ -41,7 +41,7 @@ ssize_t block_write(struct file * filp, const char * buf, if (is_read_only(dev)) return -EPERM; - written = write_error = buffercount = 0; + retval = written = write_error = buffercount = 0; blocksize = BLOCK_SIZE; if (blksize_size[MAJOR(dev)] && blksize_size[MAJOR(dev)][MINOR(dev)]) blocksize = blksize_size[MAJOR(dev)][MINOR(dev)]; @@ -61,8 +61,10 @@ ssize_t block_write(struct file * filp, const char * buf, else size = INT_MAX; while (count>0) { - if (block >= size) - return written ? written : -ENOSPC; + if (block >= size) { + retval = -ENOSPC; + goto cleanup; + } chars = blocksize - offset; if (chars > count) chars=count; @@ -74,15 +76,19 @@ ssize_t block_write(struct file * filp, const char * buf, if (chars != blocksize) fn = bread; bh = fn(dev, block, blocksize); - if (!bh) - return written ? written : -EIO; + if (!bh) { + retval = -EIO; + goto cleanup; + } if (!buffer_uptodate(bh)) wait_on_buffer(bh); } #else bh = getblk(dev, block, blocksize); - if (!bh) - return written ? written : -EIO; + if (!bh) { + retval = -EIO; + goto cleanup; + } if (!buffer_uptodate(bh)) { @@ -106,7 +112,8 @@ ssize_t block_write(struct file * filp, const char * buf, if (!bhlist[i]) { while(i >= 0) brelse(bhlist[i--]); - return written ? written : -EIO; + retval = -EIO; + goto cleanup; } } } @@ -115,7 +122,8 @@ ssize_t block_write(struct file * filp, const char * buf, wait_on_buffer(bh); if (!buffer_uptodate(bh)) { brelse(bh); - return written ? written : -EIO; + retval = -EIO; + goto cleanup; } }; }; @@ -149,6 +157,7 @@ ssize_t block_write(struct file * filp, const char * buf, if (write_error) break; } + cleanup: if ( buffercount ){ ll_rw_block(WRITE, buffercount, bufferlist); for(i=0; if_reada = 1; + if(!retval) + filp->f_reada = 1; if(write_error) return -EIO; - return written; + return written ? written : retval; } ssize_t block_read(struct file * filp, char * buf, size_t count, loff_t *ppos) diff --git a/fs/ext2/super.c b/fs/ext2/super.c index 02cb885170be..a790ae7e374a 100644 --- a/fs/ext2/super.c +++ b/fs/ext2/super.c @@ -76,9 +76,6 @@ NORET_TYPE void ext2_panic (struct super_block * sb, const char * function, va_start (args, fmt); vsprintf (error_buf, fmt, args); va_end (args); - /* this is to prevent panic from syncing this filesystem */ - if (sb->s_lock) - sb->s_lock=0; sb->s_flags |= MS_RDONLY; panic ("EXT2-fs panic (device %s): %s: %s\n", bdevname(sb->s_dev), function, error_buf); diff --git a/fs/nfsd/nfsctl.c b/fs/nfsd/nfsctl.c index 7641c5b5252c..2831b4d56486 100644 --- a/fs/nfsd/nfsctl.c +++ b/fs/nfsd/nfsctl.c @@ -158,7 +158,7 @@ nfsctl_getfd(struct nfsctl_fdparm *data, __u8 *res) err = -EINVAL; else { memset(res,0, NFS_FHSIZE); - memcpy(res, fh.fh_base.fh_pad, fh.fh_size); + memcpy(res, &fh.fh_base, fh.fh_size); } } @@ -191,7 +191,7 @@ nfsctl_getfh(struct nfsctl_fhparm *data, __u8 *res) err = -EINVAL; else { memset(res,0, NFS_FHSIZE); - memcpy(res, fh.fh_base.fh_pad, fh.fh_size); + memcpy(res, &fh.fh_base, fh.fh_size); } } diff --git a/fs/nfsd/nfsfh.c b/fs/nfsd/nfsfh.c index 890074d6630a..090cadc933ea 100644 --- a/fs/nfsd/nfsfh.c +++ b/fs/nfsd/nfsfh.c @@ -245,6 +245,11 @@ struct dentry *nfsd_findparent(struct dentry *child) */ pdentry = child->d_inode->i_op->lookup(child->d_inode, tdentry); d_drop(tdentry); /* we never want ".." hashed */ + if (!pdentry && tdentry->d_inode == NULL) { + /* File system cannot find ".." ... sad but possible */ + dput(tdentry); + pdentry = ERR_PTR(-EINVAL); + } if (!pdentry) { /* I don't want to return a ".." dentry. * I would prefer to return an unconnected "IS_ROOT" dentry, diff --git a/fs/reiserfs/prints.c b/fs/reiserfs/prints.c index 1ae19cbbe612..7393b98e0138 100644 --- a/fs/reiserfs/prints.c +++ b/fs/reiserfs/prints.c @@ -349,8 +349,6 @@ void reiserfs_panic (struct super_block * sb, const char * fmt, ...) #endif /* this is to prevent panic from syncing this filesystem */ - if (sb && sb->s_lock) - sb->s_lock=0; if (sb) sb->s_flags |= MS_RDONLY; diff --git a/fs/select.c b/fs/select.c index cf7459d3edfd..b42450eb0a33 100644 --- a/fs/select.c +++ b/fs/select.c @@ -414,9 +414,12 @@ asmlinkage long sys_poll(struct pollfd * ufds, unsigned int nfds, long timeout) int nchunks, nleft; /* Do a sanity check on nfds ... */ - if (nfds > current->files->max_fds) + if (nfds > NR_OPEN) return -EINVAL; + if (nfds > current->files->max_fds) + nfds = current->files->max_fds; + if (timeout) { /* Careful about overflow in the intermediate values */ if ((unsigned long) timeout < MAX_SCHEDULE_TIMEOUT / HZ) diff --git a/fs/smbfs/ChangeLog b/fs/smbfs/ChangeLog index 5eeeb6829892..26e92df734ad 100644 --- a/fs/smbfs/ChangeLog +++ b/fs/smbfs/ChangeLog @@ -1,5 +1,30 @@ ChangeLog for smbfs. +2001-05-08 Urban Widmark + + * inode.c: Fix for changes on the server side not being detected + properly. Must always drop cached pages when updating an inode with + new size. + +2001-05-05 Urban Widmark + + * file.c, proc.c: Drop SMB_F_LOCALWRITE to detect changes made on + both server and client, using flush with to force win9x to remember + the right filesize. + +2001-04-25 René Scharfe + + * inode.c: Don't clear s_flags and allow ro mounts + +2001-04-21 Urban Widmark + + * dir.c, proc.c: replace tests on conn_pid with tests on state to + fix smbmount reconnect on smb_retry timeout and up the timeout to 30s. + * proc.c: smb_newconn must have the server locked while updating it. + * inode.c, proc.c: need flush after truncate on some servers (win9x) + * file.c: add call to send SMBflush on fsync + (as suggested by Jochen Dolze ) + 2001-03-06 Urban Widmark * cache.c: d_add on hashed dentries corrupts d_hash list and diff --git a/fs/smbfs/dir.c b/fs/smbfs/dir.c index ba7aa95f1d24..48d716c9e3a8 100644 --- a/fs/smbfs/dir.c +++ b/fs/smbfs/dir.c @@ -210,10 +210,6 @@ out: return result; } -/* - * Note: in order to allow the smbmount process to open the - * mount point, we don't revalidate if conn_pid is NULL. - */ static int smb_dir_open(struct inode *dir, struct file *file) { @@ -230,14 +226,18 @@ smb_dir_open(struct inode *dir, struct file *file) */ lock_kernel(); server = server_from_dentry(dentry); - if (server->opt.protocol < SMB_PROTOCOL_LANMAN2) - { + if (server->opt.protocol < SMB_PROTOCOL_LANMAN2) { unsigned long age = jiffies - dir->u.smbfs_i.oldmtime; if (age > 2*HZ) smb_invalid_dir_cache(dir); } - if (server->conn_pid) + /* + * Note: in order to allow the smbmount process to open the + * mount point, we only revalidate if the connection is valid or + * if the process is trying to access something other than the root. + */ + if (server->state == CONN_VALID || !IS_ROOT(dentry)) error = smb_revalidate_inode(dentry); unlock_kernel(); return error; diff --git a/fs/smbfs/file.c b/fs/smbfs/file.c index dfc370f20bfc..06b73c41be37 100644 --- a/fs/smbfs/file.c +++ b/fs/smbfs/file.c @@ -28,8 +28,23 @@ static int smb_fsync(struct file *file, struct dentry * dentry, int datasync) { + struct smb_sb_info *server = server_from_dentry(dentry); + int result; + VERBOSE("sync file %s/%s\n", DENTRY_PATH(dentry)); - return 0; + + /* + * The VFS will writepage() all dirty pages for us, but we + * should send a SMBflush to the server, letting it know that + * we want things synchronized with actual storage. + * + * Note: this function requires all pages to have been written already + * (should be ok with writepage_sync) + */ + smb_lock_server(server); + result = smb_proc_flush(server, dentry->d_inode->u.smbfs_i.fileid); + smb_unlock_server(server); + return result; } /* @@ -138,7 +153,6 @@ smb_writepage_sync(struct inode *inode, struct page *page, inode->i_mtime = inode->i_atime = CURRENT_TIME; if (offset > inode->i_size) inode->i_size = offset; - inode->u.smbfs_i.flags |= SMB_F_LOCALWRITE; } while (count); kunmap(page); @@ -207,8 +221,7 @@ smb_file_read(struct file * file, char * buf, size_t count, loff_t *ppos) (unsigned long) count, (unsigned long) *ppos); status = smb_revalidate_inode(dentry); - if (status) - { + if (status) { PARANOIA("%s/%s validation failed, error=%Zd\n", DENTRY_PATH(dentry), status); goto out; @@ -233,8 +246,7 @@ smb_file_mmap(struct file * file, struct vm_area_struct * vma) DENTRY_PATH(dentry), vma->vm_start, vma->vm_end); status = smb_revalidate_inode(dentry); - if (status) - { + if (status) { PARANOIA("%s/%s validation failed, error=%d\n", DENTRY_PATH(dentry), status); goto out; @@ -294,8 +306,7 @@ smb_file_write(struct file *file, const char *buf, size_t count, loff_t *ppos) (unsigned long) count, (unsigned long) *ppos); result = smb_revalidate_inode(dentry); - if (result) - { + if (result) { PARANOIA("%s/%s validation failed, error=%Zd\n", DENTRY_PATH(dentry), result); goto out; @@ -305,8 +316,7 @@ smb_file_write(struct file *file, const char *buf, size_t count, loff_t *ppos) if (result) goto out; - if (count > 0) - { + if (count > 0) { result = generic_file_write(file, buf, count, ppos); VERBOSE("pos=%ld, size=%ld, mtime=%ld, atime=%ld\n", (long) file->f_pos, (long) dentry->d_inode->i_size, diff --git a/fs/smbfs/inode.c b/fs/smbfs/inode.c index e97ed2a54efe..ce5b0c0868ba 100644 --- a/fs/smbfs/inode.c +++ b/fs/smbfs/inode.c @@ -109,9 +109,20 @@ smb_get_inode_attr(struct inode *inode, struct smb_fattr *fattr) fattr->attr |= aRONLY; } +/* + * Update the inode, possibly causing it to invalidate its pages if mtime/size + * is different from last time. + */ void smb_set_inode_attr(struct inode *inode, struct smb_fattr *fattr) { + /* + * A size change should have a different mtime, or same mtime + * but different size. + */ + time_t last_time = inode->i_mtime; + loff_t last_sz = inode->i_size; + inode->i_mode = fattr->f_mode; inode->i_nlink = fattr->f_nlink; inode->i_uid = fattr->f_uid; @@ -120,21 +131,24 @@ smb_set_inode_attr(struct inode *inode, struct smb_fattr *fattr) inode->i_ctime = fattr->f_ctime; inode->i_blksize= fattr->f_blksize; inode->i_blocks = fattr->f_blocks; - /* - * Don't change the size and mtime/atime fields - * if we're writing to the file. - */ - if (!(inode->u.smbfs_i.flags & SMB_F_LOCALWRITE)) { - inode->i_size = fattr->f_size; - inode->i_mtime = fattr->f_mtime; - inode->i_atime = fattr->f_atime; - } - + inode->i_size = fattr->f_size; + inode->i_mtime = fattr->f_mtime; + inode->i_atime = fattr->f_atime; inode->u.smbfs_i.attr = fattr->attr; /* * Update the "last time refreshed" field for revalidation. */ inode->u.smbfs_i.oldmtime = jiffies; + + if (inode->i_mtime != last_time || inode->i_size != last_sz) { + VERBOSE("%s/%s changed, old=%ld, new=%ld, oz=%ld, nz=%ld\n", + DENTRY_PATH(dentry), + (long) last_time, (long) inode->i_mtime, + (long) last_sz, (long) inode->i_size); + + if (!S_ISDIR(inode->i_mode)) + invalidate_inode_pages(inode); + } } /* @@ -209,8 +223,6 @@ smb_revalidate_inode(struct dentry *dentry) { struct smb_sb_info *s = server_from_dentry(dentry); struct inode *inode = dentry->d_inode; - time_t last_time; - loff_t last_sz; int error = 0; DEBUG1("smb_revalidate_inode\n"); @@ -225,22 +237,7 @@ smb_revalidate_inode(struct dentry *dentry) goto out; } - /* - * Save the last modified time, then refresh the inode. - * (Note: a size change should have a different mtime, - * or same mtime but different size.) - */ - last_time = inode->i_mtime; - last_sz = inode->i_size; error = smb_refresh_inode(dentry); - if (error || inode->i_mtime != last_time || inode->i_size != last_sz) { - VERBOSE("%s/%s changed, old=%ld, new=%ld\n", - DENTRY_PATH(dentry), - (long) last_time, (long) inode->i_mtime); - - if (!S_ISDIR(inode->i_mode)) - invalidate_inode_pages(inode); - } out: unlock_kernel(); return error; @@ -355,8 +352,8 @@ smb_put_super(struct super_block *sb) if (server->conn_pid) kill_proc(server->conn_pid, SIGTERM, 1); - kfree(server->mnt); - kfree(sb->u.smbfs_sb.temp_buf); + smb_kfree(server->mnt); + smb_kfree(sb->u.smbfs_sb.temp_buf); if (server->packet) smb_vfree(server->packet); @@ -390,7 +387,6 @@ smb_read_super(struct super_block *sb, void *raw_data, int silent) sb->s_blocksize = 1024; /* Eh... Is this correct? */ sb->s_blocksize_bits = 10; sb->s_magic = SMB_SUPER_MAGIC; - sb->s_flags = 0; sb->s_op = &smb_sops; sb->u.smbfs_sb.mnt = NULL; @@ -400,13 +396,13 @@ smb_read_super(struct super_block *sb, void *raw_data, int silent) sb->u.smbfs_sb.conn_pid = 0; sb->u.smbfs_sb.state = CONN_INVALID; /* no connection yet */ sb->u.smbfs_sb.generation = 0; - sb->u.smbfs_sb.packet_size = smb_round_length(SMB_INITIAL_PACKET_SIZE); + sb->u.smbfs_sb.packet_size = smb_round_length(SMB_INITIAL_PACKET_SIZE); sb->u.smbfs_sb.packet = smb_vmalloc(sb->u.smbfs_sb.packet_size); if (!sb->u.smbfs_sb.packet) goto out_no_mem; /* Allocate the global temp buffer */ - sb->u.smbfs_sb.temp_buf = kmalloc(2*SMB_MAXPATHLEN + 20, GFP_KERNEL); + sb->u.smbfs_sb.temp_buf = smb_kmalloc(2*SMB_MAXPATHLEN+20, GFP_KERNEL); if (!sb->u.smbfs_sb.temp_buf) goto out_no_temp; @@ -417,7 +413,7 @@ smb_read_super(struct super_block *sb, void *raw_data, int silent) /* Allocate the mount data structure */ /* FIXME: merge this with the other malloc and get a whole page? */ - mnt = kmalloc(sizeof(struct smb_mount_data_kernel), GFP_KERNEL); + mnt = smb_kmalloc(sizeof(struct smb_mount_data_kernel), GFP_KERNEL); if (!mnt) goto out_no_mount; sb->u.smbfs_sb.mnt = mnt; @@ -482,9 +478,9 @@ smb_read_super(struct super_block *sb, void *raw_data, int silent) out_no_root: iput(root_inode); out_bad_option: - kfree(sb->u.smbfs_sb.mnt); + smb_kfree(sb->u.smbfs_sb.mnt); out_no_mount: - kfree(sb->u.smbfs_sb.temp_buf); + smb_kfree(sb->u.smbfs_sb.temp_buf); out_no_temp: smb_vfree(sb->u.smbfs_sb.packet); out_no_mem: diff --git a/fs/smbfs/ioctl.c b/fs/smbfs/ioctl.c index ff8ddc08e6b4..285c25b039aa 100644 --- a/fs/smbfs/ioctl.c +++ b/fs/smbfs/ioctl.c @@ -23,7 +23,7 @@ int smb_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg) { - struct smb_sb_info *server = SMB_SERVER(inode); + struct smb_sb_info *server = server_from_inode(inode); struct smb_conn_opt opt; int result = -EINVAL; @@ -37,7 +37,7 @@ smb_ioctl(struct inode *inode, struct file *filp, break; case SMB_IOC_NEWCONN: - /* require an argument == the mount data, else it is EINVAL */ + /* require an argument == smb_conn_opt, else it is EINVAL */ if (!arg) break; @@ -45,7 +45,8 @@ smb_ioctl(struct inode *inode, struct file *filp, if (!copy_from_user(&opt, (void *)arg, sizeof(opt))) result = smb_newconn(server, &opt); break; - default:; + default: + break; } return result; diff --git a/fs/smbfs/proc.c b/fs/smbfs/proc.c index b2f93c2fe6ad..e8738fd54204 100644 --- a/fs/smbfs/proc.c +++ b/fs/smbfs/proc.c @@ -54,18 +54,6 @@ smb_proc_do_getattr(struct smb_sb_info *server, struct dentry *dir, struct smb_fattr *fattr); -static inline void -smb_lock_server(struct smb_sb_info *server) -{ - down(&(server->sem)); -} - -static inline void -smb_unlock_server(struct smb_sb_info *server) -{ - up(&(server->sem)); -} - static void str_upper(char *name, int len) @@ -661,7 +649,7 @@ smb_retry(struct smb_sb_info *server) pid_t pid = server->conn_pid; int error, result = 0; - if (server->state != CONN_INVALID) + if (server->state == CONN_VALID || server->state == CONN_RETRYING) goto out; smb_close_socket(server); @@ -673,17 +661,18 @@ smb_retry(struct smb_sb_info *server) } /* - * Clear the pid to enable the ioctl. + * Change state so that only one retry per server will be started. */ - server->conn_pid = 0; + server->state = CONN_RETRYING; /* * Note: use the "priv" flag, as a user process may need to reconnect. */ error = kill_proc(pid, SIGUSR1, 1); if (error) { + /* FIXME: this is fatal */ printk(KERN_ERR "smb_retry: signal failed, error=%d\n", error); - goto out_restore; + goto out; } VERBOSE("signalled pid %d, waiting for new connection\n", pid); @@ -691,7 +680,9 @@ smb_retry(struct smb_sb_info *server) * Wait for the new connection. */ #ifdef SMB_RETRY_INTR - interruptible_sleep_on_timeout(&server->wait, 5*HZ); + smb_unlock_server(server); + interruptible_sleep_on_timeout(&server->wait, 30*HZ); + smb_lock_server(server); if (signal_pending(current)) printk(KERN_INFO "smb_retry: caught signal\n"); #else @@ -702,8 +693,13 @@ smb_retry(struct smb_sb_info *server) * * smbmount should be able to reconnect later, but it can't because * it will get an -EIO on attempts to open the mountpoint! + * + * FIXME: go back to the interruptable version now that smbmount + * can avoid -EIO on the mountpoint when reconnecting? */ - sleep_on_timeout(&server->wait, 5*HZ); + smb_unlock_server(server); + sleep_on_timeout(&server->wait, 30*HZ); + smb_lock_server(server); #endif /* @@ -715,15 +711,11 @@ smb_retry(struct smb_sb_info *server) PARANOIA("successful, new pid=%d, generation=%d\n", server->conn_pid, server->generation); result = 1; + } else if (server->state == CONN_RETRYING) { + /* allow further attempts later */ + server->state = CONN_RETRIED; } - /* - * Restore the original pid if we didn't get a new one. - */ -out_restore: - if (!server->conn_pid) - server->conn_pid = pid; - out: return result; } @@ -742,19 +734,16 @@ smb_request_ok(struct smb_sb_info *s, int command, int wct, int bcc) s->err = 0; /* Make sure we have a connection */ - if (s->state != CONN_VALID) - { + if (s->state != CONN_VALID) { if (!smb_retry(s)) goto out; } - if (smb_request(s) < 0) - { + if (smb_request(s) < 0) { DEBUG1("smb_request failed\n"); goto out; } - if (smb_valid_packet(s->packet) != 0) - { + if (smb_valid_packet(s->packet) != 0) { PARANOIA("invalid packet!\n"); goto out; } @@ -764,8 +753,7 @@ smb_request_ok(struct smb_sb_info *s, int command, int wct, int bcc) * is squashing some error codes, but I don't think this is * correct: after a server error the packet won't be valid. */ - if (s->rcls != 0) - { + if (s->rcls != 0) { result = -smb_errno(s); if (!result) printk(KERN_DEBUG "smb_request_ok: rcls=%d, err=%d mapped to 0\n", @@ -785,10 +773,6 @@ out: /* * This implements the NEWCONN ioctl. It installs the server pid, * sets server->state to CONN_VALID, and wakes up the waiting process. - * - * Note that this must be called with the server locked, except for - * the first call made after mounting the volume. The server pid - * will be set to zero to indicate that smbfs is awaiting a connection. */ int smb_newconn(struct smb_sb_info *server, struct smb_conn_opt *opt) @@ -798,11 +782,13 @@ smb_newconn(struct smb_sb_info *server, struct smb_conn_opt *opt) VERBOSE("fd=%d, pid=%d\n", opt->fd, current->pid); + smb_lock_server(server); + /* - * Make sure we don't already have a pid ... + * Make sure we don't already have a valid connection ... */ error = -EINVAL; - if (server->conn_pid) + if (server->state == CONN_VALID) goto out; error = -EACCES; @@ -836,9 +822,7 @@ smb_newconn(struct smb_sb_info *server, struct smb_conn_opt *opt) (server->opt.max_xmit < 0x1000) && !(server->opt.capabilities & SMB_CAP_NT_SMBS)) { server->mnt->flags |= SMB_MOUNT_WIN95; -#ifdef SMBFS_DEBUG_VERBOSE - printk(KERN_NOTICE "smb_newconn: detected WIN95 server\n"); -#endif + VERBOSE("smb_newconn: detected WIN95 server\n"); } VERBOSE("protocol=%d, max_xmit=%d, pid=%d capabilities=0x%x\n", @@ -851,6 +835,8 @@ smb_newconn(struct smb_sb_info *server, struct smb_conn_opt *opt) int len = smb_round_length(server->opt.max_xmit); char *buf = smb_vmalloc(len); if (buf) { + if (server->packet) + smb_vfree(server->packet); server->packet = buf; server->packet_size = len; } else { @@ -863,6 +849,8 @@ smb_newconn(struct smb_sb_info *server, struct smb_conn_opt *opt) } out: + smb_unlock_server(server); + #ifdef SMB_RETRY_INTR wake_up_interruptible(&server->wait); #else @@ -1016,7 +1004,7 @@ smb_open(struct dentry *dentry, int wish) } if (!smb_is_open(inode)) { - struct smb_sb_info *server = SMB_SERVER(inode); + struct smb_sb_info *server = server_from_inode(inode); smb_lock_server(server); result = 0; if (!smb_is_open(inode)) @@ -1102,7 +1090,6 @@ smb_proc_close_inode(struct smb_sb_info *server, struct inode * ino) result = smb_proc_close(server, ino->u.smbfs_i.fileid, ino->i_mtime); - ino->u.smbfs_i.flags &= ~SMB_F_LOCALWRITE; /* * Force a revalidation after closing ... some servers * don't post the size until the file has been closed. @@ -1119,9 +1106,8 @@ smb_close(struct inode *ino) { int result = 0; - if (smb_is_open(ino)) - { - struct smb_sb_info *server = SMB_SERVER(ino); + if (smb_is_open(ino)) { + struct smb_sb_info *server = server_from_inode(ino); smb_lock_server(server); result = smb_proc_close_inode(server, ino); smb_unlock_server(server); @@ -1203,14 +1189,15 @@ smb_proc_write(struct inode *inode, off_t offset, int count, const char *data) struct smb_sb_info *server = server_from_inode(inode); int result; __u8 *p; - + __u16 fileid = inode->u.smbfs_i.fileid; + VERBOSE("ino=%ld, fileid=%d, count=%d@%ld, packet_size=%d\n", inode->i_ino, inode->u.smbfs_i.fileid, count, offset, server->packet_size); smb_lock_server(server); p = smb_setup_header(server, SMBwrite, 5, count + 3); - WSET(server->packet, smb_vwv0, inode->u.smbfs_i.fileid); + WSET(server->packet, smb_vwv0, fileid); WSET(server->packet, smb_vwv1, count); DSET(server->packet, smb_vwv2, offset); WSET(server->packet, smb_vwv4, 0); @@ -1223,6 +1210,11 @@ smb_proc_write(struct inode *inode, off_t offset, int count, const char *data) if (result >= 0) result = WVAL(server->packet, smb_vwv0); + /* flush to disk, to trigger win9x to update its filesize */ + /* FIXME: this will be rather costly, won't it? */ + if (server->mnt->flags & SMB_MOUNT_WIN95) + smb_proc_flush(server, fileid); + smb_unlock_server(server); return result; } @@ -1423,6 +1415,17 @@ out: return result; } +/* + * Called with the server locked + */ +int +smb_proc_flush(struct smb_sb_info *server, __u16 fileid) +{ + smb_setup_header(server, SMBflush, 1, 0); + WSET(server->packet, smb_vwv0, fileid); + return smb_request_ok(server, SMBflush, 0, 0); +} + int smb_proc_trunc(struct smb_sb_info *server, __u16 fid, __u32 length) { @@ -1431,7 +1434,7 @@ smb_proc_trunc(struct smb_sb_info *server, __u16 fid, __u32 length) smb_lock_server(server); - retry: +retry: p = smb_setup_header(server, SMBwrite, 5, 3); WSET(server->packet, smb_vwv0, fid); WSET(server->packet, smb_vwv1, 0); @@ -1445,7 +1448,15 @@ smb_proc_trunc(struct smb_sb_info *server, __u16 fid, __u32 length) goto retry; goto out; } - result = 0; + + /* + * win9x doesn't appear to update the size immediately. + * It will return the old file size after the truncate, + * confusing smbfs. + * NT and Samba return the new value immediately. + */ + if (server->mnt->flags & SMB_MOUNT_WIN95) + smb_proc_flush(server, fid); out: smb_unlock_server(server); return result; diff --git a/fs/smbfs/sock.c b/fs/smbfs/sock.c index 6bad6d3042e7..47aad9dc1cb1 100644 --- a/fs/smbfs/sock.c +++ b/fs/smbfs/sock.c @@ -150,14 +150,14 @@ smb_data_callback(void* ptr) DEBUG1("found=%d, count=%d, result=%d\n", found, count, result); if (found) found_data(job->sk); - kfree(ptr); + smb_kfree(ptr); } static void smb_data_ready(struct sock *sk, int len) { struct data_callback* job; - job = kmalloc(sizeof(struct data_callback),GFP_ATOMIC); + job = smb_kmalloc(sizeof(struct data_callback),GFP_ATOMIC); if(job == 0) { printk("smb_data_ready: lost SESSION KEEPALIVE due to OOM.\n"); found_data(sk); diff --git a/fs/super.c b/fs/super.c index 50ccc8e4eca7..371f29026888 100644 --- a/fs/super.c +++ b/fs/super.c @@ -580,30 +580,7 @@ int get_filesystem_info( char *buf ) #undef MANGLE #undef FREEROOM } - -/** - * __wait_on_super - wait on a superblock - * @sb: superblock to wait on - * - * Waits for a superblock to become unlocked and then returns. It does - * not take the lock. This is an internal function. See wait_on_super(). - */ -void __wait_on_super(struct super_block * sb) -{ - DECLARE_WAITQUEUE(wait, current); - - add_wait_queue(&sb->s_wait, &wait); -repeat: - set_current_state(TASK_UNINTERRUPTIBLE); - if (sb->s_lock) { - schedule(); - goto repeat; - } - remove_wait_queue(&sb->s_wait, &wait); - current->state = TASK_RUNNING; -} - /* * Note: check the dirty flag before waiting, so we don't * hold up the sync while mounting a device. (The newly @@ -648,7 +625,9 @@ restart: s = sb_entry(super_blocks.next); while (s != sb_entry(&super_blocks)) if (s->s_dev == dev) { - wait_on_super(s); + /* Yes, it sucks. As soon as we get refcounting... */ + lock_super(s); + unlock_super(s); if (s->s_dev == dev) return s; goto restart; @@ -700,9 +679,7 @@ static struct super_block *get_empty_super(void) s = sb_entry(s->s_list.next)) { if (s->s_dev) continue; - if (!s->s_lock) - return s; - printk("VFS: empty superblock %p locked!\n", s); + return s; } /* Need a new one... */ if (nr_super_blocks >= max_super_blocks) @@ -714,10 +691,14 @@ static struct super_block *get_empty_super(void) INIT_LIST_HEAD(&s->s_dirty); INIT_LIST_HEAD(&s->s_locked_inodes); list_add (&s->s_list, super_blocks.prev); - init_waitqueue_head(&s->s_wait); INIT_LIST_HEAD(&s->s_files); INIT_LIST_HEAD(&s->s_mounts); init_rwsem(&s->s_umount); + sema_init(&s->s_lock, 1); + sema_init(&s->s_vfs_rename_sem,1); + sema_init(&s->s_nfsd_free_path_sem,1); + sema_init(&s->s_dquot.dqio_sem, 1); + sema_init(&s->s_dquot.dqoff_sem, 1); } return s; } @@ -734,11 +715,7 @@ static struct super_block * read_super(kdev_t dev, struct block_device *bdev, s->s_bdev = bdev; s->s_flags = flags; s->s_dirt = 0; - sema_init(&s->s_vfs_rename_sem,1); - sema_init(&s->s_nfsd_free_path_sem,1); s->s_type = type; - sema_init(&s->s_dquot.dqio_sem, 1); - sema_init(&s->s_dquot.dqoff_sem, 1); s->s_dquot.flags = 0; s->s_maxbytes = MAX_NON_LFS; lock_super(s); diff --git a/fs/ufs/super.c b/fs/ufs/super.c index 7e72e4586884..dd56edb9770b 100644 --- a/fs/ufs/super.c +++ b/fs/ufs/super.c @@ -230,9 +230,6 @@ void ufs_panic (struct super_block * sb, const char * function, va_start (args, fmt); vsprintf (error_buf, fmt, args); va_end (args); - /* this is to prevent panic from syncing this filesystem */ - if (sb->s_lock) - sb->s_lock = 0; sb->s_flags |= MS_RDONLY; printk (KERN_CRIT "UFS-fs panic (device %s): %s: %s\n", kdevname(sb->s_dev), function, error_buf); diff --git a/include/asm-alpha/pci.h b/include/asm-alpha/pci.h index 781a4882bc2e..72977a758552 100644 --- a/include/asm-alpha/pci.h +++ b/include/asm-alpha/pci.h @@ -146,6 +146,17 @@ pci_dma_sync_sg(struct pci_dev *dev, struct scatterlist *sg, int nents, extern int pci_dma_supported(struct pci_dev *hwdev, dma_addr_t mask); +/* Return the index of the PCI controller for device PDEV. */ +static __inline__ int pci_controller_num(struct pci_dev *pdev) +{ + struct pci_controller *hose = pdev->sysdata; + + if (hose != NULL) + return hose->index; + + return -ENXIO; +} + #endif /* __KERNEL__ */ /* Values for the `which' argument to sys_pciconfig_iobase. */ diff --git a/include/asm-arm/pci.h b/include/asm-arm/pci.h index c32ddbc3c28d..744cb3060179 100644 --- a/include/asm-arm/pci.h +++ b/include/asm-arm/pci.h @@ -148,6 +148,9 @@ extern inline int pci_dma_supported(struct pci_dev *hwdev, dma_addr_t mask) return 1; } +/* Return the index of the PCI controller for device PDEV. */ +#define pci_controller_num(PDEV) (0) + #endif /* __KERNEL__ */ #endif diff --git a/include/asm-i386/pci.h b/include/asm-i386/pci.h index 2624dc4eaa47..310e0062011b 100644 --- a/include/asm-i386/pci.h +++ b/include/asm-i386/pci.h @@ -173,6 +173,12 @@ extern inline int pci_dma_supported(struct pci_dev *hwdev, dma_addr_t mask) #define sg_dma_address(sg) (virt_to_bus((sg)->address)) #define sg_dma_len(sg) ((sg)->length) +/* Return the index of the PCI controller for device. */ +static inline int pci_controller_num(struct pci_dev *dev) +{ + return 0; +} + #endif /* __KERNEL__ */ #endif /* __i386_PCI_H */ diff --git a/include/asm-ia64/pci.h b/include/asm-ia64/pci.h index 7b350ee52247..049c743a6bb7 100644 --- a/include/asm-ia64/pci.h +++ b/include/asm-ia64/pci.h @@ -57,6 +57,9 @@ pci_dma_supported (struct pci_dev *hwdev, dma_addr_t mask) return 1; } +/* Return the index of the PCI controller for device PDEV. */ +#define pci_controller_num(PDEV) (0) + #define sg_dma_len(sg) ((sg)->length) #endif /* _ASM_IA64_PCI_H */ diff --git a/include/asm-m68k/pci.h b/include/asm-m68k/pci.h index 2e767ed59ce5..644cf3733ee8 100644 --- a/include/asm-m68k/pci.h +++ b/include/asm-m68k/pci.h @@ -45,4 +45,7 @@ extern inline void pcibios_penalize_isa_irq(int irq) /* We don't do dynamic PCI IRQ allocation */ } +/* Return the index of the PCI controller for device PDEV. */ +#define pci_controller_num(PDEV) (0) + #endif /* _ASM_M68K_PCI_H */ diff --git a/include/asm-mips/pci.h b/include/asm-mips/pci.h index 809bdede6d81..2bbffa9b94f6 100644 --- a/include/asm-mips/pci.h +++ b/include/asm-mips/pci.h @@ -201,6 +201,9 @@ extern inline void pci_dma_sync_sg(struct pci_dev *hwdev, #endif } +/* Return the index of the PCI controller for device PDEV. */ +#define pci_controller_num(PDEV) (0) + /* * These macros should be used after a pci_map_sg call has been done * to get bus addresses of each of the SG entries and their lengths. diff --git a/include/asm-mips64/pci.h b/include/asm-mips64/pci.h index 0112244e3b9c..08e1aba04351 100644 --- a/include/asm-mips64/pci.h +++ b/include/asm-mips64/pci.h @@ -196,6 +196,9 @@ extern inline void pci_dma_sync_sg(struct pci_dev *hwdev, #endif } +/* Return the index of the PCI controller for device PDEV. */ +#define pci_controller_num(PDEV) (0) + /* * These macros should be used after a pci_map_sg call has been done * to get bus addresses of each of the SG entries and their lengths. diff --git a/include/asm-parisc/pci.h b/include/asm-parisc/pci.h index 89ea370480fe..843ca846f8d9 100644 --- a/include/asm-parisc/pci.h +++ b/include/asm-parisc/pci.h @@ -212,4 +212,7 @@ extern int pdc_pat; /* arch/parisc/kernel/inventory.c */ #define PCIBIOS_MIN_IO 0x10 #define PCIBIOS_MIN_MEM 0x1000 /* NBPG - but pci/setup-res.c dies */ +/* Return the index of the PCI controller for device PDEV. */ +#define pci_controller_num(PDEV) (0) + #endif /* __ASM_PARISC_PCI_H */ diff --git a/include/asm-ppc/atomic.h b/include/asm-ppc/atomic.h index cf0e122dc142..7247f67ad4f7 100644 --- a/include/asm-ppc/atomic.h +++ b/include/asm-ppc/atomic.h @@ -86,4 +86,26 @@ static __inline__ int atomic_dec_return(atomic_t *v) #define atomic_dec(v) ((void) atomic_dec_return((v))) #define atomic_dec_and_test(v) (atomic_dec_return((v)) == 0) +/* + * Atomically test *v and decrement if it is greater than 0. + * The function returns the old value of *v minus 1. + */ +static __inline__ int atomic_dec_if_positive(atomic_t *v) +{ + int t; + + __asm__ __volatile__("\n" +"1: lwarx %0,0,%2\n" +" addic. %0,%0,-1\n" +" blt 2f\n" +" stwcx. %0,0,%2\n" +" bne 1b\n" +"2:" + : "=&r" (t), "=m" (v->counter) + : "r" (&v->counter), "m" (v->counter) + : "cc"); + + return t; +} + #endif /* _ASM_PPC_ATOMIC_H_ */ diff --git a/include/asm-ppc/bitops.h b/include/asm-ppc/bitops.h index c31e5c5eb304..b321407b8b1b 100644 --- a/include/asm-ppc/bitops.h +++ b/include/asm-ppc/bitops.h @@ -35,10 +35,10 @@ static __inline__ void set_bit(int nr, volatile void * addr) unsigned long mask = 1 << (nr & 0x1f); unsigned long *p = ((unsigned long *)addr) + (nr >> 5); - __asm__ __volatile__("\ -1: lwarx %0,0,%3 - or %0,%0,%2 - stwcx. %0,0,%3 + __asm__ __volatile__("\n\ +1: lwarx %0,0,%3 \n\ + or %0,%0,%2 \n\ + stwcx. %0,0,%3 \n\ bne- 1b" : "=&r" (old), "=m" (*p) : "r" (mask), "r" (p), "m" (*p) @@ -68,10 +68,10 @@ static __inline__ void clear_bit(int nr, volatile void *addr) unsigned long mask = 1 << (nr & 0x1f); unsigned long *p = ((unsigned long *)addr) + (nr >> 5); - __asm__ __volatile__("\ -1: lwarx %0,0,%3 - andc %0,%0,%2 - stwcx. %0,0,%3 + __asm__ __volatile__("\n\ +1: lwarx %0,0,%3 \n\ + andc %0,%0,%2 \n\ + stwcx. %0,0,%3 \n\ bne- 1b" : "=&r" (old), "=m" (*p) : "r" (mask), "r" (p), "m" (*p) @@ -84,10 +84,10 @@ static __inline__ void change_bit(int nr, volatile void *addr) unsigned long mask = 1 << (nr & 0x1f); unsigned long *p = ((unsigned long *)addr) + (nr >> 5); - __asm__ __volatile__("\ -1: lwarx %0,0,%3 - xor %0,%0,%2 - stwcx. %0,0,%3 + __asm__ __volatile__("\n\ +1: lwarx %0,0,%3 \n\ + xor %0,%0,%2 \n\ + stwcx. %0,0,%3 \n\ bne- 1b" : "=&r" (old), "=m" (*p) : "r" (mask), "r" (p), "m" (*p) @@ -103,10 +103,10 @@ static __inline__ int test_and_set_bit(int nr, volatile void *addr) unsigned int mask = 1 << (nr & 0x1f); volatile unsigned int *p = ((volatile unsigned int *)addr) + (nr >> 5); - __asm__ __volatile__(SMP_WMB "\ -1: lwarx %0,0,%4 - or %1,%0,%3 - stwcx. %1,0,%4 + __asm__ __volatile__(SMP_WMB "\n\ +1: lwarx %0,0,%4 \n\ + or %1,%0,%3 \n\ + stwcx. %1,0,%4 \n\ bne 1b" SMP_MB : "=&r" (old), "=&r" (t), "=m" (*p) @@ -135,10 +135,10 @@ static __inline__ int test_and_clear_bit(int nr, volatile void *addr) unsigned int mask = 1 << (nr & 0x1f); volatile unsigned int *p = ((volatile unsigned int *)addr) + (nr >> 5); - __asm__ __volatile__(SMP_WMB "\ -1: lwarx %0,0,%4 - andc %1,%0,%3 - stwcx. %1,0,%4 + __asm__ __volatile__(SMP_WMB "\n\ +1: lwarx %0,0,%4 \n\ + andc %1,%0,%3 \n\ + stwcx. %1,0,%4 \n\ bne 1b" SMP_MB : "=&r" (old), "=&r" (t), "=m" (*p) @@ -167,10 +167,10 @@ static __inline__ int test_and_change_bit(int nr, volatile void *addr) unsigned int mask = 1 << (nr & 0x1f); volatile unsigned int *p = ((volatile unsigned int *)addr) + (nr >> 5); - __asm__ __volatile__(SMP_WMB "\ -1: lwarx %0,0,%4 - xor %1,%0,%3 - stwcx. %1,0,%4 + __asm__ __volatile__(SMP_WMB "\n\ +1: lwarx %0,0,%4 \n\ + xor %1,%0,%3 \n\ + stwcx. %1,0,%4 \n\ bne 1b" SMP_MB : "=&r" (old), "=&r" (t), "=m" (*p) diff --git a/include/asm-ppc/bseip.h b/include/asm-ppc/bseip.h index af657c36e1b0..2ddfb59bc00a 100644 --- a/include/asm-ppc/bseip.h +++ b/include/asm-ppc/bseip.h @@ -8,6 +8,7 @@ #ifndef __MACH_BSEIP_DEFS #define __MACH_BSEIP_DEFS +#ifndef __ASSEMBLY__ /* A Board Information structure that is given to a program when * prom starts it up. */ @@ -29,6 +30,7 @@ extern bd_t m8xx_board_info; #define IMAP_SIZE ((uint)(64 * 1024)) #define PCMCIA_MEM_ADDR ((uint)0x04000000) #define PCMCIA_MEM_SIZE ((uint)(64 * 1024)) +#endif /* !__ASSEMBLY__ */ /* We don't use the 8259. */ diff --git a/include/asm-ppc/checksum.h b/include/asm-ppc/checksum.h index 48c8ca7b5372..8f2ba450b5b4 100644 --- a/include/asm-ppc/checksum.h +++ b/include/asm-ppc/checksum.h @@ -84,10 +84,10 @@ static inline unsigned long csum_tcpudp_nofold(unsigned long saddr, unsigned int sum) { __asm__(" - addc %0,%0,%1 - adde %0,%0,%2 - adde %0,%0,%3 - addze %0,%0 + addc %0,%0,%1 \n\ + adde %0,%0,%2 \n\ + adde %0,%0,%3 \n\ + addze %0,%0 \n\ " : "=r" (sum) : "r" (daddr), "r"(saddr), "r"((proto<<16)+len), "0"(sum)); diff --git a/include/asm-ppc/elf.h b/include/asm-ppc/elf.h index 85124797a769..62cc91fe166f 100644 --- a/include/asm-ppc/elf.h +++ b/include/asm-ppc/elf.h @@ -74,20 +74,39 @@ typedef elf_vrreg_t elf_vrregset_t[ELF_NVRREG]; * We need to put in some extra aux table entries to tell glibc what * the cache block size is, so it can use the dcbz instruction safely. */ -#define AT_DCACHEBSIZE 17 -#define AT_ICACHEBSIZE 18 -#define AT_UCACHEBSIZE 19 +#define AT_DCACHEBSIZE 19 +#define AT_ICACHEBSIZE 20 +#define AT_UCACHEBSIZE 21 +/* A special ignored type value for PPC, for glibc compatibility. */ +#define AT_IGNOREPPC 22 extern int dcache_bsize; extern int icache_bsize; extern int ucache_bsize; -#define DLINFO_EXTRA_ITEMS 3 -#define EXTRA_DLINFO do { \ - NEW_AUX_ENT(0, AT_DCACHEBSIZE, dcache_bsize); \ - NEW_AUX_ENT(1, AT_ICACHEBSIZE, icache_bsize); \ - NEW_AUX_ENT(2, AT_UCACHEBSIZE, ucache_bsize); \ -} while (0) +/* + * The requirements here are: + * - keep the final alignment of sp (sp & 0xf) + * - make sure the 32-bit value at the first 16 byte aligned position of + * AUXV is greater than 16 for glibc compatibility. + * AT_IGNOREPPC is used for that. + * - for compatibility with glibc ARCH_DLINFO must always be defined on PPC, + * even if DLINFO_ARCH_ITEMS goes to zero or is undefined. + */ +#define DLINFO_ARCH_ITEMS 3 +#define ARCH_DLINFO \ +do { \ + sp -= DLINFO_ARCH_ITEMS * 2; \ + NEW_AUX_ENT(0, AT_DCACHEBSIZE, dcache_bsize); \ + NEW_AUX_ENT(1, AT_ICACHEBSIZE, icache_bsize); \ + NEW_AUX_ENT(2, AT_UCACHEBSIZE, ucache_bsize); \ + /* \ + * Now handle glibc compatibility. \ + */ \ + sp -= 2*2; \ + NEW_AUX_ENT(0, AT_IGNOREPPC, AT_IGNOREPPC); \ + NEW_AUX_ENT(1, AT_IGNOREPPC, AT_IGNOREPPC); \ + } while (0) #endif /* __KERNEL__ */ #endif diff --git a/include/asm-ppc/fads.h b/include/asm-ppc/fads.h index a23fe8b4e5a0..75ca0dd41fef 100644 --- a/include/asm-ppc/fads.h +++ b/include/asm-ppc/fads.h @@ -8,6 +8,7 @@ #ifndef __MACH_FADS_DEFS #define __MACH_FADS_DEFS +#ifndef __ASSEMBLY__ /* A Board Information structure that is given to a program when * prom starts it up. */ @@ -16,24 +17,54 @@ typedef struct bd_info { unsigned int bi_memsize; /* Memory (end) size in bytes */ unsigned int bi_intfreq; /* Internal Freq, in Hz */ unsigned int bi_busfreq; /* Bus Freq, in Hz */ + unsigned char bi_enetaddr[6]; + unsigned int bi_baudrate; } bd_t; extern bd_t m8xx_board_info; /* Memory map is configured by the PROM startup. * I tried to follow the FADS manual, although the startup PROM - * dictates this. + * dictates this and we simply have to move some of the physical + * addresses for Linux. */ -#define BCSR_ADDR ((uint)0x02100000) +#define BCSR_ADDR ((uint)0xfe000000) #define BCSR_SIZE ((uint)(64 * 1024)) -#define BCSR0 ((uint)0x02100000) -#define BCSR1 ((uint)0x02100004) -#define BCSR2 ((uint)0x02100008) -#define BCSR3 ((uint)0x0210000c) -#define BCSR4 ((uint)0x02100010) -#define IMAP_ADDR ((uint)0x02200000) +#define BCSR0 ((uint)0xfe000000) +#define BCSR1 ((uint)0xfe000004) +#define BCSR2 ((uint)0xfe000008) +#define BCSR3 ((uint)0xfe00000c) +#define BCSR4 ((uint)0xfe000010) +#define IMAP_ADDR ((uint)0xf0000000) #define IMAP_SIZE ((uint)(64 * 1024)) #define PCMCIA_MEM_ADDR ((uint)0x04000000) #define PCMCIA_MEM_SIZE ((uint)(64 * 1024)) + +/* Bits of interest in the BCSRs. + */ +#define BCSR1_ETHEN ((uint)0x20000000) +#define BCSR1_RS232EN_1 ((uint)0x01000000) +#define BCSR1_RS232EN_2 ((uint)0x00040000) +#define BCSR4_ETHLOOP ((uint)0x80000000) /* EEST Loopback */ +#define BCSR4_EEFDX ((uint)0x40000000) /* EEST FDX enable */ +#define BCSR4_FETH_EN ((uint)0x08000000) /* PHY enable */ +#define BCSR4_FETHCFG0 ((uint)0x04000000) /* PHY autoneg mode */ +#define BCSR4_FETHCFG1 ((uint)0x00400000) /* PHY autoneg mode */ +#define BCSR4_FETHFDE ((uint)0x02000000) /* PHY FDX advertise */ +#define BCSR4_FETHRST ((uint)0x00200000) /* PHY Reset */ +#endif /* !__ASSEMBLY__ */ + +/* Interrupt level assignments. + */ +#define FEC_INTERRUPT SIU_LEVEL1 /* FEC interrupt */ +#define PHY_INTERRUPT SIU_IRQ2 /* PHY link change interrupt */ + +/* We don't use the 8259. + */ +#define NR_8259_INTS 0 + +/* Machine type + */ +#define _MACH_8xx (_MACH_fads) #endif diff --git a/include/asm-ppc/feature.h b/include/asm-ppc/feature.h index 9e9f831d5bb7..58b9a58782ac 100644 --- a/include/asm-ppc/feature.h +++ b/include/asm-ppc/feature.h @@ -75,25 +75,32 @@ extern void feature_init(void); /* - * Additional functions related to Core99 machines + * Additional functions related to Core99 machines. We should extend the + * feature mecanism to make those fit into it. For now, they are still + * separate functions. */ extern void feature_set_gmac_power(struct device_node* device, int power); /* use constants in KeyLargo.h for the reset parameter */ -extern void feature_set_gmac_phy_reset(struct device_node* device, int reset); +extern void feature_gmac_phy_reset(struct device_node* device); extern void feature_set_usb_power(struct device_node* device, int power); extern void feature_set_firewire_power(struct device_node* device, int power); +extern void feature_set_firewire_cable_power(struct device_node* device, int power); -extern void feature_core99_kick_cpu1(void); +extern void feature_set_airport_power(struct device_node* device, int power); + +extern void feature_core99_kick_cpu(int cpu_nr); /* - * Sleep related functions. At term, they should be high-priority notifiers + * Sleep related functions. At term, they should be high-priority notifiers, + * but this would require some changes to the current sleep scheme that won't + * be done in 2.4. */ extern void feature_prepare_for_sleep(void); - extern void feature_wake_up(void); +extern int feature_can_sleep(void); #endif /* __ASM_PPC_FEATURE_H */ #endif /* __KERNEL__ */ diff --git a/include/asm-ppc/gemini.h b/include/asm-ppc/gemini.h new file mode 100644 index 000000000000..ebd01c9b6598 --- /dev/null +++ b/include/asm-ppc/gemini.h @@ -0,0 +1,168 @@ +/* + * include/asm-ppc/gemini.h + * + * + * Onboard registers and descriptions for Synergy Microsystems' + * "Gemini" boards. + * + */ +#ifdef __KERNEL__ +#ifndef __PPC_GEMINI_H +#define __PPC_GEMINI_H + +/* Registers */ + +#define GEMINI_SERIAL_B (0xffeffb00) +#define GEMINI_SERIAL_A (0xffeffb08) +#define GEMINI_USWITCH (0xffeffd00) +#define GEMINI_BREV (0xffeffe00) +#define GEMINI_BECO (0xffeffe08) +#define GEMINI_FEAT (0xffeffe10) +#define GEMINI_BSTAT (0xffeffe18) +#define GEMINI_CPUSTAT (0xffeffe20) +#define GEMINI_L2CFG (0xffeffe30) +#define GEMINI_MEMCFG (0xffeffe38) +#define GEMINI_FLROM (0xffeffe40) +#define GEMINI_P0PCI (0xffeffe48) +#define GEMINI_FLWIN (0xffeffe50) +#define GEMINI_P0INTMASK (0xffeffe60) +#define GEMINI_P0INTAP (0xffeffe68) +#define GEMINI_PCIERR (0xffeffe70) +#define GEMINI_LEDBASE (0xffeffe80) +#define GEMINI_RTC (0xffe9fff8) +#define GEMINI_LEDS 8 +#define GEMINI_SWITCHES 8 + + +/* Flash ROM bit definitions */ +#define GEMINI_FLS_WEN (1<<0) +#define GEMINI_FLS_JMP (1<<6) +#define GEMINI_FLS_BOOT (1<<7) + +/* Memory bit definitions */ +#define GEMINI_MEM_TYPE_MASK 0xc0 +#define GEMINI_MEM_SIZE_MASK 0x38 +#define GEMINI_MEM_BANK_MASK 0x07 + +/* L2 cache bit definitions */ +#define GEMINI_L2_SIZE_MASK 0xc0 +#define GEMINI_L2_RATIO_MASK 0x03 + +/* Timebase register bit definitons */ +#define GEMINI_TIMEB0_EN (1<<0) +#define GEMINI_TIMEB1_EN (1<<1) +#define GEMINI_TIMEB2_EN (1<<2) +#define GEMINI_TIMEB3_EN (1<<3) + +/* CPU status bit definitions */ +#define GEMINI_CPU_ID_MASK 0x03 +#define GEMINI_CPU_COUNT_MASK 0x0c +#define GEMINI_CPU0_HALTED (1<<4) +#define GEMINI_CPU1_HALTED (1<<5) +#define GEMINI_CPU2_HALTED (1<<6) +#define GEMINI_CPU3_HALTED (1<<7) + +/* Board status bit definitions */ +#define GEMINI_BRD_FAIL (1<<0) /* FAIL led is lit */ +#define GEMINI_BRD_BUS_MASK 0x0c /* PowerPC bus speed */ + +/* Board family/feature bit descriptions */ +#define GEMINI_FEAT_HAS_FLASH (1<<0) +#define GEMINI_FEAT_HAS_ETH (1<<1) +#define GEMINI_FEAT_HAS_SCSI (1<<2) +#define GEMINI_FEAT_HAS_P0 (1<<3) +#define GEMINI_FEAT_FAM_MASK 0xf0 + +/* Mod/ECO bit definitions */ +#define GEMINI_ECO_LEVEL_MASK 0x0f +#define GEMINI_MOD_MASK 0xf0 + +/* Type/revision bit definitions */ +#define GEMINI_REV_MASK 0x0f +#define GEMINI_TYPE_MASK 0xf0 + +/* User switch definitions */ +#define GEMINI_SWITCH_VERBOSE 1 /* adds "debug" to boot cmd line */ +#define GEMINI_SWITCH_SINGLE_USER 7 /* boots into "single-user" mode */ + +#define SGS_RTC_CONTROL 0 +#define SGS_RTC_SECONDS 1 +#define SGS_RTC_MINUTES 2 +#define SGS_RTC_HOURS 3 +#define SGS_RTC_DAY 4 +#define SGS_RTC_DAY_OF_MONTH 5 +#define SGS_RTC_MONTH 6 +#define SGS_RTC_YEAR 7 + +#define SGS_RTC_SET 0x80 +#define SGS_RTC_IS_STOPPED 0x80 + +#define GRACKLE_CONFIG_ADDR_ADDR (0xfec00000) +#define GRACKLE_CONFIG_DATA_ADDR (0xfee00000) + +#define GEMINI_BOOT_INIT (0xfff00100) + +#ifndef __ASSEMBLY__ + +static inline void grackle_write( unsigned long addr, unsigned long data ) +{ + __asm__ __volatile__( + " stwbrx %1, 0, %0\n \ + sync\n \ + stwbrx %3, 0, %2\n \ + sync " + : /* no output */ + : "r" (GRACKLE_CONFIG_ADDR_ADDR), "r" (addr), + "r" (GRACKLE_CONFIG_DATA_ADDR), "r" (data)); +} + +static inline unsigned long grackle_read( unsigned long addr ) +{ + unsigned long val; + + __asm__ __volatile__( + " stwbrx %1, 0, %2\n \ + sync\n \ + lwbrx %0, 0, %3\n \ + sync " + : "=r" (val) + : "r" (addr), "r" (GRACKLE_CONFIG_ADDR_ADDR), + "r" (GRACKLE_CONFIG_DATA_ADDR)); + + return val; +} + +static inline void gemini_led_on( int led ) +{ + if (led >= 0 && led < GEMINI_LEDS) + *(unsigned char *)(GEMINI_LEDBASE + (led<<3)) = 1; +} + +static inline void gemini_led_off(int led) +{ + if (led >= 0 && led < GEMINI_LEDS) + *(unsigned char *)(GEMINI_LEDBASE + (led<<3)) = 0; +} + +static inline int gemini_led_val(int led) +{ + int val = 0; + if (led >= 0 && led < GEMINI_LEDS) + val = *(unsigned char *)(GEMINI_LEDBASE + (led<<3)); + return (val & 0x1); +} + +/* returns processor id from the board */ +static inline int gemini_processor(void) +{ + unsigned char cpu = *(unsigned char *)(GEMINI_CPUSTAT); + return (int) ((cpu == 0) ? 4 : (cpu & GEMINI_CPU_ID_MASK)); +} + + +extern void _gemini_reboot(void); +extern void gemini_prom_init(void); +extern void gemini_init_l2(void); +#endif /* __ASSEMBLY__ */ +#endif +#endif /* __KERNEL__ */ diff --git a/include/asm-ppc/gemini_serial.h b/include/asm-ppc/gemini_serial.h new file mode 100644 index 000000000000..e4e08467e00d --- /dev/null +++ b/include/asm-ppc/gemini_serial.h @@ -0,0 +1,41 @@ +#ifdef __KERNEL__ +#ifndef __ASMPPC_GEMINI_SERIAL_H +#define __ASMPPC_GEMINI_SERIAL_H + +#include +#include + +#ifdef CONFIG_SERIAL_MANY_PORTS +#define RS_TABLE_SIZE 64 +#else +#define RS_TABLE_SIZE 4 +#endif + +/* Rate for the 24.576 Mhz clock for the onboard serial chip */ +#define BASE_BAUD (24576000 / 16) + +#ifdef CONFIG_SERIAL_DETECT_IRQ +#define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF|ASYNC_SKIP_TEST|ASYNC_AUTO_IRQ) +#define STD_COM4_FLAGS (ASYNC_BOOT_AUTOCONF|ASYNC_AUTO_IRQ) +#else +#define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF|ASYNC_SKIP_TEST) +#define STD_COM4_FLAGS (ASYNC_BOOT_AUTOCONF) +#endif + +#define STD_SERIAL_PORT_DEFNS \ + { 0, BASE_BAUD, GEMINI_SERIAL_A, 15, STD_COM_FLAGS }, /* ttyS0 */ \ + { 0, BASE_BAUD, GEMINI_SERIAL_B, 14, STD_COM_FLAGS }, /* ttyS1 */ \ + +#ifdef CONFIG_GEMINI_PU32 +#define PU32_SERIAL_PORT_DEFNS \ + { 0, BASE_BAUD, NULL, 0, STD_COM_FLAGS }, +#else +#define PU32_SERIAL_PORT_DEFNS +#endif + +#define SERIAL_PORT_DFNS \ + STD_SERIAL_PORT_DEFNS \ + PU32_SERIAL_PORT_DEFNS + +#endif +#endif /* __KERNEL__ */ diff --git a/include/asm-ppc/heathrow.h b/include/asm-ppc/heathrow.h index 039f221581f0..43fa694f90b2 100644 --- a/include/asm-ppc/heathrow.h +++ b/include/asm-ppc/heathrow.h @@ -6,14 +6,21 @@ * Copyright (C) 1997 Paul Mackerras. */ +/* Front light color on Yikes/B&W G3. 32 bits */ +#define HEATHROW_FRONT_LIGHT 0x32 /* (set to 0 or 0xffffffff) */ + +/* Brightness/contrast (gossamer iMac ?). 8 bits */ +#define HEATHROW_BRIGHTNESS_CNTL 0x32 +#define HEATHROW_CONTRAST_CNTL 0x33 + /* offset from ohare base for feature control register */ -#define HEATHROW_FEATURE_REG 0x38 +#define HEATHROW_FEATURE_REG 0x38 /* * Bits in feature control register. * Bits postfixed with a _N are in inverse logic */ -#define HRW_RESET_SCC 0x00000001 /* Named in_use_led in OF ??? */ +#define HRW_RESET_SCC 0x00000001 /* actually controls transceiver... */ #define HRW_BAY_POWER_N 0x00000002 #define HRW_BAY_PCI_ENABLE 0x00000004 #define HRW_BAY_IDE_ENABLE 0x00000008 diff --git a/include/asm-ppc/hw_irq.h b/include/asm-ppc/hw_irq.h index 54e4d711133c..7f2fc16565b9 100644 --- a/include/asm-ppc/hw_irq.h +++ b/include/asm-ppc/hw_irq.h @@ -7,31 +7,18 @@ #ifndef _PPC_HW_IRQ_H #define _PPC_HW_IRQ_H -struct int_control_struct -{ - void (*int_cli)(void); - void (*int_sti)(void); - void (*int_restore_flags)(unsigned long); - void (*int_save_flags)(unsigned long *); - void (*int_set_lost)(unsigned long); -}; -extern struct int_control_struct int_control; extern unsigned long timer_interrupt_intercept; extern unsigned long do_IRQ_intercept; int timer_interrupt(struct pt_regs *); -extern void __no_use_sti(void); -extern void __no_use_cli(void); -extern void __no_use_restore_flags(unsigned long); -extern void __no_use_save_flags(unsigned long *); -extern void __no_use_set_lost(unsigned long); +extern void __sti(void); +extern void __cli(void); +extern void __restore_flags(unsigned long); +extern void __save_flags_ptr(unsigned long *); +extern unsigned long __sti_end, __cli_end, __restore_flags_end, __save_flags_ptr_end; -#define __cli() int_control.int_cli() -#define __sti() int_control.int_sti() -#define __save_flags(flags) int_control.int_save_flags((unsigned long *)&flags) -#define __restore_flags(flags) int_control.int_restore_flags((unsigned long)flags) +#define __save_flags(flags) __save_flags_ptr((unsigned long *)&flags) #define __save_and_cli(flags) ({__save_flags(flags);__cli();}) -#define __set_lost(irq) ({ if ((unsigned long)int_control.int_set_lost) int_control.int_set_lost(irq); }) extern void do_lost_interrupts(unsigned long); diff --git a/include/asm-ppc/ide.h b/include/asm-ppc/ide.h index a9e3baf0d476..36ae7275cb88 100644 --- a/include/asm-ppc/ide.h +++ b/include/asm-ppc/ide.h @@ -16,7 +16,7 @@ #include #ifndef MAX_HWIFS -#define MAX_HWIFS 4 +#define MAX_HWIFS 8 #endif #include @@ -159,8 +159,13 @@ typedef union { } b; } select_t; +#if !defined(ide_request_irq) #define ide_request_irq(irq,hand,flg,dev,id) request_irq((irq),(hand),(flg),(dev),(id)) +#endif + +#if !defined(ide_free_irq) #define ide_free_irq(irq,dev_id) free_irq((irq), (dev_id)) +#endif /* * The following are not needed for the non-m68k ports diff --git a/include/asm-ppc/keylargo.h b/include/asm-ppc/keylargo.h index 02d3d58b2189..83cd3f65b1ec 100644 --- a/include/asm-ppc/keylargo.h +++ b/include/asm-ppc/keylargo.h @@ -3,6 +3,12 @@ * */ +/* "Pangea" chipset has keylargo device-id 0x25 while core99 + * has device-id 0x22. The rev. of the pangea one is 0, so we + * fake an artificial rev. in keylargo_rev by oring 0x100 + */ +#define KL_PANGEA_REV 0x100 + /* offset from base for feature control registers */ #define KEYLARGO_MBCR 0x34 /* Media bay control/status */ #define KEYLARGO_FCR0 0x38 @@ -18,25 +24,47 @@ #define KEYLARGO_GPIO_EXTINT_CNT 18 #define KEYLARGO_GPIO_0 0x6A #define KEYLARGO_GPIO_CNT 17 +#define KEYLARGO_GPIO_OUTPUT_ENABLE 0x04 +#define KEYLARGO_GPIO_OUTOUT_DATA 0x01 /* Specific GPIO regs */ +#define KL_GPIO_MODEM_RESET (KEYLARGO_GPIO_0+0x03) /* Pangea */ +#define KL_GPIO_MODEM_POWER (KEYLARGO_GPIO_0+0x02) /* Pangea */ + +#define KL_GPIO_FW_CABLE_POWER (KEYLARGO_GPIO_0+0x09) + #define KL_GPIO_ETH_PHY_RESET (KEYLARGO_GPIO_0+0x10) -#define KL_GPIO_ETH_PHY_RESET_ASSERT 0x04 -#define KL_GPIO_ETH_PHY_RESET_RELEASE 0x05 -#define KL_GPIO_ETH_PHY_RESET_TRISTATE 0x00 -#define KL_GPIO_KICK_CPU1 (KEYLARGO_GPIO_0+0x0a) -#define KL_GPIO_KICK_CPU1_UP 0x04 -#define KL_GPIO_KICK_CPU1_DOWN 0x38 +#define KL_GPIO_EXTINT_CPU1 (KEYLARGO_GPIO_0+0x0a) +#define KL_GPIO_EXTINT_CPU1_ASSERT 0x04 +#define KL_GPIO_EXTINT_CPU1_RELEASE 0x38 + +#define KL_GPIO_RESET_CPU0 (KEYLARGO_GPIO_EXTINT_0+0x03) +#define KL_GPIO_RESET_CPU1 (KEYLARGO_GPIO_EXTINT_0+0x04) +#define KL_GPIO_RESET_CPU2 (KEYLARGO_GPIO_EXTINT_0+0x0f) +#define KL_GPIO_RESET_CPU3 (KEYLARGO_GPIO_EXTINT_0+0x10) #define KL_GPIO_PMU_MESSAGE_IRQ (KEYLARGO_GPIO_EXTINT_0+0x09) #define KL_GPIO_PMU_MESSAGE_BIT 0x02 +#define KL_GPIO_AIRPORT_0 (KEYLARGO_GPIO_EXTINT_0+0x0a) +#define KL_GPIO_AIRPORT_1 (KEYLARGO_GPIO_EXTINT_0+0x0d) +#define KL_GPIO_AIRPORT_2 (KEYLARGO_GPIO_0+0x0d) +#define KL_GPIO_AIRPORT_3 (KEYLARGO_GPIO_0+0x0e) +#define KL_GPIO_AIRPORT_4 (KEYLARGO_GPIO_0+0x0f) + /* * Bits in feature control register */ -#define KL_MBCR_MBDEV_ENABLE 0x00001000 +#define KL_MBCR_MB0_DEV_ENABLE 0x00001000 +#define KL_MBCR_MB0_DEV_POWER 0x00000400 +#define KL_MBCR_MB0_DEV_RESET 0x00000200 +#define KL_MBCR_MB0_ENABLE 0x00000100 +#define KL_MBCR_MB1_DEV_ENABLE 0x10000000 +#define KL_MBCR_MB1_DEV_POWER 0x04000000 +#define KL_MBCR_MB1_DEV_RESET 0x02000000 +#define KL_MBCR_MB1_ENABLE 0x01000000 #define KL0_SCC_B_INTF_ENABLE 0x00000001 /* ??? */ #define KL0_SCC_A_INTF_ENABLE 0x00000002 /* ??? */ @@ -45,16 +73,27 @@ #define KL0_SCCA_ENABLE 0x00000010 #define KL0_SCCB_ENABLE 0x00000020 #define KL0_SCC_CELL_ENABLE 0x00000040 -#define KL0_IRDA_ENABLE 0x00008000 -#define KL0_IRDA_CLK32_ENABLE 0x00010000 -#define KL0_IRDA_CLK19_ENABLE 0x00020000 #define KL0_USB0_PAD_SUSPEND0 0x00040000 #define KL0_USB0_PAD_SUSPEND1 0x00080000 #define KL0_USB0_CELL_ENABLE 0x00100000 #define KL0_USB1_PAD_SUSPEND0 0x00400000 #define KL0_USB1_PAD_SUSPEND1 0x00800000 #define KL0_USB1_CELL_ENABLE 0x01000000 +/* KL id 0x22 only */ #define KL0_USB_REF_SUSPEND 0x10000000 +#define KL0_IRDA_ENABLE 0x00008000 +#define KL0_IRDA_CLK32_ENABLE 0x00010000 +#define KL0_IRDA_CLK19_ENABLE 0x00020000 +/* KL id 0x25 (pangea) only */ +#define KL0_USB1_PAD_SUSPEND_SEL 0x00020000 +#define KL0_USB1_REF_SUSPEND 0x00010000 +#define KL0_USB1_REF_SUSPEND_SEL 0x00008000 +#define KL0_USB1_PMI 0x00004000 +#define KL0_USB0_PAD_SUSPEND_SEL 0x00002000 +#define KL0_USB0_REF_SUSPEND 0x00001000 +#define KL0_USB0_REF_SUSPEND_SEL 0x00000800 +#define KL0_USB0_PMI 0x00000400 + #define KL0_SERIAL_ENABLE (KL0_SCC_B_INTF_ENABLE | \ KL0_SCC_SLOWPCLK | \ @@ -102,11 +141,11 @@ #define KL3_STOPPING33_ENABLED 0x00080000 /* Port 0,1 : bus 0, port 2,3 : bus 1 */ -#define KL4_SET_PORT_ENABLE(p) (0x00000008 << (p<<3)) -#define KL4_SET_PORT_RESUME(p) (0x00000004 << (p<<3)) -#define KL4_SET_PORT_CONNECT(p) (0x00000002 << (p<<3)) -#define KL4_SET_PORT_DISCONNECT(p) (0x00000001 << (p<<3)) -#define KL4_GET_PORT_RESUME(p) (0x00000040 << (p<<3)) -#define KL4_GET_PORT_CONNECT(p) (0x00000020 << (p<<3)) -#define KL4_GET_PORT_DISCONNECT(p) (0x00000010 << (p<<3)) +#define KL4_SET_PORT_ENABLE(p) (0x00000008 << ((p)<<3)) +#define KL4_SET_PORT_RESUME(p) (0x00000004 << ((p)<<3)) +#define KL4_SET_PORT_CONNECT(p) (0x00000002 << ((p)<<3)) +#define KL4_SET_PORT_DISCONNECT(p) (0x00000001 << ((p)<<3)) +#define KL4_GET_PORT_RESUME(p) (0x00000040 << ((p)<<3)) +#define KL4_GET_PORT_CONNECT(p) (0x00000020 << ((p)<<3)) +#define KL4_GET_PORT_DISCONNECT(p) (0x00000010 << ((p)<<3)) diff --git a/include/asm-ppc/machdep.h b/include/asm-ppc/machdep.h index ca254d0e7a86..f087d7a10266 100644 --- a/include/asm-ppc/machdep.h +++ b/include/asm-ppc/machdep.h @@ -22,7 +22,6 @@ struct machdep_calls { unsigned int (*irq_cannonicalize)(unsigned int irq); void (*init_IRQ)(void); int (*get_irq)(struct pt_regs *); - void (*post_irq)( struct pt_regs *, int ); /* A general init function, called by ppc_init in init/main.c. May be NULL. */ @@ -41,6 +40,7 @@ struct machdep_calls { unsigned long heartbeat_reset; unsigned long heartbeat_count; + unsigned long (*find_end_of_memory)(void); void (*progress)(char *, unsigned short); unsigned char (*nvram_read_val)(int addr); @@ -80,6 +80,11 @@ struct machdep_calls { */ int (*pcibios_enable_device_hook)(struct pci_dev *, int initial); + /* Called at then very end of pcibios_init() + */ + void (*pcibios_after_init)(void); + + /* this is for modules, since _machine can be a define -- Cort */ int ppc_machine; }; diff --git a/include/asm-ppc/mbx.h b/include/asm-ppc/mbx.h index a3e8f9b32c80..62f90f7fbfef 100644 --- a/include/asm-ppc/mbx.h +++ b/include/asm-ppc/mbx.h @@ -11,6 +11,7 @@ #ifndef __MACH_MBX_DEFS #define __MACH_MBX_DEFS +#ifndef __ASSEMBLY__ /* A Board Information structure that is given to a program when * EPPC-Bug starts it up. */ @@ -25,7 +26,13 @@ typedef struct bd_info { unsigned int bi_busfreq; /* Bus Freq, in Hz */ unsigned int bi_clun; /* Boot device controller */ unsigned int bi_dlun; /* Boot device logical dev */ - unsigned int bi_baudrate; /* ...to be like everyone else */ + + /* These fields are not part of the board information structure + * provided by the boot rom. They are filled in by embed_config.c + * so we have the information consistent with other platforms. + */ + unsigned char bi_enetaddr[6]; + unsigned int bi_baudrate; } bd_t; /* Memory map for the MBX as configured by EPPC-Bug. We could reprogram @@ -78,6 +85,7 @@ typedef struct bd_info { #define ISA_BRIDGE_INT SIU_IRQ3 /* All those PC things */ #define COMM_L_INT SIU_IRQ6 /* MBX Comm expansion connector pin */ #define STOP_ABRT_INT SIU_IRQ7 /* Stop/Abort header pin */ +#endif /* !__ASSEMBLY__ */ /* The MBX uses the 8259. */ diff --git a/include/asm-ppc/mmu_context.h b/include/asm-ppc/mmu_context.h index f8ef4e604bf6..e03b74bc10d3 100644 --- a/include/asm-ppc/mmu_context.h +++ b/include/asm-ppc/mmu_context.h @@ -18,6 +18,12 @@ of any task that makes a kernel entry. Shared does not mean they are not protected, just that the ASID comparison is not performed. -- Dan + + The IBM4xx has 256 contexts, so we can just rotate through these + as a way of "switching" contexts. If the TID of the TLB is zero, + the PID/TID comparison is disabled, so we can use a TID of zero + to represent all kernel pages as shared among all contexts. + -- Dan */ static inline void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk, unsigned cpu) @@ -26,12 +32,22 @@ static inline void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk, #ifdef CONFIG_8xx #define NO_CONTEXT 16 #define LAST_CONTEXT 15 +#define BASE_CONTEXT (-1) +#define MUNGE_CONTEXT(n) (n) +#define flush_hash_segments(X, Y) do { } while (0) + +#elif CONFIG_4xx +#define NO_CONTEXT 256 +#define LAST_CONTEXT 255 +#define BASE_CONTEXT (0) #define MUNGE_CONTEXT(n) (n) +#define flush_hash_segments(X, Y) do { } while (0) #else /* PPC 6xx, 7xx CPUs */ #define NO_CONTEXT 0 +#define BASE_CONTEXT (0) #define LAST_CONTEXT 0xfffff /* diff --git a/include/asm-ppc/mpc8xx.h b/include/asm-ppc/mpc8xx.h index 499114d00916..fd8a11f30302 100644 --- a/include/asm-ppc/mpc8xx.h +++ b/include/asm-ppc/mpc8xx.h @@ -63,11 +63,14 @@ #define PCI_DRAM_OFFSET 0 #endif #else +#if !defined(_IO_BASE) /* defined in board specific header */ #define _IO_BASE 0 +#endif #define _ISA_MEM_BASE 0 #define PCI_DRAM_OFFSET 0 #endif +#ifndef __ASSEMBLY__ extern unsigned long isa_io_base; extern unsigned long isa_mem_base; extern unsigned long pci_dram_offset; @@ -82,6 +85,7 @@ extern int request_8xxirq(unsigned int irq, unsigned long flags, const char *device, void *dev_id); +#endif /* !__ASSEMBLY__ */ #endif /* CONFIG_8xx */ #endif #endif /* __KERNEL__ */ diff --git a/include/asm-ppc/oak.h b/include/asm-ppc/oak.h index 63f3164012a4..fcd8976f4a7b 100644 --- a/include/asm-ppc/oak.h +++ b/include/asm-ppc/oak.h @@ -66,5 +66,10 @@ typedef struct board_info { } #endif +/* Generic 4xx type +*/ +#define _MACH_4xx (_MACH_oak) + + #endif /* __OAK_H__ */ #endif /* __KERNEL__ */ diff --git a/include/asm-ppc/pci-bridge.h b/include/asm-ppc/pci-bridge.h index a6c8d89192c0..0dc296d8c708 100644 --- a/include/asm-ppc/pci-bridge.h +++ b/include/asm-ppc/pci-bridge.h @@ -27,6 +27,11 @@ extern struct pci_controller* pci_bus_to_hose(int bus); extern struct pci_controller* pci_find_hose_for_OF_device(struct device_node* node); +/* Fill up host controller resources from the OF node */ +extern void +pci_process_bridge_OF_ranges(struct pci_controller *hose, + struct device_node *dev, int primary); + /* * Structure of a PCI controller (host bridge) */ diff --git a/include/asm-ppc/pci.h b/include/asm-ppc/pci.h index 4a46b9601ea1..476156c37ed6 100644 --- a/include/asm-ppc/pci.h +++ b/include/asm-ppc/pci.h @@ -110,6 +110,9 @@ extern inline int pci_dma_supported(struct pci_dev *hwdev, dma_addr_t mask) return 1; } +/* Return the index of the PCI controller for device PDEV. */ +#define pci_controller_num(PDEV) (0) + #define sg_dma_address(sg) (virt_to_bus((sg)->address)) #define sg_dma_len(sg) ((sg)->length) diff --git a/include/asm-ppc/pgtable.h b/include/asm-ppc/pgtable.h index 353f5c9bfbe8..7684557382c3 100644 --- a/include/asm-ppc/pgtable.h +++ b/include/asm-ppc/pgtable.h @@ -418,11 +418,11 @@ static inline unsigned long pte_update(pte_t *p, unsigned long clr, { unsigned long old, tmp; - __asm__ __volatile__("\ -1: lwarx %0,0,%3 - andc %1,%0,%4 - or %1,%1,%5 - stwcx. %1,0,%3 + __asm__ __volatile__("\n\ +1: lwarx %0,0,%3 \n\ + andc %1,%0,%4 \n\ + or %1,%1,%5 \n\ + stwcx. %1,0,%3 \n\ bne- 1b" : "=&r" (old), "=&r" (tmp), "=m" (*p) : "r" (p), "r" (clr), "r" (set), "m" (*p) diff --git a/include/asm-ppc/ppc4xx.h b/include/asm-ppc/ppc4xx.h new file mode 100644 index 000000000000..270b40485416 --- /dev/null +++ b/include/asm-ppc/ppc4xx.h @@ -0,0 +1,282 @@ +/* + * + * Copyright (c) 1999 Grant Erickson + * + * Module name: ppc4xx.h + * + * Description: + * A generic include file which pulls in appropriate include files + * for specific board types based on configuration settings. + * + */ + +#ifdef __KERNEL__ +#ifndef __PPC4XX_H__ +#define __PPC4XX_H__ + +#include + +#ifndef __ASSEMBLY__ + +#if defined(CONFIG_OAK) +#include +#endif + +#if defined(CONFIG_WALNUT) +#include +#endif + +/* IO_BASE is for PCI I/O. + * ISA not supported, just here to resolve copilation. + */ + +#define _IO_BASE 0xe8000000 /* The PCI address window */ +#define _ISA_MEM_BASE 0 +#define PCI_DRAM_OFFSET 0 + +extern unsigned long isa_io_base; + +/* + * The "residual" board information structure the boot loader passes + * into the kernel. + */ +extern unsigned char __res[]; + +/* I don't know if this is general to 4xx, or unique to a specific + * processor or board. In any case it is easy to move. + */ +#define PPC4xx_PCI_IO_ADDR ((uint)0xe8000000) +#define PPC4xx_PCI_IO_SIZE ((uint)64*1024) +#define PPC4xx_PCI_CFG_ADDR ((uint)0xeec00000) +#define PPC4xx_PCI_CFG_SIZE ((uint)4*1024) +#define PPC4xx_PCI_LCFG_ADDR ((uint)0xef400000) +#define PPC4xx_PCI_LCFG_SIZE ((uint)4*1024) +#define PPC4xx_ONB_IO_ADDR ((uint)0xef600000) +#define PPC4xx_ONB_IO_SIZE ((uint)4*1024) + +#endif /* __ASSEMBLY__ */ + +/* Device Control Registers unique to 4xx */ + +#define DCRN_BEAR 0x090 /* Bus Error Address Register */ +#define DCRN_BESR 0x091 /* Bus Error Syndrome Register */ +#define BESR_DSES 0x80000000 /* Data-Side Error Status */ +#define BESR_DMES 0x40000000 /* DMA Error Status */ +#define BESR_RWS 0x20000000 /* Read/Write Status */ +#define BESR_ETMASK 0x1C000000 /* Error Type */ +#define ET_PROT 0 +#define ET_PARITY 1 +#define ET_NCFG 2 +#define ET_BUSERR 4 +#define ET_BUSTO 6 +#define DCRN_CHCR0 0x0B1 /* Chip Control Register 1 */ +#define DCRN_CHCR1 0x0B2 /* Chip Control Register 2 */ +#define DCRN_CHPSR 0x0B4 /* Chip Pin Strapping */ +#define DCRN_CPMER 0x0B9 /* CPM Enable */ +#define DCRN_CPMFR 0x0BA /* CPM Force */ +#define CPM_IIC 0x80000000 /* IIC interface */ +#define CPM_PCI 0x40000000 /* PCI bridge */ +#define CPM_CPU 0x20000000 /* processor core */ +#define CPM_DMA 0x10000000 /* DMA controller */ +#define CPM_BRG 0x08000000 /* PLB to OPB bridge */ +#define CPM_DCP 0x04000000 /* CodePack */ +#define CPM_EBC 0x02000000 /* ROM/SRAM peripheral controller */ +#define CPM_SDRAM 0x01000000 /* SDRAM memory controller */ +#define CPM_PLB 0x00800000 /* PLB bus arbiter */ +#define CPM_GPIO 0x00400000 /* General Purpose IO (??) */ +#define CPM_UART0 0x00200000 /* serial port 0 */ +#define CPM_UART1 0x00100000 /* serial port 1 */ +#define CPM_UIC 0x00080000 /* Universal Interrupt Controller */ +#define CPM_TMRCLK 0x00040000 /* CPU timers */ +#define CPM_EMAC_MM 0x00020000 /* on-chip ethernet MM unit */ +#define CPM_EMAC_RM 0x00010000 /* on-chip ethernet RM unit */ +#define CPM_EMAC_TM 0x00008000 /* on-chip ethernet TM unit */ +#define DCRN_CPMSR 0x0B8 /* CPM Status */ + +#define DCRN_DMACR0 0x100 /* DMA Channel Control Register 0 */ +#define DCRN_DMACT0 0x101 /* DMA Count Register 0 */ +#define DCRN_DMADA0 0x102 /* DMA Destination Address Register 0 */ +#define DCRN_DMASA0 0x103 /* DMA Source Address Register 0 */ +#define DCRN_ASG0 0x104 /* DMA Scatter/Gather Descriptor Addr 0 */ + +#define DCRN_DMACR1 0x108 /* DMA Channel Control Register 1 */ +#define DCRN_DMACT1 0x109 /* DMA Count Register 1 */ +#define DCRN_DMADA1 0x10A /* DMA Destination Address Register 1 */ +#define DCRN_DMASA1 0x10B /* DMA Source Address Register 1 */ +#define DCRN_ASG1 0x10C /* DMA Scatter/Gather Descriptor Addr 1 */ + +#define DCRN_DMACR2 0x110 /* DMA Channel Control Register 2 */ +#define DCRN_DMACT2 0x111 /* DMA Count Register 2 */ +#define DCRN_DMADA2 0x112 /* DMA Destination Address Register 2 */ +#define DCRN_DMASA2 0x113 /* DMA Source Address Register 2 */ +#define DCRN_ASG2 0x114 /* DMA Scatter/Gather Descriptor Addr 2 */ + +#define DCRN_DMACR3 0x118 /* DMA Channel Control Register 3 */ +#define DCRN_DMACT3 0x119 /* DMA Count Register 3 */ +#define DCRN_DMADA3 0x11A /* DMA Destination Address Register 3 */ +#define DCRN_DMASA3 0x11B /* DMA Source Address Register 3 */ +#define DCRN_ASG3 0x11C /* DMA Scatter/Gather Descriptor Addr 3 */ + +#define DCRN_DMASR 0x120 /* DMA Status Register */ +#define DCRN_ASGC 0x123 /* DMA Scatter/Gather Command */ +#define DCRN_ADR 0x124 /* DMA Address Decode */ + +#define DCRN_SLP 0x125 /* DMA Sleep Register */ +#define DCRN_POL 0x126 /* DMA Polarity Register */ + + +#define DCRN_EBCCFGADR 0x012 /* Peripheral Controller Address */ +#define DCRN_EBCCFGDATA 0x013 /* Peripheral Controller Data */ +#define DCRN_EXISR 0x040 /* External Interrupt Status Register */ +#define DCRN_EXIER 0x042 /* External Interrupt Enable Register */ +#define EXIER_CIE 0x80000000 /* Critical Interrupt Enable */ +#define EXIER_SRIE 0x08000000 /* Serial Port Rx Int. Enable */ +#define EXIER_STIE 0x04000000 /* Serial Port Tx Int. Enable */ +#define EXIER_JRIE 0x02000000 /* JTAG Serial Port Rx Int. Enable */ +#define EXIER_JTIE 0x01000000 /* JTAG Serial Port Tx Int. Enable */ +#define EXIER_D0IE 0x00800000 /* DMA Channel 0 Interrupt Enable */ +#define EXIER_D1IE 0x00400000 /* DMA Channel 1 Interrupt Enable */ +#define EXIER_D2IE 0x00200000 /* DMA Channel 2 Interrupt Enable */ +#define EXIER_D3IE 0x00100000 /* DMA Channel 3 Interrupt Enable */ +#define EXIER_E0IE 0x00000010 /* External Interrupt 0 Enable */ +#define EXIER_E1IE 0x00000008 /* External Interrupt 1 Enable */ +#define EXIER_E2IE 0x00000004 /* External Interrupt 2 Enable */ +#define EXIER_E3IE 0x00000002 /* External Interrupt 3 Enable */ +#define EXIER_E4IE 0x00000001 /* External Interrupt 4 Enable */ +#define DCRN_IOCR 0x0A0 /* Input/Output Configuration Register */ +#define IOCR_E0TE 0x80000000 +#define IOCR_E0LP 0x40000000 +#define IOCR_E1TE 0x20000000 +#define IOCR_E1LP 0x10000000 +#define IOCR_E2TE 0x08000000 +#define IOCR_E2LP 0x04000000 +#define IOCR_E3TE 0x02000000 +#define IOCR_E3LP 0x01000000 +#define IOCR_E4TE 0x00800000 +#define IOCR_E4LP 0x00400000 +#define IOCR_EDT 0x00080000 +#define IOCR_SOR 0x00040000 +#define IOCR_EDO 0x00008000 +#define IOCR_2XC 0x00004000 +#define IOCR_ATC 0x00002000 +#define IOCR_SPD 0x00001000 +#define IOCR_BEM 0x00000800 +#define IOCR_PTD 0x00000400 +#define IOCR_ARE 0x00000080 +#define IOCR_DRC 0x00000020 +#define IOCR_RDM(x) (((x) & 0x3) << 3) +#define IOCR_TCS 0x00000004 +#define IOCR_SCS 0x00000002 +#define IOCR_SPC 0x00000001 +#define DCRN_KIAR 0x014 /* Decompression Controller Address */ +#define DCRN_KIDR 0x015 /* Decompression Controller Data */ +#define DCRN_MALCR 0x180 /* MAL Configuration */ +#define MALCR_MMSR 0x80000000 /* MAL Software reset */ +#define MALCR_PLBP_1 0x00400000 /* MAL reqest priority: */ +#define MALCR_PLBP_2 0x00800000 /* lowsest is 00 */ +#define MALCR_PLBP_3 0x00C00000 /* highest */ +#define MALCR_GA 0x00200000 /* Guarded Active Bit */ +#define MALCR_OA 0x00100000 /* Ordered Active Bit */ +#define MALCR_PLBLE 0x00080000 /* PLB Lock Error Bit */ +#define MALCR_PLBLT_1 0x00040000 /* PLB Latency Timer */ +#define MALCR_PLBLT_2 0x00020000 +#define MALCR_PLBLT_3 0x00010000 +#define MALCR_PLBLT_4 0x00008000 +#define MALCR_PLBLT_DEFAULT 0x00078000 /* JSP: Is this a valid default?? */ +#define MALCR_PLBB 0x00004000 /* PLB Burst Deactivation Bit */ +#define MALCR_OPBBL 0x00000080 /* OPB Lock Bit */ +#define MALCR_EOPIE 0x00000004 /* End Of Packet Interrupt Enable */ +#define MALCR_LEA 0x00000002 /* Locked Error Active */ +#define MALCR_MSD 0x00000001 /* MAL Scroll Descriptor Bit */ +#define DCRN_MALDBR 0x183 /* Debug Register */ +#define DCRN_MALESR 0x181 /* Error Status */ +#define MALESR_EVB 0x80000000 /* Error Valid Bit */ +#define MALESR_CID 0x40000000 /* Channel ID Bit for channel 0 */ +#define MALESR_DE 0x00100000 /* Descriptor Error */ +#define MALESR_OEN 0x00080000 /* OPB Non-Fullword Error */ +#define MALESR_OTE 0x00040000 /* OPB Timeout Error */ +#define MALESR_OSE 0x00020000 /* OPB Slave Error */ +#define MALESR_PEIN 0x00010000 /* PLB Bus Error Indication */ +#define MALESR_DEI 0x00000010 /* Descriptor Error Interrupt */ +#define MALESR_ONEI 0x00000008 /* OPB Non-Fullword Error Interrupt */ +#define MALESR_OTEI 0x00000004 /* OPB Timeout Error Interrupt */ +#define MALESR_OSEI 0x00000002 /* OPB Slace Error Interrupt */ +#define MALESR_PBEI 0x00000001 /* PLB Bus Error Interrupt */ +#define DCRN_MALIER 0x182 /* Interrupt Enable */ +#define MALIER_DE 0x00000010 /* Descriptor Error Interrupt Enable */ +#define MALIER_NE 0x00000008 /* OPB Non-word Transfer Int Enable */ +#define MALIER_TE 0x00000004 /* OPB Time Out Error Interrupt Enable */ +#define MALIER_OPBE 0x00000002 /* OPB Slave Error Interrupt Enable */ +#define MALIER_PLBE 0x00000001 /* PLB Error Interrupt Enable */ +#define DCRN_MALTXCARR 0x185 /* TX Channed Active Reset Register */ +#define DCRN_MALTXCASR 0x184 /* TX Channel Active Set Register */ +#define DCRN_MALTXDEIR 0x187 /* Tx Descriptor Error Interrupt */ +#define DCRN_MALTXEOBISR 0x186 /* Tx End of Buffer Interrupt Status */ +#define MALOBISR_CH0 0x80000000 /* EOB channel 1 bit */ +#define MALOBISR_CH2 0x40000000 /* EOB channel 2 bit */ +#define DCRN_MALRXCARR 0x191 /* RX Channed Active Reset Register */ +#define DCRN_MALRXCASR 0x190 /* RX Channel Active Set Register */ +#define DCRN_MALRXDEIR 0x193 /* Rx Descriptor Error Interrupt */ +#define DCRN_MALRXEOBISR 0x192 /* Rx End of Buffer Interrupt Status */ +#define DCRN_MALRXCTP0R 0x1C0 /* Channel Rx 0 Channel Table Pointer */ +#define DCRN_MALTXCTP0R 0x1A0 /* Channel Tx 0 Channel Table Pointer */ +#define DCRN_MALTXCTP1R 0x1A1 /* Channel Tx 1 Channel Table Pointer */ +#define DCRN_MALRCBS0 0x1E0 /* Channel Rx 0 Channel Buffer Size */ +#define DCRN_MEMCFGADR 0x010 /* Memory Controller Address */ +#define DCRN_MEMCFGDATA 0x011 /* Memory Controller Data */ +#define DCRN_OCMISARC 0x018 /* OCM Instr Side Addr Range Compare */ +#define DCRN_OCMISCR 0x019 /* OCM Instr Side Control */ +#define DCRN_OCMDSARC 0x01A /* OCM Data Side Addr Range Compare */ +#define DCRN_OCMDSCR 0x01B /* OCM Data Side Control */ +#define DCRN_PLB0_ACR 0x087 /* PLB Arbiter Control */ +#define DCRN_PLB0_BEAR 0x086 /* PLB Error Address */ +#define DCRN_PLB0_BESR 0x084 /* PLB Error Status */ +#define DCRN_PLLMR 0x0B0 /* PLL Mode */ +#define DCRN_POB0_BEAR 0x0A2 /* PLB to OPB Error Address */ +#define DCRN_POB0_BESR0 0x0A0 /* PLB to OPB Error Status Register 1 */ +#define DCRN_POB0_BESR1 0x0A4 /* PLB to OPB Error Status Register 1 */ +#define DCRN_UICCR 0x0C3 /* UIC Critical */ +#define DCRN_UICER 0x0C2 /* UIC Enable */ +#define DCRN_UICPR 0x0C4 /* UIC Polarity */ +#define DCRN_UICSR 0x0C0 /* UIC Status */ +#define DCRN_UICTR 0x0C5 /* UIC Triggering */ +#define DCRN_UICMSR 0x0C6 /* UIC Masked Status */ +#define DCRN_UICVR 0x0C7 /* UIC Vector */ +#define DCRN_UICVCR 0x0C8 /* UIC Vector Configuration */ +#define UIC_U0 0x80000000 /* UART0 */ +#define UIC_U1 0x40000000 /* UART1 */ +#define UIC_IIC 0x20000000 /* IIC */ +#define UIC_EM 0x10000000 /* External Master */ +#define UIC_PCI 0x08000000 /* PCI */ +#define UIC_D0 0x04000000 /* DMA Channel 0 */ +#define UIC_D1 0x02000000 /* DMA Channel 1 */ +#define UIC_D2 0x01000000 /* DMA Channel 2 */ +#define UIC_D3 0x00800000 /* DMA Channel 3 */ +#define UIC_EW 0x00400000 /* Ethernet Wake-up */ +#define UIC_MS 0x00200000 /* MAL SERR */ +#define UIC_MTE 0x00100000 /* MAL TX EOB */ +#define UIC_MRE 0x00080000 /* MAL RX EOB */ +#define UIC_MTD 0x00040000 /* MAL TX DE */ +#define UIC_MRD 0x00020000 /* MAL RX DE */ +#define UIC_E 0x00010000 /* Ethernet */ +#define UIC_EPS 0x00008000 /* External PCI SERR */ +#define UIC_EC 0x00004000 /* ECC Correctable Error */ +#define UIC_PPM 0x00002000 /* PCI Power Management */ +/* +** 0x00001000 reserved +** 0x00000800 reserved +** 0x00000400 reserved +** 0x00000200 reserved +** 0x00000100 reserved +** 0x00000080 reserved +*/ +#define UIC_EIR0 0x00000040 /* External IRQ 0 */ +#define UIC_EIR1 0x00000020 /* External IRQ 0 */ +#define UIC_EIR2 0x00000010 /* External IRQ 0 */ +#define UIC_EIR3 0x00000008 /* External IRQ 0 */ +#define UIC_EIR4 0x00000004 /* External IRQ 0 */ +#define UIC_EIR5 0x00000002 /* External IRQ 0 */ +#define UIC_EIR6 0x00000001 /* External IRQ 0 */ + +#endif /* __PPC4XX_H__ */ +#endif /* __KERNEL__ */ diff --git a/include/asm-ppc/ppc4xx_serial.h b/include/asm-ppc/ppc4xx_serial.h new file mode 100644 index 000000000000..3296c679ecfe --- /dev/null +++ b/include/asm-ppc/ppc4xx_serial.h @@ -0,0 +1,101 @@ +/* + * Copyright 2000 MontaVista Software Inc. + * PPC405GP modifications + * Author: MontaVista Software, Inc. + * frank_rowand@mvista.com or source@mvista.com + * debbie_chu@mvista.com + * + * Module name: ppc405_serial.h + * + * Description: + * Macros, definitions, and data structures specific to the IBM PowerPC + * 405 on-chip serial port devices. + */ + +#ifdef __KERNEL__ +#ifndef __ASMPPC_PPC4xx_SERIAL_H +#define __ASMPPC_PPC4xx_SERIAL_H + +#include + +#ifdef CONFIG_SERIAL_MANY_PORTS +#define RS_TABLE_SIZE 64 +#else +#define RS_TABLE_SIZE 4 +#endif + +#define PPC405GP_UART0_INT 0 +#define PPC405GP_UART1_INT 1 + +/* +** 405GP UARTs are *not* PCI devices, so need to specify a non-pci memory +** address and an io_type of SERIAL_IO_MEM. +*/ + +#define PPC405GP_UART0_IO_BASE (u8 *) 0xef600300 +#define PPC405GP_UART1_IO_BASE (u8 *) 0xef600400 + +/* +** - there is no config option for this +** - this name could be more informative +** - also see arch/ppc/kernel/ppc405_serial.c +** +** #define CONFIG_PPC405GP_INTERNAL_CLOCK +*/ +#ifdef CONFIG_PPC405GP_INTERNAL_CLOCK +#define BASE_BAUD 201600 +#else +#define BASE_BAUD 691200 +#endif + + +#ifdef CONFIG_SERIAL_DETECT_IRQ +#define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST | ASYNC_AUTO_IRQ) +#define STD_COM4_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_AUTO_IRQ) +#else +#define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST) +#define STD_COM4_FLAGS (ASYNC_BOOT_AUTOCONF) +#endif + + +#ifdef CONFIG_STB03XXX + +#define UART0_IO_BASE 0x40040000 +#define UART0_INT 20 + +#define STD_SERIAL_PORT_DFNS \ + /* ttyS0 */ \ + { 0, BASE_BAUD, 0, UART0_INT, STD_COM_FLAGS, 0, 0, 0, 0, 0, 0, 0, \ + UART0_IO_BASE, 0, 0, 0, {}, {}, {}, SERIAL_IO_MEM, NULL }, + +#elif defined(CONFIG_UART1_DFLT_CONSOLE) + +#define STD_SERIAL_PORT_DFNS \ + /* ttyS1 */ \ + { 0, BASE_BAUD, 0, PPC405GP_UART1_INT, STD_COM_FLAGS, 0, 0, 0, 0, 0, 0, 0, \ + PPC405GP_UART1_IO_BASE, 0, 0, 0, {}, {}, {}, SERIAL_IO_MEM, NULL }, \ + /* ttyS0 */ \ + { 0, BASE_BAUD, 0, PPC405GP_UART0_INT, STD_COM_FLAGS, 0, 0, 0, 0, 0, 0, 0, \ + PPC405GP_UART0_IO_BASE, 0, 0, 0, {}, {}, {}, SERIAL_IO_MEM, NULL }, + +#else + +#define STD_SERIAL_PORT_DFNS \ + /* ttyS0 */ \ + { 0, BASE_BAUD, 0, PPC405GP_UART0_INT, STD_COM_FLAGS, 0, 0, 0, 0, 0, 0, 0, \ + PPC405GP_UART0_IO_BASE, 0, 0, 0, {}, {}, {}, SERIAL_IO_MEM, NULL }, \ + /* ttyS1 */ \ + { 0, BASE_BAUD, 0, PPC405GP_UART1_INT, STD_COM_FLAGS, 0, 0, 0, 0, 0, 0, 0, \ + PPC405GP_UART1_IO_BASE, 0, 0, 0, {}, {}, {}, SERIAL_IO_MEM, NULL }, + +#endif + + +#define SERIAL_PORT_DFNS \ + STD_SERIAL_PORT_DFNS \ + {} + + + +#endif /* __ASMPPC_PPC4xx_SERIAL_H */ +#endif /* __KERNEL__ */ diff --git a/include/asm-ppc/processor.h b/include/asm-ppc/processor.h index dc96fdcaf6db..3e01f53275ac 100644 --- a/include/asm-ppc/processor.h +++ b/include/asm-ppc/processor.h @@ -12,6 +12,7 @@ #include #include +#include /* Machine State Register (MSR) Fields */ @@ -31,6 +32,7 @@ #define MSR_ME (1<<12) /* Machine Check Enable */ #define MSR_FE0 (1<<11) /* Floating Exception mode 0 */ #define MSR_SE (1<<10) /* Single Step */ +#define MSR_DWE (1<<10) /* Debug Wait Enable (4xx) */ #define MSR_BE (1<<9) /* Branch Trace */ #define MSR_DE (1<<9) /* Debug Exception Enable */ #define MSR_FE1 (1<<8) /* Floating Exception mode 1 */ @@ -82,6 +84,7 @@ /* Special Purpose Registers (SPRNs)*/ +#define SPRN_CCR0 0x3B3 /* Core Configuration Register (4xx) */ #define SPRN_CDBCR 0x3D7 /* Cache Debug Control Register */ #define SPRN_CTR 0x009 /* Count Register */ #define SPRN_DABR 0x3F5 /* Data Address Breakpoint Register */ @@ -132,6 +135,8 @@ #define SPRN_DBCR0 0x3F2 /* Debug Control Register 0 */ #define SPRN_DBCR1 0x3BD /* Debug Control Register 1 */ #define SPRN_DBSR 0x3F0 /* Debug Status Register */ +#define DBSR_IC 0x80000000 /* Instruction Completion */ +#define DBSR_TIE 0x10000000 /* Trap Instruction debug Event */ #define SPRN_DCCR 0x3FA /* Data Cache Cacheability Register */ #define DCCR_NOCACHE 0 /* Noncacheable */ #define DCCR_CACHE 1 /* Cacheable */ @@ -141,6 +146,26 @@ #define DCWR_WRITE 1 /* Write-through */ #define SPRN_DEAR 0x3D5 /* Data Error Address Register */ #define SPRN_DEC 0x016 /* Decrement Register */ +#define SPRN_DER 0x095 /* Debug Enable Regsiter */ +#define DER_RSTE 0x40000000 /* Reset Interrupt */ +#define DER_CHSTPE 0x20000000 /* Check Stop */ +#define DER_MCIE 0x10000000 /* Machine Check Interrupt */ +#define DER_EXTIE 0x02000000 /* External Interrupt */ +#define DER_ALIE 0x01000000 /* Alignment Interrupt */ +#define DER_PRIE 0x00800000 /* Program Interrupt */ +#define DER_FPUVIE 0x00400000 /* FP Unavailable Interrupt */ +#define DER_DECIE 0x00200000 /* Decrementer Interrupt */ +#define DER_SYSIE 0x00040000 /* System Call Interrupt */ +#define DER_TRE 0x00020000 /* Trace Interrupt */ +#define DER_SEIE 0x00004000 /* FP SW Emulation Interrupt */ +#define DER_ITLBMSE 0x00002000 /* Imp. Spec. Instruction TLB Miss */ +#define DER_ITLBERE 0x00001000 /* Imp. Spec. Instruction TLB Error */ +#define DER_DTLBMSE 0x00000800 /* Imp. Spec. Data TLB Miss */ +#define DER_DTLBERE 0x00000400 /* Imp. Spec. Data TLB Error */ +#define DER_LBRKE 0x00000008 /* Load/Store Breakpoint Interrupt */ +#define DER_IBRKE 0x00000004 /* Instruction Breakpoint Interrupt */ +#define DER_EBRKE 0x00000002 /* External Breakpoint Interrupt */ +#define DER_DPIE 0x00000001 /* Dev. Port Nonmaskable Request */ #define SPRN_DMISS 0x3D0 /* Data TLB Miss Register */ #define SPRN_DSISR 0x012 /* Data Storage Interrupt Status Register */ #define SPRN_EAR 0x11A /* External Address Register */ @@ -178,6 +203,7 @@ #define HID0_SPD (1<<9) /* Speculative disable */ #define HID0_SGE (1<<7) /* Store Gathering Enable */ #define HID0_SIED (1<<7) /* Serial Instr. Execution [Disable] */ +#define HID0_DFCA (1<<6) /* Data Cache Flush Assist */ #define HID0_BTIC (1<<5) /* Branch Target Instruction Cache Enable */ #define HID0_ABE (1<<3) /* Address Broadcast Enable */ #define HID0_BHTE (1<<2) /* Branch History Table Enable */ @@ -203,12 +229,35 @@ #define SPRN_IMISS 0x3D4 /* Instruction TLB Miss Register */ #define SPRN_IMMR 0x27E /* Internal Memory Map Register */ #define SPRN_L2CR 0x3F9 /* Level 2 Cache Control Regsiter */ -#define L2CR_PIPE_LATEWR (0x01800000) /* late-write SRAM */ -#define L2CR_L2CTL (0x00100000) /* RAM control */ -#define L2CR_INST_DISABLE (0x00400000) /* disable for insn's */ -#define L2CR_L2I (0x00200000) /* global invalidate */ -#define L2CR_L2E (0x80000000) /* enable */ -#define L2CR_L2WT (0x00080000) /* write-through */ +#define L2CR_L2E 0x80000000 /* L2 enable */ +#define L2CR_L2PE 0x40000000 /* L2 parity enable */ +#define L2CR_L2SIZ_MASK 0x30000000 /* L2 size mask */ +#define L2CR_L2SIZ_256KB 0x10000000 /* L2 size 256KB */ +#define L2CR_L2SIZ_512KB 0x20000000 /* L2 size 512KB */ +#define L2CR_L2SIZ_1MB 0x30000000 /* L2 size 1MB */ +#define L2CR_L2CLK_MASK 0x0e000000 /* L2 clock mask */ +#define L2CR_L2CLK_DISABLED 0x00000000 /* L2 clock disabled */ +#define L2CR_L2CLK_DIV1 0x02000000 /* L2 clock / 1 */ +#define L2CR_L2CLK_DIV1_5 0x04000000 /* L2 clock / 1.5 */ +#define L2CR_L2CLK_DIV2 0x08000000 /* L2 clock / 2 */ +#define L2CR_L2CLK_DIV2_5 0x0a000000 /* L2 clock / 2.5 */ +#define L2CR_L2CLK_DIV3 0x0c000000 /* L2 clock / 3 */ +#define L2CR_L2RAM_MASK 0x01800000 /* L2 RAM type mask */ +#define L2CR_L2RAM_FLOW 0x00000000 /* L2 RAM flow through */ +#define L2CR_L2RAM_PIPE 0x01000000 /* L2 RAM pipelined */ +#define L2CR_L2RAM_PIPE_LW 0x01800000 /* L2 RAM pipelined latewr */ +#define L2CR_L2DO 0x00400000 /* L2 data only */ +#define L2CR_L2I 0x00200000 /* L2 global invalidate */ +#define L2CR_L2CTL 0x00100000 /* L2 RAM control */ +#define L2CR_L2WT 0x00080000 /* L2 write-through */ +#define L2CR_L2TS 0x00040000 /* L2 test support */ +#define L2CR_L2OH_MASK 0x00030000 /* L2 output hold mask */ +#define L2CR_L2OH_0_5 0x00000000 /* L2 output hold 0.5 ns */ +#define L2CR_L2OH_1_0 0x00010000 /* L2 output hold 1.0 ns */ +#define L2CR_L2SL 0x00008000 /* L2 DLL slow */ +#define L2CR_L2DF 0x00004000 /* L2 differential clock */ +#define L2CR_L2BYP 0x00002000 /* L2 DLL bypass */ +#define L2CR_L2IP 0x00000001 /* L2 GI in progress */ #define SPRN_LR 0x008 /* Link Register */ #define SPRN_MMCR0 0x3B8 /* Monitor Mode Control Register 0 */ #define SPRN_MMCR1 0x3BC /* Monitor Mode Control Register 1 */ @@ -235,6 +284,10 @@ #define SPRN_SPRG1 0x111 /* Special Purpose Register General 1 */ #define SPRN_SPRG2 0x112 /* Special Purpose Register General 2 */ #define SPRN_SPRG3 0x113 /* Special Purpose Register General 3 */ +#define SPRN_SPRG4 0x114 /* Special Purpose Register General 4 (4xx) */ +#define SPRN_SPRG5 0x115 /* Special Purpose Register General 5 (4xx) */ +#define SPRN_SPRG6 0x116 /* Special Purpose Register General 6 (4xx) */ +#define SPRN_SPRG7 0x117 /* Special Purpose Register General 7 (4xx) */ #define SPRN_SRR0 0x01A /* Save/Restore Register 0 */ #define SPRN_SRR1 0x01B /* Save/Restore Register 1 */ #define SPRN_SRR2 0x3DE /* Save/Restore Register 2 */ @@ -243,10 +296,6 @@ #define SPRN_TBRU 0x10D /* Time Base Read Upper Register (user, R/O) */ #define SPRN_TBWL 0x11C /* Time Base Lower Register (supervisor, R/W) */ #define SPRN_TBWU 0x11D /* Time Base Upper Register (supervisor, R/W) */ -#define SPRN_TBHI 0x3DC /* Time Base High (4xx) */ -#define SPRN_TBHU 0x3CC /* Time Base High User-mode (4xx) */ -#define SPRN_TBLO 0x3DD /* Time Base Low (4xx) */ -#define SPRN_TBLU 0x3CD /* Time Base Low User-mode (4xx) */ #define SPRN_TCR 0x3DA /* Timer Control Register */ #define TCR_WP(x) (((x)&0x3)<<30) /* WDT Period */ #define WP_2_17 0 /* 2^17 clocks */ @@ -343,10 +392,18 @@ #define SPR1 SPRN_SPRG1 #define SPR2 SPRN_SPRG2 #define SPR3 SPRN_SPRG3 +#define SPR4 SPRN_SPRG4 /* Supervisor Private Registers (4xx) */ +#define SPR5 SPRN_SPRG5 +#define SPR6 SPRN_SPRG6 +#define SPR7 SPRN_SPRG7 #define SPRG0 SPRN_SPRG0 #define SPRG1 SPRN_SPRG1 #define SPRG2 SPRN_SPRG2 #define SPRG3 SPRN_SPRG3 +#define SPRG4 SPRN_SPRG4 +#define SPRG5 SPRN_SPRG5 +#define SPRG6 SPRN_SPRG6 +#define SPRG7 SPRN_SPRG7 #define SRR0 SPRN_SRR0 /* Save and Restore Register 0 */ #define SRR1 SPRN_SRR1 /* Save and Restore Register 1 */ #define TBRL SPRN_TBRL /* Time Base Read Lower Register */ @@ -359,84 +416,6 @@ #define THRM3 SPRN_THRM3 /* Thermal Management Register 3 */ #define XER SPRN_XER - -/* Device Control Registers */ - -#define DCRN_BEAR 0x090 /* Bus Error Address Register */ -#define DCRN_BESR 0x091 /* Bus Error Syndrome Register */ -#define BESR_DSES 0x80000000 /* Data-Side Error Status */ -#define BESR_DMES 0x40000000 /* DMA Error Status */ -#define BESR_RWS 0x20000000 /* Read/Write Status */ -#define BESR_ETMASK 0x1C000000 /* Error Type */ -#define ET_PROT 0 -#define ET_PARITY 1 -#define ET_NCFG 2 -#define ET_BUSERR 4 -#define ET_BUSTO 6 -#define DCRN_DMACC0 0x0C4 /* DMA Chained Count Register 0 */ -#define DCRN_DMACC1 0x0CC /* DMA Chained Count Register 1 */ -#define DCRN_DMACC2 0x0D4 /* DMA Chained Count Register 2 */ -#define DCRN_DMACC3 0x0DC /* DMA Chained Count Register 3 */ -#define DCRN_DMACR0 0x0C0 /* DMA Channel Control Register 0 */ -#define DCRN_DMACR1 0x0C8 /* DMA Channel Control Register 1 */ -#define DCRN_DMACR2 0x0D0 /* DMA Channel Control Register 2 */ -#define DCRN_DMACR3 0x0D8 /* DMA Channel Control Register 3 */ -#define DCRN_DMACT0 0x0C1 /* DMA Count Register 0 */ -#define DCRN_DMACT1 0x0C9 /* DMA Count Register 1 */ -#define DCRN_DMACT2 0x0D1 /* DMA Count Register 2 */ -#define DCRN_DMACT3 0x0D9 /* DMA Count Register 3 */ -#define DCRN_DMADA0 0x0C2 /* DMA Destination Address Register 0 */ -#define DCRN_DMADA1 0x0CA /* DMA Destination Address Register 1 */ -#define DCRN_DMADA2 0x0D2 /* DMA Destination Address Register 2 */ -#define DCRN_DMADA3 0x0DA /* DMA Destination Address Register 3 */ -#define DCRN_DMASA0 0x0C3 /* DMA Source Address Register 0 */ -#define DCRN_DMASA1 0x0CB /* DMA Source Address Register 1 */ -#define DCRN_DMASA2 0x0D3 /* DMA Source Address Register 2 */ -#define DCRN_DMASA3 0x0DB /* DMA Source Address Register 3 */ -#define DCRN_DMASR 0x0E0 /* DMA Status Register */ -#define DCRN_EXIER 0x042 /* External Interrupt Enable Register */ -#define EXIER_CIE 0x80000000 /* Critical Interrupt Enable */ -#define EXIER_SRIE 0x08000000 /* Serial Port Rx Int. Enable */ -#define EXIER_STIE 0x04000000 /* Serial Port Tx Int. Enable */ -#define EXIER_JRIE 0x02000000 /* JTAG Serial Port Rx Int. Enable */ -#define EXIER_JTIE 0x01000000 /* JTAG Serial Port Tx Int. Enable */ -#define EXIER_D0IE 0x00800000 /* DMA Channel 0 Interrupt Enable */ -#define EXIER_D1IE 0x00400000 /* DMA Channel 1 Interrupt Enable */ -#define EXIER_D2IE 0x00200000 /* DMA Channel 2 Interrupt Enable */ -#define EXIER_D3IE 0x00100000 /* DMA Channel 3 Interrupt Enable */ -#define EXIER_E0IE 0x00000010 /* External Interrupt 0 Enable */ -#define EXIER_E1IE 0x00000008 /* External Interrupt 1 Enable */ -#define EXIER_E2IE 0x00000004 /* External Interrupt 2 Enable */ -#define EXIER_E3IE 0x00000002 /* External Interrupt 3 Enable */ -#define EXIER_E4IE 0x00000001 /* External Interrupt 4 Enable */ -#define DCRN_EXISR 0x040 /* External Interrupt Status Register */ -#define DCRN_IOCR 0x0A0 /* Input/Output Configuration Register */ -#define IOCR_E0TE 0x80000000 -#define IOCR_E0LP 0x40000000 -#define IOCR_E1TE 0x20000000 -#define IOCR_E1LP 0x10000000 -#define IOCR_E2TE 0x08000000 -#define IOCR_E2LP 0x04000000 -#define IOCR_E3TE 0x02000000 -#define IOCR_E3LP 0x01000000 -#define IOCR_E4TE 0x00800000 -#define IOCR_E4LP 0x00400000 -#define IOCR_EDT 0x00080000 -#define IOCR_SOR 0x00040000 -#define IOCR_EDO 0x00008000 -#define IOCR_2XC 0x00004000 -#define IOCR_ATC 0x00002000 -#define IOCR_SPD 0x00001000 -#define IOCR_BEM 0x00000800 -#define IOCR_PTD 0x00000400 -#define IOCR_ARE 0x00000080 -#define IOCR_DRC 0x00000020 -#define IOCR_RDM(x) (((x) & 0x3) << 3) -#define IOCR_TCS 0x00000004 -#define IOCR_SCS 0x00000002 -#define IOCR_SPC 0x00000001 - - /* Processor Version Register */ /* Processor Version Register (PVR) field extraction */ @@ -509,15 +488,15 @@ #define _MACH_rpxlite 0x00000040 /* RPCG RPX-Lite 8xx board */ #define _MACH_bseip 0x00000080 /* Bright Star Engineering ip-Engine */ #define _MACH_unused0 0x00000100 /* Now free to be used */ -#define _MACH_unused1 0x00000200 /* Now free to be used */ +#define _MACH_gemini 0x00000200 /* Synergy Microsystems gemini board */ #define _MACH_classic 0x00000400 /* RPCG RPX-Classic 8xx board */ #define _MACH_oak 0x00000800 /* IBM "Oak" 403 eval. board */ #define _MACH_walnut 0x00001000 /* IBM "Walnut" 405GP eval. board */ #define _MACH_8260 0x00002000 /* Generic 8260 */ #define _MACH_tqm860 0x00004000 /* TQM860/L */ #define _MACH_tqm8xxL 0x00008000 /* TQM8xxL */ -#define _MACH_spd8xxL 0x00010000 /* SPD8xx */ -#define _MACH_ibms8 0x00020000 /* IVMS8 */ +#define _MACH_spd8xx 0x00010000 /* SPD8xx */ +#define _MACH_ivms8 0x00020000 /* IVMS8 */ /* see residual.h for these */ #define _PREP_Motorola 0x01 /* motorola prep */ @@ -712,6 +691,9 @@ void _nmask_and_or_msr(unsigned long nmask, unsigned long or_val); #elif defined(CONFIG_APUS) #define _machine _MACH_apus #define have_of 0 +#elif defined(CONFIG_GEMINI) +#define _machine _MACH_gemini +#define have_of 0 #elif defined(CONFIG_8260) #define _machine _MACH_8260 #define have_of 0 diff --git a/include/asm-ppc/prom.h b/include/asm-ppc/prom.h index b80c460b3374..1f0633505a41 100644 --- a/include/asm-ppc/prom.h +++ b/include/asm-ppc/prom.h @@ -35,13 +35,6 @@ struct reg_property { unsigned int size; }; -struct translation_property { - unsigned int virt; - unsigned int size; - unsigned int phys; - unsigned int flags; -}; - struct property { char *name; int length; @@ -64,6 +57,10 @@ struct device_node { struct device_node *sibling; struct device_node *next; /* next device of same type */ struct device_node *allnext; /* next in list of all nodes */ +#if 0 /* Don't change this structure for now or you'll break BootX ! */ + int n_addr_cells; + int n_size_cells; +#endif }; struct prom_args; @@ -88,6 +85,8 @@ extern unsigned char *get_property(struct device_node *node, const char *name, int *lenp); extern void prom_add_property(struct device_node* np, struct property* prop); extern void prom_get_irq_senses(unsigned char *, int, int); +extern int prom_n_addr_cells(struct device_node* np); +extern int prom_n_size_cells(struct device_node* np); extern void print_properties(struct device_node *node); extern int call_rtas(const char *service, int nargs, int nret, diff --git a/include/asm-ppc/rpxclassic.h b/include/asm-ppc/rpxclassic.h index 0583b60fb85e..a1a6b614f343 100644 --- a/include/asm-ppc/rpxclassic.h +++ b/include/asm-ppc/rpxclassic.h @@ -11,6 +11,7 @@ #include +#ifndef __ASSEMBLY__ /* A Board Information structure that is given to a program when * prom starts it up. */ @@ -60,20 +61,38 @@ extern bd_t m8xx_board_info; #define BCSR0_PCMCIA3VOLT ((uint)0x000a0000) /* CLLF */ #define BCSR0_PCMCIA5VOLT ((uint)0x00060000) /* CLLF */ +#define BCSR1_IPB5SEL ((uint)0x00100000) +#define BCSR1_PCVCTL4 ((uint)0x00080000) +#define BCSR1_PCVCTL5 ((uint)0x00040000) +#define BCSR1_PCVCTL6 ((uint)0x00020000) +#define BCSR1_PCVCTL7 ((uint)0x00010000) + #define BCSR2_EN232XCVR ((uint)0x00008000) #define BCSR2_QSPACESEL ((uint)0x00004000) #define BCSR2_FETHLEDMODE ((uint)0x00000800) /* CLLF */ -#if defined(CONFIG_RPXLCD) || defined(CONFIG_HTDMSOUND) -/* HIOX Expansion card. -*/ -#include +#if defined(CONFIG_HTDMSOUND) +#include +#endif + +/* define IO_BASE for pcmcia, CLLF only */ +#if !defined(CONFIG_PCI) +#define _IO_BASE 0x80000000 +#define _IO_BASE_SIZE 0x1000 + +/* for pcmcia sandisk */ +#ifdef CONFIG_IDE +#define MAX_HWIFS 1 +#define ide_request_irq(irq,hand,flg,dev,id) request_8xxirq((irq),(hand),(flg),(dev),(id)) +#endif #endif /* Interrupt level assignments. */ #define FEC_INTERRUPT SIU_LEVEL1 /* FEC interrupt */ +#endif /* !__ASSEMBLY__ */ + /* We don't use the 8259. */ #define NR_8259_INTS 0 diff --git a/include/asm-ppc/rpxhiox.h b/include/asm-ppc/rpxhiox.h new file mode 100644 index 000000000000..5d0bef1ca8f5 --- /dev/null +++ b/include/asm-ppc/rpxhiox.h @@ -0,0 +1,42 @@ + +/* + * The Embedded Planet HIOX expansion card definitions. + * There were a few different versions of these cards, but only + * the one that escaped real production is defined here. + * + * Copyright (c) 2000 Dan Malek (dmalek@jlc.net) + */ +#ifndef __MACH_RPX_HIOX_DEFS +#define __MACH_RPX_HIOX_DEFS + +#define HIOX_CSR_ADDR ((uint)0xfac00000) +#define HIOX_CSR_SIZE ((uint)(4 * 1024)) +#define HIOX_CSR0_ADDR HIOX_CSR_ADDR +#define HIOX_CSR4_ADDR ((uint)0xfac00004) + +#define HIOX_CSR0_DEFAULT ((uint)0x380f3c00) +#define HIOX_CSR0_ENSCC2 ((uint)0x80000000) +#define HIOX_CSR0_ENSMC2 ((uint)0x04000000) +#define HIOX_CSR0_ENVDOCLK ((uint)0x02000000) +#define HIOX_CSR0_VDORST_HL ((uint)0x01000000) +#define HIOX_CSR0_RS232SEL ((uint)0x0000c000) +#define HIOX_CSR0_SCC3SEL ((uint)0x0000c000) +#define HIOX_CSR0_SMC1SEL ((uint)0x00008000) +#define HIOX_CSR0_SCC1SEL ((uint)0x00004000) +#define HIOX_CSR0_ENTOUCH ((uint)0x00000080) +#define HIOX_CSR0_PDOWN100 ((uint)0x00000060) +#define HIOX_CSR0_PDOWN10 ((uint)0x00000040) +#define HIOX_CSR0_PDOWN1 ((uint)0x00000020) +#define HIOX_CSR0_TSELSPI ((uint)0x00000010) +#define HIOX_CSR0_TIRQSTAT ((uint)0x00000008) +#define HIOX_CSR4_DEFAULT ((uint)0x00000000) +#define HIOX_CSR4_ENTIRQ2 ((uint)0x20000000) +#define HIOX_CSR4_ENTIRQ3 ((uint)0x10000000) +#define HIOX_CSR4_ENAUDIO ((uint)0x00000080) +#define HIOX_CSR4_RSTAUDIO ((uint)0x00000040) /* 0 == reset */ +#define HIOX_CSR4_AUDCLKHI ((uint)0x00000020) +#define HIOX_CSR4_AUDSPISEL ((uint)0x00000010) +#define HIOX_CSR4_AUDIRQSTAT ((uint)0x00000008) +#define HIOX_CSR4_AUDCLKSEL ((uint)0x00000007) + +#endif diff --git a/include/asm-ppc/rpxlite.h b/include/asm-ppc/rpxlite.h index 1d447082b6a7..2dfec0c8142a 100644 --- a/include/asm-ppc/rpxlite.h +++ b/include/asm-ppc/rpxlite.h @@ -9,6 +9,7 @@ #ifndef __MACH_RPX_DEFS #define __MACH_RPX_DEFS +#ifndef __ASSEMBLY__ /* A Board Information structure that is given to a program when * prom starts it up. */ @@ -31,8 +32,6 @@ extern bd_t m8xx_board_info; #define RPX_CSR_SIZE ((uint)(4 * 1024)) #define IMAP_ADDR ((uint)0xfa200000) #define IMAP_SIZE ((uint)(64 * 1024)) -#define HIOX_CSR_ADDR ((uint)0xfac00000) -#define HIOX_CSR_SIZE ((uint)(4 * 1024)) #define PCMCIA_MEM_ADDR ((uint)0x04000000) #define PCMCIA_MEM_SIZE ((uint)(64 * 1024)) #define PCMCIA_IO_ADDR ((uint)0x04400000) @@ -52,10 +51,25 @@ extern bd_t m8xx_board_info; #define BCSR0_PCMCIA3VOLT ((uint)0x000a0000) #define BCSR0_PCMCIA5VOLT ((uint)0x00060000) -/* HIO Expansion card. -*/ -#define HIOX_CSR_ENAUDIO ((uint)0x00000200) -#define HIOX_CSR_RSTAUDIO ((uint)0x00000100) /* 0 == reset */ +#define BCSR1_IPB5SEL ((uint)0x00100000) +#define BCSR1_PCVCTL4 ((uint)0x00080000) +#define BCSR1_PCVCTL5 ((uint)0x00040000) +#define BCSR1_PCVCTL6 ((uint)0x00020000) +#define BCSR1_PCVCTL7 ((uint)0x00010000) + +#if defined(CONFIG_HTDMSOUND) +#include +#endif +#endif /* !__ASSEMBLY__ */ + +/* define IO_BASE for pcmcia */ +#define _IO_BASE 0x80000000 +#define _IO_BASE_SIZE 0x1000 + +#ifdef CONFIG_IDE +#define MAX_HWIFS 1 +#define ide_request_irq(irq,hand,flg,dev,id) request_8xxirq((irq),(hand),(flg),(dev),(id)) +#endif /* We don't use the 8259. */ diff --git a/include/asm-ppc/rwsem.h b/include/asm-ppc/rwsem.h new file mode 100644 index 000000000000..f8f064bfb7a7 --- /dev/null +++ b/include/asm-ppc/rwsem.h @@ -0,0 +1,134 @@ +/* + * include/asm-ppc/rwsem.h: R/W semaphores for PPC using the stuff + * in lib/rwsem.c. Adapted largely from include/asm-i386/rwsem.h + * by Paul Mackerras . + */ + +#ifndef _PPC_RWSEM_H +#define _PPC_RWSEM_H + +#ifdef __KERNEL__ +#include +#include +#include +#include + +/* + * the semaphore definition + */ +struct rw_semaphore { + /* XXX this should be able to be an atomic_t -- paulus */ + signed long count; +#define RWSEM_UNLOCKED_VALUE 0x00000000 +#define RWSEM_ACTIVE_BIAS 0x00000001 +#define RWSEM_ACTIVE_MASK 0x0000ffff +#define RWSEM_WAITING_BIAS (-0x00010000) +#define RWSEM_ACTIVE_READ_BIAS RWSEM_ACTIVE_BIAS +#define RWSEM_ACTIVE_WRITE_BIAS (RWSEM_WAITING_BIAS + RWSEM_ACTIVE_BIAS) + spinlock_t wait_lock; + struct list_head wait_list; +#if RWSEM_DEBUG + int debug; +#endif +}; + +/* + * initialisation + */ +#if RWSEM_DEBUG +#define __RWSEM_DEBUG_INIT , 0 +#else +#define __RWSEM_DEBUG_INIT /* */ +#endif + +#define __RWSEM_INITIALIZER(name) \ + { RWSEM_UNLOCKED_VALUE, SPIN_LOCK_UNLOCKED, \ + LIST_HEAD_INIT((name).wait_list) \ + __RWSEM_DEBUG_INIT } + +#define DECLARE_RWSEM(name) \ + struct rw_semaphore name = __RWSEM_INITIALIZER(name) + +extern struct rw_semaphore *rwsem_down_read_failed(struct rw_semaphore *sem); +extern struct rw_semaphore *rwsem_down_write_failed(struct rw_semaphore *sem); +extern struct rw_semaphore *rwsem_wake(struct rw_semaphore *sem); + +static inline void init_rwsem(struct rw_semaphore *sem) +{ + sem->count = RWSEM_UNLOCKED_VALUE; + spin_lock_init(&sem->wait_lock); + INIT_LIST_HEAD(&sem->wait_list); +#if RWSEM_DEBUG + sem->debug = 0; +#endif +} + +/* + * lock for reading + */ +static inline void __down_read(struct rw_semaphore *sem) +{ + if (atomic_inc_return((atomic_t *)(&sem->count)) >= 0) + smp_wmb(); + else + rwsem_down_read_failed(sem); +} + +/* + * lock for writing + */ +static inline void __down_write(struct rw_semaphore *sem) +{ + int tmp; + + tmp = atomic_add_return(RWSEM_ACTIVE_WRITE_BIAS, + (atomic_t *)(&sem->count)); + if (tmp == RWSEM_ACTIVE_WRITE_BIAS) + smp_wmb(); + else + rwsem_down_write_failed(sem); +} + +/* + * unlock after reading + */ +static inline void __up_read(struct rw_semaphore *sem) +{ + int tmp; + + smp_wmb(); + tmp = atomic_dec_return((atomic_t *)(&sem->count)); + if (tmp < -1 && (tmp & RWSEM_ACTIVE_MASK) == 0) + rwsem_wake(sem); +} + +/* + * unlock after writing + */ +static inline void __up_write(struct rw_semaphore *sem) +{ + smp_wmb(); + if (atomic_sub_return(RWSEM_ACTIVE_WRITE_BIAS, + (atomic_t *)(&sem->count)) < 0) + rwsem_wake(sem); +} + +/* + * implement atomic add functionality + */ +static inline void rwsem_atomic_add(int delta, struct rw_semaphore *sem) +{ + atomic_add(delta, (atomic_t *)(&sem->count)); +} + +/* + * implement exchange and add functionality + */ +static inline int rwsem_atomic_update(int delta, struct rw_semaphore *sem) +{ + smp_mb(); + return atomic_add_return(delta, (atomic_t *)(&sem->count)); +} + +#endif /* __KERNEL__ */ +#endif /* _PPC_RWSEM_XADD_H */ diff --git a/include/asm-ppc/semaphore-helper.h b/include/asm-ppc/semaphore-helper.h deleted file mode 100644 index 14f2c0e2ede0..000000000000 --- a/include/asm-ppc/semaphore-helper.h +++ /dev/null @@ -1,109 +0,0 @@ -#ifdef __KERNEL__ -#ifndef _PPC_SEMAPHORE_HELPER_H -#define _PPC_SEMAPHORE_HELPER_H - -/* - * SMP- and interrupt-safe semaphores.. - * - * (C) Copyright 1996 Linus Torvalds - * Adapted for PowerPC by Gary Thomas and Paul Mackerras - */ - -#include - -/* - * These two (wake_one_more and waking_non_zero) _must_ execute - * atomically wrt each other. - * - * This is trivially done with load with reservation and - * store conditional on the ppc. - */ - -static inline void wake_one_more(struct semaphore * sem) -{ - atomic_inc(&sem->waking); -} - -static inline int waking_non_zero(struct semaphore *sem) -{ - int ret, tmp; - - /* Atomic decrement sem->waking iff it is > 0 */ - __asm__ __volatile__( - "1: lwarx %1,0,%2\n" /* tmp = sem->waking */ - " cmpwi 0,%1,0\n" /* test tmp */ - " addic %1,%1,-1\n" /* --tmp */ - " ble- 2f\n" /* exit if tmp was <= 0 */ - " stwcx. %1,0,%2\n" /* update sem->waking */ - " bne- 1b\n" /* try again if update failed*/ - " li %0,1\n" /* ret = 1 */ - "2:" - : "=r" (ret), "=&r" (tmp) - : "r" (&sem->waking), "0" (0) - : "cr0", "memory"); - - return ret; -} -/* - * waking_non_zero_interruptible: - * 1 got the lock - * 0 go to sleep - * -EINTR interrupted - */ -static inline int waking_non_zero_interruptible(struct semaphore *sem, - struct task_struct *tsk) -{ - int ret, tmp; - - /* Atomic decrement sem->waking iff it is > 0 */ - __asm__ __volatile__( - "1: lwarx %1,0,%2\n" /* tmp = sem->waking */ - " cmpwi 0,%1,0\n" /* test tmp */ - " addic %1,%1,-1\n" /* --tmp */ - " ble- 2f\n" /* exit if tmp was <= 0 */ - " stwcx. %1,0,%2\n" /* update sem->waking */ - " bne- 1b\n" /* try again if update failed*/ - " li %0,1\n" /* ret = 1 */ - "2:" - : "=r" (ret), "=&r" (tmp) - : "r" (&sem->waking), "0" (0) - : "cr0", "memory"); - - if (ret == 0 && signal_pending(tsk)) { - atomic_inc(&sem->count); - ret = -EINTR; - } - return ret; -} - -/* - * waking_non_zero_trylock: - * 1 failed to lock - * 0 got the lock - */ -static inline int waking_non_zero_trylock(struct semaphore *sem) -{ - int ret, tmp; - - /* Atomic decrement sem->waking iff it is > 0 */ - __asm__ __volatile__( - "1: lwarx %1,0,%2\n" /* tmp = sem->waking */ - " cmpwi 0,%1,0\n" /* test tmp */ - " addic %1,%1,-1\n" /* --tmp */ - " ble- 2f\n" /* exit if tmp was <= 0 */ - " stwcx. %1,0,%2\n" /* update sem->waking */ - " bne- 1b\n" /* try again if update failed*/ - " li %0,0\n" /* ret = 0 */ - "2:" - : "=r" (ret), "=&r" (tmp) - : "r" (&sem->waking), "0" (1) - : "cr0", "memory"); - - if (ret) - atomic_inc(&sem->count); - - return ret; -} - -#endif /* _PPC_SEMAPHORE_HELPER_H */ -#endif /* __KERNEL__ */ diff --git a/include/asm-ppc/semaphore.h b/include/asm-ppc/semaphore.h index 4c196ea4c7fa..92e629eaf99c 100644 --- a/include/asm-ppc/semaphore.h +++ b/include/asm-ppc/semaphore.h @@ -7,6 +7,11 @@ * * Stole some rw spinlock-based semaphore stuff from asm-alpha/semaphore.h * -- Ani Joshi (ajoshi@unixbox.com) + * + * Remove spinlock-based RW semaphores; RW semaphore definitions are + * now in rwsem.h and we use the the generic lib/rwsem.c implementation. + * Rework semaphores to use atomic_dec_if_positive. + * -- Paul Mackerras (paulus@samba.org) */ #ifdef __KERNEL__ @@ -17,8 +22,12 @@ #include struct semaphore { + /* + * Note that any negative value of count is equivalent to 0, + * but additionally indicates that some process(es) might be + * sleeping on `wait'. + */ atomic_t count; - atomic_t waking; wait_queue_head_t wait; #if WAITQUEUE_DEBUG long __magic; @@ -32,23 +41,23 @@ struct semaphore { # define __SEM_DEBUG_INIT(name) #endif -#define __SEMAPHORE_INITIALIZER(name,count) \ -{ ATOMIC_INIT(count), ATOMIC_INIT(0), __WAIT_QUEUE_HEAD_INITIALIZER((name).wait) \ - __SEM_DEBUG_INIT(name) } +#define __SEMAPHORE_INITIALIZER(name, count) \ + { ATOMIC_INIT(count), \ + __WAIT_QUEUE_HEAD_INITIALIZER((name).wait) \ + __SEM_DEBUG_INIT(name) } #define __MUTEX_INITIALIZER(name) \ - __SEMAPHORE_INITIALIZER(name,1) + __SEMAPHORE_INITIALIZER(name, 1) -#define __DECLARE_SEMAPHORE_GENERIC(name,count) \ +#define __DECLARE_SEMAPHORE_GENERIC(name, count) \ struct semaphore name = __SEMAPHORE_INITIALIZER(name,count) -#define DECLARE_MUTEX(name) __DECLARE_SEMAPHORE_GENERIC(name,1) -#define DECLARE_MUTEX_LOCKED(name) __DECLARE_SEMAPHORE_GENERIC(name,0) +#define DECLARE_MUTEX(name) __DECLARE_SEMAPHORE_GENERIC(name, 1) +#define DECLARE_MUTEX_LOCKED(name) __DECLARE_SEMAPHORE_GENERIC(name, 0) -extern inline void sema_init (struct semaphore *sem, int val) +static inline void sema_init (struct semaphore *sem, int val) { atomic_set(&sem->count, val); - atomic_set(&sem->waking, 0); init_waitqueue_head(&sem->wait); #if WAITQUEUE_DEBUG sem->__magic = (long)&sem->__magic; @@ -67,46 +76,59 @@ static inline void init_MUTEX_LOCKED (struct semaphore *sem) extern void __down(struct semaphore * sem); extern int __down_interruptible(struct semaphore * sem); -extern int __down_trylock(struct semaphore * sem); extern void __up(struct semaphore * sem); extern inline void down(struct semaphore * sem) { - if (atomic_dec_return(&sem->count) >= 0) - wmb(); - else +#if WAITQUEUE_DEBUG + CHECK_MAGIC(sem->__magic); +#endif + + /* + * Try to get the semaphore, take the slow path if we fail. + */ + if (atomic_dec_return(&sem->count) < 0) __down(sem); + smp_wmb(); } extern inline int down_interruptible(struct semaphore * sem) { int ret = 0; - if (atomic_dec_return(&sem->count) >= 0) - wmb(); - else +#if WAITQUEUE_DEBUG + CHECK_MAGIC(sem->__magic); +#endif + + if (atomic_dec_return(&sem->count) < 0) ret = __down_interruptible(sem); + smp_wmb(); return ret; } extern inline int down_trylock(struct semaphore * sem) { - int ret = 0; + int ret; - if (atomic_dec_return(&sem->count) >= 0) - wmb(); - else - ret = __down_trylock(sem); +#if WAITQUEUE_DEBUG + CHECK_MAGIC(sem->__magic); +#endif + + ret = atomic_dec_if_positive(&sem->count) < 0; + smp_wmb(); return ret; } extern inline void up(struct semaphore * sem) { - mb(); +#if WAITQUEUE_DEBUG + CHECK_MAGIC(sem->__magic); +#endif + + smp_wmb(); if (atomic_inc_return(&sem->count) <= 0) __up(sem); -} - +} #endif /* __KERNEL__ */ diff --git a/include/asm-ppc/serial.h b/include/asm-ppc/serial.h index 721476591e5d..f00adba97a30 100644 --- a/include/asm-ppc/serial.h +++ b/include/asm-ppc/serial.h @@ -5,6 +5,12 @@ #ifdef __KERNEL__ #include +#ifdef CONFIG_GEMINI +#include +#elif defined(CONFIG_4xx) +#include +#else + /* * This assumes you have a 1.8432 MHz clock for your UART. * @@ -123,4 +129,5 @@ HUB6_SERIAL_PORT_DFNS \ MCA_SERIAL_PORT_DFNS +#endif /* !CONFIG_GEMINI and others */ #endif /* __KERNEL__ */ diff --git a/include/asm-ppc/smp.h b/include/asm-ppc/smp.h index 6dfc778b94bc..4af7de98df60 100644 --- a/include/asm-ppc/smp.h +++ b/include/asm-ppc/smp.h @@ -1,8 +1,11 @@ /* smp.h: PPC specific SMP stuff. * - * Taken from asm-sparc/smp.h + * Original was a copy of sparc smp.h. Now heavily modified + * for PPC. + * + * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu) + * Copyright (C) 1996-2001 Cort Dougan */ - #ifdef __KERNEL__ #ifndef _PPC_SMP_H #define _PPC_SMP_H @@ -21,9 +24,11 @@ struct cpuinfo_PPC { unsigned long *pte_cache; unsigned long pgtable_cache_sz; }; -extern struct cpuinfo_PPC cpu_data[NR_CPUS]; +extern struct cpuinfo_PPC cpu_data[NR_CPUS]; +extern unsigned long cpu_online_map; extern unsigned long smp_proc_in_lock[NR_CPUS]; +extern volatile unsigned long cpu_callin_map[NR_CPUS]; extern void smp_store_cpu_info(int id); extern void smp_send_tlb_invalidate(int); @@ -37,7 +42,6 @@ extern void smp_message_recv(int, struct pt_regs *); /* 1 to 1 mapping on PPC -- Cort */ #define cpu_logical_map(cpu) (cpu) #define cpu_number_map(x) (x) -extern volatile unsigned long cpu_callin_map[NR_CPUS]; #define smp_processor_id() (current->processor) diff --git a/include/asm-ppc/system.h b/include/asm-ppc/system.h index 31354be29782..96b10ff83153 100644 --- a/include/asm-ppc/system.h +++ b/include/asm-ppc/system.h @@ -3,7 +3,6 @@ * * Copyright (C) 1999 Cort Dougan */ -#ifdef __KERNEL__ #ifndef __PPC_SYSTEM_H #define __PPC_SYSTEM_H @@ -47,6 +46,7 @@ #define smp_wmb() __asm__ __volatile__("": : :"memory") #endif /* CONFIG_SMP */ +#ifdef __KERNEL__ extern void xmon_irq(int, void *, struct pt_regs *); extern void xmon(struct pt_regs *excp); extern void print_backtrace(unsigned long *); @@ -115,6 +115,8 @@ extern void __global_restore_flags(unsigned long); #define local_irq_save(flags) __save_and_cli(flags) #define local_irq_restore(flags) __restore_flags(flags) +#endif /* __KERNEL__ */ + #define xchg(ptr,x) ((__typeof__(*(ptr)))__xchg((unsigned long)(x),(ptr),sizeof(*(ptr)))) static __inline__ unsigned long @@ -122,9 +124,9 @@ xchg_u32(volatile void *p, unsigned long val) { unsigned long prev; - __asm__ __volatile__ (" -1: lwarx %0,0,%2 - stwcx. %3,0,%2 + __asm__ __volatile__ ("\n\ +1: lwarx %0,0,%2 \n\ + stwcx. %3,0,%2 \n\ bne- 1b" : "=&r" (prev), "=m" (*(volatile unsigned long *)p) : "r" (p), "r" (val), "m" (*(volatile unsigned long *)p) @@ -171,11 +173,11 @@ __cmpxchg_u32(volatile int *p, int old, int new) { int prev; - __asm__ __volatile__ (" -1: lwarx %0,0,%2 - cmpw 0,%0,%3 - bne 2f - stwcx. %4,0,%2 + __asm__ __volatile__ ("\n\ +1: lwarx %0,0,%2 \n\ + cmpw 0,%0,%3 \n\ + bne 2f \n\ + stwcx. %4,0,%2 \n\ bne- 1b\n" #ifdef CONFIG_SMP " sync\n" @@ -216,4 +218,3 @@ __cmpxchg(volatile void *ptr, unsigned long old, unsigned long new, int size) }) #endif /* __PPC_SYSTEM_H */ -#endif /* __KERNEL__ */ diff --git a/include/asm-ppc/time.h b/include/asm-ppc/time.h index 114b97305a9e..e7bce727e8c6 100644 --- a/include/asm-ppc/time.h +++ b/include/asm-ppc/time.h @@ -9,6 +9,7 @@ #ifdef __KERNEL__ #include #include +#include #include @@ -23,7 +24,12 @@ extern time_t last_rtc_update; int via_calibrate_decr(void); -/* Accessor functions for the decrementer register. */ +/* Accessor functions for the decrementer register. + * The 4xx doesn't even have a decrementer. I tried to use the + * generic timer interrupt code, which seems OK, with the 4xx PIT + * in auto-reload mode. The problem is PIT stops counting when it + * hits zero. If it would wrap, we could use it just like a decrementer. + */ static __inline__ unsigned int get_dec(void) { #if defined(CONFIG_4xx) @@ -36,14 +42,12 @@ static __inline__ unsigned int get_dec(void) static __inline__ void set_dec(unsigned int val) { #if defined(CONFIG_4xx) - mtspr(SPRN_PIT, val); -#else -#ifdef CONFIG_8xx_CPU6 + return; /* Have to let it auto-reload */ +#elif defined(CONFIG_8xx_CPU6) set_dec_cpu6(val); #else mtspr(SPRN_DEC, val); #endif -#endif } /* Accessor functions for the timebase (RTC on 601) registers. */ @@ -62,6 +66,12 @@ extern __inline__ unsigned long get_tbl(void) { return tbl; } +extern __inline__ unsigned long get_tbu(void) { + unsigned long tbl; + asm volatile("mftbu %0" : "=r" (tbl)); + return tbl; +} + extern __inline__ unsigned long get_rtcl(void) { unsigned long rtcl; asm volatile("mfrtcl %0" : "=r" (rtcl)); diff --git a/include/asm-ppc/uninorth.h b/include/asm-ppc/uninorth.h index b21cc8931bdd..ce8c280f7ccc 100644 --- a/include/asm-ppc/uninorth.h +++ b/include/asm-ppc/uninorth.h @@ -42,13 +42,13 @@ /* Version of the UniNorth chip */ #define UNI_N_VERSION 0x0000 /* Known versions: 3,7 and 8 */ -/* This register is used to enable/disable various parts */ +/* This register is used to enable/disable various clocks */ #define UNI_N_CLOCK_CNTL 0x0020 -#define UNI_N_CLOCK_CNTL_PCI 0x00000001 /* guess ? */ -#define UNI_N_CLOCK_CNTL_GMAC 0x00000002 -#define UNI_N_CLOCK_CNTL_FW 0x00000004 /* guess ? */ +#define UNI_N_CLOCK_CNTL_PCI 0x00000001 /* PCI2 clock control */ +#define UNI_N_CLOCK_CNTL_GMAC 0x00000002 /* GMAC clock control */ +#define UNI_N_CLOCK_CNTL_FW 0x00000004 /* FireWire clock control */ -/* Power Management control ? (from Darwin) */ +/* Power Management control */ #define UNI_N_POWER_MGT 0x0030 #define UNI_N_POWER_MGT_NORMAL 0x00 #define UNI_N_POWER_MGT_IDLE2 0x01 @@ -80,4 +80,6 @@ */ #define UNI_N_HWINIT_STATE_CPU1_FLAG 0x10000000 +/* Uninorth 1.5 rev. has additional perf. monitor registers at 0xf00-0xf50 */ + #endif /* __KERNEL__ */ diff --git a/include/asm-ppc/walnut.h b/include/asm-ppc/walnut.h index 45a92bbb3522..334803d7671c 100644 --- a/include/asm-ppc/walnut.h +++ b/include/asm-ppc/walnut.h @@ -2,12 +2,21 @@ * * Copyright (c) 1999 Grant Erickson * - * Module name: walnut.h + * Copyright 2000 MontaVista Software Inc. + * PPC405 modifications + * Author: MontaVista Software, Inc. + * frank_rowand@mvista.com or source@mvista.com + * debbie_chu@mvista.com + * + * Module name: ppc405.h * * Description: - * Macros, definitions, and data structures specific to the IBM PowerPC - * 405GP "Walnut" evaluation board. Anything specific to the processor - * itself is defined elsewhere. + * Macros, definitions, and data structures specific to the IBM PowerPC + * based boards. + * + * This includes: + * + * 405GP "Walnut" evaluation board * */ @@ -19,12 +28,37 @@ #ifdef __cplusplus extern "C" { #endif +/* + * Data structure defining board information maintained by the boot + * ROM on IBM's "Walnut" evaluation board. An effort has been made to + * keep the field names consistent with the 8xx 'bd_t' board info + * structures. + */ +typedef struct board_info { + unsigned char bi_s_version[4]; /* Version of this structure */ + unsigned char bi_r_version[30]; /* Version of the IBM ROM */ + unsigned int bi_memsize; /* DRAM installed, in bytes */ + unsigned char bi_enetaddr[6]; /* Local Ethernet MAC address */ + unsigned char bi_pci_enetaddr[6]; /* PCI Ethernet MAC address */ + unsigned int bi_procfreq; /* Processor speed, in Hz */ + unsigned int bi_plb_busfreq; /* PLB Bus speed, in Hz */ + unsigned int bi_pci_busfreq; /* PCI Bus speed, in Hz */ +} bd_t; +/* Memory map for the IBM "Walnut" 405GP evaluation board. + * Generic 4xx plus RTC. + */ +#define WALNUT_RTC_ADDR ((uint)0xf0001000) +#define WALNUT_RTC_SIZE ((uint)4*1024) #ifdef __cplusplus } #endif +/* Generic 4xx type +*/ +#define _MACH_4xx (_MACH_walnut) + #endif /* __WALNUT_H__ */ #endif /* __KERNEL__ */ diff --git a/include/asm-sh/pci.h b/include/asm-sh/pci.h index 7ef16e6b2213..9f5b9cb0b7ef 100644 --- a/include/asm-sh/pci.h +++ b/include/asm-sh/pci.h @@ -160,7 +160,8 @@ extern inline int pci_dma_supported(struct pci_dev *hwdev, dma_addr_t mask) return 1; } - +/* Return the index of the PCI controller for device PDEV. */ +#define pci_controller_num(PDEV) (0) /* These macros should be used after a pci_map_sg call has been done * to get bus addresses of each of the SG entries and their lengths. diff --git a/include/asm-sparc/pci.h b/include/asm-sparc/pci.h index bbc55d0130f2..cafb22446139 100644 --- a/include/asm-sparc/pci.h +++ b/include/asm-sparc/pci.h @@ -113,6 +113,9 @@ extern inline int pci_dma_supported(struct pci_dev *hwdev, dma_addr_t mask) return 1; } +/* Return the index of the PCI controller for device PDEV. */ +#define pci_controller_num(PDEV) (0) + #endif /* __KERNEL__ */ #endif /* __SPARC_PCI_H */ diff --git a/include/asm-sparc64/floppy.h b/include/asm-sparc64/floppy.h index 83d1b7fa0037..924e0c0ba301 100644 --- a/include/asm-sparc64/floppy.h +++ b/include/asm-sparc64/floppy.h @@ -1,4 +1,4 @@ -/* $Id: floppy.h,v 1.29 2001/03/24 00:07:23 davem Exp $ +/* $Id: floppy.h,v 1.30 2001/05/11 07:05:38 davem Exp $ * asm-sparc64/floppy.h: Sparc specific parts of the Floppy driver. * * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu) @@ -173,11 +173,6 @@ char *pdma_base = 0; unsigned long pdma_areasize; /* Common routines to all controller types on the Sparc. */ -static __inline__ void virtual_dma_init(void) -{ - /* nothing... */ -} - static void sun_fd_disable_dma(void) { doing_pdma = 0; @@ -231,7 +226,7 @@ static int sun_fd_request_irq(void) once = 1; error = request_fast_irq(FLOPPY_IRQ, floppy_hardint, - SA_INTERRUPT, "floppy", NULL); + SA_INTERRUPT, "floppy", NULL); return ((error == 0) ? 0 : -1); } @@ -267,6 +262,7 @@ static int sun_fd_eject(int drive) #ifdef CONFIG_PCI #include +#include #include static struct linux_ebus_dma *sun_pci_fd_ebus_dma; @@ -583,6 +579,83 @@ static int __init ebus_fdthree_p(struct linux_ebus_device *edev) } #endif +#ifdef CONFIG_PCI +#undef ISA_FLOPPY_WORKS + +#ifdef ISA_FLOPPY_WORKS +static unsigned long __init isa_floppy_init(void) +{ + struct isa_bridge *isa_br; + struct isa_device *isa_dev = NULL; + + for_each_isa(isa_br) { + for_each_isadev(isa_dev, isa_br) { + if (!strcmp(isa_dev->prom_name, "dma")) { + struct isa_device *child = isa_dev->child; + + while (child) { + if (!strcmp(child->prom_name, "floppy")) { + isa_dev = child; + goto isa_done; + } + child = child->next; + } + } + } + } +isa_done: + if (!isa_dev) + return 0; + + /* We could use DMA on devices behind the ISA bridge, but... + * + * There is a slight problem. Normally on x86 kit the x86 processor + * delays I/O port instructions when the ISA bus "dma in progress" + * signal is active. Well, sparc64 systems do not monitor this + * signal thus we would need to block all I/O port accesses in software + * when a dma transfer is active for some device. + */ + + sun_fdc = (struct sun_flpy_controller *)isa_dev->resource.start; + FLOPPY_IRQ = isa_dev->irq; + + sun_fdops.fd_inb = sun_pci_fd_inb; + sun_fdops.fd_outb = sun_pci_fd_outb; + + can_use_virtual_dma = use_virtual_dma = 1; + sun_fdops.fd_enable_dma = sun_fd_enable_dma; + sun_fdops.fd_disable_dma = sun_fd_disable_dma; + sun_fdops.fd_set_dma_mode = sun_fd_set_dma_mode; + sun_fdops.fd_set_dma_addr = sun_fd_set_dma_addr; + sun_fdops.fd_set_dma_count = sun_fd_set_dma_count; + sun_fdops.get_dma_residue = sun_get_dma_residue; + + sun_fdops.fd_enable_irq = sun_fd_enable_irq; + sun_fdops.fd_disable_irq = sun_fd_disable_irq; + sun_fdops.fd_request_irq = sun_fd_request_irq; + sun_fdops.fd_free_irq = sun_fd_free_irq; + + /* Floppy eject is manual. Actually, could determine this + * via presence of 'manual' property in OBP node. + */ + sun_fdops.fd_eject = sun_pci_fd_eject; + + fdc_status = (unsigned long) &sun_fdc->status_82077; + FLOPPY_MOTOR_MASK = 0xf0; + + allowed_drive_mask = 0; + sun_floppy_types[0] = 0; + sun_floppy_types[1] = 4; + + sun_pci_broken_drive = 1; + sun_fdops.fd_outb = sun_pci_fd_broken_outb; + + return sun_floppy_types[0]; +} +#endif /* ISA_FLOPPY_WORKS */ + +#endif + static unsigned long __init sun_floppy_init(void) { char state[128]; @@ -615,8 +688,13 @@ static unsigned long __init sun_floppy_init(void) } } ebus_done: - if (!edev) + if (!edev) { +#ifdef ISA_FLOPPY_WORKS + return isa_floppy_init(); +#else return 0; +#endif + } prom_getproperty(edev->prom_node, "status", state, sizeof(state)); diff --git a/include/asm-sparc64/isa.h b/include/asm-sparc64/isa.h new file mode 100644 index 000000000000..51b9aef899ff --- /dev/null +++ b/include/asm-sparc64/isa.h @@ -0,0 +1,47 @@ +/* $Id: isa.h,v 1.1 2001/05/11 04:31:55 davem Exp $ + * isa.h: Sparc64 layer for PCI to ISA bridge devices. + * + * Copyright (C) 2001 David S. Miller (davem@redhat.com) + */ + +#ifndef __SPARC64_ISA_H +#define __SPARC64_ISA_H + +#include +#include + +struct isa_device { + struct isa_device *next; + struct isa_device *child; + struct isa_bridge *bus; + int prom_node; + char prom_name[64]; + char compatible[64]; + struct resource resource; + unsigned int irq; +}; + +struct isa_bridge { + struct isa_bridge *next; + struct isa_device *devices; + struct pci_pbm_info *parent; + struct pci_dev *self; + int index; + int prom_node; + char prom_name[64]; +#define linux_prom_isa_ranges linux_prom_ebus_ranges + struct linux_prom_isa_ranges isa_ranges[PROMREG_MAX]; + int num_isa_ranges; +}; + +extern struct isa_bridge *isa_chain; + +extern void isa_init(void); + +#define for_each_isa(bus) \ + for((bus) = isa_chain; (bus); (bus) = (bus)->next) + +#define for_each_isadev(dev, bus) \ + for((dev) = (bus)->devices; (dev); (dev) = (dev)->next) + +#endif /* !(__SPARC64_ISA_H) */ diff --git a/include/asm-sparc64/parport.h b/include/asm-sparc64/parport.h index 9a0902325bcb..fcaced48b29b 100644 --- a/include/asm-sparc64/parport.h +++ b/include/asm-sparc64/parport.h @@ -1,4 +1,4 @@ -/* $Id: parport.h,v 1.10 2001/03/24 00:18:57 davem Exp $ +/* $Id: parport.h,v 1.11 2001/05/11 07:54:24 davem Exp $ * parport.h: sparc64 specific parport initialization and dma. * * Copyright (C) 1999 Eddie C. Dost (ecd@skynet.be) @@ -8,6 +8,7 @@ #define _ASM_SPARC64_PARPORT_H 1 #include +#include #include #define PARPORT_PC_MAX_PORTS PARPORT_MAX @@ -118,6 +119,43 @@ static int ebus_ecpp_p(struct linux_ebus_device *edev) return 0; } +static int parport_isa_probe(int count) +{ + struct isa_bridge *isa_br; + struct isa_device *isa_dev; + + for_each_isa(isa_br) { + for_each_isadev(isa_dev, isa_br) { + struct isa_device *child; + unsigned long base; + + if (strcmp(isa_dev->prom_name, "dma")) + continue; + + child = isa_dev->child; + while (child) { + if (!strcmp(child->prom_name, "parallel")) + break; + child = child->next; + } + if (!child) + continue; + + base = child->resource.start; + + /* No DMA, see commentary in + * asm-sparc64/floppy.h:isa_floppy_init() + */ + if (parport_pc_probe_port(base, base + 0x400, + child->irq, PARPORT_DMA_NOFIFO, + child->bus->self)) + count++; + } + } + + return count; +} + static int parport_pc_find_nonpci_ports (int autoirq, int autodma) { struct linux_ebus *ebus; @@ -160,6 +198,8 @@ static int parport_pc_find_nonpci_ports (int autoirq, int autodma) } } + count = parport_isa_probe(count); + return count; } diff --git a/include/asm-sparc64/pbm.h b/include/asm-sparc64/pbm.h index ed71f2e7d7f8..7e4fb85ac9d9 100644 --- a/include/asm-sparc64/pbm.h +++ b/include/asm-sparc64/pbm.h @@ -1,4 +1,4 @@ -/* $Id: pbm.h,v 1.25 2001/02/28 03:28:55 davem Exp $ +/* $Id: pbm.h,v 1.26 2001/05/15 08:54:30 davem Exp $ * pbm.h: UltraSparc PCI controller software state. * * Copyright (C) 1997, 1998, 1999 David S. Miller (davem@redhat.com) @@ -178,6 +178,9 @@ struct pci_controller_info { */ int index; + /* Do the PBMs both exist in the same PCI domain? */ + int pbms_same_domain; + /* The PCI bus modules controlled by us. */ struct pci_pbm_info pbm_A; struct pci_pbm_info pbm_B; diff --git a/include/asm-sparc64/pci.h b/include/asm-sparc64/pci.h index 9f0c2417572a..b523e86881eb 100644 --- a/include/asm-sparc64/pci.h +++ b/include/asm-sparc64/pci.h @@ -3,6 +3,9 @@ #ifdef __KERNEL__ +#include +#include + /* Can be used to override the logic in pci_scan_bus for skipping * already-configured bus numbers - to be used for buggy BIOSes * or architectures with incomplete PCI setup by the loader. @@ -110,6 +113,20 @@ extern void pci_dma_sync_sg(struct pci_dev *hwdev, struct scatterlist *sg, int n */ extern int pci_dma_supported(struct pci_dev *hwdev, dma_addr_t mask); +/* Return the index of the PCI controller for device PDEV. */ + +extern int pci_controller_num(struct pci_dev *pdev); + +/* Platform support for /proc/bus/pci/X/Y mmap()s. */ + +#define HAVE_PCI_MMAP +#define HAVE_ARCH_PCI_GET_UNMAPPED_AREA +#define get_pci_unmapped_area get_fb_unmapped_area + +extern int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma, + enum pci_mmap_state mmap_state, + int write_combine); + #endif /* __KERNEL__ */ #endif /* __SPARC64_PCI_H */ diff --git a/include/linux/fs.h b/include/linux/fs.h index 06ade31b463b..8c954072f94b 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -652,7 +652,6 @@ struct super_block { kdev_t s_dev; unsigned long s_blocksize; unsigned char s_blocksize_bits; - unsigned char s_lock; unsigned char s_dirt; unsigned long long s_maxbytes; /* Max file size */ struct file_system_type *s_type; @@ -662,7 +661,7 @@ struct super_block { unsigned long s_magic; struct dentry *s_root; struct rw_semaphore s_umount; - wait_queue_head_t s_wait; + struct semaphore s_lock; struct list_head s_dirty; /* dirty inodes */ struct list_head s_locked_inodes;/* inodes being synced */ @@ -1279,6 +1278,7 @@ int generic_block_bmap(struct address_space *, long, get_block_t *); int generic_commit_write(struct file *, struct page *, unsigned, unsigned); int block_truncate_page(struct address_space *, loff_t, get_block_t *); +extern int waitfor_one_page(struct page*); extern int generic_file_mmap(struct file *, struct vm_area_struct *); extern int file_read_actor(read_descriptor_t * desc, struct page *page, unsigned long offset, unsigned long size); extern ssize_t generic_file_read(struct file *, char *, size_t, loff_t *); diff --git a/include/linux/inetdevice.h b/include/linux/inetdevice.h index 8164ec72f960..ded38f67b36f 100644 --- a/include/linux/inetdevice.h +++ b/include/linux/inetdevice.h @@ -17,6 +17,7 @@ struct ipv4_devconf int forwarding; int mc_forwarding; int tag; + int arp_filter; void *sysctl; }; @@ -54,6 +55,8 @@ struct in_device || (!IN_DEV_FORWARD(in_dev) && \ (ipv4_devconf.accept_redirects || (in_dev)->cnf.accept_redirects))) +#define IN_DEV_ARPFILTER(in_dev) (ipv4_devconf.arp_filter || (in_dev)->cnf.arp_filter) + struct in_ifaddr { struct in_ifaddr *ifa_next; diff --git a/include/linux/locks.h b/include/linux/locks.h index 9d342e669404..1c1f2bbb19eb 100644 --- a/include/linux/locks.h +++ b/include/linux/locks.h @@ -39,30 +39,15 @@ extern inline void unlock_buffer(struct buffer_head *bh) * a super-block (although even this isn't done right now. * nfs may need it). */ -extern void __wait_on_super(struct super_block *); - -extern inline void wait_on_super(struct super_block * sb) -{ - if (sb->s_lock) - __wait_on_super(sb); -} extern inline void lock_super(struct super_block * sb) { - if (sb->s_lock) - __wait_on_super(sb); - sb->s_lock = 1; + down(&sb->s_lock); } extern inline void unlock_super(struct super_block * sb) { - sb->s_lock = 0; - /* - * No need of any barrier, we're protected by - * the big kernel lock here... unfortunately :) - */ - if (waitqueue_active(&sb->s_wait)) - wake_up(&sb->s_wait); + up(&sb->s_lock); } #endif /* _LINUX_LOCKS_H */ diff --git a/include/linux/mii.h b/include/linux/mii.h new file mode 100644 index 000000000000..1b6b951e8b59 --- /dev/null +++ b/include/linux/mii.h @@ -0,0 +1,181 @@ +/* + * linux/mii.h: definitions for MII-compatible transceivers + * Originally drivers/net/sunhme.h. + * + * Copyright (C) 1996, 1999 David S. Miller (davem@redhat.com) + */ + +#ifndef __LINUX_MII_H__ +#define __LINUX_MII_H__ + +/* Inside the Happy Meal transceiver is the physical layer, they use an + * implementations for National Semiconductor, part number DP83840VCE. + * You can retrieve the data sheets and programming docs for this beast + * from http://www.national.com/ + * + * The DP83840 is capable of both 10 and 100Mbps ethernet, in both + * half and full duplex mode. It also supports auto negotiation. + * + * But.... THIS THING IS A PAIN IN THE ASS TO PROGRAM! + * Debugging eeprom burnt code is more fun than programming this chip! + */ + +/* First, the MII register numbers (actually DP83840 register numbers). */ +#define MII_BMCR 0x00 /* Basic mode control register */ +#define MII_BMSR 0x01 /* Basic mode status register */ +#define MII_PHYSID1 0x02 /* PHYS ID 1 */ +#define MII_PHYSID2 0x03 /* PHYS ID 2 */ +#define MII_ADVERTISE 0x04 /* Advertisement control reg */ +#define MII_LPA 0x05 /* Link partner ability reg */ +#define MII_EXPANSION 0x06 /* Expansion register */ +#define MII_DCOUNTER 0x12 /* Disconnect counter */ +#define MII_FCSCOUNTER 0x13 /* False carrier counter */ +#define MII_NWAYTEST 0x14 /* N-way auto-neg test reg */ +#define MII_RERRCOUNTER 0x15 /* Receive error counter */ +#define MII_SREVISION 0x16 /* Silicon revision */ +#define MII_CSCONFIG 0x17 /* CS configuration */ +#define MII_LBRERROR 0x18 /* Lpback, rx, bypass error */ +#define MII_PHYADDR 0x19 /* PHY address */ +#define MII_RESERVED 0x1a /* Unused... */ +#define MII_TPISTATUS 0x1b /* TPI status for 10mbps */ +#define MII_NCONFIG 0x1c /* Network interface config */ + +/* Basic mode control register. */ +#define BMCR_RESV 0x007f /* Unused... */ +#define BMCR_CTST 0x0080 /* Collision test */ +#define BMCR_FULLDPLX 0x0100 /* Full duplex */ +#define BMCR_ANRESTART 0x0200 /* Auto negotiation restart */ +#define BMCR_ISOLATE 0x0400 /* Disconnect DP83840 from MII */ +#define BMCR_PDOWN 0x0800 /* Powerdown the DP83840 */ +#define BMCR_ANENABLE 0x1000 /* Enable auto negotiation */ +#define BMCR_SPEED100 0x2000 /* Select 100Mbps */ +#define BMCR_LOOPBACK 0x4000 /* TXD loopback bits */ +#define BMCR_RESET 0x8000 /* Reset the DP83840 */ + +/* Basic mode status register. */ +#define BMSR_ERCAP 0x0001 /* Ext-reg capability */ +#define BMSR_JCD 0x0002 /* Jabber detected */ +#define BMSR_LSTATUS 0x0004 /* Link status */ +#define BMSR_ANEGCAPABLE 0x0008 /* Able to do auto-negotiation */ +#define BMSR_RFAULT 0x0010 /* Remote fault detected */ +#define BMSR_ANEGCOMPLETE 0x0020 /* Auto-negotiation complete */ +#define BMSR_RESV 0x07c0 /* Unused... */ +#define BMSR_10HALF 0x0800 /* Can do 10mbps, half-duplex */ +#define BMSR_10FULL 0x1000 /* Can do 10mbps, full-duplex */ +#define BMSR_100HALF 0x2000 /* Can do 100mbps, half-duplex */ +#define BMSR_100FULL 0x4000 /* Can do 100mbps, full-duplex */ +#define BMSR_100BASE4 0x8000 /* Can do 100mbps, 4k packets */ + +/* Advertisement control register. */ +#define ADVERTISE_SLCT 0x001f /* Selector bits */ +#define ADVERTISE_CSMA 0x0001 /* Only selector supported */ +#define ADVERTISE_10HALF 0x0020 /* Try for 10mbps half-duplex */ +#define ADVERTISE_10FULL 0x0040 /* Try for 10mbps full-duplex */ +#define ADVERTISE_100HALF 0x0080 /* Try for 100mbps half-duplex */ +#define ADVERTISE_100FULL 0x0100 /* Try for 100mbps full-duplex */ +#define ADVERTISE_100BASE4 0x0200 /* Try for 100mbps 4k packets */ +#define ADVERTISE_RESV 0x1c00 /* Unused... */ +#define ADVERTISE_RFAULT 0x2000 /* Say we can detect faults */ +#define ADVERTISE_LPACK 0x4000 /* Ack link partners response */ +#define ADVERTISE_NPAGE 0x8000 /* Next page bit */ + +#define ADVERTISE_ALL (ADVERTISE_10HALF | ADVERTISE_10FULL | \ + ADVERTISE_100HALF | ADVERTISE_100FULL) + +/* Link partner ability register. */ +#define LPA_SLCT 0x001f /* Same as advertise selector */ +#define LPA_10HALF 0x0020 /* Can do 10mbps half-duplex */ +#define LPA_10FULL 0x0040 /* Can do 10mbps full-duplex */ +#define LPA_100HALF 0x0080 /* Can do 100mbps half-duplex */ +#define LPA_100FULL 0x0100 /* Can do 100mbps full-duplex */ +#define LPA_100BASE4 0x0200 /* Can do 100mbps 4k packets */ +#define LPA_RESV 0x1c00 /* Unused... */ +#define LPA_RFAULT 0x2000 /* Link partner faulted */ +#define LPA_LPACK 0x4000 /* Link partner acked us */ +#define LPA_NPAGE 0x8000 /* Next page bit */ + +#define LPA_DUPLEX (LPA_10FULL | LPA_100FULL) +#define LPA_100 (LPA_100FULL | LPA_100HALF | LPA_100BASE4) + +/* Expansion register for auto-negotiation. */ +#define EXPANSION_NWAY 0x0001 /* Can do N-way auto-nego */ +#define EXPANSION_LCWP 0x0002 /* Got new RX page code word */ +#define EXPANSION_ENABLENPAGE 0x0004 /* This enables npage words */ +#define EXPANSION_NPCAPABLE 0x0008 /* Link partner supports npage */ +#define EXPANSION_MFAULTS 0x0010 /* Multiple faults detected */ +#define EXPANSION_RESV 0xffe0 /* Unused... */ + +/* N-way test register. */ +#define NWAYTEST_RESV1 0x00ff /* Unused... */ +#define NWAYTEST_LOOPBACK 0x0100 /* Enable loopback for N-way */ +#define NWAYTEST_RESV2 0xfe00 /* Unused... */ + +/* The Carrier Sense config register. */ +#define CSCONFIG_RESV1 0x0001 /* Unused... */ +#define CSCONFIG_LED4 0x0002 /* Pin for full-dplx LED4 */ +#define CSCONFIG_LED1 0x0004 /* Pin for conn-status LED1 */ +#define CSCONFIG_RESV2 0x0008 /* Unused... */ +#define CSCONFIG_TCVDISAB 0x0010 /* Turns off the transceiver */ +#define CSCONFIG_DFBYPASS 0x0020 /* Bypass disconnect function */ +#define CSCONFIG_GLFORCE 0x0040 /* Good link force for 100mbps */ +#define CSCONFIG_CLKTRISTATE 0x0080 /* Tristate 25m clock */ +#define CSCONFIG_RESV3 0x0700 /* Unused... */ +#define CSCONFIG_ENCODE 0x0800 /* 1=MLT-3, 0=binary */ +#define CSCONFIG_RENABLE 0x1000 /* Repeater mode enable */ +#define CSCONFIG_TCDISABLE 0x2000 /* Disable timeout counter */ +#define CSCONFIG_RESV4 0x4000 /* Unused... */ +#define CSCONFIG_NDISABLE 0x8000 /* Disable NRZI */ + +/** + * mii_nway_result + * @negotiated: value of MII ANAR and'd with ANLPAR + * + * Given a set of MII abilities, check each bit and returns the + * currently supported media, in the priority order defined by + * IEEE 802.3u. We use LPA_xxx constants but note this is not the + * value of LPA solely, as described above. + * + * The one exception to IEEE 802.3u is that 100baseT4 is placed + * between 100T-full and 100T-half. If your phy does not support + * 100T4 this is fine. If your phy places 100T4 elsewhere in the + * priority order, you will need to roll your own function. + */ +static inline unsigned int mii_nway_result (unsigned int negotiated) +{ + unsigned int ret; + + if (negotiated & LPA_100FULL) + ret = LPA_100FULL; + else if (negotiated & LPA_100BASE4) + ret = LPA_100BASE4; + else if (negotiated & LPA_100HALF) + ret = LPA_100HALF; + else if (negotiated & LPA_10FULL) + ret = LPA_10FULL; + else + ret = LPA_10HALF; + + return ret; +} + +/** + * mii_duplex + * @duplex_lock: Non-zero if duplex is locked at full + * @negotiated: value of MII ANAR and'd with ANLPAR + * + * A small helper function for a common case. Returns one + * if the media is operating or locked at full duplex, and + * returns zero otherwise. + */ +static inline unsigned int mii_duplex (unsigned int duplex_lock, + unsigned int negotiated) +{ + if (duplex_lock) + return 1; + if (mii_nway_result(negotiated) & LPA_DUPLEX) + return 1; + return 0; +} + + +#endif /* __LINUX_MII_H__ */ diff --git a/include/linux/nfsd/nfsfh.h b/include/linux/nfsd/nfsfh.h index 39ab97f14965..dc2dae68d1c7 100644 --- a/include/linux/nfsd/nfsfh.h +++ b/include/linux/nfsd/nfsfh.h @@ -31,7 +31,7 @@ * ino/dev of the exported inode. */ struct nfs_fhbase_old { - struct dentry * fb_dentry; /* dentry cookie - always 0xfeebbaca */ + __u32 fb_dcookie; /* dentry cookie - always 0xfeebbaca */ __u32 fb_ino; /* our inode number */ __u32 fb_dirino; /* dir inode number, 0 for directories */ __u32 fb_dev; /* our device */ @@ -101,7 +101,7 @@ struct knfsd_fh { } fh_base; }; -#define ofh_dcookie fh_base.fh_old.fb_dentry +#define ofh_dcookie fh_base.fh_old.fb_dcookie #define ofh_ino fh_base.fh_old.fb_ino #define ofh_dirino fh_base.fh_old.fb_dirino #define ofh_dev fh_base.fh_old.fb_dev diff --git a/include/linux/pci.h b/include/linux/pci.h index ffea2d01aea8..dedc3c674440 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -279,6 +279,13 @@ #define PCI_SLOT(devfn) (((devfn) >> 3) & 0x1f) #define PCI_FUNC(devfn) ((devfn) & 0x07) +/* Ioctls for /proc/bus/pci/X/Y nodes. */ +#define PCIIOC_BASE ('P' << 24 | 'C' << 16 | 'I' << 8) +#define PCIIOC_CONTROLLER (PCIIOC_BASE | 0x00) /* Get controller for PCI device. */ +#define PCIIOC_MMAP_IS_IO (PCIIOC_BASE | 0x01) /* Set mmap state to I/O space. */ +#define PCIIOC_MMAP_IS_MEM (PCIIOC_BASE | 0x02) /* Set mmap state to MEM space. */ +#define PCIIOC_WRITE_COMBINE (PCIIOC_BASE | 0x03) /* Enable/disable write-combining. */ + #ifdef __KERNEL__ #include @@ -287,6 +294,12 @@ #include #include +/* File state for mmap()s on /proc/bus/pci/X/Y */ +enum pci_mmap_state { + pci_mmap_io, + pci_mmap_mem +}; + /* This defines the direction arg to the DMA mapping routines. */ #define PCI_DMA_BIDIRECTIONAL 0 #define PCI_DMA_TODEVICE 1 diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index ee6d0eb47f8d..5599f65984cb 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h @@ -978,6 +978,10 @@ #define PCI_VENDOR_ID_MUTECH 0x1159 #define PCI_DEVICE_ID_MUTECH_MV1000 0x0001 +#define PCI_VENDOR_ID_XIRCOM 0x115d +#define PCI_DEVICE_ID_XIRCOM_X3201_ETH 0x0003 +#define PCI_DEVICE_ID_XIRCOM_X3201_MDM 0x0103 + #define PCI_VENDOR_ID_RENDITION 0x1163 #define PCI_DEVICE_ID_RENDITION_VERITE 0x0001 #define PCI_DEVICE_ID_RENDITION_VERITE2100 0x2000 diff --git a/include/linux/raid/md.h b/include/linux/raid/md.h index 7b184ce94cb5..5cd20c6fcc1b 100644 --- a/include/linux/raid/md.h +++ b/include/linux/raid/md.h @@ -80,7 +80,7 @@ extern int md_check_ordering (mddev_t *mddev); extern struct gendisk * find_gendisk (kdev_t dev); extern int md_notify_reboot(struct notifier_block *this, unsigned long code, void *x); -extern int md_error (kdev_t mddev, kdev_t rdev); +extern int md_error (mddev_t *mddev, kdev_t rdev); extern int md_run_setup(void); extern void md_print_devices (void); diff --git a/include/linux/raid/md_k.h b/include/linux/raid/md_k.h index b98eb998e4f3..6609c02cd35e 100644 --- a/include/linux/raid/md_k.h +++ b/include/linux/raid/md_k.h @@ -25,7 +25,7 @@ #define HSM 6UL #define MAX_PERSONALITY 7UL -extern inline int pers_to_level (int pers) +static inline int pers_to_level (int pers) { switch (pers) { case HSM: return -3; @@ -72,7 +72,7 @@ typedef struct dev_mapping_s { extern dev_mapping_t mddev_map [MAX_MD_DEVS]; -extern inline mddev_t * kdev_to_mddev (kdev_t dev) +static inline mddev_t * kdev_to_mddev (kdev_t dev) { if (MAJOR(dev) != MD_MAJOR) BUG(); @@ -90,62 +90,62 @@ extern inline mddev_t * kdev_to_mddev (kdev_t dev) */ #define MD_READAHEAD MAX_READAHEAD -extern inline int disk_faulty(mdp_disk_t * d) +static inline int disk_faulty(mdp_disk_t * d) { return d->state & (1 << MD_DISK_FAULTY); } -extern inline int disk_active(mdp_disk_t * d) +static inline int disk_active(mdp_disk_t * d) { return d->state & (1 << MD_DISK_ACTIVE); } -extern inline int disk_sync(mdp_disk_t * d) +static inline int disk_sync(mdp_disk_t * d) { return d->state & (1 << MD_DISK_SYNC); } -extern inline int disk_spare(mdp_disk_t * d) +static inline int disk_spare(mdp_disk_t * d) { return !disk_sync(d) && !disk_active(d) && !disk_faulty(d); } -extern inline int disk_removed(mdp_disk_t * d) +static inline int disk_removed(mdp_disk_t * d) { return d->state & (1 << MD_DISK_REMOVED); } -extern inline void mark_disk_faulty(mdp_disk_t * d) +static inline void mark_disk_faulty(mdp_disk_t * d) { d->state |= (1 << MD_DISK_FAULTY); } -extern inline void mark_disk_active(mdp_disk_t * d) +static inline void mark_disk_active(mdp_disk_t * d) { d->state |= (1 << MD_DISK_ACTIVE); } -extern inline void mark_disk_sync(mdp_disk_t * d) +static inline void mark_disk_sync(mdp_disk_t * d) { d->state |= (1 << MD_DISK_SYNC); } -extern inline void mark_disk_spare(mdp_disk_t * d) +static inline void mark_disk_spare(mdp_disk_t * d) { d->state = 0; } -extern inline void mark_disk_removed(mdp_disk_t * d) +static inline void mark_disk_removed(mdp_disk_t * d) { d->state = (1 << MD_DISK_FAULTY) | (1 << MD_DISK_REMOVED); } -extern inline void mark_disk_inactive(mdp_disk_t * d) +static inline void mark_disk_inactive(mdp_disk_t * d) { d->state &= ~(1 << MD_DISK_ACTIVE); } -extern inline void mark_disk_nonsync(mdp_disk_t * d) +static inline void mark_disk_nonsync(mdp_disk_t * d) { d->state &= ~(1 << MD_DISK_SYNC); } @@ -245,12 +245,12 @@ struct mdk_personality_s * number. This will have to change to dynamic allocation * once we start supporting partitioning of md devices. */ -extern inline int mdidx (mddev_t * mddev) +static inline int mdidx (mddev_t * mddev) { return mddev->__minor; } -extern inline kdev_t mddev_to_kdev(mddev_t * mddev) +static inline kdev_t mddev_to_kdev(mddev_t * mddev) { return MKDEV(MD_MAJOR, mdidx(mddev)); } @@ -304,12 +304,12 @@ extern mdk_rdev_t * find_rdev_nr(mddev_t *mddev, int nr); tmp = tmp->next, tmp->prev != &all_mddevs \ ; ) -extern inline int lock_mddev (mddev_t * mddev) +static inline int lock_mddev (mddev_t * mddev) { return down_interruptible(&mddev->reconfig_sem); } -extern inline void unlock_mddev (mddev_t * mddev) +static inline void unlock_mddev (mddev_t * mddev) { up(&mddev->reconfig_sem); } diff --git a/include/linux/smb.h b/include/linux/smb.h index 9f39c09d80ac..9cf2d068b7eb 100644 --- a/include/linux/smb.h +++ b/include/linux/smb.h @@ -94,22 +94,15 @@ struct smb_fattr { }; enum smb_conn_state { - CONN_VALID, /* everything's fine */ - CONN_INVALID, /* Something went wrong, but did not - try to reconnect yet. */ - CONN_RETRIED /* Tried a reconnection, but was refused */ + CONN_VALID, /* everything's fine */ + CONN_INVALID, /* Something went wrong, but did not + try to reconnect yet. */ + CONN_RETRIED, /* Tried a reconnection, but was refused */ + CONN_RETRYING /* Currently trying to reconnect */ }; -/* - * The readdir cache size controls how many directory entries are cached. - */ -#define SMB_READDIR_CACHE_SIZE 64 - #define SMB_SUPER_MAGIC 0x517B -#define SMB_SERVER(inode) (&(inode->i_sb->u.smbfs_sb)) -#define SMB_INOP(inode) (&(inode->u.smbfs_i)) - #define SMB_HEADER_LEN 37 /* includes everything up to, but not * including smb_bcc */ diff --git a/include/linux/smb_fs.h b/include/linux/smb_fs.h index 4a811a20d68d..69df503e70ea 100644 --- a/include/linux/smb_fs.h +++ b/include/linux/smb_fs.h @@ -48,8 +48,11 @@ #ifdef DEBUG_SMB_MALLOC +#include + extern int smb_malloced; extern int smb_current_vmalloced; +extern int smb_current_kmalloced; static inline void * smb_vmalloc(unsigned int size) @@ -66,20 +69,30 @@ smb_vfree(void *obj) vfree(obj); } +static inline void * +smb_kmalloc(size_t size, int flags) +{ + smb_malloced += 1; + smb_current_kmalloced += 1; + return kmalloc(size, flags); +} + +static inline void +smb_kfree(void *obj) +{ + smb_current_kmalloced -= 1; + kfree(obj); +} + #else /* DEBUG_SMB_MALLOC */ -#define smb_kmalloc(s,p) kmalloc(s,p) -#define smb_kfree_s(o,s) kfree(o) -#define smb_vmalloc(s) vmalloc(s) -#define smb_vfree(o) vfree(o) +#define smb_kmalloc(s,p) kmalloc(s,p) +#define smb_kfree(o) kfree(o) +#define smb_vmalloc(s) vmalloc(s) +#define smb_vfree(o) vfree(o) #endif /* DEBUG_SMB_MALLOC */ -/* - * Flags for the in-memory inode - */ -#define SMB_F_LOCALWRITE 0x02 /* file modified locally */ - /* NT1 protocol capability bits */ #define SMB_CAP_RAW_MODE 0x0001 @@ -139,7 +152,7 @@ struct smb_cache_control { static inline int smb_is_open(struct inode *i) { - return (i->u.smbfs_i.open == SMB_SERVER(i)->generation); + return (i->u.smbfs_i.open == server_from_inode(i)->generation); } @@ -194,6 +207,7 @@ int smb_proc_settime(struct dentry *, struct smb_fattr *); int smb_proc_dskattr(struct super_block *, struct statfs *); int smb_proc_disconnect(struct smb_sb_info *); int smb_proc_trunc(struct smb_sb_info *, __u16, __u32); +int smb_proc_flush(struct smb_sb_info *, __u16); void smb_init_root_dirent(struct smb_sb_info *, struct smb_fattr *); /* linux/fs/smbfs/sock.c */ diff --git a/include/linux/smb_fs_i.h b/include/linux/smb_fs_i.h index e0faddbb3d2a..a2dffed11d0a 100644 --- a/include/linux/smb_fs_i.h +++ b/include/linux/smb_fs_i.h @@ -26,7 +26,6 @@ struct smb_inode_info { __u16 attr; /* Attribute fields, DOS value */ __u16 access; /* Access mode */ - __u16 flags; /* status flags */ unsigned long oldmtime; /* last time refreshed */ unsigned long closed; /* timestamp when closed */ unsigned openers; /* number of fileid users */ diff --git a/include/linux/smb_fs_sb.h b/include/linux/smb_fs_sb.h index 0d14b83ae52a..4a2f0d43fce9 100644 --- a/include/linux/smb_fs_sb.h +++ b/include/linux/smb_fs_sb.h @@ -58,6 +58,19 @@ struct smb_sb_info { struct nls_table *, struct nls_table *); }; + +static inline void +smb_lock_server(struct smb_sb_info *server) +{ + down(&(server->sem)); +} + +static inline void +smb_unlock_server(struct smb_sb_info *server) +{ + up(&(server->sem)); +} + #endif /* __KERNEL__ */ #endif diff --git a/include/linux/sysctl.h b/include/linux/sysctl.h index 2be358f33638..add4ca9d28b1 100644 --- a/include/linux/sysctl.h +++ b/include/linux/sysctl.h @@ -324,7 +324,8 @@ enum NET_IPV4_CONF_ACCEPT_SOURCE_ROUTE=9, NET_IPV4_CONF_BOOTP_RELAY=10, NET_IPV4_CONF_LOG_MARTIANS=11, - NET_IPV4_CONF_TAG=12 + NET_IPV4_CONF_TAG=12, + NET_IPV4_CONF_ARPFILTER=13 }; /* /proc/sys/net/ipv6 */ diff --git a/include/net/addrconf.h b/include/net/addrconf.h index a8f99cee7d5b..b237fa6bb960 100644 --- a/include/net/addrconf.h +++ b/include/net/addrconf.h @@ -158,16 +158,8 @@ static __inline__ u8 ipv6_addr_hash(struct in6_addr *addr) * compute link-local solicited-node multicast address */ -static inline void addrconf_addr_solict_mult_old(struct in6_addr *addr, - struct in6_addr *solicited) -{ - ipv6_addr_set(solicited, - __constant_htonl(0xFF020000), 0, - __constant_htonl(0x1), addr->s6_addr32[3]); -} - -static inline void addrconf_addr_solict_mult_new(struct in6_addr *addr, - struct in6_addr *solicited) +static inline void addrconf_addr_solict_mult(struct in6_addr *addr, + struct in6_addr *solicited) { ipv6_addr_set(solicited, __constant_htonl(0xFF020000), 0, diff --git a/include/net/snmp.h b/include/net/snmp.h index 03b0dfa99cf5..2cefaf5f0ae8 100644 --- a/include/net/snmp.h +++ b/include/net/snmp.h @@ -14,7 +14,7 @@ * as published by the Free Software Foundation; either version * 2 of the License, or (at your option) any later version. * - * $Id: snmp.h,v 1.17 2000/09/21 01:31:50 davem Exp $ + * $Id: snmp.h,v 1.18 2001/05/16 16:45:35 davem Exp $ * */ @@ -199,6 +199,7 @@ struct linux_mib unsigned long OfoPruned; unsigned long OutOfWindowIcmps; unsigned long LockDroppedIcmps; + unsigned long ArpFilter; unsigned long TimeWaited; unsigned long TimeWaitRecycled; unsigned long TimeWaitKilled; diff --git a/kernel/ksyms.c b/kernel/ksyms.c index b28f65e9fd5f..e5d604dcc4ae 100644 --- a/kernel/ksyms.c +++ b/kernel/ksyms.c @@ -203,6 +203,7 @@ EXPORT_SYMBOL(cont_prepare_write); EXPORT_SYMBOL(generic_commit_write); EXPORT_SYMBOL(block_truncate_page); EXPORT_SYMBOL(generic_block_bmap); +EXPORT_SYMBOL(waitfor_one_page); EXPORT_SYMBOL(generic_file_read); EXPORT_SYMBOL(do_generic_file_read); EXPORT_SYMBOL(generic_file_write); @@ -478,7 +479,6 @@ EXPORT_SYMBOL(si_meminfo); /* Added to make file system as module */ EXPORT_SYMBOL(sys_tz); -EXPORT_SYMBOL(__wait_on_super); EXPORT_SYMBOL(file_fsync); EXPORT_SYMBOL(fsync_inode_buffers); EXPORT_SYMBOL(clear_inode); diff --git a/mm/filemap.c b/mm/filemap.c index 0449be67389a..c19cab5e530f 100644 --- a/mm/filemap.c +++ b/mm/filemap.c @@ -284,6 +284,34 @@ repeat: spin_unlock(&pagecache_lock); } +/* + * This function is pretty much like __find_page_nolock(), but it only + * requires 2 arguments and doesn't mark the page as touched, making it + * ideal for ->writepage() clustering and other places where you don't + * want to mark the page referenced. + * + * The caller needs to hold the pagecache_lock. + */ +static struct page * FASTCALL(__find_page_simple(struct address_space *, unsigned long)); +static struct page * __find_page_simple(struct address_space *mapping, unsigned long index) +{ + struct page **next = page_hash(mapping, index);; + + for (;;) { + struct page *page = *next; + if (!page) + break; + next = &page->next_hash; + if (page->mapping != mapping) + continue; + if (page->index != index) + continue; + return page; + } + + return NULL; +} + static inline struct page * __find_page_nolock(struct address_space *mapping, unsigned long offset, struct page *page) { goto inside; @@ -298,14 +326,9 @@ inside: if (page->index == offset) break; } - /* - * Touching the page may move it to the active list. - * If we end up with too few inactive pages, we wake - * up kswapd. - */ - age_page_up(page); - if (inactive_shortage() > inactive_target / 2 && free_shortage()) - wakeup_kswapd(); + /* Mark the page referenced, kswapd will find it later. */ + SetPageReferenced(page); + not_found: return page; } @@ -331,7 +354,7 @@ static int writeout_one_page(struct page *page) return 0; } -static int waitfor_one_page(struct page *page) +int waitfor_one_page(struct page *page) { int error = 0; struct buffer_head *bh, *head = page->buffers; @@ -762,7 +785,6 @@ static void drop_behind(struct file * file, unsigned long index) { struct inode *inode = file->f_dentry->d_inode; struct address_space *mapping = inode->i_mapping; - struct page **hash; struct page *page; unsigned long start; @@ -783,8 +805,7 @@ static void drop_behind(struct file * file, unsigned long index) */ spin_lock(&pagecache_lock); while (--index >= start) { - hash = page_hash(mapping, index); - page = __find_page_nolock(mapping, index, *hash); + page = __find_page_simple(mapping, index); if (!page) break; deactivate_page(page); diff --git a/mm/slab.c b/mm/slab.c index b66533649ca3..15268170e41d 100644 --- a/mm/slab.c +++ b/mm/slab.c @@ -1958,7 +1958,7 @@ int slabinfo_write_proc (struct file *file, const char *buffer, unsigned long count, void *data) { #ifdef CONFIG_SMP - char kbuf[MAX_SLABINFO_WRITE], *tmp; + char kbuf[MAX_SLABINFO_WRITE+1], *tmp; int limit, batchcount, res; struct list_head *p; @@ -1966,6 +1966,7 @@ int slabinfo_write_proc (struct file *file, const char *buffer, return -EINVAL; if (copy_from_user(&kbuf, buffer, count)) return -EFAULT; + kbuf[MAX_SLABINFO_WRITE] = '\0'; tmp = strchr(kbuf, ' '); if (!tmp) diff --git a/mm/vmscan.c b/mm/vmscan.c index a5047901ef5e..73f7dc4108bd 100644 --- a/mm/vmscan.c +++ b/mm/vmscan.c @@ -24,6 +24,8 @@ #include +#define MAX(a,b) ((a) > (b) ? (a) : (b)) + /* * The swap-out function returns 1 if it successfully * scanned all the pages it was asked to (`count'). @@ -228,6 +230,8 @@ static int swap_out_mm(struct mm_struct * mm, int count) unsigned long address; struct vm_area_struct* vma; + if (!count) + return 1; /* * Go through process' page directory. */ @@ -271,7 +275,12 @@ out_unlock: static inline int swap_amount(struct mm_struct *mm) { int nr = mm->rss >> SWAP_SHIFT; - return nr < SWAP_MIN ? SWAP_MIN : nr; + if (nr < SWAP_MIN) { + nr = SWAP_MIN; + if (nr > mm->rss) + nr = mm->rss; + } + return nr; } static int swap_out(unsigned int priority, int gfp_mask) @@ -285,7 +294,7 @@ static int swap_out(unsigned int priority, int gfp_mask) retval = swap_out_mm(mm, swap_amount(mm)); /* Then, look at the other mm's */ - counter = mmlist_nr >> priority; + counter = (mmlist_nr << SWAP_SHIFT) >> priority; do { struct list_head *p; @@ -350,7 +359,7 @@ struct page * reclaim_page(zone_t * zone) } /* Page is or was in use? Move it to the active list. */ - if (PageTestandClearReferenced(page) || page->age > 0 || + if (PageReferenced(page) || page->age > 0 || (!page->buffers && page_count(page) > 1)) { del_page_from_inactive_clean_list(page); add_page_to_active_list(page); @@ -453,7 +462,7 @@ dirty_page_rescan: } /* Page is or was in use? Move it to the active list. */ - if (PageTestandClearReferenced(page) || page->age > 0 || + if (PageReferenced(page) || page->age > 0 || (!page->buffers && page_count(page) > 1) || page_ramdisk(page)) { del_page_from_inactive_dirty_list(page); @@ -631,21 +640,42 @@ page_active: /** * refill_inactive_scan - scan the active list and find pages to deactivate * @priority: the priority at which to scan - * @oneshot: exit after deactivating one page + * @target: number of pages to deactivate, zero for background aging * * This function will scan a portion of the active list to find * unused pages, those pages will then be moved to the inactive list. */ -int refill_inactive_scan(unsigned int priority, int oneshot) +int refill_inactive_scan(unsigned int priority, int target) { struct list_head * page_lru; struct page * page; - int maxscan, page_active = 0; - int ret = 0; + int maxscan = nr_active_pages >> priority; + int page_active = 0; + int nr_deactivated = 0; + + /* + * When we are background aging, we try to increase the page aging + * information in the system. When we have too many inactive pages + * we don't do background aging since having all pages on the + * inactive list decreases aging information. + * + * Since not all active pages have to be on the active list, we round + * nr_active_pages up to num_physpages/2, if needed. + */ + if (!target) { + int inactive = nr_free_pages() + nr_inactive_clean_pages() + + nr_inactive_dirty_pages; + int active = MAX(nr_active_pages, num_physpages / 2); + if (active > 10 * inactive) + maxscan = nr_active_pages >> 4; + else if (active > 3 * inactive) + maxscan = nr_active_pages >> 8; + else + return 0; + } /* Take the lock while messing with the list... */ spin_lock(&pagemap_lru_lock); - maxscan = nr_active_pages >> priority; while (maxscan-- > 0 && (page_lru = active_list.prev) != &active_list) { page = list_entry(page_lru, struct page, lru); @@ -683,21 +713,21 @@ int refill_inactive_scan(unsigned int priority, int oneshot) } /* * If the page is still on the active list, move it - * to the other end of the list. Otherwise it was - * deactivated by age_page_down and we exit successfully. + * to the other end of the list. Otherwise we exit if + * we have done enough work. */ if (page_active || PageActive(page)) { list_del(page_lru); list_add(page_lru, &active_list); } else { - ret = 1; - if (oneshot) + nr_deactivated++; + if (target && nr_deactivated >= target) break; } } spin_unlock(&pagemap_lru_lock); - return ret; + return nr_deactivated; } /* @@ -709,7 +739,7 @@ int free_shortage(void) pg_data_t *pgdat = pgdat_list; int sum = 0; int freeable = nr_free_pages() + nr_inactive_clean_pages(); - int freetarget = freepages.high + inactive_target / 3; + int freetarget = freepages.high; /* Are we low on free pages globally? */ if (freeable < freetarget) @@ -721,9 +751,8 @@ int free_shortage(void) for(i = 0; i < MAX_NR_ZONES; i++) { zone_t *zone = pgdat->node_zones+ i; if (zone->size && (zone->inactive_clean_pages + - zone->free_pages < zone->pages_min+1)) { - /* + 1 to have overlap with alloc_pages() !! */ - sum += zone->pages_min + 1; + zone->free_pages < zone->pages_min)) { + sum += zone->pages_min; sum -= zone->free_pages; sum -= zone->inactive_clean_pages; } @@ -777,38 +806,46 @@ int inactive_shortage(void) } /* - * We need to make the locks finer granularity, but right - * now we need this so that we can do page allocations - * without holding the kernel lock etc. + * Refill_inactive is the function used to scan and age the pages on + * the active list and in the working set of processes, moving the + * little-used pages to the inactive list. * - * We want to try to free "count" pages, and we want to - * cluster them so that we get good swap-out behaviour. + * When called by kswapd, we try to deactivate as many pages as needed + * to recover from the inactive page shortage. This makes it possible + * for kswapd to keep up with memory demand so user processes can get + * low latency on memory allocations. * - * OTOH, if we're a user process (and not kswapd), we - * really care about latency. In that case we don't try - * to free too many pages. + * However, when the system starts to get overloaded we can get called + * by user processes. For user processes we want to both reduce the + * latency and make sure that multiple user processes together don't + * deactivate too many pages. To achieve this we simply do less work + * when called from a user process. */ #define DEF_PRIORITY (6) static int refill_inactive(unsigned int gfp_mask, int user) { int count, start_count, maxtry; - count = inactive_shortage() + free_shortage(); - if (user) + if (user) { count = (1 << page_cluster); - start_count = count; + maxtry = 6; + } else { + count = inactive_shortage(); + maxtry = 1 << DEF_PRIORITY; + } - maxtry = 6; + start_count = count; do { if (current->need_resched) { __set_current_state(TASK_RUNNING); schedule(); + if (!inactive_shortage()) + return 1; } - while (refill_inactive_scan(DEF_PRIORITY, 1)) { - if (--count <= 0) - goto done; - } + count -= refill_inactive_scan(DEF_PRIORITY, count); + if (count <= 0) + goto done; /* If refill_inactive_scan failed, try to page stuff out.. */ swap_out(DEF_PRIORITY, gfp_mask); @@ -834,8 +871,7 @@ static int do_try_to_free_pages(unsigned int gfp_mask, int user) * before we get around to moving them to the other * list, so this is a relatively cheap operation. */ - if (free_shortage() || nr_inactive_dirty_pages > nr_free_pages() + - nr_inactive_clean_pages()) + if (free_shortage()) ret += page_launder(gfp_mask, user); /* @@ -916,18 +952,15 @@ int kswapd(void *unused) if (inactive_shortage() || free_shortage()) do_try_to_free_pages(GFP_KSWAPD, 0); - /* - * Do some (very minimal) background scanning. This - * will scan all pages on the active list once - * every minute. This clears old referenced bits - * and moves unused pages to the inactive list. - */ - refill_inactive_scan(DEF_PRIORITY, 0); - - /* Once a second, recalculate some VM stats. */ + /* Once a second ... */ if (time_after(jiffies, recalc + HZ)) { recalc = jiffies; + + /* Recalculate VM statistics. */ recalculate_vm_stats(); + + /* Do background page aging. */ + refill_inactive_scan(DEF_PRIORITY, 0); } run_task_queue(&tq_disk); diff --git a/net/README b/net/README index cacc02146c64..5056fbac6e0c 100644 --- a/net/README +++ b/net/README @@ -5,7 +5,7 @@ Code Section Bug Report Contact -------------------+------------------------------------------- 802 [other ] alan@lxorguk.ukuu.org.uk [token ring ] p.norton@computer.org -appletalk jschlst@turbolinux.com +appletalk jschlst@samba.org ax25 g4klx@g4klx.demon.co.uk bridge buytenh@gnu.org core alan@lxorguk.ukuu.org.uk @@ -13,7 +13,8 @@ decnet SteveW@ACM.org ethernet alan@lxorguk.ukuu.org.uk ipv4 davem@caip.rutgers.edu,Eric.Schenk@dna.lth.se ipv6 davem@caip.rutgers.edu,Eric.Schenk@dna.lth.se -ipx/spx jschlst@turbolinux.com +ipx acme@conectiva.com.br +spx jschlst@samba.org irda dagb@cs.uit.no lapb g4klx@g4klx.demon.co.uk netrom g4klx@g4klx.demon.co.uk diff --git a/net/atm/mpoa_proc.c b/net/atm/mpoa_proc.c index bc04ecc67be0..c2bc7896893a 100644 --- a/net/atm/mpoa_proc.c +++ b/net/atm/mpoa_proc.c @@ -175,7 +175,7 @@ static ssize_t proc_mpc_write(struct file *file, const char *buff, if (nbytes < 0) return -EINVAL; if (nbytes == 0) return 0; - if (nbytes > PAGE_SIZE) nbytes = PAGE_SIZE-1; + if (nbytes >= PAGE_SIZE) nbytes = PAGE_SIZE-1; error = verify_area(VERIFY_READ, buff, nbytes); if (error) return error; diff --git a/net/core/dev.c b/net/core/dev.c index 646044fda78e..00a171a0522e 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -400,7 +400,7 @@ struct net_device *__dev_get_by_name(const char *name) struct net_device *dev; for (dev = dev_base; dev != NULL; dev = dev->next) { - if (strcmp(dev->name, name) == 0) + if (strncmp(dev->name, name, IFNAMSIZ) == 0) return dev; } return NULL; diff --git a/net/core/filter.c b/net/core/filter.c index aba32a59f26c..bfa23ac6348e 100644 --- a/net/core/filter.c +++ b/net/core/filter.c @@ -2,7 +2,7 @@ * Linux Socket Filter - Kernel level socket filtering * * Author: - * Jay Schulist + * Jay Schulist * * Based on the design of: * - The Berkeley Packet Filter @@ -382,6 +382,9 @@ int sk_chk_filter(struct sock_filter *filter, int flen) struct sock_filter *ftest; int pc; + if ((unsigned int) flen >= (~0U / sizeof(struct sock_filter))) + return -EINVAL; + /* * Check the filter code now. */ @@ -404,7 +407,7 @@ int sk_chk_filter(struct sock_filter *filter, int flen) jumps below, where offsets are limited. --ANK (981016) */ if (ftest->k >= (unsigned)(flen-pc-1)) - return (-EINVAL); + return -EINVAL; } else { @@ -412,7 +415,7 @@ int sk_chk_filter(struct sock_filter *filter, int flen) * For conditionals both must be safe */ if(pc + ftest->jt +1 >= flen || pc + ftest->jf +1 >= flen) - return (-EINVAL); + return -EINVAL; } } diff --git a/net/ipv4/arp.c b/net/ipv4/arp.c index c569e6172473..81d5e033dc43 100644 --- a/net/ipv4/arp.c +++ b/net/ipv4/arp.c @@ -1,6 +1,6 @@ /* linux/net/inet/arp.c * - * Version: $Id: arp.c,v 1.97 2001/04/30 04:36:12 davem Exp $ + * Version: $Id: arp.c,v 1.98 2001/05/16 16:45:35 davem Exp $ * * Copyright (C) 1994 by Florian La Roche * @@ -345,6 +345,22 @@ static void arp_solicit(struct neighbour *neigh, struct sk_buff *skb) read_unlock_bh(&neigh->lock); } +static int arp_filter(__u32 sip, __u32 tip, struct net_device *dev) +{ + struct rtable *rt; + int flag = 0; + /*unsigned long now; */ + + if (ip_route_output(&rt, sip, tip, 0, 0) < 0) + return 1; + if (rt->u.dst.dev != dev) { + NET_INC_STATS_BH(ArpFilter); + flag = 1; + } + ip_rt_put(rt); + return flag; +} + /* OBSOLETE FUNCTIONS */ /* @@ -741,7 +757,12 @@ int arp_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt) if (addr_type == RTN_LOCAL) { n = neigh_event_ns(&arp_tbl, sha, &sip, dev); if (n) { - arp_send(ARPOP_REPLY,ETH_P_ARP,sip,dev,tip,sha,dev->dev_addr,sha); + int dont_send = 0; + if (IN_DEV_ARPFILTER(in_dev)) + dont_send |= arp_filter(sip,tip,dev); + if (!dont_send) + arp_send(ARPOP_REPLY,ETH_P_ARP,sip,dev,tip,sha,dev->dev_addr,sha); + neigh_release(n); } goto out; diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c index e35e0d6cbbf3..ac62692297c0 100644 --- a/net/ipv4/devinet.c +++ b/net/ipv4/devinet.c @@ -1,7 +1,7 @@ /* * NET3 IP device support routines. * - * Version: $Id: devinet.c,v 1.41 2001/02/18 09:26:26 davem Exp $ + * Version: $Id: devinet.c,v 1.42 2001/05/16 16:45:35 davem Exp $ * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -1016,7 +1016,7 @@ int devinet_sysctl_forward(ctl_table *ctl, int write, struct file * filp, static struct devinet_sysctl_table { struct ctl_table_header *sysctl_header; - ctl_table devinet_vars[13]; + ctl_table devinet_vars[14]; ctl_table devinet_dev[2]; ctl_table devinet_conf_dir[2]; ctl_table devinet_proto_dir[2]; @@ -1059,6 +1059,9 @@ static struct devinet_sysctl_table {NET_IPV4_CONF_TAG, "tag", &ipv4_devconf.tag, sizeof(int), 0644, NULL, &proc_dointvec}, + {NET_IPV4_CONF_ARPFILTER, "arp_filter", + &ipv4_devconf.arp_filter, sizeof(int), 0644, NULL, + &proc_dointvec}, {0}}, {{NET_PROTO_CONF_ALL, "all", NULL, 0, 0555, devinet_sysctl.devinet_vars},{0}}, diff --git a/net/ipv4/fib_frontend.c b/net/ipv4/fib_frontend.c index c86e162fc022..f70b04cb507d 100644 --- a/net/ipv4/fib_frontend.c +++ b/net/ipv4/fib_frontend.c @@ -5,7 +5,7 @@ * * IPv4 Forwarding Information Base: FIB frontend. * - * Version: $Id: fib_frontend.c,v 1.23 2001/05/01 23:21:37 davem Exp $ + * Version: $Id: fib_frontend.c,v 1.24 2001/05/13 18:14:46 davem Exp $ * * Authors: Alexey Kuznetsov, * @@ -569,9 +569,9 @@ static void fib_del_ifaddr(struct in_ifaddr *ifa) #undef BRD1_OK } -static void fib_disable_ip(struct net_device *dev, u32 addr, int force) +static void fib_disable_ip(struct net_device *dev, int force) { - if (fib_sync_down(addr, dev, force)) + if (fib_sync_down(0, dev, force)) fib_flush(); rt_cache_flush(0); arp_ifdown(dev); @@ -587,13 +587,13 @@ static int fib_inetaddr_event(struct notifier_block *this, unsigned long event, rt_cache_flush(-1); break; case NETDEV_DOWN: + fib_del_ifaddr(ifa); if (ifa->ifa_dev && ifa->ifa_dev->ifa_list == NULL) { /* Last address was deleted from this interface. Disable IP. */ - fib_disable_ip(ifa->ifa_dev->dev, ifa->ifa_local, 1); + fib_disable_ip(ifa->ifa_dev->dev, 1); } else { - fib_del_ifaddr(ifa); rt_cache_flush(-1); } break; @@ -620,10 +620,10 @@ static int fib_netdev_event(struct notifier_block *this, unsigned long event, vo rt_cache_flush(-1); break; case NETDEV_DOWN: - fib_disable_ip(dev, 0, 0); + fib_disable_ip(dev, 0); break; case NETDEV_UNREGISTER: - fib_disable_ip(dev, 0, 1); + fib_disable_ip(dev, 1); break; case NETDEV_CHANGEMTU: case NETDEV_CHANGE: diff --git a/net/ipv4/icmp.c b/net/ipv4/icmp.c index a6d084b36fcd..d07b82f2e322 100644 --- a/net/ipv4/icmp.c +++ b/net/ipv4/icmp.c @@ -3,7 +3,7 @@ * * Alan Cox, * - * Version: $Id: icmp.c,v 1.75 2001/04/30 04:40:40 davem Exp $ + * Version: $Id: icmp.c,v 1.76 2001/05/10 01:20:58 davem Exp $ * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -1006,6 +1006,7 @@ void __init icmp_init(struct net_proto_family *ops) icmp_socket->sk->allocation=GFP_ATOMIC; icmp_socket->sk->sndbuf = SK_WMEM_MAX*2; icmp_socket->sk->protinfo.af_inet.ttl = MAXTTL; + icmp_socket->sk->protinfo.af_inet.pmtudisc = IP_PMTUDISC_DONT; /* Unhash it so that IP input processing does not even * see it, we do not wish this socket to see incoming diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c index 10ee3b7e0ddb..fd7b3d226b58 100644 --- a/net/ipv4/ip_gre.c +++ b/net/ipv4/ip_gre.c @@ -273,6 +273,7 @@ static struct ip_tunnel * ipgre_tunnel_locate(struct ip_tunnel_parm *parms, int dev->init = ipgre_tunnel_init; dev->features |= NETIF_F_DYNALLOC; memcpy(&nt->parms, parms, sizeof(*parms)); + nt->parms.name[IFNAMSIZ-1] = '\0'; strcpy(dev->name, nt->parms.name); if (dev->name[0] == 0) { int i; diff --git a/net/ipv4/ipip.c b/net/ipv4/ipip.c index 7c81d7321280..cf01c76e7d15 100644 --- a/net/ipv4/ipip.c +++ b/net/ipv4/ipip.c @@ -244,6 +244,7 @@ struct ip_tunnel * ipip_tunnel_locate(struct ip_tunnel_parm *parms, int create) dev->init = ipip_tunnel_init; dev->features |= NETIF_F_DYNALLOC; memcpy(&nt->parms, parms, sizeof(*parms)); + nt->parms.name[IFNAMSIZ-1] = '\0'; strcpy(dev->name, nt->parms.name); if (dev->name[0] == 0) { int i; diff --git a/net/ipv4/netfilter/ip_nat_core.c b/net/ipv4/netfilter/ip_nat_core.c index daece0d6286c..79d533aae138 100644 --- a/net/ipv4/netfilter/ip_nat_core.c +++ b/net/ipv4/netfilter/ip_nat_core.c @@ -890,13 +890,14 @@ int __init ip_nat_init(void) } /* Clear NAT section of all conntracks, in case we're loaded again. */ -static int __exit clean_nat(const struct ip_conntrack *i, void *data) +static int clean_nat(const struct ip_conntrack *i, void *data) { memset((void *)&i->nat, 0, sizeof(i->nat)); return 0; } -void __exit ip_nat_cleanup(void) +/* Not __exit: called from ip_nat_standalone.c:init_or_cleanup() --RR */ +void ip_nat_cleanup(void) { ip_ct_selective_cleanup(&clean_nat, NULL); ip_conntrack_destroyed = NULL; diff --git a/net/ipv4/netfilter/ip_tables.c b/net/ipv4/netfilter/ip_tables.c index 2e8201e78103..4b0dd3dd2f03 100644 --- a/net/ipv4/netfilter/ip_tables.c +++ b/net/ipv4/netfilter/ip_tables.c @@ -1243,6 +1243,7 @@ do_ipt_get_ctl(struct sock *sk, int cmd, void *user, int *len) ret = -EFAULT; break; } + name[IPT_TABLE_MAXNAMELEN-1] = '\0'; t = find_table_lock(name, &ret, &ipt_mutex); if (t) { struct ipt_getinfo info; diff --git a/net/ipv4/proc.c b/net/ipv4/proc.c index 559d75aac4ec..1c5a674de341 100644 --- a/net/ipv4/proc.c +++ b/net/ipv4/proc.c @@ -7,7 +7,7 @@ * PROC file system. It is mainly used for debugging and * statistics. * - * Version: $Id: proc.c,v 1.44 2000/08/09 11:59:04 davem Exp $ + * Version: $Id: proc.c,v 1.45 2001/05/16 16:45:35 davem Exp $ * * Authors: Fred N. van Kempen, * Gerald J. Heim, @@ -170,7 +170,7 @@ int netstat_get_info(char *buffer, char **start, off_t offset, int length) len = sprintf(buffer, "TcpExt: SyncookiesSent SyncookiesRecv SyncookiesFailed" " EmbryonicRsts PruneCalled RcvPruned OfoPruned" - " OutOfWindowIcmps LockDroppedIcmps" + " OutOfWindowIcmps LockDroppedIcmps ArpFilter" " TW TWRecycled TWKilled" " PAWSPassive PAWSActive PAWSEstab" " DelayedACKs DelayedACKLocked DelayedACKLost" diff --git a/net/ipv4/raw.c b/net/ipv4/raw.c index 44e71997f297..e8cf36d2e12c 100644 --- a/net/ipv4/raw.c +++ b/net/ipv4/raw.c @@ -5,7 +5,7 @@ * * RAW - implementation of IP "raw" sockets. * - * Version: $Id: raw.c,v 1.60 2001/02/23 06:32:11 davem Exp $ + * Version: $Id: raw.c,v 1.61 2001/05/03 20:56:04 davem Exp $ * * Authors: Ross Biro, * Fred N. van Kempen, @@ -14,8 +14,9 @@ * Alan Cox : verify_area() fixed up * Alan Cox : ICMP error handling * Alan Cox : EMSGSIZE if you send too big a packet - * Alan Cox : Now uses generic datagrams and shared skbuff - * library. No more peek crashes, no more backlogs + * Alan Cox : Now uses generic datagrams and shared + * skbuff library. No more peek crashes, + * no more backlogs * Alan Cox : Checks sk->broadcast. * Alan Cox : Uses skb_free_datagram/skb_copy_datagram * Alan Cox : Raw passes ip options too @@ -101,11 +102,11 @@ struct sock *__raw_v4_lookup(struct sock *sk, unsigned short num, { struct sock *s = sk; - for(s = sk; s; s = s->next) { - if((s->num == num) && - !(s->daddr && s->daddr != raddr) && - !(s->rcv_saddr && s->rcv_saddr != laddr) && - !(s->bound_dev_if && s->bound_dev_if != dif)) + for (s = sk; s; s = s->next) { + if (s->num == num && + !(s->daddr && s->daddr != raddr) && + !(s->rcv_saddr && s->rcv_saddr != laddr) && + !(s->bound_dev_if && s->bound_dev_if != dif)) break; /* gotcha */ } return s; @@ -117,7 +118,7 @@ struct sock *__raw_v4_lookup(struct sock *sk, unsigned short num, */ static __inline__ int icmp_filter(struct sock *sk, struct sk_buff *skb) { - int type; + int type; type = skb->h.icmph->type; if (type < 32) @@ -145,19 +146,19 @@ struct sock *raw_v4_input(struct sk_buff *skb, struct iphdr *iph, int hash) iph->saddr, iph->daddr, skb->dev->ifindex); - while(sk != NULL) { + while (sk) { struct sock *sknext = __raw_v4_lookup(sk->next, iph->protocol, iph->saddr, iph->daddr, skb->dev->ifindex); if (iph->protocol != IPPROTO_ICMP || - ! icmp_filter(sk, skb)) { + !icmp_filter(sk, skb)) { struct sk_buff *clone; - if(sknext == NULL) + if (!sknext) break; clone = skb_clone(skb, GFP_ATOMIC); /* Not releasing hash table! */ - if(clone) + if (clone) raw_rcv(sk, clone); } sk = sknext; @@ -203,14 +204,15 @@ void raw_err (struct sock *sk, struct sk_buff *skb, u32 info) err = icmp_err_convert[code].errno; harderr = icmp_err_convert[code].fatal; if (code == ICMP_FRAG_NEEDED) { - harderr = (sk->protinfo.af_inet.pmtudisc != IP_PMTUDISC_DONT); + harderr = sk->protinfo.af_inet.pmtudisc != + IP_PMTUDISC_DONT; err = EMSGSIZE; } } if (sk->protinfo.af_inet.recverr) { struct iphdr *iph = (struct iphdr*)skb->data; - u8 *payload = skb->data+(iph->ihl<<2); + u8 *payload = skb->data + (iph->ihl << 2); if (sk->protinfo.af_inet.hdrincl) payload = skb->data; @@ -227,8 +229,7 @@ static int raw_rcv_skb(struct sock * sk, struct sk_buff * skb) { /* Charge it to the socket. */ - if (sock_queue_rcv_skb(sk,skb)<0) - { + if (sock_queue_rcv_skb(sk, skb) < 0) { IP_INC_STATS(IpInDiscards); kfree_skb(skb); return NET_RX_DROP; @@ -240,7 +241,7 @@ static int raw_rcv_skb(struct sock * sk, struct sk_buff * skb) int raw_rcv(struct sock *sk, struct sk_buff *skb) { - skb_push(skb, skb->data-skb->nh.raw); + skb_push(skb, skb->data - skb->nh.raw); raw_rcv_skb(sk, skb); return 0; @@ -248,9 +249,9 @@ int raw_rcv(struct sock *sk, struct sk_buff *skb) struct rawfakehdr { - struct iovec *iov; + struct iovec *iov; u32 saddr; - struct dst_entry *dst; + struct dst_entry *dst; }; /* @@ -261,7 +262,8 @@ struct rawfakehdr * Callback support is trivial for SOCK_RAW */ -static int raw_getfrag(const void *p, char *to, unsigned int offset, unsigned int fraglen) +static int raw_getfrag(const void *p, char *to, unsigned int offset, + unsigned int fraglen) { struct rawfakehdr *rfh = (struct rawfakehdr *) p; return memcpy_fromiovecend(to, rfh->iov, offset, fraglen); @@ -271,27 +273,28 @@ static int raw_getfrag(const void *p, char *to, unsigned int offset, unsigned in * IPPROTO_RAW needs extra work. */ -static int raw_getrawfrag(const void *p, char *to, unsigned int offset, unsigned int fraglen) +static int raw_getrawfrag(const void *p, char *to, unsigned int offset, + unsigned int fraglen) { struct rawfakehdr *rfh = (struct rawfakehdr *) p; if (memcpy_fromiovecend(to, rfh->iov, offset, fraglen)) return -EFAULT; - if (offset==0) { + if (!offset) { struct iphdr *iph = (struct iphdr *)to; if (!iph->saddr) iph->saddr = rfh->saddr; - iph->check=0; - iph->tot_len=htons(fraglen); /* This is right as you can't frag - RAW packets */ + iph->check = 0; + iph->tot_len = htons(fraglen); /* This is right as you can't + frag RAW packets */ /* * Deliberate breach of modularity to keep * ip_build_xmit clean (well less messy). */ if (!iph->id) ip_select_ident(iph, rfh->dst, NULL); - iph->check=ip_fast_csum((unsigned char *)iph, iph->ihl); + iph->check = ip_fast_csum((unsigned char *)iph, iph->ihl); } return 0; } @@ -317,15 +320,17 @@ static int raw_sendmsg(struct sock *sk, struct msghdr *msg, int len) If len was ULONG_MAX-10 it would be cathastrophe --ANK */ + err = -EMSGSIZE; if (len < 0 || len > 0xFFFF) - return -EMSGSIZE; + goto out; /* * Check the flags. */ - if (msg->msg_flags & MSG_OOB) /* Mirror BSD error message compatibility */ - return -EOPNOTSUPP; + err = -EOPNOTSUPP; + if (msg->msg_flags & MSG_OOB) /* Mirror BSD error message */ + goto out; /* compatibility */ /* * Get and verify the address. @@ -333,14 +338,18 @@ static int raw_sendmsg(struct sock *sk, struct msghdr *msg, int len) if (msg->msg_namelen) { struct sockaddr_in *usin = (struct sockaddr_in*)msg->msg_name; + err = -EINVAL; if (msg->msg_namelen < sizeof(*usin)) - return(-EINVAL); + goto out; if (usin->sin_family != AF_INET) { static int complained; if (!complained++) - printk(KERN_INFO "%s forgot to set AF_INET in raw sendmsg. Fix it!\n", current->comm); + printk(KERN_INFO "%s forgot to set AF_INET in " + "raw sendmsg. Fix it!\n", + current->comm); + err = -EINVAL; if (usin->sin_family) - return -EINVAL; + goto out; } daddr = usin->sin_addr.s_addr; /* ANK: I did not forget to get protocol from port field. @@ -348,8 +357,9 @@ static int raw_sendmsg(struct sock *sk, struct msghdr *msg, int len) * IP_HDRINCL is much more convenient. */ } else { + err = -EINVAL; if (sk->state != TCP_ESTABLISHED) - return(-EINVAL); + goto out; daddr = sk->daddr; } @@ -358,11 +368,11 @@ static int raw_sendmsg(struct sock *sk, struct msghdr *msg, int len) ipc.oif = sk->bound_dev_if; if (msg->msg_controllen) { - int tmp = ip_cmsg_send(msg, &ipc); - if (tmp) - return tmp; + err = ip_cmsg_send(msg, &ipc); + if (err) + goto out; if (ipc.opt) - free=1; + free = 1; } rfh.saddr = ipc.addr; @@ -385,7 +395,7 @@ static int raw_sendmsg(struct sock *sk, struct msghdr *msg, int len) } } tos = RT_TOS(sk->protinfo.af_inet.tos) | sk->localroute; - if (msg->msg_flags&MSG_DONTROUTE) + if (msg->msg_flags & MSG_DONTROUTE) tos |= RTO_ONLINK; if (MULTICAST(daddr)) { @@ -401,31 +411,31 @@ static int raw_sendmsg(struct sock *sk, struct msghdr *msg, int len) goto done; err = -EACCES; - if (rt->rt_flags&RTCF_BROADCAST && !sk->broadcast) + if (rt->rt_flags & RTCF_BROADCAST && !sk->broadcast) goto done; - if (msg->msg_flags&MSG_CONFIRM) + if (msg->msg_flags & MSG_CONFIRM) goto do_confirm; back_from_confirm: - rfh.iov = msg->msg_iov; - rfh.saddr = rt->rt_src; - rfh.dst = &rt->u.dst; + rfh.iov = msg->msg_iov; + rfh.saddr = rt->rt_src; + rfh.dst = &rt->u.dst; if (!ipc.addr) ipc.addr = rt->rt_dst; - err=ip_build_xmit(sk, sk->protinfo.af_inet.hdrincl ? raw_getrawfrag : raw_getfrag, - &rfh, len, &ipc, rt, msg->msg_flags); + err = ip_build_xmit(sk, sk->protinfo.af_inet.hdrincl ? raw_getrawfrag : + raw_getfrag, &rfh, len, &ipc, rt, msg->msg_flags); done: if (free) kfree(ipc.opt); ip_rt_put(rt); - return err<0 ? err : len; +out: return err < 0 ? err : len; do_confirm: dst_confirm(&rt->u.dst); - if (!(msg->msg_flags&MSG_PROBE) || len) + if (!(msg->msg_flags & MSG_PROBE) || len) goto back_from_confirm; err = 0; goto done; @@ -445,19 +455,22 @@ static void raw_close(struct sock *sk, long timeout) static int raw_bind(struct sock *sk, struct sockaddr *uaddr, int addr_len) { struct sockaddr_in *addr = (struct sockaddr_in *) uaddr; + int ret = -EINVAL; int chk_addr_ret; - if((sk->state != TCP_CLOSE) || (addr_len < sizeof(struct sockaddr_in))) - return -EINVAL; + if (sk->state != TCP_CLOSE || addr_len < sizeof(struct sockaddr_in)) + goto out; chk_addr_ret = inet_addr_type(addr->sin_addr.s_addr); - if(addr->sin_addr.s_addr != 0 && chk_addr_ret != RTN_LOCAL && - chk_addr_ret != RTN_MULTICAST && chk_addr_ret != RTN_BROADCAST) - return -EADDRNOTAVAIL; + ret = -EADDRNOTAVAIL; + if (addr->sin_addr.s_addr && chk_addr_ret != RTN_LOCAL && + chk_addr_ret != RTN_MULTICAST && chk_addr_ret != RTN_BROADCAST) + goto out; sk->rcv_saddr = sk->saddr = addr->sin_addr.s_addr; - if(chk_addr_ret == RTN_MULTICAST || chk_addr_ret == RTN_BROADCAST) + if (chk_addr_ret == RTN_MULTICAST || chk_addr_ret == RTN_BROADCAST) sk->saddr = 0; /* Use device */ sk_dst_reset(sk); - return 0; + ret = 0; +out: return ret; } /* @@ -466,29 +479,30 @@ static int raw_bind(struct sock *sk, struct sockaddr *uaddr, int addr_len) */ int raw_recvmsg(struct sock *sk, struct msghdr *msg, int len, - int noblock, int flags,int *addr_len) + int noblock, int flags, int *addr_len) { - int copied=0; + int copied = 0; + int err = -EOPNOTSUPP; + struct sockaddr_in *sin = (struct sockaddr_in *)msg->msg_name; struct sk_buff *skb; - int err; - struct sockaddr_in *sin=(struct sockaddr_in *)msg->msg_name; if (flags & MSG_OOB) - return -EOPNOTSUPP; + goto out; if (addr_len) - *addr_len=sizeof(*sin); + *addr_len = sizeof(*sin); - if (flags & MSG_ERRQUEUE) - return ip_recv_error(sk, msg, len); + if (flags & MSG_ERRQUEUE) { + err = ip_recv_error(sk, msg, len); + goto out; + } - skb=skb_recv_datagram(sk,flags,noblock,&err); - if(skb==NULL) - return err; + skb = skb_recv_datagram(sk, flags, noblock, &err); + if (!skb) + goto out; copied = skb->len; - if (len < copied) - { + if (len < copied) { msg->msg_flags |= MSG_TRUNC; copied = len; } @@ -508,7 +522,7 @@ int raw_recvmsg(struct sock *sk, struct msghdr *msg, int len, ip_cmsg_recv(msg, skb); done: skb_free_datagram(sk, skb); - return (err ? : copied); +out: return err ? : copied; } static int raw_init(struct sock *sk) @@ -530,19 +544,21 @@ static int raw_seticmpfilter(struct sock *sk, char *optval, int optlen) static int raw_geticmpfilter(struct sock *sk, char *optval, int *optlen) { - int len; + int len, ret = -EFAULT; - if (get_user(len,optlen)) - return -EFAULT; + if (get_user(len, optlen)) + goto out; + ret = -EINVAL; if (len < 0) - return -EINVAL; + goto out; if (len > sizeof(struct icmp_filter)) len = sizeof(struct icmp_filter); - if (put_user(len, optlen)) - return -EFAULT; - if (copy_to_user(optval, &sk->tp_pinfo.tp_raw4.filter, len)) - return -EFAULT; - return 0; + ret = -EFAULT; + if (put_user(len, optlen) || + copy_to_user(optval, &sk->tp_pinfo.tp_raw4.filter, len)) + goto out; + ret = 0; +out: return ret; } static int raw_setsockopt(struct sock *sk, int level, int optname, @@ -551,13 +567,12 @@ static int raw_setsockopt(struct sock *sk, int level, int optname, if (level != SOL_RAW) return ip_setsockopt(sk, level, optname, optval, optlen); - switch (optname) { - case ICMP_FILTER: + if (optname == ICMP_FILTER) { if (sk->num != IPPROTO_ICMP) return -EOPNOTSUPP; - return raw_seticmpfilter(sk, optval, optlen); - }; - + else + return raw_seticmpfilter(sk, optval, optlen); + } return -ENOPROTOOPT; } @@ -567,26 +582,23 @@ static int raw_getsockopt(struct sock *sk, int level, int optname, if (level != SOL_RAW) return ip_getsockopt(sk, level, optname, optval, optlen); - switch (optname) { - case ICMP_FILTER: + if (optname == ICMP_FILTER) { if (sk->num != IPPROTO_ICMP) return -EOPNOTSUPP; - return raw_geticmpfilter(sk, optval, optlen); - }; - + else + return raw_geticmpfilter(sk, optval, optlen); + } return -ENOPROTOOPT; } static int raw_ioctl(struct sock *sk, int cmd, unsigned long arg) { - switch(cmd) { - case SIOCOUTQ: - { + switch (cmd) { + case SIOCOUTQ: { int amount = atomic_read(&sk->wmem_alloc); return put_user(amount, (int *)arg); } - case SIOCINQ: - { + case SIOCINQ: { struct sk_buff *skb; int amount = 0; @@ -609,13 +621,11 @@ static int raw_ioctl(struct sock *sk, int cmd, unsigned long arg) static void get_raw_sock(struct sock *sp, char *tmpbuf, int i) { - unsigned int dest, src; - __u16 destp, srcp; + unsigned int dest = sp->daddr, + src = sp->rcv_saddr; + __u16 destp = 0, + srcp = sp->num; - dest = sp->daddr; - src = sp->rcv_saddr; - destp = 0; - srcp = sp->num; sprintf(tmpbuf, "%4d: %08X:%04X %08X:%04X" " %02X %08X:%08X %02X:%08lX %08X %5d %8d %ld %d %p", i, src, srcp, dest, destp, sp->state, @@ -629,15 +639,15 @@ static void get_raw_sock(struct sock *sp, char *tmpbuf, int i) int raw_get_info(char *buffer, char **start, off_t offset, int length) { int len = 0, num = 0, i; - off_t pos = 0; + off_t pos = 128; off_t begin; char tmpbuf[129]; if (offset < 128) len += sprintf(buffer, "%-127s\n", " sl local_address rem_address st tx_queue " - "rx_queue tr tm->when retrnsmt uid timeout inode"); - pos = 128; + "rx_queue tr tm->when retrnsmt uid timeout " + "inode"); read_lock(&raw_v4_lock); for (i = 0; i < RAWV4_HTABLE_SIZE; i++) { struct sock *sk; @@ -649,8 +659,8 @@ int raw_get_info(char *buffer, char **start, off_t offset, int length) if (pos <= offset) continue; get_raw_sock(sk, tmpbuf, i); - len += sprintf(buffer+len, "%-127s\n", tmpbuf); - if(len >= length) + len += sprintf(buffer + len, "%-127s\n", tmpbuf); + if (len >= length) goto out; } } @@ -659,7 +669,7 @@ out: begin = len - (pos - offset); *start = buffer + begin; len -= begin; - if(len > length) + if (len > length) len = length; if (len < 0) len = 0; diff --git a/net/ipv4/route.c b/net/ipv4/route.c index 0c3ee2b93cbc..1918305e86fd 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c @@ -5,7 +5,7 @@ * * ROUTE - implementation of the IP router. * - * Version: $Id: route.c,v 1.93 2001/02/22 01:03:05 davem Exp $ + * Version: $Id: route.c,v 1.94 2001/05/05 01:01:02 davem Exp $ * * Authors: Ross Biro, * Fred N. van Kempen, @@ -101,21 +101,21 @@ #define RT_GC_TIMEOUT (300*HZ) -int ip_rt_min_delay = 2*HZ; -int ip_rt_max_delay = 10*HZ; +int ip_rt_min_delay = 2 * HZ; +int ip_rt_max_delay = 10 * HZ; int ip_rt_max_size; -int ip_rt_gc_timeout = RT_GC_TIMEOUT; -int ip_rt_gc_interval = 60*HZ; -int ip_rt_gc_min_interval = 5*HZ; -int ip_rt_redirect_number = 9; -int ip_rt_redirect_load = HZ/50; -int ip_rt_redirect_silence = ((HZ/50) << (9+1)); -int ip_rt_error_cost = HZ; -int ip_rt_error_burst = 5*HZ; -int ip_rt_gc_elasticity = 8; -int ip_rt_mtu_expires = 10*60*HZ; -int ip_rt_min_pmtu = 512+20+20; -int ip_rt_min_advmss = 256; +int ip_rt_gc_timeout = RT_GC_TIMEOUT; +int ip_rt_gc_interval = 60 * HZ; +int ip_rt_gc_min_interval = 5 * HZ; +int ip_rt_redirect_number = 9; +int ip_rt_redirect_load = HZ / 50; +int ip_rt_redirect_silence = ((HZ / 50) << (9 + 1)); +int ip_rt_error_cost = HZ; +int ip_rt_error_burst = 5 * HZ; +int ip_rt_gc_elasticity = 8; +int ip_rt_mtu_expires = 10 * 60 * HZ; +int ip_rt_min_pmtu = 512 + 20 + 20; +int ip_rt_min_advmss = 256; static unsigned long rt_deadline; @@ -128,28 +128,25 @@ static struct timer_list rt_periodic_timer; * Interface to generic destination cache. */ -static struct dst_entry * ipv4_dst_check(struct dst_entry * dst, u32); -static struct dst_entry * ipv4_dst_reroute(struct dst_entry * dst, - struct sk_buff *); -static void ipv4_dst_destroy(struct dst_entry * dst); -static struct dst_entry * ipv4_negative_advice(struct dst_entry *); -static void ipv4_link_failure(struct sk_buff *skb); +static struct dst_entry *ipv4_dst_check(struct dst_entry *dst, u32 cookie); +static struct dst_entry *ipv4_dst_reroute(struct dst_entry *dst, + struct sk_buff *skb); +static void ipv4_dst_destroy(struct dst_entry *dst); +static struct dst_entry *ipv4_negative_advice(struct dst_entry *dst); +static void ipv4_link_failure(struct sk_buff *skb); static int rt_garbage_collect(void); -struct dst_ops ipv4_dst_ops = -{ - AF_INET, - __constant_htons(ETH_P_IP), - 0, - - rt_garbage_collect, - ipv4_dst_check, - ipv4_dst_reroute, - ipv4_dst_destroy, - ipv4_negative_advice, - ipv4_link_failure, - sizeof(struct rtable), +struct dst_ops ipv4_dst_ops = { + family: AF_INET, + protocol: __constant_htons(ETH_P_IP), + gc: rt_garbage_collect, + check: ipv4_dst_check, + reroute: ipv4_dst_reroute, + destroy: ipv4_dst_destroy, + negative_advice: ipv4_negative_advice, + link_failure: ipv4_link_failure, + entry_size: sizeof(struct rtable), }; #ifdef CONFIG_INET_ECN @@ -201,32 +198,36 @@ static struct rt_hash_bucket *rt_hash_table; static unsigned rt_hash_mask; static int rt_hash_log; -static int rt_intern_hash(unsigned hash, struct rtable * rth, struct rtable ** res); +static int rt_intern_hash(unsigned hash, struct rtable *rth, + struct rtable **res); static __inline__ unsigned rt_hash_code(u32 daddr, u32 saddr, u8 tos) { - unsigned hash = ((daddr&0xF0F0F0F0)>>4)|((daddr&0x0F0F0F0F)<<4); - hash ^= saddr^tos; - hash ^= (hash>>16); - return (hash^(hash>>8)) & rt_hash_mask; + unsigned hash = ((daddr & 0xF0F0F0F0) >> 4) | + ((daddr & 0x0F0F0F0F) << 4); + hash ^= saddr ^ tos; + hash ^= (hash >> 16); + return (hash ^ (hash >> 8)) & rt_hash_mask; } -static int rt_cache_get_info(char *buffer, char **start, off_t offset, int length) +static int rt_cache_get_info(char *buffer, char **start, off_t offset, + int length) { - int len=0; - off_t pos=0; + int len = 0; + off_t pos = 128; char temp[129]; struct rtable *r; int i; - pos = 128; - - if (offset<128) { - sprintf(buffer,"%-127s\n", "Iface\tDestination\tGateway \tFlags\t\tRefCnt\tUse\tMetric\tSource\t\tMTU\tWindow\tIRTT\tTOS\tHHRef\tHHUptod\tSpecDst"); + if (offset < 128) { + sprintf(buffer, "%-127s\n", + "Iface\tDestination\tGateway \tFlags\t\tRefCnt\tUse\t" + "Metric\tSource\t\tMTU\tWindow\tIRTT\tTOS\tHHRef\t" + "HHUptod\tSpecDst"); len = 128; } - for (i = rt_hash_mask; i>=0; i--) { + for (i = rt_hash_mask; i >= 0; i--) { read_lock_bh(&rt_hash_table[i].lock); for (r = rt_hash_table[i].chain; r; r = r->u.rt_next) { /* @@ -238,7 +239,8 @@ static int rt_cache_get_info(char *buffer, char **start, off_t offset, int lengt len = 0; continue; } - sprintf(temp, "%s\t%08lX\t%08lX\t%8X\t%d\t%u\t%d\t%08lX\t%d\t%u\t%u\t%02X\t%d\t%1d\t%08X", + sprintf(temp, "%s\t%08lX\t%08lX\t%8X\t%d\t%u\t%d\t" + "%08lX\t%d\t%u\t%u\t%02X\t%d\t%1d\t%08X", r->u.dst.dev ? r->u.dst.dev->name : "*", (unsigned long)r->rt_dst, (unsigned long)r->rt_gateway, @@ -246,14 +248,19 @@ static int rt_cache_get_info(char *buffer, char **start, off_t offset, int lengt atomic_read(&r->u.dst.__refcnt), r->u.dst.__use, 0, - (unsigned long)r->rt_src, (int)r->u.dst.advmss + 40, + (unsigned long)r->rt_src, + (int)r->u.dst.advmss + 40, r->u.dst.window, - (int)((r->u.dst.rtt>>3) + r->u.dst.rttvar), + (int)((r->u.dst.rtt >> 3) + r->u.dst.rttvar), r->key.tos, - r->u.dst.hh ? atomic_read(&r->u.dst.hh->hh_refcnt) : -1, - r->u.dst.hh ? (r->u.dst.hh->hh_output == dev_queue_xmit) : 0, + r->u.dst.hh ? + atomic_read(&r->u.dst.hh->hh_refcnt) : + -1, + r->u.dst.hh ? + (r->u.dst.hh->hh_output == + dev_queue_xmit) : 0, r->rt_spec_dst); - sprintf(buffer+len,"%-127s\n",temp); + sprintf(buffer + len, "%-127s\n", temp); len += 128; if (pos >= offset+length) { read_unlock_bh(&rt_hash_table[i].lock); @@ -264,9 +271,9 @@ static int rt_cache_get_info(char *buffer, char **start, off_t offset, int lengt } done: - *start = buffer+len-(pos-offset); - len = pos-offset; - if (len>length) + *start = buffer + len - (pos - offset); + len = pos - offset; + if (len > length) len = length; return len; } @@ -286,45 +293,47 @@ static __inline__ int rt_fast_clean(struct rtable *rth) { /* Kill broadcast/multicast entries very aggresively, if they collide in hash table with more useful entries */ - return ((rth->rt_flags&(RTCF_BROADCAST|RTCF_MULTICAST)) - && rth->key.iif && rth->u.rt_next); + return (rth->rt_flags & (RTCF_BROADCAST | RTCF_MULTICAST)) && + rth->key.iif && rth->u.rt_next; } static __inline__ int rt_valuable(struct rtable *rth) { - return ((rth->rt_flags&(RTCF_REDIRECTED|RTCF_NOTIFY)) - || rth->u.dst.expires); + return (rth->rt_flags & (RTCF_REDIRECTED | RTCF_NOTIFY)) || + rth->u.dst.expires; } static __inline__ int rt_may_expire(struct rtable *rth, int tmo1, int tmo2) { int age; + int ret = 0; if (atomic_read(&rth->u.dst.__refcnt)) - return 0; + goto out; + ret = 1; if (rth->u.dst.expires && (long)(rth->u.dst.expires - jiffies) <= 0) - return 1; + goto out; age = jiffies - rth->u.dst.lastuse; - if (age <= tmo1 && !rt_fast_clean(rth)) - return 0; - if (age <= tmo2 && rt_valuable(rth)) - return 0; - return 1; + ret = 0; + if ((age <= tmo1 && !rt_fast_clean(rth)) || + (age <= tmo2 && rt_valuable(rth))) + goto out; + ret = 1; +out: return ret; } /* This runs via a timer and thus is always in BH context. */ static void SMP_TIMER_NAME(rt_check_expire)(unsigned long dummy) { - int i, t; static int rover; + int i = rover, t; struct rtable *rth, **rthp; unsigned long now = jiffies; - i = rover; - - for (t=(ip_rt_gc_interval<=0; t -= ip_rt_gc_timeout) { + for (t = ip_rt_gc_interval << rt_hash_log; t >= 0; + t -= ip_rt_gc_timeout) { unsigned tmo = ip_rt_gc_timeout; i = (i + 1) & rt_hash_mask; @@ -345,9 +354,7 @@ static void SMP_TIMER_NAME(rt_check_expire)(unsigned long dummy) continue; } - /* - * Cleanup aged off entries. - */ + /* Cleanup aged off entries. */ *rthp = rth->u.rt_next; rt_free(rth); } @@ -369,18 +376,18 @@ SMP_TIMER_DEFINE(rt_check_expire, rt_gc_task); static void SMP_TIMER_NAME(rt_run_flush)(unsigned long dummy) { int i; - struct rtable * rth, * next; + struct rtable *rth, *next; rt_deadline = 0; - for (i=rt_hash_mask; i>=0; i--) { + for (i = rt_hash_mask; i >= 0; i--) { write_lock_bh(&rt_hash_table[i].lock); rth = rt_hash_table[i].chain; if (rth) rt_hash_table[i].chain = NULL; write_unlock_bh(&rt_hash_table[i].lock); - for (; rth; rth=next) { + for (; rth; rth = next) { next = rth->u.rt_next; rt_free(rth); } @@ -460,23 +467,24 @@ static int rt_garbage_collect(void) */ if (now - last_gc < ip_rt_gc_min_interval && atomic_read(&ipv4_dst_ops.entries) < ip_rt_max_size) - return 0; + goto out; /* Calculate number of entries, which we want to expire now. */ - goal = atomic_read(&ipv4_dst_ops.entries) - (ip_rt_gc_elasticity< 0) { - equilibrium += min(goal/2, rt_hash_mask+1); + equilibrium += min(goal / 2, rt_hash_mask + 1); goal = atomic_read(&ipv4_dst_ops.entries) - equilibrium; } } else { /* We are in dangerous area. Try to reduce cache really * aggressively. */ - goal = max(goal/2, rt_hash_mask+1); + goal = max(goal / 2, rt_hash_mask + 1); equilibrium = atomic_read(&ipv4_dst_ops.entries) - goal; } @@ -491,7 +499,7 @@ static int rt_garbage_collect(void) do { int i, k; - for (i=rt_hash_mask, k=rover; i>=0; i--) { + for (i = rt_hash_mask, k = rover; i >= 0; i--) { unsigned tmo = expire; k = (k + 1) & rt_hash_mask; @@ -530,15 +538,16 @@ static int rt_garbage_collect(void) expire >>= 1; #if RT_CACHE_DEBUG >= 2 - printk(KERN_DEBUG "expire>> %u %d %d %d\n", expire, atomic_read(&ipv4_dst_ops.entries), goal, i); + printk(KERN_DEBUG "expire>> %u %d %d %d\n", expire, + atomic_read(&ipv4_dst_ops.entries), goal, i); #endif if (atomic_read(&ipv4_dst_ops.entries) < ip_rt_max_size) - return 0; + goto out; } while (!in_softirq() && jiffies - now < 1); if (atomic_read(&ipv4_dst_ops.entries) < ip_rt_max_size) - return 0; + goto out; if (net_ratelimit()) printk("dst cache overflow\n"); return 1; @@ -549,12 +558,13 @@ work_done: atomic_read(&ipv4_dst_ops.entries) < ipv4_dst_ops.gc_thresh) expire = ip_rt_gc_timeout; #if RT_CACHE_DEBUG >= 2 - printk(KERN_DEBUG "expire++ %u %d %d %d\n", expire, atomic_read(&ipv4_dst_ops.entries), goal, rover); + printk(KERN_DEBUG "expire++ %u %d %d %d\n", expire, + atomic_read(&ipv4_dst_ops.entries), goal, rover); #endif - return 0; +out: return 0; } -static int rt_intern_hash(unsigned hash, struct rtable * rt, struct rtable ** rp) +static int rt_intern_hash(unsigned hash, struct rtable *rt, struct rtable **rp) { struct rtable *rth, **rthp; unsigned long now = jiffies; @@ -604,11 +614,11 @@ restart: if (attempts-- > 0) { int saved_elasticity = ip_rt_gc_elasticity; int saved_int = ip_rt_gc_min_interval; - ip_rt_gc_elasticity = 1; - ip_rt_gc_min_interval = 0; + ip_rt_gc_elasticity = 1; + ip_rt_gc_min_interval = 0; rt_garbage_collect(); - ip_rt_gc_min_interval = saved_int; - ip_rt_gc_elasticity = saved_elasticity; + ip_rt_gc_min_interval = saved_int; + ip_rt_gc_elasticity = saved_elasticity; goto restart; } @@ -622,9 +632,10 @@ restart: rt->u.rt_next = rt_hash_table[hash].chain; #if RT_CACHE_DEBUG >= 2 if (rt->u.rt_next) { - struct rtable * trt; - printk("rt_cache @%02x: %u.%u.%u.%u", hash, NIPQUAD(rt->rt_dst)); - for (trt=rt->u.rt_next; trt; trt=trt->u.rt_next) + struct rtable *trt; + printk("rt_cache @%02x: %u.%u.%u.%u", hash, + NIPQUAD(rt->rt_dst)); + for (trt = rt->u.rt_next; trt; trt = trt->u.rt_next) printk(" . %u.%u.%u.%u", NIPQUAD(trt->rt_dst)); printk("\n"); } @@ -687,9 +698,8 @@ void __ip_select_ident(struct iphdr *iph, struct dst_entry *dst) iph->id = htons(inet_getid(rt->peer)); return; } - } else { + } else printk(KERN_DEBUG "rt_bind_peer(0) @%p\n", NET_CALLER(iph)); - } ip_select_fb_ident(iph); } @@ -700,13 +710,13 @@ static void rt_del(unsigned hash, struct rtable *rt) write_lock_bh(&rt_hash_table[hash].lock); ip_rt_put(rt); - for (rthp = &rt_hash_table[hash].chain; *rthp; rthp = &(*rthp)->u.rt_next) { + for (rthp = &rt_hash_table[hash].chain; *rthp; + rthp = &(*rthp)->u.rt_next) if (*rthp == rt) { *rthp = rt->u.rt_next; rt_free(rt); break; } - } write_unlock_bh(&rt_hash_table[hash].lock); } @@ -738,14 +748,16 @@ void ip_rt_redirect(u32 old_gw, u32 daddr, u32 new_gw, goto reject_redirect; } - for (i=0; i<2; i++) { - for (k=0; k<2; k++) { - unsigned hash = rt_hash_code(daddr, skeys[i]^(ikeys[k]<<5), tos); + for (i = 0; i < 2; i++) { + for (k = 0; k < 2; k++) { + unsigned hash = rt_hash_code(daddr, + skeys[i] ^ (ikeys[k] << 5), + tos); rthp=&rt_hash_table[hash].chain; read_lock(&rt_hash_table[hash].lock); - while ( (rth = *rthp) != NULL) { + while ((rth = *rthp) != NULL) { struct rtable *rt; if (rth->key.dst != daddr || @@ -774,23 +786,21 @@ void ip_rt_redirect(u32 old_gw, u32 daddr, u32 new_gw, return; } - /* - * Copy all the information. - */ + /* Copy all the information. */ *rt = *rth; - rt->u.dst.__use = 1; + rt->u.dst.__use = 1; atomic_set(&rt->u.dst.__refcnt, 1); if (rt->u.dst.dev) dev_hold(rt->u.dst.dev); - rt->u.dst.lastuse = jiffies; - rt->u.dst.neighbour = NULL; - rt->u.dst.hh = NULL; - rt->u.dst.obsolete = 0; + rt->u.dst.lastuse = jiffies; + rt->u.dst.neighbour = NULL; + rt->u.dst.hh = NULL; + rt->u.dst.obsolete = 0; - rt->rt_flags |= RTCF_REDIRECTED; + rt->rt_flags |= RTCF_REDIRECTED; /* Gateway is different ... */ - rt->rt_gateway = new_gw; + rt->rt_gateway = new_gw; /* Redirect received -> path was valid */ dst_confirm(&rth->u.dst); @@ -799,7 +809,8 @@ void ip_rt_redirect(u32 old_gw, u32 daddr, u32 new_gw, atomic_inc(&rt->peer->refcnt); if (arp_bind_neighbour(&rt->u.dst) || - !(rt->u.dst.neighbour->nud_state&NUD_VALID)) { + !(rt->u.dst.neighbour->nud_state & + NUD_VALID)) { if (rt->u.dst.neighbour) neigh_event_send(rt->u.dst.neighbour, NULL); ip_rt_put(rth); @@ -823,8 +834,10 @@ void ip_rt_redirect(u32 old_gw, u32 daddr, u32 new_gw, reject_redirect: #ifdef CONFIG_IP_ROUTE_VERBOSE if (IN_DEV_LOG_MARTIANS(in_dev) && net_ratelimit()) - printk(KERN_INFO "Redirect from %u.%u.%u.%u on %s about %u.%u.%u.%u ignored.\n" - " Advised path = %u.%u.%u.%u -> %u.%u.%u.%u, tos %02x\n", + printk(KERN_INFO "Redirect from %u.%u.%u.%u on %s about " + "%u.%u.%u.%u ignored.\n" + " Advised path = %u.%u.%u.%u -> %u.%u.%u.%u, " + "tos %02x\n", NIPQUAD(old_gw), dev->name, NIPQUAD(new_gw), NIPQUAD(saddr), NIPQUAD(daddr), tos); #endif @@ -834,23 +847,28 @@ reject_redirect: static struct dst_entry *ipv4_negative_advice(struct dst_entry *dst) { struct rtable *rt = (struct rtable*)dst; + struct dst_entry *ret = dst; - if (rt != NULL) { + if (rt) { if (dst->obsolete) { ip_rt_put(rt); - return NULL; - } - if ((rt->rt_flags&RTCF_REDIRECTED) || rt->u.dst.expires) { - unsigned hash = rt_hash_code(rt->key.dst, rt->key.src^(rt->key.oif<<5), rt->key.tos); + ret = NULL; + } else if ((rt->rt_flags & RTCF_REDIRECTED) || + rt->u.dst.expires) { + unsigned hash = rt_hash_code(rt->key.dst, + rt->key.src ^ + (rt->key.oif << 5), + rt->key.tos); #if RT_CACHE_DEBUG >= 1 - printk(KERN_DEBUG "ip_rt_advice: redirect to %u.%u.%u.%u/%02x dropped\n", + printk(KERN_DEBUG "ip_rt_advice: redirect to " + "%u.%u.%u.%u/%02x dropped\n", NIPQUAD(rt->rt_dst), rt->key.tos); #endif rt_del(hash, rt); - return NULL; + ret = NULL; } } - return dst; + return ret; } /* @@ -897,15 +915,17 @@ void ip_rt_send_redirect(struct sk_buff *skb) /* Check for load limit; set rate_last to the latest sent * redirect. */ - if (jiffies - rt->u.dst.rate_last > (ip_rt_redirect_load<u.dst.rate_tokens)) { + if (jiffies - rt->u.dst.rate_last > + (ip_rt_redirect_load << rt->u.dst.rate_tokens)) { icmp_send(skb, ICMP_REDIRECT, ICMP_REDIR_HOST, rt->rt_gateway); rt->u.dst.rate_last = jiffies; ++rt->u.dst.rate_tokens; #ifdef CONFIG_IP_ROUTE_VERBOSE if (IN_DEV_LOG_MARTIANS(in_dev) && - rt->u.dst.rate_tokens == ip_rt_redirect_number && net_ratelimit()) - printk(KERN_WARNING "host %u.%u.%u.%u/if%d ignores redirects for " - "%u.%u.%u.%u to %u.%u.%u.%u.\n", + rt->u.dst.rate_tokens == ip_rt_redirect_number && + net_ratelimit()) + printk(KERN_WARNING "host %u.%u.%u.%u/if%d ignores " + "redirects for %u.%u.%u.%u to %u.%u.%u.%u.\n", NIPQUAD(rt->rt_src), rt->rt_iif, NIPQUAD(rt->rt_dst), NIPQUAD(rt->rt_gateway)); #endif @@ -921,23 +941,23 @@ static int ip_error(struct sk_buff *skb) int code; switch (rt->u.dst.error) { - case EINVAL: - default: - kfree_skb(skb); - return 0; - case EHOSTUNREACH: - code = ICMP_HOST_UNREACH; - break; - case ENETUNREACH: - code = ICMP_NET_UNREACH; - break; - case EACCES: - code = ICMP_PKT_FILTERED; - break; + case EINVAL: + default: + goto out; + case EHOSTUNREACH: + code = ICMP_HOST_UNREACH; + break; + case ENETUNREACH: + code = ICMP_NET_UNREACH; + break; + case EACCES: + code = ICMP_PKT_FILTERED; + break; } now = jiffies; - if ((rt->u.dst.rate_tokens += (now - rt->u.dst.rate_last)) > ip_rt_error_burst) + rt->u.dst.rate_tokens += now - rt->u.dst.rate_last; + if (rt->u.dst.rate_tokens > ip_rt_error_burst) rt->u.dst.rate_tokens = ip_rt_error_burst; rt->u.dst.rate_last = now; if (rt->u.dst.rate_tokens >= ip_rt_error_cost) { @@ -945,7 +965,7 @@ static int ip_error(struct sk_buff *skb) icmp_send(skb, ICMP_DEST_UNREACH, code, 0); } - kfree_skb(skb); +out: kfree_skb(skb); return 0; } @@ -961,7 +981,7 @@ static __inline__ unsigned short guess_mtu(unsigned short old_mtu) { int i; - for (i = 0; i < sizeof(mtu_plateau)/sizeof(mtu_plateau[0]); i++) + for (i = 0; i < sizeof(mtu_plateau) / sizeof(mtu_plateau[0]); i++) if (old_mtu > mtu_plateau[i]) return mtu_plateau[i]; return 68; @@ -980,26 +1000,28 @@ unsigned short ip_rt_frag_needed(struct iphdr *iph, unsigned short new_mtu) if (ipv4_config.no_pmtu_disc) return 0; - for (i=0; i<2; i++) { + for (i = 0; i < 2; i++) { unsigned hash = rt_hash_code(daddr, skeys[i], tos); read_lock(&rt_hash_table[hash].lock); - for (rth = rt_hash_table[hash].chain; rth; rth = rth->u.rt_next) { + for (rth = rt_hash_table[hash].chain; rth; + rth = rth->u.rt_next) { if (rth->key.dst == daddr && rth->key.src == skeys[i] && - rth->rt_dst == daddr && - rth->rt_src == iph->saddr && + rth->rt_dst == daddr && + rth->rt_src == iph->saddr && rth->key.tos == tos && rth->key.iif == 0 && - !(rth->u.dst.mxlock&(1<u.dst.mxlock & (1 << RTAX_MTU))) { unsigned short mtu = new_mtu; if (new_mtu < 68 || new_mtu >= old_mtu) { /* BSD 4.2 compatibility hack :-( */ - if (mtu == 0 && old_mtu >= rth->u.dst.pmtu && - old_mtu >= 68 + (iph->ihl<<2)) - old_mtu -= iph->ihl<<2; + if (mtu == 0 && + old_mtu >= rth->u.dst.pmtu && + old_mtu >= 68 + (iph->ihl << 2)) + old_mtu -= iph->ihl << 2; mtu = guess_mtu(old_mtu); } @@ -1008,10 +1030,12 @@ unsigned short ip_rt_frag_needed(struct iphdr *iph, unsigned short new_mtu) dst_confirm(&rth->u.dst); if (mtu < ip_rt_min_pmtu) { mtu = ip_rt_min_pmtu; - rth->u.dst.mxlock |= (1<u.dst.mxlock |= + (1 << RTAX_MTU); } rth->u.dst.pmtu = mtu; - dst_set_expires(&rth->u.dst, ip_rt_mtu_expires); + dst_set_expires(&rth->u.dst, + ip_rt_mtu_expires); } est_mtu = mtu; } @@ -1025,29 +1049,29 @@ unsigned short ip_rt_frag_needed(struct iphdr *iph, unsigned short new_mtu) void ip_rt_update_pmtu(struct dst_entry *dst, unsigned mtu) { if (dst->pmtu > mtu && mtu >= 68 && - !(dst->mxlock&(1<mxlock & (1 << RTAX_MTU))) { if (mtu < ip_rt_min_pmtu) { mtu = ip_rt_min_pmtu; - dst->mxlock |= (1<mxlock |= (1 << RTAX_MTU); } dst->pmtu = mtu; dst_set_expires(dst, ip_rt_mtu_expires); } } -static struct dst_entry * ipv4_dst_check(struct dst_entry * dst, u32 cookie) +static struct dst_entry *ipv4_dst_check(struct dst_entry *dst, u32 cookie) { dst_release(dst); return NULL; } -static struct dst_entry * ipv4_dst_reroute(struct dst_entry * dst, - struct sk_buff *skb) +static struct dst_entry *ipv4_dst_reroute(struct dst_entry *dst, + struct sk_buff *skb) { return NULL; } -static void ipv4_dst_destroy(struct dst_entry * dst) +static void ipv4_dst_destroy(struct dst_entry *dst) { struct rtable *rt = (struct rtable *) dst; struct inet_peer *peer = rt->peer; @@ -1097,23 +1121,25 @@ void ip_rt_get_source(u8 *addr, struct rtable *rt) else if (fib_lookup(&rt->key, &res) == 0) { #ifdef CONFIG_IP_ROUTE_NAT if (res.type == RTN_NAT) - src = inet_select_addr(rt->u.dst.dev, rt->rt_gateway, RT_SCOPE_UNIVERSE); + src = inet_select_addr(rt->u.dst.dev, rt->rt_gateway, + RT_SCOPE_UNIVERSE); else #endif src = FIB_RES_PREFSRC(res); fib_res_put(&res); } else - src = inet_select_addr(rt->u.dst.dev, rt->rt_gateway, RT_SCOPE_UNIVERSE); + src = inet_select_addr(rt->u.dst.dev, rt->rt_gateway, + RT_SCOPE_UNIVERSE); memcpy(addr, &src, 4); } #ifdef CONFIG_NET_CLS_ROUTE static void set_class_tag(struct rtable *rt, u32 tag) { - if (!(rt->u.dst.tclassid&0xFFFF)) - rt->u.dst.tclassid |= tag&0xFFFF; - if (!(rt->u.dst.tclassid&0xFFFF0000)) - rt->u.dst.tclassid |= tag&0xFFFF0000; + if (!(rt->u.dst.tclassid & 0xFFFF)) + rt->u.dst.tclassid |= tag & 0xFFFF; + if (!(rt->u.dst.tclassid & 0xFFFF0000)) + rt->u.dst.tclassid |= tag & 0xFFFF0000; } #endif @@ -1122,12 +1148,14 @@ static void rt_set_nexthop(struct rtable *rt, struct fib_result *res, u32 itag) struct fib_info *fi = res->fi; if (fi) { - if (FIB_RES_GW(*res) && FIB_RES_NH(*res).nh_scope == RT_SCOPE_LINK) + if (FIB_RES_GW(*res) && + FIB_RES_NH(*res).nh_scope == RT_SCOPE_LINK) rt->rt_gateway = FIB_RES_GW(*res); - memcpy(&rt->u.dst.mxlock, fi->fib_metrics, sizeof(fi->fib_metrics)); + memcpy(&rt->u.dst.mxlock, fi->fib_metrics, + sizeof(fi->fib_metrics)); if (fi->fib_mtu == 0) { rt->u.dst.pmtu = rt->u.dst.dev->mtu; - if (rt->u.dst.mxlock&(1<u.dst.mxlock & (1 << RTAX_MTU) && rt->rt_gateway != rt->rt_dst && rt->u.dst.pmtu > 576) rt->u.dst.pmtu = 576; @@ -1135,15 +1163,16 @@ static void rt_set_nexthop(struct rtable *rt, struct fib_result *res, u32 itag) #ifdef CONFIG_NET_CLS_ROUTE rt->u.dst.tclassid = FIB_RES_NH(*res).nh_tclassid; #endif - } else { + } else rt->u.dst.pmtu = rt->u.dst.dev->mtu; - } + if (rt->u.dst.pmtu > IP_MAX_MTU) rt->u.dst.pmtu = IP_MAX_MTU; if (rt->u.dst.advmss == 0) - rt->u.dst.advmss = max(rt->u.dst.dev->mtu-40, ip_rt_min_advmss); - if (rt->u.dst.advmss > 65535-40) - rt->u.dst.advmss = 65535-40; + rt->u.dst.advmss = max(rt->u.dst.dev->mtu - 40, + ip_rt_min_advmss); + if (rt->u.dst.advmss > 65535 - 40) + rt->u.dst.advmss = 65535 - 40; #ifdef CONFIG_NET_CLS_ROUTE #ifdef CONFIG_IP_MULTIPLE_TABLES @@ -1154,9 +1183,8 @@ static void rt_set_nexthop(struct rtable *rt, struct fib_result *res, u32 itag) rt->rt_type = res->type; } -static int -ip_route_input_mc(struct sk_buff *skb, u32 daddr, u32 saddr, - u8 tos, struct net_device *dev, int our) +static int ip_route_input_mc(struct sk_buff *skb, u32 daddr, u32 saddr, + u8 tos, struct net_device *dev, int our) { unsigned hash; struct rtable *rth; @@ -1177,7 +1205,8 @@ ip_route_input_mc(struct sk_buff *skb, u32 daddr, u32 saddr, if (!LOCAL_MCAST(daddr)) goto e_inval; spec_dst = inet_select_addr(dev, 0, RT_SCOPE_LINK); - } else if (fib_validate_source(saddr, 0, tos, 0, dev, &spec_dst, &itag) < 0) + } else if (fib_validate_source(saddr, 0, tos, 0, + dev, &spec_dst, &itag) < 0) goto e_inval; rth = dst_alloc(&ipv4_dst_ops); @@ -1223,8 +1252,8 @@ ip_route_input_mc(struct sk_buff *skb, u32 daddr, u32 saddr, #endif in_dev_put(in_dev); - hash = rt_hash_code(daddr, saddr^(dev->ifindex<<5), tos); - return rt_intern_hash(hash, rth, (struct rtable**)&skb->dst); + hash = rt_hash_code(daddr, saddr ^ (dev->ifindex << 5), tos); + return rt_intern_hash(hash, rth, (struct rtable**) &skb->dst); e_nobufs: in_dev_put(in_dev); @@ -1260,24 +1289,22 @@ int ip_route_input_slow(struct sk_buff *skb, u32 daddr, u32 saddr, int err = -EINVAL; int free_res = 0; - /* - * IP on this device is disabled. - */ + /* IP on this device is disabled. */ if (!in_dev) - return -EINVAL; + goto out; - key.dst = daddr; - key.src = saddr; - key.tos = tos; + key.dst = daddr; + key.src = saddr; + key.tos = tos; #ifdef CONFIG_IP_ROUTE_FWMARK - key.fwmark = skb->nfmark; + key.fwmark = skb->nfmark; #endif - key.iif = dev->ifindex; - key.oif = 0; - key.scope = RT_SCOPE_UNIVERSE; + key.iif = dev->ifindex; + key.oif = 0; + key.scope = RT_SCOPE_UNIVERSE; - hash = rt_hash_code(daddr, saddr^(key.iif<<5), tos); + hash = rt_hash_code(daddr, saddr ^ (key.iif << 5), tos); /* Check for the most weird martians, which can be not detected by fib_lookup. @@ -1338,7 +1365,8 @@ int ip_route_input_slow(struct sk_buff *skb, u32 daddr, u32 saddr, if (res.type == RTN_LOCAL) { int result; - result = fib_validate_source(saddr, daddr, tos, loopback_dev.ifindex, + result = fib_validate_source(saddr, daddr, tos, + loopback_dev.ifindex, dev, &spec_dst, &itag); if (result < 0) goto martian_source; @@ -1360,27 +1388,29 @@ int ip_route_input_slow(struct sk_buff *skb, u32 daddr, u32 saddr, out_dev = in_dev_get(FIB_RES_DEV(res)); if (out_dev == NULL) { if (net_ratelimit()) - printk(KERN_CRIT "Bug in ip_route_input_slow(). Please, report\n"); + printk(KERN_CRIT "Bug in ip_route_input_slow(). " + "Please, report\n"); goto e_inval; } - err = fib_validate_source(saddr, daddr, tos, FIB_RES_OIF(res), dev, &spec_dst, &itag); + err = fib_validate_source(saddr, daddr, tos, FIB_RES_OIF(res), dev, + &spec_dst, &itag); if (err < 0) goto martian_source; if (err) flags |= RTCF_DIRECTSRC; - if (out_dev == in_dev && err && !(flags&(RTCF_NAT|RTCF_MASQ)) && - (IN_DEV_SHARED_MEDIA(out_dev) - || inet_addr_onlink(out_dev, saddr, FIB_RES_GW(res)))) + if (out_dev == in_dev && err && !(flags & (RTCF_NAT | RTCF_MASQ)) && + (IN_DEV_SHARED_MEDIA(out_dev) || + inet_addr_onlink(out_dev, saddr, FIB_RES_GW(res)))) flags |= RTCF_DOREDIRECT; if (skb->protocol != __constant_htons(ETH_P_IP)) { /* Not IP (i.e. ARP). Do not create route, if it is * invalid for proxy arp. DNAT routes are always valid. */ - if (out_dev == in_dev && !(flags&RTCF_DNAT)) + if (out_dev == in_dev && !(flags & RTCF_DNAT)) goto e_inval; } @@ -1438,16 +1468,17 @@ done: in_dev_put(out_dev); if (free_res) fib_res_put(&res); - return err; +out: return err; brd_input: if (skb->protocol != __constant_htons(ETH_P_IP)) goto e_inval; - if (ZERONET(saddr)) { + if (ZERONET(saddr)) spec_dst = inet_select_addr(dev, 0, RT_SCOPE_LINK); - } else { - err = fib_validate_source(saddr, 0, tos, 0, dev, &spec_dst, &itag); + else { + err = fib_validate_source(saddr, 0, tos, 0, dev, &spec_dst, + &itag); if (err < 0) goto martian_source; if (err) @@ -1508,7 +1539,8 @@ no_route: martian_destination: #ifdef CONFIG_IP_ROUTE_VERBOSE if (IN_DEV_LOG_MARTIANS(in_dev) && net_ratelimit()) - printk(KERN_WARNING "martian destination %u.%u.%u.%u from %u.%u.%u.%u, dev %s\n", + printk(KERN_WARNING "martian destination %u.%u.%u.%u from " + "%u.%u.%u.%u, dev %s\n", NIPQUAD(daddr), NIPQUAD(saddr), dev->name); #endif e_inval: @@ -1526,15 +1558,16 @@ martian_source: * RFC1812 recommendation, if source is martian, * the only hint is MAC header. */ - printk(KERN_WARNING "martian source %u.%u.%u.%u from %u.%u.%u.%u, on dev %s\n", + printk(KERN_WARNING "martian source %u.%u.%u.%u from " + "%u.%u.%u.%u, on dev %s\n", NIPQUAD(daddr), NIPQUAD(saddr), dev->name); if (dev->hard_header_len) { int i; unsigned char *p = skb->mac.raw; printk(KERN_WARNING "ll header: "); - for (i=0; ihard_header_len; i++, p++) { + for (i = 0; i < dev->hard_header_len; i++, p++) { printk("%02x", *p); - if(i<(dev->hard_header_len-1)) + if (i < (dev->hard_header_len - 1)) printk(":"); } printk("\n"); @@ -1552,10 +1585,10 @@ int ip_route_input(struct sk_buff *skb, u32 daddr, u32 saddr, int iif = dev->ifindex; tos &= IPTOS_RT_MASK; - hash = rt_hash_code(daddr, saddr^(iif<<5), tos); + hash = rt_hash_code(daddr, saddr ^ (iif << 5), tos); read_lock(&rt_hash_table[hash].lock); - for (rth=rt_hash_table[hash].chain; rth; rth=rth->u.rt_next) { + for (rth = rt_hash_table[hash].chain; rth; rth = rth->u.rt_next) { if (rth->key.dst == daddr && rth->key.src == saddr && rth->key.iif == iif && @@ -1597,7 +1630,8 @@ int ip_route_input(struct sk_buff *skb, u32 daddr, u32 saddr, #endif ) { read_unlock(&inetdev_lock); - return ip_route_input_mc(skb, daddr, saddr, tos, dev, our); + return ip_route_input_mc(skb, daddr, saddr, + tos, dev, our); } } read_unlock(&inetdev_lock); @@ -1622,31 +1656,33 @@ int ip_route_output_slow(struct rtable **rp, const struct rt_key *oldkey) int err; u32 tos; - tos = oldkey->tos & (IPTOS_RT_MASK|RTO_ONLINK); - key.dst = oldkey->dst; - key.src = oldkey->src; - key.tos = tos&IPTOS_RT_MASK; - key.iif = loopback_dev.ifindex; - key.oif = oldkey->oif; + tos = oldkey->tos & (IPTOS_RT_MASK | RTO_ONLINK); + key.dst = oldkey->dst; + key.src = oldkey->src; + key.tos = tos & IPTOS_RT_MASK; + key.iif = loopback_dev.ifindex; + key.oif = oldkey->oif; #ifdef CONFIG_IP_ROUTE_FWMARK - key.fwmark = oldkey->fwmark; + key.fwmark = oldkey->fwmark; #endif - key.scope = (tos&RTO_ONLINK) ? RT_SCOPE_LINK : RT_SCOPE_UNIVERSE; - res.fi = NULL; + key.scope = (tos & RTO_ONLINK) ? RT_SCOPE_LINK : + RT_SCOPE_UNIVERSE; + res.fi = NULL; #ifdef CONFIG_IP_MULTIPLE_TABLES - res.r = NULL; + res.r = NULL; #endif if (oldkey->src) { - if (MULTICAST(oldkey->src) - || BADCLASS(oldkey->src) - || ZERONET(oldkey->src)) - return -EINVAL; + err = -EINVAL; + if (MULTICAST(oldkey->src) || + BADCLASS(oldkey->src) || + ZERONET(oldkey->src)) + goto out; /* It is equivalent to inet_addr_type(saddr) == RTN_LOCAL */ dev_out = ip_dev_find(oldkey->src); if (dev_out == NULL) - return -EINVAL; + goto out; /* I removed check for oif == dev_out->oif here. It was wrong by three reasons: @@ -1682,23 +1718,27 @@ int ip_route_output_slow(struct rtable **rp, const struct rt_key *oldkey) } if (oldkey->oif) { dev_out = dev_get_by_index(oldkey->oif); + err = -ENODEV; if (dev_out == NULL) - return -ENODEV; + goto out; if (__in_dev_get(dev_out) == NULL) { dev_put(dev_out); - return -ENODEV; /* Wrong error code */ + goto out; /* Wrong error code */ } if (LOCAL_MCAST(oldkey->dst) || oldkey->dst == 0xFFFFFFFF) { if (!key.src) - key.src = inet_select_addr(dev_out, 0, RT_SCOPE_LINK); + key.src = inet_select_addr(dev_out, 0, + RT_SCOPE_LINK); goto make_route; } if (!key.src) { if (MULTICAST(oldkey->dst)) - key.src = inet_select_addr(dev_out, 0, key.scope); + key.src = inet_select_addr(dev_out, 0, + key.scope); else if (!oldkey->dst) - key.src = inet_select_addr(dev_out, 0, RT_SCOPE_HOST); + key.src = inet_select_addr(dev_out, 0, + RT_SCOPE_HOST); } } @@ -1738,13 +1778,15 @@ int ip_route_output_slow(struct rtable **rp, const struct rt_key *oldkey) */ if (key.src == 0) - key.src = inet_select_addr(dev_out, 0, RT_SCOPE_LINK); + key.src = inet_select_addr(dev_out, 0, + RT_SCOPE_LINK); res.type = RTN_UNICAST; goto make_route; } if (dev_out) dev_put(dev_out); - return -ENETUNREACH; + err = -ENETUNREACH; + goto out; } free_res = 1; @@ -1771,7 +1813,7 @@ int ip_route_output_slow(struct rtable **rp, const struct rt_key *oldkey) fib_select_multipath(&key, &res); else #endif - if (res.prefixlen==0 && res.type == RTN_UNICAST && key.oif == 0) + if (!res.prefixlen && res.type == RTN_UNICAST && !key.oif) fib_select_default(&key, &res); if (!key.src) @@ -1794,11 +1836,11 @@ make_route: else if (BADCLASS(key.dst) || ZERONET(key.dst)) goto e_inval; - if (dev_out->flags&IFF_LOOPBACK) + if (dev_out->flags & IFF_LOOPBACK) flags |= RTCF_LOCAL; if (res.type == RTN_BROADCAST) { - flags |= RTCF_BROADCAST|RTCF_LOCAL; + flags |= RTCF_BROADCAST | RTCF_LOCAL; if (res.fi) { fib_info_put(res.fi); res.fi = NULL; @@ -1806,7 +1848,8 @@ make_route: } else if (res.type == RTN_MULTICAST) { flags |= RTCF_MULTICAST|RTCF_LOCAL; read_lock(&inetdev_lock); - if (!__in_dev_get(dev_out) || !ip_check_mc(__in_dev_get(dev_out), oldkey->dst)) + if (!__in_dev_get(dev_out) || + !ip_check_mc(__in_dev_get(dev_out), oldkey->dst)) flags &= ~RTCF_LOCAL; read_unlock(&inetdev_lock); /* If multicast route do not exist use @@ -1847,19 +1890,20 @@ make_route: rth->u.dst.output=ip_output; - if (flags&RTCF_LOCAL) { + if (flags & RTCF_LOCAL) { rth->u.dst.input = ip_local_deliver; rth->rt_spec_dst = key.dst; } - if (flags&(RTCF_BROADCAST|RTCF_MULTICAST)) { + if (flags & (RTCF_BROADCAST | RTCF_MULTICAST)) { rth->rt_spec_dst = key.src; - if (flags&RTCF_LOCAL && !(dev_out->flags&IFF_LOOPBACK)) + if (flags & RTCF_LOCAL && !(dev_out->flags & IFF_LOOPBACK)) rth->u.dst.output = ip_mc_output; #ifdef CONFIG_IP_MROUTE if (res.type == RTN_MULTICAST) { struct in_device *in_dev = in_dev_get(dev_out); if (in_dev) { - if (IN_DEV_MFORWARD(in_dev) && !LOCAL_MCAST(oldkey->dst)) { + if (IN_DEV_MFORWARD(in_dev) && + !LOCAL_MCAST(oldkey->dst)) { rth->u.dst.input = ip_mr_input; rth->u.dst.output = ip_mc_output; } @@ -1873,14 +1917,14 @@ make_route: rth->rt_flags = flags; - hash = rt_hash_code(oldkey->dst, oldkey->src^(oldkey->oif<<5), tos); + hash = rt_hash_code(oldkey->dst, oldkey->src ^ (oldkey->oif << 5), tos); err = rt_intern_hash(hash, rth, rp); done: if (free_res) fib_res_put(&res); if (dev_out) dev_put(dev_out); - return err; +out: return err; e_inval: err = -EINVAL; @@ -1895,10 +1939,10 @@ int ip_route_output_key(struct rtable **rp, const struct rt_key *key) unsigned hash; struct rtable *rth; - hash = rt_hash_code(key->dst, key->src^(key->oif<<5), key->tos); + hash = rt_hash_code(key->dst, key->src ^ (key->oif << 5), key->tos); read_lock_bh(&rt_hash_table[hash].lock); - for (rth=rt_hash_table[hash].chain; rth; rth=rth->u.rt_next) { + for (rth = rt_hash_table[hash].chain; rth; rth = rth->u.rt_next) { if (rth->key.dst == key->dst && rth->key.src == key->src && rth->key.iif == 0 && @@ -1906,9 +1950,10 @@ int ip_route_output_key(struct rtable **rp, const struct rt_key *key) #ifdef CONFIG_IP_ROUTE_FWMARK rth->key.fwmark == key->fwmark && #endif - !((rth->key.tos^key->tos)&(IPTOS_RT_MASK|RTO_ONLINK)) && - ((key->tos&RTO_TPROXY) || !(rth->rt_flags&RTCF_TPROXY)) - ) { + !((rth->key.tos ^ key->tos) & + (IPTOS_RT_MASK | RTO_ONLINK)) && + ((key->tos & RTO_TPROXY) || + !(rth->rt_flags & RTCF_TPROXY))) { rth->u.dst.lastuse = jiffies; dst_hold(&rth->u.dst); rth->u.dst.__use++; @@ -1923,8 +1968,8 @@ int ip_route_output_key(struct rtable **rp, const struct rt_key *key) } #ifdef CONFIG_RTNETLINK - -static int rt_fill_info(struct sk_buff *skb, u32 pid, u32 seq, int event, int nowait) +static int rt_fill_info(struct sk_buff *skb, u32 pid, u32 seq, int event, + int nowait) { struct rtable *rt = (struct rtable*)skb->dst; struct rtmsg *r; @@ -1934,19 +1979,18 @@ static int rt_fill_info(struct sk_buff *skb, u32 pid, u32 seq, int event, int no #ifdef CONFIG_IP_MROUTE struct rtattr *eptr; #endif - nlh = NLMSG_PUT(skb, pid, seq, event, sizeof(*r)); r = NLMSG_DATA(nlh); nlh->nlmsg_flags = (nowait && pid) ? NLM_F_MULTI : 0; - r->rtm_family = AF_INET; - r->rtm_dst_len = 32; - r->rtm_src_len = 0; - r->rtm_tos = rt->key.tos; - r->rtm_table = RT_TABLE_MAIN; - r->rtm_type = rt->rt_type; - r->rtm_scope = RT_SCOPE_UNIVERSE; + r->rtm_family = AF_INET; + r->rtm_dst_len = 32; + r->rtm_src_len = 0; + r->rtm_tos = rt->key.tos; + r->rtm_table = RT_TABLE_MAIN; + r->rtm_type = rt->rt_type; + r->rtm_scope = RT_SCOPE_UNIVERSE; r->rtm_protocol = RTPROT_UNSPEC; - r->rtm_flags = (rt->rt_flags&~0xFFFF) | RTM_F_CLONED; + r->rtm_flags = (rt->rt_flags & ~0xFFFF) | RTM_F_CLONED; if (rt->rt_flags & RTCF_NOTIFY) r->rtm_flags |= RTM_F_NOTIFY; RTA_PUT(skb, RTA_DST, 4, &rt->rt_dst); @@ -1968,17 +2012,15 @@ static int rt_fill_info(struct sk_buff *skb, u32 pid, u32 seq, int event, int no RTA_PUT(skb, RTA_GATEWAY, 4, &rt->rt_gateway); if (rtnetlink_put_metrics(skb, &rt->u.dst.mxlock) < 0) goto rtattr_failure; - ci.rta_lastuse = jiffies - rt->u.dst.lastuse; - ci.rta_used = rt->u.dst.__use; - ci.rta_clntref = atomic_read(&rt->u.dst.__refcnt); + ci.rta_lastuse = jiffies - rt->u.dst.lastuse; + ci.rta_used = rt->u.dst.__use; + ci.rta_clntref = atomic_read(&rt->u.dst.__refcnt); if (rt->u.dst.expires) ci.rta_expires = rt->u.dst.expires - jiffies; else ci.rta_expires = 0; - ci.rta_error = rt->u.dst.error; - ci.rta_id = 0; - ci.rta_ts = 0; - ci.rta_tsage = 0; + ci.rta_error = rt->u.dst.error; + ci.rta_id = ci.rta_ts = ci.rta_tsage = 0; if (rt->peer) { ci.rta_id = rt->peer->ip_id_count; if (rt->peer->tcp_ts_stamp) { @@ -1994,7 +2036,8 @@ static int rt_fill_info(struct sk_buff *skb, u32 pid, u32 seq, int event, int no #ifdef CONFIG_IP_MROUTE u32 dst = rt->rt_dst; - if (MULTICAST(dst) && !LOCAL_MCAST(dst) && ipv4_devconf.mc_forwarding) { + if (MULTICAST(dst) && !LOCAL_MCAST(dst) && + ipv4_devconf.mc_forwarding) { int err = ipmr_get_route(skb, r, nowait); if (err <= 0) { if (!nowait) { @@ -2009,9 +2052,7 @@ static int rt_fill_info(struct sk_buff *skb, u32 pid, u32 seq, int event, int no } } else #endif - { RTA_PUT(skb, RTA_IIF, sizeof(int), &rt->key.iif); - } } nlh->nlmsg_len = skb->tail - b; @@ -2031,12 +2072,12 @@ int inet_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr* nlh, void *arg) u32 dst = 0; u32 src = 0; int iif = 0; - int err; + int err = -ENOBUFS; struct sk_buff *skb; skb = alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL); - if (skb == NULL) - return -ENOBUFS; + if (!skb) + goto out; /* Reserve room for dummy headers, this skb can pass through good chunk of routing engine. @@ -2044,20 +2085,20 @@ int inet_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr* nlh, void *arg) skb->mac.raw = skb->data; skb_reserve(skb, MAX_HEADER + sizeof(struct iphdr)); - if (rta[RTA_SRC-1]) - memcpy(&src, RTA_DATA(rta[RTA_SRC-1]), 4); - if (rta[RTA_DST-1]) - memcpy(&dst, RTA_DATA(rta[RTA_DST-1]), 4); - if (rta[RTA_IIF-1]) - memcpy(&iif, RTA_DATA(rta[RTA_IIF-1]), sizeof(int)); + if (rta[RTA_SRC - 1]) + memcpy(&src, RTA_DATA(rta[RTA_SRC - 1]), 4); + if (rta[RTA_DST - 1]) + memcpy(&dst, RTA_DATA(rta[RTA_DST - 1]), 4); + if (rta[RTA_IIF - 1]) + memcpy(&iif, RTA_DATA(rta[RTA_IIF - 1]), sizeof(int)); if (iif) { - struct net_device *dev; - dev = __dev_get_by_index(iif); + struct net_device *dev = __dev_get_by_index(iif); + err = -ENODEV; if (!dev) - return -ENODEV; - skb->protocol = __constant_htons(ETH_P_IP); - skb->dev = dev; + goto out; + skb->protocol = __constant_htons(ETH_P_IP); + skb->dev = dev; local_bh_disable(); err = ip_route_input(skb, dst, src, rtm->rtm_tos, dev); local_bh_enable(); @@ -2066,13 +2107,13 @@ int inet_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr* nlh, void *arg) err = -rt->u.dst.error; } else { int oif = 0; - if (rta[RTA_OIF-1]) - memcpy(&oif, RTA_DATA(rta[RTA_OIF-1]), sizeof(int)); + if (rta[RTA_OIF - 1]) + memcpy(&oif, RTA_DATA(rta[RTA_OIF - 1]), sizeof(int)); err = ip_route_output(&rt, dst, src, rtm->rtm_tos, oif); } if (err) { kfree_skb(skb); - return err; + goto out; } skb->dst = &rt->u.dst; @@ -2081,19 +2122,21 @@ int inet_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr* nlh, void *arg) NETLINK_CB(skb).dst_pid = NETLINK_CB(in_skb).pid; - err = rt_fill_info(skb, NETLINK_CB(in_skb).pid, nlh->nlmsg_seq, RTM_NEWROUTE, 0); - if (err == 0) - return 0; - if (err < 0) - return -EMSGSIZE; + err = rt_fill_info(skb, NETLINK_CB(in_skb).pid, nlh->nlmsg_seq, + RTM_NEWROUTE, 0); + if (!err) + goto out; + if (err < 0) { + err = -EMSGSIZE; + goto out; + } err = netlink_unicast(rtnl, skb, NETLINK_CB(in_skb).pid, MSG_DONTWAIT); - if (err < 0) - return err; - return 0; + if (err > 0) + err = 0; +out: return err; } - int ip_rt_dump(struct sk_buff *skb, struct netlink_callback *cb) { struct rtable *rt; @@ -2102,17 +2145,19 @@ int ip_rt_dump(struct sk_buff *skb, struct netlink_callback *cb) s_h = cb->args[0]; s_idx = idx = cb->args[1]; - for (h=0; h <= rt_hash_mask; h++) { + for (h = 0; h <= rt_hash_mask; h++) { if (h < s_h) continue; if (h > s_h) s_idx = 0; read_lock_bh(&rt_hash_table[h].lock); - for (rt = rt_hash_table[h].chain, idx = 0; rt; rt = rt->u.rt_next, idx++) { + for (rt = rt_hash_table[h].chain, idx = 0; rt; + rt = rt->u.rt_next, idx++) { if (idx < s_idx) continue; skb->dst = dst_clone(&rt->u.dst); if (rt_fill_info(skb, NETLINK_CB(cb->skb).pid, - cb->nlh->nlmsg_seq, RTM_NEWROUTE, 1) <= 0) { + cb->nlh->nlmsg_seq, + RTM_NEWROUTE, 1) <= 0) { dst_release(xchg(&skb->dst, NULL)); read_unlock_bh(&rt_hash_table[h].lock); goto done; @@ -2135,91 +2180,181 @@ void ip_rt_multicast_event(struct in_device *in_dev) rt_cache_flush(0); } - - #ifdef CONFIG_SYSCTL - static int flush_delay; -static -int ipv4_sysctl_rtcache_flush(ctl_table *ctl, int write, struct file * filp, - void *buffer, size_t *lenp) +static int ipv4_sysctl_rtcache_flush(ctl_table *ctl, int write, + struct file *filp, void *buffer, + size_t *lenp) { if (write) { proc_dointvec(ctl, write, filp, buffer, lenp); rt_cache_flush(flush_delay); return 0; - } else - return -EINVAL; + } + + return -EINVAL; } -static int ipv4_sysctl_rtcache_flush_strategy(ctl_table *table, int *name, int nlen, - void *oldval, size_t *oldlenp, - void *newval, size_t newlen, - void **context) +static int ipv4_sysctl_rtcache_flush_strategy(ctl_table *table, int *name, + int nlen, void *oldval, + size_t *oldlenp, void *newval, + size_t newlen, void **context) { int delay; if (newlen != sizeof(int)) return -EINVAL; - if (get_user(delay,(int *)newval)) + if (get_user(delay, (int *)newval)) return -EFAULT; rt_cache_flush(delay); return 0; } ctl_table ipv4_route_table[] = { - {NET_IPV4_ROUTE_FLUSH, "flush", - &flush_delay, sizeof(int), 0644, NULL, - &ipv4_sysctl_rtcache_flush, &ipv4_sysctl_rtcache_flush_strategy }, - {NET_IPV4_ROUTE_MIN_DELAY, "min_delay", - &ip_rt_min_delay, sizeof(int), 0644, NULL, - &proc_dointvec_jiffies, &sysctl_jiffies}, - {NET_IPV4_ROUTE_MAX_DELAY, "max_delay", - &ip_rt_max_delay, sizeof(int), 0644, NULL, - &proc_dointvec_jiffies, &sysctl_jiffies}, - {NET_IPV4_ROUTE_GC_THRESH, "gc_thresh", - &ipv4_dst_ops.gc_thresh, sizeof(int), 0644, NULL, - &proc_dointvec}, - {NET_IPV4_ROUTE_MAX_SIZE, "max_size", - &ip_rt_max_size, sizeof(int), 0644, NULL, - &proc_dointvec}, - {NET_IPV4_ROUTE_GC_MIN_INTERVAL, "gc_min_interval", - &ip_rt_gc_min_interval, sizeof(int), 0644, NULL, - &proc_dointvec_jiffies, &sysctl_jiffies}, - {NET_IPV4_ROUTE_GC_TIMEOUT, "gc_timeout", - &ip_rt_gc_timeout, sizeof(int), 0644, NULL, - &proc_dointvec_jiffies, &sysctl_jiffies}, - {NET_IPV4_ROUTE_GC_INTERVAL, "gc_interval", - &ip_rt_gc_interval, sizeof(int), 0644, NULL, - &proc_dointvec_jiffies, &sysctl_jiffies}, - {NET_IPV4_ROUTE_REDIRECT_LOAD, "redirect_load", - &ip_rt_redirect_load, sizeof(int), 0644, NULL, - &proc_dointvec}, - {NET_IPV4_ROUTE_REDIRECT_NUMBER, "redirect_number", - &ip_rt_redirect_number, sizeof(int), 0644, NULL, - &proc_dointvec}, - {NET_IPV4_ROUTE_REDIRECT_SILENCE, "redirect_silence", - &ip_rt_redirect_silence, sizeof(int), 0644, NULL, - &proc_dointvec}, - {NET_IPV4_ROUTE_ERROR_COST, "error_cost", - &ip_rt_error_cost, sizeof(int), 0644, NULL, - &proc_dointvec}, - {NET_IPV4_ROUTE_ERROR_BURST, "error_burst", - &ip_rt_error_burst, sizeof(int), 0644, NULL, - &proc_dointvec}, - {NET_IPV4_ROUTE_GC_ELASTICITY, "gc_elasticity", - &ip_rt_gc_elasticity, sizeof(int), 0644, NULL, - &proc_dointvec}, - {NET_IPV4_ROUTE_MTU_EXPIRES, "mtu_expires", - &ip_rt_mtu_expires, sizeof(int), 0644, NULL, - &proc_dointvec_jiffies, &sysctl_jiffies}, - {NET_IPV4_ROUTE_MIN_PMTU, "min_pmtu", - &ip_rt_min_pmtu, sizeof(int), 0644, NULL, - &proc_dointvec}, - {NET_IPV4_ROUTE_MIN_ADVMSS, "min_adv_mss", - &ip_rt_min_advmss, sizeof(int), 0644, NULL, - &proc_dointvec}, - {0} + { + ctl_name: NET_IPV4_ROUTE_FLUSH, + procname: "flush", + data: &flush_delay, + maxlen: sizeof(int), + mode: 0644, + proc_handler: &ipv4_sysctl_rtcache_flush, + strategy: &ipv4_sysctl_rtcache_flush_strategy, + }, + { + ctl_name: NET_IPV4_ROUTE_MIN_DELAY, + procname: "min_delay", + data: &ip_rt_min_delay, + maxlen: sizeof(int), + mode: 0644, + proc_handler: &proc_dointvec_jiffies, + strategy: &sysctl_jiffies, + }, + { + ctl_name: NET_IPV4_ROUTE_MAX_DELAY, + procname: "max_delay", + data: &ip_rt_max_delay, + maxlen: sizeof(int), + mode: 0644, + proc_handler: &proc_dointvec_jiffies, + strategy: &sysctl_jiffies, + }, + { + ctl_name: NET_IPV4_ROUTE_GC_THRESH, + procname: "gc_thresh", + data: &ipv4_dst_ops.gc_thresh, + maxlen: sizeof(int), + mode: 0644, + proc_handler: &proc_dointvec, + }, + { + ctl_name: NET_IPV4_ROUTE_MAX_SIZE, + procname: "max_size", + data: &ip_rt_max_size, + maxlen: sizeof(int), + mode: 0644, + proc_handler: &proc_dointvec, + }, + { + ctl_name: NET_IPV4_ROUTE_GC_MIN_INTERVAL, + procname: "gc_min_interval", + data: &ip_rt_gc_min_interval, + maxlen: sizeof(int), + mode: 0644, + proc_handler: &proc_dointvec_jiffies, + strategy: &sysctl_jiffies, + }, + { + ctl_name: NET_IPV4_ROUTE_GC_TIMEOUT, + procname: "gc_timeout", + data: &ip_rt_gc_timeout, + maxlen: sizeof(int), + mode: 0644, + proc_handler: &proc_dointvec_jiffies, + strategy: &sysctl_jiffies, + }, + { + ctl_name: NET_IPV4_ROUTE_GC_INTERVAL, + procname: "gc_interval", + data: &ip_rt_gc_interval, + maxlen: sizeof(int), + mode: 0644, + proc_handler: &proc_dointvec_jiffies, + strategy: &sysctl_jiffies, + }, + { + ctl_name: NET_IPV4_ROUTE_REDIRECT_LOAD, + procname: "redirect_load", + data: &ip_rt_redirect_load, + maxlen: sizeof(int), + mode: 0644, + proc_handler: &proc_dointvec, + }, + { + ctl_name: NET_IPV4_ROUTE_REDIRECT_NUMBER, + procname: "redirect_number", + data: &ip_rt_redirect_number, + maxlen: sizeof(int), + mode: 0644, + proc_handler: &proc_dointvec, + }, + { + ctl_name: NET_IPV4_ROUTE_REDIRECT_SILENCE, + procname: "redirect_silence", + data: &ip_rt_redirect_silence, + maxlen: sizeof(int), + mode: 0644, + proc_handler: &proc_dointvec, + }, + { + ctl_name: NET_IPV4_ROUTE_ERROR_COST, + procname: "error_cost", + data: &ip_rt_error_cost, + maxlen: sizeof(int), + mode: 0644, + proc_handler: &proc_dointvec, + }, + { + ctl_name: NET_IPV4_ROUTE_ERROR_BURST, + procname: "error_burst", + data: &ip_rt_error_burst, + maxlen: sizeof(int), + mode: 0644, + proc_handler: &proc_dointvec, + }, + { + ctl_name: NET_IPV4_ROUTE_GC_ELASTICITY, + procname: "gc_elasticity", + data: &ip_rt_gc_elasticity, + maxlen: sizeof(int), + mode: 0644, + proc_handler: &proc_dointvec, + }, + { + ctl_name: NET_IPV4_ROUTE_MTU_EXPIRES, + procname: "mtu_expires", + data: &ip_rt_mtu_expires, + maxlen: sizeof(int), + mode: 0644, + proc_handler: &proc_dointvec_jiffies, + strategy: &sysctl_jiffies, + }, + { + ctl_name: NET_IPV4_ROUTE_MIN_PMTU, + procname: "min_pmtu", + data: &ip_rt_min_pmtu, + maxlen: sizeof(int), + mode: 0644, + proc_handler: &proc_dointvec, + }, + { + ctl_name: NET_IPV4_ROUTE_MIN_ADVMSS, + procname: "min_adv_mss", + data: &ip_rt_min_advmss, + maxlen: sizeof(int), + mode: 0644, + proc_handler: &proc_dointvec, + }, + { 0 } }; #endif @@ -2229,13 +2364,13 @@ struct ip_rt_acct *ip_rt_acct; static int ip_rt_acct_read(char *buffer, char **start, off_t offset, int length, int *eof, void *data) { - *start=buffer; + *start = buffer; - if ((offset&3) || (length&3)) + if ((offset & 3) || (length & 3)) return -EIO; - if (offset + length >= sizeof(struct ip_rt_acct)*256) { - length = sizeof(struct ip_rt_acct)*256 - offset; + if (offset + length >= sizeof(struct ip_rt_acct) * 256) { + length = sizeof(struct ip_rt_acct) * 256 - offset; *eof = 1; } if (length > 0) { @@ -2247,9 +2382,9 @@ static int ip_rt_acct_read(char *buffer, char **start, off_t offset, #ifdef CONFIG_SMP if (smp_num_cpus > 1 || cpu_logical_map(0) != 0) { int i; - int cnt = length/4; + int cnt = length / 4; - for (i=0; i msstab[mssind+1]; mssind++) + for (mssind = 0; mss > msstab[mssind + 1]; mssind++) ; - *mssp = msstab[mssind]+1; + *mssp = msstab[mssind] + 1; NET_INC_STATS_BH(SyncookiesSent); return secure_tcp_syn_cookie(skb->nh.iph->saddr, skb->nh.iph->daddr, skb->h.th->source, skb->h.th->dest, ntohl(skb->h.th->seq), - jiffies / (HZ*60), mssind); + jiffies / (HZ * 60), mssind); } /* @@ -91,16 +90,16 @@ static inline int cookie_check(struct sk_buff *skb, __u32 cookie) mssind = check_tcp_syn_cookie(cookie, skb->nh.iph->saddr, skb->nh.iph->daddr, skb->h.th->source, skb->h.th->dest, - seq, jiffies/(HZ*60), COUNTER_TRIES); + seq, jiffies / (HZ * 60), COUNTER_TRIES); - return mssind < NUM_MSS ? msstab[mssind]+1 : 0; + return mssind < NUM_MSS ? msstab[mssind] + 1 : 0; } extern struct or_calltable or_ipv4; -static inline struct sock * -get_cookie_sock(struct sock *sk, struct sk_buff *skb, struct open_request *req, - struct dst_entry *dst) +static inline struct sock *get_cookie_sock(struct sock *sk, struct sk_buff *skb, + struct open_request *req, + struct dst_entry *dst) { struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp); struct sock *child; @@ -114,41 +113,40 @@ get_cookie_sock(struct sock *sk, struct sk_buff *skb, struct open_request *req, return child; } -struct sock * -cookie_v4_check(struct sock *sk, struct sk_buff *skb, struct ip_options *opt) +struct sock *cookie_v4_check(struct sock *sk, struct sk_buff *skb, + struct ip_options *opt) { - __u32 cookie = ntohl(skb->h.th->ack_seq)-1; + __u32 cookie = ntohl(skb->h.th->ack_seq) - 1; + struct sock *ret = sk; struct open_request *req; int mss; struct rtable *rt; __u8 rcv_wscale; - if (!sysctl_tcp_syncookies) - return sk; - if (!skb->h.th->ack) - return sk; + if (!sysctl_tcp_syncookies || !skb->h.th->ack) + goto out; mss = cookie_check(skb, cookie); - if (mss == 0) { + if (!mss) { NET_INC_STATS_BH(SyncookiesFailed); - return sk; + goto out; } NET_INC_STATS_BH(SyncookiesRecv); req = tcp_openreq_alloc(); - if (req == NULL) - return NULL; - - req->rcv_isn = htonl(skb->h.th->seq)-1; - req->snt_isn = cookie; - req->mss = mss; - req->rmt_port = skb->h.th->source; + ret = NULL; + if (!req) + goto out; + + req->rcv_isn = htonl(skb->h.th->seq) - 1; + req->snt_isn = cookie; + req->mss = mss; + req->rmt_port = skb->h.th->source; req->af.v4_req.loc_addr = skb->nh.iph->daddr; req->af.v4_req.rmt_addr = skb->nh.iph->saddr; - req->class = &or_ipv4; /* for savety */ - - req->af.v4_req.opt = NULL; + req->class = &or_ipv4; /* for savety */ + req->af.v4_req.opt = NULL; /* We throwed the options of the initial SYN away, so we hope * the ACK carries the same options again (see RFC1122 4.2.3.8) @@ -166,9 +164,9 @@ cookie_v4_check(struct sock *sk, struct sk_buff *skb, struct ip_options *opt) } req->snd_wscale = req->rcv_wscale = req->tstamp_ok = 0; - req->wscale_ok = req->sack_ok = 0; - req->expires = 0UL; - req->retrans = 0; + req->wscale_ok = req->sack_ok = 0; + req->expires = 0UL; + req->retrans = 0; /* * We need to lookup the route here to get at the correct @@ -183,18 +181,18 @@ cookie_v4_check(struct sock *sk, struct sk_buff *skb, struct ip_options *opt) sk->protinfo.af_inet.tos | RTO_CONN, 0)) { tcp_openreq_free(req); - return NULL; + goto out; } /* Try to redo what tcp_v4_send_synack did. */ req->window_clamp = rt->u.dst.window; - tcp_select_initial_window(tcp_full_space(sk),req->mss, + tcp_select_initial_window(tcp_full_space(sk), req->mss, &req->rcv_wnd, &req->window_clamp, 0, &rcv_wscale); /* BTW win scale with syncookies is 0 by definition */ - req->rcv_wscale = rcv_wscale; + req->rcv_wscale = rcv_wscale; - return get_cookie_sock(sk, skb, req, &rt->u.dst); + ret = get_cookie_sock(sk, skb, req, &rt->u.dst); +out: return ret; } - #endif diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index 342972f817e1..f8eff546c7ff 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.204 2001/05/01 23:07:49 davem Exp $ + * Version: $Id: tcp.c,v 1.205 2001/05/05 22:25:30 davem Exp $ * * Authors: Ross Biro, * Fred N. van Kempen, @@ -2357,7 +2357,7 @@ int tcp_getsockopt(struct sock *sk, int level, int optname, char *optval, break; case TCP_LINGER2: val = tp->linger2; - if (val > 0) + if (val >= 0) val = (val ? : sysctl_tcp_fin_timeout)/HZ; break; case TCP_DEFER_ACCEPT: diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index 4f463f8f898a..c6423f024056 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c @@ -5,7 +5,7 @@ * * Implementation of the Transmission Control Protocol(TCP). * - * Version: $Id: tcp_input.c,v 1.228 2001/04/20 20:46:19 davem Exp $ + * Version: $Id: tcp_input.c,v 1.229 2001/05/13 18:14:46 davem Exp $ * * Authors: Ross Biro, * Fred N. van Kempen, @@ -2527,12 +2527,12 @@ static void tcp_data_queue(struct sock *sk, struct sk_buff *skb) struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp); int eaten = -1; + if (TCP_SKB_CB(skb)->seq == TCP_SKB_CB(skb)->end_seq) + goto drop; + th = skb->h.th; __skb_pull(skb, th->doff*4); - if (skb->len == 0 && !th->fin) - goto drop; - TCP_ECN_accept_cwr(tp, skb); if (tp->dsack) { diff --git a/net/ipv6/Config.in b/net/ipv6/Config.in index dd313de812b7..4c75b179eda7 100644 --- a/net/ipv6/Config.in +++ b/net/ipv6/Config.in @@ -1,10 +1,6 @@ # # IPv6 configuration # -bool ' IPv6: enable EUI-64 token format' CONFIG_IPV6_EUI64 -if [ "$CONFIG_IPV6_EUI64" = "y" ]; then - bool ' IPv6: disable provider based addresses' CONFIG_IPV6_NO_PB -fi if [ "$CONFIG_NETLINK" = "y" ]; then if [ "$CONFIG_RTNETLINK" = "n" ]; then bool ' IPv6: routing messages via old netlink' CONFIG_IPV6_NETLINK diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index 08abd69e5d9b..da27d7679541 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c @@ -6,7 +6,7 @@ * Pedro Roque * Alexey Kuznetsov * - * $Id: addrconf.c,v 1.64 2001/05/01 23:05:47 davem Exp $ + * $Id: addrconf.c,v 1.65 2001/05/03 07:02:47 davem Exp $ * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -643,14 +643,8 @@ static void addrconf_join_solict(struct net_device *dev, struct in6_addr *addr) if (dev->flags&(IFF_LOOPBACK|IFF_NOARP)) return; -#ifndef CONFIG_IPV6_NO_PB - addrconf_addr_solict_mult_old(addr, &maddr); + addrconf_addr_solict_mult(addr, &maddr); ipv6_dev_mc_inc(dev, &maddr); -#endif -#ifdef CONFIG_IPV6_EUI64 - addrconf_addr_solict_mult_new(addr, &maddr); - ipv6_dev_mc_inc(dev, &maddr); -#endif } static void addrconf_leave_solict(struct net_device *dev, struct in6_addr *addr) @@ -660,18 +654,11 @@ static void addrconf_leave_solict(struct net_device *dev, struct in6_addr *addr) if (dev->flags&(IFF_LOOPBACK|IFF_NOARP)) return; -#ifndef CONFIG_IPV6_NO_PB - addrconf_addr_solict_mult_old(addr, &maddr); + addrconf_addr_solict_mult(addr, &maddr); ipv6_dev_mc_dec(dev, &maddr); -#endif -#ifdef CONFIG_IPV6_EUI64 - addrconf_addr_solict_mult_new(addr, &maddr); - ipv6_dev_mc_dec(dev, &maddr); -#endif } -#ifdef CONFIG_IPV6_EUI64 static int ipv6_generate_eui64(u8 *eui, struct net_device *dev) { switch (dev->type) { @@ -706,7 +693,6 @@ static int ipv6_inherit_eui64(u8 *eui, struct inet6_dev *idev) read_unlock_bh(&idev->lock); return err; } -#endif /* * Add prefix route. @@ -880,7 +866,6 @@ void addrconf_prefix_rcv(struct net_device *dev, u8 *opt, int len) plen = pinfo->prefix_len >> 3; -#ifdef CONFIG_IPV6_EUI64 if (pinfo->prefix_len == 64) { memcpy(&addr, &pinfo->prefix, 8); if (ipv6_generate_eui64(addr.s6_addr + 8, dev) && @@ -890,15 +875,6 @@ void addrconf_prefix_rcv(struct net_device *dev, u8 *opt, int len) } goto ok; } -#endif -#ifndef CONFIG_IPV6_NO_PB - if (pinfo->prefix_len == ((sizeof(struct in6_addr) - dev->addr_len)<<3)) { - memcpy(&addr, &pinfo->prefix, plen); - memcpy(addr.s6_addr + plen, dev->dev_addr, - dev->addr_len); - goto ok; - } -#endif printk(KERN_DEBUG "IPv6 addrconf: prefix with wrong length %d\n", pinfo->prefix_len); in6_dev_put(in6_dev); return; @@ -1228,7 +1204,6 @@ static void addrconf_dev_config(struct net_device *dev) if (idev == NULL) return; -#ifdef CONFIG_IPV6_EUI64 memset(&addr, 0, sizeof(struct in6_addr)); addr.s6_addr[0] = 0xFE; @@ -1236,18 +1211,6 @@ static void addrconf_dev_config(struct net_device *dev) if (ipv6_generate_eui64(addr.s6_addr + 8, dev) == 0) addrconf_add_linklocal(idev, &addr); -#endif - -#ifndef CONFIG_IPV6_NO_PB - memset(&addr, 0, sizeof(struct in6_addr)); - - addr.s6_addr[0] = 0xFE; - addr.s6_addr[1] = 0x80; - - memcpy(addr.s6_addr + (sizeof(struct in6_addr) - dev->addr_len), - dev->dev_addr, dev->addr_len); - addrconf_add_linklocal(idev, &addr); -#endif } static void addrconf_sit_config(struct net_device *dev) @@ -1518,14 +1481,8 @@ static void addrconf_dad_timer(unsigned long data) /* send a neighbour solicitation for our addr */ memset(&unspec, 0, sizeof(unspec)); -#ifdef CONFIG_IPV6_EUI64 - addrconf_addr_solict_mult_new(&ifp->addr, &mcaddr); + addrconf_addr_solict_mult(&ifp->addr, &mcaddr); ndisc_send_ns(ifp->idev->dev, NULL, &ifp->addr, &mcaddr, &unspec); -#endif -#ifndef CONFIG_IPV6_NO_PB - addrconf_addr_solict_mult_old(&ifp->addr, &mcaddr); - ndisc_send_ns(ifp->idev->dev, NULL, &ifp->addr, &mcaddr, &unspec); -#endif in6_ifa_put(ifp); } diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c index fece1e14d687..e4257e9f3b15 100644 --- a/net/ipv6/ndisc.c +++ b/net/ipv6/ndisc.c @@ -21,6 +21,7 @@ * Janos Farkas : kmalloc failure checks * Alexey Kuznetsov : state machine reworked * and moved to net/core. + * Pekka Savola : RFC2461 validation */ /* Set to 3 to get tracing... */ @@ -242,14 +243,8 @@ static int pndisc_constructor(struct pneigh_entry *n) if (dev == NULL || __in6_dev_get(dev) == NULL) return -EINVAL; -#ifndef CONFIG_IPV6_NO_PB - addrconf_addr_solict_mult_old(addr, &maddr); + addrconf_addr_solict_mult(addr, &maddr); ipv6_dev_mc_inc(dev, &maddr); -#endif -#ifdef CONFIG_IPV6_EUI64 - addrconf_addr_solict_mult_new(addr, &maddr); - ipv6_dev_mc_inc(dev, &maddr); -#endif return 0; } @@ -261,14 +256,8 @@ static void pndisc_destructor(struct pneigh_entry *n) if (dev == NULL || __in6_dev_get(dev) == NULL) return; -#ifndef CONFIG_IPV6_NO_PB - addrconf_addr_solict_mult_old(addr, &maddr); - ipv6_dev_mc_dec(dev, &maddr); -#endif -#ifdef CONFIG_IPV6_EUI64 - addrconf_addr_solict_mult_new(addr, &maddr); + addrconf_addr_solict_mult(addr, &maddr); ipv6_dev_mc_dec(dev, &maddr); -#endif } @@ -393,6 +382,12 @@ void ndisc_send_ns(struct net_device *dev, struct neighbour *neigh, int err; int send_llinfo; + if (saddr == NULL) { + if (ipv6_get_lladdr(dev, &addr_buf)) + return; + saddr = &addr_buf; + } + len = sizeof(struct icmp6hdr) + sizeof(struct in6_addr); send_llinfo = dev->addr_len && ipv6_addr_type(saddr) != IPV6_ADDR_ANY; if (send_llinfo) @@ -405,14 +400,6 @@ void ndisc_send_ns(struct net_device *dev, struct neighbour *neigh, return; } - if (saddr == NULL) { - if (ipv6_get_lladdr(dev, &addr_buf)) { - kfree_skb(skb); - return; - } - saddr = &addr_buf; - } - if (ndisc_build_ll_hdr(skb, dev, daddr, neigh, len) == 0) { kfree_skb(skb); return; @@ -550,14 +537,8 @@ static void ndisc_solicit(struct neighbour *neigh, struct sk_buff *skb) neigh_app_ns(neigh); #endif } else { -#ifdef CONFIG_IPV6_EUI64 - addrconf_addr_solict_mult_new(target, &mcaddr); + addrconf_addr_solict_mult(target, &mcaddr); ndisc_send_ns(dev, NULL, target, &mcaddr, saddr); -#endif -#ifndef CONFIG_IPV6_NO_PB - addrconf_addr_solict_mult_old(target, &mcaddr); - ndisc_send_ns(dev, NULL, target, &mcaddr, saddr); -#endif } } @@ -581,9 +562,9 @@ static void ndisc_router_discovery(struct sk_buff *skb) optlen = (skb->tail - skb->h.raw) - sizeof(struct ra_msg); - if (skb->nh.ipv6h->hop_limit != 255) { - printk(KERN_INFO - "NDISC: fake router advertisment received\n"); + if (!(ipv6_addr_type(&skb->nh.ipv6h->saddr) & IPV6_ADDR_LINKLOCAL)) { + if (net_ratelimit()) + printk(KERN_WARNING "ICMP RA: source address is not linklocal\n"); return; } @@ -756,13 +737,9 @@ static void ndisc_redirect_rcv(struct sk_buff *skb) int on_link = 0; int optlen; - if (skb->nh.ipv6h->hop_limit != 255) { - printk(KERN_WARNING "NDISC: fake ICMP redirect received\n"); - return; - } - if (!(ipv6_addr_type(&skb->nh.ipv6h->saddr) & IPV6_ADDR_LINKLOCAL)) { - printk(KERN_WARNING "ICMP redirect: source address is not linklocal\n"); + if (net_ratelimit()) + printk(KERN_WARNING "ICMP redirect: source address is not linklocal\n"); return; } @@ -770,7 +747,8 @@ static void ndisc_redirect_rcv(struct sk_buff *skb) optlen -= sizeof(struct icmp6hdr) + 2 * sizeof(struct in6_addr); if (optlen < 0) { - printk(KERN_WARNING "ICMP redirect: packet too small\n"); + if (net_ratelimit()) + printk(KERN_WARNING "ICMP redirect: packet too small\n"); return; } @@ -779,14 +757,16 @@ static void ndisc_redirect_rcv(struct sk_buff *skb) dest = target + 1; if (ipv6_addr_type(dest) & IPV6_ADDR_MULTICAST) { - printk(KERN_WARNING "ICMP redirect for multicast addr\n"); + if (net_ratelimit()) + printk(KERN_WARNING "ICMP redirect for multicast addr\n"); return; } if (ipv6_addr_cmp(dest, target) == 0) { on_link = 1; } else if (!(ipv6_addr_type(target) & IPV6_ADDR_LINKLOCAL)) { - printk(KERN_WARNING "ICMP redirect: target address is not linklocal\n"); + if (net_ratelimit()) + printk(KERN_WARNING "ICMP redirect: target address is not linklocal\n"); return; } @@ -798,6 +778,11 @@ static void ndisc_redirect_rcv(struct sk_buff *skb) return; } + /* XXX: RFC2461 8.1: + * The IP source address of the Redirect MUST be the same as the current + * first-hop router for the specified ICMP Destination Address. + */ + /* passed validation tests */ /* @@ -974,8 +959,52 @@ int ndisc_rcv(struct sk_buff *skb) __skb_push(skb, skb->data-skb->h.raw); + if (skb->nh.ipv6h->hop_limit != 255) { + if (net_ratelimit()) + printk(KERN_WARNING + "ICMP NDISC: fake message with non-255 Hop Limit received: %d\n", + skb->nh.ipv6h->hop_limit); + return 0; + } + + if (msg->icmph.icmp6_code != 0) { + if (net_ratelimit()) + printk(KERN_WARNING "ICMP NDISC: code is not zero\n"); + return 0; + } + + /* XXX: RFC2461 Validation of [all ndisc messages]: + * All included ndisc options MUST be of non-zero length + * (Some checking in ndisc_find_option) + */ + switch (msg->icmph.icmp6_type) { case NDISC_NEIGHBOUR_SOLICITATION: + /* XXX: import nd_neighbor_solicit from glibc netinet/icmp6.h */ + if (skb->nh.ipv6h->payload_len < 8+16) { + if (net_ratelimit()) + printk(KERN_WARNING "ICMP NS: packet too short\n"); + return 0; + } + + if (ipv6_addr_type(&msg->target)&IPV6_ADDR_MULTICAST) { + if (net_ratelimit()) + printk(KERN_WARNING "ICMP NS: target address is multicast\n"); + return 0; + } + + /* XXX: RFC2461 7.1.1: + * If the IP source address is the unspecified address, there + * MUST NOT be source link-layer address option in the message. + * + * NOTE! Linux kernel < 2.4.4 broke this rule. + */ + + /* XXX: RFC2461 7.1.1: + * If the IP source address is the unspecified address, the IP + * destination address MUST be a solicited-node multicast address. + */ + if ((ifp = ipv6_get_ifaddr(&msg->target, dev)) != NULL) { int addr_type = ipv6_addr_type(saddr); @@ -1010,7 +1039,9 @@ int ndisc_rcv(struct sk_buff *skb) ipv6_addr_all_nodes(&maddr); ndisc_send_na(dev, NULL, &maddr, &ifp->addr, - ifp->idev->cnf.forwarding, 0, 1, 1); + ifp->idev->cnf.forwarding, 0, + ipv6_addr_type(&ifp->addr)&IPV6_ADDR_ANYCAST ? 0 : 1, + 1); in6_ifa_put(ifp); return 0; } @@ -1032,7 +1063,9 @@ int ndisc_rcv(struct sk_buff *skb) if (neigh) { ndisc_send_na(dev, neigh, saddr, &ifp->addr, - ifp->idev->cnf.forwarding, 1, inc, inc); + ifp->idev->cnf.forwarding, 1, + ipv6_addr_type(&ifp->addr)&IPV6_ADDR_ANYCAST ? 0 : 1, + 1); neigh_release(neigh); } } @@ -1059,7 +1092,7 @@ int ndisc_rcv(struct sk_buff *skb) if (neigh) { ndisc_send_na(dev, neigh, saddr, &msg->target, - 0, 1, 0, inc); + 0, 1, 0, 1); neigh_release(neigh); } } else { @@ -1077,11 +1110,25 @@ int ndisc_rcv(struct sk_buff *skb) return 0; case NDISC_NEIGHBOUR_ADVERTISEMENT: + /* XXX: import nd_neighbor_advert from glibc netinet/icmp6.h */ + if (skb->nh.ipv6h->payload_len < 16+8 ) { + if (net_ratelimit()) + printk(KERN_WARNING "ICMP NA: packet too short\n"); + return 0; + } + + if (ipv6_addr_type(&msg->target)&IPV6_ADDR_MULTICAST) { + if (net_ratelimit()) + printk(KERN_WARNING "NDISC NA: target address is multicast\n"); + return 0; + } + if ((ipv6_addr_type(daddr)&IPV6_ADDR_MULTICAST) && msg->icmph.icmp6_solicited) { ND_PRINTK0("NDISC: solicited NA is multicasted\n"); return 0; } + if ((ifp = ipv6_get_ifaddr(&msg->target, dev))) { if (ifp->flags & IFA_F_TENTATIVE) { addrconf_dad_failure(ifp); @@ -1092,7 +1139,7 @@ int ndisc_rcv(struct sk_buff *skb) about it. It could be misconfiguration, or an smart proxy agent tries to help us :-) */ - ND_PRINTK0("%s: someone avertise our address!\n", + ND_PRINTK0("%s: someone advertises our address!\n", ifp->idev->dev->name); in6_ifa_put(ifp); return 0; @@ -1125,12 +1172,35 @@ int ndisc_rcv(struct sk_buff *skb) break; case NDISC_ROUTER_ADVERTISEMENT: + /* XXX: import nd_router_advert from glibc netinet/icmp6.h */ + if (skb->nh.ipv6h->payload_len < 8+4+4) { + if (net_ratelimit()) + printk(KERN_WARNING "ICMP RA: packet too short\n"); + return 0; + } ndisc_router_discovery(skb); break; case NDISC_REDIRECT: + /* XXX: import nd_redirect from glibc netinet/icmp6.h */ + if (skb->nh.ipv6h->payload_len < 8+16+16) { + if (net_ratelimit()) + printk(KERN_WARNING "ICMP redirect: packet too short\n"); + return 0; + } ndisc_redirect_rcv(skb); break; + + case NDISC_ROUTER_SOLICITATION: + /* No RS support in the kernel, but we do some required checks */ + + /* XXX: import nd_router_solicit from glibc netinet/icmp6.h */ + if (skb->nh.ipv6h->payload_len < 8) { + if (net_ratelimit()) + printk(KERN_WARNING "ICMP RS: packet too short\n"); + return 0; + } + break; }; return 0; @@ -1228,7 +1298,7 @@ int __init ndisc_init(struct net_proto_family *ops) if((err = ops->create(ndisc_socket, IPPROTO_ICMPV6)) < 0) { printk(KERN_DEBUG - "Failed to initializee the NDISC control socket (err %d).\n", + "Failed to initialize the NDISC control socket (err %d).\n", err); sock_release(ndisc_socket); ndisc_socket = NULL; /* For safety. */ diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c index 659bb3a1e909..0c55a5d171da 100644 --- a/net/ipv6/netfilter/ip6_tables.c +++ b/net/ipv6/netfilter/ip6_tables.c @@ -1286,6 +1286,7 @@ do_ip6t_get_ctl(struct sock *sk, int cmd, void *user, int *len) ret = -EFAULT; break; } + name[IP6T_TABLE_MAXNAMELEN-1] = '\0'; t = find_table_lock(name, &ret, &ip6t_mutex); if (t) { struct ip6t_getinfo info; diff --git a/net/ipv6/route.c b/net/ipv6/route.c index 7b06c73a707b..f6e0e4787bb7 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c @@ -5,7 +5,7 @@ * Authors: * Pedro Roque * - * $Id: route.c,v 1.50 2001/04/25 20:46:35 davem Exp $ + * $Id: route.c,v 1.51 2001/05/03 07:02:47 davem Exp $ * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -892,12 +892,6 @@ void rt6_redirect(struct in6_addr *dest, struct in6_addr *saddr, if (!(rt->rt6i_flags&RTF_GATEWAY)) goto out; -#if !defined(CONFIG_IPV6_EUI64) || defined(CONFIG_IPV6_NO_PB) - /* - * During transition gateways have more than - * one link local address. Certainly, it is violation - * of basic principles, but it is temporary. - */ /* * RFC 1970 specifies that redirects should only be * accepted if they come from the nexthop to the target. @@ -929,7 +923,6 @@ void rt6_redirect(struct in6_addr *dest, struct in6_addr *saddr, } source_ok: -#endif /* * We have finally decided to accept it. diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c index ce1433afec06..a77d9b8d12dd 100644 --- a/net/ipv6/sit.c +++ b/net/ipv6/sit.c @@ -182,6 +182,7 @@ struct ip_tunnel * ipip6_tunnel_locate(struct ip_tunnel_parm *parms, int create) dev->init = ipip6_tunnel_init; dev->features |= NETIF_F_DYNALLOC; memcpy(&nt->parms, parms, sizeof(*parms)); + nt->parms.name[IFNAMSIZ-1] = '\0'; strcpy(dev->name, nt->parms.name); if (dev->name[0] == 0) { int i; diff --git a/net/ipx/af_ipx.c b/net/ipx/af_ipx.c index d6d0817b8fbe..669cdbb06c3f 100644 --- a/net/ipx/af_ipx.c +++ b/net/ipx/af_ipx.c @@ -71,6 +71,8 @@ * sysctl for ipx_pprop_broacasting, fix the ipx sysctl * handling, making it dynamic, some cleanups, thanks to * Petr Vandrovec for review and good suggestions. (acme) + * Revision 047: Cleanups, CodingStyle changes, move the ncp connection + * hack out of line (acme) * * Protect the module by a MOD_INC_USE_COUNT/MOD_DEC_USE_COUNT * pair. Also, now usage count is managed this way @@ -116,8 +118,13 @@ #include #include +#ifdef CONFIG_SYSCTL extern void ipx_register_sysctl(void); extern void ipx_unregister_sysctl(void); +#else +#define ipx_register_sysctl() +#define ipx_unregister_sysctl() +#endif /* Configuration Variables */ static unsigned char ipxcfg_max_hops = 16; @@ -175,16 +182,12 @@ static int ipxcfg_get_config_data(ipx_config_data *arg) ipx_config_data vals; vals.ipxcfg_auto_create_interfaces = ipxcfg_auto_create_interfaces; - vals.ipxcfg_auto_select_primary = ipxcfg_auto_select_primary; + vals.ipxcfg_auto_select_primary = ipxcfg_auto_select_primary; return copy_to_user(arg, &vals, sizeof(vals)) ? -EFAULT : 0; } -/**************************************************************************\ -* * -* Handlers for the socket list. * -* * -\**************************************************************************/ +/* Handlers for the socket list. */ static inline void ipxitf_hold(ipx_interface *intrfc) { @@ -220,26 +223,28 @@ void ipx_remove_socket(struct sock *sk) /* Determine interface with which socket is associated */ intrfc = sk->protinfo.af_ipx.intrfc; if (!intrfc) - return; + goto out; ipxitf_hold(intrfc); spin_lock_bh(&intrfc->if_sklist_lock); s = intrfc->if_sklist; if (s == sk) { intrfc->if_sklist = s->next; - goto out; + goto out_unlock; } while (s && s->next) { if (s->next == sk) { s->next = sk->next; - goto out; + goto out_unlock; } s = s->next; } -out: spin_unlock_bh(&intrfc->if_sklist_lock); +out_unlock: + spin_unlock_bh(&intrfc->if_sklist_lock); sock_put(sk); ipxitf_put(intrfc); +out: return; } static void ipx_destroy_socket(struct sock *sk) @@ -267,21 +272,16 @@ static ipx_route * ipxrtr_lookup(__u32); static void ipxitf_clear_primary_net(void) { - if (ipxcfg_auto_select_primary && ipx_interfaces) - ipx_primary_net = ipx_interfaces; - else - ipx_primary_net = NULL; + ipx_primary_net = ipxcfg_auto_select_primary ? ipx_interfaces : NULL; } static ipx_interface *__ipxitf_find_using_phys(struct net_device *dev, unsigned short datalink) { - ipx_interface *i; + ipx_interface *i = ipx_interfaces; - for (i = ipx_interfaces; - i && (i->if_dev != dev || i->if_dlink_type != datalink); - i = i->if_next) - ; + while (i && (i->if_dev != dev || i->if_dlink_type != datalink)) + i = i->if_next; return i; } @@ -320,8 +320,6 @@ static ipx_interface *ipxitf_find_using_net(__u32 net) /* Sockets are bound to a particular IPX interface. */ static void ipxitf_insert_socket(ipx_interface *intrfc, struct sock *sk) { - struct sock *s; - ipxitf_hold(intrfc); sock_hold(sk); spin_lock_bh(&intrfc->if_sklist_lock); @@ -330,8 +328,9 @@ static void ipxitf_insert_socket(ipx_interface *intrfc, struct sock *sk) if (!intrfc->if_sklist) intrfc->if_sklist = sk; else { - for (s = intrfc->if_sklist; s->next; s = s->next) - ; + struct sock *s = intrfc->if_sklist; + while (s->next) + s = s->next; s->next = sk; } spin_unlock_bh(&intrfc->if_sklist_lock); @@ -342,12 +341,11 @@ static void ipxitf_insert_socket(ipx_interface *intrfc, struct sock *sk) static struct sock *__ipxitf_find_socket(ipx_interface *intrfc, unsigned short port) { - struct sock *s; + struct sock *s = intrfc->if_sklist; + + while (s && s->protinfo.af_ipx.port != port) + s = s->next; - for (s = intrfc->if_sklist; - s && s->protinfo.af_ipx.port != port; - s = s->next) - ; return s; } @@ -393,7 +391,6 @@ static void ipxrtr_del_routes(ipx_interface *); static void __ipxitf_down(ipx_interface *intrfc) { - ipx_interface *i; struct sock *s, *t; /* Delete all routes associated with this interface */ @@ -401,12 +398,12 @@ static void __ipxitf_down(ipx_interface *intrfc) spin_lock_bh(&intrfc->if_sklist_lock); /* error sockets */ - for (s = intrfc->if_sklist; s; ) { + for (s = intrfc->if_sklist; s;) { s->err = ENOLINK; s->error_report(s); s->protinfo.af_ipx.intrfc = NULL; - s->protinfo.af_ipx.port = 0; - s->zapped=1; /* Indicates it is no longer bound */ + s->protinfo.af_ipx.port = 0; + s->zapped = 1; /* Indicates it is no longer bound */ t = s; s = s->next; t->next = NULL; @@ -418,10 +415,9 @@ static void __ipxitf_down(ipx_interface *intrfc) if (intrfc == ipx_interfaces) ipx_interfaces = intrfc->if_next; else { - for (i = ipx_interfaces; - i && i->if_next != intrfc; - i = i->if_next) - ; + ipx_interface *i = ipx_interfaces; + while (i && i->if_next != intrfc) + i = i->if_next; if (i && i->if_next == intrfc) i->if_next = intrfc->if_next; } @@ -482,15 +478,15 @@ static void ipxitf_def_skb_handler(struct sock *sock, struct sk_buff *skb) /* caller must hold a reference to intrfc */ #ifdef CONFIG_IPX_INTERN -static int ipxitf_demux_socket(ipx_interface *intrfc, struct sk_buff *skb, int copy) +static int ipxitf_demux_socket(ipx_interface *intrfc, struct sk_buff *skb, + int copy) { struct ipxhdr *ipx = skb->nh.ipxh; + int is_broadcast = !memcmp(ipx->ipx_dest.node, ipx_broadcast_node, + IPX_NODE_LEN); struct sock *s; int ret; - int is_broadcast = (memcmp(ipx->ipx_dest.node, ipx_broadcast_node, - IPX_NODE_LEN) == 0); - spin_lock_bh(&intrfc->if_sklist_lock); s = intrfc->if_sklist; @@ -529,6 +525,40 @@ out: spin_unlock_bh(&intrfc->if_sklist_lock); return ret; } #else +static struct sock *ncp_connection_hack(ipx_interface *intrfc, + struct ipxhdr *ipx) +{ + /* The packet's target is a NCP connection handler. We want to hand it + * to the correct socket directly within the kernel, so that the + * mars_nwe packet distribution process does not have to do it. Here we + * only care about NCP and BURST packets. + * + * You might call this a hack, but believe me, you do not want a + * complete NCP layer in the kernel, and this is VERY fast as well. */ + struct sock *sk = NULL; + int connection = 0; + u8 *ncphdr = (u8 *)(ipx + 1); + + if (*ncphdr == 0x22 && *(ncphdr + 1) == 0x22) /* NCP request */ + connection = (((int) *(ncphdr + 5)) << 8) | (int) *(ncphdr + 3); + else if (*ncphdr == 0x77 && *(ncphdr + 1) == 0x77) /* BURST packet */ + connection = (((int) *(ncphdr + 9)) << 8) | (int) *(ncphdr + 8); + + if (connection) { + /* Now we have to look for a special NCP connection handling + * socket. Only these sockets have ipx_ncp_conn != 0, set by + * SIOCIPXNCPCONN. */ + spin_lock_bh(&intrfc->if_sklist_lock); + for (sk = intrfc->if_sklist; + sk && sk->protinfo.af_ipx.ipx_ncp_conn != connection; + sk = sk->next); + if (sk) + sock_hold(sk); + spin_unlock_bh(&intrfc->if_sklist_lock); + } + return sk; +} + static int ipxitf_demux_socket(ipx_interface *intrfc, struct sk_buff *skb, int copy) { @@ -537,43 +567,8 @@ static int ipxitf_demux_socket(ipx_interface *intrfc, struct sk_buff *skb, struct sk_buff *skb1 = NULL, *skb2 = NULL; int ret; - if (intrfc == ipx_primary_net && ntohs(ipx->ipx_dest.sock) == 0x451) { - /* - * The packet's target is a NCP connection handler. We want to - * hand it to the correct socket directly within the kernel, - * so that the mars_nwe packet distribution process - * does not have to do it. Here we only care about NCP and - * BURST packets. - * You might call this a hack, but believe me, you do not - * want a complete NCP layer in the kernel, and this is - * VERY fast as well. - */ - int connection = 0; - u8 *ncphdr = (u8 *)(ipx + 1); - - if (*ncphdr == 0x22 && *(ncphdr + 1) == 0x22) - /* The packet is a NCP request */ - connection = (((int) *(ncphdr + 5)) << 8) | - (int) *(ncphdr+3); - else if (*ncphdr == 0x77 && *(ncphdr + 1) == 0x77) - /* The packet is a BURST packet */ - connection = (((int) *(ncphdr+9)) << 8) | - (int) *(ncphdr+8); - - if (connection) { - /* Now we have to look for a special NCP connection - * handling socket. Only these sockets have - * ipx_ncp_conn != 0, set by SIOCIPXNCPCONN. */ - spin_lock_bh(&intrfc->if_sklist_lock); - for (sock1 = intrfc->if_sklist; - sock1 && - sock1->protinfo.af_ipx.ipx_ncp_conn != connection; - sock1 = sock1->next); - if (sock1) - sock_hold(sock1); - spin_unlock_bh(&intrfc->if_sklist_lock); - } - } + if (intrfc == ipx_primary_net && ntohs(ipx->ipx_dest.sock) == 0x451) + sock1 = ncp_connection_hack(intrfc, ipx); if (!sock1) /* No special socket found, forward the packet the normal way */ sock1 = ipxitf_find_socket(intrfc, ipx->ipx_dest.sock); @@ -587,22 +582,15 @@ static int ipxitf_demux_socket(ipx_interface *intrfc, struct sk_buff *skb, */ if (ipx_primary_net && intrfc != ipx_primary_net) { - switch (ntohs(ipx->ipx_dest.sock)) { - case 0x452: - case 0x453: - case 0x456: - /* - * The appropriate thing to do here is to - * dup the packet and route to the primary net - * interface via ipxitf_send; however, we'll - * cheat and just demux it here. - */ - sock2 = ipxitf_find_socket(ipx_primary_net, - ipx->ipx_dest.sock); - break; - default: - break; - } + const int dsock = ntohs(ipx->ipx_dest.sock); + + if (dsock == 0x452 || dsock == 0x453 || dsock == 0x456) + /* The appropriate thing to do here is to dup the + * packet and route to the primary net interface via + * ipxitf_send; however, we'll cheat and just demux it + * here. */ + sock2 = ipxitf_find_socket(ipx_primary_net, + ipx->ipx_dest.sock); } /* @@ -673,8 +661,7 @@ static struct sk_buff *ipxitf_adjust_skbuff(ipx_interface *intrfc, skb2 = alloc_skb(len, GFP_ATOMIC); if (skb2) { skb_reserve(skb2, out_offset); - skb2->nh.raw = - skb2->h.raw = skb_put(skb2,skb->len); + skb2->nh.raw = skb2->h.raw = skb_put(skb2, skb->len); memcpy(skb2->h.raw, skb->h.raw, skb->len); memcpy(skb2->cb, skb->cb, sizeof(skb->cb)); } @@ -742,7 +729,7 @@ static int ipxitf_send(ipx_interface *intrfc, struct sk_buff *skb, char *node) skb_orphan(skb); ipxitf_demux_socket(intrfc, skb, send_to_wire); if (!send_to_wire) - return 0; + goto out; } } @@ -758,14 +745,14 @@ static int ipxitf_send(ipx_interface *intrfc, struct sk_buff *skb, char *node) */ skb = skb_unshare(skb, GFP_ATOMIC); if (!skb) - return 0; + goto out; if (++ipx->ipx_tctrl > ipxcfg_max_hops) send_to_wire = 0; } if (!send_to_wire) { kfree_skb(skb); - return 0; + goto out; } /* Determine the appropriate hardware address */ @@ -778,16 +765,16 @@ static int ipxitf_send(ipx_interface *intrfc, struct sk_buff *skb, char *node) /* Make any compensation for differing physical/data link size */ skb = ipxitf_adjust_skbuff(intrfc, skb); if (!skb) - return 0; + goto out; /* set up data link and physical headers */ - skb->dev = dev; - skb->protocol = htons(ETH_P_IPX); + skb->dev = dev; + skb->protocol = __constant_htons(ETH_P_IPX); dl->datalink_header(dl, skb, dest_node); /* Send it out */ dev_queue_xmit(skb); - return 0; +out: return 0; } static int ipxrtr_add_route(__u32, ipx_interface *, unsigned char *); @@ -976,15 +963,14 @@ out: return ret; static void ipxitf_insert(ipx_interface *intrfc) { - ipx_interface *i; - intrfc->if_next = NULL; spin_lock_bh(&ipx_interfaces_lock); if (!ipx_interfaces) ipx_interfaces = intrfc; else { - for (i = ipx_interfaces; i->if_next; i = i->if_next) - ; + ipx_interface *i = ipx_interfaces; + while (i->if_next) + i = i->if_next; i->if_next = intrfc; } spin_unlock_bh(&ipx_interfaces_lock); @@ -998,7 +984,7 @@ static ipx_interface *ipxitf_alloc(struct net_device *dev, __u32 netnum, struct datalink_proto *dlink, unsigned char internal, int ipx_offset) { - ipx_interface *intrfc = kmalloc(sizeof(ipx_interface), GFP_ATOMIC); + ipx_interface *intrfc = kmalloc(sizeof(*intrfc), GFP_ATOMIC); if (intrfc) { intrfc->if_dev = dev; @@ -1020,23 +1006,26 @@ static ipx_interface *ipxitf_alloc(struct net_device *dev, __u32 netnum, static int ipxitf_create_internal(ipx_interface_definition *idef) { ipx_interface *intrfc; - int ret; + int ret = -EEXIST; /* Only one primary network allowed */ if (ipx_primary_net) - return -EEXIST; + goto out; /* Must have a valid network number */ + ret = -EADDRNOTAVAIL; if (!idef->ipx_network) - return -EADDRNOTAVAIL; + goto out; intrfc = ipxitf_find_using_net(idef->ipx_network); + ret = -EADDRINUSE; if (intrfc) { ipxitf_put(intrfc); - return -EADDRINUSE; + goto out; } intrfc = ipxitf_alloc(NULL, idef->ipx_network, 0, NULL, 1, 0); + ret = -EAGAIN; if (!intrfc) - return -EAGAIN; + goto out; memcpy((char *)&(intrfc->if_node), idef->ipx_node, IPX_NODE_LEN); ipx_internal_net = ipx_primary_net = intrfc; ipxitf_hold(intrfc); @@ -1044,26 +1033,29 @@ static int ipxitf_create_internal(ipx_interface_definition *idef) ret = ipxitf_add_local_route(intrfc); ipxitf_put(intrfc); - return ret; +out: return ret; } static int ipx_map_frame_type(unsigned char type) { + int ret = 0; + switch (type) { case IPX_FRAME_ETHERII: - return htons(ETH_P_IPX); - + ret = __constant_htons(ETH_P_IPX); + break; case IPX_FRAME_8022: - return htons(ETH_P_802_2); - + ret = __constant_htons(ETH_P_802_2); + break; case IPX_FRAME_SNAP: - return htons(ETH_P_SNAP); - + ret = __constant_htons(ETH_P_SNAP); + break; case IPX_FRAME_8023: - return htons(ETH_P_802_3); + ret = __constant_htons(ETH_P_802_3); + break; } - return 0; + return ret; } static int ipxitf_create(ipx_interface_definition *idef) @@ -1074,39 +1066,42 @@ static int ipxitf_create(ipx_interface_definition *idef) ipx_interface *intrfc; int err; - if (idef->ipx_special == IPX_INTERNAL) - return ipxitf_create_internal(idef); + if (idef->ipx_special == IPX_INTERNAL) { + err = ipxitf_create_internal(idef); + goto out; + } + err = -EEXIST; if (idef->ipx_special == IPX_PRIMARY && ipx_primary_net) - return -EEXIST; + goto out; intrfc = ipxitf_find_using_net(idef->ipx_network); + err = -EADDRINUSE; if (idef->ipx_network && intrfc) { ipxitf_put(intrfc); - return -EADDRINUSE; + goto out; } if (intrfc) ipxitf_put(intrfc); dev = dev_get_by_name(idef->ipx_device); + err = -ENODEV; if (!dev) - return -ENODEV; + goto out; switch (idef->ipx_dlink_type) { case IPX_FRAME_TR_8022: printk(KERN_WARNING "IPX frame type 802.2TR is " "obsolete Use 802.2 instead.\n"); /* fall through */ - case IPX_FRAME_8022: - dlink_type = htons(ETH_P_802_2); + dlink_type = __constant_htons(ETH_P_802_2); datalink = p8022_datalink; break; - case IPX_FRAME_ETHERII: if (dev->type != ARPHRD_IEEE802) { - dlink_type = htons(ETH_P_IPX); + dlink_type = __constant_htons(ETH_P_IPX); datalink = pEII_datalink; break; } else @@ -1114,17 +1109,14 @@ static int ipxitf_create(ipx_interface_definition *idef) "over token-ring is obsolete. Use SNAP " "instead.\n"); /* fall through */ - case IPX_FRAME_SNAP: - dlink_type = htons(ETH_P_SNAP); + dlink_type = __constant_htons(ETH_P_SNAP); datalink = pSNAP_datalink; break; - case IPX_FRAME_8023: - dlink_type = htons(ETH_P_802_3); + dlink_type = __constant_htons(ETH_P_802_3); datalink = p8023_datalink; break; - case IPX_FRAME_NONE: default: err = -EPROTONOSUPPORT; @@ -1155,7 +1147,7 @@ static int ipxitf_create(ipx_interface_definition *idef) if (!memcmp(idef->ipx_node, "\000\000\000\000\000\000", IPX_NODE_LEN)) { memset(intrfc->if_node, 0, IPX_NODE_LEN); - memcpy((char *)&(intrfc->if_node[IPX_NODE_LEN-dev->addr_len]), + memcpy(intrfc->if_node + IPX_NODE_LEN - dev->addr_len, dev->dev_addr, dev->addr_len); } else memcpy(intrfc->if_node, idef->ipx_node, IPX_NODE_LEN); @@ -1172,10 +1164,10 @@ static int ipxitf_create(ipx_interface_definition *idef) err = ipxitf_add_local_route(intrfc); out_intrfc: ipxitf_put(intrfc); - return err; + goto out; out_dev: dev_put(dev); - return err; +out: return err; } static int ipxitf_delete(ipx_interface_definition *idef) @@ -1196,23 +1188,22 @@ static int ipxitf_delete(ipx_interface_definition *idef) } dlink_type = ipx_map_frame_type(idef->ipx_dlink_type); - if (!dlink_type) { - ret = -EPROTONOSUPPORT; + ret = -EPROTONOSUPPORT; + if (!dlink_type) goto out; - } dev = __dev_get_by_name(idef->ipx_device); - if (!dev) { - ret = -ENODEV; + ret = -ENODEV; + if (!dev) goto out; - } intrfc = __ipxitf_find_using_phys(dev, dlink_type); - if (intrfc) - __ipxitf_put(intrfc); - else - ret = -EINVAL; + ret = -EINVAL; + if (!intrfc) + goto out; + __ipxitf_put(intrfc); + ret = 0; out: spin_unlock_bh(&ipx_interfaces_lock); return ret; } @@ -1270,7 +1261,7 @@ out: return intrfc; static int ipxitf_ioctl(unsigned int cmd, void *arg) { struct ifreq ifr; - int err = 0, val; + int val; switch (cmd) { case SIOCSIFADDR: { @@ -1285,7 +1276,8 @@ static int ipxitf_ioctl(unsigned int cmd, void *arg) return -EINVAL; f.ipx_network = sipx->sipx_network; - memcpy(f.ipx_device,ifr.ifr_name,sizeof(f.ipx_device)); + memcpy(f.ipx_device, ifr.ifr_name, + sizeof(f.ipx_device)); memcpy(f.ipx_node, sipx->sipx_node, IPX_NODE_LEN); f.ipx_dlink_type = sipx->sipx_type; f.ipx_special = sipx->sipx_special; @@ -1296,8 +1288,8 @@ static int ipxitf_ioctl(unsigned int cmd, void *arg) return ipxitf_create(&f); } - case SIOCGIFADDR: - { + case SIOCGIFADDR: { + int err = 0; struct sockaddr_ipx *sipx; ipx_interface *ipxif; struct net_device *dev; @@ -1344,11 +1336,7 @@ static int ipxitf_ioctl(unsigned int cmd, void *arg) return 0; } -/**************************************************************************\ -* * -* Routing tables for the IPX socket layer. * -* * -\**************************************************************************/ +/* Routing tables for the IPX socket layer. */ static inline void ipxrtr_hold(ipx_route *rt) { @@ -1377,7 +1365,8 @@ static ipx_route *ipxrtr_lookup(__u32 net) /* caller must hold a reference to intrfc */ -static int ipxrtr_add_route(__u32 network, ipx_interface *intrfc, unsigned char *node) +static int ipxrtr_add_route(__u32 network, ipx_interface *intrfc, + unsigned char *node) { ipx_route *rt; int ret; @@ -1385,7 +1374,7 @@ static int ipxrtr_add_route(__u32 network, ipx_interface *intrfc, unsigned char /* Get a route structure; either existing or create */ rt = ipxrtr_lookup(network); if (!rt) { - rt = kmalloc(sizeof(ipx_route),GFP_ATOMIC); + rt = kmalloc(sizeof(ipx_route), GFP_ATOMIC); ret = -EAGAIN; if (!rt) goto out; @@ -1436,15 +1425,15 @@ static void ipxrtr_del_routes(ipx_interface *intrfc) static int ipxrtr_create(ipx_route_definition *rd) { ipx_interface *intrfc; - int ret; + int ret = -ENETUNREACH; /* Find the appropriate interface */ intrfc = ipxitf_find_using_net(rd->ipx_router_network); if (!intrfc) - return -ENETUNREACH; + goto out; ret = ipxrtr_add_route(rd->ipx_network, intrfc, rd->ipx_router_node); ipxitf_put(intrfc); - return ret; +out: return ret; } static int ipxrtr_delete(long net) @@ -1481,7 +1470,7 @@ out: write_unlock_bh(&ipx_routes_lock); /* Note: We assume ipx_tctrl==0 and htons(length)==ipx_pktsize */ /* This functions should *not* mess with packet contents */ -static __u16 ipx_cksum(struct ipxhdr *packet,int length) +static __u16 ipx_cksum(struct ipxhdr *packet, int length) { /* * NOTE: sum is a net byte order quantity, which optimizes the @@ -1500,7 +1489,7 @@ static __u16 ipx_cksum(struct ipxhdr *packet,int length) sum += *p++; /* Add on the last part word if it exists */ - if (packet->ipx_pktsize & htons(1)) + if (packet->ipx_pktsize & __constant_htons(1)) sum += ntohs(0xff00) & *p; /* Do final fixup */ @@ -1516,7 +1505,8 @@ static __u16 ipx_cksum(struct ipxhdr *packet,int length) /* * Route an outgoing frame from a socket. */ -static int ipxrtr_route_packet(struct sock *sk, struct sockaddr_ipx *usipx, struct iovec *iov, int len, int noblock) +static int ipxrtr_route_packet(struct sock *sk, struct sockaddr_ipx *usipx, + struct iovec *iov, int len, int noblock) { struct sk_buff *skb; ipx_interface *intrfc; @@ -1546,15 +1536,15 @@ static int ipxrtr_route_packet(struct sock *sk, struct sockaddr_ipx *usipx, stru if (!skb) goto out_put; - skb_reserve(skb,ipx_offset); + skb_reserve(skb, ipx_offset); skb->sk = sk; /* Fill in IPX header */ ipx = (struct ipxhdr *)skb_put(skb, sizeof(struct ipxhdr)); - ipx->ipx_pktsize= htons(len + sizeof(struct ipxhdr)); + ipx->ipx_pktsize = htons(len + sizeof(struct ipxhdr)); IPX_SKB_CB(skb)->ipx_tctrl = 0; - ipx->ipx_type = usipx->sipx_type; - skb->h.raw = (void *)skb->nh.ipxh = ipx; + ipx->ipx_type = usipx->sipx_type; + skb->h.raw = (void *)skb->nh.ipxh = ipx; IPX_SKB_CB(skb)->last_hop.index = -1; #ifdef CONFIG_IPX_INTERN @@ -1572,13 +1562,12 @@ static int ipxrtr_route_packet(struct sock *sk, struct sockaddr_ipx *usipx, stru memcpy(ipx->ipx_source.node, sk->protinfo.af_ipx.intrfc->if_node, IPX_NODE_LEN); } #endif /* CONFIG_IPX_INTERN */ - - ipx->ipx_source.sock = sk->protinfo.af_ipx.port; + ipx->ipx_source.sock = sk->protinfo.af_ipx.port; IPX_SKB_CB(skb)->ipx_dest_net = usipx->sipx_network; - memcpy(ipx->ipx_dest.node,usipx->sipx_node,IPX_NODE_LEN); - ipx->ipx_dest.sock = usipx->sipx_port; + memcpy(ipx->ipx_dest.node, usipx->sipx_node, IPX_NODE_LEN); + ipx->ipx_dest.sock = usipx->sipx_port; - err = memcpy_fromiovec(skb_put(skb,len),iov,len); + err = memcpy_fromiovec(skb_put(skb, len), iov, len); if (err) { kfree_skb(skb); goto out_put; @@ -1586,7 +1575,7 @@ static int ipxrtr_route_packet(struct sock *sk, struct sockaddr_ipx *usipx, stru /* Apply checksum. Not allowed on 802.3 links. */ if (sk->no_check || intrfc->if_dlink_type == IPX_FRAME_8023) - ipx->ipx_checksum=0xFFFF; + ipx->ipx_checksum = 0xFFFF; else ipx->ipx_checksum = ipx_cksum(ipx, len + sizeof(struct ipxhdr)); @@ -1612,7 +1601,7 @@ int ipxrtr_route_skb(struct sk_buff *skb) } ipxitf_hold(r->ir_intrfc); - ipxitf_send(r->ir_intrfc, skb, (r->ir_routed) ? + ipxitf_send(r->ir_intrfc, skb, r->ir_routed ? r->ir_router_node : ipx->ipx_dest.node); ipxitf_put(r->ir_intrfc); ipxrtr_put(r); @@ -1626,61 +1615,51 @@ int ipxrtr_route_skb(struct sk_buff *skb) static int ipxrtr_ioctl(unsigned int cmd, void *arg) { struct rtentry rt; /* Use these to behave like 'other' stacks */ - struct sockaddr_ipx *sg,*st; - int err; + struct sockaddr_ipx *sg, *st; + int ret = -EFAULT; - err = copy_from_user(&rt,arg,sizeof(rt)); - if (err) - return -EFAULT; + if (copy_from_user(&rt, arg, sizeof(rt))) + goto out; sg = (struct sockaddr_ipx *)&rt.rt_gateway; st = (struct sockaddr_ipx *)&rt.rt_dst; - if (!(rt.rt_flags & RTF_GATEWAY)) - return -EINVAL; /* Direct routes are fixed */ - if (sg->sipx_family != AF_IPX) - return -EINVAL; - if (st->sipx_family != AF_IPX) - return -EINVAL; + ret = -EINVAL; + if (!(rt.rt_flags & RTF_GATEWAY) || /* Direct routes are fixed */ + sg->sipx_family != AF_IPX || + st->sipx_family != AF_IPX) + goto out; switch (cmd) { case SIOCDELRT: - return ipxrtr_delete(st->sipx_network); - - case SIOCADDRT: - { + ret = ipxrtr_delete(st->sipx_network); + break; + case SIOCADDRT: { struct ipx_route_definition f; - f.ipx_network=st->sipx_network; - f.ipx_router_network=sg->sipx_network; + f.ipx_network = st->sipx_network; + f.ipx_router_network = sg->sipx_network; memcpy(f.ipx_router_node, sg->sipx_node, IPX_NODE_LEN); - return ipxrtr_create(&f); + ret = ipxrtr_create(&f); + break; } } - return -EINVAL; +out: return ret; } static const char *ipx_frame_name(unsigned short frame) { - switch (ntohs(frame)) { - case ETH_P_IPX: - return "EtherII"; - - case ETH_P_802_2: - return "802.2"; - - case ETH_P_SNAP: - return "SNAP"; - - case ETH_P_802_3: - return "802.3"; + char* ret = "None"; - case ETH_P_TR_802_2: - return "802.2TR"; - - default: - return "None"; + switch (ntohs(frame)) { + case ETH_P_IPX: ret = "EtherII"; break; + case ETH_P_802_2: ret = "802.2"; break; + case ETH_P_SNAP: ret = "SNAP"; break; + case ETH_P_802_3: ret = "802.3"; break; + case ETH_P_TR_802_2: ret = "802.2TR"; break; } + + return ret; } static const char *ipx_device_name(ipx_interface *intrfc) @@ -1699,27 +1678,28 @@ static int ipx_interface_get_info(char *buffer, char **start, off_t offset, /* Theory.. Keep printing in the same place until we pass offset */ - len += sprintf(buffer,"%-11s%-15s%-9s%-11s%s", "Network", + len += sprintf(buffer, "%-11s%-15s%-9s%-11s%s", "Network", "Node_Address", "Primary", "Device", "Frame_Type"); #ifdef IPX_REFCNT_DEBUG len += sprintf(buffer + len, " refcnt"); #endif - strcat(buffer+len++, "\n"); + strcat(buffer + len++, "\n"); spin_lock_bh(&ipx_interfaces_lock); for (i = ipx_interfaces; i; i = i->if_next) { - len += sprintf(buffer+len, "%08lX ", (long unsigned int)ntohl(i->if_netnum)); - len += sprintf(buffer+len,"%02X%02X%02X%02X%02X%02X ", + len += sprintf(buffer + len, "%08lX ", + (long unsigned int) ntohl(i->if_netnum)); + len += sprintf(buffer + len, "%02X%02X%02X%02X%02X%02X ", i->if_node[0], i->if_node[1], i->if_node[2], i->if_node[3], i->if_node[4], i->if_node[5]); - len += sprintf(buffer+len, "%-9s", i == ipx_primary_net ? + len += sprintf(buffer + len, "%-9s", i == ipx_primary_net ? "Yes" : "No"); - len += sprintf(buffer+len, "%-11s", ipx_device_name(i)); - len += sprintf(buffer+len, "%-9s", + len += sprintf(buffer + len, "%-11s", ipx_device_name(i)); + len += sprintf(buffer + len, "%-9s", ipx_frame_name(i->if_dlink_type)); #ifdef IPX_REFCNT_DEBUG - len += sprintf(buffer+len,"%6d",atomic_read(&i->refcnt)); + len += sprintf(buffer + len, "%6d", atomic_read(&i->refcnt)); #endif - strcat(buffer+len++, "\n"); + strcat(buffer + len++, "\n"); /* Are we still dumping unwanted data then discard the record */ pos = begin + len; @@ -1751,9 +1731,9 @@ static int ipx_get_info(char *buffer, char **start, off_t offset, int length) /* Theory.. Keep printing in the same place until we pass offset */ #ifdef CONFIG_IPX_INTERN - len += sprintf(buffer,"%-28s%-28s%-10s%-10s%-7s%s\n", "Local_Address", + len += sprintf(buffer, "%-28s%-28s%-10s%-10s%-7s%s\n", "Local_Address", #else - len += sprintf(buffer,"%-15s%-28s%-10s%-10s%-7s%s\n", "Local_Address", + len += sprintf(buffer, "%-15s%-28s%-10s%-10s%-7s%s\n", "Local_Address", #endif /* CONFIG_IPX_INTERN */ "Remote_Address", "Tx_Queue", "Rx_Queue", "State", "Uid"); @@ -1764,7 +1744,7 @@ static int ipx_get_info(char *buffer, char **start, off_t offset, int length) spin_lock_bh(&i->if_sklist_lock); for (s = i->if_sklist; s; s = s->next) { #ifdef CONFIG_IPX_INTERN - len += sprintf(buffer+len, + len += sprintf(buffer + len, "%08lX:%02X%02X%02X%02X%02X%02X:%04X ", (unsigned long) htonl(s->protinfo.af_ipx.intrfc->if_netnum), s->protinfo.af_ipx.node[0], @@ -1775,15 +1755,15 @@ static int ipx_get_info(char *buffer, char **start, off_t offset, int length) s->protinfo.af_ipx.node[5], htons(s->protinfo.af_ipx.port)); #else - len += sprintf(buffer+len,"%08lX:%04X ", - (unsigned long)htonl(i->if_netnum), + len += sprintf(buffer + len, "%08lX:%04X ", + (unsigned long) htonl(i->if_netnum), htons(s->protinfo.af_ipx.port)); #endif /* CONFIG_IPX_INTERN */ - if (s->state != TCP_ESTABLISHED) - len += sprintf(buffer+len, "%-28s", "Not_Connected"); + len += sprintf(buffer + len, "%-28s", + "Not_Connected"); else { - len += sprintf(buffer+len, + len += sprintf(buffer + len, "%08lX:%02X%02X%02X%02X%02X%02X:%04X ", (unsigned long) htonl(s->protinfo.af_ipx.dest_addr.net), s->protinfo.af_ipx.dest_addr.node[0], @@ -1795,10 +1775,10 @@ static int ipx_get_info(char *buffer, char **start, off_t offset, int length) htons(s->protinfo.af_ipx.dest_addr.sock)); } - len += sprintf(buffer+len,"%08X %08X ", + len += sprintf(buffer + len, "%08X %08X ", atomic_read(&s->wmem_alloc), atomic_read(&s->rmem_alloc)); - len += sprintf(buffer+len,"%02X %03d\n", + len += sprintf(buffer + len, "%02X %03d\n", s->state, SOCK_INODE(s->socket)->i_uid); pos = begin + len; @@ -1816,7 +1796,7 @@ static int ipx_get_info(char *buffer, char **start, off_t offset, int length) spin_unlock_bh(&ipx_interfaces_lock); /* The data in question runs from begin to begin+len */ - *start = buffer + (offset-begin); + *start = buffer + offset - begin; len -= (offset - begin); if (len > length) len = length; @@ -1830,19 +1810,21 @@ static int ipx_rt_get_info(char *buffer, char **start, off_t offset, int length) off_t begin = 0, pos = 0; int len = 0; - len += sprintf(buffer,"%-11s%-13s%s\n", + len += sprintf(buffer, "%-11s%-13s%s\n", "Network", "Router_Net", "Router_Node"); read_lock_bh(&ipx_routes_lock); for (rt = ipx_routes; rt; rt = rt->ir_next) { - len += sprintf(buffer+len,"%08lX ", (long unsigned int) ntohl(rt->ir_net)); + len += sprintf(buffer + len, "%08lX ", + (long unsigned int) ntohl(rt->ir_net)); if (rt->ir_routed) { - len += sprintf(buffer+len,"%08lX %02X%02X%02X%02X%02X%02X\n", - (long unsigned int) ntohl(rt->ir_intrfc->if_netnum), + len += sprintf(buffer + len, + "%08lX %02X%02X%02X%02X%02X%02X\n", + (long unsigned int) ntohl(rt->ir_intrfc->if_netnum), rt->ir_router_node[0], rt->ir_router_node[1], rt->ir_router_node[2], rt->ir_router_node[3], rt->ir_router_node[4], rt->ir_router_node[5]); } else { - len += sprintf(buffer+len, "%-13s%s\n", + len += sprintf(buffer + len, "%-13s%s\n", "Directly", "Connected"); } @@ -1865,40 +1847,30 @@ static int ipx_rt_get_info(char *buffer, char **start, off_t offset, int length) return len; } -/**************************************************************************\ -* * -* Handling for system calls applied via the various interfaces to an * -* IPX socket object. * -* * -\**************************************************************************/ +/* Handling for system calls applied via the various interfaces to an IPX + * socket object. */ static int ipx_setsockopt(struct socket *sock, int level, int optname, char *optval, int optlen) { struct sock *sk = sock->sk; int opt; + int ret = -EINVAL; if (optlen != sizeof(int)) - return -EINVAL; + goto out; + ret = -EFAULT; if (get_user(opt, (unsigned int *)optval)) - return -EFAULT; - - switch (level) { - case SOL_IPX: - switch (optname) { - case IPX_TYPE: - sk->protinfo.af_ipx.type = opt; - return 0; + goto out; - default: - return -ENOPROTOOPT; - } - break; + ret = -ENOPROTOOPT; + if (!(level == SOL_IPX && optname == IPX_TYPE)) + goto out; - default: - return -ENOPROTOOPT; - } + sk->protinfo.af_ipx.type = opt; + ret = 0; +out: return ret; } static int ipx_getsockopt(struct socket *sock, int level, int optname, @@ -1907,49 +1879,41 @@ static int ipx_getsockopt(struct socket *sock, int level, int optname, struct sock *sk = sock->sk; int val = 0; int len; + int ret = -ENOPROTOOPT; - switch (level) { - case SOL_IPX: - switch (optname) { - case IPX_TYPE: - val = sk->protinfo.af_ipx.type; - break; + if (!(level == SOL_IPX && optname == IPX_TYPE)) + goto out; - default: - return -ENOPROTOOPT; - } - break; - - default: - return -ENOPROTOOPT; - } + val = sk->protinfo.af_ipx.type; + ret = -EFAULT; if (get_user(len, optlen)) - return -EFAULT; + goto out; len = min(len, sizeof(int)); - + ret = -EINVAL; if(len < 0) - return -EINVAL; + goto out; - if (put_user(len, optlen)) - return -EFAULT; - - if (copy_to_user(optval, &val, len)) - return -EFAULT; + ret = -EFAULT; + if (put_user(len, optlen) || copy_to_user(optval, &val, len)) + goto out; - return 0; + ret = 0; +out: return ret; } static int ipx_create(struct socket *sock, int protocol) { + int ret = -ESOCKTNOSUPPORT; struct sock *sk; switch (sock->type) { case SOCK_DGRAM: sk = sk_alloc(PF_IPX, GFP_KERNEL, 1); + ret = -ENOMEM; if (!sk) - return -ENOMEM; + goto out; sock->ops = &ipx_dgram_ops; break; @@ -1958,12 +1922,14 @@ static int ipx_create(struct socket *sock, int protocol) * From this point on SPX sockets are handled * by af_spx.c and the methods replaced. */ - if (spx_family_ops) - return spx_family_ops->create(sock,protocol); + if (spx_family_ops) { + ret = spx_family_ops->create(sock, protocol); + goto out; + } /* Fall through if SPX is not loaded */ case SOCK_STREAM: /* Allow higher levels to piggyback */ default: - return -ESOCKTNOSUPPORT; + goto out; } #ifdef IPX_REFCNT_DEBUG atomic_inc(&ipx_sock_nr); @@ -1975,7 +1941,8 @@ static int ipx_create(struct socket *sock, int protocol) sk->no_check = 1; /* Checksum off by default */ MOD_INC_USE_COUNT; - return 0; + ret = 0; +out: return ret; } static int ipx_release(struct socket *sock) @@ -1983,7 +1950,7 @@ static int ipx_release(struct socket *sock) struct sock *sk = sock->sk; if (!sk) - return 0; + goto out; if (!sk->dead) sk->state_change(sk); @@ -1995,7 +1962,7 @@ static int ipx_release(struct socket *sock) if (sock->type == SOCK_DGRAM) MOD_DEC_USE_COUNT; - return 0; +out: return 0; } /* caller must hold a reference to intrfc */ @@ -2026,30 +1993,28 @@ static int ipx_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) struct sock *sk = sock->sk; ipx_interface *intrfc; struct sockaddr_ipx *addr = (struct sockaddr_ipx *)uaddr; - int ret; - - if (!sk->zapped) - return -EINVAL; + int ret = -EINVAL; - if (addr_len != sizeof(struct sockaddr_ipx)) - return -EINVAL; + if (!sk->zapped || addr_len != sizeof(struct sockaddr_ipx)) + goto out; intrfc = ipxitf_find_using_net(addr->sipx_network); + ret = -EADDRNOTAVAIL; if (!intrfc) - return -EADDRNOTAVAIL; + goto out; if (!addr->sipx_port) { addr->sipx_port = ipx_first_free_socketnum(intrfc); ret = -EINVAL; if (!addr->sipx_port) - goto out; + goto out_put; } /* protect IPX system stuff like routing/sap */ ret = -EACCES; if (ntohs(addr->sipx_port) < IPX_MIN_EPHEMERAL_SOCKET && !capable(CAP_NET_ADMIN)) - goto out; + goto out_put; sk->protinfo.af_ipx.port = addr->sipx_port; @@ -2061,8 +2026,8 @@ static int ipx_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) */ ret = -EINVAL; - if (!memcmp(addr->sipx_node,ipx_broadcast_node,IPX_NODE_LEN)) - goto out; + if (!memcmp(addr->sipx_node, ipx_broadcast_node, IPX_NODE_LEN)) + goto out_put; if (!memcmp(addr->sipx_node, ipx_this_node, IPX_NODE_LEN)) memcpy(sk->protinfo.af_ipx.node, intrfc->if_node, IPX_NODE_LEN); @@ -2077,7 +2042,7 @@ static int ipx_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) SOCK_DEBUG(sk, "IPX: bind failed because port %X in use.\n", ntohs((int)addr->sipx_port)); - goto out; + goto out_put; } } else { /* Source addresses are easy. It must be our @@ -2093,7 +2058,7 @@ static int ipx_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) SOCK_DEBUG(sk, "IPX: bind failed because port %X in use.\n", ntohs((int)addr->sipx_port)); - goto out; + goto out_put; } } @@ -2106,7 +2071,7 @@ static int ipx_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) if (ipxitf_find_socket(intrfc, addr->sipx_port)) { SOCK_DEBUG(sk, "IPX: bind failed because port %X in use.\n", ntohs((int)addr->sipx_port)); - goto out; + goto out_put; } #endif /* CONFIG_IPX_INTERN */ @@ -2116,8 +2081,9 @@ static int ipx_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) SOCK_DEBUG(sk, "IPX: bound socket 0x%04X.\n", ntohs(addr->sipx_port) ); ret = 0; -out: ipxitf_put(intrfc); - return ret; +out_put: + ipxitf_put(intrfc); +out: return ret; } static int ipx_connect(struct socket *sock, struct sockaddr *uaddr, @@ -2125,46 +2091,48 @@ static int ipx_connect(struct socket *sock, struct sockaddr *uaddr, { struct sock *sk = sock->sk; struct sockaddr_ipx *addr; + int ret = -EINVAL; ipx_route *rt; sk->state = TCP_CLOSE; sock->state = SS_UNCONNECTED; if (addr_len != sizeof(*addr)) - return -EINVAL; + goto out; addr = (struct sockaddr_ipx *)uaddr; /* put the autobinding in */ if (!sk->protinfo.af_ipx.port) { struct sockaddr_ipx uaddr; - int ret; uaddr.sipx_port = 0; uaddr.sipx_network = 0; #ifdef CONFIG_IPX_INTERN - if (sk->protinfo.af_ipx.intrfc) - memcpy(uaddr.sipx_node, sk->protinfo.af_ipx.intrfc->if_node,IPX_NODE_LEN); - else - return -ENETDOWN; /* Someone zonked the iface */ + ret = -ENETDOWN; + if (!sk->protinfo.af_ipx.intrfc) + goto out; /* Someone zonked the iface */ + memcpy(uaddr.sipx_node, sk->protinfo.af_ipx.intrfc->if_node, + IPX_NODE_LEN); #endif /* CONFIG_IPX_INTERN */ ret = ipx_bind(sock, (struct sockaddr *)&uaddr, sizeof(struct sockaddr_ipx)); if (ret) - return ret; + goto out; } /* We can either connect to primary network or somewhere * we can route to */ rt = ipxrtr_lookup(addr->sipx_network); + ret = -ENETUNREACH; if (!rt && !(!addr->sipx_network && ipx_primary_net)) - return -ENETUNREACH; + goto out; sk->protinfo.af_ipx.dest_addr.net = addr->sipx_network; sk->protinfo.af_ipx.dest_addr.sock = addr->sipx_port; memcpy(sk->protinfo.af_ipx.dest_addr.node, - addr->sipx_node,IPX_NODE_LEN); + addr->sipx_node, IPX_NODE_LEN); sk->protinfo.af_ipx.type = addr->sipx_type; if (sock->type == SOCK_DGRAM) { @@ -2174,7 +2142,8 @@ static int ipx_connect(struct socket *sock, struct sockaddr *uaddr, if (rt) ipxrtr_put(rt); - return 0; + ret = 0; +out: return ret; } @@ -2184,24 +2153,30 @@ static int ipx_getname(struct socket *sock, struct sockaddr *uaddr, ipx_address *addr; struct sockaddr_ipx sipx; struct sock *sk = sock->sk; + int ret; *uaddr_len = sizeof(struct sockaddr_ipx); if (peer) { + ret = -ENOTCONN; if (sk->state != TCP_ESTABLISHED) - return -ENOTCONN; + goto out; addr = &sk->protinfo.af_ipx.dest_addr; - sipx.sipx_network = addr->net; - memcpy(sipx.sipx_node,addr->node,IPX_NODE_LEN); - sipx.sipx_port = addr->sock; + sipx.sipx_network = addr->net; + sipx.sipx_port = addr->sock; + memcpy(sipx.sipx_node, addr->node, IPX_NODE_LEN); } else { if (sk->protinfo.af_ipx.intrfc) { - sipx.sipx_network=sk->protinfo.af_ipx.intrfc->if_netnum; + sipx.sipx_network = + sk->protinfo.af_ipx.intrfc->if_netnum; #ifdef CONFIG_IPX_INTERN - memcpy(sipx.sipx_node, sk->protinfo.af_ipx.node, IPX_NODE_LEN); + memcpy(sipx.sipx_node, sk->protinfo.af_ipx.node, + IPX_NODE_LEN); #else - memcpy(sipx.sipx_node, sk->protinfo.af_ipx.intrfc->if_node, IPX_NODE_LEN); + memcpy(sipx.sipx_node, + sk->protinfo.af_ipx.intrfc->if_node, + IPX_NODE_LEN); #endif /* CONFIG_IPX_INTERN */ } else { @@ -2213,10 +2188,11 @@ static int ipx_getname(struct socket *sock, struct sockaddr *uaddr, } sipx.sipx_family = AF_IPX; - sipx.sipx_type = sk->protinfo.af_ipx.type; - memcpy(uaddr,&sipx,sizeof(sipx)); + sipx.sipx_type = sk->protinfo.af_ipx.type; + memcpy(uaddr, &sipx, sizeof(sipx)); - return 0; + ret = 0; +out: return ret; } int ipx_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt) @@ -2225,7 +2201,7 @@ int ipx_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt) ipx_interface *intrfc; struct ipxhdr *ipx; u16 ipx_pktsize; - int ret; + int ret = 0; /* Not ours */ if (skb->pkt_type == PACKET_OTHERHOST) @@ -2234,8 +2210,8 @@ int ipx_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt) if ((skb = skb_share_check(skb, GFP_ATOMIC)) == NULL) goto out; - ipx = skb->nh.ipxh; - ipx_pktsize = ntohs(ipx->ipx_pktsize); + ipx = skb->nh.ipxh; + ipx_pktsize = ntohs(ipx->ipx_pktsize); /* Too small or invalid header? */ if (ipx_pktsize < sizeof(struct ipxhdr) || ipx_pktsize > skb->len) @@ -2245,8 +2221,8 @@ int ipx_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt) ipx->ipx_checksum != ipx_cksum(ipx, ipx_pktsize)) goto drop; - IPX_SKB_CB(skb)->ipx_tctrl = ipx->ipx_tctrl; - IPX_SKB_CB(skb)->ipx_dest_net = ipx->ipx_dest.net; + IPX_SKB_CB(skb)->ipx_tctrl = ipx->ipx_tctrl; + IPX_SKB_CB(skb)->ipx_dest_net = ipx->ipx_dest.net; IPX_SKB_CB(skb)->ipx_source_net = ipx->ipx_source.net; /* Determine what local ipx endpoint this is */ @@ -2266,9 +2242,9 @@ int ipx_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt) ret = ipxitf_rcv(intrfc, skb); ipxitf_put(intrfc); - return ret; + goto out; drop: kfree_skb(skb); -out: return 0; +out: return ret; } static int ipx_sendmsg(struct socket *sock, struct msghdr *msg, int len, @@ -2277,58 +2253,58 @@ static int ipx_sendmsg(struct socket *sock, struct msghdr *msg, int len, struct sock *sk = sock->sk; struct sockaddr_ipx *usipx = (struct sockaddr_ipx *)msg->msg_name; struct sockaddr_ipx local_sipx; - int retval; + int ret = -EINVAL; int flags = msg->msg_flags; /* Socket gets bound below anyway */ /* if (sk->zapped) return -EIO; */ /* Socket not bound */ if (flags & ~MSG_DONTWAIT) - return -EINVAL; + goto out; if (usipx) { if (!sk->protinfo.af_ipx.port) { struct sockaddr_ipx uaddr; - int ret; - uaddr.sipx_port = 0; - uaddr.sipx_network = 0L; + uaddr.sipx_port = 0; + uaddr.sipx_network = 0; #ifdef CONFIG_IPX_INTERN - if (sk->protinfo.af_ipx.intrfc) - memcpy(uaddr.sipx_node, - sk->protinfo.af_ipx.intrfc->if_node, - IPX_NODE_LEN); - else - return -ENETDOWN; /* Someone zonked the iface */ + ret = -ENETDOWN; + if (!sk->protinfo.af_ipx.intrfc) + goto out; /* Someone zonked the iface */ + memcpy(uaddr.sipx_node, + sk->protinfo.af_ipx.intrfc->if_node, + IPX_NODE_LEN); #endif ret = ipx_bind(sock, (struct sockaddr *)&uaddr, sizeof(struct sockaddr_ipx)); if (ret) - return ret; + goto out; } - if (msg->msg_namelen < sizeof(*usipx)) - return -EINVAL; - if (usipx->sipx_family != AF_IPX) - return -EINVAL; + ret = -EINVAL; + if (msg->msg_namelen < sizeof(*usipx) || + usipx->sipx_family != AF_IPX) + goto out; } else { + ret = -ENOTCONN; if (sk->state != TCP_ESTABLISHED) - return -ENOTCONN; + goto out; - usipx=&local_sipx; + usipx = &local_sipx; usipx->sipx_family = AF_IPX; usipx->sipx_type = sk->protinfo.af_ipx.type; usipx->sipx_port = sk->protinfo.af_ipx.dest_addr.sock; usipx->sipx_network = sk->protinfo.af_ipx.dest_addr.net; - memcpy(usipx->sipx_node,sk->protinfo.af_ipx.dest_addr.node,IPX_NODE_LEN); + memcpy(usipx->sipx_node, sk->protinfo.af_ipx.dest_addr.node, + IPX_NODE_LEN); } - retval = ipxrtr_route_packet(sk, usipx, msg->msg_iov, len, + ret = ipxrtr_route_packet(sk, usipx, msg->msg_iov, len, flags & MSG_DONTWAIT); - if (retval < 0) - return retval; - - return len; + if (ret >= 0) + ret = len; +out: return ret; } @@ -2344,35 +2320,37 @@ static int ipx_recvmsg(struct socket *sock, struct msghdr *msg, int size, /* put the autobinding in */ if (!sk->protinfo.af_ipx.port) { struct sockaddr_ipx uaddr; - int ret; uaddr.sipx_port = 0; uaddr.sipx_network = 0; #ifdef CONFIG_IPX_INTERN - if (sk->protinfo.af_ipx.intrfc) - memcpy(uaddr.sipx_node, sk->protinfo.af_ipx.intrfc->if_node,IPX_NODE_LEN); - else - return -ENETDOWN; /* Someone zonked the iface */ + err = -ENETDOWN; + if (!sk->protinfo.af_ipx.intrfc) + goto out; /* Someone zonked the iface */ + memcpy(uaddr.sipx_node, + sk->protinfo.af_ipx.intrfc->if_node, IPX_NODE_LEN); #endif /* CONFIG_IPX_INTERN */ - ret = ipx_bind(sock, (struct sockaddr *)&uaddr, + err = ipx_bind(sock, (struct sockaddr *)&uaddr, sizeof(struct sockaddr_ipx)); - if (ret) - return ret; + if (err) + goto out; } + err = -ENOTCONN; if (sk->zapped) - return -ENOTCONN; + goto out; - skb = skb_recv_datagram(sk,flags&~MSG_DONTWAIT,flags&MSG_DONTWAIT,&err); + skb = skb_recv_datagram(sk, flags & ~MSG_DONTWAIT, + flags & MSG_DONTWAIT, &err); if (!skb) goto out; ipx = skb->nh.ipxh; copied = ntohs(ipx->ipx_pktsize) - sizeof(struct ipxhdr); if (copied > size) { - copied=size; + copied = size; msg->msg_flags |= MSG_TRUNC; } @@ -2387,7 +2365,7 @@ static int ipx_recvmsg(struct socket *sock, struct msghdr *msg, int size, if (sipx) { sipx->sipx_family = AF_IPX; sipx->sipx_port = ipx->ipx_source.sock; - memcpy(sipx->sipx_node,ipx->ipx_source.node,IPX_NODE_LEN); + memcpy(sipx->sipx_node, ipx->ipx_source.node, IPX_NODE_LEN); sipx->sipx_network = IPX_SKB_CB(skb)->ipx_source_net; sipx->sipx_type = ipx->ipx_type; } @@ -2399,7 +2377,7 @@ out: return err; } -static int ipx_ioctl(struct socket *sock,unsigned int cmd, unsigned long arg) +static int ipx_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) { long amount = 0; struct sock *sk = sock->sk; @@ -2411,10 +2389,10 @@ static int ipx_ioctl(struct socket *sock,unsigned int cmd, unsigned long arg) amount = 0; return put_user(amount, (int *)arg); - case TIOCINQ: - { + case TIOCINQ: { struct sk_buff *skb = skb_peek(&sk->receive_queue); - /* These two are safe on a single CPU system as only user tasks fiddle here */ + /* These two are safe on a single CPU system as only + * user tasks fiddle here */ if (skb) amount = skb->len - sizeof(struct ipxhdr); return put_user(amount, (int *)arg); @@ -2424,7 +2402,7 @@ static int ipx_ioctl(struct socket *sock,unsigned int cmd, unsigned long arg) case SIOCDELRT: if (!capable(CAP_NET_ADMIN)) return -EPERM; - return ipxrtr_ioctl(cmd,(void *)arg); + return ipxrtr_ioctl(cmd, (void *)arg); case SIOCSIFADDR: case SIOCAIPXITFCRT: @@ -2433,13 +2411,12 @@ static int ipx_ioctl(struct socket *sock,unsigned int cmd, unsigned long arg) return -EPERM; case SIOCGIFADDR: - return ipxitf_ioctl(cmd,(void *)arg); + return ipxitf_ioctl(cmd, (void *)arg); case SIOCIPXCFGDATA: return ipxcfg_get_config_data((void *)arg); case SIOCIPXNCPCONN: - { /* * This socket wants to take care of the NCP connection * handed to us in arg. @@ -2448,10 +2425,8 @@ static int ipx_ioctl(struct socket *sock,unsigned int cmd, unsigned long arg) return -EPERM; return get_user(sk->protinfo.af_ipx.ipx_ncp_conn, (const unsigned short *)(arg)); - } - case SIOCGSTAMP: - { + case SIOCGSTAMP: { int ret = -EINVAL; if (sk) { if (!sk->stamp.tv_sec) @@ -2537,16 +2512,13 @@ static struct proto_ops SOCKOPS_WRAPPED(ipx_dgram_ops) = { #include SOCKOPS_WRAP(ipx_dgram, PF_IPX); -static struct packet_type ipx_8023_packet_type = - -{ +static struct packet_type ipx_8023_packet_type = { type: __constant_htons(ETH_P_802_3), func: ipx_rcv, data: (void *) 1, /* yap, I understand shared skbs :-) */ }; -static struct packet_type ipx_dix_packet_type = -{ +static struct packet_type ipx_dix_packet_type = { type: __constant_htons(ETH_P_IPX), func: ipx_rcv, data: (void *) 1, /* yap, I understand shared skbs :-) */ @@ -2565,7 +2537,7 @@ extern void destroy_8023_client(struct datalink_proto *); static unsigned char ipx_8022_type = 0xE0; static unsigned char ipx_snap_id[5] = { 0x0, 0x0, 0x0, 0x81, 0x37 }; static const char banner[] __initdata = - KERN_INFO "NET4: Linux IPX 0.46 for NET4.0\n" + KERN_INFO "NET4: Linux IPX 0.47 for NET4.0\n" KERN_INFO "IPX Portions Copyright (c) 1995 Caldera, Inc.\n" \ KERN_INFO "IPX Portions Copyright (c) 2000, 2001 Conectiva, Inc.\n"; @@ -2579,11 +2551,11 @@ static int __init ipx_init(void) p8023_datalink = make_8023_client(); dev_add_pack(&ipx_8023_packet_type); - p8022_datalink = register_8022_client(ipx_8022_type,ipx_rcv); + p8022_datalink = register_8022_client(ipx_8022_type, ipx_rcv); if (!p8022_datalink) printk(KERN_CRIT "IPX: Unable to register with 802.2\n"); - pSNAP_datalink = register_snap_client(ipx_snap_id,ipx_rcv); + pSNAP_datalink = register_snap_client(ipx_snap_id, ipx_rcv); if (!pSNAP_datalink) printk(KERN_CRIT "IPX: Unable to register with SNAP\n"); diff --git a/net/ipx/af_spx.c b/net/ipx/af_spx.c index 5c3aa6dc33d3..575e874b8315 100644 --- a/net/ipx/af_spx.c +++ b/net/ipx/af_spx.c @@ -6,7 +6,7 @@ * Revision Date: February 9, 1993 * * Developers: - * Jay Schulist + * Jay Schulist * Jim Freeman * * Changes: diff --git a/net/ipx/sysctl_net_ipx.c b/net/ipx/sysctl_net_ipx.c index 698976180250..2de49526d5cc 100644 --- a/net/ipx/sysctl_net_ipx.c +++ b/net/ipx/sysctl_net_ipx.c @@ -10,10 +10,13 @@ #include #include +#ifndef CONFIG_SYSCTL +#error This file should not be compiled without CONFIG_SYSCTL defined +#endif + /* From af_ipx.c */ extern int sysctl_ipx_pprop_broadcasting; -#ifdef CONFIG_SYSCTL ctl_table ipx_table[] = { { NET_IPX_PPROP_BROADCASTING, "ipx_pprop_broadcasting", &sysctl_ipx_pprop_broadcasting, sizeof(int), 0644, NULL, @@ -42,13 +45,3 @@ void ipx_unregister_sysctl(void) { unregister_sysctl_table(ipx_table_header); } - -#else -void ipx_register_sysctl(void) -{ -} - -void ipx_unregister_sysctl(void) -{ -} -#endif -- 2.39.5