# This is a BitKeeper generated patch for the following project: # Project Name: Linux kernel tree # This patch format is intended for GNU patch command version 2.5 or higher. # This patch includes the following deltas: # ChangeSet v2.6.0-test4 -> 1.1413 # drivers/media/video/saa7110.c 1.14 -> 1.15 # arch/i386/kernel/process.c 1.54 -> 1.55 # drivers/net/8139too.c 1.63 -> 1.72 # arch/sparc64/kernel/entry.S 1.27 -> 1.28 # arch/sparc/Kconfig 1.19 -> 1.20 # drivers/video/fbmem.c 1.78 -> 1.79 # drivers/net/irda/via-ircc.c 1.1 -> 1.2 # net/ipv4/netfilter/ip_conntrack_core.c 1.35 -> 1.37 # arch/m68k/vmlinux-sun3.lds 1.15 -> 1.16 arch/m68k/kernel/vmlinux-sun3.lds (moved) # drivers/scsi/inia100.h 1.15 -> 1.16 # drivers/net/3c59x.c 1.41 -> 1.42 # drivers/scsi/megaraid.c 1.53 -> 1.54 # include/linux/proc_fs.h 1.24 -> 1.26 # arch/ia64/kernel/fsys.S 1.17 -> 1.18 # arch/i386/kernel/cpuid.c 1.12 -> 1.13 # include/asm-x86_64/smp.h 1.11 -> 1.12 # arch/cris/arch-v10/drivers/gpio.c 1.8 -> 1.9 # net/ipv4/netfilter/arptable_filter.c 1.6 -> 1.7 # arch/i386/kernel/timers/Makefile 1.7 -> 1.8 # drivers/scsi/imm.h 1.11 -> 1.12 # drivers/ide/legacy/macide.c 1.4 -> 1.5 # drivers/block/acsi_slm.c 1.14 -> 1.15 # drivers/scsi/qlogicisp.h 1.6 -> 1.7 # arch/ppc/boot/simple/Makefile 1.19 -> 1.20 # ipc/msg.c 1.14 -> 1.15 # drivers/block/as-iosched.c 1.14 -> 1.15 # sound/oss/cs46xx.c 1.34 -> 1.35 # drivers/usb/misc/usblcd.c 1.11 -> 1.12 # net/ipv4/ipvs/ip_vs_sync.c 1.1 -> 1.2 # drivers/ide/ide_modes.h 1.3 -> (deleted) # arch/sparc64/solaris/systbl.S 1.4 -> 1.5 # include/asm-ppc/processor.h 1.32 -> 1.33 # drivers/usb/input/kbtab.c 1.4 -> 1.5 # drivers/usb/misc/uss720.c 1.14 -> 1.15 # drivers/media/video/bt856.c 1.13 -> 1.15 # drivers/net/3c501.c 1.18 -> 1.19 # drivers/usb/misc/tiglusb.c 1.21 -> 1.23 # drivers/ieee1394/raw1394.c 1.28 -> 1.30 # drivers/media/video/saa7134/saa7134-ts.c 1.8 -> 1.9 # drivers/char/lp.c 1.26 -> 1.27 # kernel/ksyms.c 1.216 -> 1.217 # arch/arm/mach-footbridge/netwinder-pci.c 1.7 -> 1.8 # arch/ppc/xmon/start.c 1.14 -> 1.15 # net/ipv6/netfilter/ip6t_eui64.c 1.2 -> 1.3 # Documentation/sonypi.txt 1.12 -> 1.13 # net/rxrpc/krxiod.c 1.4 -> 1.5 # drivers/char/scx200_gpio.c 1.2 -> 1.3 # mm/fremap.c 1.10 -> 1.11 # drivers/net/wan/cosa.c 1.22 -> 1.24 # arch/parisc/kernel/ioctl32.c 1.13 -> 1.15 # include/asm-arm/dma-mapping.h 1.6 -> 1.7 # drivers/sbus/char/bpp.c 1.14 -> 1.15 # drivers/ieee1394/raw1394.h 1.4 -> 1.5 # drivers/char/Kconfig 1.16 -> 1.18 # drivers/net/irda/vlsi_ir.c 1.20 -> 1.27 # arch/arm/kernel/vmlinux.lds.S 1.3 -> (deleted) # drivers/usb/class/usb-midi.c 1.20 -> 1.22 # drivers/usb/net/Makefile 1.8 -> 1.9 # drivers/video/Kconfig 1.23 -> 1.24 # net/sched/sch_generic.c 1.5 -> 1.6 # sound/pcmcia/vx/vx_entry.c 1.2 -> 1.3 # drivers/media/video/saa7185.c 1.15 -> 1.17 # arch/ia64/Makefile 1.58 -> 1.59 # drivers/net/3c509.c 1.38 -> 1.41 # arch/i386/kernel/cpu/mtrr/main.c 1.31 -> 1.32 # include/asm-i386/processor.h 1.52 -> 1.53 # arch/x86_64/kernel/setup.c 1.19 -> 1.20 # drivers/telephony/ixj.c 1.26 -> 1.27 # drivers/char/agp/sis-agp.c 1.29 -> 1.30 # include/asm-h8300/h8max/ne.h 1.2 -> (deleted) # drivers/block/ioctl.c 1.57 -> 1.58 # include/linux/nfsd/state.h 1.7 -> 1.8 # include/linux/cycx_cfm.h 1.3 -> 1.4 # fs/open.c 1.48 -> 1.49 # drivers/scsi/hosts.c 1.89 -> 1.90 # net/ipv4/netfilter/ipt_TOS.c 1.8 -> 1.9 # net/ipv4/netfilter/ipt_limit.c 1.4 -> 1.5 # net/Kconfig 1.18 -> 1.20 # arch/ppc/Makefile 1.41 -> 1.42 # sound/core/hwdep.c 1.14 -> 1.16 # net/ipv6/ip6_output.c 1.43 -> 1.44 # net/sunrpc/sysctl.c 1.6 -> 1.7 # drivers/ide/pci/serverworks.c 1.19 -> 1.20 # arch/sh/boards/unknown/mach.c 1.4 -> 1.5 # drivers/usb/serial/io_edgeport.c 1.47 -> 1.50 # drivers/ide/pci/piix.c 1.16 -> 1.17 # drivers/scsi/atp870u.h 1.11 -> 1.12 # drivers/net/fmv18x.c 1.11 -> 1.12 # drivers/net/hamradio/Kconfig 1.4 -> 1.5 # net/ipv6/ip6_tunnel.c 1.6 -> 1.10 # arch/ppc/8xx_io/cs4218_tdm.c 1.7 -> 1.8 # arch/ppc/boot/include/of1275.h 1.1 -> 1.2 # drivers/usb/gadget/net2280.c 1.14 -> 1.18 # drivers/char/watchdog/pcwd.c 1.25 -> 1.26 # drivers/usb/core/inode.c 1.51 -> 1.52 # arch/ppc/8260_io/uart.c 1.24 -> 1.27 # arch/ppc/syslib/prom.c 1.20 -> 1.21 # drivers/char/random.c 1.35 -> 1.37 # drivers/scsi/sun3_scsi.h 1.7 -> 1.8 # net/ipv6/netfilter/ip6table_filter.c 1.6 -> 1.7 # include/linux/pmu.h 1.5 -> 1.8 # include/asm-sparc/unistd.h 1.24 -> 1.25 # drivers/ide/pci/cs5520.c 1.6 -> 1.7 # drivers/usb/host/ohci-hcd.c 1.46 -> 1.47 # drivers/input/serio/i8042.c 1.28 -> 1.29 # drivers/net/pcmcia/nmclan_cs.c 1.19 -> 1.20 # drivers/acpi/pci_link.c 1.16 -> 1.17 # net/llc/llc_proc.c 1.13 -> 1.14 # drivers/scsi/mvme147.h 1.3 -> 1.4 # sound/oss/emu10k1/audio.c 1.18 -> 1.19 # net/ipv4/netfilter/ipt_mac.c 1.5 -> 1.6 # include/linux/sched.h 1.162 -> 1.163 # kernel/fork.c 1.137 -> 1.138 # net/sunrpc/svcsock.c 1.59 -> 1.60 # drivers/ide/ppc/pmac.c 1.15 -> 1.18 # kernel/sys.c 1.54 -> 1.55 # drivers/block/ll_rw_blk.c 1.206 -> 1.209 # drivers/net/Space.c 1.23 -> 1.24 # fs/jffs2/os-linux.h 1.11 -> 1.13 # drivers/usb/serial/keyspan_usa28msg.h 1.4 -> 1.5 # drivers/net/wireless/airo.c 1.71 -> 1.73 # drivers/atm/ambassador.c 1.14 -> 1.16 # drivers/usb/serial/keyspan.c 1.48 -> 1.49 # net/ipv4/netfilter/ipt_tcpmss.c 1.4 -> 1.5 # drivers/media/video/bt819.c 1.12 -> 1.13 # include/asm-ia64/unistd.h 1.34 -> 1.35 # drivers/video/Makefile 1.87 -> 1.88 # drivers/net/8390.c 1.13 -> 1.14 # arch/arm/boot/Makefile 1.22 -> 1.24 # include/linux/serial_core.h 1.25 -> 1.26 # drivers/mtd/maps/pcmciamtd.c 1.6 -> 1.7 # net/rxrpc/krxtimod.c 1.6 -> 1.7 # arch/ppc/boot/simple/embed_config.c 1.7 -> 1.8 # include/asm-h8300/ide.h 1.2 -> 1.3 # drivers/media/video/videodev.c 1.24 -> 1.26 # arch/h8300/kernel/setup.c 1.3 -> 1.4 # drivers/atm/firestream.c 1.21 -> 1.22 # drivers/ieee1394/sbp2.c 1.42 -> 1.43 # sound/oss/esssolo1.c 1.31 -> 1.32 # fs/smbfs/inode.c 1.42 -> 1.43 # mm/vmscan.c 1.170 -> 1.172 # net/ipv4/af_inet.c 1.56 -> 1.57 # drivers/media/dvb/frontends/grundig_29504-401.c 1.6 -> 1.7 # drivers/scsi/a2091.h 1.3 -> 1.4 # drivers/char/agp/frontend.c 1.40 -> 1.41 # drivers/block/cpqarray.c 1.79 -> 1.80 # fs/proc/task_mmu.c 1.4 -> 1.5 # net/ax25/ax25_dev.c 1.8 -> 1.9 # drivers/net/3c515.c 1.21 -> 1.23 # arch/x86_64/kernel/apic.c 1.22 -> 1.23 # arch/ia64/hp/common/sba_iommu.c 1.28 -> 1.29 # arch/i386/Kconfig 1.72 -> 1.74 # drivers/block/floppy.c 1.84 -> 1.87 # sound/oss/dmasound/dmasound_core.c 1.16 -> 1.17 # drivers/block/ataflop.c 1.42 -> 1.44 # net/ipv4/netfilter/ip_nat_core.c 1.29 -> 1.31 # sound/core/rawmidi.c 1.27 -> 1.29 # include/linux/genhd.h 1.55 -> 1.57 # sound/core/control.c 1.24 -> 1.25 # drivers/mtd/nand/autcpu12.c 1.2 -> 1.3 # include/asm-i386/bugs.h 1.9 -> 1.10 # include/asm-ppc/macio.h 1.2 -> 1.3 # net/ipv4/netfilter/ip_nat_helper.c 1.16 -> 1.17 # include/linux/tpqic02.h 1.4 -> 1.5 # arch/x86_64/kernel/msr.c 1.9 -> 1.10 # include/asm-sparc64/unistd.h 1.23 -> 1.24 # fs/jbd/journal.c 1.62 -> 1.63 # drivers/media/video/saa7134/saa7134-video.c 1.9 -> 1.10 # drivers/ieee1394/ieee1394_core.h 1.16 -> 1.17 # arch/sh/boards/dmida/mach.c 1.4 -> 1.5 # net/ipx/af_ipx.c 1.39 -> 1.41 # arch/arm/def-configs/iq80310 1.15 -> 1.16 # arch/i386/kernel/traps.c 1.56 -> 1.57 # drivers/ide/pci/cy82c693.c 1.14 -> 1.15 # init/main.c 1.105 -> 1.107 # arch/ppc/boot/simple/misc-embedded.c 1.8 -> 1.9 # net/ipv4/netfilter/ipt_multiport.c 1.5 -> 1.6 # arch/i386/kernel/Makefile 1.48 -> 1.49 # drivers/usb/class/usblp.c 1.57 -> 1.59 # include/asm-h8300/irq.h 1.3 -> 1.4 # arch/sh/boards/dreamcast/mach.c 1.7 -> 1.8 # arch/arm/mach-sa1100/leds.c 1.10 -> 1.11 # drivers/ide/legacy/qd65xx.c 1.7 -> 1.8 # drivers/ide/legacy/umc8672.c 1.8 -> 1.9 # drivers/char/watchdog/machzwd.c 1.21 -> 1.22 # drivers/net/tg3.h 1.25 -> 1.30 # net/bluetooth/af_bluetooth.c 1.21 -> 1.22 # drivers/ide/legacy/ali14xx.c 1.7 -> 1.8 # arch/arm26/kernel/setup.c 1.3 -> 1.4 # include/asm-ppc/unistd.h 1.25 -> 1.26 # drivers/usb/serial/xircom_pgs_fw.h 1.2 -> 1.3 # drivers/net/ixgb/ixgb_main.c 1.8 -> 1.9 # fs/bad_inode.c 1.8 -> 1.9 # drivers/usb/serial/io_fw_boot2.h 1.2 -> 1.3 # drivers/net/tulip/winbond-840.c 1.37 -> 1.38 # sound/oss/ite8172.c 1.20 -> 1.22 # drivers/char/agp/nvidia-agp.c 1.14 -> 1.16 # drivers/md/raid5.c 1.76 -> 1.77 # drivers/usb/serial/keyspan_usa49msg.h 1.5 -> 1.6 # drivers/media/dvb/dvb-core/dvbdev.c 1.14 -> 1.15 # kernel/Makefile 1.32 -> 1.33 # mm/swapfile.c 1.82 -> 1.83 # include/linux/ipv6_route.h 1.3 -> 1.4 # fs/freevxfs/vxfs_inode.c 1.11 -> 1.12 # net/ipv4/netfilter/ip_nat_amanda.c 1.3 -> 1.4 # drivers/video/controlfb.c 1.26 -> 1.27 # net/ax25/ax25_uid.c 1.4 -> 1.5 # drivers/net/ne2k-pci.c 1.15 -> 1.17 # drivers/i2c/Kconfig 1.13 -> 1.14 # drivers/char/cyclades.c 1.28 -> 1.29 # drivers/ieee1394/csr.c 1.14 -> 1.15 # drivers/atm/eni.c 1.20 -> 1.22 # include/linux/blkdev.h 1.123 -> 1.124 # net/ipv6/xfrm6_policy.c 1.11 -> 1.12 # net/ipv6/ip6_flowlabel.c 1.6 -> 1.9 # net/ipv4/netfilter/Makefile 1.21 -> 1.24 # drivers/usb/net/ax8817x.c 1.8 -> 1.9 # arch/ppc/configs/power3_defconfig 1.14 -> 1.15 # drivers/usb/serial/safe_serial.c 1.14 -> 1.16 # drivers/scsi/a3000.h 1.3 -> 1.4 # arch/i386/kernel/cpu/mtrr/mtrr.h 1.4 -> 1.5 # arch/x86_64/kernel/ioport.c 1.10 -> 1.11 # drivers/net/pcmcia/3c574_cs.c 1.22 -> 1.24 # sound/oss/btaudio.c 1.19 -> 1.20 # drivers/ieee1394/ieee1394_core.c 1.35 -> 1.37 # arch/sh/boards/ec3104/irq.c 1.1 -> 1.2 # drivers/scsi/3w-xxxx.h 1.22 -> 1.23 # arch/i386/kernel/cpu/mtrr/if.c 1.7 -> 1.8 # net/rxrpc/krxsecd.c 1.5 -> 1.6 # include/asm-sparc/smp.h 1.7 -> 1.8 # drivers/usb/core/message.c 1.35 -> 1.36 # net/ipv4/netfilter/ip_tables.c 1.18 -> 1.19 # drivers/net/ethertap.c 1.8 -> 1.10 # drivers/macintosh/mediabay.c 1.7 -> 1.9 # net/ipv6/netfilter/ip6t_limit.c 1.4 -> 1.5 # include/asm-arm/proc-armo/processor.h 1.4 -> 1.5 # arch/ia64/kernel/smpboot.c 1.37 -> 1.38 # arch/arm/def-configs/iq80321 1.3 -> 1.4 # scripts/kconfig/symbol.c 1.12 -> 1.13 # drivers/usb/serial/io_fw_down2.h 1.2 -> 1.3 # drivers/net/wan/Kconfig 1.9 -> 1.10 # drivers/scsi/sr.c 1.89 -> 1.90 # net/core/ethtool.c 1.2 -> 1.7 # include/linux/ethtool.h 1.19 -> 1.22 # net/key/af_key.c 1.48 -> 1.49 # drivers/char/ftape/lowlevel/fdc-io.c 1.10 -> 1.11 # arch/i386/mach-visws/mpparse.c 1.6 -> 1.7 # fs/jffs2/wbuf.c 1.7 -> 1.8 # include/linux/fs.h 1.262 -> 1.268 # arch/ia64/kernel/entry.S 1.48 -> 1.49 # arch/ia64/sn/kernel/setup.c 1.18 -> 1.19 # drivers/usb/storage/usb.c 1.76 -> 1.77 # net/bridge/netfilter/Kconfig 1.4 -> 1.7 # include/asm-i386/timer.h 1.9 -> 1.10 # kernel/futex.c 1.28 -> 1.29 # drivers/scsi/t128.h 1.8 -> 1.9 # include/asm-arm/arch-sa1100/simpad.h 1.4 -> 1.5 # Documentation/kobject.txt 1.8 -> 1.9 # drivers/block/paride/pt.c 1.18 -> 1.19 # drivers/scsi/aic7xxx/aic79xx_osm_pci.c 1.9 -> 1.10 # drivers/isdn/hardware/avm/Kconfig 1.2 -> 1.3 # drivers/net/pcnet32.c 1.40 -> 1.41 # drivers/char/n_hdlc.c 1.16 -> 1.17 # arch/h8300/platform/h8300h/ints.c 1.3 -> 1.5 # drivers/pcmcia/sa1111_generic.c 1.17 -> 1.18 # Documentation/filesystems/proc.txt 1.15 -> 1.16 # drivers/sbus/char/rtc.c 1.10 -> 1.11 # drivers/char/vc_screen.c 1.10 -> 1.11 # arch/ia64/mm/numa.c 1.1 -> 1.2 # drivers/ide/ide.c 1.87 -> 1.94 # sound/oss/via82cxxx_audio.c 1.32 -> 1.33 # arch/alpha/kernel/core_titan.c 1.19 -> 1.20 # drivers/md/md.c 1.175 -> 1.179 # net/ipv4/netfilter/ipt_physdev.c 1.6 -> 1.8 # arch/ppc/configs/common_defconfig 1.23 -> 1.24 # arch/sh/boards/dreamcast/irq.c 1.1 -> 1.2 # drivers/char/watchdog/cpu5wdt.c 1.2 -> 1.3 # Documentation/usb/hotplug.txt 1.4 -> 1.5 # drivers/net/sunlance.c 1.17 -> 1.18 # drivers/ide/legacy/dtc2278.c 1.7 -> 1.8 # drivers/scsi/advansys.c 1.35 -> 1.36 # drivers/scsi/aic7xxx/aic7xxx_osm_pci.c 1.9 -> 1.10 # net/ipv6/icmp.c 1.40 -> 1.43 # drivers/net/sungem_phy.c 1.1 -> 1.2 # drivers/usb/media/se401.c 1.38 -> 1.41 # arch/m68knommu/platform/5272/config.c 1.4 -> 1.5 # net/sunrpc/rpc_pipe.c 1.15 -> 1.16 # drivers/usb/serial/visor.c 1.68 -> 1.71 # drivers/ieee1394/ieee1394_transactions.h 1.7 -> 1.8 # arch/sh/boards/overdrive/mach.c 1.1 -> 1.2 # net/ipv4/netfilter/ip_nat_tftp.c 1.3 -> 1.4 # arch/i386/kernel/mpparse.c 1.48 -> 1.49 # drivers/pcmcia/cistpl.c 1.18 -> 1.19 # include/asm-arm/pci.h 1.20 -> 1.21 # net/bridge/br_forward.c 1.10 -> 1.11 # fs/dnotify.c 1.8 -> 1.10 # drivers/usb/serial/io_ti.h 1.1 -> 1.2 # arch/x86_64/kernel/mpparse.c 1.12 -> 1.13 # drivers/usb/media/ov511.c 1.49 -> 1.51 # drivers/scsi/hosts.h 1.74 -> 1.75 # net/irda/af_irda.c 1.45 -> 1.46 # drivers/s390/net/cu3088.c 1.5 -> 1.6 # drivers/char/lp_old98.c 1.2 -> 1.3 # net/ipv4/netfilter/ip_conntrack_tftp.c 1.4 -> 1.6 # include/asm-h8300/machine-depend.h 1.1 -> (deleted) # fs/reiserfs/inode.c 1.81 -> 1.82 # fs/intermezzo/vfs.c 1.24 -> 1.25 # drivers/ieee1394/ieee1394_transactions.c 1.16 -> 1.17 # arch/ppc/boot/openfirmware/Makefile 1.18 -> 1.19 # drivers/isdn/i4l/Kconfig 1.3 -> 1.4 # drivers/ide/ide-tape.c 1.27 -> 1.28 # drivers/usb/core/hcd.h 1.33 -> 1.34 # arch/cris/arch-v10/drivers/pcf8563.c 1.2 -> 1.3 # drivers/ide/pci/sl82c105.c 1.12 -> 1.13 # drivers/pcmcia/yenta_socket.h 1.6 -> 1.9 # drivers/net/sunhme.c 1.39 -> 1.41 # drivers/acorn/block/fd1772.c 1.38 -> 1.39 # sound/core/pcm_native.c 1.37 -> 1.39 # arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_irq.c 1.2 -> 1.3 # drivers/usb/media/vicam.c 1.38 -> 1.39 # net/ipv4/netfilter/ipt_REDIRECT.c 1.5 -> 1.6 # include/linux/cycx_drv.h 1.3 -> 1.4 # sound/oss/ad1889.c 1.6 -> 1.7 # drivers/usb/serial/whiteheat.c 1.39 -> 1.40 # fs/afs/dir.c 1.5 -> 1.6 # net/ipv4/netfilter/ipt_ULOG.c 1.10 -> 1.12 # arch/m68knommu/platform/5206e/config.c 1.4 -> 1.5 # arch/sparc64/solaris/socksys.c 1.12 -> 1.13 # drivers/macintosh/macio_asic.c 1.2 -> 1.5 # drivers/char/agp/generic.c 1.57 -> 1.58 # drivers/ide/pci/cs5530.c 1.13 -> 1.14 # drivers/isdn/i4l/isdn_common.c 1.75 -> 1.76 # arch/arm/vmlinux-armv.lds.in 1.26 -> 1.27 arch/arm/kernel/vmlinux.lds.S (moved) # drivers/mtd/maps/ceiva.c 1.4 -> 1.5 # drivers/ide/pci/triflex.c 1.2 -> 1.3 # drivers/ieee1394/pcilynx.c 1.35 -> 1.36 # drivers/usb/media/dsbr100.c 1.17 -> 1.18 # drivers/ide/pci/alim15x3.c 1.14 -> 1.15 # drivers/pcmcia/ti113x.h 1.14 -> 1.18 # security/capability.c 1.19 -> 1.20 # drivers/scsi/gdth.h 1.13 -> 1.14 # drivers/scsi/sgiwd93.h 1.3 -> 1.4 # Documentation/DocBook/kernel-locking.tmpl 1.7 -> 1.8 # drivers/ide/pci/siimage.c 1.13 -> 1.15 # net/ipv4/netfilter/iptable_filter.c 1.9 -> 1.10 # drivers/scsi/qlogicfc.h 1.9 -> 1.10 # drivers/net/sunqe.c 1.18 -> 1.19 # arch/arm/Makefile 1.44 -> 1.45 # ipc/sem.c 1.22 -> 1.23 # drivers/block/floppy98.c 1.10 -> 1.12 # sound/oss/rme96xx.c 1.15 -> 1.16 # drivers/isdn/hardware/eicon/divasi.c 1.7 -> 1.8 # arch/cris/arch-v10/drivers/eeprom.c 1.12 -> 1.14 # include/linux/sonypi.h 1.9 -> 1.10 # arch/h8300/platform/h8s/ints.c 1.2 -> 1.4 # include/linux/ide.h 1.67 -> 1.73 # drivers/net/yellowfin.c 1.25 -> 1.26 # drivers/scsi/nsp32.c 1.20 -> 1.21 # arch/i386/mach-voyager/voyager_smp.c 1.15 -> 1.16 # drivers/ide/pci/hpt34x.c 1.14 -> 1.15 # drivers/net/3c501.h 1.2 -> 1.3 # drivers/scsi/aacraid/linit.c 1.21 -> 1.22 # drivers/ide/pci/opti621.c 1.12 -> 1.13 # drivers/usb/storage/transport.c 1.83 -> 1.84 # include/asm-arm26/xor.h 1.1 -> 1.2 # drivers/video/platinumfb.c 1.20 -> 1.22 # net/core/scm.c 1.7 -> 1.8 # drivers/net/pcmcia/xirc2ps_cs.c 1.25 -> 1.27 # drivers/net/wireless/ray_cs.c 1.20 -> 1.21 # drivers/char/ftape/zftape/zftape-init.c 1.19 -> 1.20 # net/llc/llc_main.c 1.30 -> 1.32 # net/netlink/netlink_dev.c 1.18 -> 1.19 # net/ipv6/netfilter/ip6table_mangle.c 1.8 -> 1.9 # drivers/char/watchdog/advantechwdt.c 1.18 -> 1.19 # arch/arm/kernel/bios32.c 1.24 -> 1.26 # arch/s390/Kconfig 1.15 -> 1.16 # arch/ppc/platforms/sandpoint.h 1.4 -> 1.5 # include/net/ip6_tunnel.h 1.1 -> 1.2 # drivers/usb/image/scanner.h 1.38 -> 1.39 # arch/sparc64/solaris/timod.c 1.15 -> 1.17 # drivers/mtd/devices/Kconfig 1.4 -> 1.5 # drivers/char/rtc.c 1.29 -> 1.30 # drivers/usb/misc/auerswald.c 1.34 -> 1.35 # ipc/util.c 1.12 -> 1.13 # net/ipv4/netfilter/ip_nat_rule.c 1.10 -> 1.11 # include/linux/net.h 1.16 -> 1.17 # net/netsyms.c 1.96 -> 1.98 # security/selinux/ss/policydb.c 1.2 -> 1.3 # include/asm-x86_64/bitops.h 1.11 -> 1.12 # arch/mips/sibyte/sb1250/bcm1250_tbprof.c 1.2 -> 1.3 # arch/i386/pci/common.c 1.40 -> 1.41 # net/ipv4/netfilter/ipfwadm_core.c 1.17 -> 1.19 # drivers/media/video/saa7111.c 1.17 -> 1.18 # include/linux/pci_ids.h 1.116 -> 1.123 # drivers/usb/serial/usb-serial.c 1.89 -> 1.91 # arch/sparc/kernel/sys_sunos.c 1.24 -> 1.26 # drivers/usb/media/usbvideo.h 1.18 -> 1.19 # arch/ppc/boot/simple/relocate.S 1.5 -> 1.6 # drivers/char/dtlk.c 1.13 -> 1.14 # fs/hpfs/namei.c 1.20 -> 1.21 # arch/i386/kernel/msr.c 1.14 -> 1.15 # drivers/char/agp/agp.h 1.75 -> 1.81 # security/selinux/include/objsec.h 1.2 -> 1.3 # drivers/usb/input/hiddev.c 1.35 -> 1.37 # arch/sparc64/kernel/systbls.S 1.44 -> 1.47 # arch/x86_64/ia32/sys_ia32.c 1.36 -> 1.37 # drivers/char/lcd.c 1.1 -> 1.2 # arch/arm/kernel/entry-header.S 1.8 -> 1.9 # drivers/net/sis900.c 1.41 -> 1.43 # include/linux/usb.h 1.87 -> 1.88 # include/linux/usb_gadget.h 1.4 -> 1.5 # drivers/net/dummy.c 1.5 -> 1.6 # drivers/ide/ide-cd.c 1.57 -> 1.58 # sound/oss/sonicvibes.c 1.27 -> 1.28 # drivers/atm/Kconfig 1.6 -> 1.7 # net/ipv4/netfilter/ip_conntrack_standalone.c 1.19 -> 1.20 # arch/arm/common/amba.c 1.2 -> 1.3 # include/asm-arm/xor.h 1.4 -> 1.5 # include/asm-x86_64/mpspec.h 1.7 -> 1.8 # mm/memory.c 1.129 -> 1.133 # drivers/ide/pci/ns87415.c 1.11 -> 1.12 # drivers/net/ni5010.c 1.10 -> 1.11 # arch/arm/mach-sa1100/leds-simpad.c 1.3 -> 1.4 # drivers/net/hamradio/bpqether.c 1.12 -> 1.13 # drivers/scsi/sg.c 1.62 -> 1.63 # drivers/usb/serial/pl2303.c 1.45 -> 1.46 # arch/v850/Kconfig 1.17 -> 1.18 # include/asm-ppc/cpm_8260.h 1.4 -> 1.5 # drivers/net/epic100.c 1.34 -> 1.35 # arch/sparc/kernel/entry.S 1.14 -> 1.15 # fs/compat.c 1.14 -> 1.15 # drivers/usb/serial/digi_acceleport.c 1.35 -> 1.38 # drivers/usb/usb-skeleton.c 1.41 -> 1.45 # drivers/pcmcia/ricoh.h 1.8 -> 1.10 # drivers/usb/serial/ir-usb.c 1.29 -> 1.30 # drivers/net/8139cp.c 1.43 -> 1.56 # drivers/ide/Kconfig 1.26 -> 1.27 # drivers/block/amiflop.c 1.43 -> 1.45 # include/asm-h8300/edosk2674/timer_rate.h 1.1 -> (deleted) # net/core/netfilter.c 1.23 -> 1.24 # arch/ppc/configs/ibmchrp_defconfig 1.14 -> 1.15 # arch/ia64/kernel/mca.c 1.39 -> 1.41 # drivers/block/genhd.c 1.92 -> 1.93 # include/asm-arm/arch-iop3xx/iop310.h 1.4 -> 1.5 # fs/affs/file.c 1.25 -> 1.26 # arch/i386/kernel/setup.c 1.94 -> 1.95 # include/asm-ia64/hw_irq.h 1.8 -> 1.9 # drivers/scsi/osst.c 1.48 -> 1.49 # drivers/scsi/pci2220i.h 1.6 -> 1.7 # drivers/usb/core/hcd-pci.c 1.20 -> 1.21 # arch/mips/Kconfig 1.15 -> 1.16 # net/ipv4/netfilter/ipt_ecn.c 1.3 -> 1.4 # drivers/media/video/saa7134/saa7134-oss.c 1.6 -> 1.7 # drivers/net/wan/cycx_main.c 1.14 -> 1.15 # drivers/input/serio/sa1111ps2.c 1.9 -> 1.10 # drivers/net/3c523.c 1.11 -> 1.12 # Documentation/DocBook/writing_usb_driver.tmpl 1.2 -> 1.4 # drivers/char/agp/intel-agp.c 1.48 -> 1.49 # arch/ia64/kernel/acpi.c 1.47 -> 1.48 # drivers/serial/Makefile 1.18 -> 1.19 # drivers/char/tpqic02.c 1.23 -> 1.25 # drivers/scsi/mvme16x.h 1.4 -> 1.5 # arch/i386/kernel/time.c 1.39 -> 1.40 # arch/sh/boards/adx/mach.c 1.4 -> 1.5 # sound/oss/soundcard.c 1.22 -> 1.23 # arch/mips/kernel/ioctl32.c 1.13 -> 1.14 # drivers/ide/pci/sis5513.c 1.17 -> 1.18 # drivers/usb/storage/isd200.c 1.32 -> 1.33 # net/econet/af_econet.c 1.22 -> 1.24 # arch/ppc/boot/of1275/Makefile 1.4 -> 1.5 # drivers/input/joydev.c 1.18 -> 1.19 # net/rose/af_rose.c 1.30 -> 1.32 # net/netrom/af_netrom.c 1.36 -> 1.38 # include/linux/tty.h 1.19 -> 1.20 # arch/sparc/kernel/systbls.S 1.21 -> 1.23 # net/netlink/af_netlink.c 1.30 -> 1.32 # ipc/shm.c 1.28 -> 1.29 # fs/coda/inode.c 1.27 -> 1.29 # net/core/dev.c 1.95 -> 1.97 # arch/x86_64/kernel/io_apic.c 1.13 -> 1.14 # kernel/compat.c 1.21 -> 1.22 # drivers/media/common/saa7146_fops.c 1.5 -> 1.6 # drivers/char/generic_serial.c 1.12 -> 1.13 # include/linux/cyclomx.h 1.8 -> 1.9 # drivers/usb/core/usb.c 1.136 -> 1.138 # drivers/usb/misc/brlvger.c 1.20 -> 1.22 # drivers/media/dvb/frontends/ves1820.c 1.7 -> 1.8 # drivers/char/mem.c 1.42 -> 1.43 # drivers/char/dsp56k.c 1.13 -> 1.14 # net/ipv4/netfilter/ipt_esp.c 1.7 -> 1.8 # kernel/posix-timers.c 1.19 -> 1.20 # net/ipv4/netfilter/ipt_TCPMSS.c 1.9 -> 1.10 # drivers/char/watchdog/wdt.c 1.20 -> 1.21 # drivers/md/xor.c 1.7 -> 1.8 # drivers/usb/host/ohci-sa1111.c 1.16 -> 1.17 # include/linux/personality.h 1.5 -> 1.6 # drivers/s390/char/tubio.h 1.13 -> 1.14 # drivers/scsi/i91uscsi.h 1.4 -> 1.5 # drivers/pci/pci.ids 1.50 -> 1.52 # arch/x86_64/ia32/ia32_ioctl.c 1.30 -> 1.31 # net/decnet/af_decnet.c 1.31 -> 1.32 # arch/sh/boards/se/7751/mach.c 1.4 -> 1.5 # drivers/scsi/ini9100u.h 1.10 -> 1.11 # net/ipv4/netfilter/ipt_MARK.c 1.4 -> 1.5 # arch/ppc/kernel/cputable.c 1.11 -> 1.12 # include/asm-m68knommu/irq.h 1.1 -> 1.2 # drivers/net/pcmcia/ibmtr_cs.c 1.17 -> 1.18 # include/asm-h8300/pci.h 1.2 -> 1.3 # drivers/usb/serial/keyspan_pda_fw.h 1.2 -> 1.3 # arch/ia64/sn/io/sn2/shub.c 1.4 -> 1.5 # sound/oss/cmpci.c 1.26 -> 1.27 # include/asm-x86_64/suspend.h 1.6 -> 1.7 # drivers/net/sunbmac.c 1.18 -> 1.19 # arch/arm/Kconfig 1.31 -> 1.32 # drivers/media/video/meye.h 1.8 -> 1.9 # drivers/ide/pci/siimage.h 1.6 -> 1.7 # arch/ppc/boot/openfirmware/coffmain.c 1.11 -> 1.12 # sound/oss/swarm_cs4297a.c 1.3 -> 1.4 # drivers/usb/net/usbnet.c 1.68 -> 1.73 # fs/proc/kcore.c 1.9 -> 1.11 # drivers/usb/image/mdc800.c 1.31 -> 1.33 # include/linux/wait.h 1.13 -> 1.14 # arch/ppc/boot/simple/misc-spruce.c 1.5 -> 1.6 # arch/ppc64/Kconfig 1.26 -> 1.27 # drivers/input/input.c 1.33 -> 1.35 # drivers/md/raid0.c 1.35 -> 1.36 # fs/cifs/cifsfs.c 1.30 -> 1.31 # drivers/net/sk_mca.h 1.2 -> 1.3 # drivers/char/drm/drm_fops.h 1.11 -> 1.12 # arch/ppc/kernel/head.S 1.32 -> 1.33 # drivers/net/tg3.c 1.82 -> 1.106 # sound/oss/vwsnd.c 1.10 -> 1.11 # drivers/media/video/zoran_device.c 1.1 -> 1.4 # include/linux/mmzone.h 1.41 -> 1.42 # drivers/usb/serial/keyspan_usa26msg.h 1.5 -> 1.6 # drivers/net/pcmcia/axnet_cs.c 1.16 -> 1.18 # drivers/usb/serial/kl5kusb105.c 1.24 -> 1.25 # net/ipv6/af_inet6.c 1.54 -> 1.55 # drivers/sbus/char/vfc_dev.c 1.11 -> 1.12 # drivers/net/3c527.c 1.13 -> 1.15 # fs/ext3/xattr.c 1.24 -> 1.25 # drivers/scsi/mac_scsi.h 1.5 -> 1.6 # include/linux/netfilter_bridge.h 1.5 -> 1.6 # drivers/media/video/zoran_card.c 1.2 -> 1.6 # drivers/ide/pci/hpt366.c 1.21 -> 1.23 # drivers/usb/media/dabusb.c 1.32 -> 1.35 # net/xfrm/xfrm_user.c 1.36 -> 1.37 # arch/ia64/kernel/sys_ia64.c 1.25 -> 1.26 # arch/m68knommu/platform/5249/config.c 1.4 -> 1.5 # arch/sh/boards/harp/mach.c 1.3 -> 1.4 # fs/afs/callback.c 1.1 -> 1.2 # drivers/char/agp/Kconfig 1.24 -> 1.25 # include/asm-ppc/of_device.h 1.1 -> 1.2 # arch/ppc/platforms/pmac_cpufreq.c 1.6 -> 1.8 # arch/ppc/boot/openfirmware/misc.S 1.4 -> 1.5 # drivers/ide/ide-probe.c 1.58 -> 1.64 # drivers/usb/core/hcd.c 1.72 -> 1.74 # arch/arm26/Kconfig 1.6 -> 1.7 # arch/ppc/syslib/open_pic.c 1.27 -> 1.28 # arch/sparc64/kernel/pci_psycho.c 1.24 -> 1.25 # include/asm-arm26/processor.h 1.2 -> 1.3 # drivers/usb/input/hid-core.c 1.63 -> 1.65 # arch/m68knommu/platform/5206/config.c 1.4 -> 1.5 # fs/ext3/namei.c 1.45 -> 1.46 # drivers/usb/serial/belkin_sa.c 1.37 -> 1.38 # drivers/net/wan/cycx_drv.c 1.8 -> 1.9 # drivers/media/video/meye.c 1.18 -> 1.19 # drivers/char/epca.c 1.30 -> 1.31 # include/asm-i386/smp.h 1.28 -> 1.29 # include/linux/skbuff.h 1.29 -> 1.30 # drivers/char/sonypi.h 1.16 -> 1.18 # fs/intermezzo/presto.c 1.13 -> 1.14 # drivers/media/video/vpx3220.c 1.2 -> 1.3 # arch/m68k/Kconfig 1.20 -> 1.21 # drivers/char/tty_io.c 1.113 -> 1.115 # drivers/usb/input/powermate.c 1.15 -> 1.16 # drivers/char/pcxx.c 1.19 -> 1.20 # fs/bio.c 1.49 -> 1.50 # MAINTAINERS 1.166.1.6 -> 1.171 # fs/jffs/inode-v23.c 1.50 -> 1.52 # arch/parisc/Kconfig 1.20 -> 1.21 # arch/ppc/configs/mcpn765_defconfig 1.8 -> 1.9 # drivers/pcmcia/yenta_socket.c 1.38 -> 1.45 # drivers/ide/pci/sc1200.c 1.8 -> 1.9 # arch/sh/boards/hp6xx/hp620/mach.c 1.6 -> 1.7 # net/ipv4/netfilter/ipt_unclean.c 1.10 -> (deleted) # arch/ia64/ia32/sys_ia32.c 1.73 -> 1.75 # drivers/ieee1394/nodemgr.c 1.34 -> 1.35 # drivers/block/rd.c 1.77 -> 1.79 # arch/sparc64/kernel/sys_sunos32.c 1.33 -> 1.35 # net/ipv4/netfilter/ipt_MASQUERADE.c 1.9 -> 1.10 # sound/oss/msnd_pinnacle.c 1.14 -> 1.15 # drivers/char/istallion.c 1.30 -> 1.31 # drivers/char/raw.c 1.33 -> 1.36 # include/net/irda/vlsi_ir.h 1.9 -> 1.12 # arch/sh/boards/saturn/irq.c 1.1 -> 1.2 # drivers/ieee1394/eth1394.c 1.22 -> 1.23 # sound/oss/ymfpci.c 1.37 -> 1.38 # drivers/telephony/phonedev.c 1.7 -> 1.8 # net/bridge/netfilter/Makefile 1.5 -> 1.7 # fs/proc/base.c 1.53 -> 1.55 # drivers/char/watchdog/acquirewdt.c 1.24 -> 1.26 # net/unix/af_unix.c 1.50 -> 1.51 # fs/coda/psdev.c 1.17 -> 1.18 # include/asm-arm/arch-ebsa285/timex.h 1.1 -> 1.2 # arch/sparc64/kernel/sys_sparc32.c 1.79 -> 1.81 # arch/v850/kernel/vmlinux.lds.S 1.14 -> 1.15 # net/ipv4/netfilter/ipt_ah.c 1.7 -> 1.8 # drivers/char/watchdog/wdt_pci.c 1.26 -> 1.27 # include/asm-arm/arch-pxa/pxa-regs.h 1.6 -> 1.7 # drivers/usb/class/cdc-acm.c 1.49 -> 1.50 # drivers/usb/misc/rio500.c 1.24 -> 1.26 # arch/ppc/boot/ld.script 1.6 -> 1.7 # drivers/scsi/st.c 1.69 -> 1.70 # drivers/block/z2ram.c 1.27 -> 1.29 # fs/vfat/namei.c 1.41 -> 1.42 # net/bluetooth/rfcomm/sock.c 1.22 -> 1.23 # drivers/media/common/saa7146_video.c 1.7 -> 1.8 # drivers/usb/storage/usb.h 1.36 -> 1.37 # sound/core/oss/mixer_oss.c 1.18 -> 1.19 # arch/ia64/sn/io/drivers/ioconfig_bus.c 1.3 -> 1.4 # sound/oss/au1000.c 1.2 -> 1.3 # drivers/char/agp/ali-agp.c 1.28 -> 1.29 # drivers/isdn/i4l/isdn_ppp.c 1.76 -> 1.77 # include/linux/nfsd/nfsfh.h 1.12 -> 1.14 # drivers/usb/serial/keyspan_pda.c 1.32 -> 1.34 # drivers/usb/host/ehci-hcd.c 1.57 -> 1.60 # security/selinux/ss/ebitmap.c 1.1 -> 1.2 # drivers/net/sk_mca.c 1.13 -> 1.15 # drivers/usb/serial/io_edgeport.h 1.3 -> 1.4 # include/net/ax25.h 1.13 -> 1.14 # drivers/char/watchdog/Kconfig 1.11 -> 1.12 # Makefile 1.422 -> 1.424 # arch/s390/kernel/compat_ioctl.c 1.5 -> 1.6 # fs/fcntl.c 1.28 -> 1.29 # drivers/usb/serial/mct_u232.c 1.39 -> 1.40 # arch/sparc64/mm/hugetlbpage.c 1.7 -> 1.8 # drivers/net/pcmcia/fmvj18x_cs.c 1.24 -> 1.25 # net/ipv4/netfilter/ip_nat_ftp.c 1.11 -> 1.12 # drivers/char/agp/amd-k8-agp.c 1.52 -> 1.56 # net/packet/af_packet.c 1.32 -> 1.33 # Documentation/ide.txt 1.9 -> 1.10 # drivers/usb/media/stv680.c 1.29 -> 1.33 # arch/i386/kernel/timers/timer_tsc.c 1.23 -> 1.24 # arch/sparc64/kernel/pci_schizo.c 1.30 -> 1.31 # net/sunrpc/xprt.c 1.69 -> 1.70 # sound/core/sound.c 1.31 -> 1.32 # arch/ppc/platforms/mcpn765_setup.c 1.11 -> 1.12 # net/ax25/ax25_route.c 1.12 -> 1.13 # arch/x86_64/defconfig 1.25 -> 1.26 # arch/mips/vr41xx/common/vrc4173.c 1.2 -> 1.3 # drivers/net/arcnet/arcnet.c 1.15 -> 1.16 # arch/x86_64/kernel/time.c 1.20 -> 1.21 # drivers/i2c/i2c-keywest.c 1.3 -> 1.6 # net/bluetooth/bnep/core.c 1.18 -> 1.20 # drivers/char/ite_gpio.c 1.5 -> 1.6 # net/bluetooth/l2cap.c 1.31 -> 1.32 # drivers/mtd/mtdchar.c 1.14 -> 1.15 # net/ipv4/netfilter/ipt_dscp.c 1.3 -> 1.4 # drivers/scsi/pas16.h 1.8 -> 1.9 # drivers/scsi/aha1542.h 1.9 -> 1.10 # include/asm-x86_64/topology.h 1.4 -> 1.5 # include/asm-x86_64/percpu.h 1.9 -> 1.10 # drivers/char/agp/backend.c 1.84 -> 1.85 # arch/m68knommu/Kconfig 1.20 -> 1.21 # include/asm-h8300/aki3068net/timer_rate.h 1.1 -> (deleted) # drivers/net/fealnx.c 1.29 -> 1.31 # drivers/net/8390.h 1.10 -> 1.11 # drivers/net/3c503.c 1.13 -> 1.14 # CREDITS 1.95 -> 1.97 # drivers/video/riva/fbdev.c 1.48 -> 1.49 # sound/oss/emu10k1/mixer.c 1.10 -> 1.11 # fs/nfsd/nfs4state.c 1.11 -> 1.15 # drivers/video/68328fb.c 1.2 -> 1.3 # include/asm-i386/mc146818rtc.h 1.1 -> 1.3 # include/asm-h8300/h8max/machine-depend.h 1.1 -> 1.2 # drivers/char/agp/ati-agp.c 1.6 -> 1.8 # drivers/char/sonypi.c 1.17 -> 1.18 # include/asm-m68k/system.h 1.9 -> 1.10 # net/ipv6/ipv6_syms.c 1.17 -> 1.18 # drivers/usb/host/ohci-pci.c 1.14 -> 1.17 # net/ipv4/netfilter/arpt_mangle.c 1.1 -> 1.2 # arch/sh/boards/bigsur/mach.c 1.3 -> 1.4 # drivers/char/tipar.c 1.7 -> 1.8 # drivers/char/watchdog/Makefile 1.7 -> 1.8 # include/asm-ppc/prom.h 1.10 -> 1.11 # net/core/skbuff.c 1.29 -> 1.30 # security/selinux/ss/avtab.c 1.1 -> 1.2 # arch/ppc64/kernel/proc_ppc64.c 1.1 -> 1.2 # drivers/media/video/zoran.h 1.4 -> 1.6 # drivers/input/evdev.c 1.27 -> 1.29 # drivers/usb/gadget/net2280.h 1.3 -> 1.4 # arch/ppc/8xx_io/uart.c 1.30 -> 1.31 # drivers/sbus/char/display7seg.c 1.7 -> 1.8 # net/ipv4/ipvs/ip_vs_sh.c 1.1 -> 1.2 # arch/arm/mach-iop3xx/iq80310-time.c 1.10 -> 1.11 # drivers/ide/pci/pdc202xx_new.c 1.17 -> 1.18 # drivers/usb/net/Kconfig 1.6 -> 1.7 # include/asm-sparc/pci.h 1.10 -> 1.11 # include/asm-sparc64/siginfo.h 1.11 -> 1.12 # net/ipv4/netfilter/ipt_helper.c 1.6 -> 1.7 # drivers/net/irda/Kconfig 1.8 -> 1.10 # drivers/net/hamradio/yam.c 1.19 -> 1.20 # sound/oss/nec_vrc5477.c 1.17 -> 1.18 # arch/ia64/ia32/ia32_ioctl.c 1.14 -> 1.15 # drivers/media/video/zoran_driver.c 1.1 -> 1.4 # net/ipv6/route.c 1.57 -> 1.58 # sound/oss/es1371.c 1.31 -> 1.32 # drivers/char/stallion.c 1.33 -> 1.35 # drivers/usb/class/bluetty.c 1.48 -> 1.49 # Documentation/video4linux/meye.txt 1.6 -> 1.7 # drivers/usb/serial/io_usbvend.h 1.8 -> 1.10 # drivers/net/seeq8005.c 1.13 -> 1.14 # drivers/net/tulip/Kconfig 1.5 -> 1.6 # arch/mips/sibyte/cfe/console.c 1.2 -> 1.4 # include/asm-i386/i387.h 1.12 -> 1.13 # arch/arm/mach-sa1100/leds.h 1.7 -> 1.8 # sound/oss/i810_audio.c 1.44 -> 1.45 # sound/oss/trident.c 1.45 -> 1.46 # drivers/pcmcia/ds.c 1.37 -> 1.38 # drivers/media/video/bttv-driver.c 1.32 -> 1.33 # drivers/ide/pci/slc90e66.c 1.12 -> 1.13 # drivers/block/DAC960.c 1.65 -> 1.66 # arch/alpha/Kconfig 1.25 -> 1.26 # arch/arm/kernel/ecard.c 1.24 -> 1.25 # drivers/block/DAC960.h 1.23 -> 1.24 # drivers/ide/pci/pdcadma.c 1.12 -> 1.13 # drivers/usb/media/pwc-if.c 1.38 -> 1.39 # drivers/s390/char/tape_char.c 1.3 -> 1.5 # drivers/net/3c507.c 1.12 -> 1.13 # arch/ppc/platforms/mcpn765_serial.h 1.3 -> 1.4 # drivers/usb/media/stv680.h 1.6 -> 1.8 # sound/oss/hal2.c 1.3 -> 1.4 # drivers/usb/storage/unusual_devs.h 1.51 -> 1.52 # drivers/i2c/i2c-dev.c 1.35 -> 1.36 # net/ipv4/netfilter/ip_conntrack_irc.c 1.14 -> 1.15 # arch/x86_64/kernel/vsyscall.c 1.11 -> 1.12 # arch/h8300/Kconfig 1.7 -> 1.8 # fs/nfs/inode.c 1.85 -> 1.86 # drivers/net/tulip/xircom_cb.c 1.16 -> 1.17 # net/ipv4/netfilter/arp_tables.c 1.10 -> 1.11 # net/ipv4/netfilter/ip_conntrack_ftp.c 1.16 -> 1.17 # drivers/scsi/bvme6000.h 1.4 -> 1.5 # drivers/usb/serial/ftdi_sio.c 1.49 -> 1.51 # drivers/ide/pci/it8172.c 1.10 -> 1.11 # net/ipv4/netfilter/ip_nat_standalone.c 1.24 -> 1.25 # arch/x86_64/Kconfig 1.28 -> 1.29 # sound/core/seq/oss/seq_oss.c 1.5 -> 1.6 # kernel/sched.c 1.207 -> 1.208 # sound/oss/ali5455.c 1.3 -> 1.4 # drivers/media/video/planb.c 1.16 -> 1.17 # net/ipv4/netfilter/ip_fw_compat_masq.c 1.10 -> 1.11 # drivers/Makefile 1.39 -> 1.40 # arch/sh/boards/ec3104/mach.c 1.3 -> 1.4 # arch/ppc/boot/simple/misc.c 1.11 -> 1.12 # Documentation/sysctl/README 1.1 -> 1.2 # drivers/net/tulip/de2104x.c 1.23 -> 1.24 # drivers/ide/legacy/ht6560b.c 1.7 -> 1.8 # drivers/usb/net/Makefile.mii 1.2 -> 1.3 # init/Kconfig 1.22 -> 1.24 # drivers/usb/storage/sddr09.c 1.26 -> 1.27 # drivers/ide/pci/aec62xx.c 1.13 -> 1.14 # drivers/char/drm/drm_stub.h 1.8 -> 1.9 # net/llc/llc_mac.c 1.22 -> 1.23 # include/net/ipv6.h 1.25 -> 1.26 # net/ipv4/netfilter/ip_nat_snmp_basic.c 1.10 -> 1.11 # arch/ppc/defconfig 1.22 -> 1.23 # drivers/char/busmouse.c 1.9 -> 1.10 # drivers/ide/ide-io.c 1.17 -> 1.18 # drivers/scsi/dpt_i2o.c 1.33 -> 1.34 # arch/ppc/boot/utils/mktree.c 1.2 -> 1.3 # drivers/usb/serial/ipaq.c 1.32 -> 1.33 # drivers/char/drm/drm_drv.h 1.23 -> 1.24 # net/ipv4/ipvs/ip_vs_lblcr.c 1.1 -> 1.2 # net/ipv4/netfilter/Kconfig 1.9 -> 1.15 # drivers/media/video/zoran_card.h 1.1 -> 1.2 # include/linux/kdev_t.h 1.10 -> 1.11 # net/ipv4/netfilter/ipt_REJECT.c 1.19 -> 1.22 # arch/sh/boards/sh2000/mach.c 1.2 -> 1.3 # drivers/usb/serial/io_ionsp.h 1.3 -> 1.4 # drivers/media/video/saa7114.c 1.2 -> 1.4 # kernel/timer.c 1.66 -> 1.67 # fs/nfsd/nfs4xdr.c 1.21 -> 1.22 # net/ipv4/ipvs/ip_vs_dh.c 1.1 -> 1.2 # drivers/usb/serial/visor.h 1.20 -> 1.21 # drivers/net/eth16i.c 1.14 -> 1.15 # drivers/char/agp/via-agp.c 1.49 -> 1.51 # drivers/cdrom/Kconfig 1.3 -> 1.4 # drivers/net/pcmcia/pcnet_cs.c 1.22 -> 1.24 # drivers/block/paride/pg.c 1.19 -> 1.20 # drivers/char/ipmi/ipmi_devintf.c 1.8 -> 1.9 # net/ipv4/netfilter/ipchains_core.c 1.16 -> 1.17 # include/asm-arm/arch-iop3xx/memory.h 1.8 -> 1.9 # drivers/ieee1394/ohci1394.c 1.44 -> 1.45 # drivers/net/Kconfig 1.40 -> 1.45 # arch/ppc/boot/of1275/ofinit.c 1.1 -> 1.2 # drivers/usb/serial/io_fw_down3.h 1.1 -> 1.2 # net/ipv6/mcast.c 1.32 -> 1.33 # sound/core/oss/pcm_oss.c 1.27 -> 1.28 # arch/sh/boards/se/770x/mach.c 1.5 -> 1.6 # drivers/usb/serial/io_16654.h 1.1 -> 1.3 # arch/i386/kernel/acpi/boot.c 1.29 -> 1.31 # drivers/usb/serial/kobil_sct.c 1.12 -> 1.13 # fs/ext2/namei.c 1.20 -> 1.21 # arch/arm/mach-iop3xx/iop321-time.c 1.1 -> 1.2 # drivers/scsi/gvp11.h 1.3 -> 1.4 # net/sunrpc/timer.c 1.6 -> 1.7 # net/ipv4/netfilter/ipt_LOG.c 1.8 -> 1.10 # arch/sparc64/Kconfig 1.30 -> 1.31 # net/ipv4/netfilter/iptable_mangle.c 1.14 -> 1.15 # net/ipv6/netfilter/Kconfig 1.2 -> 1.3 # drivers/usb/media/se401.h 1.5 -> 1.6 # sound/oss/maestro.c 1.35 -> 1.36 # drivers/usb/serial/omninet.c 1.31 -> 1.32 # kernel/exit.c 1.111 -> 1.112 # drivers/ide/pci/cmd64x.c 1.11 -> 1.13 # drivers/scsi/psi240i.h 1.5 -> 1.6 # drivers/media/video/zoran_procfs.c 1.4 -> 1.6 # drivers/usb/host/uhci-hcd.c 1.40 -> 1.43 # net/ipv6/netfilter/ip6_tables.c 1.21 -> 1.22 # include/asm-arm/hardware/amba.h 1.1 -> 1.2 # arch/m68k/vmlinux-std.lds 1.17 -> 1.18 arch/m68k/kernel/vmlinux-std.lds (moved) # drivers/net/tulip/dmfe.c 1.34 -> 1.35 # sound/oss/maestro3.c 1.29 -> 1.30 # include/asm-x86_64/ia32.h 1.14 -> 1.15 # drivers/i2c/i2c-keywest.h 1.1 -> 1.2 # include/asm-arm/checksum.h 1.5 -> 1.6 # drivers/media/video/tvmixer.c 1.18 -> 1.19 # arch/sparc64/kernel/ioctl32.c 1.67 -> 1.68 # net/ipv4/ipvs/ip_vs_lblc.c 1.1 -> 1.2 # arch/ppc/kernel/ppc-stub.c 1.9 -> 1.11 # net/appletalk/atalk_proc.c 1.5 -> 1.8 # arch/ppc/platforms/pmac_pic.c 1.18 -> 1.19 # drivers/scsi/Kconfig 1.25 -> 1.26 # arch/sh/boards/cqreek/mach.c 1.1 -> 1.2 # net/ipv6/netfilter/ip6t_mac.c 1.5 -> 1.6 # drivers/media/dvb/ttusb-dec/ttusb_dec.c 1.3 -> 1.4 # drivers/macintosh/via-pmu.c 1.21 -> 1.24 # drivers/media/video/stradis.c 1.15 -> 1.16 # drivers/usb/serial/cyberjack.c 1.29 -> 1.31 # arch/ppc/configs/pmac_defconfig 1.15 -> 1.16 # net/ipv4/ipvs/ip_vs_conn.c 1.5 -> 1.6 # arch/ppc/kernel/ppc_ksyms.c 1.42 -> 1.44 # net/ipv4/netfilter/ipt_conntrack.c 1.5 -> 1.6 # net/ipv6/netfilter/ip6t_MARK.c 1.4 -> 1.5 # drivers/media/video/adv7175.c 1.16 -> 1.18 # arch/arm/common/sa1111.c 1.28 -> 1.29 # fs/partitions/check.c 1.117 -> 1.118 # drivers/char/watchdog/ib700wdt.c 1.17 -> 1.18 # arch/ppc/kernel/misc.S 1.45 -> 1.46 # drivers/input/mousedev.c 1.25 -> 1.27 # drivers/scsi/pci2000.h 1.7 -> 1.8 # arch/ppc64/kernel/scanlog.c 1.1 -> 1.2 # net/ax25/af_ax25.c 1.28 -> 1.30 # drivers/serial/Kconfig 1.14 -> 1.15 # arch/sparc/boot/Makefile 1.15 -> 1.16 # include/asm-ia64/pci.h 1.20 -> 1.21 # drivers/media/video/adv7170.c 1.2 -> 1.4 # net/irda/irsyms.c 1.15 -> 1.16 # drivers/sbus/char/cpwatchdog.c 1.10 -> 1.11 # drivers/media/video/Kconfig 1.12 -> 1.13 # security/selinux/ss/global.h 1.2 -> 1.3 # drivers/ide/pci/cmd640.c 1.6 -> 1.7 # arch/sparc64/kernel/irq.c 1.33 -> 1.34 # arch/mips/au1000/common/dma.c 1.1 -> 1.2 # drivers/char/misc.c 1.20 -> 1.21 # arch/ia64/kernel/perfmon.c 1.56 -> 1.57 # drivers/scsi/3w-xxxx.c 1.37 -> 1.38 # drivers/usb/host/ohci-q.c 1.42 -> 1.43 # net/ipv4/netfilter/ipt_owner.c 1.9 -> 1.10 # arch/i386/oprofile/nmi_int.c 1.17 -> 1.18 # drivers/char/watchdog/wafer5823wdt.c 1.7 -> 1.10 # net/ipv4/icmp.c 1.34 -> 1.35 # include/asm-arm/unistd.h 1.16 -> 1.17 # include/linux/netdevice.h 1.52 -> 1.54 # security/selinux/hooks.c 1.3 -> 1.5 # arch/ppc/kernel/setup.c 1.44 -> 1.45 # arch/ppc/kernel/smp.c 1.35 -> 1.36 # drivers/net/pcmcia/3c589_cs.c 1.21 -> 1.22 # arch/ia64/Kconfig 1.38 -> 1.40 # fs/compat_ioctl.c 1.4 -> 1.5 # arch/sparc64/solaris/misc.c 1.15 -> 1.17 # net/x25/af_x25.c 1.30 -> 1.32 # arch/ppc/kernel/syscalls.c 1.12 -> 1.13 # arch/ia64/lib/Makefile 1.21 -> 1.22 # arch/sh/boards/cat68701/mach.c 1.3 -> 1.4 # arch/arm/kernel/apm.c 1.2 -> 1.4 # drivers/usb/misc/usbtest.c 1.20 -> 1.21 # net/bridge/Makefile 1.8 -> 1.9 # drivers/media/dvb/ttusb-dec/dec2000_frontend.c 1.1 -> 1.2 # drivers/isdn/capi/capi.c 1.46 -> 1.47 # net/ipv4/netfilter/ipt_DSCP.c 1.3 -> 1.4 # net/ipv4/netfilter/ipt_tos.c 1.4 -> 1.5 # include/asm-h8300/aki3068net/ne.h 1.2 -> (deleted) # arch/i386/kernel/timers/timer.c 1.10 -> 1.11 # net/appletalk/aarp.c 1.11 -> 1.16 # sound/ppc/keywest.c 1.9 -> 1.10 # drivers/input/tsdev.c 1.11 -> 1.12 # drivers/net/sungem.c 1.43 -> 1.44 # include/asm-h8300/h8max/timer_rate.h 1.1 -> (deleted) # drivers/ide/ide-lib.c 1.9 -> 1.11 # drivers/ide/ppc/mpc8xx.c 1.6 -> 1.7 # arch/sh/boards/saturn/mach.c 1.2 -> 1.3 # arch/arm/vmlinux-armo.lds.in 1.16 -> (deleted) # drivers/isdn/Kconfig 1.2 -> 1.3 # drivers/block/cciss.c 1.86 -> 1.89 # drivers/net/wireless/airport.c 1.15 -> 1.17 # drivers/usb/serial/io_ti.c 1.20 -> 1.24 # drivers/parport/parport_pc.c 1.41 -> 1.42 # arch/ppc/boot/common/ns16550.c 1.5 -> 1.6 # arch/mips/tx4927/common/tx4927_irq.c 1.1 -> 1.2 # sound/sound_core.c 1.19 -> 1.20 # drivers/char/ppdev.c 1.21 -> 1.22 # drivers/net/tokenring/lanstreamer.c 1.21 -> 1.22 # drivers/net/via-rhine.c 1.47 -> 1.48 # arch/sparc64/kernel/pci_sabre.c 1.27 -> 1.28 # net/ipv6/netfilter/ip6t_length.c 1.2 -> 1.3 # drivers/usb/serial/io_fw_down.h 1.2 -> 1.3 # kernel/kallsyms.c 1.12 -> 1.14 # include/asm-x86_64/processor.h 1.20 -> 1.22 # drivers/ide/pci/pdc202xx_old.c 1.17 -> 1.18 # drivers/usb/class/audio.c 1.40 -> 1.41 # net/wanrouter/af_wanpipe.c 1.28 -> 1.29 # drivers/char/ipmi/ipmi_watchdog.c 1.4 -> 1.5 # drivers/usb/serial/empeg.c 1.40 -> 1.41 # include/asm-arm/hardware/sa1111.h 1.11 -> 1.12 # arch/sh/boards/hp6xx/hp680/mach.c 1.2 -> 1.3 # net/ipv4/igmp.c 1.34 -> 1.35 # drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c 1.3 -> 1.4 # arch/ppc/Kconfig 1.32 -> 1.35 # net/ipv4/ip_output.c 1.41 -> 1.42 # drivers/mtd/nand/edb7312.c 1.1 -> 1.2 # net/ipv4/netfilter/ipt_ECN.c 1.5 -> 1.6 # arch/sparc/kernel/ioport.c 1.12 -> 1.13 # drivers/scsi/amiga7xx.h 1.4 -> 1.5 # arch/sh/Kconfig 1.17 -> 1.18 # include/asm-i386/apic.h 1.13 -> 1.14 # net/ipv4/route.c 1.67 -> 1.69 # sound/oss/cs4281/cs4281m.c 1.25 -> 1.26 # arch/sh/boards/hp6xx/hp690/mach.c 1.2 -> 1.3 # arch/sh/cchips/hd6446x/hd64465/setup.c 1.4 -> 1.5 # drivers/pcmcia/topic.h 1.3 -> 1.4 # drivers/usb/serial/io_fw_boot.h 1.2 -> 1.3 # sound/oss/es1370.c 1.30 -> 1.31 # net/ipv6/netfilter/ip6t_multiport.c 1.3 -> 1.4 # scripts/kconfig/Makefile 1.8 -> 1.9 # drivers/block/scsi_ioctl.c 1.32 -> 1.33 # fs/jffs2/file.c 1.20 -> 1.22 # drivers/acpi/Kconfig 1.19 -> 1.20 # arch/ppc/syslib/of_device.c 1.2 -> 1.4 # net/ipv4/netfilter/ipt_MIRROR.c 1.10 -> (deleted) # net/appletalk/ddp.c 1.26 -> 1.34 # fs/nfsd/nfs4proc.c 1.20 -> 1.21 # arch/arm/kernel/pm.c 1.4 -> 1.5 # arch/ppc64/kernel/ioctl32.c 1.36 -> 1.37 # drivers/usb/core/file.c 1.12 -> 1.14 # net/ipv4/netfilter/ip_nat_irc.c 1.7 -> 1.8 # arch/ppc/platforms/sandpoint.c 1.14 -> 1.15 # drivers/net/arm/ether00.c 1.3 -> 1.4 # arch/i386/kernel/apic.c 1.47 -> 1.48 # drivers/net/3c505.c 1.24 -> 1.25 # net/ipv4/netfilter/ipt_state.c 1.5 -> 1.6 # sound/oss/emu10k1/midi.c 1.11 -> 1.12 # drivers/usb/media/usbvideo.c 1.37 -> 1.39 # drivers/macintosh/adb.c 1.20 -> 1.21 # arch/x86_64/kernel/smpboot.c 1.20 -> 1.21 # include/asm-arm/arch-iop3xx/iop321.h 1.3 -> 1.4 # drivers/char/agp/amd-k7-agp.c 1.34 -> 1.35 # arch/ppc/boot/common/util.S 1.5 -> 1.6 # fs/block_dev.c 1.140 -> 1.142 # drivers/net/sis190.c 1.5 -> 1.12 # drivers/char/ip2main.c 1.40 -> 1.41 # drivers/s390/net/qeth.c 1.2 -> 1.3 # Documentation/kernel-parameters.txt 1.27 -> 1.28 # drivers/video/stifb.c 1.17 -> 1.18 # include/asm-arm/arch-ebsa285/time.h 1.7 -> 1.8 # net/ipv6/netfilter/ip6t_mark.c 1.4 -> 1.5 # net/atm/common.c 1.40 -> 1.42 # include/linux/videodev.h 1.19 -> 1.20 # net/sctp/socket.c 1.89 -> 1.90 # net/ipv4/netfilter/ipt_mark.c 1.4 -> 1.5 # (new) -> 1.2 net/ipv4/netfilter/ipt_CLASSIFY.c # (new) -> 1.1 net/bridge/netfilter/ebt_arpreply.c # (new) -> 1.1 drivers/serial/pmac_zilog.c # (new) -> 1.1 include/asm-m68k/sections.h # (new) -> 1.1 include/asm-m68k/local.h # (new) -> 1.2 arch/i386/kernel/time_hpet.c # (new) -> 1.1 drivers/char/watchdog/alim1535_wdt.c # (new) -> 1.1 include/linux/netfilter_ipv4/ipt_CLASSIFY.h # (new) -> 1.1 arch/ppc/boot/of1275/map.c # (new) -> 1.1 include/asm-m68knommu/local.h # (new) -> 1.1 net/ipv4/netfilter/ipt_NETMAP.c # (new) -> 1.1 net/ipv4/netfilter/ipt_iprange.c # (new) -> 1.1 drivers/serial/pmac_zilog.h # (new) -> 1.2 include/asm-i386/hpet.h # (new) -> 1.1 net/bridge/netfilter/ebt_802_3.c # (new) -> 1.1 include/linux/netfilter_bridge/ebt_arpreply.h # (new) -> 1.1 include/asm-m68knommu/sections.h # (new) -> 1.1 net/ipv4/netfilter/ipt_SAME.c # (new) -> 1.1 arch/i386/kernel/timers/timer_hpet.c # (new) -> 1.1 include/linux/netfilter_ipv4/ipt_SAME.h # (new) -> 1.1 Documentation/sysctl/abi.txt # (new) -> 1.1 include/linux/netfilter_bridge/ebt_802_3.h # (new) -> 1.1 include/asm-arm/apm.h # (new) -> 1.1 include/linux/netfilter_ipv4/ipt_iprange.h # (new) -> 1.1 include/asm-h8300/h8300_smsc.h # # The following is the BitKeeper ChangeSet Log # -------------------------------------------- # 03/08/22 torvalds@home.osdl.org 1.1276.23.1 # Linux 2.6.0-test4 # -------------------------------------------- # 03/08/22 davem@nuts.ninka.net 1.1276.2.49 # [TG3]: More missing PCI IDs. # -------------------------------------------- # 03/08/22 rwhron@earthlink.net 1.1276.22.33 # [PATCH] USB: version.h cleanup 1 of 4 # -------------------------------------------- # 03/08/22 rwhron@earthlink.net 1.1276.22.34 # [PATCH] USB: version.h cleanup 2 of 4 # # I used a combination of: # egrep -l 'UTS_RELEASE|LINUX_VERSION_CODE|\' # and "grep -l linux/version.h" to find them. They compiled # as module/non-module for me. The previous patch adds # version.h, btw. # -------------------------------------------- # 03/08/22 rwhron@earthlink.net 1.1276.22.35 # [PATCH] USB: version.h cleanup 3 of 4 # -------------------------------------------- # 03/08/22 rwhron@earthlink.net 1.1276.22.36 # [PATCH] USB: version.h cleanup 4 of 4 # -------------------------------------------- # 03/08/22 quade@hsnr.de 1.1276.22.37 # [PATCH] USB: writing usb driver documentation update # # I noticed, that your documentation of your usb-skeleton driver # is not up to date. So I took the time to rework it slightly. # I append the patch to the version I found in kernel 2.6.0-test3. # -------------------------------------------- # 03/08/22 cat@zip.com.au 1.1276.22.38 # [PATCH] USB: C99: 2.6.0-t3-bk7/Documentation # -------------------------------------------- # 03/08/23 paulus@samba.org 1.1276.1.9 # Merge samba.org:/home/paulus/kernel/linux-2.5 # into samba.org:/home/paulus/kernel/for-linus-ppc # -------------------------------------------- # 03/08/22 andersen@codepoet.org 1.1276.23.2 # [PATCH] Fix cdrom error handling in 2.6 # # In both 2.4 and in 2.6, error handling for bad cdrom media is # wrong. And it is my fault I'm afraid, since I botched an earlier # fix for the problem by putting the fix in the wrong spot. # # My kids have a "Jumpstart Toddlers" cd they have long since # completely killed, which makes a great test disc. Without this # fix, the best time projection I can get for completing a dd type # sector copy is about 2 years... Most of that is spent thrashing # about in kernel space trying to re-read sectors we already know # are not correctable.... After the fix, I was able to rip a copy # the CD (or rather muddle through it getting lots of EIO errors) # in about 15 minutes. # # Attached is the fix for 2.6.x, # -------------------------------------------- # 03/08/23 paulus@samba.org 1.1276.1.10 # PPC32: Add the fadvise64_64 system call. # # On PPC32 we reorder the arguments so they fit into 6 registers. Glibc will # need a two-line stub to change them from the standard order to the ordering # used by the system call: (fd, advice, offset, len). # -------------------------------------------- # 03/08/23 paulus@samba.org 1.1276.1.11 # PPC32: Declare cpu_online_map and cpu_possible_map as cpumask_t. # -------------------------------------------- # 03/08/23 paulus@samba.org 1.1276.1.12 # Merge samba.org:/home/paulus/kernel/linux-2.5 # into samba.org:/home/paulus/kernel/for-linus-ppc # -------------------------------------------- # 03/08/23 paulus@samba.org 1.1276.1.13 # PPC32: Update some of the example configs # -------------------------------------------- # 03/08/23 torvalds@home.osdl.org 1.1276.1.14 # Input: typo in device matching. # # Too much cut-and-paste, noticed by Dmitry Torokhov # -------------------------------------------- # 03/08/23 vinay-rc@naturesoft.net 1.1276.1.15 # [PATCH] vx_entry.c: remove release timer # # sound/pcmcia/vx/vx_entry.c: # # This patch removes the PCMCIA timer release functionality which is no # longer required. Without this the module does not compile. # -------------------------------------------- # 03/08/23 greg@kroah.com 1.1276.1.16 # Merge kroah.com:/home/greg/linux/BK/bleed-2.5 # into kroah.com:/home/greg/linux/BK/gregkh-2.6 # -------------------------------------------- # 03/08/23 zecke@org.rmk.(none) 1.1241.2.2 # [ARM PATCH] 1595/1: [PATCH] 1/10 Simpad changes # # Patch from Holger Freyther # # see content # -------------------------------------------- # 03/08/23 zecke@org.rmk.(none) 1.1241.2.3 # [ARM PATCH] 1598/1: [PATCH] 4/10 Simpad changes # # Patch from Holger Freyther # # -------------------------------------------- # 03/08/23 zecke@org.rmk.(none) 1.1241.2.4 # [ARM PATCH] 1603/1: [PATCH] 9/10 Simpad changes # # Patch from Holger Freyther # # -------------------------------------------- # 03/08/24 dsaxena@com.rmk.(none) 1.1241.2.5 # [ARM PATCH] 1611/1: Add big-endian support to AFLAGS # # Patch from Deepak Saxena # # This is required for usr/initramfs_data.o to build properly when # CONFIG_CPU_BIG_ENDIAN is enabled. # -------------------------------------------- # 03/08/24 dsaxena@com.rmk.(none) 1.1241.2.6 # [ARM PATCH] 1615/1: Fix IOP3xx timer interrupts # # Patch from Deepak Saxena # # Fix IOP321 and IQ80310 timer interrupts to return IRQ_HANDLED # -------------------------------------------- # 03/08/24 rmk@flint.arm.linux.org.uk 1.1241.2.7 # [ARM] Noddy indentation fix for arch/arm/boot/Makefile. # -------------------------------------------- # 03/08/24 dsaxena@com.rmk.(none) 1.1241.2.8 # [ARM PATCH] 1613/1: arch/arm/boot/Makefile fixups for IOP3xx and ADIFCC # # Patch from Deepak Saxena # # Small cleanups for ADIFCC and IOP3XX machine types to support # ATAG parameters. Working with Intel and ADI to get updated # bootloaders that pass the tags. # # Also, all known IOP3xx boards have memory starting at 0xa0000000, # so we can remove the redundant ARCH_IQ* zreladdr values. # -------------------------------------------- # 03/08/24 dsaxena@com.rmk.(none) 1.1241.2.9 # [ARM PATCH] 1616/1: Add PFN_TO_NID to IOP3xx # # Patch from Deepak Saxena # # -------------------------------------------- # 03/08/24 dsaxena@com.rmk.(none) 1.1241.2.10 # [ARM PATCH] 1621/1: IOP3xx CPU detection (cleaned up) # # Patch from Deepak Saxena # # Removes extraneous bits that belong to separate IOP3xx PCI cleanup patch # Supersedes 1618/1 # -------------------------------------------- # 03/08/24 dsaxena@com.rmk.(none) 1.1241.2.11 # [ARM PATCH] 1623/1: Updated def-configs for IQ80310/321 # # Patch from Deepak Saxena # # -------------------------------------------- # 03/08/24 dsaxena@com.rmk.(none) 1.1241.2.12 # [ARM PATCH] 1620/1: dma_map_single/unmap_single support for ARM # # Patch from Deepak Saxena # # -------------------------------------------- # 03/08/24 dsaxena@com.rmk.(none) 1.1241.2.13 # [ARM PATCH] 1559/1: updated include/asm-arm/checksum.h big-endian support # # Patch from Deepak Saxena # # This is an update to patch 1529/1 that cleans up the code so we don't need # #ifdef's for little vs. big-endian systems. Tested on both systems with # various network apps (ping, ftp, tftp, ssh, telnet, NFS root, http) with no # issues. # -------------------------------------------- # 03/08/24 fbecker@com.rmk.(none) 1.1241.2.14 # [ARM PATCH] 1563/1: Update pxa-regs.h with correct gpio number for 48 MHz clock output # # Patch from Frank Becker # # GPIO for 48 MHz clock output is 7 not 8. # -------------------------------------------- # 03/08/24 nico@org.rmk.(none) 1.1241.2.15 # [ARM PATCH] 1565/1: syscall macros clobbering returned error value # # Patch from Nicolas Pitre # # In both 2.5.70-rmk1 and 2.4.19-rmk7 the syscall macros are clobering # the returned error value when building library code. # # Example code: # # #include # #include # extern int fake_syscall(int x, int y, int z); # _syscall3(int, fake_syscall, int, x, int, y, int, z) # # Current generated code: # # fake_syscall: # @ args = 0, pretend = 0, frame = 0 # @ frame_needed = 0, uses_anonymous_args = 0 # str lr, [sp, #-4]! # swi __NR_fake_syscall # cmn r0, #126 # ldrls pc, [sp], #4 # bl __errno_location # rsb r3, r0, #0 # str r3, [r0, #0] # mvn r0, #0 # ldr pc, [sp], #4 # # In the code above, whenever the return value is an error code, it # is lost due to the call to __errno_location. And because of the # asm("r0") constraint on the variable __res the compiler continues # using r0 for it even if it's now a pointer value. errno ends up with # a totally bogus value. # # With the patch below the above code becomes: # # fake_syscall: # @ args = 0, pretend = 0, frame = 0 # @ frame_needed = 0, uses_anonymous_args = 0 # stmfd sp!, {r4, lr} # swi __NR_fake_syscall # cmn r0, #126 # mov r4, r0 # bls .L3 # bl __errno_location # rsb r3, r4, #0 # str r3, [r0, #0] # mvn r4, #0 # .L3: # mov r0, r4 # ldmfd sp!, {r4, pc} # # which is correct. # # Oh and added a small estetic change for generated code too. # -------------------------------------------- # 03/08/23 davem@nuts.ninka.net 1.1276.2.50 # [TG3]: Reset PHY more reliably on 570{3,4,5} chips. # -------------------------------------------- # 03/08/23 davem@nuts.ninka.net 1.1276.2.51 # [TG3]: Fix 5788/5901, update TSO code. # - Do not set RDMAC_MODE_FIFO_LONG_BURST on 5788 # - Do not set WDMAC_MODE_RX_ACCEL on 5788 # - Note that 5788 cannot use tagged irq status. # - 5788 cannot do TSO # - 5788 cannot do NETIF_F_HIGHDMA. # - 5901 is 10/100 only. # - Update TSO firmware, add 5705 specific TSO firmware. # - Update TSO packet handling in ->hard_start_xmit() to # match updated TSO firmware. # - TSO is still off by default until more perf analysis is done. # -------------------------------------------- # 03/08/23 davem@nuts.ninka.net 1.1276.2.52 # [TG3]: Differentiate between TSO capable and TSO enabled. # -------------------------------------------- # 03/08/23 davem@nuts.ninka.net 1.1276.2.53 # [ETHTOOL]: Add {G,S}TSO support to ethtool_ops. # -------------------------------------------- # 03/08/23 davem@nuts.ninka.net 1.1276.2.54 # [TG3]: Add {get,set}_tso ethtool_ops support. # # Also, include TSO support code when NETIF_F_TSO is available # but do not enable TSO by default even on capable cards. User # can turn it on via ethtool. # -------------------------------------------- # 03/08/23 davem@nuts.ninka.net 1.1276.2.55 # [TG3]: Bump version/reldate. # -------------------------------------------- # 03/08/23 davem@nuts.ninka.net 1.1276.2.56 # [TG3]: Fix tg3_phy_reset_5703_4_5 chip rev test. # -------------------------------------------- # 03/08/23 davem@nuts.ninka.net 1.1276.2.57 # [TG3]: Bump version/reldate. # -------------------------------------------- # 03/08/24 benh@kernel.crashing.org 1.1276.24.1 # Merge bk://ppc@ppc.bkbits.net/for-linus-ppc # into kernel.crashing.org:/home/benh/kernels/for-linus-ppc # -------------------------------------------- # 03/08/24 davem@nuts.ninka.net 1.1276.2.58 # [ETHTOOL]: Add ethtool_op_{set,get}_tso helpers. # -------------------------------------------- # 03/08/24 davem@nuts.ninka.net 1.1276.2.59 # [TG3]: More fixes and enhancements. # - Use ethtool_op_{get,set}_tso(). # - Avoid partial byte enables on DMA writes, this upsets several # non-x86 PCI controllers. # -------------------------------------------- # 03/08/24 benh@kernel.crashing.org 1.1276.24.2 # cputable.c: # Fix CPU table, 750FX rev 1.x must not tab high BATs # -------------------------------------------- # 03/08/24 davem@nuts.ninka.net 1.1276.25.1 # [SPARC64]: Add some missing PCI error reporting. # -------------------------------------------- # 03/08/24 benh@kernel.crashing.org 1.1276.24.3 # Add new OF tree walking APIs # -------------------------------------------- # 03/08/24 benh@kernel.crashing.org 1.1276.24.4 # Update OF platform & macio driver cores to adapt to device # model changes. Fix refcounting # -------------------------------------------- # 03/08/24 benh@kernel.crashing.org 1.1276.24.5 # Update openpic to expose a sys_dev for power management, make # it more robust vs. concurrent calls by the PM system and cpufreq # -------------------------------------------- # 03/08/24 benh@kernel.crashing.org 1.1276.24.6 # Update pmac PIC driver to register a sysdev for Power Management # -------------------------------------------- # 03/08/24 benh@kernel.crashing.org 1.1276.24.7 # Major update via-pmu driver, hopefully last before we split it & do major cleanup. # - Adapt to new power management # - Make PM and cpufreq more robust by preventing ADB requests # from getting in after the actual freq change / sleep one # - Close a few races # - Expose some IRQ stats & fix a problem where core99 machines # were getting tons of spurrious ADB events # -------------------------------------------- # 03/08/24 shemminger@osdl.org 1.1276.26.1 # [IPV4]: Route cache /proc interface cleanup. # * use proc_net_fops_create to setup # * collapse two_line setup functions into the init routine # * proc_exit routine was never called and can go. # * cleaner to refer to proc_net as base rather than net/rt_acct # -------------------------------------------- # 03/08/24 rusty@rustcorp.com.au 1.1276.26.2 # [NETFILTER]: Trivial 2.6 tftp conntrack fix. # In 2.6, the TFTP conntrack helper returns -1 if the packet is too # short, but that is an invalid return code. Return NF_ACCEPT # instead. # -------------------------------------------- # 03/08/24 rmk@flint.arm.linux.org.uk 1.1241.2.16 # [ARM] Fix vmlinux linker script # # Since we're now 32-bit "armv" only, we don't need to select the # linker script in vmlinux.lds.S. Also, whoever moved vmlinux.lds.S # into arch/arm/kernel forgot to move the other scripts. # # This cset replaces arch/arm/kernel/vmlinux.lds.S with # arch/arm/vmlinux-armv.lds.in, and deletes the obsolete scripts. # -------------------------------------------- # 03/08/24 bdschuym@pandora.be 1.1276.26.3 # [BRIDGE]: Add arpreply EBTABLES target. # -------------------------------------------- # 03/08/24 shemminger@osdl.org 1.1276.26.4 # [AX25]: Make sure and hold ref to dev. # # The lower layers of ax25 hold a reference to the underlying device # but don't increment the ref count. This is safe because it does the # right thing when UNREGISTER notification comes in, but it is better # to do the right thing. # -------------------------------------------- # 03/08/24 shemminger@osdl.org 1.1276.26.5 # [AX25]: Convert to seq_file. # -------------------------------------------- # 03/08/24 bdschuym@pandora.be 1.1276.26.6 # [BRIDGING]: Update Kconfig files for bridging firewall. # -------------------------------------------- # 03/08/24 rmk@flint.arm.linux.org.uk 1.1241.2.17 # [ARM] Remove reference to struct device name element. # -------------------------------------------- # 03/08/24 lists@mdiehl.de 1.1276.26.7 # [IRDA]: vlsi_ir v0.5 update, 1/7. # # * Kconfig: we depend on CONFIG_PCI # * update header compatibility stuff # * beautify C99-initializers for PCI IDs # * PCIDEV_NAME wrapper to abstract device name storage location # * cleanup of the pci shutdown path. Also fixing a possible NULL-pointer # dereference when the driver is rmmod with the netdev still running. # -------------------------------------------- # 03/08/24 lists@mdiehl.de 1.1276.26.8 # [IRDA]: vlsi_ir v0.5 update, 2/7. # # * don't fail without procfs - it's only needed for diagnostics # * get rid of printk in favour of IRDA_DEBUG and friends wherever possible # * reduce kernellog noise depending on irda debuglevel # -------------------------------------------- # 03/08/24 lists@mdiehl.de 1.1276.26.9 # [IRDA]: vlsi_ir v0.5 update, 3/7. # # * fix error path for ring entry alloc in case pci_map failed # * get rid of BUG() - it's mostly in interrupt and there's no need # to kill the box on such issues # * correct endianess for the hardware view of ring descriptors # -------------------------------------------- # 03/08/24 lists@mdiehl.de 1.1276.26.10 # [IRDA]: vlsi_ir v0.5 update, 4/7. # # * interrupt handler cleanup, focus on fast path and low latency # * rx-path cleanup # * add missing crc16 check of incoming SIR frames # -------------------------------------------- # 03/08/24 lists@mdiehl.de 1.1276.26.11 # [IRDA]: vlsi_ir v0.5 update, 5/7. # # * cleanup baud rate setting and mode switch # * locking and barrier review # -------------------------------------------- # 03/08/24 lists@mdiehl.de 1.1276.26.12 # [IRDA]: vlsi_ir v0.5 update, 6/7. # # * tx-path cleanup # * fix deadlock when setting speed in tx_interrupt, issue was introduced by # previous interrupt locking cleanup # * don't let start_xmit return NET_XMIT_DROP if we drop and free the skb. # This fixes an old bug in the error path leading to skb_slab corruption # -------------------------------------------- # 03/08/24 lists@mdiehl.de 1.1276.26.13 # [IRDA]: vlsi_ir v0.5 update, 7/7. # # * correct mtt bits to indicate 1msec or more # * rename IRENABLE_IREN to IRENABLE_PHYANDCLOCK # * rearrange driver metadata and header # * driver version 0.5 # -------------------------------------------- # 03/08/24 vinay-rc@naturesoft.net 1.1276.26.14 # [NET]: Fix 'spin_lock_irqrestore' typos in sk_mca.c # -------------------------------------------- # 03/08/24 laforge@netfilter.org 1.1276.26.15 # [NETFILTER]: Fix ipt_REJECT if used on bridge. # -------------------------------------------- # 03/08/24 laforge@netfilter.org 1.1276.26.16 # [NETFILTER]: Remove ipt_MIRROR target from 2.6.x # # We have decided to remove the MIRROR target, since it was considered a # stupid and potentially dangeroups example code of the early netfilter # days that should never be used on the internet anyway. # -------------------------------------------- # 03/08/24 skewer@terra.com.br 1.1276.26.17 # [NET]: Remove dead comment from dummy.c driver. # -------------------------------------------- # 03/08/24 laforge@netfilter.org 1.1276.26.18 # [NETFILTER]: Remove ipt_unclean match from 2.6.x # # We have decided to remove the unclean match, since it is considered # a potentially dangerous function of the current iptables code. # # The match is used by lots of users who don't really undestand what kind # of danger they are imposing on the future-compatibility of their # networks. (just think of the ECN issue resulting from this kind of # filtering) # # We'd rather keep it in patch-o-matic, where lots of other modules that # are only useful in experimental scenarios are kept. # # Now that we don't have to keep it for compatibility reasons, we'd like # to remove it before 2.6.0 final is released. # -------------------------------------------- # 03/08/24 laforge@netfilter.org 1.1276.26.19 # [NETFILTER]: Remove EXPERIMENTAL mark from some netfilter stuff. # -------------------------------------------- # 03/08/24 laforge@netfilter.org 1.1276.26.20 # [NETFILTER]: Cosmetic netfilter patch. # # - moves all MODULE_{AUTHOR,DESCRIPTION,LICENSE} statements to the same # location # - adds some missing MODULE_LICENSE(GPL) tags # - adds MODULE_DESCRIPTION and AUTHOR to all modules # -------------------------------------------- # 03/08/24 laforge@netfilter.org 1.1276.26.21 # [NETFILTER]: NAT optimization. # # The following patch against 2.6.0-test4 (courtesy of Patrick McHardy) # optimizes the NAT code. In the old implementation, the hash function # was passed to the LIST_DELETE macro, which resulted in it being called # two times instead of one. # -------------------------------------------- # 03/08/24 laforge@netfilter.org 1.1276.26.22 # [NETFILTER]: Conntrack optimization (LIST_DELETE). # # The following patch against 2.6.0-test4 (courtesy of Patrick McHardy) # optimizes the conntrack code. In the old implementation, the hash function # was passed to the LIST_DELETE macro, which resulted in it being called # two times instead of one. # -------------------------------------------- # 03/08/24 vinay-rc@naturesoft.net 1.1276.26.23 # [NET]: Fix MCA device name handling in 3c509.c # -------------------------------------------- # 03/08/24 drepper@redhat.com 1.1276.26.24 # [NET]: Check tgid not pid in scm_check_creds(). # -------------------------------------------- # 03/08/24 rmk@flint.arm.linux.org.uk 1.1241.2.18 # [ARM] Fix device suspend/resume calls. # # These calls no longer take "level" arguments, so there's no need to # call them multiple times. # -------------------------------------------- # 03/08/24 rmk@flint.arm.linux.org.uk 1.1241.2.19 # [ARM] Fix ecard.c manufacturer and product files. # -------------------------------------------- # 03/08/24 davem@nuts.ninka.net 1.1276.25.2 # [SPARC]: Update ethtool support in Sun net drivers. # -------------------------------------------- # 03/08/24 benh@kernel.crashing.org 1.1276.24.8 # Update PowerMac IDE driver. Adapt to new driver model, add proper # support for Kauai ATA/100 and add activity led code. # NOTE: The activity LED code has been left out of Kconfig until the # proper support for it in the blk & ide layers have been merged # (pending patch from Jens Axboe) # -------------------------------------------- # 03/08/24 rmk@flint.arm.linux.org.uk 1.1241.2.20 # [ARM] Tweak the bridge control register for PCI and cardbus bridges. # # This ensures that we release reset on devices behind a PCI bridge, # and that we have error reporting enabled behind bridges. # -------------------------------------------- # 03/08/24 benh@kernel.crashing.org 1.1276.24.9 # Adapt PowerMac i2c-keywest driver to new driver model # -------------------------------------------- # 03/08/24 benh@kernel.crashing.org 1.1276.24.10 # Fix PowerMac ALSA build with device model "name" field change # -------------------------------------------- # 03/08/24 benh@kernel.crashing.org 1.1276.24.11 # Update PowerMac mediabay driver to new model, fix an old bug # that could prevent one of the timeouts from working, fix access # to MMIO based interface # -------------------------------------------- # 03/08/24 rmk@flint.arm.linux.org.uk 1.1241.2.21 # [ARM] Remove pci_dev->dev.name in favour of pci_name() # -------------------------------------------- # 03/08/24 benh@kernel.crashing.org 1.1276.24.12 # Adapt PowerMac "airport" driver to new driver model # -------------------------------------------- # 03/08/24 benh@kernel.crashing.org 1.1276.24.13 # Fix build of controlfb driver # -------------------------------------------- # 03/08/24 benh@kernel.crashing.org 1.1276.24.14 # Adapt PowerMac "platinum" video driver to new driver model # -------------------------------------------- # 03/08/24 rmk@flint.arm.linux.org.uk 1.1241.2.22 # [ARM] Remove old binutils compatibility. # # Old binutils (without .incbin) had the idea that a certain assembler # instruction was illegal. binutils has since been fixed to allow it. # -------------------------------------------- # 03/08/24 rmk@flint.arm.linux.org.uk 1.1241.2.23 # [ARM] Update AMBA suspend/resume model. # # The device_driver suspend/resume methods are no longer used. Instead, # the bus_type contains the suspend/resume methods. Fix the AMBA bus # support for this change. # -------------------------------------------- # 03/08/24 benh@kernel.crashing.org 1.1276.24.15 # fixup xmon ADB polling so that it works before ADB core is loaded # -------------------------------------------- # 03/08/24 rmk@flint.arm.linux.org.uk 1.1241.2.24 # [ARM] Update SA1111 suspend/resume model. # # The device_driver suspend/resume methods are no longer used. Instead, # the bus_type contains the suspend/resume methods. Fix the SA1111 bus # support for this change. # # We place the probe/remove/suspend/resume methods inside struct # sa1111_driver and call them from the SA1111 bus driver (ie, how # Pat wants this stuff done.) # # We leave the parent bus device suspend/resume methods in the device # driver until power management for platform devices works again. # However, we adjust these methods so they run only once, like the # other PM methods. # -------------------------------------------- # 03/08/24 benh@kernel.crashing.org 1.1276.24.16 # Add back missing fb_set_var to PowerMac platinum driver # -------------------------------------------- # 03/08/24 rmk@flint.arm.linux.org.uk 1.1241.2.25 # [ARM] Fix EBSA285 CLOCK_TICK_RATE. # # The timex/time code requires CLOCK_TICK_RATE to be constant. We # assume that the platform picks an appropriate clock source such # that we generate an exact HZ value, and set CLOCK_TICK_RATE to # a value where ACTHZ == HZ. # -------------------------------------------- # 03/08/24 benh@kernel.crashing.org 1.1276.24.17 # Update PowerMac cpufreq driver to adapt it to some core # changes and fix a race with the PMU driver # -------------------------------------------- # 03/08/24 benh@kernel.crashing.org 1.1276.24.18 # For keeping interface ordering consistent between previous kernels and # the new driver model probing mecanism, drivers/macintosh has to be # linked before ide and scsi # -------------------------------------------- # 03/08/24 benh@kernel.crashing.org 1.1276.24.19 # Don't care about driver registration results for i2c-keywest # so failing one don't break the other # -------------------------------------------- # 03/08/24 benh@kernel.crashing.org 1.1276.24.20 # Fix drivers/video Makefile so control & platinum drivers gets # proper depedencies on the cfb* files # -------------------------------------------- # 03/08/24 benh@kernel.crashing.org 1.1276.24.21 # Add new pmac_zilog serial driver, obsolete old macserial. # # The new driver is a complete rewrite based on David Miller sunzilog # adapted to PowerMac, it uses the new driver model & the serial driver # core unlike the old macserial. It doesn't support DMA yet but this is # a "feature" for now as the DMA implementation of macserial used to # exhibit memory corruption problems. # -------------------------------------------- # 03/08/24 rmk@flint.arm.linux.org.uk 1.1276.27.1 # Merge http://linux.bkbits.net/linux-2.5 # into flint.arm.linux.org.uk:/usr/src/linux-bk-2.5/linux-2.5-rmk # -------------------------------------------- # 03/08/25 rmk@flint.arm.linux.org.uk 1.1276.28.1 # [PCMCIA] Use #define'd constants in ZV code where possible. # -------------------------------------------- # 03/08/25 rmk@flint.arm.linux.org.uk 1.1276.28.2 # [PCMCIA] Clean up yenta overrides # # Move the quirk selection to the main PCI ID table, and list the quirks # by type. Introduce "cardbus_type" structure to contain the quirk # information. # -------------------------------------------- # 03/08/25 paulus@samba.org 1.1276.29.1 # Merge bk://ppc@ppc.bkbits.net/for-linus-ppc # into samba.org:/home/paulus/kernel/for-linus-ppc # -------------------------------------------- # 03/08/25 rmk@flint.arm.linux.org.uk 1.1276.28.3 # [PCMCIA] Move socket initialisation to the quirk table. # # This removes the horrible side effect where we modify the generic # yenta_socket_operations structure (which of course other sockets # may be using.) # # We move the socket init quirks into our cardbus_type quirk # structure, and call it during the generic socket initialisation. # -------------------------------------------- # 03/08/24 laforge@netfilter.org 1.1276.26.25 # [NETFILTER]: New iptables modules (iprange, CLASSIFY, SAME, NETMAP). # # The following patch against 2.6.0-test4 adds four more iptables modules. # They are adding the following functionality # - iprange: matching against an arbitrary contiguous range of ip addresses # - CLASSIFY: setting skb->priority from iptables (so you can skip tc filter) # - NETMAP: SNAT a whole network 1:1 to another network # - SAME: tries to keep the assigned ip per client the same within an SNAT # pool # -------------------------------------------- # 03/08/24 davem@nuts.ninka.net 1.1276.26.26 # [NETFILTER]: Use correct printf format for size_t in ipt_CLASSIFY.c # -------------------------------------------- # 03/08/25 benh@kernel.crashing.org 1.1276.24.22 # Update "coff" zImage wrapper so it works with larger kernel images # -------------------------------------------- # 03/08/25 benh@kernel.crashing.org 1.1276.29.2 # Merge bk://ppc@ppc.bkbits.net/for-linus-ppc # into kernel.crashing.org:/home/benh/kernels/for-linus-ppc # -------------------------------------------- # 03/08/25 greg@kroah.com 1.1276.30.1 # Merge kroah.com:/home/greg/linux/BK/bleed-2.5 # into kroah.com:/home/greg/linux/BK/gregkh-2.6 # -------------------------------------------- # 03/08/25 benh@kernel.crashing.org 1.1276.29.3 # Fix missing bit in the new .coff wrapper # -------------------------------------------- # 03/08/25 benh@kernel.crashing.org 1.1276.29.4 # some whitespace & tab fixes # -------------------------------------------- # 03/08/25 davidm@tiger.hpl.hp.com 1.1276.31.1 # Merge tiger.hpl.hp.com:/data1/bk/vanilla/linux-2.5 # into tiger.hpl.hp.com:/data1/bk/lia64/to-linus-2.5 # -------------------------------------------- # 03/08/25 benh@kernel.crashing.org 1.1276.29.5 # Fix a bug where an ide-pmac hwif returned to the system because it's empty # would still be probed thus causing a crash on some machines. Also fix some # whitespace/tabs. # -------------------------------------------- # 03/08/25 benh@kernel.crashing.org 1.1276.29.6 # Add & export some routines to access the i2c busses that hang off the PMU, not # yet linked to the linux i2c subsystem though. Fix some whitespace/tabs too. # -------------------------------------------- # 03/08/25 trini@kernel.crashing.org 1.1276.32.1 # PPC32: Change the default behavior of a kernel with KGDB. # We now don't default to an initial breakpoint, as this is how # KGDB on i386 works. # -------------------------------------------- # 03/08/25 trini@kernel.crashing.org 1.1276.32.2 # PPC32: Fix KGDB and userland GDB interactions. # -------------------------------------------- # 03/08/25 rddunlap@osdl.org 1.1276.31.2 # [PATCH] ia64: fix printk type warning # # -------------------------------------------- # 03/08/25 willy@debian.org 1.1276.31.3 # [PATCH] ia64: default to building compressed # # i386 defaults to building bzImage (as well as modules) if you just type # make. This patch mirrors that on ia64 by building compressed. # -------------------------------------------- # 03/08/25 mort@wildopensource.com 1.1276.31.4 # [PATCH] ia64: paddr_to_nid fixup # # Here is a small patch for paddr_to_nid(). This fix is already in 2.4 # and is used in the case where a NUMA kernel is running on a machine # without a SRAT ACPI table. Without this patch the node info is not # correctly located. # -------------------------------------------- # 03/08/25 alex.williamson@hp.com 1.1276.31.5 # [PATCH] ia64: no discontig w/o NUMA # # Currently the generic kernel won't build if you turn off NUMA # support. Seems discontig support is too entangled with NUMA # support to live without it. This patch makes it behave a bit # more friendly. # -------------------------------------------- # 03/08/25 davidm@tiger.hpl.hp.com 1.1276.31.6 # ia64: Manual merge with Alex's "UP cmc/cpe polling fix" patch. # -------------------------------------------- # 03/08/25 willy@debian.org 1.1276.31.7 # [PATCH] ia64: ia64/lib/Makefile: use call-if-changed # # - IGNORE_FLAGS_OBJS is no longer honoured (this is the only reference to # it in the tree). # - Change the .o.S rule to look the same as the one in # scripts/Makefile.build. This means we'll generate .cmd files instead # of the .d files which makes CVS happier. # -------------------------------------------- # 03/08/25 davidm@tiger.hpl.hp.com 1.1276.31.8 # ia64: Use offset_in_page() instead of equivalent open code. # -------------------------------------------- # 03/08/25 davidm@tiger.hpl.hp.com 1.1276.31.9 # ia64: Hook up fadvise64_64() system call. # -------------------------------------------- # 03/08/25 davem@nuts.ninka.net 1.1276.26.27 # [NET]: net/core/ethtool.c needs asm/uaccess.h # -------------------------------------------- # 03/08/25 davem@nuts.ninka.net 1.1276.2.60 # [TG3]: Fix ethtool_ops/sun_5704 changes collision. # # tg3_init_rings() happens in tg3_init_hw(), so zap every other # occurance. # -------------------------------------------- # 03/08/25 davem@nuts.ninka.net 1.1276.2.61 # [TG3]: Protect get/set TSO support with proper ifdefs. # -------------------------------------------- # 03/08/26 benh@kernel.crashing.org 1.1276.29.7 # C99 initializer fixes # -------------------------------------------- # 03/08/26 benh@kernel.crashing.org 1.1276.29.8 # Remove useless junk at beginning of MachineCheck exception handler, # this actually is causing problems on some CPUs # -------------------------------------------- # 03/08/26 bunk@fs.tum.de 1.1276.33.1 # [netdrvr sis190] fix build with older gcc # # older gcc's do not support C99/C++ style of variable declarations. # -------------------------------------------- # 03/08/26 romieu@fr.zoreil.com 1.1276.33.2 # [netdrvr sis190] pass irq argument to synchronize_irq() # # Looks like this driver wasn't tested on SMP :) # -------------------------------------------- # 03/08/26 willy@debian.org 1.1276.33.3 # [netdrvr 3c59x] ethtool_ops support # -------------------------------------------- # 03/08/26 jgarzik@redhat.com 1.1276.33.4 # [netdrvr sis900] ethtool_ops support # -------------------------------------------- # 03/08/26 jgarzik@redhat.com 1.1276.33.5 # [netdrvr 8139cp] ethtool_ops support # -------------------------------------------- # 03/08/26 jgarzik@redhat.com 1.1276.33.6 # [netdrvr sis190] convert TX path to use PCI DMA API # # Also, minor changes: # * mark ->hard_start_xmit ETH_ZLEN test as unlikely() # * use cpu_to_le32() and le32_to_cpu() in TX path # * fix two leak in error path, in ->hard_start_xmit # * don't test netif_queue_stopped() in TX completion path, # netif_wake_queue() already does that. # -------------------------------------------- # 03/08/26 jgarzik@redhat.com 1.1276.33.7 # [netdrvr sis190] make driver depend on CONFIG_BROKEN # # Until RX path is cleaned up to use PCI DMA API and # not virt_to_bus. # -------------------------------------------- # 03/08/26 jgarzik@redhat.com 1.1276.33.8 # [netdrvr 3c501] ethtool_ops support # -------------------------------------------- # 03/08/26 jgarzik@redhat.com 1.1276.33.9 # [netdrvr] ethtool_ops support in 3c503, 3c505, 3c507 # -------------------------------------------- # 03/08/26 jgarzik@redhat.com 1.1276.33.10 # [netdrvr] ethtool_ops support for 3c515, 3c523, 3c527, and dmfe # -------------------------------------------- # 03/08/26 jgarzik@redhat.com 1.1276.33.11 # [netdrvr pcmcia] ethtool_ops for 3c574, 3c589, axnet # -------------------------------------------- # 03/08/26 jgarzik@redhat.com 1.1276.33.12 # [netdrvr pcmcia] convert several drivers to ethtool_ops # # Drivers updated: fmvj18x_cs, ibmtr_cs, nmclan_cs, pcnet_cs, # xirc2ps_cs. # -------------------------------------------- # 03/08/26 davidm@tiger.hpl.hp.com 1.1276.31.10 # ia64: The second chunk of the "UP cmc/cpe polling fix" seems to have # gotten lost. Please apply the attached for the cpe side of the # fix. # -------------------------------------------- # 03/08/26 jgarzik@redhat.com 1.1276.33.13 # [netdrvr xircom_cb] ethtool_ops support # # Also, export PCI bus id via ETHTOOL_GDRVINFO. # -------------------------------------------- # 03/08/26 jgarzik@redhat.com 1.1276.33.14 # [wireless ray_cs] ethtool_ops support # -------------------------------------------- # 03/08/26 davidm@tiger.hpl.hp.com 1.1276.31.11 # ia64: Fix usage ("corrected" machine checks and platform errors, # not "correctable"). # -------------------------------------------- # 03/08/26 romieu@fr.zoreil.com 1.1276.33.15 # [netdrvr sis190] remove unneeded alignment code, other small fixes # # Driver does not need to enforce 256 byte alignment for data returned # from pci_alloc_consistent(). # - {rx/tx}_dma_aligned and {rx/td}_dma_raw are both replaced by {rx/tx}_dma; # - {rx/tx}_desc_raw is replaced by direct use of {Rx/Tx}DescArray; # - SiS190_open() # + fixup for a lack of kmalloc() failure handling; # + (return status) there is no need for both retval/rc: merge them; # + anonymous printk() fixup: the name of the guilty device is printed; # - define {RX/TX}_DESC_TOTAL_SIZE because I am too lazy to read twice the # same lengthy arithmetic expression. # # # -------------------------------------------- # 03/08/26 srompf@isg.de 1.1276.33.16 # [netdrvr 8139too] use mii_check_media lib function, # instead of homebrew MII bitbanging. # -------------------------------------------- # 03/08/26 hirofumi@mail.parknet.co.jp 1.1276.33.17 # [netdrvr 8139too] lwake unlock fix # -------------------------------------------- # 03/08/26 hirofumi@mail.parknet.co.jp 1.1276.33.18 # [netdrvr 8139too] remove unused RxConfigMask # -------------------------------------------- # 03/08/26 hirofumi@mail.parknet.co.jp 1.1276.33.19 # [netdrvr 8139too] add more h/w revision ids # -------------------------------------------- # 03/08/26 greg@kroah.com 1.1276.33.20 # [netdrvr sis900] don't call pci_find_device from irq context # # I realized that I've had this patch in my tree for a while, and forgot # to send it to you and lkml. The patch below fixes bug number 923: # http://bugme.osdl.org/show_bug.cgi?id=923 # (basically keeps us from calling pci_find_device from interrupt # context.) # # It's been tested by a few people with this device, and they say it works # just fine for them. Please forward it on up the food chain. # -------------------------------------------- # 03/08/26 javier@tudela.mad.ttd.net 1.1276.33.21 # [wireless airo] add support for MIC and latest firmwares # -------------------------------------------- # 03/08/26 jgarzik@redhat.com 1.1276.33.22 # [netdrvr sis190] small bug fixes # # * call pci_set_dma_mask # * remove erroneous call to unregister_netdev in _init_board() # -------------------------------------------- # 03/08/27 bellucda@tiscali.it 1.1276.1.17 # [PATCH] USB: CREDITS file update # -------------------------------------------- # 03/08/27 bellucda@tiscali.it 1.1276.1.18 # [PATCH] Audit and minor cleanups in drivers/usb/* # -------------------------------------------- # 03/08/27 bellucda@tiscali.it 1.1276.1.19 # [PATCH] Audit and minor cleanups in drivers/usb/* # # - audit video_register_device # - if usb_register fails report back its return code rather than -1 # -------------------------------------------- # 03/08/27 bellucda@tiscali.it 1.1276.1.20 # [PATCH] Audit and minor cleanups in drivers/usb/* # # - if usb_register fails report back its return code rather than -1 # -------------------------------------------- # 03/08/27 bellucda@tiscali.it 1.1276.1.21 # [PATCH] Audit and minor cleanups in drivers/usb/* # # Changes # - if usb_register fails report back its return code rather than -1 # -------------------------------------------- # 03/08/27 bellucda@tiscali.it 1.1276.1.22 # [PATCH] Audit and minor cleanups in drivers/usb/* # # - if usb_register fails report back its return code rather than -1 # - static declarations for module_init/cleanup functions # - adding missing __init/__exit for module_init/cleanup functions # -------------------------------------------- # 03/08/27 bellucda@tiscali.it 1.1276.1.23 # [PATCH] Audit and minor cleanups in drivers/usb/* # # - if usb_register fails report back its return code rather than -1 # -------------------------------------------- # 03/08/27 bellucda@tiscali.it 1.1276.1.24 # [PATCH] Audit and minor cleanups in drivers/usb/* # # - if usb_register fails report back its return code rather than -1 # -------------------------------------------- # 03/08/27 bellucda@tiscali.it 1.1276.1.25 # [PATCH] Audit and minor cleanups in drivers/usb/* # # - if usb_register fails report back its return code rather than -1 # - module_init/cleanup functions declared as static # - missing __init/__exit # -------------------------------------------- # 03/08/27 bellucda@tiscali.it 1.1276.1.26 # [PATCH] Audit and minor cleanups in drivers/usb/* # # - if usb_register fails report back its return code rather than -1 # -------------------------------------------- # 03/08/27 bellucda@tiscali.it 1.1276.1.27 # [PATCH] Audit and minor cleanups in drivers/usb/* # # - if usb_register fails report back its return code rather than -1 # -------------------------------------------- # 03/08/27 bellucda@tiscali.it 1.1276.1.28 # [PATCH] Audit and minor cleanups in drivers/usb/* # # - if usb_register fails report back its return code rather than -1 # - static declarations for module_init/cleanup functions # -------------------------------------------- # 03/08/27 bellucda@tiscali.it 1.1276.1.29 # [PATCH] Audit and minor cleanups in drivers/usb/* # # - if usb_register fails report back its return code rather than -1 # -------------------------------------------- # 03/08/27 bellucda@tiscali.it 1.1276.1.30 # [PATCH] Audit and minor cleanups in drivers/usb/* # # - if usb_register fails report back its return code rather than 0 # -------------------------------------------- # 03/08/27 greg@kroah.com 1.1276.1.31 # [PATCH] USB: fix compiler warning in mdc800 driver # -------------------------------------------- # 03/08/27 davej@redhat.com 1.1279 # [AGPGART] Update VIA PCI IDs. # - Add some new IDs # - Rename some older ones. # -------------------------------------------- # 03/08/27 bellucda@tiscali.it 1.1276.1.32 # [PATCH] ...more usb audit # # - audit hiddev_init in hid_init # - audit usb_register in hid_init # -------------------------------------------- # 03/08/27 bellucda@tiscali.it 1.1276.1.33 # [PATCH] ...more usb audit # # - audit usb_register in hiddev_init # -------------------------------------------- # 03/08/27 bellucda@tiscali.it 1.1276.1.34 # [PATCH] Another bad usb_register audit: dvb-ttusb-budget # # - if usb_register failes report back its return code rather than -1 # -------------------------------------------- # 03/08/27 bellucda@tiscali.it 1.1276.1.35 # [PATCH] Another bad audit in drivers/usb/*: usblp # # Another better audit: # - If usb_register failes report back its return value # rather than -1 # -------------------------------------------- # 03/08/27 bellucda@tiscali.it 1.1276.1.36 # [PATCH] Another bad audit in drivers/usb/*: cdc-acm # # Changes: # - if tty_register_driver report back its return code rather than -1 # - if usb_register fails report back its return code rather than -1 # -------------------------------------------- # 03/08/27 bellucda@tiscali.it 1.1276.1.37 # [PATCH] Another bad audit in drivers/usb/*: usbskeleton # # Another minor cleanup: # - if usb_register fails report back its return code rather than -1 # -------------------------------------------- # 03/08/27 bellucda@tiscali.it 1.1276.1.38 # [PATCH] Audit and minor cleanups in usbnet # -------------------------------------------- # 03/08/27 bellucda@tiscali.it 1.1276.1.39 # [PATCH] Audit and minor cleanups in usbstorage # -------------------------------------------- # 03/08/27 greg@kroah.com 1.1276.1.40 # [PATCH] USB: fix up a bunch of copyrights that were incorrectly declared. # # It needs to be "Copyright (C)" not "Copyright (c)" according to the lawyers # who know these things... # -------------------------------------------- # 03/08/27 rmk@flint.arm.linux.org.uk 1.1276.28.4 # [PCMCIA] Add generic and per-controller power management handling. # # Add per-quirk power management to aid saving/restoring controller # specific state. Also, add proper pci state saving/restoring. # Note that Cardbus bridges have to save and restore at least 0x48 # bytes of configuration space, not 0x40. # # This replaces the rather muddy save state in early initialisation, # restore it on socket init stuff that we previously had. # -------------------------------------------- # 03/08/27 rmk@flint.arm.linux.org.uk 1.1276.28.5 # [PCMCIA] Move PM restore from socket initialisation. # # There is less reason for socket initialisation to vary between # controller types now. In fact, we could very well get rid of # much of the TI-specific socket initialisation quirk handling, # since TI realised that they should be more compatible with other # implementations in later versions of their bridges. # -------------------------------------------- # 03/08/27 rmk@flint.arm.linux.org.uk 1.1276.28.6 # [PCMCIA] Put socket initialisation to where it should be. # # Move re-initialisation from the socket init/resume paths to where it # belongs - the main initialisation path. # -------------------------------------------- # 03/08/27 rmk@flint.arm.linux.org.uk 1.1276.28.7 # [PCMCIA] Move more controllers to the more advanced quirks. # # Now that we clearly know what each quirk type is doing, we can think # about switching some devices to different quirks. # # Looking at the various data sheets for these devices, many of them # support the MBURSTUP bit, so we can move these to the quirk which # supports setting this bit. # -------------------------------------------- # 03/08/27 daniel.ritz@ch.rmk.(none) 1.1276.28.8 # [PCMCIA] Add ToPIC97 and ToPIC100 support. # # Patch from Daniel Ritz. # # Add zoom video support for tosiba ToPIC97 and ToPIC100 chips. # -------------------------------------------- # 03/08/27 rmk@flint.arm.linux.org.uk 1.1276.28.9 # [PCMCIA] Don't add CIS cache entries on failure. # # If we fail to map the CIS space, don't pollute the CIS cache with # invalid data. # -------------------------------------------- # 03/08/27 willy@debian.org 1.1276.33.23 # [ethtool] fix ethtool_get_strings counting bug # -------------------------------------------- # 03/08/27 vinay-rc@naturesoft.net 1.1276.1.41 # [PATCH] USB: digi_acceleport.c: typo fix # -------------------------------------------- # 03/08/27 david-b@pacbell.net 1.1276.1.42 # [PATCH] USB: Add Kconfig option for building ax8817x support in usbnet # # David T Hollis wrote: # > This patch adds support to Kconfig to build ax8817x support into # > usbnet. This renames the config option for the existing standalone # > ax8817x driver to CONFIG_USB_AX8817X_STANDALONE. # # Please merge this version instead. It includes all of David's # patch, plus it makes the descriptive info match the updated # role of this driver. So given this, only the webpage still # needs updates; the in-tree docs are now consistent. # -------------------------------------------- # 03/08/27 david-b@pacbell.net 1.1276.1.43 # [PATCH] USB: usb_new_device() shouldn't be exported # # Minor cleanup. This call no longer needs exporting for root hubs, # they have their own API to use instead. # -------------------------------------------- # 03/08/27 david-b@pacbell.net 1.1276.1.44 # [PATCH] USB: minor doc updates # # Small kerneldoc clarifications: # # - more endpoint halt clearing info: # * some hardware can't do it; which causes problems with drivers # that want to use multiple interfaces or altsettings. # * it doesn't affect queuing of data (should help usb-storage # gadget driver, plus it's more sensible this way); # - disconnect() callback not guaranteed: some hardware can't tell # # Mostly this captures answers to questions I've been asked. # -------------------------------------------- # 03/08/27 willy@debian.org 1.1276.33.24 # [netdrvr 8139too] ethtool_ops support # -------------------------------------------- # 03/08/27 olh@suse.de 1.1276.1.45 # [PATCH] USB: io_edgeport.o differences in 2.4 vs. 2.6 # # On Fri, Aug 22, Greg KH wrote: # > On Sat, Aug 16, 2003 at 01:41:01PM +0200, Olaf Hering wrote: # > > # > > I sent you a patch for 2.4 once to make that FOO_MSR_RI, it seems that # > > was not applied to 2.6 # > Care to send me a patch for 2.6 then? # # How about that one: # -------------------------------------------- # 03/08/27 romieu@fr.zoreil.com 1.1276.33.25 # [netdrvr sis190] use PCI DMA API for RX buffers # # Missing pieces for DMA-API on the Rx side: # - SiS190_init_ring: the global area for the received data is mapped. # This area is persistent during the whole driver's life. # It only needs to be unmapped in SiS190_close() as no other exit/error # path exists. # - SiS190_rx_interrupt: no map/unmap for received data buffer. A single # sync operation is done. Btw, there is no need to store the same value # in RxDescArray[cur_rx].buf_addr over and over again. # - Remove driver dependancy on CONFIG_BROKEN. # -------------------------------------------- # 03/08/27 m@mbsks.franken.de 1.1276.1.46 # [PATCH] USB: Cyberjack patch # # Mahlzeit # # I attached you the diff for 2.6.0-test4. It does there also one program run # without any error, but not more. I hope this issue will be resolved soon, # but I do not know yet how. # -------------------------------------------- # 03/08/27 maloi@phota.to 1.1276.1.47 # [PATCH] USB: Aten 4 Port USB 2.0 KVM C (ACS-1724) # -------------------------------------------- # 03/08/27 greg@kroah.com 1.1276.1.48 # [PATCH] USB: hook up the USB driver core to the power management calls of the driver model. # # Now it's up to the individual USB drivers to implement suspend() and # resume() if they want to. # -------------------------------------------- # 03/08/27 greg@kroah.com 1.1276.1.49 # [PATCH] USB: rip out old proc code from the usbvideo driver. # # This removes the compiler warning from this driver. # -------------------------------------------- # 03/08/27 greg@kroah.com 1.1276.1.50 # [PATCH] USB: removed the proc code from the se401.c driver # # This removes the compiler warning. # -------------------------------------------- # 03/08/27 david-b@pacbell.net 1.1276.1.51 # [PATCH] USB: usbnet minor cleanup # # This goes on top of Dave Hollis' patch, and makes the front matter # match the slightly revised role -- and mention that new support. # It also eliminates a potentially confusing name and corrects an # omission (Zaurus framing wasn't printed). # -------------------------------------------- # 03/08/27 david-b@pacbell.net 1.1276.1.52 # [PATCH] USB: net2280 fixes: ep halt, sysfs # # Small updates: # # - don't try chiprev 0100 erratum 0114 workaround on # newer chips; and (mostly) revert it when clearing # endpoint halt feature. (bugfix) # # - add missing define for the "force crc error" bit; # I guess those #defines were generated from old chip # specs! potentially useful with test software. # # - sysfs register dump includes chiprev and decodes some # of the more interesting endpoint response bits. # # - makes a sysfs "gadget" node, representing the gadget # itself. (decided against the class_device or bus_type # approaches, until their value outweighs their costs.) # -------------------------------------------- # 03/08/27 david-b@pacbell.net 1.1276.1.53 # [PATCH] USB: usbnet, cdc ethernet descriptor parsing fixes # # This makes the new CDC Ethernet code handle more devices: # # - Uses the active config, not just the default one, if it's # coping "descriptors in wrong place" quirk. (bugfix) # # - Uses usb_ifnum_to_if() to get interfaces. (bugfix) # # - AMBIT USB cable modems have bogus CDC Union descriptors; # workaround by switching master and slave. (add quirk) # # - To make it easier the next time we run into firmware # that violates the class spec, add debug messages saying # exactly why it's giving up on a given CDC device. # # Net result, this code now handles at least one more # cable modem design. # -------------------------------------------- # 03/08/27 david-b@pacbell.net 1.1276.1.54 # [PATCH] USB: ohci -- reset, fault recovery # # This fixes two small and unrelated bugs in the current OHCI code: # # - Certain initialization sequences had problems with IRQs. # Fixed last month in EHCI, but this ohci patch didn't seem # needed back then. OK, so now I saw the same bug in OHCI. # (I could believe UHCI needs it too, sigh.) # # - When restarting endpoint i/o after a queue fault, the HC # needs to be told the control (or bulk) list filled (CLF/BLF). # Likely this wasn't common (usbtest test10 subcase7 fault # recovery reproduced it nicely). # # Please merge. Lack of the first one might make trouble for # some people. # -------------------------------------------- # 03/08/27 david-b@pacbell.net 1.1276.1.55 # [PATCH] USB: uhci-hcd, add uhci_reset() # # This is a straightforward change matching ones sent in # for ehci (last month) and ohci (earlier this week). # # It abstracts the reset operation into something that's # called before the pci glue does much to the hardware. # # It also arranges to kick the BIOS off the hardware before # it resets it (not after) ... so there's no confusion at # any time about what driver "owns" that hardware. (Again # matching what ehci and ohci drivers do.) # -------------------------------------------- # 03/08/27 chas@cmf.nrl.navy.mil 1.1276.26.28 # [ATM]: Clean up the code making use of sti/cli (from vinay-rc@naturesoft.net) # -------------------------------------------- # 03/08/27 chas@cmf.nrl.navy.mil 1.1276.26.29 # [ATM]: In ambassador driver, use del_timer_sync instead. # -------------------------------------------- # 03/08/27 set@pobox.com 1.1276.26.30 # [NET]: Fix probing messages in 3c509.c # # Currently, 3c509.c prints this on detection: # eth%d: 3c5x9 at 0x280, BNC port, address 00 20 af 2f d4 81, IRQ 5. # ^^ # -------------------------------------------- # 03/08/27 jgarzik@redhat.com 1.1276.2.62 # [TG3]: Remove pci-set-dma-mask casts. # -------------------------------------------- # 03/08/27 yoshfuji@linux-ipv6.org 1.1276.26.31 # [NET]: Fix OOPS in multicast procfs usage. # # Fix several refcntmistakes in seq_file handlers for # /proc/net/{igmp,igmp6,msfilter,msfilter6} # -------------------------------------------- # 03/08/27 bunk@fs.tum.de 1.1276.26.32 # [NET]: Fix bpqether build with procfs disabled. # -------------------------------------------- # 03/08/27 davem@nuts.ninka.net 1.1276.25.3 # [SPARC]: Add missing timer_create syscall entries. # -------------------------------------------- # 03/08/27 jakub@redhat.com 1.1276.25.4 # [COMPAT]: Add missing set_fs() calls to {clock,timer}_*() handlers. # -------------------------------------------- # 03/08/28 krishnakumar@naturesoft.net 1.1276.26.33 # [IPV4]: Fix creat_proc_read_entry() args. # -------------------------------------------- # 03/08/28 rob@osinvestor.com 1.1276.25.5 # [SPARC]: Two build fixes. # -------------------------------------------- # 03/08/28 xose@wanadoo.es 1.1276.2.63 # [TG3]: More missing PCI ids. # -------------------------------------------- # 03/08/28 zaitcev@redhat.com 1.1276.25.6 # [SPARC]: Add pci_{map,unmap}_page(). # -------------------------------------------- # 03/08/28 rddunlap@osdl.org 1.1276.26.34 # [SCTP]: Fix printf format string. # -------------------------------------------- # 03/08/28 rddunlap@osdl.org 1.1276.26.35 # [IPVS]: Fix printf format strings. # -------------------------------------------- # 03/08/28 rddunlap@osdl.org 1.1276.26.36 # [HAMRADIO]: Missing return statement in yam.c driver. # -------------------------------------------- # 03/08/28 jakub@redhat.com 1.1276.25.7 # [SPARC64]: Fix struct sigevent32. # -------------------------------------------- # 03/08/28 jakub@redhat.com 1.1276.25.8 # [SPARC64]: sys_timer_create needs 32-bit translation. # -------------------------------------------- # 03/08/28 jakub@redhat.com 1.1276.25.9 # [SPARC]: Fix typos. # -------------------------------------------- # 03/08/28 greg@kroah.com 1.1276.1.56 # Merge gregkh@kernel.bkbits.net:linux/linus-2.6 # into kroah.com:/home/greg/linux/BK/gregkh-2.6 # -------------------------------------------- # 03/08/28 stern@rowland.harvard.edu 1.1276.1.57 # [PATCH] USB: Another unusual_devs.h entry update # # This information was provided by Anthony Arkles . # Please apply to both 2.4 and 2.6. # -------------------------------------------- # 03/08/28 david-b@pacbell.net 1.1276.1.58 # [PATCH] USB: net2280, patch dma chains # # One person working on a mass-storage driver (the usb protocol # side, not the block subsystem side) ran into a bug in how a # bit of net2280 dma automagic was handled. # # This patch fixes it by calling existing dma chain patchup # code when the dma engine was forced to "hiccup" by having # a not-yet-valid entry in it. The hiccup is needed in this # case since the IN data stage mustn't terminate with a # short transfer (zero length packet); but the status stage # is always a short packet. The "terminate with short packet" # bit is endpoint state, not request state, so IN dma queues # sometimes need this kind of fixup. # -------------------------------------------- # 03/08/28 rddunlap@osdl.org 1.1276.1.59 # [PATCH] USB: fix printk parameter types # -------------------------------------------- # 03/08/28 rddunlap@osdl.org 1.1276.1.60 # [PATCH] USB: fix functions to match prototypes # -------------------------------------------- # 03/08/28 greg@kroah.com 1.1276.1.61 # [PATCH] USB: add support for 2 new devices to the visor driver. # # Based on the 2.4 version of the driver. # -------------------------------------------- # 03/08/29 davej@redhat.com 1.1280 # [AGPGART] Numerous AMD64 gart driver cleanups. # From Andi Kleen. # # - Fix the help text for the 8151 driver # - Fix the dependencies (must be compiled in when the IOMMU is in) # - Add __setup options for when the AGP driver is compiled in: # agp=off agp=try_unsupported # Currently only supported for the K8 driver, the other drivers # would need fixes in their module init functions too. # - Add try_unsupported support for the K8 driver. # - Add some aperture sanity checking to the K8 driver. # There are unfortunately still BIOS around that get it wrong. # - Also try to read the aperture from the AGP bridge if it is bogus # in the Northbridge. Windows only looks into the bridge and some BIOS only # put the aperture there. # [These two changes are only useful for 32bit kernels. The 64bit kernel # checks this in aperture.c anyways, and fixes it. The 32bit kernel # cannot fix a complety broken aperture currently, but at least it will # not crash now] # - Clean up handling for multiple northbridges. The paths are the same # now for as for a single NB. # - Some other minor cleanups. # -------------------------------------------- # 03/08/29 davej@redhat.com 1.1281 # [AGPGART] Fix indentation. # -------------------------------------------- # 03/08/29 davej@redhat.com 1.1282 # [AGPGART] Use generic AGP_APBASE define instead of per vendor _APBASE. # # -------------------------------------------- # 03/08/29 davej@redhat.com 1.1283 # [AGPGART] move NVIDIA registers to agp.h # -------------------------------------------- # 03/08/28 davem@nuts.ninka.net 1.1276.25.10 # [SPARC64]: Make sure init_irqwork_curcpu() is called with PSTATE_IE off. # -------------------------------------------- # 03/08/29 davej@redhat.com 1.1284 # [AGPGART] Indentation fixes # -------------------------------------------- # 03/08/29 davej@redhat.com 1.1285 # [AGPGART] Fix missed AGP_APBASE conversion in VIA AGP driver. # -------------------------------------------- # 03/08/29 davej@redhat.com 1.1286 # [AGPGART] Remove unneeded 8151 defines. # -------------------------------------------- # 03/08/29 davej@redhat.com 1.1287 # [AGPGART] Make AMD64 GART driver marchitecture compliant. # X86_64 -> AMD64 # -------------------------------------------- # 03/08/28 greg@kroah.com 1.1276.1.62 # [PATCH] USB: fix usbnet for older versions of gcc # -------------------------------------------- # 03/08/29 paulus@samba.org 1.1276.29.9 # Merge bk://stop.crashing.org/linux-2.6-kgdb # into samba.org:/home/paulus/kernel/for-linus-ppc # -------------------------------------------- # 03/08/29 greg@kroah.com 1.1276.1.63 # [PATCH] USB: fix oops in keyspan and whiteheat devices when plugged in. # # Thanks to Pat Mochel for finding out where the error was for this bug. # -------------------------------------------- # 03/08/29 greg@kroah.com 1.1276.1.64 # [PATCH] USB: remove usage of DEVICE_ID_SIZE from usb core as it should not be used. # -------------------------------------------- # 03/08/29 dhollis@davehollis.com 1.1276.1.65 # [PATCH] USB: Fix building of ax8817x if CONFIG_USB_AX8817X_STANDALONE # -------------------------------------------- # 03/08/29 quade@hsnr.de 1.1276.1.66 # [PATCH] USB: usb-skeleton bugfix # -------------------------------------------- # 03/08/30 wim@iguana.be 1.1276.34.1 # [WATCHDOG] advantechwdt.c - patch # # small clean-up (add trivial comma) # -------------------------------------------- # 03/08/30 wim@iguana.be 1.1276.34.2 # [WATCHDOG] wafer5823wdt.c - patch # # general clean-up (comments, trailing spaces, ...) # Added WATCHDOG_NAME and PFX defines for easier printk's. # clean-up printk's. # -------------------------------------------- # 03/08/30 wim@iguana.be 1.1276.34.3 # [WATCHDOG] wafer5823wdt.c - patch2 # # fix possible wafwdt_is_open race # make wdt_stop and wdt_start module params # change wd_margin to timeout and make it a module_param # make expect_close the same system as in advantechwdt.c # clean-up ioctl handling # added extra printk's to report what problem occured # add MODULE_DESCRIPTION info # -------------------------------------------- # 03/08/30 jgarzik@redhat.com 1.1276.33.26 # [netdrvr 8139cp] build TX checksumming code, but default OFF # # (previously it was ifdef'd) # # Also, bump version to 1.0. # -------------------------------------------- # 03/08/30 shemminger@osdl.org 1.1276.26.37 # [LLC]: Need to pskb_may_pull() in fix_up_incoming_skb(). # -------------------------------------------- # 03/08/30 shemminger@osdl.org 1.1276.26.38 # [LLC]: Missing sk_set_owner() in llc_sk_alloc. # -------------------------------------------- # 03/08/30 jgarzik@redhat.com 1.1276.33.27 # [netdrvr 8139cp] support NAPI on RX path; Ditch RX frag handling. # # NAPI is turned on unconditionally for the RX path. The hardware # supports interrupt mitigation, so that should be investigated too. # # RX fragment handling removed. We simply ensure that we alloc # buffers large enough to hold incoming packets. Any stray RX # frags that occur (shouldn't be any) will be dropped. # -------------------------------------------- # 03/08/30 shemminger@osdl.org 1.1276.26.39 # [LLC]: Set module owner on /proc/net/llc directory. # -------------------------------------------- # 03/08/30 shemminger@osdl.org 1.1276.26.40 # [ECONET]: Missing sk_set_owner(). # -------------------------------------------- # 03/08/30 shemminger@osdl.org 1.1276.26.41 # [IPX]: Missing sk_set_owner(). # -------------------------------------------- # 03/08/30 shemminger@osdl.org 1.1276.26.42 # [ATM]: Missing sk_set_owner(). # -------------------------------------------- # 03/08/30 jgarzik@redhat.com 1.1276.33.28 # [netdrvr 8139cp] update todo list in header # -------------------------------------------- # 03/08/30 shemminger@osdl.org 1.1276.26.43 # [AX25/NETROM/ROSE]: Missing sk_set_owner(). # -------------------------------------------- # 03/08/30 shemminger@osdl.org 1.1276.26.44 # [IRDA]: Missing sk_set_owner(). # -------------------------------------------- # 03/08/30 shemminger@osdl.org 1.1276.26.45 # [DDP]: Missing sk_set_owner(). # -------------------------------------------- # 03/08/30 jgarzik@redhat.com 1.1276.33.29 # [netdrvr 8139cp] remove mentions of RTL8169 (now handled by "r8169") # -------------------------------------------- # 03/08/30 shemminger@osdl.org 1.1276.26.46 # [DDP]: Invert logic for clarity. # # It is a lot clearer to invert the logic used in the destroy_socket # so that it ends up as a positive expression, rather than a double negative. # # The SOCK_DEAD is redundant and can be eliminated because it is always # set in the atalk_release() the only caller. # -------------------------------------------- # 03/08/30 shemminger@osdl.org 1.1276.26.47 # [ATALK]: Fix whitespace in /proc/net/atalk/interfaces header. # -------------------------------------------- # 03/08/30 shemminger@osdl.org 1.1276.26.48 # [ATALK]: AARP ->last_sent field never set. # -------------------------------------------- # 03/08/30 shemminger@osdl.org 1.1276.26.49 # [ATALK]: Purge AARP table on module unload. # -------------------------------------------- # 03/08/30 shemminger@osdl.org 1.1276.26.50 # [ATALK]: AARP needs to use del_timer_sync(). # # Aarp module unload needs to use del_timer_sync to handle the # race condition where timer starts or is running during module # unload. # -------------------------------------------- # 03/08/30 shemminger@osdl.org 1.1276.26.51 # [ATALK]: Convert AARP over to seq_file. # # The output format is slightly changed: # - address is printed in same format as /proc/net/atalk/interface # - retry and last_sent are only shown for unresolved entries # - times shown in seconds.hundreths rather than raw jiffies # - column headers changed to same format as /proc/net/atalk/interface # -------------------------------------------- # 03/08/30 shemminger@osdl.org 1.1276.26.52 # [ATALK]: Set owner on /proc/net/atalk directory. # -------------------------------------------- # 03/08/30 shemminger@osdl.org 1.1276.26.53 # [DDP]: Fix obsolete comment about module handling. # -------------------------------------------- # 03/08/30 shemminger@osdl.org 1.1276.26.54 # [DDP]: Fix oops in aecho socket handling. # # This fixes the problem caused by interrupting aecho causing an oops. # What happened was that the sock was detached from the user process # but sk->sk_sleep was still so when write data was freed it would # do a wakeup on a poisoned data. The sk_state_change code that was # there isn't necessary, because we are in middle of release so no # user process can be waiting. sock_orphan does the right thing # and sets SOCK_DEAD. # # This is similar to what some other protocols do. But some will # have the same sk->sk_sleep problem... # -------------------------------------------- # 03/08/30 shemminger@osdl.org 1.1276.26.55 # [ATALK]: Move aarp procfs file into atalk subdirectory. # # Move aarp /proc interface like all the others in 2.6; # the other appletalk /proc interfaces were moved to /proc/net/atalk # but aarp was overlooked. # -------------------------------------------- # 03/08/30 shemminger@osdl.org 1.1276.26.56 # [DDP]: Missing netdev refcounting. # # DDP holds a pointer to underlying network device, but doesn't # do the refcount bookeeping that it should. # -------------------------------------------- # 03/08/30 shemminger@osdl.org 1.1276.26.57 # [DDP]: Convert to new protocol interface. # # Convert ddp to the new protocol interface which means it has to # handle fragmented skb's. The only big change is in the checksum # routine which has to do more work (like skb_checksum). # # Minor speedup is folding the carry to avoid a branch. # # Tested against a 2.4 system and by running both code over # a range of packets. # -------------------------------------------- # 03/08/30 shemminger@osdl.org 1.1276.26.58 # [BLUETOOTH]: Missing sk_set_owner(). # -------------------------------------------- # 03/08/30 jgarzik@redhat.com 1.1276.33.30 # [netdrvr 8139cp] small cleanups # # * remove netif_queue_stopped test, netif_wake_queue already does that # * move vlan stuff to top of file # * remove __dev markers # * update todo list at top of file # * remove pci_set_dma_mask argument casts; ULL suffixes preferred. # -------------------------------------------- # 03/08/30 jgarzik@redhat.com 1.1276.33.31 # [netdrvr 8139cp] fix NAPI bug; remove board_type distinction, not needed # -------------------------------------------- # 03/08/30 jgarzik@redhat.com 1.1276.33.32 # [netdrvr 8139cp] bump version # -------------------------------------------- # 03/08/30 felipewd@terra.com.br 1.1276.26.59 # [NETFILTER]: Remove unneeded version.h inclusion. # -------------------------------------------- # 03/08/30 felipewd@terra.com.br 1.1276.26.60 # [SUNRPC]: Remove unneeded version.h inclusion. # -------------------------------------------- # 03/08/30 felipewd@terra.com.br 1.1276.26.61 # [RXRPC]: Remove unneeded version.h inclusion. # -------------------------------------------- # 03/08/30 bdschuym@pandora.be 1.1276.26.62 # [BRIDGE]: Add 802.3 filtering support. # -------------------------------------------- # 03/08/30 laforge@netfilter.org 1.1276.26.63 # [NETFILTER]: Fix ipt_helper build problem wrt. Kconfig. # # Please apply the following patch (against 2.6.0-test4). It fixes a bug # in Kconfig causing ipt_helper not to be compiled if ip_conntrack is a # module. # -------------------------------------------- # 03/08/30 laforge@netfilter.org 1.1276.26.64 # [NETFILTER]: Fix email address in MODULE_AUTHOR. # -------------------------------------------- # 03/08/30 davem@nuts.ninka.net 1.1276.26.65 # [IPV6]: Do not mistakedly use ndisc route for normal ipv6 output. # # Based upon a patch from Kazunori Miyazawa # -------------------------------------------- # 03/08/31 jgarzik@redhat.com 1.1276.33.33 # [netdrvr 8139cp] stats improvements and fixes # # * make sure rx_frags is still accounted # * query RxMissed register, and clear, upon each get-stats func call # -------------------------------------------- # 03/08/30 davem@nuts.ninka.net 1.1276.25.11 # [POSIX_TIMERS]: Do not assume timeval/timespec layout is identical. # # Based upon a patch from Jakub Jelinek # -------------------------------------------- # 03/08/30 davem@nuts.ninka.net 1.1276.25.12 # [SPARC64]: In sysv IPC translation, mask out IPC_64 as appropriate. # # Based upon a patch from Keith M Wesolowski # -------------------------------------------- # 03/08/31 jgarzik@redhat.com 1.1276.33.34 # [netdrvr 8139too] make features more persistent; fix PCI DAC mode # # * only set PCIDAC (64-bit PCI) bit in hardware if # sizeof(dma_addr_t) > 32. Need a better test for whether # 64-bit mode is _really_ needed. # * cache chip command register in private struct. this allows # the setting of rx-vlan, rx-csum, and other features to be # persistent across the entire lifetime of the net device. # * remove dead private struct members frag_skb, dropping_frag, # and pci_using_dac. # -------------------------------------------- # 03/08/31 jgarzik@redhat.com 1.1276.33.35 # [netdrvr pcmcia] support SIOC[GS]MII{PHY,REG} ioctls # # Updated drivers; 3c574_cs, axnet_cs, pcnet_cs, xirc2ps_cs # # Thanks to Komuro for pointing this out. # -------------------------------------------- # 03/08/31 lethal@linux-sh.org 1.1276.33.36 # [netdrvr 8139too] fix and pci ids needed for SH platform # # a.k.a. Sega Broadband Adapter. # -------------------------------------------- # 03/08/31 jgarzik@redhat.com 1.1276.33.37 # [netdrvr 8139too] remove useless board names # # The only thing that differentiated most of the entries in the # board_info[] table and the board_t type was the vendor branding # string for the board. This table is a pain to maintain, so we # prefer to simply use "RTL8129" or "RTL8139". # -------------------------------------------- # 03/08/31 jgarzik@redhat.com 1.1276.33.38 # [netdrvr 3c509] dev->name removal build fix # -------------------------------------------- # 03/08/31 purna@jcom.home.ne.jp 1.1276.33.39 # [netdrvr] fix skb_padto bugs introduced when skb_padto was introduced # # It seems that skb_padto security fixes in 2.4 and 2.5 trying # to fix "CAN-2003-0001:Multiple ethernet NID device drivers # do not pad frames with null bytes", do not put the skb_padto # blocks in proper places in the 3c527, eth16i, fmv18x, seeq8005, # yellowfin device drivers. # # In case a driver calls skb_padto(), it is possible # that the space available in the original skb buffer tailroom is less # than the space to pad. In this case, in short, the skb_padto() # will create a new skb buffer, copy data from the original # skb buffer to a new skb buffer, free the original buffer, # and finally return the new buffer. # # If this happens to the aforementioned device drivers, they come to # point to wrong data. And, for 3c527 and yellowfin, the drivers can # unexpectedly double free the original skb buffers since they still # point to the original skb buffers. The attached patch against # 2.4.23pre1 fixes these issues. # -------------------------------------------- # 03/08/31 jgarzik@redhat.com 1.1276.33.40 # [netdrvr 8139cp] must call NAPI-specific vlan hook # -------------------------------------------- # 03/08/31 jgarzik@redhat.com 1.1276.33.41 # [netdrvr ixgb] must call NAPI-specific vlan hook # -------------------------------------------- # 03/08/31 jgarzik@redhat.com 1.1276.33.42 # [netdrvr sk_mca] somebody typo'd in their cli()-to-spinlock conversion # # Anybody with hardware, that can test this driver? # -------------------------------------------- # 03/08/31 jgarzik@redhat.com 1.1276.33.43 # [netdrvr sk_mca] remove ancient-kernel compat code; fix bugs # # * removed ancient-kernel compat code from sk_mca.h. I leave # it to janitors to remove the now-useless SKMCA_xxx wrappers. # * removed ancient-kernel compat code from sk_mca.c. # * s/SKMCA_NETDEV/net_device/ # * fixed static net_device initialization (this will go away # when dynamic-alloc patches land) # -------------------------------------------- # 03/08/31 drepper@redhat.com 1.1276.35.1 # [PATCH] More ->pid to ->tgid changes # # One more overlooked area where the proper process ID has to be used: # SysV IPC "pid" values should use the thread group ID, not the per-thread # one. # -------------------------------------------- # 03/08/31 wim@iguana.be 1.1276.34.4 # [WATCHDOG] wafer5823wdt.c - patch3 # # fix MODULE_PARM_DESC for timeout # add WDIOC_SETOPTIONS functionality # -------------------------------------------- # 03/08/31 wim@iguana.be 1.1276.34.5 # [WATCHDOG] acquirewdt.c - patch # # clean-up of comments, trailing spaces, includes, ... # removed unnecessary spinlocking # added WATCHDOG_NAME + PFX defines for easier printk's # clean-up expect_close / acq_is_open # made wdt_stop and wdt_start a module_param # clean-up ioctl handling # clean-up init and exit routines # added MODULE_AUTHOR + MODULE_DESCRIPTION info # -------------------------------------------- # 03/08/31 wim@iguana.be 1.1276.34.6 # [WATCHDOG] alim1535_wdt.c # # Add "ALi M1535 PMU Watchdog Timer" driver # -------------------------------------------- # 03/08/31 B.Zolnierkiewicz@elka.pw.edu.pl 1.1276.35.2 # [PATCH] cable detection fixes for HPT37x controllers # # From Duncan Laurie # # This same patch made its way into 2.4 via the -ac tree but hasn't # been put in 2.6 yet. # # It fixes some cable detect issues that stem from the fact that the # cable detect pins are also used as address/data lines, so they need # to first be configured as inputs to read valid cable detect state. # -------------------------------------------- # 03/08/31 B.Zolnierkiewicz@elka.pw.edu.pl 1.1276.35.3 # [PATCH] fix PowerMac driver breakage caused by recent dynamic queue change # # From Mikael Pettersson . # -------------------------------------------- # 03/08/31 B.Zolnierkiewicz@elka.pw.edu.pl 1.1276.35.4 # [PATCH] fix ide.c warning when compiling IDE for non-PCI systems # # From Stephane Ouellette . # -------------------------------------------- # 03/08/31 B.Zolnierkiewicz@elka.pw.edu.pl 1.1276.35.5 # [PATCH] fix ide-lib.c warning when compiling IDE without DMA support # # From Mikael Pettersson . # -------------------------------------------- # 03/08/31 B.Zolnierkiewicz@elka.pw.edu.pl 1.1276.35.6 # [PATCH] allow drivers (ie. mediabay) to set hwif->gendev.parent # # From Benjamin Herrenschmidt . # -------------------------------------------- # 03/08/31 B.Zolnierkiewicz@elka.pw.edu.pl 1.1276.35.7 # [PATCH] kill ide_modes.h # -------------------------------------------- # 03/08/31 B.Zolnierkiewicz@elka.pw.edu.pl 1.1276.35.8 # [PATCH] do not set drive->dn twice in probe_hwif() # -------------------------------------------- # 03/08/31 B.Zolnierkiewicz@elka.pw.edu.pl 1.1276.35.9 # [PATCH] kill ide_init_drive() in ide-probe.c # # also fix comment in init_irq() # -------------------------------------------- # 03/08/31 B.Zolnierkiewicz@elka.pw.edu.pl 1.1276.35.10 # [PATCH] remove unused exports from ide-probe.c # # export_ide_init_queue() and export_probe_for_drive() # -------------------------------------------- # 03/08/31 B.Zolnierkiewicz@elka.pw.edu.pl 1.1276.35.11 # [PATCH] remove unused ide_chipsets and IDE_CHIPSET_MODULE # -------------------------------------------- # 03/08/31 B.Zolnierkiewicz@elka.pw.edu.pl 1.1276.35.12 # [PATCH] kill ide_module_t # -------------------------------------------- # 03/08/31 B.Zolnierkiewicz@elka.pw.edu.pl 1.1276.35.13 # [PATCH] kill ide_register() # -------------------------------------------- # 03/08/31 jgarzik@redhat.com 1.1276.33.44 # Merge redhat.com:/spare/repo/linus-2.6 # into redhat.com:/spare/repo/net-drivers-2.6 # -------------------------------------------- # 03/08/31 ak@muc.de 1.1276.35.14 # [PATCH] Make ACPI_SLEEP select SOFTWARE_SUSPEND # # CONFIG_ACPI_SLEEP doesn't compile without SOFTWARE_SUSPEND. # Make it select it automagically. # # This fixes some bugzilla bug whose number I forgot. # -------------------------------------------- # 03/08/31 ak@muc.de 1.1276.35.15 # [PATCH] Do 32bit addresses in /proc/self/maps if possible # # As discussed earlier. This implements Linus' idea of printing # the addresses in /proc//maps as 32bit if possible. # # This works around some broken 32bit programs that cannot parse # 64bit addresses as generated by x86-64 kernels. # # Also simplifies the code slightly. # -------------------------------------------- # 03/08/31 romieu@fr.zoreil.com 1.1276.35.16 # [PATCH] sis190 driver fix # # synchronize_irq() requires an argument when built with CONFIG_SMP. # -------------------------------------------- # 03/08/31 ak@muc.de 1.1276.35.17 # [PATCH] x86-64 update # # Make everything compile and boot again. # # The earlier third party ioport.c changes unfortunately didn't even # compile, fix that too. # # - Update defconfig # - Some minor cleanup # - Introduce physid_t for APIC masks (fixes UP kernels) # - Finish ioport.c merge and fix compilation # - Add bandaid for CardBus bridges and broken BIOS (Vojtech) # - Add bandaid for unsynchronized TSCs (Vojtech) # - Fix ffs(0) return value (fixes XFS) # - Fix compilation with software suspend # -------------------------------------------- # 03/08/31 hirofumi@mail.parknet.co.jp 1.1276.33.45 # [netdrvr 8139too] remove driver-based poisoning of net_device # # Harmless in 2.4, but causes oopses on rmmod in 2.6. # # slab poisoning can take care of this for us, anyway. # -------------------------------------------- # 03/08/31 hirofumi@mail.parknet.co.jp 1.1276.33.46 # [netdrvr 8139too] don't start thread when it's not needed # # The thread for was unneeded on chips other than CH_8139_K/8129. So, # this patch doesn't create the thread on chips other than # CH_8139_K/8129. # # -------------------------------------------- # 03/08/31 axboe@suse.de 1.1276.35.18 # [PATCH] cciss init problem # # This assigns the queue properly. # -------------------------------------------- # 03/08/31 willy@debian.org 1.1276.35.19 # [PATCH] bio.c: reduce verbosity at boot # # The queue init is really far too verbose at boot time. I don't think # these messages add anything to either the end user experience or debug # ability. # # Acked by Jens # -------------------------------------------- # 03/08/31 neilb@cse.unsw.edu.au 1.1276.35.20 # [PATCH] Fix module ref counting for md. # # We don't need to explicitly count references as: # - refcounting already happens for opens of /dev/md? # - when an array is active, a daughter module is loaded which # locks "md" in. # We just need to make sure we clean up properly on unload. (export_array) # # Also, xor needs a null module_exit so that it can be unloaded. # -------------------------------------------- # 03/08/31 neilb@cse.unsw.edu.au 1.1276.35.21 # [PATCH] Honour the read-ahead for for reads in raid5. # # If we get a failure trying to allocate a stripe_head for a read-ahead # request (the only time we can get a failure), we skip the rest of the # request and fail the whole bio. # -------------------------------------------- # 03/08/31 neilb@cse.unsw.edu.au 1.1276.35.22 # [PATCH] Set max_sectors for raid0 only, not for all raid levels. # # raid1 and multipath have not concept of a chunksize, so basing # max_sectors on it is obviously wrong. # # Similary 'linear' has a very different concept of chunksize and # max_sectors doesn't apply. # # raid5 does have relevant chunk_size concept, but it has code to # effectively handle any chunksize. # # So we only need to set max_sectors based on chunk_size in raid0. # -------------------------------------------- # 03/08/31 neilb@cse.unsw.edu.au 1.1276.35.23 # [PATCH] Fix md superblock incompatabilities with 2.4 kernels. # # 2.4 kernels are very fussy about some values in the superblock, and # 2.6 got them wrong. This fixes it. # -------------------------------------------- # 03/08/31 neilb@cse.unsw.edu.au 1.1276.35.24 # [PATCH] Track nfsv4 open files by "struct inode" rather than dev/ino/generation # -------------------------------------------- # 03/08/31 neilb@cse.unsw.edu.au 1.1276.35.25 # [PATCH] fix in NFSv4 server for bad sequence id errors # # From: "William A.(Andy) Adamson" # # this patch fixes the share state sequenceid bookeeping. # # - increment the sequence id on an open that is confirmed # - increment the sequence id on close # -------------------------------------------- # 03/08/31 gerg@snapgear.com 1.1276.35.26 # [PATCH] use irqreturn_t in m68knommu/5206 config.c # -------------------------------------------- # 03/08/31 gerg@snapgear.com 1.1276.35.27 # [PATCH] use irqreturn_t in m68knommu/5206e config.c # # Fix up interrupt handler type to be irqreturn_t. # -------------------------------------------- # 03/08/31 gerg@snapgear.com 1.1276.35.28 # [PATCH] use irqreturn_t in m68knommu/5249 config.c # # Fix up interrupt handler type to be irqreturn_t. # -------------------------------------------- # 03/08/31 gerg@snapgear.com 1.1276.35.29 # [PATCH] use irqreturn_t in m68knommu/5272 config.c # # Fix up interrupt handler type to be irqreturn_t. # -------------------------------------------- # 03/08/31 viro@www.linux.org.uk 1.1276.35.30 # [PATCH] dev_t handling cleanups (1/12) # # removed unused kdev_t stuff, fixed a typo left from the # console->device() conversion. # -------------------------------------------- # 03/08/31 viro@www.linux.org.uk 1.1276.35.31 # [PATCH] dev_t handling cleanups (2/12) # # tty_paranoia_check() switched from kdev_t to struct inode. # -------------------------------------------- # 03/08/31 viro@www.linux.org.uk 1.1276.35.32 # [PATCH] dev_t handling cleanups (3/12) # # killed gratitious uses of kdev_t in tpqic02 # -------------------------------------------- # 03/08/31 viro@www.linux.org.uk 1.1276.35.33 # [PATCH] dev_t handling cleanups (4/12) # # jffs used to put kdev_t values on disk - blind copy of in-core # representation. # # Switched to explicit use of u16 (which is what kdev_t currently is), # with appropriate conversion # -------------------------------------------- # 03/08/31 viro@www.linux.org.uk 1.1276.35.34 # [PATCH] dev_t handling cleanups (5/12) # # removed bogus uses of ->i_sb->s_dev in intermezzo (comparizons can and # should simply compare ->i_sb, printks should use ->s_id). # -------------------------------------------- # 03/08/31 viro@www.linux.org.uk 1.1276.35.35 # [PATCH] dev_t handling cleanups (6/12) # # - hpfs_unlink() should not try to truncate the victim unless it's a # regular file; truncate will not help for anything else and it will # screw the page cache if victim happens to be a block device. # - network filesystems should *not* invalidate page cache of block # device node when inode gets invalidated; fixed, added a new helper - # invalidate_remote_inode(). # - nfs setattr syncs the file before sending SETATTR to server; that # makes a lot of sense for regular files, but not for anything else. # Fixed. # -------------------------------------------- # 03/08/31 viro@www.linux.org.uk 1.1276.35.36 # [PATCH] dev_t handling cleanups (7/12) # # removed dead code from sparc64 hugetlbpage.c # -------------------------------------------- # 03/08/31 viro@www.linux.org.uk 1.1276.35.37 # [PATCH] dev_t handling cleanups (8/12) # # Now that floppy_open() stores bdev in opened_bdevs[drive], we can remove # crap from floppy_read_block_0() and have it use that bdev instead of # messing with bdget_disk()/setting ->bd_disk by hand/bdput(). # -------------------------------------------- # 03/08/31 viro@www.linux.org.uk 1.1276.35.38 # [PATCH] dev_t handling cleanups (9/12) # # struct block_device made the private part of bdevfs inodes; bd_count # is gone, we use ->i_count of inode now; separate hash is also gone and we # are using iget5_locked()/igrab()/iput() instead. # -------------------------------------------- # 03/08/31 viro@www.linux.org.uk 1.1276.35.39 # [PATCH] dev_t handling cleanups (10/12) # # new helper - iminor(inode); defined as minor(inode->i_rdev); lots and # lots of places in drivers had been switched to it. # -------------------------------------------- # 03/08/31 viro@www.linux.org.uk 1.1276.35.40 # [PATCH] dev_t handling cleanups (11/12) # # new helper - imajor(inode) # -------------------------------------------- # 03/08/31 viro@www.linux.org.uk 1.1276.35.41 # [PATCH] dev_t handling cleanups (12/12) # # added the exclusion between ADD_PARTITION/DELETE_PARTITION/open() (BLKPG # ioctls didn't grab ->bd_sem when they should have). # # added bdev->bd_part; it is set at open() to point to the hd_struct of # partition in question, reset on final close. # # blk_partition_remap() uses ->bd_part instead of the current mess # # ->bd_offset is gone, we use ->bd_part->start_sect instead # # added missing ->release() to hd_struct kobject, moved kfree() into it # # ->bd_part cotributes to refcount of hd_struct - we bump it when # # ->bd_part is set and drop when it's reset. # -------------------------------------------- # 03/08/31 linux-watchdog.adm@hostme.bitkeeper.com 1.1276.34.7 # Merge http://linux.bkbits.net/linux-2.5 # into hostme.bitkeeper.com:/repos/l/linux-watchdog/linux-2.5-watchdog # -------------------------------------------- # 03/08/31 geert@linux-m68k.org 1.1276.35.42 # [PATCH] vmlinux-*.lds (was: Re: Linux 2.6.0-test4) # # Kai Germaschewski: # > o kbuild: Move generation of vmlinux.lds.s into arch/.../kernel # # This forgot to move two files: # # mv arch/m68k/vmlinux-std.lds arch/m68k/kernel # mv arch/m68k/vmlinux-sun3.lds arch/m68k/kernel # -------------------------------------------- # 03/08/31 geert@linux-m68k.org 1.1276.35.43 # [PATCH] macide (was: Re: Linux 2.6.0-test4) # # Bartlomiej Zolnierkiewicz: # > o ide: disk geometry/capacity cleanups # > o ide: always store disk capacity in u64 # # Forgot to update the Macintosh IDE driver: # -------------------------------------------- # 03/08/31 geert@linux-m68k.org 1.1276.35.44 # [PATCH] m68k asm/sections.h # # M68k: asm/sections.h just includes the generic version (from Roman Zippel) # -------------------------------------------- # 03/08/31 geert@linux-m68k.org 1.1276.35.45 # [PATCH] m68k asm/local.h # # M68k: asm/local.h just includes the generic version (from Roman Zippel) # -------------------------------------------- # 03/08/31 geert@linux-m68k.org 1.1276.35.46 # [PATCH] Amiga z2ram # # Amiga z2ram: Add missing includes and remove some unnecessary includes # -------------------------------------------- # 03/08/31 geert@linux-m68k.org 1.1276.35.47 # [PATCH] Amiga floppy # # Amiga floppy: Add missing includes and remove some unnecessary includes (from # Roman Zippel) # -------------------------------------------- # 03/08/31 geert@linux-m68k.org 1.1276.35.48 # [PATCH] M68k switch_to # # M68k: Set last in switch_to(), fix asm constraints (from Andreas Schwab) # -------------------------------------------- # 03/08/31 geert@linux-m68k.org 1.1276.35.49 # [PATCH] Atari floppy # # Atari floppy: Add missing includes and remove some unnecessary includes # -------------------------------------------- # 03/08/31 torvalds@home.osdl.org 1.1276.31.12 # Merge http://lia64.bkbits.net/to-linus-2.5 # into home.osdl.org:/home/torvalds/v2.5/linux # -------------------------------------------- # 03/08/31 stelian@popies.net 1.1276.31.13 # [PATCH] sonypi driver update # # This updates the sonypi driver to the latest version: # * document the fact that FX501/FX702 laptops are not supported # # * add battery insert/remove events (thanks to Daniel K.) # # * improve the event detection using a different port offset # on 'type2' models (thanks to Daniel K.) # -------------------------------------------- # 03/08/31 stelian@popies.net 1.1276.31.14 # [PATCH] meye driver update # # In order to bring the 2.4 and 2.6 versions in sync, here is the # missing bit for the meye driver :) # -------------------------------------------- # 03/08/31 ysato@users.sourceforge.jp 1.1276.31.15 # [PATCH] h8300 interrupt problem fix # # typo fixed. # -------------------------------------------- # 03/08/31 ysato@users.sourceforge.jp 1.1276.31.16 # [PATCH] h8300 include update # # o driver support headers update # o fix warnings # -------------------------------------------- # 03/08/31 miles@lsi.nec.co.jp 1.1276.31.17 # [PATCH] Give v850 its own version of the vmlinux.lds.h RODATA macro # # While it would be nice to keep using the generic version of RODATA, the # v850's linker-script structure is sufficiently different from that of # typical archs that it's not possible to use RODATA as it's currently # defined. I earlier suggested splitting the generic definition of RODATA # into `RODATA_CONTENTS' and `RODATA' (a wrapper around RODATA_CONTENTS) # where most archs would use RODATA, and the v850 would use # RODATA_CONTENTS, however Kai didn't like that idea. # # It _may_ be possible to rewrite the v850's linker scripts into something # more typical (using lots of individual output sections), but it doesn't # seem at all straightforward, so I don't have the time to do it right # now. # # Anyway, this is the short-term work-around so that Linus's kernel works # on the v850. # -------------------------------------------- # 03/08/31 miles@lsi.nec.co.jp 1.1276.31.18 # [PATCH] Properly export symbols that depend on CONFIG_MMU # -------------------------------------------- # 03/08/31 torvalds@home.osdl.org 1.1276.29.10 # Merge pmac IDE changes # -------------------------------------------- # 03/08/31 torvalds@home.osdl.org 1.1276.29.11 # Merge bk://kernel.bkbits.net/jgarzik/net-drivers-2.6 # into home.osdl.org:/home/torvalds/v2.5/linux # -------------------------------------------- # 03/08/31 torvalds@home.osdl.org 1.1288 # Merge bk://linux-dj.bkbits.net/agpgart # into home.osdl.org:/home/torvalds/v2.5/linux # -------------------------------------------- # 03/08/31 torvalds@home.osdl.org 1.1289 # Merge # -------------------------------------------- # 03/08/31 levon@movementarian.org 1.1290 # [PATCH] OProfile: correct CPU type for x86-64 # # Enable the Hammer specific events by giving the correct cpu string. # From, and tested by, Will Cohen. # -------------------------------------------- # 03/08/31 vinay-rc@naturesoft.net 1.1291 # [PATCH] pcmciamtd.c: remove release timer # # This patch removes the PCMCIA timer release functionality which is no # longer required (or supported). # -------------------------------------------- # 03/08/31 acme@conectiva.com.br 1.1292 # [PATCH] cyc2x: sanitize ioremap usage & more # # I wrote this driver a long time ago, and now, playing with my # brand new PARISC machine I found these problems, could you please apply # this patch? # # Ah, the "& more" refers to some alignment problems also solved # in this patch. # -------------------------------------------- # 03/08/31 krishnakumar@naturesoft.net 1.1293 # [PATCH] Remaining task queue to work queue conversion. # # Somewhere in the transition of task queue to the work queue, in # stallion.c, some of the schedule_task were left out from being converted # to schedule_work. This fixes it. # -------------------------------------------- # 03/08/31 guillaume@morinfr.org 1.1294 # [PATCH] fix cu3088 group write # # The current cu3088 ccwgroup write code overwrite the last char of the # given arguments. This fixes the problem. It is been tested and applies # on latest bk. # -------------------------------------------- # 03/08/31 herbert@gondor.apana.org.au 1.1295 # [PATCH] free_netdev typo # # The free_netdev fixes in 2.6.0-test4 broke drivers/net/wan/cosa.c. # This fixes it. # -------------------------------------------- # 03/08/31 torvalds@home.osdl.org 1.1296 # Merge bk://bk.arm.linux.org.uk/linux-2.6-rmk # into home.osdl.org:/home/torvalds/v2.5/linux # -------------------------------------------- # 03/08/31 jgarzik@redhat.com 1.1295.1.1 # [netdrvr 8139cp] PCI MWI cleanup; remove unneeded workaround # # * The PCI layer now handles incorrect cacheline size settings, # as it should. Remove our own workarounds. # * Move pci_set_mwi up much earlier in the probe process, # and check its return value. # * Call pci_clear_mwi() in ->probe error handling # * Call pci_clear_mwi() in ->remove # -------------------------------------------- # 03/08/31 neilb@cse.unsw.edu.au 1.1297 # [PATCH] Fix compile errors in NFSv4 server # -------------------------------------------- # 03/08/31 akpm@osdl.org 1.1298 # [PATCH] .config checks updated # # From: Sam Ravnborg # # When building a kernel right after 'make mrproper' resulted in a very short # run, and no sign that .config was missing. This has been fixed by adding a # new rule for .config in the top-level Makefile, and a new target # 'silentoldconfig' in scripts/kconfig/Makefile. # # Cleaned up a bit in scripts/kconfig/Makefile # -------------------------------------------- # 03/08/31 akpm@osdl.org 1.1299 # [PATCH] random: SMP locking # # From: Oliver Xymoron # # This patch adds locking for SMP. Apparently Willy never managed to # revive his laptop with his version so I revived mine. # # The batch pool is copied as a block to avoid long lock hold times # while mixing it into the primary pool. # # Two locks are added: # # gobal batch_lock # batch_entropy_store can be called from any context, and typically from # interrupts -> spin_lock_irqsave # # batch_entropy_process is called called via schedule_delayed_work and # runs in process context -> spin_lock_irq # # entropy_store.lock # the mixing process is too expensive to be called from an interrupt # context and the basic worker function extract_entropy can sleep, so # all this stuff can be under a normal spin_lock # -------------------------------------------- # 03/08/31 akpm@osdl.org 1.1300 # [PATCH] random: accounting and sleeping fixes # # From: Oliver Xymoron # # This fixes several calculation errors and races in entropy accounting # that would allow /dev/random output to greatly exceed the measured # entropy collection. This doesn't include any of my more controversial # hardening, it just makes it behave as intended. # # It also corrects the operation of the 'catastrophic reseeding' feature # so that it will actually prevent the state extension attack it's meant # to guard against. # # And finally, it also fixes a couple missed wake-up and accidental # sleep bugs uncovered by the above fixes. # # Debug instrumentation has been improved to help verify correctness. # -------------------------------------------- # 03/08/31 akpm@osdl.org 1.1301 # [PATCH] disable prefetch on athlons # # K7's (at least) are faulting in the prefetch instruction. The AMD # engineers have said they will be getting back to us on it, and the fix is # looking complex, and nobody seems to be standing up to work on it. # # So hum. The usual manifestation is an oops in hlist_for_each(), down in # the VFS inode lookup code. Disrupting our testers in this way is very bad, # so this patch just disables prefetch on all AMD parts in a rather stupid # way. # -------------------------------------------- # 03/08/31 akpm@osdl.org 1.1302 # [PATCH] fix /proc/pid/fd ownership across setuid() # # From: "B. D. Elliott" # # There's a bug: # # - Someone reads a (say) root-owned process's /proc/pid/fd directory # # The inodes are instantiated owned by root. # # - That process does a setuid # # - The /proc/pid/* files still have the old ownerships. # # This happened because we are now caching the proc entries. # # The patch rewrites the ownership of the inodes under /proc/pid in the # d_revalidate() handler. # -------------------------------------------- # 03/08/31 akpm@osdl.org 1.1303 # [PATCH] Call security hook from pid*_revalidate # # From: Stephen Smalley # # This patch against 2.6.0-test3-mm3 adds calls to the security_task_to_inode # hook to the pid*_revalidate functions to ensure that the inode security field # is also updated appropriately for /proc/pid inodes. This corresponds with # the uid/gid update performed by the proc-pid-setuid-ownership-fix.patch that # is already in -mm3. # -------------------------------------------- # 03/08/31 akpm@osdl.org 1.1304 # [PATCH] move DAC960 GAM IOCTLs into a new device # # From: Dave Olien # # The DAC960 driver uses an ugly overloading of the O_NONBLOCK flag to # support the controller's RAID configuration features. # # Opening "/dev/rd/c0d0" with the O_NONBLOCK flag set returns a file # descriptor that can be used to do RAID control operations using ioctl(). # The normal ioctl operations are not availabe with that file descriptor. # # This patch removes that O_NONBLOCK overloading from DAC960_open() and # DAC960_ioctl() functions. It introduces a new "miscellaneous" device # named /dev/dac960_gam. It uses minor device number 252 of the miscellaneous # character devices. # # The currently distrubted "Global Array Manager" server distrubted by # LSIlogic on their web page page works only on RH7.3 or earlier. It doesn't # work under RH9. There are probably some library incompatabilities. # So, I don't view this patch as breaking anything that currently works. # If this software package is ever brought up to date (which I doubt), # then it can be modified to use this new device at that time. # -------------------------------------------- # 03/08/31 akpm@osdl.org 1.1305 # [PATCH] Add the kernel janitors to MAINTAINERS # # From: "Randy.Dunlap" # # Add the Kernel Janitors project to MAINTAINERS. # # Probably the trivial patch monkey should be there too. # -------------------------------------------- # 03/08/31 jgarzik@redhat.com 1.1297.1.1 # Merge bk://kernel.bkbits.net/jgarzik/net-drivers-2.6 # into redhat.com:/spare/repo/net-drivers-2.5 # -------------------------------------------- # 03/08/31 akpm@osdl.org 1.1306 # [PATCH] Update ide.txt documentation to current ide.c # # From: Maciej Soltysiak # # this patches updates Documentation/ide.txt to reflect more options that # really are supported by the IDE driver (drivers/ide.c) # -------------------------------------------- # 03/08/31 akpm@osdl.org 1.1307 # [PATCH] v4l use-after-free fix # # From: Greg KH # # When working on converting the usb v4l drivers to the new v4l class # changes, I ran into this nasty bug. Seems that the core was using a # structure after it had been freed. The patch below fixes it. # -------------------------------------------- # 03/08/31 akpm@osdl.org 1.1308 # [PATCH] ikconfig - Makefile update # # From: "Randy.Dunlap" # # Please merge this makefile update from Sam. # From: Sam Ravnborg # # Remark, I removed dependencies for configs.o - the are generated by kbuild # anyway. Only generated files needs explicit dependencies. # -------------------------------------------- # 03/08/31 akpm@osdl.org 1.1309 # [PATCH] Fix ftape warning # # From: Chris Heath # # Here's a patch which fixes this warning: # # drivers/char/ftape/lowlevel/fdc-io.c: In function `ftape_interrupt': # drivers/char/ftape/lowlevel/fdc-io.c:1299: warning: unused variable `_tracing' # -------------------------------------------- # 03/08/31 akpm@osdl.org 1.1310 # [PATCH] jffs aops return type fix # # From: "Randy.Dunlap" # # prepare_write() and commit_write() return `int'. # # Fixes an ia64 compile warning. # -------------------------------------------- # 03/08/31 akpm@osdl.org 1.1311 # [PATCH] Add 3GB personality # # From: Andi Kleen # # Another a bit ugly but necessary patch for 32bit emulation. # # Some applications including some versions of java break when the stack is # beyond the i386 standard 3GB boundary. For these add a 3GB personality # that moves the stack to 3GB and fixes the beginning of the mmap area. It's # a bit ugly, but better than not running these applications at all (e.g. # the Oracle installer depends on such a buggy java :-(). It's also not only # Java, but some other programs as well. # -------------------------------------------- # 03/08/31 akpm@osdl.org 1.1312 # [PATCH] zeromap_pmd_range bugfix # # From: Benjamin Herrenschmidt # # The patch below fixes a 2.6 mm problem. Without this patch, zeromapped # pages are not flushed properly when they are swapped out. # # What happens is that the page->index field is zero for page table pages # corresponding to the zeromapped range. This causes ptep_to_address() to # return an incorrect virtual address with the result that PTEs are never # invalidated at swap-out... # # The fix below mirrors the remap_pmd_range() case. # -------------------------------------------- # 03/08/31 akpm@osdl.org 1.1313 # [PATCH] don't report async write errors on close() after all # # I had second thoughts on this. # # Reporting background writeout errors via close() only really makes sense if # allthe IO has completed anyway: ie, the app has had the fd open without # writing to it for many tens of seconds. # # It would be OK if it was harmless, but it is not. Changes are, applications # ignore errors from close(). So if an application does a fork/exit and the # child correctly does an fsync() of the fd, the close-on-exit will have wiped # out any accumulated EIO/ENOSPC errors. # # Or if someone does dup()/close()/fsync(), the fsync() could fail to detect # earlier errors, thanks to the close. # # # So. The clear-and-report of errors on close() makes the reporting of errors # on fsync/msync/fdatasync less reliable. # -------------------------------------------- # 03/08/31 akpm@osdl.org 1.1314 # [PATCH] remove add_wait_queue_cond() # # It has no callers, is using the non-existent spin_lock_irqrestore(), and is # obviously very untested. Kill. # -------------------------------------------- # 03/08/31 akpm@osdl.org 1.1315 # [PATCH] spin_lock_irqrestore() typo fixes # # From: Vinay K Nallamothu # # s/spin_lock_irqrestore/spin_unlock_irqrestore/ # -------------------------------------------- # 03/08/31 akpm@osdl.org 1.1316 # [PATCH] zoran: memleak fixes # # From: Ronald Bultje # # This patch fixes several memleaks in error cases when the setup of i2c # client drivers for video encoders/decoders fails. We forgot to free some # memory in various places. This was noticed by Francois Romieu. # -------------------------------------------- # 03/08/31 akpm@osdl.org 1.1317 # [PATCH] zoran: debug->zr_debug # # From: Ronald Bultje # # This patch renames the debug symbol to zr_debug because debug is already # defined somewhere else. Without it, it will cause a symbol conflict when # compiling this driver statically into the kernel. This was noticed by # several people, including Linus himself. # -------------------------------------------- # 03/08/31 akpm@osdl.org 1.1318 # [PATCH] zoran: add release callback # # From: Ronald Bultje # # This patch adds a release callback which frees the video_device struct. # This is needed to prevent freeing memory before it's not in use anymore, # as described in http://lwn.net/Articles/36850/. Without this, the driver # will give a warning when loaded. It might crash when unloading (see # article), too. The video4linux patch (by Gerd Knorr) was accepted a week # (or 2?) ago, but I forgot to adapt my driver to it. # -------------------------------------------- # 03/08/31 akpm@osdl.org 1.1319 # [PATCH] zoran: add pci_disable_device() call # # From: Ronald Bultje # # This patch adds pci_disable_device() to the card release function; we # already used pci_enable_device() in the card detection function. This was # noticed by Francois Romieu. # -------------------------------------------- # 03/08/31 akpm@osdl.org 1.1320 # [PATCH] zoran: cleanups # # From: Ronald Bultje # # This patch changes some funky coding style (a.k.a. indent artifact) in # the function zoran_irq() to a somewhat more conservative coding style. # It was noticed by Francois Romieu. # -------------------------------------------- # 03/08/31 akpm@osdl.org 1.1321 # [PATCH] zoran: more cleanups # # From: Ronald Bultje # # This patch adds some newlines between variable declarations and function # bodies. This was done on request by Francois Romieu. # -------------------------------------------- # 03/08/31 akpm@osdl.org 1.1322 # [PATCH] zoran: correct name field breakage # # From: Ronald Bultje # # I suddenly noticed that 2.6.0-test4 seems to have removed the struct # device->name field, apparently for memory consumption reasons. Linus # changed this to pci_name((zr)->pci_dev) in my driver, and that's almost # correct, except that it is the PCI device ID, and I'm not supposed to # touch it. Also, since it's only 4 bytes, all my device names now show # like 'DC1' (this should be 'DC10plus') and alike. # # The attached patch fixes this by going back to the behaviour that we # used in 2.4.x: we use a separate name field in our private driver # struct. # -------------------------------------------- # 03/08/31 akpm@osdl.org 1.1323 # [PATCH] airo CONFIG_PCI=n build fix # # From: Geert Uytterhoeven # # On Fri, 22 Aug 2003, Linus Torvalds wrote: # > Javier Achirica: # > o [wireless airo] Fix PCI unregister code # # This patch causes a regression: if CONFIG_PCI is not set, it doesn't compile # anymore. Here's a fix. I also killed a dead variable and its corresponding # warning: # -------------------------------------------- # 03/08/31 akpm@osdl.org 1.1324 # [PATCH] drivers/char/pcxx.c warning fix # # From: "Krishnakumar. R" # # This patch removes the warning: # # drivers/char/pcxx.c:124:8: warning: extra tokens at end of #endif directive # -------------------------------------------- # 03/08/31 akpm@osdl.org 1.1325 # [PATCH] pcnet32 needs unregister_pci # # From: Domen Puncer # # The problem in pcnet32 is, that it doesn't unregister pci, if there's no # hardware. # # This patch solves the problem. # -------------------------------------------- # 03/08/31 akpm@osdl.org 1.1326 # [PATCH] c99 struct initialiser conversions # # From: CaT # # Convert a whole bunch of struct initialisers into c99 format. # -------------------------------------------- # 03/08/31 akpm@osdl.org 1.1327 # [PATCH] Fix 'pci=noacpi' with buggy ACPI BIOSes # # From: Thomas Schlichter # # Make the `pci=noacpi' command line option work correctly. It fixes # interrupt routing probems for (at least 3) people with broken ACPI BIOSes. # -------------------------------------------- # 03/08/31 akpm@osdl.org 1.1328 # [PATCH] /proc/kallsym caching fix # # From: Rusty Russell # # Out by one error broke caching of results in /proc/kallsyms, slowing # reading to a crawl. # -------------------------------------------- # 03/08/31 akpm@osdl.org 1.1329 # [PATCH] Fix permissions on /proc/kallsyms # # From: Rusty Russell # # Change the permissions on /proc/kallsyms. As David M-T points out, # it's nice for analysis tools not to need root. Place # cond_resched() to avoid starvation problems on non-preempt. # -------------------------------------------- # 03/08/31 akpm@osdl.org 1.1330 # [PATCH] Kobject doc addition # # From: # # Here's an _important_ kobject doc patch. # -------------------------------------------- # 03/08/31 akpm@osdl.org 1.1331 # [PATCH] vm_enough_memory microoptimisation # # From: # # The expected case is (sysctl_overcommit_memory == 0), so put that first. # -------------------------------------------- # 03/08/31 akpm@osdl.org 1.1332 # [PATCH] abi doc update # # From: # # Update the abi sysctl documentation. # -------------------------------------------- # 03/08/31 akpm@osdl.org 1.1333 # [PATCH] ni5010.c: remove cli/sti # # From: Vinay K Nallamothu # # drivers/net/ni5010.c: # This patch replaces cli/sti with spinlocks. Compiles fine though # untested. # -------------------------------------------- # 03/08/31 akpm@osdl.org 1.1334 # [PATCH] do_no_page() fix # # From: David Mosberger , # "Sharma, Arun" # # The truncate race fix assumed that a non-zero vma->vm_ops->nopage implies a # non-zero vma->vm_file. # # The ia64 x86 emulation code breaks this assumption, so teach do_no_page() to # handle it. # -------------------------------------------- # 03/08/31 akpm@osdl.org 1.1335 # [PATCH] parport_pc rmmod oops fix # # The `user_specified' variable is used in cleanup_module() and hence cannot be # dropped from memory after module initialisation. # -------------------------------------------- # 03/08/31 akpm@osdl.org 1.1336 # [PATCH] reiserfs writepage-versus-truncate fix # # From: Oleg Drokin # # The conversion of reiserfs to not return errors from # writepage-outside-i_size was incorrect. Fix. # -------------------------------------------- # 03/08/31 akpm@osdl.org 1.1337 # [PATCH] visws: fix 2.6.0-test4 breakage # # From: Andrey Panin # # attached trivial patch fixes visws subarch kernel build. It was broken by # 2.6.0-test4 cpumask_t changes. # -------------------------------------------- # 03/08/31 akpm@osdl.org 1.1338 # [PATCH] Fix ext3 htree corruption on big-endian platforms # # From: Franz Sirl # # current bk 2.6.0 corrupts my ext3 filesystems, usually in the RESYNC dir # during a bk pull. Checking the recent changes I noticed that the one in # fs/ext3/namei.c misses an endian conversion. The attached patch fixes that # and works fine for me since 2 days now on PPC. # -------------------------------------------- # 03/08/31 akpm@osdl.org 1.1339 # [PATCH] Fix selinux_file_fcntl # # From: Stephen Smalley , James Morris # # This patch adds the appropriate #if around the F_*64 commands in the # selinux_file_fcntl hook function. # -------------------------------------------- # 03/08/31 akpm@osdl.org 1.1340 # [PATCH] Fix SELinux avtab # # From: Stephen Smalley , Arnd Bergmann # # This patch changes the SELinux avtab to use vmalloc/vfree; the table is too # large for kmalloc on s390. # -------------------------------------------- # 03/08/31 akpm@osdl.org 1.1341 # [PATCH] Fix SELinux format specifiers # # From: Stephen Smalley , James Morris # # This patch corrects several format specifiers in the SELinux security server # code. # -------------------------------------------- # 03/08/31 akpm@osdl.org 1.1342 # [PATCH] Rework SELinux binprm hooks # # From: Stephen Smalley # # This patch reworks the SELinux binprm hook functions to use a security # structure for the linux_binprm rather than directly stuffing the security # identifier into the void* security field. It also performs some cleanup of # the SELinux binprm hook functions, and one miscellaneous fix. # -------------------------------------------- # 03/08/31 akpm@osdl.org 1.1343 # [PATCH] Fix typo in #ifdef for ext2 xattr support # # From: Stephen Smalley # # This patch corrects a typo in an ifdef that enables xattr operations for # special files in the ext2 code; otherwise, extended attributes cannot be # obtained or set on such inodes. # -------------------------------------------- # 03/08/31 akpm@osdl.org 1.1344 # [PATCH] Add more bad_inode operations # # From: # # Flesh out the bad_inode file and inode operations tables with new # additions. # -------------------------------------------- # 03/08/31 akpm@osdl.org 1.1345 # [PATCH] Fix build with CONFIG_KCORE_AOUT # # We get a linkage error with CONFIG_KCORE_AOUT because there is no # implementation of kclist_add() and kclist_del(). # # Also fix a warning in the a.out version of read_kcore(). # # Maybe we should just remove kcore a.out support. m68knommu and h8300 are # setting CONFIG_KCORE_AOUT in their defconfigs though. # -------------------------------------------- # 03/08/31 akpm@osdl.org 1.1346 # [PATCH] kill CONFIG_KCORE_AOUT # # From: Adrian Bunk # # Remove CONFIG_KCORE_AOUT: the ability to present /proc/kcore in a.out # format. # # I've checked with various arch maintainers. It won't be missed. # -------------------------------------------- # 03/08/31 akpm@osdl.org 1.1347 # [PATCH] knfsd nfs4 warning fixes # -------------------------------------------- # 03/08/31 akpm@osdl.org 1.1348 # [PATCH] Fix bluetooth compile warnings # -------------------------------------------- # 03/08/31 akpm@osdl.org 1.1349 # [PATCH] do_no_page() rss accounting fix # # From: Jaroslav Kysela # # The do_no_page() function in mm/memory.c does accounting for reserved pages # (++mm->rss), but in zap_pte_range() we don't decrement rss if the page was # reserved. # # So don't account for PageReserved pages in the rss. (Maybe it would be # better to fix zap_pte_range in the opposite direction..) # -------------------------------------------- # 03/08/31 akpm@osdl.org 1.1350 # [PATCH] jbd: remove uninformative printk # # This printk doesn't impart any information. # -------------------------------------------- # 03/08/31 akpm@osdl.org 1.1351 # [PATCH] acpi pci_link fix # # From: Christophe Saout # # - acpi_pci_link_get_irq() returns 0 on error, not -ENODEV. # # - Fix mpparse.c tpyo. # -------------------------------------------- # 03/08/31 akpm@osdl.org 1.1352 # [PATCH] add context switch counters # # From: Peter Chubb # # Currently, the context switch counters reported by getrusage() are # always zero. The appended patch adds fields to struct task_struct to # count context switches, and adds code to do the counting. # # The patch adds 4 longs to struct task struct, and a single addition to # the fast path in schedule(). # -------------------------------------------- # 03/08/31 akpm@osdl.org 1.1353 # [PATCH] remove size_t-based printk warnings # # From: "Randy.Dunlap" # # This patch removes warnings on non-matching parameter types to printk # and incorrect function types (n_hdlc). # -------------------------------------------- # 03/08/31 akpm@osdl.org 1.1354 # [PATCH] large dev_t 12/12 oops fix # # From: viro@parcelfarce.linux.theplanet.co.uk # # On Wed, Aug 27, 2003 at 01:46:37AM -0700, Andrew Morton wrote: # > # > LILO seems to be oopsing in HDIO_GETGEO ioctl for some reason, in # > generic_ide_ioctl(). # > # > I'm not sure quite why though. Could one of your patches affected this # > area? # # The last one (fix for hd_struct handling). The fix follows: # -------------------------------------------- # 03/08/31 akpm@osdl.org 1.1355 # [PATCH] evdev_ioctl does not report EV_MSC capabilities # # From: Dmitry Torokhov # # While working on my GPM patches found out that EV_MSC was forgotten... # -------------------------------------------- # 03/08/31 akpm@osdl.org 1.1356 # [PATCH] AS: don't anticipate against a task's initial I/O # # From: Nick Piggin # # In the anticipatory scheduler, don't anticipate against the very first IO # request which a process issues. # # This solves a very specific problem wherein a process starts, submits a # single IO then exits. # -------------------------------------------- # 03/08/31 akpm@osdl.org 1.1357 # [PATCH] hch has moved # # From: Christoph Hellwig # # I moved a while ago and I'm also not at SGI anymore. # -------------------------------------------- # 03/08/31 akpm@osdl.org 1.1358 # [PATCH] Cyclades ISA serial driver fix # # From: "John Stoffel" # # Quick patch to get my 8 port Cyclades Cyclom-Y ISA card to work. # # (It doesn't look to be very SMP-robust, but then the 2.4 dirver probably # isn't either). # -------------------------------------------- # 03/08/31 akpm@osdl.org 1.1359 # [PATCH] kbuild: warn if the user has old modutils # # From: Valdis.Kletnieks@vt.edu, Sam Ravnborg # # Adds an explicit check for the new modutils in the build system. # # Generally we should avoid these sorts of hardwired checks for the right # versions of things, but we are still getting a significant number of problem # reports due to people not having the new tools. Let's help them out. # -------------------------------------------- # 03/08/31 akpm@osdl.org 1.1360 # [PATCH] fix arcnet printk parameter types # # From: "Randy.Dunlap" # # fix arcnet printk parameter types # -------------------------------------------- # 03/08/31 akpm@osdl.org 1.1361 # [PATCH] floppy driver cleanup # # From: "Randy.Dunlap" # # - use kernel.h min() and max(); # # - C99 initializers; # # - Tidy up the scheule_work() callbacks (none of them take an arg) # -------------------------------------------- # 03/08/31 akpm@osdl.org 1.1362 # [PATCH] Use tgid rather than pid in dnotify # # From: Ulrich Drepper # # I'm not entirely sure about this change. But it seems to be necessary. # The dnotify code stores the PID in the file structure. The entire process # shares the file and any signal (is it used for that?) should be sent to the # process (thread group), not the individual thread. Also keep in mind that # threads can go away while the process (and therefore file descriptor) # remain. And the ID of the thread can be reused. # # Somebody who knows this code should take a good look. # # (Looks right to me...) # -------------------------------------------- # 03/08/31 akpm@osdl.org 1.1363 # [PATCH] Fix a few declarations # # extern decls in .c files are evil. Put the send_sigio(), fcntl_setlease() # and fcntl_getlease() into fs.h. # -------------------------------------------- # 03/08/31 akpm@osdl.org 1.1364 # [PATCH] make voyager work again after the cpumask_t changes # # From: James Bottomley # # Most is just simple fixes; however, the needless change from atomic to # non-atomic operations in smp_invalidate_interrupt() caused me a lot of # pain to track down since it introduced some very subtle bugs. # # I've also taken phys_cpu_present_map out of smp.h. Since it # physid_mask_t is defined in mpspec.h anyway, and contains a duplicate # definition, I don't believe it can hurt anything. # -------------------------------------------- # 03/08/31 akpm@osdl.org 1.1365 # [PATCH] mtrr cleanups # # - Remove duplicated implementation of attrib_to_str() # # - Make mtrr_strings[] static to if.c # -------------------------------------------- # 03/08/31 akpm@osdl.org 1.1366 # [PATCH] compat ioctl_table fix # # The arch ioctl tables are doing this: # # struct foo ioctl_start[] = { # ... # }; # struct foo ioctl_end[0]; # # and fs/compat.c expects that the table lies between &ioctl_end and # &ioctl_start. # # Problem is, gcc-3.3 puts ioctl_end into bss, even if it is initialised. It # doesn't work. # # So we do away with the ioctl_end thing and add # # int ioctl_table_length = ARRAY_SIZE(ioctl_start); # # to each architecture. # -------------------------------------------- # 03/08/31 akpm@osdl.org 1.1367 # [PATCH] raw driver oops fix # # From: Dave Olien # # The raw.c character device Oopses dereferencing a NULL pointer in # bd_claim() This problem occurred after bd_claim() in block_dev.c was # modified to "claim the whole device when a partition is claimed". # # raw_open() made the mistake of calling bd_claim BEFORE calling blkdev_get(). # At that time, the bdev->bd_contains field has not yet been initialized. # Switching the order allows blkdev_get() to initialize those fields before # calling bd_claim(). # # Also fixed up some error return paths: # # igrab() should never fail under these circumstances since the caller # already has a reference to that inode through the bdev at that time. # # In the event of blkdev_get() failure or set_blocksize() failure, not all # the work to unwind from the error was done. # -------------------------------------------- # 03/08/31 akpm@osdl.org 1.1368 # [PATCH] ipc_init() uses vmalloc too early # # From: Andrea Arcangeli # # aka: "vmalloc allocations in ipc needs smp initialized (and vm must be # allowed to schedule in 2.6)" # # In short if you change SEMMNI to 8192 the kernel will crash at boot, beause # it tries to call vmalloc before the smp is initialized. The reason is that # vmalloc calls into the pte alloc code, and the fast pte alloc is tried # first, but that reads into the pte_quicklist, that requires the cpu_data to # be initialized (and that happens in smp_init()). # # the patch is obviously safe, since no piece of kernel (especially the code # in the check_bugs and smp_init paths ;) calls into the ipc subsystem. # # The reason this started to trigger wasn't really that we increased SEMMNI, # but what happend is that some IPC data structure grown, and for some reason # the corruption due the uninitalized pte_quicklist triggers only for smp # boxes with less than 1G (not very common anymore ;). So it wasn't # immediatly reproducible on all setups. # # 2.6 doesn't suffer from the same problem, simply because 2.6 isn't using # the quicklist anymore, but I think it would be much more correct to make # the same change in 2.6 too, since whatever cond_resched() in the vm paths # (and they're definitely allowed to call it), will lead to a crash since the # init task isn't initialized and the scheduler can't be invoked yet. (and # 2.6 already has the bigger data structures that should trigger the vmalloc # all the time on all setups) # -------------------------------------------- # 03/08/31 akpm@osdl.org 1.1369 # [PATCH] vmscan: zone pressure calculation fix # # Off-by-one in balance_pgdat(): `priority' can never go negative. It causes # the scanning priority thresholds to be quite wrong and kswapd tends to go # berzerk when there is a lot of mapped memory around. # -------------------------------------------- # 03/08/31 akpm@osdl.org 1.1370 # [PATCH] vmscan: zone pressure simplification and fix # # The zone->pressure field is supposed to record the amount of reclaim pressure # which this zone is under. We need this info so we know whether to unmap # pages from pagetables right from the outset of a balance_pgdat() or # try_to_free_pages() invokation. # # The problem with the current code is that the exponential average gets tugged # around too much: as we perform the increasing-priority scan, the pressure # metric is made artificially low by the early part of the scan. # # So instead what we do here is to record within the zone the scanning priority # from the zone's previous scan. It is defined as the priority at which the # zone achieved the "enough pages free" state. This prev_priority is used on # the next scan for the do-we-need-to-be-unmapping-pages decision. # -------------------------------------------- # 03/08/31 akpm@osdl.org 1.1371 # [PATCH] Remove SSE2 bugs.h check # # From: Andi Kleen # # Remove some dead code. # # CONFIG_SSE2 hasn't been defined for some time, because everything # SSE related is handled at runtime based on cpuid. # -------------------------------------------- # 03/08/31 akpm@osdl.org 1.1372 # [PATCH] HPET 1/6: Support for HPET based timer # # From: "Pallipadi, Venkatesh" # # High Precision Event Timer (HPET) is next generation timer # hardware and has various advantages over legacy 8254 # (PIT) timer, like: # - Associated registers are mapped to memory space. So, we no # longer require in and out on legacy ioports # - Memory map address is reported by ACPI (and are not # hard-coded) # - Each timer can be configured to generate separate interrupts, # even sharing lines with PCI devices # - HPET has a minimum period of 100 nanosecs and is not fixed. # Giving a flexibility of increasing the resolution in future. # - Most current implementations has 3 counters, but in future, # we can have as many as 32 timers per block, and 8 # HPET timer blocks (total 256 timers) # - Can support 32bit and 64bit counting # # (Refer to http://www.intel.com/labs/platcomp/hpet/hpetspec.htm # for complete specs) # # The patchset that follow adds support for High Precision Event # Timer (HPET) based timer in kernel. This uses the HPET in # LegacyReplacement mode (so that counter 0 will be tied to IRQ0, # and counter 1 will be tied to IRQ 8). In this mode, HPET overrides # PIT and RTC interrupt lines. The patch will enable HPET by default, # on systems where ACPI tables reports this feature. The patch will # have no impact on systems that do not support this feature. # # # # # A major change from previous version is elimination of fixmap for HPET. # Based on Andrew Morton's suggestion, we have a new hook in init/main.c for # late_time_init(), at which time we can use ioremap, in place of fixmap. # Impact on other archs: Calibrate_delay() (and hence loops_per_jiffy # calculation) has moved down in main.c, from after time_init() to after # kmem_cache_init(). # # 1/6 - hpet1.patch - main.c change to introduce late_time_init() # -------------------------------------------- # 03/08/31 akpm@osdl.org 1.1373 # [PATCH] HPET 3/6: makefile and config changes # # From: "Pallipadi, Venkatesh" # # Miscallaneous makefile and config changes # -------------------------------------------- # 03/08/31 akpm@osdl.org 1.1374 # [PATCH] HPET 4/6: Core # # From: "Pallipadi, Venkatesh" # # All the changes required to use HPET in place of PIT as the kernel base-timer # at IRQ 0. # -------------------------------------------- # 03/08/31 akpm@osdl.org 1.1375 # [PATCH] HPET 5/6: timer services # # From: "Pallipadi, Venkatesh" # # All changes required to support timer services (gettimeofday) with HPET. # -------------------------------------------- # 03/08/31 akpm@osdl.org 1.1376 # [PATCH] HPET 6/6: rtc emulation # # From: "Pallipadi, Venkatesh" # # This can be a standalone patch. With this patch we basically try to emulate # RTC interrupt functions in software using HPET counter 1. # -------------------------------------------- # 03/08/31 akpm@osdl.org 1.1377 # [PATCH] HPET 2/6: boot parsing # # From: "Pallipadi, Venkatesh" # # acpi boot time parsing changes to look for HPET # -------------------------------------------- # 03/08/31 akpm@osdl.org 1.1378 # [PATCH] fix advansys.c if !CONFIG_PROC_FS # # From: Adrian Bunk # # The patch below fixes a compile error in drivers/scsi/advansys.c if # !CONFIG_PROC_FS. # -------------------------------------------- # 03/08/31 akpm@osdl.org 1.1379 # [PATCH] handle setup_swap_extents() error in swapon. # # From: Hugh Dickins # # It's good that swapon fails on a tmpfs file ("swapfile has holes"), but not # good that it then hangs up: note error from setup_swap_extents. # -------------------------------------------- # 03/08/31 akpm@osdl.org 1.1380 # [PATCH] scsi_unregister() oops fix # # Some drivers such as aha1542 and aic7xxx_old will call scsi_register() and # then, if some succeeding operations fails they will call scsi_unregister(), # without an intervening scsi_set_host(). # # This causes an oops in scsi_put_device(), because kobj->parent is NULL. # # In other words, scsi_register() immediately followed by scsi_unregister() # is guaranteed to oops. # # The patch makes scsi_host_dev_release() more robust against this usage # pattern. # -------------------------------------------- # 03/08/31 akpm@osdl.org 1.1381 # [PATCH] tty oops fix # # Ancient bug, reported by Hiroshi Inoue : # # 1. login to tty2 (not tty1) # 2. start kon (Kanji cONsole emulator, console which support # Japanese characters) # 3. exit kon # 4. logout # # It oopses in the debugging function check_tty_count(), walking a list_head # which has been list_del()'d. Call trace is: # # #0 check_tty_count (tty=0x10d42000, routine=0xc817b00 ".paths") at include/asm/processor.h:583 # #1 0x022c6c00 in do_tty_hangup (data=0x10d42000) at drivers/char/tty_io.c:426 # #2 0x022c6f60 in tty_vhangup (tty=0xc817b00) at drivers/char/tty_io.c:536 # #3 0x022c6fcc in disassociate_ctty (on_exit=1) at drivers/char/tty_io.c:574 # #4 0x02127aee in do_exit (code=0) at kernel/exit.c:718 # #5 0x02127caa in do_group_exit (exit_code=0) at kernel/exit.c:796 # #6 0x02127cbc in sys_exit_group (error_code=0) at kernel/exit.c:807 # # The tty refcount is zero, so everything seems consistent and sensible. The # fix just uses list_del_init() on that list_head. # # # Heaven knows what the locking for tty->count is though. Some bizarre mixture # of BKL, tty_sem and nothing at all. # -------------------------------------------- # 03/08/31 akpm@osdl.org 1.1382 # [PATCH] ext3_setxattr() oops fix # # If journal_start() fails it returns an ERR_PTR. Best not pass that into # journal_stop(). # -------------------------------------------- # 03/08/31 akpm@osdl.org 1.1383 # [PATCH] Add documentation for /proc/stat # # From: "Bryan O'Sullivan" # # This patch adds documentation for the contents of the /proc/stat file. # -------------------------------------------- # 03/08/31 davem@nuts.ninka.net 1.1384 # Merge # -------------------------------------------- # 03/08/31 davem@nuts.ninka.net 1.1383.1.1 # Merge nuts.ninka.net:/home/davem/src/BK/sparc-2.5 # into nuts.ninka.net:/disk1/davem/BK/sparc-2.5 # -------------------------------------------- # 03/08/31 davem@nuts.ninka.net 1.1383.2.1 # Merge nuts.ninka.net:/home/davem/src/BK/tg3-2.5 # into nuts.ninka.net:/disk1/davem/BK/tg3-2.5 # -------------------------------------------- # 03/09/01 davem@nuts.ninka.net 1.1383.1.2 # [SPARC]: Mark get_rtc_time() static in SBUS rtc driver. # -------------------------------------------- # 03/09/01 xose@wanadoo.es 1.1385 # [TG3]: ICH2 needs MBOX write reorder bug workaround too. # -------------------------------------------- # 03/09/01 herbert@gondor.apana.org.au 1.1386 # [NET]: Add MODULE_LICENSE to xfrm_user.c # -------------------------------------------- # 03/09/01 hch@lst.de 1.1387 # [IPV6]: Use per-cpu data for icmp sockets. # -------------------------------------------- # 03/09/01 hch@lst.de 1.1388 # [NET]: Convert netdev_rx_stat to per-cpu data. # -------------------------------------------- # 03/09/01 davem@nuts.ninka.net 1.1389 # [IPV6]: Do not BUG() on icmp6 socket contention, just drop. # -------------------------------------------- # 03/09/01 davem@nuts.ninka.net 1.1390 # [IPV6]: Fix typo in icmp BUG() fix. # -------------------------------------------- # 03/09/01 bdschuym@pandora.be 1.1391 # [BRIDGE]: Create CONFIG_BRIDGE_NETFILTER and use it instead of messy tests. # -------------------------------------------- # 03/09/01 vnuorval@tcs.hut.fi 1.1392 # [IPV6]: Fix two bugs in ip6_tunnel.c ICMP error handling. # # Fix byte order of info parameter in ip6ip6_err(). # -------------------------------------------- # 03/09/01 vnuorval@tcs.hut.fi 1.1393 # [IPV6]: Use free_netdev as ip6_tunnel device destructor. # -------------------------------------------- # 03/09/01 vnuorval@tcs.hut.fi 1.1394 # [IPV6]: Set dev->{dev_addr,broadcast} in ip6_tnls. # -------------------------------------------- # 03/09/01 vnuorval@tcs.hut.fi 1.1395 # [IPV6]: Remove sockets from ip6_tunnel.c # -------------------------------------------- # 03/09/01 hch@lst.de 1.1396 # [NET]: Remove reference to CONFIG_IA64_SGI_SN1, it is gone. # -------------------------------------------- # 03/09/01 vinay-rc@naturesoft.net 1.1397 # [IPV6]: Fix timer handling in ip6_flowlabel.c # - Use time_{before,after}() macros. # - Use mod_timer instead of del_timer/add_timer # - Properly synchronize timer resetting using ip6_fl_lock. # -------------------------------------------- # 03/09/01 davem@nuts.ninka.net 1.1398 # [IPV6]: Fix types in fl6_renew(). # -------------------------------------------- # 03/09/01 davem@nuts.ninka.net 1.1399 # [IPV6]: linger member of ip6_flowlabel needs to be a long. # -------------------------------------------- # 03/09/01 davem@nuts.ninka.net 1.1400 # [IPV6]: Fix printf format in ip6fl_fl_seq_show. # -------------------------------------------- # 03/09/01 jgarzik@redhat.com 1.1297.1.2 # [netdrvr de2104x] ethtool_ops support # -------------------------------------------- # 03/09/01 jgarzik@redhat.com 1.1383.3.1 # [PCI] Remove cases where PCI_CACHE_LINE_SIZE is hardcoded. # # Modifies drivers atm/eni.c, ide/pci/cmd64x.c, and # ide/pci/ns87415.c. Ack'd by DaveM. # -------------------------------------------- # 03/09/01 jgarzik@redhat.com 1.1383.3.2 # [tokenring lanstreamer] clean up MWI / PCI_CACHE_LINE_SIZE usage # # * remove PCI_CACHE_LINE_SIZE workaround, PCI core already does # this for us. (main change) # * propagate pci_set_dma_mask return value # * add 'ULL' suffix to pci_set_dma_mask arg # * propagate pci_enable_device return value # * call pci_set_mwi, check and propagate its return value # * call pci_clear_mwi and pci_disable_device on close, and probe error # * call iounmap when cleaning up # -------------------------------------------- # 03/09/01 jgarzik@redhat.com 1.1383.3.3 # [video planb] don't hardware pci command/cacheline/latency values, # use the PCI layer instead to provide those for us. # -------------------------------------------- # 03/09/01 torvalds@home.osdl.org 1.1396.1.1 # Merge bk://kernel.bkbits.net/davem/net-2.5 # into home.osdl.org:/home/torvalds/v2.5/linux # -------------------------------------------- # 03/09/01 torvalds@home.osdl.org 1.1396.1.2 # Merge bk://kernel.bkbits.net/davem/tg3-2.5 # into home.osdl.org:/home/torvalds/v2.5/linux # -------------------------------------------- # 03/09/01 jgarzik@redhat.com 1.1297.1.3 # [netdrvr 8390] new function alloc_ei_netdev() # # (preferred over alloc_etherdev + 8390-specific ethdev_init) # -------------------------------------------- # 03/09/01 jgarzik@redhat.com 1.1297.1.4 # [netdrvr ne2k-pci] allocate netdev+8390 struct using new alloc_ei_netdev() # # Also, call pci_disable_device() in PCI ->remove handler, # to match pci_enable_device() in PCI ->probe handler. # -------------------------------------------- # 03/09/01 jgarzik@redhat.com 1.1297.1.5 # [netdrvr ne2k-pci] ethtool_ops support # -------------------------------------------- # 03/09/01 axboe@suse.de 1.1396.1.3 # [PATCH] software hd led support # # This adds support for software controlled hard drive LED activity. # # This is really nice on such machines as Apple Powerbooks, where there is # no such LED in the first place and the sleep/suspend LED isn't used for # anything when the machine is running. # -------------------------------------------- # 03/09/01 stelian@popies.net 1.1396.1.4 # [PATCH] reenable CAPTURE button in sonypi # # This reenables the CAPTURE button events in the sonypi driver, which # were lost with the latest patch... # -------------------------------------------- # 03/09/01 stelian@popies.net 1.1396.1.5 # [PATCH] meye driver update # # This implements the needed 'release' callback in order to make # videodev/sysfs happy again. # -------------------------------------------- # 03/09/01 torvalds@home.osdl.org 1.1396.1.6 # Merge bk://kernel.bkbits.net/jgarzik/pci-2.5 # into home.osdl.org:/home/torvalds/v2.5/linux # -------------------------------------------- # 03/09/01 torvalds@home.osdl.org 1.1396.1.7 # Merge bk://kernel.bkbits.net/jgarzik/net-drivers-2.5 # into home.osdl.org:/home/torvalds/v2.5/linux # -------------------------------------------- # 03/09/01 hirofumi@mail.parknet.co.jp 1.1396.1.8 # [PATCH] vfat_valid_longname() cleanup # # From René Scharfe # # As a result the size of vfat.o drops by 384 bytes in my build. # -------------------------------------------- # 03/09/01 axboe@suse.de 1.1396.1.9 # [PATCH] IO scheduler, not elevator # # I've been trying to remove these, but apparently new ones crop up. Lets # just call it io scheduler, none of the ones in the kernel are using the # classic elevator algorithm. # -------------------------------------------- # 03/09/01 davem@nuts.ninka.net 1.1401 # Merge nuts.ninka.net:/disk1/davem/BK/network-2.5 # into nuts.ninka.net:/disk1/davem/BK/net-2.5 # -------------------------------------------- # 03/09/01 jgarzik@redhat.com 1.1297.1.6 # [NET] move netif_* helpers from tg3 driver to linux/netdevice.h # # Helpers moved: # netif_poll_{enable,disable}, __netif_rx_complete, netif_tx_disable # # Use the helpers in net/core/dev.c. # -------------------------------------------- # 03/09/01 acme@allegro.kerneljanitors.org 1.1383.4.1 # o scsi: remove include procfs_h from hosts.h # -------------------------------------------- # 03/09/01 torvalds@home.osdl.org 1.1396.1.10 # Merge bk://kernel.bkbits.net/acme/scsi-2.6 # into home.osdl.org:/home/torvalds/v2.5/linux # -------------------------------------------- # 03/09/01 jgarzik@redhat.com 1.1396.1.11 # Merge redhat.com:/spare/repo/linux-2.5 # into redhat.com:/spare/repo/net-drivers-2.5 # -------------------------------------------- # 03/09/01 torvalds@home.osdl.org 1.1396.2.1 # Don't claim exclusive ownership of the device when doing # the SG_IO and SCSI_IOCTL_SEND_COMMAND ioctl's. That just # screws things up when the drive is mounted. # # If somebody wants exclusive access, he should indicate that # at open time. # -------------------------------------------- # 03/09/01 jgarzik@redhat.com 1.1396.1.12 # [netdrvr] ethtool_ops for epic100, fealnx, winbond-840, via-rhine # -------------------------------------------- # 03/09/01 jgarzik@redhat.com 1.1396.1.13 # [netdrvr fealnx] merge typo build fix (non-x86) from 2.4 # -------------------------------------------- # 03/09/01 jgarzik@redhat.com 1.1396.1.14 # [NET] move ethtool_op_set_tx_csum from 8139cp drvr to net/core/ethtool.c, # where it belongs. # -------------------------------------------- # 03/09/01 torvalds@home.osdl.org 1.1396.2.2 # Merge bk://bk.arm.linux.org.uk/linux-2.6-pcmcia # into home.osdl.org:/home/torvalds/v2.5/linux # -------------------------------------------- # 03/09/01 mdharm-scsi@one-eyed-alien.net 1.1396.2.3 # [PATCH] sr.c should issue TEST_UNIT_READY # # The linux/drivers/scsi/sr.c code will issue a MODE_SENSE[_10] command to # a device as the first command sent to the device. If the device has # just come out of reset, it will likely respond with a UNIT_ATTENTION / # NOT_READY status, which causes the MODE_SENSE to fail. In fact, the # device may have several UNIT_ATTENTION conditions queued up (power-up # reset, media change, etc.) # # This results in the mode page 0x2a data not being properly read and # interpreted. As an end-effect, things like packet-writing don't work # (because the writeable bit is not set). # # The solution to this is to issue one or more TEST_UNIT_READY commands to # the device to clear any pending UNIT_ATTENTION conditions. This is the # technique used by sd.c -- in fact, this code was lifted directly from # sd.c # # At some point in the future, abstraction of this initial TEST_UNIT_READY # code between all high-level SCSI drivers may be apropriate. For now, # this patch makes sr.c issue TEST_UNIT_READY to clear the UNIT_ATTENTION, # thus allowing the mode page 0x2a code to work properly. Given the # approaching 2.6.0-final release, I urge that this patch be accepted. # -------------------------------------------- # 03/09/01 gerg@snapgear.com 1.1396.2.4 # [PATCH] irqreturn_t fixes for m68knommu irq.h # -------------------------------------------- # 03/09/01 gerg@snapgear.com 1.1396.2.5 # [PATCH] create an m68knommu local.h # # This patch creates a local.h for the m68knommu arhcitecture. Like # most others architectures it is just an include of the generic one. # -------------------------------------------- # 03/09/01 gerg@snapgear.com 1.1396.2.6 # [PATCH] create an m68knommu sections.h # # This patch creates a sections.h for the m68knommu architecture. # Nothing special needed, just an include of the generic code. # -------------------------------------------- # 03/09/01 jgarzik@redhat.com 1.1396.3.1 # [PCI, ia32] don't assume "c->x86 > 6" applies to non-Intel CPUs # when programming PCI cache line size. # # Just to be on the safe side. Suggested by Ingo Oeser. # -------------------------------------------- # 03/09/01 torvalds@home.osdl.org 1.1396.2.7 # Merge bk://kernel.bkbits.net/jgarzik/misc-2.5 # into home.osdl.org:/home/torvalds/v2.5/linux # -------------------------------------------- # 03/09/01 torvalds@home.osdl.org 1.1396.1.15 # Merge bk://kernel.bkbits.net/jgarzik/net-drivers-2.5 # into home.osdl.org:/home/torvalds/v2.5/linux # -------------------------------------------- # 03/09/01 bcollins@debian.org 1.1396.1.16 # [PATCH] Update IEEE1394 (r1047) # # subsys : - Added hpsb_make_streampacket() helper # - Fix re-probe of bus after reset, when node's generation # changes # - Missing spinlock.h include for csr.c # # general : - Fix a few warnings from size mismatches in printk's # # raw1394 : - Added RAW1394_REQ_ASYNC_STREAM # - Use vmalloc/vfree for larger buffer support # # ohci1394 : - Fix a few endianess bugs in ISO routines # # eth1394 : - Fix cleanup of failed packets # -------------------------------------------- # 03/09/02 torvalds@home.osdl.org 1.1396.1.17 # Fix del_timer_sync() SMP memory ordering (from Tejun Huh ) # # From Tejun's posting: # > # > This patch fixes a race between del_timer_sync and recursive timers. # > Current implementation allows the value of timer->base that is used # > for timer_pending test to be fetched before finishing running_timer # > test, so it's possible for a recursive time to be pending after # > del_timer_sync. Adding smp_rmb before timer_pending removes the race. # -------------------------------------------- # 03/09/02 torvalds@home.osdl.org 1.1396.1.18 # Be a lot more careful about TS_USEDFPU and preemption # # We had some races where we testecd (or set) TS_USEDFPU together # with sequences that depended on the setting (like clearing or # setting the TS flag in %cr0) and we could be preempted in between, # which screws up the FPU state, since preemption will itself change # USEDFPU and the TS flag. # # This makes it a lot more explicit: the "internal" low-level FPU # functions ("__xxxx_fpu()") all require preemption to be disabled, # and the exported "real" functions will make sure that is the case. # # One case - in __switch_to() - was switched to the non-preempt-safe # internal version, since the scheduler itself has already disabled # preemption. # -------------------------------------------- # 03/09/02 davem@nuts.ninka.net 1.1402 # Merge nuts.ninka.net:/disk1/davem/BK/network-2.5 # into nuts.ninka.net:/disk1/davem/BK/net-2.5 # -------------------------------------------- # 03/09/02 jgarzik@redhat.com 1.1403 # [SUNHME]: Fix non-sbus build. # -------------------------------------------- # 03/09/02 rusty@rustcorp.com.au 1.1404 # [NET]: Use MODULE_ALIAS() in network families. # # Previously, default aliases were hardwired into modutils. Now they # should be inside the modules, using MODULE_ALIAS() (they will be overridden # by any user alias). # -------------------------------------------- # 03/09/02 davem@nuts.ninka.net 1.1405 # [BLUETOOTH]: Fix typo in module alias changes. # -------------------------------------------- # 03/09/02 acme@conectiva.com.br 1.1396.1.19 # [PATCH] scsi cleanups # # o scsi/imm.h: use c99 style initialization # # As far as I verified this also fixes a bug when doing the # table lookup for IMM_EPP_32, that would result in "Unknown" # as IMM_EPP_32 is equal to 6 and there is the #ifdef... # # ChangeSet@1.1386, 2003-09-02 00:11:07-03:00, acme@allegro.kerneljanitors.org # o scsi/*.h: remove not needed #define NULL # # ChangeSet@1.1385, 2003-09-02 00:05:16-03:00, acme@allegro.kerneljanitors.org # o scsi/3w-xxx.h: use c99 style init # -------------------------------------------- # 03/09/02 bcollins@debian.org 1.1396.1.20 # [PATCH] Fix compile for raw1394 # # Include vmalloc.h to fix compilation of raw1394.c # -------------------------------------------- # 03/09/02 B.Zolnierkiewicz@elka.pw.edu.pl 1.1396.1.21 # [PATCH] ide: fix ide_unregister() vs. driver model # # From: Benjamin Herrenschmidt # # This patch seem to have been lost, so here it is again. It fixes an Ooops # on unregistering hwifs due to the device model now having mandatory # release() functions. It also close the possible race we had on release if # the entry was in use (by or /sys typically) by using a semaphore waiting # for the release() to be called after doing an unregister. # -------------------------------------------- # 03/09/02 B.Zolnierkiewicz@elka.pw.edu.pl 1.1396.1.22 # [PATCH] ide: forward-port siimage driver changes from 2.4.22 # # ide: forward-port siimage driver changes from 2.4.22 # -------------------------------------------- # 03/09/02 torvalds@home.osdl.org 1.1406 # Merge bk://kernel.bkbits.net/davem/net-2.5 # into home.osdl.org:/home/torvalds/v2.5/linux # -------------------------------------------- # 03/09/02 bunk@fs.tum.de 1.1407 # [PATCH] Mark more drivers BROKEN{,ON_SMP} # # - let more drivers that don't compile depend on BROKEN # - MTD_BLKMTD is fixed, remove the dependency on BROKEN # - let all drivers that don't compile on SMP (due to cli/sti usage) # depend on a BROKEN_ON_SMP that is only defined if !SMP || BROKEN # - #include interrupt.h for dummy cli/sti/... in two files to fix the # UP compilation of these files # # I marked only drivers that are broken for a long time and where I don't # know about existing fixes with BROKEN or BROKEN_ON_SMP. # -------------------------------------------- # 03/09/02 torvalds@home.osdl.org 1.1408 # Fix keyboard double E0-sequence release case # # From Andries Brouwer : we discard the double # release keypress, but we did it without clearing the "last byte # was E0" flag. So the next byte in the input stream would get # corrupted. # -------------------------------------------- # 03/09/02 LAVARRE@iomega.com 1.1276.1.67 # [PATCH] USB: storage: cbw/csw trace in order # # Via this patch ... # # We change only when CONFIG_USB_STORAGE_DEBUG=y. # # To /proc/kmsg etc. we now trace the fields of # the cbw as we order those fields in ram and as # we order those fields in time on the bus, to # avoid disorientating those of us who view those # canonical orders often. # # Also we no longer print "S" or "Sig" to # "Signature", instead we always print "S". We # chose "S" over "Sig" because it is the "T" # signature (aka "Tag") that actually makes each # cbw/csw pair distinct, whereas the so-called # Signatures only distinguish cbw from csw by # flipping one bit. # # Also in the trace we uppercase a 'C' and an 'S' # to keep cbw from csw typographically distinct. # # For example, what was: # # <7>usb-storage: Command INQUIRY (6 bytes) # <7>usb-storage: 12 00 00 00 24 00 # <7>usb-storage: Bulk command S 0x43425355 T 0x1f13 Trg 0 LUN 0 L 36 F 128 CL 6 # ... # <7>usb-storage: Bulk status Sig 0x53425355 T 0x1f13 R 0 Stat 0x0 # # becomes: # # <7>usb-storage: Command INQUIRY (6 bytes) # <7>usb-storage: 12 00 00 00 24 00 # <7>usb-storage: Bulk Command S 0x43425355 T 0x1f3b L 36 F 128 Trg 0 LUN 0 CL 6 # ... # <7>usb-storage: Bulk Status S 0x53425355 T 0x1f3b R 0 Stat 0x0 # -------------------------------------------- # 03/09/02 stern@rowland.harvard.edu 1.1276.1.68 # [PATCH] USB: storage: Revised update to isd200 I/O buffer patch # # This is a minor revision to the previous patch as83. It changes the name # of the various struct hd_driveid variables from 'drive' to 'id', per # Andries Brouwer's request. # # - Don't do DMA into the middle of a structure (info->drive). # - Don't use I/O buffers for two different purposes simultaneously # (info->ATARegs, regs, us->iobuf). # - Rename info->drive to info->id. # -------------------------------------------- # 03/09/02 david-b@pacbell.net 1.1276.1.69 # [PATCH] USB: net2280 one-liner # # Please merge this minor fix: # # - loosen constraints on buffer allocation # # This is needed before Alan's file-backed storage # gadget driver will initialize using net2280. # -------------------------------------------- # 03/09/02 david-b@pacbell.net 1.1276.1.70 # [PATCH] USB: usb hcd states # # AFAICT this is ready for your next merge with Linus. # # Ben's ohci stuff was not cooked yet, seemed like the # pm stuff wasn't yet supporting the hook(s) he needed. # RMK had similar issues w.r.t. PM on ARM too. # # # This patch includes: # # - updates from Benjamin Herrenschmidt to make usbcore # behave a bit better during PM suspend (setting and # checking hcd state). # # - related updates from me, making more paths into hcds # fail when the driver is suspended. # # - updates based on some feedback from Alan Stern, # notably including getting rid of a state we don't # really need (most of the patch, by volume). # # - an experiment that tries to give a warning in the # sadly common case of ACPI or APIC (etc) settings # that need to change before USB works. # # Net effect is that some of the PM issues start to get # resolved, maybe IRQ problems will be diagnosed quicker, # and some overdue cleanup gets started. # -------------------------------------------- # 03/09/02 jgarzik@pobox.com 1.1409 # [PATCH] Fix non-modular compile of 3c515.c # -------------------------------------------- # 03/09/02 bdschuym@pandora.be 1.1406.1.1 # [NETFILTER]: Use CONFIG_BRIDGE_NETFILTER in ipt_REJECT.c # -------------------------------------------- # 03/09/02 torvalds@home.osdl.org 1.1410 # Add the isicom serial driver to the list of drivers that are # broken on SMP (due to expecting global irq locking). # -------------------------------------------- # 03/09/02 torvalds@home.osdl.org 1.1411 # Instead of asking for "broken drivers", ask for a "clean compile". # # This makes "allyesconfig" do a better job. # -------------------------------------------- # 03/09/02 greg@kroah.com 1.1406.2.1 # Merge kroah.com:/home/greg/linux/BK/bleed-2.5 # into kroah.com:/home/greg/linux/BK/gregkh-2.6 # -------------------------------------------- # 03/09/02 shemminger@osdl.org 1.1406.1.2 # [NET]: Convert af_netlink.c over to seq_file. # -------------------------------------------- # 03/09/02 shemminger@osdl.org 1.1406.1.3 # [NET]: ethertap fixes. # # includes these changes from viro # * switched ethertap to dynamic allocation # * ethertap: embedded ->priv # * ethertap: fixed resource leaks on failure exits # and from me # * get it out of the static device list completely. # * add dependency on NETLINK_DEV # * not really obsolete yet # * configurable number of interfaces # -------------------------------------------- # 03/09/02 greg@kroah.com 1.1412 # Merge kroah.com:/home/greg/linux/BK/bleed-2.5 # into kroah.com:/home/greg/linux/BK/gregkh-2.6 # -------------------------------------------- # 03/09/02 romieu@fr.zoreil.com 1.1406.1.4 # [NET]: Balance alloc_netdev() with free_netdev() in ethertap. # -------------------------------------------- # 03/09/02 davem@nuts.ninka.net 1.1406.1.5 # [IPV4]: Do not BUG() on icmp_xmit_lock() contention, just drop. # -------------------------------------------- # 03/09/02 davem@kernel.bkbits.net 1.1411.1.1 # Merge nuts.ninka.net:/disk1/davem/BK/net-2.5 # into kernel.bkbits.net:/home/davem/net-2.5 # -------------------------------------------- # 03/09/02 torvalds@home.osdl.org 1.1413 # Merge bk://kernel.bkbits.net/davem/net-2.5 # into home.osdl.org:/home/torvalds/v2.5/linux # -------------------------------------------- # diff -Nru a/CREDITS b/CREDITS --- a/CREDITS Tue Sep 2 19:58:17 2003 +++ b/CREDITS Tue Sep 2 19:58:17 2003 @@ -281,6 +281,14 @@ S: Greenbelt, Maryland 20771 S: USA +N: Daniele Bellucci +E: bellucda@tiscali.it +D: Various Janitor work. +W: http://web.tiscali.it/bellucda +S: Via Delle Palme, 9 +S: Terni 05100 +S: Italy + N: Randolph Bentson E: bentson@grieg.seaslug.org W: http://www.aa.net/~bentson/ @@ -1279,14 +1287,13 @@ N: Christoph Hellwig E: hch@infradead.org -E: hch@sgi.com D: all kinds of driver, filesystem & core kernel hacking D: freevxfs driver D: sysvfs maintainer D: chief codingstyle nitpicker -S: Auweg 38 -S: 85748 Garching -S: Germany +S: Ampferstr. 50 / 4 +S: 6020 Innsbruck +S: Austria N: Richard Henderson E: rth@twiddle.net diff -Nru a/Documentation/DocBook/kernel-locking.tmpl b/Documentation/DocBook/kernel-locking.tmpl --- a/Documentation/DocBook/kernel-locking.tmpl Tue Sep 2 19:58:15 2003 +++ b/Documentation/DocBook/kernel-locking.tmpl Tue Sep 2 19:58:15 2003 @@ -463,7 +463,7 @@ spin_lock_irqsave() (include/linux/spinlock.h) is a variant which saves whether interrupts were on or off in a flags word, - which is passed to spin_lock_irqrestore(). This + which is passed to spin_unlock_irqrestore(). This means that the same code can be used inside an hard irq handler (where interrupts are already off) and in softirqs (where the irq disabling is required). diff -Nru a/Documentation/DocBook/writing_usb_driver.tmpl b/Documentation/DocBook/writing_usb_driver.tmpl --- a/Documentation/DocBook/writing_usb_driver.tmpl Tue Sep 2 19:58:15 2003 +++ b/Documentation/DocBook/writing_usb_driver.tmpl Tue Sep 2 19:58:15 2003 @@ -111,12 +111,12 @@ static struct usb_driver skel_driver = { - name: "skeleton", - probe: skel_probe, - disconnect: skel_disconnect, - fops: &skel_fops, - minor: USB_SKEL_MINOR_BASE, - id_table: skel_table, + .name = "skeleton", + .probe = skel_probe, + .disconnect = skel_disconnect, + .fops = &skel_fops, + .minor = USB_SKEL_MINOR_BASE, + .id_table = skel_table, }; @@ -202,41 +202,21 @@ are passed to the function: -static void * skel_probe(struct usb_device *dev, -unsigned int ifnum, const struct usb_device_id *id) +static int skel_probe(struct usb_interface *interface, + const struct usb_device_id *id) The driver now needs to verify that this device is actually one that it - can accept. If not, or if any error occurs during initialization, a NULL - value is returned from the probe function. Otherwise a pointer to a - private data structure containing the driver's state for this device is - returned. That pointer is stored in the usb_device structure, and all - callbacks to the driver pass that pointer. + can accept. If so, it returns 0. + If not, or if any error occurs during initialization, an errorcode + (such as -ENOMEM or -ENODEV) + is returned from the probe function. In the skeleton driver, we determine what end points are marked as bulk-in and bulk-out. We create buffers to hold the data that will be sent and received from the device, and a USB urb to write data to the device is - initialized. Also, we register the device with the devfs subsystem, - allowing users of devfs to access our device. That registration looks like - the following: - - -/* initialize the devfs node for this device and register it */ -sprintf(name, "skel%d", skel->minor); -skel->devfs = devfs_register (usb_devfs_handle, - name, - DEVFS_FL_DEFAULT, - USB_MAJOR, - USB_SKEL_MINOR_BASE + skel->minor, - S_IFCHR | S_IRUSR | S_IWUSR | - S_IRGRP | S_IWGRP | S_IROTH, - &skel_fops, - NULL); - - - If the devfs_register function fails, we do not care, as the devfs - subsystem will report this to the user. + initialized. Conversely, when the device is removed from the USB bus, the disconnect @@ -254,23 +234,18 @@ the device, any of the functions in the file_operations structure that were passed to the USB subsystem will be called from a user program trying to talk to the device. The first function called will be open, as the - program tries to open the device for I/O. Within the skeleton driver's - open function we increment the driver's usage count if it is a module with - a call to MODULE_INC_USE_COUNT. With this macro call, if the driver is - compiled as a module, the driver cannot be unloaded until a corresponding - MODULE_DEC_USE_COUNT macro is called. We also increment our private usage + program tries to open the device for I/O. We increment our private usage count and save off a pointer to our internal structure in the file structure. This is done so that future calls to file operations will - enable the driver to determine which device the user is addressing. All of - this is done with the following code: + enable the driver to determine which device the user is addressing. All + of this is done with the following code: /* increment our usage count for the module */ -MOD_INC_USE_COUNT; ++skel->open_count; /* save our object in the file's private structure */ -file->private_data = skel; +file->private_data = dev; After the open function is called, the read and write functions are called @@ -349,75 +324,47 @@ When the user program releases the file handle that it has been using to - talk to the device, the release function in the driver is called. In this - function we decrement the module usage count with a call to - MOD_DEC_USE_COUNT (to match our previous call to MOD_INC_USE_COUNT). We - also determine if there are any other programs that are currently talking - to the device (a device may be opened by more than one program at one - time). If this is the last user of the device, then we shut down any - possible pending writes that might be currently occurring. This is all - done with: - + talk to the device, the release function in the driver is called. In this + function we decrement our private usage count and wait for possible + pending writes: /* decrement our usage count for the device */ --skel->open_count; -if (skel->open_count <= 0) { - /* shutdown any bulk writes that might be going on */ - usb_unlink_urb (skel->write_urb); - skel->open_count = 0; -} -/* decrement our usage count for the module */ -MOD_DEC_USE_COUNT; One of the more difficult problems that USB drivers must be able to handle smoothly is the fact that the USB device may be removed from the system at any point in time, even if a program is currently talking to it. It needs to be able to shut down any current reads and writes and notify the - user-space programs that the device is no longer there. The following - code is an example of how to do this: + user-space programs that the device is no longer there. The following + code (function skel_delete) + is an example of how to do this: -/* if the device is not opened, then we clean right now */ -if (skel->open_count) { - minor_table[skel->minor] = NULL; - if (skel->bulk_in_buffer != NULL) - kfree (skel->bulk_in_buffer); - if (skel->bulk_out_buffer != NULL) - kfree (skel->bulk_out_buffer); - if (skel->write_urb != NULL) - usb_free_urb (skel->write_urb); - kfree (skel); -} else { - skel->dev = NULL; - up (&skel->sem); +static inline void skel_delete (struct usb_skel *dev) +{ + if (dev->bulk_in_buffer != NULL) + kfree (dev->bulk_in_buffer); + if (dev->bulk_out_buffer != NULL) + usb_buffer_free (dev->udev, dev->bulk_out_size, + dev->bulk_out_buffer, + dev->write_urb->transfer_dma); + if (dev->write_urb != NULL) + usb_free_urb (dev->write_urb); + kfree (dev); } - If a program currently has an open handle to the device, we only null the - usb_device structure in our local structure, as it has now gone away. For + If a program currently has an open handle to the device, we reset the flag + device_present. For every read, write, release and other functions that expect a device to be - present, the driver first checks to see if this usb_device structure is + present, the driver first checks this flag to see if the device is still present. If not, it releases that the device has disappeared, and a - -ENODEV error is returned to the user-space program. When the release - function is eventually called, it determines if there is no usb_device - structure and if not, it does the cleanup that the skel_disconnect + -ENODEV error is returned to the user-space program. When the release + function is eventually called, it determines if there is no device + and if not, it does the cleanup that the skel_disconnect function normally does if there are no open files on the device (see Listing 5). - -if (skel->dev == NULL) { - /* the device was unplugged before the file was released */ - minor_table[skel->minor] = NULL; - if (skel->bulk_in_buffer != NULL) - kfree (skel->bulk_in_buffer); - if (skel->bulk_out_buffer != NULL) - kfree (skel->bulk_out_buffer); - if (skel->write_urb != NULL) - usb_free_urb (skel->write_urb); - kfree (skel); - goto exit; -} - diff -Nru a/Documentation/filesystems/proc.txt b/Documentation/filesystems/proc.txt --- a/Documentation/filesystems/proc.txt Tue Sep 2 19:58:14 2003 +++ b/Documentation/filesystems/proc.txt Tue Sep 2 19:58:14 2003 @@ -25,6 +25,7 @@ 1.5 SCSI info 1.6 Parallel port info in /proc/parport 1.7 TTY info in /proc/tty + 1.8 Miscellaneous kernel statistics in /proc/stat 2 Modifying System Parameters 2.1 /proc/sys/fs - File system data @@ -702,6 +703,58 @@ /dev/console /dev/console 5 1 system:console /dev/tty /dev/tty 5 0 system:/dev/tty unknown /dev/tty 4 1-63 console + + +1.8 Miscellaneous kernel statistics in /proc/stat +------------------------------------------------- + +Various pieces of information about kernel activity are available in the +/proc/stat file. All of the numbers reported in this file are aggregates +since the system first booted. For a quick look, simply cat the file: + + > cat /proc/stat + cpu 2255 34 2290 22625563 6290 127 456 + cpu0 1132 34 1441 11311718 3675 127 438 + cpu1 1123 0 849 11313845 2614 0 18 + intr 114930548 113199788 3 0 5 263 0 4 [... lots more numbers ...] + ctxt 1990473 + btime 1062191376 + processes 2915 + procs_running 1 + procs_blocked 0 + +The very first "cpu" line aggregates the numbers in all of the other "cpuN" +lines. These numbers identify the amount of time the CPU has spent performing +different kinds of work. Time units are in USER_HZ (typically hundredths of a +second). The meanings of the columns are as follows, from left to right: + +- user: normal processes executing in user mode +- nice: niced processes executing in user mode +- system: processes executing in kernel mode +- idle: twiddling thumbs +- iowait: waiting for I/O to complete +- irq: servicing interrupts +- softirq: servicing softirqs + +The "intr" line gives counts of interrupts serviced since boot time, for each +of the possible system interrupts. The first column is the total of all +interrupts serviced; each subsequent column is the total for that particular +interrupt. + +The "ctxt" line gives the total number of context switches across all CPUs. + +The "btime" line gives the time at which the system booted, in seconds since +the Unix epoch. + +The "processes" line gives the number of processes and threads created, which +includes (but is not limited to) those created by calls to the fork() and +clone() system calls. + +The "procs_running" line gives the number of processes currently running on +CPUs. + +The "procs_blocked" line gives the number of processes currently blocked, +waiting for I/O to complete. ------------------------------------------------------------------------------ diff -Nru a/Documentation/ide.txt b/Documentation/ide.txt --- a/Documentation/ide.txt Tue Sep 2 19:58:17 2003 +++ b/Documentation/ide.txt Tue Sep 2 19:58:17 2003 @@ -1,5 +1,5 @@ - Information regarding the Enhanced IDE drive in Linux 2.5 + Information regarding the Enhanced IDE drive in Linux 2.6 ============================================================================== @@ -242,8 +242,23 @@ and quite likely to cause trouble with older/odd IDE drives. + "hdx=biostimings" : driver will NOT attempt to tune interface speed + (DMA/PIO) but always honour BIOS timings. + "hdx=slow" : insert a huge pause after each access to the data port. Should be used only as a last resort. + + "hdx=swapdata" : when the drive is a disk, byte swap all data + + "hdx=bswap" : same as above.......... + + "hdx=flash" : allows for more than one ata_flash disk to be + registered. In most cases, only one device + will be present. + + "hdx=scsi" : the return of the ide-scsi flag, this is useful for + allowing ide-floppy, ide-tape, and ide-cdrom|writers + to use ide-scsi emulation on a device specific option. "hdxlun=xx" : set the drive last logical unit @@ -277,27 +292,41 @@ "idex=noautotune" : driver will NOT attempt to tune interface speed This is the default for most chipsets, except the cmd640. + + "idex=biostimings" : driver will NOT attempt to tune interface speed + (DMA/PIO) but always honour BIOS timings. "idex=serialize" : do not overlap operations on idex. Please note that you will have to specify this option for both the respecitve primary and secondary channel to take effect. + + "idex=four" : four drives on idex and ide(x^1) share same ports "idex=reset" : reset interface after probe "idex=dma" : automatically configure/use DMA if possible. -The following are valid ONLY on ide0, which usually corresponds to the first -ATA interface found on the particular host, and the defaults for the base,ctl -ports must not be altered. + "idex=ata66" : informs the interface that it has an 80c cable + for chipsets that are ATA-66 capable, but the + ability to bit test for detection is currently + unknown. + + "ide=reverse" : formerly called to pci sub-system, but now local. + +The following are valid ONLY on ide0 (except dc4030), which usually corresponds +to the first ATA interface found on the particular host, and the defaults for +the base,ctl ports must not be altered. "ide0=dtc2278" : probe/support DTC2278 interface "ide0=ht6560b" : probe/support HT6560B interface "ide0=cmd640_vlb" : *REQUIRED* for VLB cards with the CMD640 chip (not for PCI -- automatically detected) "ide0=qd65xx" : probe/support qd65xx interface - "ide0=ali14xx" : probe/support ali14xx chipsets (ALI M1439/M1445) + "ide0=ali14xx" : probe/support ali14xx chipsets (ALI M1439/M1443/M1445) "ide0=umc8672" : probe/support umc8672 chipsets + "idex=dc4030" : probe/support Promise DC4030VL interface + "ide=doubler" : probe/support IDE doublers on Amiga There may be more options than shown -- use the source, Luke! @@ -375,3 +404,6 @@ Wed Apr 17 22:52:44 CEST 2002 edited by Marcin Dalecki, the current maintainer. + +Wed Aug 20 22:31:29 CEST 2003 updated ide boot uptions to current ide.c +comments at 2.6.0-test4 time. Maciej Soltysiak diff -Nru a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt --- a/Documentation/kernel-parameters.txt Tue Sep 2 19:58:20 2003 +++ b/Documentation/kernel-parameters.txt Tue Sep 2 19:58:20 2003 @@ -215,7 +215,10 @@ when calculating gettimeofday(). If specicified timesource is not avalible, it defaults to PIT. Format: { pit | tsc | cyclone | ... } - + + hpet= [IA-32,HPET] option to disable HPET and use PIT. + Format: disable + cm206= [HW,CD] Format: { auto | [,][] } diff -Nru a/Documentation/kobject.txt b/Documentation/kobject.txt --- a/Documentation/kobject.txt Tue Sep 2 19:58:14 2003 +++ b/Documentation/kobject.txt Tue Sep 2 19:58:14 2003 @@ -245,7 +245,9 @@ see the sysfs documentation for more information. - default_attrs: Default attributes to be exported via sysfs when the - object is registered. + object is registered.Note that the last attribute has to be + initialized to NULL ! You can find a complete implementation + in drivers/block/genhd.c Instances of struct kobj_type are not registered; only referenced by diff -Nru a/Documentation/sonypi.txt b/Documentation/sonypi.txt --- a/Documentation/sonypi.txt Tue Sep 2 19:58:12 2003 +++ b/Documentation/sonypi.txt Tue Sep 2 19:58:12 2003 @@ -8,7 +8,9 @@ Copyright (C) 2000 Andrew Tridgell This driver enables access to the Sony Programmable I/O Control Device which -can be found in many (all ?) Sony Vaio laptops. +can be found in many Sony Vaio laptops. Some newer Sony laptops (seems to be +limited to new FX series laptops, at least the FX501 and the FX702) lack a +sonypi device and are not supported at all by this driver. It will give access (through a user space utility) to some events those laptops generate, like: @@ -96,6 +98,7 @@ SONYPI_THUMBPHRASE_MASK 0x0200 SONYPI_MEYE_MASK 0x0400 SONYPI_MEMORYSTICK_MASK 0x0800 + SONYPI_BATTERY_MASK 0x1000 useinput: if set (which is the default) jogdial events are forwarded to the input subsystem as mouse wheel diff -Nru a/Documentation/sysctl/README b/Documentation/sysctl/README --- a/Documentation/sysctl/README Tue Sep 2 19:58:18 2003 +++ b/Documentation/sysctl/README Tue Sep 2 19:58:18 2003 @@ -55,6 +55,7 @@ by piece basis, or just some 'thematic frobbing'. The subdirs are about: +abi/ execution domains & personalities debug/ dev/ device specific information (eg dev/cdrom/info) fs/ specific filesystems diff -Nru a/Documentation/sysctl/abi.txt b/Documentation/sysctl/abi.txt --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/Documentation/sysctl/abi.txt Tue Sep 2 19:58:20 2003 @@ -0,0 +1,54 @@ +Documentation for /proc/sys/abi/* kernel version 2.6.0.test2 + (c) 2003, Fabian Frederick + +For general info : README. + +============================================================== + +This path is binary emulation relevant aka personality types aka abi. +When a process is executed, it's linked to an exec_domain whose +personality is defined using values available from /proc/sys/abi. +You can find further details about abi in include/linux/personality.h. + +Here are the files featuring in 2.6 kernel : + +- defhandler_coff +- defhandler_elf +- defhandler_lcall7 +- defhandler_libcso +- fake_utsname +- trace + +=========================================================== +defhandler_coff: +defined value : +PER_SCOSVR3 +0x0003 | STICKY_TIMEOUTS | WHOLE_SECONDS | SHORT_INODE + +=========================================================== +defhandler_elf: +defined value : +PER_LINUX +0 + +=========================================================== +defhandler_lcall7: +defined value : +PER_SVR4 +0x0001 | STICKY_TIMEOUTS | MMAP_PAGE_ZERO, + +=========================================================== +defhandler_libsco: +defined value: +PER_SVR4 +0x0001 | STICKY_TIMEOUTS | MMAP_PAGE_ZERO, + +=========================================================== +fake_utsname: +Unused + +=========================================================== +trace: +Unused + +=========================================================== diff -Nru a/Documentation/usb/hotplug.txt b/Documentation/usb/hotplug.txt --- a/Documentation/usb/hotplug.txt Tue Sep 2 19:58:14 2003 +++ b/Documentation/usb/hotplug.txt Tue Sep 2 19:58:14 2003 @@ -122,17 +122,17 @@ something like this: static struct usb_driver mydriver = { - name: "mydriver", - id_table: mydriver_id_table, - probe: my_probe, - disconnect: my_disconnect, + .name = "mydriver", + .id_table = mydriver_id_table, + .probe = my_probe, + .disconnect = my_disconnect, /* if using the usb chardev framework: - minor: MY_USB_MINOR_START, - fops: my_file_ops, + .minor = MY_USB_MINOR_START, + .fops = my_file_ops, if exposing any operations through usbdevfs: - ioctl: my_ioctl, + .ioctl = my_ioctl, */ } diff -Nru a/Documentation/video4linux/meye.txt b/Documentation/video4linux/meye.txt --- a/Documentation/video4linux/meye.txt Tue Sep 2 19:58:18 2003 +++ b/Documentation/video4linux/meye.txt Tue Sep 2 19:58:18 2003 @@ -16,6 +16,23 @@ MJPEG hardware grabbing is supported via a private API (see below). +Hardware supported: +------------------- + +This driver supports the 'second' version of the MotionEye camera :) + +The first version was connected directly on the video bus of the Neomagic +video card and is unsupported. + +The second one, made by Kawasaki Steel is fully supported by this +driver (PCI vendor/device is 0x136b/0xff01) + +The third one, present in recent (more or less last year) Picturebooks +(C1M* models), is not supported. The manufacturer has given the specs +to the developers under a NDA (which allows the develoment of a GPL +driver however), but things are not moving very fast (see +http://r-engine.sourceforge.net/) (PCI vendor/device is 0x10cf/0x2011). + Driver options: --------------- diff -Nru a/MAINTAINERS b/MAINTAINERS --- a/MAINTAINERS Tue Sep 2 19:58:16 2003 +++ b/MAINTAINERS Tue Sep 2 19:58:16 2003 @@ -615,8 +615,6 @@ S: Maintained DRM DRIVERS -P: Rik Faith -M: faith@redhat.com L: dri-devel@lists.sourceforge.net S: Supported @@ -1087,6 +1085,14 @@ L: kbuild-devel@lists.sourceforge.net W: http://kbuild.sourceforge.net S: Maintained + +KERNEL JANITORS +P: Several +L: kernel-janitor-discuss@lists.sf.net +W: http://www.kerneljanitors.org/ +W: http://sf.net/projects/kernel-janitor/ +W: http://developer.osdl.org/rddunlap/kj-patches/ +S: Maintained KERNEL NFSD P: Neil Brown diff -Nru a/Makefile b/Makefile --- a/Makefile Tue Sep 2 19:58:17 2003 +++ b/Makefile Tue Sep 2 19:58:17 2003 @@ -268,8 +268,19 @@ # Detect when mixed targets is specified, and make a second invocation # of make so .config is not included in this case either (for *config). +no-dot-config-targets := clean mrproper distclean \ + cscope TAGS tags help %docs check% + config-targets := 0 mixed-targets := 0 +dot-config := 1 + +ifneq ($(filter $(no-dot-config-targets), $(MAKECMDGOALS)),) + ifeq ($(filter-out $(no-dot-config-targets), $(MAKECMDGOALS)),) + dot-config := 0 + endif +endif + ifneq ($(filter config %config,$(MAKECMDGOALS)),) config-targets := 1 ifneq ($(filter-out config %config,$(MAKECMDGOALS)),) @@ -309,7 +320,26 @@ core-y := usr/ SUBDIRS := --include .config +ifeq ($(dot-config),1) +# In this section, we need .config + +# Read in dependencies to all Kconfig* files, make sure to run +# oldconfig if changes are detected. +-include .config.cmd + +include .config + +# If .config needs to be updated, it will be done via the dependency +# that autoconf has on .config. +# To avoid any implicit rule to kick in, define an empty command +.config: ; + +# If .config is newer than include/linux/autoconf.h, someone tinkered +# with it and forgot to run make oldconfig +include/linux/autoconf.h: scripts/fixdep .config + $(Q)$(MAKE) $(build)=scripts/kconfig silentoldconfig + +endif include arch/$(ARCH)/Makefile @@ -338,15 +368,7 @@ # Here goes the main Makefile # --------------------------------------------------------------------------- -# -# If the user gave a *config target, it'll be handled in another -# section below, since in this case we cannot include .config -# Same goes for other targets like clean/mrproper etc, which -# don't need .config, either -# In this section, we need .config - --include .config.cmd ifndef CONFIG_FRAME_POINTER CFLAGS += -fomit-frame-pointer @@ -521,13 +543,6 @@ @scripts/split-include include/linux/autoconf.h include/config @touch $@ -# if .config is newer than include/linux/autoconf.h, someone tinkered -# with it and forgot to run make oldconfig - -include/linux/autoconf.h: .config scripts/fixdep - $(Q)$(MAKE) $(build)=scripts/kconfig scripts/kconfig/conf - ./scripts/kconfig/conf -s arch/$(ARCH)/Kconfig - # Generate some files # --------------------------------------------------------------------------- @@ -579,6 +594,11 @@ .PHONY: _modinst_ _modinst_: + @if [ -z "`$(DEPMOD) -V | grep module-init-tools`" ]; then \ + echo "Warning: you may need to install module-init-tools"; \ + echo "See http://www.codemonkey.org.uk/post-halloween-2.5.txt";\ + sleep 1; \ + fi @rm -rf $(MODLIB)/kernel @rm -f $(MODLIB)/build @mkdir -p $(MODLIB)/kernel diff -Nru a/arch/alpha/Kconfig b/arch/alpha/Kconfig --- a/arch/alpha/Kconfig Tue Sep 2 19:58:18 2003 +++ b/arch/alpha/Kconfig Tue Sep 2 19:58:18 2003 @@ -597,40 +597,6 @@ source "drivers/pcmcia/Kconfig" -choice - prompt "Kernel core (/proc/kcore) format" - depends on PROC_FS - default KCORE_ELF - -config KCORE_ELF - bool "ELF" - ---help--- - If you enabled support for /proc file system then the file - /proc/kcore will contain the kernel core image. This can be used - in gdb: - - $ cd /usr/src/linux ; gdb vmlinux /proc/kcore - - You have two choices here: ELF and A.OUT. Selecting ELF will make - /proc/kcore appear in ELF core format as defined by the Executable - and Linking Format specification. Selecting A.OUT will choose the - old "a.out" format which may be necessary for some old versions - of binutils or on some architectures. - - This is especially useful if you have compiled the kernel with the - "-g" option to preserve debugging information. It is mainly used - for examining kernel data structures on the live kernel so if you - don't understand what this means or are not a kernel hacker, just - leave it at its default value ELF. - -config KCORE_AOUT - bool "A.OUT" - help - Not necessary unless you're using a very out-of-date binutils - version. You probably want KCORE_ELF. - -endchoice - config SRM_ENV tristate "SRM environment through procfs" depends on PROC_FS diff -Nru a/arch/alpha/kernel/core_titan.c b/arch/alpha/kernel/core_titan.c --- a/arch/alpha/kernel/core_titan.c Tue Sep 2 19:58:14 2003 +++ b/arch/alpha/kernel/core_titan.c Tue Sep 2 19:58:14 2003 @@ -717,12 +717,12 @@ struct alpha_agp_ops titan_agp_ops = { - setup: titan_agp_setup, - cleanup: titan_agp_cleanup, - configure: titan_agp_configure, - bind: titan_agp_bind_memory, - unbind: titan_agp_unbind_memory, - translate: titan_agp_translate + .setup = titan_agp_setup, + .cleanup = titan_agp_cleanup, + .configure = titan_agp_configure, + .bind = titan_agp_bind_memory, + .unbind = titan_agp_unbind_memory, + .translate = titan_agp_translate }; alpha_agp_info * diff -Nru a/arch/arm/Kconfig b/arch/arm/Kconfig --- a/arch/arm/Kconfig Tue Sep 2 19:58:16 2003 +++ b/arch/arm/Kconfig Tue Sep 2 19:58:16 2003 @@ -654,39 +654,6 @@ If you do not feel you need a faster FP emulation you should better choose NWFPE. -choice - prompt "Kernel core (/proc/kcore) format" - default KCORE_ELF - -config KCORE_ELF - bool "ELF" - ---help--- - If you enabled support for /proc file system then the file - /proc/kcore will contain the kernel core image. This can be used - in gdb: - - $ cd /usr/src/linux ; gdb vmlinux /proc/kcore - - You have two choices here: ELF and A.OUT. Selecting ELF will make - /proc/kcore appear in ELF core format as defined by the Executable - and Linking Format specification. Selecting A.OUT will choose the - old "a.out" format which may be necessary for some old versions - of binutils or on some architectures. - - This is especially useful if you have compiled the kernel with the - "-g" option to preserve debugging information. It is mainly used - for examining kernel data structures on the live kernel so if you - don't understand what this means or are not a kernel hacker, just - leave it at its default value ELF. - -config KCORE_AOUT - bool "A.OUT" - help - Not necessary unless you're using a very out-of-date binutils - version. You probably want KCORE_ELF. - -endchoice - source "fs/Kconfig.binfmt" source "drivers/base/Kconfig" diff -Nru a/arch/arm/Makefile b/arch/arm/Makefile --- a/arch/arm/Makefile Tue Sep 2 19:58:15 2003 +++ b/arch/arm/Makefile Tue Sep 2 19:58:15 2003 @@ -24,6 +24,7 @@ CFLAGS += -mbig-endian AS += -EB LD += -EB +AFLAGS += -mbig-endian endif check_gcc = $(shell if $(CC) $(1) -S -o /dev/null -xc /dev/null > /dev/null 2>&1; then echo "$(1)"; else echo "$(2)"; fi) diff -Nru a/arch/arm/boot/Makefile b/arch/arm/boot/Makefile --- a/arch/arm/boot/Makefile Tue Sep 2 19:58:13 2003 +++ b/arch/arm/boot/Makefile Tue Sep 2 19:58:13 2003 @@ -42,11 +42,12 @@ ifeq ($(CONFIG_ARCH_SA1100),y) zreladdr-$(CONFIG_SA1111) := 0xc0208000 endif - zreladdr-$(CONFIG_ARCH_PXA) := 0xa0008000 - zreladdr-$(CONFIG_ARCH_ANAKIN) := 0x20008000 - zreladdr-$(CONFIG_ARCH_IQ80310) := 0xa0008000 - zreladdr-$(CONFIG_ARCH_IQ80321) := 0xa0008000 - zreladdr-$(CONFIG_ARCH_ADIFCC) := 0xc0008000 + zreladdr-$(CONFIG_ARCH_PXA) := 0xa0008000 + zreladdr-$(CONFIG_ARCH_ANAKIN) := 0x20008000 + zreladdr-$(CONFIG_ARCH_IOP3XX) := 0xa0008000 +params-phys-$(CONFIG_ARCH_IOP3XX) := 0xa0000100 + zreladdr-$(CONFIG_ARCH_ADIFCC) := 0xc0008000 +params-phys-$(CONFIG_ARCH_ADIFCC) := 0xc0000100 ZRELADDR := $(zreladdr-y) ZTEXTADDR := $(ztextaddr-y) diff -Nru a/arch/arm/common/amba.c b/arch/arm/common/amba.c --- a/arch/arm/common/amba.c Tue Sep 2 19:58:15 2003 +++ b/arch/arm/common/amba.c Tue Sep 2 19:58:15 2003 @@ -41,13 +41,35 @@ return amba_lookup(pcdrv->id_table, pcdev) != NULL; } +static int amba_suspend(struct device *dev, u32 state) +{ + struct amba_driver *drv = to_amba_driver(dev->driver); + int ret = 0; + + if (dev->driver && drv->suspend) + ret = drv->suspend(to_amba_device(dev), state); + return ret; +} + +static int amba_resume(struct device *dev) +{ + struct amba_driver *drv = to_amba_driver(dev->driver); + int ret = 0; + + if (dev->driver && drv->resume) + ret = drv->resume(to_amba_device(dev)); + return ret; +} + /* * Primecells are part of the Advanced Microcontroller Bus Architecture, * so we call the bus "amba". */ -struct bus_type amba_bustype = { - .name = "amba", - .match = amba_match, +static struct bus_type amba_bustype = { + .name = "amba", + .match = amba_match, + .suspend = amba_suspend, + .resume = amba_resume, }; static int __init amba_init(void) @@ -84,18 +106,6 @@ drv->shutdown(to_amba_device(dev)); } -static int amba_suspend(struct device *dev, u32 state, u32 level) -{ - struct amba_driver *drv = to_amba_driver(dev->driver); - return drv->suspend(to_amba_device(dev), state, level); -} - -static int amba_resume(struct device *dev, u32 level) -{ - struct amba_driver *drv = to_amba_driver(dev->driver); - return drv->resume(to_amba_device(dev), level); -} - /** * amba_driver_register - register an AMBA device driver * @drv: amba device driver structure @@ -112,8 +122,6 @@ SETFN(probe); SETFN(remove); SETFN(shutdown); - SETFN(suspend); - SETFN(resume); return driver_register(&drv->drv); } diff -Nru a/arch/arm/common/sa1111.c b/arch/arm/common/sa1111.c --- a/arch/arm/common/sa1111.c Tue Sep 2 19:58:19 2003 +++ b/arch/arm/common/sa1111.c Tue Sep 2 19:58:19 2003 @@ -790,10 +790,13 @@ struct sa1111 *sachip = dev_get_drvdata(dev); struct sa1111_save_data *save; unsigned long flags; + unsigned int val; char *base; - if (!dev->saved_state && level == SUSPEND_NOTIFY) - dev->saved_state = kmalloc(sizeof(struct sa1111_save_data), GFP_KERNEL); + if (level != SUSPEND_DISABLE) + return 0; + + dev->saved_state = kmalloc(sizeof(struct sa1111_save_data), GFP_KERNEL); if (!dev->saved_state) return -ENOMEM; @@ -804,36 +807,31 @@ /* * Save state. */ - if (level == SUSPEND_SAVE_STATE) { - base = sachip->base; - save->skcr = sa1111_readl(base + SA1111_SKCR); - save->skpcr = sa1111_readl(base + SA1111_SKPCR); - save->skcdr = sa1111_readl(base + SA1111_SKCDR); - save->skaud = sa1111_readl(base + SA1111_SKAUD); - save->skpwm0 = sa1111_readl(base + SA1111_SKPWM0); - save->skpwm1 = sa1111_readl(base + SA1111_SKPWM1); - - base = sachip->base + SA1111_INTC; - save->intpol0 = sa1111_readl(base + SA1111_INTPOL0); - save->intpol1 = sa1111_readl(base + SA1111_INTPOL1); - save->inten0 = sa1111_readl(base + SA1111_INTEN0); - save->inten1 = sa1111_readl(base + SA1111_INTEN1); - save->wakepol0 = sa1111_readl(base + SA1111_WAKEPOL0); - save->wakepol1 = sa1111_readl(base + SA1111_WAKEPOL1); - save->wakeen0 = sa1111_readl(base + SA1111_WAKEEN0); - save->wakeen1 = sa1111_readl(base + SA1111_WAKEEN1); - } + base = sachip->base; + save->skcr = sa1111_readl(base + SA1111_SKCR); + save->skpcr = sa1111_readl(base + SA1111_SKPCR); + save->skcdr = sa1111_readl(base + SA1111_SKCDR); + save->skaud = sa1111_readl(base + SA1111_SKAUD); + save->skpwm0 = sa1111_readl(base + SA1111_SKPWM0); + save->skpwm1 = sa1111_readl(base + SA1111_SKPWM1); + + base = sachip->base + SA1111_INTC; + save->intpol0 = sa1111_readl(base + SA1111_INTPOL0); + save->intpol1 = sa1111_readl(base + SA1111_INTPOL1); + save->inten0 = sa1111_readl(base + SA1111_INTEN0); + save->inten1 = sa1111_readl(base + SA1111_INTEN1); + save->wakepol0 = sa1111_readl(base + SA1111_WAKEPOL0); + save->wakepol1 = sa1111_readl(base + SA1111_WAKEPOL1); + save->wakeen0 = sa1111_readl(base + SA1111_WAKEEN0); + save->wakeen1 = sa1111_readl(base + SA1111_WAKEEN1); /* * Disable. */ - if (level == SUSPEND_POWER_DOWN && state == 4) { - unsigned int val = sa1111_readl(sachip->base + SA1111_SKCR); - - sa1111_writel(val | SKCR_SLEEP, sachip->base + SA1111_SKCR); - sa1111_writel(0, sachip->base + SA1111_SKPWM0); - sa1111_writel(0, sachip->base + SA1111_SKPWM1); - } + val = sa1111_readl(sachip->base + SA1111_SKCR); + sa1111_writel(val | SKCR_SLEEP, sachip->base + SA1111_SKCR); + sa1111_writel(0, sachip->base + SA1111_SKPWM0); + sa1111_writel(0, sachip->base + SA1111_SKPWM1); spin_unlock_irqrestore(&sachip->lock, flags); @@ -857,6 +855,9 @@ unsigned long flags, id; char *base; + if (level != RESUME_ENABLE) + return 0; + save = (struct sa1111_save_data *)dev->saved_state; if (!save) return 0; @@ -878,39 +879,32 @@ /* * First of all, wake up the chip. */ - if (level == RESUME_POWER_ON) { - sa1111_wake(sachip); - - sa1111_writel(0, sachip->base + SA1111_INTC + SA1111_INTEN0); - sa1111_writel(0, sachip->base + SA1111_INTC + SA1111_INTEN1); - } - - if (level == RESUME_RESTORE_STATE) { - base = sachip->base; - sa1111_writel(save->skcr, base + SA1111_SKCR); - sa1111_writel(save->skpcr, base + SA1111_SKPCR); - sa1111_writel(save->skcdr, base + SA1111_SKCDR); - sa1111_writel(save->skaud, base + SA1111_SKAUD); - sa1111_writel(save->skpwm0, base + SA1111_SKPWM0); - sa1111_writel(save->skpwm1, base + SA1111_SKPWM1); - - base = sachip->base + SA1111_INTC; - sa1111_writel(save->intpol0, base + SA1111_INTPOL0); - sa1111_writel(save->intpol1, base + SA1111_INTPOL1); - sa1111_writel(save->inten0, base + SA1111_INTEN0); - sa1111_writel(save->inten1, base + SA1111_INTEN1); - sa1111_writel(save->wakepol0, base + SA1111_WAKEPOL0); - sa1111_writel(save->wakepol1, base + SA1111_WAKEPOL1); - sa1111_writel(save->wakeen0, base + SA1111_WAKEEN0); - sa1111_writel(save->wakeen1, base + SA1111_WAKEEN1); - } + sa1111_wake(sachip); + sa1111_writel(0, sachip->base + SA1111_INTC + SA1111_INTEN0); + sa1111_writel(0, sachip->base + SA1111_INTC + SA1111_INTEN1); + + base = sachip->base; + sa1111_writel(save->skcr, base + SA1111_SKCR); + sa1111_writel(save->skpcr, base + SA1111_SKPCR); + sa1111_writel(save->skcdr, base + SA1111_SKCDR); + sa1111_writel(save->skaud, base + SA1111_SKAUD); + sa1111_writel(save->skpwm0, base + SA1111_SKPWM0); + sa1111_writel(save->skpwm1, base + SA1111_SKPWM1); + + base = sachip->base + SA1111_INTC; + sa1111_writel(save->intpol0, base + SA1111_INTPOL0); + sa1111_writel(save->intpol1, base + SA1111_INTPOL1); + sa1111_writel(save->inten0, base + SA1111_INTEN0); + sa1111_writel(save->inten1, base + SA1111_INTEN1); + sa1111_writel(save->wakepol0, base + SA1111_WAKEPOL0); + sa1111_writel(save->wakepol1, base + SA1111_WAKEPOL1); + sa1111_writel(save->wakeen0, base + SA1111_WAKEEN0); + sa1111_writel(save->wakeen1, base + SA1111_WAKEEN1); spin_unlock_irqrestore(&sachip->lock, flags); - if (level == RESUME_ENABLE) { - dev->saved_state = NULL; - kfree(save); - } + dev->saved_state = NULL; + kfree(save); return 0; } @@ -1135,9 +1129,55 @@ return dev->devid == drv->devid; } +static int sa1111_bus_suspend(struct device *dev, u32 state) +{ + struct sa1111_dev *sadev = SA1111_DEV(dev); + struct sa1111_driver *drv = SA1111_DRV(dev->driver); + int ret = 0; + + if (drv && drv->suspend) + ret = drv->suspend(sadev, state); + return ret; +} + +static int sa1111_bus_resume(struct device *dev) +{ + struct sa1111_dev *sadev = SA1111_DEV(dev); + struct sa1111_driver *drv = SA1111_DRV(dev->driver); + int ret = 0; + + if (drv && drv->resume) + ret = drv->resume(sadev); + return ret; +} + +static int sa1111_bus_probe(struct device *dev) +{ + struct sa1111_dev *sadev = SA1111_DEV(dev); + struct sa1111_driver *drv = SA1111_DRV(dev->driver); + int ret = -ENODEV; + + if (drv->probe) + ret = drv->probe(sadev); + return ret; +} + +static int sa1111_bus_remove(struct device *dev) +{ + struct sa1111_dev *sadev = SA1111_DEV(dev); + struct sa1111_driver *drv = SA1111_DRV(dev->driver); + int ret = 0; + + if (drv->remove) + ret = drv->remove(sadev); + return ret; +} + struct bus_type sa1111_bus_type = { - .name = "RAB", - .match = sa1111_match, + .name = "sa1111-rab", + .match = sa1111_match, + .suspend = sa1111_bus_suspend, + .resume = sa1111_bus_resume, }; static int sa1111_rab_bus_init(void) @@ -1147,6 +1187,19 @@ postcore_initcall(sa1111_rab_bus_init); +int sa1111_driver_register(struct sa1111_driver *driver) +{ + driver->drv.probe = sa1111_bus_probe; + driver->drv.remove = sa1111_bus_remove; + driver->drv.bus = &sa1111_bus_type; + return driver_register(&driver->drv); +} + +void sa1111_driver_unregister(struct sa1111_driver *driver) +{ + driver_unregister(&driver->drv); +} + EXPORT_SYMBOL(sa1111_check_dma_bug); EXPORT_SYMBOL(sa1111_select_audio_mode); EXPORT_SYMBOL(sa1111_set_audio_rate); @@ -1155,3 +1208,5 @@ EXPORT_SYMBOL(sa1111_disable_device); EXPORT_SYMBOL(sa1111_pll_clock); EXPORT_SYMBOL(sa1111_bus_type); +EXPORT_SYMBOL(sa1111_driver_register); +EXPORT_SYMBOL(sa1111_driver_unregister); diff -Nru a/arch/arm/def-configs/iq80310 b/arch/arm/def-configs/iq80310 --- a/arch/arm/def-configs/iq80310 Tue Sep 2 19:58:13 2003 +++ b/arch/arm/def-configs/iq80310 Tue Sep 2 19:58:13 2003 @@ -19,6 +19,12 @@ # CONFIG_BSD_PROCESS_ACCT is not set CONFIG_SYSCTL=y CONFIG_LOG_BUF_SHIFT=14 +# CONFIG_EMBEDDED is not set +CONFIG_KALLSYMS=y +CONFIG_FUTEX=y +CONFIG_EPOLL=y +CONFIG_IOSCHED_AS=y +CONFIG_IOSCHED_DEADLINE=y # # Loadable module support @@ -34,7 +40,6 @@ # # CONFIG_ARCH_ADIFCC is not set # CONFIG_ARCH_ANAKIN is not set -# CONFIG_ARCH_ARCA5K is not set # CONFIG_ARCH_CLPS7500 is not set # CONFIG_ARCH_CLPS711X is not set # CONFIG_ARCH_CO285 is not set @@ -50,14 +55,6 @@ # CONFIG_ARCH_SHARK is not set # -# Archimedes/A5000 Implementations -# - -# -# Archimedes/A5000 Implementations (select only ONE) -# - -# # CLPS711X/EP721X Implementations # @@ -73,7 +70,9 @@ # IOP3xx Implementation Options # CONFIG_ARCH_IQ80310=y +# CONFIG_ARCH_IQ80321 is not set CONFIG_ARCH_IOP310=y +# CONFIG_ARCH_IOP321 is not set # # IOP3xx Chipset Features @@ -84,6 +83,14 @@ # CONFIG_IOP3XX_PMON is not set # +# ADIFCC Implementation Options +# + +# +# ADI Board Types +# + +# # Intel PXA250/210 Implementations # @@ -96,6 +103,7 @@ # CONFIG_CPU_32=y CONFIG_CPU_XSCALE=y +CONFIG_XS80200=y CONFIG_CPU_32v5=y # @@ -116,9 +124,15 @@ # CONFIG_HOTPLUG is not set # +# MMC/SD Card support +# +# CONFIG_MMC is not set + +# # At least one math emulation must be selected # CONFIG_FPE_NWFPE=y +# CONFIG_FPE_NWFPE_XP is not set # CONFIG_FPE_FASTFPE is not set CONFIG_KCORE_ELF=y # CONFIG_KCORE_AOUT is not set @@ -154,6 +168,7 @@ CONFIG_MTD_BLOCK=y # CONFIG_FTL is not set # CONFIG_NFTL is not set +# CONFIG_INFTL is not set # # RAM/ROM/Flash chip drivers @@ -164,6 +179,7 @@ # CONFIG_MTD_CFI_ADV_OPTIONS is not set CONFIG_MTD_CFI_INTELEXT=y # CONFIG_MTD_CFI_AMDSTD is not set +# CONFIG_MTD_CFI_STAA is not set # CONFIG_MTD_RAM is not set # CONFIG_MTD_ROM is not set # CONFIG_MTD_ABSENT is not set @@ -172,13 +188,11 @@ # # Mapping drivers for chip access # +# CONFIG_MTD_COMPLEX_MAPPINGS is not set # CONFIG_MTD_PHYSMAP is not set -# CONFIG_MTD_NORA is not set # CONFIG_MTD_ARM_INTEGRATOR is not set CONFIG_MTD_IQ80310=y # CONFIG_MTD_EDB7312 is not set -# CONFIG_MTD_PCI is not set -# CONFIG_MTD_UCLINUX is not set # # Self-contained MTD device drivers @@ -191,9 +205,9 @@ # # Disk-On-Chip Device Drivers # -# CONFIG_MTD_DOC1000 is not set # CONFIG_MTD_DOC2000 is not set # CONFIG_MTD_DOC2001 is not set +# CONFIG_MTD_DOC2001PLUS is not set # # NAND Flash Device Drivers @@ -236,7 +250,6 @@ # CONFIG_NETLINK_DEV is not set CONFIG_NETFILTER=y # CONFIG_NETFILTER_DEBUG is not set -# CONFIG_FILTER is not set CONFIG_UNIX=y # CONFIG_NET_KEY is not set CONFIG_INET=y @@ -253,7 +266,7 @@ # CONFIG_SYN_COOKIES is not set # CONFIG_INET_AH is not set # CONFIG_INET_ESP is not set -# CONFIG_XFRM_USER is not set +# CONFIG_INET_IPCOMP is not set # # IP: Netfilter Configuration @@ -264,7 +277,13 @@ # CONFIG_IP_NF_ARPTABLES is not set # CONFIG_IP_NF_COMPAT_IPCHAINS is not set # CONFIG_IP_NF_COMPAT_IPFWADM is not set + +# +# IP: Virtual Server Configuration +# +# CONFIG_IP_VS is not set # CONFIG_IPV6 is not set +# CONFIG_XFRM_USER is not set # # SCTP Configuration (EXPERIMENTAL) @@ -310,6 +329,7 @@ # CONFIG_NET_ETHERNET=y CONFIG_MII=y +# CONFIG_SMC91X is not set # CONFIG_HAPPYMEAL is not set # CONFIG_SUNGEM is not set # CONFIG_NET_VENDOR_3COM is not set @@ -351,6 +371,11 @@ # CONFIG_R8169 is not set # CONFIG_SK98LIN is not set # CONFIG_TIGON3 is not set + +# +# Ethernet (10000 Mbit) +# +# CONFIG_IXGB is not set # CONFIG_FDDI is not set # CONFIG_HIPPI is not set # CONFIG_PPP is not set @@ -402,6 +427,7 @@ CONFIG_BLK_DEV_IDECD=y # CONFIG_BLK_DEV_IDEFLOPPY is not set # CONFIG_IDE_TASK_IOCTL is not set +# CONFIG_IDE_TASKFILE_IO is not set # # IDE chipset support/bugfixes @@ -409,7 +435,7 @@ # CONFIG_BLK_DEV_IDEPCI is not set # -# SCSI support +# SCSI device support # # CONFIG_SCSI is not set @@ -481,6 +507,7 @@ # # I2C Hardware Sensors Chip support # +# CONFIG_I2C_SENSOR is not set # # L3 serial bus support @@ -534,6 +561,8 @@ # CONFIG_VIDEO_PMS is not set # CONFIG_VIDEO_CPIA is not set # CONFIG_VIDEO_STRADIS is not set +# CONFIG_VIDEO_HEXIUM_ORION is not set +# CONFIG_VIDEO_HEXIUM_GEMINI is not set # # Radio Adapters @@ -551,18 +580,29 @@ # # Supported Frontend Modules # -CONFIG_DVB_ALPS_BSRU6=y +# CONFIG_DVB_STV0299 is not set # CONFIG_DVB_ALPS_BSRV2 is not set # CONFIG_DVB_ALPS_TDLB7 is not set # CONFIG_DVB_ALPS_TDMB7 is not set +# CONFIG_DVB_ATMEL_AT76C651 is not set +# CONFIG_DVB_CX24110 is not set # CONFIG_DVB_GRUNDIG_29504_491 is not set # CONFIG_DVB_GRUNDIG_29504_401 is not set +# CONFIG_DVB_MT312 is not set # CONFIG_DVB_VES1820 is not set +# CONFIG_DVB_TDA1004X is not set # -# Supported DVB Adapters +# Supported SAA7146 based PCI Adapters # # CONFIG_DVB_AV7110 is not set +# CONFIG_DVB_BUDGET is not set + +# +# Supported FlexCopII (B2C2) Adapters +# +# CONFIG_DVB_B2C2_SKYSTAR is not set +# CONFIG_VIDEO_BTCX is not set # # File systems @@ -598,6 +638,7 @@ CONFIG_PROC_FS=y # CONFIG_DEVFS_FS is not set CONFIG_DEVPTS_FS=y +# CONFIG_DEVPTS_FS_XATTR is not set CONFIG_TMPFS=y CONFIG_RAMFS=y @@ -631,13 +672,13 @@ CONFIG_ROOT_NFS=y CONFIG_LOCKD=y # CONFIG_EXPORTFS is not set +CONFIG_SUNRPC=y +# CONFIG_SUNRPC_GSS is not set # CONFIG_SMB_FS is not set # CONFIG_CIFS is not set # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set # CONFIG_INTERMEZZO_FS is not set -CONFIG_SUNRPC=y -# CONFIG_SUNRPC_GSS is not set # CONFIG_AFS_FS is not set # @@ -655,6 +696,7 @@ # CONFIG_SOLARIS_X86_PARTITION is not set # CONFIG_UNIXWARE_DISKLABEL is not set # CONFIG_LDM_PARTITION is not set +# CONFIG_NEC98_PARTITION is not set # CONFIG_SGI_PARTITION is not set # CONFIG_ULTRIX_PARTITION is not set # CONFIG_SUN_PARTITION is not set @@ -666,13 +708,6 @@ # CONFIG_FB is not set # -# Console display driver support -# -# CONFIG_VGA_CONSOLE is not set -# CONFIG_MDA_CONSOLE is not set -CONFIG_DUMMY_CONSOLE=y - -# # Sound # # CONFIG_SOUND is not set @@ -695,6 +730,7 @@ # USB support # # CONFIG_USB is not set +# CONFIG_USB_GADGET is not set # # Bluetooth support @@ -714,7 +750,6 @@ # CONFIG_DEBUG_WAITQ is not set CONFIG_DEBUG_BUGVERBOSE=y CONFIG_DEBUG_ERRORS=y -CONFIG_KALLSYMS=y CONFIG_DEBUG_LL=y # diff -Nru a/arch/arm/def-configs/iq80321 b/arch/arm/def-configs/iq80321 --- a/arch/arm/def-configs/iq80321 Tue Sep 2 19:58:14 2003 +++ b/arch/arm/def-configs/iq80321 Tue Sep 2 19:58:14 2003 @@ -9,7 +9,7 @@ # # Code maturity level options # -# CONFIG_EXPERIMENTAL is not set +CONFIG_EXPERIMENTAL=y # # General setup @@ -19,6 +19,12 @@ # CONFIG_BSD_PROCESS_ACCT is not set CONFIG_SYSCTL=y CONFIG_LOG_BUF_SHIFT=14 +# CONFIG_EMBEDDED is not set +CONFIG_KALLSYMS=y +CONFIG_FUTEX=y +CONFIG_EPOLL=y +CONFIG_IOSCHED_AS=y +CONFIG_IOSCHED_DEADLINE=y # # Loadable module support @@ -26,6 +32,7 @@ CONFIG_MODULES=y # CONFIG_MODULE_UNLOAD is not set CONFIG_OBSOLETE_MODPARM=y +# CONFIG_MODVERSIONS is not set CONFIG_KMOD=y # @@ -33,7 +40,6 @@ # # CONFIG_ARCH_ADIFCC is not set # CONFIG_ARCH_ANAKIN is not set -# CONFIG_ARCH_ARCA5K is not set # CONFIG_ARCH_CLPS7500 is not set # CONFIG_ARCH_CLPS711X is not set # CONFIG_ARCH_CO285 is not set @@ -49,14 +55,6 @@ # CONFIG_ARCH_SHARK is not set # -# Archimedes/A5000 Implementations -# - -# -# Archimedes/A5000 Implementations (select only ONE) -# - -# # CLPS711X/EP721X Implementations # @@ -79,6 +77,18 @@ # # IOP3xx Chipset Features # +# CONFIG_IOP3XX_AAU is not set +# CONFIG_IOP3XX_DMA is not set +# CONFIG_IOP3XX_MU is not set +# CONFIG_IOP3XX_PMON is not set + +# +# ADIFCC Implementation Options +# + +# +# ADI Board Types +# # # Intel PXA250/210 Implementations @@ -98,6 +108,7 @@ # # Processor Features # +# CONFIG_ARM_THUMB is not set CONFIG_XSCALE_PMU=y # @@ -112,17 +123,25 @@ # CONFIG_HOTPLUG is not set # +# MMC/SD Card support +# +# CONFIG_MMC is not set + +# # At least one math emulation must be selected # CONFIG_FPE_NWFPE=y +# CONFIG_FPE_NWFPE_XP is not set +# CONFIG_FPE_FASTFPE is not set CONFIG_KCORE_ELF=y # CONFIG_KCORE_AOUT is not set CONFIG_BINFMT_AOUT=y CONFIG_BINFMT_ELF=y # CONFIG_BINFMT_MISC is not set # CONFIG_PM is not set +# CONFIG_PREEMPT is not set # CONFIG_ARTHUR is not set -CONFIG_CMDLINE="ip=boot root=nfs console=ttyS0,115200" +CONFIG_CMDLINE="ip=boot root=nfs console=ttyS0,115200 mem=128M@0xa0000000" CONFIG_ALIGNMENT_TRAP=y # @@ -148,6 +167,7 @@ CONFIG_MTD_BLOCK=y # CONFIG_FTL is not set # CONFIG_NFTL is not set +# CONFIG_INFTL is not set # # RAM/ROM/Flash chip drivers @@ -158,6 +178,7 @@ # CONFIG_MTD_CFI_ADV_OPTIONS is not set CONFIG_MTD_CFI_INTELEXT=y # CONFIG_MTD_CFI_AMDSTD is not set +# CONFIG_MTD_CFI_STAA is not set # CONFIG_MTD_RAM is not set # CONFIG_MTD_ROM is not set # CONFIG_MTD_ABSENT is not set @@ -166,13 +187,10 @@ # # Mapping drivers for chip access # +# CONFIG_MTD_COMPLEX_MAPPINGS is not set # CONFIG_MTD_PHYSMAP is not set -# CONFIG_MTD_NORA is not set # CONFIG_MTD_ARM_INTEGRATOR is not set -CONFIG_MTD_IQ80321=y # CONFIG_MTD_EDB7312 is not set -# CONFIG_MTD_PCI is not set -# CONFIG_MTD_UCLINUX is not set # # Self-contained MTD device drivers @@ -185,9 +203,9 @@ # # Disk-On-Chip Device Drivers # -# CONFIG_MTD_DOC1000 is not set # CONFIG_MTD_DOC2000 is not set # CONFIG_MTD_DOC2001 is not set +# CONFIG_MTD_DOC2001PLUS is not set # # NAND Flash Device Drivers @@ -206,6 +224,7 @@ # 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_UMEM is not set # CONFIG_BLK_DEV_LOOP is not set # CONFIG_BLK_DEV_NBD is not set CONFIG_BLK_DEV_RAM=y @@ -229,7 +248,6 @@ # CONFIG_NETLINK_DEV is not set CONFIG_NETFILTER=y # CONFIG_NETFILTER_DEBUG is not set -# CONFIG_FILTER is not set CONFIG_UNIX=y # CONFIG_NET_KEY is not set CONFIG_INET=y @@ -241,24 +259,47 @@ # CONFIG_IP_PNP_RARP is not set # CONFIG_NET_IPIP is not set # CONFIG_NET_IPGRE is not set +# CONFIG_ARPD is not set # CONFIG_INET_ECN is not set # CONFIG_SYN_COOKIES is not set # CONFIG_INET_AH is not set # CONFIG_INET_ESP is not set -# CONFIG_XFRM_USER is not set +# CONFIG_INET_IPCOMP 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_ARPTABLES is not set # CONFIG_IP_NF_COMPAT_IPCHAINS is not set # CONFIG_IP_NF_COMPAT_IPFWADM is not set + +# +# IP: Virtual Server Configuration +# +# CONFIG_IP_VS is not set +# CONFIG_IPV6 is not set +# CONFIG_XFRM_USER is not set + +# +# SCTP Configuration (EXPERIMENTAL) +# +CONFIG_IPV6_SCTP__=y +# CONFIG_IP_SCTP is not set +# CONFIG_ATM is not set # CONFIG_VLAN_8021Q is not set # CONFIG_LLC is not set # CONFIG_DECNET is not set # CONFIG_BRIDGE is not set +# CONFIG_X25 is not set +# CONFIG_LAPB 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 @@ -279,12 +320,14 @@ # CONFIG_BONDING is not set # CONFIG_EQUALIZER is not set # CONFIG_TUN is not set +# CONFIG_ETHERTAP is not set # # Ethernet (10 or 100Mbit) # CONFIG_NET_ETHERNET=y # CONFIG_MII is not set +# CONFIG_SMC91X is not set # CONFIG_HAPPYMEAL is not set # CONFIG_SUNGEM is not set # CONFIG_NET_VENDOR_3COM is not set @@ -298,6 +341,7 @@ # CONFIG_PCNET32 is not set # CONFIG_AMD8111_ETH is not set # CONFIG_ADAPTEC_STARFIRE is not set +# CONFIG_B44 is not set # CONFIG_DGRS is not set CONFIG_EEPRO100=y # CONFIG_EEPRO100_PIO is not set @@ -305,6 +349,7 @@ # CONFIG_FEALNX is not set # CONFIG_NATSEMI is not set # CONFIG_NE2K_PCI is not set +# CONFIG_8139CP is not set # CONFIG_8139TOO is not set # CONFIG_SIS900 is not set # CONFIG_EPIC100 is not set @@ -317,13 +362,21 @@ # # CONFIG_ACENIC is not set # CONFIG_DL2K is not set -# CONFIG_E1000 is not set +CONFIG_E1000=y +CONFIG_E1000_NAPI=y # CONFIG_NS83820 is not set # CONFIG_HAMACHI is not set +# CONFIG_YELLOWFIN is not set # CONFIG_R8169 is not set # CONFIG_SK98LIN is not set # CONFIG_TIGON3 is not set + +# +# Ethernet (10000 Mbit) +# +# CONFIG_IXGB is not set # CONFIG_FDDI is not set +# CONFIG_HIPPI is not set # CONFIG_PPP is not set # CONFIG_SLIP is not set @@ -335,6 +388,8 @@ # # Token Ring devices (depends on LLC=y) # +# CONFIG_RCPCI is not set +# CONFIG_SHAPER is not set # # Wan interfaces @@ -371,6 +426,7 @@ CONFIG_BLK_DEV_IDECD=y # CONFIG_BLK_DEV_IDEFLOPPY is not set # CONFIG_IDE_TASK_IOCTL is not set +# CONFIG_IDE_TASKFILE_IO is not set # # IDE chipset support/bugfixes @@ -379,11 +435,13 @@ # CONFIG_BLK_DEV_GENERIC is not set # CONFIG_IDEPCI_SHARE_IRQ is not set CONFIG_BLK_DEV_IDEDMA_PCI=y +# CONFIG_BLK_DEV_IDE_TCQ is not set # CONFIG_BLK_DEV_OFFBOARD is not set # CONFIG_BLK_DEV_IDEDMA_FORCED is not set CONFIG_IDEDMA_PCI_AUTO=y # CONFIG_IDEDMA_ONLYDISK is not set CONFIG_BLK_DEV_IDEDMA=y +# CONFIG_IDEDMA_PCI_WIP is not set CONFIG_BLK_DEV_ADMA=y # CONFIG_BLK_DEV_AEC62XX is not set # CONFIG_BLK_DEV_ALI15X3 is not set @@ -391,11 +449,13 @@ CONFIG_BLK_DEV_CMD64X=y # CONFIG_BLK_DEV_TRIFLEX is not set # CONFIG_BLK_DEV_CY82C693 is not set +# CONFIG_BLK_DEV_CS5520 is not set # CONFIG_BLK_DEV_HPT34X is not set # CONFIG_BLK_DEV_HPT366 is not set # CONFIG_BLK_DEV_SC1200 is not set # CONFIG_BLK_DEV_PIIX is not set # CONFIG_BLK_DEV_NS87415 is not set +# CONFIG_BLK_DEV_OPTI621 is not set # CONFIG_BLK_DEV_PDC202XX_OLD is not set # CONFIG_BLK_DEV_PDC202XX_NEW is not set # CONFIG_BLK_DEV_SVWKS is not set @@ -408,11 +468,16 @@ # CONFIG_IDEDMA_IVB is not set # -# SCSI support +# SCSI device support # # CONFIG_SCSI is not set # +# IEEE 1394 (FireWire) support (EXPERIMENTAL) +# +# CONFIG_IEEE1394 is not set + +# # I2O device support # # CONFIG_I2O is not set @@ -450,11 +515,16 @@ # # Serial drivers # +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y +# CONFIG_SERIAL_8250_EXTENDED is not set # # Non-8250 serial port support # # CONFIG_SERIAL_DZ is not set +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y CONFIG_UNIX98_PTYS=y CONFIG_UNIX98_PTY_COUNT=256 @@ -470,6 +540,7 @@ # # I2C Hardware Sensors Chip support # +# CONFIG_I2C_SENSOR is not set # # L3 serial bus support @@ -522,6 +593,9 @@ # # CONFIG_VIDEO_PMS is not set # CONFIG_VIDEO_CPIA is not set +# CONFIG_VIDEO_STRADIS is not set +# CONFIG_VIDEO_HEXIUM_ORION is not set +# CONFIG_VIDEO_HEXIUM_GEMINI is not set # # Radio Adapters @@ -534,6 +608,7 @@ # Digital Video Broadcasting Devices # # CONFIG_DVB is not set +# CONFIG_VIDEO_BTCX is not set # # File systems @@ -567,16 +642,25 @@ # Pseudo filesystems # CONFIG_PROC_FS=y +# CONFIG_DEVFS_FS is not set CONFIG_DEVPTS_FS=y +# CONFIG_DEVPTS_FS_XATTR is not set CONFIG_TMPFS=y CONFIG_RAMFS=y # # Miscellaneous filesystems # +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set # CONFIG_JFFS_FS is not set CONFIG_JFFS2_FS=y CONFIG_JFFS2_FS_DEBUG=0 +# CONFIG_JFFS2_FS_NAND is not set # CONFIG_CRAMFS is not set # CONFIG_VXFS_FS is not set # CONFIG_HPFS_FS is not set @@ -589,15 +673,19 @@ # CONFIG_NFS_FS=y # CONFIG_NFS_V3 is not set +# CONFIG_NFS_V4 is not set # CONFIG_NFSD is not set CONFIG_ROOT_NFS=y CONFIG_LOCKD=y # CONFIG_EXPORTFS is not set +CONFIG_SUNRPC=y +# CONFIG_SUNRPC_GSS is not set # CONFIG_SMB_FS is not set # CONFIG_CIFS is not set # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set -CONFIG_SUNRPC=y +# CONFIG_INTERMEZZO_FS is not set +# CONFIG_AFS_FS is not set # # Partition Types @@ -614,6 +702,7 @@ # CONFIG_SOLARIS_X86_PARTITION is not set # CONFIG_UNIXWARE_DISKLABEL is not set # CONFIG_LDM_PARTITION is not set +# CONFIG_NEC98_PARTITION is not set # CONFIG_SGI_PARTITION is not set # CONFIG_ULTRIX_PARTITION is not set # CONFIG_SUN_PARTITION is not set @@ -625,13 +714,6 @@ # CONFIG_FB is not set # -# Console display driver support -# -# CONFIG_VGA_CONSOLE is not set -# CONFIG_MDA_CONSOLE is not set -CONFIG_DUMMY_CONSOLE=y - -# # Sound # # CONFIG_SOUND is not set @@ -654,6 +736,7 @@ # USB support # # CONFIG_USB is not set +# CONFIG_USB_GADGET is not set # # Bluetooth support @@ -664,7 +747,7 @@ # Kernel hacking # CONFIG_FRAME_POINTER=y -CONFIG_DEBUG_USER=y +# CONFIG_DEBUG_USER is not set # CONFIG_DEBUG_INFO is not set CONFIG_DEBUG_KERNEL=y # CONFIG_DEBUG_SLAB is not set @@ -673,7 +756,6 @@ # CONFIG_DEBUG_WAITQ is not set CONFIG_DEBUG_BUGVERBOSE=y CONFIG_DEBUG_ERRORS=y -# CONFIG_KALLSYMS is not set CONFIG_DEBUG_LL=y # diff -Nru a/arch/arm/kernel/apm.c b/arch/arm/kernel/apm.c --- a/arch/arm/kernel/apm.c Tue Sep 2 19:58:19 2003 +++ b/arch/arm/kernel/apm.c Tue Sep 2 19:58:19 2003 @@ -26,6 +26,7 @@ #include #include +#include /* apm_power_info */ #include /* @@ -93,18 +94,7 @@ static const char driver_version[] = "1.13"; /* no spaces */ -/* - * This structure gets filled in by the machine specific 'get_power_status' - * implementation. Any fields which are not set default to a safe value. - */ -struct apm_power_info { - unsigned char ac_line_status; - unsigned char battery_status; - unsigned char battery_flag; - unsigned char battery_life; - int time; - int units; -}; + /* * Compatibility cruft until the IPAQ people move over to the new @@ -388,18 +378,18 @@ } static struct file_operations apm_bios_fops = { - owner: THIS_MODULE, - read: apm_read, - poll: apm_poll, - ioctl: apm_ioctl, - open: apm_open, - release: apm_release, + .owner = THIS_MODULE, + .read = apm_read, + .poll = apm_poll, + .ioctl = apm_ioctl, + .open = apm_open, + .release = apm_release, }; static struct miscdevice apm_device = { - minor: APM_MINOR_DEV, - name: "apm_bios", - fops: &apm_bios_fops + .minor = APM_MINOR_DEV, + .name = "apm_bios", + .fops = &apm_bios_fops }; diff -Nru a/arch/arm/kernel/bios32.c b/arch/arm/kernel/bios32.c --- a/arch/arm/kernel/bios32.c Tue Sep 2 19:58:15 2003 +++ b/arch/arm/kernel/bios32.c Tue Sep 2 19:58:15 2003 @@ -263,7 +263,7 @@ void __devinit pcibios_update_irq(struct pci_dev *dev, int irq) { if (debug_pci) - printk("PCI: Assigning IRQ %02d to %s\n", irq, dev->dev.name); + printk("PCI: Assigning IRQ %02d to %s\n", irq, pci_name(dev)); pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq); } @@ -362,6 +362,19 @@ isa_bridge = dev; break; #endif + case PCI_CLASS_BRIDGE_PCI: + pci_read_config_word(dev, PCI_BRIDGE_CONTROL, &status); + status |= PCI_BRIDGE_CTL_PARITY|PCI_BRIDGE_CTL_MASTER_ABORT; + status &= ~(PCI_BRIDGE_CTL_BUS_RESET|PCI_BRIDGE_CTL_FAST_BACK); + pci_write_config_word(dev, PCI_BRIDGE_CONTROL, status); + break; + + case PCI_CLASS_BRIDGE_CARDBUS: + pci_read_config_word(dev, PCI_CB_BRIDGE_CONTROL, &status); + status |= PCI_CB_BRIDGE_CTL_PARITY|PCI_CB_BRIDGE_CTL_MASTER_ABORT; + pci_write_config_word(dev, PCI_CB_BRIDGE_CONTROL, status); + break; + } } /* diff -Nru a/arch/arm/kernel/ecard.c b/arch/arm/kernel/ecard.c --- a/arch/arm/kernel/ecard.c Tue Sep 2 19:58:18 2003 +++ b/arch/arm/kernel/ecard.c Tue Sep 2 19:58:18 2003 @@ -896,7 +896,7 @@ static ssize_t ecard_show_vendor(struct device *dev, char *buf) { struct expansion_card *ec = ECARD_DEV(dev); - return sprintf(buf, "%u\n", ec->manufacturer); + return sprintf(buf, "%u\n", ec->cid.manufacturer); } static DEVICE_ATTR(vendor, S_IRUGO, ecard_show_vendor, NULL); @@ -904,7 +904,7 @@ static ssize_t ecard_show_device(struct device *dev, char *buf) { struct expansion_card *ec = ECARD_DEV(dev); - return sprintf(buf, "%u\n", ec->product); + return sprintf(buf, "%u\n", ec->cid.product); } static DEVICE_ATTR(device, S_IRUGO, ecard_show_device, NULL); diff -Nru a/arch/arm/kernel/entry-header.S b/arch/arm/kernel/entry-header.S --- a/arch/arm/kernel/entry-header.S Tue Sep 2 19:58:15 2003 +++ b/arch/arm/kernel/entry-header.S Tue Sep 2 19:58:15 2003 @@ -63,13 +63,7 @@ #define S_OFF 8 .macro set_cpsr_c, reg, mode -#if 1 - /* broken binutils */ - mov \reg, \mode - msr cpsr_c, \reg -#else msr cpsr_c, \mode -#endif .endm .macro disable_irq, temp diff -Nru a/arch/arm/kernel/pm.c b/arch/arm/kernel/pm.c --- a/arch/arm/kernel/pm.c Tue Sep 2 19:58:20 2003 +++ b/arch/arm/kernel/pm.c Tue Sep 2 19:58:20 2003 @@ -36,23 +36,7 @@ if (ret != 0) goto out; - /* - * Tell LDM devices we're going to suspend. - */ - ret = device_suspend(4, SUSPEND_NOTIFY); - if (ret != 0) - goto resume_legacy; - - /* - * Disable, devices, and save state. - */ - device_suspend(4, SUSPEND_DISABLE); - device_suspend(4, SUSPEND_SAVE_STATE); - - /* - * Tell devices that they're going to be powered off. - */ - device_suspend(4, SUSPEND_POWER_DOWN); + device_suspend(3); local_irq_disable(); leds_event(led_stop); @@ -62,21 +46,8 @@ leds_event(led_start); local_irq_enable(); - /* - * Tell devices that they now have power. - */ - device_resume(RESUME_POWER_ON); - - /* - * Resume LDM devices. - */ - device_resume(RESUME_RESTORE_STATE); - device_resume(RESUME_ENABLE); + device_resume(); - resume_legacy: - /* - * Resume "legacy" devices. - */ pm_send_all(PM_RESUME, (void *)0); out: diff -Nru a/arch/arm/kernel/vmlinux.lds.S b/arch/arm/kernel/vmlinux.lds.S --- a/arch/arm/kernel/vmlinux.lds.S Tue Sep 2 19:58:12 2003 +++ b/arch/arm/kernel/vmlinux.lds.S Tue Sep 2 19:58:15 2003 @@ -1,21 +1,134 @@ -#include - -#ifdef CONFIG_CPU_26 - -#ifdef CONFIG_ROM_KERNEL - -#include "vmlinux-armo-rom.lds.in" - +/* ld script to make ARM Linux kernel + * taken from the i386 version by Russell King + * Written by Martin Mares + */ + +#include + +OUTPUT_ARCH(arm) +ENTRY(stext) +#ifndef __ARMEB__ +jiffies = jiffies_64; #else - -#include "vmlinux-armo.lds.in" - -#endif - -#endif - -#ifdef CONFIG_CPU_32 - -#include "vmlinux-armv.lds.in" - +jiffies = jiffies_64 + 4; #endif +SECTIONS +{ + . = TEXTADDR; + .init : { /* Init code and data */ + _stext = .; + __init_begin = .; + _sinittext = .; + *(.init.text) + _einittext = .; + __proc_info_begin = .; + *(.proc.info) + __proc_info_end = .; + __arch_info_begin = .; + *(.arch.info) + __arch_info_end = .; + __tagtable_begin = .; + *(.taglist) + __tagtable_end = .; + *(.init.data) + . = ALIGN(16); + __setup_start = .; + *(.init.setup) + __setup_end = .; + __early_begin = .; + *(__early_param) + __early_end = .; + __start___param = .; + *(__param) + __stop___param = .; + __initcall_start = .; + *(.initcall1.init) + *(.initcall2.init) + *(.initcall3.init) + *(.initcall4.init) + *(.initcall5.init) + *(.initcall6.init) + *(.initcall7.init) + __initcall_end = .; + __con_initcall_start = .; + *(.con_initcall.init) + __con_initcall_end = .; + __security_initcall_start = .; + *(.security_initcall.init) + __security_initcall_end = .; + . = ALIGN(32); + __initramfs_start = .; + usr/built-in.o(.init.ramfs) + __initramfs_end = .; + . = ALIGN(4096); + __init_end = .; + } + + /DISCARD/ : { /* Exit code and data */ + *(.exit.text) + *(.exit.data) + *(.exitcall.exit) + } + + .text : { /* Real text segment */ + _text = .; /* Text and read-only data */ + *(.text) + *(.fixup) + *(.gnu.warning) + *(.rodata) + *(.rodata.*) + *(.glue_7) + *(.glue_7t) + *(.got) /* Global offset table */ + + _etext = .; /* End of text section */ + } + + . = ALIGN(16); + __ex_table : { /* Exception table */ + __start___ex_table = .; + *(__ex_table) + __stop___ex_table = .; + } + + RODATA + + . = ALIGN(8192); + + .data : { + /* + * first, the init task union, aligned + * to an 8192 byte boundary. + */ + *(.init.task) + + /* + * then the cacheline aligned data + */ + . = ALIGN(32); + *(.data.cacheline_aligned) + + /* + * and the usual data section + */ + *(.data) + CONSTRUCTORS + + _edata = .; + } + + .bss : { + __bss_start = .; /* BSS */ + *(.bss) + *(COMMON) + _end = . ; + } + /* Stabs debugging sections. */ + .stab 0 : { *(.stab) } + .stabstr 0 : { *(.stabstr) } + .stab.excl 0 : { *(.stab.excl) } + .stab.exclstr 0 : { *(.stab.exclstr) } + .stab.index 0 : { *(.stab.index) } + .stab.indexstr 0 : { *(.stab.indexstr) } + .comment 0 : { *(.comment) } +} diff -Nru a/arch/arm/mach-footbridge/netwinder-pci.c b/arch/arm/mach-footbridge/netwinder-pci.c --- a/arch/arm/mach-footbridge/netwinder-pci.c Tue Sep 2 19:58:12 2003 +++ b/arch/arm/mach-footbridge/netwinder-pci.c Tue Sep 2 19:58:12 2003 @@ -36,8 +36,8 @@ return IRQ_NETWINDER_ETHER10; default: - printk(KERN_ERR "PCI: unknown device in slot %s: %s\n", - pci_name(dev), dev->dev.name); + printk(KERN_ERR "PCI: unknown device in slot %s\n", + pci_name(dev)); return 0; } } diff -Nru a/arch/arm/mach-iop3xx/iop321-time.c b/arch/arm/mach-iop3xx/iop321-time.c --- a/arch/arm/mach-iop3xx/iop321-time.c Tue Sep 2 19:58:18 2003 +++ b/arch/arm/mach-iop3xx/iop321-time.c Tue Sep 2 19:58:18 2003 @@ -51,7 +51,8 @@ return usec; } -static void iop321_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) +static irqreturn_t +iop321_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) { u32 tisr; @@ -62,6 +63,8 @@ asm volatile("mcr p6, 0, %0, c6, c1, 0" : : "r" (tisr)); do_timer(regs); + + return IRQ_HANDLED; } extern unsigned long (*gettimeoffset)(void); diff -Nru a/arch/arm/mach-iop3xx/iq80310-time.c b/arch/arm/mach-iop3xx/iq80310-time.c --- a/arch/arm/mach-iop3xx/iq80310-time.c Tue Sep 2 19:58:17 2003 +++ b/arch/arm/mach-iop3xx/iq80310-time.c Tue Sep 2 19:58:17 2003 @@ -88,7 +88,8 @@ } -static void iq80310_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) +static irqreturn_t +iq80310_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) { volatile u_char *timer_en = (volatile u_char *)IQ80310_TIMER_EN; @@ -96,21 +97,9 @@ *timer_en &= ~2; *timer_en |= 2; - /* - * AHEM..HACK - * - * Since the timer interrupt is cascaded through the CPLD and - * the 80312 and the demux code calls do_IRQ, the irq count is - * going to be at least 2 when we get here and this will cause the - * kernel to increment the system tick counter even if we're - * idle. This causes it to look like there's always 100% system - * time, which is not the case. To get around it, we just decrement - * the IRQ count before calling do_timer. We increment it again - * b/c otherwise it will go negative and than bad things happen. - * - * -DS - */ do_timer(regs); + + return IRQ_HANDLED; } extern unsigned long (*gettimeoffset)(void); @@ -126,7 +115,9 @@ volatile u_char *timer_en = (volatile u_char *)IQ80310_TIMER_EN; gettimeoffset = iq80310_gettimeoffset; + setup_irq(IRQ_IQ80310_TIMER, &timer_irq); + *timer_en = 0; iq80310_write_timer(LATCH); *timer_en |= 2; diff -Nru a/arch/arm/mach-sa1100/leds-simpad.c b/arch/arm/mach-sa1100/leds-simpad.c --- a/arch/arm/mach-sa1100/leds-simpad.c Tue Sep 2 19:58:15 2003 +++ b/arch/arm/mach-sa1100/leds-simpad.c Tue Sep 2 19:58:15 2003 @@ -9,6 +9,7 @@ #include #include #include +#include #include "leds.h" diff -Nru a/arch/arm/mach-sa1100/leds.c b/arch/arm/mach-sa1100/leds.c --- a/arch/arm/mach-sa1100/leds.c Tue Sep 2 19:58:13 2003 +++ b/arch/arm/mach-sa1100/leds.c Tue Sep 2 19:58:13 2003 @@ -41,6 +41,8 @@ leds_event = adsbitsy_leds_event; if (machine_is_pt_system3()) leds_event = system3_leds_event; + if (machine_is_simpad()) + leds_event = simpad_leds_event; /* what about machine registry? including led, apm... -zecke */ leds_event(led_start); return 0; diff -Nru a/arch/arm/mach-sa1100/leds.h b/arch/arm/mach-sa1100/leds.h --- a/arch/arm/mach-sa1100/leds.h Tue Sep 2 19:58:18 2003 +++ b/arch/arm/mach-sa1100/leds.h Tue Sep 2 19:58:18 2003 @@ -11,3 +11,4 @@ extern void graphicsmaster_leds_event(led_event_t evt); extern void adsbitsy_leds_event(led_event_t evt); extern void system3_leds_event(led_event_t evt); +extern void simpad_leds_event(led_event_t evt); diff -Nru a/arch/arm/vmlinux-armo.lds.in b/arch/arm/vmlinux-armo.lds.in --- a/arch/arm/vmlinux-armo.lds.in Tue Sep 2 19:58:19 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,114 +0,0 @@ -/* ld script to make ARM Linux kernel - * taken from the i386 version by Russell King - * Written by Martin Mares - */ - -#include - -OUTPUT_ARCH(arm) -ENTRY(stext) -jiffies = jiffies_64; -SECTIONS -{ - . = TEXTADDR; - .init : { /* Init code and data */ - _stext = .; - __init_begin = .; - _sinittext = .; - *(.init.text) - _einittext = .; - __proc_info_begin = .; - *(.proc.info) - __proc_info_end = .; - __arch_info_begin = .; - *(.arch.info) - __arch_info_end = .; - __tagtable_begin = .; - *(.taglist) - __tagtable_end = .; - *(.init.data) - . = ALIGN(16); - __setup_start = .; - *(.init.setup) - __setup_end = .; - __initcall_start = .; - *(.initcall1.init) - *(.initcall2.init) - *(.initcall3.init) - *(.initcall4.init) - *(.initcall5.init) - *(.initcall6.init) - *(.initcall7.init) - __initcall_end = .; - __con_initcall_start = .; - *(.con_initcall.init) - __con_initcall_end = .; - SECURITY_INIT - . = ALIGN(32768); - __init_end = .; - } - - .init.task : { - *(.init.task) - } - - /DISCARD/ : { /* Exit code and data */ - *(.exit.text) - *(.exit.data) - *(.exitcall.exit) - } - - .text : { /* Real text segment */ - _text = .; /* Text and read-only data */ - *(.text) - *(.fixup) - *(.gnu.warning) - *(.rodata) - *(.rodata.*) - *(.glue_7) - *(.glue_7t) - *(.got) /* Global offset table */ - - _etext = .; /* End of text section */ - } - - . = ALIGN(16); - __ex_table : { /* Exception table */ - __start___ex_table = .; - *(__ex_table) - __stop___ex_table = .; - } - - RODATA - - .data : { - /* - * The cacheline aligned data - */ - . = ALIGN(32); - *(.data.cacheline_aligned) - - /* - * and the usual data section - */ - *(.data) - CONSTRUCTORS - - _edata = .; - } - - .bss : { - __bss_start = .; /* BSS */ - *(.bss) - *(COMMON) - _end = . ; - } - /* Stabs debugging sections. */ - .stab 0 : { *(.stab) } - .stabstr 0 : { *(.stabstr) } - .stab.excl 0 : { *(.stab.excl) } - .stab.exclstr 0 : { *(.stab.exclstr) } - .stab.index 0 : { *(.stab.index) } - .stab.indexstr 0 : { *(.stab.indexstr) } - .comment 0 : { *(.comment) } -} diff -Nru a/arch/arm/vmlinux-armv.lds.in b/arch/arm/vmlinux-armv.lds.in --- a/arch/arm/vmlinux-armv.lds.in Tue Sep 2 19:58:15 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,134 +0,0 @@ -/* ld script to make ARM Linux kernel - * taken from the i386 version by Russell King - * Written by Martin Mares - */ - -#include - -OUTPUT_ARCH(arm) -ENTRY(stext) -#ifndef __ARMEB__ -jiffies = jiffies_64; -#else -jiffies = jiffies_64 + 4; -#endif -SECTIONS -{ - . = TEXTADDR; - .init : { /* Init code and data */ - _stext = .; - __init_begin = .; - _sinittext = .; - *(.init.text) - _einittext = .; - __proc_info_begin = .; - *(.proc.info) - __proc_info_end = .; - __arch_info_begin = .; - *(.arch.info) - __arch_info_end = .; - __tagtable_begin = .; - *(.taglist) - __tagtable_end = .; - *(.init.data) - . = ALIGN(16); - __setup_start = .; - *(.init.setup) - __setup_end = .; - __early_begin = .; - *(__early_param) - __early_end = .; - __start___param = .; - *(__param) - __stop___param = .; - __initcall_start = .; - *(.initcall1.init) - *(.initcall2.init) - *(.initcall3.init) - *(.initcall4.init) - *(.initcall5.init) - *(.initcall6.init) - *(.initcall7.init) - __initcall_end = .; - __con_initcall_start = .; - *(.con_initcall.init) - __con_initcall_end = .; - __security_initcall_start = .; - *(.security_initcall.init) - __security_initcall_end = .; - . = ALIGN(32); - __initramfs_start = .; - usr/built-in.o(.init.ramfs) - __initramfs_end = .; - . = ALIGN(4096); - __init_end = .; - } - - /DISCARD/ : { /* Exit code and data */ - *(.exit.text) - *(.exit.data) - *(.exitcall.exit) - } - - .text : { /* Real text segment */ - _text = .; /* Text and read-only data */ - *(.text) - *(.fixup) - *(.gnu.warning) - *(.rodata) - *(.rodata.*) - *(.glue_7) - *(.glue_7t) - *(.got) /* Global offset table */ - - _etext = .; /* End of text section */ - } - - . = ALIGN(16); - __ex_table : { /* Exception table */ - __start___ex_table = .; - *(__ex_table) - __stop___ex_table = .; - } - - RODATA - - . = ALIGN(8192); - - .data : { - /* - * first, the init task union, aligned - * to an 8192 byte boundary. - */ - *(.init.task) - - /* - * then the cacheline aligned data - */ - . = ALIGN(32); - *(.data.cacheline_aligned) - - /* - * and the usual data section - */ - *(.data) - CONSTRUCTORS - - _edata = .; - } - - .bss : { - __bss_start = .; /* BSS */ - *(.bss) - *(COMMON) - _end = . ; - } - /* Stabs debugging sections. */ - .stab 0 : { *(.stab) } - .stabstr 0 : { *(.stabstr) } - .stab.excl 0 : { *(.stab.excl) } - .stab.exclstr 0 : { *(.stab.exclstr) } - .stab.index 0 : { *(.stab.index) } - .stab.indexstr 0 : { *(.stab.indexstr) } - .comment 0 : { *(.comment) } -} diff -Nru a/arch/arm26/Kconfig b/arch/arm26/Kconfig --- a/arch/arm26/Kconfig Tue Sep 2 19:58:16 2003 +++ b/arch/arm26/Kconfig Tue Sep 2 19:58:16 2003 @@ -146,39 +146,6 @@ You may say N here if you are going to load the Acorn FPEmulator early in the bootup. -choice - prompt "Kernel core (/proc/kcore) format" - default KCORE_ELF - -config KCORE_ELF - bool "ELF" - ---help--- - If you enabled support for /proc file system then the file - /proc/kcore will contain the kernel core image. This can be used - in gdb: - - $ cd /usr/src/linux ; gdb vmlinux /proc/kcore - - You have two choices here: ELF and A.OUT. Selecting ELF will make - /proc/kcore appear in ELF core format as defined by the Executable - and Linking Format specification. Selecting A.OUT will choose the - old "a.out" format which may be necessary for some old versions - of binutils or on some architectures. - - This is especially useful if you have compiled the kernel with the - "-g" option to preserve debugging information. It is mainly used - for examining kernel data structures on the live kernel so if you - don't understand what this means or are not a kernel hacker, just - leave it at its default value ELF. - -config KCORE_AOUT - bool "A.OUT" - help - Not necessary unless you're using a very out-of-date binutils - version. You probably want KCORE_ELF. - -endchoice - source "fs/Kconfig.binfmt" config PREEMPT diff -Nru a/arch/arm26/kernel/setup.c b/arch/arm26/kernel/setup.c --- a/arch/arm26/kernel/setup.c Tue Sep 2 19:58:13 2003 +++ b/arch/arm26/kernel/setup.c Tue Sep 2 19:58:13 2003 @@ -304,12 +304,12 @@ #if defined(CONFIG_DUMMY_CONSOLE) struct screen_info screen_info = { - orig_video_lines: 30, - orig_video_cols: 80, - orig_video_mode: 0, - orig_video_ega_bx: 0, - orig_video_isVGA: 1, - orig_video_points: 8 + .orig_video_lines = 30, + .orig_video_cols = 80, + .orig_video_mode = 0, + .orig_video_ega_bx = 0, + .orig_video_isVGA = 1, + .orig_video_points = 8 }; static int __init parse_tag_videotext(const struct tag *tag) diff -Nru a/arch/cris/arch-v10/drivers/eeprom.c b/arch/cris/arch-v10/drivers/eeprom.c --- a/arch/cris/arch-v10/drivers/eeprom.c Tue Sep 2 19:58:15 2003 +++ b/arch/cris/arch-v10/drivers/eeprom.c Tue Sep 2 19:58:15 2003 @@ -441,9 +441,9 @@ static int eeprom_open(struct inode * inode, struct file * file) { - if(minor(inode->i_rdev) != EEPROM_MINOR_NR) + if(iminor(inode) != EEPROM_MINOR_NR) return -ENXIO; - if(major(inode->i_rdev) != EEPROM_MAJOR_NR) + if(imajor(inode) != EEPROM_MAJOR_NR) return -ENXIO; if( eeprom.size > 0 ) diff -Nru a/arch/cris/arch-v10/drivers/gpio.c b/arch/cris/arch-v10/drivers/gpio.c --- a/arch/cris/arch-v10/drivers/gpio.c Tue Sep 2 19:58:12 2003 +++ b/arch/cris/arch-v10/drivers/gpio.c Tue Sep 2 19:58:12 2003 @@ -386,7 +386,7 @@ gpio_open(struct inode *inode, struct file *filp) { struct gpio_private *priv; - int p = minor(inode->i_rdev); + int p = iminor(inode); if (p > GPIO_MINOR_LAST) return -EINVAL; diff -Nru a/arch/cris/arch-v10/drivers/pcf8563.c b/arch/cris/arch-v10/drivers/pcf8563.c --- a/arch/cris/arch-v10/drivers/pcf8563.c Tue Sep 2 19:58:14 2003 +++ b/arch/cris/arch-v10/drivers/pcf8563.c Tue Sep 2 19:58:14 2003 @@ -57,10 +57,10 @@ int pcf8563_release(struct inode *, struct file *); static struct file_operations pcf8563_fops = { - owner: THIS_MODULE, - ioctl: pcf8563_ioctl, - open: pcf8563_open, - release: pcf8563_release, + .owner = THIS_MODULE, + .ioctl = pcf8563_ioctl, + .open = pcf8563_open, + .release = pcf8563_release, }; unsigned char diff -Nru a/arch/h8300/Kconfig b/arch/h8300/Kconfig --- a/arch/h8300/Kconfig Tue Sep 2 19:58:18 2003 +++ b/arch/h8300/Kconfig Tue Sep 2 19:58:18 2003 @@ -177,13 +177,6 @@ menu "Executable file formats" -config KCORE_AOUT - bool - default y - -config KCORE_ELF - default y - source "fs/Kconfig.binfmt" endmenu diff -Nru a/arch/h8300/kernel/setup.c b/arch/h8300/kernel/setup.c --- a/arch/h8300/kernel/setup.c Tue Sep 2 19:58:13 2003 +++ b/arch/h8300/kernel/setup.c Tue Sep 2 19:58:13 2003 @@ -91,12 +91,12 @@ } static const struct console gdb_console = { - name: "gdb_con", - write: gdb_console_output, - device: NULL, - setup: gdb_console_setup, - flags: CON_PRINTBUFFER, - index: -1, + .name = "gdb_con", + .write = gdb_console_output, + .device = NULL, + .setup = gdb_console_setup, + .flags = CON_PRINTBUFFER, + .index = -1, }; #endif @@ -260,8 +260,8 @@ } struct seq_operations cpuinfo_op = { - start: c_start, - next: c_next, - stop: c_stop, - show: show_cpuinfo, + .start = c_start, + .next = c_next, + .stop = c_stop, + .show = show_cpuinfo, }; diff -Nru a/arch/h8300/platform/h8300h/ints.c b/arch/h8300/platform/h8300h/ints.c --- a/arch/h8300/platform/h8300h/ints.c Tue Sep 2 19:58:14 2003 +++ b/arch/h8300/platform/h8300h/ints.c Tue Sep 2 19:58:14 2003 @@ -32,15 +32,6 @@ #include #include -#define EXT_IRQ0 12 -#define EXT_IRQ1 13 -#define EXT_IRQ2 14 -#define EXT_IRQ3 15 -#define EXT_IRQ4 16 -#define EXT_IRQ5 17 -#define EXT_IRQ6 18 -#define EXT_IRQ7 19 - /* * This structure has only 4 elements for speed reasons */ @@ -57,17 +48,20 @@ extern unsigned long *interrupt_redirect_table; +#define CPU_VECTOR ((unsigned long *)0x000000) +#define ADDR_MASK (0xffffff) + static inline unsigned long *get_vector_address(void) { - unsigned long *rom_vector = (unsigned long *)0x000000; + unsigned long *rom_vector = CPU_VECTOR; unsigned long base,tmp; int vec_no; - base = rom_vector[EXT_IRQ0]; + base = rom_vector[EXT_IRQ0] & ADDR_MASK; /* check romvector format */ for (vec_no = EXT_IRQ1; vec_no <= EXT_IRQ5; vec_no++) { - if ((base+(vec_no - EXT_IRQ0)*4) != rom_vector[vec_no]) + if ((base+(vec_no - EXT_IRQ0)*4) != (rom_vector[vec_no] & ADDR_MASK)) return NULL; } @@ -171,7 +165,7 @@ irq, irq_list[irq]->devname); if (irq >= EXT_IRQ0 && irq <= EXT_IRQ5) *(volatile unsigned char *)IER &= ~(1 << (irq - EXT_IRQ0)); - if ((irq_list[irq] & 0x80000000) == 0) { + if (((unsigned long)irq_list[irq] & 0x80000000) == 0) { kfree(irq_list[irq]); irq_list[irq] = NULL; } @@ -241,8 +235,9 @@ { } -static void __init enable_kmalloc(void) +static int __init enable_kmalloc(void) { use_kmalloc = 1; + return 0; } -__initcall(enable_kmalloc); +core_initcall(enable_kmalloc); diff -Nru a/arch/h8300/platform/h8s/ints.c b/arch/h8300/platform/h8s/ints.c --- a/arch/h8300/platform/h8s/ints.c Tue Sep 2 19:58:15 2003 +++ b/arch/h8300/platform/h8s/ints.c Tue Sep 2 19:58:15 2003 @@ -33,23 +33,6 @@ #include #include -#define EXT_IRQ0 16 -#define EXT_IRQ1 17 -#define EXT_IRQ2 18 -#define EXT_IRQ3 19 -#define EXT_IRQ4 20 -#define EXT_IRQ5 21 -#define EXT_IRQ6 22 -#define EXT_IRQ7 23 -#define EXT_IRQ8 24 -#define EXT_IRQ9 25 -#define EXT_IRQ10 26 -#define EXT_IRQ11 27 -#define EXT_IRQ12 28 -#define EXT_IRQ13 29 -#define EXT_IRQ14 30 -#define EXT_IRQ15 31 - /* * This structure has only 4 elements for speed reasons */ @@ -95,17 +78,20 @@ extern unsigned long *interrupt_redirect_table; +#define CPU_VECTOR ((unsigned long *)0x000000) +#define ADDR_MASK (0xffffff) + static inline unsigned long *get_vector_address(void) { - volatile unsigned long *rom_vector = (unsigned long *)0x000000; + volatile unsigned long *rom_vector = CPU_VECTOR; unsigned long base,tmp; int vec_no; - base = rom_vector[EXT_IRQ0]; + base = rom_vector[EXT_IRQ0] & ADDR_MASK; /* check romvector format */ for (vec_no = EXT_IRQ1; vec_no <= EXT_IRQ15; vec_no++) { - if ((base+(vec_no - EXT_IRQ0)*4) != rom_vector[vec_no]) + if ((base+(vec_no - EXT_IRQ0)*4) != (rom_vector[vec_no] & ADDR_MASK)) return NULL; } @@ -307,4 +293,4 @@ use_kmalloc = 1; return 0; } -__initcall(enable_kmalloc); +core_initcall(enable_kmalloc); diff -Nru a/arch/i386/Kconfig b/arch/i386/Kconfig --- a/arch/i386/Kconfig Tue Sep 2 19:58:13 2003 +++ b/arch/i386/Kconfig Tue Sep 2 19:58:13 2003 @@ -408,6 +408,17 @@ Otherwise, say N. +config HPET_TIMER + bool "HPET Timer Support" + help + This enables the use of the HPET for the kernel's internal timer. + HPET is the next generation timer replacing legacy 8254s. + You can safely choose Y here. However, HPET will only be + activated if the platform and the BIOS support this feature. + Otherwise the 8254 will be used for timing services. + + Choose N to continue using the legacy 8254 timer. + config SMP bool "Symmetric multi-processing support" ---help--- @@ -1155,40 +1166,6 @@ menu "Executable file formats" - -choice - prompt "Kernel core (/proc/kcore) format" - depends on PROC_FS - default KCORE_ELF - -config KCORE_ELF - bool "ELF" - ---help--- - If you enabled support for /proc file system then the file - /proc/kcore will contain the kernel core image. This can be used - in gdb: - - $ cd /usr/src/linux ; gdb vmlinux /proc/kcore - - You have two choices here: ELF and A.OUT. Selecting ELF will make - /proc/kcore appear in ELF core format as defined by the Executable - and Linking Format specification. Selecting A.OUT will choose the - old "a.out" format which may be necessary for some old versions - of binutils or on some architectures. - - This is especially useful if you have compiled the kernel with the - "-g" option to preserve debugging information. It is mainly used - for examining kernel data structures on the live kernel so if you - don't understand what this means or are not a kernel hacker, just - leave it at its default value ELF. - -config KCORE_AOUT - bool "A.OUT" - help - Not necessary unless you're using a very out-of-date binutils - version. You probably want KCORE_ELF. - -endchoice source "fs/Kconfig.binfmt" diff -Nru a/arch/i386/kernel/Makefile b/arch/i386/kernel/Makefile --- a/arch/i386/kernel/Makefile Tue Sep 2 19:58:13 2003 +++ b/arch/i386/kernel/Makefile Tue Sep 2 19:58:13 2003 @@ -31,6 +31,7 @@ obj-$(CONFIG_MODULES) += module.o obj-y += sysenter.o vsyscall.o obj-$(CONFIG_ACPI_SRAT) += srat.o +obj-$(CONFIG_HPET_TIMER) += time_hpet.o EXTRA_AFLAGS := -traditional diff -Nru a/arch/i386/kernel/acpi/boot.c b/arch/i386/kernel/acpi/boot.c --- a/arch/i386/kernel/acpi/boot.c Tue Sep 2 19:58:18 2003 +++ b/arch/i386/kernel/acpi/boot.c Tue Sep 2 19:58:18 2003 @@ -41,6 +41,7 @@ #define PREFIX "ACPI: " extern int acpi_disabled; +extern int acpi_irq; extern int acpi_ht; int acpi_lapic = 0; @@ -269,6 +270,27 @@ return 0; } +#ifdef CONFIG_HPET_TIMER +extern unsigned long hpet_address; + +static int __init acpi_parse_hpet(unsigned long phys, unsigned long size) +{ + struct acpi_table_hpet *hpet_tbl; + + hpet_tbl = __va(phys); + + if (hpet_tbl->addr.space_id != ACPI_SPACE_MEM) { + printk(KERN_WARNING PREFIX "HPET timers must be located in " + "memory.\n"); + return -1; + } + + hpet_address = hpet_tbl->addr.addrl; + printk(KERN_INFO PREFIX "HPET id: %#x base: %#lx\n", hpet_tbl->id, + hpet_address); + return 0; +} +#endif unsigned long __init acpi_find_rsdp (void) @@ -407,7 +429,7 @@ * If MPS is present, it will handle them, * otherwise the system will stay in PIC mode */ - if (acpi_disabled) { + if (acpi_disabled || !acpi_irq) { return 1; } @@ -457,6 +479,9 @@ smp_found_config = 1; clustered_apic_check(); } +#endif +#ifdef CONFIG_HPET_TIMER + acpi_table_parse(ACPI_HPET, acpi_parse_hpet); #endif return 0; diff -Nru a/arch/i386/kernel/apic.c b/arch/i386/kernel/apic.c --- a/arch/i386/kernel/apic.c Tue Sep 2 19:58:20 2003 +++ b/arch/i386/kernel/apic.c Tue Sep 2 19:58:20 2003 @@ -34,6 +34,7 @@ #include #include #include +#include #include @@ -779,7 +780,8 @@ return count; } -void __init wait_8254_wraparound(void) +/* next tick in 8254 can be caught by catching timer wraparound */ +static void __init wait_8254_wraparound(void) { unsigned int curr_count, prev_count=~0; int delta; @@ -801,6 +803,12 @@ } /* + * Default initialization for 8254 timers. If we use other timers like HPET, + * we override this later + */ +void (*wait_timer_tick)(void) = wait_8254_wraparound; + +/* * This function sets up the local APIC timer, with a timeout of * 'clocks' APIC bus clock. During calibration we actually call * this function twice on the boot CPU, once with a bogus timeout @@ -841,7 +849,7 @@ /* * Wait for IRQ0's slice: */ - wait_8254_wraparound(); + wait_timer_tick(); __setup_APIC_LVTT(clocks); @@ -884,7 +892,7 @@ * (the current tick might have been already half done) */ - wait_8254_wraparound(); + wait_timer_tick(); /* * We wrapped around just now. Let's start: @@ -897,7 +905,7 @@ * Let's wait LOOPS wraprounds: */ for (i = 0; i < LOOPS; i++) - wait_8254_wraparound(); + wait_timer_tick(); tt2 = apic_read(APIC_TMCCT); if (cpu_has_tsc) diff -Nru a/arch/i386/kernel/cpu/mtrr/if.c b/arch/i386/kernel/cpu/mtrr/if.c --- a/arch/i386/kernel/cpu/mtrr/if.c Tue Sep 2 19:58:14 2003 +++ b/arch/i386/kernel/cpu/mtrr/if.c Tue Sep 2 19:58:14 2003 @@ -17,6 +17,22 @@ #define FILE_FCOUNT(f) (((struct seq_file *)((f)->private_data))->private) +static char *mtrr_strings[MTRR_NUM_TYPES] = +{ + "uncachable", /* 0 */ + "write-combining", /* 1 */ + "?", /* 2 */ + "?", /* 3 */ + "write-through", /* 4 */ + "write-protect", /* 5 */ + "write-back", /* 6 */ +}; + +char *mtrr_attrib_to_str(int x) +{ + return (x <= 6) ? mtrr_strings[x] : "?"; +} + static int mtrr_file_add(unsigned long base, unsigned long size, unsigned int type, char increment, struct file *file, int page) @@ -300,11 +316,6 @@ # endif /* CONFIG_PROC_FS */ -char * attrib_to_str(int x) -{ - return (x <= 6) ? mtrr_strings[x] : "?"; -} - static int mtrr_seq_show(struct seq_file *seq, void *offset) { char factor; @@ -332,7 +343,7 @@ len += seq_printf(seq, "reg%02i: base=0x%05lx000 (%4liMB), size=%4i%cB: %s, count=%d\n", i, base, base >> (20 - PAGE_SHIFT), size, factor, - attrib_to_str(type), usage_table[i]); + mtrr_attrib_to_str(type), usage_table[i]); } } return 0; diff -Nru a/arch/i386/kernel/cpu/mtrr/main.c b/arch/i386/kernel/cpu/mtrr/main.c --- a/arch/i386/kernel/cpu/mtrr/main.c Tue Sep 2 19:58:12 2003 +++ b/arch/i386/kernel/cpu/mtrr/main.c Tue Sep 2 19:58:12 2003 @@ -111,11 +111,6 @@ num_var_ranges = config & 0xff; } -static char * attrib_to_str(int x) -{ - return (x <= 6) ? mtrr_strings[x] : "?"; -} - static void init_table(void) { int i, max; @@ -362,8 +357,8 @@ if (type == MTRR_TYPE_UNCACHABLE) continue; printk (KERN_WARNING "mtrr: type mismatch for %lx000,%lx000 old: %s new: %s\n", - base, size, attrib_to_str(ltype), - attrib_to_str(type)); + base, size, mtrr_attrib_to_str(ltype), + mtrr_attrib_to_str(type)); goto out; } if (increment) @@ -703,16 +698,4 @@ return -ENXIO; } -char *mtrr_strings[MTRR_NUM_TYPES] = -{ - "uncachable", /* 0 */ - "write-combining", /* 1 */ - "?", /* 2 */ - "?", /* 3 */ - "write-through", /* 4 */ - "write-protect", /* 5 */ - "write-back", /* 6 */ -}; - subsys_initcall(mtrr_init); - diff -Nru a/arch/i386/kernel/cpu/mtrr/mtrr.h b/arch/i386/kernel/cpu/mtrr/mtrr.h --- a/arch/i386/kernel/cpu/mtrr/mtrr.h Tue Sep 2 19:58:14 2003 +++ b/arch/i386/kernel/cpu/mtrr/mtrr.h Tue Sep 2 19:58:14 2003 @@ -95,5 +95,6 @@ void finalize_mtrr_state(void); void mtrr_state_warn(void); +char *mtrr_attrib_to_str(int x); extern char * mtrr_if_name[]; diff -Nru a/arch/i386/kernel/cpuid.c b/arch/i386/kernel/cpuid.c --- a/arch/i386/kernel/cpuid.c Tue Sep 2 19:58:12 2003 +++ b/arch/i386/kernel/cpuid.c Tue Sep 2 19:58:12 2003 @@ -115,7 +115,7 @@ u32 data[4]; size_t rv; u32 reg = *ppos; - int cpu = minor(file->f_dentry->d_inode->i_rdev); + int cpu = iminor(file->f_dentry->d_inode); if ( count % 16 ) return -EINVAL; /* Invalid chunk size */ @@ -133,7 +133,7 @@ static int cpuid_open(struct inode *inode, struct file *file) { - int cpu = minor(file->f_dentry->d_inode->i_rdev); + int cpu = iminor(file->f_dentry->d_inode); struct cpuinfo_x86 *c = &(cpu_data)[cpu]; if (!cpu_online(cpu)) diff -Nru a/arch/i386/kernel/mpparse.c b/arch/i386/kernel/mpparse.c --- a/arch/i386/kernel/mpparse.c Tue Sep 2 19:58:14 2003 +++ b/arch/i386/kernel/mpparse.c Tue Sep 2 19:58:14 2003 @@ -850,7 +850,7 @@ return i; } - printk(KERN_ERR "ERROR: Unable to locate IOAPIC for IRQ %d/n", irq); + printk(KERN_ERR "ERROR: Unable to locate IOAPIC for IRQ %d\n", irq); return -1; } diff -Nru a/arch/i386/kernel/msr.c b/arch/i386/kernel/msr.c --- a/arch/i386/kernel/msr.c Tue Sep 2 19:58:15 2003 +++ b/arch/i386/kernel/msr.c Tue Sep 2 19:58:15 2003 @@ -194,7 +194,7 @@ u32 data[2]; size_t rv; u32 reg = *ppos; - int cpu = minor(file->f_dentry->d_inode->i_rdev); + int cpu = iminor(file->f_dentry->d_inode); int err; if ( count % 8 ) @@ -219,7 +219,7 @@ u32 data[2]; size_t rv; u32 reg = *ppos; - int cpu = minor(file->f_dentry->d_inode->i_rdev); + int cpu = iminor(file->f_dentry->d_inode); int err; if ( count % 8 ) @@ -239,7 +239,7 @@ static int msr_open(struct inode *inode, struct file *file) { - int cpu = minor(file->f_dentry->d_inode->i_rdev); + int cpu = iminor(file->f_dentry->d_inode); struct cpuinfo_x86 *c = &(cpu_data)[cpu]; if (!cpu_online(cpu)) diff -Nru a/arch/i386/kernel/process.c b/arch/i386/kernel/process.c --- a/arch/i386/kernel/process.c Tue Sep 2 19:58:12 2003 +++ b/arch/i386/kernel/process.c Tue Sep 2 19:58:12 2003 @@ -452,7 +452,7 @@ /* never put a printk in __switch_to... printk() calls wake_up*() indirectly */ - unlazy_fpu(prev_p); + __unlazy_fpu(prev_p); /* * Reload esp0, LDT and the page table pointer: diff -Nru a/arch/i386/kernel/setup.c b/arch/i386/kernel/setup.c --- a/arch/i386/kernel/setup.c Tue Sep 2 19:58:15 2003 +++ b/arch/i386/kernel/setup.c Tue Sep 2 19:58:15 2003 @@ -71,6 +71,7 @@ EXPORT_SYMBOL(acpi_disabled); #ifdef CONFIG_ACPI_BOOT + int acpi_irq __initdata = 1; /* enable IRQ */ int acpi_ht __initdata = 1; /* enable HT */ #endif @@ -542,6 +543,11 @@ else if (!memcmp(from, "acpi=ht", 7)) { acpi_ht = 1; if (!acpi_force) acpi_disabled = 1; + } + + /* "pci=noacpi" disables ACPI interrupt routing */ + else if (!memcmp(from, "pci=noacpi", 10)) { + acpi_irq = 0; } #ifdef CONFIG_X86_LOCAL_APIC diff -Nru a/arch/i386/kernel/time.c b/arch/i386/kernel/time.c --- a/arch/i386/kernel/time.c Tue Sep 2 19:58:15 2003 +++ b/arch/i386/kernel/time.c Tue Sep 2 19:58:15 2003 @@ -60,6 +60,8 @@ #include #include +#include + #include #include "io_ports.h" @@ -291,8 +293,38 @@ device_initcall(time_init_device); +#ifdef CONFIG_HPET_TIMER +extern void (*late_time_init)(void); +/* Duplicate of time_init() below, with hpet_enable part added */ +void __init hpet_time_init(void) +{ + xtime.tv_sec = get_cmos_time(); + wall_to_monotonic.tv_sec = -xtime.tv_sec; + xtime.tv_nsec = (INITIAL_JIFFIES % HZ) * (NSEC_PER_SEC / HZ); + wall_to_monotonic.tv_nsec = -xtime.tv_nsec; + + if (hpet_enable() >= 0) { + printk("Using HPET for base-timer\n"); + } + + cur_timer = select_timer(); + time_init_hook(); +} +#endif + void __init time_init(void) { +#ifdef CONFIG_HPET_TIMER + if (is_hpet_capable()) { + /* + * HPET initialization needs to do memory-mapped io. So, let + * us do a late initialization after mem_init(). + */ + late_time_init = hpet_time_init; + return; + } +#endif + xtime.tv_sec = get_cmos_time(); wall_to_monotonic.tv_sec = -xtime.tv_sec; xtime.tv_nsec = (INITIAL_JIFFIES % HZ) * (NSEC_PER_SEC / HZ); diff -Nru a/arch/i386/kernel/time_hpet.c b/arch/i386/kernel/time_hpet.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/i386/kernel/time_hpet.c Tue Sep 2 19:58:20 2003 @@ -0,0 +1,392 @@ +/* + * linux/arch/i386/kernel/time_hpet.c + * This code largely copied from arch/x86_64/kernel/time.c + * See that file for credits. + * + * 2003-06-30 Venkatesh Pallipadi - Additional changes for HPET support + */ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include + +#include + +unsigned long hpet_period; /* fsecs / HPET clock */ +unsigned long hpet_tick; /* hpet clks count per tick */ +unsigned long hpet_address; /* hpet memory map physical address */ + +static int use_hpet; /* can be used for runtime check of hpet */ +static int boot_hpet_disable; /* boottime override for HPET timer */ +static unsigned long hpet_virt_address; /* hpet kernel virtual address */ + +#define FSEC_TO_USEC (1000000000UL) + +int hpet_readl(unsigned long a) +{ + return readl(hpet_virt_address + a); +} + +void hpet_writel(unsigned long d, unsigned long a) +{ + writel(d, hpet_virt_address + a); +} + +#ifdef CONFIG_X86_LOCAL_APIC +/* + * HPET counters dont wrap around on every tick. They just change the + * comparator value and continue. Next tick can be caught by checking + * for a change in the comparator value. Used in apic.c. + */ +void __init wait_hpet_tick(void) +{ + unsigned int start_cmp_val, end_cmp_val; + + start_cmp_val = hpet_readl(HPET_T0_CMP); + do { + end_cmp_val = hpet_readl(HPET_T0_CMP); + } while (start_cmp_val == end_cmp_val); +} +#endif + +/* + * Check whether HPET was found by ACPI boot parse. If yes setup HPET + * counter 0 for kernel base timer. + */ +int __init hpet_enable(void) +{ + unsigned int cfg, id; + unsigned long tick_fsec_low, tick_fsec_high; /* tick in femto sec */ + unsigned long hpet_tick_rem; + + if (boot_hpet_disable) + return -1; + + if (!hpet_address) { + return -1; + } + hpet_virt_address = (unsigned long) ioremap_nocache(hpet_address, + HPET_MMAP_SIZE); + /* + * Read the period, compute tick and quotient. + */ + id = hpet_readl(HPET_ID); + + /* + * We are checking for value '1' or more in number field. + * So, we are OK with HPET_EMULATE_RTC part too, where we need + * to have atleast 2 timers. + */ + if (!(id & HPET_ID_NUMBER) || + !(id & HPET_ID_LEGSUP)) + return -1; + + if (((id & HPET_ID_VENDOR) >> HPET_ID_VENDOR_SHIFT) != + HPET_ID_VENDOR_8086) + return -1; + + hpet_period = hpet_readl(HPET_PERIOD); + if ((hpet_period < HPET_MIN_PERIOD) || (hpet_period > HPET_MAX_PERIOD)) + return -1; + + /* + * 64 bit math + * First changing tick into fsec + * Then 64 bit div to find number of hpet clk per tick + */ + ASM_MUL64_REG(tick_fsec_low, tick_fsec_high, + KERNEL_TICK_USEC, FSEC_TO_USEC); + ASM_DIV64_REG(hpet_tick, hpet_tick_rem, + hpet_period, tick_fsec_low, tick_fsec_high); + + if (hpet_tick_rem > (hpet_period >> 1)) + hpet_tick++; /* rounding the result */ + + /* + * Stop the timers and reset the main counter. + */ + cfg = hpet_readl(HPET_CFG); + cfg &= ~HPET_CFG_ENABLE; + hpet_writel(cfg, HPET_CFG); + hpet_writel(0, HPET_COUNTER); + hpet_writel(0, HPET_COUNTER + 4); + + /* + * Set up timer 0, as periodic with first interrupt to happen at + * hpet_tick, and period also hpet_tick. + */ + cfg = hpet_readl(HPET_T0_CFG); + cfg |= HPET_TN_ENABLE | HPET_TN_PERIODIC | + HPET_TN_SETVAL | HPET_TN_32BIT; + hpet_writel(cfg, HPET_T0_CFG); + hpet_writel(hpet_tick, HPET_T0_CMP); + + /* + * Go! + */ + cfg = hpet_readl(HPET_CFG); + cfg |= HPET_CFG_ENABLE | HPET_CFG_LEGACY; + hpet_writel(cfg, HPET_CFG); + + use_hpet = 1; +#ifdef CONFIG_X86_LOCAL_APIC + wait_timer_tick = wait_hpet_tick; +#endif + return 0; +} + +int is_hpet_enabled(void) +{ + return use_hpet; +} + +int is_hpet_capable(void) +{ + if (!boot_hpet_disable && hpet_address) + return 1; + return 0; +} + +static int __init hpet_setup(char* str) +{ + if (str) { + if (!strncmp("disable", str, 7)) + boot_hpet_disable = 1; + } + return 1; +} + +__setup("hpet=", hpet_setup); + +#ifdef CONFIG_HPET_EMULATE_RTC +/* HPET in LegacyReplacement Mode eats up RTC interrupt line. When, HPET + * is enabled, we support RTC interrupt functionality in software. + * RTC has 3 kinds of interrupts: + * 1) Update Interrupt - generate an interrupt, every sec, when RTC clock + * is updated + * 2) Alarm Interrupt - generate an interrupt at a specific time of day + * 3) Periodic Interrupt - generate periodic interrupt, with frequencies + * 2Hz-8192Hz (2Hz-64Hz for non-root user) (all freqs in powers of 2) + * (1) and (2) above are implemented using polling at a frequency of + * 64 Hz. The exact frequency is a tradeoff between accuracy and interrupt + * overhead. (DEFAULT_RTC_INT_FREQ) + * For (3), we use interrupts at 64Hz or user specified periodic + * frequency, whichever is higher. + */ +#include +#include + +extern irqreturn_t rtc_interrupt(int irq, void *dev_id, struct pt_regs *regs); +extern void get_rtc_time(struct rtc_time *rtc_tm); + +#define DEFAULT_RTC_INT_FREQ 64 +#define RTC_NUM_INTS 1 + +static unsigned long UIE_on; +static unsigned long prev_update_sec; + +static unsigned long AIE_on; +static struct rtc_time alarm_time; + +static unsigned long PIE_on; +static unsigned long PIE_freq = DEFAULT_RTC_INT_FREQ; +static unsigned long PIE_count; + +static unsigned long hpet_rtc_int_freq; /* RTC interrupt frequency */ + +/* + * Timer 1 for RTC, we do not use periodic interrupt feature, + * even if HPET supports periodic interrupts on Timer 1. + * The reason being, to set up a periodic interrupt in HPET, we need to + * stop the main counter. And if we do that everytime someone diables/enables + * RTC, we will have adverse effect on main kernel timer running on Timer 0. + * So, for the time being, simulate the periodic interrupt in software. + * + * hpet_rtc_timer_init() is called for the first time and during subsequent + * interuppts reinit happens through hpet_rtc_timer_reinit(). + */ +int hpet_rtc_timer_init(void) +{ + unsigned int cfg, cnt; + unsigned long flags; + + if (!is_hpet_enabled()) + return 0; + /* + * Set the counter 1 and enable the interrupts. + */ + if (PIE_on && (PIE_freq > DEFAULT_RTC_INT_FREQ)) + hpet_rtc_int_freq = PIE_freq; + else + hpet_rtc_int_freq = DEFAULT_RTC_INT_FREQ; + + local_irq_save(flags); + cnt = hpet_readl(HPET_COUNTER); + cnt += ((hpet_tick*HZ)/hpet_rtc_int_freq); + hpet_writel(cnt, HPET_T1_CMP); + local_irq_restore(flags); + + cfg = hpet_readl(HPET_T1_CFG); + cfg |= HPET_TN_ENABLE | HPET_TN_SETVAL | HPET_TN_32BIT; + hpet_writel(cfg, HPET_T1_CFG); + + return 1; +} + +static void hpet_rtc_timer_reinit(void) +{ + unsigned int cfg, cnt; + + if (!(PIE_on | AIE_on | UIE_on)) + return; + + if (PIE_on && (PIE_freq > DEFAULT_RTC_INT_FREQ)) + hpet_rtc_int_freq = PIE_freq; + else + hpet_rtc_int_freq = DEFAULT_RTC_INT_FREQ; + + /* It is more accurate to use the comparator value than current count.*/ + cnt = hpet_readl(HPET_T1_CMP); + cnt += hpet_tick*HZ/hpet_rtc_int_freq; + hpet_writel(cnt, HPET_T1_CMP); + + cfg = hpet_readl(HPET_T1_CFG); + cfg |= HPET_TN_ENABLE | HPET_TN_SETVAL | HPET_TN_32BIT; + hpet_writel(cfg, HPET_T1_CFG); + + return; +} + +/* + * The functions below are called from rtc driver. + * Return 0 if HPET is not being used. + * Otherwise do the necessary changes and return 1. + */ +int hpet_mask_rtc_irq_bit(unsigned long bit_mask) +{ + if (!is_hpet_enabled()) + return 0; + + if (bit_mask & RTC_UIE) + UIE_on = 0; + if (bit_mask & RTC_PIE) + PIE_on = 0; + if (bit_mask & RTC_AIE) + AIE_on = 0; + + return 1; +} + +int hpet_set_rtc_irq_bit(unsigned long bit_mask) +{ + int timer_init_reqd = 0; + + if (!is_hpet_enabled()) + return 0; + + if (!(PIE_on | AIE_on | UIE_on)) + timer_init_reqd = 1; + + if (bit_mask & RTC_UIE) { + UIE_on = 1; + } + if (bit_mask & RTC_PIE) { + PIE_on = 1; + PIE_count = 0; + } + if (bit_mask & RTC_AIE) { + AIE_on = 1; + } + + if (timer_init_reqd) + hpet_rtc_timer_init(); + + return 1; +} + +int hpet_set_alarm_time(unsigned char hrs, unsigned char min, unsigned char sec) +{ + if (!is_hpet_enabled()) + return 0; + + alarm_time.tm_hour = hrs; + alarm_time.tm_min = min; + alarm_time.tm_sec = sec; + + return 1; +} + +int hpet_set_periodic_freq(unsigned long freq) +{ + if (!is_hpet_enabled()) + return 0; + + PIE_freq = freq; + PIE_count = 0; + + return 1; +} + +int hpet_rtc_dropped_irq(void) +{ + if (!is_hpet_enabled()) + return 0; + + return 1; +} + +irqreturn_t hpet_rtc_interrupt(int irq, void *dev_id, struct pt_regs *regs) +{ + struct rtc_time curr_time; + unsigned long rtc_int_flag = 0; + int call_rtc_interrupt = 0; + + hpet_rtc_timer_reinit(); + + if (UIE_on | AIE_on) { + get_rtc_time(&curr_time); + } + if (UIE_on) { + if (curr_time.tm_sec != prev_update_sec) { + /* Set update int info, call real rtc int routine */ + call_rtc_interrupt = 1; + rtc_int_flag = RTC_UF; + prev_update_sec = curr_time.tm_sec; + } + } + if (PIE_on) { + PIE_count++; + if (PIE_count >= hpet_rtc_int_freq/PIE_freq) { + /* Set periodic int info, call real rtc int routine */ + call_rtc_interrupt = 1; + rtc_int_flag |= RTC_PF; + PIE_count = 0; + } + } + if (AIE_on) { + if ((curr_time.tm_sec == alarm_time.tm_sec) && + (curr_time.tm_min == alarm_time.tm_min) && + (curr_time.tm_hour == alarm_time.tm_hour)) { + /* Set alarm int info, call real rtc int routine */ + call_rtc_interrupt = 1; + rtc_int_flag |= RTC_AF; + } + } + if (call_rtc_interrupt) { + rtc_int_flag |= (RTC_IRQF | (RTC_NUM_INTS << 8)); + rtc_interrupt(rtc_int_flag, dev_id, regs); + } + return IRQ_HANDLED; +} +#endif + diff -Nru a/arch/i386/kernel/timers/Makefile b/arch/i386/kernel/timers/Makefile --- a/arch/i386/kernel/timers/Makefile Tue Sep 2 19:58:12 2003 +++ b/arch/i386/kernel/timers/Makefile Tue Sep 2 19:58:12 2003 @@ -5,3 +5,4 @@ obj-y := timer.o timer_none.o timer_tsc.o timer_pit.o obj-$(CONFIG_X86_CYCLONE_TIMER) += timer_cyclone.o +obj-$(CONFIG_HPET_TIMER) += timer_hpet.o diff -Nru a/arch/i386/kernel/timers/timer.c b/arch/i386/kernel/timers/timer.c --- a/arch/i386/kernel/timers/timer.c Tue Sep 2 19:58:19 2003 +++ b/arch/i386/kernel/timers/timer.c Tue Sep 2 19:58:19 2003 @@ -3,10 +3,21 @@ #include #include +#ifdef CONFIG_HPET_TIMER +/* + * HPET memory read is slower than tsc reads, but is more dependable as it + * always runs at constant frequency and reduces complexity due to + * cpufreq. So, we prefer HPET timer to tsc based one. Also, we cannot use + * timer_pit when HPET is active. So, we default to timer_tsc. + */ +#endif /* list of timers, ordered by preference, NULL terminated */ static struct timer_opts* timers[] = { #ifdef CONFIG_X86_CYCLONE_TIMER &timer_cyclone, +#endif +#ifdef CONFIG_HPET_TIMER + &timer_hpet, #endif &timer_tsc, &timer_pit, diff -Nru a/arch/i386/kernel/timers/timer_hpet.c b/arch/i386/kernel/timers/timer_hpet.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/i386/kernel/timers/timer_hpet.c Tue Sep 2 19:58:20 2003 @@ -0,0 +1,241 @@ +/* + * This code largely moved from arch/i386/kernel/time.c. + * See comments there for proper credits. + */ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "io_ports.h" +#include "mach_timer.h" +#include + +static unsigned long hpet_usec_quotient; /* convert hpet clks to usec */ +static unsigned long tsc_hpet_quotient; /* convert tsc to hpet clks */ +static unsigned long hpet_last; /* hpet counter value at last tick*/ +static unsigned long last_tsc_low; /* lsb 32 bits of Time Stamp Counter */ +static unsigned long last_tsc_high; /* msb 32 bits of Time Stamp Counter */ +static unsigned long long monotonic_base; +static rwlock_t monotonic_lock = RW_LOCK_UNLOCKED; + +/* convert from cycles(64bits) => nanoseconds (64bits) + * basic equation: + * ns = cycles / (freq / ns_per_sec) + * ns = cycles * (ns_per_sec / freq) + * ns = cycles * (10^9 / (cpu_mhz * 10^6)) + * ns = cycles * (10^3 / cpu_mhz) + * + * Then we use scaling math (suggested by george@mvista.com) to get: + * ns = cycles * (10^3 * SC / cpu_mhz) / SC + * ns = cycles * cyc2ns_scale / SC + * + * And since SC is a constant power of two, we can convert the div + * into a shift. + * -johnstul@us.ibm.com "math is hard, lets go shopping!" + */ +static unsigned long cyc2ns_scale; +#define CYC2NS_SCALE_FACTOR 10 /* 2^10, carefully chosen */ + +static inline void set_cyc2ns_scale(unsigned long cpu_mhz) +{ + cyc2ns_scale = (1000 << CYC2NS_SCALE_FACTOR)/cpu_mhz; +} + +static inline unsigned long long cycles_2_ns(unsigned long long cyc) +{ + return (cyc * cyc2ns_scale) >> CYC2NS_SCALE_FACTOR; +} + +static unsigned long long monotonic_clock_hpet(void) +{ + unsigned long long last_offset, this_offset, base; + + /* atomically read monotonic base & last_offset */ + read_lock_irq(&monotonic_lock); + last_offset = ((unsigned long long)last_tsc_high<<32)|last_tsc_low; + base = monotonic_base; + read_unlock_irq(&monotonic_lock); + + /* Read the Time Stamp Counter */ + rdtscll(this_offset); + + /* return the value in ns */ + return base + cycles_2_ns(this_offset - last_offset); +} + +static unsigned long get_offset_hpet(void) +{ + register unsigned long eax, edx; + + eax = hpet_readl(HPET_COUNTER); + eax -= hpet_last; /* hpet delta */ + + /* + * Time offset = (hpet delta) * ( usecs per HPET clock ) + * = (hpet delta) * ( usecs per tick / HPET clocks per tick) + * = (hpet delta) * ( hpet_usec_quotient ) / (2^32) + * + * Where, + * hpet_usec_quotient = (2^32 * usecs per tick)/HPET clocks per tick + * + * Using a mull instead of a divl saves some cycles in critical path. + */ + ASM_MUL64_REG(eax, edx, hpet_usec_quotient, eax); + + /* our adjusted time offset in microseconds */ + return edx; +} + +static void mark_offset_hpet(void) +{ + unsigned long long this_offset, last_offset; + unsigned long offset; + + write_lock(&monotonic_lock); + last_offset = ((unsigned long long)last_tsc_high<<32)|last_tsc_low; + rdtsc(last_tsc_low, last_tsc_high); + + offset = hpet_readl(HPET_T0_CMP) - hpet_tick; + if (unlikely(((offset - hpet_last) > hpet_tick) && (hpet_last != 0))) { + int lost_ticks = (offset - hpet_last) / hpet_tick; + jiffies += lost_ticks; + } + hpet_last = offset; + + /* update the monotonic base value */ + this_offset = ((unsigned long long)last_tsc_high<<32)|last_tsc_low; + monotonic_base += cycles_2_ns(this_offset - last_offset); + write_unlock(&monotonic_lock); +} + +void delay_hpet(unsigned long loops) +{ + unsigned long hpet_start, hpet_end; + unsigned long eax; + + /* loops is the number of cpu cycles. Convert it to hpet clocks */ + ASM_MUL64_REG(eax, loops, tsc_hpet_quotient, loops); + + hpet_start = hpet_readl(HPET_COUNTER); + do { + rep_nop(); + hpet_end = hpet_readl(HPET_COUNTER); + } while ((hpet_end - hpet_start) < (loops)); +} + +/* ------ Calibrate the TSC ------- + * Return 2^32 * (1 / (TSC clocks per usec)) for getting the CPU freq. + * Set 2^32 * (1 / (tsc per HPET clk)) for delay_hpet(). + * calibrate_tsc() calibrates the processor TSC by comparing + * it to the HPET timer of known frequency. + * Too much 64-bit arithmetic here to do this cleanly in C + */ +#define CALIBRATE_CNT_HPET (5 * hpet_tick) +#define CALIBRATE_TIME_HPET (5 * KERNEL_TICK_USEC) + +static unsigned long __init calibrate_tsc(void) +{ + unsigned long tsc_startlow, tsc_starthigh; + unsigned long tsc_endlow, tsc_endhigh; + unsigned long hpet_start, hpet_end; + unsigned long result, remain; + + hpet_start = hpet_readl(HPET_COUNTER); + rdtsc(tsc_startlow, tsc_starthigh); + do { + hpet_end = hpet_readl(HPET_COUNTER); + } while ((hpet_end - hpet_start) < CALIBRATE_CNT_HPET); + rdtsc(tsc_endlow, tsc_endhigh); + + /* 64-bit subtract - gcc just messes up with long longs */ + __asm__("subl %2,%0\n\t" + "sbbl %3,%1" + :"=a" (tsc_endlow), "=d" (tsc_endhigh) + :"g" (tsc_startlow), "g" (tsc_starthigh), + "0" (tsc_endlow), "1" (tsc_endhigh)); + + /* Error: ECPUTOOFAST */ + if (tsc_endhigh) + goto bad_calibration; + + /* Error: ECPUTOOSLOW */ + if (tsc_endlow <= CALIBRATE_TIME_HPET) + goto bad_calibration; + + ASM_DIV64_REG(result, remain, tsc_endlow, 0, CALIBRATE_TIME_HPET); + if (remain > (tsc_endlow >> 1)) + result++; /* rounding the result */ + + ASM_DIV64_REG(tsc_hpet_quotient, remain, tsc_endlow, 0, + CALIBRATE_CNT_HPET); + if (remain > (tsc_endlow >> 1)) + tsc_hpet_quotient++; /* rounding the result */ + + return result; +bad_calibration: + /* + * the CPU was so fast/slow that the quotient wouldn't fit in + * 32 bits.. + */ + return 0; +} + +static int __init init_hpet(char* override) +{ + unsigned long result, remain; + + /* check clock override */ + if (override[0] && strncmp(override,"hpet",4)) + return -ENODEV; + + if (!is_hpet_enabled()) + return -ENODEV; + + printk("Using HPET for gettimeofday\n"); + if (cpu_has_tsc) { + unsigned long tsc_quotient = calibrate_tsc(); + if (tsc_quotient) { + /* report CPU clock rate in Hz. + * The formula is (10^6 * 2^32) / (2^32 * 1 / (clocks/us)) = + * clock/second. Our precision is about 100 ppm. + */ + { unsigned long eax=0, edx=1000; + ASM_DIV64_REG(cpu_khz, edx, tsc_quotient, + eax, edx); + printk("Detected %lu.%03lu MHz processor.\n", + cpu_khz / 1000, cpu_khz % 1000); + } + set_cyc2ns_scale(cpu_khz/1000); + } + } + + /* + * Math to calculate hpet to usec multiplier + * Look for the comments at get_offset_hpet() + */ + ASM_DIV64_REG(result, remain, hpet_tick, 0, KERNEL_TICK_USEC); + if (remain > (hpet_tick >> 1)) + result++; /* rounding the result */ + hpet_usec_quotient = result; + + return 0; +} + +/************************************************************/ + +/* tsc timer_opts struct */ +struct timer_opts timer_hpet = { + .init = init_hpet, + .mark_offset = mark_offset_hpet, + .get_offset = get_offset_hpet, + .monotonic_clock = monotonic_clock_hpet, + .delay = delay_hpet, +}; diff -Nru a/arch/i386/kernel/timers/timer_tsc.c b/arch/i386/kernel/timers/timer_tsc.c --- a/arch/i386/kernel/timers/timer_tsc.c Tue Sep 2 19:58:17 2003 +++ b/arch/i386/kernel/timers/timer_tsc.c Tue Sep 2 19:58:17 2003 @@ -19,9 +19,18 @@ #include "io_ports.h" #include "mach_timer.h" +#include + +#ifdef CONFIG_HPET_TIMER +static unsigned long hpet_usec_quotient; +static unsigned long hpet_last; +struct timer_opts timer_tsc; +#endif + int tsc_disable __initdata = 0; extern spinlock_t i8253_lock; +extern volatile unsigned long jiffies; static int use_tsc; /* Number of usecs that the last interrupt was delayed */ @@ -232,7 +241,7 @@ #define CALIBRATE_TIME (5 * 1000020/HZ) -unsigned long __init calibrate_tsc(void) +static unsigned long __init calibrate_tsc(void) { mach_prepare_counter(); @@ -282,6 +291,107 @@ return 0; } +#ifdef CONFIG_HPET_TIMER +static void mark_offset_tsc_hpet(void) +{ + unsigned long long this_offset, last_offset; + unsigned long offset, temp, hpet_current; + + write_lock(&monotonic_lock); + last_offset = ((unsigned long long)last_tsc_high<<32)|last_tsc_low; + /* + * It is important that these two operations happen almost at + * the same time. We do the RDTSC stuff first, since it's + * faster. To avoid any inconsistencies, we need interrupts + * disabled locally. + */ + /* + * Interrupts are just disabled locally since the timer irq + * has the SA_INTERRUPT flag set. -arca + */ + /* read Pentium cycle counter */ + + hpet_current = hpet_readl(HPET_COUNTER); + rdtsc(last_tsc_low, last_tsc_high); + + /* lost tick compensation */ + offset = hpet_readl(HPET_T0_CMP) - hpet_tick; + if (unlikely(((offset - hpet_last) > hpet_tick) && (hpet_last != 0))) { + int lost_ticks = (offset - hpet_last) / hpet_tick; + jiffies += lost_ticks; + } + hpet_last = hpet_current; + + /* update the monotonic base value */ + this_offset = ((unsigned long long)last_tsc_high<<32)|last_tsc_low; + monotonic_base += cycles_2_ns(this_offset - last_offset); + write_unlock(&monotonic_lock); + + /* calculate delay_at_last_interrupt */ + /* + * Time offset = (hpet delta) * ( usecs per HPET clock ) + * = (hpet delta) * ( usecs per tick / HPET clocks per tick) + * = (hpet delta) * ( hpet_usec_quotient ) / (2^32) + * Where, + * hpet_usec_quotient = (2^32 * usecs per tick)/HPET clocks per tick + */ + delay_at_last_interrupt = hpet_current - offset; + ASM_MUL64_REG(temp, delay_at_last_interrupt, + hpet_usec_quotient, delay_at_last_interrupt); +} + +/* ------ Calibrate the TSC based on HPET timer ------- + * Return 2^32 * (1 / (TSC clocks per usec)) for do_fast_gettimeoffset(). + * calibrate_tsc() calibrates the processor TSC by comparing + * it to the HPET timer of known frequency. + * Too much 64-bit arithmetic here to do this cleanly in C + */ + +#define CALIBRATE_CNT_HPET (5 * hpet_tick) +#define CALIBRATE_TIME_HPET (5 * KERNEL_TICK_USEC) + +unsigned long __init calibrate_tsc_hpet(void) +{ + unsigned long tsc_startlow, tsc_starthigh; + unsigned long tsc_endlow, tsc_endhigh; + unsigned long hpet_start, hpet_end; + unsigned long result, remain; + + hpet_start = hpet_readl(HPET_COUNTER); + rdtsc(tsc_startlow, tsc_starthigh); + do { + hpet_end = hpet_readl(HPET_COUNTER); + } while ((hpet_end - hpet_start) < CALIBRATE_CNT_HPET); + rdtsc(tsc_endlow, tsc_endhigh); + + /* 64-bit subtract - gcc just messes up with long longs */ + __asm__("subl %2,%0\n\t" + "sbbl %3,%1" + :"=a" (tsc_endlow), "=d" (tsc_endhigh) + :"g" (tsc_startlow), "g" (tsc_starthigh), + "0" (tsc_endlow), "1" (tsc_endhigh)); + + /* Error: ECPUTOOFAST */ + if (tsc_endhigh) + goto bad_calibration; + + /* Error: ECPUTOOSLOW */ + if (tsc_endlow <= CALIBRATE_TIME_HPET) + goto bad_calibration; + + ASM_DIV64_REG(result, remain, tsc_endlow, 0, CALIBRATE_TIME_HPET); + if (remain > (tsc_endlow >> 1)) + result++; /* rounding the result */ + + return result; +bad_calibration: + /* + * the CPU was so fast/slow that the quotient wouldn't fit in + * 32 bits.. + */ + return 0; +} +#endif #ifdef CONFIG_CPU_FREQ static unsigned int ref_freq = 0; @@ -333,8 +443,16 @@ { /* check clock override */ - if (override[0] && strncmp(override,"tsc",3)) + if (override[0] && strncmp(override,"tsc",3)) { +#ifdef CONFIG_HPET_TIMER + if (is_hpet_enabled()) { + printk(KERN_ERR "Warning: clock= override failed. Defaulting to tsc\n"); + } else +#endif + { return -ENODEV; + } + } /* * If we have APM enabled or the CPU clock speed is variable @@ -368,7 +486,29 @@ count2 = LATCH; /* initialize counter for mark_offset_tsc() */ if (cpu_has_tsc) { - unsigned long tsc_quotient = calibrate_tsc(); + unsigned long tsc_quotient; +#ifdef CONFIG_HPET_TIMER + if (is_hpet_enabled()){ + unsigned long result, remain; + printk("Using TSC for gettimeofday\n"); + tsc_quotient = calibrate_tsc_hpet(); + timer_tsc.mark_offset = &mark_offset_tsc_hpet; + /* + * Math to calculate hpet to usec multiplier + * Look for the comments at get_offset_tsc_hpet() + */ + ASM_DIV64_REG(result, remain, hpet_tick, + 0, KERNEL_TICK_USEC); + if (remain > (hpet_tick >> 1)) + result++; /* rounding the result */ + + hpet_usec_quotient = result; + } else +#endif + { + tsc_quotient = calibrate_tsc(); + } + if (tsc_quotient) { fast_gettimeoffset_quotient = tsc_quotient; use_tsc = 1; diff -Nru a/arch/i386/kernel/traps.c b/arch/i386/kernel/traps.c --- a/arch/i386/kernel/traps.c Tue Sep 2 19:58:13 2003 +++ b/arch/i386/kernel/traps.c Tue Sep 2 19:58:13 2003 @@ -745,7 +745,8 @@ * Careful.. There are problems with IBM-designed IRQ13 behaviour. * Don't touch unless you *really* know how it works. * - * Must be called with kernel preemption disabled. + * Must be called with kernel preemption disabled (in this case, + * local interrupts are disabled at the call-site in entry.S). */ asmlinkage void math_state_restore(struct pt_regs regs) { diff -Nru a/arch/i386/mach-visws/mpparse.c b/arch/i386/mach-visws/mpparse.c --- a/arch/i386/mach-visws/mpparse.c Tue Sep 2 19:58:14 2003 +++ b/arch/i386/mach-visws/mpparse.c Tue Sep 2 19:58:14 2003 @@ -38,7 +38,7 @@ void __init MP_processor_info (struct mpc_config_processor *m) { int ver, logical_apicid; - cpumask_t apic_cpus; + physid_mask_t apic_cpus; if (!(m->mpc_cpuflag & CPU_ENABLED)) return; diff -Nru a/arch/i386/mach-voyager/voyager_smp.c b/arch/i386/mach-voyager/voyager_smp.c --- a/arch/i386/mach-voyager/voyager_smp.c Tue Sep 2 19:58:15 2003 +++ b/arch/i386/mach-voyager/voyager_smp.c Tue Sep 2 19:58:15 2003 @@ -130,7 +130,7 @@ { int cpu; - for_each_cpu(cpu, mk_cpumask_const(cpu_online_map)) { + for_each_cpu(cpu, cpu_online_map) { if(cpuset & (1<> 2; if (c->x86 >= 6 && c->x86_vendor == X86_VENDOR_AMD) pci_cache_line_size = 64 >> 2; /* K7 & K8 */ - else if (c->x86 > 6) + else if (c->x86 > 6 && c->x86_vendor == X86_VENDOR_INTEL) pci_cache_line_size = 128 >> 2; /* P4 */ pcibios_resource_survey(); diff -Nru a/arch/ia64/Kconfig b/arch/ia64/Kconfig --- a/arch/ia64/Kconfig Tue Sep 2 19:58:19 2003 +++ b/arch/ia64/Kconfig Tue Sep 2 19:58:19 2003 @@ -234,8 +234,8 @@ endchoice config DISCONTIGMEM - bool "Discontiguous memory support" if (IA64_DIG && NUMA) - default y if IA64_SGI_SN2 || IA64_GENERIC + bool "Discontiguous memory support" if (IA64_DIG || IA64_SGI_SN2 || IA64_GENERIC) && NUMA + default y if (IA64_SGI_SN2 || IA64_GENERIC) && NUMA help Say Y to support efficient handling of discontiguous physical memory, for architectures which are either NUMA (Non-Uniform Memory Access) @@ -296,29 +296,6 @@ help If you are compiling a kernel that will run under SGI's IA-64 simulator (Medusa) then say Y, otherwise say N. - -# On IA-64, we always want an ELF /proc/kcore. -config KCORE_ELF - bool - default y - ---help--- - If you enabled support for /proc file system then the file - /proc/kcore will contain the kernel core image. This can be used - in gdb: - - $ cd /usr/src/linux ; gdb vmlinux /proc/kcore - - You have two choices here: ELF and A.OUT. Selecting ELF will make - /proc/kcore appear in ELF core format as defined by the Executable - and Linking Format specification. Selecting A.OUT will choose the - old "a.out" format which may be necessary for some old versions - of binutils or on some architectures. - - This is especially useful if you have compiled the kernel with the - "-g" option to preserve debugging information. It is mainly used - for examining kernel data structures on the live kernel so if you - don't understand what this means or are not a kernel hacker, just - leave it at its default value ELF. config FORCE_MAX_ZONEORDER int diff -Nru a/arch/ia64/Makefile b/arch/ia64/Makefile --- a/arch/ia64/Makefile Tue Sep 2 19:58:12 2003 +++ b/arch/ia64/Makefile Tue Sep 2 19:58:12 2003 @@ -70,6 +70,8 @@ .PHONY: boot compressed check +all: compressed + compressed: vmlinux.gz vmlinux.gz: vmlinux @@ -100,6 +102,6 @@ define archhelp - echo ' compressed - Build compressed kernel image' + echo '* compressed - Build compressed kernel image' echo ' boot - Build vmlinux and bootloader for Ski simulator' endef diff -Nru a/arch/ia64/hp/common/sba_iommu.c b/arch/ia64/hp/common/sba_iommu.c --- a/arch/ia64/hp/common/sba_iommu.c Tue Sep 2 19:58:13 2003 +++ b/arch/ia64/hp/common/sba_iommu.c Tue Sep 2 19:58:13 2003 @@ -1935,10 +1935,10 @@ } static struct acpi_driver acpi_sba_ioc_driver = { - name: "IOC IOMMU Driver", - ids: "HWP0001,HWP0004", - ops: { - add: acpi_sba_ioc_add, + .name = "IOC IOMMU Driver", + .ids = "HWP0001,HWP0004", + .ops = { + .add = acpi_sba_ioc_add, }, }; diff -Nru a/arch/ia64/ia32/ia32_ioctl.c b/arch/ia64/ia32/ia32_ioctl.c --- a/arch/ia64/ia32/ia32_ioctl.c Tue Sep 2 19:58:17 2003 +++ b/arch/ia64/ia32/ia32_ioctl.c Tue Sep 2 19:58:17 2003 @@ -70,7 +70,7 @@ #define IOCTL_TABLE_START \ struct ioctl_trans ioctl_start[] = { #define IOCTL_TABLE_END \ - }; struct ioctl_trans ioctl_end[0]; + }; IOCTL_TABLE_START HANDLE_IOCTL(VFAT_IOCTL_READDIR_BOTH32, vfat_ioctl32) @@ -79,3 +79,5 @@ #include "compat_ioctl.c" #include IOCTL_TABLE_END + +int ioctl_table_size = ARRAY_SIZE(ioctl_start); diff -Nru a/arch/ia64/ia32/sys_ia32.c b/arch/ia64/ia32/sys_ia32.c --- a/arch/ia64/ia32/sys_ia32.c Tue Sep 2 19:58:16 2003 +++ b/arch/ia64/ia32/sys_ia32.c Tue Sep 2 19:58:16 2003 @@ -76,7 +76,6 @@ #define OFFSET4K(a) ((a) & 0xfff) #define PAGE_START(addr) ((addr) & PAGE_MASK) -#define PAGE_OFF(addr) ((addr) & ~PAGE_MASK) #define high2lowuid(uid) ((uid) > 65535 ? 65534 : (uid)) #define high2lowgid(gid) ((gid) > 65535 ? 65534 : (gid)) @@ -170,9 +169,9 @@ current->thread.map_base = old_map_base; current->thread.task_size = old_task_size; set_fs(USER_DS); /* establish new task-size as the address-limit */ - out: - kfree(av); } + out: + kfree(av); return r; } @@ -271,11 +270,11 @@ if (old_prot) { /* copy back the old page contents. */ - if (PAGE_OFF(start)) - copy_to_user((void *) PAGE_START(start), page, PAGE_OFF(start)); - if (PAGE_OFF(end)) - copy_to_user((void *) end, page + PAGE_OFF(end), - PAGE_SIZE - PAGE_OFF(end)); + if (offset_in_page(start)) + copy_to_user((void *) PAGE_START(start), page, offset_in_page(start)); + if (offset_in_page(end)) + copy_to_user((void *) end, page + offset_in_page(end), + PAGE_SIZE - offset_in_page(end)); } if (!(flags & MAP_ANONYMOUS)) { @@ -330,7 +329,7 @@ "%s(%d): emulate_mmap() can't share tail (end=0x%lx)\n", current->comm, current->pid, end); ret = mmap_subpage(file, max(start, PAGE_START(end)), end, prot, flags, - (off + len) - PAGE_OFF(end)); + (off + len) - offset_in_page(end)); if (IS_ERR((void *) ret)) return ret; pend -= PAGE_SIZE; @@ -347,14 +346,14 @@ tmp = arch_get_unmapped_area(file, pstart - fudge, pend - pstart, 0, flags); if (tmp != pstart) { pstart = tmp; - start = pstart + PAGE_OFF(off); /* make start congruent with off */ + start = pstart + offset_in_page(off); /* make start congruent with off */ end = start + len; pend = PAGE_ALIGN(end); } } poff = off + (pstart - start); /* note: (pstart - start) may be negative */ - is_congruent = (flags & MAP_ANONYMOUS) || (PAGE_OFF(poff) == 0); + is_congruent = (flags & MAP_ANONYMOUS) || (offset_in_page(poff) == 0); if ((flags & MAP_SHARED) && !is_congruent) printk(KERN_INFO "%s(%d): emulate_mmap() can't share contents of incongruent mmap " @@ -588,7 +587,7 @@ down(&ia32_mmap_sem); { - if (PAGE_OFF(start)) { + if (offset_in_page(start)) { /* start address is 4KB aligned but not page aligned. */ retval = mprotect_subpage(PAGE_START(start), prot); if (retval < 0) @@ -599,7 +598,7 @@ goto out; /* retval is already zero... */ } - if (PAGE_OFF(end)) { + if (offset_in_page(end)) { /* end address is 4KB aligned but not page aligned. */ retval = mprotect_subpage(PAGE_START(end), prot); if (retval < 0) diff -Nru a/arch/ia64/kernel/acpi.c b/arch/ia64/kernel/acpi.c --- a/arch/ia64/kernel/acpi.c Tue Sep 2 19:58:15 2003 +++ b/arch/ia64/kernel/acpi.c Tue Sep 2 19:58:15 2003 @@ -130,7 +130,7 @@ int vector = -1; if (int_type < ACPI_MAX_PLATFORM_INTERRUPTS) { - /* correctable platform error interrupt */ + /* corrected platform error interrupt */ vector = platform_intr_list[int_type]; } else printk(KERN_ERR "acpi_request_vector(): invalid interrupt type\n"); diff -Nru a/arch/ia64/kernel/entry.S b/arch/ia64/kernel/entry.S --- a/arch/ia64/kernel/entry.S Tue Sep 2 19:58:14 2003 +++ b/arch/ia64/kernel/entry.S Tue Sep 2 19:58:14 2003 @@ -1473,7 +1473,7 @@ data8 sys_clock_nanosleep data8 sys_fstatfs64 data8 sys_statfs64 - data8 ia64_ni_syscall + data8 sys_fadvise64_64 data8 ia64_ni_syscall // 1260 data8 ia64_ni_syscall data8 ia64_ni_syscall diff -Nru a/arch/ia64/kernel/fsys.S b/arch/ia64/kernel/fsys.S --- a/arch/ia64/kernel/fsys.S Tue Sep 2 19:58:12 2003 +++ b/arch/ia64/kernel/fsys.S Tue Sep 2 19:58:12 2003 @@ -678,9 +678,9 @@ data8 0 // clock_gettime data8 0 // clock_getres // 1255 data8 0 // clock_nanosleep - data8 0 - data8 0 - data8 0 + data8 0 // fstatfs64 + data8 0 // statfs64 + data8 0 // fadvise64_64 data8 0 // 1260 data8 0 data8 0 diff -Nru a/arch/ia64/kernel/mca.c b/arch/ia64/kernel/mca.c --- a/arch/ia64/kernel/mca.c Tue Sep 2 19:58:15 2003 +++ b/arch/ia64/kernel/mca.c Tue Sep 2 19:58:15 2003 @@ -1145,7 +1145,7 @@ ia64_mca_cmc_int_handler(cpe_irq, arg, ptregs); - for (++cpuid ; !cpu_online(cpuid) && cpuid < NR_CPUS ; cpuid++); + for (++cpuid ; cpuid < NR_CPUS && !cpu_online(cpuid) ; cpuid++); if (cpuid < NR_CPUS) { platform_send_ipi(cpuid, IA64_CMCP_VECTOR, IA64_IPI_DM_INT, 0); @@ -1225,7 +1225,7 @@ ia64_mca_cpe_int_handler(cpe_irq, arg, ptregs); - for (++cpuid ; !cpu_online(cpuid) && cpuid < NR_CPUS ; cpuid++); + for (++cpuid ; cpuid < NR_CPUS && !cpu_online(cpuid) ; cpuid++); if (cpuid < NR_CPUS) { platform_send_ipi(cpuid, IA64_CPEP_VECTOR, IA64_IPI_DM_INT, 0); diff -Nru a/arch/ia64/kernel/perfmon.c b/arch/ia64/kernel/perfmon.c --- a/arch/ia64/kernel/perfmon.c Tue Sep 2 19:58:19 2003 +++ b/arch/ia64/kernel/perfmon.c Tue Sep 2 19:58:19 2003 @@ -2109,7 +2109,7 @@ return 1; } static struct dentry_operations pfmfs_dentry_operations = { - d_delete: pfmfs_delete_dentry, + .d_delete = pfmfs_delete_dentry, }; diff -Nru a/arch/ia64/kernel/smpboot.c b/arch/ia64/kernel/smpboot.c --- a/arch/ia64/kernel/smpboot.c Tue Sep 2 19:58:14 2003 +++ b/arch/ia64/kernel/smpboot.c Tue Sep 2 19:58:14 2003 @@ -560,7 +560,7 @@ if (cpu_online(cpu)) bogosum += cpu_data(cpu)->loops_per_jiffy; - printk(KERN_INFO "Total of %d processors activated (%lu.%02lu BogoMIPS).\n", + printk(KERN_INFO "Total of %lu processors activated (%lu.%02lu BogoMIPS).\n", num_online_cpus(), bogosum/(500000/HZ), (bogosum/(5000/HZ))%100); } diff -Nru a/arch/ia64/kernel/sys_ia64.c b/arch/ia64/kernel/sys_ia64.c --- a/arch/ia64/kernel/sys_ia64.c Tue Sep 2 19:58:16 2003 +++ b/arch/ia64/kernel/sys_ia64.c Tue Sep 2 19:58:16 2003 @@ -242,7 +242,7 @@ asmlinkage unsigned long sys_mmap (unsigned long addr, unsigned long len, int prot, int flags, int fd, long off) { - if ((off & ~PAGE_MASK) != 0) + if (offset_in_page(off) != 0) return -EINVAL; addr = do_mmap2(addr, len, prot, flags, fd, off >> PAGE_SHIFT); diff -Nru a/arch/ia64/lib/Makefile b/arch/ia64/lib/Makefile --- a/arch/ia64/lib/Makefile Tue Sep 2 19:58:19 2003 +++ b/arch/ia64/lib/Makefile Tue Sep 2 19:58:19 2003 @@ -14,9 +14,6 @@ lib-$(CONFIG_PERFMON) += carta_random.o lib-$(CONFIG_MD_RAID5) += xor.o -IGNORE_FLAGS_OBJS = __divsi3.o __udivsi3.o __modsi3.o __umodsi3.o \ - __divdi3.o __udivdi3.o __moddi3.o __umoddi3.o - AFLAGS___divdi3.o = AFLAGS___udivdi3.o = -DUNSIGNED AFLAGS___moddi3.o = -DMODULO @@ -27,26 +24,26 @@ AFLAGS___modsi3.o = -DMODULO AFLAGS___umodsi3.o = -DUNSIGNED -DMODULO -$(obj)/__divdi3.o: $(src)/idiv64.S - $(cmd_as_o_S) +$(obj)/__divdi3.o: $(src)/idiv64.S FORCE + $(call if_changed_dep,as_o_S) -$(obj)/__udivdi3.o: $(src)/idiv64.S - $(cmd_as_o_S) +$(obj)/__udivdi3.o: $(src)/idiv64.S FORCE + $(call if_changed_dep,as_o_S) -$(obj)/__moddi3.o: $(src)/idiv64.S - $(cmd_as_o_S) +$(obj)/__moddi3.o: $(src)/idiv64.S FORCE + $(call if_changed_dep,as_o_S) -$(obj)/__umoddi3.o: $(src)/idiv64.S - $(cmd_as_o_S) +$(obj)/__umoddi3.o: $(src)/idiv64.S FORCE + $(call if_changed_dep,as_o_S) -$(obj)/__divsi3.o: $(src)/idiv32.S - $(cmd_as_o_S) +$(obj)/__divsi3.o: $(src)/idiv32.S FORCE + $(call if_changed_dep,as_o_S) -$(obj)/__udivsi3.o: $(src)/idiv32.S - $(cmd_as_o_S) +$(obj)/__udivsi3.o: $(src)/idiv32.S FORCE + $(call if_changed_dep,as_o_S) -$(obj)/__modsi3.o: $(src)/idiv32.S - $(cmd_as_o_S) +$(obj)/__modsi3.o: $(src)/idiv32.S FORCE + $(call if_changed_dep,as_o_S) -$(obj)/__umodsi3.o: $(src)/idiv32.S - $(cmd_as_o_S) +$(obj)/__umodsi3.o: $(src)/idiv32.S FORCE + $(call if_changed_dep,as_o_S) diff -Nru a/arch/ia64/mm/numa.c b/arch/ia64/mm/numa.c --- a/arch/ia64/mm/numa.c Tue Sep 2 19:58:14 2003 +++ b/arch/ia64/mm/numa.c Tue Sep 2 19:58:14 2003 @@ -42,5 +42,5 @@ paddr < node_memblk[i].start_paddr + node_memblk[i].size) break; - return (i < num_memblks) ? node_memblk[i].nid : -1; + return (i < num_memblks) ? node_memblk[i].nid : (num_memblks ? -1 : 0); } diff -Nru a/arch/ia64/sn/io/drivers/ioconfig_bus.c b/arch/ia64/sn/io/drivers/ioconfig_bus.c --- a/arch/ia64/sn/io/drivers/ioconfig_bus.c Tue Sep 2 19:58:17 2003 +++ b/arch/ia64/sn/io/drivers/ioconfig_bus.c Tue Sep 2 19:58:17 2003 @@ -346,9 +346,9 @@ } struct file_operations ioconfig_bus_fops = { - ioctl:ioconfig_bus_ioctl, - open:ioconfig_bus_open, /* open */ - release:ioconfig_bus_close /* release */ + .ioctl = ioconfig_bus_ioctl, + .open = ioconfig_bus_open, /* open */ + .release = ioconfig_bus_close /* release */ }; diff -Nru a/arch/ia64/sn/io/sn2/shub.c b/arch/ia64/sn/io/sn2/shub.c --- a/arch/ia64/sn/io/sn2/shub.c Tue Sep 2 19:58:16 2003 +++ b/arch/ia64/sn/io/sn2/shub.c Tue Sep 2 19:58:16 2003 @@ -243,7 +243,7 @@ } struct file_operations shub_mon_fops = { - ioctl: shubstats_ioctl, + .ioctl = shubstats_ioctl, }; /* diff -Nru a/arch/ia64/sn/kernel/setup.c b/arch/ia64/sn/kernel/setup.c --- a/arch/ia64/sn/kernel/setup.c Tue Sep 2 19:58:14 2003 +++ b/arch/ia64/sn/kernel/setup.c Tue Sep 2 19:58:14 2003 @@ -117,14 +117,14 @@ * VGA color display. */ struct screen_info sn_screen_info = { - orig_x: 0, - orig_y: 0, - orig_video_mode: 3, - orig_video_cols: 80, - orig_video_ega_bx: 3, - orig_video_lines: 25, - orig_video_isVGA: 1, - orig_video_points: 16 + .orig_x = 0, + .orig_y = 0, + .orig_video_mode = 3, + .orig_video_cols = 80, + .orig_video_ega_bx = 3, + .orig_video_lines = 25, + .orig_video_isVGA = 1, + .orig_video_points = 16 }; /* diff -Nru a/arch/m68k/Kconfig b/arch/m68k/Kconfig --- a/arch/m68k/Kconfig Tue Sep 2 19:58:16 2003 +++ b/arch/m68k/Kconfig Tue Sep 2 19:58:16 2003 @@ -342,40 +342,6 @@ menu "General setup" -choice - prompt "Kernel core (/proc/kcore) format" - depends on PROC_FS - default KCORE_ELF - -config KCORE_ELF - bool "ELF" - ---help--- - If you enabled support for /proc file system then the file - /proc/kcore will contain the kernel core image. This can be used - in gdb: - - $ cd /usr/src/linux ; gdb vmlinux /proc/kcore - - You have two choices here: ELF and A.OUT. Selecting ELF will make - /proc/kcore appear in ELF core format as defined by the Executable - and Linking Format specification. Selecting A.OUT will choose the - old "a.out" format which may be necessary for some old versions - of binutils or on some architectures. - - This is especially useful if you have compiled the kernel with the - "-g" option to preserve debugging information. It is mainly used - for examining kernel data structures on the live kernel so if you - don't understand what this means or are not a kernel hacker, just - leave it at its default value ELF. - -config KCORE_AOUT - bool "A.OUT" - help - Not necessary unless you're using a very out-of-date binutils - version. You probably want KCORE_ELF. - -endchoice - source "fs/Kconfig.binfmt" config ZORRO diff -Nru a/arch/m68k/kernel/vmlinux-std.lds b/arch/m68k/kernel/vmlinux-std.lds --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/m68k/kernel/vmlinux-std.lds Tue Sep 2 19:58:18 2003 @@ -0,0 +1,97 @@ +/* ld script to make m68k Linux kernel */ + +#include + +OUTPUT_FORMAT("elf32-m68k", "elf32-m68k", "elf32-m68k") +OUTPUT_ARCH(m68k) +ENTRY(_start) +jiffies = jiffies_64 + 4; +SECTIONS +{ + . = 0x1000; + _text = .; /* Text and read-only data */ + .text : { + *(.text) + *(.fixup) + *(.gnu.warning) + } = 0x4e75 + + . = ALIGN(16); /* Exception table */ + __start___ex_table = .; + __ex_table : { *(__ex_table) } + __stop___ex_table = .; + + RODATA + + _etext = .; /* End of text section */ + + .data : { /* Data */ + *(.data) + CONSTRUCTORS + } + + .bss : { *(.bss) } /* BSS */ + + . = ALIGN(16); + .data.cacheline_aligned : { *(.data.cacheline_aligned) } + + _edata = .; /* End of data section */ + + /* will be freed after init */ + . = ALIGN(4096); /* Init code and data */ + __init_begin = .; + .init.text : { + _sinittext = .; + *(.init.text) + _einittext = .; + } + .init.data : { *(.init.data) } + . = ALIGN(16); + __setup_start = .; + .init.setup : { *(.init.setup) } + __setup_end = .; + __start___param = .; + __param : { *(__param) } + __stop___param = .; + __initcall_start = .; + .initcall.init : { + *(.initcall1.init) + *(.initcall2.init) + *(.initcall3.init) + *(.initcall4.init) + *(.initcall5.init) + *(.initcall6.init) + *(.initcall7.init) + } + __initcall_end = .; + __con_initcall_start = .; + .con_initcall.init : { *(.con_initcall.init) } + __con_initcall_end = .; + SECURITY_INIT + . = ALIGN(8192); + __initramfs_start = .; + .init.ramfs : { *(.init.ramfs) } + __initramfs_end = .; + . = ALIGN(8192); + __init_end = .; + + .data.init_task : { *(.data.init_task) } /* The initial task and kernel stack */ + + _end = . ; + + /* Sections to be discarded */ + /DISCARD/ : { + *(.exit.text) + *(.exit.data) + *(.exitcall.exit) + } + + /* Stabs debugging sections. */ + .stab 0 : { *(.stab) } + .stabstr 0 : { *(.stabstr) } + .stab.excl 0 : { *(.stab.excl) } + .stab.exclstr 0 : { *(.stab.exclstr) } + .stab.index 0 : { *(.stab.index) } + .stab.indexstr 0 : { *(.stab.indexstr) } + .comment 0 : { *(.comment) } +} diff -Nru a/arch/m68k/kernel/vmlinux-sun3.lds b/arch/m68k/kernel/vmlinux-sun3.lds --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/m68k/kernel/vmlinux-sun3.lds Tue Sep 2 19:58:12 2003 @@ -0,0 +1,97 @@ +/* ld script to make m68k Linux kernel */ + +#include + +OUTPUT_FORMAT("elf32-m68k", "elf32-m68k", "elf32-m68k") +OUTPUT_ARCH(m68k) +ENTRY(_start) +jiffies = jiffies_64 + 4; +SECTIONS +{ + . = 0xE004000; + _text = .; /* Text and read-only data */ + .text : { + *(.head) + *(.text) + *(.fixup) + *(.gnu.warning) + } = 0x4e75 + RODATA + + _etext = .; /* End of text section */ + + .data : { /* Data */ + *(.data) + CONSTRUCTORS + . = ALIGN(16); /* Exception table */ + __start___ex_table = .; + *(__ex_table) + __stop___ex_table = .; + } + /* End of data goes *here* so that freeing init code works properly. */ + _edata = .; + + /* will be freed after init */ + . = ALIGN(8192); /* Init code and data */ +__init_begin = .; + .init.text : { + _sinittext = .; + *(.init.text) + _einittext = .; + } + .init.data : { *(.init.data) } + . = ALIGN(16); + __setup_start = .; + .init.setup : { *(.init.setup) } + __setup_end = .; + __start___param = .; + __param : { *(__param) } + __stop___param = .; + __initcall_start = .; + .initcall.init : { + *(.initcall1.init) + *(.initcall2.init) + *(.initcall3.init) + *(.initcall4.init) + *(.initcall5.init) + *(.initcall6.init) + *(.initcall7.init) + } + __initcall_end = .; + __con_initcall_start = .; + .con_initcall.init : { *(.con_initcall.init) } + __con_initcall_end = .; + SECURITY_INIT + . = ALIGN(8192); + __initramfs_start = .; + .init.ramfs : { *(.init.ramfs) } + __initramfs_end = .; + . = ALIGN(8192); + __init_end = .; + .init.task : { *(init_task) } + + + .bss : { *(.bss) } /* BSS */ + + _end = . ; + + /* Sections to be discarded */ + /DISCARD/ : { + *(.exit.text) + *(.exit.data) + *(.exitcall.exit) + } + + .crap : { + /* Stabs debugging sections. */ + *(.stab) + *(.stabstr) + *(.stab.excl) + *(.stab.exclstr) + *(.stab.index) + *(.stab.indexstr) + *(.comment) + *(.note) + } + +} diff -Nru a/arch/m68k/vmlinux-std.lds b/arch/m68k/vmlinux-std.lds --- a/arch/m68k/vmlinux-std.lds Tue Sep 2 19:58:18 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,97 +0,0 @@ -/* ld script to make m68k Linux kernel */ - -#include - -OUTPUT_FORMAT("elf32-m68k", "elf32-m68k", "elf32-m68k") -OUTPUT_ARCH(m68k) -ENTRY(_start) -jiffies = jiffies_64 + 4; -SECTIONS -{ - . = 0x1000; - _text = .; /* Text and read-only data */ - .text : { - *(.text) - *(.fixup) - *(.gnu.warning) - } = 0x4e75 - - . = ALIGN(16); /* Exception table */ - __start___ex_table = .; - __ex_table : { *(__ex_table) } - __stop___ex_table = .; - - RODATA - - _etext = .; /* End of text section */ - - .data : { /* Data */ - *(.data) - CONSTRUCTORS - } - - .bss : { *(.bss) } /* BSS */ - - . = ALIGN(16); - .data.cacheline_aligned : { *(.data.cacheline_aligned) } - - _edata = .; /* End of data section */ - - /* will be freed after init */ - . = ALIGN(4096); /* Init code and data */ - __init_begin = .; - .init.text : { - _sinittext = .; - *(.init.text) - _einittext = .; - } - .init.data : { *(.init.data) } - . = ALIGN(16); - __setup_start = .; - .init.setup : { *(.init.setup) } - __setup_end = .; - __start___param = .; - __param : { *(__param) } - __stop___param = .; - __initcall_start = .; - .initcall.init : { - *(.initcall1.init) - *(.initcall2.init) - *(.initcall3.init) - *(.initcall4.init) - *(.initcall5.init) - *(.initcall6.init) - *(.initcall7.init) - } - __initcall_end = .; - __con_initcall_start = .; - .con_initcall.init : { *(.con_initcall.init) } - __con_initcall_end = .; - SECURITY_INIT - . = ALIGN(8192); - __initramfs_start = .; - .init.ramfs : { *(.init.ramfs) } - __initramfs_end = .; - . = ALIGN(8192); - __init_end = .; - - .data.init_task : { *(.data.init_task) } /* The initial task and kernel stack */ - - _end = . ; - - /* Sections to be discarded */ - /DISCARD/ : { - *(.exit.text) - *(.exit.data) - *(.exitcall.exit) - } - - /* Stabs debugging sections. */ - .stab 0 : { *(.stab) } - .stabstr 0 : { *(.stabstr) } - .stab.excl 0 : { *(.stab.excl) } - .stab.exclstr 0 : { *(.stab.exclstr) } - .stab.index 0 : { *(.stab.index) } - .stab.indexstr 0 : { *(.stab.indexstr) } - .comment 0 : { *(.comment) } -} diff -Nru a/arch/m68k/vmlinux-sun3.lds b/arch/m68k/vmlinux-sun3.lds --- a/arch/m68k/vmlinux-sun3.lds Tue Sep 2 19:58:12 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,97 +0,0 @@ -/* ld script to make m68k Linux kernel */ - -#include - -OUTPUT_FORMAT("elf32-m68k", "elf32-m68k", "elf32-m68k") -OUTPUT_ARCH(m68k) -ENTRY(_start) -jiffies = jiffies_64 + 4; -SECTIONS -{ - . = 0xE004000; - _text = .; /* Text and read-only data */ - .text : { - *(.head) - *(.text) - *(.fixup) - *(.gnu.warning) - } = 0x4e75 - RODATA - - _etext = .; /* End of text section */ - - .data : { /* Data */ - *(.data) - CONSTRUCTORS - . = ALIGN(16); /* Exception table */ - __start___ex_table = .; - *(__ex_table) - __stop___ex_table = .; - } - /* End of data goes *here* so that freeing init code works properly. */ - _edata = .; - - /* will be freed after init */ - . = ALIGN(8192); /* Init code and data */ -__init_begin = .; - .init.text : { - _sinittext = .; - *(.init.text) - _einittext = .; - } - .init.data : { *(.init.data) } - . = ALIGN(16); - __setup_start = .; - .init.setup : { *(.init.setup) } - __setup_end = .; - __start___param = .; - __param : { *(__param) } - __stop___param = .; - __initcall_start = .; - .initcall.init : { - *(.initcall1.init) - *(.initcall2.init) - *(.initcall3.init) - *(.initcall4.init) - *(.initcall5.init) - *(.initcall6.init) - *(.initcall7.init) - } - __initcall_end = .; - __con_initcall_start = .; - .con_initcall.init : { *(.con_initcall.init) } - __con_initcall_end = .; - SECURITY_INIT - . = ALIGN(8192); - __initramfs_start = .; - .init.ramfs : { *(.init.ramfs) } - __initramfs_end = .; - . = ALIGN(8192); - __init_end = .; - .init.task : { *(init_task) } - - - .bss : { *(.bss) } /* BSS */ - - _end = . ; - - /* Sections to be discarded */ - /DISCARD/ : { - *(.exit.text) - *(.exit.data) - *(.exitcall.exit) - } - - .crap : { - /* Stabs debugging sections. */ - *(.stab) - *(.stabstr) - *(.stab.excl) - *(.stab.exclstr) - *(.stab.index) - *(.stab.indexstr) - *(.comment) - *(.note) - } - -} diff -Nru a/arch/m68knommu/Kconfig b/arch/m68knommu/Kconfig --- a/arch/m68knommu/Kconfig Tue Sep 2 19:58:17 2003 +++ b/arch/m68knommu/Kconfig Tue Sep 2 19:58:17 2003 @@ -490,14 +490,6 @@ menu "Executable file formats" -config KCORE_AOUT - bool - default y - -config KCORE_ELF - bool - default y - source "fs/Kconfig.binfmt" endmenu diff -Nru a/arch/m68knommu/platform/5206/config.c b/arch/m68knommu/platform/5206/config.c --- a/arch/m68knommu/platform/5206/config.c Tue Sep 2 19:58:16 2003 +++ b/arch/m68knommu/platform/5206/config.c Tue Sep 2 19:58:16 2003 @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include @@ -26,7 +27,7 @@ /***************************************************************************/ void coldfire_tick(void); -void coldfire_timer_init(void (*handler)(int, void *, struct pt_regs *)); +void coldfire_timer_init(irqreturn_t (*handler)(int, void *, struct pt_regs *)); unsigned long coldfire_timer_offset(void); void coldfire_trap_init(void); void coldfire_reset(void); diff -Nru a/arch/m68knommu/platform/5206e/config.c b/arch/m68knommu/platform/5206e/config.c --- a/arch/m68knommu/platform/5206e/config.c Tue Sep 2 19:58:15 2003 +++ b/arch/m68knommu/platform/5206e/config.c Tue Sep 2 19:58:15 2003 @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -26,7 +27,7 @@ /***************************************************************************/ void coldfire_tick(void); -void coldfire_timer_init(void (*handler)(int, void *, struct pt_regs *)); +void coldfire_timer_init(irqreturn_t (*handler)(int, void *, struct pt_regs *)); unsigned long coldfire_timer_offset(void); void coldfire_trap_init(void); void coldfire_reset(void); diff -Nru a/arch/m68knommu/platform/5249/config.c b/arch/m68knommu/platform/5249/config.c --- a/arch/m68knommu/platform/5249/config.c Tue Sep 2 19:58:16 2003 +++ b/arch/m68knommu/platform/5249/config.c Tue Sep 2 19:58:16 2003 @@ -26,7 +26,7 @@ /***************************************************************************/ void coldfire_tick(void); -void coldfire_timer_init(void (*handler)(int, void *, struct pt_regs *)); +void coldfire_timer_init(irqreturn_t (*handler)(int, void *, struct pt_regs *)); unsigned long coldfire_timer_offset(void); void coldfire_trap_init(void); void coldfire_reset(void); diff -Nru a/arch/m68knommu/platform/5272/config.c b/arch/m68knommu/platform/5272/config.c --- a/arch/m68knommu/platform/5272/config.c Tue Sep 2 19:58:14 2003 +++ b/arch/m68knommu/platform/5272/config.c Tue Sep 2 19:58:14 2003 @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include @@ -27,7 +28,7 @@ /***************************************************************************/ void coldfire_tick(void); -void coldfire_timer_init(void (*handler)(int, void *, struct pt_regs *)); +void coldfire_timer_init(irqreturn_t (*handler)(int, void *, struct pt_regs *)); unsigned long coldfire_timer_offset(void); void coldfire_trap_init(void); void coldfire_reset(void); diff -Nru a/arch/mips/Kconfig b/arch/mips/Kconfig --- a/arch/mips/Kconfig Tue Sep 2 19:58:15 2003 +++ b/arch/mips/Kconfig Tue Sep 2 19:58:15 2003 @@ -1126,31 +1126,6 @@ menu "Executable file formats" -config KCORE_ELF - bool - default y - ---help--- - If you enabled support for /proc file system then the file - /proc/kcore will contain the kernel core image. This can be used - in gdb: - - $ cd /usr/src/linux ; gdb vmlinux /proc/kcore - - You have two choices here: ELF and A.OUT. Selecting ELF will make - /proc/kcore appear in ELF core format as defined by the Executable - and Linking Format specification. Selecting A.OUT will choose the - old "a.out" format which may be necessary for some old versions - of binutils or on some architectures. - - This is especially useful if you have compiled the kernel with the - "-g" option to preserve debugging information. It is mainly used - for examining kernel data structures on the live kernel so if you - don't understand what this means or are not a kernel hacker, just - leave it at its default value ELF. - -config KCORE_AOUT - bool - source "fs/Kconfig.binfmt" config TRAD_SIGNALS diff -Nru a/arch/mips/au1000/common/dma.c b/arch/mips/au1000/common/dma.c --- a/arch/mips/au1000/common/dma.c Tue Sep 2 19:58:19 2003 +++ b/arch/mips/au1000/common/dma.c Tue Sep 2 19:58:19 2003 @@ -62,14 +62,14 @@ spinlock_t au1000_dma_spin_lock = SPIN_LOCK_UNLOCKED; struct dma_chan au1000_dma_table[NUM_AU1000_DMA_CHANNELS] = { - {dev_id:-1,}, - {dev_id:-1,}, - {dev_id:-1,}, - {dev_id:-1,}, - {dev_id:-1,}, - {dev_id:-1,}, - {dev_id:-1,}, - {dev_id:-1,} + {.dev_id = -1,}, + {.dev_id = -1,}, + {.dev_id = -1,}, + {.dev_id = -1,}, + {.dev_id = -1,}, + {.dev_id = -1,}, + {.dev_id = -1,}, + {.dev_id = -1,} }; // Device FIFO addresses and default DMA modes diff -Nru a/arch/mips/kernel/ioctl32.c b/arch/mips/kernel/ioctl32.c --- a/arch/mips/kernel/ioctl32.c Tue Sep 2 19:58:16 2003 +++ b/arch/mips/kernel/ioctl32.c Tue Sep 2 19:58:16 2003 @@ -810,8 +810,7 @@ #define IOCTL_TABLE_START \ struct ioctl_trans ioctl_start[] = { #define IOCTL_TABLE_END \ - }; struct ioctl_trans ioctl_end[0]; - + }; IOCTL_TABLE_START #include @@ -1205,6 +1204,8 @@ COMPATIBLE_IOCTL(RTC_WKALM_SET) COMPATIBLE_IOCTL(RTC_WKALM_RD) IOCTL_TABLE_END + +int ioctl_table_size = ARRAY_SIZE(ioctl_start); #define NR_IOCTL_TRANS (sizeof(ioctl_translations) / \ sizeof(ioctl_translations[0])) diff -Nru a/arch/mips/sibyte/cfe/console.c b/arch/mips/sibyte/cfe/console.c --- a/arch/mips/sibyte/cfe/console.c Tue Sep 2 19:58:18 2003 +++ b/arch/mips/sibyte/cfe/console.c Tue Sep 2 19:58:18 2003 @@ -9,7 +9,6 @@ #include "cfe_error.h" extern int cfe_cons_handle; -static kdev_t cfe_consdev; static void cfe_console_write(struct console *cons, const char *str, unsigned int count) @@ -57,15 +56,12 @@ #ifdef CONFIG_SIBYTE_SB1250_DUART if (!strcmp(consdev, "uart0")) { setleds("u0cn"); -// cfe_consdev = MKDEV(TTY_MAJOR, SB1250_DUART_MINOR_BASE + 0); } else if (!strcmp(consdev, "uart1")) { setleds("u1cn"); -// cfe_consdev = MKDEV(TTY_MAJOR, SB1250_DUART_MINOR_BASE + 1); #endif #ifdef CONFIG_VGA_CONSOLE } else if (!strcmp(consdev, "pcconsole0")) { setleds("pccn"); -// cfe_consdev = MKDEV(TTY_MAJOR, 0); #endif } else return -ENODEV; @@ -74,12 +70,12 @@ } static struct console sb1250_cfe_cons = { - name: "cfe", - write: cfe_console_write, - device: cfe_console_device, - setup: cfe_console_setup, - flags: CON_PRINTBUFFER, - index: -1, + .name = "cfe", + .write = cfe_console_write, + .device = cfe_console_device, + .setup = cfe_console_setup, + .flags = CON_PRINTBUFFER, + .index = -1, }; static int __init sb1250_cfe_console_init(void) diff -Nru a/arch/mips/sibyte/sb1250/bcm1250_tbprof.c b/arch/mips/sibyte/sb1250/bcm1250_tbprof.c --- a/arch/mips/sibyte/sb1250/bcm1250_tbprof.c Tue Sep 2 19:58:15 2003 +++ b/arch/mips/sibyte/sb1250/bcm1250_tbprof.c Tue Sep 2 19:58:15 2003 @@ -253,7 +253,7 @@ { int minor; - minor = minor(inode->i_rdev); + minor = iminor(inode); if (minor != 0) { return -ENODEV; } @@ -278,7 +278,7 @@ { int minor; - minor = minor(inode->i_rdev); + minor = iminor(inode); if (minor != 0 || !sbp.open) { return -ENODEV; } diff -Nru a/arch/mips/tx4927/common/tx4927_irq.c b/arch/mips/tx4927/common/tx4927_irq.c --- a/arch/mips/tx4927/common/tx4927_irq.c Tue Sep 2 19:58:19 2003 +++ b/arch/mips/tx4927/common/tx4927_irq.c Tue Sep 2 19:58:19 2003 @@ -149,26 +149,26 @@ #define TX4927_CP0_NAME "TX4927-CP0" static struct hw_interrupt_type tx4927_irq_cp0_type = { - typename: TX4927_CP0_NAME, - startup: tx4927_irq_cp0_startup, - shutdown: tx4927_irq_cp0_shutdown, - enable: tx4927_irq_cp0_enable, - disable: tx4927_irq_cp0_disable, - ack: tx4927_irq_cp0_mask_and_ack, - end: tx4927_irq_cp0_end, - set_affinity: NULL + .typename = TX4927_CP0_NAME, + .startup = tx4927_irq_cp0_startup, + .shutdown = tx4927_irq_cp0_shutdown, + .enable = tx4927_irq_cp0_enable, + .disable = tx4927_irq_cp0_disable, + .ack = tx4927_irq_cp0_mask_and_ack, + .end = tx4927_irq_cp0_end, + .set_affinity = NULL }; #define TX4927_PIC_NAME "TX4927-PIC" static struct hw_interrupt_type tx4927_irq_pic_type = { - typename: TX4927_PIC_NAME, - startup: tx4927_irq_pic_startup, - shutdown: tx4927_irq_pic_shutdown, - enable: tx4927_irq_pic_enable, - disable: tx4927_irq_pic_disable, - ack: tx4927_irq_pic_mask_and_ack, - end: tx4927_irq_pic_end, - set_affinity: NULL + .typename = TX4927_PIC_NAME, + .startup = tx4927_irq_pic_startup, + .shutdown = tx4927_irq_pic_shutdown, + .enable = tx4927_irq_pic_enable, + .disable = tx4927_irq_pic_disable, + .ack = tx4927_irq_pic_mask_and_ack, + .end = tx4927_irq_pic_end, + .set_affinity = NULL }; #define TX4927_PIC_ACTION(s) { no_action, 0, 0, s, NULL, NULL } diff -Nru a/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_irq.c b/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_irq.c --- a/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_irq.c Tue Sep 2 19:58:15 2003 +++ b/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_irq.c Tue Sep 2 19:58:15 2003 @@ -255,14 +255,14 @@ #define TOSHIBA_RBTX4927_IOC_NAME "RBTX4927-IOC" static struct hw_interrupt_type toshiba_rbtx4927_irq_ioc_type = { - typename:TOSHIBA_RBTX4927_IOC_NAME, - startup:toshiba_rbtx4927_irq_ioc_startup, - shutdown:toshiba_rbtx4927_irq_ioc_shutdown, - enable:toshiba_rbtx4927_irq_ioc_enable, - disable:toshiba_rbtx4927_irq_ioc_disable, - ack:toshiba_rbtx4927_irq_ioc_mask_and_ack, - end:toshiba_rbtx4927_irq_ioc_end, - set_affinity:NULL + .typename = TOSHIBA_RBTX4927_IOC_NAME, + .startup = toshiba_rbtx4927_irq_ioc_startup, + .shutdown = toshiba_rbtx4927_irq_ioc_shutdown, + .enable = toshiba_rbtx4927_irq_ioc_enable, + .disable = toshiba_rbtx4927_irq_ioc_disable, + .ack = toshiba_rbtx4927_irq_ioc_mask_and_ack, + .end = toshiba_rbtx4927_irq_ioc_end, + .set_affinity = NULL }; #define TOSHIBA_RBTX4927_IOC_INTR_ENAB 0xbc002000 #define TOSHIBA_RBTX4927_IOC_INTR_STAT 0xbc002006 @@ -271,14 +271,14 @@ #ifdef CONFIG_TOSHIBA_FPCIB0 #define TOSHIBA_RBTX4927_ISA_NAME "RBTX4927-ISA" static struct hw_interrupt_type toshiba_rbtx4927_irq_isa_type = { - typename:TOSHIBA_RBTX4927_ISA_NAME, - startup:toshiba_rbtx4927_irq_isa_startup, - shutdown:toshiba_rbtx4927_irq_isa_shutdown, - enable:toshiba_rbtx4927_irq_isa_enable, - disable:toshiba_rbtx4927_irq_isa_disable, - ack:toshiba_rbtx4927_irq_isa_mask_and_ack, - end:toshiba_rbtx4927_irq_isa_end, - set_affinity:NULL + .typename = TOSHIBA_RBTX4927_ISA_NAME, + .startup = toshiba_rbtx4927_irq_isa_startup, + .shutdown = toshiba_rbtx4927_irq_isa_shutdown, + .enable = toshiba_rbtx4927_irq_isa_enable, + .disable = toshiba_rbtx4927_irq_isa_disable, + .ack = toshiba_rbtx4927_irq_isa_mask_and_ack, + .end = toshiba_rbtx4927_irq_isa_end, + .set_affinity = NULL }; #endif diff -Nru a/arch/mips/vr41xx/common/vrc4173.c b/arch/mips/vr41xx/common/vrc4173.c --- a/arch/mips/vr41xx/common/vrc4173.c Tue Sep 2 19:58:17 2003 +++ b/arch/mips/vr41xx/common/vrc4173.c Tue Sep 2 19:58:17 2003 @@ -250,10 +250,10 @@ } static struct pci_driver vrc4173_driver = { - name: "NEC VRC4173", - probe: vrc4173_probe, - remove: NULL, - id_table: vrc4173_table, + .name = "NEC VRC4173", + .probe = vrc4173_probe, + .remove = NULL, + .id_table = vrc4173_table, }; static int __devinit vrc4173_init(void) diff -Nru a/arch/parisc/Kconfig b/arch/parisc/Kconfig --- a/arch/parisc/Kconfig Tue Sep 2 19:58:16 2003 +++ b/arch/parisc/Kconfig Tue Sep 2 19:58:16 2003 @@ -161,11 +161,6 @@ menu "Executable file formats" -config KCORE_ELF - bool - depends on PROC_FS - default y - source "fs/Kconfig.binfmt" endmenu diff -Nru a/arch/parisc/kernel/ioctl32.c b/arch/parisc/kernel/ioctl32.c --- a/arch/parisc/kernel/ioctl32.c Tue Sep 2 19:58:12 2003 +++ b/arch/parisc/kernel/ioctl32.c Tue Sep 2 19:58:12 2003 @@ -1426,7 +1426,7 @@ return -EINVAL; tty = (struct tty_struct *)file->private_data; - if (tty_paranoia_check(tty, inode->i_rdev, "tty_ioctl")) + if (tty_paranoia_check(tty, inode, "tty_ioctl")) return -EINVAL; if (tty->driver->ioctl != vt_ioctl) @@ -2458,7 +2458,7 @@ #define COMPATIBLE_IOCTL(cmd) HANDLE_IOCTL(cmd, sys_ioctl) #define IOCTL_TABLE_START struct ioctl_trans ioctl_start[] = { -#define IOCTL_TABLE_END }; struct ioctl_trans ioctl_end[0]; +#define IOCTL_TABLE_END }; IOCTL_TABLE_START #include @@ -2631,3 +2631,4 @@ #endif /* DRM */ IOCTL_TABLE_END +int ioctl_table_size = ARRAY_SIZE(ioctl_start); diff -Nru a/arch/ppc/8260_io/uart.c b/arch/ppc/8260_io/uart.c --- a/arch/ppc/8260_io/uart.c Tue Sep 2 19:58:13 2003 +++ b/arch/ppc/8260_io/uart.c Tue Sep 2 19:58:13 2003 @@ -50,6 +50,10 @@ #include #include +#ifdef CONFIG_MAGIC_SYSRQ +#include +#endif + #ifdef CONFIG_SERIAL_CONSOLE #include @@ -77,6 +81,14 @@ static struct tty_driver *serial_driver; static int serial_console_setup(struct console *co, char *options); +static void serial_console_write(struct console *c, const char *s, + unsigned count); +static kdev_t serial_console_device(struct console *c); + +#if defined(CONFIG_SERIAL_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) +static unsigned long break_pressed; /* break, really ... */ +#endif + /* * Serial driver configuration section. Here are the various options: */ @@ -208,6 +220,15 @@ cbd_t *tx_cur; } ser_info_t; +static struct console sercons = { + .name = "ttyS", + .write = serial_console_write, + .device = serial_console_device, + .setup = serial_console_setup, + .flags = CON_PRINTBUFFER, + .index = CONFIG_SERIAL_CONSOLE_PORT, +}; + static void change_speed(ser_info_t *info); static void rs_8xx_wait_until_sent(struct tty_struct *tty, int timeout); @@ -328,7 +349,7 @@ schedule_work(&info->tqueue); } -static _INLINE_ void receive_chars(ser_info_t *info) +static _INLINE_ void receive_chars(ser_info_t *info, struct pt_regs *regs) { struct tty_struct *tty = info->tty; unsigned char ch, *cp; @@ -450,6 +471,19 @@ } } } + +#if defined(CONFIG_SERIAL_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) + if (break_pressed && info->line == sercons.index) { + if (ch != 0 && time_before(jiffies, + break_pressed + HZ*5)) { + handle_sysrq(ch, regs, NULL, NULL); + break_pressed = 0; + goto ignore_char; + } else + break_pressed = 0; + } +#endif + if (tty->flip.count >= TTY_FLIPBUF_SIZE) break; @@ -458,6 +492,10 @@ tty->flip.count++; } +#if defined(CONFIG_SERIAL_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) + ignore_char: +#endif + /* This BD is ready to be used again. Clear status. * Get next BD. */ @@ -475,7 +513,36 @@ schedule_delayed_work(&tty->flip.work, 1); } -static _INLINE_ void transmit_chars(ser_info_t *info) +static _INLINE_ void receive_break(ser_info_t *info, struct pt_regs *regs) +{ + struct tty_struct *tty = info->tty; + + info->state->icount.brk++; + +#if defined(CONFIG_SERIAL_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) + if (info->line == sercons.index) { + if (!break_pressed) { + break_pressed = jiffies; + return; + } else + break_pressed = 0; + } +#endif + + /* Check to see if there is room in the tty buffer for + * the break. If not, we exit now, losing the break. FIXME + */ + if ((tty->flip.count + 1) >= TTY_FLIPBUF_SIZE) + return; + *(tty->flip.flag_buf_ptr++) = TTY_BREAK; + *(tty->flip.char_buf_ptr++) = 0; + tty->flip.count++; + + queue_task(&tty->flip.tqueue, &tq_timer); +} + + +static _INLINE_ void transmit_chars(ser_info_t *info, struct pt_regs *regs) { if (info->flags & TX_WAKEUP) { @@ -575,19 +642,23 @@ if ((idx = info->state->smc_scc_num) < SCC_NUM_BASE) { smcp = &immr->im_smc[idx]; events = smcp->smc_smce; + if (events & SMCM_BRKE) + receive_break(info, regs); if (events & SMCM_RX) - receive_chars(info); + receive_chars(info, regs); if (events & SMCM_TX) - transmit_chars(info); + transmit_chars(info, regs); smcp->smc_smce = events; } else { sccp = &immr->im_scc[idx - SCC_IDX_BASE]; events = sccp->scc_scce; + if (events & SMCM_BRKE) + receive_break(info, regs); if (events & SCCM_RX) - receive_chars(info); + receive_chars(info, regs); if (events & SCCM_TX) - transmit_chars(info); + transmit_chars(info, regs); sccp->scc_scce = events; } @@ -2207,7 +2278,7 @@ static void serial_console_write(struct console *c, const char *s, unsigned count) { -#if defined(CONFIG_KGDB) && !defined(CONFIG_USE_SERIAL2_KGDB) +#if defined(CONFIG_KGDB_CONSOLE) && !defined(CONFIG_USE_SERIAL2_KGDB) /* Try to let stub handle output. Returns true if it did. */ if (kgdb_output_string(s, count)) return; @@ -2391,21 +2462,11 @@ } #endif -static kdev_t serial_console_device(struct console *c) +static struct tty_driver *serial_console_device(struct console *c, int *index) { *index = c->index; return serial_driver; } - - -static struct console sercons = { - .name = "ttyS", - .write = serial_console_write, - .device = serial_console_device, - .setup = serial_console_setup, - .flags = CON_PRINTBUFFER, - .index = CONFIG_SERIAL_CONSOLE_PORT, -}; /* * Register console. diff -Nru a/arch/ppc/8xx_io/cs4218_tdm.c b/arch/ppc/8xx_io/cs4218_tdm.c --- a/arch/ppc/8xx_io/cs4218_tdm.c Tue Sep 2 19:58:13 2003 +++ b/arch/ppc/8xx_io/cs4218_tdm.c Tue Sep 2 19:58:13 2003 @@ -2106,11 +2106,11 @@ */ cs4218_ctl_write(cs4218_control); - sound.minDev = MINOR(inode->i_rdev) & 0x0f; + sound.minDev = iminor(inode) & 0x0f; sound.soft = sound.dsp; sound.hard = sound.dsp; sound_init(); - if ((MINOR(inode->i_rdev) & 0x0f) == SND_DEV_AUDIO) { + if ((iminor(inode) & 0x0f) == SND_DEV_AUDIO) { sound_set_speed(8000); sound_set_stereo(0); sound_set_format(AFMT_MU_LAW); diff -Nru a/arch/ppc/8xx_io/uart.c b/arch/ppc/8xx_io/uart.c --- a/arch/ppc/8xx_io/uart.c Tue Sep 2 19:58:17 2003 +++ b/arch/ppc/8xx_io/uart.c Tue Sep 2 19:58:17 2003 @@ -1068,7 +1068,7 @@ volatile cbd_t *bdp; unsigned char *cp; -#ifdef CONFIG_KGDB +#ifdef CONFIG_KGDB_CONSOLE /* Try to let stub handle output. Returns true if it did. */ if (kgdb_output_string(buf, count)) return ret; @@ -2271,7 +2271,7 @@ static void serial_console_write(struct console *c, const char *s, unsigned count) { -#ifdef CONFIG_KGDB +#ifdef CONFIG_KGDB_CONSOLE /* Try to let stub handle output. Returns true if it did. */ if (kgdb_output_string(s, count)) return; diff -Nru a/arch/ppc/Kconfig b/arch/ppc/Kconfig --- a/arch/ppc/Kconfig Tue Sep 2 19:58:19 2003 +++ b/arch/ppc/Kconfig Tue Sep 2 19:58:19 2003 @@ -795,22 +795,6 @@ bool "PCI for Permedia2" depends on !4xx && !8xx && APUS -# only elf supported, a.out is not -- Cort -config KCORE_ELF - bool - depends on PROC_FS - default y - help - If you enabled support for /proc file system then the file - /proc/kcore will contain the kernel core image in ELF format. This - can be used in gdb: - - $ cd /usr/src/linux ; gdb vmlinux /proc/kcore - - This is especially useful if you have compiled the kernel with the - "-g" option to preserve debugging information. It is mainly used - for examining kernel data structures on the live kernel. - config KERNEL_ELF bool default y @@ -1277,16 +1261,11 @@ floppy controller, say Y here. Most commonly found in PowerMacs. config MAC_SERIAL - tristate "Support for PowerMac serial ports" + tristate "Support for PowerMac serial ports (OBSOLETE DRIVER)" depends on PPC_PMAC help - If you have Macintosh style serial ports (8 pin mini-DIN), say Y - here. If you also have regular serial ports and enable the driver - for them, you can't currently use the serial console feature. - -config SERIAL_CONSOLE - bool "Support for console on serial port" - depends on PPC_PMAC && MAC_SERIAL=y + This driver is obsolete. Use CONFIG_SERIAL_PMACZILOG in + "Character devices --> Serial drivers --> PowerMac z85c30" option. config ADB bool "Apple Desktop Bus (ADB) support" @@ -1426,20 +1405,12 @@ config KGDB bool "Include kgdb kernel debugger" depends on DEBUG_KERNEL + select DEBUG_INFO help Include in-kernel hooks for kgdb, the Linux kernel source level debugger. See for more information. Unless you are intending to debug the kernel, say N here. -config DEBUG_INFO - bool "Compile the kernel with debug info" - depends on DEBUG_KERNEL - help - If you say Y here the resulting kernel image will include - debugging info resulting in a larger kernel image. - Say Y here only if you plan to use gdb to debug the kernel. - If you don't debug the kernel, you can say N. - choice prompt "Serial Port" depends on KGDB @@ -1459,6 +1430,14 @@ endchoice +config KGDB_CONSOLE + bool "Enable serial console thru kgdb port" + depends on KGDB && 8xx || 8260 + help + If you enable this, all serial console messages will be sent + over the gdb stub. + If unsure, say N. + config XMON bool "Include xmon kernel debugger" depends on DEBUG_KERNEL @@ -1474,18 +1453,16 @@ Unless you are intending to debug the kernel with one of these machines, say N here. -config MORE_COMPILE_OPTIONS - bool "Add any additional compile options" - depends on DEBUG_KERNEL && (KGDB || XMON || BDI_SWITCH) - help - If you want to add additional CFLAGS to the kernel build, such as -g - for KGDB or the BDI2000, enable this option and then enter what you - would like to add in the next question. - -config COMPILE_OPTIONS - string "Additional compile arguments" - depends on MORE_COMPILE_OPTIONS - default "-g -ggdb" +config DEBUG_INFO + bool "Compile the kernel with debug info" + depends on DEBUG_KERNEL + default y if BDI_SWITCH || XMON + help + If you say Y here the resulting kernel image will include + debugging info resulting in a larger kernel image. + Say Y here only if you plan to use some sort of debugger to + debug the kernel. + If you don't debug the kernel, you can say N. config BOOTX_TEXT bool "Support for early boot text console (BootX or OpenFirmware only)" diff -Nru a/arch/ppc/Makefile b/arch/ppc/Makefile --- a/arch/ppc/Makefile Tue Sep 2 19:58:13 2003 +++ b/arch/ppc/Makefile Tue Sep 2 19:58:13 2003 @@ -22,9 +22,6 @@ cflags-$(CONFIG_4xx) += -Wa,-m405 cflags-$(CONFIG_PPC64BRIDGE) += -Wa,-mppc64bridge -# Use sed to remove the quotes. -cflags-$(CONFIG_MORE_COMPILE_OPTIONS) += \ - $(shell echo $(CONFIG_COMPILE_OPTIONS) | sed -e 's/"//g') CFLAGS += $(cflags-y) diff -Nru a/arch/ppc/boot/common/ns16550.c b/arch/ppc/boot/common/ns16550.c --- a/arch/ppc/boot/common/ns16550.c Tue Sep 2 19:58:19 2003 +++ b/arch/ppc/boot/common/ns16550.c Tue Sep 2 19:58:19 2003 @@ -60,7 +60,7 @@ else { /* Input clock. */ outb(com_port + (UART_DLL << shift), - (BASE_BAUD / SERIAL_BAUD)); + (BASE_BAUD / SERIAL_BAUD) & 0xFF); outb(com_port + (UART_DLM << shift), (BASE_BAUD / SERIAL_BAUD) >> 8); /* 8 data, 1 stop, no parity */ diff -Nru a/arch/ppc/boot/common/util.S b/arch/ppc/boot/common/util.S --- a/arch/ppc/boot/common/util.S Tue Sep 2 19:58:20 2003 +++ b/arch/ppc/boot/common/util.S Tue Sep 2 19:58:20 2003 @@ -160,9 +160,22 @@ blr +/* udelay (on non-601 processors) needs to know the period of the + * timebase in nanoseconds. This used to be hardcoded to be 60ns + * (period of 66MHz/4). Now a variable is used that is initialized to + * 60 for backward compatibility, but it can be overridden as necessary + * with code something like this: + * extern unsigned long timebase_period_ns; + * timebase_period_ns = 1000000000 / bd->bi_tbfreq; + */ + .data + .globl timebase_period_ns +timebase_period_ns: + .long 60 + + .text /* * Delay for a number of microseconds - * -- Use the BUS timer (assumes 66MHz) */ .globl udelay udelay: @@ -180,8 +193,13 @@ .udelay_not_601: mulli r4,r3,1000 /* nanoseconds */ - addi r4,r4,59 - li r5,60 + /* Change r4 to be the number of ticks using: + * (nanoseconds + (timebase_period_ns - 1 )) / timebase_period_ns + * timebase_period_ns defaults to 60 (16.6MHz) */ + lis r5,timebase_period_ns@h + lwz r5,timebase_period_ns@l(r5) + addi r4,r4,r5 + addi r4,r4,-1 divw r4,r4,r5 /* BUS ticks */ 1: mftbu r5 mftb r6 diff -Nru a/arch/ppc/boot/include/of1275.h b/arch/ppc/boot/include/of1275.h --- a/arch/ppc/boot/include/of1275.h Tue Sep 2 19:58:13 2003 +++ b/arch/ppc/boot/include/of1275.h Tue Sep 2 19:58:13 2003 @@ -20,6 +20,7 @@ /* function declarations */ void * claim(unsigned int virt, unsigned int size, unsigned int align); +int map(unsigned int phys, unsigned int virt, unsigned int size); void enter(void); void exit(void); phandle finddevice(const char *name); diff -Nru a/arch/ppc/boot/ld.script b/arch/ppc/boot/ld.script --- a/arch/ppc/boot/ld.script Tue Sep 2 19:58:17 2003 +++ b/arch/ppc/boot/ld.script Tue Sep 2 19:58:17 2003 @@ -66,7 +66,7 @@ _edata = .; PROVIDE (edata = .); - . = ALIGN(8); + . = ALIGN(4096); __bss_start = .; .bss : { diff -Nru a/arch/ppc/boot/of1275/Makefile b/arch/ppc/boot/of1275/Makefile --- a/arch/ppc/boot/of1275/Makefile Tue Sep 2 19:58:16 2003 +++ b/arch/ppc/boot/of1275/Makefile Tue Sep 2 19:58:16 2003 @@ -3,4 +3,4 @@ # lib-y := claim.o enter.o exit.o finddevice.o getprop.o ofinit.o \ - ofstdio.o read.o release.o write.o + ofstdio.o read.o release.o write.o map.o diff -Nru a/arch/ppc/boot/of1275/map.c b/arch/ppc/boot/of1275/map.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/ppc/boot/of1275/map.c Tue Sep 2 19:58:20 2003 @@ -0,0 +1,50 @@ + +/* + * Copyright (C) Paul Mackerras 1997. + * Copyright (C) Leigh Brown 2002. + * + * 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. + */ + +#include "of1275.h" +#include "nonstdio.h" + +extern ihandle of_prom_mmu; + +int +map(unsigned int phys, unsigned int virt, unsigned int size) +{ + struct prom_args { + char *service; + int nargs; + int nret; + char *method; + ihandle mmu_ihandle; + int misc; + unsigned int phys; + unsigned int virt; + unsigned int size; + int ret0; + int ret1; + } args; + + if (of_prom_mmu == 0) { + printf("map() called, no MMU found\n"); + return -1; + } + args.service = "call-method"; + args.nargs = 6; + args.nret = 2; + args.method = "map"; + args.mmu_ihandle = of_prom_mmu; + args.misc = -1; + args.phys = phys; + args.virt = virt; + args.size = size; + (*of_prom_entry)(&args); + + return (int)args.ret0; +} diff -Nru a/arch/ppc/boot/of1275/ofinit.c b/arch/ppc/boot/of1275/ofinit.c --- a/arch/ppc/boot/of1275/ofinit.c Tue Sep 2 19:58:18 2003 +++ b/arch/ppc/boot/of1275/ofinit.c Tue Sep 2 19:58:18 2003 @@ -11,9 +11,17 @@ #include "of1275.h" prom_entry of_prom_entry; +ihandle of_prom_mmu; void ofinit(prom_entry prom_ptr) { + phandle chosen; + of_prom_entry = prom_ptr; + + if ((chosen = finddevice("/chosen")) == OF_INVALID_HANDLE) + return; + if (getprop(chosen, "mmu", &of_prom_mmu, sizeof(ihandle)) != 4) + return; } diff -Nru a/arch/ppc/boot/openfirmware/Makefile b/arch/ppc/boot/openfirmware/Makefile --- a/arch/ppc/boot/openfirmware/Makefile Tue Sep 2 19:58:14 2003 +++ b/arch/ppc/boot/openfirmware/Makefile Tue Sep 2 19:58:14 2003 @@ -22,7 +22,7 @@ images := $(boot)/images OBJCOPY_ARGS := -O aixcoff-rs6000 -R .stab -R .stabstr -R .comment -COFF_LD_ARGS := -T $(boot)/ld.script -e _start -Ttext 0x00700000 -Bstatic +COFF_LD_ARGS := -T $(boot)/ld.script -e _start -Ttext 0x00500000 -Bstatic CHRP_LD_ARGS := -T $(boot)/ld.script -e _start -Ttext 0x00800000 NEWWORLD_LD_ARGS:= -T $(boot)/ld.script -e _start -Ttext 0x01000000 diff -Nru a/arch/ppc/boot/openfirmware/coffmain.c b/arch/ppc/boot/openfirmware/coffmain.c --- a/arch/ppc/boot/openfirmware/coffmain.c Tue Sep 2 19:58:16 2003 +++ b/arch/ppc/boot/openfirmware/coffmain.c Tue Sep 2 19:58:16 2003 @@ -32,16 +32,16 @@ char *begin_avail, *end_avail; char *avail_high; -#define RAM_START 0 -#define RAM_END (RAM_START + 0x800000) /* only 8M mapped with BATs */ - -#define PROG_START RAM_START -#define PROG_SIZE 0x00700000 - #define SCRATCH_SIZE (128 << 10) static char heap[SCRATCH_SIZE]; +static unsigned long ram_start = 0; +static unsigned long ram_end = 0x1000000; +static unsigned long prog_start = 0x800000; +static unsigned long prog_size = 0x800000; + + typedef void (*kernel_start_t)(int, int, void *); void boot(int a1, int a2, void *prom) @@ -52,32 +52,34 @@ unsigned initrd_start, initrd_size; printf("coffboot starting: loaded at 0x%p\n", &_start); - setup_bats(RAM_START); + setup_bats(ram_start); initrd_size = (char *)(&__ramdisk_end) - (char *)(&__ramdisk_begin); if (initrd_size) { - initrd_start = (RAM_END - initrd_size) & ~0xFFF; + initrd_start = (ram_end - initrd_size) & ~0xFFF; a1 = initrd_start; a2 = initrd_size; - claim(initrd_start, RAM_END - initrd_start, 0); + claim(initrd_start, ram_end - initrd_start, 0); printf("initial ramdisk moving 0x%x <- 0x%p (%x bytes)\n\r", initrd_start, (char *)(&__ramdisk_begin), initrd_size); memcpy((char *)initrd_start, (char *)(&__ramdisk_begin), initrd_size); + prog_size = initrd_start - prog_start; } else a2 = 0xdeadbeef; im = (char *)(&__image_begin); len = (char *)(&__image_end) - (char *)(&__image_begin); - /* claim 4MB starting at 0 */ - claim(0, PROG_SIZE, 0); - dst = (void *) RAM_START; + /* claim 4MB starting at PROG_START */ + claim(prog_start, prog_size, 0); + map(prog_start, prog_start, prog_size); + dst = (void *) prog_start; if (im[0] == 0x1f && im[1] == 0x8b) { /* set up scratch space */ begin_avail = avail_high = avail_ram = heap; end_avail = heap + sizeof(heap); printf("heap at 0x%p\n", avail_ram); printf("gunzipping (0x%p <- 0x%p:0x%p)...", dst, im, im+len); - gunzip(dst, PROG_SIZE, im, &len); + gunzip(dst, prog_size, im, &len); printf("done %u bytes\n", len); printf("%u bytes of heap consumed, max in use %u\n", avail_high - begin_avail, heap_max); @@ -87,9 +89,9 @@ flush_cache(dst, len); make_bi_recs(((unsigned long) dst + len), "coffboot", _MACH_Pmac, - (PROG_START + PROG_SIZE)); + (prog_start + prog_size)); - sa = (unsigned long)PROG_START; + sa = (unsigned long)prog_start; printf("start address = 0x%x\n", sa); (*(kernel_start_t)sa)(a1, a2, prom); diff -Nru a/arch/ppc/boot/openfirmware/misc.S b/arch/ppc/boot/openfirmware/misc.S --- a/arch/ppc/boot/openfirmware/misc.S Tue Sep 2 19:58:16 2003 +++ b/arch/ppc/boot/openfirmware/misc.S Tue Sep 2 19:58:16 2003 @@ -9,7 +9,7 @@ .text /* - * Use the BAT3 registers to map the 1st 8MB of RAM to + * Use the BAT2 & 3 registers to map the 1st 16MB of RAM to * the address given as the 1st argument. */ .globl setup_bats @@ -22,6 +22,10 @@ mtibatl 3,0 /* invalidate BAT first */ ori 3,3,4 /* set up BAT registers for 601 */ li 4,0x7f + mtibatu 2,3 + mtibatl 2,4 + oris 3,3,0x80 + oris 4,4,0x80 mtibatu 3,3 mtibatl 3,4 b 5f @@ -29,6 +33,12 @@ mtibatu 3,0 ori 3,3,0xff /* set up BAT registers for 604 */ li 4,2 + mtdbatl 2,4 + mtdbatu 2,3 + mtibatl 2,4 + mtibatu 2,3 + oris 3,3,0x80 + oris 4,4,0x80 mtdbatl 3,4 mtdbatu 3,3 mtibatl 3,4 diff -Nru a/arch/ppc/boot/simple/Makefile b/arch/ppc/boot/simple/Makefile --- a/arch/ppc/boot/simple/Makefile Tue Sep 2 19:58:12 2003 +++ b/arch/ppc/boot/simple/Makefile Tue Sep 2 19:58:12 2003 @@ -22,7 +22,6 @@ # get_mem_size(), which is memory controller dependent. Add in the correct # XXX_memory.o file for this to work, as well as editing the $(MISC) file. -boot: zImage boot := arch/ppc/boot common := $(boot)/common @@ -32,86 +31,90 @@ # Normally, we use the 'misc.c' file for decompress_kernel and # whatnot. Sometimes we need to override this however. -MISC := misc.o -ifeq ($(CONFIG_IBM_OPENBIOS),y) -ZIMAGE := zImage-TREE -ZIMAGEINITRD := zImage.initrd-TREE -END := treeboot -TFTPIMAGE := /tftpboot/zImage.$(END) -MISC := misc-embedded.o -endif -ifeq ($(CONFIG_EMBEDDEDBOOT),y) -TFTPIMAGE := /tftpboot/zImage.embedded -MISC := misc-embedded.o -endif -ifeq ($(CONFIG_EBONY),y) -ZIMAGE := zImage-TREE -ZIMAGEINITRD := zImage.initrd-TREE -END := ebony -ENTRYPOINT := 0x01000000 -TFTPIMAGE := /tftpboot/zImage.$(END) -endif -ifeq ($(CONFIG_EV64260),y) -EXTRA := misc-ev64260.o -TFTPIMAGE := /tftpboot/zImage.ev64260 -endif -ifeq ($(CONFIG_GEMINI),y) -ZIMAGE := zImage-STRIPELF -ZIMAGEINITRD := zImage.initrd-STRIPELF -END := gemini -TFTPIMAGE := /tftpboot/zImage.$(END) -endif -ifeq ($(CONFIG_K2),y) -EXTRA := legacy.o -TFTPIMAGE := /tftpboot/zImage.k2 -endif -# kbuild-2.4 'feature', only one of these will ever by 'y' at a time. +misc-y := misc.o + +# +# See arch/ppc/kconfig and arch/ppc/platforms/Kconfig +# for definition of what platform each config option refer to. +#---------------------------------------------------------------------------- + zimage-$(CONFIG_IBM_OPENBIOS) := zImage-TREE +zimageinitrd-$(CONFIG_IBM_OPENBIOS) := zImage.initrd-TREE + end-$(CONFIG_IBM_OPENBIOS) := treeboot + tftpimage-$(CONFIG_IBM_OPENBIOS) := /tftpboot/zImage.$(end-y) + misc-$(CONFIG_IBM_OPENBIOS) := misc-embedded.o + + tftpimage-$(CONFIG_EMBEDDEDBOOT) := /tftpboot/zImage.embedded + misc-$(CONFIG_EMBEDDEDBOOT) := misc-embedded.o + + zimage-$(CONFIG_EBONY) := zImage-TREE +zimageinitrd-$(CONFIG_EBONY) := zImage.initrd-TREE + extra.o-$(CONFIG_EBONY) := direct.o + end-$(CONFIG_EBONY) := ebony + entrypoint-$(CONFIG_EBONY) := 0x01000000 + tftpimage-$(CONFIG_EBONY) := /tftpboot/zImage.$(end-y) + + extra.o-$(CONFIG_EV64260) := direct.o misc-ev64260.o + tftpimage-$(CONFIG_EV64260) := /tftpboot/zImage.ev64260 + + zimage-$(CONFIG_GEMINI) := zImage-STRIPELF +zimageinitrd-$(CONFIG_GEMINI) := zImage.initrd-STRIPELF + end-$(CONFIG_GEMINI) := gemini + tftpimage-$(CONFIG_GEMINI) := /tftpboot/zImage.$(end-y) + + extra.o-$(CONFIG_K2) := legacy.o + tftpimage-$(CONFIG_K2) := /tftpboot/zImage.k2 + +# kconfig 'feature', only one of these will ever by 'y' at a time. # The rest will be unset. -ifeq ($(CONFIG_MCPN765)$(CONFIG_MVME5100)$(CONFIG_PRPMC750)$(CONFIG_PRPMC800)$(CONFIG_LOPEC)$(CONFIG_PPLUS),y) -ZIMAGE := zImage-PPLUS -ZIMAGEINITRD := zImage.initrd-PPLUS -TFTPIMAGE := /tftpboot/zImage.pplus -ZNETBOOT := zImage.pplus -ZNETBOOTRD := zImage.initrd.pplus -endif -ifeq ($(CONFIG_PPLUS),y) -EXTRA := legacy.o -endif -ifeq ($(CONFIG_PCORE)$(CONFIG_POWERPMC250),y) -ZIMAGE := zImage-STRIPELF -ZIMAGEINITRD := zImage.initrd-STRIPELF -EXTRA := chrpmap.o -END := pcore -TFTPIMAGE := /tftpboot/zImage.$(END) -endif -ifeq ($(CONFIG_SANDPOINT),y) -TFTPIMAGE := /tftpboot/zImage.sandpoint -endif -ifeq ($(CONFIG_SPRUCE),y) -ZIMAGE := zImage-TREE -ZIMAGEINITRD := zImage.initrd-TREE -END := spruce -ENTRYPOINT := 0x00800000 -MISC := misc-spruce.o -TFTPIMAGE := /tftpboot/zImage.$(END) -endif -ifeq ($(CONFIG_SMP),y) -TFTPIMAGE += .smp -endif -ifeq ($(CONFIG_REDWOOD_4),y) +multi := $(CONFIG_MCPN765)$(CONFIG_MVME5100)$(CONFIG_PRPMC750) \ +$(CONFIG_PRPMC800)$(CONFIG_LOPEC)$(CONFIG_PPLUS) + zimage-$(multi) := zImage-PPLUS +zimageinitrd-$(multi) := zImage.initrd-PPLUS + tftpimage-$(multi) := /tftpboot/zImage.pplus + znetboot-$(multi) := zImage.pplus + znetbootrd-$(multi) := zImage.initrd.pplus + +# Overrides previous assingment + extra.o-$(CONFIG_PPLUS) := legacy.o + + zimage-$(CONFIG_PCORE) := zImage-STRIPELF +zimageinitrd-$(CONFIG_PCORE) := zImage.initrd-STRIPELF + extra.o-$(CONFIG_PCORE) := chrpmap.o + end-$(CONFIG_PCORE) := pcore + tftpimage-$(CONFIG_PCORE) := /tftpboot/zImage.$(end-y) + + zimage-$(CONFIG_POWERPMC250) := zImage-STRIPELF +zimageinitrd-$(CONFIG_POWERPMC250) := zImage.initrd-STRIPELF + extra.o-$(CONFIG_POWERPMC250) := chrpmap.o + end-$(CONFIG_POWERPMC250) := pcore + tftpimage-$(CONFIG_POWERPMC250) := /tftpboot/zImage.$(end-y) + + tftpimage-$(CONFIG_SANDPOINT) := /tftpboot/zImage.sandpoint + + zimage-$(CONFIG_SPRUCE) := zImage-TREE +zimageinitrd-$(CONFIG_SPRUCE) := zImage.initrd-TREE + end-$(CONFIG_SPRUCE) := spruce + entrypoint-$(CONFIG_SPRUCE) := 0x00800000 + misc-$(CONFIG_SPRUCE) := misc-spruce.o + tftpimage-$(CONFIG_SPRUCE) := /tftpboot/zImage.$(end-y) + + +# tftp image is prefixed with .smp if compiled for SMP +tftpimage-$(CONFIG_SMP) += .smp + # This is a treeboot that needs init functions until the # boot rom is sorted out (i.e. this is short lived) -EXTRA_AFLAGS := -Wa,-m405 -EXTRA := rw4/rw4_init.o rw4/rw4_init_brd.o -endif +extra-aflags-$(CONFIG_REDWOOD_4) := -Wa,-m405 +extra.o-$(CONFIG_REDWOOD_4) := rw4/rw4_init.o rw4/rw4_init_brd.o +EXTRA_AFLAGS := $(extra-aflags-y) # Linker args. This specifies where the image will be run at. -LD_ARGS = -T $(boot)/ld.script \ - -Ttext $(CONFIG_BOOT_LOAD) -Bstatic +LD_ARGS := -T $(boot)/ld.script \ + -Ttext $(CONFIG_BOOT_LOAD) -Bstatic OBJCOPY_ARGS := -O elf32-powerpc # head.o and relocate.o must be at the start. -boot-y := head.o relocate.o $(EXTRA) $(MISC) +boot-y := head.o relocate.o $(extra.o-y) $(misc-y) boot-$(CONFIG_40x) += embed_config.o boot-$(CONFIG_8xx) += embed_config.o boot-$(CONFIG_8260) += embed_config.o @@ -160,40 +163,40 @@ -R .stabstr -R .sysmap # Sort-of dummy rules, that let us format the image we want. -zImage: $(images)/$(ZIMAGE) $(obj)/zvmlinux +zImage: $(images)/$(zimage-y) $(obj)/zvmlinux cp -f $(obj)/zvmlinux $(images)/zImage.elf rm -f $(obj)/zvmlinux -zImage.initrd: $(images)/$(ZIMAGEINITRD) $(obj)/zvmlinux.initrd +zImage.initrd: $(images)/$(zimageinitrd-y) $(obj)/zvmlinux.initrd cp -f $(obj)/zvmlinux.initrd $(images)/zImage.initrd.elf rm -f $(obj)/zvmlinux.initrd znetboot: zImage ifneq ($(ZNETBOOT),) - cp $(images)/$(ZNETBOOT) $(TFTPIMAGE) + cp $(images)/$(ZNETBOOT) $(tftpimage-y) else - cp $(images)/zImage.* $(TFTPIMAGE) + cp $(images)/zImage.* $(tftpimage-y) endif znetboot.initrd: zImage.initrd -ifneq ($(ZNETBOOTRD),) - cp $(images)/$(ZNETBOOTRD) $(TFTPIMAGE) +ifneq ($(znetbootrd-y),) + cp $(images)/$(znetbootrd-y) $(tftpimage-y) else - cp $(images)/zImage.* $(TFTPIMAGE) + cp $(images)/zImage.* $(tftpimage-y) endif $(images)/zImage-STRIPELF: $(obj)/zvmlinux - dd if=$(obj)/zvmlinux of=$(images)/zImage.$(END) skip=64 bs=1k + dd if=$(obj)/zvmlinux of=$(images)/zImage.$(end-y) skip=64 bs=1k $(images)/zImage.initrd-STRIPELF: $(obj)/zvmlinux.initrd - dd if=$(obj)/zvmlinux.initrd of=$(images)/zImage.initrd.$(END) \ + dd if=$(obj)/zvmlinux.initrd of=$(images)/zImage.initrd.$(end-y) \ skip=64 bs=1k $(images)/zImage-TREE: $(obj)/zvmlinux $(MKTREE) - $(MKTREE) $(obj)/zvmlinux $(images)/zImage.$(END) $(ENTRYPOINT) + $(MKTREE) $(obj)/zvmlinux $(images)/zImage.$(end-y) $(ENTRYPOINT) $(images)/zImage.initrd-TREE: $(obj)/zvmlinux.initrd $(MKTREE) - $(MKTREE) $(obj)/zvmlinux.initrd $(images)/zImage.initrd.$(END) \ + $(MKTREE) $(obj)/zvmlinux.initrd $(images)/zImage.initrd.$(end-y) \ $(ENTRYPOINT) $(images)/zImage-PPLUS: $(obj)/zvmlinux $(MKPREP) $(MKBUGBOOT) diff -Nru a/arch/ppc/boot/simple/embed_config.c b/arch/ppc/boot/simple/embed_config.c --- a/arch/ppc/boot/simple/embed_config.c Tue Sep 2 19:58:13 2003 +++ b/arch/ppc/boot/simple/embed_config.c Tue Sep 2 19:58:13 2003 @@ -20,6 +20,7 @@ #ifdef CONFIG_40x #include #endif +extern unsigned long timebase_period_ns; /* For those boards that don't provide one. */ @@ -768,6 +769,7 @@ #if defined(CONFIG_REDWOOD_5) || defined (CONFIG_REDWOOD_6) bd->bi_tbfreq = 27 * 1000 * 1000; #endif + timebase_period_ns = 1000000000 / bd->bi_tbfreq; } #endif /* CONFIG_BEECH */ #endif /* CONFIG_IBM_OPENBIOS */ diff -Nru a/arch/ppc/boot/simple/misc-embedded.c b/arch/ppc/boot/simple/misc-embedded.c --- a/arch/ppc/boot/simple/misc-embedded.c Tue Sep 2 19:58:13 2003 +++ b/arch/ppc/boot/simple/misc-embedded.c Tue Sep 2 19:58:13 2003 @@ -75,7 +75,7 @@ extern void embed_config(bd_t **bp); unsigned long -decompress_kernel(unsigned long load_addr, int num_words, unsigned long cksum, bd_t *bp) +load_kernel(unsigned long load_addr, int num_words, unsigned long cksum, bd_t *bp) { char *cp, ch; int timer = 0, zimage_size; diff -Nru a/arch/ppc/boot/simple/misc-spruce.c b/arch/ppc/boot/simple/misc-spruce.c --- a/arch/ppc/boot/simple/misc-spruce.c Tue Sep 2 19:58:16 2003 +++ b/arch/ppc/boot/simple/misc-spruce.c Tue Sep 2 19:58:16 2003 @@ -147,7 +147,7 @@ #define MEM_B2EA 0x60 unsigned long -decompress_kernel(unsigned long load_addr, int num_words, unsigned long cksum) +load_kernel(unsigned long load_addr, int num_words, unsigned long cksum) { int timer = 0; char *cp, ch; diff -Nru a/arch/ppc/boot/simple/misc.c b/arch/ppc/boot/simple/misc.c --- a/arch/ppc/boot/simple/misc.c Tue Sep 2 19:58:18 2003 +++ b/arch/ppc/boot/simple/misc.c Tue Sep 2 19:58:18 2003 @@ -252,3 +252,10 @@ return (struct bi_record *)rec_loc; } + +/* Allow decompress_kernel to be hooked into. This is the default. */ +void * __attribute__ ((weak)) +load_kernel(unsigned long load_addr, int num_words, unsigned long cksum) +{ + return decompress_kernel(load_addr, num_words, cksum); +} diff -Nru a/arch/ppc/boot/simple/relocate.S b/arch/ppc/boot/simple/relocate.S --- a/arch/ppc/boot/simple/relocate.S Tue Sep 2 19:58:15 2003 +++ b/arch/ppc/boot/simple/relocate.S Tue Sep 2 19:58:15 2003 @@ -183,7 +183,7 @@ mr r4,r7 /* Program length */ mr r5,r6 /* Checksum */ mr r6,r11 /* Residual data */ - bl decompress_kernel + bl load_kernel /* * Make sure the kernel knows we don't have things set in diff -Nru a/arch/ppc/boot/utils/mktree.c b/arch/ppc/boot/utils/mktree.c --- a/arch/ppc/boot/utils/mktree.c Tue Sep 2 19:58:18 2003 +++ b/arch/ppc/boot/utils/mktree.c Tue Sep 2 19:58:18 2003 @@ -86,7 +86,7 @@ } cksum = 0; - cp = (uint *)&bt; + cp = (void *)&bt; for (i=0; i #include +#include #include #include #include @@ -136,7 +137,7 @@ /* typedef void (*trapfunc_t)(void); */ static void kgdb_fault_handler(struct pt_regs *regs); -static void handle_exception (struct pt_regs *regs); +static int handle_exception (struct pt_regs *regs); #if 0 /* Install an exception handler for kgdb */ @@ -186,7 +187,7 @@ * return 0. */ static unsigned char * -mem2hex(char *mem, char *buf, int count) +mem2hex(const char *mem, char *buf, int count) { unsigned char ch; unsigned short tmp_s; @@ -460,14 +461,12 @@ int kgdb_bpt(struct pt_regs *regs) { - handle_exception(regs); - return 1; + return handle_exception(regs); } int kgdb_sstep(struct pt_regs *regs) { - handle_exception(regs); - return 1; + return handle_exception(regs); } void kgdb(struct pt_regs *regs) @@ -477,16 +476,14 @@ int kgdb_iabr_match(struct pt_regs *regs) { - printk("kgdb doesn't support iabr, what?!?\n"); - handle_exception(regs); - return 1; + printk(KERN_ERR "kgdb doesn't support iabr, what?!?\n"); + return handle_exception(regs); } int kgdb_dabr_match(struct pt_regs *regs) { - printk("kgdb doesn't support dabr, what?!?\n"); - handle_exception(regs); - return 1; + printk(KERN_ERR "kgdb doesn't support dabr, what?!?\n"); + return handle_exception(regs); } /* Convert the hardware trap type code to a unix signal number. */ @@ -559,7 +556,7 @@ /* * This function does all command processing for interfacing to gdb. */ -static void +static int handle_exception (struct pt_regs *regs) { int sigval; @@ -568,14 +565,19 @@ char *ptr; unsigned int msr; + /* We don't handle user-mode breakpoints. */ + if (user_mode(regs)) + return 0; + if (debugger_fault_handler) { debugger_fault_handler(regs); panic("kgdb longjump failed!\n"); } if (kgdb_active) { - printk("interrupt while in kgdb, returning\n"); - return; + printk(KERN_ERR "interrupt while in kgdb, returning\n"); + return 0; } + kgdb_active = 1; kgdb_started = 1; @@ -783,7 +785,7 @@ printk("remcomInBuffer: %s\n", remcomInBuffer); printk("remcomOutBuffer: %s\n", remcomOutBuffer); } - return; + return 1; case 's': kgdb_flush_cache_all(); @@ -800,7 +802,7 @@ printk("remcomInBuffer: %s\n", remcomInBuffer); printk("remcomOutBuffer: %s\n", remcomOutBuffer); } - return; + return 1; case 'r': /* Reset (if user process..exit ???)*/ panic("kgdb reset."); @@ -828,11 +830,11 @@ return; } - asm(" .globl breakinst - breakinst: .long 0x7d821008 - "); + asm(" .globl breakinst \n\ + breakinst: .long 0x7d821008"); } +#ifdef CONFIG_KGDB_CONSOLE /* Output string in GDB O-packet format if GDB has connected. If nothing output, returns 0 (caller must then handle output). */ int @@ -852,3 +854,4 @@ return 1; } +#endif diff -Nru a/arch/ppc/kernel/ppc_ksyms.c b/arch/ppc/kernel/ppc_ksyms.c --- a/arch/ppc/kernel/ppc_ksyms.c Tue Sep 2 19:58:19 2003 +++ b/arch/ppc/kernel/ppc_ksyms.c Tue Sep 2 19:58:19 2003 @@ -200,6 +200,7 @@ EXPORT_SYMBOL(flush_icache_user_range); EXPORT_SYMBOL(flush_dcache_page); EXPORT_SYMBOL(flush_tlb_kernel_range); +EXPORT_SYMBOL(flush_tlb_page); #ifdef CONFIG_ALTIVEC EXPORT_SYMBOL(last_task_used_altivec); EXPORT_SYMBOL(giveup_altivec); @@ -259,6 +260,15 @@ EXPORT_SYMBOL(pci_busdev_to_OF_node); EXPORT_SYMBOL(pci_device_to_OF_node); EXPORT_SYMBOL(pci_device_from_OF_node); +EXPORT_SYMBOL(of_find_node_by_name); +EXPORT_SYMBOL(of_find_node_by_type); +EXPORT_SYMBOL(of_find_compatible_node); +EXPORT_SYMBOL(of_find_node_by_path); +EXPORT_SYMBOL(of_find_all_nodes); +EXPORT_SYMBOL(of_get_parent); +EXPORT_SYMBOL(of_get_next_child); +EXPORT_SYMBOL(of_node_get); +EXPORT_SYMBOL(of_node_put); #endif /* CONFIG_PPC_OF */ #if defined(CONFIG_BOOTX_TEXT) EXPORT_SYMBOL(btext_update_display); diff -Nru a/arch/ppc/kernel/setup.c b/arch/ppc/kernel/setup.c --- a/arch/ppc/kernel/setup.c Tue Sep 2 19:58:19 2003 +++ b/arch/ppc/kernel/setup.c Tue Sep 2 19:58:19 2003 @@ -624,12 +624,10 @@ #if defined(CONFIG_KGDB) kgdb_map_scc(); set_debug_traps(); - if (strstr(cmd_line, "nokgdb")) - printk("kgdb default breakpoint deactivated on command line\n"); - else { + if (strstr(cmd_line, "gdb")) { if (ppc_md.progress) ppc_md.progress("setup_arch: kgdb breakpoint", 0x4000); - printk("kgdb default breakpoint activated\n"); + printk("kgdb breakpoint activated\n"); breakpoint(); } #endif diff -Nru a/arch/ppc/kernel/smp.c b/arch/ppc/kernel/smp.c --- a/arch/ppc/kernel/smp.c Tue Sep 2 19:58:19 2003 +++ b/arch/ppc/kernel/smp.c Tue Sep 2 19:58:19 2003 @@ -47,8 +47,8 @@ DEFINE_PER_CPU(unsigned int, prof_multiplier); DEFINE_PER_CPU(unsigned int, prof_counter); unsigned long cache_decay_ticks = HZ/100; -unsigned long cpu_online_map = cpumask_of_cpu(0); -unsigned long cpu_possible_map = 1UL; +cpumask_t cpu_online_map; +cpumask_t cpu_possible_map; int smp_hw_index[NR_CPUS]; struct thread_info *secondary_ti; @@ -336,7 +336,7 @@ void __init smp_prepare_cpus(unsigned int max_cpus) { - int num_cpus; + int num_cpus, i; /* Fixup boot cpu */ smp_store_cpu_info(smp_processor_id()); @@ -350,7 +350,8 @@ /* Probe platform for CPUs: always linear. */ num_cpus = smp_ops->probe(); - cpu_possible_map = (1 << num_cpus)-1; + for (i = 0; i < num_cpus; ++i) + cpu_set(i, cpu_possible_map); /* Backup CPU 0 state */ __save_cpu_setup(); diff -Nru a/arch/ppc/kernel/syscalls.c b/arch/ppc/kernel/syscalls.c --- a/arch/ppc/kernel/syscalls.c Tue Sep 2 19:58:19 2003 +++ b/arch/ppc/kernel/syscalls.c Tue Sep 2 19:58:19 2003 @@ -262,4 +262,14 @@ return error; } +/* + * We put the arguments in a different order so we only use 6 + * registers for arguments, rather than 7 as sys_fadvise64_64 needs + * (because `offset' goes in r5/r6). + */ +long ppc_fadvise64_64(int fd, int advice, loff_t offset, loff_t len) +{ + return sys_fadvise64_64(fd, offset, len, advice); +} + cond_syscall(sys_pciconfig_iobase); diff -Nru a/arch/ppc/platforms/mcpn765_serial.h b/arch/ppc/platforms/mcpn765_serial.h --- a/arch/ppc/platforms/mcpn765_serial.h Tue Sep 2 19:58:18 2003 +++ b/arch/ppc/platforms/mcpn765_serial.h Tue Sep 2 19:58:18 2003 @@ -30,7 +30,8 @@ #endif /* Rate for the 1.8432 Mhz clock for the onboard serial chip */ -#define BASE_BAUD ( 1843200 / 16 ) +#define BASE_BAUD ( 1843200 / 16 ) +#define UART_CLK 1843200 #ifdef CONFIG_SERIAL_DETECT_IRQ #define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF|ASYNC_SKIP_TEST|ASYNC_AUTO_IRQ) diff -Nru a/arch/ppc/platforms/mcpn765_setup.c b/arch/ppc/platforms/mcpn765_setup.c --- a/arch/ppc/platforms/mcpn765_setup.c Tue Sep 2 19:58:17 2003 +++ b/arch/ppc/platforms/mcpn765_setup.c Tue Sep 2 19:58:17 2003 @@ -31,6 +31,9 @@ #include #include #include +#include +#include /* for linux/serial_core.h */ +#include #include #include @@ -49,36 +52,94 @@ #include #include "mcpn765.h" +#include "mcpn765_serial.h" + static u_char mcpn765_openpic_initsenses[] __initdata = { - 0, /* 16: i8259 cascade (active high) */ - 1, /* 17: COM1,2,3,4 */ - 1, /* 18: Enet 1 (front panel) */ - 1, /* 19: HAWK WDT XXXX */ - 1, /* 20: 21554 PCI-PCI bridge */ - 1, /* 21: cPCI INTA# */ - 1, /* 22: cPCI INTB# */ - 1, /* 23: cPCI INTC# */ - 1, /* 24: cPCI INTD# */ - 1, /* 25: PMC1 INTA#, PMC2 INTB# */ - 1, /* 26: PMC1 INTB#, PMC2 INTC# */ - 1, /* 27: PMC1 INTC#, PMC2 INTD# */ - 1, /* 28: PMC1 INTD#, PMC2 INTA# */ - 1, /* 29: Enet 2 (connected to J3) */ - 1, /* 30: Abort Switch */ - 1, /* 31: RTC Alarm */ + (IRQ_SENSE_EDGE | IRQ_POLARITY_POSITIVE),/* 16: i8259 cascade */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),/* 17: COM1,2,3,4 */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),/* 18: Enet 1 (front) */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),/* 19: HAWK WDT XXXX */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),/* 20: 21554 bridge */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),/* 21: cPCI INTA# */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),/* 22: cPCI INTB# */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),/* 23: cPCI INTC# */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),/* 24: cPCI INTD# */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),/* 25: PMC1 INTA#,PMC2 INTB#*/ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),/* 26: PMC1 INTB#,PMC2 INTC#*/ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),/* 27: PMC1 INTC#,PMC2 INTD#*/ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),/* 28: PMC1 INTD#,PMC2 INTA#*/ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),/* 29: Enet 2 (J3) */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),/* 30: Abort Switch */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),/* 31: RTC Alarm */ }; extern u_int openpic_irq(void); extern char cmd_line[]; +extern void gen550_progress(char *, unsigned short); +extern void gen550_init(int, struct uart_port *); + int use_of_interrupt_tree = 0; static void mcpn765_halt(void); TODC_ALLOC(); +#if defined(CONFIG_SERIAL_8250) && \ + (defined(CONFIG_KGDB) || defined(CONFIG_SERIAL_TEXT_DEBUG)) +static void __init +mcpn765_early_serial_map(void) +{ + struct uart_port serial_req; + + /* Setup serial port access */ + memset(&serial_req, 0, sizeof(serial_req)); + serial_req.uartclk = UART_CLK; + serial_req.irq = 17; + serial_req.flags = STD_COM_FLAGS; + serial_req.iotype = SERIAL_IO_MEM; + serial_req.membase = (u_char *)MCPN765_SERIAL_1; + serial_req.regshift = 4; + + gen550_init(0, &serial_req); + + if (early_serial_setup(&serial_req) != 0) + printk(KERN_ERR "Early serial init of port 0 failed\n"); + + /* Assume early_serial_setup() doesn't modify serial_req */ + serial_req.line = 1; + serial_req.irq = 17; + serial_req.membase = (u_char *)MCPN765_SERIAL_2; + + gen550_init(1, &serial_req); + + if (early_serial_setup(&serial_req) != 0) + printk(KERN_ERR "Early serial init of port 1 failed\n"); + + /* Assume early_serial_setup() doesn't modify serial_req */ + serial_req.line = 2; + serial_req.irq = 17; + serial_req.membase = (u_char *)MCPN765_SERIAL_3; + + gen550_init(2, &serial_req); + + if (early_serial_setup(&serial_req) != 0) + printk(KERN_ERR "Early serial init of port 2 failed\n"); + + /* Assume early_serial_setup() doesn't modify serial_req */ + serial_req.line = 3; + serial_req.irq = 17; + serial_req.membase = (u_char *)MCPN765_SERIAL_4; + + gen550_init(3, &serial_req); + + if (early_serial_setup(&serial_req) != 0) + printk(KERN_ERR "Early serial init of port 3 failed\n"); +} +#endif + static void __init mcpn765_setup_arch(void) { @@ -187,12 +248,12 @@ if ( ppc_md.progress ) ppc_md.progress("init_irq: enter", 0); - openpic_init(1, NUM_8259_INTERRUPTS, NULL, -1); + openpic_init(NUM_8259_INTERRUPTS); for(i=0; i < NUM_8259_INTERRUPTS; i++) irq_desc[i].handler = &i8259_pic; - i8259_init(NULL); + i8259_init(0); if ( ppc_md.progress ) ppc_md.progress("init_irq: exit", 0); @@ -361,65 +422,15 @@ static __inline__ void mcpn765_set_bat(void) { - unsigned long bat3u, bat3l; - static int mapping_set = 0; - - if (!mapping_set) { - - __asm__ __volatile__( - " lis %0,0xf000\n \ - ori %1,%0,0x002a\n \ - ori %0,%0,0x1ffe\n \ - mtspr 0x21e,%0\n \ - mtspr 0x21f,%1\n \ - isync\n \ - sync " - : "=r" (bat3u), "=r" (bat3l)); - - mapping_set = 1; - } - - return; -} - -#ifdef CONFIG_SERIAL_TEXT_DEBUG -#include -#include -#include - -static struct serial_state rs_table[RS_TABLE_SIZE] = { - SERIAL_PORT_DFNS /* Defined in */ -}; - -static void -mcpn765_progress(char *s, unsigned short hex) -{ - volatile char c; - volatile unsigned long com_port; - u16 shift; - - com_port = rs_table[0].port; - shift = rs_table[0].iomem_reg_shift; - - while ((c = *s++) != 0) { - while ((*((volatile unsigned char *)com_port + - (UART_LSR << shift)) & UART_LSR_THRE) == 0) - ; - *(volatile unsigned char *)com_port = c; - - if (c == '\n') { - while ((*((volatile unsigned char *)com_port + - (UART_LSR << shift)) & UART_LSR_THRE) == 0) - ; - *(volatile unsigned char *)com_port = '\r'; - } - } + mb(); + mtspr(DBAT1U, 0xfe8000fe); + mtspr(DBAT1L, 0xfe80002a); + mb(); } -#endif /* CONFIG_SERIAL_TEXT_DEBUG */ void __init platform_init(unsigned long r3, unsigned long r4, unsigned long r5, - unsigned long r6, unsigned long r7) + unsigned long r6, unsigned long r7) { parse_bootinfo(find_bootinfo()); @@ -458,11 +469,13 @@ ppc_md.heartbeat_reset = 0; ppc_md.heartbeat_count = 0; -#ifdef CONFIG_SERIAL_TEXT_DEBUG - ppc_md.progress = mcpn765_progress; -#else /* !CONFIG_SERIAL_TEXT_DEBUG */ - ppc_md.progress = NULL; -#endif /* CONFIG_SERIAL_TEXT_DEBUG */ +#if defined(CONFIG_SERIAL_8250) && \ + (defined(CONFIG_KGDB) || defined(CONFIG_SERIAL_TEXT_DEBUG)) + mcpn765_early_serial_map(); +#ifdef CONFIG_SERIAL_TEXT_DEBUG + ppc_md.progress = gen550_progress; +#endif +#endif #if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE) ppc_ide_md.default_irq = mcpn765_ide_default_irq; diff -Nru a/arch/ppc/platforms/pmac_cpufreq.c b/arch/ppc/platforms/pmac_cpufreq.c --- a/arch/ppc/platforms/pmac_cpufreq.c Tue Sep 2 19:58:16 2003 +++ b/arch/ppc/platforms/pmac_cpufreq.c Tue Sep 2 19:58:16 2003 @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include @@ -31,12 +32,16 @@ #include #include +/* WARNING !!! This will cause calibrate_delay() to be called, + * but this is an __init function ! So you MUST go edit + * init/main.c to make it non-init before enabling DEBUG_FREQ + */ #undef DEBUG_FREQ extern void low_choose_750fx_pll(int pll); extern void low_sleep_handler(void); -extern void openpic_sleep_save_intrs(void); -extern void openpic_sleep_restore_intrs(void); +extern void openpic_suspend(struct sys_device *sysdev, u32 state); +extern void openpic_resume(struct sys_device *sysdev); extern void enable_kernel_altivec(void); extern void enable_kernel_fp(void); @@ -116,10 +121,7 @@ printk(KERN_DEBUG "HID1, before: %x\n", mfspr(SPRN_HID1)); #endif /* Disable all interrupt sources on openpic */ - openpic_sleep_save_intrs(); - - /* Make sure the PMU is idle */ - pmu_suspend(); + openpic_suspend(NULL, 1); /* Make sure the decrementer won't interrupt us */ asm volatile("mtdec %0" : : "r" (0x7fffffff)); @@ -153,11 +155,16 @@ pmu_request(&req, NULL, 6, PMU_CPU_SPEED, 'W', 'O', 'O', 'F', low_speed); while (!req.complete) pmu_poll(); - - pmac_call_feature(PMAC_FTR_SLEEP_STATE,NULL,1,1); + /* Prepare the northbridge for the speed transition */ + pmac_call_feature(PMAC_FTR_SLEEP_STATE,NULL,1,1); + + /* Call low level code to backup CPU state and recover from + * hardware reset + */ low_sleep_handler(); + /* Restore the northbridge */ pmac_call_feature(PMAC_FTR_SLEEP_STATE,NULL,1,0); /* Restore L2 cache */ @@ -174,13 +181,14 @@ printk(KERN_DEBUG "HID1, after: %x\n", mfspr(SPRN_HID1)); #endif + /* Restore low level PMU operations */ + pmu_unlock(); + /* Restore decrementer */ wakeup_decrementer(); /* Restore interrupts */ - openpic_sleep_restore_intrs(); - - pmu_resume(); + openpic_resume(NULL); /* Let interrupts flow again ... */ local_irq_enable(); @@ -195,13 +203,16 @@ static int __pmac do_set_cpu_speed(int speed_mode) { - struct cpufreq_freqs freqs; + struct cpufreq_freqs freqs; int rc; freqs.old = cur_freq; freqs.new = (speed_mode == PMAC_CPU_HIGH_SPEED) ? hi_freq : low_freq; freqs.cpu = smp_processor_id(); + if (freqs.old == freqs.new) + return 0; + cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); if (cpufreq_uses_pmu) rc = pmu_set_cpu_speed(speed_mode); @@ -275,7 +286,10 @@ struct device_node *cpunode; u32 *value; int has_freq_ctl = 0; - + + if (strstr(cmd_line, "nocpufreq")) + return 0; + /* Assume only one CPU */ cpunode = find_type_devices("cpu"); if (!cpunode) diff -Nru a/arch/ppc/platforms/pmac_pic.c b/arch/ppc/platforms/pmac_pic.c --- a/arch/ppc/platforms/pmac_pic.c Tue Sep 2 19:58:18 2003 +++ b/arch/ppc/platforms/pmac_pic.c Tue Sep 2 19:58:18 2003 @@ -22,6 +22,9 @@ #include #include #include +#include +#include +#include #include #include @@ -506,7 +509,7 @@ #endif /* CONFIG_XMON */ } -#ifdef CONFIG_PMAC_PBOOK +#ifdef CONFIG_PM /* * These procedures are used in implementing sleep on the powerbooks. * sleep_save_intrs() saves the states of all interrupt enables @@ -515,9 +518,32 @@ */ unsigned long sleep_save_mask[2]; -void __pmac -pmac_sleep_save_intrs(int viaint) +/* This used to be passed by the PMU driver but that link got + * broken with the new driver model. We use this tweak for now... + */ +static int pmacpic_find_viaint(void) { + int viaint = -1; + +#ifdef CONFIG_ADB_PMU + struct device_node *np; + + if (pmu_get_model() != PMU_OHARE_BASED) + goto not_found; + np = of_find_node_by_name(NULL, "via-pmu"); + if (np == NULL) + goto not_found; + viaint = np->intrs[0].line; +#endif /* CONFIG_ADB_PMU */ + +not_found: + return viaint; +} + +static int pmacpic_suspend(struct sys_device *sysdev, u32 state) +{ + int viaint = pmacpic_find_viaint(); + sleep_save_mask[0] = ppc_cached_irq_mask[0]; sleep_save_mask[1] = ppc_cached_irq_mask[1]; ppc_cached_irq_mask[0] = 0; @@ -531,10 +557,11 @@ /* make sure mask gets to controller before we return to caller */ mb(); (void)in_le32(&pmac_irq_hw[0]->enable); + + return 0; } -void __pmac -pmac_sleep_restore_intrs(void) +static int pmacpic_resume(struct sys_device *sysdev) { int i; @@ -545,5 +572,39 @@ for (i = 0; i < max_real_irqs; ++i) if (test_bit(i, sleep_save_mask)) pmac_unmask_irq(i); + + return 0; } -#endif /* CONFIG_PMAC_PBOOK */ + +#endif /* CONFIG_PM */ + +static struct sysdev_class pmacpic_sysclass = { + set_kset_name("pmac_pic"), +}; + +static struct sys_device device_pmacpic = { + .id = 0, + .cls = &pmacpic_sysclass, +}; + +static struct sysdev_driver driver_pmacpic = { +#ifdef CONFIG_PM + .suspend = &pmacpic_suspend, + .resume = &pmacpic_resume, +#endif /* CONFIG_PM */ +}; + +static int __init init_pmacpic_sysfs(void) +{ + if (max_irqs == 0) + return -ENODEV; + + printk(KERN_DEBUG "Registering pmac pic with sysfs...\n"); + sysdev_class_register(&pmacpic_sysclass); + sys_device_register(&device_pmacpic); + sysdev_driver_register(&pmacpic_sysclass, &driver_pmacpic); + return 0; +} + +subsys_initcall(init_pmacpic_sysfs); + diff -Nru a/arch/ppc/platforms/sandpoint.c b/arch/ppc/platforms/sandpoint.c --- a/arch/ppc/platforms/sandpoint.c Tue Sep 2 19:58:20 2003 +++ b/arch/ppc/platforms/sandpoint.c Tue Sep 2 19:58:20 2003 @@ -357,6 +357,21 @@ } /* + * Fix IDE interrupts. + */ +static int __init +sandpoint_fix_winbond_83553(void) +{ + /* Make all 8259 interrupt level sensitive */ + outb(0xf8, 0x4d0); + outb(0xde, 0x4d1); + + return 0; +} + +arch_initcall(sandpoint_fix_winbond_83553); + +/* * Initialize the ISA devices on the Nat'l PC87308VUL SuperIO chip. */ static int __init @@ -390,21 +405,6 @@ } arch_initcall(sandpoint_setup_natl_87308); - -/* - * Fix IDE interrupts. - */ -static int __init -sandpoint_fix_winbond_83553(void) -{ - /* Make all 8259 interrupt level sensitive */ - outb(0xf8, 0x4d0); - outb(0xde, 0x4d1); - - return 0; -} - -arch_initcall(sandpoint_fix_winbond_83553); static int __init sandpoint_request_io(void) diff -Nru a/arch/ppc/platforms/sandpoint.h b/arch/ppc/platforms/sandpoint.h --- a/arch/ppc/platforms/sandpoint.h Tue Sep 2 19:58:15 2003 +++ b/arch/ppc/platforms/sandpoint.h Tue Sep 2 19:58:15 2003 @@ -61,9 +61,9 @@ #define UART_CLK 1843200 #ifdef CONFIG_SERIAL_DETECT_IRQ -#define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF|ASYNC_SKIP_TEST|ASYNC_AUTO_IRQ) +#define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF|ASYNC_AUTO_IRQ) #else -#define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF|ASYNC_SKIP_TEST) +#define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF) #endif #define STD_SERIAL_PORT_DFNS \ diff -Nru a/arch/ppc/syslib/of_device.c b/arch/ppc/syslib/of_device.c --- a/arch/ppc/syslib/of_device.c Tue Sep 2 19:58:20 2003 +++ b/arch/ppc/syslib/of_device.c Tue Sep 2 19:58:20 2003 @@ -15,8 +15,8 @@ * Used by a driver to check whether an of_device present in the * system is in its list of supported devices. */ -const struct of_match * -of_match_device(const struct of_match *matches, const struct of_device *dev) +const struct of_match * of_match_device(const struct of_match *matches, + const struct of_device *dev) { if (!dev->node) return NULL; @@ -38,8 +38,7 @@ return NULL; } -static int -of_platform_bus_match(struct device *dev, struct device_driver *drv) +static int of_platform_bus_match(struct device *dev, struct device_driver *drv) { struct of_device * of_dev = to_of_device(dev); struct of_platform_driver * of_drv = to_of_platform_driver(drv); @@ -51,21 +50,27 @@ return of_match_device(matches, of_dev) != NULL; } -struct bus_type of_platform_bus_type = { - name: "of_platform", - match: of_platform_bus_match, -}; +struct of_device *of_dev_get(struct of_device *dev) +{ + struct device *tmp; + + if (!dev) + return NULL; + tmp = get_device(&dev->dev); + if (tmp) + return to_of_device(tmp); + else + return NULL; +} -static int __init -of_bus_driver_init(void) +void of_dev_put(struct of_device *dev) { - return bus_register(&of_platform_bus_type); + if (dev) + put_device(&dev->dev); } -postcore_initcall(of_bus_driver_init); -static int -of_device_probe(struct device *dev) +static int of_device_probe(struct device *dev) { int error = -ENODEV; struct of_platform_driver *drv; @@ -78,22 +83,18 @@ if (!drv->probe) return error; -/* if (!try_module_get(driver->owner)) { - printk(KERN_ERR "Can't get a module reference for %s\n", driver->name); - return error; - } -*/ + of_dev_get(of_dev); + match = of_match_device(drv->match_table, of_dev); if (match) error = drv->probe(of_dev, match); -/* - module_put(driver->owner); -*/ + if (error) + of_dev_put(of_dev); + return error; } -static int -of_device_remove(struct device *dev) +static int of_device_remove(struct device *dev) { struct of_device * of_dev = to_of_device(dev); struct of_platform_driver * drv = to_of_platform_driver(of_dev->dev.driver); @@ -103,32 +104,43 @@ return 0; } -static int -of_device_suspend(struct device *dev, u32 state, u32 level) +static int of_device_suspend(struct device *dev, u32 state) { struct of_device * of_dev = to_of_device(dev); struct of_platform_driver * drv = to_of_platform_driver(of_dev->dev.driver); int error = 0; if (drv && drv->suspend) - error = drv->suspend(of_dev, state, level); + error = drv->suspend(of_dev, state); return error; } -static int -of_device_resume(struct device * dev, u32 level) +static int of_device_resume(struct device * dev) { struct of_device * of_dev = to_of_device(dev); struct of_platform_driver * drv = to_of_platform_driver(of_dev->dev.driver); int error = 0; if (drv && drv->resume) - error = drv->resume(of_dev, level); + error = drv->resume(of_dev); return error; } -int -of_register_driver(struct of_platform_driver *drv) +struct bus_type of_platform_bus_type = { + .name = "of_platform", + .match = of_platform_bus_match, + .suspend = of_device_suspend, + .resume = of_device_resume, +}; + +static int __init of_bus_driver_init(void) +{ + return bus_register(&of_platform_bus_type); +} + +postcore_initcall(of_bus_driver_init); + +int of_register_driver(struct of_platform_driver *drv) { int count = 0; @@ -136,8 +148,6 @@ drv->driver.name = drv->name; drv->driver.bus = &of_platform_bus_type; drv->driver.probe = of_device_probe; - drv->driver.resume = of_device_resume; - drv->driver.suspend = of_device_suspend; drv->driver.remove = of_device_remove; /* register with core */ @@ -145,15 +155,13 @@ return count ? count : 1; } -void -of_unregister_driver(struct of_platform_driver *drv) +void of_unregister_driver(struct of_platform_driver *drv) { driver_unregister(&drv->driver); } -static ssize_t -dev_show_devspec(struct device *dev, char *buf) +static ssize_t dev_show_devspec(struct device *dev, char *buf) { struct of_device *ofdev; @@ -163,8 +171,22 @@ static DEVICE_ATTR(devspec, S_IRUGO, dev_show_devspec, NULL); -int -of_device_register(struct of_device *ofdev) +/** + * of_release_dev - free an of device structure when all users of it are finished. + * @dev: device that's been disconnected + * + * Will be called only by the device core when all users of this of device are + * done. + */ +void of_release_dev(struct device *dev) +{ + struct of_device *ofdev; + + ofdev = to_of_device(dev); + kfree(ofdev); +} + +int of_device_register(struct of_device *ofdev) { int rc; struct of_device **odprop; @@ -197,21 +219,20 @@ return 0; } -void -of_device_unregister(struct of_device *ofdev) +void of_device_unregister(struct of_device *ofdev) { struct of_device **odprop; device_remove_file(&ofdev->dev, &dev_attr_devspec); - device_unregister(&ofdev->dev); odprop = (struct of_device **)get_property(ofdev->node, "linux,device", NULL); if (odprop) *odprop = NULL; + + device_unregister(&ofdev->dev); } -struct of_device* -of_platform_device_create(struct device_node *np, const char *bus_id) +struct of_device* of_platform_device_create(struct device_node *np, const char *bus_id) { struct of_device *dev; u32 *reg; @@ -226,6 +247,7 @@ dev->dev.dma_mask = &dev->dma_mask; dev->dev.parent = NULL; dev->dev.bus = &of_platform_bus_type; + dev->dev.release = of_release_dev; reg = (u32 *)get_property(np, "reg", NULL); strlcpy(dev->dev.bus_id, bus_id, BUS_ID_SIZE); @@ -244,4 +266,7 @@ EXPORT_SYMBOL(of_unregister_driver); EXPORT_SYMBOL(of_device_register); EXPORT_SYMBOL(of_device_unregister); +EXPORT_SYMBOL(of_dev_get); +EXPORT_SYMBOL(of_dev_put); EXPORT_SYMBOL(of_platform_device_create); +EXPORT_SYMBOL(of_release_dev); diff -Nru a/arch/ppc/syslib/open_pic.c b/arch/ppc/syslib/open_pic.c --- a/arch/ppc/syslib/open_pic.c Tue Sep 2 19:58:16 2003 +++ b/arch/ppc/syslib/open_pic.c Tue Sep 2 19:58:16 2003 @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include @@ -276,7 +277,7 @@ } #endif -#if defined(CONFIG_EPIC_SERIAL_MODE) || defined(CONFIG_PMAC_PBOOK) +#if defined(CONFIG_EPIC_SERIAL_MODE) || defined(CONFIG_PM) static void openpic_reset(void) { openpic_setfield(&OpenPIC->Global.Global_Configuration0, @@ -532,7 +533,7 @@ openpic_write(&OpenPIC->Global.Processor_Initialization, mask); } -#if defined(CONFIG_SMP) || defined(CONFIG_PMAC_PBOOK) +#if defined(CONFIG_SMP) || defined(CONFIG_PM) static spinlock_t openpic_setup_lock = SPIN_LOCK_UNLOCKED; #endif @@ -864,20 +865,55 @@ } #endif /* CONFIG_SMP */ -#ifdef CONFIG_PMAC_PBOOK +#ifdef CONFIG_PM + +/* + * We implement the IRQ controller as a sysdev and put it + * to sleep at powerdown stage (the callback is named suspend, + * but it's old semantics, for the Device Model, it's really + * powerdown). The possible problem is that another sysdev that + * happens to be suspend after this one will have interrupts off, + * that may be an issue... For now, this isn't an issue on pmac + * though... + */ + static u32 save_ipi_vp[OPENPIC_NUM_IPI]; static u32 save_irq_src_vp[OPENPIC_MAX_SOURCES]; static u32 save_irq_src_dest[OPENPIC_MAX_SOURCES]; static u32 save_cpu_task_pri[OPENPIC_MAX_PROCESSORS]; +static int openpic_suspend_count; + +static void openpic_cached_enable_irq(u_int irq) +{ + check_arg_irq(irq); + save_irq_src_vp[irq - open_pic_irq_offset] &= ~OPENPIC_MASK; +} -void __pmac -openpic_sleep_save_intrs(void) +static void openpic_cached_disable_irq(u_int irq) +{ + check_arg_irq(irq); + save_irq_src_vp[irq - open_pic_irq_offset] |= OPENPIC_MASK; +} + +/* WARNING: Can be called directly by the cpufreq code with NULL parameter, + * we need something better to deal with that... Maybe switch to S1 for + * cpufreq changes + */ +int openpic_suspend(struct sys_device *sysdev, u32 state) { int i; unsigned long flags; spin_lock_irqsave(&openpic_setup_lock, flags); + if (openpic_suspend_count++ > 0) { + spin_unlock_irqrestore(&openpic_setup_lock, flags); + return 0; + } + + open_pic.enable = openpic_cached_enable_irq; + open_pic.disable = openpic_cached_disable_irq; + for (i=0; iProcessor[i].Current_Task_Priority); openpic_writefield(&OpenPIC->Processor[i].Current_Task_Priority, @@ -889,38 +925,112 @@ for (i=0; iVector_Priority) - & ~OPENPIC_ACTIVITY; + save_irq_src_vp[i] = openpic_read(&ISR[i]->Vector_Priority) & ~OPENPIC_ACTIVITY; save_irq_src_dest[i] = openpic_read(&ISR[i]->Destination); } + spin_unlock_irqrestore(&openpic_setup_lock, flags); + + return 0; } -void __pmac -openpic_sleep_restore_intrs(void) +/* WARNING: Can be called directly by the cpufreq code with NULL parameter, + * we need something better to deal with that... Maybe switch to S1 for + * cpufreq changes + */ +int openpic_resume(struct sys_device *sysdev) { int i; unsigned long flags; + u32 vppmask = OPENPIC_PRIORITY_MASK | OPENPIC_VECTOR_MASK | + OPENPIC_SENSE_MASK | OPENPIC_POLARITY_MASK | + OPENPIC_MASK; spin_lock_irqsave(&openpic_setup_lock, flags); + if ((--openpic_suspend_count) > 0) { + spin_unlock_irqrestore(&openpic_setup_lock, flags); + return 0; + } + openpic_reset(); + /* OpenPIC sometimes seem to need some time to be fully back up... */ + do { + openpic_set_spurious(OPENPIC_VEC_SPURIOUS+open_pic_irq_offset); + } while(openpic_readfield(&OpenPIC->Global.Spurious_Vector, OPENPIC_VECTOR_MASK) + != (OPENPIC_VEC_SPURIOUS + open_pic_irq_offset)); + + openpic_disable_8259_pass_through(); + for (i=0; iGlobal.IPI_Vector_Priority(i), save_ipi_vp[i]); for (i=0; iVector_Priority, save_irq_src_vp[i]); openpic_write(&ISR[i]->Destination, save_irq_src_dest[i]); + openpic_write(&ISR[i]->Vector_Priority, save_irq_src_vp[i]); + /* make sure mask gets to controller before we return to user */ + do { + openpic_write(&ISR[i]->Vector_Priority, save_irq_src_vp[i]); + } while (openpic_readfield(&ISR[i]->Vector_Priority, vppmask) + != (save_irq_src_vp[i] & vppmask)); } - openpic_set_spurious(OPENPIC_VEC_SPURIOUS+open_pic_irq_offset); - openpic_disable_8259_pass_through(); for (i=0; iProcessor[i].Current_Task_Priority, save_cpu_task_pri[i]); + open_pic.enable = openpic_enable_irq; + open_pic.disable = openpic_disable_irq; + spin_unlock_irqrestore(&openpic_setup_lock, flags); + + return 0; +} + +#endif /* CONFIG_PM */ + +static struct sysdev_class openpic_sysclass = { + set_kset_name("openpic"), +}; + +static struct sys_device device_openpic = { + .id = 0, + .cls = &openpic_sysclass, +}; + +static struct sysdev_driver driver_openpic = { +#ifdef CONFIG_PM + .suspend = &openpic_suspend, + .resume = &openpic_resume, +#endif /* CONFIG_PM */ +}; + +static int __init init_openpic_sysfs(void) +{ + int rc; + + if (!OpenPIC_Addr) + return -ENODEV; + printk(KERN_DEBUG "Registering openpic with sysfs...\n"); + rc = sysdev_class_register(&openpic_sysclass); + if (rc) { + printk(KERN_ERR "Failed registering openpic sys class\n"); + return -ENODEV; + } + rc = sys_device_register(&device_openpic); + if (rc) { + printk(KERN_ERR "Failed registering openpic sys device\n"); + return -ENODEV; + } + rc = sysdev_driver_register(&openpic_sysclass, &driver_openpic); + if (rc) { + printk(KERN_ERR "Failed registering openpic sys driver\n"); + return -ENODEV; + } + return 0; } -#endif /* CONFIG_PMAC_PBOOK */ + +subsys_initcall(init_openpic_sysfs); + diff -Nru a/arch/ppc/syslib/prom.c b/arch/ppc/syslib/prom.c --- a/arch/ppc/syslib/prom.c Tue Sep 2 19:58:13 2003 +++ b/arch/ppc/syslib/prom.c Tue Sep 2 19:58:13 2003 @@ -941,6 +941,184 @@ return NULL; } +/******* + * + * New implementation of the OF "find" APIs, return a refcounted + * object, call of_node_put() when done. Currently, still lacks + * locking as old implementation, this is beeing done for ppc64. + * + * Note that property management will need some locking as well, + * this isn't dealt with yet + * + *******/ + +/** + * of_find_node_by_name - Find a node by it's "name" property + * @from: The node to start searching from or NULL, the node + * you pass will not be searched, only the next one + * will; typically, you pass what the previous call + * returned. of_node_put() will be called on it + * @name: The name string to match against + * + * Returns a node pointer with refcount incremented, use + * of_node_put() on it when done. + */ +struct device_node *of_find_node_by_name(struct device_node *from, + const char *name) +{ + struct device_node *np = from ? from->allnext : allnodes; + + for (; np != 0; np = np->allnext) + if (np->name != 0 && strcasecmp(np->name, name) == 0) + break; + if (from) + of_node_put(from); + return of_node_get(np); +} + +/** + * of_find_node_by_type - Find a node by it's "device_type" property + * @from: The node to start searching from or NULL, the node + * you pass will not be searched, only the next one + * will; typically, you pass what the previous call + * returned. of_node_put() will be called on it + * @name: The type string to match against + * + * Returns a node pointer with refcount incremented, use + * of_node_put() on it when done. + */ +struct device_node *of_find_node_by_type(struct device_node *from, + const char *type) +{ + struct device_node *np = from ? from->allnext : allnodes; + + for (; np != 0; np = np->allnext) + if (np->type != 0 && strcasecmp(np->type, type) == 0) + break; + if (from) + of_node_put(from); + return of_node_get(np); +} + +/** + * of_find_compatible_node - Find a node based on type and one of the + * tokens in it's "compatible" property + * @from: The node to start searching from or NULL, the node + * you pass will not be searched, only the next one + * will; typically, you pass what the previous call + * returned. of_node_put() will be called on it + * @type: The type string to match "device_type" or NULL to ignore + * @compatible: The string to match to one of the tokens in the device + * "compatible" list. + * + * Returns a node pointer with refcount incremented, use + * of_node_put() on it when done. + */ +struct device_node *of_find_compatible_node(struct device_node *from, + const char *type, const char *compatible) +{ + struct device_node *np = from ? from->allnext : allnodes; + + for (; np != 0; np = np->allnext) { + if (type != NULL + && !(np->type != 0 && strcasecmp(np->type, type) == 0)) + continue; + if (device_is_compatible(np, compatible)) + break; + } + if (from) + of_node_put(from); + return of_node_get(np); +} + +/** + * of_find_node_by_path - Find a node matching a full OF path + * @path: The full path to match + * + * Returns a node pointer with refcount incremented, use + * of_node_put() on it when done. + */ +struct device_node *of_find_node_by_path(const char *path) +{ + struct device_node *np = allnodes; + + for (; np != 0; np = np->allnext) + if (np->full_name != 0 && strcasecmp(np->full_name, path) == 0) + break; + return of_node_get(np); +} + +/** + * of_find_all_nodes - Get next node in global list + * @prev: Previous node or NULL to start iteration + * of_node_put() will be called on it + * + * Returns a node pointer with refcount incremented, use + * of_node_put() on it when done. + */ +struct device_node *of_find_all_nodes(struct device_node *prev) +{ + return of_node_get(prev ? prev->allnext : allnodes); +} + +/** + * of_get_parent - Get a node's parent if any + * @node: Node to get parent + * + * Returns a node pointer with refcount incremented, use + * of_node_put() on it when done. + */ +struct device_node *of_get_parent(const struct device_node *node) +{ + return node ? of_node_get(node->parent) : NULL; +} + +/** + * of_get_next_child - Iterate a node childs + * @node: parent node + * @prev: previous child of the parent node, or NULL to get first + * + * Returns a node pointer with refcount incremented, use + * of_node_put() on it when done. + */ +struct device_node *of_get_next_child(const struct device_node *node, + struct device_node *prev) +{ + struct device_node *next = prev ? prev->sibling : node->child; + + for (; next != 0; next = next->sibling) + if (of_node_get(next)) + break; + if (prev) + of_node_put(prev); + return next; +} + +/** + * of_node_get - Increment refcount of a node + * @node: Node to inc refcount, NULL is supported to + * simplify writing of callers + * + * Returns the node itself or NULL if gone. Current implementation + * does nothing as we don't yet do dynamic node allocation on ppc32 + */ +struct device_node *of_node_get(struct device_node *node) +{ + return node; +} + +/** + * of_node_put - Decrement refcount of a node + * @node: Node to dec refcount, NULL is supported to + * simplify writing of callers + * + * Current implementation does nothing as we don't yet do dynamic node + * allocation on ppc32 + */ +void of_node_put(struct device_node *node) +{ +} + /* * Find the device_node with a given phandle. */ diff -Nru a/arch/ppc/xmon/start.c b/arch/ppc/xmon/start.c --- a/arch/ppc/xmon/start.c Tue Sep 2 19:58:12 2003 +++ b/arch/ppc/xmon/start.c Tue Sep 2 19:58:12 2003 @@ -225,14 +225,13 @@ static int scc_initialized = 0; void xmon_init_scc(void); -extern void pmu_poll(void); extern void cuda_poll(void); static inline void do_poll_adb(void) { #ifdef CONFIG_ADB_PMU if (sys_ctrler == SYS_CTRLER_PMU) - pmu_poll(); + pmu_poll_adb(); #endif /* CONFIG_ADB_PMU */ #ifdef CONFIG_ADB_CUDA if (sys_ctrler == SYS_CTRLER_CUDA) diff -Nru a/arch/ppc64/Kconfig b/arch/ppc64/Kconfig --- a/arch/ppc64/Kconfig Tue Sep 2 19:58:16 2003 +++ b/arch/ppc64/Kconfig Tue Sep 2 19:58:16 2003 @@ -175,22 +175,6 @@ bool default PCI -# only elf supported, a.out is not -- Cort -config KCORE_ELF - bool - depends on PROC_FS - default y - help - If you enabled support for /proc file system then the file - /proc/kcore will contain the kernel core image in ELF format. This - can be used in gdb: - - $ cd /usr/src/linux ; gdb vmlinux /proc/kcore - - This is especially useful if you have compiled the kernel with the - "-g" option to preserve debugging information. It is mainly used - for examining kernel data structures on the live kernel. - source "fs/Kconfig.binfmt" source "drivers/pci/Kconfig" diff -Nru a/arch/ppc64/kernel/ioctl32.c b/arch/ppc64/kernel/ioctl32.c --- a/arch/ppc64/kernel/ioctl32.c Tue Sep 2 19:58:20 2003 +++ b/arch/ppc64/kernel/ioctl32.c Tue Sep 2 19:58:20 2003 @@ -725,7 +725,7 @@ #define IOCTL_TABLE_START \ struct ioctl_trans ioctl_start[] = { #define IOCTL_TABLE_END \ - }; struct ioctl_trans ioctl_end[0]; + }; IOCTL_TABLE_START #include @@ -763,3 +763,5 @@ HANDLE_IOCTL(USBDEVFS_REAPURBNDELAY32, do_usbdevfs_reapurb) HANDLE_IOCTL(USBDEVFS_DISCSIGNAL32, do_usbdevfs_discsignal) IOCTL_TABLE_END + +int ioctl_table_size = ARRAY_SIZE(ioctl_start); diff -Nru a/arch/ppc64/kernel/proc_ppc64.c b/arch/ppc64/kernel/proc_ppc64.c --- a/arch/ppc64/kernel/proc_ppc64.c Tue Sep 2 19:58:17 2003 +++ b/arch/ppc64/kernel/proc_ppc64.c Tue Sep 2 19:58:17 2003 @@ -47,9 +47,9 @@ static int page_map_mmap( struct file *file, struct vm_area_struct *vma ); static struct file_operations page_map_fops = { - llseek: page_map_seek, - read: page_map_read, - mmap: page_map_mmap + .llseek = page_map_seek, + .read = page_map_read, + .mmap = page_map_mmap }; diff -Nru a/arch/ppc64/kernel/scanlog.c b/arch/ppc64/kernel/scanlog.c --- a/arch/ppc64/kernel/scanlog.c Tue Sep 2 19:58:19 2003 +++ b/arch/ppc64/kernel/scanlog.c Tue Sep 2 19:58:19 2003 @@ -190,11 +190,11 @@ } struct file_operations scanlog_fops = { - owner: THIS_MODULE, - read: scanlog_read, - write: scanlog_write, - open: scanlog_open, - release: scanlog_release, + .owner = THIS_MODULE, + .read = scanlog_read, + .write = scanlog_write, + .open = scanlog_open, + .release = scanlog_release, }; int __init scanlog_init(void) diff -Nru a/arch/s390/Kconfig b/arch/s390/Kconfig --- a/arch/s390/Kconfig Tue Sep 2 19:58:15 2003 +++ b/arch/s390/Kconfig Tue Sep 2 19:58:15 2003 @@ -217,10 +217,6 @@ endchoice -config KCORE_ELF - bool - default y - source "fs/Kconfig.binfmt" config PROCESS_DEBUG diff -Nru a/arch/s390/kernel/compat_ioctl.c b/arch/s390/kernel/compat_ioctl.c --- a/arch/s390/kernel/compat_ioctl.c Tue Sep 2 19:58:17 2003 +++ b/arch/s390/kernel/compat_ioctl.c Tue Sep 2 19:58:17 2003 @@ -808,7 +808,7 @@ #define IOCTL_TABLE_START \ struct ioctl_trans ioctl_start[] = { #define IOCTL_TABLE_END \ - }; struct ioctl_trans ioctl_end[0]; + }; IOCTL_TABLE_START #include @@ -899,3 +899,5 @@ HANDLE_IOCTL(BLKPG, blkpg_ioctl_trans) IOCTL_TABLE_END + +int ioctl_table_size = ARRAY_SIZE(ioctl_start); diff -Nru a/arch/sh/Kconfig b/arch/sh/Kconfig --- a/arch/sh/Kconfig Tue Sep 2 19:58:19 2003 +++ b/arch/sh/Kconfig Tue Sep 2 19:58:19 2003 @@ -729,40 +729,6 @@ menu "Executable file formats" -choice - prompt "Kernel core (/proc/kcore) format" - depends on PROC_FS - default KCORE_ELF - -config KCORE_ELF - bool "ELF" - ---help--- - If you enabled support for /proc file system then the file - /proc/kcore will contain the kernel core image. This can be used - in gdb: - - $ cd /usr/src/linux ; gdb vmlinux /proc/kcore - - You have two choices here: ELF and A.OUT. Selecting ELF will make - /proc/kcore appear in ELF core format as defined by the Executable - and Linking Format specification. Selecting A.OUT will choose the - old "a.out" format which may be necessary for some old versions - of binutils or on some architectures. - - This is especially useful if you have compiled the kernel with the - "-g" option to preserve debugging information. It is mainly used - for examining kernel data structures on the live kernel so if you - don't understand what this means or are not a kernel hacker, just - leave it at its default value ELF. - -config KCORE_AOUT - bool "A.OUT" - help - Not necessary unless you're using a very out-of-date binutils - version. You probably want KCORE_ELF. - -endchoice - source "fs/Kconfig.binfmt" endmenu diff -Nru a/arch/sh/boards/adx/mach.c b/arch/sh/boards/adx/mach.c --- a/arch/sh/boards/adx/mach.c Tue Sep 2 19:58:15 2003 +++ b/arch/sh/boards/adx/mach.c Tue Sep 2 19:58:15 2003 @@ -24,41 +24,41 @@ */ struct sh_machine_vector mv_adx __initmv = { - mv_nr_irqs: 48, + .mv_nr_irqs = 48, - mv_inb: adx_inb, - mv_inw: adx_inw, - mv_inl: adx_inl, - mv_outb: adx_outb, - mv_outw: adx_outw, - mv_outl: adx_outl, - - mv_inb_p: adx_inb_p, - mv_inw_p: adx_inw, - mv_inl_p: adx_inl, - mv_outb_p: adx_outb_p, - mv_outw_p: adx_outw, - mv_outl_p: adx_outl, - - mv_insb: adx_insb, - mv_insw: adx_insw, - mv_insl: adx_insl, - mv_outsb: adx_outsb, - mv_outsw: adx_outsw, - mv_outsl: adx_outsl, - - mv_readb: adx_readb, - mv_readw: adx_readw, - mv_readl: adx_readl, - mv_writeb: adx_writeb, - mv_writew: adx_writew, - mv_writel: adx_writel, + .mv_inb = adx_inb, + .mv_inw = adx_inw, + .mv_inl = adx_inl, + .mv_outb = adx_outb, + .mv_outw = adx_outw, + .mv_outl = adx_outl, + + .mv_inb_p = adx_inb_p, + .mv_inw_p = adx_inw, + .mv_inl_p = adx_inl, + .mv_outb_p = adx_outb_p, + .mv_outw_p = adx_outw, + .mv_outl_p = adx_outl, + + .mv_insb = adx_insb, + .mv_insw = adx_insw, + .mv_insl = adx_insl, + .mv_outsb = adx_outsb, + .mv_outsw = adx_outsw, + .mv_outsl = adx_outsl, + + .mv_readb = adx_readb, + .mv_readw = adx_readw, + .mv_readl = adx_readl, + .mv_writeb = adx_writeb, + .mv_writew = adx_writew, + .mv_writel = adx_writel, - mv_ioremap: adx_ioremap, - mv_iounmap: adx_iounmap, + .mv_ioremap = adx_ioremap, + .mv_iounmap = adx_iounmap, - mv_isa_port2addr: adx_isa_port2addr, + .mv_isa_port2addr = adx_isa_port2addr, - mv_init_irq: init_adx_IRQ, + .mv_init_irq = init_adx_IRQ, }; ALIAS_MV(adx) diff -Nru a/arch/sh/boards/bigsur/mach.c b/arch/sh/boards/bigsur/mach.c --- a/arch/sh/boards/bigsur/mach.c Tue Sep 2 19:58:17 2003 +++ b/arch/sh/boards/bigsur/mach.c Tue Sep 2 19:58:17 2003 @@ -28,44 +28,44 @@ extern void init_bigsur_IRQ(void); struct sh_machine_vector mv_bigsur __initmv = { - mv_nr_irqs: NR_IRQS, // Defined in - mv_inb: bigsur_inb, - mv_inw: bigsur_inw, - mv_inl: bigsur_inl, - mv_outb: bigsur_outb, - mv_outw: bigsur_outw, - mv_outl: bigsur_outl, - - mv_inb_p: bigsur_inb_p, - mv_inw_p: bigsur_inw, - mv_inl_p: bigsur_inl, - mv_outb_p: bigsur_outb_p, - mv_outw_p: bigsur_outw, - mv_outl_p: bigsur_outl, - - mv_insb: bigsur_insb, - mv_insw: bigsur_insw, - mv_insl: bigsur_insl, - mv_outsb: bigsur_outsb, - mv_outsw: bigsur_outsw, - mv_outsl: bigsur_outsl, - - mv_readb: generic_readb, - mv_readw: generic_readw, - mv_readl: generic_readl, - mv_writeb: generic_writeb, - mv_writew: generic_writew, - mv_writel: generic_writel, + .mv_nr_irqs = NR_IRQS, // Defined in + .mv_inb = bigsur_inb, + .mv_inw = bigsur_inw, + .mv_inl = bigsur_inl, + .mv_outb = bigsur_outb, + .mv_outw = bigsur_outw, + .mv_outl = bigsur_outl, + + .mv_inb_p = bigsur_inb_p, + .mv_inw_p = bigsur_inw, + .mv_inl_p = bigsur_inl, + .mv_outb_p = bigsur_outb_p, + .mv_outw_p = bigsur_outw, + .mv_outl_p = bigsur_outl, + + .mv_insb = bigsur_insb, + .mv_insw = bigsur_insw, + .mv_insl = bigsur_insl, + .mv_outsb = bigsur_outsb, + .mv_outsw = bigsur_outsw, + .mv_outsl = bigsur_outsl, + + .mv_readb = generic_readb, + .mv_readw = generic_readw, + .mv_readl = generic_readl, + .mv_writeb = generic_writeb, + .mv_writew = generic_writew, + .mv_writel = generic_writel, - mv_ioremap: generic_ioremap, - mv_iounmap: generic_iounmap, + .mv_ioremap = generic_ioremap, + .mv_iounmap = generic_iounmap, - mv_isa_port2addr: bigsur_isa_port2addr, - mv_irq_demux: bigsur_irq_demux, + .mv_isa_port2addr = bigsur_isa_port2addr, + .mv_irq_demux = bigsur_irq_demux, - mv_init_irq: init_bigsur_IRQ, + .mv_init_irq = init_bigsur_IRQ, #ifdef CONFIG_HEARTBEAT - mv_heartbeat: heartbeat_bigsur, + .mv_heartbeat = heartbeat_bigsur, #endif }; diff -Nru a/arch/sh/boards/cat68701/mach.c b/arch/sh/boards/cat68701/mach.c --- a/arch/sh/boards/cat68701/mach.c Tue Sep 2 19:58:19 2003 +++ b/arch/sh/boards/cat68701/mach.c Tue Sep 2 19:58:19 2003 @@ -23,44 +23,44 @@ */ struct sh_machine_vector mv_cat68701 __initmv = { - mv_nr_irqs: 32, - mv_inb: cat68701_inb, - mv_inw: cat68701_inw, - mv_inl: cat68701_inl, - mv_outb: cat68701_outb, - mv_outw: cat68701_outw, - mv_outl: cat68701_outl, - - mv_inb_p: cat68701_inb_p, - mv_inw_p: cat68701_inw, - mv_inl_p: cat68701_inl, - mv_outb_p: cat68701_outb_p, - mv_outw_p: cat68701_outw, - mv_outl_p: cat68701_outl, - - mv_insb: cat68701_insb, - mv_insw: cat68701_insw, - mv_insl: cat68701_insl, - mv_outsb: cat68701_outsb, - mv_outsw: cat68701_outsw, - mv_outsl: cat68701_outsl, - - mv_readb: cat68701_readb, - mv_readw: cat68701_readw, - mv_readl: cat68701_readl, - mv_writeb: cat68701_writeb, - mv_writew: cat68701_writew, - mv_writel: cat68701_writel, + .mv_nr_irqs = 32, + .mv_inb = cat68701_inb, + .mv_inw = cat68701_inw, + .mv_inl = cat68701_inl, + .mv_outb = cat68701_outb, + .mv_outw = cat68701_outw, + .mv_outl = cat68701_outl, + + .mv_inb_p = cat68701_inb_p, + .mv_inw_p = cat68701_inw, + .mv_inl_p = cat68701_inl, + .mv_outb_p = cat68701_outb_p, + .mv_outw_p = cat68701_outw, + .mv_outl_p = cat68701_outl, + + .mv_insb = cat68701_insb, + .mv_insw = cat68701_insw, + .mv_insl = cat68701_insl, + .mv_outsb = cat68701_outsb, + .mv_outsw = cat68701_outsw, + .mv_outsl = cat68701_outsl, + + .mv_readb = cat68701_readb, + .mv_readw = cat68701_readw, + .mv_readl = cat68701_readl, + .mv_writeb = cat68701_writeb, + .mv_writew = cat68701_writew, + .mv_writel = cat68701_writel, - mv_ioremap: cat68701_ioremap, - mv_iounmap: cat68701_iounmap, + .mv_ioremap = cat68701_ioremap, + .mv_iounmap = cat68701_iounmap, - mv_isa_port2addr: cat68701_isa_port2addr, - mv_irq_demux: cat68701_irq_demux, + .mv_isa_port2addr = cat68701_isa_port2addr, + .mv_irq_demux = cat68701_irq_demux, - mv_init_irq: init_cat68701_IRQ, + .mv_init_irq = init_cat68701_IRQ, #ifdef CONFIG_HEARTBEAT - mv_heartbeat: heartbeat_cat68701, + .mv_heartbeat = heartbeat_cat68701, #endif }; ALIAS_MV(cat68701) diff -Nru a/arch/sh/boards/cqreek/mach.c b/arch/sh/boards/cqreek/mach.c --- a/arch/sh/boards/cqreek/mach.c Tue Sep 2 19:58:18 2003 +++ b/arch/sh/boards/cqreek/mach.c Tue Sep 2 19:58:18 2003 @@ -21,46 +21,46 @@ struct sh_machine_vector mv_cqreek __initmv = { #if defined(CONFIG_CPU_SH4) - mv_nr_irqs: 48, + .mv_nr_irqs = 48, #elif defined(CONFIG_CPU_SUBTYPE_SH7708) - mv_nr_irqs: 32, + .mv_nr_irqs = 32, #elif defined(CONFIG_CPU_SUBTYPE_SH7709) - mv_nr_irqs: 61, + .mv_nr_irqs = 61, #endif - mv_inb: generic_inb, - mv_inw: generic_inw, - mv_inl: generic_inl, - mv_outb: generic_outb, - mv_outw: generic_outw, - mv_outl: generic_outl, - - mv_inb_p: generic_inb_p, - mv_inw_p: generic_inw_p, - mv_inl_p: generic_inl_p, - mv_outb_p: generic_outb_p, - mv_outw_p: generic_outw_p, - mv_outl_p: generic_outl_p, - - mv_insb: generic_insb, - mv_insw: generic_insw, - mv_insl: generic_insl, - mv_outsb: generic_outsb, - mv_outsw: generic_outsw, - mv_outsl: generic_outsl, - - mv_readb: generic_readb, - mv_readw: generic_readw, - mv_readl: generic_readl, - mv_writeb: generic_writeb, - mv_writew: generic_writew, - mv_writel: generic_writel, + .mv_inb = generic_inb, + .mv_inw = generic_inw, + .mv_inl = generic_inl, + .mv_outb = generic_outb, + .mv_outw = generic_outw, + .mv_outl = generic_outl, + + .mv_inb_p = generic_inb_p, + .mv_inw_p = generic_inw_p, + .mv_inl_p = generic_inl_p, + .mv_outb_p = generic_outb_p, + .mv_outw_p = generic_outw_p, + .mv_outl_p = generic_outl_p, + + .mv_insb = generic_insb, + .mv_insw = generic_insw, + .mv_insl = generic_insl, + .mv_outsb = generic_outsb, + .mv_outsw = generic_outsw, + .mv_outsl = generic_outsl, + + .mv_readb = generic_readb, + .mv_readw = generic_readw, + .mv_readl = generic_readl, + .mv_writeb = generic_writeb, + .mv_writew = generic_writew, + .mv_writel = generic_writel, - mv_init_irq: init_cqreek_IRQ, + .mv_init_irq = init_cqreek_IRQ, - mv_isa_port2addr: cqreek_port2addr, + .mv_isa_port2addr = cqreek_port2addr, - mv_ioremap: generic_ioremap, - mv_iounmap: generic_iounmap, + .mv_ioremap = generic_ioremap, + .mv_iounmap = generic_iounmap, }; ALIAS_MV(cqreek) diff -Nru a/arch/sh/boards/dmida/mach.c b/arch/sh/boards/dmida/mach.c --- a/arch/sh/boards/dmida/mach.c Tue Sep 2 19:58:13 2003 +++ b/arch/sh/boards/dmida/mach.c Tue Sep 2 19:58:13 2003 @@ -30,42 +30,42 @@ */ struct sh_machine_vector mv_dmida __initmv = { - mv_name: "DMIDA", + .mv_name = "DMIDA", - mv_nr_irqs: HD64465_IRQ_BASE+HD64465_IRQ_NUM, + .mv_nr_irqs = HD64465_IRQ_BASE+HD64465_IRQ_NUM, - mv_inb: hd64465_inb, - mv_inw: hd64465_inw, - mv_inl: hd64465_inl, - mv_outb: hd64465_outb, - mv_outw: hd64465_outw, - mv_outl: hd64465_outl, - - mv_inb_p: hd64465_inb_p, - mv_inw_p: hd64465_inw, - mv_inl_p: hd64465_inl, - mv_outb_p: hd64465_outb_p, - mv_outw_p: hd64465_outw, - mv_outl_p: hd64465_outl, - - mv_insb: hd64465_insb, - mv_insw: hd64465_insw, - mv_insl: hd64465_insl, - mv_outsb: hd64465_outsb, - mv_outsw: hd64465_outsw, - mv_outsl: hd64465_outsl, - - mv_readb: generic_readb, - mv_readw: generic_readw, - mv_readl: generic_readl, - mv_writeb: generic_writeb, - mv_writew: generic_writew, - mv_writel: generic_writel, + .mv_inb = hd64465_inb, + .mv_inw = hd64465_inw, + .mv_inl = hd64465_inl, + .mv_outb = hd64465_outb, + .mv_outw = hd64465_outw, + .mv_outl = hd64465_outl, + + .mv_inb_p = hd64465_inb_p, + .mv_inw_p = hd64465_inw, + .mv_inl_p = hd64465_inl, + .mv_outb_p = hd64465_outb_p, + .mv_outw_p = hd64465_outw, + .mv_outl_p = hd64465_outl, + + .mv_insb = hd64465_insb, + .mv_insw = hd64465_insw, + .mv_insl = hd64465_insl, + .mv_outsb = hd64465_outsb, + .mv_outsw = hd64465_outsw, + .mv_outsl = hd64465_outsl, + + .mv_readb = generic_readb, + .mv_readw = generic_readw, + .mv_readl = generic_readl, + .mv_writeb = generic_writeb, + .mv_writew = generic_writew, + .mv_writel = generic_writel, - mv_irq_demux: hd64465_irq_demux, + .mv_irq_demux = hd64465_irq_demux, - mv_rtc_gettimeofday: sh_rtc_gettimeofday, - mv_rtc_settimeofday: sh_rtc_settimeofday, + .mv_rtc_gettimeofday = sh_rtc_gettimeofday, + .mv_rtc_settimeofday = sh_rtc_settimeofday, }; ALIAS_MV(dmida) diff -Nru a/arch/sh/boards/dreamcast/irq.c b/arch/sh/boards/dreamcast/irq.c --- a/arch/sh/boards/dreamcast/irq.c Tue Sep 2 19:58:14 2003 +++ b/arch/sh/boards/dreamcast/irq.c Tue Sep 2 19:58:14 2003 @@ -110,13 +110,13 @@ } struct hw_interrupt_type systemasic_int = { - typename: "System ASIC", - startup: startup_systemasic_irq, - shutdown: shutdown_systemasic_irq, - enable: enable_systemasic_irq, - disable: disable_systemasic_irq, - ack: ack_systemasic_irq, - end: end_systemasic_irq, + .typename = "System ASIC", + .startup = startup_systemasic_irq, + .shutdown = shutdown_systemasic_irq, + .enable = enable_systemasic_irq, + .disable = disable_systemasic_irq, + .ack = ack_systemasic_irq, + .end = end_systemasic_irq, }; /* diff -Nru a/arch/sh/boards/dreamcast/mach.c b/arch/sh/boards/dreamcast/mach.c --- a/arch/sh/boards/dreamcast/mach.c Tue Sep 2 19:58:13 2003 +++ b/arch/sh/boards/dreamcast/mach.c Tue Sep 2 19:58:13 2003 @@ -21,40 +21,40 @@ */ struct sh_machine_vector mv_dreamcast __initmv = { - mv_nr_irqs: NR_IRQS, + .mv_nr_irqs = NR_IRQS, - mv_inb: generic_inb, - mv_inw: generic_inw, - mv_inl: generic_inl, - mv_outb: generic_outb, - mv_outw: generic_outw, - mv_outl: generic_outl, - - mv_inb_p: generic_inb_p, - mv_inw_p: generic_inw, - mv_inl_p: generic_inl, - mv_outb_p: generic_outb_p, - mv_outw_p: generic_outw, - mv_outl_p: generic_outl, - - mv_insb: generic_insb, - mv_insw: generic_insw, - mv_insl: generic_insl, - mv_outsb: generic_outsb, - mv_outsw: generic_outsw, - mv_outsl: generic_outsl, - - mv_readb: generic_readb, - mv_readw: generic_readw, - mv_readl: generic_readl, - mv_writeb: generic_writeb, - mv_writew: generic_writew, - mv_writel: generic_writel, + .mv_inb = generic_inb, + .mv_inw = generic_inw, + .mv_inl = generic_inl, + .mv_outb = generic_outb, + .mv_outw = generic_outw, + .mv_outl = generic_outl, + + .mv_inb_p = generic_inb_p, + .mv_inw_p = generic_inw, + .mv_inl_p = generic_inl, + .mv_outb_p = generic_outb_p, + .mv_outw_p = generic_outw, + .mv_outl_p = generic_outl, + + .mv_insb = generic_insb, + .mv_insw = generic_insw, + .mv_insl = generic_insl, + .mv_outsb = generic_outsb, + .mv_outsw = generic_outsw, + .mv_outsl = generic_outsl, + + .mv_readb = generic_readb, + .mv_readw = generic_readw, + .mv_readl = generic_readl, + .mv_writeb = generic_writeb, + .mv_writew = generic_writew, + .mv_writel = generic_writel, - mv_ioremap: generic_ioremap, - mv_iounmap: generic_iounmap, + .mv_ioremap = generic_ioremap, + .mv_iounmap = generic_iounmap, - mv_isa_port2addr: dreamcast_isa_port2addr, - mv_irq_demux: systemasic_irq_demux, + .mv_isa_port2addr = dreamcast_isa_port2addr, + .mv_irq_demux = systemasic_irq_demux, }; ALIAS_MV(dreamcast) diff -Nru a/arch/sh/boards/ec3104/irq.c b/arch/sh/boards/ec3104/irq.c --- a/arch/sh/boards/ec3104/irq.c Tue Sep 2 19:58:14 2003 +++ b/arch/sh/boards/ec3104/irq.c Tue Sep 2 19:58:14 2003 @@ -169,13 +169,13 @@ } static struct hw_interrupt_type ec3104_int = { - typename: "EC3104", - enable: enable_ec3104_irq, - disable: disable_ec3104_irq, - ack: mask_and_ack_ec3104_irq, - end: end_ec3104_irq, - startup: startup_ec3104_irq, - shutdown: shutdown_ec3104_irq, + .typename = "EC3104", + .enable = enable_ec3104_irq, + .disable = disable_ec3104_irq, + .ack = mask_and_ack_ec3104_irq, + .end = end_ec3104_irq, + .startup = startup_ec3104_irq, + .shutdown = shutdown_ec3104_irq, }; /* Yuck. the _demux API is ugly */ diff -Nru a/arch/sh/boards/ec3104/mach.c b/arch/sh/boards/ec3104/mach.c --- a/arch/sh/boards/ec3104/mach.c Tue Sep 2 19:58:18 2003 +++ b/arch/sh/boards/ec3104/mach.c Tue Sep 2 19:58:18 2003 @@ -28,42 +28,42 @@ */ struct sh_machine_vector mv_ec3104 __initmv = { - mv_name: "EC3104", + .mv_name = "EC3104", - mv_nr_irqs: 96, + .mv_nr_irqs = 96, - mv_inb: ec3104_inb, - mv_inw: ec3104_inw, - mv_inl: ec3104_inl, - mv_outb: ec3104_outb, - mv_outw: ec3104_outw, - mv_outl: ec3104_outl, - - mv_inb_p: generic_inb_p, - mv_inw_p: generic_inw, - mv_inl_p: generic_inl, - mv_outb_p: generic_outb_p, - mv_outw_p: generic_outw, - mv_outl_p: generic_outl, - - mv_insb: generic_insb, - mv_insw: generic_insw, - mv_insl: generic_insl, - mv_outsb: generic_outsb, - mv_outsw: generic_outsw, - mv_outsl: generic_outsl, - - mv_readb: generic_readb, - mv_readw: generic_readw, - mv_readl: generic_readl, - mv_writeb: generic_writeb, - mv_writew: generic_writew, - mv_writel: generic_writel, + .mv_inb = ec3104_inb, + .mv_inw = ec3104_inw, + .mv_inl = ec3104_inl, + .mv_outb = ec3104_outb, + .mv_outw = ec3104_outw, + .mv_outl = ec3104_outl, + + .mv_inb_p = generic_inb_p, + .mv_inw_p = generic_inw, + .mv_inl_p = generic_inl, + .mv_outb_p = generic_outb_p, + .mv_outw_p = generic_outw, + .mv_outl_p = generic_outl, + + .mv_insb = generic_insb, + .mv_insw = generic_insw, + .mv_insl = generic_insl, + .mv_outsb = generic_outsb, + .mv_outsw = generic_outsw, + .mv_outsl = generic_outsl, + + .mv_readb = generic_readb, + .mv_readw = generic_readw, + .mv_readl = generic_readl, + .mv_writeb = generic_writeb, + .mv_writew = generic_writew, + .mv_writel = generic_writel, - mv_irq_demux: ec3104_irq_demux, + .mv_irq_demux = ec3104_irq_demux, - mv_rtc_gettimeofday: sh_rtc_gettimeofday, - mv_rtc_settimeofday: sh_rtc_settimeofday, + .mv_rtc_gettimeofday = sh_rtc_gettimeofday, + .mv_rtc_settimeofday = sh_rtc_settimeofday, }; ALIAS_MV(ec3104) diff -Nru a/arch/sh/boards/harp/mach.c b/arch/sh/boards/harp/mach.c --- a/arch/sh/boards/harp/mach.c Tue Sep 2 19:58:16 2003 +++ b/arch/sh/boards/harp/mach.c Tue Sep 2 19:58:16 2003 @@ -26,46 +26,46 @@ */ struct sh_machine_vector mv_harp __initmv = { - mv_nr_irqs: 89 + HD64465_IRQ_NUM, + .mv_nr_irqs = 89 + HD64465_IRQ_NUM, - mv_inb: hd64465_inb, - mv_inw: hd64465_inw, - mv_inl: hd64465_inl, - mv_outb: hd64465_outb, - mv_outw: hd64465_outw, - mv_outl: hd64465_outl, - - mv_inb_p: hd64465_inb_p, - mv_inw_p: hd64465_inw, - mv_inl_p: hd64465_inl, - mv_outb_p: hd64465_outb_p, - mv_outw_p: hd64465_outw, - mv_outl_p: hd64465_outl, - - mv_insb: hd64465_insb, - mv_insw: hd64465_insw, - mv_insl: hd64465_insl, - mv_outsb: hd64465_outsb, - mv_outsw: hd64465_outsw, - mv_outsl: hd64465_outsl, - - mv_readb: generic_readb, - mv_readw: generic_readw, - mv_readl: generic_readl, - mv_writeb: generic_writeb, - mv_writew: generic_writew, - mv_writel: generic_writel, + .mv_inb = hd64465_inb, + .mv_inw = hd64465_inw, + .mv_inl = hd64465_inl, + .mv_outb = hd64465_outb, + .mv_outw = hd64465_outw, + .mv_outl = hd64465_outl, + + .mv_inb_p = hd64465_inb_p, + .mv_inw_p = hd64465_inw, + .mv_inl_p = hd64465_inl, + .mv_outb_p = hd64465_outb_p, + .mv_outw_p = hd64465_outw, + .mv_outl_p = hd64465_outl, + + .mv_insb = hd64465_insb, + .mv_insw = hd64465_insw, + .mv_insl = hd64465_insl, + .mv_outsb = hd64465_outsb, + .mv_outsw = hd64465_outsw, + .mv_outsl = hd64465_outsl, + + .mv_readb = generic_readb, + .mv_readw = generic_readw, + .mv_readl = generic_readl, + .mv_writeb = generic_writeb, + .mv_writew = generic_writew, + .mv_writel = generic_writel, - mv_ioremap: generic_ioremap, - mv_iounmap: generic_iounmap, + .mv_ioremap = generic_ioremap, + .mv_iounmap = generic_iounmap, - mv_isa_port2addr: hd64465_isa_port2addr, + .mv_isa_port2addr = hd64465_isa_port2addr, #ifdef CONFIG_PCI - mv_init_irq: init_harp_irq, + .mv_init_irq = init_harp_irq, #endif #ifdef CONFIG_HEARTBEAT - mv_heartbeat: heartbeat_harp, + .mv_heartbeat = heartbeat_harp, #endif }; diff -Nru a/arch/sh/boards/hp6xx/hp620/mach.c b/arch/sh/boards/hp6xx/hp620/mach.c --- a/arch/sh/boards/hp6xx/hp620/mach.c Tue Sep 2 19:58:16 2003 +++ b/arch/sh/boards/hp6xx/hp620/mach.c Tue Sep 2 19:58:16 2003 @@ -24,41 +24,41 @@ */ struct sh_machine_vector mv_hp620 __initmv = { - mv_name: "hp620", + .mv_name = "hp620", - mv_nr_irqs: HD64461_IRQBASE+HD64461_IRQ_NUM, + .mv_nr_irqs = HD64461_IRQBASE+HD64461_IRQ_NUM, - mv_inb: hd64461_inb, - mv_inw: hd64461_inw, - mv_inl: hd64461_inl, - mv_outb: hd64461_outb, - mv_outw: hd64461_outw, - mv_outl: hd64461_outl, - - mv_inb_p: hd64461_inb_p, - mv_inw_p: hd64461_inw, - mv_inl_p: hd64461_inl, - mv_outb_p: hd64461_outb_p, - mv_outw_p: hd64461_outw, - mv_outl_p: hd64461_outl, - - mv_insb: hd64461_insb, - mv_insw: hd64461_insw, - mv_insl: hd64461_insl, - mv_outsb: hd64461_outsb, - mv_outsw: hd64461_outsw, - mv_outsl: hd64461_outsl, - - mv_readb: generic_readb, - mv_readw: generic_readw, - mv_readl: generic_readl, - mv_writeb: generic_writeb, - mv_writew: generic_writew, - mv_writel: generic_writel, + .mv_inb = hd64461_inb, + .mv_inw = hd64461_inw, + .mv_inl = hd64461_inl, + .mv_outb = hd64461_outb, + .mv_outw = hd64461_outw, + .mv_outl = hd64461_outl, + + .mv_inb_p = hd64461_inb_p, + .mv_inw_p = hd64461_inw, + .mv_inl_p = hd64461_inl, + .mv_outb_p = hd64461_outb_p, + .mv_outw_p = hd64461_outw, + .mv_outl_p = hd64461_outl, + + .mv_insb = hd64461_insb, + .mv_insw = hd64461_insw, + .mv_insl = hd64461_insl, + .mv_outsb = hd64461_outsb, + .mv_outsw = hd64461_outsw, + .mv_outsl = hd64461_outsl, + + .mv_readb = generic_readb, + .mv_readw = generic_readw, + .mv_readl = generic_readl, + .mv_writeb = generic_writeb, + .mv_writew = generic_writew, + .mv_writel = generic_writel, - mv_irq_demux: hd64461_irq_demux, + .mv_irq_demux = hd64461_irq_demux, - mv_rtc_gettimeofday: sh_rtc_gettimeofday, - mv_rtc_settimeofday: sh_rtc_settimeofday, + .mv_rtc_gettimeofday = sh_rtc_gettimeofday, + .mv_rtc_settimeofday = sh_rtc_settimeofday, }; ALIAS_MV(hp620) diff -Nru a/arch/sh/boards/hp6xx/hp680/mach.c b/arch/sh/boards/hp6xx/hp680/mach.c --- a/arch/sh/boards/hp6xx/hp680/mach.c Tue Sep 2 19:58:19 2003 +++ b/arch/sh/boards/hp6xx/hp680/mach.c Tue Sep 2 19:58:19 2003 @@ -20,41 +20,41 @@ #include struct sh_machine_vector mv_hp680 __initmv = { - mv_name: "hp680", + .mv_name = "hp680", - mv_nr_irqs: HD64461_IRQBASE+HD64461_IRQ_NUM, + .mv_nr_irqs = HD64461_IRQBASE+HD64461_IRQ_NUM, - mv_inb: hd64461_inb, - mv_inw: hd64461_inw, - mv_inl: hd64461_inl, - mv_outb: hd64461_outb, - mv_outw: hd64461_outw, - mv_outl: hd64461_outl, - - mv_inb_p: hd64461_inb_p, - mv_inw_p: hd64461_inw, - mv_inl_p: hd64461_inl, - mv_outb_p: hd64461_outb_p, - mv_outw_p: hd64461_outw, - mv_outl_p: hd64461_outl, - - mv_insb: hd64461_insb, - mv_insw: hd64461_insw, - mv_insl: hd64461_insl, - mv_outsb: hd64461_outsb, - mv_outsw: hd64461_outsw, - mv_outsl: hd64461_outsl, - - mv_readb: generic_readb, - mv_readw: generic_readw, - mv_readl: generic_readl, - mv_writeb: generic_writeb, - mv_writew: generic_writew, - mv_writel: generic_writel, + .mv_inb = hd64461_inb, + .mv_inw = hd64461_inw, + .mv_inl = hd64461_inl, + .mv_outb = hd64461_outb, + .mv_outw = hd64461_outw, + .mv_outl = hd64461_outl, + + .mv_inb_p = hd64461_inb_p, + .mv_inw_p = hd64461_inw, + .mv_inl_p = hd64461_inl, + .mv_outb_p = hd64461_outb_p, + .mv_outw_p = hd64461_outw, + .mv_outl_p = hd64461_outl, + + .mv_insb = hd64461_insb, + .mv_insw = hd64461_insw, + .mv_insl = hd64461_insl, + .mv_outsb = hd64461_outsb, + .mv_outsw = hd64461_outsw, + .mv_outsl = hd64461_outsl, + + .mv_readb = generic_readb, + .mv_readw = generic_readw, + .mv_readl = generic_readl, + .mv_writeb = generic_writeb, + .mv_writew = generic_writew, + .mv_writel = generic_writel, - mv_irq_demux: hd64461_irq_demux, + .mv_irq_demux = hd64461_irq_demux, - mv_rtc_gettimeofday: sh_rtc_gettimeofday, - mv_rtc_settimeofday: sh_rtc_settimeofday, + .mv_rtc_gettimeofday = sh_rtc_gettimeofday, + .mv_rtc_settimeofday = sh_rtc_settimeofday, }; ALIAS_MV(hp680) diff -Nru a/arch/sh/boards/hp6xx/hp690/mach.c b/arch/sh/boards/hp6xx/hp690/mach.c --- a/arch/sh/boards/hp6xx/hp690/mach.c Tue Sep 2 19:58:20 2003 +++ b/arch/sh/boards/hp6xx/hp690/mach.c Tue Sep 2 19:58:20 2003 @@ -20,41 +20,41 @@ #include struct sh_machine_vector mv_hp690 __initmv = { - mv_name: "hp690", + .mv_name = "hp690", - mv_nr_irqs: HD64461_IRQBASE+HD64461_IRQ_NUM, + .mv_nr_irqs = HD64461_IRQBASE+HD64461_IRQ_NUM, - mv_inb: hd64461_inb, - mv_inw: hd64461_inw, - mv_inl: hd64461_inl, - mv_outb: hd64461_outb, - mv_outw: hd64461_outw, - mv_outl: hd64461_outl, - - mv_inb_p: hd64461_inb_p, - mv_inw_p: hd64461_inw, - mv_inl_p: hd64461_inl, - mv_outb_p: hd64461_outb_p, - mv_outw_p: hd64461_outw, - mv_outl_p: hd64461_outl, - - mv_insb: hd64461_insb, - mv_insw: hd64461_insw, - mv_insl: hd64461_insl, - mv_outsb: hd64461_outsb, - mv_outsw: hd64461_outsw, - mv_outsl: hd64461_outsl, - - mv_readb: generic_readb, - mv_readw: generic_readw, - mv_readl: generic_readl, - mv_writeb: generic_writeb, - mv_writew: generic_writew, - mv_writel: generic_writel, + .mv_inb = hd64461_inb, + .mv_inw = hd64461_inw, + .mv_inl = hd64461_inl, + .mv_outb = hd64461_outb, + .mv_outw = hd64461_outw, + .mv_outl = hd64461_outl, + + .mv_inb_p = hd64461_inb_p, + .mv_inw_p = hd64461_inw, + .mv_inl_p = hd64461_inl, + .mv_outb_p = hd64461_outb_p, + .mv_outw_p = hd64461_outw, + .mv_outl_p = hd64461_outl, + + .mv_insb = hd64461_insb, + .mv_insw = hd64461_insw, + .mv_insl = hd64461_insl, + .mv_outsb = hd64461_outsb, + .mv_outsw = hd64461_outsw, + .mv_outsl = hd64461_outsl, + + .mv_readb = generic_readb, + .mv_readw = generic_readw, + .mv_readl = generic_readl, + .mv_writeb = generic_writeb, + .mv_writew = generic_writew, + .mv_writel = generic_writel, - mv_irq_demux: hd64461_irq_demux, + .mv_irq_demux = hd64461_irq_demux, - mv_rtc_gettimeofday: sh_rtc_gettimeofday, - mv_rtc_settimeofday: sh_rtc_settimeofday, + .mv_rtc_gettimeofday = sh_rtc_gettimeofday, + .mv_rtc_settimeofday = sh_rtc_settimeofday, }; ALIAS_MV(hp690) diff -Nru a/arch/sh/boards/overdrive/mach.c b/arch/sh/boards/overdrive/mach.c --- a/arch/sh/boards/overdrive/mach.c Tue Sep 2 19:58:14 2003 +++ b/arch/sh/boards/overdrive/mach.c Tue Sep 2 19:58:14 2003 @@ -28,46 +28,46 @@ */ struct sh_machine_vector mv_od __initmv = { - mv_nr_irqs: 48, + .mv_nr_irqs = 48, - mv_inb: od_inb, - mv_inw: od_inw, - mv_inl: od_inl, - mv_outb: od_outb, - mv_outw: od_outw, - mv_outl: od_outl, - - mv_inb_p: od_inb_p, - mv_inw_p: od_inw_p, - mv_inl_p: od_inl_p, - mv_outb_p: od_outb_p, - mv_outw_p: od_outw_p, - mv_outl_p: od_outl_p, - - mv_insb: od_insb, - mv_insw: od_insw, - mv_insl: od_insl, - mv_outsb: od_outsb, - mv_outsw: od_outsw, - mv_outsl: od_outsl, - - mv_readb: generic_readb, - mv_readw: generic_readw, - mv_readl: generic_readl, - mv_writeb: generic_writeb, - mv_writew: generic_writew, - mv_writel: generic_writel, + .mv_inb = od_inb, + .mv_inw = od_inw, + .mv_inl = od_inl, + .mv_outb = od_outb, + .mv_outw = od_outw, + .mv_outl = od_outl, + + .mv_inb_p = od_inb_p, + .mv_inw_p = od_inw_p, + .mv_inl_p = od_inl_p, + .mv_outb_p = od_outb_p, + .mv_outw_p = od_outw_p, + .mv_outl_p = od_outl_p, + + .mv_insb = od_insb, + .mv_insw = od_insw, + .mv_insl = od_insl, + .mv_outsb = od_outsb, + .mv_outsw = od_outsw, + .mv_outsl = od_outsl, + + .mv_readb = generic_readb, + .mv_readw = generic_readw, + .mv_readl = generic_readl, + .mv_writeb = generic_writeb, + .mv_writew = generic_writew, + .mv_writel = generic_writel, - mv_ioremap: generic_ioremap, - mv_iounmap: generic_iounmap, + .mv_ioremap = generic_ioremap, + .mv_iounmap = generic_iounmap, - mv_isa_port2addr: generic_isa_port2addr, + .mv_isa_port2addr = generic_isa_port2addr, #ifdef CONFIG_PCI - mv_init_irq: init_overdrive_irq, + .mv_init_irq = init_overdrive_irq, #endif #ifdef CONFIG_HEARTBEAT - mv_heartbeat: heartbeat_od, + .mv_heartbeat = heartbeat_od, #endif }; diff -Nru a/arch/sh/boards/saturn/irq.c b/arch/sh/boards/saturn/irq.c --- a/arch/sh/boards/saturn/irq.c Tue Sep 2 19:58:17 2003 +++ b/arch/sh/boards/saturn/irq.c Tue Sep 2 19:58:17 2003 @@ -102,13 +102,13 @@ } static struct hw_interrupt_type saturn_int = { - typename: "Saturn", - enable: enable_saturn_irq, - disable: disable_saturn_irq, - ack: mask_and_ack_saturn_irq, - end: end_saturn_irq, - startup: startup_saturn_irq, - shutdown: shutdown_saturn_irq, + .typename = "Saturn", + .enable = enable_saturn_irq, + .disable = disable_saturn_irq, + .ack = mask_and_ack_saturn_irq, + .end = end_saturn_irq, + .startup = startup_saturn_irq, + .shutdown = shutdown_saturn_irq, }; int saturn_irq_demux(int irq_nr) diff -Nru a/arch/sh/boards/saturn/mach.c b/arch/sh/boards/saturn/mach.c --- a/arch/sh/boards/saturn/mach.c Tue Sep 2 19:58:19 2003 +++ b/arch/sh/boards/saturn/mach.c Tue Sep 2 19:58:19 2003 @@ -18,41 +18,41 @@ * The Machine Vector */ struct sh_machine_vector mv_saturn __initmv = { - mv_nr_irqs: 80, /* Fix this later */ + .mv_nr_irqs = 80, /* Fix this later */ - mv_inb: generic_inb, - mv_inw: generic_inw, - mv_inl: generic_inl, - mv_outb: generic_outb, - mv_outw: generic_outw, - mv_outl: generic_outl, - - mv_inb_p: generic_inb_p, - mv_inw_p: generic_inw_p, - mv_inl_p: generic_inl_p, - mv_outb_p: generic_outb_p, - mv_outw_p: generic_outw_p, - mv_outl_p: generic_outl_p, - - mv_insb: generic_insb, - mv_insw: generic_insw, - mv_insl: generic_insl, - mv_outsb: generic_outsb, - mv_outsw: generic_outsw, - mv_outsl: generic_outsl, - - mv_readb: generic_readb, - mv_readw: generic_readw, - mv_readl: generic_readl, - mv_writeb: generic_writeb, - mv_writew: generic_writew, - mv_writel: generic_writel, + .mv_inb = generic_inb, + .mv_inw = generic_inw, + .mv_inl = generic_inl, + .mv_outb = generic_outb, + .mv_outw = generic_outw, + .mv_outl = generic_outl, + + .mv_inb_p = generic_inb_p, + .mv_inw_p = generic_inw_p, + .mv_inl_p = generic_inl_p, + .mv_outb_p = generic_outb_p, + .mv_outw_p = generic_outw_p, + .mv_outl_p = generic_outl_p, + + .mv_insb = generic_insb, + .mv_insw = generic_insw, + .mv_insl = generic_insl, + .mv_outsb = generic_outsb, + .mv_outsw = generic_outsw, + .mv_outsl = generic_outsl, + + .mv_readb = generic_readb, + .mv_readw = generic_readw, + .mv_readl = generic_readl, + .mv_writeb = generic_writeb, + .mv_writew = generic_writew, + .mv_writel = generic_writel, - mv_isa_port2addr: saturn_isa_port2addr, - mv_irq_demux: saturn_irq_demux, + .mv_isa_port2addr = saturn_isa_port2addr, + .mv_irq_demux = saturn_irq_demux, - mv_ioremap: saturn_ioremap, - mv_iounmap: saturn_iounmap, + .mv_ioremap = saturn_ioremap, + .mv_iounmap = saturn_iounmap, }; ALIAS_MV(saturn) diff -Nru a/arch/sh/boards/se/770x/mach.c b/arch/sh/boards/se/770x/mach.c --- a/arch/sh/boards/se/770x/mach.c Tue Sep 2 19:58:18 2003 +++ b/arch/sh/boards/se/770x/mach.c Tue Sep 2 19:58:18 2003 @@ -28,49 +28,49 @@ struct sh_machine_vector mv_se __initmv = { #if defined(CONFIG_CPU_SH4) - mv_nr_irqs: 48, + .mv_nr_irqs = 48, #elif defined(CONFIG_CPU_SUBTYPE_SH7708) - mv_nr_irqs: 32, + .mv_nr_irqs = 32, #elif defined(CONFIG_CPU_SUBTYPE_SH7709) - mv_nr_irqs: 61, + .mv_nr_irqs = 61, #endif - mv_inb: se_inb, - mv_inw: se_inw, - mv_inl: se_inl, - mv_outb: se_outb, - mv_outw: se_outw, - mv_outl: se_outl, - - mv_inb_p: se_inb_p, - mv_inw_p: se_inw, - mv_inl_p: se_inl, - mv_outb_p: se_outb_p, - mv_outw_p: se_outw, - mv_outl_p: se_outl, - - mv_insb: se_insb, - mv_insw: se_insw, - mv_insl: se_insl, - mv_outsb: se_outsb, - mv_outsw: se_outsw, - mv_outsl: se_outsl, - - mv_readb: se_readb, - mv_readw: se_readw, - mv_readl: se_readl, - mv_writeb: se_writeb, - mv_writew: se_writew, - mv_writel: se_writel, + .mv_inb = se_inb, + .mv_inw = se_inw, + .mv_inl = se_inl, + .mv_outb = se_outb, + .mv_outw = se_outw, + .mv_outl = se_outl, + + .mv_inb_p = se_inb_p, + .mv_inw_p = se_inw, + .mv_inl_p = se_inl, + .mv_outb_p = se_outb_p, + .mv_outw_p = se_outw, + .mv_outl_p = se_outl, + + .mv_insb = se_insb, + .mv_insw = se_insw, + .mv_insl = se_insl, + .mv_outsb = se_outsb, + .mv_outsw = se_outsw, + .mv_outsl = se_outsl, + + .mv_readb = se_readb, + .mv_readw = se_readw, + .mv_readl = se_readl, + .mv_writeb = se_writeb, + .mv_writew = se_writew, + .mv_writel = se_writel, - mv_ioremap: generic_ioremap, - mv_iounmap: generic_iounmap, + .mv_ioremap = generic_ioremap, + .mv_iounmap = generic_iounmap, - mv_isa_port2addr: se_isa_port2addr, + .mv_isa_port2addr = se_isa_port2addr, - mv_init_irq: init_se_IRQ, + .mv_init_irq = init_se_IRQ, #ifdef CONFIG_HEARTBEAT - mv_heartbeat: heartbeat_se, + .mv_heartbeat = heartbeat_se, #endif }; ALIAS_MV(se) diff -Nru a/arch/sh/boards/se/7751/mach.c b/arch/sh/boards/se/7751/mach.c --- a/arch/sh/boards/se/7751/mach.c Tue Sep 2 19:58:16 2003 +++ b/arch/sh/boards/se/7751/mach.c Tue Sep 2 19:58:16 2003 @@ -26,44 +26,44 @@ */ struct sh_machine_vector mv_7751se __initmv = { - mv_nr_irqs: 72, + .mv_nr_irqs = 72, - mv_inb: sh7751se_inb, - mv_inw: sh7751se_inw, - mv_inl: sh7751se_inl, - mv_outb: sh7751se_outb, - mv_outw: sh7751se_outw, - mv_outl: sh7751se_outl, - - mv_inb_p: sh7751se_inb_p, - mv_inw_p: sh7751se_inw, - mv_inl_p: sh7751se_inl, - mv_outb_p: sh7751se_outb_p, - mv_outw_p: sh7751se_outw, - mv_outl_p: sh7751se_outl, - - mv_insb: sh7751se_insb, - mv_insw: sh7751se_insw, - mv_insl: sh7751se_insl, - mv_outsb: sh7751se_outsb, - mv_outsw: sh7751se_outsw, - mv_outsl: sh7751se_outsl, - - mv_readb: sh7751se_readb, - mv_readw: sh7751se_readw, - mv_readl: sh7751se_readl, - mv_writeb: sh7751se_writeb, - mv_writew: sh7751se_writew, - mv_writel: sh7751se_writel, + .mv_inb = sh7751se_inb, + .mv_inw = sh7751se_inw, + .mv_inl = sh7751se_inl, + .mv_outb = sh7751se_outb, + .mv_outw = sh7751se_outw, + .mv_outl = sh7751se_outl, + + .mv_inb_p = sh7751se_inb_p, + .mv_inw_p = sh7751se_inw, + .mv_inl_p = sh7751se_inl, + .mv_outb_p = sh7751se_outb_p, + .mv_outw_p = sh7751se_outw, + .mv_outl_p = sh7751se_outl, + + .mv_insb = sh7751se_insb, + .mv_insw = sh7751se_insw, + .mv_insl = sh7751se_insl, + .mv_outsb = sh7751se_outsb, + .mv_outsw = sh7751se_outsw, + .mv_outsl = sh7751se_outsl, + + .mv_readb = sh7751se_readb, + .mv_readw = sh7751se_readw, + .mv_readl = sh7751se_readl, + .mv_writeb = sh7751se_writeb, + .mv_writew = sh7751se_writew, + .mv_writel = sh7751se_writel, - mv_ioremap: generic_ioremap, - mv_iounmap: generic_iounmap, + .mv_ioremap = generic_ioremap, + .mv_iounmap = generic_iounmap, - mv_isa_port2addr: sh7751se_isa_port2addr, + .mv_isa_port2addr = sh7751se_isa_port2addr, - mv_init_irq: init_7751se_IRQ, + .mv_init_irq = init_7751se_IRQ, #ifdef CONFIG_HEARTBEAT - mv_heartbeat: heartbeat_7751se, + .mv_heartbeat = heartbeat_7751se, #endif }; ALIAS_MV(7751se) diff -Nru a/arch/sh/boards/sh2000/mach.c b/arch/sh/boards/sh2000/mach.c --- a/arch/sh/boards/sh2000/mach.c Tue Sep 2 19:58:18 2003 +++ b/arch/sh/boards/sh2000/mach.c Tue Sep 2 19:58:18 2003 @@ -19,39 +19,39 @@ */ struct sh_machine_vector mv_sh2000 __initmv = { - mv_nr_irqs: 80, + .mv_nr_irqs = 80, - mv_inb: generic_inb, - mv_inw: generic_inw, - mv_inl: generic_inl, - mv_outb: generic_outb, - mv_outw: generic_outw, - mv_outl: generic_outl, - - mv_inb_p: generic_inb_p, - mv_inw_p: generic_inw_p, - mv_inl_p: generic_inl_p, - mv_outb_p: generic_outb_p, - mv_outw_p: generic_outw_p, - mv_outl_p: generic_outl_p, - - mv_insb: generic_insb, - mv_insw: generic_insw, - mv_insl: generic_insl, - mv_outsb: generic_outsb, - mv_outsw: generic_outsw, - mv_outsl: generic_outsl, - - mv_readb: generic_readb, - mv_readw: generic_readw, - mv_readl: generic_readl, - mv_writeb: generic_writeb, - mv_writew: generic_writew, - mv_writel: generic_writel, + .mv_inb = generic_inb, + .mv_inw = generic_inw, + .mv_inl = generic_inl, + .mv_outb = generic_outb, + .mv_outw = generic_outw, + .mv_outl = generic_outl, + + .mv_inb_p = generic_inb_p, + .mv_inw_p = generic_inw_p, + .mv_inl_p = generic_inl_p, + .mv_outb_p = generic_outb_p, + .mv_outw_p = generic_outw_p, + .mv_outl_p = generic_outl_p, + + .mv_insb = generic_insb, + .mv_insw = generic_insw, + .mv_insl = generic_insl, + .mv_outsb = generic_outsb, + .mv_outsw = generic_outsw, + .mv_outsl = generic_outsl, + + .mv_readb = generic_readb, + .mv_readw = generic_readw, + .mv_readl = generic_readl, + .mv_writeb = generic_writeb, + .mv_writew = generic_writew, + .mv_writel = generic_writel, - mv_isa_port2addr: sh2000_isa_port2addr, + .mv_isa_port2addr = sh2000_isa_port2addr, - mv_ioremap: generic_ioremap, - mv_iounmap: generic_iounmap, + .mv_ioremap = generic_ioremap, + .mv_iounmap = generic_iounmap, }; ALIAS_MV(sh2000) diff -Nru a/arch/sh/boards/unknown/mach.c b/arch/sh/boards/unknown/mach.c --- a/arch/sh/boards/unknown/mach.c Tue Sep 2 19:58:13 2003 +++ b/arch/sh/boards/unknown/mach.c Tue Sep 2 19:58:13 2003 @@ -24,44 +24,44 @@ struct sh_machine_vector mv_unknown __initmv = { #if defined(CONFIG_CPU_SH4) - mv_nr_irqs: 48, + .mv_nr_irqs = 48, #elif defined(CONFIG_CPU_SUBTYPE_SH7708) - mv_nr_irqs: 32, + .mv_nr_irqs = 32, #elif defined(CONFIG_CPU_SUBTYPE_SH7709) - mv_nr_irqs: 61, + .mv_nr_irqs = 61, #endif - mv_inb: unknown_inb, - mv_inw: unknown_inw, - mv_inl: unknown_inl, - mv_outb: unknown_outb, - mv_outw: unknown_outw, - mv_outl: unknown_outl, - - mv_inb_p: unknown_inb_p, - mv_inw_p: unknown_inw_p, - mv_inl_p: unknown_inl_p, - mv_outb_p: unknown_outb_p, - mv_outw_p: unknown_outw_p, - mv_outl_p: unknown_outl_p, - - mv_insb: unknown_insb, - mv_insw: unknown_insw, - mv_insl: unknown_insl, - mv_outsb: unknown_outsb, - mv_outsw: unknown_outsw, - mv_outsl: unknown_outsl, - - mv_readb: unknown_readb, - mv_readw: unknown_readw, - mv_readl: unknown_readl, - mv_writeb: unknown_writeb, - mv_writew: unknown_writew, - mv_writel: unknown_writel, + .mv_inb = unknown_inb, + .mv_inw = unknown_inw, + .mv_inl = unknown_inl, + .mv_outb = unknown_outb, + .mv_outw = unknown_outw, + .mv_outl = unknown_outl, + + .mv_inb_p = unknown_inb_p, + .mv_inw_p = unknown_inw_p, + .mv_inl_p = unknown_inl_p, + .mv_outb_p = unknown_outb_p, + .mv_outw_p = unknown_outw_p, + .mv_outl_p = unknown_outl_p, + + .mv_insb = unknown_insb, + .mv_insw = unknown_insw, + .mv_insl = unknown_insl, + .mv_outsb = unknown_outsb, + .mv_outsw = unknown_outsw, + .mv_outsl = unknown_outsl, + + .mv_readb = unknown_readb, + .mv_readw = unknown_readw, + .mv_readl = unknown_readl, + .mv_writeb = unknown_writeb, + .mv_writew = unknown_writew, + .mv_writel = unknown_writel, - mv_ioremap: unknown_ioremap, - mv_iounmap: unknown_iounmap, + .mv_ioremap = unknown_ioremap, + .mv_iounmap = unknown_iounmap, - mv_isa_port2addr: unknown_isa_port2addr, + .mv_isa_port2addr = unknown_isa_port2addr, }; ALIAS_MV(unknown) diff -Nru a/arch/sh/cchips/hd6446x/hd64465/setup.c b/arch/sh/cchips/hd6446x/hd64465/setup.c --- a/arch/sh/cchips/hd6446x/hd64465/setup.c Tue Sep 2 19:58:20 2003 +++ b/arch/sh/cchips/hd6446x/hd64465/setup.c Tue Sep 2 19:58:20 2003 @@ -89,13 +89,13 @@ static struct hw_interrupt_type hd64465_irq_type = { - typename: "HD64465-IRQ", - startup: startup_hd64465_irq, - shutdown: shutdown_hd64465_irq, - enable: enable_hd64465_irq, - disable: disable_hd64465_irq, - ack: mask_and_ack_hd64465, - end: end_hd64465_irq + .typename = "HD64465-IRQ", + .startup = startup_hd64465_irq, + .shutdown = shutdown_hd64465_irq, + .enable = enable_hd64465_irq, + .disable = disable_hd64465_irq, + .ack = mask_and_ack_hd64465, + .end = end_hd64465_irq }; diff -Nru a/arch/sparc/Kconfig b/arch/sparc/Kconfig --- a/arch/sparc/Kconfig Tue Sep 2 19:58:12 2003 +++ b/arch/sparc/Kconfig Tue Sep 2 19:58:12 2003 @@ -254,29 +254,6 @@ . The module will be called openpromfs. If unsure, say M. -config KCORE_ELF - bool - depends on PROC_FS - default y - ---help--- - If you enabled support for /proc file system then the file - /proc/kcore will contain the kernel core image. This can be used - in gdb: - - $ cd /usr/src/linux ; gdb vmlinux /proc/kcore - - You have two choices here: ELF and A.OUT. Selecting ELF will make - /proc/kcore appear in ELF core format as defined by the Executable - and Linking Format specification. Selecting A.OUT will choose the - old "a.out" format which may be necessary for some old versions - of binutils or on some architectures. - - This is especially useful if you have compiled the kernel with the - "-g" option to preserve debugging information. It is mainly used - for examining kernel data structures on the live kernel so if you - don't understand what this means or are not a kernel hacker, just - leave it at its default value ELF. - source "fs/Kconfig.binfmt" config SUNOS_EMUL diff -Nru a/arch/sparc/boot/Makefile b/arch/sparc/boot/Makefile --- a/arch/sparc/boot/Makefile Tue Sep 2 19:58:19 2003 +++ b/arch/sparc/boot/Makefile Tue Sep 2 19:58:19 2003 @@ -19,7 +19,7 @@ BTOBJS := $(HEAD_Y) $(INIT_Y) BTLIBS := $(CORE_Y) $(LIBS_Y) $(DRIVERS_Y) $(NET_Y) -LDFLAGS_image := -T arch/sparc/vmlinux.lds.s $(BTOBJS) --start-group $(BTLIBS) --end-group +LDFLAGS_image := -T arch/sparc/kernel/vmlinux.lds.s $(BTOBJS) --start-group $(BTLIBS) --end-group # Actual linking $(obj)/image: $(obj)/btfix.o FORCE diff -Nru a/arch/sparc/kernel/entry.S b/arch/sparc/kernel/entry.S --- a/arch/sparc/kernel/entry.S Tue Sep 2 19:58:15 2003 +++ b/arch/sparc/kernel/entry.S Tue Sep 2 19:58:15 2003 @@ -38,7 +38,7 @@ #define curptr g6 -#define NR_SYSCALLS 266 /* Each OS is different... */ +#define NR_SYSCALLS 267 /* Each OS is different... */ /* These are just handy. */ #define _SV save %sp, -STACKFRAME_SZ, %sp diff -Nru a/arch/sparc/kernel/ioport.c b/arch/sparc/kernel/ioport.c --- a/arch/sparc/kernel/ioport.c Tue Sep 2 19:58:19 2003 +++ b/arch/sparc/kernel/ioport.c Tue Sep 2 19:58:19 2003 @@ -511,6 +511,26 @@ } } +/* + * Same as pci_map_single, but with pages. + */ +dma_addr_t pci_map_page(struct pci_dev *hwdev, struct page *page, + unsigned long offset, size_t size, int direction) +{ + if (direction == PCI_DMA_NONE) + BUG(); + /* IIep is write-through, not flushing. */ + return page_to_phys(page) + offset; +} + +void pci_unmap_page(struct pci_dev *hwdev, + dma_addr_t dma_address, size_t size, int direction) +{ + if (direction == PCI_DMA_NONE) + BUG(); + /* mmu_inval_dma_area XXX */ +} + /* Map a set of buffers described by scatterlist in streaming * mode for DMA. This is the scather-gather version of the * above pci_map_single interface. Here the scatter gather list diff -Nru a/arch/sparc/kernel/sys_sunos.c b/arch/sparc/kernel/sys_sunos.c --- a/arch/sparc/kernel/sys_sunos.c Tue Sep 2 19:58:15 2003 +++ b/arch/sparc/kernel/sys_sunos.c Tue Sep 2 19:58:15 2003 @@ -92,8 +92,8 @@ * SunOS is so stupid some times... hmph! */ if (file) { - if(major(file->f_dentry->d_inode->i_rdev) == MEM_MAJOR && - minor(file->f_dentry->d_inode->i_rdev) == 5) { + if(imajor(file->f_dentry->d_inode) == MEM_MAJOR && + iminor(file->f_dentry->d_inode) == 5) { flags |= MAP_ANONYMOUS; fput(file); file = 0; diff -Nru a/arch/sparc/kernel/systbls.S b/arch/sparc/kernel/systbls.S --- a/arch/sparc/kernel/systbls.S Tue Sep 2 19:58:16 2003 +++ b/arch/sparc/kernel/systbls.S Tue Sep 2 19:58:16 2003 @@ -72,7 +72,7 @@ /*250*/ .long sparc_mremap, sys_sysctl, sys_getsid, sys_fdatasync, sys_nfsservctl /*255*/ .long sys_nis_syscall, sys_clock_settime, sys_clock_gettime, sys_clock_getres, sys_clock_nanosleep /*260*/ .long sys_sched_getaffinity, sys_sched_setaffinity, sys_timer_settime, sys_timer_gettime, sys_timer_getoverrun -/*261*/ .long sys_timer_delete, sys_nis_syscall +/*265*/ .long sys_timer_delete, sys_timer_create, sys_nis_syscall #ifdef CONFIG_SUNOS_EMUL /* Now the SunOS syscall table. */ @@ -171,6 +171,6 @@ .long sunos_nosys /*260*/ .long sunos_nosys, sunos_nosys, sunos_nosys .long sunos_nosys, sunos_nosys, sunos_nosys - .long sunos_nosys + .long sunos_nosys, sunos_nosys #endif diff -Nru a/arch/sparc64/Kconfig b/arch/sparc64/Kconfig --- a/arch/sparc64/Kconfig Tue Sep 2 19:58:18 2003 +++ b/arch/sparc64/Kconfig Tue Sep 2 19:58:18 2003 @@ -363,29 +363,6 @@ . The module will be called openpromfs. If unsure, say M. -config KCORE_ELF - bool - depends on PROC_FS - default y - ---help--- - If you enabled support for /proc file system then the file - /proc/kcore will contain the kernel core image. This can be used - in gdb: - - $ cd /usr/src/linux ; gdb vmlinux /proc/kcore - - You have two choices here: ELF and A.OUT. Selecting ELF will make - /proc/kcore appear in ELF core format as defined by the Executable - and Linking Format specification. Selecting A.OUT will choose the - old "a.out" format which may be necessary for some old versions - of binutils or on some architectures. - - This is especially useful if you have compiled the kernel with the - "-g" option to preserve debugging information. It is mainly used - for examining kernel data structures on the live kernel so if you - don't understand what this means or are not a kernel hacker, just - leave it at its default value ELF. - config SPARC32_COMPAT bool "Kernel support for Linux/Sparc 32bit binary compatibility" help diff -Nru a/arch/sparc64/kernel/entry.S b/arch/sparc64/kernel/entry.S --- a/arch/sparc64/kernel/entry.S Tue Sep 2 19:58:12 2003 +++ b/arch/sparc64/kernel/entry.S Tue Sep 2 19:58:12 2003 @@ -26,7 +26,7 @@ #define curptr g6 -#define NR_SYSCALLS 266 /* Each OS is different... */ +#define NR_SYSCALLS 267 /* Each OS is different... */ .text .align 32 diff -Nru a/arch/sparc64/kernel/ioctl32.c b/arch/sparc64/kernel/ioctl32.c --- a/arch/sparc64/kernel/ioctl32.c Tue Sep 2 19:58:18 2003 +++ b/arch/sparc64/kernel/ioctl32.c Tue Sep 2 19:58:18 2003 @@ -1388,7 +1388,7 @@ #define IOCTL_TABLE_START \ struct ioctl_trans ioctl_start[] = { #define IOCTL_TABLE_END \ - }; struct ioctl_trans ioctl_end[0]; + }; IOCTL_TABLE_START #include @@ -1583,3 +1583,5 @@ HANDLE_IOCTL(USBDEVFS_DISCSIGNAL32, do_usbdevfs_discsignal) /* take care of sizeof(sizeof()) breakage */ IOCTL_TABLE_END + +int ioctl_table_size = ARRAY_SIZE(ioctl_start); diff -Nru a/arch/sparc64/kernel/irq.c b/arch/sparc64/kernel/irq.c --- a/arch/sparc64/kernel/irq.c Tue Sep 2 19:58:19 2003 +++ b/arch/sparc64/kernel/irq.c Tue Sep 2 19:58:19 2003 @@ -1097,6 +1097,18 @@ memset(__irq_work + smp_processor_id(), 0, sizeof(*workp)); + /* Make sure we are called with PSTATE_IE disabled. */ + __asm__ __volatile__("rdpr %%pstate, %0\n\t" + : "=r" (tmp)); + if (tmp & PSTATE_IE) { + prom_printf("BUG: init_irqwork_curcpu() called with " + "PSTATE_IE enabled, bailing.\n"); + __asm__ __volatile__("mov %%i7, %0\n\t" + : "=r" (tmp)); + prom_printf("BUG: Called from %lx\n", tmp); + prom_halt(); + } + /* Set interrupt globals. */ workp = &__irq_work[smp_processor_id()]; __asm__ __volatile__( @@ -1105,7 +1117,7 @@ "mov %2, %%g6\n\t" "wrpr %0, 0x0, %%pstate\n\t" : "=&r" (tmp) - : "i" (PSTATE_IG | PSTATE_IE), "r" (workp)); + : "i" (PSTATE_IG), "r" (workp)); } /* Only invoked on boot processor. */ diff -Nru a/arch/sparc64/kernel/pci_psycho.c b/arch/sparc64/kernel/pci_psycho.c --- a/arch/sparc64/kernel/pci_psycho.c Tue Sep 2 19:58:16 2003 +++ b/arch/sparc64/kernel/pci_psycho.c Tue Sep 2 19:58:16 2003 @@ -874,6 +874,46 @@ #define PSYCHO_PCI_AFAR_A 0x2018UL #define PSYCHO_PCI_AFAR_B 0x4018UL +static irqreturn_t psycho_pcierr_intr_other(struct pci_pbm_info *pbm, int is_pbm_a) +{ + unsigned long csr_reg, csr, csr_error_bits; + irqreturn_t ret = IRQ_NONE; + u16 stat; + + if (is_pbm_a) { + csr_reg = pbm->controller_regs + PSYCHO_PCIA_CTRL; + } else { + csr_reg = pbm->controller_regs + PSYCHO_PCIB_CTRL; + } + csr = psycho_read(csr_reg); + csr_error_bits = + csr & (PSYCHO_PCICTRL_SBH_ERR | PSYCHO_PCICTRL_SERR); + if (csr_error_bits) { + /* Clear the errors. */ + psycho_write(csr_reg, csr); + + /* Log 'em. */ + if (csr_error_bits & PSYCHO_PCICTRL_SBH_ERR) + printk("%s: PCI streaming byte hole error asserted.\n", + pbm->name); + if (csr_error_bits & PSYCHO_PCICTRL_SERR) + printk("%s: PCI SERR signal asserted.\n", pbm->name); + ret = IRQ_HANDLED; + } + pci_read_config_word(pbm->pci_bus->self, PCI_STATUS, &stat); + if (stat & (PCI_STATUS_PARITY | + PCI_STATUS_SIG_TARGET_ABORT | + PCI_STATUS_REC_TARGET_ABORT | + PCI_STATUS_REC_MASTER_ABORT | + PCI_STATUS_SIG_SYSTEM_ERROR)) { + printk("%s: PCI bus error, PCI_STATUS[%04x]\n", + pbm->name, stat); + pci_write_config_word(pbm->pci_bus->self, PCI_STATUS, 0xffff); + ret = IRQ_HANDLED; + } + return ret; +} + static irqreturn_t psycho_pcierr_intr(int irq, void *dev_id, struct pt_regs *regs) { struct pci_pbm_info *pbm = dev_id; @@ -902,7 +942,7 @@ PSYCHO_PCIAFSR_SMA | PSYCHO_PCIAFSR_STA | PSYCHO_PCIAFSR_SRTRY | PSYCHO_PCIAFSR_SPERR); if (!error_bits) - return IRQ_NONE; + return psycho_pcierr_intr_other(pbm, is_pbm_a); psycho_write(afsr_reg, error_bits); /* Log the error. */ @@ -1008,6 +1048,7 @@ prom_halt(); } + pbm = &p->pbm_A; irq = psycho_irq_build(pbm, NULL, (portid << 6) | PSYCHO_PCIERR_A_INO); if (request_irq(irq, psycho_pcierr_intr, SA_SHIRQ, "PSYCHO PCIERR", &p->pbm_A) < 0) { @@ -1016,6 +1057,7 @@ prom_halt(); } + pbm = &p->pbm_B; irq = psycho_irq_build(pbm, NULL, (portid << 6) | PSYCHO_PCIERR_B_INO); if (request_irq(irq, psycho_pcierr_intr, SA_SHIRQ, "PSYCHO PCIERR", &p->pbm_B) < 0) { diff -Nru a/arch/sparc64/kernel/pci_sabre.c b/arch/sparc64/kernel/pci_sabre.c --- a/arch/sparc64/kernel/pci_sabre.c Tue Sep 2 19:58:19 2003 +++ b/arch/sparc64/kernel/pci_sabre.c Tue Sep 2 19:58:19 2003 @@ -221,6 +221,7 @@ ((unsigned long)(REG))) static int hummingbird_p; +static struct pci_bus *sabre_root_bus; static void *sabre_pci_config_mkaddr(struct pci_pbm_info *pbm, unsigned char bus, @@ -860,6 +861,42 @@ return IRQ_HANDLED; } +static irqreturn_t sabre_pcierr_intr_other(struct pci_controller_info *p) +{ + unsigned long csr_reg, csr, csr_error_bits; + irqreturn_t ret = IRQ_NONE; + u16 stat; + + csr_reg = p->pbm_A.controller_regs + SABRE_PCICTRL; + csr = sabre_read(csr_reg); + csr_error_bits = + csr & SABRE_PCICTRL_SERR; + if (csr_error_bits) { + /* Clear the errors. */ + sabre_write(csr_reg, csr); + + /* Log 'em. */ + if (csr_error_bits & SABRE_PCICTRL_SERR) + printk("SABRE%d: PCI SERR signal asserted.\n", + p->index); + ret = IRQ_HANDLED; + } + pci_read_config_word(sabre_root_bus->self, + PCI_STATUS, &stat); + if (stat & (PCI_STATUS_PARITY | + PCI_STATUS_SIG_TARGET_ABORT | + PCI_STATUS_REC_TARGET_ABORT | + PCI_STATUS_REC_MASTER_ABORT | + PCI_STATUS_SIG_SYSTEM_ERROR)) { + printk("SABRE%d: PCI bus error, PCI_STATUS[%04x]\n", + p->index, stat); + pci_write_config_word(sabre_root_bus->self, + PCI_STATUS, 0xffff); + ret = IRQ_HANDLED; + } + return ret; +} + static irqreturn_t sabre_pcierr_intr(int irq, void *dev_id, struct pt_regs *regs) { struct pci_controller_info *p = dev_id; @@ -881,7 +918,7 @@ SABRE_PIOAFSR_SMA | SABRE_PIOAFSR_STA | SABRE_PIOAFSR_SRTRY | SABRE_PIOAFSR_SPERR); if (!error_bits) - return IRQ_NONE; + return sabre_pcierr_intr_other(p); sabre_write(afsr_reg, error_bits); /* Log the error. */ @@ -1167,6 +1204,8 @@ &p->pbm_A); pci_fixup_host_bridge_self(sabre_bus); sabre_bus->self->sysdata = cookie; + + sabre_root_bus = sabre_bus; apb_init(p, sabre_bus); diff -Nru a/arch/sparc64/kernel/pci_schizo.c b/arch/sparc64/kernel/pci_schizo.c --- a/arch/sparc64/kernel/pci_schizo.c Tue Sep 2 19:58:17 2003 +++ b/arch/sparc64/kernel/pci_schizo.c Tue Sep 2 19:58:17 2003 @@ -845,6 +845,88 @@ #define SCHIZO_PCIAFSR_MEM 0x0000000020000000UL /* Schizo/Tomatillo */ #define SCHIZO_PCIAFSR_IO 0x0000000010000000UL /* Schizo/Tomatillo */ +#define SCHIZO_PCI_CTRL (0x2000UL) +#define SCHIZO_PCICTRL_BUS_UNUS (1UL << 63UL) /* Safari */ +#define SCHIZO_PCICTRL_ARB_PRIO (0x1ff << 52UL) /* Tomatillo */ +#define SCHIZO_PCICTRL_ESLCK (1UL << 51UL) /* Safari */ +#define SCHIZO_PCICTRL_ERRSLOT (7UL << 48UL) /* Safari */ +#define SCHIZO_PCICTRL_TTO_ERR (1UL << 38UL) /* Safari/Tomatillo */ +#define SCHIZO_PCICTRL_RTRY_ERR (1UL << 37UL) /* Safari/Tomatillo */ +#define SCHIZO_PCICTRL_DTO_ERR (1UL << 36UL) /* Safari/Tomatillo */ +#define SCHIZO_PCICTRL_SBH_ERR (1UL << 35UL) /* Safari */ +#define SCHIZO_PCICTRL_SERR (1UL << 34UL) /* Safari/Tomatillo */ +#define SCHIZO_PCICTRL_PCISPD (1UL << 33UL) /* Safari */ +#define SCHIZO_PCICTRL_MRM_PREF (1UL << 28UL) /* Tomatillo */ +#define SCHIZO_PCICTRL_RDO_PREF (1UL << 27UL) /* Tomatillo */ +#define SCHIZO_PCICTRL_RDL_PREF (1UL << 26UL) /* Tomatillo */ +#define SCHIZO_PCICTRL_PTO (3UL << 24UL) /* Safari/Tomatillo */ +#define SCHIZO_PCICTRL_PTO_SHIFT 24UL +#define SCHIZO_PCICTRL_TRWSW (7UL << 21UL) /* Tomatillo */ +#define SCHIZO_PCICTRL_F_TGT_A (1UL << 20UL) /* Tomatillo */ +#define SCHIZO_PCICTRL_S_DTO_INT (1UL << 19UL) /* Safari */ +#define SCHIZO_PCICTRL_F_TGT_RT (1UL << 19UL) /* Tomatillo */ +#define SCHIZO_PCICTRL_SBH_INT (1UL << 18UL) /* Safari */ +#define SCHIZO_PCICTRL_T_DTO_INT (1UL << 18UL) /* Tomatillo */ +#define SCHIZO_PCICTRL_EEN (1UL << 17UL) /* Safari/Tomatillo */ +#define SCHIZO_PCICTRL_PARK (1UL << 16UL) /* Safari/Tomatillo */ +#define SCHIZO_PCICTRL_PCIRST (1UL << 8UL) /* Safari */ +#define SCHIZO_PCICTRL_ARB_S (0x3fUL << 0UL) /* Safari */ +#define SCHIZO_PCICTRL_ARB_T (0xffUL << 0UL) /* Tomatillo */ + +static irqreturn_t schizo_pcierr_intr_other(struct pci_pbm_info *pbm) +{ + unsigned long csr_reg, csr, csr_error_bits; + irqreturn_t ret = IRQ_NONE; + u16 stat; + + csr_reg = pbm->pbm_regs + SCHIZO_PCI_CTRL; + csr = schizo_read(csr_reg); + csr_error_bits = + csr & (SCHIZO_PCICTRL_BUS_UNUS | + SCHIZO_PCICTRL_TTO_ERR | + SCHIZO_PCICTRL_RTRY_ERR | + SCHIZO_PCICTRL_DTO_ERR | + SCHIZO_PCICTRL_SBH_ERR | + SCHIZO_PCICTRL_SERR); + if (csr_error_bits) { + /* Clear the errors. */ + schizo_write(csr_reg, csr); + + /* Log 'em. */ + if (csr_error_bits & SCHIZO_PCICTRL_BUS_UNUS) + printk("%s: Bus unusable error asserted.\n", + pbm->name); + if (csr_error_bits & SCHIZO_PCICTRL_TTO_ERR) + printk("%s: PCI TRDY# timeout error asserted.\n", + pbm->name); + if (csr_error_bits & SCHIZO_PCICTRL_RTRY_ERR) + printk("%s: PCI excessive retry error asserted.\n", + pbm->name); + if (csr_error_bits & SCHIZO_PCICTRL_DTO_ERR) + printk("%s: PCI discard timeout error asserted.\n", + pbm->name); + if (csr_error_bits & SCHIZO_PCICTRL_SBH_ERR) + printk("%s: PCI streaming byte hole error asserted.\n", + pbm->name); + if (csr_error_bits & SCHIZO_PCICTRL_SERR) + printk("%s: PCI SERR signal asserted.\n", + pbm->name); + ret = IRQ_HANDLED; + } + pci_read_config_word(pbm->pci_bus->self, PCI_STATUS, &stat); + if (stat & (PCI_STATUS_PARITY | + PCI_STATUS_SIG_TARGET_ABORT | + PCI_STATUS_REC_TARGET_ABORT | + PCI_STATUS_REC_MASTER_ABORT | + PCI_STATUS_SIG_SYSTEM_ERROR)) { + printk("%s: PCI bus error, PCI_STATUS[%04x]\n", + pbm->name, stat); + pci_write_config_word(pbm->pci_bus->self, PCI_STATUS, 0xffff); + ret = IRQ_HANDLED; + } + return ret; +} + static irqreturn_t schizo_pcierr_intr(int irq, void *dev_id, struct pt_regs *regs) { struct pci_pbm_info *pbm = dev_id; @@ -871,7 +953,7 @@ SCHIZO_PCIAFSR_SRTRY | SCHIZO_PCIAFSR_SPERR | SCHIZO_PCIAFSR_STTO | SCHIZO_PCIAFSR_SUNUS); if (!error_bits) - return IRQ_NONE; + return schizo_pcierr_intr_other(pbm); schizo_write(afsr_reg, error_bits); /* Log the error. */ @@ -1043,34 +1125,6 @@ #define SCHIZO_PCIERR_A_INO 0x32 /* PBM A PCI bus error */ #define SCHIZO_PCIERR_B_INO 0x33 /* PBM B PCI bus error */ #define SCHIZO_SERR_INO 0x34 /* Safari interface error */ - -#define SCHIZO_PCI_CTRL (0x2000UL) -#define SCHIZO_PCICTRL_BUS_UNUS (1UL << 63UL) /* Safari */ -#define SCHIZO_PCICTRL_ARB_PRIO (0x1ff << 52UL) /* Tomatillo */ -#define SCHIZO_PCICTRL_ESLCK (1UL << 51UL) /* Safari */ -#define SCHIZO_PCICTRL_ERRSLOT (7UL << 48UL) /* Safari */ -#define SCHIZO_PCICTRL_TTO_ERR (1UL << 38UL) /* Safari/Tomatillo */ -#define SCHIZO_PCICTRL_RTRY_ERR (1UL << 37UL) /* Safari/Tomatillo */ -#define SCHIZO_PCICTRL_DTO_ERR (1UL << 36UL) /* Safari/Tomatillo */ -#define SCHIZO_PCICTRL_SBH_ERR (1UL << 35UL) /* Safari */ -#define SCHIZO_PCICTRL_SERR (1UL << 34UL) /* Safari/Tomatillo */ -#define SCHIZO_PCICTRL_PCISPD (1UL << 33UL) /* Safari */ -#define SCHIZO_PCICTRL_MRM_PREF (1UL << 28UL) /* Tomatillo */ -#define SCHIZO_PCICTRL_RDO_PREF (1UL << 27UL) /* Tomatillo */ -#define SCHIZO_PCICTRL_RDL_PREF (1UL << 26UL) /* Tomatillo */ -#define SCHIZO_PCICTRL_PTO (3UL << 24UL) /* Safari/Tomatillo */ -#define SCHIZO_PCICTRL_PTO_SHIFT 24UL -#define SCHIZO_PCICTRL_TRWSW (7UL << 21UL) /* Tomatillo */ -#define SCHIZO_PCICTRL_F_TGT_A (1UL << 20UL) /* Tomatillo */ -#define SCHIZO_PCICTRL_S_DTO_INT (1UL << 19UL) /* Safari */ -#define SCHIZO_PCICTRL_F_TGT_RT (1UL << 19UL) /* Tomatillo */ -#define SCHIZO_PCICTRL_SBH_INT (1UL << 18UL) /* Safari */ -#define SCHIZO_PCICTRL_T_DTO_INT (1UL << 18UL) /* Tomatillo */ -#define SCHIZO_PCICTRL_EEN (1UL << 17UL) /* Safari/Tomatillo */ -#define SCHIZO_PCICTRL_PARK (1UL << 16UL) /* Safari/Tomatillo */ -#define SCHIZO_PCICTRL_PCIRST (1UL << 8UL) /* Safari */ -#define SCHIZO_PCICTRL_ARB_S (0x3fUL << 0UL) /* Safari */ -#define SCHIZO_PCICTRL_ARB_T (0xffUL << 0UL) /* Tomatillo */ struct pci_pbm_info *pbm_for_ino(struct pci_controller_info *p, u32 ino) { diff -Nru a/arch/sparc64/kernel/sys_sparc32.c b/arch/sparc64/kernel/sys_sparc32.c --- a/arch/sparc64/kernel/sys_sparc32.c Tue Sep 2 19:58:17 2003 +++ b/arch/sparc64/kernel/sys_sparc32.c Tue Sep 2 19:58:17 2003 @@ -388,7 +388,7 @@ * * This is really horribly ugly. */ -#define IPCOP_MASK(__x) (1UL << (__x)) +#define IPCOP_MASK(__x) (1UL << ((__x)&~IPC_64)) static int do_sys32_semctl(int first, int second, int third, void *uptr) { union semun fourth; @@ -400,7 +400,7 @@ err = -EFAULT; if (get_user (pad, (u32 *)uptr)) goto out; - if(third == SETVAL) + if ((third & ~IPC_64) == SETVAL) fourth.val = (int)pad; else fourth.__pad = (void *)A(pad); @@ -2779,3 +2779,41 @@ return sys_lookup_dcookie((u64)cookie_high << 32 | cookie_low, buf, len); } + +extern asmlinkage long +sys_timer_create(clockid_t which_clock, struct sigevent *timer_event_spec, + timer_t * created_timer_id); + +long +sys32_timer_create(u32 clock, struct sigevent32 *se32, timer_t *timer_id) +{ + struct sigevent se; + mm_segment_t oldfs; + timer_t t; + long err; + + if (se32 == NULL) + return sys_timer_create(clock, NULL, timer_id); + + memset(&se, 0, sizeof(struct sigevent)); + if (get_user(se.sigev_value.sival_int, &se32->sigev_value.sival_int) || + __get_user(se.sigev_signo, &se32->sigev_signo) || + __get_user(se.sigev_notify, &se32->sigev_notify) || + __copy_from_user(&se._sigev_un._pad, &se32->_sigev_un._pad, + sizeof(se._sigev_un._pad))) + return -EFAULT; + + if (!access_ok(VERIFY_WRITE,timer_id,sizeof(timer_t))) + return -EFAULT; + + oldfs = get_fs(); + set_fs(KERNEL_DS); + err = sys_timer_create(clock, &se, &t); + set_fs(oldfs); + + if (!err) + err = __put_user (t, timer_id); + + return err; +} + diff -Nru a/arch/sparc64/kernel/sys_sunos32.c b/arch/sparc64/kernel/sys_sunos32.c --- a/arch/sparc64/kernel/sys_sunos32.c Tue Sep 2 19:58:16 2003 +++ b/arch/sparc64/kernel/sys_sunos32.c Tue Sep 2 19:58:16 2003 @@ -90,7 +90,7 @@ if (!file) goto out; inode = file->f_dentry->d_inode; - if (minor(inode->i_rdev) == MEM_MAJOR && minor(inode->i_rdev) == 5) { + if (imajor(inode) == MEM_MAJOR && iminor(inode) == 5) { flags |= MAP_ANONYMOUS; fput(file); file = NULL; diff -Nru a/arch/sparc64/kernel/systbls.S b/arch/sparc64/kernel/systbls.S --- a/arch/sparc64/kernel/systbls.S Tue Sep 2 19:58:15 2003 +++ b/arch/sparc64/kernel/systbls.S Tue Sep 2 19:58:15 2003 @@ -72,7 +72,7 @@ /*250*/ .word sys32_mremap, sys32_sysctl, sys_getsid, sys_fdatasync, sys32_nfsservctl .word sys_ni_syscall, compat_clock_settime, compat_clock_gettime, compat_clock_getres, compat_clock_nanosleep /*260*/ .word compat_sys_sched_getaffinity, compat_sys_sched_setaffinity, compat_timer_settime, compat_timer_gettime, sys_timer_getoverrun - .word sys_timer_delete, sys_ni_syscall + .word sys_timer_delete, sys32_timer_create, sys_ni_syscall /* Now the 64-bit native Linux syscall table. */ @@ -133,7 +133,7 @@ /*250*/ .word sys64_mremap, sys_sysctl, sys_getsid, sys_fdatasync, sys_nfsservctl .word sys_ni_syscall, sys_clock_settime, sys_clock_gettime, sys_clock_getres, sys_clock_nanosleep /*260*/ .word sys_sched_getaffinity, sys_sched_setaffinity, sys_timer_settime, sys_timer_gettime, sys_timer_getoverrun - .word sys_timer_delete, sys_ni_syscall + .word sys_timer_delete, sys_timer_create, sys_ni_syscall #if defined(CONFIG_SUNOS_EMUL) || defined(CONFIG_SOLARIS_EMUL) || \ defined(CONFIG_SOLARIS_EMUL_MODULE) @@ -228,10 +228,10 @@ .word sunos_nosys, sunos_nosys, sunos_nosys .word sunos_nosys, sunos_nosys /*250*/ .word sunos_nosys, sunos_nosys, sunos_nosys - .word sunos_nosys, sunos_nosys, sys_ni_syscall - .word sys_ni_syscall, sys_ni_syscall, sys_ni_syscall - .word sys_ni_syscall, sys_ni_syscall, sys_ni_syscall - .word sys_ni_syscall, sys_ni_syscall, sys_ni_syscall - .word sys_ni_syscall, sys_ni_syscall + .word sunos_nosys, sunos_nosys, sunos_nosys + .word sunos_nosys, sunos_nosys, sunos_nosys + .word sunos_nosys, sunos_nosys, sunos_nosys + .word sunos_nosys, sunos_nosys, sunos_nosys + .word sunos_nosys, sunos_nosys, sunos_nosys #endif diff -Nru a/arch/sparc64/mm/hugetlbpage.c b/arch/sparc64/mm/hugetlbpage.c --- a/arch/sparc64/mm/hugetlbpage.c Tue Sep 2 19:58:17 2003 +++ b/arch/sparc64/mm/hugetlbpage.c Tue Sep 2 19:58:17 2003 @@ -380,207 +380,6 @@ return 1; } -static struct inode *set_new_inode(unsigned long len, int prot, int flag, int key) -{ - struct inode *inode; - int i; - - for (i = 0; i < MAX_ID; i++) { - if (htlbpagek[i].key == 0) - break; - } - if (i == MAX_ID) - return NULL; - inode = kmalloc(sizeof (struct inode), GFP_KERNEL); - if (inode == NULL) - return NULL; - - inode_init_once(inode); - atomic_inc(&inode->i_writecount); - inode->i_mapping = &inode->i_data; - inode->i_mapping->host = inode; - inode->i_ino = (unsigned long)key; - - htlbpagek[i].key = key; - htlbpagek[i].in = inode; - inode->i_uid = current->fsuid; - inode->i_gid = current->fsgid; - inode->i_mode = prot; - inode->i_size = len; - return inode; -} - -static int check_size_prot(struct inode *inode, unsigned long len, int prot, int flag) -{ - if (inode->i_uid != current->fsuid) - return -1; - if (inode->i_gid != current->fsgid) - return -1; - if (inode->i_size != len) - return -1; - return 0; -} - -static int alloc_shared_hugetlb_pages(int key, unsigned long addr, unsigned long len, - int prot, int flag) -{ - struct mm_struct *mm = current->mm; - struct vm_area_struct *vma; - struct inode *inode; - struct address_space *mapping; - struct page *page; - int idx; - int retval = -ENOMEM; - int newalloc = 0; - -try_again: - spin_lock(&htlbpage_lock); - - inode = find_key_inode(key); - if (inode == NULL) { - if (!capable(CAP_SYS_ADMIN)) { - if (!in_group_p(0)) { - retval = -EPERM; - goto out_err; - } - } - if (!(flag & IPC_CREAT)) { - retval = -ENOENT; - goto out_err; - } - inode = set_new_inode(len, prot, flag, key); - if (inode == NULL) - goto out_err; - newalloc = 1; - } else { - if (check_size_prot(inode, len, prot, flag) < 0) { - retval = -EINVAL; - goto out_err; - } else if (atomic_read(&inode->i_writecount)) { - spin_unlock(&htlbpage_lock); - goto try_again; - } - } - spin_unlock(&htlbpage_lock); - mapping = inode->i_mapping; - - addr = do_mmap_pgoff(NULL, addr, len, (unsigned long) prot, - MAP_NORESERVE|MAP_FIXED|MAP_PRIVATE|MAP_ANONYMOUS, 0); - if (IS_ERR((void *) addr)) - goto freeinode; - - vma = find_vma(mm, addr); - if (!vma) { - retval = -EINVAL; - goto freeinode; - } - - spin_lock(&mm->page_table_lock); - do { - pte_t *pte = huge_pte_alloc_map(mm, addr); - - if (!pte || !pte_none(pte)) { - if (pte) - pte_unmap(pte); - goto out; - } - - idx = (addr - vma->vm_start) >> HPAGE_SHIFT; - page = find_get_page(mapping, idx); - if (page == NULL) { - page = alloc_hugetlb_page(); - if (page == NULL) { - pte_unmap(pte); - retval = -ENOMEM; - goto out; - } - retval = add_to_page_cache(page, mapping, - idx, GFP_ATOMIC); - if (retval) { - pte_unmap(pte); - free_hugetlb_page(page); - goto out; - } - } - set_huge_pte(mm, vma, page, pte, - (vma->vm_flags & VM_WRITE)); - pte_unmap(pte); - - addr += HPAGE_SIZE; - } while (addr < vma->vm_end); - - retval = 0; - vma->vm_flags |= (VM_HUGETLB | VM_RESERVED); - vma->vm_ops = &hugetlb_vm_ops; - spin_unlock(&mm->page_table_lock); - spin_lock(&htlbpage_lock); - atomic_set(&inode->i_writecount, 0); - spin_unlock(&htlbpage_lock); - - return retval; - -out: - if (addr > vma->vm_start) { - unsigned long raddr; - raddr = vma->vm_end; - vma->vm_end = addr; - - flush_cache_range(vma, vma->vm_start, vma->vm_end); - zap_hugetlb_resources(vma); - flush_tlb_range(vma, vma->vm_start, vma->vm_end); - - vma->vm_end = raddr; - } - spin_unlock(&mm->page_table_lock); - do_munmap(mm, vma->vm_start, len); - if (newalloc) - goto freeinode; - - return retval; - -out_err: - spin_unlock(&htlbpage_lock); - -freeinode: - if (newalloc) { - for (idx = 0; idx < MAX_ID; idx++) { - if (htlbpagek[idx].key == inode->i_ino) { - htlbpagek[idx].key = 0; - htlbpagek[idx].in = NULL; - break; - } - } - kfree(inode); - } - return retval; -} - -static int alloc_private_hugetlb_pages(int key, unsigned long addr, unsigned long len, - int prot, int flag) -{ - if (!capable(CAP_SYS_ADMIN)) { - if (!in_group_p(0)) - return -EPERM; - } - addr = do_mmap_pgoff(NULL, addr, len, prot, - MAP_NORESERVE|MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, 0); - if (IS_ERR((void *) addr)) - return -ENOMEM; - if (make_hugetlb_pages_present(addr, (addr + len), flag) < 0) { - do_munmap(current->mm, addr, len); - return -ENOMEM; - } - return 0; -} - -int alloc_hugetlb_pages(int key, unsigned long addr, unsigned long len, int prot, - int flag) -{ - if (key > 0) - return alloc_shared_hugetlb_pages(key, addr, len, prot, flag); - return alloc_private_hugetlb_pages(key, addr, len, prot, flag); -} - extern long htlbzone_pages; extern struct list_head htlbpage_freelist; diff -Nru a/arch/sparc64/solaris/misc.c b/arch/sparc64/solaris/misc.c --- a/arch/sparc64/solaris/misc.c Tue Sep 2 19:58:19 2003 +++ b/arch/sparc64/solaris/misc.c Tue Sep 2 19:58:19 2003 @@ -77,8 +77,8 @@ goto out; else { struct inode * inode = file->f_dentry->d_inode; - if(major(inode->i_rdev) == MEM_MAJOR && - minor(inode->i_rdev) == 5) { + if(imajor(inode) == MEM_MAJOR && + iminor(inode) == 5) { flags |= MAP_ANONYMOUS; fput(file); file = NULL; diff -Nru a/arch/sparc64/solaris/socksys.c b/arch/sparc64/solaris/socksys.c --- a/arch/sparc64/solaris/socksys.c Tue Sep 2 19:58:15 2003 +++ b/arch/sparc64/solaris/socksys.c Tue Sep 2 19:58:15 2003 @@ -70,14 +70,14 @@ (int (*)(int,int,int))SUNOS(97); struct sol_socket_struct * sock; - family = ((minor(inode->i_rdev) >> 4) & 0xf); + family = ((iminor(inode) >> 4) & 0xf); switch (family) { case AF_UNIX: type = SOCK_STREAM; protocol = 0; break; case AF_INET: - protocol = af_inet_protocols[minor(inode->i_rdev) & 0xf]; + protocol = af_inet_protocols[iminor(inode) & 0xf]; switch (protocol) { case IPPROTO_TCP: type = SOCK_STREAM; break; case IPPROTO_UDP: type = SOCK_DGRAM; break; diff -Nru a/arch/sparc64/solaris/systbl.S b/arch/sparc64/solaris/systbl.S --- a/arch/sparc64/solaris/systbl.S Tue Sep 2 19:58:12 2003 +++ b/arch/sparc64/solaris/systbl.S Tue Sep 2 19:58:12 2003 @@ -294,4 +294,5 @@ .word solaris_unimplemented /* 264 */ .word solaris_unimplemented /* 265 */ .word solaris_unimplemented /* 266 */ + .word solaris_unimplemented /* 267 */ diff -Nru a/arch/sparc64/solaris/timod.c b/arch/sparc64/solaris/timod.c --- a/arch/sparc64/solaris/timod.c Tue Sep 2 19:58:15 2003 +++ b/arch/sparc64/solaris/timod.c Tue Sep 2 19:58:15 2003 @@ -924,7 +924,7 @@ if (!ino) goto out; if (!ino->i_sock && - (major(ino->i_rdev) != 30 || minor(ino->i_rdev) != 1)) + (imajor(ino) != 30 || iminor(ino) != 1)) goto out; ctlptr = (struct strbuf *)A(arg1); diff -Nru a/arch/v850/Kconfig b/arch/v850/Kconfig --- a/arch/v850/Kconfig Tue Sep 2 19:58:15 2003 +++ b/arch/v850/Kconfig Tue Sep 2 19:58:15 2003 @@ -262,14 +262,6 @@ menu "Executable file formats" -config KCORE_AOUT - bool - default y - -config KCORE_ELF - bool - default y - source "fs/Kconfig.binfmt" endmenu diff -Nru a/arch/v850/kernel/vmlinux.lds.S b/arch/v850/kernel/vmlinux.lds.S --- a/arch/v850/kernel/vmlinux.lds.S Tue Sep 2 19:58:17 2003 +++ b/arch/v850/kernel/vmlinux.lds.S Tue Sep 2 19:58:17 2003 @@ -33,6 +33,30 @@ *(.intv.mach) /* Machine-specific int. vectors. */ \ __intv_end = . ; +#define RODATA_CONTENTS \ + . = ALIGN (16) ; \ + *(.rodata) *(.rodata.*) \ + *(__vermagic) /* Kernel version magic */ \ + *(.rodata1) \ + /* Kernel symbol table: Normal symbols */ \ + ___start___ksymtab = .; \ + *(__ksymtab) \ + ___stop___ksymtab = .; \ + /* Kernel symbol table: GPL-only symbols */ \ + ___start___ksymtab_gpl = .; \ + *(__ksymtab_gpl) \ + ___stop___ksymtab_gpl = .; \ + /* Kernel symbol table: strings */ \ + *(__ksymtab_strings) \ + /* Kernel symbol table: Normal symbols */ \ + ___start___kcrctab = .; \ + *(__kcrctab) \ + ___stop___kcrctab = .; \ + /* Kernel symbol table: GPL-only symbols */ \ + ___start___kcrctab_gpl = .; \ + *(__kcrctab_gpl) \ + ___stop___kcrctab_gpl = .; \ + /* Kernel text segment, and some constant data areas. */ #define TEXT_CONTENTS \ __stext = . ; \ @@ -42,7 +66,7 @@ *(.text.lock) \ *(.exitcall.exit) \ __real_etext = . ; /* There may be data after here. */ \ - RODATA \ + RODATA_CONTENTS \ . = ALIGN (4) ; \ *(.call_table_data) \ *(.call_table_text) \ diff -Nru a/arch/x86_64/Kconfig b/arch/x86_64/Kconfig --- a/arch/x86_64/Kconfig Tue Sep 2 19:58:18 2003 +++ b/arch/x86_64/Kconfig Tue Sep 2 19:58:18 2003 @@ -370,11 +370,6 @@ menu "Executable file formats / Emulations" -config KCORE_ELF - bool - depends on PROC_FS - default y - source "fs/Kconfig.binfmt" config IA32_EMULATION diff -Nru a/arch/x86_64/defconfig b/arch/x86_64/defconfig --- a/arch/x86_64/defconfig Tue Sep 2 19:58:17 2003 +++ b/arch/x86_64/defconfig Tue Sep 2 19:58:17 2003 @@ -14,6 +14,7 @@ # Code maturity level options # CONFIG_EXPERIMENTAL=y +# CONFIG_BROKEN is not set # # General setup @@ -23,10 +24,12 @@ # CONFIG_BSD_PROCESS_ACCT is not set CONFIG_SYSCTL=y CONFIG_LOG_BUF_SHIFT=18 +# CONFIG_IKCONFIG is not set # CONFIG_EMBEDDED is not set CONFIG_KALLSYMS=y CONFIG_FUTEX=y CONFIG_EPOLL=y +CONFIG_IOSCHED_NOOP=y CONFIG_IOSCHED_AS=y CONFIG_IOSCHED_DEADLINE=y @@ -72,10 +75,10 @@ CONFIG_SOFTWARE_SUSPEND=y # -# ACPI Support +# ACPI (Advanced Configuration and Power Interface) Support # +# CONFIG_ACPI_HT is not set CONFIG_ACPI=y -# CONFIG_ACPI_HT_ONLY is not set CONFIG_ACPI_BOOT=y CONFIG_ACPI_SLEEP=y CONFIG_ACPI_SLEEP_PROC_FS=y @@ -117,7 +120,6 @@ # # Generic Driver Options # -# CONFIG_FW_LOADER is not set # # Memory Technology Devices (MTD) @@ -159,6 +161,7 @@ CONFIG_IDEDISK_MULTI_MODE=y # CONFIG_IDEDISK_STROKE is not set CONFIG_BLK_DEV_IDECD=y +# CONFIG_BLK_DEV_IDETAPE is not set # CONFIG_BLK_DEV_IDEFLOPPY is not set # CONFIG_BLK_DEV_IDESCSI is not set # CONFIG_IDE_TASK_IOCTL is not set @@ -318,7 +321,6 @@ # CONFIG_DECNET is not set # CONFIG_BRIDGE is not set # CONFIG_NETFILTER is not set -# CONFIG_XFRM_USER is not set # # SCTP Configuration (EXPERIMENTAL) @@ -405,6 +407,7 @@ # CONFIG_HAMACHI is not set # CONFIG_YELLOWFIN is not set # CONFIG_R8169 is not set +# CONFIG_SIS190 is not set # CONFIG_SK98LIN is not set CONFIG_TIGON3=y @@ -595,10 +598,7 @@ CONFIG_REISERFS_FS=y # CONFIG_REISERFS_CHECK is not set # CONFIG_REISERFS_PROC_INFO is not set -CONFIG_JFS_FS=y -CONFIG_JFS_POSIX_ACL=y -# CONFIG_JFS_DEBUG is not set -# CONFIG_JFS_STATISTICS is not set +# CONFIG_JFS_FS is not set CONFIG_FS_POSIX_ACL=y # CONFIG_XFS_FS is not set # CONFIG_MINIX_FS is not set @@ -674,49 +674,6 @@ # # CONFIG_PARTITION_ADVANCED is not set CONFIG_MSDOS_PARTITION=y -CONFIG_NLS=y - -# -# Native Language Support -# -CONFIG_NLS_DEFAULT="iso8859-1" -# CONFIG_NLS_CODEPAGE_437 is not set -# CONFIG_NLS_CODEPAGE_737 is not set -# CONFIG_NLS_CODEPAGE_775 is not set -# CONFIG_NLS_CODEPAGE_850 is not set -# CONFIG_NLS_CODEPAGE_852 is not set -# CONFIG_NLS_CODEPAGE_855 is not set -# CONFIG_NLS_CODEPAGE_857 is not set -# CONFIG_NLS_CODEPAGE_860 is not set -# CONFIG_NLS_CODEPAGE_861 is not set -# CONFIG_NLS_CODEPAGE_862 is not set -# CONFIG_NLS_CODEPAGE_863 is not set -# CONFIG_NLS_CODEPAGE_864 is not set -# CONFIG_NLS_CODEPAGE_865 is not set -# CONFIG_NLS_CODEPAGE_866 is not set -# CONFIG_NLS_CODEPAGE_869 is not set -# CONFIG_NLS_CODEPAGE_936 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_1250 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 -# CONFIG_NLS_ISO8859_4 is not set -# CONFIG_NLS_ISO8859_5 is not set -# CONFIG_NLS_ISO8859_6 is not set -# CONFIG_NLS_ISO8859_7 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 # # Graphics support diff -Nru a/arch/x86_64/ia32/ia32_ioctl.c b/arch/x86_64/ia32/ia32_ioctl.c --- a/arch/x86_64/ia32/ia32_ioctl.c Tue Sep 2 19:58:16 2003 +++ b/arch/x86_64/ia32/ia32_ioctl.c Tue Sep 2 19:58:16 2003 @@ -673,12 +673,10 @@ return err; } -#define REF_SYMBOL(handler) if (0) (void)handler; -#define HANDLE_IOCTL2(cmd,handler) REF_SYMBOL(handler); asm volatile(".quad %P0, " #handler ",0"::"i" (cmd)); -#define HANDLE_IOCTL(cmd,handler) HANDLE_IOCTL2(cmd,handler) +#define HANDLE_IOCTL(cmd,handler) { (cmd), (ioctl_trans_handler_t)(handler), NULL }, #define COMPATIBLE_IOCTL(cmd) HANDLE_IOCTL(cmd,sys_ioctl) -#define IOCTL_TABLE_START void ioctl_dummy(void) { asm volatile("\n.global ioctl_start\nioctl_start:\n\t" ); -#define IOCTL_TABLE_END asm volatile("\n.global ioctl_end;\nioctl_end:\n"); } +#define IOCTL_TABLE_START struct ioctl_trans ioctl_start[] = { +#define IOCTL_TABLE_END }; IOCTL_TABLE_START #include @@ -765,3 +763,4 @@ HANDLE_IOCTL(MTRRIOC32_KILL_PAGE_ENTRY, mtrr_ioctl32) IOCTL_TABLE_END +int ioctl_table_size = ARRAY_SIZE(ioctl_start); diff -Nru a/arch/x86_64/ia32/sys_ia32.c b/arch/x86_64/ia32/sys_ia32.c --- a/arch/x86_64/ia32/sys_ia32.c Tue Sep 2 19:58:15 2003 +++ b/arch/x86_64/ia32/sys_ia32.c Tue Sep 2 19:58:15 2003 @@ -1170,8 +1170,6 @@ return ret; } -extern void check_pending(int signum); - asmlinkage long sys_utimes(char *, struct timeval *); asmlinkage long diff -Nru a/arch/x86_64/kernel/apic.c b/arch/x86_64/kernel/apic.c --- a/arch/x86_64/kernel/apic.c Tue Sep 2 19:58:13 2003 +++ b/arch/x86_64/kernel/apic.c Tue Sep 2 19:58:13 2003 @@ -299,7 +299,7 @@ * This is meaningless in clustered apic mode, so we skip it. */ if (!clustered_apic_mode && - !cpu_isset(GET_APIC_ID(apic_read(APIC_ID)), phys_cpu_present_map)) + !physid_isset(GET_APIC_ID(apic_read(APIC_ID)), phys_cpu_present_map)) BUG(); /* @@ -993,7 +993,7 @@ connect_bsp_APIC(); - phys_cpu_present_map = cpumask_of_cpu(0); + phys_cpu_present_map = physid_mask_of_physid(0); apic_write_around(APIC_ID, boot_cpu_id); setup_local_APIC(); diff -Nru a/arch/x86_64/kernel/io_apic.c b/arch/x86_64/kernel/io_apic.c --- a/arch/x86_64/kernel/io_apic.c Tue Sep 2 19:58:16 2003 +++ b/arch/x86_64/kernel/io_apic.c Tue Sep 2 19:58:16 2003 @@ -1014,7 +1014,7 @@ static void __init setup_ioapic_ids_from_mpc (void) { union IO_APIC_reg_00 reg_00; - cpumask_t phys_id_present_map = phys_cpu_present_map; + physid_mask_t phys_id_present_map = phys_cpu_present_map; int apic; int i; unsigned char old_id; @@ -1047,22 +1047,22 @@ * system must have a unique ID or we get lots of nice * 'stuck on smp_invalidate_needed IPI wait' messages. */ - if (cpu_isset(mp_ioapics[apic].mpc_apicid, phys_id_present_map)) { + if (physid_isset(mp_ioapics[apic].mpc_apicid, phys_id_present_map)) { printk(KERN_ERR "BIOS bug, IO-APIC#%d ID %d is already used!...\n", apic, mp_ioapics[apic].mpc_apicid); for (i = 0; i < 0xf; i++) - if (!cpu_isset(i, phys_id_present_map)) + if (!physid_isset(i, phys_id_present_map)) break; if (i >= 0xf) panic("Max APIC ID exceeded!\n"); printk(KERN_ERR "... fixing up to %d. (tell your hw vendor)\n", i); - cpu_set(i, phys_id_present_map); + physid_set(i, phys_id_present_map); mp_ioapics[apic].mpc_apicid = i; } else { printk(KERN_INFO "Using IO-APIC %d\n", mp_ioapics[apic].mpc_apicid); - cpu_set(mp_ioapics[apic].mpc_apicid, phys_id_present_map); + physid_set(mp_ioapics[apic].mpc_apicid, phys_id_present_map); } @@ -1642,7 +1642,7 @@ int __init io_apic_get_unique_id (int ioapic, int apic_id) { union IO_APIC_reg_00 reg_00; - static cpumask_t apic_id_map; + static physid_mask_t apic_id_map; unsigned long flags; int i = 0; @@ -1655,7 +1655,7 @@ * advantage of new APIC bus architecture. */ - if (!cpus_empty(apic_id_map)) + if (!physids_empty(apic_id_map)) apic_id_map = phys_cpu_present_map; spin_lock_irqsave(&ioapic_lock, flags); @@ -1672,10 +1672,10 @@ * Every APIC in a system must have a unique ID or we get lots of nice * 'stuck on smp_invalidate_needed IPI wait' messages. */ - if (cpu_isset(apic_id, apic_id_map)) { + if (physid_isset(apic_id, apic_id_map)) { for (i = 0; i < IO_APIC_MAX_ID; i++) { - if (!cpu_isset(i, apic_id_map)) + if (!physid_isset(i, apic_id_map)) break; } @@ -1688,7 +1688,7 @@ apic_id = i; } - cpu_set(apic_id, apic_id_map); + physid_set(apic_id, apic_id_map); if (reg_00.bits.ID != apic_id) { reg_00.bits.ID = apic_id; diff -Nru a/arch/x86_64/kernel/ioport.c b/arch/x86_64/kernel/ioport.c --- a/arch/x86_64/kernel/ioport.c Tue Sep 2 19:58:14 2003 +++ b/arch/x86_64/kernel/ioport.c Tue Sep 2 19:58:14 2003 @@ -10,12 +10,11 @@ #include #include #include -#include #include #include #include #include -#include +#include /* Set EXTENT bits starting at BASE in BITMAP to value TURN_ON. */ static void set_bitmap(unsigned long *bitmap, unsigned int base, unsigned int extent, int new_value) @@ -118,12 +117,7 @@ return -EPERM; } regs.eflags = (regs.eflags &~ 0x3000UL) | (level << 12); + /* Make sure we return the long way (not sysenter) */ + set_thread_flag(TIF_IRET); return 0; } - -void eat_key(void) -{ - if (inb(0x60) & 1) - inb(0x64); -} - diff -Nru a/arch/x86_64/kernel/mpparse.c b/arch/x86_64/kernel/mpparse.c --- a/arch/x86_64/kernel/mpparse.c Tue Sep 2 19:58:14 2003 +++ b/arch/x86_64/kernel/mpparse.c Tue Sep 2 19:58:14 2003 @@ -67,7 +67,7 @@ static unsigned int num_processors = 0; /* Bitmask of physically existing CPUs */ -cpumask_t phys_cpu_present_map = CPU_MASK_NONE; +physid_mask_t phys_cpu_present_map = PHYSID_MASK_NONE; /* ACPI MADT entry parsing functions */ #ifdef CONFIG_ACPI_BOOT @@ -126,7 +126,7 @@ } ver = m->mpc_apicver; - cpu_set(m->mpc_apicid, phys_cpu_present_map); + physid_set(m->mpc_apicid, phys_cpu_present_map); /* * Validate version */ diff -Nru a/arch/x86_64/kernel/msr.c b/arch/x86_64/kernel/msr.c --- a/arch/x86_64/kernel/msr.c Tue Sep 2 19:58:13 2003 +++ b/arch/x86_64/kernel/msr.c Tue Sep 2 19:58:13 2003 @@ -194,7 +194,7 @@ u32 data[2]; size_t rv; u32 reg = *ppos; - int cpu = minor(file->f_dentry->d_inode->i_rdev); + int cpu = iminor(file->f_dentry->d_inode); int err; if ( count % 8 ) @@ -219,7 +219,7 @@ u32 data[2]; size_t rv; u32 reg = *ppos; - int cpu = minor(file->f_dentry->d_inode->i_rdev); + int cpu = iminor(file->f_dentry->d_inode); int err; if ( count % 8 ) @@ -239,7 +239,7 @@ static int msr_open(struct inode *inode, struct file *file) { - int cpu = minor(file->f_dentry->d_inode->i_rdev); + int cpu = iminor(file->f_dentry->d_inode); struct cpuinfo_x86 *c = &(cpu_data)[cpu]; if (!cpu_online(cpu)) diff -Nru a/arch/x86_64/kernel/setup.c b/arch/x86_64/kernel/setup.c --- a/arch/x86_64/kernel/setup.c Tue Sep 2 19:58:12 2003 +++ b/arch/x86_64/kernel/setup.c Tue Sep 2 19:58:12 2003 @@ -243,6 +243,8 @@ void __init setup_arch(char **cmdline_p) { + unsigned long low_mem_size; + ROOT_DEV = ORIG_ROOT_DEV; drive_info = DRIVE_INFO; screen_info = SCREEN_INFO; @@ -378,7 +380,13 @@ request_resource(&ioport_resource, standard_io_resources+i); } - pci_mem_start = IOMAP_START; + /* Will likely break when you have unassigned resources with more + than 4GB memory and bridges that don't support more than 4GB. + Doing it properly would require to allocate GFP_DMA memory + in this case. */ + low_mem_size = ((end_pfn << PAGE_SHIFT) + 0xfffff) & ~0xfffff; + if (low_mem_size > pci_mem_start) + pci_mem_start = low_mem_size; #ifdef CONFIG_GART_IOMMU iommu_hole_init(); diff -Nru a/arch/x86_64/kernel/smpboot.c b/arch/x86_64/kernel/smpboot.c --- a/arch/x86_64/kernel/smpboot.c Tue Sep 2 19:58:20 2003 +++ b/arch/x86_64/kernel/smpboot.c Tue Sep 2 19:58:20 2003 @@ -734,10 +734,10 @@ current_thread_info()->cpu = 0; smp_tune_scheduling(); - if (!cpu_isset(hard_smp_processor_id(), phys_cpu_present_map)) { + if (!physid_isset(hard_smp_processor_id(), phys_cpu_present_map)) { printk("weird, boot CPU (#%d) not listed by the BIOS.\n", hard_smp_processor_id()); - cpu_set(hard_smp_processor_id(), phys_cpu_present_map); + physid_set(hard_smp_processor_id(), phys_cpu_present_map); } /* @@ -748,7 +748,7 @@ printk(KERN_NOTICE "SMP motherboard not detected.\n"); io_apic_irqs = 0; cpu_online_map = cpumask_of_cpu(0); - phys_cpu_present_map = cpumask_of_cpu(0); + phys_cpu_present_map = physid_mask_of_physid(0); if (APIC_init_uniprocessor()) printk(KERN_NOTICE "Local APIC not detected." " Using dummy APIC emulation.\n"); @@ -759,10 +759,10 @@ * Should not be necessary because the MP table should list the boot * CPU too, but we do it for the sake of robustness anyway. */ - if (!cpu_isset(boot_cpu_id, phys_cpu_present_map)) { + if (!physid_isset(boot_cpu_id, phys_cpu_present_map)) { printk(KERN_NOTICE "weird, boot CPU (#%d) not listed by the BIOS.\n", boot_cpu_id); - cpu_set(hard_smp_processor_id(), phys_cpu_present_map); + physid_set(hard_smp_processor_id(), phys_cpu_present_map); } /* @@ -774,7 +774,7 @@ printk(KERN_ERR "... forcing use of dummy APIC emulation. (tell your hw vendor)\n"); io_apic_irqs = 0; cpu_online_map = cpumask_of_cpu(0); - phys_cpu_present_map = cpumask_of_cpu(0); + phys_cpu_present_map = physid_mask_of_physid(0); disable_apic = 1; goto smp_done; } @@ -789,7 +789,7 @@ printk(KERN_INFO "SMP mode deactivated, forcing use of dummy APIC emulation.\n"); io_apic_irqs = 0; cpu_online_map = cpumask_of_cpu(0); - phys_cpu_present_map = cpumask_of_cpu(0); + phys_cpu_present_map = physid_mask_of_physid(0); disable_apic = 1; goto smp_done; } @@ -803,7 +803,7 @@ /* * Now scan the CPU present map and fire up the other CPUs. */ - Dprintk("CPU present map: %lx\n", phys_cpu_present_map); + Dprintk("CPU present map: %lx\n", physids_coerce(phys_cpu_present_map)); for (apicid = 0; apicid < NR_CPUS; apicid++) { /* diff -Nru a/arch/x86_64/kernel/time.c b/arch/x86_64/kernel/time.c --- a/arch/x86_64/kernel/time.c Tue Sep 2 19:58:17 2003 +++ b/arch/x86_64/kernel/time.c Tue Sep 2 19:58:17 2003 @@ -79,6 +79,7 @@ unsigned long t; unsigned long x; rdtscll_sync(&t); + if (t < vxtime.last_tsc) t = vxtime.last_tsc; /* hack */ x = ((t - vxtime.last_tsc) * vxtime.tsc_quot) >> 32; return x; } diff -Nru a/arch/x86_64/kernel/vsyscall.c b/arch/x86_64/kernel/vsyscall.c --- a/arch/x86_64/kernel/vsyscall.c Tue Sep 2 19:58:18 2003 +++ b/arch/x86_64/kernel/vsyscall.c Tue Sep 2 19:58:18 2003 @@ -85,6 +85,7 @@ if (__vxtime.mode == VXTIME_TSC) { sync_core(); rdtscll(t); + if (t < __vxtime.last_tsc) t = __vxtime.last_tsc; usec += ((t - __vxtime.last_tsc) * __vxtime.tsc_quot) >> 32; } else { diff -Nru a/drivers/Makefile b/drivers/Makefile --- a/drivers/Makefile Tue Sep 2 19:58:18 2003 +++ b/drivers/Makefile Tue Sep 2 19:58:18 2003 @@ -20,6 +20,7 @@ obj-y += base/ block/ misc/ net/ media/ obj-$(CONFIG_NUBUS) += nubus/ obj-$(CONFIG_ATM) += atm/ +obj-$(CONFIG_PPC_PMAC) += macintosh/ obj-$(CONFIG_IDE) += ide/ obj-$(CONFIG_FC4) += fc4/ obj-$(CONFIG_SCSI) += scsi/ @@ -31,7 +32,6 @@ obj-$(CONFIG_DIO) += dio/ obj-$(CONFIG_SBUS) += sbus/ obj-$(CONFIG_ZORRO) += zorro/ -obj-$(CONFIG_PPC_PMAC) += macintosh/ obj-$(CONFIG_MAC) += macintosh/ obj-$(CONFIG_PARIDE) += block/paride/ obj-$(CONFIG_TC) += tc/ diff -Nru a/drivers/acorn/block/fd1772.c b/drivers/acorn/block/fd1772.c --- a/drivers/acorn/block/fd1772.c Tue Sep 2 19:58:15 2003 +++ b/drivers/acorn/block/fd1772.c Tue Sep 2 19:58:15 2003 @@ -1455,8 +1455,8 @@ static int floppy_open(struct inode *inode, struct file *filp) { - int drive = minor(inode->i_rdev) & 3; - int type = minor(inode->i_rdev) >> 2; + int drive = iminor(inode) & 3; + int type = iminor(inode) >> 2; int old_dev = fd_device[drive]; if (fd_ref[drive] && old_dev != type) @@ -1490,7 +1490,7 @@ static int floppy_release(struct inode *inode, struct file *filp) { - int drive = minor(inode->i_rdev) & 3; + int drive = iminor(inode) & 3; if (fd_ref[drive] < 0) fd_ref[drive] = 0; diff -Nru a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig --- a/drivers/acpi/Kconfig Tue Sep 2 19:58:20 2003 +++ b/drivers/acpi/Kconfig Tue Sep 2 19:58:20 2003 @@ -69,6 +69,7 @@ bool "Sleep States (EXPERIMENTAL)" depends on X86 && ACPI depends on EXPERIMENTAL && PM + select SOFTWARE_SUSPEND default y ---help--- This option adds support for ACPI suspend states. diff -Nru a/drivers/acpi/pci_link.c b/drivers/acpi/pci_link.c --- a/drivers/acpi/pci_link.c Tue Sep 2 19:58:13 2003 +++ b/drivers/acpi/pci_link.c Tue Sep 2 19:58:13 2003 @@ -516,9 +516,8 @@ return_VALUE(0); } - if (acpi_pci_link_allocate(link)) { - return -ENODEV; - } + if (acpi_pci_link_allocate(link)) + return_VALUE(0); if (!link->irq.active) { ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Link disabled\n")); diff -Nru a/drivers/atm/Kconfig b/drivers/atm/Kconfig --- a/drivers/atm/Kconfig Tue Sep 2 19:58:15 2003 +++ b/drivers/atm/Kconfig Tue Sep 2 19:58:15 2003 @@ -241,7 +241,7 @@ config ATM_AMBASSADOR tristate "Madge Ambassador (Collage PCI 155 Server)" - depends on PCI && ATM + depends on PCI && ATM && BROKEN_ON_SMP help This is a driver for ATMizer based ATM card produced by Madge Networks Ltd. Say Y (or M to compile as a module named ambassador) diff -Nru a/drivers/atm/ambassador.c b/drivers/atm/ambassador.c --- a/drivers/atm/ambassador.c Tue Sep 2 19:58:13 2003 +++ b/drivers/atm/ambassador.c Tue Sep 2 19:58:13 2003 @@ -310,10 +310,11 @@ 0xdeadbeef }; +static void do_housekeeping (unsigned long arg); /********** globals **********/ static amb_dev * amb_devs = NULL; -static struct timer_list housekeeping; +static struct timer_list housekeeping = TIMER_INITIALIZER(do_housekeeping, 0, 1); static unsigned short debug = 0; static unsigned int cmds = 8; @@ -937,63 +938,6 @@ return IRQ_HANDLED; } -/********** don't panic... yeah, right **********/ - -#ifdef DEBUG_AMBASSADOR -static void dont_panic (amb_dev * dev) { - amb_cq * cq = &dev->cq; - volatile amb_cq_ptrs * ptrs = &cq->ptrs; - amb_txq * txq; - amb_rxq * rxq; - command * cmd; - tx_in * tx; - tx_simple * tx_descr; - unsigned char pool; - rx_in * rx; - - unsigned long flags; - save_flags (flags); - cli(); - - PRINTK (KERN_INFO, "don't panic - putting adapter into reset"); - wr_plain (dev, offsetof(amb_mem, reset_control), - rd_plain (dev, offsetof(amb_mem, reset_control)) | AMB_RESET_BITS); - - PRINTK (KERN_INFO, "marking all commands complete"); - for (cmd = ptrs->start; cmd < ptrs->limit; ++cmd) - cmd->request = cpu_to_be32 (SRB_COMPLETE); - - PRINTK (KERN_INFO, "completing all TXs"); - txq = &dev->txq; - tx = txq->in.ptr; - while (txq->pending--) { - if (tx == txq->in.start) - tx = txq->in.limit; - --tx; - tx_descr = bus_to_virt (be32_to_cpu (tx->tx_descr_addr)); - amb_kfree_skb (tx_descr->skb); - kfree (tx_descr); - } - - PRINTK (KERN_INFO, "freeing all RX buffers"); - for (pool = 0; pool < NUM_RX_POOLS; ++pool) { - rxq = &dev->rxq[pool]; - rx = rxq->in.ptr; - while (rxq->pending--) { - if (rx == rxq->in.start) - rx = rxq->in.limit; - --rx; - dev_kfree_skb_any (bus_to_virt (rx->handle)); - } - } - - PRINTK (KERN_INFO, "don't panic over - close all VCs and rmmod"); - set_bit (dead, &dev->flags); - restore_flags (flags); - return; -} -#endif - /********** make rate (not quite as much fun as Horizon) **********/ static unsigned int make_rate (unsigned int rate, rounding r, @@ -1420,32 +1364,6 @@ return; } -/********** DebugIoctl **********/ - -#if 0 -static int amb_ioctl (struct atm_dev * dev, unsigned int cmd, void * arg) { - unsigned short newdebug; - if (cmd == AMB_SETDEBUG) { - if (!capable(CAP_NET_ADMIN)) - return -EPERM; - if (copy_from_user (&newdebug, arg, sizeof(newdebug))) { - // moan - return -EFAULT; - } else { - debug = newdebug; - return 0; - } - } else if (cmd == AMB_DONTPANIC) { - if (!capable(CAP_NET_ADMIN)) - return -EPERM; - dont_panic (dev); - } else { - // moan - return -ENOIOCTLCMD; - } -} -#endif - /********** Set socket options for a VC **********/ // int amb_getsockopt (struct atm_vcc * atm_vcc, int level, int optname, void * optval, int optlen); @@ -1524,33 +1442,6 @@ tx.tx_descr_length = cpu_to_be16 (sizeof(tx_frag)+sizeof(tx_frag_end)); tx.tx_descr_addr = cpu_to_be32 (virt_to_bus (&tx_descr->tx_frag)); -#ifdef DEBUG_AMBASSADOR - /* wey-hey! */ - if (vc == 1023) { - unsigned int i; - unsigned short d = 0; - char * s = skb->data; - switch (*s++) { - case 'D': { - for (i = 0; i < 4; ++i) { - d = (d<<4) | ((*s <= '9') ? (*s - '0') : (*s - 'a' + 10)); - ++s; - } - PRINTK (KERN_INFO, "debug bitmap is now %hx", debug = d); - break; - } - case 'R': { - if (*s++ == 'e' && *s++ == 's' && *s++ == 'e' && *s++ == 't') - dont_panic (dev); - break; - } - default: { - break; - } - } - } -#endif - while (tx_give (dev, &tx)) schedule(); return 0; @@ -1663,21 +1554,14 @@ /********** Operation Structure **********/ static const struct atmdev_ops amb_ops = { - .open = amb_open, + .open = amb_open, .close = amb_close, - .send = amb_send, + .send = amb_send, .proc_read = amb_proc_read, .owner = THIS_MODULE, }; /********** housekeeping **********/ - -static inline void set_timer (struct timer_list * timer, unsigned long delay) { - timer->expires = jiffies + delay; - add_timer (timer); - return; -} - static void do_housekeeping (unsigned long arg) { amb_dev * dev = amb_devs; // data is set to zero at module unload @@ -1693,7 +1577,7 @@ dev = dev->prev; } - set_timer (&housekeeping, 10*HZ); + mod_timer(&housekeeping, jiffies + 10*HZ); } return; @@ -2579,11 +2463,7 @@ devs = amb_probe(); if (devs) { - init_timer (&housekeeping); - housekeeping.function = do_housekeeping; - // paranoia - housekeeping.data = 1; - set_timer (&housekeeping, 0); + mod_timer (&housekeeping, jiffies); } else { PRINTK (KERN_INFO, "no (usable) adapters found"); } @@ -2600,7 +2480,7 @@ // paranoia housekeeping.data = 0; - del_timer (&housekeeping); + del_timer_sync(&housekeeping); while (amb_devs) { dev = amb_devs; diff -Nru a/drivers/atm/eni.c b/drivers/atm/eni.c --- a/drivers/atm/eni.c Tue Sep 2 19:58:14 2003 +++ b/drivers/atm/eni.c Tue Sep 2 19:58:14 2003 @@ -1809,10 +1809,6 @@ "master (0x%02x)\n",dev->number,error); return error; } -#ifdef __sparc_v9__ /* copied from drivers/net/sunhme.c */ - /* NOTE: Cache line size is in 32-bit word units. */ - pci_write_config_byte(eni_dev->pci_dev, PCI_CACHE_LINE_SIZE, 0x10); -#endif if ((error = pci_write_config_byte(eni_dev->pci_dev,PCI_TONGA_CTRL, END_SWAP_DMA))) { printk(KERN_ERR DEV_LABEL "(itf %d): can't set endian swap " @@ -2345,7 +2341,7 @@ struct sk_buff *skb; /* dummy for sizeof */ if (sizeof(skb->cb) < sizeof(struct eni_skb_prv)) { - printk(KERN_ERR "eni_detect: skb->cb is too small (%d < %d)\n", + printk(KERN_ERR "eni_detect: skb->cb is too small (%Zd < %Zd)\n", sizeof(skb->cb),sizeof(struct eni_skb_prv)); return -EIO; } diff -Nru a/drivers/atm/firestream.c b/drivers/atm/firestream.c --- a/drivers/atm/firestream.c Tue Sep 2 19:58:13 2003 +++ b/drivers/atm/firestream.c Tue Sep 2 19:58:13 2003 @@ -895,7 +895,7 @@ /* XXX handle qos parameters (rate limiting) ? */ vcc = kmalloc(sizeof(struct fs_vcc), GFP_KERNEL); - fs_dprintk (FS_DEBUG_ALLOC, "Alloc VCC: %p(%d)\n", vcc, sizeof(struct fs_vcc)); + fs_dprintk (FS_DEBUG_ALLOC, "Alloc VCC: %p(%Zd)\n", vcc, sizeof(struct fs_vcc)); if (!vcc) { clear_bit(ATM_VF_ADDR, &atm_vcc->flags); return -ENOMEM; @@ -946,7 +946,7 @@ if (DO_DIRECTION (txtp)) { tc = kmalloc (sizeof (struct fs_transmit_config), GFP_KERNEL); - fs_dprintk (FS_DEBUG_ALLOC, "Alloc tc: %p(%d)\n", + fs_dprintk (FS_DEBUG_ALLOC, "Alloc tc: %p(%Zd)\n", tc, sizeof (struct fs_transmit_config)); if (!tc) { fs_dprintk (FS_DEBUG_OPEN, "fs: can't alloc transmit_config.\n"); @@ -1180,7 +1180,7 @@ vcc->last_skb = skb; td = kmalloc (sizeof (struct FS_BPENTRY), GFP_ATOMIC); - fs_dprintk (FS_DEBUG_ALLOC, "Alloc transd: %p(%d)\n", td, sizeof (struct FS_BPENTRY)); + fs_dprintk (FS_DEBUG_ALLOC, "Alloc transd: %p(%Zd)\n", td, sizeof (struct FS_BPENTRY)); if (!td) { /* Oops out of mem */ return -ENOMEM; @@ -1487,7 +1487,7 @@ fs_dprintk (FS_DEBUG_ALLOC, "Alloc rec-skb: %p(%d)\n", skb, fp->bufsize); if (!skb) break; ne = kmalloc (sizeof (struct FS_BPENTRY), gfp_flags); - fs_dprintk (FS_DEBUG_ALLOC, "Alloc rec-d: %p(%d)\n", ne, sizeof (struct FS_BPENTRY)); + fs_dprintk (FS_DEBUG_ALLOC, "Alloc rec-d: %p(%Zd)\n", ne, sizeof (struct FS_BPENTRY)); if (!ne) { fs_dprintk (FS_DEBUG_ALLOC, "Free rec-skb: %p\n", skb); dev_kfree_skb_any (skb); @@ -1792,7 +1792,7 @@ } dev->atm_vccs = kmalloc (dev->nchannels * sizeof (struct atm_vcc *), GFP_KERNEL); - fs_dprintk (FS_DEBUG_ALLOC, "Alloc atmvccs: %p(%d)\n", + fs_dprintk (FS_DEBUG_ALLOC, "Alloc atmvccs: %p(%Zd)\n", dev->atm_vccs, dev->nchannels * sizeof (struct atm_vcc *)); if (!dev->atm_vccs) { @@ -1900,7 +1900,7 @@ goto err_out; fs_dev = kmalloc (sizeof (struct fs_dev), GFP_KERNEL); - fs_dprintk (FS_DEBUG_ALLOC, "Alloc fs-dev: %p(%d)\n", + fs_dprintk (FS_DEBUG_ALLOC, "Alloc fs-dev: %p(%Zd)\n", fs_dev, sizeof (struct fs_dev)); if (!fs_dev) goto err_out; diff -Nru a/drivers/block/DAC960.c b/drivers/block/DAC960.c --- a/drivers/block/DAC960.c Tue Sep 2 19:58:18 2003 +++ b/drivers/block/DAC960.c Tue Sep 2 19:58:18 2003 @@ -23,6 +23,7 @@ #include #include #include +#include #include #include #include @@ -44,6 +45,8 @@ #include #include "DAC960.h" +#define DAC960_GAM_MINOR 252 + static DAC960_Controller_T *DAC960_Controllers[DAC960_MaxControllers]; static int DAC960_ControllerCount; @@ -71,10 +74,6 @@ DAC960_Controller_T *p = disk->queue->queuedata; int drive_nr = (int)disk->private_data; - /* bad hack for the "user" ioctls */ - if (!p->ControllerNumber && !drive_nr && (file->f_flags & O_NONBLOCK)) - return 0; - if (p->FirmwareType == DAC960_V1_Controller) { if (p->V1.LogicalDriveInformation[drive_nr]. LogicalDriveState == DAC960_V1_LogicalDrive_Offline) @@ -101,9 +100,6 @@ int drive_nr = (int)disk->private_data; struct hd_geometry g, *loc = (struct hd_geometry *)arg; - if (file && (file->f_flags & O_NONBLOCK)) - return DAC960_UserIOCTL(inode, file, cmd, arg); - if (cmd != HDIO_GETGEO || !loc) return -EINVAL; @@ -5569,407 +5565,6 @@ } /* - DAC960_UserIOCTL is the User IOCTL Function for the DAC960 Driver. -*/ - -static int DAC960_UserIOCTL(struct inode *inode, struct file *file, - unsigned int Request, unsigned long Argument) -{ - int ErrorCode = 0; - if (!capable(CAP_SYS_ADMIN)) return -EACCES; - switch (Request) - { - case DAC960_IOCTL_GET_CONTROLLER_COUNT: - return DAC960_ControllerCount; - case DAC960_IOCTL_GET_CONTROLLER_INFO: - { - DAC960_ControllerInfo_T *UserSpaceControllerInfo = - (DAC960_ControllerInfo_T *) Argument; - DAC960_ControllerInfo_T ControllerInfo; - DAC960_Controller_T *Controller; - int ControllerNumber; - if (UserSpaceControllerInfo == NULL) return -EINVAL; - ErrorCode = get_user(ControllerNumber, - &UserSpaceControllerInfo->ControllerNumber); - if (ErrorCode != 0) return ErrorCode; - if (ControllerNumber < 0 || - ControllerNumber > DAC960_ControllerCount - 1) - return -ENXIO; - Controller = DAC960_Controllers[ControllerNumber]; - if (Controller == NULL) return -ENXIO; - memset(&ControllerInfo, 0, sizeof(DAC960_ControllerInfo_T)); - ControllerInfo.ControllerNumber = ControllerNumber; - ControllerInfo.FirmwareType = Controller->FirmwareType; - ControllerInfo.Channels = Controller->Channels; - ControllerInfo.Targets = Controller->Targets; - ControllerInfo.PCI_Bus = Controller->Bus; - ControllerInfo.PCI_Device = Controller->Device; - ControllerInfo.PCI_Function = Controller->Function; - ControllerInfo.IRQ_Channel = Controller->IRQ_Channel; - ControllerInfo.PCI_Address = Controller->PCI_Address; - strcpy(ControllerInfo.ModelName, Controller->ModelName); - strcpy(ControllerInfo.FirmwareVersion, Controller->FirmwareVersion); - return (copy_to_user(UserSpaceControllerInfo, &ControllerInfo, - sizeof(DAC960_ControllerInfo_T)) ? -EFAULT : 0); - } - case DAC960_IOCTL_V1_EXECUTE_COMMAND: - { - DAC960_V1_UserCommand_T *UserSpaceUserCommand = - (DAC960_V1_UserCommand_T *) Argument; - DAC960_V1_UserCommand_T UserCommand; - DAC960_Controller_T *Controller; - DAC960_Command_T *Command = NULL; - DAC960_V1_CommandOpcode_T CommandOpcode; - DAC960_V1_CommandStatus_T CommandStatus; - DAC960_V1_DCDB_T DCDB; - DAC960_V1_DCDB_T *DCDB_IOBUF = NULL; - dma_addr_t DCDB_IOBUFDMA; - unsigned long flags; - int ControllerNumber, DataTransferLength; - unsigned char *DataTransferBuffer = NULL; - dma_addr_t DataTransferBufferDMA; - if (UserSpaceUserCommand == NULL) return -EINVAL; - if (copy_from_user(&UserCommand, UserSpaceUserCommand, - sizeof(DAC960_V1_UserCommand_T))) { - ErrorCode = -EFAULT; - goto Failure1a; - } - ControllerNumber = UserCommand.ControllerNumber; - if (ControllerNumber < 0 || - ControllerNumber > DAC960_ControllerCount - 1) - return -ENXIO; - Controller = DAC960_Controllers[ControllerNumber]; - if (Controller == NULL) return -ENXIO; - if (Controller->FirmwareType != DAC960_V1_Controller) return -EINVAL; - CommandOpcode = UserCommand.CommandMailbox.Common.CommandOpcode; - DataTransferLength = UserCommand.DataTransferLength; - if (CommandOpcode & 0x80) return -EINVAL; - if (CommandOpcode == DAC960_V1_DCDB) - { - if (copy_from_user(&DCDB, UserCommand.DCDB, - sizeof(DAC960_V1_DCDB_T))) { - ErrorCode = -EFAULT; - goto Failure1a; - } - if (DCDB.Channel >= DAC960_V1_MaxChannels) return -EINVAL; - if (!((DataTransferLength == 0 && - DCDB.Direction - == DAC960_V1_DCDB_NoDataTransfer) || - (DataTransferLength > 0 && - DCDB.Direction - == DAC960_V1_DCDB_DataTransferDeviceToSystem) || - (DataTransferLength < 0 && - DCDB.Direction - == DAC960_V1_DCDB_DataTransferSystemToDevice))) - return -EINVAL; - if (((DCDB.TransferLengthHigh4 << 16) | DCDB.TransferLength) - != abs(DataTransferLength)) - return -EINVAL; - DCDB_IOBUF = pci_alloc_consistent(Controller->PCIDevice, - sizeof(DAC960_V1_DCDB_T), &DCDB_IOBUFDMA); - if (DCDB_IOBUF == NULL) - return -ENOMEM; - } - if (DataTransferLength > 0) - { - DataTransferBuffer = pci_alloc_consistent(Controller->PCIDevice, - DataTransferLength, &DataTransferBufferDMA); - if (DataTransferBuffer == NULL) { - ErrorCode = -ENOMEM; - goto Failure1; - } - memset(DataTransferBuffer, 0, DataTransferLength); - } - else if (DataTransferLength < 0) - { - DataTransferBuffer = pci_alloc_consistent(Controller->PCIDevice, - -DataTransferLength, &DataTransferBufferDMA); - if (DataTransferBuffer == NULL) { - ErrorCode = -ENOMEM; - goto Failure1; - } - if (copy_from_user(DataTransferBuffer, - UserCommand.DataTransferBuffer, - -DataTransferLength)) { - ErrorCode = -EFAULT; - goto Failure1; - } - } - if (CommandOpcode == DAC960_V1_DCDB) - { - spin_lock_irqsave(&Controller->queue_lock, flags); - while ((Command = DAC960_AllocateCommand(Controller)) == NULL) - DAC960_WaitForCommand(Controller); - while (Controller->V1.DirectCommandActive[DCDB.Channel] - [DCDB.TargetID]) - { - spin_unlock_irq(&Controller->queue_lock); - __wait_event(Controller->CommandWaitQueue, - !Controller->V1.DirectCommandActive - [DCDB.Channel][DCDB.TargetID]); - spin_lock_irq(&Controller->queue_lock); - } - Controller->V1.DirectCommandActive[DCDB.Channel] - [DCDB.TargetID] = true; - spin_unlock_irqrestore(&Controller->queue_lock, flags); - DAC960_V1_ClearCommand(Command); - Command->CommandType = DAC960_ImmediateCommand; - memcpy(&Command->V1.CommandMailbox, &UserCommand.CommandMailbox, - sizeof(DAC960_V1_CommandMailbox_T)); - Command->V1.CommandMailbox.Type3.BusAddress = DCDB_IOBUFDMA; - DCDB.BusAddress = DataTransferBufferDMA; - memcpy(DCDB_IOBUF, &DCDB, sizeof(DAC960_V1_DCDB_T)); - } - else - { - spin_lock_irqsave(&Controller->queue_lock, flags); - while ((Command = DAC960_AllocateCommand(Controller)) == NULL) - DAC960_WaitForCommand(Controller); - spin_unlock_irqrestore(&Controller->queue_lock, flags); - DAC960_V1_ClearCommand(Command); - Command->CommandType = DAC960_ImmediateCommand; - memcpy(&Command->V1.CommandMailbox, &UserCommand.CommandMailbox, - sizeof(DAC960_V1_CommandMailbox_T)); - if (DataTransferBuffer != NULL) - Command->V1.CommandMailbox.Type3.BusAddress = - DataTransferBufferDMA; - } - DAC960_ExecuteCommand(Command); - CommandStatus = Command->V1.CommandStatus; - spin_lock_irqsave(&Controller->queue_lock, flags); - DAC960_DeallocateCommand(Command); - spin_unlock_irqrestore(&Controller->queue_lock, flags); - if (DataTransferLength > 0) - { - if (copy_to_user(UserCommand.DataTransferBuffer, - DataTransferBuffer, DataTransferLength)) { - ErrorCode = -EFAULT; - goto Failure1; - } - } - if (CommandOpcode == DAC960_V1_DCDB) - { - /* - I don't believe Target or Channel in the DCDB_IOBUF - should be any different from the contents of DCDB. - */ - Controller->V1.DirectCommandActive[DCDB.Channel] - [DCDB.TargetID] = false; - if (copy_to_user(UserCommand.DCDB, DCDB_IOBUF, - sizeof(DAC960_V1_DCDB_T))) { - ErrorCode = -EFAULT; - goto Failure1; - } - } - ErrorCode = CommandStatus; - Failure1: - if (DataTransferBuffer != NULL) - pci_free_consistent(Controller->PCIDevice, abs(DataTransferLength), - DataTransferBuffer, DataTransferBufferDMA); - if (DCDB_IOBUF != NULL) - pci_free_consistent(Controller->PCIDevice, sizeof(DAC960_V1_DCDB_T), - DCDB_IOBUF, DCDB_IOBUFDMA); - Failure1a: - return ErrorCode; - } - case DAC960_IOCTL_V2_EXECUTE_COMMAND: - { - DAC960_V2_UserCommand_T *UserSpaceUserCommand = - (DAC960_V2_UserCommand_T *) Argument; - DAC960_V2_UserCommand_T UserCommand; - DAC960_Controller_T *Controller; - DAC960_Command_T *Command = NULL; - DAC960_V2_CommandMailbox_T *CommandMailbox; - DAC960_V2_CommandStatus_T CommandStatus; - unsigned long flags; - int ControllerNumber, DataTransferLength; - int DataTransferResidue, RequestSenseLength; - unsigned char *DataTransferBuffer = NULL; - dma_addr_t DataTransferBufferDMA; - unsigned char *RequestSenseBuffer = NULL; - dma_addr_t RequestSenseBufferDMA; - if (UserSpaceUserCommand == NULL) return -EINVAL; - if (copy_from_user(&UserCommand, UserSpaceUserCommand, - sizeof(DAC960_V2_UserCommand_T))) { - ErrorCode = -EFAULT; - goto Failure2a; - } - ControllerNumber = UserCommand.ControllerNumber; - if (ControllerNumber < 0 || - ControllerNumber > DAC960_ControllerCount - 1) - return -ENXIO; - Controller = DAC960_Controllers[ControllerNumber]; - if (Controller == NULL) return -ENXIO; - if (Controller->FirmwareType != DAC960_V2_Controller) return -EINVAL; - DataTransferLength = UserCommand.DataTransferLength; - if (DataTransferLength > 0) - { - DataTransferBuffer = pci_alloc_consistent(Controller->PCIDevice, - DataTransferLength, &DataTransferBufferDMA); - if (DataTransferBuffer == NULL) return -ENOMEM; - memset(DataTransferBuffer, 0, DataTransferLength); - } - else if (DataTransferLength < 0) - { - DataTransferBuffer = pci_alloc_consistent(Controller->PCIDevice, - -DataTransferLength, &DataTransferBufferDMA); - if (DataTransferBuffer == NULL) return -ENOMEM; - if (copy_from_user(DataTransferBuffer, - UserCommand.DataTransferBuffer, - -DataTransferLength)) { - ErrorCode = -EFAULT; - goto Failure2; - } - } - RequestSenseLength = UserCommand.RequestSenseLength; - if (RequestSenseLength > 0) - { - RequestSenseBuffer = pci_alloc_consistent(Controller->PCIDevice, - RequestSenseLength, &RequestSenseBufferDMA); - if (RequestSenseBuffer == NULL) - { - ErrorCode = -ENOMEM; - goto Failure2; - } - memset(RequestSenseBuffer, 0, RequestSenseLength); - } - spin_lock_irqsave(&Controller->queue_lock, flags); - while ((Command = DAC960_AllocateCommand(Controller)) == NULL) - DAC960_WaitForCommand(Controller); - spin_unlock_irqrestore(&Controller->queue_lock, flags); - DAC960_V2_ClearCommand(Command); - Command->CommandType = DAC960_ImmediateCommand; - CommandMailbox = &Command->V2.CommandMailbox; - memcpy(CommandMailbox, &UserCommand.CommandMailbox, - sizeof(DAC960_V2_CommandMailbox_T)); - CommandMailbox->Common.CommandControlBits - .AdditionalScatterGatherListMemory = false; - CommandMailbox->Common.CommandControlBits - .NoAutoRequestSense = true; - CommandMailbox->Common.DataTransferSize = 0; - CommandMailbox->Common.DataTransferPageNumber = 0; - memset(&CommandMailbox->Common.DataTransferMemoryAddress, 0, - sizeof(DAC960_V2_DataTransferMemoryAddress_T)); - if (DataTransferLength != 0) - { - if (DataTransferLength > 0) - { - CommandMailbox->Common.CommandControlBits - .DataTransferControllerToHost = true; - CommandMailbox->Common.DataTransferSize = DataTransferLength; - } - else - { - CommandMailbox->Common.CommandControlBits - .DataTransferControllerToHost = false; - CommandMailbox->Common.DataTransferSize = -DataTransferLength; - } - CommandMailbox->Common.DataTransferMemoryAddress - .ScatterGatherSegments[0] - .SegmentDataPointer = DataTransferBufferDMA; - CommandMailbox->Common.DataTransferMemoryAddress - .ScatterGatherSegments[0] - .SegmentByteCount = - CommandMailbox->Common.DataTransferSize; - } - if (RequestSenseLength > 0) - { - CommandMailbox->Common.CommandControlBits - .NoAutoRequestSense = false; - CommandMailbox->Common.RequestSenseSize = RequestSenseLength; - CommandMailbox->Common.RequestSenseBusAddress = - RequestSenseBufferDMA; - } - DAC960_ExecuteCommand(Command); - CommandStatus = Command->V2.CommandStatus; - RequestSenseLength = Command->V2.RequestSenseLength; - DataTransferResidue = Command->V2.DataTransferResidue; - spin_lock_irqsave(&Controller->queue_lock, flags); - DAC960_DeallocateCommand(Command); - spin_unlock_irqrestore(&Controller->queue_lock, flags); - if (RequestSenseLength > UserCommand.RequestSenseLength) - RequestSenseLength = UserCommand.RequestSenseLength; - if (copy_to_user(&UserSpaceUserCommand->DataTransferLength, - &DataTransferResidue, - sizeof(DataTransferResidue))) { - ErrorCode = -EFAULT; - goto Failure2; - } - if (copy_to_user(&UserSpaceUserCommand->RequestSenseLength, - &RequestSenseLength, sizeof(RequestSenseLength))) { - ErrorCode = -EFAULT; - goto Failure2; - } - if (DataTransferLength > 0) - { - if (copy_to_user(UserCommand.DataTransferBuffer, - DataTransferBuffer, DataTransferLength)) { - ErrorCode = -EFAULT; - goto Failure2; - } - } - if (RequestSenseLength > 0) - { - if (copy_to_user(UserCommand.RequestSenseBuffer, - RequestSenseBuffer, RequestSenseLength)) { - ErrorCode = -EFAULT; - goto Failure2; - } - } - ErrorCode = CommandStatus; - Failure2: - pci_free_consistent(Controller->PCIDevice, abs(DataTransferLength), - DataTransferBuffer, DataTransferBufferDMA); - if (RequestSenseBuffer != NULL) - pci_free_consistent(Controller->PCIDevice, RequestSenseLength, - RequestSenseBuffer, RequestSenseBufferDMA); - Failure2a: - return ErrorCode; - } - case DAC960_IOCTL_V2_GET_HEALTH_STATUS: - { - DAC960_V2_GetHealthStatus_T *UserSpaceGetHealthStatus = - (DAC960_V2_GetHealthStatus_T *) Argument; - DAC960_V2_GetHealthStatus_T GetHealthStatus; - DAC960_V2_HealthStatusBuffer_T HealthStatusBuffer; - DAC960_Controller_T *Controller; - int ControllerNumber; - if (UserSpaceGetHealthStatus == NULL) return -EINVAL; - if (copy_from_user(&GetHealthStatus, UserSpaceGetHealthStatus, - sizeof(DAC960_V2_GetHealthStatus_T))) - return -EFAULT; - ControllerNumber = GetHealthStatus.ControllerNumber; - if (ControllerNumber < 0 || - ControllerNumber > DAC960_ControllerCount - 1) - return -ENXIO; - Controller = DAC960_Controllers[ControllerNumber]; - if (Controller == NULL) return -ENXIO; - if (Controller->FirmwareType != DAC960_V2_Controller) return -EINVAL; - if (copy_from_user(&HealthStatusBuffer, - GetHealthStatus.HealthStatusBuffer, - sizeof(DAC960_V2_HealthStatusBuffer_T))) - return -EFAULT; - while (Controller->V2.HealthStatusBuffer->StatusChangeCounter - == HealthStatusBuffer.StatusChangeCounter && - Controller->V2.HealthStatusBuffer->NextEventSequenceNumber - == HealthStatusBuffer.NextEventSequenceNumber) - { - interruptible_sleep_on_timeout(&Controller->HealthStatusWaitQueue, - DAC960_MonitoringTimerInterval); - if (signal_pending(current)) return -EINTR; - } - if (copy_to_user(GetHealthStatus.HealthStatusBuffer, - Controller->V2.HealthStatusBuffer, - sizeof(DAC960_V2_HealthStatusBuffer_T))) - return -EFAULT; - return 0; - } - } - return -EINVAL; -} - - -/* DAC960_CheckStatusBuffer verifies that there is room to hold ByteCount additional bytes in the Combined Status Buffer and grows the buffer if necessary. It returns true if there is enough room and false otherwise. @@ -6901,6 +6496,436 @@ Controller->ControllerProcEntry = NULL; } +#ifdef DAC960_GAM_MINOR + +/* + * DAC960_gam_ioctl is the ioctl function for performing RAID operations. +*/ + +static int DAC960_gam_ioctl(struct inode *inode, struct file *file, + unsigned int Request, unsigned long Argument) +{ + int ErrorCode = 0; + if (!capable(CAP_SYS_ADMIN)) return -EACCES; + switch (Request) + { + case DAC960_IOCTL_GET_CONTROLLER_COUNT: + return DAC960_ControllerCount; + case DAC960_IOCTL_GET_CONTROLLER_INFO: + { + DAC960_ControllerInfo_T *UserSpaceControllerInfo = + (DAC960_ControllerInfo_T *) Argument; + DAC960_ControllerInfo_T ControllerInfo; + DAC960_Controller_T *Controller; + int ControllerNumber; + if (UserSpaceControllerInfo == NULL) return -EINVAL; + ErrorCode = get_user(ControllerNumber, + &UserSpaceControllerInfo->ControllerNumber); + if (ErrorCode != 0) return ErrorCode; + if (ControllerNumber < 0 || + ControllerNumber > DAC960_ControllerCount - 1) + return -ENXIO; + Controller = DAC960_Controllers[ControllerNumber]; + if (Controller == NULL) return -ENXIO; + memset(&ControllerInfo, 0, sizeof(DAC960_ControllerInfo_T)); + ControllerInfo.ControllerNumber = ControllerNumber; + ControllerInfo.FirmwareType = Controller->FirmwareType; + ControllerInfo.Channels = Controller->Channels; + ControllerInfo.Targets = Controller->Targets; + ControllerInfo.PCI_Bus = Controller->Bus; + ControllerInfo.PCI_Device = Controller->Device; + ControllerInfo.PCI_Function = Controller->Function; + ControllerInfo.IRQ_Channel = Controller->IRQ_Channel; + ControllerInfo.PCI_Address = Controller->PCI_Address; + strcpy(ControllerInfo.ModelName, Controller->ModelName); + strcpy(ControllerInfo.FirmwareVersion, Controller->FirmwareVersion); + return (copy_to_user(UserSpaceControllerInfo, &ControllerInfo, + sizeof(DAC960_ControllerInfo_T)) ? -EFAULT : 0); + } + case DAC960_IOCTL_V1_EXECUTE_COMMAND: + { + DAC960_V1_UserCommand_T *UserSpaceUserCommand = + (DAC960_V1_UserCommand_T *) Argument; + DAC960_V1_UserCommand_T UserCommand; + DAC960_Controller_T *Controller; + DAC960_Command_T *Command = NULL; + DAC960_V1_CommandOpcode_T CommandOpcode; + DAC960_V1_CommandStatus_T CommandStatus; + DAC960_V1_DCDB_T DCDB; + DAC960_V1_DCDB_T *DCDB_IOBUF = NULL; + dma_addr_t DCDB_IOBUFDMA; + unsigned long flags; + int ControllerNumber, DataTransferLength; + unsigned char *DataTransferBuffer = NULL; + dma_addr_t DataTransferBufferDMA; + if (UserSpaceUserCommand == NULL) return -EINVAL; + if (copy_from_user(&UserCommand, UserSpaceUserCommand, + sizeof(DAC960_V1_UserCommand_T))) { + ErrorCode = -EFAULT; + goto Failure1a; + } + ControllerNumber = UserCommand.ControllerNumber; + if (ControllerNumber < 0 || + ControllerNumber > DAC960_ControllerCount - 1) + return -ENXIO; + Controller = DAC960_Controllers[ControllerNumber]; + if (Controller == NULL) return -ENXIO; + if (Controller->FirmwareType != DAC960_V1_Controller) return -EINVAL; + CommandOpcode = UserCommand.CommandMailbox.Common.CommandOpcode; + DataTransferLength = UserCommand.DataTransferLength; + if (CommandOpcode & 0x80) return -EINVAL; + if (CommandOpcode == DAC960_V1_DCDB) + { + if (copy_from_user(&DCDB, UserCommand.DCDB, + sizeof(DAC960_V1_DCDB_T))) { + ErrorCode = -EFAULT; + goto Failure1a; + } + if (DCDB.Channel >= DAC960_V1_MaxChannels) return -EINVAL; + if (!((DataTransferLength == 0 && + DCDB.Direction + == DAC960_V1_DCDB_NoDataTransfer) || + (DataTransferLength > 0 && + DCDB.Direction + == DAC960_V1_DCDB_DataTransferDeviceToSystem) || + (DataTransferLength < 0 && + DCDB.Direction + == DAC960_V1_DCDB_DataTransferSystemToDevice))) + return -EINVAL; + if (((DCDB.TransferLengthHigh4 << 16) | DCDB.TransferLength) + != abs(DataTransferLength)) + return -EINVAL; + DCDB_IOBUF = pci_alloc_consistent(Controller->PCIDevice, + sizeof(DAC960_V1_DCDB_T), &DCDB_IOBUFDMA); + if (DCDB_IOBUF == NULL) + return -ENOMEM; + } + if (DataTransferLength > 0) + { + DataTransferBuffer = pci_alloc_consistent(Controller->PCIDevice, + DataTransferLength, &DataTransferBufferDMA); + if (DataTransferBuffer == NULL) { + ErrorCode = -ENOMEM; + goto Failure1; + } + memset(DataTransferBuffer, 0, DataTransferLength); + } + else if (DataTransferLength < 0) + { + DataTransferBuffer = pci_alloc_consistent(Controller->PCIDevice, + -DataTransferLength, &DataTransferBufferDMA); + if (DataTransferBuffer == NULL) { + ErrorCode = -ENOMEM; + goto Failure1; + } + if (copy_from_user(DataTransferBuffer, + UserCommand.DataTransferBuffer, + -DataTransferLength)) { + ErrorCode = -EFAULT; + goto Failure1; + } + } + if (CommandOpcode == DAC960_V1_DCDB) + { + spin_lock_irqsave(&Controller->queue_lock, flags); + while ((Command = DAC960_AllocateCommand(Controller)) == NULL) + DAC960_WaitForCommand(Controller); + while (Controller->V1.DirectCommandActive[DCDB.Channel] + [DCDB.TargetID]) + { + spin_unlock_irq(&Controller->queue_lock); + __wait_event(Controller->CommandWaitQueue, + !Controller->V1.DirectCommandActive + [DCDB.Channel][DCDB.TargetID]); + spin_lock_irq(&Controller->queue_lock); + } + Controller->V1.DirectCommandActive[DCDB.Channel] + [DCDB.TargetID] = true; + spin_unlock_irqrestore(&Controller->queue_lock, flags); + DAC960_V1_ClearCommand(Command); + Command->CommandType = DAC960_ImmediateCommand; + memcpy(&Command->V1.CommandMailbox, &UserCommand.CommandMailbox, + sizeof(DAC960_V1_CommandMailbox_T)); + Command->V1.CommandMailbox.Type3.BusAddress = DCDB_IOBUFDMA; + DCDB.BusAddress = DataTransferBufferDMA; + memcpy(DCDB_IOBUF, &DCDB, sizeof(DAC960_V1_DCDB_T)); + } + else + { + spin_lock_irqsave(&Controller->queue_lock, flags); + while ((Command = DAC960_AllocateCommand(Controller)) == NULL) + DAC960_WaitForCommand(Controller); + spin_unlock_irqrestore(&Controller->queue_lock, flags); + DAC960_V1_ClearCommand(Command); + Command->CommandType = DAC960_ImmediateCommand; + memcpy(&Command->V1.CommandMailbox, &UserCommand.CommandMailbox, + sizeof(DAC960_V1_CommandMailbox_T)); + if (DataTransferBuffer != NULL) + Command->V1.CommandMailbox.Type3.BusAddress = + DataTransferBufferDMA; + } + DAC960_ExecuteCommand(Command); + CommandStatus = Command->V1.CommandStatus; + spin_lock_irqsave(&Controller->queue_lock, flags); + DAC960_DeallocateCommand(Command); + spin_unlock_irqrestore(&Controller->queue_lock, flags); + if (DataTransferLength > 0) + { + if (copy_to_user(UserCommand.DataTransferBuffer, + DataTransferBuffer, DataTransferLength)) { + ErrorCode = -EFAULT; + goto Failure1; + } + } + if (CommandOpcode == DAC960_V1_DCDB) + { + /* + I don't believe Target or Channel in the DCDB_IOBUF + should be any different from the contents of DCDB. + */ + Controller->V1.DirectCommandActive[DCDB.Channel] + [DCDB.TargetID] = false; + if (copy_to_user(UserCommand.DCDB, DCDB_IOBUF, + sizeof(DAC960_V1_DCDB_T))) { + ErrorCode = -EFAULT; + goto Failure1; + } + } + ErrorCode = CommandStatus; + Failure1: + if (DataTransferBuffer != NULL) + pci_free_consistent(Controller->PCIDevice, abs(DataTransferLength), + DataTransferBuffer, DataTransferBufferDMA); + if (DCDB_IOBUF != NULL) + pci_free_consistent(Controller->PCIDevice, sizeof(DAC960_V1_DCDB_T), + DCDB_IOBUF, DCDB_IOBUFDMA); + Failure1a: + return ErrorCode; + } + case DAC960_IOCTL_V2_EXECUTE_COMMAND: + { + DAC960_V2_UserCommand_T *UserSpaceUserCommand = + (DAC960_V2_UserCommand_T *) Argument; + DAC960_V2_UserCommand_T UserCommand; + DAC960_Controller_T *Controller; + DAC960_Command_T *Command = NULL; + DAC960_V2_CommandMailbox_T *CommandMailbox; + DAC960_V2_CommandStatus_T CommandStatus; + unsigned long flags; + int ControllerNumber, DataTransferLength; + int DataTransferResidue, RequestSenseLength; + unsigned char *DataTransferBuffer = NULL; + dma_addr_t DataTransferBufferDMA; + unsigned char *RequestSenseBuffer = NULL; + dma_addr_t RequestSenseBufferDMA; + if (UserSpaceUserCommand == NULL) return -EINVAL; + if (copy_from_user(&UserCommand, UserSpaceUserCommand, + sizeof(DAC960_V2_UserCommand_T))) { + ErrorCode = -EFAULT; + goto Failure2a; + } + ControllerNumber = UserCommand.ControllerNumber; + if (ControllerNumber < 0 || + ControllerNumber > DAC960_ControllerCount - 1) + return -ENXIO; + Controller = DAC960_Controllers[ControllerNumber]; + if (Controller == NULL) return -ENXIO; + if (Controller->FirmwareType != DAC960_V2_Controller) return -EINVAL; + DataTransferLength = UserCommand.DataTransferLength; + if (DataTransferLength > 0) + { + DataTransferBuffer = pci_alloc_consistent(Controller->PCIDevice, + DataTransferLength, &DataTransferBufferDMA); + if (DataTransferBuffer == NULL) return -ENOMEM; + memset(DataTransferBuffer, 0, DataTransferLength); + } + else if (DataTransferLength < 0) + { + DataTransferBuffer = pci_alloc_consistent(Controller->PCIDevice, + -DataTransferLength, &DataTransferBufferDMA); + if (DataTransferBuffer == NULL) return -ENOMEM; + if (copy_from_user(DataTransferBuffer, + UserCommand.DataTransferBuffer, + -DataTransferLength)) { + ErrorCode = -EFAULT; + goto Failure2; + } + } + RequestSenseLength = UserCommand.RequestSenseLength; + if (RequestSenseLength > 0) + { + RequestSenseBuffer = pci_alloc_consistent(Controller->PCIDevice, + RequestSenseLength, &RequestSenseBufferDMA); + if (RequestSenseBuffer == NULL) + { + ErrorCode = -ENOMEM; + goto Failure2; + } + memset(RequestSenseBuffer, 0, RequestSenseLength); + } + spin_lock_irqsave(&Controller->queue_lock, flags); + while ((Command = DAC960_AllocateCommand(Controller)) == NULL) + DAC960_WaitForCommand(Controller); + spin_unlock_irqrestore(&Controller->queue_lock, flags); + DAC960_V2_ClearCommand(Command); + Command->CommandType = DAC960_ImmediateCommand; + CommandMailbox = &Command->V2.CommandMailbox; + memcpy(CommandMailbox, &UserCommand.CommandMailbox, + sizeof(DAC960_V2_CommandMailbox_T)); + CommandMailbox->Common.CommandControlBits + .AdditionalScatterGatherListMemory = false; + CommandMailbox->Common.CommandControlBits + .NoAutoRequestSense = true; + CommandMailbox->Common.DataTransferSize = 0; + CommandMailbox->Common.DataTransferPageNumber = 0; + memset(&CommandMailbox->Common.DataTransferMemoryAddress, 0, + sizeof(DAC960_V2_DataTransferMemoryAddress_T)); + if (DataTransferLength != 0) + { + if (DataTransferLength > 0) + { + CommandMailbox->Common.CommandControlBits + .DataTransferControllerToHost = true; + CommandMailbox->Common.DataTransferSize = DataTransferLength; + } + else + { + CommandMailbox->Common.CommandControlBits + .DataTransferControllerToHost = false; + CommandMailbox->Common.DataTransferSize = -DataTransferLength; + } + CommandMailbox->Common.DataTransferMemoryAddress + .ScatterGatherSegments[0] + .SegmentDataPointer = DataTransferBufferDMA; + CommandMailbox->Common.DataTransferMemoryAddress + .ScatterGatherSegments[0] + .SegmentByteCount = + CommandMailbox->Common.DataTransferSize; + } + if (RequestSenseLength > 0) + { + CommandMailbox->Common.CommandControlBits + .NoAutoRequestSense = false; + CommandMailbox->Common.RequestSenseSize = RequestSenseLength; + CommandMailbox->Common.RequestSenseBusAddress = + RequestSenseBufferDMA; + } + DAC960_ExecuteCommand(Command); + CommandStatus = Command->V2.CommandStatus; + RequestSenseLength = Command->V2.RequestSenseLength; + DataTransferResidue = Command->V2.DataTransferResidue; + spin_lock_irqsave(&Controller->queue_lock, flags); + DAC960_DeallocateCommand(Command); + spin_unlock_irqrestore(&Controller->queue_lock, flags); + if (RequestSenseLength > UserCommand.RequestSenseLength) + RequestSenseLength = UserCommand.RequestSenseLength; + if (copy_to_user(&UserSpaceUserCommand->DataTransferLength, + &DataTransferResidue, + sizeof(DataTransferResidue))) { + ErrorCode = -EFAULT; + goto Failure2; + } + if (copy_to_user(&UserSpaceUserCommand->RequestSenseLength, + &RequestSenseLength, sizeof(RequestSenseLength))) { + ErrorCode = -EFAULT; + goto Failure2; + } + if (DataTransferLength > 0) + { + if (copy_to_user(UserCommand.DataTransferBuffer, + DataTransferBuffer, DataTransferLength)) { + ErrorCode = -EFAULT; + goto Failure2; + } + } + if (RequestSenseLength > 0) + { + if (copy_to_user(UserCommand.RequestSenseBuffer, + RequestSenseBuffer, RequestSenseLength)) { + ErrorCode = -EFAULT; + goto Failure2; + } + } + ErrorCode = CommandStatus; + Failure2: + pci_free_consistent(Controller->PCIDevice, abs(DataTransferLength), + DataTransferBuffer, DataTransferBufferDMA); + if (RequestSenseBuffer != NULL) + pci_free_consistent(Controller->PCIDevice, RequestSenseLength, + RequestSenseBuffer, RequestSenseBufferDMA); + Failure2a: + return ErrorCode; + } + case DAC960_IOCTL_V2_GET_HEALTH_STATUS: + { + DAC960_V2_GetHealthStatus_T *UserSpaceGetHealthStatus = + (DAC960_V2_GetHealthStatus_T *) Argument; + DAC960_V2_GetHealthStatus_T GetHealthStatus; + DAC960_V2_HealthStatusBuffer_T HealthStatusBuffer; + DAC960_Controller_T *Controller; + int ControllerNumber; + if (UserSpaceGetHealthStatus == NULL) return -EINVAL; + if (copy_from_user(&GetHealthStatus, UserSpaceGetHealthStatus, + sizeof(DAC960_V2_GetHealthStatus_T))) + return -EFAULT; + ControllerNumber = GetHealthStatus.ControllerNumber; + if (ControllerNumber < 0 || + ControllerNumber > DAC960_ControllerCount - 1) + return -ENXIO; + Controller = DAC960_Controllers[ControllerNumber]; + if (Controller == NULL) return -ENXIO; + if (Controller->FirmwareType != DAC960_V2_Controller) return -EINVAL; + if (copy_from_user(&HealthStatusBuffer, + GetHealthStatus.HealthStatusBuffer, + sizeof(DAC960_V2_HealthStatusBuffer_T))) + return -EFAULT; + while (Controller->V2.HealthStatusBuffer->StatusChangeCounter + == HealthStatusBuffer.StatusChangeCounter && + Controller->V2.HealthStatusBuffer->NextEventSequenceNumber + == HealthStatusBuffer.NextEventSequenceNumber) + { + interruptible_sleep_on_timeout(&Controller->HealthStatusWaitQueue, + DAC960_MonitoringTimerInterval); + if (signal_pending(current)) return -EINTR; + } + if (copy_to_user(GetHealthStatus.HealthStatusBuffer, + Controller->V2.HealthStatusBuffer, + sizeof(DAC960_V2_HealthStatusBuffer_T))) + return -EFAULT; + return 0; + } + } + return -EINVAL; +} + +static struct file_operations DAC960_gam_fops = { + .owner = THIS_MODULE, + .ioctl = DAC960_gam_ioctl +}; + +static struct miscdevice DAC960_gam_dev = { + DAC960_GAM_MINOR, + "dac960_gam", + &DAC960_gam_fops +}; + +static int DAC960_gam_init(void) +{ + int ret; + + ret = misc_register(&DAC960_gam_dev); + if (ret) + printk(KERN_ERR "DAC960_gam: can't misc_register on minor %d\n", DAC960_GAM_MINOR); + return ret; +} + +static void DAC960_gam_cleanup(void) +{ + misc_deregister(&DAC960_gam_dev); +} + +#endif /* DAC960_GAM_MINOR */ + static struct DAC960_privdata DAC960_BA_privdata = { .HardwareType = DAC960_BA_Controller, .FirmwareType = DAC960_V2_Controller, @@ -7000,12 +7025,23 @@ static int DAC960_init_module(void) { - return pci_module_init(&DAC960_pci_driver); + int ret; + + ret = pci_module_init(&DAC960_pci_driver); +#ifdef DAC960_GAM_MINOR + if (!ret) + DAC960_gam_init(); +#endif + return ret; } static void DAC960_cleanup_module(void) { int i; + +#ifdef DAC960_GAM_MINOR + DAC960_gam_cleanup(); +#endif for (i = 0; i < DAC960_ControllerCount; i++) { DAC960_Controller_T *Controller = DAC960_Controllers[i]; diff -Nru a/drivers/block/DAC960.h b/drivers/block/DAC960.h --- a/drivers/block/DAC960.h Tue Sep 2 19:58:18 2003 +++ b/drivers/block/DAC960.h Tue Sep 2 19:58:18 2003 @@ -4138,8 +4138,6 @@ static void DAC960_V1_QueueMonitoringCommand(DAC960_Command_T *); static void DAC960_V2_QueueMonitoringCommand(DAC960_Command_T *); static void DAC960_MonitoringTimerFunction(unsigned long); -static int DAC960_UserIOCTL(struct inode *, struct file *, - unsigned int, unsigned long); static void DAC960_Message(DAC960_MessageLevel_T, unsigned char *, DAC960_Controller_T *, ...); static void DAC960_CreateProcEntries(DAC960_Controller_T *); diff -Nru a/drivers/block/acsi_slm.c b/drivers/block/acsi_slm.c --- a/drivers/block/acsi_slm.c Tue Sep 2 19:58:12 2003 +++ b/drivers/block/acsi_slm.c Tue Sep 2 19:58:12 2003 @@ -374,7 +374,7 @@ if (!(page = __get_free_page( GFP_KERNEL ))) return( -ENOMEM ); - length = slm_getstats( (char *)page, MINOR(node->i_rdev) ); + length = slm_getstats( (char *)page, iminor(node) ); if (length < 0) { count = length; goto out; @@ -622,7 +622,7 @@ { struct inode *node = file->f_dentry->d_inode; - int device = MINOR( node->i_rdev ); + int device = iminor(node); int n, filled, w, h; while( SLMState == PRINTING || @@ -694,7 +694,7 @@ static int slm_ioctl( struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg ) -{ int device = MINOR( inode->i_rdev ), err; +{ int device = iminor(inode), err; /* I can think of setting: * - manual feed @@ -768,7 +768,7 @@ { int device; struct slm *sip; - device = MINOR(inode->i_rdev); + device = iminor(inode); if (device >= N_SLM_Printers) return( -ENXIO ); sip = &slm_info[device]; @@ -797,7 +797,7 @@ { int device; struct slm *sip; - device = MINOR(inode->i_rdev); + device = iminor(inode); sip = &slm_info[device]; if (file->f_mode & 2) diff -Nru a/drivers/block/amiflop.c b/drivers/block/amiflop.c --- a/drivers/block/amiflop.c Tue Sep 2 19:58:15 2003 +++ b/drivers/block/amiflop.c Tue Sep 2 19:58:15 2003 @@ -55,24 +55,15 @@ #include -#include -#include -#include -#include -#include #include #include -#include -#include #include -#include -#include #include #include #include -#include #include -#include +#include +#include #include #include @@ -1446,7 +1437,7 @@ static int fd_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long param) { - int drive = minor(inode->i_rdev) & 3; + int drive = iminor(inode) & 3; static struct floppy_struct getprm; switch(cmd){ @@ -1570,8 +1561,8 @@ */ static int floppy_open(struct inode *inode, struct file *filp) { - int drive = minor(inode->i_rdev) & 3; - int system = (minor(inode->i_rdev) & 4) >> 2; + int drive = iminor(inode) & 3; + int system = (iminor(inode) & 4) >> 2; int old_dev; unsigned long flags; @@ -1618,7 +1609,7 @@ static int floppy_release(struct inode * inode, struct file * filp) { - int drive = minor(inode->i_rdev) & 3; + int drive = iminor(inode) & 3; if (unit[drive].dirty == 1) { del_timer (flush_track_timer + drive); diff -Nru a/drivers/block/as-iosched.c b/drivers/block/as-iosched.c --- a/drivers/block/as-iosched.c Tue Sep 2 19:58:12 2003 +++ b/drivers/block/as-iosched.c Tue Sep 2 19:58:12 2003 @@ -709,6 +709,14 @@ return 1; } + if (aic->seek_samples == 0 || aic->ttime_samples == 0) { + /* + * Process has just started IO so default to not anticipate. + * Maybe should be smarter. + */ + return 1; + } + if (aic->ttime_mean > ad->antic_expire) { /* the process thinks too much between requests */ return 1; diff -Nru a/drivers/block/ataflop.c b/drivers/block/ataflop.c --- a/drivers/block/ataflop.c Tue Sep 2 19:58:13 2003 +++ b/drivers/block/ataflop.c Tue Sep 2 19:58:13 2003 @@ -63,35 +63,16 @@ #include -#include -#include -#include -#include -#include -#include #include -#include -#include #include -#include -#include #include -#include /* for invalidate_buffers() */ - -#include -#include -#include -#include -#include -#include +#include #include #include -#include #include #include #include -#include #define FD_MAX_UNITS 2 @@ -1838,7 +1819,7 @@ static int floppy_open( struct inode *inode, struct file *filp ) { struct atari_floppy_struct *p = inode->i_bdev->bd_disk->private_data; - int type = minor(inode->i_rdev) >> 2; + int type = iminor(inode) >> 2; DPRINT(("fd_open: type=%d\n",type)); if (p->ref && p->type != type) diff -Nru a/drivers/block/cciss.c b/drivers/block/cciss.c --- a/drivers/block/cciss.c Tue Sep 2 19:58:19 2003 +++ b/drivers/block/cciss.c Tue Sep 2 19:58:19 2003 @@ -356,11 +356,11 @@ */ static int cciss_open(struct inode *inode, struct file *filep) { - int ctlr = major(inode->i_rdev) - COMPAQ_CISS_MAJOR; - int dsk = minor(inode->i_rdev) >> NWD_SHIFT; + int ctlr = imajor(inode) - COMPAQ_CISS_MAJOR; + int dsk = iminor(inode) >> NWD_SHIFT; #ifdef CCISS_DEBUG - printk(KERN_DEBUG "cciss_open %x (%x:%x)\n", inode->i_rdev, ctlr, dsk); + printk(KERN_DEBUG "cciss_open %s (%x:%x)\n", inode->i_bdev->bd_disk->disk_name, ctlr, dsk); #endif /* CCISS_DEBUG */ if (ctlr >= MAX_CTLR || hba[ctlr] == NULL) @@ -372,7 +372,7 @@ * for "raw controller". */ if (hba[ctlr]->drv[dsk].nr_blocks == 0) { - if (minor(inode->i_rdev) != 0) + if (iminor(inode) != 0) return -ENXIO; if (!capable(CAP_SYS_ADMIN)) return -EPERM; @@ -386,11 +386,11 @@ */ static int cciss_release(struct inode *inode, struct file *filep) { - int ctlr = major(inode->i_rdev) - COMPAQ_CISS_MAJOR; - int dsk = minor(inode->i_rdev) >> NWD_SHIFT; + int ctlr = imajor(inode) - COMPAQ_CISS_MAJOR; + int dsk = iminor(inode) >> NWD_SHIFT; #ifdef CCISS_DEBUG - printk(KERN_DEBUG "cciss_release %x (%x:%x)\n", inode->i_rdev, ctlr, dsk); + printk(KERN_DEBUG "cciss_release %s (%x:%x)\n", inode->i_bdev->bd_disk->disk_name, ctlr, dsk); #endif /* CCISS_DEBUG */ /* fsync_dev(inode->i_rdev); */ @@ -406,8 +406,8 @@ static int cciss_ioctl(struct inode *inode, struct file *filep, unsigned int cmd, unsigned long arg) { - int ctlr = major(inode->i_rdev) - COMPAQ_CISS_MAJOR; - int dsk = minor(inode->i_rdev) >> NWD_SHIFT; + int ctlr = imajor(inode) - COMPAQ_CISS_MAJOR; + int dsk = iminor(inode) >> NWD_SHIFT; #ifdef CCISS_DEBUG printk(KERN_DEBUG "cciss_ioctl: Called with cmd=%x %lx\n", cmd, arg); @@ -2525,6 +2525,9 @@ if (!q) goto err_all; + hba[i]->queue = q; + q->queuedata = hba[i]; + /* Initialize the pdev driver private data. have it point to hba[i]. */ pci_set_drvdata(pdev, hba[i]); @@ -2545,7 +2548,6 @@ cciss_procinit(i); - q->queuedata = hba[i]; blk_queue_bounce_limit(q, hba[i]->pdev->dma_mask); /* This is a hardware imposed limit. */ diff -Nru a/drivers/block/cpqarray.c b/drivers/block/cpqarray.c --- a/drivers/block/cpqarray.c Tue Sep 2 19:58:13 2003 +++ b/drivers/block/cpqarray.c Tue Sep 2 19:58:13 2003 @@ -1078,7 +1078,7 @@ put_user(host->ctlr_sig, (int*)arg); return 0; case IDAREVALIDATEVOLS: - if (minor(inode->i_rdev) != 0) + if (iminor(inode) != 0) return -ENXIO; return revalidate_allvol(host); case IDADRIVERVERSION: diff -Nru a/drivers/block/floppy.c b/drivers/block/floppy.c --- a/drivers/block/floppy.c Tue Sep 2 19:58:13 2003 +++ b/drivers/block/floppy.c Tue Sep 2 19:58:13 2003 @@ -695,23 +695,9 @@ spin_unlock_irqrestore(&floppy_lock, flags); } -static int maximum(int a, int b) -{ - if (a > b) - return a; - else - return b; -} -#define INFBOUND(a,b) (a)=maximum((a),(b)); +#define INFBOUND(a,b) (a)=max_t(int, a, b) -static int minimum(int a, int b) -{ - if (a < b) - return a; - else - return b; -} -#define SUPBOUND(a,b) (a)=minimum((a),(b)); +#define SUPBOUND(a,b) (a)=min_t(int, a, b) /* @@ -1021,9 +1007,9 @@ static DECLARE_WORK(floppy_work, NULL, NULL); -static void schedule_bh( void (*handler)(void*) ) +static void schedule_bh(void (*handler) (void)) { - PREPARE_WORK(&floppy_work, handler, NULL); + PREPARE_WORK(&floppy_work, (void (*)(void *))handler, NULL); schedule_work(&floppy_work); } @@ -1035,7 +1021,7 @@ spin_lock_irqsave(&floppy_lock, flags); do_floppy = NULL; - PREPARE_WORK(&floppy_work, (void*)(void*)empty, NULL); + PREPARE_WORK(&floppy_work, (void*)empty, NULL); del_timer(&fd_timer); spin_unlock_irqrestore(&floppy_lock, flags); } @@ -1813,9 +1799,9 @@ max_sensei--; } while ((ST0 & 0x83) != UNIT(current_drive) && inr == 2 && max_sensei); } - if (handler) { - schedule_bh( (void *)(void *) handler); - } else + if (handler) + schedule_bh(handler); + else FDCS->reset = 1; is_alive("normal interrupt end"); @@ -2058,26 +2044,26 @@ wake_up(&command_done); } -static struct cont_t wakeup_cont={ - empty, - do_wakeup, - empty, - (done_f)empty +static struct cont_t wakeup_cont = { + .interrupt = empty, + .redo = do_wakeup, + .error = empty, + .done = (done_f) empty }; -static struct cont_t intr_cont={ - empty, - process_fd_request, - empty, - (done_f) empty +static struct cont_t intr_cont = { + .interrupt = empty, + .redo = process_fd_request, + .error = empty, + .done = (done_f) empty }; static int wait_til_done(void (*handler)(void), int interruptible) { int ret; - schedule_bh((void *)(void *)handler); + schedule_bh(handler); if (command_status < 2 && NO_SIGNAL) { DECLARE_WAITQUEUE(wait, current); @@ -2281,11 +2267,12 @@ #endif } -static struct cont_t format_cont={ - format_interrupt, - redo_format, - bad_flp_intr, - generic_done }; +static struct cont_t format_cont = { + .interrupt = format_interrupt, + .redo = redo_format, + .error = bad_flp_intr, + .done = generic_done +}; static int do_format(int drive, struct format_descr *tmp_format_req) { @@ -2523,12 +2510,12 @@ int size, i; max_sector = transfer_size(ssize, - minimum(max_sector, max_sector_2), + min(max_sector, max_sector_2), current_req->nr_sectors); if (current_count_sectors <= 0 && CT(COMMAND) == FD_WRITE && buffer_max > fsector_t + current_req->nr_sectors) - current_count_sectors = minimum(buffer_max - fsector_t, + current_count_sectors = min_t(int, buffer_max - fsector_t, current_req->nr_sectors); remaining = current_count_sectors << 9; @@ -2546,7 +2533,7 @@ } #endif - buffer_max = maximum(max_sector, buffer_max); + buffer_max = max(max_sector, buffer_max); dma_buffer = floppy_track_buffer + ((fsector_t - buffer_min) << 9); @@ -2697,7 +2684,7 @@ if ((_floppy->rate & FD_2M) && (!TRACK) && (!HEAD)){ max_sector = 2 * _floppy->sect / 3; if (fsector_t >= max_sector){ - current_count_sectors = minimum(_floppy->sect - fsector_t, + current_count_sectors = min_t(int, _floppy->sect - fsector_t, current_req->nr_sectors); return 1; } @@ -2987,7 +2974,7 @@ if (TESTF(FD_NEED_TWADDLE)) twaddle(); - schedule_bh( (void *)(void *) floppy_start); + schedule_bh(floppy_start); #ifdef DEBUGT debugt("queue fd request"); #endif @@ -2996,16 +2983,17 @@ #undef REPEAT } -static struct cont_t rw_cont={ - rw_interrupt, - redo_fd_request, - bad_flp_intr, - request_done }; +static struct cont_t rw_cont = { + .interrupt = rw_interrupt, + .redo = redo_fd_request, + .error = bad_flp_intr, + .done = request_done +}; static void process_fd_request(void) { cont = &rw_cont; - schedule_bh( (void *)(void *) redo_fd_request); + schedule_bh(redo_fd_request); } static void do_fd_request(request_queue_t * q) @@ -3031,11 +3019,12 @@ is_alive("do fd request"); } -static struct cont_t poll_cont={ - success_and_wakeup, - floppy_ready, - generic_failure, - generic_done }; +static struct cont_t poll_cont = { + .interrupt = success_and_wakeup, + .redo = floppy_ready, + .error = generic_failure, + .done = generic_done +}; static int poll_drive(int interruptible, int flag) { @@ -3066,11 +3055,12 @@ printk("weird, reset interrupt called\n"); } -static struct cont_t reset_cont={ - reset_intr, - success_and_wakeup, - generic_failure, - generic_done }; +static struct cont_t reset_cont = { + .interrupt = reset_intr, + .redo = success_and_wakeup, + .error = generic_failure, + .done = generic_done +}; static int user_reset_fdc(int drive, int arg, int interruptible) { @@ -3174,11 +3164,11 @@ } -static struct cont_t raw_cmd_cont={ - success_and_wakeup, - floppy_start, - generic_failure, - raw_cmd_done +static struct cont_t raw_cmd_cont = { + .interrupt = success_and_wakeup, + .redo = floppy_start, + .error = generic_failure, + .done = raw_cmd_done }; static inline int raw_cmd_copyout(int cmd, char *param, @@ -3781,9 +3771,9 @@ } } - UDRS->fd_device = minor(inode->i_rdev); - set_capacity(disks[drive], floppy_sizes[minor(inode->i_rdev)]); - if (old_dev != -1 && old_dev != minor(inode->i_rdev)) { + UDRS->fd_device = iminor(inode); + set_capacity(disks[drive], floppy_sizes[iminor(inode)]); + if (old_dev != -1 && old_dev != iminor(inode)) { if (buffer_drive == drive) buffer_track = -1; } @@ -3910,22 +3900,6 @@ return 0; } -static int floppy_read_block_0(struct gendisk *disk) -{ - struct block_device *bdev; - int ret; - - bdev = bdget_disk(disk, 0); - if (!bdev) { - printk("No block device for %s\n", disk->disk_name); - BUG(); - } - bdev->bd_disk = disk; /* ewww */ - ret = __floppy_read_block_0(bdev); - atomic_dec(&bdev->bd_count); - return ret; -} - /* revalidate the floppy disk, i.e. trigger format autodetection by reading * the bootblock (block 0). "Autodetection" is also needed to check whether * there is a disk in the drive at all... Thus we also do it for fixed @@ -3961,7 +3935,7 @@ UDRS->generation++; if (NO_GEOM){ /* auto-sensing */ - res = floppy_read_block_0(disk); + res = __floppy_read_block_0(opened_bdev[drive]); } else { if (cf) poll_drive(0, FD_RAW_NEED_DISK); diff -Nru a/drivers/block/floppy98.c b/drivers/block/floppy98.c --- a/drivers/block/floppy98.c Tue Sep 2 19:58:15 2003 +++ b/drivers/block/floppy98.c Tue Sep 2 19:58:15 2003 @@ -3844,9 +3844,9 @@ } } - UDRS->fd_device = minor(inode->i_rdev); - set_capacity(disks[drive], floppy_sizes[minor(inode->i_rdev)]); - if (old_dev != -1 && old_dev != minor(inode->i_rdev)) { + UDRS->fd_device = iminor(inode); + set_capacity(disks[drive], floppy_sizes[iminor(inode)]); + if (old_dev != -1 && old_dev != iminor(inode)) { if (buffer_drive == drive) buffer_track = -1; } @@ -3989,22 +3989,6 @@ return 0; } -static int floppy_read_block_0(struct gendisk *disk) -{ - struct block_device *bdev; - int ret; - - bdev = bdget_disk(disk, 0); - if (!bdev) { - printk("No block device for %s\n", disk->disk_name); - BUG(); - } - bdev->bd_disk = disk; /* ewww */ - ret = __floppy_read_block_0(bdev); - atomic_dec(&bdev->bd_count); - return ret; -} - /* revalidate the floppy disk, i.e. trigger format autodetection by reading * the bootblock (block 0). "Autodetection" is also needed to check whether * there is a disk in the drive at all... Thus we also do it for fixed @@ -4040,7 +4024,7 @@ UDRS->generation++; if (NO_GEOM){ /* auto-sensing */ - res = floppy_read_block_0(disk); + res = __floppy_read_block_0(opened_bdev[drive]); } else { if (cf) poll_drive(0, FD_RAW_NEED_DISK); diff -Nru a/drivers/block/genhd.c b/drivers/block/genhd.c --- a/drivers/block/genhd.c Tue Sep 2 19:58:15 2003 +++ b/drivers/block/genhd.c Tue Sep 2 19:58:15 2003 @@ -576,13 +576,10 @@ void set_device_ro(struct block_device *bdev, int flag) { - struct gendisk *disk = bdev->bd_disk; - if (bdev->bd_contains != bdev) { - int part = bdev->bd_dev - MKDEV(disk->major, disk->first_minor); - struct hd_struct *p = disk->part[part-1]; - if (p) p->policy = flag; - } else - disk->policy = flag; + if (bdev->bd_contains != bdev) + bdev->bd_part->policy = flag; + else + bdev->bd_disk->policy = flag; } void set_disk_ro(struct gendisk *disk, int flag) @@ -595,17 +592,12 @@ int bdev_read_only(struct block_device *bdev) { - struct gendisk *disk; if (!bdev) return 0; - disk = bdev->bd_disk; - if (bdev->bd_contains != bdev) { - int part = bdev->bd_dev - MKDEV(disk->major, disk->first_minor); - struct hd_struct *p = disk->part[part-1]; - if (p) return p->policy; - return 0; - } else - return disk->policy; + else if (bdev->bd_contains != bdev) + return bdev->bd_part->policy; + else + return bdev->bd_disk->policy; } int invalidate_partition(struct gendisk *disk, int index) diff -Nru a/drivers/block/ioctl.c b/drivers/block/ioctl.c --- a/drivers/block/ioctl.c Tue Sep 2 19:58:13 2003 +++ b/drivers/block/ioctl.c Tue Sep 2 19:58:13 2003 @@ -8,7 +8,6 @@ static int blkpg_ioctl(struct block_device *bdev, struct blkpg_ioctl_arg *arg) { struct block_device *bdevp; - int holder; struct gendisk *disk; struct blkpg_ioctl_arg a; struct blkpg_partition p; @@ -41,8 +40,11 @@ return -EINVAL; } /* partition number in use? */ - if (disk->part[part - 1]) + down(&bdev->bd_sem); + if (disk->part[part - 1]) { + up(&bdev->bd_sem); return -EBUSY; + } /* overlap? */ for (i = 0; i < disk->minors - 1; i++) { struct hd_struct *s = disk->part[i]; @@ -50,22 +52,26 @@ if (!s) continue; if (!(start+length <= s->start_sect || - start >= s->start_sect + s->nr_sects)) + start >= s->start_sect + s->nr_sects)) { + up(&bdev->bd_sem); return -EBUSY; + } } /* all seems OK */ add_partition(disk, part, start, length); + up(&bdev->bd_sem); return 0; case BLKPG_DEL_PARTITION: if (!disk->part[part-1]) return -ENXIO; if (disk->part[part - 1]->nr_sects == 0) return -ENXIO; - /* partition in use? Incomplete check for now. */ bdevp = bdget_disk(disk, part); if (!bdevp) return -ENOMEM; - if (bd_claim(bdevp, &holder) < 0) { + down(&bdevp->bd_sem); + if (bdevp->bd_openers) { + up(&bdevp->bd_sem); bdput(bdevp); return -EBUSY; } @@ -73,9 +79,12 @@ fsync_bdev(bdevp); invalidate_bdev(bdevp, 0); + down(&bdev->bd_sem); delete_partition(disk, part); - bd_release(bdevp); + up(&bdev->bd_sem); + up(&bdevp->bd_sem); bdput(bdevp); + return 0; default: return -EINVAL; diff -Nru a/drivers/block/ll_rw_blk.c b/drivers/block/ll_rw_blk.c --- a/drivers/block/ll_rw_blk.c Tue Sep 2 19:58:13 2003 +++ b/drivers/block/ll_rw_blk.c Tue Sep 2 19:58:13 2003 @@ -136,6 +136,12 @@ return ret; } +void blk_queue_activity_fn(request_queue_t *q, activity_fn *fn, void *data) +{ + q->activity_fn = fn; + q->activity_data = data; +} + /** * blk_queue_prep_rq - set a prepare_request function for queue * @q: queue @@ -225,6 +231,8 @@ blk_queue_bounce_limit(q, BLK_BOUNCE_HIGH); INIT_LIST_HEAD(&q->plug_list); + + blk_queue_activity_fn(q, NULL, NULL); } /** @@ -1314,7 +1322,7 @@ if (!printed) { printed = 1; - printk("Using %s elevator\n", chosen_elevator->elevator_name); + printk("Using %s io scheduler\n", chosen_elevator->elevator_name); } if (elevator_init(q, chosen_elevator)) @@ -1666,6 +1674,9 @@ { drive_stat_acct(req, req->nr_sectors, 1); + if (q->activity_fn) + q->activity_fn(q->activity_data, rq_data_dir(req)); + /* * elevator indicated where it wants this request to be * inserted at elevator_merge time @@ -2043,24 +2054,23 @@ static inline void blk_partition_remap(struct bio *bio) { struct block_device *bdev = bio->bi_bdev; - struct gendisk *disk = bdev->bd_disk; - struct hd_struct *p; - if (bdev == bdev->bd_contains) - return; - p = disk->part[bdev->bd_dev-MKDEV(disk->major,disk->first_minor)-1]; - switch (bio->bi_rw) { - case READ: - p->read_sectors += bio_sectors(bio); - p->reads++; - break; - case WRITE: - p->write_sectors += bio_sectors(bio); - p->writes++; - break; + if (bdev != bdev->bd_contains) { + struct hd_struct *p = bdev->bd_part; + + switch (bio->bi_rw) { + case READ: + p->read_sectors += bio_sectors(bio); + p->reads++; + break; + case WRITE: + p->write_sectors += bio_sectors(bio); + p->writes++; + break; + } + bio->bi_sector += p->start_sect; + bio->bi_bdev = bdev->bd_contains; } - bio->bi_sector += bdev->bd_offset; - bio->bi_bdev = bdev->bd_contains; } /** diff -Nru a/drivers/block/paride/pg.c b/drivers/block/paride/pg.c --- a/drivers/block/paride/pg.c Tue Sep 2 19:58:18 2003 +++ b/drivers/block/paride/pg.c Tue Sep 2 19:58:18 2003 @@ -527,11 +527,9 @@ return -1; } -#define DEVICE_NR(dev) (minor(dev) & 0x7F) - static int pg_open(struct inode *inode, struct file *file) { - int unit = DEVICE_NR(inode->i_rdev); + int unit = iminor(inode) & 0x7f; struct pg *dev = &devices[unit]; if ((unit >= PG_UNITS) || (!dev->present)) diff -Nru a/drivers/block/paride/pt.c b/drivers/block/paride/pt.c --- a/drivers/block/paride/pt.c Tue Sep 2 19:58:14 2003 +++ b/drivers/block/paride/pt.c Tue Sep 2 19:58:14 2003 @@ -670,11 +670,11 @@ return -1; } -#define DEVICE_NR(dev) (minor(dev) & 0x7F) +#define DEVICE_NR(inode) (iminor(inode) & 0x7F) static int pt_open(struct inode *inode, struct file *file) { - int unit = DEVICE_NR(inode->i_rdev); + int unit = DEVICE_NR(inode); if ((unit >= PT_UNITS) || (!PT.present)) return -ENODEV; @@ -696,7 +696,7 @@ return -EROFS; } - if (!(minor(inode->i_rdev) & 128)) + if (!(iminor(inode) & 128)) PT.flags |= PT_REWIND; PT.bufptr = kmalloc(PT_BUFSIZE, GFP_KERNEL); @@ -715,7 +715,7 @@ int unit; struct mtop mtop; - unit = DEVICE_NR(inode->i_rdev); + unit = DEVICE_NR(inode); if (unit >= PT_UNITS) return -EINVAL; if (!PT.present) @@ -753,7 +753,7 @@ static int pt_release(struct inode *inode, struct file *file) { - int unit = DEVICE_NR(inode->i_rdev); + int unit = DEVICE_NR(inode); if ((unit >= PT_UNITS) || (atomic_read(&PT.available) > 1)) return -EINVAL; @@ -776,7 +776,7 @@ static ssize_t pt_read(struct file *filp, char *buf, size_t count, loff_t * ppos) { struct inode *ino = filp->f_dentry->d_inode; - int unit = DEVICE_NR(ino->i_rdev); + int unit = DEVICE_NR(ino); char rd_cmd[12] = { ATAPI_READ_6, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; int k, n, r, p, s, t, b; @@ -873,7 +873,7 @@ static ssize_t pt_write(struct file *filp, const char *buf, size_t count, loff_t * ppos) { struct inode *ino = filp->f_dentry->d_inode; - int unit = DEVICE_NR(ino->i_rdev); + int unit = DEVICE_NR(ino); char wr_cmd[12] = { ATAPI_WRITE_6, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; int k, n, r, p, s, t, b; diff -Nru a/drivers/block/rd.c b/drivers/block/rd.c --- a/drivers/block/rd.c Tue Sep 2 19:58:16 2003 +++ b/drivers/block/rd.c Tue Sep 2 19:58:16 2003 @@ -245,6 +245,7 @@ static int rd_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) { int error; + struct block_device *bdev = inode->i_bdev; if (cmd != BLKFLSBUF) return -EINVAL; @@ -253,12 +254,12 @@ it's not like with the other blockdevices where this ioctl only flushes away the buffer cache. */ error = -EBUSY; - down(&inode->i_bdev->bd_sem); - if (inode->i_bdev->bd_openers <= 2) { - truncate_inode_pages(inode->i_mapping, 0); + down(&bdev->bd_sem); + if (bdev->bd_openers <= 2) { + truncate_inode_pages(bdev->bd_inode->i_mapping, 0); error = 0; } - up(&inode->i_bdev->bd_sem); + up(&bdev->bd_sem); return error; } @@ -269,18 +270,18 @@ static int rd_open(struct inode * inode, struct file * filp) { - unsigned unit = minor(inode->i_rdev); + unsigned unit = iminor(inode); /* * Immunize device against invalidate_buffers() and prune_icache(). */ if (rd_bdev[unit] == NULL) { struct block_device *bdev = inode->i_bdev; - atomic_inc(&bdev->bd_count); + inode = igrab(bdev->bd_inode); rd_bdev[unit] = bdev; bdev->bd_openers++; bdev->bd_block_size = rd_blocksize; - bdev->bd_inode->i_size = get_capacity(rd_disks[unit])<<9; + inode->i_size = get_capacity(rd_disks[unit])<<9; inode->i_mapping->a_ops = &ramdisk_aops; inode->i_mapping->backing_dev_info = &rd_backing_dev_info; } diff -Nru a/drivers/block/scsi_ioctl.c b/drivers/block/scsi_ioctl.c --- a/drivers/block/scsi_ioctl.c Tue Sep 2 19:58:20 2003 +++ b/drivers/block/scsi_ioctl.c Tue Sep 2 19:58:20 2003 @@ -438,11 +438,7 @@ err = sg_emulated_host(q, (int *) arg); break; case SG_IO: - err = bd_claim(bdev, current); - if (err) - break; err = sg_io(q, bdev, (struct sg_io_hdr *) arg); - bd_release(bdev); break; /* * old junk scsi send command ioctl @@ -452,11 +448,7 @@ if (!arg) break; - err = bd_claim(bdev, current); - if (err) - break; err = sg_scsi_ioctl(q, bdev, (Scsi_Ioctl_Command *)arg); - bd_release(bdev); break; case CDROMCLOSETRAY: close = 1; diff -Nru a/drivers/block/z2ram.c b/drivers/block/z2ram.c --- a/drivers/block/z2ram.c Tue Sep 2 19:58:17 2003 +++ b/drivers/block/z2ram.c Tue Sep 2 19:58:17 2003 @@ -28,10 +28,10 @@ #define DEVICE_NAME "Z2RAM" #include -#include #include #include #include +#include #include #include @@ -150,7 +150,7 @@ sizeof( z2ram_map[0] ); int rc = -ENOMEM; - device = minor( inode->i_rdev ); + device = iminor(inode); if ( current_device != -1 && current_device != device ) { diff -Nru a/drivers/cdrom/Kconfig b/drivers/cdrom/Kconfig --- a/drivers/cdrom/Kconfig Tue Sep 2 19:58:18 2003 +++ b/drivers/cdrom/Kconfig Tue Sep 2 19:58:18 2003 @@ -74,7 +74,7 @@ config SBPCD tristate "Matsushita/Panasonic/Creative, Longshine, TEAC CDROM support" - depends on CD_NO_IDESCSI + depends on CD_NO_IDESCSI && BROKEN_ON_SMP ---help--- This driver supports most of the drives which use the Panasonic or Sound Blaster interface. Please read the file @@ -199,7 +199,7 @@ config CM206 tristate "Philips/LMS CM206 CDROM support" - depends on CD_NO_IDESCSI + depends on CD_NO_IDESCSI && BROKEN_ON_SMP ---help--- If you have a Philips/LMS CD-ROM drive cm206 in combination with a cm260 host adapter card, say Y here. Please also read the file @@ -245,7 +245,7 @@ config CDU31A tristate "Sony CDU31A/CDU33A CDROM support" - depends on CD_NO_IDESCSI + depends on CD_NO_IDESCSI && BROKEN_ON_SMP ---help--- These CD-ROM drives have a spring-pop-out caddyless drawer, and a rectangular green LED centered beneath it. NOTE: these CD-ROM @@ -267,7 +267,7 @@ config CDU535 tristate "Sony CDU535 CDROM support" - depends on CD_NO_IDESCSI + depends on CD_NO_IDESCSI && BROKEN_ON_SMP ---help--- This is the driver for the older Sony CDU-535 and CDU-531 CD-ROM drives. Please read the file . diff -Nru a/drivers/char/Kconfig b/drivers/char/Kconfig --- a/drivers/char/Kconfig Tue Sep 2 19:58:12 2003 +++ b/drivers/char/Kconfig Tue Sep 2 19:58:12 2003 @@ -80,7 +80,7 @@ config COMPUTONE tristate "Computone IntelliPort Plus serial support" - depends on SERIAL_NONSTANDARD + depends on SERIAL_NONSTANDARD && BROKEN_ON_SMP ---help--- This driver supports the entire family of Intelliport II/Plus controllers with the exception of the MicroChannel controllers and @@ -113,7 +113,7 @@ config CYCLADES tristate "Cyclades async mux support" - depends on SERIAL_NONSTANDARD + depends on SERIAL_NONSTANDARD && BROKEN_ON_SMP ---help--- This is a driver for a card that gives you many serial ports. You would need something like this to connect more than two modems to @@ -145,7 +145,7 @@ config DIGIEPCA tristate "Digiboard Intelligent Async Support" - depends on SERIAL_NONSTANDARD + depends on SERIAL_NONSTANDARD && BROKEN_ON_SMP ---help--- This is a driver for Digi International's Xx, Xeve, and Xem series of cards which provide multiple serial ports. You would need @@ -164,7 +164,7 @@ config DIGI tristate "Digiboard PC/Xx Support" - depends on SERIAL_NONSTANDARD && DIGIEPCA=n + depends on SERIAL_NONSTANDARD && DIGIEPCA=n && BROKEN_ON_SMP help This is a driver for the Digiboard PC/Xe, PC/Xi, and PC/Xeve cards that give you many serial ports. You would need something like this @@ -177,7 +177,7 @@ config ESPSERIAL tristate "Hayes ESP serial port support" - depends on SERIAL_NONSTANDARD && ISA + depends on SERIAL_NONSTANDARD && ISA && BROKEN_ON_SMP help This is a driver which supports Hayes ESP serial ports. Both single port cards and multiport cards are supported. Make sure to read @@ -190,7 +190,7 @@ config MOXA_INTELLIO tristate "Moxa Intellio support" - depends on SERIAL_NONSTANDARD + depends on SERIAL_NONSTANDARD && BROKEN_ON_SMP help Say Y here if you have a Moxa Intellio multiport serial card. @@ -201,7 +201,7 @@ config MOXA_SMARTIO tristate "Moxa SmartIO support" - depends on SERIAL_NONSTANDARD + depends on SERIAL_NONSTANDARD && BROKEN_ON_SMP help Say Y here if you have a Moxa SmartIO multiport serial card. @@ -212,7 +212,7 @@ config ISI tristate "Multi-Tech multiport card support (EXPERIMENTAL)" - depends on SERIAL_NONSTANDARD && EXPERIMENTAL && m + depends on SERIAL_NONSTANDARD && EXPERIMENTAL && BROKEN_ON_SMP && m help This is a driver for the Multi-Tech cards which provide several serial ports. The driver is experimental and can currently only be @@ -262,7 +262,7 @@ config RISCOM8 tristate "SDL RISCom/8 card support" - depends on SERIAL_NONSTANDARD + depends on SERIAL_NONSTANDARD && BROKEN_ON_SMP help This is a driver for the SDL Communications RISCom/8 multiport card, which gives you many serial ports. You would need something like @@ -275,7 +275,7 @@ config SPECIALIX tristate "Specialix IO8+ card support" - depends on SERIAL_NONSTANDARD + depends on SERIAL_NONSTANDARD && BROKEN_ON_SMP help This is a driver for the Specialix IO8+ multiport card (both the ISA and the PCI version) which gives you many serial ports. You @@ -299,7 +299,7 @@ config SX tristate "Specialix SX (and SI) card support" - depends on SERIAL_NONSTANDARD + depends on SERIAL_NONSTANDARD && BROKEN_ON_SMP help This is a driver for the SX and SI multiport serial cards. Please read the file for details. @@ -310,7 +310,7 @@ config RIO tristate "Specialix RIO system support" - depends on SERIAL_NONSTANDARD + depends on SERIAL_NONSTANDARD && BROKEN_ON_SMP help This is a driver for the Specialix RIO, a smart serial card which drives an outboard box that can support up to 128 ports. Product @@ -339,7 +339,7 @@ config STALLION tristate "Stallion EasyIO or EC8/32 support" - depends on STALDRV + depends on STALDRV && BROKEN_ON_SMP help If you have an EasyIO or EasyConnection 8/32 multiport Stallion card, then this is for you; say Y. Make sure to read @@ -352,7 +352,7 @@ config ISTALLION tristate "Stallion EC8/64, ONboard, Brumby support" - depends on STALDRV + depends on STALDRV && BROKEN help If you have an EasyConnection 8/64, ONboard, Brumby or Stallion serial multiport card, say Y here. Make sure to read @@ -365,7 +365,7 @@ config SERIAL_TX3912 bool "TMPTX3912/PR31700 serial port support" - depends on SERIAL_NONSTANDARD && MIPS + depends on SERIAL_NONSTANDARD && MIPS && BROKEN_ON_SMP help The TX3912 is a Toshiba RISC processor based o the MIPS 3900 core; see . @@ -425,7 +425,7 @@ config A2232 tristate "Commodore A2232 serial support (EXPERIMENTAL)" - depends on EXPERIMENTAL && ZORRO + depends on EXPERIMENTAL && ZORRO && BROKEN_ON_SMP ---help--- This option supports the 2232 7-port serial card shipped with the Amiga 2000 and other Zorro-bus machines, dating from 1989. At @@ -909,6 +909,7 @@ config FTAPE tristate "Ftape (QIC-80/Travan) support" + depends on BROKEN_ON_SMP ---help--- If you have a tape drive that is connected to your floppy controller, say Y here. diff -Nru a/drivers/char/agp/Kconfig b/drivers/char/agp/Kconfig --- a/drivers/char/agp/Kconfig Tue Sep 2 19:58:16 2003 +++ b/drivers/char/agp/Kconfig Tue Sep 2 19:58:16 2003 @@ -63,15 +63,19 @@ You should say Y here if you use XFree86 3.3.6 or 4.x and want to use GLX or DRI. If unsure, say N. +# RED-PEN this option is misnamed, it's not 8151 specific config AGP_AMD_8151 - tristate "AMD Opteron/Athlon64 on-CPU GART support" + tristate "AMD Opteron/Athlon64 on-CPU GART support" if !GART_IOMMU depends on AGP && X86 - default GART_IOMMU + default y if GART_IOMMU help This option gives you AGP support for the GLX component of - XFree86 4.x using the on-CPU AGP bridge of the AMD Athlon64/Opteron CPUs. + XFree86 4.x using the on-CPU northbridge of the AMD Athlon64/Opteron CPUs. + You still need an external AGP bridge like the AMD 8151, VIA + K8T400M, SiS755. It may also support other AGP bridges when loaded + with agp_try_unsupported=1. You should say Y here if you use XFree86 3.3.6 or 4.x and want to - use GLX or DRI. If unsure, say N + use GLX or DRI. If unsure, say Y config AGP_INTEL tristate "Intel 440LX/BX/GX, I8xx and E7x05 chipset support" diff -Nru a/drivers/char/agp/agp.h b/drivers/char/agp/agp.h --- a/drivers/char/agp/agp.h Tue Sep 2 19:58:15 2003 +++ b/drivers/char/agp/agp.h Tue Sep 2 19:58:15 2003 @@ -167,8 +167,10 @@ #define PGE_EMPTY(b, p) (!(p) || (p) == (unsigned long) (b)->scratch_page) -/* intel register */ -#define INTEL_APBASE 0x10 +/* Chipset independant registers (from AGP Spec) */ +#define AGP_APBASE 0x10 + +/* Intel registers */ #define INTEL_APSIZE 0xb4 #define INTEL_ATTBASE 0xb8 #define INTEL_AGPCTRL 0xb0 @@ -176,7 +178,6 @@ #define INTEL_ERRSTS 0x91 /* Intel 460GX Registers */ -#define INTEL_I460_APBASE 0x10 #define INTEL_I460_BAPBASE 0x98 #define INTEL_I460_GXBCTL 0xa0 #define INTEL_I460_AGPSIZ 0xa2 @@ -184,7 +185,7 @@ #define INTEL_I460_GATT_VALID (1UL << 24) #define INTEL_I460_GATT_COHERENT (1UL << 25) -/* intel i830 registers */ +/* Intel i830 registers */ #define I830_GMCH_CTRL 0x52 #define I830_GMCH_ENABLED 0x4 #define I830_GMCH_MEM_MASK 0x1 @@ -218,31 +219,31 @@ #define I852_GME 0x2 #define I852_GM 0x5 -/* intel 815 register */ +/* Intel 815 register */ #define INTEL_815_APCONT 0x51 #define INTEL_815_ATTBASE_MASK ~0x1FFFFFFF -/* intel i820 registers */ +/* Intel i820 registers */ #define INTEL_I820_RDCR 0x51 #define INTEL_I820_ERRSTS 0xc8 -/* intel i840 registers */ +/* Intel i840 registers */ #define INTEL_I840_MCHCFG 0x50 #define INTEL_I840_ERRSTS 0xc8 -/* intel i845 registers */ +/* Intel i845 registers */ #define INTEL_I845_AGPM 0x51 #define INTEL_I845_ERRSTS 0xc8 -/* intel i850 registers */ +/* Intel i850 registers */ #define INTEL_I850_MCHCFG 0x50 #define INTEL_I850_ERRSTS 0xc8 -/* intel i860 registers */ +/* Intel i860 registers */ #define INTEL_I860_MCHCFG 0x50 #define INTEL_I860_ERRSTS 0xc8 -/* intel i810 registers */ +/* Intel i810 registers */ #define I810_GMADDR 0x10 #define I810_MMADDR 0x14 #define I810_PTE_BASE 0x10000 @@ -261,7 +262,6 @@ #define I810_DRAM_ROW_0_SDRAM 0x00000001 /* Intel 7505 registers */ -#define INTEL_I7505_NAPBASELO 0x10 #define INTEL_I7505_APSIZE 0x74 #define INTEL_I7505_NCAPID 0x60 #define INTEL_I7505_NISTAT 0x6c @@ -271,26 +271,23 @@ #define INTEL_I7505_MCHCFG 0x50 /* VIA register */ -#define VIA_APBASE 0x10 #define VIA_GARTCTRL 0x80 #define VIA_APSIZE 0x84 #define VIA_ATTBASE 0x88 /* VIA KT400 */ #define VIA_AGP3_GARTCTRL 0x90 -#define VIA_AGP3_APSIZE 0x94 +#define VIA_AGP3_APSIZE 0x94 #define VIA_AGP3_ATTBASE 0x98 -#define VIA_AGPSEL 0xfd +#define VIA_AGPSEL 0xfd /* SiS registers */ -#define SIS_APBASE 0x10 #define SIS_ATTBASE 0x90 #define SIS_APSIZE 0x94 #define SIS_TLBCNTRL 0x97 #define SIS_TLBFLUSH 0x98 /* AMD registers */ -#define AMD_APBASE 0x10 #define AMD_MMBASE 0x14 #define AMD_APSIZE 0xac #define AMD_MODECNTL 0xb0 @@ -300,24 +297,14 @@ #define AMD_TLBFLUSH 0x0c /* In mmio region (32-bit register) */ #define AMD_CACHEENTRY 0x10 /* In mmio region (32-bit register) */ -#define AMD_8151_APSIZE 0xb4 -#define AMD_8151_GARTBLOCK 0xb8 - -#define AMD_X86_64_GARTAPERTURECTL 0x90 -#define AMD_X86_64_GARTAPERTUREBASE 0x94 -#define AMD_X86_64_GARTTABLEBASE 0x98 -#define AMD_X86_64_GARTCACHECTL 0x9c -#define AMD_X86_64_GARTEN 1<<0 - -#define AMD_8151_VMAPERTURE 0x10 -#define AMD_8151_AGP_CTL 0xb0 -#define AMD_8151_APERTURESIZE 0xb4 -#define AMD_8151_GARTPTR 0xb8 -#define AMD_8151_GTLBEN 1<<7 -#define AMD_8151_APEREN 1<<8 +/* AMD64 registers */ +#define AMD64_GARTAPERTURECTL 0x90 +#define AMD64_GARTAPERTUREBASE 0x94 +#define AMD64_GARTTABLEBASE 0x98 +#define AMD64_GARTCACHECTL 0x9c +#define AMD64_GARTEN 1<<0 /* ALi registers */ -#define ALI_APBASE 0x10 #define ALI_AGPCTRL 0xb8 #define ALI_ATTBASE 0xbc #define ALI_TLBCTRL 0xc0 @@ -327,19 +314,17 @@ #define ALI_CACHE_FLUSH_EN 0x100 /* ATI register */ -#define ATI_APBASE 0x10 -#define ATI_GART_MMBASE_ADDR 0x14 -#define ATI_RS100_APSIZE 0xac -#define ATI_RS300_APSIZE 0xf8 -#define ATI_RS100_IG_AGPMODE 0xb0 -#define ATI_RS300_IG_AGPMODE 0xfc - -#define ATI_GART_FEATURE_ID 0x00 -#define ATI_GART_BASE 0x04 -#define ATI_GART_CACHE_SZBASE 0x08 -#define ATI_GART_CACHE_CNTRL 0x0c -#define ATI_GART_CACHE_ENTRY_CNTRL 0x10 - +#define ATI_GART_MMBASE_ADDR 0x14 +#define ATI_RS100_APSIZE 0xac +#define ATI_RS300_APSIZE 0xf8 +#define ATI_RS100_IG_AGPMODE 0xb0 +#define ATI_RS300_IG_AGPMODE 0xfc + +#define ATI_GART_FEATURE_ID 0x00 +#define ATI_GART_BASE 0x04 +#define ATI_GART_CACHE_SZBASE 0x08 +#define ATI_GART_CACHE_CNTRL 0x0c +#define ATI_GART_CACHE_ENTRY_CNTRL 0x10 /* Serverworks Registers */ #define SVWRKS_APSIZE 0x10 @@ -369,6 +354,17 @@ #define HP_ZX1_PDIR_BASE 0x320 #define HP_ZX1_CACHE_FLUSH 0x428 +/* NVIDIA registers */ +#define NVIDIA_0_APSIZE 0x80 +#define NVIDIA_1_WBC 0xf0 +#define NVIDIA_2_GARTCTRL 0xd0 +#define NVIDIA_2_APBASE 0xd8 +#define NVIDIA_2_APLIMIT 0xdc +#define NVIDIA_2_ATTBASE(i) (0xe0 + (i) * 4) +#define NVIDIA_3_APBASE 0x50 +#define NVIDIA_3_APLIMIT 0x54 + + struct agp_device_ids { unsigned short device_id; /* first, to make table easier to read */ enum chipset_type chipset; @@ -405,6 +401,9 @@ void global_cache_flush(void); void get_agp_version(struct agp_bridge_data *bridge); unsigned long agp_generic_mask_memory(unsigned long addr, int type); + +extern int agp_off; +extern int agp_try_unsupported_boot; /* Standard agp registers */ #define AGPSTAT 0x4 diff -Nru a/drivers/char/agp/ali-agp.c b/drivers/char/agp/ali-agp.c --- a/drivers/char/agp/ali-agp.c Tue Sep 2 19:58:17 2003 +++ b/drivers/char/agp/ali-agp.c Tue Sep 2 19:58:17 2003 @@ -76,7 +76,7 @@ pci_write_config_dword(agp_bridge->dev, ALI_TLBCTRL, ((temp & 0xffffff00) | 0x00000010)); /* address to map to */ - pci_read_config_dword(agp_bridge->dev, ALI_APBASE, &temp); + pci_read_config_dword(agp_bridge->dev, AGP_APBASE, &temp); agp_bridge->gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK); #if 0 diff -Nru a/drivers/char/agp/amd-k7-agp.c b/drivers/char/agp/amd-k7-agp.c --- a/drivers/char/agp/amd-k7-agp.c Tue Sep 2 19:58:20 2003 +++ b/drivers/char/agp/amd-k7-agp.c Tue Sep 2 19:58:20 2003 @@ -148,7 +148,7 @@ * used to program the agp master not the cpu */ - pci_read_config_dword(agp_bridge->dev, AMD_APBASE, &temp); + pci_read_config_dword(agp_bridge->dev, AGP_APBASE, &temp); addr = (temp & PCI_BASE_ADDRESS_MEM_MASK); agp_bridge->gart_bus_addr = addr; diff -Nru a/drivers/char/agp/amd-k8-agp.c b/drivers/char/agp/amd-k8-agp.c --- a/drivers/char/agp/amd-k8-agp.c Tue Sep 2 19:58:17 2003 +++ b/drivers/char/agp/amd-k8-agp.c Tue Sep 2 19:58:17 2003 @@ -8,12 +8,6 @@ * work is done in the northbridge(s). */ -/* - * On x86-64 the AGP driver needs to be initialized early by the IOMMU - * code. When you use this driver as a template for a new K8 AGP bridge - * driver don't forget to change arch/x86_64/kernel/pci-gart.c too -AK. - */ - #include #include #include @@ -21,7 +15,11 @@ #include "agp.h" /* Will need to be increased if hammer ever goes >8-way. */ +#ifdef CONFIG_SMP #define MAX_HAMMER_GARTS 8 +#else +#define MAX_HAMMER_GARTS 1 +#endif /* PTE bits. */ #define GPTE_VALID 1 @@ -39,6 +37,8 @@ static int nr_garts; static struct pci_dev * hammers[MAX_HAMMER_GARTS]; +static int __initdata agp_try_unsupported; + static int gart_iterator; #define for_each_nb() for(gart_iterator=0;gart_iterator>= 12; tmp = (u32) addr<<4; tmp &= ~0xf; - pci_write_config_dword (hammer, AMD_X86_64_GARTTABLEBASE, tmp); + pci_write_config_dword (hammer, AMD64_GARTTABLEBASE, tmp); /* Enable GART translation for this hammer. */ - pci_read_config_dword(hammer, AMD_X86_64_GARTAPERTURECTL, &tmp); + pci_read_config_dword(hammer, AMD64_GARTAPERTURECTL, &tmp); tmp |= GARTEN; tmp &= ~(DISGARTCPU | DISGARTIO); - pci_write_config_dword(hammer, AMD_X86_64_GARTAPERTURECTL, tmp); + pci_write_config_dword(hammer, AMD64_GARTAPERTURECTL, tmp); /* keep CPU's coherent. */ flush_x86_64_tlb (hammer); @@ -216,9 +216,9 @@ for_each_nb() { /* disable gart translation */ - pci_read_config_dword (hammers[gart_iterator], AMD_X86_64_GARTAPERTURECTL, &tmp); - tmp &= ~(AMD_X86_64_GARTEN); - pci_write_config_dword (hammers[gart_iterator], AMD_X86_64_GARTAPERTURECTL, tmp); + pci_read_config_dword (hammers[gart_iterator], AMD64_GARTAPERTURECTL, &tmp); + tmp &= ~AMD64_GARTEN; + pci_write_config_dword (hammers[gart_iterator], AMD64_GARTAPERTURECTL, tmp); } } @@ -246,24 +246,123 @@ .agp_destroy_page = agp_generic_destroy_page, }; +/* Some basic sanity checks for the aperture. */ +static int __init aperture_valid(u64 aper, u32 size) +{ + static int not_first_call; + u32 pfn, c; + if (aper == 0) { + printk(KERN_ERR "No aperture\n"); + return 0; + } + if (size < 32*1024*1024) { + printk(KERN_ERR "Aperture too small (%d MB)\n", size>>20); + return 0; + } + if (aper + size > 0xffffffff) { + printk(KERN_ERR "Aperture out of bounds\n"); + return 0; + } + pfn = aper >> PAGE_SHIFT; + for (c = 0; c < size/PAGE_SIZE; c++) { + if (!pfn_valid(pfn + c)) + break; + if (!PageReserved(pfn_to_page(pfn + c))) { + printk(KERN_ERR "Aperture pointing to RAM\n"); + return 0; + } + } -#ifdef CONFIG_SMP -static int cache_nbs (void) + /* Request the Aperture. This catches cases when someone else + already put a mapping in there - happens with some very broken BIOS + + Maybe better to use pci_assign_resource/pci_enable_device instead trusting + the bridges? */ + if (!not_first_call && request_mem_region(aper, size, "aperture") < 0) { + printk(KERN_ERR "Aperture conflicts with PCI mapping.\n"); + return 0; + } + + not_first_call = 1; + return 1; +} + +/* + * W*s centric BIOS sometimes only set up the aperture in the AGP + * bridge, not the northbridge. On AMD64 this is handled early + * in aperture.c, but when GART_IOMMU is not enabled or we run + * on a 32bit kernel this needs to be redone. + * Unfortunately it is impossible to fix the aperture here because it's too late + * to allocate that much memory. But at least error out cleanly instead of + * crashing. + */ +static __init int fix_northbridge(struct pci_dev *nb, struct pci_dev *agp, + u16 cap) +{ + u32 aper_low, aper_hi; + u64 aper, nb_aper; + int order = 0; + u32 nb_order, nb_base; + u16 apsize; + + pci_read_config_dword(nb, 0x90, &nb_order); + nb_order = (nb_order >> 1) & 7; + pci_read_config_dword(nb, 0x94, &nb_base); + nb_aper = nb_base << 25; + if (aperture_valid(nb_aper, (32*1024*1024)<> 25); + + return 0; +} + +static __init int cache_nbs (struct pci_dev *pdev, u32 cap_ptr) { struct pci_dev *loop_dev = NULL; int i = 0; /* cache pci_devs of northbridges. */ - while ((loop_dev = pci_find_device(PCI_VENDOR_ID_AMD, 0x1103, loop_dev)) != NULL) { + while ((loop_dev = pci_find_device(PCI_VENDOR_ID_AMD, 0x1103, loop_dev)) + != NULL) { + if (fix_northbridge(loop_dev, pdev, cap_ptr) < 0) { + printk("No usable aperture found.\n"); +#ifdef __x86_64__ + /* should port this to i386 */ + printk("Consider rebooting with iommu=memaper=2 to get a good aperture.\n"); +#endif + return -1; + } hammers[i++] = loop_dev; nr_garts = i; - if (i == MAX_HAMMER_GARTS) + if (i == MAX_HAMMER_GARTS) { + printk(KERN_INFO "Too many northbridges for AGP\n"); return -1; + } } - return 0; + return i == 0 ? -1 : 0; } -#endif - static int __init agp_amdk8_probe(struct pci_dev *pdev, const struct pci_device_id *ent) @@ -277,7 +376,7 @@ if (!cap_ptr) return -ENODEV; - printk(KERN_INFO PFX "Detected Opteron/Athlon64 on-CPU GART\n"); + /* Could check for AGPv3 here */ bridge = agp_alloc_bridge(); if (!bridge) @@ -311,6 +410,9 @@ bridge->major_version = 3; bridge->minor_version = 0; } + } else { + printk(KERN_INFO PFX "Detected AGP bridge %x\n", + pdev->devfn); } bridge->driver = &amd_8151_driver; @@ -320,22 +422,10 @@ /* Fill in the mode register */ pci_read_config_dword(pdev, bridge->capndx+PCI_AGP_STATUS, &bridge->mode); -#ifdef CONFIG_SMP - if (cache_nbs() == -1) { + if (cache_nbs(pdev, cap_ptr) == -1) { agp_put_bridge(bridge); - return -ENOMEM; - } -#else - { - struct pci_dev *loop_dev = NULL; - while ((loop_dev = pci_find_device(PCI_VENDOR_ID_AMD, 0x1103, loop_dev)) != NULL) { - /* For UP, we only care about the first GART. */ - hammers[0] = loop_dev; - nr_garts = 1; - break; - } + return -ENODEV; } -#endif pci_set_drvdata(pdev, bridge); return agp_add_bridge(bridge); @@ -345,6 +435,8 @@ { struct agp_bridge_data *bridge = pci_get_drvdata(pdev); + release_mem_region(virt_to_phys(bridge->gatt_table_real), + x86_64_aperture_sizes[bridge->aperture_size_idx].size); agp_remove_bridge(bridge); agp_put_bridge(bridge); } @@ -358,11 +450,21 @@ .subvendor = PCI_ANY_ID, .subdevice = PCI_ANY_ID, }, + /* VIA K8T800 */ { .class = (PCI_CLASS_BRIDGE_HOST << 8), .class_mask = ~0, .vendor = PCI_VENDOR_ID_VIA, - .device = PCI_DEVICE_ID_VIA_K8T400M_0, + .device = PCI_DEVICE_ID_VIA_8385_0, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, + }, + /* VIA K8M800 / K8N800 */ + { + .class = (PCI_CLASS_BRIDGE_HOST << 8), + .class_mask = ~0, + .vendor = PCI_VENDOR_ID_VIA, + .device = PCI_DEVICE_ID_VIA_8380_0, .subvendor = PCI_ANY_ID, .subdevice = PCI_ANY_ID, }, @@ -386,10 +488,43 @@ .remove = agp_amdk8_remove, }; + /* Not static due to IOMMU code calling it early. */ int __init agp_amdk8_init(void) { - return pci_module_init(&agp_amdk8_pci_driver); + int err = 0; + if (agp_off) + return -EINVAL; + if (pci_module_init(&agp_amdk8_pci_driver) == 0) { + struct pci_dev *dev; + if (!agp_try_unsupported && !agp_try_unsupported_boot) { + printk(KERN_INFO "No supported AGP bridge found.\n"); +#ifdef MODULE + printk(KERN_INFO "You can try agp_try_unsupported=1\n"); +#else + printk(KERN_INFO "You can boot with agp=try_unsupported\n"); +#endif + return -ENODEV; + } + + /* First check that we have at least one K8 NB */ + if (!pci_find_device(PCI_VENDOR_ID_AMD, 0x1103, NULL)) + return -ENODEV; + + /* Look for any AGP bridge */ + dev = NULL; + err = -ENODEV; + while ((dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev))) { + if (!pci_find_capability(dev, PCI_CAP_ID_AGP)) + continue; + /* Only one bridge supported right now */ + if (agp_amdk8_probe(dev, NULL) == 0) { + err = 0; + break; + } + } + } + return err; } static void __exit agp_amdk8_cleanup(void) @@ -404,6 +539,6 @@ module_exit(agp_amdk8_cleanup); #endif -MODULE_AUTHOR("Dave Jones "); +MODULE_AUTHOR("Dave Jones , Andi Kleen"); +MODULE_PARM(agp_try_unsupported, "1i"); MODULE_LICENSE("GPL and additional rights"); - diff -Nru a/drivers/char/agp/ati-agp.c b/drivers/char/agp/ati-agp.c --- a/drivers/char/agp/ati-agp.c Tue Sep 2 19:58:17 2003 +++ b/drivers/char/agp/ati-agp.c Tue Sep 2 19:58:17 2003 @@ -1,5 +1,5 @@ /* - * ALi AGPGART routines. + * ATi AGPGART routines. */ #include @@ -212,7 +212,7 @@ /* address to map too */ /* - pci_read_config_dword(agp_bridge.dev, ATI_APBASE, &temp); + pci_read_config_dword(agp_bridge.dev, AGP_APBASE, &temp); agp_bridge.gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK); printk(KERN_INFO "IGP320 gart_bus_addr: %x\n", agp_bridge.gart_bus_addr); */ @@ -355,7 +355,7 @@ * This is a bus address even on the alpha, b/c its * used to program the agp master not the cpu */ - pci_read_config_dword(agp_bridge->dev, ATI_APBASE, &temp); + pci_read_config_dword(agp_bridge->dev, AGP_APBASE, &temp); addr = (temp & PCI_BASE_ADDRESS_MEM_MASK); agp_bridge->gart_bus_addr = addr; diff -Nru a/drivers/char/agp/backend.c b/drivers/char/agp/backend.c --- a/drivers/char/agp/backend.c Tue Sep 2 19:58:17 2003 +++ b/drivers/char/agp/backend.c Tue Sep 2 19:58:17 2003 @@ -301,9 +301,14 @@ } EXPORT_SYMBOL_GPL(agp_remove_bridge); +int agp_off; +int agp_try_unsupported_boot; +EXPORT_SYMBOL(agp_off); +EXPORT_SYMBOL(agp_try_unsupported_boot); static int __init agp_init(void) { + if (!agp_off) printk(KERN_INFO "Linux agpgart interface v%d.%d (c) Dave Jones\n", AGPGART_VERSION_MAJOR, AGPGART_VERSION_MINOR); return 0; @@ -313,6 +318,15 @@ { } +static __init int agp_setup(char *s) +{ + if (!strcmp(s,"off")) + agp_off = 1; + if (!strcmp(s,"try_unsupported")) + agp_try_unsupported_boot = 1; + return 1; +} +__setup("agp=", agp_setup); MODULE_AUTHOR("Dave Jones "); MODULE_DESCRIPTION("AGP GART driver"); diff -Nru a/drivers/char/agp/frontend.c b/drivers/char/agp/frontend.c --- a/drivers/char/agp/frontend.c Tue Sep 2 19:58:13 2003 +++ b/drivers/char/agp/frontend.c Tue Sep 2 19:58:13 2003 @@ -698,7 +698,7 @@ static int agp_open(struct inode *inode, struct file *file) { - int minor = minor(inode->i_rdev); + int minor = iminor(inode); struct agp_file_private *priv; struct agp_client *client; int rc = -ENXIO; diff -Nru a/drivers/char/agp/generic.c b/drivers/char/agp/generic.c --- a/drivers/char/agp/generic.c Tue Sep 2 19:58:15 2003 +++ b/drivers/char/agp/generic.c Tue Sep 2 19:58:15 2003 @@ -577,12 +577,12 @@ agp_device_command(command, TRUE); return; } else { - /* Disable calibration cycle in RX91<1> when not in AGP3.0 mode of operation.*/ + /* Disable calibration cycle in RX91<1> when not in AGP3.0 mode of operation.*/ command &= ~(7<<10) ; pci_read_config_dword(agp_bridge->dev, agp_bridge->capndx+AGPCTRL, &temp); temp |= (1<<9); pci_write_config_dword(agp_bridge->dev, agp_bridge->capndx+AGPCTRL, temp); - + printk (KERN_INFO PFX "Device is in legacy mode," " falling back to 2.x\n"); } diff -Nru a/drivers/char/agp/intel-agp.c b/drivers/char/agp/intel-agp.c --- a/drivers/char/agp/intel-agp.c Tue Sep 2 19:58:15 2003 +++ b/drivers/char/agp/intel-agp.c Tue Sep 2 19:58:15 2003 @@ -618,7 +618,7 @@ pci_write_config_word(agp_bridge->dev, INTEL_APSIZE, current_size->size_value); /* address to map to */ - pci_read_config_dword(agp_bridge->dev, INTEL_APBASE, &temp); + pci_read_config_dword(agp_bridge->dev, AGP_APBASE, &temp); agp_bridge->gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK); /* attbase - aperture base */ @@ -657,7 +657,7 @@ current_size->size_value); /* address to map to */ - pci_read_config_dword(agp_bridge->dev, INTEL_APBASE, &temp); + pci_read_config_dword(agp_bridge->dev, AGP_APBASE, &temp); agp_bridge->gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK); pci_read_config_dword(agp_bridge->dev, INTEL_ATTBASE, &addr); @@ -708,7 +708,7 @@ pci_write_config_byte(agp_bridge->dev, INTEL_APSIZE, current_size->size_value); /* address to map to */ - pci_read_config_dword(agp_bridge->dev, INTEL_APBASE, &temp); + pci_read_config_dword(agp_bridge->dev, AGP_APBASE, &temp); agp_bridge->gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK); /* attbase - aperture base */ @@ -739,7 +739,7 @@ pci_write_config_byte(agp_bridge->dev, INTEL_APSIZE, current_size->size_value); /* address to map to */ - pci_read_config_dword(agp_bridge->dev, INTEL_APBASE, &temp); + pci_read_config_dword(agp_bridge->dev, AGP_APBASE, &temp); agp_bridge->gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK); /* attbase - aperture base */ @@ -768,7 +768,7 @@ pci_write_config_byte(agp_bridge->dev, INTEL_APSIZE, current_size->size_value); /* address to map to */ - pci_read_config_dword(agp_bridge->dev, INTEL_APBASE, &temp); + pci_read_config_dword(agp_bridge->dev, AGP_APBASE, &temp); agp_bridge->gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK); /* attbase - aperture base */ @@ -797,7 +797,7 @@ pci_write_config_byte(agp_bridge->dev, INTEL_APSIZE, current_size->size_value); /* address to map to */ - pci_read_config_dword(agp_bridge->dev, INTEL_APBASE, &temp); + pci_read_config_dword(agp_bridge->dev, AGP_APBASE, &temp); agp_bridge->gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK); /* attbase - aperture base */ @@ -826,7 +826,7 @@ pci_write_config_byte(agp_bridge->dev, INTEL_APSIZE, current_size->size_value); /* address to map to */ - pci_read_config_dword(agp_bridge->dev, INTEL_APBASE, &temp); + pci_read_config_dword(agp_bridge->dev, AGP_APBASE, &temp); agp_bridge->gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK); /* attbase - aperture base */ @@ -855,7 +855,7 @@ pci_write_config_byte(agp_bridge->dev, INTEL_APSIZE, current_size->size_value); /* address to map to */ - pci_read_config_dword(agp_bridge->dev, INTEL_APBASE, &temp); + pci_read_config_dword(agp_bridge->dev, AGP_APBASE, &temp); agp_bridge->gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK); /* attbase - aperture base */ @@ -884,7 +884,7 @@ pci_write_config_byte(agp_bridge->dev, INTEL_APSIZE, current_size->size_value); /* address to map to */ - pci_read_config_dword(agp_bridge->dev, INTEL_APBASE, &temp); + pci_read_config_dword(agp_bridge->dev, AGP_APBASE, &temp); agp_bridge->gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK); /* attbase - aperture base */ diff -Nru a/drivers/char/agp/nvidia-agp.c b/drivers/char/agp/nvidia-agp.c --- a/drivers/char/agp/nvidia-agp.c Tue Sep 2 19:58:13 2003 +++ b/drivers/char/agp/nvidia-agp.c Tue Sep 2 19:58:13 2003 @@ -13,18 +13,6 @@ #include #include "agp.h" - -/* registers */ -#define NVIDIA_0_APBASE 0x10 -#define NVIDIA_0_APSIZE 0x80 -#define NVIDIA_1_WBC 0xf0 -#define NVIDIA_2_GARTCTRL 0xd0 -#define NVIDIA_2_APBASE 0xd8 -#define NVIDIA_2_APLIMIT 0xdc -#define NVIDIA_2_ATTBASE(i) (0xe0 + (i) * 4) -#define NVIDIA_3_APBASE 0x50 -#define NVIDIA_3_APLIMIT 0x54 - static struct _nvidia_private { struct pci_dev *dev_1; struct pci_dev *dev_2; @@ -73,7 +61,7 @@ current_size->size_value); /* address to map to */ - pci_read_config_dword(agp_bridge->dev, NVIDIA_0_APBASE, &apbase); + pci_read_config_dword(agp_bridge->dev, AGP_APBASE, &apbase); apbase &= PCI_BASE_ADDRESS_MEM_MASK; agp_bridge->gart_bus_addr = apbase; aplimit = apbase + (current_size->size * 1024 * 1024) - 1; diff -Nru a/drivers/char/agp/sis-agp.c b/drivers/char/agp/sis-agp.c --- a/drivers/char/agp/sis-agp.c Tue Sep 2 19:58:13 2003 +++ b/drivers/char/agp/sis-agp.c Tue Sep 2 19:58:13 2003 @@ -43,7 +43,7 @@ current_size = A_SIZE_8(agp_bridge->current_size); pci_write_config_byte(agp_bridge->dev, SIS_TLBCNTRL, 0x05); - pci_read_config_dword(agp_bridge->dev, SIS_APBASE, &temp); + pci_read_config_dword(agp_bridge->dev, AGP_APBASE, &temp); agp_bridge->gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK); pci_write_config_dword(agp_bridge->dev, SIS_ATTBASE, agp_bridge->gatt_bus_addr); diff -Nru a/drivers/char/agp/via-agp.c b/drivers/char/agp/via-agp.c --- a/drivers/char/agp/via-agp.c Tue Sep 2 19:58:18 2003 +++ b/drivers/char/agp/via-agp.c Tue Sep 2 19:58:18 2003 @@ -39,7 +39,7 @@ pci_write_config_byte(agp_bridge->dev, VIA_APSIZE, current_size->size_value); /* address to map too */ - pci_read_config_dword(agp_bridge->dev, VIA_APBASE, &temp); + pci_read_config_dword(agp_bridge->dev, AGP_APBASE, &temp); agp_bridge->gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK); /* GART control register */ @@ -114,7 +114,7 @@ current_size = A_SIZE_16(agp_bridge->current_size); /* address to map too */ - pci_read_config_dword(agp_bridge->dev, VIA_APBASE, &temp); + pci_read_config_dword(agp_bridge->dev, AGP_APBASE, &temp); agp_bridge->gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK); /* attbase - aperture GATT base */ @@ -215,52 +215,52 @@ { { .device_id = PCI_DEVICE_ID_VIA_82C597_0, - .chipset_name = "VP3", + .chipset_name = "Apollo VP3", }, { .device_id = PCI_DEVICE_ID_VIA_82C598_0, - .chipset_name = "MVP3", + .chipset_name = "Apollo MVP3", }, { .device_id = PCI_DEVICE_ID_VIA_8501_0, - .chipset_name = "MVP4", + .chipset_name = "Apollo MVP4", }, /* VT8601 */ { .device_id = PCI_DEVICE_ID_VIA_8601_0, - .chipset_name = "PLE133 ProMedia", + .chipset_name = "Apollo ProMedia/PLE133Ta", }, /* VT82C693A / VT28C694T */ { - .device_id = PCI_DEVICE_ID_VIA_82C691, + .device_id = PCI_DEVICE_ID_VIA_82C691_0, .chipset_name = "Apollo Pro 133", }, { .device_id = PCI_DEVICE_ID_VIA_8371_0, - .chipset_name = "Apollo Pro KX133", + .chipset_name = "KX133", }, /* VT8633 */ { .device_id = PCI_DEVICE_ID_VIA_8633_0, - .chipset_name = "Apollo Pro 266", + .chipset_name = "Pro 266", }, /* VT8361 */ { .device_id = PCI_DEVICE_ID_VIA_8361, - .chipset_name = "Apollo KLE133", + .chipset_name = "KLE133", }, /* VT8365 / VT8362 */ { .device_id = PCI_DEVICE_ID_VIA_8363_0, - .chipset_name = "Apollo Pro KT133/KM133/TwisterK", + .chipset_name = "Twister-K/KT133x/KM133", }, /* VT8753A */ @@ -272,79 +272,79 @@ /* VT8366 */ { .device_id = PCI_DEVICE_ID_VIA_8367_0, - .chipset_name = "Apollo Pro KT266/KT333", + .chipset_name = "KT266/KY266x/KT333", }, /* VT8633 (for CuMine/ Celeron) */ { .device_id = PCI_DEVICE_ID_VIA_8653_0, - .chipset_name = "Apollo Pro 266T", + .chipset_name = "Pro266T", }, /* KM266 / PM266 */ { - .device_id = PCI_DEVICE_ID_VIA_KM266, - .chipset_name = "KM266/PM266", + .device_id = PCI_DEVICE_ID_VIA_XM266, + .chipset_name = "PM266/KM266", }, /* CLE266 */ { - .device_id = PCI_DEVICE_ID_VIA_CLE266, + .device_id = PCI_DEVICE_ID_VIA_862X_0, .chipset_name = "CLE266", }, { .device_id = PCI_DEVICE_ID_VIA_8377_0, - .chipset_name = "Apollo Pro KT400", + .chipset_name = "KT400/KT400A/KT600", }, - /* VT8604 / VT8605 / VT8603 / TwisterT + /* VT8604 / VT8605 / VT8603 * (Apollo Pro133A chipset with S3 Savage4) */ { - .device_id = PCI_DEVICE_ID_VIA_82C694X_0, - .chipset_name = "Apollo ProSavage PM133/PL133/PN133/Twister" + .device_id = PCI_DEVICE_ID_VIA_8605_0, + .chipset_name = "ProSavage PM133/PL133/PN133" }, - /* VT8752*/ + /* P4M266x/P4N266 */ { - .device_id = PCI_DEVICE_ID_VIA_8752, - .chipset_name = "ProSavage DDR P4M266", + .device_id = PCI_DEVICE_ID_VIA_8703_51_0, + .chipset_name = "P4M266x/P4N266", }, - /* KN266/PN266 */ + /* VT8754 */ { - .device_id = PCI_DEVICE_ID_VIA_KN266, - .chipset_name = "KN266/PN266", + .device_id = PCI_DEVICE_ID_VIA_8754C_0, + .chipset_name = "PT800", }, - /* VT8754 */ + /* P4X600 */ { - .device_id = PCI_DEVICE_ID_VIA_8754, - .chipset_name = "Apollo P4X333/P4X400" + .device_id = PCI_DEVICE_ID_VIA_8763_0, + .chipset_name = "P4X600" }, - /* P4N333 */ + /* KM400 */ { - .device_id = PCI_DEVICE_ID_VIA_P4N333, - .chipset_name = "P4N333", + .device_id = PCI_DEVICE_ID_VIA_8378_0, + .chipset_name = "KM400/KM400A", }, - /* P4X600 */ + /* PT880 */ { - .device_id = PCI_DEVICE_ID_VIA_P4X600, - .chipset_name = "P4X600", + .device_id = PCI_DEVICE_ID_VIA_PT880, + .chipset_name = "PT880", }, - /* KM400 */ + /* PT890 */ { - .device_id = PCI_DEVICE_ID_VIA_KM400, - .chipset_name = "KM400", + .device_id = PCI_DEVICE_ID_VIA_8783_0, + .chipset_name = "PT890", }, - /* P4M400 */ + /* PM800/PN800/PM880/PN880 */ { - .device_id = PCI_DEVICE_ID_VIA_P4M400, - .chipset_name = "P4M400", + .device_id = PCI_DEVICE_ID_VIA_PX8X0_0, + .chipset_name = "PM800/PN800/PM880/PN880", }, { }, /* dummy final entry, always present */ diff -Nru a/drivers/char/busmouse.c b/drivers/char/busmouse.c --- a/drivers/char/busmouse.c Tue Sep 2 19:58:18 2003 +++ b/drivers/char/busmouse.c Tue Sep 2 19:58:18 2003 @@ -51,7 +51,7 @@ #define NR_MICE 15 #define FIRST_MOUSE 0 -#define DEV_TO_MOUSE(dev) MINOR_TO_MOUSE(minor(dev)) +#define DEV_TO_MOUSE(inode) MINOR_TO_MOUSE(iminor(inode)) #define MINOR_TO_MOUSE(minor) ((minor) - FIRST_MOUSE) /* @@ -190,7 +190,7 @@ unsigned int mousedev; int ret; - mousedev = DEV_TO_MOUSE(inode->i_rdev); + mousedev = DEV_TO_MOUSE(inode); if (mousedev >= NR_MICE) return -EINVAL; diff -Nru a/drivers/char/cyclades.c b/drivers/char/cyclades.c --- a/drivers/char/cyclades.c Tue Sep 2 19:58:14 2003 +++ b/drivers/char/cyclades.c Tue Sep 2 19:58:14 2003 @@ -1050,14 +1050,14 @@ udelay(5000L); /* Enable the Tx interrupts on the CD1400 */ - save_flags(flags); cli(); + local_irq_save(flags); cy_writeb((u_long)address + (CyCAR<i_rdev) == DRM(minor)[i]) { + if (iminor(inode) == DRM(minor)[i]) { dev = &(DRM(device)[i]); break; } diff -Nru a/drivers/char/drm/drm_fops.h b/drivers/char/drm/drm_fops.h --- a/drivers/char/drm/drm_fops.h Tue Sep 2 19:58:16 2003 +++ b/drivers/char/drm/drm_fops.h Tue Sep 2 19:58:16 2003 @@ -51,7 +51,7 @@ */ int DRM(open_helper)(struct inode *inode, struct file *filp, drm_device_t *dev) { - int minor = minor(inode->i_rdev); + int minor = iminor(inode); drm_file_t *priv; if (filp->f_flags & O_EXCL) return -EBUSY; /* No exclusive opens */ diff -Nru a/drivers/char/drm/drm_stub.h b/drivers/char/drm/drm_stub.h --- a/drivers/char/drm/drm_stub.h Tue Sep 2 19:58:18 2003 +++ b/drivers/char/drm/drm_stub.h Tue Sep 2 19:58:18 2003 @@ -62,7 +62,7 @@ */ static int DRM(stub_open)(struct inode *inode, struct file *filp) { - int minor = minor(inode->i_rdev); + int minor = iminor(inode); int err = -ENODEV; struct file_operations *old_fops; diff -Nru a/drivers/char/dsp56k.c b/drivers/char/dsp56k.c --- a/drivers/char/dsp56k.c Tue Sep 2 19:58:16 2003 +++ b/drivers/char/dsp56k.c Tue Sep 2 19:58:16 2003 @@ -207,7 +207,7 @@ loff_t *ppos) { struct inode *inode = file->f_dentry->d_inode; - int dev = minor(inode->i_rdev) & 0x0f; + int dev = iminor(inode) & 0x0f; switch(dev) { @@ -270,7 +270,7 @@ loff_t *ppos) { struct inode *inode = file->f_dentry->d_inode; - int dev = minor(inode->i_rdev) & 0x0f; + int dev = iminor(inode) & 0x0f; switch(dev) { @@ -331,7 +331,7 @@ static int dsp56k_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) { - int dev = minor(inode->i_rdev) & 0x0f; + int dev = iminor(inode) & 0x0f; switch(dev) { @@ -424,7 +424,7 @@ #if 0 static unsigned int dsp56k_poll(struct file *file, poll_table *wait) { - int dev = minor(file->f_dentry->d_inode->i_rdev) & 0x0f; + int dev = iminor(file->f_dentry->d_inode) & 0x0f; switch(dev) { @@ -441,7 +441,7 @@ static int dsp56k_open(struct inode *inode, struct file *file) { - int dev = minor(inode->i_rdev) & 0x0f; + int dev = iminor(inode) & 0x0f; switch(dev) { @@ -472,7 +472,7 @@ static int dsp56k_release(struct inode *inode, struct file *file) { - int dev = minor(inode->i_rdev) & 0x0f; + int dev = iminor(inode) & 0x0f; switch(dev) { diff -Nru a/drivers/char/dtlk.c b/drivers/char/dtlk.c --- a/drivers/char/dtlk.c Tue Sep 2 19:58:15 2003 +++ b/drivers/char/dtlk.c Tue Sep 2 19:58:15 2003 @@ -125,7 +125,7 @@ static ssize_t dtlk_read(struct file *file, char *buf, size_t count, loff_t * ppos) { - unsigned int minor = minor(file->f_dentry->d_inode->i_rdev); + unsigned int minor = iminor(file->f_dentry->d_inode); char ch; int i = 0, retries; @@ -185,7 +185,7 @@ if (ppos != &file->f_pos) return -ESPIPE; - if (minor(file->f_dentry->d_inode->i_rdev) != DTLK_MINOR) + if (iminor(file->f_dentry->d_inode) != DTLK_MINOR) return -EINVAL; while (1) { @@ -304,7 +304,7 @@ { TRACE_TEXT("(dtlk_open"); - switch (minor(inode->i_rdev)) { + switch (iminor(inode)) { case DTLK_MINOR: if (dtlk_busy) return -EBUSY; @@ -319,7 +319,7 @@ { TRACE_TEXT("(dtlk_release"); - switch (minor(inode->i_rdev)) { + switch (iminor(inode)) { case DTLK_MINOR: break; diff -Nru a/drivers/char/epca.c b/drivers/char/epca.c --- a/drivers/char/epca.c Tue Sep 2 19:58:16 2003 +++ b/drivers/char/epca.c Tue Sep 2 19:58:16 2003 @@ -40,6 +40,7 @@ #include #include #include +#include #include #include diff -Nru a/drivers/char/ftape/lowlevel/fdc-io.c b/drivers/char/ftape/lowlevel/fdc-io.c --- a/drivers/char/ftape/lowlevel/fdc-io.c Tue Sep 2 19:58:14 2003 +++ b/drivers/char/ftape/lowlevel/fdc-io.c Tue Sep 2 19:58:14 2003 @@ -1305,7 +1305,7 @@ } else { TRACE(ft_t_bug, "Unexpected ftape interrupt"); } - return IRQ_RETVAL(handled); + TRACE_EXIT IRQ_RETVAL(handled); } int fdc_grab_irq_and_dma(void) diff -Nru a/drivers/char/ftape/zftape/zftape-init.c b/drivers/char/ftape/zftape/zftape-init.c --- a/drivers/char/ftape/zftape/zftape-init.c Tue Sep 2 19:58:15 2003 +++ b/drivers/char/ftape/zftape/zftape-init.c Tue Sep 2 19:58:15 2003 @@ -110,11 +110,11 @@ int result; TRACE_FUN(ft_t_flow); - TRACE(ft_t_flow, "called for minor %d", minor(ino->i_rdev)); + TRACE(ft_t_flow, "called for minor %d", iminor(ino)); if ( test_and_set_bit(0,&busy_flag) ) { TRACE_ABORT(-EBUSY, ft_t_warn, "failed: already busy"); } - if ((minor(ino->i_rdev) & ~(ZFT_MINOR_OP_MASK | FTAPE_NO_REWIND)) + if ((iminor(ino) & ~(ZFT_MINOR_OP_MASK | FTAPE_NO_REWIND)) > FTAPE_SEL_D) { clear_bit(0,&busy_flag); @@ -122,7 +122,7 @@ } orig_sigmask = current->blocked; sigfillset(¤t->blocked); - result = _zft_open(minor(ino->i_rdev), filep->f_flags & O_ACCMODE); + result = _zft_open(iminor(ino), filep->f_flags & O_ACCMODE); if (result < 0) { current->blocked = orig_sigmask; /* restore mask */ clear_bit(0,&busy_flag); @@ -144,7 +144,7 @@ int result; TRACE_FUN(ft_t_flow); - if ( !test_bit(0,&busy_flag) || minor(ino->i_rdev) != zft_unit) { + if ( !test_bit(0,&busy_flag) || iminor(ino) != zft_unit) { TRACE(ft_t_err, "failed: not busy or wrong unit"); TRACE_EXIT 0; } @@ -167,7 +167,7 @@ sigset_t old_sigmask; TRACE_FUN(ft_t_flow); - if ( !test_bit(0,&busy_flag) || minor(ino->i_rdev) != zft_unit || ft_failure) { + if ( !test_bit(0,&busy_flag) || iminor(ino) != zft_unit || ft_failure) { TRACE_ABORT(-EIO, ft_t_err, "failed: not busy, failure or wrong unit"); } @@ -188,7 +188,7 @@ TRACE_FUN(ft_t_flow); if ( !test_bit(0,&busy_flag) || - minor(filep->f_dentry->d_inode->i_rdev) != zft_unit || + iminor(filep->f_dentry->d_inode) != zft_unit || ft_failure) { TRACE_ABORT(-EIO, ft_t_err, @@ -217,7 +217,7 @@ TRACE_FUN(ft_t_flow); TRACE(ft_t_data_flow, "called with count: %ld", (unsigned long)req_len); - if (!test_bit(0,&busy_flag) || minor(ino->i_rdev) != zft_unit || ft_failure) { + if (!test_bit(0,&busy_flag) || iminor(ino) != zft_unit || ft_failure) { TRACE_ABORT(-EIO, ft_t_err, "failed: not busy, failure or wrong unit"); } @@ -240,7 +240,7 @@ TRACE_FUN(ft_t_flow); TRACE(ft_t_flow, "called with count: %ld", (unsigned long)req_len); - if (!test_bit(0,&busy_flag) || minor(ino->i_rdev) != zft_unit || ft_failure) { + if (!test_bit(0,&busy_flag) || iminor(ino) != zft_unit || ft_failure) { TRACE_ABORT(-EIO, ft_t_err, "failed: not busy, failure or wrong unit"); } diff -Nru a/drivers/char/generic_serial.c b/drivers/char/generic_serial.c --- a/drivers/char/generic_serial.c Tue Sep 2 19:58:16 2003 +++ b/drivers/char/generic_serial.c Tue Sep 2 19:58:16 2003 @@ -25,6 +25,7 @@ #include #include #include +#include #include #include diff -Nru a/drivers/char/ip2main.c b/drivers/char/ip2main.c --- a/drivers/char/ip2main.c Tue Sep 2 19:58:20 2003 +++ b/drivers/char/ip2main.c Tue Sep 2 19:58:20 2003 @@ -2733,7 +2733,7 @@ ssize_t ip2_ipl_read(struct file *pFile, char *pData, size_t count, loff_t *off ) { - unsigned int minor = minor( pFile->f_dentry->d_inode->i_rdev ); + unsigned int minor = iminor(pFile->f_dentry->d_inode); int rc = 0; #ifdef IP2DEBUG_IPL @@ -2863,7 +2863,7 @@ static int ip2_ipl_ioctl ( struct inode *pInode, struct file *pFile, UINT cmd, ULONG arg ) { - unsigned int iplminor = minor(pInode->i_rdev); + unsigned int iplminor = iminor(pInode); int rc = 0; ULONG *pIndex = (ULONG*)arg; i2eBordStrPtr pB = i2BoardPtrTable[iplminor / 4]; @@ -2998,7 +2998,7 @@ static int ip2_ipl_open( struct inode *pInode, struct file *pFile ) { - unsigned int iplminor = minor(pInode->i_rdev); + unsigned int iplminor = iminor(pInode); i2eBordStrPtr pB; i2ChanStrPtr pCh; diff -Nru a/drivers/char/ipmi/ipmi_devintf.c b/drivers/char/ipmi/ipmi_devintf.c --- a/drivers/char/ipmi/ipmi_devintf.c Tue Sep 2 19:58:18 2003 +++ b/drivers/char/ipmi/ipmi_devintf.c Tue Sep 2 19:58:18 2003 @@ -110,7 +110,7 @@ static int ipmi_open(struct inode *inode, struct file *file) { - int if_num = minor(inode->i_rdev); + int if_num = iminor(inode); int rv; struct ipmi_file_private *priv; diff -Nru a/drivers/char/ipmi/ipmi_watchdog.c b/drivers/char/ipmi/ipmi_watchdog.c --- a/drivers/char/ipmi/ipmi_watchdog.c Tue Sep 2 19:58:19 2003 +++ b/drivers/char/ipmi/ipmi_watchdog.c Tue Sep 2 19:58:19 2003 @@ -645,7 +645,7 @@ static int ipmi_open(struct inode *ino, struct file *filep) { - switch (minor(ino->i_rdev)) + switch (iminor(ino)) { case WATCHDOG_MINOR: if (ipmi_wdog_open) @@ -688,7 +688,7 @@ static int ipmi_close(struct inode *ino, struct file *filep) { - if (minor(ino->i_rdev)==WATCHDOG_MINOR) + if (iminor(ino)==WATCHDOG_MINOR) { #ifndef CONFIG_WATCHDOG_NOWAYOUT ipmi_watchdog_state = WDOG_TIMEOUT_NONE; diff -Nru a/drivers/char/istallion.c b/drivers/char/istallion.c --- a/drivers/char/istallion.c Tue Sep 2 19:58:16 2003 +++ b/drivers/char/istallion.c Tue Sep 2 19:58:17 2003 @@ -4805,7 +4805,7 @@ (int) fp, (int) buf, count, (int) offp); #endif - brdnr = minor(fp->f_dentry->d_inode->i_rdev); + brdnr = iminor(fp->f_dentry->d_inode); if (brdnr >= stli_nrbrds) return(-ENODEV); brdp = stli_brds[brdnr]; @@ -4860,7 +4860,7 @@ (int) fp, (int) buf, count, (int) offp); #endif - brdnr = minor(fp->f_dentry->d_inode->i_rdev); + brdnr = iminor(fp->f_dentry->d_inode); if (brdnr >= stli_nrbrds) return(-ENODEV); brdp = stli_brds[brdnr]; @@ -5201,7 +5201,7 @@ * Now handle the board specific ioctls. These all depend on the * minor number of the device they were called from. */ - brdnr = minor(ip->i_rdev); + brdnr = iminor(ip); if (brdnr >= STL_MAXBRDS) return(-ENODEV); brdp = stli_brds[brdnr]; diff -Nru a/drivers/char/ite_gpio.c b/drivers/char/ite_gpio.c --- a/drivers/char/ite_gpio.c Tue Sep 2 19:58:17 2003 +++ b/drivers/char/ite_gpio.c Tue Sep 2 19:58:17 2003 @@ -238,7 +238,7 @@ static int ite_gpio_open(struct inode *inode, struct file *file) { - unsigned int minor = minor(inode->i_rdev); + unsigned int minor = iminor(inode); if (minor != GPIO_MINOR) return -ENODEV; diff -Nru a/drivers/char/lcd.c b/drivers/char/lcd.c --- a/drivers/char/lcd.c Tue Sep 2 19:58:15 2003 +++ b/drivers/char/lcd.c Tue Sep 2 19:58:15 2003 @@ -551,9 +551,9 @@ */ static struct file_operations lcd_fops = { - read: lcd_read, - ioctl: lcd_ioctl, - open: lcd_open, + .read = lcd_read, + .ioctl = lcd_ioctl, + .open = lcd_open, }; static struct miscdevice lcd_dev= diff -Nru a/drivers/char/lp.c b/drivers/char/lp.c --- a/drivers/char/lp.c Tue Sep 2 19:58:12 2003 +++ b/drivers/char/lp.c Tue Sep 2 19:58:12 2003 @@ -292,7 +292,7 @@ static ssize_t lp_write(struct file * file, const char * buf, size_t count, loff_t *ppos) { - unsigned int minor = minor(file->f_dentry->d_inode->i_rdev); + unsigned int minor = iminor(file->f_dentry->d_inode); struct parport *port = lp_table[minor].dev->port; char *kbuf = lp_table[minor].lp_buffer; ssize_t retv = 0; @@ -408,7 +408,7 @@ static ssize_t lp_read(struct file * file, char * buf, size_t count, loff_t *ppos) { - unsigned int minor=minor(file->f_dentry->d_inode->i_rdev); + unsigned int minor=iminor(file->f_dentry->d_inode); struct parport *port = lp_table[minor].dev->port; ssize_t retval = 0; char *kbuf = lp_table[minor].lp_buffer; @@ -483,7 +483,7 @@ static int lp_open(struct inode * inode, struct file * file) { - unsigned int minor = minor(inode->i_rdev); + unsigned int minor = iminor(inode); if (minor >= LP_NO) return -ENXIO; @@ -540,7 +540,7 @@ static int lp_release(struct inode * inode, struct file * file) { - unsigned int minor = minor(inode->i_rdev); + unsigned int minor = iminor(inode); lp_claim_parport_or_block (&lp_table[minor]); parport_negotiate (lp_table[minor].dev->port, IEEE1284_MODE_COMPAT); @@ -555,7 +555,7 @@ static int lp_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) { - unsigned int minor = minor(inode->i_rdev); + unsigned int minor = iminor(inode); int status; int retval = 0; diff -Nru a/drivers/char/lp_old98.c b/drivers/char/lp_old98.c --- a/drivers/char/lp_old98.c Tue Sep 2 19:58:14 2003 +++ b/drivers/char/lp_old98.c Tue Sep 2 19:58:14 2003 @@ -219,7 +219,7 @@ static int lp_old98_open(struct inode * inode, struct file * file) { - if (minor(inode->i_rdev) != 0) + if (iminor(inode) != 0) return -ENXIO; if (lp.flags & LP_BUSY) diff -Nru a/drivers/char/mem.c b/drivers/char/mem.c --- a/drivers/char/mem.c Tue Sep 2 19:58:16 2003 +++ b/drivers/char/mem.c Tue Sep 2 19:58:16 2003 @@ -607,7 +607,7 @@ static int memory_open(struct inode * inode, struct file * filp) { - switch (minor(inode->i_rdev)) { + switch (iminor(inode)) { case 1: filp->f_op = &mem_fops; break; diff -Nru a/drivers/char/misc.c b/drivers/char/misc.c --- a/drivers/char/misc.c Tue Sep 2 19:58:19 2003 +++ b/drivers/char/misc.c Tue Sep 2 19:58:19 2003 @@ -100,7 +100,7 @@ static int misc_open(struct inode * inode, struct file * file) { - int minor = minor(inode->i_rdev); + int minor = iminor(inode); struct miscdevice *c; int err = -ENODEV; struct file_operations *old_fops, *new_fops = NULL; diff -Nru a/drivers/char/n_hdlc.c b/drivers/char/n_hdlc.c --- a/drivers/char/n_hdlc.c Tue Sep 2 19:58:14 2003 +++ b/drivers/char/n_hdlc.c Tue Sep 2 19:58:14 2003 @@ -182,9 +182,9 @@ /* TTY callbacks */ -static int n_hdlc_tty_read(struct tty_struct *tty, struct file *file, +static ssize_t n_hdlc_tty_read(struct tty_struct *tty, struct file *file, __u8 *buf, size_t nr); -static int n_hdlc_tty_write(struct tty_struct *tty, struct file *file, +static ssize_t n_hdlc_tty_write(struct tty_struct *tty, struct file *file, const __u8 *buf, size_t nr); static int n_hdlc_tty_ioctl(struct tty_struct *tty, struct file *file, unsigned int cmd, unsigned long arg); @@ -572,7 +572,7 @@ * * Returns the number of bytes returned or error code. */ -static int n_hdlc_tty_read(struct tty_struct *tty, struct file *file, +static ssize_t n_hdlc_tty_read(struct tty_struct *tty, struct file *file, __u8 *buf, size_t nr) { struct n_hdlc *n_hdlc = tty2n_hdlc(tty); @@ -649,7 +649,7 @@ * * Returns the number of bytes written (or error code). */ -static int n_hdlc_tty_write(struct tty_struct *tty, struct file *file, +static ssize_t n_hdlc_tty_write(struct tty_struct *tty, struct file *file, const __u8 *data, size_t count) { struct n_hdlc *n_hdlc = tty2n_hdlc (tty); @@ -658,7 +658,7 @@ struct n_hdlc_buf *tbuf; if (debuglevel >= DEBUG_LEVEL_INFO) - printk("%s(%d)n_hdlc_tty_write() called count=%d\n", + printk("%s(%d)n_hdlc_tty_write() called count=%Zd\n", __FILE__,__LINE__,count); /* Verify pointers */ @@ -673,7 +673,7 @@ if (debuglevel & DEBUG_LEVEL_INFO) printk (KERN_WARNING "n_hdlc_tty_write: truncating user packet " - "from %lu to %d\n", (unsigned long) count, + "from %lu to %Zd\n", (unsigned long) count, maxframe ); count = maxframe; } diff -Nru a/drivers/char/pcxx.c b/drivers/char/pcxx.c --- a/drivers/char/pcxx.c Tue Sep 2 19:58:16 2003 +++ b/drivers/char/pcxx.c Tue Sep 2 19:58:16 2003 @@ -121,7 +121,7 @@ MODULE_PARM(altpin, "1-4i"); MODULE_PARM(numports, "1-4i"); -#endif MODULE +#endif /* MODULE */ static int numcards = 1; static int nbdevs = 0; diff -Nru a/drivers/char/ppdev.c b/drivers/char/ppdev.c --- a/drivers/char/ppdev.c Tue Sep 2 19:58:19 2003 +++ b/drivers/char/ppdev.c Tue Sep 2 19:58:19 2003 @@ -104,7 +104,7 @@ static ssize_t pp_read (struct file * file, char * buf, size_t count, loff_t * ppos) { - unsigned int minor = minor (file->f_dentry->d_inode->i_rdev); + unsigned int minor = iminor(file->f_dentry->d_inode); struct pp_struct *pp = file->private_data; char * kbuffer; ssize_t bytes_read = 0; @@ -187,7 +187,7 @@ static ssize_t pp_write (struct file * file, const char * buf, size_t count, loff_t * ppos) { - unsigned int minor = minor (file->f_dentry->d_inode->i_rdev); + unsigned int minor = iminor(file->f_dentry->d_inode); struct pp_struct *pp = file->private_data; char * kbuffer; ssize_t bytes_written = 0; @@ -330,7 +330,7 @@ static int pp_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) { - unsigned int minor = minor(inode->i_rdev); + unsigned int minor = iminor(inode); struct pp_struct *pp = file->private_data; struct parport * port; @@ -638,7 +638,7 @@ static int pp_open (struct inode * inode, struct file * file) { - unsigned int minor = minor (inode->i_rdev); + unsigned int minor = iminor(inode); struct pp_struct *pp; if (minor >= PARPORT_MAX) @@ -667,7 +667,7 @@ static int pp_release (struct inode * inode, struct file * file) { - unsigned int minor = minor (inode->i_rdev); + unsigned int minor = iminor(inode); struct pp_struct *pp = file->private_data; int compat_negot; diff -Nru a/drivers/char/random.c b/drivers/char/random.c --- a/drivers/char/random.c Tue Sep 2 19:58:13 2003 +++ b/drivers/char/random.c Tue Sep 2 19:58:13 2003 @@ -269,9 +269,9 @@ /* * The minimum number of bits of entropy before we wake up a read on - * /dev/random. Should always be at least 8, or at least 1 byte. + * /dev/random. Should be enough to do a significant reseed. */ -static int random_read_wakeup_thresh = 8; +static int random_read_wakeup_thresh = 64; /* * If the entropy count falls under this number of bits, then we @@ -483,9 +483,9 @@ unsigned add_ptr; int entropy_count; int input_rotate; - int extract_count; struct poolinfo poolinfo; __u32 *pool; + spinlock_t lock; }; /* @@ -502,7 +502,7 @@ poolwords = (size + 3) / 4; /* Convert bytes->words */ /* The pool size must be a multiple of 16 32-bit words */ - poolwords = ((poolwords + 15) / 16) * 16; + poolwords = ((poolwords + 15) / 16) * 16; for (p = poolinfo_table; p->poolwords; p++) { if (poolwords == p->poolwords) @@ -524,6 +524,7 @@ return -ENOMEM; } memset(r->pool, 0, POOLBYTES); + r->lock = SPIN_LOCK_UNLOCKED; *ret_bucket = r; return 0; } @@ -534,7 +535,6 @@ r->add_ptr = 0; r->entropy_count = 0; r->input_rotate = 0; - r->extract_count = 0; memset(r->pool, 0, r->poolinfo.POOLBYTES); } #ifdef CONFIG_SYSCTL @@ -565,6 +565,9 @@ int new_rotate; int wordmask = r->poolinfo.poolwords - 1; __u32 w; + unsigned long flags; + + spin_lock_irqsave(&r->lock, flags); while (nwords--) { w = rotate_left(r->input_rotate, *in++); @@ -589,6 +592,8 @@ w ^= r->pool[i]; r->pool[i] = (w >> 3) ^ twist_table[w & 7]; } + + spin_unlock_irqrestore(&r->lock, flags); } /* @@ -596,6 +601,10 @@ */ static void credit_entropy_store(struct entropy_store *r, int nbits) { + unsigned long flags; + + spin_lock_irqsave(&r->lock, flags); + if (r->entropy_count + nbits < 0) { DEBUG_ENT("negative entropy/overflow (%d+%d)\n", r->entropy_count, nbits); @@ -605,11 +614,15 @@ } else { r->entropy_count += nbits; if (nbits) - DEBUG_ENT("%s added %d bits, now %d\n", + DEBUG_ENT("%04d %04d : added %d bits to %s\n", + random_state->entropy_count, + sec_random_state->entropy_count, + nbits, r == sec_random_state ? "secondary" : - r == random_state ? "primary" : "unknown", - nbits, r->entropy_count); + r == random_state ? "primary" : "unknown"); } + + spin_unlock_irqrestore(&r->lock, flags); } /********************************************************************** @@ -620,27 +633,33 @@ * **********************************************************************/ -static __u32 *batch_entropy_pool; -static int *batch_entropy_credit; -static int batch_max; +struct sample { + __u32 data[2]; + int credit; +}; + +static struct sample *batch_entropy_pool, *batch_entropy_copy; static int batch_head, batch_tail; +static spinlock_t batch_lock = SPIN_LOCK_UNLOCKED; + +static int batch_max; static void batch_entropy_process(void *private_); static DECLARE_WORK(batch_work, batch_entropy_process, NULL); /* note: the size must be a power of 2 */ static int __init batch_entropy_init(int size, struct entropy_store *r) { - batch_entropy_pool = kmalloc(2*size*sizeof(__u32), GFP_KERNEL); + batch_entropy_pool = kmalloc(size*sizeof(struct sample), GFP_KERNEL); if (!batch_entropy_pool) return -1; - batch_entropy_credit =kmalloc(size*sizeof(int), GFP_KERNEL); - if (!batch_entropy_credit) { + batch_entropy_copy = kmalloc(size*sizeof(struct sample), GFP_KERNEL); + if (!batch_entropy_copy) { kfree(batch_entropy_pool); return -1; } batch_head = batch_tail = 0; - batch_max = size; batch_work.data = r; + batch_max = size; return 0; } @@ -652,27 +671,33 @@ */ void batch_entropy_store(u32 a, u32 b, int num) { - int new; + int new; + unsigned long flags; if (!batch_max) return; - - batch_entropy_pool[2*batch_head] = a; - batch_entropy_pool[(2*batch_head) + 1] = b; - batch_entropy_credit[batch_head] = num; - new = (batch_head+1) & (batch_max-1); - if ((unsigned)(new - batch_tail) >= (unsigned)(batch_max / 2)) { + spin_lock_irqsave(&batch_lock, flags); + + batch_entropy_pool[batch_head].data[0] = a; + batch_entropy_pool[batch_head].data[1] = b; + batch_entropy_pool[batch_head].credit = num; + + if (((batch_head - batch_tail) & (batch_max-1)) >= (batch_max / 2)) { /* * Schedule it for the next timer tick: */ schedule_delayed_work(&batch_work, 1); - batch_head = new; - } else if (new == batch_tail) { + } + + new = (batch_head+1) & (batch_max-1); + if (new == batch_tail) { DEBUG_ENT("batch entropy buffer full\n"); } else { batch_head = new; } + + spin_unlock_irqrestore(&batch_lock, flags); } /* @@ -684,20 +709,34 @@ { struct entropy_store *r = (struct entropy_store *) private_, *p; int max_entropy = r->poolinfo.POOLBITS; + unsigned head, tail; - if (!batch_max) - return; + /* Mixing into the pool is expensive, so copy over the batch + * data and release the batch lock. The pool is at least half + * full, so don't worry too much about copying only the used + * part. + */ + spin_lock_irq(&batch_lock); + + memcpy(batch_entropy_copy, batch_entropy_pool, + batch_max*sizeof(struct sample)); + + head = batch_head; + tail = batch_tail; + batch_tail = batch_head; + + spin_unlock_irq(&batch_lock); p = r; - while (batch_head != batch_tail) { + while (head != tail) { if (r->entropy_count >= max_entropy) { r = (r == sec_random_state) ? random_state : sec_random_state; max_entropy = r->poolinfo.POOLBITS; } - add_entropy_words(r, batch_entropy_pool + 2*batch_tail, 2); - credit_entropy_store(r, batch_entropy_credit[batch_tail]); - batch_tail = (batch_tail+1) & (batch_max-1); + add_entropy_words(r, batch_entropy_copy[tail].data, 2); + credit_entropy_store(r, batch_entropy_copy[tail].credit); + tail = (tail+1) & (batch_max-1); } if (p->entropy_count >= random_read_wakeup_thresh) wake_up_interruptible(&random_read_wait); @@ -1216,6 +1255,7 @@ #define EXTRACT_ENTROPY_USER 1 #define EXTRACT_ENTROPY_SECONDARY 2 +#define EXTRACT_ENTROPY_LIMIT 4 #define TMP_BUF_SIZE (HASH_BUFFER_SIZE + HASH_EXTRA_SIZE) #define SEC_XFER_SIZE (TMP_BUF_SIZE*4) @@ -1224,36 +1264,28 @@ /* * This utility inline function is responsible for transfering entropy - * from the primary pool to the secondary extraction pool. We pull - * randomness under two conditions; one is if there isn't enough entropy - * in the secondary pool. The other is after we have extracted 1024 bytes, - * at which point we do a "catastrophic reseeding". + * from the primary pool to the secondary extraction pool. We make + * sure we pull enough for a 'catastrophic reseed'. */ static inline void xfer_secondary_pool(struct entropy_store *r, size_t nbytes, __u32 *tmp) { if (r->entropy_count < nbytes * 8 && r->entropy_count < r->poolinfo.POOLBITS) { - int nwords = min_t(int, - r->poolinfo.poolwords - r->entropy_count/32, - sizeof(tmp) / 4); + int bytes = max_t(int, random_read_wakeup_thresh / 8, + min_t(int, nbytes, TMP_BUF_SIZE)); - DEBUG_ENT("xfer %d from primary to %s (have %d, need %d)\n", - nwords * 32, + DEBUG_ENT("%04d %04d : going to reseed %s with %d bits " + "(%d of %d requested)\n", + random_state->entropy_count, + sec_random_state->entropy_count, r == sec_random_state ? "secondary" : "unknown", - r->entropy_count, nbytes * 8); + bytes * 8, nbytes * 8, r->entropy_count); - extract_entropy(random_state, tmp, nwords * 4, 0); - add_entropy_words(r, tmp, nwords); - credit_entropy_store(r, nwords * 32); - } - if (r->extract_count > 1024) { - DEBUG_ENT("reseeding %s with %d from primary\n", - r == sec_random_state ? "secondary" : "unknown", - sizeof(tmp) * 8); - extract_entropy(random_state, tmp, sizeof(tmp), 0); - add_entropy_words(r, tmp, sizeof(tmp) / 4); - r->extract_count = 0; + bytes=extract_entropy(random_state, tmp, bytes, + EXTRACT_ENTROPY_LIMIT); + add_entropy_words(r, tmp, bytes); + credit_entropy_store(r, bytes*8); } } @@ -1276,8 +1308,8 @@ ssize_t ret, i; __u32 tmp[TMP_BUF_SIZE]; __u32 x; + unsigned long cpuflags; - add_timer_randomness(&extract_timer_state, nbytes); /* Redundant, but just in case... */ if (r->entropy_count > r->poolinfo.POOLBITS) @@ -1286,10 +1318,18 @@ if (flags & EXTRACT_ENTROPY_SECONDARY) xfer_secondary_pool(r, nbytes, tmp); - DEBUG_ENT("%s has %d bits, want %d bits\n", + /* Hold lock while accounting */ + spin_lock_irqsave(&r->lock, cpuflags); + + DEBUG_ENT("%04d %04d : trying to extract %d bits from %s\n", + random_state->entropy_count, + sec_random_state->entropy_count, + nbytes * 8, r == sec_random_state ? "secondary" : - r == random_state ? "primary" : "unknown", - r->entropy_count, nbytes * 8); + r == random_state ? "primary" : "unknown"); + + if (flags & EXTRACT_ENTROPY_LIMIT && nbytes >= r->entropy_count / 8) + nbytes = r->entropy_count / 8; if (r->entropy_count / 8 >= nbytes) r->entropy_count -= nbytes*8; @@ -1299,8 +1339,16 @@ if (r->entropy_count < random_write_wakeup_thresh) wake_up_interruptible(&random_write_wait); - r->extract_count += nbytes; - + DEBUG_ENT("%04d %04d : debiting %d bits from %s%s\n", + random_state->entropy_count, + sec_random_state->entropy_count, + nbytes * 8, + r == sec_random_state ? "secondary" : + r == random_state ? "primary" : "unknown", + flags & EXTRACT_ENTROPY_LIMIT ? "" : " (unlimited)"); + + spin_unlock_irqrestore(&r->lock, cpuflags); + ret = 0; while (nbytes) { /* @@ -1312,7 +1360,16 @@ ret = -ERESTARTSYS; break; } + + DEBUG_ENT("%04d %04d : extract feeling sleepy (%d bytes left)\n", + random_state->entropy_count, + sec_random_state->entropy_count, nbytes); + schedule(); + + DEBUG_ENT("%04d %04d : extract woke up\n", + random_state->entropy_count, + sec_random_state->entropy_count); } /* Hash the pool to get the output */ @@ -1361,7 +1418,6 @@ nbytes -= i; buf += i; ret += i; - add_timer_randomness(&extract_timer_state, nbytes); } /* Wipe data just returned from memory */ @@ -1488,15 +1544,27 @@ if (nbytes == 0) return 0; - add_wait_queue(&random_read_wait, &wait); while (nbytes > 0) { - set_current_state(TASK_INTERRUPTIBLE); - n = nbytes; if (n > SEC_XFER_SIZE) n = SEC_XFER_SIZE; - if (n > random_state->entropy_count / 8) - n = random_state->entropy_count / 8; + + DEBUG_ENT("%04d %04d : reading %d bits, p: %d s: %d\n", + random_state->entropy_count, + sec_random_state->entropy_count, + n*8, random_state->entropy_count, + sec_random_state->entropy_count); + + n = extract_entropy(sec_random_state, buf, n, + EXTRACT_ENTROPY_USER | + EXTRACT_ENTROPY_LIMIT | + EXTRACT_ENTROPY_SECONDARY); + + DEBUG_ENT("%04d %04d : read got %d bits (%d still needed)\n", + random_state->entropy_count, + sec_random_state->entropy_count, + n*8, (nbytes-n)*8); + if (n == 0) { if (file->f_flags & O_NONBLOCK) { retval = -EAGAIN; @@ -1506,12 +1574,27 @@ retval = -ERESTARTSYS; break; } - schedule(); + + DEBUG_ENT("%04d %04d : sleeping?\n", + random_state->entropy_count, + sec_random_state->entropy_count); + + set_current_state(TASK_INTERRUPTIBLE); + add_wait_queue(&random_read_wait, &wait); + + if (sec_random_state->entropy_count / 8 == 0) + schedule(); + + set_current_state(TASK_RUNNING); + remove_wait_queue(&random_read_wait, &wait); + + DEBUG_ENT("%04d %04d : waking up\n", + random_state->entropy_count, + sec_random_state->entropy_count); + continue; } - n = extract_entropy(sec_random_state, buf, n, - EXTRACT_ENTROPY_USER | - EXTRACT_ENTROPY_SECONDARY); + if (n < 0) { retval = n; break; @@ -1522,8 +1605,6 @@ break; /* This break makes the device work */ /* like a named pipe */ } - current->state = TASK_RUNNING; - remove_wait_queue(&random_read_wait, &wait); /* * If we gave the user some bytes, update the access time. @@ -1595,8 +1676,9 @@ random_ioctl(struct inode * inode, struct file * file, unsigned int cmd, unsigned long arg) { - int *p, size, ent_count; + int *p, *tmp, size, ent_count; int retval; + unsigned long flags; switch (cmd) { case RNDGETENTCNT: @@ -1621,17 +1703,36 @@ if (!capable(CAP_SYS_ADMIN)) return -EPERM; p = (int *) arg; - ent_count = random_state->entropy_count; - if (put_user(ent_count, p++) || - get_user(size, p) || + if (get_user(size, p) || put_user(random_state->poolinfo.poolwords, p++)) return -EFAULT; if (size < 0) - return -EINVAL; + return -EFAULT; if (size > random_state->poolinfo.poolwords) size = random_state->poolinfo.poolwords; - if (copy_to_user(p, random_state->pool, size * sizeof(__u32))) + + /* prepare to atomically snapshot pool */ + + tmp = kmalloc(size * sizeof(__u32), GFP_KERNEL); + + if (!tmp) return -EFAULT; + + spin_lock_irqsave(&random_state->lock, flags); + ent_count = random_state->entropy_count; + memcpy(tmp, random_state->pool, size * sizeof(__u32)); + spin_unlock_irqrestore(&random_state->lock, flags); + + if (!copy_to_user(p, tmp, size * sizeof(__u32))) { + kfree(tmp); + return -EFAULT; + } + + kfree(tmp); + + if(put_user(ent_count, p++)) + return -EFAULT; + return 0; case RNDADDENTROPY: if (!capable(CAP_SYS_ADMIN)) diff -Nru a/drivers/char/raw.c b/drivers/char/raw.c --- a/drivers/char/raw.c Tue Sep 2 19:58:17 2003 +++ b/drivers/char/raw.c Tue Sep 2 19:58:17 2003 @@ -43,7 +43,7 @@ */ static int raw_open(struct inode *inode, struct file *filp) { - const int minor = minor(inode->i_rdev); + const int minor = iminor(inode); struct block_device *bdev; int err; @@ -60,23 +60,25 @@ bdev = raw_devices[minor].binding; err = -ENODEV; if (bdev) { - err = bd_claim(bdev, raw_open); + err = blkdev_get(bdev, filp->f_mode, 0, BDEV_RAW); if (err) goto out; - atomic_inc(&bdev->bd_count); - err = blkdev_get(bdev, filp->f_mode, 0, BDEV_RAW); + igrab(bdev->bd_inode); + err = bd_claim(bdev, raw_open); + if (err) { + blkdev_put(bdev, BDEV_RAW); + goto out; + } + err = set_blocksize(bdev, bdev_hardsect_size(bdev)); if (err) { bd_release(bdev); + blkdev_put(bdev, BDEV_RAW); goto out; - } else { - err = set_blocksize(bdev, bdev_hardsect_size(bdev)); - if (err == 0) { - filp->f_flags |= O_DIRECT; - if (++raw_devices[minor].inuse == 1) - filp->f_dentry->d_inode->i_mapping = - bdev->bd_inode->i_mapping; - } } + filp->f_flags |= O_DIRECT; + if (++raw_devices[minor].inuse == 1) + filp->f_dentry->d_inode->i_mapping = + bdev->bd_inode->i_mapping; } filp->private_data = bdev; out: @@ -90,7 +92,7 @@ */ static int raw_release(struct inode *inode, struct file *filp) { - const int minor= minor(inode->i_rdev); + const int minor= iminor(inode); struct block_device *bdev; down(&raw_mutex); diff -Nru a/drivers/char/rtc.c b/drivers/char/rtc.c --- a/drivers/char/rtc.c Tue Sep 2 19:58:15 2003 +++ b/drivers/char/rtc.c Tue Sep 2 19:58:15 2003 @@ -44,10 +44,12 @@ * 1.11 Takashi Iwai: Kernel access functions * rtc_register/rtc_unregister/rtc_control * 1.11a Daniele Bellucci: Audit create_proc_read_entry in rtc_init + * 1.12 Venkatesh Pallipadi: Hooks for emulating rtc on HPET base-timer + * CONFIG_HPET_EMULATE_RTC * */ -#define RTC_VERSION "1.11a" +#define RTC_VERSION "1.12" #define RTC_IO_EXTENT 0x8 @@ -80,6 +82,10 @@ #include #include +#if defined(__i386__) +#include +#endif + #ifdef __sparc__ #include #include @@ -95,6 +101,17 @@ static int rtc_has_irq = 1; #endif +#ifndef CONFIG_HPET_EMULATE_RTC +#define is_hpet_enabled() 0 +#define hpet_set_alarm_time(hrs, min, sec) 0 +#define hpet_set_periodic_freq(arg) 0 +#define hpet_mask_rtc_irq_bit(arg) 0 +#define hpet_set_rtc_irq_bit(arg) 0 +#define hpet_rtc_timer_init() do { } while (0) +#define hpet_rtc_dropped_irq() 0 +static inline irqreturn_t hpet_rtc_interrupt(int irq, void *dev_id, struct pt_regs *regs) {return 0;} +#endif + /* * We sponge a minor off of the misc major. No need slurping * up another valuable major dev number for this. If you add @@ -120,7 +137,7 @@ static unsigned int rtc_poll(struct file *file, poll_table *wait); #endif -static void get_rtc_time (struct rtc_time *rtc_tm); +void get_rtc_time (struct rtc_time *rtc_tm); static void get_rtc_alm_time (struct rtc_time *alm_tm); #if RTC_IRQ static void rtc_dropped_irq(unsigned long data); @@ -182,7 +199,7 @@ * (See ./arch/XXXX/kernel/time.c for the set_rtc_mmss() function.) */ -static irqreturn_t rtc_interrupt(int irq, void *dev_id, struct pt_regs *regs) +irqreturn_t rtc_interrupt(int irq, void *dev_id, struct pt_regs *regs) { /* * Can be an alarm interrupt, update complete interrupt, @@ -194,7 +211,16 @@ spin_lock (&rtc_lock); rtc_irq_data += 0x100; rtc_irq_data &= ~0xff; - rtc_irq_data |= (CMOS_READ(RTC_INTR_FLAGS) & 0xF0); + if (is_hpet_enabled()) { + /* + * In this case it is HPET RTC interrupt handler + * calling us, with the interrupt information + * passed as arg1, instead of irq. + */ + rtc_irq_data |= (unsigned long)irq & 0xF0; + } else { + rtc_irq_data |= (CMOS_READ(RTC_INTR_FLAGS) & 0xF0); + } if (rtc_status & RTC_TIMER_ON) mod_timer(&rtc_irq_timer, jiffies + HZ/rtc_freq + 2*HZ/100); @@ -429,6 +455,12 @@ sec = alm_tm.tm_sec; spin_lock_irq(&rtc_lock); + if (hpet_set_alarm_time(hrs, min, sec)) { + /* + * Fallthru and set alarm time in CMOS too, + * so that we will get proper value in RTC_ALM_READ + */ + } if (!(CMOS_READ(RTC_CONTROL) & RTC_DM_BINARY) || RTC_ALWAYS_BCD) { @@ -582,6 +614,10 @@ return -EINVAL; spin_lock_irq(&rtc_lock); + if (hpet_set_periodic_freq(arg)) { + spin_unlock_irq(&rtc_lock); + return 0; + } rtc_freq = arg; val = CMOS_READ(RTC_FREQ_SELECT) & 0xf0; @@ -667,13 +703,14 @@ */ spin_lock_irq(&rtc_lock); - tmp = CMOS_READ(RTC_CONTROL); - tmp &= ~RTC_PIE; - tmp &= ~RTC_AIE; - tmp &= ~RTC_UIE; - CMOS_WRITE(tmp, RTC_CONTROL); - CMOS_READ(RTC_INTR_FLAGS); - + if (!hpet_mask_rtc_irq_bit(RTC_PIE | RTC_AIE | RTC_UIE)) { + tmp = CMOS_READ(RTC_CONTROL); + tmp &= ~RTC_PIE; + tmp &= ~RTC_AIE; + tmp &= ~RTC_UIE; + CMOS_WRITE(tmp, RTC_CONTROL); + CMOS_READ(RTC_INTR_FLAGS); + } if (rtc_status & RTC_TIMER_ON) { rtc_status &= ~RTC_TIMER_ON; del_timer(&rtc_irq_timer); @@ -765,12 +802,14 @@ rtc_callback = NULL; /* disable controls */ - tmp = CMOS_READ(RTC_CONTROL); - tmp &= ~RTC_PIE; - tmp &= ~RTC_AIE; - tmp &= ~RTC_UIE; - CMOS_WRITE(tmp, RTC_CONTROL); - CMOS_READ(RTC_INTR_FLAGS); + if (!hpet_mask_rtc_irq_bit(RTC_PIE | RTC_AIE | RTC_UIE)) { + tmp = CMOS_READ(RTC_CONTROL); + tmp &= ~RTC_PIE; + tmp &= ~RTC_AIE; + tmp &= ~RTC_UIE; + CMOS_WRITE(tmp, RTC_CONTROL); + CMOS_READ(RTC_INTR_FLAGS); + } if (rtc_status & RTC_TIMER_ON) { rtc_status &= ~RTC_TIMER_ON; del_timer(&rtc_irq_timer); @@ -822,6 +861,10 @@ &rtc_fops }; +#if RTC_IRQ +static irqreturn_t (*rtc_int_handler_ptr)(int irq, void *dev_id, struct pt_regs *regs); +#endif + static int __init rtc_init(void) { #if defined(__alpha__) || defined(__mips__) @@ -889,12 +932,20 @@ } #if RTC_IRQ - if (request_irq(RTC_IRQ, rtc_interrupt, SA_INTERRUPT, "rtc", NULL)) { + if (is_hpet_enabled()) { + rtc_int_handler_ptr = hpet_rtc_interrupt; + } else { + rtc_int_handler_ptr = rtc_interrupt; + } + + if(request_irq(RTC_IRQ, rtc_int_handler_ptr, SA_INTERRUPT, "rtc", NULL)) { /* Yeah right, seeing as irq 8 doesn't even hit the bus. */ printk(KERN_ERR "rtc: IRQ %d is not free.\n", RTC_IRQ); release_region(RTC_PORT(0), RTC_IO_EXTENT); return -EIO; } + hpet_rtc_timer_init(); + #endif #endif /* __sparc__ vs. others */ @@ -965,10 +1016,12 @@ init_timer(&rtc_irq_timer); rtc_irq_timer.function = rtc_dropped_irq; spin_lock_irq(&rtc_lock); - /* Initialize periodic freq. to CMOS reset default, which is 1024Hz */ - CMOS_WRITE(((CMOS_READ(RTC_FREQ_SELECT) & 0xF0) | 0x06), RTC_FREQ_SELECT); - spin_unlock_irq(&rtc_lock); rtc_freq = 1024; + if (!hpet_set_periodic_freq(rtc_freq)) { + /* Initialize periodic freq. to CMOS reset default, which is 1024Hz */ + CMOS_WRITE(((CMOS_READ(RTC_FREQ_SELECT) & 0xF0) | 0x06), RTC_FREQ_SELECT); + } + spin_unlock_irq(&rtc_lock); no_irq2: #endif @@ -1019,6 +1072,11 @@ spin_lock_irq (&rtc_lock); + if (hpet_rtc_dropped_irq()) { + spin_unlock_irq(&rtc_lock); + return; + } + /* Just in case someone disabled the timer from behind our back... */ if (rtc_status & RTC_TIMER_ON) mod_timer(&rtc_irq_timer, jiffies + HZ/rtc_freq + 2*HZ/100); @@ -1148,7 +1206,7 @@ return uip; } -static void get_rtc_time(struct rtc_time *rtc_tm) +void get_rtc_time(struct rtc_time *rtc_tm) { unsigned long uip_watchdog = jiffies; unsigned char ctrl; @@ -1254,6 +1312,10 @@ unsigned char val; spin_lock_irq(&rtc_lock); + if (hpet_mask_rtc_irq_bit(bit)) { + spin_unlock_irq(&rtc_lock); + return; + } val = CMOS_READ(RTC_CONTROL); val &= ~bit; CMOS_WRITE(val, RTC_CONTROL); @@ -1268,6 +1330,10 @@ unsigned char val; spin_lock_irq(&rtc_lock); + if (hpet_set_rtc_irq_bit(bit)) { + spin_unlock_irq(&rtc_lock); + return; + } val = CMOS_READ(RTC_CONTROL); val |= bit; CMOS_WRITE(val, RTC_CONTROL); diff -Nru a/drivers/char/scx200_gpio.c b/drivers/char/scx200_gpio.c --- a/drivers/char/scx200_gpio.c Tue Sep 2 19:58:12 2003 +++ b/drivers/char/scx200_gpio.c Tue Sep 2 19:58:12 2003 @@ -29,7 +29,7 @@ static ssize_t scx200_gpio_write(struct file *file, const char *data, size_t len, loff_t *ppos) { - unsigned m = minor(file->f_dentry->d_inode->i_rdev); + unsigned m = iminor(file->f_dentry->d_inode); size_t i; if (ppos != &file->f_pos) @@ -80,7 +80,7 @@ static ssize_t scx200_gpio_read(struct file *file, char *buf, size_t len, loff_t *ppos) { - unsigned m = minor(file->f_dentry->d_inode->i_rdev); + unsigned m = iminor(file->f_dentry->d_inode); int value; if (ppos != &file->f_pos) @@ -95,7 +95,7 @@ static int scx200_gpio_open(struct inode *inode, struct file *file) { - unsigned m = minor(inode->i_rdev); + unsigned m = iminor(inode); if (m > 63) return -EINVAL; return 0; diff -Nru a/drivers/char/sonypi.c b/drivers/char/sonypi.c --- a/drivers/char/sonypi.c Tue Sep 2 19:58:17 2003 +++ b/drivers/char/sonypi.c Tue Sep 2 19:58:17 2003 @@ -308,7 +308,7 @@ int i, j; v1 = inb_p(sonypi_device.ioport1); - v2 = inb_p(sonypi_device.ioport2); + v2 = inb_p(sonypi_device.ioport1 + sonypi_device.evtype_offset); for (i = 0; sonypi_eventtypes[i].model; i++) { if (sonypi_device.model != sonypi_eventtypes[i].model) @@ -670,11 +670,13 @@ if (sonypi_device.model == SONYPI_DEVICE_MODEL_TYPE2) { ioport_list = sonypi_type2_ioport_list; sonypi_device.region_size = SONYPI_TYPE2_REGION_SIZE; + sonypi_device.evtype_offset = SONYPI_TYPE2_EVTYPE_OFFSET; irq_list = sonypi_type2_irq_list; } else { ioport_list = sonypi_type1_ioport_list; sonypi_device.region_size = SONYPI_TYPE1_REGION_SIZE; + sonypi_device.evtype_offset = SONYPI_TYPE1_EVTYPE_OFFSET; irq_list = sonypi_type1_irq_list; } diff -Nru a/drivers/char/sonypi.h b/drivers/char/sonypi.h --- a/drivers/char/sonypi.h Tue Sep 2 19:58:16 2003 +++ b/drivers/char/sonypi.h Tue Sep 2 19:58:16 2003 @@ -56,12 +56,14 @@ #define SONYPI_BASE 0x50 #define SONYPI_G10A (SONYPI_BASE+0x14) #define SONYPI_TYPE1_REGION_SIZE 0x08 +#define SONYPI_TYPE1_EVTYPE_OFFSET 0x04 /* type2 series specifics */ #define SONYPI_SIRQ 0x9b #define SONYPI_SLOB 0x9c #define SONYPI_SHIB 0x9d #define SONYPI_TYPE2_REGION_SIZE 0x20 +#define SONYPI_TYPE2_EVTYPE_OFFSET 0x12 /* battery / brightness addresses */ #define SONYPI_BAT_FLAGS 0x81 @@ -167,6 +169,7 @@ #define SONYPI_THUMBPHRASE_MASK 0x00000200 #define SONYPI_MEYE_MASK 0x00000400 #define SONYPI_MEMORYSTICK_MASK 0x00000800 +#define SONYPI_BATTERY_MASK 0x00001000 struct sonypi_event { u8 data; @@ -293,6 +296,13 @@ { 0, 0 } }; +/* The set of possible battery events */ +static struct sonypi_event sonypi_batteryev[] = { + { 0x20, SONYPI_EVENT_BATTERY_INSERT }, + { 0x30, SONYPI_EVENT_BATTERY_REMOVE }, + { 0, 0 } +}; + struct sonypi_eventtypes { int model; u8 data; @@ -307,19 +317,22 @@ { SONYPI_DEVICE_MODEL_TYPE1, 0x20, SONYPI_FNKEY_MASK, sonypi_fnkeyev }, { SONYPI_DEVICE_MODEL_TYPE1, 0x30, SONYPI_BLUETOOTH_MASK, sonypi_blueev }, { SONYPI_DEVICE_MODEL_TYPE1, 0x40, SONYPI_PKEY_MASK, sonypi_pkeyev }, + { SONYPI_DEVICE_MODEL_TYPE1, 0x30, SONYPI_MEMORYSTICK_MASK, sonypi_memorystickev }, + { SONYPI_DEVICE_MODEL_TYPE1, 0x40, SONYPI_BATTERY_MASK, sonypi_batteryev }, { SONYPI_DEVICE_MODEL_TYPE2, 0, 0xffffffff, sonypi_releaseev }, { SONYPI_DEVICE_MODEL_TYPE2, 0x38, SONYPI_LID_MASK, sonypi_lidev }, - { SONYPI_DEVICE_MODEL_TYPE2, 0x08, SONYPI_JOGGER_MASK, sonypi_joggerev }, - { SONYPI_DEVICE_MODEL_TYPE2, 0x08, SONYPI_CAPTURE_MASK, sonypi_captureev }, - { SONYPI_DEVICE_MODEL_TYPE2, 0x08, SONYPI_FNKEY_MASK, sonypi_fnkeyev }, - { SONYPI_DEVICE_MODEL_TYPE2, 0x08, SONYPI_BLUETOOTH_MASK, sonypi_blueev }, + { SONYPI_DEVICE_MODEL_TYPE2, 0x11, SONYPI_JOGGER_MASK, sonypi_joggerev }, + { SONYPI_DEVICE_MODEL_TYPE2, 0x61, SONYPI_CAPTURE_MASK, sonypi_captureev }, + { SONYPI_DEVICE_MODEL_TYPE2, 0x21, SONYPI_FNKEY_MASK, sonypi_fnkeyev }, + { SONYPI_DEVICE_MODEL_TYPE2, 0x31, SONYPI_BLUETOOTH_MASK, sonypi_blueev }, { SONYPI_DEVICE_MODEL_TYPE2, 0x08, SONYPI_PKEY_MASK, sonypi_pkeyev }, - { SONYPI_DEVICE_MODEL_TYPE2, 0x08, SONYPI_BACK_MASK, sonypi_backev }, + { SONYPI_DEVICE_MODEL_TYPE2, 0x11, SONYPI_BACK_MASK, sonypi_backev }, { SONYPI_DEVICE_MODEL_TYPE2, 0x08, SONYPI_HELP_MASK, sonypi_helpev }, { SONYPI_DEVICE_MODEL_TYPE2, 0x08, SONYPI_ZOOM_MASK, sonypi_zoomev }, { SONYPI_DEVICE_MODEL_TYPE2, 0x08, SONYPI_THUMBPHRASE_MASK, sonypi_thumbphraseev }, - { SONYPI_DEVICE_MODEL_TYPE2, 0x08, SONYPI_MEMORYSTICK_MASK, sonypi_memorystickev }, + { SONYPI_DEVICE_MODEL_TYPE2, 0x31, SONYPI_MEMORYSTICK_MASK, sonypi_memorystickev }, + { SONYPI_DEVICE_MODEL_TYPE2, 0x41, SONYPI_BATTERY_MASK, sonypi_batteryev }, { 0, 0, 0, 0 } }; @@ -354,6 +367,7 @@ u16 ioport1; u16 ioport2; u16 region_size; + u16 evtype_offset; int camera_power; int bluetooth_power; struct semaphore lock; diff -Nru a/drivers/char/stallion.c b/drivers/char/stallion.c --- a/drivers/char/stallion.c Tue Sep 2 19:58:18 2003 +++ b/drivers/char/stallion.c Tue Sep 2 19:58:18 2003 @@ -3078,7 +3078,7 @@ (int) fp, cmd, (int) arg); #endif - brdnr = minor(ip->i_rdev); + brdnr = iminor(ip); if (brdnr >= STL_MAXBRDS) return(-ENODEV); rc = 0; @@ -4234,7 +4234,7 @@ misr = inb(ioaddr + EREG_DATA); if (misr & MISR_DCD) { set_bit(ASYI_DCDCHANGE, &portp->istate); - schedule_task(&portp->tqueue); + schedule_work(&portp->tqueue); portp->stats.modem++; } @@ -5031,7 +5031,7 @@ if ((len == 0) || ((len < STL_TXBUFLOW) && (test_bit(ASYI_TXLOW, &portp->istate) == 0))) { set_bit(ASYI_TXLOW, &portp->istate); - schedule_task(&portp->tqueue); + schedule_work(&portp->tqueue); } if (len == 0) { @@ -5248,7 +5248,7 @@ ipr = stl_sc26198getreg(portp, IPR); if (ipr & IPR_DCDCHANGE) { set_bit(ASYI_DCDCHANGE, &portp->istate); - schedule_task(&portp->tqueue); + schedule_work(&portp->tqueue); portp->stats.modem++; } break; diff -Nru a/drivers/char/tipar.c b/drivers/char/tipar.c --- a/drivers/char/tipar.c Tue Sep 2 19:58:17 2003 +++ b/drivers/char/tipar.c Tue Sep 2 19:58:17 2003 @@ -248,7 +248,7 @@ static int tipar_open(struct inode *inode, struct file *file) { - unsigned int minor = minor(inode->i_rdev) - TIPAR_MINOR; + unsigned int minor = iminor(inode) - TIPAR_MINOR; if (minor > tp_count - 1) return -ENXIO; @@ -266,7 +266,7 @@ static int tipar_close(struct inode *inode, struct file *file) { - unsigned int minor = minor(inode->i_rdev) - TIPAR_MINOR; + unsigned int minor = iminor(inode) - TIPAR_MINOR; if (minor > tp_count - 1) return -ENXIO; @@ -279,8 +279,7 @@ static ssize_t tipar_write(struct file *file, const char *buf, size_t count, loff_t * ppos) { - unsigned int minor = - minor(file->f_dentry->d_inode->i_rdev) - TIPAR_MINOR; + unsigned int minor = iminor(file->f_dentry->d_inode) - TIPAR_MINOR; ssize_t n; parport_claim_or_block(table[minor].dev); @@ -308,8 +307,7 @@ tipar_read(struct file *file, char *buf, size_t count, loff_t * ppos) { int b = 0; - unsigned int minor = - minor(file->f_dentry->d_inode->i_rdev) - TIPAR_MINOR; + unsigned int minor = iminor(file->f_dentry->d_inode) - TIPAR_MINOR; ssize_t retval = 0; ssize_t n = 0; diff -Nru a/drivers/char/tpqic02.c b/drivers/char/tpqic02.c --- a/drivers/char/tpqic02.c Tue Sep 2 19:58:15 2003 +++ b/drivers/char/tpqic02.c Tue Sep 2 19:58:15 2003 @@ -169,7 +169,7 @@ static volatile unsigned dma_mode; /* !=0 also means DMA in use */ static flag need_rewind = YES; -static kdev_t current_tape_dev; +static int current_type; static int extra_blocks_left = BLOCKS_BEYOND_EW; static struct timer_list tp_timer; @@ -677,7 +677,7 @@ * exception flag from previous exception which we are trying to clear. */ - if (TP_DIAGS(current_tape_dev)) + if (TP_DIAGS(current_type)) printk(TPQIC02_NAME ": reading status bytes: "); for (q = stp; q < stp + size; q++) { @@ -693,7 +693,7 @@ *q = inb_p(QIC02_DATA_PORT); /* read status byte */ - if (TP_DIAGS(current_tape_dev)) + if (TP_DIAGS(current_type)) printk("[%1d]=0x%x ", q - stp, (unsigned) (*q) & 0xff); outb_p(ctlbits | QIC02_CTL_REQUEST, QIC02_CTL_PORT); /* set request */ @@ -714,7 +714,7 @@ cpu_relax(); /* wait for ready */ - if (TP_DIAGS(current_tape_dev)) + if (TP_DIAGS(current_type)) printk("\n"); return TE_OK; @@ -1614,7 +1614,7 @@ if (status_expect_int) { #ifdef WANT_EXTRA_FULL_DEBUGGING - if (TP_DIAGS(current_tape_dev)) + if (TP_DIAGS(current_type)) printk("@"); #endif stat = inb(QIC02_STAT_PORT); /* Knock, knock */ @@ -1726,7 +1726,7 @@ static ssize_t qic02_tape_read(struct file *filp, char *buf, size_t count, loff_t * ppos) { - kdev_t dev = filp->f_dentry->d_inode->i_rdev; + int type = iminor(filp->f_dentry->d_inode); unsigned short flags = filp->f_flags; unsigned long bytes_todo, bytes_done, total_bytes_done = 0; int stat; @@ -1736,8 +1736,8 @@ return -ENXIO; } - if (TP_DIAGS(current_tape_dev)) - printk(TPQIC02_NAME ": request READ, minor=%x, buf=%p, count=%lx, pos=%Lx, flags=%x\n", minor(dev), buf, + if (TP_DIAGS(current_type)) + printk(TPQIC02_NAME ": request READ, minor=%x, buf=%p, count=%lx, pos=%Lx, flags=%x\n", type, buf, (long) count, filp->f_pos, flags); if (count % TAPE_BLKSIZE) { /* Only allow mod 512 bytes at a time. */ @@ -1904,7 +1904,7 @@ */ static ssize_t qic02_tape_write(struct file *filp, const char *buf, size_t count, loff_t * ppos) { - kdev_t dev = filp->f_dentry->d_inode->i_rdev; + int type = iminor(filp->f_dentry->d_inode); unsigned short flags = filp->f_flags; unsigned long bytes_todo, bytes_done, total_bytes_done = 0; @@ -1913,9 +1913,9 @@ return -ENXIO; } - if (TP_DIAGS(current_tape_dev)) { + if (TP_DIAGS(current_type)) { printk(TPQIC02_NAME ": request WRITE, minor=%x, buf=%p, count=%lx, pos=%Lx, flags=%x\n", - minor(dev), buf, (long) count, filp->f_pos, flags); + type, buf, (long) count, filp->f_pos, flags); } if (count % TAPE_BLKSIZE) { /* only allow mod 512 bytes at a time */ @@ -2070,17 +2070,18 @@ static int qic02_tape_open_no_use_count(struct inode *inode, struct file *filp) { - kdev_t dev = inode->i_rdev; + int type = iminor(inode); unsigned short flags = filp->f_flags; unsigned short dens = 0; int s; - if (TP_DIAGS(dev)) { - printk("qic02_tape_open: dev=%s, flags=%x ", cdevname(dev), flags); + if (TP_DIAGS(type)) { + printk("qic02_tape_open: dev=tpqic2(%d), flags=%x ", + type, flags); } - if (minor(dev) == 255) { /* special case for resetting */ + if (type == 255) { /* special case for resetting */ if (capable(CAP_SYS_ADMIN)) { return (tape_reset(1) == TE_OK) ? -EAGAIN : -ENXIO; } else { @@ -2162,7 +2163,7 @@ */ /* not allowed to do QCMD_DENS_* unless tape is rewound */ - if ((TP_DENS(dev) != 0) && (TP_DENS(current_tape_dev) != TP_DENS(dev))) { + if ((TP_DENS(type) != 0) && (TP_DENS(current_type) != TP_DENS(type))) { /* force rewind if minor bits have changed, * i.e. user wants to use tape in different format. * [assuming single drive operation] @@ -2175,7 +2176,7 @@ /* density bits still the same, but TP_DIAGS bit * may have changed. */ - current_tape_dev = dev; + current_type = type; } if (need_rewind == YES) { @@ -2212,14 +2213,14 @@ * so we must have done a rewind by now. If not, just skip over. * Only give set density command when minor bits have changed. */ - if (TP_DENS(current_tape_dev) == TP_DENS(dev)) { + if (TP_DENS(current_type) == TP_DENS(type)) { return 0; } - current_tape_dev = dev; + current_type = type; need_rewind = NO; if (TP_HAVE_DENS) { - dens = TP_DENS(dev); + dens = TP_DENS(type); } if (dens < sizeof(format_names) / sizeof(char *)) @@ -2227,7 +2228,7 @@ else tpqputs(TPQD_REWIND, "Wait for retensioning..."); - switch (TP_DENS(dev)) { + switch (TP_DENS(type)) { case 0: /* Minor 0 is for drives without set-density support */ s = 0; break; @@ -2254,7 +2255,7 @@ } if (s != 0) { status_dead = YES; /* force reset */ - current_tape_dev = NODEV;/* earlier 0xff80 */ + current_type = 0;/* earlier 0xff80 */ return -EIO; } @@ -2264,10 +2265,10 @@ static int qic02_tape_release(struct inode *inode, struct file *filp) { - kdev_t dev = inode->i_rdev; + int type = iminor(inode); - if (TP_DIAGS(dev)) { - printk("qic02_tape_release: dev=%s\n", cdevname(dev)); + if (TP_DIAGS(type)) { + printk("qic02_tape_release: dev=tpqic2(%d)\n", type); } if (status_zombie == NO) { /* don't rewind in zombie mode */ @@ -2283,7 +2284,7 @@ /* Rewind only if minor number requires it AND * read/writes have been done. ************* IS THIS CORRECT?????????? */ - if ((TP_REWCLOSE(dev)) && (status_bytes_rd | status_bytes_wr)) { + if (TP_REWCLOSE(type) && (status_bytes_rd | status_bytes_wr)) { tpqputs(TPQD_REWIND, "release: Doing rewind..."); (void) do_qic_cmd(QCMD_REWIND, TIM_R); } @@ -2398,7 +2399,7 @@ struct mtpos ioctl_tell; - if (TP_DIAGS(current_tape_dev)) + if (TP_DIAGS(current_type)) printk(TPQIC02_NAME ": ioctl(%4x, %4lx)\n", iocmd, ioarg); if (!inode) @@ -2459,7 +2460,7 @@ * --- tape at the beginning of the current file. */ - if (TP_DIAGS(current_tape_dev)) + if (TP_DIAGS(current_type)) printk("OP op=%4x, count=%4x\n", operation.mt_op, operation.mt_count); if (operation.mt_count < 0) @@ -2492,7 +2493,7 @@ return 0; } else if (c == _IOC_NR(MTIOCGET)) { - if (TP_DIAGS(current_tape_dev)) + if (TP_DIAGS(current_type)) printk("GET "); CHECK_IOC_SIZE(mtget); @@ -2507,7 +2508,7 @@ return -EFAULT; return 0; } else if (TP_HAVE_TELL && (c == _IOC_NR(MTIOCPOS))) { - if (TP_DIAGS(current_tape_dev)) + if (TP_DIAGS(current_type)) printk("POS "); CHECK_IOC_SIZE(mtpos); @@ -2664,7 +2665,7 @@ return -ENODEV; } - current_tape_dev = mk_kdev(QIC02_TAPE_MAJOR, 0); + current_type = 0; #ifndef CONFIG_QIC02_DYNCONF printk(TPQIC02_NAME ": IRQ %d, DMA %d, IO 0x%x, IFC %s, %s, %s\n", diff -Nru a/drivers/char/tty_io.c b/drivers/char/tty_io.c --- a/drivers/char/tty_io.c Tue Sep 2 19:58:16 2003 +++ b/drivers/char/tty_io.c Tue Sep 2 19:58:16 2003 @@ -177,7 +177,7 @@ EXPORT_SYMBOL(tty_name); -inline int tty_paranoia_check(struct tty_struct *tty, kdev_t device, +inline int tty_paranoia_check(struct tty_struct *tty, struct inode *inode, const char *routine) { #ifdef TTY_PARANOIA_CHECK @@ -187,11 +187,11 @@ "Warning: null TTY for (%s) in %s\n"; if (!tty) { - printk(badtty, cdevname(device), routine); + printk(badtty, cdevname(inode->i_rdev), routine); return 1; } if (tty->magic != TTY_MAGIC) { - printk(badmagic, cdevname(device), routine); + printk(badmagic, cdevname(inode->i_rdev), routine); return 1; } #endif @@ -646,7 +646,7 @@ tty = (struct tty_struct *)file->private_data; inode = file->f_dentry->d_inode; - if (tty_paranoia_check(tty, inode->i_rdev, "tty_read")) + if (tty_paranoia_check(tty, inode, "tty_read")) return -EIO; if (!tty || (test_bit(TTY_IO_ERROR, &tty->flags))) return -EIO; @@ -763,7 +763,7 @@ } tty = (struct tty_struct *)file->private_data; - if (tty_paranoia_check(tty, inode->i_rdev, "tty_write")) + if (tty_paranoia_check(tty, inode, "tty_write")) return -EIO; if (!tty || !tty->driver->write || (test_bit(TTY_IO_ERROR, &tty->flags))) return -EIO; @@ -1023,7 +1023,7 @@ o_tty->magic = 0; o_tty->driver->refcount--; file_list_lock(); - list_del(&o_tty->tty_files); + list_del_init(&o_tty->tty_files); file_list_unlock(); free_tty_struct(o_tty); } @@ -1037,7 +1037,7 @@ tty->magic = 0; tty->driver->refcount--; file_list_lock(); - list_del(&tty->tty_files); + list_del_init(&tty->tty_files); file_list_unlock(); module_put(tty->driver->owner); free_tty_struct(tty); @@ -1059,7 +1059,7 @@ char buf[64]; tty = (struct tty_struct *)filp->private_data; - if (tty_paranoia_check(tty, filp->f_dentry->d_inode->i_rdev, "release_dev")) + if (tty_paranoia_check(tty, filp->f_dentry->d_inode, "release_dev")) return; check_tty_count(tty, "release_dev"); @@ -1439,7 +1439,7 @@ struct tty_struct * tty; tty = (struct tty_struct *)filp->private_data; - if (tty_paranoia_check(tty, filp->f_dentry->d_inode->i_rdev, "tty_poll")) + if (tty_paranoia_check(tty, filp->f_dentry->d_inode, "tty_poll")) return 0; if (tty->ldisc.poll) @@ -1453,7 +1453,7 @@ int retval; tty = (struct tty_struct *)filp->private_data; - if (tty_paranoia_check(tty, filp->f_dentry->d_inode->i_rdev, "tty_fasync")) + if (tty_paranoia_check(tty, filp->f_dentry->d_inode, "tty_fasync")) return 0; retval = fasync_helper(fd, filp, on, &tty->fasync); @@ -1727,7 +1727,7 @@ int retval; tty = (struct tty_struct *)file->private_data; - if (tty_paranoia_check(tty, inode->i_rdev, "tty_ioctl")) + if (tty_paranoia_check(tty, inode, "tty_ioctl")) return -EINVAL; real_tty = tty; diff -Nru a/drivers/char/vc_screen.c b/drivers/char/vc_screen.c --- a/drivers/char/vc_screen.c Tue Sep 2 19:58:14 2003 +++ b/drivers/char/vc_screen.c Tue Sep 2 19:58:14 2003 @@ -49,7 +49,7 @@ vcs_size(struct inode *inode) { int size; - int minor = minor(inode->i_rdev); + int minor = iminor(inode); int currcons = minor & 127; if (currcons == 0) currcons = fg_console; @@ -104,7 +104,7 @@ vcs_read(struct file *file, char *buf, size_t count, loff_t *ppos) { struct inode *inode = file->f_dentry->d_inode; - unsigned int currcons = minor(inode->i_rdev); + unsigned int currcons = iminor(inode); long pos = *ppos; long viewed, attr, read; int col, maxcol; @@ -273,7 +273,7 @@ vcs_write(struct file *file, const char *buf, size_t count, loff_t *ppos) { struct inode *inode = file->f_dentry->d_inode; - unsigned int currcons = minor(inode->i_rdev); + unsigned int currcons = iminor(inode); long pos = *ppos; long viewed, attr, size, written; char *con_buf0; @@ -456,7 +456,7 @@ static int vcs_open(struct inode *inode, struct file *filp) { - unsigned int currcons = minor(inode->i_rdev) & 127; + unsigned int currcons = iminor(inode) & 127; if(currcons && !vc_cons_allocated(currcons-1)) return -ENXIO; return 0; diff -Nru a/drivers/char/watchdog/Kconfig b/drivers/char/watchdog/Kconfig --- a/drivers/char/watchdog/Kconfig Tue Sep 2 19:58:17 2003 +++ b/drivers/char/watchdog/Kconfig Tue Sep 2 19:58:17 2003 @@ -346,6 +346,18 @@ module, say M here and read . Most people will say N. +config ALIM1535_WDT + tristate "ALi M1535 PMU Watchdog Timer" + depends on WATCHDOG + ---help--- + This is the driver for the hardware watchdog on the ALi M1535 PMU. + + This driver is also available as a module ( = code which can be + inserted in and removed from the running kernel whenever you want). + The module is called alim1535_wdt. If you want to compile it as a + module, say M here and read . Most + people will say N. + config SC1200_WDT tristate "National Semiconductor PC87307/PC97307 (ala SC1200) Watchdog" depends on WATCHDOG diff -Nru a/drivers/char/watchdog/Makefile b/drivers/char/watchdog/Makefile --- a/drivers/char/watchdog/Makefile Tue Sep 2 19:58:17 2003 +++ b/drivers/char/watchdog/Makefile Tue Sep 2 19:58:17 2003 @@ -27,6 +27,7 @@ obj-$(CONFIG_W83877F_WDT) += w83877f_wdt.o obj-$(CONFIG_SC520_WDT) += sc520_wdt.o obj-$(CONFIG_ALIM7101_WDT) += alim7101_wdt.o +obj-$(CONFIG_ALIM1535_WDT) += alim1535_wdt.o obj-$(CONFIG_SC1200_WDT) += sc1200wdt.o obj-$(CONFIG_WAFER_WDT) += wafer5823wdt.o obj-$(CONFIG_CPU5_WDT) += cpu5wdt.o diff -Nru a/drivers/char/watchdog/acquirewdt.c b/drivers/char/watchdog/acquirewdt.c --- a/drivers/char/watchdog/acquirewdt.c Tue Sep 2 19:58:17 2003 +++ b/drivers/char/watchdog/acquirewdt.c Tue Sep 2 19:58:17 2003 @@ -1,5 +1,5 @@ /* - * Acquire Single Board Computer Watchdog Timer driver for Linux 2.1.x + * Acquire Single Board Computer Watchdog Timer driver * * Based on wdt.c. Original copyright messages: * @@ -10,10 +10,10 @@ * 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. - * - * Neither Alan Cox nor CymruNet Ltd. admit liability nor provide - * warranty for any of this software. This material is provided - * "AS-IS" and at no charge. + * + * Neither Alan Cox nor CymruNet Ltd. admit liability nor provide + * warranty for any of this software. This material is provided + * "AS-IS" and at no charge. * * (c) Copyright 1995 Alan Cox * @@ -22,33 +22,39 @@ * Can't add timeout - driver doesn't allow changing value */ -#include #include #include #include #include #include +#include #include #include -#include #include #include -#include #include #include #include -static int acq_is_open; -static spinlock_t acq_lock; -static int expect_close = 0; +#define WATCHDOG_NAME "Acquire WDT" +#define PFX WATCHDOG_NAME ": " +#define WATCHDOG_TIMEOUT 0 /* ??? Is the timeout hardcoded to 1 minute ??? */ + +static unsigned long acq_is_open; +static char expect_close; /* * You must set these - there is no sane way to probe for this board. */ - -#define WDT_STOP 0x43 -#define WDT_START 0x443 + +static int wdt_stop = 0x43; +module_param(wdt_stop, int, 0); +MODULE_PARM_DESC(wdt_stop, "Acquire WDT 'stop' io port (default 0x43)"); + +static int wdt_start = 0x443; +module_param(wdt_start, int, 0); +MODULE_PARM_DESC(wdt_start, "Acquire WDT 'start' io port (default 0x443)"); #ifdef CONFIG_WATCHDOG_NOWAYOUT static int nowayout = 1; @@ -62,38 +68,52 @@ /* * Kernel methods. */ - static void acq_ping(void) { /* Write a watchdog value */ - inb_p(WDT_START); + inb_p(wdt_start); } +static void acq_stop(void) +{ + /* Turn the card off */ + inb_p(wdt_stop); +} + +/* + * /dev/watchdog handling. + */ + static ssize_t acq_write(struct file *file, const char *buf, size_t count, loff_t *ppos) { /* Can't seek (pwrite) on this device */ if (ppos != &file->f_pos) return -ESPIPE; + /* See if we got the magic character 'V' and reload the timer */ if(count) { if (!nowayout) { size_t i; + /* note: just in case someone wrote the magic character + * five months ago... */ expect_close = 0; + /* scan to see wether or not we got the magic character */ for (i = 0; i != count; i++) { char c; if (get_user(c, buf + i)) return -EFAULT; if (c == 'V') - expect_close = 1; + expect_close = 42; } } + + /* Well, anyhow someone wrote to us, we should return that favour */ acq_ping(); - return 1; } - return 0; + return count; } static int acq_ioctl(struct inode *inode, struct file *file, unsigned int cmd, @@ -103,65 +123,75 @@ { .options = WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE, .firmware_version = 1, - .identity = "Acquire WDT" + .identity = "Acquire WDT", }; - + switch(cmd) { case WDIOC_GETSUPPORT: - if (copy_to_user((struct watchdog_info *)arg, &ident, sizeof(ident))) - return -EFAULT; - break; - + return copy_to_user((struct watchdog_info *)arg, &ident, sizeof(ident)) ? -EFAULT : 0; + case WDIOC_GETSTATUS: - if (copy_to_user((int *)arg, &acq_is_open, sizeof(int))) - return -EFAULT; - break; + case WDIOC_GETBOOTSTATUS: + return put_user(0, (int *)arg); case WDIOC_KEEPALIVE: acq_ping(); - break; + return 0; + + case WDIOC_GETTIMEOUT: + return put_user(WATCHDOG_TIMEOUT, (int *)arg); + + case WDIOC_SETOPTIONS: + { + int options, retval = -EINVAL; + + if (get_user(options, (int *)arg)) + return -EFAULT; + + if (options & WDIOS_DISABLECARD) + { + acq_stop(); + retval = 0; + } + + if (options & WDIOS_ENABLECARD) + { + acq_ping(); + retval = 0; + } + + return retval; + } default: - return -ENOTTY; + return -ENOIOCTLCMD; } - return 0; } static int acq_open(struct inode *inode, struct file *file) { - if ((minor(inode->i_rdev) == WATCHDOG_MINOR)) { - spin_lock(&acq_lock); - if(acq_is_open) { - spin_unlock(&acq_lock); - return -EBUSY; - } - if (nowayout) - __module_get(THIS_MODULE); + if (test_and_set_bit(0, &acq_is_open)) + return -EBUSY; - /* Activate */ - acq_is_open=1; - inb_p(WDT_START); - spin_unlock(&acq_lock); - return 0; + if (nowayout) + __module_get(THIS_MODULE); - } else { - return -ENODEV; - } + /* Activate */ + acq_ping(); + return 0; } static int acq_close(struct inode *inode, struct file *file) { - if(minor(inode->i_rdev)==WATCHDOG_MINOR) { - spin_lock(&acq_lock); - if (expect_close) - inb_p(WDT_STOP); - else - printk(KERN_CRIT "WDT closed unexpectedly. WDT will not stop!\n"); - - acq_is_open=0; - spin_unlock(&acq_lock); + if (expect_close == 42) { + acq_stop(); + } else { + printk(KERN_CRIT PFX "Unexpected close, not stopping watchdog!\n"); + acq_ping(); } + clear_bit(0, &acq_is_open); + expect_close = 0; return 0; } @@ -172,20 +202,20 @@ static int acq_notify_sys(struct notifier_block *this, unsigned long code, void *unused) { - if(code==SYS_DOWN || code==SYS_HALT) - /* Turn the card off */ - inb_p(WDT_STOP); - + if(code==SYS_DOWN || code==SYS_HALT) { + /* Turn the WDT off */ + acq_stop(); + } return NOTIFY_DONE; } - + /* * Kernel Interfaces */ - - + static struct file_operations acq_fops = { .owner = THIS_MODULE, + .llseek = no_llseek, .write = acq_write, .ioctl = acq_ioctl, .open = acq_open, @@ -196,52 +226,84 @@ { .minor = WATCHDOG_MINOR, .name = "watchdog", - .fops = &acq_fops + .fops = &acq_fops, }; - /* * The WDT card needs to learn about soft shutdowns in order to - * turn the timebomb registers off. + * turn the timebomb registers off. */ - + static struct notifier_block acq_notifier = { .notifier_call = acq_notify_sys, .next = NULL, - .priority = 0 + .priority = 0, }; static int __init acq_init(void) { + int ret; + printk(KERN_INFO "WDT driver for Acquire single board computer initialising.\n"); - spin_lock_init(&acq_lock); - if (misc_register(&acq_miscdev)) - return -ENODEV; - if (!request_region(WDT_STOP, 1, "Acquire WDT")) { - misc_deregister(&acq_miscdev); - return -EIO; - } - if (!request_region(WDT_START, 1, "Acquire WDT")) { - release_region(WDT_STOP, 1); - misc_deregister(&acq_miscdev); - return -EIO; + if (wdt_stop != wdt_start) { + if (!request_region(wdt_stop, 1, WATCHDOG_NAME)) { + printk (KERN_ERR PFX "I/O address 0x%04x already in use\n", + wdt_stop); + ret = -EIO; + goto out; + } } - register_reboot_notifier(&acq_notifier); - return 0; + if (!request_region(wdt_start, 1, WATCHDOG_NAME)) { + printk (KERN_ERR PFX "I/O address 0x%04x already in use\n", + wdt_start); + ret = -EIO; + goto unreg_stop; + } + + ret = register_reboot_notifier(&acq_notifier); + if (ret != 0) { + printk (KERN_ERR PFX "cannot register reboot notifier (err=%d)\n", + ret); + goto unreg_regions; + } + + ret = misc_register(&acq_miscdev); + if (ret != 0) { + printk (KERN_ERR PFX "cannot register miscdev on minor=%d (err=%d)\n", + WATCHDOG_MINOR, ret); + goto unreg_reboot; + } + + printk (KERN_INFO PFX "initialized. (nowayout=%d)\n", + nowayout); + +out: + return ret; +unreg_reboot: + unregister_reboot_notifier(&acq_notifier); +unreg_regions: + release_region(wdt_start, 1); +unreg_stop: + if (wdt_stop != wdt_start) + release_region(wdt_stop, 1); + goto out; } - + static void __exit acq_exit(void) { misc_deregister(&acq_miscdev); unregister_reboot_notifier(&acq_notifier); - release_region(WDT_STOP,1); - release_region(WDT_START,1); + if(wdt_stop != wdt_start) + release_region(wdt_stop,1); + release_region(wdt_start,1); } module_init(acq_init); module_exit(acq_exit); MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Unkown"); +MODULE_DESCRIPTION("Acquire Single Board Computer Watchdog Timer driver"); diff -Nru a/drivers/char/watchdog/advantechwdt.c b/drivers/char/watchdog/advantechwdt.c --- a/drivers/char/watchdog/advantechwdt.c Tue Sep 2 19:58:15 2003 +++ b/drivers/char/watchdog/advantechwdt.c Tue Sep 2 19:58:15 2003 @@ -133,7 +133,7 @@ static struct watchdog_info ident = { .options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE, .firmware_version = 1, - .identity = "Advantech WDT" + .identity = "Advantech WDT", }; switch (cmd) { diff -Nru a/drivers/char/watchdog/alim1535_wdt.c b/drivers/char/watchdog/alim1535_wdt.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/drivers/char/watchdog/alim1535_wdt.c Tue Sep 2 19:58:20 2003 @@ -0,0 +1,465 @@ +/* + * Watchdog for the 7101 PMU version found in the ALi M1535 chipsets + * + * 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. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#define WATCHDOG_NAME "ALi_M1535" +#define PFX WATCHDOG_NAME ": " +#define WATCHDOG_TIMEOUT 60 /* 60 sec default timeout */ + +/* internal variables */ +static unsigned long ali_is_open; +static char ali_expect_release; +static struct pci_dev *ali_pci; +static u32 ali_timeout_bits; /* stores the computed timeout */ +static spinlock_t ali_lock; /* Guards the hardware */ + +/* module parameters */ +static int timeout = WATCHDOG_TIMEOUT; +module_param(timeout, int, 0); +MODULE_PARM_DESC(timeout, "Watchdog timeout in seconds. (0f_pos) + return -ESPIPE; + + /* See if we got the magic character 'V' and reload the timer */ + if (len) { + if (!nowayout) { + size_t i; + + /* note: just in case someone wrote the magic character + * five months ago... */ + ali_expect_release = 0; + + /* scan to see wether or not we got the magic character */ + for (i = 0; i != len; i++) { + char c; + if(get_user(c, data+i)) + return -EFAULT; + if (c == 'V') + ali_expect_release = 42; + } + } + + /* someone wrote to us, we should reload the timer */ + ali_start(); + } + return len; +} + +/* + * ali_ioctl - handle watchdog ioctls + * @inode: VFS inode + * @file: VFS file pointer + * @cmd: ioctl number + * @arg: arguments to the ioctl + * + * Handle the watchdog ioctls supported by the ALi driver. Really + * we want an extension to enable irq ack monitoring and the like + */ + +static int ali_ioctl(struct inode *inode, struct file *file, + unsigned int cmd, unsigned long arg) +{ + static struct watchdog_info ident = { + .options = WDIOF_KEEPALIVEPING | + WDIOF_SETTIMEOUT | + WDIOF_MAGICCLOSE, + .firmware_version = 0, + .identity = "ALi M1535 WatchDog Timer", + }; + + switch (cmd) { + case WDIOC_GETSUPPORT: + return copy_to_user((struct watchdog_info *) arg, &ident, + sizeof (ident)) ? -EFAULT : 0; + + case WDIOC_GETSTATUS: + case WDIOC_GETBOOTSTATUS: + return put_user(0, (int *) arg); + + case WDIOC_KEEPALIVE: + ali_keepalive(); + return 0; + + case WDIOC_SETOPTIONS: + { + int new_options, retval = -EINVAL; + + if (get_user (new_options, (int *) arg)) + return -EFAULT; + + if (new_options & WDIOS_DISABLECARD) { + ali_stop(); + retval = 0; + } + + if (new_options & WDIOS_ENABLECARD) { + ali_start(); + retval = 0; + } + + return retval; + } + + case WDIOC_SETTIMEOUT: + { + int new_timeout; + + if (get_user(new_timeout, (int *) arg)) + return -EFAULT; + + if (ali_settimer(new_timeout)) + return -EINVAL; + + ali_keepalive(); + /* Fall */ + } + + case WDIOC_GETTIMEOUT: + return put_user(timeout, (int *)arg); + + default: + return -ENOIOCTLCMD; + } +} + +/* + * ali_open - handle open of ali watchdog + * @inode: inode from VFS + * @file: file from VFS + * + * Open the ALi watchdog device. Ensure only one person opens it + * at a time. Also start the watchdog running. + */ + +static int ali_open(struct inode *inode, struct file *file) +{ + /* /dev/watchdog can only be opened once */ + if (test_and_set_bit(0, &ali_is_open)) + return -EBUSY; + + /* Activate */ + ali_start(); + return 0; +} + +/* + * ali_release - close an ALi watchdog + * @inode: inode from VFS + * @file: file from VFS + * + * Close the ALi watchdog device. Actual shutdown of the timer + * only occurs if the magic sequence has been set. + */ + +static int ali_release(struct inode *inode, struct file *file) +{ + /* + * Shut off the timer. + */ + if (ali_expect_release == 42) { + ali_stop(); + } else { + printk(KERN_CRIT PFX "Unexpected close, not stopping watchdog!\n"); + ali_keepalive(); + } + clear_bit(0, &ali_is_open); + ali_expect_release = 0; + return 0; +} + +/* + * ali_notify_sys - System down notifier + * + * Notifier for system down + */ + + +static int ali_notify_sys(struct notifier_block *this, unsigned long code, void *unused) +{ + if (code==SYS_DOWN || code==SYS_HALT) { + /* Turn the WDT off */ + ali_stop(); + } + + return NOTIFY_DONE; +} + +/* + * Data for PCI driver interface + * + * This data only exists for exporting the supported + * PCI ids via MODULE_DEVICE_TABLE. We do not actually + * register a pci_driver, because someone else might one day + * want to register another driver on the same PCI id. + */ + +static struct pci_device_id ali_pci_tbl[] __initdata = { + { PCI_VENDOR_ID_AL, 1535, PCI_ANY_ID, PCI_ANY_ID,}, + { 0, }, +}; +MODULE_DEVICE_TABLE(pci, ali_pci_tbl); + +/* + * ali_find_watchdog - find a 1535 and 7101 + * + * Scans the PCI hardware for a 1535 series bridge and matching 7101 + * watchdog device. This may be overtight but it is better to be safe + */ + +static int __init ali_find_watchdog(void) +{ + struct pci_dev *pdev; + u32 wdog; + + /* Check for a 1535 series bridge */ + pdev = pci_find_device(PCI_VENDOR_ID_AL, 0x1535, NULL); + if(pdev == NULL) + return -ENODEV; + + /* Check for the a 7101 PMU */ + pdev = pci_find_device(PCI_VENDOR_ID_AL, 0x7101, NULL); + if(pdev == NULL) + return -ENODEV; + + if(pci_enable_device(pdev)) + return -EIO; + + ali_pci = pdev; + + /* + * Initialize the timer bits + */ + pci_read_config_dword(pdev, 0xCC, &wdog); + + wdog &= ~0x3F; /* Timer bits */ + wdog &= ~((1<<27)|(1<<26)|(1<<25)|(1<<24)); /* Issued events */ + wdog &= ~((1<<16)|(1<<13)|(1<<12)|(1<<11)|(1<<10)|(1<<9)); /* No monitor bits */ + + pci_write_config_dword(pdev, 0xCC, wdog); + + return 0; +} + +/* + * Kernel Interfaces + */ + +static struct file_operations ali_fops = { + .owner = THIS_MODULE, + .llseek = no_llseek, + .write = ali_write, + .ioctl = ali_ioctl, + .open = ali_open, + .release = ali_release, +}; + +static struct miscdevice ali_miscdev = { + .minor = WATCHDOG_MINOR, + .name = "watchdog", + .fops = &ali_fops, +}; + +static struct notifier_block ali_notifier = { + .notifier_call = ali_notify_sys, + .next = NULL, + .priority = 0, +}; + +/* + * watchdog_init - module initialiser + * + * Scan for a suitable watchdog and if so initialize it. Return an error + * if we cannot, the error causes the module to unload + */ + +static int __init watchdog_init(void) +{ + int ret; + + spin_lock_init(&ali_lock); + + /* Check wether or not the hardware watchdog is there */ + if (ali_find_watchdog() != 0) { + return -ENODEV; + } + + /* Check that the timeout value is within it's range ; if not reset to the default */ + if (timeout < 1 || timeout >= 18000) { + timeout = WATCHDOG_TIMEOUT; + printk(KERN_INFO PFX "timeout value must be 0i_rdev)) { + switch(iminor(inode)) { case WATCHDOG_MINOR: if ( test_and_set_bit(0, &cpu5wdt_device.inuse) ) return -EBUSY; @@ -148,7 +148,7 @@ static int cpu5wdt_release(struct inode *inode, struct file *file) { - if(minor(inode->i_rdev)==WATCHDOG_MINOR) { + if(iminor(inode)==WATCHDOG_MINOR) { clear_bit(0, &cpu5wdt_device.inuse); } return 0; diff -Nru a/drivers/char/watchdog/ib700wdt.c b/drivers/char/watchdog/ib700wdt.c --- a/drivers/char/watchdog/ib700wdt.c Tue Sep 2 19:58:19 2003 +++ b/drivers/char/watchdog/ib700wdt.c Tue Sep 2 19:58:19 2003 @@ -218,7 +218,7 @@ static int ibwdt_open(struct inode *inode, struct file *file) { - if (minor(inode->i_rdev) == WATCHDOG_MINOR) { + if (iminor(inode) == WATCHDOG_MINOR) { spin_lock(&ibwdt_lock); if (ibwdt_is_open) { spin_unlock(&ibwdt_lock); @@ -240,7 +240,7 @@ static int ibwdt_close(struct inode *inode, struct file *file) { - if (minor(inode->i_rdev) == WATCHDOG_MINOR) { + if (iminor(inode) == WATCHDOG_MINOR) { spin_lock(&ibwdt_lock); if (expect_close) outb_p(wd_times[wd_margin], WDT_STOP); diff -Nru a/drivers/char/watchdog/machzwd.c b/drivers/char/watchdog/machzwd.c --- a/drivers/char/watchdog/machzwd.c Tue Sep 2 19:58:13 2003 +++ b/drivers/char/watchdog/machzwd.c Tue Sep 2 19:58:13 2003 @@ -377,7 +377,7 @@ static int zf_open(struct inode *inode, struct file *file) { - switch(minor(inode->i_rdev)){ + switch(iminor(inode)){ case WATCHDOG_MINOR: spin_lock(&zf_lock); if(zf_is_open){ @@ -402,7 +402,7 @@ static int zf_close(struct inode *inode, struct file *file) { - if(minor(inode->i_rdev) == WATCHDOG_MINOR){ + if(iminor(inode) == WATCHDOG_MINOR){ if(zf_expect_close){ zf_timer_off(); diff -Nru a/drivers/char/watchdog/pcwd.c b/drivers/char/watchdog/pcwd.c --- a/drivers/char/watchdog/pcwd.c Tue Sep 2 19:58:13 2003 +++ b/drivers/char/watchdog/pcwd.c Tue Sep 2 19:58:13 2003 @@ -426,7 +426,7 @@ static int pcwd_open(struct inode *ino, struct file *filep) { - switch (minor(ino->i_rdev)) { + switch (iminor(ino)) { case WATCHDOG_MINOR: if (!atomic_dec_and_test(&open_allowed) ) { atomic_inc( &open_allowed ); @@ -457,7 +457,7 @@ /* Can't seek (pread) on this device */ if (ppos != &file->f_pos) return -ESPIPE; - switch(minor(file->f_dentry->d_inode->i_rdev)) + switch(iminor(file->f_dentry->d_inode)) { case TEMP_MINOR: /* @@ -477,7 +477,7 @@ static int pcwd_close(struct inode *ino, struct file *filep) { - if (minor(ino->i_rdev)==WATCHDOG_MINOR) { + if (iminor(ino)==WATCHDOG_MINOR) { if (expect_close) { /* Disable the board */ if (revision == PCWD_REVISION_C) { diff -Nru a/drivers/char/watchdog/wafer5823wdt.c b/drivers/char/watchdog/wafer5823wdt.c --- a/drivers/char/watchdog/wafer5823wdt.c Tue Sep 2 19:58:19 2003 +++ b/drivers/char/watchdog/wafer5823wdt.c Tue Sep 2 19:58:19 2003 @@ -1,5 +1,5 @@ /* - * ICP Wafer 5823 Single Board Computer WDT driver for Linux 2.4.x + * ICP Wafer 5823 Single Board Computer WDT driver * http://www.icpamerica.com/wafer_5823.php * May also work on other similar models * @@ -17,10 +17,10 @@ * 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. - * - * Neither Alan Cox nor CymruNet Ltd. admit liability nor provide - * warranty for any of this software. This material is provided - * "AS-IS" and at no charge. + * + * Neither Alan Cox nor CymruNet Ltd. admit liability nor provide + * warranty for any of this software. This material is provided + * "AS-IS" and at no charge. * * (c) Copyright 1995 Alan Cox * @@ -39,9 +39,13 @@ #include #include +#define WATCHDOG_NAME "Wafer 5823 WDT" +#define PFX WATCHDOG_NAME ": " +#define WD_TIMO 60 /* 60 sec default timeout */ + static unsigned long wafwdt_is_open; +static char expect_close; static spinlock_t wafwdt_lock; -static int expect_close = 0; /* * You must set these - there is no sane way to probe for this board. @@ -52,11 +56,17 @@ * to restart it again. */ -#define WDT_START 0x443 -#define WDT_STOP 0x843 - -#define WD_TIMO 60 /* 1 minute */ -static int wd_margin = WD_TIMO; +static int wdt_stop = 0x843; +module_param(wdt_stop, int, 0); +MODULE_PARM_DESC(wdt_stop, "Wafer 5823 WDT 'stop' io port (default 0x843)"); + +static int wdt_start = 0x443; +module_param(wdt_start, int, 0); +MODULE_PARM_DESC(wdt_start, "Wafer 5823 WDT 'start' io port (default 0x443)"); + +static int timeout = WD_TIMO; /* in seconds */ +module_param(timeout, int, 0); +MODULE_PARM_DESC(timeout, "Watchdog timeout in seconds. 1<= timeout <=255, default=" __MODULE_STRING(WD_TIMO) "."); #ifdef CONFIG_WATCHDOG_NOWAYOUT static int nowayout = 1; @@ -70,24 +80,24 @@ static void wafwdt_ping(void) { /* pat watchdog */ - spin_lock(&wafwdt_lock); - inb_p(WDT_STOP); - inb_p(WDT_START); - spin_unlock(&wafwdt_lock); + spin_lock(&wafwdt_lock); + inb_p(wdt_stop); + inb_p(wdt_start); + spin_unlock(&wafwdt_lock); } static void wafwdt_start(void) { /* start up watchdog */ - outb_p(wd_margin, WDT_START); - inb_p(WDT_START); + outb_p(timeout, wdt_start); + inb_p(wdt_start); } static void wafwdt_stop(void) { /* stop watchdog */ - inb_p(WDT_STOP); + inb_p(wdt_stop); } static ssize_t wafwdt_write(struct file *file, const char *buf, size_t count, loff_t * ppos) @@ -96,6 +106,7 @@ if (ppos != &file->f_pos) return -ESPIPE; + /* See if we got the magic character 'V' and reload the timer */ if (count) { if (!nowayout) { size_t i; @@ -103,30 +114,30 @@ /* In case it was set long ago */ expect_close = 0; + /* scan to see wether or not we got the magic character */ for (i = 0; i != count; i++) { char c; if (get_user(c, buf + i)) return -EFAULT; if (c == 'V') - expect_close = 1; + expect_close = 42; } } + /* Well, anyhow someone wrote to us, we should return that favour */ wafwdt_ping(); - return 1; } - return 0; + return count; } static int wafwdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) { - int new_margin; + int new_timeout; static struct watchdog_info ident = { .options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE, .firmware_version = 1, - .identity = "Wafer 5823 WDT" + .identity = "Wafer 5823 WDT", }; - int one=1; switch (cmd) { case WDIOC_GETSUPPORT: @@ -136,25 +147,44 @@ break; case WDIOC_GETSTATUS: - if (copy_to_user((int *) arg, &one, sizeof (int))) - return -EFAULT; - break; + case WDIOC_GETBOOTSTATUS: + return put_user(0, (int *)arg); case WDIOC_KEEPALIVE: wafwdt_ping(); break; case WDIOC_SETTIMEOUT: - if (get_user(new_margin, (int *)arg)) + if (get_user(new_timeout, (int *)arg)) return -EFAULT; - if ((new_margin < 1) || (new_margin > 255)) + if ((new_timeout < 1) || (new_timeout > 255)) return -EINVAL; - wd_margin = new_margin; + timeout = new_timeout; wafwdt_stop(); wafwdt_start(); /* Fall */ case WDIOC_GETTIMEOUT: - return put_user(wd_margin, (int *)arg); + return put_user(timeout, (int *)arg); + + case WDIOC_SETOPTIONS: + { + int options, retval = -EINVAL; + + if (get_user(options, (int *)arg)) + return -EFAULT; + + if (options & WDIOS_DISABLECARD) { + wafwdt_start(); + retval = 0; + } + + if (options & WDIOS_ENABLECARD) { + wafwdt_stop(); + retval = 0; + } + + return retval; + } default: return -ENOTTY; @@ -166,6 +196,10 @@ { if (test_and_set_bit(0, &wafwdt_is_open)) return -EBUSY; + + /* + * Activate + */ wafwdt_start(); return 0; } @@ -173,12 +207,14 @@ static int wafwdt_close(struct inode *inode, struct file *file) { - clear_bit(0, &wafwdt_is_open); - if (expect_close) { + if (expect_close == 42) { wafwdt_stop(); } else { - printk(KERN_CRIT "WDT device closed unexpectedly. WDT will not stop!\n"); + printk(KERN_CRIT PFX "WDT device closed unexpectedly. WDT will not stop!\n"); + wafwdt_ping(); } + clear_bit(0, &wafwdt_is_open); + expect_close = 0; return 0; } @@ -201,6 +237,7 @@ static struct file_operations wafwdt_fops = { .owner = THIS_MODULE, + .llseek = no_llseek, .write = wafwdt_write, .ioctl = wafwdt_ioctl, .open = wafwdt_open, @@ -210,53 +247,93 @@ static struct miscdevice wafwdt_miscdev = { .minor = WATCHDOG_MINOR, .name = "watchdog", - .fops = &wafwdt_fops + .fops = &wafwdt_fops, }; /* * The WDT needs to learn about soft shutdowns in order to - * turn the timebomb registers off. + * turn the timebomb registers off. */ static struct notifier_block wafwdt_notifier = { .notifier_call = wafwdt_notify_sys, .next = NULL, - .priority = 0 + .priority = 0, }; static int __init wafwdt_init(void) { + int ret; + printk(KERN_INFO "WDT driver for Wafer 5823 single board computer initialising.\n"); spin_lock_init(&wafwdt_lock); - if(!request_region(WDT_STOP, 1, "Wafer 5823 WDT")) - goto error; - if(!request_region(WDT_START, 1, "Wafer 5823 WDT")) + + if (timeout < 1 || timeout > 63) { + timeout = WD_TIMO; + printk (KERN_INFO PFX "timeout value must be 1<=x<=255, using %d\n", + timeout); + } + + if (wdt_stop != wdt_start) { + if(!request_region(wdt_stop, 1, "Wafer 5823 WDT")) { + printk (KERN_ERR PFX "I/O address 0x%04x already in use\n", + wdt_stop); + ret = -EIO; + goto error; + } + } + + if(!request_region(wdt_start, 1, "Wafer 5823 WDT")) { + printk (KERN_ERR PFX "I/O address 0x%04x already in use\n", + wdt_start); + ret = -EIO; goto error2; - if(misc_register(&wafwdt_miscdev)<0) + } + + ret = register_reboot_notifier(&wafwdt_notifier); + if (ret != 0) { + printk (KERN_ERR PFX "cannot register reboot notifier (err=%d)\n", + ret); goto error3; - register_reboot_notifier(&wafwdt_notifier); - return 0; + } + + ret = misc_register(&wafwdt_miscdev); + if (ret != 0) { + printk (KERN_ERR PFX "cannot register miscdev on minor=%d (err=%d)\n", + WATCHDOG_MINOR, ret); + goto error4; + } + + printk (KERN_INFO PFX "initialized. timeout=%d sec (nowayout=%d)\n", + timeout, nowayout); + + return ret; +error4: + unregister_reboot_notifier(&wafwdt_notifier); error3: - release_region(WDT_START, 1); + release_region(wdt_start, 1); error2: - release_region(WDT_STOP, 1); + if (wdt_stop != wdt_start) + release_region(wdt_stop, 1); error: - return -ENODEV; + return ret; } static void __exit wafwdt_exit(void) { misc_deregister(&wafwdt_miscdev); unregister_reboot_notifier(&wafwdt_notifier); - release_region(WDT_STOP, 1); - release_region(WDT_START, 1); + if(wdt_stop != wdt_start) + release_region(wdt_stop, 1); + release_region(wdt_start, 1); } module_init(wafwdt_init); module_exit(wafwdt_exit); MODULE_AUTHOR("Justin Cormack"); +MODULE_DESCRIPTION("ICP Wafer 5823 Single Board Computer WDT driver"); MODULE_LICENSE("GPL"); /* end of wafer5823wdt.c */ diff -Nru a/drivers/char/watchdog/wdt.c b/drivers/char/watchdog/wdt.c --- a/drivers/char/watchdog/wdt.c Tue Sep 2 19:58:16 2003 +++ b/drivers/char/watchdog/wdt.c Tue Sep 2 19:58:16 2003 @@ -290,7 +290,7 @@ if (ptr != &file->f_pos) return -ESPIPE; - switch(minor(file->f_dentry->d_inode->i_rdev)) + switch(iminor(file->f_dentry->d_inode)) { case TEMP_MINOR: c*=11; @@ -373,7 +373,7 @@ static int wdt_open(struct inode *inode, struct file *file) { - switch(minor(inode->i_rdev)) + switch(iminor(inode)) { case WATCHDOG_MINOR: if(test_and_set_bit(0, &wdt_is_open)) @@ -413,7 +413,7 @@ static int wdt_release(struct inode *inode, struct file *file) { - if(minor(inode->i_rdev)==WATCHDOG_MINOR) + if(iminor(inode)==WATCHDOG_MINOR) { if (expect_close) { inb_p(WDT_DC); /* Disable counters */ diff -Nru a/drivers/char/watchdog/wdt_pci.c b/drivers/char/watchdog/wdt_pci.c --- a/drivers/char/watchdog/wdt_pci.c Tue Sep 2 19:58:17 2003 +++ b/drivers/char/watchdog/wdt_pci.c Tue Sep 2 19:58:17 2003 @@ -276,7 +276,7 @@ if (ptr != &file->f_pos) return -ESPIPE; - switch(minor(file->f_dentry->d_inode->i_rdev)) + switch(iminor(file->f_dentry->d_inode)) { case TEMP_MINOR: c*=11; @@ -361,7 +361,7 @@ { unsigned long flags; - switch(minor(inode->i_rdev)) + switch(iminor(inode)) { case WATCHDOG_MINOR: if (down_trylock(&open_sem)) @@ -423,7 +423,7 @@ static int wdtpci_release(struct inode *inode, struct file *file) { - if (minor(inode->i_rdev)==WATCHDOG_MINOR) { + if (iminor(inode)==WATCHDOG_MINOR) { unsigned long flags; if (expect_close) { spin_lock_irqsave(&wdtpci_lock, flags); diff -Nru a/drivers/i2c/Kconfig b/drivers/i2c/Kconfig --- a/drivers/i2c/Kconfig Tue Sep 2 19:58:14 2003 +++ b/drivers/i2c/Kconfig Tue Sep 2 19:58:14 2003 @@ -150,7 +150,7 @@ config I2C_ELEKTOR tristate "Elektor ISA card" - depends on I2C_ALGOPCF + depends on I2C_ALGOPCF && BROKEN_ON_SMP help This supports the PCF8584 ISA bus I2C adapter. Say Y if you own such an adapter. diff -Nru a/drivers/i2c/i2c-dev.c b/drivers/i2c/i2c-dev.c --- a/drivers/i2c/i2c-dev.c Tue Sep 2 19:58:18 2003 +++ b/drivers/i2c/i2c-dev.c Tue Sep 2 19:58:18 2003 @@ -138,7 +138,7 @@ return -ENOMEM; pr_debug("i2c-dev.o: i2c-%d reading %d bytes.\n", - minor(file->f_dentry->d_inode->i_rdev), count); + iminor(file->f_dentry->d_inode), count); ret = i2c_master_recv(client,tmp,count); if (ret >= 0) @@ -166,7 +166,7 @@ } pr_debug("i2c-dev.o: i2c-%d writing %d bytes.\n", - minor(file->f_dentry->d_inode->i_rdev), count); + iminor(file->f_dentry->d_inode), count); ret = i2c_master_send(client,tmp,count); kfree(tmp); @@ -186,7 +186,7 @@ unsigned long funcs; dev_dbg(&client->dev, "i2c-%d ioctl, cmd: 0x%x, arg: %lx.\n", - minor(inode->i_rdev),cmd, arg); + iminor(inode),cmd, arg); switch ( cmd ) { case I2C_SLAVE: @@ -373,7 +373,7 @@ static int i2cdev_open(struct inode *inode, struct file *file) { - unsigned int minor = minor(inode->i_rdev); + unsigned int minor = iminor(inode); struct i2c_client *client; struct i2c_adapter *adap; struct i2c_dev *i2c_dev; diff -Nru a/drivers/i2c/i2c-keywest.c b/drivers/i2c/i2c-keywest.c --- a/drivers/i2c/i2c-keywest.c Tue Sep 2 19:58:17 2003 +++ b/drivers/i2c/i2c-keywest.c Tue Sep 2 19:58:17 2003 @@ -81,9 +81,6 @@ int probe = 0; int debug = 0; -static struct keywest_iface *ifaces = NULL; - - static void do_stop(struct keywest_iface* iface, int result) { @@ -306,6 +303,7 @@ write_reg(reg_control, read_reg(reg_control) | KW_I2C_CTL_XADDR); write_reg(reg_ier, KW_I2C_IRQ_MASK); + /* Wait interrupt operations completion */ wait_for_completion(&iface->complete); rc = iface->result; @@ -385,6 +383,7 @@ write_reg(reg_control, read_reg(reg_control) | KW_I2C_CTL_XADDR); write_reg(reg_ier, KW_I2C_IRQ_MASK); + /* Wait interrupt operations completion */ wait_for_completion(&iface->complete); rc = iface->result; @@ -409,16 +408,16 @@ /* For now, we only handle combined mode (smbus) */ static struct i2c_algorithm keywest_algorithm = { - name: "Keywest i2c", - id: I2C_ALGO_SMBUS, - smbus_xfer: keywest_smbus_xfer, - master_xfer: keywest_xfer, - functionality: keywest_func, + .name = "Keywest i2c", + .id = I2C_ALGO_SMBUS, + .smbus_xfer = keywest_smbus_xfer, + .master_xfer = keywest_xfer, + .functionality = keywest_func, }; static int -create_iface(struct device_node* np) +create_iface(struct device_node *np, struct device *dev) { unsigned long steps, *psteps, *prate; unsigned bsteps, tsize, i, nchan, addroffset; @@ -487,8 +486,8 @@ *prate); } - /* Select standard mode by default */ - iface->cur_mode |= KW_I2C_MODE_STANDARD; + /* Select standard sub mode */ + iface->cur_mode |= KW_I2C_MODE_STANDARDSUB; /* Write mode */ write_reg(reg_mode, iface->cur_mode); @@ -506,11 +505,13 @@ return -ENODEV; } + dev_set_drvdata(dev, iface); + for (i=0; ichannels[i]; u8 addr; - sprintf(chan->adapter.dev.name, "%s %d", np->parent->name, i); + sprintf(chan->adapter.name, "%s %d", np->parent->name, i); chan->iface = iface; chan->chan_no = i; chan->adapter.id = I2C_ALGO_SMBUS; @@ -519,11 +520,12 @@ chan->adapter.client_register = NULL; chan->adapter.client_unregister = NULL; i2c_set_adapdata(&chan->adapter, chan); + chan->adapter.dev.parent = dev; rc = i2c_add_adapter(&chan->adapter); if (rc) { printk("i2c-keywest.c: Adapter %s registration failed\n", - chan->adapter.dev.name); + chan->adapter.name); i2c_set_adapdata(&chan->adapter, NULL); } if (probe) { @@ -540,20 +542,18 @@ printk(KERN_INFO "Found KeyWest i2c on \"%s\", %d channel%s, stepping: %d bits\n", np->parent->name, nchan, nchan > 1 ? "s" : "", bsteps); - iface->next = ifaces; - ifaces = iface; return 0; } -static void -dispose_iface(struct keywest_iface *iface) +static int +dispose_iface(struct device *dev) { + struct keywest_iface *iface = dev_get_drvdata(dev); int i, rc; - ifaces = iface->next; - /* Make sure we stop all activity */ down(&iface->sem); + spin_lock_irq(&iface->lock); while (iface->state != state_idle) { spin_unlock_irq(&iface->lock); @@ -578,31 +578,76 @@ printk("i2c-keywest.c: i2c_del_adapter failed, that's bad !\n"); } iounmap((void *)iface->base); + dev_set_drvdata(dev, NULL); kfree(iface); + + return 0; +} + +static int +create_iface_macio(struct macio_dev* dev, const struct of_match *match) +{ + return create_iface(dev->ofdev.node, &dev->ofdev.dev); +} + +static int +dispose_iface_macio(struct macio_dev* dev) +{ + return dispose_iface(&dev->ofdev.dev); +} + +static int +create_iface_of_platform(struct of_device* dev, const struct of_match *match) +{ + return create_iface(dev->node, &dev->dev); +} + +static int +dispose_iface_of_platform(struct of_device* dev) +{ + return dispose_iface(&dev->dev); } +static struct of_match i2c_keywest_match[] = +{ + { + .name = OF_ANY_MATCH, + .type = "i2c", + .compatible = "keywest" + }, + {}, +}; + +static struct macio_driver i2c_keywest_macio_driver = +{ + .name = "i2c-keywest", + .match_table = i2c_keywest_match, + .probe = create_iface_macio, + .remove = dispose_iface_macio +}; + +static struct of_platform_driver i2c_keywest_of_platform_driver = +{ + .name = "i2c-keywest", + .match_table = i2c_keywest_match, + .probe = create_iface_of_platform, + .remove = dispose_iface_of_platform +}; + static int __init i2c_keywest_init(void) { - struct device_node *np; - int rc = -ENODEV; - - np = find_compatible_devices("i2c", "keywest"); - while (np != 0) { - if (np->n_addrs >= 1 && np->n_intrs >= 1) - rc = create_iface(np); - np = np->next; - } - if (ifaces) - rc = 0; - return rc; + macio_register_driver(&i2c_keywest_macio_driver); + of_register_driver(&i2c_keywest_of_platform_driver); + + return 0; } static void __exit i2c_keywest_cleanup(void) { - while(ifaces) - dispose_iface(ifaces); + macio_unregister_driver(&i2c_keywest_macio_driver); + of_unregister_driver(&i2c_keywest_of_platform_driver); } module_init(i2c_keywest_init); diff -Nru a/drivers/i2c/i2c-keywest.h b/drivers/i2c/i2c-keywest.h --- a/drivers/i2c/i2c-keywest.h Tue Sep 2 19:58:18 2003 +++ b/drivers/i2c/i2c-keywest.h Tue Sep 2 19:58:18 2003 @@ -67,7 +67,6 @@ int stopretry; struct timer_list timeout_timer; struct completion complete; - struct keywest_iface* next; }; enum { diff -Nru a/drivers/ide/Kconfig b/drivers/ide/Kconfig --- a/drivers/ide/Kconfig Tue Sep 2 19:58:15 2003 +++ b/drivers/ide/Kconfig Tue Sep 2 19:58:15 2003 @@ -815,6 +815,17 @@ most of the recent Apple Power Macintoshes and PowerBooks. If unsure, say Y. +config BLK_DEV_IDE_PMAC_ATA100FIRST + bool "Probe internal ATA/100 (Kauai) first" + depends on BLK_DEV_IDE_PMAC + help + This option will cause the ATA/100 controller found in UniNorth2 + based machines (Windtunnel PowerMac, Aluminium PowerBooks, ...) + to be probed before the ATA/66 and ATA/33 controllers. Without + these, those machine used to have the hard disk on hdc and the + CD-ROM on hda. This option changes this to more natural hda for + hard disk and hdc for CD-ROM. + config BLK_DEV_IDEDMA_PMAC bool "PowerMac IDE DMA support" depends on BLK_DEV_IDE_PMAC diff -Nru a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c --- a/drivers/ide/ide-cd.c Tue Sep 2 19:58:15 2003 +++ b/drivers/ide/ide-cd.c Tue Sep 2 19:58:15 2003 @@ -794,16 +794,16 @@ request or data protect error.*/ ide_dump_status (drive, "command error", stat); do_end_request = 1; - } else if ((err & ~ABRT_ERR) != 0) { - /* Go to the default handler - for other errors. */ - DRIVER(drive)->error(drive, "cdrom_decode_status",stat); - return 1; } else if (sense_key == MEDIUM_ERROR) { /* No point in re-trying a zillion times on a bad * sector... If we got here the error is not correctable */ ide_dump_status (drive, "media error (bad sector)", stat); do_end_request = 1; + } else if ((err & ~ABRT_ERR) != 0) { + /* Go to the default handler + for other errors. */ + DRIVER(drive)->error(drive, "cdrom_decode_status",stat); + return 1; } else if ((++rq->errors > ERROR_MAX)) { /* We've racked up too many retries. Abort. */ do_end_request = 1; diff -Nru a/drivers/ide/ide-io.c b/drivers/ide/ide-io.c --- a/drivers/ide/ide-io.c Tue Sep 2 19:58:18 2003 +++ b/drivers/ide/ide-io.c Tue Sep 2 19:58:18 2003 @@ -54,8 +54,6 @@ #include #include -#include "ide_modes.h" - #if (DISK_RECOVERY_TIME > 0) #error So the User Has To Fix the Compilation And Stop Hacking Port 0x43. Does anyone ever use this anyway ?? diff -Nru a/drivers/ide/ide-lib.c b/drivers/ide/ide-lib.c --- a/drivers/ide/ide-lib.c Tue Sep 2 19:58:19 2003 +++ b/drivers/ide/ide-lib.c Tue Sep 2 19:58:19 2003 @@ -22,8 +22,6 @@ #include #include -#include "ide_modes.h" - /* * IDE library routines. These are plug in code that most * drivers can use but occasionally may be weird enough @@ -170,7 +168,7 @@ BUG(); return min(speed, speed_max[mode]); #else /* !CONFIG_BLK_DEV_IDEDMA */ - return min(speed, XFER_PIO_4); + return min(speed, (u8)XFER_PIO_4); #endif /* CONFIG_BLK_DEV_IDEDMA */ } @@ -188,6 +186,12 @@ EXPORT_SYMBOL(ide_dma_enable); +/* + * Standard (generic) timings for PIO modes, from ATA2 specification. + * These timings are for access to the IDE data port register *only*. + * Some drives may specify a mode, while also specifying a different + * value for cycle_time (from drive identification data). + */ const ide_pio_timings_t ide_pio_timings[6] = { { 70, 165, 600 }, /* PIO Mode 0 */ { 50, 125, 383 }, /* PIO Mode 1 */ @@ -198,6 +202,13 @@ }; EXPORT_SYMBOL_GPL(ide_pio_timings); + +/* + * Shared data/functions for determining best PIO mode for an IDE drive. + * Most of this stuff originally lived in cmd640.c, and changes to the + * ide_pio_blacklist[] table should be made with EXTREME CAUTION to avoid + * breaking the fragile cmd640.c support. + */ /* * Black list. Some drives incorrectly report their maximal PIO mode, diff -Nru a/drivers/ide/ide-probe.c b/drivers/ide/ide-probe.c --- a/drivers/ide/ide-probe.c Tue Sep 2 19:58:16 2003 +++ b/drivers/ide/ide-probe.c Tue Sep 2 19:58:16 2003 @@ -644,15 +644,26 @@ return drive->present; } +static void hwif_release_dev (struct device *dev) +{ + ide_hwif_t *hwif = container_of(dev, ide_hwif_t, gendev); + + up(&hwif->gendev_rel_sem); +} + static void hwif_register (ide_hwif_t *hwif) { /* register with global device tree */ strlcpy(hwif->gendev.bus_id,hwif->name,BUS_ID_SIZE); hwif->gendev.driver_data = hwif; - if (hwif->pci_dev) - hwif->gendev.parent = &hwif->pci_dev->dev; - else - hwif->gendev.parent = NULL; /* Would like to do = &device_legacy */ + if (hwif->gendev.parent == NULL) { + if (hwif->pci_dev) + hwif->gendev.parent = &hwif->pci_dev->dev; + else + /* Would like to do = &device_legacy */ + hwif->gendev.parent = NULL; + } + hwif->gendev.release = hwif_release_dev; device_register(&hwif->gendev); } @@ -770,8 +781,7 @@ */ for (unit = 0; unit < MAX_DRIVES; ++unit) { ide_drive_t *drive = &hwif->drives[unit]; - drive->dn = ((hwif->channel ? 2 : 0) + unit); - hwif->drives[unit].dn = ((hwif->channel ? 2 : 0) + unit); + drive->dn = (hwif->channel ? 2 : 0) + unit; (void) probe_for_drive(drive); if (drive->present && !hwif->present) { hwif->present = 1; @@ -945,15 +955,10 @@ if (drive->disk) drive->disk->queue = drive->queue; - return 0; -} - -/* - * Setup the drive for request handling. - */ -static void ide_init_drive(ide_drive_t *drive) -{ + /* needs drive->queue to be set */ ide_toggle_bounce(drive, 1); + + return 0; } /* @@ -1068,10 +1073,9 @@ } /* - * Link any new drives into the hwgroup, allocate - * the block device queue and initialize the drive. - * Note that ide_init_drive sends commands to the new - * drive. + * For any present drive: + * - allocate the block device queue + * - link drive into the hwgroup */ for (index = 0; index < MAX_DRIVES; ++index) { ide_drive_t *drive = &hwif->drives[index]; @@ -1092,7 +1096,6 @@ hwgroup->drive->next = drive; } spin_unlock_irq(&ide_lock); - ide_init_drive(drive); } #if !defined(__mc68000__) && !defined(CONFIG_APUS) && !defined(__sparc__) @@ -1201,6 +1204,13 @@ return -ENOMEM; } +static void drive_release_dev (struct device *dev) +{ + ide_drive_t *drive = container_of(dev, ide_drive_t, gendev); + + up(&drive->gendev_rel_sem); +} + /* * init_gendisk() (as opposed to ide_geninit) is called for each major device, * after probing for drives, to allocate partition tables and other data @@ -1219,6 +1229,7 @@ drive->gendev.parent = &hwif->gendev; drive->gendev.bus = &ide_bus_type; drive->gendev.driver_data = drive; + drive->gendev.release = drive_release_dev; if (drive->present) { device_register(&drive->gendev); sprintf(drive->devfs_name, "ide/host%d/bus%d/target%d/lun%d", @@ -1303,31 +1314,6 @@ EXPORT_SYMBOL(hwif_init); -int export_ide_init_queue (ide_drive_t *drive) -{ - if (ide_init_queue(drive)) - return 1; - - ide_init_drive(drive); - return 0; -} - -EXPORT_SYMBOL(export_ide_init_queue); - -u8 export_probe_for_drive (ide_drive_t *drive) -{ - return probe_for_drive(drive); -} - -EXPORT_SYMBOL(export_probe_for_drive); - -int ideprobe_init (void); -static ide_module_t ideprobe_module = { - IDE_PROBE_MODULE, - ideprobe_init, - NULL -}; - int ideprobe_init (void) { unsigned int index; @@ -1359,7 +1345,7 @@ } } if (!ide_probe) - ide_probe = &ideprobe_module; + ide_probe = &ideprobe_init; MOD_DEC_USE_COUNT; return 0; } diff -Nru a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.c --- a/drivers/ide/ide-tape.c Tue Sep 2 19:58:14 2003 +++ b/drivers/ide/ide-tape.c Tue Sep 2 19:58:14 2003 @@ -4922,7 +4922,7 @@ struct inode *inode = file->f_dentry->d_inode; ide_drive_t *drive = file->private_data; idetape_tape_t *tape = drive->driver_data; - unsigned int minor = minor(inode->i_rdev); + unsigned int minor = iminor(inode); ssize_t retval, actually_written = 0; int position; @@ -5568,7 +5568,7 @@ */ static int idetape_chrdev_open (struct inode *inode, struct file *filp) { - unsigned int minor = minor(inode->i_rdev), i = minor & ~0xc0; + unsigned int minor = iminor(inode), i = minor & ~0xc0; ide_drive_t *drive; idetape_tape_t *tape; idetape_pc_t pc; @@ -5649,7 +5649,7 @@ ide_drive_t *drive = filp->private_data; idetape_tape_t *tape; idetape_pc_t pc; - unsigned int minor = minor(inode->i_rdev); + unsigned int minor = iminor(inode); lock_kernel(); tape = drive->driver_data; diff -Nru a/drivers/ide/ide.c b/drivers/ide/ide.c --- a/drivers/ide/ide.c Tue Sep 2 19:58:14 2003 +++ b/drivers/ide/ide.c Tue Sep 2 19:58:14 2003 @@ -161,8 +161,6 @@ #include #include -#include "ide_modes.h" - /* default maximum number of failures */ #define IDE_DEFAULT_MAX_FAILURES 1 @@ -180,7 +178,9 @@ DECLARE_MUTEX(ide_cfg_sem); spinlock_t ide_lock __cacheline_aligned_in_smp = SPIN_LOCK_UNLOCKED; +#ifdef CONFIG_BLK_DEV_IDEPCI static int ide_scan_direction; /* THIS was formerly 2.2.x pci=reverse */ +#endif #ifdef CONFIG_IDEDMA_AUTO int noautodma = 0; @@ -190,11 +190,7 @@ EXPORT_SYMBOL(noautodma); -/* - * ide_modules keeps track of the available IDE chipset/probe/driver modules. - */ -ide_module_t *ide_chipsets; -ide_module_t *ide_probe; +int (*ide_probe)(void); /* * This is declared extern in ide.h, for access by other IDE modules: @@ -255,6 +251,8 @@ hwif->mwdma_mask = 0x80; /* disable all mwdma */ hwif->swdma_mask = 0x80; /* disable all swdma */ + sema_init(&hwif->gendev_rel_sem, 0); + default_hwif_iops(hwif); default_hwif_transport(hwif); for (unit = 0; unit < MAX_DRIVES; ++unit) { @@ -277,6 +275,7 @@ drive->driver = &idedefault_driver; drive->vdma = 0; INIT_LIST_HEAD(&drive->list); + sema_init(&drive->gendev_rel_sem, 0); } } @@ -452,7 +451,7 @@ (void) request_module("ide-probe-mod"); #endif /* (CONFIG_KMOD) && (CONFIG_BLK_DEV_IDE_MODULE) */ } else { - (void) ide_probe->init(); + (void)ide_probe(); } } @@ -749,6 +748,7 @@ spin_unlock_irq(&ide_lock); blk_cleanup_queue(drive->queue); device_unregister(&drive->gendev); + down(&drive->gendev_rel_sem); spin_lock_irq(&ide_lock); drive->queue = NULL; } @@ -778,6 +778,7 @@ /* More messed up locking ... */ spin_unlock_irq(&ide_lock); device_unregister(&hwif->gendev); + down(&hwif->gendev_rel_sem); /* * Remove us from the kernel's knowledge @@ -1046,21 +1047,6 @@ EXPORT_SYMBOL(ide_register_hw); /* - * Compatibility function with existing drivers. If you want - * something different, use the function above. - */ -int ide_register (int arg1, int arg2, int irq) -{ - hw_regs_t hw; - ide_init_hwif_ports(&hw, (unsigned long) arg1, (unsigned long) arg2, NULL); - hw.irq = irq; - return ide_register_hw(&hw, NULL); -} - -EXPORT_SYMBOL(ide_register); - - -/* * Locks for IDE setting functionality */ @@ -1658,11 +1644,15 @@ case HDIO_SCAN_HWIF: { + hw_regs_t hw; int args[3]; if (!capable(CAP_SYS_RAWIO)) return -EACCES; if (copy_from_user(args, (void *)arg, 3 * sizeof(int))) return -EFAULT; - if (ide_register(args[0], args[1], args[2]) == -1) + ide_init_hwif_ports(&hw, (unsigned long) args[0], + (unsigned long) args[1], NULL); + hw.irq = args[2]; + if (ide_register_hw(&hw, NULL) == -1) return -EIO; return 0; } @@ -1870,7 +1860,7 @@ * registered. In most cases, only one device * will be present. * "hdx=scsi" : the return of the ide-scsi flag, this is useful for - * allowwing ide-floppy, ide-tape, and ide-cdrom|writers + * allowing ide-floppy, ide-tape, and ide-cdrom|writers * to use ide-scsi emulation on a device specific option. * "idebus=xx" : inform IDE driver of VESA/PCI bus speed in MHz, * where "xx" is between 20 and 66 inclusive, diff -Nru a/drivers/ide/ide_modes.h b/drivers/ide/ide_modes.h --- a/drivers/ide/ide_modes.h Tue Sep 2 19:58:12 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,41 +0,0 @@ -/* - * linux/drivers/ide/ide_modes.h - * - * Copyright (C) 1996 Linus Torvalds, Igor Abramov, and Mark Lord - */ - -#ifndef _IDE_MODES_H -#define _IDE_MODES_H - -#include - -/* - * Shared data/functions for determining best PIO mode for an IDE drive. - * Most of this stuff originally lived in cmd640.c, and changes to the - * ide_pio_blacklist[] table should be made with EXTREME CAUTION to avoid - * breaking the fragile cmd640.c support. - */ - -/* - * Standard (generic) timings for PIO modes, from ATA2 specification. - * These timings are for access to the IDE data port register *only*. - * Some drives may specify a mode, while also specifying a different - * value for cycle_time (from drive identification data). - */ -typedef struct ide_pio_timings_s { - int setup_time; /* Address setup (ns) minimum */ - int active_time; /* Active pulse (ns) minimum */ - int cycle_time; /* Cycle time (ns) minimum = (setup + active + recovery) */ -} ide_pio_timings_t; - -typedef struct ide_pio_data_s { - u8 pio_mode; - u8 use_iordy; - u8 overridden; - u8 blacklisted; - unsigned int cycle_time; -} ide_pio_data_t; - -u8 ide_get_best_pio_mode (ide_drive_t *drive, u8 mode_wanted, u8 max_mode, ide_pio_data_t *d); -extern const ide_pio_timings_t ide_pio_timings[6]; -#endif /* _IDE_MODES_H */ diff -Nru a/drivers/ide/legacy/ali14xx.c b/drivers/ide/legacy/ali14xx.c --- a/drivers/ide/legacy/ali14xx.c Tue Sep 2 19:58:13 2003 +++ b/drivers/ide/legacy/ali14xx.c Tue Sep 2 19:58:13 2003 @@ -54,8 +54,6 @@ #include -#include "ide_modes.h" - /* port addresses for auto-detection */ #define ALI_NUM_PORTS 4 static int ports[ALI_NUM_PORTS] __initdata = {0x074, 0x0f4, 0x034, 0x0e4}; diff -Nru a/drivers/ide/legacy/dtc2278.c b/drivers/ide/legacy/dtc2278.c --- a/drivers/ide/legacy/dtc2278.c Tue Sep 2 19:58:14 2003 +++ b/drivers/ide/legacy/dtc2278.c Tue Sep 2 19:58:14 2003 @@ -21,8 +21,6 @@ #include -#include "ide_modes.h" - /* * Changing this #undef to #define may solve start up problems in some systems. */ diff -Nru a/drivers/ide/legacy/ht6560b.c b/drivers/ide/legacy/ht6560b.c --- a/drivers/ide/legacy/ht6560b.c Tue Sep 2 19:58:18 2003 +++ b/drivers/ide/legacy/ht6560b.c Tue Sep 2 19:58:18 2003 @@ -53,8 +53,6 @@ #include -#include "ide_modes.h" - /* #define DEBUG */ /* remove comments for DEBUG messages */ /* diff -Nru a/drivers/ide/legacy/macide.c b/drivers/ide/legacy/macide.c --- a/drivers/ide/legacy/macide.c Tue Sep 2 19:58:12 2003 +++ b/drivers/ide/legacy/macide.c Tue Sep 2 19:58:12 2003 @@ -126,7 +126,7 @@ /* probing the drive which freezes a 190. */ ide_drive_t *drive = &ide_hwifs[index].drives[0]; - drive->capacity = drive->cyl*drive->head*drive->sect; + drive->capacity64 = drive->cyl*drive->head*drive->sect; #ifdef CONFIG_BLK_DEV_MAC_MEDIABAY request_irq(IRQ_BABOON_2, macide_mediabay_interrupt, diff -Nru a/drivers/ide/legacy/qd65xx.c b/drivers/ide/legacy/qd65xx.c --- a/drivers/ide/legacy/qd65xx.c Tue Sep 2 19:58:13 2003 +++ b/drivers/ide/legacy/qd65xx.c Tue Sep 2 19:58:13 2003 @@ -42,7 +42,6 @@ #include #include -#include "ide_modes.h" #include "qd65xx.h" /* diff -Nru a/drivers/ide/legacy/umc8672.c b/drivers/ide/legacy/umc8672.c --- a/drivers/ide/legacy/umc8672.c Tue Sep 2 19:58:13 2003 +++ b/drivers/ide/legacy/umc8672.c Tue Sep 2 19:58:13 2003 @@ -54,8 +54,6 @@ #include -#include "ide_modes.h" - /* * Default speeds. These can be changed with "auto-tune" and/or hdparm. */ diff -Nru a/drivers/ide/pci/aec62xx.c b/drivers/ide/pci/aec62xx.c --- a/drivers/ide/pci/aec62xx.c Tue Sep 2 19:58:18 2003 +++ b/drivers/ide/pci/aec62xx.c Tue Sep 2 19:58:18 2003 @@ -16,7 +16,6 @@ #include -#include "ide_modes.h" #include "aec62xx.h" #if defined(DISPLAY_AEC62XX_TIMINGS) && defined(CONFIG_PROC_FS) diff -Nru a/drivers/ide/pci/alim15x3.c b/drivers/ide/pci/alim15x3.c --- a/drivers/ide/pci/alim15x3.c Tue Sep 2 19:58:15 2003 +++ b/drivers/ide/pci/alim15x3.c Tue Sep 2 19:58:15 2003 @@ -37,7 +37,6 @@ #include -#include "ide_modes.h" #include "alim15x3.h" /* diff -Nru a/drivers/ide/pci/cmd640.c b/drivers/ide/pci/cmd640.c --- a/drivers/ide/pci/cmd640.c Tue Sep 2 19:58:19 2003 +++ b/drivers/ide/pci/cmd640.c Tue Sep 2 19:58:19 2003 @@ -115,8 +115,6 @@ #include -#include "ide_modes.h" - /* * This flag is set in ide.c by the parameter: ide0=cmd640_vlb */ diff -Nru a/drivers/ide/pci/cmd64x.c b/drivers/ide/pci/cmd64x.c --- a/drivers/ide/pci/cmd64x.c Tue Sep 2 19:58:18 2003 +++ b/drivers/ide/pci/cmd64x.c Tue Sep 2 19:58:18 2003 @@ -25,7 +25,6 @@ #include -#include "ide_modes.h" #include "cmd64x.h" #if defined(DISPLAY_CMD64X_TIMINGS) && defined(CONFIG_PROC_FS) @@ -629,10 +628,7 @@ /* Set a good latency timer and cache line size value. */ (void) pci_write_config_byte(dev, PCI_LATENCY_TIMER, 64); -#ifdef __sparc_v9__ - (void) pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, 0x10); -#endif - + /* FIXME: pci_set_master() to ensure a good latency timer value */ /* Setup interrupts. */ (void) pci_read_config_byte(dev, MRDMODE, &mrdmode); diff -Nru a/drivers/ide/pci/cs5520.c b/drivers/ide/pci/cs5520.c --- a/drivers/ide/pci/cs5520.c Tue Sep 2 19:58:13 2003 +++ b/drivers/ide/pci/cs5520.c Tue Sep 2 19:58:13 2003 @@ -51,7 +51,6 @@ #include #include -#include "ide_modes.h" #include "cs5520.h" #if defined(DISPLAY_CS5520_TIMINGS) && defined(CONFIG_PROC_FS) diff -Nru a/drivers/ide/pci/cs5530.c b/drivers/ide/pci/cs5530.c --- a/drivers/ide/pci/cs5530.c Tue Sep 2 19:58:15 2003 +++ b/drivers/ide/pci/cs5530.c Tue Sep 2 19:58:15 2003 @@ -31,7 +31,6 @@ #include #include -#include "ide_modes.h" #include "cs5530.h" #if defined(DISPLAY_CS5530_TIMINGS) && defined(CONFIG_PROC_FS) diff -Nru a/drivers/ide/pci/cy82c693.c b/drivers/ide/pci/cy82c693.c --- a/drivers/ide/pci/cy82c693.c Tue Sep 2 19:58:13 2003 +++ b/drivers/ide/pci/cy82c693.c Tue Sep 2 19:58:13 2003 @@ -54,7 +54,6 @@ #include -#include "ide_modes.h" #include "cy82c693.h" /* @@ -113,7 +112,7 @@ /* note: we use the same values for 16bit IOR and IOW * those are all the same, since I don't have other - * timings than those from ide_modes.h + * timings than those from ide-lib.c */ p_pclk->time_16r = (u8)clk1; diff -Nru a/drivers/ide/pci/hpt34x.c b/drivers/ide/pci/hpt34x.c --- a/drivers/ide/pci/hpt34x.c Tue Sep 2 19:58:15 2003 +++ b/drivers/ide/pci/hpt34x.c Tue Sep 2 19:58:15 2003 @@ -42,7 +42,6 @@ #include #include -#include "ide_modes.h" #include "hpt34x.h" #if defined(DISPLAY_HPT34X_TIMINGS) && defined(CONFIG_PROC_FS) diff -Nru a/drivers/ide/pci/hpt366.c b/drivers/ide/pci/hpt366.c --- a/drivers/ide/pci/hpt366.c Tue Sep 2 19:58:16 2003 +++ b/drivers/ide/pci/hpt366.c Tue Sep 2 19:58:16 2003 @@ -62,7 +62,6 @@ #include #include -#include "ide_modes.h" #include "hpt366.h" #if defined(DISPLAY_HPT366_TIMINGS) && defined(CONFIG_PROC_FS) @@ -989,7 +988,40 @@ hwif->intrproc = &hpt3xx_intrproc; hwif->maskproc = &hpt3xx_maskproc; - pci_read_config_byte(hwif->pci_dev, 0x5a, &ata66); + /* + * The HPT37x uses the CBLID pins as outputs for MA15/MA16 + * address lines to access an external eeprom. To read valid + * cable detect state the pins must be enabled as inputs. + */ + if (hpt_minimum_revision(dev, 8) && PCI_FUNC(dev->devfn) & 1) { + /* + * HPT374 PCI function 1 + * - set bit 15 of reg 0x52 to enable TCBLID as input + * - set bit 15 of reg 0x56 to enable FCBLID as input + */ + u16 mcr3, mcr6; + pci_read_config_word(dev, 0x52, &mcr3); + pci_read_config_word(dev, 0x56, &mcr6); + pci_write_config_word(dev, 0x52, mcr3 | 0x8000); + pci_write_config_word(dev, 0x56, mcr6 | 0x8000); + /* now read cable id register */ + pci_read_config_byte(dev, 0x5a, &ata66); + pci_write_config_word(dev, 0x52, mcr3); + pci_write_config_word(dev, 0x56, mcr6); + } else if (hpt_minimum_revision(dev, 3)) { + /* + * HPT370/372 and 374 pcifn 0 + * - clear bit 0 of 0x5b to enable P/SCBLID as inputs + */ + u8 scr2; + pci_read_config_byte(dev, 0x5b, &scr2); + pci_write_config_byte(dev, 0x5b, scr2 & ~1); + /* now read cable id register */ + pci_read_config_byte(dev, 0x5a, &ata66); + pci_write_config_byte(dev, 0x5b, scr2); + } else { + pci_read_config_byte(dev, 0x5a, &ata66); + } #ifdef DEBUG printk("HPT366: reg5ah=0x%02x ATA-%s Cable Port%d\n", diff -Nru a/drivers/ide/pci/it8172.c b/drivers/ide/pci/it8172.c --- a/drivers/ide/pci/it8172.c Tue Sep 2 19:58:18 2003 +++ b/drivers/ide/pci/it8172.c Tue Sep 2 19:58:18 2003 @@ -42,7 +42,6 @@ #include #include -#include "ide_modes.h" #include "it8172.h" /* diff -Nru a/drivers/ide/pci/ns87415.c b/drivers/ide/pci/ns87415.c --- a/drivers/ide/pci/ns87415.c Tue Sep 2 19:58:15 2003 +++ b/drivers/ide/pci/ns87415.c Tue Sep 2 19:58:15 2003 @@ -147,9 +147,7 @@ /* Set a good latency timer and cache line size value. */ (void) pci_write_config_byte(dev, PCI_LATENCY_TIMER, 64); -#ifdef __sparc_v9__ - (void) pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, 0x10); -#endif + /* FIXME: use pci_set_master() to ensure good latency timer value */ /* * We cannot probe for IRQ: both ports share common IRQ on INTA. diff -Nru a/drivers/ide/pci/opti621.c b/drivers/ide/pci/opti621.c --- a/drivers/ide/pci/opti621.c Tue Sep 2 19:58:15 2003 +++ b/drivers/ide/pci/opti621.c Tue Sep 2 19:58:15 2003 @@ -104,7 +104,6 @@ #include -#include "ide_modes.h" #include "opti621.h" #define OPTI621_MAX_PIO 3 diff -Nru a/drivers/ide/pci/pdc202xx_new.c b/drivers/ide/pci/pdc202xx_new.c --- a/drivers/ide/pci/pdc202xx_new.c Tue Sep 2 19:58:17 2003 +++ b/drivers/ide/pci/pdc202xx_new.c Tue Sep 2 19:58:17 2003 @@ -32,7 +32,6 @@ #include #include -#include "ide_modes.h" #include "pdc202xx_new.h" #define PDC202_DEBUG_CABLE 0 diff -Nru a/drivers/ide/pci/pdc202xx_old.c b/drivers/ide/pci/pdc202xx_old.c --- a/drivers/ide/pci/pdc202xx_old.c Tue Sep 2 19:58:19 2003 +++ b/drivers/ide/pci/pdc202xx_old.c Tue Sep 2 19:58:19 2003 @@ -46,7 +46,6 @@ #include #include -#include "ide_modes.h" #include "pdc202xx_old.h" #define PDC202_DEBUG_CABLE 0 diff -Nru a/drivers/ide/pci/pdcadma.c b/drivers/ide/pci/pdcadma.c --- a/drivers/ide/pci/pdcadma.c Tue Sep 2 19:58:18 2003 +++ b/drivers/ide/pci/pdcadma.c Tue Sep 2 19:58:18 2003 @@ -24,7 +24,6 @@ #include #include -#include "ide_modes.h" #include "pdcadma.h" #if defined(DISPLAY_PDCADMA_TIMINGS) && defined(CONFIG_PROC_FS) diff -Nru a/drivers/ide/pci/piix.c b/drivers/ide/pci/piix.c --- a/drivers/ide/pci/piix.c Tue Sep 2 19:58:13 2003 +++ b/drivers/ide/pci/piix.c Tue Sep 2 19:58:13 2003 @@ -103,7 +103,6 @@ #include -#include "ide_modes.h" #include "piix.h" static int no_piix_dma; diff -Nru a/drivers/ide/pci/sc1200.c b/drivers/ide/pci/sc1200.c --- a/drivers/ide/pci/sc1200.c Tue Sep 2 19:58:16 2003 +++ b/drivers/ide/pci/sc1200.c Tue Sep 2 19:58:16 2003 @@ -29,7 +29,6 @@ #include #include -#include "ide_modes.h" #include "sc1200.h" #define SC1200_REV_A 0x00 diff -Nru a/drivers/ide/pci/serverworks.c b/drivers/ide/pci/serverworks.c --- a/drivers/ide/pci/serverworks.c Tue Sep 2 19:58:13 2003 +++ b/drivers/ide/pci/serverworks.c Tue Sep 2 19:58:13 2003 @@ -39,7 +39,6 @@ #include -#include "ide_modes.h" #include "serverworks.h" static u8 svwks_revision = 0; diff -Nru a/drivers/ide/pci/siimage.c b/drivers/ide/pci/siimage.c --- a/drivers/ide/pci/siimage.c Tue Sep 2 19:58:15 2003 +++ b/drivers/ide/pci/siimage.c Tue Sep 2 19:58:15 2003 @@ -1,7 +1,24 @@ /* - * linux/drivers/ide/pci/siimage.c Version 1.02 Jan 30, 2003 + * linux/drivers/ide/pci/siimage.c Version 1.06 June 11, 2003 * * Copyright (C) 2001-2002 Andre Hedrick + * Copyright (C) 2003 Red Hat + * + * May be copied or modified under the terms of the GNU General Public License + * + * Documentation available under NDA only + * + * + * FAQ Items: + * If you are using Marvell SATA-IDE adapters with Maxtor drives + * ensure the system is set up for ATA100/UDMA5 not UDMA6. + * + * If you are using WD drives with SATA bridges you must set the + * drive to "Single". "Master" will hang + * + * If you have strange problems with nVidia chipset systems please + * see the SI support documentation and update your system BIOS + * if neccessary */ #include @@ -15,7 +32,6 @@ #include -#include "ide_modes.h" #include "siimage.h" #if defined(DISPLAY_SIIMAGE_TIMINGS) && defined(CONFIG_PROC_FS) @@ -23,16 +39,107 @@ #include static u8 siimage_proc = 0; -#define SIIMAGE_MAX_DEVS 5 +#define SIIMAGE_MAX_DEVS 16 static struct pci_dev *siimage_devs[SIIMAGE_MAX_DEVS]; static int n_siimage_devs; -static char * print_siimage_get_info (char *buf, struct pci_dev *dev, int index) +/** + * pdev_is_sata - check if device is SATA + * @pdev: PCI device to check + * + * Returns true if this is a SATA controller + */ + +static int pdev_is_sata(struct pci_dev *pdev) +{ + switch(pdev->device) + { + case PCI_DEVICE_ID_SII_3112: + case PCI_DEVICE_ID_SII_1210SA: + return 1; + case PCI_DEVICE_ID_SII_680: + return 0; + } + BUG(); + return 0; +} + +/** + * is_sata - check if hwif is SATA + * @hwif: interface to check + * + * Returns true if this is a SATA controller + */ + +static inline int is_sata(ide_hwif_t *hwif) +{ + return pdev_is_sata(hwif->pci_dev); +} + +/** + * siimage_selreg - return register base + * @hwif: interface + * @r: config offset + * + * Turn a config register offset into the right address in either + * PCI space or MMIO space to access the control register in question + * Thankfully this is a configuration operation so isnt performance + * criticial. + */ + +static unsigned long siimage_selreg(ide_hwif_t *hwif, int r) +{ + unsigned long base = (unsigned long)hwif->hwif_data; + base += 0xA0 + r; + if(hwif->mmio) + base += (hwif->channel << 6); + else + base += (hwif->channel << 4); + return base; +} + +/** + * siimage_seldev - return register base + * @hwif: interface + * @r: config offset + * + * Turn a config register offset into the right address in either + * PCI space or MMIO space to access the control register in question + * including accounting for the unit shift. + */ + +static inline unsigned long siimage_seldev(ide_drive_t *drive, int r) +{ + ide_hwif_t *hwif = HWIF(drive); + unsigned long base = (unsigned long)hwif->hwif_data; + base += 0xA0 + r; + if(hwif->mmio) + base += (hwif->channel << 6); + else + base += (hwif->channel << 4); + base |= drive->select.b.unit << drive->select.b.unit; + return base; +} + +/** + * print_siimage_get_info - print minimal proc information + * @buf: buffer to write into (kernel space) + * @dev: PCI device we are describing + * @index: Controller number + * + * Print the basic information for the state of the CMD680/SI3112 + * channel. We don't actually dump a lot of information out for + * this controller although we could expand it if we needed. + */ + +static char *print_siimage_get_info (char *buf, struct pci_dev *dev, int index) { char *p = buf; u8 mmio = (pci_get_drvdata(dev) != NULL) ? 1 : 0; - unsigned long bmdma = (mmio) ? ((unsigned long) pci_get_drvdata(dev)) : - (pci_resource_start(dev, 4)); + unsigned long bmdma = pci_resource_start(dev, 4); + + if(mmio) + bmdma = pci_resource_start(dev, 5); p += sprintf(p, "\nController: %d\n", index); p += sprintf(p, "SiI%x Chipset.\n", dev->device); @@ -40,18 +147,20 @@ p += sprintf(p, "MMIO Base 0x%lx\n", bmdma); p += sprintf(p, "%s-DMA Base 0x%lx\n", (mmio)?"MMIO":"BM", bmdma); p += sprintf(p, "%s-DMA Base 0x%lx\n", (mmio)?"MMIO":"BM", bmdma+8); - - p += sprintf(p, "--------------- Primary Channel " - "---------------- Secondary Channel " - "-------------\n"); - p += sprintf(p, "--------------- drive0 --------- drive1 " - "-------- drive0 ---------- drive1 ------\n"); - p += sprintf(p, "PIO Mode: %s %s" - " %s %s\n", - "?", "?", "?", "?"); return (char *)p; } +/** + * siimage_get_info - proc callback + * @buffer: kernel buffer to complete + * @addr: written with base of data to return + * offset: seek offset + * count: bytes to fill in + * + * Called when the user reads data from the virtual file for this + * controller from /proc + */ + static int siimage_get_info (char *buffer, char **addr, off_t offset, int count) { char *p = buffer; @@ -72,46 +181,70 @@ #endif /* defined(DISPLAY_SIIMAGE_TIMINGS) && defined(CONFIG_PROC_FS) */ +/** + * siimage_ratemask - Compute available modes + * @drive: IDE drive + * + * Compute the available speeds for the devices on the interface. + * For the CMD680 this depends on the clocking mode (scsc), for the + * SI3312 SATA controller life is a bit simpler. Enforce UDMA33 + * as a limit if there is no 80pin cable present. + */ + static byte siimage_ratemask (ide_drive_t *drive) { ide_hwif_t *hwif = HWIF(drive); u8 mode = 0, scsc = 0; + unsigned long base = (unsigned long) hwif->hwif_data; if (hwif->mmio) - scsc = hwif->INB(HWIFADDR(0x4A)); + scsc = hwif->INB(base + 0x4A); else pci_read_config_byte(hwif->pci_dev, 0x8A, &scsc); - switch(hwif->pci_dev->device) { - case PCI_DEVICE_ID_SII_3112: - return 4; - case PCI_DEVICE_ID_SII_680: - if ((scsc & 0x10) == 0x10) /* 133 */ - mode = 4; - else if ((scsc & 0x30) == 0x00) /* 100 */ - mode = 3; - else if ((scsc & 0x20) == 0x20) /* 66 eek */ - BUG(); // mode = 2; - break; - default: return 0; + if(is_sata(hwif)) + { + if(strstr(drive->id->model, "Maxtor")) + return 3; + return 4; } + + if ((scsc & 0x30) == 0x10) /* 133 */ + mode = 4; + else if ((scsc & 0x30) == 0x20) /* 2xPCI */ + mode = 4; + else if ((scsc & 0x30) == 0x00) /* 100 */ + mode = 3; + else /* Disabled ? */ + BUG(); + if (!eighty_ninty_three(drive)) mode = min(mode, (u8)1); return mode; } +/** + * siimage_taskfile_timing - turn timing data to a mode + * @hwif: interface to query + * + * Read the timing data for the interface and return the + * mode that is being used. + */ + static byte siimage_taskfile_timing (ide_hwif_t *hwif) { u16 timing = 0x328a; + unsigned long addr = siimage_selreg(hwif, 2); if (hwif->mmio) - timing = hwif->INW(SELADDR(2)); + timing = hwif->INW(addr); else - pci_read_config_word(hwif->pci_dev, SELREG(2), &timing); + pci_read_config_word(hwif->pci_dev, addr, &timing); switch (timing) { case 0x10c1: return 4; case 0x10c3: return 3; + case 0x1104: case 0x1281: return 2; case 0x2283: return 1; case 0x328a: @@ -119,34 +252,88 @@ } } +/** + * simmage_tuneproc - tune a drive + * @drive: drive to tune + * @mode_wanted: the target operating mode + * + * Load the timing settings for this device mode into the + * controller. If we are in PIO mode 3 or 4 turn on IORDY + * monitoring (bit 9). The TF timing is bits 31:16 + */ + static void siimage_tuneproc (ide_drive_t *drive, byte mode_wanted) { ide_hwif_t *hwif = HWIF(drive); - struct pci_dev *dev = hwif->pci_dev; - u16 speedt = 0; - u8 unit = drive->select.b.unit; - - if (hwif->mmio) - speedt = hwif->INW(SELADDR(0x04|(unit<mmio) - hwif->OUTW(speedt, SELADDR(0x04|(unit<OUTW(speedt, addr); + hwif->OUTW(speedp, tfaddr); + /* Now set up IORDY */ + if(mode_wanted == 3 || mode_wanted == 4) + hwif->OUTW(hwif->INW(tfaddr-2)|0x200, tfaddr-2); + else + hwif->OUTW(hwif->INW(tfaddr-2)&~0x200, tfaddr-2); + } else - pci_write_config_word(dev, SELADDR(0x04|(unit<pci_dev, addr, speedp); + pci_write_config_word(hwif->pci_dev, tfaddr, speedt); + pci_read_config_word(hwif->pci_dev, tfaddr-2, &speedp); + speedp &= ~0x200; + /* Set IORDY for mode 3 or 4 */ + if(mode_wanted == 3 || mode_wanted == 4) + speedp |= 0x200; + pci_write_config_word(hwif->pci_dev, tfaddr-2, speedp); + } } +/** + * config_siimage_chipset_for_pio - set drive timings + * @drive: drive to tune + * @speed we want + * + * Compute the best pio mode we can for a given device. Also honour + * the timings for the driver when dealing with mixed devices. Some + * of this is ugly but its all wrapped up here + * + * The SI680 can also do VDMA - we need to start using that + * + * FIXME: we use the BIOS channel timings to avoid driving the task + * files too fast at the disk. We need to compute the master/slave + * drive PIO mode properly so that we can up the speed on a hotplug + * system. + */ + static void config_siimage_chipset_for_pio (ide_drive_t *drive, byte set_speed) { u8 channel_timings = siimage_taskfile_timing(HWIF(drive)); @@ -167,6 +354,16 @@ config_siimage_chipset_for_pio(drive, set_speed); } +/** + * siimage_tune_chipset - set controller timings + * @drive: Drive to set up + * @xferspeed: speed we want to achieve + * + * Tune the SII chipset for the desired mode. If we can't achieve + * the desired mode then tune for a lower one, but ultimately + * make the thing work. + */ + static int siimage_tune_chipset (ide_drive_t *drive, byte xferspeed) { u8 ultra6[] = { 0x0F, 0x0B, 0x07, 0x05, 0x03, 0x02, 0x01 }; @@ -176,30 +373,32 @@ ide_hwif_t *hwif = HWIF(drive); u16 ultra = 0, multi = 0; u8 mode = 0, unit = drive->select.b.unit; - u8 speed = ide_rate_filter(siimage_ratemask(drive), xferspeed); + u8 speed = ide_rate_filter(siimage_ratemask(drive), xferspeed); + unsigned long base = (unsigned long)hwif->hwif_data; u8 scsc = 0, addr_mask = ((hwif->channel) ? ((hwif->mmio) ? 0xF4 : 0x84) : ((hwif->mmio) ? 0xB4 : 0x80)); + + unsigned long ma = siimage_seldev(drive, 0x08); + unsigned long ua = siimage_seldev(drive, 0x0C); if (hwif->mmio) { - scsc = hwif->INB(HWIFADDR(0x4A)); - mode = hwif->INB(HWIFADDR(addr_mask)); - multi = hwif->INW(SELADDR(0x08|(unit<INW(SELADDR(0x0C|(unit<INB(base + 0x4A); + mode = hwif->INB(base + addr_mask); + multi = hwif->INW(ma); + ultra = hwif->INW(ua); } else { - pci_read_config_byte(hwif->pci_dev, HWIFADDR(0x8A), &scsc); + pci_read_config_byte(hwif->pci_dev, 0x8A, &scsc); pci_read_config_byte(hwif->pci_dev, addr_mask, &mode); - pci_read_config_word(hwif->pci_dev, - SELREG(0x08|(unit<pci_dev, - SELREG(0x0C|(unit<pci_dev, ma, &multi); + pci_read_config_word(hwif->pci_dev, ua, &ultra); } mode &= ~((unit) ? 0x30 : 0x03); ultra &= ~0x3F; scsc = ((scsc & 0x30) == 0x00) ? 0 : 1; - scsc = (hwif->pci_dev->device == PCI_DEVICE_ID_SII_3112) ? 1 : scsc; + scsc = is_sata(hwif) ? 1 : scsc; switch(speed) { case XFER_PIO_4: @@ -225,8 +424,8 @@ case XFER_UDMA_1: case XFER_UDMA_0: multi = dma[2]; - ultra |= ((scsc) ? (ultra5[speed - XFER_UDMA_0]) : - (ultra6[speed - XFER_UDMA_0])); + ultra |= ((scsc) ? (ultra6[speed - XFER_UDMA_0]) : + (ultra5[speed - XFER_UDMA_0])); mode |= ((unit) ? 0x30 : 0x03); config_siimage_chipset_for_pio(drive, 0); break; @@ -235,20 +434,26 @@ } if (hwif->mmio) { - hwif->OUTB(mode, HWIFADDR(addr_mask)); - hwif->OUTW(multi, SELADDR(0x08|(unit<OUTW(ultra, SELADDR(0x0C|(unit<OUTB(mode, base + addr_mask); + hwif->OUTW(multi, ma); + hwif->OUTW(ultra, ua); } else { pci_write_config_byte(hwif->pci_dev, addr_mask, mode); - pci_write_config_word(hwif->pci_dev, - SELREG(0x08|(unit<pci_dev, - SELREG(0x0C|(unit<pci_dev, ma, multi); + pci_write_config_word(hwif->pci_dev, ua, ultra); } - return (ide_config_drive_speed(drive, speed)); } +/** + * config_chipset_for_dma - configure for DMA + * @drive: drive to configure + * + * Called by the IDE layer when it wants the timings set up. + * For the CMD680 we also need to set up the PIO timings and + * enable DMA. + */ + static int config_chipset_for_dma (ide_drive_t *drive) { u8 speed = ide_dma_speed(drive, siimage_ratemask(drive)); @@ -267,14 +472,22 @@ return ide_dma_enable(drive); } +/** + * siimage_configure_drive_for_dma - set up for DMA transfers + * @drive: drive we are going to set up + * + * Set up the drive for DMA, tune the controller and drive as + * required. If the drive isn't suitable for DMA or we hit + * other problems then we will drop down to PIO and set up + * PIO appropriately + */ + static int siimage_config_drive_for_dma (ide_drive_t *drive) { ide_hwif_t *hwif = HWIF(drive); struct hd_driveid *id = drive->id; - if (id != NULL && (id->capability & 1) != 0 && drive->autodma) { - if (!(hwif->atapi_dma)) - goto fast_ata_pio; + if ((id->capability & 1) != 0 && drive->autodma) { /* Consult the list of known "bad" drives */ if (hwif->ide_dma_bad_drive(drive)) goto fast_ata_pio; @@ -316,18 +529,28 @@ { ide_hwif_t *hwif = HWIF(drive); u8 dma_altstat = 0; + unsigned long addr = siimage_selreg(hwif, 1); /* return 1 if INTR asserted */ if ((hwif->INB(hwif->dma_status) & 4) == 4) return 1; /* return 1 if Device INTR asserted */ - pci_read_config_byte(hwif->pci_dev, SELREG(1), &dma_altstat); + pci_read_config_byte(hwif->pci_dev, addr, &dma_altstat); if (dma_altstat & 8) return 0; //return 1; return 0; } +/** + * siimage_mmio_ide_dma_count - DMA bytes done + * @drive + * + * If we are doing VDMA the CMD680 requires a little bit + * of more careful handling and we have to read the counts + * off ourselves. For non VDMA life is normal. + */ + static int siimage_mmio_ide_dma_count (ide_drive_t *drive) { #ifdef SIIMAGE_VIRTUAL_DMAPIO @@ -335,9 +558,10 @@ ide_hwif_t *hwif = HWIF(drive); u32 count = (rq->nr_sectors * SECTOR_SIZE); u32 rcount = 0; + unsigned long addr = siimage_selreg(hwif, 0x1C); - hwif->OUTL(count, SELADDR(0x1C)); - rcount = hwif->INL(SELADDR(0x1C)); + hwif->OUTL(count, addr); + rcount = hwif->INL(addr); printk("\n%s: count = %d, rcount = %d, nr_sectors = %lu\n", drive->name, count, rcount, rq->nr_sectors); @@ -346,13 +570,22 @@ return __ide_dma_count(drive); } -/* returns 1 if dma irq issued, 0 otherwise */ +/** + * siimage_mmio_ide_dma_test_irq - check we caused an IRQ + * @drive: drive we are testing + * + * Check if we caused an IDE DMA interrupt. We may also have caused + * SATA status interrupts, if so we clean them up and continue. + */ + static int siimage_mmio_ide_dma_test_irq (ide_drive_t *drive) { ide_hwif_t *hwif = HWIF(drive); + unsigned long base = (unsigned long)hwif->hwif_data; + unsigned long addr = siimage_selreg(hwif, 0x1); if (SATA_ERROR_REG) { - u32 ext_stat = hwif->INL(HWIFADDR(0x10)); + u32 ext_stat = hwif->INL(base + 0x10); u8 watchdog = 0; if (ext_stat & ((hwif->channel) ? 0x40 : 0x10)) { u32 sata_error = hwif->INL(SATA_ERROR_REG); @@ -379,7 +612,7 @@ return 1; /* return 1 if Device INTR asserted */ - if ((hwif->INB(SELADDR(1)) & 8) == 8) + if ((hwif->INB(addr) & 8) == 8) return 0; //return 1; return 0; @@ -388,21 +621,29 @@ static int siimage_mmio_ide_dma_verbose (ide_drive_t *drive) { int temp = __ide_dma_verbose(drive); -#if 0 - drive->using_dma = 0; -#endif return temp; } +/** + * siimage_busproc - bus isolation ioctl + * @drive: drive to isolate/restore + * @state: bus state to set + * + * Used by the SII3112 to handle bus isolation. As this is a + * SATA controller the work required is quite limited, we + * just have to clean up the statistics + */ + static int siimage_busproc (ide_drive_t * drive, int state) { ide_hwif_t *hwif = HWIF(drive); u32 stat_config = 0; + unsigned long addr = siimage_selreg(hwif, 0); if (hwif->mmio) { - stat_config = hwif->INL(SELADDR(0)); + stat_config = hwif->INL(addr); } else - pci_read_config_dword(hwif->pci_dev, SELREG(0), &stat_config); + pci_read_config_dword(hwif->pci_dev, addr, &stat_config); switch (state) { case BUSSTATE_ON: @@ -418,12 +659,20 @@ hwif->drives[1].failures = hwif->drives[1].max_failures + 1; break; default: - return 0; + return -EINVAL; } hwif->bus_state = state; return 0; } +/** + * siimage_reset_poll - wait for sata reset + * @drive: drive we are resetting + * + * Poll the SATA phy and see whether it has come back from the dead + * yet. + */ + static int siimage_reset_poll (ide_drive_t *drive) { if (SATA_STATUS_REG) { @@ -433,13 +682,7 @@ printk(KERN_WARNING "%s: reset phy dead, status=0x%08x\n", hwif->name, hwif->INL(SATA_STATUS_REG)); HWGROUP(drive)->poll_timeout = 0; -#if 0 - drive->failures++; - return ide_stopped; -#else return ide_started; -#endif - return 1; } return 0; } else { @@ -447,34 +690,53 @@ } } +/** + * siimage_pre_reset - reset hook + * @drive: IDE device being reset + * + * For the SATA devices we need to handle recalibration/geometry + * differently + */ + static void siimage_pre_reset (ide_drive_t *drive) { if (drive->media != ide_disk) return; - if (HWIF(drive)->pci_dev->device == PCI_DEVICE_ID_SII_3112) { + if (is_sata(HWIF(drive))) + { drive->special.b.set_geometry = 0; drive->special.b.recalibrate = 0; } } +/** + * siimage_reset - reset a device on an siimage controller + * @drive: drive to reset + * + * Perform a controller level reset fo the device. For + * SATA we must also check the PHY. + */ + static void siimage_reset (ide_drive_t *drive) { ide_hwif_t *hwif = HWIF(drive); u8 reset = 0; + unsigned long addr = siimage_selreg(hwif, 0); if (hwif->mmio) { - reset = hwif->INB(SELADDR(0)); - hwif->OUTB((reset|0x03), SELADDR(0)); + reset = hwif->INB(addr); + hwif->OUTB((reset|0x03), addr); + /* FIXME:posting */ udelay(25); - hwif->OUTB(reset, SELADDR(0)); - (void) hwif->INB(SELADDR(0)); + hwif->OUTB(reset, addr); + (void) hwif->INB(addr); } else { - pci_read_config_byte(hwif->pci_dev, SELREG(0), &reset); - pci_write_config_byte(hwif->pci_dev, SELREG(0), reset|0x03); + pci_read_config_byte(hwif->pci_dev, addr, &reset); + pci_write_config_byte(hwif->pci_dev, addr, reset|0x03); udelay(25); - pci_write_config_byte(hwif->pci_dev, SELREG(0), reset); - pci_read_config_byte(hwif->pci_dev, SELREG(0), &reset); + pci_write_config_byte(hwif->pci_dev, addr, reset); + pci_read_config_byte(hwif->pci_dev, addr, &reset); } if (SATA_STATUS_REG) { @@ -490,20 +752,28 @@ } +/** + * proc_reports_siimage - add siimage controller to proc + * @dev: PCI device + * @clocking: SCSC value + * @name: controller name + * + * Report the clocking mode of the controller and add it to + * the /proc interface layer + */ + static void proc_reports_siimage (struct pci_dev *dev, u8 clocking, const char *name) { - if (dev->device == PCI_DEVICE_ID_SII_3112) + if(pdev_is_sata(dev)) goto sata_skip; printk(KERN_INFO "%s: BASE CLOCK ", name); - clocking &= ~0x0C; + clocking &= 0x03; switch(clocking) { case 0x03: printk("DISABLED !\n"); break; case 0x02: printk("== 2X PCI \n"); break; case 0x01: printk("== 133 \n"); break; case 0x00: printk("== 100 \n"); break; - default: - BUG(); } sata_skip: @@ -518,75 +788,108 @@ #endif /* DISPLAY_SIIMAGE_TIMINGS && CONFIG_PROC_FS */ } +/** + * setup_mmio_siimage - switch an SI controller into MMIO + * @dev: PCI device we are configuring + * @name: device name + * + * Attempt to put the device into mmio mode. There are some slight + * complications here with certain systems where the mmio bar isnt + * mapped so we have to be sure we can fall back to I/O. + */ + static unsigned int setup_mmio_siimage (struct pci_dev *dev, const char *name) { unsigned long bar5 = pci_resource_start(dev, 5); - unsigned long end5 = pci_resource_end(dev, 5); + unsigned long barsize = pci_resource_len(dev, 5); u8 tmpbyte = 0; unsigned long addr; void *ioaddr; - ioaddr = ioremap_nocache(bar5, (end5 - bar5)); + /* + * Drop back to PIO if we can't map the mmio. Some + * systems seem to get terminally confused in the PCI + * spaces. + */ + + if(!request_mem_region(bar5, barsize, name)) + { + printk(KERN_WARNING "siimage: IDE controller MMIO ports not available.\n"); + return 0; + } + + ioaddr = ioremap(bar5, barsize); if (ioaddr == NULL) + { + release_mem_region(bar5, barsize); return 0; + } pci_set_master(dev); pci_set_drvdata(dev, ioaddr); addr = (unsigned long) ioaddr; - if (dev->device == PCI_DEVICE_ID_SII_3112) { - writel(0, DEVADDR(0x148)); - writel(0, DEVADDR(0x1C8)); + if (pdev_is_sata(dev)) { + writel(0, addr + 0x148); + writel(0, addr + 0x1C8); } - writeb(0, DEVADDR(0xB4)); - writeb(0, DEVADDR(0xF4)); - tmpbyte = readb(DEVADDR(0x4A)); - - switch(tmpbyte) { - case 0x01: - writeb(tmpbyte|0x10, DEVADDR(0x4A)); - tmpbyte = readb(DEVADDR(0x4A)); - case 0x31: - /* if clocking is disabled */ - /* 133 clock attempt to force it on */ - writeb(tmpbyte & ~0x20, DEVADDR(0x4A)); - tmpbyte = readb(DEVADDR(0x4A)); - case 0x11: - case 0x21: + writeb(0, addr + 0xB4); + writeb(0, addr + 0xF4); + tmpbyte = readb(addr + 0x4A); + + switch(tmpbyte & 0x30) { + case 0x00: + /* In 100 MHz clocking, try and switch to 133 */ + writeb(tmpbyte|0x10, addr + 0x4A); break; - default: - tmpbyte &= ~0x30; - tmpbyte |= 0x20; - writeb(tmpbyte, DEVADDR(0x4A)); + case 0x10: + /* On 133Mhz clocking */ + break; + case 0x20: + /* On PCIx2 clocking */ + break; + case 0x30: + /* Clocking is disabled */ + /* 133 clock attempt to force it on */ + writeb(tmpbyte & ~0x20, addr + 0x4A); break; } - writeb(0x72, DEVADDR(0xA1)); - writew(0x328A, DEVADDR(0xA2)); - writel(0x62DD62DD, DEVADDR(0xA4)); - writel(0x43924392, DEVADDR(0xA8)); - writel(0x40094009, DEVADDR(0xAC)); - writeb(0x72, DEVADDR(0xE1)); - writew(0x328A, DEVADDR(0xE2)); - writel(0x62DD62DD, DEVADDR(0xE4)); - writel(0x43924392, DEVADDR(0xE8)); - writel(0x40094009, DEVADDR(0xEC)); - - if (dev->device == PCI_DEVICE_ID_SII_3112) { - writel(0xFFFF0000, DEVADDR(0x108)); - writel(0xFFFF0000, DEVADDR(0x188)); - writel(0x00680000, DEVADDR(0x148)); - writel(0x00680000, DEVADDR(0x1C8)); + writeb( 0x72, addr + 0xA1); + writew( 0x328A, addr + 0xA2); + writel(0x62DD62DD, addr + 0xA4); + writel(0x43924392, addr + 0xA8); + writel(0x40094009, addr + 0xAC); + writeb( 0x72, addr + 0xE1); + writew( 0x328A, addr + 0xE2); + writel(0x62DD62DD, addr + 0xE4); + writel(0x43924392, addr + 0xE8); + writel(0x40094009, addr + 0xEC); + + if (pdev_is_sata(dev)) { + writel(0xFFFF0000, addr + 0x108); + writel(0xFFFF0000, addr + 0x188); + writel(0x00680000, addr + 0x148); + writel(0x00680000, addr + 0x1C8); } - tmpbyte = readb(DEVADDR(0x4A)); + tmpbyte = readb(addr + 0x4A); - proc_reports_siimage(dev, (tmpbyte>>=4), name); + proc_reports_siimage(dev, (tmpbyte>>4), name); return 1; } +/** + * init_chipset_siimage - set up an SI device + * @dev: PCI device + * @name: device name + * + * Perform the initial PCI set up for this device. Attempt to switch + * to 133MHz clocking if the system isn't already set up to do it. + */ + static unsigned int __init init_chipset_siimage (struct pci_dev *dev, const char *name) { u32 class_rev = 0; @@ -607,139 +910,150 @@ pci_write_config_byte(dev, 0x80, 0x00); pci_write_config_byte(dev, 0x84, 0x00); pci_read_config_byte(dev, 0x8A, &tmpbyte); - switch(tmpbyte) { + switch(tmpbyte & 0x30) { case 0x00: - case 0x01: /* 133 clock attempt to force it on */ pci_write_config_byte(dev, 0x8A, tmpbyte|0x10); - pci_read_config_byte(dev, 0x8A, &tmpbyte); case 0x30: - case 0x31: /* if clocking is disabled */ /* 133 clock attempt to force it on */ pci_write_config_byte(dev, 0x8A, tmpbyte & ~0x20); - pci_read_config_byte(dev, 0x8A, &tmpbyte); case 0x10: - case 0x11: - case 0x20: - case 0x21: + /* 133 already */ break; - default: - tmpbyte &= ~0x30; - tmpbyte |= 0x20; - pci_write_config_byte(dev, 0x8A, tmpbyte); + case 0x20: + /* BIOS set PCI x2 clocking */ break; } - pci_read_config_byte(dev, 0x8A, &tmpbyte); - pci_write_config_byte(dev, 0xA1, 0x72); - pci_write_config_word(dev, 0xA2, 0x328A); + pci_read_config_byte(dev, 0x8A, &tmpbyte); + + pci_write_config_byte(dev, 0xA1, 0x72); + pci_write_config_word(dev, 0xA2, 0x328A); pci_write_config_dword(dev, 0xA4, 0x62DD62DD); pci_write_config_dword(dev, 0xA8, 0x43924392); pci_write_config_dword(dev, 0xAC, 0x40094009); - pci_write_config_byte(dev, 0xB1, 0x72); - pci_write_config_word(dev, 0xB2, 0x328A); + pci_write_config_byte(dev, 0xB1, 0x72); + pci_write_config_word(dev, 0xB2, 0x328A); pci_write_config_dword(dev, 0xB4, 0x62DD62DD); pci_write_config_dword(dev, 0xB8, 0x43924392); pci_write_config_dword(dev, 0xBC, 0x40094009); - pci_read_config_byte(dev, 0x8A, &tmpbyte); - proc_reports_siimage(dev, (tmpbyte>>=4), name); + proc_reports_siimage(dev, (tmpbyte>>4), name); return 0; } +/** + * init_mmio_iops_siimage - set up the iops for MMIO + * @hwif: interface to set up + * + * The basic setup here is fairly simple, we can use standard MMIO + * operations. However we do have to set the taskfile register offsets + * by hand as there isnt a standard defined layout for them this + * time. + * + * The hardware supports buffered taskfiles and also some rather nice + * extended PRD tables. Unfortunately right now we don't. + */ + static void __init init_mmio_iops_siimage (ide_hwif_t *hwif) { struct pci_dev *dev = hwif->pci_dev; - unsigned long addr = (unsigned long) pci_get_drvdata(hwif->pci_dev); + void *addr = pci_get_drvdata(dev); u8 ch = hwif->channel; -// u16 i = 0; - hw_regs_t hw; + hw_regs_t hw; + unsigned long base; + + /* + * Fill in the basic HWIF bits + */ default_hwif_mmiops(hwif); + hwif->hwif_data = addr; + + /* + * Now set up the hw. We have to do this ourselves as + * the MMIO layout isnt the same as the the standard port + * based I/O + */ + memset(&hw, 0, sizeof(hw_regs_t)); + hw.priv = addr; -#if 1 -#ifdef SIIMAGE_BUFFERED_TASKFILE - hw.io_ports[IDE_DATA_OFFSET] = DEVADDR((ch) ? 0xD0 : 0x90); - hw.io_ports[IDE_ERROR_OFFSET] = DEVADDR((ch) ? 0xD1 : 0x91); - hw.io_ports[IDE_NSECTOR_OFFSET] = DEVADDR((ch) ? 0xD2 : 0x92); - hw.io_ports[IDE_SECTOR_OFFSET] = DEVADDR((ch) ? 0xD3 : 0x93); - hw.io_ports[IDE_LCYL_OFFSET] = DEVADDR((ch) ? 0xD4 : 0x94); - hw.io_ports[IDE_HCYL_OFFSET] = DEVADDR((ch) ? 0xD5 : 0x95); - hw.io_ports[IDE_SELECT_OFFSET] = DEVADDR((ch) ? 0xD6 : 0x96); - hw.io_ports[IDE_STATUS_OFFSET] = DEVADDR((ch) ? 0xD7 : 0x97); - hw.io_ports[IDE_CONTROL_OFFSET] = DEVADDR((ch) ? 0xDA : 0x9A); -#else /* ! SIIMAGE_BUFFERED_TASKFILE */ - hw.io_ports[IDE_DATA_OFFSET] = DEVADDR((ch) ? 0xC0 : 0x80); - hw.io_ports[IDE_ERROR_OFFSET] = DEVADDR((ch) ? 0xC1 : 0x81); - hw.io_ports[IDE_NSECTOR_OFFSET] = DEVADDR((ch) ? 0xC2 : 0x82); - hw.io_ports[IDE_SECTOR_OFFSET] = DEVADDR((ch) ? 0xC3 : 0x83); - hw.io_ports[IDE_LCYL_OFFSET] = DEVADDR((ch) ? 0xC4 : 0x84); - hw.io_ports[IDE_HCYL_OFFSET] = DEVADDR((ch) ? 0xC5 : 0x85); - hw.io_ports[IDE_SELECT_OFFSET] = DEVADDR((ch) ? 0xC6 : 0x86); - hw.io_ports[IDE_STATUS_OFFSET] = DEVADDR((ch) ? 0xC7 : 0x87); - hw.io_ports[IDE_CONTROL_OFFSET] = DEVADDR((ch) ? 0xCA : 0x8A); -#endif /* SIIMAGE_BUFFERED_TASKFILE */ -#else -#ifdef SIIMAGE_BUFFERED_TASKFILE - for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; i++) - hw.io_ports[i] = DEVADDR((ch) ? 0xD0 : 0x90)|(i); - hw.io_ports[IDE_CONTROL_OFFSET] = DEVADDR((ch) ? 0xDA : 0x9A); -#else /* ! SIIMAGE_BUFFERED_TASKFILE */ - for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; i++) - hw.io_ports[i] = DEVADDR((ch) ? 0xC0 : 0x80)|(i); - hw.io_ports[IDE_CONTROL_OFFSET] = DEVADDR((ch) ? 0xCA : 0x8A); -#endif /* SIIMAGE_BUFFERED_TASKFILE */ -#endif + base = (unsigned long)addr; + if(ch) + base += 0xC0; + else + base += 0x80; -#if 0 - printk(KERN_DEBUG "%s: ", hwif->name); - for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; i++) - printk("0x%08x ", DEVADDR((ch) ? 0xC0 : 0x80)|(i)); - printk("0x%08x ", DEVADDR((ch) ? 0xCA : 0x8A)|(i)); -#endif + /* + * The buffered task file doesn't have status/control + * so we can't currently use it sanely since we want to + * use LBA48 mode. + */ +// base += 0x10; +// hwif->no_lba48 = 1; + + hw.io_ports[IDE_DATA_OFFSET] = base; + hw.io_ports[IDE_ERROR_OFFSET] = base + 1; + hw.io_ports[IDE_NSECTOR_OFFSET] = base + 2; + hw.io_ports[IDE_SECTOR_OFFSET] = base + 3; + hw.io_ports[IDE_LCYL_OFFSET] = base + 4; + hw.io_ports[IDE_HCYL_OFFSET] = base + 5; + hw.io_ports[IDE_SELECT_OFFSET] = base + 6; + hw.io_ports[IDE_STATUS_OFFSET] = base + 7; + hw.io_ports[IDE_CONTROL_OFFSET] = base + 10; hw.io_ports[IDE_IRQ_OFFSET] = 0; - if (dev->device == PCI_DEVICE_ID_SII_3112) { - hw.sata_scr[SATA_STATUS_OFFSET] = DEVADDR((ch) ? 0x184 : 0x104); - hw.sata_scr[SATA_ERROR_OFFSET] = DEVADDR((ch) ? 0x188 : 0x108); - hw.sata_scr[SATA_CONTROL_OFFSET]= DEVADDR((ch) ? 0x180 : 0x100); - hw.sata_misc[SATA_MISC_OFFSET] = DEVADDR((ch) ? 0x1C0 : 0x140); - hw.sata_misc[SATA_PHY_OFFSET] = DEVADDR((ch) ? 0x1C4 : 0x144); - hw.sata_misc[SATA_IEN_OFFSET] = DEVADDR((ch) ? 0x1C8 : 0x148); + if (pdev_is_sata(dev)) { + base = (unsigned long) addr; + if(ch) + base += 0x80; + hw.sata_scr[SATA_STATUS_OFFSET] = base + 0x104; + hw.sata_scr[SATA_ERROR_OFFSET] = base + 0x108; + hw.sata_scr[SATA_CONTROL_OFFSET]= base + 0x100; + hw.sata_misc[SATA_MISC_OFFSET] = base + 0x140; + hw.sata_misc[SATA_PHY_OFFSET] = base + 0x144; + hw.sata_misc[SATA_IEN_OFFSET] = base + 0x148; } - hw.priv = (void *) addr; -// hw.priv = pci_get_drvdata(hwif->pci_dev); hw.irq = hwif->pci_dev->irq; memcpy(&hwif->hw, &hw, sizeof(hw)); memcpy(hwif->io_ports, hwif->hw.io_ports, sizeof(hwif->hw.io_ports)); - if (hwif->pci_dev->device == PCI_DEVICE_ID_SII_3112) { + if (is_sata(hwif)) { memcpy(hwif->sata_scr, hwif->hw.sata_scr, sizeof(hwif->hw.sata_scr)); memcpy(hwif->sata_misc, hwif->hw.sata_misc, sizeof(hwif->hw.sata_misc)); } -#ifdef SIIMAGE_BUFFERED_TASKFILE - hwif->no_lba48 = 1; -#endif /* SIIMAGE_BUFFERED_TASKFILE */ hwif->irq = hw.irq; - hwif->hwif_data = pci_get_drvdata(hwif->pci_dev); + + base = (unsigned long) addr; #ifdef SIIMAGE_LARGE_DMA - hwif->dma_base = DEVADDR((ch) ? 0x18 : 0x10); - hwif->dma_base2 = DEVADDR((ch) ? 0x08 : 0x00); - hwif->dma_prdtable = (hwif->dma_base2 + 4); +/* Watch the brackets - even Ken and Dennis get some language design wrong */ + hwif->dma_base = base + (ch ? 0x18 : 0x10); + hwif->dma_base2 = base + (ch ? 0x08 : 0x00); + hwif->dma_prdtable = hwif->dma_base2 + 4; #else /* ! SIIMAGE_LARGE_DMA */ - hwif->dma_base = DEVADDR((ch) ? 0x08 : 0x00); - hwif->dma_base2 = DEVADDR((ch) ? 0x18 : 0x10); + hwif->dma_base = base + (ch ? 0x08 : 0x00); + hwif->dma_base2 = base + (ch ? 0x18 : 0x10); #endif /* SIIMAGE_LARGE_DMA */ - hwif->mmio = 1; + hwif->mmio = 2; } +/** + * init_iops_siimage - set up iops + * @hwif: interface to set up + * + * Do the basic setup for the SIIMAGE hardware interface + * and then do the MMIO setup if we can. This is the first + * look in we get for setting up the hwif so that we + * can get the iops right before using them. + */ + static void __init init_iops_siimage (ide_hwif_t *hwif) { struct pci_dev *dev = hwif->pci_dev; @@ -747,37 +1061,60 @@ pci_read_config_dword(dev, PCI_CLASS_REVISION, &class_rev); class_rev &= 0xff; + + hwif->hwif_data = 0; hwif->rqsize = 128; - if ((dev->device == PCI_DEVICE_ID_SII_3112) && (!(class_rev))) - hwif->rqsize = 16; + if (is_sata(hwif)) + hwif->rqsize = 15; if (pci_get_drvdata(dev) == NULL) return; init_mmio_iops_siimage(hwif); } +/** + * ata66_siimage - check for 80 pin cable + * @hwif: interface to check + * + * Check for the presence of an ATA66 capable cable on the + * interface. + */ + static unsigned int __init ata66_siimage (ide_hwif_t *hwif) { + unsigned long addr = siimage_selreg(hwif, 0); if (pci_get_drvdata(hwif->pci_dev) == NULL) { u8 ata66 = 0; - pci_read_config_byte(hwif->pci_dev, SELREG(0), &ata66); + pci_read_config_byte(hwif->pci_dev, addr, &ata66); return (ata66 & 0x01) ? 1 : 0; } - return (hwif->INB(SELADDR(0)) & 0x01) ? 1 : 0; + return (hwif->INB(addr) & 0x01) ? 1 : 0; } +/** + * init_hwif_siimage - set up hwif structs + * @hwif: interface to set up + * + * We do the basic set up of the interface structure. The SIIMAGE + * requires several custom handlers so we override the default + * ide DMA handlers appropriately + */ + static void __init init_hwif_siimage (ide_hwif_t *hwif) { hwif->autodma = 0; - hwif->busproc = &siimage_busproc; + hwif->resetproc = &siimage_reset; hwif->speedproc = &siimage_tune_chipset; hwif->tuneproc = &siimage_tuneproc; hwif->reset_poll = &siimage_reset_poll; hwif->pre_reset = &siimage_pre_reset; + if(is_sata(hwif)) + hwif->busproc = &siimage_busproc; + if (!hwif->dma_base) { hwif->drives[0].autotune = 1; hwif->drives[1].autotune = 1; @@ -788,7 +1125,7 @@ hwif->mwdma_mask = 0x07; hwif->swdma_mask = 0x07; - if (hwif->pci_dev->device != PCI_DEVICE_ID_SII_3112) + if (!is_sata(hwif)) hwif->atapi_dma = 1; hwif->ide_dma_check = &siimage_config_drive_for_dma; @@ -802,12 +1139,26 @@ } else { hwif->ide_dma_test_irq = & siimage_io_ide_dma_test_irq; } - if (!noautodma) - hwif->autodma = 1; + + /* + * The BIOS often doesn't set up DMA on this controller + * so we always do it. + */ + + hwif->autodma = 1; hwif->drives[0].autodma = hwif->autodma; hwif->drives[1].autodma = hwif->autodma; } +/** + * init_dma_siimage - set up IDE DMA + * @hwif: interface + * @dmabase: DMA base address to use + * + * For the SI chips this requires no special set up so we can just + * let the IDE DMA core do the usual work. + */ + static void __init init_dma_siimage (ide_hwif_t *hwif, unsigned long dmabase) { ide_setup_dma(hwif, dmabase, 8); @@ -816,6 +1167,15 @@ extern void ide_setup_pci_device(struct pci_dev *, ide_pci_device_t *); +/** + * siimage_init_one - pci layer discovery entry + * @dev: PCI device + * @id: ident table entry + * + * Called by the PCI code when it finds an SI680 or SI3112 controller. + * We then use the IDE PCI generic helper to do most of the work. + */ + static int __devinit siimage_init_one(struct pci_dev *dev, const struct pci_device_id *id) { ide_pci_device_t *d = &siimage_chipsets[id->driver_data]; @@ -829,6 +1189,7 @@ static struct pci_device_id siimage_pci_tbl[] = { { PCI_VENDOR_ID_CMD, PCI_DEVICE_ID_SII_680, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, { PCI_VENDOR_ID_CMD, PCI_DEVICE_ID_SII_3112, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 1}, + { PCI_VENDOR_ID_CMD, PCI_DEVICE_ID_SII_1210SA, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 2}, { 0, }, }; @@ -851,6 +1212,6 @@ module_init(siimage_ide_init); module_exit(siimage_ide_exit); -MODULE_AUTHOR("Andre Hedrick"); +MODULE_AUTHOR("Andre Hedrick, Alan Cox"); MODULE_DESCRIPTION("PCI driver module for SiI IDE"); MODULE_LICENSE("GPL"); diff -Nru a/drivers/ide/pci/siimage.h b/drivers/ide/pci/siimage.h --- a/drivers/ide/pci/siimage.h Tue Sep 2 19:58:16 2003 +++ b/drivers/ide/pci/siimage.h Tue Sep 2 19:58:16 2003 @@ -13,12 +13,6 @@ #undef SIIMAGE_BUFFERED_TASKFILE #undef SIIMAGE_LARGE_DMA -#if 0 -typedef struct ide_io_ops_s siimage_iops { - -} -#endif - #define SII_DEBUG 0 #if SII_DEBUG @@ -27,12 +21,6 @@ #define siiprintk(x...) #endif -#define ADJREG(B,R) ((B)|(R)|((hwif->channel)<<(4+(2*(hwif->mmio))))) -#define SELREG(R) ADJREG((0xA0),(R)) -#define SELADDR(R) ((((unsigned long)hwif->hwif_data)*(hwif->mmio))|SELREG((R))) -#define HWIFADDR(R) ((((unsigned long)hwif->hwif_data)*(hwif->mmio))|(R)) -#define DEVADDR(R) (((unsigned long) pci_get_drvdata(dev))|(R)) - #if defined(DISPLAY_SIIMAGE_TIMINGS) && defined(CONFIG_PROC_FS) #include @@ -76,6 +64,19 @@ .vendor = PCI_VENDOR_ID_CMD, .device = PCI_DEVICE_ID_SII_3112, .name = "SiI3112 Serial ATA", + .init_chipset = init_chipset_siimage, + .init_iops = init_iops_siimage, + .init_hwif = init_hwif_siimage, + .init_dma = init_dma_siimage, + .channels = 2, + .autodma = AUTODMA, + .enablebits = {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, + .bootable = ON_BOARD, + .extra = 0, + },{ /* 2 */ + .vendor = PCI_VENDOR_ID_CMD, + .device = PCI_DEVICE_ID_SII_1210SA, + .name = "Adaptec AAR-1210SA", .init_chipset = init_chipset_siimage, .init_iops = init_iops_siimage, .init_hwif = init_hwif_siimage, diff -Nru a/drivers/ide/pci/sis5513.c b/drivers/ide/pci/sis5513.c --- a/drivers/ide/pci/sis5513.c Tue Sep 2 19:58:16 2003 +++ b/drivers/ide/pci/sis5513.c Tue Sep 2 19:58:16 2003 @@ -63,7 +63,6 @@ #include #include "ide-timing.h" -#include "ide_modes.h" #include "sis5513.h" /* registers layout and init values are chipset family dependant */ diff -Nru a/drivers/ide/pci/sl82c105.c b/drivers/ide/pci/sl82c105.c --- a/drivers/ide/pci/sl82c105.c Tue Sep 2 19:58:14 2003 +++ b/drivers/ide/pci/sl82c105.c Tue Sep 2 19:58:14 2003 @@ -29,7 +29,6 @@ #include #include -#include "ide_modes.h" #include "sl82c105.h" #undef DEBUG diff -Nru a/drivers/ide/pci/slc90e66.c b/drivers/ide/pci/slc90e66.c --- a/drivers/ide/pci/slc90e66.c Tue Sep 2 19:58:18 2003 +++ b/drivers/ide/pci/slc90e66.c Tue Sep 2 19:58:18 2003 @@ -21,7 +21,6 @@ #include -#include "ide_modes.h" #include "slc90e66.h" #if defined(DISPLAY_SLC90E66_TIMINGS) && defined(CONFIG_PROC_FS) diff -Nru a/drivers/ide/pci/triflex.c b/drivers/ide/pci/triflex.c --- a/drivers/ide/pci/triflex.c Tue Sep 2 19:58:15 2003 +++ b/drivers/ide/pci/triflex.c Tue Sep 2 19:58:15 2003 @@ -41,7 +41,6 @@ #include #include -#include "ide_modes.h" #include "triflex.h" static struct pci_dev *triflex_dev; diff -Nru a/drivers/ide/ppc/mpc8xx.c b/drivers/ide/ppc/mpc8xx.c --- a/drivers/ide/ppc/mpc8xx.c Tue Sep 2 19:58:19 2003 +++ b/drivers/ide/ppc/mpc8xx.c Tue Sep 2 19:58:19 2003 @@ -42,7 +42,6 @@ #include #include -#include "ide_modes.h" static int identify (volatile u8 *p); static void print_fixed (volatile u8 *p); static void print_funcid (int func); diff -Nru a/drivers/ide/ppc/pmac.c b/drivers/ide/ppc/pmac.c --- a/drivers/ide/ppc/pmac.c Tue Sep 2 19:58:13 2003 +++ b/drivers/ide/ppc/pmac.c Tue Sep 2 19:58:13 2003 @@ -5,7 +5,7 @@ * These IDE interfaces are memory-mapped and have a DBDMA channel * for doing DMA. * - * Copyright (C) 1998-2001 Paul Mackerras & Ben. Herrenschmidt + * Copyright (C) 1998-2003 Paul Mackerras & Ben. Herrenschmidt * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -16,6 +16,11 @@ * * Copyright (c) 1995-1998 Mark Lord * + * TODO: - Use pre-calculated (kauai) timing tables all the time and + * get rid of the "rounded" tables used previously, so we have the + * same table format for all controllers and can then just have one + * big table + * */ #include #include @@ -27,6 +32,8 @@ #include #include #include +#include +#include #include #include @@ -38,26 +45,27 @@ #include #include #include -#ifdef CONFIG_PMAC_PBOOK -#include -#include -#endif -#include "ide_modes.h" + +#include "ide-timing.h" extern void ide_do_request(ide_hwgroup_t *hwgroup, int masked_irq); #define IDE_PMAC_DEBUG -#define DMA_WAIT_TIMEOUT 500 +#define DMA_WAIT_TIMEOUT 100 typedef struct pmac_ide_hwif { unsigned long regbase; int irq; int kind; int aapl_bus_id; + int cable_80 : 1; + int mediabay : 1; + int broken_dma : 1; + int broken_dma_warn : 1; struct device_node* node; - u32 timings[2]; - int index; + struct macio_dev *mdev; + u32 timings[4]; #ifdef CONFIG_BLK_DEV_IDEDMA_PMAC /* Those fields are duplicating what is in hwif. We currently * can't use the hwif ones because of some assumptions that are @@ -82,7 +90,15 @@ controller_heathrow, /* Heathrow/Paddington */ controller_kl_ata3, /* KeyLargo ATA-3 */ controller_kl_ata4, /* KeyLargo ATA-4 */ - controller_kl_ata4_80 /* KeyLargo ATA-4 with 80 conductor cable */ + controller_un_ata6 /* UniNorth2 ATA-6 */ +}; + +static const char* model_name[] = { + "OHare ATA", /* OHare based */ + "Heathrow ATA", /* Heathrow/Paddington */ + "KeyLargo ATA-3", /* KeyLargo ATA-3 */ + "KeyLargo ATA-4", /* KeyLargo ATA-4 */ + "UniNorth ATA-6" /* UniNorth2 ATA-6 */ }; /* @@ -91,6 +107,11 @@ #define IDE_TIMING_CONFIG 0x200 #define IDE_INTERRUPT 0x300 +/* Kauai (U2) ATA has different register setup */ +#define IDE_KAUAI_PIO_CONFIG 0x200 +#define IDE_KAUAI_ULTRA_CONFIG 0x210 +#define IDE_KAUAI_POLL_CONFIG 0x220 + /* * Timing configuration register definitions */ @@ -101,6 +122,28 @@ #define IDE_SYSCLK_NS 30 /* 33Mhz cell */ #define IDE_SYSCLK_66_NS 15 /* 66Mhz cell */ +/* 100Mhz cell, found in Uninorth 2. I don't have much infos about + * this one yet, it appears as a pci device (106b/0033) on uninorth + * internal PCI bus and it's clock is controlled like gem or fw. It + * appears to be an evolution of keylargo ATA4 with a timing register + * extended to 2 32bits registers and a similar DBDMA channel. Other + * registers seem to exist but I can't tell much about them. + * + * So far, I'm using pre-calculated tables for this extracted from + * the values used by the MacOS X driver. + * + * The "PIO" register controls PIO and MDMA timings, the "ULTRA" + * register controls the UDMA timings. At least, it seems bit 0 + * of this one enables UDMA vs. MDMA, and bits 4..7 are the + * cycle time in units of 10ns. Bits 8..15 are used by I don't + * know their meaning yet + */ +#define TR_100_PIOREG_PIO_MASK 0xff000fff +#define TR_100_PIOREG_MDMA_MASK 0x00fff000 +#define TR_100_UDMAREG_UDMA_MASK 0x0000ffff +#define TR_100_UDMAREG_UDMA_EN 0x00000001 + + /* 66Mhz cell, found in KeyLargo. Can do ultra mode 0 to 2 on * 40 connector cable and to 4 on 80 connector one. * Clock unit is 15ns (66Mhz) @@ -115,8 +158,7 @@ * well, despite a comment that would lead to think it has a * min value of 45ns. * Apple also add 60ns to the write data setup (or cycle time ?) on - * reads. I can't explain that, I tried it and it broke everything - * here. + * reads. */ #define TR_66_UDMA_MASK 0xfff00000 #define TR_66_UDMA_EN 0x00100000 /* Enable Ultra mode for DMA */ @@ -220,12 +262,12 @@ { 0, 0, 0 } }; -/* Ultra DMA timings (rounded) */ +/* KeyLargo ATA-4 Ultra DMA timings (rounded) */ struct { int addrSetup; /* ??? */ int rdy2pause; int wrDataSetup; -} udma_timings[] __pmacdata = +} kl66_udma_timings[] __pmacdata = { { 0, 180, 120 }, /* Mode 0 */ { 0, 150, 90 }, /* 1 */ @@ -234,6 +276,63 @@ { 0, 90, 30 } /* 4 */ }; +/* UniNorth 2 ATA/100 timings */ +struct kauai_timing { + int cycle_time; + u32 timing_reg; +}; + +static struct kauai_timing kauai_pio_timings[] __pmacdata = +{ + { 930 , 0x08000fff }, + { 600 , 0x08000a92 }, + { 383 , 0x0800060f }, + { 360 , 0x08000492 }, + { 330 , 0x0800048f }, + { 300 , 0x080003cf }, + { 270 , 0x080003cc }, + { 240 , 0x0800038b }, + { 239 , 0x0800030c }, + { 180 , 0x05000249 }, + { 120 , 0x04000148 } +}; + +static struct kauai_timing kauai_mdma_timings[] __pmacdata = +{ + { 1260 , 0x00fff000 }, + { 480 , 0x00618000 }, + { 360 , 0x00492000 }, + { 270 , 0x0038e000 }, + { 240 , 0x0030c000 }, + { 210 , 0x002cb000 }, + { 180 , 0x00249000 }, + { 150 , 0x00209000 }, + { 120 , 0x00148000 }, + { 0 , 0 }, +}; + +static struct kauai_timing kauai_udma_timings[] __pmacdata = +{ + { 120 , 0x000070c0 }, + { 90 , 0x00005d80 }, + { 60 , 0x00004a60 }, + { 45 , 0x00003a50 }, + { 30 , 0x00002a30 }, + { 20 , 0x00002921 }, + { 0 , 0 }, +}; + +static inline u32 +kauai_lookup_timing(struct kauai_timing* table, int cycle_time) +{ + int i; + + for (i=0; table[i].cycle_time; i++) + if (cycle_time > table[i+1].cycle_time) + return table[i].timing_reg; + return 0; +} + /* allow up to 256 DBDMA commands per xfer */ #define MAX_DCMDS 256 @@ -242,24 +341,106 @@ * NOTE: There is at least one case I know of a disk that needs about 10sec * before anwering on the bus. I beleive we could add a kernel command * line arg to override this delay for such cases. + * + * NOTE2: This has to be fixed with a BSY wait loop. I'm working on adding + * that to the generic probe code. */ #define IDE_WAKEUP_DELAY_MS 2000 -static void pmac_ide_setup_dma(struct device_node *np, int ix); -static int pmac_ide_build_dmatable(ide_drive_t *drive, int wr); +static void pmac_ide_setup_dma(pmac_ide_hwif_t *pmif, ide_hwif_t *hwif); +static int pmac_ide_build_dmatable(ide_drive_t *drive, struct request *rq); static int pmac_ide_tune_chipset(ide_drive_t *drive, u8 speed); static void pmac_ide_tuneproc(ide_drive_t *drive, u8 pio); static void pmac_ide_selectproc(ide_drive_t *drive); +static void pmac_ide_kauai_selectproc(ide_drive_t *drive); static int pmac_ide_dma_begin (ide_drive_t *drive); #endif /* CONFIG_BLK_DEV_IDEDMA_PMAC */ -#ifdef CONFIG_PMAC_PBOOK -static int idepmac_notify_sleep(struct pmu_sleep_notifier *self, int when); -struct pmu_sleep_notifier idepmac_sleep_notifier = { - idepmac_notify_sleep, SLEEP_LEVEL_BLOCK, -}; -#endif /* CONFIG_PMAC_PBOOK */ +#ifdef CONFIG_BLK_DEV_IDE_PMAC_BLINK + +/* Set to 50ms */ +#define PMU_HD_BLINK_TIME (HZ/50) + +static struct adb_request pmu_blink_on, pmu_blink_off; +static spinlock_t pmu_blink_lock; +static unsigned long pmu_blink_stoptime; +static int pmu_blink_ledstate; +static struct timer_list pmu_blink_timer; +static int pmu_ide_blink_enabled; + + +static void +pmu_hd_blink_timeout(unsigned long data) +{ + unsigned long flags; + + spin_lock_irqsave(&pmu_blink_lock, flags); + + /* We may have been triggered again in a racy way, check + * that we really want to switch it off + */ + if (time_after(pmu_blink_stoptime, jiffies)) + goto done; + + /* Previous req. not complete, try 100ms more */ + if (pmu_blink_off.complete == 0) + mod_timer(&pmu_blink_timer, jiffies + PMU_HD_BLINK_TIME); + else if (pmu_blink_ledstate) { + pmu_request(&pmu_blink_off, NULL, 4, 0xee, 4, 0, 0); + pmu_blink_ledstate = 0; + } +done: + spin_unlock_irqrestore(&pmu_blink_lock, flags); +} + +static void +pmu_hd_kick_blink(void *data, int rw) +{ + unsigned long flags; + + pmu_blink_stoptime = jiffies + PMU_HD_BLINK_TIME; + wmb(); + mod_timer(&pmu_blink_timer, pmu_blink_stoptime); + if (pmu_blink_ledstate == 1) + return; + spin_lock_irqsave(&pmu_blink_lock, flags); + if (pmu_blink_on.complete && !pmu_blink_ledstate) { + pmu_request(&pmu_blink_on, NULL, 4, 0xee, 4, 0, 1); + pmu_blink_ledstate = 1; + } + spin_unlock_irqrestore(&pmu_blink_lock, flags); +} + +static int +pmu_hd_blink_init(void) +{ + struct device_node *dt; + const char *model; + + if (pmu_get_model() != PMU_KEYLARGO_BASED) + return 0; + + dt = find_devices("device-tree"); + if (dt == NULL) + return 0; + model = (const char *)get_property(dt, "model", NULL); + if (model == NULL) + return 0; + if (strncmp(model, "PowerBook", strlen("PowerBook")) != 0 && + strncmp(model, "iBook", strlen("iBook")) != 0) + return 0; + + pmu_blink_on.complete = 1; + pmu_blink_off.complete = 1; + spin_lock_init(&pmu_blink_lock); + init_timer(&pmu_blink_timer); + pmu_blink_timer.function = pmu_hd_blink_timeout; + + return 1; +} + +#endif /* CONFIG_BLK_DEV_IDE_PMAC_BLINK */ /* * N.B. this can't be an initfunc, because the media-bay task can @@ -315,6 +496,41 @@ (void)readl((unsigned *)(IDE_DATA_REG+IDE_TIMING_CONFIG)); } +static void __pmac +pmac_ide_kauai_selectproc(ide_drive_t *drive) +{ + pmac_ide_hwif_t* pmif = (pmac_ide_hwif_t *)HWIF(drive)->hwif_data; + + if (pmif == NULL) + return; + + if (drive->select.b.unit & 0x01) { + writel(pmif->timings[1], + (unsigned *)(IDE_DATA_REG + IDE_KAUAI_PIO_CONFIG)); + writel(pmif->timings[3], + (unsigned *)(IDE_DATA_REG + IDE_KAUAI_ULTRA_CONFIG)); + } else { + writel(pmif->timings[0], + (unsigned *)(IDE_DATA_REG + IDE_KAUAI_PIO_CONFIG)); + writel(pmif->timings[2], + (unsigned *)(IDE_DATA_REG + IDE_KAUAI_ULTRA_CONFIG)); + } + (void)readl((unsigned *)(IDE_DATA_REG + IDE_KAUAI_PIO_CONFIG)); +} + +static void __pmac +pmac_ide_do_update_timings(ide_drive_t *drive) +{ + pmac_ide_hwif_t* pmif = (pmac_ide_hwif_t *)HWIF(drive)->hwif_data; + + if (pmif == NULL) + return; + + if (pmif->kind == controller_un_ata6) + pmac_ide_kauai_selectproc(drive); + else + pmac_ide_selectproc(drive); +} static int __pmac pmac_ide_do_setfeature(ide_drive_t *drive, u8 command) @@ -322,7 +538,7 @@ ide_hwif_t *hwif = HWIF(drive); int result = 1; - disable_irq(hwif->irq); /* disable_irq_nosync ?? */ + disable_irq_nosync(hwif->irq); udelay(1); SELECT_DRIVE(drive); SELECT_MASK(drive, 0); @@ -332,22 +548,22 @@ /* Timeout bumped for some powerbooks */ if (wait_for_ready(drive, 2000)) { /* Timeout bumped for some powerbooks */ - printk(KERN_ERR "pmac_ide_do_setfeature disk not ready " - "before SET_FEATURE!\n"); + printk(KERN_ERR "%s: pmac_ide_do_setfeature disk not ready " + "before SET_FEATURE!\n", drive->name); goto out; } udelay(10); hwif->OUTB(drive->ctl | 2, IDE_CONTROL_REG); hwif->OUTB(command, IDE_NSECTOR_REG); hwif->OUTB(SETFEATURES_XFER, IDE_FEATURE_REG); - hwif->OUTB(WIN_SETFEATURES, IDE_COMMAND_REG); + hwif->OUTBSYNC(drive, WIN_SETFEATURES, IDE_COMMAND_REG); udelay(1); /* Timeout bumped for some powerbooks */ result = wait_for_ready(drive, 2000); hwif->OUTB(drive->ctl, IDE_CONTROL_REG); if (result) - printk(KERN_ERR "pmac_ide_do_setfeature disk not ready " - "after SET_FEATURE !\n"); + printk(KERN_ERR "%s: pmac_ide_do_setfeature disk not ready " + "after SET_FEATURE !\n", drive->name); out: SELECT_MASK(drive, 0); if (result == 0) { @@ -403,21 +619,27 @@ if (pmif == NULL) return; + /* which drive is it ? */ + timings = &pmif->timings[drive->select.b.unit & 0x01]; + pio = ide_get_best_pio_mode(drive, pio, 4, &d); - accessTicks = SYSCLK_TICKS(ide_pio_timings[pio].active_time); - if (drive->select.b.unit & 0x01) - timings = &pmif->timings[1]; - else - timings = &pmif->timings[0]; - recTime = d.cycle_time - ide_pio_timings[pio].active_time - - ide_pio_timings[pio].setup_time; - recTime = max(recTime, 150U); - accessTime = ide_pio_timings[pio].active_time; - accessTime = max(accessTime, 150U); - if (pmif->kind == controller_kl_ata4 || - pmif->kind == controller_kl_ata4_80) { + switch (pmif->kind) { + case controller_un_ata6: { + /* 100Mhz cell */ + u32 tr = kauai_lookup_timing(kauai_pio_timings, d.cycle_time); + if (tr == 0) + return; + *timings = ((*timings) & ~TR_100_PIOREG_PIO_MASK) | tr; + break; + } + case controller_kl_ata4: /* 66Mhz cell */ + recTime = d.cycle_time - ide_pio_timings[pio].active_time + - ide_pio_timings[pio].setup_time; + recTime = max(recTime, 150U); + accessTime = ide_pio_timings[pio].active_time; + accessTime = max(accessTime, 150U); accessTicks = SYSCLK_TICKS_66(accessTime); accessTicks = min(accessTicks, 0x1fU); recTicks = SYSCLK_TICKS_66(recTime); @@ -425,9 +647,15 @@ *timings = ((*timings) & ~TR_66_PIO_MASK) | (accessTicks << TR_66_PIO_ACCESS_SHIFT) | (recTicks << TR_66_PIO_RECOVERY_SHIFT); - } else { + break; + default: { /* 33Mhz cell */ int ebit = 0; + recTime = d.cycle_time - ide_pio_timings[pio].active_time + - ide_pio_timings[pio].setup_time; + recTime = max(recTime, 150U); + accessTime = ide_pio_timings[pio].active_time; + accessTime = max(accessTime, 150U); accessTicks = SYSCLK_TICKS(accessTime); accessTicks = min(accessTicks, 0x1fU); accessTicks = max(accessTicks, 4U); @@ -443,26 +671,31 @@ (recTicks << TR_33_PIO_RECOVERY_SHIFT); if (ebit) *timings |= TR_33_PIO_E; + break; + } } #ifdef IDE_PMAC_DEBUG - printk(KERN_ERR "ide_pmac: Set PIO timing for mode %d, reg: 0x%08x\n", - pio, *timings); + printk(KERN_ERR "%s: Set PIO timing for mode %d, reg: 0x%08x\n", + drive->name, pio, *timings); #endif if (drive->select.all == HWIF(drive)->INB(IDE_SELECT_REG)) - pmac_ide_selectproc(drive); + pmac_ide_do_update_timings(drive); } #ifdef CONFIG_BLK_DEV_IDEDMA_PMAC static int __pmac -set_timings_udma(u32 *timings, u8 speed) +set_timings_udma_ata4(u32 *timings, u8 speed) { unsigned rdyToPauseTicks, wrDataSetupTicks, addrTicks; - rdyToPauseTicks = SYSCLK_TICKS_66(udma_timings[speed & 0xf].rdy2pause); - wrDataSetupTicks = SYSCLK_TICKS_66(udma_timings[speed & 0xf].wrDataSetup); - addrTicks = SYSCLK_TICKS_66(udma_timings[speed & 0xf].addrSetup); + if (speed > XFER_UDMA_4) + return 1; + + rdyToPauseTicks = SYSCLK_TICKS_66(kl66_udma_timings[speed & 0xf].rdy2pause); + wrDataSetupTicks = SYSCLK_TICKS_66(kl66_udma_timings[speed & 0xf].wrDataSetup); + addrTicks = SYSCLK_TICKS_66(kl66_udma_timings[speed & 0xf].addrSetup); *timings = ((*timings) & ~(TR_66_UDMA_MASK | TR_66_MDMA_MASK)) | (wrDataSetupTicks << TR_66_UDMA_WRDATASETUP_SHIFT) | @@ -478,11 +711,29 @@ } static int __pmac -set_timings_mdma(int intf_type, u32 *timings, u8 speed, int drive_cycle_time) +set_timings_udma_ata6(u32 *pio_timings, u32 *ultra_timings, u8 speed) +{ + struct ide_timing *t = ide_timing_find_mode(speed); + u32 tr; + + if (speed > XFER_UDMA_5 || t == NULL) + return 1; + tr = kauai_lookup_timing(kauai_udma_timings, (int)t->udma); + if (tr == 0) + return 1; + *ultra_timings = ((*ultra_timings) & ~TR_100_UDMAREG_UDMA_MASK) | tr; + *ultra_timings = (*ultra_timings) | TR_100_UDMAREG_UDMA_EN; + + return 0; +} + +static int __pmac +set_timings_mdma(ide_drive_t *drive, int intf_type, u32 *timings, u32 *timings2, + u8 speed, int drive_cycle_time) { int cycleTime, accessTime, recTime; unsigned accessTicks, recTicks; - struct mdma_timings_t* tm; + struct mdma_timings_t* tm = NULL; int i; /* Get default cycle time for mode */ @@ -491,7 +742,7 @@ case 1: cycleTime = 150; break; case 2: cycleTime = 120; break; default: - return -1; + return 1; } /* Adjust for drive */ if (drive_cycle_time && drive_cycle_time > cycleTime) @@ -501,8 +752,9 @@ cycleTime = 150; /* Get the proper timing array for this controller */ switch(intf_type) { + case controller_un_ata6: + break; case controller_kl_ata4: - case controller_kl_ata4_80: tm = mdma_timings_66; break; case controller_kl_ata3: @@ -512,24 +764,36 @@ tm = mdma_timings_33; break; } - /* Lookup matching access & recovery times */ - i = -1; - for (;;) { - if (tm[i+1].cycleTime < cycleTime) - break; - i++; - } - if (i < 0) - return -1; - cycleTime = tm[i].cycleTime; - accessTime = tm[i].accessTime; - recTime = tm[i].recoveryTime; + if (tm != NULL) { + /* Lookup matching access & recovery times */ + i = -1; + for (;;) { + if (tm[i+1].cycleTime < cycleTime) + break; + i++; + } + if (i < 0) + return 1; + cycleTime = tm[i].cycleTime; + accessTime = tm[i].accessTime; + recTime = tm[i].recoveryTime; #ifdef IDE_PMAC_DEBUG - printk(KERN_ERR "ide_pmac: MDMA, cycleTime: %d, accessTime: %d, recTime: %d\n", - cycleTime, accessTime, recTime); -#endif - if (intf_type == controller_kl_ata4 || intf_type == controller_kl_ata4_80) { + printk(KERN_ERR "%s: MDMA, cycleTime: %d, accessTime: %d, recTime: %d\n", + drive->name, cycleTime, accessTime, recTime); +#endif + } + switch(intf_type) { + case controller_un_ata6: { + /* 100Mhz cell */ + u32 tr = kauai_lookup_timing(kauai_mdma_timings, cycleTime); + if (tr == 0) + return 1; + *timings = ((*timings) & ~TR_100_PIOREG_MDMA_MASK) | tr; + *timings2 = (*timings2) & ~TR_100_UDMAREG_UDMA_EN; + } + break; + case controller_kl_ata4: /* 66Mhz cell */ accessTicks = SYSCLK_TICKS_66(accessTime); accessTicks = min(accessTicks, 0x1fU); @@ -541,7 +805,8 @@ *timings = ((*timings) & ~(TR_66_MDMA_MASK | TR_66_UDMA_MASK)) | (accessTicks << TR_66_MDMA_ACCESS_SHIFT) | (recTicks << TR_66_MDMA_RECOVERY_SHIFT); - } else if (intf_type == controller_kl_ata3) { + break; + case controller_kl_ata3: /* 33Mhz cell on KeyLargo */ accessTicks = SYSCLK_TICKS(accessTime); accessTicks = max(accessTicks, 1U); @@ -553,7 +818,8 @@ *timings = ((*timings) & ~TR_33_MDMA_MASK) | (accessTicks << TR_33_MDMA_ACCESS_SHIFT) | (recTicks << TR_33_MDMA_RECOVERY_SHIFT); - } else { + break; + default: { /* 33Mhz cell on others */ int halfTick = 0; int origAccessTime = accessTime; @@ -578,10 +844,11 @@ (recTicks << TR_33_MDMA_RECOVERY_SHIFT); if (halfTick) *timings |= TR_33_MDMA_HALFTICK; + } } #ifdef IDE_PMAC_DEBUG - printk(KERN_ERR "ide_pmac: Set MDMA timing for mode %d, reg: 0x%08x\n", - speed & 0xf, *timings); + printk(KERN_ERR "%s: Set MDMA timing for mode %d, reg: 0x%08x\n", + drive->name, speed & 0xf, *timings); #endif return 0; } @@ -591,36 +858,42 @@ * our, normal mdma function is supposed to be more precise */ static int __pmac -pmac_ide_tune_chipset (ide_drive_t *drive, u8 speed) +pmac_ide_tune_chipset (ide_drive_t *drive, byte speed) { int unit = (drive->select.b.unit & 0x01); int ret = 0; pmac_ide_hwif_t* pmif = (pmac_ide_hwif_t *)HWIF(drive)->hwif_data; - u32 *timings; - + u32 *timings, *timings2; + if (pmif == NULL) return 1; - + timings = &pmif->timings[unit]; + timings2 = &pmif->timings[unit+2]; switch(speed) { #ifdef CONFIG_BLK_DEV_IDEDMA_PMAC + case XFER_UDMA_5: + if (pmif->kind != controller_un_ata6) + return 1; case XFER_UDMA_4: case XFER_UDMA_3: - if (pmif->kind != controller_kl_ata4_80) + if (HWIF(drive)->udma_four == 0) return 1; case XFER_UDMA_2: case XFER_UDMA_1: case XFER_UDMA_0: - if (pmif->kind != controller_kl_ata4 && - pmif->kind != controller_kl_ata4_80) - return 1; - ret = set_timings_udma(timings, speed); + if (pmif->kind == controller_kl_ata4) + ret = set_timings_udma_ata4(timings, speed); + else if (pmif->kind == controller_un_ata6) + ret = set_timings_udma_ata6(timings, timings2, speed); + else + ret = 1; break; case XFER_MW_DMA_2: case XFER_MW_DMA_1: case XFER_MW_DMA_0: - ret = set_timings_mdma(pmif->kind, timings, speed, 0); + ret = set_timings_mdma(drive, pmif->kind, timings, timings2, speed, 0); break; case XFER_SW_DMA_2: case XFER_SW_DMA_1: @@ -644,7 +917,7 @@ if (ret) return ret; - pmac_ide_selectproc(drive); + pmac_ide_do_update_timings(drive); drive->current_speed = speed; return 0; @@ -653,11 +926,14 @@ static void __pmac sanitize_timings(pmac_ide_hwif_t *pmif) { - unsigned value; + unsigned int value, value2 = 0; switch(pmif->kind) { + case controller_un_ata6: + value = 0x08618a92; + value2 = 0x00002921; + break; case controller_kl_ata4: - case controller_kl_ata4_80: value = 0x0008438c; break; case controller_kl_ata3: @@ -670,6 +946,7 @@ break; } pmif->timings[0] = pmif->timings[1] = value; + pmif->timings[2] = pmif->timings[3] = value2; } unsigned long __pmac @@ -724,214 +1001,474 @@ return 0; } -void __init -pmac_ide_probe(void) +/* Suspend call back, should be called after the child devices + * have actually been suspended + */ +static int +pmac_ide_do_suspend(ide_hwif_t *hwif) { - struct device_node *np; - int i; - struct device_node *atas; - struct device_node *p, **pp, *removables, **rp; - unsigned long base; - int irq, big_delay; - ide_hwif_t *hwif; + pmac_ide_hwif_t *pmif = (pmac_ide_hwif_t *)hwif->hwif_data; + + /* We clear the timings */ + pmif->timings[0] = 0; + pmif->timings[1] = 0; + +#ifdef CONFIG_BLK_DEV_IDE_PMAC_BLINK + /* Note: This code will be called for every hwif, thus we'll + * try several time to stop the LED blinker timer, but that + * should be harmless + */ + if (pmu_ide_blink_enabled) { + unsigned long flags; - if (_machine != _MACH_Pmac) - return; - pp = &atas; - rp = &removables; - p = find_devices("ATA"); - if (p == NULL) - p = find_devices("IDE"); - if (p == NULL) - p = find_type_devices("ide"); - if (p == NULL) - p = find_type_devices("ata"); - /* Move removable devices such as the media-bay CDROM - on the PB3400 to the end of the list. */ - for (; p != NULL; p = p->next) { - if (p->parent && p->parent->type - && strcasecmp(p->parent->type, "media-bay") == 0) { - *rp = p; - rp = &p->next; - } else { - *pp = p; - pp = &p->next; - } + /* Make sure we don't hit the PMU blink */ + spin_lock_irqsave(&pmu_blink_lock, flags); + if (pmu_blink_ledstate) + del_timer(&pmu_blink_timer); + pmu_blink_ledstate = 0; + spin_unlock_irqrestore(&pmu_blink_lock, flags); } - *rp = NULL; - *pp = removables; - big_delay = 0; - - for (i = 0, np = atas; i < MAX_HWIFS && np != NULL; np = np->next) { - struct device_node *tp; - struct pmac_ide_hwif* pmif; - int *bidp; - int in_bay = 0; - u8 pbus, pid; - struct pci_dev *pdev = NULL; - - /* - * If this node is not under a mac-io or dbdma node, - * leave it to the generic PCI driver. - */ - for (tp = np->parent; tp != 0; tp = tp->parent) - if (tp->type && (strcmp(tp->type, "mac-io") == 0 - || strcmp(tp->type, "dbdma") == 0)) - break; - if (tp == 0) - continue; +#endif /* CONFIG_BLK_DEV_IDE_PMAC_BLINK */ - if (np->n_addrs == 0) { - printk(KERN_WARNING "ide: no address for device %s\n", - np->full_name); - continue; - } + /* The media bay will handle itself just fine */ + if (pmif->mediabay) + return 0; + + /* Disable the bus */ + ppc_md.feature_call(PMAC_FTR_IDE_ENABLE, pmif->node, pmif->aapl_bus_id, 0); - /* We need to find the pci_dev of the mac-io holding the - * IDE interface - */ - if (pci_device_from_OF_node(tp, &pbus, &pid) == 0) - pdev = pci_find_slot(pbus, pid); - if (pdev == NULL) - printk(KERN_WARNING "ide: no PCI host for device %s, DMA disabled\n", - np->full_name); + return 0; +} - /* - * If this slot is taken (e.g. by ide-pci.c) try the next one. - */ - while (i < MAX_HWIFS - && ide_hwifs[i].io_ports[IDE_DATA_OFFSET] != 0) - ++i; - if (i >= MAX_HWIFS) - break; - pmif = &pmac_ide[i]; +/* Resume call back, should be called before the child devices + * are resumed + */ +static int +pmac_ide_do_resume(ide_hwif_t *hwif) +{ + pmac_ide_hwif_t *pmif = (pmac_ide_hwif_t *)hwif->hwif_data; + + /* Hard reset & re-enable controller (do we really need to reset ? -BenH) */ + if (!pmif->mediabay) { + ppc_md.feature_call(PMAC_FTR_IDE_RESET, pmif->node, pmif->aapl_bus_id, 1); + ppc_md.feature_call(PMAC_FTR_IDE_ENABLE, pmif->node, pmif->aapl_bus_id, 1); + mdelay(10); + ppc_md.feature_call(PMAC_FTR_IDE_RESET, pmif->node, pmif->aapl_bus_id, 0); + mdelay(100); + } - /* - * Some older OFs have bogus sizes, causing request_OF_resource - * to fail. We fix them up here - */ - if (np->addrs[0].size > 0x1000) - np->addrs[0].size = 0x1000; - if (np->n_addrs > 1 && np->addrs[1].size > 0x100) - np->addrs[1].size = 0x100; + /* Sanitize drive timings */ + sanitize_timings(pmif); - if (request_OF_resource(np, 0, " (mac-io IDE IO)") == NULL) { - printk(KERN_ERR "ide-pmac(%s): can't request IO resource !\n", np->name); - continue; - } + return 0; +} - base = (unsigned long) ioremap(np->addrs[0].address, 0x400); +static int +pmac_ide_setup_device(pmac_ide_hwif_t *pmif, ide_hwif_t *hwif) +{ + struct device_node *np = pmif->node; + int *bidp, i; - /* XXX This is bogus. Should be fixed in the registry by checking - the kind of host interrupt controller, a bit like gatwick - fixes in irq.c - */ - if (np->n_intrs == 0) { - printk(KERN_WARNING "ide: no intrs for device %s, using 13\n", - np->full_name); - irq = 13; - } else { - irq = np->intrs[0].line; - } - pmif->regbase = base; - pmif->irq = irq; - pmif->node = np; - pmif->index = i; - if (device_is_compatible(np, "keylargo-ata")) { - if (strcmp(np->name, "ata-4") == 0) - pmif->kind = controller_kl_ata4; - else - pmif->kind = controller_kl_ata3; - } else if (device_is_compatible(np, "heathrow-ata")) - pmif->kind = controller_heathrow; + pmif->cable_80 = 0; + pmif->broken_dma = pmif->broken_dma_warn = 0; + if (device_is_compatible(np, "kauai-ata")) + pmif->kind = controller_un_ata6; + else if (device_is_compatible(np, "keylargo-ata")) { + if (strcmp(np->name, "ata-4") == 0) + pmif->kind = controller_kl_ata4; else - pmif->kind = controller_ohare; + pmif->kind = controller_kl_ata3; + } else if (device_is_compatible(np, "heathrow-ata")) + pmif->kind = controller_heathrow; + else { + pmif->kind = controller_ohare; + pmif->broken_dma = 1; + } - bidp = (int *)get_property(np, "AAPL,bus-id", NULL); - pmif->aapl_bus_id = bidp ? *bidp : 0; + bidp = (int *)get_property(np, "AAPL,bus-id", NULL); + pmif->aapl_bus_id = bidp ? *bidp : 0; - if (pmif->kind == controller_kl_ata4) { - char* cable = get_property(np, "cable-type", NULL); - if (cable && !strncmp(cable, "80-", 3)) - pmif->kind = controller_kl_ata4_80; - } + /* Get cable type from device-tree */ + if (pmif->kind == controller_kl_ata4 || pmif->kind == controller_un_ata6) { + char* cable = get_property(np, "cable-type", NULL); + if (cable && !strncmp(cable, "80-", 3)) + pmif->cable_80 = 1; + } - /* Make sure we have sane timings */ - sanitize_timings(pmif); + pmif->mediabay = 0; + + /* Make sure we have sane timings */ + sanitize_timings(pmif); - if (np->parent && np->parent->name - && strcasecmp(np->parent->name, "media-bay") == 0) { + /* XXX FIXME: Media bay stuff need re-organizing */ + if (np->parent && np->parent->name + && strcasecmp(np->parent->name, "media-bay") == 0) { #ifdef CONFIG_PMAC_PBOOK - media_bay_set_ide_infos(np->parent,base,irq,i); + media_bay_set_ide_infos(np->parent, pmif->regbase, pmif->irq, hwif->index); #endif /* CONFIG_PMAC_PBOOK */ - in_bay = 1; - if (!bidp) - pmif->aapl_bus_id = 1; - } else if (pmif->kind == controller_ohare) { - /* The code below is having trouble on some ohare machines - * (timing related ?). Until I can put my hand on one of these - * units, I keep the old way - */ - ppc_md.feature_call(PMAC_FTR_IDE_ENABLE, np, 0, 1); - } else { - /* This is necessary to enable IDE when net-booting */ - printk(KERN_INFO "pmac_ide: enabling IDE bus ID %d\n", - pmif->aapl_bus_id); - ppc_md.feature_call(PMAC_FTR_IDE_RESET, np, pmif->aapl_bus_id, 1); - ppc_md.feature_call(PMAC_FTR_IDE_ENABLE, np, pmif->aapl_bus_id, 1); - mdelay(10); - ppc_md.feature_call(PMAC_FTR_IDE_RESET, np, pmif->aapl_bus_id, 0); - big_delay = 1; - } + pmif->mediabay = 1; + if (!bidp) + pmif->aapl_bus_id = 1; + } else if (pmif->kind == controller_ohare) { + /* The code below is having trouble on some ohare machines + * (timing related ?). Until I can put my hand on one of these + * units, I keep the old way + */ + ppc_md.feature_call(PMAC_FTR_IDE_ENABLE, np, 0, 1); + } else { + /* This is necessary to enable IDE when net-booting */ + ppc_md.feature_call(PMAC_FTR_IDE_RESET, np, pmif->aapl_bus_id, 1); + ppc_md.feature_call(PMAC_FTR_IDE_ENABLE, np, pmif->aapl_bus_id, 1); + mdelay(10); + ppc_md.feature_call(PMAC_FTR_IDE_RESET, np, pmif->aapl_bus_id, 0); + mdelay(100); + } - hwif = &ide_hwifs[i]; - /* Setup MMIO ops */ - default_hwif_mmiops(hwif); - /* Tell common code _not_ to mess with resources */ - hwif->mmio = 2; - hwif->hwif_data = pmif; - pmac_ide_init_hwif_ports(&hwif->hw, base, 0, &hwif->irq); - memcpy(hwif->io_ports, hwif->hw.io_ports, sizeof(hwif->io_ports)); - hwif->chipset = ide_pmac; - hwif->noprobe = !hwif->io_ports[IDE_DATA_OFFSET] || in_bay; - hwif->udma_four = (pmif->kind == controller_kl_ata4_80); - hwif->pci_dev = pdev; - hwif->drives[0].unmask = 1; - hwif->drives[1].unmask = 1; - hwif->tuneproc = pmac_ide_tuneproc; + /* Setup MMIO ops */ + default_hwif_mmiops(hwif); + + /* Tell common code _not_ to mess with resources */ + hwif->mmio = 2; + hwif->hwif_data = pmif; + pmac_ide_init_hwif_ports(&hwif->hw, pmif->regbase, 0, &hwif->irq); + memcpy(hwif->io_ports, hwif->hw.io_ports, sizeof(hwif->io_ports)); + hwif->chipset = ide_pmac; + hwif->noprobe = !hwif->io_ports[IDE_DATA_OFFSET] || pmif->mediabay; + hwif->hold = pmif->mediabay; + hwif->udma_four = pmif->cable_80; + hwif->drives[0].unmask = 1; + hwif->drives[1].unmask = 1; + hwif->tuneproc = pmac_ide_tuneproc; + if (pmif->kind == controller_un_ata6) + hwif->selectproc = pmac_ide_kauai_selectproc; + else hwif->selectproc = pmac_ide_selectproc; - hwif->speedproc = pmac_ide_tune_chipset; + hwif->speedproc = pmac_ide_tune_chipset; + +#ifdef CONFIG_BLK_DEV_IDE_PMAC_BLINK + pmu_ide_blink_enabled = pmu_hd_blink_init(); + + if (pmu_ide_blink_enabled) + hwif->led_act = pmu_hd_kick_blink; +#endif + + printk(KERN_INFO "ide%d: Found Apple %s controller, bus ID %d%s\n", + hwif->index, model_name[pmif->kind], pmif->aapl_bus_id, + pmif->mediabay ? " (mediabay)" : ""); + #ifdef CONFIG_PMAC_PBOOK - if (in_bay && check_media_bay_by_base(base, MB_CD) == 0) - hwif->noprobe = 0; + if (pmif->mediabay && check_media_bay_by_base(pmif->regbase, MB_CD) == 0) + hwif->noprobe = 0; #endif /* CONFIG_PMAC_PBOOK */ #ifdef CONFIG_BLK_DEV_IDEDMA_PMAC - if (np->n_addrs >= 2) { - /* has a DBDMA controller channel */ - pmac_ide_setup_dma(np, i); - } - hwif->atapi_dma = 1; - hwif->ultra_mask = 0x1f; - hwif->mwdma_mask = 0x07; - hwif->swdma_mask = 0x07; - + /* has a DBDMA controller channel */ + if (pmif->dma_regs) + pmac_ide_setup_dma(pmif, hwif); #endif /* CONFIG_BLK_DEV_IDEDMA_PMAC */ + /* We probe the hwif now */ + probe_hwif_init(hwif); + + /* The code IDE code will have set hwif->present if we have devices attached, + * if we don't, the discard the interface except if we are on a media bay slot + */ + if (!hwif->present && !pmif->mediabay) { + printk(KERN_INFO "ide%d: Bus empty, interface released.\n", + hwif->index); + default_hwif_iops(hwif); + for (i = IDE_DATA_OFFSET; i <= IDE_CONTROL_OFFSET; ++i) + hwif->io_ports[i] = 0; + hwif->chipset = ide_unknown; + hwif->noprobe = 1; + return -ENODEV; + } + + return 0; +} + +static int __devinit +pmac_ide_macio_attach(struct macio_dev *mdev, const struct of_match *match) +{ + unsigned long base, regbase; + int irq; + ide_hwif_t *hwif; + pmac_ide_hwif_t *pmif; + int i, rc; + + i = 0; + while (i < MAX_HWIFS && (ide_hwifs[i].io_ports[IDE_DATA_OFFSET] != 0 + || pmac_ide[i].node != NULL)) ++i; + if (i >= MAX_HWIFS) { + printk(KERN_ERR "ide-pmac: MacIO interface attach with no slot\n"); + printk(KERN_ERR " %s\n", mdev->ofdev.node->full_name); + return -ENODEV; } - pmac_ide_count = i; - if (big_delay) - mdelay(IDE_WAKEUP_DELAY_MS); -#ifdef CONFIG_PMAC_PBOOK - pmu_register_sleep_notifier(&idepmac_sleep_notifier); -#endif /* CONFIG_PMAC_PBOOK */ + pmif = &pmac_ide[i]; + hwif = &ide_hwifs[i]; + + if (mdev->ofdev.node->n_addrs == 0) { + printk(KERN_WARNING "ide%d: no address for %s\n", + i, mdev->ofdev.node->full_name); + return -ENXIO; + } + + /* + * Some older OFs have bogus sizes, causing request_OF_resource + * to fail. We fix them up here + */ + if (mdev->ofdev.node->addrs[0].size > 0x1000) + mdev->ofdev.node->addrs[0].size = 0x1000; + if (mdev->ofdev.node->n_addrs > 1 && mdev->ofdev.node->addrs[1].size > 0x100) + mdev->ofdev.node->addrs[1].size = 0x100; + + /* Request memory resource for IO ports */ + if (request_OF_resource(mdev->ofdev.node, 0, " (mac-io ata ports)") == NULL) { + printk(KERN_ERR "ide%d: can't request mmio resource !\n", i); + return -EBUSY; + } + + /* XXX This is bogus. Should be fixed in the registry by checking + * the kind of host interrupt controller, a bit like gatwick + * fixes in irq.c. That works well enough for the single case + * where that happens though... + */ + if (mdev->ofdev.node->n_intrs == 0) { + printk(KERN_WARNING "ide%d: no intrs for device %s, using 13\n", + i, mdev->ofdev.node->full_name); + irq = 13; + } else + irq = mdev->ofdev.node->intrs[0].line; + + base = (unsigned long) ioremap(mdev->ofdev.node->addrs[0].address, 0x400); + regbase = base; + + hwif->pci_dev = mdev->bus->pdev; + hwif->gendev.parent = &mdev->ofdev.dev; + + pmif->mdev = mdev; + pmif->node = mdev->ofdev.node; + pmif->regbase = regbase; + pmif->irq = irq; +#ifdef CONFIG_BLK_DEV_IDEDMA_PMAC + if (mdev->ofdev.node->n_addrs >= 2) + pmif->dma_regs = (volatile struct dbdma_regs*) + ioremap(mdev->ofdev.node->addrs[1].address, 0x1000); + else + pmif->dma_regs = NULL; +#endif /* CONFIG_BLK_DEV_IDEDMA_PMAC */ + dev_set_drvdata(&mdev->ofdev.dev, hwif); + + rc = pmac_ide_setup_device(pmif, hwif); + if (rc != 0) { + /* The inteface is released to the common IDE layer */ + dev_set_drvdata(&mdev->ofdev.dev, NULL); + iounmap((void *)base); + if (pmif->dma_regs) + iounmap((void *)pmif->dma_regs); + memset(pmif, 0, sizeof(*pmif)); + release_OF_resource(mdev->ofdev.node, 0); + } + + return rc; } +static int +pmac_ide_macio_suspend(struct macio_dev *mdev, u32 state) +{ + ide_hwif_t *hwif = (ide_hwif_t *)dev_get_drvdata(&mdev->ofdev.dev); + int rc = 0; + + if (state != mdev->ofdev.dev.power_state && state >= 2) { + rc = pmac_ide_do_suspend(hwif); + if (rc == 0) + mdev->ofdev.dev.power_state = state; + } + + return rc; +} + +static int +pmac_ide_macio_resume(struct macio_dev *mdev) +{ + ide_hwif_t *hwif = (ide_hwif_t *)dev_get_drvdata(&mdev->ofdev.dev); + int rc = 0; + + if (mdev->ofdev.dev.power_state != 0) { + rc = pmac_ide_do_resume(hwif); + if (rc == 0) + mdev->ofdev.dev.power_state = 0; + } + + return rc; +} + +static int __devinit +pmac_ide_pci_attach(struct pci_dev *pdev, const struct pci_device_id *id) +{ + ide_hwif_t *hwif; + struct device_node *np; + pmac_ide_hwif_t *pmif; + unsigned long base; + unsigned long rbase, rlen; + int i, rc; + + np = pci_device_to_OF_node(pdev); + if (np == NULL) { + printk(KERN_ERR "ide-pmac: cannot find MacIO node for Kauai ATA interface\n"); + return -ENODEV; + } + i = 0; + while (i < MAX_HWIFS && (ide_hwifs[i].io_ports[IDE_DATA_OFFSET] != 0 + || pmac_ide[i].node != NULL)) + ++i; + if (i >= MAX_HWIFS) { + printk(KERN_ERR "ide-pmac: PCI interface attach with no slot\n"); + printk(KERN_ERR " %s\n", np->full_name); + return -ENODEV; + } + + pmif = &pmac_ide[i]; + hwif = &ide_hwifs[i]; + + if (pci_enable_device(pdev)) { + printk(KERN_WARNING "ide%i: Can't enable PCI device for %s\n", + i, np->full_name); + return -ENXIO; + } + pci_set_master(pdev); + + if (pci_request_regions(pdev, "Kauai ATA")) { + printk(KERN_ERR "ide%d: Cannot obtain PCI resources for %s\n", + i, np->full_name); + return -ENXIO; + } + + hwif->pci_dev = pdev; + hwif->gendev.parent = &pdev->dev; + pmif->mdev = NULL; + pmif->node = np; + + rbase = pci_resource_start(pdev, 0); + rlen = pci_resource_len(pdev, 0); + + base = (unsigned long) ioremap(rbase, rlen); + pmif->regbase = base + 0x2000; #ifdef CONFIG_BLK_DEV_IDEDMA_PMAC + pmif->dma_regs = (volatile struct dbdma_regs*)(base + 0x1000); +#endif /* CONFIG_BLK_DEV_IDEDMA_PMAC */ + pmif->irq = pdev->irq; + + pci_set_drvdata(pdev, hwif); + + rc = pmac_ide_setup_device(pmif, hwif); + if (rc != 0) { + /* The inteface is released to the common IDE layer */ + pci_set_drvdata(pdev, NULL); + iounmap((void *)base); + memset(pmif, 0, sizeof(*pmif)); + pci_release_regions(pdev); + } + + return rc; +} + +static int +pmac_ide_pci_suspend(struct pci_dev *pdev, u32 state) +{ + ide_hwif_t *hwif = (ide_hwif_t *)pci_get_drvdata(pdev); + int rc = 0; + + if (state != pdev->dev.power_state && state >= 2) { + rc = pmac_ide_do_suspend(hwif); + if (rc == 0) + pdev->dev.power_state = state; + } + + return rc; +} static int +pmac_ide_pci_resume(struct pci_dev *pdev) +{ + ide_hwif_t *hwif = (ide_hwif_t *)pci_get_drvdata(pdev); + int rc = 0; + + if (pdev->dev.power_state != 0) { + rc = pmac_ide_do_resume(hwif); + if (rc == 0) + pdev->dev.power_state = 0; + } + + return rc; +} + +static struct of_match pmac_ide_macio_match[] = +{ + { + .name = "IDE", + .type = OF_ANY_MATCH, + .compatible = OF_ANY_MATCH + }, + { + .name = "ATA", + .type = OF_ANY_MATCH, + .compatible = OF_ANY_MATCH + }, + { + .name = OF_ANY_MATCH, + .type = "ide", + .compatible = OF_ANY_MATCH + }, + { + .name = OF_ANY_MATCH, + .type = "ata", + .compatible = OF_ANY_MATCH + }, + {}, +}; + +static struct macio_driver pmac_ide_macio_driver = +{ + .name = "ide-pmac", + .match_table = pmac_ide_macio_match, + .probe = pmac_ide_macio_attach, + .suspend = pmac_ide_macio_suspend, + .resume = pmac_ide_macio_resume, +}; + +static struct pci_device_id pmac_ide_pci_match[] __devinitdata = { + { PCI_VENDOR_ID_APPLE, PCI_DEVICE_ID_APPLE_KAUAI_ATA, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, +}; + +static struct pci_driver pmac_ide_pci_driver = { + .name = "ide-pmac", + .id_table = pmac_ide_pci_match, + .probe = pmac_ide_pci_attach, + .suspend = pmac_ide_pci_suspend, + .resume = pmac_ide_pci_resume, +}; + +void __init +pmac_ide_probe(void) +{ + if (_machine != _MACH_Pmac) + return; + +#ifdef CONFIG_BLK_DEV_IDE_PMAC_ATA100FIRST + pci_register_driver(&pmac_ide_pci_driver); + macio_register_driver(&pmac_ide_macio_driver); +#else + macio_register_driver(&pmac_ide_macio_driver); + pci_register_driver(&pmac_ide_pci_driver); +#endif +} + +#ifdef CONFIG_BLK_DEV_IDEDMA_PMAC + +static int __pmac pmac_ide_build_sglist(ide_drive_t *drive, struct request *rq) { ide_hwif_t *hwif = HWIF(drive); @@ -942,7 +1479,7 @@ if (hwif->sg_dma_active) BUG(); - nents = blk_rq_map_sg(&drive->queue, rq, sg); + nents = blk_rq_map_sg(drive->queue, rq, sg); if (rq_data_dir(rq) == READ) pmif->sg_dma_direction = PCI_DMA_FROMDEVICE; @@ -952,7 +1489,7 @@ return pci_map_sg(hwif->pci_dev, sg, nents, pmif->sg_dma_direction); } -static int +static int __pmac pmac_ide_raw_build_sglist(ide_drive_t *drive, struct request *rq) { ide_hwif_t *hwif = HWIF(drive); @@ -968,14 +1505,14 @@ else pmif->sg_dma_direction = PCI_DMA_FROMDEVICE; - if (sector_count > 127) { + if (sector_count > 128) { memset(&sg[nents], 0, sizeof(*sg)); sg[nents].page = virt_to_page(virt_addr); sg[nents].offset = offset_in_page(virt_addr); - sg[nents].length = 127 * SECTOR_SIZE; + sg[nents].length = 128 * SECTOR_SIZE; nents++; - virt_addr = virt_addr + (127 * SECTOR_SIZE); - sector_count -= 127; + virt_addr = virt_addr + (128 * SECTOR_SIZE); + sector_count -= 128; } memset(&sg[nents], 0, sizeof(*sg)); sg[nents].page = virt_to_page(virt_addr); @@ -990,16 +1527,16 @@ * pmac_ide_build_dmatable builds the DBDMA command list * for a transfer and sets the DBDMA channel to point to it. */ -static int -pmac_ide_build_dmatable(ide_drive_t *drive, int wr) +static int __pmac +pmac_ide_build_dmatable(ide_drive_t *drive, struct request *rq) { struct dbdma_cmd *table; int i, count = 0; - struct request *rq = HWGROUP(drive)->rq; ide_hwif_t *hwif = HWIF(drive); pmac_ide_hwif_t* pmif = (pmac_ide_hwif_t *)hwif->hwif_data; volatile struct dbdma_regs *dma = pmif->dma_regs; struct scatterlist *sg; + int wr = (rq_data_dir(rq) == WRITE); /* DMA table is already aligned */ table = (struct dbdma_cmd *) pmif->dma_table_cpu; @@ -1026,10 +1563,18 @@ cur_addr = sg_dma_address(sg); cur_len = sg_dma_len(sg); + if (pmif->broken_dma && cur_addr & (L1_CACHE_BYTES - 1)) { + if (pmif->broken_dma_warn == 0) { + printk(KERN_WARNING "%s: DMA on non aligned address," + "switching to PIO on Ohare chipset\n", drive->name); + pmif->broken_dma_warn = 1; + } + goto use_pio_instead; + } while (cur_len) { unsigned int tc = (cur_len < 0xfe00)? cur_len: 0xfe00; - if (++count >= MAX_DCMDS) { + if (count++ >= MAX_DCMDS) { printk(KERN_WARNING "%s: DMA table too small\n", drive->name); goto use_pio_instead; @@ -1070,7 +1615,7 @@ } /* Teardown mappings after DMA has completed. */ -static void +static void __pmac pmac_ide_destroy_dmatable (ide_drive_t *drive) { struct pci_dev *dev = HWIF(drive)->pci_dev; @@ -1081,67 +1626,25 @@ if (nents) { pci_unmap_sg(dev, sg, nents, pmif->sg_dma_direction); pmif->sg_nents = 0; + HWIF(drive)->sg_dma_active = 0; } } -static __inline__ unsigned char -dma_bits_to_command(unsigned char bits) -{ - if(bits & 0x04) - return XFER_MW_DMA_2; - if(bits & 0x02) - return XFER_MW_DMA_1; - if(bits & 0x01) - return XFER_MW_DMA_0; - return 0; -} - -static __inline__ unsigned char -udma_bits_to_command(unsigned char bits, int high_speed) -{ - if (high_speed) { - if(bits & 0x10) - return XFER_UDMA_4; - if(bits & 0x08) - return XFER_UDMA_3; - } - if(bits & 0x04) - return XFER_UDMA_2; - if(bits & 0x02) - return XFER_UDMA_1; - if(bits & 0x01) - return XFER_UDMA_0; - return 0; -} - /* Calculate MultiWord DMA timings */ static int __pmac -pmac_ide_mdma_enable(ide_drive_t *drive) +pmac_ide_mdma_enable(ide_drive_t *drive, u16 mode) { - u8 bits = drive->id->dma_mword & 0x07; - u8 feature = dma_bits_to_command(bits); - u32 *timings; + ide_hwif_t *hwif = HWIF(drive); + pmac_ide_hwif_t* pmif = (pmac_ide_hwif_t *)hwif->hwif_data; int drive_cycle_time; struct hd_driveid *id = drive->id; - pmac_ide_hwif_t* pmif = (pmac_ide_hwif_t *)HWIF(drive)->hwif_data; + u32 *timings, *timings2; + u32 timing_local[2]; int ret; - /* Set feature on drive */ - printk(KERN_INFO "%s: Enabling MultiWord DMA %d\n", drive->name, feature & 0xf); - ret = pmac_ide_do_setfeature(drive, feature); - if (ret) { - printk(KERN_WARNING "%s: Failed !\n", drive->name); - return 0; - } - - if (!drive->init_speed) - drive->init_speed = feature; - /* which drive is it ? */ - if (drive->select.b.unit & 0x01) - timings = &pmif->timings[1]; - else - timings = &pmif->timings[0]; + timings = &pmif->timings[drive->select.b.unit & 0x01]; + timings2 = &pmif->timings[(drive->select.b.unit & 0x01) + 2]; /* Check if drive provide explicit cycle time */ if ((id->field_valid & 2) && (id->eide_dma_time)) @@ -1149,201 +1652,220 @@ else drive_cycle_time = 0; + /* Copy timings to local image */ + timing_local[0] = *timings; + timing_local[1] = *timings2; + /* Calculate controller timings */ - set_timings_mdma(pmif->kind, timings, feature, drive_cycle_time); + ret = set_timings_mdma( drive, pmif->kind, + &timing_local[0], + &timing_local[1], + mode, + drive_cycle_time); + if (ret) + return 0; + + /* Set feature on drive */ + printk(KERN_INFO "%s: Enabling MultiWord DMA %d\n", drive->name, mode & 0xf); + ret = pmac_ide_do_setfeature(drive, mode); + if (ret) { + printk(KERN_WARNING "%s: Failed !\n", drive->name); + return 0; + } + + /* Apply timings to controller */ + *timings = timing_local[0]; + *timings2 = timing_local[1]; + + /* Set speed info in drive */ + drive->current_speed = mode; + if (!drive->init_speed) + drive->init_speed = mode; - drive->current_speed = feature; return 1; } /* Calculate Ultra DMA timings */ static int __pmac -pmac_ide_udma_enable(ide_drive_t *drive, int high_speed) +pmac_ide_udma_enable(ide_drive_t *drive, u16 mode) { - u8 bits = drive->id->dma_ultra & 0x1f; - u8 feature = udma_bits_to_command(bits, high_speed); - pmac_ide_hwif_t* pmif = (pmac_ide_hwif_t *)HWIF(drive)->hwif_data; - u32 *timings; + ide_hwif_t *hwif = HWIF(drive); + pmac_ide_hwif_t* pmif = (pmac_ide_hwif_t *)hwif->hwif_data; + u32 *timings, *timings2; + u32 timing_local[2]; int ret; + + /* which drive is it ? */ + timings = &pmif->timings[drive->select.b.unit & 0x01]; + timings2 = &pmif->timings[(drive->select.b.unit & 0x01) + 2]; + /* Copy timings to local image */ + timing_local[0] = *timings; + timing_local[1] = *timings2; + + /* Calculate timings for interface */ + if (pmif->kind == controller_un_ata6) + ret = set_timings_udma_ata6( &timing_local[0], + &timing_local[1], + mode); + else + ret = set_timings_udma_ata4(&timing_local[0], mode); + if (ret) + return 0; + /* Set feature on drive */ - printk(KERN_INFO "%s: Enabling Ultra DMA %d\n", drive->name, feature & 0xf); - ret = pmac_ide_do_setfeature(drive, feature); + printk(KERN_INFO "%s: Enabling Ultra DMA %d\n", drive->name, mode & 0x0f); + ret = pmac_ide_do_setfeature(drive, mode); if (ret) { printk(KERN_WARNING "%s: Failed !\n", drive->name); return 0; } - if (!drive->init_speed) - drive->init_speed = feature; + /* Apply timings to controller */ + *timings = timing_local[0]; + *timings2 = timing_local[1]; - /* which drive is it ? */ - if (drive->select.b.unit & 0x01) - timings = &pmif->timings[1]; - else - timings = &pmif->timings[0]; - - set_timings_udma(timings, feature); + /* Set speed info in drive */ + drive->current_speed = mode; + if (!drive->init_speed) + drive->init_speed = mode; - drive->current_speed = feature; return 1; } -int pmac_ide_dma_check(ide_drive_t *drive) +static int __pmac +pmac_ide_dma_check(ide_drive_t *drive) { - int ata4, udma; struct hd_driveid *id = drive->id; ide_hwif_t *hwif = HWIF(drive); pmac_ide_hwif_t* pmif = (pmac_ide_hwif_t *)hwif->hwif_data; int enable = 1; - + int map; drive->using_dma = 0; - if (pmif == NULL) - return 0; - if (drive->media == ide_floppy) enable = 0; - if (((id->capability & 1) == 0) && - !HWIF(drive)->ide_dma_good_drive(drive)) + if (((id->capability & 1) == 0) && !__ide_dma_good_drive(drive)) enable = 0; - if (HWIF(drive)->ide_dma_bad_drive(drive)) + if (__ide_dma_bad_drive(drive)) enable = 0; - udma = 0; - ata4 = (pmif->kind == controller_kl_ata4 || - pmif->kind == controller_kl_ata4_80); - - if(enable) { - if (ata4 && (drive->media == ide_disk) && - (id->field_valid & 0x0004) && (id->dma_ultra & 0x1f)) { - /* UltraDMA modes. */ - drive->using_dma = pmac_ide_udma_enable(drive, - pmif->kind == controller_kl_ata4_80); - } - if (!drive->using_dma && (id->dma_mword & 0x0007)) { - /* Normal MultiWord DMA modes. */ - drive->using_dma = pmac_ide_mdma_enable(drive); + + if (enable) { + short mode; + + map = XFER_MWDMA; + if (pmif->kind == controller_kl_ata4 || pmif->kind == controller_un_ata6) { + map |= XFER_UDMA; + if (pmif->cable_80) { + map |= XFER_UDMA_66; + if (pmif->kind == controller_un_ata6) + map |= XFER_UDMA_100; + } } + mode = ide_find_best_mode(drive, map); + if (mode & XFER_UDMA) + drive->using_dma = pmac_ide_udma_enable(drive, mode); + else if (mode & XFER_MWDMA) + drive->using_dma = pmac_ide_mdma_enable(drive, mode); hwif->OUTB(0, IDE_CONTROL_REG); /* Apply settings to controller */ - pmac_ide_selectproc(drive); + pmac_ide_do_update_timings(drive); } return 0; } -static int -pmac_ide_dma_read (ide_drive_t *drive) +static int __pmac +pmac_ide_dma_start(ide_drive_t *drive, int reading) { ide_hwif_t *hwif = HWIF(drive); pmac_ide_hwif_t* pmif = (pmac_ide_hwif_t *)hwif->hwif_data; struct request *rq = HWGROUP(drive)->rq; -// ide_task_t *args = rq->special; u8 unit = (drive->select.b.unit & 0x01); u8 ata4; - u8 lba48 = (drive->addressing == 1) ? 1 : 0; - task_ioreg_t command = WIN_NOP; if (pmif == NULL) return 1; + ata4 = (pmif->kind == controller_kl_ata4); - ata4 = (pmif->kind == controller_kl_ata4 || - pmif->kind == controller_kl_ata4_80); - - if (!pmac_ide_build_dmatable(drive, 0)) + if (!pmac_ide_build_dmatable(drive, rq)) return 1; + /* Apple adds 60ns to wrDataSetup on reads */ if (ata4 && (pmif->timings[unit] & TR_66_UDMA_EN)) { - writel(pmif->timings[unit]+0x00800000UL, + writel(pmif->timings[unit] + (reading ? 0x00800000UL : 0), (unsigned *)(IDE_DATA_REG+IDE_TIMING_CONFIG)); (void)readl((unsigned *)(IDE_DATA_REG + IDE_TIMING_CONFIG)); } + drive->waiting_for_dma = 1; + + return 0; +} + +static int __pmac +pmac_ide_dma_read(ide_drive_t *drive) +{ + struct request *rq = HWGROUP(drive)->rq; + u8 lba48 = (drive->addressing == 1) ? 1 : 0; + task_ioreg_t command = WIN_NOP; + + if (pmac_ide_dma_start(drive, 1)) + return 1; + if (drive->media != ide_disk) return 0; - if (HWGROUP(drive)->handler != NULL) /* paranoia check */ - BUG(); - ide_set_handler(drive, &ide_dma_intr, WAIT_CMD, NULL); - /* - * FIX ME to use only ACB ide_task_t args Struct - */ -#if 0 - { - ide_task_t *args = rq->special; - command = args->tfRegister[IDE_COMMAND_OFFSET]; - } -#else + command = (lba48) ? WIN_READDMA_EXT : WIN_READDMA; + + if (drive->vdma) + command = (lba48) ? WIN_READ_EXT: WIN_READ; + if (rq->flags & REQ_DRIVE_TASKFILE) { ide_task_t *args = rq->special; command = args->tfRegister[IDE_COMMAND_OFFSET]; } -#endif + /* issue cmd to drive */ - hwif->OUTB(command, IDE_COMMAND_REG); + ide_execute_command(drive, command, &ide_dma_intr, 2*WAIT_CMD, NULL); return pmac_ide_dma_begin(drive); } -static int +static int __pmac pmac_ide_dma_write (ide_drive_t *drive) { - ide_hwif_t *hwif = HWIF(drive); - pmac_ide_hwif_t* pmif = (pmac_ide_hwif_t *)hwif->hwif_data; struct request *rq = HWGROUP(drive)->rq; -// ide_task_t *args = rq->special; - u8 unit = (drive->select.b.unit & 0x01); - u8 ata4; u8 lba48 = (drive->addressing == 1) ? 1 : 0; task_ioreg_t command = WIN_NOP; - if (pmif == NULL) + if (pmac_ide_dma_start(drive, 0)) return 1; - ata4 = (pmif->kind == controller_kl_ata4 || - pmif->kind == controller_kl_ata4_80); - - if (!pmac_ide_build_dmatable(drive, 1)) - return 1; - /* Apple adds 60ns to wrDataSetup on reads */ - if (ata4 && (pmif->timings[unit] & TR_66_UDMA_EN)) { - writel(pmif->timings[unit], - (unsigned *)(IDE_DATA_REG+IDE_TIMING_CONFIG)); - (void)readl((unsigned *)(IDE_DATA_REG + IDE_TIMING_CONFIG)); - } - drive->waiting_for_dma = 1; if (drive->media != ide_disk) return 0; - if (HWGROUP(drive)->handler != NULL) /* paranoia check */ - BUG(); - ide_set_handler(drive, &ide_dma_intr, WAIT_CMD, NULL); - /* - * FIX ME to use only ACB ide_task_t args Struct - */ -#if 0 - { - ide_task_t *args = rq->special; - command = args->tfRegister[IDE_COMMAND_OFFSET]; - } -#else + command = (lba48) ? WIN_WRITEDMA_EXT : WIN_WRITEDMA; + if (drive->vdma) + command = (lba48) ? WIN_WRITE_EXT: WIN_WRITE; + if (rq->flags & REQ_DRIVE_TASKFILE) { ide_task_t *args = rq->special; command = args->tfRegister[IDE_COMMAND_OFFSET]; } -#endif + /* issue cmd to drive */ - hwif->OUTB(command, IDE_COMMAND_REG); + ide_execute_command(drive, command, &ide_dma_intr, 2*WAIT_CMD, NULL); return pmac_ide_dma_begin(drive); } -static int +static int __pmac pmac_ide_dma_count (ide_drive_t *drive) { return HWIF(drive)->ide_dma_begin(drive); } -static int +static int __pmac pmac_ide_dma_begin (ide_drive_t *drive) { pmac_ide_hwif_t* pmif = (pmac_ide_hwif_t *)HWIF(drive)->hwif_data; @@ -1359,7 +1881,7 @@ return 0; } -static int +static int __pmac pmac_ide_dma_end (ide_drive_t *drive) { pmac_ide_hwif_t* pmif = (pmac_ide_hwif_t *)HWIF(drive)->hwif_data; @@ -1378,7 +1900,7 @@ return (dstat & (RUN|DEAD|ACTIVE)) != RUN; } -static int +static int __pmac pmac_ide_dma_test_irq (ide_drive_t *drive) { pmac_ide_hwif_t* pmif = (pmac_ide_hwif_t *)HWIF(drive)->hwif_data; @@ -1418,33 +1940,33 @@ return 1; if (!drive->waiting_for_dma) printk(KERN_WARNING "ide%d, ide_dma_test_irq \ - called while not waiting\n", pmif->index); + called while not waiting\n", HWIF(drive)->index); /* If dbdma didn't execute the STOP command yet, the * active bit is still set */ drive->waiting_for_dma++; if (drive->waiting_for_dma >= DMA_WAIT_TIMEOUT) { printk(KERN_WARNING "ide%d, timeout waiting \ - for dbdma command stop\n", pmif->index); + for dbdma command stop\n", HWIF(drive)->index); return 1; } - udelay(1); + udelay(5); return 0; } -static int +static int __pmac pmac_ide_dma_host_off (ide_drive_t *drive) { return 0; } -static int +static int __pmac pmac_ide_dma_host_on (ide_drive_t *drive) { return 0; } -static int +static int __pmac pmac_ide_dma_lostirq (ide_drive_t *drive) { pmac_ide_hwif_t* pmif = (pmac_ide_hwif_t *)HWIF(drive)->hwif_data; @@ -1461,316 +1983,87 @@ } static void __init -pmac_ide_setup_dma(struct device_node *np, int ix) +pmac_ide_setup_dma(pmac_ide_hwif_t *pmif, ide_hwif_t *hwif) { - struct pmac_ide_hwif *pmif = &pmac_ide[ix]; - - if (request_OF_resource(np, 1, " (mac-io IDE DMA)") == NULL) { - printk(KERN_ERR "ide-pmac(%s): can't request DMA resource !\n", np->name); + /* We won't need pci_dev if we switch to generic consistent + * DMA routines ... + */ + if (hwif->pci_dev == NULL) return; - } - - pmif->dma_regs = - (volatile struct dbdma_regs*)ioremap(np->addrs[1].address, 0x200); - /* * Allocate space for the DBDMA commands. * The +2 is +1 for the stop command and +1 to allow for * aligning the start address to a multiple of 16 bytes. */ pmif->dma_table_cpu = (struct dbdma_cmd*)pci_alloc_consistent( - ide_hwifs[ix].pci_dev, + hwif->pci_dev, (MAX_DCMDS + 2) * sizeof(struct dbdma_cmd), &pmif->dma_table_dma); if (pmif->dma_table_cpu == NULL) { printk(KERN_ERR "%s: unable to allocate DMA command list\n", - ide_hwifs[ix].name); + hwif->name); return; } pmif->sg_table = kmalloc(sizeof(struct scatterlist) * MAX_DCMDS, GFP_KERNEL); if (pmif->sg_table == NULL) { - pci_free_consistent( ide_hwifs[ix].pci_dev, + pci_free_consistent( hwif->pci_dev, (MAX_DCMDS + 2) * sizeof(struct dbdma_cmd), pmif->dma_table_cpu, pmif->dma_table_dma); return; } - ide_hwifs[ix].ide_dma_off = &__ide_dma_off; - ide_hwifs[ix].ide_dma_off_quietly = &__ide_dma_off_quietly; - ide_hwifs[ix].ide_dma_on = &__ide_dma_on; - ide_hwifs[ix].ide_dma_check = &pmac_ide_dma_check; - ide_hwifs[ix].ide_dma_read = &pmac_ide_dma_read; - ide_hwifs[ix].ide_dma_write = &pmac_ide_dma_write; - ide_hwifs[ix].ide_dma_count = &pmac_ide_dma_count; - ide_hwifs[ix].ide_dma_begin = &pmac_ide_dma_begin; - ide_hwifs[ix].ide_dma_end = &pmac_ide_dma_end; - ide_hwifs[ix].ide_dma_test_irq = &pmac_ide_dma_test_irq; - ide_hwifs[ix].ide_dma_host_off = &pmac_ide_dma_host_off; - ide_hwifs[ix].ide_dma_host_on = &pmac_ide_dma_host_on; - ide_hwifs[ix].ide_dma_good_drive = &__ide_dma_good_drive; - ide_hwifs[ix].ide_dma_bad_drive = &__ide_dma_bad_drive; - ide_hwifs[ix].ide_dma_verbose = &__ide_dma_verbose; - ide_hwifs[ix].ide_dma_timeout = &__ide_dma_timeout; - ide_hwifs[ix].ide_dma_retune = &__ide_dma_retune; - ide_hwifs[ix].ide_dma_lostirq = &pmac_ide_dma_lostirq; - ide_hwifs[ix].ide_dma_queued_on = &__ide_dma_queued_on; - ide_hwifs[ix].ide_dma_queued_off = &__ide_dma_queued_off; + hwif->ide_dma_off = &__ide_dma_off; + hwif->ide_dma_off_quietly = &__ide_dma_off_quietly; + hwif->ide_dma_on = &__ide_dma_on; + hwif->ide_dma_check = &pmac_ide_dma_check; + hwif->ide_dma_read = &pmac_ide_dma_read; + hwif->ide_dma_write = &pmac_ide_dma_write; + hwif->ide_dma_count = &pmac_ide_dma_count; + hwif->ide_dma_begin = &pmac_ide_dma_begin; + hwif->ide_dma_end = &pmac_ide_dma_end; + hwif->ide_dma_test_irq = &pmac_ide_dma_test_irq; + hwif->ide_dma_host_off = &pmac_ide_dma_host_off; + hwif->ide_dma_host_on = &pmac_ide_dma_host_on; + hwif->ide_dma_good_drive = &__ide_dma_good_drive; + hwif->ide_dma_bad_drive = &__ide_dma_bad_drive; + hwif->ide_dma_verbose = &__ide_dma_verbose; + hwif->ide_dma_timeout = &__ide_dma_timeout; + hwif->ide_dma_retune = &__ide_dma_retune; + hwif->ide_dma_lostirq = &pmac_ide_dma_lostirq; + hwif->ide_dma_queued_on = &__ide_dma_queued_on; + hwif->ide_dma_queued_off = &__ide_dma_queued_off; +#ifdef CONFIG_BLK_DEV_IDE_TCQ + hwif->ide_dma_queued_read = __ide_dma_queued_read; + hwif->ide_dma_queued_write = __ide_dma_queued_write; + hwif->ide_dma_queued_start = __ide_dma_queued_start; +#endif #ifdef CONFIG_BLK_DEV_IDEDMA_PMAC_AUTO if (!noautodma) - ide_hwifs[ix].autodma = 1; + hwif->autodma = 1; #endif - ide_hwifs[ix].drives[0].autodma = ide_hwifs[ix].autodma; - ide_hwifs[ix].drives[1].autodma = ide_hwifs[ix].autodma; -} - -#endif /* CONFIG_BLK_DEV_IDEDMA_PMAC */ - -static void __pmac -idepmac_sleep_device(ide_drive_t *drive, unsigned base) -{ - ide_hwif_t *hwif = HWIF(drive); - int j; - - /* FIXME: We only handle the master IDE disk, we shoud - * try to fix CD-ROMs here - */ - switch (drive->media) { - case ide_disk: - /* Spin down the drive */ - hwif->OUTB(drive->select.all, base+0x60); - (void) hwif->INB(base+0x60); - udelay(100); - hwif->OUTB(0x0, base+0x30); - hwif->OUTB(0x0, base+0x20); - hwif->OUTB(0x0, base+0x40); - hwif->OUTB(0x0, base+0x50); - hwif->OUTB(0xe0, base+0x70); - hwif->OUTB(0x2, base+0x160); - for (j = 0; j < 10; j++) { - u8 status; - mdelay(100); - status = hwif->INB(base+0x70); - if (!(status & BUSY_STAT) && (status & DRQ_STAT)) - break; - } - break; - case ide_cdrom: - // todo - break; - case ide_floppy: - // todo - break; - } -} - -#ifdef CONFIG_PMAC_PBOOK -static void __pmac -idepmac_wake_device(ide_drive_t *drive, int used_dma) -{ - /* We force the IDE subdriver to check for a media change - * This must be done first or we may lost the condition - * - * Problem: This can schedule. I moved the block device - * wakeup almost late by priority because of that. - */ - //if (DRIVER(drive)) - // check_disk_change(MKDEV(drive->disk->major, drive->disk->first_minor)); - -#ifdef CONFIG_BLK_DEV_IDEDMA_PMAC - /* We re-enable DMA on the drive if it was active. */ - /* This doesn't work with the CD-ROM in the media-bay, probably - * because of a pending unit attention. The problem if that if I - * clear the error, the filesystem dies. - */ - if (used_dma && !ide_spin_wait_hwgroup(drive)) { - /* Lock HW group */ - HWGROUP(drive)->busy = 1; - pmac_ide_dma_check(drive); - HWGROUP(drive)->busy = 0; - if (!list_empty(&drive->queue.queue_head)) - ide_do_request(HWGROUP(drive), 0); - spin_unlock_irq(&ide_lock); - } -#endif /* CONFIG_BLK_DEV_IDEDMA_PMAC */ -} - -static void __pmac -idepmac_sleep_interface(pmac_ide_hwif_t *pmif, unsigned base, int mediabay) -{ - struct device_node* np = pmif->node; - - /* We clear the timings */ - pmif->timings[0] = 0; - pmif->timings[1] = 0; - - /* The media bay will handle itself just fine */ - if (mediabay) - return; - - /* Disable the bus */ - ppc_md.feature_call(PMAC_FTR_IDE_ENABLE, np, pmif->aapl_bus_id, 0); -} + hwif->drives[0].autodma = hwif->autodma; + hwif->drives[1].autodma = hwif->autodma; -static void __pmac -idepmac_wake_interface(pmac_ide_hwif_t *pmif, unsigned long base, int mediabay) -{ - struct device_node* np = pmif->node; - - if (!mediabay) { - /* Revive IDE disk and controller */ - ppc_md.feature_call(PMAC_FTR_IDE_RESET, np, pmif->aapl_bus_id, 1); - ppc_md.feature_call(PMAC_FTR_IDE_ENABLE, np, pmif->aapl_bus_id, 1); - mdelay(10); - ppc_md.feature_call(PMAC_FTR_IDE_RESET, np, pmif->aapl_bus_id, 0); - } -} - -static void -idepmac_sleep_drive(ide_drive_t *drive, unsigned long base) -{ - int unlock = 0; - - /* Wait for HW group to complete operations */ - if (ide_spin_wait_hwgroup(drive)) { - // What can we do here ? Wake drive we had already - // put to sleep and return an error ? - } else { - unlock = 1; - /* Lock HW group */ - HWGROUP(drive)->busy = 1; - /* Stop the device */ - idepmac_sleep_device(drive, base); - } - if (unlock) - spin_unlock_irq(&ide_lock); -} - -static void -idepmac_wake_drive(ide_drive_t *drive, unsigned long base) -{ - ide_hwif_t *hwif = HWIF(drive); - unsigned long flags; - int j; - - /* Reset timings */ - pmac_ide_selectproc(drive); - mdelay(10); - - /* Wait up to 20 seconds for the drive to be ready */ - for (j = 0; j < 200; j++) { - u8 status = 0; - mdelay(100); - hwif->OUTB(drive->select.all, base + 0x60); - if ((hwif->INB(base + 0x60)) != drive->select.all) - continue; - status = hwif->INB(base + 0x70); - if (!(status & BUSY_STAT)) + hwif->atapi_dma = 1; + switch(pmif->kind) { + case controller_un_ata6: + hwif->ultra_mask = pmif->cable_80 ? 0x3f : 0x07; + hwif->mwdma_mask = 0x07; + hwif->swdma_mask = 0x00; break; - } - - /* We resume processing on the HW group */ - spin_lock_irqsave(&ide_lock, flags); - HWGROUP(drive)->busy = 0; - if (!list_empty(&drive->queue.queue_head)) - ide_do_request(HWGROUP(drive), 0); - spin_unlock_irqrestore(&ide_lock, flags); + case controller_kl_ata4: + hwif->ultra_mask = pmif->cable_80 ? 0x1f : 0x07; + hwif->mwdma_mask = 0x07; + hwif->swdma_mask = 0x00; + break; + default: + hwif->ultra_mask = 0x00; + hwif->mwdma_mask = 0x07; + hwif->swdma_mask = 0x00; + break; + } } -/* Note: We support only master drives for now. This will have to be - * improved if we want to handle sleep on the iMacDV where the CD-ROM - * is a slave - */ -static int __pmac -idepmac_notify_sleep(struct pmu_sleep_notifier *self, int when) -{ - int i, ret; - unsigned long base; - int big_delay; - - switch (when) { - case PBOOK_SLEEP_REQUEST: - break; - case PBOOK_SLEEP_REJECT: - break; - case PBOOK_SLEEP_NOW: - for (i = 0; i < pmac_ide_count; ++i) { - ide_hwif_t *hwif; - int dn; - - if ((base = pmac_ide[i].regbase) == 0) - continue; - - hwif = &ide_hwifs[i]; - for (dn=0; dndrives[dn].present) - continue; - idepmac_sleep_drive(&hwif->drives[dn], base); - } - /* Disable irq during sleep */ - disable_irq(pmac_ide[i].irq); - - /* Check if this is a media bay with an IDE device or not - * a media bay. - */ - ret = check_media_bay_by_base(base, MB_CD); - if ((ret == 0) || (ret == -ENODEV)) - idepmac_sleep_interface(&pmac_ide[i], base, (ret == 0)); - } - break; - case PBOOK_WAKE: - big_delay = 0; - for (i = 0; i < pmac_ide_count; ++i) { - - if ((base = pmac_ide[i].regbase) == 0) - continue; - - /* Make sure we have sane timings */ - sanitize_timings(&pmac_ide[i]); - - /* Check if this is a media bay with an IDE device or not - * a media bay - */ - ret = check_media_bay_by_base(base, MB_CD); - if ((ret == 0) || (ret == -ENODEV)) { - idepmac_wake_interface(&pmac_ide[i], base, (ret == 0)); - big_delay = 1; - } - - } - /* Let hardware get up to speed */ - if (big_delay) - mdelay(IDE_WAKEUP_DELAY_MS); - - for (i = 0; i < pmac_ide_count; ++i) { - ide_hwif_t *hwif; - int used_dma, dn; - int irq_on = 0; - - if ((base = pmac_ide[i].regbase) == 0) - continue; - - hwif = &ide_hwifs[i]; - for (dn=0; dndrives[dn]; - if (!drive->present) - continue; - /* We don't have re-configured DMA yet */ - used_dma = drive->using_dma; - drive->using_dma = 0; - idepmac_wake_drive(drive, base); - if (!irq_on) { - enable_irq(pmac_ide[i].irq); - irq_on = 1; - } - idepmac_wake_device(drive, used_dma); - } - if (!irq_on) - enable_irq(pmac_ide[i].irq); - } - break; - } - return PBOOK_SLEEP_OK; -} -#endif /* CONFIG_PMAC_PBOOK */ +#endif /* CONFIG_BLK_DEV_IDEDMA_PMAC */ diff -Nru a/drivers/ieee1394/csr.c b/drivers/ieee1394/csr.c --- a/drivers/ieee1394/csr.c Tue Sep 2 19:58:14 2003 +++ b/drivers/ieee1394/csr.c Tue Sep 2 19:58:14 2003 @@ -21,6 +21,7 @@ #include #include #include +#include #include "ieee1394_types.h" #include "hosts.h" diff -Nru a/drivers/ieee1394/eth1394.c b/drivers/ieee1394/eth1394.c --- a/drivers/ieee1394/eth1394.c Tue Sep 2 19:58:17 2003 +++ b/drivers/ieee1394/eth1394.c Tue Sep 2 19:58:17 2003 @@ -89,7 +89,7 @@ #define TRACE() printk(KERN_ERR "%s:%s[%d] ---- TRACE\n", driver_name, __FUNCTION__, __LINE__) static char version[] __devinitdata = - "$Rev: 1020 $ Ben Collins "; + "$Rev: 1043 $ Ben Collins "; struct fragment_info { struct list_head list; @@ -1349,21 +1349,20 @@ ptask->dest_node, ptask->addr, ptask->skb->data, tx_len)) { - goto fail; + free_hpsb_packet(packet); + return -1; } ptask->packet = packet; hpsb_set_packet_complete_task(ptask->packet, ether1394_complete_cb, ptask); - if (hpsb_send_packet(packet)) - return 0; - -fail: - if (packet) + if (!hpsb_send_packet(packet)) { ether1394_free_packet(packet); + return -1; + } - return -1; + return 0; } @@ -1600,7 +1599,7 @@ case ETHTOOL_GDRVINFO: { struct ethtool_drvinfo info = { ETHTOOL_GDRVINFO }; strcpy (info.driver, driver_name); - strcpy (info.version, "$Rev: 1020 $"); + strcpy (info.version, "$Rev: 1043 $"); /* FIXME XXX provide sane businfo */ strcpy (info.bus_info, "ieee1394"); if (copy_to_user (useraddr, &info, sizeof (info))) diff -Nru a/drivers/ieee1394/ieee1394_core.c b/drivers/ieee1394/ieee1394_core.c --- a/drivers/ieee1394/ieee1394_core.c Tue Sep 2 19:58:14 2003 +++ b/drivers/ieee1394/ieee1394_core.c Tue Sep 2 19:58:14 2003 @@ -1124,7 +1124,7 @@ to get the index of the ieee1394_driver we want */ - blocknum = (minor(inode->i_rdev) >> 4) & 0xF; + blocknum = (iminor(inode) >> 4) & 0xF; /* look up the driver */ @@ -1237,6 +1237,7 @@ EXPORT_SYMBOL(hpsb_free_tlabel); EXPORT_SYMBOL(hpsb_make_readpacket); EXPORT_SYMBOL(hpsb_make_writepacket); +EXPORT_SYMBOL(hpsb_make_streampacket); EXPORT_SYMBOL(hpsb_make_lockpacket); EXPORT_SYMBOL(hpsb_make_lock64packet); EXPORT_SYMBOL(hpsb_make_phypacket); diff -Nru a/drivers/ieee1394/ieee1394_core.h b/drivers/ieee1394/ieee1394_core.h --- a/drivers/ieee1394/ieee1394_core.h Tue Sep 2 19:58:13 2003 +++ b/drivers/ieee1394/ieee1394_core.h Tue Sep 2 19:58:13 2003 @@ -202,7 +202,7 @@ /* return the index (within a minor number block) of a file */ static inline unsigned char ieee1394_file_to_instance(struct file *file) { - unsigned char minor = minor(file->f_dentry->d_inode->i_rdev); + unsigned char minor = iminor(file->f_dentry->d_inode); /* return lower 4 bits */ return minor & 0xF; diff -Nru a/drivers/ieee1394/ieee1394_transactions.c b/drivers/ieee1394/ieee1394_transactions.c --- a/drivers/ieee1394/ieee1394_transactions.c Tue Sep 2 19:58:14 2003 +++ b/drivers/ieee1394/ieee1394_transactions.c Tue Sep 2 19:58:14 2003 @@ -104,7 +104,7 @@ int channel, int tag, int sync) { packet->header[0] = (length << 16) | (tag << 14) | (channel << 8) - | (TCODE_STREAM_DATA << 4) | sync; + | (TCODE_STREAM_DATA << 4) | sync; packet->header_size = 4; packet->data_size = length; @@ -317,6 +317,35 @@ return packet; } +struct hpsb_packet *hpsb_make_streampacket(struct hpsb_host *host, u8 *buffer, int length, + int channel, int tag, int sync) +{ + struct hpsb_packet *packet; + + if (length == 0) + return NULL; + + packet = alloc_hpsb_packet(length + (length % 4 ? 4 - (length % 4) : 0)); + if (!packet) + return NULL; + + if (length % 4) { /* zero padding bytes */ + packet->data[length >> 2] = 0; + } + packet->host = host; + + if (hpsb_get_tlabel(packet)) { + free_hpsb_packet(packet); + return NULL; + } + + fill_async_stream_packet(packet, length, channel, tag, sync); + if (buffer) + memcpy(packet->data, buffer, length); + + return packet; +} + struct hpsb_packet *hpsb_make_lockpacket(struct hpsb_host *host, nodeid_t node, u64 addr, int extcode, quadlet_t *data, quadlet_t arg) @@ -580,25 +609,18 @@ u16 specifier_id_hi = (specifier_id & 0x00ffff00) >> 8; u8 specifier_id_lo = specifier_id & 0xff; - HPSB_VERBOSE("Send GASP: channel = %d, length = %d", channel, length); + HPSB_VERBOSE("Send GASP: channel = %d, length = %Zd", channel, length); length += 8; - - packet = alloc_hpsb_packet(length + (length % 4 ? 4 - (length % 4) : 0)); + + packet = hpsb_make_streampacket(host, NULL, length, channel, 3, 0); if (!packet) return -ENOMEM; - if (length % 4) { - packet->data[length / 4] = 0; - } - - packet->host = host; - fill_async_stream_packet(packet, length, channel, 3, 0); - packet->data[0] = cpu_to_be32((host->node_id << 16) | specifier_id_hi); packet->data[1] = cpu_to_be32((specifier_id_lo << 24) | (version & 0x00ffffff)); - memcpy(&(packet->data[2]), buffer, length - 4); + memcpy(&(packet->data[2]), buffer, length - 8); packet->generation = generation; diff -Nru a/drivers/ieee1394/ieee1394_transactions.h b/drivers/ieee1394/ieee1394_transactions.h --- a/drivers/ieee1394/ieee1394_transactions.h Tue Sep 2 19:58:14 2003 +++ b/drivers/ieee1394/ieee1394_transactions.h Tue Sep 2 19:58:14 2003 @@ -25,6 +25,8 @@ int tag, int sync); struct hpsb_packet *hpsb_make_writepacket (struct hpsb_host *host, nodeid_t node, u64 addr, quadlet_t *buffer, size_t length); +struct hpsb_packet *hpsb_make_streampacket(struct hpsb_host *host, u8 *buffer, + int length, int channel, int tag, int sync); /* * hpsb_packet_success - Make sense of the ack and reply codes and diff -Nru a/drivers/ieee1394/nodemgr.c b/drivers/ieee1394/nodemgr.c --- a/drivers/ieee1394/nodemgr.c Tue Sep 2 19:58:16 2003 +++ b/drivers/ieee1394/nodemgr.c Tue Sep 2 19:58:16 2003 @@ -1304,12 +1304,14 @@ * unregister all the unit directories. */ nodemgr_remove_node_uds(ne); + /* With all the ud's gone, mark the generation current, + * this way the probe will succeed. */ + ne->generation = generation; + /* This will re-register our unitdir's */ nodemgr_process_config_rom (hi, ne, busoptions); - } - - /* Since that's done, we can declare this record current */ - ne->generation = generation; + } else + ne->generation = generation; /* Update unit_dirs with attached drivers */ bus_for_each_dev(&ieee1394_bus_type, NULL, ne, diff -Nru a/drivers/ieee1394/ohci1394.c b/drivers/ieee1394/ohci1394.c --- a/drivers/ieee1394/ohci1394.c Tue Sep 2 19:58:18 2003 +++ b/drivers/ieee1394/ohci1394.c Tue Sep 2 19:58:18 2003 @@ -161,7 +161,7 @@ printk(level "%s_%d: " fmt "\n" , OHCI1394_DRIVER_NAME, card , ## args) static char version[] __devinitdata = - "$Rev: 1023 $ Ben Collins "; + "$Rev: 1045 $ Ben Collins "; /* Module Parameters */ static int phys_dma = 1; @@ -1451,7 +1451,7 @@ if (sync != -1) { /* set sync flag on first DMA descriptor */ struct dma_cmd *cmd = &recv->block[recv->block_dma]; - cmd->control |= DMA_CTL_WAIT; + cmd->control |= cpu_to_le32(DMA_CTL_WAIT); /* match sync field */ contextMatch |= (sync&0xf)<<8; @@ -1675,10 +1675,10 @@ struct dma_cmd *im = &recv->block[recv->block_dma]; /* check the DMA descriptor for new writes to xferStatus */ - u16 xferstatus = im->status >> 16; + u16 xferstatus = le32_to_cpu(im->status) >> 16; /* rescount is the number of bytes *remaining to be written* in the block */ - u16 rescount = im->status & 0xFFFF; + u16 rescount = le32_to_cpu(im->status) & 0xFFFF; unsigned char event = xferstatus & 0x1F; diff -Nru a/drivers/ieee1394/pcilynx.c b/drivers/ieee1394/pcilynx.c --- a/drivers/ieee1394/pcilynx.c Tue Sep 2 19:58:15 2003 +++ b/drivers/ieee1394/pcilynx.c Tue Sep 2 19:58:15 2003 @@ -875,7 +875,7 @@ static int mem_open(struct inode *inode, struct file *file) { - int cid = minor(inode->i_rdev); + int cid = iminor(inode); enum { t_rom, t_aux, t_ram } type; struct memdata *md; diff -Nru a/drivers/ieee1394/raw1394.c b/drivers/ieee1394/raw1394.c --- a/drivers/ieee1394/raw1394.c Tue Sep 2 19:58:12 2003 +++ b/drivers/ieee1394/raw1394.c Tue Sep 2 19:58:12 2003 @@ -38,6 +38,7 @@ #include #include #include +#include #include #include #include @@ -180,6 +181,7 @@ if ((req->req.type == RAW1394_REQ_ASYNC_READ) || (req->req.type == RAW1394_REQ_ASYNC_WRITE) || + (req->req.type == RAW1394_REQ_ASYNC_STREAM) || (req->req.type == RAW1394_REQ_LOCK) || (req->req.type == RAW1394_REQ_LOCK64)) hpsb_free_tlabel(packet); @@ -689,6 +691,21 @@ req->req.length = 0; break; + case RAW1394_REQ_ASYNC_STREAM: + DBGMSG("stream_request called"); + + packet = hpsb_make_streampacket(fi->host, NULL, req->req.length, node & 0x3f/*channel*/, + (req->req.misc >> 16) & 0x3, req->req.misc & 0xf); + if (!packet) + return -ENOMEM; + + if (copy_from_user(packet->data, int2ptr(req->req.sendb), + req->req.length)) + req->req.error = RAW1394_ERROR_MEMFAULT; + + req->req.length = 0; + break; + case RAW1394_REQ_LOCK: DBGMSG("lock_request called"); if ((req->req.misc == EXTCODE_FETCH_ADD) @@ -892,7 +909,7 @@ struct arm_request_response *arm_req_resp = NULL; DBGMSG("arm_read called by node: %X" - "addr: %4.4x %8.8x length: %u", nodeid, + "addr: %4.4x %8.8x length: %Zu", nodeid, (u16) ((addr >>32) & 0xFFFF), (u32) (addr & 0xFFFFFFFF), length); spin_lock(&host_info_lock); @@ -1028,7 +1045,7 @@ struct arm_request_response *arm_req_resp = NULL; DBGMSG("arm_write called by node: %X" - "addr: %4.4x %8.8x length: %u", nodeid, + "addr: %4.4x %8.8x length: %Zu", nodeid, (u16) ((addr >>32) & 0xFFFF), (u32) (addr & 0xFFFFFFFF), length); spin_lock(&host_info_lock); @@ -1566,8 +1583,8 @@ req->req.length, ((req->req.misc >> 8) & 0xFF), (req->req.misc & 0xFF),((req->req.misc >> 16) & 0xFFFF)); /* check addressrange */ - if ((((req->req.address) & ~((u64)0xFFFFFFFFFFFFLL)) != 0) || - (((req->req.address + req->req.length) & ~((u64)0xFFFFFFFFFFFFLL)) != 0)) { + if ((((req->req.address) & ~(0xFFFFFFFFFFFFULL)) != 0) || + (((req->req.address + req->req.length) & ~(0xFFFFFFFFFFFFULL)) != 0)) { req->req.length = 0; return (-EINVAL); } @@ -1578,7 +1595,7 @@ return (-ENOMEM); } /* allocation of addr_space_buffer */ - addr->addr_space_buffer = (u8 *)kmalloc(req->req.length,SLAB_KERNEL); + addr->addr_space_buffer = (u8 *)vmalloc(req->req.length); if (!(addr->addr_space_buffer)) { kfree(addr); req->req.length = 0; @@ -1592,7 +1609,7 @@ /* init: user -> kernel */ if (copy_from_user(addr->addr_space_buffer,int2ptr(req->req.sendb), req->req.length)) { - kfree(addr->addr_space_buffer); + vfree(addr->addr_space_buffer); kfree(addr); return (-EFAULT); } @@ -1633,7 +1650,7 @@ } if (same_host) { /* addressrange occupied by same host */ - kfree(addr->addr_space_buffer); + vfree(addr->addr_space_buffer); kfree(addr); spin_unlock_irqrestore(&host_info_lock, flags); return (-EALREADY); @@ -1668,7 +1685,7 @@ int2ptr(&addr->start),sizeof(u64))) { printk(KERN_ERR "raw1394: arm_register failed " " address-range-entry is invalid -> EFAULT !!!\n"); - kfree(addr->addr_space_buffer); + vfree(addr->addr_space_buffer); kfree(addr); spin_unlock_irqrestore(&host_info_lock, flags); return (-EFAULT); @@ -1686,7 +1703,7 @@ list_add_tail(&addr->addr_list, &fi->addr_list); } else { DBGMSG("arm_register failed errno: %d \n",retval); - kfree(addr->addr_space_buffer); + vfree(addr->addr_space_buffer); kfree(addr); spin_unlock_irqrestore(&host_info_lock, flags); return (-EALREADY); @@ -1760,7 +1777,7 @@ if (another_host) { DBGMSG("delete entry from list -> success"); list_del(&addr->addr_list); - kfree(addr->addr_space_buffer); + vfree(addr->addr_space_buffer); kfree(addr); free_pending_request(req); /* immediate success or fail */ spin_unlock_irqrestore(&host_info_lock, flags); @@ -1775,7 +1792,7 @@ DBGMSG("delete entry from list -> success"); list_del(&addr->addr_list); spin_unlock_irqrestore(&host_info_lock, flags); - kfree(addr->addr_space_buffer); + vfree(addr->addr_space_buffer); kfree(addr); free_pending_request(req); /* immediate success or fail */ return sizeof(struct raw1394_request); @@ -2440,7 +2457,7 @@ } DBGMSG("raw1394_release: delete addr_entry from list"); list_del(&addr->addr_list); - kfree(addr->addr_space_buffer); + vfree(addr->addr_space_buffer); kfree(addr); } /* while */ spin_unlock_irq(&host_info_lock); diff -Nru a/drivers/ieee1394/raw1394.h b/drivers/ieee1394/raw1394.h --- a/drivers/ieee1394/raw1394.h Tue Sep 2 19:58:12 2003 +++ b/drivers/ieee1394/raw1394.h Tue Sep 2 19:58:12 2003 @@ -19,6 +19,7 @@ #define RAW1394_REQ_LOCK64 103 #define RAW1394_REQ_ISO_SEND 104 #define RAW1394_REQ_ASYNC_SEND 105 +#define RAW1394_REQ_ASYNC_STREAM 106 #define RAW1394_REQ_ISO_LISTEN 200 #define RAW1394_REQ_FCP_LISTEN 201 diff -Nru a/drivers/ieee1394/sbp2.c b/drivers/ieee1394/sbp2.c --- a/drivers/ieee1394/sbp2.c Tue Sep 2 19:58:13 2003 +++ b/drivers/ieee1394/sbp2.c Tue Sep 2 19:58:13 2003 @@ -80,7 +80,7 @@ #include "sbp2.h" static char version[] __devinitdata = - "$Rev: 1018 $ Ben Collins "; + "$Rev: 1034 $ Ben Collins "; /* * Module load parameter definitions @@ -1002,9 +1002,8 @@ sbp2scsi_complete_all_commands(scsi_id, DID_NO_CONNECT); /* Remove it from the scsi layer now */ - if (sdev) { + if (sdev) scsi_remove_device(sdev); - } sbp2util_remove_command_orb_pool(scsi_id); diff -Nru a/drivers/input/evdev.c b/drivers/input/evdev.c --- a/drivers/input/evdev.c Tue Sep 2 19:58:17 2003 +++ b/drivers/input/evdev.c Tue Sep 2 19:58:17 2003 @@ -122,7 +122,7 @@ static int evdev_open(struct inode * inode, struct file * file) { struct evdev_list *list; - int i = minor(inode->i_rdev) - EVDEV_MINOR_BASE; + int i = iminor(inode) - EVDEV_MINOR_BASE; int accept_err; if (i >= EVDEV_MINORS || !evdev_table[i]) @@ -305,6 +305,7 @@ case EV_KEY: bits = dev->keybit; len = KEY_MAX; break; case EV_REL: bits = dev->relbit; len = REL_MAX; break; case EV_ABS: bits = dev->absbit; len = ABS_MAX; break; + case EV_MSC: bits = dev->mscbit; len = MSC_MAX; break; case EV_LED: bits = dev->ledbit; len = LED_MAX; break; case EV_SND: bits = dev->sndbit; len = SND_MAX; break; case EV_FF: bits = dev->ffbit; len = FF_MAX; break; diff -Nru a/drivers/input/input.c b/drivers/input/input.c --- a/drivers/input/input.c Tue Sep 2 19:58:16 2003 +++ b/drivers/input/input.c Tue Sep 2 19:58:16 2003 @@ -280,7 +280,7 @@ if (id->id.product != dev->id.product) continue; - if (id->flags & INPUT_DEVICE_ID_MATCH_BUS) + if (id->flags & INPUT_DEVICE_ID_MATCH_VERSION) if (id->id.version != dev->id.version) continue; @@ -527,7 +527,7 @@ static int input_open_file(struct inode *inode, struct file *file) { - struct input_handler *handler = input_table[minor(inode->i_rdev) >> 5]; + struct input_handler *handler = input_table[iminor(inode) >> 5]; struct file_operations *old_fops, *new_fops = NULL; int err; diff -Nru a/drivers/input/joydev.c b/drivers/input/joydev.c --- a/drivers/input/joydev.c Tue Sep 2 19:58:16 2003 +++ b/drivers/input/joydev.c Tue Sep 2 19:58:16 2003 @@ -170,7 +170,7 @@ static int joydev_open(struct inode *inode, struct file *file) { struct joydev_list *list; - int i = minor(inode->i_rdev) - JOYDEV_MINOR_BASE; + int i = iminor(inode) - JOYDEV_MINOR_BASE; if (i >= JOYDEV_MINORS || !joydev_table[i]) return -ENODEV; diff -Nru a/drivers/input/mousedev.c b/drivers/input/mousedev.c --- a/drivers/input/mousedev.c Tue Sep 2 19:58:19 2003 +++ b/drivers/input/mousedev.c Tue Sep 2 19:58:19 2003 @@ -228,11 +228,11 @@ int i; #ifdef CONFIG_INPUT_MOUSEDEV_PSAUX - if (major(inode->i_rdev) == MISC_MAJOR) + if (imajor(inode) == MISC_MAJOR) i = MOUSEDEV_MIX; else #endif - i = minor(inode->i_rdev) - MOUSEDEV_MINOR_BASE; + i = iminor(inode) - MOUSEDEV_MINOR_BASE; if (i >= MOUSEDEV_MINORS || !mousedev_table[i]) return -ENODEV; diff -Nru a/drivers/input/serio/i8042.c b/drivers/input/serio/i8042.c --- a/drivers/input/serio/i8042.c Tue Sep 2 19:58:13 2003 +++ b/drivers/input/serio/i8042.c Tue Sep 2 19:58:13 2003 @@ -410,6 +410,7 @@ /* work around hardware that doubles key releases */ if (index == i8042_last_release) { dbg("i8042 skipped double release (%d)\n", index); + i8042_last_e0 = 0; continue; } if (index == 0xaa || index == 0xb6) diff -Nru a/drivers/input/serio/sa1111ps2.c b/drivers/input/serio/sa1111ps2.c --- a/drivers/input/serio/sa1111ps2.c Tue Sep 2 19:58:15 2003 +++ b/drivers/input/serio/sa1111ps2.c Tue Sep 2 19:58:15 2003 @@ -62,9 +62,9 @@ serio_interrupt(&ps2if->io, scancode, flag, regs); - status = sa1111_readl(ps2if->base + SA1111_PS2STAT); + status = sa1111_readl(ps2if->base + SA1111_PS2STAT); - handled = IRQ_HANDLED; + handled = IRQ_HANDLED; } return handled; @@ -232,9 +232,8 @@ /* * Add one device to this driver. */ -static int ps2_probe(struct device *dev) +static int ps2_probe(struct sa1111_dev *dev) { - struct sa1111_dev *sadev = SA1111_DEV(dev); struct ps2if *ps2if; int ret; @@ -249,20 +248,20 @@ ps2if->io.write = ps2_write; ps2if->io.open = ps2_open; ps2if->io.close = ps2_close; - ps2if->io.name = dev->name; - ps2if->io.phys = dev->bus_id; + ps2if->io.name = dev->dev.bus_id; + ps2if->io.phys = dev->dev.bus_id; ps2if->io.driver = ps2if; - ps2if->dev = sadev; - dev->driver_data = ps2if; + ps2if->dev = dev; + sa1111_set_drvdata(dev, ps2if); spin_lock_init(&ps2if->lock); /* * Request the physical region for this PS2 port. */ - if (!request_mem_region(sadev->res.start, - sadev->res.end - sadev->res.start + 1, - SA1111_DRIVER_NAME(sadev))) { + if (!request_mem_region(dev->res.start, + dev->res.end - dev->res.start + 1, + SA1111_DRIVER_NAME(dev))) { ret = -EBUSY; goto free; } @@ -270,7 +269,7 @@ /* * Our parent device has already mapped the region. */ - ps2if->base = (unsigned long)sadev->mapbase; + ps2if->base = (unsigned long)dev->mapbase; sa1111_enable_device(ps2if->dev); @@ -301,10 +300,10 @@ out: sa1111_disable_device(ps2if->dev); - release_mem_region(sadev->res.start, - sadev->res.end - sadev->res.start + 1); + release_mem_region(dev->res.start, + dev->res.end - dev->res.start + 1); free: - dev->driver_data = NULL; + sa1111_set_drvdata(dev, NULL); kfree(ps2if); return ret; } @@ -312,31 +311,17 @@ /* * Remove one device from this driver. */ -static int ps2_remove(struct device *dev) +static int ps2_remove(struct sa1111_dev *dev) { - struct ps2if *ps2if = dev->driver_data; - struct sa1111_dev *sadev = SA1111_DEV(dev); + struct ps2if *ps2if = sa1111_get_drvdata(dev); serio_unregister_port(&ps2if->io); - release_mem_region(sadev->res.start, - sadev->res.end - sadev->res.start + 1); - kfree(ps2if); - - dev->driver_data = NULL; - - return 0; -} + release_mem_region(dev->res.start, + dev->res.end - dev->res.start + 1); + sa1111_set_drvdata(dev, NULL); -/* - * We should probably do something here, but what? - */ -static int ps2_suspend(struct device *dev, u32 state, u32 level) -{ - return 0; -} + kfree(ps2if); -static int ps2_resume(struct device *dev, u32 level) -{ return 0; } @@ -345,24 +330,21 @@ */ static struct sa1111_driver ps2_driver = { .drv = { - .name = "sa1111-ps2", - .bus = &sa1111_bus_type, - .probe = ps2_probe, - .remove = ps2_remove, - .suspend = ps2_suspend, - .resume = ps2_resume, + .name = "sa1111-ps2", }, - .devid = SA1111_DEVID_PS2, + .devid = SA1111_DEVID_PS2, + .probe = ps2_probe, + .remove = ps2_remove, }; static int __init ps2_init(void) { - return driver_register(&ps2_driver.drv); + return sa1111_driver_register(&ps2_driver); } static void __exit ps2_exit(void) { - driver_unregister(&ps2_driver.drv); + sa1111_driver_unregister(&ps2_driver); } module_init(ps2_init); diff -Nru a/drivers/input/tsdev.c b/drivers/input/tsdev.c --- a/drivers/input/tsdev.c Tue Sep 2 19:58:19 2003 +++ b/drivers/input/tsdev.c Tue Sep 2 19:58:19 2003 @@ -96,7 +96,7 @@ static int tsdev_open(struct inode *inode, struct file *file) { - int i = minor(inode->i_rdev) - TSDEV_MINOR_BASE; + int i = iminor(inode) - TSDEV_MINOR_BASE; struct tsdev_list *list; if (i >= TSDEV_MINORS || !tsdev_table[i]) diff -Nru a/drivers/isdn/Kconfig b/drivers/isdn/Kconfig --- a/drivers/isdn/Kconfig Tue Sep 2 19:58:19 2003 +++ b/drivers/isdn/Kconfig Tue Sep 2 19:58:19 2003 @@ -22,7 +22,7 @@ menu "Old ISDN4Linux" - depends on NET && ISDN_BOOL + depends on NET && ISDN_BOOL && BROKEN_ON_SMP config ISDN tristate "Old ISDN4Linux (obsolete)" diff -Nru a/drivers/isdn/capi/capi.c b/drivers/isdn/capi/capi.c --- a/drivers/isdn/capi/capi.c Tue Sep 2 19:58:19 2003 +++ b/drivers/isdn/capi/capi.c Tue Sep 2 19:58:19 2003 @@ -964,7 +964,7 @@ { struct capiminor *mp; - if ((mp = capiminor_find(minor(file->f_dentry->d_inode->i_rdev))) == 0) + if ((mp = capiminor_find(iminor(file->f_dentry->d_inode))) == 0) return -ENXIO; if (mp->nccip == 0) return -ENXIO; diff -Nru a/drivers/isdn/hardware/avm/Kconfig b/drivers/isdn/hardware/avm/Kconfig --- a/drivers/isdn/hardware/avm/Kconfig Tue Sep 2 19:58:14 2003 +++ b/drivers/isdn/hardware/avm/Kconfig Tue Sep 2 19:58:14 2003 @@ -12,13 +12,13 @@ config ISDN_DRV_AVMB1_B1ISA tristate "AVM B1 ISA support" - depends on CAPI_AVM && ISDN_CAPI && ISA + depends on CAPI_AVM && ISDN_CAPI && ISA && BROKEN_ON_SMP help Enable support for the ISA version of the AVM B1 card. config ISDN_DRV_AVMB1_B1PCI tristate "AVM B1 PCI support" - depends on CAPI_AVM && ISDN_CAPI && PCI + depends on CAPI_AVM && ISDN_CAPI && PCI && BROKEN_ON_SMP help Enable support for the PCI version of the AVM B1 card. @@ -30,14 +30,14 @@ config ISDN_DRV_AVMB1_T1ISA tristate "AVM T1/T1-B ISA support" - depends on CAPI_AVM && ISDN_CAPI && ISA + depends on CAPI_AVM && ISDN_CAPI && ISA && BROKEN_ON_SMP help Enable support for the AVM T1 T1B card. Note: This is a PRI card and handle 30 B-channels. config ISDN_DRV_AVMB1_B1PCMCIA tristate "AVM B1/M1/M2 PCMCIA support" - depends on CAPI_AVM && ISDN_CAPI + depends on CAPI_AVM && ISDN_CAPI && BROKEN_ON_SMP help Enable support for the PCMCIA version of the AVM B1 card. @@ -50,14 +50,14 @@ config ISDN_DRV_AVMB1_T1PCI tristate "AVM T1/T1-B PCI support" - depends on CAPI_AVM && ISDN_CAPI && PCI + depends on CAPI_AVM && ISDN_CAPI && PCI && BROKEN_ON_SMP help Enable support for the AVM T1 T1B card. Note: This is a PRI card and handle 30 B-channels. config ISDN_DRV_AVMB1_C4 tristate "AVM C4/C2 support" - depends on CAPI_AVM && ISDN_CAPI && PCI + depends on CAPI_AVM && ISDN_CAPI && PCI && BROKEN_ON_SMP help Enable support for the AVM C4/C2 PCI cards. These cards handle 4/2 BRI ISDN lines (8/4 channels). diff -Nru a/drivers/isdn/hardware/eicon/divasi.c b/drivers/isdn/hardware/eicon/divasi.c --- a/drivers/isdn/hardware/eicon/divasi.c Tue Sep 2 19:58:15 2003 +++ b/drivers/isdn/hardware/eicon/divasi.c Tue Sep 2 19:58:15 2003 @@ -432,7 +432,7 @@ static int um_idi_release(struct inode *inode, struct file *file) { - unsigned int adapter_nr = minor(inode->i_rdev); + unsigned int adapter_nr = iminor(inode); int ret = 0; if (!(file->private_data)) { diff -Nru a/drivers/isdn/i4l/Kconfig b/drivers/isdn/i4l/Kconfig --- a/drivers/isdn/i4l/Kconfig Tue Sep 2 19:58:14 2003 +++ b/drivers/isdn/i4l/Kconfig Tue Sep 2 19:58:14 2003 @@ -106,6 +106,7 @@ config ISDN_DIVERSION tristate "Support isdn diversion services" + depends on BROKEN help This option allows you to use some supplementary diversion services in conjunction with the HiSax driver on an EURO/DSS1 diff -Nru a/drivers/isdn/i4l/isdn_common.c b/drivers/isdn/i4l/isdn_common.c --- a/drivers/isdn/i4l/isdn_common.c Tue Sep 2 19:58:15 2003 +++ b/drivers/isdn/i4l/isdn_common.c Tue Sep 2 19:58:15 2003 @@ -1432,7 +1432,7 @@ static int isdn_ctrl_open(struct inode *ino, struct file *file) { - unsigned int minor = minor(ino->i_rdev); + unsigned int minor = iminor(ino); struct isdn_slot *slot = get_slot_by_minor(minor - ISDN_MINOR_CTRL); if (!slot) @@ -1795,7 +1795,7 @@ static int isdn_open(struct inode * inode, struct file * file) { - int minor = minor(inode->i_rdev); + int minor = iminor(inode); int err = -ENODEV; struct file_operations *old_fops, *new_fops = NULL; diff -Nru a/drivers/isdn/i4l/isdn_ppp.c b/drivers/isdn/i4l/isdn_ppp.c --- a/drivers/isdn/i4l/isdn_ppp.c Tue Sep 2 19:58:17 2003 +++ b/drivers/isdn/i4l/isdn_ppp.c Tue Sep 2 19:58:17 2003 @@ -119,7 +119,7 @@ ipppd_open(struct inode *ino, struct file *file) { unsigned long flags; - unsigned int minor = minor(ino->i_rdev) - ISDN_MINOR_PPP; + unsigned int minor = iminor(ino) - ISDN_MINOR_PPP; struct ipppd *ipppd; ipppd = kmalloc(sizeof(*ipppd), GFP_KERNEL); diff -Nru a/drivers/macintosh/adb.c b/drivers/macintosh/adb.c --- a/drivers/macintosh/adb.c Tue Sep 2 19:58:20 2003 +++ b/drivers/macintosh/adb.c Tue Sep 2 19:58:20 2003 @@ -712,7 +712,7 @@ { struct adbdev_state *state; - if (minor(inode->i_rdev) > 0 || adb_controller == NULL) + if (iminor(inode) > 0 || adb_controller == NULL) return -ENXIO; state = kmalloc(sizeof(struct adbdev_state), GFP_KERNEL); if (state == 0) diff -Nru a/drivers/macintosh/macio_asic.c b/drivers/macintosh/macio_asic.c --- a/drivers/macintosh/macio_asic.c Tue Sep 2 19:58:15 2003 +++ b/drivers/macintosh/macio_asic.c Tue Sep 2 19:58:15 2003 @@ -23,6 +23,8 @@ #include #include +static struct macio_chip *macio_on_hold; + static int macio_bus_match(struct device *dev, struct device_driver *drv) { @@ -36,21 +38,27 @@ return of_match_device(matches, &macio_dev->ofdev) != NULL; } -struct bus_type macio_bus_type = { - name: "macio", - match: macio_bus_match, -}; +struct macio_dev *macio_dev_get(struct macio_dev *dev) +{ + struct device *tmp; -static int __init -macio_bus_driver_init(void) + if (!dev) + return NULL; + tmp = get_device(&dev->ofdev.dev); + if (tmp) + return to_macio_device(tmp); + else + return NULL; +} + +void macio_dev_put(struct macio_dev *dev) { - return bus_register(&macio_bus_type); + if (dev) + put_device(&dev->ofdev.dev); } -postcore_initcall(macio_bus_driver_init); -static int -macio_device_probe(struct device *dev) +static int macio_device_probe(struct device *dev) { int error = -ENODEV; struct macio_driver *drv; @@ -63,55 +71,89 @@ if (!drv->probe) return error; -/* if (!try_module_get(driver->owner)) { - printk(KERN_ERR "Can't get a module reference for %s\n", driver->name); - return error; - } -*/ + macio_dev_get(macio_dev); + match = of_match_device(drv->match_table, &macio_dev->ofdev); if (match) error = drv->probe(macio_dev, match); -/* - module_put(driver->owner); -*/ + if (error) + macio_dev_put(macio_dev); + return error; } -static int -macio_device_remove(struct device *dev) +static int macio_device_remove(struct device *dev) { struct macio_dev * macio_dev = to_macio_device(dev); struct macio_driver * drv = to_macio_driver(macio_dev->ofdev.dev.driver); if (drv && drv->remove) drv->remove(macio_dev); + macio_dev_put(macio_dev); + return 0; } -static int -macio_device_suspend(struct device *dev, u32 state, u32 level) +static int macio_device_suspend(struct device *dev, u32 state) { struct macio_dev * macio_dev = to_macio_device(dev); - struct macio_driver * drv = to_macio_driver(macio_dev->ofdev.dev.driver); + struct macio_driver * drv; int error = 0; - if (drv && drv->suspend) - error = drv->suspend(macio_dev, state, level); + if (macio_dev->ofdev.dev.driver == NULL) + return 0; + drv = to_macio_driver(macio_dev->ofdev.dev.driver); + if (drv->suspend) + error = drv->suspend(macio_dev, state); return error; } -static int -macio_device_resume(struct device * dev, u32 level) +static int macio_device_resume(struct device * dev) { struct macio_dev * macio_dev = to_macio_device(dev); - struct macio_driver * drv = to_macio_driver(macio_dev->ofdev.dev.driver); + struct macio_driver * drv; int error = 0; - if (drv && drv->resume) - error = drv->resume(macio_dev, level); + if (macio_dev->ofdev.dev.driver == NULL) + return 0; + drv = to_macio_driver(macio_dev->ofdev.dev.driver); + if (drv->resume) + error = drv->resume(macio_dev); return error; } +struct bus_type macio_bus_type = { + .name = "macio", + .match = macio_bus_match, + .suspend = macio_device_suspend, + .resume = macio_device_resume, +}; + +static int __init +macio_bus_driver_init(void) +{ + return bus_register(&macio_bus_type); +} + +postcore_initcall(macio_bus_driver_init); + + +/** + * macio_release_dev - free a macio device structure when all users of it are finished. + * @dev: device that's been disconnected + * + * Will be called only by the device core when all users of this macio device are + * done. This currently means never as we don't hot remove any macio device yet, + * though that will happen with mediabay based devices in a later implementation. + */ +static void macio_release_dev(struct device *dev) +{ + struct macio_dev *mdev; + + mdev = to_macio_device(dev); + kfree(mdev); +} + /** * macio_add_one_device - Add one device from OF node to the device tree * @chip: pointer to the macio_chip holding the device @@ -121,13 +163,15 @@ * When media-bay is changed to hotswap drivers, this function will * be exposed to the bay driver some way... */ -static struct macio_dev * -macio_add_one_device(struct macio_chip *chip, struct device *parent, +static struct macio_dev * macio_add_one_device(struct macio_chip *chip, struct device *parent, struct device_node *np, struct macio_dev *in_bay) { struct macio_dev *dev; u32 *reg; + if (np == NULL) + return NULL; + dev = kmalloc(sizeof(*dev), GFP_KERNEL); if (!dev) return NULL; @@ -140,6 +184,7 @@ dev->ofdev.dev.dma_mask = &dev->ofdev.dma_mask; dev->ofdev.dev.parent = parent; dev->ofdev.dev.bus = &macio_bus_type; + dev->ofdev.dev.release = macio_release_dev; /* MacIO itself has a different reg, we use it's PCI base */ if (np == chip->of_node) { @@ -164,8 +209,7 @@ return dev; } -static int -macio_skip_device(struct device_node *np) +static int macio_skip_device(struct device_node *np) { if (strncmp(np->name, "battery", 7) == 0) return 1; @@ -185,10 +229,9 @@ * For now, childs of media-bay are added now as well. This will * change rsn though. */ -static void -macio_pci_add_devices(struct macio_chip *chip) +static void macio_pci_add_devices(struct macio_chip *chip) { - struct device_node *np; + struct device_node *np, *pnode; struct macio_dev *rdev, *mdev, *mbdev = NULL, *sdev = NULL; struct device *parent = NULL; @@ -196,16 +239,23 @@ #ifdef CONFIG_PCI if (chip->lbus.pdev) parent = &chip->lbus.pdev->dev; -#endif - rdev = macio_add_one_device(chip, parent, chip->of_node, NULL); +#endif + pnode = of_node_get(chip->of_node); + if (pnode == NULL) + return; + + rdev = macio_add_one_device(chip, parent, pnode, NULL); if (rdev == NULL) return; /* First scan 1st level */ - for (np = chip->of_node->child; np != NULL; np = np->sibling) { + for (np = NULL; (np = of_get_next_child(pnode, np)) != NULL;) { if (!macio_skip_device(np)) { + of_node_get(np); mdev = macio_add_one_device(chip, &rdev->ofdev.dev, np, NULL); - if (strncmp(np->name, "media-bay", 9) == 0) + if (mdev == NULL) + of_node_put(np); + else if (strncmp(np->name, "media-bay", 9) == 0) mbdev = mdev; else if (strncmp(np->name, "escc", 4) == 0) sdev = mdev; @@ -213,17 +263,21 @@ } /* Add media bay devices if any */ - if (mbdev) { - for (np = mbdev->ofdev.node->child; np != NULL; np = np->sibling) - if (!macio_skip_device(np)) - macio_add_one_device(chip, &mbdev->ofdev.dev, np, mbdev); - } + if (mbdev) + for (np = NULL; (np = of_get_next_child(mbdev->ofdev.node, np)) != NULL;) + if (!macio_skip_device(np)) { + of_node_get(np); + if (macio_add_one_device(chip, &mbdev->ofdev.dev, np, mbdev) == NULL) + of_node_put(np); + } /* Add serial ports if any */ - if (sdev) { - for (np = sdev->ofdev.node->child; np != NULL; np = np->sibling) - if (!macio_skip_device(np)) - macio_add_one_device(chip, &sdev->ofdev.dev, np, NULL); - } + if (sdev) + for (np = NULL; (np = of_get_next_child(sdev->ofdev.node, np)) != NULL;) + if (!macio_skip_device(np)) { + of_node_get(np); + if (macio_add_one_device(chip, &sdev->ofdev.dev, np, NULL) == NULL) + of_node_put(np); + } } @@ -231,8 +285,7 @@ * macio_register_driver - Registers a new MacIO device driver * @drv: pointer to the driver definition structure */ -int -macio_register_driver(struct macio_driver *drv) +int macio_register_driver(struct macio_driver *drv) { int count = 0; @@ -240,8 +293,6 @@ drv->driver.name = drv->name; drv->driver.bus = &macio_bus_type; drv->driver.probe = macio_device_probe; - drv->driver.resume = macio_device_resume; - drv->driver.suspend = macio_device_suspend; drv->driver.remove = macio_device_remove; /* register with core */ @@ -253,16 +304,14 @@ * macio_unregister_driver - Unregisters a new MacIO device driver * @drv: pointer to the driver definition structure */ -void -macio_unregister_driver(struct macio_driver *drv) +void macio_unregister_driver(struct macio_driver *drv) { driver_unregister(&drv->driver); } #ifdef CONFIG_PCI -static int __devinit -macio_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) +static int __devinit macio_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) { struct device_node* np; struct macio_chip* chip; @@ -270,19 +319,27 @@ if (ent->vendor != PCI_VENDOR_ID_APPLE) return -ENODEV; + /* Note regarding refcounting: We assume pci_device_to_OF_node() is ported + * to new OF APIs and returns a node with refcount incremented. This isn't + * the case today, but on the other hand ppc32 doesn't do refcounting. This + * will have to be fixed when going to ppc64. --BenH. + */ np = pci_device_to_OF_node(pdev); if (np == NULL) return -ENODEV; + /* We also assume that pmac_feature will have done a get() on nodes stored + * in the macio chips array + */ chip = macio_find(np, macio_unknown); + of_node_put(np); if (chip == NULL) return -ENODEV; - /* XXX Need locking */ + /* XXX Need locking ??? */ if (chip->lbus.pdev == NULL) { chip->lbus.pdev = pdev; chip->lbus.chip = chip; -// INIT_LIST_HEAD(&chip->lbus.devices); pci_set_drvdata(pdev, &chip->lbus); pci_set_master(pdev); } @@ -290,13 +347,28 @@ printk(KERN_INFO "MacIO PCI driver attached to %s chipset\n", chip->name); + /* + * HACK ALERT: The WallStreet PowerBook and some OHare based machines + * have 2 macio ASICs. I must probe the "main" one first or IDE ordering + * will be incorrect. So I put on "hold" the second one since it seem to + * appear first on PCI + */ + if (chip->type == macio_gatwick || chip->type == macio_ohareII) + if (macio_chips[0].lbus.pdev == NULL) { + macio_on_hold = chip; + return 0; + } + macio_pci_add_devices(chip); + if (macio_on_hold && macio_chips[0].lbus.pdev != NULL) { + macio_pci_add_devices(macio_on_hold); + macio_on_hold = NULL; + } return 0; } -static void __devexit -macio_pci_remove(struct pci_dev* pdev) +static void __devexit macio_pci_remove(struct pci_dev* pdev) { panic("removing of macio-asic not supported !\n"); } @@ -306,10 +378,10 @@ * will then decide wether it applies or not */ static const struct pci_device_id __devinitdata pci_ids [] = { { - .vendor = PCI_VENDOR_ID_APPLE, - .device = PCI_ANY_ID, - .subvendor = PCI_ANY_ID, - .subdevice = PCI_ANY_ID, + .vendor = PCI_VENDOR_ID_APPLE, + .device = PCI_ANY_ID, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, }, { /* end: all zeroes */ } }; @@ -317,17 +389,16 @@ /* pci driver glue; this is a "new style" PCI driver module */ static struct pci_driver macio_pci_driver = { - .name = (char *) "macio", - .id_table = pci_ids, + .name = (char *) "macio", + .id_table = pci_ids, - .probe = macio_pci_probe, - .remove = macio_pci_remove, + .probe = macio_pci_probe, + .remove = macio_pci_remove, }; #endif /* CONFIG_PCI */ -static int __init -macio_module_init (void) +static int __init macio_module_init (void) { #ifdef CONFIG_PCI int rc; @@ -339,17 +410,9 @@ return 0; } -/* -static void __exit -macio_module_cleanup (void) -{ -#ifdef CONFIG_PCI - pci_unregister_driver(&macio_pci_driver); -#endif -} -module_exit(macio_module_cleanup); -*/ module_init(macio_module_init); EXPORT_SYMBOL(macio_register_driver); EXPORT_SYMBOL(macio_unregister_driver); +EXPORT_SYMBOL(macio_dev_get); +EXPORT_SYMBOL(macio_dev_put); diff -Nru a/drivers/macintosh/mediabay.c b/drivers/macintosh/mediabay.c --- a/drivers/macintosh/mediabay.c Tue Sep 2 19:58:14 2003 +++ b/drivers/macintosh/mediabay.c Tue Sep 2 19:58:14 2003 @@ -37,15 +37,7 @@ #include #include -#ifdef CONFIG_PMAC_PBOOK -static int mb_notify_sleep(struct pmu_sleep_notifier *self, int when); -static struct pmu_sleep_notifier mb_sleep_notifier = { - mb_notify_sleep, - SLEEP_LEVEL_MEDIABAY, -}; -#endif -#undef MB_USE_INTERRUPTS #define MB_DEBUG #define MB_IGNORE_SIGNALS @@ -55,13 +47,6 @@ #define MBDBG(fmt, arg...) do { } while (0) #endif -/* Type of media bay */ -enum { - mb_ohare, - mb_heathrow, - mb_keylargo -}; - #define MB_FCR32(bay, r) ((bay)->base + ((r) >> 2)) #define MB_FCR8(bay, r) (((volatile u8*)((bay)->base)) + (r)) @@ -76,11 +61,12 @@ struct mb_ops { char* name; - u8 (*content)(struct media_bay_info* bay); - void (*power)(struct media_bay_info* bay, int on_off); - int (*setup_bus)(struct media_bay_info* bay, u8 device_id); - void (*un_reset)(struct media_bay_info* bay); - void (*un_reset_ide)(struct media_bay_info* bay); + void (*init)(struct media_bay_info *bay); + u8 (*content)(struct media_bay_info *bay); + void (*power)(struct media_bay_info *bay, int on_off); + int (*setup_bus)(struct media_bay_info *bay, u8 device_id); + void (*un_reset)(struct media_bay_info *bay); + void (*un_reset_ide)(struct media_bay_info *bay); }; struct media_bay_info { @@ -90,11 +76,12 @@ int last_value; int value_count; int timer; - struct device_node* dev_node; - int mb_type; + struct macio_dev *mdev; struct mb_ops* ops; int index; int cached_gpio; + int sleeping; + struct semaphore lock; #ifdef CONFIG_BLK_DEV_IDE unsigned long cd_base; int cd_index; @@ -111,13 +98,13 @@ #ifdef CONFIG_BLK_DEV_IDE /* check the busy bit in the media-bay ide interface (assumes the media-bay contains an ide device) */ -#define MB_IDE_READY(i) ((inb(media_bays[i].cd_base + 0x70) & 0x80) == 0) +#define MB_IDE_READY(i) ((readb(media_bays[i].cd_base + 0x70) & 0x80) == 0) #endif /* Note: All delays are not in milliseconds and converted to HZ relative * values by the macro below */ -#define MS_TO_HZ(ms) ((ms * HZ) / 1000) +#define MS_TO_HZ(ms) ((ms * HZ + 999) / 1000) /* * Consider the media-bay ID value stable if it is the same for @@ -352,38 +339,37 @@ MB_BIS(bay, OHARE_FCR, OH_BAY_RESET_N); } -static void __pmac -heathrow_mb_un_reset(struct media_bay_info* bay) +static void __pmac keylargo_mb_init(struct media_bay_info *bay) +{ + MB_BIS(bay, KEYLARGO_MBCR, KL_MBCR_MB0_ENABLE); +} + +static void __pmac heathrow_mb_un_reset(struct media_bay_info* bay) { MB_BIS(bay, HEATHROW_FCR, HRW_BAY_RESET_N); } -static void __pmac -keylargo_mb_un_reset(struct media_bay_info* bay) +static void __pmac keylargo_mb_un_reset(struct media_bay_info* bay) { MB_BIS(bay, KEYLARGO_MBCR, KL_MBCR_MB0_DEV_RESET); } -static void __pmac -ohare_mb_un_reset_ide(struct media_bay_info* bay) +static void __pmac ohare_mb_un_reset_ide(struct media_bay_info* bay) { MB_BIS(bay, OHARE_FCR, OH_IDE1_RESET_N); } -static void __pmac -heathrow_mb_un_reset_ide(struct media_bay_info* bay) +static void __pmac heathrow_mb_un_reset_ide(struct media_bay_info* bay) { MB_BIS(bay, HEATHROW_FCR, HRW_IDE1_RESET_N); } -static void __pmac -keylargo_mb_un_reset_ide(struct media_bay_info* bay) +static void __pmac keylargo_mb_un_reset_ide(struct media_bay_info* bay) { MB_BIS(bay, KEYLARGO_FCR1, KL1_EIDE0_RESET_N); } -static inline void __pmac -set_mb_power(struct media_bay_info* bay, int onoff) +static inline void __pmac set_mb_power(struct media_bay_info* bay, int onoff) { /* Power up up and assert the bay reset line */ if (onoff) { @@ -399,8 +385,7 @@ bay->timer = MS_TO_HZ(MB_POWER_DELAY); } -static void __pmac -poll_media_bay(struct media_bay_info* bay) +static void __pmac poll_media_bay(struct media_bay_info* bay) { int id = bay->ops->content(bay); @@ -429,15 +414,13 @@ } } -int __pmac -check_media_bay(struct device_node *which_bay, int what) +int __pmac check_media_bay(struct device_node *which_bay, int what) { #ifdef CONFIG_BLK_DEV_IDE int i; for (i=0; iofdev.node) { if ((what == media_bays[i].content_id) && media_bays[i].state == mb_up) return 0; media_bays[i].cd_index = -1; @@ -447,15 +430,13 @@ return -ENODEV; } -int __pmac -check_media_bay_by_base(unsigned long base, int what) +int __pmac check_media_bay_by_base(unsigned long base, int what) { #ifdef CONFIG_BLK_DEV_IDE int i; for (i=0; imdev && which_bay == bay->mdev->ofdev.node) { int timeout = 5000; - media_bays[i].cd_base = base; - media_bays[i].cd_irq = irq; + down(&bay->lock); - if ((MB_CD != media_bays[i].content_id) || media_bays[i].state != mb_up) - return 0; + bay->cd_base = base; + bay->cd_irq = irq; - printk(KERN_DEBUG "Registered ide %d for media bay %d\n", index, i); + if ((MB_CD != bay->content_id) || bay->state != mb_up) { + up(&bay->lock); + return 0; + } + printk(KERN_DEBUG "Registered ide%d for media bay %d\n", index, i); do { if (MB_IDE_READY(i)) { - media_bays[i].cd_index = index; + bay->cd_index = index; + up(&bay->lock); return 0; } mdelay(1); } while(--timeout); printk(KERN_DEBUG "Timeount waiting IDE in bay %d\n", i); + up(&bay->lock); return -ENODEV; } -#endif + } +#endif /* CONFIG_BLK_DEV_IDE */ return -ENODEV; } -static void __pmac -media_bay_step(int i) +static void __pmac media_bay_step(int i) { struct media_bay_info* bay = &media_bays[i]; @@ -567,6 +553,7 @@ if (bay->cd_index < 0) { hw_regs_t hw; + printk("mediabay %d, registering IDE...\n", i); pmu_suspend(); ide_init_hwif_ports(&hw, (unsigned long) bay->cd_base, (unsigned long) 0, NULL); hw.irq = bay->cd_irq; @@ -580,13 +567,15 @@ printk("IDE register error\n"); set_mb_power(bay, 0); } else { - printk(KERN_DEBUG "media-bay %d is ide %d\n", i, bay->cd_index); + printk(KERN_DEBUG "media-bay %d is ide%d\n", i, bay->cd_index); MBDBG("mediabay %d IDE ready\n", i); } break; - } + } else if (bay->timer > 0) + bay->timer--; if (bay->timer == 0) { - printk("\nIDE Timeout in bay %d !\n", i); + printk("\nIDE Timeout in bay %d !, IDE state is: 0x%02x\n", + i, readb(bay->cd_base + 0x70)); MBDBG("mediabay%d: nIDE Timeout !\n", i); set_mb_power(bay, 0); } @@ -623,8 +612,7 @@ * with the IDE driver. It needs to be a thread because * ide_register can't be called from interrupt context. */ -static int __pmac -media_bay_task(void *x) +static int __pmac media_bay_task(void *x) { int i; @@ -634,75 +622,140 @@ #endif for (;;) { - for (i = 0; i < media_bay_count; ++i) - media_bay_step(i); + for (i = 0; i < media_bay_count; ++i) { + down(&media_bays[i].lock); + if (!media_bays[i].sleeping) + media_bay_step(i); + up(&media_bays[i].lock); + } current->state = TASK_INTERRUPTIBLE; - schedule_timeout(1); + schedule_timeout(MS_TO_HZ(10)); if (signal_pending(current)) return 0; } } -#ifdef MB_USE_INTERRUPTS -static void __pmac -media_bay_intr(int irq, void *devid, struct pt_regs *regs) -{ -} -#endif - -#ifdef CONFIG_PMAC_PBOOK -/* - * notify clients before sleep and reset bus afterwards - */ -int __pmac -mb_notify_sleep(struct pmu_sleep_notifier *self, int when) +static int __devinit media_bay_attach(struct macio_dev *mdev, const struct of_match *match) { struct media_bay_info* bay; + volatile u32 *regbase; + struct device_node *ofnode; int i; + + ofnode = mdev->ofdev.node; + + if (!request_OF_resource(ofnode, 0, NULL)) + return -ENXIO; + + /* Media bay registers are located at the beginning of the + * mac-io chip, we get the parent address for now (hrm...) + */ + if (ofnode->parent->n_addrs == 0) + return -ENODEV; + regbase = (volatile u32 *)ioremap(ofnode->parent->addrs[0].address, 0x100); + if (regbase == NULL) { + release_OF_resource(ofnode, 0); + return -ENOMEM; + } - switch (when) { - case PBOOK_SLEEP_REQUEST: - case PBOOK_SLEEP_REJECT: - break; - - case PBOOK_SLEEP_NOW: - for (i=0; iops->content(bay) != bay->content_id) - continue; - set_mb_power(bay, 1); - bay->last_value = bay->content_id; - bay->value_count = MS_TO_HZ(MB_STABLE_DELAY); - bay->timer = MS_TO_HZ(MB_POWER_DELAY); -#ifdef CONFIG_BLK_DEV_IDE - bay->cd_retry = 0; -#endif - do { - mdelay(1000/HZ); - media_bay_step(i); - } while((media_bays[i].state != mb_empty) && - (media_bays[i].state != mb_up)); - } - break; + i = media_bay_count++; + bay = &media_bays[i]; + bay->mdev = mdev; + bay->base = regbase; + bay->index = i; + bay->ops = match->data; + bay->sleeping = 0; + init_MUTEX(&bay->lock); + + /* Init HW probing */ + if (bay->ops->init) + bay->ops->init(bay); + + printk(KERN_INFO "mediabay%d: Registered %s media-bay\n", i, bay->ops->name); + + /* Force an immediate detect */ + set_mb_power(bay, 0); + set_current_state(TASK_UNINTERRUPTIBLE); + schedule_timeout(MS_TO_HZ(MB_POWER_DELAY)); + bay->content_id = MB_NO; + bay->last_value = bay->ops->content(bay); + bay->value_count = MS_TO_HZ(MB_STABLE_DELAY); + bay->state = mb_empty; + do { + set_current_state(TASK_UNINTERRUPTIBLE); + schedule_timeout(MS_TO_HZ(10)); + media_bay_step(i); + } while((bay->state != mb_empty) && + (bay->state != mb_up)); + + /* Mark us ready by filling our mdev data */ + dev_set_drvdata(&mdev->ofdev.dev, bay); + + /* Startup kernel thread */ + if (i == 0) + kernel_thread(media_bay_task, NULL, + CLONE_FS | CLONE_FILES | CLONE_SIGHAND); + + return 0; + +} + +static int __pmac media_bay_suspend(struct macio_dev *mdev, u32 state) +{ + struct media_bay_info *bay = dev_get_drvdata(&mdev->ofdev.dev); + + if (state != mdev->ofdev.dev.power_state && state >= 2) { + down(&bay->lock); + bay->sleeping = 1; + set_mb_power(bay, 0); + up(&bay->lock); + set_current_state(TASK_UNINTERRUPTIBLE); + schedule_timeout(MS_TO_HZ(10)); + mdev->ofdev.dev.power_state = state; } - return PBOOK_SLEEP_OK; + return 0; +} + +static int __pmac media_bay_resume(struct macio_dev *mdev) +{ + struct media_bay_info *bay = dev_get_drvdata(&mdev->ofdev.dev); + + if (mdev->ofdev.dev.power_state != 0) { + mdev->ofdev.dev.power_state = 0; + + /* We re-enable the bay using it's previous content + only if it did not change. Note those bozo timings, + they seem to help the 3400 get it right. + */ + /* Force MB power to 0 */ + down(&bay->lock); + set_mb_power(bay, 0); + set_current_state(TASK_UNINTERRUPTIBLE); + schedule_timeout(MS_TO_HZ(MB_POWER_DELAY)); + if (bay->ops->content(bay) != bay->content_id) { + printk("mediabay%d: content changed during sleep...\n", bay->index); + up(&bay->lock); + return 0; + } + set_mb_power(bay, 1); + bay->last_value = bay->content_id; + bay->value_count = MS_TO_HZ(MB_STABLE_DELAY); + bay->timer = MS_TO_HZ(MB_POWER_DELAY); +#ifdef CONFIG_BLK_DEV_IDE + bay->cd_retry = 0; +#endif + do { + set_current_state(TASK_UNINTERRUPTIBLE); + schedule_timeout(MS_TO_HZ(10)); + media_bay_step(bay->index); + } while((bay->state != mb_empty) && + (bay->state != mb_up)); + bay->sleeping = 0; + up(&bay->lock); + } + return 0; } -#endif /* CONFIG_PMAC_PBOOK */ /* Definitions of "ops" structures. @@ -727,6 +780,7 @@ static struct mb_ops keylargo_mb_ops __pmacdata = { .name = "KeyLargo", + .init = keylargo_mb_init, .content = keylargo_mb_content, .power = keylargo_mb_power, .setup_bus = keylargo_mb_setup_bus, @@ -743,12 +797,42 @@ * Therefore we do it all by polling the media bay once each tick. */ -static int __init -media_bay_init(void) +static struct of_match media_bay_match[] = { - struct device_node *np; - int n,i; - + { + .name = "media-bay", + .type = OF_ANY_MATCH, + .compatible = "keylargo-media-bay", + .data = &keylargo_mb_ops, + }, + { + .name = "media-bay", + .type = OF_ANY_MATCH, + .compatible = "heathrow-media-bay", + .data = &heathrow_mb_ops, + }, + { + .name = "media-bay", + .type = OF_ANY_MATCH, + .compatible = "ohare-media-bay", + .data = &ohare_mb_ops, + }, + {}, +}; + +static struct macio_driver media_bay_driver = +{ + .name = "media-bay", + .match_table = media_bay_match, + .probe = media_bay_attach, + .suspend = media_bay_suspend, + .resume = media_bay_resume +}; + +static int __init media_bay_init(void) +{ + int i; + for (i=0; iparent || np->n_addrs == 0 || !request_OF_resource(np, 0, NULL)) { - np = np->next; - printk(KERN_ERR "media-bay: Can't request IO resource !\n"); - continue; - } - bay->mb_type = mb_ohare; - - if (device_is_compatible(np, "keylargo-media-bay")) { - bay->mb_type = mb_keylargo; - bay->ops = &keylargo_mb_ops; - } else if (device_is_compatible(np, "heathrow-media-bay")) { - bay->mb_type = mb_heathrow; - bay->ops = &heathrow_mb_ops; - } else if (device_is_compatible(np, "ohare-media-bay")) { - bay->mb_type = mb_ohare; - bay->ops = &ohare_mb_ops; - } else { - printk(KERN_ERR "mediabay: Unknown bay type !\n"); - np = np->next; - continue; - } - bay->base = (volatile u32*)ioremap(np->parent->addrs[0].address, 0x1000); - - /* Enable probe logic on keylargo */ - if (bay->mb_type == mb_keylargo) - MB_BIS(bay, KEYLARGO_MBCR, KL_MBCR_MB0_ENABLE); -#ifdef MB_USE_INTERRUPTS - if (np->n_intrs == 0) { - printk(KERN_ERR "media bay %d has no irq\n",n); - np = np->next; - continue; - } - - if (request_irq(np->intrs[0].line, media_bay_intr, 0, "Media bay", (void *)n)) { - printk(KERN_ERR "Couldn't get IRQ %d for media bay %d\n", - np->intrs[0].line, n); - np = np->next; - continue; - } -#endif - media_bay_count++; - - printk(KERN_INFO "mediabay%d: Registered %s media-bay\n", n, bay->ops->name); - bay->dev_node = np; - bay->index = n; - - /* Force an immediate detect */ - set_mb_power(bay, 0); - mdelay(MB_POWER_DELAY); - bay->content_id = MB_NO; - bay->last_value = bay->ops->content(bay); - bay->value_count = MS_TO_HZ(MB_STABLE_DELAY); - bay->state = mb_empty; - do { - mdelay(1000/HZ); - media_bay_step(n); - } while((bay->state != mb_empty) && - (bay->state != mb_up)); - - n++; - np=np->next; - } + if (_machine != _MACH_Pmac) + return -ENODEV; - if (media_bay_count) - { -#ifdef CONFIG_PMAC_PBOOK - pmu_register_sleep_notifier(&mb_sleep_notifier); -#endif /* CONFIG_PMAC_PBOOK */ + macio_register_driver(&media_bay_driver); - kernel_thread(media_bay_task, NULL, - CLONE_FS | CLONE_FILES | CLONE_SIGHAND); - } return 0; } -subsys_initcall(media_bay_init); +device_initcall(media_bay_init); diff -Nru a/drivers/macintosh/via-pmu.c b/drivers/macintosh/via-pmu.c --- a/drivers/macintosh/via-pmu.c Tue Sep 2 19:58:18 2003 +++ b/drivers/macintosh/via-pmu.c Tue Sep 2 19:58:18 2003 @@ -11,6 +11,14 @@ * Copyright (C) 1998 Paul Mackerras and Fabio Riccardi. * Copyright (C) 2001-2002 Benjamin Herrenschmidt * + * THIS DRIVER IS BECOMING A TOTAL MESS ! + * - Cleanup atomically disabling reply to PMU events after + * a sleep or a freq. switch + * - Move sleep code out of here to pmac_pm, merge into new + * common PM infrastructure + * - Move backlight code out as well + * - Save/Restore PCI space properly + * */ #include #include @@ -34,6 +42,8 @@ #include #include #include +#include +#include #include #include #include @@ -47,6 +57,7 @@ #include #include #include +#include #ifdef CONFIG_PMAC_BACKLIGHT #include #endif @@ -55,7 +66,6 @@ #undef SUSPEND_USES_PMU #define DEBUG_SLEEP #undef HACKED_PCI_SAVE -#define NEW_OHARE_CODE /* Misc minor number allocated for /dev/pmu */ #define PMU_MINOR 154 @@ -63,6 +73,13 @@ /* How many iterations between battery polls */ #define BATTERY_POLLING_COUNT 2 +/* Some debugging tools */ +#ifdef CONFIG_XMON +//#define LIVE_DEBUG(req) ((req) && (req)->data[0] == 0x7d) +#define LIVE_DEBUG(req) (0) +static int whacky_debug; +#endif /* CONFIG_XMON */ + static volatile unsigned char *via; /* VIA registers - spaced 0x200 bytes apart */ @@ -106,6 +123,7 @@ intack, reading, reading_intr, + locked, } pmu_state; static volatile enum int_data_state { @@ -133,6 +151,7 @@ static int pmu_has_adb; static unsigned char *gpio_reg = NULL; static int gpio_irq = -1; +static int gpio_irq_enabled = -1; static volatile int pmu_suspended = 0; static spinlock_t pmu_lock; static u8 pmu_intr_mask; @@ -143,9 +162,11 @@ static int sleep_in_progress; static int can_sleep; #endif /* CONFIG_PMAC_PBOOK */ +static unsigned int pmu_irq_stats[11]; static struct proc_dir_entry *proc_pmu_root; static struct proc_dir_entry *proc_pmu_info; +static struct proc_dir_entry *proc_pmu_irqstats; static struct proc_dir_entry *proc_pmu_options; #ifdef CONFIG_PMAC_PBOOK @@ -184,6 +205,8 @@ static irqreturn_t gpio1_interrupt(int irq, void *arg, struct pt_regs *regs); static int proc_get_info(char *page, char **start, off_t off, int count, int *eof, void *data); +static int proc_get_irqstats(char *page, char **start, off_t off, + int count, int *eof, void *data); #ifdef CONFIG_PMAC_BACKLIGHT static int pmu_set_backlight_level(int level, void* data); static int pmu_set_backlight_enable(int on, int level, void* data); @@ -205,16 +228,12 @@ pmu_init, pmu_send_request, pmu_adb_autopoll, - pmu_poll, + pmu_poll_adb, pmu_adb_reset_bus }; #endif /* CONFIG_ADB */ extern void low_sleep_handler(void); -extern void pmac_sleep_save_intrs(int); -extern void pmac_sleep_restore_intrs(void); -extern void openpic_sleep_save_intrs(void); -extern void openpic_sleep_restore_intrs(void); extern void enable_kernel_altivec(void); extern void enable_kernel_fp(void); @@ -223,14 +242,6 @@ int pmu_wink(struct adb_request *req); #endif -#if defined(CONFIG_PMAC_PBOOK) && defined(CONFIG_PM) -static int generic_notify_sleep(struct pmu_sleep_notifier *self, int when); -static struct pmu_sleep_notifier generic_sleep_notifier = { - generic_notify_sleep, - SLEEP_LEVEL_MISC, -}; -#endif /* defined(CONFIG_PMAC_PBOOK) && defined(CONFIG_PM) */ - /* * This table indicates for each PMU opcode: * - the number of data bytes to be sent with the command, or -1 @@ -361,11 +372,6 @@ sys_ctrler = SYS_CTRLER_PMU; -#if defined(CONFIG_PMAC_PBOOK) && defined(CONFIG_PM) - pmu_register_sleep_notifier(&generic_sleep_notifier); - pm_active = 1; -#endif - return 1; } @@ -416,6 +422,7 @@ if (pmu_kind == PMU_KEYLARGO_BASED && gpio_irq != -1) { if (request_irq(gpio_irq, gpio1_interrupt, 0, "GPIO1/ADB", (void *)0)) printk(KERN_ERR "pmu: can't get irq %d (GPIO1)\n", gpio_irq); + gpio_irq_enabled = 1; } /* Enable interrupts */ @@ -489,6 +496,8 @@ int i; proc_pmu_info = create_proc_read_entry("info", 0, proc_pmu_root, proc_get_info, NULL); + proc_pmu_irqstats = create_proc_read_entry("interrupts", 0, proc_pmu_root, + proc_get_irqstats, NULL); #ifdef CONFIG_PMAC_PBOOK for (i=0; i 0) pmu_version = req.reply[0]; return 1; } -int __pmac +int pmu_get_model(void) { return pmu_kind; @@ -774,6 +782,33 @@ return p - page; } +static int __pmac +proc_get_irqstats(char *page, char **start, off_t off, + int count, int *eof, void *data) +{ + int i; + char* p = page; + static const char *irq_names[] = { + "Total CB1 triggered events", + "Total GPIO1 triggered events", + "PC-Card eject button", + "Sound/Brightness button", + "ADB message", + "Battery state change", + "Environment interrupt", + "Tick timer", + "Ghost interrupt (zero len)", + "Empty interrupt (empty mask)", + "Max irqs in a row" + }; + + for (i=0; i<11; i++) { + p += sprintf(p, " %2u: %10u (%s)\n", + i, pmu_irq_stats[i], irq_names[i]); + } + return p - page; +} + #ifdef CONFIG_PMAC_PBOOK static int __pmac proc_get_batt(char *page, char **start, off_t off, @@ -982,8 +1017,7 @@ printk(KERN_ERR "pmu_adb_reset_bus: pmu_queue_request failed\n"); return -EIO; } - while (!req.complete) - pmu_poll(); + pmu_wait_complete(&req); if (save_autopoll != 0) pmu_adb_autopoll(save_autopoll); @@ -1133,6 +1167,12 @@ wait_for_ack(); /* set the shift register to shift out and send a byte */ send_byte(req->data[0]); +#ifdef CONFIG_XMON + if (LIVE_DEBUG(req)) + xmon_printf("R"); + else + whacky_debug = 0; +#endif /* CONFIG_XMON */ } void __openfirmware @@ -1142,15 +1182,33 @@ return; if (disable_poll) return; + via_pmu_interrupt(0, 0, 0); +} + +void __openfirmware +pmu_poll_adb(void) +{ + if (!via) + return; + if (disable_poll) + return; /* Kicks ADB read when PMU is suspended */ - if (pmu_suspended) - adb_int_pending = 1; + adb_int_pending = 1; do { via_pmu_interrupt(0, 0, 0); } while (pmu_suspended && (adb_int_pending || pmu_state != idle || req_awaiting_reply)); } +void __openfirmware +pmu_wait_complete(struct adb_request *req) +{ + if (!via) + return; + while((pmu_state != idle && pmu_state != locked) || !req->complete) + via_pmu_interrupt(0, 0, 0); +} + /* This function loops until the PMU is idle and prevents it from * anwsering to ADB interrupts. pmu_request can still be called. * This is done to avoid spurrious shutdowns when we know we'll have @@ -1175,6 +1233,8 @@ do { spin_unlock_irqrestore(&pmu_lock, flags); + if (req_awaiting_reply) + adb_int_pending = 1; via_pmu_interrupt(0, 0, 0); spin_lock_irqsave(&pmu_lock, flags); if (!adb_int_pending && pmu_state == idle && !req_awaiting_reply) { @@ -1185,7 +1245,7 @@ pmu_poll(); #else /* SUSPEND_USES_PMU */ if (gpio_irq >= 0) - disable_irq(gpio_irq); + disable_irq_nosync(gpio_irq); out_8(&via[IER], CB1_INT | IER_CLR); spin_unlock_irqrestore(&pmu_lock, flags); #endif /* SUSPEND_USES_PMU */ @@ -1227,16 +1287,47 @@ static void __pmac pmu_handle_data(unsigned char *data, int len, struct pt_regs *regs) { + unsigned char ints, pirq; + int i = 0; + asleep = 0; if (drop_interrupts || len < 1) { adb_int_pending = 0; + pmu_irq_stats[8]++; + return; + } + + /* Get PMU interrupt mask */ + ints = data[0]; + + /* Record zero interrupts for stats */ + if (ints == 0) + pmu_irq_stats[9]++; + + /* Hack to deal with ADB autopoll flag */ + if (ints & PMU_INT_ADB) + ints &= ~(PMU_INT_ADB_AUTO | PMU_INT_AUTO_SRQ_POLL); + +next: + + if (ints == 0) { + if (i > pmu_irq_stats[10]) + pmu_irq_stats[10] = i; return; } + + for (pirq = 0; pirq < 8; pirq++) + if (ints & (1 << pirq)) + break; + pmu_irq_stats[pirq]++; + i++; + ints &= ~(1 << pirq); + /* Note: for some reason, we get an interrupt with len=1, * data[0]==0 after each normal ADB interrupt, at least * on the Pismo. Still investigating... --BenH */ - if (data[0] & PMU_INT_ADB) { + if ((1 << pirq) & PMU_INT_ADB) { if ((data[0] & PMU_INT_ADB_AUTO) == 0) { struct adb_request *req = req_awaiting_reply; if (req == 0) { @@ -1274,29 +1365,37 @@ adb_input(data+1, len-1, regs, 1); #endif /* CONFIG_ADB */ } - } else { - /* Sound/brightness button pressed */ - if ((data[0] & PMU_INT_SNDBRT) && len == 3) { + } + /* Sound/brightness button pressed */ + else if ((1 << pirq) & PMU_INT_SNDBRT) { #ifdef CONFIG_PMAC_BACKLIGHT + if (len == 3) #ifdef CONFIG_INPUT_ADBHID if (!disable_kernel_backlight) #endif /* CONFIG_INPUT_ADBHID */ set_backlight_level(data[1] >> 4); #endif /* CONFIG_PMAC_BACKLIGHT */ - } + } + /* Tick interrupt */ + else if ((1 << pirq) & PMU_INT_TICK) { #ifdef CONFIG_PMAC_PBOOK /* Environement or tick interrupt, query batteries */ - if (pmu_battery_count && (data[0] & PMU_INT_TICK)) { + if (pmu_battery_count) { if ((--query_batt_timer) == 0) { query_battery_state(); query_batt_timer = BATTERY_POLLING_COUNT; } - } else if (pmu_battery_count && (data[0] & PMU_INT_ENVIRONMENT)) + } + } + else if ((1 << pirq) & PMU_INT_ENVIRONMENT) { + if (pmu_battery_count) query_battery_state(); - if (data[0]) - pmu_pass_intr(data, len); + pmu_pass_intr(data, len); + } else + pmu_pass_intr(data, len); + #endif /* CONFIG_PMAC_PBOOK */ - } + goto next; } static struct adb_request* __pmac @@ -1326,17 +1425,29 @@ case sending: req = current_req; if (data_len < 0) { +#ifdef CONFIG_XMON + if (LIVE_DEBUG(req)) + xmon_printf("s"); +#endif /* CONFIG_XMON */ data_len = req->nbytes - 1; send_byte(data_len); break; } if (data_index <= data_len) { +#ifdef CONFIG_XMON + if (LIVE_DEBUG(req)) + xmon_printf("S"); +#endif /* CONFIG_XMON */ send_byte(req->data[data_index++]); break; } req->sent = 1; data_len = pmu_data_len[req->data[0]][1]; if (data_len == 0) { +#ifdef CONFIG_XMON + if (LIVE_DEBUG(req)) + xmon_printf("D"); +#endif /* CONFIG_XMON */ pmu_state = idle; current_req = req->next; if (req->reply_expected) @@ -1344,6 +1455,10 @@ else return req; } else { +#ifdef CONFIG_XMON + if (LIVE_DEBUG(req)) + xmon_printf("-"); +#endif /* CONFIG_XMON */ pmu_state = reading; data_index = 0; reply_ptr = req->reply + req->reply_len; @@ -1357,15 +1472,27 @@ pmu_state = reading_intr; reply_ptr = interrupt_data[int_data_last]; recv_byte(); + if (gpio_irq >= 0 && !gpio_irq_enabled) { + enable_irq(gpio_irq); + gpio_irq_enabled = 1; + } break; case reading: case reading_intr: if (data_len == -1) { +#ifdef CONFIG_XMON + if (LIVE_DEBUG(current_req)) + xmon_printf("r"); +#endif /* CONFIG_XMON */ data_len = bite; if (bite > 32) printk(KERN_ERR "PMU: bad reply len %d\n", bite); } else if (data_index < 32) { +#ifdef CONFIG_XMON + if (LIVE_DEBUG(current_req)) + xmon_printf("R"); +#endif /* CONFIG_XMON */ reply_ptr[data_index++] = bite; } if (data_index < data_len) { @@ -1373,15 +1500,29 @@ break; } +#ifdef CONFIG_XMON + if (LIVE_DEBUG(current_req)) { + whacky_debug = 1; + xmon_printf("D"); + } +#endif /* CONFIG_XMON */ if (pmu_state == reading_intr) { pmu_state = idle; int_data_state[int_data_last] = int_data_ready; interrupt_data_len[int_data_last] = data_len; } else { req = current_req; + /* + * For PMU sleep and freq change requests, we lock the + * PMU until it's explicitely unlocked. This avoids any + * spurrious event polling getting in + */ current_req = req->next; req->reply_len += data_index; - pmu_state = idle; + if (req->data[0] == PMU_SLEEP || req->data[0] == PMU_CPU_SPEED) + pmu_state = locked; + else + pmu_state = idle; return req; } break; @@ -1411,6 +1552,10 @@ intr = in_8(&via[IFR]) & (SR_INT | CB1_INT); if (intr == 0) break; +#ifdef CONFIG_XMON + if (whacky_debug) + xmon_printf("|%02x|", intr); +#endif /* CONFIG_XMON */ handled = 1; if (++nloop > 1000) { printk(KERN_DEBUG "PMU: stuck in intr loop, " @@ -1419,8 +1564,10 @@ break; } out_8(&via[IFR], intr); - if (intr & CB1_INT) + if (intr & CB1_INT) { adb_int_pending = 1; + pmu_irq_stats[0]++; + } if (intr & SR_INT) { req = pmu_sr_intr(regs); if (req) @@ -1431,6 +1578,10 @@ recheck: if (pmu_state == idle) { if (adb_int_pending) { +#ifdef CONFIG_XMON + if (whacky_debug) + xmon_printf("!A!"); +#endif /* CONFIG_XMON */ if (int_data_state[0] == int_data_empty) int_data_last = 0; else if (int_data_state[1] == int_data_empty) @@ -1479,11 +1630,33 @@ return IRQ_RETVAL(handled); } +void __pmac +pmu_unlock(void) +{ + unsigned long flags; + + spin_lock_irqsave(&pmu_lock, flags); + if (pmu_state == locked) + pmu_state = idle; + adb_int_pending = 1; + spin_unlock_irqrestore(&pmu_lock, flags); +} + + static irqreturn_t __pmac gpio1_interrupt(int irq, void *arg, struct pt_regs *regs) { + unsigned long flags; + if ((in_8(gpio_reg + 0x9) & 0x02) == 0) { + spin_lock_irqsave(&pmu_lock, flags); + if (gpio_irq_enabled > 0) { + disable_irq_nosync(gpio_irq); + gpio_irq_enabled = 0; + } + pmu_irq_stats[1]++; adb_int_pending = 1; + spin_unlock_irqrestore(&pmu_lock, flags); via_pmu_interrupt(0, 0, 0); return IRQ_HANDLED; } @@ -1507,13 +1680,11 @@ if (on) { pmu_request(&req, NULL, 2, PMU_BACKLIGHT_BRIGHT, backlight_to_bright[level]); - while (!req.complete) - pmu_poll(); + pmu_wait_complete(&req); } pmu_request(&req, NULL, 2, PMU_POWER_CTRL, PMU_POW_BACKLIGHT | (on ? PMU_POW_ON : PMU_POW_OFF)); - while (!req.complete) - pmu_poll(); + pmu_wait_complete(&req); return 0; } @@ -1549,8 +1720,7 @@ pmu_request(&req, NULL, 2, PMU_POWER_CTRL, PMU_POW_IRLED | (on ? PMU_POW_ON : PMU_POW_OFF)); - while (!req.complete) - pmu_poll(); + pmu_wait_complete(&req); } void __pmac @@ -1570,8 +1740,7 @@ } pmu_request(&req, NULL, 1, PMU_RESET); - while(!req.complete || (pmu_state != idle)) - pmu_poll(); + pmu_wait_complete(&req); for (;;) ; } @@ -1588,14 +1757,12 @@ if (pmu_kind != PMU_KEYLARGO_BASED) { pmu_request(&req, NULL, 2, PMU_SET_INTR_MASK, PMU_INT_ADB | PMU_INT_TICK ); - while(!req.complete) - pmu_poll(); + pmu_wait_complete(&req); } pmu_request(&req, NULL, 5, PMU_SHUTDOWN, 'M', 'A', 'T', 'T'); - while(!req.complete || (pmu_state != idle)) - pmu_poll(); + pmu_wait_complete(&req); for (;;) ; } @@ -1606,25 +1773,261 @@ return via != 0; } -#ifdef CONFIG_PMAC_PBOOK +struct pmu_i2c_hdr { + u8 bus; + u8 mode; + u8 bus2; + u8 address; + u8 sub_addr; + u8 comb_addr; + u8 count; +}; -static LIST_HEAD(sleep_notifiers); +int +pmu_i2c_combined_read(int bus, int addr, int subaddr, u8* data, int len) +{ + struct adb_request req; + struct pmu_i2c_hdr *hdr = (struct pmu_i2c_hdr *)&req.data[1]; + int retry; + int rc; + + for (retry=0; retry<16; retry++) { + memset(&req, 0, sizeof(req)); + + hdr->bus = bus; + hdr->address = addr & 0xfe; + hdr->mode = PMU_I2C_MODE_COMBINED; + hdr->bus2 = 0; + hdr->sub_addr = subaddr; + hdr->comb_addr = addr | 1; + hdr->count = len; + + req.nbytes = sizeof(struct pmu_i2c_hdr) + 1; + req.reply_expected = 0; + req.reply_len = 0; + req.data[0] = PMU_I2C_CMD; + req.reply[0] = 0xff; + rc = pmu_queue_request(&req); + if (rc) + return rc; + while(!req.complete) + pmu_poll(); + if (req.reply[0] == PMU_I2C_STATUS_OK) + break; + mdelay(15); + } + if (req.reply[0] != PMU_I2C_STATUS_OK) + return -1; -#ifdef CONFIG_PM -static int __pmac -generic_notify_sleep(struct pmu_sleep_notifier *self, int when) + for (retry=0; retry<16; retry++) { + memset(&req, 0, sizeof(req)); + + mdelay(15); + + hdr->bus = PMU_I2C_BUS_STATUS; + req.reply[0] = 0xff; + + req.nbytes = 2; + req.reply_expected = 0; + req.reply_len = 0; + req.data[0] = PMU_I2C_CMD; + rc = pmu_queue_request(&req); + if (rc) + return rc; + while(!req.complete) + pmu_poll(); + if (req.reply[0] == PMU_I2C_STATUS_DATAREAD) { + memcpy(data, &req.reply[1], req.reply_len - 1); + return req.reply_len - 1; + } + } + return -1; +} + +int +pmu_i2c_stdsub_write(int bus, int addr, int subaddr, u8* data, int len) { - switch (when) { - case PBOOK_SLEEP_NOW: - if (pm_send_all(PM_SUSPEND, (void *)3)) - return PBOOK_SLEEP_REJECT; + struct adb_request req; + struct pmu_i2c_hdr *hdr = (struct pmu_i2c_hdr *)&req.data[1]; + int retry; + int rc; + + for (retry=0; retry<16; retry++) { + memset(&req, 0, sizeof(req)); + + hdr->bus = bus; + hdr->address = addr & 0xfe; + hdr->mode = PMU_I2C_MODE_STDSUB; + hdr->bus2 = 0; + hdr->sub_addr = subaddr; + hdr->comb_addr = addr & 0xfe; + hdr->count = len; + + req.data[0] = PMU_I2C_CMD; + memcpy(&req.data[sizeof(struct pmu_i2c_hdr) + 1], data, len); + req.nbytes = sizeof(struct pmu_i2c_hdr) + len + 1; + req.reply_expected = 0; + req.reply_len = 0; + req.reply[0] = 0xff; + rc = pmu_queue_request(&req); + if (rc) + return rc; + while(!req.complete) + pmu_poll(); + if (req.reply[0] == PMU_I2C_STATUS_OK) break; - case PBOOK_WAKE: - (void) pm_send_all(PM_RESUME, (void *)0); + mdelay(15); } - return PBOOK_SLEEP_OK; + if (req.reply[0] != PMU_I2C_STATUS_OK) + return -1; + + for (retry=0; retry<16; retry++) { + memset(&req, 0, sizeof(req)); + + mdelay(15); + + hdr->bus = PMU_I2C_BUS_STATUS; + req.reply[0] = 0xff; + + req.nbytes = 2; + req.reply_expected = 0; + req.reply_len = 0; + req.data[0] = PMU_I2C_CMD; + rc = pmu_queue_request(&req); + if (rc) + return rc; + while(!req.complete) + pmu_poll(); + if (req.reply[0] == PMU_I2C_STATUS_OK) + return len; + } + return -1; } -#endif /* CONFIG_PM */ + +int +pmu_i2c_simple_read(int bus, int addr, u8* data, int len) +{ + struct adb_request req; + struct pmu_i2c_hdr *hdr = (struct pmu_i2c_hdr *)&req.data[1]; + int retry; + int rc; + + for (retry=0; retry<16; retry++) { + memset(&req, 0, sizeof(req)); + + hdr->bus = bus; + hdr->address = addr | 1; + hdr->mode = PMU_I2C_MODE_SIMPLE; + hdr->bus2 = 0; + hdr->sub_addr = 0; + hdr->comb_addr = 0; + hdr->count = len; + + req.data[0] = PMU_I2C_CMD; + req.nbytes = sizeof(struct pmu_i2c_hdr) + 1; + req.reply_expected = 0; + req.reply_len = 0; + req.reply[0] = 0xff; + rc = pmu_queue_request(&req); + if (rc) + return rc; + while(!req.complete) + pmu_poll(); + if (req.reply[0] == PMU_I2C_STATUS_OK) + break; + mdelay(15); + } + if (req.reply[0] != PMU_I2C_STATUS_OK) + return -1; + + for (retry=0; retry<16; retry++) { + memset(&req, 0, sizeof(req)); + + mdelay(15); + + hdr->bus = PMU_I2C_BUS_STATUS; + req.reply[0] = 0xff; + + req.nbytes = 2; + req.reply_expected = 0; + req.reply_len = 0; + req.data[0] = PMU_I2C_CMD; + rc = pmu_queue_request(&req); + if (rc) + return rc; + while(!req.complete) + pmu_poll(); + if (req.reply[0] == PMU_I2C_STATUS_DATAREAD) { + memcpy(data, &req.reply[1], req.reply_len - 1); + return req.reply_len - 1; + } + } + return -1; +} + +int +pmu_i2c_simple_write(int bus, int addr, u8* data, int len) +{ + struct adb_request req; + struct pmu_i2c_hdr *hdr = (struct pmu_i2c_hdr *)&req.data[1]; + int retry; + int rc; + + for (retry=0; retry<16; retry++) { + memset(&req, 0, sizeof(req)); + + hdr->bus = bus; + hdr->address = addr & 0xfe; + hdr->mode = PMU_I2C_MODE_SIMPLE; + hdr->bus2 = 0; + hdr->sub_addr = 0; + hdr->comb_addr = 0; + hdr->count = len; + + req.data[0] = PMU_I2C_CMD; + memcpy(&req.data[sizeof(struct pmu_i2c_hdr) + 1], data, len); + req.nbytes = sizeof(struct pmu_i2c_hdr) + len + 1; + req.reply_expected = 0; + req.reply_len = 0; + req.reply[0] = 0xff; + rc = pmu_queue_request(&req); + if (rc) + return rc; + while(!req.complete) + pmu_poll(); + if (req.reply[0] == PMU_I2C_STATUS_OK) + break; + mdelay(15); + } + if (req.reply[0] != PMU_I2C_STATUS_OK) + return -1; + + for (retry=0; retry<16; retry++) { + memset(&req, 0, sizeof(req)); + + mdelay(15); + + hdr->bus = PMU_I2C_BUS_STATUS; + req.reply[0] = 0xff; + + req.nbytes = 2; + req.reply_expected = 0; + req.reply_len = 0; + req.data[0] = PMU_I2C_CMD; + rc = pmu_queue_request(&req); + if (rc) + return rc; + while(!req.complete) + pmu_poll(); + if (req.reply[0] == PMU_I2C_STATUS_OK) + return len; + } + return -1; +} + +#ifdef CONFIG_PMAC_PBOOK + +static LIST_HEAD(sleep_notifiers); int pmu_register_sleep_notifier(struct pmu_sleep_notifier *n) @@ -1885,90 +2288,166 @@ } extern long sys_sync(void); +extern void pm_prepare_console(void); +extern void pm_restore_console(void); -#define GRACKLE_PM (1<<7) -#define GRACKLE_DOZE (1<<5) -#define GRACKLE_NAP (1<<4) -#define GRACKLE_SLEEP (1<<3) - -int __pmac -powerbook_sleep_G3(void) +static int __pmac +pmac_suspend_devices(void) { - unsigned long save_l2cr; - unsigned short pmcr1; - struct adb_request req; int ret; - struct pci_dev *grackle; - - grackle = pci_find_slot(0, 0); - if (!grackle) - return -ENODEV; - - /* Notify device drivers */ + + pm_prepare_console(); + + /* Notify old-style device drivers & userland */ ret = broadcast_sleep(PBOOK_SLEEP_REQUEST, PBOOK_SLEEP_REJECT); if (ret != PBOOK_SLEEP_OK) { - printk("pmu: sleep rejected\n"); + printk(KERN_ERR "Sleep rejected by drivers\n"); return -EBUSY; } /* Sync the disks. */ /* XXX It would be nice to have some way to ensure that - * nobody is dirtying any new buffers while we wait. - * BenH: Moved to _after_ sleep request and changed video - * drivers to vmalloc() during sleep request. This way, all - * vmalloc's are done before actual sleep of block drivers */ + * nobody is dirtying any new buffers while we wait. That + * could be acheived using the refrigerator for processes + * that swsusp uses + */ sys_sync(); /* Sleep can fail now. May not be very robust but useful for debugging */ ret = broadcast_sleep(PBOOK_SLEEP_NOW, PBOOK_WAKE); if (ret != PBOOK_SLEEP_OK) { - printk("pmu: sleep failed\n"); + printk(KERN_ERR "Driver sleep failed\n"); return -EBUSY; } - /* Wait for completion of async backlight requests */ - while (!bright_req_1.complete || !bright_req_2.complete || - !bright_req_3.complete || !batt_req.complete) - pmu_poll(); + /* Send suspend call to devices, hold the device core's dpm_sem */ + ret = device_suspend(PM_SUSPEND_MEM); + if (ret) { + printk(KERN_ERR "Driver sleep failed\n"); + broadcast_wake(); + return -EBUSY; + } - /* Turn off various things. Darwin does some retry tests here... */ - pmu_request(&req, NULL, 2, PMU_POWER_CTRL0, PMU_POW0_OFF|PMU_POW0_HARD_DRIVE); - while (!req.complete) - pmu_poll(); - pmu_request(&req, NULL, 2, PMU_POWER_CTRL, - PMU_POW_OFF|PMU_POW_BACKLIGHT|PMU_POW_IRLED|PMU_POW_MEDIABAY); - while (!req.complete) - pmu_poll(); - - /* Disable all interrupts */ - pmac_sleep_save_intrs(-1); - - /* Make sure the PMU is idle */ - while (pmu_state != idle) - pmu_poll(); - /* Make sure the decrementer won't interrupt us */ asm volatile("mtdec %0" : : "r" (0x7fffffff)); /* Make sure any pending DEC interrupt occurring while we did * the above didn't re-enable the DEC */ mb(); asm volatile("mtdec %0" : : "r" (0x7fffffff)); - - /* We can now disable MSR_EE */ + + /* We can now disable MSR_EE. This code of course works properly only + * on UP machines... For SMP, if we ever implement sleep, we'll have to + * stop the "other" CPUs way before we do all that stuff. + */ local_irq_disable(); - /* Giveup the FPU */ + /* Broadcast power down irq + * This isn't that useful in most cases (only directly wired devices can + * use this but still... This will take care of sysdev's as well, so + * we exit from here with local irqs disabled and PIC off. + */ + ret = device_power_down(PM_SUSPEND_MEM); + if (ret) { + wakeup_decrementer(); + local_irq_enable(); + device_resume(); + broadcast_wake(); + printk(KERN_ERR "Driver powerdown failed\n"); + return -EBUSY; + } + + /* Wait for completion of async backlight requests */ + while (!bright_req_1.complete || !bright_req_2.complete || + !bright_req_3.complete || !batt_req.complete) + pmu_poll(); + + /* Giveup the lazy FPU & vec so we don't have to back them + * up from the low level code + */ enable_kernel_fp(); +#ifdef CONFIG_ALTIVEC + if (cur_cpu_spec[0]->cpu_features & CPU_FTR_ALTIVEC) + enable_kernel_altivec(); +#endif /* CONFIG_ALTIVEC */ + + return 0; +} + +static int __pmac +pmac_wakeup_devices(void) +{ + mdelay(100); + + /* Power back up system devices (including the PIC) */ + device_power_up(); + + pmu_blink(1); + + /* Force a poll of ADB interrupts */ + adb_int_pending = 1; + via_pmu_interrupt(0, 0, 0); + + /* Restart jiffies & scheduling */ + wakeup_decrementer(); + + /* Re-enable local CPU interrupts */ + local_irq_enable(); + + pmu_blink(1); + + /* Resume devices */ + device_resume(); + + /* Notify old style drivers */ + broadcast_wake(); + + pm_restore_console(); + + return 0; +} + +#define GRACKLE_PM (1<<7) +#define GRACKLE_DOZE (1<<5) +#define GRACKLE_NAP (1<<4) +#define GRACKLE_SLEEP (1<<3) + +int __pmac +powerbook_sleep_grackle(void) +{ + unsigned long save_l2cr; + unsigned short pmcr1; + struct adb_request req; + int ret; + struct pci_dev *grackle; + + grackle = pci_find_slot(0, 0); + if (!grackle) + return -ENODEV; + + ret = pmac_suspend_devices(); + if (ret) { + printk(KERN_ERR "Sleep rejected by devices\n"); + return ret; + } + + /* Turn off various things. Darwin does some retry tests here... */ + pmu_request(&req, NULL, 2, PMU_POWER_CTRL0, PMU_POW0_OFF|PMU_POW0_HARD_DRIVE); + pmu_wait_complete(&req); + pmu_request(&req, NULL, 2, PMU_POWER_CTRL, + PMU_POW_OFF|PMU_POW_BACKLIGHT|PMU_POW_IRLED|PMU_POW_MEDIABAY); + pmu_wait_complete(&req); + /* For 750, save backside cache setting and disable it */ save_l2cr = _get_L2CR(); /* (returns -1 if not available) */ if (save_l2cr != 0xffffffff && (save_l2cr & L2CR_L2E) != 0) _set_L2CR(save_l2cr & 0x7fffffff); - /* Ask the PMU to put us to sleep */ - pmu_request(&req, NULL, 5, PMU_SLEEP, 'M', 'A', 'T', 'T'); - while (!req.complete) - pmu_poll(); + if (!__fake_sleep) { + /* Ask the PMU to put us to sleep */ + pmu_request(&req, NULL, 5, PMU_SLEEP, 'M', 'A', 'T', 'T'); + pmu_wait_complete(&req); + } /* The VIA is supposed not to be restored correctly*/ save_via_state(); @@ -1982,7 +2461,10 @@ pci_write_config_word(grackle, 0x70, pmcr1); /* Call low-level ASM sleep handler */ - low_sleep_handler(); + if (__fake_sleep) + mdelay(5000); + else + low_sleep_handler(); /* We're awake again, stop grackle PM */ pci_read_config_word(grackle, 0x70, &pmcr1); @@ -2001,36 +2483,17 @@ set_context(current->active_mm->context, current->active_mm->pgd); /* Power things up */ - pmu_request(&req, NULL, 2, PMU_SET_INTR_MASK, 0xfc); - while (!req.complete) - pmu_poll(); + pmu_unlock(); + pmu_request(&req, NULL, 2, PMU_SET_INTR_MASK, pmu_intr_mask); + pmu_wait_complete(&req); pmu_request(&req, NULL, 2, PMU_POWER_CTRL0, PMU_POW0_ON|PMU_POW0_HARD_DRIVE); - while (!req.complete) - pmu_poll(); + pmu_wait_complete(&req); pmu_request(&req, NULL, 2, PMU_POWER_CTRL, PMU_POW_ON|PMU_POW_BACKLIGHT|PMU_POW_CHARGER|PMU_POW_IRLED|PMU_POW_MEDIABAY); - while (!req.complete) - pmu_poll(); - - /* reenable interrupt controller */ - pmac_sleep_restore_intrs(); + pmu_wait_complete(&req); - /* Leave some time for HW to settle down */ - mdelay(100); - - /* Restart jiffies & scheduling */ - wakeup_decrementer(); - - /* Force a poll of ADB interrupts */ - adb_int_pending = 1; - via_pmu_interrupt(0, 0, 0); - - /* Re-enable local CPU interrupts */ - local_irq_enable(); - - /* Notify drivers */ - broadcast_wake(); + pmac_wakeup_devices(); return 0; } @@ -2048,68 +2511,20 @@ return -ENOSYS; } - /* Notify device drivers */ - ret = broadcast_sleep(PBOOK_SLEEP_REQUEST, PBOOK_SLEEP_REJECT); - if (ret != PBOOK_SLEEP_OK) { - printk("pmu: sleep rejected\n"); - return -EBUSY; - } - - /* Sync the disks. */ - /* XXX It would be nice to have some way to ensure that - * nobody is dirtying any new buffers while we wait. - * BenH: Moved to _after_ sleep request and changed video - * drivers to vmalloc() during sleep request. This way, all - * vmalloc's are done before actual sleep of block drivers */ - sys_sync(); - - /* Sleep can fail now. May not be very robust but useful for debugging */ - ret = broadcast_sleep(PBOOK_SLEEP_NOW, PBOOK_WAKE); - if (ret != PBOOK_SLEEP_OK) { - printk("pmu: sleep failed\n"); - return -EBUSY; + ret = pmac_suspend_devices(); + if (ret) { + printk(KERN_ERR "Sleep rejected by devices\n"); + return ret; } - /* Wait for completion of async backlight requests */ - while (!bright_req_1.complete || !bright_req_2.complete || - !bright_req_3.complete || !batt_req.complete) - pmu_poll(); - + /* Tell PMU what events will wake us up */ pmu_request(&req, NULL, 4, PMU_POWER_EVENTS, PMU_PWR_CLR_WAKEUP_EVENTS, 0xff, 0xff); - while (!req.complete) - pmu_poll(); - + pmu_wait_complete(&req); pmu_request(&req, NULL, 4, PMU_POWER_EVENTS, PMU_PWR_SET_WAKEUP_EVENTS, 0, PMU_PWR_WAKEUP_KEY | (option_lid_wakeup ? PMU_PWR_WAKEUP_LID_OPEN : 0)); - while (!req.complete) - pmu_poll(); - - /* Save & disable all interrupts */ - openpic_sleep_save_intrs(); - - /* Make sure the PMU is idle */ - while (pmu_state != idle) - pmu_poll(); - - /* Make sure the decrementer won't interrupt us */ - asm volatile("mtdec %0" : : "r" (0x7fffffff)); - /* Make sure any pending DEC interrupt occurring while we did - * the above didn't re-enable the DEC */ - mb(); - asm volatile("mtdec %0" : : "r" (0x7fffffff)); - - /* We can now disable MSR_EE */ - local_irq_disable(); - - /* Giveup the FPU & vec */ - enable_kernel_fp(); - -#ifdef CONFIG_ALTIVEC - if (cur_cpu_spec[0]->cpu_features & CPU_FTR_ALTIVEC) - enable_kernel_altivec(); -#endif /* CONFIG_ALTIVEC */ + pmu_wait_complete(&req); /* Save & disable L2 and L3 caches*/ save_l3cr = _get_L3CR(); /* (returns -1 if not available) */ @@ -2125,13 +2540,9 @@ if (!__fake_sleep) { /* Ask the PMU to put us to sleep */ pmu_request(&req, NULL, 5, PMU_SLEEP, 'M', 'A', 'T', 'T'); - while (!req.complete && pmu_state != idle) - pmu_poll(); + pmu_wait_complete(&req); } - out_8(&via[B], in_8(&via[B]) | TREQ); - wait_for_ack(); - /* The VIA is supposed not to be restored correctly*/ save_via_state(); @@ -2161,8 +2572,6 @@ /* Don't restore PCI for now, it crashes. Maybe unnecessary on pbook */ //pbook_pci_restore(); - pmu_blink(2); - /* Restore L2 cache */ if (save_l2cr != 0xffffffff && (save_l2cr & L2CR_L2E) != 0) _set_L2CR(save_l2cr); @@ -2174,31 +2583,15 @@ set_context(current->active_mm->context, current->active_mm->pgd); /* Tell PMU we are ready */ + pmu_unlock(); pmu_request(&req, NULL, 2, PMU_SYSTEM_READY, 2); - while (!req.complete) - pmu_poll(); - pmu_request(&req, NULL, 2, PMU_SET_INTR_MASK, 0xfc); - while (!req.complete) - pmu_poll(); - - /* reenable interrupt controller */ - openpic_sleep_restore_intrs(); - - /* Leave some time for HW to settle down */ - mdelay(100); - - /* Restart jiffies & scheduling */ - wakeup_decrementer(); + pmu_wait_complete(&req); + pmu_request(&req, NULL, 2, PMU_SET_INTR_MASK, pmu_intr_mask); + pmu_wait_complete(&req); - /* Force a poll of ADB interrupts */ - adb_int_pending = 1; - via_pmu_interrupt(0, 0, 0); + pmu_blink(1); - /* Re-enable local CPU interrupts */ - local_irq_enable(); - - /* Notify drivers */ - broadcast_wake(); + pmac_wakeup_devices(); return 0; } @@ -2227,45 +2620,13 @@ /* Allocate room for PCI save */ pbook_alloc_pci_save(); - /* Notify device drivers */ - ret = broadcast_sleep(PBOOK_SLEEP_REQUEST, PBOOK_SLEEP_REJECT); - if (ret != PBOOK_SLEEP_OK) { - pbook_free_pci_save(); - printk("pmu: sleep rejected\n"); - return -EBUSY; - } - - /* Sync the disks. */ - /* XXX It would be nice to have some way to ensure that - * nobody is dirtying any new buffers while we wait. - * BenH: Moved to _after_ sleep request and changed video - * drivers to vmalloc() during sleep request. This way, all - * vmalloc's are done before actual sleep of block drivers */ - sys_sync(); - - /* Sleep can fail now. May not be very robust but useful for debugging */ - ret = broadcast_sleep(PBOOK_SLEEP_NOW, PBOOK_WAKE); - if (ret != PBOOK_SLEEP_OK) { - printk("pmu: sleep failed\n"); + ret = pmac_suspend_devices(); + if (ret) { pbook_free_pci_save(); - return -EBUSY; + printk(KERN_ERR "Sleep rejected by devices\n"); + return ret; } - /* Wait for completion of async backlight requests */ - while (!bright_req_1.complete || !bright_req_2.complete || - !bright_req_3.complete || !batt_req.complete) - pmu_poll(); - - /* Disable all interrupts except pmu */ - pmac_sleep_save_intrs(vias->intrs[0].line); - - /* Make sure the decrementer won't interrupt us */ - asm volatile("mtdec %0" : : "r" (0x7fffffff)); - /* Make sure any pending DEC interrupt occurring while we did - * the above didn't re-enable the DEC */ - mb(); - asm volatile("mtdec %0" : : "r" (0x7fffffff)); - /* Save the state of PCI config space for some slots */ pbook_pci_save(); @@ -2303,25 +2664,13 @@ out_be32(mem_ctrl_sleep, 0x3f); pmac_call_feature(PMAC_FTR_SLEEP_STATE,NULL,0,0); pbook_pci_restore(); + pmu_unlock(); /* wait for the PMU interrupt sequence to complete */ while (asleep) mb(); - /* reenable interrupts */ - pmac_sleep_restore_intrs(); - - /* Leave some time for HW to settle down */ - mdelay(100); - - /* Restart jiffies & scheduling */ - wakeup_decrementer(); - - /* Re-enable local CPU interrupts */ - local_irq_enable(); - - /* Notify drivers */ - broadcast_wake(); + pmac_wakeup_devices(); pbook_free_pci_save(); iounmap(mem_ctrl); @@ -2524,7 +2873,7 @@ break; case PMU_HEATHROW_BASED: case PMU_PADDINGTON_BASED: - error = powerbook_sleep_G3(); + error = powerbook_sleep_grackle(); break; case PMU_KEYLARGO_BASED: error = powerbook_sleep_Core99(); @@ -2676,8 +3025,15 @@ EXPORT_SYMBOL(pmu_request); EXPORT_SYMBOL(pmu_poll); +EXPORT_SYMBOL(pmu_poll_adb); +EXPORT_SYMBOL(pmu_wait_complete); EXPORT_SYMBOL(pmu_suspend); EXPORT_SYMBOL(pmu_resume); +EXPORT_SYMBOL(pmu_unlock); +EXPORT_SYMBOL(pmu_i2c_combined_read); +EXPORT_SYMBOL(pmu_i2c_stdsub_write); +EXPORT_SYMBOL(pmu_i2c_simple_read); +EXPORT_SYMBOL(pmu_i2c_simple_write); #ifdef CONFIG_PMAC_PBOOK EXPORT_SYMBOL(pmu_register_sleep_notifier); EXPORT_SYMBOL(pmu_unregister_sleep_notifier); diff -Nru a/drivers/md/md.c b/drivers/md/md.c --- a/drivers/md/md.c Tue Sep 2 19:58:14 2003 +++ b/drivers/md/md.c Tue Sep 2 19:58:14 2003 @@ -179,7 +179,6 @@ mddev_map[mdidx(mddev)] = NULL; blk_put_queue(mddev->queue); kfree(mddev); - MOD_DEC_USE_COUNT; } spin_unlock(&all_mddevs_lock); } @@ -201,7 +200,6 @@ mddev_map[unit] = new; list_add(&new->all_mddevs, &all_mddevs); spin_unlock(&all_mddevs_lock); - MOD_INC_USE_COUNT; return new; } spin_unlock(&all_mddevs_lock); @@ -640,14 +638,13 @@ /* make rdev->sb match mddev data.. * * 1/ zero out disks - * 2/ Add info for each disk, keeping track of highest desc_nr - * 3/ any empty disks < highest become removed + * 2/ Add info for each disk, keeping track of highest desc_nr (next_spare); + * 3/ any empty disks < next_spare become removed * * disks[0] gets initialised to REMOVED because * we cannot be sure from other fields if it has * been initialised or not. */ - int highest = 0; int i; int active=0, working=0,failed=0,spare=0,nr_disks=0; @@ -718,17 +715,17 @@ spare++; working++; } - if (rdev2->desc_nr > highest) - highest = rdev2->desc_nr; } - /* now set the "removed" bit on any non-trailing holes */ - for (i=0; iraid_disks ; i++) { mdp_disk_t *d = &sb->disks[i]; if (d->state == 0 && d->number == 0) { d->number = i; d->raid_disk = i; d->state = (1<state |= (1<nr_disks = nr_disks; @@ -1612,12 +1609,6 @@ spin_unlock(&pers_lock); blk_queue_make_request(mddev->queue, mddev->pers->make_request); - printk("%s: setting max_sectors to %d, segment boundary to %d\n", - disk->disk_name, - chunk_size >> 9, - (chunk_size>>1)-1); - blk_queue_max_sectors(mddev->queue, chunk_size >> 9); - blk_queue_segment_boundary(mddev->queue, (chunk_size>>1) - 1); mddev->queue->queuedata = mddev; err = mddev->pers->run(mddev); @@ -2366,17 +2357,14 @@ unsigned int cmd, unsigned long arg) { char b[BDEVNAME_SIZE]; - unsigned int minor; + unsigned int minor = iminor(inode); int err = 0; struct hd_geometry *loc = (struct hd_geometry *) arg; mddev_t *mddev = NULL; - kdev_t dev; if (!capable(CAP_SYS_ADMIN)) return -EACCES; - dev = inode->i_rdev; - minor = minor(dev); if (minor >= MAX_MD_DEVS) { MD_BUG(); return -EINVAL; @@ -2615,7 +2603,7 @@ /* * Succeed if we can find or allocate a mddev structure. */ - mddev_t *mddev = mddev_find(minor(inode->i_rdev)); + mddev_t *mddev = mddev_find(iminor(inode)); int err = -ENOMEM; if (!mddev) @@ -3590,6 +3578,7 @@ if (!disks[i]) continue; mddev = disk->private_data; + export_array(mddev); del_gendisk(disk); put_disk(disk); mddev_put(mddev); diff -Nru a/drivers/md/raid0.c b/drivers/md/raid0.c --- a/drivers/md/raid0.c Tue Sep 2 19:58:16 2003 +++ b/drivers/md/raid0.c Tue Sep 2 19:58:16 2003 @@ -231,6 +231,13 @@ mdk_rdev_t *rdev; struct list_head *tmp; + printk("md%d: setting max_sectors to %d, segment boundary to %d\n", + mdidx(mddev), + mddev->chunk_size >> 9, + (mddev->chunk_size>>1)-1); + blk_queue_max_sectors(mddev->queue, mddev->chunk_size >> 9); + blk_queue_segment_boundary(mddev->queue, (mddev->chunk_size>>1) - 1); + conf = kmalloc(sizeof (raid0_conf_t), GFP_KERNEL); if (!conf) goto out; diff -Nru a/drivers/md/raid5.c b/drivers/md/raid5.c --- a/drivers/md/raid5.c Tue Sep 2 19:58:14 2003 +++ b/drivers/md/raid5.c Tue Sep 2 19:58:14 2003 @@ -1326,7 +1326,7 @@ (unsigned long long)new_sector, (unsigned long long)logical_sector); - sh = get_active_stripe(conf, new_sector, pd_idx, 0/*(bi->bi_rw&RWA_MASK)*/); + sh = get_active_stripe(conf, new_sector, pd_idx, (bi->bi_rw&RWA_MASK)); if (sh) { add_stripe_bio(sh, bi, dd_idx, (bi->bi_rw&RW_MASK)); @@ -1334,7 +1334,12 @@ raid5_plug_device(conf); handle_stripe(sh); release_stripe(sh); + } else { + /* cannot get stripe for read-ahead, just give-up */ + clear_bit(BIO_UPTODATE, &bi->bi_flags); + break; } + } spin_lock_irq(&conf->device_lock); if (--bi->bi_phys_segments == 0) { diff -Nru a/drivers/md/xor.c b/drivers/md/xor.c --- a/drivers/md/xor.c Tue Sep 2 19:58:16 2003 +++ b/drivers/md/xor.c Tue Sep 2 19:58:16 2003 @@ -134,7 +134,10 @@ return 0; } +static __exit void xor_exit(void) { } + EXPORT_SYMBOL(xor_block); MODULE_LICENSE("GPL"); module_init(calibrate_xor_block); +module_exit(xor_exit); diff -Nru a/drivers/media/common/saa7146_fops.c b/drivers/media/common/saa7146_fops.c --- a/drivers/media/common/saa7146_fops.c Tue Sep 2 19:58:16 2003 +++ b/drivers/media/common/saa7146_fops.c Tue Sep 2 19:58:16 2003 @@ -157,7 +157,7 @@ static int fops_open(struct inode *inode, struct file *file) { - unsigned int minor = minor(inode->i_rdev); + unsigned int minor = iminor(inode); struct saa7146_dev *h = NULL, *dev = NULL; struct list_head *list; struct saa7146_fh *fh = NULL; diff -Nru a/drivers/media/common/saa7146_video.c b/drivers/media/common/saa7146_video.c --- a/drivers/media/common/saa7146_video.c Tue Sep 2 19:58:17 2003 +++ b/drivers/media/common/saa7146_video.c Tue Sep 2 19:58:17 2003 @@ -359,41 +359,41 @@ static struct v4l2_queryctrl controls[] = { { - id: V4L2_CID_BRIGHTNESS, - name: "Brightness", - minimum: 0, - maximum: 255, - step: 1, - default_value: 128, - type: V4L2_CTRL_TYPE_INTEGER, + .id = V4L2_CID_BRIGHTNESS, + .name = "Brightness", + .minimum = 0, + .maximum = 255, + .step = 1, + .default_value = 128, + .type = V4L2_CTRL_TYPE_INTEGER, },{ - id: V4L2_CID_CONTRAST, - name: "Contrast", - minimum: 0, - maximum: 127, - step: 1, - default_value: 64, - type: V4L2_CTRL_TYPE_INTEGER, + .id = V4L2_CID_CONTRAST, + .name = "Contrast", + .minimum = 0, + .maximum = 127, + .step = 1, + .default_value = 64, + .type = V4L2_CTRL_TYPE_INTEGER, },{ - id: V4L2_CID_SATURATION, - name: "Saturation", - minimum: 0, - maximum: 127, - step: 1, - default_value: 64, - type: V4L2_CTRL_TYPE_INTEGER, + .id = V4L2_CID_SATURATION, + .name = "Saturation", + .minimum = 0, + .maximum = 127, + .step = 1, + .default_value = 64, + .type = V4L2_CTRL_TYPE_INTEGER, },{ - id: V4L2_CID_VFLIP, - name: "Vertical flip", - minimum: 0, - maximum: 1, - type: V4L2_CTRL_TYPE_BOOLEAN, + .id = V4L2_CID_VFLIP, + .name = "Vertical flip", + .minimum = 0, + .maximum = 1, + .type = V4L2_CTRL_TYPE_BOOLEAN, },{ - id: V4L2_CID_HFLIP, - name: "Horizontal flip", - minimum: 0, - maximum: 1, - type: V4L2_CTRL_TYPE_BOOLEAN, + .id = V4L2_CID_HFLIP, + .name = "Horizontal flip", + .minimum = 0, + .maximum = 1, + .type = V4L2_CTRL_TYPE_BOOLEAN, }, }; static int NUM_CONTROLS = sizeof(controls)/sizeof(struct v4l2_queryctrl); diff -Nru a/drivers/media/dvb/dvb-core/dvbdev.c b/drivers/media/dvb/dvb-core/dvbdev.c --- a/drivers/media/dvb/dvb-core/dvbdev.c Tue Sep 2 19:58:14 2003 +++ b/drivers/media/dvb/dvb-core/dvbdev.c Tue Sep 2 19:58:14 2003 @@ -73,7 +73,7 @@ { struct dvb_device *dvbdev; - dvbdev = dvbdev_find_device (minor(inode->i_rdev)); + dvbdev = dvbdev_find_device (iminor(inode)); if (dvbdev && dvbdev->fops) { int err = 0; diff -Nru a/drivers/media/dvb/frontends/grundig_29504-401.c b/drivers/media/dvb/frontends/grundig_29504-401.c --- a/drivers/media/dvb/frontends/grundig_29504-401.c Tue Sep 2 19:58:13 2003 +++ b/drivers/media/dvb/frontends/grundig_29504-401.c Tue Sep 2 19:58:13 2003 @@ -37,15 +37,15 @@ struct dvb_frontend_info grundig_29504_401_info = { - name: "Grundig 29504-401", - type: FE_OFDM, -/* frequency_min: ???,*/ -/* frequency_max: ???,*/ - frequency_stepsize: 166666, -/* frequency_tolerance: ???,*/ -/* symbol_rate_tolerance: ???,*/ - notifier_delay: 0, - caps: FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | + .name = "Grundig 29504-401", + .type = FE_OFDM, +/* .frequency_min = ???,*/ +/* .frequency_max = ???,*/ + .frequency_stepsize = 166666, +/* .frequency_tolerance = ???,*/ +/* .symbol_rate_tolerance = ???,*/ + .notifier_delay = 0, + .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_MUTE_TS /*| FE_CAN_CLEAN_SETUP*/ diff -Nru a/drivers/media/dvb/frontends/ves1820.c b/drivers/media/dvb/frontends/ves1820.c --- a/drivers/media/dvb/frontends/ves1820.c Tue Sep 2 19:58:16 2003 +++ b/drivers/media/dvb/frontends/ves1820.c Tue Sep 2 19:58:16 2003 @@ -81,9 +81,9 @@ .symbol_rate_min = (XIN/2)/64, /* SACLK/64 == (XIN/2)/64 */ .symbol_rate_max = (XIN/2)/4, /* SACLK/4 */ #if 0 - frequency_tolerance: ???, - symbol_rate_tolerance: ???, /* ppm */ /* == 8% (spec p. 5) */ - notifier_delay: ?, + .frequency_tolerance = ???, + .symbol_rate_tolerance = ???, /* ppm */ /* == 8% (spec p. 5) */ + .notifier_delay = ?, #endif .caps = FE_CAN_QAM_16 | FE_CAN_QAM_32 | FE_CAN_QAM_64 | FE_CAN_QAM_128 | FE_CAN_QAM_256 | diff -Nru a/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c b/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c --- a/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c Tue Sep 2 19:58:19 2003 +++ b/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c Tue Sep 2 19:58:19 2003 @@ -1249,7 +1249,7 @@ if ((err = usb_register(&ttusb_driver)) < 0) { printk("%s: usb_register failed! Error number %d", __FILE__, err); - return -1; + return err; } return 0; diff -Nru a/drivers/media/dvb/ttusb-dec/dec2000_frontend.c b/drivers/media/dvb/ttusb-dec/dec2000_frontend.c --- a/drivers/media/dvb/ttusb-dec/dec2000_frontend.c Tue Sep 2 19:58:19 2003 +++ b/drivers/media/dvb/ttusb-dec/dec2000_frontend.c Tue Sep 2 19:58:19 2003 @@ -30,12 +30,12 @@ #define dprintk if (debug) printk static struct dvb_frontend_info dec2000_frontend_info = { - name: "TechnoTrend/Hauppauge DEC-2000-t Frontend", - type: FE_OFDM, - frequency_min: 51000000, - frequency_max: 858000000, - frequency_stepsize: 62500, - caps: FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | + .name = "TechnoTrend/Hauppauge DEC-2000-t Frontend", + .type = FE_OFDM, + .frequency_min = 51000000, + .frequency_max = 858000000, + .frequency_stepsize = 62500, + .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO | FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_GUARD_INTERVAL_AUTO | diff -Nru a/drivers/media/dvb/ttusb-dec/ttusb_dec.c b/drivers/media/dvb/ttusb-dec/ttusb_dec.c --- a/drivers/media/dvb/ttusb-dec/ttusb_dec.c Tue Sep 2 19:58:18 2003 +++ b/drivers/media/dvb/ttusb-dec/ttusb_dec.c Tue Sep 2 19:58:18 2003 @@ -1003,10 +1003,10 @@ }; static struct usb_driver ttusb_dec_driver = { - name: DRIVER_NAME, - probe: ttusb_dec_probe, - disconnect: ttusb_dec_disconnect, - id_table: ttusb_dec_table, + .name = DRIVER_NAME, + .probe = ttusb_dec_probe, + .disconnect = ttusb_dec_disconnect, + .id_table = ttusb_dec_table, }; static int __init ttusb_dec_init(void) diff -Nru a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig --- a/drivers/media/video/Kconfig Tue Sep 2 19:58:19 2003 +++ b/drivers/media/video/Kconfig Tue Sep 2 19:58:19 2003 @@ -201,7 +201,7 @@ config VIDEO_ZR36120 tristate "Zoran ZR36120/36125 Video For Linux" - depends on VIDEO_DEV && PCI && I2C + depends on VIDEO_DEV && PCI && I2C && BROKEN help Support for ZR36120/ZR36125 based frame grabber/overlay boards. This includes the Victor II, WaveWatcher, Video Wonder, Maxi-TV, diff -Nru a/drivers/media/video/adv7170.c b/drivers/media/video/adv7170.c --- a/drivers/media/video/adv7170.c Tue Sep 2 19:58:19 2003 +++ b/drivers/media/video/adv7170.c Tue Sep 2 19:58:19 2003 @@ -104,6 +104,7 @@ u8 value) { struct adv7170 *encoder = i2c_get_clientdata(client); + encoder->reg[reg] = value; return i2c_smbus_write_byte_data(client, reg, value); } @@ -130,6 +131,7 @@ struct adv7170 *encoder = i2c_get_clientdata(client); struct i2c_msg msg; u8 block_data[32]; + msg.addr = client->addr; msg.flags = client->flags; while (len >= 2) { @@ -143,16 +145,16 @@ data += 2; } while (len >= 2 && data[0] == reg && msg.len < 32); - if ((ret = - i2c_transfer(client->adapter, &msg, 1)) < 0) + if ((ret = i2c_transfer(client->adapter, + &msg, 1)) < 0) break; } } else { /* do some slow I2C emulation kind of thing */ while (len >= 2) { reg = *data++; - if ((ret = - adv7170_write(client, reg, *data++)) < 0) + if ((ret = adv7170_write(client, reg, + *data++)) < 0) break; len -= 2; } @@ -442,6 +444,7 @@ dname = adv7171_name; } else { /* We should never get here!!! */ + kfree(client); return 0; } snprintf(I2C_NAME(client), sizeof(I2C_NAME(client)) - 1, @@ -449,6 +452,7 @@ encoder = kmalloc(sizeof(struct adv7170), GFP_KERNEL); if (encoder == NULL) { + kfree(client); return -ENOMEM; } memset(encoder, 0, sizeof(struct adv7170)); diff -Nru a/drivers/media/video/adv7175.c b/drivers/media/video/adv7175.c --- a/drivers/media/video/adv7175.c Tue Sep 2 19:58:19 2003 +++ b/drivers/media/video/adv7175.c Tue Sep 2 19:58:19 2003 @@ -100,6 +100,7 @@ u8 value) { struct adv7175 *encoder = i2c_get_clientdata(client); + encoder->reg[reg] = value; return i2c_smbus_write_byte_data(client, reg, value); } @@ -126,6 +127,7 @@ struct adv7175 *encoder = i2c_get_clientdata(client); struct i2c_msg msg; u8 block_data[32]; + msg.addr = client->addr; msg.flags = client->flags; while (len >= 2) { @@ -139,16 +141,16 @@ data += 2; } while (len >= 2 && data[0] == reg && msg.len < 32); - if ((ret = - i2c_transfer(client->adapter, &msg, 1)) < 0) + if ((ret = i2c_transfer(client->adapter, + &msg, 1)) < 0) break; } } else { /* do some slow I2C emulation kind of thing */ while (len >= 2) { reg = *data++; - if ((ret = - adv7175_write(client, reg, *data++)) < 0) + if ((ret = adv7175_write(client, reg, + *data++)) < 0) break; len -= 2; } @@ -163,6 +165,7 @@ { struct adv7175 *encoder = i2c_get_clientdata(client); int i, j; + printk(KERN_INFO "%s: registry dump\n", I2C_NAME(client)); for (i = 0; i < 182 / 8; i++) { printk("%s: 0x%02x -", I2C_NAME(client), i * 8); @@ -463,6 +466,7 @@ dname = adv7176_name; } else { /* We should never get here!!! */ + kfree(client); return 0; } snprintf(I2C_NAME(client), sizeof(I2C_NAME(client)) - 1, @@ -470,6 +474,7 @@ encoder = kmalloc(sizeof(struct adv7175), GFP_KERNEL); if (encoder == NULL) { + kfree(client); return -ENOMEM; } memset(encoder, 0, sizeof(struct adv7175)); diff -Nru a/drivers/media/video/bt819.c b/drivers/media/video/bt819.c --- a/drivers/media/video/bt819.c Tue Sep 2 19:58:13 2003 +++ b/drivers/media/video/bt819.c Tue Sep 2 19:58:13 2003 @@ -113,6 +113,7 @@ u8 value) { struct bt819 *decoder = i2c_get_clientdata(client); + decoder->reg[reg] = value; return i2c_smbus_write_byte_data(client, reg, value); } @@ -124,6 +125,7 @@ u8 value) { struct bt819 *decoder = i2c_get_clientdata(client); + return bt819_write(client, reg, (decoder-> reg[reg] & ~(1 << bit)) | @@ -145,6 +147,7 @@ struct bt819 *decoder = i2c_get_clientdata(client); struct i2c_msg msg; u8 block_data[32]; + msg.addr = client->addr; msg.flags = client->flags; while (len >= 2) { @@ -158,8 +161,8 @@ data += 2; } while (len >= 2 && data[0] == reg && msg.len < 32); - if ((ret = - i2c_transfer(client->adapter, &msg, 1)) < 0) + if ((ret = i2c_transfer(client->adapter, + &msg, 1)) < 0) break; } } else { diff -Nru a/drivers/media/video/bt856.c b/drivers/media/video/bt856.c --- a/drivers/media/video/bt856.c Tue Sep 2 19:58:12 2003 +++ b/drivers/media/video/bt856.c Tue Sep 2 19:58:12 2003 @@ -98,6 +98,7 @@ u8 value) { struct bt856 *encoder = i2c_get_clientdata(client); + encoder->reg[reg - REG_OFFSET] = value; return i2c_smbus_write_byte_data(client, reg, value); } @@ -109,6 +110,7 @@ u8 value) { struct bt856 *encoder = i2c_get_clientdata(client); + return bt856_write(client, reg, (encoder-> reg[reg - REG_OFFSET] & ~(1 << bit)) | @@ -120,6 +122,7 @@ { int i; struct bt856 *encoder = i2c_get_clientdata(client); + printk(KERN_INFO "%s: register dump:", I2C_NAME(client)); for (i = 0xd6; i <= 0xde; i += 2) printk(" %02x", encoder->reg[i - REG_OFFSET]); @@ -341,6 +344,7 @@ encoder = kmalloc(sizeof(struct bt856), GFP_KERNEL); if (encoder == NULL) { + kfree(client); return -ENOMEM; } memset(encoder, 0, sizeof(struct bt856)); diff -Nru a/drivers/media/video/bttv-driver.c b/drivers/media/video/bttv-driver.c --- a/drivers/media/video/bttv-driver.c Tue Sep 2 19:58:18 2003 +++ b/drivers/media/video/bttv-driver.c Tue Sep 2 19:58:18 2003 @@ -2758,7 +2758,7 @@ static int bttv_open(struct inode *inode, struct file *file) { - int minor = minor(inode->i_rdev); + int minor = iminor(inode); struct bttv *btv = NULL; struct bttv_fh *fh; enum v4l2_buf_type type = 0; @@ -2894,7 +2894,7 @@ static int radio_open(struct inode *inode, struct file *file) { - int minor = minor(inode->i_rdev); + int minor = iminor(inode); struct bttv *btv = NULL; u32 v = 400*16; unsigned int i; diff -Nru a/drivers/media/video/meye.c b/drivers/media/video/meye.c --- a/drivers/media/video/meye.c Tue Sep 2 19:58:16 2003 +++ b/drivers/media/video/meye.c Tue Sep 2 19:58:16 2003 @@ -920,7 +920,7 @@ case VIDIOCGCAP: { struct video_capability *b = arg; - strcpy(b->name,meye.video_dev.name); + strcpy(b->name,meye.video_dev->name); b->type = VID_TYPE_CAPTURE; b->channels = 1; b->audios = 0; @@ -1225,6 +1225,8 @@ .type = VID_TYPE_CAPTURE, .hardware = VID_HARDWARE_MEYE, .fops = &meye_fops, + .release = video_device_release, + .minor = -1, }; #ifdef CONFIG_PM @@ -1275,10 +1277,17 @@ goto out1; } - sonypi_camera_command(SONYPI_COMMAND_SETCAMERA, 1); - meye.mchip_dev = pcidev; - memcpy(&meye.video_dev, &meye_template, sizeof(meye_template)); + meye.video_dev = video_device_alloc(); + if (!meye.video_dev) { + printk(KERN_ERR "meye: video_device_alloc() failed!\n"); + ret = -EBUSY; + goto out1; + } + memcpy(meye.video_dev, &meye_template, sizeof(meye_template)); + meye.video_dev->dev = &meye.mchip_dev->dev; + + sonypi_camera_command(SONYPI_COMMAND_SETCAMERA, 1); if ((ret = pci_enable_device(meye.mchip_dev))) { printk(KERN_ERR "meye: pci_enable_device failed\n"); @@ -1335,7 +1344,7 @@ wait_ms(1); mchip_set(MCHIP_MM_INTA, MCHIP_MM_INTA_HIC_1_MASK); - if (video_register_device(&meye.video_dev, VFL_TYPE_GRABBER, video_nr) < 0) { + if (video_register_device(meye.video_dev, VFL_TYPE_GRABBER, video_nr) < 0) { printk(KERN_ERR "meye: video_register_device failed\n"); ret = -EIO; @@ -1383,6 +1392,9 @@ out3: pci_disable_device(meye.mchip_dev); out2: + video_device_release(meye.video_dev); + meye.video_dev = NULL; + sonypi_camera_command(SONYPI_COMMAND_SETCAMERA, 0); out1: return ret; @@ -1390,7 +1402,7 @@ static void __devexit meye_remove(struct pci_dev *pcidev) { - video_unregister_device(&meye.video_dev); + video_unregister_device(meye.video_dev); mchip_hic_stop(); diff -Nru a/drivers/media/video/meye.h b/drivers/media/video/meye.h --- a/drivers/media/video/meye.h Tue Sep 2 19:58:16 2003 +++ b/drivers/media/video/meye.h Tue Sep 2 19:58:16 2003 @@ -312,7 +312,7 @@ struct meye_queue grabq; /* queue for buffers to be grabbed */ - struct video_device video_dev; /* video device parameters */ + struct video_device *video_dev; /* video device parameters */ struct video_picture picture; /* video picture parameters */ struct meye_params params; /* additional parameters */ #ifdef CONFIG_PM diff -Nru a/drivers/media/video/planb.c b/drivers/media/video/planb.c --- a/drivers/media/video/planb.c Tue Sep 2 19:58:18 2003 +++ b/drivers/media/video/planb.c Tue Sep 2 19:58:18 2003 @@ -2158,6 +2158,7 @@ unsigned int old_base, new_base; unsigned int irq; struct pci_dev *pdev; + int rc; if (_machine != _MACH_Pmac) return 0; @@ -2211,18 +2212,25 @@ pdev = pci_find_slot (bus, dev_fn); if (!pdev) { - printk(KERN_ERR "cannot find slot\n"); - /* XXX handle error */ + printk(KERN_ERR "planb: cannot find slot\n"); + goto err_out; } /* Enable response in memory space, bus mastering, use memory write and invalidate */ - pci_write_config_word (pdev, PCI_COMMAND, - PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER | - PCI_COMMAND_INVALIDATE); - /* Set PCI Cache line size & latency timer */ - pci_write_config_byte (pdev, PCI_CACHE_LINE_SIZE, 0x8); - pci_write_config_byte (pdev, PCI_LATENCY_TIMER, 0x40); + rc = pci_enable_device(pdev); + if (rc) { + printk(KERN_ERR "planb: cannot enable PCI device %s\n", + pci_name(pdev)); + goto err_out; + } + rc = pci_set_mwi(pdev); + if (rc) { + printk(KERN_ERR "planb: cannot enable MWI on PCI device %s\n", + pci_name(pdev)); + goto err_out_disable; + } + pci_set_master(pdev); /* Set the new base address */ pci_write_config_dword (pdev, confreg, new_base); @@ -2234,6 +2242,12 @@ pb->irq = irq; return planb_num; + +err_out_disable: + pci_disable_device(pdev); +err_out: + /* FIXME handle error */ /* comment moved from pci_find_slot, above */ + return 0; } static void release_planb(void) diff -Nru a/drivers/media/video/saa7110.c b/drivers/media/video/saa7110.c --- a/drivers/media/video/saa7110.c Tue Sep 2 19:58:12 2003 +++ b/drivers/media/video/saa7110.c Tue Sep 2 19:58:12 2003 @@ -86,6 +86,7 @@ u8 value) { struct saa7110 *decoder = i2c_get_clientdata(client); + decoder->reg[reg] = value; return i2c_smbus_write_byte_data(client, reg, value); } @@ -97,6 +98,7 @@ { int ret = -1; u8 reg = *data++; + len--; /* the saa7110 has an autoincrement function, use it if @@ -105,6 +107,7 @@ struct saa7110 *decoder = i2c_get_clientdata(client); struct i2c_msg msg; u8 block_data[54]; + msg.len = 0; msg.buf = (char *) block_data; msg.addr = client->addr; @@ -119,8 +122,8 @@ } } else { while (len-- >= 1) { - if ((ret = - saa7110_write(client, reg++, *data++)) < 0) + if ((ret = saa7110_write(client, reg++, + *data++)) < 0) break; } } @@ -279,6 +282,7 @@ case DECODER_GET_CAPABILITIES: { struct video_decoder_capability *dc = arg; + dc->flags = VIDEO_DECODER_PAL | VIDEO_DECODER_NTSC | VIDEO_DECODER_SECAM | VIDEO_DECODER_AUTO; diff -Nru a/drivers/media/video/saa7111.c b/drivers/media/video/saa7111.c --- a/drivers/media/video/saa7111.c Tue Sep 2 19:58:15 2003 +++ b/drivers/media/video/saa7111.c Tue Sep 2 19:58:15 2003 @@ -93,6 +93,7 @@ u8 value) { struct saa7111 *decoder = i2c_get_clientdata(client); + decoder->reg[reg] = value; return i2c_smbus_write_byte_data(client, reg, value); } @@ -112,6 +113,7 @@ struct saa7111 *decoder = i2c_get_clientdata(client); struct i2c_msg msg; u8 block_data[32]; + msg.addr = client->addr; msg.flags = client->flags; while (len >= 2) { @@ -125,16 +127,16 @@ data += 2; } while (len >= 2 && data[0] == reg && msg.len < 32); - if ((ret = - i2c_transfer(client->adapter, &msg, 1)) < 0) + if ((ret = i2c_transfer(client->adapter, + &msg, 1)) < 0) break; } } else { /* do some slow I2C emulation kind of thing */ while (len >= 2) { reg = *data++; - if ((ret = - saa7111_write(client, reg, *data++)) < 0) + if ((ret = saa7111_write(client, reg, + *data++)) < 0) break; len -= 2; } diff -Nru a/drivers/media/video/saa7114.c b/drivers/media/video/saa7114.c --- a/drivers/media/video/saa7114.c Tue Sep 2 19:58:18 2003 +++ b/drivers/media/video/saa7114.c Tue Sep 2 19:58:18 2003 @@ -144,6 +144,7 @@ u8 value) { /*struct saa7114 *decoder = i2c_get_clientdata(client);*/ + /*decoder->reg[reg] = value;*/ return i2c_smbus_write_byte_data(client, reg, value); } @@ -163,6 +164,7 @@ /*struct saa7114 *decoder = i2c_get_clientdata(client);*/ struct i2c_msg msg; u8 block_data[32]; + msg.addr = client->addr; msg.flags = client->flags; while (len >= 2) { @@ -176,16 +178,16 @@ data += 2; } while (len >= 2 && data[0] == reg && msg.len < 32); - if ((ret = - i2c_transfer(client->adapter, &msg, 1)) < 0) + if ((ret = i2c_transfer(client->adapter, + &msg, 1)) < 0) break; } } else { /* do some slow I2C emulation kind of thing */ while (len >= 2) { reg = *data++; - if ((ret = - saa7114_write(client, reg, *data++)) < 0) + if ((ret = saa7114_write(client, reg, + *data++)) < 0) break; len -= 2; } @@ -995,6 +997,8 @@ KERN_ERR "%s_attach: init error %d at stage %d, leaving attach.\n", I2C_NAME(client), i, err[i]); + kfree(decoder); + kfree(client); return 0; } } @@ -1022,6 +1026,8 @@ KERN_ERR "%s_attach: init error %d at stage %d, leaving attach.\n", I2C_NAME(client), i, err[i]); + kfree(decoder); + kfree(client); return 0; } } @@ -1068,6 +1074,8 @@ KERN_ERR "%s_attach: init error %d at stage %d, leaving attach.\n", I2C_NAME(client), i, err[i]); + kfree(decoder); + kfree(client); return 0; } } @@ -1107,6 +1115,8 @@ KERN_ERR "%s_attach: init error %d at stage %d, leaving attach.\n", I2C_NAME(client), i, err[i]); + kfree(decoder); + kfree(client); return 0; } } @@ -1127,6 +1137,8 @@ KERN_ERR "%s_attach: init error %d at stage %d, leaving attach.\n", I2C_NAME(client), i, err[i]); + kfree(decoder); + kfree(client); return 0; } } diff -Nru a/drivers/media/video/saa7134/saa7134-oss.c b/drivers/media/video/saa7134/saa7134-oss.c --- a/drivers/media/video/saa7134/saa7134-oss.c Tue Sep 2 19:58:15 2003 +++ b/drivers/media/video/saa7134/saa7134-oss.c Tue Sep 2 19:58:15 2003 @@ -215,7 +215,7 @@ static int dsp_open(struct inode *inode, struct file *file) { - int minor = minor(inode->i_rdev); + int minor = iminor(inode); struct saa7134_dev *h,*dev = NULL; struct list_head *list; int err; @@ -598,7 +598,7 @@ static int mixer_open(struct inode *inode, struct file *file) { - int minor = minor(inode->i_rdev); + int minor = iminor(inode); struct saa7134_dev *h,*dev = NULL; struct list_head *list; diff -Nru a/drivers/media/video/saa7134/saa7134-ts.c b/drivers/media/video/saa7134/saa7134-ts.c --- a/drivers/media/video/saa7134/saa7134-ts.c Tue Sep 2 19:58:12 2003 +++ b/drivers/media/video/saa7134/saa7134-ts.c Tue Sep 2 19:58:12 2003 @@ -166,7 +166,7 @@ static int ts_open(struct inode *inode, struct file *file) { - int minor = minor(inode->i_rdev); + int minor = iminor(inode); struct saa7134_dev *h,*dev = NULL; struct list_head *list; int err; diff -Nru a/drivers/media/video/saa7134/saa7134-video.c b/drivers/media/video/saa7134/saa7134-video.c --- a/drivers/media/video/saa7134/saa7134-video.c Tue Sep 2 19:58:13 2003 +++ b/drivers/media/video/saa7134/saa7134-video.c Tue Sep 2 19:58:13 2003 @@ -1131,7 +1131,7 @@ static int video_open(struct inode *inode, struct file *file) { - int minor = minor(inode->i_rdev); + int minor = iminor(inode); struct saa7134_dev *h,*dev = NULL; struct saa7134_fh *fh; struct list_head *list; diff -Nru a/drivers/media/video/saa7185.c b/drivers/media/video/saa7185.c --- a/drivers/media/video/saa7185.c Tue Sep 2 19:58:12 2003 +++ b/drivers/media/video/saa7185.c Tue Sep 2 19:58:12 2003 @@ -98,6 +98,7 @@ u8 value) { struct saa7185 *encoder = i2c_get_clientdata(client); + dprintk(1, KERN_DEBUG "SAA7185: %02x set to %02x\n", reg, value); encoder->reg[reg] = value; return i2c_smbus_write_byte_data(client, reg, value); @@ -118,6 +119,7 @@ struct saa7185 *encoder = i2c_get_clientdata(client); struct i2c_msg msg; u8 block_data[32]; + msg.addr = client->addr; msg.flags = client->flags; while (len >= 2) { @@ -131,16 +133,16 @@ data += 2; } while (len >= 2 && data[0] == reg && msg.len < 32); - if ((ret = - i2c_transfer(client->adapter, &msg, 1)) < 0) + if ((ret = i2c_transfer(client->adapter, + &msg, 1)) < 0) break; } } else { /* do some slow I2C emulation kind of thing */ while (len >= 2) { reg = *data++; - if ((ret = - saa7185_write(client, reg, *data++)) < 0) + if ((ret = saa7185_write(client, reg, + *data++)) < 0) break; len -= 2; } @@ -434,6 +436,7 @@ encoder = kmalloc(sizeof(struct saa7185), GFP_KERNEL); if (encoder == NULL) { + kfree(client); return -ENOMEM; } memset(encoder, 0, sizeof(struct saa7185)); diff -Nru a/drivers/media/video/stradis.c b/drivers/media/video/stradis.c --- a/drivers/media/video/stradis.c Tue Sep 2 19:58:18 2003 +++ b/drivers/media/video/stradis.c Tue Sep 2 19:58:19 2003 @@ -1946,7 +1946,7 @@ static int saa_open(struct inode *inode, struct file *file) { struct saa7146 *saa = NULL; - unsigned int minor = minor(inode->i_rdev); + unsigned int minor = iminor(inode); int i; for (i = 0; i < SAA7146_MAX; i++) { diff -Nru a/drivers/media/video/tvmixer.c b/drivers/media/video/tvmixer.c --- a/drivers/media/video/tvmixer.c Tue Sep 2 19:58:18 2003 +++ b/drivers/media/video/tvmixer.c Tue Sep 2 19:58:18 2003 @@ -173,7 +173,7 @@ static int tvmixer_open(struct inode *inode, struct file *file) { - int i, minor = minor(inode->i_rdev); + int i, minor = iminor(inode); struct TVMIXER *mix = NULL; struct i2c_client *client = NULL; diff -Nru a/drivers/media/video/videodev.c b/drivers/media/video/videodev.c --- a/drivers/media/video/videodev.c Tue Sep 2 19:58:13 2003 +++ b/drivers/media/video/videodev.c Tue Sep 2 19:58:13 2003 @@ -99,7 +99,7 @@ struct video_device* video_devdata(struct file *file) { - return video_device[minor(file->f_dentry->d_inode->i_rdev)]; + return video_device[iminor(file->f_dentry->d_inode)]; } /* @@ -107,7 +107,7 @@ */ static int video_open(struct inode *inode, struct file *file) { - unsigned int minor = minor(inode->i_rdev); + unsigned int minor = iminor(inode); int err = 0; struct video_device *vfl; struct file_operations *old_fops; @@ -349,9 +349,9 @@ if(video_device[vfd->minor]!=vfd) panic("videodev: bad unregister"); - class_device_unregister(&vfd->class_dev); devfs_remove(vfd->devfs_name); video_device[vfd->minor]=NULL; + class_device_unregister(&vfd->class_dev); up(&videodev_lock); } diff -Nru a/drivers/media/video/vpx3220.c b/drivers/media/video/vpx3220.c --- a/drivers/media/video/vpx3220.c Tue Sep 2 19:58:16 2003 +++ b/drivers/media/video/vpx3220.c Tue Sep 2 19:58:16 2003 @@ -76,6 +76,7 @@ u8 value) { struct vpx3220 *decoder = i2c_get_clientdata(client); + decoder->reg[reg] = value; return i2c_smbus_write_byte_data(client, reg, value); } @@ -294,6 +295,7 @@ { int len = sizeof(init_common); const unsigned char *data = init_common; + while (len > 1) { dprintk(1, KERN_DEBUG "vpx3216b i2c reg 0x%02x data 0x%02x\n", diff -Nru a/drivers/media/video/zoran.h b/drivers/media/video/zoran.h --- a/drivers/media/video/zoran.h Tue Sep 2 19:58:17 2003 +++ b/drivers/media/video/zoran.h Tue Sep 2 19:58:17 2003 @@ -146,7 +146,7 @@ #define ZORAN_NAME "ZORAN" /* name of the device */ -#define ZR_DEVNAME(zr) pci_name((zr)->pci_dev) +#define ZR_DEVNAME(zr) ((zr)->name) #define BUZ_MAX_WIDTH (zr->timing->Wa) #define BUZ_MAX_HEIGHT (zr->timing->Ha) @@ -383,7 +383,7 @@ }; struct zoran { - struct video_device video_dev; + struct video_device *video_dev; struct i2c_adapter i2c_adapter; /* */ struct i2c_algo_bit_data i2c_algo; /* */ @@ -403,9 +403,7 @@ struct tvnorm *timing; unsigned short id; /* number of this device */ -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) char name[32]; /* name of this device */ -#endif struct pci_dev *pci_dev; /* PCI device */ unsigned char revision; /* revision of zr36057 */ unsigned int zr36057_adr; /* bus address of IO mem returned by PCI BIOS */ diff -Nru a/drivers/media/video/zoran_card.c b/drivers/media/video/zoran_card.c --- a/drivers/media/video/zoran_card.c Tue Sep 2 19:58:16 2003 +++ b/drivers/media/video/zoran_card.c Tue Sep 2 19:58:16 2003 @@ -136,7 +136,8 @@ MODULE_PARM_DESC(pass_through, "Pass TV signal through to TV-out when idling"); -int debug = 1; +static int debug = 1; +int *zr_debug = &debug; MODULE_PARM(debug, "i"); MODULE_PARM_DESC(debug, "Debug level (0-4)"); @@ -153,7 +154,7 @@ #define dprintk(num, format, args...) \ do { \ - if (debug >= num) \ + if (*zr_debug >= num) \ printk(format, ##args); \ } while (0) @@ -623,6 +624,7 @@ zoran_i2c_getsda (void *data) { struct zoran *zr = (struct zoran *) data; + return (btread(ZR36057_I2CBR) >> 1) & 1; } @@ -630,6 +632,7 @@ zoran_i2c_getscl (void *data) { struct zoran *zr = (struct zoran *) data; + return btread(ZR36057_I2CBR) & 1; } @@ -638,6 +641,7 @@ int state) { struct zoran *zr = (struct zoran *) data; + if (state) zr->i2cbr |= 2; else @@ -650,6 +654,7 @@ int state) { struct zoran *zr = (struct zoran *) data; + if (state) zr->i2cbr |= 1; else @@ -766,6 +771,7 @@ struct zoran_jpg_settings *settings) { int err = 0, err0 = 0; + dprintk(4, KERN_DEBUG "%s: check_jpg_settings() - dec: %d, Hdcm: %d, Vdcm: %d, Tdcm: %d\n", @@ -977,7 +983,7 @@ if (timeout) { dprintk(1, ": time spent: %d\n", 1 * HZ - timeout); } - if (debug > 1) + if (*zr_debug > 1) print_interrupts(zr); btwrite(icr, ZR36057_ICR); } @@ -986,6 +992,7 @@ zr36057_init (struct zoran *zr) { unsigned long mem; + void *vdev; unsigned mem_needed; int j; int two = 2; @@ -1040,11 +1047,16 @@ * in case allocation fails */ mem_needed = BUZ_NUM_STAT_COM * 4; mem = (unsigned long) kmalloc(mem_needed, GFP_KERNEL); - if (!mem) { + vdev = (void *) kmalloc(sizeof(struct video_device), GFP_KERNEL); + if (!mem || !vdev) { dprintk(1, KERN_ERR "%s: zr36057_init() - kmalloc (STAT_COM) failed\n", ZR_DEVNAME(zr)); + if (vdev) + kfree(vdev); + if (mem) + kfree((void *)mem); return -ENOMEM; } memset((void *) mem, 0, mem_needed); @@ -1056,17 +1068,19 @@ /* * Now add the template and register the device unit. */ - memcpy(&zr->video_dev, &zoran_template, sizeof(zoran_template)); - strcpy(zr->video_dev.name, ZR_DEVNAME(zr)); - if (video_register_device - (&zr->video_dev, VFL_TYPE_GRABBER, video_nr) < 0) { + zr->video_dev = vdev; + memcpy(zr->video_dev, &zoran_template, sizeof(zoran_template)); + strcpy(zr->video_dev->name, ZR_DEVNAME(zr)); + if (video_register_device(zr->video_dev, VFL_TYPE_GRABBER, + video_nr) < 0) { zoran_unregister_i2c(zr); kfree((void *) zr->stat_com); + kfree(vdev); return -1; } zoran_init_hardware(zr); - if (debug > 2) + if (*zr_debug > 2) detect_guest_activity(zr); test_interrupts(zr); if (!pass_through) { @@ -1109,7 +1123,14 @@ kfree((void *) zr->stat_com); zoran_proc_cleanup(zr); iounmap(zr->zr36057_mem); - video_unregister_device(&zr->video_dev); + pci_disable_device(zr->pci_dev); + video_unregister_device(zr->video_dev); +} + +void +zoran_vdev_release (struct video_device *vdev) +{ + kfree(vdev); } static struct videocodec_master * __devinit @@ -1207,6 +1228,7 @@ } else { int i; unsigned short ss_vendor, ss_device; + ss_vendor = zr->pci_dev->subsystem_vendor; ss_device = zr->pci_dev->subsystem_device; dprintk(1, @@ -1467,6 +1489,7 @@ init_dc10_cards (void) { int i; + memset(zoran, 0, sizeof(zoran)); printk(KERN_INFO "Zoran MJPEG board driver version %d.%d.%d\n", MAJOR_VERSION, MINOR_VERSION, RELEASE_VERSION); @@ -1523,6 +1546,7 @@ /* take care of Natoma chipset and a revision 1 zr36057 */ for (i = 0; i < zoran_num; i++) { struct zoran *zr = &zoran[i]; + if (pci_pci_problems & PCIPCI_NATOMA && zr->revision <= 1) { zr->jpg_buffers.need_contiguous = 1; dprintk(1, @@ -1546,6 +1570,7 @@ unload_dc10_cards (void) { int i; + for (i = 0; i < zoran_num; i++) zoran_release(&zoran[i]); } diff -Nru a/drivers/media/video/zoran_card.h b/drivers/media/video/zoran_card.h --- a/drivers/media/video/zoran_card.h Tue Sep 2 19:58:18 2003 +++ b/drivers/media/video/zoran_card.h Tue Sep 2 19:58:18 2003 @@ -40,5 +40,6 @@ extern int zoran_check_jpg_settings(struct zoran *zr, struct zoran_jpg_settings *settings); extern void zoran_open_init_params(struct zoran *zr); +extern void zoran_vdev_release(struct video_device *vdev); #endif /* __ZORAN_CARD_H__ */ diff -Nru a/drivers/media/video/zoran_device.c b/drivers/media/video/zoran_device.c --- a/drivers/media/video/zoran_device.c Tue Sep 2 19:58:16 2003 +++ b/drivers/media/video/zoran_device.c Tue Sep 2 19:58:16 2003 @@ -58,11 +58,11 @@ extern const struct zoran_format zoran_formats[]; extern const int zoran_num_formats; -extern int debug; +extern int *zr_debug; #define dprintk(num, format, args...) \ do { \ - if (debug >= num) \ + if (*zr_debug >= num) \ printk(format, ##args); \ } while (0) @@ -170,7 +170,7 @@ static void dump_guests (struct zoran *zr) { - if (debug > 2) { + if (*zr_debug > 2) { int i, guest[8]; for (i = 1; i < 8; i++) { // Don't read jpeg codec here @@ -190,6 +190,7 @@ get_time (void) { struct timeval tv; + do_gettimeofday(&tv); return (1000000 * tv.tv_sec + tv.tv_usec); } @@ -868,8 +869,8 @@ void print_interrupts (struct zoran *zr) { - int res, noerr; - noerr = 0; + int res, noerr = 0; + printk(KERN_INFO "%s: interrupts received:", ZR_DEVNAME(zr)); if ((res = zr->field_counter) < -1 || res > 1) { printk(" FD:%d", res); @@ -931,6 +932,7 @@ count_reset_interrupt (struct zoran *zr) { u32 isr; + if ((isr = btread(ZR36057_ISR) & 0x78000000)) { if (isr & ZR36057_ISR_GIRQ1) { btwrite(ZR36057_ISR_GIRQ1, ZR36057_ISR); @@ -961,6 +963,7 @@ jpeg_start (struct zoran *zr) { int reg; + zr->frame_num = 0; /* deassert P_reset, disable code transfer, deassert Active */ @@ -1272,7 +1275,7 @@ zr->num_errors++; /* Report error */ - if (debug > 1 && zr->num_errors <= 8) { + if (*zr_debug > 1 && zr->num_errors <= 8) { long frame; frame = zr->jpg_pend[zr->jpg_dma_tail & BUZ_MASK_FRAME]; @@ -1453,38 +1456,23 @@ 0) { /* it is finished, notify the user */ - zr->v4l_buffers.buffer[zr-> - v4l_grab_frame]. - state = BUZ_STATE_DONE; - zr->v4l_buffers.buffer[zr-> - v4l_grab_frame]. - bs.seq = - zr->v4l_grab_seq; - do_gettimeofday(&zr-> - v4l_buffers. - buffer[zr-> - v4l_grab_frame]. - bs. - timestamp); - zr->v4l_grab_frame = - NO_GRAB_ACTIVE; + zr->v4l_buffers.buffer[zr->v4l_grab_frame].state = BUZ_STATE_DONE; + zr->v4l_buffers.buffer[zr->v4l_grab_frame].bs.seq = zr->v4l_grab_seq; + do_gettimeofday(&zr->v4l_buffers.buffer[zr->v4l_grab_frame].bs.timestamp); + zr->v4l_grab_frame = NO_GRAB_ACTIVE; zr->v4l_pend_tail++; } } if (zr->v4l_grab_frame == NO_GRAB_ACTIVE) - wake_up_interruptible(&zr-> - v4l_capq); + wake_up_interruptible(&zr->v4l_capq); /* Check if there is another grab queued */ if (zr->v4l_grab_frame == NO_GRAB_ACTIVE && - zr->v4l_pend_tail != - zr->v4l_pend_head) { + zr->v4l_pend_tail != zr->v4l_pend_head) { - int frame = - zr->v4l_pend[zr-> - v4l_pend_tail & + int frame = zr->v4l_pend[zr->v4l_pend_tail & V4L_MASK_FRAME]; u32 reg; @@ -1544,7 +1532,7 @@ if (zr->codec_mode == BUZ_MODE_MOTION_DECOMPRESS || zr->codec_mode == BUZ_MODE_MOTION_COMPRESS) { - if (debug > 1 && + if (*zr_debug > 1 && (!zr->frame_num || zr->JPEG_error)) { printk(KERN_INFO "%s: first frame ready: state=0x%08x odd_even=%d field_per_buff=%d delay=%d\n", @@ -1559,11 +1547,8 @@ int i; strcpy(sv, sc); for (i = 0; i < 4; i++) { - if (zr-> - stat_com[i] & - 1) - sv[i] = - '1'; + if (zr->stat_com[i] & 1) + sv[i] = '1'; } sv[4] = 0; printk(KERN_INFO @@ -1584,7 +1569,7 @@ zr->JPEG_missed; } - if (debug > 2 && zr->frame_num < 6) { + if (*zr_debug > 2 && zr->frame_num < 6) { int i; printk("%s: seq=%ld stat_com:", ZR_DEVNAME(zr), zr->jpg_seq_num); @@ -1643,10 +1628,11 @@ zoran_set_pci_master (struct zoran *zr, int set_master) { - u16 command; if (set_master) { pci_set_master(zr->pci_dev); } else { + u16 command; + pci_read_config_word(zr->pci_dev, PCI_COMMAND, &command); command &= ~PCI_COMMAND_MASTER; pci_write_config_word(zr->pci_dev, PCI_COMMAND, command); @@ -1657,6 +1643,7 @@ zoran_init_hardware (struct zoran *zr) { int j, zero = 0; + /* Enable bus-mastering */ zoran_set_pci_master(zr, 1); @@ -1718,6 +1705,7 @@ zr36057_init_vfe (struct zoran *zr) { u32 reg; + reg = btread(ZR36057_VFESPFR); reg |= ZR36057_VFESPFR_LittleEndian; reg &= ~ZR36057_VFESPFR_VCLKPol; @@ -1748,6 +1736,7 @@ if (zr->card.type == LML33 && (cmd == DECODER_SET_NORM || DECODER_SET_INPUT)) { int res; + // Bt819 needs to reset its FIFO buffer using #FRST pin and // LML33 card uses GPIO(7) for that. GPIO(zr, 7, 0); diff -Nru a/drivers/media/video/zoran_driver.c b/drivers/media/video/zoran_driver.c --- a/drivers/media/video/zoran_driver.c Tue Sep 2 19:58:17 2003 +++ b/drivers/media/video/zoran_driver.c Tue Sep 2 19:58:17 2003 @@ -51,6 +51,7 @@ #include #include #include +#include #include #include @@ -187,11 +188,11 @@ # include #endif -extern int debug; +extern int *zr_debug; #define dprintk(num, format, args...) \ do { \ - if (debug >= num) \ + if (*zr_debug >= num) \ printk(format, ##args); \ } while (0) @@ -370,6 +371,7 @@ int n = (fh->v4l_buffers.buffer_size + PAGE_SIZE - 1) / PAGE_SIZE; + mem = (unsigned char *) bigphysarea_alloc_pages(n, 0, GFP_KERNEL); @@ -412,6 +414,7 @@ int size = fh->v4l_buffers.num_buffers * fh->v4l_buffers.buffer_size; + pmem = get_high_mem(size); if (pmem == 0) { dprintk(1, @@ -847,9 +850,10 @@ if (res) return res; } - if ((res = - zoran_v4l_set_format(file, mp->width, mp->height, - &zoran_formats[i]))) + if ((res = zoran_v4l_set_format(file, + mp->width, + mp->height, + &zoran_formats[i]))) return res; zr->v4l_settings = fh->v4l_settings; @@ -1144,7 +1148,7 @@ frame = zr->jpg_pend[zr->jpg_que_tail & BUZ_MASK_FRAME]; /* buffer should now be in BUZ_STATE_DONE */ - if (debug > 0) + if (*zr_debug > 0) if (zr->jpg_buffers.buffer[frame].state != BUZ_STATE_DONE) dprintk(2, KERN_ERR @@ -1268,7 +1272,7 @@ /* find the device */ for (i = 0; i < zoran_num; i++) { - if (zoran[i].video_dev.minor == minor) { + if (zoran[i].video_dev->minor == minor) { zr = &zoran[i]; break; } @@ -1424,7 +1428,7 @@ /* disable interrupts */ btand(~ZR36057_ICR_IntPinEn, ZR36057_ICR); - if (debug > 1) + if (*zr_debug > 1) print_interrupts(zr); /* Overlay off */ @@ -2032,6 +2036,7 @@ case VIDIOCGCAP: { struct video_capability *vcap = arg; + dprintk(3, KERN_DEBUG "%s: VIDIOCGCAP\n", ZR_DEVNAME(zr)); memset(vcap, 0, sizeof(struct video_capability)); @@ -2154,6 +2159,7 @@ for (i = 0; i < zoran_num_formats; i++) { const struct zoran_format *fmt = &zoran_formats[i]; + if (fmt->palette != -1 && fmt->flags & ZORAN_FORMAT_OVERLAY && fmt->palette == vpict->palette && @@ -2203,7 +2209,9 @@ case VIDIOCGWIN: { struct video_window *vwin = arg; + dprintk(3, KERN_DEBUG "%s: VIDIOCGWIN\n", ZR_DEVNAME(zr)); + memset(vwin, 0, sizeof(struct video_window)); down(&zr->resource_lock); vwin->x = fh->overlay_settings.x; @@ -2241,7 +2249,9 @@ case VIDIOCGFBUF: { struct video_buffer *vbuf = arg; + dprintk(3, KERN_DEBUG "%s: VIDIOCGFBUF\n", ZR_DEVNAME(zr)); + down(&zr->resource_lock); *vbuf = zr->buffer; up(&zr->resource_lock); @@ -2285,8 +2295,10 @@ case VIDIOCSYNC: { int *frame = arg, res; + dprintk(3, KERN_DEBUG "%s: VIDIOCSYNC - frame=%d\n", ZR_DEVNAME(zr), *frame); + down(&zr->resource_lock); res = v4l_sync(file, *frame); up(&zr->resource_lock); @@ -2300,11 +2312,13 @@ { struct video_mmap *vmap = arg; int res; + dprintk(3, KERN_DEBUG "%s: VIDIOCMCAPTURE - frame=%d, geom=%dx%d, fmt=%d\n", ZR_DEVNAME(zr), vmap->frame, vmap->width, vmap->height, vmap->format); + down(&zr->resource_lock); res = v4l_grab(file, vmap); up(&zr->resource_lock); @@ -2358,7 +2372,8 @@ struct video_unit *vunit = arg; dprintk(3, KERN_DEBUG "%s: VIDIOCGUNIT\n", ZR_DEVNAME(zr)); - vunit->video = zr->video_dev.minor; + + vunit->video = zr->video_dev->minor; vunit->vbi = VIDEO_NO_UNIT; vunit->radio = VIDEO_NO_UNIT; vunit->audio = VIDEO_NO_UNIT; @@ -2393,6 +2408,7 @@ case BUZIOC_G_PARAMS: { struct zoran_params *bparams = arg; + dprintk(3, KERN_DEBUG "%s: BUZIOC_G_PARAMS\n", ZR_DEVNAME(zr)); memset(bparams, 0, sizeof(struct zoran_params)); @@ -2686,6 +2702,7 @@ struct v4l2_fmtdesc *fmt = arg; int index = fmt->index, num = -1, i, flag = 0, type = fmt->type; + dprintk(3, KERN_DEBUG "%s: VIDIOC_ENUM_FMT - index=%d\n", ZR_DEVNAME(zr), fmt->index); @@ -3530,6 +3547,7 @@ case VIDIOC_QUERYCTRL: { struct v4l2_queryctrl *ctrl = arg; + dprintk(3, KERN_DEBUG "%s: VIDIOC_QUERYCTRL - id=%d\n", ZR_DEVNAME(zr), ctrl->id); @@ -3571,6 +3589,7 @@ case VIDIOC_G_CTRL: { struct v4l2_control *ctrl = arg; + dprintk(3, KERN_DEBUG "%s: VIDIOC_G_CTRL - id=%d\n", ZR_DEVNAME(zr), ctrl->id); @@ -3652,6 +3671,7 @@ case VIDIOC_ENUMSTD: { struct v4l2_standard *std = arg; + dprintk(3, KERN_DEBUG "%s: VIDIOC_ENUMSTD - index=%d\n", ZR_DEVNAME(zr), std->index); @@ -3707,6 +3727,7 @@ { v4l2_std_id *std = arg; int norm; + dprintk(3, KERN_DEBUG "%s: VIDIOC_G_STD\n", ZR_DEVNAME(zr)); down(&zr->resource_lock); @@ -3804,6 +3825,7 @@ case VIDIOC_G_INPUT: { int *input = arg; + dprintk(3, KERN_DEBUG "%s: VIDIOC_G_INPUT\n", ZR_DEVNAME(zr)); down(&zr->resource_lock); @@ -3817,6 +3839,7 @@ case VIDIOC_S_INPUT: { int *input = arg, res = 0; + dprintk(3, KERN_DEBUG "%s: VIDIOC_S_INPUT - input=%d\n", ZR_DEVNAME(zr), *input); @@ -3835,6 +3858,7 @@ case VIDIOC_ENUMOUTPUT: { struct v4l2_output *outp = arg; + dprintk(3, KERN_DEBUG "%s: VIDIOC_ENUMOUTPUT - index=%d\n", ZR_DEVNAME(zr), outp->index); @@ -4005,7 +4029,9 @@ case VIDIOC_G_JPEGCOMP: { struct v4l2_jpegcompression *params = arg; - dprintk(3, KERN_DEBUG "%s: VIDIOC_G_JPEGCOMP\n", ZR_DEVNAME(zr)); + + dprintk(3, KERN_DEBUG "%s: VIDIOC_G_JPEGCOMP\n", + ZR_DEVNAME(zr)); memset(params, 0, sizeof(*params)); @@ -4175,6 +4201,7 @@ } else if (fmt->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) { int i; + for (i = 0; i < zoran_num_formats; i++) if (zoran_formats[i].fourcc == fmt->fmt.pix.pixelformat) @@ -4321,6 +4348,7 @@ zoran_vm_open (struct vm_area_struct *vma) { struct zoran_mapping *map = vma->vm_private_data; + map->count++; } @@ -4665,5 +4693,6 @@ #endif .hardware = ZORAN_HARDWARE, .fops = &zoran_fops, + .release = &zoran_vdev_release, .minor = -1 }; diff -Nru a/drivers/media/video/zoran_procfs.c b/drivers/media/video/zoran_procfs.c --- a/drivers/media/video/zoran_procfs.c Tue Sep 2 19:58:18 2003 +++ b/drivers/media/video/zoran_procfs.c Tue Sep 2 19:58:18 2003 @@ -49,11 +49,11 @@ #include "zoran.h" #include "zoran_procfs.h" -extern int debug; +extern int *zr_debug; #define dprintk(num, format, args...) \ do { \ - if (debug >= num) \ + if (*zr_debug >= num) \ printk(format, ##args); \ } while (0) @@ -248,6 +248,7 @@ { #ifdef CONFIG_PROC_FS char name[8]; + snprintf(name, 7, "zoran%d", zr->id); if ((zr->zoran_proc = create_proc_entry(name, 0, 0))) { zr->zoran_proc->read_proc = zoran_read_proc; @@ -272,6 +273,7 @@ { #ifdef CONFIG_PROC_FS char name[8]; + snprintf(name, 7, "zoran%d", zr->id); if (zr->zoran_proc) { remove_proc_entry(name, 0); diff -Nru a/drivers/mtd/devices/Kconfig b/drivers/mtd/devices/Kconfig --- a/drivers/mtd/devices/Kconfig Tue Sep 2 19:58:15 2003 +++ b/drivers/mtd/devices/Kconfig Tue Sep 2 19:58:15 2003 @@ -102,7 +102,7 @@ config MTD_BLKMTD tristate "MTD emulation using block device" - depends on MTD && BROKEN + depends on MTD help This driver allows a block device to appear as an MTD. It would generally be used in the following cases: diff -Nru a/drivers/mtd/maps/ceiva.c b/drivers/mtd/maps/ceiva.c --- a/drivers/mtd/maps/ceiva.c Tue Sep 2 19:58:15 2003 +++ b/drivers/mtd/maps/ceiva.c Tue Sep 2 19:58:15 2003 @@ -64,23 +64,23 @@ static struct mtd_partition ceiva_partitions[] = { { - name: "Ceiva BOOT partition", - size: BOOT_PARTITION_SIZE_KiB*1024, - offset: 0, + .name = "Ceiva BOOT partition", + .size = BOOT_PARTITION_SIZE_KiB*1024, + .offset = 0, },{ - name: "Ceiva parameters partition", - size: PARAMS_PARTITION_SIZE_KiB*1024, - offset: (16 + 8) * 1024, + .name = "Ceiva parameters partition", + .size = PARAMS_PARTITION_SIZE_KiB*1024, + .offset = (16 + 8) * 1024, },{ - name: "Ceiva kernel partition", - size: (KERNEL_PARTITION_SIZE_KiB)*1024, - offset: 0x20000, + .name = "Ceiva kernel partition", + .size = (KERNEL_PARTITION_SIZE_KiB)*1024, + .offset = 0x20000, },{ - name: "Ceiva root filesystem partition", - offset: MTDPART_OFS_APPEND, - size: (ROOT_PARTITION_SIZE_KiB)*1024, + .name = "Ceiva root filesystem partition", + .offset = MTDPART_OFS_APPEND, + .size = (ROOT_PARTITION_SIZE_KiB)*1024, } }; #endif diff -Nru a/drivers/mtd/maps/pcmciamtd.c b/drivers/mtd/maps/pcmciamtd.c --- a/drivers/mtd/maps/pcmciamtd.c Tue Sep 2 19:58:13 2003 +++ b/drivers/mtd/maps/pcmciamtd.c Tue Sep 2 19:58:13 2003 @@ -344,9 +344,8 @@ * still open, this will be postponed until it is closed. */ -static void pcmciamtd_release(u_long arg) +static void pcmciamtd_release(dev_link_t *link) { - dev_link_t *link = (dev_link_t *)arg; struct pcmciamtd_dev *dev = link->priv; DEBUG(3, "link = 0x%p", link); @@ -564,7 +563,7 @@ if(!dev->win_size) { err("Cant allocate memory window"); - pcmciamtd_release((u_long)link); + pcmciamtd_release(link); return; } DEBUG(1, "Allocated a window of %dKiB", dev->win_size >> 10); @@ -576,7 +575,7 @@ dev->win_base = ioremap(req.Base, req.Size); if(!dev->win_base) { err("ioremap(%lu, %u) failed", req.Base, req.Size); - pcmciamtd_release((u_long)link); + pcmciamtd_release(link); return; } DEBUG(1, "mapped window dev = %p req.base = 0x%lx base = %p size = 0x%x", @@ -631,7 +630,7 @@ if(!mtd) { DEBUG(1, "Cant find an MTD"); - pcmciamtd_release((u_long)link); + pcmciamtd_release(link); return; } @@ -671,7 +670,7 @@ map_destroy(mtd); dev->mtd_info = NULL; err("Couldnt register MTD device"); - pcmciamtd_release((u_long)link); + pcmciamtd_release(link); return; } snprintf(dev->node.dev_name, sizeof(dev->node.dev_name), "mtd%d", mtd->index); @@ -683,7 +682,7 @@ cs_failed: cs_error(link->handle, last_fn, last_ret); err("CS Error, exiting"); - pcmciamtd_release((u_long)link); + pcmciamtd_release(link); return; } @@ -710,7 +709,7 @@ del_mtd_device(dev->mtd_info); info("mtd%d: Removed", dev->mtd_info->index); } - mod_timer(&link->release, jiffies + HZ/20); + pcmciamtd_release(link); } break; case CS_EVENT_CARD_INSERTION: @@ -751,10 +750,8 @@ { DEBUG(3, "link=0x%p", link); - del_timer(&link->release); - if(link->state & DEV_CONFIG) { - pcmciamtd_release((u_long)link); + pcmciamtd_release(link); } if (link->handle) { @@ -789,10 +786,6 @@ memset(dev, 0, sizeof(*dev)); link = &dev->link; link->priv = dev; - - init_timer(&link->release); - link->release.function = &pcmciamtd_release; - link->release.data = (u_long)link; link->conf.Attributes = 0; link->conf.IntType = INT_MEMORY; diff -Nru a/drivers/mtd/mtdchar.c b/drivers/mtd/mtdchar.c --- a/drivers/mtd/mtdchar.c Tue Sep 2 19:58:17 2003 +++ b/drivers/mtd/mtdchar.c Tue Sep 2 19:58:17 2003 @@ -59,7 +59,7 @@ static int mtd_open(struct inode *inode, struct file *file) { - int minor = minor(inode->i_rdev); + int minor = iminor(inode); int devnum = minor >> 1; struct mtd_info *mtd; diff -Nru a/drivers/mtd/nand/autcpu12.c b/drivers/mtd/nand/autcpu12.c --- a/drivers/mtd/nand/autcpu12.c Tue Sep 2 19:58:13 2003 +++ b/drivers/mtd/nand/autcpu12.c Tue Sep 2 19:58:13 2003 @@ -73,39 +73,39 @@ extern struct nand_oobinfo jffs2_oobinfo; static struct mtd_partition partition_info16k[] = { - { name: "AUTCPU12 flash partition 1", - offset: 0, - size: 8 * SZ_1M }, - { name: "AUTCPU12 flash partition 2", - offset: 8 * SZ_1M, - size: 8 * SZ_1M }, + { .name = "AUTCPU12 flash partition 1", + .offset = 0, + .size = 8 * SZ_1M }, + { .name = "AUTCPU12 flash partition 2", + .offset = 8 * SZ_1M, + .size = 8 * SZ_1M }, }; static struct mtd_partition partition_info32k[] = { - { name: "AUTCPU12 flash partition 1", - offset: 0, - size: 8 * SZ_1M }, - { name: "AUTCPU12 flash partition 2", - offset: 8 * SZ_1M, - size: 24 * SZ_1M }, + { .name = "AUTCPU12 flash partition 1", + .offset = 0, + .size = 8 * SZ_1M }, + { .name = "AUTCPU12 flash partition 2", + .offset = 8 * SZ_1M, + .size = 24 * SZ_1M }, }; static struct mtd_partition partition_info64k[] = { - { name: "AUTCPU12 flash partition 1", - offset: 0, - size: 16 * SZ_1M }, - { name: "AUTCPU12 flash partition 2", - offset: 16 * SZ_1M, - size: 48 * SZ_1M }, + { .name = "AUTCPU12 flash partition 1", + .offset = 0, + .size = 16 * SZ_1M }, + { .name = "AUTCPU12 flash partition 2", + .offset = 16 * SZ_1M, + .size = 48 * SZ_1M }, }; static struct mtd_partition partition_info128k[] = { - { name: "AUTCPU12 flash partition 1", - offset: 0, - size: 16 * SZ_1M }, - { name: "AUTCPU12 flash partition 2", - offset: 16 * SZ_1M, - size: 112 * SZ_1M }, + { .name = "AUTCPU12 flash partition 1", + .offset = 0, + .size = 16 * SZ_1M }, + { .name = "AUTCPU12 flash partition 2", + .offset = 16 * SZ_1M, + .size = 112 * SZ_1M }, }; #define NUM_PARTITIONS16K 2 diff -Nru a/drivers/mtd/nand/edb7312.c b/drivers/mtd/nand/edb7312.c --- a/drivers/mtd/nand/edb7312.c Tue Sep 2 19:58:19 2003 +++ b/drivers/mtd/nand/edb7312.c Tue Sep 2 19:58:19 2003 @@ -71,9 +71,9 @@ * Define static partitions for flash device */ static struct mtd_partition partition_info[] = { - { name: "EP7312 Nand Flash", - offset: 0, - size: 8*1024*1024 } + { .name = "EP7312 Nand Flash", + .offset = 0, + .size = 8*1024*1024 } }; #define NUM_PARTITIONS 1 diff -Nru a/drivers/net/3c501.c b/drivers/net/3c501.c --- a/drivers/net/3c501.c Tue Sep 2 19:58:12 2003 +++ b/drivers/net/3c501.c Tue Sep 2 19:58:12 2003 @@ -307,7 +307,7 @@ dev->stop = &el1_close; dev->get_stats = &el1_get_stats; dev->set_multicast_list = &set_multicast_list; - dev->do_ioctl = netdev_ioctl; + dev->ethtool_ops = &netdev_ethtool_ops; /* * Setup the generic properties @@ -857,86 +857,31 @@ } } -/** - * netdev_ethtool_ioctl: Handle network interface SIOCETHTOOL ioctls - * @dev: network interface on which out-of-band action is to be performed - * @useraddr: userspace address to which data is to be read and returned - * - * Process the various commands of the SIOCETHTOOL interface. - */ -static int netdev_ethtool_ioctl (struct net_device *dev, void *useraddr) +static void netdev_get_drvinfo(struct net_device *dev, + struct ethtool_drvinfo *info) { - u32 ethcmd; - - /* dev_ioctl() in ../../net/core/dev.c has already checked - capable(CAP_NET_ADMIN), so don't bother with that here. */ - - if (get_user(ethcmd, (u32 *)useraddr)) - return -EFAULT; - - switch (ethcmd) { - - case ETHTOOL_GDRVINFO: { - struct ethtool_drvinfo info = { ETHTOOL_GDRVINFO }; - strcpy (info.driver, DRV_NAME); - strcpy (info.version, DRV_VERSION); - sprintf(info.bus_info, "ISA 0x%lx", dev->base_addr); - if (copy_to_user (useraddr, &info, sizeof (info))) - return -EFAULT; - return 0; - } - - /* get message-level */ - case ETHTOOL_GMSGLVL: { - struct ethtool_value edata = {ETHTOOL_GMSGLVL}; - edata.data = debug; - if (copy_to_user(useraddr, &edata, sizeof(edata))) - return -EFAULT; - return 0; - } - /* set message-level */ - case ETHTOOL_SMSGLVL: { - struct ethtool_value edata; - if (copy_from_user(&edata, useraddr, sizeof(edata))) - return -EFAULT; - debug = edata.data; - return 0; - } - - default: - break; - } - - return -EOPNOTSUPP; + strcpy(info->driver, DRV_NAME); + strcpy(info->version, DRV_VERSION); + sprintf(info->bus_info, "ISA 0x%lx", dev->base_addr); } -/** - * netdev_ioctl: Handle network interface ioctls - * @dev: network interface on which out-of-band action is to be performed - * @rq: user request data - * @cmd: command issued by user - * - * Process the various out-of-band ioctls passed to this driver. - */ +static u32 netdev_get_msglevel(struct net_device *dev) +{ + return debug; +} -static int netdev_ioctl (struct net_device *dev, struct ifreq *rq, int cmd) +static void netdev_set_msglevel(struct net_device *dev, u32 level) { - int rc = 0; + debug = level; +} - switch (cmd) { - case SIOCETHTOOL: - rc = netdev_ethtool_ioctl(dev, (void *) rq->ifr_data); - break; - - default: - rc = -EOPNOTSUPP; - break; - } +static struct ethtool_ops netdev_ethtool_ops = { + .get_drvinfo = netdev_get_drvinfo, + .get_msglevel = netdev_get_msglevel, + .set_msglevel = netdev_set_msglevel, +}; - return rc; -} - #ifdef MODULE static struct net_device dev_3c501 = { diff -Nru a/drivers/net/3c501.h b/drivers/net/3c501.h --- a/drivers/net/3c501.h Tue Sep 2 19:58:15 2003 +++ b/drivers/net/3c501.h Tue Sep 2 19:58:15 2003 @@ -14,7 +14,7 @@ static int el1_close(struct net_device *dev); static struct net_device_stats *el1_get_stats(struct net_device *dev); static void set_multicast_list(struct net_device *dev); -static int netdev_ioctl (struct net_device *dev, struct ifreq *rq, int cmd); +static struct ethtool_ops netdev_ethtool_ops; #define EL1_IO_EXTENT 16 diff -Nru a/drivers/net/3c503.c b/drivers/net/3c503.c --- a/drivers/net/3c503.c Tue Sep 2 19:58:17 2003 +++ b/drivers/net/3c503.c Tue Sep 2 19:58:17 2003 @@ -80,7 +80,7 @@ int ring_offset); static void el2_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_page); -static int netdev_ioctl (struct net_device *dev, struct ifreq *rq, int cmd); +static struct ethtool_ops netdev_ethtool_ops; /* This routine probes for a memory-mapped 3c503 board by looking for @@ -308,7 +308,7 @@ dev->open = &el2_open; dev->stop = &el2_close; - dev->do_ioctl = &netdev_ioctl; + dev->ethtool_ops = &netdev_ethtool_ops; if (dev->mem_start) printk("%s: %s - %dkB RAM, 8kB shared mem window at %#6lx-%#6lx.\n", @@ -617,69 +617,18 @@ return; } -/** - * netdev_ethtool_ioctl: Handle network interface SIOCETHTOOL ioctls - * @dev: network interface on which out-of-band action is to be performed - * @useraddr: userspace address to which data is to be read and returned - * - * Process the various commands of the SIOCETHTOOL interface. - */ -static int netdev_ethtool_ioctl (struct net_device *dev, void *useraddr) +static void netdev_get_drvinfo(struct net_device *dev, + struct ethtool_drvinfo *info) { - u32 ethcmd; - - /* dev_ioctl() in ../../net/core/dev.c has already checked - capable(CAP_NET_ADMIN), so don't bother with that here. */ - - if (get_user(ethcmd, (u32 *)useraddr)) - return -EFAULT; - - switch (ethcmd) { - - case ETHTOOL_GDRVINFO: { - struct ethtool_drvinfo info = { ETHTOOL_GDRVINFO }; - strcpy (info.driver, DRV_NAME); - strcpy (info.version, DRV_VERSION); - sprintf(info.bus_info, "ISA 0x%lx", dev->base_addr); - if (copy_to_user (useraddr, &info, sizeof (info))) - return -EFAULT; - return 0; - } - - default: - break; - } - - return -EOPNOTSUPP; + strcpy(info->driver, DRV_NAME); + strcpy(info->version, DRV_VERSION); + sprintf(info->bus_info, "ISA 0x%lx", dev->base_addr); } -/** - * netdev_ioctl: Handle network interface ioctls - * @dev: network interface on which out-of-band action is to be performed - * @rq: user request data - * @cmd: command issued by user - * - * Process the various out-of-band ioctls passed to this driver. - */ - -static int netdev_ioctl (struct net_device *dev, struct ifreq *rq, int cmd) -{ - int rc = 0; - - switch (cmd) { - case SIOCETHTOOL: - rc = netdev_ethtool_ioctl(dev, (void *) rq->ifr_data); - break; - - default: - rc = -EOPNOTSUPP; - break; - } - - return rc; -} - +static struct ethtool_ops netdev_ethtool_ops = { + .get_drvinfo = netdev_get_drvinfo, +}; #ifdef MODULE #define MAX_EL2_CARDS 4 /* Max number of EL2 cards per module */ diff -Nru a/drivers/net/3c505.c b/drivers/net/3c505.c --- a/drivers/net/3c505.c Tue Sep 2 19:58:20 2003 +++ b/drivers/net/3c505.c Tue Sep 2 19:58:20 2003 @@ -1163,86 +1163,30 @@ return &adapter->stats; } -/** - * netdev_ethtool_ioctl: Handle network interface SIOCETHTOOL ioctls - * @dev: network interface on which out-of-band action is to be performed - * @useraddr: userspace address to which data is to be read and returned - * - * Process the various commands of the SIOCETHTOOL interface. - */ - -static int netdev_ethtool_ioctl (struct net_device *dev, void *useraddr) -{ - u32 ethcmd; - - /* dev_ioctl() in ../../net/core/dev.c has already checked - capable(CAP_NET_ADMIN), so don't bother with that here. */ - - if (get_user(ethcmd, (u32 *)useraddr)) - return -EFAULT; - - switch (ethcmd) { - - case ETHTOOL_GDRVINFO: { - struct ethtool_drvinfo info = { ETHTOOL_GDRVINFO }; - strcpy (info.driver, DRV_NAME); - strcpy (info.version, DRV_VERSION); - sprintf(info.bus_info, "ISA 0x%lx", dev->base_addr); - if (copy_to_user (useraddr, &info, sizeof (info))) - return -EFAULT; - return 0; - } - - /* get message-level */ - case ETHTOOL_GMSGLVL: { - struct ethtool_value edata = {ETHTOOL_GMSGLVL}; - edata.data = debug; - if (copy_to_user(useraddr, &edata, sizeof(edata))) - return -EFAULT; - return 0; - } - /* set message-level */ - case ETHTOOL_SMSGLVL: { - struct ethtool_value edata; - if (copy_from_user(&edata, useraddr, sizeof(edata))) - return -EFAULT; - debug = edata.data; - return 0; - } - - default: - break; - } - return -EOPNOTSUPP; +static void netdev_get_drvinfo(struct net_device *dev, + struct ethtool_drvinfo *info) +{ + strcpy(info->driver, DRV_NAME); + strcpy(info->version, DRV_VERSION); + sprintf(info->bus_info, "ISA 0x%lx", dev->base_addr); } -/** - * netdev_ioctl: Handle network interface ioctls - * @dev: network interface on which out-of-band action is to be performed - * @rq: user request data - * @cmd: command issued by user - * - * Process the various out-of-band ioctls passed to this driver. - */ - -static int netdev_ioctl (struct net_device *dev, struct ifreq *rq, int cmd) -{ - int rc = 0; - - switch (cmd) { - case SIOCETHTOOL: - rc = netdev_ethtool_ioctl(dev, (void *) rq->ifr_data); - break; - - default: - rc = -EOPNOTSUPP; - break; - } +static u32 netdev_get_msglevel(struct net_device *dev) +{ + return debug; +} - return rc; +static void netdev_set_msglevel(struct net_device *dev, u32 level) +{ + debug = level; } - + +static struct ethtool_ops netdev_ethtool_ops = { + .get_drvinfo = netdev_get_drvinfo, + .get_msglevel = netdev_get_msglevel, + .set_msglevel = netdev_set_msglevel, +}; /****************************************************** * @@ -1373,7 +1317,7 @@ dev->tx_timeout = elp_timeout; /* local */ dev->watchdog_timeo = 10*HZ; dev->set_multicast_list = elp_set_mc_list; /* local */ - dev->do_ioctl = netdev_ioctl; /* local */ + dev->ethtool_ops = &netdev_ethtool_ops; /* local */ /* Setup the generic properties */ ether_setup(dev); diff -Nru a/drivers/net/3c507.c b/drivers/net/3c507.c --- a/drivers/net/3c507.c Tue Sep 2 19:58:18 2003 +++ b/drivers/net/3c507.c Tue Sep 2 19:58:18 2003 @@ -299,7 +299,7 @@ static void hardware_send_packet(struct net_device *dev, void *buf, short length, short pad); static void init_82586_mem(struct net_device *dev); -static int netdev_ioctl (struct net_device *dev, struct ifreq *rq, int cmd); +static struct ethtool_ops netdev_ethtool_ops; /* Check for a network adaptor of this type, and return '0' iff one exists. @@ -431,7 +431,7 @@ dev->get_stats = el16_get_stats; dev->tx_timeout = el16_tx_timeout; dev->watchdog_timeo = TX_TIMEOUT; - dev->do_ioctl = netdev_ioctl; + dev->ethtool_ops = &netdev_ethtool_ops; ether_setup(dev); /* Generic ethernet behaviour */ @@ -874,86 +874,29 @@ lp->rx_tail = rx_tail; } -/** - * netdev_ethtool_ioctl: Handle network interface SIOCETHTOOL ioctls - * @dev: network interface on which out-of-band action is to be performed - * @useraddr: userspace address to which data is to be read and returned - * - * Process the various commands of the SIOCETHTOOL interface. - */ - -static int netdev_ethtool_ioctl (struct net_device *dev, void *useraddr) -{ - u32 ethcmd; - - /* dev_ioctl() in ../../net/core/dev.c has already checked - capable(CAP_NET_ADMIN), so don't bother with that here. */ - - if (get_user(ethcmd, (u32 *)useraddr)) - return -EFAULT; - - switch (ethcmd) { - - case ETHTOOL_GDRVINFO: { - struct ethtool_drvinfo info = { ETHTOOL_GDRVINFO }; - strcpy (info.driver, DRV_NAME); - strcpy (info.version, DRV_VERSION); - sprintf(info.bus_info, "ISA 0x%lx", dev->base_addr); - if (copy_to_user (useraddr, &info, sizeof (info))) - return -EFAULT; - return 0; - } - - /* get message-level */ - case ETHTOOL_GMSGLVL: { - struct ethtool_value edata = {ETHTOOL_GMSGLVL}; - edata.data = debug; - if (copy_to_user(useraddr, &edata, sizeof(edata))) - return -EFAULT; - return 0; - } - /* set message-level */ - case ETHTOOL_SMSGLVL: { - struct ethtool_value edata; - if (copy_from_user(&edata, useraddr, sizeof(edata))) - return -EFAULT; - debug = edata.data; - return 0; - } - - default: - break; - } - - return -EOPNOTSUPP; +static void netdev_get_drvinfo(struct net_device *dev, + struct ethtool_drvinfo *info) +{ + strcpy(info->driver, DRV_NAME); + strcpy(info->version, DRV_VERSION); + sprintf(info->bus_info, "ISA 0x%lx", dev->base_addr); } -/** - * netdev_ioctl: Handle network interface ioctls - * @dev: network interface on which out-of-band action is to be performed - * @rq: user request data - * @cmd: command issued by user - * - * Process the various out-of-band ioctls passed to this driver. - */ - -static int netdev_ioctl (struct net_device *dev, struct ifreq *rq, int cmd) +static u32 netdev_get_msglevel(struct net_device *dev) { - int rc = 0; - - switch (cmd) { - case SIOCETHTOOL: - rc = netdev_ethtool_ioctl(dev, (void *) rq->ifr_data); - break; - - default: - rc = -EOPNOTSUPP; - break; - } + return debug; +} - return rc; +static void netdev_set_msglevel(struct net_device *dev, u32 level) +{ + debug = level; } - + +static struct ethtool_ops netdev_ethtool_ops = { + .get_drvinfo = netdev_get_drvinfo, + .get_msglevel = netdev_get_msglevel, + .set_msglevel = netdev_set_msglevel, +}; #ifdef MODULE static struct net_device dev_3c507; diff -Nru a/drivers/net/3c509.c b/drivers/net/3c509.c --- a/drivers/net/3c509.c Tue Sep 2 19:58:12 2003 +++ b/drivers/net/3c509.c Tue Sep 2 19:58:12 2003 @@ -300,10 +300,11 @@ * * Both call el3_common_init/el3_common_remove. */ -static void __init el3_common_init(struct net_device *dev) +static int __init el3_common_init(struct net_device *dev) { struct el3_private *lp = dev->priv; short i; + int err; spin_lock_init(&lp->lock); @@ -314,10 +315,29 @@ dev->if_port |= (dev->mem_start & 0x08); } + /* The EL3-specific entries in the device structure. */ + dev->open = &el3_open; + dev->hard_start_xmit = &el3_start_xmit; + dev->stop = &el3_close; + dev->get_stats = &el3_get_stats; + dev->set_multicast_list = &set_multicast_list; + dev->tx_timeout = el3_tx_timeout; + dev->watchdog_timeo = TX_TIMEOUT; + dev->do_ioctl = netdev_ioctl; + + err = register_netdev(dev); + if (err) { + printk(KERN_ERR "Failed to register 3c5x9 at %#3.3lx, IRQ %d.\n", + dev->base_addr, dev->irq); + release_region(dev->base_addr, EL3_IO_EXTENT); + return err; + } + { const char *if_names[] = {"10baseT", "AUI", "undefined", "BNC"}; - printk("%s: 3c5x9 at %#3.3lx, %s port, address ", - dev->name, dev->base_addr, if_names[(dev->if_port & 0x03)]); + printk("%s: 3c5x9 found at %#3.3lx, %s port, address ", + dev->name, dev->base_addr, + if_names[(dev->if_port & 0x03)]); } /* Read in the station address. */ @@ -327,16 +347,8 @@ if (el3_debug > 0) printk(KERN_INFO "%s" KERN_INFO "%s", versionA, versionB); + return 0; - /* The EL3-specific entries in the device structure. */ - dev->open = &el3_open; - dev->hard_start_xmit = &el3_start_xmit; - dev->stop = &el3_close; - dev->get_stats = &el3_get_stats; - dev->set_multicast_list = &set_multicast_list; - dev->tx_timeout = el3_tx_timeout; - dev->watchdog_timeo = TX_TIMEOUT; - dev->do_ioctl = netdev_ioctl; } static void el3_common_remove (struct net_device *dev) @@ -564,9 +576,8 @@ #if defined(__ISAPNP__) && !defined(CONFIG_X86_PC9800) lp->dev = &idev->dev; #endif - el3_common_init(dev); + err = el3_common_init(dev); - err = register_netdev(dev); if (err) goto out1; @@ -588,7 +599,6 @@ return 0; out1: - release_region(ioaddr, EL3_IO_EXTENT); #if defined(__ISAPNP__) && !defined(CONFIG_X86_PC9800) if (idev) pnp_device_detach(idev); @@ -629,8 +639,8 @@ el3_mca_adapter_names[mdev->index], slot + 1); /* claim the slot */ - strncpy(device->name, el3_mca_adapter_names[mdev->index], - sizeof(device->name)); + strncpy(mdev->name, el3_mca_adapter_names[mdev->index], + sizeof(mdev->name)); mca_device_set_claim(mdev, 1); if_port = pos4 & 0x03; @@ -662,11 +672,9 @@ lp->dev = device; lp->type = EL3_MCA; device->driver_data = dev; - el3_common_init(dev); + err = el3_common_init(dev); - err = register_netdev(dev); if (err) { - release_region(ioaddr, EL3_IO_EXTENT); return -ENOMEM; } @@ -723,11 +731,9 @@ lp->dev = device; lp->type = EL3_EISA; eisa_set_drvdata (edev, dev); - el3_common_init(dev); + err = el3_common_init(dev); - err = register_netdev(dev); if (err) { - release_region(ioaddr, EL3_IO_EXTENT); return err; } diff -Nru a/drivers/net/3c515.c b/drivers/net/3c515.c --- a/drivers/net/3c515.c Tue Sep 2 19:58:13 2003 +++ b/drivers/net/3c515.c Tue Sep 2 19:58:13 2003 @@ -392,7 +392,7 @@ static void update_stats(int addr, struct net_device *dev); static struct net_device_stats *corkscrew_get_stats(struct net_device *dev); static void set_rx_mode(struct net_device *dev); -static int netdev_ioctl (struct net_device *dev, struct ifreq *rq, int cmd); +static struct ethtool_ops netdev_ethtool_ops; /* @@ -718,7 +718,7 @@ dev->stop = &corkscrew_close; dev->get_stats = &corkscrew_get_stats; dev->set_multicast_list = &set_rx_mode; - dev->do_ioctl = netdev_ioctl; + dev->ethtool_ops = &netdev_ethtool_ops; return 0; } @@ -1580,86 +1580,30 @@ outw(new_mode, ioaddr + EL3_CMD); } -/** - * netdev_ethtool_ioctl: Handle network interface SIOCETHTOOL ioctls - * @dev: network interface on which out-of-band action is to be performed - * @useraddr: userspace address to which data is to be read and returned - * - * Process the various commands of the SIOCETHTOOL interface. - */ - -static int netdev_ethtool_ioctl (struct net_device *dev, void *useraddr) +static void netdev_get_drvinfo(struct net_device *dev, + struct ethtool_drvinfo *info) { - u32 ethcmd; - - /* dev_ioctl() in ../../net/core/dev.c has already checked - capable(CAP_NET_ADMIN), so don't bother with that here. */ - - if (get_user(ethcmd, (u32 *)useraddr)) - return -EFAULT; - - switch (ethcmd) { - - case ETHTOOL_GDRVINFO: { - struct ethtool_drvinfo info = { ETHTOOL_GDRVINFO }; - strcpy (info.driver, DRV_NAME); - strcpy (info.version, DRV_VERSION); - sprintf(info.bus_info, "ISA 0x%lx", dev->base_addr); - if (copy_to_user (useraddr, &info, sizeof (info))) - return -EFAULT; - return 0; - } - - /* get message-level */ - case ETHTOOL_GMSGLVL: { - struct ethtool_value edata = {ETHTOOL_GMSGLVL}; - edata.data = corkscrew_debug; - if (copy_to_user(useraddr, &edata, sizeof(edata))) - return -EFAULT; - return 0; - } - /* set message-level */ - case ETHTOOL_SMSGLVL: { - struct ethtool_value edata; - if (copy_from_user(&edata, useraddr, sizeof(edata))) - return -EFAULT; - corkscrew_debug = edata.data; - return 0; - } - - default: - break; - } - - return -EOPNOTSUPP; + strcpy(info->driver, DRV_NAME); + strcpy(info->version, DRV_VERSION); + sprintf(info->bus_info, "ISA 0x%lx", dev->base_addr); } -/** - * netdev_ioctl: Handle network interface ioctls - * @dev: network interface on which out-of-band action is to be performed - * @rq: user request data - * @cmd: command issued by user - * - * Process the various out-of-band ioctls passed to this driver. - */ - -static int netdev_ioctl (struct net_device *dev, struct ifreq *rq, int cmd) +static u32 netdev_get_msglevel(struct net_device *dev) { - int rc = 0; + return corkscrew_debug; +} - switch (cmd) { - case SIOCETHTOOL: - rc = netdev_ethtool_ioctl(dev, (void *) rq->ifr_data); - break; +static void netdev_set_msglevel(struct net_device *dev, u32 level) +{ + corkscrew_debug = level; +} - default: - rc = -EOPNOTSUPP; - break; - } +static struct ethtool_ops netdev_ethtool_ops = { + .get_drvinfo = netdev_get_drvinfo, + .get_msglevel = netdev_get_msglevel, + .set_msglevel = netdev_set_msglevel, +}; - return rc; -} - #ifdef MODULE void cleanup_module(void) diff -Nru a/drivers/net/3c523.c b/drivers/net/3c523.c --- a/drivers/net/3c523.c Tue Sep 2 19:58:15 2003 +++ b/drivers/net/3c523.c Tue Sep 2 19:58:15 2003 @@ -188,7 +188,7 @@ #ifdef ELMC_MULTICAST static void set_multicast_list(struct net_device *dev); #endif -static int netdev_ioctl (struct net_device *dev, struct ifreq *rq, int cmd); +static struct ethtool_ops netdev_ethtool_ops; /* helper-functions */ static int init586(struct net_device *dev); @@ -571,7 +571,7 @@ #else dev->set_multicast_list = NULL; #endif - dev->do_ioctl = netdev_ioctl; + dev->ethtool_ops = &netdev_ethtool_ops; ether_setup(dev); @@ -1228,70 +1228,17 @@ } #endif -/** - * netdev_ethtool_ioctl: Handle network interface SIOCETHTOOL ioctls - * @dev: network interface on which out-of-band action is to be performed - * @useraddr: userspace address to which data is to be read and returned - * - * Process the various commands of the SIOCETHTOOL interface. - */ - -static int netdev_ethtool_ioctl (struct net_device *dev, void *useraddr) +static void netdev_get_drvinfo(struct net_device *dev, + struct ethtool_drvinfo *info) { - u32 ethcmd; - - /* dev_ioctl() in ../../net/core/dev.c has already checked - capable(CAP_NET_ADMIN), so don't bother with that here. */ - - if (get_user(ethcmd, (u32 *)useraddr)) - return -EFAULT; - - switch (ethcmd) { - - case ETHTOOL_GDRVINFO: { - struct ethtool_drvinfo info = { ETHTOOL_GDRVINFO }; - strcpy (info.driver, DRV_NAME); - strcpy (info.version, DRV_VERSION); - sprintf(info.bus_info, "MCA 0x%lx", dev->base_addr); - if (copy_to_user (useraddr, &info, sizeof (info))) - return -EFAULT; - return 0; - } - - default: - break; - } - - return -EOPNOTSUPP; + strcpy(info->driver, DRV_NAME); + strcpy(info->version, DRV_VERSION); + sprintf(info->bus_info, "MCA 0x%lx", dev->base_addr); } -/** - * netdev_ioctl: Handle network interface ioctls - * @dev: network interface on which out-of-band action is to be performed - * @rq: user request data - * @cmd: command issued by user - * - * Process the various out-of-band ioctls passed to this driver. - */ - -static int netdev_ioctl (struct net_device *dev, struct ifreq *rq, int cmd) -{ - int rc = 0; - - switch (cmd) { - case SIOCETHTOOL: - rc = netdev_ethtool_ioctl(dev, (void *) rq->ifr_data); - break; - - default: - rc = -EOPNOTSUPP; - break; - } - - return rc; -} - -/*************************************************************************/ +static struct ethtool_ops netdev_ethtool_ops = { + .get_drvinfo = netdev_get_drvinfo, +}; #ifdef MODULE diff -Nru a/drivers/net/3c527.c b/drivers/net/3c527.c --- a/drivers/net/3c527.c Tue Sep 2 19:58:16 2003 +++ b/drivers/net/3c527.c Tue Sep 2 19:58:16 2003 @@ -218,7 +218,7 @@ static struct net_device_stats *mc32_get_stats(struct net_device *dev); static void mc32_set_multicast_list(struct net_device *dev); static void mc32_reset_multicast_list(struct net_device *dev); -static int netdev_ioctl (struct net_device *dev, struct ifreq *rq, int cmd); +static struct ethtool_ops netdev_ethtool_ops; /** * mc32_probe - Search for supported boards @@ -508,7 +508,7 @@ dev->set_multicast_list = mc32_set_multicast_list; dev->tx_timeout = mc32_timeout; dev->watchdog_timeo = HZ*5; /* Board does all the work */ - dev->do_ioctl = netdev_ioctl; + dev->ethtool_ops = &netdev_ethtool_ops; lp->xceiver_state = HALTED; @@ -1081,14 +1081,15 @@ /* NP is the buffer we will be loading */ np=lp->tx_ring[lp->tx_ring_head].p; - /* We will need this to flush the buffer out */ - lp->tx_ring[lp->tx_ring_head].skb=skb; - if (skb->len < ETH_ZLEN) { skb = skb_padto(skb, ETH_ZLEN); if (skb == NULL) goto out; } + + /* We will need this to flush the buffer out */ + lp->tx_ring[lp->tx_ring_head].skb = skb; + np->length = (skb->len < ETH_ZLEN) ? ETH_ZLEN : skb->len; np->data = isa_virt_to_bus(skb->data); @@ -1655,86 +1656,30 @@ do_mc32_set_multicast_list(dev,1); } -/** - * netdev_ethtool_ioctl: Handle network interface SIOCETHTOOL ioctls - * @dev: network interface on which out-of-band action is to be performed - * @useraddr: userspace address to which data is to be read and returned - * - * Process the various commands of the SIOCETHTOOL interface. - */ - -static int netdev_ethtool_ioctl (struct net_device *dev, void *useraddr) +static void netdev_get_drvinfo(struct net_device *dev, + struct ethtool_drvinfo *info) { - u32 ethcmd; - - /* dev_ioctl() in ../../net/core/dev.c has already checked - capable(CAP_NET_ADMIN), so don't bother with that here. */ - - if (get_user(ethcmd, (u32 *)useraddr)) - return -EFAULT; - - switch (ethcmd) { - - case ETHTOOL_GDRVINFO: { - struct ethtool_drvinfo info = { ETHTOOL_GDRVINFO }; - strcpy (info.driver, DRV_NAME); - strcpy (info.version, DRV_VERSION); - sprintf(info.bus_info, "MCA 0x%lx", dev->base_addr); - if (copy_to_user (useraddr, &info, sizeof (info))) - return -EFAULT; - return 0; - } - - /* get message-level */ - case ETHTOOL_GMSGLVL: { - struct ethtool_value edata = {ETHTOOL_GMSGLVL}; - edata.data = mc32_debug; - if (copy_to_user(useraddr, &edata, sizeof(edata))) - return -EFAULT; - return 0; - } - /* set message-level */ - case ETHTOOL_SMSGLVL: { - struct ethtool_value edata; - if (copy_from_user(&edata, useraddr, sizeof(edata))) - return -EFAULT; - mc32_debug = edata.data; - return 0; - } - - default: - break; - } - - return -EOPNOTSUPP; + strcpy(info->driver, DRV_NAME); + strcpy(info->version, DRV_VERSION); + sprintf(info->bus_info, "MCA 0x%lx", dev->base_addr); } -/** - * netdev_ioctl: Handle network interface ioctls - * @dev: network interface on which out-of-band action is to be performed - * @rq: user request data - * @cmd: command issued by user - * - * Process the various out-of-band ioctls passed to this driver. - */ +static u32 netdev_get_msglevel(struct net_device *dev) +{ + return mc32_debug; +} -static int netdev_ioctl (struct net_device *dev, struct ifreq *rq, int cmd) +static void netdev_set_msglevel(struct net_device *dev, u32 level) { - int rc = 0; + mc32_debug = level; +} - switch (cmd) { - case SIOCETHTOOL: - rc = netdev_ethtool_ioctl(dev, (void *) rq->ifr_data); - break; +static struct ethtool_ops netdev_ethtool_ops = { + .get_drvinfo = netdev_get_drvinfo, + .get_msglevel = netdev_get_msglevel, + .set_msglevel = netdev_set_msglevel, +}; - default: - rc = -EOPNOTSUPP; - break; - } - - return rc; -} - #ifdef MODULE static struct net_device this_device; diff -Nru a/drivers/net/3c59x.c b/drivers/net/3c59x.c --- a/drivers/net/3c59x.c Tue Sep 2 19:58:12 2003 +++ b/drivers/net/3c59x.c Tue Sep 2 19:58:12 2003 @@ -900,6 +900,7 @@ static int vortex_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); static void vortex_tx_timeout(struct net_device *dev); static void acpi_set_WOL(struct net_device *dev); +static struct ethtool_ops vortex_ethtool_ops; /* This driver uses 'options' to pass the media type, full-duplex flag, etc. */ /* Option count limit only -- unlimited interfaces are supported. */ @@ -1445,6 +1446,7 @@ dev->stop = vortex_close; dev->get_stats = vortex_get_stats; dev->do_ioctl = vortex_ioctl; + dev->ethtool_ops = &vortex_ethtool_ops; dev->set_multicast_list = set_rx_mode; dev->tx_timeout = vortex_tx_timeout; dev->watchdog_timeo = (watchdog * HZ) / 1000; @@ -2816,38 +2818,28 @@ } -static int netdev_ethtool_ioctl(struct net_device *dev, void *useraddr) +static void vortex_get_drvinfo(struct net_device *dev, + struct ethtool_drvinfo *info) { struct vortex_private *vp = dev->priv; - u32 ethcmd; - - if (copy_from_user(ðcmd, useraddr, sizeof(ethcmd))) - return -EFAULT; - switch (ethcmd) { - case ETHTOOL_GDRVINFO: { - struct ethtool_drvinfo info = {ETHTOOL_GDRVINFO}; - strcpy(info.driver, DRV_NAME); - strcpy(info.version, DRV_VERSION); - if (VORTEX_PCI(vp)) - strcpy(info.bus_info, pci_name(VORTEX_PCI(vp))); - else { - if (VORTEX_EISA(vp)) - sprintf (info.bus_info, vp->gendev->bus_id); - else - sprintf(info.bus_info, "EISA 0x%lx %d", - dev->base_addr, dev->irq); - } - if (copy_to_user(useraddr, &info, sizeof(info))) - return -EFAULT; - return 0; + strcpy(info->driver, DRV_NAME); + strcpy(info->version, DRV_VERSION); + if (VORTEX_PCI(vp)) { + strcpy(info->bus_info, pci_name(VORTEX_PCI(vp))); + } else { + if (VORTEX_EISA(vp)) + sprintf(info->bus_info, vp->gendev->bus_id); + else + sprintf(info->bus_info, "EISA 0x%lx %d", + dev->base_addr, dev->irq); } - - } - - return -EOPNOTSUPP; } +static struct ethtool_ops vortex_ethtool_ops = { + .get_drvinfo = vortex_get_drvinfo, +}; + static int vortex_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) { struct vortex_private *vp = (struct vortex_private *)dev->priv; @@ -2857,9 +2849,6 @@ int retval; switch(cmd) { - case SIOCETHTOOL: - return netdev_ethtool_ioctl(dev, (void *) rq->ifr_data); - case SIOCGMIIPHY: /* Get address of MII PHY in use. */ data->phy_id = phy; diff -Nru a/drivers/net/8139cp.c b/drivers/net/8139cp.c --- a/drivers/net/8139cp.c Tue Sep 2 19:58:15 2003 +++ b/drivers/net/8139cp.c Tue Sep 2 19:58:15 2003 @@ -24,15 +24,13 @@ PCI suspend/resume - Felipe Damasio LinkChg interrupt - Felipe Damasio - TODO, in rough priority order: + TODO: * Test Tx checksumming thoroughly - * dev->tx_timeout - * Constants (module parms?) for Rx work limit + * Implement dev->tx_timeout + + Low priority TODO: * Complete reset on PciErr * Consider Rx interrupt mitigation using TimerIntr - * Implement 8139C+ statistics dump; maybe not... - h/w stats can be reset only by software reset - * Handle netif_rx return value * Investigate using skb->priority with h/w VLAN priority * Investigate using High Priority Tx Queue with skb->priority * Adjust Rx FIFO threshold and Max Rx DMA burst on Rx FIFO error @@ -41,14 +39,17 @@ Tx descriptor bit * The real minimum of CP_MIN_MTU is 4 bytes. However, for this to be supported, one must(?) turn on packet padding. - * Support 8169 GMII - * Support external MII transceivers + * Support external MII transceivers (patch available) + + NOTES: + * TX checksumming is considered experimental. It is off by + default, use ethtool to turn it on. */ #define DRV_NAME "8139cp" -#define DRV_VERSION "0.3.0" -#define DRV_RELDATE "Sep 29, 2002" +#define DRV_VERSION "1.1" +#define DRV_RELDATE "Aug 30, 2003" #include @@ -71,9 +72,6 @@ #include #include -/* experimental TX checksumming feature enable/disable */ -#undef CP_TX_CHECKSUM - /* VLAN tagging feature enable/disable */ #if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE) #define CP_VLAN_TAG_USED 1 @@ -86,7 +84,7 @@ #endif /* These identify the driver base version and may not be removed. */ -static char version[] __devinitdata = +static char version[] = KERN_INFO DRV_NAME ": 10/100 PCI Ethernet driver v" DRV_VERSION " (" DRV_RELDATE ")\n"; MODULE_AUTHOR("Jeff Garzik "); @@ -160,6 +158,7 @@ TxConfig = 0x40, /* Tx configuration */ ChipVersion = 0x43, /* 8-bit chip version, inside TxConfig */ RxConfig = 0x44, /* Rx configuration */ + RxMissed = 0x4C, /* 24 bits valid, write clears */ Cfg9346 = 0x50, /* EEPROM select/control; Cfg reg [un]lock */ Config1 = 0x52, /* Config1 */ Config3 = 0x59, /* Config3 */ @@ -292,12 +291,11 @@ UWF = (1 << 4), /* Accept Unicast wakeup frame */ LANWake = (1 << 1), /* Enable LANWake signal */ PMEStatus = (1 << 0), /* PME status can be reset by PCI RST# */ -}; -static const unsigned int cp_intr_mask = - PciErr | LinkChg | - RxOK | RxErr | RxEmpty | RxFIFOOvr | - TxOK | TxErr | TxEmpty; + cp_norx_intr_mask = PciErr | LinkChg | TxOK | TxErr | TxEmpty, + cp_rx_intr_mask = RxOK | RxErr | RxEmpty | RxFIFOOvr, + cp_intr_mask = cp_rx_intr_mask | cp_norx_intr_mask, +}; static const unsigned int cp_rx_config = (RX_FIFO_THRESH << RxCfgFIFOShift) | @@ -364,11 +362,7 @@ struct pci_dev *pdev; u32 rx_config; - - struct sk_buff *frag_skb; - unsigned dropping_frag : 1; - unsigned pci_using_dac : 1; - unsigned int board_type; + u16 cpcmd; unsigned int wol_enabled : 1; /* Is Wake-on-LAN enabled? */ u32 power_state[16]; @@ -400,28 +394,9 @@ static void cp_tx (struct cp_private *cp); static void cp_clean_rings (struct cp_private *cp); -enum board_type { - RTL8139Cp, - RTL8169, -}; - -static struct cp_board_info { - const char *name; -} cp_board_tbl[] __devinitdata = { - /* RTL8139Cp */ - { "RTL-8139C+" }, - - /* RTL8169 */ - { "RTL-8169" }, -}; - static struct pci_device_id cp_pci_tbl[] = { { PCI_VENDOR_ID_REALTEK, PCI_DEVICE_ID_REALTEK_8139, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, RTL8139Cp }, -#if 0 - { PCI_VENDOR_ID_REALTEK, PCI_DEVICE_ID_REALTEK_8169, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, RTL8169 }, -#endif + PCI_ANY_ID, PCI_ANY_ID, 0, 0, }, { }, }; MODULE_DEVICE_TABLE(pci, cp_pci_tbl); @@ -446,6 +421,31 @@ }; +#if CP_VLAN_TAG_USED +static void cp_vlan_rx_register(struct net_device *dev, struct vlan_group *grp) +{ + struct cp_private *cp = dev->priv; + + spin_lock_irq(&cp->lock); + cp->vlgrp = grp; + cp->cpcmd |= RxVlanOn; + cpw16(CpCmd, cp->cpcmd); + spin_unlock_irq(&cp->lock); +} + +static void cp_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid) +{ + struct cp_private *cp = dev->priv; + + spin_lock_irq(&cp->lock); + cp->cpcmd &= ~RxVlanOn; + cpw16(CpCmd, cp->cpcmd); + if (cp->vlgrp) + cp->vlgrp->vlan_devices[vid] = NULL; + spin_unlock_irq(&cp->lock); +} +#endif /* CP_VLAN_TAG_USED */ + static inline void cp_set_rxbufsize (struct cp_private *cp) { unsigned int mtu = cp->dev->mtu; @@ -468,10 +468,11 @@ #if CP_VLAN_TAG_USED if (cp->vlgrp && (desc->opts2 & RxVlanTagged)) { - vlan_hwaccel_rx(skb, cp->vlgrp, be16_to_cpu(desc->opts2 & 0xffff)); + vlan_hwaccel_receive_skb(skb, cp->vlgrp, + be16_to_cpu(desc->opts2 & 0xffff)); } else #endif - netif_rx(skb); + netif_receive_skb(skb); } static void cp_rx_err_acct (struct cp_private *cp, unsigned rx_tail, @@ -486,81 +487,14 @@ cp->net_stats.rx_frame_errors++; if (status & RxErrCRC) cp->net_stats.rx_crc_errors++; - if (status & RxErrRunt) + if ((status & RxErrRunt) || (status & RxErrLong)) cp->net_stats.rx_length_errors++; - if (status & RxErrLong) + if ((status & (FirstFrag | LastFrag)) != (FirstFrag | LastFrag)) cp->net_stats.rx_length_errors++; if (status & RxErrFIFO) cp->net_stats.rx_fifo_errors++; } -static void cp_rx_frag (struct cp_private *cp, unsigned rx_tail, - struct sk_buff *skb, u32 status, u32 len) -{ - struct sk_buff *copy_skb, *frag_skb = cp->frag_skb; - unsigned orig_len = frag_skb ? frag_skb->len : 0; - unsigned target_len = orig_len + len; - unsigned first_frag = status & FirstFrag; - unsigned last_frag = status & LastFrag; - - if (netif_msg_rx_status (cp)) - printk (KERN_DEBUG "%s: rx %s%sfrag, slot %d status 0x%x len %d\n", - cp->dev->name, - cp->dropping_frag ? "dropping " : "", - first_frag ? "first " : - last_frag ? "last " : "", - rx_tail, status, len); - - cp->cp_stats.rx_frags++; - - if (!frag_skb && !first_frag) - cp->dropping_frag = 1; - if (cp->dropping_frag) - goto drop_frag; - - copy_skb = dev_alloc_skb (target_len + RX_OFFSET); - if (!copy_skb) { - printk(KERN_WARNING "%s: rx slot %d alloc failed\n", - cp->dev->name, rx_tail); - - cp->dropping_frag = 1; -drop_frag: - if (frag_skb) { - dev_kfree_skb_irq(frag_skb); - cp->frag_skb = NULL; - } - if (last_frag) { - cp->net_stats.rx_dropped++; - cp->dropping_frag = 0; - } - return; - } - - copy_skb->dev = cp->dev; - skb_reserve(copy_skb, RX_OFFSET); - skb_put(copy_skb, target_len); - if (frag_skb) { - memcpy(copy_skb->data, frag_skb->data, orig_len); - dev_kfree_skb_irq(frag_skb); - } - pci_dma_sync_single(cp->pdev, cp->rx_skb[rx_tail].mapping, - len, PCI_DMA_FROMDEVICE); - memcpy(copy_skb->data + orig_len, skb->data, len); - - copy_skb->ip_summed = CHECKSUM_NONE; - - if (last_frag) { - if (status & (RxError | RxErrFIFO)) { - cp_rx_err_acct(cp, rx_tail, status, len); - dev_kfree_skb_irq(copy_skb); - } else - cp_rx_skb(cp, copy_skb, &cp->rx_ring[rx_tail]); - cp->frag_skb = NULL; - } else { - cp->frag_skb = copy_skb; - } -} - static inline unsigned int cp_rx_csum_ok (u32 status) { unsigned int protocol = (status >> 16) & 0x3; @@ -574,12 +508,18 @@ return 0; } -static void cp_rx (struct cp_private *cp) +static int cp_rx_poll (struct net_device *dev, int *budget) { + struct cp_private *cp = dev->priv; unsigned rx_tail = cp->rx_tail; - unsigned rx_work = 100; + unsigned rx_work = dev->quota; + unsigned rx; + +rx_status_loop: + rx = 0; + cpw16(IntrStatus, cp_rx_intr_mask); - while (rx_work--) { + while (1) { u32 status, len; dma_addr_t mapping; struct sk_buff *skb, *new_skb; @@ -599,7 +539,14 @@ mapping = cp->rx_skb[rx_tail].mapping; if ((status & (FirstFrag | LastFrag)) != (FirstFrag | LastFrag)) { - cp_rx_frag(cp, rx_tail, skb, status, len); + /* we don't support incoming fragmented frames. + * instead, we attempt to ensure that the + * pre-allocated RX skbs are properly sized such + * that RX fragments are never encountered + */ + cp_rx_err_acct(cp, rx_tail, status, len); + cp->net_stats.rx_dropped++; + cp->cp_stats.rx_frags++; goto rx_next; } @@ -640,6 +587,7 @@ cp->rx_skb[rx_tail].skb = new_skb; cp_rx_skb(cp, skb, desc); + rx++; rx_next: cp->rx_ring[rx_tail].opts2 = 0; @@ -650,12 +598,30 @@ else desc->opts1 = cpu_to_le32(DescOwn | cp->rx_buf_sz); rx_tail = NEXT_RX(rx_tail); - } - if (!rx_work) - printk(KERN_WARNING "%s: rx work limit reached\n", cp->dev->name); + if (!rx_work--) + break; + } cp->rx_tail = rx_tail; + + dev->quota -= rx; + *budget -= rx; + + /* if we did not reach work limit, then we're done with + * this round of polling + */ + if (rx_work) { + if (cpr16(IntrStatus) & cp_rx_intr_mask) + goto rx_status_loop; + + cpw16_f(IntrMask, cp_intr_mask); + netif_rx_complete(dev); + + return 0; /* done */ + } + + return 1; /* not done */ } static irqreturn_t @@ -673,12 +639,16 @@ printk(KERN_DEBUG "%s: intr, status %04x cmd %02x cpcmd %04x\n", dev->name, status, cpr8(Cmd), cpr16(CpCmd)); - cpw16_f(IntrStatus, status); + cpw16(IntrStatus, status & ~cp_rx_intr_mask); spin_lock(&cp->lock); - if (status & (RxOK | RxErr | RxEmpty | RxFIFOOvr)) - cp_rx(cp); + if (status & (RxOK | RxErr | RxEmpty | RxFIFOOvr)) { + if (netif_rx_schedule_prep(dev)) { + cpw16_f(IntrMask, cp_norx_intr_mask); + __netif_rx_schedule(dev); + } + } if (status & (TxOK | TxErr | TxEmpty | SWInt)) cp_tx(cp); if (status & LinkChg) @@ -691,6 +661,8 @@ pci_write_config_word(cp->pdev, PCI_STATUS, pci_status); printk(KERN_ERR "%s: PCI bus error, status=%04x, PCI status=%04x\n", dev->name, status, pci_status); + + /* TODO: reset hardware */ } spin_unlock(&cp->lock); @@ -750,7 +722,7 @@ cp->tx_tail = tx_tail; - if (netif_queue_stopped(cp->dev) && (TX_BUFFS_AVAIL(cp) > (MAX_SKB_FRAGS + 1))) + if (TX_BUFFS_AVAIL(cp) > (MAX_SKB_FRAGS + 1)) netif_wake_queue(cp->dev); } @@ -792,7 +764,6 @@ txd->addr = cpu_to_le64(mapping); wmb(); -#ifdef CP_TX_CHECKSUM if (skb->ip_summed == CHECKSUM_HW) { const struct iphdr *ip = skb->nh.iph; if (ip->protocol == IPPROTO_TCP) @@ -806,7 +777,6 @@ else BUG(); } else -#endif txd->opts1 = cpu_to_le32(eor | len | DescOwn | FirstFrag | LastFrag); wmb(); @@ -820,9 +790,7 @@ u32 first_len, first_eor; dma_addr_t first_mapping; int frag, first_entry = entry; -#ifdef CP_TX_CHECKSUM const struct iphdr *ip = skb->nh.iph; -#endif /* We must give this initial chunk to the device last. * Otherwise we could race with the device. @@ -848,7 +816,7 @@ this_frag->page_offset), len, PCI_DMA_TODEVICE); eor = (entry == (CP_TX_RING_SIZE - 1)) ? RingEnd : 0; -#ifdef CP_TX_CHECKSUM + if (skb->ip_summed == CHECKSUM_HW) { ctrl = eor | len | DescOwn | IPCS; if (ip->protocol == IPPROTO_TCP) @@ -858,7 +826,6 @@ else BUG(); } else -#endif ctrl = eor | len | DescOwn; if (frag == skb_shinfo(skb)->nr_frags - 1) @@ -883,7 +850,6 @@ txd->addr = cpu_to_le64(first_mapping); wmb(); -#ifdef CP_TX_CHECKSUM if (skb->ip_summed == CHECKSUM_HW) { if (ip->protocol == IPPROTO_TCP) txd->opts1 = cpu_to_le32(first_eor | first_len | @@ -896,7 +862,6 @@ else BUG(); } else -#endif txd->opts1 = cpu_to_le32(first_eor | first_len | FirstFrag | DescOwn); wmb(); @@ -975,7 +940,9 @@ static void __cp_get_stats(struct cp_private *cp) { - /* XXX implement */ + /* only lower 24 bits valid; write any value to clear */ + cp->net_stats.rx_missed_errors += (cpr32 (RxMissed) & 0xffffff); + cpw32 (RxMissed, 0); } static struct net_device_stats *cp_get_stats(struct net_device *dev) @@ -995,11 +962,10 @@ { struct net_device *dev = cp->dev; - cpw16(IntrMask, 0); - cpr16(IntrMask); + cpw16(IntrStatus, ~(cpr16(IntrStatus))); + cpw16_f(IntrMask, 0); cpw8(Cmd, 0); - cpw16(CpCmd, 0); - cpr16(CpCmd); + cpw16_f(CpCmd, 0); cpw16(IntrStatus, ~(cpr16(IntrStatus))); synchronize_irq(dev->irq); udelay(10); @@ -1031,11 +997,7 @@ static inline void cp_start_hw (struct cp_private *cp) { - u16 pci_dac = cp->pci_using_dac ? PCIDAC : 0; - if (cp->board_type == RTL8169) - cpw16(CpCmd, pci_dac | PCIMulRW | RxChkSum); - else - cpw16(CpCmd, pci_dac | PCIMulRW | RxChkSum | CpRxOn | CpTxOn); + cpw16(CpCmd, cp->cpcmd); cpw8(Cmd, RxOn | TxOn); } @@ -1059,13 +1021,10 @@ cpw8(Config1, cpr8(Config1) | DriverLoaded | PMEnable); /* Disable Wake-on-LAN. Can be turned on with ETHTOOL_SWOL */ - if (cp->board_type == RTL8139Cp) { - cpw8(Config3, PARMEnable); - cp->wol_enabled = 0; - } + cpw8(Config3, PARMEnable); + cp->wol_enabled = 0; + cpw8(Config5, cpr8(Config5) & PMEStatus); - if (cp->board_type == RTL8169) - cpw16(RxMaxSize, cp->rx_buf_sz); cpw32_f(HiTxRingAddr, 0); cpw32_f(HiTxRingAddr + 4, 0); @@ -1258,8 +1217,6 @@ dev->mtu = new_mtu; cp_set_rxbufsize(cp); /* set new rx buf size */ - if (cp->board_type == RTL8169) - cpw16(RxMaxSize, cp->rx_buf_sz); rc = cp_init_rings(cp); /* realloc and restart h/w */ cp_start_hw(cp); @@ -1304,8 +1261,8 @@ } /* Set the ethtool Wake-on-LAN settings */ -static void netdev_set_wol (struct cp_private *cp, - const struct ethtool_wolinfo *wol) +static int netdev_set_wol (struct cp_private *cp, + const struct ethtool_wolinfo *wol) { u8 options; @@ -1332,6 +1289,8 @@ cpw8 (Config5, options); cp->wol_enabled = (wol->wolopts) ? 1 : 0; + + return 0; } /* Get the ethtool Wake-on-LAN settings */ @@ -1357,308 +1316,205 @@ if (options & MWF) wol->wolopts |= WAKE_MCAST; } -static int cp_ethtool_ioctl (struct cp_private *cp, void *useraddr) +static void cp_get_drvinfo (struct net_device *dev, struct ethtool_drvinfo *info) { - u32 ethcmd; + struct cp_private *cp = dev->priv; - /* dev_ioctl() in ../../net/core/dev.c has already checked - capable(CAP_NET_ADMIN), so don't bother with that here. */ + strcpy (info->driver, DRV_NAME); + strcpy (info->version, DRV_VERSION); + strcpy (info->bus_info, pci_name(cp->pdev)); +} - if (get_user(ethcmd, (u32 *)useraddr)) - return -EFAULT; - - switch (ethcmd) { - - case ETHTOOL_GDRVINFO: { - struct ethtool_drvinfo info = { ETHTOOL_GDRVINFO }; - strcpy (info.driver, DRV_NAME); - strcpy (info.version, DRV_VERSION); - strcpy (info.bus_info, pci_name(cp->pdev)); - info.regdump_len = CP_REGS_SIZE; - info.n_stats = CP_NUM_STATS; - if (copy_to_user (useraddr, &info, sizeof (info))) - return -EFAULT; - return 0; - } +static int cp_get_regs_len(struct net_device *dev) +{ + return CP_REGS_SIZE; +} - /* get settings */ - case ETHTOOL_GSET: { - struct ethtool_cmd ecmd = { ETHTOOL_GSET }; - spin_lock_irq(&cp->lock); - mii_ethtool_gset(&cp->mii_if, &ecmd); - spin_unlock_irq(&cp->lock); - if (copy_to_user(useraddr, &ecmd, sizeof(ecmd))) - return -EFAULT; - return 0; - } - /* set settings */ - case ETHTOOL_SSET: { - int r; - struct ethtool_cmd ecmd; - if (copy_from_user(&ecmd, useraddr, sizeof(ecmd))) - return -EFAULT; - spin_lock_irq(&cp->lock); - r = mii_ethtool_sset(&cp->mii_if, &ecmd); - spin_unlock_irq(&cp->lock); - return r; - } - /* restart autonegotiation */ - case ETHTOOL_NWAY_RST: { - return mii_nway_restart(&cp->mii_if); - } - /* get link status */ - case ETHTOOL_GLINK: { - struct ethtool_value edata = {ETHTOOL_GLINK}; - edata.data = mii_link_ok(&cp->mii_if); - if (copy_to_user(useraddr, &edata, sizeof(edata))) - return -EFAULT; - return 0; - } +static int cp_get_stats_count (struct net_device *dev) +{ + return CP_NUM_STATS; +} - /* get message-level */ - case ETHTOOL_GMSGLVL: { - struct ethtool_value edata = {ETHTOOL_GMSGLVL}; - edata.data = cp->msg_enable; - if (copy_to_user(useraddr, &edata, sizeof(edata))) - return -EFAULT; - return 0; - } - /* set message-level */ - case ETHTOOL_SMSGLVL: { - struct ethtool_value edata; - if (copy_from_user(&edata, useraddr, sizeof(edata))) - return -EFAULT; - cp->msg_enable = edata.data; - return 0; - } +static int cp_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) +{ + struct cp_private *cp = dev->priv; + int rc; - /* NIC register dump */ - case ETHTOOL_GREGS: { - struct ethtool_regs regs; - u8 *regbuf = kmalloc(CP_REGS_SIZE, GFP_KERNEL); - int rc; - - if (!regbuf) - return -ENOMEM; - memset(regbuf, 0, CP_REGS_SIZE); + spin_lock_irq(&cp->lock); + rc = mii_ethtool_gset(&cp->mii_if, cmd); + spin_unlock_irq(&cp->lock); - rc = copy_from_user(®s, useraddr, sizeof(regs)); - if (rc) { - rc = -EFAULT; - goto err_out_gregs; - } - - if (regs.len > CP_REGS_SIZE) - regs.len = CP_REGS_SIZE; - if (regs.len < CP_REGS_SIZE) { - rc = -EINVAL; - goto err_out_gregs; - } + return rc; +} - regs.version = CP_REGS_VER; - rc = copy_to_user(useraddr, ®s, sizeof(regs)); - if (rc) { - rc = -EFAULT; - goto err_out_gregs; - } +static int cp_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) +{ + struct cp_private *cp = dev->priv; + int rc; - useraddr += offsetof(struct ethtool_regs, data); + spin_lock_irq(&cp->lock); + rc = mii_ethtool_sset(&cp->mii_if, cmd); + spin_unlock_irq(&cp->lock); - spin_lock_irq(&cp->lock); - memcpy_fromio(regbuf, cp->regs, CP_REGS_SIZE); - spin_unlock_irq(&cp->lock); + return rc; +} - if (copy_to_user(useraddr, regbuf, regs.len)) - rc = -EFAULT; +static int cp_nway_reset(struct net_device *dev) +{ + struct cp_private *cp = dev->priv; + return mii_nway_restart(&cp->mii_if); +} -err_out_gregs: - kfree(regbuf); - return rc; - } +static u32 cp_get_msglevel(struct net_device *dev) +{ + struct cp_private *cp = dev->priv; + return cp->msg_enable; +} - /* get/set RX checksumming */ - case ETHTOOL_GRXCSUM: { - struct ethtool_value edata = { ETHTOOL_GRXCSUM }; - u16 cmd = cpr16(CpCmd) & RxChkSum; - - edata.data = cmd ? 1 : 0; - if (copy_to_user(useraddr, &edata, sizeof(edata))) - return -EFAULT; - return 0; - } - case ETHTOOL_SRXCSUM: { - struct ethtool_value edata; - u16 cmd = cpr16(CpCmd), newcmd; +static void cp_set_msglevel(struct net_device *dev, u32 value) +{ + struct cp_private *cp = dev->priv; + cp->msg_enable = value; +} - newcmd = cmd; +static u32 cp_get_rx_csum(struct net_device *dev) +{ + struct cp_private *cp = dev->priv; + return (cpr16(CpCmd) & RxChkSum) ? 1 : 0; +} - if (copy_from_user(&edata, useraddr, sizeof(edata))) - return -EFAULT; +static int cp_set_rx_csum(struct net_device *dev, u32 data) +{ + struct cp_private *cp = dev->priv; + u16 cmd = cp->cpcmd, newcmd; - if (edata.data) - newcmd |= RxChkSum; - else - newcmd &= ~RxChkSum; + newcmd = cmd; - if (newcmd == cmd) - return 0; + if (data) + newcmd |= RxChkSum; + else + newcmd &= ~RxChkSum; + if (newcmd != cmd) { spin_lock_irq(&cp->lock); + cp->cpcmd = newcmd; cpw16_f(CpCmd, newcmd); spin_unlock_irq(&cp->lock); } - /* get/set TX checksumming */ - case ETHTOOL_GTXCSUM: { - struct ethtool_value edata = { ETHTOOL_GTXCSUM }; - - edata.data = (cp->dev->features & NETIF_F_IP_CSUM) != 0; - if (copy_to_user(useraddr, &edata, sizeof(edata))) - return -EFAULT; - return 0; - } - case ETHTOOL_STXCSUM: { - struct ethtool_value edata; - - if (copy_from_user(&edata, useraddr, sizeof(edata))) - return -EFAULT; - - if (edata.data) - cp->dev->features |= NETIF_F_IP_CSUM; - else - cp->dev->features &= ~NETIF_F_IP_CSUM; - - return 0; - } + return 0; +} - /* get/set scatter-gather */ - case ETHTOOL_GSG: { - struct ethtool_value edata = { ETHTOOL_GSG }; - - edata.data = (cp->dev->features & NETIF_F_SG) != 0; - if (copy_to_user(useraddr, &edata, sizeof(edata))) - return -EFAULT; - return 0; - } - case ETHTOOL_SSG: { - struct ethtool_value edata; +static void cp_get_regs(struct net_device *dev, struct ethtool_regs *regs, + void *p) +{ + struct cp_private *cp = dev->priv; - if (copy_from_user(&edata, useraddr, sizeof(edata))) - return -EFAULT; + if (regs->len < CP_REGS_SIZE) + return /* -EINVAL */; - if (edata.data) - cp->dev->features |= NETIF_F_SG; - else - cp->dev->features &= ~NETIF_F_SG; + regs->version = CP_REGS_VER; - return 0; - } + spin_lock_irq(&cp->lock); + memcpy_fromio(p, cp->regs, CP_REGS_SIZE); + spin_unlock_irq(&cp->lock); +} - /* get string list(s) */ - case ETHTOOL_GSTRINGS: { - struct ethtool_gstrings estr = { ETHTOOL_GSTRINGS }; - - if (copy_from_user(&estr, useraddr, sizeof(estr))) - return -EFAULT; - if (estr.string_set != ETH_SS_STATS) - return -EINVAL; - - estr.len = CP_NUM_STATS; - if (copy_to_user(useraddr, &estr, sizeof(estr))) - return -EFAULT; - if (copy_to_user(useraddr + sizeof(estr), - ðtool_stats_keys, - sizeof(ethtool_stats_keys))) - return -EFAULT; - return 0; - } +static void cp_get_wol (struct net_device *dev, struct ethtool_wolinfo *wol) +{ + struct cp_private *cp = dev->priv; - /* get NIC-specific statistics */ - case ETHTOOL_GSTATS: { - struct ethtool_stats estats = { ETHTOOL_GSTATS }; - u64 *tmp_stats; - unsigned int work = 100; - const unsigned int sz = sizeof(u64) * CP_NUM_STATS; - int i; - - /* begin NIC statistics dump */ - cpw32(StatsAddr + 4, 0); /* FIXME: 64-bit PCI */ - cpw32(StatsAddr, cp->nic_stats_dma | DumpStats); - cpr32(StatsAddr); - - estats.n_stats = CP_NUM_STATS; - if (copy_to_user(useraddr, &estats, sizeof(estats))) - return -EFAULT; - - while (work-- > 0) { - if ((cpr32(StatsAddr) & DumpStats) == 0) - break; - cpu_relax(); - } + spin_lock_irq (&cp->lock); + netdev_get_wol (cp, wol); + spin_unlock_irq (&cp->lock); +} - if (cpr32(StatsAddr) & DumpStats) - return -EIO; +static int cp_set_wol (struct net_device *dev, struct ethtool_wolinfo *wol) +{ + struct cp_private *cp = dev->priv; + int rc; - tmp_stats = kmalloc(sz, GFP_KERNEL); - if (!tmp_stats) - return -ENOMEM; - memset(tmp_stats, 0, sz); - - i = 0; - tmp_stats[i++] = le64_to_cpu(cp->nic_stats->tx_ok); - tmp_stats[i++] = le64_to_cpu(cp->nic_stats->rx_ok); - tmp_stats[i++] = le64_to_cpu(cp->nic_stats->tx_err); - tmp_stats[i++] = le32_to_cpu(cp->nic_stats->rx_err); - tmp_stats[i++] = le16_to_cpu(cp->nic_stats->rx_fifo); - tmp_stats[i++] = le16_to_cpu(cp->nic_stats->frame_align); - tmp_stats[i++] = le32_to_cpu(cp->nic_stats->tx_ok_1col); - tmp_stats[i++] = le32_to_cpu(cp->nic_stats->tx_ok_mcol); - tmp_stats[i++] = le64_to_cpu(cp->nic_stats->rx_ok_phys); - tmp_stats[i++] = le64_to_cpu(cp->nic_stats->rx_ok_bcast); - tmp_stats[i++] = le32_to_cpu(cp->nic_stats->rx_ok_mcast); - tmp_stats[i++] = le16_to_cpu(cp->nic_stats->tx_abort); - tmp_stats[i++] = le16_to_cpu(cp->nic_stats->tx_underrun); - tmp_stats[i++] = cp->cp_stats.rx_frags; - if (i != CP_NUM_STATS) - BUG(); + spin_lock_irq (&cp->lock); + rc = netdev_set_wol (cp, wol); + spin_unlock_irq (&cp->lock); - i = copy_to_user(useraddr + sizeof(estats), - tmp_stats, sz); - kfree(tmp_stats); + return rc; +} - if (i) - return -EFAULT; - return 0; +static void cp_get_strings (struct net_device *dev, u32 stringset, u8 *buf) +{ + switch (stringset) { + case ETH_SS_STATS: + memcpy(buf, ðtool_stats_keys, sizeof(ethtool_stats_keys)); + break; + default: + BUG(); + break; } +} - /* get/set Wake-on-LAN settings */ - case ETHTOOL_GWOL: { - struct ethtool_wolinfo wol = { ETHTOOL_GWOL }; - - spin_lock_irq (&cp->lock); - netdev_get_wol (cp, &wol); - spin_unlock_irq (&cp->lock); - return ((copy_to_user (useraddr, &wol, sizeof (wol)))? -EFAULT : 0); - } - - case ETHTOOL_SWOL: { - struct ethtool_wolinfo wol; +static void cp_get_ethtool_stats (struct net_device *dev, + struct ethtool_stats *estats, u64 *tmp_stats) +{ + struct cp_private *cp = dev->priv; + unsigned int work = 100; + int i; - if (copy_from_user (&wol, useraddr, sizeof (wol))) - return -EFAULT; - spin_lock_irq (&cp->lock); - netdev_set_wol (cp, &wol); - spin_unlock_irq (&cp->lock); - return 0; - } + /* begin NIC statistics dump */ + cpw32(StatsAddr + 4, 0); /* FIXME: 64-bit PCI */ + cpw32(StatsAddr, cp->nic_stats_dma | DumpStats); + cpr32(StatsAddr); - default: - break; + while (work-- > 0) { + if ((cpr32(StatsAddr) & DumpStats) == 0) + break; + cpu_relax(); } - return -EOPNOTSUPP; + if (cpr32(StatsAddr) & DumpStats) + return /* -EIO */; + + i = 0; + tmp_stats[i++] = le64_to_cpu(cp->nic_stats->tx_ok); + tmp_stats[i++] = le64_to_cpu(cp->nic_stats->rx_ok); + tmp_stats[i++] = le64_to_cpu(cp->nic_stats->tx_err); + tmp_stats[i++] = le32_to_cpu(cp->nic_stats->rx_err); + tmp_stats[i++] = le16_to_cpu(cp->nic_stats->rx_fifo); + tmp_stats[i++] = le16_to_cpu(cp->nic_stats->frame_align); + tmp_stats[i++] = le32_to_cpu(cp->nic_stats->tx_ok_1col); + tmp_stats[i++] = le32_to_cpu(cp->nic_stats->tx_ok_mcol); + tmp_stats[i++] = le64_to_cpu(cp->nic_stats->rx_ok_phys); + tmp_stats[i++] = le64_to_cpu(cp->nic_stats->rx_ok_bcast); + tmp_stats[i++] = le32_to_cpu(cp->nic_stats->rx_ok_mcast); + tmp_stats[i++] = le16_to_cpu(cp->nic_stats->tx_abort); + tmp_stats[i++] = le16_to_cpu(cp->nic_stats->tx_underrun); + tmp_stats[i++] = cp->cp_stats.rx_frags; + if (i != CP_NUM_STATS) + BUG(); } +static struct ethtool_ops cp_ethtool_ops = { + .get_drvinfo = cp_get_drvinfo, + .get_regs_len = cp_get_regs_len, + .get_stats_count = cp_get_stats_count, + .get_settings = cp_get_settings, + .set_settings = cp_set_settings, + .nway_reset = cp_nway_reset, + .get_link = ethtool_op_get_link, + .get_msglevel = cp_get_msglevel, + .set_msglevel = cp_set_msglevel, + .get_rx_csum = cp_get_rx_csum, + .set_rx_csum = cp_set_rx_csum, + .get_tx_csum = ethtool_op_get_tx_csum, + .set_tx_csum = ethtool_op_set_tx_csum, /* local! */ + .get_sg = ethtool_op_get_sg, + .set_sg = ethtool_op_set_sg, + .get_regs = cp_get_regs, + .get_wol = cp_get_wol, + .set_wol = cp_set_wol, + .get_strings = cp_get_strings, + .get_ethtool_stats = cp_get_ethtool_stats, +}; static int cp_ioctl (struct net_device *dev, struct ifreq *rq, int cmd) { @@ -1669,38 +1525,12 @@ if (!netif_running(dev)) return -EINVAL; - if (cmd == SIOCETHTOOL) - return cp_ethtool_ioctl(cp, (void *) rq->ifr_data); - spin_lock_irq(&cp->lock); rc = generic_mii_ioctl(&cp->mii_if, mii, cmd, NULL); spin_unlock_irq(&cp->lock); return rc; } -#if CP_VLAN_TAG_USED -static void cp_vlan_rx_register(struct net_device *dev, struct vlan_group *grp) -{ - struct cp_private *cp = dev->priv; - - spin_lock_irq(&cp->lock); - cp->vlgrp = grp; - cpw16(CpCmd, cpr16(CpCmd) | RxVlanOn); - spin_unlock_irq(&cp->lock); -} - -static void cp_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid) -{ - struct cp_private *cp = dev->priv; - - spin_lock_irq(&cp->lock); - cpw16(CpCmd, cpr16(CpCmd) & ~RxVlanOn); - if (cp->vlgrp) - cp->vlgrp->vlan_devices[vid] = NULL; - spin_unlock_irq(&cp->lock); -} -#endif - /* Serial EEPROM section. */ /* EEPROM_Ctrl bits. */ @@ -1723,7 +1553,7 @@ #define EE_READ_CMD (6) #define EE_ERASE_CMD (7) -static int __devinit read_eeprom (void *ioaddr, int location, int addr_len) +static int read_eeprom (void *ioaddr, int location, int addr_len) { int i; unsigned retval = 0; @@ -1769,17 +1599,15 @@ pci_set_power_state (cp->pdev, 3); } -static int __devinit cp_init_one (struct pci_dev *pdev, - const struct pci_device_id *ent) +static int cp_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) { struct net_device *dev; struct cp_private *cp; int rc; void *regs; long pciaddr; - unsigned int addr_len, i; - u8 pci_rev, cache_size; - unsigned int board_type = (unsigned int) ent->driver_data; + unsigned int addr_len, i, pci_using_dac; + u8 pci_rev; #ifndef MODULE static int version_printed; @@ -1805,7 +1633,6 @@ cp = dev->priv; cp->pdev = pdev; - cp->board_type = board_type; cp->dev = dev; cp->msg_enable = (debug < 0 ? CP_DEF_MSG_ENABLE : debug); spin_lock_init (&cp->lock); @@ -1821,10 +1648,14 @@ if (rc) goto err_out_free; - rc = pci_request_regions(pdev, DRV_NAME); + rc = pci_set_mwi(pdev); if (rc) goto err_out_disable; + rc = pci_request_regions(pdev, DRV_NAME); + if (rc) + goto err_out_mwi; + if (pdev->irq < 2) { rc = -EIO; printk(KERN_ERR PFX "invalid irq (%d) for pci dev %s\n", @@ -1846,18 +1677,22 @@ } /* Configure DMA attributes. */ - if (!pci_set_dma_mask(pdev, (u64) 0xffffffffffffffffULL)) { - cp->pci_using_dac = 1; + if ((sizeof(dma_addr_t) > 32) && + !pci_set_dma_mask(pdev, 0xffffffffffffffffULL)) { + pci_using_dac = 1; } else { - rc = pci_set_dma_mask(pdev, (u64) 0xffffffff); + rc = pci_set_dma_mask(pdev, 0xffffffffULL); if (rc) { printk(KERN_ERR PFX "No usable DMA configuration, " "aborting.\n"); goto err_out_res; } - cp->pci_using_dac = 0; + pci_using_dac = 0; } + cp->cpcmd = (pci_using_dac ? PCIDAC : 0) | + PCIMulRW | RxChkSum | CpRxOn | CpTxOn; + regs = ioremap_nocache(pciaddr, CP_REGS_SIZE); if (!regs) { rc = -EIO; @@ -1882,16 +1717,17 @@ dev->hard_start_xmit = cp_start_xmit; dev->get_stats = cp_get_stats; dev->do_ioctl = cp_ioctl; + dev->poll = cp_rx_poll; + dev->weight = 16; /* arbitrary? from NAPI_HOWTO.txt. */ #ifdef BROKEN dev->change_mtu = cp_change_mtu; #endif + dev->ethtool_ops = &cp_ethtool_ops; #if 0 dev->tx_timeout = cp_tx_timeout; dev->watchdog_timeo = TX_TIMEOUT; #endif -#ifdef CP_TX_CHECKSUM - dev->features |= NETIF_F_SG | NETIF_F_IP_CSUM; -#endif + #if CP_VLAN_TAG_USED dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX; dev->vlan_rx_register = cp_vlan_rx_register; @@ -1904,11 +1740,10 @@ if (rc) goto err_out_iomap; - printk (KERN_INFO "%s: %s at 0x%lx, " + printk (KERN_INFO "%s: RTL-8139C+ at 0x%lx, " "%02x:%02x:%02x:%02x:%02x:%02x, " "IRQ %d\n", dev->name, - cp_board_tbl[board_type].name, dev->base_addr, dev->dev_addr[0], dev->dev_addr[1], dev->dev_addr[2], dev->dev_addr[3], @@ -1917,29 +1752,8 @@ pci_set_drvdata(pdev, dev); - /* - * Looks like this is necessary to deal with on all architectures, - * even this %$#%$# N440BX Intel based thing doesn't get it right. - * Ie. having two NICs in the machine, one will have the cache - * line set at boot time, the other will not. - */ - pci_read_config_byte(pdev, PCI_CACHE_LINE_SIZE, &cache_size); - cache_size <<= 2; - if (cache_size != SMP_CACHE_BYTES) { - printk(KERN_INFO "%s: PCI cache line size set incorrectly " - "(%i bytes) by BIOS/FW, ", dev->name, cache_size); - if (cache_size > SMP_CACHE_BYTES) - printk("expecting %i\n", SMP_CACHE_BYTES); - else { - printk("correcting to %i\n", SMP_CACHE_BYTES); - pci_write_config_byte(pdev, PCI_CACHE_LINE_SIZE, - SMP_CACHE_BYTES >> 2); - } - } - /* enable busmastering and memory-write-invalidate */ pci_set_master(pdev); - pci_set_mwi(pdev); if (cp->wol_enabled) cp_set_d3_state (cp); @@ -1949,6 +1763,8 @@ iounmap(regs); err_out_res: pci_release_regions(pdev); +err_out_mwi: + pci_clear_mwi(pdev); err_out_disable: pci_disable_device(pdev); err_out_free: @@ -1956,7 +1772,7 @@ return rc; } -static void __devexit cp_remove_one (struct pci_dev *pdev) +static void cp_remove_one (struct pci_dev *pdev) { struct net_device *dev = pci_get_drvdata(pdev); struct cp_private *cp = dev->priv; @@ -1967,6 +1783,7 @@ iounmap(cp->regs); if (cp->wol_enabled) pci_set_power_state (pdev, 0); pci_release_regions(pdev); + pci_clear_mwi(pdev); pci_disable_device(pdev); pci_set_drvdata(pdev, NULL); free_netdev(dev); @@ -2029,7 +1846,7 @@ .name = DRV_NAME, .id_table = cp_pci_tbl, .probe = cp_init_one, - .remove = __devexit_p(cp_remove_one), + .remove = cp_remove_one, #ifdef CONFIG_PM .resume = cp_resume, .suspend = cp_suspend, diff -Nru a/drivers/net/8139too.c b/drivers/net/8139too.c --- a/drivers/net/8139too.c Tue Sep 2 19:58:12 2003 +++ b/drivers/net/8139too.c Tue Sep 2 19:58:12 2003 @@ -123,6 +123,11 @@ #define USE_IO_OPS 1 #endif +/* use a 16K rx ring buffer instead of the default 32K */ +#ifdef CONFIG_SH_DREAMCAST +#define USE_BUF16K 1 +#endif + /* define to 1 to enable copious debugging info */ #undef RTL8139_DEBUG @@ -165,7 +170,11 @@ static int debug = -1; /* Size of the in-memory receive ring. */ +#ifdef USE_BUF16K +#define RX_BUF_LEN_IDX 1 /* 0==8K, 1==16K, 2==32K, 3==64K */ +#else #define RX_BUF_LEN_IDX 2 /* 0==8K, 1==16K, 2==32K, 3==64K */ +#endif #define RX_BUF_LEN (8192 << RX_BUF_LEN_IDX) #define RX_BUF_PAD 16 #define RX_BUF_WRAP_PAD 2048 /* spare padding to handle lack of packet wrap */ @@ -212,18 +221,7 @@ typedef enum { RTL8139 = 0, - RTL8139_CB, - SMC1211TX, - /*MPX5030,*/ - DELTA8139, - ADDTRON8139, - DFE538TX, - DFE690TXD, - FE2000VX, - ALLIED8139, RTL8129, - FNW3603TX, - FNW3800TX, } board_t; @@ -232,36 +230,29 @@ const char *name; u32 hw_flags; } board_info[] __devinitdata = { - { "RealTek RTL8139 Fast Ethernet", RTL8139_CAPS }, - { "RealTek RTL8139B PCI/CardBus", RTL8139_CAPS }, - { "SMC1211TX EZCard 10/100 (RealTek RTL8139)", RTL8139_CAPS }, -/* { MPX5030, "Accton MPX5030 (RealTek RTL8139)", RTL8139_CAPS },*/ - { "Delta Electronics 8139 10/100BaseTX", RTL8139_CAPS }, - { "Addtron Technolgy 8139 10/100BaseTX", RTL8139_CAPS }, - { "D-Link DFE-538TX (RealTek RTL8139)", RTL8139_CAPS }, - { "D-Link DFE-690TXD (RealTek RTL8139)", RTL8139_CAPS }, - { "AboCom FE2000VX (RealTek RTL8139)", RTL8139_CAPS }, - { "Allied Telesyn 8139 CardBus", RTL8139_CAPS }, + { "RealTek RTL8139", RTL8139_CAPS }, { "RealTek RTL8129", RTL8129_CAPS }, - { "Planex FNW-3603-TX 10/100 CardBus", RTL8139_CAPS }, - { "Planex FNW-3800-TX 10/100 CardBus", RTL8139_CAPS }, }; static struct pci_device_id rtl8139_pci_tbl[] = { {0x10ec, 0x8139, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RTL8139 }, - {0x10ec, 0x8138, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RTL8139_CB }, - {0x1113, 0x1211, PCI_ANY_ID, PCI_ANY_ID, 0, 0, SMC1211TX }, -/* {0x1113, 0x1211, PCI_ANY_ID, PCI_ANY_ID, 0, 0, MPX5030 },*/ - {0x1500, 0x1360, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DELTA8139 }, - {0x4033, 0x1360, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ADDTRON8139 }, - {0x1186, 0x1300, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DFE538TX }, - {0x1186, 0x1340, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DFE690TXD }, - {0x13d1, 0xab06, PCI_ANY_ID, PCI_ANY_ID, 0, 0, FE2000VX }, - {0x1259, 0xa117, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ALLIED8139 }, - {0x14ea, 0xab06, PCI_ANY_ID, PCI_ANY_ID, 0, 0, FNW3603TX }, - {0x14ea, 0xab07, PCI_ANY_ID, PCI_ANY_ID, 0, 0, FNW3800TX }, - + {0x10ec, 0x8138, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RTL8139 }, + {0x1113, 0x1211, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RTL8139 }, + {0x1500, 0x1360, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RTL8139 }, + {0x4033, 0x1360, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RTL8139 }, + {0x1186, 0x1300, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RTL8139 }, + {0x1186, 0x1340, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RTL8139 }, + {0x13d1, 0xab06, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RTL8139 }, + {0x1259, 0xa117, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RTL8139 }, + {0x14ea, 0xab06, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RTL8139 }, + {0x14ea, 0xab07, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RTL8139 }, + {0x11db, 0x1234, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RTL8139 }, + +#ifdef CONFIG_SH_SECUREEDGE5410 + /* Bogus 8139 silicon reports 8129 without external PROM :-( */ + {0x10ec, 0x8129, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RTL8139 }, +#endif #ifdef CONFIG_8139TOO_8129 {0x10ec, 0x8129, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RTL8129 }, #endif @@ -271,8 +262,8 @@ * so we simply don't match on the main vendor id. */ {PCI_ANY_ID, 0x8139, 0x10ec, 0x8139, 0, 0, RTL8139 }, - {PCI_ANY_ID, 0x8139, 0x1186, 0x1300, 0, 0, DFE538TX }, - {PCI_ANY_ID, 0x8139, 0x13d1, 0xab06, 0, 0, FE2000VX }, + {PCI_ANY_ID, 0x8139, 0x1186, 0x1300, 0, 0, RTL8139 }, + {PCI_ANY_ID, 0x8139, 0x13d1, 0xab06, 0, 0, RTL8139 }, {0,} }; @@ -302,7 +293,6 @@ IntrMask = 0x3C, IntrStatus = 0x3E, TxConfig = 0x40, - ChipVersion = 0x43, RxConfig = 0x44, Timer = 0x48, /* A general-purpose counter. */ RxMissed = 0x4C, /* 24 bits valid, write clears. */ @@ -461,7 +451,6 @@ RxNoWrap = (1 << 7), }; - /* Twister tuning parameters from RealTek. Completely undocumented, but required to tune bad links on some boards. */ enum CSCRBits { @@ -472,36 +461,22 @@ CSCR_LinkDownCmd = 0x0f3c0, }; - enum Cfg9346Bits { Cfg9346_Lock = 0x00, Cfg9346_Unlock = 0xC0, }; -#ifdef CONFIG_8139TOO_TUNE_TWISTER - -enum TwisterParamVals { - PARA78_default = 0x78fa8388, - PARA7c_default = 0xcb38de43, /* param[0][3] */ - PARA7c_xxx = 0xcb38de43, -}; - -static const unsigned long param[4][4] = { - {0xcb39de43, 0xcb39ce43, 0xfb38de03, 0xcb38de43}, - {0xcb39de43, 0xcb39ce43, 0xcb39ce83, 0xcb39ce83}, - {0xcb39de43, 0xcb39ce43, 0xcb39ce83, 0xcb39ce83}, - {0xbb39de43, 0xbb39ce43, 0xbb39ce83, 0xbb39ce83} -}; - -#endif /* CONFIG_8139TOO_TUNE_TWISTER */ - typedef enum { CH_8139 = 0, CH_8139_K, CH_8139A, + CH_8139A_G, CH_8139B, CH_8130, CH_8139C, + CH_8100, + CH_8100B_8139D, + CH_8101, } chip_t; enum chip_flags { @@ -509,50 +484,65 @@ HasLWake = (1 << 1), }; +#define HW_REVID(b30, b29, b28, b27, b26, b23, b22) \ + (b30<<30 | b29<<29 | b28<<28 | b27<<27 | b26<<26 | b23<<23 | b22<<22) +#define HW_REVID_MASK HW_REVID(1, 1, 1, 1, 1, 1, 1) /* directly indexed by chip_t, above */ const static struct { const char *name; - u8 version; /* from RTL8139C docs */ - u32 RxConfigMask; /* should clear the bits supported by this chip */ + u32 version; /* from RTL8139C/RTL8139D docs */ u32 flags; } rtl_chip_info[] = { { "RTL-8139", - 0x40, - 0xf0fe0040, /* XXX copied from RTL8139A, verify */ + HW_REVID(1, 0, 0, 0, 0, 0, 0), HasHltClk, }, { "RTL-8139 rev K", - 0x60, - 0xf0fe0040, + HW_REVID(1, 1, 0, 0, 0, 0, 0), HasHltClk, }, { "RTL-8139A", - 0x70, - 0xf0fe0040, + HW_REVID(1, 1, 1, 0, 0, 0, 0), + HasHltClk, /* XXX undocumented? */ + }, + + { "RTL-8139A rev G", + HW_REVID(1, 1, 1, 0, 0, 1, 0), HasHltClk, /* XXX undocumented? */ }, { "RTL-8139B", - 0x78, - 0xf0fc0040, + HW_REVID(1, 1, 1, 1, 0, 0, 0), HasLWake, }, { "RTL-8130", - 0x7C, - 0xf0fe0040, /* XXX copied from RTL8139A, verify */ + HW_REVID(1, 1, 1, 1, 1, 0, 0), HasLWake, }, { "RTL-8139C", - 0x74, - 0xf0fc0040, /* XXX copied from RTL8139B, verify */ + HW_REVID(1, 1, 1, 0, 1, 0, 0), HasLWake, }, + { "RTL-8100", + HW_REVID(1, 1, 1, 1, 0, 1, 0), + HasLWake, + }, + + { "RTL-8100B/8139D", + HW_REVID(1, 1, 1, 0, 1, 0, 1), + HasLWake, + }, + + { "RTL-8101", + HW_REVID(1, 1, 1, 0, 1, 1, 1), + HasLWake, + }, }; struct rtl_extra_stats { @@ -612,7 +602,7 @@ static 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 val); -static int rtl8139_thread (void *data); +static inline void rtl8139_start_thread(struct net_device *dev); static void rtl8139_tx_timeout (struct net_device *dev); static void rtl8139_init_ring (struct net_device *dev); static int rtl8139_start_xmit (struct sk_buff *skb, @@ -625,6 +615,7 @@ static void rtl8139_set_rx_mode (struct net_device *dev); static void __set_rx_mode (struct net_device *dev); static void rtl8139_hw_start (struct net_device *dev); +static struct ethtool_ops rtl8139_ethtool_ops; #ifdef USE_IO_OPS @@ -688,10 +679,17 @@ PCIErr | PCSTimeout | RxUnderrun | RxOverflow | RxFIFOOver | TxErr | TxOK | RxErr | RxOK; +#ifdef USE_BUF16K +static const unsigned int rtl8139_rx_config = + RxCfgRcv16K | RxNoWrap | + (RX_FIFO_THRESH << RxCfgFIFOShift) | + (RX_DMA_BURST << RxCfgDMAShift); +#else static const unsigned int rtl8139_rx_config = RxCfgRcv32K | RxNoWrap | (RX_FIFO_THRESH << RxCfgFIFOShift) | (RX_DMA_BURST << RxCfgDMAShift); +#endif static const unsigned int rtl8139_tx_config = (TX_DMA_BURST << TxDMAShift) | (TX_RETRY << TxRetryShift); @@ -716,13 +714,6 @@ /* it's ok to call this even if we have no regions to free */ pci_release_regions (pdev); -#ifndef RTL8139_NDEBUG - /* poison memory before freeing */ - memset (dev, 0xBC, - sizeof (struct net_device) + - sizeof (struct rtl8139_private)); -#endif /* RTL8139_NDEBUG */ - free_netdev(dev); pci_set_drvdata (pdev, NULL); @@ -757,7 +748,7 @@ unsigned int i; u32 pio_start, pio_end, pio_flags, pio_len; unsigned long mmio_start, mmio_end, mmio_flags, mmio_len; - u32 tmp; + u32 version; assert (pdev != NULL); @@ -859,9 +850,9 @@ } /* identify chip attached to board */ - tmp = RTL_R8 (ChipVersion); + version = RTL_R32 (TxConfig) & HW_REVID_MASK; for (i = 0; i < ARRAY_SIZE (rtl_chip_info); i++) - if (tmp == rtl_chip_info[i].version) { + if (version == rtl_chip_info[i].version) { tp->chipset = i; goto match; } @@ -892,8 +883,11 @@ } if (rtl_chip_info[tp->chipset].flags & HasLWake) { tmp8 = RTL_R8 (Config4); - if (tmp8 & LWPTN) + if (tmp8 & LWPTN) { + RTL_W8 (Cfg9346, Cfg9346_Unlock); RTL_W8 (Config4, tmp8 & ~LWPTN); + RTL_W8 (Cfg9346, Cfg9346_Lock); + } } } else { DPRINTK("Old chip wakeup\n"); @@ -971,6 +965,7 @@ dev->get_stats = rtl8139_get_stats; dev->set_multicast_list = rtl8139_set_rx_mode; dev->do_ioctl = netdev_ioctl; + dev->ethtool_ops = &rtl8139_ethtool_ops; dev->tx_timeout = rtl8139_tx_timeout; dev->watchdog_timeo = TX_TIMEOUT; @@ -1318,8 +1313,6 @@ tp->mii.full_duplex = tp->mii.force_media; tp->tx_flag = (TX_FIFO_THRESH << 11) & 0x003f0000; - tp->twistie = (tp->chipset == CH_8139_K) ? 1 : 0; - tp->time_to_die = 0; rtl8139_init_ring (dev); rtl8139_hw_start (dev); @@ -1330,32 +1323,18 @@ dev->irq, RTL_R8 (MediaStatus), tp->mii.full_duplex ? "full" : "half"); - tp->thr_pid = kernel_thread (rtl8139_thread, dev, CLONE_FS | CLONE_FILES); - if (tp->thr_pid < 0) - printk (KERN_WARNING "%s: unable to start kernel thread\n", - dev->name); + rtl8139_start_thread(dev); return 0; } -static void rtl_check_media (struct net_device *dev) +static void rtl_check_media (struct net_device *dev, unsigned int init_media) { struct rtl8139_private *tp = dev->priv; if (tp->phys[0] >= 0) { - u16 mii_lpa = mdio_read(dev, tp->phys[0], MII_LPA); - if (mii_lpa == 0xffff) - ; /* Not there */ - else if ((mii_lpa & LPA_100FULL) == LPA_100FULL - || (mii_lpa & 0x00C0) == LPA_10FULL) - tp->mii.full_duplex = 1; - - printk (KERN_INFO"%s: Setting %s%s-duplex based on" - " auto-negotiated partner ability %4.4x.\n", - dev->name, mii_lpa == 0 ? "" : - (mii_lpa & 0x0180) ? "100mbps " : "10mbps ", - tp->mii.full_duplex ? "full" : "half", mii_lpa); + mii_check_media(&tp->mii, 1, init_media); } } @@ -1390,7 +1369,7 @@ tp->cur_rx = 0; - rtl_check_media (dev); + rtl_check_media (dev, 1); if (tp->chipset >= CH_8139B) { /* Disable magic packet scanning, which is enabled @@ -1452,6 +1431,19 @@ static inline void rtl8139_tune_twister (struct net_device *dev, struct rtl8139_private *tp) {} #else +enum TwisterParamVals { + PARA78_default = 0x78fa8388, + PARA7c_default = 0xcb38de43, /* param[0][3] */ + PARA7c_xxx = 0xcb38de43, +}; + +static const unsigned long param[4][4] = { + {0xcb39de43, 0xcb39ce43, 0xfb38de03, 0xcb38de43}, + {0xcb39de43, 0xcb39ce43, 0xcb39ce83, 0xcb39ce83}, + {0xcb39de43, 0xcb39ce43, 0xcb39ce83, 0xcb39ce83}, + {0xbb39de43, 0xbb39ce43, 0xbb39ce83, 0xbb39ce83} +}; + static void rtl8139_tune_twister (struct net_device *dev, struct rtl8139_private *tp) { @@ -1538,7 +1530,6 @@ } #endif /* CONFIG_8139TOO_TUNE_TWISTER */ - static inline void rtl8139_thread_iter (struct net_device *dev, struct rtl8139_private *tp, void *ioaddr) @@ -1585,7 +1576,6 @@ RTL_R8 (Config1)); } - static int rtl8139_thread (void *data) { struct net_device *dev = data; @@ -1619,6 +1609,24 @@ complete_and_exit (&tp->thr_exited, 0); } +static inline void rtl8139_start_thread(struct net_device *dev) +{ + struct rtl8139_private *tp = dev->priv; + + tp->thr_pid = -1; + tp->twistie = 0; + tp->time_to_die = 0; + if (tp->chipset == CH_8139_K) + tp->twistie = 1; + else if (tp->drv_flags & HAS_LNK_CHNG) + return; + + tp->thr_pid = kernel_thread(rtl8139_thread, dev, CLONE_FS|CLONE_FILES); + if (tp->thr_pid < 0) { + printk (KERN_WARNING "%s: unable to start kernel thread\n", + dev->name); + } +} static void rtl8139_tx_clear (struct rtl8139_private *tp) { @@ -1999,18 +2007,7 @@ if ((status & RxUnderrun) && link_changed && (tp->drv_flags & HAS_LNK_CHNG)) { - /* Really link-change on new chips. */ - int lpar = RTL_R16 (NWayLPAR); - int duplex = (lpar & LPA_100FULL) || (lpar & 0x01C0) == 0x0040 - || tp->mii.force_media; - if (tp->mii.full_duplex != duplex) { - tp->mii.full_duplex = duplex; -#if 0 - RTL_W8 (Cfg9346, Cfg9346_Unlock); - RTL_W8 (Config1, tp->mii.full_duplex ? 0x60 : 0x20); - RTL_W8 (Cfg9346, Cfg9346_Lock); -#endif - } + rtl_check_media(dev, 0); status &= ~RxUnderrun; } @@ -2173,11 +2170,12 @@ /* Get the ethtool Wake-on-LAN settings. Assumes that wol points to kernel memory, *wol has been initialized as {ETHTOOL_GWOL}, and other threads or interrupts aren't messing with the 8139. */ -static void netdev_get_wol (struct net_device *dev, struct ethtool_wolinfo *wol) +static void rtl8139_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol) { struct rtl8139_private *np = dev->priv; void *ioaddr = np->mmio_addr; + spin_lock_irq(&np->lock); if (rtl_chip_info[np->chipset].flags & HasLWake) { u8 cfg3 = RTL_R8 (Config3); u8 cfg5 = RTL_R8 (Config5); @@ -2199,14 +2197,14 @@ if (cfg5 & Cfg5_BWF) wol->wolopts |= WAKE_BCAST; } + spin_unlock_irq(&np->lock); } /* Set the ethtool Wake-on-LAN settings. Return 0 or -errno. Assumes that wol points to kernel memory and other threads or interrupts aren't messing with the 8139. */ -static int netdev_set_wol (struct net_device *dev, - const struct ethtool_wolinfo *wol) +static int rtl8139_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol) { struct rtl8139_private *np = dev->priv; void *ioaddr = np->mmio_addr; @@ -2220,6 +2218,7 @@ if (wol->wolopts & ~support) return -EINVAL; + spin_lock_irq(&np->lock); cfg3 = RTL_R8 (Config3) & ~(Cfg3_LinkUp | Cfg3_Magic); if (wol->wolopts & WAKE_PHY) cfg3 |= Cfg3_LinkUp; @@ -2240,213 +2239,120 @@ if (wol->wolopts & WAKE_BCAST) cfg5 |= Cfg5_BWF; RTL_W8 (Config5, cfg5); /* need not unlock via Cfg9346 */ + spin_unlock_irq(&np->lock); return 0; } -static int netdev_ethtool_ioctl (struct net_device *dev, void *useraddr) +static void rtl8139_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info) { struct rtl8139_private *np = dev->priv; - u32 ethcmd; - - /* dev_ioctl() in ../../net/core/dev.c has already checked - capable(CAP_NET_ADMIN), so don't bother with that here. */ + strcpy(info->driver, DRV_NAME); + strcpy(info->version, DRV_VERSION); + strcpy(info->bus_info, pci_name(np->pci_dev)); + info->regdump_len = np->regs_len; +} - if (get_user(ethcmd, (u32 *)useraddr)) - return -EFAULT; +static int rtl8139_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) +{ + struct rtl8139_private *np = dev->priv; + spin_lock_irq(&np->lock); + mii_ethtool_gset(&np->mii, cmd); + spin_unlock_irq(&np->lock); + return 0; +} - switch (ethcmd) { - - case ETHTOOL_GDRVINFO: { - struct ethtool_drvinfo info = { ETHTOOL_GDRVINFO }; - strcpy (info.driver, DRV_NAME); - strcpy (info.version, DRV_VERSION); - strcpy (info.bus_info, pci_name(np->pci_dev)); - info.regdump_len = np->regs_len; - if (copy_to_user (useraddr, &info, sizeof (info))) - return -EFAULT; - return 0; - } +static int rtl8139_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) +{ + struct rtl8139_private *np = dev->priv; + int rc; + spin_lock_irq(&np->lock); + rc = mii_ethtool_sset(&np->mii, cmd); + spin_unlock_irq(&np->lock); + return rc; +} - /* get settings */ - case ETHTOOL_GSET: { - struct ethtool_cmd ecmd = { ETHTOOL_GSET }; - spin_lock_irq(&np->lock); - mii_ethtool_gset(&np->mii, &ecmd); - spin_unlock_irq(&np->lock); - if (copy_to_user(useraddr, &ecmd, sizeof(ecmd))) - return -EFAULT; - return 0; - } - /* set settings */ - case ETHTOOL_SSET: { - int r; - struct ethtool_cmd ecmd; - if (copy_from_user(&ecmd, useraddr, sizeof(ecmd))) - return -EFAULT; - spin_lock_irq(&np->lock); - r = mii_ethtool_sset(&np->mii, &ecmd); - spin_unlock_irq(&np->lock); - return r; - } - /* restart autonegotiation */ - case ETHTOOL_NWAY_RST: { - return mii_nway_restart(&np->mii); - } - /* get link status */ - case ETHTOOL_GLINK: { - struct ethtool_value edata = {ETHTOOL_GLINK}; - edata.data = mii_link_ok(&np->mii); - if (copy_to_user(useraddr, &edata, sizeof(edata))) - return -EFAULT; - return 0; - } +static int rtl8139_nway_reset(struct net_device *dev) +{ + struct rtl8139_private *np = dev->priv; + return mii_nway_restart(&np->mii); +} - /* get message-level */ - case ETHTOOL_GMSGLVL: { - struct ethtool_value edata = {ETHTOOL_GMSGLVL}; - edata.data = debug; - if (copy_to_user(useraddr, &edata, sizeof(edata))) - return -EFAULT; - return 0; - } - /* set message-level */ - case ETHTOOL_SMSGLVL: { - struct ethtool_value edata; - if (copy_from_user(&edata, useraddr, sizeof(edata))) - return -EFAULT; - debug = edata.data; - return 0; - } +static u32 rtl8139_get_link(struct net_device *dev) +{ + struct rtl8139_private *np = dev->priv; + return mii_link_ok(&np->mii); +} - case ETHTOOL_GWOL: - { - struct ethtool_wolinfo wol = { ETHTOOL_GWOL }; - spin_lock_irq (&np->lock); - netdev_get_wol (dev, &wol); - spin_unlock_irq (&np->lock); - if (copy_to_user (useraddr, &wol, sizeof (wol))) - return -EFAULT; - return 0; - } +static u32 rtl8139_get_msglevel(struct net_device *dev) +{ + return debug; +} - case ETHTOOL_SWOL: - { - struct ethtool_wolinfo wol; - int rc; - if (copy_from_user (&wol, useraddr, sizeof (wol))) - return -EFAULT; - spin_lock_irq (&np->lock); - rc = netdev_set_wol (dev, &wol); - spin_unlock_irq (&np->lock); - return rc; - } +static void rtl8139_set_msglevel(struct net_device *dev, u32 datum) +{ + debug = datum; +} /* TODO: we are too slack to do reg dumping for pio, for now */ -#ifndef CONFIG_8139TOO_PIO - /* NIC register dump */ - case ETHTOOL_GREGS: { - struct ethtool_regs regs; - unsigned int regs_len = np->regs_len; - u8 *regbuf = kmalloc(regs_len, GFP_KERNEL); - int rc; - - if (!regbuf) - return -ENOMEM; - memset(regbuf, 0, regs_len); - - rc = copy_from_user(®s, useraddr, sizeof(regs)); - if (rc) { - rc = -EFAULT; - goto err_out_gregs; - } - - if (regs.len > regs_len) - regs.len = regs_len; - if (regs.len < regs_len) { - rc = -EINVAL; - goto err_out_gregs; - } - - regs.version = RTL_REGS_VER; - rc = copy_to_user(useraddr, ®s, sizeof(regs)); - if (rc) { - rc = -EFAULT; - goto err_out_gregs; - } - - useraddr += offsetof(struct ethtool_regs, data); - - spin_lock_irq(&np->lock); - memcpy_fromio(regbuf, np->mmio_addr, regs_len); - spin_unlock_irq(&np->lock); - - if (copy_to_user(useraddr, regbuf, regs_len)) - rc = -EFAULT; - -err_out_gregs: - kfree(regbuf); - return rc; - } -#endif /* CONFIG_8139TOO_PIO */ - - /* get string list(s) */ - case ETHTOOL_GSTRINGS: { - struct ethtool_gstrings estr = { ETHTOOL_GSTRINGS }; - - if (copy_from_user(&estr, useraddr, sizeof(estr))) - return -EFAULT; - if (estr.string_set != ETH_SS_STATS) - return -EINVAL; - - estr.len = RTL_NUM_STATS; - if (copy_to_user(useraddr, &estr, sizeof(estr))) - return -EFAULT; - if (copy_to_user(useraddr + sizeof(estr), - ðtool_stats_keys, - sizeof(ethtool_stats_keys))) - return -EFAULT; - return 0; - } +#ifdef CONFIG_8139TOO_PIO +#define rtl8139_get_regs_len NULL +#define rtl8139_get_regs NULL +#else +static int rtl8139_get_regs_len(struct net_device *dev) +{ + struct rtl8139_private *np = dev->priv; + return np->regs_len; +} - /* get NIC-specific statistics */ - case ETHTOOL_GSTATS: { - struct ethtool_stats estats = { ETHTOOL_GSTATS }; - u64 *tmp_stats; - const unsigned int sz = sizeof(u64) * RTL_NUM_STATS; - int i; - - estats.n_stats = RTL_NUM_STATS; - if (copy_to_user(useraddr, &estats, sizeof(estats))) - return -EFAULT; - - tmp_stats = kmalloc(sz, GFP_KERNEL); - if (!tmp_stats) - return -ENOMEM; - memset(tmp_stats, 0, sz); - - i = 0; - tmp_stats[i++] = np->xstats.early_rx; - tmp_stats[i++] = np->xstats.tx_buf_mapped; - tmp_stats[i++] = np->xstats.tx_timeouts; - tmp_stats[i++] = np->xstats.rx_lost_in_ring; - if (i != RTL_NUM_STATS) - BUG(); +static void rtl8139_get_regs(struct net_device *dev, struct ethtool_regs *regs, void *regbuf) +{ + struct rtl8139_private *np = dev->priv; - i = copy_to_user(useraddr + sizeof(estats), tmp_stats, sz); - kfree(tmp_stats); + regs->version = RTL_REGS_VER; - if (i) - return -EFAULT; - return 0; - } - default: - break; - } + spin_lock_irq(&np->lock); + memcpy_fromio(regbuf, np->mmio_addr, regs->len); + spin_unlock_irq(&np->lock); +} +#endif /* CONFIG_8139TOO_MMIO */ - return -EOPNOTSUPP; +static int rtl8139_get_stats_count(struct net_device *dev) +{ + return RTL_NUM_STATS; } +static void rtl8139_get_ethtool_stats(struct net_device *dev, struct ethtool_stats *stats, u64 *data) +{ + struct rtl8139_private *np = dev->priv; + + data[0] = np->xstats.early_rx; + data[1] = np->xstats.tx_buf_mapped; + data[2] = np->xstats.tx_timeouts; + data[3] = np->xstats.rx_lost_in_ring; +} + +static void rtl8139_get_strings(struct net_device *dev, u32 stringset, u8 *data) +{ + memcpy(data, ethtool_stats_keys, sizeof(ethtool_stats_keys)); +} + +static struct ethtool_ops rtl8139_ethtool_ops = { + .get_drvinfo = rtl8139_get_drvinfo, + .get_settings = rtl8139_get_settings, + .set_settings = rtl8139_set_settings, + .get_regs_len = rtl8139_get_regs_len, + .get_regs = rtl8139_get_regs, + .nway_reset = rtl8139_nway_reset, + .get_link = rtl8139_get_link, + .get_msglevel = rtl8139_get_msglevel, + .set_msglevel = rtl8139_set_msglevel, + .get_wol = rtl8139_get_wol, + .set_wol = rtl8139_set_wol, + .get_strings = rtl8139_get_strings, + .get_stats_count = rtl8139_get_stats_count, + .get_ethtool_stats = rtl8139_get_ethtool_stats, +}; static int netdev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) { @@ -2457,14 +2363,9 @@ if (!netif_running(dev)) return -EINVAL; - if (cmd == SIOCETHTOOL) - rc = netdev_ethtool_ioctl(dev, (void *) rq->ifr_data); - - else { - spin_lock_irq(&np->lock); - rc = generic_mii_ioctl(&np->mii, data, cmd, NULL); - spin_unlock_irq(&np->lock); - } + spin_lock_irq(&np->lock); + rc = generic_mii_ioctl(&np->mii, data, cmd, NULL); + spin_unlock_irq(&np->lock); return rc; } diff -Nru a/drivers/net/8390.c b/drivers/net/8390.c --- a/drivers/net/8390.c Tue Sep 2 19:58:13 2003 +++ b/drivers/net/8390.c Tue Sep 2 19:58:13 2003 @@ -997,6 +997,11 @@ spin_unlock_irqrestore(&ei_local->page_lock, flags); } +static inline void ei_device_init(struct ei_device *ei_local) +{ + spin_lock_init(&ei_local->page_lock); +} + /** * ethdev_init - init rest of 8390 device struct * @dev: network device structure to init @@ -1012,14 +1017,11 @@ if (dev->priv == NULL) { - struct ei_device *ei_local; - dev->priv = kmalloc(sizeof(struct ei_device), GFP_KERNEL); if (dev->priv == NULL) return -ENOMEM; memset(dev->priv, 0, sizeof(struct ei_device)); - ei_local = (struct ei_device *)dev->priv; - spin_lock_init(&ei_local->page_lock); + ei_device_init(dev->priv); } dev->hard_start_xmit = &ei_start_xmit; @@ -1030,6 +1032,29 @@ return 0; } + +/* wrapper to make alloc_netdev happy; probably should just cast... */ +static void __ethdev_init(struct net_device *dev) +{ + ethdev_init(dev); +} + +/** + * alloc_ei_netdev - alloc_etherdev counterpart for 8390 + * + * Allocate 8390-specific net_device. + */ +struct net_device *alloc_ei_netdev(void) +{ + struct net_device *dev; + + dev = alloc_netdev(sizeof(struct ei_device), "eth%d", __ethdev_init); + if (dev) + ei_device_init(dev->priv); + + return dev; +} + @@ -1133,6 +1158,7 @@ EXPORT_SYMBOL(ei_tx_timeout); EXPORT_SYMBOL(ethdev_init); EXPORT_SYMBOL(NS8390_init); +EXPORT_SYMBOL(alloc_ei_netdev); #if defined(MODULE) diff -Nru a/drivers/net/8390.h b/drivers/net/8390.h --- a/drivers/net/8390.h Tue Sep 2 19:58:17 2003 +++ b/drivers/net/8390.h Tue Sep 2 19:58:17 2003 @@ -44,6 +44,7 @@ extern int ei_open(struct net_device *dev); extern int ei_close(struct net_device *dev); extern irqreturn_t ei_interrupt(int irq, void *dev_id, struct pt_regs *regs); +extern struct net_device *alloc_ei_netdev(void); /* You have one of these per-board */ struct ei_device { diff -Nru a/drivers/net/Kconfig b/drivers/net/Kconfig --- a/drivers/net/Kconfig Tue Sep 2 19:58:18 2003 +++ b/drivers/net/Kconfig Tue Sep 2 19:58:18 2003 @@ -132,8 +132,8 @@ If you don't know what to use this for, you don't need it. config ETHERTAP - tristate "Ethertap network tap (OBSOLETE)" - depends on NETDEVICES && EXPERIMENTAL + tristate "Ethertap network tap" + depends on NETDEVICES && EXPERIMENTAL && NETLINK_DEV ---help--- If you say Y here (and have said Y to "Kernel/User network link driver", above) and create a character special file /dev/tap0 with @@ -502,7 +502,7 @@ config SGI_IOC3_ETH bool "SGI IOC3 Ethernet" - depends on NET_ETHERNET && (IA64_SGI_SN1 || SGI_IP27) + depends on NET_ETHERNET && SGI_IP27 help If you have a network (Ethernet) card of this type, say Y and read the Ethernet-HOWTO, available from @@ -704,7 +704,7 @@ config ELMC_II tristate "3c527 \"EtherLink/MC 32\" support (EXPERIMENTAL)" - depends on NET_VENDOR_3COM && MCA && EXPERIMENTAL + depends on NET_VENDOR_3COM && MCA && EXPERIMENTAL && BROKEN_ON_SMP help If you have a network (Ethernet) card of this type, say Y and read the Ethernet-HOWTO, available from @@ -882,7 +882,7 @@ config NI5010 tristate "NI5010 support (EXPERIMENTAL)" - depends on NET_VENDOR_RACAL && ISA && EXPERIMENTAL + depends on NET_VENDOR_RACAL && ISA && EXPERIMENTAL && BROKEN_ON_SMP ---help--- If you have a network (Ethernet) card of this type, say Y and read the Ethernet-HOWTO, available from @@ -1221,7 +1221,7 @@ config SKMC tristate "SKnet MCA support" - depends on NET_ETHERNET && MCA + depends on NET_ETHERNET && MCA && BROKEN ---help--- These are Micro Channel Ethernet adapters. You need to say Y to "MCA support" in order to use this driver. Supported cards are the SKnet @@ -2670,7 +2670,7 @@ config IPHASE5526 tristate "Interphase 5526 Tachyon chipset based adapter support" - depends on NET_FC && SCSI && PCI + depends on NET_FC && SCSI && PCI && BROKEN help Say Y here if you have a Fibre Channel adaptor of this kind. diff -Nru a/drivers/net/Space.c b/drivers/net/Space.c --- a/drivers/net/Space.c Tue Sep 2 19:58:13 2003 +++ b/drivers/net/Space.c Tue Sep 2 19:58:13 2003 @@ -89,7 +89,6 @@ extern int bionet_probe(struct net_device *); extern int pamsnet_probe(struct net_device *); extern int cs89x0_probe(struct net_device *dev); -extern int ethertap_probe(struct net_device *dev); extern int hplance_probe(struct net_device *dev); extern int bagetlance_probe(struct net_device *); extern int mvme147lance_probe(struct net_device *dev); @@ -386,17 +385,6 @@ return 0; return -ENODEV; } - -#ifdef CONFIG_ETHERTAP -static struct net_device tap0_dev = { - .name = "tap0", - .base_addr = NETLINK_TAPBASE, - .next = NEXT_DEV, - .init = ethertap_probe, -}; -#undef NEXT_DEV -#define NEXT_DEV (&tap0_dev) -#endif #ifdef CONFIG_SDLA extern int sdla_init(struct net_device *); diff -Nru a/drivers/net/arcnet/arcnet.c b/drivers/net/arcnet/arcnet.c --- a/drivers/net/arcnet/arcnet.c Tue Sep 2 19:58:17 2003 +++ b/drivers/net/arcnet/arcnet.c Tue Sep 2 19:58:17 2003 @@ -135,7 +135,7 @@ arc_proto_map[count] = arc_proto_default; BUGLVL(D_DURING) - printk("arcnet: struct sizes: %d %d %d %d %d\n", + printk("arcnet: struct sizes: %Zd %Zd %Zd %Zd %Zd\n", sizeof(struct arc_hardware), sizeof(struct arc_rfc1201), sizeof(struct arc_rfc1051), sizeof(struct arc_eth_encap), sizeof(struct archdr)); diff -Nru a/drivers/net/arm/ether00.c b/drivers/net/arm/ether00.c --- a/drivers/net/arm/ether00.c Tue Sep 2 19:58:20 2003 +++ b/drivers/net/arm/ether00.c Tue Sep 2 19:58:20 2003 @@ -991,9 +991,9 @@ } static struct pld_hotswap_ops ether00_pldhs_ops={ - name: ETHER00_NAME, - add_device: ether00_add_device, - remove_devices: ether00_remove_devices, + .name = ETHER00_NAME, + .add_device = ether00_add_device, + .remove_devices = ether00_remove_devices, }; diff -Nru a/drivers/net/dummy.c b/drivers/net/dummy.c --- a/drivers/net/dummy.c Tue Sep 2 19:58:15 2003 +++ b/drivers/net/dummy.c Tue Sep 2 19:58:15 2003 @@ -28,8 +28,6 @@ Alan Cox, 30th May 1994 */ -/* To have statistics (just packets sent) define this */ - #include #include #include diff -Nru a/drivers/net/epic100.c b/drivers/net/epic100.c --- a/drivers/net/epic100.c Tue Sep 2 19:58:15 2003 +++ b/drivers/net/epic100.c Tue Sep 2 19:58:15 2003 @@ -362,6 +362,7 @@ static int epic_rx(struct net_device *dev); static irqreturn_t epic_interrupt(int irq, void *dev_instance, struct pt_regs *regs); static int netdev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); +static struct ethtool_ops netdev_ethtool_ops; static int epic_close(struct net_device *dev); static struct net_device_stats *epic_get_stats(struct net_device *dev); static void set_rx_mode(struct net_device *dev); @@ -539,6 +540,7 @@ dev->get_stats = &epic_get_stats; dev->set_multicast_list = &set_rx_mode; dev->do_ioctl = &netdev_ioctl; + dev->ethtool_ops = &netdev_ethtool_ops; dev->watchdog_timeo = TX_TIMEOUT; dev->tx_timeout = &epic_tx_timeout; @@ -1361,82 +1363,73 @@ return; } -static int netdev_ethtool_ioctl (struct net_device *dev, void *useraddr) +static void netdev_get_drvinfo (struct net_device *dev, struct ethtool_drvinfo *info) { struct epic_private *np = dev->priv; - u32 ethcmd; - if (copy_from_user (ðcmd, useraddr, sizeof (ethcmd))) - return -EFAULT; + strcpy (info->driver, DRV_NAME); + strcpy (info->version, DRV_VERSION); + strcpy (info->bus_info, pci_name(np->pci_dev)); +} - switch (ethcmd) { - case ETHTOOL_GDRVINFO: { - struct ethtool_drvinfo info = { ETHTOOL_GDRVINFO }; - strcpy (info.driver, DRV_NAME); - strcpy (info.version, DRV_VERSION); - strcpy (info.bus_info, pci_name(np->pci_dev)); - if (copy_to_user (useraddr, &info, sizeof (info))) - return -EFAULT; - return 0; - } - - /* get settings */ - case ETHTOOL_GSET: { - struct ethtool_cmd ecmd = { ETHTOOL_GSET }; - spin_lock_irq(&np->lock); - mii_ethtool_gset(&np->mii, &ecmd); - spin_unlock_irq(&np->lock); - if (copy_to_user(useraddr, &ecmd, sizeof(ecmd))) - return -EFAULT; - return 0; - } - /* set settings */ - case ETHTOOL_SSET: { - int r; - struct ethtool_cmd ecmd; - if (copy_from_user(&ecmd, useraddr, sizeof(ecmd))) - return -EFAULT; - spin_lock_irq(&np->lock); - r = mii_ethtool_sset(&np->mii, &ecmd); - spin_unlock_irq(&np->lock); - return r; - } - /* restart autonegotiation */ - case ETHTOOL_NWAY_RST: { - return mii_nway_restart(&np->mii); - } - /* get link status */ - case ETHTOOL_GLINK: { - struct ethtool_value edata = {ETHTOOL_GLINK}; - edata.data = mii_link_ok(&np->mii); - if (copy_to_user(useraddr, &edata, sizeof(edata))) - return -EFAULT; - return 0; - } - - /* get message-level */ - case ETHTOOL_GMSGLVL: { - struct ethtool_value edata = {ETHTOOL_GMSGLVL}; - edata.data = debug; - if (copy_to_user(useraddr, &edata, sizeof(edata))) - return -EFAULT; - return 0; - } - /* set message-level */ - case ETHTOOL_SMSGLVL: { - struct ethtool_value edata; - if (copy_from_user(&edata, useraddr, sizeof(edata))) - return -EFAULT; - debug = edata.data; - return 0; - } - default: - break; - } +static int netdev_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) +{ + struct epic_private *np = dev->priv; + int rc; + + spin_lock_irq(&np->lock); + rc = mii_ethtool_gset(&np->mii, cmd); + spin_unlock_irq(&np->lock); + + return rc; +} + +static int netdev_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) +{ + struct epic_private *np = dev->priv; + int rc; + + spin_lock_irq(&np->lock); + rc = mii_ethtool_sset(&np->mii, cmd); + spin_unlock_irq(&np->lock); + + return rc; +} + +static int netdev_nway_reset(struct net_device *dev) +{ + struct epic_private *np = dev->priv; + return mii_nway_restart(&np->mii); +} - return -EOPNOTSUPP; +static u32 netdev_get_link(struct net_device *dev) +{ + struct epic_private *np = dev->priv; + return mii_link_ok(&np->mii); } +static u32 netdev_get_msglevel(struct net_device *dev) +{ + return debug; +} + +static void netdev_set_msglevel(struct net_device *dev, u32 value) +{ + debug = value; +} + +static struct ethtool_ops netdev_ethtool_ops = { + .get_drvinfo = netdev_get_drvinfo, + .get_settings = netdev_get_settings, + .set_settings = netdev_set_settings, + .nway_reset = netdev_nway_reset, + .get_link = netdev_get_link, + .get_msglevel = netdev_get_msglevel, + .set_msglevel = netdev_set_msglevel, + .get_sg = ethtool_op_get_sg, + .get_tx_csum = ethtool_op_get_tx_csum, +}; + static int netdev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) { struct epic_private *np = dev->priv; @@ -1450,16 +1443,10 @@ outl((inl(ioaddr + NVCTL) & ~0x003C) | 0x4800, ioaddr + NVCTL); } - /* ethtool commands */ - if (cmd == SIOCETHTOOL) - rc = netdev_ethtool_ioctl(dev, (void *) rq->ifr_data); - - /* all other ioctls (the SIOC[GS]MIIxxx ioctls) */ - else { - spin_lock_irq(&np->lock); - rc = generic_mii_ioctl(&np->mii, data, cmd, NULL); - spin_unlock_irq(&np->lock); - } + /* all non-ethtool ioctls (the SIOC[GS]MIIxxx ioctls) */ + spin_lock_irq(&np->lock); + rc = generic_mii_ioctl(&np->mii, data, cmd, NULL); + spin_unlock_irq(&np->lock); /* power-down, if interface is down */ if (! netif_running(dev)) { diff -Nru a/drivers/net/eth16i.c b/drivers/net/eth16i.c --- a/drivers/net/eth16i.c Tue Sep 2 19:58:18 2003 +++ b/drivers/net/eth16i.c Tue Sep 2 19:58:18 2003 @@ -1053,7 +1053,7 @@ int ioaddr = dev->base_addr; int status = 0; ushort length = skb->len; - unsigned char *buf = skb->data; + unsigned char *buf; unsigned long flags; if (length < ETH_ZLEN) { @@ -1062,6 +1062,7 @@ return 0; length = ETH_ZLEN; } + buf = skb->data; netif_stop_queue(dev); diff -Nru a/drivers/net/ethertap.c b/drivers/net/ethertap.c --- a/drivers/net/ethertap.c Tue Sep 2 19:58:14 2003 +++ b/drivers/net/ethertap.c Tue Sep 2 19:58:14 2003 @@ -33,7 +33,6 @@ * Index to functions. */ -int ethertap_probe(struct net_device *dev); static int ethertap_open(struct net_device *dev); static int ethertap_start_xmit(struct sk_buff *skb, struct net_device *dev); static int ethertap_close(struct net_device *dev); @@ -45,7 +44,11 @@ static int ethertap_debug; -static struct net_device *tap_map[32]; /* Returns the tap device for a given netlink */ +static int max_taps = 1; +MODULE_PARM(max_taps, "i"); +MODULE_PARM_DESC(max_taps,"Max number of ethernet tap devices"); + +static struct net_device **tap_map; /* Returns the tap device for a given netlink */ /* * Board-specific info in dev->priv. @@ -64,25 +67,29 @@ * To call this a probe is a bit misleading, however for real * hardware it would have to check what was present. */ - -int __init ethertap_probe(struct net_device *dev) +static int __init ethertap_probe(int unit) { + struct net_device *dev; + int err = -ENOMEM; + + dev = alloc_netdev(sizeof(struct net_local), "tap%d", + ether_setup); + + if (!dev) + goto out; + SET_MODULE_OWNER(dev); + sprintf(dev->name, "tap%d", unit); + dev->base_addr = unit + NETLINK_TAPBASE; + + netdev_boot_setup_check(dev); + memcpy(dev->dev_addr, "\xFE\xFD\x00\x00\x00\x00", 6); if (dev->mem_start & 0xf) ethertap_debug = dev->mem_start & 0x7; /* - * Initialize the device structure. - */ - - dev->priv = kmalloc(sizeof(struct net_local), GFP_KERNEL); - if (dev->priv == NULL) - return -ENOMEM; - memset(dev->priv, 0, sizeof(struct net_local)); - - /* * The tap specific entries in the device structure. */ @@ -94,17 +101,19 @@ dev->set_multicast_list = set_multicast_list; #endif - /* - * Setup the generic properties - */ - - ether_setup(dev); - dev->tx_queue_len = 0; dev->flags|=IFF_NOARP; - tap_map[dev->base_addr]=dev; + err = register_netdev(dev); + if (err) + goto out_free; + + tap_map[unit]=dev; return 0; +out_free: + free_netdev(dev); +out: + return err; } /* @@ -116,11 +125,12 @@ struct net_local *lp = (struct net_local*)dev->priv; if (ethertap_debug > 2) - printk("%s: Doing ethertap_open()...", dev->name); + printk(KERN_DEBUG "%s: Doing ethertap_open()...", dev->name); lp->nl = netlink_kernel_create(dev->base_addr, ethertap_rx); if (lp->nl == NULL) return -ENOBUFS; + netif_start_queue(dev); return 0; } @@ -302,7 +312,7 @@ } if (ethertap_debug > 3) - printk("%s: ethertap_rx()\n", dev->name); + printk(KERN_DEBUG "%s: ethertap_rx()\n", dev->name); while ((skb = skb_dequeue(&sk->sk_receive_queue)) != NULL) ethertap_rx_skb(skb, dev); @@ -314,7 +324,7 @@ struct sock *sk = lp->nl; if (ethertap_debug > 2) - printk("%s: Shutting down.\n", dev->name); + printk(KERN_DEBUG "%s: Shutting down.\n", dev->name); netif_stop_queue(dev); @@ -332,45 +342,49 @@ return &lp->stats; } -#ifdef MODULE - -static int unit; -MODULE_PARM(unit,"i"); -MODULE_PARM_DESC(unit,"Ethertap device number"); -static struct net_device dev_ethertap = +int __init ethertap_init(void) { - .name = " ", - .init = ethertap_probe -}; + int i, err = 0; -int init_module(void) -{ - dev_ethertap.base_addr=unit+NETLINK_TAPBASE; - sprintf(dev_ethertap.name,"tap%d",unit); - if (dev_get(dev_ethertap.name)) - { - printk(KERN_INFO "%s already loaded.\n", dev_ethertap.name); - return -EBUSY; - } - if (register_netdev(&dev_ethertap) != 0) - return -EIO; - return 0; -} - -void cleanup_module(void) -{ - tap_map[dev_ethertap.base_addr]=NULL; - unregister_netdev(&dev_ethertap); + /* netlink can only hande 16 entries unless modified */ + if (max_taps > MAX_LINKS - NETLINK_TAPBASE) + return -E2BIG; - /* - * Free up the private structure. - */ + tap_map = kmalloc(sizeof(struct net_device *)*max_taps, GFP_KERNEL); + if (!tap_map) + return -ENOMEM; - kfree(dev_ethertap.priv); - dev_ethertap.priv = NULL; /* gets re-allocated by ethertap_probe */ + for (i = 0; i < max_taps; i++) { + err = ethertap_probe(i); + if (err) { + while (--i > 0) { + unregister_netdev(tap_map[i]); + free_netdev(tap_map[i]); + } + break; + } + } + if (err) + kfree(tap_map); + return err; +} +module_init(ethertap_init); + +void __exit ethertap_cleanup(void) +{ + int i; + + for (i = 0; i < max_taps; i++) { + struct net_device *dev = tap_map[i]; + if (dev) { + tap_map[i] = NULL; + unregister_netdev(dev); + free_netdev(dev); + } + } + kfree(tap_map); } +module_exit(ethertap_cleanup); -#endif /* MODULE */ MODULE_LICENSE("GPL"); - diff -Nru a/drivers/net/fealnx.c b/drivers/net/fealnx.c --- a/drivers/net/fealnx.c Tue Sep 2 19:58:17 2003 +++ b/drivers/net/fealnx.c Tue Sep 2 19:58:17 2003 @@ -443,6 +443,7 @@ 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 struct ethtool_ops netdev_ethtool_ops; static int netdev_close(struct net_device *dev); static void reset_rx_descriptors(struct net_device *dev); @@ -667,6 +668,7 @@ dev->get_stats = &get_stats; dev->set_multicast_list = &set_rx_mode; dev->do_ioctl = &mii_ioctl; + dev->ethtool_ops = &netdev_ethtool_ops; dev->tx_timeout = tx_timeout; dev->watchdog_timeo = TX_TIMEOUT; @@ -938,7 +940,7 @@ // 89/9/1 modify, // np->bcrvalue=0x38; np->bcrvalue = 0x10; - np->cralue = 0xe00; /* rx 128 burst length */ + np->crvalue = 0xe00; /* rx 128 burst length */ #warning Processor architecture undefined! #endif // 89/12/29 add, @@ -1760,82 +1762,72 @@ writel(np->crvalue, ioaddr + TCRRCR); } -static int netdev_ethtool_ioctl (struct net_device *dev, void *useraddr) +static void netdev_get_drvinfo (struct net_device *dev, struct ethtool_drvinfo *info) { struct netdev_private *np = dev->priv; - u32 ethcmd; - if (copy_from_user (ðcmd, useraddr, sizeof (ethcmd))) - return -EFAULT; + strcpy (info->driver, DRV_NAME); + strcpy (info->version, DRV_VERSION); + strcpy (info->bus_info, pci_name(np->pci_dev)); +} - switch (ethcmd) { - case ETHTOOL_GDRVINFO: { - struct ethtool_drvinfo info = { ETHTOOL_GDRVINFO }; - strcpy (info.driver, DRV_NAME); - strcpy (info.version, DRV_VERSION); - strcpy (info.bus_info, pci_name(np->pci_dev)); - if (copy_to_user (useraddr, &info, sizeof (info))) - return -EFAULT; - return 0; - } - - /* get settings */ - case ETHTOOL_GSET: { - struct ethtool_cmd ecmd = { ETHTOOL_GSET }; - spin_lock_irq(&np->lock); - mii_ethtool_gset(&np->mii, &ecmd); - spin_unlock_irq(&np->lock); - if (copy_to_user(useraddr, &ecmd, sizeof(ecmd))) - return -EFAULT; - return 0; - } - /* set settings */ - case ETHTOOL_SSET: { - int r; - struct ethtool_cmd ecmd; - if (copy_from_user(&ecmd, useraddr, sizeof(ecmd))) - return -EFAULT; - spin_lock_irq(&np->lock); - r = mii_ethtool_sset(&np->mii, &ecmd); - spin_unlock_irq(&np->lock); - return r; - } - /* restart autonegotiation */ - case ETHTOOL_NWAY_RST: { - return mii_nway_restart(&np->mii); - } - /* get link status */ - case ETHTOOL_GLINK: { - struct ethtool_value edata = {ETHTOOL_GLINK}; - edata.data = mii_link_ok(&np->mii); - if (copy_to_user(useraddr, &edata, sizeof(edata))) - return -EFAULT; - return 0; - } - - /* get message-level */ - case ETHTOOL_GMSGLVL: { - struct ethtool_value edata = {ETHTOOL_GMSGLVL}; - edata.data = debug; - if (copy_to_user(useraddr, &edata, sizeof(edata))) - return -EFAULT; - return 0; - } - /* set message-level */ - case ETHTOOL_SMSGLVL: { - struct ethtool_value edata; - if (copy_from_user(&edata, useraddr, sizeof(edata))) - return -EFAULT; - debug = edata.data; - return 0; - } - default: - break; - } +static int netdev_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) +{ + struct netdev_private *np = dev->priv; + int rc; + + spin_lock_irq(&np->lock); + rc = mii_ethtool_gset(&np->mii, cmd); + spin_unlock_irq(&np->lock); + + return rc; +} + +static int netdev_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) +{ + struct netdev_private *np = dev->priv; + int rc; + + spin_lock_irq(&np->lock); + rc = mii_ethtool_sset(&np->mii, cmd); + spin_unlock_irq(&np->lock); + + return rc; +} + +static int netdev_nway_reset(struct net_device *dev) +{ + struct netdev_private *np = dev->priv; + return mii_nway_restart(&np->mii); +} + +static u32 netdev_get_link(struct net_device *dev) +{ + struct netdev_private *np = dev->priv; + return mii_link_ok(&np->mii); +} + +static u32 netdev_get_msglevel(struct net_device *dev) +{ + return debug; +} - return -EOPNOTSUPP; +static void netdev_set_msglevel(struct net_device *dev, u32 value) +{ + debug = value; } +static struct ethtool_ops netdev_ethtool_ops = { + .get_drvinfo = netdev_get_drvinfo, + .get_settings = netdev_get_settings, + .set_settings = netdev_set_settings, + .nway_reset = netdev_nway_reset, + .get_link = netdev_get_link, + .get_msglevel = netdev_get_msglevel, + .set_msglevel = netdev_set_msglevel, + .get_sg = ethtool_op_get_sg, + .get_tx_csum = ethtool_op_get_tx_csum, +}; static int mii_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) { @@ -1846,14 +1838,9 @@ if (!netif_running(dev)) return -EINVAL; - if (cmd == SIOCETHTOOL) - rc = netdev_ethtool_ioctl(dev, (void *) rq->ifr_data); - - else { - spin_lock_irq(&np->lock); - rc = generic_mii_ioctl(&np->mii, data, cmd, NULL); - spin_unlock_irq(&np->lock); - } + spin_lock_irq(&np->lock); + rc = generic_mii_ioctl(&np->mii, data, cmd, NULL); + spin_unlock_irq(&np->lock); return rc; } diff -Nru a/drivers/net/fmv18x.c b/drivers/net/fmv18x.c --- a/drivers/net/fmv18x.c Tue Sep 2 19:58:13 2003 +++ b/drivers/net/fmv18x.c Tue Sep 2 19:58:13 2003 @@ -367,7 +367,7 @@ struct net_local *lp = dev->priv; int ioaddr = dev->base_addr; short length = skb->len; - unsigned char *buf = skb->data; + unsigned char *buf; unsigned long flags; /* Block a transmit from overlapping. */ @@ -385,6 +385,7 @@ return 0; length = ETH_ZLEN; } + buf = skb->data; if (net_debug > 4) printk("%s: Transmitting a packet of length %lu.\n", dev->name, diff -Nru a/drivers/net/hamradio/Kconfig b/drivers/net/hamradio/Kconfig --- a/drivers/net/hamradio/Kconfig Tue Sep 2 19:58:13 2003 +++ b/drivers/net/hamradio/Kconfig Tue Sep 2 19:58:13 2003 @@ -1,6 +1,6 @@ config MKISS tristate "Serial port KISS driver" - depends on AX25 + depends on AX25 && BROKEN_ON_SMP ---help--- KISS is a protocol used for the exchange of data between a computer and a Terminal Node Controller (a small embedded system commonly @@ -19,7 +19,7 @@ config 6PACK tristate "Serial port 6PACK driver" - depends on AX25 + depends on AX25 && BROKEN_ON_SMP ---help--- 6pack is a transmission protocol for the data exchange between your PC and your TNC (the Terminal Node Controller acts as a kind of @@ -49,7 +49,7 @@ config DMASCC tristate "High-speed (DMA) SCC driver for AX.25" - depends on ISA && AX25 + depends on ISA && AX25 && BROKEN_ON_SMP ---help--- This is a driver for high-speed SCC boards, i.e. those supporting DMA on one port. You usually use those boards to connect your diff -Nru a/drivers/net/hamradio/bpqether.c b/drivers/net/hamradio/bpqether.c --- a/drivers/net/hamradio/bpqether.c Tue Sep 2 19:58:15 2003 +++ b/drivers/net/hamradio/bpqether.c Tue Sep 2 19:58:15 2003 @@ -605,6 +605,7 @@ printk(banner); +#ifdef CONFIG_PROC_FS if (!proc_net_fops_create("bpqether", S_IRUGO, &bpq_info_fops)) { printk(KERN_ERR "bpq: cannot create /proc/net/bpqether entry.\n"); @@ -612,6 +613,7 @@ dev_remove_pack(&bpq_packet_type); return -ENOENT; } +#endif /* CONFIG_PROC_FS */ rtnl_lock(); for (dev = dev_base; dev != NULL; dev = dev->next) { diff -Nru a/drivers/net/hamradio/yam.c b/drivers/net/hamradio/yam.c --- a/drivers/net/hamradio/yam.c Tue Sep 2 19:58:17 2003 +++ b/drivers/net/hamradio/yam.c Tue Sep 2 19:58:17 2003 @@ -807,7 +807,7 @@ seq_printf(seq, " RxInt %u\n", yp->nb_rxint); seq_printf(seq, " RxOver %lu\n", yp->stats.rx_fifo_errors); seq_printf(seq, "\n"); - + return 0; } static struct seq_operations yam_seqops = { diff -Nru a/drivers/net/irda/Kconfig b/drivers/net/irda/Kconfig --- a/drivers/net/irda/Kconfig Tue Sep 2 19:58:17 2003 +++ b/drivers/net/irda/Kconfig Tue Sep 2 19:58:17 2003 @@ -256,7 +256,7 @@ config TOSHIBA_OLD tristate "Toshiba Type-O IR Port (old driver)" - depends on IRDA + depends on IRDA && BROKEN_ON_SMP help Say Y here if you want to build support for the Toshiba Type-O IR chipset. This chipset is used by the Toshiba Libretto 100CT, and @@ -319,7 +319,7 @@ config VLSI_FIR tristate "VLSI 82C147 SIR/MIR/FIR (EXPERIMENTAL)" - depends on EXPERIMENTAL && IRDA + depends on EXPERIMENTAL && IRDA && PCI help Say Y here if you want to build support for the VLSI 82C147 PCI-IrDA Controller. This controller is used by the HP OmniBook 800 diff -Nru a/drivers/net/irda/via-ircc.c b/drivers/net/irda/via-ircc.c --- a/drivers/net/irda/via-ircc.c Tue Sep 2 19:58:12 2003 +++ b/drivers/net/irda/via-ircc.c Tue Sep 2 19:58:12 2003 @@ -134,10 +134,10 @@ static struct pci_driver via_driver = { - name: VIA_MODULE_NAME, - id_table: via_pci_tbl, - probe: via_init_one, - remove: via_remove_one, + .name = VIA_MODULE_NAME, + .id_table = via_pci_tbl, + .probe = via_init_one, + .remove = via_remove_one, }; diff -Nru a/drivers/net/irda/vlsi_ir.c b/drivers/net/irda/vlsi_ir.c --- a/drivers/net/irda/vlsi_ir.c Tue Sep 2 19:58:12 2003 +++ b/drivers/net/irda/vlsi_ir.c Tue Sep 2 19:58:12 2003 @@ -21,18 +21,20 @@ * ********************************************************************/ +#include #include -MODULE_DESCRIPTION("IrDA SIR/MIR/FIR driver for VLSI 82C147"); -MODULE_AUTHOR("Martin Diehl "); -MODULE_LICENSE("GPL"); +#define DRIVER_NAME "vlsi_ir" +#define DRIVER_VERSION "v0.5" +#define DRIVER_DESCRIPTION "IrDA SIR/MIR/FIR driver for VLSI 82C147" +#define DRIVER_AUTHOR "Martin Diehl " -#define DRIVER_NAME "vlsi_ir" -#define DRIVER_VERSION "v0.4a" +MODULE_DESCRIPTION(DRIVER_DESCRIPTION); +MODULE_AUTHOR(DRIVER_AUTHOR); +MODULE_LICENSE("GPL"); /********************************************************/ -#include #include #include #include @@ -44,10 +46,12 @@ #include #include #include +#include #include #include #include +#include #include @@ -55,14 +59,16 @@ static /* const */ char drivername[] = DRIVER_NAME; -#define PCI_CLASS_WIRELESS_IRDA 0x0d00 - -static struct pci_device_id vlsi_irda_table [] = { { - - .class = PCI_CLASS_WIRELESS_IRDA << 8, - .vendor = PCI_VENDOR_ID_VLSI, - .device = PCI_DEVICE_ID_VLSI_82C147, - }, { /* all zeroes */ } +static struct pci_device_id vlsi_irda_table [] = { + { + .class = PCI_CLASS_WIRELESS_IRDA << 8, + .class_mask = PCI_CLASS_SUBCLASS_MASK << 8, + .vendor = PCI_VENDOR_ID_VLSI, + .device = PCI_DEVICE_ID_VLSI_82C147, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, + }, + { /* all zeroes */ } }; MODULE_DEVICE_TABLE(pci, vlsi_irda_table); @@ -114,7 +120,7 @@ MODULE_PARM(qos_mtt_bits, "i"); MODULE_PARM_DESC(qos_mtt_bits, "IrLAP bitfield representing min-turn-time"); -static int qos_mtt_bits = 0x04; /* default is 1 ms */ +static int qos_mtt_bits = 0x07; /* default is 1 ms or more */ /********************************************************/ @@ -164,7 +170,7 @@ return 0; out += sprintf(out, "\n%s (vid/did: %04x/%04x)\n", - pci_name(pdev), (int)pdev->vendor, (int)pdev->device); + PCIDEV_NAME(pdev), (int)pdev->vendor, (int)pdev->device); out += sprintf(out, "pci-power-state: %u\n", (unsigned) pdev->current_state); out += sprintf(out, "resources: irq=%u / io=0x%04x / dma_mask=0x%016Lx\n", pdev->irq, (unsigned)pci_resource_start(pdev, 0), (u64)pdev->dma_mask); @@ -198,13 +204,13 @@ out += sprintf(out, "\nhw-state:\n"); pci_read_config_byte(idev->pdev, VLSI_PCI_IRMISC, &byte); - out += sprintf(out, "IRMISC:%s%s%s UART%s", + out += sprintf(out, "IRMISC:%s%s%s uart%s", (byte&IRMISC_IRRAIL) ? " irrail" : "", (byte&IRMISC_IRPD) ? " irpd" : "", (byte&IRMISC_UARTTST) ? " uarttest" : "", - (byte&IRMISC_UARTEN) ? "" : " disabled\n"); + (byte&IRMISC_UARTEN) ? "@" : " disabled\n"); if (byte&IRMISC_UARTEN) { - out += sprintf(out, "@0x%s\n", + out += sprintf(out, "0x%s\n", (byte&2) ? ((byte&1) ? "3e8" : "2e8") : ((byte&1) ? "3f8" : "2f8")); } @@ -254,7 +260,7 @@ (word&IRCFG_RXPOL) ? " RXPOL" : ""); word = inw(iobase+VLSI_PIO_IRENABLE); out += sprintf(out, "IRENABLE:%s%s%s%s%s%s%s%s\n", - (word&IRENABLE_IREN) ? " IRENABLE" : "", + (word&IRENABLE_PHYANDCLOCK) ? " PHYANDCLOCK" : "", (word&IRENABLE_CFGER) ? " CFGERR" : "", (word&IRENABLE_FIR_ON) ? " FIR_ON" : "", (word&IRENABLE_MIR_ON) ? " MIR_ON" : "", @@ -358,7 +364,7 @@ char *out = buf; if (!ndev || !ndev->priv) { - printk(KERN_ERR "%s: invalid ptr!\n", __FUNCTION__); + ERROR("%s: invalid ptr!\n", __FUNCTION__); return 0; } @@ -539,7 +545,14 @@ memset(rd, 0, sizeof(*rd)); rd->hw = hwmap + i; rd->buf = kmalloc(len, GFP_KERNEL|GFP_DMA); - if (rd->buf == NULL) { + if (rd->buf == NULL + || !(busaddr = pci_map_single(pdev, rd->buf, len, dir))) { + if (rd->buf) { + ERROR("%s: failed to create PCI-MAP for %p", + __FUNCTION__, rd->buf); + kfree(rd->buf); + rd->buf = NULL; + } for (j = 0; j < i; j++) { rd = r->rd + j; busaddr = rd_get_addr(rd); @@ -552,12 +565,6 @@ kfree(r); return NULL; } - busaddr = pci_map_single(pdev, rd->buf, len, dir); - if (!busaddr) { - printk(KERN_ERR "%s: failed to create PCI-MAP for %p", - __FUNCTION__, rd->buf); - BUG(); - } rd_set_addr_status(rd, busaddr, 0); pci_dma_sync_single(pdev, busaddr, len, dir); /* initially, the dma buffer is owned by the CPU */ @@ -597,8 +604,7 @@ ringarea = pci_alloc_consistent(idev->pdev, HW_RING_AREA_SIZE, &idev->busaddr); if (!ringarea) { - printk(KERN_ERR "%s: insufficient memory for descriptor rings\n", - __FUNCTION__); + ERROR("%s: insufficient memory for descriptor rings\n", __FUNCTION__); goto out; } memset(ringarea, 0, HW_RING_AREA_SIZE); @@ -666,33 +672,52 @@ ret |= VLSI_RX_FRAME; if (status & RD_RX_CRCERR) ret |= VLSI_RX_CRC; + goto done; } - else { - len = rd_get_count(rd); - crclen = (idev->mode==IFF_FIR) ? sizeof(u32) : sizeof(u16); - len -= crclen; /* remove trailing CRC */ - if (len <= 0) { - printk(KERN_ERR "%s: strange frame (len=%d)\n", - __FUNCTION__, len); - ret |= VLSI_RX_DROP; - } - else if (!rd->skb) { - printk(KERN_ERR "%s: rx packet dropped\n", __FUNCTION__); - ret |= VLSI_RX_DROP; - } - else { - skb = rd->skb; - rd->skb = NULL; - skb->dev = ndev; - memcpy(skb_put(skb,len), rd->buf, len); - skb->mac.raw = skb->data; - if (in_interrupt()) - netif_rx(skb); - else - netif_rx_ni(skb); - ndev->last_rx = jiffies; + + len = rd_get_count(rd); + crclen = (idev->mode==IFF_FIR) ? sizeof(u32) : sizeof(u16); + len -= crclen; /* remove trailing CRC */ + if (len <= 0) { + IRDA_DEBUG(0, "%s: strange frame (len=%d)\n", __FUNCTION__, len); + ret |= VLSI_RX_DROP; + goto done; + } + + if (idev->mode == IFF_SIR) { /* hw checks CRC in MIR, FIR mode */ + + /* rd->buf is a streaming PCI_DMA_FROMDEVICE map. Doing the + * endian-adjustment there just in place will dirty a cache line + * which belongs to the map and thus we must be sure it will + * get flushed before giving the buffer back to hardware. + * vlsi_fill_rx() will do this anyway - but here we rely on. + */ + le16_to_cpus(rd->buf+len); + if (irda_calc_crc16(INIT_FCS,rd->buf,len+crclen) != GOOD_FCS) { + IRDA_DEBUG(0, "%s: crc error\n", __FUNCTION__); + ret |= VLSI_RX_CRC; + goto done; } } + + if (!rd->skb) { + WARNING("%s: rx packet lost\n", __FUNCTION__); + ret |= VLSI_RX_DROP; + goto done; + } + + skb = rd->skb; + rd->skb = NULL; + skb->dev = ndev; + memcpy(skb_put(skb,len), rd->buf, len); + skb->mac.raw = skb->data; + if (in_interrupt()) + netif_rx(skb); + else + netif_rx_ni(skb); + ndev->last_rx = jiffies; + +done: rd_set_status(rd, 0); rd_set_count(rd, 0); /* buffer still owned by CPU */ @@ -706,7 +731,9 @@ for (rd = ring_last(r); rd != NULL; rd = ring_put(r)) { if (rd_is_active(rd)) { - BUG(); + WARNING("%s: driver bug: rx descr race with hw\n", + __FUNCTION__); + vlsi_ring_debug(r); break; } if (!rd->skb) { @@ -764,7 +791,7 @@ if (ring_first(r) == NULL) { /* we are in big trouble, if this should ever happen */ - printk(KERN_ERR "%s: rx ring exhausted!\n", __FUNCTION__); + ERROR("%s: rx ring exhausted!\n", __FUNCTION__); vlsi_ring_debug(r); } else @@ -785,7 +812,7 @@ if (rd_is_active(rd)) { rd_set_status(rd, 0); if (rd_get_count(rd)) { - printk(KERN_INFO "%s - dropping rx packet\n", __FUNCTION__); + IRDA_DEBUG(0, "%s - dropping rx packet\n", __FUNCTION__); ret = -VLSI_RX_DROP; } rd_set_count(rd, 0); @@ -850,24 +877,17 @@ return (ret) ? -ret : len; } -static int vlsi_set_baud(struct net_device *ndev, int dolock) +static int vlsi_set_baud(vlsi_irda_dev_t *idev, unsigned iobase) { - vlsi_irda_dev_t *idev = ndev->priv; - unsigned long flags; u16 nphyctl; - unsigned iobase; u16 config; unsigned mode; - unsigned idle_retry; int ret; int baudrate; - int fifocnt = 0; /* Keep compiler happy */ + int fifocnt; baudrate = idev->new_baud; - iobase = ndev->base_addr; -#if 0 - printk(KERN_DEBUG "%s: %d -> %d\n", __FUNCTION__, idev->baud, idev->new_baud); -#endif + IRDA_DEBUG(2, "%s: %d -> %d\n", __FUNCTION__, idev->baud, idev->new_baud); if (baudrate == 4000000) { mode = IFF_FIR; config = IRCFG_FIR; @@ -883,7 +903,7 @@ config = IRCFG_SIR | IRCFG_SIRFILT | IRCFG_RXANY; switch(baudrate) { default: - printk(KERN_ERR "%s: undefined baudrate %d - fallback to 9600!\n", + WARNING("%s: undefined baudrate %d - fallback to 9600!\n", __FUNCTION__, baudrate); baudrate = 9600; /* fallthru */ @@ -897,40 +917,18 @@ break; } } + config |= IRCFG_MSTR | IRCFG_ENRX; - if (dolock) - spin_lock_irqsave(&idev->lock, flags); - else - flags = 0xdead; /* prevent bogus warning about possible uninitialized use */ - - for (idle_retry=0; idle_retry < 100; idle_retry++) { - fifocnt = inw(ndev->base_addr+VLSI_PIO_RCVBCNT) & RCVBCNT_MASK; - if (fifocnt == 0) - break; - if (!idle_retry) - printk(KERN_WARNING "%s: waiting for rx fifo to become empty(%d)\n", - __FUNCTION__, fifocnt); - if (dolock) { - spin_unlock_irqrestore(&idev->lock, flags); - udelay(100); - spin_lock_irqsave(&idev->lock, flags); - } - else - udelay(100); + fifocnt = inw(iobase+VLSI_PIO_RCVBCNT) & RCVBCNT_MASK; + if (fifocnt != 0) { + IRDA_DEBUG(0, "%s: rx fifo not empty(%d)\n", __FUNCTION__, fifocnt); } - if (fifocnt != 0) - printk(KERN_ERR "%s: rx fifo not empty(%d)\n", __FUNCTION__, fifocnt); outw(0, iobase+VLSI_PIO_IRENABLE); - wmb(); - - config |= IRCFG_MSTR | IRCFG_ENRX; - outw(config, iobase+VLSI_PIO_IRCFG); - outw(nphyctl, iobase+VLSI_PIO_NPHYCTL); wmb(); - outw(IRENABLE_IREN, iobase+VLSI_PIO_IRENABLE); + outw(IRENABLE_PHYANDCLOCK, iobase+VLSI_PIO_IRENABLE); mb(); udelay(1); /* chip applies IRCFG on next rising edge of its 8MHz clock */ @@ -946,14 +944,14 @@ else config ^= IRENABLE_SIR_ON; - if (config != (IRENABLE_IREN|IRENABLE_ENRXST)) { - printk(KERN_ERR "%s: failed to set %s mode!\n", __FUNCTION__, + if (config != (IRENABLE_PHYANDCLOCK|IRENABLE_ENRXST)) { + WARNING("%s: failed to set %s mode!\n", __FUNCTION__, (mode==IFF_SIR)?"SIR":((mode==IFF_MIR)?"MIR":"FIR")); ret = -1; } else { if (inw(iobase+VLSI_PIO_PHYCTL) != nphyctl) { - printk(KERN_ERR "%s: failed to apply baudrate %d\n", + WARNING("%s: failed to apply baudrate %d\n", __FUNCTION__, baudrate); ret = -1; } @@ -964,8 +962,6 @@ ret = 0; } } - if (dolock) - spin_unlock_irqrestore(&idev->lock, flags); if (ret) vlsi_reg_debug(iobase,__FUNCTION__); @@ -973,16 +969,6 @@ return ret; } -static inline int vlsi_set_baud_lock(struct net_device *ndev) -{ - return vlsi_set_baud(ndev, 1); -} - -static inline int vlsi_set_baud_nolock(struct net_device *ndev) -{ - return vlsi_set_baud(ndev, 0); -} - static int vlsi_hard_start_xmit(struct sk_buff *skb, struct net_device *ndev) { vlsi_irda_dev_t *idev = ndev->priv; @@ -995,79 +981,100 @@ int mtt; int len, speed; struct timeval now, ready; + char *msg = NULL; speed = irda_get_next_speed(skb); + spin_lock_irqsave(&idev->lock, flags); if (speed != -1 && speed != idev->baud) { netif_stop_queue(ndev); idev->new_baud = speed; - if (!skb->len) { - dev_kfree_skb_any(skb); - - /* due to the completely asynch tx operation we might have - * IrLAP racing with the hardware here, f.e. if the controller - * is just sending the last packet with current speed while - * the LAP is already switching the speed using synchronous - * len=0 packet. Immediate execution would lead to hw lockup - * requiring a powercycle to reset. Good candidate to trigger - * this is the final UA:RSP packet after receiving a DISC:CMD - * when getting the LAP down. - * Note that we are not protected by the queue_stop approach - * because the final UA:RSP arrives _without_ request to apply - * new-speed-after-this-packet - hence the driver doesn't know - * this was the last packet and doesn't stop the queue. So the - * forced switch to default speed from LAP gets through as fast - * as only some 10 usec later while the UA:RSP is still processed - * by the hardware and we would get screwed. - * Note: no locking required since we (netdev->xmit) are the only - * supplier for tx and the network layer provides serialization - */ - spin_lock_irqsave(&idev->lock, flags); - if (ring_first(idev->tx_ring) == NULL) { - /* no race - tx-ring already empty */ - vlsi_set_baud_nolock(ndev); - netif_wake_queue(ndev); - } - else - ; /* keep the speed change pending like it would - * for any len>0 packet. tx completion interrupt - * will apply it when the tx ring becomes empty. - */ - spin_unlock_irqrestore(&idev->lock, flags); - return 0; - } status = RD_TX_CLRENTX; /* stop tx-ring after this frame */ } else status = 0; if (skb->len == 0) { - printk(KERN_ERR "%s: dropping len=0 packet\n", __FUNCTION__); - goto drop; + /* handle zero packets - should be speed change */ + if (status == 0) { + msg = "bogus zero-length packet"; + goto drop_unlock; + } + + /* due to the completely asynch tx operation we might have + * IrLAP racing with the hardware here, f.e. if the controller + * is just sending the last packet with current speed while + * the LAP is already switching the speed using synchronous + * len=0 packet. Immediate execution would lead to hw lockup + * requiring a powercycle to reset. Good candidate to trigger + * this is the final UA:RSP packet after receiving a DISC:CMD + * when getting the LAP down. + * Note that we are not protected by the queue_stop approach + * because the final UA:RSP arrives _without_ request to apply + * new-speed-after-this-packet - hence the driver doesn't know + * this was the last packet and doesn't stop the queue. So the + * forced switch to default speed from LAP gets through as fast + * as only some 10 usec later while the UA:RSP is still processed + * by the hardware and we would get screwed. + */ + + if (ring_first(idev->tx_ring) == NULL) { + /* no race - tx-ring already empty */ + vlsi_set_baud(idev, iobase); + netif_wake_queue(ndev); + } + else + ; + /* keep the speed change pending like it would + * for any len>0 packet. tx completion interrupt + * will apply it when the tx ring becomes empty. + */ + spin_unlock_irqrestore(&idev->lock, flags); + dev_kfree_skb_any(skb); + return 0; } - /* sanity checks - should never happen! - * simply BUGging the violation and dropping the packet - */ + /* sanity checks - simply drop the packet */ rd = ring_last(r); - if (!rd) { /* ring full - queue should have been stopped! */ - BUG(); - goto drop; + if (!rd) { + msg = "ring full, but queue wasn't stopped"; + goto drop_unlock; } - if (rd_is_active(rd)) { /* entry still owned by hw! */ - BUG(); - goto drop; + if (rd_is_active(rd)) { + msg = "entry still owned by hw"; + goto drop_unlock; } - if (!rd->buf) { /* no memory for this tx entry - weird! */ - BUG(); - goto drop; + if (!rd->buf) { + msg = "tx ring entry without pci buffer"; + goto drop_unlock; } - if (rd->skb) { /* hm, associated old skb still there */ - BUG(); - goto drop; + if (rd->skb) { + msg = "ring entry with old skb still attached"; + goto drop_unlock; + } + + /* no need for serialization or interrupt disable during mtt */ + spin_unlock_irqrestore(&idev->lock, flags); + + if ((mtt = irda_get_mtt(skb)) > 0) { + + ready.tv_usec = idev->last_rx.tv_usec + mtt; + ready.tv_sec = idev->last_rx.tv_sec; + if (ready.tv_usec >= 1000000) { + ready.tv_usec -= 1000000; + ready.tv_sec++; /* IrLAP 1.1: mtt always < 1 sec */ + } + for(;;) { + do_gettimeofday(&now); + if (now.tv_sec > ready.tv_sec + || (now.tv_sec==ready.tv_sec && now.tv_usec>=ready.tv_usec)) + break; + udelay(100); + /* must not sleep here - we are called under xmit_lock! */ + } } /* tx buffer already owned by CPU due to pci_dma_sync_single() either @@ -1089,7 +1096,7 @@ */ if (len >= r->len-5) - printk(KERN_WARNING "%s: possible buffer overflow with SIR wrapping!\n", + WARNING("%s: possible buffer overflow with SIR wrapping!\n", __FUNCTION__); } else { @@ -1097,34 +1104,13 @@ status |= RD_TX_PULSE; /* send 2 us highspeed indication pulse */ len = skb->len; if (len > r->len) { - printk(KERN_ERR "%s: no space - skb too big (%d)\n", - __FUNCTION__, skb->len); + msg = "frame exceeds tx buffer length"; goto drop; } else memcpy(rd->buf, skb->data, len); } - /* do mtt delay before we need to disable interrupts! */ - - if ((mtt = irda_get_mtt(skb)) > 0) { - - ready.tv_usec = idev->last_rx.tv_usec + mtt; - ready.tv_sec = idev->last_rx.tv_sec; - if (ready.tv_usec >= 1000000) { - ready.tv_usec -= 1000000; - ready.tv_sec++; /* IrLAP 1.1: mtt always < 1 sec */ - } - for(;;) { - do_gettimeofday(&now); - if (now.tv_sec > ready.tv_sec - || (now.tv_sec==ready.tv_sec && now.tv_usec>=ready.tv_usec)) - break; - udelay(100); - /* must not sleep here - we are called under xmit_lock! */ - } - } - rd->skb = skb; /* remember skb for tx-complete stats */ rd_set_count(rd, len); @@ -1136,10 +1122,7 @@ pci_dma_prep_single(r->pdev, rd_get_addr(rd), r->len, r->dir); -/* - * We need to disable IR output in order to switch to TX mode. - * Better not do this blindly anytime we want to transmit something - * because TX may already run. However we are racing with the controller +/* Switching to TX mode here races with the controller * which may stop TX at any time when fetching an inactive descriptor * or one with CLR_ENTX set. So we switch on TX only, if TX was not running * _after_ the new descriptor was activated on the ring. This ensures @@ -1158,31 +1141,39 @@ int fifocnt; fifocnt = inw(ndev->base_addr+VLSI_PIO_RCVBCNT) & RCVBCNT_MASK; - if (fifocnt != 0) - printk(KERN_WARNING "%s: rx fifo not empty(%d)\n", - __FUNCTION__, fifocnt); + if (fifocnt != 0) { + IRDA_DEBUG(0, "%s: rx fifo not empty(%d)\n", __FUNCTION__, fifocnt); + } config = inw(iobase+VLSI_PIO_IRCFG); - rmb(); - outw(config | IRCFG_ENTX, iobase+VLSI_PIO_IRCFG); mb(); + outw(config | IRCFG_ENTX, iobase+VLSI_PIO_IRCFG); + wmb(); outw(0, iobase+VLSI_PIO_PROMPT); } ndev->trans_start = jiffies; if (ring_put(r) == NULL) { netif_stop_queue(ndev); - printk(KERN_DEBUG "%s: tx ring full - queue stopped\n", __FUNCTION__); + IRDA_DEBUG(3, "%s: tx ring full - queue stopped\n", __FUNCTION__); } spin_unlock_irqrestore(&idev->lock, flags); return 0; +drop_unlock: + spin_unlock_irqrestore(&idev->lock, flags); drop: + WARNING("%s: dropping packet - %s\n", __FUNCTION__, msg); dev_kfree_skb_any(skb); idev->stats.tx_errors++; idev->stats.tx_dropped++; - return 1; + /* Don't even think about returning NET_XMIT_DROP (=1) here! + * In fact any retval!=0 causes the packet scheduler to requeue the + * packet for later retry of transmission - which isn't exactly + * what we want after we've just called dev_kfree_skb_any ;-) + */ + return 0; } static void vlsi_tx_interrupt(struct net_device *ndev) @@ -1215,12 +1206,12 @@ } } + iobase = ndev->base_addr; + if (idev->new_baud && rd == NULL) /* tx ring empty and speed change pending */ - vlsi_set_baud_lock(ndev); + vlsi_set_baud(idev, iobase); - iobase = ndev->base_addr; config = inw(iobase+VLSI_PIO_IRCFG); - if (rd == NULL) /* tx ring empty: re-enable rx */ outw((config & ~IRCFG_ENTX) | IRCFG_ENRX, iobase+VLSI_PIO_IRCFG); @@ -1228,9 +1219,10 @@ int fifocnt; fifocnt = inw(iobase+VLSI_PIO_RCVBCNT) & RCVBCNT_MASK; - if (fifocnt != 0) - printk(KERN_WARNING "%s: rx fifo not empty(%d)\n", + if (fifocnt != 0) { + IRDA_DEBUG(0, "%s: rx fifo not empty(%d)\n", __FUNCTION__, fifocnt); + } outw(config | IRCFG_ENTX, iobase+VLSI_PIO_IRCFG); } @@ -1238,7 +1230,7 @@ if (netif_queue_stopped(ndev) && !idev->new_baud) { netif_wake_queue(ndev); - printk(KERN_DEBUG "%s: queue awoken\n", __FUNCTION__); + IRDA_DEBUG(3, "%s: queue awoken\n", __FUNCTION__); } } @@ -1261,7 +1253,7 @@ dev_kfree_skb_any(rd->skb); rd->skb = NULL; } - printk(KERN_INFO "%s - dropping tx packet\n", __FUNCTION__); + IRDA_DEBUG(0, "%s - dropping tx packet\n", __FUNCTION__); ret = -VLSI_TX_DROP; } else @@ -1310,8 +1302,7 @@ } if (count < 3) { if (clksrc == 1) { /* explicitly asked for PLL hence bail out */ - printk(KERN_ERR "%s: no PLL or failed to lock!\n", - __FUNCTION__); + ERROR("%s: no PLL or failed to lock!\n", __FUNCTION__); clkctl = CLKCTL_CLKSTP; pci_write_config_byte(pdev, VLSI_PCI_CLKCTL, clkctl); return -1; @@ -1319,7 +1310,7 @@ else /* was: clksrc=0(auto) */ clksrc = 3; /* fallback to 40MHz XCLK (OB800) */ - printk(KERN_INFO "%s: PLL not locked, fallback to clksrc=%d\n", + IRDA_DEBUG(0, "%s: PLL not locked, fallback to clksrc=%d\n", __FUNCTION__, clksrc); } else @@ -1392,9 +1383,7 @@ /* start the clock and clean the registers */ if (vlsi_start_clock(pdev)) { - printk(KERN_ERR "%s: no valid clock source\n", - __FUNCTION__); - pci_disable_device(pdev); + ERROR("%s: no valid clock source\n", __FUNCTION__); return -1; } iobase = ndev->base_addr; @@ -1422,7 +1411,7 @@ atomic_set(&idev->tx_ring->head, RINGPTR_GET_TX(ptr)); atomic_set(&idev->tx_ring->tail, RINGPTR_GET_TX(ptr)); - vlsi_set_baud_lock(ndev); /* idev->new_baud used as provided by caller */ + vlsi_set_baud(idev, iobase); /* idev->new_baud used as provided by caller */ outb(IRINTR_INT_MASK, iobase+VLSI_PIO_IRINTR); /* just in case - w/c pending IRQ's */ wmb(); @@ -1455,7 +1444,10 @@ pci_write_config_byte(pdev, VLSI_PCI_MSTRPAGE, MSTRPAGE_VALUE); pci_set_master(pdev); - vlsi_init_chip(pdev); + if (vlsi_init_chip(pdev) < 0) { + pci_disable_device(pdev); + return -1; + } vlsi_fill_rx(idev->rx_ring); @@ -1476,10 +1468,11 @@ spin_lock_irqsave(&idev->lock,flags); outw(0, iobase+VLSI_PIO_IRENABLE); outw(0, iobase+VLSI_PIO_IRCFG); /* disable everything */ - wmb(); - outb(IRINTR_INT_MASK, iobase+VLSI_PIO_IRINTR); /* w/c pending + disable further IRQ */ - mb(); + /* disable and w/c irqs */ + outb(0, iobase+VLSI_PIO_IRINTR); + wmb(); + outb(IRINTR_INT_MASK, iobase+VLSI_PIO_IRINTR); spin_unlock_irqrestore(&idev->lock,flags); vlsi_unarm_tx(idev); @@ -1521,8 +1514,8 @@ idev->new_baud = idev->baud; /* keep current baudrate */ if (vlsi_start_hw(idev)) - printk(KERN_CRIT "%s: failed to restart hw - %s(%s) unusable!\n", - __FUNCTION__, pci_name(idev->pdev), ndev->name); + ERROR("%s: failed to restart hw - %s(%s) unusable!\n", + __FUNCTION__, PCIDEV_NAME(idev->pdev), ndev->name); else netif_start_queue(ndev); } @@ -1547,7 +1540,7 @@ * if the stack tries to change speed concurrently - which would be * pretty strange anyway with the userland having full control... */ - vlsi_set_baud_nolock(ndev); + vlsi_set_baud(idev, ndev->base_addr); spin_unlock_irqrestore(&idev->lock, flags); break; case SIOCSMEDIABUSY: @@ -1566,8 +1559,7 @@ irq->ifr_receiving = (fifocnt!=0) ? 1 : 0; break; default: - printk(KERN_ERR "%s: notsupp - cmd=%04x\n", - __FUNCTION__, cmd); + WARNING("%s: notsupp - cmd=%04x\n", __FUNCTION__, cmd); ret = -EOPNOTSUPP; } @@ -1583,41 +1575,36 @@ vlsi_irda_dev_t *idev = ndev->priv; unsigned iobase; u8 irintr; - int boguscount = 32; - unsigned got_act; + int boguscount = 5; unsigned long flags; int handled = 0; - got_act = 0; iobase = ndev->base_addr; + spin_lock_irqsave(&idev->lock,flags); do { - spin_lock_irqsave(&idev->lock,flags); irintr = inb(iobase+VLSI_PIO_IRINTR); - rmb(); - outb(irintr, iobase+VLSI_PIO_IRINTR); /* acknowledge asap */ - spin_unlock_irqrestore(&idev->lock,flags); + mb(); + outb(irintr, iobase+VLSI_PIO_IRINTR); /* acknowledge asap */ if (!(irintr&=IRINTR_INT_MASK)) /* not our INT - probably shared */ break; + handled = 1; + + if (unlikely(!(irintr & ~IRINTR_ACTIVITY))) + break; /* nothing todo if only activity */ + if (irintr&IRINTR_RPKTINT) vlsi_rx_interrupt(ndev); if (irintr&IRINTR_TPKTINT) vlsi_tx_interrupt(ndev); - if (!(irintr & ~IRINTR_ACTIVITY)) - break; /* done if only activity remaining */ - - if (irintr & ~(IRINTR_RPKTINT|IRINTR_TPKTINT|IRINTR_ACTIVITY)) { - printk(KERN_DEBUG "%s: IRINTR = %02x\n", - __FUNCTION__, (unsigned)irintr); - vlsi_reg_debug(iobase,__FUNCTION__); - } } while (--boguscount > 0); + spin_unlock_irqrestore(&idev->lock,flags); if (boguscount <= 0) - printk(KERN_WARNING "%s: too much work in interrupt!\n", __FUNCTION__); + MESSAGE("%s: too much work in interrupt!\n", __FUNCTION__); return IRQ_RETVAL(handled); } @@ -1630,7 +1617,7 @@ char hwname[32]; if (pci_request_regions(idev->pdev, drivername)) { - printk(KERN_ERR "%s: io resource busy\n", __FUNCTION__); + WARNING("%s: io resource busy\n", __FUNCTION__); goto errout; } ndev->base_addr = pci_resource_start(idev->pdev,0); @@ -1644,8 +1631,7 @@ if (request_irq(ndev->irq, vlsi_interrupt, SA_SHIRQ, drivername, ndev)) { - printk(KERN_ERR "%s: couldn't get IRQ: %d\n", - __FUNCTION__, ndev->irq); + WARNING("%s: couldn't get IRQ: %d\n", __FUNCTION__, ndev->irq); goto errout_io; } @@ -1666,7 +1652,7 @@ netif_start_queue(ndev); - printk(KERN_INFO "%s: device %s operational\n", __FUNCTION__, ndev->name); + MESSAGE("%s: device %s operational\n", __FUNCTION__, ndev->name); return 0; @@ -1700,7 +1686,7 @@ pci_release_regions(idev->pdev); - printk(KERN_INFO "%s: device %s stopped\n", __FUNCTION__, ndev->name); + MESSAGE("%s: device %s stopped\n", __FUNCTION__, ndev->name); return 0; } @@ -1721,8 +1707,7 @@ if (pci_set_dma_mask(pdev,DMA_MASK_USED_BY_HW) || pci_set_dma_mask(pdev,DMA_MASK_MSTRPAGE)) { - printk(KERN_ERR "%s: aborting due to PCI BM-DMA address limitations\n", - __FUNCTION__); + ERROR("%s: aborting due to PCI BM-DMA address limitations\n", __FUNCTION__); return -1; } @@ -1771,12 +1756,12 @@ else pdev->current_state = 0; /* hw must be running now */ - printk(KERN_INFO "%s: IrDA PCI controller %s detected\n", - drivername, pci_name(pdev)); + MESSAGE("%s: IrDA PCI controller %s detected\n", + drivername, PCIDEV_NAME(pdev)); if ( !pci_resource_start(pdev,0) || !(pci_resource_flags(pdev,0) & IORESOURCE_IO) ) { - printk(KERN_ERR "%s: bar 0 invalid", __FUNCTION__); + ERROR("%s: bar 0 invalid", __FUNCTION__); goto out_disable; } @@ -1784,8 +1769,7 @@ ndev = (struct net_device *) kmalloc (alloc_size, GFP_KERNEL); if (ndev==NULL) { - printk(KERN_ERR "%s: Unable to allocate device memory.\n", - __FUNCTION__); + ERROR("%s: Unable to allocate device memory.\n", __FUNCTION__); goto out_disable; } @@ -1801,37 +1785,33 @@ ndev->init = vlsi_irda_init; strcpy(ndev->name,"irda%d"); if (register_netdev(ndev)) { - printk(KERN_ERR "%s: register_netdev failed\n", - __FUNCTION__); + ERROR("%s: register_netdev failed\n", __FUNCTION__); goto out_freedev; } + idev->proc_entry = NULL; if (vlsi_proc_root != NULL) { struct proc_dir_entry *ent; ent = create_proc_entry(ndev->name, S_IFREG|S_IRUGO, vlsi_proc_root); if (!ent) { - printk(KERN_ERR "%s: failed to create proc entry\n", __FUNCTION__); - goto out_unregister; + WARNING("%s: failed to create proc entry\n", __FUNCTION__); + idev->proc_entry = NULL; } - ent->data = ndev; - ent->proc_fops = VLSI_PROC_FOPS; - ent->size = 0; - idev->proc_entry = ent; - } else - idev->proc_entry = NULL; - - printk(KERN_INFO "%s: registered device %s\n", drivername, ndev->name); + else { + ent->data = ndev; + ent->proc_fops = VLSI_PROC_FOPS; + ent->size = 0; + idev->proc_entry = ent; + } + } + MESSAGE("%s: registered device %s\n", drivername, ndev->name); pci_set_drvdata(pdev, ndev); up(&idev->sem); return 0; -out_unregister: - up(&idev->sem); - unregister_netdev(ndev); - goto out_disable; out_freedev: up(&idev->sem); kfree(ndev); @@ -1848,14 +1828,12 @@ vlsi_irda_dev_t *idev; if (!ndev) { - printk(KERN_CRIT "%s: lost netdevice?\n", drivername); + ERROR("%s: lost netdevice?\n", drivername); return; } idev = ndev->priv; down(&idev->sem); - pci_set_drvdata(pdev, NULL); - pci_disable_device(pdev); if (idev->proc_entry) { remove_proc_entry(ndev->name, vlsi_proc_root); idev->proc_entry = NULL; @@ -1867,7 +1845,9 @@ * ndev->destructor called (if present) when going to free */ - printk(KERN_INFO "%s: %s removed\n", drivername, pci_name(pdev)); + pci_set_drvdata(pdev, NULL); + + MESSAGE("%s: %s removed\n", drivername, PCIDEV_NAME(pdev)); } #ifdef CONFIG_PM @@ -1882,8 +1862,8 @@ static int vlsi_irda_save_state(struct pci_dev *pdev, u32 state) { if (state < 1 || state > 3 ) { - printk( KERN_ERR "%s - %s: invalid pm state request: %u\n", - __FUNCTION__, pci_name(pdev), state); + ERROR("%s - %s: invalid pm state request: %u\n", + __FUNCTION__, PCIDEV_NAME(pdev), state); return -1; } return 0; @@ -1895,12 +1875,12 @@ vlsi_irda_dev_t *idev; if (state < 1 || state > 3 ) { - printk( KERN_ERR "%s - %s: invalid pm state request: %u\n", - __FUNCTION__, pci_name(pdev), state); + ERROR("%s - %s: invalid pm state request: %u\n", + __FUNCTION__, PCIDEV_NAME(pdev), state); return 0; } if (!ndev) { - printk(KERN_ERR "%s - %s: no netdevice \n", __FUNCTION__, pci_name(pdev)); + ERROR("%s - %s: no netdevice \n", __FUNCTION__, PCIDEV_NAME(pdev)); return 0; } idev = ndev->priv; @@ -1911,8 +1891,8 @@ pdev->current_state = state; } else - printk(KERN_ERR "%s - %s: invalid suspend request %u -> %u\n", - __FUNCTION__, pci_name(pdev), pdev->current_state, state); + ERROR("%s - %s: invalid suspend request %u -> %u\n", + __FUNCTION__, PCIDEV_NAME(pdev), pdev->current_state, state); up(&idev->sem); return 0; } @@ -1939,14 +1919,14 @@ vlsi_irda_dev_t *idev; if (!ndev) { - printk(KERN_ERR "%s - %s: no netdevice \n", __FUNCTION__, pci_name(pdev)); + ERROR("%s - %s: no netdevice \n", __FUNCTION__, PCIDEV_NAME(pdev)); return 0; } idev = ndev->priv; down(&idev->sem); if (pdev->current_state == 0) { up(&idev->sem); - printk(KERN_ERR "%s - %s: already resumed\n", __FUNCTION__, pci_name(pdev)); + WARNING("%s - %s: already resumed\n", __FUNCTION__, PCIDEV_NAME(pdev)); return 0; } @@ -1965,7 +1945,7 @@ * now we explicitly set pdev->current_state = 0 after enabling the * device and independently resume_ok should catch any garbage config. */ - printk(KERN_ERR "%s - hm, nothing to resume?\n", __FUNCTION__); + WARNING("%s - hm, nothing to resume?\n", __FUNCTION__); up(&idev->sem); return 0; } @@ -2003,7 +1983,7 @@ int i, ret; if (clksrc < 0 || clksrc > 3) { - printk(KERN_ERR "%s: invalid clksrc=%d\n", drivername, clksrc); + ERROR("%s: invalid clksrc=%d\n", drivername, clksrc); return -1; } @@ -2016,9 +1996,8 @@ case 64: break; default: - printk(KERN_WARNING "%s: invalid %s ringsize %d", + WARNING("%s: invalid %s ringsize %d, using default=8", drivername, (i)?"rx":"tx", ringsize[i]); - printk(", using default=8\n"); ringsize[i] = 8; break; } diff -Nru a/drivers/net/ixgb/ixgb_main.c b/drivers/net/ixgb/ixgb_main.c --- a/drivers/net/ixgb/ixgb_main.c Tue Sep 2 19:58:13 2003 +++ b/drivers/net/ixgb/ixgb_main.c Tue Sep 2 19:58:13 2003 @@ -1914,10 +1914,8 @@ skb->protocol = eth_type_trans(skb, netdev); if (adapter->vlgrp && (rx_desc->status & IXGB_RX_DESC_STATUS_VP)) { - vlan_hwaccel_rx(skb, adapter->vlgrp, - (rx_desc-> - special & - IXGB_RX_DESC_SPECIAL_VLAN_MASK)); + vlan_hwaccel_receive_skb(skb, adapter->vlgrp, + (rx_desc-> special & IXGB_RX_DESC_SPECIAL_VLAN_MASK)); } else { netif_receive_skb(skb); } diff -Nru a/drivers/net/ne2k-pci.c b/drivers/net/ne2k-pci.c --- a/drivers/net/ne2k-pci.c Tue Sep 2 19:58:14 2003 +++ b/drivers/net/ne2k-pci.c Tue Sep 2 19:58:14 2003 @@ -174,7 +174,7 @@ struct sk_buff *skb, int ring_offset); static void ne2k_pci_block_output(struct net_device *dev, const int count, const unsigned char *buf, const int start_page); -static int netdev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); +static struct ethtool_ops ne2k_pci_ethtool_ops; @@ -259,7 +259,8 @@ } } - dev = alloc_etherdev(0); + /* Allocate net_device, dev->priv; fill in 8390 specific dev fields. */ + dev = alloc_ei_netdev(); if (!dev) { printk (KERN_ERR PFX "cannot allocate ethernet device\n"); goto err_out_free_res; @@ -331,13 +332,6 @@ dev->base_addr = ioaddr; pci_set_drvdata(pdev, dev); - /* Allocate dev->priv and fill in 8390 specific dev fields. */ - if (ethdev_init(dev)) { - printk (KERN_ERR "ne2kpci(%s): unable to get memory for dev->priv.\n", - pci_name(pdev)); - goto err_out_free_netdev; - } - ei_status.name = pci_clone_list[chip_idx].name; ei_status.tx_start_page = start_page; ei_status.stop_page = stop_page; @@ -361,12 +355,12 @@ ei_status.priv = (unsigned long) pdev; dev->open = &ne2k_pci_open; dev->stop = &ne2k_pci_close; - dev->do_ioctl = &netdev_ioctl; + dev->ethtool_ops = &ne2k_pci_ethtool_ops; NS8390_init(dev, 0); i = register_netdev(dev); if (i) - goto err_out_free_8390; + goto err_out_free_netdev; printk("%s: %s found at %#lx, IRQ %d, ", dev->name, pci_clone_list[chip_idx].name, ioaddr, dev->irq); @@ -377,10 +371,8 @@ return 0; -err_out_free_8390: - kfree(dev->priv); err_out_free_netdev: - kfree (dev); + free_netdev (dev); err_out_free_res: release_region (ioaddr, NE_IO_EXTENT); pci_set_drvdata (pdev, NULL); @@ -591,41 +583,23 @@ return; } -static int netdev_ethtool_ioctl(struct net_device *dev, void *useraddr) +static void ne2k_pci_get_drvinfo(struct net_device *dev, + struct ethtool_drvinfo *info) { struct ei_device *ei = dev->priv; struct pci_dev *pci_dev = (struct pci_dev *) ei->priv; - u32 ethcmd; - - if (copy_from_user(ðcmd, useraddr, sizeof(ethcmd))) - return -EFAULT; - - switch (ethcmd) { - case ETHTOOL_GDRVINFO: { - struct ethtool_drvinfo info = {ETHTOOL_GDRVINFO}; - strcpy(info.driver, DRV_NAME); - strcpy(info.version, DRV_VERSION); - strcpy(info.bus_info, pci_name(pci_dev)); - if (copy_to_user(useraddr, &info, sizeof(info))) - return -EFAULT; - return 0; - } - - } - - return -EOPNOTSUPP; -} -static int netdev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) -{ - switch(cmd) { - case SIOCETHTOOL: - return netdev_ethtool_ioctl(dev, (void *) rq->ifr_data); - default: - return -EOPNOTSUPP; - } + strcpy(info->driver, DRV_NAME); + strcpy(info->version, DRV_VERSION); + strcpy(info->bus_info, pci_name(pci_dev)); } +static struct ethtool_ops ne2k_pci_ethtool_ops = { + .get_drvinfo = ne2k_pci_get_drvinfo, + .get_tx_csum = ethtool_op_get_tx_csum, + .get_sg = ethtool_op_get_sg, +}; + static void __devexit ne2k_pci_remove_one (struct pci_dev *pdev) { struct net_device *dev = pci_get_drvdata(pdev); @@ -635,8 +609,8 @@ unregister_netdev(dev); release_region(dev->base_addr, NE_IO_EXTENT); - kfree(dev->priv); free_netdev(dev); + pci_disable_device(pdev); pci_set_drvdata(pdev, NULL); } diff -Nru a/drivers/net/ni5010.c b/drivers/net/ni5010.c --- a/drivers/net/ni5010.c Tue Sep 2 19:58:15 2003 +++ b/drivers/net/ni5010.c Tue Sep 2 19:58:15 2003 @@ -96,6 +96,7 @@ struct net_device_stats stats; int o_pkt_size; int i_pkt_size; + spinlock_t lock; }; /* Index to functions, as function prototypes. */ @@ -280,11 +281,16 @@ /* DMA is not supported (yet?), so no use detecting it */ if (dev->priv == NULL) { + struct ni5010_local* lp; + dev->priv = kmalloc(sizeof(struct ni5010_local), GFP_KERNEL|GFP_DMA); if (dev->priv == NULL) { printk(KERN_WARNING "%s: Failed to allocate private memory\n", dev->name); return -ENOMEM; } + + lp = (struct ni5010_local*)dev->priv; + spin_lock_init(&lp->lock); } PRINTK2((KERN_DEBUG "%s: I/O #10 passed!\n", dev->name)); @@ -463,6 +469,7 @@ ioaddr = dev->base_addr; lp = (struct ni5010_local *)dev->priv; + spin_lock(&lp->lock); status = inb(IE_ISTAT); PRINTK3((KERN_DEBUG "%s: IE_ISTAT = %#02x\n", dev->name, status)); @@ -479,6 +486,7 @@ if (!xmit_was_error) reset_receiver(dev); + spin_unlock(&lp->lock); return IRQ_HANDLED; } @@ -693,8 +701,7 @@ buf_offs = NI5010_BUFSIZE - length - pad; lp->o_pkt_size = length + pad; - save_flags(flags); - cli(); + spin_lock_irqsave(&lp->lock, flags); outb(0, EDLC_RMASK); /* Mask all receive interrupts */ outb(0, IE_MMODE); /* Put Xmit buffer on system bus */ @@ -712,7 +719,7 @@ outb(MM_EN_XMT | MM_MUX, IE_MMODE); /* Begin transmission */ outb(XM_ALL, EDLC_XMASK); /* Cause interrupt after completion or fail */ - restore_flags(flags); + spin_unlock_irqrestore(&lp->lock, flags); netif_wake_queue(dev); diff -Nru a/drivers/net/pcmcia/3c574_cs.c b/drivers/net/pcmcia/3c574_cs.c --- a/drivers/net/pcmcia/3c574_cs.c Tue Sep 2 19:58:14 2003 +++ b/drivers/net/pcmcia/3c574_cs.c Tue Sep 2 19:58:14 2003 @@ -253,6 +253,7 @@ static int el3_close(struct net_device *dev); static void el3_tx_timeout(struct net_device *dev); static int el3_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); +static struct ethtool_ops netdev_ethtool_ops; static void set_rx_mode(struct net_device *dev); static dev_info_t dev_info = "3c574_cs"; @@ -319,6 +320,7 @@ dev->hard_start_xmit = &el3_start_xmit; dev->get_stats = &el3_get_stats; dev->do_ioctl = &el3_ioctl; + SET_ETHTOOL_OPS(dev, &netdev_ethtool_ops); dev->set_multicast_list = &set_rx_mode; dev->open = &el3_open; dev->stop = &el3_close; @@ -1202,26 +1204,16 @@ return worklimit; } -static int netdev_ethtool_ioctl(struct net_device *dev, void *useraddr) +static void netdev_get_drvinfo(struct net_device *dev, + struct ethtool_drvinfo *info) { - u32 ethcmd; - - if (copy_from_user(ðcmd, useraddr, sizeof(ethcmd))) - return -EFAULT; - - switch (ethcmd) { - case ETHTOOL_GDRVINFO: { - struct ethtool_drvinfo info = {ETHTOOL_GDRVINFO}; - strncpy(info.driver, "3c574_cs", sizeof(info.driver)-1); - if (copy_to_user(useraddr, &info, sizeof(info))) - return -EFAULT; - return 0; - } - } - - return -EOPNOTSUPP; + strcpy(info->driver, "3c574_cs"); } +static struct ethtool_ops netdev_ethtool_ops = { + .get_drvinfo = netdev_get_drvinfo, +}; + /* Provide ioctl() calls to examine the MII xcvr state. */ static int el3_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) { @@ -1235,11 +1227,9 @@ data[0], data[1], data[2], data[3]); switch(cmd) { - case SIOCETHTOOL: - return netdev_ethtool_ioctl(dev, (void *)rq->ifr_data); - case SIOCDEVPRIVATE: /* Get the address of the PHY in use. */ + case SIOCGMIIPHY: /* Get the address of the PHY in use. */ data[0] = phy; - case SIOCDEVPRIVATE+1: /* Read the specified MII register. */ + case SIOCGMIIREG: /* Read the specified MII register. */ { int saved_window; unsigned long flags; @@ -1252,7 +1242,7 @@ spin_unlock_irqrestore(&lp->window_lock, flags); return 0; } - case SIOCDEVPRIVATE+2: /* Write the specified MII register */ + case SIOCSMIIREG: /* Write the specified MII register */ { int saved_window; unsigned long flags; diff -Nru a/drivers/net/pcmcia/3c589_cs.c b/drivers/net/pcmcia/3c589_cs.c --- a/drivers/net/pcmcia/3c589_cs.c Tue Sep 2 19:58:19 2003 +++ b/drivers/net/pcmcia/3c589_cs.c Tue Sep 2 19:58:19 2003 @@ -165,7 +165,7 @@ static int el3_close(struct net_device *dev); static void el3_tx_timeout(struct net_device *dev); static void set_multicast_list(struct net_device *dev); -static int netdev_ioctl (struct net_device *dev, struct ifreq *rq, int cmd); +static struct ethtool_ops netdev_ethtool_ops; static dev_info_t dev_info = "3c589_cs"; @@ -249,7 +249,7 @@ dev->tx_timeout = el3_tx_timeout; dev->watchdog_timeo = TX_TIMEOUT; #endif - dev->do_ioctl = netdev_ioctl; + SET_ETHTOOL_OPS(dev, &netdev_ethtool_ops); /* Register with Card Services */ link->next = dev_list; @@ -639,70 +639,33 @@ | AdapterFailure, ioaddr + EL3_CMD); } -static int netdev_ethtool_ioctl (struct net_device *dev, void *useraddr) +static void netdev_get_drvinfo(struct net_device *dev, + struct ethtool_drvinfo *info) { - u32 ethcmd; - - /* dev_ioctl() in ../../net/core/dev.c has already checked - capable(CAP_NET_ADMIN), so don't bother with that here. */ - - if (get_user(ethcmd, (u32 *)useraddr)) - return -EFAULT; - - switch (ethcmd) { - - case ETHTOOL_GDRVINFO: { - struct ethtool_drvinfo info = { ETHTOOL_GDRVINFO }; - strcpy (info.driver, DRV_NAME); - strcpy (info.version, DRV_VERSION); - sprintf(info.bus_info, "PCMCIA 0x%lx", dev->base_addr); - if (copy_to_user (useraddr, &info, sizeof (info))) - return -EFAULT; - return 0; - } + strcpy(info->driver, DRV_NAME); + strcpy(info->version, DRV_VERSION); + sprintf(info->bus_info, "PCMCIA 0x%lx", dev->base_addr); +} #ifdef PCMCIA_DEBUG - /* get message-level */ - case ETHTOOL_GMSGLVL: { - struct ethtool_value edata = {ETHTOOL_GMSGLVL}; - edata.data = pc_debug; - if (copy_to_user(useraddr, &edata, sizeof(edata))) - return -EFAULT; - return 0; - } - /* set message-level */ - case ETHTOOL_SMSGLVL: { - struct ethtool_value edata; - if (copy_from_user(&edata, useraddr, sizeof(edata))) - return -EFAULT; - pc_debug = edata.data; - return 0; - } -#endif - - default: - break; - } - - return -EOPNOTSUPP; +static u32 netdev_get_msglevel(struct net_device *dev) +{ + return pc_debug; } -static int netdev_ioctl (struct net_device *dev, struct ifreq *rq, int cmd) +static void netdev_set_msglevel(struct net_device *dev, u32 level) { - int rc; - - switch (cmd) { - case SIOCETHTOOL: - rc = netdev_ethtool_ioctl(dev, (void *) rq->ifr_data); - break; - - default: - rc = -EOPNOTSUPP; - break; - } - - return rc; + pc_debug = level; } +#endif /* PCMCIA_DEBUG */ + +static struct ethtool_ops netdev_ethtool_ops = { + .get_drvinfo = netdev_get_drvinfo, +#ifdef PCMCIA_DEBUG + .get_msglevel = netdev_get_msglevel, + .set_msglevel = netdev_set_msglevel, +#endif /* PCMCIA_DEBUG */ +}; static int el3_config(struct net_device *dev, struct ifmap *map) { diff -Nru a/drivers/net/pcmcia/axnet_cs.c b/drivers/net/pcmcia/axnet_cs.c --- a/drivers/net/pcmcia/axnet_cs.c Tue Sep 2 19:58:16 2003 +++ b/drivers/net/pcmcia/axnet_cs.c Tue Sep 2 19:58:16 2003 @@ -98,6 +98,7 @@ static int axnet_open(struct net_device *dev); static int axnet_close(struct net_device *dev); static int axnet_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); +static struct ethtool_ops netdev_ethtool_ops; static irqreturn_t ei_irq_wrapper(int irq, void *dev_id, struct pt_regs *regs); static void ei_watchdog(u_long arg); static void axnet_reset_8390(struct net_device *dev); @@ -209,6 +210,7 @@ dev->open = &axnet_open; dev->stop = &axnet_close; dev->do_ioctl = &axnet_ioctl; + SET_ETHTOOL_OPS(dev, &netdev_ethtool_ops); /* Register with Card Services */ link->next = dev_list; @@ -807,26 +809,16 @@ add_timer(&info->watchdog); } -static int netdev_ethtool_ioctl(struct net_device *dev, void *useraddr) +static void netdev_get_drvinfo(struct net_device *dev, + struct ethtool_drvinfo *info) { - u32 ethcmd; - - if (copy_from_user(ðcmd, useraddr, sizeof(ethcmd))) - return -EFAULT; - - switch (ethcmd) { - case ETHTOOL_GDRVINFO: { - struct ethtool_drvinfo info = {ETHTOOL_GDRVINFO}; - strncpy(info.driver, "axnet_cs", sizeof(info.driver)-1); - if (copy_to_user(useraddr, &info, sizeof(info))) - return -EFAULT; - return 0; - } - } - - return -EOPNOTSUPP; + strcpy(info->driver, "axnet_cs"); } +static struct ethtool_ops netdev_ethtool_ops = { + .get_drvinfo = netdev_get_drvinfo, +}; + /*====================================================================*/ static int axnet_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) @@ -835,14 +827,12 @@ u16 *data = (u16 *)&rq->ifr_data; ioaddr_t mii_addr = dev->base_addr + AXNET_MII_EEP; switch (cmd) { - case SIOCETHTOOL: - return netdev_ethtool_ioctl(dev, (void *) rq->ifr_data); - case SIOCDEVPRIVATE: + case SIOCGMIIPHY: data[0] = info->phy_id; - case SIOCDEVPRIVATE+1: + case SIOCGMIIREG: /* Read MII PHY register. */ data[3] = mdio_read(mii_addr, data[0], data[1] & 0x1f); return 0; - case SIOCDEVPRIVATE+2: + case SIOCSMIIREG: /* Write MII PHY register. */ if (!capable(CAP_NET_ADMIN)) return -EPERM; mdio_write(mii_addr, data[0], data[1] & 0x1f, data[2]); diff -Nru a/drivers/net/pcmcia/fmvj18x_cs.c b/drivers/net/pcmcia/fmvj18x_cs.c --- a/drivers/net/pcmcia/fmvj18x_cs.c Tue Sep 2 19:58:17 2003 +++ b/drivers/net/pcmcia/fmvj18x_cs.c Tue Sep 2 19:58:17 2003 @@ -113,7 +113,7 @@ static struct net_device_stats *fjn_get_stats(struct net_device *dev); static void set_rx_mode(struct net_device *dev); static void fjn_tx_timeout(struct net_device *dev); -static int fjn_ioctl(struct net_device *, struct ifreq *, int); +static struct ethtool_ops netdev_ethtool_ops; static dev_info_t dev_info = "fmvj18x_cs"; static dev_link_t *dev_list; @@ -312,7 +312,7 @@ dev->tx_timeout = fjn_tx_timeout; dev->watchdog_timeo = TX_TIMEOUT; #endif - dev->do_ioctl = fjn_ioctl; + SET_ETHTOOL_OPS(dev, &netdev_ethtool_ops); /* Register with Card Services */ link->next = dev_list; @@ -1186,64 +1186,33 @@ /*====================================================================*/ -static int netdev_ethtool_ioctl (struct net_device *dev, void *useraddr) +static void netdev_get_drvinfo(struct net_device *dev, + struct ethtool_drvinfo *info) { - u32 ethcmd; - - /* dev_ioctl() in ../../net/core/dev.c has already checked - capable(CAP_NET_ADMIN), so don't bother with that here. */ - - if (get_user(ethcmd, (u32 *)useraddr)) - return -EFAULT; - - switch (ethcmd) { - - case ETHTOOL_GDRVINFO: { - struct ethtool_drvinfo info = { ETHTOOL_GDRVINFO }; - strcpy (info.driver, DRV_NAME); - strcpy (info.version, DRV_VERSION); - sprintf(info.bus_info, "PCMCIA 0x%lx", dev->base_addr); - if (copy_to_user (useraddr, &info, sizeof (info))) - return -EFAULT; - return 0; - } + strcpy(info->driver, DRV_NAME); + strcpy(info->version, DRV_VERSION); + sprintf(info->bus_info, "PCMCIA 0x%lx", dev->base_addr); +} #ifdef PCMCIA_DEBUG - /* get message-level */ - case ETHTOOL_GMSGLVL: { - struct ethtool_value edata = {ETHTOOL_GMSGLVL}; - edata.data = pc_debug; - if (copy_to_user(useraddr, &edata, sizeof(edata))) - return -EFAULT; - return 0; - } - /* set message-level */ - case ETHTOOL_SMSGLVL: { - struct ethtool_value edata; - if (copy_from_user(&edata, useraddr, sizeof(edata))) - return -EFAULT; - pc_debug = edata.data; - return 0; - } -#endif - - default: - break; - } - - return -EOPNOTSUPP; +static u32 netdev_get_msglevel(struct net_device *dev) +{ + return pc_debug; } -static int fjn_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) +static void netdev_set_msglevel(struct net_device *dev, u32 level) { - switch (cmd) { - case SIOCETHTOOL: - return netdev_ethtool_ioctl(dev, (void *) rq->ifr_data); - - default: - return -EOPNOTSUPP; - } + pc_debug = level; } +#endif /* PCMCIA_DEBUG */ + +static struct ethtool_ops netdev_ethtool_ops = { + .get_drvinfo = netdev_get_drvinfo, +#ifdef PCMCIA_DEBUG + .get_msglevel = netdev_get_msglevel, + .set_msglevel = netdev_set_msglevel, +#endif /* PCMCIA_DEBUG */ +}; static int fjn_config(struct net_device *dev, struct ifmap *map){ return 0; diff -Nru a/drivers/net/pcmcia/ibmtr_cs.c b/drivers/net/pcmcia/ibmtr_cs.c --- a/drivers/net/pcmcia/ibmtr_cs.c Tue Sep 2 19:58:16 2003 +++ b/drivers/net/pcmcia/ibmtr_cs.c Tue Sep 2 19:58:16 2003 @@ -157,36 +157,15 @@ } } -static int netdev_ethtool_ioctl(struct net_device *dev, void *useraddr) +static void netdev_get_drvinfo(struct net_device *dev, + struct ethtool_drvinfo *info) { - u32 ethcmd; - - if (copy_from_user(ðcmd, useraddr, sizeof(ethcmd))) - return -EFAULT; - - switch (ethcmd) { - case ETHTOOL_GDRVINFO: { - struct ethtool_drvinfo info = {ETHTOOL_GDRVINFO}; - strncpy(info.driver, "ibmtr_cs", sizeof(info.driver)-1); - if (copy_to_user(useraddr, &info, sizeof(info))) - return -EFAULT; - return 0; - } - } - - return -EOPNOTSUPP; + strcpy(info->driver, "ibmtr_cs"); } -static int private_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) -{ - - switch(cmd) { - case SIOCETHTOOL: - return netdev_ethtool_ioctl(dev, (void *) rq->ifr_data); - default: - return -EOPNOTSUPP; - } -} +static struct ethtool_ops netdev_ethtool_ops = { + .get_drvinfo = netdev_get_drvinfo, +}; /*====================================================================== @@ -235,7 +214,7 @@ link->irq.Instance = info->dev = dev; dev->init = &ibmtr_probe; - dev->do_ioctl = &private_ioctl; + SET_ETHTOOL_OPS(dev, &netdev_ethtool_ops); /* Register with Card Services */ link->next = dev_list; diff -Nru a/drivers/net/pcmcia/nmclan_cs.c b/drivers/net/pcmcia/nmclan_cs.c --- a/drivers/net/pcmcia/nmclan_cs.c Tue Sep 2 19:58:13 2003 +++ b/drivers/net/pcmcia/nmclan_cs.c Tue Sep 2 19:58:13 2003 @@ -442,7 +442,8 @@ static int mace_rx(struct net_device *dev, unsigned char RxCnt); static void restore_multicast_list(struct net_device *dev); static void set_multicast_list(struct net_device *dev); -static int mace_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); +static struct ethtool_ops netdev_ethtool_ops; + static dev_link_t *nmclan_attach(void); static void nmclan_detach(dev_link_t *); @@ -515,7 +516,7 @@ dev->set_config = &mace_config; dev->get_stats = &mace_get_stats; dev->set_multicast_list = &set_multicast_list; - dev->do_ioctl = &mace_ioctl; + SET_ETHTOOL_OPS(dev, &netdev_ethtool_ops); dev->open = &mace_open; dev->stop = &mace_close; #ifdef HAVE_TX_TIMEOUT @@ -1014,65 +1015,33 @@ return 0; } /* mace_close */ -static int netdev_ethtool_ioctl (struct net_device *dev, void *useraddr) +static void netdev_get_drvinfo(struct net_device *dev, + struct ethtool_drvinfo *info) { - u32 ethcmd; - - /* dev_ioctl() in ../../net/core/dev.c has already checked - capable(CAP_NET_ADMIN), so don't bother with that here. */ - - if (get_user(ethcmd, (u32 *)useraddr)) - return -EFAULT; - - switch (ethcmd) { - - case ETHTOOL_GDRVINFO: { - struct ethtool_drvinfo info = { ETHTOOL_GDRVINFO }; - strcpy (info.driver, DRV_NAME); - strcpy (info.version, DRV_VERSION); - sprintf(info.bus_info, "PCMCIA 0x%lx", dev->base_addr); - if (copy_to_user (useraddr, &info, sizeof (info))) - return -EFAULT; - return 0; - } + strcpy(info->driver, DRV_NAME); + strcpy(info->version, DRV_VERSION); + sprintf(info->bus_info, "PCMCIA 0x%lx", dev->base_addr); +} #ifdef PCMCIA_DEBUG - /* get message-level */ - case ETHTOOL_GMSGLVL: { - struct ethtool_value edata = {ETHTOOL_GMSGLVL}; - edata.data = pc_debug; - if (copy_to_user(useraddr, &edata, sizeof(edata))) - return -EFAULT; - return 0; - } - /* set message-level */ - case ETHTOOL_SMSGLVL: { - struct ethtool_value edata; - if (copy_from_user(&edata, useraddr, sizeof(edata))) - return -EFAULT; - pc_debug = edata.data; - return 0; - } -#endif - - default: - break; - } - - return -EOPNOTSUPP; +static u32 netdev_get_msglevel(struct net_device *dev) +{ + return pc_debug; } -static int mace_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) +static void netdev_set_msglevel(struct net_device *dev, u32 level) { - switch (cmd) { - case SIOCETHTOOL: - return netdev_ethtool_ioctl(dev, (void *) rq->ifr_data); - - default: - return -EOPNOTSUPP; - } - return 0; + pc_debug = level; } +#endif /* PCMCIA_DEBUG */ + +static struct ethtool_ops netdev_ethtool_ops = { + .get_drvinfo = netdev_get_drvinfo, +#ifdef PCMCIA_DEBUG + .get_msglevel = netdev_get_msglevel, + .set_msglevel = netdev_set_msglevel, +#endif /* PCMCIA_DEBUG */ +}; /* ---------------------------------------------------------------------------- mace_start_xmit diff -Nru a/drivers/net/pcmcia/pcnet_cs.c b/drivers/net/pcmcia/pcnet_cs.c --- a/drivers/net/pcmcia/pcnet_cs.c Tue Sep 2 19:58:18 2003 +++ b/drivers/net/pcmcia/pcnet_cs.c Tue Sep 2 19:58:18 2003 @@ -116,7 +116,7 @@ static int pcnet_open(struct net_device *dev); static int pcnet_close(struct net_device *dev); static int ei_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); -static int do_ioctl_light(struct net_device *dev, struct ifreq *rq, int cmd); +static struct ethtool_ops netdev_ethtool_ops; static irqreturn_t ei_irq_wrapper(int irq, void *dev_id, struct pt_regs *regs); static void ei_watchdog(u_long arg); static void pcnet_reset_8390(struct net_device *dev); @@ -756,6 +756,7 @@ strcpy(info->node.dev_name, dev->name); link->dev = &info->node; + SET_ETHTOOL_OPS(dev, &netdev_ethtool_ops); if (info->flags & (IS_DL10019|IS_DL10022)) { u_char id = inb(dev->base_addr + 0x1a); @@ -769,7 +770,6 @@ printk("PNA, "); } else { printk(KERN_INFO "%s: NE2000 Compatible: ", dev->name); - dev->do_ioctl = &do_ioctl_light; } printk("io %#3lx, irq %d,", dev->base_addr, dev->irq); if (info->flags & USE_SHMEM) @@ -1205,26 +1205,16 @@ /*====================================================================*/ -static int netdev_ethtool_ioctl(struct net_device *dev, void *useraddr) +static void netdev_get_drvinfo(struct net_device *dev, + struct ethtool_drvinfo *info) { - u32 ethcmd; - - if (copy_from_user(ðcmd, useraddr, sizeof(ethcmd))) - return -EFAULT; - - switch (ethcmd) { - case ETHTOOL_GDRVINFO: { - struct ethtool_drvinfo info = {ETHTOOL_GDRVINFO}; - strncpy(info.driver, "pcnet_cs", sizeof(info.driver)-1); - if (copy_to_user(useraddr, &info, sizeof(info))) - return -EFAULT; - return 0; - } - } - - return -EOPNOTSUPP; + strcpy(info->driver, "pcnet_cs"); } +static struct ethtool_ops netdev_ethtool_ops = { + .get_drvinfo = netdev_get_drvinfo, +}; + /*====================================================================*/ @@ -1234,31 +1224,18 @@ u16 *data = (u16 *)&rq->ifr_data; ioaddr_t mii_addr = dev->base_addr + DLINK_GPIO; switch (cmd) { - case SIOCETHTOOL: - return netdev_ethtool_ioctl(dev, (void *) rq->ifr_data); - case SIOCDEVPRIVATE: + case SIOCGMIIPHY: data[0] = info->phy_id; - case SIOCDEVPRIVATE+1: + case SIOCGMIIREG: /* Read MII PHY register. */ data[3] = mdio_read(mii_addr, data[0], data[1] & 0x1f); return 0; - case SIOCDEVPRIVATE+2: + case SIOCSMIIREG: /* Write MII PHY register. */ if (!capable(CAP_NET_ADMIN)) return -EPERM; mdio_write(mii_addr, data[0], data[1] & 0x1f, data[2]); return 0; } return -EOPNOTSUPP; -} - -/*====================================================================*/ - -static int do_ioctl_light(struct net_device *dev, struct ifreq *rq, int cmd) -{ - switch (cmd) { - case SIOCETHTOOL: - return netdev_ethtool_ioctl(dev, (void *) rq->ifr_data); - } - return -EOPNOTSUPP; } /*====================================================================*/ diff -Nru a/drivers/net/pcmcia/xirc2ps_cs.c b/drivers/net/pcmcia/xirc2ps_cs.c --- a/drivers/net/pcmcia/xirc2ps_cs.c Tue Sep 2 19:58:15 2003 +++ b/drivers/net/pcmcia/xirc2ps_cs.c Tue Sep 2 19:58:15 2003 @@ -382,6 +382,7 @@ static int do_config(struct net_device *dev, struct ifmap *map); static int do_open(struct net_device *dev); static int do_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); +static struct ethtool_ops netdev_ethtool_ops; static void hardreset(struct net_device *dev); static void do_reset(struct net_device *dev, int full); static int init_mii(struct net_device *dev); @@ -626,6 +627,7 @@ dev->set_config = &do_config; dev->get_stats = &do_get_stats; dev->do_ioctl = &do_ioctl; + SET_ETHTOOL_OPS(dev, &netdev_ethtool_ops); dev->set_multicast_list = &set_multicast_list; dev->open = &do_open; dev->stop = &do_stop; @@ -1699,26 +1701,16 @@ return 0; } -static int netdev_ethtool_ioctl(struct net_device *dev, void *useraddr) +static void netdev_get_drvinfo(struct net_device *dev, + struct ethtool_drvinfo *info) { - u32 ethcmd; - - if (copy_from_user(ðcmd, useraddr, sizeof(ethcmd))) - return -EFAULT; - - switch (ethcmd) { - case ETHTOOL_GDRVINFO: { - struct ethtool_drvinfo info = {ETHTOOL_GDRVINFO}; - strncpy(info.driver, "xirc2ps_cs", sizeof(info.driver)-1); - if (copy_to_user(useraddr, &info, sizeof(info))) - return -EFAULT; - return 0; - } - } - - return -EOPNOTSUPP; + strcpy(info->driver, "xirc2ps_cs"); } +static struct ethtool_ops netdev_ethtool_ops = { + .get_drvinfo = netdev_get_drvinfo, +}; + static int do_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) { @@ -1734,15 +1726,13 @@ return -EOPNOTSUPP; switch(cmd) { - case SIOCETHTOOL: - return netdev_ethtool_ioctl(dev, (void *) rq->ifr_data); - case SIOCDEVPRIVATE: /* Get the address of the PHY in use. */ + case SIOCGMIIPHY: /* Get the address of the PHY in use. */ data[0] = 0; /* we have only this address */ /* fall trough */ - case SIOCDEVPRIVATE+1: /* Read the specified MII register. */ + case SIOCGMIIREG: /* Read the specified MII register. */ data[3] = mii_rd(ioaddr, data[0] & 0x1f, data[1] & 0x1f); break; - case SIOCDEVPRIVATE+2: /* Write the specified MII register */ + case SIOCSMIIREG: /* Write the specified MII register */ if (!capable(CAP_NET_ADMIN)) return -EPERM; mii_wr(ioaddr, data[0] & 0x1f, data[1] & 0x1f, data[2], 16); diff -Nru a/drivers/net/pcnet32.c b/drivers/net/pcnet32.c --- a/drivers/net/pcnet32.c Tue Sep 2 19:58:14 2003 +++ b/drivers/net/pcnet32.c Tue Sep 2 19:58:14 2003 @@ -1726,6 +1726,7 @@ /* An additional parameter that may be passed in... */ static int debug = -1; static int tx_start_pt = -1; +static int pcnet32_have_pci; static int __init pcnet32_init_module(void) { @@ -1738,7 +1739,8 @@ tx_start = tx_start_pt; /* find the PCI devices */ - pci_module_init(&pcnet32_driver); + if (!pci_module_init(&pcnet32_driver)) + pcnet32_have_pci = 1; /* should we find any remaining VLbus devices ? */ if (pcnet32vlb) @@ -1747,7 +1749,7 @@ if (cards_found) printk(KERN_INFO PFX "%d cards_found.\n", cards_found); - return cards_found ? 0 : -ENODEV; + return (pcnet32_have_pci + cards_found) ? 0 : -ENODEV; } static void __exit pcnet32_cleanup_module(void) @@ -1765,6 +1767,9 @@ free_netdev(pcnet32_dev); pcnet32_dev = next_dev; } + + if (pcnet32_have_pci) + pci_unregister_driver(&pcnet32_driver); } module_init(pcnet32_init_module); diff -Nru a/drivers/net/seeq8005.c b/drivers/net/seeq8005.c --- a/drivers/net/seeq8005.c Tue Sep 2 19:58:18 2003 +++ b/drivers/net/seeq8005.c Tue Sep 2 19:58:18 2003 @@ -378,7 +378,7 @@ { struct net_local *lp = (struct net_local *)dev->priv; short length = skb->len; - unsigned char *buf = skb->data; + unsigned char *buf; if (length < ETH_ZLEN) { skb = skb_padto(skb, ETH_ZLEN); @@ -386,6 +386,8 @@ return 0; length = ETH_ZLEN; } + buf = skb->data; + /* Block a timer-based transmit from overlapping */ netif_stop_queue(dev); diff -Nru a/drivers/net/sis190.c b/drivers/net/sis190.c --- a/drivers/net/sis190.c Tue Sep 2 19:58:20 2003 +++ b/drivers/net/sis190.c Tue Sep 2 19:58:20 2003 @@ -76,6 +76,8 @@ #define NUM_TX_DESC 64 /* Number of Tx descriptor registers */ #define NUM_RX_DESC 64 /* Number of Rx descriptor registers */ +#define TX_DESC_TOTAL_SIZE (NUM_TX_DESC * sizeof (struct TxDesc)) +#define RX_DESC_TOTAL_SIZE (NUM_RX_DESC * sizeof (struct RxDesc)) #define RX_BUF_SIZE 1536 /* Rx Buffer size */ #define SiS190_MIN_IO_SIZE 0x80 @@ -311,12 +313,8 @@ unsigned long cur_rx; /* Index into the Rx descriptor buffer of next Rx pkt. */ unsigned long cur_tx; /* Index into the Tx descriptor buffer of next Rx pkt. */ unsigned long dirty_tx; - void *tx_desc_raw; /* Tx descriptor buffer */ - dma_addr_t tx_dma_raw; - dma_addr_t tx_dma_aligned; - void *rx_desc_raw; /* Rx descriptor buffer */ - dma_addr_t rx_dma_raw; - dma_addr_t rx_dma_aligned; + dma_addr_t tx_dma; + dma_addr_t rx_dma; struct TxDesc *TxDescArray; /* Index of 256-alignment Tx Descriptor buffer */ struct RxDesc *RxDescArray; /* Index of 256-alignment Rx Descriptor buffer */ unsigned char *RxBufferRings; /* Index of Rx Buffer */ @@ -470,6 +468,10 @@ if (rc) goto err_out; + rc = pci_set_dma_mask(pdev, 0xffffffffULL); + if (rc) + goto err_out; + mmio_start = pci_resource_start(pdev, 0); mmio_end = pci_resource_end(pdev, 0); mmio_flags = pci_resource_flags(pdev, 0); @@ -521,7 +523,6 @@ err_out: pci_disable_device(pdev); - unregister_netdev(dev); kfree(dev); return rc; } @@ -536,6 +537,7 @@ static int printed_version = 0; int i, rc; u16 reg31; + int val; assert(pdev != NULL); assert(ent != NULL); @@ -620,7 +622,7 @@ dev->dev_addr[2], dev->dev_addr[3], dev->dev_addr[4], dev->dev_addr[5], dev->irq); - int val = smdio_read(ioaddr, PHY_AUTO_NEGO_REG); + val = smdio_read(ioaddr, PHY_AUTO_NEGO_REG); printk(KERN_INFO "%s: Auto-negotiation Enabled.\n", dev->name); @@ -714,54 +716,50 @@ SiS190_open(struct net_device *dev) { struct sis190_private *tp = dev->priv; - int retval; - u8 diff; int rc; - retval = - request_irq(dev->irq, SiS190_interrupt, SA_SHIRQ, dev->name, dev); - if (retval) { - return retval; - } + rc = request_irq(dev->irq, SiS190_interrupt, SA_SHIRQ, dev->name, dev); + if (rc) + goto out; - tp->tx_desc_raw = pci_alloc_consistent(tp->pci_dev, - (NUM_TX_DESC * sizeof (struct TxDesc)) + 256, - &tp->tx_dma_raw); - if (!tp->tx_desc_raw) { + /* + * Rx and Tx descriptors need 256 bytes alignment. + * pci_alloc_consistent() guarantees a stronger alignment. + */ + tp->TxDescArray = pci_alloc_consistent(tp->pci_dev, TX_DESC_TOTAL_SIZE, + &tp->tx_dma); + if (!tp->TxDescArray) { rc = -ENOMEM; goto err_out; } - // Tx Desscriptor needs 256 bytes alignment; - diff = 256 - (tp->tx_dma_raw - ((tp->tx_dma_raw >> 8) << 8)); - tp->tx_dma_aligned = tp->tx_dma_raw + diff; - tp->TxDescArray = (struct TxDesc *) (tp->tx_desc_raw + diff); - - tp->rx_desc_raw = pci_alloc_consistent(tp->pci_dev, - (NUM_RX_DESC * sizeof (struct RxDesc)) + 256, - &tp->rx_dma_raw); - if (!tp->rx_desc_raw) { + + tp->RxDescArray = pci_alloc_consistent(tp->pci_dev, RX_DESC_TOTAL_SIZE, + &tp->rx_dma); + if (!tp->RxDescArray) { rc = -ENOMEM; goto err_out_free_tx; } - // Rx Desscriptor needs 256 bytes alignment; - diff = 256 - (tp->rx_dma_raw - ((tp->rx_dma_raw >> 8) << 8)); - tp->rx_dma_aligned = tp->rx_dma_raw + diff; - tp->RxDescArray = (struct RxDesc *) (tp->rx_desc_raw + diff); tp->RxBufferRings = kmalloc(RX_BUF_SIZE * NUM_RX_DESC, GFP_KERNEL); if (tp->RxBufferRings == NULL) { - printk(KERN_INFO "Allocate RxBufferRing failed\n"); + printk(KERN_INFO "%s: allocate RxBufferRing failed\n", + dev->name); + rc = -ENOMEM; + goto err_out_free_rx; } SiS190_init_ring(dev); SiS190_hw_start(dev); - return 0; +out: + return rc; +err_out_free_rx: + pci_free_consistent(tp->pci_dev, RX_DESC_TOTAL_SIZE, tp->RxDescArray, + tp->rx_dma); err_out_free_tx: - pci_free_consistent(tp->pci_dev, - (NUM_TX_DESC * sizeof (struct TxDesc)) + 256, - tp->tx_desc_raw, tp->tx_dma_raw); + pci_free_consistent(tp->pci_dev, TX_DESC_TOTAL_SIZE, tp->TxDescArray, + tp->tx_dma); err_out: free_irq(dev->irq, dev); return rc; @@ -780,10 +778,10 @@ SiS_W32(IntrControl, 0x0); SiS_W32(0x0, 0x01a00); - SiS_W32(0x4, tp->tx_dma_aligned); + SiS_W32(0x4, tp->tx_dma); SiS_W32(0x10, 0x1a00); - SiS_W32(0x14, tp->rx_dma_aligned); + SiS_W32(0x14, tp->rx_dma); SiS_W32(0x20, 0xffffffff); SiS_W32(0x24, 0x0); @@ -830,19 +828,19 @@ tp->Tx_skbuff[i] = NULL; } for (i = 0; i < NUM_RX_DESC; i++) { + struct RxDesc *desc = tp->RxDescArray + i; - tp->RxDescArray[i].PSize = 0x0; + desc->PSize = 0x0; if (i == (NUM_RX_DESC - 1)) - tp->RxDescArray[i].buf_Len = BIT_31 + RX_BUF_SIZE; //bit 31 is End bit + desc->buf_Len = BIT_31 + RX_BUF_SIZE; //bit 31 is End bit else - tp->RxDescArray[i].buf_Len = RX_BUF_SIZE; - -#warning Replace virt_to_bus with DMA mapping - tp->RxBufferRing[i] = &(tp->RxBufferRings[i * RX_BUF_SIZE]); - tp->RxDescArray[i].buf_addr = virt_to_bus(tp->RxBufferRing[i]); - tp->RxDescArray[i].status = OWNbit | INTbit; + desc->buf_Len = RX_BUF_SIZE; + tp->RxBufferRing[i] = tp->RxBufferRings + i * RX_BUF_SIZE; + desc->buf_addr = pci_map_single(tp->pci_dev, + tp->RxBufferRing[i], RX_BUF_SIZE, PCI_DMA_FROMDEVICE); + desc->status = OWNbit | INTbit; } } @@ -855,7 +853,14 @@ tp->cur_tx = 0; for (i = 0; i < NUM_TX_DESC; i++) { if (tp->Tx_skbuff[i] != NULL) { - dev_kfree_skb(tp->Tx_skbuff[i]); + struct sk_buff *skb; + + skb = tp->Tx_skbuff[i]; + pci_unmap_single(tp->pci_dev, + le32_to_cpu(tp->TxDescArray[i].buf_addr), + skb->len < ETH_ZLEN ? ETH_ZLEN : skb->len, + PCI_DMA_TODEVICE); + dev_kfree_skb(skb); tp->Tx_skbuff[i] = NULL; tp->stats.tx_dropped++; } @@ -894,46 +899,58 @@ struct sis190_private *tp = dev->priv; void *ioaddr = tp->mmio_addr; int entry = tp->cur_tx % NUM_TX_DESC; + u32 len; - if (skb->len < ETH_ZLEN) { + if (unlikely(skb->len < ETH_ZLEN)) { skb = skb_padto(skb, ETH_ZLEN); if (skb == NULL) - return 0; + goto drop_tx; + len = ETH_ZLEN; + } else { + len = skb->len; } spin_lock_irq(&tp->lock); - if ((tp->TxDescArray[entry].status & OWNbit) == 0) { -#warning Replace virt_to_bus with DMA mapping + if ((le32_to_cpu(tp->TxDescArray[entry].status) & OWNbit) == 0) { + dma_addr_t mapping; + + mapping = pci_map_single(tp->pci_dev, skb->data, len, + PCI_DMA_TODEVICE); + tp->Tx_skbuff[entry] = skb; - tp->TxDescArray[entry].buf_addr = virt_to_bus(skb->data); - tp->TxDescArray[entry].PSize = - ((skb->len > ETH_ZLEN) ? skb->len : ETH_ZLEN); + tp->TxDescArray[entry].buf_addr = cpu_to_le32(mapping); + tp->TxDescArray[entry].PSize = cpu_to_le32(len); - if (entry != (NUM_TX_DESC - 1)) { - tp->TxDescArray[entry].buf_Len = - tp->TxDescArray[entry].PSize; - } else { + if (entry != (NUM_TX_DESC - 1)) + tp->TxDescArray[entry].buf_Len = cpu_to_le32(len); + else tp->TxDescArray[entry].buf_Len = - tp->TxDescArray[entry].PSize | ENDbit; - } + cpu_to_le32(len | ENDbit); tp->TxDescArray[entry].status |= - (OWNbit | INTbit | DEFbit | CRCbit | PADbit); + cpu_to_le32(OWNbit | INTbit | DEFbit | CRCbit | PADbit); SiS_W32(TxControl, 0x1a11); //Start Send dev->trans_start = jiffies; tp->cur_tx++; + } else { + spin_unlock_irq(&tp->lock); + goto drop_tx; } + if ((tp->cur_tx - NUM_TX_DESC) == tp->dirty_tx) + netif_stop_queue(dev); + spin_unlock_irq(&tp->lock); - if ((tp->cur_tx - NUM_TX_DESC) == tp->dirty_tx) { - netif_stop_queue(dev); - } + return 0; +drop_tx: + tp->stats.tx_dropped++; + dev_kfree_skb(skb); return 0; } @@ -952,10 +969,18 @@ tx_left = tp->cur_tx - dirty_tx; while (tx_left > 0) { - if ((tp->TxDescArray[entry].status & OWNbit) == 0) { - dev_kfree_skb_irq(tp-> - Tx_skbuff[dirty_tx % NUM_TX_DESC]); - tp->Tx_skbuff[dirty_tx % NUM_TX_DESC] = NULL; + if ((le32_to_cpu(tp->TxDescArray[entry].status) & OWNbit) == 0) { + struct sk_buff *skb; + + skb = tp->Tx_skbuff[entry]; + + pci_unmap_single(tp->pci_dev, + le32_to_cpu(tp->TxDescArray[entry].buf_addr), + skb->len < ETH_ZLEN ? ETH_ZLEN : skb->len, + PCI_DMA_TODEVICE); + + dev_kfree_skb_irq(skb); + tp->Tx_skbuff[entry] = NULL; tp->stats.tx_packets++; dirty_tx++; tx_left--; @@ -965,8 +990,7 @@ if (tp->dirty_tx != dirty_tx) { tp->dirty_tx = dirty_tx; - if (netif_queue_stopped(dev)) - netif_wake_queue(dev); + netif_wake_queue(dev); } } @@ -974,29 +998,30 @@ SiS190_rx_interrupt(struct net_device *dev, struct sis190_private *tp, void *ioaddr) { - int cur_rx; - struct sk_buff *skb; - int pkt_size = 0; + int cur_rx = tp->cur_rx; + struct RxDesc *desc = tp->RxDescArray + cur_rx; assert(dev != NULL); assert(tp != NULL); assert(ioaddr != NULL); - cur_rx = tp->cur_rx; - while ((tp->RxDescArray[cur_rx].status & OWNbit) == 0) { + while ((desc->status & OWNbit) == 0) { - if (tp->RxDescArray[cur_rx].PSize & 0x0080000) { + if (desc->PSize & 0x0080000) { printk(KERN_INFO "%s: Rx ERROR!!!\n", dev->name); tp->stats.rx_errors++; tp->stats.rx_length_errors++; - } else if (!(tp->RxDescArray[cur_rx].PSize & 0x0010000)) { + } else if (!(desc->PSize & 0x0010000)) { printk(KERN_INFO "%s: Rx ERROR!!!\n", dev->name); tp->stats.rx_errors++; tp->stats.rx_crc_errors++; } else { - pkt_size = - (int) (tp->RxDescArray[cur_rx]. - PSize & 0x0000FFFF) - 4; + struct sk_buff *skb; + int pkt_size; + + pkt_size = (int) (desc->PSize & 0x0000FFFF) - 4; + pci_dma_sync_single(tp->pci_dev, desc->buf_addr, + RX_BUF_SIZE, PCI_DMA_FROMDEVICE); skb = dev_alloc_skb(pkt_size + 2); if (skb != NULL) { skb->dev = dev; @@ -1007,24 +1032,18 @@ skb->protocol = eth_type_trans(skb, dev); netif_rx(skb); - tp->RxDescArray[cur_rx].PSize = 0x0; + desc->PSize = 0x0; if (cur_rx == (NUM_RX_DESC - 1)) - tp->RxDescArray[cur_rx].buf_Len = - ENDbit + RX_BUF_SIZE; + desc->buf_Len = ENDbit + RX_BUF_SIZE; else - tp->RxDescArray[cur_rx].buf_Len = - RX_BUF_SIZE; + desc->buf_Len = RX_BUF_SIZE; -#warning Replace virt_to_bus with DMA mapping - tp->RxDescArray[cur_rx].buf_addr = - virt_to_bus(tp->RxBufferRing[cur_rx]); dev->last_rx = jiffies; tp->stats.rx_bytes += pkt_size; tp->stats.rx_packets++; - tp->RxDescArray[cur_rx].status = - OWNbit | INTbit; + desc->status = OWNbit | INTbit; } else { printk(KERN_WARNING "%s: Memory squeeze, deferring packet.\n", @@ -1036,7 +1055,7 @@ } cur_rx = (cur_rx + 1) % NUM_RX_DESC; - + desc = tp->RxDescArray + cur_rx; } tp->cur_rx = cur_rx; @@ -1111,22 +1130,22 @@ spin_unlock_irq(&tp->lock); - synchronize_irq(); + synchronize_irq(dev->irq); free_irq(dev->irq, dev); SiS190_tx_clear(tp); - pci_free_consistent(tp->pci_dev, - (NUM_TX_DESC * sizeof (struct TxDesc)) + 256, - tp->tx_desc_raw, tp->tx_dma_raw); - pci_free_consistent(tp->pci_dev, - (NUM_RX_DESC * sizeof (struct RxDesc)) + 256, - tp->rx_desc_raw, tp->rx_dma_raw); + pci_free_consistent(tp->pci_dev, TX_DESC_TOTAL_SIZE, tp->TxDescArray, + tp->tx_dma); + pci_free_consistent(tp->pci_dev, RX_DESC_TOTAL_SIZE, tp->RxDescArray, + tp->rx_dma); tp->TxDescArray = NULL; - tp->RxDescArray = NULL; - kfree(tp->RxBufferRings); for (i = 0; i < NUM_RX_DESC; i++) { + pci_unmap_single(tp->pci_dev, tp->RxDescArray[i].buf_addr, + RX_BUF_SIZE, PCI_DMA_FROMDEVICE); tp->RxBufferRing[i] = NULL; } + tp->RxDescArray = NULL; + kfree(tp->RxBufferRings); return 0; } diff -Nru a/drivers/net/sis900.c b/drivers/net/sis900.c --- a/drivers/net/sis900.c Tue Sep 2 19:58:15 2003 +++ b/drivers/net/sis900.c Tue Sep 2 19:58:15 2003 @@ -169,6 +169,7 @@ dma_addr_t rx_ring_dma; unsigned int tx_full; /* The Tx queue is full. */ + u8 host_bridge_rev; }; MODULE_AUTHOR("Jim Huang , Ollie Lho "); @@ -210,6 +211,7 @@ static u16 sis900_reset_phy(struct net_device *net_dev, int phy_addr); static void sis900_auto_negotiate(struct net_device *net_dev, int phy_addr); static void sis900_set_mode (long ioaddr, int speed, int duplex); +static struct ethtool_ops sis900_ethtool_ops; /** * sis900_get_mac_addr - Get MAC address for stand alone SiS900 model @@ -367,6 +369,7 @@ { struct sis900_private *sis_priv; struct net_device *net_dev; + struct pci_dev *dev; dma_addr_t ring_dma; void *ring_space; long ioaddr; @@ -440,6 +443,7 @@ net_dev->do_ioctl = &mii_ioctl; net_dev->tx_timeout = sis900_tx_timeout; net_dev->watchdog_timeo = TX_TIMEOUT; + net_dev->ethtool_ops = &sis900_ethtool_ops; ret = register_netdev(net_dev); if (ret) @@ -473,6 +477,11 @@ goto err_out_unregister; } + /* save our host bridge revision */ + dev = pci_find_device(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_630, NULL); + if (dev) + pci_read_config_byte(dev, PCI_CLASS_REVISION, &sis_priv->host_bridge_rev); + /* print some information about our NIC */ printk(KERN_INFO "%s: %s at %#lx, IRQ %d, ", net_dev->name, card_name, ioaddr, net_dev->irq); @@ -1108,18 +1117,12 @@ { struct sis900_private *sis_priv = net_dev->priv; u16 reg14h, eq_value=0, max_value=0, min_value=0; - u8 host_bridge_rev; int i, maxcount=10; - struct pci_dev *dev=NULL; if ( !(revision == SIS630E_900_REV || revision == SIS630EA1_900_REV || revision == SIS630A_900_REV || revision == SIS630ET_900_REV) ) return; - dev = pci_find_device(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_630, dev); - if (dev) - pci_read_config_byte(dev, PCI_CLASS_REVISION, &host_bridge_rev); - if (netif_carrier_ok(net_dev)) { reg14h=mdio_read(net_dev, sis_priv->cur_phy, MII_RESV); mdio_write(net_dev, sis_priv->cur_phy, MII_RESV, (0x2200 | reg14h) & 0xBFFF); @@ -1142,7 +1145,8 @@ } /* 630B0&B1 rule to determine the equalizer value */ if (revision == SIS630A_900_REV && - (host_bridge_rev == SIS630B0 || host_bridge_rev == SIS630B1)) { + (sis_priv->host_bridge_rev == SIS630B0 || + sis_priv->host_bridge_rev == SIS630B1)) { if (max_value == 0) eq_value=3; else @@ -1157,7 +1161,8 @@ else { reg14h=mdio_read(net_dev, sis_priv->cur_phy, MII_RESV); if (revision == SIS630A_900_REV && - (host_bridge_rev == SIS630B0 || host_bridge_rev == SIS630B1)) + (sis_priv->host_bridge_rev == SIS630B0 || + sis_priv->host_bridge_rev == SIS630B1)) mdio_write(net_dev, sis_priv->cur_phy, MII_RESV, (reg14h | 0x2200) & 0xBFFF); else mdio_write(net_dev, sis_priv->cur_phy, MII_RESV, (reg14h | 0x2000) & 0xBFFF); @@ -1853,39 +1858,27 @@ } /** - * netdev_ethtool_ioctl - For the basic support of ethtool - * @net_dev: the net device to command for - * @useraddr: start address of interface request + * sis900_get_drvinfo - Return information about driver + * @net_dev: the net device to probe + * @info: container for info returned * * Process ethtool command such as "ehtool -i" to show information */ - -static int netdev_ethtool_ioctl (struct net_device *net_dev, void *useraddr) + +static void sis900_get_drvinfo(struct net_device *net_dev, + struct ethtool_drvinfo *info) { struct sis900_private *sis_priv = net_dev->priv; - u32 ethcmd; - if (copy_from_user (ðcmd, useraddr, sizeof (ethcmd))) - return -EFAULT; - - switch (ethcmd) { - case ETHTOOL_GDRVINFO: - { - struct ethtool_drvinfo info = { ETHTOOL_GDRVINFO }; - strcpy (info.driver, SIS900_MODULE_NAME); - strcpy (info.version, SIS900_DRV_VERSION); - strcpy (info.bus_info, pci_name(sis_priv->pci_dev)); - if (copy_to_user (useraddr, &info, sizeof (info))) - return -EFAULT; - return 0; - } - default: - break; - } - - return -EOPNOTSUPP; + strcpy (info->driver, SIS900_MODULE_NAME); + strcpy (info->version, SIS900_DRV_VERSION); + strcpy (info->bus_info, pci_name(sis_priv->pci_dev)); } +static struct ethtool_ops sis900_ethtool_ops = { + .get_drvinfo = sis900_get_drvinfo, +}; + /** * mii_ioctl - process MII i/o control command * @net_dev: the net device to command for @@ -1901,9 +1894,6 @@ struct mii_ioctl_data *data = (struct mii_ioctl_data *)&rq->ifr_data; switch(cmd) { - case SIOCETHTOOL: - return netdev_ethtool_ioctl(net_dev, (void *) rq->ifr_data); - case SIOCGMIIPHY: /* Get address of MII PHY in use. */ data->phy_id = sis_priv->mii->phy_addr; /* Fall Through */ diff -Nru a/drivers/net/sk_mca.c b/drivers/net/sk_mca.c --- a/drivers/net/sk_mca.c Tue Sep 2 19:58:17 2003 +++ b/drivers/net/sk_mca.c Tue Sep 2 19:58:17 2003 @@ -124,7 +124,7 @@ /* dump parts of shared memory - only needed during debugging */ #ifdef DEBUG -static void dumpmem(struct SKMCA_NETDEV *dev, u32 start, u32 len) +static void dumpmem(struct net_device *dev, u32 start, u32 len) { int z; @@ -217,7 +217,7 @@ /* reset the whole board */ -static void ResetBoard(struct SKMCA_NETDEV *dev) +static void ResetBoard(struct net_device *dev) { skmca_priv *priv = (skmca_priv *) dev->priv; @@ -228,7 +228,7 @@ /* wait for LANCE interface to become not busy */ -static int WaitLANCE(struct SKMCA_NETDEV *dev) +static int WaitLANCE(struct net_device *dev) { skmca_priv *priv = (skmca_priv *) dev->priv; int t = 0; @@ -247,7 +247,7 @@ /* set LANCE register - must be atomic */ -static void SetLANCE(struct SKMCA_NETDEV *dev, u16 addr, u16 value) +static void SetLANCE(struct net_device *dev, u16 addr, u16 value) { skmca_priv *priv = (skmca_priv *) dev->priv; unsigned long flags; @@ -280,12 +280,12 @@ /* reenable interrupts */ - spin_lock_irqrestore(&priv->lock, flags); + spin_unlock_irqrestore(&priv->lock, flags); } /* get LANCE register */ -static u16 GetLANCE(struct SKMCA_NETDEV *dev, u16 addr) +static u16 GetLANCE(struct net_device *dev, u16 addr) { skmca_priv *priv = (skmca_priv *) dev->priv; unsigned long flags; @@ -319,14 +319,14 @@ /* reenable interrupts */ - spin_lock_irqrestore(&priv->lock, flags); + spin_unlock_irqrestore(&priv->lock, flags); return res; } /* build up descriptors in shared RAM */ -static void InitDscrs(struct SKMCA_NETDEV *dev) +static void InitDscrs(struct net_device *dev) { u32 bufaddr; @@ -422,7 +422,7 @@ /* feed ready-built initialization block into LANCE */ -static void InitLANCE(struct SKMCA_NETDEV *dev) +static void InitLANCE(struct net_device *dev) { skmca_priv *priv = (skmca_priv *) dev->priv; @@ -452,11 +452,7 @@ /* we don't get ready until the LANCE has read the init block */ -#if (LINUX_VERSION_CODE >= 0x02032a) netif_stop_queue(dev); -#else - dev->tbusy = 1; -#endif /* let LANCE read the initialization block. LANCE is ready when we receive the corresponding interrupt. */ @@ -466,15 +462,11 @@ /* stop the LANCE so we can reinitialize it */ -static void StopLANCE(struct SKMCA_NETDEV *dev) +static void StopLANCE(struct net_device *dev) { /* can't take frames any more */ -#if (LINUX_VERSION_CODE >= 0x02032a) netif_stop_queue(dev); -#else - dev->tbusy = 1; -#endif /* disable interrupts, stop it */ @@ -483,7 +475,7 @@ /* initialize card and LANCE for proper operation */ -static void InitBoard(struct SKMCA_NETDEV *dev) +static void InitBoard(struct net_device *dev) { LANCE_InitBlock block; @@ -508,7 +500,7 @@ /* deinitialize card and LANCE */ -static void DeinitBoard(struct SKMCA_NETDEV *dev) +static void DeinitBoard(struct net_device *dev) { /* stop LANCE */ @@ -521,7 +513,7 @@ /* probe for device's irq */ -static int __init ProbeIRQ(struct SKMCA_NETDEV *dev) +static int __init ProbeIRQ(struct net_device *dev) { unsigned long imaskval, njiffies, irq; u16 csr0val; @@ -563,15 +555,11 @@ /* LANCE has read initialization block -> start it */ -static u16 irqstart_handler(struct SKMCA_NETDEV *dev, u16 oldcsr0) +static u16 irqstart_handler(struct net_device *dev, u16 oldcsr0) { /* now we're ready to transmit */ -#if (LINUX_VERSION_CODE >= 0x02032a) netif_wake_queue(dev); -#else - dev->tbusy = 0; -#endif /* reset IDON bit, start LANCE */ @@ -581,7 +569,7 @@ /* did we lose blocks due to a FIFO overrun ? */ -static u16 irqmiss_handler(struct SKMCA_NETDEV *dev, u16 oldcsr0) +static u16 irqmiss_handler(struct net_device *dev, u16 oldcsr0) { skmca_priv *priv = (skmca_priv *) dev->priv; @@ -597,7 +585,7 @@ /* receive interrupt */ -static u16 irqrx_handler(struct SKMCA_NETDEV *dev, u16 oldcsr0) +static u16 irqrx_handler(struct net_device *dev, u16 oldcsr0) { skmca_priv *priv = (skmca_priv *) dev->priv; LANCE_RxDescr descr; @@ -678,7 +666,7 @@ /* transmit interrupt */ -static u16 irqtx_handler(struct SKMCA_NETDEV *dev, u16 oldcsr0) +static u16 irqtx_handler(struct net_device *dev, u16 oldcsr0) { skmca_priv *priv = (skmca_priv *) dev->priv; LANCE_TxDescr descr; @@ -740,12 +728,7 @@ a new one */ /* inform upper layers we're in business again */ -#if (LINUX_VERSION_CODE >= 0x02032a) netif_wake_queue(dev); -#else - dev->tbusy = 0; - mark_bh(NET_BH); -#endif return oldcsr0; } @@ -754,7 +737,7 @@ static irqreturn_t irq_handler(int irq, void *device, struct pt_regs *regs) { - struct SKMCA_NETDEV *dev = (struct SKMCA_NETDEV *) device; + struct net_device *dev = (struct net_device *) device; u16 csr0val; /* read CSR0 to get interrupt cause */ @@ -766,13 +749,9 @@ if ((csr0val & CSR0_INTR) == 0) return IRQ_NONE; -#if (LINUX_VERSION_CODE >= 0x02032a) #if 0 set_bit(LINK_STATE_RXSEM, &dev->state); #endif -#else - dev->interrupt = 1; -#endif /* loop through the interrupt bits until everything is clear */ @@ -796,13 +775,9 @@ } while ((csr0val & CSR0_INTR) != 0); -#if (LINUX_VERSION_CODE >= 0x02032a) #if 0 clear_bit(LINK_STATE_RXSEM, &dev->state); #endif -#else - dev->interrupt = 0; -#endif return IRQ_HANDLED; } @@ -815,7 +790,7 @@ static int skmca_getinfo(char *buf, int slot, void *d) { int len = 0, i; - struct SKMCA_NETDEV *dev = (struct SKMCA_NETDEV *) d; + struct net_device *dev = (struct net_device *) d; skmca_priv *priv; /* can't say anything about an uninitialized device... */ @@ -846,7 +821,7 @@ /* open driver. Means also initialization and start of LANCE */ -static int skmca_open(struct SKMCA_NETDEV *dev) +static int skmca_open(struct net_device *dev) { int result; skmca_priv *priv = (skmca_priv *) dev->priv; @@ -868,21 +843,14 @@ /* set up flags */ -#if (LINUX_VERSION_CODE >= 0x02032a) netif_start_queue(dev); -#else - dev->interrupt = 0; - dev->tbusy = 0; - dev->start = 0; - MOD_INC_USE_COUNT; -#endif return 0; } /* close driver. Shut down board and free allocated resources */ -static int skmca_close(struct SKMCA_NETDEV *dev) +static int skmca_close(struct net_device *dev) { /* turn off board */ DeinitBoard(dev); @@ -892,16 +860,12 @@ free_irq(dev->irq, dev); dev->irq = 0; -#if (LINUX_VERSION_CODE < 0x02032a) - MOD_DEC_USE_COUNT; -#endif - return 0; } /* transmit a block. */ -static int skmca_tx(struct sk_buff *skb, struct SKMCA_NETDEV *dev) +static int skmca_tx(struct sk_buff *skb, struct net_device *dev) { skmca_priv *priv = (skmca_priv *) dev->priv; LANCE_TxDescr descr; @@ -977,11 +941,7 @@ /* are we saturated ? */ if (priv->txbusy >= TXCOUNT) -#if (LINUX_VERSION_CODE >= 0x02032a) netif_stop_queue(dev); -#else - dev->tbusy = 1; -#endif /* write descriptor back to RAM */ SKMCA_TOIO(dev->mem_start + address, &descr, @@ -993,7 +953,7 @@ if (priv->txbusy == 0) SetLANCE(dev, LANCE_CSR0, CSR0_INEA | CSR0_TDMD); - spin_lock_irqrestore(&priv->lock, flags); + spin_unlock_irqrestore(&priv->lock, flags); tx_done: @@ -1004,7 +964,7 @@ /* return pointer to Ethernet statistics */ -static struct net_device_stats *skmca_stats(struct SKMCA_NETDEV *dev) +static struct net_device_stats *skmca_stats(struct net_device *dev) { skmca_priv *priv = (skmca_priv *) dev->priv; @@ -1014,7 +974,7 @@ /* we don't support runtime reconfiguration, since an MCA card can be unambigously identified by its POS registers. */ -static int skmca_config(struct SKMCA_NETDEV *dev, struct ifmap *map) +static int skmca_config(struct net_device *dev, struct ifmap *map) { return 0; } @@ -1022,7 +982,7 @@ /* switch receiver mode. We use the LANCE's multicast filter to prefilter multicast addresses. */ -static void skmca_set_multicast_list(struct SKMCA_NETDEV *dev) +static void skmca_set_multicast_list(struct net_device *dev) { LANCE_InitBlock block; @@ -1062,7 +1022,7 @@ static int startslot; /* counts through slots when probing multiple devices */ -int __init skmca_probe(struct SKMCA_NETDEV *dev) +int __init skmca_probe(struct net_device *dev) { int force_detect = 0; int junior, slot, i; @@ -1095,14 +1055,12 @@ getaddrs(slot, junior, &base, &irq, &medium); -#if LINUX_VERSION_CODE >= 0x020300 /* slot already in use ? */ if (mca_is_adapter_used(slot)) { slot = dofind(&junior, slot + 1); continue; } -#endif /* were we looking for something different ? */ @@ -1221,24 +1179,13 @@ #define DEVMAX 5 -#if (LINUX_VERSION_CODE >= 0x020369) -static struct SKMCA_NETDEV moddevs[DEVMAX] = - { {" ", 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, skmca_probe}, -{" ", 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, skmca_probe}, -{" ", 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, skmca_probe}, -{" ", 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, skmca_probe}, -{" ", 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, skmca_probe} -}; -#else -static char NameSpace[8 * DEVMAX]; -static struct SKMCA_NETDEV moddevs[DEVMAX] = - { {NameSpace + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, skmca_probe}, -{NameSpace + 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, skmca_probe}, -{NameSpace + 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, skmca_probe}, -{NameSpace + 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, skmca_probe}, -{NameSpace + 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, skmca_probe} +static struct net_device moddevs[DEVMAX] = { + { .name = " ", .init = skmca_probe }, + { .name = " ", .init = skmca_probe }, + { .name = " ", .init = skmca_probe }, + { .name = " ", .init = skmca_probe }, + { .name = " ", .init = skmca_probe } }; -#endif int irq; int io; @@ -1260,7 +1207,7 @@ void cleanup_module(void) { - struct SKMCA_NETDEV *dev; + struct net_device *dev; skmca_priv *priv; int z; diff -Nru a/drivers/net/sk_mca.h b/drivers/net/sk_mca.h --- a/drivers/net/sk_mca.h Tue Sep 2 19:58:16 2003 +++ b/drivers/net/sk_mca.h Tue Sep 2 19:58:16 2003 @@ -5,7 +5,6 @@ /* version-dependent functions/structures */ -#if LINUX_VERSION_CODE >= 0x020318 #define SKMCA_READB(addr) isa_readb(addr) #define SKMCA_READW(addr) isa_readw(addr) #define SKMCA_WRITEB(data, addr) isa_writeb(data, addr) @@ -13,17 +12,6 @@ #define SKMCA_TOIO(dest, src, len) isa_memcpy_toio(dest, src, len) #define SKMCA_FROMIO(dest, src, len) isa_memcpy_fromio(dest, src, len) #define SKMCA_SETIO(dest, val, len) isa_memset_io(dest, val, len) -#define SKMCA_NETDEV net_device -#else -#define SKMCA_READB(addr) readb(addr) -#define SKMCA_READW(addr) readw(addr) -#define SKMCA_WRITEB(data, addr) writeb(data, addr) -#define SKMCA_WRITEW(data, addr) writew(data, addr) -#define SKMCA_TOIO(dest, src, len) memcpy_toio(dest, src, len) -#define SKMCA_FROMIO(dest, src, len) memcpy_fromio(dest, src, len) -#define SKMCA_SETIO(dest, val, len) memset_io(dest, val, len) -#define SKMCA_NETDEV device -#endif /* Adapter ID's */ #define SKNET_MCA_ID 0x6afd @@ -188,7 +176,7 @@ #endif /* _SK_MCA_DRIVER_ */ -extern int skmca_probe(struct SKMCA_NETDEV *); +extern int skmca_probe(struct net_device *); #endif /* _SK_MCA_INCLUDE_ */ diff -Nru a/drivers/net/sunbmac.c b/drivers/net/sunbmac.c --- a/drivers/net/sunbmac.c Tue Sep 2 19:58:16 2003 +++ b/drivers/net/sunbmac.c Tue Sep 2 19:58:16 2003 @@ -1,7 +1,7 @@ /* $Id: sunbmac.c,v 1.30 2002/01/15 06:48:55 davem Exp $ * sunbmac.c: Driver for Sparc BigMAC 100baseT ethernet adapters. * - * Copyright (C) 1997, 1998, 1999 David S. Miller (davem@redhat.com) + * Copyright (C) 1997, 1998, 1999, 2003 David S. Miller (davem@redhat.com) */ #include @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #include @@ -37,7 +38,7 @@ #include "sunbmac.h" static char version[] __initdata = - "sunbmac.c:v1.9 11/Sep/99 David S. Miller (davem@redhat.com)\n"; + "sunbmac.c:v2.0 24/Nov/03 David S. Miller (davem@redhat.com)\n"; #undef DEBUG_PROBE #undef DEBUG_TX @@ -1035,6 +1036,33 @@ sbus_writel(tmp, bregs + BMAC_RXCFG); } +/* Ethtool support... */ +static void bigmac_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info) +{ + struct bigmac *bp = dev->priv; + + strcpy(info->driver, "sunbmac"); + strcpy(info->version, "2.0"); + sprintf(info->bus_info, "SBUS:%d", + bp->qec_sdev->slot); +} + +static u32 bigmac_get_link(struct net_device *dev) +{ + struct bigmac *bp = dev->priv; + + spin_lock_irq(&bp->lock); + bp->sw_bmsr = bigmac_tcvr_read(bp, bp->tregs, BIGMAC_BMSR); + spin_unlock_irq(&bp->lock); + + return (bp->sw_bmsr & BMSR_LSTATUS); +} + +static struct ethtool_ops bigmac_ethtool_ops = { + .get_drvinfo = bigmac_get_drvinfo, + .get_link = bigmac_get_link, +}; + static int __init bigmac_ether_init(struct sbus_dev *qec_sdev) { struct net_device *dev; @@ -1169,6 +1197,7 @@ dev->open = &bigmac_open; dev->stop = &bigmac_close; dev->hard_start_xmit = &bigmac_start_xmit; + dev->ethtool_ops = &bigmac_ethtool_ops; /* Set links to BigMAC statistic and multi-cast loading code. */ dev->get_stats = &bigmac_get_stats; diff -Nru a/drivers/net/sungem.c b/drivers/net/sungem.c --- a/drivers/net/sungem.c Tue Sep 2 19:58:19 2003 +++ b/drivers/net/sungem.c Tue Sep 2 19:58:19 2003 @@ -1,7 +1,7 @@ /* $Id: sungem.c,v 1.44.2.22 2002/03/13 01:18:12 davem Exp $ * sungem.c: Sun GEM ethernet driver. * - * Copyright (C) 2000, 2001, 2002 David S. Miller (davem@redhat.com) + * Copyright (C) 2000, 2001, 2002, 2003 David S. Miller (davem@redhat.com) * * Support for Apple GMAC and assorted PHYs by * Benjamin Herrenscmidt (benh@kernel.crashing.org) @@ -70,8 +70,8 @@ SUPPORTED_1000baseT_Half | SUPPORTED_1000baseT_Full) #define DRV_NAME "sungem" -#define DRV_VERSION "0.97" -#define DRV_RELDATE "3/20/02" +#define DRV_VERSION "0.98" +#define DRV_RELDATE "8/24/03" #define DRV_AUTHOR "David S. Miller (davem@redhat.com)" static char version[] __devinitdata = @@ -2317,177 +2317,134 @@ spin_unlock_irq(&gp->lock); } -/* Eventually add support for changing the advertisement - * on autoneg. - */ -static int gem_ethtool_ioctl(struct net_device *dev, void *ep_user) +static void gem_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info) +{ + struct gem *gp = dev->priv; + + strcpy(info->driver, DRV_NAME); + strcpy(info->version, DRV_VERSION); + strcpy(info->bus_info, pci_name(gp->pdev)); +} + +static int gem_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) { struct gem *gp = dev->priv; - struct ethtool_cmd ecmd; - - if (copy_from_user(&ecmd, ep_user, sizeof(ecmd))) - return -EFAULT; - - switch(ecmd.cmd) { - case ETHTOOL_GDRVINFO: { - struct ethtool_drvinfo info = { .cmd = ETHTOOL_GDRVINFO }; - - strncpy(info.driver, DRV_NAME, ETHTOOL_BUSINFO_LEN); - strncpy(info.version, DRV_VERSION, ETHTOOL_BUSINFO_LEN); - info.fw_version[0] = '\0'; - strncpy(info.bus_info, pci_name(gp->pdev), ETHTOOL_BUSINFO_LEN); - info.regdump_len = 0; /*SUNGEM_NREGS;*/ - if (copy_to_user(ep_user, &info, sizeof(info))) - return -EFAULT; + if (gp->phy_type == phy_mii_mdio0 || + gp->phy_type == phy_mii_mdio1) { + if (gp->phy_mii.def) + cmd->supported = gp->phy_mii.def->features; + else + cmd->supported = (SUPPORTED_10baseT_Half | + SUPPORTED_10baseT_Full); - return 0; - } + /* XXX hardcoded stuff for now */ + cmd->port = PORT_MII; + cmd->transceiver = XCVR_EXTERNAL; + cmd->phy_address = 0; /* XXX fixed PHYAD */ - case ETHTOOL_GSET: - if (gp->phy_type == phy_mii_mdio0 || - gp->phy_type == phy_mii_mdio1) { - if (gp->phy_mii.def) - ecmd.supported = gp->phy_mii.def->features; - else - ecmd.supported = SUPPORTED_10baseT_Half | SUPPORTED_10baseT_Full; - - /* XXX hardcoded stuff for now */ - ecmd.port = PORT_MII; - ecmd.transceiver = XCVR_EXTERNAL; - ecmd.phy_address = 0; /* XXX fixed PHYAD */ - - /* Return current PHY settings */ - spin_lock_irq(&gp->lock); - ecmd.autoneg = gp->want_autoneg; - ecmd.speed = gp->phy_mii.speed; - ecmd.duplex = gp->phy_mii.duplex; - ecmd.advertising = gp->phy_mii.advertising; - /* If we started with a forced mode, we don't have a default - * advertise set, we need to return something sensible so - * userland can re-enable autoneg properly */ - if (ecmd.advertising == 0) - ecmd.advertising = ecmd.supported; - spin_unlock_irq(&gp->lock); - } else { // XXX PCS ? - ecmd.supported = + /* Return current PHY settings */ + spin_lock_irq(&gp->lock); + cmd->autoneg = gp->want_autoneg; + cmd->speed = gp->phy_mii.speed; + cmd->duplex = gp->phy_mii.duplex; + cmd->advertising = gp->phy_mii.advertising; + + /* If we started with a forced mode, we don't have a default + * advertise set, we need to return something sensible so + * userland can re-enable autoneg properly. + */ + if (cmd->advertising == 0) + cmd->advertising = cmd->supported; + spin_unlock_irq(&gp->lock); + } else { // XXX PCS ? + cmd->supported = (SUPPORTED_10baseT_Half | SUPPORTED_10baseT_Full | SUPPORTED_100baseT_Half | SUPPORTED_100baseT_Full | SUPPORTED_Autoneg); - ecmd.advertising = ecmd.supported; - } - if (copy_to_user(ep_user, &ecmd, sizeof(ecmd))) - return -EFAULT; - return 0; + cmd->advertising = cmd->supported; + cmd->speed = 0; + cmd->duplex = cmd->port = cmd->phy_address = + cmd->transceiver = cmd->autoneg = 0; + } + cmd->maxtxpkt = cmd->maxrxpkt = 0; - case ETHTOOL_SSET: - /* Verify the settings we care about. */ - if (ecmd.autoneg != AUTONEG_ENABLE && - ecmd.autoneg != AUTONEG_DISABLE) - return -EINVAL; - - if (ecmd.autoneg == AUTONEG_ENABLE && - ecmd.advertising == 0) - return -EINVAL; - - if (ecmd.autoneg == AUTONEG_DISABLE && - ((ecmd.speed != SPEED_1000 && - ecmd.speed != SPEED_100 && - ecmd.speed != SPEED_10) || - (ecmd.duplex != DUPLEX_HALF && - ecmd.duplex != DUPLEX_FULL))) - return -EINVAL; - - /* Apply settings and restart link process. */ - spin_lock_irq(&gp->lock); - gem_begin_auto_negotiation(gp, &ecmd); - spin_unlock_irq(&gp->lock); + return 0; +} - return 0; +static int gem_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) +{ + struct gem *gp = dev->priv; - case ETHTOOL_NWAY_RST: - if (!gp->want_autoneg) - return -EINVAL; + /* Verify the settings we care about. */ + if (cmd->autoneg != AUTONEG_ENABLE && + cmd->autoneg != AUTONEG_DISABLE) + return -EINVAL; - /* Restart link process. */ - spin_lock_irq(&gp->lock); - gem_begin_auto_negotiation(gp, NULL); - spin_unlock_irq(&gp->lock); + if (cmd->autoneg == AUTONEG_ENABLE && + cmd->advertising == 0) + return -EINVAL; - return 0; + if (cmd->autoneg == AUTONEG_DISABLE && + ((cmd->speed != SPEED_1000 && + cmd->speed != SPEED_100 && + cmd->speed != SPEED_10) || + (cmd->duplex != DUPLEX_HALF && + cmd->duplex != DUPLEX_FULL))) + return -EINVAL; + + /* Apply settings and restart link process. */ + spin_lock_irq(&gp->lock); + gem_begin_auto_negotiation(gp, cmd); + spin_unlock_irq(&gp->lock); - case ETHTOOL_GWOL: - case ETHTOOL_SWOL: - break; /* todo */ - - /* get link status */ - case ETHTOOL_GLINK: { - struct ethtool_value edata = { .cmd = ETHTOOL_GLINK }; - - edata.data = (gp->lstate == link_up); - if (copy_to_user(ep_user, &edata, sizeof(edata))) - return -EFAULT; - return 0; - } + return 0; +} - /* get message-level */ - case ETHTOOL_GMSGLVL: { - struct ethtool_value edata = { .cmd = ETHTOOL_GMSGLVL }; - - edata.data = gp->msg_enable; - if (copy_to_user(ep_user, &edata, sizeof(edata))) - return -EFAULT; - return 0; - } +static int gem_nway_reset(struct net_device *dev) +{ + struct gem *gp = dev->priv; - /* set message-level */ - case ETHTOOL_SMSGLVL: { - struct ethtool_value edata; - - if (copy_from_user(&edata, ep_user, sizeof(edata))) - return -EFAULT; - gp->msg_enable = edata.data; - return 0; - } + if (!gp->want_autoneg) + return -EINVAL; -#if 0 - case ETHTOOL_GREGS: { - struct ethtool_regs regs; - u32 *regbuf; - int r = 0; + /* Restart link process. */ + spin_lock_irq(&gp->lock); + gem_begin_auto_negotiation(gp, NULL); + spin_unlock_irq(&gp->lock); - if (copy_from_user(®s, useraddr, sizeof(regs))) - return -EFAULT; - - if (regs.len > SUNGEM_NREGS) { - regs.len = SUNGEM_NREGS; - } - regs.version = 0; - if (copy_to_user(useraddr, ®s, sizeof(regs))) - return -EFAULT; + return 0; +} - if (!gp->hw_running) - return -ENODEV; - useraddr += offsetof(struct ethtool_regs, data); +static u32 gem_get_link(struct net_device *dev) +{ + struct gem *gp = dev->priv; - /* Use kmalloc to avoid bloating the stack */ - regbuf = kmalloc(4 * SUNGEM_NREGS, GFP_KERNEL); - if (!regbuf) - return -ENOMEM; - spin_lock_irq(&np->lock); - gem_get_regs(gp, regbuf); - spin_unlock_irq(&np->lock); - - if (copy_to_user(useraddr, regbuf, regs.len*sizeof(u32))) - r = -EFAULT; - kfree(regbuf); - return r; - } -#endif - }; + return (gp->lstate == link_up); +} - return -EOPNOTSUPP; +static u32 gem_get_msglevel(struct net_device *dev) +{ + struct gem *gp = dev->priv; + return gp->msg_enable; +} + +static void gem_set_msglevel(struct net_device *dev, u32 value) +{ + struct gem *gp = dev->priv; + gp->msg_enable = value; } + +static struct ethtool_ops gem_ethtool_ops = { + .get_drvinfo = gem_get_drvinfo, + .get_link = ethtool_op_get_link, + .get_settings = gem_get_settings, + .set_settings = gem_set_settings, + .nway_reset = gem_nway_reset, + .get_link = gem_get_link, + .get_msglevel = gem_get_msglevel, + .set_msglevel = gem_set_msglevel, +}; static int gem_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) { @@ -2501,10 +2458,6 @@ down(&gp->pm_sem); switch (cmd) { - case SIOCETHTOOL: - rc = gem_ethtool_ioctl(dev, ifr->ifr_data); - break; - case SIOCGMIIPHY: /* Get address of MII PHY in use. */ data->phy_id = gp->mii_phy_addr; /* Fallthrough... */ @@ -2812,6 +2765,7 @@ dev->get_stats = gem_get_stats; dev->set_multicast_list = gem_set_multicast; dev->do_ioctl = gem_ioctl; + dev->ethtool_ops = &gem_ethtool_ops; dev->tx_timeout = gem_tx_timeout; dev->watchdog_timeo = 5 * HZ; dev->change_mtu = gem_change_mtu; diff -Nru a/drivers/net/sungem_phy.c b/drivers/net/sungem_phy.c --- a/drivers/net/sungem_phy.c Tue Sep 2 19:58:14 2003 +++ b/drivers/net/sungem_phy.c Tue Sep 2 19:58:14 2003 @@ -634,116 +634,116 @@ /* Broadcom BCM 5201 */ static struct mii_phy_ops bcm5201_phy_ops = { - init: bcm5201_init, - suspend: bcm5201_suspend, - setup_aneg: genmii_setup_aneg, - setup_forced: genmii_setup_forced, - poll_link: genmii_poll_link, - read_link: genmii_read_link, + .init = bcm5201_init, + .suspend = bcm5201_suspend, + .setup_aneg = genmii_setup_aneg, + .setup_forced = genmii_setup_forced, + .poll_link = genmii_poll_link, + .read_link = genmii_read_link, }; static struct mii_phy_def bcm5201_phy_def = { - phy_id: 0x00406210, - phy_id_mask: 0xfffffff0, - name: "BCM5201", - features: MII_BASIC_FEATURES, - magic_aneg: 0, - ops: &bcm5201_phy_ops + .phy_id = 0x00406210, + .phy_id_mask = 0xfffffff0, + .name = "BCM5201", + .features = MII_BASIC_FEATURES, + .magic_aneg = 0, + .ops = &bcm5201_phy_ops }; /* Broadcom BCM 5221 */ static struct mii_phy_ops bcm5221_phy_ops = { - suspend: bcm5201_suspend, - init: bcm5221_init, - setup_aneg: genmii_setup_aneg, - setup_forced: genmii_setup_forced, - poll_link: genmii_poll_link, - read_link: genmii_read_link, + .suspend = bcm5201_suspend, + .init = bcm5221_init, + .setup_aneg = genmii_setup_aneg, + .setup_forced = genmii_setup_forced, + .poll_link = genmii_poll_link, + .read_link = genmii_read_link, }; static struct mii_phy_def bcm5221_phy_def = { - phy_id: 0x004061e0, - phy_id_mask: 0xfffffff0, - name: "BCM5221", - features: MII_BASIC_FEATURES, - magic_aneg: 0, - ops: &bcm5221_phy_ops + .phy_id = 0x004061e0, + .phy_id_mask = 0xfffffff0, + .name = "BCM5221", + .features = MII_BASIC_FEATURES, + .magic_aneg = 0, + .ops = &bcm5221_phy_ops }; /* Broadcom BCM 5400 */ static struct mii_phy_ops bcm5400_phy_ops = { - init: bcm5400_init, - suspend: bcm5400_suspend, - setup_aneg: bcm54xx_setup_aneg, - setup_forced: bcm54xx_setup_forced, - poll_link: genmii_poll_link, - read_link: bcm54xx_read_link, + .init = bcm5400_init, + .suspend = bcm5400_suspend, + .setup_aneg = bcm54xx_setup_aneg, + .setup_forced = bcm54xx_setup_forced, + .poll_link = genmii_poll_link, + .read_link = bcm54xx_read_link, }; static struct mii_phy_def bcm5400_phy_def = { - phy_id: 0x00206040, - phy_id_mask: 0xfffffff0, - name: "BCM5400", - features: MII_GBIT_FEATURES, - magic_aneg: 1, - ops: &bcm5400_phy_ops + .phy_id = 0x00206040, + .phy_id_mask = 0xfffffff0, + .name = "BCM5400", + .features = MII_GBIT_FEATURES, + .magic_aneg = 1, + .ops = &bcm5400_phy_ops }; /* Broadcom BCM 5401 */ static struct mii_phy_ops bcm5401_phy_ops = { - init: bcm5401_init, - suspend: bcm5401_suspend, - setup_aneg: bcm54xx_setup_aneg, - setup_forced: bcm54xx_setup_forced, - poll_link: genmii_poll_link, - read_link: bcm54xx_read_link, + .init = bcm5401_init, + .suspend = bcm5401_suspend, + .setup_aneg = bcm54xx_setup_aneg, + .setup_forced = bcm54xx_setup_forced, + .poll_link = genmii_poll_link, + .read_link = bcm54xx_read_link, }; static struct mii_phy_def bcm5401_phy_def = { - phy_id: 0x00206050, - phy_id_mask: 0xfffffff0, - name: "BCM5401", - features: MII_GBIT_FEATURES, - magic_aneg: 1, - ops: &bcm5401_phy_ops + .phy_id = 0x00206050, + .phy_id_mask = 0xfffffff0, + .name = "BCM5401", + .features = MII_GBIT_FEATURES, + .magic_aneg = 1, + .ops = &bcm5401_phy_ops }; /* Broadcom BCM 5411 */ static struct mii_phy_ops bcm5411_phy_ops = { - init: bcm5411_init, - suspend: bcm5411_suspend, - setup_aneg: bcm54xx_setup_aneg, - setup_forced: bcm54xx_setup_forced, - poll_link: genmii_poll_link, - read_link: bcm54xx_read_link, + .init = bcm5411_init, + .suspend = bcm5411_suspend, + .setup_aneg = bcm54xx_setup_aneg, + .setup_forced = bcm54xx_setup_forced, + .poll_link = genmii_poll_link, + .read_link = bcm54xx_read_link, }; static struct mii_phy_def bcm5411_phy_def = { - phy_id: 0x00206070, - phy_id_mask: 0xfffffff0, - name: "BCM5411", - features: MII_GBIT_FEATURES, - magic_aneg: 1, - ops: &bcm5411_phy_ops + .phy_id = 0x00206070, + .phy_id_mask = 0xfffffff0, + .name = "BCM5411", + .features = MII_GBIT_FEATURES, + .magic_aneg = 1, + .ops = &bcm5411_phy_ops }; /* Broadcom BCM 5421 */ static struct mii_phy_ops bcm5421_phy_ops = { - init: bcm5421_init, - suspend: bcm5411_suspend, - setup_aneg: bcm54xx_setup_aneg, - setup_forced: bcm54xx_setup_forced, - poll_link: genmii_poll_link, - read_link: bcm54xx_read_link, + .init = bcm5421_init, + .suspend = bcm5411_suspend, + .setup_aneg = bcm54xx_setup_aneg, + .setup_forced = bcm54xx_setup_forced, + .poll_link = genmii_poll_link, + .read_link = bcm54xx_read_link, }; static struct mii_phy_def bcm5421_phy_def = { - phy_id: 0x002060e0, - phy_id_mask: 0xfffffff0, - name: "BCM5421", - features: MII_GBIT_FEATURES, - magic_aneg: 1, - ops: &bcm5421_phy_ops + .phy_id = 0x002060e0, + .phy_id_mask = 0xfffffff0, + .name = "BCM5421", + .features = MII_GBIT_FEATURES, + .magic_aneg = 1, + .ops = &bcm5421_phy_ops }; /* Marvell 88E1101 (Apple seem to deal with 2 different revs, @@ -751,36 +751,36 @@ * would be useful here) --BenH. */ static struct mii_phy_ops marvell_phy_ops = { - setup_aneg: marvell_setup_aneg, - setup_forced: marvell_setup_forced, - poll_link: genmii_poll_link, - read_link: marvell_read_link + .setup_aneg = marvell_setup_aneg, + .setup_forced = marvell_setup_forced, + .poll_link = genmii_poll_link, + .read_link = marvell_read_link }; static struct mii_phy_def marvell_phy_def = { - phy_id: 0x01410c00, - phy_id_mask: 0xffffff00, - name: "Marvell 88E1101", - features: MII_GBIT_FEATURES, - magic_aneg: 1, - ops: &marvell_phy_ops + .phy_id = 0x01410c00, + .phy_id_mask = 0xffffff00, + .name = "Marvell 88E1101", + .features = MII_GBIT_FEATURES, + .magic_aneg = 1, + .ops = &marvell_phy_ops }; /* Generic implementation for most 10/100 PHYs */ static struct mii_phy_ops generic_phy_ops = { - setup_aneg: genmii_setup_aneg, - setup_forced: genmii_setup_forced, - poll_link: genmii_poll_link, - read_link: genmii_read_link + .setup_aneg = genmii_setup_aneg, + .setup_forced = genmii_setup_forced, + .poll_link = genmii_poll_link, + .read_link = genmii_read_link }; static struct mii_phy_def genmii_phy_def = { - phy_id: 0x00000000, - phy_id_mask: 0x00000000, - name: "Generic MII", - features: MII_BASIC_FEATURES, - magic_aneg: 0, - ops: &generic_phy_ops + .phy_id = 0x00000000, + .phy_id_mask = 0x00000000, + .name = "Generic MII", + .features = MII_BASIC_FEATURES, + .magic_aneg = 0, + .ops = &generic_phy_ops }; static struct mii_phy_def* mii_phy_table[] = { diff -Nru a/drivers/net/sunhme.c b/drivers/net/sunhme.c --- a/drivers/net/sunhme.c Tue Sep 2 19:58:14 2003 +++ b/drivers/net/sunhme.c Tue Sep 2 19:58:15 2003 @@ -3,7 +3,7 @@ * auto carrier detecting ethernet driver. Also known as the * "Happy Meal Ethernet" found on SunSwift SBUS cards. * - * Copyright (C) 1996, 1998, 1999, 2002 David S. Miller (davem@redhat.com) + * Copyright (C) 1996, 1998, 1999, 2002, 2003 David S. Miller (davem@redhat.com) * * Changes : * 2000/11/11 Willy Tarreau @@ -14,10 +14,10 @@ */ static char version[] = - "sunhme.c:v2.01 26/Mar/2002 David S. Miller (davem@redhat.com)\n"; + "sunhme.c:v2.02 24/Aug/2003 David S. Miller (davem@redhat.com)\n"; -#include #include +#include #include #include #include @@ -2426,85 +2426,112 @@ } /* Ethtool support... */ -static int happy_meal_ioctl(struct net_device *dev, - struct ifreq *rq, int cmd) +static int hme_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) { struct happy_meal *hp = dev->priv; - struct ethtool_cmd *ep_user = (struct ethtool_cmd *) rq->ifr_data; - struct ethtool_cmd ecmd; - if (cmd != SIOCETHTOOL) - return -EOPNOTSUPP; - if (copy_from_user(&ecmd, ep_user, sizeof(ecmd))) - return -EFAULT; - - if (ecmd.cmd == ETHTOOL_GSET) { - ecmd.supported = - (SUPPORTED_10baseT_Half | SUPPORTED_10baseT_Full | - SUPPORTED_100baseT_Half | SUPPORTED_100baseT_Full | - SUPPORTED_Autoneg | SUPPORTED_TP | SUPPORTED_MII); - - /* XXX hardcoded stuff for now */ - ecmd.port = PORT_TP; /* XXX no MII support */ - ecmd.transceiver = XCVR_INTERNAL; /* XXX no external xcvr support */ - ecmd.phy_address = 0; /* XXX fixed PHYAD */ - - /* Record PHY settings. */ - spin_lock_irq(&hp->happy_lock); - hp->sw_bmcr = happy_meal_tcvr_read(hp, hp->tcvregs, MII_BMCR); - hp->sw_lpa = happy_meal_tcvr_read(hp, hp->tcvregs, MII_LPA); - spin_unlock_irq(&hp->happy_lock); + cmd->supported = + (SUPPORTED_10baseT_Half | SUPPORTED_10baseT_Full | + SUPPORTED_100baseT_Half | SUPPORTED_100baseT_Full | + SUPPORTED_Autoneg | SUPPORTED_TP | SUPPORTED_MII); + + /* XXX hardcoded stuff for now */ + cmd->port = PORT_TP; /* XXX no MII support */ + cmd->transceiver = XCVR_INTERNAL; /* XXX no external xcvr support */ + cmd->phy_address = 0; /* XXX fixed PHYAD */ - if (hp->sw_bmcr & BMCR_ANENABLE) { - ecmd.autoneg = AUTONEG_ENABLE; - ecmd.speed = - (hp->sw_lpa & (LPA_100HALF | LPA_100FULL)) ? - SPEED_100 : SPEED_10; - if (ecmd.speed == SPEED_100) - ecmd.duplex = - (hp->sw_lpa & (LPA_100FULL)) ? - DUPLEX_FULL : DUPLEX_HALF; - else - ecmd.duplex = - (hp->sw_lpa & (LPA_10FULL)) ? - DUPLEX_FULL : DUPLEX_HALF; - } else { - ecmd.autoneg = AUTONEG_DISABLE; - ecmd.speed = - (hp->sw_bmcr & BMCR_SPEED100) ? - SPEED_100 : SPEED_10; - ecmd.duplex = - (hp->sw_bmcr & BMCR_FULLDPLX) ? + /* Record PHY settings. */ + spin_lock_irq(&hp->happy_lock); + hp->sw_bmcr = happy_meal_tcvr_read(hp, hp->tcvregs, MII_BMCR); + hp->sw_lpa = happy_meal_tcvr_read(hp, hp->tcvregs, MII_LPA); + spin_unlock_irq(&hp->happy_lock); + + if (hp->sw_bmcr & BMCR_ANENABLE) { + cmd->autoneg = AUTONEG_ENABLE; + cmd->speed = + (hp->sw_lpa & (LPA_100HALF | LPA_100FULL)) ? + SPEED_100 : SPEED_10; + if (cmd->speed == SPEED_100) + cmd->duplex = + (hp->sw_lpa & (LPA_100FULL)) ? DUPLEX_FULL : DUPLEX_HALF; - } - if (copy_to_user(ep_user, &ecmd, sizeof(ecmd))) - return -EFAULT; - return 0; - } else if (ecmd.cmd == ETHTOOL_SSET) { - /* Verify the settings we care about. */ - if (ecmd.autoneg != AUTONEG_ENABLE && - ecmd.autoneg != AUTONEG_DISABLE) - return -EINVAL; - if (ecmd.autoneg == AUTONEG_DISABLE && - ((ecmd.speed != SPEED_100 && - ecmd.speed != SPEED_10) || - (ecmd.duplex != DUPLEX_HALF && - ecmd.duplex != DUPLEX_FULL))) - return -EINVAL; - - /* Ok, do it to it. */ - spin_lock_irq(&hp->happy_lock); - del_timer(&hp->happy_timer); - happy_meal_begin_auto_negotiation(hp, - hp->tcvregs, - &ecmd); - spin_unlock_irq(&hp->happy_lock); + else + cmd->duplex = + (hp->sw_lpa & (LPA_10FULL)) ? + DUPLEX_FULL : DUPLEX_HALF; + } else { + cmd->autoneg = AUTONEG_DISABLE; + cmd->speed = + (hp->sw_bmcr & BMCR_SPEED100) ? + SPEED_100 : SPEED_10; + cmd->duplex = + (hp->sw_bmcr & BMCR_FULLDPLX) ? + DUPLEX_FULL : DUPLEX_HALF; + } + return 0; +} - return 0; - } else - return -EOPNOTSUPP; +static int hme_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) +{ + struct happy_meal *hp = dev->priv; + + /* Verify the settings we care about. */ + if (cmd->autoneg != AUTONEG_ENABLE && + cmd->autoneg != AUTONEG_DISABLE) + return -EINVAL; + if (cmd->autoneg == AUTONEG_DISABLE && + ((cmd->speed != SPEED_100 && + cmd->speed != SPEED_10) || + (cmd->duplex != DUPLEX_HALF && + cmd->duplex != DUPLEX_FULL))) + return -EINVAL; + + /* Ok, do it to it. */ + spin_lock_irq(&hp->happy_lock); + del_timer(&hp->happy_timer); + happy_meal_begin_auto_negotiation(hp, hp->tcvregs, cmd); + spin_unlock_irq(&hp->happy_lock); + + return 0; } +static void hme_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info) +{ + struct happy_meal *hp = dev->priv; + + strcpy(info->driver, "sunhme"); + strcpy(info->version, "2.02"); + if (hp->happy_flags & HFLAG_PCI) { + struct pci_dev *pdev = hp->happy_dev; + strcpy(info->bus_info, pci_name(pdev)); + } +#ifdef CONFIG_SBUS + else { + struct sbus_dev *sdev = hp->happy_dev; + sprintf(info->bus_info, "SBUS:%d", + sdev->slot); + } +#endif +} + +static u32 hme_get_link(struct net_device *dev) +{ + struct happy_meal *hp = dev->priv; + + spin_lock_irq(&hp->happy_lock); + hp->sw_bmcr = happy_meal_tcvr_read(hp, hp->tcvregs, MII_BMCR); + spin_unlock_irq(&hp->happy_lock); + + return (hp->sw_bmsr & BMSR_LSTATUS); +} + +static struct ethtool_ops hme_ethtool_ops = { + .get_settings = hme_get_settings, + .set_settings = hme_set_settings, + .get_drvinfo = hme_get_drvinfo, + .get_link = hme_get_link, +}; + static int hme_version_printed; #ifdef CONFIG_SBUS @@ -2797,7 +2824,7 @@ dev->set_multicast_list = &happy_meal_set_multicast; dev->tx_timeout = &happy_meal_tx_timeout; dev->watchdog_timeo = 5*HZ; - dev->do_ioctl = &happy_meal_ioctl; + dev->ethtool_ops = &hme_ethtool_ops; /* Happy Meal can do it all... except VLAN. */ dev->features |= NETIF_F_SG | NETIF_F_HW_CSUM | NETIF_F_VLAN_CHALLENGED; @@ -3141,7 +3168,7 @@ dev->set_multicast_list = &happy_meal_set_multicast; dev->tx_timeout = &happy_meal_tx_timeout; dev->watchdog_timeo = 5*HZ; - dev->do_ioctl = &happy_meal_ioctl; + dev->ethtool_ops = &hme_ethtool_ops; dev->irq = pdev->irq; dev->dma = 0; diff -Nru a/drivers/net/sunlance.c b/drivers/net/sunlance.c --- a/drivers/net/sunlance.c Tue Sep 2 19:58:14 2003 +++ b/drivers/net/sunlance.c Tue Sep 2 19:58:14 2003 @@ -70,7 +70,7 @@ #undef DEBUG_DRIVER static char version[] = - "sunlance.c:v2.01 08/Nov/01 Miguel de Icaza (miguel@nuclecu.unam.mx)\n"; + "sunlance.c:v2.02 24/Aug/03 Miguel de Icaza (miguel@nuclecu.unam.mx)\n"; static char lancestr[] = "LANCE"; @@ -93,6 +93,7 @@ #include #include #include +#include #include #include @@ -1287,6 +1288,30 @@ } } +/* Ethtool support... */ +static void sparc_lance_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info) +{ + struct lance_private *lp = dev->priv; + + strcpy(info->driver, "sunlance"); + strcpy(info->version, "2.02"); + sprintf(info->bus_info, "SBUS:%d", + lp->sdev->slot); +} + +static u32 sparc_lance_get_link(struct net_device *dev) +{ + /* We really do not keep track of this, but this + * is better than not reporting anything at all. + */ + return 1; +} + +static struct ethtool_ops sparc_lance_ethtool_ops = { + .get_drvinfo = sparc_lance_get_drvinfo, + .get_link = sparc_lance_get_link, +}; + static int __init sparc_lance_init(struct net_device *dev, struct sbus_dev *sdev, struct sbus_dma *ledma, @@ -1456,6 +1481,7 @@ dev->watchdog_timeo = 5*HZ; dev->get_stats = &lance_get_stats; dev->set_multicast_list = &lance_set_multicast; + dev->ethtool_ops = &sparc_lance_ethtool_ops; dev->irq = sdev->irqs[0]; diff -Nru a/drivers/net/sunqe.c b/drivers/net/sunqe.c --- a/drivers/net/sunqe.c Tue Sep 2 19:58:15 2003 +++ b/drivers/net/sunqe.c Tue Sep 2 19:58:15 2003 @@ -4,11 +4,11 @@ * controller out there can be most efficiently programmed * if you make it look like a LANCE. * - * Copyright (C) 1996, 1999 David S. Miller (davem@redhat.com) + * Copyright (C) 1996, 1999, 2003 David S. Miller (davem@redhat.com) */ static char version[] = - "sunqe.c:v2.9 9/11/99 David S. Miller (davem@redhat.com)\n"; + "sunqe.c:v3.0 8/24/03 David S. Miller (davem@redhat.com)\n"; #include #include @@ -26,6 +26,7 @@ #include #include #include +#include #include #include @@ -684,6 +685,35 @@ netif_wake_queue(dev); } +/* Ethtool support... */ +static void qe_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info) +{ + struct sunqe *qep = dev->priv; + + strcpy(info->driver, "sunqe"); + strcpy(info->version, "3.0"); + sprintf(info->bus_info, "SBUS:%d", + qep->qe_sdev->slot); +} + +static u32 qe_get_link(struct net_device *dev) +{ + struct sunqe *qep = dev->priv; + unsigned long mregs = qep->mregs; + u8 phyconfig; + + spin_lock_irq(&qep->lock); + phyconfig = sbus_readb(mregs + MREGS_PHYCONFIG); + spin_unlock_irq(&qep->lock); + + return (phyconfig & MREGS_PHYCONFIG_LSTAT); +} + +static struct ethtool_ops qe_ethtool_ops = { + .get_drvinfo = qe_get_drvinfo, + .get_link = qe_get_link, +}; + /* This is only called once at boot time for each card probed. */ static inline void qec_init_once(struct sunqec *qecp, struct sbus_dev *qsdev) { @@ -850,6 +880,7 @@ qe_devs[i]->watchdog_timeo = 5*HZ; qe_devs[i]->irq = sdev->irqs[0]; qe_devs[i]->dma = 0; + qe_devs[i]->ethtool_ops = &qe_ethtool_ops; } /* QEC receives interrupts from each QE, then it sends the actual diff -Nru a/drivers/net/tg3.c b/drivers/net/tg3.c --- a/drivers/net/tg3.c Tue Sep 2 19:58:16 2003 +++ b/drivers/net/tg3.c Tue Sep 2 19:58:16 2003 @@ -2,7 +2,7 @@ * tg3.c: Broadcom Tigon3 ethernet driver. * * Copyright (C) 2001, 2002, 2003 David S. Miller (davem@redhat.com) - * Copyright (C) 2001, 2002 Jeff Garzik (jgarzik@pobox.com) + * Copyright (C) 2001, 2002, 2003 Jeff Garzik (jgarzik@pobox.com) */ #include @@ -27,6 +27,8 @@ #include #include +#include + #include #include #include @@ -45,20 +47,17 @@ #endif #ifdef NETIF_F_TSO -/* XXX Works but still disabled, decreases TCP performance to 7MB/sec even - * XXX over gigabit. - */ -#define TG3_DO_TSO 0 +#define TG3_TSO_SUPPORT 1 #else -#define TG3_DO_TSO 0 +#define TG3_TSO_SUPPORT 0 #endif #include "tg3.h" #define DRV_MODULE_NAME "tg3" #define PFX DRV_MODULE_NAME ": " -#define DRV_MODULE_VERSION "1.9" -#define DRV_MODULE_RELDATE "August 3, 2003" +#define DRV_MODULE_VERSION "2.2" +#define DRV_MODULE_RELDATE "August 24, 2003" #define TG3_DEF_MAC_MODE 0 #define TG3_DEF_RX_MODE 0 @@ -80,7 +79,8 @@ /* hardware minimum and maximum for a single frame's data payload */ #define TG3_MIN_MTU 60 -#define TG3_MAX_MTU 9000 +#define TG3_MAX_MTU(tp) \ + (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5705 ? 9000 : 1500) /* These numbers seem to be hard coded in the NIC firmware somehow. * You can't change the ring sizes, but you can change where you place @@ -90,7 +90,17 @@ #define TG3_DEF_RX_RING_PENDING 200 #define TG3_RX_JUMBO_RING_SIZE 256 #define TG3_DEF_RX_JUMBO_RING_PENDING 100 -#define TG3_RX_RCB_RING_SIZE 1024 + +/* Do not place this n-ring entries value into the tp struct itself, + * we really want to expose these constants to GCC so that modulo et + * al. operations are done with shifts and masks instead of with + * hw multiply/modulo instructions. Another solution would be to + * replace things like '% foo' with '& (foo - 1)'. + */ +#define TG3_RX_RCB_RING_SIZE(tp) \ + (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705 ? \ + 512 : 1024) + #define TG3_TX_RING_SIZE 512 #define TG3_DEF_TX_RING_PENDING (TG3_TX_RING_SIZE - 1) @@ -98,8 +108,8 @@ TG3_RX_RING_SIZE) #define TG3_RX_JUMBO_RING_BYTES (sizeof(struct tg3_rx_buffer_desc) * \ TG3_RX_JUMBO_RING_SIZE) -#define TG3_RX_RCB_RING_BYTES (sizeof(struct tg3_rx_buffer_desc) * \ - TG3_RX_RCB_RING_SIZE) +#define TG3_RX_RCB_RING_BYTES(tp) (sizeof(struct tg3_rx_buffer_desc) * \ + TG3_RX_RCB_RING_SIZE(tp)) #define TG3_TX_RING_BYTES (sizeof(struct tg3_tx_buffer_desc) * \ TG3_TX_RING_SIZE) #define TX_RING_GAP(TP) \ @@ -140,6 +150,14 @@ PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5702FE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, + { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5705, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, + { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5705_2, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, + { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5705M, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, + { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5705M_2, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5702X, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5703X, @@ -150,12 +168,24 @@ PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5703A3, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, - { PCI_VENDOR_ID_SYSKONNECT, 0x4400, + { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5782, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, + { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5788, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, + { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5901, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, + { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5901_2, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, + { PCI_VENDOR_ID_SYSKONNECT, PCI_DEVICE_ID_SYSKONNECT_9DXX, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, + { PCI_VENDOR_ID_SYSKONNECT, PCI_DEVICE_ID_SYSKONNECT_9MXX, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, { PCI_VENDOR_ID_ALTIMA, PCI_DEVICE_ID_ALTIMA_AC1000, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, { PCI_VENDOR_ID_ALTIMA, PCI_DEVICE_ID_ALTIMA_AC1001, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, + { PCI_VENDOR_ID_ALTIMA, PCI_DEVICE_ID_ALTIMA_AC1003, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, { PCI_VENDOR_ID_ALTIMA, PCI_DEVICE_ID_ALTIMA_AC9100, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, { 0, } @@ -237,38 +267,6 @@ tg3_cond_int(tp); } -/* these netif_xxx funcs should be moved into generic net layer */ -static void netif_poll_disable(struct net_device *dev) -{ - while (test_and_set_bit(__LINK_STATE_RX_SCHED, &dev->state)) { - current->state = TASK_INTERRUPTIBLE; - schedule_timeout(1); - } -} - -static inline void netif_poll_enable(struct net_device *dev) -{ - clear_bit(__LINK_STATE_RX_SCHED, &dev->state); -} - -/* same as netif_rx_complete, except that local_irq_save(flags) - * has already been issued - */ -static inline void __netif_rx_complete(struct net_device *dev) -{ - if (!test_bit(__LINK_STATE_RX_SCHED, &dev->state)) BUG(); - list_del(&dev->poll_list); - smp_mb__before_clear_bit(); - clear_bit(__LINK_STATE_RX_SCHED, &dev->state); -} - -static inline void netif_tx_disable(struct net_device *dev) -{ - spin_lock_bh(&dev->xmit_lock); - netif_stop_queue(dev); - spin_unlock_bh(&dev->xmit_lock); -} - static inline void tg3_netif_stop(struct tg3 *tp) { netif_poll_disable(tp->dev); @@ -288,17 +286,28 @@ static void tg3_switch_clocks(struct tg3 *tp) { - if (tr32(TG3PCI_CLOCK_CTRL) & CLOCK_CTRL_44MHZ_CORE) { + u32 clock_ctrl = tr32(TG3PCI_CLOCK_CTRL); + u32 orig_clock_ctrl; + + orig_clock_ctrl = clock_ctrl; + clock_ctrl &= (CLOCK_CTRL_FORCE_CLKRUN | + CLOCK_CTRL_CLKRUN_OENABLE | + 0x1f); + tp->pci_clock_ctrl = clock_ctrl; + + if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5705 && + (orig_clock_ctrl & CLOCK_CTRL_44MHZ_CORE) != 0) { tw32(TG3PCI_CLOCK_CTRL, + clock_ctrl | (CLOCK_CTRL_44MHZ_CORE | CLOCK_CTRL_ALTCLK)); tr32(TG3PCI_CLOCK_CTRL); udelay(40); tw32(TG3PCI_CLOCK_CTRL, - (CLOCK_CTRL_ALTCLK)); + clock_ctrl | (CLOCK_CTRL_ALTCLK)); tr32(TG3PCI_CLOCK_CTRL); udelay(40); } - tw32(TG3PCI_CLOCK_CTRL, 0); + tw32(TG3PCI_CLOCK_CTRL, clock_ctrl); tr32(TG3PCI_CLOCK_CTRL); udelay(40); } @@ -401,24 +410,22 @@ return ret; } -/* This will reset the tigon3 PHY if there is no valid - * link unless the FORCE argument is non-zero. - */ -static int tg3_phy_reset(struct tg3 *tp, int force) +static void tg3_phy_set_wirespeed(struct tg3 *tp) { - u32 phy_status, phy_control; - int err, limit; + u32 val; - err = tg3_readphy(tp, MII_BMSR, &phy_status); - err |= tg3_readphy(tp, MII_BMSR, &phy_status); - if (err != 0) - return -EBUSY; + if (tp->tg3_flags2 & TG3_FLG2_NO_ETH_WIRE_SPEED) + return; - /* If we have link, and not forcing a reset, then nothing - * to do. - */ - if ((phy_status & BMSR_LSTATUS) != 0 && (force == 0)) - return 0; + tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x7007); + tg3_readphy(tp, MII_TG3_AUX_CTRL, &val); + tg3_writephy(tp, MII_TG3_AUX_CTRL, (val | (1 << 15) | (1 << 4))); +} + +static int tg3_bmcr_reset(struct tg3 *tp) +{ + u32 phy_control; + int limit, err; /* OK, reset it, and poll the BMCR_RESET bit until it * clears or we time out. @@ -436,12 +443,303 @@ if ((phy_control & BMCR_RESET) == 0) { udelay(40); - return 0; + break; } udelay(10); } + if (limit <= 0) + return -EBUSY; + + return 0; +} + +static int tg3_wait_macro_done(struct tg3 *tp) +{ + int limit = 100; + + while (limit--) { + u32 tmp32; + + tg3_readphy(tp, 0x16, &tmp32); + if ((tmp32 & 0x1000) == 0) + break; + } + if (limit <= 0) + return -EBUSY; + + return 0; +} + +static int tg3_phy_write_and_check_testpat(struct tg3 *tp, int *resetp) +{ + static const u32 test_pat[4][6] = { + { 0x00005555, 0x00000005, 0x00002aaa, 0x0000000a, 0x00003456, 0x00000003 }, + { 0x00002aaa, 0x0000000a, 0x00003333, 0x00000003, 0x0000789a, 0x00000005 }, + { 0x00005a5a, 0x00000005, 0x00002a6a, 0x0000000a, 0x00001bcd, 0x00000003 }, + { 0x00002a5a, 0x0000000a, 0x000033c3, 0x00000003, 0x00002ef1, 0x00000005 } + }; + int chan; + + for (chan = 0; chan < 4; chan++) { + int i; + + tg3_writephy(tp, MII_TG3_DSP_ADDRESS, + (chan * 0x2000) | 0x0200); + tg3_writephy(tp, 0x16, 0x0002); + + for (i = 0; i < 6; i++) + tg3_writephy(tp, MII_TG3_DSP_RW_PORT, + test_pat[chan][i]); + + tg3_writephy(tp, 0x16, 0x0202); + if (tg3_wait_macro_done(tp)) { + *resetp = 1; + return -EBUSY; + } + + tg3_writephy(tp, MII_TG3_DSP_ADDRESS, + (chan * 0x2000) | 0x0200); + tg3_writephy(tp, 0x16, 0x0082); + if (tg3_wait_macro_done(tp)) { + *resetp = 1; + return -EBUSY; + } + + tg3_writephy(tp, 0x16, 0x0802); + if (tg3_wait_macro_done(tp)) { + *resetp = 1; + return -EBUSY; + } + + for (i = 0; i < 6; i += 2) { + u32 low, high; + + tg3_readphy(tp, MII_TG3_DSP_RW_PORT, &low); + tg3_readphy(tp, MII_TG3_DSP_RW_PORT, &high); + if (tg3_wait_macro_done(tp)) { + *resetp = 1; + return -EBUSY; + } + low &= 0x7fff; + high &= 0x000f; + if (low != test_pat[chan][i] || + high != test_pat[chan][i+1]) { + tg3_writephy(tp, MII_TG3_DSP_ADDRESS, 0x000b); + tg3_writephy(tp, MII_TG3_DSP_RW_PORT, 0x4001); + tg3_writephy(tp, MII_TG3_DSP_RW_PORT, 0x4005); + + return -EBUSY; + } + } + } - return -EBUSY; + return 0; +} + +static int tg3_phy_reset_chanpat(struct tg3 *tp) +{ + int chan; + + for (chan = 0; chan < 4; chan++) { + int i; + + tg3_writephy(tp, MII_TG3_DSP_ADDRESS, + (chan * 0x2000) | 0x0200); + tg3_writephy(tp, 0x16, 0x0002); + for (i = 0; i < 6; i++) + tg3_writephy(tp, MII_TG3_DSP_RW_PORT, 0x000); + tg3_writephy(tp, 0x16, 0x0202); + if (tg3_wait_macro_done(tp)) + return -EBUSY; + } + + return 0; +} + +static int tg3_phy_reset_5703_4_5(struct tg3 *tp) +{ + u32 reg32, phy9_orig; + int retries, do_phy_reset, err; + + retries = 10; + do_phy_reset = 1; + do { + if (do_phy_reset) { + err = tg3_bmcr_reset(tp); + if (err) + return err; + do_phy_reset = 0; + } + + /* Disable transmitter and interrupt. */ + tg3_readphy(tp, MII_TG3_EXT_CTRL, ®32); + reg32 |= 0x3000; + tg3_writephy(tp, MII_TG3_EXT_CTRL, reg32); + + /* Set full-duplex, 1000 mbps. */ + tg3_writephy(tp, MII_BMCR, + BMCR_FULLDPLX | TG3_BMCR_SPEED1000); + + /* Set to master mode. */ + tg3_readphy(tp, MII_TG3_CTRL, &phy9_orig); + tg3_writephy(tp, MII_TG3_CTRL, + (MII_TG3_CTRL_AS_MASTER | + MII_TG3_CTRL_ENABLE_AS_MASTER)); + + /* Enable SM_DSP_CLOCK and 6dB. */ + tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x0c00); + + /* Block the PHY control access. */ + tg3_writephy(tp, MII_TG3_DSP_ADDRESS, 0x8005); + tg3_writephy(tp, MII_TG3_DSP_RW_PORT, 0x0800); + + err = tg3_phy_write_and_check_testpat(tp, &do_phy_reset); + if (!err) + break; + } while (--retries); + + err = tg3_phy_reset_chanpat(tp); + if (err) + return err; + + tg3_writephy(tp, MII_TG3_DSP_ADDRESS, 0x8005); + tg3_writephy(tp, MII_TG3_DSP_RW_PORT, 0x0000); + + tg3_writephy(tp, MII_TG3_DSP_ADDRESS, 0x8200); + tg3_writephy(tp, 0x16, 0x0000); + + tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x0400); + + tg3_writephy(tp, MII_TG3_CTRL, phy9_orig); + + tg3_readphy(tp, MII_TG3_EXT_CTRL, ®32); + reg32 &= ~0x3000; + tg3_writephy(tp, MII_TG3_EXT_CTRL, reg32); + + return err; +} + +/* This will reset the tigon3 PHY if there is no valid + * link unless the FORCE argument is non-zero. + */ +static int tg3_phy_reset(struct tg3 *tp, int force) +{ + u32 phy_status; + int err; + + err = tg3_readphy(tp, MII_BMSR, &phy_status); + err |= tg3_readphy(tp, MII_BMSR, &phy_status); + if (err != 0) + return -EBUSY; + + /* If we have link, and not forcing a reset, then nothing + * to do. + */ + if ((phy_status & BMSR_LSTATUS) != 0 && (force == 0)) + return 0; + + if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5703 || + GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704 || + GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705) { + err = tg3_phy_reset_5703_4_5(tp); + if (err) + return err; + goto out; + } + + err = tg3_bmcr_reset(tp); + if (err) + return err; + +out: + tg3_phy_set_wirespeed(tp); + return 0; +} + +static void tg3_frob_aux_power(struct tg3 *tp) +{ + struct tg3 *tp_peer = tp; + + if ((tp->tg3_flags & TG3_FLAG_EEPROM_WRITE_PROT) != 0) + return; + + if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704) { + tp_peer = pci_get_drvdata(tp->pdev_peer); + if (!tp_peer) + BUG(); + } + + + if ((tp->tg3_flags & TG3_FLAG_WOL_ENABLE) != 0 || + (tp_peer->tg3_flags & TG3_FLAG_WOL_ENABLE) != 0) { + if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5700 || + GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5701) { + tw32(GRC_LOCAL_CTRL, tp->grc_local_ctrl | + (GRC_LCLCTRL_GPIO_OE0 | + GRC_LCLCTRL_GPIO_OE1 | + GRC_LCLCTRL_GPIO_OE2 | + GRC_LCLCTRL_GPIO_OUTPUT0 | + GRC_LCLCTRL_GPIO_OUTPUT1)); + tr32(GRC_LOCAL_CTRL); + udelay(100); + } else { + if (tp_peer != tp && + (tp_peer->tg3_flags & TG3_FLAG_INIT_COMPLETE) != 0) + return; + + tw32(GRC_LOCAL_CTRL, tp->grc_local_ctrl | + (GRC_LCLCTRL_GPIO_OE0 | + GRC_LCLCTRL_GPIO_OE1 | + GRC_LCLCTRL_GPIO_OE2 | + GRC_LCLCTRL_GPIO_OUTPUT1 | + GRC_LCLCTRL_GPIO_OUTPUT2)); + tr32(GRC_LOCAL_CTRL); + udelay(100); + + tw32(GRC_LOCAL_CTRL, tp->grc_local_ctrl | + (GRC_LCLCTRL_GPIO_OE0 | + GRC_LCLCTRL_GPIO_OE1 | + GRC_LCLCTRL_GPIO_OE2 | + GRC_LCLCTRL_GPIO_OUTPUT0 | + GRC_LCLCTRL_GPIO_OUTPUT1 | + GRC_LCLCTRL_GPIO_OUTPUT2)); + tr32(GRC_LOCAL_CTRL); + udelay(100); + + tw32(GRC_LOCAL_CTRL, tp->grc_local_ctrl | + (GRC_LCLCTRL_GPIO_OE0 | + GRC_LCLCTRL_GPIO_OE1 | + GRC_LCLCTRL_GPIO_OE2 | + GRC_LCLCTRL_GPIO_OUTPUT0 | + GRC_LCLCTRL_GPIO_OUTPUT1)); + tr32(GRC_LOCAL_CTRL); + udelay(100); + } + } else { + if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5700 && + GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5701) { + if (tp_peer != tp && + (tp_peer->tg3_flags & TG3_FLAG_INIT_COMPLETE) != 0) + return; + + tw32(GRC_LOCAL_CTRL, tp->grc_local_ctrl | + (GRC_LCLCTRL_GPIO_OE1 | + GRC_LCLCTRL_GPIO_OUTPUT1)); + tr32(GRC_LOCAL_CTRL); + udelay(100); + + tw32(GRC_LOCAL_CTRL, tp->grc_local_ctrl | + (GRC_LCLCTRL_GPIO_OE1)); + tr32(GRC_LOCAL_CTRL); + udelay(100); + + tw32(GRC_LOCAL_CTRL, tp->grc_local_ctrl | + (GRC_LCLCTRL_GPIO_OE1 | + GRC_LCLCTRL_GPIO_OUTPUT1)); + tr32(GRC_LOCAL_CTRL); + udelay(100); + } + } } static int tg3_setup_phy(struct tg3 *); @@ -547,89 +845,65 @@ udelay(10); } - if (tp->tg3_flags & TG3_FLAG_WOL_SPEED_100MB) { + if (!(tp->tg3_flags & TG3_FLAG_WOL_SPEED_100MB) && + (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5700 || + GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5701)) { u32 base_val; - base_val = 0; - if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5700 || - GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5701) - base_val |= (CLOCK_CTRL_RXCLK_DISABLE | - CLOCK_CTRL_TXCLK_DISABLE); - - tw32(TG3PCI_CLOCK_CTRL, base_val | - CLOCK_CTRL_ALTCLK); - tr32(TG3PCI_CLOCK_CTRL); - udelay(40); + base_val = tp->pci_clock_ctrl; + base_val |= (CLOCK_CTRL_RXCLK_DISABLE | + CLOCK_CTRL_TXCLK_DISABLE); tw32(TG3PCI_CLOCK_CTRL, base_val | CLOCK_CTRL_ALTCLK | - CLOCK_CTRL_44MHZ_CORE); - tr32(TG3PCI_CLOCK_CTRL); - udelay(40); - - tw32(TG3PCI_CLOCK_CTRL, base_val | - CLOCK_CTRL_44MHZ_CORE); + CLOCK_CTRL_PWRDOWN_PLL133); tr32(TG3PCI_CLOCK_CTRL); udelay(40); } else { - u32 base_val; + u32 newbits1, newbits2; - base_val = 0; if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5700 || - GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5701) - base_val |= (CLOCK_CTRL_RXCLK_DISABLE | - CLOCK_CTRL_TXCLK_DISABLE); + GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5701) { + newbits1 = (CLOCK_CTRL_RXCLK_DISABLE | + CLOCK_CTRL_TXCLK_DISABLE | + CLOCK_CTRL_ALTCLK); + newbits2 = newbits1 | CLOCK_CTRL_44MHZ_CORE; + } else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705) { + newbits1 = CLOCK_CTRL_625_CORE; + newbits2 = newbits1 | CLOCK_CTRL_ALTCLK; + } else { + newbits1 = CLOCK_CTRL_ALTCLK; + newbits2 = newbits1 | CLOCK_CTRL_44MHZ_CORE; + } - tw32(TG3PCI_CLOCK_CTRL, base_val | - CLOCK_CTRL_ALTCLK | - CLOCK_CTRL_PWRDOWN_PLL133); + tw32(TG3PCI_CLOCK_CTRL, tp->pci_clock_ctrl | newbits1); tr32(TG3PCI_CLOCK_CTRL); udelay(40); - } - if (!(tp->tg3_flags & TG3_FLAG_EEPROM_WRITE_PROT) && - (tp->tg3_flags & TG3_FLAG_WOL_ENABLE)) { - if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5700 || - GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5701) { - tw32(GRC_LOCAL_CTRL, - (GRC_LCLCTRL_GPIO_OE0 | - GRC_LCLCTRL_GPIO_OE1 | - GRC_LCLCTRL_GPIO_OE2 | - GRC_LCLCTRL_GPIO_OUTPUT0 | - GRC_LCLCTRL_GPIO_OUTPUT1)); - tr32(GRC_LOCAL_CTRL); - udelay(100); - } else { - tw32(GRC_LOCAL_CTRL, - (GRC_LCLCTRL_GPIO_OE0 | - GRC_LCLCTRL_GPIO_OE1 | - GRC_LCLCTRL_GPIO_OE2 | - GRC_LCLCTRL_GPIO_OUTPUT1 | - GRC_LCLCTRL_GPIO_OUTPUT2)); - tr32(GRC_LOCAL_CTRL); - udelay(100); + tw32(TG3PCI_CLOCK_CTRL, tp->pci_clock_ctrl | newbits2); + tr32(TG3PCI_CLOCK_CTRL); + udelay(40); - tw32(GRC_LOCAL_CTRL, - (GRC_LCLCTRL_GPIO_OE0 | - GRC_LCLCTRL_GPIO_OE1 | - GRC_LCLCTRL_GPIO_OE2 | - GRC_LCLCTRL_GPIO_OUTPUT0 | - GRC_LCLCTRL_GPIO_OUTPUT1 | - GRC_LCLCTRL_GPIO_OUTPUT2)); - tr32(GRC_LOCAL_CTRL); - udelay(100); + if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5705) { + u32 newbits3; - tw32(GRC_LOCAL_CTRL, - (GRC_LCLCTRL_GPIO_OE0 | - GRC_LCLCTRL_GPIO_OE1 | - GRC_LCLCTRL_GPIO_OE2 | - GRC_LCLCTRL_GPIO_OUTPUT0 | - GRC_LCLCTRL_GPIO_OUTPUT1)); - tr32(GRC_LOCAL_CTRL); - udelay(100); + if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5700 || + GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5701) { + newbits3 = (CLOCK_CTRL_RXCLK_DISABLE | + CLOCK_CTRL_TXCLK_DISABLE | + CLOCK_CTRL_44MHZ_CORE); + } else { + newbits3 = CLOCK_CTRL_44MHZ_CORE; + } + + tw32(TG3PCI_CLOCK_CTRL, tp->pci_clock_ctrl | newbits3); + tr32(TG3PCI_CLOCK_CTRL); + udelay(40); } } + tg3_frob_aux_power(tp); + /* Finally, set the new power state. */ pci_write_config_word(tp->pdev, pm + PCI_PM_CTRL, power_control); @@ -948,11 +1222,10 @@ /* Some third-party PHYs need to be reset on link going * down. - * - * XXX 5705 note: This workaround also applies to 5705_a0 */ if ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5703 || - GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704) && + GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704 || + tp->pci_chip_rev_id == CHIPREV_ID_5705_A0) && netif_carrier_ok(tp->dev)) { tg3_readphy(tp, MII_BMSR, &bmsr); tg3_readphy(tp, MII_BMSR, &bmsr); @@ -1942,7 +2215,7 @@ int received; hw_idx = tp->hw_status->idx[0].rx_producer; - sw_idx = rx_rcb_ptr % TG3_RX_RCB_RING_SIZE; + sw_idx = rx_rcb_ptr % TG3_RX_RCB_RING_SIZE(tp); work_mask = 0; received = 0; while (sw_idx != hw_idx && budget > 0) { @@ -2043,13 +2316,13 @@ (*post_ptr)++; next_pkt_nopost: rx_rcb_ptr++; - sw_idx = rx_rcb_ptr % TG3_RX_RCB_RING_SIZE; + sw_idx = rx_rcb_ptr % TG3_RX_RCB_RING_SIZE(tp); } /* ACK the status ring. */ tp->rx_rcb_ptr = rx_rcb_ptr; tw32_mailbox(MAILBOX_RCVRET_CON_IDX_0 + TG3_64BIT_REG_LOW, - (rx_rcb_ptr % TG3_RX_RCB_RING_SIZE)); + (rx_rcb_ptr % TG3_RX_RCB_RING_SIZE(tp))); if (tp->tg3_flags & TG3_FLAG_MBOX_WRITE_REORDER) tr32(MAILBOX_RCVRET_CON_IDX_0 + TG3_64BIT_REG_LOW); @@ -2388,19 +2661,34 @@ base_flags = 0; if (skb->ip_summed == CHECKSUM_HW) base_flags |= TXD_FLAG_TCPUDP_CSUM; -#if TG3_DO_TSO != 0 - if ((mss = skb_shinfo(skb)->tso_size) != 0) { - static int times = 0; +#if TG3_TSO_SUPPORT != 0 + mss = 0; + if (skb->len > (tp->dev->mtu + ETH_HLEN) && + (mss = skb_shinfo(skb)->tso_size) != 0) { + int tcp_opt_len, ip_tcp_len; + + tcp_opt_len = ((skb->h.th->doff - 5) * 4); + ip_tcp_len = (skb->nh.iph->ihl * 4) + sizeof(struct tcphdr); - mss += ((skb->h.th->doff * 4) - 20); base_flags |= (TXD_FLAG_CPU_PRE_DMA | TXD_FLAG_CPU_POST_DMA); - if (times++ < 5) { - printk("tg3_xmit: tso_size[%u] tso_segs[%u] len[%u]\n", - (unsigned int) skb_shinfo(skb)->tso_size, - (unsigned int) skb_shinfo(skb)->tso_segs, - skb->len); + skb->nh.iph->check = 0; + skb->nh.iph->tot_len = ntohs(mss + ip_tcp_len + tcp_opt_len); + skb->h.th->check = ~csum_tcpudp_magic(skb->nh.iph->saddr, + skb->nh.iph->daddr, + 0, IPPROTO_TCP, 0); + + if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705) { + if (tcp_opt_len || skb->nh.iph->ihl > 5) { + int tsflags; + + tsflags = ((skb->nh.iph->ihl - 5) + + (tcp_opt_len >> 2)); + mss |= (tsflags << 11); + } + } else { + mss += tcp_opt_len; } } #else @@ -2580,23 +2868,34 @@ base_flags = 0; if (skb->ip_summed == CHECKSUM_HW) base_flags |= TXD_FLAG_TCPUDP_CSUM; -#if TG3_DO_TSO != 0 - if ((mss = skb_shinfo(skb)->tso_size) != 0) { - static int times = 0; +#if TG3_TSO_SUPPORT != 0 + mss = 0; + if (skb->len > (tp->dev->mtu + ETH_HLEN) && + (mss = skb_shinfo(skb)->tso_size) != 0) { + int tcp_opt_len, ip_tcp_len; - /* TSO firmware wants TCP options included in - * tx descriptor MSS value. - */ - mss += ((skb->h.th->doff * 4) - 20); + tcp_opt_len = ((skb->h.th->doff - 5) * 4); + ip_tcp_len = (skb->nh.iph->ihl * 4) + sizeof(struct tcphdr); base_flags |= (TXD_FLAG_CPU_PRE_DMA | TXD_FLAG_CPU_POST_DMA); - if (times++ < 5) { - printk("tg3_xmit: tso_size[%u] tso_segs[%u] len[%u]\n", - (unsigned int) skb_shinfo(skb)->tso_size, - (unsigned int) skb_shinfo(skb)->tso_segs, - skb->len); + skb->nh.iph->check = 0; + skb->nh.iph->tot_len = ntohs(mss + ip_tcp_len + tcp_opt_len); + skb->h.th->check = ~csum_tcpudp_magic(skb->nh.iph->saddr, + skb->nh.iph->daddr, + 0, IPPROTO_TCP, 0); + + if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705) { + if (tcp_opt_len || skb->nh.iph->ihl > 5) { + int tsflags; + + tsflags = ((skb->nh.iph->ihl - 5) + + (tcp_opt_len >> 2)); + mss |= (tsflags << 11); + } + } else { + mss += tcp_opt_len; } } #else @@ -2698,7 +2997,7 @@ { struct tg3 *tp = dev->priv; - if (new_mtu < TG3_MIN_MTU || new_mtu > TG3_MAX_MTU) + if (new_mtu < TG3_MIN_MTU || new_mtu > TG3_MAX_MTU(tp)) return -EINVAL; if (!netif_running(dev)) { @@ -2816,7 +3115,7 @@ /* Zero out all descriptors. */ memset(tp->rx_std, 0, TG3_RX_RING_BYTES); memset(tp->rx_jumbo, 0, TG3_RX_JUMBO_RING_BYTES); - memset(tp->rx_rcb, 0, TG3_RX_RCB_RING_BYTES); + memset(tp->rx_rcb, 0, TG3_RX_RCB_RING_BYTES(tp)); if (tp->tg3_flags & TG3_FLAG_HOST_TXDS) { memset(tp->tx_ring, 0, TG3_TX_RING_BYTES); @@ -2899,7 +3198,7 @@ tp->rx_jumbo = NULL; } if (tp->rx_rcb) { - pci_free_consistent(tp->pdev, TG3_RX_RCB_RING_BYTES, + pci_free_consistent(tp->pdev, TG3_RX_RCB_RING_BYTES(tp), tp->rx_rcb, tp->rx_rcb_mapping); tp->rx_rcb = NULL; } @@ -2957,7 +3256,7 @@ if (!tp->rx_jumbo) goto err_out; - tp->rx_rcb = pci_alloc_consistent(tp->pdev, TG3_RX_RCB_RING_BYTES, + tp->rx_rcb = pci_alloc_consistent(tp->pdev, TG3_RX_RCB_RING_BYTES(tp), &tp->rx_rcb_mapping); if (!tp->rx_rcb) goto err_out; @@ -3004,6 +3303,23 @@ unsigned int i; u32 val; + if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705) { + switch (ofs) { + case RCVLSC_MODE: + case DMAC_MODE: + case MBFREE_MODE: + case BUFMGR_MODE: + case MEMARB_MODE: + /* We can't enable/disable these bits of the + * 5705, just say success. + */ + return 0; + + default: + break; + }; + } + val = tr32(ofs); val &= ~enable_bit; tw32(ofs, val); @@ -3127,7 +3443,10 @@ tp->tg3_flags &= ~TG3_FLAG_5701_REG_WRITE_BUG; /* do the reset */ - tw32(GRC_MISC_CFG, GRC_MISC_CFG_CORECLK_RESET); + val = GRC_MISC_CFG_CORECLK_RESET; + if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705) + val |= GRC_MISC_CFG_KEEP_GPHY_POWER; + tw32(GRC_MISC_CFG, val); /* restore 5701 hardware bug workaround flag */ tp->tg3_flags = flags_save; @@ -3163,6 +3482,13 @@ tw32(MEMARB_MODE, MEMARB_MODE_ENABLE); + if ((tp->nic_sram_data_cfg & NIC_SRAM_DATA_CFG_MINI_PCI) != 0 && + GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705) { + tp->pci_clock_ctrl |= + (CLOCK_CTRL_FORCE_CLKRUN | CLOCK_CTRL_CLKRUN_OENABLE); + tw32(TG3PCI_CLOCK_CTRL, tp->pci_clock_ctrl); + } + tw32(TG3PCI_MISC_HOST_CTRL, tp->misc_host_ctrl); } @@ -3358,28 +3684,32 @@ #define TX_CPU_SCRATCH_SIZE 0x04000 /* tp->lock is held. */ -static int tg3_reset_cpu(struct tg3 *tp, u32 offset) +static int tg3_halt_cpu(struct tg3 *tp, u32 offset) { int i; - tw32(offset + CPU_STATE, 0xffffffff); - tw32(offset + CPU_MODE, CPU_MODE_RESET); + if (offset == TX_CPU_BASE && + GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705) + BUG(); + if (offset == RX_CPU_BASE) { - for (i = 0; i < 10000; i++) - if (!(tr32(offset + CPU_MODE) & CPU_MODE_RESET)) + for (i = 0; i < 10000; i++) { + tw32(offset + CPU_STATE, 0xffffffff); + tw32(offset + CPU_MODE, CPU_MODE_HALT); + if (tr32(offset + CPU_MODE) & CPU_MODE_HALT) break; + } + tw32(offset + CPU_STATE, 0xffffffff); - tw32(offset + CPU_MODE, CPU_MODE_RESET); + tw32(offset + CPU_MODE, CPU_MODE_HALT); tr32(offset + CPU_MODE); udelay(10); } else { for (i = 0; i < 10000; i++) { - if (!(tr32(offset + CPU_MODE) & CPU_MODE_RESET)) - break; tw32(offset + CPU_STATE, 0xffffffff); - tw32(offset + CPU_MODE, CPU_MODE_RESET); - tr32(offset + CPU_MODE); - udelay(10); + tw32(offset + CPU_MODE, CPU_MODE_HALT); + if (tr32(offset + CPU_MODE) & CPU_MODE_HALT) + break; } } @@ -3411,38 +3741,52 @@ { int err, i; u32 orig_tg3_flags = tp->tg3_flags; + void (*write_op)(struct tg3 *, u32, u32); + + if (cpu_base == TX_CPU_BASE && + GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705) { + printk(KERN_ERR PFX "tg3_load_firmware_cpu: Trying to load " + "TX cpu firmware on %s which is 5705.\n", + tp->dev->name); + return -EINVAL; + } + + if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705) + write_op = tg3_write_mem; + else + write_op = tg3_write_indirect_reg32; /* Force use of PCI config space for indirect register * write calls. */ tp->tg3_flags |= TG3_FLAG_PCIX_TARGET_HWBUG; - err = tg3_reset_cpu(tp, cpu_base); + err = tg3_halt_cpu(tp, cpu_base); if (err) goto out; for (i = 0; i < cpu_scratch_size; i += sizeof(u32)) - tg3_write_indirect_reg32(tp, cpu_scratch_base + i, 0); + write_op(tp, cpu_scratch_base + i, 0); tw32(cpu_base + CPU_STATE, 0xffffffff); tw32(cpu_base + CPU_MODE, tr32(cpu_base+CPU_MODE)|CPU_MODE_HALT); for (i = 0; i < (info->text_len / sizeof(u32)); i++) - tg3_write_indirect_reg32(tp, (cpu_scratch_base + - (info->text_base & 0xffff) + - (i * sizeof(u32))), - (info->text_data ? - info->text_data[i] : 0)); + write_op(tp, (cpu_scratch_base + + (info->text_base & 0xffff) + + (i * sizeof(u32))), + (info->text_data ? + info->text_data[i] : 0)); for (i = 0; i < (info->rodata_len / sizeof(u32)); i++) - tg3_write_indirect_reg32(tp, (cpu_scratch_base + - (info->rodata_base & 0xffff) + - (i * sizeof(u32))), - (info->rodata_data ? - info->rodata_data[i] : 0)); + write_op(tp, (cpu_scratch_base + + (info->rodata_base & 0xffff) + + (i * sizeof(u32))), + (info->rodata_data ? + info->rodata_data[i] : 0)); for (i = 0; i < (info->data_len / sizeof(u32)); i++) - tg3_write_indirect_reg32(tp, (cpu_scratch_base + - (info->data_base & 0xffff) + - (i * sizeof(u32))), - (info->data_data ? - info->data_data[i] : 0)); + write_op(tp, (cpu_scratch_base + + (info->data_base & 0xffff) + + (i * sizeof(u32))), + (info->data_data ? + info->data_data[i] : 0)); err = 0; @@ -3513,269 +3857,318 @@ return 0; } -#if TG3_DO_TSO != 0 +#if TG3_TSO_SUPPORT != 0 #define TG3_TSO_FW_RELEASE_MAJOR 0x1 -#define TG3_TSO_FW_RELASE_MINOR 0x8 +#define TG3_TSO_FW_RELASE_MINOR 0x3 #define TG3_TSO_FW_RELEASE_FIX 0x0 #define TG3_TSO_FW_START_ADDR 0x08000000 #define TG3_TSO_FW_TEXT_ADDR 0x08000000 -#define TG3_TSO_FW_TEXT_LEN 0x1650 +#define TG3_TSO_FW_TEXT_LEN 0x1ac0 #define TG3_TSO_FW_RODATA_ADDR 0x08001650 -#define TG3_TSO_FW_RODATA_LEN 0x30 +#define TG3_TSO_FW_RODATA_LEN 0x60 #define TG3_TSO_FW_DATA_ADDR 0x080016a0 #define TG3_TSO_FW_DATA_LEN 0x20 #define TG3_TSO_FW_SBSS_ADDR 0x080016c0 -#define TG3_TSO_FW_SBSS_LEN 0x14 +#define TG3_TSO_FW_SBSS_LEN 0x2c #define TG3_TSO_FW_BSS_ADDR 0x080016e0 -#define TG3_TSO_FW_BSS_LEN 0x8fc +#define TG3_TSO_FW_BSS_LEN 0x890 static u32 tg3TsoFwText[] = { 0x00000000, 0x10000003, 0x00000000, 0x0000000d, 0x0000000d, 0x3c1d0800, 0x37bd4000, 0x03a0f021, 0x3c100800, 0x26100000, 0x0e000010, 0x00000000, - 0x0000000d, 0x00000000, 0x00000000, 0x00000000, 0x27bdffe0, 0x3c1bc000, - 0xafbf0018, 0x0e000058, 0xaf60680c, 0x3c040800, 0x24841650, 0x03602821, - 0x24060001, 0x24070004, 0xafa00010, 0x0e00006c, 0xafa00014, 0x8f625c50, - 0x34420001, 0xaf625c50, 0x8f625c90, 0x34420001, 0xaf625c90, 0x2402ffff, - 0x0e000098, 0xaf625404, 0x8fbf0018, 0x03e00008, 0x27bd0020, 0x00000000, - 0x00000000, 0x00000000, 0x24030b60, 0x24050fff, 0xac000b50, 0x00002021, - 0xac640000, 0x24630004, 0x0065102b, 0x1440fffc, 0x24840001, 0x24030b60, - 0x0065102b, 0x10400011, 0x00002021, 0x24090b54, 0x3c06dead, 0x34c6beef, - 0x24080b58, 0x24070b5c, 0x8c620000, 0x50440006, 0x24630004, 0xad260000, - 0x8c620000, 0xace40000, 0xad020000, 0x24630004, 0x0065102b, 0x1440fff6, - 0x24840001, 0x03e00008, 0x00000000, 0x27bdfff8, 0x18800009, 0x00002821, - 0x8f63680c, 0x8f62680c, 0x1043fffe, 0x00000000, 0x24a50001, 0x00a4102a, - 0x1440fff9, 0x00000000, 0x03e00008, 0x27bd0008, 0x3c020800, 0x34423000, - 0x3c030800, 0x34633000, 0x3c040800, 0x348437ff, 0x3c010800, 0xac2216c4, - 0x24020040, 0x3c010800, 0xac2216c8, 0x3c010800, 0xac2016c0, 0xac600000, - 0x24630004, 0x0083102b, 0x5040fffd, 0xac600000, 0x03e00008, 0x00000000, - 0x00804821, 0x8faa0010, 0x3c020800, 0x8c4216c0, 0x3c040800, 0x8c8416c8, - 0x8fab0014, 0x24430001, 0x0044102b, 0x3c010800, 0xac2316c0, 0x14400003, - 0x00004021, 0x3c010800, 0xac2016c0, 0x3c020800, 0x8c4216c0, 0x3c030800, - 0x8c6316c4, 0x91240000, 0x00021140, 0x00431021, 0x00481021, 0x25080001, - 0xa0440000, 0x29020008, 0x1440fff4, 0x25290001, 0x3c020800, 0x8c4216c0, - 0x3c030800, 0x8c6316c4, 0x8f64680c, 0x00021140, 0x00431021, 0xac440008, - 0xac45000c, 0xac460010, 0xac470014, 0xac4a0018, 0x03e00008, 0xac4b001c, - 0x00000000, 0x00000000, 0x27bdffe0, 0xafbf0018, 0xafb10014, 0x0e0000b6, - 0xafb00010, 0x24110001, 0x8f706820, 0x32020100, 0x10400003, 0x00000000, - 0x0e000127, 0x00000000, 0x8f706820, 0x32022000, 0x10400004, 0x32020001, - 0x0e00025a, 0x24040001, 0x32020001, 0x10400003, 0x00000000, 0x0e0000e6, - 0x00000000, 0x0a00009e, 0xaf715028, 0x8fbf0018, 0x8fb10014, 0x8fb00010, - 0x03e00008, 0x27bd0020, 0x27bdffe0, 0x3c040800, 0x24841660, 0x00002821, - 0x00003021, 0x00003821, 0xafbf0018, 0xafa00010, 0x0e00006c, 0xafa00014, - 0x3c010800, 0xa4201fb8, 0x3c010800, 0xa02016f8, 0x3c010800, 0xac2016fc, - 0x3c010800, 0xac201700, 0x3c010800, 0xac201704, 0x3c010800, 0xac20170c, - 0x3c010800, 0xac201718, 0x3c010800, 0xac20171c, 0x8f624434, 0x3c010800, - 0xac2216e8, 0x8f624438, 0x3c010800, 0xac2216ec, 0x8f624410, 0x3c010800, - 0xac2016e0, 0x3c010800, 0xac2016e4, 0x3c010800, 0xac201fc0, 0x3c010800, - 0xac201f68, 0x3c010800, 0xac201f6c, 0x3c010800, 0xac2216f0, 0x8fbf0018, - 0x03e00008, 0x27bd0020, 0x27bdffe0, 0x3c040800, 0x2484166c, 0x00002821, - 0x00003021, 0x00003821, 0xafbf0018, 0xafa00010, 0x0e00006c, 0xafa00014, - 0x3c040800, 0x24841660, 0x00002821, 0x00003021, 0x00003821, 0xafa00010, - 0x0e00006c, 0xafa00014, 0x3c010800, 0xa4201fb8, 0x3c010800, 0xa02016f8, - 0x3c010800, 0xac2016fc, 0x3c010800, 0xac201700, 0x3c010800, 0xac201704, - 0x3c010800, 0xac20170c, 0x3c010800, 0xac201718, 0x3c010800, 0xac20171c, - 0x8f624434, 0x3c010800, 0xac2216e8, 0x8f624438, 0x3c010800, 0xac2216ec, - 0x8f624410, 0x3c010800, 0xac2016e0, 0x3c010800, 0xac2016e4, 0x3c010800, - 0xac201fc0, 0x3c010800, 0xac201f68, 0x3c010800, 0xac201f6c, 0x3c010800, - 0xac2216f0, 0x0e000120, 0x00002021, 0x8fbf0018, 0x03e00008, 0x27bd0020, - 0x24020001, 0x8f636820, 0x00821004, 0x00021027, 0x00621824, 0x03e00008, - 0xaf636820, 0x27bdffd0, 0x3c0300ff, 0xafbf002c, 0xafb60028, 0xafb50024, - 0xafb40020, 0xafb3001c, 0xafb20018, 0xafb10014, 0xafb00010, 0x8f665c5c, - 0x3c040800, 0x2484171c, 0x8c820000, 0x3463fff8, 0x14460005, 0x00c38824, - 0x3c020800, 0x904216f8, 0x14400115, 0x00000000, 0x00111902, 0x306300ff, - 0x30c20003, 0x000211c0, 0x00623825, 0x00e02821, 0x00061602, 0xac860000, - 0x3c030800, 0x906316f8, 0x3044000f, 0x1460002b, 0x00804021, 0x24020001, - 0x3c010800, 0xa02216f8, 0x00071100, 0x00821025, 0x3c010800, 0xac2016fc, - 0x3c010800, 0xac201700, 0x3c010800, 0xac201704, 0x3c010800, 0xac20170c, - 0x3c010800, 0xac201718, 0x3c010800, 0xac201710, 0x3c010800, 0xac201714, - 0x3c010800, 0xa4221fb8, 0x9623000c, 0x30628000, 0x10400008, 0x30627fff, - 0x2442003e, 0x3c010800, 0xa42216f6, 0x24020001, 0x3c010800, 0x0a00016e, - 0xac221fd4, 0x24620036, 0x3c010800, 0xa42216f6, 0x3c010800, 0xac201fd4, - 0x3c010800, 0xac201fd0, 0x3c010800, 0x0a000176, 0xac201fd8, 0x9622000c, - 0x3c010800, 0xa4221fcc, 0x3c040800, 0x248416fc, 0x8c820000, 0x00021100, - 0x3c010800, 0x00220821, 0xac311728, 0x8c820000, 0x00021100, 0x3c010800, - 0x00220821, 0xac26172c, 0x8c820000, 0x24a30001, 0x306701ff, 0x00021100, - 0x3c010800, 0x00220821, 0xac271730, 0x8c820000, 0x00021100, 0x3c010800, - 0x00220821, 0xac281734, 0x96230008, 0x3c020800, 0x8c42170c, 0x00432821, - 0x3c010800, 0xac25170c, 0x9622000a, 0x30420004, 0x14400019, 0x00071100, - 0x3c02c000, 0x00c21825, 0xaf635c5c, 0x8f625c50, 0x30420002, 0x1440fffc, - 0x00000000, 0x8f630c14, 0x3063000f, 0x2c620002, 0x1440001e, 0x00000000, - 0x8f630c14, 0x3c020800, 0x8c4216b4, 0x3063000f, 0x24420001, 0x3c010800, - 0xac2216b4, 0x2c620002, 0x1040fff7, 0x00000000, 0x0a0001c1, 0x00000000, - 0x3c030800, 0x8c6316e0, 0x3c040800, 0x948416f4, 0x01021025, 0x3c010800, - 0xa4221fba, 0x24020001, 0x3c010800, 0xac221718, 0x24630001, 0x0085202a, - 0x3c010800, 0x10800003, 0xac2316e0, 0x3c010800, 0xa42516f4, 0x3c030800, - 0x246316fc, 0x8c620000, 0x24420001, 0xac620000, 0x28420080, 0x14400005, - 0x24020001, 0x0e0002df, 0x24040002, 0x0a000250, 0x00000000, 0x3c030800, - 0x906316f8, 0x1462007c, 0x24020003, 0x3c160800, 0x96d616f6, 0x3c050800, - 0x8ca5170c, 0x32c4ffff, 0x00a4102a, 0x14400078, 0x00000000, 0x3c020800, - 0x8c421718, 0x10400005, 0x32c2ffff, 0x14a40003, 0x00000000, 0x3c010800, - 0xac231fd0, 0x10400062, 0x00009021, 0x0040a021, 0x3c150800, 0x26b51700, - 0x26b30010, 0x8ea20000, 0x00028100, 0x3c110800, 0x02308821, 0x0e0002e1, - 0x8e311728, 0x00403021, 0x10c00059, 0x00000000, 0x9628000a, 0x31020040, - 0x10400004, 0x2407180c, 0x8e22000c, 0x2407188c, 0xacc20018, 0x31021000, - 0x10400004, 0x34e32000, 0x00081040, 0x3042c000, 0x00623825, 0x3c030800, - 0x00701821, 0x8c631730, 0x3c020800, 0x00501021, 0x8c421734, 0x00031d00, - 0x00021400, 0x00621825, 0xacc30014, 0x8ea30004, 0x96220008, 0x00432023, - 0x3242ffff, 0x3083ffff, 0x00431021, 0x0282102a, 0x14400002, 0x02d22823, - 0x00802821, 0x8e620000, 0x30a4ffff, 0x00441021, 0xae620000, 0x8e220000, - 0xacc20000, 0x8e220004, 0x8e63fff4, 0x00431021, 0xacc20004, 0xa4c5000e, - 0x8e62fff4, 0x00441021, 0xae62fff4, 0x96230008, 0x0043102a, 0x14400005, - 0x02459021, 0x8e62fff0, 0xae60fff4, 0x24420001, 0xae62fff0, 0xacc00008, - 0x3242ffff, 0x14540008, 0x24020305, 0x31020080, 0x54400001, 0x34e70010, - 0x24020905, 0xa4c2000c, 0x0a000233, 0x34e70020, 0xa4c2000c, 0x30e2ffff, - 0xacc20010, 0x3c020800, 0x8c421fd0, 0x10400003, 0x3c024b65, 0x0a00023d, - 0x34427654, 0x3c02b49a, 0x344289ab, 0xacc2001c, 0x0e000560, 0x00c02021, - 0x3242ffff, 0x0054102b, 0x1440ffa4, 0x00000000, 0x24020002, 0x3c010800, - 0x0a000250, 0xa02216f8, 0x8ea208bc, 0x24420001, 0x0a000250, 0xaea208bc, - 0x14620003, 0x00000000, 0x0e000450, 0x00000000, 0x8fbf002c, 0x8fb60028, - 0x8fb50024, 0x8fb40020, 0x8fb3001c, 0x8fb20018, 0x8fb10014, 0x8fb00010, - 0x03e00008, 0x27bd0030, 0x27bdffd8, 0xafb3001c, 0x00809821, 0xafbf0020, - 0xafb20018, 0xafb10014, 0xafb00010, 0x8f725c9c, 0x3c0200ff, 0x3442fff8, - 0x3c040800, 0x24841714, 0x02428824, 0x9623000e, 0x8c820000, 0x00431021, - 0xac820000, 0x8e220010, 0x30420020, 0x14400011, 0x00000000, 0x0e0002f7, + 0x0000000d, 0x00000000, 0x00000000, 0x00000000, 0x27bdffe0, 0x3c04fefe, + 0xafbf0018, 0x0e0005e0, 0x34840002, 0x0e000670, 0x00000000, 0x3c030800, + 0x90631b78, 0x24020002, 0x3c040800, 0x24841acc, 0x14620003, 0x24050001, + 0x3c040800, 0x24841ac0, 0x24060002, 0x00003821, 0xafa00010, 0x0e000684, + 0xafa00014, 0x8f625c50, 0x34420001, 0xaf625c50, 0x8f625c90, 0x34420001, + 0xaf625c90, 0x2402ffff, 0x0e000034, 0xaf625404, 0x8fbf0018, 0x03e00008, + 0x27bd0020, 0x00000000, 0x00000000, 0x00000000, 0x27bdffe0, 0xafbf0018, + 0xafb10014, 0x0e000052, 0xafb00010, 0x24110001, 0x8f706820, 0x32020100, + 0x10400003, 0x00000000, 0x0e0000b2, 0x00000000, 0x8f706820, 0x32022000, + 0x10400004, 0x32020001, 0x0e0001e3, 0x24040001, 0x32020001, 0x10400003, + 0x00000000, 0x0e00009a, 0x00000000, 0x0a00003a, 0xaf715028, 0x8fbf0018, + 0x8fb10014, 0x8fb00010, 0x03e00008, 0x27bd0020, 0x27bdffe0, 0x3c040800, + 0x24841ae0, 0x00002821, 0x00003021, 0x00003821, 0xafbf0018, 0xafa00010, + 0x0e000684, 0xafa00014, 0x3c040800, 0x248423e8, 0xa4800000, 0x3c010800, + 0xa0201ba8, 0x3c010800, 0xac201bac, 0x3c010800, 0xac201bb0, 0x3c010800, + 0xac201bb4, 0x3c010800, 0xac201bbc, 0x3c010800, 0xac201bc8, 0x3c010800, + 0xac201bcc, 0x8f624434, 0x3c010800, 0xac221b98, 0x8f624438, 0x3c010800, + 0xac221b9c, 0x8f624410, 0xac80f7a8, 0x3c010800, 0xac201b94, 0x3c010800, + 0xac2023f0, 0x3c010800, 0xac2023d8, 0x3c010800, 0xac2023dc, 0x3c010800, + 0xac202410, 0x3c010800, 0xac221ba0, 0x8f620068, 0x24030007, 0x00021702, + 0x10430005, 0x00000000, 0x8f620068, 0x00021702, 0x14400004, 0x24020001, + 0x3c010800, 0x0a00008e, 0xac20241c, 0xac820034, 0x3c040800, 0x24841aec, + 0x3c050800, 0x8ca5241c, 0x00003021, 0x00003821, 0xafa00010, 0x0e000684, + 0xafa00014, 0x8fbf0018, 0x03e00008, 0x27bd0020, 0x27bdffe0, 0x3c040800, + 0x24841af8, 0x00002821, 0x00003021, 0x00003821, 0xafbf0018, 0xafa00010, + 0x0e000684, 0xafa00014, 0x0e000052, 0x00000000, 0x0e0000ab, 0x00002021, + 0x8fbf0018, 0x03e00008, 0x27bd0020, 0x24020001, 0x8f636820, 0x00821004, + 0x00021027, 0x00621824, 0x03e00008, 0xaf636820, 0x27bdffd0, 0xafbf002c, + 0xafb60028, 0xafb50024, 0xafb40020, 0xafb3001c, 0xafb20018, 0xafb10014, + 0xafb00010, 0x8f665c5c, 0x3c030800, 0x24631bcc, 0x8c620000, 0x14460005, + 0x3c0200ff, 0x3c020800, 0x90421ba8, 0x14400115, 0x3c0200ff, 0x3442fff8, + 0x00c28824, 0xac660000, 0x00111902, 0x306300ff, 0x30c20003, 0x000211c0, + 0x00623825, 0x00e02821, 0x00061602, 0x3c030800, 0x90631ba8, 0x3044000f, + 0x1460002b, 0x00804021, 0x24020001, 0x3c010800, 0xa0221ba8, 0x00071100, + 0x00821025, 0x3c010800, 0xac201bac, 0x3c010800, 0xac201bb0, 0x3c010800, + 0xac201bb4, 0x3c010800, 0xac201bbc, 0x3c010800, 0xac201bc8, 0x3c010800, + 0xac201bc0, 0x3c010800, 0xac201bc4, 0x3c010800, 0xa42223e8, 0x9623000c, + 0x30628000, 0x10400008, 0x30627fff, 0x2442003e, 0x3c010800, 0xa4221ba6, + 0x24020001, 0x3c010800, 0x0a0000f9, 0xac222404, 0x24620036, 0x3c010800, + 0xa4221ba6, 0x3c010800, 0xac202404, 0x3c010800, 0xac202400, 0x3c010800, + 0x0a000101, 0xac202408, 0x9622000c, 0x3c010800, 0xa42223fc, 0x3c040800, + 0x24841bac, 0x8c820000, 0x00021100, 0x3c010800, 0x00220821, 0xac311bd8, + 0x8c820000, 0x00021100, 0x3c010800, 0x00220821, 0xac261bdc, 0x8c820000, + 0x24a30001, 0x306701ff, 0x00021100, 0x3c010800, 0x00220821, 0xac271be0, + 0x8c820000, 0x00021100, 0x3c010800, 0x00220821, 0xac281be4, 0x96230008, + 0x3c020800, 0x8c421bbc, 0x00432821, 0x3c010800, 0xac251bbc, 0x9622000a, + 0x30420004, 0x14400018, 0x00071100, 0x8f630c14, 0x3063000f, 0x2c620002, + 0x1440000b, 0x3c02c000, 0x8f630c14, 0x3c020800, 0x8c421b50, 0x3063000f, + 0x24420001, 0x3c010800, 0xac221b50, 0x2c620002, 0x1040fff7, 0x3c02c000, + 0x00c21825, 0xaf635c5c, 0x8f625c50, 0x30420002, 0x10400014, 0x00000000, + 0x0a000133, 0x00000000, 0x3c030800, 0x8c631b90, 0x3c040800, 0x94841ba4, + 0x01021025, 0x3c010800, 0xa42223ea, 0x24020001, 0x3c010800, 0xac221bc8, + 0x24630001, 0x0085202a, 0x3c010800, 0x10800003, 0xac231b90, 0x3c010800, + 0xa4251ba4, 0x3c060800, 0x24c61bac, 0x8cc20000, 0x24420001, 0xacc20000, + 0x28420080, 0x14400005, 0x00000000, 0x0e00065e, 0x24040002, 0x0a0001d9, + 0x00000000, 0x3c020800, 0x8c421bc8, 0x1040007f, 0x24020001, 0x3c040800, + 0x90841ba8, 0x14820077, 0x24020003, 0x3c150800, 0x96b51ba6, 0x3c050800, + 0x8ca51bbc, 0x32a3ffff, 0x00a3102a, 0x14400073, 0x00000000, 0x14a30003, + 0x00000000, 0x3c010800, 0xac242400, 0x10600061, 0x00009021, 0x24d60004, + 0x0060a021, 0x24d30014, 0x8ec20000, 0x00028100, 0x3c110800, 0x02308821, + 0x0e00062d, 0x8e311bd8, 0x00403021, 0x10c00059, 0x00000000, 0x9628000a, + 0x31020040, 0x10400004, 0x2407180c, 0x8e22000c, 0x2407188c, 0xacc20018, + 0x31021000, 0x10400004, 0x34e32000, 0x00081040, 0x3042c000, 0x00623825, + 0x3c030800, 0x00701821, 0x8c631be0, 0x3c020800, 0x00501021, 0x8c421be4, + 0x00031d00, 0x00021400, 0x00621825, 0xacc30014, 0x8ec30004, 0x96220008, + 0x00432023, 0x3242ffff, 0x3083ffff, 0x00431021, 0x0282102a, 0x14400002, + 0x02b22823, 0x00802821, 0x8e620000, 0x30a4ffff, 0x00441021, 0xae620000, + 0x8e220000, 0xacc20000, 0x8e220004, 0x8e63fff4, 0x00431021, 0xacc20004, + 0xa4c5000e, 0x8e62fff4, 0x00441021, 0xae62fff4, 0x96230008, 0x0043102a, + 0x14400005, 0x02459021, 0x8e62fff0, 0xae60fff4, 0x24420001, 0xae62fff0, + 0xacc00008, 0x3242ffff, 0x14540008, 0x24020305, 0x31020080, 0x54400001, + 0x34e70010, 0x24020905, 0xa4c2000c, 0x0a0001bc, 0x34e70020, 0xa4c2000c, + 0x3c020800, 0x8c422400, 0x10400003, 0x3c024b65, 0x0a0001c4, 0x34427654, + 0x3c02b49a, 0x344289ab, 0xacc2001c, 0x30e2ffff, 0xacc20010, 0x0e0005aa, + 0x00c02021, 0x3242ffff, 0x0054102b, 0x1440ffa4, 0x00000000, 0x24020002, + 0x3c010800, 0x0a0001d9, 0xa0221ba8, 0x8ec2083c, 0x24420001, 0x0a0001d9, + 0xaec2083c, 0x14820003, 0x00000000, 0x0e0004b9, 0x00000000, 0x8fbf002c, + 0x8fb60028, 0x8fb50024, 0x8fb40020, 0x8fb3001c, 0x8fb20018, 0x8fb10014, + 0x8fb00010, 0x03e00008, 0x27bd0030, 0x27bdffd0, 0xafbf0028, 0xafb30024, + 0xafb20020, 0xafb1001c, 0xafb00018, 0x8f725c9c, 0x3c0200ff, 0x3442fff8, + 0x3c060800, 0x24c61bc4, 0x02428824, 0x9623000e, 0x8cc20000, 0x00431021, + 0xacc20000, 0x8e220010, 0x30420020, 0x14400011, 0x00809821, 0x0e000643, 0x02202021, 0x3c02c000, 0x02421825, 0xaf635c9c, 0x8f625c90, 0x30420002, - 0x10400061, 0x00000000, 0xaf635c9c, 0x8f625c90, 0x30420002, 0x1040005c, - 0x00000000, 0x0a000278, 0x00000000, 0x8e220008, 0x00021c02, 0x000321c0, - 0x3042ffff, 0x3c030800, 0x906316f8, 0x000229c0, 0x24020002, 0x14620003, - 0x3c034b65, 0x0a000290, 0x00008021, 0x8e22001c, 0x34637654, 0x10430002, - 0x24100002, 0x24100001, 0x0e000300, 0x02003021, 0x24020003, 0x3c010800, - 0xa02216f8, 0x24020002, 0x1202000a, 0x24020001, 0x3c030800, 0x8c631fd0, - 0x10620006, 0x00000000, 0x3c020800, 0x94421fb8, 0x00021400, 0x0a0002cd, - 0xae220014, 0x3c040800, 0x24841fba, 0x94820000, 0x00021400, 0xae220014, - 0x3c020800, 0x8c42171c, 0x3c03c000, 0x3c010800, 0xa02016f8, 0x00431025, - 0xaf625c5c, 0x8f625c50, 0x30420002, 0x10400009, 0x00000000, 0x2484f762, + 0x10400121, 0x00000000, 0xaf635c9c, 0x8f625c90, 0x30420002, 0x1040011c, + 0x00000000, 0x0a000200, 0x00000000, 0x8e240008, 0x8e230014, 0x00041402, + 0x000241c0, 0x00031502, 0x304201ff, 0x2442ffff, 0x3042007f, 0x00031942, + 0x30637800, 0x00021100, 0x24424000, 0x00625021, 0x9542000a, 0x3084ffff, + 0x30420008, 0x104000b3, 0x000429c0, 0x3c020800, 0x8c422410, 0x1440002d, + 0x25050008, 0x95020014, 0x3c010800, 0xa42223e0, 0x8d070010, 0x00071402, + 0x3c010800, 0xa42223e2, 0x3c010800, 0xa42723e4, 0x9502000e, 0x30e3ffff, + 0x00431023, 0x3c010800, 0xac222418, 0x8f626800, 0x3c030010, 0x00431024, + 0x10400005, 0x00000000, 0x9503001a, 0x9502001c, 0x0a000235, 0x00431021, + 0x9502001a, 0x3c010800, 0xac22240c, 0x3c02c000, 0x02421825, 0x3c010800, + 0xac282410, 0x3c010800, 0xac322414, 0xaf635c9c, 0x8f625c90, 0x30420002, + 0x104000df, 0x00000000, 0xaf635c9c, 0x8f625c90, 0x30420002, 0x104000da, + 0x00000000, 0x0a000242, 0x00000000, 0x9502000e, 0x3c030800, 0x946323e4, + 0x00434823, 0x3123ffff, 0x2c620008, 0x1040001c, 0x00000000, 0x95020014, + 0x24420028, 0x00a22821, 0x00031042, 0x1840000b, 0x00002021, 0x24c60848, + 0x00403821, 0x94a30000, 0x8cc20000, 0x24840001, 0x00431021, 0xacc20000, + 0x0087102a, 0x1440fff9, 0x24a50002, 0x31220001, 0x1040001f, 0x3c024000, + 0x3c040800, 0x2484240c, 0xa0a00001, 0x94a30000, 0x8c820000, 0x00431021, + 0x0a000281, 0xac820000, 0x8f626800, 0x3c030010, 0x00431024, 0x10400009, + 0x00000000, 0x9502001a, 0x3c030800, 0x8c63240c, 0x00431021, 0x3c010800, + 0xac22240c, 0x0a000282, 0x3c024000, 0x9502001a, 0x9504001c, 0x3c030800, + 0x8c63240c, 0x00441023, 0x00621821, 0x3c010800, 0xac23240c, 0x3c024000, + 0x02421825, 0xaf635c9c, 0x8f625c90, 0x30420002, 0x1440fffc, 0x00000000, + 0x9542000a, 0x30420010, 0x10400095, 0x00000000, 0x3c060800, 0x24c62410, + 0x3c020800, 0x944223e4, 0x8cc50000, 0x3c040800, 0x8c842418, 0x24420030, + 0x00a22821, 0x94a20004, 0x3c030800, 0x8c63240c, 0x00441023, 0x00621821, + 0x00603821, 0x00032402, 0x30e2ffff, 0x00823821, 0x00071402, 0x00e23821, + 0x00071027, 0x3c010800, 0xac23240c, 0xa4a20006, 0x3c030800, 0x8c632414, + 0x3c0200ff, 0x3442fff8, 0x00628824, 0x96220008, 0x24040001, 0x24034000, + 0x000241c0, 0x00e01021, 0xa502001a, 0xa500001c, 0xacc00000, 0x3c010800, + 0xac241b70, 0xaf635cb8, 0x8f625cb0, 0x30420002, 0x10400003, 0x00000000, + 0x3c010800, 0xac201b70, 0x8e220008, 0xaf625cb8, 0x8f625cb0, 0x30420002, + 0x10400003, 0x00000000, 0x3c010800, 0xac201b70, 0x3c020800, 0x8c421b70, + 0x1040ffec, 0x00000000, 0x3c040800, 0x0e000643, 0x8c842414, 0x0a000320, + 0x00000000, 0x3c030800, 0x90631ba8, 0x24020002, 0x14620003, 0x3c034b65, + 0x0a0002d7, 0x00008021, 0x8e22001c, 0x34637654, 0x10430002, 0x24100002, + 0x24100001, 0x01002021, 0x0e000346, 0x02003021, 0x24020003, 0x3c010800, + 0xa0221ba8, 0x24020002, 0x1202000a, 0x24020001, 0x3c030800, 0x8c632400, + 0x10620006, 0x00000000, 0x3c020800, 0x944223e8, 0x00021400, 0x0a000315, + 0xae220014, 0x3c040800, 0x248423ea, 0x94820000, 0x00021400, 0xae220014, + 0x3c020800, 0x8c421bcc, 0x3c03c000, 0x3c010800, 0xa0201ba8, 0x00431025, + 0xaf625c5c, 0x8f625c50, 0x30420002, 0x10400009, 0x00000000, 0x2484f7e2, 0x8c820000, 0x00431025, 0xaf625c5c, 0x8f625c50, 0x30420002, 0x1440fffa, - 0x00000000, 0x3c020800, 0x244216e4, 0x8c430000, 0x24630001, 0xac430000, - 0x8f630c14, 0x3063000f, 0x2c620002, 0x1440000b, 0x00009821, 0x8f630c14, - 0x3c020800, 0x8c4216b4, 0x3063000f, 0x24420001, 0x3c010800, 0xac2216b4, - 0x2c620002, 0x1040fff7, 0x00009821, 0x3c024000, 0x02421825, 0xaf635c9c, + 0x00000000, 0x3c020800, 0x24421b94, 0x8c430000, 0x24630001, 0xac430000, + 0x8f630c14, 0x3063000f, 0x2c620002, 0x1440000c, 0x3c024000, 0x8f630c14, + 0x3c020800, 0x8c421b50, 0x3063000f, 0x24420001, 0x3c010800, 0xac221b50, + 0x2c620002, 0x1040fff7, 0x00000000, 0x3c024000, 0x02421825, 0xaf635c9c, 0x8f625c90, 0x30420002, 0x1440fffc, 0x00000000, 0x12600003, 0x00000000, - 0x0e000450, 0x00000000, 0x8fbf0020, 0x8fb3001c, 0x8fb20018, 0x8fb10014, - 0x8fb00010, 0x03e00008, 0x27bd0028, 0x0a0002df, 0x00000000, 0x8f634450, - 0x3c040800, 0x248416e8, 0x8c820000, 0x00031c02, 0x0043102b, 0x14400007, - 0x3c038000, 0x8c840004, 0x8f624450, 0x00021c02, 0x0083102b, 0x1040fffc, - 0x3c038000, 0xaf634444, 0x8f624444, 0x00431024, 0x1440fffd, 0x00000000, - 0x8f624448, 0x03e00008, 0x3042ffff, 0x3c024000, 0x00822025, 0xaf645c38, - 0x8f625c30, 0x30420002, 0x1440fffc, 0x00000000, 0x03e00008, 0x00000000, - 0x27bdffe0, 0x00805021, 0x14c00017, 0x254c0008, 0x3c020800, 0x8c421fd4, - 0x1040000a, 0x2402003e, 0x3c010800, 0xa4221fb0, 0x24020016, 0x3c010800, - 0xa4221fb2, 0x2402002a, 0x3c010800, 0x0a00031a, 0xa4221fb4, 0x95420014, - 0x3c010800, 0xa4221fb0, 0x8d430010, 0x00031402, 0x3c010800, 0xa4221fb2, - 0x3c010800, 0xa4231fb4, 0x3c040800, 0x94841fb4, 0x3c030800, 0x94631fb2, - 0x958d0006, 0x3c020800, 0x94421fb0, 0x00832023, 0x01a27023, 0x3065ffff, - 0x24a20028, 0x01824021, 0x3082ffff, 0x14c0001a, 0x01025821, 0x9562000c, - 0x3042003f, 0x3c010800, 0xa4221fb6, 0x95620004, 0x95630006, 0x3c010800, - 0xac201fc4, 0x3c010800, 0xac201fc8, 0x00021400, 0x00431025, 0x3c010800, - 0xac221720, 0x95020004, 0x3c010800, 0xa4221724, 0x95030002, 0x01a51023, - 0x0043102a, 0x10400010, 0x24020001, 0x3c010800, 0x0a00034e, 0xac221fd8, - 0x3c030800, 0x8c631fc8, 0x3c020800, 0x94421724, 0x00431021, 0xa5020004, - 0x3c020800, 0x94421720, 0xa5620004, 0x3c020800, 0x8c421720, 0xa5620006, - 0x3c020800, 0x8c421fd0, 0x3c070800, 0x8ce71fc4, 0x3c050800, 0x144000c7, - 0x8ca51fc8, 0x3c020800, 0x94421724, 0x00451821, 0x3063ffff, 0x0062182b, - 0x24020002, 0x10c2000d, 0x00a32823, 0x3c020800, 0x94421fb6, 0x30420009, - 0x10400008, 0x00000000, 0x9562000c, 0x3042fff6, 0xa562000c, 0x3c020800, - 0x94421fb6, 0x30420009, 0x00e23823, 0x3c020800, 0x8c421fd8, 0x1040004b, - 0x24020002, 0x01003021, 0x3c020800, 0x94421fb2, 0x00003821, 0xa500000a, - 0x01a21023, 0xa5020002, 0x3082ffff, 0x00021042, 0x18400008, 0x00002821, - 0x00401821, 0x94c20000, 0x24e70001, 0x00a22821, 0x00e3102a, 0x1440fffb, - 0x24c60002, 0x00051c02, 0x30a2ffff, 0x00622821, 0x00051402, 0x00a22821, - 0x00a04821, 0x00051027, 0xa502000a, 0x00002821, 0x2506000c, 0x00003821, - 0x94c20000, 0x24e70001, 0x00a22821, 0x2ce20004, 0x1440fffb, 0x24c60002, - 0x95020002, 0x00003821, 0x91030009, 0x00442023, 0x01603021, 0x3082ffff, - 0xa4c00010, 0x00621821, 0x00021042, 0x18400010, 0x00a32821, 0x00404021, - 0x94c20000, 0x24c60002, 0x00a22821, 0x30c2007f, 0x14400006, 0x24e70001, - 0x8d430000, 0x3c02007f, 0x3442ff80, 0x00625024, 0x25460008, 0x00e8102a, - 0x1440fff3, 0x00000000, 0x30820001, 0x10400005, 0x00051c02, 0xa0c00001, - 0x94c20000, 0x00a22821, 0x00051c02, 0x30a2ffff, 0x00622821, 0x00051402, - 0x00a22821, 0x0a000415, 0x30a5ffff, 0x14c20063, 0x00000000, 0x3c090800, - 0x95291fb2, 0x95030002, 0x01a91023, 0x1062005d, 0x01003021, 0x00003821, - 0x00002821, 0x01a91023, 0xa5020002, 0x3082ffff, 0x00021042, 0x18400008, - 0xa500000a, 0x00401821, 0x94c20000, 0x24e70001, 0x00a22821, 0x00e3102a, - 0x1440fffb, 0x24c60002, 0x00051c02, 0x30a2ffff, 0x00622821, 0x00051402, - 0x00a22821, 0x00a04821, 0x00051027, 0xa502000a, 0x00002821, 0x2506000c, - 0x00003821, 0x94c20000, 0x24e70001, 0x00a22821, 0x2ce20004, 0x1440fffb, - 0x24c60002, 0x95020002, 0x00003821, 0x91030009, 0x00442023, 0x01603021, - 0x3082ffff, 0xa4c00010, 0x3c040800, 0x94841fb4, 0x00621821, 0x00a32821, - 0x00051c02, 0x30a2ffff, 0x00622821, 0x00051c02, 0x3c020800, 0x94421fb0, - 0x00a34021, 0x00441023, 0x00021fc2, 0x00431021, 0x00021043, 0x18400010, - 0x00002821, 0x00402021, 0x94c20000, 0x24c60002, 0x00a22821, 0x30c2007f, - 0x14400006, 0x24e70001, 0x8d430000, 0x3c02007f, 0x3442ff80, 0x00625024, - 0x25460008, 0x00e4102a, 0x1440fff3, 0x00000000, 0x3c020800, 0x94421fcc, - 0x00a22821, 0x00051c02, 0x30a2ffff, 0x00622821, 0x00051402, 0x00a22821, - 0x3102ffff, 0x00a22821, 0x00051c02, 0x30a2ffff, 0x00622821, 0x00051402, - 0x00a22821, 0x00a02021, 0x00051027, 0xa5620010, 0xad800014, 0x0a000435, - 0xad800000, 0x8d830010, 0x00602021, 0x10a00007, 0x00034c02, 0x01252821, - 0x00051402, 0x30a3ffff, 0x00432821, 0x00051402, 0x00a24821, 0x00091027, - 0xa502000a, 0x3c030800, 0x94631fb4, 0x3082ffff, 0x01a21021, 0x00432823, - 0x00a72821, 0x00051c02, 0x30a2ffff, 0x00622821, 0x00051402, 0x00a22821, - 0x00a02021, 0x00051027, 0xa5620010, 0x3082ffff, 0x00091c00, 0x00431025, - 0xad820010, 0x3c020800, 0x8c421fd4, 0x10400002, 0x25a2fff2, 0xa5820034, - 0x3c020800, 0x8c421fc8, 0x3c030800, 0x8c631720, 0x24420001, 0x3c010800, - 0xac221fc8, 0x3c020800, 0x8c421fc4, 0x31c4ffff, 0x00641821, 0x3c010800, - 0xac231720, 0x00441021, 0x3c010800, 0xac221fc4, 0x03e00008, 0x27bd0020, - 0x27bdffc8, 0x3c040800, 0x248416f8, 0xafbf0034, 0xafbe0030, 0xafb7002c, - 0xafb60028, 0xafb50024, 0xafb40020, 0xafb3001c, 0xafb20018, 0xafb10014, - 0xafb00010, 0x90830000, 0x24020003, 0x146200f4, 0x00000000, 0x3c020800, - 0x8c421710, 0x3c030800, 0x8c63170c, 0x3c1e0800, 0x97de16f6, 0x0043102a, - 0x104000eb, 0x3c168000, 0x249708c4, 0x33d5ffff, 0x24920018, 0x3c020800, - 0x8c421718, 0x104000e4, 0x00000000, 0x3c140800, 0x96941fb0, 0x3282ffff, - 0x104000d6, 0x00008021, 0x00409821, 0x00008821, 0x8f634450, 0x3c020800, - 0x8c4216e8, 0x00031c02, 0x0043102b, 0x14400008, 0x00000000, 0x3c040800, - 0x8c8416ec, 0x8f624450, 0x00021c02, 0x0083102b, 0x1040fffc, 0x00000000, - 0xaf764444, 0x8f624444, 0x00561024, 0x10400006, 0x00000000, 0x3c038000, - 0x8f624444, 0x00431024, 0x1440fffd, 0x00000000, 0x8f624448, 0x3046ffff, - 0x10c0005f, 0x00000000, 0x3c090800, 0x01314821, 0x8d291728, 0x9528000a, - 0x31020040, 0x10400004, 0x2407180c, 0x8d22000c, 0x2407188c, 0xacc20018, - 0x31021000, 0x10400004, 0x34e32000, 0x00081040, 0x3042c000, 0x00623825, - 0x31020080, 0x54400001, 0x34e70010, 0x3c020800, 0x00511021, 0x8c421730, - 0x3c030800, 0x00711821, 0x8c631734, 0x00021500, 0x00031c00, 0x00431025, - 0xacc20014, 0x95240008, 0x3202ffff, 0x00821021, 0x0262102a, 0x14400002, - 0x02902823, 0x00802821, 0x8d220000, 0x02058021, 0xacc20000, 0x8d220004, - 0x00c02021, 0x26310010, 0xac820004, 0x30e2ffff, 0xac800008, 0xa485000e, - 0xac820010, 0x24020305, 0x0e000560, 0xa482000c, 0x3202ffff, 0x0053102b, - 0x1440ffaf, 0x3202ffff, 0x0a00054c, 0x00000000, 0x8e420000, 0x8e43fffc, - 0x0043102a, 0x10400084, 0x00000000, 0x8e45fff0, 0x8f644450, 0x3c030800, - 0x8c6316e8, 0x00051100, 0x3c090800, 0x01224821, 0x8d291728, 0x00041402, - 0x0062182b, 0x14600008, 0x00000000, 0x3c030800, 0x8c6316ec, 0x8f624450, - 0x00021402, 0x0062102b, 0x1040fffc, 0x00000000, 0xaf764444, 0x8f624444, - 0x00561024, 0x10400006, 0x00000000, 0x3c038000, 0x8f624444, 0x00431024, - 0x1440fffd, 0x00000000, 0x8f624448, 0x3046ffff, 0x14c00005, 0x00000000, - 0x8ee20000, 0x24420001, 0x0a000554, 0xaee20000, 0x9528000a, 0x31020040, - 0x10400004, 0x2407180c, 0x8d22000c, 0x2407188c, 0xacc20018, 0x31021000, - 0x10400004, 0x34e32000, 0x00081040, 0x3042c000, 0x00623825, 0x00051900, - 0x3c020800, 0x00431021, 0x8c421730, 0x3c010800, 0x00230821, 0x8c231734, - 0x00021500, 0x00031c00, 0x00431025, 0xacc20014, 0x3c030800, 0x8c631704, - 0x95220008, 0x00432023, 0x3202ffff, 0x3083ffff, 0x00431021, 0x02a2102a, - 0x14400002, 0x03d02823, 0x00802821, 0x8e420000, 0x30a4ffff, 0x00441021, - 0xae420000, 0xa4c5000e, 0x8d220000, 0xacc20000, 0x8d220004, 0x8e43fff4, - 0x00431021, 0xacc20004, 0x8e43fff4, 0x95220008, 0x00641821, 0x0062102a, - 0x14400006, 0x02058021, 0x8e42fff0, 0xae40fff4, 0x24420001, 0x0a000530, - 0xae42fff0, 0xae43fff4, 0xacc00008, 0x3202ffff, 0x10550003, 0x31020004, - 0x10400006, 0x24020305, 0x31020080, 0x54400001, 0x34e70010, 0x34e70020, - 0x24020905, 0xa4c2000c, 0x30e2ffff, 0xacc20010, 0x3c030800, 0x8c63170c, - 0x3c020800, 0x8c421710, 0x54620004, 0x3c02b49a, 0x3c024b65, 0x0a000548, - 0x34427654, 0x344289ab, 0xacc2001c, 0x0e000560, 0x00c02021, 0x3202ffff, - 0x0055102b, 0x1440ff7e, 0x00000000, 0x8e420000, 0x8e43fffc, 0x0043102a, - 0x1440ff1a, 0x00000000, 0x8fbf0034, 0x8fbe0030, 0x8fb7002c, 0x8fb60028, - 0x8fb50024, 0x8fb40020, 0x8fb3001c, 0x8fb20018, 0x8fb10014, 0x8fb00010, - 0x03e00008, 0x27bd0038, 0x27bdffe8, 0xafbf0014, 0xafb00010, 0x8f624450, - 0x8f634410, 0x0a00056f, 0x00808021, 0x8f626820, 0x30422000, 0x10400003, - 0x00000000, 0x0e00025a, 0x00002021, 0x8f624450, 0x8f634410, 0x3042ffff, - 0x0043102b, 0x1440fff5, 0x00000000, 0x8f630c14, 0x3063000f, 0x2c620002, - 0x1440000b, 0x00000000, 0x8f630c14, 0x3c020800, 0x8c4216b4, 0x3063000f, - 0x24420001, 0x3c010800, 0xac2216b4, 0x2c620002, 0x1040fff7, 0x00000000, - 0xaf705c18, 0x8f625c10, 0x30420002, 0x10400009, 0x00000000, 0x8f626820, - 0x30422000, 0x1040fff8, 0x00000000, 0x0e00025a, 0x00002021, 0x0a000582, - 0x00000000, 0x8fbf0014, 0x8fb00010, 0x03e00008, 0x27bd0018, 0x00000000, - 0x00000000 + 0x0e0004b9, 0x00000000, 0x8fbf0028, 0x8fb30024, 0x8fb20020, 0x8fb1001c, + 0x8fb00018, 0x03e00008, 0x27bd0030, 0x8f634450, 0x3c040800, 0x24841b98, + 0x8c820000, 0x00031c02, 0x0043102b, 0x14400007, 0x3c038000, 0x8c840004, + 0x8f624450, 0x00021c02, 0x0083102b, 0x1040fffc, 0x3c038000, 0xaf634444, + 0x8f624444, 0x00431024, 0x1440fffd, 0x00000000, 0x8f624448, 0x03e00008, + 0x3042ffff, 0x3c024000, 0x00822025, 0xaf645c38, 0x8f625c30, 0x30420002, + 0x1440fffc, 0x00000000, 0x03e00008, 0x00000000, 0x27bdffe0, 0x00805821, + 0x14c00017, 0x256e0008, 0x3c020800, 0x8c422404, 0x1040000a, 0x2402003e, + 0x3c010800, 0xa42223e0, 0x24020016, 0x3c010800, 0xa42223e2, 0x2402002a, + 0x3c010800, 0x0a000360, 0xa42223e4, 0x95620014, 0x3c010800, 0xa42223e0, + 0x8d670010, 0x00071402, 0x3c010800, 0xa42223e2, 0x3c010800, 0xa42723e4, + 0x3c040800, 0x948423e4, 0x3c030800, 0x946323e2, 0x95cf0006, 0x3c020800, + 0x944223e0, 0x00832023, 0x01e2c023, 0x3065ffff, 0x24a20028, 0x01c24821, + 0x3082ffff, 0x14c0001a, 0x01226021, 0x9582000c, 0x3042003f, 0x3c010800, + 0xa42223e6, 0x95820004, 0x95830006, 0x3c010800, 0xac2023f4, 0x3c010800, + 0xac2023f8, 0x00021400, 0x00431025, 0x3c010800, 0xac221bd0, 0x95220004, + 0x3c010800, 0xa4221bd4, 0x95230002, 0x01e51023, 0x0043102a, 0x10400010, + 0x24020001, 0x3c010800, 0x0a000394, 0xac222408, 0x3c030800, 0x8c6323f8, + 0x3c020800, 0x94421bd4, 0x00431021, 0xa5220004, 0x3c020800, 0x94421bd0, + 0xa5820004, 0x3c020800, 0x8c421bd0, 0xa5820006, 0x3c020800, 0x8c422400, + 0x3c0d0800, 0x8dad23f4, 0x3c0a0800, 0x144000e5, 0x8d4a23f8, 0x3c020800, + 0x94421bd4, 0x004a1821, 0x3063ffff, 0x0062182b, 0x24020002, 0x10c2000d, + 0x01435023, 0x3c020800, 0x944223e6, 0x30420009, 0x10400008, 0x00000000, + 0x9582000c, 0x3042fff6, 0xa582000c, 0x3c020800, 0x944223e6, 0x30420009, + 0x01a26823, 0x3c020800, 0x8c422408, 0x1040004a, 0x01203821, 0x3c020800, + 0x944223e2, 0x00004021, 0xa520000a, 0x01e21023, 0xa5220002, 0x3082ffff, + 0x00021042, 0x18400008, 0x00003021, 0x00401821, 0x94e20000, 0x25080001, + 0x00c23021, 0x0103102a, 0x1440fffb, 0x24e70002, 0x00061c02, 0x30c2ffff, + 0x00623021, 0x00061402, 0x00c23021, 0x00c02821, 0x00061027, 0xa522000a, + 0x00003021, 0x2527000c, 0x00004021, 0x94e20000, 0x25080001, 0x00c23021, + 0x2d020004, 0x1440fffb, 0x24e70002, 0x95220002, 0x00004021, 0x91230009, + 0x00442023, 0x01803821, 0x3082ffff, 0xa4e00010, 0x00621821, 0x00021042, + 0x18400010, 0x00c33021, 0x00404821, 0x94e20000, 0x24e70002, 0x00c23021, + 0x30e2007f, 0x14400006, 0x25080001, 0x8d630000, 0x3c02007f, 0x3442ff80, + 0x00625824, 0x25670008, 0x0109102a, 0x1440fff3, 0x00000000, 0x30820001, + 0x10400005, 0x00061c02, 0xa0e00001, 0x94e20000, 0x00c23021, 0x00061c02, + 0x30c2ffff, 0x00623021, 0x00061402, 0x00c23021, 0x0a000479, 0x30c6ffff, + 0x24020002, 0x14c20081, 0x00000000, 0x3c020800, 0x8c42241c, 0x14400007, + 0x00000000, 0x3c020800, 0x944223e2, 0x95230002, 0x01e21023, 0x10620077, + 0x00000000, 0x3c020800, 0x944223e2, 0x01e21023, 0xa5220002, 0x3c020800, + 0x8c42241c, 0x1040001a, 0x31e3ffff, 0x8dc70010, 0x3c020800, 0x94421ba6, + 0x00e04021, 0x00072c02, 0x00aa2021, 0x00431023, 0x00823823, 0x00072402, + 0x30e2ffff, 0x00823821, 0x00071027, 0xa522000a, 0x3102ffff, 0x3c040800, + 0x948423e4, 0x00453023, 0x00e02821, 0x00641823, 0x006d1821, 0x00c33021, + 0x00061c02, 0x30c2ffff, 0x0a000479, 0x00623021, 0x01203821, 0x00004021, + 0x3082ffff, 0x00021042, 0x18400008, 0x00003021, 0x00401821, 0x94e20000, + 0x25080001, 0x00c23021, 0x0103102a, 0x1440fffb, 0x24e70002, 0x00061c02, + 0x30c2ffff, 0x00623021, 0x00061402, 0x00c23021, 0x00c02821, 0x00061027, + 0xa522000a, 0x00003021, 0x2527000c, 0x00004021, 0x94e20000, 0x25080001, + 0x00c23021, 0x2d020004, 0x1440fffb, 0x24e70002, 0x95220002, 0x00004021, + 0x91230009, 0x00442023, 0x01803821, 0x3082ffff, 0xa4e00010, 0x3c040800, + 0x948423e4, 0x00621821, 0x00c33021, 0x00061c02, 0x30c2ffff, 0x00623021, + 0x00061c02, 0x3c020800, 0x944223e0, 0x00c34821, 0x00441023, 0x00021fc2, + 0x00431021, 0x00021043, 0x18400010, 0x00003021, 0x00402021, 0x94e20000, + 0x24e70002, 0x00c23021, 0x30e2007f, 0x14400006, 0x25080001, 0x8d630000, + 0x3c02007f, 0x3442ff80, 0x00625824, 0x25670008, 0x0104102a, 0x1440fff3, + 0x00000000, 0x3c020800, 0x944223fc, 0x00c23021, 0x3122ffff, 0x00c23021, + 0x00061c02, 0x30c2ffff, 0x00623021, 0x00061402, 0x00c23021, 0x00c04021, + 0x00061027, 0xa5820010, 0xadc00014, 0x0a000499, 0xadc00000, 0x8dc70010, + 0x00e04021, 0x11400007, 0x00072c02, 0x00aa3021, 0x00061402, 0x30c3ffff, + 0x00433021, 0x00061402, 0x00c22821, 0x00051027, 0xa522000a, 0x3c030800, + 0x946323e4, 0x3102ffff, 0x01e21021, 0x00433023, 0x00cd3021, 0x00061c02, + 0x30c2ffff, 0x00623021, 0x00061402, 0x00c23021, 0x00c04021, 0x00061027, + 0xa5820010, 0x3102ffff, 0x00051c00, 0x00431025, 0xadc20010, 0x3c020800, + 0x8c422404, 0x10400002, 0x25e2fff2, 0xa5c20034, 0x3c020800, 0x8c4223f8, + 0x3c040800, 0x8c8423f4, 0x24420001, 0x3c010800, 0xac2223f8, 0x3c020800, + 0x8c421bd0, 0x3303ffff, 0x00832021, 0x3c010800, 0xac2423f4, 0x00431821, + 0x0062102b, 0x10400003, 0x2482ffff, 0x3c010800, 0xac2223f4, 0x3c010800, + 0xac231bd0, 0x03e00008, 0x27bd0020, 0x27bdffb8, 0x3c050800, 0x24a51ba8, + 0xafbf0044, 0xafbe0040, 0xafb7003c, 0xafb60038, 0xafb50034, 0xafb40030, + 0xafb3002c, 0xafb20028, 0xafb10024, 0xafb00020, 0x90a30000, 0x24020003, + 0x146200d5, 0x00000000, 0x3c090800, 0x95291ba6, 0x3c020800, 0x944223e0, + 0x3c030800, 0x8c631bc0, 0x3c040800, 0x8c841bbc, 0x01221023, 0x0064182a, + 0xa7a9001e, 0x106000c8, 0xa7a20016, 0x24be0020, 0x97b6001e, 0x24b30018, + 0x24b70014, 0x8fc20000, 0x14400008, 0x00000000, 0x8fc2fff8, 0x97a30016, + 0x8fc4fff4, 0x00431021, 0x0082202a, 0x148000ba, 0x00000000, 0x97d50818, + 0x32a2ffff, 0x104000ad, 0x00009021, 0x0040a021, 0x00008821, 0x0e00062d, + 0x00000000, 0x00403021, 0x14c00007, 0x00000000, 0x3c020800, 0x8c4223ec, + 0x24420001, 0x3c010800, 0x0a00059e, 0xac2223ec, 0x3c100800, 0x02118021, + 0x8e101bd8, 0x9608000a, 0x31020040, 0x10400004, 0x2407180c, 0x8e02000c, + 0x2407188c, 0xacc20018, 0x31021000, 0x10400004, 0x34e32000, 0x00081040, + 0x3042c000, 0x00623825, 0x31020080, 0x54400001, 0x34e70010, 0x3c020800, + 0x00511021, 0x8c421be0, 0x3c030800, 0x00711821, 0x8c631be4, 0x00021500, + 0x00031c00, 0x00431025, 0xacc20014, 0x96040008, 0x3242ffff, 0x00821021, + 0x0282102a, 0x14400002, 0x02b22823, 0x00802821, 0x8e020000, 0x02459021, + 0xacc20000, 0x8e020004, 0x00c02021, 0x26310010, 0xac820004, 0x30e2ffff, + 0xac800008, 0xa485000e, 0xac820010, 0x24020305, 0x0e0005aa, 0xa482000c, + 0x3242ffff, 0x0054102b, 0x1440ffc0, 0x3242ffff, 0x0a000596, 0x00000000, + 0x8e620000, 0x8e63fffc, 0x0043102a, 0x1040006c, 0x00000000, 0x8e62fff0, + 0x00028900, 0x3c100800, 0x02118021, 0x0e00062d, 0x8e101bd8, 0x00403021, + 0x14c00005, 0x00000000, 0x8e62082c, 0x24420001, 0x0a00059e, 0xae62082c, + 0x9608000a, 0x31020040, 0x10400004, 0x2407180c, 0x8e02000c, 0x2407188c, + 0xacc20018, 0x31021000, 0x10400004, 0x34e32000, 0x00081040, 0x3042c000, + 0x00623825, 0x3c020800, 0x00511021, 0x8c421be0, 0x3c030800, 0x00711821, + 0x8c631be4, 0x00021500, 0x00031c00, 0x00431025, 0xacc20014, 0x8e63fff4, + 0x96020008, 0x00432023, 0x3242ffff, 0x3083ffff, 0x00431021, 0x02c2102a, + 0x10400003, 0x00802821, 0x97a9001e, 0x01322823, 0x8e620000, 0x30a4ffff, + 0x00441021, 0xae620000, 0xa4c5000e, 0x8e020000, 0xacc20000, 0x8e020004, + 0x8e63fff4, 0x00431021, 0xacc20004, 0x8e63fff4, 0x96020008, 0x00641821, + 0x0062102a, 0x14400006, 0x02459021, 0x8e62fff0, 0xae60fff4, 0x24420001, + 0x0a000579, 0xae62fff0, 0xae63fff4, 0xacc00008, 0x3242ffff, 0x10560003, + 0x31020004, 0x10400006, 0x24020305, 0x31020080, 0x54400001, 0x34e70010, + 0x34e70020, 0x24020905, 0xa4c2000c, 0x8ee30000, 0x8ee20004, 0x14620007, + 0x3c02b49a, 0x8ee20860, 0x54400001, 0x34e70400, 0x3c024b65, 0x0a000590, + 0x34427654, 0x344289ab, 0xacc2001c, 0x30e2ffff, 0xacc20010, 0x0e0005aa, + 0x00c02021, 0x3242ffff, 0x0056102b, 0x1440ff96, 0x00000000, 0x8e620000, + 0x8e63fffc, 0x0043102a, 0x1440ff3e, 0x00000000, 0x8fbf0044, 0x8fbe0040, + 0x8fb7003c, 0x8fb60038, 0x8fb50034, 0x8fb40030, 0x8fb3002c, 0x8fb20028, + 0x8fb10024, 0x8fb00020, 0x03e00008, 0x27bd0048, 0x27bdffe8, 0xafbf0014, + 0xafb00010, 0x8f624450, 0x8f634410, 0x0a0005b9, 0x00808021, 0x8f626820, + 0x30422000, 0x10400003, 0x00000000, 0x0e0001e3, 0x00002021, 0x8f624450, + 0x8f634410, 0x3042ffff, 0x0043102b, 0x1440fff5, 0x00000000, 0x8f630c14, + 0x3063000f, 0x2c620002, 0x1440000b, 0x00000000, 0x8f630c14, 0x3c020800, + 0x8c421b50, 0x3063000f, 0x24420001, 0x3c010800, 0xac221b50, 0x2c620002, + 0x1040fff7, 0x00000000, 0xaf705c18, 0x8f625c10, 0x30420002, 0x10400009, + 0x00000000, 0x8f626820, 0x30422000, 0x1040fff8, 0x00000000, 0x0e0001e3, + 0x00002021, 0x0a0005cc, 0x00000000, 0x8fbf0014, 0x8fb00010, 0x03e00008, + 0x27bd0018, 0x00000000, 0x00000000, 0x00000000, 0x27bdffe8, 0x3c1bc000, + 0xafbf0014, 0xafb00010, 0xaf60680c, 0x8f626804, 0x34420082, 0xaf626804, + 0x8f634000, 0x24020b50, 0x3c010800, 0xac221b64, 0x24020b78, 0x3c010800, + 0xac221b74, 0x34630002, 0xaf634000, 0x0e00060d, 0x00808021, 0x3c010800, + 0xa0221b78, 0x304200ff, 0x24030002, 0x14430005, 0x00000000, 0x3c020800, + 0x8c421b64, 0x0a000600, 0xac5000c0, 0x3c020800, 0x8c421b64, 0xac5000bc, + 0x8f624434, 0x8f634438, 0x8f644410, 0x3c010800, 0xac221b6c, 0x3c010800, + 0xac231b7c, 0x3c010800, 0xac241b68, 0x8fbf0014, 0x8fb00010, 0x03e00008, + 0x27bd0018, 0x3c040800, 0x8c870000, 0x3c03aa55, 0x3463aa55, 0x3c06c003, + 0xac830000, 0x8cc20000, 0x14430007, 0x24050002, 0x3c0355aa, 0x346355aa, + 0xac830000, 0x8cc20000, 0x50430001, 0x24050001, 0x3c020800, 0xac470000, + 0x03e00008, 0x00a01021, 0x27bdfff8, 0x18800009, 0x00002821, 0x8f63680c, + 0x8f62680c, 0x1043fffe, 0x00000000, 0x24a50001, 0x00a4102a, 0x1440fff9, + 0x00000000, 0x03e00008, 0x27bd0008, 0x8f634450, 0x3c020800, 0x8c421b6c, + 0x00031c02, 0x0043102b, 0x14400008, 0x3c038000, 0x3c040800, 0x8c841b7c, + 0x8f624450, 0x00021c02, 0x0083102b, 0x1040fffc, 0x3c038000, 0xaf634444, + 0x8f624444, 0x00431024, 0x1440fffd, 0x00000000, 0x8f624448, 0x03e00008, + 0x3042ffff, 0x3082ffff, 0x2442e000, 0x2c422001, 0x14400003, 0x3c024000, + 0x0a000650, 0x2402ffff, 0x00822025, 0xaf645c38, 0x8f625c30, 0x30420002, + 0x1440fffc, 0x00001021, 0x03e00008, 0x00000000, 0x8f624450, 0x3c030800, + 0x8c631b68, 0x0a000659, 0x3042ffff, 0x8f624450, 0x3042ffff, 0x0043102b, + 0x1440fffc, 0x00000000, 0x03e00008, 0x00000000, 0x27bdffe0, 0x00802821, + 0x3c040800, 0x24841b10, 0x00003021, 0x00003821, 0xafbf0018, 0xafa00010, + 0x0e000684, 0xafa00014, 0x0a000668, 0x00000000, 0x8fbf0018, 0x03e00008, + 0x27bd0020, 0x00000000, 0x00000000, 0x00000000, 0x3c020800, 0x34423000, + 0x3c030800, 0x34633000, 0x3c040800, 0x348437ff, 0x3c010800, 0xac221b84, + 0x24020040, 0x3c010800, 0xac221b88, 0x3c010800, 0xac201b80, 0xac600000, + 0x24630004, 0x0083102b, 0x5040fffd, 0xac600000, 0x03e00008, 0x00000000, + 0x00804821, 0x8faa0010, 0x3c020800, 0x8c421b80, 0x3c040800, 0x8c841b88, + 0x8fab0014, 0x24430001, 0x0044102b, 0x3c010800, 0xac231b80, 0x14400003, + 0x00004021, 0x3c010800, 0xac201b80, 0x3c020800, 0x8c421b80, 0x3c030800, + 0x8c631b84, 0x91240000, 0x00021140, 0x00431021, 0x00481021, 0x25080001, + 0xa0440000, 0x29020008, 0x1440fff4, 0x25290001, 0x3c020800, 0x8c421b80, + 0x3c030800, 0x8c631b84, 0x8f64680c, 0x00021140, 0x00431021, 0xac440008, + 0xac45000c, 0xac460010, 0xac470014, 0xac4a0018, 0x03e00008, 0xac4b001c, + 0x00000000, 0x00000000, }; u32 tg3TsoFwRodata[] = { - 0x4d61696e, 0x43707542, 0x00000000, 0x00000000, 0x74637073, 0x6567496e, - 0x00000000, 0x53774576, 0x656e7430, 0x00000000, 0x00000000, 0x00000000, - 0x00000000 + 0x4d61696e, 0x43707542, 0x00000000, 0x4d61696e, 0x43707541, + 0x00000000, 0x00000000, 0x00000000, 0x73746b6f, 0x66666c64, + 0x496e0000, 0x73746b6f, 0x66662a2a, 0x00000000, 0x53774576, + 0x656e7430, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x66617461, 0x6c457272, 0x00000000, 0x00000000, 0x00000000 }; #if 0 /* All zeros, don't eat up space with it. */ @@ -3785,63 +4178,274 @@ }; #endif +/* 5705 needs a special version of the TSO firmware. */ +#define TG3_TSO5_FW_RELEASE_MAJOR 0x1 +#define TG3_TSO5_FW_RELASE_MINOR 0x1 +#define TG3_TSO5_FW_RELEASE_FIX 0x0 +#define TG3_TSO5_FW_START_ADDR 0x00010000 +#define TG3_TSO5_FW_TEXT_ADDR 0x00010000 +#define TG3_TSO5_FW_TEXT_LEN 0xeb0 +#define TG3_TSO5_FW_RODATA_ADDR 0x00010eb0 +#define TG3_TSO5_FW_RODATA_LEN 0x50 +#define TG3_TSO5_FW_DATA_ADDR 0x00010f20 +#define TG3_TSO5_FW_DATA_LEN 0x20 +#define TG3_TSO5_FW_SBSS_ADDR 0x00010f40 +#define TG3_TSO5_FW_SBSS_LEN 0x28 +#define TG3_TSO5_FW_BSS_ADDR 0x00010f70 +#define TG3_TSO5_FW_BSS_LEN 0x88 + +static u32 tg3Tso5FwText[] = { + 0x0c004003, 0x00000000, 0x00010f30, 0x00000000, 0x10000003, 0x00000000, + 0x0000000d, 0x0000000d, 0x3c1d0001, 0x37bde000, 0x03a0f021, 0x3c100001, + 0x26100000, 0x0c004010, 0x00000000, 0x0000000d, 0x27bdffe0, 0x3c04fefe, + 0xafbf0018, 0x0c0042f0, 0x34840002, 0x0c00436c, 0x00000000, 0x3c030001, + 0x90630f54, 0x24020002, 0x3c040001, 0x24840ebc, 0x14620003, 0x24050001, + 0x3c040001, 0x24840eb0, 0x24060001, 0x00003821, 0xafa00010, 0x0c004380, + 0xafa00014, 0x0c00402c, 0x00000000, 0x8fbf0018, 0x03e00008, 0x27bd0020, + 0x00000000, 0x00000000, 0x27bdffe0, 0xafbf001c, 0xafb20018, 0xafb10014, + 0x0c0042d3, 0xafb00010, 0x3c128000, 0x24110001, 0x8f706810, 0x32020400, + 0x10400007, 0x00000000, 0x8f641008, 0x00921024, 0x14400003, 0x00000000, + 0x0c004064, 0x00000000, 0x3c020001, 0x90420f76, 0x10510003, 0x32020200, + 0x1040fff1, 0x00000000, 0x0c0041b4, 0x00000000, 0x08004034, 0x00000000, + 0x8fbf001c, 0x8fb20018, 0x8fb10014, 0x8fb00010, 0x03e00008, 0x27bd0020, + 0x27bdffe0, 0x3c040001, 0x24840ed0, 0x00002821, 0x00003021, 0x00003821, + 0xafbf0018, 0xafa00010, 0x0c004380, 0xafa00014, 0x0000d021, 0x24020130, + 0xaf625000, 0x3c010001, 0xa4200f70, 0x3c010001, 0xa0200f77, 0x8fbf0018, + 0x03e00008, 0x27bd0020, 0x00000000, 0x00000000, 0x3c030001, 0x24630f80, + 0x90620000, 0x27bdfff0, 0x14400003, 0x0080c021, 0x08004073, 0x00004821, + 0x3c022000, 0x03021024, 0x10400003, 0x24090002, 0x08004073, 0xa0600000, + 0x24090001, 0x00181040, 0x30431f80, 0x346f8008, 0x1520004b, 0x25eb0028, + 0x3c040001, 0x00832021, 0x8c848010, 0x3c050001, 0x24a50f9a, 0x00041402, + 0xa0a20000, 0x3c010001, 0xa0240f9b, 0x3c020001, 0x00431021, 0x94428014, + 0x3c010001, 0xa0220f9c, 0x3c0c0001, 0x01836021, 0x8d8c8018, 0x304200ff, + 0x24420008, 0x000220c3, 0x24020001, 0x3c010001, 0xa0220f80, 0x0124102b, + 0x1040000c, 0x00003821, 0x24a6000e, 0x01602821, 0x8ca20000, 0x8ca30004, + 0x24a50008, 0x24e70001, 0xacc20000, 0xacc30004, 0x00e4102b, 0x1440fff8, + 0x24c60008, 0x00003821, 0x3c080001, 0x25080f9b, 0x91060000, 0x3c020001, + 0x90420f9c, 0x2503000d, 0x00c32821, 0x00461023, 0x00021fc2, 0x00431021, + 0x00021043, 0x1840000c, 0x00002021, 0x91020001, 0x00461023, 0x00021fc2, + 0x00431021, 0x00021843, 0x94a20000, 0x24e70001, 0x00822021, 0x00e3102a, + 0x1440fffb, 0x24a50002, 0x00041c02, 0x3082ffff, 0x00622021, 0x00041402, + 0x00822021, 0x3c02ffff, 0x01821024, 0x3083ffff, 0x00431025, 0x3c010001, + 0x080040fa, 0xac220fa0, 0x3c050001, 0x24a50f9c, 0x90a20000, 0x3c0c0001, + 0x01836021, 0x8d8c8018, 0x000220c2, 0x1080000e, 0x00003821, 0x01603021, + 0x24a5000c, 0x8ca20000, 0x8ca30004, 0x24a50008, 0x24e70001, 0xacc20000, + 0xacc30004, 0x00e4102b, 0x1440fff8, 0x24c60008, 0x3c050001, 0x24a50f9c, + 0x90a20000, 0x30430007, 0x24020004, 0x10620011, 0x28620005, 0x10400005, + 0x24020002, 0x10620008, 0x000710c0, 0x080040fa, 0x00000000, 0x24020006, + 0x1062000e, 0x000710c0, 0x080040fa, 0x00000000, 0x00a21821, 0x9463000c, + 0x004b1021, 0x080040fa, 0xa4430000, 0x000710c0, 0x00a21821, 0x8c63000c, + 0x004b1021, 0x080040fa, 0xac430000, 0x00a21821, 0x8c63000c, 0x004b2021, + 0x00a21021, 0xac830000, 0x94420010, 0xa4820004, 0x95e70006, 0x3c020001, + 0x90420f9c, 0x3c030001, 0x90630f9a, 0x00e2c823, 0x3c020001, 0x90420f9b, + 0x24630028, 0x01e34021, 0x24420028, 0x15200012, 0x01e23021, 0x94c2000c, + 0x3c010001, 0xa4220f98, 0x94c20004, 0x94c30006, 0x3c010001, 0xa4200f96, + 0x3c010001, 0xa4200f92, 0x00021400, 0x00431025, 0x3c010001, 0xac220f8c, + 0x95020004, 0x3c010001, 0x08004124, 0xa4220f90, 0x3c020001, 0x94420f90, + 0x3c030001, 0x94630f92, 0x00431021, 0xa5020004, 0x3c020001, 0x94420f8c, + 0xa4c20004, 0x3c020001, 0x8c420f8c, 0xa4c20006, 0x3c040001, 0x94840f92, + 0x3c020001, 0x94420f90, 0x3c0a0001, 0x954a0f96, 0x00441821, 0x3063ffff, + 0x0062182a, 0x24020002, 0x1122000b, 0x00832023, 0x3c030001, 0x94630f98, + 0x30620009, 0x10400006, 0x3062fff6, 0xa4c2000c, 0x3c020001, 0x94420f98, + 0x30420009, 0x01425023, 0x24020001, 0x1122001b, 0x29220002, 0x50400005, + 0x24020002, 0x11200007, 0x31a2ffff, 0x08004197, 0x00000000, 0x1122001d, + 0x24020016, 0x08004197, 0x31a2ffff, 0x3c0e0001, 0x95ce0fa0, 0x10800005, + 0x01806821, 0x01c42021, 0x00041c02, 0x3082ffff, 0x00627021, 0x000e1027, + 0xa502000a, 0x3c030001, 0x90630f9b, 0x31a2ffff, 0x00e21021, 0x0800418d, + 0x00432023, 0x3c020001, 0x94420fa0, 0x00442021, 0x00041c02, 0x3082ffff, + 0x00622021, 0x00807021, 0x00041027, 0x08004185, 0xa502000a, 0x3c050001, + 0x24a50f9a, 0x90a30000, 0x14620002, 0x24e2fff2, 0xa5e20034, 0x90a20000, + 0x00e21023, 0xa5020002, 0x3c030001, 0x94630fa0, 0x3c020001, 0x94420f7a, + 0x30e5ffff, 0x00641821, 0x00451023, 0x00622023, 0x00041c02, 0x3082ffff, + 0x00622021, 0x00041027, 0xa502000a, 0x3c030001, 0x90630f9c, 0x24620001, + 0x14a20005, 0x00807021, 0x01631021, 0x90420000, 0x08004185, 0x00026200, + 0x24620002, 0x14a20003, 0x306200fe, 0x004b1021, 0x944c0000, 0x3c020001, + 0x94420fa2, 0x3183ffff, 0x3c040001, 0x90840f9b, 0x00431021, 0x00e21021, + 0x00442023, 0x008a2021, 0x00041c02, 0x3082ffff, 0x00622021, 0x00041402, + 0x00822021, 0x00806821, 0x00041027, 0xa4c20010, 0x31a2ffff, 0x000e1c00, + 0x00431025, 0x3c040001, 0x24840f92, 0xade20010, 0x94820000, 0x3c050001, + 0x94a50f96, 0x3c030001, 0x8c630f8c, 0x24420001, 0x00b92821, 0xa4820000, + 0x3322ffff, 0x00622021, 0x0083182b, 0x3c010001, 0xa4250f96, 0x10600003, + 0x24a2ffff, 0x3c010001, 0xa4220f96, 0x3c024000, 0x03021025, 0x3c010001, + 0xac240f8c, 0xaf621008, 0x03e00008, 0x27bd0010, 0x3c030001, 0x90630f76, + 0x27bdffe8, 0x24020001, 0xafbf0014, 0x10620026, 0xafb00010, 0x8f620cf4, + 0x2442ffff, 0x3042007f, 0x00021100, 0x8c434000, 0x3c010001, 0xac230f84, + 0x8c434008, 0x24444000, 0x8c5c4004, 0x30620040, 0x14400002, 0x24020088, + 0x24020008, 0x3c010001, 0xa4220f88, 0x30620004, 0x10400005, 0x24020001, + 0x3c010001, 0xa0220f77, 0x080041d5, 0x00031402, 0x3c010001, 0xa0200f77, + 0x00031402, 0x3c010001, 0xa4220f74, 0x9483000c, 0x24020001, 0x3c010001, + 0xa4200f70, 0x3c010001, 0xa0220f76, 0x3c010001, 0xa4230f82, 0x24020001, + 0x1342001e, 0x00000000, 0x13400005, 0x24020003, 0x13420067, 0x00000000, + 0x080042cf, 0x00000000, 0x3c020001, 0x94420f82, 0x241a0001, 0x3c010001, + 0xa4200f7e, 0x3c010001, 0xa4200f72, 0x304407ff, 0x00021bc2, 0x00031823, + 0x3063003e, 0x34630036, 0x00021242, 0x3042003c, 0x00621821, 0x3c010001, + 0xa4240f78, 0x00832021, 0x24630030, 0x3c010001, 0xa4240f7a, 0x3c010001, + 0xa4230f7c, 0x3c060001, 0x24c60f72, 0x94c50000, 0x94c30002, 0x3c040001, + 0x94840f7a, 0x00651021, 0x0044102a, 0x10400013, 0x3c108000, 0x00a31021, + 0xa4c20000, 0x3c02a000, 0xaf620cf4, 0x3c010001, 0xa0200f76, 0x8f641008, + 0x00901024, 0x14400003, 0x00000000, 0x0c004064, 0x00000000, 0x8f620cf4, + 0x00501024, 0x104000b7, 0x00000000, 0x0800420f, 0x00000000, 0x3c030001, + 0x94630f70, 0x00851023, 0xa4c40000, 0x00621821, 0x3042ffff, 0x3c010001, + 0xa4230f70, 0xaf620ce8, 0x3c020001, 0x94420f88, 0x34420024, 0xaf620cec, + 0x94c30002, 0x3c020001, 0x94420f70, 0x14620012, 0x3c028000, 0x3c108000, + 0x3c02a000, 0xaf620cf4, 0x3c010001, 0xa0200f76, 0x8f641008, 0x00901024, + 0x14400003, 0x00000000, 0x0c004064, 0x00000000, 0x8f620cf4, 0x00501024, + 0x1440fff7, 0x00000000, 0x080042cf, 0x241a0003, 0xaf620cf4, 0x3c108000, + 0x8f641008, 0x00901024, 0x14400003, 0x00000000, 0x0c004064, 0x00000000, + 0x8f620cf4, 0x00501024, 0x1440fff7, 0x00000000, 0x080042cf, 0x241a0003, + 0x3c070001, 0x24e70f70, 0x94e20000, 0x03821021, 0xaf620ce0, 0x3c020001, + 0x8c420f84, 0xaf620ce4, 0x3c050001, 0x94a50f74, 0x94e30000, 0x3c040001, + 0x94840f78, 0x3c020001, 0x94420f7e, 0x00a32823, 0x00822023, 0x30a6ffff, + 0x3083ffff, 0x00c3102b, 0x14400043, 0x00000000, 0x3c020001, 0x94420f7c, + 0x00021400, 0x00621025, 0xaf620ce8, 0x94e20000, 0x3c030001, 0x94630f74, + 0x00441021, 0xa4e20000, 0x3042ffff, 0x14430021, 0x3c020008, 0x3c020001, + 0x90420f77, 0x10400006, 0x3c03000c, 0x3c020001, 0x94420f88, 0x34630624, + 0x0800427c, 0x0000d021, 0x3c020001, 0x94420f88, 0x3c030008, 0x34630624, + 0x00431025, 0xaf620cec, 0x3c108000, 0x3c02a000, 0xaf620cf4, 0x3c010001, + 0xa0200f76, 0x8f641008, 0x00901024, 0x14400003, 0x00000000, 0x0c004064, + 0x00000000, 0x8f620cf4, 0x00501024, 0x10400015, 0x00000000, 0x08004283, + 0x00000000, 0x3c030001, 0x94630f88, 0x34420624, 0x3c108000, 0x00621825, + 0x3c028000, 0xaf630cec, 0xaf620cf4, 0x8f641008, 0x00901024, 0x14400003, + 0x00000000, 0x0c004064, 0x00000000, 0x8f620cf4, 0x00501024, 0x1440fff7, + 0x00000000, 0x3c010001, 0x080042cf, 0xa4200f7e, 0x3c020001, 0x94420f7c, + 0x00021400, 0x00c21025, 0xaf620ce8, 0x3c020001, 0x90420f77, 0x10400009, + 0x3c03000c, 0x3c020001, 0x94420f88, 0x34630624, 0x0000d021, 0x00431025, + 0xaf620cec, 0x080042c1, 0x3c108000, 0x3c020001, 0x94420f88, 0x3c030008, + 0x34630604, 0x00431025, 0xaf620cec, 0x3c020001, 0x94420f7e, 0x00451021, + 0x3c010001, 0xa4220f7e, 0x3c108000, 0x3c02a000, 0xaf620cf4, 0x3c010001, + 0xa0200f76, 0x8f641008, 0x00901024, 0x14400003, 0x00000000, 0x0c004064, + 0x00000000, 0x8f620cf4, 0x00501024, 0x1440fff7, 0x00000000, 0x8fbf0014, + 0x8fb00010, 0x03e00008, 0x27bd0018, 0x27bdffe0, 0x3c040001, 0x24840ee0, + 0x00002821, 0x00003021, 0x00003821, 0xafbf0018, 0xafa00010, 0x0c004380, + 0xafa00014, 0x0000d021, 0x24020130, 0xaf625000, 0x3c010001, 0xa4200f70, + 0x3c010001, 0xa0200f77, 0x8f636804, 0x3c020001, 0x3442e000, 0x00621824, + 0x3c020001, 0x14620003, 0x00000000, 0x080042eb, 0x00000000, 0x8fbf0018, + 0x03e00008, 0x27bd0020, 0x27bdffe8, 0x3c1bc000, 0xafbf0014, 0xafb00010, + 0xaf60680c, 0x8f626804, 0x34420082, 0xaf626804, 0x8f634000, 0x24020b50, + 0x3c010001, 0xac220f40, 0x24020b78, 0x3c010001, 0xac220f50, 0x34630002, + 0xaf634000, 0x0c00431d, 0x00808021, 0x3c010001, 0xa0220f54, 0x304200ff, + 0x24030002, 0x14430005, 0x00000000, 0x3c020001, 0x8c420f40, 0x08004310, + 0xac5000c0, 0x3c020001, 0x8c420f40, 0xac5000bc, 0x8f624434, 0x8f634438, + 0x8f644410, 0x3c010001, 0xac220f48, 0x3c010001, 0xac230f58, 0x3c010001, + 0xac240f44, 0x8fbf0014, 0x8fb00010, 0x03e00008, 0x27bd0018, 0x03e00008, + 0x24020001, 0x27bdfff8, 0x18800009, 0x00002821, 0x8f63680c, 0x8f62680c, + 0x1043fffe, 0x00000000, 0x24a50001, 0x00a4102a, 0x1440fff9, 0x00000000, + 0x03e00008, 0x27bd0008, 0x8f634450, 0x3c020001, 0x8c420f48, 0x00031c02, + 0x0043102b, 0x14400008, 0x3c038000, 0x3c040001, 0x8c840f58, 0x8f624450, + 0x00021c02, 0x0083102b, 0x1040fffc, 0x3c038000, 0xaf634444, 0x8f624444, + 0x00431024, 0x1440fffd, 0x00000000, 0x8f624448, 0x03e00008, 0x3042ffff, + 0x3082ffff, 0x2442e000, 0x2c422001, 0x14400003, 0x3c024000, 0x0800434f, + 0x2402ffff, 0x00822025, 0xaf645c38, 0x8f625c30, 0x30420002, 0x1440fffc, + 0x00001021, 0x03e00008, 0x00000000, 0x8f624450, 0x3c030001, 0x8c630f44, + 0x08004358, 0x3042ffff, 0x8f624450, 0x3042ffff, 0x0043102b, 0x1440fffc, + 0x00000000, 0x03e00008, 0x00000000, 0x27bdffe0, 0x00802821, 0x3c040001, + 0x24840ef0, 0x00003021, 0x00003821, 0xafbf0018, 0xafa00010, 0x0c004380, + 0xafa00014, 0x08004367, 0x00000000, 0x8fbf0018, 0x03e00008, 0x27bd0020, + 0x3c020001, 0x3442d600, 0x3c030001, 0x3463d600, 0x3c040001, 0x3484ddff, + 0x3c010001, 0xac220f60, 0x24020040, 0x3c010001, 0xac220f64, 0x3c010001, + 0xac200f5c, 0xac600000, 0x24630004, 0x0083102b, 0x5040fffd, 0xac600000, + 0x03e00008, 0x00000000, 0x00804821, 0x8faa0010, 0x3c020001, 0x8c420f5c, + 0x3c040001, 0x8c840f64, 0x8fab0014, 0x24430001, 0x0044102b, 0x3c010001, + 0xac230f5c, 0x14400003, 0x00004021, 0x3c010001, 0xac200f5c, 0x3c020001, + 0x8c420f5c, 0x3c030001, 0x8c630f60, 0x91240000, 0x00021140, 0x00431021, + 0x00481021, 0x25080001, 0xa0440000, 0x29020008, 0x1440fff4, 0x25290001, + 0x3c020001, 0x8c420f5c, 0x3c030001, 0x8c630f60, 0x8f64680c, 0x00021140, + 0x00431021, 0xac440008, 0xac45000c, 0xac460010, 0xac470014, 0xac4a0018, + 0x03e00008, 0xac4b001c, 0x00000000, 0x00000000, +}; + +u32 tg3Tso5FwRodata[] = { + 0x4d61696e, 0x43707542, 0x00000000, 0x4d61696e, 0x43707541, 0x00000000, + 0x00000000, 0x00000000, 0x73746b6f, 0x66666c64, 0x00000000, 0x00000000, + 0x73746b6f, 0x66666c64, 0x00000000, 0x00000000, 0x66617461, 0x6c457272, + 0x00000000, 0x00000000, 0x00000000 +}; + +u32 tg3Tso5FwData[] = { + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x73746b6f, + 0x66666c64, 0x5f76312e, 0x312e3000, 0x00000000 +}; + /* tp->lock is held. */ static int tg3_load_tso_firmware(struct tg3 *tp) { struct fw_info info; + unsigned long cpu_base, cpu_scratch_base, cpu_scratch_size; int err, i; - info.text_base = TG3_TSO_FW_TEXT_ADDR; - info.text_len = TG3_TSO_FW_TEXT_LEN; - info.text_data = &tg3TsoFwText[0]; - info.rodata_base = TG3_TSO_FW_RODATA_ADDR; - info.rodata_len = TG3_TSO_FW_RODATA_LEN; - info.rodata_data = &tg3TsoFwRodata[0]; - info.data_base = TG3_TSO_FW_DATA_ADDR; - info.data_len = TG3_TSO_FW_DATA_LEN; - info.data_data = NULL; + if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705) { + info.text_base = TG3_TSO5_FW_TEXT_ADDR; + info.text_len = TG3_TSO5_FW_TEXT_LEN; + info.text_data = &tg3Tso5FwText[0]; + info.rodata_base = TG3_TSO5_FW_RODATA_ADDR; + info.rodata_len = TG3_TSO5_FW_RODATA_LEN; + info.rodata_data = &tg3Tso5FwRodata[0]; + info.data_base = TG3_TSO5_FW_DATA_ADDR; + info.data_len = TG3_TSO5_FW_DATA_LEN; + info.data_data = &tg3Tso5FwData[0]; + cpu_base = RX_CPU_BASE; + cpu_scratch_base = NIC_SRAM_MBUF_POOL_BASE5705; + cpu_scratch_size = (info.text_len + + info.rodata_len + + info.data_len + + TG3_TSO5_FW_SBSS_LEN + + TG3_TSO5_FW_BSS_LEN); + } else { + info.text_base = TG3_TSO_FW_TEXT_ADDR; + info.text_len = TG3_TSO_FW_TEXT_LEN; + info.text_data = &tg3TsoFwText[0]; + info.rodata_base = TG3_TSO_FW_RODATA_ADDR; + info.rodata_len = TG3_TSO_FW_RODATA_LEN; + info.rodata_data = &tg3TsoFwRodata[0]; + info.data_base = TG3_TSO_FW_DATA_ADDR; + info.data_len = TG3_TSO_FW_DATA_LEN; + info.data_data = NULL; + cpu_base = TX_CPU_BASE; + cpu_scratch_base = TX_CPU_SCRATCH_BASE; + cpu_scratch_size = TX_CPU_SCRATCH_SIZE; + } - err = tg3_load_firmware_cpu(tp, TX_CPU_BASE, - TX_CPU_SCRATCH_BASE, TX_CPU_SCRATCH_SIZE, + err = tg3_load_firmware_cpu(tp, cpu_base, + cpu_scratch_base, cpu_scratch_size, &info); if (err) return err; - /* Now startup only the TX cpu. */ - tw32(TX_CPU_BASE + CPU_STATE, 0xffffffff); - tw32(TX_CPU_BASE + CPU_PC, TG3_TSO_FW_TEXT_ADDR); + /* Now startup the cpu. */ + tw32(cpu_base + CPU_STATE, 0xffffffff); + tw32(cpu_base + CPU_PC, info.text_base); /* Flush posted writes. */ - tr32(TX_CPU_BASE + CPU_PC); + tr32(cpu_base + CPU_PC); for (i = 0; i < 5; i++) { - if (tr32(TX_CPU_BASE + CPU_PC) == TG3_TSO_FW_TEXT_ADDR) + if (tr32(cpu_base + CPU_PC) == info.text_base) break; - tw32(TX_CPU_BASE + CPU_STATE, 0xffffffff); - tw32(TX_CPU_BASE + CPU_MODE, CPU_MODE_HALT); - tw32(TX_CPU_BASE + CPU_PC, TG3_TSO_FW_TEXT_ADDR); + tw32(cpu_base + CPU_STATE, 0xffffffff); + tw32(cpu_base + CPU_MODE, CPU_MODE_HALT); + tw32(cpu_base + CPU_PC, info.text_base); /* Flush posted writes. */ - tr32(TX_CPU_BASE + CPU_PC); + tr32(cpu_base + CPU_PC); udelay(1000); } if (i >= 5) { printk(KERN_ERR PFX "tg3_load_tso_firmware fails for %s " - "to set TX CPU PC, is %08x should be %08x\n", - tp->dev->name, tr32(TX_CPU_BASE + CPU_PC), - TG3_TSO_FW_TEXT_ADDR); + "to set CPU PC, is %08x should be %08x\n", + tp->dev->name, tr32(cpu_base + CPU_PC), + info.text_base); return -ENODEV; } - tw32(TX_CPU_BASE + CPU_STATE, 0xffffffff); - tw32(TX_CPU_BASE + CPU_MODE, 0x00000000); + tw32(cpu_base + CPU_STATE, 0xffffffff); + tw32(cpu_base + CPU_MODE, 0x00000000); /* Flush posted writes. */ - tr32(TX_CPU_BASE + CPU_MODE); + tr32(cpu_base + CPU_MODE); return 0; } -#endif /* TG3_DO_TSO != 0 */ +#endif /* TG3_TSO_SUPPORT != 0 */ /* tp->lock is held. */ static void __tg3_set_mac_addr(struct tg3 *tp) @@ -3860,6 +4464,15 @@ tw32(MAC_ADDR_0_LOW + (i * 8), addr_low); } + if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5700 && + GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5701 && + GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5705) { + for (i = 0; i < 12; i++) { + tw32(MAC_EXTADDR_0_HIGH + (i * 8), addr_high); + tw32(MAC_EXTADDR_0_LOW + (i * 8), addr_low); + } + } + addr_high = (tp->dev->dev_addr[0] + tp->dev->dev_addr[1] + tp->dev->dev_addr[2] + @@ -3893,23 +4506,19 @@ u32 nic_addr) { tg3_write_mem(tp, - (bdinfo_addr + - TG3_BDINFO_HOST_ADDR + - TG3_64BIT_REG_HIGH), + (bdinfo_addr + TG3_BDINFO_HOST_ADDR + TG3_64BIT_REG_HIGH), ((u64) mapping >> 32)); tg3_write_mem(tp, - (bdinfo_addr + - TG3_BDINFO_HOST_ADDR + - TG3_64BIT_REG_LOW), + (bdinfo_addr + TG3_BDINFO_HOST_ADDR + TG3_64BIT_REG_LOW), ((u64) mapping & 0xffffffff)); tg3_write_mem(tp, - (bdinfo_addr + - TG3_BDINFO_MAXLEN_FLAGS), + (bdinfo_addr + TG3_BDINFO_MAXLEN_FLAGS), maxlen_flags); - tg3_write_mem(tp, - (bdinfo_addr + - TG3_BDINFO_NIC_ADDR), - nic_addr); + + if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5705) + tg3_write_mem(tp, + (bdinfo_addr + TG3_BDINFO_NIC_ADDR), + nic_addr); } static void __tg3_set_rx_mode(struct net_device *); @@ -3917,8 +4526,8 @@ /* tp->lock is held. */ static int tg3_reset_hw(struct tg3 *tp) { - u32 val; - int i, err; + u32 val, rdmac_mode; + int i, err, limit; tg3_disable_ints(tp); @@ -3970,9 +4579,8 @@ * B3 tigon3 silicon. This bit has no effect on any * other revision. */ - val = tr32(TG3PCI_CLOCK_CTRL); - val |= CLOCK_CTRL_DELAY_PCI_GRANT; - tw32(TG3PCI_CLOCK_CTRL, val); + tp->pci_clock_ctrl |= CLOCK_CTRL_DELAY_PCI_GRANT; + tw32(TG3PCI_CLOCK_CTRL, tp->pci_clock_ctrl); tr32(TG3PCI_CLOCK_CTRL); if (tp->pci_chip_rev_id == CHIPREV_ID_5704_A0 && @@ -3990,11 +4598,13 @@ tg3_init_rings(tp); /* Clear statistics/status block in chip, and status block in ram. */ - for (i = NIC_SRAM_STATS_BLK; - i < NIC_SRAM_STATUS_BLK + TG3_HW_STATUS_SIZE; - i += sizeof(u32)) { - tg3_write_mem(tp, i, 0); - udelay(40); + if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5705) { + for (i = NIC_SRAM_STATS_BLK; + i < NIC_SRAM_STATUS_BLK + TG3_HW_STATUS_SIZE; + i += sizeof(u32)) { + tg3_write_mem(tp, i, 0); + udelay(40); + } } memset(tp->hw_status, 0, TG3_HW_STATUS_SIZE); @@ -4025,13 +4635,31 @@ (65 << GRC_MISC_CFG_PRESCALAR_SHIFT)); /* Initialize MBUF/DESC pool. */ - tw32(BUFMGR_MB_POOL_ADDR, NIC_SRAM_MBUF_POOL_BASE); - if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704) - tw32(BUFMGR_MB_POOL_SIZE, NIC_SRAM_MBUF_POOL_SIZE64); - else - tw32(BUFMGR_MB_POOL_SIZE, NIC_SRAM_MBUF_POOL_SIZE96); - tw32(BUFMGR_DMA_DESC_POOL_ADDR, NIC_SRAM_DMA_DESC_POOL_BASE); - tw32(BUFMGR_DMA_DESC_POOL_SIZE, NIC_SRAM_DMA_DESC_POOL_SIZE); + if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5705) { + tw32(BUFMGR_MB_POOL_ADDR, NIC_SRAM_MBUF_POOL_BASE); + if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704) + tw32(BUFMGR_MB_POOL_SIZE, NIC_SRAM_MBUF_POOL_SIZE64); + else + tw32(BUFMGR_MB_POOL_SIZE, NIC_SRAM_MBUF_POOL_SIZE96); + tw32(BUFMGR_DMA_DESC_POOL_ADDR, NIC_SRAM_DMA_DESC_POOL_BASE); + tw32(BUFMGR_DMA_DESC_POOL_SIZE, NIC_SRAM_DMA_DESC_POOL_SIZE); + } +#if TG3_TSO_SUPPORT != 0 + else if (tp->tg3_flags2 & TG3_FLG2_TSO_CAPABLE) { + int fw_len; + + fw_len = (TG3_TSO5_FW_TEXT_LEN + + TG3_TSO5_FW_RODATA_LEN + + TG3_TSO5_FW_DATA_LEN + + TG3_TSO5_FW_SBSS_LEN + + TG3_TSO5_FW_BSS_LEN); + fw_len = (fw_len + (0x80 - 1)) & ~(0x80 - 1); + tw32(BUFMGR_MB_POOL_ADDR, + NIC_SRAM_MBUF_POOL_BASE5705 + fw_len); + tw32(BUFMGR_MB_POOL_SIZE, + NIC_SRAM_MBUF_POOL_SIZE5705 - fw_len - 0xa00); + } +#endif if (!(tp->tg3_flags & TG3_FLAG_JUMBO_ENABLE)) { tw32(BUFMGR_MB_RDMA_LOW_WATER, @@ -4078,6 +4706,9 @@ return -ENODEV; } + /* Setup replenish threshold. */ + tw32(RCVBDI_STD_THRESH, tp->rx_pending / 8); + /* Initialize TG3_BDINFO's at: * RCVDBDI_STD_BD: standard eth size rx ring * RCVDBDI_JUMBO_BD: jumbo frame rx ring @@ -4099,35 +4730,50 @@ ((u64) tp->rx_std_mapping >> 32)); tw32(RCVDBDI_STD_BD + TG3_BDINFO_HOST_ADDR + TG3_64BIT_REG_LOW, ((u64) tp->rx_std_mapping & 0xffffffff)); - tw32(RCVDBDI_STD_BD + TG3_BDINFO_MAXLEN_FLAGS, - RX_STD_MAX_SIZE << BDINFO_FLAGS_MAXLEN_SHIFT); tw32(RCVDBDI_STD_BD + TG3_BDINFO_NIC_ADDR, NIC_SRAM_RX_BUFFER_DESC); - tw32(RCVDBDI_MINI_BD + TG3_BDINFO_MAXLEN_FLAGS, - BDINFO_FLAGS_DISABLED); - - if (tp->tg3_flags & TG3_FLAG_JUMBO_ENABLE) { - tw32(RCVDBDI_JUMBO_BD + TG3_BDINFO_HOST_ADDR + TG3_64BIT_REG_HIGH, - ((u64) tp->rx_jumbo_mapping >> 32)); - tw32(RCVDBDI_JUMBO_BD + TG3_BDINFO_HOST_ADDR + TG3_64BIT_REG_LOW, - ((u64) tp->rx_jumbo_mapping & 0xffffffff)); - tw32(RCVDBDI_JUMBO_BD + TG3_BDINFO_MAXLEN_FLAGS, - RX_JUMBO_MAX_SIZE << BDINFO_FLAGS_MAXLEN_SHIFT); - tw32(RCVDBDI_JUMBO_BD + TG3_BDINFO_NIC_ADDR, - NIC_SRAM_RX_JUMBO_BUFFER_DESC); + /* Don't even try to program the JUMBO/MINI buffer descriptor + * configs on 5705. + */ + if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705) { + tw32(RCVDBDI_STD_BD + TG3_BDINFO_MAXLEN_FLAGS, + RX_STD_MAX_SIZE_5705 << BDINFO_FLAGS_MAXLEN_SHIFT); } else { - tw32(RCVDBDI_JUMBO_BD + TG3_BDINFO_MAXLEN_FLAGS, + tw32(RCVDBDI_STD_BD + TG3_BDINFO_MAXLEN_FLAGS, + RX_STD_MAX_SIZE << BDINFO_FLAGS_MAXLEN_SHIFT); + + tw32(RCVDBDI_MINI_BD + TG3_BDINFO_MAXLEN_FLAGS, BDINFO_FLAGS_DISABLED); - } - /* Setup replenish thresholds. */ - tw32(RCVBDI_STD_THRESH, tp->rx_pending / 8); - tw32(RCVBDI_JUMBO_THRESH, tp->rx_jumbo_pending / 8); + /* Setup replenish threshold. */ + tw32(RCVBDI_JUMBO_THRESH, tp->rx_jumbo_pending / 8); - /* Clear out send RCB ring in SRAM. */ - for (i = NIC_SRAM_SEND_RCB; i < NIC_SRAM_RCV_RET_RCB; i += TG3_BDINFO_SIZE) - tg3_write_mem(tp, i + TG3_BDINFO_MAXLEN_FLAGS, BDINFO_FLAGS_DISABLED); + if (tp->tg3_flags & TG3_FLAG_JUMBO_ENABLE) { + tw32(RCVDBDI_JUMBO_BD + TG3_BDINFO_HOST_ADDR + TG3_64BIT_REG_HIGH, + ((u64) tp->rx_jumbo_mapping >> 32)); + tw32(RCVDBDI_JUMBO_BD + TG3_BDINFO_HOST_ADDR + TG3_64BIT_REG_LOW, + ((u64) tp->rx_jumbo_mapping & 0xffffffff)); + tw32(RCVDBDI_JUMBO_BD + TG3_BDINFO_MAXLEN_FLAGS, + RX_JUMBO_MAX_SIZE << BDINFO_FLAGS_MAXLEN_SHIFT); + tw32(RCVDBDI_JUMBO_BD + TG3_BDINFO_NIC_ADDR, + NIC_SRAM_RX_JUMBO_BUFFER_DESC); + } else { + tw32(RCVDBDI_JUMBO_BD + TG3_BDINFO_MAXLEN_FLAGS, + BDINFO_FLAGS_DISABLED); + } + + } + + /* There is only one send ring on 5705, no need to explicitly + * disable the others. + */ + if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5705) { + /* Clear out send RCB ring in SRAM. */ + for (i = NIC_SRAM_SEND_RCB; i < NIC_SRAM_RCV_RET_RCB; i += TG3_BDINFO_SIZE) + tg3_write_mem(tp, i + TG3_BDINFO_MAXLEN_FLAGS, + BDINFO_FLAGS_DISABLED); + } tp->tx_prod = 0; tp->tx_cons = 0; @@ -4149,9 +4795,15 @@ NIC_SRAM_TX_BUFFER_DESC); } - for (i = NIC_SRAM_RCV_RET_RCB; i < NIC_SRAM_STATS_BLK; i += TG3_BDINFO_SIZE) { - tg3_write_mem(tp, i + TG3_BDINFO_MAXLEN_FLAGS, - BDINFO_FLAGS_DISABLED); + /* There is only one receive return ring on 5705, no need to explicitly + * disable the others. + */ + if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5705) { + for (i = NIC_SRAM_RCV_RET_RCB; i < NIC_SRAM_STATS_BLK; + i += TG3_BDINFO_SIZE) { + tg3_write_mem(tp, i + TG3_BDINFO_MAXLEN_FLAGS, + BDINFO_FLAGS_DISABLED); + } } tp->rx_rcb_ptr = 0; @@ -4161,7 +4813,7 @@ tg3_set_bdinfo(tp, NIC_SRAM_RCV_RET_RCB, tp->rx_rcb_mapping, - (TG3_RX_RCB_RING_SIZE << + (TG3_RX_RCB_RING_SIZE(tp) << BDINFO_FLAGS_MAXLEN_SHIFT), 0); @@ -4198,8 +4850,36 @@ tw32(MAC_RCV_RULE_CFG, RCV_RULE_CFG_DEFAULT_CLASS); tw32(RCVLPC_CONFIG, 0x0181); + /* Calculate RDMAC_MODE setting early, we need it to determine + * the RCVLPC_STATE_ENABLE mask. + */ + rdmac_mode = (RDMAC_MODE_ENABLE | RDMAC_MODE_TGTABORT_ENAB | + RDMAC_MODE_MSTABORT_ENAB | RDMAC_MODE_PARITYERR_ENAB | + RDMAC_MODE_ADDROFLOW_ENAB | RDMAC_MODE_FIFOOFLOW_ENAB | + RDMAC_MODE_FIFOURUN_ENAB | RDMAC_MODE_FIFOOREAD_ENAB | + RDMAC_MODE_LNGREAD_ENAB); + if (tp->tg3_flags & TG3_FLAG_SPLIT_MODE) + rdmac_mode |= RDMAC_MODE_SPLIT_ENABLE; + if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705) { + if (tp->pci_chip_rev_id != CHIPREV_ID_5705_A0) { + if (tp->tg3_flags2 & TG3_FLG2_TSO_CAPABLE) { + rdmac_mode |= RDMAC_MODE_FIFO_SIZE_128; + } else if (!(tr32(TG3PCI_PCISTATE) & PCISTATE_BUS_SPEED_HIGH) && + !(tp->tg3_flags2 & TG3_FLG2_IS_5788)) { + rdmac_mode |= RDMAC_MODE_FIFO_LONG_BURST; + } + } + } + /* Receive/send statistics. */ - tw32(RCVLPC_STATS_ENABLE, 0xffffff); + if ((rdmac_mode & RDMAC_MODE_FIFO_SIZE_128) && + (tp->tg3_flags2 & TG3_FLG2_TSO_CAPABLE)) { + val = tr32(RCVLPC_STATS_ENABLE); + val &= ~RCVLPC_STATSENAB_LNGBRST_RFIX; + tw32(RCVLPC_STATS_ENABLE, val); + } else { + tw32(RCVLPC_STATS_ENABLE, 0xffffff); + } tw32(RCVLPC_STATSCTRL, RCVLPC_STATSCTRL_ENABLE); tw32(SNDDATAI_STATSENAB, 0xffffff); tw32(SNDDATAI_STATSCTRL, @@ -4215,33 +4895,43 @@ } tw32(HOSTCC_RXCOL_TICKS, 0); - tw32(HOSTCC_RXMAX_FRAMES, 1); - tw32(HOSTCC_RXCOAL_TICK_INT, 0); - tw32(HOSTCC_RXCOAL_MAXF_INT, 1); tw32(HOSTCC_TXCOL_TICKS, LOW_TXCOL_TICKS); + tw32(HOSTCC_RXMAX_FRAMES, 1); tw32(HOSTCC_TXMAX_FRAMES, LOW_RXMAX_FRAMES); - tw32(HOSTCC_TXCOAL_TICK_INT, 0); + if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5705) + tw32(HOSTCC_RXCOAL_TICK_INT, 0); + if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5705) + tw32(HOSTCC_TXCOAL_TICK_INT, 0); + tw32(HOSTCC_RXCOAL_MAXF_INT, 1); tw32(HOSTCC_TXCOAL_MAXF_INT, 0); - tw32(HOSTCC_STAT_COAL_TICKS, - DEFAULT_STAT_COAL_TICKS); - /* Status/statistics block address. */ - tw32(HOSTCC_STATS_BLK_HOST_ADDR + TG3_64BIT_REG_HIGH, - ((u64) tp->stats_mapping >> 32)); - tw32(HOSTCC_STATS_BLK_HOST_ADDR + TG3_64BIT_REG_LOW, - ((u64) tp->stats_mapping & 0xffffffff)); + /* set status block DMA address */ tw32(HOSTCC_STATUS_BLK_HOST_ADDR + TG3_64BIT_REG_HIGH, ((u64) tp->status_mapping >> 32)); tw32(HOSTCC_STATUS_BLK_HOST_ADDR + TG3_64BIT_REG_LOW, ((u64) tp->status_mapping & 0xffffffff)); - tw32(HOSTCC_STATS_BLK_NIC_ADDR, NIC_SRAM_STATS_BLK); - tw32(HOSTCC_STATUS_BLK_NIC_ADDR, NIC_SRAM_STATUS_BLK); + + if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5705) { + /* Status/statistics block address. See tg3_timer, + * the tg3_periodic_fetch_stats call there, and + * tg3_get_stats to see how this works for 5705 chips. + */ + tw32(HOSTCC_STAT_COAL_TICKS, + DEFAULT_STAT_COAL_TICKS); + tw32(HOSTCC_STATS_BLK_HOST_ADDR + TG3_64BIT_REG_HIGH, + ((u64) tp->stats_mapping >> 32)); + tw32(HOSTCC_STATS_BLK_HOST_ADDR + TG3_64BIT_REG_LOW, + ((u64) tp->stats_mapping & 0xffffffff)); + tw32(HOSTCC_STATS_BLK_NIC_ADDR, NIC_SRAM_STATS_BLK); + tw32(HOSTCC_STATUS_BLK_NIC_ADDR, NIC_SRAM_STATUS_BLK); + } tw32(HOSTCC_MODE, HOSTCC_MODE_ENABLE | tp->coalesce_mode); tw32(RCVCC_MODE, RCVCC_MODE_ENABLE | RCVCC_MODE_ATTN_ENABLE); tw32(RCVLPC_MODE, RCVLPC_MODE_ENABLE); - tw32(RCVLSC_MODE, RCVLSC_MODE_ENABLE | RCVLSC_MODE_ATTN_ENABLE); + if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5705) + tw32(RCVLSC_MODE, RCVLSC_MODE_ENABLE | RCVLSC_MODE_ATTN_ENABLE); tp->mac_mode = MAC_MODE_TXSTAT_ENABLE | MAC_MODE_RXSTAT_ENABLE | MAC_MODE_TDE_ENABLE | MAC_MODE_RDE_ENABLE | MAC_MODE_FHDE_ENABLE; @@ -4260,42 +4950,47 @@ tw32_mailbox(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW, 0); tr32(MAILBOX_INTERRUPT_0); - tw32(DMAC_MODE, DMAC_MODE_ENABLE); - tr32(DMAC_MODE); - udelay(40); + if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5705) { + tw32(DMAC_MODE, DMAC_MODE_ENABLE); + tr32(DMAC_MODE); + udelay(40); + } - tw32(WDMAC_MODE, (WDMAC_MODE_ENABLE | WDMAC_MODE_TGTABORT_ENAB | - WDMAC_MODE_MSTABORT_ENAB | WDMAC_MODE_PARITYERR_ENAB | - WDMAC_MODE_ADDROFLOW_ENAB | WDMAC_MODE_FIFOOFLOW_ENAB | - WDMAC_MODE_FIFOURUN_ENAB | WDMAC_MODE_FIFOOREAD_ENAB | - WDMAC_MODE_LNGREAD_ENAB)); + val = (WDMAC_MODE_ENABLE | WDMAC_MODE_TGTABORT_ENAB | + WDMAC_MODE_MSTABORT_ENAB | WDMAC_MODE_PARITYERR_ENAB | + WDMAC_MODE_ADDROFLOW_ENAB | WDMAC_MODE_FIFOOFLOW_ENAB | + WDMAC_MODE_FIFOURUN_ENAB | WDMAC_MODE_FIFOOREAD_ENAB | + WDMAC_MODE_LNGREAD_ENAB); + if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705 && + (tr32(TG3PCI_PCISTATE) & PCISTATE_BUS_SPEED_HIGH) != 0 && + !(tp->tg3_flags2 & TG3_FLG2_IS_5788)) + val |= WDMAC_MODE_RX_ACCEL; + tw32(WDMAC_MODE, val); tr32(WDMAC_MODE); udelay(40); - if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704 && - (tp->tg3_flags & TG3_FLAG_PCIX_MODE)) { + if ((tp->tg3_flags & TG3_FLAG_PCIX_MODE) != 0) { val = tr32(TG3PCI_X_CAPS); - val &= ~(PCIX_CAPS_SPLIT_MASK | PCIX_CAPS_BURST_MASK); - val |= (PCIX_CAPS_MAX_BURST_5704 << PCIX_CAPS_BURST_SHIFT); - if (tp->tg3_flags & TG3_FLAG_SPLIT_MODE) - val |= (tp->split_mode_max_reqs << - PCIX_CAPS_SPLIT_SHIFT); + if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5703) { + val &= ~PCIX_CAPS_BURST_MASK; + val |= (PCIX_CAPS_MAX_BURST_CPIOB << PCIX_CAPS_BURST_SHIFT); + } else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704) { + val &= ~(PCIX_CAPS_SPLIT_MASK | PCIX_CAPS_BURST_MASK); + val |= (PCIX_CAPS_MAX_BURST_CPIOB << PCIX_CAPS_BURST_SHIFT); + if (tp->tg3_flags & TG3_FLAG_SPLIT_MODE) + val |= (tp->split_mode_max_reqs << + PCIX_CAPS_SPLIT_SHIFT); + } tw32(TG3PCI_X_CAPS, val); } - val = (RDMAC_MODE_ENABLE | RDMAC_MODE_TGTABORT_ENAB | - RDMAC_MODE_MSTABORT_ENAB | RDMAC_MODE_PARITYERR_ENAB | - RDMAC_MODE_ADDROFLOW_ENAB | RDMAC_MODE_FIFOOFLOW_ENAB | - RDMAC_MODE_FIFOURUN_ENAB | RDMAC_MODE_FIFOOREAD_ENAB | - RDMAC_MODE_LNGREAD_ENAB); - if (tp->tg3_flags & TG3_FLAG_SPLIT_MODE) - val |= RDMAC_MODE_SPLIT_ENABLE; - tw32(RDMAC_MODE, val); + tw32(RDMAC_MODE, rdmac_mode); tr32(RDMAC_MODE); udelay(40); tw32(RCVDCC_MODE, RCVDCC_MODE_ENABLE | RCVDCC_MODE_ATTN_ENABLE); - tw32(MBFREE_MODE, MBFREE_MODE_ENABLE); + if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5705) + tw32(MBFREE_MODE, MBFREE_MODE_ENABLE); tw32(SNDDATAC_MODE, SNDDATAC_MODE_ENABLE); tw32(SNDBDC_MODE, SNDBDC_MODE_ENABLE | SNDBDC_MODE_ATTN_ENABLE); tw32(RCVBDI_MODE, RCVBDI_MODE_ENABLE | RCVBDI_MODE_RCB_ATTN_ENAB); @@ -4310,8 +5005,8 @@ return err; } -#if TG3_DO_TSO != 0 - if (tp->dev->features & NETIF_F_TSO) { +#if TG3_TSO_SUPPORT != 0 + if (tp->tg3_flags2 & TG3_FLG2_TSO_CAPABLE) { err = tg3_load_tso_firmware(tp); if (err) return err; @@ -4342,9 +5037,11 @@ tw32(MAC_LED_CTRL, 0); tw32(MAC_MI_STAT, MAC_MI_STAT_LNKSTAT_ATTN_ENAB); - tw32(MAC_RX_MODE, RX_MODE_RESET); - tr32(MAC_RX_MODE); - udelay(10); + if (tp->phy_id == PHY_ID_SERDES) { + tw32(MAC_RX_MODE, RX_MODE_RESET); + tr32(MAC_RX_MODE); + udelay(10); + } tw32(MAC_RX_MODE, tp->rx_mode); tr32(MAC_RX_MODE); udelay(10); @@ -4378,22 +5075,48 @@ tw32(MAC_RCV_VALUE_0, 0xffffffff & RCV_RULE_DISABLE_MASK); tw32(MAC_RCV_RULE_1, 0x86000004 & RCV_RULE_DISABLE_MASK); tw32(MAC_RCV_VALUE_1, 0xffffffff & RCV_RULE_DISABLE_MASK); -#if 0 - tw32(MAC_RCV_RULE_2, 0); tw32(MAC_RCV_VALUE_2, 0); - tw32(MAC_RCV_RULE_3, 0); tw32(MAC_RCV_VALUE_3, 0); -#endif - tw32(MAC_RCV_RULE_4, 0); tw32(MAC_RCV_VALUE_4, 0); - tw32(MAC_RCV_RULE_5, 0); tw32(MAC_RCV_VALUE_5, 0); - tw32(MAC_RCV_RULE_6, 0); tw32(MAC_RCV_VALUE_6, 0); - tw32(MAC_RCV_RULE_7, 0); tw32(MAC_RCV_VALUE_7, 0); - tw32(MAC_RCV_RULE_8, 0); tw32(MAC_RCV_VALUE_8, 0); - tw32(MAC_RCV_RULE_9, 0); tw32(MAC_RCV_VALUE_9, 0); - tw32(MAC_RCV_RULE_10, 0); tw32(MAC_RCV_VALUE_10, 0); - tw32(MAC_RCV_RULE_11, 0); tw32(MAC_RCV_VALUE_11, 0); - tw32(MAC_RCV_RULE_12, 0); tw32(MAC_RCV_VALUE_12, 0); - tw32(MAC_RCV_RULE_13, 0); tw32(MAC_RCV_VALUE_13, 0); - tw32(MAC_RCV_RULE_14, 0); tw32(MAC_RCV_VALUE_14, 0); - tw32(MAC_RCV_RULE_15, 0); tw32(MAC_RCV_VALUE_15, 0); + + if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705) + limit = 8; + else + limit = 16; + if (tp->tg3_flags & TG3_FLAG_ENABLE_ASF) + limit -= 4; + switch (limit) { + case 16: + tw32(MAC_RCV_RULE_15, 0); tw32(MAC_RCV_VALUE_15, 0); + case 15: + tw32(MAC_RCV_RULE_14, 0); tw32(MAC_RCV_VALUE_14, 0); + case 14: + tw32(MAC_RCV_RULE_13, 0); tw32(MAC_RCV_VALUE_13, 0); + case 13: + tw32(MAC_RCV_RULE_12, 0); tw32(MAC_RCV_VALUE_12, 0); + case 12: + tw32(MAC_RCV_RULE_11, 0); tw32(MAC_RCV_VALUE_11, 0); + case 11: + tw32(MAC_RCV_RULE_10, 0); tw32(MAC_RCV_VALUE_10, 0); + case 10: + tw32(MAC_RCV_RULE_9, 0); tw32(MAC_RCV_VALUE_9, 0); + case 9: + tw32(MAC_RCV_RULE_8, 0); tw32(MAC_RCV_VALUE_8, 0); + case 8: + tw32(MAC_RCV_RULE_7, 0); tw32(MAC_RCV_VALUE_7, 0); + case 7: + tw32(MAC_RCV_RULE_6, 0); tw32(MAC_RCV_VALUE_6, 0); + case 6: + tw32(MAC_RCV_RULE_5, 0); tw32(MAC_RCV_VALUE_5, 0); + case 5: + tw32(MAC_RCV_RULE_4, 0); tw32(MAC_RCV_VALUE_4, 0); + case 4: + /* tw32(MAC_RCV_RULE_3, 0); tw32(MAC_RCV_VALUE_3, 0); */ + case 3: + /* tw32(MAC_RCV_RULE_2, 0); tw32(MAC_RCV_VALUE_2, 0); */ + case 2: + case 1: + + default: + break; + }; if (tp->tg3_flags & TG3_FLAG_INIT_COMPLETE) tg3_enable_ints(tp); @@ -4423,6 +5146,50 @@ return err; } +#define TG3_STAT_ADD32(PSTAT, REG) \ +do { u32 __val = tr32(REG); \ + (PSTAT)->low += __val; \ + if ((PSTAT)->low < __val) \ + (PSTAT)->high += 1; \ +} while (0) + +static void tg3_periodic_fetch_stats(struct tg3 *tp) +{ + struct tg3_hw_stats *sp = tp->hw_stats; + + if (!netif_carrier_ok(tp->dev)) + return; + + TG3_STAT_ADD32(&sp->tx_octets, MAC_TX_STATS_OCTETS); + TG3_STAT_ADD32(&sp->tx_collisions, MAC_TX_STATS_COLLISIONS); + TG3_STAT_ADD32(&sp->tx_xon_sent, MAC_TX_STATS_XON_SENT); + TG3_STAT_ADD32(&sp->tx_xoff_sent, MAC_TX_STATS_XOFF_SENT); + TG3_STAT_ADD32(&sp->tx_mac_errors, MAC_TX_STATS_MAC_ERRORS); + TG3_STAT_ADD32(&sp->tx_single_collisions, MAC_TX_STATS_SINGLE_COLLISIONS); + TG3_STAT_ADD32(&sp->tx_mult_collisions, MAC_TX_STATS_MULT_COLLISIONS); + TG3_STAT_ADD32(&sp->tx_deferred, MAC_TX_STATS_DEFERRED); + TG3_STAT_ADD32(&sp->tx_excessive_collisions, MAC_TX_STATS_EXCESSIVE_COL); + TG3_STAT_ADD32(&sp->tx_late_collisions, MAC_TX_STATS_LATE_COL); + TG3_STAT_ADD32(&sp->tx_ucast_packets, MAC_TX_STATS_UCAST); + TG3_STAT_ADD32(&sp->tx_mcast_packets, MAC_TX_STATS_MCAST); + TG3_STAT_ADD32(&sp->tx_bcast_packets, MAC_TX_STATS_BCAST); + + TG3_STAT_ADD32(&sp->rx_octets, MAC_RX_STATS_OCTETS); + TG3_STAT_ADD32(&sp->rx_fragments, MAC_RX_STATS_FRAGMENTS); + TG3_STAT_ADD32(&sp->rx_ucast_packets, MAC_RX_STATS_UCAST); + TG3_STAT_ADD32(&sp->rx_mcast_packets, MAC_RX_STATS_MCAST); + TG3_STAT_ADD32(&sp->rx_bcast_packets, MAC_RX_STATS_BCAST); + TG3_STAT_ADD32(&sp->rx_fcs_errors, MAC_RX_STATS_FCS_ERRORS); + TG3_STAT_ADD32(&sp->rx_align_errors, MAC_RX_STATS_ALIGN_ERRORS); + TG3_STAT_ADD32(&sp->rx_xon_pause_rcvd, MAC_RX_STATS_XON_PAUSE_RECVD); + TG3_STAT_ADD32(&sp->rx_xoff_pause_rcvd, MAC_RX_STATS_XOFF_PAUSE_RECVD); + TG3_STAT_ADD32(&sp->rx_mac_ctrl_rcvd, MAC_RX_STATS_MAC_CTRL_RECVD); + TG3_STAT_ADD32(&sp->rx_xoff_entered, MAC_RX_STATS_XOFF_ENTERED); + TG3_STAT_ADD32(&sp->rx_frame_too_long_errors, MAC_RX_STATS_FRAME_TOO_LONG); + TG3_STAT_ADD32(&sp->rx_jabbers, MAC_RX_STATS_JABBERS); + TG3_STAT_ADD32(&sp->rx_undersize_packets, MAC_RX_STATS_UNDERSIZE); +} + static void tg3_timer(unsigned long __opaque) { struct tg3 *tp = (struct tg3 *) __opaque; @@ -4451,6 +5218,9 @@ return; } + if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705) + tg3_periodic_fetch_stats(tp); + /* This part only runs once per second. */ if (!--tp->timer_counter) { if (tp->tg3_flags & TG3_FLAG_USE_LINKCHG_REG) { @@ -4908,7 +5678,9 @@ get_stat64(&hw_stats->rx_bcast_packets); stats->tx_packets = old_stats->tx_packets + - get_stat64(&hw_stats->COS_out_packets[0]); + get_stat64(&hw_stats->tx_ucast_packets) + + get_stat64(&hw_stats->tx_mcast_packets) + + get_stat64(&hw_stats->tx_bcast_packets); stats->rx_bytes = old_stats->rx_bytes + get_stat64(&hw_stats->rx_octets); @@ -5232,6 +6004,20 @@ tp->msg_enable = value; } +#if TG3_TSO_SUPPORT != 0 +static int tg3_set_tso(struct net_device *dev, u32 value) +{ + struct tg3 *tp = dev->priv; + + if (!(tp->tg3_flags2 & TG3_FLG2_TSO_CAPABLE)) { + if (value) + return -EINVAL; + return 0; + } + return ethtool_op_set_tso(dev, value); +} +#endif + static int tg3_nway_reset(struct net_device *dev) { struct tg3 *tp = dev->priv; @@ -5279,11 +6065,14 @@ spin_lock(&tp->tx_lock); tp->rx_pending = ering->rx_pending; + + if ((tp->tg3_flags2 & TG3_FLG2_MAX_RXPEND_64) && + tp->rx_pending > 64) + tp->rx_pending = 64; tp->rx_jumbo_pending = ering->rx_jumbo_pending; tp->tx_pending = ering->tx_pending; tg3_halt(tp); - tg3_init_rings(tp); tg3_init_hw(tp); netif_wake_queue(tp->dev); spin_unlock(&tp->tx_lock); @@ -5322,7 +6111,6 @@ else tp->tg3_flags &= ~TG3_FLAG_PAUSE_TX; tg3_halt(tp); - tg3_init_rings(tp); tg3_init_hw(tp); spin_unlock(&tp->tx_lock); spin_unlock_irq(&tp->lock); @@ -5467,6 +6255,10 @@ .set_tx_csum = tg3_set_tx_csum, .get_sg = ethtool_op_get_sg, .set_sg = ethtool_op_set_sg, +#if TG3_TSO_SUPPORT != 0 + .get_tso = ethtool_op_get_tso, + .set_tso = tg3_set_tso, +#endif }; /* Chips other than 5700/5701 use the NVRAM for fetching info. */ @@ -5669,6 +6461,7 @@ u32 nic_cfg; tg3_read_mem(tp, NIC_SRAM_DATA_CFG, &nic_cfg); + tp->nic_sram_data_cfg = nic_cfg; eeprom_signature_found = 1; @@ -5702,8 +6495,10 @@ eeprom_led_mode = led_mode_auto; break; }; - if ((tp->pci_chip_rev_id == CHIPREV_ID_5703_A1 || - tp->pci_chip_rev_id == CHIPREV_ID_5703_A2) && + + if (((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5703) || + (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704) || + (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705)) && (nic_cfg & NIC_SRAM_DATA_CFG_EEPROM_WP)) tp->tg3_flags |= TG3_FLAG_EEPROM_WRITE_PROT; @@ -5785,9 +6580,7 @@ } /* Enable Ethernet@WireSpeed */ - tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x7007); - tg3_readphy(tp, MII_TG3_AUX_CTRL, &val); - tg3_writephy(tp, MII_TG3_AUX_CTRL, (val | (1 << 15) | (1 << 4))); + tg3_phy_set_wirespeed(tp); if (!err && ((tp->phy_id & PHY_ID_MASK) == PHY_ID_BCM5401)) { err = tg3_init_5401phy_dsp(tp); @@ -5927,7 +6720,7 @@ tp->tg3_flags2 |= TG3_FLG2_SUN_5704; #endif - /* If we have an AMD 762 or Intel ICH/ICH0 chipset, write + /* If we have an AMD 762 or Intel ICH/ICH0/ICH2 chipset, write * reordering to the mailbox registers done by the host * controller can cause major troubles. We read back from * every mailbox register write to force the writes to be @@ -5937,6 +6730,10 @@ PCI_DEVICE_ID_INTEL_82801AA_8, NULL) || pci_find_device(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801AB_8, NULL) || + pci_find_device(PCI_VENDOR_ID_INTEL, + PCI_DEVICE_ID_INTEL_82801BA_11, NULL) || + pci_find_device(PCI_VENDOR_ID_INTEL, + PCI_DEVICE_ID_INTEL_82801BA_6, NULL) || pci_find_device(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_FE_GATE_700C, NULL)) tp->tg3_flags |= TG3_FLAG_MBOX_WRITE_REORDER; @@ -6085,7 +6882,15 @@ tp->tg3_flags |= TG3_FLAG_WOL_SPEED_100MB; } + /* A few boards don't want Ethernet@WireSpeed phy feature */ + if ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5700) || + ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705) && + (tp->pci_chip_rev_id != CHIPREV_ID_5705_A0) && + (tp->pci_chip_rev_id != CHIPREV_ID_5705_A1))) + tp->tg3_flags2 |= TG3_FLG2_NO_ETH_WIRE_SPEED; + /* Only 5701 and later support tagged irq status mode. + * Also, 5788 chips cannot use tagged irq status. * * However, since we are using NAPI avoid tagged irq status * because the interrupt condition is more difficult to @@ -6142,7 +6947,8 @@ /* Determine if TX descriptors will reside in * main memory or in the chip SRAM. */ - if (tp->tg3_flags & TG3_FLAG_PCIX_TARGET_HWBUG) + if ((tp->tg3_flags & TG3_FLAG_PCIX_TARGET_HWBUG) != 0 || + GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705) tp->tg3_flags |= TG3_FLAG_HOST_TXDS; grc_misc_cfg = tr32(GRC_MISC_CFG); @@ -6154,8 +6960,18 @@ tp->split_mode_max_reqs = SPLIT_MODE_5704_MAX_REQ; } - /* this one is limited to 10/100 only */ - if (grc_misc_cfg == GRC_MISC_CFG_BOARD_ID_5702FE) + if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705 && + (grc_misc_cfg == GRC_MISC_CFG_BOARD_ID_5788 || + grc_misc_cfg == GRC_MISC_CFG_BOARD_ID_5788M)) + tp->tg3_flags2 |= TG3_FLG2_IS_5788; + + /* these are limited to 10/100 only */ + if ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5703 && + (grc_misc_cfg == 0x8000 || grc_misc_cfg == 0x4000)) || + (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705 && + tp->pdev->vendor == PCI_VENDOR_ID_BROADCOM && + (tp->pdev->device == PCI_DEVICE_ID_TIGON3_5901 || + tp->pdev->device == PCI_DEVICE_ID_TIGON3_5901_2))) tp->tg3_flags |= TG3_FLAG_10_100_ONLY; err = tg3_phy_probe(tp); @@ -6414,8 +7230,6 @@ goto out_nofree; } - tw32(TG3PCI_CLOCK_CTRL, 0); - if ((tp->tg3_flags & TG3_FLAG_PCIX_MODE) == 0) { tp->dma_rwctrl = (0x7 << DMA_RWCTRL_PCI_WRITE_CMD_SHIFT) | @@ -6423,7 +7237,9 @@ (0x7 << DMA_RWCTRL_WRITE_WATER_SHIFT) | (0x7 << DMA_RWCTRL_READ_WATER_SHIFT) | (0x0f << DMA_RWCTRL_MIN_DMA_SHIFT); - /* XXX 5705 note: set MIN_DMA to zero here */ + if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705) + tp->dma_rwctrl &= ~(DMA_RWCTRL_MIN_DMA + << DMA_RWCTRL_MIN_DMA_SHIFT); } else { if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704) tp->dma_rwctrl = @@ -6524,8 +7340,15 @@ tp->dma_rwctrl |= DMA_RWCTRL_USE_MEM_READ_MULT; } + tp->dma_rwctrl |= DMA_RWCTRL_ASSERT_ALL_BE; + tw32(TG3PCI_DMA_RW_CTRL, tp->dma_rwctrl); +#if 0 + /* Unneeded, already done by tg3_get_invariants. */ + tg3_switch_clocks(tp); +#endif + ret = 0; if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5700 && GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5701) @@ -6630,12 +7453,35 @@ case PHY_ID_BCM5701: return "5701"; case PHY_ID_BCM5703: return "5703"; case PHY_ID_BCM5704: return "5704"; + case PHY_ID_BCM5705: return "5705"; case PHY_ID_BCM8002: return "8002"; case PHY_ID_SERDES: return "serdes"; default: return "unknown"; }; } +static struct pci_dev * __devinit tg3_find_5704_peer(struct tg3 *tp) +{ + struct pci_dev *peer = NULL; + unsigned int func; + + for (func = 0; func < 7; func++) { + unsigned int devfn = tp->pdev->devfn; + + devfn &= ~7; + devfn |= func; + + if (devfn == tp->pdev->devfn) + continue; + peer = pci_find_slot(tp->pdev->bus->number, devfn); + if (peer) + break; + } + if (!peer || peer == tp->pdev) + BUG(); + return peer; +} + static int __devinit tg3_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) { @@ -6688,7 +7534,7 @@ goto err_out_free_res; } } else { - err = pci_set_dma_mask(pdev, (u64) 0xffffffff); + err = pci_set_dma_mask(pdev, 0xffffffffULL); if (err) { printk(KERN_ERR PFX "No usable DMA configuration, " "aborting.\n"); @@ -6794,6 +7640,44 @@ goto err_out_iounmap; } + if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705) { + tp->bufmgr_config.mbuf_read_dma_low_water = + DEFAULT_MB_RDMA_LOW_WATER_5705; + tp->bufmgr_config.mbuf_mac_rx_low_water = + DEFAULT_MB_MACRX_LOW_WATER_5705; + tp->bufmgr_config.mbuf_high_water = + DEFAULT_MB_HIGH_WATER_5705; + } + +#if TG3_TSO_SUPPORT != 0 + if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5700 || + GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5701 || + tp->pci_chip_rev_id == CHIPREV_ID_5705_A0 || + (tp->tg3_flags & TG3_FLAG_ENABLE_ASF) != 0 || + (tp->tg3_flags2 & TG3_FLG2_IS_5788)) { + tp->tg3_flags2 &= ~TG3_FLG2_TSO_CAPABLE; + } else { + tp->tg3_flags2 |= TG3_FLG2_TSO_CAPABLE; + } + + /* TSO is off by default, user can enable using ethtool. */ +#if 0 + if (tp->tg3_flags2 & TG3_FLG2_TSO_CAPABLE) + dev->features |= NETIF_F_TSO; +#endif + +#endif + + if (tp->pci_chip_rev_id == CHIPREV_ID_5705_A1 && + !(tp->tg3_flags2 & TG3_FLG2_TSO_CAPABLE) && + !(tr32(TG3PCI_PCISTATE) & PCISTATE_BUS_SPEED_HIGH)) { + tp->tg3_flags2 |= TG3_FLG2_MAX_RXPEND_64; + tp->rx_pending = 64; + } + + if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704) + tp->pdev_peer = tg3_find_5704_peer(tp); + err = tg3_get_device_address(tp); if (err) { printk(KERN_ERR PFX "Could not obtain valid ethernet address, " @@ -6816,16 +7700,8 @@ } else tp->tg3_flags &= ~TG3_FLAG_RX_CHECKSUMS; -#if TG3_DO_TSO != 0 - if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5700 || - (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5701 && - tp->pci_chip_rev_id <= CHIPREV_ID_5701_B2)) { - /* Not TSO capable. */ - dev->features &= ~NETIF_F_TSO; - } else { - dev->features |= NETIF_F_TSO; - } -#endif + if (tp->tg3_flags2 & TG3_FLG2_IS_5788) + dev->features &= ~NETIF_F_HIGHDMA; err = register_netdev(dev); if (err) { diff -Nru a/drivers/net/tg3.h b/drivers/net/tg3.h --- a/drivers/net/tg3.h Tue Sep 2 19:58:13 2003 +++ b/drivers/net/tg3.h Tue Sep 2 19:58:13 2003 @@ -24,6 +24,7 @@ #define RX_COPY_THRESHOLD 256 #define RX_STD_MAX_SIZE 1536 +#define RX_STD_MAX_SIZE_5705 512 #define RX_JUMBO_MAX_SIZE 0xdeadbeef /* XXX */ /* First 256 bytes are a mirror of PCI config space. */ @@ -59,7 +60,7 @@ #define PCIX_CAPS_SPLIT_SHIFT 20 #define PCIX_CAPS_BURST_MASK 0x000c0000 #define PCIX_CAPS_BURST_SHIFT 18 -#define PCIX_CAPS_MAX_BURST_5704 2 +#define PCIX_CAPS_MAX_BURST_CPIOB 2 #define TG3PCI_PM_CAP_PTR 0x00000041 #define TG3PCI_X_COMMAND 0x00000042 #define TG3PCI_X_STATUS 0x00000044 @@ -115,11 +116,14 @@ #define CHIPREV_ID_5704_A0 0x2000 #define CHIPREV_ID_5704_A1 0x2001 #define CHIPREV_ID_5704_A2 0x2002 +#define CHIPREV_ID_5705_A0 0x3000 +#define CHIPREV_ID_5705_A1 0x3001 #define GET_ASIC_REV(CHIP_REV_ID) ((CHIP_REV_ID) >> 12) #define ASIC_REV_5700 0x07 #define ASIC_REV_5701 0x00 #define ASIC_REV_5703 0x01 #define ASIC_REV_5704 0x02 +#define ASIC_REV_5705 0x03 #define GET_CHIP_REV(CHIP_REV_ID) ((CHIP_REV_ID) >> 8) #define CHIPREV_5700_AX 0x70 #define CHIPREV_5700_BX 0x71 @@ -180,6 +184,9 @@ #define CLOCK_CTRL_ALTCLK 0x00001000 #define CLOCK_CTRL_PWRDOWN_PLL133 0x00008000 #define CLOCK_CTRL_44MHZ_CORE 0x00040000 +#define CLOCK_CTRL_625_CORE 0x00100000 +#define CLOCK_CTRL_FORCE_CLKRUN 0x00200000 +#define CLOCK_CTRL_CLKRUN_OENABLE 0x00400000 #define CLOCK_CTRL_DELAY_PCI_GRANT 0x80000000 #define TG3PCI_REG_BASE_ADDR 0x00000078 #define TG3PCI_MEM_WIN_BASE_ADDR 0x0000007c @@ -457,17 +464,89 @@ #define MAC_RCV_RULE_CFG 0x00000500 #define RCV_RULE_CFG_DEFAULT_CLASS 0x00000008 #define MAC_LOW_WMARK_MAX_RX_FRAME 0x00000504 -/* 0x504 --> 0x590 unused */ +/* 0x508 --> 0x520 unused */ +#define MAC_HASHREGU_0 0x00000520 +#define MAC_HASHREGU_1 0x00000524 +#define MAC_HASHREGU_2 0x00000528 +#define MAC_HASHREGU_3 0x0000052c +#define MAC_EXTADDR_0_HIGH 0x00000530 +#define MAC_EXTADDR_0_LOW 0x00000534 +#define MAC_EXTADDR_1_HIGH 0x00000538 +#define MAC_EXTADDR_1_LOW 0x0000053c +#define MAC_EXTADDR_2_HIGH 0x00000540 +#define MAC_EXTADDR_2_LOW 0x00000544 +#define MAC_EXTADDR_3_HIGH 0x00000548 +#define MAC_EXTADDR_3_LOW 0x0000054c +#define MAC_EXTADDR_4_HIGH 0x00000550 +#define MAC_EXTADDR_4_LOW 0x00000554 +#define MAC_EXTADDR_5_HIGH 0x00000558 +#define MAC_EXTADDR_5_LOW 0x0000055c +#define MAC_EXTADDR_6_HIGH 0x00000560 +#define MAC_EXTADDR_6_LOW 0x00000564 +#define MAC_EXTADDR_7_HIGH 0x00000568 +#define MAC_EXTADDR_7_LOW 0x0000056c +#define MAC_EXTADDR_8_HIGH 0x00000570 +#define MAC_EXTADDR_8_LOW 0x00000574 +#define MAC_EXTADDR_9_HIGH 0x00000578 +#define MAC_EXTADDR_9_LOW 0x0000057c +#define MAC_EXTADDR_10_HIGH 0x00000580 +#define MAC_EXTADDR_10_LOW 0x00000584 +#define MAC_EXTADDR_11_HIGH 0x00000588 +#define MAC_EXTADDR_11_LOW 0x0000058c #define MAC_SERDES_CFG 0x00000590 #define MAC_SERDES_STAT 0x00000594 /* 0x598 --> 0x600 unused */ #define MAC_TX_MAC_STATE_BASE 0x00000600 /* 16 bytes */ #define MAC_RX_MAC_STATE_BASE 0x00000610 /* 20 bytes */ /* 0x624 --> 0x800 unused */ -#define MAC_RX_STATS_BASE 0x00000800 /* 26 32-bit words */ -/* 0x868 --> 0x880 unused */ -#define MAC_TX_STATS_BASE 0x00000880 /* 28 32-bit words */ -/* 0x8f0 --> 0xc00 unused */ +#define MAC_TX_STATS_OCTETS 0x00000800 +#define MAC_TX_STATS_RESV1 0x00000804 +#define MAC_TX_STATS_COLLISIONS 0x00000808 +#define MAC_TX_STATS_XON_SENT 0x0000080c +#define MAC_TX_STATS_XOFF_SENT 0x00000810 +#define MAC_TX_STATS_RESV2 0x00000814 +#define MAC_TX_STATS_MAC_ERRORS 0x00000818 +#define MAC_TX_STATS_SINGLE_COLLISIONS 0x0000081c +#define MAC_TX_STATS_MULT_COLLISIONS 0x00000820 +#define MAC_TX_STATS_DEFERRED 0x00000824 +#define MAC_TX_STATS_RESV3 0x00000828 +#define MAC_TX_STATS_EXCESSIVE_COL 0x0000082c +#define MAC_TX_STATS_LATE_COL 0x00000830 +#define MAC_TX_STATS_RESV4_1 0x00000834 +#define MAC_TX_STATS_RESV4_2 0x00000838 +#define MAC_TX_STATS_RESV4_3 0x0000083c +#define MAC_TX_STATS_RESV4_4 0x00000840 +#define MAC_TX_STATS_RESV4_5 0x00000844 +#define MAC_TX_STATS_RESV4_6 0x00000848 +#define MAC_TX_STATS_RESV4_7 0x0000084c +#define MAC_TX_STATS_RESV4_8 0x00000850 +#define MAC_TX_STATS_RESV4_9 0x00000854 +#define MAC_TX_STATS_RESV4_10 0x00000858 +#define MAC_TX_STATS_RESV4_11 0x0000085c +#define MAC_TX_STATS_RESV4_12 0x00000860 +#define MAC_TX_STATS_RESV4_13 0x00000864 +#define MAC_TX_STATS_RESV4_14 0x00000868 +#define MAC_TX_STATS_UCAST 0x0000086c +#define MAC_TX_STATS_MCAST 0x00000870 +#define MAC_TX_STATS_BCAST 0x00000874 +#define MAC_TX_STATS_RESV5_1 0x00000878 +#define MAC_TX_STATS_RESV5_2 0x0000087c +#define MAC_RX_STATS_OCTETS 0x00000880 +#define MAC_RX_STATS_RESV1 0x00000884 +#define MAC_RX_STATS_FRAGMENTS 0x00000888 +#define MAC_RX_STATS_UCAST 0x0000088c +#define MAC_RX_STATS_MCAST 0x00000890 +#define MAC_RX_STATS_BCAST 0x00000894 +#define MAC_RX_STATS_FCS_ERRORS 0x00000898 +#define MAC_RX_STATS_ALIGN_ERRORS 0x0000089c +#define MAC_RX_STATS_XON_PAUSE_RECVD 0x000008a0 +#define MAC_RX_STATS_XOFF_PAUSE_RECVD 0x000008a4 +#define MAC_RX_STATS_MAC_CTRL_RECVD 0x000008a8 +#define MAC_RX_STATS_XOFF_ENTERED 0x000008ac +#define MAC_RX_STATS_FRAME_TOO_LONG 0x000008b0 +#define MAC_RX_STATS_JABBERS 0x000008b4 +#define MAC_RX_STATS_UNDERSIZE 0x000008b8 +/* 0x8bc --> 0xc00 unused */ /* Send data initiator control registers */ #define SNDDATAI_MODE 0x00000c00 @@ -599,6 +678,7 @@ #define RCVLPC_STATSCTRL_ENABLE 0x00000001 #define RCVLPC_STATSCTRL_FASTUPD 0x00000002 #define RCVLPC_STATS_ENABLE 0x00002018 +#define RCVLPC_STATSENAB_LNGBRST_RFIX 0x00400000 #define RCVLPC_STATS_INCMASK 0x0000201c /* 0x2020 --> 0x2100 unused */ #define RCVLPC_SELLST_BASE 0x00002100 /* 16 16-byte entries */ @@ -812,13 +892,16 @@ #define BUFMGR_MB_POOL_ADDR 0x00004408 #define BUFMGR_MB_POOL_SIZE 0x0000440c #define BUFMGR_MB_RDMA_LOW_WATER 0x00004410 -#define DEFAULT_MB_RDMA_LOW_WATER 0x00000040 +#define DEFAULT_MB_RDMA_LOW_WATER 0x00000050 +#define DEFAULT_MB_RDMA_LOW_WATER_5705 0x00000000 #define DEFAULT_MB_RDMA_LOW_WATER_JUMBO 0x00000130 #define BUFMGR_MB_MACRX_LOW_WATER 0x00004414 #define DEFAULT_MB_MACRX_LOW_WATER 0x00000020 +#define DEFAULT_MB_MACRX_LOW_WATER_5705 0x00000010 #define DEFAULT_MB_MACRX_LOW_WATER_JUMBO 0x00000098 #define BUFMGR_MB_HIGH_WATER 0x00004418 #define DEFAULT_MB_HIGH_WATER 0x00000060 +#define DEFAULT_MB_HIGH_WATER_5705 0x00000060 #define DEFAULT_MB_HIGH_WATER_JUMBO 0x0000017c #define BUFMGR_RX_MB_ALLOC_REQ 0x0000441c #define BUFMGR_MB_ALLOC_BIT 0x10000000 @@ -854,6 +937,8 @@ #define RDMAC_MODE_LNGREAD_ENAB 0x00000200 #define RDMAC_MODE_SPLIT_ENABLE 0x00000800 #define RDMAC_MODE_SPLIT_RESET 0x00001000 +#define RDMAC_MODE_FIFO_SIZE_128 0x00020000 +#define RDMAC_MODE_FIFO_LONG_BURST 0x00030000 #define RDMAC_STATUS 0x00004804 #define RDMAC_STATUS_TGTABORT 0x00000004 #define RDMAC_STATUS_MSTABORT 0x00000008 @@ -877,6 +962,7 @@ #define WDMAC_MODE_FIFOURUN_ENAB 0x00000080 #define WDMAC_MODE_FIFOOREAD_ENAB 0x00000100 #define WDMAC_MODE_LNGREAD_ENAB 0x00000200 +#define WDMAC_MODE_RX_ACCEL 0x00000400 #define WDMAC_STATUS 0x00004c04 #define WDMAC_STATUS_TGTABORT 0x00000004 #define WDMAC_STATUS_MSTABORT 0x00000008 @@ -1140,7 +1226,10 @@ #define GRC_MISC_CFG_BOARD_ID_5704 0x00000000 #define GRC_MISC_CFG_BOARD_ID_5704CIOBE 0x00004000 #define GRC_MISC_CFG_BOARD_ID_5704_A2 0x00008000 +#define GRC_MISC_CFG_BOARD_ID_5788 0x00010000 +#define GRC_MISC_CFG_BOARD_ID_5788M 0x00018000 #define GRC_MISC_CFG_BOARD_ID_AC91002A1 0x00018000 +#define GRC_MISC_CFG_KEEP_GPHY_POWER 0x04000000 #define GRC_LOCAL_CTRL 0x00006808 #define GRC_LCLCTRL_INT_ACTIVE 0x00000001 #define GRC_LCLCTRL_CLEARINT 0x00000002 @@ -1275,6 +1364,7 @@ #define NIC_SRAM_DATA_CFG_WOL_ENABLE 0x00000040 #define NIC_SRAM_DATA_CFG_ASF_ENABLE 0x00000080 #define NIC_SRAM_DATA_CFG_EEPROM_WP 0x00000100 +#define NIC_SRAM_DATA_CFG_MINI_PCI 0x00001000 #define NIC_SRAM_DATA_CFG_FIBER_WOL 0x00004000 #define NIC_SRAM_DATA_PHY_ID 0x00000b74 @@ -1312,6 +1402,8 @@ #define NIC_SRAM_MBUF_POOL_BASE 0x00008000 #define NIC_SRAM_MBUF_POOL_SIZE96 0x00018000 #define NIC_SRAM_MBUF_POOL_SIZE64 0x00010000 +#define NIC_SRAM_MBUF_POOL_BASE5705 0x00010000 +#define NIC_SRAM_MBUF_POOL_SIZE5705 0x0000e000 /* Currently this is fixed. */ #define PHY_ADDR 0x01 @@ -1824,6 +1916,10 @@ u32 tg3_flags2; #define TG3_FLG2_RESTART_TIMER 0x00000001 #define TG3_FLG2_SUN_5704 0x00000002 +#define TG3_FLG2_NO_ETH_WIRE_SPEED 0x00000004 +#define TG3_FLG2_IS_5788 0x00000008 +#define TG3_FLG2_MAX_RXPEND_64 0x00000010 +#define TG3_FLG2_TSO_CAPABLE 0x00000020 u32 split_mode_max_reqs; #define SPLIT_MODE_5704_MAX_REQ 3 @@ -1868,6 +1964,7 @@ #define PHY_ID_BCM5701 0x60008110 #define PHY_ID_BCM5703 0x60008160 #define PHY_ID_BCM5704 0x60008190 +#define PHY_ID_BCM5705 0x600081a0 #define PHY_ID_BCM8002 0x60010140 #define PHY_ID_SERDES 0xfeedbee0 #define PHY_ID_INVALID 0xffffffff @@ -1880,6 +1977,9 @@ enum phy_led_mode led_mode; char board_part_number[24]; + u32 nic_sram_data_cfg; + u32 pci_clock_ctrl; + struct pci_dev *pdev_peer; /* This macro assumes the passed PHY ID is already masked * with PHY_ID_MASK. @@ -1888,6 +1988,7 @@ ((X) == PHY_ID_BCM5400 || (X) == PHY_ID_BCM5401 || \ (X) == PHY_ID_BCM5411 || (X) == PHY_ID_BCM5701 || \ (X) == PHY_ID_BCM5703 || (X) == PHY_ID_BCM5704 || \ + (X) == PHY_ID_BCM5705 || \ (X) == PHY_ID_BCM8002 || (X) == PHY_ID_SERDES) struct tg3_hw_stats *hw_stats; diff -Nru a/drivers/net/tokenring/lanstreamer.c b/drivers/net/tokenring/lanstreamer.c --- a/drivers/net/tokenring/lanstreamer.c Tue Sep 2 19:58:19 2003 +++ b/drivers/net/tokenring/lanstreamer.c Tue Sep 2 19:58:19 2003 @@ -228,7 +228,6 @@ int rc = 0; static int card_no=-1; u16 pcr; - u8 cls = 0; #if STREAMER_DEBUG printk("lanstreamer::streamer_init_one, entry pdev %p\n",pdev); @@ -254,14 +253,16 @@ #endif #endif - if (pci_set_dma_mask(pdev, 0xFFFFFFFF)) { + rc = pci_set_dma_mask(pdev, 0xFFFFFFFFULL); + if (rc) { printk(KERN_ERR "%s: No suitable PCI mapping available.\n", dev->name); rc = -ENODEV; goto err_out; } - if (pci_enable_device(pdev)) { + rc = pci_enable_device(pdev); + if (rc) { printk(KERN_ERR "lanstreamer: unable to enable pci device\n"); rc=-EIO; goto err_out; @@ -269,6 +270,12 @@ pci_set_master(pdev); + rc = pci_set_mwi(pdev); + if (rc) { + printk(KERN_ERR "lanstreamer: unable to enable MWI on pci device\n"); + goto err_out_disable; + } + pio_start = pci_resource_start(pdev, 0); pio_end = pci_resource_end(pdev, 0); pio_flags = pci_resource_flags(pdev, 0); @@ -290,7 +297,7 @@ printk(KERN_ERR "lanstreamer: unable to get pci io addr %lx\n", pio_start); rc= -EBUSY; - goto err_out; + goto err_out_mwi; } if (!request_mem_region(mmio_start, mmio_len, "lanstreamer")) { @@ -341,26 +348,9 @@ spin_lock_init(&streamer_priv->streamer_lock); - pci_read_config_byte(pdev, PCI_CACHE_LINE_SIZE, &cls); - cls <<= 2; - if (cls != SMP_CACHE_BYTES) { - printk(KERN_INFO " PCI cache line size set incorrectly " - "(%i bytes) by BIOS/FW, ", cls); - if (cls > SMP_CACHE_BYTES) - printk("expecting %i\n", SMP_CACHE_BYTES); - else { - printk("correcting to %i\n", SMP_CACHE_BYTES); - pci_write_config_byte(pdev, PCI_CACHE_LINE_SIZE, - SMP_CACHE_BYTES >> 2); - } - } - pci_read_config_word (pdev, PCI_COMMAND, &pcr); - - pcr |= (PCI_COMMAND_INVALIDATE | PCI_COMMAND_SERR); - + pcr |= PCI_COMMAND_SERR; pci_write_config_word (pdev, PCI_COMMAND, pcr); - pci_read_config_word (pdev, PCI_COMMAND, &pcr); printk("%s \n", version); printk("%s: %s. I/O at %hx, MMIO at %p, using irq %d\n",dev->name, @@ -383,8 +373,12 @@ release_mem_region(mmio_start, mmio_len); err_out_free_pio: release_region(pio_start, pio_len); +err_out_mwi: + pci_clear_mwi(pdev); +err_out_disable: + pci_disable_device(pdev); err_out: - kfree(dev); + free_netdev(dev); #if STREAMER_DEBUG printk("lanstreamer: Exit error %x\n",rc); #endif @@ -430,9 +424,11 @@ #endif unregister_netdev(dev); - /* shouldn't we do iounmap here? */ - release_region(pci_resource_start(pdev, 0), pci_resource_len(pdev,0)); + iounmap(streamer_priv->streamer_mmio); release_mem_region(pci_resource_start(pdev, 1), pci_resource_len(pdev,1)); + release_region(pci_resource_start(pdev, 0), pci_resource_len(pdev,0)); + pci_clear_mwi(pdev); + pci_disable_device(pdev); free_netdev(dev); pci_set_drvdata(pdev, NULL); } diff -Nru a/drivers/net/tulip/Kconfig b/drivers/net/tulip/Kconfig --- a/drivers/net/tulip/Kconfig Tue Sep 2 19:58:18 2003 +++ b/drivers/net/tulip/Kconfig Tue Sep 2 19:58:18 2003 @@ -129,7 +129,7 @@ config PCMCIA_XIRTULIP tristate "Xircom Tulip-like CardBus support (old driver)" - depends on NET_TULIP && CARDBUS + depends on NET_TULIP && CARDBUS && BROKEN_ON_SMP ---help--- This driver is for the Digital "Tulip" Ethernet CardBus adapters. It should work with most DEC 21*4*-based chips/ethercards, as well diff -Nru a/drivers/net/tulip/de2104x.c b/drivers/net/tulip/de2104x.c --- a/drivers/net/tulip/de2104x.c Tue Sep 2 19:58:18 2003 +++ b/drivers/net/tulip/de2104x.c Tue Sep 2 19:58:18 2003 @@ -1,6 +1,6 @@ /* de2104x.c: A Linux PCI Ethernet driver for Intel/Digital 21040/1 chips. */ /* - Copyright 2001 Jeff Garzik + Copyright 2001,2003 Jeff Garzik Copyright 1994, 1995 Digital Equipment Corporation. [de4x5.c] Written/copyright 1994-2001 by Donald Becker. [tulip.c] @@ -28,8 +28,8 @@ */ #define DRV_NAME "de2104x" -#define DRV_VERSION "0.5.4" -#define DRV_RELDATE "Jan 1, 2002" +#define DRV_VERSION "0.6" +#define DRV_RELDATE "Sep 1, 2003" #include #include @@ -1464,7 +1464,7 @@ netif_wake_queue(dev); } -static int de_get_regs(struct de_private *de, u8 *buf) +static void __de_get_regs(struct de_private *de, u8 *buf) { int i; u32 *rbuf = (u32 *)buf; @@ -1475,11 +1475,9 @@ /* handle self-clearing RxMissed counter, CSR8 */ de_rx_missed(de, rbuf[8]); - - return 0; } -static int de_ethtool_gset(struct de_private *de, struct ethtool_cmd *ecmd) +static int __de_get_settings(struct de_private *de, struct ethtool_cmd *ecmd) { ecmd->supported = de->media_supported; ecmd->transceiver = XCVR_INTERNAL; @@ -1516,7 +1514,7 @@ return 0; } -static int de_ethtool_sset(struct de_private *de, struct ethtool_cmd *ecmd) +static int __de_set_settings(struct de_private *de, struct ethtool_cmd *ecmd) { u32 new_media; unsigned int media_lock; @@ -1584,169 +1582,121 @@ return 0; } -static int de_ethtool_ioctl (struct de_private *de, void *useraddr) +static void de_get_drvinfo (struct net_device *dev,struct ethtool_drvinfo *info) { - u32 ethcmd; + struct de_private *de = dev->priv; - /* dev_ioctl() in ../../net/core/dev.c has already checked - capable(CAP_NET_ADMIN), so don't bother with that here. */ + strcpy (info->driver, DRV_NAME); + strcpy (info->version, DRV_VERSION); + strcpy (info->bus_info, pci_name(de->pdev)); + info->eedump_len = DE_EEPROM_SIZE; +} - if (get_user(ethcmd, (u32 *)useraddr)) - return -EFAULT; - - switch (ethcmd) { - - case ETHTOOL_GDRVINFO: { - struct ethtool_drvinfo info = { ETHTOOL_GDRVINFO }; - strcpy (info.driver, DRV_NAME); - strcpy (info.version, DRV_VERSION); - strcpy (info.bus_info, pci_name(de->pdev)); - info.eedump_len = DE_EEPROM_SIZE; - info.regdump_len = DE_REGS_SIZE; - if (copy_to_user (useraddr, &info, sizeof (info))) - return -EFAULT; - return 0; - } - - /* get settings */ - case ETHTOOL_GSET: { - struct ethtool_cmd ecmd = { ETHTOOL_GSET }; - spin_lock_irq(&de->lock); - de_ethtool_gset(de, &ecmd); - spin_unlock_irq(&de->lock); - if (copy_to_user(useraddr, &ecmd, sizeof(ecmd))) - return -EFAULT; - return 0; - } - /* set settings */ - case ETHTOOL_SSET: { - struct ethtool_cmd ecmd; - int r; - if (copy_from_user(&ecmd, useraddr, sizeof(ecmd))) - return -EFAULT; - spin_lock_irq(&de->lock); - r = de_ethtool_sset(de, &ecmd); - spin_unlock_irq(&de->lock); - return r; - } +static int de_get_regs_len(struct net_device *dev) +{ + return DE_REGS_SIZE; +} - /* restart autonegotiation */ - case ETHTOOL_NWAY_RST: { - u32 status; +static int de_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd) +{ + struct de_private *de = dev->priv; + int rc; - if (de->media_type != DE_MEDIA_TP_AUTO) - return -EINVAL; - if (netif_carrier_ok(de->dev)) - de_link_down(de); + spin_lock_irq(&de->lock); + rc = __de_get_settings(de, ecmd); + spin_unlock_irq(&de->lock); - status = dr32(SIAStatus); - dw32(SIAStatus, (status & ~NWayState) | NWayRestart); - if (netif_msg_link(de)) - printk(KERN_INFO "%s: link nway restart, status %x,%x\n", - de->dev->name, status, dr32(SIAStatus)); - return 0; - } - - /* get link status */ - case ETHTOOL_GLINK: { - struct ethtool_value edata = {ETHTOOL_GLINK}; - edata.data = (netif_carrier_ok(de->dev)) ? 1 : 0; - if (copy_to_user(useraddr, &edata, sizeof(edata))) - return -EFAULT; - return 0; - } - - /* get message-level */ - case ETHTOOL_GMSGLVL: { - struct ethtool_value edata = {ETHTOOL_GMSGLVL}; - edata.data = de->msg_enable; - if (copy_to_user(useraddr, &edata, sizeof(edata))) - return -EFAULT; - return 0; - } - /* set message-level */ - case ETHTOOL_SMSGLVL: { - struct ethtool_value edata; - if (copy_from_user(&edata, useraddr, sizeof(edata))) - return -EFAULT; - de->msg_enable = edata.data; - return 0; - } - - /* get registers */ - case ETHTOOL_GREGS: { - struct ethtool_regs regs; - u8 regbuf[DE_REGS_SIZE]; - int r; + return rc; +} - if (copy_from_user(®s, useraddr, sizeof(regs))) - return -EFAULT; - - if (regs.len > DE_REGS_SIZE) { - regs.len = DE_REGS_SIZE; - } - regs.version = (DE_REGS_VER << 2) | de->de21040; - if (copy_to_user(useraddr, ®s, sizeof(regs))) - return -EFAULT; +static int de_set_settings(struct net_device *dev, struct ethtool_cmd *ecmd) +{ + struct de_private *de = dev->priv; + int rc; - useraddr += offsetof(struct ethtool_regs, data); + spin_lock_irq(&de->lock); + rc = __de_set_settings(de, ecmd); + spin_unlock_irq(&de->lock); - spin_lock_irq(&de->lock); - r = de_get_regs(de, regbuf); - spin_unlock_irq(&de->lock); + return rc; +} - if (r) - return r; - if (copy_to_user(useraddr, regbuf, regs.len)) - return -EFAULT; - return 0; - } +static u32 de_get_msglevel(struct net_device *dev) +{ + struct de_private *de = dev->priv; - /* get SROM dump */ - case ETHTOOL_GEEPROM: { - struct ethtool_eeprom eeprom; + return de->msg_enable; +} - if (!de->ee_data) - break; - if (copy_from_user(&eeprom, useraddr, sizeof(eeprom))) - return -EFAULT; - if ((eeprom.offset != 0) || (eeprom.magic != 0) || - (eeprom.len != DE_EEPROM_SIZE)) - return -EINVAL; +static void de_set_msglevel(struct net_device *dev, u32 msglvl) +{ + struct de_private *de = dev->priv; - useraddr += offsetof(struct ethtool_regs, data); - if (copy_to_user(useraddr, de->ee_data, DE_EEPROM_SIZE)) - return -EFAULT; - } + de->msg_enable = msglvl; +} - default: - break; - } +static int de_get_eeprom(struct net_device *dev, + struct ethtool_eeprom *eeprom, u8 *data) +{ + struct de_private *de = dev->priv; - return -EOPNOTSUPP; -} + if (!de->ee_data) + return -EOPNOTSUPP; + if ((eeprom->offset != 0) || (eeprom->magic != 0) || + (eeprom->len != DE_EEPROM_SIZE)) + return -EINVAL; + memcpy(data, de->ee_data, eeprom->len); + return 0; +} -static int de_ioctl (struct net_device *dev, struct ifreq *rq, int cmd) +static int de_nway_reset(struct net_device *dev) { struct de_private *de = dev->priv; - int rc = 0; + u32 status; - if (!netif_running(dev)) + if (de->media_type != DE_MEDIA_TP_AUTO) return -EINVAL; - - switch (cmd) { - case SIOCETHTOOL: - return de_ethtool_ioctl(de, (void *) rq->ifr_data); + if (netif_carrier_ok(de->dev)) + de_link_down(de); - default: - rc = -EOPNOTSUPP; - break; - } + status = dr32(SIAStatus); + dw32(SIAStatus, (status & ~NWayState) | NWayRestart); + if (netif_msg_link(de)) + printk(KERN_INFO "%s: link nway restart, status %x,%x\n", + de->dev->name, status, dr32(SIAStatus)); + return 0; +} - return rc; +static void de_get_regs(struct net_device *dev, struct ethtool_regs *regs, + void *data) +{ + struct de_private *de = dev->priv; + + if (regs->len > DE_REGS_SIZE) + regs->len = DE_REGS_SIZE; + regs->version = (DE_REGS_VER << 2) | de->de21040; + + spin_lock_irq(&de->lock); + __de_get_regs(de, data); + spin_unlock_irq(&de->lock); } +static struct ethtool_ops de_ethtool_ops = { + .get_link = ethtool_op_get_link, + .get_tx_csum = ethtool_op_get_tx_csum, + .get_sg = ethtool_op_get_sg, + .get_drvinfo = de_get_drvinfo, + .get_regs_len = de_get_regs_len, + .get_settings = de_get_settings, + .set_settings = de_set_settings, + .get_msglevel = de_get_msglevel, + .set_msglevel = de_set_msglevel, + .get_eeprom = de_get_eeprom, + .nway_reset = de_nway_reset, + .get_regs = de_get_regs, +}; + static void __init de21040_get_mac_address (struct de_private *de) { unsigned i; @@ -2011,7 +1961,7 @@ dev->set_multicast_list = de_set_rx_mode; dev->hard_start_xmit = de_start_xmit; dev->get_stats = de_get_stats; - dev->do_ioctl = de_ioctl; + dev->ethtool_ops = &de_ethtool_ops; dev->tx_timeout = de_tx_timeout; dev->watchdog_timeo = TX_TIMEOUT; diff -Nru a/drivers/net/tulip/dmfe.c b/drivers/net/tulip/dmfe.c --- a/drivers/net/tulip/dmfe.c Tue Sep 2 19:58:18 2003 +++ b/drivers/net/tulip/dmfe.c Tue Sep 2 19:58:18 2003 @@ -296,7 +296,7 @@ static int dmfe_stop(struct DEVICE *); static struct net_device_stats * dmfe_get_stats(struct DEVICE *); static void dmfe_set_filter_mode(struct DEVICE *); -static int dmfe_do_ioctl(struct DEVICE *, struct ifreq *, int); +static struct ethtool_ops netdev_ethtool_ops; static u16 read_srom_word(long ,int); static irqreturn_t dmfe_interrupt(int , void *, struct pt_regs *); static void dmfe_descriptor_init(struct dmfe_board_info *, unsigned long); @@ -417,7 +417,7 @@ dev->stop = &dmfe_stop; dev->get_stats = &dmfe_get_stats; dev->set_multicast_list = &dmfe_set_filter_mode; - dev->do_ioctl = &dmfe_do_ioctl; + dev->ethtool_ops = &netdev_ethtool_ops; spin_lock_init(&db->lock); pci_read_config_dword(pdev, 0x50, &pci_pmr); @@ -1000,55 +1000,23 @@ spin_unlock_irqrestore(&db->lock, flags); } - -/* - * Process the ethtool ioctl command - */ - -static int dmfe_ethtool_ioctl(struct net_device *dev, void *useraddr) +static void netdev_get_drvinfo(struct net_device *dev, + struct ethtool_drvinfo *info) { - struct dmfe_board_info *db = dev->priv; - struct ethtool_drvinfo info = { ETHTOOL_GDRVINFO }; - u32 ethcmd; - - if (copy_from_user(ðcmd, useraddr, sizeof(ethcmd))) - return -EFAULT; - - switch (ethcmd) { - case ETHTOOL_GDRVINFO: - strcpy(info.driver, DRV_NAME); - strcpy(info.version, DRV_VERSION); - if (db->pdev) - strcpy(info.bus_info, pci_name(db->pdev)); - else - sprintf(info.bus_info, "EISA 0x%lx %d", - dev->base_addr, dev->irq); - if (copy_to_user(useraddr, &info, sizeof(info))) - return -EFAULT; - return 0; - } - - return -EOPNOTSUPP; -} + struct dmfe_board_info *np = dev->priv; - -/* - * Process the upper socket ioctl command - */ - -static int dmfe_do_ioctl(struct DEVICE *dev, struct ifreq *ifr, int cmd) -{ - int retval = -EOPNOTSUPP; - DMFE_DBUG(0, "dmfe_do_ioctl()", 0); - - switch(cmd) { - case SIOCETHTOOL: - return dmfe_ethtool_ioctl(dev, (void*)ifr->ifr_data); - } - - return retval; + strcpy(info->driver, DRV_NAME); + strcpy(info->version, DRV_VERSION); + if (np->pdev) + strcpy(info->bus_info, pci_name(np->pdev)); + else + sprintf(info->bus_info, "EISA 0x%lx %d", + dev->base_addr, dev->irq); } +static struct ethtool_ops netdev_ethtool_ops = { + .get_drvinfo = netdev_get_drvinfo, +}; /* * A periodic timer routine diff -Nru a/drivers/net/tulip/winbond-840.c b/drivers/net/tulip/winbond-840.c --- a/drivers/net/tulip/winbond-840.c Tue Sep 2 19:58:13 2003 +++ b/drivers/net/tulip/winbond-840.c Tue Sep 2 19:58:13 2003 @@ -392,6 +392,7 @@ static void set_rx_mode(struct net_device *dev); static struct net_device_stats *get_stats(struct net_device *dev); static int netdev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); +static struct ethtool_ops netdev_ethtool_ops; static int netdev_close(struct net_device *dev); @@ -482,6 +483,7 @@ dev->get_stats = &get_stats; dev->set_multicast_list = &set_rx_mode; dev->do_ioctl = &netdev_ioctl; + dev->ethtool_ops = &netdev_ethtool_ops; dev->tx_timeout = &tx_timeout; dev->watchdog_timeo = TX_TIMEOUT; @@ -1452,88 +1454,79 @@ spin_unlock_irq(&np->lock); } -static int netdev_ethtool_ioctl(struct net_device *dev, void *useraddr) +static void netdev_get_drvinfo (struct net_device *dev, struct ethtool_drvinfo *info) { struct netdev_private *np = dev->priv; - u32 ethcmd; - - if (copy_from_user(ðcmd, useraddr, sizeof(ethcmd))) - return -EFAULT; - - switch (ethcmd) { - case ETHTOOL_GDRVINFO: { - struct ethtool_drvinfo info = {ETHTOOL_GDRVINFO}; - strcpy(info.driver, DRV_NAME); - strcpy(info.version, DRV_VERSION); - strcpy(info.bus_info, pci_name(np->pci_dev)); - if (copy_to_user(useraddr, &info, sizeof(info))) - return -EFAULT; - return 0; - } - - /* get settings */ - case ETHTOOL_GSET: { - struct ethtool_cmd ecmd = { ETHTOOL_GSET }; - spin_lock_irq(&np->lock); - mii_ethtool_gset(&np->mii_if, &ecmd); - spin_unlock_irq(&np->lock); - if (copy_to_user(useraddr, &ecmd, sizeof(ecmd))) - return -EFAULT; - return 0; - } - /* set settings */ - case ETHTOOL_SSET: { - int r; - struct ethtool_cmd ecmd; - if (copy_from_user(&ecmd, useraddr, sizeof(ecmd))) - return -EFAULT; - spin_lock_irq(&np->lock); - r = mii_ethtool_sset(&np->mii_if, &ecmd); - spin_unlock_irq(&np->lock); - return r; - } - /* restart autonegotiation */ - case ETHTOOL_NWAY_RST: { - return mii_nway_restart(&np->mii_if); - } - /* get link status */ - case ETHTOOL_GLINK: { - struct ethtool_value edata = {ETHTOOL_GLINK}; - edata.data = mii_link_ok(&np->mii_if); - if (copy_to_user(useraddr, &edata, sizeof(edata))) - return -EFAULT; - return 0; - } - - /* get message-level */ - case ETHTOOL_GMSGLVL: { - struct ethtool_value edata = {ETHTOOL_GMSGLVL}; - edata.data = debug; - if (copy_to_user(useraddr, &edata, sizeof(edata))) - return -EFAULT; - return 0; - } - /* set message-level */ - case ETHTOOL_SMSGLVL: { - struct ethtool_value edata; - if (copy_from_user(&edata, useraddr, sizeof(edata))) - return -EFAULT; - debug = edata.data; - return 0; - } - } - - return -EOPNOTSUPP; + + strcpy (info->driver, DRV_NAME); + strcpy (info->version, DRV_VERSION); + strcpy (info->bus_info, pci_name(np->pci_dev)); +} + +static int netdev_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) +{ + struct netdev_private *np = dev->priv; + int rc; + + spin_lock_irq(&np->lock); + rc = mii_ethtool_gset(&np->mii_if, cmd); + spin_unlock_irq(&np->lock); + + return rc; } +static int netdev_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) +{ + struct netdev_private *np = dev->priv; + int rc; + + spin_lock_irq(&np->lock); + rc = mii_ethtool_sset(&np->mii_if, cmd); + spin_unlock_irq(&np->lock); + + return rc; +} + +static int netdev_nway_reset(struct net_device *dev) +{ + struct netdev_private *np = dev->priv; + return mii_nway_restart(&np->mii_if); +} + +static u32 netdev_get_link(struct net_device *dev) +{ + struct netdev_private *np = dev->priv; + return mii_link_ok(&np->mii_if); +} + +static u32 netdev_get_msglevel(struct net_device *dev) +{ + return debug; +} + +static void netdev_set_msglevel(struct net_device *dev, u32 value) +{ + debug = value; +} + +static struct ethtool_ops netdev_ethtool_ops = { + .get_drvinfo = netdev_get_drvinfo, + .get_settings = netdev_get_settings, + .set_settings = netdev_set_settings, + .nway_reset = netdev_nway_reset, + .get_link = netdev_get_link, + .get_msglevel = netdev_get_msglevel, + .set_msglevel = netdev_set_msglevel, + .get_sg = ethtool_op_get_sg, + .get_tx_csum = ethtool_op_get_tx_csum, +}; + static int netdev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) { struct mii_ioctl_data *data = (struct mii_ioctl_data *)&rq->ifr_data; struct netdev_private *np = dev->priv; switch(cmd) { - case SIOCETHTOOL: - return netdev_ethtool_ioctl(dev, (void *) rq->ifr_data); case SIOCGMIIPHY: /* Get address of MII PHY in use. */ data->phy_id = ((struct netdev_private *)dev->priv)->phys[0] & 0x1f; /* Fall Through */ diff -Nru a/drivers/net/tulip/xircom_cb.c b/drivers/net/tulip/xircom_cb.c --- a/drivers/net/tulip/xircom_cb.c Tue Sep 2 19:58:18 2003 +++ b/drivers/net/tulip/xircom_cb.c Tue Sep 2 19:58:18 2003 @@ -175,37 +175,19 @@ } #endif -static int netdev_ethtool_ioctl(struct net_device *dev, void *useraddr) +static void netdev_get_drvinfo(struct net_device *dev, + struct ethtool_drvinfo *info) { - u32 ethcmd; - - if (copy_from_user(ðcmd, useraddr, sizeof(ethcmd))) - return -EFAULT; - - switch (ethcmd) { - case ETHTOOL_GDRVINFO: { - struct ethtool_drvinfo info = {ETHTOOL_GDRVINFO}; - strncpy(info.driver, "xircom_cb", sizeof(info.driver)-1); - if (copy_to_user(useraddr, &info, sizeof(info))) - return -EFAULT; - return 0; - } - } - - return -EOPNOTSUPP; -} + struct xircom_private *private = dev->priv; -static int private_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) -{ - - switch(cmd) { - case SIOCETHTOOL: - return netdev_ethtool_ioctl(dev, (void *) rq->ifr_data); - default: - return -EOPNOTSUPP; - } + strcpy(info->driver, "xircom_cb"); + strcpy(info->bus_info, pci_name(private->pdev)); } +static struct ethtool_ops netdev_ethtool_ops = { + .get_drvinfo = netdev_get_drvinfo, +}; + /* xircom_probe is the code that gets called on device insertion. it sets up the hardware and registers the device to the networklayer. @@ -287,7 +269,7 @@ dev->stop = &xircom_close; dev->get_stats = &xircom_get_stats; dev->priv = private; - dev->do_ioctl = &private_ioctl; + SET_ETHTOOL_OPS(dev, &netdev_ethtool_ops); pci_set_drvdata(pdev, dev); diff -Nru a/drivers/net/via-rhine.c b/drivers/net/via-rhine.c --- a/drivers/net/via-rhine.c Tue Sep 2 19:58:19 2003 +++ b/drivers/net/via-rhine.c Tue Sep 2 19:58:19 2003 @@ -547,6 +547,7 @@ static void via_rhine_set_rx_mode(struct net_device *dev); static struct net_device_stats *via_rhine_get_stats(struct net_device *dev); static int netdev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); +static struct ethtool_ops netdev_ethtool_ops; static int via_rhine_close(struct net_device *dev); static inline u32 get_intr_status(struct net_device *dev) @@ -780,6 +781,7 @@ dev->get_stats = via_rhine_get_stats; dev->set_multicast_list = via_rhine_set_rx_mode; dev->do_ioctl = netdev_ioctl; + dev->ethtool_ops = &netdev_ethtool_ops; dev->tx_timeout = via_rhine_tx_timeout; dev->watchdog_timeo = TX_TIMEOUT; if (np->drv_flags & ReqTxAlign) @@ -1741,90 +1743,87 @@ writeb(np->rx_thresh | rx_mode, ioaddr + RxConfig); } -static int netdev_ethtool_ioctl (struct net_device *dev, void *useraddr) +static void netdev_get_drvinfo (struct net_device *dev, struct ethtool_drvinfo *info) { struct netdev_private *np = dev->priv; - u32 ethcmd; - if (get_user(ethcmd, (u32 *)useraddr)) - return -EFAULT; + strcpy (info->driver, DRV_NAME); + strcpy (info->version, DRV_VERSION); + strcpy (info->bus_info, pci_name(np->pdev)); +} - switch (ethcmd) { - case ETHTOOL_GDRVINFO: { - struct ethtool_drvinfo info = { ETHTOOL_GDRVINFO }; - strcpy (info.driver, DRV_NAME); - strcpy (info.version, DRV_VERSION); - strcpy (info.bus_info, pci_name(np->pdev)); - if (copy_to_user (useraddr, &info, sizeof (info))) - return -EFAULT; - return 0; - } +static int netdev_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) +{ + struct netdev_private *np = dev->priv; + int rc; - /* get settings */ - case ETHTOOL_GSET: { - struct ethtool_cmd ecmd = { ETHTOOL_GSET }; - if (!(np->drv_flags & CanHaveMII)) - break; - spin_lock_irq(&np->lock); - mii_ethtool_gset(&np->mii_if, &ecmd); - spin_unlock_irq(&np->lock); - if (copy_to_user(useraddr, &ecmd, sizeof(ecmd))) - return -EFAULT; - return 0; - } - /* set settings */ - case ETHTOOL_SSET: { - int r; - struct ethtool_cmd ecmd; - if (!(np->drv_flags & CanHaveMII)) - break; - if (copy_from_user(&ecmd, useraddr, sizeof(ecmd))) - return -EFAULT; - spin_lock_irq(&np->lock); - r = mii_ethtool_sset(&np->mii_if, &ecmd); - spin_unlock_irq(&np->lock); - return r; - } - /* restart autonegotiation */ - case ETHTOOL_NWAY_RST: { - if (!(np->drv_flags & CanHaveMII)) - break; - return mii_nway_restart(&np->mii_if); - } - /* get link status */ - case ETHTOOL_GLINK: { - struct ethtool_value edata = {ETHTOOL_GLINK}; - if (!(np->drv_flags & CanHaveMII)) - break; - edata.data = mii_link_ok(&np->mii_if); - if (copy_to_user(useraddr, &edata, sizeof(edata))) - return -EFAULT; - return 0; - } - - /* get message-level */ - case ETHTOOL_GMSGLVL: { - struct ethtool_value edata = {ETHTOOL_GMSGLVL}; - edata.data = debug; - if (copy_to_user(useraddr, &edata, sizeof(edata))) - return -EFAULT; - return 0; - } - /* set message-level */ - case ETHTOOL_SMSGLVL: { - struct ethtool_value edata; - if (copy_from_user(&edata, useraddr, sizeof(edata))) - return -EFAULT; - debug = edata.data; - return 0; - } - default: - break; - } + if (!(np->drv_flags & CanHaveMII)) + return -EINVAL; + + spin_lock_irq(&np->lock); + rc = mii_ethtool_gset(&np->mii_if, cmd); + spin_unlock_irq(&np->lock); + + return rc; +} + +static int netdev_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) +{ + struct netdev_private *np = dev->priv; + int rc; + + if (!(np->drv_flags & CanHaveMII)) + return -EINVAL; + + spin_lock_irq(&np->lock); + rc = mii_ethtool_sset(&np->mii_if, cmd); + spin_unlock_irq(&np->lock); - return -EOPNOTSUPP; + return rc; } +static int netdev_nway_reset(struct net_device *dev) +{ + struct netdev_private *np = dev->priv; + + if (!(np->drv_flags & CanHaveMII)) + return -EINVAL; + + return mii_nway_restart(&np->mii_if); +} + +static u32 netdev_get_link(struct net_device *dev) +{ + struct netdev_private *np = dev->priv; + + if (!(np->drv_flags & CanHaveMII)) + return 0; /* -EINVAL */ + + return mii_link_ok(&np->mii_if); +} + +static u32 netdev_get_msglevel(struct net_device *dev) +{ + return debug; +} + +static void netdev_set_msglevel(struct net_device *dev, u32 value) +{ + debug = value; +} + +static struct ethtool_ops netdev_ethtool_ops = { + .get_drvinfo = netdev_get_drvinfo, + .get_settings = netdev_get_settings, + .set_settings = netdev_set_settings, + .nway_reset = netdev_nway_reset, + .get_link = netdev_get_link, + .get_msglevel = netdev_get_msglevel, + .set_msglevel = netdev_set_msglevel, + .get_sg = ethtool_op_get_sg, + .get_tx_csum = ethtool_op_get_tx_csum, +}; + static int netdev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) { struct netdev_private *np = dev->priv; @@ -1834,14 +1833,9 @@ if (!netif_running(dev)) return -EINVAL; - if (cmd == SIOCETHTOOL) - rc = netdev_ethtool_ioctl(dev, (void *) rq->ifr_data); - - else { - spin_lock_irq(&np->lock); - rc = generic_mii_ioctl(&np->mii_if, data, cmd, NULL); - spin_unlock_irq(&np->lock); - } + spin_lock_irq(&np->lock); + rc = generic_mii_ioctl(&np->mii_if, data, cmd, NULL); + spin_unlock_irq(&np->lock); return rc; } diff -Nru a/drivers/net/wan/Kconfig b/drivers/net/wan/Kconfig --- a/drivers/net/wan/Kconfig Tue Sep 2 19:58:14 2003 +++ b/drivers/net/wan/Kconfig Tue Sep 2 19:58:14 2003 @@ -35,7 +35,7 @@ # The COSA/SRP driver has not been tested as non-modular yet. config COSA tristate "COSA/SRP sync serial boards support" - depends on WAN && ISA && m + depends on WAN && ISA && m && BROKEN ---help--- This is a driver for COSA and SRP synchronous serial boards. These boards allow to connect synchronous serial devices (for example @@ -63,7 +63,7 @@ # Not updated to 2.6. config COMX tristate "MultiGate (COMX) synchronous serial boards support" - depends on WAN && (ISA || PCI) && OBSOLETE + depends on WAN && (ISA || PCI) && BROKEN ---help--- Say Y if you want to use any board from the MultiGate (COMX) family. These boards are synchronous serial adapters for the PC, @@ -465,7 +465,7 @@ config SDLA tristate "SDLA (Sangoma S502/S508) support" - depends on DLCI && ISA + depends on DLCI && ISA && BROKEN_ON_SMP help Say Y here if you need a driver for the Sangoma S502A, S502E, and S508 Frame Relay Access Devices. These are multi-protocol cards, but @@ -498,7 +498,7 @@ config VENDOR_SANGOMA tristate "Sangoma WANPIPE(tm) multiprotocol cards" - depends on WAN_ROUTER_DRIVERS && WAN_ROUTER && (PCI || ISA) + depends on WAN_ROUTER_DRIVERS && WAN_ROUTER && (PCI || ISA) && BROKEN ---help--- WANPIPE from Sangoma Technologies Inc. () is a family of intelligent multiprotocol WAN adapters with data diff -Nru a/drivers/net/wan/cosa.c b/drivers/net/wan/cosa.c --- a/drivers/net/wan/cosa.c Tue Sep 2 19:58:12 2003 +++ b/drivers/net/wan/cosa.c Tue Sep 2 19:58:12 2003 @@ -632,7 +632,7 @@ { sppp_detach(chan->pppdev.dev); unregister_netdev(chan->pppdev.dev); - free_netdev(chan->ppp.dev); + free_netdev(chan->pppdev.dev); } static int cosa_sppp_open(struct net_device *d) @@ -961,12 +961,12 @@ unsigned long flags; int n; - if ((n=minor(file->f_dentry->d_inode->i_rdev)>>CARD_MINOR_BITS) + if ((n=iminor(file->f_dentry->d_inode)>>CARD_MINOR_BITS) >= nr_cards) return -ENODEV; cosa = cosa_cards+n; - if ((n=minor(file->f_dentry->d_inode->i_rdev) + if ((n=iminor(file->f_dentry->d_inode) & ((1<= cosa->nchannels) return -ENODEV; chan = cosa->chan + n; @@ -1009,7 +1009,7 @@ /* To be done ... */ static int cosa_fasync(struct inode *inode, struct file *file, int on) { - int port = MINOR(inode->i_rdev); + int port = iminor(inode); int rv = fasync_helper(inode, file, on, &fasync[port]); return rv < 0 ? rv : 0; } diff -Nru a/drivers/net/wan/cycx_drv.c b/drivers/net/wan/cycx_drv.c --- a/drivers/net/wan/cycx_drv.c Tue Sep 2 19:58:16 2003 +++ b/drivers/net/wan/cycx_drv.c Tue Sep 2 19:58:16 2003 @@ -70,12 +70,12 @@ static int load_cyc2x(struct cycx_hw *hw, struct cycx_firmware *cfm, u32 len); static void cycx_bootcfg(struct cycx_hw *hw); -static int reset_cyc2x(u32 addr); -static int detect_cyc2x(u32 addr); +static int reset_cyc2x(void *addr); +static int detect_cyc2x(void *addr); /* Miscellaneous functions */ static void delay_cycx(int sec); -static int get_option_index(u32 *optlist, u32 optval); +static int get_option_index(long *optlist, long optval); static u16 checksum(u8 *buf, u32 len); #define wait_cyc(addr) cycx_exec(addr + CMD_OFFSET) @@ -92,14 +92,14 @@ * These are arrays of configuration options used by verification routines. * The first element of each array is its size (i.e. number of options). */ -static u32 cyc2x_dpmbase_options[] = { +static long cyc2x_dpmbase_options[] = { 20, 0xA0000, 0xA4000, 0xA8000, 0xAC000, 0xB0000, 0xB4000, 0xB8000, 0xBC000, 0xC0000, 0xC4000, 0xC8000, 0xCC000, 0xD0000, 0xD4000, 0xD8000, 0xDC000, 0xE0000, 0xE4000, 0xE8000, 0xEC000 }; -static u32 cycx_2x_irq_options[] = { 7, 3, 5, 9, 10, 11, 12, 15 }; +static long cycx_2x_irq_options[] = { 7, 3, 5, 9, 10, 11, 12, 15 }; /* Kernel Loadable Module Entry Points */ /* Module 'insert' entry point. @@ -137,7 +137,7 @@ EXPORT_SYMBOL(cycx_setup); int cycx_setup(struct cycx_hw *hw, void *cfm, u32 len) { - unsigned long dpmbase = hw->dpmbase; + long dpmbase = (long)hw->dpmbase; int err; /* Verify IRQ configuration options */ @@ -147,17 +147,17 @@ } /* Setup adapter dual-port memory window and test memory */ - if (!hw->dpmbase) { + if (!dpmbase) { printk(KERN_ERR "%s: you must specify the dpm address!\n", modname); return -EINVAL; - } else if (!get_option_index(cyc2x_dpmbase_options, hw->dpmbase)) { + } else if (!get_option_index(cyc2x_dpmbase_options, dpmbase)) { printk(KERN_ERR "%s: memory address 0x%lX is invalid!\n", modname, dpmbase); return -EINVAL; } - hw->dpmbase = (u32)ioremap(dpmbase, CYCX_WINDOWSIZE); + hw->dpmbase = ioremap(dpmbase, CYCX_WINDOWSIZE); hw->dpmsize = CYCX_WINDOWSIZE; if (!detect_cyc2x(hw->dpmbase)) { @@ -181,8 +181,7 @@ EXPORT_SYMBOL(cycx_down); int cycx_down(struct cycx_hw *hw) { - iounmap((u32 *)hw->dpmbase); - + iounmap(hw->dpmbase); return 0; } @@ -204,7 +203,7 @@ * o Set exec flag. * o Busy-wait until flag is reset. */ EXPORT_SYMBOL(cycx_exec); -int cycx_exec(u32 addr) +int cycx_exec(void *addr) { u16 i = 0; /* wait till addr content is zeroed */ @@ -250,7 +249,7 @@ /* Load Aux Routines */ /* Reset board hardware. return 1 if memory exists at addr and 0 if not. */ -static int memory_exists(u32 addr) +static int memory_exists(void *addr) { int tries = 0; @@ -268,9 +267,9 @@ } /* Load reset code. */ -static void reset_load(u32 addr, u8 *buffer, u32 cnt) +static void reset_load(void *addr, u8 *buffer, u32 cnt) { - u32 pt_code = addr + RESET_OFFSET; + void *pt_code = addr + RESET_OFFSET; u16 i; /*, j; */ for (i = 0 ; i < cnt ; i++) { @@ -282,7 +281,7 @@ /* Load buffer using boot interface. * o copy data from buffer to Cyclom-X memory * o wait for reset code to copy it to right portion of memory */ -static int buffer_load(u32 addr, u8 *buffer, u32 cnt) +static int buffer_load(void *addr, u8 *buffer, u32 cnt) { memcpy_toio(addr + DATA_OFFSET, buffer, cnt); writew(GEN_BOOT_DAT, addr + CMD_OFFSET); @@ -291,7 +290,7 @@ } /* Set up entry point and kick start Cyclom-X CPU. */ -static void cycx_start(u32 addr) +static void cycx_start(void *addr) { /* put in 0x30 offset the jump instruction to the code entry point */ writeb(0xea, addr + 0x30); @@ -305,9 +304,9 @@ } /* Load and boot reset code. */ -static void cycx_reset_boot(u32 addr, u8 *code, u32 len) +static void cycx_reset_boot(void *addr, u8 *code, u32 len) { - u32 pt_start = addr + START_OFFSET; + void *pt_start = addr + START_OFFSET; writeb(0xea, pt_start++); /* jmp to f000:3f00 */ writeb(0x00, pt_start++); @@ -322,9 +321,9 @@ } /* Load data.bin file through boot (reset) interface. */ -static int cycx_data_boot(u32 addr, u8 *code, u32 len) +static int cycx_data_boot(void *addr, u8 *code, u32 len) { - u32 pt_boot_cmd = addr + CMD_OFFSET; + void *pt_boot_cmd = addr + CMD_OFFSET; u32 i; /* boot buffer lenght */ @@ -353,9 +352,9 @@ /* Load code.bin file through boot (reset) interface. */ -static int cycx_code_boot(u32 addr, u8 *code, u32 len) +static int cycx_code_boot(void *addr, u8 *code, u32 len) { - u32 pt_boot_cmd = addr + CMD_OFFSET; + void *pt_boot_cmd = addr + CMD_OFFSET; u32 i; /* boot buffer lenght */ @@ -392,7 +391,7 @@ u8 *reset_image, *data_image, *code_image; - u32 pt_cycld = hw->dpmbase + 0x400; + void *pt_cycld = hw->dpmbase + 0x400; u16 cksum; /* Announce */ @@ -426,7 +425,7 @@ if (cksum != cfm->checksum) { printk(KERN_ERR "%s:%s: firmware corrupted!\n", modname, __FUNCTION__); - printk(KERN_ERR " cdsize = 0x%x (expected 0x%lx)\n", + printk(KERN_ERR " cdsize = 0x%lx (expected 0x%lx)\n", len - sizeof(struct cycx_firmware) - 1, cfm->info.codesize); printk(KERN_ERR " chksum = 0x%x (expected 0x%x)\n", @@ -435,9 +434,7 @@ } /* If everything is ok, set reset, data and code pointers */ - - img_hdr = (struct cycx_fw_header *)(((u8 *)cfm) + - sizeof(struct cycx_firmware) - 1); + img_hdr = (struct cycx_fw_header *)&cfm->image; #ifdef FIRMWARE_DEBUG printk(KERN_INFO "%s:%s: image sizes\n", __FUNCTION__, modname); printk(KERN_INFO " reset=%lu\n", img_hdr->reset_size); @@ -526,7 +523,7 @@ * Return 1 if detected o.k. or 0 if failed. * Note: This test is destructive! Adapter will be left in shutdown * state after the test. */ -static int detect_cyc2x(u32 addr) +static int detect_cyc2x(void *addr) { reset_cyc2x(addr); @@ -536,7 +533,7 @@ /* Miscellaneous */ /* Get option's index into the options list. * Return option's index (1 .. N) or zero if option is invalid. */ -static int get_option_index(u32 *optlist, u32 optval) +static int get_option_index(long *optlist, long optval) { int i = 1; @@ -548,7 +545,7 @@ } /* Reset adapter's CPU. */ -static int reset_cyc2x(u32 addr) +static int reset_cyc2x(void *addr) { writeb(0, addr + RST_ENABLE); delay_cycx(2); diff -Nru a/drivers/net/wan/cycx_main.c b/drivers/net/wan/cycx_main.c --- a/drivers/net/wan/cycx_main.c Tue Sep 2 19:58:15 2003 +++ b/drivers/net/wan/cycx_main.c Tue Sep 2 19:58:15 2003 @@ -223,7 +223,7 @@ /* Configure hardware, load firmware, etc. */ memset(&card->hw, 0, sizeof(card->hw)); card->hw.irq = irq; - card->hw.dpmbase = conf->maddr; + card->hw.dpmbase = (void *)conf->maddr; card->hw.dpmsize = CYCX_WINDOWSIZE; card->hw.fwid = CFID_X25_2X; card->lock = SPIN_LOCK_UNLOCKED; @@ -236,7 +236,7 @@ /* Initialize WAN device data space */ wandev->irq = irq; wandev->dma = wandev->ioport = 0; - wandev->maddr = card->hw.dpmbase; + wandev->maddr = (unsigned long)card->hw.dpmbase; wandev->msize = card->hw.dpmsize; wandev->hw_opt[2] = 0; wandev->hw_opt[3] = card->hw.fwid; diff -Nru a/drivers/net/wireless/airo.c b/drivers/net/wireless/airo.c --- a/drivers/net/wireless/airo.c Tue Sep 2 19:58:13 2003 +++ b/drivers/net/wireless/airo.c Tue Sep 2 19:58:13 2003 @@ -81,12 +81,12 @@ #endif /* Support Cisco MIC feature */ -/* As this feature requires the AES encryption algorithm, it is not included - in the kernel tree. If you want to enable it, you need to download the - aes.h, aestab.h and mic.h files from the CVS at - http://sf.net/projects/airo-linux/ Put the files in the same directory - as airo.c and compile normally */ +#define MICSUPPORT + +#if defined(MICSUPPORT) && !defined(CONFIG_CRYPTO) +#warning MIC support requires Crypto API #undef MICSUPPORT +#endif /* Hack to do some power saving */ #define POWER_ON_DOWN @@ -615,14 +615,14 @@ u16 arlDelay; u16 _reserved4[1]; /*---------- Aironet Extensions ----------*/ - u16 magicAction; + u8 magicAction; #define MAGIC_ACTION_STSCHG 1 #define MACIC_ACTION_RESUME 2 #define MAGIC_IGNORE_MCAST (1<<8) #define MAGIC_IGNORE_BCAST (1<<9) #define MAGIC_SWITCH_TO_PSP (0<<10) #define MAGIC_STAY_IN_CAM (1<<10) - u16 magicControl; + u8 magicControl; u16 autoWake; } ConfigRid; @@ -843,6 +843,7 @@ #define AIROGMICRID 11 #define AIROGMICSTATS 12 #define AIROGFLAGS 13 +#define AIRORRID 15 /* Leave gap of 40 commands after AIROGSTATSD32 for future */ @@ -994,6 +995,8 @@ static int micsetup(struct airo_info *ai); static int encapsulate(struct airo_info *ai, etherHead *pPacket, MICBuffer *buffer, int len); static int decapsulate(struct airo_info *ai, MICBuffer *mic, etherHead *pPacket, u16 payLen); + +#include #endif struct airo_info { @@ -1063,9 +1066,12 @@ #endif /* WIRELESS_SPY */ #endif /* WIRELESS_EXT > 15 */ #endif /* WIRELESS_EXT */ +#ifdef MICSUPPORT /* MIC stuff */ + struct crypto_tfm *tfm; mic_module mod[2]; mic_statistics micstats; +#endif }; static inline int bap_read(struct airo_info *ai, u16 *pu16Dst, int bytelen, @@ -1079,7 +1085,462 @@ struct airo_info *apriv ); #ifdef MICSUPPORT -#include "mic.h" +/*********************************************************************** + * MIC ROUTINES * + *********************************************************************** + */ + +static int RxSeqValid (struct airo_info *ai,miccntx *context,int mcast,u32 micSeq); +static void MoveWindow(miccntx *context, u32 micSeq); +void emmh32_setseed(emmh32_context *context, u8 *pkey, int keylen, struct crypto_tfm *); +void emmh32_init(emmh32_context *context); +void emmh32_update(emmh32_context *context, u8 *pOctets, int len); +void emmh32_final(emmh32_context *context, u8 digest[4]); + +/* micinit - Initialize mic seed */ + +static void micinit(struct airo_info *ai) +{ + MICRid mic_rid; + + clear_bit(JOB_MIC, &ai->flags); + PC4500_readrid(ai, RID_MIC, &mic_rid, sizeof(mic_rid), 0); + up(&ai->sem); + + ai->micstats.enabled = (mic_rid.state & 0x00FF) ? 1 : 0; + + if (ai->micstats.enabled) { + /* Key must be valid and different */ + if (mic_rid.multicastValid && (!ai->mod[0].mCtx.valid || + (memcmp (ai->mod[0].mCtx.key, mic_rid.multicast, + sizeof(ai->mod[0].mCtx.key)) != 0))) { + /* Age current mic Context */ + memcpy(&ai->mod[1].mCtx,&ai->mod[0].mCtx,sizeof(miccntx)); + /* Initialize new context */ + memcpy(&ai->mod[0].mCtx.key,mic_rid.multicast,sizeof(mic_rid.multicast)); + ai->mod[0].mCtx.window = 33; //Window always points to the middle + ai->mod[0].mCtx.rx = 0; //Rx Sequence numbers + ai->mod[0].mCtx.tx = 0; //Tx sequence numbers + ai->mod[0].mCtx.valid = 1; //Key is now valid + + /* Give key to mic seed */ + emmh32_setseed(&ai->mod[0].mCtx.seed,mic_rid.multicast,sizeof(mic_rid.multicast), ai->tfm); + } + + /* Key must be valid and different */ + if (mic_rid.unicastValid && (!ai->mod[0].uCtx.valid || + (memcmp(ai->mod[0].uCtx.key, mic_rid.unicast, + sizeof(ai->mod[0].uCtx.key)) != 0))) { + /* Age current mic Context */ + memcpy(&ai->mod[1].uCtx,&ai->mod[0].uCtx,sizeof(miccntx)); + /* Initialize new context */ + memcpy(&ai->mod[0].uCtx.key,mic_rid.unicast,sizeof(mic_rid.unicast)); + + ai->mod[0].uCtx.window = 33; //Window always points to the middle + ai->mod[0].uCtx.rx = 0; //Rx Sequence numbers + ai->mod[0].uCtx.tx = 0; //Tx sequence numbers + ai->mod[0].uCtx.valid = 1; //Key is now valid + + //Give key to mic seed + emmh32_setseed(&ai->mod[0].uCtx.seed, mic_rid.unicast, sizeof(mic_rid.unicast), ai->tfm); + } + } else { + /* So next time we have a valid key and mic is enabled, we will update + * the sequence number if the key is the same as before. + */ + ai->mod[0].uCtx.valid = 0; + ai->mod[0].mCtx.valid = 0; + } +} + +/* micsetup - Get ready for business */ + +static int micsetup(struct airo_info *ai) { + int i; + + if (ai->tfm == NULL) + ai->tfm = crypto_alloc_tfm("aes", 0); + + if (ai->tfm == NULL) { + printk(KERN_ERR "airo: failed to load transform for AES\n"); + return ERROR; + } + + for (i=0; i < NUM_MODULES; i++) { + memset(&ai->mod[i].mCtx,0,sizeof(miccntx)); + memset(&ai->mod[i].uCtx,0,sizeof(miccntx)); + } + return SUCCESS; +} + +char micsnap[]= {0xAA,0xAA,0x03,0x00,0x40,0x96,0x00,0x02}; + +/*=========================================================================== + * Description: Mic a packet + * + * Inputs: etherHead * pointer to an 802.3 frame + * + * Returns: BOOLEAN if successful, otherwise false. + * PacketTxLen will be updated with the mic'd packets size. + * + * Caveats: It is assumed that the frame buffer will already + * be big enough to hold the largets mic message possible. + * (No memory allocation is done here). + * + * Author: sbraneky (10/15/01) + * Merciless hacks by rwilcher (1/14/02) + */ + +static int encapsulate(struct airo_info *ai ,etherHead *frame, MICBuffer *mic, int payLen) +{ + miccntx *context; + + // Determine correct context + // If not adhoc, always use unicast key + + if (test_bit(FLAG_ADHOC, &ai->flags) && (frame->da[0] & 0x1)) + context = &ai->mod[0].mCtx; + else + context = &ai->mod[0].uCtx; + + if (!context->valid) + return ERROR; + + mic->typelen = htons(payLen + 16); //Length of Mic'd packet + + memcpy(&mic->u.snap, micsnap, sizeof(micsnap)); // Add Snap + + // Add Tx sequence + mic->seq = htonl(context->tx); + context->tx += 2; + + emmh32_init(&context->seed); // Mic the packet + emmh32_update(&context->seed,frame->da,ETH_ALEN * 2); // DA,SA + emmh32_update(&context->seed,(u8*)&mic->typelen,10); // Type/Length and Snap + emmh32_update(&context->seed,(u8*)&mic->seq,sizeof(mic->seq)); //SEQ + emmh32_update(&context->seed,frame->da + ETH_ALEN * 2,payLen); //payload + emmh32_final(&context->seed, (u8*)&mic->mic); + + /* New Type/length ?????????? */ + mic->typelen = 0; //Let NIC know it could be an oversized packet + return SUCCESS; +} + +typedef enum { + NONE, + NOMIC, + NOMICPLUMMED, + SEQUENCE, + INCORRECTMIC, +} mic_error; + +/*=========================================================================== + * Description: Decapsulates a MIC'd packet and returns the 802.3 packet + * (removes the MIC stuff) if packet is a valid packet. + * + * Inputs: etherHead pointer to the 802.3 packet + * + * Returns: BOOLEAN - TRUE if packet should be dropped otherwise FALSE + * + * Author: sbraneky (10/15/01) + * Merciless hacks by rwilcher (1/14/02) + *--------------------------------------------------------------------------- + */ + +static int decapsulate(struct airo_info *ai, MICBuffer *mic, etherHead *eth, u16 payLen) +{ + int i; + u32 micSEQ; + miccntx *context; + u8 digest[4]; + mic_error micError = NONE; + + // Check if the packet is a Mic'd packet + + if (!ai->micstats.enabled) { + //No Mic set or Mic OFF but we received a MIC'd packet. + if (memcmp ((u8*)eth + 14, micsnap, sizeof(micsnap)) == 0) { + ai->micstats.rxMICPlummed++; + return ERROR; + } + return SUCCESS; + } + + if (ntohs(mic->typelen) == 0x888E) + return SUCCESS; + + if (memcmp (mic->u.snap, micsnap, sizeof(micsnap)) != 0) { + // Mic enabled but packet isn't Mic'd + ai->micstats.rxMICPlummed++; + return ERROR; + } + + micSEQ = ntohl(mic->seq); //store SEQ as CPU order + + //At this point we a have a mic'd packet and mic is enabled + //Now do the mic error checking. + + //Receive seq must be odd + if ( (micSEQ & 1) == 0 ) { + ai->micstats.rxWrongSequence++; + return ERROR; + } + + for (i = 0; i < NUM_MODULES; i++) { + int mcast = eth->da[0] & 1; + //Determine proper context + context = mcast ? &ai->mod[i].mCtx : &ai->mod[i].uCtx; + + //Make sure context is valid + if (!context->valid) { + if (i == 0) + micError = NOMICPLUMMED; + continue; + } + //DeMic it + + if (!mic->typelen) + mic->typelen = htons(payLen + sizeof(MICBuffer) - 2); + + emmh32_init(&context->seed); + emmh32_update(&context->seed, eth->da, ETH_ALEN*2); + emmh32_update(&context->seed, (u8 *)&mic->typelen, sizeof(mic->typelen)+sizeof(mic->u.snap)); + emmh32_update(&context->seed, (u8 *)&mic->seq,sizeof(mic->seq)); + emmh32_update(&context->seed, eth->da + ETH_ALEN*2,payLen); + //Calculate MIC + emmh32_final(&context->seed, digest); + + if (memcmp(digest, &mic->mic, 4)) { //Make sure the mics match + //Invalid Mic + if (i == 0) + micError = INCORRECTMIC; + continue; + } + + //Check Sequence number if mics pass + if (RxSeqValid(ai, context, mcast, micSEQ) == SUCCESS) { + ai->micstats.rxSuccess++; + return SUCCESS; + } + if (i == 0) + micError = SEQUENCE; + } + + // Update statistics + switch (micError) { + case NOMICPLUMMED: ai->micstats.rxMICPlummed++; break; + case SEQUENCE: ai->micstats.rxWrongSequence++; break; + case INCORRECTMIC: ai->micstats.rxIncorrectMIC++; break; + case NONE: break; + case NOMIC: break; + } + return ERROR; +} + +/*=========================================================================== + * Description: Checks the Rx Seq number to make sure it is valid + * and hasn't already been received + * + * Inputs: miccntx - mic context to check seq against + * micSeq - the Mic seq number + * + * Returns: TRUE if valid otherwise FALSE. + * + * Author: sbraneky (10/15/01) + * Merciless hacks by rwilcher (1/14/02) + *--------------------------------------------------------------------------- + */ + +static int RxSeqValid (struct airo_info *ai,miccntx *context,int mcast,u32 micSeq) +{ + u32 seq,index; + + //Allow for the ap being rebooted - if it is then use the next + //sequence number of the current sequence number - might go backwards + + if (mcast) { + if (test_bit(FLAG_UPDATE_MULTI, &ai->flags)) { + clear_bit (FLAG_UPDATE_MULTI, &ai->flags); + context->window = (micSeq > 33) ? micSeq : 33; + context->rx = 0; // Reset rx + } + } else if (test_bit(FLAG_UPDATE_UNI, &ai->flags)) { + clear_bit (FLAG_UPDATE_UNI, &ai->flags); + context->window = (micSeq > 33) ? micSeq : 33; // Move window + context->rx = 0; // Reset rx + } + + //Make sequence number relative to START of window + seq = micSeq - (context->window - 33); + + //Too old of a SEQ number to check. + if ((u32)seq < 0) + return ERROR; + + if ( seq > 64 ) { + //Window is infinite forward + MoveWindow(context,micSeq); + return SUCCESS; + } + + // We are in the window. Now check the context rx bit to see if it was already sent + seq >>= 1; //divide by 2 because we only have odd numbers + index = 1 << seq; //Get an index number + + if (!(context->rx & index)) { + //micSEQ falls inside the window. + //Add seqence number to the list of received numbers. + context->rx |= index; + + MoveWindow(context,micSeq); + + return SUCCESS; + } + return ERROR; +} + +static void MoveWindow(miccntx *context, u32 micSeq) +{ + u32 shift; + + //Move window if seq greater than the middle of the window + if (micSeq > context->window) { + shift = (micSeq - context->window) >> 1; + + //Shift out old + if (shift < 32) + context->rx >>= shift; + else + context->rx = 0; + + context->window = micSeq; //Move window + } +} + +/*==============================================*/ +/*========== EMMH ROUTINES ====================*/ +/*==============================================*/ + +/* mic accumulate */ +#define MIC_ACCUM(val) \ + context->accum += (u64)(val) * context->coeff[coeff_position++]; + +static unsigned char aes_counter[16]; + +/* expand the key to fill the MMH coefficient array */ +void emmh32_setseed(emmh32_context *context, u8 *pkey, int keylen, struct crypto_tfm *tfm) +{ + /* take the keying material, expand if necessary, truncate at 16-bytes */ + /* run through AES counter mode to generate context->coeff[] */ + + int i,j; + u32 counter; + u8 *cipher; + struct scatterlist sg[1]; + + crypto_cipher_setkey(tfm, pkey, 16); + counter = 0; + for (i = 0; i < (sizeof(context->coeff)/sizeof(context->coeff[0])); ) { + aes_counter[15] = (u8)(counter >> 0); + aes_counter[14] = (u8)(counter >> 8); + aes_counter[13] = (u8)(counter >> 16); + aes_counter[12] = (u8)(counter >> 24); + counter++; + sg[0].page = virt_to_page(aes_counter); + sg[0].offset = ((long) aes_counter & ~PAGE_MASK); + sg[0].length = 16; + crypto_cipher_encrypt(tfm, sg, sg, 16); + cipher = kmap(sg[0].page) + sg[0].offset; + for (j=0; (j<16) && (i< (sizeof(context->coeff)/sizeof(context->coeff[0]))); ) { + context->coeff[i++] = ntohl(*(u32 *)&cipher[j]); + j += 4; + } + } +} + +/* prepare for calculation of a new mic */ +void emmh32_init(emmh32_context *context) +{ + /* prepare for new mic calculation */ + context->accum = 0; + context->position = 0; +} + +/* add some bytes to the mic calculation */ +void emmh32_update(emmh32_context *context, u8 *pOctets, int len) +{ + int coeff_position, byte_position; + + if (len == 0) return; + + coeff_position = context->position >> 2; + + /* deal with partial 32-bit word left over from last update */ + byte_position = context->position & 3; + if (byte_position) { + /* have a partial word in part to deal with */ + do { + if (len == 0) return; + context->part.d8[byte_position++] = *pOctets++; + context->position++; + len--; + } while (byte_position < 4); + MIC_ACCUM(htonl(context->part.d32)); + } + + /* deal with full 32-bit words */ + while (len >= 4) { + MIC_ACCUM(htonl(*(u32 *)pOctets)); + context->position += 4; + pOctets += 4; + len -= 4; + } + + /* deal with partial 32-bit word that will be left over from this update */ + byte_position = 0; + while (len > 0) { + context->part.d8[byte_position++] = *pOctets++; + context->position++; + len--; + } +} + +/* mask used to zero empty bytes for final partial word */ +static u32 mask32[4] = { 0x00000000L, 0xFF000000L, 0xFFFF0000L, 0xFFFFFF00L }; + +/* calculate the mic */ +void emmh32_final(emmh32_context *context, u8 digest[4]) +{ + int coeff_position, byte_position; + u32 val; + + u64 sum, utmp; + s64 stmp; + + coeff_position = context->position >> 2; + + /* deal with partial 32-bit word left over from last update */ + byte_position = context->position & 3; + if (byte_position) { + /* have a partial word in part to deal with */ + val = htonl(context->part.d32); + MIC_ACCUM(val & mask32[byte_position]); /* zero empty bytes */ + } + + /* reduce the accumulated u64 to a 32-bit MIC */ + sum = context->accum; + stmp = (sum & 0xffffffffLL) - ((sum >> 32) * 15); + utmp = (stmp & 0xffffffffLL) - ((stmp >> 32) * 15); + sum = utmp & 0xffffffffLL; + if (utmp > 0x10000000fLL) + sum -= 15; + + val = (u32)sum; + digest[0] = (val>>24) & 0xFF; + digest[1] = (val>>16) & 0xFF; + digest[2] = (val>>8) & 0xFF; + digest[3] = val & 0xFF; +} #endif static int readBSSListRid(struct airo_info *ai, int first, @@ -1556,6 +2017,7 @@ struct sockaddr *addr = p; Resp rsp; + readConfigRid(ai, 1); memcpy (ai->config.macAddr, addr->sa_data, dev->addr_len); ai->need_commit = 1; disable_MAC(ai, 1); @@ -1624,6 +2086,10 @@ /* PCMCIA frees this stuff, so only for PCI and ISA */ release_region( dev->base_addr, 64 ); } +#ifdef MICSUPPORT + if (ai->tfm) + crypto_free_tfm(ai->tfm); +#endif del_airo_dev( dev ); free_netdev( dev ); } @@ -1725,6 +2191,9 @@ ai->thr_pid = kernel_thread(airo_thread, dev, CLONE_FS | CLONE_FILES); if (ai->thr_pid < 0) goto err_out_free; +#ifdef MICSUPPORT + ai->tfm = NULL; +#endif rc = add_airo_dev( dev ); if (rc) goto err_out_thr; @@ -2125,146 +2594,149 @@ if (len > 2312) { printk( KERN_ERR "airo: Bad size %d\n", len ); - len = 0; + goto badrx; } - if (len) { - if (test_bit(FLAG_802_11, &apriv->flags)) { - bap_read (apriv, (u16*)&fc, sizeof(fc), BAP0); - fc = le16_to_cpu(fc); - switch (fc & 0xc) { - case 4: - if ((fc & 0xe0) == 0xc0) - hdrlen = 10; - else - hdrlen = 16; - break; - case 8: - if ((fc&0x300)==0x300){ - hdrlen = 30; - break; - } - default: - hdrlen = 24; - } - } else - hdrlen = ETH_ALEN * 2; + if (len == 0) + goto badrx; - skb = dev_alloc_skb( len + hdrlen + 2 ); - if ( !skb ) { - apriv->stats.rx_dropped++; - len = 0; - } - } - if (len) { - buffer = (u16*)skb_put (skb, len + hdrlen); - if (test_bit(FLAG_802_11, &apriv->flags)) { - buffer[0] = fc; - bap_read (apriv, buffer + 1, hdrlen - 2, BAP0); - if (hdrlen == 24) - bap_read (apriv, tmpbuf, 6, BAP0); - - bap_read (apriv, &gap, sizeof(gap), BAP0); - gap = le16_to_cpu(gap); - if (gap) { - if (gap <= 8) - bap_read (apriv, tmpbuf, gap, BAP0); + if (test_bit(FLAG_802_11, &apriv->flags)) { + bap_read (apriv, (u16*)&fc, sizeof(fc), BAP0); + fc = le16_to_cpu(fc); + switch (fc & 0xc) { + case 4: + if ((fc & 0xe0) == 0xc0) + hdrlen = 10; else - printk(KERN_ERR "airo: gaplen too big. Problems will follow...\n"); - } - - - bap_read (apriv, buffer + hdrlen/2, len, BAP0); - } else { - MICBuffer micbuf; - bap_read (apriv, buffer, ETH_ALEN*2, BAP0); - if (apriv->micstats.enabled) { - bap_read (apriv,(u16*)&micbuf,sizeof(micbuf),BAP0); - if (ntohs(micbuf.typelen) > 0x05DC) - bap_setup (apriv, fid, 0x44, BAP0); - else { - len -= sizeof(micbuf); - if (len < 48) - len = 48; - skb_trim (skb, len + hdrlen); + hdrlen = 16; + break; + case 8: + if ((fc&0x300)==0x300){ + hdrlen = 30; + break; } - } - bap_read(apriv,buffer+ETH_ALEN,len,BAP0); + default: + hdrlen = 24; + } + } else + hdrlen = ETH_ALEN * 2; + + skb = dev_alloc_skb( len + hdrlen + 2 ); + if ( !skb ) { + apriv->stats.rx_dropped++; + goto badrx; + } + buffer = (u16*)skb_put (skb, len + hdrlen); + if (test_bit(FLAG_802_11, &apriv->flags)) { + buffer[0] = fc; + bap_read (apriv, buffer + 1, hdrlen - 2, BAP0); + if (hdrlen == 24) + bap_read (apriv, tmpbuf, 6, BAP0); + + bap_read (apriv, &gap, sizeof(gap), BAP0); + gap = le16_to_cpu(gap); + if (gap) { + if (gap <= 8) + bap_read (apriv, tmpbuf, gap, BAP0); + else + printk(KERN_ERR "airo: gaplen too big. Problems will follow...\n"); + } + bap_read (apriv, buffer + hdrlen/2, len, BAP0); + } else { +#ifdef MICSUPPORT + MICBuffer micbuf; +#endif + bap_read (apriv, buffer, ETH_ALEN*2, BAP0); #ifdef MICSUPPORT - if (decapsulate(apriv,&micbuf,(etherHead*)buffer,len)) { - dev_kfree_skb_irq (skb); - len = 0; + if (apriv->micstats.enabled) { + bap_read (apriv,(u16*)&micbuf,sizeof(micbuf),BAP0); + if (ntohs(micbuf.typelen) > 0x05DC) + bap_setup (apriv, fid, 0x44, BAP0); + else { + if (len <= sizeof(micbuf)) + goto badmic; + + len -= sizeof(micbuf); + skb_trim (skb, len + hdrlen); } + } #endif + bap_read(apriv,buffer+ETH_ALEN,len,BAP0); +#ifdef MICSUPPORT + if (decapsulate(apriv,&micbuf,(etherHead*)buffer,len)) { +badmic: + dev_kfree_skb_irq (skb); +badrx: + OUT4500( apriv, EVACK, EV_RX); + goto exitrx; } +#endif } - if (len) { #if WIRELESS_EXT > 15 #ifdef IW_WIRELESS_SPY /* defined in iw_handler.h */ - if (apriv->spy_data.spy_number > 0) { - char *sa; - struct iw_quality wstats; - /* Prepare spy data : addr + qual */ - if (!test_bit(FLAG_802_11, &apriv->flags)) { - sa = (char*)buffer + 6; - bap_setup (apriv, fid, 8, BAP0); - bap_read (apriv, (u16*)hdr.rssi, 2, BAP0); - } else - sa = (char*)buffer + 10; - wstats.qual = hdr.rssi[0]; - if (apriv->rssi) - wstats.level = 0x100 - apriv->rssi[hdr.rssi[1]].rssidBm; - else - wstats.level = (hdr.rssi[1] + 321) / 2; - wstats.updated = 3; - /* Update spy records */ - wireless_spy_update(dev, sa, &wstats); - } + if (apriv->spy_data.spy_number > 0) { + char *sa; + struct iw_quality wstats; + /* Prepare spy data : addr + qual */ + if (!test_bit(FLAG_802_11, &apriv->flags)) { + sa = (char*)buffer + 6; + bap_setup (apriv, fid, 8, BAP0); + bap_read (apriv, (u16*)hdr.rssi, 2, BAP0); + } else + sa = (char*)buffer + 10; + wstats.qual = hdr.rssi[0]; + if (apriv->rssi) + wstats.level = 0x100 - apriv->rssi[hdr.rssi[1]].rssidBm; + else + wstats.level = (hdr.rssi[1] + 321) / 2; + wstats.updated = 3; + /* Update spy records */ + wireless_spy_update(dev, sa, &wstats); + } #endif /* IW_WIRELESS_SPY */ #else /* WIRELESS_EXT > 15 */ #ifdef WIRELESS_SPY - if (apriv->spy_number > 0) { - int i; - char *sa; - - sa = (char*)buffer + (test_bit(FLAG_802_11, &apriv->flags) ? 10 : 6); - - for (i=0; ispy_number; i++) - if (!memcmp(sa,apriv->spy_address[i],ETH_ALEN)) - { - if (!test_bit(FLAG_802_11, &apriv->flags)) { - bap_setup (apriv, fid, 8, BAP0); - bap_read (apriv, (u16*)hdr.rssi, 2, BAP0); - } - apriv->spy_stat[i].qual = hdr.rssi[0]; - if (apriv->rssi) - apriv->spy_stat[i].level = 0x100 - apriv->rssi[hdr.rssi[1]].rssidBm; - else - apriv->spy_stat[i].level = (hdr.rssi[1] + 321) / 2; - apriv->spy_stat[i].noise = 0; - apriv->spy_stat[i].updated = 3; - break; + if (apriv->spy_number > 0) { + int i; + char *sa; + + sa = (char*)buffer + (test_bit(FLAG_802_11, &apriv->flags) ? 10 : 6); + + for (i=0; ispy_number; i++) + if (!memcmp(sa,apriv->spy_address[i],ETH_ALEN)) + { + if (!test_bit(FLAG_802_11, &apriv->flags)) { + bap_setup (apriv, fid, 8, BAP0); + bap_read (apriv, (u16*)hdr.rssi, 2, BAP0); } - } + apriv->spy_stat[i].qual = hdr.rssi[0]; + if (apriv->rssi) + apriv->spy_stat[i].level = 0x100 - apriv->rssi[hdr.rssi[1]].rssidBm; + else + apriv->spy_stat[i].level = (hdr.rssi[1] + 321) / 2; + apriv->spy_stat[i].noise = 0; + apriv->spy_stat[i].updated = 3; + break; + } + } #endif /* WIRELESS_SPY */ #endif /* WIRELESS_EXT > 15 */ - OUT4500( apriv, EVACK, EV_RX); + OUT4500( apriv, EVACK, EV_RX); - if (test_bit(FLAG_802_11, &apriv->flags)) { - skb->mac.raw = skb->data; - skb->pkt_type = PACKET_OTHERHOST; - skb->dev = apriv->wifidev; - skb->protocol = htons(ETH_P_802_2); - } else { - skb->dev = dev; - skb->protocol = eth_type_trans(skb,dev); - } - skb->dev->last_rx = jiffies; - skb->ip_summed = CHECKSUM_NONE; + if (test_bit(FLAG_802_11, &apriv->flags)) { + skb->mac.raw = skb->data; + skb->pkt_type = PACKET_OTHERHOST; + skb->dev = apriv->wifidev; + skb->protocol = htons(ETH_P_802_2); + } else { + skb->dev = dev; + skb->protocol = eth_type_trans(skb,dev); + } + skb->dev->last_rx = jiffies; + skb->ip_summed = CHECKSUM_NONE; - netif_rx( skb ); - } else - OUT4500( apriv, EVACK, EV_RX); + netif_rx( skb ); } +exitrx: /* Check to see if a packet has been transmitted */ if ( status & ( EV_TX|EV_TXEXC ) ) { @@ -2469,6 +2941,9 @@ printk(KERN_WARNING "airo: unknown received signal level scale\n"); } ai->config.opmode = adhoc ? MODE_STA_IBSS : MODE_STA_ESS; + ai->config.authType = AUTH_OPEN; + ai->config.modulation = MOD_CCK; + ai->config._reserved1a[0] = 2; /* ??? */ #ifdef MICSUPPORT if ((cap_rid.len>=sizeof(cap_rid)) && (cap_rid.extSoftCap&1) && @@ -2515,6 +2990,7 @@ memcpy(mySsid.ssids[i].ssid, ssids[i], mySsid.ssids[i].len); } + mySsid.len = sizeof(mySsid); } status = writeConfigRid(ai, 1); @@ -3692,6 +4168,8 @@ offset < data->writelen ) offset++; offset++; } + if (i) + SSID_rid.len = sizeof(SSID_rid); disable_MAC(ai, 1); writeSsidRid(ai, &SSID_rid); enable_MAC(ai, &rsp, 1); @@ -4156,7 +4634,7 @@ static int __init airo_init_module( void ) { - int i, rc = 0, have_isa_dev = 0; + int i, have_isa_dev = 0; airo_entry = create_proc_entry("aironet", S_IFDIR | airo_perm, @@ -4174,7 +4652,7 @@ #ifdef CONFIG_PCI printk( KERN_INFO "airo: Probing for PCI adapters\n" ); - rc = pci_module_init(&airo_driver); + pci_module_init(&airo_driver); printk( KERN_INFO "airo: Finished probing for PCI adapters\n" ); #endif @@ -4197,8 +4675,11 @@ } remove_proc_entry("aironet", proc_root_driver); - if (is_pci) + if (is_pci) { +#ifdef CONFIG_PCI pci_unregister_driver(&airo_driver); +#endif + } } #ifdef WIRELESS_EXT @@ -4260,6 +4741,7 @@ printk(KERN_DEBUG "%s: New channel value of %d is invalid!\n", dev->name, fwrq->m); rc = -EINVAL; } else { + readConfigRid(local, 1); /* Yes ! We can set it !!! */ local->config.channelSet = (u16)(channel - 1); local->need_commit = 1; @@ -4280,6 +4762,7 @@ struct airo_info *local = dev->priv; StatusRid status_rid; /* Card status info */ + readConfigRid(local, 1); if ((local->config.opmode & 0xFF) == MODE_STA_ESS) status_rid.channel = local->config.channelSet; else @@ -4336,6 +4819,7 @@ sizeof(SSID_rid.ssids[index].ssid)); memcpy(SSID_rid.ssids[index].ssid, extra, dwrq->length); SSID_rid.ssids[index].len = dwrq->length - 1; + SSID_rid.len = sizeof(SSID_rid); } /* Write it to the card */ disable_MAC(local, 1); @@ -4445,6 +4929,7 @@ if(dwrq->length > 16 + 1) { return -E2BIG; } + readConfigRid(local, 1); memset(local->config.nodeName, 0, sizeof(local->config.nodeName)); memcpy(local->config.nodeName, extra, dwrq->length); local->need_commit = 1; @@ -4463,6 +4948,7 @@ { struct airo_info *local = dev->priv; + readConfigRid(local, 1); strncpy(extra, local->config.nodeName, 16); extra[16] = '\0'; dwrq->length = strlen(extra) + 1; @@ -4519,6 +5005,7 @@ return -EINVAL; } + readConfigRid(local, 1); /* Now, check if we want a fixed or auto value */ if(vwrq->fixed == 0) { /* Fill all the rates up to this max rate */ @@ -4555,6 +5042,7 @@ vwrq->value = status_rid.currentXmitRate * 500000; /* If more than one rate, set auto */ + readConfigRid(local, 1); vwrq->fixed = (local->config.rates[1] == 0); return 0; @@ -4577,6 +5065,7 @@ if((rthr < 0) || (rthr > 2312)) { return -EINVAL; } + readConfigRid(local, 1); local->config.rtsThres = rthr; local->need_commit = 1; @@ -4594,6 +5083,7 @@ { struct airo_info *local = dev->priv; + readConfigRid(local, 1); vwrq->value = local->config.rtsThres; vwrq->disabled = (vwrq->value >= 2312); vwrq->fixed = 1; @@ -4619,6 +5109,7 @@ return -EINVAL; } fthr &= ~0x1; /* Get an even value - is it really needed ??? */ + readConfigRid(local, 1); local->config.fragThresh = (u16)fthr; local->need_commit = 1; @@ -4636,6 +5127,7 @@ { struct airo_info *local = dev->priv; + readConfigRid(local, 1); vwrq->value = local->config.fragThresh; vwrq->disabled = (vwrq->value >= 2312); vwrq->fixed = 1; @@ -4655,6 +5147,7 @@ struct airo_info *local = dev->priv; int commit = 1; + readConfigRid(local, 1); if ((local->config.rmode & 0xff) >= RXMODE_RFMON) commit = 2; @@ -4714,6 +5207,7 @@ { struct airo_info *local = dev->priv; + readConfigRid(local, 1); /* If not managed, assume it's ad-hoc */ switch (local->config.opmode & 0xFF) { case MODE_STA_ESS: @@ -4750,6 +5244,7 @@ if(!(cap_rid.softCap & 2)) { return -EOPNOTSUPP; } */ + readConfigRid(local, 1); /* Basic checking: do we have a key to set ? * Note : with the new API, it's impossible to get a NULL pointer. @@ -4836,6 +5331,7 @@ if(!(cap_rid.softCap & 2)) { return -EOPNOTSUPP; } + readConfigRid(local, 1); /* Check encryption mode */ switch(local->config.authType) { case AUTH_ENCRYPT: @@ -4892,6 +5388,7 @@ clear_bit (FLAG_RADIO_OFF, &local->flags); for (i = 0; cap_rid.txPowerLevels[i] && (i < 8); i++) if ((vwrq->value==cap_rid.txPowerLevels[i])) { + readConfigRid(local, 1); local->config.txPower = vwrq->value; local->need_commit = 1; rc = -EINPROGRESS; /* Call commit handler */ @@ -4911,6 +5408,7 @@ { struct airo_info *local = dev->priv; + readConfigRid(local, 1); vwrq->value = local->config.txPower; vwrq->fixed = 1; /* No power control */ vwrq->disabled = test_bit(FLAG_RADIO_OFF, &local->flags); @@ -4934,6 +5432,7 @@ if(vwrq->disabled) { return -EINVAL; } + readConfigRid(local, 1); if(vwrq->flags & IW_RETRY_LIMIT) { if(vwrq->flags & IW_RETRY_MAX) local->config.longRetryLimit = vwrq->value; @@ -4968,6 +5467,7 @@ vwrq->disabled = 0; /* Can't be disabled */ + readConfigRid(local, 1); /* Note : by default, display the min retry number */ if((vwrq->flags & IW_RETRY_TYPE) == IW_RETRY_LIFETIME) { vwrq->flags = IW_RETRY_LIFETIME; @@ -5106,6 +5606,7 @@ { struct airo_info *local = dev->priv; + readConfigRid(local, 1); if (vwrq->disabled) { if ((local->config.rmode & 0xFF) >= RXMODE_RFMON) { return -EINVAL; @@ -5162,6 +5663,7 @@ { struct airo_info *local = dev->priv; + readConfigRid(local, 1); int mode = local->config.powerSaveMode; if ((vwrq->disabled = (mode == POWERSAVE_CAM))) return 0; @@ -5191,6 +5693,7 @@ { struct airo_info *local = dev->priv; + readConfigRid(local, 1); local->config.rssiThreshold = vwrq->disabled ? RSSI_DEFAULT : vwrq->value; local->need_commit = 1; @@ -5208,6 +5711,7 @@ { struct airo_info *local = dev->priv; + readConfigRid(local, 1); vwrq->value = local->config.rssiThreshold; vwrq->disabled = (vwrq->value == 0); vwrq->fixed = 1; @@ -6017,7 +6521,7 @@ /* Separate R/W functions bracket legality here */ - if ( com.command <= AIROGMICSTATS ) + if ( com.command <= AIRORRID ) rc = readrids(dev,&com); else if ( com.command >= AIROPCAP && com.command <= AIROPLEAPUSR ) rc = writerids(dev,&com); @@ -6107,6 +6611,7 @@ static int readrids(struct net_device *dev, aironet_ioctl *comp) { unsigned short ridcode; unsigned char *iobuf; + int len; struct airo_info *ai = dev->priv; if (test_bit(FLAG_FLASHING, &ai->flags)) @@ -6134,11 +6639,14 @@ case AIROGSTAT: ridcode = RID_STATUS; break; case AIROGSTATSD32: ridcode = RID_STATSDELTA; break; case AIROGSTATSC32: ridcode = RID_STATS; break; +#ifdef MICSUPPORT case AIROGMICSTATS: if (copy_to_user(comp->data, &ai->micstats, min((int)comp->len,(int)sizeof(ai->micstats)))) return -EFAULT; return 0; +#endif + case AIRORRID: ridcode = comp->len; break; default: return -EINVAL; break; @@ -6152,9 +6660,12 @@ * then return it to the user * 9/22/2000 Honor user given length */ + if (comp->command == AIRORRID) + len = le16_to_cpu(*(unsigned short *)iobuf); /* Yuck! */ + else + len = comp->len; - if (copy_to_user(comp->data, iobuf, - min((int)comp->len, (int)RIDS_SIZE))) { + if (copy_to_user(comp->data, iobuf, min(len, (int)RIDS_SIZE))) { kfree (iobuf); return -EFAULT; } @@ -6222,9 +6733,11 @@ PC4500_readrid(ai,RID_STATSDELTACLEAR,iobuf,RIDS_SIZE, 1); +#ifdef MICSUPPORT enabled = ai->micstats.enabled; memset(&ai->micstats,0,sizeof(ai->micstats)); ai->micstats.enabled = enabled; +#endif if (copy_to_user(comp->data, iobuf, min((int)comp->len, (int)RIDS_SIZE))) { diff -Nru a/drivers/net/wireless/airport.c b/drivers/net/wireless/airport.c --- a/drivers/net/wireless/airport.c Tue Sep 2 19:58:19 2003 +++ b/drivers/net/wireless/airport.c Tue Sep 2 19:58:19 2003 @@ -25,8 +25,6 @@ #include #include #include -#include -#include #include #include @@ -48,96 +46,115 @@ int ndev_registered; }; -#ifdef CONFIG_PMAC_PBOOK -static int airport_sleep_notify(struct pmu_sleep_notifier *self, int when); -static struct pmu_sleep_notifier airport_sleep_notifier = { - airport_sleep_notify, SLEEP_LEVEL_NET, -}; -#endif +static int +airport_suspend(struct macio_dev *mdev, u32 state) +{ + struct net_device *dev = dev_get_drvdata(&mdev->ofdev.dev); + struct orinoco_private *priv = dev->priv; + struct airport *card = priv->card; + unsigned long flags; + int err; + + printk(KERN_DEBUG "%s: Airport entering sleep mode\n", dev->name); + + err = orinoco_lock(priv, &flags); + if (err) { + printk(KERN_ERR "%s: hw_unavailable on PBOOK_SLEEP_NOW\n", + dev->name); + return 0; + } + + err = __orinoco_down(dev); + if (err) + printk(KERN_WARNING "%s: PBOOK_SLEEP_NOW: Error %d downing interface\n", + dev->name, err); -/* - * Function prototypes - */ + netif_device_detach(dev); -static struct net_device *airport_attach(struct device_node *of_node); -static void airport_detach(struct net_device *dev); + priv->hw_unavailable++; -static struct net_device *airport_dev; + orinoco_unlock(priv, &flags); + + disable_irq(dev->irq); + pmac_call_feature(PMAC_FTR_AIRPORT_ENABLE, card->node, 0, 0); + + return 0; +} -#ifdef CONFIG_PMAC_PBOOK static int -airport_sleep_notify(struct pmu_sleep_notifier *self, int when) +airport_resume(struct macio_dev *mdev) { - struct net_device *dev = airport_dev; + struct net_device *dev = dev_get_drvdata(&mdev->ofdev.dev); struct orinoco_private *priv = dev->priv; struct airport *card = priv->card; unsigned long flags; int err; - - if (! airport_dev) - return PBOOK_SLEEP_OK; - - switch (when) { - case PBOOK_SLEEP_NOW: - printk(KERN_DEBUG "%s: Airport entering sleep mode\n", dev->name); - - err = orinoco_lock(priv, &flags); - if (err) { - printk(KERN_ERR "%s: hw_unavailable on PBOOK_SLEEP_NOW\n", - dev->name); - break; - } - err = __orinoco_down(dev); - if (err) - printk(KERN_WARNING "%s: PBOOK_SLEEP_NOW: Error %d downing interface\n", - dev->name, err); + printk(KERN_DEBUG "%s: Airport waking up\n", dev->name); - netif_device_detach(dev); + pmac_call_feature(PMAC_FTR_AIRPORT_ENABLE, card->node, 0, 1); + mdelay(200); - priv->hw_unavailable++; + enable_irq(dev->irq); - orinoco_unlock(priv, &flags); + err = orinoco_reinit_firmware(dev); + if (err) { + printk(KERN_ERR "%s: Error %d re-initializing firmware on PBOOK_WAKE\n", + dev->name, err); + return 0; + } - disable_irq(dev->irq); - pmac_call_feature(PMAC_FTR_AIRPORT_ENABLE, card->node, 0, 0); - break; + spin_lock_irqsave(&priv->lock, flags); - case PBOOK_WAKE: - printk(KERN_DEBUG "%s: Airport waking up\n", dev->name); - pmac_call_feature(PMAC_FTR_AIRPORT_ENABLE, card->node, 0, 1); - mdelay(200); + netif_device_attach(dev); - enable_irq(dev->irq); + priv->hw_unavailable--; - err = orinoco_reinit_firmware(dev); - if (err) { - printk(KERN_ERR "%s: Error %d re-initializing firmware on PBOOK_WAKE\n", + if (priv->open && (! priv->hw_unavailable)) { + err = __orinoco_up(dev); + if (err) + printk(KERN_ERR "%s: Error %d restarting card on PBOOK_WAKE\n", dev->name, err); - break; - } + } - spin_lock_irqsave(&priv->lock, flags); - netif_device_attach(dev); + spin_unlock_irqrestore(&priv->lock, flags); - priv->hw_unavailable--; + return 0; +} - if (priv->open && (! priv->hw_unavailable)) { - err = __orinoco_up(dev); - if (err) - printk(KERN_ERR "%s: Error %d restarting card on PBOOK_WAKE\n", - dev->name, err); - } +static int +airport_detach(struct macio_dev *mdev) +{ + struct net_device *dev = dev_get_drvdata(&mdev->ofdev.dev); + struct orinoco_private *priv = dev->priv; + struct airport *card = priv->card; + if (card->ndev_registered) + unregister_netdev(dev); + card->ndev_registered = 0; - spin_unlock_irqrestore(&priv->lock, flags); + if (card->irq_requested) + free_irq(dev->irq, dev); + card->irq_requested = 0; - break; - } - return PBOOK_SLEEP_OK; + if (card->vaddr) + iounmap(card->vaddr); + card->vaddr = 0; + + dev->base_addr = 0; + + release_OF_resource(card->node, 0); + + pmac_call_feature(PMAC_FTR_AIRPORT_ENABLE, card->node, 0, 0); + current->state = TASK_UNINTERRUPTIBLE; + schedule_timeout(HZ); + + dev_set_drvdata(&mdev->ofdev.dev, NULL); + free_netdev(dev); + + return 0; } -#endif /* CONFIG_PMAC_PBOOK */ static int airport_hard_reset(struct orinoco_private *priv) { @@ -170,25 +187,26 @@ return 0; } -static struct net_device * -airport_attach(struct device_node *of_node) +static int +airport_attach(struct macio_dev *mdev, const struct of_match *match) { struct orinoco_private *priv; struct net_device *dev; struct airport *card; unsigned long phys_addr; + struct device_node *of_node = mdev->ofdev.node; hermes_t *hw; if (of_node->n_addrs < 1 || of_node->n_intrs < 1) { printk(KERN_ERR "airport: wrong interrupt/addresses in OF tree\n"); - return NULL; + return -ENODEV; } /* Allocate space for private device-specific data */ dev = alloc_orinocodev(sizeof(*card), airport_hard_reset); if (! dev) { printk(KERN_ERR "airport: can't allocate device datas\n"); - return NULL; + return -ENODEV; } priv = dev->priv; card = priv->card; @@ -199,11 +217,14 @@ if (! request_OF_resource(of_node, 0, " (airport)")) { printk(KERN_ERR "airport: can't request IO resource !\n"); kfree(dev); - return NULL; + return -ENODEV; } dev->name[0] = '\0'; /* register_netdev will give us an ethX name */ SET_MODULE_OWNER(dev); + SET_NETDEV_DEV(dev, &mdev->ofdev.dev); + + dev_set_drvdata(&mdev->ofdev.dev, dev); /* Setup interrupts & base address */ dev->irq = of_node->intrs[0].line; @@ -240,79 +261,50 @@ } printk(KERN_DEBUG "airport: card registered for interface %s\n", dev->name); card->ndev_registered = 1; - -#ifdef CONFIG_PMAC_PBOOK - pmu_register_sleep_notifier(&airport_sleep_notifier); -#endif - return dev; - + return 0; failed: - airport_detach(dev); - return NULL; + airport_detach(mdev); + return -ENODEV; } /* airport_attach */ -/*====================================================================== - This deletes a driver "instance". - ======================================================================*/ - -static void -airport_detach(struct net_device *dev) -{ - struct orinoco_private *priv = dev->priv; - struct airport *card = priv->card; - -#ifdef CONFIG_PMAC_PBOOK - pmu_unregister_sleep_notifier(&airport_sleep_notifier); -#endif - if (card->ndev_registered) - unregister_netdev(dev); - card->ndev_registered = 0; - - if (card->irq_requested) - free_irq(dev->irq, dev); - card->irq_requested = 0; - - if (card->vaddr) - iounmap(card->vaddr); - card->vaddr = 0; - - dev->base_addr = 0; - - release_OF_resource(card->node, 0); - - pmac_call_feature(PMAC_FTR_AIRPORT_ENABLE, card->node, 0, 0); - current->state = TASK_UNINTERRUPTIBLE; - schedule_timeout(HZ); - - free_netdev(dev); -} /* airport_detach */ static char version[] __initdata = "airport.c 0.13e (Benjamin Herrenschmidt )"; MODULE_AUTHOR("Benjamin Herrenschmidt "); MODULE_DESCRIPTION("Driver for the Apple Airport wireless card."); MODULE_LICENSE("Dual MPL/GPL"); +static struct of_match airport_match[] = +{ + { + .name = "radio", + .type = OF_ANY_MATCH, + .compatible = OF_ANY_MATCH + }, + {}, +}; + +static struct macio_driver airport_driver = +{ + .name = "airport", + .match_table = airport_match, + .probe = airport_attach, + .remove = airport_detach, + .suspend = airport_suspend, + .resume = airport_resume, +}; + static int __init init_airport(void) { - struct device_node *airport_node; - printk(KERN_DEBUG "%s\n", version); - /* Lookup card in device tree */ - airport_node = find_devices("radio"); - if (airport_node && !strcmp(airport_node->parent->name, "mac-io")) - airport_dev = airport_attach(airport_node); - - return airport_dev ? 0 : -ENODEV; + return macio_register_driver(&airport_driver); } static void __exit exit_airport(void) { - if (airport_dev) - airport_detach(airport_dev); - airport_dev = NULL; + return macio_unregister_driver(&airport_driver); } module_init(init_airport); diff -Nru a/drivers/net/wireless/ray_cs.c b/drivers/net/wireless/ray_cs.c --- a/drivers/net/wireless/ray_cs.c Tue Sep 2 19:58:15 2003 +++ b/drivers/net/wireless/ray_cs.c Tue Sep 2 19:58:15 2003 @@ -105,6 +105,9 @@ static struct net_device_stats *ray_get_stats(struct net_device *dev); static int ray_dev_init(struct net_device *dev); static int ray_dev_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd); + +static struct ethtool_ops netdev_ethtool_ops; + static int ray_open(struct net_device *dev); static int ray_dev_start_xmit(struct sk_buff *skb, struct net_device *dev); static void set_multicast_list(struct net_device *dev); @@ -408,6 +411,7 @@ dev->set_config = &ray_dev_config; dev->get_stats = &ray_get_stats; dev->do_ioctl = &ray_dev_ioctl; + SET_ETHTOOL_OPS(dev, &netdev_ethtool_ops); #if WIRELESS_EXT > 7 /* If wireless extension exist in the kernel */ dev->get_wireless_stats = ray_get_wireless_stats; #endif @@ -1226,26 +1230,16 @@ /*===========================================================================*/ -static int netdev_ethtool_ioctl(struct net_device *dev, void *useraddr) +static void netdev_get_drvinfo(struct net_device *dev, + struct ethtool_drvinfo *info) { - u32 ethcmd; - - if (copy_from_user(ðcmd, useraddr, sizeof(ethcmd))) - return -EFAULT; - - switch (ethcmd) { - case ETHTOOL_GDRVINFO: { - struct ethtool_drvinfo info = {ETHTOOL_GDRVINFO}; - strncpy(info.driver, "ray_cs", sizeof(info.driver)-1); - if (copy_to_user(useraddr, &info, sizeof(info))) - return -EFAULT; - return 0; - } - } - - return -EOPNOTSUPP; + strcpy(info->driver, "ray_cs"); } +static struct ethtool_ops netdev_ethtool_ops = { + .get_drvinfo = netdev_get_drvinfo, +}; + /*====================================================================*/ static int ray_dev_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) @@ -1265,10 +1259,6 @@ /* Validate the command */ switch (cmd) { - case SIOCETHTOOL: - err = netdev_ethtool_ioctl(dev, (void *) ifr->ifr_data); - break; - #if WIRELESS_EXT > 7 /* --------------- WIRELESS EXTENSIONS --------------- */ /* Get name */ diff -Nru a/drivers/net/yellowfin.c b/drivers/net/yellowfin.c --- a/drivers/net/yellowfin.c Tue Sep 2 19:58:15 2003 +++ b/drivers/net/yellowfin.c Tue Sep 2 19:58:15 2003 @@ -873,8 +873,6 @@ /* Calculate the next Tx descriptor entry. */ entry = yp->cur_tx % TX_RING_SIZE; - yp->tx_skbuff[entry] = skb; - if (gx_fix) { /* Note: only works for paddable protocols e.g. IP. */ int cacheline_end = ((unsigned long)skb->data + skb->len) % 32; /* Fix GX chipset errata. */ @@ -889,6 +887,8 @@ return 0; } } + yp->tx_skbuff[entry] = skb; + #ifdef NO_TXSTATS yp->tx_ring[entry].addr = cpu_to_le32(pci_map_single(yp->pci_dev, skb->data, len, PCI_DMA_TODEVICE)); diff -Nru a/drivers/parport/parport_pc.c b/drivers/parport/parport_pc.c --- a/drivers/parport/parport_pc.c Tue Sep 2 19:58:19 2003 +++ b/drivers/parport/parport_pc.c Tue Sep 2 19:58:19 2003 @@ -93,7 +93,7 @@ int dma; } superios[NR_SUPERIOS] __devinitdata = { {0,},}; -static int user_specified __devinitdata = 0; +static int user_specified; #if defined(CONFIG_PARPORT_PC_SUPERIO) || \ (defined(CONFIG_PARPORT_1284) && defined(CONFIG_PARPORT_PC_FIFO)) static int verbose_probing; diff -Nru a/drivers/pci/pci.ids b/drivers/pci/pci.ids --- a/drivers/pci/pci.ids Tue Sep 2 19:58:16 2003 +++ b/drivers/pci/pci.ids Tue Sep 2 19:58:16 2003 @@ -3247,7 +3247,8 @@ 1148 5061 SK-9861 V2.0 Gigabit Ethernet 1000Base-SX Adapter 1148 5071 SK-9871 V2.0 Gigabit Ethernet 1000Base-ZX Adapter 1148 9521 SK-9521 10/100/1000Base-T Adapter - 4400 Gigabit Ethernet + 4400 SK-9Dxx Gigabit Ethernet Adapter + 4500 SK-9Mxx Gigabit Ethernet Adapter 1149 Win System Corporation 114a VMIC 5579 VMIPCI-5579 (Reflective Memory Card) @@ -5313,9 +5314,12 @@ 1166 1648 NetXtreme CIOB-E 1000Base-T 164d NetXtreme BCM5702FE Gigabit Ethernet 1653 NetXtreme BCM5705 Gigabit Ethernet + 1654 NetXtreme BCM5705 Gigabit Ethernet 165d NetXtreme BCM5705M Gigabit Ethernet + 165e NetXtreme BCM5705M Gigabit Ethernet 1696 NetXtreme BCM5782 Gigabit Ethernet 14e4 000d NetXtreme BCM5782 1000Base-T + 169c NetXtreme BCM5788 Gigabit Ethernet 16a6 NetXtreme BCM5702 Gigabit Ethernet 0e11 00bb NC7760 Gigabit Server Adapter (PCI-X, 10/100/1000-T) 1028 0126 BCM5702 1000Base-T @@ -5337,6 +5341,8 @@ 16c7 NetXtreme BCM5703 Gigabit Ethernet 14e4 0009 NetXtreme BCM5703 1000Base-T 14e4 000a NetXtreme BCM5703 1000Base-SX + 170d NetXtreme BCM5901 Gigabit Ethernet + 170e NetXtreme BCM5901 Gigabit Ethernet 4210 BCM4210 iLine10 HomePNA 2.0 4211 BCM4211 iLine10 HomePNA 2.0 + V.90 56k modem 4212 BCM4212 v.90 56k modem @@ -5877,6 +5883,8 @@ 03e8 AC1000 Gigabit Ethernet 03e9 AC1001 Gigabit Ethernet 03ea AC9100 Gigabit Ethernet + 173b 0001 AC1002 + 03eb AC1003 Gigabit Ethernet 1743 Peppercon AG 8139 ROL/F-100 Fast Ethernet Adapter with ROL 174b PC Partner Limited diff -Nru a/drivers/pcmcia/cistpl.c b/drivers/pcmcia/cistpl.c --- a/drivers/pcmcia/cistpl.c Tue Sep 2 19:58:14 2003 +++ b/drivers/pcmcia/cistpl.c Tue Sep 2 19:58:14 2003 @@ -293,15 +293,17 @@ #endif ret = read_cis_mem(s, attr, addr, len, ptr); - /* Copy data into the cache */ - cis = kmalloc(sizeof(struct cis_cache_entry) + len, GFP_KERNEL); - if (cis) { - cis->addr = addr; - cis->len = len; - cis->attr = attr; - memcpy(cis->cache, ptr, len); - list_add(&cis->node, &s->cis_cache); - } + if (ret == 0) { + /* Copy data into the cache */ + cis = kmalloc(sizeof(struct cis_cache_entry) + len, GFP_KERNEL); + if (cis) { + cis->addr = addr; + cis->len = len; + cis->attr = attr; + memcpy(cis->cache, ptr, len); + list_add(&cis->node, &s->cis_cache); + } + } } static void diff -Nru a/drivers/pcmcia/ds.c b/drivers/pcmcia/ds.c --- a/drivers/pcmcia/ds.c Tue Sep 2 19:58:18 2003 +++ b/drivers/pcmcia/ds.c Tue Sep 2 19:58:18 2003 @@ -495,7 +495,7 @@ static int ds_open(struct inode *inode, struct file *file) { - socket_t i = minor(inode->i_rdev); + socket_t i = iminor(inode); struct pcmcia_bus_socket *s; user_info_t *user; @@ -529,7 +529,7 @@ static int ds_release(struct inode *inode, struct file *file) { - socket_t i = minor(inode->i_rdev); + socket_t i = iminor(inode); struct pcmcia_bus_socket *s; user_info_t *user, **link; @@ -563,7 +563,7 @@ static ssize_t ds_read(struct file *file, char *buf, size_t count, loff_t *ppos) { - socket_t i = minor(file->f_dentry->d_inode->i_rdev); + socket_t i = iminor(file->f_dentry->d_inode); struct pcmcia_bus_socket *s; user_info_t *user; @@ -594,7 +594,7 @@ static ssize_t ds_write(struct file *file, const char *buf, size_t count, loff_t *ppos) { - socket_t i = minor(file->f_dentry->d_inode->i_rdev); + socket_t i = iminor(file->f_dentry->d_inode); struct pcmcia_bus_socket *s; user_info_t *user; @@ -629,7 +629,7 @@ /* No kernel lock - fine */ static u_int ds_poll(struct file *file, poll_table *wait) { - socket_t i = minor(file->f_dentry->d_inode->i_rdev); + socket_t i = iminor(file->f_dentry->d_inode); struct pcmcia_bus_socket *s; user_info_t *user; @@ -653,7 +653,7 @@ static int ds_ioctl(struct inode * inode, struct file * file, u_int cmd, u_long arg) { - socket_t i = minor(inode->i_rdev); + socket_t i = iminor(inode); struct pcmcia_bus_socket *s; u_int size; int ret, err; diff -Nru a/drivers/pcmcia/ricoh.h b/drivers/pcmcia/ricoh.h --- a/drivers/pcmcia/ricoh.h Tue Sep 2 19:58:15 2003 +++ b/drivers/pcmcia/ricoh.h Tue Sep 2 19:58:15 2003 @@ -142,59 +142,61 @@ config_writeb(socket, RL5C4XX_MISC_CONTROL, reg); } -static void ricoh_set_zv(struct pcmcia_socket *sock) +static void ricoh_set_zv(struct yenta_socket *socket) { - struct yenta_socket *socket = container_of(sock, struct yenta_socket, socket); if(socket->dev->vendor == PCI_VENDOR_ID_RICOH) { switch(socket->dev->device) { /* There may be more .. */ case PCI_DEVICE_ID_RICOH_RL5C478: - sock->zoom_video = ricoh_zoom_video; + socket->socket.zoom_video = ricoh_zoom_video; break; } } } -static int ricoh_init(struct pcmcia_socket *sock) +static void ricoh_save_state(struct yenta_socket *socket) { - struct yenta_socket *socket = container_of(sock, struct yenta_socket, socket); - yenta_init(sock); - ricoh_set_zv(sock); + rl_misc(socket) = config_readw(socket, RL5C4XX_MISC); + rl_ctl(socket) = config_readw(socket, RL5C4XX_16BIT_CTL); + rl_io(socket) = config_readw(socket, RL5C4XX_16BIT_IO_0); + rl_mem(socket) = config_readw(socket, RL5C4XX_16BIT_MEM_0); + rl_config(socket) = config_readw(socket, RL5C4XX_CONFIG); +} +static void ricoh_restore_state(struct yenta_socket *socket) +{ config_writew(socket, RL5C4XX_MISC, rl_misc(socket)); config_writew(socket, RL5C4XX_16BIT_CTL, rl_ctl(socket)); config_writew(socket, RL5C4XX_16BIT_IO_0, rl_io(socket)); config_writew(socket, RL5C4XX_16BIT_MEM_0, rl_mem(socket)); config_writew(socket, RL5C4XX_CONFIG, rl_config(socket)); - - return 0; } /* - * Magic Ricoh initialization code.. Save state at - * beginning, re-initialize it after suspend. + * Magic Ricoh initialization code.. */ static int ricoh_override(struct yenta_socket *socket) { - rl_misc(socket) = config_readw(socket, RL5C4XX_MISC); - rl_ctl(socket) = config_readw(socket, RL5C4XX_16BIT_CTL); - rl_io(socket) = config_readw(socket, RL5C4XX_16BIT_IO_0); - rl_mem(socket) = config_readw(socket, RL5C4XX_16BIT_MEM_0); - rl_config(socket) = config_readw(socket, RL5C4XX_CONFIG); + u16 config, ctl; + + config = config_readw(socket, RL5C4XX_CONFIG); /* Set the default timings, don't trust the original values */ - rl_ctl(socket) = RL5C4XX_16CTL_IO_TIMING | RL5C4XX_16CTL_MEM_TIMING; + ctl = RL5C4XX_16CTL_IO_TIMING | RL5C4XX_16CTL_MEM_TIMING; if(socket->dev->device < PCI_DEVICE_ID_RICOH_RL5C475) { - rl_ctl(socket) |= RL5C46X_16CTL_LEVEL_1 | RL5C46X_16CTL_LEVEL_2; + ctl |= RL5C46X_16CTL_LEVEL_1 | RL5C46X_16CTL_LEVEL_2; } else { - rl_config(socket) |= RL5C4XX_CONFIG_PREFETCH; + config |= RL5C4XX_CONFIG_PREFETCH; } - socket->socket.ops->init = ricoh_init; + config_writew(socket, RL5C4XX_16BIT_CTL, ctl); + config_writew(socket, RL5C4XX_CONFIG, config); + + ricoh_set_zv(socket); return 0; } diff -Nru a/drivers/pcmcia/sa1111_generic.c b/drivers/pcmcia/sa1111_generic.c --- a/drivers/pcmcia/sa1111_generic.c Tue Sep 2 19:58:14 2003 +++ b/drivers/pcmcia/sa1111_generic.c Tue Sep 2 19:58:14 2003 @@ -16,6 +16,7 @@ #include #include +#include #include #include "sa1111_generic.h" @@ -118,16 +119,15 @@ sa11xx_disable_irqs(skt, irqs, ARRAY_SIZE(irqs)); } -static int pcmcia_probe(struct device *dev) +static int pcmcia_probe(struct sa1111_dev *dev) { - struct sa1111_dev *sadev = SA1111_DEV(dev); char *base; - if (!request_mem_region(sadev->res.start, 512, - SA1111_DRIVER_NAME(sadev))) + if (!request_mem_region(dev->res.start, 512, + SA1111_DRIVER_NAME(dev))) return -EBUSY; - base = sadev->mapbase; + base = dev->mapbase; /* * Initialise the suspend state. @@ -136,61 +136,68 @@ sa1111_writel(PCCR_S0_FLT | PCCR_S1_FLT, base + SA1111_PCCR); #ifdef CONFIG_SA1100_ADSBITSY - pcmcia_adsbitsy_init(dev); + pcmcia_adsbitsy_init(&dev->dev); #endif #ifdef CONFIG_SA1100_BADGE4 - pcmcia_badge4_init(dev); + pcmcia_badge4_init(&dev->dev); #endif #ifdef CONFIG_SA1100_GRAPHICSMASTER - pcmcia_graphicsmaster_init(dev); + pcmcia_graphicsmaster_init(&dev->dev); #endif #ifdef CONFIG_SA1100_JORNADA720 - pcmcia_jornada720_init(dev); + pcmcia_jornada720_init(&dev->dev); #endif #ifdef CONFIG_ASSABET_NEPONSET - pcmcia_neponset_init(dev); + pcmcia_neponset_init(&dev->dev); #endif #ifdef CONFIG_SA1100_PFS168 - pcmcia_pfs_init(dev); + pcmcia_pfs_init(&dev->dev); #endif #ifdef CONFIG_SA1100_PT_SYSTEM3 - pcmcia_system3_init(dev); + pcmcia_system3_init(&dev->dev); #endif #ifdef CONFIG_SA1100_XP860 - pcmcia_xp860_init(dev); + pcmcia_xp860_init(&dev->dev); #endif return 0; } -static int __devexit pcmcia_remove(struct device *dev) +static int __devexit pcmcia_remove(struct sa1111_dev *dev) { - struct sa1111_dev *sadev = SA1111_DEV(dev); - - sa11xx_drv_pcmcia_remove(dev); - release_mem_region(sadev->res.start, 512); + sa11xx_drv_pcmcia_remove(&dev->dev); + release_mem_region(dev->res.start, 512); return 0; } +static int pcmcia_suspend(struct sa1111_dev *dev, u32 state) +{ + return pcmcia_socket_dev_suspend(&dev->dev, state, SUSPEND_SAVE_STATE); +} + +static int pcmcia_resume(struct sa1111_dev *dev) +{ + return pcmcia_socket_dev_resume(&dev->dev, RESUME_RESTORE_STATE); +} + static struct sa1111_driver pcmcia_driver = { .drv = { - .name = "sa1111-pcmcia", - .bus = &sa1111_bus_type, - .probe = pcmcia_probe, - .remove = __devexit_p(pcmcia_remove), - .suspend = pcmcia_socket_dev_suspend, - .resume = pcmcia_socket_dev_resume, + .name = "sa1111-pcmcia", }, - .devid = SA1111_DEVID_PCMCIA, + .devid = SA1111_DEVID_PCMCIA, + .probe = pcmcia_probe, + .remove = __devexit_p(pcmcia_remove), + .suspend = pcmcia_suspend, + .resume = pcmcia_resume, }; static int __init sa1111_drv_pcmcia_init(void) { - return driver_register(&pcmcia_driver.drv); + return sa1111_driver_register(&pcmcia_driver); } static void __exit sa1111_drv_pcmcia_exit(void) { - driver_unregister(&pcmcia_driver.drv); + sa1111_driver_unregister(&pcmcia_driver); } module_init(sa1111_drv_pcmcia_init); diff -Nru a/drivers/pcmcia/ti113x.h b/drivers/pcmcia/ti113x.h --- a/drivers/pcmcia/ti113x.h Tue Sep 2 19:58:15 2003 +++ b/drivers/pcmcia/ti113x.h Tue Sep 2 19:58:15 2003 @@ -136,16 +136,34 @@ #ifdef CONFIG_CARDBUS -static int ti_intctl(struct yenta_socket *socket) +/* + * Texas Instruments CardBus controller overrides. + */ +#define ti_sysctl(socket) ((socket)->private[0]) +#define ti_cardctl(socket) ((socket)->private[1]) +#define ti_devctl(socket) ((socket)->private[2]) +#define ti_diag(socket) ((socket)->private[3]) +#define ti_irqmux(socket) ((socket)->private[4]) + +/* + * These are the TI specific power management handlers. + */ +static void ti_save_state(struct yenta_socket *socket) { - u8 new, reg = exca_readb(socket, I365_INTCTL); + ti_sysctl(socket) = config_readl(socket, TI113X_SYSTEM_CONTROL); + ti_irqmux(socket) = config_readl(socket, TI122X_IRQMUX); + ti_cardctl(socket) = config_readb(socket, TI113X_CARD_CONTROL); + ti_devctl(socket) = config_readb(socket, TI113X_DEVICE_CONTROL); + ti_diag(socket) = config_readb(socket, TI1250_DIAGNOSTIC); +} - new = reg & ~I365_INTR_ENA; - if (socket->cb_irq) - new |= I365_INTR_ENA; - if (new != reg) - exca_writeb(socket, I365_INTCTL, new); - return 0; +static void ti_restore_state(struct yenta_socket *socket) +{ + config_writel(socket, TI113X_SYSTEM_CONTROL, ti_sysctl(socket)); + config_writel(socket, TI122X_IRQMUX, ti_irqmux(socket)); + config_writeb(socket, TI113X_CARD_CONTROL, ti_cardctl(socket)); + config_writeb(socket, TI113X_DEVICE_CONTROL, ti_devctl(socket)); + config_writeb(socket, TI1250_DIAGNOSTIC, ti_diag(socket)); } /* @@ -185,8 +203,8 @@ ti_zoom_video(sock, onoff); - reg = config_readb(socket, 0x84); - reg |= (1<<7); /* ZV bus enable */ + reg = config_readb(socket, TI1250_MULTIMEDIA_CTL); + reg |= TI1250_MMC_ZVOUTEN; /* ZV bus enable */ if(PCI_FUNC(socket->dev->devfn)==1) shift = 1; @@ -204,12 +222,11 @@ reg &= ~(1<dev->vendor == PCI_VENDOR_ID_TI) { switch(socket->dev->device) @@ -218,24 +235,16 @@ case PCI_DEVICE_ID_TI_1220: case PCI_DEVICE_ID_TI_1221: case PCI_DEVICE_ID_TI_1225: - sock->zoom_video = ti_zoom_video; + socket->socket.zoom_video = ti_zoom_video; break; case PCI_DEVICE_ID_TI_1250: case PCI_DEVICE_ID_TI_1251A: case PCI_DEVICE_ID_TI_1251B: case PCI_DEVICE_ID_TI_1450: - sock->zoom_video = ti1250_zoom_video; + socket->socket.zoom_video = ti1250_zoom_video; } } } -static int ti_init(struct pcmcia_socket *sock) -{ - struct yenta_socket *socket = container_of(sock, struct yenta_socket, socket); - yenta_init(sock); - ti_set_zv(sock); - ti_intctl(socket); - return 0; -} /* @@ -250,6 +259,18 @@ * This makes us correctly get PCI CSC interrupt * events. */ +static int ti_init(struct yenta_socket *socket) +{ + u8 new, reg = exca_readb(socket, I365_INTCTL); + + new = reg & ~I365_INTR_ENA; + if (socket->cb_irq) + new |= I365_INTR_ENA; + if (new != reg) + exca_writeb(socket, I365_INTCTL, new); + return 0; +} + static int ti_override(struct yenta_socket *socket) { u8 new, reg = exca_readb(socket, I365_INTCTL); @@ -258,6 +279,8 @@ if (new != reg) exca_writeb(socket, I365_INTCTL, new); + ti_set_zv(socket); + #if 0 /* * If ISA interrupts don't work, then fall back to routing card @@ -285,83 +308,85 @@ } #endif - socket->socket.ops->init = ti_init; - return 0; -} - -#define ti_sysctl(socket) ((socket)->private[0]) -#define ti_cardctl(socket) ((socket)->private[1]) -#define ti_devctl(socket) ((socket)->private[2]) -#define ti_diag(socket) ((socket)->private[3]) -#define ti_irqmux(socket) ((socket)->private[4]) - - -static int ti113x_init(struct pcmcia_socket *sock) -{ - struct yenta_socket *socket = container_of(sock, struct yenta_socket, socket); - yenta_init(sock); - ti_set_zv(sock); - - config_writel(socket, TI113X_SYSTEM_CONTROL, ti_sysctl(socket)); - config_writeb(socket, TI113X_CARD_CONTROL, ti_cardctl(socket)); - config_writeb(socket, TI113X_DEVICE_CONTROL, ti_devctl(socket)); - ti_intctl(socket); return 0; } static int ti113x_override(struct yenta_socket *socket) { - ti_sysctl(socket) = config_readl(socket, TI113X_SYSTEM_CONTROL); - ti_cardctl(socket) = config_readb(socket, TI113X_CARD_CONTROL); - ti_devctl(socket) = config_readb(socket, TI113X_DEVICE_CONTROL); + u8 cardctl; - ti_cardctl(socket) &= ~(TI113X_CCR_PCI_IRQ_ENA | TI113X_CCR_PCI_IREQ | TI113X_CCR_PCI_CSC); + cardctl = config_readb(socket, TI113X_CARD_CONTROL); + cardctl &= ~(TI113X_CCR_PCI_IRQ_ENA | TI113X_CCR_PCI_IREQ | TI113X_CCR_PCI_CSC); if (socket->cb_irq) - ti_cardctl(socket) |= TI113X_CCR_PCI_IRQ_ENA | TI113X_CCR_PCI_CSC | TI113X_CCR_PCI_IREQ; - ti_override(socket); - socket->socket.ops->init = ti113x_init; - return 0; + cardctl |= TI113X_CCR_PCI_IRQ_ENA | TI113X_CCR_PCI_CSC | TI113X_CCR_PCI_IREQ; + config_writeb(socket, TI113X_CARD_CONTROL, cardctl); + + return ti_override(socket); } -static int ti1250_init(struct pcmcia_socket *sock) +static int ti12xx_override(struct yenta_socket *socket) { - struct yenta_socket *socket = container_of(sock, struct yenta_socket, socket); - ti113x_init(sock); - ti_irqmux(socket) = config_readl(socket, TI122X_IRQMUX); -#if 0 - ti_irqmux(socket) = (ti_irqmux(socket) & ~0x0f) | 0x02; /* route INTA */ - if (!(ti_sysctl(socket) & TI122X_SCR_INTRTIE)) - ti_irqmux(socket) |= 0x20; /* route INTB */ -#endif - - config_writel(socket, TI122X_IRQMUX, ti_irqmux(socket)); - - config_writeb(socket, TI1250_DIAGNOSTIC, ti_diag(socket)); - return 0; + u32 val; + + /* make sure that memory burst is active */ + val = config_readl(socket, TI113X_SYSTEM_CONTROL); + if (!(val & TI122X_SCR_MRBURSTUP)) { + printk(KERN_INFO "Yenta: Enabling burst memory read transactions\n"); + val |= TI122X_SCR_MRBURSTUP; + config_writel(socket, TI113X_SYSTEM_CONTROL, val); + } + + /* + * Yenta expects controllers to use CSCINT to route + * CSC interrupts to PCI rather than INTVAL. + */ + val = config_readb(socket, TI1250_DIAGNOSTIC); + printk(KERN_INFO "Yenta: Using %s to route CSC interrupts to PCI\n", + (val & TI1250_DIAG_PCI_CSC) ? "CSCINT" : "INTVAL"); + printk(KERN_INFO "Yenta: Routing CardBus interrupts to %s\n", + (val & TI1250_DIAG_PCI_IREQ) ? "PCI" : "ISA"); + + return ti_override(socket); } + static int ti1250_override(struct yenta_socket *socket) { - ti_diag(socket) = config_readb(socket, TI1250_DIAGNOSTIC); + u8 old, diag; - ti_diag(socket) &= ~(TI1250_DIAG_PCI_CSC | TI1250_DIAG_PCI_IREQ); + old = config_readb(socket, TI1250_DIAGNOSTIC); + diag = old & ~(TI1250_DIAG_PCI_CSC | TI1250_DIAG_PCI_IREQ); if (socket->cb_irq) - ti_diag(socket) |= TI1250_DIAG_PCI_CSC | TI1250_DIAG_PCI_IREQ; - ti113x_override(socket); - socket->socket.ops->init = ti1250_init; - return 0; -} + diag |= TI1250_DIAG_PCI_CSC | TI1250_DIAG_PCI_IREQ; + if (diag != old) { + printk(KERN_INFO "Yenta: adjusting diagnostic: %02x -> %02x\n", + old, diag); + config_writeb(socket, TI1250_DIAGNOSTIC, diag); + } -static int ti12xx_override(struct yenta_socket *socket) -{ - /* make sure that memory burst is active */ - ti_sysctl(socket) = config_readl(socket, TI113X_SYSTEM_CONTROL); - ti_sysctl(socket) |= TI122X_SCR_MRBURSTUP; - config_writel(socket, TI113X_SYSTEM_CONTROL, ti_sysctl(socket)); +#if 0 + /* + * This is highly machine specific, and we should NOT touch + * this register - we have no knowledge how the hardware + * is actually wired. + * + * If we're going to do this, we should probably look into + * using the subsystem IDs. + * + * On ThinkPad 380XD, this changes MFUNC0 from the ISA IRQ3 + * output (which it is) to IRQ2. We also change MFUNC1 + * from ISA IRQ4 to IRQ6. + */ + irqmux = config_readl(socket, TI122X_IRQMUX); + irqmux = (irqmux & ~0x0f) | 0x02; /* route INTA */ + if (!(ti_sysctl(socket) & TI122X_SCR_INTRTIE)) + irqmux = (irqmux & ~0xf0) | 0x20; /* route INTB */ + config_writel(socket, TI122X_IRQMUX, irqmux); +#endif - return ti113x_override(socket); + return ti12xx_override(socket); } #endif /* CONFIG_CARDBUS */ diff -Nru a/drivers/pcmcia/topic.h b/drivers/pcmcia/topic.h --- a/drivers/pcmcia/topic.h Tue Sep 2 19:58:20 2003 +++ b/drivers/pcmcia/topic.h Tue Sep 2 19:58:20 2003 @@ -31,20 +31,7 @@ #ifndef _LINUX_TOPIC_H #define _LINUX_TOPIC_H -#ifndef PCI_VENDOR_ID_TOSHIBA -#define PCI_VENDOR_ID_TOSHIBA 0x1179 -#endif -#ifndef PCI_DEVICE_ID_TOSHIBA_TOPIC95_A -#define PCI_DEVICE_ID_TOSHIBA_TOPIC95_A 0x0603 -#endif -#ifndef PCI_DEVICE_ID_TOSHIBA_TOPIC95_B -#define PCI_DEVICE_ID_TOSHIBA_TOPIC95_B 0x060a -#endif -#ifndef PCI_DEVICE_ID_TOSHIBA_TOPIC97 -#define PCI_DEVICE_ID_TOSHIBA_TOPIC97 0x060f -#endif - -/* Register definitions for Toshiba ToPIC95 controllers */ +/* Register definitions for Toshiba ToPIC95/97/100 controllers */ #define TOPIC_SOCKET_CONTROL 0x0090 /* 32 bit */ #define TOPIC_SCR_IRQSEL 0x00000001 @@ -92,5 +79,62 @@ #define TOPIC97_RCR_RI_DISABLE 0x00000004 #define TOPIC97_RCR_CAUDIO_OFF 0x00000002 #define TOPIC_RCR_CAUDIO_INVERT 0x00000001 + +#define TOPIC97_MISC1 0x00ad /* 8bit */ +#define TOPIC97_MISC1_CLOCKRUN_ENABLE 0x80 +#define TOPIC97_MISC1_CLOCKRUN_MODE 0x40 +#define TOPIC97_MISC1_DETECT_REQ_ENA 0x10 +#define TOPIC97_MISC1_SCK_CLEAR_DIS 0x04 +#define TOPIC97_MISC1_R2_LOW_ENABLE 0x10 + +#define TOPIC97_MISC2 0x00ae /* 8 bit */ +#define TOPIC97_MISC2_SPWRCLK_MASK 0x70 +#define TOPIC97_MISC2_SPWRMOD 0x08 +#define TOPIC97_MISC2_SPWR_ENABLE 0x04 +#define TOPIC97_MISC2_ZV_MODE 0x02 +#define TOPIC97_MISC2_ZV_ENABLE 0x01 + +#define TOPIC97_ZOOM_VIDEO_CONTROL 0x009c /* 8 bit */ +#define TOPIC97_ZV_CONTROL_ENABLE 0x01 + +#define TOPIC97_AUDIO_VIDEO_SWITCH 0x003c /* 8 bit */ +#define TOPIC97_AVS_AUDIO_CONTROL 0x02 +#define TOPIC97_AVS_VIDEO_CONTROL 0x01 + + +static void topic97_zoom_video(struct pcmcia_socket *sock, int onoff) +{ + struct yenta_socket *socket = container_of(sock, struct yenta_socket, socket); + u8 reg_zv, reg; + + reg_zv = config_readb(socket, TOPIC97_ZOOM_VIDEO_CONTROL); + if (onoff) { + reg_zv |= TOPIC97_ZV_CONTROL_ENABLE; + config_writeb(socket, TOPIC97_ZOOM_VIDEO_CONTROL, reg_zv); + + reg = config_readb(socket, TOPIC97_MISC2); + reg |= TOPIC97_MISC2_ZV_ENABLE; + config_writeb(socket, TOPIC97_MISC2, reg); + + /* not sure this is needed, doc is unclear */ +#if 0 + reg = config_readb(socket, TOPIC97_AUDIO_VIDEO_SWITCH); + reg |= TOPIC97_AVS_AUDIO_CONTROL | TOPIC97_AVS_VIDEO_CONTROL; + config_writeb(socket, TOPIC97_AUDIO_VIDEO_SWITCH, reg); +#endif + } + else { + reg_zv &= ~TOPIC97_ZV_CONTROL_ENABLE; + config_writeb(socket, TOPIC97_ZOOM_VIDEO_CONTROL, reg_zv); + } + +} + +static int topic97_override(struct yenta_socket *socket) +{ + /* ToPIC97/100 support ZV */ + socket->socket.zoom_video = topic97_zoom_video; + return 0; +} #endif /* _LINUX_TOPIC_H */ diff -Nru a/drivers/pcmcia/yenta_socket.c b/drivers/pcmcia/yenta_socket.c --- a/drivers/pcmcia/yenta_socket.c Tue Sep 2 19:58:16 2003 +++ b/drivers/pcmcia/yenta_socket.c Tue Sep 2 19:58:16 2003 @@ -443,73 +443,6 @@ add_timer(&socket->poll_timer); } -/* - * Only probe "regular" interrupts, don't - * touch dangerous spots like the mouse irq, - * because there are mice that apparently - * get really confused if they get fondled - * too intimately. - * - * Default to 11, 10, 9, 7, 6, 5, 4, 3. - */ -static u32 isa_interrupts = 0x0ef8; - -static unsigned int yenta_probe_irq(struct yenta_socket *socket, u32 isa_irq_mask) -{ - int i; - unsigned long val; - u16 bridge_ctrl; - u32 mask; - - /* Set up ISA irq routing to probe the ISA irqs.. */ - bridge_ctrl = config_readw(socket, CB_BRIDGE_CONTROL); - if (!(bridge_ctrl & CB_BRIDGE_INTR)) { - bridge_ctrl |= CB_BRIDGE_INTR; - config_writew(socket, CB_BRIDGE_CONTROL, bridge_ctrl); - } - - /* - * Probe for usable interrupts using the force - * register to generate bogus card status events. - */ - cb_writel(socket, CB_SOCKET_EVENT, -1); - cb_writel(socket, CB_SOCKET_MASK, CB_CSTSMASK); - exca_writeb(socket, I365_CSCINT, 0); - val = probe_irq_on() & isa_irq_mask; - for (i = 1; i < 16; i++) { - if (!((val >> i) & 1)) - continue; - exca_writeb(socket, I365_CSCINT, I365_CSC_STSCHG | (i << 4)); - cb_writel(socket, CB_SOCKET_FORCE, CB_FCARDSTS); - udelay(100); - cb_writel(socket, CB_SOCKET_EVENT, -1); - } - cb_writel(socket, CB_SOCKET_MASK, 0); - exca_writeb(socket, I365_CSCINT, 0); - - mask = probe_irq_mask(val) & 0xffff; - - bridge_ctrl &= ~CB_BRIDGE_INTR; - config_writew(socket, CB_BRIDGE_CONTROL, bridge_ctrl); - - return mask; -} - -/* - * Set static data that doesn't need re-initializing.. - */ -static void yenta_get_socket_capabilities(struct yenta_socket *socket, u32 isa_irq_mask) -{ - socket->socket.features |= SS_CAP_PAGE_REGS | SS_CAP_PCCARD | SS_CAP_CARDBUS; - socket->socket.map_size = 0x1000; - socket->socket.pci_irq = socket->cb_irq; - socket->socket.irq_mask = yenta_probe_irq(socket, isa_irq_mask); - socket->socket.cb_dev = socket->dev; - - printk("Yenta IRQ list %04x, PCI irq%d\n", socket->socket.irq_mask, socket->cb_irq); -} - - static void yenta_clear_maps(struct yenta_socket *socket) { int i; @@ -528,42 +461,13 @@ } } -/* - * Initialize the standard cardbus registers - */ -static void yenta_config_init(struct yenta_socket *socket) +/* Called at resume and initialization events */ +static int yenta_sock_init(struct pcmcia_socket *sock) { + struct yenta_socket *socket = container_of(sock, struct yenta_socket, socket); u16 bridge; - struct pci_dev *dev = socket->dev; - - pci_set_power_state(socket->dev, 0); - - config_writel(socket, CB_LEGACY_MODE_BASE, 0); - config_writel(socket, PCI_BASE_ADDRESS_0, dev->resource[0].start); - config_writew(socket, PCI_COMMAND, - PCI_COMMAND_IO | - PCI_COMMAND_MEMORY | - PCI_COMMAND_MASTER | - PCI_COMMAND_WAIT); - - /* MAGIC NUMBERS! Fixme */ - config_writeb(socket, PCI_CACHE_LINE_SIZE, L1_CACHE_BYTES / 4); - config_writeb(socket, PCI_LATENCY_TIMER, 168); - config_writel(socket, PCI_PRIMARY_BUS, - (176 << 24) | /* sec. latency timer */ - (dev->subordinate->subordinate << 16) | /* subordinate bus */ - (dev->subordinate->secondary << 8) | /* secondary bus */ - dev->subordinate->primary); /* primary bus */ - /* - * Set up the bridging state: - * - enable write posting. - * - memory window 0 prefetchable, window 1 non-prefetchable - * - PCI interrupts enabled if a PCI interrupt exists.. - */ - bridge = config_readw(socket, CB_BRIDGE_CONTROL); - bridge &= ~(CB_BRIDGE_CRST | CB_BRIDGE_PREFETCH1 | CB_BRIDGE_INTR | CB_BRIDGE_ISAEN | CB_BRIDGE_VGAEN); - bridge |= CB_BRIDGE_PREFETCH0 | CB_BRIDGE_POSTEN; + bridge = config_readw(socket, CB_BRIDGE_CONTROL) & ~CB_BRIDGE_INTR; if (!socket->cb_irq) bridge |= CB_BRIDGE_INTR; config_writew(socket, CB_BRIDGE_CONTROL, bridge); @@ -573,41 +477,27 @@ /* Redo card voltage interrogation */ cb_writel(socket, CB_SOCKET_FORCE, CB_CVSTEST); -} -/* Called at resume and initialization events */ -static int yenta_init(struct pcmcia_socket *sock) -{ - struct yenta_socket *socket = container_of(sock, struct yenta_socket, socket); - yenta_config_init(socket); yenta_clear_maps(socket); - /* Re-enable interrupts */ + if (socket->type && socket->type->sock_init) + socket->type->sock_init(socket); + + /* Re-enable CSC interrupts */ cb_writel(socket, CB_SOCKET_MASK, CB_CDMASK); + return 0; } -static int yenta_suspend(struct pcmcia_socket *sock) +static int yenta_sock_suspend(struct pcmcia_socket *sock) { struct yenta_socket *socket = container_of(sock, struct yenta_socket, socket); yenta_set_socket(sock, &dead_socket); - /* Disable interrupts */ + /* Disable CSC interrupts */ cb_writel(socket, CB_SOCKET_MASK, 0x0); - /* - * This does not work currently. The controller - * loses too much information during D3 to come up - * cleanly. We should probably fix yenta_init() - * to update all the critical registers, notably - * the IO and MEM bridging region data.. That is - * something that pci_set_power_state() should - * probably know about bridges anyway. - * - pci_set_power_state(socket->dev, 3); - */ - return 0; } @@ -758,8 +648,8 @@ static struct pccard_operations yenta_socket_operations = { - .init = yenta_init, - .suspend = yenta_suspend, + .init = yenta_sock_init, + .suspend = yenta_sock_suspend, .get_status = yenta_get_status, .get_socket = yenta_get_socket, .set_socket = yenta_set_socket, @@ -770,52 +660,165 @@ #include "ti113x.h" #include "ricoh.h" +#include "topic.h" + +enum { + CARDBUS_TYPE_DEFAULT = -1, + CARDBUS_TYPE_TI, + CARDBUS_TYPE_TI113X, + CARDBUS_TYPE_TI12XX, + CARDBUS_TYPE_TI1250, + CARDBUS_TYPE_RICOH, + CARDBUS_TYPE_TOPIC97 +}; /* * Different cardbus controllers have slightly different * initialization sequences etc details. List them here.. */ -#define PD(x,y) PCI_VENDOR_ID_##x, PCI_DEVICE_ID_##x##_##y -struct cardbus_override_struct { - unsigned short vendor; - unsigned short device; - int (*override) (struct yenta_socket *socket); -} cardbus_override[] = { - { PD(TI,1031), &ti_override }, - - /* TBD: Check if these TI variants can use more - * advanced overrides instead */ - { PD(TI,1210), &ti_override }, - { PD(TI,1211), &ti_override }, - { PD(TI,1251A), &ti_override }, - { PD(TI,1251B), &ti_override }, - { PD(TI,1420), &ti_override }, - { PD(TI,1450), &ti_override }, - { PD(TI,4410), &ti_override }, - { PD(TI,4451), &ti_override }, - - { PD(TI,1130), &ti113x_override }, - { PD(TI,1131), &ti113x_override }, - - { PD(TI,1220), &ti12xx_override }, - { PD(TI,1221), &ti12xx_override }, - { PD(TI,1225), &ti12xx_override }, - { PD(TI,1520), &ti12xx_override }, - - { PD(TI,1250), &ti1250_override }, - { PD(TI,1410), &ti1250_override }, - - { PD(RICOH,RL5C465), &ricoh_override }, - { PD(RICOH,RL5C466), &ricoh_override }, - { PD(RICOH,RL5C475), &ricoh_override }, - { PD(RICOH,RL5C476), &ricoh_override }, - { PD(RICOH,RL5C478), &ricoh_override }, - - { }, /* all zeroes */ +struct cardbus_type cardbus_type[] = { + [CARDBUS_TYPE_TI] = { + .override = ti_override, + .save_state = ti_save_state, + .restore_state = ti_restore_state, + .sock_init = ti_init, + }, + [CARDBUS_TYPE_TI113X] = { + .override = ti113x_override, + .save_state = ti_save_state, + .restore_state = ti_restore_state, + .sock_init = ti_init, + }, + [CARDBUS_TYPE_TI12XX] = { + .override = ti12xx_override, + .save_state = ti_save_state, + .restore_state = ti_restore_state, + .sock_init = ti_init, + }, + [CARDBUS_TYPE_TI1250] = { + .override = ti1250_override, + .save_state = ti_save_state, + .restore_state = ti_restore_state, + .sock_init = ti_init, + }, + [CARDBUS_TYPE_RICOH] = { + .override = ricoh_override, + .save_state = ricoh_save_state, + .restore_state = ricoh_restore_state, + }, + [CARDBUS_TYPE_TOPIC97] = { + .override = topic97_override, + }, }; /* + * Only probe "regular" interrupts, don't + * touch dangerous spots like the mouse irq, + * because there are mice that apparently + * get really confused if they get fondled + * too intimately. + * + * Default to 11, 10, 9, 7, 6, 5, 4, 3. + */ +static u32 isa_interrupts = 0x0ef8; + +static unsigned int yenta_probe_irq(struct yenta_socket *socket, u32 isa_irq_mask) +{ + int i; + unsigned long val; + u16 bridge_ctrl; + u32 mask; + + /* Set up ISA irq routing to probe the ISA irqs.. */ + bridge_ctrl = config_readw(socket, CB_BRIDGE_CONTROL); + if (!(bridge_ctrl & CB_BRIDGE_INTR)) { + bridge_ctrl |= CB_BRIDGE_INTR; + config_writew(socket, CB_BRIDGE_CONTROL, bridge_ctrl); + } + + /* + * Probe for usable interrupts using the force + * register to generate bogus card status events. + */ + cb_writel(socket, CB_SOCKET_EVENT, -1); + cb_writel(socket, CB_SOCKET_MASK, CB_CSTSMASK); + exca_writeb(socket, I365_CSCINT, 0); + val = probe_irq_on() & isa_irq_mask; + for (i = 1; i < 16; i++) { + if (!((val >> i) & 1)) + continue; + exca_writeb(socket, I365_CSCINT, I365_CSC_STSCHG | (i << 4)); + cb_writel(socket, CB_SOCKET_FORCE, CB_FCARDSTS); + udelay(100); + cb_writel(socket, CB_SOCKET_EVENT, -1); + } + cb_writel(socket, CB_SOCKET_MASK, 0); + exca_writeb(socket, I365_CSCINT, 0); + + mask = probe_irq_mask(val) & 0xffff; + + bridge_ctrl &= ~CB_BRIDGE_INTR; + config_writew(socket, CB_BRIDGE_CONTROL, bridge_ctrl); + + return mask; +} + +/* + * Set static data that doesn't need re-initializing.. + */ +static void yenta_get_socket_capabilities(struct yenta_socket *socket, u32 isa_irq_mask) +{ + socket->socket.features |= SS_CAP_PAGE_REGS | SS_CAP_PCCARD | SS_CAP_CARDBUS; + socket->socket.map_size = 0x1000; + socket->socket.pci_irq = socket->cb_irq; + socket->socket.irq_mask = yenta_probe_irq(socket, isa_irq_mask); + socket->socket.cb_dev = socket->dev; + + printk(KERN_INFO "Yenta: ISA IRQ list %04x, PCI irq%d\n", + socket->socket.irq_mask, socket->cb_irq); +} + +/* + * Initialize the standard cardbus registers + */ +static void yenta_config_init(struct yenta_socket *socket) +{ + u16 bridge; + struct pci_dev *dev = socket->dev; + + pci_set_power_state(socket->dev, 0); + + config_writel(socket, CB_LEGACY_MODE_BASE, 0); + config_writel(socket, PCI_BASE_ADDRESS_0, dev->resource[0].start); + config_writew(socket, PCI_COMMAND, + PCI_COMMAND_IO | + PCI_COMMAND_MEMORY | + PCI_COMMAND_MASTER | + PCI_COMMAND_WAIT); + + /* MAGIC NUMBERS! Fixme */ + config_writeb(socket, PCI_CACHE_LINE_SIZE, L1_CACHE_BYTES / 4); + config_writeb(socket, PCI_LATENCY_TIMER, 168); + config_writel(socket, PCI_PRIMARY_BUS, + (176 << 24) | /* sec. latency timer */ + (dev->subordinate->subordinate << 16) | /* subordinate bus */ + (dev->subordinate->secondary << 8) | /* secondary bus */ + dev->subordinate->primary); /* primary bus */ + + /* + * Set up the bridging state: + * - enable write posting. + * - memory window 0 prefetchable, window 1 non-prefetchable + * - PCI interrupts enabled if a PCI interrupt exists.. + */ + bridge = config_readw(socket, CB_BRIDGE_CONTROL); + bridge &= ~(CB_BRIDGE_CRST | CB_BRIDGE_PREFETCH1 | CB_BRIDGE_INTR | CB_BRIDGE_ISAEN | CB_BRIDGE_VGAEN); + bridge |= CB_BRIDGE_PREFETCH0 | CB_BRIDGE_POSTEN | CB_BRIDGE_INTR; + config_writew(socket, CB_BRIDGE_CONTROL, bridge); +} + +/* * Initialize a cardbus controller. Make sure we have a usable * interrupt, and that we can map the cardbus area. Fill in the * socket information structure.. @@ -823,7 +826,6 @@ static int __devinit yenta_probe (struct pci_dev *dev, const struct pci_device_id *id) { struct yenta_socket *socket; - struct cardbus_override_struct *d; int ret; socket = kmalloc(sizeof(struct yenta_socket), GFP_KERNEL); @@ -887,14 +889,13 @@ socket->cb_irq = dev->irq; /* Do we have special options for the device? */ - d = cardbus_override; - while (d->override) { - if ((dev->vendor == d->vendor) && (dev->device == d->device)) { - ret = d->override(socket); - if (ret < 0) - goto unmap; - } - d++; + if (id->driver_data != CARDBUS_TYPE_DEFAULT && + id->driver_data < ARRAY_SIZE(cardbus_type)) { + socket->type = &cardbus_type[id->driver_data]; + + ret = socket->type->override(socket); + if (ret < 0) + goto unmap; } /* We must finish initialization here */ @@ -933,25 +934,97 @@ static int yenta_dev_suspend (struct pci_dev *dev, u32 state) { - return pcmcia_socket_dev_suspend(&dev->dev, state, SUSPEND_SAVE_STATE); + struct yenta_socket *socket = pci_get_drvdata(dev); + int ret; + + ret = pcmcia_socket_dev_suspend(&dev->dev, state, SUSPEND_SAVE_STATE); + + if (socket) { + if (socket->type && socket->type->save_state) + socket->type->save_state(socket); + + /* FIXME: pci_save_state needs to have a better interface */ + pci_save_state(dev, socket->saved_state); + pci_read_config_dword(dev, 16*4, &socket->saved_state[16]); + pci_read_config_dword(dev, 17*4, &socket->saved_state[17]); + pci_set_power_state(dev, 3); + } + + return ret; } static int yenta_dev_resume (struct pci_dev *dev) { + struct yenta_socket *socket = pci_get_drvdata(dev); + + if (socket) { + pci_set_power_state(dev, 0); + /* FIXME: pci_restore_state needs to have a better interface */ + pci_restore_state(dev, socket->saved_state); + pci_write_config_dword(dev, 16*4, socket->saved_state[16]); + pci_write_config_dword(dev, 17*4, socket->saved_state[17]); + + if (socket->type && socket->type->restore_state) + socket->type->restore_state(socket); + } + return pcmcia_socket_dev_resume(&dev->dev, RESUME_RESTORE_STATE); } -static struct pci_device_id yenta_table [] = { { - .class = PCI_CLASS_BRIDGE_CARDBUS << 8, - .class_mask = ~0, - - .vendor = PCI_ANY_ID, - .device = PCI_ANY_ID, - .subvendor = PCI_ANY_ID, - .subdevice = PCI_ANY_ID, -}, { /* all zeroes */ } +#define CB_ID(vend,dev,type) \ + { \ + .vendor = vend, \ + .device = dev, \ + .subvendor = PCI_ANY_ID, \ + .subdevice = PCI_ANY_ID, \ + .class = PCI_CLASS_BRIDGE_CARDBUS << 8, \ + .class_mask = ~0, \ + .driver_data = CARDBUS_TYPE_##type, \ + } + +static struct pci_device_id yenta_table [] = { + CB_ID(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_1031, TI), + + /* + * TBD: Check if these TI variants can use more + * advanced overrides instead. (I can't get the + * data sheets for these devices. --rmk) + */ + CB_ID(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_1210, TI), + CB_ID(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_1251B, TI), + + CB_ID(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_1130, TI113X), + CB_ID(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_1131, TI113X), + + CB_ID(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_1211, TI12XX), + CB_ID(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_1220, TI12XX), + CB_ID(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_1221, TI12XX), + CB_ID(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_1225, TI12XX), + CB_ID(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_1251A, TI12XX), + CB_ID(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_1420, TI12XX), + CB_ID(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_1450, TI12XX), + CB_ID(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_1520, TI12XX), + CB_ID(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_4410, TI12XX), +// CB_ID(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_4450, TI12XX), + CB_ID(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_4451, TI12XX), + + CB_ID(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_1250, TI1250), + CB_ID(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_1410, TI1250), + + CB_ID(PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_RL5C465, RICOH), + CB_ID(PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_RL5C466, RICOH), + CB_ID(PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_RL5C475, RICOH), + CB_ID(PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_RL5C476, RICOH), + CB_ID(PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_RL5C478, RICOH), + + CB_ID(PCI_VENDOR_ID_TOSHIBA, PCI_DEVICE_ID_TOSHIBA_TOPIC97, TOPIC97), + CB_ID(PCI_VENDOR_ID_TOSHIBA, PCI_DEVICE_ID_TOSHIBA_TOPIC100, TOPIC97), + + /* match any cardbus bridge */ + CB_ID(PCI_ANY_ID, PCI_ANY_ID, DEFAULT), + { /* all zeroes */ } }; MODULE_DEVICE_TABLE(pci, yenta_table); diff -Nru a/drivers/pcmcia/yenta_socket.h b/drivers/pcmcia/yenta_socket.h --- a/drivers/pcmcia/yenta_socket.h Tue Sep 2 19:58:14 2003 +++ b/drivers/pcmcia/yenta_socket.h Tue Sep 2 19:58:14 2003 @@ -95,6 +95,15 @@ */ #define CB_MEM_PAGE(map) (0x40 + (map)) +struct yenta_socket; + +struct cardbus_type { + int (*override)(struct yenta_socket *); + void (*save_state)(struct yenta_socket *); + void (*restore_state)(struct yenta_socket *); + int (*sock_init)(struct yenta_socket *); +}; + struct yenta_socket { struct pci_dev *dev; int cb_irq, io_irq; @@ -102,9 +111,13 @@ struct timer_list poll_timer; struct pcmcia_socket socket; + struct cardbus_type *type; /* A few words of private data for special stuff of overrides... */ unsigned int private[8]; + + /* PCI saved state */ + u32 saved_state[18]; }; diff -Nru a/drivers/s390/char/tape_char.c b/drivers/s390/char/tape_char.c --- a/drivers/s390/char/tape_char.c Tue Sep 2 19:58:18 2003 +++ b/drivers/s390/char/tape_char.c Tue Sep 2 19:58:18 2003 @@ -238,14 +238,14 @@ struct tape_device *device; int minor, rc; - if (major(filp->f_dentry->d_inode->i_rdev) != tapechar_major) + if (imajor(filp->f_dentry->d_inode) != tapechar_major) return -ENODEV; - minor = minor(filp->f_dentry->d_inode->i_rdev); + minor = iminor(filp->f_dentry->d_inode); device = tape_get_device(minor / TAPE_MINORS_PER_DEV); if (IS_ERR(device)) { return PTR_ERR(device); } - DBF_EVENT(6, "TCHAR:open: %x\n", minor(inode->i_rdev)); + DBF_EVENT(6, "TCHAR:open: %x\n", iminor(inode)); rc = tape_open(device); if (rc == 0) { rc = tape_assign(device); @@ -269,7 +269,7 @@ struct tape_device *device; device = (struct tape_device *) filp->private_data; - DBF_EVENT(6, "TCHAR:release: %x\n", minor(inode->i_rdev)); + DBF_EVENT(6, "TCHAR:release: %x\n", iminor(inode)); #if 0 // FIXME: this is broken. Either MTWEOF/MTWEOF/MTBSR is done // EVERYTIME the user switches from write to something different @@ -281,7 +281,7 @@ /* * If this is the rewinding tape minor then rewind. */ - if ((minor(inode->i_rdev) & 1) != 0) + if ((iminor(inode) & 1) != 0) tape_mtop(device, MTREW, 1); if (device->char_data.idal_buf != NULL) { idal_buffer_free(device->char_data.idal_buf); diff -Nru a/drivers/s390/char/tubio.h b/drivers/s390/char/tubio.h --- a/drivers/s390/char/tubio.h Tue Sep 2 19:58:16 2003 +++ b/drivers/s390/char/tubio.h Tue Sep 2 19:58:16 2003 @@ -377,7 +377,7 @@ */ extern inline tub_t *INODE2TUB(struct inode *ip) { - unsigned int minor = minor(ip->i_rdev); + unsigned int minor = iminor(ip); tub_t *tubp = NULL; if (minor == 0 && current->tty) { if (current->tty->driver == tty3270_driver) diff -Nru a/drivers/s390/net/cu3088.c b/drivers/s390/net/cu3088.c --- a/drivers/s390/net/cu3088.c Tue Sep 2 19:58:14 2003 +++ b/drivers/s390/net/cu3088.c Tue Sep 2 19:58:14 2003 @@ -64,7 +64,7 @@ group_write(struct device_driver *drv, const char *buf, size_t count) { const char *start, *end; - char bus_ids[2][BUS_ID_SIZE], *argv[2]; + char bus_ids[2][BUS_ID_SIZE+1], *argv[2]; int i; int ret; struct ccwgroup_driver *cdrv; @@ -79,7 +79,7 @@ if (!(end = strchr(start, delim[i]))) return count; - len = min_t(ptrdiff_t, BUS_ID_SIZE, end - start); + len = min_t(ptrdiff_t, BUS_ID_SIZE, end - start)+1; strlcpy (bus_ids[i], start, len); argv[i] = bus_ids[i]; start = end + 1; diff -Nru a/drivers/s390/net/qeth.c b/drivers/s390/net/qeth.c --- a/drivers/s390/net/qeth.c Tue Sep 2 19:58:20 2003 +++ b/drivers/s390/net/qeth.c Tue Sep 2 19:58:20 2003 @@ -9765,19 +9765,19 @@ }; static struct file_operations qeth_procfile_fops = { - ioctl:qeth_procfile_ioctl, - read:qeth_procfile_read, - open:qeth_procfile_open, - release:qeth_procfile_release, + .ioctl = qeth_procfile_ioctl, + .read = qeth_procfile_read, + .open = qeth_procfile_open, + .release = qeth_procfile_release, }; static struct proc_dir_entry *qeth_proc_file; static struct file_operations qeth_ipato_procfile_fops = { - read:qeth_procfile_read, /* same as above! */ - write:qeth_ipato_procfile_write, - open:qeth_ipato_procfile_open, - release:qeth_procfile_release /* same as above! */ + .read = qeth_procfile_read, /* same as above! */ + .write = qeth_ipato_procfile_write, + .open = qeth_ipato_procfile_open, + .release = qeth_procfile_release /* same as above! */ }; static struct proc_dir_entry *qeth_ipato_proc_file; diff -Nru a/drivers/sbus/char/bpp.c b/drivers/sbus/char/bpp.c --- a/drivers/sbus/char/bpp.c Tue Sep 2 19:58:12 2003 +++ b/drivers/sbus/char/bpp.c Tue Sep 2 19:58:12 2003 @@ -440,7 +440,7 @@ */ static int bpp_open(struct inode *inode, struct file *f) { - unsigned minor = minor(inode->i_rdev); + unsigned minor = iminor(inode); int ret; spin_lock(&bpp_open_lock); @@ -470,7 +470,7 @@ */ static int bpp_release(struct inode *inode, struct file *f) { - unsigned minor = minor(inode->i_rdev); + unsigned minor = iminor(inode); spin_lock(&bpp_open_lock); instances[minor].opened = 0; @@ -634,7 +634,7 @@ static ssize_t bpp_read(struct file *f, char *c, size_t cnt, loff_t * ppos) { long rc; - const unsigned minor = minor(f->f_dentry->d_inode->i_rdev); + unsigned minor = iminor(f->f_dentry->d_inode); if (minor >= BPP_NO) return -ENODEV; if (!instances[minor].present) return -ENODEV; @@ -787,7 +787,7 @@ static ssize_t bpp_write(struct file *f, const char *c, size_t cnt, loff_t * ppos) { long errno = 0; - const unsigned minor = minor(f->f_dentry->d_inode->i_rdev); + unsigned minor = iminor(f->f_dentry->d_inode); if (minor >= BPP_NO) return -ENODEV; if (!instances[minor].present) return -ENODEV; @@ -813,7 +813,7 @@ { int errno = 0; - unsigned minor = minor(inode->i_rdev); + unsigned minor = iminor(inode); if (minor >= BPP_NO) return -ENODEV; if (!instances[minor].present) return -ENODEV; diff -Nru a/drivers/sbus/char/cpwatchdog.c b/drivers/sbus/char/cpwatchdog.c --- a/drivers/sbus/char/cpwatchdog.c Tue Sep 2 19:58:19 2003 +++ b/drivers/sbus/char/cpwatchdog.c Tue Sep 2 19:58:19 2003 @@ -295,7 +295,7 @@ static int wd_open(struct inode *inode, struct file *f) { - switch(minor(inode->i_rdev)) + switch(iminor(inode)) { case WD0_MINOR: f->private_data = &wd_dev.watchdog[WD0_ID]; diff -Nru a/drivers/sbus/char/display7seg.c b/drivers/sbus/char/display7seg.c --- a/drivers/sbus/char/display7seg.c Tue Sep 2 19:58:17 2003 +++ b/drivers/sbus/char/display7seg.c Tue Sep 2 19:58:17 2003 @@ -91,7 +91,7 @@ static int d7s_open(struct inode *inode, struct file *f) { - if (D7S_MINOR != minor(inode->i_rdev)) + if (D7S_MINOR != iminor(inode)) return -ENODEV; atomic_inc(&d7s_users); return 0; @@ -121,7 +121,7 @@ __u8 regs = readb(d7s_regs); __u8 ireg = 0; - if (D7S_MINOR != minor(inode->i_rdev)) + if (D7S_MINOR != iminor(inode)) return -ENODEV; switch (cmd) { diff -Nru a/drivers/sbus/char/rtc.c b/drivers/sbus/char/rtc.c --- a/drivers/sbus/char/rtc.c Tue Sep 2 19:58:14 2003 +++ b/drivers/sbus/char/rtc.c Tue Sep 2 19:58:14 2003 @@ -28,7 +28,7 @@ static int rtc_busy = 0; /* Retrieve the current date and time from the real time clock. */ -void get_rtc_time(struct rtc_time *t) +static void get_rtc_time(struct rtc_time *t) { unsigned long regs = mstk48t02_regs; u8 tmp; diff -Nru a/drivers/sbus/char/vfc_dev.c b/drivers/sbus/char/vfc_dev.c --- a/drivers/sbus/char/vfc_dev.c Tue Sep 2 19:58:16 2003 +++ b/drivers/sbus/char/vfc_dev.c Tue Sep 2 19:58:16 2003 @@ -184,7 +184,7 @@ struct vfc_dev *dev; spin_lock(&vfc_dev_lock); - dev = vfc_get_dev_ptr(MINOR(inode->i_rdev)); + dev = vfc_get_dev_ptr(iminor(inode)); if (dev == NULL) { spin_unlock(&vfc_dev_lock); return -ENODEV; @@ -215,7 +215,7 @@ struct vfc_dev *dev; spin_lock(&vfc_dev_lock); - dev = vfc_get_dev_ptr(MINOR(inode->i_rdev)); + dev = vfc_get_dev_ptr(iminor(inode)); if (!dev || !dev->busy) { spin_unlock(&vfc_dev_lock); return -EINVAL; @@ -557,7 +557,7 @@ unsigned int tmp; struct vfc_dev *dev; - dev = vfc_get_dev_ptr(MINOR(inode->i_rdev)); + dev = vfc_get_dev_ptr(iminor(inode)); if(dev == NULL) return -ENODEV; @@ -602,7 +602,7 @@ VFC_IOCTL_DEBUG_PRINTK(("vfc%d: IOCTL(VFCRDINFO)\n", dev->instance)); break; default: - ret = vfc_debug(vfc_get_dev_ptr(MINOR(inode->i_rdev)), + ret = vfc_debug(vfc_get_dev_ptr(iminor(inode)), cmd, arg); break; }; @@ -616,7 +616,7 @@ unsigned int map_size, ret, map_offset; struct vfc_dev *dev; - dev = vfc_get_dev_ptr(MINOR(inode->i_rdev)); + dev = vfc_get_dev_ptr(iminor(inode)); if(dev == NULL) return -ENODEV; diff -Nru a/drivers/scsi/3w-xxxx.c b/drivers/scsi/3w-xxxx.c --- a/drivers/scsi/3w-xxxx.c Tue Sep 2 19:58:19 2003 +++ b/drivers/scsi/3w-xxxx.c Tue Sep 2 19:58:19 2003 @@ -628,7 +628,7 @@ unsigned long *cpu_addr; TW_New_Ioctl *tw_ioctl; TW_Passthru *passthru; - TW_Device_Extension *tw_dev = tw_device_extension_list[minor(inode->i_rdev)]; + TW_Device_Extension *tw_dev = tw_device_extension_list[iminor(inode)]; int retval = -EFAULT; dprintk(KERN_WARNING "3w-xxxx: tw_chrdev_ioctl()\n"); @@ -786,7 +786,7 @@ dprintk(KERN_WARNING "3w-xxxx: tw_ioctl_open()\n"); - minor_number = minor(inode->i_rdev); + minor_number = iminor(inode); if (minor_number >= tw_device_extension_count) return -ENODEV; diff -Nru a/drivers/scsi/3w-xxxx.h b/drivers/scsi/3w-xxxx.h --- a/drivers/scsi/3w-xxxx.h Tue Sep 2 19:58:14 2003 +++ b/drivers/scsi/3w-xxxx.h Tue Sep 2 19:58:14 2003 @@ -59,42 +59,37 @@ /* AEN strings */ static char *tw_aen_string[] = { - "INFO: AEN queue empty", // 0x000 - "INFO: Soft reset occurred", // 0x001 - "ERROR: Unit degraded: Unit #", // 0x002 - "ERROR: Controller error", // 0x003 - "ERROR: Rebuild failed: Unit #", // 0x004 - "INFO: Rebuild complete: Unit #", // 0x005 - "ERROR: Incomplete unit detected: Unit #", // 0x006 - "INFO: Initialization complete: Unit #", // 0x007 - "WARNING: Unclean shutdown detected: Unit #", // 0x008 - "WARNING: ATA port timeout: Port #", // 0x009 - "ERROR: Drive error: Port #", // 0x00A - "INFO: Rebuild started: Unit #", // 0x00B - "INFO: Initialization started: Unit #", // 0x00C - "ERROR: Logical unit deleted: Unit #", // 0x00D - NULL, // 0x00E unused - "WARNING: SMART threshold exceeded: Port #", // 0x00F - NULL, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, NULL, - NULL, NULL, // 0x010-0x020 unused - "WARNING: ATA UDMA downgrade: Port #", // 0x021 - "WARNING: ATA UDMA upgrade: Port #", // 0x022 - "WARNING: Sector repair occurred: Port #", // 0x023 - "ERROR: SBUF integrity check failure", // 0x024 - "ERROR: Lost cached write: Port #", // 0x025 - "ERROR: Drive ECC error detected: Port #", // 0x026 - "ERROR: DCB checksum error: Port #", // 0x027 - "ERROR: DCB unsupported version: Port #", // 0x028 - "INFO: Verify started: Unit #", // 0x029 - "ERROR: Verify failed: Port #", // 0x02A - "INFO: Verify complete: Unit #", // 0x02B - "WARNING: Overwrote bad sector during rebuild: Port #", //0x02C - "ERROR: Encountered bad sector during rebuild: Port #", //0x02D - "ERROR: Replacement drive is too small: Port #", //0x02E - "WARNING: Verify error: Unit not previously initialized: Unit #", //0x02F - "ERROR: Drive not supported: Port #" // 0x030 + [0x000] = "INFO: AEN queue empty", + [0x001] = "INFO: Soft reset occurred", + [0x002] = "ERROR: Unit degraded: Unit #", + [0x003] = "ERROR: Controller error", + [0x004] = "ERROR: Rebuild failed: Unit #", + [0x005] = "INFO: Rebuild complete: Unit #", + [0x006] = "ERROR: Incomplete unit detected: Unit #", + [0x007] = "INFO: Initialization complete: Unit #", + [0x008] = "WARNING: Unclean shutdown detected: Unit #", + [0x009] = "WARNING: ATA port timeout: Port #", + [0x00A] = "ERROR: Drive error: Port #", + [0x00B] = "INFO: Rebuild started: Unit #", + [0x00C] = "INFO: Initialization started: Unit #", + [0x00D] = "ERROR: Logical unit deleted: Unit #", + [0x00F] = "WARNING: SMART threshold exceeded: Port #", + [0x021] = "WARNING: ATA UDMA downgrade: Port #", + [0x021] = "WARNING: ATA UDMA upgrade: Port #", + [0x023] = "WARNING: Sector repair occurred: Port #", + [0x024] = "ERROR: SBUF integrity check failure", + [0x025] = "ERROR: Lost cached write: Port #", + [0x026] = "ERROR: Drive ECC error detected: Port #", + [0x027] = "ERROR: DCB checksum error: Port #", + [0x028] = "ERROR: DCB unsupported version: Port #", + [0x029] = "INFO: Verify started: Unit #", + [0x02A] = "ERROR: Verify failed: Port #", + [0x02B] = "INFO: Verify complete: Unit #", + [0x02C] = "WARNING: Overwrote bad sector during rebuild: Port #", + [0x02D] = "ERROR: Encountered bad sector during rebuild: Port #", + [0x02E] = "ERROR: Replacement drive is too small: Port #", + [0x02F] = "WARNING: Verify error: Unit not previously initialized: Unit #", + [0x030] = "ERROR: Drive not supported: Port #", }; /* diff -Nru a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig --- a/drivers/scsi/Kconfig Tue Sep 2 19:58:18 2003 +++ b/drivers/scsi/Kconfig Tue Sep 2 19:58:18 2003 @@ -355,7 +355,7 @@ # All the I2O code and drivers do not seem to be 64bit safe. config SCSI_DPT_I2O tristate "Adaptec I2O RAID support " - depends on !X86_64 && SCSI + depends on !X86_64 && SCSI && BROKEN help This driver supports all of Adaptec's I2O based RAID controllers as well as the DPT SmartRaid V cards. This is an Adaptec maintained @@ -398,7 +398,7 @@ # does not use pci dma and seems to be onboard only for old machines config SCSI_AM53C974 tristate "AM53/79C974 PCI SCSI support" - depends on X86 && PCI && SCSI + depends on X86 && PCI && SCSI && BROKEN ---help--- This is support for the AM53/79C974 SCSI host adapters. Please read for details. Also, the @@ -742,7 +742,7 @@ config SCSI_INITIO tristate "Initio 9100U(W) support" - depends on PCI && SCSI + depends on PCI && SCSI && BROKEN help This is support for the Initio 91XXU(W) SCSI host adapter. Please read the SCSI-HOWTO, available from @@ -1161,7 +1161,7 @@ config SCSI_MCA_53C9X tristate "NCR MCA 53C9x SCSI support" - depends on MCA && SCSI + depends on MCA && SCSI && BROKEN_ON_SMP help Some MicroChannel machines, notably the NCR 35xx line, use a SCSI controller based on the NCR 53C94. This driver will allow use of @@ -1189,7 +1189,7 @@ config SCSI_PCI2000 tristate "PCI2000 support" - depends on PCI && SCSI + depends on PCI && SCSI && BROKEN help This is support for the PCI2000I EIDE interface card which acts as a SCSI host adapter. Please read the SCSI-HOWTO, available from @@ -1202,7 +1202,7 @@ config SCSI_PCI2220I tristate "PCI2220i support" - depends on PCI && SCSI + depends on PCI && SCSI && BROKEN help This is support for the PCI2220i EIDE interface card which acts as a SCSI host adapter. Please read the SCSI-HOWTO, available from @@ -1314,7 +1314,7 @@ config SCSI_SEAGATE tristate "Seagate ST-02 and Future Domain TMC-8xx SCSI support" - depends on X86 && ISA && SCSI + depends on X86 && ISA && SCSI && BROKEN ---help--- These are 8-bit SCSI controllers; the ST-01 is also supported by this driver. It is explained in section 3.9 of the SCSI-HOWTO, @@ -1381,7 +1381,7 @@ config SCSI_DC390T tristate "Tekram DC390(T) and Am53/79C974 SCSI support" - depends on PCI && SCSI + depends on PCI && SCSI && BROKEN ---help--- This driver supports PCI SCSI host adapters based on the Am53C974A chip, e.g. Tekram DC390(T), DawiControl 2974 and some onboard diff -Nru a/drivers/scsi/a2091.h b/drivers/scsi/a2091.h --- a/drivers/scsi/a2091.h Tue Sep 2 19:58:13 2003 +++ b/drivers/scsi/a2091.h Tue Sep 2 19:58:13 2003 @@ -18,10 +18,6 @@ int wd33c93_abort(Scsi_Cmnd *); int wd33c93_reset(Scsi_Cmnd *, unsigned int); -#ifndef NULL -#define NULL 0 -#endif - #ifndef CMD_PER_LUN #define CMD_PER_LUN 2 #endif diff -Nru a/drivers/scsi/a3000.h b/drivers/scsi/a3000.h --- a/drivers/scsi/a3000.h Tue Sep 2 19:58:14 2003 +++ b/drivers/scsi/a3000.h Tue Sep 2 19:58:14 2003 @@ -18,10 +18,6 @@ int wd33c93_abort(Scsi_Cmnd *); int wd33c93_reset(Scsi_Cmnd *, unsigned int); -#ifndef NULL -#define NULL 0 -#endif - #ifndef CMD_PER_LUN #define CMD_PER_LUN 2 #endif diff -Nru a/drivers/scsi/aacraid/linit.c b/drivers/scsi/aacraid/linit.c --- a/drivers/scsi/aacraid/linit.c Tue Sep 2 19:58:15 2003 +++ b/drivers/scsi/aacraid/linit.c Tue Sep 2 19:58:15 2003 @@ -565,7 +565,7 @@ static int aac_cfg_open(struct inode * inode, struct file * file ) { - unsigned minor_number = minor(inode->i_rdev); + unsigned minor_number = iminor(inode); if(minor_number >= aac_count) return -ENODEV; return 0; @@ -601,7 +601,7 @@ static int aac_cfg_ioctl(struct inode * inode, struct file * file, unsigned int cmd, unsigned long arg ) { - struct aac_dev *dev = aac_devices[minor(inode->i_rdev)]; + struct aac_dev *dev = aac_devices[iminor(inode)]; return aac_do_ioctl(dev, cmd, (void *)arg); } diff -Nru a/drivers/scsi/advansys.c b/drivers/scsi/advansys.c --- a/drivers/scsi/advansys.c Tue Sep 2 19:58:14 2003 +++ b/drivers/scsi/advansys.c Tue Sep 2 19:58:14 2003 @@ -6199,7 +6199,9 @@ static Scsi_Host_Template driver_template = { .proc_name = "advansys", +#ifdef CONFIG_PROC_FS .proc_info = advansys_proc_info, +#endif .name = "advansys", .detect = advansys_detect, .release = advansys_release, diff -Nru a/drivers/scsi/aha1542.h b/drivers/scsi/aha1542.h --- a/drivers/scsi/aha1542.h Tue Sep 2 19:58:17 2003 +++ b/drivers/scsi/aha1542.h Tue Sep 2 19:58:17 2003 @@ -146,8 +146,4 @@ #define AHA1542_SCATTER 16 #define AHA1542_CMDLUN 1 -#ifndef NULL - #define NULL 0 -#endif - #endif diff -Nru a/drivers/scsi/aic7xxx/aic79xx_osm_pci.c b/drivers/scsi/aic7xxx/aic79xx_osm_pci.c --- a/drivers/scsi/aic7xxx/aic79xx_osm_pci.c Tue Sep 2 19:58:14 2003 +++ b/drivers/scsi/aic7xxx/aic79xx_osm_pci.c Tue Sep 2 19:58:14 2003 @@ -72,10 +72,10 @@ MODULE_DEVICE_TABLE(pci, ahd_linux_pci_id_table); struct pci_driver aic79xx_pci_driver = { - name: "aic79xx", - probe: ahd_linux_pci_dev_probe, - remove: ahd_linux_pci_dev_remove, - id_table: ahd_linux_pci_id_table + .name = "aic79xx", + .probe = ahd_linux_pci_dev_probe, + .remove = ahd_linux_pci_dev_remove, + .id_table = ahd_linux_pci_id_table }; static void diff -Nru a/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c b/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c --- a/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c Tue Sep 2 19:58:14 2003 +++ b/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c Tue Sep 2 19:58:14 2003 @@ -75,10 +75,10 @@ MODULE_DEVICE_TABLE(pci, ahc_linux_pci_id_table); struct pci_driver aic7xxx_pci_driver = { - name: "aic7xxx", - probe: ahc_linux_pci_dev_probe, - remove: ahc_linux_pci_dev_remove, - id_table: ahc_linux_pci_id_table + .name = "aic7xxx", + .probe = ahc_linux_pci_dev_probe, + .remove = ahc_linux_pci_dev_remove, + .id_table = ahc_linux_pci_id_table }; static void diff -Nru a/drivers/scsi/amiga7xx.h b/drivers/scsi/amiga7xx.h --- a/drivers/scsi/amiga7xx.h Tue Sep 2 19:58:19 2003 +++ b/drivers/scsi/amiga7xx.h Tue Sep 2 19:58:19 2003 @@ -10,10 +10,6 @@ int NCR53c7xx_reset(Scsi_Cmnd *, unsigned int); void NCR53c7x0_intr(int irq, void *dev_id, struct pt_regs * regs); -#ifndef NULL -#define NULL 0 -#endif - #ifndef CMD_PER_LUN #define CMD_PER_LUN 3 #endif diff -Nru a/drivers/scsi/atp870u.h b/drivers/scsi/atp870u.h --- a/drivers/scsi/atp870u.h Tue Sep 2 19:58:13 2003 +++ b/drivers/scsi/atp870u.h Tue Sep 2 19:58:13 2003 @@ -28,10 +28,6 @@ #define ATP870U_SCATTER 128 #define ATP870U_CMDLUN 1 -#ifndef NULL -#define NULL 0 -#endif - extern const char *atp870u_info(struct Scsi_Host *); #endif diff -Nru a/drivers/scsi/bvme6000.h b/drivers/scsi/bvme6000.h --- a/drivers/scsi/bvme6000.h Tue Sep 2 19:58:18 2003 +++ b/drivers/scsi/bvme6000.h Tue Sep 2 19:58:18 2003 @@ -11,10 +11,6 @@ int NCR53c7xx_reset(Scsi_Cmnd *, unsigned int); void NCR53c7x0_intr(int irq, void *dev_id, struct pt_regs * regs); -#ifndef NULL -#define NULL 0 -#endif - #ifndef CMD_PER_LUN #define CMD_PER_LUN 3 #endif diff -Nru a/drivers/scsi/dpt_i2o.c b/drivers/scsi/dpt_i2o.c --- a/drivers/scsi/dpt_i2o.c Tue Sep 2 19:58:18 2003 +++ b/drivers/scsi/dpt_i2o.c Tue Sep 2 19:58:18 2003 @@ -1551,7 +1551,7 @@ //TODO check for root access // - minor = minor(inode->i_rdev); + minor = iminor(inode); if (minor >= hba_count) { return -ENXIO; } @@ -1582,7 +1582,7 @@ int minor; adpt_hba* pHba; - minor = minor(inode->i_rdev); + minor = iminor(inode); if (minor >= hba_count) { return -ENXIO; } @@ -1878,7 +1878,7 @@ adpt_hba* pHba; ulong flags; - minor = minor(inode->i_rdev); + minor = iminor(inode); if (minor >= DPTI_MAX_HBA){ return -ENXIO; } diff -Nru a/drivers/scsi/gdth.h b/drivers/scsi/gdth.h --- a/drivers/scsi/gdth.h Tue Sep 2 19:58:15 2003 +++ b/drivers/scsi/gdth.h Tue Sep 2 19:58:15 2003 @@ -16,9 +16,6 @@ #include #include -#ifndef NULL -#define NULL 0 -#endif #ifndef TRUE #define TRUE 1 #endif diff -Nru a/drivers/scsi/gvp11.h b/drivers/scsi/gvp11.h --- a/drivers/scsi/gvp11.h Tue Sep 2 19:58:18 2003 +++ b/drivers/scsi/gvp11.h Tue Sep 2 19:58:18 2003 @@ -18,10 +18,6 @@ int wd33c93_abort(Scsi_Cmnd *); int wd33c93_reset(Scsi_Cmnd *, unsigned int); -#ifndef NULL -#define NULL 0 -#endif - #ifndef CMD_PER_LUN #define CMD_PER_LUN 2 #endif diff -Nru a/drivers/scsi/hosts.c b/drivers/scsi/hosts.c --- a/drivers/scsi/hosts.c Tue Sep 2 19:58:13 2003 +++ b/drivers/scsi/hosts.c Tue Sep 2 19:58:13 2003 @@ -158,7 +158,13 @@ scsi_proc_hostdir_rm(shost->hostt); scsi_destroy_command_freelist(shost); - put_device(parent); + /* + * Some drivers (eg aha1542) do scsi_register()/scsi_unregister() + * during probing without performing a scsi_set_device() in between. + * In this case dev->parent is NULL. + */ + if (parent) + put_device(parent); kfree(shost); } diff -Nru a/drivers/scsi/hosts.h b/drivers/scsi/hosts.h --- a/drivers/scsi/hosts.h Tue Sep 2 19:58:14 2003 +++ b/drivers/scsi/hosts.h Tue Sep 2 19:58:14 2003 @@ -25,7 +25,6 @@ #define _HOSTS_H #include -#include #include diff -Nru a/drivers/scsi/i91uscsi.h b/drivers/scsi/i91uscsi.h --- a/drivers/scsi/i91uscsi.h Tue Sep 2 19:58:16 2003 +++ b/drivers/scsi/i91uscsi.h Tue Sep 2 19:58:16 2003 @@ -67,9 +67,6 @@ #define UDWORD unsigned long #define U32 u32 -#ifndef NULL -#define NULL 0 /* zero */ -#endif #ifndef FAILURE #define FAILURE (-1) #endif diff -Nru a/drivers/scsi/imm.h b/drivers/scsi/imm.h --- a/drivers/scsi/imm.h Tue Sep 2 19:58:12 2003 +++ b/drivers/scsi/imm.h Tue Sep 2 19:58:12 2003 @@ -96,17 +96,18 @@ static char *IMM_MODE_STRING[] = { - "Autodetect", - "SPP", - "PS/2", - "EPP 8 bit", - "EPP 16 bit", + [IMM_AUTODETECT] = "Autodetect", + [IMM_NIBBLE] = "SPP", + [IMM_PS2] = "PS/2", + [IMM_EPP_8] = "EPP 8 bit", + [IMM_EPP_16] = "EPP 16 bit", #ifdef CONFIG_SCSI_IZIP_EPP16 - "EPP 16 bit", + [IMM_EPP_16] = "EPP 16 bit", #else - "EPP 32 bit", + [IMM_EPP_32] = "EPP 32 bit", #endif - "Unknown"}; + [IMM_UNKNOWN] = "Unknown", +}; /* This is a global option */ int imm_sg = SG_ALL; /* enable/disable scatter-gather. */ diff -Nru a/drivers/scsi/ini9100u.h b/drivers/scsi/ini9100u.h --- a/drivers/scsi/ini9100u.h Tue Sep 2 19:58:16 2003 +++ b/drivers/scsi/ini9100u.h Tue Sep 2 19:58:16 2003 @@ -99,9 +99,6 @@ #define UDWORD unsigned long #define U32 u32 -#ifndef NULL -#define NULL 0 /* zero */ -#endif #ifndef TRUE #define TRUE (1) /* boolean true */ #endif diff -Nru a/drivers/scsi/inia100.h b/drivers/scsi/inia100.h --- a/drivers/scsi/inia100.h Tue Sep 2 19:58:12 2003 +++ b/drivers/scsi/inia100.h Tue Sep 2 19:58:12 2003 @@ -88,9 +88,6 @@ #define UDWORD unsigned long #define U32 u32 -#ifndef NULL -#define NULL 0 /* zero */ -#endif #ifndef FAILURE #define FAILURE (-1) #endif diff -Nru a/drivers/scsi/mac_scsi.h b/drivers/scsi/mac_scsi.h --- a/drivers/scsi/mac_scsi.h Tue Sep 2 19:58:16 2003 +++ b/drivers/scsi/mac_scsi.h Tue Sep 2 19:58:16 2003 @@ -32,9 +32,6 @@ #define MACSCSI_PUBLIC_RELEASE 2 #ifndef ASM -#ifndef NULL -#define NULL 0 -#endif #ifndef CMD_PER_LUN #define CMD_PER_LUN 2 diff -Nru a/drivers/scsi/megaraid.c b/drivers/scsi/megaraid.c --- a/drivers/scsi/megaraid.c Tue Sep 2 19:58:12 2003 +++ b/drivers/scsi/megaraid.c Tue Sep 2 19:58:12 2003 @@ -36,6 +36,7 @@ #include #include #include +#include #include #include #include diff -Nru a/drivers/scsi/mvme147.h b/drivers/scsi/mvme147.h --- a/drivers/scsi/mvme147.h Tue Sep 2 19:58:13 2003 +++ b/drivers/scsi/mvme147.h Tue Sep 2 19:58:13 2003 @@ -17,10 +17,6 @@ int wd33c93_abort(Scsi_Cmnd *); int wd33c93_reset(Scsi_Cmnd *, unsigned int); -#ifndef NULL -#define NULL 0 -#endif - #ifndef CMD_PER_LUN #define CMD_PER_LUN 2 #endif diff -Nru a/drivers/scsi/mvme16x.h b/drivers/scsi/mvme16x.h --- a/drivers/scsi/mvme16x.h Tue Sep 2 19:58:15 2003 +++ b/drivers/scsi/mvme16x.h Tue Sep 2 19:58:15 2003 @@ -11,10 +11,6 @@ int NCR53c7xx_reset(Scsi_Cmnd *, unsigned int); void NCR53c7x0_intr(int irq, void *dev_id, struct pt_regs * regs); -#ifndef NULL -#define NULL 0 -#endif - #ifndef CMD_PER_LUN #define CMD_PER_LUN 3 #endif diff -Nru a/drivers/scsi/nsp32.c b/drivers/scsi/nsp32.c --- a/drivers/scsi/nsp32.c Tue Sep 2 19:58:15 2003 +++ b/drivers/scsi/nsp32.c Tue Sep 2 19:58:15 2003 @@ -2809,13 +2809,13 @@ for (j = 0; j < NUMBER(data->lunt[0]); j++) { int offset = i * NUMBER(data->lunt[0]) + j; nsp32_lunt tmp = { - SCpnt: NULL, - save_datp: 0, - msgin03: FALSE, - sg_num: 0, - cur_entry: 0, - sglun: &(data->sg_list[offset]), - sglun_paddr: data->sg_paddr + (offset * sizeof(nsp32_sglun)), + .SCpnt = NULL, + .save_datp = 0, + .msgin03 = FALSE, + .sg_num = 0, + .cur_entry = 0, + .sglun = &(data->sg_list[offset]), + .sglun_paddr = data->sg_paddr + (offset * sizeof(nsp32_sglun)), }; data->lunt[i][j] = tmp; diff -Nru a/drivers/scsi/osst.c b/drivers/scsi/osst.c --- a/drivers/scsi/osst.c Tue Sep 2 19:58:15 2003 +++ b/drivers/scsi/osst.c Tue Sep 2 19:58:15 2003 @@ -132,9 +132,9 @@ #define OSST_TIMEOUT (200 * HZ) #define OSST_LONG_TIMEOUT (1800 * HZ) -#define TAPE_NR(x) (minor(x) & ~(-1 << ST_MODE_SHIFT)) -#define TAPE_MODE(x) ((minor(x) & ST_MODE_MASK) >> ST_MODE_SHIFT) -#define TAPE_REWIND(x) ((minor(x) & 0x80) == 0) +#define TAPE_NR(x) (iminor(x) & ~(-1 << ST_MODE_SHIFT)) +#define TAPE_MODE(x) ((iminor(x) & ST_MODE_MASK) >> ST_MODE_SHIFT) +#define TAPE_REWIND(x) ((iminor(x) & 0x80) == 0) #define TAPE_IS_RAW(x) (TAPE_MODE(x) & (ST_NBR_MODES >> 1)) /* Internal ioctl to set both density (uppermost 8 bits) and blocksize (lower @@ -4215,8 +4215,8 @@ ST_mode * STm; ST_partstat * STps; char * name; - int dev = TAPE_NR(inode->i_rdev); - int mode = TAPE_MODE(inode->i_rdev); + int dev = TAPE_NR(inode); + int mode = TAPE_MODE(inode); write_lock(&os_scsi_tapes_lock); if (dev >= osst_max_dev || os_scsi_tapes == NULL || @@ -4244,7 +4244,7 @@ filp->private_data = STp; STp->in_use = 1; write_unlock(&os_scsi_tapes_lock); - STp->rew_at_close = TAPE_REWIND(inode->i_rdev); + STp->rew_at_close = TAPE_REWIND(inode); if( !scsi_block_when_processing_errors(STp->device) ) { return -ENXIO; @@ -4264,7 +4264,7 @@ flags = filp->f_flags; STp->write_prot = ((flags & O_ACCMODE) == O_RDONLY); - STp->raw = TAPE_IS_RAW(inode->i_rdev); + STp->raw = TAPE_IS_RAW(inode); if (STp->raw) STp->header_ok = 0; diff -Nru a/drivers/scsi/pas16.h b/drivers/scsi/pas16.h --- a/drivers/scsi/pas16.h Tue Sep 2 19:58:17 2003 +++ b/drivers/scsi/pas16.h Tue Sep 2 19:58:17 2003 @@ -123,10 +123,6 @@ static int pas16_host_reset(Scsi_Cmnd *); static int pas16_device_reset(Scsi_Cmnd *); -#ifndef NULL -#define NULL 0 -#endif - #ifndef CMD_PER_LUN #define CMD_PER_LUN 2 #endif diff -Nru a/drivers/scsi/pci2000.h b/drivers/scsi/pci2000.h --- a/drivers/scsi/pci2000.h Tue Sep 2 19:58:19 2003 +++ b/drivers/scsi/pci2000.h Tue Sep 2 19:58:19 2003 @@ -197,8 +197,4 @@ struct block_device *bdev, sector_t capacity, int geom[]); -#ifndef NULL - #define NULL 0 -#endif - #endif diff -Nru a/drivers/scsi/pci2220i.h b/drivers/scsi/pci2220i.h --- a/drivers/scsi/pci2220i.h Tue Sep 2 19:58:15 2003 +++ b/drivers/scsi/pci2220i.h Tue Sep 2 19:58:15 2003 @@ -36,8 +36,4 @@ int Pci2220i_BiosParam (struct scsi_device *sdev, struct block_device *dev, sector_t capacity, int geom[]); - -#ifndef NULL - #define NULL 0 -#endif #endif diff -Nru a/drivers/scsi/psi240i.h b/drivers/scsi/psi240i.h --- a/drivers/scsi/psi240i.h Tue Sep 2 19:58:18 2003 +++ b/drivers/scsi/psi240i.h Tue Sep 2 19:58:18 2003 @@ -316,8 +316,4 @@ int Psi240i_Reset (Scsi_Cmnd *SCpnt, unsigned int flags); int Psi240i_BiosParam (struct scsi_device *sdev, struct block_device *bdev, sector_t capacity, int geom[]); - -#ifndef NULL - #define NULL 0 -#endif #endif diff -Nru a/drivers/scsi/qlogicfc.h b/drivers/scsi/qlogicfc.h --- a/drivers/scsi/qlogicfc.h Tue Sep 2 19:58:15 2003 +++ b/drivers/scsi/qlogicfc.h Tue Sep 2 19:58:15 2003 @@ -77,9 +77,4 @@ int isp2x00_reset(Scsi_Cmnd *, unsigned int); int isp2x00_biosparam(struct scsi_device *, struct block_device *, sector_t, int[]); - -#ifndef NULL -#define NULL (0) -#endif - #endif /* _QLOGICFC_H */ diff -Nru a/drivers/scsi/qlogicisp.h b/drivers/scsi/qlogicisp.h --- a/drivers/scsi/qlogicisp.h Tue Sep 2 19:58:12 2003 +++ b/drivers/scsi/qlogicisp.h Tue Sep 2 19:58:12 2003 @@ -66,8 +66,4 @@ int isp1020_reset(Scsi_Cmnd *, unsigned int); int isp1020_biosparam(struct scsi_device *, struct block_device *, sector_t, int[]); - -#ifndef NULL -#define NULL (0) -#endif #endif /* _QLOGICISP_H */ diff -Nru a/drivers/scsi/sg.c b/drivers/scsi/sg.c --- a/drivers/scsi/sg.c Tue Sep 2 19:58:15 2003 +++ b/drivers/scsi/sg.c Tue Sep 2 19:58:15 2003 @@ -238,7 +238,7 @@ static int sg_open(struct inode *inode, struct file *filp) { - int dev = minor(inode->i_rdev); + int dev = iminor(inode); int flags = filp->f_flags; Sg_device *sdp; Sg_fd *sfp; diff -Nru a/drivers/scsi/sgiwd93.h b/drivers/scsi/sgiwd93.h --- a/drivers/scsi/sgiwd93.h Tue Sep 2 19:58:15 2003 +++ b/drivers/scsi/sgiwd93.h Tue Sep 2 19:58:15 2003 @@ -6,10 +6,6 @@ #ifndef _SGIWD93_H #define _SGIWD93_H -#ifndef NULL -#define NULL 0 -#endif - #ifndef CMD_PER_LUN #define CMD_PER_LUN 8 #endif diff -Nru a/drivers/scsi/sr.c b/drivers/scsi/sr.c --- a/drivers/scsi/sr.c Tue Sep 2 19:58:14 2003 +++ b/drivers/scsi/sr.c Tue Sep 2 19:58:14 2003 @@ -695,6 +695,10 @@ unsigned char *buffer; int rc, n; struct scsi_mode_data data; + struct scsi_request *SRpnt; + unsigned char cmd[MAX_COMMAND_SIZE]; + unsigned int the_result; + int retries; static char *loadmech[] = { @@ -708,11 +712,46 @@ "" }; + /* allocate a request for the TEST_UNIT_READY */ + SRpnt = scsi_allocate_request(cd->device); + if (!SRpnt) { + printk(KERN_WARNING "(get_capabilities:) Request allocation " + "failure.\n"); + return; + } + + /* allocate transfer buffer */ buffer = kmalloc(512, GFP_KERNEL | GFP_DMA); if (!buffer) { printk(KERN_ERR "sr: out of memory.\n"); + scsi_release_request(SRpnt); return; } + + /* issue TEST_UNIT_READY until the initial startup UNIT_ATTENTION + * conditions are gone, or a timeout happens + */ + retries = 0; + do { + memset((void *)cmd, 0, MAX_COMMAND_SIZE); + cmd[0] = TEST_UNIT_READY; + + SRpnt->sr_cmd_len = 0; + SRpnt->sr_sense_buffer[0] = 0; + SRpnt->sr_sense_buffer[2] = 0; + SRpnt->sr_data_direction = DMA_NONE; + + scsi_wait_req (SRpnt, (void *) cmd, buffer, + 0, SR_TIMEOUT, MAX_RETRIES); + + the_result = SRpnt->sr_result; + retries++; + } while (retries < 5 && + (!scsi_status_is_good(the_result) || + ((driver_byte(the_result) & DRIVER_SENSE) && + SRpnt->sr_sense_buffer[2] == UNIT_ATTENTION))); + + /* ask for mode page 0x2a */ rc = scsi_mode_sense(cd->device, 0, 0x2a, buffer, 128, SR_TIMEOUT, 3, &data); @@ -722,6 +761,7 @@ cd->cdi.mask |= (CDC_CD_R | CDC_CD_RW | CDC_DVD_R | CDC_DVD | CDC_DVD_RAM | CDC_SELECT_DISC | CDC_SELECT_SPEED); + scsi_release_request(SRpnt); kfree(buffer); printk("%s: scsi-1 drive\n", cd->cdi.name); return; @@ -775,6 +815,7 @@ /*else I don't think it can close its tray cd->cdi.mask |= CDC_CLOSE_TRAY; */ + scsi_release_request(SRpnt); kfree(buffer); } diff -Nru a/drivers/scsi/st.c b/drivers/scsi/st.c --- a/drivers/scsi/st.c Tue Sep 2 19:58:17 2003 +++ b/drivers/scsi/st.c Tue Sep 2 19:58:17 2003 @@ -140,8 +140,8 @@ #define ST_TIMEOUT (900 * HZ) #define ST_LONG_TIMEOUT (14000 * HZ) -#define TAPE_NR(x) (minor(x) & ~(-1 << ST_MODE_SHIFT)) -#define TAPE_MODE(x) ((minor(x) & ST_MODE_MASK) >> ST_MODE_SHIFT) +#define TAPE_NR(x) (iminor(x) & ~(-1 << ST_MODE_SHIFT)) +#define TAPE_MODE(x) ((iminor(x) & ST_MODE_MASK) >> ST_MODE_SHIFT) /* Internal ioctl to set both density (uppermost 8 bits) and blocksize (lower 24 bits) */ @@ -786,7 +786,7 @@ ST_partstat *STps; char *name = tape_name(STp); struct inode *inode = filp->f_dentry->d_inode; - int mode = TAPE_MODE(inode->i_rdev); + int mode = TAPE_MODE(inode); STp->ready = ST_READY; @@ -980,7 +980,7 @@ int i, retval = (-EIO); Scsi_Tape *STp; ST_partstat *STps; - int dev = TAPE_NR(inode->i_rdev); + int dev = TAPE_NR(inode); char *name; write_lock(&st_dev_arr_lock); @@ -1004,7 +1004,7 @@ } STp->in_use = 1; write_unlock(&st_dev_arr_lock); - STp->rew_at_close = STp->autorew_dev = (minor(inode->i_rdev) & 0x80) == 0; + STp->rew_at_close = STp->autorew_dev = (iminor(inode) & 0x80) == 0; if (!scsi_block_when_processing_errors(STp->device)) { diff -Nru a/drivers/scsi/sun3_scsi.h b/drivers/scsi/sun3_scsi.h --- a/drivers/scsi/sun3_scsi.h Tue Sep 2 19:58:13 2003 +++ b/drivers/scsi/sun3_scsi.h Tue Sep 2 19:58:13 2003 @@ -36,11 +36,6 @@ #ifndef SUN3_NCR5380_H #define SUN3_NCR5380_H -#ifndef NULL -#define NULL 0 -#endif - - #define SUN3SCSI_PUBLIC_RELEASE 1 /* diff -Nru a/drivers/scsi/t128.h b/drivers/scsi/t128.h --- a/drivers/scsi/t128.h Tue Sep 2 19:58:14 2003 +++ b/drivers/scsi/t128.h Tue Sep 2 19:58:14 2003 @@ -100,10 +100,6 @@ static int t128_bus_reset(Scsi_Cmnd *); static int t128_device_reset(Scsi_Cmnd *); -#ifndef NULL -#define NULL 0 -#endif - #ifndef CMD_PER_LUN #define CMD_PER_LUN 2 #endif diff -Nru a/drivers/serial/Kconfig b/drivers/serial/Kconfig --- a/drivers/serial/Kconfig Tue Sep 2 19:58:19 2003 +++ b/drivers/serial/Kconfig Tue Sep 2 19:58:19 2003 @@ -430,12 +430,12 @@ config SERIAL_CORE tristate - default m if SERIAL_AMBA!=y && SERIAL_CLPS711X!=y && SERIAL_21285!=y && !SERIAL_SA1100 && !SERIAL_ANAKIN && !SERIAL_UART00 && SERIAL_8250!=y && SERIAL_MUX!=y && !SERIAL_ROCKETPORT && !SERIAL_SUNCORE && !V850E_UART && (SERIAL_AMBA=m || SERIAL_CLPS711X=m || SERIAL_21285=m || SERIAL_8250=m || SERIAL_MUX=m || SERIAL98=m) - default y if SERIAL_AMBA=y || SERIAL_CLPS711X=y || SERIAL_21285=y || SERIAL_SA1100 || SERIAL_ANAKIN || SERIAL_UART00 || SERIAL_8250=y || SERIAL_MUX=y || SERIAL_ROCKETPORT || SERIAL_SUNCORE || V850E_UART || SERIAL98=y + default m if SERIAL_AMBA!=y && SERIAL_CLPS711X!=y && SERIAL_21285!=y && !SERIAL_SA1100 && !SERIAL_ANAKIN && !SERIAL_UART00 && SERIAL_8250!=y && SERIAL_MUX!=y && !SERIAL_ROCKETPORT && !SERIAL_SUNCORE && !V850E_UART && SERIAL_PMACZILOG!=y && (SERIAL_AMBA=m || SERIAL_CLPS711X=m || SERIAL_21285=m || SERIAL_8250=m || SERIAL_MUX=m || SERIAL98=m || SERIAL_PMACZILOG=m) + default y if SERIAL_AMBA=y || SERIAL_CLPS711X=y || SERIAL_21285=y || SERIAL_SA1100 || SERIAL_ANAKIN || SERIAL_UART00 || SERIAL_8250=y || SERIAL_MUX=y || SERIAL_ROCKETPORT || SERIAL_SUNCORE || V850E_UART || SERIAL98=y || SERIAL_PMACZILOG=y config SERIAL_CORE_CONSOLE bool - depends on SERIAL_AMBA_CONSOLE || SERIAL_CLPS711X_CONSOLE || SERIAL_21285_CONSOLE || SERIAL_SA1100_CONSOLE || SERIAL_ANAKIN_CONSOLE || SERIAL_UART00_CONSOLE || SERIAL_8250_CONSOLE || SERIAL_MUX_CONSOLE || SERIAL_SUNZILOG_CONSOLE || SERIAL_SUNSU_CONSOLE || SERIAL_SUNSAB_CONSOLE || V850E_UART_CONSOLE || SERIAL98_CONSOLE + depends on SERIAL_AMBA_CONSOLE || SERIAL_CLPS711X_CONSOLE || SERIAL_21285_CONSOLE || SERIAL_SA1100_CONSOLE || SERIAL_ANAKIN_CONSOLE || SERIAL_UART00_CONSOLE || SERIAL_8250_CONSOLE || SERIAL_MUX_CONSOLE || SERIAL_SUNZILOG_CONSOLE || SERIAL_SUNSU_CONSOLE || SERIAL_SUNSAB_CONSOLE || V850E_UART_CONSOLE || SERIAL98_CONSOLE || SERIAL_PMACZILOG_CONSOLE default y config SERIAL_68328 @@ -472,6 +472,22 @@ bool depends on SERIAL_68360_SMC || SERIAL_68360_SCC default y + +config SERIAL_PMACZILOG + tristate "PowerMac z85c30 ESCC support" + depends on PPC_OF + help + This driver supports the Zilog z85C30 serial ports found on + PowerMac machines. + Say Y or M if you want to be able to these serial ports. + +config SERIAL_PMACZILOG_CONSOLE + bool "Console on PowerMac z85c30 serial port" + depends on SERIAL_PMACZILOG=y + help + If you would like to be able to use the z85c30 serial port + on your PowerMac as the console, you can do so by answering + Y to this option. endmenu diff -Nru a/drivers/serial/Makefile b/drivers/serial/Makefile --- a/drivers/serial/Makefile Tue Sep 2 19:58:15 2003 +++ b/drivers/serial/Makefile Tue Sep 2 19:58:15 2003 @@ -31,3 +31,4 @@ obj-$(CONFIG_SERIAL_COLDFIRE) += mcfserial.o obj-$(CONFIG_V850E_UART) += v850e_uart.o obj-$(CONFIG_SERIAL98) += serial98.o +obj-$(CONFIG_SERIAL_PMACZILOG) += pmac_zilog.o diff -Nru a/drivers/serial/pmac_zilog.c b/drivers/serial/pmac_zilog.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/drivers/serial/pmac_zilog.c Tue Sep 2 19:58:20 2003 @@ -0,0 +1,1626 @@ +/* + * linux/drivers/serial/pmac_zilog.c + * + * Driver for PowerMac Z85c30 based ESCC cell found in the + * "macio" ASICs of various PowerMac models + * + * Copyright (C) 2003 Ben. Herrenschmidt (benh@kernel.crashing.org) + * + * Derived from drivers/macintosh/macserial.c by Paul Mackerras + * and drivers/serial/sunzilog.c by David S. Miller + * + * Hrm... actually, I ripped most of sunzilog (Thanks David !) and + * adapted special tweaks needed for us. I don't think it's worth + * merging back those though. The DMA code still has to get in + * and once done, I expect that driver to remain fairly stable in + * the long term, unless we change the driver model again... + * + * 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. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * TODO: - Add DMA support + * - Defer port shutdown to a few seconds after close + * - maybe put something right into up->clk_divisor + */ + +#undef DEBUG + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "pmac_zilog.h" + + +/* Not yet implemented */ +#undef HAS_DBDMA + +static char version[] __initdata = "pmac_zilog.c 0.5a (Benjamin Herrenschmidt )"; +MODULE_AUTHOR("Benjamin Herrenschmidt "); +MODULE_DESCRIPTION("Driver for the PowerMac serial ports."); +MODULE_LICENSE("GPL"); + +#define PWRDBG(fmt, arg...) printk(KERN_DEBUG fmt , ## arg) + + +/* + * For the sake of early serial console, we can do a pre-probe + * (optional) of the ports at rather early boot time. + */ +static struct uart_pmac_port pmz_ports[MAX_ZS_PORTS]; +static int pmz_ports_count; + + +/* + * Load all registers to reprogram the port + * This function must only be called when the TX is not busy. The UART + * port lock must be held and local interrupts disabled. + */ +static void pmz_load_zsregs(struct uart_pmac_port *up, u8 *regs) +{ + int i; + + /* Let pending transmits finish. */ + for (i = 0; i < 1000; i++) { + unsigned char stat = read_zsreg(up, R1); + if (stat & ALL_SNT) + break; + udelay(100); + } + + ZS_CLEARERR(up); + zssync(up); + ZS_CLEARFIFO(up); + zssync(up); + ZS_CLEARERR(up); + + /* Disable all interrupts. */ + write_zsreg(up, R1, + regs[R1] & ~(RxINT_MASK | TxINT_ENAB | EXT_INT_ENAB)); + + /* Set parity, sync config, stop bits, and clock divisor. */ + write_zsreg(up, R4, regs[R4]); + + /* Set misc. TX/RX control bits. */ + write_zsreg(up, R10, regs[R10]); + + /* Set TX/RX controls sans the enable bits. */ + write_zsreg(up, R3, regs[R3] & ~RxENABLE); + write_zsreg(up, R5, regs[R5] & ~TxENABLE); + + /* Synchronous mode config. */ + write_zsreg(up, R6, regs[R6]); + write_zsreg(up, R7, regs[R7]); + + /* Disable baud generator. */ + write_zsreg(up, R14, regs[R14] & ~BRENAB); + + /* Clock mode control. */ + write_zsreg(up, R11, regs[R11]); + + /* Lower and upper byte of baud rate generator divisor. */ + write_zsreg(up, R12, regs[R12]); + write_zsreg(up, R13, regs[R13]); + + /* Now rewrite R14, with BRENAB (if set). */ + write_zsreg(up, R14, regs[R14]); + + /* External status interrupt control. */ + write_zsreg(up, R15, regs[R15]); + + /* Reset external status interrupts. */ + write_zsreg(up, R0, RES_EXT_INT); + write_zsreg(up, R0, RES_EXT_INT); + + /* Rewrite R3/R5, this time without enables masked. */ + write_zsreg(up, R3, regs[R3]); + write_zsreg(up, R5, regs[R5]); + + /* Rewrite R1, this time without IRQ enabled masked. */ + write_zsreg(up, R1, regs[R1]); + + /* Enable interrupts */ + write_zsreg(up, R9, regs[R9]); +} + +/* + * We do like sunzilog to avoid disrupting pending Tx + * Reprogram the Zilog channel HW registers with the copies found in the + * software state struct. If the transmitter is busy, we defer this update + * until the next TX complete interrupt. Else, we do it right now. + * + * The UART port lock must be held and local interrupts disabled. + */ +static void pmz_maybe_update_regs(struct uart_pmac_port *up) +{ +#if 1 + if (!ZS_REGS_HELD(up)) { + if (ZS_TX_ACTIVE(up)) { + up->flags |= PMACZILOG_FLAG_REGS_HELD; + } else { + pr_debug("pmz: maybe_update_regs: updating\n"); + pmz_load_zsregs(up, up->curregs); + } + } +#else + pr_debug("pmz: maybe_update_regs: updating\n"); + pmz_load_zsregs(up, up->curregs); +#endif +} + +static void pmz_receive_chars(struct uart_pmac_port *up, struct pt_regs *regs) +{ + struct tty_struct *tty = up->port.info->tty; /* XXX info==NULL? */ + + while (1) { + unsigned char ch, r1; + + if (unlikely(tty->flip.count >= TTY_FLIPBUF_SIZE)) { + tty->flip.work.func((void *)tty); + if (tty->flip.count >= TTY_FLIPBUF_SIZE) + /* XXX Ignores SysRq when we need it most. Fix. */ + return; + } + + r1 = read_zsreg(up, R1); + if (r1 & (PAR_ERR | Rx_OVR | CRC_ERR)) { + write_zsreg(up, R0, ERR_RES); + zssync(up); + } + + ch = read_zsreg(up, R0); + + /* This funny hack depends upon BRK_ABRT not interfering + * with the other bits we care about in R1. + */ + if (ch & BRK_ABRT) + r1 |= BRK_ABRT; + + ch = read_zsdata(up); + ch &= up->parity_mask; + + /* A real serial line, record the character and status. */ + *tty->flip.char_buf_ptr = ch; + *tty->flip.flag_buf_ptr = TTY_NORMAL; + up->port.icount.rx++; + if (r1 & (BRK_ABRT | PAR_ERR | Rx_OVR | CRC_ERR)) { + if (r1 & BRK_ABRT) { + r1 &= ~(PAR_ERR | CRC_ERR); + up->port.icount.brk++; + if (uart_handle_break(&up->port)) + goto next_char; + } + else if (r1 & PAR_ERR) + up->port.icount.parity++; + else if (r1 & CRC_ERR) + up->port.icount.frame++; + if (r1 & Rx_OVR) + up->port.icount.overrun++; + r1 &= up->port.read_status_mask; + if (r1 & BRK_ABRT) + *tty->flip.flag_buf_ptr = TTY_BREAK; + else if (r1 & PAR_ERR) + *tty->flip.flag_buf_ptr = TTY_PARITY; + else if (r1 & CRC_ERR) + *tty->flip.flag_buf_ptr = TTY_FRAME; + } + if (uart_handle_sysrq_char(&up->port, ch, regs)) + goto next_char; + + if (up->port.ignore_status_mask == 0xff || + (r1 & up->port.ignore_status_mask) == 0) { + tty->flip.flag_buf_ptr++; + tty->flip.char_buf_ptr++; + tty->flip.count++; + } + if ((r1 & Rx_OVR) && + tty->flip.count < TTY_FLIPBUF_SIZE) { + *tty->flip.flag_buf_ptr = TTY_OVERRUN; + tty->flip.flag_buf_ptr++; + tty->flip.char_buf_ptr++; + tty->flip.count++; + } + next_char: + ch = read_zsreg(up, R0); + if (!(ch & Rx_CH_AV)) + break; + } + + tty_flip_buffer_push(tty); +} + +static void pmz_status_handle(struct uart_pmac_port *up, struct pt_regs *regs) +{ + unsigned char status; + + status = read_zsreg(up, R0); + write_zsreg(up, R0, RES_EXT_INT); + zssync(up); + + if (ZS_WANTS_MODEM_STATUS(up)) { + if (status & SYNC_HUNT) + up->port.icount.dsr++; + + /* The Zilog just gives us an interrupt when DCD/CTS/etc. change. + * But it does not tell us which bit has changed, we have to keep + * track of this ourselves. + */ + if ((status & DCD) ^ up->prev_status) + uart_handle_dcd_change(&up->port, + (status & DCD)); + if ((status & CTS) ^ up->prev_status) + uart_handle_cts_change(&up->port, + (status & CTS)); + + wake_up_interruptible(&up->port.info->delta_msr_wait); + } + + up->prev_status = status; +} + +static void pmz_transmit_chars(struct uart_pmac_port *up) +{ + struct circ_buf *xmit; + + if (ZS_IS_CONS(up)) { + unsigned char status = read_zsreg(up, R0); + + /* TX still busy? Just wait for the next TX done interrupt. + * + * It can occur because of how we do serial console writes. It would + * be nice to transmit console writes just like we normally would for + * a TTY line. (ie. buffered and TX interrupt driven). That is not + * easy because console writes cannot sleep. One solution might be + * to poll on enough port->xmit space becomming free. -DaveM + */ + if (!(status & Tx_BUF_EMP)) + return; + } + + up->flags &= ~PMACZILOG_FLAG_TX_ACTIVE; + + if (ZS_REGS_HELD(up)) { + pmz_load_zsregs(up, up->curregs); + up->flags &= ~PMACZILOG_FLAG_REGS_HELD; + } + + if (ZS_TX_STOPPED(up)) { + up->flags &= ~PMACZILOG_FLAG_TX_STOPPED; + goto ack_tx_int; + } + + if (up->port.x_char) { + up->flags |= PMACZILOG_FLAG_TX_ACTIVE; + write_zsdata(up, up->port.x_char); + zssync(up); + up->port.icount.tx++; + up->port.x_char = 0; + return; + } + + if (up->port.info == NULL) + goto ack_tx_int; + xmit = &up->port.info->xmit; + if (uart_circ_empty(xmit)) { + uart_write_wakeup(&up->port); + goto ack_tx_int; + } + if (uart_tx_stopped(&up->port)) + goto ack_tx_int; + + up->flags |= PMACZILOG_FLAG_TX_ACTIVE; + write_zsdata(up, xmit->buf[xmit->tail]); + zssync(up); + + xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); + up->port.icount.tx++; + + if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) + uart_write_wakeup(&up->port); + + return; + +ack_tx_int: + write_zsreg(up, R0, RES_Tx_P); + zssync(up); +} + +/* Hrm... we register that twice, fixme later.... */ +static irqreturn_t pmz_interrupt(int irq, void *dev_id, struct pt_regs *regs) +{ + struct uart_pmac_port *up = dev_id; + struct uart_pmac_port *up_a; + struct uart_pmac_port *up_b; + int rc = IRQ_NONE; + u8 r3; + + up_a = ZS_IS_CHANNEL_A(up) ? up : up->mate; + up_b = up_a->mate; + + spin_lock(&up_a->port.lock); + r3 = read_zsreg(up, R3); + pr_debug("pmz_irq: %x\n", r3); + + /* Channel A */ + if (r3 & (CHAEXT | CHATxIP | CHARxIP)) { + write_zsreg(up_a, R0, RES_H_IUS); + zssync(up_a); + pr_debug("pmz: irq channel A: %x\n", r3); + if (r3 & CHARxIP) + pmz_receive_chars(up_a, regs); + if (r3 & CHAEXT) + pmz_status_handle(up_a, regs); + if (r3 & CHATxIP) + pmz_transmit_chars(up_a); + rc = IRQ_HANDLED; + } + spin_unlock(&up_a->port.lock); + + spin_lock(&up_b->port.lock); + if (r3 & (CHBEXT | CHBTxIP | CHBRxIP)) { + write_zsreg(up_b, R0, RES_H_IUS); + zssync(up_b); + pr_debug("pmz: irq channel B: %x\n", r3); + if (r3 & CHBRxIP) + pmz_receive_chars(up_b, regs); + if (r3 & CHBEXT) + pmz_status_handle(up_b, regs); + if (r3 & CHBTxIP) + pmz_transmit_chars(up_b); + rc = IRQ_HANDLED; + } + spin_unlock(&up_b->port.lock); + + + return rc; +} + +/* + * Peek the status register, lock not held by caller + */ +static inline u8 pmz_peek_status(struct uart_pmac_port *up) +{ + unsigned long flags; + u8 status; + + spin_lock_irqsave(&up->port.lock, flags); + status = read_zsreg(up, R0); + spin_unlock_irqrestore(&up->port.lock, flags); + + return status; +} + +/* + * Check if transmitter is empty + * The port lock is not held. + */ +static unsigned int pmz_tx_empty(struct uart_port *port) +{ + unsigned char status; + + status = pmz_peek_status(to_pmz(port)); + if (status & Tx_BUF_EMP) + return TIOCSER_TEMT; + return 0; +} + +/* + * Set Modem Control (RTS & DTR) bits + * The port lock is held and interrupts are disabled. + * Note: Shall we really filter out RTS on external ports or + * should that be dealt at higher level only ? + */ +static void pmz_set_mctrl(struct uart_port *port, unsigned int mctrl) +{ + struct uart_pmac_port *up = to_pmz(port); + unsigned char set_bits, clear_bits; + + /* Do nothing for irda for now... */ + if (ZS_IS_IRDA(up)) + return; + + set_bits = clear_bits = 0; + + if (ZS_IS_INTMODEM(up)) { + if (mctrl & TIOCM_RTS) + set_bits |= RTS; + else + clear_bits |= RTS; + } + if (mctrl & TIOCM_DTR) + set_bits |= DTR; + else + clear_bits |= DTR; + + /* NOTE: Not subject to 'transmitter active' rule. */ + up->curregs[R5] |= set_bits; + up->curregs[R5] &= ~clear_bits; + write_zsreg(up, R5, up->curregs[R5]); + zssync(up); +} + +/* + * Get Modem Control bits (only the input ones, the core will + * or that with a cached value of the control ones) + * The port lock is not held. + */ +static unsigned int pmz_get_mctrl(struct uart_port *port) +{ + unsigned char status; + unsigned int ret; + + status = pmz_peek_status(to_pmz(port)); + + ret = 0; + if (status & DCD) + ret |= TIOCM_CAR; + if (status & SYNC_HUNT) + ret |= TIOCM_DSR; + if (status & CTS) + ret |= TIOCM_CTS; + + return ret; +} + +/* + * Stop TX side. Dealt like sunzilog at next Tx interrupt, + * though for DMA, we will have to do a bit more. What is + * the meaning of the tty_stop bit ? XXX + * The port lock is held and interrupts are disabled. + */ +static void pmz_stop_tx(struct uart_port *port, unsigned int tty_stop) +{ + to_pmz(port)->flags |= PMACZILOG_FLAG_TX_STOPPED; +} + +/* + * Kick the Tx side. + * The port lock is held and interrupts are disabled. + */ +static void pmz_start_tx(struct uart_port *port, unsigned int tty_start) +{ + struct uart_pmac_port *up = to_pmz(port); + unsigned char status; + + pr_debug("pmz: start_tx()\n"); + + up->flags |= PMACZILOG_FLAG_TX_ACTIVE; + up->flags &= ~PMACZILOG_FLAG_TX_STOPPED; + + status = read_zsreg(up, R0); + + /* TX busy? Just wait for the TX done interrupt. */ + if (!(status & Tx_BUF_EMP)) + return; + + /* Send the first character to jump-start the TX done + * IRQ sending engine. + */ + if (port->x_char) { + write_zsdata(up, port->x_char); + zssync(up); + port->icount.tx++; + port->x_char = 0; + } else { + struct circ_buf *xmit = &port->info->xmit; + + write_zsdata(up, xmit->buf[xmit->tail]); + zssync(up); + xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); + port->icount.tx++; + + if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) + uart_write_wakeup(&up->port); + } + pr_debug("pmz: start_tx() done.\n"); +} + +/* + * Stop Rx side, basically disable emitting of + * Rx interrupts on the port + * The port lock is held. + */ +static void pmz_stop_rx(struct uart_port *port) +{ + struct uart_pmac_port *up = to_pmz(port); + + if (ZS_IS_CONS(up)) + return; + + pr_debug("pmz: stop_rx()()\n"); + + /* Disable all RX interrupts. */ + up->curregs[R1] &= ~RxINT_MASK; + pmz_maybe_update_regs(up); + + pr_debug("pmz: stop_rx() done.\n"); +} + +/* + * Enable modem status change interrupts + * The port lock is not held. + */ +static void pmz_enable_ms(struct uart_port *port) +{ + struct uart_pmac_port *up = to_pmz(port); + unsigned char new_reg; + unsigned long flags; + + spin_lock_irqsave(&port->lock, flags); + + new_reg = up->curregs[R15] | (DCDIE | SYNCIE | CTSIE); + if (new_reg != up->curregs[R15]) { + up->curregs[R15] = new_reg; + + /* NOTE: Not subject to 'transmitter active' rule. */ + write_zsreg(up, R15, up->curregs[R15]); + } + + spin_unlock_irqrestore(&port->lock, flags); +} + +/* + * Control break state emission + * The port lock is not held. + */ +static void pmz_break_ctl(struct uart_port *port, int break_state) +{ + struct uart_pmac_port *up = to_pmz(port); + unsigned char set_bits, clear_bits, new_reg; + unsigned long flags; + + set_bits = clear_bits = 0; + + if (break_state) + set_bits |= SND_BRK; + else + clear_bits |= SND_BRK; + + spin_lock_irqsave(&port->lock, flags); + + new_reg = (up->curregs[R5] | set_bits) & ~clear_bits; + if (new_reg != up->curregs[R5]) { + up->curregs[R5] = new_reg; + + /* NOTE: Not subject to 'transmitter active' rule. */ + write_zsreg(up, R5, up->curregs[R5]); + } + + spin_unlock_irqrestore(&port->lock, flags); +} + +/* + * Turn power on or off to the SCC and associated stuff + * (port drivers, modem, IR port, etc.) + * Returns the number of milliseconds we should wait before + * trying to use the port. + */ +static int pmz_set_scc_power(struct uart_pmac_port *up, int state) +{ + int delay = 0; + + if (state) { + pmac_call_feature( + PMAC_FTR_SCC_ENABLE, up->node, up->port_type, 1); + if (ZS_IS_INTMODEM(up)) { + pmac_call_feature( + PMAC_FTR_MODEM_ENABLE, up->node, 0, 1); + delay = 2500; /* wait for 2.5s before using */ + } else if (ZS_IS_IRDA(up)) + mdelay(50); /* Do better here once the problems + * with blocking have been ironed out + */ + } else { + /* TODO: Make that depend on a timer, don't power down + * immediately + */ + if (ZS_IS_INTMODEM(up)) { + pmac_call_feature( + PMAC_FTR_MODEM_ENABLE, up->node, 0, 0); + } + pmac_call_feature( + PMAC_FTR_SCC_ENABLE, up->node, up->port_type, 0); + } + return delay; +} + +/* + * FixZeroBug....Works around a bug in the SCC receving channel. + * Taken from Darwin code, 15 Sept. 2000 -DanM + * + * The following sequence prevents a problem that is seen with O'Hare ASICs + * (most versions -- also with some Heathrow and Hydra ASICs) where a zero + * at the input to the receiver becomes 'stuck' and locks up the receiver. + * This problem can occur as a result of a zero bit at the receiver input + * coincident with any of the following events: + * + * The SCC is initialized (hardware or software). + * A framing error is detected. + * The clocking option changes from synchronous or X1 asynchronous + * clocking to X16, X32, or X64 asynchronous clocking. + * The decoding mode is changed among NRZ, NRZI, FM0, or FM1. + * + * This workaround attempts to recover from the lockup condition by placing + * the SCC in synchronous loopback mode with a fast clock before programming + * any of the asynchronous modes. + */ +static void pmz_fix_zero_bug_scc(struct uart_pmac_port *up) +{ + write_zsreg(up, 9, ZS_IS_CHANNEL_A(up) ? CHRA : CHRB); + zssync(up); + udelay(10); + write_zsreg(up, 9, (ZS_IS_CHANNEL_A(up) ? CHRA : CHRB) | NV); + zssync(up); + + write_zsreg(up, 4, (X1CLK | EXTSYNC)); + + /* I think this is wrong....but, I just copying code.... + */ + write_zsreg(up, 3, (8 & ~RxENABLE)); + + write_zsreg(up, 5, (8 & ~TxENABLE)); + write_zsreg(up, 9, NV); /* Didn't we already do this? */ + write_zsreg(up, 11, (RCBR | TCBR)); + write_zsreg(up, 12, 0); + write_zsreg(up, 13, 0); + write_zsreg(up, 14, (LOOPBAK | SSBR)); + write_zsreg(up, 14, (LOOPBAK | SSBR | BRENAB)); + write_zsreg(up, 3, (8 | RxENABLE)); + write_zsreg(up, 0, RES_EXT_INT); + write_zsreg(up, 0, RES_EXT_INT); /* to kill some time */ + + /* The channel should be OK now, but it is probably receiving + * loopback garbage. + * Switch to asynchronous mode, disable the receiver, + * and discard everything in the receive buffer. + */ + write_zsreg(up, 9, NV); + write_zsreg(up, 4, PAR_ENAB); + write_zsreg(up, 3, (8 & ~RxENABLE)); + + while (read_zsreg(up, 0) & Rx_CH_AV) { + (void)read_zsreg(up, 8); + write_zsreg(up, 0, RES_EXT_INT); + write_zsreg(up, 0, ERR_RES); + } +} + +/* + * Real startup routine, powers up the hardware and sets up + * the SCC. Returns a delay in ms where you need to wait before + * actually using the port, this is typically the internal modem + * powerup delay. This routine expect the lock to be taken. + */ +static int __pmz_startup(struct uart_pmac_port *up) +{ + int pwr_delay = 0; + + memset(&up->curregs, 0, sizeof(up->curregs)); + + /* Power up the SCC & underlying hardware (modem/irda) */ + pwr_delay = pmz_set_scc_power(up, 1); + + /* Nice buggy HW ... */ + pmz_fix_zero_bug_scc(up); + + /* Reset the chip */ + write_zsreg(up, 9, ZS_IS_CHANNEL_A(up) ? CHRA : CHRB); + zssync(up); + udelay(10); + write_zsreg(up, 9, 0); + zssync(up); + + /* Clear the interrupt registers */ + write_zsreg(up, R1, 0); + write_zsreg(up, R0, ERR_RES); + write_zsreg(up, R0, ERR_RES); + write_zsreg(up, R0, RES_H_IUS); + write_zsreg(up, R0, RES_H_IUS); + + /* Remember status for DCD/CTS changes */ + up->prev_status = read_zsreg(up, R0); + + /* Enable receiver and transmitter. */ + up->curregs[R3] |= RxENABLE; + up->curregs[R5] |= TxENABLE | RTS | DTR; + + /* Master interrupt enable */ + up->curregs[R9] |= NV | MIE; + + up->curregs[R1] |= EXT_INT_ENAB | INT_ALL_Rx | TxINT_ENAB; + // pmz_maybe_update_regs(up); + + return pwr_delay; +} + +/* + * This is the "normal" startup routine, using the above one + * wrapped with the lock and doing a schedule delay + */ +static int pmz_startup(struct uart_port *port) +{ + struct uart_pmac_port *up = to_pmz(port); + unsigned long flags; + int pwr_delay = 0; + + pr_debug("pmz: startup()\n"); + + /* A console is never powered down */ + if (!ZS_IS_CONS(up)) { + spin_lock_irqsave(&port->lock, flags); + pwr_delay = __pmz_startup(up); + spin_unlock_irqrestore(&port->lock, flags); + } + + if (request_irq(up->port.irq, pmz_interrupt, SA_SHIRQ, "PowerMac Zilog", up)) { + printk(KERN_ERR "Unable to register zs interrupt handler.\n"); + pmz_set_scc_power(up, 0); + return -ENXIO; + } + + /* Right now, we deal with delay by blocking here, I'll be + * smarter later on + */ + if (pwr_delay != 0) { + pr_debug("pmz: delaying %d ms\n", pwr_delay); + set_current_state(TASK_UNINTERRUPTIBLE); + schedule_timeout((pwr_delay * HZ)/1000); + } + + pr_debug("pmz: startup() done.\n"); + + return 0; +} + +static void pmz_shutdown(struct uart_port *port) +{ + struct uart_pmac_port *up = to_pmz(port); + unsigned long flags; + + pr_debug("pmz: shutdown()\n"); + + /* Release interrupt handler */ + free_irq(up->port.irq, up); + + if (ZS_IS_CONS(up)) + return; + + spin_lock_irqsave(&port->lock, flags); + + /* Disable receiver and transmitter. */ + up->curregs[R3] &= ~RxENABLE; + up->curregs[R5] &= ~TxENABLE; + + /* Disable all interrupts and BRK assertion. */ + up->curregs[R1] &= ~(EXT_INT_ENAB | TxINT_ENAB | RxINT_MASK); + up->curregs[R5] &= ~SND_BRK; + pmz_maybe_update_regs(up); + + /* Shut the chip down */ + pmz_set_scc_power(up, 0); + + spin_unlock_irqrestore(&port->lock, flags); + + pr_debug("pmz: shutdown() done.\n"); +} + +/* Shared by TTY driver and serial console setup. The port lock is held + * and local interrupts are disabled. + */ +static void +pmz_convert_to_zs(struct uart_pmac_port *up, unsigned int cflag, + unsigned int iflag, int baud) +{ + int brg; + + switch (baud) { + case ZS_CLOCK/16: /* 230400 */ + up->curregs[R4] = X16CLK; + up->curregs[R11] = 0; + break; + case ZS_CLOCK/32: /* 115200 */ + up->curregs[R4] = X32CLK; + up->curregs[R11] = 0; + break; + default: + up->curregs[R4] = X16CLK; + up->curregs[R11] = TCBR | RCBR; + brg = BPS_TO_BRG(baud, ZS_CLOCK / 16); + up->curregs[R12] = (brg & 255); + up->curregs[R13] = ((brg >> 8) & 255); + up->curregs[R14] = BRENAB; + } + + /* Character size, stop bits, and parity. */ + up->curregs[3] &= ~RxN_MASK; + up->curregs[5] &= ~TxN_MASK; + + switch (cflag & CSIZE) { + case CS5: + up->curregs[3] |= Rx5; + up->curregs[5] |= Tx5; + up->parity_mask = 0x1f; + break; + case CS6: + up->curregs[3] |= Rx6; + up->curregs[5] |= Tx6; + up->parity_mask = 0x3f; + break; + case CS7: + up->curregs[3] |= Rx7; + up->curregs[5] |= Tx7; + up->parity_mask = 0x7f; + break; + case CS8: + default: + up->curregs[3] |= Rx8; + up->curregs[5] |= Tx8; + up->parity_mask = 0xff; + break; + }; + up->curregs[4] &= ~(SB_MASK); + if (cflag & CSTOPB) + up->curregs[4] |= SB2; + else + up->curregs[4] |= SB1; + if (cflag & PARENB) + up->curregs[4] |= PAR_ENAB; + else + up->curregs[4] &= ~PAR_ENAB; + if (!(cflag & PARODD)) + up->curregs[4] |= PAR_EVEN; + else + up->curregs[4] &= ~PAR_EVEN; + + up->port.read_status_mask = Rx_OVR; + if (iflag & INPCK) + up->port.read_status_mask |= CRC_ERR | PAR_ERR; + if (iflag & (BRKINT | PARMRK)) + up->port.read_status_mask |= BRK_ABRT; + + up->port.ignore_status_mask = 0; + if (iflag & IGNPAR) + up->port.ignore_status_mask |= CRC_ERR | PAR_ERR; + if (iflag & IGNBRK) { + up->port.ignore_status_mask |= BRK_ABRT; + if (iflag & IGNPAR) + up->port.ignore_status_mask |= Rx_OVR; + } + + if ((cflag & CREAD) == 0) + up->port.ignore_status_mask = 0xff; +} + +static void pmz_irda_rts_pulses(struct uart_pmac_port *up, int w) +{ + udelay(w); + write_zsreg(up, 5, Tx8 | TxENABLE); + zssync(up); + udelay(2); + write_zsreg(up, 5, Tx8 | TxENABLE | RTS); + zssync(up); + udelay(8); + write_zsreg(up, 5, Tx8 | TxENABLE); + zssync(up); + udelay(4); + write_zsreg(up, 5, Tx8 | TxENABLE | RTS); + zssync(up); +} + +/* + * Set the irda codec on the imac to the specified baud rate. + */ +static void pmz_irda_setup(struct uart_pmac_port *up, int cflags) +{ + int code, speed, t; + + speed = cflags & CBAUD; + if (speed < B2400 || speed > B115200) + return; + code = 0x4d + B115200 - speed; + + /* disable serial interrupts and receive DMA */ + write_zsreg(up, 1, up->curregs[1] & ~0x9f); + + /* wait for transmitter to drain */ + t = 10000; + while ((read_zsreg(up, R0) & Tx_BUF_EMP) == 0 + || (read_zsreg(up, R1) & ALL_SNT) == 0) { + if (--t <= 0) { + printk(KERN_ERR "transmitter didn't drain\n"); + return; + } + udelay(10); + } + udelay(100); + + /* set to 8 bits, no parity, 19200 baud, RTS on, DTR off */ + write_zsreg(up, R4, X16CLK | SB1); + write_zsreg(up, R11, TCBR | RCBR); + t = BPS_TO_BRG(19200, ZS_CLOCK/16); + write_zsreg(up, R12, t); + write_zsreg(up, R13, t >> 8); + write_zsreg(up, R14, BRENAB); + write_zsreg(up, R3, Rx8 | RxENABLE); + write_zsreg(up, R5, Tx8 | TxENABLE | RTS); + zssync(up); + + /* set TxD low for ~104us and pulse RTS */ + udelay(1000); + write_zsdata(up, 0xfe); + pmz_irda_rts_pulses(up, 150); + pmz_irda_rts_pulses(up, 180); + pmz_irda_rts_pulses(up, 50); + udelay(100); + + /* assert DTR, wait 30ms, talk to the chip */ + write_zsreg(up, R5, Tx8 | TxENABLE | RTS | DTR); + zssync(up); + mdelay(30); + while (read_zsreg(up, R0) & Rx_CH_AV) + read_zsdata(up); + + write_zsdata(up, 1); + t = 1000; + while ((read_zsreg(up, R0) & Rx_CH_AV) == 0) { + if (--t <= 0) { + printk(KERN_ERR "irda_setup timed out on 1st byte\n"); + goto out; + } + udelay(10); + } + t = read_zsdata(up); + if (t != 4) + printk(KERN_ERR "irda_setup 1st byte = %x\n", t); + + write_zsdata(up, code); + t = 1000; + while ((read_zsreg(up, R0) & Rx_CH_AV) == 0) { + if (--t <= 0) { + printk(KERN_ERR "irda_setup timed out on 2nd byte\n"); + goto out; + } + udelay(10); + } + t = read_zsdata(up); + if (t != code) + printk(KERN_ERR "irda_setup 2nd byte = %x (%x)\n", t, code); + + /* Drop DTR again and do some more RTS pulses */ + out: + udelay(100); + write_zsreg(up, R5, Tx8 | TxENABLE | RTS); + pmz_irda_rts_pulses(up, 80); + + /* We should be right to go now. We assume that load_zsregs + will get called soon to load up the correct baud rate etc. */ + up->curregs[R5] = (up->curregs[R5] | RTS) & ~DTR; +} + +/* The port lock is not held. */ +static void +pmz_set_termios(struct uart_port *port, struct termios *termios, + struct termios *old) +{ + struct uart_pmac_port *up = to_pmz(port); + unsigned long flags; + int baud; + + pr_debug("pmz: set_termios()\n"); + + baud = uart_get_baud_rate(port, termios, old, 1200, 230400); + + spin_lock_irqsave(&up->port.lock, flags); + + pmz_convert_to_zs(up, termios->c_cflag, termios->c_iflag, baud); + + if (UART_ENABLE_MS(&up->port, termios->c_cflag)) + up->flags |= PMACZILOG_FLAG_MODEM_STATUS; + else + up->flags &= ~PMACZILOG_FLAG_MODEM_STATUS; + + /* set the irda codec to the right rate */ + if (ZS_IS_IRDA(up)) + pmz_irda_setup(up, termios->c_cflag); + + /* Load registers to the chip */ + pmz_maybe_update_regs(up); + + spin_unlock_irqrestore(&up->port.lock, flags); + + pr_debug("pmz: set_termios() done.\n"); +} + +static const char *pmz_type(struct uart_port *port) +{ + return "PowerMac Zilog"; +} + +/* We do not request/release mappings of the registers here, this + * happens at early serial probe time. + */ +static void pmz_release_port(struct uart_port *port) +{ +} + +static int pmz_request_port(struct uart_port *port) +{ + return 0; +} + +/* These do not need to do anything interesting either. */ +static void pmz_config_port(struct uart_port *port, int flags) +{ +} + +/* We do not support letting the user mess with the divisor, IRQ, etc. */ +static int pmz_verify_port(struct uart_port *port, struct serial_struct *ser) +{ + return -EINVAL; +} + +static struct uart_ops pmz_pops = { + .tx_empty = pmz_tx_empty, + .set_mctrl = pmz_set_mctrl, + .get_mctrl = pmz_get_mctrl, + .stop_tx = pmz_stop_tx, + .start_tx = pmz_start_tx, + .stop_rx = pmz_stop_rx, + .enable_ms = pmz_enable_ms, + .break_ctl = pmz_break_ctl, + .startup = pmz_startup, + .shutdown = pmz_shutdown, + .set_termios = pmz_set_termios, + .type = pmz_type, + .release_port = pmz_release_port, + .request_port = pmz_request_port, + .config_port = pmz_config_port, + .verify_port = pmz_verify_port, +}; + +/* + * Setup one port structure after probing, HW is down at this point, + * Unlike sunzilog, we don't need to pre-init the spinlock as we don't + * register our console before uart_add_one_port() is called + */ +static int __init pmz_setup_port(struct uart_pmac_port *up, int early) +{ + struct device_node *np = up->node; + char *conn; + struct slot_names_prop { + int count; + char name[1]; + } *slots; + int len; + + /* + * Request & map chip registers + */ + if (!early && request_OF_resource(np, 0, NULL) == NULL) { + printk("pmac_zilog: failed to request resources for %s\n", + np->full_name); + return -EBUSY; + } + up->port.mapbase = np->addrs[0].address; + up->port.membase = ioremap(up->port.mapbase, 0x1000); + + up->control_reg = (volatile u8 *)up->port.membase; + up->data_reg = up->control_reg + 0x10; + + /* + * Request & map DBDMA registers + */ +#ifdef HAS_DBDMA + if (np->n_addrs >= 3 && np->n_intrs >= 3) + up->flags |= PMACZILOG_FLAG_HAS_DMA; +#endif + if (ZS_HAS_DMA(up)) { + if (!early && request_OF_resource(np, np->n_addrs - 2, " (tx dma)") == NULL) { + printk(KERN_ERR "pmac_zilog: can't request TX DMA resource !\n"); + up->flags &= ~PMACZILOG_FLAG_HAS_DMA; + goto no_dma; + } + if (!early && request_OF_resource(np, np->n_addrs - 1, " (rx dma)") == NULL) { + release_OF_resource(np, np->n_addrs - 2); + printk(KERN_ERR "pmac_zilog: can't request RX DMA resource !\n"); + up->flags &= ~PMACZILOG_FLAG_HAS_DMA; + goto no_dma; + } + up->tx_dma_regs = (volatile struct dbdma_regs *) + ioremap(np->addrs[np->n_addrs - 2].address, 0x1000); + up->rx_dma_regs = (volatile struct dbdma_regs *) + ioremap(np->addrs[np->n_addrs - 1].address, 0x1000); + up->tx_dma_irq = np->intrs[1].line; + up->rx_dma_irq = np->intrs[2].line; + } +no_dma: + if (!early) + up->flags |= PMACZILOG_FLAG_RSRC_REQUESTED; + + /* + * Detect port type + */ + if (device_is_compatible(np, "cobalt")) + up->flags |= PMACZILOG_FLAG_IS_INTMODEM; + conn = get_property(np, "AAPL,connector", &len); + if (conn && (strcmp(conn, "infrared") == 0)) + up->flags |= PMACZILOG_FLAG_IS_IRDA; + up->port_type = PMAC_SCC_ASYNC; + /* 1999 Powerbook G3 has slot-names property instead */ + slots = (struct slot_names_prop *)get_property(np, "slot-names", &len); + if (slots && slots->count > 0) { + if (strcmp(slots->name, "IrDA") == 0) + up->flags |= PMACZILOG_FLAG_IS_IRDA; + else if (strcmp(slots->name, "Modem") == 0) + up->flags |= PMACZILOG_FLAG_IS_INTMODEM; + } + if (ZS_IS_IRDA(up)) + up->port_type = PMAC_SCC_IRDA; + if (ZS_IS_INTMODEM(up)) { + struct device_node* i2c_modem = find_devices("i2c-modem"); + if (i2c_modem) { + char* mid = get_property(i2c_modem, "modem-id", NULL); + if (mid) switch(*mid) { + case 0x04 : + case 0x05 : + case 0x07 : + case 0x08 : + case 0x0b : + case 0x0c : + up->port_type = PMAC_SCC_I2S1; + } + printk(KERN_INFO "pmac_zilog: i2c-modem detected, id: %d\n", + mid ? (*mid) : 0); + } else { + printk(KERN_INFO "pmac_zilog: serial modem detected\n"); + } + } + + /* + * Init remaining bits of "port" structure + */ + up->port.iotype = SERIAL_IO_MEM; + up->port.irq = np->intrs[0].line; + up->port.uartclk = ZS_CLOCK; + up->port.fifosize = 1; + up->port.ops = &pmz_pops; + up->port.type = PORT_PMAC_ZILOG; + up->port.flags = 0; + + return 0; +} + +/* + * Get rid of a port on module removal + */ +static void pmz_dispose_port(struct uart_pmac_port *up) +{ + struct device_node *np; + + if (up->flags & PMACZILOG_FLAG_RSRC_REQUESTED) { + release_OF_resource(up->node, 0); + if (ZS_HAS_DMA(up)) { + release_OF_resource(up->node, up->node->n_addrs - 2); + release_OF_resource(up->node, up->node->n_addrs - 1); + } + } + iounmap((void *)up->control_reg); + np = up->node; + up->node = NULL; + of_node_put(np); +} + +/* + * Called upon match with an escc node in the devive-tree. + */ +static int pmz_attach(struct macio_dev *mdev, const struct of_match *match) +{ + int i; + + /* Iterate the pmz_ports array to find a matching entry + */ + for (i = 0; i < MAX_ZS_PORTS; i++) + if (pmz_ports[i].node == mdev->ofdev.node) { + pmz_ports[i].dev = mdev; + dev_set_drvdata(&mdev->ofdev.dev, &pmz_ports[i]); + return 0; + } + return -ENODEV; +} + +/* + * That one should not be called, macio isn't really a hotswap device, + * we don't expect one of those serial ports to go away... + */ +static int pmz_detach(struct macio_dev *mdev) +{ + struct uart_pmac_port *port = dev_get_drvdata(&mdev->ofdev.dev); + + if (!port) + return -ENODEV; + + dev_set_drvdata(&mdev->ofdev.dev, NULL); + port->dev = NULL; + + return 0; +} + +/* + * Probe all ports in the system and build the ports array, we register + * with the serial layer at this point, the macio-type probing is only + * used later to "attach" to the sysfs tree so we get power management + * events + */ +static int __init pmz_probe(int early) +{ + struct device_node *node_p, *node_a, *node_b, *np; + int count = 0; + int rc; + + /* + * Find all escc chips in the system + */ + node_p = of_find_node_by_name(NULL, "escc"); + while (node_p) { + /* + * First get channel A/B node pointers + * + * TODO: Add routines with proper locking to do that... + */ + node_a = node_b = NULL; + for (np = NULL; (np = of_get_next_child(node_p, np)) != NULL;) { + if (strncmp(np->name, "ch-a", 4) == 0) + node_a = of_node_get(np); + else if (strncmp(np->name, "ch-b", 4) == 0) + node_b = of_node_get(np); + } + if (!node_a || !node_b) { + of_node_put(node_a); + of_node_put(node_b); + printk(KERN_ERR "pmac_zilog: missing node %c for escc %s\n", + (!node_a) ? 'a' : 'b', node_p->full_name); + goto next; + } + + /* + * Fill basic fields in the port structures + */ + pmz_ports[count].mate = &pmz_ports[count+1]; + pmz_ports[count+1].mate = &pmz_ports[count]; + pmz_ports[count].flags = PMACZILOG_FLAG_IS_CHANNEL_A; + pmz_ports[count].node = node_a; + pmz_ports[count+1].node = node_b; + pmz_ports[count].port.line = count; + pmz_ports[count+1].port.line = count+1; + + /* + * Setup the ports for real + */ + rc = pmz_setup_port(&pmz_ports[count], early); + if (rc == 0) + rc = pmz_setup_port(&pmz_ports[count+1], early); + if (rc != 0) { + of_node_put(node_a); + of_node_put(node_b); + memset(&pmz_ports[count], 0, sizeof(struct uart_pmac_port)); + memset(&pmz_ports[count+1], 0, sizeof(struct uart_pmac_port)); + goto next; + } + count += 2; +next: + node_p = of_find_node_by_name(node_p, "escc"); + } + pmz_ports_count = count; + + return 0; +} + +static struct uart_driver pmz_uart_reg = { + .owner = THIS_MODULE, + .driver_name = "ttyS", + .devfs_name = "tts/", + .dev_name = "ttyS", + .major = TTY_MAJOR, +}; + +#ifdef CONFIG_SERIAL_PMACZILOG_CONSOLE + +static void pmz_console_write(struct console *con, const char *s, unsigned int count); +static int __init pmz_console_setup(struct console *co, char *options); + +static struct console pmz_console = { + .name = "ttyS", + .write = pmz_console_write, + .device = uart_console_device, + .setup = pmz_console_setup, + .flags = CON_PRINTBUFFER, + .index = -1, + .data = &pmz_uart_reg, +}; + +#define PMACZILOG_CONSOLE &pmz_console +#else /* CONFIG_SERIAL_PMACZILOG_CONSOLE */ +#define PMACZILOG_CONSOLE (NULL) +#endif /* CONFIG_SERIAL_PMACZILOG_CONSOLE */ + +/* + * Register the driver, console driver and ports with the serial + * core + */ +static int __init pmz_register(void) +{ + int i, rc; + + pmz_uart_reg.nr = pmz_ports_count; + pmz_uart_reg.cons = PMACZILOG_CONSOLE; + pmz_uart_reg.minor = 64; + + /* + * Register this driver with the serial core + */ + rc = uart_register_driver(&pmz_uart_reg); + if (rc != 0) + return rc; + + /* + * Register each port with the serial core + */ + for (i = 0; i < pmz_ports_count; i++) { + struct uart_pmac_port *uport = &pmz_ports[i]; + if (uport->node != NULL) + uart_add_one_port(&pmz_uart_reg, &uport->port); + } + + return 0; +} + +static struct of_match pmz_match[] = +{ + { + .name = "ch-a", + .type = OF_ANY_MATCH, + .compatible = OF_ANY_MATCH + }, + { + .name = "ch-b", + .type = OF_ANY_MATCH, + .compatible = OF_ANY_MATCH + }, + {}, +}; + +static struct macio_driver pmz_driver = +{ + .name = "pmac_zilog", + .match_table = pmz_match, + .probe = pmz_attach, + .remove = pmz_detach, +// .suspend = pmz_suspend, *** NYI +// .resume = pmz_resume, *** NYI +}; + +static void pmz_fixup_resources(void) +{ + int i; + for (i=0; inode == NULL) + continue; + if (up->flags & PMACZILOG_FLAG_RSRC_REQUESTED) + continue; + if (request_OF_resource(up->node, 0, NULL) == NULL) + printk(KERN_WARNING "%s: Failed to do late IO resource request, port still active\n", + up->node->name); + up->flags |= PMACZILOG_FLAG_RSRC_REQUESTED; + if (!ZS_HAS_DMA(up)) + continue; + if (request_OF_resource(up->node, up->node->n_addrs - 2, NULL) == NULL) + printk(KERN_WARNING "%s: Failed to do late DMA resource request, port still active\n", + up->node->name); + if (request_OF_resource(up->node, up->node->n_addrs - 1, NULL) == NULL) + printk(KERN_WARNING "%s: Failed to do late DMA resource request, port still active\n", + up->node->name); + } + +} + +static int __init init_pmz(void) +{ + printk(KERN_DEBUG "%s\n", version); + + /* + * If we had serial console, then we didn't request + * resources yet. We fix that up now + */ + if (pmz_ports_count > 0) + pmz_fixup_resources(); + + /* + * First, we need to do a direct OF-based probe pass. We + * do that because we want serial console up before the + * macio stuffs calls us back, and since that makes it + * easier to pass the proper number of channels to + * uart_register_driver() + */ + if (pmz_ports_count == 0) + pmz_probe(0); + + /* + * Bail early if no port found + */ + if (pmz_ports_count == 0) + return -ENODEV; + + /* + * Now we register with the serial layer + */ + pmz_register(); + + /* + * Then we register the macio driver itself + */ + return macio_register_driver(&pmz_driver); +} + +static void __exit exit_pmz(void) +{ + int i; + + /* Get rid of macio-driver (detach from macio) */ + macio_unregister_driver(&pmz_driver); + + /* Unregister UART driver */ + uart_unregister_driver(&pmz_uart_reg); + + for (i = 0; i < pmz_ports_count; i++) { + struct uart_pmac_port *uport = &pmz_ports[i]; + if (uport->node != NULL) { + uart_remove_one_port(&pmz_uart_reg, &uport->port); + pmz_dispose_port(uport); + } + } +} + +#ifdef CONFIG_SERIAL_PMACZILOG_CONSOLE + +/* + * Print a string to the serial port trying not to disturb + * any possible real use of the port... + */ +static void pmz_console_write(struct console *con, const char *s, unsigned int count) +{ + struct uart_pmac_port *up = &pmz_ports[con->index]; + unsigned long flags; + int i; + + spin_lock_irqsave(&up->port.lock, flags); + + /* Turn of interrupts and enable the transmitter. */ + write_zsreg(up, R1, up->curregs[1] & ~TxINT_ENAB); + write_zsreg(up, R5, up->curregs[5] | TxENABLE | RTS | DTR); + + for (i = 0; i < count; i++) { + /* Wait for the transmit buffer to empty. */ + while ((read_zsreg(up, R0) & Tx_BUF_EMP) == 0) + udelay(5); + write_zsdata(up, s[i]); + if (s[i] == 10) { + while ((read_zsreg(up, R0) & Tx_BUF_EMP) == 0) + udelay(5); + write_zsdata(up, R13); + } + } + + /* Restore the values in the registers. */ + write_zsreg(up, R1, up->curregs[1]); + /* Don't disable the transmitter. */ + + spin_unlock_irqrestore(&up->port.lock, flags); +} + +/* + * Setup the serial console + */ +static int __init pmz_console_setup(struct console *co, char *options) +{ + struct uart_port *port; + int baud = 38400; + int bits = 8; + int parity = 'n'; + int flow = 'n'; + unsigned long pwr_delay; + + /* + * XServe's default to 57600 bps + */ + if (machine_is_compatible("RackMac1,1") + || machine_is_compatible("RackMac1,2")) + baud = 57600; + + /* + * Check whether an invalid uart number has been specified, and + * if so, search for the first available port that does have + * console support. + */ + if (co->index >= pmz_ports_count) + co->index = 0; + port = &pmz_ports[co->index].port; + + /* + * Mark port as beeing a console + */ + port->flags |= PMACZILOG_FLAG_IS_CONS; + + /* + * Temporary fix for uart layer who didn't setup the spinlock yet + */ + spin_lock_init(&port->lock); + + /* + * Enable the hardware + */ + pwr_delay = __pmz_startup(&pmz_ports[co->index]); + if (pwr_delay) + mdelay(pwr_delay); + + if (options) + uart_parse_options(options, &baud, &parity, &bits, &flow); + + return uart_set_options(port, co, baud, parity, bits, flow); +} + +static int __init pmz_console_init(void) +{ + /* Probe ports */ + pmz_probe(1); + + /* TODO: Autoprobe console based on OF */ + /* pmz_console.index = i; */ + register_console(&pmz_console); + + return 0; + +} +console_initcall(pmz_console_init); +#endif /* CONFIG_SERIAL_PMACZILOG_CONSOLE */ + +module_init(init_pmz); +module_exit(exit_pmz); diff -Nru a/drivers/serial/pmac_zilog.h b/drivers/serial/pmac_zilog.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/drivers/serial/pmac_zilog.h Tue Sep 2 19:58:20 2003 @@ -0,0 +1,361 @@ +#ifndef __PMAC_ZILOG_H__ +#define __PMAC_ZILOG_H__ + +/* + * At most 2 ESCCs with 2 ports each + */ +#define MAX_ZS_PORTS 4 + +/* + * We wrap our port structure around the generic uart_port. + */ +#define NUM_ZSREGS 16 + +struct uart_pmac_port { + struct uart_port port; + struct uart_pmac_port *mate; + + /* macio_dev for the escc holding this port (maybe be null on + * early inited port) + */ + struct macio_dev *dev; + /* device node to this port, this points to one of 2 childs + * of "escc" node (ie. ch-a or ch-b) + */ + struct device_node *node; + + /* Port type as obtained from device tree (IRDA, modem, ...) */ + int port_type; + u8 curregs[NUM_ZSREGS]; + + unsigned int flags; +#define PMACZILOG_FLAG_IS_CONS 0x00000001 +#define PMACZILOG_FLAG_IS_KGDB 0x00000002 +#define PMACZILOG_FLAG_MODEM_STATUS 0x00000004 +#define PMACZILOG_FLAG_IS_CHANNEL_A 0x00000008 +#define PMACZILOG_FLAG_REGS_HELD 0x00000010 +#define PMACZILOG_FLAG_TX_STOPPED 0x00000020 +#define PMACZILOG_FLAG_TX_ACTIVE 0x00000040 +#define PMACZILOG_FLAG_ENABLED 0x00000080 +#define PMACZILOG_FLAG_IS_IRDA 0x00000100 +#define PMACZILOG_FLAG_IS_INTMODEM 0x00000200 +#define PMACZILOG_FLAG_HAS_DMA 0x00000400 +#define PMACZILOG_FLAG_RSRC_REQUESTED 0x00000800 + + unsigned char parity_mask; + unsigned char prev_status; + + volatile u8 *control_reg; + volatile u8 *data_reg; + + unsigned int tx_dma_irq; + unsigned int rx_dma_irq; + volatile struct dbdma_regs *tx_dma_regs; + volatile struct dbdma_regs *rx_dma_regs; +}; + +#define to_pmz(p) ((struct uart_pmac_port *)(p)) + +/* + * Register acessors. Note that we don't need to enforce a recovery + * delay on PCI PowerMac hardware, it's dealt in HW by the MacIO chip, + * though if we try to use this driver on older machines, we might have + * to add it back + */ +static inline u8 read_zsreg(struct uart_pmac_port *port, u8 reg) +{ + if (reg != 0) + writeb(reg, port->control_reg); + return readb(port->control_reg); +} + +static inline void write_zsreg(struct uart_pmac_port *port, u8 reg, u8 value) +{ + if (reg != 0) + writeb(reg, port->control_reg); + writeb(value, port->control_reg); +} + +static inline u8 read_zsdata(struct uart_pmac_port *port) +{ + return readb(port->data_reg); +} + +static inline void write_zsdata(struct uart_pmac_port *port, u8 data) +{ + writeb(data, port->data_reg); +} + +static inline void zssync(struct uart_pmac_port *port) +{ + (void)readb(port->control_reg); +} + +/* Conversion routines to/from brg time constants from/to bits + * per second. + */ +#define BRG_TO_BPS(brg, freq) ((freq) / 2 / ((brg) + 2)) +#define BPS_TO_BRG(bps, freq) ((((freq) + (bps)) / (2 * (bps))) - 2) + +#define ZS_CLOCK 3686400 /* Z8530 RTxC input clock rate */ + +/* The Zilog register set */ + +#define FLAG 0x7e + +/* Write Register 0 */ +#define R0 0 /* Register selects */ +#define R1 1 +#define R2 2 +#define R3 3 +#define R4 4 +#define R5 5 +#define R6 6 +#define R7 7 +#define R8 8 +#define R9 9 +#define R10 10 +#define R11 11 +#define R12 12 +#define R13 13 +#define R14 14 +#define R15 15 + +#define NULLCODE 0 /* Null Code */ +#define POINT_HIGH 0x8 /* Select upper half of registers */ +#define RES_EXT_INT 0x10 /* Reset Ext. Status Interrupts */ +#define SEND_ABORT 0x18 /* HDLC Abort */ +#define RES_RxINT_FC 0x20 /* Reset RxINT on First Character */ +#define RES_Tx_P 0x28 /* Reset TxINT Pending */ +#define ERR_RES 0x30 /* Error Reset */ +#define RES_H_IUS 0x38 /* Reset highest IUS */ + +#define RES_Rx_CRC 0x40 /* Reset Rx CRC Checker */ +#define RES_Tx_CRC 0x80 /* Reset Tx CRC Checker */ +#define RES_EOM_L 0xC0 /* Reset EOM latch */ + +/* Write Register 1 */ + +#define EXT_INT_ENAB 0x1 /* Ext Int Enable */ +#define TxINT_ENAB 0x2 /* Tx Int Enable */ +#define PAR_SPEC 0x4 /* Parity is special condition */ + +#define RxINT_DISAB 0 /* Rx Int Disable */ +#define RxINT_FCERR 0x8 /* Rx Int on First Character Only or Error */ +#define INT_ALL_Rx 0x10 /* Int on all Rx Characters or error */ +#define INT_ERR_Rx 0x18 /* Int on error only */ +#define RxINT_MASK 0x18 + +#define WT_RDY_RT 0x20 /* W/Req reflects recv if 1, xmit if 0 */ +#define WT_FN_RDYFN 0x40 /* W/Req pin is DMA request if 1, wait if 0 */ +#define WT_RDY_ENAB 0x80 /* Enable W/Req pin */ + +/* Write Register #2 (Interrupt Vector) */ + +/* Write Register 3 */ + +#define RxENABLE 0x1 /* Rx Enable */ +#define SYNC_L_INH 0x2 /* Sync Character Load Inhibit */ +#define ADD_SM 0x4 /* Address Search Mode (SDLC) */ +#define RxCRC_ENAB 0x8 /* Rx CRC Enable */ +#define ENT_HM 0x10 /* Enter Hunt Mode */ +#define AUTO_ENAB 0x20 /* Auto Enables */ +#define Rx5 0x0 /* Rx 5 Bits/Character */ +#define Rx7 0x40 /* Rx 7 Bits/Character */ +#define Rx6 0x80 /* Rx 6 Bits/Character */ +#define Rx8 0xc0 /* Rx 8 Bits/Character */ +#define RxN_MASK 0xc0 + +/* Write Register 4 */ + +#define PAR_ENAB 0x1 /* Parity Enable */ +#define PAR_EVEN 0x2 /* Parity Even/Odd* */ + +#define SYNC_ENAB 0 /* Sync Modes Enable */ +#define SB1 0x4 /* 1 stop bit/char */ +#define SB15 0x8 /* 1.5 stop bits/char */ +#define SB2 0xc /* 2 stop bits/char */ +#define SB_MASK 0xc + +#define MONSYNC 0 /* 8 Bit Sync character */ +#define BISYNC 0x10 /* 16 bit sync character */ +#define SDLC 0x20 /* SDLC Mode (01111110 Sync Flag) */ +#define EXTSYNC 0x30 /* External Sync Mode */ + +#define X1CLK 0x0 /* x1 clock mode */ +#define X16CLK 0x40 /* x16 clock mode */ +#define X32CLK 0x80 /* x32 clock mode */ +#define X64CLK 0xC0 /* x64 clock mode */ +#define XCLK_MASK 0xC0 + +/* Write Register 5 */ + +#define TxCRC_ENAB 0x1 /* Tx CRC Enable */ +#define RTS 0x2 /* RTS */ +#define SDLC_CRC 0x4 /* SDLC/CRC-16 */ +#define TxENABLE 0x8 /* Tx Enable */ +#define SND_BRK 0x10 /* Send Break */ +#define Tx5 0x0 /* Tx 5 bits (or less)/character */ +#define Tx7 0x20 /* Tx 7 bits/character */ +#define Tx6 0x40 /* Tx 6 bits/character */ +#define Tx8 0x60 /* Tx 8 bits/character */ +#define TxN_MASK 0x60 +#define DTR 0x80 /* DTR */ + +/* Write Register 6 (Sync bits 0-7/SDLC Address Field) */ + +/* Write Register 7 (Sync bits 8-15/SDLC 01111110) */ + +/* Write Register 7' (Some enhanced feature control) */ +#define ENEXREAD 0x40 /* Enable read of some write registers */ + +/* Write Register 8 (transmit buffer) */ + +/* Write Register 9 (Master interrupt control) */ +#define VIS 1 /* Vector Includes Status */ +#define NV 2 /* No Vector */ +#define DLC 4 /* Disable Lower Chain */ +#define MIE 8 /* Master Interrupt Enable */ +#define STATHI 0x10 /* Status high */ +#define NORESET 0 /* No reset on write to R9 */ +#define CHRB 0x40 /* Reset channel B */ +#define CHRA 0x80 /* Reset channel A */ +#define FHWRES 0xc0 /* Force hardware reset */ + +/* Write Register 10 (misc control bits) */ +#define BIT6 1 /* 6 bit/8bit sync */ +#define LOOPMODE 2 /* SDLC Loop mode */ +#define ABUNDER 4 /* Abort/flag on SDLC xmit underrun */ +#define MARKIDLE 8 /* Mark/flag on idle */ +#define GAOP 0x10 /* Go active on poll */ +#define NRZ 0 /* NRZ mode */ +#define NRZI 0x20 /* NRZI mode */ +#define FM1 0x40 /* FM1 (transition = 1) */ +#define FM0 0x60 /* FM0 (transition = 0) */ +#define CRCPS 0x80 /* CRC Preset I/O */ + +/* Write Register 11 (Clock Mode control) */ +#define TRxCXT 0 /* TRxC = Xtal output */ +#define TRxCTC 1 /* TRxC = Transmit clock */ +#define TRxCBR 2 /* TRxC = BR Generator Output */ +#define TRxCDP 3 /* TRxC = DPLL output */ +#define TRxCOI 4 /* TRxC O/I */ +#define TCRTxCP 0 /* Transmit clock = RTxC pin */ +#define TCTRxCP 8 /* Transmit clock = TRxC pin */ +#define TCBR 0x10 /* Transmit clock = BR Generator output */ +#define TCDPLL 0x18 /* Transmit clock = DPLL output */ +#define RCRTxCP 0 /* Receive clock = RTxC pin */ +#define RCTRxCP 0x20 /* Receive clock = TRxC pin */ +#define RCBR 0x40 /* Receive clock = BR Generator output */ +#define RCDPLL 0x60 /* Receive clock = DPLL output */ +#define RTxCX 0x80 /* RTxC Xtal/No Xtal */ + +/* Write Register 12 (lower byte of baud rate generator time constant) */ + +/* Write Register 13 (upper byte of baud rate generator time constant) */ + +/* Write Register 14 (Misc control bits) */ +#define BRENAB 1 /* Baud rate generator enable */ +#define BRSRC 2 /* Baud rate generator source */ +#define DTRREQ 4 /* DTR/Request function */ +#define AUTOECHO 8 /* Auto Echo */ +#define LOOPBAK 0x10 /* Local loopback */ +#define SEARCH 0x20 /* Enter search mode */ +#define RMC 0x40 /* Reset missing clock */ +#define DISDPLL 0x60 /* Disable DPLL */ +#define SSBR 0x80 /* Set DPLL source = BR generator */ +#define SSRTxC 0xa0 /* Set DPLL source = RTxC */ +#define SFMM 0xc0 /* Set FM mode */ +#define SNRZI 0xe0 /* Set NRZI mode */ + +/* Write Register 15 (external/status interrupt control) */ +#define EN85C30 1 /* Enable some 85c30-enhanced registers */ +#define ZCIE 2 /* Zero count IE */ +#define ENSTFIFO 4 /* Enable status FIFO (SDLC) */ +#define DCDIE 8 /* DCD IE */ +#define SYNCIE 0x10 /* Sync/hunt IE */ +#define CTSIE 0x20 /* CTS IE */ +#define TxUIE 0x40 /* Tx Underrun/EOM IE */ +#define BRKIE 0x80 /* Break/Abort IE */ + + +/* Read Register 0 */ +#define Rx_CH_AV 0x1 /* Rx Character Available */ +#define ZCOUNT 0x2 /* Zero count */ +#define Tx_BUF_EMP 0x4 /* Tx Buffer empty */ +#define DCD 0x8 /* DCD */ +#define SYNC_HUNT 0x10 /* Sync/hunt */ +#define CTS 0x20 /* CTS */ +#define TxEOM 0x40 /* Tx underrun */ +#define BRK_ABRT 0x80 /* Break/Abort */ + +/* Read Register 1 */ +#define ALL_SNT 0x1 /* All sent */ +/* Residue Data for 8 Rx bits/char programmed */ +#define RES3 0x8 /* 0/3 */ +#define RES4 0x4 /* 0/4 */ +#define RES5 0xc /* 0/5 */ +#define RES6 0x2 /* 0/6 */ +#define RES7 0xa /* 0/7 */ +#define RES8 0x6 /* 0/8 */ +#define RES18 0xe /* 1/8 */ +#define RES28 0x0 /* 2/8 */ +/* Special Rx Condition Interrupts */ +#define PAR_ERR 0x10 /* Parity error */ +#define Rx_OVR 0x20 /* Rx Overrun Error */ +#define CRC_ERR 0x40 /* CRC/Framing Error */ +#define END_FR 0x80 /* End of Frame (SDLC) */ + +/* Read Register 2 (channel b only) - Interrupt vector */ +#define CHB_Tx_EMPTY 0x00 +#define CHB_EXT_STAT 0x02 +#define CHB_Rx_AVAIL 0x04 +#define CHB_SPECIAL 0x06 +#define CHA_Tx_EMPTY 0x08 +#define CHA_EXT_STAT 0x0a +#define CHA_Rx_AVAIL 0x0c +#define CHA_SPECIAL 0x0e +#define STATUS_MASK 0x06 + +/* Read Register 3 (interrupt pending register) ch a only */ +#define CHBEXT 0x1 /* Channel B Ext/Stat IP */ +#define CHBTxIP 0x2 /* Channel B Tx IP */ +#define CHBRxIP 0x4 /* Channel B Rx IP */ +#define CHAEXT 0x8 /* Channel A Ext/Stat IP */ +#define CHATxIP 0x10 /* Channel A Tx IP */ +#define CHARxIP 0x20 /* Channel A Rx IP */ + +/* Read Register 8 (receive data register) */ + +/* Read Register 10 (misc status bits) */ +#define ONLOOP 2 /* On loop */ +#define LOOPSEND 0x10 /* Loop sending */ +#define CLK2MIS 0x40 /* Two clocks missing */ +#define CLK1MIS 0x80 /* One clock missing */ + +/* Read Register 12 (lower byte of baud rate generator constant) */ + +/* Read Register 13 (upper byte of baud rate generator constant) */ + +/* Read Register 15 (value of WR 15) */ + +/* Misc macros */ +#define ZS_CLEARERR(port) (write_zsreg(port, 0, ERR_RES)) +#define ZS_CLEARFIFO(port) do { volatile unsigned char garbage; \ + garbage = read_zsdata(port); \ + garbage = read_zsdata(port); \ + garbage = read_zsdata(port); \ + } while(0) + +#define ZS_IS_CONS(UP) ((UP)->flags & PMACZILOG_FLAG_IS_CONS) +#define ZS_IS_KGDB(UP) ((UP)->flags & PMACZILOG_FLAG_IS_KGDB) +#define ZS_IS_CHANNEL_A(UP) ((UP)->flags & PMACZILOG_FLAG_IS_CHANNEL_A) +#define ZS_REGS_HELD(UP) ((UP)->flags & PMACZILOG_FLAG_REGS_HELD) +#define ZS_TX_STOPPED(UP) ((UP)->flags & PMACZILOG_FLAG_TX_STOPPED) +#define ZS_TX_ACTIVE(UP) ((UP)->flags & PMACZILOG_FLAG_TX_ACTIVE) +#define ZS_WANTS_MODEM_STATUS(UP) ((UP)->flags & PMACZILOG_FLAG_MODEM_STATUS) +#define ZS_IS_IRDA(UP) ((UP)->flags & PMACZILOG_FLAG_IS_IRDA) +#define ZS_IS_INTMODEM(UP) ((UP)->flags & PMACZILOG_FLAG_IS_INTMODEM) +#define ZS_HAS_DMA(UP) ((UP)->flags & PMACZILOG_FLAG_HAS_DMA) + +#endif /* __PMAC_ZILOG_H__ */ diff -Nru a/drivers/telephony/ixj.c b/drivers/telephony/ixj.c --- a/drivers/telephony/ixj.c Tue Sep 2 19:58:13 2003 +++ b/drivers/telephony/ixj.c Tue Sep 2 19:58:13 2003 @@ -278,8 +278,8 @@ #include "ixj.h" -#define TYPE(dev) (minor(dev) >> 4) -#define NUM(dev) (minor(dev) & 0xf) +#define TYPE(inode) (iminor(inode) >> 4) +#define NUM(inode) (iminor(inode) & 0xf) static int ixjdebug; static int hertz = HZ; @@ -2273,7 +2273,7 @@ schedule_timeout(1); } if (ixjdebug & 0x0002) - printk(KERN_INFO "Closing board %d\n", NUM(inode->i_rdev)); + printk(KERN_INFO "Closing board %d\n", NUM(inode)); if (j->cardtype == QTI_PHONECARD) ixj_set_port(j, PORT_SPEAKER); @@ -2858,7 +2858,7 @@ static ssize_t ixj_read(struct file * file_p, char *buf, size_t length, loff_t * ppos) { unsigned long i = *ppos; - IXJ * j = get_ixj(NUM(file_p->f_dentry->d_inode->i_rdev)); + IXJ * j = get_ixj(NUM(file_p->f_dentry->d_inode)); DECLARE_WAITQUEUE(wait, current); @@ -2915,7 +2915,7 @@ { int pre_retval; ssize_t read_retval = 0; - IXJ *j = get_ixj(NUM(file_p->f_dentry->d_inode->i_rdev)); + IXJ *j = get_ixj(NUM(file_p->f_dentry->d_inode)); pre_retval = ixj_PreRead(j, 0L); switch (pre_retval) { @@ -2994,7 +2994,7 @@ int pre_retval; ssize_t write_retval = 0; - IXJ *j = get_ixj(NUM(file_p->f_dentry->d_inode->i_rdev)); + IXJ *j = get_ixj(NUM(file_p->f_dentry->d_inode)); pre_retval = ixj_PreWrite(j, 0L); switch (pre_retval) { @@ -4707,7 +4707,7 @@ { unsigned int mask = 0; - IXJ *j = get_ixj(NUM(file_p->f_dentry->d_inode->i_rdev)); + IXJ *j = get_ixj(NUM(file_p->f_dentry->d_inode)); poll_wait(file_p, &(j->poll_q), wait); if (j->read_buffer_ready > 0) @@ -6208,10 +6208,10 @@ IXJ_FILTER_RAW jfr; unsigned int raise, mant; - unsigned int minor = minor(inode->i_rdev); - int board = NUM(inode->i_rdev); + unsigned int minor = iminor(inode); + int board = NUM(inode); - IXJ *j = get_ixj(NUM(inode->i_rdev)); + IXJ *j = get_ixj(NUM(inode)); int retval = 0; @@ -6764,7 +6764,7 @@ static int ixj_fasync(int fd, struct file *file_p, int mode) { - IXJ *j = get_ixj(NUM(file_p->f_dentry->d_inode->i_rdev)); + IXJ *j = get_ixj(NUM(file_p->f_dentry->d_inode)); return fasync_helper(fd, file_p, mode, &j->async_queue); } diff -Nru a/drivers/telephony/phonedev.c b/drivers/telephony/phonedev.c --- a/drivers/telephony/phonedev.c Tue Sep 2 19:58:17 2003 +++ b/drivers/telephony/phonedev.c Tue Sep 2 19:58:17 2003 @@ -46,7 +46,7 @@ static int phone_open(struct inode *inode, struct file *file) { - unsigned int minor = minor(inode->i_rdev); + unsigned int minor = iminor(inode); int err = 0; struct phone_device *p; struct file_operations *old_fops, *new_fops = NULL; diff -Nru a/drivers/usb/class/audio.c b/drivers/usb/class/audio.c --- a/drivers/usb/class/audio.c Tue Sep 2 19:58:19 2003 +++ b/drivers/usb/class/audio.c Tue Sep 2 19:58:19 2003 @@ -1955,7 +1955,7 @@ static int usb_audio_open_mixdev(struct inode *inode, struct file *file) { - unsigned int minor = minor(inode->i_rdev); + unsigned int minor = iminor(inode); struct list_head *devs, *mdevs; struct usb_mixerdev *ms; struct usb_audio_state *s; @@ -2633,7 +2633,7 @@ static int usb_audio_open(struct inode *inode, struct file *file) { - unsigned int minor = minor(inode->i_rdev); + unsigned int minor = iminor(inode); DECLARE_WAITQUEUE(wait, current); struct list_head *devs, *adevs; struct usb_audiodev *as; diff -Nru a/drivers/usb/class/bluetty.c b/drivers/usb/class/bluetty.c --- a/drivers/usb/class/bluetty.c Tue Sep 2 19:58:18 2003 +++ b/drivers/usb/class/bluetty.c Tue Sep 2 19:58:18 2003 @@ -1,8 +1,8 @@ /* * bluetty.c Version 0.13 * - * Copyright (c) 2000, 2001 Greg Kroah-Hartman - * Copyright (c) 2000 Mark Douglas Corner + * Copyright (C) 2000, 2001 Greg Kroah-Hartman + * Copyright (C) 2000 Mark Douglas Corner * * USB Bluetooth TTY driver, based on the Bluetooth Spec version 1.0B * diff -Nru a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c --- a/drivers/usb/class/cdc-acm.c Tue Sep 2 19:58:17 2003 +++ b/drivers/usb/class/cdc-acm.c Tue Sep 2 19:58:17 2003 @@ -767,6 +767,7 @@ static int __init acm_init(void) { + int retval; acm_tty_driver = alloc_tty_driver(ACM_TTY_MINORS); if (!acm_tty_driver) return -ENOMEM; @@ -783,15 +784,17 @@ acm_tty_driver->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL; tty_set_operations(acm_tty_driver, &acm_ops); - if (tty_register_driver(acm_tty_driver)) { + retval = tty_register_driver(acm_tty_driver); + if (retval) { put_tty_driver(acm_tty_driver); - return -1; + return retval; } - if (usb_register(&acm_driver) < 0) { + retval = usb_register(&acm_driver); + if (retval) { tty_unregister_driver(acm_tty_driver); put_tty_driver(acm_tty_driver); - return -1; + return retval; } info(DRIVER_VERSION ":" DRIVER_DESC); diff -Nru a/drivers/usb/class/usb-midi.c b/drivers/usb/class/usb-midi.c --- a/drivers/usb/class/usb-midi.c Tue Sep 2 19:58:12 2003 +++ b/drivers/usb/class/usb-midi.c Tue Sep 2 19:58:12 2003 @@ -812,7 +812,7 @@ static int usb_midi_open(struct inode *inode, struct file *file) { - int minor = minor(inode->i_rdev); + int minor = iminor(inode); DECLARE_WAITQUEUE(wait, current); struct list_head *devs, *mdevs; struct usb_midi_state *s; @@ -2084,16 +2084,12 @@ /* ------------------------------------------------------------------------- */ -int __init usb_midi_init(void) +static int __init usb_midi_init(void) { - if ( usb_register(&usb_midi_driver) < 0 ) - return -1; - - return 0; - + return usb_register(&usb_midi_driver); } -void __exit usb_midi_exit(void) +static void __exit usb_midi_exit(void) { usb_deregister(&usb_midi_driver); } diff -Nru a/drivers/usb/class/usblp.c b/drivers/usb/class/usblp.c --- a/drivers/usb/class/usblp.c Tue Sep 2 19:58:13 2003 +++ b/drivers/usb/class/usblp.c Tue Sep 2 19:58:13 2003 @@ -318,7 +318,7 @@ static int usblp_open(struct inode *inode, struct file *file) { - int minor = minor(inode->i_rdev); + int minor = iminor(inode); struct usblp *usblp; struct usb_interface *intf; int retval; @@ -1150,10 +1150,13 @@ static int __init usblp_init(void) { - if (usb_register(&usblp_driver)) - return -1; + int retval; + retval = usb_register(&usblp_driver); + if (retval) + goto out; info(DRIVER_VERSION ": " DRIVER_DESC); - return 0; +out: + return retval; } static void __exit usblp_exit(void) diff -Nru a/drivers/usb/core/file.c b/drivers/usb/core/file.c --- a/drivers/usb/core/file.c Tue Sep 2 19:58:20 2003 +++ b/drivers/usb/core/file.c Tue Sep 2 19:58:20 2003 @@ -34,7 +34,7 @@ static int usb_open(struct inode * inode, struct file * file) { - int minor = minor(inode->i_rdev); + int minor = iminor(inode); struct file_operations *c; int err = -ENODEV; struct file_operations *old_fops, *new_fops = NULL; @@ -129,7 +129,7 @@ int retval = -EINVAL; int minor_base = class_driver->minor_base; int minor = 0; - char name[DEVICE_ID_SIZE]; + char name[BUS_ID_SIZE]; struct class_device *class_dev; char *temp; @@ -166,7 +166,7 @@ intf->minor = minor; /* handle the devfs registration */ - snprintf(name, DEVICE_ID_SIZE, class_driver->name, minor - minor_base); + snprintf(name, BUS_ID_SIZE, class_driver->name, minor - minor_base); devfs_mk_cdev(MKDEV(USB_MAJOR, minor), class_driver->mode, name); /* create a usb class device for this usb interface */ @@ -211,7 +211,7 @@ struct usb_class_driver *class_driver) { int minor_base = class_driver->minor_base; - char name[DEVICE_ID_SIZE]; + char name[BUS_ID_SIZE]; #ifdef CONFIG_USB_DYNAMIC_MINORS minor_base = 0; @@ -226,7 +226,7 @@ usb_minors[intf->minor] = NULL; spin_unlock (&minor_lock); - snprintf(name, DEVICE_ID_SIZE, class_driver->name, intf->minor - minor_base); + snprintf(name, BUS_ID_SIZE, class_driver->name, intf->minor - minor_base); devfs_remove (name); if (intf->class_dev) { diff -Nru a/drivers/usb/core/hcd-pci.c b/drivers/usb/core/hcd-pci.c --- a/drivers/usb/core/hcd-pci.c Tue Sep 2 19:58:15 2003 +++ b/drivers/usb/core/hcd-pci.c Tue Sep 2 19:58:15 2003 @@ -139,6 +139,7 @@ return retval; } } + // hcd zeroed everything hcd->regs = base; hcd->region = region; @@ -165,6 +166,7 @@ dev_err (hcd->controller, "can't reset\n"); goto clean_3; } + hcd->state = USB_STATE_HALT; pci_set_master (dev); #ifndef __sparc__ @@ -230,7 +232,8 @@ BUG (); hub = hcd->self.root_hub; - hcd->state = USB_STATE_QUIESCING; + if (HCD_IS_RUNNING (hcd->state)) + hcd->state = USB_STATE_QUIESCING; dev_dbg (hcd->controller, "roothub graceful disconnect\n"); usb_disconnect (&hub); @@ -287,8 +290,8 @@ pci_save_state (dev, hcd->pci_state); /* driver may want to disable DMA etc */ + hcd->state = USB_STATE_QUIESCING; retval = hcd->driver->suspend (hcd, state); - hcd->state = USB_STATE_SUSPENDED; } pci_set_power_state (dev, state); diff -Nru a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c --- a/drivers/usb/core/hcd.c Tue Sep 2 19:58:16 2003 +++ b/drivers/usb/core/hcd.c Tue Sep 2 19:58:16 2003 @@ -483,7 +483,7 @@ { struct urb *urb; struct usb_hcd *hcd; - int length; + int length = 0; unsigned long flags; urb = (struct urb *) ptr; @@ -499,7 +499,9 @@ return; } - length = hcd->driver->hub_status_data (hcd, urb->transfer_buffer); + if (!HCD_IS_SUSPENDED (hcd->state)) + length = hcd->driver->hub_status_data ( + hcd, urb->transfer_buffer); /* complete the status urb, or retrigger the timer */ spin_lock (&hcd_data_lock); @@ -1097,6 +1099,8 @@ static int hcd_get_frame_number (struct usb_device *udev) { struct usb_hcd *hcd = (struct usb_hcd *)udev->bus->hcpriv; + if (!HCD_IS_RUNNING (hcd->state)) + return -ESHUTDOWN; return hcd->driver->get_frame_number (hcd); } @@ -1193,6 +1197,12 @@ goto done; } + /* running ~= hc unlink handshake works (irq, timer, etc) + * halted ~= no unlink handshake is needed + * suspended, resuming == should never happen + */ + WARN_ON (!HCD_IS_RUNNING (hcd->state) && hcd->state != USB_STATE_HALT); + if (!urb->hcpriv) { retval = -EINVAL; goto done; @@ -1208,6 +1218,17 @@ goto done; } + /* PCI IRQ setup can easily be broken so that USB controllers + * never get completion IRQs ... maybe even the ones we need to + * finish unlinking the initial failed usb_set_address(). + */ + if (!hcd->saw_irq) { + dev_warn (hcd->controller, "Unlink after no-IRQ? " + "Different ACPI or APIC settings may help." + "\n"); + hcd->saw_irq = 1; + } + /* maybe set up to block until the urb's completion fires. the * lower level hcd code is always async, locking on urb->status * updates; an intercepted completion unblocks us. @@ -1287,6 +1308,8 @@ dev = udev->hcpriv; hcd = udev->bus->hcpriv; + WARN_ON (!HCD_IS_RUNNING (hcd->state) && hcd->state != USB_STATE_HALT); + local_irq_disable (); rescan: @@ -1483,6 +1506,7 @@ if (unlikely (hcd->state == USB_STATE_HALT)) /* irq sharing? */ return IRQ_NONE; + hcd->saw_irq = 1; hcd->driver->irq (hcd, r); if (hcd->state != start && hcd->state == USB_STATE_HALT) usb_hc_died (hcd); diff -Nru a/drivers/usb/core/hcd.h b/drivers/usb/core/hcd.h --- a/drivers/usb/core/hcd.h Tue Sep 2 19:58:14 2003 +++ b/drivers/usb/core/hcd.h Tue Sep 2 19:58:14 2003 @@ -73,6 +73,7 @@ * hardware info/state */ struct hc_driver *driver; /* hw-specific hooks */ + unsigned saw_irq : 1; int irq; /* irq allocated */ void *regs; /* device memory/io */ struct device *controller; /* handle to hardware */ @@ -89,13 +90,11 @@ int state; # define __ACTIVE 0x01 -# define __SLEEPY 0x02 # define __SUSPEND 0x04 # define __TRANSIENT 0x80 # define USB_STATE_HALT 0 # define USB_STATE_RUNNING (__ACTIVE) -# define USB_STATE_READY (__ACTIVE|__SLEEPY) # define USB_STATE_QUIESCING (__SUSPEND|__TRANSIENT|__ACTIVE) # define USB_STATE_RESUMING (__SUSPEND|__TRANSIENT) # define USB_STATE_SUSPENDED (__SUSPEND) diff -Nru a/drivers/usb/core/inode.c b/drivers/usb/core/inode.c --- a/drivers/usb/core/inode.c Tue Sep 2 19:58:13 2003 +++ b/drivers/usb/core/inode.c Tue Sep 2 19:58:13 2003 @@ -4,7 +4,7 @@ * inode.c -- Inode/Dentry functions for the USB device file system. * * Copyright (C) 2000 Thomas Sailer (sailer@ife.ee.ethz.ch) - * Copyright (c) 2001,2002 Greg Kroah-Hartman (greg@kroah.com) + * Copyright (C) 2001,2002 Greg Kroah-Hartman (greg@kroah.com) * * 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 diff -Nru a/drivers/usb/core/message.c b/drivers/usb/core/message.c --- a/drivers/usb/core/message.c Tue Sep 2 19:58:14 2003 +++ b/drivers/usb/core/message.c Tue Sep 2 19:58:14 2003 @@ -246,21 +246,22 @@ io->status = urb->status; /* the previous urbs, and this one, completed already. - * unlink the later ones so they won't rx/tx bad data, - * - * FIXME don't bother unlinking urbs that haven't yet been - * submitted; those non-error cases shouldn't be syslogged + * unlink pending urbs so they won't rx/tx bad data. */ for (i = 0, found = 0; i < io->entries; i++) { + if (!io->urbs [i]) + continue; if (found) { status = usb_unlink_urb (io->urbs [i]); - if (status && status != -EINPROGRESS) - err ("sg_complete, unlink --> %d", - status); + if (status != -EINPROGRESS && status != -EBUSY) + dev_err (&io->dev->dev, + "%s, unlink --> %d\n", + __FUNCTION__, status); } else if (urb == io->urbs [i]) found = 1; } } + urb->dev = 0; /* on the last completion, signal usb_sg_wait() */ io->bytes += urb->actual_length; @@ -356,7 +357,7 @@ goto nomem; } - io->urbs [i]->dev = dev; + io->urbs [i]->dev = 0; io->urbs [i]->pipe = pipe; io->urbs [i]->interval = period; io->urbs [i]->transfer_flags = urb_flags; @@ -448,6 +449,7 @@ for (i = 0; i < io->entries && !io->status; i++) { int retval; + io->urbs [i]->dev = io->dev; retval = usb_submit_urb (io->urbs [i], SLAB_ATOMIC); /* after we submit, let completions or cancelations fire; @@ -459,9 +461,9 @@ case -ENXIO: // hc didn't queue this one case -EAGAIN: case -ENOMEM: + io->urbs [i]->dev = 0; retval = 0; i--; - // FIXME: should it usb_sg_cancel() on INTERRUPT? yield (); break; @@ -477,8 +479,10 @@ /* fail any uncompleted urbs */ default: + io->urbs [i]->dev = 0; io->urbs [i]->status = retval; - dbg ("usb_sg_msg, submit --> %d", retval); + dev_dbg (&io->dev->dev, "%s, submit --> %d\n", + __FUNCTION__, retval); usb_sg_cancel (io); } spin_lock_irqsave (&io->lock, flags); @@ -521,9 +525,9 @@ if (!io->urbs [i]->dev) continue; retval = usb_unlink_urb (io->urbs [i]); - if (retval && retval != -EINPROGRESS) - warn ("usb_sg_cancel, unlink --> %d", retval); - // FIXME don't warn on "not yet submitted" error + if (retval != -EINPROGRESS && retval != -EBUSY) + dev_warn (&io->dev->dev, "%s, unlink --> %d\n", + __FUNCTION__, retval); } } spin_unlock_irqrestore (&io->lock, flags); diff -Nru a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c --- a/drivers/usb/core/usb.c Tue Sep 2 19:58:16 2003 +++ b/drivers/usb/core/usb.c Tue Sep 2 19:58:16 2003 @@ -991,8 +991,8 @@ * * This call is synchronous, and may not be used in an interrupt context. * - * Only hub drivers (including virtual root hub drivers for host - * controllers) should ever call this. + * Only the hub driver should ever call this; root hub registration + * uses it only indirectly. */ #define NEW_DEVICE_RETRYS 2 #define SET_ADDRESS_RETRYS 2 @@ -1417,11 +1417,46 @@ usb_pipein (pipe) ? DMA_FROM_DEVICE : DMA_TO_DEVICE); } +static int usb_device_suspend(struct device *dev, u32 state) +{ + struct usb_interface *intf; + struct usb_driver *driver; + + if ((dev->driver == &usb_generic_driver) || + (dev->driver_data == &usb_generic_driver_data)) + return 0; + + intf = to_usb_interface(dev); + driver = to_usb_driver(dev->driver); + + if (driver && driver->suspend) + return driver->suspend(intf, state); + return 0; +} + +static int usb_device_resume(struct device *dev) +{ + struct usb_interface *intf; + struct usb_driver *driver; + + if ((dev->driver == &usb_generic_driver) || + (dev->driver_data == &usb_generic_driver_data)) + return 0; + + intf = to_usb_interface(dev); + driver = to_usb_driver(dev->driver); + + if (driver && driver->resume) + return driver->resume(intf); + return 0; +} struct bus_type usb_bus_type = { .name = "usb", .match = usb_device_match, .hotplug = usb_hotplug, + .suspend = usb_device_suspend, + .resume = usb_device_resume, }; #ifndef MODULE @@ -1509,7 +1544,6 @@ EXPORT_SYMBOL(usb_find_interface); EXPORT_SYMBOL(usb_ifnum_to_if); -EXPORT_SYMBOL(usb_new_device); EXPORT_SYMBOL(usb_reset_device); EXPORT_SYMBOL(usb_disconnect); diff -Nru a/drivers/usb/gadget/net2280.c b/drivers/usb/gadget/net2280.c --- a/drivers/usb/gadget/net2280.c Tue Sep 2 19:58:13 2003 +++ b/drivers/usb/gadget/net2280.c Tue Sep 2 19:58:13 2003 @@ -30,6 +30,7 @@ /* * Copyright (C) 2003 David Brownell + * Copyright (C) 2003 NetChip Technologies * * 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 @@ -49,6 +50,7 @@ #define DEBUG 1 // #define VERBOSE /* extra debug messages (success too) */ +#include #include #include #include @@ -76,7 +78,7 @@ #define DRIVER_DESC "NetChip 2280 USB Peripheral Controller" -#define DRIVER_VERSION "May Day 2003" +#define DRIVER_VERSION "Bastille Day 2003" #define DMA_ADDR_INVALID (~(dma_addr_t)0) #define EP_DONTUSE 13 /* nonzero */ @@ -448,7 +450,7 @@ struct net2280_ep *ep; ep = container_of (_ep, struct net2280_ep, ep); - if (!_ep || (!ep->desc && ep->num != 0)) + if (!_ep) return 0; *dma = DMA_ADDR_INVALID; @@ -1344,11 +1346,12 @@ s = "(none)"; /* Main Control Registers */ - t = snprintf (next, size, "%s " DRIVER_VERSION "\n" + t = snprintf (next, size, "%s version " DRIVER_VERSION + ", chiprev %04x\n" "devinit %03x fifoctl %08x gadget '%s'\n" "pci irqenb0 %02x irqenb1 %08x " "irqstat0 %04x irqstat1 %08x\n", - driver_name, + driver_name, dev->chiprev, readl (&dev->regs->devinit), readl (&dev->regs->fifoctl), s, @@ -1393,16 +1396,33 @@ continue; t1 = readl (&ep->regs->ep_cfg); + t2 = readl (&ep->regs->ep_rsp) & 0xff; t = snprintf (next, size, - "%s\tcfg %05x rsp %02x enb %02x ", - ep->ep.name, t1, - readl (&ep->regs->ep_rsp) & 0xff, + "%s\tcfg %05x rsp (%02x) %s%s%s%s%s%s%s%s" + "irqenb %02x\n", + ep->ep.name, t1, t2, + (t2 & (1 << CLEAR_NAK_OUT_PACKETS)) + ? "NAK " : "", + (t2 & (1 << CLEAR_EP_HIDE_STATUS_PHASE)) + ? "hide " : "", + (t2 & (1 << CLEAR_EP_FORCE_CRC_ERROR)) + ? "CRC " : "", + (t2 & (1 << CLEAR_INTERRUPT_MODE)) + ? "interrupt " : "", + (t2 & (1<regs->ep_irqenb)); size -= t; next += t; t = snprintf (next, size, - "stat %08x avail %04x " + "\tstat %08x avail %04x " "(ep%d%s-%s)%s\n", readl (&ep->regs->ep_stat), readl (&ep->regs->ep_avail), @@ -1796,6 +1816,7 @@ dev->ep [i].irqs = 0; /* hook up the driver ... */ + driver->driver.bus = 0; dev->driver = driver; dev->gadget.dev.driver = &driver->driver; retval = driver->bind (&dev->gadget); @@ -1807,10 +1828,6 @@ return retval; } - // FIXME - // driver_register (&driver->driver); - // device_register (&dev->gadget.dev); - device_create_file (&dev->pdev->dev, &dev_attr_function); device_create_file (&dev->pdev->dev, &dev_attr_queues); @@ -1877,10 +1894,6 @@ device_remove_file (&dev->pdev->dev, &dev_attr_function); device_remove_file (&dev->pdev->dev, &dev_attr_queues); - // FIXME - // device_unregister() - // driver_unregister (&driver->driver); - DEBUG (dev, "unregistered driver '%s'\n", driver->driver.name); return 0; } @@ -2049,9 +2062,9 @@ /* maybe advance queue to next request */ if (ep->num == 0) { - /* FIXME need mechanism (request flag?) so control OUT - * can decide to stall ep0 after that done() returns, - * from non-irq context + /* NOTE: net2280 could let gadget driver start the + * status stage later. since not all controllers let + * them control that, the api doesn't (yet) allow it. */ if (!ep->stopped) allow_status (ep); @@ -2174,6 +2187,8 @@ /* watch control traffic at the token level, and force * synchronization before letting the status stage happen. + * FIXME ignore tokens we'll NAK, until driver responds. + * that'll mean a lot less irqs for some drivers. */ ep->is_in = (u.r.bRequestType & USB_DIR_IN) != 0; if (ep->is_in) @@ -2417,6 +2432,28 @@ if ((tmp & (1 << DMA_SCATTER_GATHER_ENABLE)) == 0 || (tmp & (1 << DMA_ENABLE)) == 0) restart_dma (ep); +#ifdef USE_DMA_CHAINING + else if (ep->desc->bEndpointAddress & USB_DIR_IN) { + struct net2280_request *req; + u32 dmacount; + + /* the descriptor at the head of the chain + * may still have VALID_BIT clear; that's + * used to trigger changing DMA_FIFO_VALIDATE + * (affects automagic zlp writes). + */ + req = list_entry (ep->queue.next, + struct net2280_request, queue); + dmacount = req->td->dmacount; + dmacount &= __constant_cpu_to_le32 ( + (1 << VALID_BIT) + | DMA_BYTE_COUNT_MASK); + if (dmacount && (dmacount & valid_bit) == 0) { + stop_dma (ep->dma); + restart_dma (ep); + } + } +#endif } ep->irqs++; } @@ -2458,6 +2495,13 @@ /*-------------------------------------------------------------------------*/ +static void gadget_release (struct device *_dev) +{ + struct net2280 *dev = dev_get_drvdata (_dev); + + kfree (dev); +} + /* tear down the binding between this driver and the pci device */ static void net2280_remove (struct pci_dev *pdev) @@ -2493,12 +2537,12 @@ pci_resource_len (pdev, 0)); if (dev->enabled) pci_disable_device (pdev); + device_unregister (&dev->gadget.dev); device_remove_file (&pdev->dev, &dev_attr_registers); pci_set_drvdata (pdev, 0); - INFO (dev, "unbind from pci %s\n", pci_name(pdev)); + INFO (dev, "unbind\n"); - kfree (dev); the_controller = 0; } @@ -2518,7 +2562,7 @@ * usb_gadget_driver_{register,unregister}() must change. */ if (the_controller) { - WARN (the_controller, "ignoring %s\n", pci_name(pdev)); + dev_warn (&pdev->dev, "ignoring\n"); return -EBUSY; } @@ -2534,9 +2578,11 @@ dev->pdev = pdev; dev->gadget.ops = &net2280_ops; - strcpy (dev->gadget.dev.bus_id, pci_name(pdev)); + /* the "gadget" abstracts/virtualizes the controller */ + strcpy (dev->gadget.dev.bus_id, "gadget"); dev->gadget.dev.parent = &pdev->dev; dev->gadget.dev.dma_mask = pdev->dev.dma_mask; + dev->gadget.dev.release = gadget_release; dev->gadget.name = driver_name; /* now all the pci goodies ... */ @@ -2650,6 +2696,7 @@ INFO (dev, "version: %s\n", bufp); the_controller = dev; + device_register (&dev->gadget.dev); device_create_file (&pdev->dev, &dev_attr_registers); return 0; diff -Nru a/drivers/usb/gadget/net2280.h b/drivers/usb/gadget/net2280.h --- a/drivers/usb/gadget/net2280.h Tue Sep 2 19:58:17 2003 +++ b/drivers/usb/gadget/net2280.h Tue Sep 2 19:58:17 2003 @@ -389,6 +389,7 @@ u32 ep_rsp; #define SET_NAK_OUT_PACKETS 15 #define SET_EP_HIDE_STATUS_PHASE 14 +#define SET_EP_FORCE_CRC_ERROR 13 #define SET_INTERRUPT_MODE 12 #define SET_CONTROL_STATUS_PHASE_HANDSHAKE 11 #define SET_NAK_OUT_PACKETS_MODE 10 @@ -396,6 +397,7 @@ #define SET_ENDPOINT_HALT 8 #define CLEAR_NAK_OUT_PACKETS 7 #define CLEAR_EP_HIDE_STATUS_PHASE 6 +#define CLEAR_EP_FORCE_CRC_ERROR 5 #define CLEAR_INTERRUPT_MODE 4 #define CLEAR_CONTROL_STATUS_PHASE_HANDSHAKE 3 #define CLEAR_NAK_OUT_PACKETS_MODE 2 @@ -476,6 +478,9 @@ #define REG_CHIPREV 0x03 /* in bcd */ #define REG_HS_NAK_RATE 0x0a /* NAK per N uframes */ +#define CHIPREV_1 0x0100 +#define CHIPREV_1A 0x0110 + #ifdef __KERNEL__ /* ep a-f highspeed and fullspeed maxpacket, addresses @@ -529,24 +534,6 @@ ep->stopped = 1; } -static inline void set_halt (struct net2280_ep *ep) -{ - /* ep0 and bulk/intr endpoints */ - writel ( (1 << CLEAR_CONTROL_STATUS_PHASE_HANDSHAKE) - /* set NAK_OUT for erratum 0114 */ - | (1 << SET_NAK_OUT_PACKETS) - | (1 << SET_ENDPOINT_HALT) - , &ep->regs->ep_rsp); -} - -static inline void clear_halt (struct net2280_ep *ep) -{ - /* bulk/intr endpoints */ - writel ( (1 << CLEAR_ENDPOINT_HALT) - | (1 << CLEAR_ENDPOINT_TOGGLE) - , &ep->regs->ep_rsp); -} - /* count (<= 4) bytes in the next fifo write will be valid */ static inline void set_fifo_bytecount (struct net2280_ep *ep, unsigned count) { @@ -588,6 +575,28 @@ struct pci_pool *requests; // statistics... }; + +static inline void set_halt (struct net2280_ep *ep) +{ + /* ep0 and bulk/intr endpoints */ + writel ( (1 << CLEAR_CONTROL_STATUS_PHASE_HANDSHAKE) + /* set NAK_OUT for erratum 0114 */ + | ((ep->dev->chiprev == CHIPREV_1) << SET_NAK_OUT_PACKETS) + | (1 << SET_ENDPOINT_HALT) + , &ep->regs->ep_rsp); +} + +static inline void clear_halt (struct net2280_ep *ep) +{ + /* ep0 and bulk/intr endpoints */ + writel ( (1 << CLEAR_ENDPOINT_HALT) + | (1 << CLEAR_ENDPOINT_TOGGLE) + /* unless the gadget driver left a short packet in the + * fifo, this reverses the erratum 0114 workaround. + */ + | ((ep->dev->chiprev == CHIPREV_1) << CLEAR_NAK_OUT_PACKETS) + , &ep->regs->ep_rsp); +} #ifdef USE_RDK_LEDS diff -Nru a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c --- a/drivers/usb/host/ehci-hcd.c Tue Sep 2 19:58:17 2003 +++ b/drivers/usb/host/ehci-hcd.c Tue Sep 2 19:58:17 2003 @@ -41,7 +41,6 @@ #include #include -#include #include "../core/hcd.h" #include @@ -232,7 +231,6 @@ ehci->hcd.state = USB_STATE_HALT; return; } - ehci->hcd.state = USB_STATE_READY; } /*-------------------------------------------------------------------------*/ @@ -482,7 +480,7 @@ ehci->reboot_notifier.notifier_call = ehci_reboot; register_reboot_notifier (&ehci->reboot_notifier); - ehci->hcd.state = USB_STATE_READY; + ehci->hcd.state = USB_STATE_RUNNING; writel (FLAG_CF, &ehci->regs->configured_flag); readl (&ehci->regs->command); /* unblock posted write */ @@ -626,7 +624,7 @@ /* resume HC and each port */ // restore pci FLADJ value // khubd and drivers will set HC running, if needed; - hcd->state = USB_STATE_READY; + hcd->state = USB_STATE_RUNNING; // FIXME Philips/Intel/... etc don't really have a "READY" // state ... turn on CMD_RUN too for (i = 0; i < ports; i++) { @@ -979,21 +977,12 @@ /* EHCI spec says PCI is required. */ /* PCI driver selection metadata; PCI hotplugging uses this */ -static struct pci_device_id pci_ids [] = { { - +static const struct pci_device_id pci_ids [] = { { /* handle any USB 2.0 EHCI controller */ - - .class = ((PCI_CLASS_SERIAL_USB << 8) | 0x20), - .class_mask = ~0, + PCI_DEVICE_CLASS(((PCI_CLASS_SERIAL_USB << 8) | 0x20), ~0), .driver_data = (unsigned long) &ehci_driver, - - /* no matter who makes it */ - .vendor = PCI_ANY_ID, - .device = PCI_ANY_ID, - .subvendor = PCI_ANY_ID, - .subdevice = PCI_ANY_ID, - -}, { /* end: all zeroes */ } + }, + { /* end: all zeroes */ } }; MODULE_DEVICE_TABLE (pci, pci_ids); diff -Nru a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c --- a/drivers/usb/host/ohci-hcd.c Tue Sep 2 19:58:13 2003 +++ b/drivers/usb/host/ohci-hcd.c Tue Sep 2 19:58:13 2003 @@ -529,7 +529,7 @@ /* connect the virtual root hub */ bus = hcd_to_bus (&ohci->hcd); bus->root_hub = udev = usb_alloc_dev (NULL, bus); - ohci->hcd.state = USB_STATE_READY; + ohci->hcd.state = USB_STATE_RUNNING; if (!udev) { disable (ohci); ohci->hc_control &= ~OHCI_CTRL_HCFS; diff -Nru a/drivers/usb/host/ohci-pci.c b/drivers/usb/host/ohci-pci.c --- a/drivers/usb/host/ohci-pci.c Tue Sep 2 19:58:17 2003 +++ b/drivers/usb/host/ohci-pci.c Tue Sep 2 19:58:17 2003 @@ -30,6 +30,15 @@ /*-------------------------------------------------------------------------*/ +static int +ohci_pci_reset (struct usb_hcd *hcd) +{ + struct ohci_hcd *ohci = hcd_to_ohci (hcd); + + ohci->regs = hcd->regs; + return hc_reset (ohci); +} + static int __devinit ohci_pci_start (struct usb_hcd *hcd) { @@ -89,12 +98,6 @@ ohci_stop (hcd); return ret; } - ohci->regs = hcd->regs; - - if (hc_reset (ohci) < 0) { - ohci_stop (hcd); - return -ENODEV; - } if (hc_start (ohci) < 0) { ohci_err (ohci, "can't start\n"); @@ -264,7 +267,7 @@ if (ohci->ed_bulktail) ohci->hc_control |= OHCI_CTRL_BLE; } - hcd->state = USB_STATE_READY; + hcd->state = USB_STATE_RUNNING; writel (ohci->hc_control, &ohci->regs->control); /* trigger a start-frame interrupt (why?) */ @@ -315,6 +318,7 @@ /* * basic lifecycle operations */ + .reset = ohci_pci_reset, .start = ohci_pci_start, #ifdef CONFIG_PM .suspend = ohci_pci_suspend, @@ -351,18 +355,9 @@ static const struct pci_device_id pci_ids [] = { { - /* handle any USB OHCI controller */ - .class = (PCI_CLASS_SERIAL_USB << 8) | 0x10, - .class_mask = ~0, + PCI_DEVICE_CLASS((PCI_CLASS_SERIAL_USB << 8) | 0x10, ~0), .driver_data = (unsigned long) &ohci_pci_hc_driver, - - /* no matter who makes it */ - .vendor = PCI_ANY_ID, - .device = PCI_ANY_ID, - .subvendor = PCI_ANY_ID, - .subdevice = PCI_ANY_ID, - }, { /* end: all zeroes */ } }; MODULE_DEVICE_TABLE (pci, pci_ids); diff -Nru a/drivers/usb/host/ohci-q.c b/drivers/usb/host/ohci-q.c --- a/drivers/usb/host/ohci-q.c Tue Sep 2 19:58:19 2003 +++ b/drivers/usb/host/ohci-q.c Tue Sep 2 19:58:19 2003 @@ -1013,10 +1013,22 @@ if (list_empty (&ed->td_list)) ed_deschedule (ohci, ed); /* ... reenabling halted EDs only after fault cleanup */ - else if (!(ed->hwINFO & ED_DEQUEUE)) { + else if ((ed->hwINFO & (ED_SKIP | ED_DEQUEUE)) == ED_SKIP) { td = list_entry (ed->td_list.next, struct td, td_list); - if (!(td->hwINFO & TD_DONE)) + if (!(td->hwINFO & TD_DONE)) { ed->hwINFO &= ~ED_SKIP; + /* ... hc may need waking-up */ + switch (ed->type) { + case PIPE_CONTROL: + writel (OHCI_CLF, + &ohci->regs->cmdstatus); + break; + case PIPE_BULK: + writel (OHCI_BLF, + &ohci->regs->cmdstatus); + break; + } + } } td = td_next; diff -Nru a/drivers/usb/host/ohci-sa1111.c b/drivers/usb/host/ohci-sa1111.c --- a/drivers/usb/host/ohci-sa1111.c Tue Sep 2 19:58:16 2003 +++ b/drivers/usb/host/ohci-sa1111.c Tue Sep 2 19:58:16 2003 @@ -352,9 +352,8 @@ /*-------------------------------------------------------------------------*/ -static int ohci_hcd_sa1111_drv_probe(struct device *_dev) +static int ohci_hcd_sa1111_drv_probe(struct sa1111_dev *dev) { - struct sa1111_dev *dev = SA1111_DEV(_dev); struct usb_hcd *hcd = NULL; int ret; @@ -364,43 +363,29 @@ ret = usb_hcd_sa1111_probe(&ohci_sa1111_hc_driver, &hcd, dev); if (ret == 0) - dev->dev.driver_data = hcd; + sa1111_set_drvdata(dev, hcd); return ret; } -static int ohci_hcd_sa1111_drv_remove(struct device *_dev) +static int ohci_hcd_sa1111_drv_remove(struct sa1111_dev *dev) { - struct sa1111_dev *dev = SA1111_DEV(_dev); - struct usb_hcd *hcd = dev->dev.driver_data; + struct usb_hcd *hcd = sa1111_get_drvdata(dev); usb_hcd_sa1111_remove(hcd, dev); - dev->dev.driver_data = NULL; + sa1111_set_drvdata(dev, NULL); return 0; } -static int ohci_hcd_sa1111_drv_suspend(struct device *dev, u32 state, u32 level) -{ - return 0; -} - -static int ohci_hcd_sa1111_drv_resume(struct device *dev, u32 level) -{ - return 0; -} - static struct sa1111_driver ohci_hcd_sa1111_driver = { .drv = { - .name = "sa1111-ohci", - .bus = &sa1111_bus_type, - .probe = ohci_hcd_sa1111_drv_probe, - .remove = ohci_hcd_sa1111_drv_remove, - .suspend = ohci_hcd_sa1111_drv_suspend, - .resume = ohci_hcd_sa1111_drv_resume, + .name = "sa1111-ohci", }, - .devid = SA1111_DEVID_USB, + .devid = SA1111_DEVID_USB, + .probe = ohci_hcd_sa1111_drv_probe, + .remove = ohci_hcd_sa1111_drv_remove, }; static int __init ohci_hcd_sa1111_init (void) @@ -409,12 +394,12 @@ dbg ("block sizes: ed %d td %d", sizeof (struct ed), sizeof (struct td)); - return driver_register(&ohci_hcd_sa1111_driver.drv); + return sa1111_driver_register(&ohci_hcd_sa1111_driver); } static void __exit ohci_hcd_sa1111_cleanup (void) { - driver_unregister(&ohci_hcd_sa1111_driver.drv); + sa1111_driver_unregister(&ohci_hcd_sa1111_driver); } module_init (ohci_hcd_sa1111_init); diff -Nru a/drivers/usb/host/uhci-hcd.c b/drivers/usb/host/uhci-hcd.c --- a/drivers/usb/host/uhci-hcd.c Tue Sep 2 19:58:18 2003 +++ b/drivers/usb/host/uhci-hcd.c Tue Sep 2 19:58:18 2003 @@ -2099,7 +2099,7 @@ uhci->state_end = jiffies + HZ; outw(USBCMD_RS | USBCMD_CF | USBCMD_MAXP, io_addr + USBCMD); - uhci->hcd.state = USB_STATE_READY; + uhci->hcd.state = USB_STATE_RUNNING; } /* @@ -2143,6 +2143,20 @@ #endif } +static int uhci_reset(struct usb_hcd *hcd) +{ + struct uhci_hcd *uhci = hcd_to_uhci(hcd); + + uhci->io_addr = (unsigned long) hcd->regs; + + /* Maybe kick BIOS off this hardware. Then reset, so we won't get + * interrupts from any previous setup. + */ + pci_write_config_word(hcd->pdev, USBLEGSUP, USBLEGSUP_DEFAULT); + reset_hc(uhci); + return 0; +} + /* * Allocate a frame list, and then setup the skeleton * @@ -2159,7 +2173,7 @@ * - The fourth queue is the bandwidth reclamation queue, which loops back * to the high speed control queue. */ -static int __devinit uhci_start(struct usb_hcd *hcd) +static int uhci_start(struct usb_hcd *hcd) { struct uhci_hcd *uhci = hcd_to_uhci(hcd); int retval = -EBUSY; @@ -2171,7 +2185,6 @@ struct proc_dir_entry *ent; #endif - uhci->io_addr = (unsigned long) hcd->regs; io_size = pci_resource_len(hcd->pdev, hcd->region); #ifdef CONFIG_PROC_FS @@ -2188,10 +2201,6 @@ uhci->proc_entry = ent; #endif - /* Reset here so we don't get any interrupts from an old setup */ - /* or broken setup */ - reset_hc(uhci); - uhci->fsbr = 0; uhci->fsbrtimeout = 0; @@ -2343,9 +2352,6 @@ init_stall_timer(hcd); - /* disable legacy emulation */ - pci_write_config_word(hcd->pdev, USBLEGSUP, USBLEGSUP_DEFAULT); - udev->speed = USB_SPEED_FULL; if (usb_register_root_hub(udev, &hcd->pdev->dev) != 0) { @@ -2446,7 +2452,7 @@ reset_hc(uhci); start_hc(uhci); } - uhci->hcd.state = USB_STATE_READY; + uhci->hcd.state = USB_STATE_RUNNING; return 0; } #endif @@ -2484,6 +2490,7 @@ .flags = HCD_USB11, /* Basic lifecycle operations */ + .reset = uhci_reset, .start = uhci_start, #ifdef CONFIG_PM .suspend = uhci_suspend, @@ -2504,18 +2511,9 @@ }; static const struct pci_device_id uhci_pci_ids[] = { { - /* handle any USB UHCI controller */ - .class = ((PCI_CLASS_SERIAL_USB << 8) | 0x00), - .class_mask = ~0, + PCI_DEVICE_CLASS(((PCI_CLASS_SERIAL_USB << 8) | 0x00), ~0), .driver_data = (unsigned long) &uhci_driver, - - /* no matter who makes it */ - .vendor = PCI_ANY_ID, - .device = PCI_ANY_ID, - .subvendor = PCI_ANY_ID, - .subdevice = PCI_ANY_ID, - }, { /* end: all zeroes */ } }; diff -Nru a/drivers/usb/image/mdc800.c b/drivers/usb/image/mdc800.c --- a/drivers/usb/image/mdc800.c Tue Sep 2 19:58:16 2003 +++ b/drivers/usb/image/mdc800.c Tue Sep 2 19:58:16 2003 @@ -977,8 +977,9 @@ #define try_free_mem(A) if (A != 0) { kfree (A); A=0; } #define try_free_urb(A) if (A != 0) { usb_free_urb (A); A=0; } -int __init usb_mdc800_init (void) +static int __init usb_mdc800_init (void) { + int retval = -ENODEV; /* Allocate Memory */ try (mdc800=kmalloc (sizeof (struct mdc800_data), GFP_KERNEL)); @@ -1005,7 +1006,8 @@ try (mdc800->write_urb=usb_alloc_urb (0, GFP_KERNEL)); /* Register the driver */ - if (usb_register (&mdc800_usb_driver) < 0) + retval = usb_register(&mdc800_usb_driver); + if (retval) goto cleanup_on_fail; info (DRIVER_VERSION ":" DRIVER_DESC); @@ -1031,11 +1033,11 @@ kfree (mdc800); } mdc800=0; - return -1; + return retval; } -void __exit usb_mdc800_cleanup (void) +static void __exit usb_mdc800_cleanup (void) { usb_deregister (&mdc800_usb_driver); diff -Nru a/drivers/usb/image/scanner.h b/drivers/usb/image/scanner.h --- a/drivers/usb/image/scanner.h Tue Sep 2 19:58:15 2003 +++ b/drivers/usb/image/scanner.h Tue Sep 2 19:58:15 2003 @@ -313,7 +313,7 @@ #define IS_EP_BULK_OUT(ep) (IS_EP_BULK(ep) && ((ep)->bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_DIR_OUT) #define IS_EP_INTR(ep) ((ep)->bmAttributes == USB_ENDPOINT_XFER_INT ? 1 : 0) -#define USB_SCN_MINOR(X) minor((X)->i_rdev) +#define USB_SCN_MINOR(X) iminor(X) #ifdef DEBUG #define SCN_DEBUG(X) X diff -Nru a/drivers/usb/input/hid-core.c b/drivers/usb/input/hid-core.c --- a/drivers/usb/input/hid-core.c Tue Sep 2 19:58:16 2003 +++ b/drivers/usb/input/hid-core.c Tue Sep 2 19:58:16 2003 @@ -1328,6 +1328,7 @@ #define USB_DEVICE_ID_ATEN_CS124U 0x2202 #define USB_DEVICE_ID_ATEN_2PORTKVM 0x2204 #define USB_DEVICE_ID_ATEN_4PORTKVM 0x2205 +#define USB_DEVICE_ID_ATEN_4PORTKVMC 0x2208 #define USB_VENDOR_ID_TOPMAX 0x0663 #define USB_DEVICE_ID_TOPMAX_COBRAPAD 0x0103 @@ -1386,6 +1387,7 @@ { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_CS124U, HID_QUIRK_NOGET }, { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_2PORTKVM, HID_QUIRK_NOGET }, { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_4PORTKVM, HID_QUIRK_NOGET }, + { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_4PORTKVMC, HID_QUIRK_NOGET }, { USB_VENDOR_ID_MGE, USB_DEVICE_ID_MGE_UPS, HID_QUIRK_HIDDEV }, { USB_VENDOR_ID_MGE, USB_DEVICE_ID_MGE_UPS1, HID_QUIRK_HIDDEV }, { USB_VENDOR_ID_TOPMAX, USB_DEVICE_ID_TOPMAX_COBRAPAD, HID_QUIRK_BADPAD }, @@ -1691,11 +1693,20 @@ static int __init hid_init(void) { - hiddev_init(); - usb_register(&hid_driver); + int retval; + retval = hiddev_init(); + if (retval) + goto hiddev_init_fail; + retval = usb_register(&hid_driver); + if (retval) + goto usb_register_fail; info(DRIVER_VERSION ":" DRIVER_DESC); return 0; +usb_register_fail: + hiddev_exit(); +hiddev_init_fail: + return retval; } static void __exit hid_exit(void) diff -Nru a/drivers/usb/input/hiddev.c b/drivers/usb/input/hiddev.c --- a/drivers/usb/input/hiddev.c Tue Sep 2 19:58:15 2003 +++ b/drivers/usb/input/hiddev.c Tue Sep 2 19:58:15 2003 @@ -271,7 +271,7 @@ static int hiddev_open(struct inode * inode, struct file * file) { struct hiddev_list *list; - int i = minor(inode->i_rdev) - HIDDEV_MINOR_BASE; + int i = iminor(inode) - HIDDEV_MINOR_BASE; if (i >= HIDDEV_MINORS || !hiddev_table[i]) return -ENODEV; @@ -795,8 +795,7 @@ int __init hiddev_init(void) { devfs_mk_dir("usb/hid"); - usb_register(&hiddev_driver); - return 0; + return usb_register(&hiddev_driver); } void __exit hiddev_exit(void) diff -Nru a/drivers/usb/input/kbtab.c b/drivers/usb/input/kbtab.c --- a/drivers/usb/input/kbtab.c Tue Sep 2 19:58:12 2003 +++ b/drivers/usb/input/kbtab.c Tue Sep 2 19:58:12 2003 @@ -216,9 +216,13 @@ static int __init kbtab_init(void) { - usb_register(&kbtab_driver); + int retval; + retval = usb_register(&kbtab_driver); + if (retval) + goto out; info(DRIVER_VERSION ":" DRIVER_DESC); - return 0; +out: + return retval; } static void __exit kbtab_exit(void) diff -Nru a/drivers/usb/input/powermate.c b/drivers/usb/input/powermate.c --- a/drivers/usb/input/powermate.c Tue Sep 2 19:58:16 2003 +++ b/drivers/usb/input/powermate.c Tue Sep 2 19:58:16 2003 @@ -433,14 +433,12 @@ .id_table = powermate_devices, }; -int powermate_init(void) +static int __init powermate_init(void) { - if (usb_register(&powermate_driver) < 0) - return -1; - return 0; + return usb_register(&powermate_driver); } -void powermate_cleanup(void) +static void __exit powermate_cleanup(void) { usb_deregister(&powermate_driver); } diff -Nru a/drivers/usb/media/dabusb.c b/drivers/usb/media/dabusb.c --- a/drivers/usb/media/dabusb.c Tue Sep 2 19:58:16 2003 +++ b/drivers/usb/media/dabusb.c Tue Sep 2 19:58:16 2003 @@ -29,7 +29,6 @@ #include #include -#include #include #include #include @@ -583,7 +582,7 @@ static int dabusb_open (struct inode *inode, struct file *file) { - int devnum = minor (inode->i_rdev); + int devnum = iminor(inode); pdabusb_t s; if (devnum < DABUSB_MINOR || devnum >= (DABUSB_MINOR + NRDABUSB)) @@ -819,6 +818,7 @@ static int __init dabusb_init (void) { + int retval; unsigned u; /* initialize struct */ @@ -836,14 +836,16 @@ } /* register misc device */ - if (usb_register(&dabusb_driver)) - return -1; + retval = usb_register(&dabusb_driver); + if (retval) + goto out; dbg("dabusb_init: driver registered"); info(DRIVER_VERSION ":" DRIVER_DESC); - return 0; +out: + return retval; } static void __exit dabusb_cleanup (void) diff -Nru a/drivers/usb/media/dsbr100.c b/drivers/usb/media/dsbr100.c --- a/drivers/usb/media/dsbr100.c Tue Sep 2 19:58:15 2003 +++ b/drivers/usb/media/dsbr100.c Tue Sep 2 19:58:15 2003 @@ -354,15 +354,23 @@ static int __init dsbr100_init(void) { + int retval; usb_dsbr100_radio.priv = NULL; - usb_register(&usb_dsbr100_driver); - if (video_register_device(&usb_dsbr100_radio, VFL_TYPE_RADIO, - radio_nr)==-1) { + retval = usb_register(&usb_dsbr100_driver); + if (retval) + goto failed_usb_register; + retval = video_register_device(&usb_dsbr100_radio, VFL_TYPE_RADIO, + radio_nr); + if (retval) { warn("Couldn't register video device"); - return -EINVAL; + goto failed_video_register; } info(DRIVER_VERSION ":" DRIVER_DESC); return 0; +failed_video_register: + usb_deregister(&usb_dsbr100_driver); +failed_usb_register: + return retval; } static void __exit dsbr100_exit(void) diff -Nru a/drivers/usb/media/ov511.c b/drivers/usb/media/ov511.c --- a/drivers/usb/media/ov511.c Tue Sep 2 19:58:14 2003 +++ b/drivers/usb/media/ov511.c Tue Sep 2 19:58:14 2003 @@ -4592,7 +4592,7 @@ return rc; } -static int +static ssize_t ov51x_v4l1_read(struct file *file, char *buf, size_t cnt, loff_t *ppos) { struct video_device *vdev = file->private_data; @@ -6115,13 +6115,16 @@ static int __init usb_ov511_init(void) { + int retval; - if (usb_register(&ov511_driver) < 0) - return -1; + retval = usb_register(&ov511_driver); + if (retval) + goto out; info(DRIVER_VERSION " : " DRIVER_DESC); - return 0; +out: + return retval; } static void __exit diff -Nru a/drivers/usb/media/pwc-if.c b/drivers/usb/media/pwc-if.c --- a/drivers/usb/media/pwc-if.c Tue Sep 2 19:58:18 2003 +++ b/drivers/usb/media/pwc-if.c Tue Sep 2 19:58:18 2003 @@ -129,7 +129,7 @@ static int pwc_video_open(struct inode *inode, struct file *file); static int pwc_video_close(struct inode *inode, struct file *file); -static int pwc_video_read(struct file *file, char *buf, +static ssize_t pwc_video_read(struct file *file, char *buf, size_t count, loff_t *ppos); static unsigned int pwc_video_poll(struct file *file, poll_table *wait); static int pwc_video_ioctl(struct inode *inode, struct file *file, @@ -1116,7 +1116,7 @@ device is tricky anyhow. */ -static int pwc_video_read(struct file *file, char *buf, +static ssize_t pwc_video_read(struct file *file, char *buf, size_t count, loff_t *ppos) { struct video_device *vdev = file->private_data; @@ -1124,7 +1124,7 @@ int noblock = file->f_flags & O_NONBLOCK; DECLARE_WAITQUEUE(wait, current); - Trace(TRACE_READ, "video_read(0x%p, %p, %d) called.\n", vdev, buf, count); + Trace(TRACE_READ, "video_read(0x%p, %p, %Zd) called.\n", vdev, buf, count); if (vdev == NULL) return -EFAULT; pdev = vdev->priv; diff -Nru a/drivers/usb/media/se401.c b/drivers/usb/media/se401.c --- a/drivers/usb/media/se401.c Tue Sep 2 19:58:14 2003 +++ b/drivers/usb/media/se401.c Tue Sep 2 19:58:14 2003 @@ -30,16 +30,10 @@ #include #include #include -#include #include #include -#include #include #include -#include -#include -#include - #include "se401.h" static int flickerless=0; @@ -126,131 +120,6 @@ /**************************************************************************** * - * /proc interface - * - ***************************************************************************/ - -#warning please convert me from procfs to sysfs -#undef CONFIG_VIDEO_PROC_FS - -#if defined(CONFIG_PROC_FS) && defined(CONFIG_VIDEO_PROC_FS) - -static struct proc_dir_entry *se401_proc_entry = NULL; -extern struct proc_dir_entry *video_proc_entry; - -#define YES_NO(x) ((x) ? "yes" : "no") - -static int se401_read_proc(char *page, char **start, off_t off, int count, - int *eof, void *data) -{ - char *out = page; - int i, len; - struct usb_se401 *se401 = data; - - /* Stay under PAGE_SIZE or else bla bla bla.... */ - - out+=sprintf(out, "driver_version : %s\n", version); - out+=sprintf(out, "model : %s\n", se401->camera_name); - out+=sprintf(out, "in use : %s\n", YES_NO (se401->user)); - out+=sprintf(out, "streaming : %s\n", YES_NO (se401->streaming)); - out+=sprintf(out, "button state : %s\n", YES_NO (se401->button)); - out+=sprintf(out, "button pressed : %s\n", YES_NO (se401->buttonpressed)); - out+=sprintf(out, "num_frames : %d\n", SE401_NUMFRAMES); - - out+=sprintf(out, "Sizes :"); - for (i=0; isizes; i++) { - out+=sprintf(out, " %dx%d", se401->width[i], - se401->height[i]); - } - out+=sprintf(out, "\n"); - - out+=sprintf(out, "Frames total : %d\n", se401->readcount); - out+=sprintf(out, "Frames read : %d\n", se401->framecount); - out+=sprintf(out, "Packets dropped : %d\n", se401->dropped); - out+=sprintf(out, "Decoding Errors : %d\n", se401->error); - - len = out - page; - len -= off; - if (len < count) { - *eof = 1; - if (len <= 0) - return 0; - } else - len = count; - - *start = page + off; - - return len; -} - -static int se401_write_proc(struct file *file, const char *buffer, - unsigned long count, void *data) -{ - return -EINVAL; -} - -static void create_proc_se401_cam (struct usb_se401 *se401) -{ - char name[7]; - struct proc_dir_entry *ent; - - if (!se401_proc_entry || !se401) - return; - - sprintf (name, "video%d", se401->vdev.minor); - - ent = create_proc_entry(name, S_IFREG | S_IRUGO | S_IWUSR, - se401_proc_entry); - - if (!ent) - return; - - ent->data = se401; - ent->read_proc = se401_read_proc; - ent->write_proc = se401_write_proc; - se401->proc_entry = ent; -} - -static void destroy_proc_se401_cam (struct usb_se401 *se401) -{ - /* One to much, just to be sure :) */ - char name[9]; - - if (!se401 || !se401->proc_entry) - return; - - sprintf(name, "video%d", se401->vdev.minor); - remove_proc_entry(name, se401_proc_entry); - se401->proc_entry = NULL; -} - -static void proc_se401_create (void) -{ - if (video_proc_entry == NULL) { - err("/proc/video/ doesn't exist"); - return; - } - - se401_proc_entry=create_proc_entry("se401", S_IFDIR, video_proc_entry); - - if (se401_proc_entry) - se401_proc_entry->owner = THIS_MODULE; - else - err("Unable to initialize /proc/video/se401"); -} - -static void proc_se401_destroy(void) -{ - if (se401_proc_entry == NULL) - return; - - remove_proc_entry("se401", video_proc_entry); -} -#endif /* CONFIG_PROC_FS && CONFIG_VIDEO_PROC_FS */ - - -/**************************************************************************** - * * se401 register read/write functions * ***************************************************************************/ @@ -1252,7 +1121,7 @@ return video_usercopy(inode, file, cmd, arg, se401_do_ioctl); } -static int se401_read(struct file *file, char *buf, +static ssize_t se401_read(struct file *file, char *buf, size_t count, loff_t *ppos) { int realcount=count, ret=0; @@ -1517,9 +1386,6 @@ err("video_register_device failed"); return -EIO; } -#if defined(CONFIG_PROC_FS) && defined(CONFIG_VIDEO_PROC_FS) - create_proc_se401_cam(se401); -#endif info("registered new video device: video%d", se401->vdev.minor); usb_set_intfdata (intf, se401); @@ -1544,9 +1410,6 @@ wake_up_interruptible(&se401->wq); se401->removed = 1; } -#if defined(CONFIG_PROC_FS) && defined(CONFIG_VIDEO_PROC_FS) - destroy_proc_se401_cam(se401); -#endif } } @@ -1568,29 +1431,19 @@ static int __init usb_se401_init(void) { -#if defined(CONFIG_PROC_FS) && defined(CONFIG_VIDEO_PROC_FS) - proc_se401_create(); -#endif - info("SE401 usb camera driver version %s registering", version); if (flickerless) if (flickerless!=50 && flickerless!=60) { info("Invallid flickerless value, use 0, 50 or 60."); return -1; } - if (usb_register(&se401_driver) < 0) - return -1; - return 0; + return usb_register(&se401_driver); } static void __exit usb_se401_exit(void) { usb_deregister(&se401_driver); info("SE401 driver deregistered"); - -#if defined(CONFIG_PROC_FS) && defined(CONFIG_VIDEO_PROC_FS) - proc_se401_destroy(); -#endif } module_init(usb_se401_init); diff -Nru a/drivers/usb/media/se401.h b/drivers/usb/media/se401.h --- a/drivers/usb/media/se401.h Tue Sep 2 19:58:18 2003 +++ b/drivers/usb/media/se401.h Tue Sep 2 19:58:18 2003 @@ -224,9 +224,6 @@ wait_queue_head_t wq; /* Processes waiting */ - /* proc interface */ - struct proc_dir_entry *proc_entry; /* /proc/se401/videoX */ - int nullpackets; }; diff -Nru a/drivers/usb/media/stv680.c b/drivers/usb/media/stv680.c --- a/drivers/usb/media/stv680.c Tue Sep 2 19:58:17 2003 +++ b/drivers/usb/media/stv680.c Tue Sep 2 19:58:17 2003 @@ -61,14 +61,9 @@ #include #include #include -#include #include #include -#include #include -#include -#include -#include #include #include #include @@ -515,124 +510,57 @@ /***************** last of pencam routines *******************/ -/******************************************************************** - * /proc interface - *******************************************************************/ - -#warning please convert me from procfs to sysfs -#undef CONFIG_VIDEO_PROC_FS - -#if defined(CONFIG_PROC_FS) && defined(CONFIG_VIDEO_PROC_FS) - -static struct proc_dir_entry *stv680_proc_entry = NULL; -extern struct proc_dir_entry *video_proc_entry; - -#define YES_NO(x) ((x) ? "yes" : "no") -#define ON_OFF(x) ((x) ? "(auto) on" : "(auto) off") - -static int stv680_read_proc (char *page, char **start, off_t off, int count, int *eof, void *data) -{ - char *out = page; - int len; - struct usb_stv *stv680 = data; - - /* Stay under PAGE_SIZE or else bla bla bla.... */ - - out += sprintf (out, "driver_version : %s\n", DRIVER_VERSION); - out += sprintf (out, "model : %s\n", stv680->camera_name); - out += sprintf (out, "in use : %s\n", YES_NO (stv680->user)); - out += sprintf (out, "streaming : %s\n", YES_NO (stv680->streaming)); - out += sprintf (out, "num_frames : %d\n", STV680_NUMFRAMES); - - out += sprintf (out, "Current size : %ix%i\n", stv680->vwidth, stv680->vheight); - if (swapRGB_on == 0) - out += sprintf (out, "swapRGB : %s\n", ON_OFF (swapRGB)); - else if (swapRGB_on == 1) - out += sprintf (out, "swapRGB : (forced) on\n"); - else if (swapRGB_on == -1) - out += sprintf (out, "swapRGB : (forced) off\n"); - - out += sprintf (out, "Palette : %i", stv680->palette); - - out += sprintf (out, "\n"); - - out += sprintf (out, "Frames total : %d\n", stv680->readcount); - out += sprintf (out, "Frames read : %d\n", stv680->framecount); - out += sprintf (out, "Packets dropped : %d\n", stv680->dropped); - out += sprintf (out, "Decoding Errors : %d\n", stv680->error); - - len = out - page; - len -= off; - if (len < count) { - *eof = 1; - if (len <= 0) - return 0; - } else - len = count; - - *start = page + off; - return len; -} - -static int create_proc_stv680_cam (struct usb_stv *stv680) -{ - char name[9]; - struct proc_dir_entry *ent; - - if (!stv680_proc_entry || !stv680) - return -1; - - sprintf (name, "video%d", stv680->vdev.minor); - - ent = create_proc_entry (name, S_IFREG | S_IRUGO | S_IWUSR, stv680_proc_entry); - if (!ent) - return -1; - - ent->data = stv680; - ent->read_proc = stv680_read_proc; - stv680->proc_entry = ent; - return 0; +/**************************************************************************** + * sysfs + ***************************************************************************/ +static inline struct usb_stv *cd_to_stv(struct class_device *cd) +{ + struct video_device *vdev = to_video_device(cd); + return video_get_drvdata(vdev); +} + +#define stv680_file(name, variable, field) \ +static ssize_t show_##name(struct class_device *class_dev, char *buf) \ +{ \ + struct video_device *vdev = to_video_device(class_dev); \ + struct usb_stv *stv = video_get_drvdata(vdev); \ + return sprintf(buf, field, stv->variable); \ +} \ +static CLASS_DEVICE_ATTR(name, S_IRUGO, show_##name, NULL); + +stv680_file(model, camera_name, "%s\n"); +stv680_file(in_use, user, "%d\n"); +stv680_file(streaming, streaming, "%d\n"); +stv680_file(palette, palette, "%i\n"); +stv680_file(frames_total, readcount, "%d\n"); +stv680_file(frames_read, framecount, "%d\n"); +stv680_file(packets_dropped, dropped, "%d\n"); +stv680_file(decoding_errors, error, "%d\n"); + +static void stv680_create_sysfs_files(struct video_device *vdev) +{ + video_device_create_file(vdev, &class_device_attr_model); + video_device_create_file(vdev, &class_device_attr_in_use); + video_device_create_file(vdev, &class_device_attr_streaming); + video_device_create_file(vdev, &class_device_attr_palette); + video_device_create_file(vdev, &class_device_attr_frames_total); + video_device_create_file(vdev, &class_device_attr_frames_read); + video_device_create_file(vdev, &class_device_attr_packets_dropped); + video_device_create_file(vdev, &class_device_attr_decoding_errors); +} + +static void stv680_remove_sysfs_files(struct video_device *vdev) +{ + video_device_remove_file(vdev, &class_device_attr_model); + video_device_remove_file(vdev, &class_device_attr_in_use); + video_device_remove_file(vdev, &class_device_attr_streaming); + video_device_remove_file(vdev, &class_device_attr_palette); + video_device_remove_file(vdev, &class_device_attr_frames_total); + video_device_remove_file(vdev, &class_device_attr_frames_read); + video_device_remove_file(vdev, &class_device_attr_packets_dropped); + video_device_remove_file(vdev, &class_device_attr_decoding_errors); } -static void destroy_proc_stv680_cam (struct usb_stv *stv680) -{ - /* One to much, just to be sure :) */ - char name[9]; - - if (!stv680 || !stv680->proc_entry) - return; - - sprintf (name, "video%d", stv680->vdev.minor); - remove_proc_entry (name, stv680_proc_entry); - stv680->proc_entry = NULL; -} - -static int proc_stv680_create (void) -{ - if (video_proc_entry == NULL) { - PDEBUG (0, "STV(e): /proc/video/ doesn't exist!"); - return -1; - } - stv680_proc_entry = create_proc_entry ("stv680", S_IFDIR, video_proc_entry); - - if (stv680_proc_entry) { - stv680_proc_entry->owner = THIS_MODULE; - } else { - PDEBUG (0, "STV(e): Unable to initialize /proc/video/stv680"); - return -1; - } - return 0; -} - -static void proc_stv680_destroy (void) -{ - if (stv680_proc_entry == NULL) - return; - - remove_proc_entry ("stv680", video_proc_entry); -} -#endif /* CONFIG_PROC_FS && CONFIG_VIDEO_PROC_FS */ - /******************************************************************** * Camera control *******************************************************************/ @@ -1123,7 +1051,7 @@ static int stv_open (struct inode *inode, struct file *file) { struct video_device *dev = video_devdata(file); - struct usb_stv *stv680 = (struct usb_stv *) dev; + struct usb_stv *stv680 = video_get_drvdata(dev); int err = 0; /* we are called with the BKL held */ @@ -1147,7 +1075,7 @@ static int stv_close (struct inode *inode, struct file *file) { struct video_device *dev = file->private_data; - struct usb_stv *stv680 = (struct usb_stv *) dev; + struct usb_stv *stv680 = video_get_drvdata(dev); int i; for (i = 0; i < STV680_NUMFRAMES; i++) @@ -1174,7 +1102,7 @@ unsigned int cmd, void *arg) { struct video_device *vdev = file->private_data; - struct usb_stv *stv680 = (struct usb_stv *) vdev; + struct usb_stv *stv680 = video_get_drvdata(vdev); if (!stv680->udev) return -EIO; @@ -1350,7 +1278,7 @@ static int stv680_mmap (struct file *file, struct vm_area_struct *vma) { struct video_device *dev = file->private_data; - struct usb_stv *stv680 = (struct usb_stv *) dev; + struct usb_stv *stv680 = video_get_drvdata(dev); unsigned long start = vma->vm_start; unsigned long size = vma->vm_end-vma->vm_start; unsigned long page, pos; @@ -1385,13 +1313,13 @@ return 0; } -static int stv680_read (struct file *file, char *buf, +static ssize_t stv680_read (struct file *file, char *buf, size_t count, loff_t *ppos) { struct video_device *dev = file->private_data; unsigned long int realcount = count; int ret = 0; - struct usb_stv *stv680 = (struct usb_stv *) dev; + struct usb_stv *stv680 = video_get_drvdata(dev); unsigned long int i; if (STV680_NUMFRAMES != 2) { @@ -1448,14 +1376,17 @@ .type = VID_TYPE_CAPTURE, .hardware = VID_HARDWARE_SE401, .fops = &stv680_fops, + .release = video_device_release, + .minor = -1, }; static int stv680_probe (struct usb_interface *intf, const struct usb_device_id *id) { struct usb_device *dev = interface_to_usbdev(intf); struct usb_host_interface *interface; - struct usb_stv *stv680; + struct usb_stv *stv680 = NULL; char *camera_name = NULL; + int retval = 0; /* We don't handle multi-config cameras */ if (dev->descriptor.bNumConfigurations != 1) { @@ -1471,12 +1402,14 @@ } else { PDEBUG (0, "STV(e): Vendor/Product ID do not match STV0680 values."); PDEBUG (0, "STV(e): Check that the STV0680 camera is connected to the computer."); - return -ENODEV; + retval = -ENODEV; + goto error; } /* We found one */ if ((stv680 = kmalloc (sizeof (*stv680), GFP_KERNEL)) == NULL) { PDEBUG (0, "STV(e): couldn't kmalloc stv680 struct."); - return -ENOMEM; + retval = -ENOMEM; + goto error; } memset (stv680, 0, sizeof (*stv680)); @@ -1484,24 +1417,34 @@ stv680->udev = dev; stv680->camera_name = camera_name; - memcpy (&stv680->vdev, &stv680_template, sizeof (stv680_template)); - memcpy (stv680->vdev.name, stv680->camera_name, strlen (stv680->camera_name)); + stv680->vdev = video_device_alloc(); + if (!stv680->vdev) { + retval = -ENOMEM; + goto error; + } + memcpy(stv680->vdev, &stv680_template, sizeof(stv680_template)); + stv680->vdev->dev = &intf->dev; + video_set_drvdata(stv680->vdev, stv680); + + memcpy (stv680->vdev->name, stv680->camera_name, strlen (stv680->camera_name)); init_waitqueue_head (&stv680->wq); init_MUTEX (&stv680->lock); wmb (); - if (video_register_device (&stv680->vdev, VFL_TYPE_GRABBER, video_nr) == -1) { - kfree (stv680); + if (video_register_device (stv680->vdev, VFL_TYPE_GRABBER, video_nr) == -1) { PDEBUG (0, "STV(e): video_register_device failed"); - return -EIO; + retval = -EIO; + goto error; } -#if defined(CONFIG_PROC_FS) && defined(CONFIG_VIDEO_PROC_FS) - create_proc_stv680_cam (stv680); -#endif - PDEBUG (0, "STV(i): registered new video device: video%d", stv680->vdev.minor); + PDEBUG (0, "STV(i): registered new video device: video%d", stv680->vdev->minor); usb_set_intfdata (intf, stv680); + stv680_create_sysfs_files(stv680->vdev); return 0; + +error: + kfree(stv680); + return retval; } static inline void usb_stv680_remove_disconnected (struct usb_stv *stv680) @@ -1528,9 +1471,6 @@ } PDEBUG (0, "STV(i): %s disconnected", stv680->camera_name); -#if defined(CONFIG_PROC_FS) && defined(CONFIG_VIDEO_PROC_FS) - destroy_proc_stv680_cam (stv680); -#endif /* Free the memory */ kfree (stv680); } @@ -1543,7 +1483,11 @@ if (stv680) { /* We don't want people trying to open up the device */ - video_unregister_device (&stv680->vdev); + if (stv680->vdev) { + stv680_remove_sysfs_files(stv680->vdev); + video_unregister_device(stv680->vdev); + stv680->vdev = NULL; + } if (!stv680->user) { usb_stv680_remove_disconnected (stv680); } else { @@ -1566,10 +1510,6 @@ static int __init usb_stv680_init (void) { -#if defined(CONFIG_PROC_FS) && defined(CONFIG_VIDEO_PROC_FS) - if (proc_stv680_create () < 0) - return -1; -#endif if (usb_register (&stv680_driver) < 0) { PDEBUG (0, "STV(e): Could not setup STV0680 driver"); return -1; @@ -1584,10 +1524,6 @@ { usb_deregister (&stv680_driver); PDEBUG (0, "STV(i): driver deregistered"); - -#if defined(CONFIG_PROC_FS) && defined(CONFIG_VIDEO_PROC_FS) - proc_stv680_destroy (); -#endif } module_init (usb_stv680_init); diff -Nru a/drivers/usb/media/stv680.h b/drivers/usb/media/stv680.h --- a/drivers/usb/media/stv680.h Tue Sep 2 19:58:18 2003 +++ b/drivers/usb/media/stv680.h Tue Sep 2 19:58:18 2003 @@ -89,7 +89,7 @@ /* this is almost the video structure uvd_t, with extra parameters for stv */ struct usb_stv { - struct video_device vdev; + struct video_device *vdev; struct usb_device *udev; @@ -142,7 +142,6 @@ wait_queue_head_t wq; /* Processes waiting */ - struct proc_dir_entry *proc_entry; /* /proc/stv680/videoX */ int nullpackets; }; diff -Nru a/drivers/usb/media/usbvideo.c b/drivers/usb/media/usbvideo.c --- a/drivers/usb/media/usbvideo.c Tue Sep 2 19:58:20 2003 +++ b/drivers/usb/media/usbvideo.c Tue Sep 2 19:58:20 2003 @@ -37,24 +37,9 @@ static int video_nr = -1; MODULE_PARM(video_nr, "i"); -#warning please convert me from procfs to sysfs -#define USES_PROC_FS 0 /* * Local prototypes. */ -#if USES_PROC_FS -static void usbvideo_procfs_level1_create(struct usbvideo *ut); -static void usbvideo_procfs_level1_destroy(struct usbvideo *ut); -static void usbvideo_procfs_level2_create(struct uvd *uvd); -static void usbvideo_procfs_level2_destroy(struct uvd *uvd); -static int usbvideo_default_procfs_read_proc( - char *page, char **start, off_t off, int count, - int *eof, void *data); -static int usbvideo_default_procfs_write_proc( - struct file *file, const char *buffer, - unsigned long count, void *data); -#endif - static void usbvideo_Disconnect(struct usb_interface *intf); static void usbvideo_CameraRelease(struct uvd *uvd); @@ -813,24 +798,7 @@ cams->cb.startDataPump = usbvideo_StartDataPump; if (cams->cb.stopDataPump == NULL) cams->cb.stopDataPump = usbvideo_StopDataPump; -#if USES_PROC_FS - /* - * If both /proc fs callbacks are NULL then we assume that the driver - * does not need procfs services at all. Leave them NULL. - */ - cams->uses_procfs = (cams->cb.procfs_read != NULL) || (cams->cb.procfs_write == NULL); - if (cams->uses_procfs) { - if (cams->cb.procfs_read == NULL) - cams->cb.procfs_read = usbvideo_default_procfs_read_proc; - if (cams->cb.procfs_write == NULL) - cams->cb.procfs_write = usbvideo_default_procfs_write_proc; - } -#else /* !USES_PROC_FS */ - /* Report a warning so that user knows why there is no /proc entries */ - if ((cams->cb.procfs_read != NULL) || (cams->cb.procfs_write == NULL)) { - dbg("%s: /proc fs support requested but not configured!", __FUNCTION__); - } -#endif + cams->num_cameras = num_cams; cams->cam = (struct uvd *) &cams[1]; cams->md_module = md; @@ -871,13 +839,6 @@ cams->usbdrv.disconnect = cams->cb.disconnect; cams->usbdrv.id_table = id_table; -#if USES_PROC_FS - if (cams->uses_procfs) { - dbg("%s: Creating /proc filesystem entries.", __FUNCTION__); - usbvideo_procfs_level1_create(cams); - } -#endif - /* * Update global handle to usbvideo. This is very important * because probe() can be called before usb_register() returns. @@ -920,13 +881,6 @@ return; } -#if USES_PROC_FS - if (cams->uses_procfs) { - dbg("%s: Deregistering filesystem entries.", __FUNCTION__); - usbvideo_procfs_level1_destroy(cams); - } -#endif - dbg("%s: Deregistering %s driver.", __FUNCTION__, cams->drvName); usb_deregister(&cams->usbdrv); @@ -1041,14 +995,6 @@ return; } -#if USES_PROC_FS - assert(uvd->handle != NULL); - if (uvd->handle->uses_procfs) { - dbg("%s: Removing /proc/%s/ filesystem entries.", __FUNCTION__, uvd->handle->drvName); - usbvideo_procfs_level2_destroy(uvd); - } -#endif - RingQueue_Free(&uvd->dp); if (VALID_CALLBACK(uvd, userFree)) GET_CALLBACK(uvd, userFree)(uvd); @@ -1200,17 +1146,6 @@ (uvd->handle != NULL) ? uvd->handle->drvName : "???", uvd->vdev.minor, tmp2, tmp1); -#if USES_PROC_FS - assert(uvd->handle != NULL); - if (uvd->handle->uses_procfs) { - if (uvd->debug > 0) { - info("%s: Creating /proc/video/%s/ filesystem entries.", - __FUNCTION__, uvd->handle->drvName); - } - usbvideo_procfs_level2_create(uvd); - } -#endif - usb_get_dev(uvd->dev); return 0; } @@ -1665,7 +1600,7 @@ return -EFAULT; if (uvd->debug >= 1) - info("%s: %d. bytes, noblock=%d.", __FUNCTION__, count, noblock); + info("%s: %Zd. bytes, noblock=%d.", __FUNCTION__, count, noblock); down(&uvd->lock); @@ -1783,7 +1718,7 @@ /* Update last read position */ frame->seqRead_Index += count; if (uvd->debug >= 1) { - err("%s: {copy} count used=%d, new seqRead_Index=%ld", + err("%s: {copy} count used=%Zd, new seqRead_Index=%ld", __FUNCTION__, count, frame->seqRead_Index); } @@ -2345,130 +2280,4 @@ } } -/* - * /proc interface - * - * We will be creating directories and entries under /proc/video using - * external 'video_proc_entry' directory which is exported by videodev.o - * module. Within that directory we will create $driver/ directory to - * uniquely and uniformly refer to our specific $driver. Within that - * directory we will finally create an entry that is named after the - * video device node - video3, for example. The format of that file - * is determined by callbacks that the minidriver may provide. If no - * callbacks are provided (neither read nor write) then we don't create - * the entry. - * - * Here is a sample directory entry: /proc/video/ibmcam/video3 - * - * The "file" video3 (in example above) is readable and writeable, in - * theory. If the minidriver provides callbacks to do reading and - * writing then both those procedures are supported. However if the - * driver leaves callbacks in default (NULL) state the default - * read and write handlers are used. The default read handler reports - * that the driver does not support /proc fs. The default write handler - * returns error code on any write attempt. - */ - -#if USES_PROC_FS - -extern struct proc_dir_entry *video_proc_entry; - -static void usbvideo_procfs_level1_create(struct usbvideo *ut) -{ - if (ut == NULL) { - err("%s: ut == NULL", __FUNCTION__); - return; - } - if (video_proc_entry == NULL) { - err("%s: /proc/video/ doesn't exist.", __FUNCTION__); - return; - } - ut->procfs_dEntry = create_proc_entry(ut->drvName, S_IFDIR, video_proc_entry); - if (ut->procfs_dEntry != NULL) { - if (ut->md_module != NULL) - ut->procfs_dEntry->owner = ut->md_module; - } else { - err("%s: Unable to initialize /proc/video/%s", __FUNCTION__, ut->drvName); - } -} - -static void usbvideo_procfs_level1_destroy(struct usbvideo *ut) -{ - if (ut == NULL) { - err("%s: ut == NULL", __FUNCTION__); - return; - } - if (ut->procfs_dEntry != NULL) { - remove_proc_entry(ut->drvName, video_proc_entry); - ut->procfs_dEntry = NULL; - } -} - -static void usbvideo_procfs_level2_create(struct uvd *uvd) -{ - if (uvd == NULL) { - err("%s: uvd == NULL", __FUNCTION__); - return; - } - assert(uvd->handle != NULL); - if (uvd->handle->procfs_dEntry == NULL) { - err("%s: uvd->handle->procfs_dEntry == NULL", __FUNCTION__); - return; - } - - sprintf(uvd->videoName, "video%d", uvd->vdev.minor); - uvd->procfs_vEntry = create_proc_entry( - uvd->videoName, - S_IFREG | S_IRUGO | S_IWUSR, - uvd->handle->procfs_dEntry); - if (uvd->procfs_vEntry != NULL) { - uvd->procfs_vEntry->data = uvd; - uvd->procfs_vEntry->read_proc = uvd->handle->cb.procfs_read; - uvd->procfs_vEntry->write_proc = uvd->handle->cb.procfs_write; - } else { - err("%s: Failed to create entry \"%s\"", __FUNCTION__, uvd->videoName); - } -} - -static void usbvideo_procfs_level2_destroy(struct uvd *uvd) -{ - if (uvd == NULL) { - err("%s: uvd == NULL", __FUNCTION__); - return; - } - if (uvd->procfs_vEntry != NULL) { - remove_proc_entry(uvd->videoName, uvd->procfs_vEntry); - uvd->procfs_vEntry = NULL; - } -} - -static int usbvideo_default_procfs_read_proc( - char *page, char **start, off_t off, int count, - int *eof, void *data) -{ - char *out = page; - int len; - - /* Stay under PAGE_SIZE or else */ - out += sprintf(out, "This driver does not support /proc services.\n"); - len = out - page; - len -= off; - if (len < count) { - *eof = 1; - if (len <= 0) - return 0; - } else - len = count; - *start = page + off; - return len; -} - -static int usbvideo_default_procfs_write_proc( - struct file *file, const char *buffer, - unsigned long count, void *data) -{ - return -EINVAL; -} - -#endif /* USES_PROC_FS */ MODULE_LICENSE("GPL"); diff -Nru a/drivers/usb/media/usbvideo.h b/drivers/usb/media/usbvideo.h --- a/drivers/usb/media/usbvideo.h Tue Sep 2 19:58:15 2003 +++ b/drivers/usb/media/usbvideo.h Tue Sep 2 19:58:15 2003 @@ -17,14 +17,12 @@ #define usbvideo_h #include -#include #include #include /* Most helpful debugging aid */ #define assert(expr) ((void) ((expr) ? 0 : (err("assert failed at line %d",__LINE__)))) -#define USES_PROC_FS (defined(CONFIG_PROC_FS) && defined(CONFIG_VIDEO_PROC_FS)) #define USBVIDEO_REPORT_STATS 1 /* Set to 0 to block statistics on close */ /* Bit flags (options) */ @@ -244,7 +242,6 @@ struct video_capability vcap; /* Video capabilities */ struct video_channel vchan; /* May be used for tuner support */ struct usbvideo_statistics stats; - struct proc_dir_entry *procfs_vEntry; /* /proc/video/MYDRIVER/video2 */ char videoName[32]; /* Holds name like "video7" */ }; @@ -266,8 +263,6 @@ int (*getFPS)(struct uvd *); int (*overlayHook)(struct uvd *, struct usbvideo_frame *); int (*getFrame)(struct uvd *, int); - int (*procfs_read)(char *page,char **start,off_t off,int count,int *eof,void *data); - int (*procfs_write)(struct file *file,const char *buffer,unsigned long count,void *data); int (*startDataPump)(struct uvd *uvd); void (*stopDataPump)(struct uvd *uvd); int (*setVideoMode)(struct uvd *uvd, struct video_window *vw); @@ -281,8 +276,6 @@ struct usbvideo_cb cb; /* Table of callbacks (virtual methods) */ struct video_device vdt; /* Video device template */ struct uvd *cam; /* Array of camera structures */ - int uses_procfs; /* Non-zero if we create /proc entries */ - struct proc_dir_entry *procfs_dEntry; /* /proc/video/MYDRIVER */ struct module *md_module; /* Minidriver module */ }; diff -Nru a/drivers/usb/media/vicam.c b/drivers/usb/media/vicam.c --- a/drivers/usb/media/vicam.c Tue Sep 2 19:58:15 2003 +++ b/drivers/usb/media/vicam.c Tue Sep 2 19:58:15 2003 @@ -1388,11 +1388,13 @@ static int __init usb_vicam_init(void) { + int retval; DBG(KERN_INFO "ViCam-based WebCam driver startup\n"); vicam_create_proc_root(); - if (usb_register(&vicam_driver) != 0) + retval = usb_register(&vicam_driver); + if (retval) printk(KERN_WARNING "usb_register failed!\n"); - return 0; + return retval; } static void __exit diff -Nru a/drivers/usb/misc/auerswald.c b/drivers/usb/misc/auerswald.c --- a/drivers/usb/misc/auerswald.c Tue Sep 2 19:58:15 2003 +++ b/drivers/usb/misc/auerswald.c Tue Sep 2 19:58:15 2003 @@ -1380,7 +1380,7 @@ /* Open a new character device */ static int auerchar_open (struct inode *inode, struct file *file) { - int dtindex = minor(inode->i_rdev); + int dtindex = iminor(inode); pauerswald_t cp = NULL; pauerchar_t ccp = NULL; struct usb_interface *intf; diff -Nru a/drivers/usb/misc/brlvger.c b/drivers/usb/misc/brlvger.c --- a/drivers/usb/misc/brlvger.c Tue Sep 2 19:58:16 2003 +++ b/drivers/usb/misc/brlvger.c Tue Sep 2 19:58:16 2003 @@ -249,17 +249,20 @@ static int __init brlvger_init (void) { + int retval; printk(BANNER); if(stall_tries < 1 || write_repeats < 1) return -EINVAL; - if (usb_register(&brlvger_driver)) { + retval = usb_register(&brlvger_driver); + if (retval) { err("USB registration failed"); - return -ENOSYS; + goto out; } - return 0; +out: + return retval; } static void @@ -432,7 +435,7 @@ static int brlvger_open(struct inode *inode, struct file *file) { - int devnum = minor (inode->i_rdev); + int devnum = iminor(inode); struct usb_interface *intf = NULL; struct brlvger_priv *priv = NULL; int n, ret; diff -Nru a/drivers/usb/misc/rio500.c b/drivers/usb/misc/rio500.c --- a/drivers/usb/misc/rio500.c Tue Sep 2 19:58:17 2003 +++ b/drivers/usb/misc/rio500.c Tue Sep 2 19:58:17 2003 @@ -33,7 +33,6 @@ #include #include #include -#include #include #include #include @@ -531,12 +530,15 @@ static int __init usb_rio_init(void) { - if (usb_register(&rio_driver) < 0) - return -1; + int retval; + retval = usb_register(&rio_driver); + if (retval) + goto out; info(DRIVER_VERSION ":" DRIVER_DESC); - return 0; +out: + return retval; } diff -Nru a/drivers/usb/misc/tiglusb.c b/drivers/usb/misc/tiglusb.c --- a/drivers/usb/misc/tiglusb.c Tue Sep 2 19:58:12 2003 +++ b/drivers/usb/misc/tiglusb.c Tue Sep 2 19:58:12 2003 @@ -24,7 +24,6 @@ #include #include -#include #include #include #include @@ -93,7 +92,7 @@ static int tiglusb_open (struct inode *inode, struct file *filp) { - int devnum = minor (inode->i_rdev); + int devnum = iminor(inode); ptiglusb_t s; if (devnum < TIUSB_MINOR || devnum >= (TIUSB_MINOR + MAXTIGL)) diff -Nru a/drivers/usb/misc/usblcd.c b/drivers/usb/misc/usblcd.c --- a/drivers/usb/misc/usblcd.c Tue Sep 2 19:58:12 2003 +++ b/drivers/usb/misc/usblcd.c Tue Sep 2 19:58:12 2003 @@ -342,18 +342,21 @@ .id_table = id_table, }; -int usb_lcd_init(void) +static int __init usb_lcd_init(void) { - if (usb_register(&lcd_driver) < 0) - return -1; + int retval; + retval = usb_register(&lcd_driver); + if (retval) + goto out; info("%s (C) Adams IT Services http://www.usblcd.de", DRIVER_VERSION); info("USBLCD support registered."); - return 0; +out: + return retval; } -void usb_lcd_cleanup(void) +static void __exit usb_lcd_cleanup(void) { struct lcd_usb_data *lcd = &lcd_instance; diff -Nru a/drivers/usb/misc/usbtest.c b/drivers/usb/misc/usbtest.c --- a/drivers/usb/misc/usbtest.c Tue Sep 2 19:58:19 2003 +++ b/drivers/usb/misc/usbtest.c Tue Sep 2 19:58:19 2003 @@ -435,7 +435,7 @@ return 0; } - le32_to_cpus (&config->wTotalLength); + le16_to_cpus (&config->wTotalLength); if (config->wTotalLength == len) /* read it all */ return 1; return config->wTotalLength >= TBUF_SIZE; /* max partial read */ diff -Nru a/drivers/usb/misc/uss720.c b/drivers/usb/misc/uss720.c --- a/drivers/usb/misc/uss720.c Tue Sep 2 19:58:12 2003 +++ b/drivers/usb/misc/uss720.c Tue Sep 2 19:58:12 2003 @@ -653,11 +653,14 @@ static int __init uss720_init(void) { - if (usb_register(&uss720_driver) < 0) - return -1; + int retval; + retval = usb_register(&uss720_driver); + if (retval) + goto out; info(DRIVER_VERSION ":" DRIVER_DESC); - return 0; +out: + return retval; } static void __exit uss720_cleanup(void) diff -Nru a/drivers/usb/net/Kconfig b/drivers/usb/net/Kconfig --- a/drivers/usb/net/Kconfig Tue Sep 2 19:58:17 2003 +++ b/drivers/usb/net/Kconfig Tue Sep 2 19:58:17 2003 @@ -7,7 +7,7 @@ comment "Networking support is needed for USB Networking device support" depends on USB && !NET -config USB_AX8817X +config USB_AX8817X_STANDALONE tristate "USB ASIX AX8817X Ethernet device support (EXPERIMENTAL)" depends on USB && NET && EXPERIMENTAL ---help--- @@ -121,15 +121,15 @@ module, say M here and read . config USB_USBNET - tristate "Host-to-Host Networking for Cables and Smart Devices" + tristate "Multi-purpose USB Networking Framework" depends on USB && NET ---help--- This driver supports several kinds of network links over USB, with "minidrivers" built around a common network driver core - that supports deep queues for efficient transfers. - - Typically, these links involves only two network hosts. The - host runs "usbnet", and the other end of the link might be: + that supports deep queues for efficient transfers. (This gives + better performance with small packets and at high speeds). + + The USB host runs "usbnet", and the other end of the link might be: - Another USB host, when using USB "network" or "data transfer" cables. These are often used to network laptops to PCs, like @@ -141,6 +141,9 @@ others), and devices that interoperate using the standard CDC-Ethernet specification (including many cable modems). + - Network adapter hardware (like those for 10/100 Ethernet) which + uses this driver framework. + The link will appear with a name like "usb0", when the link is a two-node link, or "eth0" for most CDC-Ethernet devices. Those two-node links are most easily managed with Ethernet Bridging @@ -265,4 +268,30 @@ what other networking devices you have in use. However, if the IEEE 802 "local assignment" bit is set in the address, a "usbX" name is used instead. + +comment "USB Network Adapters" + depends on USB_USBNET + +config USB_AX8817X + boolean "ASIX AX88172 Based USB 2.0 Ethernet Devices" + depends on USB_USBNET && EXPERIMENTAL + default y + help + + This option adds support for ASIX AX88172 based USB 2.0 + 10/100 Ethernet devices. + + This driver should work with at least the following devices: + * ASIX AX88172 + * D-Link DUB-E100 + * Hawking UF200 + * Linksys USB200M + * Netgear FA120 + * Intellinet + * ST Lab USB Ethernet + * TrendNet TU2-ET100 + + This driver creates an interface named "ethX", where X depends on + what other networking devices you have in use. + diff -Nru a/drivers/usb/net/Makefile b/drivers/usb/net/Makefile --- a/drivers/usb/net/Makefile Tue Sep 2 19:58:12 2003 +++ b/drivers/usb/net/Makefile Tue Sep 2 19:58:12 2003 @@ -2,7 +2,7 @@ # Makefile for USB Network drivers # -obj-$(CONFIG_USB_AX8817X) += ax8817x.o +obj-$(CONFIG_USB_AX8817X_STANDALONE) += ax8817x.o obj-$(CONFIG_USB_CATC) += catc.o obj-$(CONFIG_USB_KAWETH) += kaweth.o obj-$(CONFIG_USB_PEGASUS) += pegasus.o diff -Nru a/drivers/usb/net/Makefile.mii b/drivers/usb/net/Makefile.mii --- a/drivers/usb/net/Makefile.mii Tue Sep 2 19:58:18 2003 +++ b/drivers/usb/net/Makefile.mii Tue Sep 2 19:58:18 2003 @@ -4,3 +4,4 @@ obj-$(CONFIG_USB_AX8817X) += mii.o obj-$(CONFIG_USB_PEGASUS) += mii.o +obj-$(CONFIG_USB_USBNET) += mii.o diff -Nru a/drivers/usb/net/ax8817x.c b/drivers/usb/net/ax8817x.c --- a/drivers/usb/net/ax8817x.c Tue Sep 2 19:58:14 2003 +++ b/drivers/usb/net/ax8817x.c Tue Sep 2 19:58:14 2003 @@ -75,7 +75,6 @@ #include #include #include -#include /* Version Information */ #define DRIVER_VERSION "v2.0.2" diff -Nru a/drivers/usb/net/usbnet.c b/drivers/usb/net/usbnet.c --- a/drivers/usb/net/usbnet.c Tue Sep 2 19:58:16 2003 +++ b/drivers/usb/net/usbnet.c Tue Sep 2 19:58:16 2003 @@ -1,7 +1,9 @@ /* - * USB Host-to-Host Links - * Copyright (C) 2000-2002 by David Brownell + * USB Networking Links + * Copyright (C) 2000-2003 by David Brownell * Copyright (C) 2002 Pavel Machek + * Copyright (C) 2003 David Hollis + * Copyright (c) 2002-2003 TiVo Inc. * * 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 @@ -19,63 +21,38 @@ */ /* - * This is used for "USB networking", connecting USB hosts as peers. - * - * It can be used with USB "network cables", for IP-over-USB communications; - * Ethernet speeds without the Ethernet. USB devices (including some PDAs) - * can support such links directly, replacing device-specific protocols - * with Internet standard ones. - * - * The links can be bridged using the Ethernet bridging (net/bridge) - * support as appropriate. Devices currently supported include: + * This is a generic "USB networking" framework that works with several + * kinds of full and high speed networking devices: * + * + USB host-to-host "network cables", used for IP-over-USB links. + * These are often used for Laplink style connectivity products. * - AnchorChip 2720 * - Belkin, eTEK (interops with Win32 drivers) - * - EPSON USB clients * - GeneSys GL620USB-A * - NetChip 1080 (interoperates with NetChip Win32 drivers) * - Prolific PL-2301/2302 (replaces "plusb" driver) - * - PXA-250 or SA-1100 Linux PDAs like iPaq, Yopy, and Zaurus + * + * + Smart USB devices can support such links directly, using Internet + * standard protocols instead of proprietary host-to-device links. + * - Linux PDAs like iPaq, Yopy, and Zaurus + * - The BLOB boot loader (for diskless booting) + * - Linux "gadgets", perhaps using PXA-2xx or Net2280 controllers + * - Devices using EPSON's sample USB firmware + * - CDC-Ethernet class devices, such as many cable modems + * + * + Adapters to networks such as Ethernet. + * - AX8817X based USB 2.0 products + * + * Links to these devices can be bridged using Linux Ethernet bridging. + * With minor exceptions, these all use similar USB framing for network + * traffic, but need different protocols for control traffic. * * USB devices can implement their side of this protocol at the cost * of two bulk endpoints; it's not restricted to "cable" applications. * See the SA1110, Zaurus, or EPSON device/client support in this driver; - * slave/target drivers such as "usb-eth" (on most SA-1100 PDAs) are - * used inside USB slave/target devices. - * - * - * Status: - * - * - AN2720 ... not widely available, but reportedly works well - * - * - Belkin/eTEK ... no known issues - * - * - Both GeneSys and PL-230x use interrupt transfers for driver-to-driver - * handshaking; it'd be worth implementing those as "carrier detect". - * Prefer generic hooks, not minidriver-specific hacks. - * - * - For Netchip, should use keventd to poll via control requests to detect - * hardware level "carrier detect". - * - * - PL-230x ... the initialization protocol doesn't seem to match chip data - * sheets, sometimes it's not needed and sometimes it hangs. Prolific has - * not responded to repeated support/information requests. - * - * - SA-1100 PDAs ... the standard ARM Linux SA-1100 support works nicely, - * as found in www.handhelds.org and other kernels. The Sharp/Lineo - * kernels use different drivers, which also talk to this code. - * - * Interop with more Win32 drivers may be a good thing. - * - * Seems like reporting "peer connected" (carrier present) events may end - * up going through the netlink event system, not hotplug ... so new links - * would likely be handled with a link monitoring thread in some daemon. - * - * There are reports that bridging gives lower-than-usual throughput. - * - * Need smarter hotplug policy scripts ... ones that know how to arrange - * bridging with "brctl", and can handle static and dynamic ("pump") setups. - * Use those eventual "peer connected" events, and zeroconf. + * slave/target drivers such as "usb-eth" (on most SA-1100 PDAs) or + * "g_ether" (in the Linux "gadget" framework) implement that behavior + * within devices. * * * CHANGELOG: @@ -126,6 +103,7 @@ * vs pxa25x, and CDC Ethernet. Throttle down log floods on * disconnect; other cleanups. (db) Flush net1080 fifos * after several sequential framing errors. (Johannes Erdfelt) + * 22-aug-2003 AX8817X support (Dave Hollis). * *-------------------------------------------------------------------------*/ @@ -139,9 +117,11 @@ #include #include #include +#include #include #include + // #define DEBUG // error path messages, extra info // #define VERBOSE // more; success messages #define REALLY_QUEUE @@ -157,7 +137,7 @@ #include -#define DRIVER_VERSION "25-Apr-2003" +#define DRIVER_VERSION "25-Aug-2003" /*-------------------------------------------------------------------------*/ @@ -218,6 +198,8 @@ int msg_level; unsigned long data [5]; + struct mii_if_info mii; + // various kinds of pending driver work struct sk_buff_head rxq; struct sk_buff_head txq; @@ -399,6 +381,275 @@ #endif /* CONFIG_USB_AN2720 */ + +#ifdef CONFIG_USB_AX8817X +#define NEED_MII +/* ASIX AX8817X based USB 2.0 Ethernet Devices */ + +#define HAVE_HARDWARE + +#include + +#define AX_CMD_SET_SW_MII 0x06 +#define AX_CMD_READ_MII_REG 0x07 +#define AX_CMD_WRITE_MII_REG 0x08 +#define AX_CMD_SET_HW_MII 0x0a +#define AX_CMD_WRITE_RX_CTL 0x10 +#define AX_CMD_READ_IPG012 0x11 +#define AX_CMD_WRITE_IPG0 0x12 +#define AX_CMD_WRITE_IPG1 0x13 +#define AX_CMD_WRITE_IPG2 0x14 +#define AX_CMD_WRITE_MULTI_FILTER 0x16 +#define AX_CMD_READ_NODE_ID 0x17 +#define AX_CMD_READ_PHY_ID 0x19 +#define AX_CMD_WRITE_MEDIUM_MODE 0x1b +#define AX_CMD_WRITE_GPIOS 0x1f + +#define AX_MCAST_FILTER_SIZE 8 +#define AX_MAX_MCAST 64 + +static int ax8817x_read_cmd(struct usbnet *dev, u8 cmd, u16 value, u16 index, + u16 size, void *data) +{ + return usb_control_msg( + dev->udev, + usb_rcvctrlpipe(dev->udev, 0), + cmd, + USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, + value, + index, + data, + size, + CONTROL_TIMEOUT_JIFFIES); +} + +static int ax8817x_write_cmd(struct usbnet *dev, u8 cmd, u16 value, u16 index, + u16 size, void *data) +{ + return usb_control_msg( + dev->udev, + usb_sndctrlpipe(dev->udev, 0), + cmd, + USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, + value, + index, + data, + size, + CONTROL_TIMEOUT_JIFFIES); +} + +static void ax8817x_async_cmd_callback(struct urb *urb, struct pt_regs *regs) +{ + struct usb_ctrlrequest *req = (struct usb_ctrlrequest *)urb->context; + + if (urb->status < 0) + printk(KERN_DEBUG "ax8817x_async_cmd_callback() failed with %d", + urb->status); + + kfree(req); + usb_free_urb(urb); +} + +static void ax8817x_write_cmd_async(struct usbnet *dev, u8 cmd, u16 value, u16 index, + u16 size, void *data) +{ + struct usb_ctrlrequest *req; + int status; + struct urb *urb; + + if ((urb = usb_alloc_urb(0, GFP_ATOMIC)) == NULL) { + devdbg(dev, "Error allocating URB in write_cmd_async!"); + return; + } + + if ((req = kmalloc(sizeof(struct usb_ctrlrequest), GFP_ATOMIC)) == NULL) { + deverr(dev, "Failed to allocate memory for control request"); + usb_free_urb(urb); + return; + } + + req->bRequestType = USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE; + req->bRequest = cmd; + req->wValue = cpu_to_le16(value); + req->wIndex = cpu_to_le16(index); + req->wLength = cpu_to_le16(size); + + usb_fill_control_urb(urb, dev->udev, + usb_sndctrlpipe(dev->udev, 0), + (void *)req, data, size, + ax8817x_async_cmd_callback, req); + + if((status = usb_submit_urb(urb, GFP_ATOMIC)) < 0) + deverr(dev, "Error submitting the control message: status=%d", status); +} + +static void ax8817x_set_multicast(struct net_device *net) +{ + struct usbnet *dev = (struct usbnet *) net->priv; + u8 rx_ctl = 0x8c; + + if (net->flags & IFF_PROMISC) { + rx_ctl |= 0x01; + } else if (net->flags & IFF_ALLMULTI + || net->mc_count > AX_MAX_MCAST) { + rx_ctl |= 0x02; + } else if (net->mc_count == 0) { + /* just broadcast and directed */ + } else { + struct dev_mc_list *mc_list = net->mc_list; + u8 *multi_filter; + u32 crc_bits; + int i; + + multi_filter = kmalloc(AX_MCAST_FILTER_SIZE, GFP_ATOMIC); + if (multi_filter == NULL) { + /* Oops, couldn't allocate a buffer for setting the multicast + filter. Try all multi mode. */ + rx_ctl |= 0x02; + } else { + memset(multi_filter, 0, AX_MCAST_FILTER_SIZE); + + /* Build the multicast hash filter. */ + for (i = 0; i < net->mc_count; i++) { + crc_bits = + ether_crc(ETH_ALEN, + mc_list->dmi_addr) >> 26; + multi_filter[crc_bits >> 3] |= + 1 << (crc_bits & 7); + mc_list = mc_list->next; + } + + ax8817x_write_cmd_async(dev, AX_CMD_WRITE_MULTI_FILTER, 0, 0, + AX_MCAST_FILTER_SIZE, multi_filter); + + rx_ctl |= 0x10; + } + } + + ax8817x_write_cmd_async(dev, AX_CMD_WRITE_RX_CTL, rx_ctl, 0, 0, NULL); +} + +static int ax8817x_mdio_read(struct net_device *netdev, int phy_id, int loc) +{ + struct usbnet *dev = netdev->priv; + u16 res; + u8 buf[4]; + + ax8817x_write_cmd(dev, AX_CMD_SET_SW_MII, 0, 0, 0, &buf); + ax8817x_read_cmd(dev, AX_CMD_READ_MII_REG, phy_id, (__u16)loc, 2, (u16 *)&res); + ax8817x_write_cmd(dev, AX_CMD_SET_HW_MII, 0, 0, 0, &buf); + + return res & 0xffff; +} + +static void ax8817x_mdio_write(struct net_device *netdev, int phy_id, int loc, int val) +{ + struct usbnet *dev = netdev->priv; + u16 res = val; + u8 buf[4]; + + ax8817x_write_cmd(dev, AX_CMD_SET_SW_MII, 0, 0, 0, &buf); + ax8817x_write_cmd(dev, AX_CMD_WRITE_MII_REG, phy_id, (__u16)loc, 2, (u16 *)&res); + ax8817x_write_cmd(dev, AX_CMD_SET_HW_MII, 0, 0, 0, &buf); +} + +static int ax8817x_bind(struct usbnet *dev, struct usb_interface *intf) +{ + int ret; + u8 buf[6]; + u16 *buf16 = (u16 *) buf; + int i; + + dev->in = usb_rcvbulkpipe(dev->udev, 3); + dev->out = usb_sndbulkpipe(dev->udev, 2); + + if ((ret = ax8817x_write_cmd(dev, AX_CMD_WRITE_RX_CTL, 0x80, 0, 0, buf)) < 0) { + dbg("send AX_CMD_WRITE_RX_CTL failed: %d", ret); + return ret; + } + + /* Get the MAC address */ + memset(buf, 0, ETH_ALEN); + if ((ret = ax8817x_read_cmd(dev, AX_CMD_READ_NODE_ID, 0, 0, 6, buf)) < 0) { + dbg("read AX_CMD_READ_NODE_ID failed: %d", ret); + return ret; + } + memcpy(dev->net->dev_addr, buf, ETH_ALEN); + + /* Get IPG values */ + if ((ret = ax8817x_read_cmd(dev, AX_CMD_READ_IPG012, 0, 0, 3, buf)) < 0) { + dbg("Error reading IPG values: %d", ret); + return ret; + } + + for(i = 0;i < 3;i++) { + ax8817x_write_cmd(dev, AX_CMD_WRITE_IPG0 + i, 0, 0, 1, &buf[i]); + } + + /* Get the PHY id */ + if ((ret = ax8817x_read_cmd(dev, AX_CMD_READ_PHY_ID, 0, 0, 2, buf)) < 0) { + dbg("error on read AX_CMD_READ_PHY_ID: %02x", ret); + return ret; + } else if (ret < 2) { + /* this should always return 2 bytes */ + dbg("AX_CMD_READ_PHY_ID returned less than 2 bytes: ret=%02x", ret); + return -EIO; + } + + /* Initialize MII structure */ + dev->mii.dev = dev->net; + dev->mii.mdio_read = ax8817x_mdio_read; + dev->mii.mdio_write = ax8817x_mdio_write; + dev->mii.phy_id_mask = 0x3f; + dev->mii.reg_num_mask = 0x1f; + dev->mii.phy_id = buf[1]; + + if ((ret = ax8817x_write_cmd(dev, AX_CMD_SET_SW_MII, 0, 0, 0, &buf)) < 0) { + dbg("Failed to go to software MII mode: %02x", ret); + return ret; + } + + *buf16 = cpu_to_le16(BMCR_RESET); + if ((ret = ax8817x_write_cmd(dev, AX_CMD_WRITE_MII_REG, + dev->mii.phy_id, MII_BMCR, 2, buf16)) < 0) { + dbg("Failed to write MII reg - MII_BMCR: %02x", ret); + return ret; + } + + /* Advertise that we can do full-duplex pause */ + *buf16 = cpu_to_le16(ADVERTISE_ALL | ADVERTISE_CSMA | 0x0400); + if ((ret = ax8817x_write_cmd(dev, AX_CMD_WRITE_MII_REG, + dev->mii.phy_id, MII_ADVERTISE, + 2, buf16)) < 0) { + dbg("Failed to write MII_REG advertisement: %02x", ret); + return ret; + } + + *buf16 = cpu_to_le16(BMCR_ANENABLE | BMCR_ANRESTART); + if ((ret = ax8817x_write_cmd(dev, AX_CMD_WRITE_MII_REG, + dev->mii.phy_id, MII_BMCR, + 2, buf16)) < 0) { + dbg("Failed to write MII reg autonegotiate: %02x", ret); + return ret; + } + + if ((ret = ax8817x_write_cmd(dev, AX_CMD_SET_HW_MII, 0, 0, 0, &buf)) < 0) { + dbg("Failed to set hardware MII: %02x", ret); + return ret; + } + + dev->net->set_multicast_list = ax8817x_set_multicast; + + return 0; +} + +static const struct driver_info ax8817x_info = { + .description = "ASIX AX8817x USB 2.0 Ethernet", + .bind = ax8817x_bind, + .flags = FLAG_ETHER, +}; +#endif /* CONFIG_USB_AX8817X */ + #ifdef CONFIG_USB_BELKIN @@ -470,7 +721,7 @@ u8 bNumberPowerFilters; } __attribute__ ((packed)); -struct cdc_info { +struct cdc_state { struct header_desc *header; struct union_desc *u; struct ether_desc *ether; @@ -513,7 +764,7 @@ u8 *buf = intf->altsetting->extra; int len = intf->altsetting->extralen; struct usb_interface_descriptor *d; - struct cdc_info *info = (void *) &dev->data; + struct cdc_state *info = (void *) &dev->data; int status; if (sizeof dev->data < sizeof *info) @@ -522,12 +773,15 @@ /* expect strict spec conformance for the descriptors, but * cope with firmware which stores them in the wrong place */ - if (len == 0 && dev->udev->config->extralen) { - /* Motorola SB4100 (and maybe others) put - * CDC descriptors here + if (len == 0 && dev->udev->actconfig->extralen) { + /* Motorola SB4100 (and others: Brad Hards says it's + * from a Broadcom design) put CDC descriptors here */ - buf = dev->udev->config->extra; - len = dev->udev->config->extralen; + buf = dev->udev->actconfig->extra; + len = dev->udev->actconfig->extralen; + if (len) + dev_dbg (&intf->dev, + "CDC descriptors on config\n"); } memset (info, 0, sizeof *info); @@ -542,48 +796,92 @@ */ switch (buf [2]) { case 0x00: /* Header, mostly useless */ - if (info->header) + if (info->header) { + dev_dbg (&intf->dev, "extra CDC header\n"); goto bad_desc; + } info->header = (void *) buf; - if (info->header->bLength != sizeof *info->header) + if (info->header->bLength != sizeof *info->header) { + dev_dbg (&intf->dev, "CDC header len %u\n", + info->header->bLength); goto bad_desc; + } break; case 0x06: /* Union (groups interfaces) */ - if (info->u) + if (info->u) { + dev_dbg (&intf->dev, "extra CDC union\n"); goto bad_desc; + } info->u = (void *) buf; - if (info->u->bLength != sizeof *info->u) - goto bad_desc; - d = &intf->altsetting->desc; - if (info->u->bMasterInterface0 != d->bInterfaceNumber) + if (info->u->bLength != sizeof *info->u) { + dev_dbg (&intf->dev, "CDC union len %u\n", + info->u->bLength); goto bad_desc; - info->data = dev->udev->actconfig->interface[0]; - if (intf != (info->data + info->u->bMasterInterface0)) + } + + /* we need a master/control interface (what we're + * probed with) and a slave/data interface; union + * descriptors sort this all out. + */ + info->control = usb_ifnum_to_if(dev->udev, + info->u->bMasterInterface0); + info->data = usb_ifnum_to_if(dev->udev, + info->u->bSlaveInterface0); + if (!info->control || !info->data) { + dev_dbg (&intf->dev, + "master #%u/%p slave #%u/%p\n", + info->u->bMasterInterface0 + info->control, + info->u->bSlaveInterface0, + info->data); goto bad_desc; + } + if (info->control != intf) { + dev_dbg (&intf->dev, "bogus CDC Union\n"); + /* Ambit USB Cable Modem (and maybe others) + * interchanges master and slave interface. + */ + if (info->data == intf) { + info->data = info->control; + info->control = intf; + } else + goto bad_desc; + } /* a data interface altsetting does the real i/o */ - info->data += info->u->bSlaveInterface0; d = &info->data->altsetting->desc; - if (info->u->bSlaveInterface0 != d->bInterfaceNumber - || d->bInterfaceClass != USB_CLASS_CDC_DATA) + if (d->bInterfaceClass != USB_CLASS_CDC_DATA) { + dev_dbg (&intf->dev, "slave class %u\n", + d->bInterfaceClass); goto bad_desc; + } if (usb_interface_claimed (info->data)) return -EBUSY; break; case 0x0F: /* Ethernet Networking */ - if (info->ether) + if (info->ether) { + dev_dbg (&intf->dev, "extra CDC ether\n"); goto bad_desc; + } info->ether = (void *) buf; - if (info->ether->bLength != sizeof *info->ether) + if (info->ether->bLength != sizeof *info->ether) { + dev_dbg (&intf->dev, "CDC ether len %u\n", + info->u->bLength); goto bad_desc; + } break; } next_desc: len -= buf [0]; /* bLength */ buf += buf [0]; } - if (!info->header || !info ->u || !info->ether) + if (!info->header || !info ->u || !info->ether) { + dev_dbg (&intf->dev, "missing cdc %s%s%sdescriptor\n", + info->header ? "" : "header ", + info->u ? "" : "union ", + info->ether ? "" : "ether "); goto bad_desc; + } #ifdef CONFIG_USB_ZAURUS /* Zaurus ethernet addresses aren't unique ... */ @@ -624,7 +922,7 @@ static void cdc_unbind (struct usbnet *dev, struct usb_interface *intf) { - struct cdc_info *info = (void *) &dev->data; + struct cdc_state *info = (void *) &dev->data; /* disconnect master --> disconnect slave */ if (intf == info->control && info->data) { @@ -2091,16 +2389,23 @@ } netif_start_queue (net); - if (dev->msg_level >= 2) + if (dev->msg_level >= 2) { + char *framing; + + if (dev->driver_info->flags & FLAG_FRAMING_NC) + framing = "NetChip"; + else if (dev->driver_info->flags & FLAG_FRAMING_GL) + framing = "GeneSys"; + else if (dev->driver_info->flags & FLAG_FRAMING_Z) + framing = "Zaurus"; + else + framing = "simple"; + devinfo (dev, "open: enable queueing " "(rx %d, tx %d) mtu %d %s framing", RX_QLEN (dev), TX_QLEN (dev), dev->net->mtu, - (info->flags & (FLAG_FRAMING_NC | FLAG_FRAMING_GL)) - ? ((info->flags & FLAG_FRAMING_NC) - ? "NetChip" - : "GeneSys") - : "raw" - ); + framing); + } // delay posting reads until we're fully open tasklet_schedule (&dev->bh); @@ -2173,12 +2478,20 @@ static int usbnet_ioctl (struct net_device *net, struct ifreq *rq, int cmd) { - switch (cmd) { - case SIOCETHTOOL: + if (cmd == SIOCETHTOOL) return usbnet_ethtool_ioctl (net, (void __user *)rq->ifr_data); - default: - return -EOPNOTSUPP; + +#ifdef NEED_MII + { + struct usbnet *dev = (struct usbnet *)net->priv; + + if (dev->mii.mdio_read != NULL && dev->mii.mdio_write != NULL) + return generic_mii_ioctl(&dev->mii, + (struct mii_ioctl_data *) &rq->ifr_data, + cmd, NULL); } +#endif + return -EOPNOTSUPP; } /*-------------------------------------------------------------------------*/ @@ -2342,7 +2655,7 @@ if (!((skb->len + sizeof *trailer) & 0x01)) *skb_put (skb, 1) = PAD_BYTE; trailer = (struct nc_trailer *) skb_put (skb, sizeof *trailer); - } + } #endif /* CONFIG_USB_NET1080 */ usb_fill_bulk_urb (urb, dev->udev, dev->out, @@ -2670,6 +2983,30 @@ }, #endif +#ifdef CONFIG_USB_AX8817X +{ + // Linksys USB200M + USB_DEVICE (0x077b, 0x2226), + .driver_info = (unsigned long) &ax8817x_info, +}, { + // Netgear FA120 + USB_DEVICE (0x0846, 0x1040), + .driver_info = (unsigned long) &ax8817x_info, +}, { + // DLink DUB-E100 + USB_DEVICE (0x2001, 0x1a00), + .driver_info = (unsigned long) &ax8817x_info, +}, { + // Intellinet, ST Lab USB Ethernet + USB_DEVICE (0x0b95, 0x1720), + .driver_info = (unsigned long) &ax8817x_info, +}, { + // Hawking UF200, TrendNet TU2-ET100 + USB_DEVICE (0x07b8, 0x420a), + .driver_info = (unsigned long) &ax8817x_info, +}, +#endif + #ifdef CONFIG_USB_EPSON2888 { USB_DEVICE (0x0525, 0x2888), // EPSON USB client @@ -2834,18 +3171,19 @@ static int __init usbnet_init (void) { - // compiler should optimize this out - if (sizeof (((struct sk_buff *)0)->cb) < sizeof (struct skb_data)) - BUG (); + // compiler should optimize these out + BUG_ON (sizeof (((struct sk_buff *)0)->cb) + < sizeof (struct skb_data)); +#ifdef CONFIG_USB_CDCETHER + BUG_ON ((sizeof (((struct usbnet *)0)->data) + < sizeof (struct cdc_state))); +#endif get_random_bytes (node_id, sizeof node_id); node_id [0] &= 0xfe; // clear multicast bit node_id [0] |= 0x02; // set local assignment bit (IEEE802) - if (usb_register (&usbnet_driver) < 0) - return -1; - - return 0; + return usb_register(&usbnet_driver); } module_init (usbnet_init); diff -Nru a/drivers/usb/serial/belkin_sa.c b/drivers/usb/serial/belkin_sa.c --- a/drivers/usb/serial/belkin_sa.c Tue Sep 2 19:58:16 2003 +++ b/drivers/usb/serial/belkin_sa.c Tue Sep 2 19:58:16 2003 @@ -602,10 +602,19 @@ static int __init belkin_sa_init (void) { - usb_serial_register (&belkin_device); - usb_register (&belkin_driver); + int retval; + retval = usb_serial_register(&belkin_device); + if (retval) + goto failed_usb_serial_register; + retval = usb_register(&belkin_driver); + if (retval) + goto failed_usb_register; info(DRIVER_DESC " " DRIVER_VERSION); return 0; +failed_usb_register: + usb_serial_deregister(&belkin_device); +failed_usb_serial_register: + return retval; } diff -Nru a/drivers/usb/serial/cyberjack.c b/drivers/usb/serial/cyberjack.c --- a/drivers/usb/serial/cyberjack.c Tue Sep 2 19:58:19 2003 +++ b/drivers/usb/serial/cyberjack.c Tue Sep 2 19:58:19 2003 @@ -101,10 +101,11 @@ }; struct cyberjack_private { - short rdtodo; /* Bytes still to read */ + spinlock_t lock; /* Lock for SMP */ + short rdtodo; /* Bytes still to read */ unsigned char wrbuf[5*64]; /* Buffer for collecting data to write */ - short wrfilled; /* Overall data size we already got */ - short wrsent; /* Data akready sent */ + short wrfilled; /* Overall data size we already got */ + short wrsent; /* Data akready sent */ }; /* do some startup allocations not currently performed by usb_serial_probe() */ @@ -120,6 +121,7 @@ return -ENOMEM; /* set initial values */ + spin_lock_init(&priv->lock); priv->rdtodo = 0; priv->wrfilled = 0; priv->wrsent = 0; @@ -146,6 +148,7 @@ static int cyberjack_open (struct usb_serial_port *port, struct file *filp) { struct cyberjack_private *priv; + unsigned long flags; int result = 0; if (port_paranoia_check (port, __FUNCTION__)) @@ -160,9 +163,11 @@ port->tty->low_latency = 1; priv = usb_get_serial_port_data(port); + spin_lock_irqsave(&priv->lock, flags); priv->rdtodo = 0; priv->wrfilled = 0; priv->wrsent = 0; + spin_unlock_irqrestore(&priv->lock, flags); /* shutdown any bulk reads that might be going on */ usb_unlink_urb (port->write_urb); @@ -194,6 +199,7 @@ { struct usb_serial *serial = port->serial; struct cyberjack_private *priv = usb_get_serial_port_data(port); + unsigned long flags; int result; int wrexpected; @@ -210,15 +216,19 @@ return (0); } + spin_lock_irqsave(&priv->lock, flags); + if( (count+priv->wrfilled)>sizeof(priv->wrbuf) ) { /* To much data for buffer. Reset buffer. */ priv->wrfilled=0; + spin_unlock_irqrestore(&priv->lock, flags); return (0); } /* Copy data */ if (from_user) { if (copy_from_user(priv->wrbuf+priv->wrfilled, buf, count)) { + spin_unlock_irqrestore(&priv->lock, flags); return -EFAULT; } } else { @@ -261,6 +271,7 @@ /* Throw away data. No better idea what to do with it. */ priv->wrfilled=0; priv->wrsent=0; + spin_unlock_irqrestore(&priv->lock, flags); return 0; } @@ -275,6 +286,8 @@ } } + spin_unlock_irqrestore(&priv->lock, flags); + return (count); } @@ -282,8 +295,10 @@ { struct usb_serial_port *port = (struct usb_serial_port *)urb->context; struct cyberjack_private *priv = usb_get_serial_port_data(port); + unsigned long flags; struct usb_serial *serial; unsigned char *data = urb->transfer_buffer; + int result; if (port_paranoia_check (port, __FUNCTION__)) return; @@ -302,21 +317,20 @@ /* React only to interrupts signaling a bulk_in transfer */ if( (urb->actual_length==4) && (data[0]==0x01) ) { - short old_rdtodo = priv->rdtodo; + short old_rdtodo; int result; /* This is a announcement of coming bulk_ins. */ unsigned short size = ((unsigned short)data[3]<<8)+data[2]+3; - if( (size>259) || (size==0) ) { - dbg( "Bad announced bulk_in data length: %d", size ); - /* Dunno what is most reliable to do here. */ - /* return; */ - } + spin_lock_irqsave(&priv->lock, flags); + + old_rdtodo = priv->rdtodo; if( (old_rdtodo+size)<(old_rdtodo) ) { dbg( "To many bulk_in urbs to do." ); - return; + spin_unlock_irqrestore(&priv->lock, flags); + goto resubmit; } /* "+=" is probably more fault tollerant than "=" */ @@ -324,23 +338,34 @@ dbg("%s - rdtodo: %d", __FUNCTION__, priv->rdtodo); + spin_unlock_irqrestore(&priv->lock, flags); + if( !old_rdtodo ) { port->read_urb->dev = port->serial->dev; - result = usb_submit_urb(port->read_urb, GFP_ATOMIC); + result = usb_submit_urb(port->read_urb, GFP_KERNEL); if( result ) err("%s - failed resubmitting read urb, error %d", __FUNCTION__, result); dbg("%s - usb_submit_urb(read urb)", __FUNCTION__); } } + +resubmit: + port->interrupt_in_urb->dev = port->serial->dev; + result = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL); + if (result) + err(" usb_submit_urb(read int) failed"); + dbg("%s - usb_submit_urb(int urb)", __FUNCTION__); } static void cyberjack_read_bulk_callback (struct urb *urb, struct pt_regs *regs) { struct usb_serial_port *port = (struct usb_serial_port *)urb->context; struct cyberjack_private *priv = usb_get_serial_port_data(port); + unsigned long flags; struct usb_serial *serial = get_usb_serial (port, __FUNCTION__); struct tty_struct *tty; unsigned char *data = urb->transfer_buffer; + short todo; int i; int result; @@ -372,18 +397,22 @@ tty_flip_buffer_push(tty); } + spin_lock_irqsave(&priv->lock, flags); + /* Reduce urbs to do by one. */ priv->rdtodo-=urb->actual_length; /* Just to be sure */ - if ( priv->rdtodo<0 ) - priv->rdtodo = 0; + if ( priv->rdtodo<0 ) priv->rdtodo = 0; + todo = priv->rdtodo; - dbg("%s - rdtodo: %d", __FUNCTION__, priv->rdtodo); + spin_unlock_irqrestore(&priv->lock, flags); + + dbg("%s - rdtodo: %d", __FUNCTION__, todo); /* Continue to read if we have still urbs to do. */ - if( priv->rdtodo /* || (urb->actual_length==port->bulk_in_endpointAddress)*/ ) { + if( todo /* || (urb->actual_length==port->bulk_in_endpointAddress)*/ ) { port->read_urb->dev = port->serial->dev; - result = usb_submit_urb(port->read_urb, GFP_ATOMIC); + result = usb_submit_urb(port->read_urb, GFP_KERNEL); if (result) err("%s - failed resubmitting read urb, error %d", __FUNCTION__, result); dbg("%s - usb_submit_urb(read urb)", __FUNCTION__); @@ -394,6 +423,7 @@ { struct usb_serial_port *port = (struct usb_serial_port *)urb->context; struct cyberjack_private *priv = usb_get_serial_port_data(port); + unsigned long flags; struct usb_serial *serial = get_usb_serial (port, __FUNCTION__); dbg("%s - port %d", __FUNCTION__, port->number); @@ -408,12 +438,15 @@ return; } + spin_lock_irqsave(&priv->lock, flags); + /* only do something if we have more data to send */ if( priv->wrfilled ) { int length, blksize, result; if (port->write_urb->status == -EINPROGRESS) { dbg("%s - already writing", __FUNCTION__); + spin_unlock_irqrestore(&priv->lock, flags); return; } @@ -459,18 +492,28 @@ } exit: + spin_unlock_irqrestore(&priv->lock, flags); schedule_work(&port->work); } static int __init cyberjack_init (void) { - usb_serial_register (&cyberjack_device); - usb_register (&cyberjack_driver); + int retval; + retval = usb_serial_register(&cyberjack_device); + if (retval) + goto failed_usb_serial_register; + retval = usb_register(&cyberjack_driver); + if (retval) + goto failed_usb_register; info(DRIVER_VERSION " " DRIVER_AUTHOR); info(DRIVER_DESC); return 0; +failed_usb_register: + usb_serial_deregister(&cyberjack_device); +failed_usb_serial_register: + return retval; } static void __exit cyberjack_exit (void) diff -Nru a/drivers/usb/serial/digi_acceleport.c b/drivers/usb/serial/digi_acceleport.c --- a/drivers/usb/serial/digi_acceleport.c Tue Sep 2 19:58:15 2003 +++ b/drivers/usb/serial/digi_acceleport.c Tue Sep 2 19:58:15 2003 @@ -218,7 +218,7 @@ * interrupt time. * - digi_write_bulk_callback() and digi_read_bulk_callback() are * called directly from interrupts. Hence spin_lock_irqsave() -* and spin_lock_irqrestore() are used in the rest of the code +* and spin_unlock_irqrestore() are used in the rest of the code * for any locks they acquire. * - digi_write_bulk_callback() gets the port lock before waking up * processes sleeping on the port write_wait. It also schedules @@ -571,7 +571,7 @@ * * Do spin_unlock_irqrestore and interruptible_sleep_on_timeout * so that wake ups are not lost if they occur between the unlock -* and the sleep. In other words, spin_lock_irqrestore and +* and the sleep. In other words, spin_unlock_irqrestore and * interruptible_sleep_on_timeout are "atomic" with respect to * wake ups. This is used to implement condition variables. */ @@ -2045,11 +2045,24 @@ static int __init digi_init (void) { - usb_serial_register (&digi_acceleport_2_device); - usb_serial_register (&digi_acceleport_4_device); - usb_register (&digi_driver); + int retval; + retval = usb_serial_register(&digi_acceleport_2_device); + if (retval) + goto failed_acceleport_2_device; + retval = usb_serial_register(&digi_acceleport_4_device); + if (retval) + goto failed_acceleport_4_device; + retval = usb_register(&digi_driver); + if (retval) + goto failed_usb_register; info(DRIVER_VERSION ":" DRIVER_DESC); return 0; +failed_usb_register: + usb_serial_deregister(&digi_acceleport_4_device); +failed_acceleport_4_device: + usb_serial_deregister(&digi_acceleport_2_device); +failed_acceleport_2_device: + return retval; } diff -Nru a/drivers/usb/serial/empeg.c b/drivers/usb/serial/empeg.c --- a/drivers/usb/serial/empeg.c Tue Sep 2 19:58:19 2003 +++ b/drivers/usb/serial/empeg.c Tue Sep 2 19:58:19 2003 @@ -558,7 +558,7 @@ static int __init empeg_init (void) { struct urb *urb; - int i; + int i, retval; /* create our write urb pool and transfer buffers */ spin_lock_init (&write_urb_pool_lock); @@ -570,7 +570,6 @@ continue; } - urb->transfer_buffer = NULL; urb->transfer_buffer = kmalloc (URB_TRANSFER_BUFFER_SIZE, GFP_KERNEL); if (!urb->transfer_buffer) { err("%s - out of memory for urb buffers.", @@ -579,12 +578,27 @@ } } - usb_serial_register (&empeg_device); - usb_register (&empeg_driver); + retval = usb_serial_register(&empeg_device); + if (retval) + goto failed_usb_serial_register; + retval = usb_register(&empeg_driver); + if (retval) + goto failed_usb_register; info(DRIVER_VERSION ":" DRIVER_DESC); return 0; +failed_usb_register: + usb_serial_deregister(&empeg_device); +failed_usb_serial_register: + for (i = 0; i < NUM_URBS; ++i) { + if (write_urb_pool[i]) { + if (write_urb_pool[i]->transfer_buffer) + kfree(write_urb_pool[i]->transfer_buffer); + usb_free_urb(write_urb_pool[i]); + } + } + return retval; } @@ -593,7 +607,7 @@ int i; unsigned long flags; - usb_register (&empeg_driver); + usb_deregister(&empeg_driver); usb_serial_deregister (&empeg_device); spin_lock_irqsave (&write_urb_pool_lock, flags); diff -Nru a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c --- a/drivers/usb/serial/ftdi_sio.c Tue Sep 2 19:58:18 2003 +++ b/drivers/usb/serial/ftdi_sio.c Tue Sep 2 19:58:18 2003 @@ -17,6 +17,11 @@ * See http://ftdi-usb-sio.sourceforge.net for upto date testing info * and extra documentation * + * (19/Aug/2003) Ian Abbott + * Freed urb's transfer buffer in write bulk callback. + * Omitted some paranoid checks in write bulk callback that don't matter. + * Scheduled work in write bulk callback regardless of port's open count. + * * (05/Aug/2003) Ian Abbott * Added VID/PID for ID TECH IDT1221U USB to RS-232 adapter. * VID/PID provided by Steve Briggs. @@ -1391,31 +1396,21 @@ static void ftdi_write_bulk_callback (struct urb *urb, struct pt_regs *regs) { struct usb_serial_port *port = (struct usb_serial_port *)urb->context; - struct usb_serial *serial = get_usb_serial (port, __FUNCTION__); - dbg("%s", __FUNCTION__); + /* free up the transfer buffer, as usb_free_urb() does not do this */ + kfree (urb->transfer_buffer); if (port_paranoia_check (port, __FUNCTION__)) return; + dbg("%s - port %d", __FUNCTION__, port->number); + if (urb->status) { dbg("nonzero write bulk status received: %d", urb->status); return; } - if (!serial) { - dbg("%s - bad serial pointer, exiting", __FUNCTION__); - return; - } - - /* Have to check for validity of queueing up the tasks */ - dbg("%s - port->open_count = %d", __FUNCTION__, port->open_count); - - if (port->open_count > 0){ - schedule_work(&port->work); - } - - return; + schedule_work(&port->work); } /* ftdi_write_bulk_callback */ @@ -1999,17 +1994,42 @@ static int __init ftdi_init (void) { + int retval; dbg("%s", __FUNCTION__); - usb_serial_register (&ftdi_SIO_device); - usb_serial_register (&ftdi_8U232AM_device); - usb_serial_register (&ftdi_FT232BM_device); - usb_serial_register (&ftdi_USB_UIRT_device); - usb_serial_register (&ftdi_HE_TIRA1_device); - usb_register (&ftdi_driver); + retval = usb_serial_register(&ftdi_SIO_device); + if (retval) + goto failed_SIO_register; + retval = usb_serial_register(&ftdi_8U232AM_device); + if (retval) + goto failed_8U232AM_register; + retval = usb_serial_register(&ftdi_FT232BM_device); + if (retval) + goto failed_FT232BM_register; + retval = usb_serial_register(&ftdi_USB_UIRT_device); + if (retval) + goto failed_USB_UIRT_register; + retval = usb_serial_register(&ftdi_HE_TIRA1_device); + if (retval) + goto failed_HE_TIRA1_register; + retval = usb_register(&ftdi_driver); + if (retval) + goto failed_usb_register; info(DRIVER_VERSION ":" DRIVER_DESC); return 0; +failed_usb_register: + usb_serial_deregister(&ftdi_HE_TIRA1_device); +failed_HE_TIRA1_register: + usb_serial_deregister(&ftdi_USB_UIRT_device); +failed_USB_UIRT_register: + usb_serial_deregister(&ftdi_FT232BM_device); +failed_FT232BM_register: + usb_serial_deregister(&ftdi_8U232AM_device); +failed_8U232AM_register: + usb_serial_deregister(&ftdi_SIO_device); +failed_SIO_register: + return retval; } diff -Nru a/drivers/usb/serial/io_16654.h b/drivers/usb/serial/io_16654.h --- a/drivers/usb/serial/io_16654.h Tue Sep 2 19:58:18 2003 +++ b/drivers/usb/serial/io_16654.h Tue Sep 2 19:58:18 2003 @@ -2,7 +2,7 @@ * * 16654.H Definitions for 16C654 UART used on EdgePorts * - * Copyright (c) 1998 Inside Out Networks, Inc. + * Copyright (C) 1998 Inside Out Networks, Inc. * 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 @@ -142,14 +142,14 @@ #define LSR_FIFO_ERR 0x80 // Rx Fifo contains at least 1 erred char -#define MSR_DELTA_CTS 0x01 // CTS changed from last read -#define MSR_DELTA_DSR 0x02 // DSR changed from last read -#define MSR_DELTA_RI 0x04 // RI changed from 0 -> 1 -#define MSR_DELTA_CD 0x08 // CD changed from last read -#define MSR_CTS 0x10 // Current state of CTS -#define MSR_DSR 0x20 // Current state of DSR -#define MSR_RI 0x40 // Current state of RI -#define MSR_CD 0x80 // Current state of CD +#define EDGEPORT_MSR_DELTA_CTS 0x01 // CTS changed from last read +#define EDGEPORT_MSR_DELTA_DSR 0x02 // DSR changed from last read +#define EDGEPORT_MSR_DELTA_RI 0x04 // RI changed from 0 -> 1 +#define EDGEPORT_MSR_DELTA_CD 0x08 // CD changed from last read +#define EDGEPORT_MSR_CTS 0x10 // Current state of CTS +#define EDGEPORT_MSR_DSR 0x20 // Current state of DSR +#define EDGEPORT_MSR_RI 0x40 // Current state of RI +#define EDGEPORT_MSR_CD 0x80 // Current state of CD diff -Nru a/drivers/usb/serial/io_edgeport.c b/drivers/usb/serial/io_edgeport.c --- a/drivers/usb/serial/io_edgeport.c Tue Sep 2 19:58:13 2003 +++ b/drivers/usb/serial/io_edgeport.c Tue Sep 2 19:58:13 2003 @@ -1,8 +1,8 @@ /* * Edgeport USB Serial Converter driver * - * Copyright(c) 2000 Inside Out Networks, All rights reserved. - * Copyright(c) 2001-2002 Greg Kroah-Hartman + * Copyright (C) 2000 Inside Out Networks, All rights reserved. + * Copyright (C) 2001-2002 Greg Kroah-Hartman * * 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 @@ -1806,10 +1806,10 @@ mcr = edge_port->shadowMCR; result = ((mcr & MCR_DTR) ? TIOCM_DTR: 0) /* 0x002 */ | ((mcr & MCR_RTS) ? TIOCM_RTS: 0) /* 0x004 */ - | ((msr & MSR_CTS) ? TIOCM_CTS: 0) /* 0x020 */ - | ((msr & MSR_CD) ? TIOCM_CAR: 0) /* 0x040 */ - | ((msr & MSR_RI) ? TIOCM_RI: 0) /* 0x080 */ - | ((msr & MSR_DSR) ? TIOCM_DSR: 0); /* 0x100 */ + | ((msr & EDGEPORT_MSR_CTS) ? TIOCM_CTS: 0) /* 0x020 */ + | ((msr & EDGEPORT_MSR_CD) ? TIOCM_CAR: 0) /* 0x040 */ + | ((msr & EDGEPORT_MSR_RI) ? TIOCM_RI: 0) /* 0x080 */ + | ((msr & EDGEPORT_MSR_DSR) ? TIOCM_DSR: 0); /* 0x100 */ dbg("%s -- %x", __FUNCTION__, result); @@ -2221,20 +2221,20 @@ dbg("%s %02x", __FUNCTION__, newMsr); - if (newMsr & (MSR_DELTA_CTS | MSR_DELTA_DSR | MSR_DELTA_RI | MSR_DELTA_CD)) { + if (newMsr & (EDGEPORT_MSR_DELTA_CTS | EDGEPORT_MSR_DELTA_DSR | EDGEPORT_MSR_DELTA_RI | EDGEPORT_MSR_DELTA_CD)) { icount = &edge_port->icount; /* update input line counters */ - if (newMsr & MSR_DELTA_CTS) { + if (newMsr & EDGEPORT_MSR_DELTA_CTS) { icount->cts++; } - if (newMsr & MSR_DELTA_DSR) { + if (newMsr & EDGEPORT_MSR_DELTA_DSR) { icount->dsr++; } - if (newMsr & MSR_DELTA_CD) { + if (newMsr & EDGEPORT_MSR_DELTA_CD) { icount->dcd++; } - if (newMsr & MSR_DELTA_RI) { + if (newMsr & EDGEPORT_MSR_DELTA_RI) { icount->rng++; } wake_up_interruptible(&edge_port->delta_msr_wait); @@ -3051,15 +3051,36 @@ * edgeport_init * This is called by the module subsystem, or on startup to initialize us ****************************************************************************/ -int __init edgeport_init(void) +static int __init edgeport_init(void) { - usb_serial_register (&edgeport_1port_device); - usb_serial_register (&edgeport_2port_device); - usb_serial_register (&edgeport_4port_device); - usb_serial_register (&edgeport_8port_device); - usb_register (&io_driver); + int retval; + retval = usb_serial_register(&edgeport_1port_device); + if (retval) + goto failed_1port_device_register; + retval = usb_serial_register(&edgeport_2port_device); + if (retval) + goto failed_2port_device_register; + retval = usb_serial_register(&edgeport_4port_device); + if (retval) + goto failed_4port_device_register; + retval = usb_serial_register(&edgeport_8port_device); + if (retval) + goto failed_8port_device_register; + retval = usb_register(&io_driver); + if (retval) + goto failed_usb_register; info(DRIVER_DESC " " DRIVER_VERSION); return 0; +failed_usb_register: + usb_serial_deregister(&edgeport_8port_device); +failed_8port_device_register: + usb_serial_deregister(&edgeport_4port_device); +failed_4port_device_register: + usb_serial_deregister(&edgeport_2port_device); +failed_2port_device_register: + usb_serial_deregister(&edgeport_1port_device); +failed_1port_device_register: + return retval; } @@ -3068,7 +3089,7 @@ * edgeport_exit * Called when the driver is about to be unloaded. ****************************************************************************/ -void __exit edgeport_exit (void) +static void __exit edgeport_exit (void) { usb_deregister (&io_driver); usb_serial_deregister (&edgeport_1port_device); diff -Nru a/drivers/usb/serial/io_edgeport.h b/drivers/usb/serial/io_edgeport.h --- a/drivers/usb/serial/io_edgeport.h Tue Sep 2 19:58:17 2003 +++ b/drivers/usb/serial/io_edgeport.h Tue Sep 2 19:58:17 2003 @@ -2,7 +2,7 @@ * * io_edgeport.h Edgeport Linux Interface definitions * - * Copyright (c) 2000 Inside Out Networks, Inc. + * Copyright (C) 2000 Inside Out Networks, Inc. * * 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 diff -Nru a/drivers/usb/serial/io_fw_boot.h b/drivers/usb/serial/io_fw_boot.h --- a/drivers/usb/serial/io_fw_boot.h Tue Sep 2 19:58:20 2003 +++ b/drivers/usb/serial/io_fw_boot.h Tue Sep 2 19:58:20 2003 @@ -1,7 +1,7 @@ //************************************************************** //* Edgeport/4 Binary Image //* Generated by HEX2C v1.06 -//* Copyright(c) 1998 Inside Out Networks, All rights reserved. +//* Copyright (C) 1998 Inside Out Networks, All rights reserved. //* 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 diff -Nru a/drivers/usb/serial/io_fw_boot2.h b/drivers/usb/serial/io_fw_boot2.h --- a/drivers/usb/serial/io_fw_boot2.h Tue Sep 2 19:58:13 2003 +++ b/drivers/usb/serial/io_fw_boot2.h Tue Sep 2 19:58:13 2003 @@ -1,7 +1,7 @@ //************************************************************** //* Edgeport/4 Binary Image //* Generated by HEX2C v1.06 -//* Copyright(c) 1998 Inside Out Networks, All rights reserved. +//* Copyright (C) 1998 Inside Out Networks, All rights reserved. //* 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 diff -Nru a/drivers/usb/serial/io_fw_down.h b/drivers/usb/serial/io_fw_down.h --- a/drivers/usb/serial/io_fw_down.h Tue Sep 2 19:58:19 2003 +++ b/drivers/usb/serial/io_fw_down.h Tue Sep 2 19:58:19 2003 @@ -1,7 +1,7 @@ //************************************************************** //* Edgeport/4 Binary Image //* Generated by HEX2C v1.06 -//* Copyright(c) 1998 Inside Out Networks, All rights reserved. +//* Copyright (C) 1998 Inside Out Networks, All rights reserved. //* 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 diff -Nru a/drivers/usb/serial/io_fw_down2.h b/drivers/usb/serial/io_fw_down2.h --- a/drivers/usb/serial/io_fw_down2.h Tue Sep 2 19:58:14 2003 +++ b/drivers/usb/serial/io_fw_down2.h Tue Sep 2 19:58:14 2003 @@ -1,7 +1,7 @@ //************************************************************** //* Edgeport/4 Binary Image //* Generated by HEX2C v1.06 -//* Copyright(c) 1998 Inside Out Networks, All rights reserved. +//* Copyright (C) 1998 Inside Out Networks, All rights reserved. //* 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 diff -Nru a/drivers/usb/serial/io_fw_down3.h b/drivers/usb/serial/io_fw_down3.h --- a/drivers/usb/serial/io_fw_down3.h Tue Sep 2 19:58:18 2003 +++ b/drivers/usb/serial/io_fw_down3.h Tue Sep 2 19:58:18 2003 @@ -1,7 +1,7 @@ //************************************************************** //* Edgeport Binary Image (for TI based products) //* Generated by TIBin2C v1.00 -//* Copyright(c) 2001 Inside Out Networks, All rights reserved. +//* Copyright (C) 2001 Inside Out Networks, All rights reserved. //************************************************************** diff -Nru a/drivers/usb/serial/io_ionsp.h b/drivers/usb/serial/io_ionsp.h --- a/drivers/usb/serial/io_ionsp.h Tue Sep 2 19:58:18 2003 +++ b/drivers/usb/serial/io_ionsp.h Tue Sep 2 19:58:18 2003 @@ -2,7 +2,7 @@ * * IONSP.H Definitions for I/O Networks Serial Protocol * - * Copyright (c) 1997-1998 Inside Out Networks, Inc. + * Copyright (C) 1997-1998 Inside Out Networks, Inc. * * 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 diff -Nru a/drivers/usb/serial/io_ti.c b/drivers/usb/serial/io_ti.c --- a/drivers/usb/serial/io_ti.c Tue Sep 2 19:58:19 2003 +++ b/drivers/usb/serial/io_ti.c Tue Sep 2 19:58:19 2003 @@ -1,8 +1,8 @@ /* * Edgeport USB Serial Converter driver * - * Copyright(c) 2000-2002 Inside Out Networks, All rights reserved. - * Copyright(c) 2001-2002 Greg Kroah-Hartman + * Copyright (C) 2000-2002 Inside Out Networks, All rights reserved. + * Copyright (C) 2001-2002 Greg Kroah-Hartman * * 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 @@ -127,6 +127,7 @@ static struct usb_device_id edgeport_2port_id_table [] = { { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_TI_EDGEPORT_2) }, + { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_TI_EDGEPORT_2C) }, { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_TI_EDGEPORT_2I) }, { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_TI_EDGEPORT_421) }, { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_TI_EDGEPORT_421_BOOT) }, @@ -145,6 +146,7 @@ static struct usb_device_id id_table_combined [] = { { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_TI_EDGEPORT_1) }, { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_TI_EDGEPORT_2) }, + { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_TI_EDGEPORT_2C) }, { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_TI_EDGEPORT_2I) }, { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_TI_EDGEPORT_421) }, { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_TI_EDGEPORT_421_BOOT) }, @@ -1575,17 +1577,17 @@ dbg ("%s - %02x", __FUNCTION__, msr); - if (msr & (MSR_DELTA_CTS | MSR_DELTA_DSR | MSR_DELTA_RI | MSR_DELTA_CD)) { + if (msr & (EDGEPORT_MSR_DELTA_CTS | EDGEPORT_MSR_DELTA_DSR | EDGEPORT_MSR_DELTA_RI | EDGEPORT_MSR_DELTA_CD)) { icount = &edge_port->icount; /* update input line counters */ - if (msr & MSR_DELTA_CTS) + if (msr & EDGEPORT_MSR_DELTA_CTS) icount->cts++; - if (msr & MSR_DELTA_DSR) + if (msr & EDGEPORT_MSR_DELTA_DSR) icount->dsr++; - if (msr & MSR_DELTA_CD) + if (msr & EDGEPORT_MSR_DELTA_CD) icount->dcd++; - if (msr & MSR_DELTA_RI) + if (msr & EDGEPORT_MSR_DELTA_RI) icount->rng++; wake_up_interruptible (&edge_port->delta_msr_wait); } @@ -2447,10 +2449,10 @@ mcr = edge_port->shadow_mcr; result = ((mcr & MCR_DTR) ? TIOCM_DTR: 0) /* 0x002 */ | ((mcr & MCR_RTS) ? TIOCM_RTS: 0) /* 0x004 */ - | ((msr & MSR_CTS) ? TIOCM_CTS: 0) /* 0x020 */ - | ((msr & MSR_CD) ? TIOCM_CAR: 0) /* 0x040 */ - | ((msr & MSR_RI) ? TIOCM_RI: 0) /* 0x080 */ - | ((msr & MSR_DSR) ? TIOCM_DSR: 0); /* 0x100 */ + | ((msr & EDGEPORT_MSR_CTS) ? TIOCM_CTS: 0) /* 0x020 */ + | ((msr & EDGEPORT_MSR_CD) ? TIOCM_CAR: 0) /* 0x040 */ + | ((msr & EDGEPORT_MSR_RI) ? TIOCM_RI: 0) /* 0x080 */ + | ((msr & EDGEPORT_MSR_DSR) ? TIOCM_DSR: 0); /* 0x100 */ dbg("%s -- %x", __FUNCTION__, result); @@ -2679,11 +2681,24 @@ static int __init edgeport_init(void) { - usb_serial_register (&edgeport_1port_device); - usb_serial_register (&edgeport_2port_device); - usb_register (&io_driver); + int retval; + retval = usb_serial_register(&edgeport_1port_device); + if (retval) + goto failed_1port_device_register; + retval = usb_serial_register(&edgeport_2port_device); + if (retval) + goto failed_2port_device_register; + retval = usb_register(&io_driver); + if (retval) + goto failed_usb_register; info(DRIVER_DESC " " DRIVER_VERSION); return 0; +failed_usb_register: + usb_serial_deregister(&edgeport_2port_device); +failed_2port_device_register: + usb_serial_deregister(&edgeport_1port_device); +failed_1port_device_register: + return retval; } static void __exit edgeport_exit (void) diff -Nru a/drivers/usb/serial/io_ti.h b/drivers/usb/serial/io_ti.h --- a/drivers/usb/serial/io_ti.h Tue Sep 2 19:58:14 2003 +++ b/drivers/usb/serial/io_ti.h Tue Sep 2 19:58:14 2003 @@ -1,6 +1,6 @@ /***************************************************************************** * - * Copyright (c) 1997-2002 Inside Out Networks, Inc. + * Copyright (C) 1997-2002 Inside Out Networks, Inc. * * 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 diff -Nru a/drivers/usb/serial/io_usbvend.h b/drivers/usb/serial/io_usbvend.h --- a/drivers/usb/serial/io_usbvend.h Tue Sep 2 19:58:18 2003 +++ b/drivers/usb/serial/io_usbvend.h Tue Sep 2 19:58:18 2003 @@ -7,7 +7,7 @@ * ************************************************************************ * - * Copyright (c) 1998 Inside Out Networks, Inc. + * Copyright (C) 1998 Inside Out Networks, Inc. * 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 @@ -118,6 +118,7 @@ #define ION_DEVICE_ID_TI_EDGEPORT_1 0x0215 /* Edgeport/1 RS232 */ #define ION_DEVICE_ID_TI_EDGEPORT_42 0x0217 /* Edgeport/42 4 hub 2 RS232 */ #define ION_DEVICE_ID_TI_EDGEPORT_22 0x021A /* Edgeport/22 Edgeport/22I is an Edgeport/4 with ports 1&2 RS422 and ports 3&4 RS232 */ +#define ION_DEVICE_ID_TI_EDGEPORT_2C 0x021B /* Edgeport/2c RS232 */ #define ION_DEVICE_ID_TI_EDGEPORT_421_BOOT 0x0240 /* Edgeport/421 in boot mode */ #define ION_DEVICE_ID_TI_EDGEPORT_421_DOWN 0x0241 /* Edgeport/421 in download mode first interface is 2 RS232 (Note that the second interface of this multi interface device should be a standard USB class 7 printer port) */ diff -Nru a/drivers/usb/serial/ipaq.c b/drivers/usb/serial/ipaq.c --- a/drivers/usb/serial/ipaq.c Tue Sep 2 19:58:18 2003 +++ b/drivers/usb/serial/ipaq.c Tue Sep 2 19:58:18 2003 @@ -570,16 +570,25 @@ static int __init ipaq_init(void) { + int retval; spin_lock_init(&write_list_lock); - usb_serial_register(&ipaq_device); + retval = usb_serial_register(&ipaq_device); + if (retval) + goto failed_usb_serial_register; info(DRIVER_DESC " " DRIVER_VERSION); if (vendor) { ipaq_id_table[0].idVendor = vendor; ipaq_id_table[0].idProduct = product; } - usb_register(&ipaq_driver); - + retval = usb_register(&ipaq_driver); + if (retval) + goto failed_usb_register; + return 0; +failed_usb_register: + usb_serial_deregister(&ipaq_device); +failed_usb_serial_register: + return retval; } diff -Nru a/drivers/usb/serial/ir-usb.c b/drivers/usb/serial/ir-usb.c --- a/drivers/usb/serial/ir-usb.c Tue Sep 2 19:58:15 2003 +++ b/drivers/usb/serial/ir-usb.c Tue Sep 2 19:58:15 2003 @@ -609,10 +609,19 @@ static int __init ir_init (void) { - usb_serial_register (&ir_device); - usb_register (&ir_driver); + int retval; + retval = usb_serial_register(&ir_device); + if (retval) + goto failed_usb_serial_register; + retval = usb_register(&ir_driver); + if (retval) + goto failed_usb_register; info(DRIVER_DESC " " DRIVER_VERSION); return 0; +failed_usb_register: + usb_serial_deregister(&ir_device); +failed_usb_serial_register: + return retval; } diff -Nru a/drivers/usb/serial/keyspan.c b/drivers/usb/serial/keyspan.c --- a/drivers/usb/serial/keyspan.c Tue Sep 2 19:58:13 2003 +++ b/drivers/usb/serial/keyspan.c Tue Sep 2 19:58:13 2003 @@ -197,15 +197,36 @@ /* Functions used by new usb-serial code. */ static int __init keyspan_init (void) { - usb_serial_register (&keyspan_pre_device); - usb_serial_register (&keyspan_1port_device); - usb_serial_register (&keyspan_2port_device); - usb_serial_register (&keyspan_4port_device); - usb_register (&keyspan_driver); + int retval; + retval = usb_serial_register(&keyspan_pre_device); + if (retval) + goto failed_pre_device_register; + retval = usb_serial_register(&keyspan_1port_device); + if (retval) + goto failed_1port_device_register; + retval = usb_serial_register(&keyspan_2port_device); + if (retval) + goto failed_2port_device_register; + retval = usb_serial_register(&keyspan_4port_device); + if (retval) + goto failed_4port_device_register; + retval = usb_register(&keyspan_driver); + if (retval) + goto failed_usb_register; info(DRIVER_VERSION ":" DRIVER_DESC); return 0; +failed_usb_register: + usb_serial_deregister(&keyspan_4port_device); +failed_4port_device_register: + usb_serial_deregister(&keyspan_2port_device); +failed_2port_device_register: + usb_serial_deregister(&keyspan_1port_device); +failed_1port_device_register: + usb_serial_deregister(&keyspan_pre_device); +failed_pre_device_register: + return retval; } static void __exit keyspan_exit (void) diff -Nru a/drivers/usb/serial/keyspan_pda.c b/drivers/usb/serial/keyspan_pda.c --- a/drivers/usb/serial/keyspan_pda.c Tue Sep 2 19:58:17 2003 +++ b/drivers/usb/serial/keyspan_pda.c Tue Sep 2 19:58:17 2003 @@ -1,9 +1,9 @@ /* * USB Keyspan PDA / Xircom / Entregra Converter driver * - * Copyright (c) 1999 - 2001 Greg Kroah-Hartman - * Copyright (c) 1999, 2000 Brian Warner - * Copyright (c) 2000 Al Borchers + * Copyright (C) 1999 - 2001 Greg Kroah-Hartman + * Copyright (C) 1999, 2000 Brian Warner + * Copyright (C) 2000 Al Borchers * * 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 @@ -876,16 +876,39 @@ static int __init keyspan_pda_init (void) { - usb_serial_register (&keyspan_pda_device); + int retval; + retval = usb_serial_register(&keyspan_pda_device); + if (retval) + goto failed_pda_register; #ifdef KEYSPAN - usb_serial_register (&keyspan_pda_fake_device); + retval = usb_serial_register(&keyspan_pda_fake_device); + if (retval) + goto failed_pda_fake_register; #endif #ifdef XIRCOM - usb_serial_register (&xircom_pgs_fake_device); -#endif - usb_register (&keyspan_pda_driver); + retval = usb_serial_register(&xircom_pgs_fake_device); + if (retval) + goto failed_xircom_register; +#endif + retval = usb_register(&keyspan_pda_driver); + if (retval) + goto failed_usb_register; info(DRIVER_DESC " " DRIVER_VERSION); return 0; +failed_usb_register: +#ifdef XIRCOM + usb_serial_deregister(&xircom_pgs_fake_device); +failed_xircom_register: +#endif /* XIRCOM */ +#ifdef KEYSPAN + usb_serial_deregister(&keyspan_pda_fake_device); +#endif +#ifdef KEYSPAN +failed_pda_fake_register: +#endif + usb_serial_deregister(&keyspan_pda_device); +failed_pda_register: + return retval; } diff -Nru a/drivers/usb/serial/keyspan_pda_fw.h b/drivers/usb/serial/keyspan_pda_fw.h --- a/drivers/usb/serial/keyspan_pda_fw.h Tue Sep 2 19:58:16 2003 +++ b/drivers/usb/serial/keyspan_pda_fw.h Tue Sep 2 19:58:16 2003 @@ -1,7 +1,7 @@ /* * USB Keyspan PDA Firmware * - * Copyright (c) 1999, 2000 Brian Warner + * Copyright (C) 1999, 2000 Brian Warner * * 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 diff -Nru a/drivers/usb/serial/keyspan_usa26msg.h b/drivers/usb/serial/keyspan_usa26msg.h --- a/drivers/usb/serial/keyspan_usa26msg.h Tue Sep 2 19:58:16 2003 +++ b/drivers/usb/serial/keyspan_usa26msg.h Tue Sep 2 19:58:16 2003 @@ -1,7 +1,7 @@ /* usa26msg.h - Copyright (c) 1998-2000 InnoSys Incorporated. All Rights Reserved + Copyright (C) 1998-2000 InnoSys Incorporated. All Rights Reserved This file is available under a BSD-style copyright Keyspan USB Async Firmware to run on Anchor EZ-USB @@ -15,7 +15,7 @@ disclaimer. The following copyright notice must appear immediately at the beginning of all source files: - Copyright (c) 1998-2000 InnoSys Incorporated. All Rights Reserved + Copyright (C) 1998-2000 InnoSys Incorporated. All Rights Reserved This file is available under a BSD-style copyright diff -Nru a/drivers/usb/serial/keyspan_usa28msg.h b/drivers/usb/serial/keyspan_usa28msg.h --- a/drivers/usb/serial/keyspan_usa28msg.h Tue Sep 2 19:58:13 2003 +++ b/drivers/usb/serial/keyspan_usa28msg.h Tue Sep 2 19:58:13 2003 @@ -1,7 +1,7 @@ /* usa28msg.h - Copyright (c) 1998-2000 InnoSys Incorporated. All Rights Reserved + Copyright (C) 1998-2000 InnoSys Incorporated. All Rights Reserved This file is available under a BSD-style copyright Keyspan USB Async Firmware to run on Anchor EZ-USB @@ -15,7 +15,7 @@ disclaimer. The following copyright notice must appear immediately at the beginning of all source files: - Copyright (c) 1998-2000 InnoSys Incorporated. All Rights Reserved + Copyright (C) 1998-2000 InnoSys Incorporated. All Rights Reserved This file is available under a BSD-style copyright diff -Nru a/drivers/usb/serial/keyspan_usa49msg.h b/drivers/usb/serial/keyspan_usa49msg.h --- a/drivers/usb/serial/keyspan_usa49msg.h Tue Sep 2 19:58:14 2003 +++ b/drivers/usb/serial/keyspan_usa49msg.h Tue Sep 2 19:58:14 2003 @@ -1,7 +1,7 @@ /* usa49msg.h - Copyright (c) 1998-2000 InnoSys Incorporated. All Rights Reserved + Copyright (C) 1998-2000 InnoSys Incorporated. All Rights Reserved This file is available under a BSD-style copyright Keyspan USB Async Firmware to run on Anchor EZ-USB @@ -15,7 +15,7 @@ disclaimer. The following copyright notice must appear immediately at the beginning of all source files: - Copyright (c) 1998-2000 InnoSys Incorporated. All Rights Reserved + Copyright (C) 1998-2000 InnoSys Incorporated. All Rights Reserved This file is available under a BSD-style copyright diff -Nru a/drivers/usb/serial/kl5kusb105.c b/drivers/usb/serial/kl5kusb105.c --- a/drivers/usb/serial/kl5kusb105.c Tue Sep 2 19:58:16 2003 +++ b/drivers/usb/serial/kl5kusb105.c Tue Sep 2 19:58:16 2003 @@ -1037,11 +1037,20 @@ static int __init klsi_105_init (void) { - usb_serial_register (&kl5kusb105d_device); - usb_register (&kl5kusb105d_driver); + int retval; + retval = usb_serial_register(&kl5kusb105d_device); + if (retval) + goto failed_usb_serial_register; + retval = usb_register(&kl5kusb105d_driver); + if (retval) + goto failed_usb_register; info(DRIVER_DESC " " DRIVER_VERSION); return 0; +failed_usb_register: + usb_serial_deregister(&kl5kusb105d_device); +failed_usb_serial_register: + return retval; } diff -Nru a/drivers/usb/serial/kobil_sct.c b/drivers/usb/serial/kobil_sct.c --- a/drivers/usb/serial/kobil_sct.c Tue Sep 2 19:58:18 2003 +++ b/drivers/usb/serial/kobil_sct.c Tue Sep 2 19:58:18 2003 @@ -743,13 +743,22 @@ static int __init kobil_init (void) { - usb_serial_register (&kobil_device); - usb_register (&kobil_driver); + int retval; + retval = usb_serial_register(&kobil_device); + if (retval) + goto failed_usb_serial_register; + retval = usb_register(&kobil_driver); + if (retval) + goto failed_usb_register; info(DRIVER_VERSION " " DRIVER_AUTHOR); info(DRIVER_DESC); return 0; +failed_usb_register: + usb_serial_deregister(&kobil_device); +failed_usb_serial_register: + return retval; } diff -Nru a/drivers/usb/serial/mct_u232.c b/drivers/usb/serial/mct_u232.c --- a/drivers/usb/serial/mct_u232.c Tue Sep 2 19:58:17 2003 +++ b/drivers/usb/serial/mct_u232.c Tue Sep 2 19:58:17 2003 @@ -850,10 +850,19 @@ static int __init mct_u232_init (void) { - usb_serial_register (&mct_u232_device); - usb_register (&mct_u232_driver); + int retval; + retval = usb_serial_register(&mct_u232_device); + if (retval) + goto failed_usb_serial_register; + retval = usb_register(&mct_u232_driver); + if (retval) + goto failed_usb_register; info(DRIVER_DESC " " DRIVER_VERSION); return 0; +failed_usb_register: + usb_serial_deregister(&mct_u232_device); +failed_usb_serial_register: + return retval; } diff -Nru a/drivers/usb/serial/omninet.c b/drivers/usb/serial/omninet.c --- a/drivers/usb/serial/omninet.c Tue Sep 2 19:58:18 2003 +++ b/drivers/usb/serial/omninet.c Tue Sep 2 19:58:18 2003 @@ -375,10 +375,19 @@ static int __init omninet_init (void) { - usb_serial_register (&zyxel_omninet_device); - usb_register (&omninet_driver); + int retval; + retval = usb_serial_register(&zyxel_omninet_device); + if (retval) + goto failed_usb_serial_register; + retval = usb_register(&omninet_driver); + if (retval) + goto failed_usb_register; info(DRIVER_VERSION ":" DRIVER_DESC); return 0; +failed_usb_register: + usb_serial_deregister(&zyxel_omninet_device); +failed_usb_serial_register: + return retval; } diff -Nru a/drivers/usb/serial/pl2303.c b/drivers/usb/serial/pl2303.c --- a/drivers/usb/serial/pl2303.c Tue Sep 2 19:58:15 2003 +++ b/drivers/usb/serial/pl2303.c Tue Sep 2 19:58:15 2003 @@ -768,10 +768,19 @@ static int __init pl2303_init (void) { - usb_serial_register (&pl2303_device); - usb_register (&pl2303_driver); + int retval; + retval = usb_serial_register(&pl2303_device); + if (retval) + goto failed_usb_serial_register; + retval = usb_register(&pl2303_driver); + if (retval) + goto failed_usb_register; info(DRIVER_DESC " " DRIVER_VERSION); return 0; +failed_usb_register: + usb_serial_deregister(&pl2303_device); +failed_usb_serial_register: + return retval; } diff -Nru a/drivers/usb/serial/safe_serial.c b/drivers/usb/serial/safe_serial.c --- a/drivers/usb/serial/safe_serial.c Tue Sep 2 19:58:14 2003 +++ b/drivers/usb/serial/safe_serial.c Tue Sep 2 19:58:14 2003 @@ -1,8 +1,8 @@ /* * Safe Encapsulated USB Serial Driver * - * Copyright (c) 2001 Lineo - * Copyright (c) 2001 Hewlett-Packard + * Copyright (C) 2001 Lineo + * Copyright (C) 2001 Hewlett-Packard * * 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 @@ -422,7 +422,7 @@ static int __init safe_init (void) { - int i; + int i, retval; info (DRIVER_VERSION " " DRIVER_AUTHOR); info (DRIVER_DESC); @@ -441,10 +441,18 @@ } } - usb_serial_register (&safe_device); - usb_register (&safe_driver); + retval = usb_serial_register(&safe_device); + if (retval) + goto failed_usb_serial_register; + retval = usb_register(&safe_driver); + if (retval) + goto failed_usb_register; return 0; +failed_usb_register: + usb_serial_deregister(&safe_device); +failed_usb_serial_register: + return retval; } static void __exit safe_exit (void) diff -Nru a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c --- a/drivers/usb/serial/usb-serial.c Tue Sep 2 19:58:15 2003 +++ b/drivers/usb/serial/usb-serial.c Tue Sep 2 19:58:15 2003 @@ -2,8 +2,8 @@ * USB Serial Converter driver * * Copyright (C) 1999 - 2003 Greg Kroah-Hartman (greg@kroah.com) - * Copyright (c) 2000 Peter Berger (pberger@brimson.com) - * Copyright (c) 2000 Al Borchers (borchers@steinerpoint.com) + * Copyright (C) 2000 Peter Berger (pberger@brimson.com) + * Copyright (C) 2000 Al Borchers (borchers@steinerpoint.com) * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License version @@ -871,7 +871,8 @@ /* the ports are cleaned up and released in port_release() */ for (i = 0; i < serial->num_ports; ++i) - device_unregister(&serial->port[i]->dev); + if (serial->port[i]->dev.parent != NULL) + device_unregister(&serial->port[i]->dev); /* If this is a "fake" port, we have to clean it up here, as it will * not get cleaned up in port_release() as it was never registered with diff -Nru a/drivers/usb/serial/visor.c b/drivers/usb/serial/visor.c --- a/drivers/usb/serial/visor.c Tue Sep 2 19:58:14 2003 +++ b/drivers/usb/serial/visor.c Tue Sep 2 19:58:14 2003 @@ -225,11 +225,16 @@ .driver_info = (kernel_ulong_t)&palm_os_4_probe }, { USB_DEVICE(SONY_VENDOR_ID, SONY_CLIE_S360_ID), .driver_info = (kernel_ulong_t)&palm_os_4_probe }, - { USB_DEVICE(SONY_VENDOR_ID, SONY_CLIE_4_1_ID) }, + { USB_DEVICE(SONY_VENDOR_ID, SONY_CLIE_4_1_ID), + .driver_info = (kernel_ulong_t)&palm_os_4_probe }, { USB_DEVICE(SONY_VENDOR_ID, SONY_CLIE_NX60_ID), .driver_info = (kernel_ulong_t)&palm_os_4_probe }, { USB_DEVICE(SONY_VENDOR_ID, SONY_CLIE_NZ90V_ID), .driver_info = (kernel_ulong_t)&palm_os_4_probe }, + { USB_DEVICE(SAMSUNG_VENDOR_ID, SAMSUNG_SCH_I330_ID), + .driver_info = (kernel_ulong_t)&palm_os_4_probe }, + { USB_DEVICE(GARMIN_VENDOR_ID, GARMIN_IQUE_3600_ID), + .driver_info = (kernel_ulong_t)&palm_os_4_probe }, { }, /* optional parameter entry */ { } /* Terminating entry */ }; @@ -258,6 +263,8 @@ { USB_DEVICE(SONY_VENDOR_ID, SONY_CLIE_4_1_ID) }, { USB_DEVICE(SONY_VENDOR_ID, SONY_CLIE_NX60_ID) }, { USB_DEVICE(SONY_VENDOR_ID, SONY_CLIE_NZ90V_ID) }, + { USB_DEVICE(SAMSUNG_VENDOR_ID, SAMSUNG_SCH_I330_ID) }, + { USB_DEVICE(GARMIN_VENDOR_ID, GARMIN_IQUE_3600_ID) }, { }, /* optional parameter entry */ { } /* Terminating entry */ }; @@ -649,7 +656,7 @@ transfer_buffer = kmalloc (sizeof (*connection_info), GFP_KERNEL); if (!transfer_buffer) { - dev_err(dev, "%s - kmalloc(%d) failed.\n", __FUNCTION__, + dev_err(dev, "%s - kmalloc(%Zd) failed.\n", __FUNCTION__, sizeof(*connection_info)); return -ENOMEM; } @@ -735,7 +742,7 @@ transfer_buffer = kmalloc (sizeof (*connection_info), GFP_KERNEL); if (!transfer_buffer) { - dev_err(dev, "%s - kmalloc(%d) failed.\n", __FUNCTION__, + dev_err(dev, "%s - kmalloc(%Zd) failed.\n", __FUNCTION__, sizeof(*connection_info)); return -ENOMEM; } @@ -956,7 +963,7 @@ static int __init visor_init (void) { - int i; + int i, retval; /* Only if parameters were passed to us */ if ((vendor>0) && (product>0)) { struct usb_device_id usb_dev_temp[]= @@ -983,12 +990,24 @@ info("Adding Palm OS protocol 4.x support for unknown device: 0x%x/0x%x", vendor, product); } - usb_serial_register (&handspring_device); - usb_serial_register (&clie_3_5_device); - usb_register (&visor_driver); + retval = usb_serial_register(&handspring_device); + if (retval) + goto failed_handspring_register; + retval = usb_serial_register(&clie_3_5_device); + if (retval) + goto failed_clie_3_5_register; + retval = usb_register(&visor_driver); + if (retval) + goto failed_usb_register; info(DRIVER_DESC " " DRIVER_VERSION); return 0; +failed_usb_register: + usb_serial_deregister(&clie_3_5_device); +failed_clie_3_5_register: + usb_serial_deregister(&handspring_device); +failed_handspring_register: + return retval; } diff -Nru a/drivers/usb/serial/visor.h b/drivers/usb/serial/visor.h --- a/drivers/usb/serial/visor.h Tue Sep 2 19:58:18 2003 +++ b/drivers/usb/serial/visor.h Tue Sep 2 19:58:18 2003 @@ -41,6 +41,12 @@ #define SONY_CLIE_NX60_ID 0x00DA #define SONY_CLIE_NZ90V_ID 0x00E9 +#define SAMSUNG_VENDOR_ID 0x04E8 +#define SAMSUNG_SCH_I330_ID 0x8001 + +#define GARMIN_VENDOR_ID 0x091E +#define GARMIN_IQUE_3600_ID 0x0004 + /**************************************************************************** * Handspring Visor Vendor specific request codes (bRequest values) * A big thank you to Handspring for providing the following information. diff -Nru a/drivers/usb/serial/whiteheat.c b/drivers/usb/serial/whiteheat.c --- a/drivers/usb/serial/whiteheat.c Tue Sep 2 19:58:15 2003 +++ b/drivers/usb/serial/whiteheat.c Tue Sep 2 19:58:15 2003 @@ -1486,11 +1486,24 @@ *****************************************************************************/ static int __init whiteheat_init (void) { - usb_serial_register (&whiteheat_fake_device); - usb_serial_register (&whiteheat_device); - usb_register (&whiteheat_driver); + int retval; + retval = usb_serial_register(&whiteheat_fake_device); + if (retval) + goto failed_fake_register; + retval = usb_serial_register(&whiteheat_device); + if (retval) + goto failed_device_register; + retval = usb_register(&whiteheat_driver); + if (retval) + goto failed_usb_register; info(DRIVER_DESC " " DRIVER_VERSION); return 0; +failed_usb_register: + usb_serial_deregister(&whiteheat_device); +failed_device_register: + usb_serial_deregister(&whiteheat_fake_device); +failed_fake_register: + return retval; } diff -Nru a/drivers/usb/serial/xircom_pgs_fw.h b/drivers/usb/serial/xircom_pgs_fw.h --- a/drivers/usb/serial/xircom_pgs_fw.h Tue Sep 2 19:58:13 2003 +++ b/drivers/usb/serial/xircom_pgs_fw.h Tue Sep 2 19:58:13 2003 @@ -1,8 +1,8 @@ /* * USB Xircom PGS Firmware * - * Copyright (c) 1999, 2000 Brian Warner - * Copyright (c) 2001 Cristian M. Craciunescu + * Copyright (C) 1999, 2000 Brian Warner + * Copyright (C) 2001 Cristian M. Craciunescu * * 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 diff -Nru a/drivers/usb/storage/isd200.c b/drivers/usb/storage/isd200.c --- a/drivers/usb/storage/isd200.c Tue Sep 2 19:58:16 2003 +++ b/drivers/usb/storage/isd200.c Tue Sep 2 19:58:16 2003 @@ -272,8 +272,9 @@ struct isd200_info { struct inquiry_data InquiryData; - struct hd_driveid drive; + struct hd_driveid *id; struct isd200_config ConfigData; + unsigned char *RegsBuf; unsigned char ATARegs[8]; unsigned char DeviceHead; unsigned char DeviceFlags; @@ -473,7 +474,7 @@ ata.generic.RegisterSelect = REG_COMMAND; ata.write.CommandByte = WIN_IDENTIFY; srb->sc_data_direction = SCSI_DATA_READ; - srb->request_buffer = (void *)&info->drive; + srb->request_buffer = (void *) info->id; srb->request_bufflen = sizeof(struct hd_driveid); break; @@ -513,11 +514,12 @@ US_DEBUGP("Entering isd200_IssueATAReadRegs\n"); transferStatus = isd200_action( us, ACTION_READ_STATUS, - info->ATARegs, sizeof(info->ATARegs) ); + info->RegsBuf, sizeof(info->ATARegs) ); if (transferStatus != ISD200_TRANSPORT_GOOD) { US_DEBUGP(" Error reading ATA registers\n"); retStatus = ISD200_ERROR; } else { + memcpy(info->ATARegs, info->RegsBuf, sizeof(info->ATARegs)); US_DEBUGP(" Got ATA Register[IDE_ERROR_OFFSET] = 0x%x\n", info->ATARegs[IDE_ERROR_OFFSET]); } @@ -835,9 +837,9 @@ int detect ) { int status = ISD200_GOOD; - unsigned char *regs = us->iobuf; unsigned long endTime; struct isd200_info *info = (struct isd200_info *)us->extra; + unsigned char *regs = info->RegsBuf; int recheckAsMaster = FALSE; if ( detect ) @@ -984,6 +986,7 @@ { struct isd200_info *info = (struct isd200_info *)us->extra; int retStatus = ISD200_GOOD; + struct hd_driveid *id = info->id; US_DEBUGP("Entering isd200_get_inquiry_data\n"); @@ -1000,7 +1003,7 @@ /* this must be an ATA device */ /* perform an ATA Command Identify */ transferStatus = isd200_action( us, ACTION_IDENTIFY, - &info->drive, + id, sizeof(struct hd_driveid) ); if (transferStatus != ISD200_TRANSPORT_GOOD) { /* Error issuing ATA Command Identify */ @@ -1010,35 +1013,35 @@ /* ATA Command Identify successful */ int i; __u16 *src, *dest; - ide_fix_driveid(&info->drive); + ide_fix_driveid(id); US_DEBUGP(" Identify Data Structure:\n"); - US_DEBUGP(" config = 0x%x\n", info->drive.config); - US_DEBUGP(" cyls = 0x%x\n", info->drive.cyls); - US_DEBUGP(" heads = 0x%x\n", info->drive.heads); - US_DEBUGP(" track_bytes = 0x%x\n", info->drive.track_bytes); - US_DEBUGP(" sector_bytes = 0x%x\n", info->drive.sector_bytes); - US_DEBUGP(" sectors = 0x%x\n", info->drive.sectors); - US_DEBUGP(" serial_no[0] = 0x%x\n", info->drive.serial_no[0]); - US_DEBUGP(" buf_type = 0x%x\n", info->drive.buf_type); - US_DEBUGP(" buf_size = 0x%x\n", info->drive.buf_size); - US_DEBUGP(" ecc_bytes = 0x%x\n", info->drive.ecc_bytes); - US_DEBUGP(" fw_rev[0] = 0x%x\n", info->drive.fw_rev[0]); - US_DEBUGP(" model[0] = 0x%x\n", info->drive.model[0]); - US_DEBUGP(" max_multsect = 0x%x\n", info->drive.max_multsect); - US_DEBUGP(" dword_io = 0x%x\n", info->drive.dword_io); - US_DEBUGP(" capability = 0x%x\n", info->drive.capability); - US_DEBUGP(" tPIO = 0x%x\n", info->drive.tPIO); - US_DEBUGP(" tDMA = 0x%x\n", info->drive.tDMA); - US_DEBUGP(" field_valid = 0x%x\n", info->drive.field_valid); - US_DEBUGP(" cur_cyls = 0x%x\n", info->drive.cur_cyls); - US_DEBUGP(" cur_heads = 0x%x\n", info->drive.cur_heads); - US_DEBUGP(" cur_sectors = 0x%x\n", info->drive.cur_sectors); - US_DEBUGP(" cur_capacity = 0x%x\n", (info->drive.cur_capacity1 << 16) + info->drive.cur_capacity0 ); - US_DEBUGP(" multsect = 0x%x\n", info->drive.multsect); - US_DEBUGP(" lba_capacity = 0x%x\n", info->drive.lba_capacity); - US_DEBUGP(" command_set_1 = 0x%x\n", info->drive.command_set_1); - US_DEBUGP(" command_set_2 = 0x%x\n", info->drive.command_set_2); + US_DEBUGP(" config = 0x%x\n", id->config); + US_DEBUGP(" cyls = 0x%x\n", id->cyls); + US_DEBUGP(" heads = 0x%x\n", id->heads); + US_DEBUGP(" track_bytes = 0x%x\n", id->track_bytes); + US_DEBUGP(" sector_bytes = 0x%x\n", id->sector_bytes); + US_DEBUGP(" sectors = 0x%x\n", id->sectors); + US_DEBUGP(" serial_no[0] = 0x%x\n", id->serial_no[0]); + US_DEBUGP(" buf_type = 0x%x\n", id->buf_type); + US_DEBUGP(" buf_size = 0x%x\n", id->buf_size); + US_DEBUGP(" ecc_bytes = 0x%x\n", id->ecc_bytes); + US_DEBUGP(" fw_rev[0] = 0x%x\n", id->fw_rev[0]); + US_DEBUGP(" model[0] = 0x%x\n", id->model[0]); + US_DEBUGP(" max_multsect = 0x%x\n", id->max_multsect); + US_DEBUGP(" dword_io = 0x%x\n", id->dword_io); + US_DEBUGP(" capability = 0x%x\n", id->capability); + US_DEBUGP(" tPIO = 0x%x\n", id->tPIO); + US_DEBUGP(" tDMA = 0x%x\n", id->tDMA); + US_DEBUGP(" field_valid = 0x%x\n", id->field_valid); + US_DEBUGP(" cur_cyls = 0x%x\n", id->cur_cyls); + US_DEBUGP(" cur_heads = 0x%x\n", id->cur_heads); + US_DEBUGP(" cur_sectors = 0x%x\n", id->cur_sectors); + US_DEBUGP(" cur_capacity = 0x%x\n", (id->cur_capacity1 << 16) + id->cur_capacity0 ); + US_DEBUGP(" multsect = 0x%x\n", id->multsect); + US_DEBUGP(" lba_capacity = 0x%x\n", id->lba_capacity); + US_DEBUGP(" command_set_1 = 0x%x\n", id->command_set_1); + US_DEBUGP(" command_set_2 = 0x%x\n", id->command_set_2); memset(&info->InquiryData, 0, sizeof(info->InquiryData)); @@ -1054,30 +1057,30 @@ /* The length must be at least 36 (5 + 31) */ info->InquiryData.AdditionalLength = 0x1F; - if (info->drive.command_set_1 & COMMANDSET_MEDIA_STATUS) { + if (id->command_set_1 & COMMANDSET_MEDIA_STATUS) { /* set the removable bit */ info->InquiryData.DeviceTypeModifier = DEVICE_REMOVABLE; info->DeviceFlags |= DF_REMOVABLE_MEDIA; } /* Fill in vendor identification fields */ - src = (__u16*)info->drive.model; + src = (__u16*)id->model; dest = (__u16*)info->InquiryData.VendorId; for (i=0;i<4;i++) dest[i] = be16_to_cpu(src[i]); - src = (__u16*)(info->drive.model+8); + src = (__u16*)(id->model+8); dest = (__u16*)info->InquiryData.ProductId; for (i=0;i<8;i++) dest[i] = be16_to_cpu(src[i]); - src = (__u16*)info->drive.fw_rev; + src = (__u16*)id->fw_rev; dest = (__u16*)info->InquiryData.ProductRevisionLevel; for (i=0;i<2;i++) dest[i] = be16_to_cpu(src[i]); /* determine if it supports Media Status Notification */ - if (info->drive.command_set_2 & COMMANDSET_MEDIA_STATUS) { + if (id->command_set_2 & COMMANDSET_MEDIA_STATUS) { US_DEBUGP(" Device supports Media Status Notification\n"); /* Indicate that it is enabled, even though it is not @@ -1101,11 +1104,9 @@ US_DEBUGP("Protocol changed to: %s\n", us->protocol_name); /* Free driver structure */ - if (us->extra != NULL) { - kfree(us->extra); - us->extra = NULL; - us->extra_destructor = NULL; - } + us->extra_destructor(info); + us->extra = NULL; + us->extra_destructor = NULL; } } @@ -1182,6 +1183,7 @@ union ata_cdb * ataCdb) { struct isd200_info *info = (struct isd200_info *)us->extra; + struct hd_driveid *id = info->id; int sendToTransport = TRUE; unsigned char sectnum, head; unsigned short cylinder; @@ -1254,12 +1256,12 @@ US_DEBUGP(" ATA OUT - SCSIOP_READ_CAPACITY\n"); - if (info->drive.capability & CAPABILITY_LBA ) { - capacity = info->drive.lba_capacity - 1; + if (id->capability & CAPABILITY_LBA ) { + capacity = id->lba_capacity - 1; } else { - capacity = (info->drive.heads * - info->drive.cyls * - info->drive.sectors) - 1; + capacity = (id->heads * + id->cyls * + id->sectors) - 1; } readCapacityData.LogicalBlockAddress = cpu_to_be32(capacity); readCapacityData.BytesPerBlock = cpu_to_be32(0x200); @@ -1280,16 +1282,16 @@ lba = cpu_to_be32(lba); blockCount = (unsigned long)srb->cmnd[7]<<8 | (unsigned long)srb->cmnd[8]; - if (info->drive.capability & CAPABILITY_LBA) { + if (id->capability & CAPABILITY_LBA) { sectnum = (unsigned char)(lba); cylinder = (unsigned short)(lba>>8); head = ATA_ADDRESS_DEVHEAD_LBA_MODE | (unsigned char)(lba>>24 & 0x0F); } else { - sectnum = (unsigned char)((lba % info->drive.sectors) + 1); - cylinder = (unsigned short)(lba / (info->drive.sectors * - info->drive.heads)); - head = (unsigned char)((lba / info->drive.sectors) % - info->drive.heads); + sectnum = (unsigned char)((lba % id->sectors) + 1); + cylinder = (unsigned short)(lba / (id->sectors * + id->heads)); + head = (unsigned char)((lba / id->sectors) % + id->heads); } ataCdb->generic.SignatureByte0 = info->ConfigData.ATAMajorCommand; ataCdb->generic.SignatureByte1 = info->ConfigData.ATAMinorCommand; @@ -1313,14 +1315,14 @@ lba = cpu_to_be32(lba); blockCount = (unsigned long)srb->cmnd[7]<<8 | (unsigned long)srb->cmnd[8]; - if (info->drive.capability & CAPABILITY_LBA) { + if (id->capability & CAPABILITY_LBA) { sectnum = (unsigned char)(lba); cylinder = (unsigned short)(lba>>8); head = ATA_ADDRESS_DEVHEAD_LBA_MODE | (unsigned char)(lba>>24 & 0x0F); } else { - sectnum = (unsigned char)((lba % info->drive.sectors) + 1); - cylinder = (unsigned short)(lba / (info->drive.sectors * info->drive.heads)); - head = (unsigned char)((lba / info->drive.sectors) % info->drive.heads); + sectnum = (unsigned char)((lba % id->sectors) + 1); + cylinder = (unsigned short)(lba / (id->sectors * id->heads)); + head = (unsigned char)((lba / id->sectors) % id->heads); } ataCdb->generic.SignatureByte0 = info->ConfigData.ATAMajorCommand; ataCdb->generic.SignatureByte1 = info->ConfigData.ATAMinorCommand; @@ -1398,6 +1400,21 @@ /************************************************************************** + * isd200_free_info + * + * Frees the driver structure. + */ +void isd200_free_info_ptrs(void *info_) +{ + struct isd200_info *info = (struct isd200_info *) info_; + + if (info) { + kfree(info->id); + kfree(info->RegsBuf); + } +} + +/************************************************************************** * isd200_init_info * * Allocates (if necessary) and initializes the driver structure. @@ -1408,18 +1425,31 @@ int isd200_init_info(struct us_data *us) { int retStatus = ISD200_GOOD; + struct isd200_info *info; - if (!us->extra) { - us->extra = (void *) kmalloc(sizeof(struct isd200_info), GFP_KERNEL); - if (!us->extra) { - US_DEBUGP("ERROR - kmalloc failure\n"); + info = (struct isd200_info *) + kmalloc(sizeof(struct isd200_info), GFP_KERNEL); + if (!info) + retStatus = ISD200_ERROR; + else { + memset(info, 0, sizeof(struct isd200_info)); + info->id = (struct hd_driveid *) + kmalloc(sizeof(struct hd_driveid), GFP_KERNEL); + info->RegsBuf = (unsigned char *) + kmalloc(sizeof(info->ATARegs), GFP_KERNEL); + if (!info->id || !info->RegsBuf) { + isd200_free_info_ptrs(info); + kfree(info); retStatus = ISD200_ERROR; - } + } else + memset(info->id, 0, sizeof(struct hd_driveid)); } if (retStatus == ISD200_GOOD) { - memset(us->extra, 0, sizeof(struct isd200_info)); - } + us->extra = info; + us->extra_destructor = isd200_free_info_ptrs; + } else + US_DEBUGP("ERROR - kmalloc failure\n"); return(retStatus); } diff -Nru a/drivers/usb/storage/sddr09.c b/drivers/usb/storage/sddr09.c --- a/drivers/usb/storage/sddr09.c Tue Sep 2 19:58:18 2003 +++ b/drivers/usb/storage/sddr09.c Tue Sep 2 19:58:18 2003 @@ -34,6 +34,7 @@ #include "debug.h" #include "sddr09.h" +#include #include #include #include diff -Nru a/drivers/usb/storage/transport.c b/drivers/usb/storage/transport.c --- a/drivers/usb/storage/transport.c Tue Sep 2 19:58:15 2003 +++ b/drivers/usb/storage/transport.c Tue Sep 2 19:58:15 2003 @@ -942,11 +942,11 @@ memcpy(bcb->CDB, srb->cmnd, bcb->Length); /* send it to out endpoint */ - US_DEBUGP("Bulk command S 0x%x T 0x%x Trg %d LUN %d L %d F %d CL %d\n", + US_DEBUGP("Bulk Command S 0x%x T 0x%x L %d F %d Trg %d LUN %d CL %d\n", le32_to_cpu(bcb->Signature), bcb->Tag, + le32_to_cpu(bcb->DataTransferLength), bcb->Flags, (bcb->Lun >> 4), (bcb->Lun & 0x0F), - le32_to_cpu(bcb->DataTransferLength), - bcb->Flags, bcb->Length); + bcb->Length); result = usb_stor_bulk_transfer_buf(us, us->send_bulk_pipe, bcb, US_BULK_CB_WRAP_LEN, NULL); US_DEBUGP("Bulk command transfer result=%d\n", result); @@ -999,7 +999,7 @@ return USB_STOR_TRANSPORT_ERROR; /* check bulk status */ - US_DEBUGP("Bulk status Sig 0x%x T 0x%x R %d Stat 0x%x\n", + US_DEBUGP("Bulk Status S 0x%x T 0x%x R %d Stat 0x%x\n", le32_to_cpu(bcs->Signature), bcs->Tag, bcs->Residue, bcs->Status); if ((bcs->Signature != cpu_to_le32(US_BULK_CS_SIGN) && diff -Nru a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h --- a/drivers/usb/storage/unusual_devs.h Tue Sep 2 19:58:18 2003 +++ b/drivers/usb/storage/unusual_devs.h Tue Sep 2 19:58:18 2003 @@ -264,7 +264,7 @@ UNUSUAL_DEV( 0x054c, 0x002e, 0x0106, 0x0310, "Sony", "Handycam", - US_SC_SCSI, US_PR_CB, NULL, + US_SC_SCSI, US_PR_DEVICE, NULL, US_FL_SINGLE_LUN | US_FL_MODE_XLATE), UNUSUAL_DEV( 0x054c, 0x0032, 0x0000, 0x9999, diff -Nru a/drivers/usb/storage/usb.c b/drivers/usb/storage/usb.c --- a/drivers/usb/storage/usb.c Tue Sep 2 19:58:14 2003 +++ b/drivers/usb/storage/usb.c Tue Sep 2 19:58:14 2003 @@ -1006,20 +1006,23 @@ * Initialization and registration ***********************************************************************/ -int __init usb_stor_init(void) +static int __init usb_stor_init(void) { + int retval; printk(KERN_INFO "Initializing USB Mass Storage driver...\n"); - /* register the driver, return -1 if error */ - if (usb_register(&usb_storage_driver) < 0) - return -1; + /* register the driver, return usb_register return code if error */ + retval = usb_register(&usb_storage_driver); + if (retval) + goto out; /* we're all set */ printk(KERN_INFO "USB Mass Storage support registered.\n"); - return 0; +out: + return retval; } -void __exit usb_stor_exit(void) +static void __exit usb_stor_exit(void) { US_DEBUGP("usb_stor_exit() called\n"); diff -Nru a/drivers/usb/storage/usb.h b/drivers/usb/storage/usb.h --- a/drivers/usb/storage/usb.h Tue Sep 2 19:58:17 2003 +++ b/drivers/usb/storage/usb.h Tue Sep 2 19:58:17 2003 @@ -48,7 +48,6 @@ #include #include #include -#include #include "scsi.h" #include "hosts.h" diff -Nru a/drivers/usb/usb-skeleton.c b/drivers/usb/usb-skeleton.c --- a/drivers/usb/usb-skeleton.c Tue Sep 2 19:58:15 2003 +++ b/drivers/usb/usb-skeleton.c Tue Sep 2 19:58:15 2003 @@ -1,7 +1,7 @@ /* * USB Skeleton driver - 1.1 * - * Copyright (c) 2001-2003 Greg Kroah-Hartman (greg@kroah.com) + * Copyright (C) 2001-2003 Greg Kroah-Hartman (greg@kroah.com) * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as @@ -229,7 +229,7 @@ dbg("%s", __FUNCTION__); - subminor = minor (inode->i_rdev); + subminor = iminor(inode); /* prevent disconnects */ down (&disconnect_sem); @@ -295,7 +295,7 @@ if (atomic_read (&dev->write_busy)) wait_for_completion (&dev->write_finished); - dev->open = 0; + --dev->open; if (!dev->present) { /* the device was unplugged before the file was released */ @@ -677,10 +677,10 @@ /* register this driver with the USB subsystem */ result = usb_register(&skel_driver); - if (result < 0) { + if (result) { err("usb_register failed. Error number %d", result); - return -1; + return result; } info(DRIVER_DESC " " DRIVER_VERSION); diff -Nru a/drivers/video/68328fb.c b/drivers/video/68328fb.c --- a/drivers/video/68328fb.c Tue Sep 2 19:58:17 2003 +++ b/drivers/video/68328fb.c Tue Sep 2 19:58:17 2003 @@ -401,12 +401,12 @@ ((1<<(width))-1)) : 0)) static struct fb_ops mc68328_fb_ops = { - .owner: THIS_MODULE, - .fb_setcolreg: mc68328fb_setcolreg, - .fb_fillrect: cfbfillrect, - .fb_copyarea: cfbcopyarea, - .fb_imageblit: cfbimgblt, - .fb_cursor: softcursor, + .owner = THIS_MODULE, + .fb_setcolreg = mc68328fb_setcolreg, + .fb_fillrect = cfbfillrect, + .fb_copyarea = cfbcopyarea, + .fb_imageblit = cfbimgblt, + .fb_cursor = softcursor, }; diff -Nru a/drivers/video/Kconfig b/drivers/video/Kconfig --- a/drivers/video/Kconfig Tue Sep 2 19:58:12 2003 +++ b/drivers/video/Kconfig Tue Sep 2 19:58:12 2003 @@ -40,7 +40,7 @@ config FB_CIRRUS tristate "Cirrus Logic support" - depends on FB && (AMIGA || PCI) + depends on FB && (AMIGA || PCI) && BROKEN ---help--- This enables support for Cirrus Logic GD542x/543x based boards on Amiga: SD64, Piccolo, Picasso II/II+, Picasso IV, or EGS Spectrum. @@ -55,7 +55,7 @@ config FB_PM2 tristate "Permedia2 support" - depends on FB && (AMIGA || PCI) + depends on FB && (AMIGA || PCI) && BROKEN help This is the frame buffer device driver for the Permedia2 AGP frame buffer card from ASK, aka `Graphic Blaster Exxtreme'. There is a @@ -802,7 +802,7 @@ config FB_PM3 tristate "Permedia3 support" - depends on FB && PCI + depends on FB && PCI && BROKEN help This is the frame buffer device driver for the 3DLabs Permedia3 chipset, used in Formac ProFormance III, 3DLabs Oxygen VX1 & diff -Nru a/drivers/video/Makefile b/drivers/video/Makefile --- a/drivers/video/Makefile Tue Sep 2 19:58:13 2003 +++ b/drivers/video/Makefile Tue Sep 2 19:58:13 2003 @@ -24,8 +24,8 @@ obj-$(CONFIG_FB_RADEON) += radeonfb.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o obj-$(CONFIG_FB_NEOMAGIC) += neofb.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o obj-$(CONFIG_FB_IGA) += igafb.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o -obj-$(CONFIG_FB_CONTROL) += controlfb.o -obj-$(CONFIG_FB_PLATINUM) += platinumfb.o +obj-$(CONFIG_FB_CONTROL) += controlfb.o macmodes.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o +obj-$(CONFIG_FB_PLATINUM) += platinumfb.o macmodes.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o obj-$(CONFIG_FB_VALKYRIE) += valkyriefb.o macmodes.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o obj-$(CONFIG_FB_CT65550) += chipsfb.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o obj-$(CONFIG_FB_ANAKIN) += anakinfb.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o diff -Nru a/drivers/video/controlfb.c b/drivers/video/controlfb.c --- a/drivers/video/controlfb.c Tue Sep 2 19:58:14 2003 +++ b/drivers/video/controlfb.c Tue Sep 2 19:58:14 2003 @@ -475,7 +475,7 @@ /* Apply default var */ var.activate = FB_ACTIVATE_NOW; - rc = fb_set_var(&var, &p->info); + rc = fb_set_var(&p->info, &var); if (rc && (vmode != VMODE_640_480_60 || cmode != CMODE_8)) goto try_again; diff -Nru a/drivers/video/fbmem.c b/drivers/video/fbmem.c --- a/drivers/video/fbmem.c Tue Sep 2 19:58:12 2003 +++ b/drivers/video/fbmem.c Tue Sep 2 19:58:12 2003 @@ -768,7 +768,7 @@ { unsigned long p = *ppos; struct inode *inode = file->f_dentry->d_inode; - int fbidx = minor(inode->i_rdev); + int fbidx = iminor(inode); struct fb_info *info = registered_fb[fbidx]; if (!info || ! info->screen_base) @@ -802,7 +802,7 @@ { unsigned long p = *ppos; struct inode *inode = file->f_dentry->d_inode; - int fbidx = minor(inode->i_rdev); + int fbidx = iminor(inode); struct fb_info *info = registered_fb[fbidx]; int err; @@ -964,7 +964,7 @@ fb_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) { - int fbidx = minor(inode->i_rdev); + int fbidx = iminor(inode); struct fb_info *info = registered_fb[fbidx]; struct fb_ops *fb = info->fbops; struct fb_var_screeninfo var; @@ -1050,7 +1050,7 @@ static int fb_mmap(struct file *file, struct vm_area_struct * vma) { - int fbidx = minor(file->f_dentry->d_inode->i_rdev); + int fbidx = iminor(file->f_dentry->d_inode); struct fb_info *info = registered_fb[fbidx]; struct fb_ops *fb = info->fbops; unsigned long off; @@ -1149,7 +1149,7 @@ static int fb_open(struct inode *inode, struct file *file) { - int fbidx = minor(inode->i_rdev); + int fbidx = iminor(inode); struct fb_info *info; int res = 0; @@ -1174,7 +1174,7 @@ static int fb_release(struct inode *inode, struct file *file) { - int fbidx = minor(inode->i_rdev); + int fbidx = iminor(inode); struct fb_info *info; lock_kernel(); diff -Nru a/drivers/video/platinumfb.c b/drivers/video/platinumfb.c --- a/drivers/video/platinumfb.c Tue Sep 2 19:58:15 2003 +++ b/drivers/video/platinumfb.c Tue Sep 2 19:58:15 2003 @@ -35,6 +35,7 @@ #include #include #include +#include #include "macmodes.h" #include "platinumfb.h" @@ -87,7 +88,6 @@ * internal functions */ -static void platinum_of_init(struct device_node *dp); static inline int platinum_vram_reqd(int video_mode, int color_mode); static int read_platinum_sense(struct fb_info_platinum *info); static void set_platinum_clock(struct fb_info_platinum *info); @@ -323,7 +323,7 @@ /* * Set misc info vars for this driver */ -static void __init platinum_init_info(struct fb_info *info, struct fb_info_platinum *p) +static void __devinit platinum_init_info(struct fb_info *info, struct fb_info_platinum *p) { /* Fill fb_info */ info->par = &p->par; @@ -349,7 +349,7 @@ } -static int __init init_platinum(struct fb_info_platinum *p) +static int __devinit platinum_init_fb(struct fb_info_platinum *p) { struct fb_var_screeninfo var; int sense, rc; @@ -399,126 +399,21 @@ /* Apply default var */ p->info.var = var; var.activate = FB_ACTIVATE_NOW; - rc = fb_set_var(&var, &p->info); + rc = fb_set_var(&p->info, &var); if (rc && (default_vmode != VMODE_640_480_60 || default_cmode != CMODE_8)) goto try_again; /* Register with fbdev layer */ - if (register_framebuffer(&p->info) < 0) - return 0; + rc = register_framebuffer(&p->info); + if (rc < 0) + return rc; printk(KERN_INFO "fb%d: platinum frame buffer device\n", p->info.node); - return 1; -} - -int __init platinum_init(void) -{ - struct device_node *dp; - - dp = find_devices("platinum"); - if (dp != 0) - platinum_of_init(dp); return 0; } -#ifdef __powerpc__ -#define invalidate_cache(addr) \ - asm volatile("eieio; dcbf 0,%1" \ - : "=m" (*(addr)) : "r" (addr) : "memory"); -#else -#define invalidate_cache(addr) -#endif - -static void __init platinum_of_init(struct device_node *dp) -{ - struct fb_info_platinum *info; - unsigned long addr, size; - volatile __u8 *fbuffer; - int i, bank0, bank1, bank2, bank3; - - if(dp->n_addrs != 2) { - printk(KERN_ERR "expecting 2 address for platinum (got %d)", dp->n_addrs); - return; - } - - info = kmalloc(sizeof(*info), GFP_ATOMIC); - if (info == 0) - return; - memset(info, 0, sizeof(*info)); - - /* Map in frame buffer and registers */ - for (i = 0; i < dp->n_addrs; ++i) { - addr = dp->addrs[i].address; - size = dp->addrs[i].size; - /* Let's assume we can request either all or nothing */ - if (!request_mem_region(addr, size, "platinumfb")) { - kfree(info); - return; - } - if (size >= 0x400000) { - /* frame buffer - map only 4MB */ - info->frame_buffer_phys = addr; - info->frame_buffer = __ioremap(addr, 0x400000, _PAGE_WRITETHRU); - info->base_frame_buffer = info->frame_buffer; - } else { - /* registers */ - info->platinum_regs_phys = addr; - info->platinum_regs = ioremap(addr, size); - } - } - - info->cmap_regs_phys = 0xf301b000; /* XXX not in prom? */ - request_mem_region(info->cmap_regs_phys, 0x1000, "platinumfb cmap"); - info->cmap_regs = ioremap(info->cmap_regs_phys, 0x1000); - - /* Grok total video ram */ - out_be32(&info->platinum_regs->reg[16].r, (unsigned)info->frame_buffer_phys); - out_be32(&info->platinum_regs->reg[20].r, 0x1011); /* select max vram */ - out_be32(&info->platinum_regs->reg[24].r, 0); /* switch in vram */ - - fbuffer = info->base_frame_buffer; - fbuffer[0x100000] = 0x34; - fbuffer[0x100008] = 0x0; - invalidate_cache(&fbuffer[0x100000]); - fbuffer[0x200000] = 0x56; - fbuffer[0x200008] = 0x0; - invalidate_cache(&fbuffer[0x200000]); - fbuffer[0x300000] = 0x78; - fbuffer[0x300008] = 0x0; - invalidate_cache(&fbuffer[0x300000]); - bank0 = 1; /* builtin 1MB vram, always there */ - bank1 = fbuffer[0x100000] == 0x34; - bank2 = fbuffer[0x200000] == 0x56; - bank3 = fbuffer[0x300000] == 0x78; - info->total_vram = (bank0 + bank1 + bank2 + bank3) * 0x100000; - printk(KERN_INFO "Total VRAM = %dMB %d%d%d%d\n", (int) (info->total_vram / 1024 / 1024), bank3, bank2, bank1, bank0); - - /* - * Try to determine whether we have an old or a new DACula. - */ - out_8(&info->cmap_regs->addr, 0x40); - info->dactype = in_8(&info->cmap_regs->d2); - switch (info->dactype) { - case 0x3c: - info->clktype = 1; - break; - case 0x84: - info->clktype = 0; - break; - default: - info->clktype = 0; - printk(KERN_INFO "Unknown DACula type: %x\n", info->dactype); - break; - } - - if (!init_platinum(info)) { - kfree(info); - return; - } -} - /* * Get the monitor sense value. * Note that this can be called before calibrate_delay, @@ -630,4 +525,169 @@ return 0; } +#ifdef __powerpc__ +#define invalidate_cache(addr) \ + asm volatile("eieio; dcbf 0,%1" \ + : "=m" (*(addr)) : "r" (addr) : "memory"); +#else +#define invalidate_cache(addr) +#endif + +static int __devinit platinumfb_probe(struct of_device* odev, const struct of_match *match) +{ + struct device_node *dp = odev->node; + struct fb_info_platinum *info; + unsigned long addr, size; + volatile __u8 *fbuffer; + int i, bank0, bank1, bank2, bank3, rc; + + if (dp->n_addrs != 2) { + printk(KERN_ERR "expecting 2 address for platinum (got %d)", dp->n_addrs); + return -ENXIO; + } + + info = kmalloc(sizeof(*info), GFP_ATOMIC); + if (info == 0) + return -ENOMEM; + memset(info, 0, sizeof(*info)); + + /* Map in frame buffer and registers */ + for (i = 0; i < dp->n_addrs; ++i) { + addr = dp->addrs[i].address; + size = dp->addrs[i].size; + /* Let's assume we can request either all or nothing */ + if (!request_mem_region(addr, size, "platinumfb")) { + kfree(info); + return -ENXIO; + } + if (size >= 0x400000) { + /* frame buffer - map only 4MB */ + info->frame_buffer_phys = addr; + info->frame_buffer = __ioremap(addr, 0x400000, _PAGE_WRITETHRU); + info->base_frame_buffer = info->frame_buffer; + } else { + /* registers */ + info->platinum_regs_phys = addr; + info->platinum_regs = ioremap(addr, size); + } + } + + info->cmap_regs_phys = 0xf301b000; /* XXX not in prom? */ + request_mem_region(info->cmap_regs_phys, 0x1000, "platinumfb cmap"); + info->cmap_regs = ioremap(info->cmap_regs_phys, 0x1000); + + /* Grok total video ram */ + out_be32(&info->platinum_regs->reg[16].r, (unsigned)info->frame_buffer_phys); + out_be32(&info->platinum_regs->reg[20].r, 0x1011); /* select max vram */ + out_be32(&info->platinum_regs->reg[24].r, 0); /* switch in vram */ + + fbuffer = info->base_frame_buffer; + fbuffer[0x100000] = 0x34; + fbuffer[0x100008] = 0x0; + invalidate_cache(&fbuffer[0x100000]); + fbuffer[0x200000] = 0x56; + fbuffer[0x200008] = 0x0; + invalidate_cache(&fbuffer[0x200000]); + fbuffer[0x300000] = 0x78; + fbuffer[0x300008] = 0x0; + invalidate_cache(&fbuffer[0x300000]); + bank0 = 1; /* builtin 1MB vram, always there */ + bank1 = fbuffer[0x100000] == 0x34; + bank2 = fbuffer[0x200000] == 0x56; + bank3 = fbuffer[0x300000] == 0x78; + info->total_vram = (bank0 + bank1 + bank2 + bank3) * 0x100000; + printk(KERN_INFO "Total VRAM = %dMB %d%d%d%d\n", (int) (info->total_vram / 1024 / 1024), bank3, bank2, bank1, bank0); + + /* + * Try to determine whether we have an old or a new DACula. + */ + out_8(&info->cmap_regs->addr, 0x40); + info->dactype = in_8(&info->cmap_regs->d2); + switch (info->dactype) { + case 0x3c: + info->clktype = 1; + break; + case 0x84: + info->clktype = 0; + break; + default: + info->clktype = 0; + printk(KERN_INFO "Unknown DACula type: %x\n", info->dactype); + break; + } + dev_set_drvdata(&odev->dev, info); + + rc = platinum_init_fb(info); + if (rc != 0) { + dev_set_drvdata(&odev->dev, NULL); + kfree(info); + } + + return rc; +} + +static int __devexit platinumfb_remove(struct of_device* odev) +{ + struct fb_info_platinum *pinfo = dev_get_drvdata(&odev->dev); + struct device_node *dp = odev->node; + unsigned long addr, size; + int i; + + if (!pinfo) + return 0; + + unregister_framebuffer (&pinfo->info); + + /* Unmap frame buffer and registers */ + for (i = 0; i < dp->n_addrs; ++i) { + addr = dp->addrs[i].address; + size = dp->addrs[i].size; + release_mem_region(addr, size); + } + iounmap((void *)pinfo->frame_buffer); + iounmap((void *)pinfo->platinum_regs); + release_mem_region(pinfo->cmap_regs_phys, 0x1000); + iounmap((void *)pinfo->cmap_regs); + + kfree(pinfo); + + return 0; +} + +static struct of_match platinumfb_match[] = +{ + { + .name = "platinum", + .type = OF_ANY_MATCH, + .compatible = OF_ANY_MATCH, + }, + {}, +}; + +static struct of_platform_driver platinum_driver = +{ + .name = "platinumfb", + .match_table = platinumfb_match, + .probe = platinumfb_probe, + .remove = platinumfb_remove, +}; + +int __init platinum_init(void) +{ + of_register_driver(&platinum_driver); + + return 0; +} + +void __exit platinum_exit(void) +{ + of_unregister_driver(&platinum_driver); +} + MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("framebuffer driver for Apple Platinum video"); + +#ifdef MODULE +module_init(platinum_init); +module_exit(platinum_exit); +#endif diff -Nru a/drivers/video/riva/fbdev.c b/drivers/video/riva/fbdev.c --- a/drivers/video/riva/fbdev.c Tue Sep 2 19:58:17 2003 +++ b/drivers/video/riva/fbdev.c Tue Sep 2 19:58:17 2003 @@ -297,34 +297,34 @@ #endif static struct fb_fix_screeninfo rivafb_fix = { - id: "nVidia", - type: FB_TYPE_PACKED_PIXELS, - xpanstep: 1, - ypanstep: 1, + .id = "nVidia", + .type = FB_TYPE_PACKED_PIXELS, + .xpanstep = 1, + .ypanstep = 1, }; static struct fb_var_screeninfo rivafb_default_var = { - xres: 640, - yres: 480, - xres_virtual: 640, - yres_virtual: 480, - bits_per_pixel: 8, - red: {0, 8, 0}, - green: {0, 8, 0}, - blue: {0, 8, 0}, - transp: {0, 0, 0}, - activate: FB_ACTIVATE_NOW, - height: -1, - width: -1, - accel_flags: FB_ACCELF_TEXT, - pixclock: 39721, - left_margin: 40, - right_margin: 24, - upper_margin: 32, - lower_margin: 11, - hsync_len: 96, - vsync_len: 2, - vmode: FB_VMODE_NONINTERLACED + .xres = 640, + .yres = 480, + .xres_virtual = 640, + .yres_virtual = 480, + .bits_per_pixel = 8, + .red = {0, 8, 0}, + .green = {0, 8, 0}, + .blue = {0, 8, 0}, + .transp = {0, 0, 0}, + .activate = FB_ACTIVATE_NOW, + .height = -1, + .width = -1, + .accel_flags = FB_ACCELF_TEXT, + .pixclock = 39721, + .left_margin = 40, + .right_margin = 24, + .upper_margin = 32, + .lower_margin = 11, + .hsync_len = 96, + .vsync_len = 2, + .vmode = FB_VMODE_NONINTERLACED }; /* from GGI */ @@ -1977,10 +1977,10 @@ #endif /* !MODULE */ static struct pci_driver rivafb_driver = { - name: "rivafb", - id_table: rivafb_pci_tbl, - probe: rivafb_probe, - remove: __exit_p(rivafb_remove), + .name = "rivafb", + .id_table = rivafb_pci_tbl, + .probe = rivafb_probe, + .remove = __exit_p(rivafb_remove), }; diff -Nru a/drivers/video/stifb.c b/drivers/video/stifb.c --- a/drivers/video/stifb.c Tue Sep 2 19:58:20 2003 +++ b/drivers/video/stifb.c Tue Sep 2 19:58:20 2003 @@ -890,7 +890,7 @@ { unsigned long p = *ppos; struct inode *inode = file->f_dentry->d_inode; - int fbidx = minor(inode->i_rdev); + int fbidx = iminor(inode); struct fb_info *info = registered_fb[fbidx]; char tmpbuf[TMPBUFLEN]; @@ -922,7 +922,7 @@ stifb_write(struct file *file, const char *buf, size_t count, loff_t *ppos) { struct inode *inode = file->f_dentry->d_inode; - int fbidx = minor(inode->i_rdev); + int fbidx = iminor(inode); struct fb_info *info = registered_fb[fbidx]; unsigned long p = *ppos; size_t c; diff -Nru a/fs/affs/file.c b/fs/affs/file.c --- a/fs/affs/file.c Tue Sep 2 19:58:15 2003 +++ b/fs/affs/file.c Tue Sep 2 19:58:15 2003 @@ -793,8 +793,8 @@ struct address_space_operations affs_aops_ofs = { .readpage = affs_readpage_ofs, - //writepage: affs_writepage_ofs, - //sync_page: affs_sync_page_ofs, + //.writepage = affs_writepage_ofs, + //.sync_page = affs_sync_page_ofs, .prepare_write = affs_prepare_write_ofs, .commit_write = affs_commit_write_ofs }; diff -Nru a/fs/afs/callback.c b/fs/afs/callback.c --- a/fs/afs/callback.c Tue Sep 2 19:58:16 2003 +++ b/fs/afs/callback.c Tue Sep 2 19:58:16 2003 @@ -146,7 +146,7 @@ spin_unlock(&vnode->lock); if (valid) { - invalidate_inode_pages(inode->i_mapping); + invalidate_remote_inode(inode); afs_put_server(server); } iput(inode); diff -Nru a/fs/afs/dir.c b/fs/afs/dir.c --- a/fs/afs/dir.c Tue Sep 2 19:58:15 2003 +++ b/fs/afs/dir.c Tue Sep 2 19:58:15 2003 @@ -569,7 +569,7 @@ spin_lock(&AFS_FS_I(inode)->lock); AFS_FS_I(inode)->flags |= AFS_VNODE_DELETED; spin_unlock(&AFS_FS_I(inode)->lock); - invalidate_inode_pages(inode->i_mapping); + invalidate_remote_inode(inode); goto out_bad; } diff -Nru a/fs/bad_inode.c b/fs/bad_inode.c --- a/fs/bad_inode.c Tue Sep 2 19:58:13 2003 +++ b/fs/bad_inode.c Tue Sep 2 19:58:13 2003 @@ -4,6 +4,8 @@ * Copyright (C) 1997, Stephen Tweedie * * Provide stub functions for unreadable inodes + * + * Fabian Frederick : August 2003 - All file operations assigned to EIO */ #include @@ -31,8 +33,10 @@ static struct file_operations bad_file_ops = { .llseek = EIO_ERROR, + .aio_read = EIO_ERROR, .read = EIO_ERROR, .write = EIO_ERROR, + .aio_write = EIO_ERROR, .readdir = EIO_ERROR, .poll = EIO_ERROR, .ioctl = EIO_ERROR, @@ -41,8 +45,14 @@ .flush = EIO_ERROR, .release = EIO_ERROR, .fsync = EIO_ERROR, + .aio_fsync = EIO_ERROR, .fasync = EIO_ERROR, .lock = EIO_ERROR, + .readv = EIO_ERROR, + .writev = EIO_ERROR, + .sendfile = EIO_ERROR, + .sendpage = EIO_ERROR, + .get_unmapped_area = EIO_ERROR, }; struct inode_operations bad_inode_ops = @@ -61,6 +71,11 @@ .truncate = EIO_ERROR, .permission = EIO_ERROR, .getattr = EIO_ERROR, + .setattr = EIO_ERROR, + .setxattr = EIO_ERROR, + .getxattr = EIO_ERROR, + .listxattr = EIO_ERROR, + .removexattr = EIO_ERROR, }; diff -Nru a/fs/bio.c b/fs/bio.c --- a/fs/bio.c Tue Sep 2 19:58:16 2003 +++ b/fs/bio.c Tue Sep 2 19:58:16 2003 @@ -793,10 +793,6 @@ mempool_free_slab, bp->slab); if (!bp->pool) panic("biovec: can't init mempool\n"); - - printk("biovec pool[%d]: %3d bvecs: %3d entries (%d bytes)\n", - i, bp->nr_vecs, pool_entries, - size); } } @@ -809,8 +805,6 @@ bio_pool = mempool_create(BIO_POOL_SIZE, mempool_alloc_slab, mempool_free_slab, bio_slab); if (!bio_pool) panic("bio: can't create mempool\n"); - - printk("BIO: pool of %d setup, %ZuKb (%Zd bytes/bio)\n", BIO_POOL_SIZE, BIO_POOL_SIZE * sizeof(struct bio) >> 10, sizeof(struct bio)); biovec_init_pools(); diff -Nru a/fs/block_dev.c b/fs/block_dev.c --- a/fs/block_dev.c Tue Sep 2 19:58:20 2003 +++ b/fs/block_dev.c Tue Sep 2 19:58:20 2003 @@ -197,40 +197,36 @@ * pseudo-fs */ -static struct super_block *bd_get_sb(struct file_system_type *fs_type, - int flags, const char *dev_name, void *data) -{ - return get_sb_pseudo(fs_type, "bdev:", NULL, 0x62646576); -} +static spinlock_t bdev_lock __cacheline_aligned_in_smp = SPIN_LOCK_UNLOCKED; +static kmem_cache_t * bdev_cachep; -static struct file_system_type bd_type = { - .name = "bdev", - .get_sb = bd_get_sb, - .kill_sb = kill_anon_super, +struct bdev_inode { + struct block_device bdev; + struct inode vfs_inode; }; -static struct vfsmount *bd_mnt; -struct super_block *blockdev_superblock; - -/* - * bdev cache handling - shamelessly stolen from inode.c - * We use smaller hashtable, though. - */ +static inline struct bdev_inode *BDEV_I(struct inode *inode) +{ + return container_of(inode, struct bdev_inode, vfs_inode); +} -#define HASH_BITS 6 -#define HASH_SIZE (1UL << HASH_BITS) -#define HASH_MASK (HASH_SIZE-1) -static struct list_head bdev_hashtable[HASH_SIZE]; -static spinlock_t bdev_lock __cacheline_aligned_in_smp = SPIN_LOCK_UNLOCKED; -static kmem_cache_t * bdev_cachep; +static struct inode *bdev_alloc_inode(struct super_block *sb) +{ + struct bdev_inode *ei = kmem_cache_alloc(bdev_cachep, SLAB_KERNEL); + if (!ei) + return NULL; + return &ei->vfs_inode; +} -#define alloc_bdev() \ - ((struct block_device *) kmem_cache_alloc(bdev_cachep, SLAB_KERNEL)) -#define destroy_bdev(bdev) kmem_cache_free(bdev_cachep, (bdev)) +static void bdev_destroy_inode(struct inode *inode) +{ + kmem_cache_free(bdev_cachep, BDEV_I(inode)); +} static void init_once(void * foo, kmem_cache_t * cachep, unsigned long flags) { - struct block_device * bdev = (struct block_device *) foo; + struct bdev_inode *ei = (struct bdev_inode *) foo; + struct block_device *bdev = &ei->bdev; if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) == SLAB_CTOR_CONSTRUCTOR) @@ -238,25 +234,62 @@ memset(bdev, 0, sizeof(*bdev)); sema_init(&bdev->bd_sem, 1); INIT_LIST_HEAD(&bdev->bd_inodes); + INIT_LIST_HEAD(&bdev->bd_list); + inode_init_once(&ei->vfs_inode); } } -void __init bdev_cache_init(void) +static inline void __bd_forget(struct inode *inode) +{ + list_del_init(&inode->i_devices); + inode->i_bdev = NULL; + inode->i_mapping = &inode->i_data; +} + +static void bdev_clear_inode(struct inode *inode) +{ + struct block_device *bdev = &BDEV_I(inode)->bdev; + struct list_head *p; + spin_lock(&bdev_lock); + while ( (p = bdev->bd_inodes.next) != &bdev->bd_inodes ) { + __bd_forget(list_entry(p, struct inode, i_devices)); + } + list_del_init(&bdev->bd_list); + spin_unlock(&bdev_lock); +} + +static struct super_operations bdev_sops = { + .statfs = simple_statfs, + .alloc_inode = bdev_alloc_inode, + .destroy_inode = bdev_destroy_inode, + .drop_inode = generic_delete_inode, + .clear_inode = bdev_clear_inode, +}; + +static struct super_block *bd_get_sb(struct file_system_type *fs_type, + int flags, const char *dev_name, void *data) { - int i, err; - struct list_head *head = bdev_hashtable; + return get_sb_pseudo(fs_type, "bdev:", &bdev_sops, 0x62646576); +} + +static struct file_system_type bd_type = { + .name = "bdev", + .get_sb = bd_get_sb, + .kill_sb = kill_anon_super, +}; - i = HASH_SIZE; - do { - INIT_LIST_HEAD(head); - head++; - i--; - } while (i); +static struct vfsmount *bd_mnt; +struct super_block *blockdev_superblock; +void __init bdev_cache_init(void) +{ + int err; bdev_cachep = kmem_cache_create("bdev_cache", - sizeof(struct block_device), - 0, SLAB_HWCACHE_ALIGN, init_once, - NULL); + sizeof(struct bdev_inode), + 0, + SLAB_HWCACHE_ALIGN|SLAB_RECLAIM_ACCOUNT, + init_once, + NULL); if (!bdev_cachep) panic("Cannot create bdev_cache SLAB cache"); err = register_filesystem(&bd_type); @@ -272,123 +305,83 @@ /* * Most likely _very_ bad one - but then it's hardly critical for small * /dev and can be fixed when somebody will need really large one. + * Keep in mind that it will be fed through icache hash function too. */ static inline unsigned long hash(dev_t dev) { - unsigned long tmp = dev; - tmp = tmp + (tmp >> HASH_BITS) + (tmp >> HASH_BITS*2); - return tmp & HASH_MASK; + return MAJOR(dev)+MINOR(dev); } -static struct block_device *bdfind(dev_t dev, struct list_head *head) +static int bdev_test(struct inode *inode, void *data) { - struct list_head *p; - struct block_device *bdev; - list_for_each(p, head) { - bdev = list_entry(p, struct block_device, bd_hash); - if (bdev->bd_dev != dev) - continue; - atomic_inc(&bdev->bd_count); - return bdev; - } - return NULL; + return BDEV_I(inode)->bdev.bd_dev == *(dev_t *)data; } +static int bdev_set(struct inode *inode, void *data) +{ + BDEV_I(inode)->bdev.bd_dev = *(dev_t *)data; + return 0; +} + +static LIST_HEAD(all_bdevs); + struct block_device *bdget(dev_t dev) { - struct list_head * head = bdev_hashtable + hash(dev); - struct block_device *bdev, *new_bdev; - spin_lock(&bdev_lock); - bdev = bdfind(dev, head); - spin_unlock(&bdev_lock); - if (bdev) - return bdev; - new_bdev = alloc_bdev(); - if (new_bdev) { - struct inode *inode = new_inode(bd_mnt->mnt_sb); - if (inode) { - kdev_t kdev = to_kdev_t(dev); - - atomic_set(&new_bdev->bd_count,1); - new_bdev->bd_dev = dev; - new_bdev->bd_contains = NULL; - new_bdev->bd_inode = inode; - new_bdev->bd_block_size = (1 << inode->i_blkbits); - new_bdev->bd_part_count = 0; - new_bdev->bd_invalidated = 0; - inode->i_mode = S_IFBLK; - inode->i_rdev = kdev; - inode->i_bdev = new_bdev; - inode->i_data.a_ops = &def_blk_aops; - mapping_set_gfp_mask(&inode->i_data, GFP_USER); - inode->i_data.backing_dev_info = &default_backing_dev_info; - spin_lock(&bdev_lock); - bdev = bdfind(dev, head); - if (!bdev) { - list_add(&new_bdev->bd_hash, head); - spin_unlock(&bdev_lock); - return new_bdev; - } - spin_unlock(&bdev_lock); - iput(new_bdev->bd_inode); - } - destroy_bdev(new_bdev); + struct block_device *bdev; + struct inode *inode; + + inode = iget5_locked(bd_mnt->mnt_sb, hash(dev), + bdev_test, bdev_set, &dev); + + if (!inode) + return NULL; + + bdev = &BDEV_I(inode)->bdev; + + if (inode->i_state & I_NEW) { + bdev->bd_contains = NULL; + bdev->bd_inode = inode; + bdev->bd_block_size = (1 << inode->i_blkbits); + bdev->bd_part_count = 0; + bdev->bd_invalidated = 0; + inode->i_mode = S_IFBLK; + inode->i_rdev = to_kdev_t(dev); + inode->i_bdev = bdev; + inode->i_data.a_ops = &def_blk_aops; + mapping_set_gfp_mask(&inode->i_data, GFP_USER); + inode->i_data.backing_dev_info = &default_backing_dev_info; + spin_lock(&bdev_lock); + list_add(&bdev->bd_list, &all_bdevs); + spin_unlock(&bdev_lock); + unlock_new_inode(inode); } return bdev; } long nr_blockdev_pages(void) { + struct list_head *p; long ret = 0; - int i; - spin_lock(&bdev_lock); - for (i = 0; i < ARRAY_SIZE(bdev_hashtable); i++) { - struct list_head *head = &bdev_hashtable[i]; - struct list_head *lh; - - if (head == NULL) - continue; - list_for_each(lh, head) { - struct block_device *bdev; - - bdev = list_entry(lh, struct block_device, bd_hash); - ret += bdev->bd_inode->i_mapping->nrpages; - } + list_for_each(p, &all_bdevs) { + struct block_device *bdev; + bdev = list_entry(p, struct block_device, bd_list); + ret += bdev->bd_inode->i_mapping->nrpages; } spin_unlock(&bdev_lock); return ret; } -static inline void __bd_forget(struct inode *inode) -{ - list_del_init(&inode->i_devices); - inode->i_bdev = NULL; - inode->i_mapping = &inode->i_data; -} - void bdput(struct block_device *bdev) { - if (atomic_dec_and_lock(&bdev->bd_count, &bdev_lock)) { - struct list_head *p; - if (bdev->bd_openers) - BUG(); - list_del(&bdev->bd_hash); - while ( (p = bdev->bd_inodes.next) != &bdev->bd_inodes ) { - __bd_forget(list_entry(p, struct inode, i_devices)); - } - spin_unlock(&bdev_lock); - iput(bdev->bd_inode); - destroy_bdev(bdev); - } + iput(bdev->bd_inode); } int bd_acquire(struct inode *inode) { struct block_device *bdev; spin_lock(&bdev_lock); - if (inode->i_bdev) { - atomic_inc(&inode->i_bdev->bd_count); + if (inode->i_bdev && igrab(inode->i_bdev->bd_inode)) { spin_unlock(&bdev_lock); return 0; } @@ -397,12 +390,11 @@ if (!bdev) return -ENOMEM; spin_lock(&bdev_lock); - if (!inode->i_bdev) { - inode->i_bdev = bdev; - inode->i_mapping = bdev->bd_inode->i_mapping; - list_add(&inode->i_devices, &bdev->bd_inodes); - } else if (inode->i_bdev != bdev) - BUG(); + if (inode->i_bdev) + __bd_forget(inode); + inode->i_bdev = bdev; + inode->i_mapping = bdev->bd_inode->i_mapping; + list_add(&inode->i_devices, &bdev->bd_inodes); spin_unlock(&bdev_lock); return 0; } @@ -548,7 +540,6 @@ if (ret) goto out_first; } - bdev->bd_offset = 0; if (!bdev->bd_openers) { bd_set_size(bdev,(loff_t)get_capacity(disk)<<9); bdi = blk_get_backing_dev_info(bdev); @@ -580,7 +571,8 @@ ret = -ENXIO; goto out_first; } - bdev->bd_offset = p->start_sect; + kobject_get(&p->kobj); + bdev->bd_part = p; bd_set_size(bdev, (loff_t) p->nr_sects << 9); up(&whole->bd_sem); } @@ -701,6 +693,10 @@ put_disk(disk); module_put(owner); + if (bdev->bd_contains != bdev) { + kobject_put(&bdev->bd_part->kobj); + bdev->bd_part = NULL; + } bdev->bd_disk = NULL; bdev->bd_inode->i_data.backing_dev_info = &default_backing_dev_info; if (bdev != bdev->bd_contains) { diff -Nru a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c --- a/fs/cifs/cifsfs.c Tue Sep 2 19:58:16 2003 +++ b/fs/cifs/cifsfs.c Tue Sep 2 19:58:16 2003 @@ -598,10 +598,12 @@ netfid = oplock_item->netfid; DeleteOplockQEntry(oplock_item); write_unlock(&GlobalMid_Lock); - rc = filemap_fdatawrite(inode->i_mapping); - if(rc) - CIFS_I(inode)->write_behind_rc - = rc; + if (S_ISREG(inode->i_mode)) + rc = filemap_fdatawrite(inode->i_mapping); + else + rc = 0; + if (rc) + CIFS_I(inode)->write_behind_rc = rc; cFYI(1,("Oplock flush inode %p rc %d",inode,rc)); rc = CIFSSMBLock(0, pTcon, netfid, 0 /* len */ , 0 /* offset */, 0, diff -Nru a/fs/coda/inode.c b/fs/coda/inode.c --- a/fs/coda/inode.c Tue Sep 2 19:58:16 2003 +++ b/fs/coda/inode.c Tue Sep 2 19:58:16 2003 @@ -115,7 +115,7 @@ inode = file->f_dentry->d_inode; if(!inode || !S_ISCHR(inode->i_mode) || - major(inode->i_rdev) != CODA_PSDEV_MAJOR) { + imajor(inode) != CODA_PSDEV_MAJOR) { if(file) fput(file); @@ -123,7 +123,7 @@ return -1; } - idx = minor(inode->i_rdev); + idx = iminor(inode); fput(file); if(idx < 0 || idx >= MAX_CODADEVS) { diff -Nru a/fs/coda/psdev.c b/fs/coda/psdev.c --- a/fs/coda/psdev.c Tue Sep 2 19:58:17 2003 +++ b/fs/coda/psdev.c Tue Sep 2 19:58:17 2003 @@ -279,7 +279,7 @@ int idx; lock_kernel(); - idx = minor(inode->i_rdev); + idx = iminor(inode); if(idx >= MAX_CODADEVS) { unlock_kernel(); return -ENODEV; diff -Nru a/fs/compat.c b/fs/compat.c --- a/fs/compat.c Tue Sep 2 19:58:15 2003 +++ b/fs/compat.c Tue Sep 2 19:58:15 2003 @@ -227,7 +227,8 @@ #define IOCTL_HASHSIZE 256 struct ioctl_trans *ioctl32_hash_table[IOCTL_HASHSIZE]; -extern struct ioctl_trans ioctl_start[], ioctl_end[]; +extern struct ioctl_trans ioctl_start[]; +extern int ioctl_table_size; static inline unsigned long ioctl32_hash(unsigned long cmd) { @@ -255,7 +256,7 @@ { int i; - for (i = 0; &ioctl_start[i] < &ioctl_end[0]; i++) { + for (i = 0; i < ioctl_table_size; i++) { if (ioctl_start[i].next != 0) { printk("ioctl translation %d bad\n",i); return -1; @@ -318,8 +319,7 @@ static inline int builtin_ioctl(struct ioctl_trans *t) { - return t >= (struct ioctl_trans *)ioctl_start && - t < (struct ioctl_trans *)ioctl_end; + return t >= ioctl_start && t < (ioctl_start + ioctl_table_size); } /* Problem: diff -Nru a/fs/compat_ioctl.c b/fs/compat_ioctl.c --- a/fs/compat_ioctl.c Tue Sep 2 19:58:19 2003 +++ b/fs/compat_ioctl.c Tue Sep 2 19:58:19 2003 @@ -1573,7 +1573,7 @@ return -EINVAL; tty = (struct tty_struct *)file->private_data; - if (tty_paranoia_check(tty, inode->i_rdev, "tty_ioctl")) + if (tty_paranoia_check(tty, inode, "tty_ioctl")) return -EINVAL; if (tty->driver->ioctl != vt_ioctl) diff -Nru a/fs/dnotify.c b/fs/dnotify.c --- a/fs/dnotify.c Tue Sep 2 19:58:14 2003 +++ b/fs/dnotify.c Tue Sep 2 19:58:14 2003 @@ -20,8 +20,6 @@ #include #include -extern void send_sigio(struct fown_struct *fown, int fd, int band); - int dir_notify_enable = 1; static rwlock_t dn_lock = RW_LOCK_UNLOCKED; @@ -94,7 +92,7 @@ prev = &odn->dn_next; } - error = f_setown(filp, current->pid, 1); + error = f_setown(filp, current->tgid, 1); if (error) goto out_free; diff -Nru a/fs/ext2/namei.c b/fs/ext2/namei.c --- a/fs/ext2/namei.c Tue Sep 2 19:58:18 2003 +++ b/fs/ext2/namei.c Tue Sep 2 19:58:18 2003 @@ -143,7 +143,7 @@ int err = PTR_ERR(inode); if (!IS_ERR(inode)) { init_special_inode(inode, inode->i_mode, rdev); -#ifdef CONFIG_EXT2_FS_EXT_ATTR +#ifdef CONFIG_EXT2_FS_XATTR inode->i_op = &ext2_special_inode_operations; #endif mark_inode_dirty(inode); diff -Nru a/fs/ext3/namei.c b/fs/ext3/namei.c --- a/fs/ext3/namei.c Tue Sep 2 19:58:16 2003 +++ b/fs/ext3/namei.c Tue Sep 2 19:58:16 2003 @@ -1306,7 +1306,7 @@ /* The 0th block becomes the root, move the dirents out */ fde = &root->dotdot; - de = (struct ext3_dir_entry_2 *)((char *)fde + fde->rec_len); + de = (struct ext3_dir_entry_2 *)((char *)fde + le16_to_cpu(fde->rec_len)); len = ((char *) root) + blocksize - (char *) de; memcpy (data1, de, len); de = (struct ext3_dir_entry_2 *) data1; diff -Nru a/fs/ext3/xattr.c b/fs/ext3/xattr.c --- a/fs/ext3/xattr.c Tue Sep 2 19:58:16 2003 +++ b/fs/ext3/xattr.c Tue Sep 2 19:58:16 2003 @@ -873,17 +873,22 @@ const void *value, size_t value_len, int flags) { handle_t *handle; - int error, error2; + int error; handle = ext3_journal_start(inode, EXT3_DATA_TRANS_BLOCKS); - if (IS_ERR(handle)) + if (IS_ERR(handle)) { error = PTR_ERR(handle); - else + } else { + int error2; + error = ext3_xattr_set_handle(handle, inode, name_index, name, value, value_len, flags); - error2 = ext3_journal_stop(handle); + error2 = ext3_journal_stop(handle); + if (error == 0) + error = error2; + } - return error ? error : error2; + return error; } /* diff -Nru a/fs/fcntl.c b/fs/fcntl.c --- a/fs/fcntl.c Tue Sep 2 19:58:17 2003 +++ b/fs/fcntl.c Tue Sep 2 19:58:17 2003 @@ -6,6 +6,7 @@ #include #include +#include #include #include #include @@ -17,9 +18,6 @@ #include #include #include - -extern int fcntl_setlease(unsigned int fd, struct file *filp, long arg); -extern int fcntl_getlease(struct file *filp); void set_close_on_exec(unsigned int fd, int flag) { diff -Nru a/fs/freevxfs/vxfs_inode.c b/fs/freevxfs/vxfs_inode.c --- a/fs/freevxfs/vxfs_inode.c Tue Sep 2 19:58:14 2003 +++ b/fs/freevxfs/vxfs_inode.c Tue Sep 2 19:58:14 2003 @@ -171,7 +171,7 @@ return NULL; fail: - printk(KERN_WARNING "vxfs: unable to read inode %ld\n", ino); + printk(KERN_WARNING "vxfs: unable to read inode %ld\n", (unsigned long)ino); vxfs_put_page(pp); return NULL; } diff -Nru a/fs/hpfs/namei.c b/fs/hpfs/namei.c --- a/fs/hpfs/namei.c Tue Sep 2 19:58:15 2003 +++ b/fs/hpfs/namei.c Tue Sep 2 19:58:15 2003 @@ -375,6 +375,7 @@ spin_lock(&dentry->d_lock); if (atomic_read(&dentry->d_count) > 1 || permission(inode, MAY_WRITE, NULL) || + !S_ISREG(inode->i_mode) || get_write_access(inode)) { spin_unlock(&dentry->d_lock); d_rehash(dentry); diff -Nru a/fs/intermezzo/presto.c b/fs/intermezzo/presto.c --- a/fs/intermezzo/presto.c Tue Sep 2 19:58:16 2003 +++ b/fs/intermezzo/presto.c Tue Sep 2 19:58:16 2003 @@ -66,8 +66,8 @@ cache = presto_get_cache(inode); CDEBUG(D_PSDEV, "\n"); if ( !cache ) { - CERROR("PRESTO: BAD: cannot find cache for dev %d, ino %ld\n", - inode->i_sb->s_dev, inode->i_ino); + CERROR("PRESTO: BAD: cannot find cache for dev %s, ino %ld\n", + inode->i_sb->s_id, inode->i_ino); EXIT; return -1; } diff -Nru a/fs/intermezzo/vfs.c b/fs/intermezzo/vfs.c --- a/fs/intermezzo/vfs.c Tue Sep 2 19:58:14 2003 +++ b/fs/intermezzo/vfs.c Tue Sep 2 19:58:14 2003 @@ -743,7 +743,7 @@ goto exit_lock; error = -EXDEV; - if (dir->d_inode->i_sb->s_dev != inode->i_sb->s_dev) + if (dir->d_inode->i_sb != inode->i_sb) goto exit_lock; /* @@ -1800,7 +1800,7 @@ if (error) return error; - if (new_dir->i_sb->s_dev != old_dir->i_sb->s_dev) + if (new_dir->i_sb != old_dir->i_sb) return -EXDEV; if (!new_dentry->d_inode) @@ -1881,7 +1881,7 @@ if (error) return error; - if (new_dir->i_sb->s_dev != old_dir->i_sb->s_dev) + if (new_dir->i_sb != old_dir->i_sb) return -EXDEV; if (!new_dentry->d_inode) diff -Nru a/fs/jbd/journal.c b/fs/jbd/journal.c --- a/fs/jbd/journal.c Tue Sep 2 19:58:13 2003 +++ b/fs/jbd/journal.c Tue Sep 2 19:58:13 2003 @@ -1890,7 +1890,6 @@ { int ret; - printk(KERN_INFO "Journalled Block Device driver loaded\n"); ret = journal_init_caches(); if (ret != 0) journal_destroy_caches(); diff -Nru a/fs/jffs/inode-v23.c b/fs/jffs/inode-v23.c --- a/fs/jffs/inode-v23.c Tue Sep 2 19:58:16 2003 +++ b/fs/jffs/inode-v23.c Tue Sep 2 19:58:16 2003 @@ -1080,9 +1080,11 @@ struct jffs_control *c; struct inode *inode; int result = 0; - kdev_t dev = to_kdev_t(rdev); + u16 data; int err; + data = (MAJOR(rdev) << 8) | MINOR(rdev); + D1(printk("***jffs_mknod()\n")); lock_kernel(); @@ -1114,7 +1116,7 @@ raw_inode.mtime = raw_inode.atime; raw_inode.ctime = raw_inode.atime; raw_inode.offset = 0; - raw_inode.dsize = sizeof(kdev_t); + raw_inode.dsize = 2; raw_inode.rsize = 0; raw_inode.nsize = dentry->d_name.len; raw_inode.nlink = 1; @@ -1124,7 +1126,7 @@ /* Write the new node to the flash. */ if ((err = jffs_write_node(c, node, &raw_inode, dentry->d_name.name, - (unsigned char *)&dev, 0, NULL)) < 0) { + (unsigned char *)&data, 0, NULL)) < 0) { D(printk("jffs_mknod(): jffs_write_node() failed.\n")); result = err; goto jffs_mknod_err; @@ -1530,7 +1532,7 @@ return err; } /* jffs_file_write() */ -static ssize_t +static int jffs_prepare_write(struct file *filp, struct page *page, unsigned from, unsigned to) { @@ -1543,7 +1545,7 @@ return 0; } /* jffs_prepare_write() */ -static ssize_t +static int jffs_commit_write(struct file *filp, struct page *page, unsigned from, unsigned to) { @@ -1732,9 +1734,10 @@ /* If the node is a device of some sort, then the number of the device should be read from the flash memory and then added to the inode's i_rdev member. */ - kdev_t rdev; - jffs_read_data(f, (char *)&rdev, 0, sizeof(kdev_t)); - init_special_inode(inode, inode->i_mode, kdev_t_to_nr(rdev)); + u16 val; + jffs_read_data(f, (char *)val, 0, 2); + init_special_inode(inode, inode->i_mode, + MKDEV((val >> 8) & 255, val & 255)); } D3(printk (KERN_NOTICE "read_inode(): up biglock\n")); diff -Nru a/fs/jffs2/file.c b/fs/jffs2/file.c --- a/fs/jffs2/file.c Tue Sep 2 19:58:20 2003 +++ b/fs/jffs2/file.c Tue Sep 2 19:58:20 2003 @@ -103,8 +103,8 @@ it out again with the appropriate data attached */ if (S_ISBLK(inode->i_mode) || S_ISCHR(inode->i_mode)) { /* For these, we don't actually need to read the old node */ - dev = (major(dentry->d_inode->i_rdev) << 8) | - minor(dentry->d_inode->i_rdev); + dev = (imajor(dentry->d_inode) << 8) | + iminor(dentry->d_inode); mdata = (char *)&dev; mdatalen = sizeof(dev); D1(printk(KERN_DEBUG "jffs2_setattr(): Writing %d bytes of kdev_t\n", mdatalen)); diff -Nru a/fs/jffs2/os-linux.h b/fs/jffs2/os-linux.h --- a/fs/jffs2/os-linux.h Tue Sep 2 19:58:13 2003 +++ b/fs/jffs2/os-linux.h Tue Sep 2 19:58:13 2003 @@ -44,8 +44,8 @@ #define JFFS2_F_I_GID(f) (OFNI_EDONI_2SFFJ(f)->i_gid) #if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,1) -#define JFFS2_F_I_RDEV_MIN(f) (minor(OFNI_EDONI_2SFFJ(f)->i_rdev)) -#define JFFS2_F_I_RDEV_MAJ(f) (major(OFNI_EDONI_2SFFJ(f)->i_rdev)) +#define JFFS2_F_I_RDEV_MIN(f) (iminor(OFNI_EDONI_2SFFJ(f))) +#define JFFS2_F_I_RDEV_MAJ(f) (imajor(OFNI_EDONI_2SFFJ(f))) #else #define JFFS2_F_I_RDEV_MIN(f) (MINOR(to_kdev_t(OFNI_EDONI_2SFFJ(f)->i_rdev))) #define JFFS2_F_I_RDEV_MAJ(f) (MAJOR(to_kdev_t(OFNI_EDONI_2SFFJ(f)->i_rdev))) diff -Nru a/fs/jffs2/wbuf.c b/fs/jffs2/wbuf.c --- a/fs/jffs2/wbuf.c Tue Sep 2 19:58:14 2003 +++ b/fs/jffs2/wbuf.c Tue Sep 2 19:58:14 2003 @@ -37,8 +37,8 @@ #define NAND_JFFS2_OOB16_FSDALEN 8 struct nand_oobinfo jffs2_oobinfo = { - useecc: 1, - eccpos: {JFFS2_OOB_ECCPOS0, JFFS2_OOB_ECCPOS1, JFFS2_OOB_ECCPOS2, JFFS2_OOB_ECCPOS3, JFFS2_OOB_ECCPOS4, JFFS2_OOB_ECCPOS5} + .useecc = 1, + .eccpos = {JFFS2_OOB_ECCPOS0, JFFS2_OOB_ECCPOS1, JFFS2_OOB_ECCPOS2, JFFS2_OOB_ECCPOS3, JFFS2_OOB_ECCPOS4, JFFS2_OOB_ECCPOS5} }; static inline void jffs2_refile_wbuf_blocks(struct jffs2_sb_info *c) diff -Nru a/fs/nfs/inode.c b/fs/nfs/inode.c --- a/fs/nfs/inode.c Tue Sep 2 19:58:18 2003 +++ b/fs/nfs/inode.c Tue Sep 2 19:58:18 2003 @@ -620,7 +620,7 @@ NFS_ATTRTIMEO(inode) = NFS_MINATTRTIMEO(inode); NFS_ATTRTIMEO_UPDATE(inode) = jiffies; - invalidate_inode_pages(inode->i_mapping); + invalidate_remote_inode(inode); memset(NFS_COOKIEVERF(inode), 0, sizeof(NFS_COOKIEVERF(inode))); NFS_CACHEINV(inode); @@ -823,14 +823,15 @@ goto out; } - if (!S_ISREG(inode->i_mode)) + if (!S_ISREG(inode->i_mode)) { attr->ia_valid &= ~ATTR_SIZE; - - filemap_fdatawrite(inode->i_mapping); - error = nfs_wb_all(inode); - filemap_fdatawait(inode->i_mapping); - if (error) - goto out; + } else { + filemap_fdatawrite(inode->i_mapping); + error = nfs_wb_all(inode); + filemap_fdatawait(inode->i_mapping); + if (error) + goto out; + } error = NFS_PROTO(inode)->setattr(dentry, &fattr, attr); if (error) @@ -1205,7 +1206,7 @@ if (invalid) { nfsi->attrtimeo = NFS_MINATTRTIMEO(inode); nfsi->attrtimeo_timestamp = jiffies; - invalidate_inode_pages(inode->i_mapping); + invalidate_remote_inode(inode); memset(NFS_COOKIEVERF(inode), 0, sizeof(NFS_COOKIEVERF(inode))); } else if (time_after(jiffies, nfsi->attrtimeo_timestamp+nfsi->attrtimeo)) { if ((nfsi->attrtimeo <<= 1) > NFS_MAXATTRTIMEO(inode)) diff -Nru a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c --- a/fs/nfsd/nfs4proc.c Tue Sep 2 19:58:20 2003 +++ b/fs/nfsd/nfs4proc.c Tue Sep 2 19:58:20 2003 @@ -106,7 +106,8 @@ nfsd4_open(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_open *open) { int status; - dprintk("NFSD: nfsd4_open filename %.*s\n",open->op_fname.len, open->op_fname.data); + dprintk("NFSD: nfsd4_open filename %.*s\n", + (int)open->op_fname.len, open->op_fname.data); /* This check required by spec. */ if (open->op_create && open->op_claim_type != NFS4_OPEN_CLAIM_NULL) diff -Nru a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c --- a/fs/nfsd/nfs4state.c Tue Sep 2 19:58:17 2003 +++ b/fs/nfsd/nfs4state.c Tue Sep 2 19:58:17 2003 @@ -688,7 +688,7 @@ #define OPENSTATEID_HASH_MASK (OPENSTATEID_HASH_SIZE - 1) #define file_hashval(x) \ - ((unsigned int)((x)->dev + (x)->ino + (x)->generation) & FILE_HASH_MASK) + hash_ptr(x, FILE_HASH_BITS) #define openstateid_hashval(owner_id, file_id) \ (((owner_id) + (file_id)) & OPENSTATEID_HASH_MASK) @@ -697,13 +697,13 @@ /* OPEN Share state helper functions */ static inline struct nfs4_file * -alloc_init_file(unsigned int hashval, nfs4_ino_desc_t *ino) { +alloc_init_file(unsigned int hashval, struct inode *ino) { struct nfs4_file *fp; if ((fp = kmalloc(sizeof(struct nfs4_file),GFP_KERNEL))) { INIT_LIST_HEAD(&fp->fi_hash); INIT_LIST_HEAD(&fp->fi_perfile); list_add(&fp->fi_hash, &file_hashtbl[hashval]); - memcpy(&fp->fi_ino, ino, sizeof(nfs4_ino_desc_t)); + fp->fi_inode = igrab(ino); fp->fi_id = current_fileid++; alloc_file++; return fp; @@ -841,11 +841,12 @@ { free_file++; list_del_init(&fp->fi_hash); + iput(fp->fi_inode); kfree(fp); } void -release_open_state(struct nfs4_stateid *stp) +release_open_state(struct nfs4_stateid *stp, struct nfsd4_close *cl) { struct nfs4_stateowner *sop = stp->st_stateowner; struct nfs4_file *fp = stp->st_file; @@ -860,6 +861,7 @@ */ if (sop->so_confirmed && list_empty(&sop->so_peropenstate)) { release_stateowner(sop); + cl->cl_stateowner = NULL; } /* unused nfs4_file's are releseed. XXX slab cache? */ if (list_empty(&fp->fi_perfile)) { @@ -911,13 +913,13 @@ /* search file_hashtbl[] for file */ static int -find_file(unsigned int hashval, nfs4_ino_desc_t *ino, struct nfs4_file **fp) { +find_file(unsigned int hashval, struct inode *ino, struct nfs4_file **fp) { struct list_head *pos, *next; struct nfs4_file *local = NULL; list_for_each_safe(pos, next, &file_hashtbl[hashval]) { local = list_entry(pos, struct nfs4_file, fi_hash); - if(!memcmp(&local->fi_ino, ino, sizeof(nfs4_ino_desc_t))) { + if (local->fi_inode == ino) { *fp = local; return(1); } @@ -934,24 +936,10 @@ return 1; } -static inline void -nfs4_init_ino(nfs4_ino_desc_t *ino, struct svc_fh *fhp) -{ - struct inode *inode; - if (!fhp->fh_dentry) - BUG(); - inode = fhp->fh_dentry->d_inode; - if (!inode) - BUG(); - ino->dev = inode->i_sb->s_dev; - ino->ino = inode->i_ino; - ino->generation = inode->i_generation; -} - int nfs4_share_conflict(struct svc_fh *current_fh, unsigned int deny_type) { - nfs4_ino_desc_t ino; + struct inode *ino = current_fh->fh_dentry->d_inode; unsigned int fi_hashval; struct nfs4_file *fp; struct nfs4_stateid *stp; @@ -959,9 +947,8 @@ dprintk("NFSD: nfs4_share_conflict\n"); - nfs4_init_ino(&ino, current_fh); - fi_hashval = file_hashval(&ino); - if (find_file(fi_hashval, &ino, &fp)) { + fi_hashval = file_hashval(ino); + if (find_file(fi_hashval, ino, &fp)) { /* Search for conflicting share reservations */ list_for_each_safe(pos, next, &fp->fi_perfile) { stp = list_entry(pos, struct nfs4_stateid, st_perfile); @@ -1084,7 +1071,7 @@ struct iattr iattr; struct nfs4_stateowner *sop = open->op_stateowner; struct nfs4_file *fp; - nfs4_ino_desc_t ino; + struct inode *ino; unsigned int fi_hashval; struct list_head *pos, *next; struct nfs4_stateid *stq, *stp = NULL; @@ -1094,11 +1081,11 @@ if (!sop) goto out; - nfs4_init_ino(&ino, current_fh); + ino = current_fh->fh_dentry->d_inode; down(&client_sema); /*XXX need finer grained locking */ - fi_hashval = file_hashval(&ino); - if (find_file(fi_hashval, &ino, &fp)) { + fi_hashval = file_hashval(ino); + if (find_file(fi_hashval, ino, &fp)) { /* Search for conflicting share reservations */ status = nfserr_share_denied; list_for_each_safe(pos, next, &fp->fi_perfile) { @@ -1113,7 +1100,7 @@ } else { /* No nfs4_file found; allocate and init a new one */ status = nfserr_resource; - if ((fp = alloc_init_file(fi_hashval, &ino)) == NULL) + if ((fp = alloc_init_file(fi_hashval, ino)) == NULL) goto out; } @@ -1172,6 +1159,9 @@ open->op_delegate_type = NFS4_OPEN_DELEGATE_NONE; status = nfs_ok; out: + if (fp && list_empty(&fp->fi_perfile)) + release_file(fp); + /* * To finish the open response, we just need to set the rflags. */ @@ -1494,7 +1484,7 @@ struct nfs4_stateid *stp; dprintk("NFSD: nfsd4_open_confirm on file %.*s\n", - current_fh->fh_dentry->d_name.len, + (int)current_fh->fh_dentry->d_name.len, current_fh->fh_dentry->d_name.name); oc->oc_stateowner = NULL; down(&client_sema); /* XXX need finer grained locking */ @@ -1528,7 +1518,7 @@ struct nfs4_stateid *stp; dprintk("NFSD: nfsd4_open_downgrade on file %.*s\n", - current_fh->fh_dentry->d_name.len, + (int)current_fh->fh_dentry->d_name.len, current_fh->fh_dentry->d_name.name); down(&client_sema); /* XXX need finer grained locking */ @@ -1567,7 +1557,7 @@ struct nfs4_stateid *stp; dprintk("NFSD: nfsd4_close on file %.*s\n", - current_fh->fh_dentry->d_name.len, + (int)current_fh->fh_dentry->d_name.len, current_fh->fh_dentry->d_name.name); down(&client_sema); /* XXX need finer grained locking */ @@ -1584,7 +1574,7 @@ memcpy(&close->cl_stateid, &stp->st_stateid, sizeof(stateid_t)); /* release_open_state() calls nfsd_close() if needed */ - release_open_state(stp); + release_open_state(stp,close); out: up(&client_sema); return status; diff -Nru a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c --- a/fs/nfsd/nfs4xdr.c Tue Sep 2 19:58:18 2003 +++ b/fs/nfsd/nfs4xdr.c Tue Sep 2 19:58:18 2003 @@ -1631,6 +1631,8 @@ WRITEMEM(&close->cl_stateid.si_opaque, sizeof(stateid_opaque_t)); ADJUST_ARGS(); } + if ((close->cl_stateowner) && (close->cl_stateowner->so_confirmed)) + close->cl_stateowner->so_seqid++; } @@ -1767,6 +1769,8 @@ default: BUG(); } + + ENCODE_SEQID_OP_TAIL(open->op_stateowner); } static int diff -Nru a/fs/open.c b/fs/open.c --- a/fs/open.c Tue Sep 2 19:58:13 2003 +++ b/fs/open.c Tue Sep 2 19:58:13 2003 @@ -945,20 +945,12 @@ */ int filp_close(struct file *filp, fl_owner_t id) { - struct address_space *mapping = filp->f_dentry->d_inode->i_mapping; - int retval = 0, err; + int retval; /* Report and clear outstanding errors */ - err = filp->f_error; - if (err) { + retval = filp->f_error; + if (retval) filp->f_error = 0; - retval = err; - } - - if (test_and_clear_bit(AS_ENOSPC, &mapping->flags)) - retval = -ENOSPC; - if (test_and_clear_bit(AS_EIO, &mapping->flags)) - retval = -EIO; if (!file_count(filp)) { printk(KERN_ERR "VFS: Close: file count is 0\n"); @@ -966,7 +958,7 @@ } if (filp->f_op && filp->f_op->flush) { - err = filp->f_op->flush(filp); + int err = filp->f_op->flush(filp); if (!retval) retval = err; } diff -Nru a/fs/partitions/check.c b/fs/partitions/check.c --- a/fs/partitions/check.c Tue Sep 2 19:58:19 2003 +++ b/fs/partitions/check.c Tue Sep 2 19:58:19 2003 @@ -267,7 +267,14 @@ extern struct subsystem block_subsys; +static void part_release(struct kobject *kobj) +{ + struct hd_struct * p = container_of(kobj,struct hd_struct,kobj); + kfree(p); +} + struct kobj_type ktype_part = { + .release = part_release, .default_attrs = default_attrs, .sysfs_ops = &part_sysfs_ops, }; @@ -279,13 +286,12 @@ return; if (!p->nr_sects) return; + disk->part[part-1] = NULL; p->start_sect = 0; p->nr_sects = 0; p->reads = p->writes = p->read_sectors = p->write_sectors = 0; devfs_remove("%s/part%d", disk->devfs_name, part); kobject_unregister(&p->kobj); - disk->part[part-1] = NULL; - kfree(p); } void add_partition(struct gendisk *disk, int part, sector_t start, sector_t len) @@ -300,7 +306,6 @@ p->start_sect = start; p->nr_sects = len; p->partno = part; - disk->part[part-1] = p; devfs_mk_bdev(MKDEV(disk->major, disk->first_minor + part), S_IFBLK|S_IRUSR|S_IWUSR, @@ -310,6 +315,7 @@ p->kobj.parent = &disk->kobj; p->kobj.ktype = &ktype_part; kobject_register(&p->kobj); + disk->part[part-1] = p; } static void disk_sysfs_symlinks(struct gendisk *disk) diff -Nru a/fs/proc/base.c b/fs/proc/base.c --- a/fs/proc/base.c Tue Sep 2 19:58:17 2003 +++ b/fs/proc/base.c Tue Sep 2 19:58:17 2003 @@ -864,19 +864,34 @@ * Exceptional case: normally we are not allowed to unhash a busy * directory. In this case, however, we can do it - no aliasing problems * due to the way we treat inodes. + * + * Rewrite the inode's ownerships here because the owning task may have + * performed a setuid(), etc. */ -static int pid_revalidate(struct dentry * dentry, struct nameidata *nd) +static int pid_revalidate(struct dentry *dentry, struct nameidata *nd) { - if (pid_alive(proc_task(dentry->d_inode))) + struct inode *inode = dentry->d_inode; + struct task_struct *task = proc_task(inode); + if (pid_alive(task)) { + if (proc_type(inode) == PROC_PID_INO || task_dumpable(task)) { + inode->i_uid = task->euid; + inode->i_gid = task->egid; + } else { + inode->i_uid = 0; + inode->i_gid = 0; + } + security_task_to_inode(task, inode); return 1; + } d_drop(dentry); return 0; } -static int pid_fd_revalidate(struct dentry * dentry, struct nameidata *nd) +static int pid_fd_revalidate(struct dentry *dentry, struct nameidata *nd) { - struct task_struct *task = proc_task(dentry->d_inode); - int fd = proc_type(dentry->d_inode) - PROC_PID_FD_DIR; + struct inode *inode = dentry->d_inode; + struct task_struct *task = proc_task(inode); + int fd = proc_type(inode) - PROC_PID_FD_DIR; struct files_struct *files; task_lock(task); @@ -889,6 +904,14 @@ if (fcheck_files(files, fd)) { spin_unlock(&files->file_lock); put_files_struct(files); + if (task_dumpable(task)) { + inode->i_uid = task->euid; + inode->i_gid = task->egid; + } else { + inode->i_uid = 0; + inode->i_gid = 0; + } + security_task_to_inode(task, inode); return 1; } spin_unlock(&files->file_lock); diff -Nru a/fs/proc/kcore.c b/fs/proc/kcore.c --- a/fs/proc/kcore.c Tue Sep 2 19:58:16 2003 +++ b/fs/proc/kcore.c Tue Sep 2 19:58:16 2003 @@ -1,5 +1,5 @@ /* - * fs/proc/kcore.c kernel ELF/AOUT core dumper + * fs/proc/kcore.c kernel ELF core dumper * * Modelled on fs/exec.c:aout_core_dump() * Jeremy Fitzhardinge @@ -34,71 +34,6 @@ .open = open_kcore, }; -#ifdef CONFIG_KCORE_AOUT -static ssize_t read_kcore(struct file *file, char *buf, size_t count, loff_t *ppos) -{ - unsigned long long p = *ppos, memsize; - ssize_t read; - ssize_t count1; - char * pnt; - struct user dump; -#if defined (__i386__) || defined (__mc68000__) || defined(__x86_64__) -# define FIRST_MAPPED PAGE_SIZE /* we don't have page 0 mapped on x86.. */ -#else -# define FIRST_MAPPED 0 -#endif - - memset(&dump, 0, sizeof(struct user)); - dump.magic = CMAGIC; - dump.u_dsize = (virt_to_phys(high_memory) >> PAGE_SHIFT); -#if defined (__i386__) || defined(__x86_64__) - dump.start_code = PAGE_OFFSET; -#endif -#ifdef __alpha__ - dump.start_data = PAGE_OFFSET; -#endif - - memsize = virt_to_phys(high_memory); - if (p >= memsize) - return 0; - if (count > memsize - p) - count = memsize - p; - read = 0; - - if (p < sizeof(struct user) && count > 0) { - count1 = count; - if (p + count1 > sizeof(struct user)) - count1 = sizeof(struct user)-p; - pnt = (char *) &dump + p; - if (copy_to_user(buf,(void *) pnt, count1)) - return -EFAULT; - buf += count1; - p += count1; - count -= count1; - read += count1; - } - - if (count > 0 && p < PAGE_SIZE + FIRST_MAPPED) { - count1 = PAGE_SIZE + FIRST_MAPPED - p; - if (count1 > count) - count1 = count; - if (clear_user(buf, count1)) - return -EFAULT; - buf += count1; - p += count1; - count -= count1; - read += count1; - } - if (count > 0) { - if (copy_to_user(buf, (void *) (PAGE_OFFSET+p-PAGE_SIZE), count)) - return -EFAULT; - read += count; - } - *ppos += read; - return read; -} -#else /* CONFIG_KCORE_AOUT */ - #ifndef kc_vaddr_to_offset #define kc_vaddr_to_offset(v) ((v) - PAGE_OFFSET) #endif @@ -480,4 +415,3 @@ return acc; } -#endif /* CONFIG_KCORE_AOUT */ diff -Nru a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c --- a/fs/proc/task_mmu.c Tue Sep 2 19:58:13 2003 +++ b/fs/proc/task_mmu.c Tue Sep 2 19:58:13 2003 @@ -90,14 +90,14 @@ ino = inode->i_ino; } - seq_printf(m, "%0*lx-%0*lx %c%c%c%c %0*lx %02x:%02x %lu %n", - (int) (2*sizeof(void*)), map->vm_start, - (int) (2*sizeof(void*)), map->vm_end, + seq_printf(m, "%08lx-%08lx %c%c%c%c %08lx %02x:%02x %lu %n", + map->vm_start, + map->vm_end, flags & VM_READ ? 'r' : '-', flags & VM_WRITE ? 'w' : '-', flags & VM_EXEC ? 'x' : '-', flags & VM_MAYSHARE ? 's' : 'p', - (int) (2*sizeof(void*)), map->vm_pgoff << PAGE_SHIFT, + map->vm_pgoff << PAGE_SHIFT, MAJOR(dev), MINOR(dev), ino, &len); if (map->vm_file) { diff -Nru a/fs/reiserfs/inode.c b/fs/reiserfs/inode.c --- a/fs/reiserfs/inode.c Tue Sep 2 19:58:14 2003 +++ b/fs/reiserfs/inode.c Tue Sep 2 19:58:14 2003 @@ -2048,8 +2048,8 @@ last_offset = inode->i_size & (PAGE_CACHE_SIZE - 1) ; /* no file contents in this page */ if (page->index >= end_index + 1 || !last_offset) { - error = 0 ; - goto done ; + unlock_page(page); + return 0; } kaddr = kmap_atomic(page, KM_USER0); memset(kaddr + last_offset, 0, PAGE_CACHE_SIZE-last_offset) ; diff -Nru a/fs/smbfs/inode.c b/fs/smbfs/inode.c --- a/fs/smbfs/inode.c Tue Sep 2 19:58:13 2003 +++ b/fs/smbfs/inode.c Tue Sep 2 19:58:13 2003 @@ -212,7 +212,7 @@ (long) last_sz, (long) inode->i_size); if (!S_ISDIR(inode->i_mode)) - invalidate_inode_pages(inode->i_mapping); + invalidate_remote_inode(inode); } } @@ -276,7 +276,7 @@ * But we do want to invalidate the caches ... */ if (!S_ISDIR(inode->i_mode)) - invalidate_inode_pages(inode->i_mapping); + invalidate_remote_inode(inode); else smb_invalid_dir_cache(inode); error = -EIO; diff -Nru a/fs/vfat/namei.c b/fs/vfat/namei.c --- a/fs/vfat/namei.c Tue Sep 2 19:58:17 2003 +++ b/fs/vfat/namei.c Tue Sep 2 19:58:17 2003 @@ -200,20 +200,6 @@ return 1; } -/* MS-DOS "device special files" */ - -static const unsigned char *reserved3_names[] = { - "con ", "prn ", "nul ", "aux ", NULL -}; - -static const unsigned char *reserved4_names[] = { - "com1 ", "com2 ", "com3 ", "com4 ", "com5 ", - "com6 ", "com7 ", "com8 ", "com9 ", - "lpt1 ", "lpt2 ", "lpt3 ", "lpt4 ", "lpt5 ", - "lpt6 ", "lpt7 ", "lpt8 ", "lpt9 ", - NULL }; - - /* Characters that are undesirable in an MS-DOS file name */ static wchar_t bad_chars[] = { @@ -255,38 +241,31 @@ return 0; } -/* Checks the validity of a long MS-DOS filename */ -/* Returns negative number on error, 0 for a normal - * return, and 1 for . or .. */ - -static int vfat_valid_longname(const unsigned char *name, int len, int xlate) +static int vfat_valid_longname(const unsigned char *name, unsigned int len) { - const unsigned char **reserved, *walk; - int baselen; - if (len && name[len-1] == ' ') - return -EINVAL; + return 0; if (len >= 256) - return -EINVAL; - if (len < 3) return 0; - for (walk = name; *walk != 0 && *walk != '.'; walk++) - ; - baselen = walk - name; - - if (baselen == 3) { - for (reserved = reserved3_names; *reserved; reserved++) { - if (!strnicmp(name,*reserved,baselen)) - return -EINVAL; - } - } else if (baselen == 4) { - for (reserved = reserved4_names; *reserved; reserved++) { - if (!strnicmp(name,*reserved,baselen)) - return -EINVAL; + /* MS-DOS "device special files" */ + if (len == 3 || (len > 3 && name[3] == '.')) { /* basename == 3 */ + if (!strnicmp(name, "aux", 3) || + !strnicmp(name, "con", 3) || + !strnicmp(name, "nul", 3) || + !strnicmp(name, "prn", 3)) + return 0; + } + if (len == 4 || (len > 4 && name[4] == '.')) { /* basename == 4 */ + /* "com1", "com2", ... */ + if ('1' <= name[3] && name[3] <= '9') { + if (!strnicmp(name, "com", 3) || + !strnicmp(name, "lpt", 3)) + return 0; } } - return 0; + + return 1; } static int vfat_find_form(struct inode *dir, unsigned char *name) @@ -684,9 +663,8 @@ loff_t offset; *slots = 0; - res = vfat_valid_longname(name, len, opts->unicode_xlate); - if (res < 0) - return res; + if (!vfat_valid_longname(name, len)) + return -EINVAL; if(!(page = __get_free_page(GFP_KERNEL))) return -ENOMEM; diff -Nru a/include/asm-arm/apm.h b/include/asm-arm/apm.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/asm-arm/apm.h Tue Sep 2 19:58:20 2003 @@ -0,0 +1,56 @@ +/* -*- linux-c -*- + * + * (C) 2003 zecke@handhelds.org + * + * GPL version 2 + * + * based on arch/arm/kernel/apm.c + * factor out the information needed by architectures to provide + * apm status + * + * + */ +#ifndef ARM_ASM_SA1100_APM_H +#define ARM_ASM_SA1100_APM_H + +#include + +#ifdef CONFIG_APM + + +#define APM_AC_OFFLINE 0 +#define APM_AC_ONLINE 1 +#define APM_AC_BACKUP 2 +#define APM_AC_UNKNOWN 0xFF + +#define APM_BATTERY_STATUS_HIGH 0 +#define APM_BATTERY_STATUS_LOW 1 +#define APM_BATTERY_STATUS_CRITICAL 2 +#define APM_BATTERY_STATUS_CHARGING 3 +#define APM_BATTERY_STATUS_UNKNOWN 0xFF + +#define APM_BATTERY_LIFE_UNKNOWN 0xFFFF +#define APM_BATTERY_LIFE_MINUTES 0x8000 +#define APM_BATTERY_LIFE_VALUE_MASK 0x7FFF + +/* + * This structure gets filled in by the machine specific 'get_power_status' + * implementation. Any fields which are not set default to a safe value. + */ +struct apm_power_info { + unsigned char ac_line_status; + unsigned char battery_status; + unsigned char battery_flag; + unsigned char battery_life; + int time; + int units; +}; + +/* + * This allows machines to provide their own "apm get power status" function. + */ +extern void (*apm_get_power_status)(struct apm_power_info *); +#endif + + +#endif diff -Nru a/include/asm-arm/arch-ebsa285/time.h b/include/asm-arm/arch-ebsa285/time.h --- a/include/asm-arm/arch-ebsa285/time.h Tue Sep 2 19:58:20 2003 +++ b/include/asm-arm/arch-ebsa285/time.h Tue Sep 2 19:58:20 2003 @@ -181,12 +181,13 @@ } +static unsigned long timer1_latch; static unsigned long timer1_gettimeoffset (void) { - unsigned long value = LATCH - *CSR_TIMER1_VALUE; + unsigned long value = timer1_latch - *CSR_TIMER1_VALUE; - return ((tick_nsec / 1000) * value) / LATCH; + return ((tick_nsec / 1000) * value) / timer1_latch; } static irqreturn_t @@ -260,8 +261,10 @@ machine_is_personal_server()) { gettimeoffset = timer1_gettimeoffset; + timer1_latch = (mem_fclk_21285 + 8 * HZ) / (16 * HZ); + *CSR_TIMER1_CLR = 0; - *CSR_TIMER1_LOAD = LATCH; + *CSR_TIMER1_LOAD = timer1_latch; *CSR_TIMER1_CNTL = TIMER_CNTL_ENABLE | TIMER_CNTL_AUTORELOAD | TIMER_CNTL_DIV16; timer_irq.handler = timer1_interrupt; diff -Nru a/include/asm-arm/arch-ebsa285/timex.h b/include/asm-arm/arch-ebsa285/timex.h --- a/include/asm-arm/arch-ebsa285/timex.h Tue Sep 2 19:58:17 2003 +++ b/include/asm-arm/arch-ebsa285/timex.h Tue Sep 2 19:58:17 2003 @@ -11,8 +11,8 @@ */ /* - * On EBSA285 boards, the clock runs at 50MHz and is - * divided by a 4-bit prescaler. Other boards use an - * ISA derived timer, and this is unused. + * We assume a constant here; this satisfies the maths in linux/timex.h + * and linux/time.h. CLOCK_TICK_RATE is actually system dependent, but + * this must be a constant. */ -#define CLOCK_TICK_RATE (mem_fclk_21285 / 16) +#define CLOCK_TICK_RATE (50000000/16) diff -Nru a/include/asm-arm/arch-iop3xx/iop310.h b/include/asm-arm/arch-iop3xx/iop310.h --- a/include/asm-arm/arch-iop3xx/iop310.h Tue Sep 2 19:58:15 2003 +++ b/include/asm-arm/arch-iop3xx/iop310.h Tue Sep 2 19:58:15 2003 @@ -12,6 +12,14 @@ #define _IOP310_HW_H_ /* + * This is needed for mixed drivers that need to work on all + * IOP3xx variants but behave slightly differently on each. + */ +#ifndef __ASSEMBLY__ +#define iop_is_310() ((processor_id & 0xffffe3f0) == 0x69052000) +#endif + +/* * IOP310 I/O and Mem space regions for PCI autoconfiguration */ #define IOP310_PCISEC_LOWER_IO 0x90010000 diff -Nru a/include/asm-arm/arch-iop3xx/iop321.h b/include/asm-arm/arch-iop3xx/iop321.h --- a/include/asm-arm/arch-iop3xx/iop321.h Tue Sep 2 19:58:20 2003 +++ b/include/asm-arm/arch-iop3xx/iop321.h Tue Sep 2 19:58:20 2003 @@ -15,6 +15,10 @@ #define _IOP321_HW_H_ +/* + * This is needed for mixed drivers that need to work on all + * IOP3xx variants but behave slightly differently on each. + */ #ifndef __ASSEMBLY__ #define iop_is_321() ((processor_id & 0xfffff7e0) == 0x69052420) #endif diff -Nru a/include/asm-arm/arch-iop3xx/memory.h b/include/asm-arm/arch-iop3xx/memory.h --- a/include/asm-arm/arch-iop3xx/memory.h Tue Sep 2 19:58:18 2003 +++ b/include/asm-arm/arch-iop3xx/memory.h Tue Sep 2 19:58:18 2003 @@ -66,4 +66,6 @@ extern void *mu_mem; #endif +#define PFN_TO_NID(addr) (0) + #endif diff -Nru a/include/asm-arm/arch-pxa/pxa-regs.h b/include/asm-arm/arch-pxa/pxa-regs.h --- a/include/asm-arm/arch-pxa/pxa-regs.h Tue Sep 2 19:58:17 2003 +++ b/include/asm-arm/arch-pxa/pxa-regs.h Tue Sep 2 19:58:17 2003 @@ -836,7 +836,7 @@ #define GPIO1_RST 1 /* reset */ #define GPIO6_MMCCLK 6 /* MMC Clock */ -#define GPIO8_48MHz 7 /* 48 MHz clock output */ +#define GPIO7_48MHz 7 /* 48 MHz clock output */ #define GPIO8_MMCCS0 8 /* MMC Chip Select 0 */ #define GPIO9_MMCCS1 9 /* MMC Chip Select 1 */ #define GPIO10_RTCCLK 10 /* real time clock (1 Hz) */ @@ -939,7 +939,7 @@ #define GPIO1_RTS_MD ( 1 | GPIO_ALT_FN_1_IN) #define GPIO6_MMCCLK_MD ( 6 | GPIO_ALT_FN_1_OUT) -#define GPIO8_48MHz_MD ( 8 | GPIO_ALT_FN_1_OUT) +#define GPIO7_48MHz_MD ( 7 | GPIO_ALT_FN_1_OUT) #define GPIO8_MMCCS0_MD ( 8 | GPIO_ALT_FN_1_OUT) #define GPIO9_MMCCS1_MD ( 9 | GPIO_ALT_FN_1_OUT) #define GPIO10_RTCCLK_MD (10 | GPIO_ALT_FN_1_OUT) diff -Nru a/include/asm-arm/arch-sa1100/simpad.h b/include/asm-arm/arch-sa1100/simpad.h --- a/include/asm-arm/arch-sa1100/simpad.h Tue Sep 2 19:58:14 2003 +++ b/include/asm-arm/arch-sa1100/simpad.h Tue Sep 2 19:58:14 2003 @@ -5,17 +5,13 @@ * * This file contains the hardware specific definitions for SIMpad * - * 2001/05/14 Juergen Messerer + * 2001/05/14 Juergen Messerer */ -#ifndef SIMPAD_H -#define SIMPAD_H +#ifndef __ASM_ARCH_SIMPAD_H +#define __ASM_ARCH_SIMPAD_H -#ifndef __ASM_ARCH_HARDWARE_H -#error "include instead" -#endif - #define GPIO_UART1_RTS GPIO_GPIO14 #define GPIO_UART1_DTR GPIO_GPIO7 #define GPIO_UART1_CTS GPIO_GPIO8 @@ -28,7 +24,8 @@ #define GPIO_UART3_DCD GPIO_GPIO18 #define GPIO_UART3_DSR GPIO_GPIO17 -#define GPIO_UCB1300_IRQ GPIO_GPIO (22) /* UCB GPIO and touchscreen */ +#define GPIO_POWER_BUTTON GPIO_GPIO0 +#define GPIO_UCB1300_IRQ GPIO_GPIO22 /* UCB GPIO and touchscreen */ #define IRQ_UART1_CTS IRQ_GPIO15 #define IRQ_UART1_DCD GPIO_GPIO23 @@ -37,21 +34,26 @@ #define IRQ_UART3_DCD GPIO_GPIO18 #define IRQ_UART3_DSR GPIO_GPIO17 -#define IRQ_GPIO_UCB1300_IRQ IRQ_GPIO22 +#define IRQ_GPIO_UCB1300_IRQ IRQ_GPIO22 +#define IRQ_GPIO_POWER_BUTTON IRQ_GPIO0 /*--- PCMCIA ---*/ #define GPIO_CF_CD GPIO_GPIO24 -#define GPIO_CF_IRQ GPIO_GPIO1 +#define GPIO_CF_IRQ GPIO_GPIO1 #define IRQ_GPIO_CF_IRQ IRQ_GPIO1 -#define IRQ_GPIO_CF_CD IRQ_GPIO24 +#define IRQ_GPIO_CF_CD IRQ_GPIO24 + +/*--- SmartCard ---*/ +#define GPIO_SMART_CARD GPIO_GPIO10 +#define IRQ_GPIO_SMARD_CARD IRQ_GPIO10 -// CS3 Latch is write only, a shadow is necessary +// CS3 Latch is write only, a shadow is necessary -#define CS3BUSTYPE unsigned volatile long +#define CS3BUSTYPE unsigned volatile long #define CS3_BASE 0xf1000000 -#define VCC_5V_EN 0x0001 // For 5V PCMCIA +#define VCC_5V_EN 0x0001 // For 5V PCMCIA #define VCC_3V_EN 0x0002 // FOR 3.3V PCMCIA #define EN1 0x0004 // This is only for EPROM's #define EN0 0x0008 // Both should be enable for 3.3V or 5V @@ -63,15 +65,43 @@ #define IRDA_SD 0x0200 // Shutdown for powersave #define RS232_ON 0x0400 #define SD_MEDIAQ 0x0800 // Shutdown for powersave -#define LED2_ON 0x1000 +#define LED2_ON 0x1000 #define IRDA_MODE 0x2000 // Fast/Slow IrDA mode #define ENABLE_5V 0x4000 // Enable 5V circuit #define RESET_SIMCARD 0x8000 #define RS232_ENABLE 0x0440 -#define PCMCIAMASK 0x402f +#define PCMCIAMASK 0x402f + + +struct simpad_battery { + unsigned char ac_status; /* line connected yes/no */ + unsigned char status; /* battery loading yes/no */ + unsigned char percentage; /* percentage loaded */ + unsigned short life; /* life till empty */ +}; + +/* These should match the apm_bios.h definitions */ +#define SIMPAD_AC_STATUS_AC_OFFLINE 0x00 +#define SIMPAD_AC_STATUS_AC_ONLINE 0x01 +#define SIMPAD_AC_STATUS_AC_BACKUP 0x02 /* What does this mean? */ +#define SIMPAD_AC_STATUS_AC_UNKNOWN 0xff + +/* These bitfields are rarely "or'd" together */ +#define SIMPAD_BATT_STATUS_HIGH 0x01 +#define SIMPAD_BATT_STATUS_LOW 0x02 +#define SIMPAD_BATT_STATUS_CRITICAL 0x04 +#define SIMPAD_BATT_STATUS_CHARGING 0x08 +#define SIMPAD_BATT_STATUS_CHARGE_MAIN 0x10 +#define SIMPAD_BATT_STATUS_DEAD 0x20 /* Battery will not charge */ +#define SIMPAD_BATT_NOT_INSTALLED 0x20 /* For expansion pack batteries */ +#define SIMPAD_BATT_STATUS_FULL 0x40 /* Battery fully charged (and connected to AC) */ +#define SIMPAD_BATT_STATUS_NOBATT 0x80 +#define SIMPAD_BATT_STATUS_UNKNOWN 0xff + +extern int simpad_get_battery(struct simpad_battery* ); -#endif // SIMPAD_H +#endif // __ASM_ARCH_SIMPAD_H diff -Nru a/include/asm-arm/checksum.h b/include/asm-arm/checksum.h --- a/include/asm-arm/checksum.h Tue Sep 2 19:58:18 2003 +++ b/include/asm-arm/checksum.h Tue Sep 2 19:58:18 2003 @@ -105,7 +105,7 @@ adcs %0, %0, %5 \n\ adc %0, %0, #0" : "=&r"(sum) - : "r" (sum), "r" (daddr), "r" (saddr), "r" (ntohs(len) << 16), "Ir" (proto << 8) + : "r" (sum), "r" (daddr), "r" (saddr), "r" (ntohs(len)), "Ir" (ntohs(proto)) : "cc"); return sum; } @@ -127,7 +127,7 @@ addcs %0, %0, #0x10000 \n\ mvn %0, %0" : "=&r"(sum) - : "r" (sum), "r" (daddr), "r" (saddr), "r" (ntohs(len)), "Ir" (proto << 8) + : "r" (sum), "r" (daddr), "r" (saddr), "r" (ntohs(len)), "Ir" (ntohs(proto)) : "cc"); return sum >> 16; } diff -Nru a/include/asm-arm/dma-mapping.h b/include/asm-arm/dma-mapping.h --- a/include/asm-arm/dma-mapping.h Tue Sep 2 19:58:12 2003 +++ b/include/asm-arm/dma-mapping.h Tue Sep 2 19:58:12 2003 @@ -129,6 +129,28 @@ } /** + * dma_map_page - map a portion of a page for streaming DMA + * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices + * @page: page that buffer resides in + * @offset: offset into page for start of buffer + * @size: size of buffer to map + * @dir: DMA transfer direction + * + * Ensure that any data held in the cache is appropriately discarded + * or written back. + * + * The device owns this memory once this call has completed. The CPU + * can regain ownership by calling dma_unmap_page() or dma_sync_single(). + */ +static inline dma_addr_t +dma_map_page(struct device *dev, struct page *page, + unsigned long offset, size_t size, + enum dma_data_direction dir) +{ + return dma_map_single(dev, page_address(page) + offset, size, (int)dir); +} + +/** * dma_unmap_single - unmap a single buffer previously mapped * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices * @handle: DMA address of buffer @@ -152,21 +174,26 @@ /* nothing to do */ } -#if 0 -static inline dma_addr_t -dma_map_page(struct device *dev, struct page *page, unsigned long off, - size_t size, enum dma_data_direction dir) -{ - /* fixme */ -} - +/** + * dma_unmap_page - unmap a buffer previously mapped through dma_map_page() + * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices + * @handle: DMA address of buffer + * @size: size of buffer to map + * @dir: DMA transfer direction + * + * Unmap a single streaming mode DMA translation. The handle and size + * must match what was provided in the previous dma_map_single() call. + * All other usages are undefined. + * + * After this call, reads by the CPU to the buffer are guaranteed to see + * whatever the device wrote there. + */ static inline void dma_unmap_page(struct device *dev, dma_addr_t handle, size_t size, enum dma_data_direction dir) { - /* fixme */ + dma_unmap_single(dev, handle, size, (int)dir); } -#endif /** * dma_map_sg - map a set of SG buffers for streaming mode DMA diff -Nru a/include/asm-arm/hardware/amba.h b/include/asm-arm/hardware/amba.h --- a/include/asm-arm/hardware/amba.h Tue Sep 2 19:58:18 2003 +++ b/include/asm-arm/hardware/amba.h Tue Sep 2 19:58:18 2003 @@ -28,8 +28,8 @@ int (*probe)(struct amba_device *, void *); int (*remove)(struct amba_device *); void (*shutdown)(struct amba_device *); - int (*suspend)(struct amba_device *, u32, u32); - int (*resume)(struct amba_device *, u32); + int (*suspend)(struct amba_device *, u32); + int (*resume)(struct amba_device *); struct amba_id *id_table; }; diff -Nru a/include/asm-arm/hardware/sa1111.h b/include/asm-arm/hardware/sa1111.h --- a/include/asm-arm/hardware/sa1111.h Tue Sep 2 19:58:19 2003 +++ b/include/asm-arm/hardware/sa1111.h Tue Sep 2 19:58:19 2003 @@ -542,9 +542,16 @@ #define SA1111_DEV(_d) container_of((_d), struct sa1111_dev, dev) +#define sa1111_get_drvdata(d) dev_get_drvdata(&(d)->dev) +#define sa1111_set_drvdata(d,p) dev_get_drvdata(&(d)->dev, p) + struct sa1111_driver { struct device_driver drv; unsigned int devid; + int (*probe)(struct sa1111_dev *); + int (*remove)(struct sa1111_dev *); + int (*suspend)(struct sa1111_dev *, u32); + int (*resume)(struct sa1111_dev *); }; #define SA1111_DRV(_d) container_of((_d), struct sa1111_driver, drv) @@ -572,5 +579,8 @@ int sa1111_get_audio_rate(struct sa1111_dev *sadev); int sa1111_check_dma_bug(dma_addr_t addr); + +int sa1111_driver_register(struct sa1111_driver *); +void sa1111_driver_unregister(struct sa1111_driver *); #endif /* _ASM_ARCH_SA1111 */ diff -Nru a/include/asm-arm/pci.h b/include/asm-arm/pci.h --- a/include/asm-arm/pci.h Tue Sep 2 19:58:14 2003 +++ b/include/asm-arm/pci.h Tue Sep 2 19:58:14 2003 @@ -96,6 +96,19 @@ return dma_unmap_sg(hwdev ? &hwdev->dev : NULL, sg, nents, dir); } +static inline dma_addr_t +pci_map_page(struct pci_dev *hwdev, struct page *page, unsigned long offset, + size_t size, int dir) +{ + return pci_map_single(hwdev, page_address(page) + offset, size, dir); +} + +static inline void +pci_unmap_page(struct pci_dev *hwdev, dma_addr_t handle, size_t size, int dir) +{ + return pci_unmap_single(hwdev, handle, size, dir); +} + static inline void pci_dma_sync_single(struct pci_dev *hwdev, dma_addr_t handle, size_t size, int dir) { diff -Nru a/include/asm-arm/proc-armo/processor.h b/include/asm-arm/proc-armo/processor.h --- a/include/asm-arm/proc-armo/processor.h Tue Sep 2 19:58:14 2003 +++ b/include/asm-arm/proc-armo/processor.h Tue Sep 2 19:58:14 2003 @@ -43,7 +43,7 @@ uaccess_t *uaccess; /* User access functions*/ #define EXTRA_THREAD_STRUCT_INIT \ - uaccess: &uaccess_kernel, + .uaccess = &uaccess_kernel, #define start_thread(regs,pc,sp) \ ({ \ diff -Nru a/include/asm-arm/unistd.h b/include/asm-arm/unistd.h --- a/include/asm-arm/unistd.h Tue Sep 2 19:58:19 2003 +++ b/include/asm-arm/unistd.h Tue Sep 2 19:58:19 2003 @@ -303,7 +303,7 @@ "swi 0\n\t" \ "pop {r7}" #else -#define __syscall(name) "swi\t" __sys1(__NR_##name) "\n\t" +#define __syscall(name) "swi\t" __sys1(__NR_##name) "" #endif #endif @@ -318,24 +318,28 @@ #define _syscall0(type,name) \ type name(void) { \ - register long __res __asm__("r0"); \ + register long __res_r0 __asm__("r0"); \ + long __res; \ __asm__ __volatile__ ( \ __syscall(name) \ - :"=r" (__res) \ + : "=r" (__res_r0) \ : \ : "lr"); \ + __res = __res_r0; \ __syscall_return(type,__res); \ } #define _syscall1(type,name,type1,arg1) \ type name(type1 arg1) { \ register long __r0 __asm__("r0") = (long)arg1; \ - register long __res __asm__("r0"); \ + register long __res_r0 __asm__("r0"); \ + long __res; \ __asm__ __volatile__ ( \ __syscall(name) \ - : "=r" (__res) \ + : "=r" (__res_r0) \ : "r" (__r0) \ : "lr"); \ + __res = __res_r0; \ __syscall_return(type,__res); \ } @@ -343,12 +347,14 @@ type name(type1 arg1,type2 arg2) { \ register long __r0 __asm__("r0") = (long)arg1; \ register long __r1 __asm__("r1") = (long)arg2; \ - register long __res __asm__("r0"); \ + register long __res_r0 __asm__("r0"); \ + long __res; \ __asm__ __volatile__ ( \ __syscall(name) \ - : "=r" (__res) \ + : "=r" (__res_r0) \ : "r" (__r0),"r" (__r1) \ : "lr"); \ + __res = __res_r0; \ __syscall_return(type,__res); \ } @@ -358,12 +364,14 @@ register long __r0 __asm__("r0") = (long)arg1; \ register long __r1 __asm__("r1") = (long)arg2; \ register long __r2 __asm__("r2") = (long)arg3; \ - register long __res __asm__("r0"); \ + register long __res_r0 __asm__("r0"); \ + long __res; \ __asm__ __volatile__ ( \ __syscall(name) \ - : "=r" (__res) \ + : "=r" (__res_r0) \ : "r" (__r0),"r" (__r1),"r" (__r2) \ : "lr"); \ + __res = __res_r0; \ __syscall_return(type,__res); \ } @@ -374,12 +382,14 @@ register long __r1 __asm__("r1") = (long)arg2; \ register long __r2 __asm__("r2") = (long)arg3; \ register long __r3 __asm__("r3") = (long)arg4; \ - register long __res __asm__("r0"); \ + register long __res_r0 __asm__("r0"); \ + long __res; \ __asm__ __volatile__ ( \ __syscall(name) \ - : "=r" (__res) \ + : "=r" (__res_r0) \ : "r" (__r0),"r" (__r1),"r" (__r2),"r" (__r3) \ : "lr"); \ + __res = __res_r0; \ __syscall_return(type,__res); \ } @@ -391,12 +401,14 @@ register long __r2 __asm__("r2") = (long)arg3; \ register long __r3 __asm__("r3") = (long)arg4; \ register long __r4 __asm__("r4") = (long)arg5; \ - register long __res __asm__("r0"); \ + register long __res_r0 __asm__("r0"); \ + long __res; \ __asm__ __volatile__ ( \ __syscall(name) \ - : "=r" (__res) \ + : "=r" (__res_r0) \ : "r" (__r0),"r" (__r1),"r" (__r2),"r" (__r3),"r" (__r4) \ : "lr"); \ + __res = __res_r0; \ __syscall_return(type,__res); \ } @@ -408,12 +420,14 @@ register long __r3 __asm__("r3") = (long)arg4; \ register long __r4 __asm__("r4") = (long)arg5; \ register long __r5 __asm__("r5") = (long)arg6; \ - register long __res __asm__("r0"); \ + register long __res_r0 __asm__("r0"); \ + long __res; \ __asm__ __volatile__ ( \ __syscall(name) \ - : "=r" (__res) \ + : "=r" (__res_r0) \ : "r" (__r0),"r" (__r1),"r" (__r2),"r" (__r3), "r" (__r4),"r" (__r5) \ : "lr"); \ + __res = __res_r0; \ __syscall_return(type,__res); \ } diff -Nru a/include/asm-arm/xor.h b/include/asm-arm/xor.h --- a/include/asm-arm/xor.h Tue Sep 2 19:58:15 2003 +++ b/include/asm-arm/xor.h Tue Sep 2 19:58:15 2003 @@ -125,11 +125,11 @@ } static struct xor_block_template xor_block_arm4regs = { - name: "arm4regs", - do_2: xor_arm4regs_2, - do_3: xor_arm4regs_3, - do_4: xor_arm4regs_4, - do_5: xor_arm4regs_5, + .name = "arm4regs", + .do_2 = xor_arm4regs_2, + .do_3 = xor_arm4regs_3, + .do_4 = xor_arm4regs_4, + .do_5 = xor_arm4regs_5, }; #undef XOR_TRY_TEMPLATES diff -Nru a/include/asm-arm26/processor.h b/include/asm-arm26/processor.h --- a/include/asm-arm26/processor.h Tue Sep 2 19:58:16 2003 +++ b/include/asm-arm26/processor.h Tue Sep 2 19:58:16 2003 @@ -51,7 +51,7 @@ uaccess_t *uaccess; /* User access functions*/ #define EXTRA_THREAD_STRUCT_INIT \ - uaccess: &uaccess_kernel, + .uaccess = &uaccess_kernel, // FIXME?!! diff -Nru a/include/asm-arm26/xor.h b/include/asm-arm26/xor.h --- a/include/asm-arm26/xor.h Tue Sep 2 19:58:15 2003 +++ b/include/asm-arm26/xor.h Tue Sep 2 19:58:15 2003 @@ -125,11 +125,11 @@ } static struct xor_block_template xor_block_arm4regs = { - name: "arm4regs", - do_2: xor_arm4regs_2, - do_3: xor_arm4regs_3, - do_4: xor_arm4regs_4, - do_5: xor_arm4regs_5, + .name = "arm4regs", + .do_2 = xor_arm4regs_2, + .do_3 = xor_arm4regs_3, + .do_4 = xor_arm4regs_4, + .do_5 = xor_arm4regs_5, }; #undef XOR_TRY_TEMPLATES diff -Nru a/include/asm-h8300/aki3068net/ne.h b/include/asm-h8300/aki3068net/ne.h --- a/include/asm-h8300/aki3068net/ne.h Tue Sep 2 19:58:19 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,28 +0,0 @@ -/* AE-3068 (aka. aki3068net) RTL8019AS Config */ - -#ifndef __H8300_AKI3068NET_NE__ -#define __H8300_AKI3068NET_NE__ - -#define NE2000_ADDR 0x200000 -#define NE2000_IRQ 5 -#define NE2000_IRQ_VECTOR (12 + NE2000_IRQ) -#define NE2000_BYTE volatile unsigned short - -#define IER 0xfee015 -#define ISR 0xfee016 -#define IRQ_MASK (1 << NE2000_IRQ) - -#define WCRL 0xfee023 -#define MAR0A 0xffff20 -#define ETCR0A 0xffff24 -#define DTCR0A 0xffff27 -#define MAR0B 0xffff28 -#define DTCR0B 0xffff2f - -#define H8300_INIT_NE() \ -do { \ - wordlength = 1; \ - outb_p(0x48, ioaddr + EN0_DCFG); \ -} while(0) - -#endif diff -Nru a/include/asm-h8300/aki3068net/timer_rate.h b/include/asm-h8300/aki3068net/timer_rate.h --- a/include/asm-h8300/aki3068net/timer_rate.h Tue Sep 2 19:58:17 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,9 +0,0 @@ -#ifndef __H8300_AKI3068NET_TIMER_RATE__ -#define __H8300_AKI3068NET_TIMER_RATE__ - -#include - -#define H8300_TIMER_COUNT_DATA CONFIG_CPU_CLOCK*10/8192 -#define H8300_TIMER_FREQ CONFIG_CPU_CLOCK*1000/8192 - -#endif diff -Nru a/include/asm-h8300/edosk2674/timer_rate.h b/include/asm-h8300/edosk2674/timer_rate.h --- a/include/asm-h8300/edosk2674/timer_rate.h Tue Sep 2 19:58:15 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,4 +0,0 @@ -#include - -#define H8300_TIMER_COUNT_DATA CONFIG_CPU_CLOCK*10/8192 -#define H8300_TIMER_FREQ CONFIG_CPU_CLOCK*1000/8192 diff -Nru a/include/asm-h8300/h8300_smsc.h b/include/asm-h8300/h8300_smsc.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/asm-h8300/h8300_smsc.h Tue Sep 2 19:58:20 2003 @@ -0,0 +1,20 @@ +/****************************************************************************/ + +/* + * h8300_smsc.h -- SMSC in H8/300H and H8S Evalution Board. + * + * (C) Copyright 2003, Yoshinori Sato + */ + +/****************************************************************************/ +#ifndef h8300smsc_h +#define h8300smsc_h +/****************************************************************************/ + +/* Such a description is OK ? */ +#define H8300_SMSC_DEFINE +#include +#undef H8300_SMSC_DEFINE + +/****************************************************************************/ +#endif /* h8300smsc_h */ diff -Nru a/include/asm-h8300/h8max/machine-depend.h b/include/asm-h8300/h8max/machine-depend.h --- a/include/asm-h8300/h8max/machine-depend.h Tue Sep 2 19:58:17 2003 +++ b/include/asm-h8300/h8max/machine-depend.h Tue Sep 2 19:58:17 2003 @@ -101,67 +101,3 @@ } #endif - -/* H8MAX IDE I/F Config */ -#ifdef H8300_IDE_DEFINE - -#define H8300_IDE_BASE 0x200000 -#define H8300_IDE_CTRL 0x60000c -#define H8300_IDE_IRQ 5 -#define H8300_IDE_REG_OFFSET 2 - -#undef outb -#undef inb -#undef outb_p -#undef inb_p -#undef outsw -#undef insw - -#define outb(d,a) h8max_outb(d,(unsigned short *)a) -#define inb(a) h8max_inb((unsigned char *)a) -#define outb_p(d,a) h8max_outb(d,(unsigned short *)a) -#define inb_p(a) h8max_inb((unsigned char *)a) -#define outsw(addr,buf,len) h8max_outsw(addr,buf,len); -#define insw(addr,buf,len) h8max_insw(addr,buf,len); - -static inline void h8max_outb(unsigned short d,unsigned short *a) -{ - *a = d; -} - -static inline unsigned char h8max_inb(unsigned char *a) -{ - return *(a+1); -} - -static inline void h8max_outsw(void *addr, void *buf, int len) -{ - unsigned volatile short *ap = (unsigned volatile short *)addr; - unsigned short *bp = (unsigned short *)buf; - unsigned short d; - while(len--) { - d = *bp++; - *ap = (d >> 8) | (d << 8); - } -} - -static inline void h8max_insw(void *addr, void *buf, int len) -{ - unsigned volatile short *ap = (unsigned volatile short *)addr; - unsigned short *bp = (unsigned short *)buf; - unsigned short d; - while(len--) { - d = *ap; - *bp++ = (d >> 8) | (d << 8); - } -} - -static inline void target_ide_fix_driveid(struct hd_driveid *id) -{ - int c; - unsigned short *p = (unsigned short *)id; - for (c = 0; c < SECTOR_WORDS; c++, p++) - *p = (*p >> 8) | (*p << 8); -} - -#endif diff -Nru a/include/asm-h8300/h8max/ne.h b/include/asm-h8300/h8max/ne.h --- a/include/asm-h8300/h8max/ne.h Tue Sep 2 19:58:13 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,97 +0,0 @@ -/* H8MAX RTL8019AS Config */ - -#ifndef __H8300_H8MAX_NE__ -#define __H8300_H8MAX_NE__ - -#define NE2000_ADDR 0x800600 -#define NE2000_IRQ 4 -#define NE2000_IRQ_VECTOR (12 + NE2000_IRQ) -#define NE2000_BYTE volatile unsigned short - -#define IER 0xfee015 -#define ISR 0xfee016 -#define IRQ_MASK (1 << NE2000_IRQ) -/* sorry quick hack */ -#if defined(outb) -# undef outb -#endif -#define outb(d,a) h8max_outb((d),(a) - NE2000_ADDR) -#if defined(inb) -# undef inb -#endif -#define inb(a) h8max_inb((a) - NE2000_ADDR) -#if defined(outb_p) -# undef outb_p -#endif -#define outb_p(d,a) h8max_outb((d),(a) - NE2000_ADDR) -#if defined(inb_p) -# undef inb_p -#endif -#define inb_p(a) h8max_inb((a) - NE2000_ADDR) -#if defined(outsw) -# undef outsw -#endif -#define outsw(a,p,l) h8max_outsw((a) - NE2000_ADDR,(unsigned short *)p,l) -#if defined(insw) -# undef insw -#endif -#define insw(a,p,l) h8max_insw((a) - NE2000_ADDR,(unsigned short *)p,l) -#if defined(outsb) -# undef outsb -#endif -#define outsb(a,p,l) h8max_outsb((a) - NE2000_ADDR,(unsigned char *)p,l) -#if defined(insb) -# undef insb -#endif -#define insb(a,p,l) h8max_insb((a) - NE2000_ADDR,(unsigned char *)p,l) - -#define H8300_INIT_NE() \ -do { \ - wordlength = 2; \ - h8max_outb(0x49, ioaddr + EN0_DCFG); \ - SA_prom[14] = SA_prom[15] = 0x57;\ -} while(0) - -static inline void h8max_outb(unsigned char d,unsigned char a) -{ - *(unsigned short *)(NE2000_ADDR + (a << 1)) = d; -} - -static inline unsigned char h8max_inb(unsigned char a) -{ - return *(unsigned char *)(NE2000_ADDR + (a << 1) +1); -} - -static inline void h8max_outsw(unsigned char a,unsigned short *p,unsigned long l) -{ - unsigned short d; - for (; l != 0; --l, p++) { - d = (((*p) >> 8) & 0xff) | ((*p) << 8); - *(unsigned short *)(NE2000_ADDR + (a << 1)) = d; - } -} - -static inline void h8max_insw(unsigned char a,unsigned short *p,unsigned long l) -{ - unsigned short d; - for (; l != 0; --l, p++) { - d = *(unsigned short *)(NE2000_ADDR + (a << 1)); - *p = (d << 8)|((d >> 8) & 0xff); - } -} - -static inline void h8max_outsb(unsigned char a,unsigned char *p,unsigned long l) -{ - for (; l != 0; --l, p++) { - *(unsigned short *)(NE2000_ADDR + (a << 1)) = *p; - } -} - -static inline void h8max_insb(unsigned char a,unsigned char *p,unsigned long l) -{ - for (; l != 0; --l, p++) { - *p = *((unsigned char *)(NE2000_ADDR + (a << 1))+1); - } -} - -#endif diff -Nru a/include/asm-h8300/h8max/timer_rate.h b/include/asm-h8300/h8max/timer_rate.h --- a/include/asm-h8300/h8max/timer_rate.h Tue Sep 2 19:58:19 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,10 +0,0 @@ -#ifndef __H8300_H8MAX_TIMER_RATE__ -#define __H8300_H8MAX_TIMER_RATE__ - -#include - -#define H8300_TIMER_COUNT_DATA CONFIG_CPU_CLOCK*10/8192 -#define H8300_TIMER_FREQ CONFIG_CPU_CLOCK*1000/8192 - -#endif - diff -Nru a/include/asm-h8300/ide.h b/include/asm-h8300/ide.h --- a/include/asm-h8300/ide.h Tue Sep 2 19:58:13 2003 +++ b/include/asm-h8300/ide.h Tue Sep 2 19:58:13 2003 @@ -16,145 +16,26 @@ #ifdef __KERNEL__ /****************************************************************************/ -#include -#include +void h8300_ide_print_resource(char *name, hw_regs_t *hw); +static inline int ide_default_irq(unsigned long base) { return 0; }; +static inline ide_ioreg_t ide_default_io_base(int index) { return 0; }; -#include -#include -#include - -/* - * Some coldfire specifics. - */ - -/* - * Save some space, only have 1 interface. - */ -#define MAX_HWIFS 1 - -/* - * Fix up things that may not have been provided. - */ - -#undef SUPPORT_SLOW_DATA_PORTS -#define SUPPORT_SLOW_DATA_PORTS 0 - -#undef SUPPORT_VLB_SYNC -#define SUPPORT_VLB_SYNC 0 - -/* this definition is used only on startup .. */ -#undef HD_DATA -#define HD_DATA NULL - -#define DBGIDE(fmt,a...) -// #define DBGIDE(fmt,a...) printk(fmt, ##a) -#define IDE_INLINE __inline__ -// #define IDE_INLINE - -#define ide__sti() __sti() - -/****************************************************************************/ - -typedef union { - unsigned all : 8; /* all of the bits together */ - struct { - unsigned bit7 : 1; /* always 1 */ - unsigned lba : 1; /* using LBA instead of CHS */ - unsigned bit5 : 1; /* always 1 */ - unsigned unit : 1; /* drive select number, 0 or 1 */ - unsigned head : 4; /* always zeros here */ - } b; -} select_t; - -/* - * Our list of ports/irq's for different boards. - */ - -/* machine depend header include */ -#define H8300_IDE_DEFINE -#include -#undef H8300_IDE_DEFINE - -/****************************************************************************/ - -static IDE_INLINE int ide_default_irq(ide_ioreg_t base) +static __inline__ void ide_init_hwif_ports(hw_regs_t *hw, unsigned long data_port, + unsigned long ctrl_port, int *irq) { - return H8300_IDE_IRQ+12; } -static IDE_INLINE ide_ioreg_t ide_default_io_base(int index) -{ - return (ide_ioreg_t)H8300_IDE_BASE; -} -/* - * Set up a hw structure for a specified data port, control port and IRQ. - * This should follow whatever the default interface uses. - */ -static IDE_INLINE void ide_init_hwif_ports( - hw_regs_t *hw, - ide_ioreg_t data_port, - ide_ioreg_t ctrl_port, - int *irq) +static inline void ide_init_default_hwifs(void) { - ide_ioreg_t reg = data_port; - int i; - - for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; i++) { - hw->io_ports[i] = reg; - reg += H8300_IDE_REG_OFFSET; - } - if (ctrl_port) { - hw->io_ports[IDE_CONTROL_OFFSET] = ctrl_port; - } else { - hw->io_ports[IDE_CONTROL_OFFSET] = (ide_ioreg_t)H8300_IDE_CTRL; - } } +#define MAX_HWIFS 1 -/* - * This registers the standard ports for this architecture with the IDE - * driver. - */ -static IDE_INLINE void ide_init_default_hwifs(void) -{ - hw_regs_t hw; - ide_ioreg_t base; - int index; - - for (index = 0; index < MAX_HWIFS; index++) { - base = ide_default_io_base(index); - if (!base) - continue; - memset(&hw, 0, sizeof(hw)); - ide_init_hwif_ports(&hw, base, 0, NULL); - hw.irq = ide_default_irq(base); - ide_register_hw(&hw, NULL); - } -} - -#define ide_request_irq(irq,hand,flg,dev,id) request_irq((irq),(hand),(flg),(dev),(id)) -#define ide_free_irq(irq,dev_id) free_irq((irq), (dev_id)) -#define ide_check_region(from,extent) (0) -#define ide_request_region(from,extent,name) do {} while(0) -#define ide_release_region(from,extent) do {} while(0) - -/* - * The following are not needed for the non-m68k ports - */ -#define ide_ack_intr(hwif) (1) -#define ide_fix_driveid(id) target_ide_fix_driveid(id) -#define ide_release_lock(lock) do {} while (0) -#define ide_get_lock(lock, hdlr, data) do {} while (0) - -static IDE_INLINE void ide_print_resource(char *name,hw_regs_t *hw) -{ - printk("%s at 0x%08x-0x%08x,0x%08x on irq %d", name, - (unsigned int)hw->io_ports[IDE_DATA_OFFSET], - (unsigned int)hw->io_ports[IDE_DATA_OFFSET]+(8*H8300_IDE_REG_OFFSET)-1, - (unsigned int)hw->io_ports[IDE_CONTROL_OFFSET], - hw->irq); -} +#define __ide_mm_insw(port,addr,count) do { } while(0) +#define __ide_mm_insl(port,addr,count) do { } while(0) +#define __ide_mm_outsw(port,addr,count) do { } while(0) +#define __ide_mm_outsl(port,addr,count) do { } while(0) /****************************************************************************/ #endif /* __KERNEL__ */ diff -Nru a/include/asm-h8300/irq.h b/include/asm-h8300/irq.h --- a/include/asm-h8300/irq.h Tue Sep 2 19:58:13 2003 +++ b/include/asm-h8300/irq.h Tue Sep 2 19:58:13 2003 @@ -3,11 +3,35 @@ #include -#if defined(CONFIG_CPU_H8300H) +#if defined(__H8300H__) #define NR_IRQS 64 +#define EXT_IRQ0 12 +#define EXT_IRQ1 13 +#define EXT_IRQ2 14 +#define EXT_IRQ3 15 +#define EXT_IRQ4 16 +#define EXT_IRQ5 17 +#define EXT_IRQ6 18 +#define EXT_IRQ7 19 #endif #if defined(CONFIG_CPU_H8S) #define NR_IRQS 128 +#define EXT_IRQ0 16 +#define EXT_IRQ1 17 +#define EXT_IRQ2 18 +#define EXT_IRQ3 19 +#define EXT_IRQ4 20 +#define EXT_IRQ5 21 +#define EXT_IRQ6 22 +#define EXT_IRQ7 23 +#define EXT_IRQ8 24 +#define EXT_IRQ9 25 +#define EXT_IRQ10 26 +#define EXT_IRQ11 27 +#define EXT_IRQ12 28 +#define EXT_IRQ13 29 +#define EXT_IRQ14 30 +#define EXT_IRQ15 31 #endif static __inline__ int irq_canonicalize(int irq) diff -Nru a/include/asm-h8300/machine-depend.h b/include/asm-h8300/machine-depend.h --- a/include/asm-h8300/machine-depend.h Tue Sep 2 19:58:14 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,70 +0,0 @@ -/* EDOSK2674 board depend header */ - -/* TIMER rate define */ -#ifdef H8300_TIMER_DEFINE -#define H8300_TIMER_COUNT_DATA 33000*10/8192 -#define H8300_TIMER_FREQ 33000*1000/8192 -#endif - -/* EDOSK-2674R SMSC Network Controler Target Depend impliments */ -#ifdef H8300_SMSC_DEFINE - -#define SMSC_BASE 0xf80000 -#define SMSC_IRQ 16 - -/* sorry quick hack */ -#if defined(outw) -# undef outw -#endif -#define outw(d,a) edosk2674_smsc_outw(d,(volatile unsigned short *)(a)) -#if defined(inw) -# undef inw -#endif -#define inw(a) edosk2674_smsc_inw((volatile unsigned short *)(a)) -#if defined(outsw) -# undef outsw -#endif -#define outsw(a,p,l) edosk2674_smsc_outsw((volatile unsigned short *)(a),p,l) -#if defined(insw) -# undef insw -#endif -#define insw(a,p,l) edosk2674_smsc_insw((volatile unsigned short *)(a),p,l) - -static inline void edosk2674_smsc_outw( - unsigned short d, - volatile unsigned short *a - ) -{ - *a = (d >> 8) | (d << 8); -} - -static inline unsigned short edosk2674_smsc_inw( - volatile unsigned short *a - ) -{ - unsigned short d; - d = *a; - return (d >> 8) | (d << 8); -} - -static inline void edosk2674_smsc_outsw( - volatile unsigned short *a, - unsigned short *p, - unsigned long l - ) -{ - for (; l != 0; --l, p++) - *a = *p; -} - -static inline void edosk2674_smsc_insw( - volatile unsigned short *a, - unsigned short *p, - unsigned long l - ) -{ - for (; l != 0; --l, p++) - *p = *a; -} - -#endif diff -Nru a/include/asm-h8300/pci.h b/include/asm-h8300/pci.h --- a/include/asm-h8300/pci.h Tue Sep 2 19:58:16 2003 +++ b/include/asm-h8300/pci.h Tue Sep 2 19:58:16 2003 @@ -19,4 +19,6 @@ /* We don't do dynamic PCI IRQ allocation */ } +#define PCI_DMA_BUS_IS_PHYS (1) + #endif /* _ASM_H8300_PCI_H */ diff -Nru a/include/asm-i386/apic.h b/include/asm-i386/apic.h --- a/include/asm-i386/apic.h Tue Sep 2 19:58:19 2003 +++ b/include/asm-i386/apic.h Tue Sep 2 19:58:19 2003 @@ -64,6 +64,8 @@ apic_write_around(APIC_EOI, 0); } +extern void (*wait_timer_tick)(void); + extern int get_maxlvt(void); extern void clear_local_APIC(void); extern void connect_bsp_APIC (void); diff -Nru a/include/asm-i386/bugs.h b/include/asm-i386/bugs.h --- a/include/asm-i386/bugs.h Tue Sep 2 19:58:13 2003 +++ b/include/asm-i386/bugs.h Tue Sep 2 19:58:13 2003 @@ -193,11 +193,6 @@ && (boot_cpu_data.x86_mask < 6 || boot_cpu_data.x86_mask == 11)) panic("Kernel compiled for PMMX+, assumes a local APIC without the read-before-write bug!"); #endif - -#ifdef CONFIG_X86_SSE2 - if (!cpu_has_sse2) - panic("Kernel compiled for SSE2, CPU doesn't have it."); -#endif } extern void alternative_instructions(void); diff -Nru a/include/asm-i386/hpet.h b/include/asm-i386/hpet.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/asm-i386/hpet.h Tue Sep 2 19:58:20 2003 @@ -0,0 +1,116 @@ + +#ifndef _I386_HPET_H +#define _I386_HPET_H + +#ifdef CONFIG_HPET_TIMER + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include + +/* + * Documentation on HPET can be found at: + * http://www.intel.com/ial/home/sp/pcmmspec.htm + * ftp://download.intel.com/ial/home/sp/mmts098.pdf + */ + +#define HPET_MMAP_SIZE 1024 + +#define HPET_ID 0x000 +#define HPET_PERIOD 0x004 +#define HPET_CFG 0x010 +#define HPET_STATUS 0x020 +#define HPET_COUNTER 0x0f0 +#define HPET_T0_CFG 0x100 +#define HPET_T0_CMP 0x108 +#define HPET_T0_ROUTE 0x110 +#define HPET_T1_CFG 0x120 +#define HPET_T1_CMP 0x128 +#define HPET_T1_ROUTE 0x130 +#define HPET_T2_CFG 0x140 +#define HPET_T2_CMP 0x148 +#define HPET_T2_ROUTE 0x150 + +#define HPET_ID_VENDOR 0xffff0000 +#define HPET_ID_LEGSUP 0x00008000 +#define HPET_ID_NUMBER 0x00001f00 +#define HPET_ID_REV 0x000000ff + +#define HPET_ID_VENDOR_SHIFT 16 +#define HPET_ID_VENDOR_8086 0x8086 + +#define HPET_CFG_ENABLE 0x001 +#define HPET_CFG_LEGACY 0x002 + +#define HPET_TN_ENABLE 0x004 +#define HPET_TN_PERIODIC 0x008 +#define HPET_TN_PERIODIC_CAP 0x010 +#define HPET_TN_SETVAL 0x040 +#define HPET_TN_32BIT 0x100 + +/* Use our own asm for 64 bit multiply/divide */ +#define ASM_MUL64_REG(eax_out,edx_out,reg_in,eax_in) \ + __asm__ __volatile__("mull %2" \ + :"=a" (eax_out), "=d" (edx_out) \ + :"r" (reg_in), "0" (eax_in)) + +#define ASM_DIV64_REG(eax_out,edx_out,reg_in,eax_in,edx_in) \ + __asm__ __volatile__("divl %2" \ + :"=a" (eax_out), "=d" (edx_out) \ + :"r" (reg_in), "0" (eax_in), "1" (edx_in)) + +#define KERNEL_TICK_USEC (1000000UL/HZ) /* tick value in microsec */ +/* Max HPET Period is 10^8 femto sec as in HPET spec */ +#define HPET_MAX_PERIOD (100000000UL) +/* + * Min HPET period is 10^5 femto sec just for safety. If it is less than this, + * then 32 bit HPET counter wrapsaround in less than 0.5 sec. + */ +#define HPET_MIN_PERIOD (100000UL) + +extern unsigned long hpet_period; /* fsecs / HPET clock */ +extern unsigned long hpet_tick; /* hpet clks count per tick */ +extern unsigned long hpet_address; /* hpet memory map physical address */ + +extern int hpet_rtc_timer_init(void); +extern int hpet_enable(void); +extern int is_hpet_enabled(void); +extern int is_hpet_capable(void); +extern int hpet_readl(unsigned long a); +extern void hpet_writel(unsigned long d, unsigned long a); + +#ifdef CONFIG_RTC +#define CONFIG_HPET_EMULATE_RTC 1 +extern int hpet_mask_rtc_irq_bit(unsigned long bit_mask); +extern int hpet_set_rtc_irq_bit(unsigned long bit_mask); +extern int hpet_set_alarm_time(unsigned char hrs, unsigned char min, unsigned char sec); +extern int hpet_set_periodic_freq(unsigned long freq); +extern int hpet_rtc_dropped_irq(void); +extern int hpet_rtc_timer_init(void); +extern irqreturn_t hpet_rtc_interrupt(int irq, void *dev_id, struct pt_regs *regs); +#endif /* CONFIG_RTC */ +#endif /* CONFIG_HPET_TIMER */ +#endif /* _I386_HPET_H */ diff -Nru a/include/asm-i386/i387.h b/include/asm-i386/i387.h --- a/include/asm-i386/i387.h Tue Sep 2 19:58:18 2003 +++ b/include/asm-i386/i387.h Tue Sep 2 19:58:18 2003 @@ -26,7 +26,9 @@ extern void kernel_fpu_begin(void); #define kernel_fpu_end() do { stts(); preempt_enable(); } while(0) - +/* + * These must be called with preempt disabled + */ static inline void __save_init_fpu( struct task_struct *tsk ) { if ( cpu_has_fxsr ) { @@ -39,19 +41,12 @@ tsk->thread_info->status &= ~TS_USEDFPU; } -static inline void save_init_fpu( struct task_struct *tsk ) -{ - __save_init_fpu(tsk); - stts(); -} - - -#define unlazy_fpu( tsk ) do { \ +#define __unlazy_fpu( tsk ) do { \ if ((tsk)->thread_info->status & TS_USEDFPU) \ save_init_fpu( tsk ); \ } while (0) -#define clear_fpu( tsk ) \ +#define __clear_fpu( tsk ) \ do { \ if ((tsk)->thread_info->status & TS_USEDFPU) { \ asm volatile("fwait"); \ @@ -60,6 +55,30 @@ } \ } while (0) + +/* + * These disable preemption on their own and are safe + */ +static inline void save_init_fpu( struct task_struct *tsk ) +{ + preempt_disable(); + __save_init_fpu(tsk); + stts(); + preempt_enable(); +} + +#define unlazy_fpu( tsk ) do { \ + preempt_disable(); \ + __unlazy_fpu(tsk); \ + preempt_enable(); \ +} while (0) + +#define clear_fpu( tsk ) do { \ + preempt_disable(); \ + __clear_fpu( tsk ); \ + preempt_enable(); \ +} while (0) + \ /* * FPU state interaction... */ diff -Nru a/include/asm-i386/processor.h b/include/asm-i386/processor.h --- a/include/asm-i386/processor.h Tue Sep 2 19:58:12 2003 +++ b/include/asm-i386/processor.h Tue Sep 2 19:58:12 2003 @@ -578,6 +578,8 @@ #define ARCH_HAS_PREFETCH extern inline void prefetch(const void *x) { + if (cpu_data[0].x86_vendor == X86_VENDOR_AMD) + return; /* Some athlons fault if the address is bad */ alternative_input(ASM_NOP4, "prefetchnta (%1)", X86_FEATURE_XMM, diff -Nru a/include/asm-i386/smp.h b/include/asm-i386/smp.h --- a/include/asm-i386/smp.h Tue Sep 2 19:58:16 2003 +++ b/include/asm-i386/smp.h Tue Sep 2 19:58:16 2003 @@ -32,7 +32,6 @@ */ extern void smp_alloc_memory(void); -extern physid_mask_t phys_cpu_present_map; extern int pic_mode; extern int smp_num_siblings; extern int cpu_sibling_map[]; diff -Nru a/include/asm-i386/timer.h b/include/asm-i386/timer.h --- a/include/asm-i386/timer.h Tue Sep 2 19:58:14 2003 +++ b/include/asm-i386/timer.h Tue Sep 2 19:58:14 2003 @@ -38,4 +38,8 @@ extern struct timer_opts timer_cyclone; #endif +#ifdef CONFIG_HPET_TIMER +extern struct timer_opts timer_hpet; +#endif + #endif diff -Nru a/include/asm-ia64/hw_irq.h b/include/asm-ia64/hw_irq.h --- a/include/asm-ia64/hw_irq.h Tue Sep 2 19:58:15 2003 +++ b/include/asm-ia64/hw_irq.h Tue Sep 2 19:58:15 2003 @@ -39,9 +39,9 @@ * Vectors 0x10-0x1f are used for low priority interrupts, e.g. CMCI. */ #define IA64_CPEP_VECTOR 0x1c /* corrected platform error polling vector */ -#define IA64_CMCP_VECTOR 0x1d /* correctable machine-check polling vector */ +#define IA64_CMCP_VECTOR 0x1d /* corrected machine-check polling vector */ #define IA64_CPE_VECTOR 0x1e /* corrected platform error interrupt vector */ -#define IA64_CMC_VECTOR 0x1f /* correctable machine-check interrupt vector */ +#define IA64_CMC_VECTOR 0x1f /* corrected machine-check interrupt vector */ /* * Vectors 0x20-0x2f are reserved for legacy ISA IRQs. */ diff -Nru a/include/asm-ia64/pci.h b/include/asm-ia64/pci.h --- a/include/asm-ia64/pci.h Tue Sep 2 19:58:19 2003 +++ b/include/asm-ia64/pci.h Tue Sep 2 19:58:19 2003 @@ -74,7 +74,7 @@ #define pci_dac_dma_supported(pci_dev, mask) (1) #define pci_dac_page_to_dma(dev,pg,off,dir) ((dma_addr_t) page_to_bus(pg) + (off)) #define pci_dac_dma_to_page(dev,dma_addr) (virt_to_page(bus_to_virt(dma_addr))) -#define pci_dac_dma_to_offset(dev,dma_addr) ((dma_addr) & ~PAGE_MASK) +#define pci_dac_dma_to_offset(dev,dma_addr) offset_in_page(dma_addr) #define pci_dac_dma_sync_single(dev,dma_addr,len,dir) do { mb(); } while (0) #define sg_dma_len(sg) ((sg)->dma_length) diff -Nru a/include/asm-ia64/unistd.h b/include/asm-ia64/unistd.h --- a/include/asm-ia64/unistd.h Tue Sep 2 19:58:13 2003 +++ b/include/asm-ia64/unistd.h Tue Sep 2 19:58:13 2003 @@ -248,6 +248,7 @@ #define __NR_sys_clock_nanosleep 1256 #define __NR_sys_fstatfs64 1257 #define __NR_sys_statfs64 1258 +#define __NR_fadvises64_64 1259 #ifdef __KERNEL__ diff -Nru a/include/asm-m68k/local.h b/include/asm-m68k/local.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/asm-m68k/local.h Tue Sep 2 19:58:20 2003 @@ -0,0 +1,6 @@ +#ifndef _ASM_M68K_LOCAL_H +#define _ASM_M68K_LOCAL_H + +#include + +#endif /* _ASM_M68K_LOCAL_H */ diff -Nru a/include/asm-m68k/sections.h b/include/asm-m68k/sections.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/asm-m68k/sections.h Tue Sep 2 19:58:20 2003 @@ -0,0 +1,6 @@ +#ifndef _ASM_M68K_SECTIONS_H +#define _ASM_M68K_SECTIONS_H + +#include + +#endif /* _ASM_M68K_SECTIONS_H */ diff -Nru a/include/asm-m68k/system.h b/include/asm-m68k/system.h --- a/include/asm-m68k/system.h Tue Sep 2 19:58:17 2003 +++ b/include/asm-m68k/system.h Tue Sep 2 19:58:17 2003 @@ -36,9 +36,12 @@ #define switch_to(prev,next,last) do { \ register void *_prev __asm__ ("a0") = (prev); \ register void *_next __asm__ ("a1") = (next); \ + register void *_last __asm__ ("d1"); \ __asm__ __volatile__("jbsr resume" \ - : : "a" (_prev), "a" (_next) \ - : "d0", "d1", "d2", "d3", "d4", "d5", "a0", "a1"); \ + : "=a" (_prev), "=a" (_next), "=d" (_last) \ + : "0" (_prev), "1" (_next) \ + : "d0", "d2", "d3", "d4", "d5"); \ + (last) = _last; \ } while (0) diff -Nru a/include/asm-m68knommu/irq.h b/include/asm-m68knommu/irq.h --- a/include/asm-m68knommu/irq.h Tue Sep 2 19:58:16 2003 +++ b/include/asm-m68knommu/irq.h Tue Sep 2 19:58:16 2003 @@ -2,6 +2,7 @@ #define _M68K_IRQ_H_ #include +#include #include #ifdef CONFIG_COLDFIRE @@ -62,7 +63,7 @@ extern void (*mach_disable_irq)(unsigned int); extern int sys_request_irq(unsigned int, - void (*)(int, void *, struct pt_regs *), + irqreturn_t (*)(int, void *, struct pt_regs *), unsigned long, const char *, void *); extern void sys_free_irq(unsigned int, void *); @@ -91,7 +92,7 @@ * interrupt source (if it supports chaining). */ typedef struct irq_node { - void (*handler)(int, void *, struct pt_regs *); + irqreturn_t (*handler)(int, void *, struct pt_regs *); unsigned long flags; void *dev_id; const char *devname; @@ -102,7 +103,7 @@ * This structure has only 4 elements for speed reasons */ typedef struct irq_handler { - void (*handler)(int, void *, struct pt_regs *); + irqreturn_t (*handler)(int, void *, struct pt_regs *); unsigned long flags; void *dev_id; const char *devname; diff -Nru a/include/asm-m68knommu/local.h b/include/asm-m68knommu/local.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/asm-m68knommu/local.h Tue Sep 2 19:58:20 2003 @@ -0,0 +1,6 @@ +#ifndef __M68KNOMMU_LOCAL_H +#define __M68KNOMMU_LOCAL_H + +#include + +#endif /* __M68KNOMMU_LOCAL_H */ diff -Nru a/include/asm-m68knommu/sections.h b/include/asm-m68knommu/sections.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/asm-m68knommu/sections.h Tue Sep 2 19:58:20 2003 @@ -0,0 +1,7 @@ +#ifndef _M68KNOMMU_SECTIONS_H +#define _M68KNOMMU_SECTIONS_H + +/* nothing to see, move along */ +#include + +#endif diff -Nru a/include/asm-ppc/cpm_8260.h b/include/asm-ppc/cpm_8260.h --- a/include/asm-ppc/cpm_8260.h Tue Sep 2 19:58:15 2003 +++ b/include/asm-ppc/cpm_8260.h Tue Sep 2 19:58:15 2003 @@ -195,7 +195,7 @@ /* SMC uart mode register (Internal memory map). */ -#define SMCMR_REN ((ushort)0x0001) +#define SMCMR_REN ((ushort)0x0001) #define SMCMR_TEN ((ushort)0x0002) #define SMCMR_DM ((ushort)0x000c) #define SMCMR_SM_GCI ((ushort)0x0000) @@ -212,10 +212,12 @@ /* SMC Event and Mask register. */ -#define SMCM_TXE ((unsigned char)0x10) -#define SMCM_BSY ((unsigned char)0x04) -#define SMCM_TX ((unsigned char)0x02) -#define SMCM_RX ((unsigned char)0x01) +#define SMCM_BRKE ((unsigned char)0x40) /* When in UART Mode */ +#define SMCM_BRK ((unsigned char)0x10) /* When in UART Mode */ +#define SMCM_TXE ((unsigned char)0x10) +#define SMCM_BSY ((unsigned char)0x04) +#define SMCM_TX ((unsigned char)0x02) +#define SMCM_RX ((unsigned char)0x01) /* Baud rate generators. */ @@ -314,10 +316,10 @@ /* SCC Event and Mask register. */ -#define SCCM_TXE ((unsigned char)0x10) -#define SCCM_BSY ((unsigned char)0x04) -#define SCCM_TX ((unsigned char)0x02) -#define SCCM_RX ((unsigned char)0x01) +#define SCCM_TXE ((unsigned char)0x10) +#define SCCM_BSY ((unsigned char)0x04) +#define SCCM_TX ((unsigned char)0x02) +#define SCCM_RX ((unsigned char)0x01) typedef struct scc_param { ushort scc_rbase; /* Rx Buffer descriptor base address */ diff -Nru a/include/asm-ppc/macio.h b/include/asm-ppc/macio.h --- a/include/asm-ppc/macio.h Tue Sep 2 19:58:13 2003 +++ b/include/asm-ppc/macio.h Tue Sep 2 19:58:13 2003 @@ -42,6 +42,9 @@ #define to_macio_device(d) container_of(d, struct macio_dev, ofdev.dev) #define of_to_macio_device(d) container_of(d, struct macio_dev, ofdev) +extern struct macio_dev *macio_dev_get(struct macio_dev *dev); +extern void macio_dev_put(struct macio_dev *dev); + /* * A driver for a mac-io chip based device */ @@ -54,8 +57,8 @@ int (*probe)(struct macio_dev* dev, const struct of_match *match); int (*remove)(struct macio_dev* dev); - int (*suspend)(struct macio_dev* dev, u32 state, u32 level); - int (*resume)(struct macio_dev* dev, u32 level); + int (*suspend)(struct macio_dev* dev, u32 state); + int (*resume)(struct macio_dev* dev); int (*shutdown)(struct macio_dev* dev); struct device_driver driver; diff -Nru a/include/asm-ppc/of_device.h b/include/asm-ppc/of_device.h --- a/include/asm-ppc/of_device.h Tue Sep 2 19:58:16 2003 +++ b/include/asm-ppc/of_device.h Tue Sep 2 19:58:16 2003 @@ -39,6 +39,9 @@ extern const struct of_match *of_match_device( const struct of_match *matches, const struct of_device *dev); +extern struct of_device *of_dev_get(struct of_device *dev); +extern void of_dev_put(struct of_device *dev); + /* * An of_platform_driver driver is attached to a basic of_device on * the "platform bus" (of_platform_bus_type) @@ -52,8 +55,8 @@ int (*probe)(struct of_device* dev, const struct of_match *match); int (*remove)(struct of_device* dev); - int (*suspend)(struct of_device* dev, u32 state, u32 level); - int (*resume)(struct of_device* dev, u32 level); + int (*suspend)(struct of_device* dev, u32 state); + int (*resume)(struct of_device* dev); int (*shutdown)(struct of_device* dev); struct device_driver driver; @@ -65,6 +68,7 @@ extern int of_device_register(struct of_device *ofdev); extern void of_device_unregister(struct of_device *ofdev); extern struct of_device *of_platform_device_create(struct device_node *np, const char *bus_id); +extern void of_release_dev(struct device *dev); #endif /* __OF_DEVICE_H__ */ diff -Nru a/include/asm-ppc/processor.h b/include/asm-ppc/processor.h --- a/include/asm-ppc/processor.h Tue Sep 2 19:58:12 2003 +++ b/include/asm-ppc/processor.h Tue Sep 2 19:58:12 2003 @@ -654,6 +654,7 @@ */ #define EISA_bus 0 #define MCA_bus 0 +#define MCA_bus__is_a_macro /* Lazy FPU handling on uni-processor */ extern struct task_struct *last_task_used_math; diff -Nru a/include/asm-ppc/prom.h b/include/asm-ppc/prom.h --- a/include/asm-ppc/prom.h Tue Sep 2 19:58:17 2003 +++ b/include/asm-ppc/prom.h Tue Sep 2 19:58:17 2003 @@ -62,18 +62,35 @@ struct prom_args; typedef void (*prom_entry)(struct prom_args *); -/* Prototypes */ -extern void abort(void); -extern unsigned long prom_init(int, int, prom_entry); -extern void prom_print(const char *msg); -extern void relocate_nodes(void); -extern void finish_device_tree(void); +/* OBSOLETE: Old style node lookup */ extern struct device_node *find_devices(const char *name); extern struct device_node *find_type_devices(const char *type); extern struct device_node *find_path_device(const char *path); extern struct device_node *find_compatible_devices(const char *type, const char *compat); extern struct device_node *find_all_nodes(void); + +/* New style node lookup */ +extern struct device_node *of_find_node_by_name(struct device_node *from, + const char *name); +extern struct device_node *of_find_node_by_type(struct device_node *from, + const char *type); +extern struct device_node *of_find_compatible_node(struct device_node *from, + const char *type, const char *compat); +extern struct device_node *of_find_node_by_path(const char *path); +extern struct device_node *of_find_all_nodes(struct device_node *prev); +extern struct device_node *of_get_parent(const struct device_node *node); +extern struct device_node *of_get_next_child(const struct device_node *node, + struct device_node *prev); +extern struct device_node *of_node_get(struct device_node *node); +extern void of_node_put(struct device_node *node); + +/* Other Prototypes */ +extern void abort(void); +extern unsigned long prom_init(int, int, prom_entry); +extern void prom_print(const char *msg); +extern void relocate_nodes(void); +extern void finish_device_tree(void); extern int device_is_compatible(struct device_node *device, const char *); extern int machine_is_compatible(const char *compat); extern unsigned char *get_property(struct device_node *node, const char *name, diff -Nru a/include/asm-ppc/unistd.h b/include/asm-ppc/unistd.h --- a/include/asm-ppc/unistd.h Tue Sep 2 19:58:13 2003 +++ b/include/asm-ppc/unistd.h Tue Sep 2 19:58:13 2003 @@ -258,8 +258,9 @@ #define __NR_utimes 251 #define __NR_statfs64 252 #define __NR_fstatfs64 253 +#define __NR_fadvise64_64 254 -#define __NR_syscalls 254 +#define __NR_syscalls 255 #define __NR(n) #n diff -Nru a/include/asm-sparc/pci.h b/include/asm-sparc/pci.h --- a/include/asm-sparc/pci.h Tue Sep 2 19:58:17 2003 +++ b/include/asm-sparc/pci.h Tue Sep 2 19:58:17 2003 @@ -78,6 +78,14 @@ #define pci_unmap_len_set(PTR, LEN_NAME, VAL) \ (((PTR)->LEN_NAME) = (VAL)) +/* + * Same as above, only with pages instead of mapped addresses. + */ +extern dma_addr_t pci_map_page(struct pci_dev *hwdev, struct page *page, + unsigned long offset, size_t size, int direction); +extern void pci_unmap_page(struct pci_dev *hwdev, + dma_addr_t dma_address, size_t size, int direction); + /* Map a set of buffers described by scatterlist in streaming * mode for DMA. This is the scather-gather version of the * above pci_map_single interface. Here the scatter gather list diff -Nru a/include/asm-sparc/smp.h b/include/asm-sparc/smp.h --- a/include/asm-sparc/smp.h Tue Sep 2 19:58:14 2003 +++ b/include/asm-sparc/smp.h Tue Sep 2 19:58:14 2003 @@ -8,11 +8,13 @@ #include #include -#include #include #include #ifndef __ASSEMBLY__ + +#include + /* PROM provided per-processor information we need * to start them all up. */ diff -Nru a/include/asm-sparc/unistd.h b/include/asm-sparc/unistd.h --- a/include/asm-sparc/unistd.h Tue Sep 2 19:58:13 2003 +++ b/include/asm-sparc/unistd.h Tue Sep 2 19:58:13 2003 @@ -282,10 +282,11 @@ #define __NR_timer_gettime 263 #define __NR_timer_getoverrun 264 #define __NR_timer_delete 265 -/* WARNING: You MAY NOT add syscall numbers larger than 265, since +#define __NR_timer_create 266 +/* WARNING: You MAY NOT add syscall numbers larger than 266, since * all of the syscall tables in the Sparc kernel are - * sized to have 266 entries (starting at zero). Therefore - * find a free slot in the 0-265 range. + * sized to have 267 entries (starting at zero). Therefore + * find a free slot in the 0-266 range. */ #define _syscall0(type,name) \ diff -Nru a/include/asm-sparc64/siginfo.h b/include/asm-sparc64/siginfo.h --- a/include/asm-sparc64/siginfo.h Tue Sep 2 19:58:17 2003 +++ b/include/asm-sparc64/siginfo.h Tue Sep 2 19:58:17 2003 @@ -83,7 +83,7 @@ #ifdef __KERNEL__ typedef struct sigevent32 { - sigval_t sigev_value; + sigval_t32 sigev_value; int sigev_signo; int sigev_notify; union { diff -Nru a/include/asm-sparc64/unistd.h b/include/asm-sparc64/unistd.h --- a/include/asm-sparc64/unistd.h Tue Sep 2 19:58:13 2003 +++ b/include/asm-sparc64/unistd.h Tue Sep 2 19:58:13 2003 @@ -284,10 +284,11 @@ #define __NR_timer_gettime 263 #define __NR_timer_getoverrun 264 #define __NR_timer_delete 265 -/* WARNING: You MAY NOT add syscall numbers larger than 265, since +#define __NR_timer_create 266 +/* WARNING: You MAY NOT add syscall numbers larger than 266, since * all of the syscall tables in the Sparc kernel are - * sized to have 266 entries (starting at zero). Therefore - * find a free slot in the 0-265 range. + * sized to have 267 entries (starting at zero). Therefore + * find a free slot in the 0-266 range. */ #define _syscall0(type,name) \ diff -Nru a/include/asm-x86_64/bitops.h b/include/asm-x86_64/bitops.h --- a/include/asm-x86_64/bitops.h Tue Sep 2 19:58:15 2003 +++ b/include/asm-x86_64/bitops.h Tue Sep 2 19:58:15 2003 @@ -466,7 +466,7 @@ __asm__("bsfl %1,%0\n\t" "cmovzl %2,%0" - : "=r" (r) : "g" (x), "r" (32)); + : "=r" (r) : "g" (x), "r" (-1)); return r+1; } diff -Nru a/include/asm-x86_64/ia32.h b/include/asm-x86_64/ia32.h --- a/include/asm-x86_64/ia32.h Tue Sep 2 19:58:18 2003 +++ b/include/asm-x86_64/ia32.h Tue Sep 2 19:58:18 2003 @@ -160,7 +160,6 @@ char f_fpack[6]; }; -#define IA32_PAGE_OFFSET 0xffffe000 #define IA32_STACK_TOP IA32_PAGE_OFFSET #ifdef __KERNEL__ diff -Nru a/include/asm-x86_64/mpspec.h b/include/asm-x86_64/mpspec.h --- a/include/asm-x86_64/mpspec.h Tue Sep 2 19:58:15 2003 +++ b/include/asm-x86_64/mpspec.h Tue Sep 2 19:58:15 2003 @@ -169,7 +169,6 @@ extern cpumask_t mp_bus_to_cpumask [MAX_MP_BUSSES]; extern unsigned int boot_cpu_physical_apicid; -extern cpumask_t phys_cpu_present_map; extern int smp_found_config; extern void find_smp_config (void); extern void get_smp_config (void); @@ -197,6 +196,50 @@ extern void mp_config_ioapic_for_sci(int irq); extern int using_apic_timer; + +#define PHYSID_ARRAY_SIZE BITS_TO_LONGS(MAX_APICS) + +struct physid_mask +{ + unsigned long mask[PHYSID_ARRAY_SIZE]; +}; + +typedef struct physid_mask physid_mask_t; + +#define physid_set(physid, map) set_bit(physid, (map).mask) +#define physid_clear(physid, map) clear_bit(physid, (map).mask) +#define physid_isset(physid, map) test_bit(physid, (map).mask) +#define physid_test_and_set(physid, map) test_and_set_bit(physid, (map).mask) + +#define physids_and(dst, src1, src2) bitmap_and((dst).mask, (src1).mask, (src2).mask, MAX_APICS) +#define physids_or(dst, src1, src2) bitmap_or((dst).mask, (src1).mask, (src2).mask, MAX_APICS) +#define physids_clear(map) bitmap_clear((map).mask, MAX_APICS) +#define physids_complement(map) bitmap_complement((map).mask, MAX_APICS) +#define physids_empty(map) bitmap_empty((map).mask, MAX_APICS) +#define physids_equal(map1, map2) bitmap_equal((map1).mask, (map2).mask, MAX_APICS) +#define physids_weight(map) bitmap_weight((map).mask, MAX_APICS) +#define physids_shift_right(d, s, n) bitmap_shift_right((d).mask, (s).mask, n, MAX_APICS) +#define physids_shift_left(d, s, n) bitmap_shift_left((d).mask, (s).mask, n, MAX_APICS) +#define physids_coerce(map) ((map).mask[0]) + +#define physids_promote(physids) \ + ({ \ + physid_mask_t __physid_mask = PHYSID_MASK_NONE; \ + __physid_mask.mask[0] = physids; \ + __physid_mask; \ + }) + +#define physid_mask_of_physid(physid) \ + ({ \ + physid_mask_t __physid_mask = PHYSID_MASK_NONE; \ + physid_set(physid, __physid_mask); \ + __physid_mask; \ + }) + +#define PHYSID_MASK_ALL { {[0 ... PHYSID_ARRAY_SIZE-1] = ~0UL} } +#define PHYSID_MASK_NONE { {[0 ... PHYSID_ARRAY_SIZE-1] = 0UL} } + +extern physid_mask_t phys_cpu_present_map; #endif diff -Nru a/include/asm-x86_64/percpu.h b/include/asm-x86_64/percpu.h --- a/include/asm-x86_64/percpu.h Tue Sep 2 19:58:17 2003 +++ b/include/asm-x86_64/percpu.h Tue Sep 2 19:58:17 2003 @@ -31,6 +31,9 @@ memcpy((pcpudst)+__per_cpu_offset(__i), \ (src), (size)); \ } while (0) + +extern void setup_per_cpu_areas(void); + #else /* ! SMP */ #define DEFINE_PER_CPU(type, name) \ @@ -45,7 +48,5 @@ #define EXPORT_PER_CPU_SYMBOL(var) EXPORT_SYMBOL(per_cpu__##var) #define EXPORT_PER_CPU_SYMBOL_GPL(var) EXPORT_SYMBOL_GPL(per_cpu__##var) - -extern void setup_per_cpu_areas(void); #endif /* _ASM_X8664_PERCPU_H_ */ diff -Nru a/include/asm-x86_64/processor.h b/include/asm-x86_64/processor.h --- a/include/asm-x86_64/processor.h Tue Sep 2 19:58:19 2003 +++ b/include/asm-x86_64/processor.h Tue Sep 2 19:58:19 2003 @@ -18,6 +18,7 @@ #include #include #include +#include #define TF_MASK 0x00000100 #define IF_MASK 0x00000200 @@ -172,7 +173,8 @@ /* This decides where the kernel will search for a free chunk of vm * space during mmap's. */ -#define TASK_UNMAPPED_32 0xa0000000 +#define IA32_PAGE_OFFSET ((current->personality & ADDR_LIMIT_3GB) ? 0xc0000000 : 0xFFFFe000) +#define TASK_UNMAPPED_32 (IA32_PAGE_OFFSET / 3) #define TASK_UNMAPPED_64 PAGE_ALIGN(TASK_SIZE/3) #define TASK_UNMAPPED_BASE \ (test_thread_flag(TIF_IA32) ? TASK_UNMAPPED_32 : TASK_UNMAPPED_64) @@ -225,7 +227,6 @@ * 8 bytes, for an extra "long" of ~0UL */ unsigned long io_bitmap[IO_BITMAP_LONGS + 1]; - u32 __cacheline_filler[4]; /* size is 0x100 */ } __attribute__((packed)) ____cacheline_aligned; struct thread_struct { diff -Nru a/include/asm-x86_64/smp.h b/include/asm-x86_64/smp.h --- a/include/asm-x86_64/smp.h Tue Sep 2 19:58:12 2003 +++ b/include/asm-x86_64/smp.h Tue Sep 2 19:58:12 2003 @@ -36,7 +36,6 @@ */ extern void smp_alloc_memory(void); -extern cpumask_t phys_cpu_present_map; extern cpumask_t cpu_online_map; extern volatile unsigned long smp_invalidate_needed; extern int pic_mode; diff -Nru a/include/asm-x86_64/suspend.h b/include/asm-x86_64/suspend.h --- a/include/asm-x86_64/suspend.h Tue Sep 2 19:58:16 2003 +++ b/include/asm-x86_64/suspend.h Tue Sep 2 19:58:16 2003 @@ -44,7 +44,7 @@ :"r" ((thread)->debugreg##register)) extern void fix_processor_context(void); -extern void do_magic(int resume); +extern int do_magic(int resume); #ifdef CONFIG_ACPI_SLEEP extern unsigned long saved_eip; diff -Nru a/include/asm-x86_64/topology.h b/include/asm-x86_64/topology.h --- a/include/asm-x86_64/topology.h Tue Sep 2 19:58:17 2003 +++ b/include/asm-x86_64/topology.h Tue Sep 2 19:58:17 2003 @@ -10,21 +10,18 @@ /* Map the K8 CPU local memory controllers to a simple 1:1 CPU:NODE topology */ extern int fake_node; -extern cpumask_t cpu_online_map; +extern unsigned long cpu_online_map; #define cpu_to_node(cpu) (fake_node ? 0 : (cpu)) #define memblk_to_node(memblk) (fake_node ? 0 : (memblk)) #define parent_node(node) (node) #define node_to_first_cpu(node) (fake_node ? 0 : (node)) -#define node_to_cpu_mask(node) (fake_node ? cpu_online_map : cpumask_of_cpu(node)) +#define node_to_cpu_mask(node) (fake_node ? cpu_online_map : (1UL << (node))) #define node_to_memblk(node) (node) -static inline cpumask_t pcibus_to_cpumask(int bus) +static inline unsigned long pcibus_to_cpumask(int bus) { - cpumask_t ret; - - cpus_and(ret, mp_bus_to_cpumask[bus], cpu_online_map); - return ret; + return mp_bus_to_cpumask[bus] & cpu_online_map; } #define NODE_BALANCE_RATE 30 /* CHECKME */ diff -Nru a/include/linux/blkdev.h b/include/linux/blkdev.h --- a/include/linux/blkdev.h Tue Sep 2 19:58:14 2003 +++ b/include/linux/blkdev.h Tue Sep 2 19:58:14 2003 @@ -243,6 +243,7 @@ struct bio_vec; typedef int (merge_bvec_fn) (request_queue_t *, struct bio *, struct bio_vec *); +typedef void (activity_fn) (void *data, int rw); enum blk_queue_state { Queue_down, @@ -283,6 +284,7 @@ prep_rq_fn *prep_rq_fn; unplug_fn *unplug_fn; merge_bvec_fn *merge_bvec_fn; + activity_fn *activity_fn; /* * Auto-unplugging state @@ -300,6 +302,8 @@ */ void *queuedata; + void *activity_data; + /* * queue needs bounce pages for pages above this limit */ @@ -504,6 +508,7 @@ extern void blk_stop_queue(request_queue_t *q); extern void __blk_stop_queue(request_queue_t *q); extern void blk_run_queue(request_queue_t *q); +extern void blk_queue_activity_fn(request_queue_t *, activity_fn *, void *); static inline request_queue_t *bdev_get_queue(struct block_device *bdev) { diff -Nru a/include/linux/cyclomx.h b/include/linux/cyclomx.h --- a/include/linux/cyclomx.h Tue Sep 2 19:58:16 2003 +++ b/include/linux/cyclomx.h Tue Sep 2 19:58:16 2003 @@ -52,7 +52,7 @@ char in_isr; /* interrupt-in-service flag */ char buff_int_mode_unbusy; /* flag for carrying out dev_tint */ wait_queue_head_t wait_stats; /* to wait for the STATS indication */ - u32 mbox; /* -> mailbox */ + void *mbox; /* -> mailbox */ void (*isr)(struct cycx_device* card); /* interrupt service routine */ int (*exec)(struct cycx_device* card, void* u_cmd, void* u_data); union { diff -Nru a/include/linux/cycx_cfm.h b/include/linux/cycx_cfm.h --- a/include/linux/cycx_cfm.h Tue Sep 2 19:58:13 2003 +++ b/include/linux/cycx_cfm.h Tue Sep 2 19:58:13 2003 @@ -90,7 +90,7 @@ unsigned short reserved[6]; char descr[CFM_DESCR_LEN]; struct cycx_fw_info info; - unsigned char image[1]; + unsigned char image[0]; }; struct cycx_fw_header { diff -Nru a/include/linux/cycx_drv.h b/include/linux/cycx_drv.h --- a/include/linux/cycx_drv.h Tue Sep 2 19:58:15 2003 +++ b/include/linux/cycx_drv.h Tue Sep 2 19:58:15 2003 @@ -48,7 +48,7 @@ struct cycx_hw { u32 fwid; int irq; - u32 dpmbase; + void *dpmbase; u32 dpmsize; u32 reserved[5]; }; @@ -58,7 +58,7 @@ extern int cycx_down(struct cycx_hw *hw); extern int cycx_peek(struct cycx_hw *hw, u32 addr, void *buf, u32 len); extern int cycx_poke(struct cycx_hw *hw, u32 addr, void *buf, u32 len); -extern int cycx_exec(u32 addr); +extern int cycx_exec(void *addr); extern void cycx_inten(struct cycx_hw *hw); extern void cycx_intr(struct cycx_hw *hw); diff -Nru a/include/linux/ethtool.h b/include/linux/ethtool.h --- a/include/linux/ethtool.h Tue Sep 2 19:58:14 2003 +++ b/include/linux/ethtool.h Tue Sep 2 19:58:14 2003 @@ -255,8 +255,11 @@ /* Some generic methods drivers may use in their ethtool_ops */ u32 ethtool_op_get_link(struct net_device *dev); u32 ethtool_op_get_tx_csum(struct net_device *dev); +int ethtool_op_set_tx_csum(struct net_device *dev, u32 data); u32 ethtool_op_get_sg(struct net_device *dev); int ethtool_op_set_sg(struct net_device *dev, u32 data); +u32 ethtool_op_get_tso(struct net_device *dev); +int ethtool_op_set_tso(struct net_device *dev, u32 data); /** * ðtool_ops - Alter and report network device settings @@ -284,6 +287,8 @@ * set_tx_csum: Turn transmit checksums on or off * get_sg: Report whether scatter-gather is enabled * set_sg: Turn scatter-gather on or off + * get_tso: Report whether TCP segmentation offload is enabled + * set_tso: Turn TCP segmentation offload on or off * self_test: Run specified self-tests * get_strings: Return a set of strings that describe the requested objects * phys_id: Identify the device @@ -337,6 +342,8 @@ int (*set_tx_csum)(struct net_device *, u32); u32 (*get_sg)(struct net_device *); int (*set_sg)(struct net_device *, u32); + u32 (*get_tso)(struct net_device *); + int (*set_tso)(struct net_device *, u32); int (*self_test_count)(struct net_device *); void (*self_test)(struct net_device *, struct ethtool_test *, u64 *); void (*get_strings)(struct net_device *, u32 stringset, u8 *); diff -Nru a/include/linux/fs.h b/include/linux/fs.h --- a/include/linux/fs.h Tue Sep 2 19:58:14 2003 +++ b/include/linux/fs.h Tue Sep 2 19:58:14 2003 @@ -336,10 +336,8 @@ }; struct block_device { - struct list_head bd_hash; - atomic_t bd_count; - struct inode * bd_inode; dev_t bd_dev; /* not a kdev_t - it's a search key */ + struct inode * bd_inode; /* will die */ int bd_openers; struct semaphore bd_sem; /* open/close mutex */ struct list_head bd_inodes; @@ -347,10 +345,11 @@ int bd_holders; struct block_device * bd_contains; unsigned bd_block_size; - sector_t bd_offset; + struct hd_struct * bd_part; unsigned bd_part_count; int bd_invalidated; struct gendisk * bd_disk; + struct list_head bd_list; }; /* @@ -468,6 +467,16 @@ #endif } +static inline unsigned iminor(struct inode *inode) +{ + return minor(inode->i_rdev); +} + +static inline unsigned imajor(struct inode *inode) +{ + return major(inode->i_rdev); +} + struct fown_struct { rwlock_t lock; /* protects pid, uid, euid fields */ int pid; /* pid or -pgrp where SIGIO should be sent */ @@ -600,6 +609,10 @@ extern int fcntl_setlk64(struct file *, unsigned int, struct flock64 __user *); #endif +extern void send_sigio(struct fown_struct *fown, int fd, int band); +extern int fcntl_setlease(unsigned int fd, struct file *filp, long arg); +extern int fcntl_getlease(struct file *filp); + /* fs/locks.c */ extern void locks_init_lock(struct file_lock *); extern void locks_copy_lock(struct file_lock *, struct file_lock *); @@ -1176,6 +1189,12 @@ unsigned long invalidate_mapping_pages(struct address_space *mapping, pgoff_t start, pgoff_t end); unsigned long invalidate_inode_pages(struct address_space *mapping); +static inline void invalidate_remote_inode(struct inode *inode) +{ + if (S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) || + S_ISLNK(inode->i_mode)) + invalidate_inode_pages(inode->i_mapping); +} extern void invalidate_inode_pages2(struct address_space *mapping); extern void write_inode_now(struct inode *, int); extern int filemap_fdatawrite(struct address_space *); diff -Nru a/include/linux/genhd.h b/include/linux/genhd.h --- a/include/linux/genhd.h Tue Sep 2 19:58:13 2003 +++ b/include/linux/genhd.h Tue Sep 2 19:58:13 2003 @@ -197,7 +197,7 @@ static inline sector_t get_start_sect(struct block_device *bdev) { - return bdev->bd_offset; + return bdev->bd_contains == bdev ? 0 : bdev->bd_part->start_sect; } static inline sector_t get_capacity(struct gendisk *disk) { diff -Nru a/include/linux/ide.h b/include/linux/ide.h --- a/include/linux/ide.h Tue Sep 2 19:58:15 2003 +++ b/include/linux/ide.h Tue Sep 2 19:58:15 2003 @@ -22,6 +22,7 @@ #include #include #include +#include #define DEBUG_PM @@ -774,6 +775,7 @@ int crc_count; /* crc counter to reduce drive speed */ struct list_head list; struct device gendev; + struct semaphore gendev_rel_sem; /* to deal with device release() */ struct gendisk *disk; } ide_drive_t; @@ -1040,10 +1042,13 @@ unsigned auto_poll : 1; /* supports nop auto-poll */ struct device gendev; + struct semaphore gendev_rel_sem; /* To deal with device release() */ void *hwif_data; /* extra hwif data */ unsigned dma; + + void (*led_act)(void *data, int rw); } ide_hwif_t; /* @@ -1242,21 +1247,6 @@ extern int generic_ide_ioctl(struct block_device *, unsigned, unsigned long); -/* - * IDE modules. - */ -#define IDE_CHIPSET_MODULE 0 /* not supported yet */ -#define IDE_PROBE_MODULE 1 - -typedef int (ide_module_init_proc)(void); - -typedef struct ide_module_s { - int type; - ide_module_init_proc *init; - void *info; - struct ide_module_s *next; -} ide_module_t; - typedef struct ide_devices_s { char name[4]; /* hdX */ unsigned attached : 1; /* native */ @@ -1274,8 +1264,7 @@ */ #ifndef _IDE_C extern ide_hwif_t ide_hwifs[]; /* master data repository */ -extern ide_module_t *ide_chipsets; -extern ide_module_t *ide_probe; +extern int (*ide_probe)(void); extern ide_devices_t *idedisk; extern ide_devices_t *idecd; @@ -1772,8 +1761,6 @@ extern void ide_hwif_release_regions(ide_hwif_t* hwif); extern void ide_unregister (unsigned int index); -extern int export_ide_init_queue(ide_drive_t *); -extern u8 export_probe_for_drive(ide_drive_t *); extern int probe_hwif_init(ide_hwif_t *); static inline void *ide_get_hwifdata (ide_hwif_t * hwif) @@ -1793,6 +1780,24 @@ extern char *ide_xfer_verbose(u8 xfer_rate); extern void ide_toggle_bounce(ide_drive_t *drive, int on); extern int ide_set_xfer_rate(ide_drive_t *drive, u8 rate); + +typedef struct ide_pio_timings_s { + int setup_time; /* Address setup (ns) minimum */ + int active_time; /* Active pulse (ns) minimum */ + int cycle_time; /* Cycle time (ns) minimum = (setup + active + recovery) */ +} ide_pio_timings_t; + +typedef struct ide_pio_data_s { + u8 pio_mode; + u8 use_iordy; + u8 overridden; + u8 blacklisted; + unsigned int cycle_time; +} ide_pio_data_t; + +extern u8 ide_get_best_pio_mode (ide_drive_t *drive, u8 mode_wanted, u8 max_mode, ide_pio_data_t *d); +extern const ide_pio_timings_t ide_pio_timings[6]; + extern spinlock_t ide_lock; extern struct semaphore ide_cfg_sem; diff -Nru a/include/linux/ipv6_route.h b/include/linux/ipv6_route.h --- a/include/linux/ipv6_route.h Tue Sep 2 19:58:14 2003 +++ b/include/linux/ipv6_route.h Tue Sep 2 19:58:14 2003 @@ -24,6 +24,7 @@ #define RTF_CACHE 0x01000000 /* cache entry */ #define RTF_FLOW 0x02000000 /* flow significant route */ #define RTF_POLICY 0x04000000 /* policy route */ +#define RTF_NDISC 0x08000000 /* ndisc route */ #define RTF_LOCAL 0x80000000 diff -Nru a/include/linux/kdev_t.h b/include/linux/kdev_t.h --- a/include/linux/kdev_t.h Tue Sep 2 19:58:18 2003 +++ b/include/linux/kdev_t.h Tue Sep 2 19:58:18 2003 @@ -90,22 +90,7 @@ return dev.value; } -static inline kdev_t val_to_kdev(unsigned int val) -{ - kdev_t dev; - dev.value = val; - return dev; -} - -#define HASHDEV(dev) (kdev_val(dev)) #define NODEV (mk_kdev(0,0)) - -static inline int kdev_same(kdev_t dev1, kdev_t dev2) -{ - return dev1.value == dev2.value; -} - -#define kdev_none(d1) (!kdev_val(d1)) /* Mask off the high bits for now.. */ #define minor(dev) ((dev).value & 0xff) diff -Nru a/include/linux/mmzone.h b/include/linux/mmzone.h --- a/include/linux/mmzone.h Tue Sep 2 19:58:16 2003 +++ b/include/linux/mmzone.h Tue Sep 2 19:58:16 2003 @@ -89,17 +89,24 @@ ZONE_PADDING(_pad2_) - /* - * measure of scanning intensity for this zone. It is calculated - * as exponentially decaying average of the scanning priority - * required to free enough pages in this zone - * (zone_adj_pressure()). + /* + * prev_priority holds the scanning priority for this zone. It is + * defined as the scanning priority at which we achieved our reclaim + * target at the previous try_to_free_pages() or balance_pgdat() + * invokation. * - * 0 --- low pressure + * We use prev_priority as a measure of how much stress page reclaim is + * under - it drives the swappiness decision: whether to unmap mapped + * pages. * - * (DEF_PRIORITY << 10) --- high pressure + * temp_priority is used to remember the scanning priority at which + * this zone was successfully refilled to free_pages == pages_high. + * + * Access to both these fields is quite racy even on uniprocessor. But + * it is expected to average out OK. */ - int pressure; + int temp_priority; + int prev_priority; /* * free areas of different sizes diff -Nru a/include/linux/net.h b/include/linux/net.h --- a/include/linux/net.h Tue Sep 2 19:58:15 2003 +++ b/include/linux/net.h Tue Sep 2 19:58:15 2003 @@ -20,6 +20,7 @@ #include #include +#include struct poll_table_struct; struct inode; @@ -243,6 +244,8 @@ }; #endif +#define MODULE_ALIAS_NETPROTO(proto) \ + MODULE_ALIAS("net-pf-" __stringify(proto)) #endif /* __KERNEL__ */ #endif /* _LINUX_NET_H */ diff -Nru a/include/linux/netdevice.h b/include/linux/netdevice.h --- a/include/linux/netdevice.h Tue Sep 2 19:58:19 2003 +++ b/include/linux/netdevice.h Tue Sep 2 19:58:19 2003 @@ -168,9 +168,9 @@ unsigned fastroute_deferred_out; unsigned fastroute_latency_reduction; unsigned cpu_collision; -} ____cacheline_aligned; +}; -extern struct netif_rx_stats netdev_rx_stat[]; +DECLARE_PER_CPU(struct netif_rx_stats, netdev_rx_stat); /* @@ -830,6 +830,38 @@ smp_mb__before_clear_bit(); clear_bit(__LINK_STATE_RX_SCHED, &dev->state); local_irq_restore(flags); +} + +static inline void netif_poll_disable(struct net_device *dev) +{ + while (test_and_set_bit(__LINK_STATE_RX_SCHED, &dev->state)) { + /* No hurry. */ + current->state = TASK_INTERRUPTIBLE; + schedule_timeout(1); + } +} + +static inline void netif_poll_enable(struct net_device *dev) +{ + clear_bit(__LINK_STATE_RX_SCHED, &dev->state); +} + +/* same as netif_rx_complete, except that local_irq_save(flags) + * has already been issued + */ +static inline void __netif_rx_complete(struct net_device *dev) +{ + if (!test_bit(__LINK_STATE_RX_SCHED, &dev->state)) BUG(); + list_del(&dev->poll_list); + smp_mb__before_clear_bit(); + clear_bit(__LINK_STATE_RX_SCHED, &dev->state); +} + +static inline void netif_tx_disable(struct net_device *dev) +{ + spin_lock_bh(&dev->xmit_lock); + netif_stop_queue(dev); + spin_unlock_bh(&dev->xmit_lock); } /* These functions live elsewhere (drivers/net/net_init.c, but related) */ diff -Nru a/include/linux/netfilter_bridge/ebt_802_3.h b/include/linux/netfilter_bridge/ebt_802_3.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/linux/netfilter_bridge/ebt_802_3.h Tue Sep 2 19:58:20 2003 @@ -0,0 +1,60 @@ +#ifndef __LINUX_BRIDGE_EBT_802_3_H +#define __LINUX_BRIDGE_EBT_802_3_H + +#define EBT_802_3_SAP 0x01 +#define EBT_802_3_TYPE 0x02 + +#define EBT_802_3_MATCH "802_3" + +/* + * If frame has DSAP/SSAP value 0xaa you must check the SNAP type + * to discover what kind of packet we're carrying. + */ +#define CHECK_TYPE 0xaa + +/* + * Control field may be one or two bytes. If the first byte has + * the value 0x03 then the entire length is one byte, otherwise it is two. + * One byte controls are used in Unnumbered Information frames. + * Two byte controls are used in Numbered Information frames. + */ +#define IS_UI 0x03 + +#define EBT_802_3_MASK (EBT_802_3_SAP | EBT_802_3_TYPE | EBT_802_3) + +/* ui has one byte ctrl, ni has two */ +struct hdr_ui { + uint8_t dsap; + uint8_t ssap; + uint8_t ctrl; + uint8_t orig[3]; + uint16_t type; +}; + +struct hdr_ni { + uint8_t dsap; + uint8_t ssap; + uint16_t ctrl; + uint8_t orig[3]; + uint16_t type; +}; + +struct ebt_802_3_hdr { + uint8_t daddr[6]; + uint8_t saddr[6]; + uint16_t len; + union { + struct hdr_ui ui; + struct hdr_ni ni; + } llc; +}; + +struct ebt_802_3_info +{ + uint8_t sap; + uint16_t type; + uint8_t bitmask; + uint8_t invflags; +}; + +#endif diff -Nru a/include/linux/netfilter_bridge/ebt_arpreply.h b/include/linux/netfilter_bridge/ebt_arpreply.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/linux/netfilter_bridge/ebt_arpreply.h Tue Sep 2 19:58:20 2003 @@ -0,0 +1,11 @@ +#ifndef __LINUX_BRIDGE_EBT_ARPREPLY_H +#define __LINUX_BRIDGE_EBT_ARPREPLY_H + +struct ebt_arpreply_info +{ + unsigned char mac[ETH_ALEN]; + int target; +}; +#define EBT_ARPREPLY_TARGET "arpreply" + +#endif diff -Nru a/include/linux/netfilter_bridge.h b/include/linux/netfilter_bridge.h --- a/include/linux/netfilter_bridge.h Tue Sep 2 19:58:16 2003 +++ b/include/linux/netfilter_bridge.h Tue Sep 2 19:58:16 2003 @@ -6,7 +6,7 @@ #include #include -#if defined(__KERNEL__) && defined(CONFIG_NETFILTER) +#if defined(__KERNEL__) && defined(CONFIG_BRIDGE_NETFILTER) #include #endif @@ -27,11 +27,6 @@ #ifdef __KERNEL__ -#define BRNF_PKT_TYPE 0x01 -#define BRNF_BRIDGED_DNAT 0x02 -#define BRNF_DONT_TAKE_PARENT 0x04 -#define BRNF_BRIDGED 0x08 - enum nf_br_hook_priorities { NF_BR_PRI_FIRST = INT_MIN, NF_BR_PRI_NAT_DST_BRIDGED = -300, @@ -43,7 +38,13 @@ NF_BR_PRI_LAST = INT_MAX, }; -#ifdef CONFIG_NETFILTER +#ifdef CONFIG_BRIDGE_NETFILTER + +#define BRNF_PKT_TYPE 0x01 +#define BRNF_BRIDGED_DNAT 0x02 +#define BRNF_DONT_TAKE_PARENT 0x04 +#define BRNF_BRIDGED 0x08 + static inline struct nf_bridge_info *nf_bridge_alloc(struct sk_buff *skb) { @@ -63,7 +64,7 @@ __u32 ipv4; } daddr; }; -#endif /* CONFIG_NETFILTER */ +#endif /* CONFIG_BRIDGE_NETFILTER */ #endif /* __KERNEL__ */ #endif diff -Nru a/include/linux/netfilter_ipv4/ipt_CLASSIFY.h b/include/linux/netfilter_ipv4/ipt_CLASSIFY.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/linux/netfilter_ipv4/ipt_CLASSIFY.h Tue Sep 2 19:58:20 2003 @@ -0,0 +1,8 @@ +#ifndef _IPT_CLASSIFY_H +#define _IPT_CLASSIFY_H + +struct ipt_classify_target_info { + u_int32_t priority; +}; + +#endif /*_IPT_CLASSIFY_H */ diff -Nru a/include/linux/netfilter_ipv4/ipt_SAME.h b/include/linux/netfilter_ipv4/ipt_SAME.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/linux/netfilter_ipv4/ipt_SAME.h Tue Sep 2 19:58:20 2003 @@ -0,0 +1,19 @@ +#ifndef _IPT_SAME_H +#define _IPT_SAME_H + +#define IPT_SAME_MAX_RANGE 10 + +#define IPT_SAME_NODST 0x01 + +struct ipt_same_info +{ + unsigned char info; + u_int32_t rangesize; + u_int32_t ipnum; + u_int32_t *iparray; + + /* hangs off end. */ + struct ip_nat_range range[IPT_SAME_MAX_RANGE]; +}; + +#endif /*_IPT_SAME_H*/ diff -Nru a/include/linux/netfilter_ipv4/ipt_iprange.h b/include/linux/netfilter_ipv4/ipt_iprange.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/linux/netfilter_ipv4/ipt_iprange.h Tue Sep 2 19:58:20 2003 @@ -0,0 +1,23 @@ +#ifndef _IPT_IPRANGE_H +#define _IPT_IPRANGE_H + +#define IPRANGE_SRC 0x01 /* Match source IP address */ +#define IPRANGE_DST 0x02 /* Match destination IP address */ +#define IPRANGE_SRC_INV 0x10 /* Negate the condition */ +#define IPRANGE_DST_INV 0x20 /* Negate the condition */ + +struct ipt_iprange { + /* Inclusive: network order. */ + u_int32_t min_ip, max_ip; +}; + +struct ipt_iprange_info +{ + struct ipt_iprange src; + struct ipt_iprange dst; + + /* Flags from above */ + u_int8_t flags; +}; + +#endif /* _IPT_IPRANGE_H */ diff -Nru a/include/linux/nfsd/nfsfh.h b/include/linux/nfsd/nfsfh.h --- a/include/linux/nfsd/nfsfh.h Tue Sep 2 19:58:17 2003 +++ b/include/linux/nfsd/nfsfh.h Tue Sep 2 19:58:17 2003 @@ -294,8 +294,8 @@ /* how much do we care for accuracy with MinixFS? */ fhp->fh_post_blocks = (inode->i_size+511) >> 9; } - fhp->fh_post_rdev[0] = htonl((u32)major(inode->i_rdev)); - fhp->fh_post_rdev[1] = htonl((u32)minor(inode->i_rdev)); + fhp->fh_post_rdev[0] = htonl((u32)imajor(inode)); + fhp->fh_post_rdev[1] = htonl((u32)iminor(inode)); fhp->fh_post_atime = inode->i_atime; fhp->fh_post_mtime = inode->i_mtime; fhp->fh_post_ctime = inode->i_ctime; diff -Nru a/include/linux/nfsd/state.h b/include/linux/nfsd/state.h --- a/include/linux/nfsd/state.h Tue Sep 2 19:58:13 2003 +++ b/include/linux/nfsd/state.h Tue Sep 2 19:58:13 2003 @@ -113,21 +113,15 @@ int so_confirmed; /* successful OPEN_CONFIRM? */ }; -typedef struct { - u32 dev; /* super_block->s_dev */ - unsigned long ino; - u32 generation; -} nfs4_ino_desc_t; - /* * nfs4_file: a file opened by some number of (open) nfs4_stateowners. * o fi_perfile list is used to search for conflicting * share_acces, share_deny on the file. */ struct nfs4_file { - struct list_head fi_hash; /* hash by nfs4_ino_desc_t fields */ + struct list_head fi_hash; /* hash by "struct inode *" */ struct list_head fi_perfile; /* list: nfs4_stateid */ - nfs4_ino_desc_t fi_ino; + struct inode *fi_inode; u32 fi_id; /* used with stateowner->so_id * for openstateid_hashtbl hash */ }; diff -Nru a/include/linux/pci_ids.h b/include/linux/pci_ids.h --- a/include/linux/pci_ids.h Tue Sep 2 19:58:15 2003 +++ b/include/linux/pci_ids.h Tue Sep 2 19:58:15 2003 @@ -798,6 +798,7 @@ #define PCI_DEVICE_ID_APPLE_UNI_N_FW2 0x0030 #define PCI_DEVICE_ID_APPLE_UNI_N_GMAC2 0x0032 #define PCI_DEVICE_ID_APPLE_UNI_N_AGP2 0x0034 +#define PCI_DEVICE_ID_APPLE_KAUAI_ATA 0x003b #define PCI_DEVICE_ID_APPLE_KEYLARGO_I 0x003e #define PCI_DEVICE_ID_APPLE_TIGON3 0x1645 @@ -877,6 +878,7 @@ #define PCI_DEVICE_ID_SII_680 0x0680 #define PCI_DEVICE_ID_SII_3112 0x3112 +#define PCI_DEVICE_ID_SII_1210SA 0x0240 #define PCI_VENDOR_ID_VISION 0x1098 #define PCI_DEVICE_ID_VISION_QD8500 0x0001 @@ -1115,7 +1117,9 @@ #define PCI_DEVICE_ID_TTI_HPT374 0x0008 #define PCI_VENDOR_ID_VIA 0x1106 -#define PCI_DEVICE_ID_VIA_P4X600 0x0198 +#define PCI_DEVICE_ID_VIA_8763_0 0x0198 +#define PCI_DEVICE_ID_VIA_8380_0 0x0204 +#define PCI_DEVICE_ID_VIA_PX8X0_0 0x0259 #define PCI_DEVICE_ID_VIA_8363_0 0x0305 #define PCI_DEVICE_ID_VIA_8371_0 0x0391 #define PCI_DEVICE_ID_VIA_8501_0 0x0501 @@ -1130,10 +1134,10 @@ #define PCI_DEVICE_ID_VIA_82C597_0 0x0597 #define PCI_DEVICE_ID_VIA_82C598_0 0x0598 #define PCI_DEVICE_ID_VIA_8601_0 0x0601 -#define PCI_DEVICE_ID_VIA_82C694X_0 0x0605 +#define PCI_DEVICE_ID_VIA_8605_0 0x0605 #define PCI_DEVICE_ID_VIA_82C680 0x0680 #define PCI_DEVICE_ID_VIA_82C686 0x0686 -#define PCI_DEVICE_ID_VIA_82C691 0x0691 +#define PCI_DEVICE_ID_VIA_82C691_0 0x0691 #define PCI_DEVICE_ID_VIA_82C693 0x0693 #define PCI_DEVICE_ID_VIA_82C693_1 0x0698 #define PCI_DEVICE_ID_VIA_82C926 0x0926 @@ -1156,19 +1160,21 @@ #define PCI_DEVICE_ID_VIA_8622 0x3102 #define PCI_DEVICE_ID_VIA_8233C_0 0x3109 #define PCI_DEVICE_ID_VIA_8361 0x3112 -#define PCI_DEVICE_ID_VIA_KM266 0x3116 -#define PCI_DEVICE_ID_VIA_CLE266 0x3123 +#define PCI_DEVICE_ID_VIA_XM266 0x3116 +#define PCI_DEVICE_ID_VIA_862X_0 0x3123 #define PCI_DEVICE_ID_VIA_8753_0 0x3128 #define PCI_DEVICE_ID_VIA_8233A 0x3147 -#define PCI_DEVICE_ID_VIA_8752 0x3148 +#define PCI_DEVICE_ID_VIA_8703_51_0 0x3148 #define PCI_DEVICE_ID_VIA_8237_SATA 0x3149 -#define PCI_DEVICE_ID_VIA_KN266 0x3156 -#define PCI_DEVICE_ID_VIA_8754 0x3168 +#define PCI_DEVICE_ID_VIA_XN266 0x3156 +#define PCI_DEVICE_ID_VIA_8754C_0 0x3168 #define PCI_DEVICE_ID_VIA_8235 0x3177 #define PCI_DEVICE_ID_VIA_P4N333 0x3178 -#define PCI_DEVICE_ID_VIA_K8T400M_0 0x3188 +#define PCI_DEVICE_ID_VIA_8385_0 0x3188 #define PCI_DEVICE_ID_VIA_8377_0 0x3189 -#define PCI_DEVICE_ID_VIA_KM400 0x3205 +#define PCI_DEVICE_ID_VIA_8378_0 0x3205 +#define PCI_DEVICE_ID_VIA_8783_0 0x3208 +#define PCI_DEVICE_ID_VIA_PT880 0x3258 #define PCI_DEVICE_ID_VIA_P4M400 0x3209 #define PCI_DEVICE_ID_VIA_8237 0x3227 #define PCI_DEVICE_ID_VIA_86C100A 0x6100 @@ -1183,7 +1189,12 @@ #define PCI_DEVICE_ID_VIA_8505_1 0x8605 #define PCI_DEVICE_ID_VIA_8633_1 0xB091 #define PCI_DEVICE_ID_VIA_8367_1 0xB099 -#define PCI_DEVICE_ID_VIA_8653_1 0xB101 +#define PCI_DEVICE_ID_VIA_P4X266_1 0xB101 +#define PCI_DEVICE_ID_VIA_8615_1 0xB103 +#define PCI_DEVICE_ID_VIA_8361_1 0xB112 +#define PCI_DEVICE_ID_VIA_8235_1 0xB168 +#define PCI_DEVICE_ID_VIA_838X_1 0xB188 +#define PCI_DEVICE_ID_VIA_83_87XX_1 0xB198 #define PCI_VENDOR_ID_SIEMENS 0x110A #define PCI_DEVICE_ID_SIEMENS_DSCC4 0x2102 @@ -1274,6 +1285,9 @@ #define PCI_DEVICE_ID_SYSKONNECT_FP 0x4000 #define PCI_DEVICE_ID_SYSKONNECT_TR 0x4200 #define PCI_DEVICE_ID_SYSKONNECT_GE 0x4300 +#define PCI_DEVICE_ID_SYSKONNECT_YU 0x4320 +#define PCI_DEVICE_ID_SYSKONNECT_9DXX 0x4400 +#define PCI_DEVICE_ID_SYSKONNECT_9MXX 0x4500 #define PCI_VENDOR_ID_VMIC 0x114a #define PCI_DEVICE_ID_VMIC_VME 0x7587 @@ -1332,7 +1346,10 @@ #define PCI_VENDOR_ID_TOSHIBA 0x1179 #define PCI_DEVICE_ID_TOSHIBA_601 0x0601 #define PCI_DEVICE_ID_TOSHIBA_TOPIC95 0x060a +#define PCI_DEVICE_ID_TOSHIBA_TOPIC95_A 0x0603 +#define PCI_DEVICE_ID_TOSHIBA_TOPIC95_B 0x060a #define PCI_DEVICE_ID_TOSHIBA_TOPIC97 0x060f +#define PCI_DEVICE_ID_TOSHIBA_TOPIC100 0x0617 #define PCI_VENDOR_ID_TOSHIBA_2 0x102f #define PCI_DEVICE_ID_TOSHIBA_TX3927 0x000a @@ -1758,11 +1775,19 @@ #define PCI_DEVICE_ID_TIGON3_5703 0x1647 #define PCI_DEVICE_ID_TIGON3_5704 0x1648 #define PCI_DEVICE_ID_TIGON3_5702FE 0x164d +#define PCI_DEVICE_ID_TIGON3_5705 0x1653 +#define PCI_DEVICE_ID_TIGON3_5705_2 0x1654 +#define PCI_DEVICE_ID_TIGON3_5705M 0x165d +#define PCI_DEVICE_ID_TIGON3_5705M_2 0x165e +#define PCI_DEVICE_ID_TIGON3_5782 0x1696 +#define PCI_DEVICE_ID_TIGON3_5788 0x169c #define PCI_DEVICE_ID_TIGON3_5702X 0x16a6 #define PCI_DEVICE_ID_TIGON3_5703X 0x16a7 #define PCI_DEVICE_ID_TIGON3_5704S 0x16a8 #define PCI_DEVICE_ID_TIGON3_5702A3 0x16c6 #define PCI_DEVICE_ID_TIGON3_5703A3 0x16c7 +#define PCI_DEVICE_ID_TIGON3_5901 0x170d +#define PCI_DEVICE_ID_TIGON3_5901_2 0x170e #define PCI_DEVICE_ID_BCM4401 0x4401 #define PCI_VENDOR_ID_SYBA 0x1592 @@ -1790,6 +1815,7 @@ #define PCI_DEVICE_ID_ALTIMA_AC1000 0x03e8 #define PCI_DEVICE_ID_ALTIMA_AC1001 0x03e9 #define PCI_DEVICE_ID_ALTIMA_AC9100 0x03ea +#define PCI_DEVICE_ID_ALTIMA_AC1003 0x03eb #define PCI_VENDOR_ID_SYMPHONY 0x1c1c #define PCI_DEVICE_ID_SYMPHONY_101 0x0001 diff -Nru a/include/linux/personality.h b/include/linux/personality.h --- a/include/linux/personality.h Tue Sep 2 19:58:16 2003 +++ b/include/linux/personality.h Tue Sep 2 19:58:16 2003 @@ -34,6 +34,7 @@ SHORT_INODE = 0x1000000, WHOLE_SECONDS = 0x2000000, STICKY_TIMEOUTS = 0x4000000, + ADDR_LIMIT_3GB = 0x8000000, }; /* @@ -56,6 +57,7 @@ PER_SUNOS = 0x0006 | STICKY_TIMEOUTS, PER_XENIX = 0x0007 | STICKY_TIMEOUTS | SHORT_INODE, PER_LINUX32 = 0x0008, + PER_LINUX32_3GB = 0x0008 | ADDR_LIMIT_3GB, PER_IRIX32 = 0x0009 | STICKY_TIMEOUTS,/* IRIX5 32-bit */ PER_IRIXN32 = 0x000a | STICKY_TIMEOUTS,/* IRIX6 new 32-bit */ PER_IRIX64 = 0x000b | STICKY_TIMEOUTS,/* IRIX6 64-bit */ diff -Nru a/include/linux/pmu.h b/include/linux/pmu.h --- a/include/linux/pmu.h Tue Sep 2 19:58:13 2003 +++ b/include/linux/pmu.h Tue Sep 2 19:58:13 2003 @@ -33,6 +33,7 @@ #define PMU_CPU_SPEED 0x7d /* control CPU speed on some models */ #define PMU_SLEEP 0x7f /* put CPU to sleep */ #define PMU_POWER_EVENTS 0x8f /* Send power-event commands to PMU */ +#define PMU_I2C_CMD 0x9a /* I2C operations */ #define PMU_RESET 0xd0 /* reset CPU */ #define PMU_GET_BRIGHTBUTTON 0xd9 /* report brightness up/down pos */ #define PMU_GET_COVER 0xdc /* report cover open/closed */ @@ -69,6 +70,20 @@ * or via PMU_INT_ENVIRONMENT on core99 */ #define PMU_ENV_LID_CLOSED 0x01 /* The lid is closed */ +/* I2C related definitions */ +#define PMU_I2C_MODE_SIMPLE 0 +#define PMU_I2C_MODE_STDSUB 1 +#define PMU_I2C_MODE_COMBINED 2 + +#define PMU_I2C_BUS_STATUS 0 +#define PMU_I2C_BUS_SYSCLK 1 +#define PMU_I2C_BUS_POWER 2 + +#define PMU_I2C_STATUS_OK 0 +#define PMU_I2C_STATUS_DATAREAD 1 +#define PMU_I2C_STATUS_BUSY 0xfe + + /* Kind of PMU (model) */ enum { PMU_UNKNOWN, @@ -127,6 +142,8 @@ void (*done)(struct adb_request *), int nbytes, ...); extern void pmu_poll(void); +extern void pmu_poll_adb(void); /* For use by xmon */ +extern void pmu_wait_complete(struct adb_request *req); /* For use before switching interrupts off for a long time; * warning: not stackable @@ -138,9 +155,16 @@ extern void pmu_restart(void); extern void pmu_shutdown(void); +extern void pmu_unlock(void); extern int pmu_present(void); extern int pmu_get_model(void); + +extern int pmu_i2c_combined_read(int bus, int addr, int subaddr, u8* data, int len); +extern int pmu_i2c_stdsub_write(int bus, int addr, int subaddr, u8* data, int len); +extern int pmu_i2c_simple_read(int bus, int addr, u8* data, int len); +extern int pmu_i2c_simple_write(int bus, int addr, u8* data, int len); + #ifdef CONFIG_PMAC_PBOOK /* diff -Nru a/include/linux/proc_fs.h b/include/linux/proc_fs.h --- a/include/linux/proc_fs.h Tue Sep 2 19:58:12 2003 +++ b/include/linux/proc_fs.h Tue Sep 2 19:58:12 2003 @@ -182,12 +182,6 @@ remove_proc_entry(name,proc_net); } -/* - * fs/proc/kcore.c - */ -extern void kclist_add(struct kcore_list *, void *, size_t); -extern struct kcore_list *kclist_del(void *); - #else #define proc_root_driver NULL @@ -223,6 +217,9 @@ extern struct proc_dir_entry proc_root; +#endif /* CONFIG_PROC_FS */ + +#if !defined(CONFIG_PROC_FS) static inline void kclist_add(struct kcore_list *new, void *addr, size_t size) { } @@ -230,8 +227,10 @@ { return NULL; } - -#endif /* CONFIG_PROC_FS */ +#else +extern void kclist_add(struct kcore_list *, void *, size_t); +extern struct kcore_list *kclist_del(void *); +#endif struct proc_inode { struct task_struct *task; diff -Nru a/include/linux/sched.h b/include/linux/sched.h --- a/include/linux/sched.h Tue Sep 2 19:58:13 2003 +++ b/include/linux/sched.h Tue Sep 2 19:58:13 2003 @@ -391,6 +391,7 @@ struct timer_list real_timer; struct list_head posix_timers; /* POSIX.1b Interval Timers */ unsigned long utime, stime, cutime, cstime; + unsigned long nvcsw, nivcsw, cnvcsw, cnivcsw; /* context switch counts */ u64 start_time; /* mm fault and swap info: this can arguably be seen as either mm-specific or thread-specific */ unsigned long min_flt, maj_flt, nswap, cmin_flt, cmaj_flt, cnswap; diff -Nru a/include/linux/serial_core.h b/include/linux/serial_core.h --- a/include/linux/serial_core.h Tue Sep 2 19:58:13 2003 +++ b/include/linux/serial_core.h Tue Sep 2 19:58:13 2003 @@ -67,6 +67,9 @@ #define PORT_PC9861 45 #define PORT_PC9801_101 46 +/* Macintosh Zilog type numbers */ +#define PORT_MAC_ZILOG 50 /* m68k : not yet implemented */ +#define PORT_PMAC_ZILOG 51 #ifdef __KERNEL__ diff -Nru a/include/linux/skbuff.h b/include/linux/skbuff.h --- a/include/linux/skbuff.h Tue Sep 2 19:58:16 2003 +++ b/include/linux/skbuff.h Tue Sep 2 19:58:16 2003 @@ -98,7 +98,7 @@ struct nf_conntrack *master; }; -#if defined(CONFIG_BRIDGE) || defined(CONFIG_BRIDGE_MODULE) +#ifdef CONFIG_BRIDGE_NETFILTER struct nf_bridge_info { atomic_t use; struct net_device *physindev; @@ -244,7 +244,7 @@ #ifdef CONFIG_NETFILTER_DEBUG unsigned int nf_debug; #endif -#if defined(CONFIG_BRIDGE) || defined(CONFIG_BRIDGE_MODULE) +#ifdef CONFIG_BRIDGE_NETFILTER struct nf_bridge_info *nf_bridge; #endif #endif /* CONFIG_NETFILTER */ @@ -1195,7 +1195,7 @@ atomic_inc(&nfct->master->use); } -#if defined(CONFIG_BRIDGE) || defined(CONFIG_BRIDGE_MODULE) +#ifdef CONFIG_BRIDGE_NETFILTER static inline void nf_bridge_put(struct nf_bridge_info *nf_bridge) { if (nf_bridge && atomic_dec_and_test(&nf_bridge->use)) diff -Nru a/include/linux/sonypi.h b/include/linux/sonypi.h --- a/include/linux/sonypi.h Tue Sep 2 19:58:15 2003 +++ b/include/linux/sonypi.h Tue Sep 2 19:58:15 2003 @@ -94,6 +94,8 @@ #define SONYPI_EVENT_MEMORYSTICK_INSERT 54 #define SONYPI_EVENT_MEMORYSTICK_EJECT 55 #define SONYPI_EVENT_ANYBUTTON_RELEASED 56 +#define SONYPI_EVENT_BATTERY_INSERT 57 +#define SONYPI_EVENT_BATTERY_REMOVE 58 /* get/set brightness */ #define SONYPI_IOCGBRT _IOR('v', 0, __u8) diff -Nru a/include/linux/tpqic02.h b/include/linux/tpqic02.h --- a/include/linux/tpqic02.h Tue Sep 2 19:58:13 2003 +++ b/include/linux/tpqic02.h Tue Sep 2 19:58:13 2003 @@ -587,10 +587,10 @@ * |___________________ Reserved for diagnostics during debugging. */ -#define TP_REWCLOSE(d) ((minor(d)&0x01) == 1) /* rewind bit */ +#define TP_REWCLOSE(d) ((d)&1) /* rewind bit */ /* rewind is only done if data has been transferred */ -#define TP_DENS(dev) ((minor(dev) >> 1) & 0x07) /* tape density */ -#define TP_UNIT(dev) ((minor(dev) >> 4) & 0x07) /* unit number */ +#define TP_DENS(d) (((d) >> 1) & 0x07) /* tape density */ +#define TP_UNIT(d) (((d) >> 4) & 0x07) /* unit number */ /* print excessive diagnostics */ #define TP_DIAGS(dev) (QIC02_TAPE_DEBUG & TPQD_DIAGS) diff -Nru a/include/linux/tty.h b/include/linux/tty.h --- a/include/linux/tty.h Tue Sep 2 19:58:16 2003 +++ b/include/linux/tty.h Tue Sep 2 19:58:16 2003 @@ -367,7 +367,7 @@ extern int macserial_init(void); extern int a2232board_init(void); -extern int tty_paranoia_check(struct tty_struct *tty, kdev_t device, +extern int tty_paranoia_check(struct tty_struct *tty, struct inode *inode, const char *routine); extern char *tty_name(struct tty_struct *tty, char *buf); extern void tty_wait_until_sent(struct tty_struct * tty, long timeout); diff -Nru a/include/linux/usb.h b/include/linux/usb.h --- a/include/linux/usb.h Tue Sep 2 19:58:15 2003 +++ b/include/linux/usb.h Tue Sep 2 19:58:15 2003 @@ -410,6 +410,8 @@ * the "usbfs" filesystem. This lets devices provide ways to * expose information to user space regardless of where they * do (or don't) show up otherwise in the filesystem. + * @suspend: Called when the device is going to be suspended by the system. + * @resume: Called when the device is being resumed by the system. * @id_table: USB drivers use ID table to support hotplugging. * Export this with MODULE_DEVICE_TABLE(usb,...). This must be set * or your driver's probe function will never get called. @@ -444,6 +446,9 @@ void (*disconnect) (struct usb_interface *intf); int (*ioctl) (struct usb_interface *intf, unsigned int code, void *buf); + + int (*suspend) (struct usb_interface *intf, u32 state); + int (*resume) (struct usb_interface *intf); const struct usb_device_id *id_table; diff -Nru a/include/linux/usb_gadget.h b/include/linux/usb_gadget.h --- a/include/linux/usb_gadget.h Tue Sep 2 19:58:15 2003 +++ b/include/linux/usb_gadget.h Tue Sep 2 19:58:15 2003 @@ -313,8 +313,8 @@ * arranges to poll once per interval, and the gadget driver usually will * have queued some data to transfer at that time. * - * Returns zero, or a negative error code. Endpoints that are not enabled, - * or which are enabled but halted, report errors; errors will also be + * Returns zero, or a negative error code. Endpoints that are not enabled + * report errors; errors will also be * reported when the usb peripheral is disconnected. */ static inline int @@ -352,6 +352,11 @@ * clears this feature; drivers may need to empty the endpoint's request * queue first, to make sure no inappropriate transfers happen. * + * Note that while an endpoint CLEAR_FEATURE will be invisible to the + * gadget driver, a SET_INTERFACE will not be. To reset endpoints for the + * current altsetting, see usb_ep_clear_halt(). When switching altsettings, + * it's simplest to use usb_ep_enable() or usb_ep_disable() for the endpoints. + * * Returns zero, or a negative error code. On success, this call sets * underlying hardware state that blocks data transfers. */ @@ -365,12 +370,14 @@ * usb_ep_clear_halt - clears endpoint halt, and resets toggle * @ep:the bulk or interrupt endpoint being reset * - * use this when responding to the standard usb "set interface" request, + * Use this when responding to the standard usb "set interface" request, * for endpoints that aren't reconfigured, after clearing any other state * in the endpoint's i/o queue. * - * returns zero, or a negative error code. on success, this call clears + * Returns zero, or a negative error code. On success, this call clears * the underlying hardware state reflecting endpoint halt and data toggle. + * Note that some hardware can't support this request (like pxa2xx_udc), + * and accordingly can't correctly implement interface altsettings. */ static inline int usb_ep_clear_halt (struct usb_ep *ep) @@ -562,7 +569,8 @@ * queues a response to ep0, or returns negative to stall. * @disconnect: Invoked after all transfers have been stopped, * when the host is disconnected. May be called in_interrupt; this - * may not sleep. + * may not sleep. Some devices can't detect disconnect, so this might + * not be called except as part of controller shutdown. * @unbind: Invoked when the driver is unbound from a gadget, * usually from rmmod (after a disconnect is reported). * Called in a context that permits sleeping. @@ -603,7 +611,9 @@ * not provide those callbacks. However, some may need to change modes * when the host is not longer directing those activities. For example, * local controls (buttons, dials, etc) may need to be re-enabled since - * the (remote) host can't do that any longer. + * the (remote) host can't do that any longer; or an error state might + * be cleared, to make the device behave identically whether or not + * power is maintained. */ struct usb_gadget_driver { char *function; diff -Nru a/include/linux/videodev.h b/include/linux/videodev.h --- a/include/linux/videodev.h Tue Sep 2 19:58:20 2003 +++ b/include/linux/videodev.h Tue Sep 2 19:58:20 2003 @@ -63,6 +63,12 @@ { class_device_create_file(&vfd->class_dev, attr); } +static inline void +video_device_remove_file(struct video_device *vfd, + struct class_device_attribute *attr) +{ + class_device_remove_file(&vfd->class_dev, attr); +} /* helper functions to alloc / release struct video_device, the later can be used for video_device->release() */ diff -Nru a/include/linux/wait.h b/include/linux/wait.h --- a/include/linux/wait.h Tue Sep 2 19:58:16 2003 +++ b/include/linux/wait.h Tue Sep 2 19:58:16 2003 @@ -220,22 +220,6 @@ __remove_wait_queue(q, wait); } -#define add_wait_queue_cond(q, wait, cond) \ - ({ \ - unsigned long flags; \ - int _raced = 0; \ - spin_lock_irqsave(&(q)->lock, flags); \ - (wait)->flags = 0; \ - __add_wait_queue((q), (wait)); \ - rmb(); \ - if (!(cond)) { \ - _raced = 1; \ - __remove_wait_queue((q), (wait)); \ - } \ - spin_lock_irqrestore(&(q)->lock, flags); \ - _raced; \ - }) - /* * These are the old interfaces to sleep waiting for an event. * They are racy. DO NOT use them, use the wait_event* interfaces above. diff -Nru a/include/net/ax25.h b/include/net/ax25.h --- a/include/net/ax25.h Tue Sep 2 19:58:17 2003 +++ b/include/net/ax25.h Tue Sep 2 19:58:17 2003 @@ -314,7 +314,7 @@ /* ax25_route.c */ extern void ax25_rt_device_down(struct net_device *); extern int ax25_rt_ioctl(unsigned int, void *); -extern int ax25_rt_get_info(char *, char **, off_t, int); +extern struct file_operations ax25_route_fops; extern int ax25_rt_autobind(ax25_cb *, ax25_address *); extern ax25_route *ax25_rt_find_route(ax25_route *, ax25_address *, struct net_device *); @@ -373,7 +373,7 @@ extern int ax25_uid_policy; extern ax25_address *ax25_findbyuid(uid_t); extern int ax25_uid_ioctl(int, struct sockaddr_ax25 *); -extern int ax25_uid_get_info(char *, char **, off_t, int); +extern struct file_operations ax25_uid_fops; extern void ax25_uid_free(void); /* sysctl_net_ax25.c */ diff -Nru a/include/net/ip6_tunnel.h b/include/net/ip6_tunnel.h --- a/include/net/ip6_tunnel.h Tue Sep 2 19:58:15 2003 +++ b/include/net/ip6_tunnel.h Tue Sep 2 19:58:15 2003 @@ -25,6 +25,8 @@ int recursion; /* depth of hard_start_xmit recursion */ struct ip6_tnl_parm parms; /* tunnel configuration paramters */ struct flowi fl; /* flowi template for xmit */ + struct dst_entry *dst_cache; /* cached dst */ + u32 dst_cookie; }; /* Tunnel encapsulation limit destination sub-option */ diff -Nru a/include/net/ipv6.h b/include/net/ipv6.h --- a/include/net/ipv6.h Tue Sep 2 19:58:18 2003 +++ b/include/net/ipv6.h Tue Sep 2 19:58:18 2003 @@ -193,7 +193,7 @@ struct in6_addr dst; struct ipv6_txoptions *opt; atomic_t users; - u32 linger; + unsigned long linger; u8 share; u32 owner; unsigned long lastuse; diff -Nru a/include/net/irda/vlsi_ir.h b/include/net/irda/vlsi_ir.h --- a/include/net/irda/vlsi_ir.h Tue Sep 2 19:58:17 2003 +++ b/include/net/irda/vlsi_ir.h Tue Sep 2 19:58:17 2003 @@ -3,7 +3,7 @@ * * vlsi_ir.h: VLSI82C147 PCI IrDA controller driver for Linux * - * Version: 0.4a + * Version: 0.5 * * Copyright (c) 2001-2003 Martin Diehl * @@ -27,18 +27,71 @@ #ifndef IRDA_VLSI_FIR_H #define IRDA_VLSI_FIR_H -/* - * #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,xx) - * - * missing pci-dma api call to give streaming dma buffer back to hw - * patch floating on lkml - probably present in 2.5.26 or later - * otherwise defining it as noop is ok, since the vlsi-ir is only - * used on two oldish x86-based notebooks which are cache-coherent +/* ================================================================ + * compatibility stuff */ -#define pci_dma_prep_single(dev, addr, size, direction) /* nothing */ -/* - * #endif + +/* definitions not present in pci_ids.h */ + +#ifndef PCI_CLASS_WIRELESS_IRDA +#define PCI_CLASS_WIRELESS_IRDA 0x0d00 +#endif + +#ifndef PCI_CLASS_SUBCLASS_MASK +#define PCI_CLASS_SUBCLASS_MASK 0xffff +#endif + +/* missing pci-dma api call to give streaming dma buffer back to hw + * patch was floating on lkml around 2.5.2x and might be present later. + * Defining it this way is ok, since the vlsi-ir is only + * used on two oldish x86-based notebooks which are cache-coherent + * (and flush_write_buffers also handles PPro errata and C3 OOstore) */ +#ifdef CONFIG_X86 +#include +#define pci_dma_prep_single(dev, addr, size, direction) flush_write_buffers() +#else +#error missing pci dma api call +#endif + +/* in recent 2.5 interrupt handlers have non-void return value */ +#ifndef IRQ_RETVAL +typedef void irqreturn_t; +#define IRQ_NONE +#define IRQ_HANDLED +#define IRQ_RETVAL(x) +#endif + +/* some stuff need to check kernelversion. Not all 2.5 stuff was present + * in early 2.5.x - the test is merely to separate 2.4 from 2.5 + */ +#include + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) + +/* PDE() introduced in 2.5.4 */ +#ifdef CONFIG_PROC_FS +#define PDE(inode) ((inode)->u.generic_ip) +#endif + +/* irda crc16 calculation exported in 2.5.42 */ +#define irda_calc_crc16(fcs,buf,len) (GOOD_FCS) + +/* we use this for unified pci device name access */ +#define PCIDEV_NAME(pdev) ((pdev)->name) + +#else /* 2.5 or later */ + +/* recent 2.5/2.6 stores pci device names at varying places ;-) */ +#ifdef CONFIG_PCI_NAMES +/* human readable name */ +#define PCIDEV_NAME(pdev) ((pdev)->pretty_name) +#else +/* whatever we get from the associated struct device - bus:slot:dev.fn id */ +#define PCIDEV_NAME(pdev) (pci_name(pdev)) +#endif + +#endif /* ================================================================ */ @@ -138,7 +191,7 @@ * - IRMISC_UARTSEL configured * - IRCFG_MASTER must be cleared * - IRCFG_SIR must be set - * - IRENABLE_IREN must be asserted 0->1 (and hence IRENABLE_SIR_ON) + * - IRENABLE_PHYANDCLOCK must be asserted 0->1 (and hence IRENABLE_SIR_ON) */ enum vlsi_pci_irmisc { @@ -298,7 +351,7 @@ /* notes: * - not more than one SIR/MIR/FIR bit must be set at any time * - SIR, MIR, FIR and CRC16 select the configuration which will - * be applied on next 0->1 transition of IRENABLE_IREN (see below). + * be applied on next 0->1 transition of IRENABLE_PHYANDCLOCK (see below). * - besides allowing the PCI interface to execute busmaster cycles * and therefore the ring SM to operate, the MSTR bit has side-effects: * when MSTR is cleared, the RINGPTR's get reset and the legacy UART mode @@ -349,7 +402,7 @@ */ enum vlsi_pio_irenable { - IRENABLE_IREN = 0x8000, /* enable IR phy and gate the mode config (rw) */ + IRENABLE_PHYANDCLOCK = 0x8000, /* enable IR phy and gate the mode config (rw) */ IRENABLE_CFGER = 0x4000, /* mode configuration error (ro) */ IRENABLE_FIR_ON = 0x2000, /* FIR on status (ro) */ IRENABLE_MIR_ON = 0x1000, /* MIR on status (ro) */ @@ -366,7 +419,7 @@ /* VLSI_PIO_PHYCTL: IR Physical Layer Current Control Register (u16, ro) */ /* read-back of the currently applied physical layer status. - * applied from VLSI_PIO_NPHYCTL at rising edge of IRENABLE_IREN + * applied from VLSI_PIO_NPHYCTL at rising edge of IRENABLE_PHYANDCLOCK * contents identical to VLSI_PIO_NPHYCTL (see below) */ @@ -374,7 +427,7 @@ /* VLSI_PIO_NPHYCTL: IR Physical Layer Next Control Register (u16, rw) */ -/* latched during IRENABLE_IREN=0 and applied at 0-1 transition +/* latched during IRENABLE_PHYANDCLOCK=0 and applied at 0-1 transition * * consists of BAUD[15:10], PLSWID[9:5] and PREAMB[4:0] bits defined as follows: * @@ -616,21 +669,22 @@ */ if ((a & ~DMA_MASK_MSTRPAGE)>>24 != MSTRPAGE_VALUE) { - BUG(); + ERROR("%s: pci busaddr inconsistency!\n", __FUNCTION__); + dump_stack(); return; } a &= DMA_MASK_MSTRPAGE; /* clear highbyte to make sure we won't write * to status - just in case MSTRPAGE_VALUE!=0 */ - rd->hw->rd_addr = a; + rd->hw->rd_addr = cpu_to_le32(a); wmb(); rd_set_status(rd, s); /* may pass ownership to the hardware */ } static inline void rd_set_count(struct ring_descr *rd, u16 c) { - rd->hw->rd_count = c; + rd->hw->rd_count = cpu_to_le16(c); } static inline u8 rd_get_status(struct ring_descr *rd) @@ -642,13 +696,13 @@ { dma_addr_t a; - a = (rd->hw->rd_addr & DMA_MASK_MSTRPAGE) | (MSTRPAGE_VALUE << 24); - return a; + a = le32_to_cpu(rd->hw->rd_addr); + return (a & DMA_MASK_MSTRPAGE) | (MSTRPAGE_VALUE << 24); } static inline u16 rd_get_count(struct ring_descr *rd) { - return rd->hw->rd_count; + return le16_to_cpu(rd->hw->rd_count); } /******************************************************************/ diff -Nru a/init/Kconfig b/init/Kconfig --- a/init/Kconfig Tue Sep 2 19:58:18 2003 +++ b/init/Kconfig Tue Sep 2 19:58:18 2003 @@ -32,16 +32,24 @@ you say Y here, you will be offered the choice of using features or drivers that are currently considered to be in the alpha-test phase. -config BROKEN - bool "Prompt for old and known-broken drivers" - depends on EXPERIMENTAL - default n +config CLEAN_COMPILE + bool "Don't select drivers known to be broken" if EXPERIMENTAL + default y help - This option allows you to choose whether you want to try to - compile (and fix) old drivers that haven't been updated to - new infrastructure. + Select this option if you don't even want to see the option + to configure known-broken drivers. + + If unsure, say Y + +config BROKEN + bool + depends on !CLEAN_COMPILE + default y - If unsure, say N. +config BROKEN_ON_SMP + bool + depends on BROKEN || !SMP + default y endmenu diff -Nru a/init/main.c b/init/main.c --- a/init/main.c Tue Sep 2 19:58:13 2003 +++ b/init/main.c Tue Sep 2 19:58:13 2003 @@ -89,10 +89,6 @@ extern void tc_init(void); #endif -#if defined(CONFIG_SYSVIPC) -extern void ipc_init(void); -#endif - /* * Are we up and running (ie do we have all the infrastructure * set up) @@ -106,6 +102,8 @@ #define MAX_INIT_ENVS 8 extern void time_init(void); +/* Default late time init is NULL. archs can override this later. */ +void (*late_time_init)(void) = NULL; extern void softirq_init(void); int rows, cols; @@ -421,7 +419,6 @@ console_init(); profile_init(); local_irq_enable(); - calibrate_delay(); #ifdef CONFIG_BLK_DEV_INITRD if (initrd_start && !initrd_below_start_ok && initrd_start < min_low_pfn << PAGE_SHIFT) { @@ -433,6 +430,9 @@ page_address_init(); mem_init(); kmem_cache_init(); + if (late_time_init) + late_time_init(); + calibrate_delay(); pidmap_init(); pgtable_cache_init(); pte_chain_init(); @@ -448,9 +448,6 @@ populate_rootfs(); #ifdef CONFIG_PROC_FS proc_root_init(); -#endif -#if defined(CONFIG_SYSVIPC) - ipc_init(); #endif check_bugs(); printk("POSIX conformance testing by UNIFIX\n"); diff -Nru a/ipc/msg.c b/ipc/msg.c --- a/ipc/msg.c Tue Sep 2 19:58:12 2003 +++ b/ipc/msg.c Tue Sep 2 19:58:12 2003 @@ -707,7 +707,7 @@ goto retry; } - msq->q_lspid = current->pid; + msq->q_lspid = current->tgid; msq->q_stime = get_seconds(); if(!pipelined_send(msq,msg)) { @@ -801,7 +801,7 @@ list_del(&msg->m_list); msq->q_qnum--; msq->q_rtime = get_seconds(); - msq->q_lrpid = current->pid; + msq->q_lrpid = current->tgid; msq->q_cbytes -= msg->m_ts; atomic_sub(msg->m_ts,&msg_bytes); atomic_dec(&msg_hdrs); diff -Nru a/ipc/sem.c b/ipc/sem.c --- a/ipc/sem.c Tue Sep 2 19:58:15 2003 +++ b/ipc/sem.c Tue Sep 2 19:58:15 2003 @@ -664,7 +664,7 @@ for (un = sma->undo; un; un = un->id_next) un->semadj[semnum] = 0; curr->semval = val; - curr->sempid = current->pid; + curr->sempid = current->tgid; sma->sem_ctime = get_seconds(); /* maybe some queued-up processes were waiting for this */ update_queue(sma); @@ -1052,7 +1052,7 @@ if (error) goto out_unlock_free; - error = try_atomic_semop (sma, sops, nsops, un, current->pid); + error = try_atomic_semop (sma, sops, nsops, un, current->tgid); if (error <= 0) goto update; @@ -1064,7 +1064,7 @@ queue.sops = sops; queue.nsops = nsops; queue.undo = un; - queue.pid = current->pid; + queue.pid = current->tgid; queue.id = semid; if (alter) append_to_queue(sma ,&queue); @@ -1206,7 +1206,7 @@ sem->semval += u->semadj[i]; if (sem->semval < 0) sem->semval = 0; /* shouldn't happen */ - sem->sempid = current->pid; + sem->sempid = current->tgid; } } sma->sem_otime = get_seconds(); diff -Nru a/ipc/shm.c b/ipc/shm.c --- a/ipc/shm.c Tue Sep 2 19:58:16 2003 +++ b/ipc/shm.c Tue Sep 2 19:58:16 2003 @@ -89,7 +89,7 @@ if(!(shp = shm_lock(id))) BUG(); shp->shm_atim = get_seconds(); - shp->shm_lprid = current->pid; + shp->shm_lprid = current->tgid; shp->shm_nattch++; shm_unlock(shp); } @@ -136,7 +136,7 @@ /* remove from the list of attaches of the shm segment */ if(!(shp = shm_lock(id))) BUG(); - shp->shm_lprid = current->pid; + shp->shm_lprid = current->tgid; shp->shm_dtim = get_seconds(); shp->shm_nattch--; if(shp->shm_nattch == 0 && @@ -209,7 +209,7 @@ if(id == -1) goto no_id; - shp->shm_cprid = current->pid; + shp->shm_cprid = current->tgid; shp->shm_lprid = 0; shp->shm_atim = shp->shm_dtim = 0; shp->shm_ctim = get_seconds(); diff -Nru a/ipc/util.c b/ipc/util.c --- a/ipc/util.c Tue Sep 2 19:58:15 2003 +++ b/ipc/util.c Tue Sep 2 19:58:15 2003 @@ -36,13 +36,14 @@ * memory are initialised */ -void __init ipc_init (void) +static int __init ipc_init(void) { sem_init(); msg_init(); shm_init(); - return; + return 0; } +__initcall(ipc_init); /** * ipc_init_ids - initialise IPC identifiers diff -Nru a/kernel/Makefile b/kernel/Makefile --- a/kernel/Makefile Tue Sep 2 19:58:14 2003 +++ b/kernel/Makefile Tue Sep 2 19:58:14 2003 @@ -20,9 +20,6 @@ obj-$(CONFIG_COMPAT) += compat.o obj-$(CONFIG_IKCONFIG) += configs.o -# files to be removed upon make clean -clean-files := ikconfig.h - ifneq ($(CONFIG_IA64),y) # According to Alan Modra , the -fno-omit-frame-pointer is # needed for x86 only. Why this used to be enabled for all architectures is beyond @@ -32,8 +29,12 @@ CFLAGS_sched.o := $(PROFILING) -fno-omit-frame-pointer endif -$(obj)/ikconfig.h: scripts/mkconfigs .config Makefile - $(CONFIG_SHELL) scripts/mkconfigs .config Makefile > $(obj)/ikconfig.h +quiet_cmd_ikconfig = IKCFG $@ + cmd_ikconfig = $(CONFIG_SHELL) $< .config $(srctree)/Makefile > $@ + +targets += ikconfig.h + +$(obj)/ikconfig.h: scripts/mkconfigs .config Makefile FORCE + $(call if_changed,ikconfig) -$(obj)/configs.o: $(obj)/ikconfig.h $(obj)/configs.c \ - include/linux/version.h include/linux/compile.h +$(obj)/configs.o: $(obj)/ikconfig.h diff -Nru a/kernel/compat.c b/kernel/compat.c --- a/kernel/compat.c Tue Sep 2 19:58:16 2003 +++ b/kernel/compat.c Tue Sep 2 19:58:16 2003 @@ -464,6 +464,7 @@ if (get_compat_itimerspec(&newts, new)) return -EFAULT; oldfs = get_fs(); + set_fs(KERNEL_DS); err = sys_timer_settime(timer_id, flags, &newts, &oldts); set_fs(oldfs); if (!err && old && put_compat_itimerspec(old, &oldts)) @@ -477,6 +478,7 @@ mm_segment_t oldfs; struct itimerspec ts; oldfs = get_fs(); + set_fs(KERNEL_DS); err = sys_timer_gettime(timer_id, &ts); set_fs(oldfs); if (!err && put_compat_itimerspec(setting, &ts)) @@ -494,7 +496,8 @@ struct timespec ts; if (get_compat_timespec(&ts, tp)) return -EFAULT; - oldfs = get_fs(); + oldfs = get_fs(); + set_fs(KERNEL_DS); err = sys_clock_settime(which_clock, &ts); set_fs(oldfs); return err; @@ -508,7 +511,8 @@ long err; mm_segment_t oldfs; struct timespec ts; - oldfs = get_fs(); + oldfs = get_fs(); + set_fs(KERNEL_DS); err = sys_clock_gettime(which_clock, &ts); set_fs(oldfs); if (!err && put_compat_timespec(&ts, tp)) @@ -524,7 +528,8 @@ long err; mm_segment_t oldfs; struct timespec ts; - oldfs = get_fs(); + oldfs = get_fs(); + set_fs(KERNEL_DS); err = sys_clock_getres(which_clock, &ts); set_fs(oldfs); if (!err && put_compat_timespec(&ts, tp)) @@ -546,7 +551,8 @@ struct timespec in, out; if (get_compat_timespec(&in, rqtp)) return -EFAULT; - oldfs = get_fs(); + oldfs = get_fs(); + set_fs(KERNEL_DS); err = sys_clock_nanosleep(which_clock, flags, &in, &out); set_fs(oldfs); if ((err == -ERESTART_RESTARTBLOCK) && rmtp && diff -Nru a/kernel/exit.c b/kernel/exit.c --- a/kernel/exit.c Tue Sep 2 19:58:18 2003 +++ b/kernel/exit.c Tue Sep 2 19:58:18 2003 @@ -80,6 +80,8 @@ p->parent->cmin_flt += p->min_flt + p->cmin_flt; p->parent->cmaj_flt += p->maj_flt + p->cmaj_flt; p->parent->cnswap += p->nswap + p->cnswap; + p->parent->cnvcsw += p->nvcsw + p->cnvcsw; + p->parent->cnivcsw += p->nivcsw + p->cnivcsw; sched_exit(p); write_unlock_irq(&tasklist_lock); spin_unlock(&p->proc_lock); diff -Nru a/kernel/fork.c b/kernel/fork.c --- a/kernel/fork.c Tue Sep 2 19:58:13 2003 +++ b/kernel/fork.c Tue Sep 2 19:58:13 2003 @@ -461,6 +461,7 @@ tsk->min_flt = tsk->maj_flt = 0; tsk->cmin_flt = tsk->cmaj_flt = 0; tsk->nswap = tsk->cnswap = 0; + tsk->nvcsw = tsk->nivcsw = tsk->cnvcsw = tsk->cnivcsw = 0; tsk->mm = NULL; tsk->active_mm = NULL; diff -Nru a/kernel/futex.c b/kernel/futex.c --- a/kernel/futex.c Tue Sep 2 19:58:14 2003 +++ b/kernel/futex.c Tue Sep 2 19:58:14 2003 @@ -28,6 +28,7 @@ */ #include #include +#include #include #include #include @@ -60,8 +61,6 @@ /* The key for the hash is the address + index + offset within page */ static struct list_head futex_queues[1<pos) reset_iter(iter); - /* We need to iterate through the previous symbols. */ - for (; iter->pos <= pos; iter->pos++) + /* We need to iterate through the previous symbols: can be slow */ + for (; iter->pos != pos; iter->pos++) { get_ksymbol_core(iter); + cond_resched(); + } return 1; } @@ -280,8 +282,7 @@ { struct proc_dir_entry *entry; - /* root-only: could chew up lots of cpu by read, seek back, read... */ - entry = create_proc_entry("kallsyms", 0400, NULL); + entry = create_proc_entry("kallsyms", 0444, NULL); if (entry) entry->proc_fops = &kallsyms_operations; return 0; diff -Nru a/kernel/ksyms.c b/kernel/ksyms.c --- a/kernel/ksyms.c Tue Sep 2 19:58:12 2003 +++ b/kernel/ksyms.c Tue Sep 2 19:58:12 2003 @@ -120,7 +120,6 @@ EXPORT_SYMBOL(max_mapnr); #endif EXPORT_SYMBOL(high_memory); -EXPORT_SYMBOL_GPL(invalidate_mmap_range); EXPORT_SYMBOL(vmtruncate); EXPORT_SYMBOL(find_vma); EXPORT_SYMBOL(get_unmapped_area); @@ -198,7 +197,6 @@ EXPORT_SYMBOL(invalidate_inode_pages); EXPORT_SYMBOL_GPL(invalidate_inode_pages2); EXPORT_SYMBOL(truncate_inode_pages); -EXPORT_SYMBOL(install_page); EXPORT_SYMBOL(fsync_bdev); EXPORT_SYMBOL(permission); EXPORT_SYMBOL(vfs_permission); diff -Nru a/kernel/posix-timers.c b/kernel/posix-timers.c --- a/kernel/posix-timers.c Tue Sep 2 19:58:16 2003 +++ b/kernel/posix-timers.c Tue Sep 2 19:58:16 2003 @@ -948,11 +948,15 @@ */ static int do_posix_gettime(struct k_clock *clock, struct timespec *tp) { + struct timeval tv; + if (clock->clock_get) return clock->clock_get(tp); - do_gettimeofday((struct timeval *) tp); - tp->tv_nsec *= NSEC_PER_USEC; + do_gettimeofday(&tv); + tp->tv_sec = tv.tv_sec; + tp->tv_nsec = tv.tv_usec * NSEC_PER_USEC; + return 0; } diff -Nru a/kernel/sched.c b/kernel/sched.c --- a/kernel/sched.c Tue Sep 2 19:58:18 2003 +++ b/kernel/sched.c Tue Sep 2 19:58:18 2003 @@ -1325,8 +1325,10 @@ } default: deactivate_task(prev, rq); + prev->nvcsw++; + break; case TASK_RUNNING: - ; + prev->nivcsw++; } pick_next_task: if (unlikely(!rq->nr_running)) { diff -Nru a/kernel/sys.c b/kernel/sys.c --- a/kernel/sys.c Tue Sep 2 19:58:13 2003 +++ b/kernel/sys.c Tue Sep 2 19:58:13 2003 @@ -1309,6 +1309,8 @@ case RUSAGE_SELF: jiffies_to_timeval(p->utime, &r.ru_utime); jiffies_to_timeval(p->stime, &r.ru_stime); + r.ru_nvcsw = p->nvcsw; + r.ru_nivcsw = p->nivcsw; r.ru_minflt = p->min_flt; r.ru_majflt = p->maj_flt; r.ru_nswap = p->nswap; @@ -1316,6 +1318,8 @@ case RUSAGE_CHILDREN: jiffies_to_timeval(p->cutime, &r.ru_utime); jiffies_to_timeval(p->cstime, &r.ru_stime); + r.ru_nvcsw = p->cnvcsw; + r.ru_nivcsw = p->cnivcsw; r.ru_minflt = p->cmin_flt; r.ru_majflt = p->cmaj_flt; r.ru_nswap = p->cnswap; @@ -1323,6 +1327,8 @@ default: jiffies_to_timeval(p->utime + p->cutime, &r.ru_utime); jiffies_to_timeval(p->stime + p->cstime, &r.ru_stime); + r.ru_nvcsw = p->nvcsw + p->cnvcsw; + r.ru_nivcsw = p->nivcsw + p->cnivcsw; r.ru_minflt = p->min_flt + p->cmin_flt; r.ru_majflt = p->maj_flt + p->cmaj_flt; r.ru_nswap = p->nswap + p->cnswap; diff -Nru a/kernel/timer.c b/kernel/timer.c --- a/kernel/timer.c Tue Sep 2 19:58:18 2003 +++ b/kernel/timer.c Tue Sep 2 19:58:18 2003 @@ -338,6 +338,7 @@ break; } } + smp_rmb(); if (timer_pending(timer)) goto del_again; diff -Nru a/mm/fremap.c b/mm/fremap.c --- a/mm/fremap.c Tue Sep 2 19:58:12 2003 +++ b/mm/fremap.c Tue Sep 2 19:58:12 2003 @@ -3,7 +3,7 @@ * * Explicit pagetable population and nonlinear (random) mappings support. * - * started by Ingo Molnar, Copyright (C) 2002 + * started by Ingo Molnar, Copyright (C) 2002, 2003 */ #include @@ -13,6 +13,8 @@ #include #include #include +#include + #include #include #include @@ -95,6 +97,8 @@ err: return err; } +EXPORT_SYMBOL(install_page); + /*** * sys_remap_file_pages - remap arbitrary pages of a shared backing store diff -Nru a/mm/memory.c b/mm/memory.c --- a/mm/memory.c Tue Sep 2 19:58:15 2003 +++ b/mm/memory.c Tue Sep 2 19:58:15 2003 @@ -45,6 +45,7 @@ #include #include #include +#include #include #include @@ -810,17 +811,18 @@ static inline int zeromap_pmd_range(struct mm_struct *mm, pmd_t * pmd, unsigned long address, unsigned long size, pgprot_t prot) { - unsigned long end; + unsigned long base, end; + base = address & PGDIR_MASK; address &= ~PGDIR_MASK; end = address + size; if (end > PGDIR_SIZE) end = PGDIR_SIZE; do { - pte_t * pte = pte_alloc_map(mm, pmd, address); + pte_t * pte = pte_alloc_map(mm, pmd, base + address); if (!pte) return -ENOMEM; - zeromap_pte_range(pte, address, end - address, prot); + zeromap_pte_range(pte, base + address, end - address, prot); pte_unmap(pte); address = (address + PMD_SIZE) & PMD_MASK; pmd++; @@ -1138,6 +1140,7 @@ invalidate_mmap_range_list(&mapping->i_mmap_shared, hba, hlen); up(&mapping->i_shared_sem); } +EXPORT_SYMBOL_GPL(invalidate_mmap_range); /* * Handle all mappings that got truncated by a "truncate()" @@ -1384,10 +1387,10 @@ unsigned long address, int write_access, pte_t *page_table, pmd_t *pmd) { struct page * new_page; - struct address_space *mapping; + struct address_space *mapping = NULL; pte_t entry; struct pte_chain *pte_chain; - int sequence; + int sequence = 0; int ret; if (!vma->vm_ops || !vma->vm_ops->nopage) @@ -1396,8 +1399,10 @@ pte_unmap(page_table); spin_unlock(&mm->page_table_lock); - mapping = vma->vm_file->f_dentry->d_inode->i_mapping; - sequence = atomic_read(&mapping->truncate_count); + if (vma->vm_file) { + mapping = vma->vm_file->f_dentry->d_inode->i_mapping; + sequence = atomic_read(&mapping->truncate_count); + } smp_rmb(); /* Prevent CPU from reordering lock-free ->nopage() */ retry: new_page = vma->vm_ops->nopage(vma, address & PAGE_MASK, 0); @@ -1433,7 +1438,8 @@ * invalidated this page. If invalidate_mmap_range got called, * retry getting the page. */ - if (unlikely(sequence != atomic_read(&mapping->truncate_count))) { + if (mapping && + (unlikely(sequence != atomic_read(&mapping->truncate_count)))) { sequence = atomic_read(&mapping->truncate_count); spin_unlock(&mm->page_table_lock); page_cache_release(new_page); @@ -1453,7 +1459,8 @@ */ /* Only go through if we didn't race with anybody else... */ if (pte_none(*page_table)) { - ++mm->rss; + if (!PageReserved(new_page)) + ++mm->rss; flush_icache_page(vma, new_page); entry = mk_pte(new_page, vma->vm_page_prot); if (write_access) diff -Nru a/mm/swapfile.c b/mm/swapfile.c --- a/mm/swapfile.c Tue Sep 2 19:58:14 2003 +++ b/mm/swapfile.c Tue Sep 2 19:58:14 2003 @@ -1403,7 +1403,8 @@ p->max = maxpages; p->pages = nr_good_pages; - if (setup_swap_extents(p)) + error = setup_swap_extents(p); + if (error) goto bad_swap; swap_list_lock(); diff -Nru a/mm/vmscan.c b/mm/vmscan.c --- a/mm/vmscan.c Tue Sep 2 19:58:13 2003 +++ b/mm/vmscan.c Tue Sep 2 19:58:13 2003 @@ -80,25 +80,6 @@ #endif /* - * exponentially decaying average - */ -static inline int expavg(int avg, int val) -{ - return ((val - avg) >> 1) + avg; -} - -static void zone_adj_pressure(struct zone *zone, int priority) -{ - zone->pressure = expavg(zone->pressure, - (DEF_PRIORITY - priority) << 10); -} - -static int pressure_to_priority(int pressure) -{ - return DEF_PRIORITY - (pressure >> 10); -} - -/* * The list of shrinker callbacks used by to apply pressure to * ageable caches. */ @@ -646,7 +627,7 @@ * `distress' is a measure of how much trouble we're having reclaiming * pages. 0 -> no problems. 100 -> great trouble. */ - distress = 100 >> pressure_to_priority(zone->pressure); + distress = 100 >> zone->prev_priority; /* * The point of this algorithm is to decide when to start reclaiming @@ -830,6 +811,9 @@ int nr_mapped = 0; int max_scan; + if (zone->free_pages < zone->pages_high) + zone->temp_priority = priority; + if (zone->all_unreclaimable && priority != DEF_PRIORITY) continue; /* Let kswapd poll it */ @@ -843,10 +827,8 @@ ret += shrink_zone(zone, max_scan, gfp_mask, to_reclaim, &nr_mapped, ps, priority); *total_scanned += max_scan + nr_mapped; - if (ret >= nr_pages) { - zone_adj_pressure(zone, priority); + if (ret >= nr_pages) break; - } } return ret; } @@ -880,6 +862,9 @@ inc_page_state(allocstall); + for (zone = cz; zone >= cz->zone_pgdat->node_zones; --zone) + zone->temp_priority = DEF_PRIORITY; + for (priority = DEF_PRIORITY; priority >= 0; priority--) { int total_scanned = 0; struct page_state ps; @@ -912,9 +897,9 @@ } if ((gfp_mask & __GFP_FS) && !(gfp_mask & __GFP_NORETRY)) out_of_memory(); - for (zone = cz; zone >= cz->zone_pgdat->node_zones; -- zone) - zone_adj_pressure(zone, -1); out: + for (zone = cz; zone >= cz->zone_pgdat->node_zones; --zone) + zone->prev_priority = zone->temp_priority; return ret; } @@ -945,6 +930,12 @@ inc_page_state(pageoutrun); + for (i = 0; i < pgdat->nr_zones; i++) { + struct zone *zone = pgdat->node_zones + i; + + zone->temp_priority = DEF_PRIORITY; + } + for (priority = DEF_PRIORITY; priority; priority--) { int all_zones_ok = 1; @@ -961,11 +952,10 @@ to_reclaim = min(to_free, SWAP_CLUSTER_MAX*8); } else { /* Zone balancing */ to_reclaim = zone->pages_high-zone->free_pages; - if (to_reclaim <= 0) { - zone_adj_pressure(zone, priority); + if (to_reclaim <= 0) continue; - } } + zone->temp_priority = priority; all_zones_ok = 0; max_scan = zone->nr_inactive >> priority; if (max_scan < to_reclaim * 2) @@ -989,13 +979,11 @@ if (to_free > 0) blk_congestion_wait(WRITE, HZ/10); } - if (priority < 0) { - for (i = 0; i < pgdat->nr_zones; i++) { - struct zone *zone = pgdat->node_zones + i; - if (zone->free_pages < zone->pages_high) - zone_adj_pressure(zone, -1); - } + for (i = 0; i < pgdat->nr_zones; i++) { + struct zone *zone = pgdat->node_zones + i; + + zone->prev_priority = zone->temp_priority; } return nr_pages - to_free; } diff -Nru a/net/Kconfig b/net/Kconfig --- a/net/Kconfig Tue Sep 2 19:58:13 2003 +++ b/net/Kconfig Tue Sep 2 19:58:13 2003 @@ -191,9 +191,11 @@ information. If you enable iptables support along with the bridge support then you - turn your bridge into a bridging firewall. + turn your bridge into a bridging IP firewall. iptables will then see the IP packets being bridged, so you need to take this into account when setting up your firewall rules. + Enabling arptables support when bridging will let arptables see + bridged ARP traffic in the arptables FORWARD chain. If you want to compile this code as a module ( = code which can be inserted in and removed from the running kernel whenever you want), @@ -243,6 +245,12 @@ box can transparently forward the traffic to a local server, typically a caching proxy server. + Yet another use of Netfilter is building a bridging firewall. Using + a bridge with Network packet filtering enabled makes iptables "see" + the bridged traffic. For filtering on the lower network and Ethernet + protocols over the bridge, use ebtables (under bridge netfilter + configuration). + Various modules exist for netfilter which replace the previous masquerading (ipmasqadm), packet filtering (ipchains), transparent proxying, and portforwarding mechanisms. Please see @@ -263,6 +271,19 @@ help You can say Y here if you want to get additional messages useful in debugging the netfilter code. + +config BRIDGE_NETFILTER + bool "Bridged IP/ARP packets filtering" + depends on BRIDGE && NETFILTER && INET + default y + ---help--- + Enabling this option will let arptables resp. iptables see bridged + ARP resp. IP traffic. If you want a bridging firewall, you probably + want this option enabled. + Enabling or disabling this option doesn't enable or disable + ebtables. + + If unsure, say N. source "net/ipv4/netfilter/Kconfig" source "net/ipv6/netfilter/Kconfig" diff -Nru a/net/appletalk/aarp.c b/net/appletalk/aarp.c --- a/net/appletalk/aarp.c Tue Sep 2 19:58:19 2003 +++ b/net/appletalk/aarp.c Tue Sep 2 19:58:19 2003 @@ -37,6 +37,7 @@ #include #include #include +#include int sysctl_aarp_expiry_time = AARP_EXPIRY_TIME; int sysctl_aarp_tick_time = AARP_TICK_TIME; @@ -145,6 +146,7 @@ aarp_dl->request(aarp_dl, skb, aarp_eth_multicast); /* Update the sending count */ a->xmit_count++; + a->last_sent = jiffies; } /* This runs under aarp_lock and in softint context, so only atomic memory @@ -338,6 +340,32 @@ return NOTIFY_DONE; } +/* Expire all entries in a hash chain */ +static void __aarp_expire_all(struct aarp_entry **n) +{ + struct aarp_entry *t; + + while (*n) { + t = *n; + *n = (*n)->next; + __aarp_expire(t); + } +} + +/* Cleanup all hash chains -- module unloading */ +static void aarp_purge(void) +{ + int ct; + + write_lock_bh(&aarp_lock); + for (ct = 0; ct < AARP_HASH_SIZE; ct++) { + __aarp_expire_all(&resolved[ct]); + __aarp_expire_all(&unresolved[ct]); + __aarp_expire_all(&proxies[ct]); + } + write_unlock_bh(&aarp_lock); +} + /* * Create a new aarp entry. This must use GFP_ATOMIC because it * runs while holding spinlocks. @@ -861,112 +889,181 @@ write_unlock_bh(&aarp_lock); } -/* Called from proc fs */ -static int aarp_get_info(char *buffer, char **start, off_t offset, int length) +#ifdef CONFIG_PROC_FS +struct aarp_iter_state { + int bucket; + struct aarp_entry **table; +}; + +/* + * Get the aarp entry that is in the chain described + * by the iterator. + * If pos is set then skip till that index. + * pos = 1 is the first entry + */ +static struct aarp_entry *iter_next(struct aarp_iter_state *iter, loff_t *pos) { - /* we should dump all our AARP entries */ + int ct = iter->bucket; + struct aarp_entry **table = iter->table; + loff_t off = 0; struct aarp_entry *entry; - int ct, len = sprintf(buffer, - "%-10.10s %-10.10s%-18.18s%12.12s%12.12s " - "xmit_count status\n", - "address", "device", "hw addr", "last_sent", - "expires"); + + rescan: + while(ct < AARP_HASH_SIZE) { + for (entry = table[ct]; entry; entry = entry->next) { + if (!pos || ++off == *pos) { + iter->table = table; + iter->bucket = ct; + return entry; + } + } + ++ct; + } + + if (table == resolved) { + ct = 0; + table = unresolved; + goto rescan; + } + if (table == unresolved) { + ct = 0; + table = proxies; + goto rescan; + } + return NULL; +} + +static void *aarp_seq_start(struct seq_file *seq, loff_t *pos) +{ + struct aarp_iter_state *iter = seq->private; read_lock_bh(&aarp_lock); + iter->table = resolved; + iter->bucket = 0; - for (ct = 0; ct < AARP_HASH_SIZE; ct++) { - for (entry = resolved[ct]; entry; entry = entry->next) { - len += sprintf(buffer + len, "%6u:%-3u ", - (unsigned int)ntohs(entry->target_addr.s_net), - (unsigned int)(entry->target_addr.s_node)); - len += sprintf(buffer + len, "%-10.10s", - entry->dev->name); - len += sprintf(buffer + len, - "%2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X", - (int)(entry->hwaddr[0] & 0x000000FF), - (int)(entry->hwaddr[1] & 0x000000FF), - (int)(entry->hwaddr[2] & 0x000000FF), - (int)(entry->hwaddr[3] & 0x000000FF), - (int)(entry->hwaddr[4] & 0x000000FF), - (int)(entry->hwaddr[5] & 0x000000FF)); - len += sprintf(buffer + len, "%12lu ""%12lu ", - (unsigned long)entry->last_sent, - (unsigned long)entry->expires_at); - len += sprintf(buffer + len, "%10u", - (unsigned int)entry->xmit_count); + return *pos ? iter_next(iter, pos) : ((void *)1); +} - len += sprintf(buffer + len, " resolved\n"); - } - } +static void *aarp_seq_next(struct seq_file *seq, void *v, loff_t *pos) +{ + struct aarp_entry *entry = v; + struct aarp_iter_state *iter = seq->private; - for (ct = 0; ct < AARP_HASH_SIZE; ct++) { - for (entry = unresolved[ct]; entry; entry = entry->next) { - len += sprintf(buffer + len, "%6u:%-3u ", - (unsigned int)ntohs(entry->target_addr.s_net), - (unsigned int)(entry->target_addr.s_node)); - len += sprintf(buffer + len, "%-10.10s", - entry->dev->name); - len += sprintf(buffer + len, - "%2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X", - (int)(entry->hwaddr[0] & 0x000000FF), - (int)(entry->hwaddr[1] & 0x000000FF), - (int)(entry->hwaddr[2] & 0x000000FF), - (int)(entry->hwaddr[3] & 0x000000FF), - (int)(entry->hwaddr[4] & 0x000000FF), - (int)(entry->hwaddr[5] & 0x000000FF)); - len += sprintf(buffer + len, "%12lu ""%12lu ", - (unsigned long)entry->last_sent, - (unsigned long)entry->expires_at); - len += sprintf(buffer + len, "%10u", - (unsigned int)entry->xmit_count); - len += sprintf(buffer + len, " unresolved\n"); - } - } + ++*pos; - for (ct = 0; ct < AARP_HASH_SIZE; ct++) { - for (entry = proxies[ct]; entry; entry = entry->next) { - len += sprintf(buffer + len, "%6u:%-3u ", - (unsigned int)ntohs(entry->target_addr.s_net), - (unsigned int)(entry->target_addr.s_node)); - len += sprintf(buffer + len, "%-10.10s", - entry->dev->name); - len += sprintf(buffer + len, - "%2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X", - (int)(entry->hwaddr[0] & 0x000000FF), - (int)(entry->hwaddr[1] & 0x000000FF), - (int)(entry->hwaddr[2] & 0x000000FF), - (int)(entry->hwaddr[3] & 0x000000FF), - (int)(entry->hwaddr[4] & 0x000000FF), - (int)(entry->hwaddr[5] & 0x000000FF)); - len += sprintf(buffer + len, "%12lu ""%12lu ", - (unsigned long)entry->last_sent, - (unsigned long)entry->expires_at); - len += sprintf(buffer + len, "%10u", - (unsigned int)entry->xmit_count); - len += sprintf(buffer + len, " proxy\n"); - } + /* first line after header */ + if (v == ((void *)1)) + entry = iter_next(iter, NULL); + + /* next entry in current bucket */ + else if (entry->next) + entry = entry->next; + + /* next bucket or table */ + else { + ++iter->bucket; + entry = iter_next(iter, NULL); } + return entry; +} +static void aarp_seq_stop(struct seq_file *seq, void *v) +{ read_unlock_bh(&aarp_lock); - return len; } -/* General module cleanup. Called from cleanup_module() in ddp.c. */ -void aarp_cleanup_module(void) +static const char *dt2str(unsigned long ticks) { - del_timer(&aarp_timer); - unregister_netdevice_notifier(&aarp_notifier); - unregister_snap_client(aarp_dl); + static char buf[32]; + + sprintf(buf, "%ld.%02ld", ticks / HZ, ((ticks % HZ) * 100 ) / HZ); + + return buf; } -#ifdef CONFIG_PROC_FS -void aarp_register_proc_fs(void) +static int aarp_seq_show(struct seq_file *seq, void *v) { - proc_net_create("aarp", 0, aarp_get_info); + struct aarp_iter_state *iter = seq->private; + struct aarp_entry *entry = v; + unsigned long now = jiffies; + + if (v == ((void *)1)) + seq_puts(seq, + "Address Interface Hardware Address" + " Expires LastSend Retry Status\n"); + else { + seq_printf(seq, "%04X:%02X %-12s", + ntohs(entry->target_addr.s_net), + (unsigned int) entry->target_addr.s_node, + entry->dev ? entry->dev->name : "????"); + seq_printf(seq, "%02X:%02X:%02X:%02X:%02X:%02X", + entry->hwaddr[0] & 0xFF, + entry->hwaddr[1] & 0xFF, + entry->hwaddr[2] & 0xFF, + entry->hwaddr[3] & 0xFF, + entry->hwaddr[4] & 0xFF, + entry->hwaddr[5] & 0xFF); + seq_printf(seq, " %8s", + dt2str((long)entry->expires_at - (long)now)); + if (iter->table == unresolved) + seq_printf(seq, " %8s %6hu", + dt2str(now - entry->last_sent), + entry->xmit_count); + else + seq_puts(seq, " "); + seq_printf(seq, " %s\n", + (iter->table == resolved) ? "resolved" + : (iter->table == unresolved) ? "unresolved" + : (iter->table == proxies) ? "proxies" + : "unknown"); + } + return 0; } -void aarp_unregister_proc_fs(void) +static struct seq_operations aarp_seq_ops = { + .start = aarp_seq_start, + .next = aarp_seq_next, + .stop = aarp_seq_stop, + .show = aarp_seq_show, +}; + +static int aarp_seq_open(struct inode *inode, struct file *file) { - proc_net_remove("aarp"); + struct seq_file *seq; + int rc = -ENOMEM; + struct aarp_iter_state *s = kmalloc(sizeof(*s), GFP_KERNEL); + + if (!s) + goto out; + + rc = seq_open(file, &aarp_seq_ops); + if (rc) + goto out_kfree; + + seq = file->private_data; + seq->private = s; + memset(s, 0, sizeof(*s)); +out: + return rc; +out_kfree: + kfree(s); + goto out; } + +struct file_operations atalk_seq_arp_fops = { + .owner = THIS_MODULE, + .open = aarp_seq_open, + .read = seq_read, + .llseek = seq_lseek, + .release = seq_release_private, +}; #endif + +/* General module cleanup. Called from cleanup_module() in ddp.c. */ +void aarp_cleanup_module(void) +{ + del_timer_sync(&aarp_timer); + unregister_netdevice_notifier(&aarp_notifier); + unregister_snap_client(aarp_dl); + aarp_purge(); +} diff -Nru a/net/appletalk/atalk_proc.c b/net/appletalk/atalk_proc.c --- a/net/appletalk/atalk_proc.c Tue Sep 2 19:58:18 2003 +++ b/net/appletalk/atalk_proc.c Tue Sep 2 19:58:18 2003 @@ -16,6 +16,8 @@ #include #ifdef CONFIG_PROC_FS +extern struct file_operations atalk_seq_arp_fops; + static __inline__ struct atalk_iface *atalk_get_interface_idx(loff_t pos) { struct atalk_iface *i; @@ -61,7 +63,7 @@ struct atalk_iface *iface; if (v == (void *)1) { - seq_puts(seq, "Interface Address Networks " + seq_puts(seq, "Interface Address Networks " "Status\n"); goto out; } @@ -275,6 +277,7 @@ atalk_proc_dir = proc_mkdir("atalk", proc_net); if (!atalk_proc_dir) goto out; + atalk_proc_dir->owner = THIS_MODULE; p = create_proc_entry("interface", S_IRUGO, atalk_proc_dir); if (!p) @@ -291,9 +294,16 @@ goto out_socket; p->proc_fops = &atalk_seq_socket_fops; + p = create_proc_entry("arp", S_IRUGO, atalk_proc_dir); + if (!p) + goto out_arp; + p->proc_fops = &atalk_seq_arp_fops; + rc = 0; out: return rc; +out_arp: + remove_proc_entry("socket", atalk_proc_dir); out_socket: remove_proc_entry("route", atalk_proc_dir); out_route: @@ -308,6 +318,7 @@ remove_proc_entry("interface", atalk_proc_dir); remove_proc_entry("route", atalk_proc_dir); remove_proc_entry("socket", atalk_proc_dir); + remove_proc_entry("arp", atalk_proc_dir); remove_proc_entry("atalk", proc_net); } diff -Nru a/net/appletalk/ddp.c b/net/appletalk/ddp.c --- a/net/appletalk/ddp.c Tue Sep 2 19:58:20 2003 +++ b/net/appletalk/ddp.c Tue Sep 2 19:58:20 2003 @@ -61,11 +61,6 @@ #include #include -#ifdef CONFIG_PROC_FS -extern void aarp_register_proc_fs(void); -extern void aarp_unregister_proc_fs(void); -#endif - extern void aarp_cleanup_module(void); extern void aarp_probe_network(struct atalk_iface *atif); @@ -183,13 +178,12 @@ { struct sock *sk = (struct sock *)data; - if (!atomic_read(&sk->sk_wmem_alloc) && - !atomic_read(&sk->sk_rmem_alloc) && sock_flag(sk, SOCK_DEAD)) - sock_put(sk); - else { + if (atomic_read(&sk->sk_wmem_alloc) || + atomic_read(&sk->sk_rmem_alloc)) { sk->sk_timer.expires = jiffies + SOCK_DESTROY_TIME; add_timer(&sk->sk_timer); - } + } else + sock_put(sk); } static inline void atalk_destroy_socket(struct sock *sk) @@ -197,16 +191,15 @@ atalk_remove_socket(sk); skb_queue_purge(&sk->sk_receive_queue); - if (!atomic_read(&sk->sk_wmem_alloc) && - !atomic_read(&sk->sk_rmem_alloc) && sock_flag(sk, SOCK_DEAD)) - sock_put(sk); - else { + if (atomic_read(&sk->sk_wmem_alloc) || + atomic_read(&sk->sk_rmem_alloc)) { init_timer(&sk->sk_timer); sk->sk_timer.expires = jiffies + SOCK_DESTROY_TIME; sk->sk_timer.function = atalk_destroy_timer; sk->sk_timer.data = (unsigned long)sk; add_timer(&sk->sk_timer); - } + } else + sock_put(sk); } /**************************************************************************\ @@ -239,6 +232,7 @@ while ((tmp = *iface) != NULL) { if (tmp->dev == dev) { *iface = tmp->next; + dev_put(dev); kfree(tmp); dev->atalk_ptr = NULL; } else @@ -255,6 +249,7 @@ if (!iface) goto out; + dev_hold(dev); iface->dev = dev; dev->atalk_ptr = iface; iface->address = *sa; @@ -616,6 +611,7 @@ (!(tmp->flags&RTF_GATEWAY) || tmp->target.s_node == addr->s_node)) { *r = tmp->next; + dev_put(tmp->dev); kfree(tmp); goto out; } @@ -640,6 +636,7 @@ while ((tmp = *r) != NULL) { if (tmp->dev == dev) { *r = tmp->next; + dev_put(dev); kfree(tmp); } else r = &tmp->next; @@ -935,24 +932,95 @@ * Checksum: This is 'optional'. It's quite likely also a good * candidate for assembler hackery 8) */ -unsigned short atalk_checksum(struct ddpehdr *ddp, int len) +static unsigned long atalk_sum_partial(const unsigned char *data, + int len, unsigned long sum) { - unsigned long sum = 0; /* Assume unsigned long is >16 bits */ - unsigned char *data = (unsigned char *)ddp; - - len -= 4; /* skip header 4 bytes */ - data += 4; - /* This ought to be unwrapped neatly. I'll trust gcc for now */ while (len--) { - sum += *data; + sum += *data++; sum <<= 1; - if (sum & 0x10000) { - sum++; - sum &= 0xFFFF; + sum = ((sum >> 16) + sum) & 0xFFFF; + } + return sum; +} + +/* Checksum skb data -- similar to skb_checksum */ +static unsigned long atalk_sum_skb(const struct sk_buff *skb, int offset, + int len, unsigned long sum) +{ + int start = skb_headlen(skb); + int i, copy; + + /* checksum stuff in header space */ + if ( (copy = start - offset) > 0) { + if (copy > len) + copy = len; + sum = atalk_sum_partial(skb->data + offset, copy, sum); + if ( (len -= copy) == 0) + return sum; + + offset += copy; + } + + /* checksum stuff in frags */ + for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { + int end; + + BUG_TRAP(start <= offset + len); + + end = start + skb_shinfo(skb)->frags[i].size; + if ((copy = end - offset) > 0) { + u8 *vaddr; + skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; + + if (copy > len) + copy = len; + vaddr = kmap_skb_frag(frag); + sum = atalk_sum_partial(vaddr + frag->page_offset + + offset - start, copy, sum); + kunmap_skb_frag(vaddr); + + if (!(len -= copy)) + return sum; + offset += copy; + } + start = end; + } + + if (skb_shinfo(skb)->frag_list) { + struct sk_buff *list = skb_shinfo(skb)->frag_list; + + for (; list; list = list->next) { + int end; + + BUG_TRAP(start <= offset + len); + + end = start + list->len; + if ((copy = end - offset) > 0) { + if (copy > len) + copy = len; + sum = atalk_sum_skb(list, offset - start, + copy, sum); + if ((len -= copy) == 0) + return sum; + offset += copy; + } + start = end; } - data++; } + + BUG_ON(len > 0); + + return sum; +} + +static unsigned short atalk_checksum(const struct sk_buff *skb, int len) +{ + unsigned long sum; + + /* skip header 4 bytes */ + sum = atalk_sum_skb(skb, 4, len-4, 0); + /* Use 0xFFFF for 0. 0 itself means none */ return sum ? htons((unsigned short)sum) : 0xFFFF; } @@ -983,6 +1051,8 @@ rc = 0; sock->ops = &atalk_dgram_ops; sock_init_data(sock, sk); + sk_set_owner(sk, THIS_MODULE); + /* Checksums on by default */ sk->sk_zapped = 1; out: @@ -998,10 +1068,7 @@ struct sock *sk = sock->sk; if (sk) { - if (!sock_flag(sk, SOCK_DEAD)) { - sk->sk_state_change(sk); - sock_set_flag(sk, SOCK_DEAD); - } + sock_orphan(sk); sock->sk = NULL; atalk_destroy_socket(sk); } @@ -1335,25 +1402,27 @@ static int atalk_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt) { - struct ddpehdr *ddp = ddp_hdr(skb); + struct ddpehdr *ddp; struct sock *sock; struct atalk_iface *atif; struct sockaddr_at tosat; int origlen; struct ddpebits ddphv; - /* Size check */ - if (skb->len < sizeof(*ddp)) + /* Don't mangle buffer if shared */ + if (!(skb = skb_share_check(skb, GFP_ATOMIC))) + goto out; + + /* Size check and make sure header is contiguous */ + if (!pskb_may_pull(skb, sizeof(*ddp))) goto freeit; + ddp = ddp_hdr(skb); + /* * Fix up the length field [Ok this is horrible but otherwise * I end up with unions of bit fields and messy bit field order * compiler/endian dependencies..] - * - * FIXME: This is a write to a shared object. Granted it - * happens to be safe BUT.. (Its safe as user space will not - * run until we put it back) */ *((__u16 *)&ddphv) = ntohs(*((__u16 *)ddp)); @@ -1374,7 +1443,7 @@ * valid for net byte orders all over the networking code... */ if (ddp->deh_sum && - atalk_checksum(ddp, ddphv.deh_len) != ddp->deh_sum) + atalk_checksum(skb, ddphv.deh_len) != ddp->deh_sum) /* Not a valid AppleTalk frame - dustbin time */ goto freeit; @@ -1433,14 +1502,16 @@ if (!ap || skb->len < sizeof(struct ddpshdr)) goto freeit; + + /* Don't mangle buffer if shared */ + if (!(skb = skb_share_check(skb, GFP_ATOMIC))) + return 0; + /* * The push leaves us with a ddephdr not an shdr, and * handily the port bytes in the right place preset. */ - - skb_push(skb, sizeof(*ddp) - 4); - /* FIXME: use skb->cb to be able to use shared skbs */ - ddp = (struct ddpehdr *)skb->data; + ddp = (struct ddpehdr *) skb_push(skb, sizeof(*ddp) - 4); /* Now fill in the long header */ @@ -1592,7 +1663,7 @@ if (sk->sk_no_check == 1) ddp->deh_sum = 0; else - ddp->deh_sum = atalk_checksum(ddp, len + sizeof(*ddp)); + ddp->deh_sum = atalk_checksum(skb, len + sizeof(*ddp)); /* * Loopback broadcast packets to non gateway targets (ie routes @@ -1801,11 +1872,13 @@ struct packet_type ltalk_packet_type = { .type = __constant_htons(ETH_P_LOCALTALK), .func = ltalk_rcv, + .data = (void *)1, }; struct packet_type ppptalk_packet_type = { .type = __constant_htons(ETH_P_PPPTALK), .func = atalk_rcv, + .data = (void *)1, }; static unsigned char ddp_snap_id[] = { 0x08, 0x00, 0x07, 0x80, 0x9B }; @@ -1834,9 +1907,6 @@ register_netdevice_notifier(&ddp_notifier); aarp_proto_init(); atalk_proc_init(); -#ifdef CONFIG_PROC_FS - aarp_register_proc_fs(); -#endif /* CONFIG_PROC_FS */ atalk_register_sysctl(); printk(atalk_banner); return 0; @@ -1844,13 +1914,10 @@ module_init(atalk_init); /* - * Note on MOD_{INC,DEC}_USE_COUNT: - * - * Use counts are incremented/decremented when - * sockets are created/deleted. - * - * AppleTalk interfaces are not incremented until atalkd is run - * and are only decremented when they are downed. + * No explicit module reference count manipulation is needed in the + * protocol. Socket layer sets module reference count for us + * and interfaces reference counting is done + * by the network device layer. * * Ergo, before the AppleTalk module can be removed, all AppleTalk * sockets be closed from user space. @@ -1861,9 +1928,6 @@ atalk_unregister_sysctl(); #endif /* CONFIG_SYSCTL */ atalk_proc_exit(); -#ifdef CONFIG_PROC_FS - aarp_unregister_proc_fs(); -#endif /* CONFIG_PROC_FS */ aarp_cleanup_module(); /* General aarp clean-up. */ unregister_netdevice_notifier(&ddp_notifier); dev_remove_pack(<alk_packet_type); @@ -1876,3 +1940,4 @@ MODULE_LICENSE("GPL"); MODULE_AUTHOR("Alan Cox "); MODULE_DESCRIPTION("AppleTalk 0.20 for Linux NET4.0\n"); +MODULE_ALIAS_NETPROTO(PF_APPLETALK); diff -Nru a/net/atm/common.c b/net/atm/common.c --- a/net/atm/common.c Tue Sep 2 19:58:20 2003 +++ b/net/atm/common.c Tue Sep 2 19:58:20 2003 @@ -279,6 +279,7 @@ if (!sk) return -ENOMEM; sock_init_data(sock, sk); + sk_set_owner(sk, THIS_MODULE); sk->sk_state_change = vcc_def_wakeup; sk->sk_write_space = vcc_write_space; @@ -1135,3 +1136,5 @@ module_exit(atm_exit); MODULE_LICENSE("GPL"); +MODULE_ALIAS_NETPROTO(PF_ATMPVC); +MODULE_ALIAS_NETPROTO(PF_ATMSVC); diff -Nru a/net/ax25/af_ax25.c b/net/ax25/af_ax25.c --- a/net/ax25/af_ax25.c Tue Sep 2 19:58:19 2003 +++ b/net/ax25/af_ax25.c Tue Sep 2 19:58:19 2003 @@ -1842,81 +1842,107 @@ return res; } -static int ax25_get_info(char *buffer, char **start, off_t offset, int length) +#ifdef CONFIG_PROC_FS + +static void *ax25_info_start(struct seq_file *seq, loff_t *pos) { - ax25_cb *ax25; - int k; - int len = 0; - off_t pos = 0; - off_t begin = 0; + struct ax25_cb *ax25; struct hlist_node *node; + int i = 0; spin_lock_bh(&ax25_list_lock); + ax25_for_each(ax25, node, &ax25_list) { + if (i == *pos) + return ax25; + ++i; + } + return NULL; +} + +static void *ax25_info_next(struct seq_file *seq, void *v, loff_t *pos) +{ + ++*pos; + + return hlist_entry( ((struct ax25_cb *)v)->ax25_node.next, + struct ax25_cb, ax25_node); +} + +static void ax25_info_stop(struct seq_file *seq, void *v) +{ + spin_unlock_bh(&ax25_list_lock); +} + +static int ax25_info_show(struct seq_file *seq, void *v) +{ + ax25_cb *ax25 = v; + int k; + /* * New format: * magic dev src_addr dest_addr,digi1,digi2,.. st vs vr va t1 t1 t2 t2 t3 t3 idle idle n2 n2 rtt window paclen Snd-Q Rcv-Q inode */ - ax25_for_each(ax25, node, &ax25_list) { - len += sprintf(buffer+len, "%8.8lx %s %s%s ", - (long) ax25, - ax25->ax25_dev == NULL? "???" : ax25->ax25_dev->dev->name, - ax2asc(&ax25->source_addr), - ax25->iamdigi? "*":""); - - len += sprintf(buffer+len, "%s", ax2asc(&ax25->dest_addr)); - - for (k=0; (ax25->digipeat != NULL) && (k < ax25->digipeat->ndigi); k++) { - len += sprintf(buffer+len, ",%s%s", - ax2asc(&ax25->digipeat->calls[k]), - ax25->digipeat->repeated[k]? "*":""); - } - - len += sprintf(buffer+len, " %d %d %d %d %lu %lu %lu %lu %lu %lu %lu %lu %d %d %lu %d %d", - ax25->state, - ax25->vs, ax25->vr, ax25->va, - ax25_display_timer(&ax25->t1timer) / HZ, ax25->t1 / HZ, - ax25_display_timer(&ax25->t2timer) / HZ, ax25->t2 / HZ, - ax25_display_timer(&ax25->t3timer) / HZ, ax25->t3 / HZ, - ax25_display_timer(&ax25->idletimer) / (60 * HZ), - ax25->idle / (60 * HZ), - ax25->n2count, ax25->n2, - ax25->rtt / HZ, - ax25->window, - ax25->paclen); - - if (ax25->sk != NULL) { - bh_lock_sock(ax25->sk); - len += sprintf(buffer + len, " %d %d %ld\n", - atomic_read(&ax25->sk->sk_wmem_alloc), - atomic_read(&ax25->sk->sk_rmem_alloc), - ax25->sk->sk_socket != NULL ? SOCK_INODE(ax25->sk->sk_socket)->i_ino : 0L); - bh_unlock_sock(ax25->sk); - } else { - len += sprintf(buffer + len, " * * *\n"); - } - - pos = begin + len; - - if (pos < offset) { - len = 0; - begin = pos; - } + seq_printf(seq, "%8.8lx %s %s%s ", + (long) ax25, + ax25->ax25_dev == NULL? "???" : ax25->ax25_dev->dev->name, + ax2asc(&ax25->source_addr), + ax25->iamdigi? "*":""); + seq_printf(seq, "%s", ax2asc(&ax25->dest_addr)); + + for (k=0; (ax25->digipeat != NULL) && (k < ax25->digipeat->ndigi); k++) { + seq_printf(seq, ",%s%s", + ax2asc(&ax25->digipeat->calls[k]), + ax25->digipeat->repeated[k]? "*":""); + } - if (pos > offset + length) - break; + seq_printf(seq, " %d %d %d %d %lu %lu %lu %lu %lu %lu %lu %lu %d %d %lu %d %d", + ax25->state, + ax25->vs, ax25->vr, ax25->va, + ax25_display_timer(&ax25->t1timer) / HZ, ax25->t1 / HZ, + ax25_display_timer(&ax25->t2timer) / HZ, ax25->t2 / HZ, + ax25_display_timer(&ax25->t3timer) / HZ, ax25->t3 / HZ, + ax25_display_timer(&ax25->idletimer) / (60 * HZ), + ax25->idle / (60 * HZ), + ax25->n2count, ax25->n2, + ax25->rtt / HZ, + ax25->window, + ax25->paclen); + + if (ax25->sk != NULL) { + bh_lock_sock(ax25->sk); + seq_printf(seq," %d %d %ld\n", + atomic_read(&ax25->sk->sk_wmem_alloc), + atomic_read(&ax25->sk->sk_rmem_alloc), + ax25->sk->sk_socket != NULL ? SOCK_INODE(ax25->sk->sk_socket)->i_ino : 0L); + bh_unlock_sock(ax25->sk); + } else { + seq_puts(seq, " * * *\n"); } + return 0; +} - spin_unlock_bh(&ax25_list_lock); +static struct seq_operations ax25_info_seqops = { + .start = ax25_info_start, + .next = ax25_info_next, + .stop = ax25_info_stop, + .show = ax25_info_show, +}; - *start = buffer + (offset - begin); - len -= (offset - begin); +static int ax25_info_open(struct inode *inode, struct file *file) +{ + return seq_open(file, &ax25_info_seqops); +} - if (len > length) len = length; +static struct file_operations ax25_info_fops = { + .owner = THIS_MODULE, + .open = ax25_info_open, + .read = seq_read, + .llseek = seq_lseek, + .release = seq_release, +}; - return(len); -} +#endif static struct net_proto_family ax25_family_ops = { .family = PF_AX25, @@ -1986,9 +2012,9 @@ register_netdevice_notifier(&ax25_dev_notifier); ax25_register_sysctl(); - proc_net_create("ax25_route", 0, ax25_rt_get_info); - proc_net_create("ax25", 0, ax25_get_info); - proc_net_create("ax25_calls", 0, ax25_uid_get_info); + proc_net_fops_create("ax25_route", S_IRUGO, &ax25_route_fops); + proc_net_fops_create("ax25", S_IRUGO, &ax25_info_fops); + proc_net_fops_create("ax25_calls", S_IRUGO, &ax25_uid_fops); printk(banner); return 0; @@ -1999,6 +2025,7 @@ MODULE_AUTHOR("Jonathan Naylor G4KLX "); MODULE_DESCRIPTION("The amateur radio AX.25 link layer protocol"); MODULE_LICENSE("GPL"); +MODULE_ALIAS_NETPROTO(PF_AX25); static void __exit ax25_exit(void) { diff -Nru a/net/ax25/ax25_dev.c b/net/ax25/ax25_dev.c --- a/net/ax25/ax25_dev.c Tue Sep 2 19:58:13 2003 +++ b/net/ax25/ax25_dev.c Tue Sep 2 19:58:13 2003 @@ -67,6 +67,7 @@ dev->ax25_ptr = ax25_dev; ax25_dev->dev = dev; + dev_hold(dev); ax25_dev->forward = NULL; ax25_dev->values[AX25_VALUES_IPDEFMODE] = AX25_DEF_IPDEFMODE; @@ -121,6 +122,7 @@ if ((s = ax25_dev_list) == ax25_dev) { ax25_dev_list = s->next; spin_unlock_bh(&ax25_dev_lock); + dev_put(dev); kfree(ax25_dev); ax25_register_sysctl(); return; @@ -130,6 +132,7 @@ if (s->next == ax25_dev) { s->next = ax25_dev->next; spin_unlock_bh(&ax25_dev_lock); + dev_put(dev); kfree(ax25_dev); ax25_register_sysctl(); return; @@ -196,8 +199,8 @@ ax25_dev = ax25_dev_list; while (ax25_dev != NULL) { s = ax25_dev; + dev_put(ax25_dev->dev); ax25_dev = ax25_dev->next; - kfree(s); } ax25_dev_list = NULL; diff -Nru a/net/ax25/ax25_route.c b/net/ax25/ax25_route.c --- a/net/ax25/ax25_route.c Tue Sep 2 19:58:17 2003 +++ b/net/ax25/ax25_route.c Tue Sep 2 19:58:17 2003 @@ -34,6 +34,7 @@ #include #include #include +#include static ax25_route *ax25_route_list; static rwlock_t ax25_route_lock = RW_LOCK_UNLOCKED; @@ -278,66 +279,100 @@ } } -int ax25_rt_get_info(char *buffer, char **start, off_t offset, int length) -{ - ax25_route *ax25_rt; - int len = 0; - off_t pos = 0; - off_t begin = 0; - char *callsign; - int i; +#ifdef CONFIG_PROC_FS - read_lock(&ax25_route_lock); +#define AX25_PROC_START ((void *)1) - len += sprintf(buffer, "callsign dev mode digipeaters\n"); +static void *ax25_rt_seq_start(struct seq_file *seq, loff_t *pos) +{ + struct ax25_route *ax25_rt; + int i = 1; + + read_lock(&ax25_route_lock); + if (*pos == 0) + return AX25_PROC_START; for (ax25_rt = ax25_route_list; ax25_rt != NULL; ax25_rt = ax25_rt->next) { + if (i == *pos) + return ax25_rt; + ++i; + } + + return NULL; +} + +static void *ax25_rt_seq_next(struct seq_file *seq, void *v, loff_t *pos) +{ + ++*pos; + return (v == AX25_PROC_START) ? ax25_route_list : + ((struct ax25_route *) v)->next; +} + +static void ax25_rt_seq_stop(struct seq_file *seq, void *v) +{ + read_unlock(&ax25_route_lock); +} + +static int ax25_rt_seq_show(struct seq_file *seq, void *v) +{ + if (v == AX25_PROC_START) + seq_puts(seq, "callsign dev mode digipeaters\n"); + else { + struct ax25_route *ax25_rt = v; + const char *callsign; + int i; + if (ax25cmp(&ax25_rt->callsign, &null_ax25_address) == 0) callsign = "default"; else callsign = ax2asc(&ax25_rt->callsign); - len += sprintf(buffer + len, "%-9s %-4s", + + seq_printf(seq, "%-9s %-4s", callsign, ax25_rt->dev ? ax25_rt->dev->name : "???"); switch (ax25_rt->ip_mode) { case 'V': - len += sprintf(buffer + len, " vc"); + seq_puts(seq, " vc"); break; case 'D': - len += sprintf(buffer + len, " dg"); + seq_puts(seq, " dg"); break; default: - len += sprintf(buffer + len, " *"); + seq_puts(seq, " *"); break; } if (ax25_rt->digipeat != NULL) for (i = 0; i < ax25_rt->digipeat->ndigi; i++) - len += sprintf(buffer + len, " %s", ax2asc(&ax25_rt->digipeat->calls[i])); - - len += sprintf(buffer + len, "\n"); + seq_printf(seq, " %s", ax2asc(&ax25_rt->digipeat->calls[i])); - pos = begin + len; - - if (pos < offset) { - len = 0; - begin = pos; - } - - if (pos > offset + length) - break; + seq_puts(seq, "\n"); } - read_unlock(&ax25_route_lock); - - *start = buffer + (offset - begin); - len -= (offset - begin); + return 0; +} - if (len > length) - len = length; +static struct seq_operations ax25_rt_seqops = { + .start = ax25_rt_seq_start, + .next = ax25_rt_seq_next, + .stop = ax25_rt_seq_stop, + .show = ax25_rt_seq_show, +}; - return len; +static int ax25_rt_info_open(struct inode *inode, struct file *file) +{ + return seq_open(file, &ax25_rt_seqops); } + +struct file_operations ax25_route_fops = { + .owner = THIS_MODULE, + .open = ax25_rt_info_open, + .read = seq_read, + .llseek = seq_lseek, + .release = seq_release, +}; + +#endif /* * Find AX.25 route diff -Nru a/net/ax25/ax25_uid.c b/net/ax25/ax25_uid.c --- a/net/ax25/ax25_uid.c Tue Sep 2 19:58:14 2003 +++ b/net/ax25/ax25_uid.c Tue Sep 2 19:58:14 2003 @@ -30,6 +30,7 @@ #include #include #include +#include #include #include #include @@ -141,39 +142,73 @@ return -EINVAL; /*NOTREACHED */ } -int ax25_uid_get_info(char *buffer, char **start, off_t offset, int length) +#ifdef CONFIG_PROC_FS + +#define AX25_PROC_START ((void *)1) + +static void *ax25_uid_seq_start(struct seq_file *seq, loff_t *pos) { - ax25_uid_assoc *pt; - int len = 0; - off_t pos = 0; - off_t begin = 0; + struct ax25_uid_assoc *pt; + int i = 1; read_lock(&ax25_uid_lock); - len += sprintf(buffer, "Policy: %d\n", ax25_uid_policy); + if (*pos == 0) + return AX25_PROC_START; for (pt = ax25_uid_list; pt != NULL; pt = pt->next) { - len += sprintf(buffer + len, "%6d %s\n", pt->uid, ax2asc(&pt->call)); - - pos = begin + len; + if (i == *pos) + return pt; + ++i; + } + return NULL; +} - if (pos < offset) { - len = 0; - begin = pos; - } +static void *ax25_uid_seq_next(struct seq_file *seq, void *v, loff_t *pos) +{ + ++*pos; + return (v == AX25_PROC_START) ? ax25_uid_list : + ((struct ax25_uid_assoc *) v)->next; +} - if (pos > offset + length) - break; - } +static void ax25_uid_seq_stop(struct seq_file *seq, void *v) +{ read_unlock(&ax25_uid_lock); +} + +static int ax25_uid_seq_show(struct seq_file *seq, void *v) +{ + if (v == AX25_PROC_START) + seq_printf(seq, "Policy: %d\n", ax25_uid_policy); + else { + struct ax25_uid_assoc *pt = v; + - *start = buffer + (offset - begin); - len -= offset - begin; + seq_printf(seq, "%6d %s\n", pt->uid, ax2asc(&pt->call)); + } + return 0; +} - if (len > length) - len = length; +static struct seq_operations ax25_uid_seqops = { + .start = ax25_uid_seq_start, + .next = ax25_uid_seq_next, + .stop = ax25_uid_seq_stop, + .show = ax25_uid_seq_show, +}; - return len; +static int ax25_uid_info_open(struct inode *inode, struct file *file) +{ + return seq_open(file, &ax25_uid_seqops); } + +struct file_operations ax25_uid_fops = { + .owner = THIS_MODULE, + .open = ax25_uid_info_open, + .read = seq_read, + .llseek = seq_lseek, + .release = seq_release, +}; + +#endif /* * Free all memory associated with UID/Callsign structures. diff -Nru a/net/bluetooth/af_bluetooth.c b/net/bluetooth/af_bluetooth.c --- a/net/bluetooth/af_bluetooth.c Tue Sep 2 19:58:13 2003 +++ b/net/bluetooth/af_bluetooth.c Tue Sep 2 19:58:13 2003 @@ -130,6 +130,7 @@ } sock_init_data(sock, sk); + sk_set_owner(sk, THIS_MODULE); INIT_LIST_HEAD(&bt_sk(sk)->accept_q); sk->sk_zapped = 0; diff -Nru a/net/bluetooth/bnep/core.c b/net/bluetooth/bnep/core.c --- a/net/bluetooth/bnep/core.c Tue Sep 2 19:58:17 2003 +++ b/net/bluetooth/bnep/core.c Tue Sep 2 19:58:17 2003 @@ -711,3 +711,4 @@ MODULE_DESCRIPTION("Bluetooth BNEP ver " VERSION); MODULE_AUTHOR("David Libault , Maxim Krasnyanskiy "); MODULE_LICENSE("GPL"); +MODULE_ALIAS_NETPROTO(PF_BLUETOOTH); diff -Nru a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c --- a/net/bluetooth/l2cap.c Tue Sep 2 19:58:17 2003 +++ b/net/bluetooth/l2cap.c Tue Sep 2 19:58:17 2003 @@ -200,7 +200,7 @@ */ static struct sock *__l2cap_get_sock_by_psm(int state, u16 psm, bdaddr_t *src) { - struct sock *sk, *sk1 = NULL; + struct sock *sk = NULL, *sk1 = NULL; struct hlist_node *node; sk_for_each(sk, node, &l2cap_sk_list.head) { diff -Nru a/net/bluetooth/rfcomm/sock.c b/net/bluetooth/rfcomm/sock.c --- a/net/bluetooth/rfcomm/sock.c Tue Sep 2 19:58:17 2003 +++ b/net/bluetooth/rfcomm/sock.c Tue Sep 2 19:58:17 2003 @@ -114,7 +114,7 @@ /* ---- Socket functions ---- */ static struct sock *__rfcomm_get_sock_by_addr(u8 channel, bdaddr_t *src) { - struct sock *sk; + struct sock *sk = NULL; struct hlist_node *node; sk_for_each(sk, node, &rfcomm_sk_list.head) { @@ -131,7 +131,7 @@ */ static struct sock *__rfcomm_get_sock_by_channel(int state, u8 channel, bdaddr_t *src) { - struct sock *sk, *sk1 = NULL; + struct sock *sk = NULL, *sk1 = NULL; struct hlist_node *node; sk_for_each(sk, node, &rfcomm_sk_list.head) { diff -Nru a/net/bridge/Makefile b/net/bridge/Makefile --- a/net/bridge/Makefile Tue Sep 2 19:58:19 2003 +++ b/net/bridge/Makefile Tue Sep 2 19:58:19 2003 @@ -8,9 +8,6 @@ br_ioctl.o br_notify.o br_stp.o br_stp_bpdu.o \ br_stp_if.o br_stp_timer.o -# br_netfilter only deals with IPv4 and ARP filtering, both are INET protocols -ifeq ($(CONFIG_INET),y) -bridge-$(CONFIG_NETFILTER) += br_netfilter.o -endif +bridge-$(CONFIG_BRIDGE_NETFILTER) += br_netfilter.o obj-$(CONFIG_BRIDGE_NF_EBTABLES) += netfilter/ diff -Nru a/net/bridge/br_forward.c b/net/bridge/br_forward.c --- a/net/bridge/br_forward.c Tue Sep 2 19:58:14 2003 +++ b/net/bridge/br_forward.c Tue Sep 2 19:58:14 2003 @@ -33,7 +33,7 @@ int br_dev_queue_push_xmit(struct sk_buff *skb) { -#ifdef CONFIG_NETFILTER +#ifdef CONFIG_BRIDGE_NETFILTER /* ip_refrag calls ip_fragment, which doesn't copy the MAC header. */ if (skb->nf_bridge) memcpy(skb->data - 16, skb->nf_bridge->hh, 16); diff -Nru a/net/bridge/netfilter/Kconfig b/net/bridge/netfilter/Kconfig --- a/net/bridge/netfilter/Kconfig Tue Sep 2 19:58:14 2003 +++ b/net/bridge/netfilter/Kconfig Tue Sep 2 19:58:14 2003 @@ -1,9 +1,30 @@ # # Bridge netfilter configuration # + +menu "Bridge: Netfilter Configuration" + depends on BRIDGE && NETFILTER + config BRIDGE_NF_EBTABLES - tristate "Bridge: ebtables" - depends on NETFILTER && BRIDGE + tristate "Ethernet Bridge tables (ebtables) support" + help + ebtables is a general, extensible frame/packet identification + framework. Say 'Y' or 'M' here if you want to do Ethernet + filtering/NAT/brouting on the Ethernet bridge. +# +# tables +# +config BRIDGE_EBT_BROUTE + tristate "ebt: broute table support" + depends on BRIDGE_NF_EBTABLES + help + The ebtables broute table is used to define rules that decide between + bridging and routing frames, giving Linux the functionality of a + brouter. See the man page for ebtables(8) and examples on the ebtables + website. + + If you want to compile it as a module, say M here and read + . If unsure, say `N'. config BRIDGE_EBT_T_FILTER tristate "ebt: filter table support" @@ -26,35 +47,14 @@ If you want to compile it as a module, say M here and read . If unsure, say `N'. - -config BRIDGE_EBT_BROUTE - tristate "ebt: broute table support" +# +# matches +# +config BRIDGE_EBT_802_3 + tristate "ebt: 802.3 filter support" depends on BRIDGE_NF_EBTABLES help - The ebtables broute table is used to define rules that decide between - bridging and routing frames, giving Linux the functionality of a - brouter. See the man page for ebtables(8) and examples on the ebtables - website. - - If you want to compile it as a module, say M here and read - . If unsure, say `N'. - -config BRIDGE_EBT_LOG - tristate "ebt: log support" - depends on BRIDGE_NF_EBTABLES - help - This option adds the log target, that you can use in any rule in - any ebtables table. It records the frame header to the syslog. - - If you want to compile it as a module, say M here and read - . If unsure, say `N'. - -config BRIDGE_EBT_IP - tristate "ebt: IP filter support" - depends on BRIDGE_NF_EBTABLES - help - This option adds the IP match, which allows basic IP header field - filtering. + This option adds matching support for 802.3 Ethernet frames. If you want to compile it as a module, say M here and read . If unsure, say `N'. @@ -69,12 +69,12 @@ If you want to compile it as a module, say M here and read . If unsure, say `N'. -config BRIDGE_EBT_VLAN - tristate "ebt: 802.1Q VLAN filter support" +config BRIDGE_EBT_IP + tristate "ebt: IP filter support" depends on BRIDGE_NF_EBTABLES help - This option adds the 802.1Q vlan match, which allows the filtering of - 802.1Q vlan fields. + This option adds the IP match, which allows basic IP header field + filtering. If you want to compile it as a module, say M here and read . If unsure, say `N'. @@ -113,12 +113,24 @@ If you want to compile it as a module, say M here and read . If unsure, say `N'. -config BRIDGE_EBT_SNAT - tristate "ebt: snat target support" +config BRIDGE_EBT_VLAN + tristate "ebt: 802.1Q VLAN filter support" depends on BRIDGE_NF_EBTABLES help - This option adds the MAC SNAT target, which allows altering the MAC - source address of frames. + This option adds the 802.1Q vlan match, which allows the filtering of + 802.1Q vlan fields. + + If you want to compile it as a module, say M here and read + . If unsure, say `N'. +# +# targets +# +config BRIDGE_EBT_ARPREPLY + tristate "ebt: arp reply target support" + depends on BRIDGE_NF_EBTABLES + help + This option adds the arp reply target, which allows + automatically sending arp replies to arp requests. If you want to compile it as a module, say M here and read . If unsure, say `N'. @@ -133,6 +145,18 @@ If you want to compile it as a module, say M here and read . If unsure, say `N'. +config BRIDGE_EBT_MARK_T + tristate "ebt: mark target support" + depends on BRIDGE_NF_EBTABLES + help + This option adds the mark target, which allows marking frames by + setting the 'nfmark' value in the frame. + This value is the same as the one used in the iptables mark match and + target. + + If you want to compile it as a module, say M here and read + . If unsure, say `N'. + config BRIDGE_EBT_REDIRECT tristate "ebt: redirect target support" depends on BRIDGE_NF_EBTABLES @@ -143,15 +167,26 @@ If you want to compile it as a module, say M here and read . If unsure, say `N'. -config BRIDGE_EBT_MARK_T - tristate "ebt: mark target support" +config BRIDGE_EBT_SNAT + tristate "ebt: snat target support" depends on BRIDGE_NF_EBTABLES help - This option adds the mark target, which allows marking frames by - setting the 'nfmark' value in the frame. - This value is the same as the one used in the iptables mark match and - target. + This option adds the MAC SNAT target, which allows altering the MAC + source address of frames. + + If you want to compile it as a module, say M here and read + . If unsure, say `N'. +# +# watchers +# +config BRIDGE_EBT_LOG + tristate "ebt: log support" + depends on BRIDGE_NF_EBTABLES + help + This option adds the log target, that you can use in any rule in + any ebtables table. It records the frame header to the syslog. If you want to compile it as a module, say M here and read . If unsure, say `N'. +endmenu diff -Nru a/net/bridge/netfilter/Makefile b/net/bridge/netfilter/Makefile --- a/net/bridge/netfilter/Makefile Tue Sep 2 19:58:17 2003 +++ b/net/bridge/netfilter/Makefile Tue Sep 2 19:58:17 2003 @@ -3,17 +3,27 @@ # obj-$(CONFIG_BRIDGE_NF_EBTABLES) += ebtables.o + +# tables +obj-$(CONFIG_BRIDGE_EBT_BROUTE) += ebtable_broute.o obj-$(CONFIG_BRIDGE_EBT_T_FILTER) += ebtable_filter.o obj-$(CONFIG_BRIDGE_EBT_T_NAT) += ebtable_nat.o -obj-$(CONFIG_BRIDGE_EBT_BROUTE) += ebtable_broute.o -obj-$(CONFIG_BRIDGE_EBT_IP) += ebt_ip.o + +#matches +obj-$(CONFIG_BRIDGE_EBT_802_3) += ebt_802_3.o obj-$(CONFIG_BRIDGE_EBT_ARP) += ebt_arp.o -obj-$(CONFIG_BRIDGE_EBT_VLAN) += ebt_vlan.o +obj-$(CONFIG_BRIDGE_EBT_IP) += ebt_ip.o obj-$(CONFIG_BRIDGE_EBT_MARK) += ebt_mark_m.o obj-$(CONFIG_BRIDGE_EBT_PKTTYPE) += ebt_pkttype.o obj-$(CONFIG_BRIDGE_EBT_STP) += ebt_stp.o -obj-$(CONFIG_BRIDGE_EBT_LOG) += ebt_log.o -obj-$(CONFIG_BRIDGE_EBT_SNAT) += ebt_snat.o +obj-$(CONFIG_BRIDGE_EBT_VLAN) += ebt_vlan.o + +# targets +obj-$(CONFIG_BRIDGE_EBT_ARPREPLY) += ebt_arpreply.o +obj-$(CONFIG_BRIDGE_EBT_MARK_T) += ebt_mark.o obj-$(CONFIG_BRIDGE_EBT_DNAT) += ebt_dnat.o obj-$(CONFIG_BRIDGE_EBT_REDIRECT) += ebt_redirect.o -obj-$(CONFIG_BRIDGE_EBT_MARK_T) += ebt_mark.o +obj-$(CONFIG_BRIDGE_EBT_SNAT) += ebt_snat.o + +# watchers +obj-$(CONFIG_BRIDGE_EBT_LOG) += ebt_log.o diff -Nru a/net/bridge/netfilter/ebt_802_3.c b/net/bridge/netfilter/ebt_802_3.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/net/bridge/netfilter/ebt_802_3.c Tue Sep 2 19:58:20 2003 @@ -0,0 +1,73 @@ +/* + * 802_3 + * + * Author: + * Chris Vitale csv@bluetail.com + * + * May 2003 + * + */ + +#include +#include +#include + +static int ebt_filter_802_3(const struct sk_buff *skb, const struct net_device *in, + const struct net_device *out, const void *data, unsigned int datalen) +{ + struct ebt_802_3_info *info = (struct ebt_802_3_info *)data; + struct ebt_802_3_hdr *hdr = (struct ebt_802_3_hdr *)skb->mac.ethernet; + uint16_t type = hdr->llc.ui.ctrl & IS_UI ? hdr->llc.ui.type : hdr->llc.ni.type; + + if (info->bitmask & EBT_802_3_SAP) { + if (FWINV(info->sap != hdr->llc.ui.ssap, EBT_802_3_SAP)) + return EBT_NOMATCH; + if (FWINV(info->sap != hdr->llc.ui.dsap, EBT_802_3_SAP)) + return EBT_NOMATCH; + } + + if (info->bitmask & EBT_802_3_TYPE) { + if (!(hdr->llc.ui.dsap == CHECK_TYPE && hdr->llc.ui.ssap == CHECK_TYPE)) + return EBT_NOMATCH; + if (FWINV(info->type != type, EBT_802_3_TYPE)) + return EBT_NOMATCH; + } + + return EBT_MATCH; +} + +static struct ebt_match filter_802_3; +static int ebt_802_3_check(const char *tablename, unsigned int hookmask, + const struct ebt_entry *e, void *data, unsigned int datalen) +{ + struct ebt_802_3_info *info = (struct ebt_802_3_info *)data; + + if (datalen < sizeof(struct ebt_802_3_info)) + return -EINVAL; + if (info->bitmask & ~EBT_802_3_MASK || info->invflags & ~EBT_802_3_MASK) + return -EINVAL; + + return 0; +} + +static struct ebt_match filter_802_3 = +{ + .name = EBT_802_3_MATCH, + .match = ebt_filter_802_3, + .check = ebt_802_3_check, + .me = THIS_MODULE, +}; + +static int __init init(void) +{ + return ebt_register_match(&filter_802_3); +} + +static void __exit fini(void) +{ + ebt_unregister_match(&filter_802_3); +} + +module_init(init); +module_exit(fini); +MODULE_LICENSE("GPL"); diff -Nru a/net/bridge/netfilter/ebt_arpreply.c b/net/bridge/netfilter/ebt_arpreply.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/net/bridge/netfilter/ebt_arpreply.c Tue Sep 2 19:58:20 2003 @@ -0,0 +1,89 @@ +/* + * ebt_arpreply + * + * Authors: + * Grzegorz Borowiak + * Bart De Schuymer + * + * August, 2003 + * + */ + +#include +#include +#include +#include +#include + +static int ebt_target_reply(struct sk_buff **pskb, unsigned int hooknr, + const struct net_device *in, const struct net_device *out, + const void *data, unsigned int datalen) +{ + struct ebt_arpreply_info *info = (struct ebt_arpreply_info *)data; + u32 sip, dip; + struct arphdr ah; + unsigned char sha[ETH_ALEN]; + struct sk_buff *skb = *pskb; + + if (skb_copy_bits(skb, 0, &ah, sizeof(ah))) + return EBT_DROP; + + if (ah.ar_op != __constant_htons(ARPOP_REQUEST) || ah.ar_hln != ETH_ALEN + || ah.ar_pro != __constant_htons(ETH_P_IP) || ah.ar_pln != 4) + return EBT_CONTINUE; + + if (skb_copy_bits(skb, sizeof(ah), &sha, ETH_ALEN)) + return EBT_DROP; + + if (skb_copy_bits(skb, sizeof(ah) + ETH_ALEN, &sip, sizeof(sip))) + return EBT_DROP; + + if (skb_copy_bits(skb, sizeof(ah) + 2 * ETH_ALEN + sizeof(sip), + &dip, sizeof(dip))) + return EBT_DROP; + + arp_send(ARPOP_REPLY, ETH_P_ARP, sip, (struct net_device *)in, + dip, sha, info->mac, sha); + + return info->target; +} + +static int ebt_target_reply_check(const char *tablename, unsigned int hookmask, + const struct ebt_entry *e, void *data, unsigned int datalen) +{ + struct ebt_arpreply_info *info = (struct ebt_arpreply_info *)data; + + if (datalen != EBT_ALIGN(sizeof(struct ebt_arpreply_info))) + return -EINVAL; + if (BASE_CHAIN && info->target == EBT_RETURN) + return -EINVAL; + if (e->ethproto != __constant_htons(ETH_P_ARP) || + e->invflags & EBT_IPROTO) + return -EINVAL; + CLEAR_BASE_CHAIN_BIT; + if (strcmp(tablename, "nat") || hookmask & ~(1 << NF_BR_PRE_ROUTING)) + return -EINVAL; + return 0; +} + +static struct ebt_target reply_target = +{ + .name = EBT_ARPREPLY_TARGET, + .target = ebt_target_reply, + .check = ebt_target_reply_check, + .me = THIS_MODULE, +}; + +static int __init init(void) +{ + return ebt_register_target(&reply_target); +} + +static void __exit fini(void) +{ + ebt_unregister_target(&reply_target); +} + +module_init(init); +module_exit(fini); +MODULE_LICENSE("GPL"); diff -Nru a/net/core/dev.c b/net/core/dev.c --- a/net/core/dev.c Tue Sep 2 19:58:16 2003 +++ b/net/core/dev.c Tue Sep 2 19:58:16 2003 @@ -845,11 +845,7 @@ * engine, but this requires more changes in devices. */ smp_mb__after_clear_bit(); /* Commit netif_running(). */ - while (test_bit(__LINK_STATE_RX_SCHED, &dev->state)) { - /* No hurry. */ - current->state = TASK_INTERRUPTIBLE; - schedule_timeout(1); - } + netif_poll_disable(dev); /* * Call the device specific close. This cannot fail. @@ -1210,7 +1206,7 @@ int lo_cong = 100; int mod_cong = 290; -struct netif_rx_stats netdev_rx_stat[NR_CPUS]; +DEFINE_PER_CPU(struct netif_rx_stats, netdev_rx_stat) = { 0, }; #ifdef CONFIG_NET_HW_FLOWCONTROL @@ -1359,7 +1355,7 @@ this_cpu = smp_processor_id(); queue = &__get_cpu_var(softnet_data); - netdev_rx_stat[this_cpu].total++; + __get_cpu_var(netdev_rx_stat).total++; if (queue->input_pkt_queue.qlen <= netdev_max_backlog) { if (queue->input_pkt_queue.qlen) { if (queue->throttle) @@ -1389,14 +1385,14 @@ if (!queue->throttle) { queue->throttle = 1; - netdev_rx_stat[this_cpu].throttled++; + __get_cpu_var(netdev_rx_stat).throttled++; #ifdef CONFIG_NET_HW_FLOWCONTROL atomic_inc(&netdev_dropping); #endif } drop: - netdev_rx_stat[this_cpu].dropped++; + __get_cpu_var(netdev_rx_stat).dropped++; local_irq_restore(flags); kfree_skb(skb); @@ -1537,11 +1533,11 @@ skb_bond(skb); - netdev_rx_stat[smp_processor_id()].total++; + __get_cpu_var(netdev_rx_stat).total++; #ifdef CONFIG_NET_FASTROUTE if (skb->pkt_type == PACKET_FASTROUTE) { - netdev_rx_stat[smp_processor_id()].fastroute_deferred_out++; + __get_cpu_var(netdev_rx_stat).fastroute_deferred_out++; return dev_queue_xmit(skb); } #endif @@ -1657,7 +1653,7 @@ list_del(&backlog_dev->poll_list); smp_mb__before_clear_bit(); - clear_bit(__LINK_STATE_RX_SCHED, &backlog_dev->state); + netif_poll_enable(backlog_dev); if (queue->throttle) { queue->throttle = 0; @@ -1672,7 +1668,6 @@ static void net_rx_action(struct softirq_action *h) { - int this_cpu = smp_processor_id(); struct softnet_data *queue = &__get_cpu_var(softnet_data); unsigned long start_time = jiffies; int budget = netdev_max_backlog; @@ -1711,7 +1706,7 @@ return; softnet_break: - netdev_rx_stat[this_cpu].time_squeeze++; + __get_cpu_var(netdev_rx_stat).time_squeeze++; __raise_softirq_irqoff(NET_RX_SOFTIRQ); goto out; } @@ -1912,7 +1907,7 @@ while (*pos < NR_CPUS) if (cpu_online(*pos)) { - rc = &netdev_rx_stat[*pos]; + rc = &per_cpu(netdev_rx_stat, *pos); break; } else ++*pos; diff -Nru a/net/core/ethtool.c b/net/core/ethtool.c --- a/net/core/ethtool.c Tue Sep 2 19:58:14 2003 +++ b/net/core/ethtool.c Tue Sep 2 19:58:14 2003 @@ -13,6 +13,7 @@ #include #include #include +#include /* * Some useful ethtool_ops methods that're device independent. @@ -30,6 +31,16 @@ return (dev->features & NETIF_F_IP_CSUM) != 0; } +int ethtool_op_set_tx_csum(struct net_device *dev, u32 data) +{ + if (data) + dev->features |= NETIF_F_IP_CSUM; + else + dev->features &= ~NETIF_F_IP_CSUM; + + return 0; +} + u32 ethtool_op_get_sg(struct net_device *dev) { return (dev->features & NETIF_F_SG) != 0; @@ -45,6 +56,21 @@ return 0; } +u32 ethtool_op_get_tso(struct net_device *dev) +{ + return (dev->features & NETIF_F_TSO) != 0; +} + +int ethtool_op_set_tso(struct net_device *dev, u32 data) +{ + if (data) + dev->features |= NETIF_F_TSO; + else + dev->features &= ~NETIF_F_TSO; + + return 0; +} + /* Handlers for each ethtool command */ static int ethtool_get_settings(struct net_device *dev, void *useraddr) @@ -454,6 +480,33 @@ return dev->ethtool_ops->set_sg(dev, edata.data); } +static int ethtool_get_tso(struct net_device *dev, char *useraddr) +{ + struct ethtool_value edata = { ETHTOOL_GTSO }; + + if (!dev->ethtool_ops->get_tso) + return -EOPNOTSUPP; + + edata.data = dev->ethtool_ops->get_tso(dev); + + if (copy_to_user(useraddr, &edata, sizeof(edata))) + return -EFAULT; + return 0; +} + +static int ethtool_set_tso(struct net_device *dev, char *useraddr) +{ + struct ethtool_value edata; + + if (!dev->ethtool_ops->set_tso) + return -EOPNOTSUPP; + + if (copy_from_user(&edata, useraddr, sizeof(edata))) + return -EFAULT; + + return dev->ethtool_ops->set_tso(dev, edata.data); +} + static int ethtool_self_test(struct net_device *dev, char *useraddr) { struct ethtool_test test; @@ -502,15 +555,15 @@ switch (gstrings.string_set) { case ETH_SS_TEST: - if (ops->self_test_count) - gstrings.len = ops->self_test_count(dev); - else + if (!ops->self_test_count) return -EOPNOTSUPP; + gstrings.len = ops->self_test_count(dev); + break; case ETH_SS_STATS: - if (ops->get_stats_count) - gstrings.len = ops->get_stats_count(dev); - else + if (!ops->get_stats_count) return -EOPNOTSUPP; + gstrings.len = ops->get_stats_count(dev); + break; default: return -EINVAL; } @@ -653,6 +706,10 @@ return ethtool_get_sg(dev, useraddr); case ETHTOOL_SSG: return ethtool_set_sg(dev, useraddr); + case ETHTOOL_GTSO: + return ethtool_get_tso(dev, useraddr); + case ETHTOOL_STSO: + return ethtool_set_tso(dev, useraddr); case ETHTOOL_TEST: return ethtool_self_test(dev, useraddr); case ETHTOOL_GSTRINGS: diff -Nru a/net/core/netfilter.c b/net/core/netfilter.c --- a/net/core/netfilter.c Tue Sep 2 19:58:15 2003 +++ b/net/core/netfilter.c Tue Sep 2 19:58:15 2003 @@ -430,7 +430,7 @@ { int status; struct nf_info *info; -#if defined(CONFIG_BRIDGE) || defined(CONFIG_BRIDGE_MODULE) +#ifdef CONFIG_BRIDGE_NETFILTER struct net_device *physindev = NULL; struct net_device *physoutdev = NULL; #endif @@ -467,7 +467,7 @@ if (indev) dev_hold(indev); if (outdev) dev_hold(outdev); -#if defined(CONFIG_BRIDGE) || defined(CONFIG_BRIDGE_MODULE) +#ifdef CONFIG_BRIDGE_NETFILTER if (skb->nf_bridge) { physindev = skb->nf_bridge->physindev; if (physindev) dev_hold(physindev); @@ -483,7 +483,7 @@ /* James M doesn't say fuck enough. */ if (indev) dev_put(indev); if (outdev) dev_put(outdev); -#if defined(CONFIG_BRIDGE) || defined(CONFIG_BRIDGE_MODULE) +#ifdef CONFIG_BRIDGE_NETFILTER if (physindev) dev_put(physindev); if (physoutdev) dev_put(physoutdev); #endif @@ -560,7 +560,7 @@ /* Release those devices we held, or Alexey will kill me. */ if (info->indev) dev_put(info->indev); if (info->outdev) dev_put(info->outdev); -#if defined(CONFIG_BRIDGE) || defined(CONFIG_BRIDGE_MODULE) +#ifdef CONFIG_BRIDGE_NETFILTER if (skb->nf_bridge) { if (skb->nf_bridge->physindev) dev_put(skb->nf_bridge->physindev); diff -Nru a/net/core/scm.c b/net/core/scm.c --- a/net/core/scm.c Tue Sep 2 19:58:15 2003 +++ b/net/core/scm.c Tue Sep 2 19:58:15 2003 @@ -41,7 +41,7 @@ static __inline__ int scm_check_creds(struct ucred *creds) { - if ((creds->pid == current->pid || capable(CAP_SYS_ADMIN)) && + if ((creds->pid == current->tgid || capable(CAP_SYS_ADMIN)) && ((creds->uid == current->uid || creds->uid == current->euid || creds->uid == current->suid) || capable(CAP_SETUID)) && ((creds->gid == current->gid || creds->gid == current->egid || diff -Nru a/net/core/skbuff.c b/net/core/skbuff.c --- a/net/core/skbuff.c Tue Sep 2 19:58:17 2003 +++ b/net/core/skbuff.c Tue Sep 2 19:58:17 2003 @@ -236,7 +236,7 @@ } #ifdef CONFIG_NETFILTER nf_conntrack_put(skb->nfct); -#if defined(CONFIG_BRIDGE) || defined(CONFIG_BRIDGE_MODULE) +#ifdef CONFIG_BRIDGE_NETFILTER nf_bridge_put(skb->nf_bridge); #endif #endif @@ -301,7 +301,7 @@ #ifdef CONFIG_NETFILTER_DEBUG C(nf_debug); #endif -#if defined(CONFIG_BRIDGE) || defined(CONFIG_BRIDGE_MODULE) +#ifdef CONFIG_BRIDGE_NETFILTER C(nf_bridge); nf_bridge_get(skb->nf_bridge); #endif @@ -359,7 +359,7 @@ #ifdef CONFIG_NETFILTER_DEBUG new->nf_debug = old->nf_debug; #endif -#if defined(CONFIG_BRIDGE) || defined(CONFIG_BRIDGE_MODULE) +#ifdef CONFIG_BRIDGE_NETFILTER new->nf_bridge = old->nf_bridge; nf_bridge_get(old->nf_bridge); #endif diff -Nru a/net/decnet/af_decnet.c b/net/decnet/af_decnet.c --- a/net/decnet/af_decnet.c Tue Sep 2 19:58:16 2003 +++ b/net/decnet/af_decnet.c Tue Sep 2 19:58:16 2003 @@ -2349,6 +2349,7 @@ MODULE_DESCRIPTION("The Linux DECnet Network Protocol"); MODULE_AUTHOR("Linux DECnet Project Team"); MODULE_LICENSE("GPL"); +MODULE_ALIAS_NETPROTO(PF_DECnet); static char banner[] __initdata = KERN_INFO "NET4: DECnet for Linux: V.2.5.68s (C) 1995-2003 Linux DECnet Project Team\n"; diff -Nru a/net/econet/af_econet.c b/net/econet/af_econet.c --- a/net/econet/af_econet.c Tue Sep 2 19:58:16 2003 +++ b/net/econet/af_econet.c Tue Sep 2 19:58:16 2003 @@ -562,6 +562,7 @@ sk->sk_reuse = 1; sock->ops = &econet_ops; sock_init_data(sock,sk); + sk_set_owner(sk, THIS_MODULE); eo = ec_sk(sk) = kmalloc(sizeof(*eo), GFP_KERNEL); if (!eo) @@ -1115,3 +1116,4 @@ module_exit(econet_proto_exit); MODULE_LICENSE("GPL"); +MODULE_ALIAS_NETPROTO(PF_ECONET); diff -Nru a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c --- a/net/ipv4/af_inet.c Tue Sep 2 19:58:13 2003 +++ b/net/ipv4/af_inet.c Tue Sep 2 19:58:13 2003 @@ -1248,3 +1248,4 @@ return 0; } #endif /* CONFIG_PROC_FS */ +MODULE_ALIAS_NETPROTO(PF_INET); diff -Nru a/net/ipv4/icmp.c b/net/ipv4/icmp.c --- a/net/ipv4/icmp.c Tue Sep 2 19:58:19 2003 +++ b/net/ipv4/icmp.c Tue Sep 2 19:58:19 2003 @@ -230,12 +230,18 @@ static DEFINE_PER_CPU(struct socket *, __icmp_socket) = NULL; #define icmp_socket __get_cpu_var(__icmp_socket) -static __inline__ void icmp_xmit_lock(void) +static __inline__ int icmp_xmit_lock(void) { local_bh_disable(); - if (unlikely(!spin_trylock(&icmp_socket->sk->sk_lock.slock))) - BUG(); + if (unlikely(!spin_trylock(&icmp_socket->sk->sk_lock.slock))) { + /* This can happen if the output path signals a + * dst_link_failure() for an outgoing ICMP packet. + */ + local_bh_enable(); + return 1; + } + return 0; } static void icmp_xmit_unlock(void) @@ -376,7 +382,8 @@ if (ip_options_echo(&icmp_param->replyopts, skb)) goto out; - icmp_xmit_lock(); + if (icmp_xmit_lock()) + return; icmp_param->data.icmph.checksum = 0; icmp_out_count(icmp_param->data.icmph.type); @@ -488,7 +495,8 @@ } } - icmp_xmit_lock(); + if (icmp_xmit_lock()) + return; /* * Construct source address and options. diff -Nru a/net/ipv4/igmp.c b/net/ipv4/igmp.c --- a/net/ipv4/igmp.c Tue Sep 2 19:58:19 2003 +++ b/net/ipv4/igmp.c Tue Sep 2 19:58:19 2003 @@ -2122,6 +2122,7 @@ break; } read_unlock(&in_dev->lock); + in_dev_put(in_dev); } return im; } @@ -2181,7 +2182,9 @@ if (likely(state->in_dev != NULL)) { read_unlock(&state->in_dev->lock); in_dev_put(state->in_dev); + state->in_dev = NULL; } + state->dev = NULL; read_unlock(&dev_base_lock); } @@ -2284,6 +2287,7 @@ spin_unlock_bh(&im->lock); } read_unlock_bh(&idev->lock); + in_dev_put(idev); } return psf; } @@ -2350,12 +2354,16 @@ static void igmp_mcf_seq_stop(struct seq_file *seq, void *v) { struct igmp_mcf_iter_state *state = igmp_mcf_seq_private(seq); - if (likely(state->im != NULL)) + if (likely(state->im != NULL)) { spin_unlock_bh(&state->im->lock); + state->im = NULL; + } if (likely(state->idev != NULL)) { read_unlock_bh(&state->idev->lock); in_dev_put(state->idev); + state->idev = NULL; } + state->dev = NULL; read_unlock(&dev_base_lock); } diff -Nru a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c --- a/net/ipv4/ip_output.c Tue Sep 2 19:58:19 2003 +++ b/net/ipv4/ip_output.c Tue Sep 2 19:58:19 2003 @@ -414,7 +414,7 @@ /* Connection association is same as pre-frag packet */ to->nfct = from->nfct; nf_conntrack_get(to->nfct); -#if defined(CONFIG_BRIDGE) || defined(CONFIG_BRIDGE_MODULE) +#ifdef CONFIG_BRIDGE_NETFILTER to->nf_bridge = from->nf_bridge; nf_bridge_get(to->nf_bridge); #endif diff -Nru a/net/ipv4/ipvs/ip_vs_conn.c b/net/ipv4/ipvs/ip_vs_conn.c --- a/net/ipv4/ipvs/ip_vs_conn.c Tue Sep 2 19:58:19 2003 +++ b/net/ipv4/ipvs/ip_vs_conn.c Tue Sep 2 19:58:19 2003 @@ -837,7 +837,7 @@ "(size=%d, memory=%ldKbytes)\n", IP_VS_CONN_TAB_SIZE, (long)(IP_VS_CONN_TAB_SIZE*sizeof(struct list_head))/1024); - IP_VS_DBG(0, "Each connection entry needs %d bytes at least\n", + IP_VS_DBG(0, "Each connection entry needs %Zd bytes at least\n", sizeof(struct ip_vs_conn)); for (idx = 0; idx < IP_VS_CONN_TAB_SIZE; idx++) { diff -Nru a/net/ipv4/ipvs/ip_vs_dh.c b/net/ipv4/ipvs/ip_vs_dh.c --- a/net/ipv4/ipvs/ip_vs_dh.c Tue Sep 2 19:58:18 2003 +++ b/net/ipv4/ipvs/ip_vs_dh.c Tue Sep 2 19:58:18 2003 @@ -147,7 +147,7 @@ return -ENOMEM; } svc->sched_data = tbl; - IP_VS_DBG(6, "DH hash table (memory=%dbytes) allocated for " + IP_VS_DBG(6, "DH hash table (memory=%Zdbytes) allocated for " "current service\n", sizeof(struct ip_vs_dh_bucket)*IP_VS_DH_TAB_SIZE); @@ -167,7 +167,7 @@ /* release the table itself */ kfree(svc->sched_data); - IP_VS_DBG(6, "DH hash table (memory=%dbytes) released\n", + IP_VS_DBG(6, "DH hash table (memory=%Zdbytes) released\n", sizeof(struct ip_vs_dh_bucket)*IP_VS_DH_TAB_SIZE); return 0; diff -Nru a/net/ipv4/ipvs/ip_vs_lblc.c b/net/ipv4/ipvs/ip_vs_lblc.c --- a/net/ipv4/ipvs/ip_vs_lblc.c Tue Sep 2 19:58:18 2003 +++ b/net/ipv4/ipvs/ip_vs_lblc.c Tue Sep 2 19:58:18 2003 @@ -396,7 +396,7 @@ return -ENOMEM; } svc->sched_data = tbl; - IP_VS_DBG(6, "LBLC hash table (memory=%dbytes) allocated for " + IP_VS_DBG(6, "LBLC hash table (memory=%Zdbytes) allocated for " "current service\n", sizeof(struct ip_vs_lblc_table)); @@ -436,7 +436,7 @@ /* release the table itself */ kfree(svc->sched_data); - IP_VS_DBG(6, "LBLC hash table (memory=%dbytes) released\n", + IP_VS_DBG(6, "LBLC hash table (memory=%Zdbytes) released\n", sizeof(struct ip_vs_lblc_table)); return 0; diff -Nru a/net/ipv4/ipvs/ip_vs_lblcr.c b/net/ipv4/ipvs/ip_vs_lblcr.c --- a/net/ipv4/ipvs/ip_vs_lblcr.c Tue Sep 2 19:58:18 2003 +++ b/net/ipv4/ipvs/ip_vs_lblcr.c Tue Sep 2 19:58:18 2003 @@ -649,7 +649,7 @@ return -ENOMEM; } svc->sched_data = tbl; - IP_VS_DBG(6, "LBLCR hash table (memory=%dbytes) allocated for " + IP_VS_DBG(6, "LBLCR hash table (memory=%Zdbytes) allocated for " "current service\n", sizeof(struct ip_vs_lblcr_table)); @@ -692,7 +692,7 @@ /* release the table itself */ kfree(svc->sched_data); - IP_VS_DBG(6, "LBLCR hash table (memory=%dbytes) released\n", + IP_VS_DBG(6, "LBLCR hash table (memory=%Zdbytes) released\n", sizeof(struct ip_vs_lblcr_table)); return 0; diff -Nru a/net/ipv4/ipvs/ip_vs_sh.c b/net/ipv4/ipvs/ip_vs_sh.c --- a/net/ipv4/ipvs/ip_vs_sh.c Tue Sep 2 19:58:17 2003 +++ b/net/ipv4/ipvs/ip_vs_sh.c Tue Sep 2 19:58:17 2003 @@ -144,7 +144,7 @@ return -ENOMEM; } svc->sched_data = tbl; - IP_VS_DBG(6, "SH hash table (memory=%dbytes) allocated for " + IP_VS_DBG(6, "SH hash table (memory=%Zdbytes) allocated for " "current service\n", sizeof(struct ip_vs_sh_bucket)*IP_VS_SH_TAB_SIZE); @@ -164,7 +164,7 @@ /* release the table itself */ kfree(svc->sched_data); - IP_VS_DBG(6, "SH hash table (memory=%dbytes) released\n", + IP_VS_DBG(6, "SH hash table (memory=%Zdbytes) released\n", sizeof(struct ip_vs_sh_bucket)*IP_VS_SH_TAB_SIZE); return 0; diff -Nru a/net/ipv4/ipvs/ip_vs_sync.c b/net/ipv4/ipvs/ip_vs_sync.c --- a/net/ipv4/ipvs/ip_vs_sync.c Tue Sep 2 19:58:12 2003 +++ b/net/ipv4/ipvs/ip_vs_sync.c Tue Sep 2 19:58:12 2003 @@ -851,7 +851,7 @@ return -EEXIST; IP_VS_DBG(7, "%s: pid %d\n", __FUNCTION__, current->pid); - IP_VS_DBG(7, "Each ip_vs_sync_conn entry need %d bytes\n", + IP_VS_DBG(7, "Each ip_vs_sync_conn entry need %Zd bytes\n", sizeof(struct ip_vs_sync_conn)); ip_vs_sync_state |= state; diff -Nru a/net/ipv4/netfilter/Kconfig b/net/ipv4/netfilter/Kconfig --- a/net/ipv4/netfilter/Kconfig Tue Sep 2 19:58:18 2003 +++ b/net/ipv4/netfilter/Kconfig Tue Sep 2 19:58:18 2003 @@ -74,8 +74,7 @@ . If unsure, say `Y'. config IP_NF_QUEUE - tristate "Userspace queueing via NETLINK (EXPERIMENTAL)" - depends on EXPERIMENTAL + tristate "Userspace queueing via NETLINK" help Netfilter has the ability to queue packets to user space: the netlink device can be used to access them using this driver. @@ -106,6 +105,16 @@ If you want to compile it as a module, say M here and read . If unsure, say `N'. +config IP_NF_MATCH_IPRANGE + tristate "IP range match support" + depends on IP_NF_IPTABLES + help + This option makes possible to match IP addresses against IP address + ranges. + + If you want to compile it as a module, say M here and read + . If unsure, say `N'. + config IP_NF_MATCH_MAC tristate "MAC address match support" depends on IP_NF_IPTABLES @@ -239,7 +248,7 @@ config IP_NF_MATCH_HELPER tristate "Helper match support" - depends on IP_NF_CONNTRACK!=n && IP_NF_IPTABLES + depends on IP_NF_CONNTRACK && IP_NF_IPTABLES help Helper matching allows you to match packets in dynamic connections tracked by a conntrack-helper, ie. ip_conntrack_ftp @@ -271,19 +280,9 @@ If you want to compile it as a module, say M here and read Documentation/modules.txt. If unsure, say `N'. -config IP_NF_MATCH_UNCLEAN - tristate "Unclean match support (EXPERIMENTAL)" - depends on EXPERIMENTAL && IP_NF_IPTABLES - help - Unclean packet matching matches any strange or invalid packets, by - looking at a series of fields in the IP, TCP, UDP and ICMP headers. - - If you want to compile it as a module, say M here and read - . If unsure, say `N'. - config IP_NF_MATCH_OWNER - tristate "Owner match support (EXPERIMENTAL)" - depends on EXPERIMENTAL && IP_NF_IPTABLES + tristate "Owner match support" + depends on IP_NF_IPTABLES help Packet owner matching allows you to match locally-generated packets based on who created them: the user, group, process or session. @@ -293,7 +292,7 @@ config IP_NF_MATCH_PHYSDEV tristate "Physdev match support" - depends on IP_NF_IPTABLES!=n && BRIDGE!=n + depends on IP_NF_IPTABLES!=n && BRIDGE_NETFILTER help Physdev packet matching matches against the physical bridge ports the IP packet arrived on or will leave by. @@ -324,16 +323,6 @@ If you want to compile it as a module, say M here and read . If unsure, say `N'. -config IP_NF_TARGET_MIRROR - tristate "MIRROR target support (EXPERIMENTAL)" - depends on EXPERIMENTAL && IP_NF_FILTER - help - The MIRROR target allows a filtering rule to specify that an - incoming packet should be bounced back to the sender. - - If you want to compile it as a module, say M here and read - . If unsure, say `N'. - config IP_NF_NAT tristate "Full NAT" depends on IP_NF_IPTABLES && IP_NF_CONNTRACK @@ -375,6 +364,28 @@ If you want to compile it as a module, say M here and read . If unsure, say `N'. +config IP_NF_TARGET_NETMAP + tristate "NETMAP target support" + depends on IP_NF_NAT + help + NETMAP is an implementation of static 1:1 NAT mapping of network + addresses. It maps the network address part, while keeping the host + address part intact. It is similar to Fast NAT, except that + Netfilter's connection tracking doesn't work well with Fast NAT. + + If you want to compile it as a module, say M here and read + . If unsure, say `N'. + +config IP_NF_TARGET_SAME + tristate "SAME target support" + depends on IP_NF_NAT + help + This option adds a `SAME' target, which works like the standard SNAT + target, but attempts to give clients the same IP for all connections. + + If you want to compile it as a module, say M here and read + Documentation/modules.txt. If unsure, say `N'. + config IP_NF_NAT_LOCAL bool "NAT of local connections (READ HELP)" depends on IP_NF_NAT @@ -490,6 +501,19 @@ the routing method (see `Use netfilter MARK value as routing key') and can also be used by other subsystems to change their behavior. + + If you want to compile it as a module, say M here and read + . If unsure, say `N'. + +config IP_NF_TARGET_CLASSIFY + tristate "CLASSIFY target support" + depends on IP_NF_MANGLE + help + This option adds a `CLASSIFY' target, which enables the user to set + the priority of a packet. Some qdiscs can use this value for + classification, among these are: + + atm, cbq, dsmark, pfifo_fast, htb, prio If you want to compile it as a module, say M here and read . If unsure, say `N'. diff -Nru a/net/ipv4/netfilter/Makefile b/net/ipv4/netfilter/Makefile --- a/net/ipv4/netfilter/Makefile Tue Sep 2 19:58:14 2003 +++ b/net/ipv4/netfilter/Makefile Tue Sep 2 19:58:14 2003 @@ -44,6 +44,7 @@ obj-$(CONFIG_IP_NF_MATCH_LIMIT) += ipt_limit.o obj-$(CONFIG_IP_NF_MATCH_MARK) += ipt_mark.o obj-$(CONFIG_IP_NF_MATCH_MAC) += ipt_mac.o +obj-$(CONFIG_IP_NF_MATCH_IPRANGE) += ipt_iprange.o obj-$(CONFIG_IP_NF_MATCH_PKTTYPE) += ipt_pkttype.o obj-$(CONFIG_IP_NF_MATCH_MULTIPORT) += ipt_multiport.o @@ -61,20 +62,21 @@ obj-$(CONFIG_IP_NF_MATCH_TTL) += ipt_ttl.o obj-$(CONFIG_IP_NF_MATCH_STATE) += ipt_state.o obj-$(CONFIG_IP_NF_MATCH_CONNTRACK) += ipt_conntrack.o -obj-$(CONFIG_IP_NF_MATCH_UNCLEAN) += ipt_unclean.o obj-$(CONFIG_IP_NF_MATCH_TCPMSS) += ipt_tcpmss.o obj-$(CONFIG_IP_NF_MATCH_PHYSDEV) += ipt_physdev.o # targets obj-$(CONFIG_IP_NF_TARGET_REJECT) += ipt_REJECT.o -obj-$(CONFIG_IP_NF_TARGET_MIRROR) += ipt_MIRROR.o obj-$(CONFIG_IP_NF_TARGET_TOS) += ipt_TOS.o obj-$(CONFIG_IP_NF_TARGET_ECN) += ipt_ECN.o obj-$(CONFIG_IP_NF_TARGET_DSCP) += ipt_DSCP.o obj-$(CONFIG_IP_NF_TARGET_MARK) += ipt_MARK.o obj-$(CONFIG_IP_NF_TARGET_MASQUERADE) += ipt_MASQUERADE.o obj-$(CONFIG_IP_NF_TARGET_REDIRECT) += ipt_REDIRECT.o +obj-$(CONFIG_IP_NF_TARGET_NETMAP) += ipt_NETMAP.o +obj-$(CONFIG_IP_NF_TARGET_SAME) += ipt_SAME.o +obj-$(CONFIG_IP_NF_TARGET_CLASSIFY) += ipt_CLASSIFY.o obj-$(CONFIG_IP_NF_NAT_SNMP_BASIC) += ip_nat_snmp_basic.o obj-$(CONFIG_IP_NF_TARGET_LOG) += ipt_LOG.o obj-$(CONFIG_IP_NF_TARGET_ULOG) += ipt_ULOG.o diff -Nru a/net/ipv4/netfilter/arp_tables.c b/net/ipv4/netfilter/arp_tables.c --- a/net/ipv4/netfilter/arp_tables.c Tue Sep 2 19:58:18 2003 +++ b/net/ipv4/netfilter/arp_tables.c Tue Sep 2 19:58:18 2003 @@ -25,6 +25,10 @@ #include +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("David S. Miller "); +MODULE_DESCRIPTION("arptables core"); + /*#define DEBUG_ARP_TABLES*/ /*#define DEBUG_ARP_TABLES_USER*/ @@ -1324,4 +1328,3 @@ module_init(init); module_exit(fini); -MODULE_LICENSE("GPL"); diff -Nru a/net/ipv4/netfilter/arpt_mangle.c b/net/ipv4/netfilter/arpt_mangle.c --- a/net/ipv4/netfilter/arpt_mangle.c Tue Sep 2 19:58:17 2003 +++ b/net/ipv4/netfilter/arpt_mangle.c Tue Sep 2 19:58:17 2003 @@ -3,6 +3,10 @@ #include #include +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("David S. Miller "); +MODULE_DESCRIPTION("arptables mangle table"); + static unsigned int target(struct sk_buff **pskb, unsigned int hooknum, const struct net_device *in, const struct net_device *out, const void *targinfo, void *userinfo) @@ -98,4 +102,3 @@ module_init(init); module_exit(fini); -MODULE_LICENSE("GPL"); diff -Nru a/net/ipv4/netfilter/arptable_filter.c b/net/ipv4/netfilter/arptable_filter.c --- a/net/ipv4/netfilter/arptable_filter.c Tue Sep 2 19:58:12 2003 +++ b/net/ipv4/netfilter/arptable_filter.c Tue Sep 2 19:58:12 2003 @@ -8,6 +8,10 @@ #include #include +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("David S. Miller "); +MODULE_DESCRIPTION("arptables filter table"); + #define FILTER_VALID_HOOKS ((1 << NF_ARP_IN) | (1 << NF_ARP_OUT) | \ (1 << NF_ARP_FORWARD)) @@ -209,4 +213,3 @@ module_init(init); module_exit(fini); -MODULE_LICENSE("GPL"); diff -Nru a/net/ipv4/netfilter/ip_conntrack_core.c b/net/ipv4/netfilter/ip_conntrack_core.c --- a/net/ipv4/netfilter/ip_conntrack_core.c Tue Sep 2 19:58:12 2003 +++ b/net/ipv4/netfilter/ip_conntrack_core.c Tue Sep 2 19:58:12 2003 @@ -13,7 +13,6 @@ * - export ip_conntrack[_expect]_{find_get,put} functions * */ -#include #include #include #include @@ -285,14 +284,15 @@ static void clean_from_lists(struct ip_conntrack *ct) { + unsigned int ho, hr; + DEBUGP("clean_from_lists(%p)\n", ct); MUST_BE_WRITE_LOCKED(&ip_conntrack_lock); - LIST_DELETE(&ip_conntrack_hash - [hash_conntrack(&ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple)], - &ct->tuplehash[IP_CT_DIR_ORIGINAL]); - LIST_DELETE(&ip_conntrack_hash - [hash_conntrack(&ct->tuplehash[IP_CT_DIR_REPLY].tuple)], - &ct->tuplehash[IP_CT_DIR_REPLY]); + + ho = hash_conntrack(&ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple); + hr = hash_conntrack(&ct->tuplehash[IP_CT_DIR_REPLY].tuple); + LIST_DELETE(&ip_conntrack_hash[ho], &ct->tuplehash[IP_CT_DIR_ORIGINAL]); + LIST_DELETE(&ip_conntrack_hash[hr], &ct->tuplehash[IP_CT_DIR_REPLY]); /* Destroy all un-established, pending expectations */ remove_expectations(ct, 1); @@ -364,9 +364,10 @@ const struct ip_conntrack *ignored_conntrack) { struct ip_conntrack_tuple_hash *h; + unsigned int hash = hash_conntrack(tuple); MUST_BE_READ_LOCKED(&ip_conntrack_lock); - h = LIST_FIND(&ip_conntrack_hash[hash_conntrack(tuple)], + h = LIST_FIND(&ip_conntrack_hash[hash], conntrack_tuple_cmp, struct ip_conntrack_tuple_hash *, tuple, ignored_conntrack); diff -Nru a/net/ipv4/netfilter/ip_conntrack_ftp.c b/net/ipv4/netfilter/ip_conntrack_ftp.c --- a/net/ipv4/netfilter/ip_conntrack_ftp.c Tue Sep 2 19:58:18 2003 +++ b/net/ipv4/netfilter/ip_conntrack_ftp.c Tue Sep 2 19:58:18 2003 @@ -11,6 +11,10 @@ #include #include +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Rusty Russell "); +MODULE_DESCRIPTION("ftp connection tracking helper"); + /* This is slow, but it's simple. --RR */ static char ftp_buffer[65536]; @@ -439,6 +443,5 @@ PROVIDES_CONNTRACK(ftp); EXPORT_SYMBOL(ip_ftp_lock); -MODULE_LICENSE("GPL"); module_init(init); module_exit(fini); diff -Nru a/net/ipv4/netfilter/ip_conntrack_irc.c b/net/ipv4/netfilter/ip_conntrack_irc.c --- a/net/ipv4/netfilter/ip_conntrack_irc.c Tue Sep 2 19:58:18 2003 +++ b/net/ipv4/netfilter/ip_conntrack_irc.c Tue Sep 2 19:58:18 2003 @@ -41,8 +41,8 @@ /* This is slow, but it's simple. --RR */ static char irc_buffer[65536]; -MODULE_AUTHOR("Harald Welte "); -MODULE_DESCRIPTION("IRC (DCC) connection tracking module"); +MODULE_AUTHOR("Harald Welte "); +MODULE_DESCRIPTION("IRC (DCC) connection tracking helper"); MODULE_LICENSE("GPL"); #ifdef MODULE_PARM MODULE_PARM(ports, "1-" __MODULE_STRING(MAX_PORTS) "i"); diff -Nru a/net/ipv4/netfilter/ip_conntrack_standalone.c b/net/ipv4/netfilter/ip_conntrack_standalone.c --- a/net/ipv4/netfilter/ip_conntrack_standalone.c Tue Sep 2 19:58:15 2003 +++ b/net/ipv4/netfilter/ip_conntrack_standalone.c Tue Sep 2 19:58:15 2003 @@ -14,7 +14,6 @@ #include #include #include -#include #include #define ASSERT_READ_LOCK(x) MUST_BE_READ_LOCKED(&ip_conntrack_lock) diff -Nru a/net/ipv4/netfilter/ip_conntrack_tftp.c b/net/ipv4/netfilter/ip_conntrack_tftp.c --- a/net/ipv4/netfilter/ip_conntrack_tftp.c Tue Sep 2 19:58:14 2003 +++ b/net/ipv4/netfilter/ip_conntrack_tftp.c Tue Sep 2 19:58:14 2003 @@ -17,7 +17,7 @@ #include MODULE_AUTHOR("Magnus Boden "); -MODULE_DESCRIPTION("Netfilter connection tracking module for tftp"); +MODULE_DESCRIPTION("tftp connection tracking helper"); MODULE_LICENSE("GPL"); #define MAX_PORTS 8 @@ -44,7 +44,7 @@ if (skb_copy_bits(skb, skb->nh.iph->ihl * 4 + sizeof(struct udphdr), &tftph, sizeof(tftph)) != 0) - return -1; + return NF_ACCEPT; switch (ntohs(tftph.opcode)) { /* RRQ and WRQ works the same way */ diff -Nru a/net/ipv4/netfilter/ip_fw_compat_masq.c b/net/ipv4/netfilter/ip_fw_compat_masq.c --- a/net/ipv4/netfilter/ip_fw_compat_masq.c Tue Sep 2 19:58:18 2003 +++ b/net/ipv4/netfilter/ip_fw_compat_masq.c Tue Sep 2 19:58:18 2003 @@ -13,7 +13,6 @@ #include #include #include -#include #include #include diff -Nru a/net/ipv4/netfilter/ip_nat_amanda.c b/net/ipv4/netfilter/ip_nat_amanda.c --- a/net/ipv4/netfilter/ip_nat_amanda.c Tue Sep 2 19:58:14 2003 +++ b/net/ipv4/netfilter/ip_nat_amanda.c Tue Sep 2 19:58:14 2003 @@ -35,7 +35,7 @@ #endif MODULE_AUTHOR("Brian J. Murrell "); -MODULE_DESCRIPTION("Amanda network address translation module"); +MODULE_DESCRIPTION("Amanda NAT helper"); MODULE_LICENSE("GPL"); /* protects amanda part of conntracks */ diff -Nru a/net/ipv4/netfilter/ip_nat_core.c b/net/ipv4/netfilter/ip_nat_core.c --- a/net/ipv4/netfilter/ip_nat_core.c Tue Sep 2 19:58:13 2003 +++ b/net/ipv4/netfilter/ip_nat_core.c Tue Sep 2 19:58:13 2003 @@ -2,7 +2,6 @@ /* (c) 1999 Paul `Rusty' Russell. Licenced under the GNU General Public Licence. */ -#include #include #include #include @@ -68,6 +67,7 @@ static void ip_nat_cleanup_conntrack(struct ip_conntrack *conn) { struct ip_nat_info *info = &conn->nat.info; + unsigned int hs, hp; if (!info->initialized) return; @@ -75,21 +75,18 @@ IP_NF_ASSERT(info->bysource.conntrack); IP_NF_ASSERT(info->byipsproto.conntrack); + hs = hash_by_src(&conn->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src, + conn->tuplehash[IP_CT_DIR_ORIGINAL] + .tuple.dst.protonum); + + hp = hash_by_ipsproto(conn->tuplehash[IP_CT_DIR_REPLY].tuple.src.ip, + conn->tuplehash[IP_CT_DIR_REPLY].tuple.dst.ip, + conn->tuplehash[IP_CT_DIR_REPLY] + .tuple.dst.protonum); + WRITE_LOCK(&ip_nat_lock); - LIST_DELETE(&bysource[hash_by_src(&conn->tuplehash[IP_CT_DIR_ORIGINAL] - .tuple.src, - conn->tuplehash[IP_CT_DIR_ORIGINAL] - .tuple.dst.protonum)], - &info->bysource); - - LIST_DELETE(&byipsproto - [hash_by_ipsproto(conn->tuplehash[IP_CT_DIR_REPLY] - .tuple.src.ip, - conn->tuplehash[IP_CT_DIR_REPLY] - .tuple.dst.ip, - conn->tuplehash[IP_CT_DIR_REPLY] - .tuple.dst.protonum)], - &info->byipsproto); + LIST_DELETE(&bysource[hs], &info->bysource); + LIST_DELETE(&byipsproto[hp], &info->byipsproto); WRITE_UNLOCK(&ip_nat_lock); } @@ -246,11 +243,12 @@ const struct ip_conntrack *conntrack) { unsigned int score = 0; + unsigned int h; MUST_BE_READ_LOCKED(&ip_nat_lock); - LIST_FIND(&byipsproto[hash_by_ipsproto(src, dst, protonum)], - fake_cmp, struct ip_nat_hash *, src, dst, protonum, &score, - conntrack); + h = hash_by_ipsproto(src, dst, protonum); + LIST_FIND(&byipsproto[h], fake_cmp, struct ip_nat_hash *, + src, dst, protonum, &score, conntrack); return score; } diff -Nru a/net/ipv4/netfilter/ip_nat_ftp.c b/net/ipv4/netfilter/ip_nat_ftp.c --- a/net/ipv4/netfilter/ip_nat_ftp.c Tue Sep 2 19:58:17 2003 +++ b/net/ipv4/netfilter/ip_nat_ftp.c Tue Sep 2 19:58:17 2003 @@ -10,6 +10,10 @@ #include #include +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Rusty Russell "); +MODULE_DESCRIPTION("ftp NAT helper"); + #if 0 #define DEBUGP printk #else @@ -342,4 +346,3 @@ module_init(init); module_exit(fini); -MODULE_LICENSE("GPL"); diff -Nru a/net/ipv4/netfilter/ip_nat_helper.c b/net/ipv4/netfilter/ip_nat_helper.c --- a/net/ipv4/netfilter/ip_nat_helper.c Tue Sep 2 19:58:13 2003 +++ b/net/ipv4/netfilter/ip_nat_helper.c Tue Sep 2 19:58:13 2003 @@ -12,7 +12,6 @@ * - make ip_nat_resize_packet more generic (TCP and UDP) * - add ip_nat_mangle_udp_packet */ -#include #include #include #include diff -Nru a/net/ipv4/netfilter/ip_nat_irc.c b/net/ipv4/netfilter/ip_nat_irc.c --- a/net/ipv4/netfilter/ip_nat_irc.c Tue Sep 2 19:58:20 2003 +++ b/net/ipv4/netfilter/ip_nat_irc.c Tue Sep 2 19:58:20 2003 @@ -39,7 +39,7 @@ static int ports_c; MODULE_AUTHOR("Harald Welte "); -MODULE_DESCRIPTION("IRC (DCC) network address translation module"); +MODULE_DESCRIPTION("IRC (DCC) NAT helper"); MODULE_LICENSE("GPL"); #ifdef MODULE_PARM MODULE_PARM(ports, "1-" __MODULE_STRING(MAX_PORTS) "i"); diff -Nru a/net/ipv4/netfilter/ip_nat_rule.c b/net/ipv4/netfilter/ip_nat_rule.c --- a/net/ipv4/netfilter/ip_nat_rule.c Tue Sep 2 19:58:15 2003 +++ b/net/ipv4/netfilter/ip_nat_rule.c Tue Sep 2 19:58:15 2003 @@ -9,7 +9,6 @@ #include #include #include -#include #define ASSERT_READ_LOCK(x) MUST_BE_READ_LOCKED(&ip_nat_lock) #define ASSERT_WRITE_LOCK(x) MUST_BE_WRITE_LOCKED(&ip_nat_lock) diff -Nru a/net/ipv4/netfilter/ip_nat_snmp_basic.c b/net/ipv4/netfilter/ip_nat_snmp_basic.c --- a/net/ipv4/netfilter/ip_nat_snmp_basic.c Tue Sep 2 19:58:18 2003 +++ b/net/ipv4/netfilter/ip_nat_snmp_basic.c Tue Sep 2 19:58:18 2003 @@ -56,7 +56,9 @@ #include #include - +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("James Morris "); +MODULE_DESCRIPTION("Basic SNMP Application Layer Gateway"); #define SNMP_PORT 161 #define SNMP_TRAP_PORT 162 @@ -1357,5 +1359,3 @@ module_exit(fini); MODULE_PARM(debug, "i"); -MODULE_DESCRIPTION("Basic SNMP Application Layer Gateway"); -MODULE_LICENSE("GPL"); diff -Nru a/net/ipv4/netfilter/ip_nat_standalone.c b/net/ipv4/netfilter/ip_nat_standalone.c --- a/net/ipv4/netfilter/ip_nat_standalone.c Tue Sep 2 19:58:18 2003 +++ b/net/ipv4/netfilter/ip_nat_standalone.c Tue Sep 2 19:58:18 2003 @@ -23,7 +23,6 @@ #include #include #include -#include #define ASSERT_READ_LOCK(x) MUST_BE_READ_LOCKED(&ip_nat_lock) #define ASSERT_WRITE_LOCK(x) MUST_BE_WRITE_LOCKED(&ip_nat_lock) diff -Nru a/net/ipv4/netfilter/ip_nat_tftp.c b/net/ipv4/netfilter/ip_nat_tftp.c --- a/net/ipv4/netfilter/ip_nat_tftp.c Tue Sep 2 19:58:14 2003 +++ b/net/ipv4/netfilter/ip_nat_tftp.c Tue Sep 2 19:58:14 2003 @@ -30,7 +30,7 @@ #include MODULE_AUTHOR("Magnus Boden "); -MODULE_DESCRIPTION("Netfilter NAT helper for tftp"); +MODULE_DESCRIPTION("tfpt NAT helper"); MODULE_LICENSE("GPL"); #define MAX_PORTS 8 diff -Nru a/net/ipv4/netfilter/ip_tables.c b/net/ipv4/netfilter/ip_tables.c --- a/net/ipv4/netfilter/ip_tables.c Tue Sep 2 19:58:14 2003 +++ b/net/ipv4/netfilter/ip_tables.c Tue Sep 2 19:58:14 2003 @@ -25,6 +25,10 @@ #include +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Netfilter Core Team "); +MODULE_DESCRIPTION("IPv4 packet filter"); + /*#define DEBUG_IP_FIREWALL*/ /*#define DEBUG_ALLOW_ALL*/ /* Useful for remote debugging */ /*#define DEBUG_IP_FIREWALL_USER*/ @@ -1845,4 +1849,3 @@ module_init(init); module_exit(fini); -MODULE_LICENSE("GPL"); diff -Nru a/net/ipv4/netfilter/ipchains_core.c b/net/ipv4/netfilter/ipchains_core.c --- a/net/ipv4/netfilter/ipchains_core.c Tue Sep 2 19:58:18 2003 +++ b/net/ipv4/netfilter/ipchains_core.c Tue Sep 2 19:58:18 2003 @@ -100,6 +100,9 @@ #include #include +MODULE_LICENSE("Dual BSD/GPL"); +MODULE_DESCRIPTION("ipchains backwards compatibility layer"); + /* Understanding locking in this code: (thanks to Alan Cox for using * little words to explain this to me). -- PR * @@ -1842,4 +1845,3 @@ #endif return ret; } -MODULE_LICENSE("Dual BSD/GPL"); diff -Nru a/net/ipv4/netfilter/ipfwadm_core.c b/net/ipv4/netfilter/ipfwadm_core.c --- a/net/ipv4/netfilter/ipfwadm_core.c Tue Sep 2 19:58:15 2003 +++ b/net/ipv4/netfilter/ipfwadm_core.c Tue Sep 2 19:58:15 2003 @@ -131,9 +131,9 @@ #include #include #include -#include MODULE_LICENSE("Dual BSD/GPL"); +MODULE_DESCRIPTION("ipfwadm backwards compatibility layer"); /* * Implement IP packet firewall diff -Nru a/net/ipv4/netfilter/ipt_CLASSIFY.c b/net/ipv4/netfilter/ipt_CLASSIFY.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/net/ipv4/netfilter/ipt_CLASSIFY.c Tue Sep 2 19:58:20 2003 @@ -0,0 +1,86 @@ +/* + * This is a module which is used for setting the skb->priority field + * of an skb for qdisc classification. + */ + +#include +#include +#include +#include + +#include +#include + +MODULE_AUTHOR("Patrick McHardy "); +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("iptables qdisc classification target module"); + +static unsigned int +target(struct sk_buff **pskb, + const struct net_device *in, + const struct net_device *out, + unsigned int hooknum, + const void *targinfo, + void *userinfo) +{ + const struct ipt_classify_target_info *clinfo = targinfo; + + if((*pskb)->priority != clinfo->priority) { + (*pskb)->priority = clinfo->priority; + (*pskb)->nfcache |= NFC_ALTERED; + } + + return IPT_CONTINUE; +} + +static int +checkentry(const char *tablename, + const struct ipt_entry *e, + void *targinfo, + unsigned int targinfosize, + unsigned int hook_mask) +{ + if (targinfosize != IPT_ALIGN(sizeof(struct ipt_classify_target_info))){ + printk(KERN_ERR "CLASSIFY: invalid size (%u != %Zu).\n", + targinfosize, + IPT_ALIGN(sizeof(struct ipt_classify_target_info))); + return 0; + } + + if (hook_mask & ~(1 << NF_IP_POST_ROUTING)) { + printk(KERN_ERR "CLASSIFY: only valid in POST_ROUTING.\n"); + return 0; + } + + if (strcmp(tablename, "mangle") != 0) { + printk(KERN_WARNING "CLASSIFY: can only be called from " + "\"mangle\" table, not \"%s\".\n", + tablename); + return 0; + } + + return 1; +} + +static struct ipt_target ipt_classify_reg = { + .name = "CLASSIFY", + .target = target, + .checkentry = checkentry, + .me = THIS_MODULE, +}; + +static int __init init(void) +{ + if (ipt_register_target(&ipt_classify_reg)) + return -EINVAL; + + return 0; +} + +static void __exit fini(void) +{ + ipt_unregister_target(&ipt_classify_reg); +} + +module_init(init); +module_exit(fini); diff -Nru a/net/ipv4/netfilter/ipt_DSCP.c b/net/ipv4/netfilter/ipt_DSCP.c --- a/net/ipv4/netfilter/ipt_DSCP.c Tue Sep 2 19:58:19 2003 +++ b/net/ipv4/netfilter/ipt_DSCP.c Tue Sep 2 19:58:19 2003 @@ -17,8 +17,8 @@ #include #include -MODULE_AUTHOR("Harald Welte "); -MODULE_DESCRIPTION("IP tables DSCP modification module"); +MODULE_AUTHOR("Harald Welte "); +MODULE_DESCRIPTION("iptables DSCP modification module"); MODULE_LICENSE("GPL"); static unsigned int diff -Nru a/net/ipv4/netfilter/ipt_ECN.c b/net/ipv4/netfilter/ipt_ECN.c --- a/net/ipv4/netfilter/ipt_ECN.c Tue Sep 2 19:58:19 2003 +++ b/net/ipv4/netfilter/ipt_ECN.c Tue Sep 2 19:58:19 2003 @@ -17,6 +17,8 @@ #include MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Harald Welte "); +MODULE_DESCRIPTION("iptables ECN modification module"); /* set ECT codepoint from IP header. * return 0 if there was an error. */ diff -Nru a/net/ipv4/netfilter/ipt_LOG.c b/net/ipv4/netfilter/ipt_LOG.c --- a/net/ipv4/netfilter/ipt_LOG.c Tue Sep 2 19:58:18 2003 +++ b/net/ipv4/netfilter/ipt_LOG.c Tue Sep 2 19:58:18 2003 @@ -13,6 +13,10 @@ #include #include +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Netfilter Core Team "); +MODULE_DESCRIPTION("iptables syslog logging module"); + #if 0 #define DEBUGP printk #else @@ -329,7 +333,7 @@ loginfo->prefix, in ? in->name : "", out ? out->name : ""); -#if defined(CONFIG_BRIDGE) || defined(CONFIG_BRIDGE_MODULE) +#ifdef CONFIG_BRIDGE_NETFILTER if ((*pskb)->nf_bridge) { struct net_device *physindev = (*pskb)->nf_bridge->physindev; struct net_device *physoutdev = (*pskb)->nf_bridge->physoutdev; @@ -413,4 +417,3 @@ module_init(init); module_exit(fini); -MODULE_LICENSE("GPL"); diff -Nru a/net/ipv4/netfilter/ipt_MARK.c b/net/ipv4/netfilter/ipt_MARK.c --- a/net/ipv4/netfilter/ipt_MARK.c Tue Sep 2 19:58:16 2003 +++ b/net/ipv4/netfilter/ipt_MARK.c Tue Sep 2 19:58:16 2003 @@ -7,6 +7,10 @@ #include #include +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Marc Boucher "); +MODULE_DESCRIPTION("iptables MARK modification module"); + static unsigned int target(struct sk_buff **pskb, const struct net_device *in, @@ -68,4 +72,3 @@ module_init(init); module_exit(fini); -MODULE_LICENSE("GPL"); diff -Nru a/net/ipv4/netfilter/ipt_MASQUERADE.c b/net/ipv4/netfilter/ipt_MASQUERADE.c --- a/net/ipv4/netfilter/ipt_MASQUERADE.c Tue Sep 2 19:58:16 2003 +++ b/net/ipv4/netfilter/ipt_MASQUERADE.c Tue Sep 2 19:58:16 2003 @@ -12,6 +12,10 @@ #include #include +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Netfilter Core Team "); +MODULE_DESCRIPTION("iptables MASQUERADE target module"); + #if 0 #define DEBUGP printk #else @@ -213,4 +217,3 @@ module_init(init); module_exit(fini); -MODULE_LICENSE("GPL"); diff -Nru a/net/ipv4/netfilter/ipt_MIRROR.c b/net/ipv4/netfilter/ipt_MIRROR.c --- a/net/ipv4/netfilter/ipt_MIRROR.c Tue Sep 2 19:58:20 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,222 +0,0 @@ -/* - This is a module which is used for resending packets with inverted src and dst. - - Based on code from: ip_nat_dumb.c,v 1.9 1999/08/20 - and various sources. - - Copyright (C) 2000 Emmanuel Roger - - Changes: - 25 Aug 2001 Harald Welte - - decrement and check TTL if not called from FORWARD hook - 18 Jul 2003 Harald Welte - - merge Patrick McHardy's mirror fixes from 2.4.22 to - 2.6.0-test1 - 19 Jul 2003 Harald Welte - - merge Patrick McHardy's rp_filter fixes from 2.4.22 to - 2.6.0-test1 - - 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. - - This program is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software Foundation, - Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#if 0 -#define DEBUGP printk -#else -#define DEBUGP(format, args...) -#endif - -static inline struct rtable *route_mirror(struct sk_buff *skb, int local) -{ - struct iphdr *iph = skb->nh.iph; - struct dst_entry *odst; - struct flowi fl = {}; - struct rtable *rt; - - if (local) { - fl.nl_u.ip4_u.daddr = iph->saddr; - fl.nl_u.ip4_u.saddr = iph->daddr; - fl.nl_u.ip4_u.tos = RT_TOS(iph->tos); - - if (ip_route_output_key(&rt, &fl) != 0) - return NULL; - } else { - /* non-local src, find valid iif to satisfy - * rp-filter when calling ip_route_input(). */ - fl.nl_u.ip4_u.daddr = iph->daddr; - if (ip_route_output_key(&rt, &fl) != 0) - return NULL; - - odst = skb->dst; - if (ip_route_input(skb, iph->saddr, iph->daddr, - RT_TOS(iph->tos), rt->u.dst.dev) != 0) { - dst_release(&rt->u.dst); - return NULL; - } - dst_release(&rt->u.dst); - rt = (struct rtable *)skb->dst; - skb->dst = odst; - } - - if (rt->u.dst.error) { - dst_release(&rt->u.dst); - rt = NULL; - } - - return rt; -} - -static inline void ip_rewrite(struct sk_buff *skb) -{ - u32 odaddr, osaddr; - - odaddr = skb->nh.iph->saddr; - osaddr = skb->nh.iph->daddr; - - skb->nfcache |= NFC_ALTERED; - - /* Rewrite IP header */ - skb->nh.iph->daddr = odaddr; - skb->nh.iph->saddr = osaddr; -} - -/* Stolen from ip_finish_output2 */ -static void ip_direct_send(struct sk_buff *skb) -{ - struct dst_entry *dst = skb->dst; - struct hh_cache *hh = dst->hh; - - if (hh) { - int hh_alen; - - read_lock_bh(&hh->hh_lock); - hh_alen = HH_DATA_ALIGN(hh->hh_len); - memcpy(skb->data - hh_alen, hh->hh_data, hh_alen); - read_unlock_bh(&hh->hh_lock); - skb_push(skb, hh->hh_len); - hh->hh_output(skb); - } else if (dst->neighbour) - dst->neighbour->output(skb); - else { - printk(KERN_DEBUG "khm in MIRROR\n"); - kfree_skb(skb); - } -} - -static unsigned int ipt_mirror_target(struct sk_buff **pskb, - const struct net_device *in, - const struct net_device *out, - unsigned int hooknum, - const void *targinfo, - void *userinfo) -{ - struct rtable *rt; - struct sk_buff *nskb; - unsigned int hh_len; - - /* Make skb writable */ - if (!skb_ip_make_writable(pskb, sizeof(struct iphdr))) - return 0; - - /* If we are not at FORWARD hook (INPUT/PREROUTING), - * the TTL isn't decreased by the IP stack */ - if (hooknum != NF_IP_FORWARD) { - if ((*pskb)->nh.iph->ttl <= 1) { - /* this will traverse normal stack, and - * thus call conntrack on the icmp packet */ - icmp_send(*pskb, ICMP_TIME_EXCEEDED, - ICMP_EXC_TTL, 0); - return NF_DROP; - } - ip_decrease_ttl((*pskb)->nh.iph); - } - - if ((rt = route_mirror(*pskb, hooknum == NF_IP_LOCAL_IN)) == NULL) - return NF_DROP; - - hh_len = (rt->u.dst.dev->hard_header_len + 15) & ~15; - - /* Copy skb (even if skb is about to be dropped, we can't just - * clone it because there may be other things, such as tcpdump, - * interested in it). We also need to expand headroom in case - * hh_len of incoming interface < hh_len of outgoing interface */ - nskb = skb_copy_expand(*pskb, hh_len, skb_tailroom(*pskb), GFP_ATOMIC); - if (nskb == NULL) { - dst_release(&rt->u.dst); - return NF_DROP; - } - - dst_release(nskb->dst); - nskb->dst = &rt->u.dst; - - ip_rewrite(nskb); - /* Don't let conntrack code see this packet: - * it will think we are starting a new - * connection! --RR */ - ip_direct_send(nskb); - - return NF_DROP; -} - -static int ipt_mirror_checkentry(const char *tablename, - const struct ipt_entry *e, - void *targinfo, - unsigned int targinfosize, - unsigned int hook_mask) -{ - /* Only on INPUT, FORWARD or PRE_ROUTING, otherwise loop danger. */ - if (hook_mask & ~((1 << NF_IP_PRE_ROUTING) - | (1 << NF_IP_FORWARD) - | (1 << NF_IP_LOCAL_IN))) { - DEBUGP("MIRROR: bad hook\n"); - return 0; - } - - if (targinfosize != IPT_ALIGN(0)) { - DEBUGP("MIRROR: targinfosize %u != 0\n", targinfosize); - return 0; - } - - return 1; -} - -static struct ipt_target ipt_mirror_reg = { - .name = "MIRROR", - .target = ipt_mirror_target, - .checkentry = ipt_mirror_checkentry, - .me = THIS_MODULE, -}; - -static int __init init(void) -{ - return ipt_register_target(&ipt_mirror_reg); -} - -static void __exit fini(void) -{ - ipt_unregister_target(&ipt_mirror_reg); -} - -module_init(init); -module_exit(fini); -MODULE_LICENSE("GPL"); diff -Nru a/net/ipv4/netfilter/ipt_NETMAP.c b/net/ipv4/netfilter/ipt_NETMAP.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/net/ipv4/netfilter/ipt_NETMAP.c Tue Sep 2 19:58:20 2003 @@ -0,0 +1,112 @@ +/* NETMAP - static NAT mapping of IP network addresses (1:1). + The mapping can be applied to source (POSTROUTING), + destination (PREROUTING), or both (with separate rules). + + Author: Svenning Soerensen +*/ + +#include +#include +#include +#include +#include +#include +#include + +#define MODULENAME "NETMAP" +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Svenning Soerensen "); +MODULE_DESCRIPTION("iptables 1:1 NAT mapping of IP networks target"); + +#if 0 +#define DEBUGP printk +#else +#define DEBUGP(format, args...) +#endif + +static int +check(const char *tablename, + const struct ipt_entry *e, + void *targinfo, + unsigned int targinfosize, + unsigned int hook_mask) +{ + const struct ip_nat_multi_range *mr = targinfo; + + if (strcmp(tablename, "nat") != 0) { + DEBUGP(MODULENAME":check: bad table `%s'.\n", tablename); + return 0; + } + if (targinfosize != IPT_ALIGN(sizeof(*mr))) { + DEBUGP(MODULENAME":check: size %u.\n", targinfosize); + return 0; + } + if (hook_mask & ~((1 << NF_IP_PRE_ROUTING) | (1 << NF_IP_POST_ROUTING))) { + DEBUGP(MODULENAME":check: bad hooks %x.\n", hook_mask); + return 0; + } + if (!(mr->range[0].flags & IP_NAT_RANGE_MAP_IPS)) { + DEBUGP(MODULENAME":check: bad MAP_IPS.\n"); + return 0; + } + if (mr->rangesize != 1) { + DEBUGP(MODULENAME":check: bad rangesize %u.\n", mr->rangesize); + return 0; + } + return 1; +} + +static unsigned int +target(struct sk_buff **pskb, + const struct net_device *in, + const struct net_device *out, + unsigned int hooknum, + const void *targinfo, + void *userinfo) +{ + struct ip_conntrack *ct; + enum ip_conntrack_info ctinfo; + u_int32_t new_ip, netmask; + const struct ip_nat_multi_range *mr = targinfo; + struct ip_nat_multi_range newrange; + + IP_NF_ASSERT(hooknum == NF_IP_PRE_ROUTING + || hooknum == NF_IP_POST_ROUTING); + ct = ip_conntrack_get(*pskb, &ctinfo); + + netmask = ~(mr->range[0].min_ip ^ mr->range[0].max_ip); + + if (hooknum == NF_IP_PRE_ROUTING) + new_ip = (*pskb)->nh.iph->daddr & ~netmask; + else + new_ip = (*pskb)->nh.iph->saddr & ~netmask; + new_ip |= mr->range[0].min_ip & netmask; + + newrange = ((struct ip_nat_multi_range) + { 1, { { mr->range[0].flags | IP_NAT_RANGE_MAP_IPS, + new_ip, new_ip, + mr->range[0].min, mr->range[0].max } } }); + + /* Hand modified range to generic setup. */ + return ip_nat_setup_info(ct, &newrange, hooknum); +} + +static struct ipt_target target_module = { + .name = MODULENAME, + .target = target, + .checkentry = check, + .me = THIS_MODULE +}; + +static int __init init(void) +{ + return ipt_register_target(&target_module); +} + +static void __exit fini(void) +{ + ipt_unregister_target(&target_module); +} + +module_init(init); +module_exit(fini); diff -Nru a/net/ipv4/netfilter/ipt_REDIRECT.c b/net/ipv4/netfilter/ipt_REDIRECT.c --- a/net/ipv4/netfilter/ipt_REDIRECT.c Tue Sep 2 19:58:15 2003 +++ b/net/ipv4/netfilter/ipt_REDIRECT.c Tue Sep 2 19:58:15 2003 @@ -12,6 +12,10 @@ #include #include +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Netfilter Core Team "); +MODULE_DESCRIPTION("iptables REDIRECT target module"); + #if 0 #define DEBUGP printk #else @@ -115,4 +119,3 @@ module_init(init); module_exit(fini); -MODULE_LICENSE("GPL"); diff -Nru a/net/ipv4/netfilter/ipt_REJECT.c b/net/ipv4/netfilter/ipt_REJECT.c --- a/net/ipv4/netfilter/ipt_REJECT.c Tue Sep 2 19:58:18 2003 +++ b/net/ipv4/netfilter/ipt_REJECT.c Tue Sep 2 19:58:18 2003 @@ -16,6 +16,10 @@ #include #include +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Netfilter Core Team "); +MODULE_DESCRIPTION("iptables REJECT target module"); + #if 0 #define DEBUGP printk #else @@ -137,6 +141,10 @@ nskb->nf_debug = 0; #endif nskb->nfmark = 0; +#ifdef CONFIG_BRIDGE_NETFILTER + nf_bridge_put(nskb->nf_bridge); + nskb->nf_bridge = NULL; +#endif tcph = (struct tcphdr *)((u_int32_t*)nskb->nh.iph + nskb->nh.iph->ihl); @@ -462,4 +470,3 @@ module_init(init); module_exit(fini); -MODULE_LICENSE("GPL"); diff -Nru a/net/ipv4/netfilter/ipt_SAME.c b/net/ipv4/netfilter/ipt_SAME.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/net/ipv4/netfilter/ipt_SAME.c Tue Sep 2 19:58:20 2003 @@ -0,0 +1,206 @@ +/* Same. Just like SNAT, only try to make the connections + * between client A and server B always have the same source ip. + * + * (C) 2000 Rusty Russell. GPL. + * + * 010320 Martin Josefsson + * * copied ipt_BALANCE.c to ipt_SAME.c and changed a few things. + * 010728 Martin Josefsson + * * added --nodst to not include destination-ip in new source + * calculations. + * * added some more sanity-checks. + * 010729 Martin Josefsson + * * fixed a buggy if-statement in same_check(), should have + * used ntohl() but didn't. + * * added support for multiple ranges. IPT_SAME_MAX_RANGE is + * defined in linux/include/linux/netfilter_ipv4/ipt_SAME.h + * and is currently set to 10. + * * added support for 1-address range, nice to have now that + * we have multiple ranges. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Martin Josefsson "); +MODULE_DESCRIPTION("iptables special SNAT module for consistent sourceip"); + +#if 0 +#define DEBUGP printk +#else +#define DEBUGP(format, args...) +#endif + +static int +same_check(const char *tablename, + const struct ipt_entry *e, + void *targinfo, + unsigned int targinfosize, + unsigned int hook_mask) +{ + unsigned int count, countess, rangeip, index = 0; + struct ipt_same_info *mr = targinfo; + + mr->ipnum = 0; + + if (strcmp(tablename, "nat") != 0) { + DEBUGP("same_check: bad table `%s'.\n", tablename); + return 0; + } + if (targinfosize != IPT_ALIGN(sizeof(*mr))) { + DEBUGP("same_check: size %u.\n", targinfosize); + return 0; + } + if (hook_mask & ~(1 << NF_IP_PRE_ROUTING | 1 << NF_IP_POST_ROUTING)) { + DEBUGP("same_check: bad hooks %x.\n", hook_mask); + return 0; + } + if (mr->rangesize < 1) { + DEBUGP("same_check: need at least one dest range.\n"); + return 0; + } + if (mr->rangesize > IPT_SAME_MAX_RANGE) { + DEBUGP("same_check: too many ranges specified, maximum " + "is %u ranges\n", + IPT_SAME_MAX_RANGE); + return 0; + } + for (count = 0; count < mr->rangesize; count++) { + if (ntohl(mr->range[count].min_ip) > + ntohl(mr->range[count].max_ip)) { + DEBUGP("same_check: min_ip is larger than max_ip in " + "range `%u.%u.%u.%u-%u.%u.%u.%u'.\n", + NIPQUAD(mr->range[count].min_ip), + NIPQUAD(mr->range[count].max_ip)); + return 0; + } + if (!(mr->range[count].flags & IP_NAT_RANGE_MAP_IPS)) { + DEBUGP("same_check: bad MAP_IPS.\n"); + return 0; + } + rangeip = (ntohl(mr->range[count].max_ip) - + ntohl(mr->range[count].min_ip) + 1); + mr->ipnum += rangeip; + + DEBUGP("same_check: range %u, ipnum = %u\n", count, rangeip); + } + DEBUGP("same_check: total ipaddresses = %u\n", mr->ipnum); + + mr->iparray = kmalloc((sizeof(u_int32_t) * mr->ipnum), GFP_KERNEL); + if (!mr->iparray) { + DEBUGP("same_check: Couldn't allocate %u bytes " + "for %u ipaddresses!\n", + (sizeof(u_int32_t) * mr->ipnum), mr->ipnum); + return 0; + } + DEBUGP("same_check: Allocated %u bytes for %u ipaddresses.\n", + (sizeof(u_int32_t) * mr->ipnum), mr->ipnum); + + for (count = 0; count < mr->rangesize; count++) { + for (countess = ntohl(mr->range[count].min_ip); + countess <= ntohl(mr->range[count].max_ip); + countess++) { + mr->iparray[index] = countess; + DEBUGP("same_check: Added ipaddress `%u.%u.%u.%u' " + "in index %u.\n", + HIPQUAD(countess), index); + index++; + } + } + return 1; +} + +static void +same_destroy(void *targinfo, + unsigned int targinfosize) +{ + struct ipt_same_info *mr = targinfo; + + kfree(mr->iparray); + + DEBUGP("same_destroy: Deallocated %u bytes for %u ipaddresses.\n", + (sizeof(u_int32_t) * mr->ipnum), mr->ipnum); +} + +static unsigned int +same_target(struct sk_buff **pskb, + const struct net_device *in, + const struct net_device *out, + unsigned int hooknum, + const void *targinfo, + void *userinfo) +{ + struct ip_conntrack *ct; + enum ip_conntrack_info ctinfo; + u_int32_t tmpip, aindex, new_ip; + const struct ipt_same_info *mr = targinfo; + struct ip_nat_multi_range newrange; + const struct ip_conntrack_tuple *t; + + IP_NF_ASSERT(hooknum == NF_IP_PRE_ROUTING || + hooknum == NF_IP_POST_ROUTING); + ct = ip_conntrack_get(*pskb, &ctinfo); + + t = &ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple; + + /* Base new source on real src ip and optionally dst ip, + giving some hope for consistency across reboots. + Here we calculate the index in mr->iparray which + holds the ipaddress we should use */ + + tmpip = ntohl(t->src.ip); + + if (!(mr->info & IPT_SAME_NODST)) + tmpip += ntohl(t->dst.ip); + + aindex = tmpip % mr->ipnum; + + new_ip = htonl(mr->iparray[aindex]); + + DEBUGP("ipt_SAME: src=%u.%u.%u.%u dst=%u.%u.%u.%u, " + "new src=%u.%u.%u.%u\n", + NIPQUAD(t->src.ip), NIPQUAD(t->dst.ip), + NIPQUAD(new_ip)); + + /* Transfer from original range. */ + newrange = ((struct ip_nat_multi_range) + { 1, { { mr->range[0].flags | IP_NAT_RANGE_MAP_IPS, + new_ip, new_ip, + mr->range[0].min, mr->range[0].max } } }); + + /* Hand modified range to generic setup. */ + return ip_nat_setup_info(ct, &newrange, hooknum); +} + +static struct ipt_target same_reg = { + .name = "SAME", + .target = same_target, + .checkentry = same_check, + .destroy = same_destroy, + .me = THIS_MODULE, +}; + +static int __init init(void) +{ + return ipt_register_target(&same_reg); +} + +static void __exit fini(void) +{ + ipt_unregister_target(&same_reg); +} + +module_init(init); +module_exit(fini); + diff -Nru a/net/ipv4/netfilter/ipt_TCPMSS.c b/net/ipv4/netfilter/ipt_TCPMSS.c --- a/net/ipv4/netfilter/ipt_TCPMSS.c Tue Sep 2 19:58:16 2003 +++ b/net/ipv4/netfilter/ipt_TCPMSS.c Tue Sep 2 19:58:16 2003 @@ -12,6 +12,10 @@ #include #include +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Marc Boucher "); +MODULE_DESCRIPTION("iptables TCP MSS modification module"); + #if 0 #define DEBUGP printk #else @@ -250,4 +254,3 @@ module_init(init); module_exit(fini); -MODULE_LICENSE("GPL"); diff -Nru a/net/ipv4/netfilter/ipt_TOS.c b/net/ipv4/netfilter/ipt_TOS.c --- a/net/ipv4/netfilter/ipt_TOS.c Tue Sep 2 19:58:13 2003 +++ b/net/ipv4/netfilter/ipt_TOS.c Tue Sep 2 19:58:13 2003 @@ -7,6 +7,10 @@ #include #include +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Netfilter Core Team "); +MODULE_DESCRIPTION("iptables TOS mangling module"); + static unsigned int target(struct sk_buff **pskb, const struct net_device *in, @@ -93,4 +97,3 @@ module_init(init); module_exit(fini); -MODULE_LICENSE("GPL"); diff -Nru a/net/ipv4/netfilter/ipt_ULOG.c b/net/ipv4/netfilter/ipt_ULOG.c --- a/net/ipv4/netfilter/ipt_ULOG.c Tue Sep 2 19:58:15 2003 +++ b/net/ipv4/netfilter/ipt_ULOG.c Tue Sep 2 19:58:15 2003 @@ -36,7 +36,6 @@ */ #include -#include #include #include #include @@ -55,7 +54,7 @@ MODULE_LICENSE("GPL"); MODULE_AUTHOR("Harald Welte "); -MODULE_DESCRIPTION("IP tables userspace logging module"); +MODULE_DESCRIPTION("iptables userspace logging module"); #define ULOG_NL_EVENT 111 /* Harald's favorite number */ #define ULOG_MAXNLGROUPS 32 /* numer of nlgroups */ diff -Nru a/net/ipv4/netfilter/ipt_ah.c b/net/ipv4/netfilter/ipt_ah.c --- a/net/ipv4/netfilter/ipt_ah.c Tue Sep 2 19:58:17 2003 +++ b/net/ipv4/netfilter/ipt_ah.c Tue Sep 2 19:58:17 2003 @@ -7,6 +7,8 @@ #include MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Yon Uriarte "); +MODULE_DESCRIPTION("iptables AH SPI match module"); #ifdef DEBUG_CONNTRACK #define duprintf(format, args...) printk(format , ## args) diff -Nru a/net/ipv4/netfilter/ipt_conntrack.c b/net/ipv4/netfilter/ipt_conntrack.c --- a/net/ipv4/netfilter/ipt_conntrack.c Tue Sep 2 19:58:19 2003 +++ b/net/ipv4/netfilter/ipt_conntrack.c Tue Sep 2 19:58:19 2003 @@ -8,6 +8,10 @@ #include #include +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Marc Boucher "); +MODULE_DESCRIPTION("iptables connection tracking match module"); + static int match(const struct sk_buff *skb, const struct net_device *in, @@ -122,4 +126,3 @@ module_init(init); module_exit(fini); -MODULE_LICENSE("GPL"); diff -Nru a/net/ipv4/netfilter/ipt_dscp.c b/net/ipv4/netfilter/ipt_dscp.c --- a/net/ipv4/netfilter/ipt_dscp.c Tue Sep 2 19:58:17 2003 +++ b/net/ipv4/netfilter/ipt_dscp.c Tue Sep 2 19:58:17 2003 @@ -13,8 +13,8 @@ #include #include -MODULE_AUTHOR("Harald Welte "); -MODULE_DESCRIPTION("IP tables DSCP matching module"); +MODULE_AUTHOR("Harald Welte "); +MODULE_DESCRIPTION("iptables DSCP matching module"); MODULE_LICENSE("GPL"); static int match(const struct sk_buff *skb, const struct net_device *in, diff -Nru a/net/ipv4/netfilter/ipt_ecn.c b/net/ipv4/netfilter/ipt_ecn.c --- a/net/ipv4/netfilter/ipt_ecn.c Tue Sep 2 19:58:15 2003 +++ b/net/ipv4/netfilter/ipt_ecn.c Tue Sep 2 19:58:15 2003 @@ -14,8 +14,8 @@ #include #include -MODULE_AUTHOR("Harald Welte "); -MODULE_DESCRIPTION("IP tables ECN matching module"); +MODULE_AUTHOR("Harald Welte "); +MODULE_DESCRIPTION("iptables ECN matching module"); MODULE_LICENSE("GPL"); static inline int match_ip(const struct sk_buff *skb, diff -Nru a/net/ipv4/netfilter/ipt_esp.c b/net/ipv4/netfilter/ipt_esp.c --- a/net/ipv4/netfilter/ipt_esp.c Tue Sep 2 19:58:16 2003 +++ b/net/ipv4/netfilter/ipt_esp.c Tue Sep 2 19:58:16 2003 @@ -7,6 +7,8 @@ #include MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Yon Uriarte "); +MODULE_DESCRIPTION("iptables ESP SPI match module"); #ifdef DEBUG_CONNTRACK #define duprintf(format, args...) printk(format , ## args) diff -Nru a/net/ipv4/netfilter/ipt_helper.c b/net/ipv4/netfilter/ipt_helper.c --- a/net/ipv4/netfilter/ipt_helper.c Tue Sep 2 19:58:17 2003 +++ b/net/ipv4/netfilter/ipt_helper.c Tue Sep 2 19:58:17 2003 @@ -17,6 +17,8 @@ #include MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Martin Josefsson "); +MODULE_DESCRIPTION("iptables helper match module"); #if 0 #define DEBUGP printk diff -Nru a/net/ipv4/netfilter/ipt_iprange.c b/net/ipv4/netfilter/ipt_iprange.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/net/ipv4/netfilter/ipt_iprange.c Tue Sep 2 19:58:20 2003 @@ -0,0 +1,97 @@ +/* + * iptables module to match IP address ranges + * (c) 2003 Jozsef Kadlecsik + * + * Released under the terms of GNU GPLv2. + * + */ +#include +#include +#include +#include +#include + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Jozsef Kadlecsik "); +MODULE_DESCRIPTION("iptables arbitrary IP range match module"); + +#if 0 +#define DEBUGP printk +#else +#define DEBUGP(format, args...) +#endif + +static int +match(const struct sk_buff *skb, + const struct net_device *in, + const struct net_device *out, + const void *matchinfo, + int offset, int *hotdrop) +{ + const struct ipt_iprange_info *info = matchinfo; + const struct iphdr *iph = skb->nh.iph; + + if (info->flags & IPRANGE_SRC) { + if (((ntohl(iph->saddr) < ntohl(info->src.min_ip)) + || (ntohl(iph->saddr) > ntohl(info->src.max_ip))) + ^ !!(info->flags & IPRANGE_SRC_INV)) { + DEBUGP("src IP %u.%u.%u.%u NOT in range %s" + "%u.%u.%u.%u-%u.%u.%u.%u\n", + NIPQUAD(iph->saddr), + info->flags & IPRANGE_SRC_INV ? "(INV) " : "", + NIPQUAD(info->src.min_ip), + NIPQUAD(info->src.max_ip)); + return 0; + } + } + if (info->flags & IPRANGE_DST) { + if (((ntohl(iph->daddr) < ntohl(info->dst.min_ip)) + || (ntohl(iph->daddr) > ntohl(info->dst.max_ip))) + ^ !!(info->flags & IPRANGE_DST_INV)) { + DEBUGP("dst IP %u.%u.%u.%u NOT in range %s" + "%u.%u.%u.%u-%u.%u.%u.%u\n", + NIPQUAD(iph->daddr), + info->flags & IPRANGE_DST_INV ? "(INV) " : "", + NIPQUAD(info->dst.min_ip), + NIPQUAD(info->dst.max_ip)); + return 0; + } + } + return 1; +} + +static int check(const char *tablename, + const struct ipt_ip *ip, + void *matchinfo, + unsigned int matchsize, + unsigned int hook_mask) +{ + /* verify size */ + if (matchsize != IPT_ALIGN(sizeof(struct ipt_iprange_info))) + return 0; + + return 1; +} + +static struct ipt_match iprange_match = +{ + .list = { NULL, NULL }, + .name = "iprange", + .match = &match, + .checkentry = &check, + .destroy = NULL, + .me = THIS_MODULE +}; + +static int __init init(void) +{ + return ipt_register_match(&iprange_match); +} + +static void __exit fini(void) +{ + ipt_unregister_match(&iprange_match); +} + +module_init(init); +module_exit(fini); diff -Nru a/net/ipv4/netfilter/ipt_limit.c b/net/ipv4/netfilter/ipt_limit.c --- a/net/ipv4/netfilter/ipt_limit.c Tue Sep 2 19:58:13 2003 +++ b/net/ipv4/netfilter/ipt_limit.c Tue Sep 2 19:58:13 2003 @@ -15,6 +15,10 @@ #include #include +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Herve Eychenne "); +MODULE_DESCRIPTION("iptables rate limit match"); + /* The algorithm used is the Simple Token Bucket Filter (TBF) * see net/sched/sch_tbf.c in the linux source tree */ @@ -134,4 +138,3 @@ module_init(init); module_exit(fini); -MODULE_LICENSE("GPL"); diff -Nru a/net/ipv4/netfilter/ipt_mac.c b/net/ipv4/netfilter/ipt_mac.c --- a/net/ipv4/netfilter/ipt_mac.c Tue Sep 2 19:58:13 2003 +++ b/net/ipv4/netfilter/ipt_mac.c Tue Sep 2 19:58:13 2003 @@ -6,6 +6,10 @@ #include #include +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Netfilter Core Team "); +MODULE_DESCRIPTION("iptables mac matching module"); + static int match(const struct sk_buff *skb, const struct net_device *in, @@ -64,4 +68,3 @@ module_init(init); module_exit(fini); -MODULE_LICENSE("GPL"); diff -Nru a/net/ipv4/netfilter/ipt_mark.c b/net/ipv4/netfilter/ipt_mark.c --- a/net/ipv4/netfilter/ipt_mark.c Tue Sep 2 19:58:20 2003 +++ b/net/ipv4/netfilter/ipt_mark.c Tue Sep 2 19:58:20 2003 @@ -5,6 +5,10 @@ #include #include +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Marc Boucher "); +MODULE_DESCRIPTION("iptables mark matching module"); + static int match(const struct sk_buff *skb, const struct net_device *in, @@ -50,4 +54,3 @@ module_init(init); module_exit(fini); -MODULE_LICENSE("GPL"); diff -Nru a/net/ipv4/netfilter/ipt_multiport.c b/net/ipv4/netfilter/ipt_multiport.c --- a/net/ipv4/netfilter/ipt_multiport.c Tue Sep 2 19:58:13 2003 +++ b/net/ipv4/netfilter/ipt_multiport.c Tue Sep 2 19:58:13 2003 @@ -8,6 +8,10 @@ #include #include +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Netfilter Core Team "); +MODULE_DESCRIPTION("iptables multiple port match module"); + #if 0 #define duprintf(format, args...) printk(format , ## args) #else @@ -106,4 +110,3 @@ module_init(init); module_exit(fini); -MODULE_LICENSE("GPL"); diff -Nru a/net/ipv4/netfilter/ipt_owner.c b/net/ipv4/netfilter/ipt_owner.c --- a/net/ipv4/netfilter/ipt_owner.c Tue Sep 2 19:58:19 2003 +++ b/net/ipv4/netfilter/ipt_owner.c Tue Sep 2 19:58:19 2003 @@ -11,6 +11,10 @@ #include #include +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Marc Boucher "); +MODULE_DESCRIPTION("iptables owner match"); + static int match_comm(const struct sk_buff *skb, const char *comm) { @@ -198,4 +202,3 @@ module_init(init); module_exit(fini); -MODULE_LICENSE("GPL"); diff -Nru a/net/ipv4/netfilter/ipt_physdev.c b/net/ipv4/netfilter/ipt_physdev.c --- a/net/ipv4/netfilter/ipt_physdev.c Tue Sep 2 19:58:14 2003 +++ b/net/ipv4/netfilter/ipt_physdev.c Tue Sep 2 19:58:14 2003 @@ -8,6 +8,10 @@ #define MATCH 1 #define NOMATCH 0 +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Bart De Schuymer "); +MODULE_DESCRIPTION("iptables bridge physical device match module"); + static int match(const struct sk_buff *skb, const struct net_device *in, @@ -120,4 +124,3 @@ module_init(init); module_exit(fini); -MODULE_LICENSE("GPL"); diff -Nru a/net/ipv4/netfilter/ipt_state.c b/net/ipv4/netfilter/ipt_state.c --- a/net/ipv4/netfilter/ipt_state.c Tue Sep 2 19:58:20 2003 +++ b/net/ipv4/netfilter/ipt_state.c Tue Sep 2 19:58:20 2003 @@ -7,6 +7,10 @@ #include #include +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Rusty Russell "); +MODULE_DESCRIPTION("iptables connection tracking state match module"); + static int match(const struct sk_buff *skb, const struct net_device *in, @@ -59,4 +63,3 @@ module_init(init); module_exit(fini); -MODULE_LICENSE("GPL"); diff -Nru a/net/ipv4/netfilter/ipt_tcpmss.c b/net/ipv4/netfilter/ipt_tcpmss.c --- a/net/ipv4/netfilter/ipt_tcpmss.c Tue Sep 2 19:58:13 2003 +++ b/net/ipv4/netfilter/ipt_tcpmss.c Tue Sep 2 19:58:13 2003 @@ -8,6 +8,10 @@ #define TH_SYN 0x02 +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Marc Boucher "); +MODULE_DESCRIPTION("iptables TCP MSS match module"); + /* Returns 1 if the mss option is set and matched by the range, 0 otherwise */ static inline int mssoption_match(u_int16_t min, u_int16_t max, @@ -117,4 +121,3 @@ module_init(init); module_exit(fini); -MODULE_LICENSE("GPL"); diff -Nru a/net/ipv4/netfilter/ipt_tos.c b/net/ipv4/netfilter/ipt_tos.c --- a/net/ipv4/netfilter/ipt_tos.c Tue Sep 2 19:58:19 2003 +++ b/net/ipv4/netfilter/ipt_tos.c Tue Sep 2 19:58:19 2003 @@ -5,6 +5,9 @@ #include #include +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("iptables TOS match module"); + static int match(const struct sk_buff *skb, const struct net_device *in, @@ -50,4 +53,3 @@ module_init(init); module_exit(fini); -MODULE_LICENSE("GPL"); diff -Nru a/net/ipv4/netfilter/ipt_unclean.c b/net/ipv4/netfilter/ipt_unclean.c --- a/net/ipv4/netfilter/ipt_unclean.c Tue Sep 2 19:58:16 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,610 +0,0 @@ -/* Kernel module to match suspect packets. */ -#include -#include -#include -#include -#include -#include -#include - -#include - -#define limpk(format, args...) \ -do { \ - if (net_ratelimit()) \ - printk("ipt_unclean: %s" format, \ - embedded ? "(embedded packet) " : "" , ## args); \ -} while(0) - -enum icmp_error_status -{ - ICMP_MAY_BE_ERROR, - ICMP_IS_ERROR, - ICMP_NOT_ERROR -}; - -struct icmp_info -{ - size_t min_len, max_len; - enum icmp_error_status err; - u_int8_t min_code, max_code; -}; - -static int -check_ip(const struct sk_buff *skb, unsigned int offset); - -/* ICMP-specific checks. */ -static int -check_icmp(const struct sk_buff *skb, - unsigned int offset, - unsigned int fragoff, - int more_frags, - int embedded) -{ - struct icmphdr icmph; - static struct icmp_info info[] - = { [ICMP_ECHOREPLY] - = { 8, 65536, ICMP_NOT_ERROR, 0, 0 }, - [ICMP_DEST_UNREACH] - = { 8 + 28, 65536, ICMP_IS_ERROR, 0, 15 }, - [ICMP_SOURCE_QUENCH] - = { 8 + 28, 65536, ICMP_IS_ERROR, 0, 0 }, - [ICMP_REDIRECT] - = { 8 + 28, 65536, ICMP_IS_ERROR, 0, 3 }, - [ICMP_ECHO] - = { 8, 65536, ICMP_NOT_ERROR, 0, 0 }, - /* Router advertisement. */ - [9] - = { 8, 8 + 255 * 8, ICMP_NOT_ERROR, 0, 0 }, - /* Router solicitation. */ - [10] - = { 8, 8, ICMP_NOT_ERROR, 0, 0 }, - [ICMP_TIME_EXCEEDED] - = { 8 + 28, 65536, ICMP_IS_ERROR, 0, 1 }, - [ICMP_PARAMETERPROB] - = { 8 + 28, 65536, ICMP_IS_ERROR, 0, 1 }, - [ICMP_TIMESTAMP] - = { 20, 20, ICMP_NOT_ERROR, 0, 0 }, - [ICMP_TIMESTAMPREPLY] - = { 20, 20, ICMP_NOT_ERROR, 0, 0 }, - [ICMP_INFO_REQUEST] - = { 8, 65536, ICMP_NOT_ERROR, 0, 0 }, - [ICMP_INFO_REPLY] - = { 8, 65536, ICMP_NOT_ERROR, 0, 0 }, - [ICMP_ADDRESS] - = { 12, 12, ICMP_NOT_ERROR, 0, 0 }, - [ICMP_ADDRESSREPLY] - = { 12, 12, ICMP_NOT_ERROR, 0, 0 } }; - - /* Can't do anything if it's a fragment. */ - if (fragoff) - return 1; - - /* CHECK: Must have whole header.. */ - if (skb_copy_bits(skb, offset, &icmph, sizeof(icmph)) < 0) { - limpk("ICMP len=%u too short\n", skb->len - offset); - return 0; - } - - /* If not embedded in an ICMP error already. */ - if (!embedded) { - /* CHECK: Truncated ICMP (even if first fragment). */ - if (icmph.type < sizeof(info)/sizeof(struct icmp_info) - && info[icmph.type].min_len != 0 - && skb->len - offset < info[icmph.type].min_len) { - limpk("ICMP type %u len %u too short\n", - icmph.type, skb->len - offset); - return 0; - } - - /* CHECK: Check within known error ICMPs. */ - if (icmph.type < sizeof(info)/sizeof(struct icmp_info) - && info[icmph.type].err == ICMP_IS_ERROR) { - /* Max IP header size = 60 */ - char inner[60 + 8]; - struct iphdr *inner_ip = (struct iphdr *)inner; - - /* CHECK: Embedded packet must be at least - length of iph + 8 bytes. */ - if (skb_copy_bits(skb, offset + sizeof(icmph), - inner, sizeof(struct iphdr)+8) < 0) { - limpk("ICMP error internal way too short\n"); - return 0; - } - - /* iphhdr may actually be longer: still need 8 - actual protocol bytes. */ - if (offset + sizeof(icmph) + inner_ip->ihl*4 + 8 - > skb->len) { - limpk("ICMP error internal too short\n"); - return 0; - } - if (!check_ip(skb, offset + sizeof(icmph))) - return 0; - } - } else { - /* CHECK: Can't embed ICMP unless known non-error. */ - if (icmph.type >= sizeof(info)/sizeof(struct icmp_info) - || info[icmph.type].err != ICMP_NOT_ERROR) { - limpk("ICMP type %u not embeddable\n", - icmph.type); - return 0; - } - } - - /* CHECK: Invalid ICMP codes. */ - if (icmph.type < sizeof(info)/sizeof(struct icmp_info) - && (icmph.code < info[icmph.type].min_code - || icmph.code > info[icmph.type].max_code)) { - limpk("ICMP type=%u code=%u\n", - icmph.type, icmph.code); - return 0; - } - - /* CHECK: Above maximum length. */ - if (icmph.type < sizeof(info)/sizeof(struct icmp_info) - && info[icmph.type].max_len != 0 - && skb->len - offset > info[icmph.type].max_len) { - limpk("ICMP type=%u too long: %u bytes\n", - icmph.type, skb->len - offset); - return 0; - } - - switch (icmph.type) { - case ICMP_PARAMETERPROB: { - /* CHECK: Problem param must be within error packet's - * IP header. */ - u_int32_t arg = ntohl(icmph.un.gateway); - - if (icmph.code == 0) { - /* We've already made sure it's long enough. */ - struct iphdr iph; - skb_copy_bits(skb, offset + sizeof(icmph), &iph, - sizeof(iph)); - /* Code 0 means that upper 8 bits is pointer - to problem. */ - if ((arg >> 24) >= iph.ihl*4) { - limpk("ICMP PARAMETERPROB ptr = %u\n", - ntohl(icmph.un.gateway) >> 24); - return 0; - } - arg &= 0x00FFFFFF; - } - - /* CHECK: Rest must be zero. */ - if (arg) { - limpk("ICMP PARAMETERPROB nonzero arg = %u\n", - arg); - return 0; - } - break; - } - - case ICMP_TIME_EXCEEDED: - case ICMP_SOURCE_QUENCH: - /* CHECK: Unused must be zero. */ - if (icmph.un.gateway != 0) { - limpk("ICMP type=%u unused = %u\n", - icmph.type, ntohl(icmph.un.gateway)); - return 0; - } - break; - } - - return 1; -} - -/* UDP-specific checks. */ -static int -check_udp(const struct sk_buff *skb, - unsigned int offset, - unsigned int fragoff, - int more_frags, - int embedded) -{ - struct udphdr udph; - - /* Can't do anything if it's a fragment. */ - if (fragoff) - return 1; - - /* CHECK: Must cover UDP header. */ - if (skb_copy_bits(skb, offset, &udph, sizeof(udph)) < 0) { - limpk("UDP len=%u too short\n", skb->len - offset); - return 0; - } - - /* CHECK: Destination port can't be zero. */ - if (!udph.dest) { - limpk("UDP zero destination port\n"); - return 0; - } - - if (!more_frags) { - if (!embedded) { - /* CHECK: UDP length must match. */ - if (ntohs(udph.len) != skb->len - offset) { - limpk("UDP len too short %u vs %u\n", - ntohs(udph.len), skb->len - offset); - return 0; - } - } else { - /* CHECK: UDP length be >= this truncated pkt. */ - if (ntohs(udph.len) < skb->len - offset) { - limpk("UDP len too long %u vs %u\n", - ntohs(udph.len), skb->len - offset); - return 0; - } - } - } else { - /* CHECK: UDP length must be > this frag's length. */ - if (ntohs(udph.len) <= skb->len - offset) { - limpk("UDP fragment len too short %u vs %u\n", - ntohs(udph.len), skb->len - offset); - return 0; - } - } - - return 1; -} - -/* TCP-specific checks. */ -static int -check_tcp(const struct sk_buff *skb, - unsigned int offset, - unsigned int fragoff, - int more_frags, - int embedded) -{ - struct tcphdr tcph; - unsigned char opt[15 * 4 - sizeof(struct tcphdr)]; - u32 tcpflags; - int end_of_options = 0; - unsigned int i, optlen; - - /* CHECK: Can't have offset=1: used to override TCP syn-checks. */ - /* In fact, this is caught below (offset < 516). */ - - /* Can't do anything if it's a fragment. */ - if (fragoff) - return 1; - - /* CHECK: Smaller than minimal TCP hdr. */ - if (skb_copy_bits(skb, offset, &tcph, sizeof(tcph)) < 0) { - u16 ports[2]; - - if (!embedded) { - limpk("Packet length %u < TCP header.\n", - skb->len - offset); - return 0; - } - - /* Must have ports available (datalen >= 8), from - check_icmp which set embedded = 1 */ - /* CHECK: TCP ports inside ICMP error */ - skb_copy_bits(skb, offset, ports, sizeof(ports)); - if (!ports[0] || !ports[1]) { - limpk("Zero TCP ports %u/%u.\n", - htons(ports[0]), htons(ports[1])); - return 0; - } - return 1; - } - - /* CHECK: TCP header claims tiny size. */ - if (tcph.doff * 4 < sizeof(tcph)) { - limpk("TCP header claims tiny size %u\n", tcph.doff * 4); - return 0; - } - - /* CHECK: Packet smaller than actual TCP hdr. */ - optlen = tcph.doff*4 - sizeof(tcph); - if (skb_copy_bits(skb, offset + sizeof(tcph), opt, optlen) < 0) { - if (!embedded) { - limpk("Packet length %u < actual TCP header.\n", - skb->len - offset); - return 0; - } else - return 1; - } - - /* CHECK: TCP ports non-zero */ - if (!tcph.source || !tcph.dest) { - limpk("Zero TCP ports %u/%u.\n", - htons(tcph.source), htons(tcph.dest)); - return 0; - } - - tcpflags = tcp_flag_word(&tcph); - - /* CHECK: TCP reserved bits zero. */ - if (tcpflags & TCP_RESERVED_BITS) { - limpk("TCP reserved bits not zero\n"); - return 0; - } - - tcpflags &= ~(TCP_DATA_OFFSET | TCP_FLAG_CWR | TCP_FLAG_ECE - | __constant_htonl(0x0000FFFF)); - - /* CHECK: TCP flags. */ - if (tcpflags != TCP_FLAG_SYN - && tcpflags != (TCP_FLAG_SYN|TCP_FLAG_ACK) - && tcpflags != TCP_FLAG_RST - && tcpflags != (TCP_FLAG_RST|TCP_FLAG_ACK) - && tcpflags != (TCP_FLAG_RST|TCP_FLAG_ACK|TCP_FLAG_PSH) - && tcpflags != (TCP_FLAG_FIN|TCP_FLAG_ACK) - && tcpflags != TCP_FLAG_ACK - && tcpflags != (TCP_FLAG_ACK|TCP_FLAG_PSH) - && tcpflags != (TCP_FLAG_ACK|TCP_FLAG_URG) - && tcpflags != (TCP_FLAG_ACK|TCP_FLAG_URG|TCP_FLAG_PSH) - && tcpflags != (TCP_FLAG_FIN|TCP_FLAG_ACK|TCP_FLAG_PSH) - && tcpflags != (TCP_FLAG_FIN|TCP_FLAG_ACK|TCP_FLAG_URG) - && tcpflags != (TCP_FLAG_FIN|TCP_FLAG_ACK|TCP_FLAG_URG - |TCP_FLAG_PSH)) { - limpk("TCP flags bad: 0x%04X\n", ntohl(tcpflags) >> 16); - return 0; - } - - for (i = 0; i < optlen; ) { - switch (opt[i]) { - case 0: - end_of_options = 1; - i++; - break; - case 1: - i++; - break; - default: - /* CHECK: options after EOO. */ - if (end_of_options) { - limpk("TCP option %u after end\n", - opt[i]); - return 0; - } - /* CHECK: options at tail. */ - else if (i+1 >= optlen) { - limpk("TCP option %u at tail\n", - opt[i]); - return 0; - } - /* CHECK: zero-length options. */ - else if (opt[i+1] == 0) { - limpk("TCP option %u 0 len\n", - opt[i]); - return 0; - } - /* CHECK: oversize options. */ - else if (i + opt[i+1] > optlen) { - limpk("TCP option %u at %u too long\n", - (unsigned int) opt[i], i); - return 0; - } - /* Move to next option */ - i += opt[i+1]; - } - } - - return 1; -} - -/* Returns 1 if ok */ -/* Standard IP checks. */ -static int -check_ip(const struct sk_buff *skb, unsigned int offset) -{ - int end_of_options = 0; - unsigned int datalen, optlen; - unsigned int i; - unsigned int fragoff; - struct iphdr iph; - unsigned char opt[15 * 4 - sizeof(struct iphdr)]; - int embedded = offset; - - /* Should only happen for local outgoing raw-socket packets. */ - /* CHECK: length >= ip header. */ - if (skb_copy_bits(skb, offset, &iph, sizeof(iph)) < 0) { - limpk("Packet length %u < IP header.\n", skb->len - offset); - return 0; - } - if (iph.ihl * 4 < sizeof(iph)) { - limpk("IP len %u < minimum IP header.\n", iph.ihl*4); - return 0; - } - - optlen = iph.ihl * 4 - sizeof(iph); - if (skb_copy_bits(skb, offset+sizeof(struct iphdr), opt, optlen)<0) { - limpk("Packet length %u < IP header %u.\n", - skb->len - offset, iph.ihl * 4); - return 0; - } - - fragoff = (ntohs(iph.frag_off) & IP_OFFSET); - datalen = skb->len - (offset + sizeof(struct iphdr) + optlen); - - /* CHECK: Embedded fragment. */ - if (offset && fragoff) { - limpk("Embedded fragment.\n"); - return 0; - } - - for (i = 0; i < optlen; ) { - switch (opt[i]) { - case 0: - end_of_options = 1; - i++; - break; - case 1: - i++; - break; - default: - /* CHECK: options after EOO. */ - if (end_of_options) { - limpk("IP option %u after end\n", - opt[i]); - return 0; - } - /* CHECK: options at tail. */ - else if (i+1 >= optlen) { - limpk("IP option %u at tail\n", - opt[i]); - return 0; - } - /* CHECK: zero-length or one-length options. */ - else if (opt[i+1] < 2) { - limpk("IP option %u %u len\n", - opt[i], opt[i+1]); - return 0; - } - /* CHECK: oversize options. */ - else if (i + opt[i+1] > optlen) { - limpk("IP option %u at %u too long\n", - opt[i], i); - return 0; - } - /* Move to next option */ - i += opt[i+1]; - } - } - - /* Fragment checks. */ - - /* CHECK: More fragments, but doesn't fill 8-byte boundary. */ - if ((ntohs(iph.frag_off) & IP_MF) - && (ntohs(iph.tot_len) % 8) != 0) { - limpk("Truncated fragment %u long.\n", ntohs(iph.tot_len)); - return 0; - } - - /* CHECK: Oversize fragment a-la Ping of Death. */ - if (fragoff * 8 + datalen > 65535) { - limpk("Oversize fragment to %u.\n", fragoff * 8); - return 0; - } - - /* CHECK: DF set and fragoff or MF set. */ - if ((ntohs(iph.frag_off) & IP_DF) - && (fragoff || (ntohs(iph.frag_off) & IP_MF))) { - limpk("DF set and offset=%u, MF=%u.\n", - fragoff, ntohs(iph.frag_off) & IP_MF); - return 0; - } - - /* CHECK: Zero-sized fragments. */ - if ((fragoff || (ntohs(iph.frag_off) & IP_MF)) - && datalen == 0) { - limpk("Zero size fragment offset=%u\n", fragoff); - return 0; - } - - /* Note: we can have even middle fragments smaller than this: - consider a large packet passing through a 600MTU then - 576MTU link: this gives a fragment of 24 data bytes. But - everyone packs fragments largest first, hence a fragment - can't START before 576 - MAX_IP_HEADER_LEN. */ - - /* Used to be min-size 576: I recall Alan Cox saying ax25 goes - down to 128 (576 taken from RFC 791: All hosts must be - prepared to accept datagrams of up to 576 octets). Use 128 - here. */ -#define MIN_LIKELY_MTU 128 - /* CHECK: Min size of first frag = 128. */ - if ((ntohs(iph.frag_off) & IP_MF) - && fragoff == 0 - && ntohs(iph.tot_len) < MIN_LIKELY_MTU) { - limpk("First fragment size %u < %u\n", ntohs(iph.tot_len), - MIN_LIKELY_MTU); - return 0; - } - - /* CHECK: Min offset of frag = 128 - IP hdr len. */ - if (fragoff && fragoff * 8 < MIN_LIKELY_MTU - iph.ihl * 4) { - limpk("Fragment starts at %u < %u\n", fragoff * 8, - MIN_LIKELY_MTU - iph.ihl * 4); - return 0; - } - - /* CHECK: Protocol specification non-zero. */ - if (iph.protocol == 0) { - limpk("Zero protocol\n"); - return 0; - } - - /* FIXME: This is already checked for in "Oversize fragment" - above --RR */ - /* CHECK: Do not use what is unused. - * First bit of fragmentation flags should be unused. - * May be used by OS fingerprinting tools. - * 04 Jun 2002, Maciej Soltysiak, solt@dns.toxicfilms.tv - */ - if (ntohs(iph.frag_off)>>15) { - limpk("IP unused bit set\n"); - return 0; - } - - /* Per-protocol checks. */ - switch (iph.protocol) { - case IPPROTO_ICMP: - return check_icmp(skb, offset + iph.ihl*4, fragoff, - (ntohs(iph.frag_off) & IP_MF), - embedded); - - case IPPROTO_UDP: - return check_udp(skb, offset + iph.ihl*4, fragoff, - (ntohs(iph.frag_off) & IP_MF), - embedded); - - case IPPROTO_TCP: - return check_tcp(skb, offset + iph.ihl*4, fragoff, - (ntohs(iph.frag_off) & IP_MF), - embedded); - default: - /* Ignorance is bliss. */ - return 1; - } -} - -static int -match(const struct sk_buff *skb, - const struct net_device *in, - const struct net_device *out, - const void *matchinfo, - int offset, - int *hotdrop) -{ - return !check_ip(skb, 0); -} - -/* Called when user tries to insert an entry of this type. */ -static int -checkentry(const char *tablename, - const struct ipt_ip *ip, - void *matchinfo, - unsigned int matchsize, - unsigned int hook_mask) -{ - if (matchsize != IPT_ALIGN(0)) - return 0; - - return 1; -} - -static struct ipt_match unclean_match = { - .name = "unclean", - .match = &match, - .checkentry = &checkentry, - .me = THIS_MODULE, -}; - -static int __init init(void) -{ - return ipt_register_match(&unclean_match); -} - -static void __exit fini(void) -{ - ipt_unregister_match(&unclean_match); -} - -module_init(init); -module_exit(fini); -MODULE_LICENSE("GPL"); diff -Nru a/net/ipv4/netfilter/iptable_filter.c b/net/ipv4/netfilter/iptable_filter.c --- a/net/ipv4/netfilter/iptable_filter.c Tue Sep 2 19:58:15 2003 +++ b/net/ipv4/netfilter/iptable_filter.c Tue Sep 2 19:58:15 2003 @@ -6,6 +6,10 @@ #include #include +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Netfilter Core Team "); +MODULE_DESCRIPTION("iptables filter table"); + #define FILTER_VALID_HOOKS ((1 << NF_IP_LOCAL_IN) | (1 << NF_IP_FORWARD) | (1 << NF_IP_LOCAL_OUT)) /* Standard entry. */ @@ -200,4 +204,3 @@ module_init(init); module_exit(fini); -MODULE_LICENSE("GPL"); diff -Nru a/net/ipv4/netfilter/iptable_mangle.c b/net/ipv4/netfilter/iptable_mangle.c --- a/net/ipv4/netfilter/iptable_mangle.c Tue Sep 2 19:58:18 2003 +++ b/net/ipv4/netfilter/iptable_mangle.c Tue Sep 2 19:58:18 2003 @@ -14,6 +14,10 @@ #include #include +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Netfilter Core Team "); +MODULE_DESCRIPTION("iptables mangle table"); + #define MANGLE_VALID_HOOKS ((1 << NF_IP_PRE_ROUTING) | \ (1 << NF_IP_LOCAL_IN) | \ (1 << NF_IP_FORWARD) | \ @@ -267,4 +271,3 @@ module_init(init); module_exit(fini); -MODULE_LICENSE("GPL"); diff -Nru a/net/ipv4/route.c b/net/ipv4/route.c --- a/net/ipv4/route.c Tue Sep 2 19:58:19 2003 +++ b/net/ipv4/route.c Tue Sep 2 19:58:20 2003 @@ -312,49 +312,6 @@ return 0; } -static int rt_cache_stat_get_info(char *buffer, char **start, off_t offset, int length) -{ - unsigned int dst_entries = atomic_read(&ipv4_dst_ops.entries); - int i; - int len = 0; - - for (i = 0; i < NR_CPUS; i++) { - if (!cpu_possible(i)) - continue; - len += sprintf(buffer+len, "%08x %08x %08x %08x %08x %08x %08x %08x %08x %08x %08x %08x %08x %08x %08x %08x %08x \n", - dst_entries, - per_cpu_ptr(rt_cache_stat, i)->in_hit, - per_cpu_ptr(rt_cache_stat, i)->in_slow_tot, - per_cpu_ptr(rt_cache_stat, i)->in_slow_mc, - per_cpu_ptr(rt_cache_stat, i)->in_no_route, - per_cpu_ptr(rt_cache_stat, i)->in_brd, - per_cpu_ptr(rt_cache_stat, i)->in_martian_dst, - per_cpu_ptr(rt_cache_stat, i)->in_martian_src, - - per_cpu_ptr(rt_cache_stat, i)->out_hit, - per_cpu_ptr(rt_cache_stat, i)->out_slow_tot, - per_cpu_ptr(rt_cache_stat, i)->out_slow_mc, - - per_cpu_ptr(rt_cache_stat, i)->gc_total, - per_cpu_ptr(rt_cache_stat, i)->gc_ignored, - per_cpu_ptr(rt_cache_stat, i)->gc_goal_miss, - per_cpu_ptr(rt_cache_stat, i)->gc_dst_overflow, - per_cpu_ptr(rt_cache_stat, i)->in_hlist_search, - per_cpu_ptr(rt_cache_stat, i)->out_hlist_search - - ); - } - len -= offset; - - if (len > length) - len = length; - if (len < 0) - len = 0; - - *start = buffer + offset; - return len; -} - static struct seq_operations rt_cache_seq_ops = { .start = rt_cache_seq_start, .next = rt_cache_seq_next, @@ -391,22 +348,89 @@ .release = seq_release_private, }; -int __init rt_cache_proc_init(void) + +static void *rt_cpu_seq_start(struct seq_file *seq, loff_t *pos) { - int rc = 0; - struct proc_dir_entry *p = create_proc_entry("rt_cache", S_IRUGO, - proc_net); - if (p) - p->proc_fops = &rt_cache_seq_fops; - else - rc = -ENOMEM; - return rc; + int cpu; + + for (cpu = *pos; cpu < NR_CPUS; ++cpu) { + if (!cpu_possible(cpu)) + continue; + *pos = cpu; + return per_cpu_ptr(rt_cache_stat, cpu); + } + return NULL; +} + +static void *rt_cpu_seq_next(struct seq_file *seq, void *v, loff_t *pos) +{ + int cpu; + + for (cpu = *pos + 1; cpu < NR_CPUS; ++cpu) { + if (!cpu_possible(cpu)) + continue; + *pos = cpu; + return per_cpu_ptr(rt_cache_stat, cpu); + } + return NULL; + } -void __init rt_cache_proc_exit(void) +static void rt_cpu_seq_stop(struct seq_file *seq, void *v) { - remove_proc_entry("rt_cache", proc_net); + } + +static int rt_cpu_seq_show(struct seq_file *seq, void *v) +{ + struct rt_cache_stat *st = v; + + seq_printf(seq,"%08x %08x %08x %08x %08x %08x %08x %08x " + " %08x %08x %08x %08x %08x %08x %08x %08x %08x \n", + atomic_read(&ipv4_dst_ops.entries), + st->in_hit, + st->in_slow_tot, + st->in_slow_mc, + st->in_no_route, + st->in_brd, + st->in_martian_dst, + st->in_martian_src, + + st->out_hit, + st->out_slow_tot, + st->out_slow_mc, + + st->gc_total, + st->gc_ignored, + st->gc_goal_miss, + st->gc_dst_overflow, + st->in_hlist_search, + st->out_hlist_search + ); + return 0; +} + +static struct seq_operations rt_cpu_seq_ops = { + .start = rt_cpu_seq_start, + .next = rt_cpu_seq_next, + .stop = rt_cpu_seq_stop, + .show = rt_cpu_seq_show, +}; + + +static int rt_cpu_seq_open(struct inode *inode, struct file *file) +{ + return seq_open(file, &rt_cpu_seq_ops); +} + +static struct file_operations rt_cpu_seq_fops = { + .owner = THIS_MODULE, + .open = rt_cpu_seq_open, + .read = seq_read, + .llseek = seq_lseek, + .release = seq_release_private, +}; + #endif /* CONFIG_PROC_FS */ static __inline__ void rt_free(struct rtable *rt) @@ -2779,11 +2803,12 @@ add_timer(&rt_secret_timer); #ifdef CONFIG_PROC_FS - if (rt_cache_proc_init()) + if (!proc_net_fops_create("rt_cache", S_IRUGO, &rt_cache_seq_fops) || + !proc_net_fops_create("rt_cache_stat", S_IRUGO, &rt_cpu_seq_fops)) goto out_enomem; - proc_net_create ("rt_cache_stat", 0, rt_cache_stat_get_info); + #ifdef CONFIG_NET_CLS_ROUTE - create_proc_read_entry("net/rt_acct", 0, 0, ip_rt_acct_read, NULL); + create_proc_read_entry("rt_acct", 0, proc_net, ip_rt_acct_read, NULL); #endif #endif #ifdef CONFIG_XFRM diff -Nru a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c --- a/net/ipv6/af_inet6.c Tue Sep 2 19:58:16 2003 +++ b/net/ipv6/af_inet6.c Tue Sep 2 19:58:16 2003 @@ -893,3 +893,5 @@ } module_exit(inet6_exit); #endif /* MODULE */ + +MODULE_ALIAS_NETPROTO(PF_INET6); diff -Nru a/net/ipv6/icmp.c b/net/ipv6/icmp.c --- a/net/ipv6/icmp.c Tue Sep 2 19:58:14 2003 +++ b/net/ipv6/icmp.c Tue Sep 2 19:58:14 2003 @@ -70,12 +70,14 @@ DEFINE_SNMP_STAT(struct icmpv6_mib, icmpv6_statistics); /* - * ICMP socket(s) for flow control. + * The ICMP socket(s). This is the most convenient way to flow control + * our ICMP output as well as maintain a clean interface throughout + * all layers. All Socketless IP sends will soon be gone. + * + * On SMP we have one ICMP socket per-cpu. */ - -/* XXX We can't use per_cpu because this can be modular... */ -static struct socket *__icmpv6_socket[NR_CPUS]; -#define icmpv6_socket __icmpv6_socket[smp_processor_id()] +static DEFINE_PER_CPU(struct socket *, __icmpv6_socket) = NULL; +#define icmpv6_socket __get_cpu_var(__icmpv6_socket) static int icmpv6_rcv(struct sk_buff **pskb, unsigned int *nhoffp); @@ -93,11 +95,19 @@ __u32 csum; }; -static __inline__ void icmpv6_xmit_lock(void) +static __inline__ int icmpv6_xmit_lock(void) { local_bh_disable(); - if (unlikely(!spin_trylock(&icmpv6_socket->sk->sk_lock.slock))) - BUG(); + + if (unlikely(!spin_trylock(&icmpv6_socket->sk->sk_lock.slock))) { + /* This can happen if the output path (f.e. SIT or + * ip6ip6 tunnel) signals dst_link_failure() for an + * outgoing ICMP6 packet. + */ + local_bh_enable(); + return 1; + } + return 0; } static __inline__ void icmpv6_xmit_unlock(void) @@ -342,7 +352,8 @@ fl.fl_icmp_type = type; fl.fl_icmp_code = code; - icmpv6_xmit_lock(); + if (icmpv6_xmit_lock()) + return; if (!icmpv6_xrlim_allow(sk, type, &fl)) goto out; @@ -432,7 +443,8 @@ fl.oif = skb->dev->ifindex; fl.fl_icmp_type = ICMPV6_ECHO_REPLY; - icmpv6_xmit_lock(); + if (icmpv6_xmit_lock()) + return; if (!fl.oif && ipv6_addr_is_multicast(&fl.fl6_dst)) fl.oif = np->mcast_oif; @@ -657,33 +669,23 @@ int __init icmpv6_init(struct net_proto_family *ops) { struct sock *sk; - int i; + int err, i, j; for (i = 0; i < NR_CPUS; i++) { - int err; - if (!cpu_possible(i)) continue; err = sock_create(PF_INET6, SOCK_RAW, IPPROTO_ICMPV6, - &__icmpv6_socket[i]); + &per_cpu(__icmpv6_socket, i)); if (err < 0) { - int j; - printk(KERN_ERR "Failed to initialize the ICMP6 control socket " "(err %d).\n", err); - for (j = 0; j < i; j++) { - if (!cpu_possible(j)) - continue; - sock_release(__icmpv6_socket[j]); - __icmpv6_socket[j] = NULL; /* for safety */ - } - return err; + goto fail; } - sk = __icmpv6_socket[i]->sk; + sk = per_cpu(__icmpv6_socket, i)->sk; sk->sk_allocation = GFP_ATOMIC; sk->sk_sndbuf = SK_WMEM_MAX * 2; sk->sk_prot->unhash(sk); @@ -692,16 +694,20 @@ if (inet6_add_protocol(&icmpv6_protocol, IPPROTO_ICMPV6) < 0) { printk(KERN_ERR "Failed to register ICMP6 protocol\n"); - for (i = 0; i < NR_CPUS; i++) { - if (!cpu_possible(i)) - continue; - sock_release(__icmpv6_socket[i]); - __icmpv6_socket[i] = NULL; - } - return -EAGAIN; + err = -EAGAIN; + goto fail; } return 0; + + fail: + for (j = 0; j < i; j++) { + if (!cpu_possible(j)) + continue; + sock_release(per_cpu(__icmpv6_socket, j)); + } + + return err; } void icmpv6_cleanup(void) @@ -711,8 +717,7 @@ for (i = 0; i < NR_CPUS; i++) { if (!cpu_possible(i)) continue; - sock_release(__icmpv6_socket[i]); - __icmpv6_socket[i] = NULL; /* For safety. */ + sock_release(per_cpu(__icmpv6_socket, i)); } inet6_del_protocol(&icmpv6_protocol, IPPROTO_ICMPV6); } diff -Nru a/net/ipv6/ip6_flowlabel.c b/net/ipv6/ip6_flowlabel.c --- a/net/ipv6/ip6_flowlabel.c Tue Sep 2 19:58:14 2003 +++ b/net/ipv6/ip6_flowlabel.c Tue Sep 2 19:58:14 2003 @@ -49,7 +49,8 @@ static atomic_t fl_size = ATOMIC_INIT(0); static struct ip6_flowlabel *fl_ht[FL_HASH_MASK+1]; -static struct timer_list ip6_fl_gc_timer; +static void ip6_fl_gc(unsigned long dummy); +static struct timer_list ip6_fl_gc_timer = TIMER_INITIALIZER(ip6_fl_gc, 0, 0); /* FL hash table lock: it protects only of GC */ @@ -93,10 +94,12 @@ static void fl_release(struct ip6_flowlabel *fl) { + write_lock_bh(&ip6_fl_lock); + fl->lastuse = jiffies; if (atomic_dec_and_test(&fl->users)) { unsigned long ttd = fl->lastuse + fl->linger; - if ((long)(ttd - fl->expires) > 0) + if (time_after(ttd, fl->expires)) fl->expires = ttd; ttd = fl->expires; if (fl->opt && fl->share == IPV6_FL_S_EXCL) { @@ -104,11 +107,12 @@ fl->opt = NULL; kfree(opt); } - if (!del_timer(&ip6_fl_gc_timer) || - (long)(ip6_fl_gc_timer.expires - ttd) > 0) - ip6_fl_gc_timer.expires = ttd; - add_timer(&ip6_fl_gc_timer); + if (!timer_pending(&ip6_fl_gc_timer) || + time_after(ip6_fl_gc_timer.expires, ttd)) + mod_timer(&ip6_fl_gc_timer, ttd); } + + write_unlock_bh(&ip6_fl_lock); } static void ip6_fl_gc(unsigned long dummy) @@ -125,16 +129,16 @@ while ((fl=*flp) != NULL) { if (atomic_read(&fl->users) == 0) { unsigned long ttd = fl->lastuse + fl->linger; - if ((long)(ttd - fl->expires) > 0) + if (time_after(ttd, fl->expires)) fl->expires = ttd; ttd = fl->expires; - if ((long)(now - ttd) >= 0) { + if (time_after_eq(now, ttd)) { *flp = fl->next; fl_free(fl); atomic_dec(&fl_size); continue; } - if (!sched || (long)(ttd - sched) < 0) + if (!sched || time_before(ttd, sched)) sched = ttd; } flp = &fl->next; @@ -245,7 +249,7 @@ return opt_space; } -static __u32 check_linger(__u16 ttl) +static unsigned long check_linger(unsigned long ttl) { if (ttl < FL_MIN_LINGER) return FL_MIN_LINGER*HZ; @@ -254,7 +258,7 @@ return ttl*HZ; } -static int fl6_renew(struct ip6_flowlabel *fl, unsigned linger, unsigned expires) +static int fl6_renew(struct ip6_flowlabel *fl, unsigned long linger, unsigned long expires) { linger = check_linger(linger); if (!linger) @@ -263,11 +267,11 @@ if (!expires) return -EPERM; fl->lastuse = jiffies; - if (fl->linger < linger) + if (time_before(fl->linger, linger)) fl->linger = linger; - if (expires < fl->linger) + if (time_before(expires, fl->linger)) expires = fl->linger; - if ((long)(fl->expires - (fl->lastuse+expires)) < 0) + if (time_before(fl->expires, fl->lastuse + expires)) fl->expires = fl->lastuse + expires; return 0; } @@ -623,7 +627,7 @@ { while(fl) { seq_printf(seq, - "%05X %-1d %-6d %-6d %-6d %-8ld " + "%05X %-1d %-6d %-6d %-6ld %-8ld " "%02x%02x%02x%02x%02x%02x%02x%02x " "%-4d\n", (unsigned)ntohl(fl->label), @@ -693,8 +697,6 @@ #ifdef CONFIG_PROC_FS struct proc_dir_entry *p; #endif - init_timer(&ip6_fl_gc_timer); - ip6_fl_gc_timer.function = ip6_fl_gc; #ifdef CONFIG_PROC_FS p = create_proc_entry("ip6_flowlabel", S_IRUGO, proc_net); if (p) diff -Nru a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c --- a/net/ipv6/ip6_output.c Tue Sep 2 19:58:13 2003 +++ b/net/ipv6/ip6_output.c Tue Sep 2 19:58:13 2003 @@ -876,7 +876,7 @@ /* Connection association is same as pre-frag packet */ to->nfct = from->nfct; nf_conntrack_get(to->nfct); -#if defined(CONFIG_BRIDGE) || defined(CONFIG_BRIDGE_MODULE) +#ifdef CONFIG_BRIDGE_NETFILTER to->nf_bridge = from->nf_bridge; nf_bridge_get(to->nf_bridge); #endif diff -Nru a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c --- a/net/ipv6/ip6_tunnel.c Tue Sep 2 19:58:13 2003 +++ b/net/ipv6/ip6_tunnel.c Tue Sep 2 19:58:13 2003 @@ -23,7 +23,6 @@ #include #include #include -#include #include #include #include @@ -37,12 +36,12 @@ #include #include #include +#include #include #include #include -#include #include #include #include @@ -63,22 +62,6 @@ #define IPV6_TCLASS_MASK (IPV6_FLOWINFO_MASK & ~IPV6_FLOWLABEL_MASK) -/* socket(s) used by ip6ip6_tnl_xmit() for resending packets */ -static struct socket *__ip6_socket[NR_CPUS]; -#define ip6_socket __ip6_socket[smp_processor_id()] - -static void ip6_xmit_lock(void) -{ - local_bh_disable(); - if (unlikely(!spin_trylock(&ip6_socket->sk->sk_lock.slock))) - BUG(); -} - -static void ip6_xmit_unlock(void) -{ - spin_unlock_bh(&ip6_socket->sk->sk_lock.slock); -} - #define HASH_SIZE 32 #define HASH(addr) (((addr)->s6_addr32[0] ^ (addr)->s6_addr32[1] ^ \ @@ -101,6 +84,33 @@ /* lock for the tunnel lists */ static rwlock_t ip6ip6_lock = RW_LOCK_UNLOCKED; +static inline struct dst_entry *ip6_tnl_dst_check(struct ip6_tnl *t) +{ + struct dst_entry *dst = t->dst_cache; + + if (dst && dst->obsolete && + dst->ops->check(dst, t->dst_cookie) == NULL) { + t->dst_cache = NULL; + return NULL; + } + + return dst; +} + +static inline void ip6_tnl_dst_reset(struct ip6_tnl *t) +{ + dst_release(t->dst_cache); + t->dst_cache = NULL; +} + +static inline void ip6_tnl_dst_store(struct ip6_tnl *t, struct dst_entry *dst) +{ + struct rt6_info *rt = (struct rt6_info *) dst; + t->dst_cookie = rt->rt6i_node ? rt->rt6i_node->fn_sernum : 0; + dst_release(t->dst_cache); + t->dst_cache = dst; +} + /** * ip6ip6_tnl_lookup - fetch tunnel matching the end-point addresses * @remote: the address of the tunnel exit-point @@ -294,13 +304,16 @@ static void ip6ip6_tnl_dev_uninit(struct net_device *dev) { + struct ip6_tnl *t = dev->priv; + if (dev == ip6ip6_fb_tnl_dev) { write_lock_bh(&ip6ip6_lock); tnls_wc[0] = NULL; write_unlock_bh(&ip6ip6_lock); } else { - ip6ip6_tnl_unlink((struct ip6_tnl *) dev->priv); + ip6ip6_tnl_unlink(t); } + ip6_tnl_dst_reset(t); dev_put(dev); } @@ -421,7 +434,7 @@ } teli = parse_tlv_tnl_enc_lim(skb, skb->data); - if (teli && teli == info - 2) { + if (teli && teli == ntohl(info) - 2) { tel = (struct ipv6_tlv_tnl_enc_lim *) &skb->data[teli]; if (tel->encap_limit == 0) { if (net_ratelimit()) @@ -434,10 +447,9 @@ } break; case ICMPV6_PKT_TOOBIG: - mtu = info - offset; - if (mtu <= IPV6_MIN_MTU) { + mtu = ntohl(info) - offset; + if (mtu < IPV6_MIN_MTU) mtu = IPV6_MIN_MTU; - } t->dev->mtu = mtu; if ((len = sizeof (*ipv6h) + ipv6h->payload_len) > mtu) { @@ -523,112 +535,34 @@ return 0; } -/** - * txopt_len - get necessary size for new &struct ipv6_txoptions - * @orig_opt: old options - * - * Return: - * Size of old one plus size of tunnel encapsulation limit option - **/ - -static inline int -txopt_len(struct ipv6_txoptions *orig_opt) -{ - int len = sizeof (*orig_opt) + 8; - - if (orig_opt && orig_opt->dst0opt) - len += ipv6_optlen(orig_opt->dst0opt); - return len; -} - -/** - * merge_options - add encapsulation limit to original options - * @encap_limit: number of allowed encapsulation limits - * @orig_opt: original options - * - * Return: - * Pointer to new &struct ipv6_txoptions containing the tunnel - * encapsulation limit - **/ - -static struct ipv6_txoptions * -merge_options(struct sock *sk, __u8 encap_limit, - struct ipv6_txoptions *orig_opt) +static inline struct ipv6_txoptions *create_tel(__u8 encap_limit) { struct ipv6_tlv_tnl_enc_lim *tel; struct ipv6_txoptions *opt; __u8 *raw; - __u8 pad_to = 8; - int opt_len = txopt_len(orig_opt); - if (!(opt = sock_kmalloc(sk, opt_len, GFP_ATOMIC))) { + int opt_len = sizeof(*opt) + 8; + + if (!(opt = kmalloc(opt_len, GFP_ATOMIC))) { return NULL; } - memset(opt, 0, opt_len); opt->tot_len = opt_len; opt->dst0opt = (struct ipv6_opt_hdr *) (opt + 1); opt->opt_nflen = 8; - raw = (__u8 *) opt->dst0opt; - tel = (struct ipv6_tlv_tnl_enc_lim *) (opt->dst0opt + 1); tel->type = IPV6_TLV_TNL_ENCAP_LIMIT; tel->length = 1; tel->encap_limit = encap_limit; - if (orig_opt) { - __u8 *orig_raw; - - opt->hopopt = orig_opt->hopopt; - - /* Keep the original destination options properly - aligned and merge possible old paddings to the - new padding option */ - if ((orig_raw = (__u8 *) orig_opt->dst0opt) != NULL) { - __u8 type; - int i = sizeof (struct ipv6_opt_hdr); - pad_to += sizeof (struct ipv6_opt_hdr); - while (i < ipv6_optlen(orig_opt->dst0opt)) { - type = orig_raw[i++]; - if (type == IPV6_TLV_PAD0) - pad_to++; - else if (type == IPV6_TLV_PADN) { - int len = orig_raw[i++]; - i += len; - pad_to += len + 2; - } else { - break; - } - } - opt->dst0opt->hdrlen = orig_opt->dst0opt->hdrlen + 1; - memcpy(raw + pad_to, orig_raw + pad_to - 8, - opt_len - sizeof (*opt) - pad_to); - } - opt->srcrt = orig_opt->srcrt; - opt->opt_nflen += orig_opt->opt_nflen; - - opt->dst1opt = orig_opt->dst1opt; - opt->auth = orig_opt->auth; - opt->opt_flen = orig_opt->opt_flen; - } + raw = (__u8 *) opt->dst0opt; raw[5] = IPV6_TLV_PADN; - - /* subtract lengths of destination suboption header, - tunnel encapsulation limit and pad N header */ - raw[6] = pad_to - 7; + raw[6] = 1; return opt; } -static int -ip6ip6_getfrag(void *from, char *to, int offset, int len, int odd, - struct sk_buff *skb) -{ - memcpy(to, (char *) from + offset, len); - return 0; -} - /** * ip6ip6_tnl_addr_conflict - compare packet addresses to tunnel's own * @t: the outgoing tunnel device @@ -656,7 +590,7 @@ * * Description: * Build new header and do some sanity checks on the packet before sending - * it to ip6_build_xmit(). + * it. * * Return: * 0 @@ -667,18 +601,17 @@ struct ip6_tnl *t = (struct ip6_tnl *) dev->priv; struct net_device_stats *stats = &t->stat; struct ipv6hdr *ipv6h = skb->nh.ipv6h; - struct ipv6_txoptions *orig_opt = NULL; struct ipv6_txoptions *opt = NULL; int encap_limit = -1; __u16 offset; struct flowi fl; - struct ip6_flowlabel *fl_lbl = NULL; - int err = 0; struct dst_entry *dst; - int link_failure = 0; - struct sock *sk = ip6_socket->sk; - struct ipv6_pinfo *np = inet6_sk(sk); + struct net_device *tdev; int mtu; + int max_headroom = sizeof(struct ipv6hdr); + u8 proto; + int err; + int pkt_len; if (t->recursion++) { stats->collisions++; @@ -701,58 +634,39 @@ } else if (!(t->parms.flags & IP6_TNL_F_IGN_ENCAP_LIMIT)) { encap_limit = t->parms.encap_limit; } - ip6_xmit_lock(); - memcpy(&fl, &t->fl, sizeof (fl)); + proto = fl.proto; if ((t->parms.flags & IP6_TNL_F_USE_ORIG_TCLASS)) fl.fl6_flowlabel |= (*(__u32 *) ipv6h & IPV6_TCLASS_MASK); if ((t->parms.flags & IP6_TNL_F_USE_ORIG_FLOWLABEL)) fl.fl6_flowlabel |= (*(__u32 *) ipv6h & IPV6_FLOWLABEL_MASK); - if (fl.fl6_flowlabel) { - fl_lbl = fl6_sock_lookup(sk, fl.fl6_flowlabel); - if (fl_lbl) - orig_opt = fl_lbl->opt; - } - if (encap_limit >= 0) { - if (!(opt = merge_options(sk, encap_limit, orig_opt))) { - goto tx_err_free_fl_lbl; - } - } else { - opt = orig_opt; - } - dst = __sk_dst_check(sk, np->dst_cookie); + if (encap_limit >= 0 && (opt = create_tel(encap_limit)) == NULL) + goto tx_err; - if (dst) { - if (np->daddr_cache == NULL || - ipv6_addr_cmp(&fl.fl6_dst, np->daddr_cache) || - (fl.oif && fl.oif != dst->dev->ifindex)) { - dst = NULL; - } - } - if (dst == NULL) { - dst = ip6_route_output(sk, &fl); - if (dst->error) { - stats->tx_carrier_errors++; - link_failure = 1; - goto tx_err_dst_release; - } - /* local routing loop */ - if (dst->dev == dev) { - stats->collisions++; - if (net_ratelimit()) - printk(KERN_WARNING - "%s: Local routing loop detected!\n", - t->parms.name); - goto tx_err_dst_release; - } - ipv6_addr_copy(&np->daddr, &fl.fl6_dst); - ipv6_addr_copy(&np->saddr, &fl.fl6_src); + if ((dst = ip6_tnl_dst_check(t)) != NULL) + dst_hold(dst); + else + dst = ip6_route_output(NULL, &fl); + + if (dst->error || xfrm_lookup(&dst, &fl, NULL, 0) < 0) + goto tx_err_link_failure; + + tdev = dst->dev; + + if (tdev == dev) { + stats->collisions++; + if (net_ratelimit()) + printk(KERN_WARNING + "%s: Local routing loop detected!\n", + t->parms.name); + goto tx_err_dst_release; } mtu = dst_pmtu(dst) - sizeof (*ipv6h); if (opt) { - mtu -= (opt->opt_nflen + opt->opt_flen); + max_headroom += 8; + mtu -= 8; } if (mtu < IPV6_MIN_MTU) mtu = IPV6_MIN_MTU; @@ -765,41 +679,71 @@ icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu, dev); goto tx_err_dst_release; } - err = ip6_append_data(sk, ip6ip6_getfrag, skb->nh.raw, skb->len, 0, - t->parms.hop_limit, opt, &fl, - (struct rt6_info *)dst, MSG_DONTWAIT); + skb->h.raw = skb->nh.raw; - if (err) { - ip6_flush_pending_frames(sk); - } else { - err = ip6_push_pending_frames(sk); - err = (err < 0 ? err : 0); + /* + * Okay, now see if we can stuff it in the buffer as-is. + */ + max_headroom += LL_RESERVED_SPACE(tdev); + + if (skb_headroom(skb) < max_headroom || + skb_cloned(skb) || skb_shared(skb)) { + struct sk_buff *new_skb; + + if (!(new_skb = skb_realloc_headroom(skb, max_headroom))) + goto tx_err_dst_release; + + if (skb->sk) + skb_set_owner_w(new_skb, skb->sk); + kfree_skb(skb); + skb = new_skb; } - if (!err) { - stats->tx_bytes += skb->len; + dst_release(skb->dst); + skb->dst = dst_clone(dst); + + if (opt) + ipv6_push_nfrag_opts(skb, opt, &proto, NULL); + + skb->nh.raw = skb_push(skb, sizeof(struct ipv6hdr)); + ipv6h = skb->nh.ipv6h; + *(u32*)ipv6h = fl.fl6_flowlabel | htonl(0x60000000); + ipv6h->payload_len = htons(skb->len - sizeof(struct ipv6hdr)); + ipv6h->hop_limit = t->parms.hop_limit; + ipv6h->nexthdr = proto; + ipv6_addr_copy(&ipv6h->saddr, &fl.fl6_src); + ipv6_addr_copy(&ipv6h->daddr, &fl.fl6_dst); +#ifdef CONFIG_NETFILTER + nf_conntrack_put(skb->nfct); + skb->nfct = NULL; +#ifdef CONFIG_NETFILTER_DEBUG + skb->nf_debug = 0; +#endif +#endif + pkt_len = skb->len; + err = NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, skb, NULL, + skb->dst->dev, dst_output); + + if (err == NET_XMIT_SUCCESS || err == NET_XMIT_CN) { + stats->tx_bytes += pkt_len; stats->tx_packets++; } else { stats->tx_errors++; stats->tx_aborted_errors++; } - if (opt && opt != orig_opt) - sock_kfree_s(sk, opt, opt->tot_len); + ip6_tnl_dst_store(t, dst); + + if (opt) + kfree(opt); - fl6_sock_release(fl_lbl); - ip6_dst_store(sk, dst, &np->daddr); - ip6_xmit_unlock(); - kfree_skb(skb); t->recursion--; return 0; +tx_err_link_failure: + stats->tx_carrier_errors++; + dst_link_failure(skb); tx_err_dst_release: dst_release(dst); - if (opt && opt != orig_opt) - sock_kfree_s(sk, opt, opt->tot_len); -tx_err_free_fl_lbl: - fl6_sock_release(fl_lbl); - ip6_xmit_unlock(); - if (link_failure) - dst_link_failure(skb); + if (opt) + kfree(opt); tx_err: stats->tx_errors++; stats->tx_dropped++; @@ -851,9 +795,12 @@ { struct net_device *dev = t->dev; struct ip6_tnl_parm *p = &t->parms; - struct flowi *fl; + struct flowi *fl = &t->fl; + + memcpy(&dev->dev_addr, &p->laddr, sizeof(struct in6_addr)); + memcpy(&dev->broadcast, &p->raddr, sizeof(struct in6_addr)); + /* Set up flowi template */ - fl = &t->fl; ipv6_addr_copy(&fl->fl6_src, &p->laddr); ipv6_addr_copy(&fl->fl6_dst, &p->raddr); fl->oif = p->link; @@ -878,10 +825,7 @@ if (rt == NULL) return; - /* as long as tunnels use the same socket for transmission, - locally nested tunnels won't work */ - - if (rt->rt6i_dev && rt->rt6i_dev->type != ARPHRD_TUNNEL6) { + if (rt->rt6i_dev) { dev->iflink = rt->rt6i_dev->ifindex; dev->hard_header_len = rt->rt6i_dev->hard_header_len + @@ -1083,7 +1027,7 @@ { SET_MODULE_OWNER(dev); dev->uninit = ip6ip6_tnl_dev_uninit; - dev->destructor = (void (*)(struct net_device *))kfree; + dev->destructor = free_netdev; dev->hard_start_xmit = ip6ip6_tnl_xmit; dev->get_stats = ip6ip6_tnl_get_stats; dev->do_ioctl = ip6ip6_tnl_ioctl; @@ -1094,10 +1038,7 @@ dev->mtu = ETH_DATA_LEN - sizeof (struct ipv6hdr); dev->flags |= IFF_NOARP; dev->iflink = 0; - /* Hmm... MAX_ADDR_LEN is 8, so the ipv6 addresses can't be - copied to dev->dev_addr and dev->broadcast, like the ipv4 - addresses were in ipip.c, ip_gre.c and sit.c. */ - dev->addr_len = 0; + dev->addr_len = sizeof(struct in6_addr); } @@ -1139,7 +1080,7 @@ int ip6ip6_fb_tnl_dev_init(struct net_device *dev) { struct ip6_tnl *t = dev->priv; - ip6ip6_tnl_dev_init_gen(dev); + ip6ip6_tnl_dev_init_gen(dev); dev_hold(dev); tnls_wc[0] = t; return 0; @@ -1159,61 +1100,28 @@ int __init ip6_tunnel_init(void) { - int i, j, err; - struct sock *sk; - struct ipv6_pinfo *np; - - for (i = 0; i < NR_CPUS; i++) { - if (!cpu_possible(i)) - continue; - - err = sock_create(PF_INET6, SOCK_RAW, IPPROTO_IPV6, - &__ip6_socket[i]); - if (err < 0) { - printk(KERN_ERR - "Failed to create the IPv6 tunnel socket " - "(err %d).\n", - err); - goto fail; - } - sk = __ip6_socket[i]->sk; - sk->sk_allocation = GFP_ATOMIC; - - np = inet6_sk(sk); - np->hop_limit = 255; - np->mc_loop = 0; + int err; - sk->sk_prot->unhash(sk); - } if ((err = inet6_add_protocol(&ip6ip6_protocol, IPPROTO_IPV6)) < 0) { printk(KERN_ERR "Failed to register IPv6 protocol\n"); - goto fail; + return err; } - - ip6ip6_fb_tnl_dev = alloc_netdev(sizeof(struct ip6_tnl), "ip6tnl0", ip6ip6_tnl_dev_setup); if (!ip6ip6_fb_tnl_dev) { err = -ENOMEM; - goto tnl_fail; + goto fail; } ip6ip6_fb_tnl_dev->init = ip6ip6_fb_tnl_dev_init; if ((err = register_netdev(ip6ip6_fb_tnl_dev))) { kfree(ip6ip6_fb_tnl_dev); - goto tnl_fail; + goto fail; } return 0; -tnl_fail: - inet6_del_protocol(&ip6ip6_protocol, IPPROTO_IPV6); fail: - for (j = 0; j < i; j++) { - if (!cpu_possible(j)) - continue; - sock_release(__ip6_socket[j]); - __ip6_socket[j] = NULL; - } + inet6_del_protocol(&ip6ip6_protocol, IPPROTO_IPV6); return err; } @@ -1223,18 +1131,8 @@ void ip6_tunnel_cleanup(void) { - int i; - unregister_netdev(ip6ip6_fb_tnl_dev); - inet6_del_protocol(&ip6ip6_protocol, IPPROTO_IPV6); - - for (i = 0; i < NR_CPUS; i++) { - if (!cpu_possible(i)) - continue; - sock_release(__ip6_socket[i]); - __ip6_socket[i] = NULL; - } } #ifdef MODULE diff -Nru a/net/ipv6/ipv6_syms.c b/net/ipv6/ipv6_syms.c --- a/net/ipv6/ipv6_syms.c Tue Sep 2 19:58:17 2003 +++ b/net/ipv6/ipv6_syms.c Tue Sep 2 19:58:17 2003 @@ -45,3 +45,4 @@ EXPORT_SYMBOL(ip6_append_data); EXPORT_SYMBOL(ip6_flush_pending_frames); EXPORT_SYMBOL(ip6_push_pending_frames); +EXPORT_SYMBOL(ipv6_push_nfrag_opts); diff -Nru a/net/ipv6/mcast.c b/net/ipv6/mcast.c --- a/net/ipv6/mcast.c Tue Sep 2 19:58:18 2003 +++ b/net/ipv6/mcast.c Tue Sep 2 19:58:18 2003 @@ -2078,6 +2078,7 @@ break; } read_unlock_bh(&idev->lock); + in6_dev_put(idev); } return im; } @@ -2135,7 +2136,9 @@ if (likely(state->idev != NULL)) { read_unlock_bh(&state->idev->lock); in6_dev_put(state->idev); + state->idev = NULL; } + state->dev = NULL; read_unlock(&dev_base_lock); } @@ -2225,6 +2228,7 @@ spin_unlock_bh(&im->mca_lock); } read_unlock_bh(&idev->lock); + in6_dev_put(idev); } return psf; } @@ -2291,12 +2295,16 @@ static void igmp6_mcf_seq_stop(struct seq_file *seq, void *v) { struct igmp6_mcf_iter_state *state = igmp6_mcf_seq_private(seq); - if (likely(state->im != NULL)) + if (likely(state->im != NULL)) { spin_unlock_bh(&state->im->mca_lock); + state->im = NULL; + } if (likely(state->idev != NULL)) { read_unlock_bh(&state->idev->lock); in6_dev_put(state->idev); + state->idev = NULL; } + state->dev = NULL; read_unlock(&dev_base_lock); } diff -Nru a/net/ipv6/netfilter/Kconfig b/net/ipv6/netfilter/Kconfig --- a/net/ipv6/netfilter/Kconfig Tue Sep 2 19:58:18 2003 +++ b/net/ipv6/netfilter/Kconfig Tue Sep 2 19:58:18 2003 @@ -3,14 +3,14 @@ # menu "IPv6: Netfilter Configuration" - depends on INET && EXPERIMENTAL && IPV6!=n && NETFILTER + depends on INET && IPV6!=n && NETFILTER #tristate 'Connection tracking (required for masq/NAT)' CONFIG_IP6_NF_CONNTRACK #if [ "$CONFIG_IP6_NF_CONNTRACK" != "n" ]; then # dep_tristate ' FTP protocol support' CONFIG_IP6_NF_FTP $CONFIG_IP6_NF_CONNTRACK #fi config IP6_NF_QUEUE - tristate "Userspace queueing via NETLINK (EXPERIMENTAL)" + tristate "Userspace queueing via NETLINK" ---help--- This option adds a queue handler to the kernel for IPv6 @@ -62,7 +62,7 @@ config IP6_NF_MATCH_RT tristate "Routing header match support" - depends on IP6_NF_IPTABLES && EXPERIMENTAL + depends on IP6_NF_IPTABLES help rt matching allows you to match packets based on the routing header of the packet. @@ -72,7 +72,7 @@ config IP6_NF_MATCH_OPTS tristate "Hop-by-hop and Dst opts header match support" - depends on IP6_NF_IPTABLES && EXPERIMENTAL + depends on IP6_NF_IPTABLES help This allows one to match packets based on the hop-by-hop and destination options headers of a packet. @@ -82,7 +82,7 @@ config IP6_NF_MATCH_FRAG tristate "Fragmentation header match support" - depends on IP6_NF_IPTABLES && EXPERIMENTAL + depends on IP6_NF_IPTABLES help frag matching allows you to match packets based on the fragmentation header of the packet. @@ -112,7 +112,7 @@ . If unsure, say `N'. config IP6_NF_MATCH_OWNER - tristate "Owner match support (EXPERIMENTAL)" + tristate "Owner match support" depends on IP6_NF_IPTABLES help Packet owner matching allows you to match locally-generated packets @@ -134,8 +134,8 @@ . If unsure, say `N'. config IP6_NF_MATCH_IPV6HEADER - tristate "IPv6 Extension Headers Match (EXPERIMENTAL)" - depends on IP6_NF_IPTABLES && EXPERIMENTAL + tristate "IPv6 Extension Headers Match" + depends on IP6_NF_IPTABLES help This module allows one to match packets based upon the ipv6 extension headers. @@ -144,8 +144,8 @@ . If unsure, say `N'. config IP6_NF_MATCH_AHESP - tristate "AH/ESP match support (EXPERIMENTAL)" - depends on IP6_NF_IPTABLES && EXPERIMENTAL + tristate "AH/ESP match support" + depends on IP6_NF_IPTABLES help This module allows one to match AH and ESP packets. @@ -163,7 +163,7 @@ Documentation/modules.txt. If unsure, say `N'. config IP6_NF_MATCH_EUI64 - tristate "EUI64 address check (EXPERIMENTAL)" + tristate "EUI64 address check" depends on IP6_NF_IPTABLES help This module performs checking on the IPv6 source address diff -Nru a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c --- a/net/ipv6/netfilter/ip6_tables.c Tue Sep 2 19:58:18 2003 +++ b/net/ipv6/netfilter/ip6_tables.c Tue Sep 2 19:58:18 2003 @@ -26,6 +26,10 @@ #include +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Netfilter Core Team "); +MODULE_DESCRIPTION("IPv6 packet filter"); + #define IPV6_HDR_LEN (sizeof(struct ipv6hdr)) #define IPV6_OPTHDR_LEN (sizeof(struct ipv6_opt_hdr)) @@ -1923,4 +1927,3 @@ module_init(init); module_exit(fini); -MODULE_LICENSE("GPL"); diff -Nru a/net/ipv6/netfilter/ip6t_MARK.c b/net/ipv6/netfilter/ip6t_MARK.c --- a/net/ipv6/netfilter/ip6t_MARK.c Tue Sep 2 19:58:19 2003 +++ b/net/ipv6/netfilter/ip6t_MARK.c Tue Sep 2 19:58:19 2003 @@ -7,6 +7,9 @@ #include #include +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Netfilter Core Team "); + static unsigned int target(struct sk_buff **pskb, unsigned int hooknum, @@ -65,4 +68,3 @@ module_init(init); module_exit(fini); -MODULE_LICENSE("GPL"); diff -Nru a/net/ipv6/netfilter/ip6t_eui64.c b/net/ipv6/netfilter/ip6t_eui64.c --- a/net/ipv6/netfilter/ip6t_eui64.c Tue Sep 2 19:58:12 2003 +++ b/net/ipv6/netfilter/ip6t_eui64.c Tue Sep 2 19:58:12 2003 @@ -6,6 +6,10 @@ #include +MODULE_DESCRIPTION("IPv6 EUI64 address checking match"); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Andras Kis-Szabo "); + static int match(const struct sk_buff *skb, const struct net_device *in, @@ -88,6 +92,3 @@ module_init(init); module_exit(fini); -MODULE_DESCRIPTION("IPv6 EUI64 address checking match"); -MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Andras Kis-Szabo "); diff -Nru a/net/ipv6/netfilter/ip6t_length.c b/net/ipv6/netfilter/ip6t_length.c --- a/net/ipv6/netfilter/ip6t_length.c Tue Sep 2 19:58:19 2003 +++ b/net/ipv6/netfilter/ip6t_length.c Tue Sep 2 19:58:19 2003 @@ -5,6 +5,10 @@ #include #include +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("James Morris "); +MODULE_DESCRIPTION("IPv6 packet length match"); + static int match(const struct sk_buff *skb, const struct net_device *in, diff -Nru a/net/ipv6/netfilter/ip6t_limit.c b/net/ipv6/netfilter/ip6t_limit.c --- a/net/ipv6/netfilter/ip6t_limit.c Tue Sep 2 19:58:14 2003 +++ b/net/ipv6/netfilter/ip6t_limit.c Tue Sep 2 19:58:14 2003 @@ -15,6 +15,10 @@ #include #include +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Herve Eychenne "); +MODULE_DESCRIPTION("rate limiting within ip6tables"); + /* The algorithm used is the Simple Token Bucket Filter (TBF) * see net/sched/sch_tbf.c in the linux source tree */ @@ -136,4 +140,3 @@ module_init(init); module_exit(fini); -MODULE_LICENSE("GPL"); diff -Nru a/net/ipv6/netfilter/ip6t_mac.c b/net/ipv6/netfilter/ip6t_mac.c --- a/net/ipv6/netfilter/ip6t_mac.c Tue Sep 2 19:58:18 2003 +++ b/net/ipv6/netfilter/ip6t_mac.c Tue Sep 2 19:58:18 2003 @@ -6,6 +6,10 @@ #include #include +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("MAC address matching module for IPv6"); +MODULE_AUTHOR("Netfilter Core Teaam "); + static int match(const struct sk_buff *skb, const struct net_device *in, @@ -66,5 +70,3 @@ module_init(init); module_exit(fini); -MODULE_LICENSE("GPL"); -MODULE_DESCRIPTION("MAC address matching module for IPv6"); diff -Nru a/net/ipv6/netfilter/ip6t_mark.c b/net/ipv6/netfilter/ip6t_mark.c --- a/net/ipv6/netfilter/ip6t_mark.c Tue Sep 2 19:58:20 2003 +++ b/net/ipv6/netfilter/ip6t_mark.c Tue Sep 2 19:58:20 2003 @@ -5,6 +5,10 @@ #include #include +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Netfilter Core Team "); +MODULE_DESCRIPTION("ip6tables mark match"); + static int match(const struct sk_buff *skb, const struct net_device *in, @@ -52,4 +56,3 @@ module_init(init); module_exit(fini); -MODULE_LICENSE("GPL"); diff -Nru a/net/ipv6/netfilter/ip6t_multiport.c b/net/ipv6/netfilter/ip6t_multiport.c --- a/net/ipv6/netfilter/ip6t_multiport.c Tue Sep 2 19:58:20 2003 +++ b/net/ipv6/netfilter/ip6t_multiport.c Tue Sep 2 19:58:20 2003 @@ -9,6 +9,10 @@ #include #include +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Netfilter Core Team "); +MODULE_DESCRIPTION("ip6tables match for multiple ports"); + #if 0 #define duprintf(format, args...) printk(format , ## args) #else diff -Nru a/net/ipv6/netfilter/ip6table_filter.c b/net/ipv6/netfilter/ip6table_filter.c --- a/net/ipv6/netfilter/ip6table_filter.c Tue Sep 2 19:58:13 2003 +++ b/net/ipv6/netfilter/ip6table_filter.c Tue Sep 2 19:58:13 2003 @@ -6,6 +6,10 @@ #include #include +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Netfilter Core Team "); +MODULE_DESCRIPTION("ip6tables filter table"); + #define FILTER_VALID_HOOKS ((1 << NF_IP6_LOCAL_IN) | (1 << NF_IP6_FORWARD) | (1 << NF_IP6_LOCAL_OUT)) /* Standard entry. */ @@ -202,4 +206,3 @@ module_init(init); module_exit(fini); -MODULE_LICENSE("GPL"); diff -Nru a/net/ipv6/netfilter/ip6table_mangle.c b/net/ipv6/netfilter/ip6table_mangle.c --- a/net/ipv6/netfilter/ip6table_mangle.c Tue Sep 2 19:58:15 2003 +++ b/net/ipv6/netfilter/ip6table_mangle.c Tue Sep 2 19:58:15 2003 @@ -6,6 +6,10 @@ #include #include +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Netfilter Core Team "); +MODULE_DESCRIPTION("ip6tables mangle table"); + #define MANGLE_VALID_HOOKS ((1 << NF_IP6_PRE_ROUTING) | \ (1 << NF_IP6_LOCAL_IN) | \ (1 << NF_IP6_FORWARD) | \ @@ -279,4 +283,3 @@ module_init(init); module_exit(fini); -MODULE_LICENSE("GPL"); diff -Nru a/net/ipv6/route.c b/net/ipv6/route.c --- a/net/ipv6/route.c Tue Sep 2 19:58:17 2003 +++ b/net/ipv6/route.c Tue Sep 2 19:58:17 2003 @@ -577,7 +577,7 @@ rt->rt6i_dev = dev; rt->rt6i_nexthop = neigh; rt->rt6i_expires = 0; - rt->rt6i_flags = RTF_LOCAL; + rt->rt6i_flags = RTF_LOCAL | RTF_NDISC; rt->rt6i_metric = 0; atomic_set(&rt->u.dst.__refcnt, 1); rt->u.dst.metrics[RTAX_HOPLIMIT-1] = 255; @@ -831,7 +831,7 @@ } } - rt->rt6i_flags = rtmsg->rtmsg_flags; + rt->rt6i_flags = rtmsg->rtmsg_flags & ~RTF_NDISC; install_route: if (rta && rta[RTA_METRICS-1]) { @@ -1123,6 +1123,8 @@ static struct rt6_info * ip6_rt_copy(struct rt6_info *ort) { struct rt6_info *rt = ip6_dst_alloc(); + + BUG_ON(ort->rt6i_flags & RTF_NDISC); if (rt) { rt->u.dst.input = ort->u.dst.input; diff -Nru a/net/ipv6/xfrm6_policy.c b/net/ipv6/xfrm6_policy.c --- a/net/ipv6/xfrm6_policy.c Tue Sep 2 19:58:14 2003 +++ b/net/ipv6/xfrm6_policy.c Tue Sep 2 19:58:14 2003 @@ -55,12 +55,22 @@ __xfrm6_find_bundle(struct flowi *fl, struct rtable *rt, struct xfrm_policy *policy) { struct dst_entry *dst; + u32 ndisc_bit = 0; + + if (fl->proto == IPPROTO_ICMPV6 && + (fl->fl_icmp_type == NDISC_NEIGHBOUR_ADVERTISEMENT || + fl->fl_icmp_type == NDISC_NEIGHBOUR_SOLICITATION || + fl->fl_icmp_type == NDISC_ROUTER_SOLICITATION)) + ndisc_bit = RTF_NDISC; /* Still not clear if we should set fl->fl6_{src,dst}... */ read_lock_bh(&policy->lock); for (dst = policy->bundles; dst; dst = dst->next) { struct xfrm_dst *xdst = (struct xfrm_dst*)dst; struct in6_addr fl_dst_prefix, fl_src_prefix; + + if ((xdst->u.rt6.rt6i_flags & RTF_NDISC) != ndisc_bit) + continue; ipv6_addr_prefix(&fl_dst_prefix, &fl->fl6_dst, diff -Nru a/net/ipx/af_ipx.c b/net/ipx/af_ipx.c --- a/net/ipx/af_ipx.c Tue Sep 2 19:58:13 2003 +++ b/net/ipx/af_ipx.c Tue Sep 2 19:58:13 2003 @@ -1365,6 +1365,7 @@ atomic_read(&ipx_sock_nr)); #endif sock_init_data(sock, sk); + sk_set_owner(sk, THIS_MODULE); sk->sk_no_check = 1; /* Checksum off by default */ rc = 0; out: @@ -2020,3 +2021,4 @@ module_init(ipx_init); module_exit(ipx_proto_finito); MODULE_LICENSE("GPL"); +MODULE_ALIAS_NETPROTO(PF_IPX); diff -Nru a/net/irda/af_irda.c b/net/irda/af_irda.c --- a/net/irda/af_irda.c Tue Sep 2 19:58:14 2003 +++ b/net/irda/af_irda.c Tue Sep 2 19:58:14 2003 @@ -1098,6 +1098,7 @@ /* Initialise networking socket struct */ sock_init_data(sock, sk); /* Note : set sk->sk_refcnt to 1 */ + sk_set_owner(sk, THIS_MODULE); sk->sk_family = PF_IRDA; sk->sk_protocol = protocol; /* Link networking socket and IrDA socket structs together */ diff -Nru a/net/irda/irsyms.c b/net/irda/irsyms.c --- a/net/irda/irsyms.c Tue Sep 2 19:58:19 2003 +++ b/net/irda/irsyms.c Tue Sep 2 19:58:19 2003 @@ -351,3 +351,4 @@ #ifdef CONFIG_IRDA_DEBUG MODULE_PARM(irda_debug, "1l"); #endif +MODULE_ALIAS_NETPROTO(PF_IRDA); diff -Nru a/net/key/af_key.c b/net/key/af_key.c --- a/net/key/af_key.c Tue Sep 2 19:58:14 2003 +++ b/net/key/af_key.c Tue Sep 2 19:58:14 2003 @@ -2844,3 +2844,4 @@ module_init(ipsec_pfkey_init); module_exit(ipsec_pfkey_exit); MODULE_LICENSE("GPL"); +MODULE_ALIAS_NETPROTO(PF_KEY); diff -Nru a/net/llc/llc_mac.c b/net/llc/llc_mac.c --- a/net/llc/llc_mac.c Tue Sep 2 19:58:18 2003 +++ b/net/llc/llc_mac.c Tue Sep 2 19:58:18 2003 @@ -35,7 +35,7 @@ u8 llc_mac_null_var[IFHWADDRLEN]; -static void fix_up_incoming_skb(struct sk_buff *skb); +static int fix_up_incoming_skb(struct sk_buff *skb); static void llc_station_rcv(struct sk_buff *skb); static void llc_sap_rcv(struct llc_sap *sap, struct sk_buff *skb); @@ -69,7 +69,8 @@ skb = skb_share_check(skb, GFP_ATOMIC); if (!skb) goto out; - fix_up_incoming_skb(skb); + if (!fix_up_incoming_skb(skb)) + goto drop; pdu = llc_pdu_sn_hdr(skb); if (!pdu->dsap) { /* NULL DSAP, refer to station */ dprintk("%s: calling llc_station_rcv!\n", __FUNCTION__); @@ -172,11 +173,15 @@ * by looking at the two lowest-order bits of the first control field * byte; field is either 3 or 4 bytes long. */ -static void fix_up_incoming_skb(struct sk_buff *skb) +static int fix_up_incoming_skb(struct sk_buff *skb) { u8 llc_len = 2; - struct llc_pdu_sn *pdu = (struct llc_pdu_sn *)skb->data; + struct llc_pdu_sn *pdu; + + if (!pskb_may_pull(skb, sizeof(*pdu))) + return 0; + pdu = (struct llc_pdu_sn *)skb->data; if ((pdu->ctrl_1 & LLC_PDU_TYPE_MASK) == LLC_PDU_TYPE_U) llc_len = 1; llc_len += 2; @@ -188,6 +193,7 @@ skb_trim(skb, data_size); } + return 1; } /* diff -Nru a/net/llc/llc_main.c b/net/llc/llc_main.c --- a/net/llc/llc_main.c Tue Sep 2 19:58:15 2003 +++ b/net/llc/llc_main.c Tue Sep 2 19:58:15 2003 @@ -229,6 +229,7 @@ if (llc_sk_init(sk)) goto outsk; sock_init_data(NULL, sk); + sk_set_owner(sk, THIS_MODULE); #ifdef LLC_REFCNT_DEBUG atomic_inc(&llc_sock_nr); printk(KERN_DEBUG "LLC socket %p created in %s, now we have %d alive\n", sk, @@ -603,3 +604,4 @@ MODULE_LICENSE("GPL"); MODULE_AUTHOR("Procom, 1997, Arnaldo C. Melo, Jay Schullist, 2001-2003"); MODULE_DESCRIPTION("LLC 2.0, NET4.0 IEEE 802.2 extended support"); +MODULE_ALIAS_NETPROTO(PF_LLC); diff -Nru a/net/llc/llc_proc.c b/net/llc/llc_proc.c --- a/net/llc/llc_proc.c Tue Sep 2 19:58:13 2003 +++ b/net/llc/llc_proc.c Tue Sep 2 19:58:13 2003 @@ -245,6 +245,7 @@ llc_proc_dir = proc_mkdir("llc", proc_net); if (!llc_proc_dir) goto out; + llc_proc_dir->owner = THIS_MODULE; p = create_proc_entry("socket", S_IRUGO, llc_proc_dir); if (!p) diff -Nru a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c --- a/net/netlink/af_netlink.c Tue Sep 2 19:58:16 2003 +++ b/net/netlink/af_netlink.c Tue Sep 2 19:58:16 2003 @@ -40,6 +40,7 @@ #include #include #include +#include #include #include #include @@ -964,62 +965,108 @@ #endif - #ifdef CONFIG_PROC_FS -static int netlink_read_proc(char *buffer, char **start, off_t offset, - int length, int *eof, void *data) +static struct sock *netlink_seq_socket_idx(struct seq_file *seq, loff_t pos) { - off_t pos=0; - off_t begin=0; - int len=0; int i; struct sock *s; struct hlist_node *node; - - len+= sprintf(buffer,"sk Eth Pid Groups " - "Rmem Wmem Dump Locks\n"); - + loff_t off = 0; + for (i=0; iprivate = (void *) i; + return s; + } + ++off; + } + } + return NULL; +} - len+=sprintf(buffer+len,"%p %-3d %-6d %08x %-8d %-8d %p %d", - s, - s->sk_protocol, - nlk->pid, - nlk->groups, - atomic_read(&s->sk_rmem_alloc), - atomic_read(&s->sk_wmem_alloc), - nlk->cb, - atomic_read(&s->sk_refcnt) - ); +static void *netlink_seq_start(struct seq_file *seq, loff_t *pos) +{ + read_lock(&nl_table_lock); + return *pos ? netlink_seq_socket_idx(seq, *pos - 1) : (void *) 1; +} + +static void *netlink_seq_next(struct seq_file *seq, void *v, loff_t *pos) +{ + struct sock *s; + + ++*pos; - buffer[len++]='\n'; + if (v == (void *) 1) + return netlink_seq_socket_idx(seq, 0); - pos=begin+len; - if(posoffset+length) { - read_unlock(&nl_table_lock); - goto done; + s = sk_next(v); + if (!s) { + int i = (int) seq->private; + + while (++i < MAX_LINKS) { + s = sk_head(&nl_table[i]); + if (s) { + seq->private = (void *) i; + break; } } - read_unlock(&nl_table_lock); } - *eof = 1; + return s; +} -done: - *start=buffer+(offset-begin); - len-=(offset-begin); - if(len>length) - len=length; - if(len<0) - len=0; - return len; +static void netlink_seq_stop(struct seq_file *seq, void *v) +{ + read_unlock(&nl_table_lock); +} + + +static int netlink_seq_show(struct seq_file *seq, void *v) +{ + if (v == (void *)1) + seq_puts(seq, + "sk Eth Pid Groups " + "Rmem Wmem Dump Locks\n"); + else { + struct sock *s = v; + struct netlink_opt *nlk = nlk_sk(s); + + seq_printf(seq, "%p %-3d %-6d %08x %-8d %-8d %p %d\n", + s, + s->sk_protocol, + nlk->pid, + nlk->groups, + atomic_read(&s->sk_rmem_alloc), + atomic_read(&s->sk_wmem_alloc), + nlk->cb, + atomic_read(&s->sk_refcnt) + ); + + } + return 0; } + +struct seq_operations netlink_seq_ops = { + .start = netlink_seq_start, + .next = netlink_seq_next, + .stop = netlink_seq_stop, + .show = netlink_seq_show, +}; + + +static int netlink_seq_open(struct inode *inode, struct file *file) +{ + return seq_open(file, &netlink_seq_ops); +} + +static struct file_operations netlink_seq_fops = { + .owner = THIS_MODULE, + .open = netlink_seq_open, + .read = seq_read, + .llseek = seq_lseek, + .release = seq_release, +}; + #endif int netlink_register_notifier(struct notifier_block *nb) @@ -1069,7 +1116,7 @@ } sock_register(&netlink_family_ops); #ifdef CONFIG_PROC_FS - create_proc_read_entry("net/netlink", 0, 0, netlink_read_proc, NULL); + proc_net_fops_create("netlink", 0, &netlink_seq_fops); #endif /* The netlink device handler may be needed early. */ rtnetlink_init(); @@ -1079,10 +1126,11 @@ static void __exit netlink_proto_exit(void) { sock_unregister(PF_NETLINK); - remove_proc_entry("net/netlink", NULL); + proc_net_remove("netlink"); } core_initcall(netlink_proto_init); module_exit(netlink_proto_exit); MODULE_LICENSE("GPL"); +MODULE_ALIAS_NETPROTO(PF_NETLINK); diff -Nru a/net/netlink/netlink_dev.c b/net/netlink/netlink_dev.c --- a/net/netlink/netlink_dev.c Tue Sep 2 19:58:15 2003 +++ b/net/netlink/netlink_dev.c Tue Sep 2 19:58:15 2003 @@ -41,7 +41,7 @@ static unsigned int netlink_poll(struct file *file, poll_table * wait) { - struct socket *sock = netlink_user[minor(file->f_dentry->d_inode->i_rdev)]; + struct socket *sock = netlink_user[iminor(file->f_dentry->d_inode)]; if (sock->ops->poll==NULL) return 0; @@ -56,7 +56,7 @@ size_t count, loff_t *pos) { struct inode *inode = file->f_dentry->d_inode; - struct socket *sock = netlink_user[minor(inode->i_rdev)]; + struct socket *sock = netlink_user[iminor(inode)]; struct msghdr msg; struct iovec iov; @@ -80,7 +80,7 @@ size_t count, loff_t *pos) { struct inode *inode = file->f_dentry->d_inode; - struct socket *sock = netlink_user[minor(inode->i_rdev)]; + struct socket *sock = netlink_user[iminor(inode)]; struct msghdr msg; struct iovec iov; @@ -100,7 +100,7 @@ static int netlink_open(struct inode * inode, struct file * file) { - unsigned int minor = minor(inode->i_rdev); + unsigned int minor = iminor(inode); struct socket *sock; struct sockaddr_nl nladdr; int err; @@ -132,7 +132,7 @@ static int netlink_release(struct inode * inode, struct file * file) { - unsigned int minor = minor(inode->i_rdev); + unsigned int minor = iminor(inode); struct socket *sock; sock = netlink_user[minor]; @@ -146,7 +146,7 @@ static int netlink_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) { - unsigned int minor = minor(inode->i_rdev); + unsigned int minor = iminor(inode); int retval = 0; if (minor >= MAX_LINKS) diff -Nru a/net/netrom/af_netrom.c b/net/netrom/af_netrom.c --- a/net/netrom/af_netrom.c Tue Sep 2 19:58:16 2003 +++ b/net/netrom/af_netrom.c Tue Sep 2 19:58:16 2003 @@ -433,6 +433,7 @@ nr = nr_sk(sk); sock_init_data(sock, sk); + sk_set_owner(sk, THIS_MODULE); sock->ops = &nr_proto_ops; sk->sk_protocol = protocol; @@ -473,6 +474,7 @@ nr = nr_sk(sk); sock_init_data(NULL, sk); + sk_set_owner(sk, THIS_MODULE); sk->sk_type = osk->sk_type; sk->sk_socket = osk->sk_socket; @@ -1458,6 +1460,7 @@ MODULE_AUTHOR("Jonathan Naylor G4KLX "); MODULE_DESCRIPTION("The amateur radio NET/ROM network and transport layer protocol"); MODULE_LICENSE("GPL"); +MODULE_ALIAS_NETPROTO(PF_NETROM); static void __exit nr_exit(void) { diff -Nru a/net/netsyms.c b/net/netsyms.c --- a/net/netsyms.c Tue Sep 2 19:58:15 2003 +++ b/net/netsyms.c Tue Sep 2 19:58:15 2003 @@ -631,7 +631,10 @@ /* ethtool.c */ EXPORT_SYMBOL(ethtool_op_get_link); EXPORT_SYMBOL(ethtool_op_get_tx_csum); +EXPORT_SYMBOL(ethtool_op_set_tx_csum); EXPORT_SYMBOL(ethtool_op_get_sg); EXPORT_SYMBOL(ethtool_op_set_sg); +EXPORT_SYMBOL(ethtool_op_get_tso); +EXPORT_SYMBOL(ethtool_op_set_tso); #endif /* CONFIG_NET */ diff -Nru a/net/packet/af_packet.c b/net/packet/af_packet.c --- a/net/packet/af_packet.c Tue Sep 2 19:58:17 2003 +++ b/net/packet/af_packet.c Tue Sep 2 19:58:17 2003 @@ -1832,3 +1832,4 @@ module_init(packet_init); module_exit(packet_exit); MODULE_LICENSE("GPL"); +MODULE_ALIAS_NETPROTO(PF_PACKET); diff -Nru a/net/rose/af_rose.c b/net/rose/af_rose.c --- a/net/rose/af_rose.c Tue Sep 2 19:58:16 2003 +++ b/net/rose/af_rose.c Tue Sep 2 19:58:16 2003 @@ -518,6 +518,7 @@ rose = rose_sk(sk); sock_init_data(sock, sk); + sk_set_owner(sk, THIS_MODULE); skb_queue_head_init(&rose->ack_queue); #ifdef M_BIT @@ -556,6 +557,7 @@ rose = rose_sk(sk); sock_init_data(NULL, sk); + sk_set_owner(sk, THIS_MODULE); skb_queue_head_init(&rose->ack_queue); #ifdef M_BIT @@ -1549,6 +1551,7 @@ MODULE_AUTHOR("Jonathan Naylor G4KLX "); MODULE_DESCRIPTION("The amateur radio ROSE network layer protocol"); MODULE_LICENSE("GPL"); +MODULE_ALIAS_NETPROTO(PF_ROSE); static void __exit rose_exit(void) { diff -Nru a/net/rxrpc/krxiod.c b/net/rxrpc/krxiod.c --- a/net/rxrpc/krxiod.c Tue Sep 2 19:58:12 2003 +++ b/net/rxrpc/krxiod.c Tue Sep 2 19:58:12 2003 @@ -9,7 +9,6 @@ * 2 of the License, or (at your option) any later version. */ -#include #include #include #include diff -Nru a/net/rxrpc/krxsecd.c b/net/rxrpc/krxsecd.c --- a/net/rxrpc/krxsecd.c Tue Sep 2 19:58:14 2003 +++ b/net/rxrpc/krxsecd.c Tue Sep 2 19:58:14 2003 @@ -14,7 +14,6 @@ * - responding to security challenges on outbound connections */ -#include #include #include #include diff -Nru a/net/rxrpc/krxtimod.c b/net/rxrpc/krxtimod.c --- a/net/rxrpc/krxtimod.c Tue Sep 2 19:58:13 2003 +++ b/net/rxrpc/krxtimod.c Tue Sep 2 19:58:13 2003 @@ -9,7 +9,6 @@ * 2 of the License, or (at your option) any later version. */ -#include #include #include #include diff -Nru a/net/sched/sch_generic.c b/net/sched/sch_generic.c --- a/net/sched/sch_generic.c Tue Sep 2 19:58:12 2003 +++ b/net/sched/sch_generic.c Tue Sep 2 19:58:12 2003 @@ -121,7 +121,7 @@ printk(KERN_DEBUG "Dead loop on netdevice %s, fix it urgently!\n", dev->name); return -1; } - netdev_rx_stat[smp_processor_id()].cpu_collision++; + __get_cpu_var(netdev_rx_stat).cpu_collision++; } /* Device kicked us out :( diff -Nru a/net/sctp/socket.c b/net/sctp/socket.c --- a/net/sctp/socket.c Tue Sep 2 19:58:20 2003 +++ b/net/sctp/socket.c Tue Sep 2 19:58:20 2003 @@ -852,7 +852,7 @@ associd = sinfo->sinfo_assoc_id; } - SCTP_DEBUG_PRINTK("msg_len: %Zd, sinfo_flags: 0x%x\n", + SCTP_DEBUG_PRINTK("msg_len: %d, sinfo_flags: 0x%x\n", msg_len, sinfo_flags); /* MSG_EOF or MSG_ABORT cannot be set on a TCP-style socket. */ diff -Nru a/net/sunrpc/rpc_pipe.c b/net/sunrpc/rpc_pipe.c --- a/net/sunrpc/rpc_pipe.c Tue Sep 2 19:58:14 2003 +++ b/net/sunrpc/rpc_pipe.c Tue Sep 2 19:58:14 2003 @@ -10,7 +10,6 @@ */ #include #include -#include #include #include #include diff -Nru a/net/sunrpc/svcsock.c b/net/sunrpc/svcsock.c --- a/net/sunrpc/svcsock.c Tue Sep 2 19:58:13 2003 +++ b/net/sunrpc/svcsock.c Tue Sep 2 19:58:13 2003 @@ -27,7 +27,6 @@ #include #include #include -#include #include #include #include diff -Nru a/net/sunrpc/sysctl.c b/net/sunrpc/sysctl.c --- a/net/sunrpc/sysctl.c Tue Sep 2 19:58:13 2003 +++ b/net/sunrpc/sysctl.c Tue Sep 2 19:58:13 2003 @@ -8,7 +8,6 @@ */ #include -#include #include #include #include diff -Nru a/net/sunrpc/timer.c b/net/sunrpc/timer.c --- a/net/sunrpc/timer.c Tue Sep 2 19:58:18 2003 +++ b/net/sunrpc/timer.c Tue Sep 2 19:58:18 2003 @@ -15,7 +15,6 @@ #include -#include #include #include diff -Nru a/net/sunrpc/xprt.c b/net/sunrpc/xprt.c --- a/net/sunrpc/xprt.c Tue Sep 2 19:58:17 2003 +++ b/net/sunrpc/xprt.c Tue Sep 2 19:58:17 2003 @@ -45,7 +45,6 @@ #define __KERNEL_SYSCALLS__ -#include #include #include #include diff -Nru a/net/unix/af_unix.c b/net/unix/af_unix.c --- a/net/unix/af_unix.c Tue Sep 2 19:58:17 2003 +++ b/net/unix/af_unix.c Tue Sep 2 19:58:17 2003 @@ -1965,3 +1965,4 @@ module_exit(af_unix_exit); MODULE_LICENSE("GPL"); +MODULE_ALIAS_NETPROTO(PF_UNIX); diff -Nru a/net/wanrouter/af_wanpipe.c b/net/wanrouter/af_wanpipe.c --- a/net/wanrouter/af_wanpipe.c Tue Sep 2 19:58:19 2003 +++ b/net/wanrouter/af_wanpipe.c Tue Sep 2 19:58:19 2003 @@ -2600,3 +2600,4 @@ } #endif MODULE_LICENSE("GPL"); +MODULE_ALIAS_NETPROTO(PF_WANPIPE); diff -Nru a/net/x25/af_x25.c b/net/x25/af_x25.c --- a/net/x25/af_x25.c Tue Sep 2 19:58:19 2003 +++ b/net/x25/af_x25.c Tue Sep 2 19:58:19 2003 @@ -449,6 +449,7 @@ x25->sk = sk; sock_init_data(NULL, sk); + sk_set_owner(sk, THIS_MODULE); skb_queue_head_init(&x25->ack_queue); skb_queue_head_init(&x25->fragment_queue); @@ -478,6 +479,7 @@ x25 = x25_sk(sk); sock_init_data(sock, sk); + sk_set_owner(sk, THIS_MODULE); init_timer(&x25->timer); @@ -1421,3 +1423,4 @@ MODULE_AUTHOR("Jonathan Naylor "); MODULE_DESCRIPTION("The X.25 Packet Layer network layer protocol"); MODULE_LICENSE("GPL"); +MODULE_ALIAS_NETPROTO(PF_X25); diff -Nru a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c --- a/net/xfrm/xfrm_user.c Tue Sep 2 19:58:16 2003 +++ b/net/xfrm/xfrm_user.c Tue Sep 2 19:58:16 2003 @@ -1195,3 +1195,4 @@ module_init(xfrm_user_init); module_exit(xfrm_user_exit); +MODULE_LICENSE("GPL"); diff -Nru a/scripts/kconfig/Makefile b/scripts/kconfig/Makefile --- a/scripts/kconfig/Makefile Tue Sep 2 19:58:20 2003 +++ b/scripts/kconfig/Makefile Tue Sep 2 19:58:20 2003 @@ -2,40 +2,43 @@ # Kernel configuration targets # These targets are used from top-level makefile -.PHONY: oldconfig xconfig gconfig menuconfig config +.PHONY: oldconfig xconfig gconfig menuconfig config silentoldconfig -xconfig: scripts/kconfig/qconf - ./scripts/kconfig/qconf arch/$(ARCH)/Kconfig +xconfig: $(obj)/qconf + $< arch/$(ARCH)/Kconfig -gconfig: scripts/kconfig/gconf - ./scripts/kconfig/gconf arch/$(ARCH)/Kconfig +gconfig: $(obj)/gconf + ./$< arch/$(ARCH)/Kconfig -menuconfig: scripts/kconfig/mconf +menuconfig: $(obj)/mconf $(Q)$(MAKE) $(build)=scripts/lxdialog - ./scripts/kconfig/mconf arch/$(ARCH)/Kconfig + $< arch/$(ARCH)/Kconfig -config: scripts/kconfig/conf - ./scripts/kconfig/conf arch/$(ARCH)/Kconfig +config: $(obj)/conf + $< arch/$(ARCH)/Kconfig -oldconfig: scripts/kconfig/conf - ./scripts/kconfig/conf -o arch/$(ARCH)/Kconfig +oldconfig: $(obj)/conf + $< -o arch/$(ARCH)/Kconfig + +silentoldconfig: $(obj)/conf + $< -s arch/$(ARCH)/Kconfig .PHONY: randconfig allyesconfig allnoconfig allmodconfig defconfig -randconfig: scripts/kconfig/conf - ./scripts/kconfig/conf -r arch/$(ARCH)/Kconfig +randconfig: $(obj)/conf + $< -r arch/$(ARCH)/Kconfig -allyesconfig: scripts/kconfig/conf - ./scripts/kconfig/conf -y arch/$(ARCH)/Kconfig +allyesconfig: $(obj)/conf + $< -y arch/$(ARCH)/Kconfig -allnoconfig: scripts/kconfig/conf - ./scripts/kconfig/conf -n arch/$(ARCH)/Kconfig +allnoconfig: $(obj)/conf + $< -n arch/$(ARCH)/Kconfig -allmodconfig: scripts/kconfig/conf - ./scripts/kconfig/conf -m arch/$(ARCH)/Kconfig +allmodconfig: $(obj)/conf + $< -m arch/$(ARCH)/Kconfig -defconfig: scripts/kconfig/conf - ./scripts/kconfig/conf -d arch/$(ARCH)/Kconfig +defconfig: $(obj)/conf + $< -d arch/$(ARCH)/Kconfig # Help text used by make help help: diff -Nru a/scripts/kconfig/symbol.c b/scripts/kconfig/symbol.c --- a/scripts/kconfig/symbol.c Tue Sep 2 19:58:14 2003 +++ b/scripts/kconfig/symbol.c Tue Sep 2 19:58:14 2003 @@ -12,21 +12,21 @@ #include "lkc.h" struct symbol symbol_yes = { - name: "y", - curr: { "y", yes }, - flags: SYMBOL_YES|SYMBOL_VALID, + .name = "y", + .curr = { "y", yes }, + .flags = SYMBOL_YES|SYMBOL_VALID, }, symbol_mod = { - name: "m", - curr: { "m", mod }, - flags: SYMBOL_MOD|SYMBOL_VALID, + .name = "m", + .curr = { "m", mod }, + .flags = SYMBOL_MOD|SYMBOL_VALID, }, symbol_no = { - name: "n", - curr: { "n", no }, - flags: SYMBOL_NO|SYMBOL_VALID, + .name = "n", + .curr = { "n", no }, + .flags = SYMBOL_NO|SYMBOL_VALID, }, symbol_empty = { - name: "", - curr: { "", no }, - flags: SYMBOL_VALID, + .name = "", + .curr = { "", no }, + .flags = SYMBOL_VALID, }; int sym_change_count; diff -Nru a/security/capability.c b/security/capability.c --- a/security/capability.c Tue Sep 2 19:58:15 2003 +++ b/security/capability.c Tue Sep 2 19:58:15 2003 @@ -295,12 +295,7 @@ vm_acct_memory(pages); - /* - * Sometimes we want to use more memory than we have - */ - if (sysctl_overcommit_memory == 1) - return 0; - + /* We estimate memory ourselves (common case) */ if (sysctl_overcommit_memory == 0) { free = get_page_cache_size(); free += nr_free_pages(); @@ -322,10 +317,16 @@ if (free > pages) return 0; + vm_unacct_memory(pages); return -ENOMEM; } + /* Kernel assumes allocation */ + if (sysctl_overcommit_memory == 1) + return 0; + + /* sysctl_overcommit_memory must be 2 which means strict_overcommit*/ allowed = totalram_pages * sysctl_overcommit_ratio / 100; allowed += total_swap_pages; diff -Nru a/security/selinux/hooks.c b/security/selinux/hooks.c --- a/security/selinux/hooks.c Tue Sep 2 19:58:19 2003 +++ b/security/selinux/hooks.c Tue Sep 2 19:58:19 2003 @@ -1332,31 +1332,19 @@ static int selinux_bprm_alloc_security(struct linux_binprm *bprm) { - int rc; + struct bprm_security_struct *bsec; - /* Make sure that the secondary module doesn't use the - bprm->security field, since we do not yet support chaining - of multiple security structures on the field. Neither - the dummy nor the capability module use the field. The owlsm - module uses the field if CONFIG_OWLSM_FD is enabled. */ - rc = secondary_ops->bprm_alloc_security(bprm); - if (rc) - return rc; - if (bprm->security) { - printk(KERN_WARNING "%s: no support yet for chaining on the " - "security field by secondary modules.\n", __FUNCTION__); - /* Release the secondary module's security object. */ - secondary_ops->bprm_free_security(bprm); - /* Unregister the secondary module to prevent problems - with subsequent binprm hooks. This will revert to the - original (dummy) module for the secondary operations. */ - rc = security_ops->unregister_security("unknown", secondary_ops); - if (rc) - return rc; - printk(KERN_WARNING "%s: Unregistered the secondary security " - "module.\n", __FUNCTION__); - } - bprm->security = NULL; + bsec = kmalloc(sizeof(struct bprm_security_struct), GFP_KERNEL); + if (!bsec) + return -ENOMEM; + + memset(bsec, 0, sizeof *bsec); + bsec->magic = SELINUX_MAGIC; + bsec->bprm = bprm; + bsec->sid = SECINITSID_UNLABELED; + bsec->set = 0; + + bprm->security = bsec; return 0; } @@ -1365,6 +1353,7 @@ struct task_security_struct *tsec; struct inode *inode = bprm->file->f_dentry->d_inode; struct inode_security_struct *isec; + struct bprm_security_struct *bsec; u32 newsid; struct avc_audit_data ad; int rc; @@ -1373,15 +1362,16 @@ if (rc) return rc; - if (bprm->sh_bang || bprm->security) - /* The security field should already be set properly. */ + bsec = bprm->security; + + if (bsec->set) return 0; tsec = current->security; isec = inode->i_security; /* Default to the current task SID. */ - bprm->security = (void *)tsec->sid; + bsec->sid = tsec->sid; /* Reset create SID on execve. */ tsec->create_sid = 0; @@ -1427,9 +1417,10 @@ return rc; /* Set the security field to the new SID. */ - bprm->security = (void*) newsid; + bsec->sid = newsid; } + bsec->set = 1; return 0; } @@ -1463,8 +1454,9 @@ static void selinux_bprm_free_security(struct linux_binprm *bprm) { - /* Nothing to do - not dynamically allocated. */ - return; + struct bprm_security_struct *bsec = bprm->security; + bprm->security = NULL; + kfree(bsec); } /* Derived from fs/exec.c:flush_old_files. */ @@ -1509,6 +1501,7 @@ static void selinux_bprm_compute_creds(struct linux_binprm *bprm) { struct task_security_struct *tsec, *psec; + struct bprm_security_struct *bsec; u32 sid; struct av_decision avd; int rc; @@ -1517,9 +1510,8 @@ tsec = current->security; - sid = (u32)bprm->security; - if (!sid) - sid = tsec->sid; + bsec = bprm->security; + sid = bsec->sid; tsec->osid = tsec->sid; if (tsec->sid != sid) { @@ -2057,9 +2049,11 @@ case F_GETLK: case F_SETLK: case F_SETLKW: +#if BITS_PER_LONG == 32 case F_GETLK64: case F_SETLK64: case F_SETLKW64: +#endif if (!file->f_dentry || !file->f_dentry->d_inode) { err = -EINVAL; break; @@ -3112,9 +3106,8 @@ char *name, void *value, size_t size) { struct task_security_struct *tsec; - u32 sid; + u32 sid, len; char *context; - size_t len; int error; if (current != p) { diff -Nru a/security/selinux/include/objsec.h b/security/selinux/include/objsec.h --- a/security/selinux/include/objsec.h Tue Sep 2 19:58:15 2003 +++ b/security/selinux/include/objsec.h Tue Sep 2 19:58:15 2003 @@ -21,6 +21,7 @@ #include #include #include +#include #include #include "flask.h" #include "avc.h" @@ -83,6 +84,13 @@ u16 sclass; /* security class of this object */ u32 sid; /* SID of IPC resource */ struct avc_entry_ref avcr; /* reference to permissions */ +}; + +struct bprm_security_struct { + unsigned long magic; /* magic number for this module */ + struct linux_binprm *bprm; /* back pointer to bprm object */ + u32 sid; /* SID for transformed process */ + unsigned char set; }; extern int inode_security_set_sid(struct inode *inode, u32 sid); diff -Nru a/security/selinux/ss/avtab.c b/security/selinux/ss/avtab.c --- a/security/selinux/ss/avtab.c Tue Sep 2 19:58:17 2003 +++ b/security/selinux/ss/avtab.c Tue Sep 2 19:58:17 2003 @@ -106,7 +106,7 @@ } h->htable[i] = NULL; } - kfree(h->htable); + vfree(h->htable); } @@ -138,7 +138,7 @@ { int i; - h->htable = kmalloc(sizeof(*(h->htable)) * AVTAB_SIZE, GFP_KERNEL); + h->htable = vmalloc(sizeof(*(h->htable)) * AVTAB_SIZE); if (!h->htable) return -ENOMEM; for (i = 0; i < AVTAB_SIZE; i++) diff -Nru a/security/selinux/ss/ebitmap.c b/security/selinux/ss/ebitmap.c --- a/security/selinux/ss/ebitmap.c Tue Sep 2 19:58:17 2003 +++ b/security/selinux/ss/ebitmap.c Tue Sep 2 19:58:17 2003 @@ -250,8 +250,8 @@ count = le32_to_cpu(buf[2]); if (mapsize != MAPSIZE) { - printk(KERN_ERR "security: ebitmap: map size %d does not " - "match my size %d (high bit was %d)\n", mapsize, + printk(KERN_ERR "security: ebitmap: map size %u does not " + "match my size %Zd (high bit was %d)\n", mapsize, MAPSIZE, e->highbit); goto out; } @@ -261,7 +261,7 @@ } if (e->highbit & (MAPSIZE - 1)) { printk(KERN_ERR "security: ebitmap: high bit (%d) is not a " - "multiple of the map size (%d)\n", e->highbit, MAPSIZE); + "multiple of the map size (%Zd)\n", e->highbit, MAPSIZE); goto bad; } l = NULL; @@ -283,13 +283,13 @@ if (n->startbit & (MAPSIZE - 1)) { printk(KERN_ERR "security: ebitmap start bit (%d) is " - "not a multiple of the map size (%d)\n", + "not a multiple of the map size (%Zd)\n", n->startbit, MAPSIZE); goto bad_free; } if (n->startbit > (e->highbit - MAPSIZE)) { printk(KERN_ERR "security: ebitmap start bit (%d) is " - "beyond the end of the bitmap (%d)\n", + "beyond the end of the bitmap (%Zd)\n", n->startbit, (e->highbit - MAPSIZE)); goto bad_free; } diff -Nru a/security/selinux/ss/global.h b/security/selinux/ss/global.h --- a/security/selinux/ss/global.h Tue Sep 2 19:58:19 2003 +++ b/security/selinux/ss/global.h Tue Sep 2 19:58:19 2003 @@ -8,6 +8,7 @@ #include #include #include +#include #include "flask.h" #include "avc.h" diff -Nru a/security/selinux/ss/policydb.c b/security/selinux/ss/policydb.c --- a/security/selinux/ss/policydb.c Tue Sep 2 19:58:15 2003 +++ b/security/selinux/ss/policydb.c Tue Sep 2 19:58:15 2003 @@ -1074,7 +1074,7 @@ len = buf[1]; if (len != strlen(POLICYDB_STRING)) { printk(KERN_ERR "security: policydb string length %d does not " - "match expected length %d\n", + "match expected length %Zd\n", len, strlen(POLICYDB_STRING)); goto bad; } diff -Nru a/sound/core/control.c b/sound/core/control.c --- a/sound/core/control.c Tue Sep 2 19:58:13 2003 +++ b/sound/core/control.c Tue Sep 2 19:58:13 2003 @@ -42,7 +42,7 @@ static int snd_ctl_open(struct inode *inode, struct file *file) { - int cardnum = SNDRV_MINOR_CARD(minor(inode->i_rdev)); + int cardnum = SNDRV_MINOR_CARD(iminor(inode)); unsigned long flags; snd_card_t *card; snd_ctl_file_t *ctl; diff -Nru a/sound/core/hwdep.c b/sound/core/hwdep.c --- a/sound/core/hwdep.c Tue Sep 2 19:58:13 2003 +++ b/sound/core/hwdep.c Tue Sep 2 19:58:13 2003 @@ -73,7 +73,7 @@ static int snd_hwdep_open(struct inode *inode, struct file * file) { - int major = major(inode->i_rdev); + int major = imajor(inode); int cardnum; int device; snd_hwdep_t *hw; @@ -82,12 +82,12 @@ switch (major) { case CONFIG_SND_MAJOR: - cardnum = SNDRV_MINOR_CARD(minor(inode->i_rdev)); - device = SNDRV_MINOR_DEVICE(minor(inode->i_rdev)) - SNDRV_MINOR_HWDEP; + cardnum = SNDRV_MINOR_CARD(iminor(inode)); + device = SNDRV_MINOR_DEVICE(iminor(inode)) - SNDRV_MINOR_HWDEP; break; #ifdef CONFIG_SND_OSSEMUL case SOUND_MAJOR: - cardnum = SNDRV_MINOR_OSS_CARD(minor(inode->i_rdev)); + cardnum = SNDRV_MINOR_OSS_CARD(iminor(inode)); device = 0; break; #endif diff -Nru a/sound/core/oss/mixer_oss.c b/sound/core/oss/mixer_oss.c --- a/sound/core/oss/mixer_oss.c Tue Sep 2 19:58:17 2003 +++ b/sound/core/oss/mixer_oss.c Tue Sep 2 19:58:17 2003 @@ -36,7 +36,7 @@ static int snd_mixer_oss_open(struct inode *inode, struct file *file) { - int cardnum = SNDRV_MINOR_OSS_CARD(minor(inode->i_rdev)); + int cardnum = SNDRV_MINOR_OSS_CARD(iminor(inode)); snd_card_t *card; snd_mixer_oss_file_t *fmixer; int err; diff -Nru a/sound/core/oss/pcm_oss.c b/sound/core/oss/pcm_oss.c --- a/sound/core/oss/pcm_oss.c Tue Sep 2 19:58:18 2003 +++ b/sound/core/oss/pcm_oss.c Tue Sep 2 19:58:18 2003 @@ -1681,7 +1681,7 @@ static int snd_pcm_oss_open(struct inode *inode, struct file *file) { - int minor = minor(inode->i_rdev); + int minor = iminor(inode); int cardnum = SNDRV_MINOR_OSS_CARD(minor); int device; int err; diff -Nru a/sound/core/pcm_native.c b/sound/core/pcm_native.c --- a/sound/core/pcm_native.c Tue Sep 2 19:58:15 2003 +++ b/sound/core/pcm_native.c Tue Sep 2 19:58:15 2003 @@ -1431,11 +1431,11 @@ return 0; inode = file->f_dentry->d_inode; if (!S_ISCHR(inode->i_mode) || - major(inode->i_rdev) != snd_major) { + imajor(inode) != snd_major) { fput(file); return 0; } - minor = minor(inode->i_rdev); + minor = iminor(inode); if (minor >= 256 || minor % SNDRV_MINOR_DEVICES < SNDRV_MINOR_PCM_PLAYBACK) { fput(file); @@ -1940,8 +1940,8 @@ int snd_pcm_open(struct inode *inode, struct file *file) { - int cardnum = SNDRV_MINOR_CARD(minor(inode->i_rdev)); - int device = SNDRV_MINOR_DEVICE(minor(inode->i_rdev)); + int cardnum = SNDRV_MINOR_CARD(iminor(inode)); + int device = SNDRV_MINOR_DEVICE(iminor(inode)); int err; snd_pcm_t *pcm; snd_pcm_file_t *pcm_file; diff -Nru a/sound/core/rawmidi.c b/sound/core/rawmidi.c --- a/sound/core/rawmidi.c Tue Sep 2 19:58:13 2003 +++ b/sound/core/rawmidi.c Tue Sep 2 19:58:13 2003 @@ -345,7 +345,7 @@ static int snd_rawmidi_open(struct inode *inode, struct file *file) { - int maj = major(inode->i_rdev); + int maj = imajor(inode); int cardnum; snd_card_t *card; int device, subdevice; @@ -359,16 +359,16 @@ switch (maj) { case CONFIG_SND_MAJOR: - cardnum = SNDRV_MINOR_CARD(minor(inode->i_rdev)); + cardnum = SNDRV_MINOR_CARD(iminor(inode)); cardnum %= SNDRV_CARDS; - device = SNDRV_MINOR_DEVICE(minor(inode->i_rdev)) - SNDRV_MINOR_RAWMIDI; + device = SNDRV_MINOR_DEVICE(iminor(inode)) - SNDRV_MINOR_RAWMIDI; device %= SNDRV_MINOR_RAWMIDIS; break; #ifdef CONFIG_SND_OSSEMUL case SOUND_MAJOR: - cardnum = SNDRV_MINOR_OSS_CARD(minor(inode->i_rdev)); + cardnum = SNDRV_MINOR_OSS_CARD(iminor(inode)); cardnum %= SNDRV_CARDS; - device = SNDRV_MINOR_OSS_DEVICE(minor(inode->i_rdev)) == SNDRV_MINOR_OSS_MIDI ? + device = SNDRV_MINOR_OSS_DEVICE(iminor(inode)) == SNDRV_MINOR_OSS_MIDI ? midi_map[cardnum] : amidi_map[cardnum]; break; #endif diff -Nru a/sound/core/seq/oss/seq_oss.c b/sound/core/seq/oss/seq_oss.c --- a/sound/core/seq/oss/seq_oss.c Tue Sep 2 19:58:18 2003 +++ b/sound/core/seq/oss/seq_oss.c Tue Sep 2 19:58:18 2003 @@ -121,7 +121,7 @@ { int level, rc; - if (minor(inode->i_rdev) == SNDRV_MINOR_OSS_MUSIC) + if (iminor(inode) == SNDRV_MINOR_OSS_MUSIC) level = SNDRV_SEQ_OSS_MODE_MUSIC; else level = SNDRV_SEQ_OSS_MODE_SYNTH; diff -Nru a/sound/core/sound.c b/sound/core/sound.c --- a/sound/core/sound.c Tue Sep 2 19:58:17 2003 +++ b/sound/core/sound.c Tue Sep 2 19:58:17 2003 @@ -117,7 +117,7 @@ static int snd_open(struct inode *inode, struct file *file) { - int minor = minor(inode->i_rdev); + int minor = iminor(inode); int card = SNDRV_MINOR_CARD(minor); int dev = SNDRV_MINOR_DEVICE(minor); snd_minor_t *mptr = NULL; diff -Nru a/sound/oss/ad1889.c b/sound/oss/ad1889.c --- a/sound/oss/ad1889.c Tue Sep 2 19:58:15 2003 +++ b/sound/oss/ad1889.c Tue Sep 2 19:58:15 2003 @@ -755,7 +755,7 @@ static int ad1889_open(struct inode *inode, struct file *file) { /* check minor; only support /dev/dsp atm */ - if (minor(inode->i_rdev) != 3) + if (iminor(inode) != 3) return -ENXIO; file->private_data = ad1889_dev; @@ -788,7 +788,7 @@ /************************* /dev/mixer interfaces ************************ */ static int ad1889_mixer_open(struct inode *inode, struct file *file) { - if (ad1889_dev->ac97_codec->dev_mixer != minor(inode->i_rdev)) + if (ad1889_dev->ac97_codec->dev_mixer != iminor(inode)) return -ENODEV; file->private_data = ad1889_dev->ac97_codec; diff -Nru a/sound/oss/ali5455.c b/sound/oss/ali5455.c --- a/sound/oss/ali5455.c Tue Sep 2 19:58:18 2003 +++ b/sound/oss/ali5455.c Tue Sep 2 19:58:18 2003 @@ -3026,7 +3026,7 @@ static int ali_open_mixdev(struct inode *inode, struct file *file) { int i; - int minor = minor(inode->i_rdev); + int minor = iminor(inode); struct ali_card *card = devs; for (card = devs; card != NULL; card = card->next) { /* diff -Nru a/sound/oss/au1000.c b/sound/oss/au1000.c --- a/sound/oss/au1000.c Tue Sep 2 19:58:17 2003 +++ b/sound/oss/au1000.c Tue Sep 2 19:58:17 2003 @@ -1842,7 +1842,7 @@ static int au1000_open(struct inode *inode, struct file *file) { - int minor = MINOR(inode->i_rdev); + int minor = iminor(inode); DECLARE_WAITQUEUE(wait, current); struct au1000_state *s = &au1000_state; int ret; diff -Nru a/sound/oss/btaudio.c b/sound/oss/btaudio.c --- a/sound/oss/btaudio.c Tue Sep 2 19:58:14 2003 +++ b/sound/oss/btaudio.c Tue Sep 2 19:58:14 2003 @@ -299,7 +299,7 @@ static int btaudio_mixer_open(struct inode *inode, struct file *file) { - int minor = minor(inode->i_rdev); + int minor = iminor(inode); struct btaudio *bta; for (bta = btaudios; bta != NULL; bta = bta->next) @@ -458,7 +458,7 @@ static int btaudio_dsp_open_digital(struct inode *inode, struct file *file) { - int minor = minor(inode->i_rdev); + int minor = iminor(inode); struct btaudio *bta; for (bta = btaudios; bta != NULL; bta = bta->next) @@ -474,7 +474,7 @@ static int btaudio_dsp_open_analog(struct inode *inode, struct file *file) { - int minor = minor(inode->i_rdev); + int minor = iminor(inode); struct btaudio *bta; for (bta = btaudios; bta != NULL; bta = bta->next) diff -Nru a/sound/oss/cmpci.c b/sound/oss/cmpci.c --- a/sound/oss/cmpci.c Tue Sep 2 19:58:16 2003 +++ b/sound/oss/cmpci.c Tue Sep 2 19:58:16 2003 @@ -1448,7 +1448,7 @@ static int cm_open_mixdev(struct inode *inode, struct file *file) { - int minor = minor(inode->i_rdev); + int minor = iminor(inode); struct cm_state *s = devs; while (s && s->dev_mixer != minor) @@ -2207,7 +2207,7 @@ static int cm_open(struct inode *inode, struct file *file) { - int minor = minor(inode->i_rdev); + int minor = iminor(inode); struct cm_state *s = devs; unsigned char fmtm = ~0, fmts = 0; @@ -2462,7 +2462,7 @@ static int cm_midi_open(struct inode *inode, struct file *file) { - int minor = minor(inode->i_rdev); + int minor = iminor(inode); struct cm_state *s = devs; unsigned long flags; @@ -2679,7 +2679,7 @@ static int cm_dmfm_open(struct inode *inode, struct file *file) { - int minor = minor(inode->i_rdev); + int minor = iminor(inode); struct cm_state *s = devs; while (s && s->dev_dmfm != minor) diff -Nru a/sound/oss/cs4281/cs4281m.c b/sound/oss/cs4281/cs4281m.c --- a/sound/oss/cs4281/cs4281m.c Tue Sep 2 19:58:20 2003 +++ b/sound/oss/cs4281/cs4281m.c Tue Sep 2 19:58:20 2003 @@ -2567,7 +2567,7 @@ static int cs4281_open_mixdev(struct inode *inode, struct file *file) { - unsigned int minor = minor(inode->i_rdev); + unsigned int minor = iminor(inode); struct cs4281_state *s=NULL; struct list_head *entry; @@ -3624,7 +3624,7 @@ static int cs4281_open(struct inode *inode, struct file *file) { - unsigned int minor = minor(inode->i_rdev); + unsigned int minor = iminor(inode); struct cs4281_state *s=NULL; struct list_head *entry; @@ -3966,7 +3966,7 @@ static int cs4281_midi_open(struct inode *inode, struct file *file) { unsigned long flags, temp1; - unsigned int minor = minor(inode->i_rdev); + unsigned int minor = iminor(inode); struct cs4281_state *s=NULL; struct list_head *entry; list_for_each(entry, &cs4281_devs) diff -Nru a/sound/oss/cs46xx.c b/sound/oss/cs46xx.c --- a/sound/oss/cs46xx.c Tue Sep 2 19:58:12 2003 +++ b/sound/oss/cs46xx.c Tue Sep 2 19:58:12 2003 @@ -1838,7 +1838,7 @@ static int cs_midi_open(struct inode *inode, struct file *file) { - unsigned int minor = minor(inode->i_rdev); + unsigned int minor = iminor(inode); struct cs_card *card=NULL; unsigned long flags; struct list_head *entry; @@ -3200,7 +3200,7 @@ struct cs_state *state = NULL; struct dmabuf *dmabuf = NULL; struct list_head *entry; - unsigned int minor = minor(inode->i_rdev); + unsigned int minor = iminor(inode); int ret=0; unsigned int tmp; @@ -4066,7 +4066,7 @@ static int cs_open_mixdev(struct inode *inode, struct file *file) { int i=0; - unsigned int minor = minor(inode->i_rdev); + unsigned int minor = iminor(inode); struct cs_card *card=NULL; struct list_head *entry; unsigned int tmp; @@ -4113,7 +4113,7 @@ static int cs_release_mixdev(struct inode *inode, struct file *file) { - unsigned int minor = minor(inode->i_rdev); + unsigned int minor = iminor(inode); struct cs_card *card=NULL; struct list_head *entry; int i; diff -Nru a/sound/oss/dmasound/dmasound_core.c b/sound/oss/dmasound/dmasound_core.c --- a/sound/oss/dmasound/dmasound_core.c Tue Sep 2 19:58:13 2003 +++ b/sound/oss/dmasound/dmasound_core.c Tue Sep 2 19:58:13 2003 @@ -904,7 +904,7 @@ O_RDONLY and dsp1 could be opened O_WRONLY */ - dmasound.minDev = minor(inode->i_rdev) & 0x0f; + dmasound.minDev = iminor(inode) & 0x0f; /* OK. - we should make some attempt at consistency. At least the H'ware options should be set with a valid mode. We will make it that the LL diff -Nru a/sound/oss/emu10k1/audio.c b/sound/oss/emu10k1/audio.c --- a/sound/oss/emu10k1/audio.c Tue Sep 2 19:58:13 2003 +++ b/sound/oss/emu10k1/audio.c Tue Sep 2 19:58:13 2003 @@ -1112,7 +1112,7 @@ static int emu10k1_audio_open(struct inode *inode, struct file *file) { - int minor = minor(inode->i_rdev); + int minor = iminor(inode); struct emu10k1_card *card = NULL; struct list_head *entry; struct emu10k1_wavedevice *wave_dev; diff -Nru a/sound/oss/emu10k1/midi.c b/sound/oss/emu10k1/midi.c --- a/sound/oss/emu10k1/midi.c Tue Sep 2 19:58:20 2003 +++ b/sound/oss/emu10k1/midi.c Tue Sep 2 19:58:20 2003 @@ -86,7 +86,7 @@ static int emu10k1_midi_open(struct inode *inode, struct file *file) { - int minor = minor(inode->i_rdev); + int minor = iminor(inode); struct emu10k1_card *card = NULL; struct emu10k1_mididevice *midi_dev; struct list_head *entry; diff -Nru a/sound/oss/emu10k1/mixer.c b/sound/oss/emu10k1/mixer.c --- a/sound/oss/emu10k1/mixer.c Tue Sep 2 19:58:17 2003 +++ b/sound/oss/emu10k1/mixer.c Tue Sep 2 19:58:17 2003 @@ -654,7 +654,7 @@ static int emu10k1_mixer_open(struct inode *inode, struct file *file) { - int minor = minor(inode->i_rdev); + int minor = iminor(inode); struct emu10k1_card *card = NULL; struct list_head *entry; diff -Nru a/sound/oss/es1370.c b/sound/oss/es1370.c --- a/sound/oss/es1370.c Tue Sep 2 19:58:20 2003 +++ b/sound/oss/es1370.c Tue Sep 2 19:58:20 2003 @@ -1023,7 +1023,7 @@ static int es1370_open_mixdev(struct inode *inode, struct file *file) { - unsigned int minor = minor(inode->i_rdev); + unsigned int minor = iminor(inode); struct list_head *list; struct es1370_state *s; @@ -1727,7 +1727,7 @@ static int es1370_open(struct inode *inode, struct file *file) { - unsigned int minor = minor(inode->i_rdev); + unsigned int minor = iminor(inode); DECLARE_WAITQUEUE(wait, current); unsigned long flags; struct list_head *list; @@ -2165,7 +2165,7 @@ static int es1370_open_dac(struct inode *inode, struct file *file) { - unsigned int minor = minor(inode->i_rdev); + unsigned int minor = iminor(inode); DECLARE_WAITQUEUE(wait, current); unsigned long flags; struct list_head *list; @@ -2408,7 +2408,7 @@ static int es1370_midi_open(struct inode *inode, struct file *file) { - unsigned int minor = minor(inode->i_rdev); + unsigned int minor = iminor(inode); DECLARE_WAITQUEUE(wait, current); unsigned long flags; struct list_head *list; diff -Nru a/sound/oss/es1371.c b/sound/oss/es1371.c --- a/sound/oss/es1371.c Tue Sep 2 19:58:17 2003 +++ b/sound/oss/es1371.c Tue Sep 2 19:58:18 2003 @@ -1210,7 +1210,7 @@ static int es1371_open_mixdev(struct inode *inode, struct file *file) { - int minor = minor(inode->i_rdev); + int minor = iminor(inode); struct list_head *list; struct es1371_state *s; @@ -1914,7 +1914,7 @@ static int es1371_open(struct inode *inode, struct file *file) { - int minor = minor(inode->i_rdev); + int minor = iminor(inode); DECLARE_WAITQUEUE(wait, current); unsigned long flags; struct list_head *list; @@ -2345,7 +2345,7 @@ static int es1371_open_dac(struct inode *inode, struct file *file) { - int minor = minor(inode->i_rdev); + int minor = iminor(inode); DECLARE_WAITQUEUE(wait, current); unsigned long flags; struct list_head *list; @@ -2587,7 +2587,7 @@ static int es1371_midi_open(struct inode *inode, struct file *file) { - int minor = minor(inode->i_rdev); + int minor = iminor(inode); DECLARE_WAITQUEUE(wait, current); unsigned long flags; struct list_head *list; diff -Nru a/sound/oss/esssolo1.c b/sound/oss/esssolo1.c --- a/sound/oss/esssolo1.c Tue Sep 2 19:58:13 2003 +++ b/sound/oss/esssolo1.c Tue Sep 2 19:58:13 2003 @@ -913,7 +913,7 @@ static int solo1_open_mixdev(struct inode *inode, struct file *file) { - unsigned int minor = minor(inode->i_rdev); + unsigned int minor = iminor(inode); struct solo1_state *s = NULL; struct pci_dev *pci_dev = NULL; @@ -1594,7 +1594,7 @@ static int solo1_open(struct inode *inode, struct file *file) { - unsigned int minor = minor(inode->i_rdev); + unsigned int minor = iminor(inode); DECLARE_WAITQUEUE(wait, current); struct solo1_state *s = NULL; struct pci_dev *pci_dev = NULL; @@ -1884,7 +1884,7 @@ static int solo1_midi_open(struct inode *inode, struct file *file) { - unsigned int minor = minor(inode->i_rdev); + unsigned int minor = iminor(inode); DECLARE_WAITQUEUE(wait, current); unsigned long flags; struct solo1_state *s = NULL; @@ -2106,7 +2106,7 @@ static int solo1_dmfm_open(struct inode *inode, struct file *file) { - unsigned int minor = minor(inode->i_rdev); + unsigned int minor = iminor(inode); DECLARE_WAITQUEUE(wait, current); struct solo1_state *s = NULL; struct pci_dev *pci_dev = NULL; diff -Nru a/sound/oss/hal2.c b/sound/oss/hal2.c --- a/sound/oss/hal2.c Tue Sep 2 19:58:18 2003 +++ b/sound/oss/hal2.c Tue Sep 2 19:58:18 2003 @@ -867,7 +867,7 @@ static int hal2_open_mixdev(struct inode *inode, struct file *file) { - hal2_card_t *hal2 = hal2_mixer_find_card(MINOR(inode->i_rdev)); + hal2_card_t *hal2 = hal2_mixer_find_card(iminor(inode)); if (hal2) { file->private_data = hal2; @@ -1242,7 +1242,7 @@ static int hal2_open(struct inode *inode, struct file *file) { int err; - hal2_card_t *hal2 = hal2_dsp_find_card(MINOR(inode->i_rdev)); + hal2_card_t *hal2 = hal2_dsp_find_card(iminor(inode)); DEBUG("opening audio device.\n"); diff -Nru a/sound/oss/i810_audio.c b/sound/oss/i810_audio.c --- a/sound/oss/i810_audio.c Tue Sep 2 19:58:18 2003 +++ b/sound/oss/i810_audio.c Tue Sep 2 19:58:18 2003 @@ -2648,7 +2648,7 @@ static int i810_open_mixdev(struct inode *inode, struct file *file) { int i; - int minor = minor(inode->i_rdev); + int minor = iminor(inode); struct i810_card *card = devs; for (card = devs; card != NULL; card = card->next) { diff -Nru a/sound/oss/ite8172.c b/sound/oss/ite8172.c --- a/sound/oss/ite8172.c Tue Sep 2 19:58:13 2003 +++ b/sound/oss/ite8172.c Tue Sep 2 19:58:13 2003 @@ -867,7 +867,7 @@ static int it8172_open_mixdev(struct inode *inode, struct file *file) { - int minor = MINOR(inode->i_rdev); + int minor = iminor(inode); struct list_head *list; struct it8172_state *s; @@ -1771,7 +1771,7 @@ static int it8172_open(struct inode *inode, struct file *file) { - int minor = MINOR(inode->i_rdev); + int minor = iminor(inode); DECLARE_WAITQUEUE(wait, current); unsigned long flags; struct list_head *list; @@ -2198,10 +2198,10 @@ MODULE_DEVICE_TABLE(pci, id_table); static struct pci_driver it8172_driver = { - name: IT8172_MODULE_NAME, - id_table: id_table, - probe: it8172_probe, - remove: it8172_remove + .name = IT8172_MODULE_NAME, + .id_table = id_table, + .probe = it8172_probe, + .remove = it8172_remove }; static int __init init_it8172(void) diff -Nru a/sound/oss/maestro.c b/sound/oss/maestro.c --- a/sound/oss/maestro.c Tue Sep 2 19:58:18 2003 +++ b/sound/oss/maestro.c Tue Sep 2 19:58:18 2003 @@ -2138,7 +2138,7 @@ /* --------------------------------------------------------------------- */ static int ess_open_mixdev(struct inode *inode, struct file *file) { - unsigned int minor = minor(inode->i_rdev); + unsigned int minor = iminor(inode); struct ess_card *card = NULL; struct pci_dev *pdev = NULL; struct pci_driver *drvr; @@ -2983,7 +2983,7 @@ static int ess_open(struct inode *inode, struct file *file) { - unsigned int minor = minor(inode->i_rdev); + unsigned int minor = iminor(inode); struct ess_state *s = NULL; unsigned char fmtm = ~0, fmts = 0; struct pci_dev *pdev = NULL; diff -Nru a/sound/oss/maestro3.c b/sound/oss/maestro3.c --- a/sound/oss/maestro3.c Tue Sep 2 19:58:18 2003 +++ b/sound/oss/maestro3.c Tue Sep 2 19:58:18 2003 @@ -1980,7 +1980,7 @@ static int m3_open(struct inode *inode, struct file *file) { - unsigned int minor = minor(inode->i_rdev); + unsigned int minor = iminor(inode); struct m3_card *c; struct m3_state *s = NULL; int i; @@ -2149,7 +2149,7 @@ /* OSS /dev/mixer file operation methods */ static int m3_open_mixdev(struct inode *inode, struct file *file) { - unsigned int minor = minor(inode->i_rdev); + unsigned int minor = iminor(inode); struct m3_card *card = devs; for (card = devs; card != NULL; card = card->next) { diff -Nru a/sound/oss/msnd_pinnacle.c b/sound/oss/msnd_pinnacle.c --- a/sound/oss/msnd_pinnacle.c Tue Sep 2 19:58:16 2003 +++ b/sound/oss/msnd_pinnacle.c Tue Sep 2 19:58:16 2003 @@ -646,7 +646,7 @@ static int dev_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) { - int minor = minor(inode->i_rdev); + int minor = iminor(inode); if (cmd == OSS_GETVERSION) { int sound_version = SOUND_VERSION; @@ -758,7 +758,7 @@ static int dev_open(struct inode *inode, struct file *file) { - int minor = minor(inode->i_rdev); + int minor = iminor(inode); int err = 0; if (minor == dev.dsp_minor) { @@ -793,7 +793,7 @@ static int dev_release(struct inode *inode, struct file *file) { - int minor = minor(inode->i_rdev); + int minor = iminor(inode); int err = 0; lock_kernel(); @@ -983,7 +983,7 @@ static ssize_t dev_read(struct file *file, char *buf, size_t count, loff_t *off) { - int minor = minor(file->f_dentry->d_inode->i_rdev); + int minor = iminor(file->f_dentry->d_inode); if (minor == dev.dsp_minor) return dsp_read(buf, count); else @@ -992,7 +992,7 @@ static ssize_t dev_write(struct file *file, const char *buf, size_t count, loff_t *off) { - int minor = minor(file->f_dentry->d_inode->i_rdev); + int minor = iminor(file->f_dentry->d_inode); if (minor == dev.dsp_minor) return dsp_write(buf, count); else diff -Nru a/sound/oss/nec_vrc5477.c b/sound/oss/nec_vrc5477.c --- a/sound/oss/nec_vrc5477.c Tue Sep 2 19:58:17 2003 +++ b/sound/oss/nec_vrc5477.c Tue Sep 2 19:58:17 2003 @@ -857,7 +857,7 @@ static int vrc5477_ac97_open_mixdev(struct inode *inode, struct file *file) { - int minor = minor(inode->i_rdev); + int minor = iminor(inode); struct list_head *list; struct vrc5477_ac97_state *s; @@ -1569,7 +1569,7 @@ static int vrc5477_ac97_open(struct inode *inode, struct file *file) { - int minor = minor(inode->i_rdev); + int minor = iminor(inode); DECLARE_WAITQUEUE(wait, current); unsigned long flags; struct list_head *list; diff -Nru a/sound/oss/rme96xx.c b/sound/oss/rme96xx.c --- a/sound/oss/rme96xx.c Tue Sep 2 19:58:15 2003 +++ b/sound/oss/rme96xx.c Tue Sep 2 19:58:15 2003 @@ -1445,7 +1445,7 @@ static int rme96xx_open(struct inode *in, struct file *f) { - int minor = minor(in->i_rdev); + int minor = iminor(in); struct list_head *list; int devnum; rme96xx_info *s; @@ -1769,7 +1769,7 @@ static int rme96xx_mixer_open(struct inode *inode, struct file *file) { - int minor = minor(inode->i_rdev); + int minor = iminor(inode); struct list_head *list; rme96xx_info *s; diff -Nru a/sound/oss/sonicvibes.c b/sound/oss/sonicvibes.c --- a/sound/oss/sonicvibes.c Tue Sep 2 19:58:15 2003 +++ b/sound/oss/sonicvibes.c Tue Sep 2 19:58:15 2003 @@ -1238,7 +1238,7 @@ static int sv_open_mixdev(struct inode *inode, struct file *file) { - int minor = minor(inode->i_rdev); + int minor = iminor(inode); struct list_head *list; struct sv_state *s; @@ -1900,7 +1900,7 @@ static int sv_open(struct inode *inode, struct file *file) { - int minor = minor(inode->i_rdev); + int minor = iminor(inode); DECLARE_WAITQUEUE(wait, current); unsigned char fmtm = ~0, fmts = 0; struct list_head *list; @@ -2149,7 +2149,7 @@ static int sv_midi_open(struct inode *inode, struct file *file) { - int minor = minor(inode->i_rdev); + int minor = iminor(inode); DECLARE_WAITQUEUE(wait, current); unsigned long flags; struct list_head *list; @@ -2371,7 +2371,7 @@ static int sv_dmfm_open(struct inode *inode, struct file *file) { - int minor = minor(inode->i_rdev); + int minor = iminor(inode); DECLARE_WAITQUEUE(wait, current); struct list_head *list; struct sv_state *s; diff -Nru a/sound/oss/soundcard.c b/sound/oss/soundcard.c --- a/sound/oss/soundcard.c Tue Sep 2 19:58:15 2003 +++ b/sound/oss/soundcard.c Tue Sep 2 19:58:15 2003 @@ -144,7 +144,7 @@ static ssize_t sound_read(struct file *file, char *buf, size_t count, loff_t *ppos) { - int dev = minor(file->f_dentry->d_inode->i_rdev); + int dev = iminor(file->f_dentry->d_inode); int ret = -EINVAL; /* @@ -177,7 +177,7 @@ static ssize_t sound_write(struct file *file, const char *buf, size_t count, loff_t *ppos) { - int dev = minor(file->f_dentry->d_inode->i_rdev); + int dev = iminor(file->f_dentry->d_inode); int ret = -EINVAL; lock_kernel(); @@ -204,7 +204,7 @@ static int sound_open(struct inode *inode, struct file *file) { - int dev = minor(inode->i_rdev); + int dev = iminor(inode); int retval; DEB(printk("sound_open(dev=%d)\n", dev)); @@ -253,7 +253,7 @@ static int sound_release(struct inode *inode, struct file *file) { - int dev = minor(inode->i_rdev); + int dev = iminor(inode); lock_kernel(); DEB(printk("sound_release(dev=%d)\n", dev)); @@ -333,7 +333,7 @@ unsigned int cmd, unsigned long arg) { int err, len = 0, dtype; - int dev = minor(inode->i_rdev); + int dev = iminor(inode); if (_SIOC_DIR(cmd) != _SIOC_NONE && _SIOC_DIR(cmd) != 0) { /* @@ -396,7 +396,7 @@ static unsigned int sound_poll(struct file *file, poll_table * wait) { struct inode *inode = file->f_dentry->d_inode; - int dev = minor(inode->i_rdev); + int dev = iminor(inode); DEB(printk("sound_poll(dev=%d)\n", dev)); switch (dev & 0x0f) { @@ -420,7 +420,7 @@ int dev_class; unsigned long size; struct dma_buffparms *dmap = NULL; - int dev = minor(file->f_dentry->d_inode->i_rdev); + int dev = iminor(file->f_dentry->d_inode); dev_class = dev & 0x0f; dev >>= 4; diff -Nru a/sound/oss/swarm_cs4297a.c b/sound/oss/swarm_cs4297a.c --- a/sound/oss/swarm_cs4297a.c Tue Sep 2 19:58:16 2003 +++ b/sound/oss/swarm_cs4297a.c Tue Sep 2 19:58:16 2003 @@ -1537,7 +1537,7 @@ static int cs4297a_open_mixdev(struct inode *inode, struct file *file) { - int minor = MINOR(inode->i_rdev); + int minor = iminor(inode); struct cs4297a_state *s=NULL; struct list_head *entry; @@ -2386,7 +2386,7 @@ static int cs4297a_open(struct inode *inode, struct file *file) { - int minor = MINOR(inode->i_rdev); + int minor = iminor(inode); struct cs4297a_state *s=NULL; struct list_head *entry; diff -Nru a/sound/oss/trident.c b/sound/oss/trident.c --- a/sound/oss/trident.c Tue Sep 2 19:58:18 2003 +++ b/sound/oss/trident.c Tue Sep 2 19:58:18 2003 @@ -2600,7 +2600,7 @@ static int trident_open(struct inode *inode, struct file *file) { int i = 0; - int minor = minor(inode->i_rdev); + int minor = iminor(inode); struct trident_card *card = devs; struct trident_state *state = NULL; struct dmabuf *dmabuf = NULL; @@ -3883,7 +3883,7 @@ static int trident_open_mixdev(struct inode *inode, struct file *file) { int i = 0; - int minor = minor(inode->i_rdev); + int minor = iminor(inode); struct trident_card *card = devs; for (card = devs; card != NULL; card = card->next) diff -Nru a/sound/oss/via82cxxx_audio.c b/sound/oss/via82cxxx_audio.c --- a/sound/oss/via82cxxx_audio.c Tue Sep 2 19:58:14 2003 +++ b/sound/oss/via82cxxx_audio.c Tue Sep 2 19:58:14 2003 @@ -1556,7 +1556,7 @@ static int via_mixer_open (struct inode *inode, struct file *file) { - int minor = minor(inode->i_rdev); + int minor = iminor(inode); struct via_info *card; struct pci_dev *pdev = NULL; struct pci_driver *drvr; @@ -3252,7 +3252,7 @@ static int via_dsp_open (struct inode *inode, struct file *file) { - int minor = minor(inode->i_rdev); + int minor = iminor(inode); struct via_info *card; struct pci_dev *pdev = NULL; struct via_channel *chan; diff -Nru a/sound/oss/vwsnd.c b/sound/oss/vwsnd.c --- a/sound/oss/vwsnd.c Tue Sep 2 19:58:16 2003 +++ b/sound/oss/vwsnd.c Tue Sep 2 19:58:16 2003 @@ -2916,7 +2916,7 @@ static int vwsnd_audio_open(struct inode *inode, struct file *file) { vwsnd_dev_t *devc; - dev_t minor = minor(inode->i_rdev); + int minor = iminor(inode); int sw_samplefmt; DBGE("(inode=0x%p, file=0x%p)\n", inode, file); @@ -3063,7 +3063,7 @@ INC_USE_COUNT; for (devc = vwsnd_dev_list; devc; devc = devc->next_dev) - if (devc->mixer_minor == minor(inode->i_rdev)) + if (devc->mixer_minor == iminor(inode)) break; if (devc == NULL) { diff -Nru a/sound/oss/ymfpci.c b/sound/oss/ymfpci.c --- a/sound/oss/ymfpci.c Tue Sep 2 19:58:17 2003 +++ b/sound/oss/ymfpci.c Tue Sep 2 19:58:17 2003 @@ -1905,7 +1905,7 @@ struct ymf_state *state; int err; - minor = minor(inode->i_rdev); + minor = iminor(inode); if ((minor & 0x0F) == 3) { /* /dev/dspN */ ; } else { @@ -2019,7 +2019,7 @@ */ static int ymf_open_mixdev(struct inode *inode, struct file *file) { - int minor = minor(inode->i_rdev); + int minor = iminor(inode); struct list_head *list; ymfpci_t *unit; int i; diff -Nru a/sound/pcmcia/vx/vx_entry.c b/sound/pcmcia/vx/vx_entry.c --- a/sound/pcmcia/vx/vx_entry.c Tue Sep 2 19:58:12 2003 +++ b/sound/pcmcia/vx/vx_entry.c Tue Sep 2 19:58:12 2003 @@ -34,10 +34,8 @@ static int vxpocket_event(event_t event, int priority, event_callback_args_t *args); -static void vxpocket_release(u_long arg) +static void vxpocket_release(dev_link_t* link) { - dev_link_t *link = (dev_link_t *)arg; - if (link->state & DEV_CONFIG) { /* release cs resources */ CardServices(ReleaseConfiguration, link->handle); @@ -56,7 +54,7 @@ struct snd_vxp_entry *hw; dev_link_t *link = &vxp->link; - vxpocket_release((u_long)link); + vxpocket_release(link); /* Break the link with Card Services */ if (link->handle) @@ -148,9 +146,6 @@ link->irq.Handler = &snd_vx_irq_handler; link->irq.Instance = chip; - link->release.function = &vxpocket_release; - link->release.data = (u_long)link; - link->conf.Attributes = CONF_ENABLE_IRQ; link->conf.Vcc = 50; link->conf.IntType = INT_MEMORY_AND_IO; @@ -229,8 +224,6 @@ { vx_core_t *chip = snd_magic_cast(vx_core_t, link->priv, return); - del_timer(&link->release); - snd_printdd(KERN_DEBUG "vxpocket_detach called\n"); /* Remove the interface data from the linked list */ if (hw) { @@ -326,7 +319,6 @@ snd_printdd(KERN_DEBUG "CARD_REMOVAL..\n"); link->state &= ~DEV_PRESENT; if (link->state & DEV_CONFIG) { - mod_timer(&link->release, jiffies + HZ/20); chip->chip_status |= VX_STAT_IS_STALE; } break; diff -Nru a/sound/ppc/keywest.c b/sound/ppc/keywest.c --- a/sound/ppc/keywest.c Tue Sep 2 19:58:19 2003 +++ b/sound/ppc/keywest.c Tue Sep 2 19:58:19 2003 @@ -50,7 +50,7 @@ #ifndef i2c_device_name -#define i2c_device_name(x) ((x)->dev.name) +#define i2c_device_name(x) ((x)->name) #endif static int keywest_attach_adapter(struct i2c_adapter *adapter) diff -Nru a/sound/sound_core.c b/sound/sound_core.c --- a/sound/sound_core.c Tue Sep 2 19:58:19 2003 +++ b/sound/sound_core.c Tue Sep 2 19:58:19 2003 @@ -483,7 +483,7 @@ int soundcore_open(struct inode *inode, struct file *file) { int chain; - int unit = minor(inode->i_rdev); + int unit = iminor(inode); struct sound_unit *s; struct file_operations *new_fops = NULL;