# 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.1455 # 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 # net/core/link_watch.c 1.4 -> 1.5 # Documentation/DocBook/scsidrivers.tmpl 1.3 -> 1.4 # drivers/net/irda/irtty-sir.c 1.8 -> 1.9 # drivers/isdn/i4l/isdn_audio.c 1.15 -> 1.16 # 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.43 # 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 # include/asm-s390/semaphore.h 1.4 -> 1.5 # fs/cifs/file.c 1.29 -> 1.31 # 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 # include/linux/kernel.h 1.39 -> 1.40 # arch/i386/kernel/timers/Makefile 1.7 -> 1.8 # include/linux/rtc.h 1.6 -> 1.7 # include/asm-x86_64/semaphore.h 1.4 -> 1.5 # include/asm-ppc/pgalloc.h 1.12 -> 1.13 # drivers/scsi/imm.h 1.11 -> 1.13 # drivers/ide/legacy/macide.c 1.4 -> 1.5 # include/asm-parisc/semaphore.h 1.5 -> 1.6 # drivers/scsi/sym53c8xx_2/sym_hipd.c 1.9 -> 1.10 # drivers/block/acsi_slm.c 1.14 -> 1.15 # drivers/scsi/qlogicisp.h 1.6 -> 1.7 # include/asm-arm/proc-armo/elf.h 1.1 -> (deleted) # arch/ppc/boot/simple/Makefile 1.19 -> 1.21 # ipc/msg.c 1.14 -> 1.15 # drivers/scsi/ips.c 1.67 -> 1.68 # drivers/block/as-iosched.c 1.14 -> 1.16 # 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 # drivers/scsi/scsi_error.c 1.61 -> 1.62 # include/asm-ppc/processor.h 1.32 -> 1.34 # drivers/usb/input/kbtab.c 1.4 -> 1.5 # net/bluetooth/rfcomm/core.c 1.22 -> 1.23 # drivers/usb/misc/uss720.c 1.14 -> 1.15 # arch/arm/kernel/head.S 1.16 -> 1.17 # 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 # include/asm-arm/proc-armv/uaccess.h 1.10 -> (deleted) # 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.28 # kernel/ksyms.c 1.216 -> 1.217 # fs/cifs/inode.c 1.22 -> 1.24 # drivers/cdrom/gscd.c 1.35 -> 1.36 # arch/arm/mach-footbridge/netwinder-pci.c 1.7 -> 1.8 # arch/ppc/xmon/start.c 1.14 -> 1.15 # include/linux/if_frad.h 1.3 -> 1.4 # arch/arm/kernel/entry-common.S 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/isdn/i4l/isdn_ttyfax.c 1.16 -> 1.17 # drivers/net/wan/cosa.c 1.22 -> 1.24 # drivers/net/tulip/de4x5.c 1.30 -> 1.31 # arch/parisc/kernel/ioctl32.c 1.13 -> 1.15 # include/asm-arm/dma-mapping.h 1.6 -> 1.7 # arch/arm/mm/proc-arm920.S 1.21 -> 1.22 # include/asm-arm/proc-armv/system.h 1.11 -> (deleted) # 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 # drivers/isdn/i4l/isdn_net_lib.c 1.42 -> 1.43 # net/sched/sch_generic.c 1.5 -> 1.6 # drivers/net/bmac.c 1.17 -> 1.18 # include/scsi/scsi_device.h 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.42 # 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/isdn/hisax/hfc_2bds0.c 1.28 -> 1.29 # 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 # net/atm/addr.c 1.3 -> 1.4 # include/net/profile.h 1.2 -> (deleted) # arch/i386/kernel/apm.c 1.56 -> 1.57 # drivers/net/dgrs.c 1.19 -> 1.20 # drivers/net/natsemi.c 1.54 -> 1.55 # fs/open.c 1.48 -> 1.49 # drivers/scsi/hosts.c 1.89 -> 1.91 # 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.21 # arch/ppc/Makefile 1.41 -> 1.43 # sound/core/hwdep.c 1.14 -> 1.16 # arch/arm/mm/proc-arm1020.S 1.16 -> 1.17 # drivers/net/sb1000.c 1.21 -> 1.22 # net/ipv6/ip6_output.c 1.43 -> 1.44 # net/sunrpc/sysctl.c 1.6 -> 1.7 # drivers/scsi/cpqfcTSinit.c 1.41 -> 1.42 # drivers/ide/pci/serverworks.c 1.19 -> 1.20 # arch/sh/boards/unknown/mach.c 1.4 -> 1.5 # drivers/net/ioc3-eth.c 1.23 -> 1.24 # 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/syslib/Makefile 1.9 -> 1.10 # arch/ppc/8xx_io/cs4218_tdm.c 1.7 -> 1.8 # drivers/net/wireless/hermes.h 1.14 -> 1.15 # drivers/scsi/scsi_logging.h 1.1 -> 1.4 # include/asm-arm/assembler.h 1.3 -> 1.4 # arch/ppc/boot/include/of1275.h 1.1 -> 1.2 # mm/page_alloc.c 1.169 -> 1.171 # drivers/scsi/scsi_proc.c 1.34 -> 1.36 # 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 # include/asm-ppc/ppc_asm.h 1.14 -> 1.15 # 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 # drivers/isdn/hisax/hfc_sx.c 1.39 -> 1.40 # include/linux/pmu.h 1.5 -> 1.8 # include/asm-arm/proc-armo/shmparam.h 1.1 -> (deleted) # include/asm-sparc/unistd.h 1.24 -> 1.25 # include/asm-arm/proc-armv/pgtable.h 1.14 -> (deleted) # 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.30 # drivers/isdn/hisax/hfc_2bs0.c 1.22 -> 1.23 # drivers/net/pcmcia/nmclan_cs.c 1.19 -> 1.20 # security/selinux/Kconfig 1.1 -> 1.2 # 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.210 # kernel/sysctl.c 1.51 -> 1.52 # drivers/net/Space.c 1.23 -> 1.33 # 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.75 # 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 # include/asm-ppc/irq.h 1.9 -> 1.10 # drivers/media/video/bt819.c 1.12 -> 1.13 # include/asm-ia64/unistd.h 1.34 -> 1.35 # drivers/net/smc-mca.c 1.10 -> 1.11 # drivers/video/Makefile 1.87 -> 1.88 # drivers/net/8390.c 1.13 -> 1.14 # arch/arm/boot/Makefile 1.22 -> 1.24 # arch/ppc/platforms/4xx/Kconfig 1.5 -> 1.6 # 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/net/lasi_82596.c 1.20 -> 1.21 # drivers/net/tlan.c 1.26 -> 1.27 # include/asm-arm/system.h 1.17 -> 1.18 # 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 # fs/proc/proc_misc.c 1.85 -> 1.89 # drivers/char/agp/frontend.c 1.40 -> 1.42 # include/asm-arm/atomic.h 1.7 -> 1.8 # drivers/scsi/dc395x.c 1.20 -> 1.26 # 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 # arch/i386/kernel/cpu/mcheck/non-fatal.c 1.5 -> 1.6 # drivers/net/3c515.c 1.21 -> 1.23 # arch/x86_64/kernel/apic.c 1.22 -> 1.23 # drivers/net/loopback.c 1.8 -> 1.9 # arch/ia64/hp/common/sba_iommu.c 1.28 -> 1.29 # arch/i386/Kconfig 1.72 -> 1.75 # drivers/block/floppy.c 1.84 -> 1.88 # 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.32 # sound/core/rawmidi.c 1.27 -> 1.29 # include/linux/genhd.h 1.55 -> 1.58 # drivers/isdn/hisax/elsa.c 1.38 -> 1.39 # drivers/scsi/53c700.c 1.40 -> 1.42 # 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 # drivers/ide/pci/generic.h 1.5 -> 1.6 # include/asm-ppc/tlbflush.h 1.7 -> 1.8 # 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 # drivers/isdn/hisax/netjet.c 1.26 -> 1.27 # 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 # net/ipv4/udp.c 1.46 -> 1.47 # drivers/cdrom/sbpcd.c 1.47 -> 1.48 # 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/net/hamradio/6pack.c 1.14 -> 1.15 # 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 # include/asm-arm/page.h 1.11 -> 1.12 # 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 # arch/ppc/mm/pgtable.c 1.12 -> 1.13 # include/asm-arm/proc-armo/cache.h 1.6 -> (deleted) # 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/isdn/hisax/isdnl2.c 1.11 -> 1.12 # 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/isdn/i4l/isdn_net_lib.h 1.6 -> 1.7 # 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 # arch/arm/mach-l7200/core.c 1.5 -> 1.6 # 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 # include/asm-sparc64/termios.h 1.5 -> 1.6 # fs/cifs/cifssmb.c 1.27 -> 1.28 # drivers/ieee1394/csr.c 1.14 -> 1.15 # drivers/atm/eni.c 1.20 -> 1.22 # include/asm-ppc/pgtable.h 1.23 -> 1.24 # include/linux/blkdev.h 1.123 -> 1.125 # 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 # arch/ppc/mm/init.c 1.30 -> 1.31 # drivers/isdn/hisax/l3ni1.c 1.10 -> 1.11 # 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 -> (deleted) # drivers/scsi/NCR5380.c 1.19 -> 1.20 # arch/ia64/kernel/smpboot.c 1.37 -> 1.38 # drivers/cdrom/optcd.c 1.31 -> 1.32 # arch/arm/def-configs/iq80321 1.3 -> 1.4 # net/bluetooth/sco.c 1.20 -> 1.21 # 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.11 # drivers/net/starfire.c 1.30 -> 1.31 # drivers/scsi/sr.c 1.89 -> 1.92 # 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 # include/linux/hiddev.h 1.8 -> 1.9 # 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.269 # drivers/atm/lanai.c 1.16 -> 1.17 # 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 # include/asm-arm/pgtable.h 1.16 -> 1.17 # 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 # arch/arm/kernel/entry-armo.S 1.10 -> (deleted) # include/asm-arm/proc-armo/pgtable.h 1.5 -> (deleted) # include/asm-ppc/page.h 1.13 -> 1.14 # drivers/scsi/aic7xxx/aic79xx_osm_pci.c 1.9 -> 1.10 # drivers/isdn/hardware/avm/Kconfig 1.2 -> 1.3 # drivers/net/lp486e.c 1.13 -> 1.14 # drivers/net/pcnet32.c 1.40 -> 1.42 # drivers/char/n_hdlc.c 1.16 -> 1.18 # 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.96 # 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/ncr53c8xx.c 1.33 -> 1.34 # fs/cifs/link.c 1.6 -> 1.7 # drivers/scsi/advansys.c 1.35 -> 1.37 # drivers/net/appletalk/ltpc.c 1.12 -> 1.13 # 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 # arch/arm/kernel/entry-armv.S 1.31 -> 1.32 # fs/dnotify.c 1.8 -> 1.10 # drivers/isdn/sc/command.c 1.8 -> 1.9 # 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 # drivers/char/pty.c 1.21 -> 1.22 # 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/isdn/sc/shmem.c 1.3 -> 1.4 # include/asm-arm/tlbflush.h 1.1 -> (deleted) # include/asm-arm/proc-armo/page.h 1.2 -> (deleted) # drivers/ide/ide-tape.c 1.27 -> 1.29 # 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 # include/asm-arm/proc-armo/system.h 1.5 -> (deleted) # drivers/net/sunhme.c 1.39 -> 1.42 # drivers/acorn/block/fd1772.c 1.38 -> 1.39 # net/decnet/dn_dev.c 1.17 -> 1.18 # sound/core/pcm_native.c 1.37 -> 1.39 # arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_irq.c 1.2 -> 1.3 # drivers/scsi/scsi_devinfo.c 1.5 -> 1.6 # 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 # drivers/cdrom/sonycd535.c 1.37 -> 1.38 # drivers/isdn/hisax/elsa_ser.c 1.17 -> 1.18 # include/asm-arm/proc-armo/ptrace.h 1.3 -> (deleted) # kernel/configs.c 1.2 -> 1.3 # 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.13 # arch/m68knommu/platform/5206e/config.c 1.4 -> 1.5 # arch/sparc64/solaris/socksys.c 1.12 -> 1.13 # drivers/net/wan/sbni.c 1.21 -> 1.22 # 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.77 # include/asm-cris/semaphore.h 1.4 -> 1.5 # 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 # Documentation/kmod.txt 1.1 -> (deleted) # 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.20 # arch/arm/Makefile 1.44 -> 1.47 # 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.74 # drivers/net/yellowfin.c 1.25 -> 1.27 # 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/sym53c8xx_2/sym_defs.h 1.1 -> 1.2 # drivers/scsi/arm/fas216.c 1.24 -> 1.25 # 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/asm-mips/semaphore.h 1.5 -> 1.6 # include/net/ip6_tunnel.h 1.1 -> 1.2 # drivers/char/nvram.c 1.18 -> 1.19 # drivers/isdn/hisax/q931.c 1.6 -> 1.7 # include/linux/isdn/capilli.h 1.14 -> 1.15 # drivers/isdn/hisax/st5481_b.c 1.12 -> 1.13 # 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.32 # drivers/message/fusion/mptscsih.c 1.26 -> 1.28 # 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 # include/asm-v850/semaphore.h 1.1 -> 1.2 # 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 # net/rxrpc/sysctl.c 1.3 -> 1.4 # 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/ide/ide-disk.c 1.60 -> 1.61 # drivers/net/dl2k.c 1.29 -> 1.30 # drivers/usb/serial/usb-serial.c 1.89 -> 1.91 # arch/sparc/kernel/sys_sunos.c 1.24 -> 1.26 # drivers/isdn/hisax/l3dss1.c 1.10 -> 1.11 # 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 # drivers/isdn/hisax/hfc_pci.c 1.42 -> 1.43 # include/asm-arm/proc-armo/uaccess.h 1.2 -> (deleted) # drivers/net/b44.c 1.11 -> 1.12 # 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.38 # drivers/net/ppp_synctty.c 1.9 -> 1.10 # drivers/isdn/hisax/isar.c 1.27 -> 1.28 # 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.44 # include/linux/usb.h 1.87 -> 1.89 # include/linux/usb_gadget.h 1.4 -> 1.5 # drivers/isdn/capi/capidrv.c 1.24 -> 1.25 # drivers/net/dummy.c 1.5 -> 1.6 # include/asm-arm/proc-armo/locks.h 1.2 -> (deleted) # drivers/ide/ide-cd.c 1.57 -> 1.59 # drivers/net/tun.c 1.26 -> 1.27 # 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.21 # 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 # include/asm-arm/proc-armv/cache.h 1.15 -> (deleted) # 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/char/riscom8.c 1.22 -> 1.23 # drivers/scsi/sg.c 1.62 -> 1.66 # drivers/usb/serial/pl2303.c 1.45 -> 1.46 # drivers/isdn/hisax/st5481_d.c 1.11 -> 1.12 # arch/v850/Kconfig 1.17 -> 1.18 # include/asm-ppc/cpm_8260.h 1.4 -> 1.5 # drivers/net/epic100.c 1.34 -> 1.36 # 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 # include/asm-ia64/semaphore.h 1.4 -> 1.5 # drivers/net/8139cp.c 1.43 -> 1.57 # drivers/net/acenic.c 1.38 -> 1.39 # drivers/ide/Kconfig 1.26 -> 1.28 # drivers/block/amiflop.c 1.43 -> 1.46 # drivers/cdrom/mcdx.c 1.34 -> 1.35 # include/asm-h8300/edosk2674/timer_rate.h 1.1 -> (deleted) # net/core/netfilter.c 1.23 -> 1.25 # 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.94 # include/asm-arm/thread_info.h 1.7 -> 1.8 # arch/arm/mm/proc-sa110.S 1.20 -> 1.21 # include/asm-arm/arch-iop3xx/iop310.h 1.4 -> 1.5 # fs/affs/file.c 1.25 -> 1.26 # include/asm-arm/proc-armv/shmparam.h 1.1 -> (deleted) # include/asm-h8300/semaphore.h 1.3 -> 1.4 # 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.50 # drivers/scsi/pci2220i.h 1.6 -> 1.7 # include/asm-sparc/termios.h 1.5 -> 1.6 # 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/scsi/gdth_proc.c 1.14 -> 1.15 # drivers/scsi/AM53C974.c 1.17 -> 1.18 # 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 # include/asm-arm/processor.h 1.14 -> 1.15 # 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 # drivers/ide/ide-floppy.c 1.31 -> 1.32 # 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 # drivers/scsi/scsi_lib.c 1.110 -> 1.111 # net/netrom/af_netrom.c 1.36 -> 1.38 # include/linux/tty.h 1.19 -> 1.20 # drivers/net/appletalk/cops.c 1.17 -> 1.18 # include/asm-arm/semaphore.h 1.4 -> 1.6 # drivers/net/wan/dlci.c 1.11 -> 1.12 # arch/sparc/kernel/systbls.S 1.21 -> 1.23 # net/netlink/af_netlink.c 1.30 -> 1.33 # ipc/shm.c 1.28 -> 1.29 # fs/coda/inode.c 1.27 -> 1.29 # net/core/dev.c 1.95 -> 1.100 # 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/isdn/hisax/ipacx.c 1.39 -> 1.40 # drivers/scsi/scsi.c 1.123 -> 1.125 # 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/isdn/hisax/callc.c 1.22 -> 1.23 # drivers/char/dsp56k.c 1.13 -> 1.14 # include/asm-ppc/ibm4xx.h 1.7 -> 1.8 # include/asm-arm/shmparam.h 1.1 -> 1.2 # drivers/net/r8169.c 1.14 -> 1.15 # 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 # arch/arm/mm/proc-arm2_3.S 1.12 -> (deleted) # drivers/char/watchdog/wdt.c 1.20 -> 1.22 # drivers/md/xor.c 1.7 -> 1.8 # include/asm-arm/proc-armv/ptrace.h 1.4 -> (deleted) # drivers/usb/host/ohci-sa1111.c 1.16 -> 1.17 # include/linux/personality.h 1.5 -> 1.6 # drivers/ide/pci/generic.c 1.9 -> 1.10 # drivers/scsi/arm/acornscsi.c 1.34 -> 1.35 # 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 # include/asm-arm/proc-armv/pgalloc.h 1.8 -> (deleted) # include/asm-i386/termios.h 1.3 -> 1.4 # net/ipv4/netfilter/ipt_MARK.c 1.4 -> 1.5 # arch/ppc/kernel/cputable.c 1.11 -> 1.13 # arch/ppc/mm/mmu_decl.h 1.8 -> 1.9 # 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 # include/asm-arm/proc-fns.h 1.8 -> 1.9 # include/asm-arm/param.h 1.4 -> 1.5 # 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 # arch/arm/mm/proc-arm926.S 1.18 -> 1.19 # 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 # mm/mremap.c 1.32 -> 1.33 # drivers/net/sk_mca.h 1.2 -> 1.3 # include/linux/sysctl.h 1.50 -> 1.51 # drivers/isdn/hardware/avm/c4.c 1.36 -> 1.37 # 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.107 # 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.56 # 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/net/amd8111e.c 1.10 -> 1.11 # 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.65 # 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/linux/miscdevice.h 1.7 -> 1.8 # include/asm-i386/smp.h 1.28 -> 1.29 # include/linux/skbuff.h 1.29 -> 1.31 # drivers/char/sonypi.h 1.16 -> 1.18 # fs/intermezzo/presto.c 1.13 -> 1.14 # include/asm-arm/ptrace.h 1.3 -> 1.4 # 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.51 # MAINTAINERS 1.166.1.6 -> 1.172 # drivers/net/sundance.c 1.49 -> 1.50 # 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 # include/asm-m68knommu/semaphore.h 1.2 -> 1.3 # arch/sparc64/kernel/sys_sunos32.c 1.33 -> 1.35 # include/asm-arm/proc-armo/assembler.h 1.1 -> (deleted) # net/ipv4/netfilter/ipt_MASQUERADE.c 1.9 -> 1.10 # drivers/cdrom/mcd.c 1.34 -> 1.35 # 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 # include/asm-arm/proc-armo/tlbflush.h 1.1 -> (deleted) # 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/scsi/gdth.c 1.34 -> 1.35 # 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 # drivers/isdn/hisax/l3_1tr6.c 1.6 -> 1.7 # include/asm-arm/arch-ebsa285/timex.h 1.1 -> 1.2 # drivers/net/typhoon.c 1.7 -> 1.8 # 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/uaccess.h 1.11 -> 1.12 # include/asm-arm/arch-pxa/pxa-regs.h 1.6 -> 1.7 # drivers/isdn/hisax/amd7930_fn.c 1.16 -> 1.17 # fs/cifs/dir.c 1.14 -> 1.16 # 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/ide-scsi.c 1.30 -> 1.31 # arch/arm/mm/mm-armv.c 1.21 -> 1.22 # drivers/scsi/st.c 1.69 -> 1.71 # drivers/block/z2ram.c 1.27 -> 1.29 # fs/vfat/namei.c 1.41 -> 1.42 # net/bluetooth/rfcomm/sock.c 1.22 -> 1.24 # arch/arm/mm/proc-arm720.S 1.19 -> 1.20 # 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 # drivers/net/eepro100.c 1.67 -> 1.68 # drivers/scsi/pcmcia/Kconfig 1.5 -> 1.6 # 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 # drivers/scsi/sr_ioctl.c 1.30 -> 1.31 # 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 # arch/arm/mach-rpc/riscpc.c 1.5 -> 1.6 # drivers/usb/serial/mct_u232.c 1.39 -> 1.40 # drivers/cdrom/sjcd.c 1.28 -> 1.29 # drivers/isdn/hisax/hisax.h 1.50 -> 1.51 # arch/sparc64/mm/hugetlbpage.c 1.7 -> 1.8 # drivers/net/pcmcia/fmvj18x_cs.c 1.24 -> 1.25 # drivers/scsi/sym53c8xx.c 1.41 -> 1.42 # 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 # include/asm-arm/proc-armv/page.h 1.2 -> (deleted) # net/ax25/ax25_route.c 1.12 -> 1.13 # net/ipv6/ah6.c 1.23 -> 1.24 # 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 # drivers/scsi/scsi_priv.h 1.22 -> 1.26 # net/bluetooth/l2cap.c 1.31 -> 1.33 # 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/cdrom/cdu31a.c 1.38 -> 1.39 # 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.86 # arch/m68knommu/Kconfig 1.20 -> 1.21 # include/asm-h8300/aki3068net/timer_rate.h 1.1 -> (deleted) # include/linux/page-flags.h 1.41 -> 1.42 # include/asm-arm/proc-armv/elf.h 1.4 -> (deleted) # drivers/net/fealnx.c 1.29 -> 1.32 # 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 # drivers/isdn/sc/init.c 1.7 -> 1.8 # 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/isdn/i4l/isdn_tty.c 1.52 -> 1.53 # 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/isdn/hisax/isdnl1.h 1.30 -> 1.31 # drivers/ide/pci/pdc202xx_new.c 1.17 -> 1.18 # drivers/net/ppp_async.c 1.13 -> 1.14 # 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/isdn/hardware/eicon/platform.h 1.2 -> 1.3 # 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/isdn/hisax/hisax_fcpcipnp.c 1.20 -> 1.21 # 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 # drivers/scsi/sd.c 1.132 -> 1.134 # include/asm-arm/proc-armv/tlbflush.h 1.5 -> 1.7 include/asm-arm/tlbflush.h (moved) # 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.34 # drivers/ide/pci/slc90e66.c 1.12 -> 1.13 # drivers/bluetooth/hci_ldisc.c 1.10 -> 1.11 # arch/arm/mm/proc-sa1100.S 1.3 -> 1.4 # include/asm-arm/proc-armv/domain.h 1.2 -> 1.4 include/asm-arm/domain.h (moved) # 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 # arch/arm/mm/proc-arm6_7.S 1.19 -> 1.20 # 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 # include/asm-arm/cpu-multi26.h 1.4 -> (deleted) # 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 # mm/slab.c 1.97 -> 1.99 # drivers/block/elevator.c 1.50 -> 1.51 # net/ipv4/netfilter/arp_tables.c 1.10 -> 1.11 # net/ipv4/netfilter/ip_conntrack_ftp.c 1.16 -> 1.17 # drivers/scsi/cpqfcTSworker.c 1.18 -> 1.19 # drivers/scsi/sym53c8xx_defs.h 1.9 -> 1.10 # 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.26 # arch/sparc64/kernel/semaphore.c 1.6 -> 1.7 # drivers/scsi/scsi_scan.c 1.103 -> 1.105 # arch/x86_64/Kconfig 1.28 -> 1.29 # sound/core/seq/oss/seq_oss.c 1.5 -> 1.6 # drivers/net/rcpci45.c 1.25 -> 1.26 # 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 # include/asm-arm/proc-armo/pgalloc.h 1.3 -> (deleted) # drivers/scsi/sym53c8xx_2/sym_conf.h 1.2 -> 1.3 # arch/ppc/mm/Makefile 1.13 -> 1.14 # crypto/tcrypt.c 1.27 -> 1.28 # drivers/Makefile 1.39 -> 1.40 # drivers/block/deadline-iosched.c 1.23 -> 1.24 # arch/sh/boards/ec3104/mach.c 1.3 -> 1.4 # arch/ppc/boot/simple/misc.c 1.11 -> 1.13 # 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/scsi/Makefile 1.45 -> 1.47 # drivers/usb/net/Makefile.mii 1.2 -> 1.3 # init/Kconfig 1.22 -> 1.25 # 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 # drivers/isdn/capi/kcapi.c 1.44 -> 1.45 # include/asm-alpha/semaphore.h 1.8 -> 1.9 # include/net/ipv6.h 1.25 -> 1.26 # drivers/block/xd.c 1.56 -> 1.57 # net/ipv4/netfilter/ip_nat_snmp_basic.c 1.10 -> 1.12 # arch/ppc/defconfig 1.22 -> 1.23 # drivers/char/busmouse.c 1.9 -> 1.11 # 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 # include/asm-ppc/io.h 1.13 -> 1.14 # 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 # sound/oss/Kconfig 1.11 -> 1.12 # 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/net/Makefile.lib 1.9 -> 1.10 # 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 # arch/arm/mm/proc-xscale.S 1.21 -> 1.22 # drivers/net/Kconfig 1.40 -> 1.45 # arch/ppc/boot/of1275/ofinit.c 1.1 -> 1.2 # drivers/isdn/sc/timer.c 1.3 -> 1.4 # 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 # drivers/isdn/sc/message.c 1.5 -> 1.6 # 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 # drivers/isdn/hardware/eicon/capifunc.c 1.5 -> 1.6 # net/ipv6/netfilter/Kconfig 1.2 -> 1.3 # drivers/usb/media/se401.h 1.5 -> 1.6 # fs/cifs/CHANGES 1.31 -> 1.36 # sound/oss/maestro.c 1.35 -> 1.36 # drivers/usb/serial/omninet.c 1.31 -> 1.32 # kernel/exit.c 1.111 -> 1.112 # arch/arm/mm/proc-arm922.S 1.16 -> 1.17 # drivers/ide/pci/cmd64x.c 1.11 -> 1.13 # drivers/isdn/hardware/avm/b1.c 1.22 -> 1.23 # 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) # arch/ppc/platforms/4xx/Makefile 1.7 -> 1.8 # 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 # arch/ppc/kernel/Makefile 1.38 -> 1.39 # 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 # drivers/input/serio/serport.c 1.12 -> 1.13 # arch/ppc/platforms/pmac_pic.c 1.18 -> 1.19 # arch/arm/kernel/Makefile 1.19 -> 1.20 # drivers/scsi/Kconfig 1.25 -> 1.30 # arch/sh/boards/cqreek/mach.c 1.1 -> 1.2 # net/ipv6/netfilter/ip6t_mac.c 1.5 -> 1.6 # include/linux/device.h 1.108 -> 1.109 # drivers/media/dvb/ttusb-dec/ttusb_dec.c 1.3 -> 1.4 # drivers/cdrom/cm206.c 1.35 -> 1.36 # net/ipv4/ipvs/ip_vs_ctl.c 1.3 -> 1.4 # drivers/macintosh/via-pmu.c 1.21 -> 1.25 # include/asm-arm/elf.h 1.6 -> 1.7 # drivers/media/video/stradis.c 1.15 -> 1.16 # drivers/isdn/hardware/avm/avmcard.h 1.16 -> 1.17 # 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.45 # net/ipv4/netfilter/ipt_conntrack.c 1.5 -> 1.6 # include/asm-ppc/mmu.h 1.6 -> 1.7 # include/asm-arm/cacheflush.h 1.2 -> 1.3 # 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.47 # 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 # include/asm-arm/proc-armv/locks.h 1.4 -> 1.6 include/asm-arm/locks.h (moved) # drivers/media/video/adv7170.c 1.2 -> 1.4 # drivers/cdrom/aztcd.c 1.31 -> 1.32 # include/asm-arm/memory.h 1.8 -> 1.9 # 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 # mm/rmap.c 1.29 -> 1.30 # 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 # net/ipv6/addrconf.c 1.63 -> 1.64 # 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/net/ppp_generic.c 1.38 -> 1.39 # net/core/Makefile 1.17 -> 1.18 # drivers/char/watchdog/wafer5823wdt.c 1.7 -> 1.11 # net/ipv4/icmp.c 1.34 -> 1.35 # drivers/isdn/hisax/diva.c 1.42 -> 1.43 # include/asm-arm/unistd.h 1.16 -> 1.17 # include/linux/netdevice.h 1.52 -> 1.56 # security/selinux/hooks.c 1.3 -> 1.6 # arch/ppc/kernel/setup.c 1.44 -> 1.45 # arch/ppc/kernel/smp.c 1.35 -> 1.36 # include/asm-arm/pgalloc.h 1.8 -> 1.9 # drivers/net/pcmcia/3c589_cs.c 1.21 -> 1.22 # arch/ia64/Kconfig 1.38 -> 1.40 # drivers/char/n_r3964.c 1.13 -> 1.14 # fs/compat_ioctl.c 1.4 -> 1.5 # include/asm-ppc/serial.h 1.10 -> 1.11 # 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 # include/linux/initrd.h 1.2 -> 1.3 # arch/arm/kernel/apm.c 1.2 -> 1.4 # drivers/isdn/capi/capilib.c 1.2 -> 1.3 # 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.48 # 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.46 # fs/cifs/misc.c 1.12 -> 1.13 # include/asm-h8300/h8max/timer_rate.h 1.1 -> (deleted) # drivers/scsi/scsi_ioctl.c 1.22 -> 1.24 # 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) # include/asm-arm/proc-armv/processor.h 1.7 -> (deleted) # drivers/isdn/Kconfig 1.2 -> 1.3 # drivers/block/cciss.c 1.86 -> 1.90 # include/asm-arm/proc-armv/assembler.h 1.2 -> (deleted) # drivers/isdn/sc/card.h 1.2 -> 1.3 # 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/net/hamradio/mkiss.c 1.12 -> 1.13 # 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.49 # arch/sparc64/kernel/pci_sabre.c 1.27 -> 1.28 # drivers/isdn/hisax/sedlbauer.c 1.36 -> 1.37 # 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.19 # drivers/usb/class/audio.c 1.40 -> 1.41 # net/wanrouter/af_wanpipe.c 1.28 -> 1.29 # drivers/serial/8250_acpi.c 1.1 -> 1.2 # 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 # include/scsi/scsi_request.h 1.4 -> 1.5 # arch/sh/boards/hp6xx/hp680/mach.c 1.2 -> 1.3 # drivers/scsi/sym53c8xx_2/sym_fw.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.36 # net/ipv4/ip_output.c 1.41 -> 1.42 # include/asm-sh/semaphore.h 1.6 -> 1.7 # include/asm-arm26/semaphore.h 1.1 -> 1.2 # 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 # drivers/ide/ide-default.c 1.1 -> 1.2 # net/ipv4/route.c 1.67 -> 1.69 # sound/oss/cs4281/cs4281m.c 1.25 -> 1.26 # drivers/scsi/imm.c 1.24 -> 1.25 # 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 # include/asm-sparc/semaphore.h 1.4 -> 1.5 # sound/oss/es1370.c 1.30 -> 1.31 # net/ipv6/netfilter/ip6t_multiport.c 1.3 -> 1.4 # include/asm-m68k/semaphore.h 1.4 -> 1.5 # scripts/kconfig/Makefile 1.8 -> 1.9 # drivers/block/scsi_ioctl.c 1.32 -> 1.33 # fs/jffs2/file.c 1.20 -> 1.22 # arch/ppc/mm/cachemap.c 1.8 -> 1.9 # drivers/acpi/Kconfig 1.19 -> 1.20 # arch/ppc/syslib/of_device.c 1.2 -> 1.4 # drivers/scsi/sym53c8xx_2/sym_glue.h 1.11 -> 1.13 # net/ipv4/netfilter/ipt_MIRROR.c 1.10 -> (deleted) # net/appletalk/ddp.c 1.26 -> 1.34 # net/core/profile.c 1.5 -> (deleted) # drivers/net/hamachi.c 1.29 -> 1.30 # fs/nfsd/nfs4proc.c 1.20 -> 1.21 # arch/arm/kernel/pm.c 1.4 -> 1.5 # include/linux/isdn.h 1.84 -> 1.85 # drivers/scsi/qla1280.c 1.44 -> 1.46 # 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/scsi/sym53c8xx_2/sym_misc.h 1.1 -> 1.2 # 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 # drivers/net/wan/sdla.c 1.12 -> 1.13 # drivers/isdn/icn/icn.c 1.15 -> 1.16 # arch/ppc/ocp/ocp-probe.c 1.1 -> 1.2 # arch/x86_64/kernel/smpboot.c 1.20 -> 1.21 # include/asm-arm/arch-iop3xx/iop321.h 1.3 -> 1.4 # net/sunrpc/stats.c 1.7 -> 1.8 # drivers/net/slip.c 1.20 -> 1.21 # 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.13 # security/selinux/selinuxfs.c 1.1 -> 1.2 # drivers/char/ip2main.c 1.40 -> 1.41 # drivers/s390/net/qeth.c 1.2 -> 1.3 # arch/arm/mm/Makefile 1.18 -> 1.19 # 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 # drivers/scsi/sym53c8xx_2/sym_glue.c 1.32 -> 1.36 # 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.1 arch/ppc/syslib/ibm440gp_common.h # (new) -> 1.3 arch/i386/kernel/time_hpet.c # (new) -> 1.1 arch/ppc/syslib/ibm440gp_common.c # (new) -> 1.1 drivers/char/watchdog/alim1535_wdt.c # (new) -> 1.1 arch/ppc/kernel/head_44x.S # (new) -> 1.1 include/linux/netfilter_ipv4/ipt_CLASSIFY.h # (new) -> 1.1 arch/ppc/boot/of1275/map.c # (new) -> 1.2 arch/ppc/configs/ebony_defconfig # (new) -> 1.1 arch/ppc/platforms/4xx/ibm440gp.h # (new) -> 1.1 include/asm-m68knommu/local.h # (new) -> 1.2 arch/ppc/platforms/4xx/ibm440gx.h # (new) -> 1.1 arch/ppc/syslib/ibm44x_common.c # (new) -> 1.2 arch/ppc/platforms/4xx/ocotea.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.3 include/asm-i386/hpet.h # (new) -> 1.1 net/bridge/netfilter/ebt_802_3.c # (new) -> 1.1 arch/ppc/platforms/4xx/ibm440gx.c # (new) -> 1.1 include/linux/netfilter_bridge/ebt_arpreply.h # (new) -> 1.1 arch/ppc/platforms/4xx/ibm440gp.c # (new) -> 1.1 arch/ppc/mm/44x_mmu.c # (new) -> 1.1 include/asm-m68knommu/sections.h # (new) -> 1.1 net/ipv4/netfilter/ipt_SAME.c # (new) -> 1.1 arch/ppc/platforms/4xx/ebony.h # (new) -> 1.2 arch/ppc/configs/ocotea_defconfig # (new) -> 1.1 arch/i386/kernel/timers/timer_hpet.c # (new) -> 1.1 include/linux/netfilter_ipv4/ipt_SAME.h # (new) -> 1.1 drivers/scsi/scsi_sysctl.c # (new) -> 1.1 Documentation/sysctl/abi.txt # (new) -> 1.1 arch/ppc/platforms/4xx/ocotea.c # (new) -> 1.1 include/asm-ppc/ibm44x.h # (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 arch/ppc/platforms/4xx/ebony.c # (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 ak@muc.de 1.1276.31.1 # [PATCH] IOMMU overflow handling fix for MPT fusion # # Currently mpt fusion does not handle IOMMU overflow (pci_map_sg returning 0) # very gracefully. It gets not reported to the upper layers. This patch fixes this. # # As a related note the fusion driver tends to trigger the NMI watchdog as soon # as it goes into any error recovery, because it busy waits for seconds with # interrupts disabled (seems to be still true with the new error handling in 2.6). # This is a big inconvenient because it leads to a forced oops. # # I tried to work around it by exporting touch_nmi_watchdog and using it in # the delays, but Linus was opposed to this approach. It would be nice # if someone could fix this. Afaik in 2.6 the error recovery should mostly # run in process context, so it should be possible to use schedule_timeout() # with interrupts on for the delays. # # At least on x86-64 the NMI watchdog runs by default and even on i386 it is a # very useful debugging tool. # -------------------------------------------- # 03/08/25 benh@kernel.crashing.org 1.1276.29.4 # some whitespace & tab fixes # -------------------------------------------- # 03/08/25 dougg@torque.net 1.1276.31.2 # [PATCH] GFDL issue in Documentation/DocBook/scsidrivers.tmpl # # [Switch GFDL to GPL] # -------------------------------------------- # 03/08/25 davidm@tiger.hpl.hp.com 1.1276.32.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 rddunlap@osdl.org 1.1276.31.3 # [PATCH] imm driver needs scsi_unregister() # # Same as the ppa driver, keeping them in sync. # # patch_name: scsi_imm_unreg.patch # patch_version: 2003-08-19.21:14:54 # author: Randy.Dunlap # description: scsi imm driver needs to call scsi_unregister(); # product: Linux # product_versions: 260-test3 # diffstat: = # drivers/scsi/imm.c | 1 + # 1 files changed, 1 insertion(+) # -------------------------------------------- # 03/08/25 randy.dunlap@verizon.net 1.1276.31.4 # [PATCH] advansys build with ADVANSYS_DEBUG defined # # This patch enables the advansys driver to build when # ADVANSYS_DEBUG is #defined. # # patch_name: scsi_advan_260t3.patch # patch_version: 2003-08-10.22:37:15 # author: Randy.Dunlap # description: enable compile with ADVANSYS_DEBUG #defined # product: Linux # product_versions: 260-test3 # URL: _ # maintainer: unknown # diffstat: = # drivers/scsi/advansys.c | 13 +++++++------ # 1 files changed, 6 insertions(+), 6 deletions(-) # -------------------------------------------- # 03/08/25 anton@samba.org 1.1276.31.5 # [PATCH] sym2 hotplug fix # # When testing sym2 hotplug I found a few places where we need to use # __devinit, not __init. # -------------------------------------------- # 03/08/25 lenehan@twibble.org 1.1276.31.6 # [PATCH] dc395x [1/6] - make functions static # # I forgot to make some of the new functions added during the list # cleanups static. This patch just declares those new functions static. # -------------------------------------------- # 03/08/25 lenehan@twibble.org 1.1276.31.7 # [PATCH] dc395x [2/6] - cleanup devices # # This cleans up the device management. It makes the init and cleanup # seperate functions that basically do the opposite type things in # reverse order. Makes it clear which functions remove a device and # which ones free a device (or devices.) # -------------------------------------------- # 03/08/25 lenehan@twibble.org 1.1276.31.8 # [PATCH] dc395x [3/6] - cleanup adapter init # # Cleanup of the adapter initialization sequence. Now it's clear what # is going on and what has been done at any point. It also keeps the # initialization of various things together and not spread out over a # bunch of different functions. This then made it possible to ensure # that appropriate the resources were correctly released in the event # of failure. # -------------------------------------------- # 03/08/25 lenehan@twibble.org 1.1276.31.9 # [PATCH] dc395x [4/6] - cleanup adapter uninit # # Clean up the initialization sequence for the adapter. Makes it easier # to follow. # -------------------------------------------- # 03/08/25 lenehan@twibble.org 1.1276.31.10 # [PATCH] dc395x [5/6] - check for device # # After searching for a device to free, only free it if it was found. # -------------------------------------------- # 03/08/25 lenehan@twibble.org 1.1276.31.11 # [PATCH] dc395x [6/6] - use pci resource len # # Instead of hard coding the number of io ports (to the wrong value no # less) use the pci_resource_length to determine the number. # -------------------------------------------- # 03/08/25 hch@lst.de 1.1276.31.12 # [PATCH] make scsi_priv.h includable standalone # -------------------------------------------- # 03/08/25 trini@kernel.crashing.org 1.1276.33.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.33.2 # PPC32: Fix KGDB and userland GDB interactions. # -------------------------------------------- # 03/08/25 rddunlap@osdl.org 1.1276.32.2 # [PATCH] ia64: fix printk type warning # # -------------------------------------------- # 03/08/25 willy@debian.org 1.1276.32.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.32.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.32.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.32.6 # ia64: Manual merge with Alex's "UP cmc/cpe polling fix" patch. # -------------------------------------------- # 03/08/25 willy@debian.org 1.1276.32.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 hch@lst.de 1.1276.31.13 # [PATCH] make scsi logging level a sysctl # # The logging level is now controlled by a # /proc/sys/dev/scsi/logging_level sysctl instead of /proc/scsi/scsi. # The format is the same as the logging_level module parameter. # -------------------------------------------- # 03/08/25 hch@lst.de 1.1276.31.14 # [PATCH] make /proc/scsi/scsi/ support optional # # There's no more essential functionality in it so allow the # embedded folks to configure it out. # -------------------------------------------- # 03/08/25 davidm@tiger.hpl.hp.com 1.1276.32.8 # ia64: Use offset_in_page() instead of equivalent open code. # -------------------------------------------- # 03/08/25 davidm@tiger.hpl.hp.com 1.1276.32.9 # ia64: Hook up fadvise64_64() system call. # -------------------------------------------- # 03/08/25 hch@lst.de 1.1276.31.15 # [PATCH] don't export proc_scsi # # proc_mkdir can also take absolute pathes, so we can avoid the export. # -------------------------------------------- # 03/08/25 davem@nuts.ninka.net 1.1276.26.27 # [NET]: net/core/ethtool.c needs asm/uaccess.h # -------------------------------------------- # 03/08/25 hch@lst.de 1.1276.31.16 # [PATCH] add a missing extern to scsi_priv.h # # scsi_scan_host_selected was the only prototype without 'extern' # -------------------------------------------- # 03/08/25 hch@lst.de 1.1276.31.17 # [PATCH] serialize bus scanning # # Synchronize all scanning activity, this fixes long-standing races # vs /proc/scsi/scsi and sysfs addition and deletion of devices. # # Note that this does not serialize removing, the lists will get # their own locking soon. # -------------------------------------------- # 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 hch@lst.de 1.1276.31.18 # [PATCH] fixup some tagged queuing mess # # This is a followup to Doug's comments and older work. It kills # sdev->tagged_queue which wasn't ever set in 2.5/2.6 except through # obscure and broken ioctls (!). As a reason of that tagged queing # didn't work for a lot of drivers, so this does change behaviour. # Be careful.. # # James, can you review the code in 53c700.c? Calling scsi_activate_tcq # in ->queuecommand rather than ->slave_configure looks rather strange to # me.. # -------------------------------------------- # 03/08/25 davem@nuts.ninka.net 1.1276.2.61 # [TG3]: Protect get/set TSO support with proper ifdefs. # -------------------------------------------- # 03/08/25 hch@lst.de 1.1276.31.19 # [PATCH] give scsi_allocate_request a gfp_mask # # most callers really want GFP_KERNEL, not GFP_ATOMIC. # -------------------------------------------- # 03/08/25 hch@lst.de 1.1276.31.20 # [PATCH] kill an unused variable in sym2 # -------------------------------------------- # 03/08/25 hch@lst.de 1.1276.31.21 # [PATCH] kill some dead code in sym2 # # No need to keep around the non-dma mapping code in 2.6 # -------------------------------------------- # 03/08/25 hch@lst.de 1.1276.31.22 # [PATCH] check whether a disk got writeable in sd_open # # This is the 2.5 version of a 2.4 patch posted to the list long # ago, the aacraid thread reminded me of it. # # The problem is that certain highend arrays allow to mark a r/o # volume writeable on the fly so we have to call check_disk_change # for write-protected devices in sd_open, too. # -------------------------------------------- # 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 andmike@us.ibm.com 1.1276.31.23 # [PATCH] fix Kernel Panic in scsi_host_dev_release # # If a driver calls scsi_register, but then has a problem in there # detect where they need to call scsi_unregister the parent pointer of # the struct device may never be set. # # drivers/scsi/hosts.c | 3 ++- # 1 files changed, 2 insertions(+), 1 deletion(-) # -------------------------------------------- # 03/08/26 bunk@fs.tum.de 1.1276.34.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.34.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.34.3 # [netdrvr 3c59x] ethtool_ops support # -------------------------------------------- # 03/08/26 jgarzik@redhat.com 1.1276.34.4 # [netdrvr sis900] ethtool_ops support # -------------------------------------------- # 03/08/26 jgarzik@redhat.com 1.1276.34.5 # [netdrvr 8139cp] ethtool_ops support # -------------------------------------------- # 03/08/26 jgarzik@redhat.com 1.1276.34.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.34.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.34.8 # [netdrvr 3c501] ethtool_ops support # -------------------------------------------- # 03/08/26 jgarzik@redhat.com 1.1276.34.9 # [netdrvr] ethtool_ops support in 3c503, 3c505, 3c507 # -------------------------------------------- # 03/08/26 jgarzik@redhat.com 1.1276.34.10 # [netdrvr] ethtool_ops support for 3c515, 3c523, 3c527, and dmfe # -------------------------------------------- # 03/08/26 jgarzik@redhat.com 1.1276.34.11 # [netdrvr pcmcia] ethtool_ops for 3c574, 3c589, axnet # -------------------------------------------- # 03/08/26 jgarzik@redhat.com 1.1276.34.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.32.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.34.13 # [netdrvr xircom_cb] ethtool_ops support # # Also, export PCI bus id via ETHTOOL_GDRVINFO. # -------------------------------------------- # 03/08/26 jgarzik@redhat.com 1.1276.34.14 # [wireless ray_cs] ethtool_ops support # -------------------------------------------- # 03/08/26 davidm@tiger.hpl.hp.com 1.1276.32.11 # ia64: Fix usage ("corrected" machine checks and platform errors, # not "correctable"). # -------------------------------------------- # 03/08/26 romieu@fr.zoreil.com 1.1276.34.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 jejb@raven.il.steeleye.com 1.1276.31.24 # Fix typo introduced into 53c700 by tag fixup patch # -------------------------------------------- # 03/08/26 jejb@raven.il.steeleye.com 1.1276.31.25 # Add extern for scsi_logging_level so scsi_sysctl.c can compile # -------------------------------------------- # 03/08/26 srompf@isg.de 1.1276.34.16 # [netdrvr 8139too] use mii_check_media lib function, # instead of homebrew MII bitbanging. # -------------------------------------------- # 03/08/26 hirofumi@mail.parknet.co.jp 1.1276.34.17 # [netdrvr 8139too] lwake unlock fix # -------------------------------------------- # 03/08/26 hirofumi@mail.parknet.co.jp 1.1276.34.18 # [netdrvr 8139too] remove unused RxConfigMask # -------------------------------------------- # 03/08/26 hirofumi@mail.parknet.co.jp 1.1276.34.19 # [netdrvr 8139too] add more h/w revision ids # -------------------------------------------- # 03/08/26 greg@kroah.com 1.1276.34.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.34.21 # [wireless airo] add support for MIC and latest firmwares # -------------------------------------------- # 03/08/26 jgarzik@redhat.com 1.1276.34.22 # [netdrvr sis190] small bug fixes # # * call pci_set_dma_mask # * remove erroneous call to unregister_netdev in _init_board() # -------------------------------------------- # 03/08/27 stevef@smfhome2.austin.rr.com 1.1276.35.1 # Fix scheduling while atomic problem in getting attributes of newly created file. Fix truncate of existing file when O_CREAT but not O_TRUNC specified. # -------------------------------------------- # 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.34.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.34.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.34.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 stevef@smfhome2.austin.rr.com 1.1276.35.2 # Fix oops in reconnection logic when no dentry for file being reconnected. # -------------------------------------------- # 03/08/29 stevef@smfhome2.austin.rr.com 1.1276.35.3 # Match smb pid to current->tgid # -------------------------------------------- # 03/08/29 stevef@smfhome2.austin.rr.com 1.1276.35.4 # update change log for 0.9.1 cifs vfs # -------------------------------------------- # 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.36.1 # [WATCHDOG] advantechwdt.c - patch # # small clean-up (add trivial comma) # -------------------------------------------- # 03/08/30 wim@iguana.be 1.1276.36.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.36.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.34.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.34.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.34.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.34.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.34.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.34.31 # [netdrvr 8139cp] fix NAPI bug; remove board_type distinction, not needed # -------------------------------------------- # 03/08/30 jgarzik@redhat.com 1.1276.34.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.34.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.34.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.34.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.34.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.34.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.34.38 # [netdrvr 3c509] dev->name removal build fix # -------------------------------------------- # 03/08/31 purna@jcom.home.ne.jp 1.1276.34.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.34.40 # [netdrvr 8139cp] must call NAPI-specific vlan hook # -------------------------------------------- # 03/08/31 jgarzik@redhat.com 1.1276.34.41 # [netdrvr ixgb] must call NAPI-specific vlan hook # -------------------------------------------- # 03/08/31 jgarzik@redhat.com 1.1276.34.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.34.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.37.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.36.4 # [WATCHDOG] wafer5823wdt.c - patch3 # # fix MODULE_PARM_DESC for timeout # add WDIOC_SETOPTIONS functionality # -------------------------------------------- # 03/08/31 wim@iguana.be 1.1276.36.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.36.6 # [WATCHDOG] alim1535_wdt.c # # Add "ALi M1535 PMU Watchdog Timer" driver # -------------------------------------------- # 03/08/31 B.Zolnierkiewicz@elka.pw.edu.pl 1.1276.37.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.37.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.37.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.37.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.37.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.37.7 # [PATCH] kill ide_modes.h # -------------------------------------------- # 03/08/31 B.Zolnierkiewicz@elka.pw.edu.pl 1.1276.37.8 # [PATCH] do not set drive->dn twice in probe_hwif() # -------------------------------------------- # 03/08/31 B.Zolnierkiewicz@elka.pw.edu.pl 1.1276.37.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.37.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.37.11 # [PATCH] remove unused ide_chipsets and IDE_CHIPSET_MODULE # -------------------------------------------- # 03/08/31 B.Zolnierkiewicz@elka.pw.edu.pl 1.1276.37.12 # [PATCH] kill ide_module_t # -------------------------------------------- # 03/08/31 B.Zolnierkiewicz@elka.pw.edu.pl 1.1276.37.13 # [PATCH] kill ide_register() # -------------------------------------------- # 03/08/31 jgarzik@redhat.com 1.1276.34.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.37.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.37.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.37.16 # [PATCH] sis190 driver fix # # synchronize_irq() requires an argument when built with CONFIG_SMP. # -------------------------------------------- # 03/08/31 ak@muc.de 1.1276.37.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.34.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.34.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.37.18 # [PATCH] cciss init problem # # This assigns the queue properly. # -------------------------------------------- # 03/08/31 willy@debian.org 1.1276.37.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.37.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.37.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.37.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.37.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.37.24 # [PATCH] Track nfsv4 open files by "struct inode" rather than dev/ino/generation # -------------------------------------------- # 03/08/31 neilb@cse.unsw.edu.au 1.1276.37.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.37.26 # [PATCH] use irqreturn_t in m68knommu/5206 config.c # -------------------------------------------- # 03/08/31 gerg@snapgear.com 1.1276.37.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.37.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.37.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.37.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.37.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.37.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.37.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.37.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.37.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.37.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.37.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.37.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.37.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.37.40 # [PATCH] dev_t handling cleanups (11/12) # # new helper - imajor(inode) # -------------------------------------------- # 03/08/31 viro@www.linux.org.uk 1.1276.37.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.36.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.37.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.37.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.37.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.37.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.37.46 # [PATCH] Amiga z2ram # # Amiga z2ram: Add missing includes and remove some unnecessary includes # -------------------------------------------- # 03/08/31 geert@linux-m68k.org 1.1276.37.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.37.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.37.49 # [PATCH] Atari floppy # # Atari floppy: Add missing includes and remove some unnecessary includes # -------------------------------------------- # 03/08/31 torvalds@home.osdl.org 1.1276.32.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.32.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.32.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.32.15 # [PATCH] h8300 interrupt problem fix # # typo fixed. # -------------------------------------------- # 03/08/31 ysato@users.sourceforge.jp 1.1276.32.16 # [PATCH] h8300 include update # # o driver support headers update # o fix warnings # -------------------------------------------- # 03/08/31 miles@lsi.nec.co.jp 1.1276.32.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.32.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 stevef@steveft21.ltcsamba 1.1276.35.5 # Return error correctly on revalidate so dentry will be dropped. # -------------------------------------------- # 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 cifs.adm@hostme.bitkeeper.com 1.1383.4.1 # Merge bk://linux.bkbits.net/linux-2.5 # into hostme.bitkeeper.com:/repos/c/cifs/linux-2.5cifs # -------------------------------------------- # 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.5.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 cifs.adm@hostme.bitkeeper.com 1.1396.1.19 # Merge bk://linux.bkbits.net/linux-2.5 # into hostme.bitkeeper.com:/repos/c/cifs/linux-2.5cifs # -------------------------------------------- # 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.4.1 # [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.4.2 # [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.4.3 # [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.4.4 # [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 cifs.adm@hostme.bitkeeper.com 1.1406.1.1 # Merge bk://linux.bkbits.net/linux-2.5 # into hostme.bitkeeper.com:/repos/c/cifs/linux-2.5cifs # -------------------------------------------- # 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.2.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 stevef@steveft21.ltcsamba 1.1406.1.2 # fix bad return code mapping when server lacks hard link support # -------------------------------------------- # 03/09/02 greg@kroah.com 1.1406.3.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.2.2 # [NET]: Convert af_netlink.c over to seq_file. # -------------------------------------------- # 03/09/02 shemminger@osdl.org 1.1406.2.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.2.4 # [NET]: Balance alloc_netdev() with free_netdev() in ethertap. # -------------------------------------------- # 03/09/02 davem@nuts.ninka.net 1.1406.2.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 # -------------------------------------------- # 03/09/02 cifs.adm@hostme.bitkeeper.com 1.1414 # Merge bk://linux.bkbits.net/linux-2.5 # into hostme.bitkeeper.com:/repos/c/cifs/linux-2.5cifs # -------------------------------------------- # 03/09/03 rmk@flint.arm.linux.org.uk 1.1396.5.1 # [ARM] Remove more 26-bit ARM support. # # Remove more of the redundant 26-bit ARM CPU support from the # 32-bit ARM tree. # -------------------------------------------- # 03/09/03 axboe@suse.de 1.1415 # [PATCH] amiflop error handling # # amiflop didn't init the queue before assigning it to disk->queue. the # error handling was also immensely screwed, I've cleaned that up too. # -------------------------------------------- # 03/09/03 paulus@samba.org 1.1413.1.1 # PPC32: Add support for the PPC 440 family of embedded processors. # # This has three main parts: (1) support for the 440GP and 440GX processors, # (2) support for the "Ebony" and "Ocotea" reference boards for those processors, # and (3) support for 64-bit physical addresses. The 440GP and 440GX are "Book E" # processors, and this introduces a CONFIG_BOOKE and some definitions that apply # to all Book E processors. # # Having 64-bit physical addresses means that PTEs are now 64 bits. The PTE pages # stay at 4kB, and the pgdir expands to 8kB. # -------------------------------------------- # 03/09/03 paulus@samba.org 1.1413.1.2 # PPC32: Eliminate one use of struct device name field. # -------------------------------------------- # 03/09/03 bunk@fs.tum.de 1.1416 # [wireless airo] fix build with gcc 2.95 # -------------------------------------------- # 03/09/03 torvalds@home.osdl.org 1.1415.1.1 # Merge bk://ppc.bkbits.net/for-linus-ppc # into home.osdl.org:/home/torvalds/v2.5/linux # -------------------------------------------- # 03/09/03 B.Zolnierkiewicz@elka.pw.edu.pl 1.1415.1.2 # [PATCH] ide: allow LBA48 on Promise 20265 # # It was disabled to workaround a bug in a driver. The orginal bug was # fixed but the workaround was not removed. # -------------------------------------------- # 03/09/03 B.Zolnierkiewicz@elka.pw.edu.pl 1.1415.1.3 # [PATCH] ide: add very basic support for VIA 8237 SATA controller # # From Daniela Engert . # -------------------------------------------- # 03/09/03 B.Zolnierkiewicz@elka.pw.edu.pl 1.1415.1.4 # [PATCH] ide: enable LED support for PowerMac # # From Benjamin Herrenschmidt : # # This adds the Kconfig option for the PowerMac IDE driver "LED" feature # (using the laptop's front LED as a disk activity indicator). It also # adds a small bit to ide-probe.c that was missing from Jens patch when he # added the activity function infrastructure. He did add the hwif field, # but not the code to actually enable it. # -------------------------------------------- # 03/09/03 benh@kernel.crashing.org 1.1415.1.5 # [PATCH] PowerMac: Fix build of via-pmu driver with some .config's # # This fixes the build of the via-pmu.c driver when CONFIG_PMAC_PBOOK is # not set. # -------------------------------------------- # 03/09/03 rmk@flint.arm.linux.org.uk 1.1396.5.2 # [ARM] Remove more reminants of 26-bit ARM support. # # This removes include/asm-arm/proc-armv entirely, merging the # contents into the relevant include files in include/asm-arm. # We also update various files in arch/arm which reference # definitions in the now non-existent directory. # -------------------------------------------- # 03/09/03 mzyngier@freesurf.fr 1.1417 # [netdrvr de4x5] big modernization / cleanup # # The enclosed patch tries to clean the tulip de4x5 driver, and update # it to some of the 2.6 APIs : # # - Use PCI and EISA probing APIs # - Use generic DMA API # - Fix DE425 init on the Jensen # - Remove de4x5 from Space.c # # It's been tested on x86 and Alpha, with a DE425 (21040, EISA), a DE435 # (21040, PCI) and a quad DLink (4*21143, PCI). # # The major problem with this patch is that, because of the Space.c # removal, interfaces get potentially renumbered. This has been # discussed to death on lkml, without any obvious solution. IMHO, we'd # better remove as many drivers as we can from Space.c before # 2.6.0-final ships... # -------------------------------------------- # 03/09/03 ernstp@mac.com 1.1418 # [netdrvr] list CONFIG_BMAC in drivers/net/Makefile.lib, # as it uses the crc32 library. # -------------------------------------------- # 03/09/03 bunk@fs.tum.de 1.1415.1.6 # [PATCH] COSA is no longer BROKEN # # the compilation of cosa.c was already fixed in your BK tree, so we can # now remove the dependency on BROKEN. # -------------------------------------------- # 03/09/03 torvalds@home.osdl.org 1.1415.1.7 # Avoid a negative in config questions: we don't want to have users # forced into double negatives. # -------------------------------------------- # 03/09/03 javier@tudela.mad.ttd.net 1.1419 # [wireless airo] build fix when MIC support is disabled # -------------------------------------------- # 03/09/03 torvalds@home.osdl.org 1.1420 # Merge bk://kernel.bkbits.net/jgarzik/net-drivers-2.5 # into home.osdl.org:/home/torvalds/v2.5/linux # -------------------------------------------- # 03/09/03 wim@iguana.be 1.1276.36.8 # [WATCHDOG] wafer5823wdt.c - patch4 # # remove module_param's for wdt_start and wdt_stop # fix timeout check in init procedure # -------------------------------------------- # 03/09/03 wim@iguana.be 1.1415.2.1 # Merge http://linux-watchdog.bkbits.net/linux-2.5-watchdog # into iguana.be:/home/wim/BitKeeper/projects/linux-2.5-watchdog # -------------------------------------------- # 03/09/03 wim@iguana.be 1.1421 # Merge http://linux-watchdog.bkbits.net/linux-2.5-watchdog # into iguana.be:/home/wim/BitKeeper/projects/linux-2.5-watchdog # -------------------------------------------- # 03/09/03 jejb@raven.il.steeleye.com 1.1420.1.1 # Merge hch/akpm changes # -------------------------------------------- # 03/09/03 rddunlap@osdl.org 1.1420.1.2 # [PATCH] label needs statement following it # # patch_name: cpqfc_labelend.patch # patch_version: 2003-08-27.18:19:34 # author: Randy.Dunlap # description: cpqfc: label needs a (empty) statement after it; # product: Linux # product_versions: 260-test4 # maintainer: support@compaq.com # -------------------------------------------- # 03/09/03 hch@lst.de 1.1420.1.3 # [PATCH] fix the scsi_logging_level fix # # We already had a prototype for it, it just was conditional on # CONFIG_SCSI_LOGGING.. # -------------------------------------------- # 03/09/03 david_jeffery@adaptec.com 1.1420.1.4 # [PATCH] ips: remove arch limitations # # This patch removes the X86 arch limitation in drivers/scsi/Kconfig, # downgrades the #error check for x86/x86_64/ia64 to a #warning, and # updates an old email address in the help. # # It also fixes up a two places in the driver which have 8 spaces instead # of a tab for indention. # -------------------------------------------- # 03/09/03 willy@debian.org 1.1420.1.5 # [PATCH] ncr & sym1 patches # # Some misc sym1 and ncr driver changes. # # Changelog: # - Kconfig: Delete sym1 driver from Kconfig # - Kconfig: Delete SCSI_NCR53C8XX_IOMAPPED, SCSI_NCR53C8XX_PQS_PDS # and SCSI_NCR53C8XX_SYMBIOS_COMPAT options. # - ncr53c8xx: Delete SCSI_NCR53C8XX_SYMBIOS_COMPAT option # -------------------------------------------- # 03/09/03 willy@debian.org 1.1420.2.1 # [PATCH] sym2 patchset # # A big pile of sym2-related changes. I have most of them split apart in # CVS, so I can submit them as individual patches if anyone's interested. # # Changelog: # - Use pci_set_mwi() instead of trying to do it ourselves. # - Rename PCI_ID_LSI53C1010 to 1010_33 and PCI_ID_LSI53C1010_2 to 1010_66. # - Turn sym_udelay and sym_mdelay into macros. # - Move the definition of sym53c8xx_lock near the functions that call it # and remove the macros that wrapper it. # - SYM_LINUX_DYNAMIC_DMA_MAPPING is always defined. (Christoph Hellwig) # - Remove first_host (Christoph Hellwig) # - Support for hp C3000 (Grant Grundler) # - Switch to using pci_name() # - Remove the #if 0'd code from the pci_driver conversion. # - Remove the sym_chip typedef. # - Remove the pcifix option. # - Remove a redundant printk on driver initialisation. # - Use rmb() for __READ_BARRIER and wmb() for __WRITE_BARRIER # - Increment the version to 2.1.17a. # -------------------------------------------- # 03/09/03 jejb@raven.il.steeleye.com 1.1420.1.6 # Merge willy/hch fixes # -------------------------------------------- # 03/09/03 kkeil@suse.de 1.1422 # [PATCH] ISDN bugfixes part 1 # # Here is the first part of ISDN bugfixes for 2.6. # It should make ISDN work again with most controllers. # # More fixes follow after more testing. # -------------------------------------------- # 03/09/03 torvalds@home.osdl.org 1.1423 # Merge bk://bk.arm.linux.org.uk/linux-2.6-rmk # into home.osdl.org:/home/torvalds/v2.5/linux # -------------------------------------------- # 03/09/03 jejb@raven.il.steeleye.com 1.1420.1.7 # Fix up scsi_alloc_request in sr.c to take a GFP_ flag # -------------------------------------------- # 03/09/04 akpm@osdl.org 1.1421.1.1 # [NET]: Fix 64-bit warnings in af_netlink.c # -------------------------------------------- # 03/09/04 janitor@sternwelten.at 1.1421.1.2 # [NET]: Use list_for_each() where applicable. # -------------------------------------------- # 03/09/04 felipewd@terra.com.br 1.1421.1.3 # [IPV6]: Remove unnecessary linux/version.h include. # -------------------------------------------- # 03/09/04 jgarzik@pobox.com 1.1421.1.4 # [NET]: Fix ethtool_ops thinko in sungem.c # -------------------------------------------- # 03/09/04 chas@nrl.navy.mil 1.1421.1.5 # [ATM]: In atm_getaddr() do not copy_to_user() with locks held. # -------------------------------------------- # 03/09/04 mitch@sfgoth.com 1.1421.1.6 # [ATM]: Lanai driver updates. # # o Big performance improvement. The version of the driver in the kernel # still had a "mdelay(1)" after every register write. This capped # performance at about 8Mbps and ate tons of CPU time. (Luckily, most # users of this card are just terminating a DSL line where its not too # noticeable) # # However, after removing this delay the card started getting out of # sync with the driver under stress tests. After a couple days of chasing # the bug I finally determine that the card's support for transmitting # partial PDUs just doesn't quite work as advertised (before we would send # a partial PDU to completely fill a VCC's transmit buffer and then send # the rest of the skb when more buffer space filled up). The usefulness of # this is somewhat doubtful anyway and removing it cleaned up a lot of code. # # I also added some memory barriers to make sure operations to the card # happen in the correct order. # # Now for the first time ever we get near line-rate performance out of this # card (~19Mb/s TCP in netperf between two ~300Mhz machines) # # o Locking changes (essentially the patch Chas sent me a couple weeks ago # with some minor tweaking) I'm still not sure we're getting 100% of the # cases right but it's definitely FAR better than the old lock-less version. # # o Cleanup the backlog draining code in lanai_shutdown_tx_vci() # # o Remove outdated comment describing how to compile the module # # o Got rid of the "service_novcc_[tr]x" stats - it's really the same error # as "service_[tr]x" - there's no reason to count them separately. # # o Use the ATM_25_PCR constant instead of computing it for ourselves # -------------------------------------------- # 03/09/04 shemminger@osdl.org 1.1421.1.7 # [NET]: DLCI driver cleanups for 2.6.x # # - keep list of arrays for devices and use a lock # - make sure header is contiguous before overlaying data structure # - dynamically allocate dev->priv with alloc_netdev # - get rid of MOD_INC/DEC # - free devices on module unload # - keep refcount on slave device's since holding a ptr # -------------------------------------------- # 03/09/04 romieu@fr.zoreil.com 1.1421.1.8 # [NET]: Use free_netdev() even in error paths. # -------------------------------------------- # 03/09/04 shemminger@osdl.org 1.1421.1.9 # [NET]: Add probe_old_netdevs() hook. # # This set of patches is a mixture of Al's work to device initialization, # and some of my own to complete it for all the ether, tr, sbni, and loopback # devices. # # The first patch adds the hook for converting old driver initialization # code over to dynamic allocation. # # This part extracted from Al viro's set of net driver changes for ethertap. # -------------------------------------------- # 03/09/04 shemminger@osdl.org 1.1421.1.10 # [NET]: Convert SDLA to new initialization. # # Based on Al viro's NE10-sdla # * switched sdla to dynamic allocation # * sdla: embedded ->priv # * sdla: fixed resource leaks on failure exits # Additionally fixes. # * get rid of cli/sti # * get rid of MOD/INC # # Builds and probes, but don't have the hardware. # Driver has never built on 2.6 before this. # -------------------------------------------- # 03/09/04 shemminger@osdl.org 1.1421.1.11 # [NET]: Convert cops over to new initialization. # # More from Al # NE12-cops # * switched cops to dynamic allocation # * cops: embedded ->priv # * cops: fixed ->irq clobbering on autoprobe # Added # * free_netdev # -------------------------------------------- # 03/09/04 shemminger@osdl.org 1.1421.1.12 # [NET]: Convert ether probes to probe_old_netdevs(). # # Convert old ethernet device probing from dev_base linked list # to the probe_old_netdevs. # # Blame me for this one ;-) # # Builds and runs, but don't have old ISA hardware to really test it. # So please find some or review it carefully. # -------------------------------------------- # 03/09/04 shemminger@osdl.org 1.1421.1.13 # [NET]: Convert tr probes to probe_old_netdevs(). # # Analogous to previous patch. Instead of dev_base list of static # entries, use a loop and dynamically allocate devices. # # Tested only the 'no hardware' case. # -------------------------------------------- # 03/09/04 shemminger@osdl.org 1.1421.1.14 # [NET]: Convert sbni initialization. # # Convert sbni driver # - new probing # - single allocation using alloc_netdev for private data # -------------------------------------------- # 03/09/04 shemminger@osdl.org 1.1421.1.15 # [NET]: Loopback device simplification. # # Now that all the magic chain of static devices is gone from Space.c # The initialization of the one remaining static device (ie the loopback driver) # can be simplified. # # One small change was to reduce possibility of failing the initialization if # allocation of private data failed by just going without statistics. # -------------------------------------------- # 03/09/04 shemminger@osdl.org 1.1421.1.16 # [NET]: Convert ltpc to new initialization. # # Originally from Al Viro # NE11-ltpc # * switched ltpc to dynamic allocation # * ltpc: embedded ->priv # * ltpc: fixed bugs in DMA allocation # * ltpc: fixed resource leaks on failure exits # * ltpc: fixed part of timer bugs (still a-f**ing-plenty of those) # * ltpc: fixed order of freeing bugs # Added # * switch to free_netdev # -------------------------------------------- # 03/09/04 rddunlap@osdl.org 1.1421.1.17 # [NET]: remove duplicate #includes in net/ # -------------------------------------------- # 03/09/04 rddunlap@osdl.org 1.1421.1.18 # [CRYPTO]: remove duplicate #includes in crypto/ # -------------------------------------------- # 03/09/04 davem@nuts.ninka.net 1.1421.1.19 # [NET]: Kill NET_PROFILE, has not built for years. # -------------------------------------------- # 03/09/04 yoshfuji@linux-ipv6.org 1.1421.1.20 # [IPV{4,6}]: Fixing a bug that reading /proc/net/{udp,udp6} may drop some data. # -------------------------------------------- # 03/09/04 akpm@osdl.org 1.1424 # [PATCH] misc fixes # # - non_fatal.c comment fix (Zwane Mwaikambo ) # # - s/elevator/io scheduler/ in ll_rw_blk.c (Jens) # # - update KJ mailing list address ("Randy.Dunlap" ) # # - unused var in riscom8.c (Adrian Bunk ) # # - add help texts to two OSS drivers (Adrian Bunk ) # # - "PCMCIA SCSI adapter support" requires CONFIG_MODULES (Adrian Bunk # ) # -------------------------------------------- # 03/09/04 akpm@osdl.org 1.1425 # [PATCH] Fix odd code in bio_add_page # # From: Neil Brown # # With the current code in bio_add_page, if fail_segments is ever set, it # stays set, so bio_add_page will eventually fail having recounted the # segmentation once. # # I don't think this is intended. This patch changes the code to allow # success if the recounting the segments helps. # # (Jens has acked this) # -------------------------------------------- # 03/09/04 akpm@osdl.org 1.1426 # [PATCH] convert /proc/stat to seq_file # # From: "Randy.Dunlap" # # Anton needs this for ppc64. Things overflow with a huge number of CPUs. # -------------------------------------------- # 03/09/04 akpm@osdl.org 1.1427 # [PATCH] Fix rtc symbol clash and HPET config problems # # The new HPET RTC emulation code uses a function in rtc.c, get_rtc_time(). # # So that function was made non-static. Problem is, the same function name is # used elsewhere by some architectures, so there will be linkage problems. # # And rtc_get_time() is used too, so I renamed it to rtc_get_rtc_time(). # # Also, the HPET code was setting CONFIG_HPET_EMULATE_RTC by hand in a header # file. Fix it to use the Kconfig system properly. # -------------------------------------------- # 03/09/04 akpm@osdl.org 1.1428 # [PATCH] add config option for qla1280 SCSI MMIO/ioport # # From: Andrey Panin # # Add a config option which allows ioport/mmio selection for QLA1280 SCSI # driver. # # With this patch applied QLA1280 can be used on Visws again. # -------------------------------------------- # 03/09/04 akpm@osdl.org 1.1429 # [PATCH] elevator insertion fixes # # From: Nick Piggin # # This fixes a bug in deadline and AS that causes insert_here to be ignored on # blk_fs_requests. This has been causing problems with SCSI requeueing code. # It makes elevator insertion more correct as advertised wrt insert_here and # REQ_SOFTBARRIER. # # It also fixes a buglet in the as_requeue code where the request wasn't being # put into the front of the list (in rare cases). # -------------------------------------------- # 03/09/04 akpm@osdl.org 1.1430 # [PATCH] 8250_acpi taints kernel # # From: Dmitry Torokhov # # 8250_acpi module does not have MODULE_LICENSE specified. 8250_gsc does not # have it either but as I can't compile it I did not touch it. # -------------------------------------------- # 03/09/04 akpm@osdl.org 1.1431 # [PATCH] proc_misc.c needs irq.h # # fs/proc/proc_misc.c: In function `show_stat': # fs/proc/proc_misc.c:423: `irq_desc' undeclared (first use in this function) # -------------------------------------------- # 03/09/04 akpm@osdl.org 1.1432 # [PATCH] more slab page checking # # Add checks for kfree() of a page which was allocated with __alloc_pages(), # and for free_pages() of a page which was allocated with kmalloc(). # -------------------------------------------- # 03/09/04 akpm@osdl.org 1.1433 # [PATCH] might_sleep() improvements # # From: Mitchell Blank Jr # # This patch makes the following improvements to might_sleep(): # # o Add a "might_sleep_if()" macro for when we might sleep only if some # condition is met. It's a bit tidier, and has an unlikely() in it. # # o Add might_sleep checks to skb_share_check() and skb_unshare() which # sometimes need to allocate memory. # # o Make all architectures call might_sleep() in both down() and # down_interruptible(). Before only ppc, ppc64, and i386 did this check. # (sh did the check on down() but not down_interruptible()) # -------------------------------------------- # 03/09/04 akpm@osdl.org 1.1434 # [PATCH] MODULE_ALIAS() in block devices # # From: Rusty Russell # # 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/04 akpm@osdl.org 1.1435 # [PATCH] MODULE_ALIAS() in char devices # # From: Rusty Russell # # 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/04 akpm@osdl.org 1.1436 # [PATCH] Remove percpufication of in_flight counter in # # From: Ravikiran G Thirumalai # # The routine disk_round_stats showed up considerably under oprofile for high # disk io load (four processes doing dd to the same disk (different # partitions) on a 4 way). # # This is because the counter in_flight which is per-cpu right now gets read # every time disk_round_stats gets called. Per cpu counters like disk # statistics improve write speed, but reads are slow (since all cpus' local # counter values have to be read and summed up). Considering the fact that # in_flight counter is modified post disk_round_stats (which reads the # in_flight counter) it is better not to per-cpu this counter. # # Following patch does just that. Below is the profile comparison before and # after the change. This was on a 4 way PIII Xeon, 1G ram, 2.6.0-test4-mm2. # # Before: # c010aa60 2910109 92.2249 poll_idle # c0275340 23208 0.73549 __copy_to_user_ll # c02753b0 11191 0.354657 __copy_from_user_ll # c0114aa0 7168 0.227163 mark_offset_tsc # c011ad10 6767 0.214455 schedule # c011a2b0 6741 0.213631 load_balance # c0138890 6710 0.212648 __generic_file_aio_write_nolock # c011d302 4683 0.14841 .text.lock.sched # c02e4b50 4533 0.143656 ahc_linux_isr # c029cec0 3582 0.113518 disk_round_stats # c0119b40 3509 0.111205 try_to_wake_up # c029d320 3306 0.104771 __make_request # c01567d0 3300 0.104581 __block_write_full_page # c0156c00 3299 0.104549 __block_prepare_write # # After: # c010aa60 2777940 92.1302 poll_idle # c0275340 23479 0.778679 __copy_to_user_ll # c02753b0 10943 0.362924 __copy_from_user_ll # c0114aa0 7022 0.232884 mark_offset_tsc # c0138890 6988 0.231757 __generic_file_aio_write_nolock # c011ad10 6607 0.219121 schedule # c011d302 5771 0.191395 .text.lock.sched # c02e4a60 4458 0.147849 ahc_linux_isr # c011a2b0 3921 0.13004 load_balance # c01567d0 3569 0.118366 __block_write_full_page # c029d2a0 3540 0.117404 __make_request # ... # c029ceb0 311 0.0103143 disk_round_stats # c011d5b0 299 0.00991631 remove_wait_queue # -------------------------------------------- # 03/09/04 akpm@osdl.org 1.1437 # [PATCH] Enable SELinux via boot parameter # # From: James Morris # # This patch adds an 'selinux' boot parameter which must be used to actually # enable SELinux. # # It follows some internal discussion about deployment issues, where a vendor # would want to ship a single kernel image with SELinux built-in, without # requiring the user to use it. # # Without specifying selinux=1 as a boot parameter, SELinux will not register # with LSM and selinuxfs will not be registered as a filesystem. This causes # SELinux to be bypassed entirely from then on, and no performance overhead # is imposed. Other security modules may then also be loaded if needed. # -------------------------------------------- # 03/09/04 akpm@osdl.org 1.1438 # [PATCH] devfs pty fix # # From: Andrew Lunn # # Create the pty slaves on init so the behaviour is consistant with 2.4 and 2.6 # without devfs. # -------------------------------------------- # 03/09/04 akpm@osdl.org 1.1439 # [PATCH] i8042 free_irq() aliasing fix # # The same address `i8042_request_irq_cookie' is used in three places for the # i8042 request_irq() argument. This means that if someone calls # i8042_check_mux() or i8042_check_aux() while the IRQ is in use, the # free_irq() call in there will free the wrong IRQ handler. # # So give all three instances of request_irq() in i8042.c a distinct address by # which to identify the IRQ instance. # # (This is probably a non-bug, because the `check' functions are not called # when the device is open, but it is better this way). # -------------------------------------------- # 03/09/04 akpm@osdl.org 1.1440 # [PATCH] Remove Documentation/kmod.txt # # From: Rusty Russell # # Please delete Documentation/kmod.txt: it's entirely outdated and misleading. # # I thought about rewriting it, but there's not much to add beyond what's in # the CONFIG_KMOD's help text. # -------------------------------------------- # 03/09/04 akpm@osdl.org 1.1441 # [PATCH] drivers/scsi/imm.c build fix # -------------------------------------------- # 03/09/04 akpm@osdl.org 1.1442 # [PATCH] hermes.h fails with outw_p() in :? # # From: Michael Pruznick # # build errors: # hermes.h: In function `hermes_set_irqmask': # hermes.h:337: parse error before "do" # hermes.h:337: parse error before ';' token # hermes.h: In function `hermes_write_words': # # In mips, outw_p() is a #define do...while(0) which, in the case of ?:, # results in a statement being used where an expression is required. # -------------------------------------------- # 03/09/04 akpm@osdl.org 1.1443 # [PATCH] cciss error handling cleanup # # From: mike.miller@hp.com # # Clean up the error handling in cciss_init_one(). # -------------------------------------------- # 03/09/04 akpm@osdl.org 1.1444 # [PATCH] MODULE_ALIAS for tty ldisc # # From: Rusty Russell # # Rather than hardcoded names in modprobe, modules can offer their own # aliases (which can be overridden by the config file). # # Here are the tty-ldisc ones. # -------------------------------------------- # 03/09/04 laforge@netfilter.org 1.1421.1.21 # [NETFILTER]: NAT range calculation fix. # # This patch fixes a logic bug in NAT range calculations, which also # causes a large slowdown when ICMP floods go through NAT. # # Author: Karlis Peisenieks # -------------------------------------------- # 03/09/04 davem@nuts.ninka.net 1.1445 # [USB]: hiddev_exit() can no longer be __exit, called from init code now. # -------------------------------------------- # 03/09/04 davem@nuts.ninka.net 1.1446 # [SPARC]: Add MODULE_ALIAS_LDISC() defines. # -------------------------------------------- # 03/09/04 davem@kernel.bkbits.net 1.1444.1.1 # Merge nuts.ninka.net:/disk1/davem/BK/net-2.5 # into kernel.bkbits.net:/home/davem/net-2.5 # -------------------------------------------- # 03/09/04 torvalds@home.osdl.org 1.1447 # Merge bk://kernel.bkbits.net/davem/net-2.5 # into home.osdl.org:/home/torvalds/v2.5/linux # -------------------------------------------- # 03/09/04 rmk@arm.linux.org.uk 1.1448 # [PATCH] Don't #ifdef prototypes # # It seems that changing CONFIG_BLK_DEV_INITRD causes the whole kernel to # rebuild due to an inappropriate ifdef in linux/fs.h - we should not # conditionalise prototypes. # # In addition, real_root_dev is only used by two files (kernel/sysctl.c # and init/do_mounts_initrd.c) so it makes even less sense that it was in # linux/fs.h # -------------------------------------------- # 03/09/04 jejb@raven.il.steeleye.com 1.1447.1.1 # Merge raven.il.steeleye.com:/home/jejb/BK/scsi-misc-2.5 # into raven.il.steeleye.com:/home/jejb/BK/scsi-for-linus-2.6 # -------------------------------------------- # 03/09/04 akpm@osdl.org 1.1449 # [PATCH] fix /proc/stat handler for ARM, SPARC64, others.. # # Some references to irq_stat[] snuck into generic code. It doesn't work on # several architectures. # # So revert that little improvement to the original version. # -------------------------------------------- # 03/09/04 torvalds@home.osdl.org 1.1450 # Merge bk://linux-scsi.bkbits.net/scsi-for-linus-2.6 # into home.osdl.org:/home/torvalds/v2.5/linux # -------------------------------------------- # 03/09/04 B.Zolnierkiewicz@elka.pw.edu.pl 1.1451 # [PATCH] ide: fix PM with ide-default driver # # From Benjamin Herrenschmidt # -------------------------------------------- # 03/09/04 B.Zolnierkiewicz@elka.pw.edu.pl 1.1452 # [PATCH] ide: remove supports_dma field from ide_driver_t # # driver->supports_dma was used together with CONFIG_IDEDMA_ONLYDISK to limit # DMA access to disk devices only. However Alan introduced new scheme in 2.5.63 # and this field is not needed any longer because all ide drivers support DMA. # -------------------------------------------- # 03/09/04 James.Bottomley@SteelEye.com 1.1453 # [PATCH] fix remap of shared read only mappings # # When mmap MAP_SHARED is done on a file, it gets marked with VM_MAYSHARE # and, if it's read/write, VM_SHARED. However, if it is remapped with # mremap(), the MAP_SHARED is only passed into the new mapping based on # VM_SHARED. This means that remapped read only MAP_SHARED mappings lose # VM_MAYSHARE. This is causing us a problem on parisc because we have to # align all shared mappings carefully to mitigate cache aliasing problems. # # The fix is to key passing the MAP_SHARED flag back into the remapped are # off VM_MAYSHARE not VM_SHARED. # -------------------------------------------- # 03/09/04 shemminger@osdl.org 1.1454 # [PATCH] ikconfig - cleanups # # Cleanup ikconfig # - use single_open for built_with file. # - get rid of unneeded globals # - use copy_to_user instead of char at a time # - only need the read routine, proc defaults to correct behaviour # for the rest. # -------------------------------------------- # 03/09/04 akpm@osdl.org 1.1455 # [PATCH] Fix /proc/stat off-by-one # # I should have stayed in bed. # -------------------------------------------- # diff -Nru a/CREDITS b/CREDITS --- a/CREDITS Thu Sep 4 15:38:40 2003 +++ b/CREDITS Thu Sep 4 15:38:40 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 Thu Sep 4 15:38:32 2003 +++ b/Documentation/DocBook/kernel-locking.tmpl Thu Sep 4 15:38:32 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/scsidrivers.tmpl b/Documentation/DocBook/scsidrivers.tmpl --- a/Documentation/DocBook/scsidrivers.tmpl Thu Sep 4 15:38:28 2003 +++ b/Documentation/DocBook/scsidrivers.tmpl Thu Sep 4 15:38:28 2003 @@ -16,20 +16,40 @@ - 2002-04-27 + 2003-08-11 2002 + 2003 Douglas Gilbert + - Permission is granted to copy, distribute and/or modify this - document under the terms of the GNU Free Documentation License, - Version 1.1 or any later version published by the Free Software - Foundation; with no Invariant Sections, with no Front-Cover Texts, - and with no Back-Cover Texts. A copy of the license is included - in the section entitled "GNU Free Documentation License". + This documentation 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 + + + + For more details see the file COPYING in the source + distribution of Linux. diff -Nru a/Documentation/DocBook/writing_usb_driver.tmpl b/Documentation/DocBook/writing_usb_driver.tmpl --- a/Documentation/DocBook/writing_usb_driver.tmpl Thu Sep 4 15:38:33 2003 +++ b/Documentation/DocBook/writing_usb_driver.tmpl Thu Sep 4 15:38:33 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 Thu Sep 4 15:38:31 2003 +++ b/Documentation/filesystems/proc.txt Thu Sep 4 15:38:31 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 Thu Sep 4 15:38:39 2003 +++ b/Documentation/ide.txt Thu Sep 4 15:38:39 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 Thu Sep 4 15:38:48 2003 +++ b/Documentation/kernel-parameters.txt Thu Sep 4 15:38:48 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/kmod.txt b/Documentation/kmod.txt --- a/Documentation/kmod.txt Thu Sep 4 15:38:32 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,68 +0,0 @@ -Kmod: The Kernel Module Loader -Kirk Petersen - -Kmod is a simple replacement for kerneld. It consists of a -request_module() replacement and a kernel thread called kmod. When the -kernel requests a module, the kmod wakes up and execve()s modprobe, -passing it the name that was requested. - -If you have the /proc filesystem mounted, you can set the path of -modprobe (where the kernel looks for it) by doing: - - echo "/sbin/modprobe" > /proc/sys/kernel/modprobe - -To periodically unload unused modules, put something like the following -in root's crontab entry: - - 0-59/5 * * * * /sbin/rmmod -a - -Kmod only loads modules. Kerneld could do more (although -nothing in the standard kernel used its other features). If you -require features such as request_route, we suggest that you take -a similar approach. A simple request_route function could be called, -and a kroute kernel thread could be sent off to do the work. But -we should probably keep this to a minimum. - -Kerneld also had a mechanism for storing device driver settings. This -can easily be done with modprobe. When a module is unloaded, modprobe -could look at a per-driver-configurable location (/proc/sys/drivers/blah) -for device driver settings and save them to a file. When a module -is loaded, simply cat that file back to that location in the proc -filesystem. Or perhaps a script could be a setting in /etc/modules.conf. -There are many user-land methods that will work (I prefer using /proc, -myself). - -If kerneld worked, why replace it? - -- kerneld used SysV IPC, which can now be made into a module. Besides, - SysV IPC is ugly and should therefore be avoided (well, certainly for - kernel level stuff) - -- both kmod and kerneld end up doing the same thing (calling modprobe), - so why not skip the middle man? - -- removing kerneld related stuff from ipc/msg.c made it 40% smaller - -- kmod reports errors through the normal kernel mechanisms, which avoids - the chicken and egg problem of kerneld and modular Unix domain sockets - - -Keith Owens December 1999 - -The combination of kmod and modprobe can loop, especially if modprobe uses a -system call that requires a module. If modules.dep does not exist and modprobe -was started with the -s option (kmod does this), modprobe tries to syslog() a -message. syslog() needs Unix sockets, if Unix sockets are modular then kmod -runs "modprobe -s net-pf-1". This runs a second copy of modprobe which -complains that modules.dep does not exist, tries to use syslog() and starts yet -another copy of modprobe. This is not the only possible kmod/modprobe loop, -just the most common. - -To detect loops caused by "modprobe needs a service which is in a module", kmod -limits the number of concurrent kmod issued modprobes. See MAX_KMOD_CONCURRENT -in kernel/kmod.c. When this limit is exceeded, the kernel issues message "kmod: -runaway modprobe loop assumed and stopped". - -Note for users building a heavily modularised system. It is a good idea to -create modules.dep after installing the modules and before booting a kernel for -the first time. "depmod -ae m.n.p" where m.n.p is the new kernel version. diff -Nru a/Documentation/kobject.txt b/Documentation/kobject.txt --- a/Documentation/kobject.txt Thu Sep 4 15:38:31 2003 +++ b/Documentation/kobject.txt Thu Sep 4 15:38:31 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 Thu Sep 4 15:38:28 2003 +++ b/Documentation/sonypi.txt Thu Sep 4 15:38:28 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 Thu Sep 4 15:38:42 2003 +++ b/Documentation/sysctl/README Thu Sep 4 15:38:42 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 Thu Sep 4 15:38:48 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 Thu Sep 4 15:38:31 2003 +++ b/Documentation/usb/hotplug.txt Thu Sep 4 15:38:31 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 Thu Sep 4 15:38:41 2003 +++ b/Documentation/video4linux/meye.txt Thu Sep 4 15:38:41 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 Thu Sep 4 15:38:37 2003 +++ b/MAINTAINERS Thu Sep 4 15:38:37 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-janitors@osdl.org +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 Thu Sep 4 15:38:39 2003 +++ b/Makefile Thu Sep 4 15:38:39 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 Thu Sep 4 15:38:41 2003 +++ b/arch/alpha/Kconfig Thu Sep 4 15:38:41 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 Thu Sep 4 15:38:31 2003 +++ b/arch/alpha/kernel/core_titan.c Thu Sep 4 15:38:31 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 Thu Sep 4 15:38:35 2003 +++ b/arch/arm/Kconfig Thu Sep 4 15:38:35 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 Thu Sep 4 15:38:32 2003 +++ b/arch/arm/Makefile Thu Sep 4 15:38:32 2003 @@ -24,17 +24,12 @@ 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) comma = , -# Select CPU dependent flags. Note that order of declaration is important; -# the options further down the list override previous items. -# -apcs-$(CONFIG_CPU_32) :=-mapcs-32 -apcs-$(CONFIG_CPU_26) :=-mapcs-26 -mcpu=arm3 - # This selects which instruction set is used. # Note that GCC does not numerically define an architecture version # macro, but instead defines a whole series of macros which makes @@ -54,37 +49,21 @@ tune-$(CONFIG_CPU_SA1100) :=-mtune=strongarm1100 tune-$(CONFIG_CPU_XSCALE) :=$(call check_gcc,-mtune=xscale,-mtune=strongarm110) -# Force -mno-fpu to be passed to the assembler. Some versions of gcc don't -# do this with -msoft-float -CFLAGS_BOOT :=$(apcs-y) $(arch-y) $(tune-y) -mshort-load-bytes -msoft-float -Wa,-mno-fpu -Uarm -CFLAGS +=$(apcs-y) $(arch-y) $(tune-y) -mshort-load-bytes -msoft-float -Wa,-mno-fpu -Uarm -AFLAGS +=$(apcs-y) $(arch-y) $(tune-y) -msoft-float -Wa,-mno-fpu +CFLAGS_BOOT :=-mapcs-32 $(arch-y) $(tune-y) -mshort-load-bytes -msoft-float -Wa,-mno-fpu -Uarm +CFLAGS +=-mapcs-32 $(arch-y) $(tune-y) -mshort-load-bytes -msoft-float -Wa,-mno-fpu -Uarm +AFLAGS +=-mapcs-32 $(arch-y) $(tune-y) -msoft-float -Wa,-mno-fpu #Default value DATAADDR := . -ifeq ($(CONFIG_CPU_26),y) -PROCESSOR := armo -head-y := arch/arm/mach-arc/head.o arch/arm/kernel/init_task.o -LDFLAGS_BLOB += --oformat elf26-littlearm - ifeq ($(CONFIG_ROM_KERNEL),y) - DATAADDR := 0x02080000 - textaddr-y := 0x03800000 - else - textaddr-y := 0x02080000 - endif -endif - -ifeq ($(CONFIG_CPU_32),y) PROCESSOR := armv head-y := arch/arm/kernel/head.o arch/arm/kernel/init_task.o - ifeq ($(CONFIG_CPU_BIG_ENDIAN),y) - LDFLAGS_BLOB += --oformat elf32-bigarm - else - LDFLAGS_BLOB += --oformat elf32-littlearm - endif -textaddr-y := 0xC0008000 +ifeq ($(CONFIG_CPU_BIG_ENDIAN),y) + LDFLAGS_BLOB += --oformat elf32-bigarm +else + LDFLAGS_BLOB += --oformat elf32-littlearm endif +textaddr-y := 0xC0008000 machine-$(CONFIG_ARCH_ARCA5K) := arc machine-$(CONFIG_ARCH_RPC) := rpc @@ -159,16 +138,10 @@ @ln -sf arch-$(INCDIR) include/asm-arm/arch @touch $@ -include/asm-arm/.proc: $(wildcard include/config/cpu/32.h) $(wildcard include/config/cpu/26.h) - @echo ' Making asm-arm/proc -> asm-arm/proc-$(PROCESSOR) symlink' - @rm -f include/asm-arm/proc - @ln -sf proc-$(PROCESSOR) include/asm-arm/proc - @touch $@ - prepare: maketools .PHONY: maketools FORCE -maketools: include/asm-arm/.arch include/asm-arm/.proc \ +maketools: include/asm-arm/.arch \ include/asm-arm/constants.h include/linux/version.h FORCE $(Q)$(MAKE) $(build)=arch/arm/tools include/asm-arm/mach-types.h @@ -184,7 +157,6 @@ MRPROPER_FILES += \ include/asm-arm/arch include/asm-arm/.arch \ - include/asm-arm/proc include/asm-arm/.proc \ include/asm-arm/constants.h* \ include/asm-arm/mach-types.h @@ -216,7 +188,7 @@ ) arch/$(ARCH)/kernel/asm-offsets.s: include/asm include/linux/version.h \ - include/asm-arm/.arch include/asm-arm/.proc \ + include/asm-arm/.arch \ include/config/MARKER include/asm-$(ARCH)/constants.h: arch/$(ARCH)/kernel/asm-offsets.s diff -Nru a/arch/arm/boot/Makefile b/arch/arm/boot/Makefile --- a/arch/arm/boot/Makefile Thu Sep 4 15:38:30 2003 +++ b/arch/arm/boot/Makefile Thu Sep 4 15:38:30 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 Thu Sep 4 15:38:33 2003 +++ b/arch/arm/common/amba.c Thu Sep 4 15:38:33 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 Thu Sep 4 15:38:44 2003 +++ b/arch/arm/common/sa1111.c Thu Sep 4 15:38:44 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 Thu Sep 4 15:38:30 2003 +++ b/arch/arm/def-configs/iq80310 Thu Sep 4 15:38:30 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 Thu Sep 4 15:38:31 2003 +++ b/arch/arm/def-configs/iq80321 Thu Sep 4 15:38:31 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/Makefile b/arch/arm/kernel/Makefile --- a/arch/arm/kernel/Makefile Thu Sep 4 15:38:44 2003 +++ b/arch/arm/kernel/Makefile Thu Sep 4 15:38:44 2003 @@ -2,13 +2,11 @@ # Makefile for the linux kernel. # -ENTRY_OBJ = entry-$(PROCESSOR).o - AFLAGS_head.o := -DTEXTADDR=$(TEXTADDR) # Object file lists. -obj-y := arch.o compat.o dma.o $(ENTRY_OBJ) entry-common.o irq.o \ +obj-y := arch.o compat.o dma.o entry-armv.o entry-common.o irq.o \ process.o ptrace.o semaphore.o setup.o signal.o sys_arm.o \ time.o traps.o @@ -34,6 +32,5 @@ # Spell out some dependencies that `make dep' doesn't spot $(obj)/entry-armv.o: $(obj)/entry-header.S include/asm-arm/constants.h -$(obj)/entry-armo.o: $(obj)/entry-header.S include/asm-arm/constants.h $(obj)/entry-common.o: $(obj)/entry-header.S include/asm-arm/constants.h \ $(obj)/calls.S diff -Nru a/arch/arm/kernel/apm.c b/arch/arm/kernel/apm.c --- a/arch/arm/kernel/apm.c Thu Sep 4 15:38:45 2003 +++ b/arch/arm/kernel/apm.c Thu Sep 4 15:38:45 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 Thu Sep 4 15:38:32 2003 +++ b/arch/arm/kernel/bios32.c Thu Sep 4 15:38:32 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 Thu Sep 4 15:38:41 2003 +++ b/arch/arm/kernel/ecard.c Thu Sep 4 15:38:41 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-armo.S b/arch/arm/kernel/entry-armo.S --- a/arch/arm/kernel/entry-armo.S Thu Sep 4 15:38:31 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,633 +0,0 @@ -/* - * linux/arch/arm/kernel/entry-armo.S - * - * Copyright (C) 1995,1996,1997,1998 Russell King. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * Low-level vector interface routines - * - * Design issues: - * - We have several modes that each vector can be called from, - * each with its own set of registers. On entry to any vector, - * we *must* save the registers used in *that* mode. - * - * - This code must be as fast as possible. - * - * There are a few restrictions on the vectors: - * - the SWI vector cannot be called from *any* non-user mode - * - * - the FP emulator is *never* called from *any* non-user mode undefined - * instruction. - * - * Ok, so this file may be a mess, but its as efficient as possible while - * adhering to the above criteria. - */ -#include -#include -#include "entry-header.S" - - .text - -#ifdef IOC_BASE -/* IOC / IOMD based hardware */ - .equ ioc_base_high, IOC_BASE & 0xff000000 - .equ ioc_base_low, IOC_BASE & 0x00ff0000 - .macro disable_fiq - mov r12, #ioc_base_high - .if ioc_base_low - orr r12, r12, #ioc_base_low - .endif - strb r12, [r12, #0x38] @ Disable FIQ register - .endm - - .macro get_irqnr_and_base, irqnr, base - mov r4, #ioc_base_high @ point at IOC - .if ioc_base_low - orr r4, r4, #ioc_base_low - .endif - ldrb \irqnr, [r4, #0x24] @ get high priority first - adr \base, irq_prio_h - teq \irqnr, #0 - ldreqb \irqnr, [r4, #0x14] @ get low priority - adreq \base, irq_prio_l - .endm - -/* - * Interrupt table (incorporates priority) - */ - .macro irq_prio_table -irq_prio_l: .byte 0, 0, 1, 0, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3 - .byte 4, 0, 1, 0, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3 - .byte 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5 - .byte 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5 - .byte 6, 6, 6, 6, 6, 6, 6, 6, 3, 3, 3, 3, 3, 3, 3, 3 - .byte 6, 6, 6, 6, 6, 6, 6, 6, 3, 3, 3, 3, 3, 3, 3, 3 - .byte 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5 - .byte 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5 - .byte 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7 - .byte 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7 - .byte 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7 - .byte 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7 - .byte 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7 - .byte 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7 - .byte 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7 - .byte 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7 -irq_prio_h: .byte 0, 8, 9, 8,10,10,10,10,11,11,11,11,10,10,10,10 - .byte 12, 8, 9, 8,10,10,10,10,11,11,11,11,10,10,10,10 - .byte 13,13,13,13,10,10,10,10,11,11,11,11,10,10,10,10 - .byte 13,13,13,13,10,10,10,10,11,11,11,11,10,10,10,10 - .byte 14,14,14,14,10,10,10,10,11,11,11,11,10,10,10,10 - .byte 14,14,14,14,10,10,10,10,11,11,11,11,10,10,10,10 - .byte 13,13,13,13,10,10,10,10,11,11,11,11,10,10,10,10 - .byte 13,13,13,13,10,10,10,10,11,11,11,11,10,10,10,10 - .byte 15,15,15,15,10,10,10,10,11,11,11,11,10,10,10,10 - .byte 15,15,15,15,10,10,10,10,11,11,11,11,10,10,10,10 - .byte 13,13,13,13,10,10,10,10,11,11,11,11,10,10,10,10 - .byte 13,13,13,13,10,10,10,10,11,11,11,11,10,10,10,10 - .byte 15,15,15,15,10,10,10,10,11,11,11,11,10,10,10,10 - .byte 15,15,15,15,10,10,10,10,11,11,11,11,10,10,10,10 - .byte 13,13,13,13,10,10,10,10,11,11,11,11,10,10,10,10 - .byte 13,13,13,13,10,10,10,10,11,11,11,11,10,10,10,10 - .endm -#else -#error Unknown architecture -#endif - -/*============================================================================= - * For entry-common.S - */ - -#if 0 -/* - * Uncomment these if you wish to get more debugging into about data aborts. - */ -#define FAULT_CODE_LDRSTRPOST 0x80 -#define FAULT_CODE_LDRSTRPRE 0x40 -#define FAULT_CODE_LDRSTRREG 0x20 -#define FAULT_CODE_LDMSTM 0x10 -#define FAULT_CODE_LDCSTC 0x08 -#endif -#define FAULT_CODE_PREFETCH 0x04 -#define FAULT_CODE_WRITE 0x02 -#define FAULT_CODE_FORCECOW 0x01 - -#define SVC_SAVE_ALL \ - str sp, [sp, #-16]! ;\ - str lr, [sp, #8] ;\ - str lr, [sp, #4] ;\ - stmfd sp!, {r0 - r12} ;\ - mov r0, #-1 ;\ - str r0, [sp, #S_OLD_R0] ;\ - zero_fp - -#define SVC_IRQ_SAVE_ALL \ - str sp, [sp, #-16]! ;\ - str lr, [sp, #4] ;\ - ldr lr, .LCirq ;\ - ldr lr, [lr] ;\ - str lr, [sp, #8] ;\ - stmfd sp!, {r0 - r12} ;\ - mov r0, #-1 ;\ - str r0, [sp, #S_OLD_R0] ;\ - zero_fp - -#define SVC_RESTORE_ALL \ - ldmfd sp, {r0 - pc}^ - -/*============================================================================= - * Undefined FIQs - *----------------------------------------------------------------------------- - */ -_unexp_fiq: ldr sp, .LCfiq - mov r12, #IOC_BASE - strb r12, [r12, #0x38] @ Disable FIQ register - teqp pc, #0x0c000003 - mov r0, r0 - stmfd sp!, {r0 - r3, ip, lr} - adr r0, Lfiqmsg - bl printk - ldmfd sp!, {r0 - r3, ip, lr} - teqp pc, #0x0c000001 - mov r0, r0 - movs pc, lr - -Lfiqmsg: .ascii "*** Unexpected FIQ\n\0" - .align - -.LCfiq: .word __temp_fiq -.LCirq: .word __temp_irq - -/*============================================================================= - * Undefined instruction handler - *----------------------------------------------------------------------------- - * Handles floating point instructions - */ -vector_undefinstr: - tst lr,#3 - bne __und_svc - save_user_regs - zero_fp - teqp pc, #PSR_I_BIT | MODE_SVC -.Lbug_undef: - ldr r4, .LC2 - ldr pc, [r4] @ Call FP module USR entry point - - .globl fpundefinstr -fpundefinstr: @ Called by FP module on undefined instr - mov r0, lr - mov r1, sp - teqp pc, #MODE_SVC - bl do_undefinstr - b ret_from_exception @ Normal FP exit - -__und_svc: SVC_SAVE_ALL @ Non-user mode - mask_pc r0, lr - and r2, lr, #3 - sub r0, r0, #4 - mov r1, sp - bl do_undefinstr - SVC_RESTORE_ALL - -#if defined CONFIG_FPE_NWFPE || defined CONFIG_FPE_FASTFPE - /* The FPE is always present */ - .equ fpe_not_present, 0 -#else -/* We get here if an undefined instruction happens and the floating - * point emulator is not present. If the offending instruction was - * a WFS, we just perform a normal return as if we had emulated the - * operation. This is a hack to allow some basic userland binaries - * to run so that the emulator module proper can be loaded. --philb - */ -fpe_not_present: - adr r10, wfs_mask_data - ldmia r10, {r4, r5, r6, r7, r8} - ldr r10, [sp, #S_PC] @ Load PC - sub r10, r10, #4 - mask_pc r10, r10 - ldrt r10, [r10] @ get instruction - and r5, r10, r5 - teq r5, r4 @ Is it WFS? - beq ret_from_exception - and r5, r10, r8 - teq r5, r6 @ Is it LDF/STF on sp or fp? - teqne r5, r7 - bne fpundefinstr - tst r10, #0x00200000 @ Does it have WB - beq ret_from_exception - and r4, r10, #255 @ get offset - and r6, r10, #0x000f0000 - tst r10, #0x00800000 @ +/- - ldr r5, [sp, r6, lsr #14] @ Load reg - rsbeq r4, r4, #0 - add r5, r5, r4, lsl #2 - str r5, [sp, r6, lsr #14] @ Save reg - b ret_from_exception - -wfs_mask_data: .word 0x0e200110 @ WFS/RFS - .word 0x0fef0fff - .word 0x0d0d0100 @ LDF [sp]/STF [sp] - .word 0x0d0b0100 @ LDF [fp]/STF [fp] - .word 0x0f0f0f00 -#endif - -.LC2: .word fp_enter - -/*============================================================================= - * Prefetch abort handler - *----------------------------------------------------------------------------- - */ - -vector_prefetch: - sub lr, lr, #4 - tst lr, #3 - bne __pabt_invalid - save_user_regs - teqp pc, #0x00000003 @ NOT a problem - doesn't change mode - mask_pc r0, lr @ Address of abort - mov r1, sp @ Tasks registers - bl do_PrefetchAbort - teq r0, #0 @ If non-zero, we believe this abort.. - bne ret_from_exception -#ifdef DEBUG_UNDEF - adr r0, t - bl printk -#endif - ldr lr, [sp,#S_PC] @ program to test this on. I think its - b .Lbug_undef @ broken at the moment though!) - -__pabt_invalid: SVC_SAVE_ALL - mov r0, sp @ Prefetch aborts are definitely *not* - mov r1, #BAD_PREFETCH @ allowed in non-user modes. We cant - and r2, lr, #3 @ recover from this problem. - b bad_mode - -#ifdef DEBUG_UNDEF -t: .ascii "*** undef ***\r\n\0" - .align -#endif - -/*============================================================================= - * Address exception handler - *----------------------------------------------------------------------------- - * These aren't too critical. - * (they're not supposed to happen). - * In order to debug the reason for address exceptions in non-user modes, - * we have to obtain all the registers so that we can see what's going on. - */ - -vector_addrexcptn: - sub lr, lr, #8 - tst lr, #3 - bne Laddrexcptn_not_user - save_user_regs - teq pc, #0x00000003 - mask_pc r0, lr @ Point to instruction - mov r1, sp @ Point to registers - mov r2, #0x400 - mov lr, pc - bl do_excpt - b ret_from_exception - -Laddrexcptn_not_user: - SVC_SAVE_ALL - and r2, lr, #3 - teq r2, #3 - bne Laddrexcptn_illegal_mode - teqp pc, #0x00000003 @ NOT a problem - doesn't change mode - mask_pc r0, lr - mov r1, sp - orr r2, r2, #0x400 - bl do_excpt - ldmia sp, {r0 - lr} @ I cant remember the reason I changed this... - add sp, sp, #15*4 - movs pc, lr - -Laddrexcptn_illegal_mode: - mov r0, sp - str lr, [sp, #-4]! - orr r1, r2, #0x0c000000 - teqp r1, #0 @ change into mode (wont be user mode) - mov r0, r0 - mov r1, r8 @ Any register from r8 - r14 can be banked - mov r2, r9 - mov r3, r10 - mov r4, r11 - mov r5, r12 - mov r6, r13 - mov r7, r14 - teqp pc, #0x04000003 @ back to svc - mov r0, r0 - stmfd sp!, {r1-r7} - ldmia r0, {r0-r7} - stmfd sp!, {r0-r7} - mov r0, sp - mov r1, #BAD_ADDREXCPTN - b bad_mode - -/*============================================================================= - * Interrupt (IRQ) handler - *----------------------------------------------------------------------------- - * Note: if in user mode, then *no* kernel routine is running, so do not have - * to save svc lr - * (r13 points to irq temp save area) - */ - -vector_IRQ: ldr r13, .LCirq @ I will leave this one in just in case... - sub lr, lr, #4 - str lr, [r13] - tst lr, #3 - bne __irq_svc - teqp pc, #0x08000003 - mov r0, r0 - ldr lr, .LCirq - ldr lr, [lr] - save_user_regs - -1: get_irqnr_and_base r6, r5 - teq r6, #0 - ldrneb r0, [r5, r6] @ get IRQ number - movne r1, sp - @ - @ routine called with r0 = irq number, r1 = struct pt_regs * - @ - adr lr, 1b - orr lr, lr, #0x08000003 @ Force SVC - bne asm_do_IRQ - - mov why, #0 - get_current_task r5 - b ret_to_user - - irq_prio_table - -__irq_svc: teqp pc, #0x08000003 - mov r0, r0 - SVC_IRQ_SAVE_ALL - and r2, lr, #3 - teq r2, #3 - bne __irq_invalid -1: get_irqnr_and_base r6, r5 - teq r6, #0 - ldrneb r0, [r5, r6] @ get IRQ number - movne r1, sp - @ - @ routine called with r0 = irq number, r1 = struct pt_regs * - @ - adr lr, 1b - orr lr, lr, #0x08000003 @ Force SVC - bne asm_do_IRQ @ Returns to 1b - SVC_RESTORE_ALL - -__irq_invalid: mov r0, sp - mov r1, #BAD_IRQ - b bad_mode - -/*============================================================================= - * Data abort handler code - *----------------------------------------------------------------------------- - * - * This handles both exceptions from user and SVC modes, computes the address - * range of the problem, and does any correction that is required. It then - * calls the kernel data abort routine. - * - * This is where I wish that the ARM would tell you which address aborted. - */ - -vector_data: sub lr, lr, #8 @ Correct lr - tst lr, #3 - bne Ldata_not_user - save_user_regs - teqp pc, #0x00000003 @ NOT a problem - doesn't change mode - mask_pc r0, lr - bl Ldata_do - b ret_from_exception - -Ldata_not_user: - SVC_SAVE_ALL - and r2, lr, #3 - teq r2, #3 - bne Ldata_illegal_mode - tst lr, #0x08000000 - teqeqp pc, #0x00000003 @ NOT a problem - doesn't change mode - mask_pc r0, lr - bl Ldata_do - SVC_RESTORE_ALL - -Ldata_illegal_mode: - mov r0, sp - mov r1, #BAD_DATA - b bad_mode - -Ldata_do: mov r3, sp - ldr r4, [r0] @ Get instruction - mov r2, #0 - tst r4, #1 << 20 @ Check to see if it is a write instruction - orreq r2, r2, #FAULT_CODE_WRITE @ Indicate write instruction - mov r1, r4, lsr #22 @ Now branch to the relevant processing routine - and r1, r1, #15 << 2 - add pc, pc, r1 - movs pc, lr - b Ldata_unknown - b Ldata_unknown - b Ldata_unknown - b Ldata_unknown - b Ldata_ldrstr_post @ ldr rd, [rn], #m - b Ldata_ldrstr_numindex @ ldr rd, [rn, #m] @ RegVal - b Ldata_ldrstr_post @ ldr rd, [rn], rm - b Ldata_ldrstr_regindex @ ldr rd, [rn, rm] - b Ldata_ldmstm @ ldm*a rn, - b Ldata_ldmstm @ ldm*b rn, - b Ldata_unknown - b Ldata_unknown - b Ldata_ldrstr_post @ ldc rd, [rn], #m @ Same as ldr rd, [rn], #m - b Ldata_ldcstc_pre @ ldc rd, [rn, #m] - b Ldata_unknown -Ldata_unknown: @ Part of jumptable - mov r0, r1 - mov r1, r4 - mov r2, r3 - b baddataabort - -Ldata_ldrstr_post: - mov r0, r4, lsr #14 @ Get Rn - and r0, r0, #15 << 2 @ Mask out reg. - teq r0, #15 << 2 - ldr r0, [r3, r0] @ Get register - biceq r0, r0, #PCMASK - mov r1, r0 -#ifdef FAULT_CODE_LDRSTRPOST - orr r2, r2, #FAULT_CODE_LDRSTRPOST -#endif - b do_DataAbort - -Ldata_ldrstr_numindex: - mov r0, r4, lsr #14 @ Get Rn - and r0, r0, #15 << 2 @ Mask out reg. - teq r0, #15 << 2 - ldr r0, [r3, r0] @ Get register - mov r1, r4, lsl #20 - biceq r0, r0, #PCMASK - tst r4, #1 << 23 - addne r0, r0, r1, lsr #20 - subeq r0, r0, r1, lsr #20 - mov r1, r0 -#ifdef FAULT_CODE_LDRSTRPRE - orr r2, r2, #FAULT_CODE_LDRSTRPRE -#endif - b do_DataAbort - -Ldata_ldrstr_regindex: - mov r0, r4, lsr #14 @ Get Rn - and r0, r0, #15 << 2 @ Mask out reg. - teq r0, #15 << 2 - ldr r0, [r3, r0] @ Get register - and r7, r4, #15 - biceq r0, r0, #PCMASK - teq r7, #15 @ Check for PC - ldr r7, [r3, r7, lsl #2] @ Get Rm - and r8, r4, #0x60 @ Get shift types - biceq r7, r7, #PCMASK - mov r9, r4, lsr #7 @ Get shift amount - and r9, r9, #31 - teq r8, #0 - moveq r7, r7, lsl r9 - teq r8, #0x20 @ LSR shift - moveq r7, r7, lsr r9 - teq r8, #0x40 @ ASR shift - moveq r7, r7, asr r9 - teq r8, #0x60 @ ROR shift - moveq r7, r7, ror r9 - tst r4, #1 << 23 - addne r0, r0, r7 - subeq r0, r0, r7 @ Apply correction - mov r1, r0 -#ifdef FAULT_CODE_LDRSTRREG - orr r2, r2, #FAULT_CODE_LDRSTRREG -#endif - b do_DataAbort - -Ldata_ldmstm: - mov r7, #0x11 - orr r7, r7, r7, lsl #8 - and r0, r4, r7 - and r1, r4, r7, lsl #1 - add r0, r0, r1, lsr #1 - and r1, r4, r7, lsl #2 - add r0, r0, r1, lsr #2 - and r1, r4, r7, lsl #3 - add r0, r0, r1, lsr #3 - add r0, r0, r0, lsr #8 - add r0, r0, r0, lsr #4 - and r7, r0, #15 @ r7 = no. of registers to transfer. - mov r5, r4, lsr #14 @ Get Rn - and r5, r5, #15 << 2 - ldr r0, [r3, r5] @ Get reg - eor r6, r4, r4, lsl #2 - tst r6, #1 << 23 @ Check inc/dec ^ writeback - rsbeq r7, r7, #0 - add r7, r0, r7, lsl #2 @ Do correction (signed) - subne r1, r7, #1 - subeq r1, r0, #1 - moveq r0, r7 - tst r4, #1 << 21 @ Check writeback - strne r7, [r3, r5] - eor r6, r4, r4, lsl #1 - tst r6, #1 << 24 @ Check Pre/Post ^ inc/dec - addeq r0, r0, #4 - addeq r1, r1, #4 - teq r5, #15*4 @ CHECK FOR PC - biceq r1, r1, #PCMASK - biceq r0, r0, #PCMASK -#ifdef FAULT_CODE_LDMSTM - orr r2, r2, #FAULT_CODE_LDMSTM -#endif - b do_DataAbort - -Ldata_ldcstc_pre: - mov r0, r4, lsr #14 @ Get Rn - and r0, r0, #15 << 2 @ Mask out reg. - teq r0, #15 << 2 - ldr r0, [r3, r0] @ Get register - mov r1, r4, lsl #24 @ Get offset - biceq r0, r0, #PCMASK - tst r4, #1 << 23 - addne r0, r0, r1, lsr #24 - subeq r0, r0, r1, lsr #24 - mov r1, r0 -#ifdef FAULT_CODE_LDCSTC - orr r2, r2, #FAULT_CODE_LDCSTC -#endif - b do_DataAbort - - -/* - * This is the return code to user mode for abort handlers - */ -ENTRY(ret_from_exception) - get_current_task tsk - mov why, #0 - b ret_to_user - - .data -ENTRY(fp_enter) - .word fpe_not_present - .text -/* - * Register switch for older 26-bit only ARMs - */ -ENTRY(__switch_to) - stmfd sp!, {r4 - sl, fp, lr} @ Store most regs on stack - str sp, [r0, #TSS_SAVE] @ Save sp_SVC - ldr sp, [r1, #TSS_SAVE] @ Get saved sp_SVC - ldmfd sp!, {r4 - sl, fp, pc}^ @ Load all regs saved previously - -/* - *============================================================================= - * Low-level interface code - *----------------------------------------------------------------------------- - * Trap initialisation - *----------------------------------------------------------------------------- - * - * Note - FIQ code has changed. The default is a couple of words in 0x1c, 0x20 - * that call _unexp_fiq. Nowever, we now copy the FIQ routine to 0x1c (removes - * some excess cycles). - * - * What we need to put into 0-0x1c are branches to branch to the kernel. - */ - - __INIT - -.Ljump_addresses: - swi SYS_ERROR0 - .word vector_undefinstr - 12 - .word vector_swi - 16 - .word vector_prefetch - 20 - .word vector_data - 24 - .word vector_addrexcptn - 28 - .word vector_IRQ - 32 - .word _unexp_fiq - 36 - b . + 8 -/* - * initialise the trap system - */ -ENTRY(__trap_init) - stmfd sp!, {r4 - r7, lr} - adr r1, .Ljump_addresses - ldmia r1, {r1 - r7, ip, lr} - orr r2, lr, r2, lsr #2 - orr r3, lr, r3, lsr #2 - orr r4, lr, r4, lsr #2 - orr r5, lr, r5, lsr #2 - orr r6, lr, r6, lsr #2 - orr r7, lr, r7, lsr #2 - orr ip, lr, ip, lsr #2 - mov r0, #0 - stmia r0, {r1 - r7, ip} - ldmfd sp!, {r4 - r7, pc}^ - - .bss -__temp_irq: .space 4 @ saved lr_irq -__temp_fiq: .space 128 diff -Nru a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S --- a/arch/arm/kernel/entry-armv.S Thu Sep 4 15:38:31 2003 +++ b/arch/arm/kernel/entry-armv.S Thu Sep 4 15:38:31 2003 @@ -15,10 +15,12 @@ */ #include #include -#include "entry-header.S" + #include #include +#include +#include "entry-header.S" #ifdef IOC_BASE /* IOC / IOMD based hardware */ diff -Nru a/arch/arm/kernel/entry-common.S b/arch/arm/kernel/entry-common.S --- a/arch/arm/kernel/entry-common.S Thu Sep 4 15:38:28 2003 +++ b/arch/arm/kernel/entry-common.S Thu Sep 4 15:38:28 2003 @@ -8,8 +8,11 @@ * published by the Free Software Foundation. */ #include -#include "entry-header.S" + #include +#include + +#include "entry-header.S" /* * We rely on the fact that R0 is at the bottom of the stack (due to diff -Nru a/arch/arm/kernel/entry-header.S b/arch/arm/kernel/entry-header.S --- a/arch/arm/kernel/entry-header.S Thu Sep 4 15:38:32 2003 +++ b/arch/arm/kernel/entry-header.S Thu Sep 4 15:38:32 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/head.S b/arch/arm/kernel/head.S --- a/arch/arm/kernel/head.S Thu Sep 4 15:38:28 2003 +++ b/arch/arm/kernel/head.S Thu Sep 4 15:38:28 2003 @@ -16,6 +16,7 @@ #include #include #include +#include #include /* diff -Nru a/arch/arm/kernel/pm.c b/arch/arm/kernel/pm.c --- a/arch/arm/kernel/pm.c Thu Sep 4 15:38:47 2003 +++ b/arch/arm/kernel/pm.c Thu Sep 4 15:38:47 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 Thu Sep 4 15:38:29 2003 +++ b/arch/arm/kernel/vmlinux.lds.S Thu Sep 4 15:38:32 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 Thu Sep 4 15:38:28 2003 +++ b/arch/arm/mach-footbridge/netwinder-pci.c Thu Sep 4 15:38:28 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 Thu Sep 4 15:38:43 2003 +++ b/arch/arm/mach-iop3xx/iop321-time.c Thu Sep 4 15:38:43 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 Thu Sep 4 15:38:40 2003 +++ b/arch/arm/mach-iop3xx/iq80310-time.c Thu Sep 4 15:38:40 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-l7200/core.c b/arch/arm/mach-l7200/core.c --- a/arch/arm/mach-l7200/core.c Thu Sep 4 15:38:30 2003 +++ b/arch/arm/mach-l7200/core.c Thu Sep 4 15:38:30 2003 @@ -11,7 +11,6 @@ #include #include -#include #include #include diff -Nru a/arch/arm/mach-rpc/riscpc.c b/arch/arm/mach-rpc/riscpc.c --- a/arch/arm/mach-rpc/riscpc.c Thu Sep 4 15:38:39 2003 +++ b/arch/arm/mach-rpc/riscpc.c Thu Sep 4 15:38:39 2003 @@ -21,7 +21,7 @@ #include #include #include -#include +#include #include #include 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 Thu Sep 4 15:38:33 2003 +++ b/arch/arm/mach-sa1100/leds-simpad.c Thu Sep 4 15:38:33 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 Thu Sep 4 15:38:30 2003 +++ b/arch/arm/mach-sa1100/leds.c Thu Sep 4 15:38:30 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 Thu Sep 4 15:38:41 2003 +++ b/arch/arm/mach-sa1100/leds.h Thu Sep 4 15:38:41 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/mm/Makefile b/arch/arm/mm/Makefile --- a/arch/arm/mm/Makefile Thu Sep 4 15:38:48 2003 +++ b/arch/arm/mm/Makefile Thu Sep 4 15:38:48 2003 @@ -4,20 +4,12 @@ # Object file lists. -obj-y := init.o extable.o fault-common.o -obj-m := -obj-n := -obj- := -ifeq ($(CONFIG_CPU_32),y) -obj-y += consistent.o fault-armv.o ioremap.o mm-armv.o +obj-y := consistent.o extable.o fault-armv.o fault-common.o \ + init.o ioremap.o mm-armv.o obj-$(CONFIG_MODULES) += proc-syms.o -endif obj-$(CONFIG_ALIGNMENT_TRAP) += alignment.o obj-$(CONFIG_DISCONTIGMEM) += discontig.o - -# Select the processor-specific files -p-$(CONFIG_CPU_26) += proc-arm2_3.o # ARMv3 p-$(CONFIG_CPU_ARM610) += proc-arm6_7.o tlb-v3.o cache-v3.o copypage-v3.o diff -Nru a/arch/arm/mm/mm-armv.c b/arch/arm/mm/mm-armv.c --- a/arch/arm/mm/mm-armv.c Thu Sep 4 15:38:38 2003 +++ b/arch/arm/mm/mm-armv.c Thu Sep 4 15:38:38 2003 @@ -34,8 +34,8 @@ }; static struct cachepolicy cache_policies[] __initdata = { - { "uncached", CR1_W|CR1_C, PMD_SECT_UNCACHED }, - { "buffered", CR1_C, PMD_SECT_BUFFERED }, + { "uncached", CR_W|CR_C, PMD_SECT_UNCACHED }, + { "buffered", CR_C, PMD_SECT_BUFFERED }, { "writethrough", 0, PMD_SECT_WT }, #ifndef CONFIG_CPU_DCACHE_WRITETHROUGH { "writeback", 0, PMD_SECT_WB }, @@ -102,8 +102,8 @@ static int __init noalign_setup(char *__unused) { - cr_alignment &= ~CR1_A; - cr_no_alignment &= ~CR1_A; + cr_alignment &= ~CR_A; + cr_no_alignment &= ~CR_A; set_cr(cr_alignment); return 1; } diff -Nru a/arch/arm/mm/proc-arm1020.S b/arch/arm/mm/proc-arm1020.S --- a/arch/arm/mm/proc-arm1020.S Thu Sep 4 15:38:29 2003 +++ b/arch/arm/mm/proc-arm1020.S Thu Sep 4 15:38:29 2003 @@ -30,6 +30,7 @@ #include #include #include +#include #include /* diff -Nru a/arch/arm/mm/proc-arm2_3.S b/arch/arm/mm/proc-arm2_3.S --- a/arch/arm/mm/proc-arm2_3.S Thu Sep 4 15:38:34 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,360 +0,0 @@ -/* - * linux/arch/arm/mm/proc-arm2,3.S - * - * Copyright (C) 1997-1999 Russell King - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * MMU functions for ARM2,3 - * - * These are the low level assembler for performing cache - * and memory functions on ARM2, ARM250 and ARM3 processors. - */ -#include -#include -#include -#include -#include - -/* - * MEMC workhorse code. It's both a horse which things it's a pig. - */ -/* - * Function: cpu_memc_update_entry(pgd_t *pgd, unsigned long phys_pte, unsigned long addr) - * Params : pgd Page tables/MEMC mapping - * : phys_pte physical address, or PTE - * : addr virtual address - */ -ENTRY(cpu_memc_update_entry) - tst r1, #PAGE_PRESENT @ is the page present - orreq r1, r1, #PAGE_OLD | PAGE_CLEAN - moveq r2, #0x01f00000 - mov r3, r1, lsr #13 @ convert to physical page nr - and r3, r3, #0x3fc - adr ip, memc_phys_table_32 - ldr r3, [ip, r3] - tst r1, #PAGE_OLD | PAGE_NOT_USER - biceq r3, r3, #0x200 - tsteq r1, #PAGE_READONLY | PAGE_CLEAN - biceq r3, r3, #0x300 - mov r2, r2, lsr #15 @ virtual -> nr - orr r3, r3, r2, lsl #15 - and r2, r2, #0x300 - orr r3, r3, r2, lsl #2 - and r2, r3, #255 - sub r0, r0, #256 * 4 - str r3, [r0, r2, lsl #2] - strb r3, [r3] - movs pc, lr -/* - * Params : r0 = preserved - * : r1 = memc table base (preserved) - * : r2 = page table entry - * : r3 = preserved - * : r4 = unused - * : r5 = memc physical address translation table - * : ip = virtual address (preserved) - */ -update_pte: - mov r4, r2, lsr #13 - and r4, r4, #0x3fc - ldr r4, [r5, r4] @ covert to MEMC page - - tst r2, #PAGE_OLD | PAGE_NOT_USER @ check for MEMC read - biceq r4, r4, #0x200 - tsteq r2, #PAGE_READONLY | PAGE_CLEAN @ check for MEMC write - biceq r4, r4, #0x300 - - orr r4, r4, ip - and r2, ip, #0x01800000 - orr r4, r4, r2, lsr #13 - - and r2, r4, #255 - str r4, [r1, r2, lsl #2] - movs pc, lr - -/* - * Params : r0 = preserved - * : r1 = memc table base (preserved) - * : r2 = page table base - * : r3 = preserved - * : r4 = unused - * : r5 = memc physical address translation table - * : ip = virtual address (updated) - */ -update_pte_table: - stmfd sp!, {r0, lr} - bic r0, r2, #3 -1: ldr r2, [r0], #4 @ get entry - tst r2, #PAGE_PRESENT @ page present - blne update_pte @ process pte - add ip, ip, #32768 @ increment virt addr - ldr r2, [r0], #4 @ get entry - tst r2, #PAGE_PRESENT @ page present - blne update_pte @ process pte - add ip, ip, #32768 @ increment virt addr - ldr r2, [r0], #4 @ get entry - tst r2, #PAGE_PRESENT @ page present - blne update_pte @ process pte - add ip, ip, #32768 @ increment virt addr - ldr r2, [r0], #4 @ get entry - tst r2, #PAGE_PRESENT @ page present - blne update_pte @ process pte - add ip, ip, #32768 @ increment virt addr - tst ip, #32768 * 31 @ finished? - bne 1b - ldmfd sp!, {r0, pc}^ - -/* - * Function: cpu_memc_update_all(pgd_t *pgd) - * Params : pgd Page tables/MEMC mapping - * Notes : this is optimised for 32k pages - */ -ENTRY(cpu_memc_update_all) - stmfd sp!, {r4, r5, lr} - bl clear_tables - sub r1, r0, #256 * 4 @ start of MEMC tables - adr r5, memc_phys_table_32 @ Convert to logical page number - mov ip, #0 @ virtual address -1: ldmia r0!, {r2, r3} - tst r2, #PAGE_PRESENT - addeq ip, ip, #1048576 - blne update_pte_table - mov r2, r3 - tst r2, #PAGE_PRESENT - addeq ip, ip, #1048576 - blne update_pte_table - teq ip, #32 * 1048576 - bne 1b - ldmfd sp!, {r4, r5, pc}^ - -/* - * Build the table to map from physical page number to memc page number - */ - .type memc_phys_table_32, #object -memc_phys_table_32: - .irp b7, 0x00, 0x80 - .irp b6, 0x00, 0x02 - .irp b5, 0x00, 0x04 - .irp b4, 0x00, 0x01 - - .irp b3, 0x00, 0x40 - .irp b2, 0x00, 0x20 - .irp b1, 0x00, 0x10 - .irp b0, 0x00, 0x08 - .long 0x03800300 + \b7 + \b6 + \b5 + \b4 + \b3 + \b2 + \b1 + \b0 - .endr - .endr - .endr - .endr - - .endr - .endr - .endr - .endr - .size memc_phys_table_32, . - memc_phys_table_32 - -/* - * helper for cpu_memc_update_all, this clears out all - * mappings, setting them close to the top of memory, - * and inaccessible (0x01f00000). - * Params : r0 = page table pointer - */ -clear_tables: ldr r1, _arm3_switch_mm - 4 - ldr r2, [r1] - sub r1, r0, #256 * 4 @ start of MEMC tables - add r2, r1, r2, lsl #2 @ end of tables - mov r3, #0x03f00000 @ Default mapping (null mapping) - orr r3, r3, #0x00000f00 - orr r4, r3, #1 - orr r5, r3, #2 - orr ip, r3, #3 -1: stmia r1!, {r3, r4, r5, ip} - add r3, r3, #4 - add r4, r4, #4 - add r5, r5, #4 - add ip, ip, #4 - stmia r1!, {r3, r4, r5, ip} - add r3, r3, #4 - add r4, r4, #4 - add r5, r5, #4 - add ip, ip, #4 - teq r1, r2 - bne 1b - mov pc, lr - -/* - * Function: *_switch_mm(pgd_t *pgd) - * Params : pgd New page tables/MEMC mapping - * Purpose : update MEMC hardware with new mapping - */ - .word page_nr -_arm3_switch_mm: - mcr p15, 0, r1, c1, c0, 0 @ flush cache -_arm2_switch_mm: - stmfd sp!, {lr} - ldr r1, _arm3_switch_mm - 4 - ldr r2, [r1] - sub r0, r0, #256 * 4 @ start of MEMC tables - add r1, r0, r2, lsl #2 @ end of tables -1: ldmia r0!, {r2, r3, ip, lr} - strb r2, [r2] - strb r3, [r3] - strb ip, [ip] - strb lr, [lr] - ldmia r0!, {r2, r3, ip, lr} - strb r2, [r2] - strb r3, [r3] - strb ip, [ip] - strb lr, [lr] - teq r0, r1 - bne 1b - ldmfd sp!, {pc}^ - -/* - * Function: *_proc_init (void) - * Purpose : Initialise the cache control registers - */ -_arm3_proc_init: - mov r0, #0x001f0000 - orr r0, r0, #0x0000ff00 - orr r0, r0, #0x000000ff - mcr p15, 0, r0, c3, c0 @ ARM3 Cacheable - mcr p15, 0, r0, c4, c0 @ ARM3 Updateable - mov r0, #0 - mcr p15, 0, r0, c5, c0 @ ARM3 Disruptive - mcr p15, 0, r0, c1, c0 @ ARM3 Flush - mov r0, #3 - mcr p15, 0, r0, c2, c0 @ ARM3 Control -_arm2_proc_init: - movs pc, lr - -/* - * Function: *_proc_fin (void) - * Purpose : Finalise processor (disable caches) - */ -_arm3_proc_fin: mov r0, #2 - mcr p15, 0, r0, c2, c0 -_arm2_proc_fin: orrs pc, lr, #PSR_I_BIT|PSR_F_BIT - -/* - * Function: *_xchg_1 (int new, volatile void *ptr) - * Params : new New value to store at... - * : ptr pointer to byte-wide location - * Purpose : Performs an exchange operation - * Returns : Original byte data at 'ptr' - */ -_arm2_xchg_1: mov r2, pc - orr r2, r2, #PSR_I_BIT - teqp r2, #0 - ldrb r2, [r1] - strb r0, [r1] - mov r0, r2 - movs pc, lr - -_arm3_xchg_1: swpb r0, r0, [r1] - movs pc, lr - -/* - * Function: *_xchg_4 (int new, volatile void *ptr) - * Params : new New value to store at... - * : ptr pointer to word-wide location - * Purpose : Performs an exchange operation - * Returns : Original word data at 'ptr' - */ -_arm2_xchg_4: mov r2, pc - orr r2, r2, #PSR_I_BIT - teqp r2, #0 - ldr r2, [r1] - str r0, [r1] - mov r0, r2 - movs pc, lr - -_arm3_xchg_4: swp r0, r0, [r1] - movs pc, lr - -cpu_arm2_name: - .asciz "ARM 2" -cpu_arm250_name: - .asciz "ARM 250" -cpu_arm3_name: - .asciz "ARM 3" - - __INIT -/* - * Purpose : Function pointers used to access above functions - all calls - * come through these - */ - .globl arm2_processor_functions -arm2_processor_functions: - .word _arm2_proc_init - .word _arm2_proc_fin - .word _arm2_switch_mm - .word _arm2_xchg_1 - .word _arm2_xchg_4 - - .globl arm250_processor_functions -arm250_processor_functions: - .word _arm2_proc_init - .word _arm2_proc_fin - .word _arm2_switch_mm - .word _arm3_xchg_1 - .word _arm3_xchg_4 - - .globl arm3_processor_functions -arm3_processor_functions: - .word _arm3_proc_init - .word _arm3_proc_fin - .word _arm3_switch_mm - .word _arm3_xchg_1 - .word _arm3_xchg_4 - -arm2_arch_name: .asciz "armv1" -arm3_arch_name: .asciz "armv2" -arm2_elf_name: .asciz "v1" -arm3_elf_name: .asciz "v2" - .align - - .section ".proc.info", #alloc, #execinstr - - .long 0x41560200 - .long 0xfffffff0 - .long 0 - mov pc, lr - .long arm2_arch_name - .long arm2_elf_name - .long 0 - .long cpu_arm2_name - .long arm2_processor_functions - .long 0 - .long 0 - .long 0 - - .long 0x41560250 - .long 0xfffffff0 - .long 0 - mov pc, lr - .long arm3_arch_name - .long arm3_elf_name - .long 0 - .long cpu_arm250_name - .long arm250_processor_functions - .long 0 - .long 0 - .long 0 - - .long 0x41560300 - .long 0xfffffff0 - .long 0 - mov pc, lr - .long arm3_arch_name - .long arm3_elf_name - .long 0 - .long cpu_arm3_name - .long arm3_processor_functions - .long 0 - .long 0 - .long 0 - diff -Nru a/arch/arm/mm/proc-arm6_7.S b/arch/arm/mm/proc-arm6_7.S --- a/arch/arm/mm/proc-arm6_7.S Thu Sep 4 15:38:42 2003 +++ b/arch/arm/mm/proc-arm6_7.S Thu Sep 4 15:38:42 2003 @@ -15,6 +15,7 @@ #include #include #include +#include ENTRY(cpu_arm6_dcache_clean_area) ENTRY(cpu_arm7_dcache_clean_area) diff -Nru a/arch/arm/mm/proc-arm720.S b/arch/arm/mm/proc-arm720.S --- a/arch/arm/mm/proc-arm720.S Thu Sep 4 15:38:38 2003 +++ b/arch/arm/mm/proc-arm720.S Thu Sep 4 15:38:38 2003 @@ -35,6 +35,7 @@ #include #include #include +#include #include /* diff -Nru a/arch/arm/mm/proc-arm920.S b/arch/arm/mm/proc-arm920.S --- a/arch/arm/mm/proc-arm920.S Thu Sep 4 15:38:29 2003 +++ b/arch/arm/mm/proc-arm920.S Thu Sep 4 15:38:29 2003 @@ -31,6 +31,7 @@ #include #include #include +#include #include "proc-macros.S" /* diff -Nru a/arch/arm/mm/proc-arm922.S b/arch/arm/mm/proc-arm922.S --- a/arch/arm/mm/proc-arm922.S Thu Sep 4 15:38:43 2003 +++ b/arch/arm/mm/proc-arm922.S Thu Sep 4 15:38:43 2003 @@ -32,6 +32,7 @@ #include #include #include +#include #include "proc-macros.S" /* diff -Nru a/arch/arm/mm/proc-arm926.S b/arch/arm/mm/proc-arm926.S --- a/arch/arm/mm/proc-arm926.S Thu Sep 4 15:38:35 2003 +++ b/arch/arm/mm/proc-arm926.S Thu Sep 4 15:38:35 2003 @@ -31,6 +31,7 @@ #include #include #include +#include #include "proc-macros.S" /* diff -Nru a/arch/arm/mm/proc-sa110.S b/arch/arm/mm/proc-sa110.S --- a/arch/arm/mm/proc-sa110.S Thu Sep 4 15:38:33 2003 +++ b/arch/arm/mm/proc-sa110.S Thu Sep 4 15:38:33 2003 @@ -18,7 +18,8 @@ #include #include #include -#include +#include +#include /* * the cache line size of the I and D cache diff -Nru a/arch/arm/mm/proc-sa1100.S b/arch/arm/mm/proc-sa1100.S --- a/arch/arm/mm/proc-sa1100.S Thu Sep 4 15:38:41 2003 +++ b/arch/arm/mm/proc-sa1100.S Thu Sep 4 15:38:41 2003 @@ -23,7 +23,8 @@ #include #include #include -#include +#include +#include /* * the cache line size of the I and D cache diff -Nru a/arch/arm/mm/proc-xscale.S b/arch/arm/mm/proc-xscale.S --- a/arch/arm/mm/proc-xscale.S Thu Sep 4 15:38:43 2003 +++ b/arch/arm/mm/proc-xscale.S Thu Sep 4 15:38:43 2003 @@ -25,8 +25,9 @@ #include #include #include -#include +#include #include +#include #include "proc-macros.S" /* diff -Nru a/arch/arm/vmlinux-armo.lds.in b/arch/arm/vmlinux-armo.lds.in --- a/arch/arm/vmlinux-armo.lds.in Thu Sep 4 15:38:46 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 Thu Sep 4 15:38:32 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 Thu Sep 4 15:38:36 2003 +++ b/arch/arm26/Kconfig Thu Sep 4 15:38:36 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 Thu Sep 4 15:38:30 2003 +++ b/arch/arm26/kernel/setup.c Thu Sep 4 15:38:30 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 Thu Sep 4 15:38:32 2003 +++ b/arch/cris/arch-v10/drivers/eeprom.c Thu Sep 4 15:38:32 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 Thu Sep 4 15:38:28 2003 +++ b/arch/cris/arch-v10/drivers/gpio.c Thu Sep 4 15:38:28 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 Thu Sep 4 15:38:31 2003 +++ b/arch/cris/arch-v10/drivers/pcf8563.c Thu Sep 4 15:38:31 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 Thu Sep 4 15:38:42 2003 +++ b/arch/h8300/Kconfig Thu Sep 4 15:38:42 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 Thu Sep 4 15:38:30 2003 +++ b/arch/h8300/kernel/setup.c Thu Sep 4 15:38:30 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 Thu Sep 4 15:38:31 2003 +++ b/arch/h8300/platform/h8300h/ints.c Thu Sep 4 15:38:31 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 Thu Sep 4 15:38:32 2003 +++ b/arch/h8300/platform/h8s/ints.c Thu Sep 4 15:38:32 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 Thu Sep 4 15:38:30 2003 +++ b/arch/i386/Kconfig Thu Sep 4 15:38:30 2003 @@ -408,6 +408,20 @@ 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 HPET_EMULATE_RTC + def_bool HPET_TIMER && RTC=y + config SMP bool "Symmetric multi-processing support" ---help--- @@ -1155,40 +1169,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 Thu Sep 4 15:38:30 2003 +++ b/arch/i386/kernel/Makefile Thu Sep 4 15:38:30 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 Thu Sep 4 15:38:43 2003 +++ b/arch/i386/kernel/acpi/boot.c Thu Sep 4 15:38:43 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 Thu Sep 4 15:38:48 2003 +++ b/arch/i386/kernel/apic.c Thu Sep 4 15:38:48 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/apm.c b/arch/i386/kernel/apm.c --- a/arch/i386/kernel/apm.c Thu Sep 4 15:38:29 2003 +++ b/arch/i386/kernel/apm.c Thu Sep 4 15:38:29 2003 @@ -2080,4 +2080,4 @@ MODULE_PARM(smp, "i"); MODULE_PARM_DESC(smp, "Set this to enable APM use on an SMP platform. Use with caution on older systems"); - +MODULE_ALIAS_MISCDEV(APM_MINOR_DEV); diff -Nru a/arch/i386/kernel/cpu/mcheck/non-fatal.c b/arch/i386/kernel/cpu/mcheck/non-fatal.c --- a/arch/i386/kernel/cpu/mcheck/non-fatal.c Thu Sep 4 15:38:30 2003 +++ b/arch/i386/kernel/cpu/mcheck/non-fatal.c Thu Sep 4 15:38:30 2003 @@ -1,5 +1,5 @@ /* - * P4 specific Machine Check Exception Reporting + * Non Fatal Machine Check Exception Reporting */ #include 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 Thu Sep 4 15:38:30 2003 +++ b/arch/i386/kernel/cpu/mtrr/if.c Thu Sep 4 15:38:30 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 Thu Sep 4 15:38:29 2003 +++ b/arch/i386/kernel/cpu/mtrr/main.c Thu Sep 4 15:38:29 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 Thu Sep 4 15:38:30 2003 +++ b/arch/i386/kernel/cpu/mtrr/mtrr.h Thu Sep 4 15:38:30 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 Thu Sep 4 15:38:28 2003 +++ b/arch/i386/kernel/cpuid.c Thu Sep 4 15:38:28 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 Thu Sep 4 15:38:31 2003 +++ b/arch/i386/kernel/mpparse.c Thu Sep 4 15:38:31 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 Thu Sep 4 15:38:32 2003 +++ b/arch/i386/kernel/msr.c Thu Sep 4 15:38:32 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 Thu Sep 4 15:38:28 2003 +++ b/arch/i386/kernel/process.c Thu Sep 4 15:38:28 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 Thu Sep 4 15:38:33 2003 +++ b/arch/i386/kernel/setup.c Thu Sep 4 15:38:33 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 Thu Sep 4 15:38:33 2003 +++ b/arch/i386/kernel/time.c Thu Sep 4 15:38:33 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 Thu Sep 4 15:38:48 2003 @@ -0,0 +1,391 @@ +/* + * 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); + +#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) { + rtc_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 Thu Sep 4 15:38:28 2003 +++ b/arch/i386/kernel/timers/Makefile Thu Sep 4 15:38:28 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 Thu Sep 4 15:38:45 2003 +++ b/arch/i386/kernel/timers/timer.c Thu Sep 4 15:38:45 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 Thu Sep 4 15:38:48 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 Thu Sep 4 15:38:39 2003 +++ b/arch/i386/kernel/timers/timer_tsc.c Thu Sep 4 15:38:39 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 Thu Sep 4 15:38:30 2003 +++ b/arch/i386/kernel/traps.c Thu Sep 4 15:38:30 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 Thu Sep 4 15:38:31 2003 +++ b/arch/i386/mach-visws/mpparse.c Thu Sep 4 15:38:31 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 Thu Sep 4 15:38:32 2003 +++ b/arch/i386/mach-voyager/voyager_smp.c Thu Sep 4 15:38:32 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 Thu Sep 4 15:38:45 2003 +++ b/arch/ia64/Kconfig Thu Sep 4 15:38:45 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 Thu Sep 4 15:38:29 2003 +++ b/arch/ia64/Makefile Thu Sep 4 15:38:29 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 Thu Sep 4 15:38:30 2003 +++ b/arch/ia64/hp/common/sba_iommu.c Thu Sep 4 15:38:30 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 Thu Sep 4 15:38:40 2003 +++ b/arch/ia64/ia32/ia32_ioctl.c Thu Sep 4 15:38:40 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 Thu Sep 4 15:38:37 2003 +++ b/arch/ia64/ia32/sys_ia32.c Thu Sep 4 15:38:37 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 Thu Sep 4 15:38:33 2003 +++ b/arch/ia64/kernel/acpi.c Thu Sep 4 15:38:33 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 Thu Sep 4 15:38:31 2003 +++ b/arch/ia64/kernel/entry.S Thu Sep 4 15:38:31 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 Thu Sep 4 15:38:28 2003 +++ b/arch/ia64/kernel/fsys.S Thu Sep 4 15:38:28 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 Thu Sep 4 15:38:33 2003 +++ b/arch/ia64/kernel/mca.c Thu Sep 4 15:38:33 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 Thu Sep 4 15:38:45 2003 +++ b/arch/ia64/kernel/perfmon.c Thu Sep 4 15:38:45 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 Thu Sep 4 15:38:31 2003 +++ b/arch/ia64/kernel/smpboot.c Thu Sep 4 15:38:31 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 Thu Sep 4 15:38:36 2003 +++ b/arch/ia64/kernel/sys_ia64.c Thu Sep 4 15:38:36 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 Thu Sep 4 15:38:45 2003 +++ b/arch/ia64/lib/Makefile Thu Sep 4 15:38:45 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 Thu Sep 4 15:38:31 2003 +++ b/arch/ia64/mm/numa.c Thu Sep 4 15:38:31 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 Thu Sep 4 15:38:38 2003 +++ b/arch/ia64/sn/io/drivers/ioconfig_bus.c Thu Sep 4 15:38:38 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 Thu Sep 4 15:38:35 2003 +++ b/arch/ia64/sn/io/sn2/shub.c Thu Sep 4 15:38:35 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 Thu Sep 4 15:38:31 2003 +++ b/arch/ia64/sn/kernel/setup.c Thu Sep 4 15:38:31 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 Thu Sep 4 15:38:37 2003 +++ b/arch/m68k/Kconfig Thu Sep 4 15:38:37 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 Thu Sep 4 15:38:43 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 Thu Sep 4 15:38:28 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 Thu Sep 4 15:38:43 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 Thu Sep 4 15:38:28 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 Thu Sep 4 15:38:40 2003 +++ b/arch/m68knommu/Kconfig Thu Sep 4 15:38:40 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 Thu Sep 4 15:38:36 2003 +++ b/arch/m68knommu/platform/5206/config.c Thu Sep 4 15:38:36 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 Thu Sep 4 15:38:32 2003 +++ b/arch/m68knommu/platform/5206e/config.c Thu Sep 4 15:38:32 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 Thu Sep 4 15:38:36 2003 +++ b/arch/m68knommu/platform/5249/config.c Thu Sep 4 15:38:36 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 Thu Sep 4 15:38:31 2003 +++ b/arch/m68knommu/platform/5272/config.c Thu Sep 4 15:38:31 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 Thu Sep 4 15:38:33 2003 +++ b/arch/mips/Kconfig Thu Sep 4 15:38:33 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 Thu Sep 4 15:38:45 2003 +++ b/arch/mips/au1000/common/dma.c Thu Sep 4 15:38:45 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 Thu Sep 4 15:38:33 2003 +++ b/arch/mips/kernel/ioctl32.c Thu Sep 4 15:38:33 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 Thu Sep 4 15:38:41 2003 +++ b/arch/mips/sibyte/cfe/console.c Thu Sep 4 15:38:41 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 Thu Sep 4 15:38:32 2003 +++ b/arch/mips/sibyte/sb1250/bcm1250_tbprof.c Thu Sep 4 15:38:32 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 Thu Sep 4 15:38:46 2003 +++ b/arch/mips/tx4927/common/tx4927_irq.c Thu Sep 4 15:38:46 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 Thu Sep 4 15:38:32 2003 +++ b/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_irq.c Thu Sep 4 15:38:32 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 Thu Sep 4 15:38:39 2003 +++ b/arch/mips/vr41xx/common/vrc4173.c Thu Sep 4 15:38:39 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 Thu Sep 4 15:38:37 2003 +++ b/arch/parisc/Kconfig Thu Sep 4 15:38:37 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 Thu Sep 4 15:38:29 2003 +++ b/arch/parisc/kernel/ioctl32.c Thu Sep 4 15:38:29 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 Thu Sep 4 15:38:29 2003 +++ b/arch/ppc/8260_io/uart.c Thu Sep 4 15:38:29 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 Thu Sep 4 15:38:29 2003 +++ b/arch/ppc/8xx_io/cs4218_tdm.c Thu Sep 4 15:38:29 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 Thu Sep 4 15:38:40 2003 +++ b/arch/ppc/8xx_io/uart.c Thu Sep 4 15:38:40 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 Thu Sep 4 15:38:47 2003 +++ b/arch/ppc/Kconfig Thu Sep 4 15:38:47 2003 @@ -66,6 +66,9 @@ config 40x bool "40x" +config 44x + bool "44x" + config POWER3 bool "POWER3" @@ -74,6 +77,11 @@ endchoice +config PTE_64BIT + bool + depends on 44x + default y + source arch/ppc/platforms/4xx/Kconfig config 8260 @@ -766,8 +774,8 @@ RS/6000 machines are currently not supported by Linux. config PCI - bool "PCI support" if 4xx || 8260 - default y if !4xx && !8260 && !8xx && !APUS + bool "PCI support" if 40x || 8260 + default y if !40x && !8260 && !8xx && !APUS default PCI_PERMEDIA if !4xx && !8260 && !8xx && APUS default PCI_QSPAN if !4xx && !8260 && 8xx help @@ -795,22 +803,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 @@ -1159,6 +1151,7 @@ config BOOT_LOAD hex "Link/load address for booting" if BOOT_LOAD_BOOL default "0x00400000" if 40x || 8xx || 8260 + default "0x01000000" if 44x default "0x00800000" config PIN_TLB @@ -1277,16 +1270,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 +1414,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 +1439,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 +1462,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 Thu Sep 4 15:38:29 2003 +++ b/arch/ppc/Makefile Thu Sep 4 15:38:29 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) @@ -32,7 +29,7 @@ head-y := arch/ppc/kernel/head.o head-$(CONFIG_8xx) := arch/ppc/kernel/head_8xx.o head-$(CONFIG_4xx) := arch/ppc/kernel/head_4xx.o -head-$(CONFIG_440) := arch/ppc/kernel/head_44x.o +head-$(CONFIG_44x) := arch/ppc/kernel/head_44x.o head-$(CONFIG_6xx) += arch/ppc/kernel/idle_6xx.o diff -Nru a/arch/ppc/boot/common/ns16550.c b/arch/ppc/boot/common/ns16550.c --- a/arch/ppc/boot/common/ns16550.c Thu Sep 4 15:38:46 2003 +++ b/arch/ppc/boot/common/ns16550.c Thu Sep 4 15:38:46 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 Thu Sep 4 15:38:48 2003 +++ b/arch/ppc/boot/common/util.S Thu Sep 4 15:38:48 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 Thu Sep 4 15:38:29 2003 +++ b/arch/ppc/boot/include/of1275.h Thu Sep 4 15:38:29 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 Thu Sep 4 15:38:38 2003 +++ b/arch/ppc/boot/ld.script Thu Sep 4 15:38:38 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 Thu Sep 4 15:38:34 2003 +++ b/arch/ppc/boot/of1275/Makefile Thu Sep 4 15:38:34 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 Thu Sep 4 15:38:48 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 Thu Sep 4 15:38:43 2003 +++ b/arch/ppc/boot/of1275/ofinit.c Thu Sep 4 15:38:43 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 Thu Sep 4 15:38:31 2003 +++ b/arch/ppc/boot/openfirmware/Makefile Thu Sep 4 15:38:31 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 Thu Sep 4 15:38:35 2003 +++ b/arch/ppc/boot/openfirmware/coffmain.c Thu Sep 4 15:38:35 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 Thu Sep 4 15:38:36 2003 +++ b/arch/ppc/boot/openfirmware/misc.S Thu Sep 4 15:38:36 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 Thu Sep 4 15:38:28 2003 +++ b/arch/ppc/boot/simple/Makefile Thu Sep 4 15:38:28 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,95 @@ # 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 + end-$(CONFIG_EBONY) := ebony + entrypoint-$(CONFIG_EBONY) := 0x01000000 + tftpimage-$(CONFIG_EBONY) := /tftpboot/zImage.$(end-y) + + zimage-$(CONFIG_OCOTEA) := zImage-TREE +zimageinitrd-$(CONFIG_OCOTEA) := zImage.initrd-TREE + end-$(CONFIG_OCOTEA) := ocotea + entrypoint-$(CONFIG_OCOTEA) := 0x01000000 + tftpimage-$(CONFIG_OCOTEA) := /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 +168,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 Thu Sep 4 15:38:30 2003 +++ b/arch/ppc/boot/simple/embed_config.c Thu Sep 4 15:38:30 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 Thu Sep 4 15:38:30 2003 +++ b/arch/ppc/boot/simple/misc-embedded.c Thu Sep 4 15:38:30 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 Thu Sep 4 15:38:35 2003 +++ b/arch/ppc/boot/simple/misc-spruce.c Thu Sep 4 15:38:35 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 Thu Sep 4 15:38:42 2003 +++ b/arch/ppc/boot/simple/misc.c Thu Sep 4 15:38:42 2003 @@ -25,6 +25,9 @@ #include #include #include +#ifdef CONFIG_44x +#include +#endif #include "nonstdio.h" #include "zlib.h" @@ -80,6 +83,16 @@ serial_fixups(); com_port = serial_init(0, NULL); +#ifdef CONFIG_44x + /* Reset MAL */ + mtdcr(DCRN_MALCR(DCRN_MAL_BASE), MALCR_MMSR); + /* Wait for reset */ + while (mfdcr(DCRN_MALCR(DCRN_MAL_BASE)) & MALCR_MMSR) {}; + /* Reset EMAC */ + *(volatile unsigned long *)PPC44x_EMAC0_MR0 = 0x20000000; + __asm__ __volatile__("eieio"); +#endif + #if defined(CONFIG_LOPEC) || defined(CONFIG_PAL4) /* * Call get_mem_size(), which is memory controller dependent, @@ -251,4 +264,11 @@ serial_close(com_port); 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 Thu Sep 4 15:38:32 2003 +++ b/arch/ppc/boot/simple/relocate.S Thu Sep 4 15:38:32 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 Thu Sep 4 15:38:43 2003 +++ b/arch/ppc/boot/utils/mktree.c Thu Sep 4 15:38:43 2003 @@ -86,7 +86,7 @@ } cksum = 0; - cp = (uint *)&bt; + cp = (void *)&bt; for (i=0; i + * + * Copyright 2002-2003 MontaVista Software, 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 (at your + * option) any later version. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * Macros + */ + +#define SET_IVOR(vector_number, vector_label) \ + li r26,vector_label@l; \ + mtspr SPRN_IVOR##vector_number,r26; \ + sync + +/* As with the other PowerPC ports, it is expected that when code + * execution begins here, the following registers contain valid, yet + * optional, information: + * + * r3 - Board info structure pointer (DRAM, frequency, MAC address, etc.) + * r4 - Starting address of the init RAM disk + * r5 - Ending address of the init RAM disk + * r6 - Start of kernel command line string (e.g. "mem=128") + * r7 - End of kernel command line string + * + */ + .text +_GLOBAL(_stext) +_GLOBAL(_start) + /* + * Reserve a word at a fixed location to store the address + * of abatron_pteptrs + */ + nop +/* + * Save parameters we are passed + */ + mr r31,r3 + mr r30,r4 + mr r29,r5 + mr r28,r6 + mr r27,r7 + li r24,0 /* CPU number */ + +/* + * Set up the initial MMU state + * + * We are still executing code at the virtual address + * mappings set by the firmware for the base of RAM. + * + * We first invalidate all TLB entries but the one + * we are running from. We then load the KERNELBASE + * mappings so we can begin to use kernel addresses + * natively and so the interrupt vector locations are + * permanently pinned (necessary since Book E + * implementations always have translation enabled). + * + * TODO: Use the known TLB entry we are running from to + * determine which physical region we are located + * in. This can be used to determine where in RAM + * (on a shared CPU system) or PCI memory space + * (on a DRAMless system) we are located. + * For now, we assume a perfect world which means + * we are located at the base of DRAM (physical 0). + */ + +/* + * Search TLB for entry that we are currently using. + * Invalidate all entries but the one we are using. + */ + /* Load our current PID->MMUCR TID and MSR IS->MMUCR STS */ + mfspr r3,SPRN_MMUCR /* Get MMUCR */ + lis r4,PPC44x_MMUCR_STS@h + ori r4,r4,PPC44x_MMUCR_TID@l /* Create mask */ + andc r3,r3,r4 /* Clear out TID/STS bits */ + mfspr r4,SPRN_PID /* Get PID */ + or r3,r3,r4 /* Set TID bits */ + mfmsr r5 /* Get MSR */ + andi. r5,r5,MSR_IS@l /* TS=1? */ + beq wmmucr /* If not, leave STS=0 */ + oris r3,r3,PPC44x_MMUCR_STS@h /* Set STS=1 */ +wmmucr: mtspr SPRN_MMUCR,r3 /* Put MMUCR */ + sync + + bl invstr /* Find our address */ +invstr: mflr r5 /* Make it accessible */ + tlbsx r23,0,r5 /* Find entry we are in */ + li r4,0 /* Start at TLB entry 0 */ + li r3,0 /* Set PAGEID inval value */ +1: cmpw r23,r4 /* Is this our entry? */ + beq skpinv /* If so, skip the inval */ + tlbwe r3,r4,PPC44x_TLB_PAGEID /* If not, inval the entry */ +skpinv: addi r4,r4,1 /* Increment */ + cmpwi r4,64 /* Are we done? */ + bne 1b /* If not, repeat */ + isync /* If so, context change */ + +/* + * Configure and load pinned entries into TLB slots 62 and 63. + */ + + lis r3,KERNELBASE@h /* Load the kernel virtual address */ + ori r3,r3,KERNELBASE@l + + /* Kernel is at the base of RAM */ + li r4, 0 /* Load the kernel physical address */ + + /* Load the kernel PID = 0 */ + li r0,0 + mtspr SPRN_PID,r0 + sync + + /* Load the kernel TID = 0 */ + mfspr r5,SPRN_MMUCR + lis r6, PPC44x_MMUCR_TID@h + ori r6,r6,PPC44x_MMUCR_TID@l + andc r5,r5,r6 + mtspr SPRN_MMUCR,r5 + sync + + /* pageid fields */ + clrrwi r3,r3,10 /* Mask off the effective page number */ + ori r3,r3,(PPC44x_TLB_VALID | PPC44x_TLB_PAGESZ(PPC44x_PAGESZ_256M)) + + /* xlat fields */ + clrrwi r4,r4,10 /* Mask off the real page number */ + /* ERPN is 0 for first 4GB page */ + + /* attrib fields */ + /* Added guarded bit to protect against speculative loads/stores */ + li r5,0 + ori r5,r5,(PPC44x_TLB_SW | PPC44x_TLB_SR | PPC44x_TLB_SX | PPC44x_TLB_G) + + li r0,62 /* TLB slot 62 */ + + tlbwe r3,r0,PPC44x_TLB_PAGEID /* Load the pageid fields */ + tlbwe r4,r0,PPC44x_TLB_XLAT /* Load the translation fields */ + tlbwe r5,r0,PPC44x_TLB_ATTRIB /* Load the attrib/access fields */ + + /* Force context change */ + mfmsr r0 + mtspr SRR1, r0 + lis r0,3f@h + ori r0,r0,3f@l + mtspr SRR0,r0 + sync + rfi + + /* If necessary, invalidate original entry we used */ +3: cmpwi r23,62 + beq 4f + li r6,0 + tlbwe r6,r23,PPC44x_TLB_PAGEID + sync + +4: ori r3,r3,PPC44x_TLB_TS /* TS = 1 */ + + li r0,63 /* TLB slot 63 */ + + tlbwe r3,r0,PPC44x_TLB_PAGEID /* Load the pageid fields */ + tlbwe r4,r0,PPC44x_TLB_XLAT /* Load the translation fields */ + tlbwe r5,r0,PPC44x_TLB_ATTRIB /* Load the attrib/access fields */ + +#ifdef CONFIG_SERIAL_TEXT_DEBUG + /* + * Add temporary UART mapping for early debug. This + * mapping must be identical to that used by the early + * bootloader code since the same asm/serial.h parameters + * are used for polled operation. + */ + /* pageid fields */ + lis r3,0xe000 + ori r3,r3,(PPC44x_TLB_VALID | PPC44x_TLB_PAGESZ(PPC44x_PAGESZ_256M)) + + /* xlat fields */ + lis r4,0x4000 /* RPN is 0x40000000 */ + ori r4,r4,0x0001 /* ERPN is 1 for second 4GB page */ + + /* attrib fields */ + li r5,0 + ori r5,r5,(PPC44x_TLB_SW | PPC44x_TLB_SR | PPC44x_TLB_I | PPC44x_TLB_G) + + li r0,60 /* TLB slot 60 */ + + tlbwe r3,r0,PPC44x_TLB_PAGEID /* Load the pageid fields */ + tlbwe r4,r0,PPC44x_TLB_XLAT /* Load the translation fields */ + tlbwe r5,r0,PPC44x_TLB_ATTRIB /* Load the attrib/access fields */ + + ori r3,r3,PPC44x_TLB_TS /* Translation state 1 */ + + li r0,61 /* TLB slot 61 */ + + tlbwe r3,r0,PPC44x_TLB_PAGEID /* Load the pageid fields */ + tlbwe r4,r0,PPC44x_TLB_XLAT /* Load the translation fields */ + tlbwe r5,r0,PPC44x_TLB_ATTRIB /* Load the attrib/access fields */ +#endif /* CONFIG_SERIAL_TEXT_DEBUG */ + + /* Force context change */ + isync + + /* Establish the interrupt vector offsets */ + SET_IVOR(0, CriticalInput); + SET_IVOR(1, MachineCheck); + SET_IVOR(2, DataStorage); + SET_IVOR(3, InstructionStorage); + SET_IVOR(4, ExternalInput); + SET_IVOR(5, Alignment); + SET_IVOR(6, Program); + SET_IVOR(7, FloatingPointUnavailable); + SET_IVOR(8, SystemCall); + SET_IVOR(9, AuxillaryProcessorUnavailable); + SET_IVOR(10, Decrementer); + SET_IVOR(11, FixedIntervalTimer); + SET_IVOR(12, WatchdogTimer); + SET_IVOR(13, DataTLBError); + SET_IVOR(14, InstructionTLBError); + SET_IVOR(15, Debug); + + /* Establish the interrupt vector base */ + lis r4,interrupt_base@h /* IVPR only uses the high 16-bits */ + mtspr SPRN_IVPR,r4 + + /* + * This is where the main kernel code starts. + */ + + /* ptr to current */ + lis r2,init_task@h + ori r2,r2,init_task@l + + /* ptr to current thread */ + addi r4,r2,THREAD /* init task's THREAD */ + mtspr SPRG3,r4 + + /* stack */ + lis r1,init_thread_union@h + ori r1,r1,init_thread_union@l + li r0,0 + stwu r0,THREAD_SIZE-STACK_FRAME_OVERHEAD(r1) + + bl early_init + +/* + * Decide what sort of machine this is and initialize the MMU. + */ + mr r3,r31 + mr r4,r30 + mr r5,r29 + mr r6,r28 + mr r7,r27 + bl machine_init + bl MMU_init + + /* Setup PTE pointers for the Abatron bdiGDB */ + lis r6, swapper_pg_dir@h + ori r6, r6, swapper_pg_dir@l + lis r5, abatron_pteptrs@h + ori r5, r5, abatron_pteptrs@l + lis r4, KERNELBASE@h + ori r4, r4, KERNELBASE@l + stw r5, 0(r4) /* Save abatron_pteptrs at a fixed location */ + stw r6, 0(r5) + + /* Let's move on */ + lis r4,start_kernel@h + ori r4,r4,start_kernel@l + lis r3,MSR_KERNEL@h + ori r3,r3,MSR_KERNEL@l + mtspr SRR0,r4 + mtspr SRR1,r3 + rfi /* change context and jump to start_kernel */ + +/* + * Interrupt vector entry code + * + * The Book E MMUs are always on so we don't need to handle + * interrupts in real mode as with previous PPC processors. In + * this case we handle interrupts in the kernel virtual address + * space. + * + * Interrupt vectors are dynamically placed relative to the + * interrupt prefix as determined by the address of interrupt_base. + * The interrupt vectors offsets are programmed using the labels + * for each interrupt vector entry. + * + * Interrupt vectors must be aligned on a 16 byte boundary. + * We align on a 32 byte cache line boundary for good measure. + */ + +#define NORMAL_EXCEPTION_PROLOG \ + mtspr SPRN_SPRG0,r10; /* save two registers to work with */\ + mtspr SPRN_SPRG1,r11; \ + mtspr SPRN_SPRG2,r1; \ + mfcr r10; /* save CR in r10 for now */\ + mfspr r11,SPRN_SRR1; /* check whether user or kernel */\ + andi. r11,r11,MSR_PR; \ + beq 1f; \ + mfspr r1,SPRG3; /* if from user, start at top of */\ + lwz r1,THREAD_INFO-THREAD(r1); /* this thread's kernel stack */\ + addi r1,r1,THREAD_SIZE; \ +1: subi r1,r1,INT_FRAME_SIZE; /* Allocate an exception frame */\ + tophys(r11,r1); \ + stw r10,_CCR(r11); /* save various registers */\ + stw r12,GPR12(r11); \ + stw r9,GPR9(r11); \ + mfspr r10,SPRG0; \ + stw r10,GPR10(r11); \ + mfspr r12,SPRG1; \ + stw r12,GPR11(r11); \ + mflr r10; \ + stw r10,_LINK(r11); \ + mfspr r10,SPRG2; \ + mfspr r12,SRR0; \ + stw r10,GPR1(r11); \ + mfspr r9,SRR1; \ + stw r10,0(r11); \ + rlwinm r9,r9,0,14,12; /* clear MSR_WE (necessary?) */\ + stw r0,GPR0(r11); \ + SAVE_4GPRS(3, r11); \ + SAVE_2GPRS(7, r11) + +/* + * Exception prolog for critical exceptions. This is a little different + * from the normal exception prolog above since a critical exception + * can potentially occur at any point during normal exception processing. + * Thus we cannot use the same SPRG registers as the normal prolog above. + * Instead we use a couple of words of memory at low physical addresses. + * This is OK since we don't support SMP on these processors. + */ +/* XXX but we don't have RAM mapped at 0 in space 0 -- paulus. */ +#define CRITICAL_EXCEPTION_PROLOG \ + stw r10,crit_r10@l(0); /* save two registers to work with */\ + stw r11,crit_r11@l(0); \ + mfspr r10,SPRG0; \ + stw r10,crit_sprg0@l(0); \ + mfspr r10,SPRG1; \ + stw r10,crit_sprg1@l(0); \ + mfspr r10,SPRG4R; \ + stw r10,crit_sprg4@l(0); \ + mfspr r10,SPRG5R; \ + stw r10,crit_sprg5@l(0); \ + mfspr r10,SPRG6R; \ + stw r10,crit_sprg6@l(0); \ + mfspr r10,SPRG7R; \ + stw r10,crit_sprg7@l(0); \ + mfspr r10,SPRN_PID; \ + stw r10,crit_pid@l(0); \ + mfspr r10,SRR0; \ + stw r10,crit_srr0@l(0); \ + mfspr r10,SRR1; \ + stw r10,crit_srr1@l(0); \ + mfcr r10; /* save CR in r10 for now */\ + mfspr r11,SPRN_CSRR1; /* check whether user or kernel */\ + andi. r11,r11,MSR_PR; \ + lis r11,critical_stack_top@h; \ + ori r11,r11,critical_stack_top@l; \ + beq 1f; \ + /* COMING FROM USER MODE */ \ + mfspr r11,SPRG3; /* if from user, start at top of */\ + lwz r11,THREAD_INFO-THREAD(r11); /* this thread's kernel stack */\ + addi r11,r11,THREAD_SIZE; \ +1: subi r11,r11,INT_FRAME_SIZE; /* Allocate an exception frame */\ + tophys(r11,r11); \ + stw r10,_CCR(r11); /* save various registers */\ + stw r12,GPR12(r11); \ + stw r9,GPR9(r11); \ + mflr r10; \ + stw r10,_LINK(r11); \ + mfspr r12,SPRN_DEAR; /* save DEAR and ESR in the frame */\ + stw r12,_DEAR(r11); /* since they may have had stuff */\ + mfspr r9,SPRN_ESR; /* in them at the point where the */\ + stw r9,_ESR(r11); /* exception was taken */\ + mfspr r12,CSRR0; \ + stw r1,GPR1(r11); \ + mfspr r9,CSRR1; \ + stw r1,0(r11); \ + tovirt(r1,r11); \ + rlwinm r9,r9,0,14,12; /* clear MSR_WE (necessary?) */\ + stw r0,GPR0(r11); \ + SAVE_4GPRS(3, r11); \ + SAVE_2GPRS(7, r11) + +/* + * Exception vectors. + */ +#define START_EXCEPTION(label) \ + .align 5; \ +label: + +#define FINISH_EXCEPTION(func) \ + bl transfer_to_handler_full; \ + .long func; \ + .long ret_from_except_full + +#define EXCEPTION(n, label, hdlr, xfer) \ + START_EXCEPTION(label); \ + NORMAL_EXCEPTION_PROLOG; \ + addi r3,r1,STACK_FRAME_OVERHEAD; \ + xfer(n, hdlr) + +#define CRITICAL_EXCEPTION(n, label, hdlr) \ + START_EXCEPTION(label); \ + CRITICAL_EXCEPTION_PROLOG; \ + addi r3,r1,STACK_FRAME_OVERHEAD; \ + EXC_XFER_TEMPLATE(hdlr, n+2, (MSR_KERNEL & ~(MSR_ME|MSR_DE|MSR_CE)), \ + NOCOPY, transfer_to_handler_full, \ + ret_from_except_full) + +#define EXC_XFER_TEMPLATE(hdlr, trap, msr, copyee, tfer, ret) \ + li r10,trap; \ + stw r10,TRAP(r11); \ + lis r10,msr@h; \ + ori r10,r10,msr@l; \ + copyee(r10, r9); \ + bl tfer; \ + .long hdlr; \ + .long ret + +#define COPY_EE(d, s) rlwimi d,s,0,16,16 +#define NOCOPY(d, s) + +#define EXC_XFER_STD(n, hdlr) \ + EXC_XFER_TEMPLATE(hdlr, n, MSR_KERNEL, NOCOPY, transfer_to_handler_full, \ + ret_from_except_full) + +#define EXC_XFER_LITE(n, hdlr) \ + EXC_XFER_TEMPLATE(hdlr, n+1, MSR_KERNEL, NOCOPY, transfer_to_handler, \ + ret_from_except) + +#define EXC_XFER_EE(n, hdlr) \ + EXC_XFER_TEMPLATE(hdlr, n, MSR_KERNEL, COPY_EE, transfer_to_handler_full, \ + ret_from_except_full) + +#define EXC_XFER_EE_LITE(n, hdlr) \ + EXC_XFER_TEMPLATE(hdlr, n+1, MSR_KERNEL, COPY_EE, transfer_to_handler, \ + ret_from_except) + +interrupt_base: + /* Critical Input Interrupt */ + CRITICAL_EXCEPTION(0x0100, CriticalInput, UnknownException) + + /* Machine Check Interrupt */ + CRITICAL_EXCEPTION(0x0200, MachineCheck, MachineCheckException) + + /* Data Storage Interrupt */ + START_EXCEPTION(DataStorage) + mtspr SPRG0, r10 /* Save some working registers */ + mtspr SPRG1, r11 + mtspr SPRG4W, r12 + mtspr SPRG5W, r13 + mtspr SPRG6W, r14 + mfcr r11 + mtspr SPRG7W, r11 + + /* + * Check if it was a store fault, if not then bail + * because a user tried to access a kernel or + * read-protected page. Otherwise, get the + * offending address and handle it. + */ + mfspr r10, SPRN_ESR + andis. r10, r10, ESR_ST@h + beq 2f + + mfspr r10, SPRN_DEAR /* Get faulting address */ + + /* If we are faulting a kernel address, we have to use the + * kernel page tables. + */ + andis. r11, r10, 0x8000 + beq 3f + lis r11, swapper_pg_dir@h + ori r11, r11, swapper_pg_dir@l + + mfspr r12,SPRN_MMUCR /* Set TID to 0 */ + li r13,PPC44x_MMUCR_TID@l + andc r12,r12,r13 + mtspr SPRN_MMUCR,r12 + + b 4f + + /* Get the PGD for the current thread */ +3: + mfspr r11,SPRG3 + lwz r11,PGDIR(r11) + + /* Load MMUCR with our PID and STS= */ + mfspr r12,SPRN_MMUCR /* Get MMUCR */ + lis r13,PPC44x_MMUCR_STS@h + ori r13,r13,PPC44x_MMUCR_TID@l /* Create mask */ + andc r12,r12,r13 /* Clear out TID/STS bits */ + mfspr r13,SPRN_PID /* Get PID */ + or r12,r12,r13 /* Set TID bits */ + mfspr r14,SPRN_SRR1 /* Get SRR1 */ + andi. r14,r14,MSR_IS@l /* TS=1? */ + beq 4f /* If not, leave STS=0 */ + oris r12,r12,PPC44x_MMUCR_STS@h /* Set STS=1 */ + mtspr SPRN_MMUCR,r12 +4: + rlwinm r12, r10, 13, 19, 29 /* Compute pgdir/pmd offset */ + lwzx r11, r12, r11 /* Get pgd/pmd entry */ + rlwinm. r12, r11, 0, 0, 20 /* Extract pt base address */ + beq 2f /* Bail if no table */ + + rlwimi r12, r10, 23, 20, 28 /* Compute pte address */ + lwz r11, 4(r12) /* Get pte entry */ + + andi. r13, r11, _PAGE_RW /* Is it writeable? */ + beq 2f /* Bail if not */ + + /* Update 'changed'. + */ + ori r11, r11, _PAGE_DIRTY|_PAGE_ACCESSED|_PAGE_HWWRITE + stw r11, 4(r12) /* Update Linux page table */ + + /* FIXME: Staticly setting some permissions */ + li r13, 0x003f /* Set UX,UW,UR,SX,SW,SR */ + andi. r11,r11,0xffff /* Clear MS 16 bits */ + /* FIXME: Force attributes */ + ori r11,r11, 0x0100 /* Set G */ + /* FIXME: Already set in PTE */ + rlwimi r11,r13,0,26,31 /* Insert static perms */ + + lis r13,0xffff + ori r13,r13,0x0fff /* Set U0-U3 mask */ + and r11,r11,r13 /* Clear U0-U3 */ + + /* find the TLB index that caused the fault. It has to be here. */ + tlbsx r14, 0, r10 + + tlbwe r11, r14, PPC44x_TLB_ATTRIB /* Write ATTRIB */ + + /* Done...restore registers and get out of here. + */ + mfspr r11, SPRG7R + mtcr r11 + mfspr r14, SPRG6R + mfspr r13, SPRG5R + mfspr r12, SPRG4R + + mfspr r11, SPRG1 + mfspr r10, SPRG0 + rfi /* Force context change */ + +2: + /* + * The bailout. Restore registers to pre-exception conditions + * and call the heavyweights to help us out. + */ + mfspr r11, SPRG7R + mtcr r11 + mfspr r14, SPRG6R + mfspr r13, SPRG5R + mfspr r12, SPRG4R + + mfspr r11, SPRG1 + mfspr r10, SPRG0 + b data_access + + /* Instruction Storage Interrupt */ + START_EXCEPTION(InstructionStorage) + NORMAL_EXCEPTION_PROLOG + mr r4,r12 /* Pass SRR0 as arg2 */ + li r5,0 /* Pass zero as arg3 */ + addi r3,r1,STACK_FRAME_OVERHEAD + EXC_XFER_EE_LITE(0x0400, do_page_fault) + + /* External Input Interrupt */ + EXCEPTION(0x0500, ExternalInput, do_IRQ, EXC_XFER_LITE) + + /* Alignment Interrupt */ + START_EXCEPTION(Alignment) + NORMAL_EXCEPTION_PROLOG + mfspr r4,SPRN_DEAR /* Grab the DEAR and save it */ + stw r4,_DEAR(r11) + addi r3,r1,STACK_FRAME_OVERHEAD + EXC_XFER_EE(0x0600, AlignmentException) + + /* Program Interrupt */ + START_EXCEPTION(Program) + NORMAL_EXCEPTION_PROLOG + mfspr r4,SPRN_ESR /* Grab the ESR and save it */ + stw r4,_ESR(r11) + addi r3,r1,STACK_FRAME_OVERHEAD + EXC_XFER_EE(0x700, ProgramCheckException) + + /* Floating Point Unavailable Interrupt */ + EXCEPTION(0x2010, FloatingPointUnavailable, UnknownException, EXC_XFER_EE) + + /* System Call Interrupt */ + START_EXCEPTION(SystemCall) + NORMAL_EXCEPTION_PROLOG + EXC_XFER_EE_LITE(0x0c00, DoSyscall) + + /* Auxillary Processor Unavailable Interrupt */ + EXCEPTION(0x2020, AuxillaryProcessorUnavailable, UnknownException, EXC_XFER_EE) + + /* Decrementer Interrupt */ + START_EXCEPTION(Decrementer) + NORMAL_EXCEPTION_PROLOG + lis r0,TSR_DIS@h /* Setup the DEC interrupt mask */ + mtspr SPRN_TSR,r0 /* Clear the DEC interrupt */ + addi r3,r1,STACK_FRAME_OVERHEAD + EXC_XFER_LITE(0x1000, timer_interrupt) + + /* Fixed Internal Timer Interrupt */ + /* TODO: Add FIT support */ + EXCEPTION(0x1010, FixedIntervalTimer, UnknownException, EXC_XFER_EE) + + /* Watchdog Timer Interrupt */ + /* TODO: Add watchdog support */ + CRITICAL_EXCEPTION(0x1020, WatchdogTimer, UnknownException) + + /* Data TLB Error Interrupt */ + START_EXCEPTION(DataTLBError) + mtspr SPRG0, r10 /* Save some working registers */ + mtspr SPRG1, r11 + mtspr SPRG4W, r12 + mtspr SPRG5W, r13 + mtspr SPRG6W, r14 + mfcr r11 + mtspr SPRG7W, r11 + mfspr r10, SPRN_DEAR /* Get faulting address */ + + /* If we are faulting a kernel address, we have to use the + * kernel page tables. + */ + andis. r11, r10, 0x8000 + beq 3f + lis r11, swapper_pg_dir@h + ori r11, r11, swapper_pg_dir@l + + mfspr r12,SPRN_MMUCR /* Set TID to 0 */ + li r13,PPC44x_MMUCR_TID@l + andc r12,r12,r13 + mtspr SPRN_MMUCR,r12 + + b 4f + + /* Get the PGD for the current thread */ +3: + mfspr r11,SPRG3 + lwz r11,PGDIR(r11) + + /* Load PID into MMUCR TID */ + li r13,PPC44x_MMUCR_TID@l /* Create mask */ + andc r12,r12,r13 /* Clear out TID/STS bits */ + mfspr r13,SPRN_PID /* Get PID */ + or r12,r12,r13 + mtspr SPRN_MMUCR,r12 +4: + rlwinm r12, r10, 13, 19, 29 /* Compute pgdir/pmd offset */ + lwzx r11, r12, r11 /* Get pgd/pmd entry */ + rlwinm. r12, r11, 0, 0, 20 /* Extract pt base address */ + beq 2f /* Bail if no table */ + + rlwimi r12, r10, 23, 20, 28 /* Compute pte address */ + lwz r11, 4(r12) /* Get pte entry */ + andi. r13, r11, _PAGE_PRESENT /* Is the page present? */ + beq 2f /* Bail if not present */ + + ori r11, r11, _PAGE_ACCESSED + stw r11, 4(r12) + + /* Jump to common tlb load */ + b finish_tlb_load + +2: + /* The bailout. Restore registers to pre-exception conditions + * and call the heavyweights to help us out. + */ + mfspr r11, SPRG7R + mtcr r11 + mfspr r14, SPRG6R + mfspr r13, SPRG5R + mfspr r12, SPRG4R + mfspr r11, SPRG1 + mfspr r10, SPRG0 + b data_access + + /* Instruction TLB Error Interrupt */ + /* + * Nearly the same as above, except we get our + * information from different registers and bailout + * to a different point. + */ + START_EXCEPTION(InstructionTLBError) + mtspr SPRG0, r10 /* Save some working registers */ + mtspr SPRG1, r11 + mtspr SPRG4W, r12 + mtspr SPRG5W, r13 + mtspr SPRG6W, r14 + mfcr r11 + mtspr SPRG7W, r11 + mfspr r10, SRR0 /* Get faulting address */ + + /* If we are faulting a kernel address, we have to use the + * kernel page tables. + */ + andis. r11, r10, 0x8000 + beq 3f + lis r11, swapper_pg_dir@h + ori r11, r11, swapper_pg_dir@l + + mfspr r12,SPRN_MMUCR /* Set TID to 0 */ + li r13,PPC44x_MMUCR_TID@l + andc r12,r12,r13 + mtspr SPRN_MMUCR,r12 + + b 4f + + /* Get the PGD for the current thread */ +3: + mfspr r11,SPRG3 + lwz r11,PGDIR(r11) + + /* Load PID into MMUCR TID */ + li r13,PPC44x_MMUCR_TID@l /* Create mask */ + andc r12,r13,r13 /* Clear out TID/STS bits */ + mfspr r13,SPRN_PID /* Get PID */ + or r12,r12,r13 + mtspr SPRN_MMUCR,r12 + +4: + rlwinm r12, r10, 13, 19, 29 /* Compute pgdir/pmd offset */ + lwzx r11, r12, r11 /* Get pgd/pmd entry */ + rlwinm. r12, r11, 0, 0, 20 /* Extract pt base address */ + beq 2f /* Bail if no table */ + + rlwimi r12, r10, 23, 20, 28 /* Compute pte address */ + lwz r11, 4(r12) /* Get pte entry */ + andi. r13, r11, _PAGE_PRESENT /* Is the page present? */ + beq 2f /* Bail if not present */ + + ori r11, r11, _PAGE_ACCESSED + stw r11, 4(r12) + + /* Jump to common TLB load point */ + b finish_tlb_load + +2: + /* The bailout. Restore registers to pre-exception conditions + * and call the heavyweights to help us out. + */ + mfspr r11, SPRG7R + mtcr r11 + mfspr r14, SPRG6R + mfspr r13, SPRG5R + mfspr r12, SPRG4R + mfspr r11, SPRG1 + mfspr r10, SPRG0 + b InstructionStorage + +/* Check for a single step debug exception while in an exception + * handler before state has been saved. This is to catch the case + * where an instruction that we are trying to single step causes + * an exception (eg ITLB/DTLB miss) and thus the first instruction of + * the exception handler generates a single step debug exception. + * + * If we get a debug trap on the first instruction of an exception handler, + * we reset the MSR_DE in the _exception handler's_ MSR (the debug trap is + * a critical exception, so we are using SPRN_CSRR1 to manipulate the MSR). + * The exception handler was handling a non-critical interrupt, so it will + * save (and later restore) the MSR via SPRN_SRR1, which will still have + * the MSR_DE bit set. + */ + /* Debug Interrupt */ + CRITICAL_EXCEPTION(0x2000, Debug, DebugException) +#if 0 + START_EXCEPTION(Debug) + /* This first instruction was already executed by the exception + * handler and must be the first instruction of every exception + * handler. + */ + mtspr SPRN_SPRG0,r10 /* Save some working registers... */ + mtspr SPRN_SPRG1,r11 + mtspr SPRN_SPRG4W,r12 + mfcr r10 /* ..and the cr because we change it */ + + mfspr r11,SPRN_CSRR1 /* MSR at the time of fault */ + andi. r11,r11,MSR_PR + bne+ 2f /* trapped from problem state */ + + mfspr r11,SPRN_CSRR0 /* Faulting instruction address */ + lis r12, KERNELBASE@h + ori r12, r12, KERNELBASE@l + cmplw r11,r12 + blt+ 2f /* addr below exception vectors */ + + lis r12, Debug@h + ori r12, r12, Debug@l + cmplw r11,r12 + bgt+ 2f /* addr above TLB exception vectors */ + + lis r11,DBSR_IC@h /* Remove the trap status */ + mtspr SPRN_DBSR,r11 + + mfspr r11,SPRN_CSRR1 + rlwinm r11,r11,0,23,21 /* clear MSR_DE */ + mtspr SPRN_CSRR1, r11 /* restore MSR at rcfi without DE */ + + mtcrf 0xff,r10 /* restore registers */ + mfspr r12,SPRN_SPRG4R + mfspr r11,SPRN_SPRG1 + mfspr r10,SPRN_SPRG0 + + sync + rfci /* return to the exception handler */ + b . /* prevent prefetch past rfci */ + +2: + mtcrf 0xff,r10 /* restore registers */ + mfspr r12,SPRN_SPRG4R + mfspr r11,SPRN_SPRG1 + mfspr r10,SPRN_SPRG0 + + CRIT_EXCEPTION_PROLOG + addi r3,r1,STACK_FRAME_OVERHEAD + li r7,CRIT_EXC; + li r9,MSR_KERNEL + FINISH_EXCEPTION(DebugException) +#endif + +/* + * Local functions + */ + /* + * Data TLB exceptions will bail out to this point + * if they can't resolve the lightweight TLB fault. + */ +data_access: + NORMAL_EXCEPTION_PROLOG + mfspr r5,SPRN_ESR /* Grab the ESR, save it, pass arg3 */ + stw r5,_ESR(r11) + mfspr r4,SPRN_DEAR /* Grab the DEAR, save it, pass arg2 */ + stw r4,_DEAR(r11) + addi r3,r1,STACK_FRAME_OVERHEAD + EXC_XFER_EE_LITE(0x0300, do_page_fault) + +/* + + * Both the instruction and data TLB miss get to this + * point to load the TLB. + * r10 - EA of fault + * r11 - available to use + * r12 - Pointer to the 64-bit PTE + * r13 - available to use + * r14 - available to use + * MMUCR - loaded with proper value when we get here + * Upon exit, we reload everything and RFI. + */ +finish_tlb_load: + /* + * We set execute, because we don't have the granularity to + * properly set this at the page level (Linux problem). + * If shared is set, we cause a zero PID->TID load. + * Many of these bits are software only. Bits we don't set + * here we (properly should) assume have the appropriate value. + */ + + /* Load the next available TLB index */ + lis r13, tlb_44x_index@h + ori r13, r13, tlb_44x_index@l + lwz r14, 0(r13) + /* Load the TLB high watermark */ + lis r13, tlb_44x_hwater@h + ori r13, r13, tlb_44x_hwater@l + lwz r11, 0(r13) + + + /* Increment, rollover, and store TLB index */ + addi r14, r14, 1 + cmpw 0, r14, r11 /* reserve entries 62-63 for kernel */ + ble 7f + li r14, 0 +7: + /* Load the next available TLB index */ + lis r13, tlb_44x_index@h + ori r13, r13, tlb_44x_index@l + stw r14, 0(r13) + +6: + lwz r13, 0(r12) /* Get MS word of PTE */ + lwz r11, 4(r12) /* Get LS word of PTE */ + rlwimi r13, r11, 0, 0 , 19 /* Insert RPN */ + tlbwe r13, r14, PPC44x_TLB_XLAT /* Write XLAT */ + + /* + * Create PAGEID. This is the faulting address plus + * a set of static bits. The static bits are page + * size and valid. Bits 20 and 21 should be zero + * for a page size of 4KB. + */ + li r12, 0x0210 /* Set size and valid */ + mfspr r13, SPRN_SRR1 /* Get SRR1 */ + andi. r13, r13, MSR_IS@l + beq 7f + ori r12, r12, PPC44x_TLB_TS@l /* Set TS=1 */ +7: rlwimi r10, r12, 0, 20, 31 /* Insert statics */ + tlbwe r10, r14, PPC44x_TLB_PAGEID /* Write PAGEID */ + + /* FIXME: Staticly setting some permissions */ + li r13, 0x002d /* Set UX,UR,SX,SR */ + andi. r11, r11, 0xffff /* Clear MS 16 bits */ + andi. r12, r11, 0x0002 /* _PAGE_HWWRITE? */ + beq 8f + ori r13, r13, 0x0002 /* Set SW */ + /* FIXME: Force attributes */ +8: ori r11, r11, 0x0100 /* Set G */ + /* FIXME: Already set in PTE */ + rlwimi r11, r13, 0, 26, 31 /* Insert static perms */ + + lis r13,0xffff + ori r13,r13,0x0fff /* Set U0-U3 mask */ + and r11,r11,r13 /* Clear U0-U3 */ + tlbwe r11, r14, PPC44x_TLB_ATTRIB /* Write ATTRIB */ + + /* Done...restore registers and get out of here. + */ + mfspr r11, SPRG7R + mtcr r11 + mfspr r14, SPRG6R + mfspr r13, SPRG5R + mfspr r12, SPRG4R + mfspr r11, SPRG1 + mfspr r10, SPRG0 + rfi /* Force context change */ + +/* + * Global functions + */ + +/* + * extern void giveup_altivec(struct task_struct *prev) + * + * The 44x core does not have an AltiVec unit. + */ +_GLOBAL(giveup_altivec) + blr + +/* + * extern void giveup_fpu(struct task_struct *prev) + * + * The 44x core does not have an FPU. + */ +_GLOBAL(giveup_fpu) + blr + +/* + * extern void abort(void) + * + * At present, this routine just applies a system reset. + */ +_GLOBAL(abort) + mfspr r13,SPRN_DBCR0 + oris r13,r13,DBCR_RST(DBCR_RST_SYSTEM)@h + mtspr SPRN_DBCR0,r13 + +_GLOBAL(set_context) + +#ifdef CONFIG_BDI_SWITCH + /* Context switch the PTE pointer for the Abatron BDI2000. + * The PGDIR is the second parameter. + */ + lis r5, abatron_pteptrs@h + ori r5, r5, abatron_pteptrs@l + stw r4, 0x4(r5) +#endif + mtspr SPRN_PID,r3 + isync /* Force context change */ + blr + +/* + * We put a few things here that have to be page-aligned. This stuff + * goes at the beginning of the data segment, which is page-aligned. + */ + .data +_GLOBAL(sdata) +_GLOBAL(empty_zero_page) + .space 4096 + +/* + * To support >32-bit physical addresses, we use an 8KB pgdir. + */ +_GLOBAL(swapper_pg_dir) + .space 8192 + +/* Stack for handling critical exceptions from kernel mode */ + .section .bss +critical_stack_bottom: + .space 4096 +critical_stack_top: + .previous + +/* + * This space gets a copy of optional info passed to us by the bootstrap + * which is used to pass parameters into the kernel like root=/dev/sda1, etc. + */ +_GLOBAL(cmd_line) + .space 512 + +/* + * Room for two PTE pointers, usually the kernel and current user pointers + * to their respective root page table. + */ +abatron_pteptrs: + .space 8 + +/* + * This area is used for temporarily saving registers during the + * critical exception prolog. + */ +crit_save: +_GLOBAL(crit_r10) + .space 4 +_GLOBAL(crit_r11) + .space 4 +_GLOBAL(crit_sprg0) + .space 4 +_GLOBAL(crit_sprg1) + .space 4 +_GLOBAL(crit_sprg4) + .space 4 +_GLOBAL(crit_sprg5) + .space 4 +_GLOBAL(crit_sprg6) + .space 4 +_GLOBAL(crit_sprg7) + .space 4 +_GLOBAL(crit_pid) + .space 4 +_GLOBAL(crit_srr0) + .space 4 +_GLOBAL(crit_srr1) + .space 4 diff -Nru a/arch/ppc/kernel/misc.S b/arch/ppc/kernel/misc.S --- a/arch/ppc/kernel/misc.S Thu Sep 4 15:38:44 2003 +++ b/arch/ppc/kernel/misc.S Thu Sep 4 15:38:44 2003 @@ -405,16 +405,20 @@ sync /* Flush to memory before changing mapping */ tlbia isync /* Flush shadow TLB */ -#elif defined(CONFIG_440) +#elif defined(CONFIG_44x) lis r3,0 sync 1: - tlbwe r3,r3,PPC440_TLB_PAGEID + tlbwe r3,r3,PPC44x_TLB_PAGEID addi r3,r3,1 - cmpwi 0,r3,61 + /* Load high watermark */ + lis r4,tlb_44x_hwater@h + ori r4,r4,tlb_44x_hwater@l + lwz r5,0(r4) + cmpw 0,r3,r5 ble 1b isync -#else /* !(CONFIG_40x || CONFIG_440) */ +#else /* !(CONFIG_40x || CONFIG_44x) */ #if defined(CONFIG_SMP) rlwinm r8,r1,0,0,18 lwz r8,TI_CPU(r8) @@ -465,17 +469,17 @@ tlbwe r3, r3, TLB_TAG isync 10: -#elif defined(CONFIG_440) +#elif defined(CONFIG_44x) mfspr r4,SPRN_MMUCR /* Get MMUCR */ - lis r5,PPC440_MMUCR_STS@h - ori r5,r5,PPC440_MMUCR_TID@l /* Create mask */ + lis r5,PPC44x_MMUCR_STS@h + ori r5,r5,PPC44x_MMUCR_TID@l /* Create mask */ andc r4,r4,r5 /* Clear out TID/STS bits */ mfspr r5,SPRN_PID /* Get PID */ or r4,r4,r5 /* Set TID bits */ mfmsr r6 /* Get MSR */ andi. r6,r6,MSR_IS@l /* TS=1? */ beq 11f /* If not, leave STS=0 */ - oris r4,r4,PPC440_MMUCR_STS@h /* Set STS=1 */ + oris r4,r4,PPC44x_MMUCR_STS@h /* Set STS=1 */ 11: mtspr SPRN_MMUCR, r4 /* Put MMUCR */ tlbsx. r3, 0, r3 @@ -486,10 +490,10 @@ * the V bit in the TLB_PAGEID, loading this * value will invalidate the TLB entry. */ - tlbwe r3, r3, PPC440_TLB_PAGEID + tlbwe r3, r3, PPC44x_TLB_PAGEID isync 10: -#else /* !(CONFIG_40x || CONFIG_440) */ +#else /* !(CONFIG_40x || CONFIG_44x) */ #if defined(CONFIG_SMP) rlwinm r8,r1,0,0,18 lwz r8,TI_CPU(r8) @@ -658,9 +662,9 @@ #ifdef CONFIG_NOT_COHERENT_CACHE /* * 40x cores have 8K or 16K dcache and 32 byte line size. - * 440 has a 32K dcache and 32 byte line size. + * 44x has a 32K dcache and 32 byte line size. * 8xx has 1, 2, 4, 8K variants. - * For now, cover the worst case of the 440. + * For now, cover the worst case of the 44x. * Must be called with external interrupts disabled. */ #define CACHE_NWAYS 64 @@ -1380,3 +1384,4 @@ .long sys_utimes .long sys_statfs64 .long sys_fstatfs64 + .long ppc_fadvise64_64 diff -Nru a/arch/ppc/kernel/ppc-stub.c b/arch/ppc/kernel/ppc-stub.c --- a/arch/ppc/kernel/ppc-stub.c Thu Sep 4 15:38:44 2003 +++ b/arch/ppc/kernel/ppc-stub.c Thu Sep 4 15:38:44 2003 @@ -106,6 +106,7 @@ #include #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 Thu Sep 4 15:38:44 2003 +++ b/arch/ppc/kernel/ppc_ksyms.c Thu Sep 4 15:38:44 2003 @@ -155,6 +155,9 @@ EXPORT_SYMBOL(iopa); EXPORT_SYMBOL(mm_ptov); EXPORT_SYMBOL(ioremap); +#ifdef CONFIG_44x +EXPORT_SYMBOL(ioremap64); +#endif EXPORT_SYMBOL(__ioremap); EXPORT_SYMBOL(iounmap); EXPORT_SYMBOL(ioremap_bot); /* aka VMALLOC_END */ @@ -200,6 +203,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 +263,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); @@ -343,7 +356,7 @@ EXPORT_SYMBOL(cpm_install_handler); EXPORT_SYMBOL(cpm_free_handler); #endif /* CONFIG_8xx */ -#if defined(CONFIG_8xx) || defined(CONFIG_40x) +#if defined(CONFIG_8xx) || defined(CONFIG_4xx) EXPORT_SYMBOL(__res); #endif #if defined(CONFIG_8xx) diff -Nru a/arch/ppc/kernel/setup.c b/arch/ppc/kernel/setup.c --- a/arch/ppc/kernel/setup.c Thu Sep 4 15:38:45 2003 +++ b/arch/ppc/kernel/setup.c Thu Sep 4 15:38:45 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 Thu Sep 4 15:38:45 2003 +++ b/arch/ppc/kernel/smp.c Thu Sep 4 15:38:45 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 Thu Sep 4 15:38:45 2003 +++ b/arch/ppc/kernel/syscalls.c Thu Sep 4 15:38:45 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/mm/44x_mmu.c b/arch/ppc/mm/44x_mmu.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/ppc/mm/44x_mmu.c Thu Sep 4 15:38:48 2003 @@ -0,0 +1,162 @@ +/* + * Modifications by Matt Porter (mporter@mvista.com) to support + * PPC44x Book E processors. + * + * This file contains the routines for initializing the MMU + * on the 4xx series of chips. + * -- paulus + * + * Derived from arch/ppc/mm/init.c: + * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org) + * + * Modifications by Paul Mackerras (PowerMac) (paulus@cs.anu.edu.au) + * and Cort Dougan (PReP) (cort@cs.nmt.edu) + * Copyright (C) 1996 Paul Mackerras + * Amiga/APUS changes by Jesper Skov (jskov@cygnus.co.uk). + * + * Derived from "arch/i386/mm/init.c" + * Copyright (C) 1991, 1992, 1993, 1994 Linus Torvalds + * + * 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 +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "mmu_decl.h" +#include "mem_pieces.h" + +extern char etext[], _stext[]; +extern struct mem_pieces phys_avail; + +/* Used by the 44x TLB replacement exception handler. + * Just needed it declared someplace. + */ +unsigned int tlb_44x_index = 0; +unsigned int tlb_44x_hwater = 61; + +/* + * "Pins" a 256MB TLB entry in AS0 for kernel lowmem + */ +static void __init +ppc44x_pin_tlb(int slot, unsigned int virt, unsigned int phys) +{ + unsigned long attrib; + + __asm__ __volatile__("\ + clrrwi %2,%2,10\n\ + ori %2,%2,%4\n\ + clrrwi %1,%1,10\n\ + li %0,0\n\ + ori %0,%0,%5\n\ + tlbwe %2,%3,%6\n\ + tlbwe %1,%3,%7\n\ + tlbwe %0,%3,%8" + : + : "r" (attrib), "r" (phys), "r" (virt), "r" (slot), + "i" (PPC44x_TLB_VALID | PPC44x_TLB_PAGESZ(PPC44x_PAGESZ_256M)), + "i" (PPC44x_TLB_SW | PPC44x_TLB_SR | PPC44x_TLB_SX | PPC44x_TLB_G), + "i" (PPC44x_TLB_PAGEID), + "i" (PPC44x_TLB_XLAT), + "i" (PPC44x_TLB_ATTRIB)); +} + +/* + * Configure PPC44x TLB for AS0 exception processing. + */ +static void __init +ppc44x_tlb_config(void) +{ + unsigned int pinned_tlbs = 1; + int i; + + /* + * If lowmem is not on a pin tlb entry size boundary, + * then reserve the last page of system memory. This + * eliminates the possibility of a speculative dcache + * fetch past the end of system memory that would + * result in a machine check exception. + */ + if (total_lowmem | (PPC44x_PIN_SIZE - 1)) + mem_pieces_remove(&phys_avail, total_lowmem - PAGE_SIZE, PAGE_SIZE, 1); + + /* Determine number of entries necessary to cover lowmem */ + pinned_tlbs = (unsigned int) + (_ALIGN(total_lowmem, PPC44x_PIN_SIZE) >> PPC44x_PIN_SHIFT); + + /* Write upper watermark to save location */ + tlb_44x_hwater = PPC44x_LOW_SLOT - pinned_tlbs; + + /* If necessary, set additional pinned TLBs */ + if (pinned_tlbs > 1) + for (i = (PPC44x_LOW_SLOT-(pinned_tlbs-1)); i < PPC44x_LOW_SLOT; i++) { + unsigned int phys_addr = (PPC44x_LOW_SLOT-i) * PPC44x_PIN_SIZE; + ppc44x_pin_tlb(i, phys_addr+PAGE_OFFSET, phys_addr); + } +} + +/* + * MMU_init_hw does the chip-specific initialization of the MMU hardware. + */ +void __init MMU_init_hw(void) +{ + flush_instruction_cache(); + + ppc44x_tlb_config(); +} + +/* TODO: Add large page lowmem mapping support */ +unsigned long __init mmu_mapin_ram(void) +{ + unsigned long v, s, f = _PAGE_GUARDED; + phys_addr_t p; + + v = KERNELBASE; + p = PPC_MEMSTART; + + for (s = 0; s < total_lowmem; s += PAGE_SIZE) { + if ((char *) v >= _stext && (char *) v < etext) + f |= _PAGE_RAM_TEXT; + else + f |= _PAGE_RAM; + map_page(v, p, f); + v += PAGE_SIZE; + p += PAGE_SIZE; + } + + if (ppc_md.progress) + ppc_md.progress("MMU:mmu_mapin_ram done", 0x401); + + return s; +} diff -Nru a/arch/ppc/mm/Makefile b/arch/ppc/mm/Makefile --- a/arch/ppc/mm/Makefile Thu Sep 4 15:38:42 2003 +++ b/arch/ppc/mm/Makefile Thu Sep 4 15:38:42 2003 @@ -11,4 +11,5 @@ obj-$(CONFIG_PPC_STD_MMU) += hashtable.o ppc_mmu.o tlb.o obj-$(CONFIG_40x) += 4xx_mmu.o +obj-$(CONFIG_44x) += 44x_mmu.o obj-$(CONFIG_NOT_COHERENT_CACHE) += cachemap.o diff -Nru a/arch/ppc/mm/cachemap.c b/arch/ppc/mm/cachemap.c --- a/arch/ppc/mm/cachemap.c Thu Sep 4 15:38:47 2003 +++ b/arch/ppc/mm/cachemap.c Thu Sep 4 15:38:47 2003 @@ -48,7 +48,7 @@ #include #include -int map_page(unsigned long va, unsigned long pa, int flags); +int map_page(unsigned long va, phys_addr_t pa, int flags); /* This function will allocate the requested contiguous pages and * map them into the kernel's vmalloc() space. This is done so we @@ -61,7 +61,8 @@ { int order, err; struct page *page, *free, *end; - unsigned long pa, flags, offset; + phys_addr_t pa; + unsigned long flags, offset; struct vm_struct *area = NULL; unsigned long va = 0; diff -Nru a/arch/ppc/mm/init.c b/arch/ppc/mm/init.c --- a/arch/ppc/mm/init.c Thu Sep 4 15:38:30 2003 +++ b/arch/ppc/mm/init.c Thu Sep 4 15:38:30 2003 @@ -6,6 +6,7 @@ * and Cort Dougan (PReP) (cort@cs.nmt.edu) * Copyright (C) 1996 Paul Mackerras * Amiga/APUS changes by Jesper Skov (jskov@cygnus.co.uk). + * PPC44x/36-bit changes by Matt Porter (mporter@mvista.com) * * Derived from "arch/i386/mm/init.c" * Copyright (C) 1991, 1992, 1993, 1994 Linus Torvalds diff -Nru a/arch/ppc/mm/mmu_decl.h b/arch/ppc/mm/mmu_decl.h --- a/arch/ppc/mm/mmu_decl.h Thu Sep 4 15:38:35 2003 +++ b/arch/ppc/mm/mmu_decl.h Thu Sep 4 15:38:35 2003 @@ -20,9 +20,10 @@ * */ #include +#include extern void mapin_ram(void); -extern int map_page(unsigned long va, unsigned long pa, int flags); +extern int map_page(unsigned long va, phys_addr_t pa, int flags); extern void setbat(int index, unsigned long virt, unsigned long phys, unsigned int size, int flags); extern void reserve_phys_mem(unsigned long start, unsigned long size); diff -Nru a/arch/ppc/mm/pgtable.c b/arch/ppc/mm/pgtable.c --- a/arch/ppc/mm/pgtable.c Thu Sep 4 15:38:30 2003 +++ b/arch/ppc/mm/pgtable.c Thu Sep 4 15:38:30 2003 @@ -55,11 +55,18 @@ #define p_mapped_by_bats(x) (0UL) #endif /* HAVE_BATS */ +#ifdef CONFIG_44x +/* 44x uses an 8kB pgdir because it has 8-byte Linux PTEs. */ +#define PGDIR_ORDER 1 +#else +#define PGDIR_ORDER 0 +#endif + pgd_t *pgd_alloc(struct mm_struct *mm) { pgd_t *ret; - if ((ret = (pgd_t *)__get_free_page(GFP_KERNEL)) != NULL) + if ((ret = (pgd_t *)__get_free_pages(GFP_KERNEL, PGDIR_ORDER)) != NULL) clear_page(ret); return ret; } @@ -110,16 +117,33 @@ __free_page(pte); } +#ifndef CONFIG_44x +void * +ioremap(phys_addr_t addr, unsigned long size) +{ + return __ioremap(addr, size, _PAGE_NO_CACHE); +} +#else /* CONFIG_44x */ void * -ioremap(unsigned long addr, unsigned long size) +ioremap64(unsigned long long addr, unsigned long size) { return __ioremap(addr, size, _PAGE_NO_CACHE); } void * -__ioremap(unsigned long addr, unsigned long size, unsigned long flags) +ioremap(phys_addr_t addr, unsigned long size) +{ + phys_addr_t addr64 = fixup_bigphys_addr(addr, size);; + + return ioremap64(addr64, size); +} +#endif /* CONFIG_44x */ + +void * +__ioremap(phys_addr_t addr, unsigned long size, unsigned long flags) { - unsigned long p, v, i; + unsigned long v, i; + phys_addr_t p; int err; /* @@ -144,7 +168,7 @@ */ if ( mem_init_done && (p < virt_to_phys(high_memory)) ) { - printk("__ioremap(): phys addr %0lx is RAM lr %p\n", p, + printk("__ioremap(): phys addr "PTE_FMT" is RAM lr %p\n", p, __builtin_return_address(0)); return NULL; } @@ -195,7 +219,7 @@ } out: - return (void *) (v + (addr & ~PAGE_MASK)); + return (void *) (v + ((unsigned long)addr & ~PAGE_MASK)); } void iounmap(void *addr) @@ -211,7 +235,7 @@ } int -map_page(unsigned long va, unsigned long pa, int flags) +map_page(unsigned long va, phys_addr_t pa, int flags) { pmd_t *pd; pte_t *pg; @@ -261,7 +285,7 @@ * virt, phys, size must all be page-aligned. * This should only be called before ioremap is called. */ -void __init io_block_mapping(unsigned long virt, unsigned long phys, +void __init io_block_mapping(unsigned long virt, phys_addr_t phys, unsigned int size, int flags) { int i; diff -Nru a/arch/ppc/ocp/ocp-probe.c b/arch/ppc/ocp/ocp-probe.c --- a/arch/ppc/ocp/ocp-probe.c Thu Sep 4 15:38:48 2003 +++ b/arch/ppc/ocp/ocp-probe.c Thu Sep 4 15:38:48 2003 @@ -62,7 +62,6 @@ (unsigned long) dev->paddr, dev->irq, dev->pm); /* now put in global tree */ - strcpy(dev->dev.name, dev->name); sprintf(dev->dev.bus_id, "%d", index); dev->dev.parent = ocp_bus; dev->dev.bus = &ocp_bus_type; @@ -80,7 +79,7 @@ return NULL; memset(b, 0, sizeof(struct device)); strcpy(b->bus_id, "ocp"); - strcpy(b->name, "Host/OCP Bridge"); + device_register(b); return b; diff -Nru a/arch/ppc/platforms/4xx/Kconfig b/arch/ppc/platforms/4xx/Kconfig --- a/arch/ppc/platforms/4xx/Kconfig Thu Sep 4 15:38:30 2003 +++ b/arch/ppc/platforms/4xx/Kconfig Thu Sep 4 15:38:30 2003 @@ -1,6 +1,6 @@ config 4xx bool - depends on 40x + depends on 40x || 44x default y menu "IBM 4xx options" @@ -57,6 +57,23 @@ endchoice +choice + prompt "Machine Type" + depends on 44x + default EBONY + +config EBONY + bool "Ebony" + help + This option enables support for the IBM PPC440GP evaluation board. + +config OCOTEA + bool "Ocotea" + help + This option enables support for the IBM PPC440GX evaluation board. + +endchoice + config EP405PC bool "EP405PC Support" depends on EP405 @@ -70,6 +87,26 @@ depends on ASH default y +config 440GP + bool + depends on EBONY + default y + +config 440GX + bool + depends on OCOTEA + default y + +config 440 + bool + depends on 440GP + default y + +config 440A + bool + depends on 440GX + default y + # All 405-based cores up until the 405GPR and 405EP have this errata. config IBM405_ERR77 bool @@ -82,9 +119,25 @@ depends on 40x && !405GPR default y + +config PIN_TLB + bool + depends on 44x + default y + +config BOOKE + bool + depends on 44x + default y + config IBM_OCP bool - depends on ASH || BEECH || CEDAR || CPCI405 || EP405 || REDWOOD_4 || REDWOOD_5 || REDWOOD_6 || SYCAMORE || WALNUT + depends on ASH || BEECH || CEDAR || CPCI405 || EBONY || EP405 || OCOTEA || REDWOOD_4 || REDWOOD_5 || REDWOOD_6 || SYCAMORE || WALNUT + default y + +config IBM_EMAC4 + bool + depends on 440GX default y config NP405L diff -Nru a/arch/ppc/platforms/4xx/Makefile b/arch/ppc/platforms/4xx/Makefile --- a/arch/ppc/platforms/4xx/Makefile Thu Sep 4 15:38:43 2003 +++ b/arch/ppc/platforms/4xx/Makefile Thu Sep 4 15:38:43 2003 @@ -5,8 +5,10 @@ obj-$(CONFIG_BEECH) += beech.o obj-$(CONFIG_CEDAR) += cedar.o obj-$(CONFIG_CPCI405) += cpci405.o +obj-$(CONFIG_EBONY) += ebony.o obj-$(CONFIG_EP405) += ep405.o obj-$(CONFIG_OAK) += oak.o +obj-$(CONFIG_OCOTEA) += ocotea.o obj-$(CONFIG_REDWOOD_4) += redwood.o obj-$(CONFIG_REDWOOD_5) += redwood5.o obj-$(CONFIG_REDWOOD_6) += redwood6.o @@ -21,4 +23,6 @@ obj-$(CONFIG_REDWOOD_6) += ibmstbx25.o obj-$(CONFIG_NP4GS3) += ibmnp4gs.o obj-$(CONFIG_405LP) += ibm405lp.o +obj-$(CONFIG_EBONY) += ibm440gp.o +obj-$(CONFIG_OCOTEA) += ibm440gx.o obj-$(CONFIG_405GPR) += ibm405gpr.o diff -Nru a/arch/ppc/platforms/4xx/ebony.c b/arch/ppc/platforms/4xx/ebony.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/ppc/platforms/4xx/ebony.c Thu Sep 4 15:38:48 2003 @@ -0,0 +1,536 @@ +/* + * arch/ppc/platforms/ebony.c + * + * Ebony board specific routines + * + * Matt Porter + * + * Copyright 2002 MontaVista Software 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 (at your + * option) any later version. + */ + +#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 +#include +#include +#include +#include + +/* + * Ebony IRQ triggering/polarity settings + */ +static u_char ebony_IRQ_initsenses[] __initdata = { + (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* 0: UART 0 */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* 1: UART 1 */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* 2: IIC 0 */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* 3: IIC 1 */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* 4: PCI Inb Mess */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* 5: PCI Cmd Wrt */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* 6: PCI PM */ + (IRQ_SENSE_EDGE | IRQ_POLARITY_POSITIVE), /* 7: PCI MSI 0 */ + (IRQ_SENSE_EDGE | IRQ_POLARITY_POSITIVE), /* 8: PCI MSI 1 */ + (IRQ_SENSE_EDGE | IRQ_POLARITY_POSITIVE), /* 9: PCI MSI 2 */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* 10: MAL TX EOB */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* 11: MAL RX EOB */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* 12: DMA Chan 0 */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* 13: DMA Chan 1 */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* 14: DMA Chan 2 */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* 15: DMA Chan 3 */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* 16: Reserved */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* 17: Reserved */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* 18: GPT Timer 0 */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* 19: GPT Timer 1 */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* 20: GPT Timer 2 */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* 21: GPT Timer 3 */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* 22: GPT Timer 4 */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* 23: Ext Int 0 */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* 24: Ext Int 1 */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* 25: Ext Int 2 */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* 26: Ext Int 3 */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* 27: Ext Int 4 */ + (IRQ_SENSE_EDGE | IRQ_POLARITY_NEGATIVE), /* 28: Ext Int 5 */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* 29: Ext Int 6 */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* 30: UIC1 NC Int */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* 31: UIC1 Crit Int */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* 32: MAL SERR */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* 33: MAL TXDE */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* 34: MAL RXDE */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* 35: ECC Unc Err */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* 36: ECC Corr Err */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* 37: Ext Bus Ctrl */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* 38: Ext Bus Mstr */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* 39: OPB->PLB */ + (IRQ_SENSE_EDGE | IRQ_POLARITY_POSITIVE), /* 40: PCI MSI 3 */ + (IRQ_SENSE_EDGE | IRQ_POLARITY_POSITIVE), /* 41: PCI MSI 4 */ + (IRQ_SENSE_EDGE | IRQ_POLARITY_POSITIVE), /* 42: PCI MSI 5 */ + (IRQ_SENSE_EDGE | IRQ_POLARITY_POSITIVE), /* 43: PCI MSI 6 */ + (IRQ_SENSE_EDGE | IRQ_POLARITY_POSITIVE), /* 44: PCI MSI 7 */ + (IRQ_SENSE_EDGE | IRQ_POLARITY_POSITIVE), /* 45: PCI MSI 8 */ + (IRQ_SENSE_EDGE | IRQ_POLARITY_POSITIVE), /* 46: PCI MSI 9 */ + (IRQ_SENSE_EDGE | IRQ_POLARITY_POSITIVE), /* 47: PCI MSI 10 */ + (IRQ_SENSE_EDGE | IRQ_POLARITY_POSITIVE), /* 48: PCI MSI 11 */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* 49: PLB Perf Mon */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* 50: Ext Int 7 */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* 51: Ext Int 8 */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* 52: Ext Int 9 */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* 53: Ext Int 10 */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* 54: Ext Int 11 */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* 55: Ext Int 12 */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* 56: Ser ROM Err */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* 57: Reserved */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* 58: Reserved */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* 59: PCI Async Err */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* 60: EMAC 0 */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* 61: EMAC 0 WOL */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* 62: EMAC 1 */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* 63: EMAC 1 WOL */ +}; + +extern void abort(void); + +/* Global Variables */ +bd_t __res; + +static void __init +ebony_calibrate_decr(void) +{ + unsigned int freq; + + /* + * Determine system clock speed + * + * If we are on Rev. B silicon, then use + * default external system clock. If we are + * on Rev. C silicon then errata forces us to + * use the internal clock. + */ + switch (PVR_REV(mfspr(PVR))) { + case PVR_REV(PVR_440GP_RB): + freq = EBONY_440GP_RB_SYSCLK; + break; + case PVR_REV(PVR_440GP_RC1): + default: + freq = EBONY_440GP_RC_SYSCLK; + break; + } + + tb_ticks_per_jiffy = freq / HZ; + tb_to_us = mulhwu_scale_factor(freq, 1000000); + + /* Set the time base to zero */ + mtspr(SPRN_TBWL, 0); + mtspr(SPRN_TBWU, 0); + + /* Clear any pending timer interrupts */ + mtspr(SPRN_TSR, TSR_ENW | TSR_WIS | TSR_DIS | TSR_FIS); + + /* Enable decrementer interrupt */ + mtspr(SPRN_TCR, TCR_DIE); +} + +static int +ebony_show_cpuinfo(struct seq_file *m) +{ + seq_printf(m, "vendor\t\t: IBM\n"); + seq_printf(m, "machine\t\t: Ebony\n"); + + return 0; +} + +static inline int +ebony_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin) +{ + static char pci_irq_table[][4] = + /* + * PCI IDSEL/INTPIN->INTLINE + * A B C D + */ + { + { 23, 23, 23, 23 }, /* IDSEL 1 - PCI Slot 0 */ + { 24, 24, 24, 24 }, /* IDSEL 2 - PCI Slot 1 */ + { 25, 25, 25, 25 }, /* IDSEL 3 - PCI Slot 2 */ + { 26, 26, 26, 26 }, /* IDSEL 4 - PCI Slot 3 */ + }; + + const long min_idsel = 1, max_idsel = 4, irqs_per_slot = 4; + return PCI_IRQ_TABLE_LOOKUP; +} + +#define PCIX_WRITEL(value, offset) \ + (writel(value, (u32)pcix_reg_base+offset)) + +/* + * FIXME: This is only here to "make it work". This will move + * to a ibm_pcix.c which will contain a generic IBM PCIX bridge + * configuration library. -Matt + */ +static void __init +ebony_setup_pcix(void) +{ + void *pcix_reg_base; + + pcix_reg_base = ioremap64(PCIX0_REG_BASE, PCIX0_REG_SIZE); + + /* Disable all windows */ + PCIX_WRITEL(0, PCIX0_POM0SA); + PCIX_WRITEL(0, PCIX0_POM1SA); + PCIX_WRITEL(0, PCIX0_POM2SA); + PCIX_WRITEL(0, PCIX0_PIM0SA); + PCIX_WRITEL(0, PCIX0_PIM1SA); + PCIX_WRITEL(0, PCIX0_PIM2SA); + + /* Setup 2GB PLB->PCI outbound mem window (3_8000_0000->0_8000_0000) */ + PCIX_WRITEL(0x00000003, PCIX0_POM0LAH); + PCIX_WRITEL(0x80000000, PCIX0_POM0LAL); + PCIX_WRITEL(0x00000000, PCIX0_POM0PCIAH); + PCIX_WRITEL(0x80000000, PCIX0_POM0PCIAL); + PCIX_WRITEL(0x80000001, PCIX0_POM0SA); + + /* Setup 2GB PCI->PLB inbound memory window at 0, enable MSIs */ + PCIX_WRITEL(0x00000000, PCIX0_PIM0LAH); + PCIX_WRITEL(0x00000000, PCIX0_PIM0LAL); + PCIX_WRITEL(0x80000007, PCIX0_PIM0SA); + + eieio(); +} + +static void __init +ebony_setup_hose(void) +{ + struct pci_controller *hose; + + /* Configure windows on the PCI-X host bridge */ + ebony_setup_pcix(); + + hose = pcibios_alloc_controller(); + + if (!hose) + return; + + hose->first_busno = 0; + hose->last_busno = 0xff; + + hose->pci_mem_offset = EBONY_PCI_MEM_OFFSET; + + pci_init_resource(&hose->io_resource, + EBONY_PCI_LOWER_IO, + EBONY_PCI_UPPER_IO, + IORESOURCE_IO, + "PCI host bridge"); + + pci_init_resource(&hose->mem_resources[0], + EBONY_PCI_LOWER_MEM, + EBONY_PCI_UPPER_MEM, + IORESOURCE_MEM, + "PCI host bridge"); + + hose->io_space.start = EBONY_PCI_LOWER_IO; + hose->io_space.end = EBONY_PCI_UPPER_IO; + hose->mem_space.start = EBONY_PCI_LOWER_MEM; + hose->mem_space.end = EBONY_PCI_UPPER_MEM; + isa_io_base = + (unsigned long)ioremap64(EBONY_PCI_IO_BASE, EBONY_PCI_IO_SIZE); + hose->io_base_virt = (void *)isa_io_base; + + setup_indirect_pci(hose, + EBONY_PCI_CFGA_PLB32, + EBONY_PCI_CFGD_PLB32); + hose->set_cfg_type = 1; + + hose->last_busno = pciauto_bus_scan(hose, hose->first_busno); + + ppc_md.pci_swizzle = common_swizzle; + ppc_md.pci_map_irq = ebony_map_irq; +} + +TODC_ALLOC(); + +static void __init +ebony_early_serial_map(void) +{ + struct uart_port port; + + /* Setup ioremapped serial port access */ + memset(&port, 0, sizeof(port)); + port.membase = ioremap64(PPC440GP_UART0_ADDR, 8); + port.irq = 0; + port.uartclk = BASE_BAUD * 16; + port.regshift = 0; + port.iotype = SERIAL_IO_MEM; + port.flags = ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST; + port.line = 0; + + if (early_serial_setup(&port) != 0) { + printk("Early serial init of port 0 failed\n"); + } + + port.membase = ioremap64(PPC440GP_UART1_ADDR, 8); + port.irq = 1; + port.line = 1; + + if (early_serial_setup(&port) != 0) { + printk("Early serial init of port 1 failed\n"); + } +} + +static void __init +ebony_setup_arch(void) +{ + unsigned char * vpd_base; + struct ibm440gp_clocks clocks; + +#if !defined(CONFIG_BDI_SWITCH) + /* + * The Abatron BDI JTAG debugger does not tolerate others + * mucking with the debug registers. + */ + mtspr(SPRN_DBCR0, (DBCR0_TDE | DBCR0_IDM)); +#endif + + /* Retrieve MAC addresses */ + vpd_base = ioremap64(EBONY_VPD_BASE, EBONY_VPD_SIZE); + memcpy(__res.bi_enetaddr[0],EBONY_NA0_ADDR(vpd_base),6); + memcpy(__res.bi_enetaddr[1],EBONY_NA1_ADDR(vpd_base),6); + + /* + * Determine various clocks. + * To be completely correct we should get SysClk + * from FPGA, because it can be changed by on-board switches + * --ebs + */ + ibm440gp_get_clocks(&clocks, 33333333, 6 * 1843200); + __res.bi_opb_busfreq = clocks.opb; + + /* Use IIC in standard (100 kHz) mode */ + __res.bi_iic_fast[0] = __res.bi_iic_fast[1] = 0; + + /* Setup TODC access */ + TODC_INIT(TODC_TYPE_DS1743, + 0, + 0, + ioremap64(EBONY_RTC_ADDR, EBONY_RTC_SIZE), + 8); + + /* init to some ~sane value until calibrate_delay() runs */ + loops_per_jiffy = 50000000/HZ; + + /* Setup PCI host bridge */ + ebony_setup_hose(); + +#ifdef CONFIG_BLK_DEV_INITRD + if (initrd_start) + ROOT_DEV = Root_RAM0; + else +#endif +#ifdef CONFIG_ROOT_NFS + ROOT_DEV = Root_NFS; +#else + ROOT_DEV = Root_HDA1; +#endif + +#ifdef CONFIG_VT + conswitchp = &dummy_con; +#endif + + ebony_early_serial_map(); + + ibm4xxPIC_InitSenses = ebony_IRQ_initsenses; + ibm4xxPIC_NumInitSenses = sizeof(ebony_IRQ_initsenses); + + /* Identify the system */ + printk("IBM Ebony port (MontaVista Software, Inc. (source@mvista.com))\n"); +} + +static void +ebony_restart(char *cmd) +{ + local_irq_disable(); + abort(); +} + +static void +ebony_power_off(void) +{ + local_irq_disable(); + for(;;); +} + +static void +ebony_halt(void) +{ + local_irq_disable(); + for(;;); +} + +/* + * Read the 440GP memory controller to get size of system memory. + */ +static unsigned long __init +ebony_find_end_of_memory(void) +{ + u32 i, bank_config; + u32 mem_size = 0; + + for (i=0; i<4; i++) + { + switch (i) + { + case 0: + mtdcr(DCRN_SDRAM0_CFGADDR, SDRAM0_B0CR); + break; + case 1: + mtdcr(DCRN_SDRAM0_CFGADDR, SDRAM0_B1CR); + break; + case 2: + mtdcr(DCRN_SDRAM0_CFGADDR, SDRAM0_B2CR); + break; + case 3: + mtdcr(DCRN_SDRAM0_CFGADDR, SDRAM0_B3CR); + break; + } + + bank_config = mfdcr(DCRN_SDRAM0_CFGDATA); + + if (!(bank_config & SDRAM_CONFIG_BANK_ENABLE)) + continue; + switch (SDRAM_CONFIG_BANK_SIZE(bank_config)) + { + case SDRAM_CONFIG_SIZE_8M: + mem_size += PPC44x_MEM_SIZE_8M; + break; + case SDRAM_CONFIG_SIZE_16M: + mem_size += PPC44x_MEM_SIZE_16M; + break; + case SDRAM_CONFIG_SIZE_32M: + mem_size += PPC44x_MEM_SIZE_32M; + break; + case SDRAM_CONFIG_SIZE_64M: + mem_size += PPC44x_MEM_SIZE_64M; + break; + case SDRAM_CONFIG_SIZE_128M: + mem_size += PPC44x_MEM_SIZE_128M; + break; + case SDRAM_CONFIG_SIZE_256M: + mem_size += PPC44x_MEM_SIZE_256M; + break; + case SDRAM_CONFIG_SIZE_512M: + mem_size += PPC44x_MEM_SIZE_512M; + break; + } + } + return mem_size; +} + +static void __init +ebony_init_irq(void) +{ + int i; + + ppc4xx_pic_init(); + + for (i = 0; i < NR_IRQS; i++) + irq_desc[i].handler = ppc4xx_pic; +} + +#ifdef CONFIG_SERIAL_TEXT_DEBUG +#include +#include +#include + +static struct serial_state rs_table[RS_TABLE_SIZE] = { + SERIAL_PORT_DFNS /* Defined in */ +}; + +static void +ebony_progress(char *s, unsigned short hex) +{ + volatile char c; + volatile unsigned long com_port; + u16 shift; + + com_port = (unsigned long)rs_table[0].iomem_base; + 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; + + } + + /* Send LF/CR to pretty up output */ + while ((*((volatile unsigned char *)com_port + + (UART_LSR << shift)) & UART_LSR_THRE) == 0) + ; + *(volatile unsigned char *)com_port = '\r'; + while ((*((volatile unsigned char *)com_port + + (UART_LSR << shift)) & UART_LSR_THRE) == 0) + ; + *(volatile unsigned char *)com_port = '\n'; +} +#endif /* CONFIG_SERIAL_TEXT_DEBUG */ + +void __init platform_init(unsigned long r3, unsigned long r4, + unsigned long r5, unsigned long r6, unsigned long r7) +{ + parse_bootinfo((struct bi_record *) (r3 + KERNELBASE)); + + ppc_md.setup_arch = ebony_setup_arch; + ppc_md.show_cpuinfo = ebony_show_cpuinfo; + ppc_md.init_IRQ = ebony_init_irq; + ppc_md.get_irq = NULL; /* Set in ppc4xx_pic_init() */ + + ppc_md.find_end_of_memory = ebony_find_end_of_memory; + + ppc_md.restart = ebony_restart; + ppc_md.power_off = ebony_power_off; + ppc_md.halt = ebony_halt; + + ppc_md.calibrate_decr = ebony_calibrate_decr; + ppc_md.time_init = todc_time_init; + ppc_md.set_rtc_time = todc_set_rtc_time; + ppc_md.get_rtc_time = todc_get_rtc_time; + + ppc_md.nvram_read_val = todc_direct_read_val; + ppc_md.nvram_write_val = todc_direct_write_val; + +#ifdef CONFIG_SERIAL_TEXT_DEBUG + ppc_md.progress = ebony_progress; +#endif /* CONFIG_SERIAL_TEXT_DEBUG */ +#ifdef CONFIG_KGDB + ppc_md.early_serial_map = ebony_early_serial_map; +#endif +} + diff -Nru a/arch/ppc/platforms/4xx/ebony.h b/arch/ppc/platforms/4xx/ebony.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/ppc/platforms/4xx/ebony.h Thu Sep 4 15:38:48 2003 @@ -0,0 +1,96 @@ +/* + * arch/ppc/platforms/ebony.h + * + * Ebony board definitions + * + * Matt Porter + * + * Copyright 2002 MontaVista Software 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 (at your + * option) any later version. + */ + +#ifdef __KERNEL__ +#ifndef __ASM_EBONY_H__ +#define __ASM_EBONY_H__ + +#include +#include + +/* F/W TLB mapping used in bootloader glue to reset EMAC */ +#define PPC44x_EMAC0_MR0 0xE0000800 + +/* Macros to get at Ebony VPD info */ +#define EBONY_VPD_BASE 0x00000001fffffe00ULL +#define EBONY_VPD_SIZE 0x24 +#define EBONY_NA0_OFFSET 0x0c +#define EBONY_NA1_OFFSET 0x18 +#define EBONY_NA0_ADDR(base) (base + EBONY_NA0_OFFSET) +#define EBONY_NA1_ADDR(base) (base + EBONY_NA1_OFFSET) + +/* Default clock rates for Rev. B and Rev. C silicon */ +#define EBONY_440GP_RB_SYSCLK 33000000 +#define EBONY_440GP_RC_SYSCLK 400000000 + +/* RTC/NVRAM location */ +#define EBONY_RTC_ADDR 0x0000000148000000ULL +#define EBONY_RTC_SIZE 0x2000 + +/* Flash */ +#define EBONY_FPGA_ADDR 0x0000000148300000 +#define EBONY_BOOT_SMALL_FLASH(x) (x & 0x20) +#define EBONY_ONBRD_FLASH_EN(x) (x & 0x02) +#define EBONY_FLASH_SEL(x) (x & 0x01) +#define EBONY_SMALL_FLASH_LOW1 0x00000001ff800000 +#define EBONY_SMALL_FLASH_LOW2 0x00000001ff880000 +#define EBONY_SMALL_FLASH_HIGH1 0x00000001fff00000 +#define EBONY_SMALL_FLASH_HIGH2 0x00000001fff80000 +#define EBONY_SMALL_FLASH_SIZE 0x80000 +#define EBONY_LARGE_FLASH_LOW 0x00000001ff800000 +#define EBONY_LARGE_FLASH_HIGH 0x00000001ffc00000 +#define EBONY_LARGE_FLASH_SIZE 0x400000 + +#define EBONY_SMALL_FLASH_BASE 0x00000001fff80000 +#define EBONY_LARGE_FLASH_BASE 0x00000001ff800000 + +/* + * Serial port defines + */ + +/* OpenBIOS defined UART mappings, used before early_serial_setup */ +#define UART0_IO_BASE (u8 *) 0xE0000200 +#define UART1_IO_BASE (u8 *) 0xE0000300 + +#define BASE_BAUD 33000000/3/16 +#define UART0_INT 0 +#define UART1_INT 1 + +#define STD_UART_OP(num) \ + { 0, BASE_BAUD, 0, UART##num##_INT, \ + (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST), \ + iomem_base: UART##num##_IO_BASE, \ + io_type: SERIAL_IO_MEM}, + +#define SERIAL_PORT_DFNS \ + STD_UART_OP(0) \ + STD_UART_OP(1) + +/* PCI support */ +#define EBONY_PCI_LOWER_IO 0x00000000 +#define EBONY_PCI_UPPER_IO 0x0000ffff +#define EBONY_PCI_LOWER_MEM 0x80002000 +#define EBONY_PCI_UPPER_MEM 0xffffefff + +#define EBONY_PCI_CFGREGS_BASE 0x000000020ec00000 +#define EBONY_PCI_CFGA_PLB32 0x0ec00000 +#define EBONY_PCI_CFGD_PLB32 0x0ec00004 + +#define EBONY_PCI_IO_BASE 0x0000000208000000ULL +#define EBONY_PCI_IO_SIZE 0x00010000 +#define EBONY_PCI_MEM_OFFSET 0x00000000 + +#endif /* __ASM_EBONY_H__ */ +#endif /* __KERNEL__ */ diff -Nru a/arch/ppc/platforms/4xx/ibm440gp.c b/arch/ppc/platforms/4xx/ibm440gp.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/ppc/platforms/4xx/ibm440gp.c Thu Sep 4 15:38:48 2003 @@ -0,0 +1,31 @@ +/* + * arch/ppc/platforms/4xx/ibm440gp.c + * + * PPC440GP I/O descriptions + * + * Matt Porter + * + * Copyright 2002 MontaVista Software 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 (at your + * option) any later version. + * + */ +#include +#include +#include + +struct ocp_def core_ocp[] __initdata = { + {OCP_VENDOR_IBM, OCP_FUNC_OPB, PPC440GP_OPB_BASE_START, OCP_IRQ_NA, OCP_CPM_NA}, + {OCP_VENDOR_IBM, OCP_FUNC_16550, PPC440GP_UART0_ADDR, UART0_INT, IBM_CPM_UART0}, + {OCP_VENDOR_IBM, OCP_FUNC_16550, PPC440GP_UART1_ADDR, UART1_INT, IBM_CPM_UART1}, + {OCP_VENDOR_IBM, OCP_FUNC_IIC, PPC440GP_IIC0_ADDR, IIC0_IRQ, IBM_CPM_IIC0}, + {OCP_VENDOR_IBM, OCP_FUNC_IIC, PPC440GP_IIC1_ADDR, IIC1_IRQ, IBM_CPM_IIC1}, + {OCP_VENDOR_IBM, OCP_FUNC_GPIO, PPC440GP_GPIO0_ADDR, OCP_IRQ_NA, IBM_CPM_GPIO0}, + {OCP_VENDOR_IBM, OCP_FUNC_EMAC, PPC440GP_EMAC0_ADDR, BL_MAC_ETH0, OCP_CPM_NA}, + {OCP_VENDOR_IBM, OCP_FUNC_EMAC, PPC440GP_EMAC1_ADDR, BL_MAC_ETH1, OCP_CPM_NA}, + {OCP_VENDOR_IBM, OCP_FUNC_ZMII, PPC440GP_ZMII_ADDR, OCP_IRQ_NA, OCP_CPM_NA}, + {OCP_VENDOR_INVALID, OCP_FUNC_INVALID, 0x0, OCP_IRQ_NA, OCP_CPM_NA}, +}; diff -Nru a/arch/ppc/platforms/4xx/ibm440gp.h b/arch/ppc/platforms/4xx/ibm440gp.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/ppc/platforms/4xx/ibm440gp.h Thu Sep 4 15:38:48 2003 @@ -0,0 +1,102 @@ +/* + * arch/ppc/platforms/4xx/ibm440gp.h + * + * PPC440GP definitions + * + * Roland Dreier + * + * Copyright 2002 Roland Dreier + * + * 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 file contains code that was originally in the files ibm44x.h + * and ebony.h, which were written by Matt Porter of MontaVista Software Inc. + */ + +#ifdef __KERNEL__ +#ifndef __PPC_PLATFORMS_IBM440GP_H +#define __PPC_PLATFORMS_IBM440GP_H + +#include + +#define EMAC_NUMS 2 +#define UART_NUMS 2 +#define ZMII_NUMS 1 +#define IIC_NUMS 2 +#define IIC0_IRQ 2 +#define IIC1_IRQ 3 +#define GPIO_NUMS 1 + +/* UART location */ +#define PPC440GP_UART0_ADDR 0x0000000140000200ULL +#define PPC440GP_UART1_ADDR 0x0000000140000300ULL + +/* EMAC location */ +#define PPC440GP_EMAC0_ADDR 0x0000000140000800ULL +#define PPC440GP_EMAC1_ADDR 0x0000000140000900ULL +#define PPC440GP_EMAC_SIZE 0x70 + +/* EMAC IRQ's */ +#define BL_MAC_WOL 61 /* WOL */ +#define BL_MAC_WOL1 63 /* WOL */ +#define BL_MAL_SERR 32 /* MAL SERR */ +#define BL_MAL_TXDE 33 /* MAL TXDE */ +#define BL_MAL_RXDE 34 /* MAL RXDE */ +#define BL_MAL_TXEOB 10 /* MAL TX EOB */ +#define BL_MAL_RXEOB 11 /* MAL RX EOB */ +#define BL_MAC_ETH0 60 /* MAC */ +#define BL_MAC_ETH1 62 /* MAC */ + +/* ZMII location */ +#define PPC440GP_ZMII_ADDR 0x0000000140000780ULL +#define PPC440GP_ZMII_SIZE 0x0c + +/* I2C location */ +#define PPC440GP_IIC0_ADDR 0x40000400 +#define PPC440GP_IIC1_ADDR 0x40000500 + +/* GPIO location */ +#define PPC440GP_GPIO0_ADDR 0x0000000140000700ULL + +/* Clock and Power Management */ +#define IBM_CPM_IIC0 0x80000000 /* IIC interface */ +#define IBM_CPM_IIC1 0x40000000 /* IIC interface */ +#define IBM_CPM_PCI 0x20000000 /* PCI bridge */ +#define IBM_CPM_CPU 0x02000000 /* processor core */ +#define IBM_CPM_DMA 0x01000000 /* DMA controller */ +#define IBM_CPM_BGO 0x00800000 /* PLB to OPB bus arbiter */ +#define IBM_CPM_BGI 0x00400000 /* OPB to PLB bridge */ +#define IBM_CPM_EBC 0x00200000 /* External Bux Controller */ +#define IBM_CPM_EBM 0x00100000 /* Ext Bus Master Interface */ +#define IBM_CPM_DMC 0x00080000 /* SDRAM peripheral controller */ +#define IBM_CPM_PLB 0x00040000 /* PLB bus arbiter */ +#define IBM_CPM_SRAM 0x00020000 /* SRAM memory controller */ +#define IBM_CPM_PPM 0x00002000 /* PLB Performance Monitor */ +#define IBM_CPM_UIC1 0x00001000 /* Universal Interrupt Controller */ +#define IBM_CPM_GPIO0 0x00000800 /* General Purpose IO (??) */ +#define IBM_CPM_GPT 0x00000400 /* General Purpose Timers */ +#define IBM_CPM_UART0 0x00000200 /* serial port 0 */ +#define IBM_CPM_UART1 0x00000100 /* serial port 1 */ +#define IBM_CPM_UIC0 0x00000080 /* Universal Interrupt Controller */ +#define IBM_CPM_TMRCLK 0x00000040 /* CPU timers */ + +#define DFLT_IBM4xx_PM ~(IBM_CPM_UIC | IBM_CPM_UIC1 | IBM_CPM_CPU \ + | IBM_CPM_EBC | IBM_CPM_SRAM | IBM_CPM_BGO \ + | IBM_CPM_EBM | IBM_CPM_PLB | IBM_CPM_OPB \ + | IBM_CPM_TMRCLK | IBM_CPM_DMA | IBM_CPM_PCI) + +#define PPC440GP_OPB_BASE_START 0x0000000140000000ULL + +/* + * Serial port defines + */ +#define RS_TABLE_SIZE 2 + +#include +#include + +#endif /* __PPC_PLATFORMS_IBM440GP_H */ +#endif /* __KERNEL__ */ diff -Nru a/arch/ppc/platforms/4xx/ibm440gx.c b/arch/ppc/platforms/4xx/ibm440gx.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/ppc/platforms/4xx/ibm440gx.c Thu Sep 4 15:38:48 2003 @@ -0,0 +1,37 @@ +/* + * arch/ppc/platforms/ibm440gx.c + * + * PPC440GX I/O descriptions + * + * Matt Porter + * + * Copyright 2002-2003 MontaVista Software 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 (at your + * option) any later version. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +struct ocp_def core_ocp[] __initdata = { + {OCP_VENDOR_IBM, OCP_FUNC_OPB, PPC440GX_OPB_BASE_START, OCP_IRQ_NA, OCP_CPM_NA}, + {OCP_VENDOR_IBM, OCP_FUNC_16550, PPC440GX_UART0_ADDR, UART0_IRQ, IBM_CPM_UART0}, + {OCP_VENDOR_IBM, OCP_FUNC_16550, PPC440GX_UART1_ADDR, UART1_IRQ, IBM_CPM_UART1}, + {OCP_VENDOR_IBM, OCP_FUNC_IIC, PPC440GX_IIC0_ADDR, IIC0_IRQ, IBM_CPM_IIC0}, + {OCP_VENDOR_IBM, OCP_FUNC_IIC, PPC440GX_IIC1_ADDR, IIC1_IRQ, IBM_CPM_IIC1}, + {OCP_VENDOR_IBM, OCP_FUNC_GPIO, PPC440GX_GPIO0_ADDR, OCP_IRQ_NA, IBM_CPM_GPIO0}, + {OCP_VENDOR_IBM, OCP_FUNC_EMAC, PPC440GX_EMAC0_ADDR, BL_MAC_ETH0, OCP_CPM_NA}, + {OCP_VENDOR_IBM, OCP_FUNC_EMAC, PPC440GX_EMAC1_ADDR, BL_MAC_ETH1, OCP_CPM_NA}, + {OCP_VENDOR_IBM, OCP_FUNC_ZMII, PPC440GX_ZMII_ADDR, OCP_IRQ_NA, OCP_CPM_NA}, + {OCP_VENDOR_INVALID, OCP_FUNC_INVALID, 0x0, OCP_IRQ_NA, OCP_CPM_NA}, +}; diff -Nru a/arch/ppc/platforms/4xx/ibm440gx.h b/arch/ppc/platforms/4xx/ibm440gx.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/ppc/platforms/4xx/ibm440gx.h Thu Sep 4 15:38:48 2003 @@ -0,0 +1,123 @@ +/* + * arch/ppc/platforms/ibm440gx.h + * + * PPC440GX definitions + * + * Matt Porter + * + * Copyright 2002 Roland Dreier + * Copyright 2003 MontaVista Software, 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 (at your + * option) any later version. + * + */ + +#ifdef __KERNEL__ +#ifndef __PPC_PLATFORMS_IBM440GX_H +#define __PPC_PLATFORMS_IBM440GX_H + +#include + +#include + +/* UART */ +#define PPC440GX_UART0_ADDR 0x0000000140000200ULL +#define PPC440GX_UART1_ADDR 0x0000000140000300ULL +#define UART0_IRQ 0 +#define UART1_IRQ 1 + +/* EMAC */ +#define PPC440GX_EMAC0_ADDR 0x0000000140000800ULL +#define PPC440GX_EMAC1_ADDR 0x0000000140000900ULL +#define PPC440GX_EMAC2_ADDR 0x0000000140000C00ULL +#define PPC440GX_EMAC3_ADDR 0x0000000140000E00ULL +#define PPC440GX_EMAC_SIZE 0xFC +#define EMAC_NUMS 2 +#define BL_MAC_WOL 61 /* WOL */ +#define BL_MAC_WOL1 63 /* WOL */ +#define BL_MAC_WOL2 65 /* WOL */ +#define BL_MAC_WOL3 67 /* WOL */ +#define BL_MAL_SERR 32 /* MAL SERR */ +#define BL_MAL_TXDE 33 /* MAL TXDE */ +#define BL_MAL_RXDE 34 /* MAL RXDE */ +#define BL_MAL_TXEOB 10 /* MAL TX EOB */ +#define BL_MAL_RXEOB 11 /* MAL RX EOB */ +#define BL_MAC_ETH0 60 /* MAC */ +#define BL_MAC_ETH1 62 /* MAC */ +#define BL_MAC_ETH2 64 /* MAC */ +#define BL_MAC_ETH3 66 /* MAC */ +#define BL_TAH0 68 /* TAH 0 */ +#define BL_TAH1 69 /* TAH 1 */ + +/* TAH */ +#define PPC440GX_TAH0_ADDR 0x0000000140000B00ULL +#define PPC440GX_TAH1_ADDR 0x0000000140000D00ULL +#define PPC440GX_TAH_SIZE 0xFC + +/* ZMII */ +#define PPC440GX_ZMII_ADDR 0x0000000140000780ULL +#define PPC440GX_ZMII_SIZE 0x0c + +/* RGMII */ +#define PPC440GX_RGMII_ADDR 0x0000000140000790ULL +#define PPC440GX_RGMII_SIZE 0x0c + +/* IIC */ +#define PPC440GX_IIC0_ADDR 0x40000400 +#define PPC440GX_IIC1_ADDR 0x40000500 +#define IIC0_IRQ 2 +#define IIC1_IRQ 3 + +/* GPIO */ +#define PPC440GX_GPIO0_ADDR 0x0000000140000700ULL + +/* Clock and Power Management */ +#define IBM_CPM_IIC0 0x80000000 /* IIC interface */ +#define IBM_CPM_IIC1 0x40000000 /* IIC interface */ +#define IBM_CPM_PCI 0x20000000 /* PCI bridge */ +#define IBM_CPM_RGMII 0x10000000 /* RGMII */ +#define IBM_CPM_TAHOE0 0x08000000 /* TAHOE 0 */ +#define IBM_CPM_TAHOE1 0x04000000 /* TAHOE 1 */ +#define IBM_CPM_CPU 0x02000000 /* processor core */ +#define IBM_CPM_DMA 0x01000000 /* DMA controller */ +#define IBM_CPM_BGO 0x00800000 /* PLB to OPB bus arbiter */ +#define IBM_CPM_BGI 0x00400000 /* OPB to PLB bridge */ +#define IBM_CPM_EBC 0x00200000 /* External Bux Controller */ +#define IBM_CPM_EBM 0x00100000 /* Ext Bus Master Interface */ +#define IBM_CPM_DMC 0x00080000 /* SDRAM peripheral controller */ +#define IBM_CPM_PLB 0x00040000 /* PLB bus arbiter */ +#define IBM_CPM_SRAM 0x00020000 /* SRAM memory controller */ +#define IBM_CPM_PPM 0x00002000 /* PLB Performance Monitor */ +#define IBM_CPM_UIC1 0x00001000 /* Universal Interrupt Controller */ +#define IBM_CPM_GPIO0 0x00000800 /* General Purpose IO (??) */ +#define IBM_CPM_GPT 0x00000400 /* General Purpose Timers */ +#define IBM_CPM_UART0 0x00000200 /* serial port 0 */ +#define IBM_CPM_UART1 0x00000100 /* serial port 1 */ +#define IBM_CPM_UIC0 0x00000080 /* Universal Interrupt Controller */ +#define IBM_CPM_TMRCLK 0x00000040 /* CPU timers */ +#define IBM_CPM_EMAC0 0x00000020 /* EMAC 0 */ +#define IBM_CPM_EMAC1 0x00000010 /* EMAC 1 */ +#define IBM_CPM_EMAC2 0x00000008 /* EMAC 2 */ +#define IBM_CPM_EMAC3 0x00000004 /* EMAC 3 */ + +#define DFLT_IBM4xx_PM ~(IBM_CPM_UIC | IBM_CPM_UIC1 | IBM_CPM_CPU \ + | IBM_CPM_EBC | IBM_CPM_SRAM | IBM_CPM_BGO \ + | IBM_CPM_EBM | IBM_CPM_PLB | IBM_CPM_OPB \ + | IBM_CPM_TMRCLK | IBM_CPM_DMA | IBM_CPM_PCI \ + | IBM_CPM_TAHOE0 | IBM_CPM_TAHOE1 \ + | IBM_CPM_EMAC0 | IBM_CPM_EMAC1 \ + | IBM_CPM_EMAC2 | IBM_CPM_EMAC3 ) + +/* OPB */ +#define PPC440GX_OPB_BASE_START 0x0000000140000000ULL + +/* + * Serial port defines + */ +#define RS_TABLE_SIZE 2 + +#endif /* __PPC_PLATFORMS_IBM440GX_H */ +#endif /* __KERNEL__ */ diff -Nru a/arch/ppc/platforms/4xx/ocotea.c b/arch/ppc/platforms/4xx/ocotea.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/ppc/platforms/4xx/ocotea.c Thu Sep 4 15:38:48 2003 @@ -0,0 +1,459 @@ +/* + * arch/ppc/platforms/ocotea.c + * + * Ocotea board specific routines + * + * Matt Porter + * + * Copyright 2003 MontaVista Software 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 (at your + * option) any later version. + */ + +#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 +#include +#include +#include +#include + +extern void abort(void); + +/* Global Variables */ +bd_t __res; + +static void __init +ocotea_calibrate_decr(void) +{ + unsigned int freq; + + freq = OCOTEA_SYSCLK; + + tb_ticks_per_jiffy = freq / HZ; + tb_to_us = mulhwu_scale_factor(freq, 1000000); + + /* Set the time base to zero */ + mtspr(SPRN_TBWL, 0); + mtspr(SPRN_TBWU, 0); + + /* Clear any pending timer interrupts */ + mtspr(SPRN_TSR, TSR_ENW | TSR_WIS | TSR_DIS | TSR_FIS); + + /* Enable decrementer interrupt */ + mtspr(SPRN_TCR, TCR_DIE); +} + +static int +ocotea_show_cpuinfo(struct seq_file *m) +{ + seq_printf(m, "vendor\t\t: IBM\n"); + seq_printf(m, "machine\t\t: PPC440GX EVB (Ocotea)\n"); + + return 0; +} +static inline int +ocotea_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin) +{ + static char pci_irq_table[][4] = + /* + * PCI IDSEL/INTPIN->INTLINE + * A B C D + */ + { + { 23, 23, 23, 23 }, /* IDSEL 1 - PCI Slot 0 */ + { 24, 24, 24, 24 }, /* IDSEL 2 - PCI Slot 1 */ + { 25, 25, 25, 25 }, /* IDSEL 3 - PCI Slot 2 */ + { 26, 26, 26, 26 }, /* IDSEL 4 - PCI Slot 3 */ + }; + + const long min_idsel = 1, max_idsel = 4, irqs_per_slot = 4; + return PCI_IRQ_TABLE_LOOKUP; +} + +#define PCIX_READW(offset) \ + (readw((u32)pcix_reg_base+offset)) + +#define PCIX_WRITEW(value, offset) \ + (writew(value, (u32)pcix_reg_base+offset)) + +#define PCIX_WRITEL(value, offset) \ + (writel(value, (u32)pcix_reg_base+offset)) + +/* + * FIXME: This is only here to "make it work". This will move + * to a ibm_pcix.c which will contain a generic IBM PCIX bridge + * configuration library. -Matt + */ +static void __init +ocotea_setup_pcix(void) +{ + void *pcix_reg_base; + + pcix_reg_base = ioremap64(PCIX0_REG_BASE, PCIX0_REG_SIZE); + + /* Enable PCIX0 I/O, Mem, and Busmaster cycles */ + PCIX_WRITEW(PCIX_READW(PCIX0_COMMAND) | PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER, PCIX0_COMMAND); + + /* Disable all windows */ + PCIX_WRITEL(0, PCIX0_POM0SA); + PCIX_WRITEL(0, PCIX0_POM1SA); + PCIX_WRITEL(0, PCIX0_POM2SA); + PCIX_WRITEL(0, PCIX0_PIM0SA); + PCIX_WRITEL(0, PCIX0_PIM0SAH); + PCIX_WRITEL(0, PCIX0_PIM1SA); + PCIX_WRITEL(0, PCIX0_PIM2SA); + PCIX_WRITEL(0, PCIX0_PIM2SAH); + + /* Setup 2GB PLB->PCI outbound mem window (3_8000_0000->0_8000_0000) */ + PCIX_WRITEL(0x00000003, PCIX0_POM0LAH); + PCIX_WRITEL(0x80000000, PCIX0_POM0LAL); + PCIX_WRITEL(0x00000000, PCIX0_POM0PCIAH); + PCIX_WRITEL(0x80000000, PCIX0_POM0PCIAL); + PCIX_WRITEL(0x80000001, PCIX0_POM0SA); + + /* Setup 2GB PCI->PLB inbound memory window at 0, enable MSIs */ + PCIX_WRITEL(0x00000000, PCIX0_PIM0LAH); + PCIX_WRITEL(0x00000000, PCIX0_PIM0LAL); + PCIX_WRITEL(0xe0000007, PCIX0_PIM0SA); + + eieio(); +} + +static void __init +ocotea_setup_hose(void) +{ + struct pci_controller *hose; + + /* Configure windows on the PCI-X host bridge */ + ocotea_setup_pcix(); + + hose = pcibios_alloc_controller(); + + if (!hose) + return; + + hose->first_busno = 0; + hose->last_busno = 0xff; + + hose->pci_mem_offset = OCOTEA_PCI_MEM_OFFSET; + + pci_init_resource(&hose->io_resource, + OCOTEA_PCI_LOWER_IO, + OCOTEA_PCI_UPPER_IO, + IORESOURCE_IO, + "PCI host bridge"); + + pci_init_resource(&hose->mem_resources[0], + OCOTEA_PCI_LOWER_MEM, + OCOTEA_PCI_UPPER_MEM, + IORESOURCE_MEM, + "PCI host bridge"); + + hose->io_space.start = OCOTEA_PCI_LOWER_IO; + hose->io_space.end = OCOTEA_PCI_UPPER_IO; + hose->mem_space.start = OCOTEA_PCI_LOWER_MEM; + hose->mem_space.end = OCOTEA_PCI_UPPER_MEM; + isa_io_base = + (unsigned long)ioremap64(OCOTEA_PCI_IO_BASE, OCOTEA_PCI_IO_SIZE); + hose->io_base_virt = (void *)isa_io_base; + + setup_indirect_pci(hose, + OCOTEA_PCI_CFGA_PLB32, + OCOTEA_PCI_CFGD_PLB32); + hose->set_cfg_type = 1; + + hose->last_busno = pciauto_bus_scan(hose, hose->first_busno); + + ppc_md.pci_swizzle = common_swizzle; + ppc_md.pci_map_irq = ocotea_map_irq; +} + + +TODC_ALLOC(); + +static void __init +ocotea_early_serial_map(void) +{ + struct uart_port port; + + /* Setup ioremapped serial port access */ + memset(&port, 0, sizeof(port)); + port.membase = ioremap64(PPC440GX_UART0_ADDR, 8); + port.irq = 0; + port.uartclk = BASE_BAUD * 16; + port.regshift = 0; + port.iotype = SERIAL_IO_MEM; + port.flags = ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST; + port.line = 0; + + if (early_serial_setup(&port) != 0) { + printk("Early serial init of port 0 failed\n"); + } + + port.membase = ioremap64(PPC440GX_UART1_ADDR, 8); + port.irq = 1; + port.line = 1; + + if (early_serial_setup(&port) != 0) { + printk("Early serial init of port 1 failed\n"); + } +} + +static void __init +ocotea_setup_arch(void) +{ + unsigned char *addr; + unsigned long long mac64; + + /* Retrieve MAC addresses from flash */ + addr = ioremap64(OCOTEA_MAC_BASE, OCOTEA_MAC_SIZE); + mac64 = simple_strtoull(addr, 0, 16); + memcpy(__res.bi_enetaddr[0], (char *)&mac64+2, 6); + mac64 = simple_strtoull(addr+OCOTEA_MAC1_OFFSET, 0, 16); + memcpy(__res.bi_enetaddr[1], (char *)&mac64+2, 6); + iounmap(addr); + +#if !defined(CONFIG_BDI_SWITCH) + /* + * The Abatron BDI JTAG debugger does not tolerate others + * mucking with the debug registers. + */ + mtspr(SPRN_DBCR0, (DBCR0_TDE | DBCR0_IDM)); +#endif + + /* Setup TODC access */ + TODC_INIT(TODC_TYPE_DS1743, + 0, + 0, + ioremap64(OCOTEA_RTC_ADDR, OCOTEA_RTC_SIZE), + 8); + + /* init to some ~sane value until calibrate_delay() runs */ + loops_per_jiffy = 50000000/HZ; + + /* Setup PCI host bridge */ + ocotea_setup_hose(); + +#ifdef CONFIG_BLK_DEV_INITRD + if (initrd_start) + ROOT_DEV = Root_RAM0; + else +#endif +#ifdef CONFIG_ROOT_NFS + ROOT_DEV = Root_NFS; +#else + ROOT_DEV = Root_HDA1; +#endif + +#ifdef CONFIG_DUMMY_CONSOLE + conswitchp = &dummy_con; +#endif + + ocotea_early_serial_map(); + + /* Identify the system */ + printk("IBM Ocotea port (MontaVista Software, Inc. )\n"); +} + +static void +ocotea_restart(char *cmd) +{ + local_irq_disable(); + abort(); +} + +static void +ocotea_power_off(void) +{ + local_irq_disable(); + for(;;); +} + +static void +ocotea_halt(void) +{ + local_irq_disable(); + for(;;); +} + +/* + * Read the 440GX memory controller to get size of system memory. + */ +static unsigned long __init +ocotea_find_end_of_memory(void) +{ + u32 i, bank_config; + u32 mem_size = 0; + + for (i=0; i<4; i++) + { + switch (i) + { + case 0: + mtdcr(DCRN_SDRAM0_CFGADDR, SDRAM0_B0CR); + break; + case 1: + mtdcr(DCRN_SDRAM0_CFGADDR, SDRAM0_B1CR); + break; + case 2: + mtdcr(DCRN_SDRAM0_CFGADDR, SDRAM0_B2CR); + break; + case 3: + mtdcr(DCRN_SDRAM0_CFGADDR, SDRAM0_B3CR); + break; + } + + bank_config = mfdcr(DCRN_SDRAM0_CFGDATA); + + if (!(bank_config & SDRAM_CONFIG_BANK_ENABLE)) + continue; + switch (SDRAM_CONFIG_BANK_SIZE(bank_config)) + { + case SDRAM_CONFIG_SIZE_8M: + mem_size += PPC44x_MEM_SIZE_8M; + break; + case SDRAM_CONFIG_SIZE_16M: + mem_size += PPC44x_MEM_SIZE_16M; + break; + case SDRAM_CONFIG_SIZE_32M: + mem_size += PPC44x_MEM_SIZE_32M; + break; + case SDRAM_CONFIG_SIZE_64M: + mem_size += PPC44x_MEM_SIZE_64M; + break; + case SDRAM_CONFIG_SIZE_128M: + mem_size += PPC44x_MEM_SIZE_128M; + break; + case SDRAM_CONFIG_SIZE_256M: + mem_size += PPC44x_MEM_SIZE_256M; + break; + case SDRAM_CONFIG_SIZE_512M: + mem_size += PPC44x_MEM_SIZE_512M; + break; + } + } + return mem_size; +} + +static void __init +ocotea_init_irq(void) +{ + int i; + + /* Enable PPC440GP interrupt compatibility mode */ + SDR_WRITE(DCRN_SDR_MFR,SDR_READ(DCRN_SDR_MFR) | DCRN_SDR_MFR_PCM); + + ppc4xx_pic_init(); + + for (i = 0; i < NR_IRQS; i++) + irq_desc[i].handler = ppc4xx_pic; +} + +#ifdef CONFIG_SERIAL_TEXT_DEBUG +#include +#include +#include +struct serial_state rs_table[RS_TABLE_SIZE] = { + SERIAL_PORT_DFNS /* Defined in */ +}; + +static void +ocotea_progress(char *s, unsigned short hex) +{ + volatile char c; + volatile unsigned long com_port; + u16 shift; + + com_port = (unsigned long)rs_table[0].iomem_base; + 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; + + } + + /* Send LF/CR to pretty up output */ + while ((*((volatile unsigned char *)com_port + + (UART_LSR << shift)) & UART_LSR_THRE) == 0) + ; + *(volatile unsigned char *)com_port = '\r'; + while ((*((volatile unsigned char *)com_port + + (UART_LSR << shift)) & UART_LSR_THRE) == 0) + ; + *(volatile unsigned char *)com_port = '\n'; +} +#endif /* CONFIG_SERIAL_TEXT_DEBUG */ + +#if 0 +static void __init +ocotea_map_io(void) +{ + io_block_mapping(0xe0000000, 0x0000000140000000, + 0x00001000, _PAGE_IO); +} +#endif + +void __init platform_init(unsigned long r3, unsigned long r4, + unsigned long r5, unsigned long r6, unsigned long r7) +{ + parse_bootinfo((struct bi_record *) (r3 + KERNELBASE)); + + ppc_md.setup_arch = ocotea_setup_arch; + ppc_md.show_cpuinfo = ocotea_show_cpuinfo; + ppc_md.init_IRQ = ocotea_init_irq; + ppc_md.get_irq = NULL; /* Set in ppc4xx_pic_init() */ + + ppc_md.find_end_of_memory = ocotea_find_end_of_memory; + + ppc_md.restart = ocotea_restart; + ppc_md.power_off = ocotea_power_off; + ppc_md.halt = ocotea_halt; + + ppc_md.calibrate_decr = ocotea_calibrate_decr; + ppc_md.time_init = todc_time_init; + ppc_md.set_rtc_time = todc_set_rtc_time; + ppc_md.get_rtc_time = todc_get_rtc_time; + + ppc_md.nvram_read_val = todc_direct_read_val; + ppc_md.nvram_write_val = todc_direct_write_val; + +#ifdef CONFIG_SERIAL_TEXT_DEBUG + ppc_md.progress = ocotea_progress; +#endif /* CONFIG_SERIAL_TEXT_DEBUG */ +#ifdef CONFIG_KGDB + ppc_md.early_serial_map = ocotea_early_serial_map; +#endif +} diff -Nru a/arch/ppc/platforms/4xx/ocotea.h b/arch/ppc/platforms/4xx/ocotea.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/ppc/platforms/4xx/ocotea.h Thu Sep 4 15:38:48 2003 @@ -0,0 +1,84 @@ +/* + * arch/ppc/platforms/ocotea.h + * + * Ocotea board definitions + * + * Matt Porter + * + * Copyright 2003 MontaVista Software 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 (at your + * option) any later version. + * + */ + +#ifdef __KERNEL__ +#ifndef __ASM_OCOTEA_H__ +#define __ASM_OCOTEA_H__ + +#include +#include + +/* F/W TLB mapping used in bootloader glue to reset EMAC */ +#define PPC44x_EMAC0_MR0 0xE0000800 + +/* Location of MAC addresses in firmware */ +#define OCOTEA_MAC_BASE (OCOTEA_SMALL_FLASH_HIGH+0xc0500) +#define OCOTEA_MAC_SIZE 0x200 +#define OCOTEA_MAC1_OFFSET 0x100 + +/* Default clock rate */ +#define OCOTEA_SYSCLK 25000000 + +/* RTC/NVRAM location */ +#define OCOTEA_RTC_ADDR 0x0000000148000000ULL +#define OCOTEA_RTC_SIZE 0x2000 + +/* Flash */ +#define OCOTEA_FPGA_ADDR 0x0000000148300000ULL +#define OCOTEA_BOOT_LARGE_FLASH(x) (x & 0x40) +#define OCOTEA_SMALL_FLASH_LOW 0x00000001ff900000ULL +#define OCOTEA_SMALL_FLASH_HIGH 0x00000001fff00000ULL +#define OCOTEA_SMALL_FLASH_SIZE 0x100000 +#define OCOTEA_LARGE_FLASH_LOW 0x00000001ff800000ULL +#define OCOTEA_LARGE_FLASH_HIGH 0x00000001ffc00000ULL +#define OCOTEA_LARGE_FLASH_SIZE 0x400000 + +/* + * Serial port defines + */ +#define RS_TABLE_SIZE 2 + +/* OpenBIOS defined UART mappings, used before early_serial_setup */ +#define UART0_IO_BASE (u8 *) 0xE0000200 +#define UART1_IO_BASE (u8 *) 0xE0000300 + +#define BASE_BAUD 11059200/16 +#define STD_UART_OP(num) \ + { 0, BASE_BAUD, 0, UART##num##_IRQ, \ + (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST), \ + iomem_base: UART##num##_IO_BASE, \ + io_type: SERIAL_IO_MEM}, + +#define SERIAL_PORT_DFNS \ + STD_UART_OP(0) \ + STD_UART_OP(1) + +/* PCI support */ +#define OCOTEA_PCI_LOWER_IO 0x00000000 +#define OCOTEA_PCI_UPPER_IO 0x0000ffff +#define OCOTEA_PCI_LOWER_MEM 0x80000000 +#define OCOTEA_PCI_UPPER_MEM 0xffffefff + +#define OCOTEA_PCI_CFGREGS_BASE 0x000000020ec00000ULL +#define OCOTEA_PCI_CFGA_PLB32 0x0ec00000 +#define OCOTEA_PCI_CFGD_PLB32 0x0ec00004 + +#define OCOTEA_PCI_IO_BASE 0x0000000208000000ULL +#define OCOTEA_PCI_IO_SIZE 0x00010000 +#define OCOTEA_PCI_MEM_OFFSET 0x00000000 + +#endif /* __ASM_OCOTEA_H__ */ +#endif /* __KERNEL__ */ diff -Nru a/arch/ppc/platforms/mcpn765_serial.h b/arch/ppc/platforms/mcpn765_serial.h --- a/arch/ppc/platforms/mcpn765_serial.h Thu Sep 4 15:38:42 2003 +++ b/arch/ppc/platforms/mcpn765_serial.h Thu Sep 4 15:38:42 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 Thu Sep 4 15:38:39 2003 +++ b/arch/ppc/platforms/mcpn765_setup.c Thu Sep 4 15:38:39 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 Thu Sep 4 15:38:36 2003 +++ b/arch/ppc/platforms/pmac_cpufreq.c Thu Sep 4 15:38:36 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 Thu Sep 4 15:38:44 2003 +++ b/arch/ppc/platforms/pmac_pic.c Thu Sep 4 15:38:44 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 Thu Sep 4 15:38:48 2003 +++ b/arch/ppc/platforms/sandpoint.c Thu Sep 4 15:38:48 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 Thu Sep 4 15:38:32 2003 +++ b/arch/ppc/platforms/sandpoint.h Thu Sep 4 15:38:32 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/Makefile b/arch/ppc/syslib/Makefile --- a/arch/ppc/syslib/Makefile Thu Sep 4 15:38:29 2003 +++ b/arch/ppc/syslib/Makefile Thu Sep 4 15:38:29 2003 @@ -13,6 +13,8 @@ CFLAGS_btext.o += -mrelocatable-lib obj-$(CONFIG_PPCBUG_NVRAM) += prep_nvram.o +obj-$(CONFIG_44x) += ibm44x_common.o +obj-$(CONFIG_440GP) += ibm440gp_common.o ifeq ($(CONFIG_4xx),y) obj-$(CONFIG_4xx) += ppc4xx_pic.o obj-$(CONFIG_40x) += ppc4xx_setup.o @@ -33,6 +35,7 @@ obj-$(CONFIG_PPC_PREP) += open_pic.o indirect_pci.o i8259.o obj-$(CONFIG_ADIR) += i8259.o indirect_pci.o pci_auto.o \ todc_time.o +obj-$(CONFIG_EBONY) += indirect_pci.o pci_auto.o todc_time.o obj-$(CONFIG_EV64260) += gt64260_common.o gt64260_pic.o \ indirect_pci.o todc_time.o pci_auto.o obj-$(CONFIG_GEMINI) += open_pic.o i8259.o indirect_pci.o @@ -46,6 +49,7 @@ pci_auto.o indirect_pci.o obj-$(CONFIG_MVME5100) += open_pic.o todc_time.o indirect_pci.o \ i8259.o pci_auto.o pplus_common.o +obj-$(CONFIG_OCOTEA) += indirect_pci.o pci_auto.o todc_time.o obj-$(CONFIG_PAL4) += cpc700_pic.o obj-$(CONFIG_PCORE) += mpc10x_common.o todc_time.o i8259.o \ indirect_pci.o pci_auto.o diff -Nru a/arch/ppc/syslib/ibm440gp_common.c b/arch/ppc/syslib/ibm440gp_common.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/ppc/syslib/ibm440gp_common.c Thu Sep 4 15:38:48 2003 @@ -0,0 +1,77 @@ +/* + * arch/ppc/syslib/ibm440gp_common.c + * + * PPC440GP system library + * + * Matt Porter + * Copyright 2002-2003 MontaVista Software Inc. + * + * Eugene Surovegin or + * Copyright (c) 2003 Zultys 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 the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + */ +#include +#include +#include +#include + +/* + * Calculate 440GP clocks + */ +void __init ibm440gp_get_clocks(struct ibm440gp_clocks* p, + unsigned int sys_clk, + unsigned int ser_clk) +{ + u32 cpc0_sys0 = mfdcr(DCRN_CPC0_SYS0); + u32 cpc0_cr0 = mfdcr(DCRN_CPC0_CR0); + u32 opdv, epdv; + + if (cpc0_sys0 & 0x2){ + /* Bypass system PLL */ + p->cpu = p->plb = sys_clk; + } + else { + u32 fbdv, fwdva, fwdvb, m, vco; + + fbdv = (cpc0_sys0 >> 18) & 0x0f; + if (!fbdv) + fbdv = 16; + + fwdva = 8 - ((cpc0_sys0 >> 15) & 0x7); + fwdvb = 8 - ((cpc0_sys0 >> 12) & 0x7); + + /* Feedback path */ + if (cpc0_sys0 & 0x00000080){ + /* PerClk */ + m = fwdvb * opdv * epdv; + } + else { + /* CPU clock */ + m = fbdv * fwdva; + } + vco = sys_clk * m; + p->cpu = vco / fwdva; + p->plb = vco / fwdvb; + } + + opdv = ((cpc0_sys0 >> 10) & 0x3) + 1; + epdv = ((cpc0_sys0 >> 8) & 0x3) + 1; + + p->opb = p->plb / opdv; + p->ebc = p->opb / epdv; + + if (cpc0_cr0 & 0x00400000){ + /* External UART clock */ + p->uart = ser_clk; + } + else { + /* Internal UART clock */ + u32 uart_div = ((cpc0_cr0 >> 16) & 0x1f) + 1; + p->uart = p->plb / uart_div; + } +} diff -Nru a/arch/ppc/syslib/ibm440gp_common.h b/arch/ppc/syslib/ibm440gp_common.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/ppc/syslib/ibm440gp_common.h Thu Sep 4 15:38:48 2003 @@ -0,0 +1,45 @@ +/* + * arch/ppc/syslib/ibm440gp_common.h + * + * PPC440GP system library + * + * Eugene Surovegin or + * Copyright (c) 2003 Zultys 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 the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + */ +#ifdef __KERNEL__ +#ifndef __PPC_SYSLIB_IBM440GP_COMMON_H +#define __PPC_SYSLIB_IBM440GP_COMMON_H + +#ifndef __ASSEMBLY__ + +#include +#include + +/* + * All clocks are in Hz + */ +struct ibm440gp_clocks { + unsigned int cpu; /* CPUCoreClk */ + unsigned int plb; /* PLBClk */ + unsigned int opb; /* OPBClk */ + unsigned int ebc; /* PerClk */ + unsigned int uart; +}; + +/* + * Please, refer to the Figure 13.1 in 440GP user manual + * + * if internal UART clock is used, ser_clk is ignored + */ +void ibm440gp_get_clocks(struct ibm440gp_clocks*, unsigned int sys_clk, + unsigned int ser_clk) __init; + +#endif /* __ASSEMBLY__ */ +#endif /* __PPC_SYSLIB_IBM440GP_COMMON_H */ +#endif /* __KERNEL__ */ diff -Nru a/arch/ppc/syslib/ibm44x_common.c b/arch/ppc/syslib/ibm44x_common.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/ppc/syslib/ibm44x_common.c Thu Sep 4 15:38:48 2003 @@ -0,0 +1,37 @@ +/* + * arch/ppc/syslib/ibm44x_common.c + * + * PPC44x system library + * + * Matt Porter + * Copyright 2002-2003 MontaVista Software 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 (at your + * option) any later version. + * + */ +#include +#include +#include +#include + +phys_addr_t fixup_bigphys_addr(phys_addr_t addr, phys_addr_t size) +{ + phys_addr_t page_4gb = 0; + + /* + * Trap the least significant 32-bit portions of an + * address in the 440's 36-bit address space. Fix + * them up with the appropriate ERPN + */ + if ((addr >= PPC44x_IO_LO) && (addr < PPC44x_IO_HI)) + page_4gb = PPC44x_IO_PAGE; + else if ((addr >= PPC44x_PCICFG_LO) && (addr < PPC44x_PCICFG_HI)) + page_4gb = PPC44x_PCICFG_PAGE; + else if ((addr >= PPC44x_PCIMEM_LO) && (addr < PPC44x_PCIMEM_HI)) + page_4gb = PPC44x_PCIMEM_PAGE; + + return (page_4gb | addr); +}; diff -Nru a/arch/ppc/syslib/of_device.c b/arch/ppc/syslib/of_device.c --- a/arch/ppc/syslib/of_device.c Thu Sep 4 15:38:47 2003 +++ b/arch/ppc/syslib/of_device.c Thu Sep 4 15:38:47 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 Thu Sep 4 15:38:36 2003 +++ b/arch/ppc/syslib/open_pic.c Thu Sep 4 15:38:36 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 Thu Sep 4 15:38:29 2003 +++ b/arch/ppc/syslib/prom.c Thu Sep 4 15:38:29 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 Thu Sep 4 15:38:28 2003 +++ b/arch/ppc/xmon/start.c Thu Sep 4 15:38:28 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 Thu Sep 4 15:38:35 2003 +++ b/arch/ppc64/Kconfig Thu Sep 4 15:38:35 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 Thu Sep 4 15:38:47 2003 +++ b/arch/ppc64/kernel/ioctl32.c Thu Sep 4 15:38:47 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 Thu Sep 4 15:38:40 2003 +++ b/arch/ppc64/kernel/proc_ppc64.c Thu Sep 4 15:38:40 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 Thu Sep 4 15:38:45 2003 +++ b/arch/ppc64/kernel/scanlog.c Thu Sep 4 15:38:45 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 Thu Sep 4 15:38:32 2003 +++ b/arch/s390/Kconfig Thu Sep 4 15:38:32 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 Thu Sep 4 15:38:39 2003 +++ b/arch/s390/kernel/compat_ioctl.c Thu Sep 4 15:38:39 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 Thu Sep 4 15:38:47 2003 +++ b/arch/sh/Kconfig Thu Sep 4 15:38:47 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 Thu Sep 4 15:38:33 2003 +++ b/arch/sh/boards/adx/mach.c Thu Sep 4 15:38:33 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 Thu Sep 4 15:38:40 2003 +++ b/arch/sh/boards/bigsur/mach.c Thu Sep 4 15:38:40 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 Thu Sep 4 15:38:45 2003 +++ b/arch/sh/boards/cat68701/mach.c Thu Sep 4 15:38:45 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 Thu Sep 4 15:38:44 2003 +++ b/arch/sh/boards/cqreek/mach.c Thu Sep 4 15:38:44 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 Thu Sep 4 15:38:30 2003 +++ b/arch/sh/boards/dmida/mach.c Thu Sep 4 15:38:30 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 Thu Sep 4 15:38:31 2003 +++ b/arch/sh/boards/dreamcast/irq.c Thu Sep 4 15:38:31 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 Thu Sep 4 15:38:30 2003 +++ b/arch/sh/boards/dreamcast/mach.c Thu Sep 4 15:38:30 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 Thu Sep 4 15:38:30 2003 +++ b/arch/sh/boards/ec3104/irq.c Thu Sep 4 15:38:30 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 Thu Sep 4 15:38:42 2003 +++ b/arch/sh/boards/ec3104/mach.c Thu Sep 4 15:38:42 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 Thu Sep 4 15:38:36 2003 +++ b/arch/sh/boards/harp/mach.c Thu Sep 4 15:38:36 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 Thu Sep 4 15:38:37 2003 +++ b/arch/sh/boards/hp6xx/hp620/mach.c Thu Sep 4 15:38:37 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 Thu Sep 4 15:38:47 2003 +++ b/arch/sh/boards/hp6xx/hp680/mach.c Thu Sep 4 15:38:47 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 Thu Sep 4 15:38:47 2003 +++ b/arch/sh/boards/hp6xx/hp690/mach.c Thu Sep 4 15:38:47 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 Thu Sep 4 15:38:31 2003 +++ b/arch/sh/boards/overdrive/mach.c Thu Sep 4 15:38:31 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 Thu Sep 4 15:38:37 2003 +++ b/arch/sh/boards/saturn/irq.c Thu Sep 4 15:38:37 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 Thu Sep 4 15:38:46 2003 +++ b/arch/sh/boards/saturn/mach.c Thu Sep 4 15:38:46 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 Thu Sep 4 15:38:43 2003 +++ b/arch/sh/boards/se/770x/mach.c Thu Sep 4 15:38:43 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 Thu Sep 4 15:38:35 2003 +++ b/arch/sh/boards/se/7751/mach.c Thu Sep 4 15:38:35 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 Thu Sep 4 15:38:43 2003 +++ b/arch/sh/boards/sh2000/mach.c Thu Sep 4 15:38:43 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 Thu Sep 4 15:38:29 2003 +++ b/arch/sh/boards/unknown/mach.c Thu Sep 4 15:38:29 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 Thu Sep 4 15:38:47 2003 +++ b/arch/sh/cchips/hd6446x/hd64465/setup.c Thu Sep 4 15:38:47 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 Thu Sep 4 15:38:28 2003 +++ b/arch/sparc/Kconfig Thu Sep 4 15:38:28 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 Thu Sep 4 15:38:45 2003 +++ b/arch/sparc/boot/Makefile Thu Sep 4 15:38:45 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 Thu Sep 4 15:38:33 2003 +++ b/arch/sparc/kernel/entry.S Thu Sep 4 15:38:33 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 Thu Sep 4 15:38:47 2003 +++ b/arch/sparc/kernel/ioport.c Thu Sep 4 15:38:47 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 Thu Sep 4 15:38:32 2003 +++ b/arch/sparc/kernel/sys_sunos.c Thu Sep 4 15:38:32 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 Thu Sep 4 15:38:34 2003 +++ b/arch/sparc/kernel/systbls.S Thu Sep 4 15:38:34 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 Thu Sep 4 15:38:43 2003 +++ b/arch/sparc64/Kconfig Thu Sep 4 15:38:43 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 Thu Sep 4 15:38:28 2003 +++ b/arch/sparc64/kernel/entry.S Thu Sep 4 15:38:28 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 Thu Sep 4 15:38:44 2003 +++ b/arch/sparc64/kernel/ioctl32.c Thu Sep 4 15:38:44 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 Thu Sep 4 15:38:45 2003 +++ b/arch/sparc64/kernel/irq.c Thu Sep 4 15:38:45 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 Thu Sep 4 15:38:36 2003 +++ b/arch/sparc64/kernel/pci_psycho.c Thu Sep 4 15:38:36 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 Thu Sep 4 15:38:46 2003 +++ b/arch/sparc64/kernel/pci_sabre.c Thu Sep 4 15:38:46 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 Thu Sep 4 15:38:39 2003 +++ b/arch/sparc64/kernel/pci_schizo.c Thu Sep 4 15:38:39 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/semaphore.c b/arch/sparc64/kernel/semaphore.c --- a/arch/sparc64/kernel/semaphore.c Thu Sep 4 15:38:42 2003 +++ b/arch/sparc64/kernel/semaphore.c Thu Sep 4 15:38:42 2003 @@ -110,6 +110,7 @@ void down(struct semaphore *sem) { + might_sleep(); /* This atomically does: * old_val = sem->count; * new_val = sem->count - 1; @@ -219,6 +220,7 @@ { int ret = 0; + might_sleep(); /* This atomically does: * old_val = sem->count; * new_val = sem->count - 1; diff -Nru a/arch/sparc64/kernel/sys_sparc32.c b/arch/sparc64/kernel/sys_sparc32.c --- a/arch/sparc64/kernel/sys_sparc32.c Thu Sep 4 15:38:38 2003 +++ b/arch/sparc64/kernel/sys_sparc32.c Thu Sep 4 15:38:38 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 Thu Sep 4 15:38:37 2003 +++ b/arch/sparc64/kernel/sys_sunos32.c Thu Sep 4 15:38:37 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 Thu Sep 4 15:38:32 2003 +++ b/arch/sparc64/kernel/systbls.S Thu Sep 4 15:38:32 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 Thu Sep 4 15:38:39 2003 +++ b/arch/sparc64/mm/hugetlbpage.c Thu Sep 4 15:38:39 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 Thu Sep 4 15:38:45 2003 +++ b/arch/sparc64/solaris/misc.c Thu Sep 4 15:38:45 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 Thu Sep 4 15:38:32 2003 +++ b/arch/sparc64/solaris/socksys.c Thu Sep 4 15:38:32 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 Thu Sep 4 15:38:28 2003 +++ b/arch/sparc64/solaris/systbl.S Thu Sep 4 15:38:28 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 Thu Sep 4 15:38:32 2003 +++ b/arch/sparc64/solaris/timod.c Thu Sep 4 15:38:32 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 Thu Sep 4 15:38:33 2003 +++ b/arch/v850/Kconfig Thu Sep 4 15:38:33 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 Thu Sep 4 15:38:38 2003 +++ b/arch/v850/kernel/vmlinux.lds.S Thu Sep 4 15:38:38 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 Thu Sep 4 15:38:42 2003 +++ b/arch/x86_64/Kconfig Thu Sep 4 15:38:42 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 Thu Sep 4 15:38:39 2003 +++ b/arch/x86_64/defconfig Thu Sep 4 15:38:39 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 Thu Sep 4 15:38:35 2003 +++ b/arch/x86_64/ia32/ia32_ioctl.c Thu Sep 4 15:38:35 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 Thu Sep 4 15:38:32 2003 +++ b/arch/x86_64/ia32/sys_ia32.c Thu Sep 4 15:38:32 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 Thu Sep 4 15:38:30 2003 +++ b/arch/x86_64/kernel/apic.c Thu Sep 4 15:38:30 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 Thu Sep 4 15:38:34 2003 +++ b/arch/x86_64/kernel/io_apic.c Thu Sep 4 15:38:34 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 Thu Sep 4 15:38:30 2003 +++ b/arch/x86_64/kernel/ioport.c Thu Sep 4 15:38:30 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 Thu Sep 4 15:38:31 2003 +++ b/arch/x86_64/kernel/mpparse.c Thu Sep 4 15:38:31 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 Thu Sep 4 15:38:30 2003 +++ b/arch/x86_64/kernel/msr.c Thu Sep 4 15:38:30 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 Thu Sep 4 15:38:29 2003 +++ b/arch/x86_64/kernel/setup.c Thu Sep 4 15:38:29 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 Thu Sep 4 15:38:48 2003 +++ b/arch/x86_64/kernel/smpboot.c Thu Sep 4 15:38:48 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 Thu Sep 4 15:38:39 2003 +++ b/arch/x86_64/kernel/time.c Thu Sep 4 15:38:39 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 Thu Sep 4 15:38:42 2003 +++ b/arch/x86_64/kernel/vsyscall.c Thu Sep 4 15:38:42 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/crypto/tcrypt.c b/crypto/tcrypt.c --- a/crypto/tcrypt.c Thu Sep 4 15:38:42 2003 +++ b/crypto/tcrypt.c Thu Sep 4 15:38:42 2003 @@ -15,7 +15,6 @@ */ #include #include -#include #include #include #include diff -Nru a/drivers/Makefile b/drivers/Makefile --- a/drivers/Makefile Thu Sep 4 15:38:42 2003 +++ b/drivers/Makefile Thu Sep 4 15:38:42 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 Thu Sep 4 15:38:31 2003 +++ b/drivers/acorn/block/fd1772.c Thu Sep 4 15:38:31 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 Thu Sep 4 15:38:47 2003 +++ b/drivers/acpi/Kconfig Thu Sep 4 15:38:47 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 Thu Sep 4 15:38:29 2003 +++ b/drivers/acpi/pci_link.c Thu Sep 4 15:38:29 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 Thu Sep 4 15:38:33 2003 +++ b/drivers/atm/Kconfig Thu Sep 4 15:38:33 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 Thu Sep 4 15:38:29 2003 +++ b/drivers/atm/ambassador.c Thu Sep 4 15:38:29 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 Thu Sep 4 15:38:30 2003 +++ b/drivers/atm/eni.c Thu Sep 4 15:38:30 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 Thu Sep 4 15:38:30 2003 +++ b/drivers/atm/firestream.c Thu Sep 4 15:38:30 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/atm/lanai.c b/drivers/atm/lanai.c --- a/drivers/atm/lanai.c Thu Sep 4 15:38:31 2003 +++ b/drivers/atm/lanai.c Thu Sep 4 15:38:31 2003 @@ -15,12 +15,6 @@ * * Things not working yet: * - * o We're only set up to compile as a module currently. i.e. - * you should put the source in drivers/atm/lanai.c and then - * just do "make drivers/atm/lanai.o" from the main - * source directory. This will produce a drivers/atm/lanai.o - * file suitable for insmod'ing - * * o We don't support the Speedstream 3060 yet - this card has * an on-board DSL modem chip by Alcatel and the driver will * need some extra code added to handle it @@ -245,9 +239,6 @@ struct atm_vcc *atmvcc; /* atm_vcc who is transmitter */ int endptr; /* last endptr from service entry */ struct sk_buff_head backlog; - struct sk_buff *inprogress; /* We're streaming this PDU */ - unsigned char *pptr; /* Where we are in above */ - int inprogleft; /* Bytes left to send "inprogress" */ void (*unqueue)(struct lanai_dev *, struct lanai_vcc *, int); } tx; }; @@ -268,8 +259,6 @@ unsigned pcierr_m_target_abort; unsigned pcierr_s_target_abort; unsigned pcierr_master_parity; - unsigned service_novcc_rx; - unsigned service_novcc_tx; unsigned service_notx; unsigned service_norx; unsigned service_rxnotaal5; @@ -297,7 +286,7 @@ struct lanai_buffer aal0buf; /* AAL0 RX buffers */ u32 conf1, conf2; /* CONFIG[12] registers */ u32 status; /* STATUS register */ - spinlock_t txlock; + spinlock_t endtxlock; spinlock_t servicelock; struct atm_vcc *cbrvcc; int number; @@ -501,7 +490,6 @@ RWDEBUG("W [0x%08X] 0x%02X < 0x%08X\n", (unsigned int) lanai->base, (int) reg, val); writel(val, reg_addr(lanai, reg)); - mdelay(1); } static inline void conf1_write(const struct lanai_dev *lanai) @@ -537,63 +525,6 @@ udelay(5); } -/* -------------------- VCC LIST LOCK: */ - -/* - * The linux-atm code disables local IRQs while managing the list of - * VCCs on a card. This is good, but it doesn't save us against - * SMP. Unfortunately, fixing this will require changes in the - * API which will have to wait a little bit. It's a hard race to - * trigger accidentally, so it isn't TOO horrible so far. - * - * One possible solution would be to have an rwlock which is - * always grabbed _irq-style on writing. This would automatically - * be grabbed (for writing) by the higher layers on things that - * would result in a change in the vcc list (_open, _close, - * probably _change_qos) - thus it would also protect the - * higher-level list of vccs on each device (atm_dev->vccs). - * The driver would be responsible for grabbing it as a read_lock - * anytime it wants to consult its table of vccs - for instance - * when handling an incoming PDU. This also explains why we would - * probably want the write_lock while in _change_qos - to prevent - * handling of PDUs while possibly in an inconsistent state. - * Also, _send would grab the lock for reading. - * - * One problem with this is that _open and _close could no longer - * do anything that might provoke a schedule. First, it would - * force us to use GFP_ATOMIC memory (which is bad), but also - * some devices pretty much require scheduling due to long - * delays (see lanai_close for an example). So in this case - * we need a way to schedule without losing the spinlock. - * The cleanest way to do this is probably have a way to mark a - * VCC as "in progress" so that the interrupt handler can - * still disregard any traffic for it while _open or _close - * are sleeping on it. Then it will need to be _open and - * _close's job to relinquish the write_lock. Thus, the - * lock could be dropped around the times that scheduling - * might occur. Perhaps the _READY flag can be used for - * this purpose. - * - * One short note about this "upper layer grabs, driver - * relinquishes" write lock - since this needs to be - * an _irq lock we're going to have problem saving - * and restoring flags (_irqsave/_irqrestore). This - * shouldn't be a problem, however - we must just - * require that those syscalls are never called with - * interrupts disabled so we can use the non-flags-saving - * versions. - * - * Anyway, all of the above is vaporware currently - fixing - * this right will require changes in the API and all of - * the drivers - this will wait until 2.5.x most likely. - * The following NOP macros are just here to mark where - * the locks will be needed in the future. - */ -#define vcclist_read_lock() do {} while (0) -#define vcclist_read_unlock() do {} while (0) -#define vcclist_write_lock() do {} while (0) -#define vcclist_write_unlock() do {} while (0) - /* -------------------- CARD SRAM UTILITIES: */ /* The SRAM is mapped into normal PCI memory space - the only catch is @@ -851,36 +782,39 @@ if (lvcc->vbase == 0) /* We were never bound to a VCI */ return; /* 15.2.1 - wait for queue to drain */ - spin_lock_irqsave(&lanai->txlock, flags); - if (lvcc->tx.inprogress != NULL) { - lanai_free_skb(lvcc->tx.atmvcc, lvcc->tx.inprogress); - lvcc->tx.inprogress = NULL; - } while ((skb = skb_dequeue(&lvcc->tx.backlog)) != NULL) lanai_free_skb(lvcc->tx.atmvcc, skb); + read_lock_irqsave(&vcc_sklist_lock, flags); __clear_bit(lvcc->vci, lanai->backlog_vccs); - spin_unlock_irqrestore(&lanai->txlock, flags); - timeout = jiffies + ((lanai_buf_size(&lvcc->tx.buf) * HZ) >> 17); + read_unlock_irqrestore(&vcc_sklist_lock, flags); + /* + * We need to wait for the VCC to drain but don't wait forever. We + * give each 1K of buffer size 1/128th of a second to clear out. + * TODO: maybe disable CBR if we're about to timeout? + */ + timeout = jiffies + + (((lanai_buf_size(&lvcc->tx.buf) / 1024) * HZ) >> 7); write = TXWRITEPTR_GET_PTR(cardvcc_read(lvcc, vcc_txwriteptr)); - goto start; - while (time_before_eq(jiffies, timeout)) { - schedule_timeout(HZ / 25); - start: + for (;;) { read = TXREADPTR_GET_PTR(cardvcc_read(lvcc, vcc_txreadptr)); if (read == write && /* Is TX buffer empty? */ (lvcc->tx.atmvcc->qos.txtp.traffic_class != ATM_CBR || (cardvcc_read(lvcc, vcc_txcbr_next) & TXCBR_NEXT_BOZO) == 0)) - goto done; + break; if (read != lastread) { /* Has there been any progress? */ lastread = read; timeout += HZ / 10; } + if (unlikely(time_after(jiffies, timeout))) { + printk(KERN_ERR DEV_LABEL "(itf %d): Timed out on " + "backlog closing vci %d\n", + lvcc->tx.atmvcc->dev->number, lvcc->vci); + DPRINTK("read, write = %d, %d\n", read, write); + break; + } + schedule_timeout(HZ / 25); } - printk(KERN_ERR DEV_LABEL "(itf %d): Timed out on backlog closing " - "vci %d\n", lvcc->tx.atmvcc->dev->number, lvcc->vci); - DPRINTK("read, write = %d, %d\n", read, write); - done: /* 15.2.2 - clear out all tx registers */ cardvcc_write(lvcc, 0, vcc_txreadptr); cardvcc_write(lvcc, 0, vcc_txwriteptr); @@ -1226,8 +1160,7 @@ /* test if VCC is currently backlogged */ static inline int vcc_is_backlogged(/*const*/ struct lanai_vcc *lvcc) { - return lvcc->tx.inprogress != NULL || - !skb_queue_empty(&lvcc->tx.backlog); + return !skb_queue_empty(&lvcc->tx.backlog); } /* Bit fields in the segmentation buffer descriptor */ @@ -1264,11 +1197,11 @@ } /* Add 32-bit AAL5 trailer and leave room for its CRC */ -static inline void vcc_tx_add_aal5trailer(struct lanai_vcc *lvcc, +static inline void vcc_tx_add_aal5_trailer(struct lanai_vcc *lvcc, int len, int cpi, int uu) { APRINTK((((unsigned long) lvcc->tx.buf.ptr) & 15) == 8, - "vcc_tx_add_aal5_descriptor: bad ptr=%p\n", lvcc->tx.buf.ptr); + "vcc_tx_add_aal5_trailer: bad ptr=%p\n", lvcc->tx.buf.ptr); lvcc->tx.buf.ptr += 2; lvcc->tx.buf.ptr[-2] = cpu_to_be32((uu << 24) | (cpi << 16) | len); if (lvcc->tx.buf.ptr >= lvcc->tx.buf.end) @@ -1311,7 +1244,7 @@ } /* Update "butt" register to specify new WritePtr */ -static inline void lanai_endtx(const struct lanai_dev *lanai, +static inline void lanai_endtx(struct lanai_dev *lanai, const struct lanai_vcc *lvcc) { int i, ptr = ((unsigned char *) lvcc->tx.buf.ptr) - @@ -1320,6 +1253,14 @@ "lanai_endtx: bad ptr (%d), vci=%d, start,ptr,end=%p,%p,%p\n", ptr, lvcc->vci, lvcc->tx.buf.start, lvcc->tx.buf.ptr, lvcc->tx.buf.end); + + /* + * Since the "butt register" is a shared resounce on the card we + * serialize all accesses to it through this spinlock. This is + * mostly just paranoia sicne the register is rarely "busy" anyway + * but is needed for correctness. + */ + spin_lock(&lanai->endtxlock); /* * We need to check if the "butt busy" bit is set before * updating the butt register. In theory this should @@ -1334,131 +1275,86 @@ } udelay(5); } + /* + * Before we tall the card to start work we need to be sure 100% of + * the info in the service buffer has been written before we tell + * the card about it + */ + wmb(); reg_write(lanai, (ptr << 12) | lvcc->vci, Butt_Reg); + spin_unlock(&lanai->endtxlock); +} + +/* + * Add one AAL5 PDU to lvcc's transmit buffer. Caller garauntees there's + * space available. "pdusize" is the number of bytes the PDU will take + */ +static void lanai_send_one_aal5(struct lanai_dev *lanai, + struct lanai_vcc *lvcc, struct sk_buff *skb, int pdusize) +{ + int pad; + APRINTK(pdusize == aal5_size(skb->len), + "lanai_send_one_aal5: wrong size packet (%d != %d)\n", + pdusize, aal5_size(skb->len)); + vcc_tx_add_aal5_descriptor(lvcc, 0, pdusize); + pad = pdusize - skb->len - 8; + APRINTK(pad >= 0, "pad is negative (%d)\n", pad); + APRINTK(pad < 48, "pad is too big (%d)\n", pad); + vcc_tx_memcpy(lvcc, skb->data, skb->len); + vcc_tx_memzero(lvcc, pad); + vcc_tx_add_aal5_trailer(lvcc, skb->len, 0, 0); + lanai_endtx(lanai, lvcc); + lanai_free_skb(lvcc->tx.atmvcc, skb); + atomic_inc(&lvcc->tx.atmvcc->stats->tx); } /* Try to fill the buffer - don't call unless there is backlog */ static void vcc_tx_unqueue_aal5(struct lanai_dev *lanai, struct lanai_vcc *lvcc, int endptr) { - int pad, n; + int n; struct sk_buff *skb; int space = vcc_tx_space(lvcc, endptr); APRINTK(vcc_is_backlogged(lvcc), "vcc_tx_unqueue() called with empty backlog (vci=%d)\n", lvcc->vci); - if (space < 64) - return; /* No space for even 1 cell+descriptor */ - if (lvcc->tx.inprogress != NULL) { - APRINTK((lvcc->tx.inprogleft % 48) == 0, - "vcc_tx_unqueue_aal5: bad progleft=%d\n", - lvcc->tx.inprogleft); - if (lvcc->tx.inprogleft + 16 > space) { /* Can't send all? */ - n = aal5_spacefor(space - 16); /* Bytes to send */ - vcc_tx_add_aal5_descriptor(lvcc, - DESCRIPTOR_AAL5_STREAM, n); - pad = lvcc->tx.pptr + n - lvcc->tx.inprogress->tail; - if (pad < 0) - pad = 0; - vcc_tx_memcpy(lvcc, lvcc->tx.pptr, n - pad); - vcc_tx_memzero(lvcc, pad); - lvcc->tx.pptr += n; - lvcc->tx.inprogleft -= n; - goto end; /* Buffer is now full */ - } - /* OK, there's at least space for all of "inprogress" skb */ - vcc_tx_add_aal5_descriptor(lvcc, 0, - lvcc->tx.inprogleft); - pad = lvcc->tx.pptr + lvcc->tx.inprogleft - - lvcc->tx.inprogress->tail; - if (pad >= lvcc->tx.inprogleft) { /* Nothing but pad left */ - APRINTK(lvcc->tx.inprogleft == 48, - "vcc_tx_unqueue_aal5: bad pure-pad=%d\n", - lvcc->tx.inprogleft); - pad = 48; - } else - vcc_tx_memcpy(lvcc, lvcc->tx.pptr, - lvcc->tx.inprogleft - pad); - vcc_tx_memzero(lvcc, pad - 8); - vcc_tx_add_aal5trailer(lvcc, lvcc->tx.inprogress->len, 0, 0); - lanai_free_skb(lvcc->tx.atmvcc, lvcc->tx.inprogress); - lvcc->tx.inprogress = NULL; - space -= lvcc->tx.inprogleft + 16; - atomic_inc(&lvcc->tx.atmvcc->stats->tx); - } while (space >= 64) { - if ((skb = skb_dequeue(&lvcc->tx.backlog)) == NULL) - break; + skb = skb_dequeue(&lvcc->tx.backlog); + if (skb == NULL) + goto no_backlog; n = aal5_size(skb->len); - if (n + 16 > space) { /* Can only send part */ - int m = aal5_spacefor(space - 16); /* Bytes to send */ - vcc_tx_add_aal5_descriptor(lvcc, - DESCRIPTOR_AAL5_STREAM, m); - lvcc->tx.pptr = skb->data + m; - pad = lvcc->tx.pptr - skb->tail; - if (pad < 0) - pad = 0; - vcc_tx_memcpy(lvcc, skb->data, m - pad); - vcc_tx_memzero(lvcc, pad); - lvcc->tx.inprogleft = n - m; - lvcc->tx.inprogress = skb; - goto end; + if (n + 16 > space) { + /* No room for this packet - put it back on queue */ + skb_queue_head(&lvcc->tx.backlog, skb); + return; } - vcc_tx_add_aal5_descriptor(lvcc, 0, n); - pad = n - skb->len - 8; - vcc_tx_memcpy(lvcc, skb->data, skb->len); - vcc_tx_memzero(lvcc, pad); - lanai_free_skb(lvcc->tx.atmvcc, skb); - vcc_tx_add_aal5trailer(lvcc, skb->len, 0, 0); + lanai_send_one_aal5(lanai, lvcc, skb, n); space -= n + 16; - atomic_inc(&lvcc->tx.atmvcc->stats->tx); } - if (skb_queue_empty(&lvcc->tx.backlog)) + if (!vcc_is_backlogged(lvcc)) { + no_backlog: __clear_bit(lvcc->vci, lanai->backlog_vccs); - end: - lanai_endtx(lanai, lvcc); + } } /* Given an skb that we want to transmit either send it now or queue */ static void vcc_tx_aal5(struct lanai_dev *lanai, struct lanai_vcc *lvcc, struct sk_buff *skb) { - int space, n, pad; + int space, n; if (vcc_is_backlogged(lvcc)) /* Already backlogged */ goto queue_it; - space = vcc_tx_space(lvcc, TXREADPTR_GET_PTR(cardvcc_read(lvcc, - vcc_txreadptr))); - if (space < 64) { /* No space at all */ - __set_bit(lvcc->vci, lanai->backlog_vccs); - goto queue_it; - } - if (space >= 16 + (n = aal5_size(skb->len))) { - /* We can send the whole thing now */ - vcc_tx_add_aal5_descriptor(lvcc, 0, n); - pad = n - skb->len; - vcc_tx_memcpy(lvcc, skb->data, skb->len); - vcc_tx_memzero(lvcc, pad - 8); - vcc_tx_add_aal5trailer(lvcc, skb->len, 0, 0); - lanai_free_skb(lvcc->tx.atmvcc, skb); - atomic_inc(&lvcc->tx.atmvcc->stats->tx); - } else { /* Space for only part of skb */ - int bytes = aal5_spacefor(space - 16); /* Bytes to send */ - vcc_tx_add_aal5_descriptor(lvcc, - DESCRIPTOR_AAL5_STREAM, bytes); - pad = bytes - skb->len; - if (pad < 0) - pad = 0; - vcc_tx_memcpy(lvcc, skb->data, bytes - pad); - vcc_tx_memzero(lvcc, pad); - lvcc->tx.inprogress = skb; - lvcc->tx.inprogleft = n - bytes; - lvcc->tx.pptr = skb->data + bytes; + space = vcc_tx_space(lvcc, + TXREADPTR_GET_PTR(cardvcc_read(lvcc, vcc_txreadptr))); + n = aal5_size(skb->len); + APRINTK(n + 16 >= 64, "vcc_tx_aal5: n too small (%d)\n", n); + if (space < n + 16) { /* No space for this PDU */ __set_bit(lvcc->vci, lanai->backlog_vccs); + queue_it: + skb_queue_tail(&lvcc->tx.backlog, skb); + return; } - lanai_endtx(lanai, lvcc); - return; - queue_it: - skb_queue_tail(&lvcc->tx.backlog, skb); + lanai_send_one_aal5(lanai, lvcc, skb, n); } static void vcc_tx_unqueue_aal0(struct lanai_dev *lanai, @@ -1476,28 +1372,6 @@ lanai_free_skb(lvcc->tx.atmvcc, skb); } -/* Try to undequeue 1 backlogged vcc */ -static void iter_dequeue(struct lanai_dev *lanai, vci_t vci) -{ - struct lanai_vcc *lvcc = lanai->vccs[vci]; - int endptr; - if (lvcc == NULL || !vcc_is_backlogged(lvcc)) { - __clear_bit(vci, lanai->backlog_vccs); - return; - } - endptr = TXREADPTR_GET_PTR(cardvcc_read(lvcc, vcc_txreadptr)); - lvcc->tx.unqueue(lanai, lvcc, endptr); -} - -/* Try a dequeue on all backlogged connections */ -static inline void vcc_tx_dequeue_all(struct lanai_dev *lanai) -{ - unsigned long flags; - spin_lock_irqsave(&lanai->txlock, flags); - vci_bitfield_iterate(lanai, lanai->backlog_vccs, iter_dequeue); - spin_unlock_irqrestore(&lanai->txlock, flags); -} - /* -------------------- VCC RX BUFFER UTILITIES: */ /* unlike the _tx_ cousins, this doesn't update ptr */ @@ -1510,6 +1384,8 @@ m = 0; memcpy(dest, lvcc->rx.buf.ptr, n - m); memcpy(dest + n - m, lvcc->rx.buf.start, m); + /* Make sure that these copies don't get reordered */ + barrier(); } /* Receive AAL5 data on a VCC with a particular endptr */ @@ -1527,6 +1403,11 @@ /* Recover the second-to-last word to get true pdu length */ if ((x = &end[-2]) < lvcc->rx.buf.start) x = &lvcc->rx.buf.end[-2]; + /* + * Before we actually read from the buffer, make sure the memory + * changes have arrived + */ + rmb(); size = be32_to_cpup(x) & 0xffff; if (unlikely(n != aal5_size(size))) { /* Make sure size matches padding */ @@ -1542,9 +1423,9 @@ goto out; } skb_put(skb, size); + vcc_rx_memcpy(skb->data, lvcc, size); ATM_SKB(skb)->vcc = lvcc->rx.atmvcc; do_gettimeofday(&skb->stamp); - vcc_rx_memcpy(skb->data, lvcc, size); lvcc->rx.atmvcc->push(lvcc->rx.atmvcc, skb); atomic_inc(&lvcc->rx.atmvcc->stats->rx); out: @@ -1555,7 +1436,7 @@ static void vcc_rx_aal0(struct lanai_dev *lanai) { printk(KERN_INFO DEV_LABEL ": vcc_rx_aal0: not implemented\n"); - /* Remember to get vcclist_read_lock while looking up VC */ + /* Remember to get read_lock(&vcc_sklist_lock) while looking up VC */ /* Remember to increment lvcc->rx.atmvcc->stats->rx */ } @@ -1606,7 +1487,6 @@ memset(&lvcc->stats, 0, sizeof lvcc->stats); lvcc->rx.buf.start = lvcc->tx.buf.start = NULL; skb_queue_head_init(&lvcc->tx.backlog); - lvcc->tx.inprogress = NULL; #ifdef DEBUG lvcc->tx.unqueue = NULL; lvcc->vci = -1; @@ -1617,14 +1497,14 @@ static int lanai_get_sized_buffer(struct lanai_dev *lanai, struct lanai_buffer *buf, int max_sdu, int multiplier, - int min, const char *name) + const char *name) { int size; if (unlikely(max_sdu < 1)) max_sdu = 1; max_sdu = aal5_size(max_sdu); size = (max_sdu + 16) * multiplier + 16; - lanai_buf_allocate(buf, size, min, lanai->pci); + lanai_buf_allocate(buf, size, max_sdu + 32, lanai->pci); if (unlikely(buf->start == NULL)) return -ENOMEM; if (unlikely(lanai_buf_size(buf) < size)) @@ -1640,8 +1520,7 @@ struct lanai_vcc *lvcc, const struct atm_qos *qos) { return lanai_get_sized_buffer(lanai, &lvcc->rx.buf, - qos->rxtp.max_sdu, AAL5_RX_MULTIPLIER, qos->rxtp.max_sdu + 32, - "RX"); + qos->rxtp.max_sdu, AAL5_RX_MULTIPLIER, "RX"); } /* Setup a TX buffer for a currently unbound AAL5 vci */ @@ -1659,7 +1538,7 @@ multiplier = AAL5_TX_MULTIPLIER; } return lanai_get_sized_buffer(lanai, &lvcc->tx.buf, max_sdu, - multiplier, 80, "TX"); + multiplier, "TX"); } static inline void host_vcc_bind(struct lanai_dev *lanai, @@ -1759,21 +1638,21 @@ { vci_t vci = SERVICE_GET_VCI(s); struct lanai_vcc *lvcc; - vcclist_read_lock(); + read_lock(&vcc_sklist_lock); lvcc = lanai->vccs[vci]; if (unlikely(lvcc == NULL)) { - vcclist_read_unlock(); + read_unlock(&vcc_sklist_lock); DPRINTK("(itf %d) got service entry 0x%X for nonexistent " "vcc %d\n", lanai->number, (unsigned int) s, vci); if (s & SERVICE_TX) - lanai->stats.service_novcc_tx++; + lanai->stats.service_notx++; else - lanai->stats.service_novcc_rx++; + lanai->stats.service_norx++; return 0; } if (s & SERVICE_TX) { /* segmentation interrupt */ if (unlikely(lvcc->tx.atmvcc == NULL)) { - vcclist_read_unlock(); + read_unlock(&vcc_sklist_lock); DPRINTK("(itf %d) got service entry 0x%X for non-TX " "vcc %d\n", lanai->number, (unsigned int) s, vci); lanai->stats.service_notx++; @@ -1781,18 +1660,18 @@ } __set_bit(vci, lanai->transmit_ready); lvcc->tx.endptr = SERVICE_GET_END(s); - vcclist_read_unlock(); + read_unlock(&vcc_sklist_lock); return 1; } if (unlikely(lvcc->rx.atmvcc == NULL)) { - vcclist_read_unlock(); + read_unlock(&vcc_sklist_lock); DPRINTK("(itf %d) got service entry 0x%X for non-RX " "vcc %d\n", lanai->number, (unsigned int) s, vci); lanai->stats.service_norx++; return 0; } if (unlikely(lvcc->rx.atmvcc->qos.aal != ATM_AAL5)) { - vcclist_read_unlock(); + read_unlock(&vcc_sklist_lock); DPRINTK("(itf %d) got RX service entry 0x%X for non-AAL5 " "vcc %d\n", lanai->number, (unsigned int) s, vci); lanai->stats.service_rxnotaal5++; @@ -1801,12 +1680,12 @@ } if (likely(!(s & (SERVICE_TRASH | SERVICE_STREAM | SERVICE_CRCERR)))) { vcc_rx_aal5(lvcc, SERVICE_GET_END(s)); - vcclist_read_unlock(); + read_unlock(&vcc_sklist_lock); return 0; } if (s & SERVICE_TRASH) { int bytes; - vcclist_read_unlock(); + read_unlock(&vcc_sklist_lock); DPRINTK("got trashed rx pdu on vci %d\n", vci); atomic_inc(&lvcc->rx.atmvcc->stats->rx_err); lvcc->stats.x.aal5.service_trash++; @@ -1819,7 +1698,7 @@ return 0; } if (s & SERVICE_STREAM) { - vcclist_read_unlock(); + read_unlock(&vcc_sklist_lock); atomic_inc(&lvcc->rx.atmvcc->stats->rx_err); lvcc->stats.x.aal5.service_stream++; printk(KERN_ERR DEV_LABEL "(itf %d): Got AAL5 stream " @@ -1832,7 +1711,7 @@ lvcc->stats.x.aal5.service_rxcrc++; lvcc->rx.buf.ptr = &lvcc->rx.buf.start[SERVICE_GET_END(s) * 4]; cardvcc_write(lvcc, SERVICE_GET_END(s), vcc_rxreadptr); - vcclist_read_unlock(); + read_unlock(&vcc_sklist_lock); return 0; } @@ -1840,9 +1719,8 @@ static void iter_transmit(struct lanai_dev *lanai, vci_t vci) { struct lanai_vcc *lvcc = lanai->vccs[vci]; - if (!vcc_is_backlogged(lvcc)) - return; - lvcc->tx.unqueue(lanai, lvcc, lvcc->tx.endptr); + if (vcc_is_backlogged(lvcc)) + lvcc->tx.unqueue(lanai, lvcc, lvcc->tx.endptr); } /* Run service queue -- called from interrupt context or with @@ -1862,13 +1740,11 @@ } reg_write(lanai, wreg, ServRead_Reg); if (ntx != 0) { - spin_lock(&lanai->txlock); - vcclist_read_lock(); + read_lock(&vcc_sklist_lock); vci_bitfield_iterate(lanai, lanai->transmit_ready, iter_transmit); CLEAR_BITMAP(&lanai->transmit_ready, NUM_VCI); - vcclist_read_unlock(); - spin_unlock(&lanai->txlock); + read_unlock(&vcc_sklist_lock); } } @@ -1885,22 +1761,47 @@ /* -------------------- POLLING TIMER: */ +#ifndef DEBUG_RW +/* Try to undequeue 1 backlogged vcc */ +static void iter_dequeue(struct lanai_dev *lanai, vci_t vci) +{ + struct lanai_vcc *lvcc = lanai->vccs[vci]; + int endptr; + if (lvcc == NULL || lvcc->tx.atmvcc == NULL || + !vcc_is_backlogged(lvcc)) { + __clear_bit(vci, lanai->backlog_vccs); + return; + } + endptr = TXREADPTR_GET_PTR(cardvcc_read(lvcc, vcc_txreadptr)); + lvcc->tx.unqueue(lanai, lvcc, endptr); +} +#endif /* !DEBUG_RW */ + static void lanai_timed_poll(unsigned long arg) { -#ifndef DEBUG_RW struct lanai_dev *lanai = (struct lanai_dev *) arg; +#ifndef DEBUG_RW unsigned long flags; #ifdef USE_POWERDOWN if (lanai->conf1 & CONFIG1_POWERDOWN) return; -#endif - spin_lock_irqsave(&lanai->servicelock, flags); - run_service(lanai); - spin_unlock_irqrestore(&lanai->servicelock, flags); - vcc_tx_dequeue_all(lanai); +#endif /* USE_POWERDOWN */ + local_irq_save(flags); + /* If we can grab the spinlock, check if any services need to be run */ + if (spin_trylock(&lanai->servicelock)) { + run_service(lanai); + spin_unlock(&lanai->servicelock); + } + /* ...and see if any backlogged VCs can make progress */ + /* unfortunately linux has no read_trylock() currently */ + read_lock(&vcc_sklist_lock); + vci_bitfield_iterate(lanai, lanai->backlog_vccs, iter_dequeue); + read_unlock(&vcc_sklist_lock); + local_irq_restore(flags); + get_statistics(lanai); +#endif /* !DEBUG_RW */ mod_timer(&lanai->timer, jiffies + LANAI_POLL_PERIOD); -#endif /* DEBUG_RW */ } static inline void lanai_timed_poll_start(struct lanai_dev *lanai) @@ -1914,7 +1815,7 @@ static inline void lanai_timed_poll_stop(struct lanai_dev *lanai) { - del_timer(&lanai->timer); + del_timer_sync(&lanai->timer); } /* -------------------- INTERRUPT SERVICE: */ @@ -2265,13 +2166,13 @@ #endif lanai->cbrvcc = NULL; memset(&lanai->stats, 0, sizeof lanai->stats); - spin_lock_init(&lanai->txlock); + spin_lock_init(&lanai->endtxlock); spin_lock_init(&lanai->servicelock); atmdev->ci_range.vpi_bits = 0; atmdev->ci_range.vci_bits = 0; while (1 << atmdev->ci_range.vci_bits < lanai->num_vci) atmdev->ci_range.vci_bits++; - atmdev->link_rate = ((25600000 / 8 - 8000) / 54); + atmdev->link_rate = ATM_25_PCR; /* 3.2: PCI initialization */ if ((result = lanai_pci_start(lanai)) != 0) @@ -2342,6 +2243,7 @@ goto error_vcctable; } MOD_INC_USE_COUNT; /* At this point we can't fail */ + mb(); /* Make sure that all that made it */ intr_enable(lanai, INT_ALL & ~(INT_PING | INT_WAKE)); /* 3.11: initialize loop mode (i.e. turn looping off) */ lanai->conf1 = (lanai->conf1 & ~CONFIG1_MASK_LOOPMODE) | @@ -2466,16 +2368,11 @@ atmvcc->vpi = vpi; atmvcc->vci = vci; set_bit(ATM_VF_ADDR, &atmvcc->flags); - lvcc = lanai->vccs[vci]; if (atmvcc->qos.aal != ATM_AAL0 && atmvcc->qos.aal != ATM_AAL5) return -EINVAL; -#if 0 - DPRINTK(DEV_LABEL "(itf %d): open %d.%d flags=0x%lX\n", - lanai->number, (int) vpi, vci, (unsigned long) atmvcc->flags); -#else DPRINTK(DEV_LABEL "(itf %d): open %d.%d\n", lanai->number, (int) vpi, vci); -#endif + lvcc = lanai->vccs[vci]; if (lvcc == NULL) { lvcc = new_lanai_vcc(); if (unlikely(lvcc == NULL)) @@ -2517,6 +2414,11 @@ } } host_vcc_bind(lanai, lvcc, vci); + /* + * Make sure everything made it to RAM before we tell the card about + * the VCC + */ + wmb(); if (atmvcc == lvcc->rx.atmvcc) host_vcc_start_rx(lvcc); if (atmvcc == lvcc->tx.atmvcc) { @@ -2549,9 +2451,6 @@ run_service(lanai); spin_unlock_irqrestore(&lanai->servicelock, flags); return 0; } - case 2200001: - vcc_tx_dequeue_all(lanai); - return 0; case 2200002: get_statistics(lanai); return 0; @@ -2644,18 +2543,18 @@ ATM_SKB(skb)->vcc = atmvcc; switch (atmvcc->qos.aal) { case ATM_AAL5: - spin_lock_irqsave(&lanai->txlock, flags); + read_lock_irqsave(&vcc_sklist_lock, flags); vcc_tx_aal5(lanai, lvcc, skb); - spin_unlock_irqrestore(&lanai->txlock, flags); + read_unlock_irqrestore(&vcc_sklist_lock, flags); return 0; case ATM_AAL0: if (unlikely(skb->len != ATM_CELL_SIZE-1)) goto einval; /* NOTE - this next line is technically invalid - we haven't unshared skb */ cpu_to_be32s((u32 *) skb->data); - spin_lock_irqsave(&lanai->txlock, flags); + read_lock_irqsave(&vcc_sklist_lock, flags); vcc_tx_aal0(lanai, lvcc, skb); - spin_unlock_irqrestore(&lanai->txlock, flags); + read_unlock_irqrestore(&vcc_sklist_lock, flags); return 0; } DPRINTK("lanai_send: bad aal=%d on vci=%d\n", (int) atmvcc->qos.aal, @@ -2725,10 +2624,6 @@ "master_parity=%u\n", lanai->stats.pcierr_s_target_abort, lanai->stats.pcierr_master_parity); if (left-- == 0) - return sprintf(page, "service list errors: no_vcc_rx=%u, " - "no_vcc_tx=%u,\n", lanai->stats.service_novcc_rx, - lanai->stats.service_novcc_tx); - if (left-- == 0) return sprintf(page, " no_tx=%u, " "no_rx=%u, bad_rx_aal=%u\n", lanai->stats.service_norx, lanai->stats.service_notx, @@ -2737,7 +2632,7 @@ return sprintf(page, "resets: dma=%u, card=%u\n", lanai->stats.dma_reenable, lanai->stats.card_reset); /* At this point, "left" should be the VCI we're looking for */ - vcclist_read_lock(); + read_lock(&vcc_sklist_lock); for (; ; left++) { if (left >= NUM_VCI) { left = 0; @@ -2773,7 +2668,7 @@ page[left++] = '\n'; page[left] = '\0'; out: - vcclist_read_unlock(); + read_unlock(&vcc_sklist_lock); return left; } #endif /* CONFIG_PROC_FS */ diff -Nru a/drivers/block/DAC960.c b/drivers/block/DAC960.c --- a/drivers/block/DAC960.c Thu Sep 4 15:38:41 2003 +++ b/drivers/block/DAC960.c Thu Sep 4 15:38:41 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 Thu Sep 4 15:38:41 2003 +++ b/drivers/block/DAC960.h Thu Sep 4 15:38:41 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 Thu Sep 4 15:38:28 2003 +++ b/drivers/block/acsi_slm.c Thu Sep 4 15:38:28 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 Thu Sep 4 15:38:33 2003 +++ b/drivers/block/amiflop.c Thu Sep 4 15:38:33 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); @@ -1740,7 +1731,7 @@ int __init amiga_floppy_init(void) { - int i; + int i, ret; if (!AMIGAHW_PRESENT(AMI_FLOPPY)) return -ENXIO; @@ -1752,41 +1743,39 @@ * We request DSKPTR, DSKLEN and DSKDATA only, because the other * floppy registers are too spreaded over the custom register space */ + ret = -EBUSY; if (!request_mem_region(CUSTOM_PHYSADDR+0x20, 8, "amiflop [Paula]")) { printk("fd: cannot get floppy registers\n"); - unregister_blkdev(FLOPPY_MAJOR,"fd"); - return -EBUSY; + goto out_blkdev; } + + ret = -ENOMEM; if ((raw_buf = (char *)amiga_chip_alloc (RAW_BUF_SIZE, "Floppy")) == NULL) { printk("fd: cannot get chip mem buffer\n"); - release_mem_region(CUSTOM_PHYSADDR+0x20, 8); - unregister_blkdev(FLOPPY_MAJOR,"fd"); - return -ENOMEM; + goto out_memregion; } + + ret = -EBUSY; if (request_irq(IRQ_AMIGA_DSKBLK, fd_block_done, 0, "floppy_dma", NULL)) { printk("fd: cannot get irq for dma\n"); - amiga_chip_free(raw_buf); - release_mem_region(CUSTOM_PHYSADDR+0x20, 8); - unregister_blkdev(FLOPPY_MAJOR,"fd"); - return -EBUSY; + goto out_irq; } + if (request_irq(IRQ_AMIGA_CIAA_TB, ms_isr, 0, "floppy_timer", NULL)) { printk("fd: cannot get irq for timer\n"); - free_irq(IRQ_AMIGA_DSKBLK, NULL); - amiga_chip_free(raw_buf); - release_mem_region(CUSTOM_PHYSADDR+0x20, 8); - unregister_blkdev(FLOPPY_MAJOR,"fd"); - return -EBUSY; - } - if (fd_probe_drives() < 1) { /* No usable drives */ - free_irq(IRQ_AMIGA_CIAA_TB, NULL); - free_irq(IRQ_AMIGA_DSKBLK, NULL); - amiga_chip_free(raw_buf); - release_mem_region(CUSTOM_PHYSADDR+0x20, 8); - unregister_blkdev(FLOPPY_MAJOR,"fd"); - return -ENXIO; + goto out_irq2; } + + ret = -ENOMEM; + floppy_queue = blk_init_queue(do_fd_request, &amiflop_lock); + if (!floppy_queue) + goto out_queue; + + ret = -ENXIO; + if (fd_probe_drives() < 1) /* No usable drives */ + goto out_probe; + blk_register_region(MKDEV(FLOPPY_MAJOR, 0), 256, THIS_MODULE, floppy_find, NULL, NULL); @@ -1813,17 +1802,6 @@ post_write_timer.data = 0; post_write_timer.function = post_write; - floppy_queue = blk_init_queue(do_fd_request, &amiflop_lock); - if (!floppy_queue) { - free_irq(IRQ_AMIGA_CIAA_TB, NULL); - free_irq(IRQ_AMIGA_DSKBLK, NULL); - amiga_chip_free(raw_buf); - release_mem_region(CUSTOM_PHYSADDR+0x20, 8); - unregister_blkdev(FLOPPY_MAJOR,"fd"); - blk_unregister_region(MKDEV(FLOPPY_MAJOR, 0), 256); - return -ENOMEM; - } - for (i = 0; i < 128; i++) mfmdecode[i]=255; for (i = 0; i < 16; i++) @@ -1835,6 +1813,20 @@ /* init ms timer */ ciaa.crb = 8; /* one-shot, stop */ return 0; + +out_probe: + blk_cleanup_queue(floppy_queue); +out_queue: + free_irq(IRQ_AMIGA_CIAA_TB, NULL); +out_irq2: + free_irq(IRQ_AMIGA_DSKBLK, NULL); +out_irq: + amiga_chip_free(raw_buf); +out_memregion: + release_mem_region(CUSTOM_PHYSADDR+0x20, 8); +out_blkdev: + unregister_blkdev(FLOPPY_MAJOR,"fd"); + return ret; } #ifdef MODULE diff -Nru a/drivers/block/as-iosched.c b/drivers/block/as-iosched.c --- a/drivers/block/as-iosched.c Thu Sep 4 15:38:28 2003 +++ b/drivers/block/as-iosched.c Thu Sep 4 15:38:28 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; @@ -902,12 +910,7 @@ struct as_rq *arq = RQ_DATA(rq); struct as_io_context *aic; - if (unlikely(!blk_fs_request(rq))) - return; - - WARN_ON(blk_fs_request(rq) && arq->state == AS_RQ_NEW); - - if (arq->state != AS_RQ_DISPATCHED) + if (unlikely(arq->state != AS_RQ_DISPATCHED)) return; if (ad->changed_batch && ad->nr_dispatched == 1) { @@ -1027,7 +1030,7 @@ { struct as_rq *arq = RQ_DATA(rq); - if (unlikely(!blk_fs_request(rq))) + if (unlikely(arq->state == AS_RQ_NEW)) return; if (!arq) { @@ -1333,9 +1336,9 @@ atomic_inc(&arq->io_context->aic->nr_dispatched); } else WARN_ON(blk_fs_request(rq) - && (!(rq->flags & REQ_HARDBARRIER)) ); + && (!(rq->flags & (REQ_HARDBARRIER|REQ_SOFTBARRIER))) ); - list_add_tail(&rq->queuelist, ad->dispatch); + list_add(&rq->queuelist, ad->dispatch); /* Stop anticipating - let this request get through */ as_antic_stop(ad); @@ -1350,26 +1353,31 @@ struct as_data *ad = q->elevator.elevator_data; struct as_rq *arq = RQ_DATA(rq); - if (unlikely(rq->flags & REQ_HARDBARRIER)) { + if (unlikely(rq->flags & (REQ_HARDBARRIER|REQ_SOFTBARRIER))) { q->last_merge = NULL; - while (ad->next_arq[REQ_SYNC]) - as_move_to_dispatch(ad, ad->next_arq[REQ_SYNC]); + if (insert_here != ad->dispatch) { + while (ad->next_arq[REQ_SYNC]) + as_move_to_dispatch(ad, ad->next_arq[REQ_SYNC]); + + while (ad->next_arq[REQ_ASYNC]) + as_move_to_dispatch(ad, ad->next_arq[REQ_ASYNC]); + } - while (ad->next_arq[REQ_ASYNC]) - as_move_to_dispatch(ad, ad->next_arq[REQ_ASYNC]); + if (!insert_here) + insert_here = ad->dispatch->prev; } if (unlikely(!blk_fs_request(rq))) { if (!insert_here) - insert_here = ad->dispatch->prev; + insert_here = ad->dispatch; + } + if (insert_here) { list_add(&rq->queuelist, insert_here); /* Stop anticipating - let this request get through */ - if (!list_empty(ad->dispatch) - && (ad->antic_status == ANTIC_WAIT_REQ - || ad->antic_status == ANTIC_WAIT_NEXT)) + if (list_empty(ad->dispatch)) as_antic_stop(ad); return; diff -Nru a/drivers/block/ataflop.c b/drivers/block/ataflop.c --- a/drivers/block/ataflop.c Thu Sep 4 15:38:30 2003 +++ b/drivers/block/ataflop.c Thu Sep 4 15:38:30 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 Thu Sep 4 15:38:46 2003 +++ b/drivers/block/cciss.c Thu Sep 4 15:38:46 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); @@ -2447,11 +2447,8 @@ if( i < 0 ) return (-1); if (cciss_pci_init(hba[i], pdev) != 0) - { - release_io_mem(hba[i]); - free_hba(i); - return (-1); - } + goto clean1; + sprintf(hba[i]->devname, "cciss%d", i); hba[i]->ctlr = i; hba[i]->pdev = pdev; @@ -2463,28 +2460,23 @@ printk("cciss: not using DAC cycles\n"); else { printk("cciss: no suitable DMA available\n"); - free_hba(i); - return -ENODEV; + goto clean1; } if (register_blkdev(COMPAQ_CISS_MAJOR+i, hba[i]->devname)) { - release_io_mem(hba[i]); - free_hba(i); - return -1; + printk(KERN_ERR "cciss: Unable to register device %s\n", + hba[i]->devname); + goto clean1; } /* make sure the board interrupts are off */ hba[i]->access.set_intr_mask(hba[i], CCISS_INTR_OFF); if( request_irq(hba[i]->intr, do_cciss_intr, SA_INTERRUPT | SA_SHIRQ | SA_SAMPLE_RANDOM, - hba[i]->devname, hba[i])) - { - printk(KERN_ERR "ciss: Unable to get irq %d for %s\n", + hba[i]->devname, hba[i])) { + printk(KERN_ERR "cciss: Unable to get irq %d for %s\n", hba[i]->intr, hba[i]->devname); - unregister_blkdev( COMPAQ_CISS_MAJOR+i, hba[i]->devname); - release_io_mem(hba[i]); - free_hba(i); - return(-1); + goto clean2; } hba[i]->cmd_pool_bits = kmalloc(((NR_CMDS+BITS_PER_LONG-1)/BITS_PER_LONG)*sizeof(unsigned long), GFP_KERNEL); hba[i]->cmd_pool = (CommandList_struct *)pci_alloc_consistent( @@ -2495,35 +2487,18 @@ &(hba[i]->errinfo_pool_dhandle)); if((hba[i]->cmd_pool_bits == NULL) || (hba[i]->cmd_pool == NULL) - || (hba[i]->errinfo_pool == NULL)) - { -err_all: - if(hba[i]->cmd_pool_bits) - kfree(hba[i]->cmd_pool_bits); - if(hba[i]->cmd_pool) - pci_free_consistent(hba[i]->pdev, - NR_CMDS * sizeof(CommandList_struct), - hba[i]->cmd_pool, hba[i]->cmd_pool_dhandle); - if(hba[i]->errinfo_pool) - pci_free_consistent(hba[i]->pdev, - NR_CMDS * sizeof( ErrorInfo_struct), - hba[i]->errinfo_pool, - hba[i]->errinfo_pool_dhandle); - free_irq(hba[i]->intr, hba[i]); - unregister_blkdev(COMPAQ_CISS_MAJOR+i, hba[i]->devname); - release_io_mem(hba[i]); - free_hba(i); + || (hba[i]->errinfo_pool == NULL)) { printk( KERN_ERR "cciss: out of memory"); - return(-1); + goto clean4; } - /* - * someone needs to clean up this failure handling mess - */ spin_lock_init(&hba[i]->lock); q = blk_init_queue(do_cciss_request, &hba[i]->lock); if (!q) - goto err_all; + goto clean4; + + hba[i]->queue = q; + q->queuedata = hba[i]; /* Initialize the pdev driver private data. have it point to hba[i]. */ @@ -2545,7 +2520,6 @@ cciss_procinit(i); - q->queuedata = hba[i]; blk_queue_bounce_limit(q, hba[i]->pdev->dma_mask); /* This is a hardware imposed limit. */ @@ -2574,6 +2548,26 @@ add_disk(disk); } return(1); + +clean4: + if(hba[i]->cmd_pool_bits) + kfree(hba[i]->cmd_pool_bits); + if(hba[i]->cmd_pool) + pci_free_consistent(hba[i]->pdev, + NR_CMDS * sizeof(CommandList_struct), + hba[i]->cmd_pool, hba[i]->cmd_pool_dhandle); + if(hba[i]->errinfo_pool) + pci_free_consistent(hba[i]->pdev, + NR_CMDS * sizeof( ErrorInfo_struct), + hba[i]->errinfo_pool, + hba[i]->errinfo_pool_dhandle); + free_irq(hba[i]->intr, hba[i]); +clean2: + unregister_blkdev(COMPAQ_CISS_MAJOR+i, hba[i]->devname); +clean1: + release_io_mem(hba[i]); + free_hba(i); + return(-1); } static void __devexit cciss_remove_one (struct pci_dev *pdev) diff -Nru a/drivers/block/cpqarray.c b/drivers/block/cpqarray.c --- a/drivers/block/cpqarray.c Thu Sep 4 15:38:30 2003 +++ b/drivers/block/cpqarray.c Thu Sep 4 15:38:30 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/deadline-iosched.c b/drivers/block/deadline-iosched.c --- a/drivers/block/deadline-iosched.c Thu Sep 4 15:38:42 2003 +++ b/drivers/block/deadline-iosched.c Thu Sep 4 15:38:42 2003 @@ -627,21 +627,25 @@ struct deadline_data *dd = q->elevator.elevator_data; struct deadline_rq *drq = RQ_DATA(rq); - if (unlikely(rq->flags & REQ_HARDBARRIER)) { + if (unlikely(rq->flags & (REQ_HARDBARRIER|REQ_SOFTBARRIER))) { DL_INVALIDATE_HASH(dd); q->last_merge = NULL; - while (deadline_dispatch_requests(dd)) - ; + if (insert_here != dd->dispatch) { + while (deadline_dispatch_requests(dd)) + ; + } - list_add_tail(&rq->queuelist, dd->dispatch); - return; + if (!insert_here) + insert_here = dd->dispatch->prev; } if (unlikely(!blk_fs_request(rq))) { if (!insert_here) - insert_here = dd->dispatch->prev; + insert_here = dd->dispatch; + } + if (insert_here) { list_add(&rq->queuelist, insert_here); return; } diff -Nru a/drivers/block/elevator.c b/drivers/block/elevator.c --- a/drivers/block/elevator.c Thu Sep 4 15:38:42 2003 +++ b/drivers/block/elevator.c Thu Sep 4 15:38:42 2003 @@ -162,10 +162,10 @@ void __elv_add_request(request_queue_t *q, struct request *rq, int at_end, int plug) { - struct list_head *insert = &q->queue_head; + struct list_head *insert = NULL; - if (at_end) - insert = insert->prev; + if (!at_end) + insert = &q->queue_head; if (plug) blk_plug_device(q); diff -Nru a/drivers/block/floppy.c b/drivers/block/floppy.c --- a/drivers/block/floppy.c Thu Sep 4 15:38:30 2003 +++ b/drivers/block/floppy.c Thu Sep 4 15:38:30 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); @@ -4633,3 +4607,5 @@ __setup ("floppy=", floppy_setup); module_init(floppy_init) #endif + +MODULE_ALIAS_BLOCKDEV_MAJOR(FLOPPY_MAJOR); diff -Nru a/drivers/block/floppy98.c b/drivers/block/floppy98.c --- a/drivers/block/floppy98.c Thu Sep 4 15:38:32 2003 +++ b/drivers/block/floppy98.c Thu Sep 4 15:38:32 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 Thu Sep 4 15:38:33 2003 +++ b/drivers/block/genhd.c Thu Sep 4 15:38:33 2003 @@ -372,7 +372,7 @@ disk_stat_read(disk, write_merges), (unsigned long long)disk_stat_read(disk, write_sectors), jiffies_to_msec(disk_stat_read(disk, write_ticks)), - disk_stat_read(disk, in_flight), + disk->in_flight, jiffies_to_msec(disk_stat_read(disk, io_ticks)), jiffies_to_msec(disk_stat_read(disk, time_in_queue))); } @@ -492,7 +492,7 @@ disk_stat_read(gp, writes), disk_stat_read(gp, write_merges), (unsigned long long)disk_stat_read(gp, write_sectors), jiffies_to_msec(disk_stat_read(gp, write_ticks)), - disk_stat_read(gp, in_flight), + gp->in_flight, jiffies_to_msec(disk_stat_read(gp, io_ticks)), jiffies_to_msec(disk_stat_read(gp, time_in_queue))); @@ -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 Thu Sep 4 15:38:29 2003 +++ b/drivers/block/ioctl.c Thu Sep 4 15:38:29 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 Thu Sep 4 15:38:29 2003 +++ b/drivers/block/ll_rw_blk.c Thu Sep 4 15:38:29 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)) @@ -1652,7 +1660,7 @@ } if (new_io) { disk_round_stats(rq->rq_disk); - disk_stat_inc(rq->rq_disk, in_flight); + rq->rq_disk->in_flight++; } } @@ -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 @@ -1693,10 +1704,10 @@ unsigned long now = jiffies; disk_stat_add(disk, time_in_queue, - disk_stat_read(disk, in_flight) * (now - disk->stamp)); + disk->in_flight * (now - disk->stamp)); disk->stamp = now; - if (disk_stat_read(disk, in_flight)) + if (disk->in_flight) disk_stat_add(disk, io_ticks, (now - disk->stamp_idle)); disk->stamp_idle = now; } @@ -1808,7 +1819,7 @@ if (req->rq_disk) { disk_round_stats(req->rq_disk); - disk_stat_dec(req->rq_disk, in_flight); + req->rq_disk->in_flight--; } __blk_put_request(q, next); @@ -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; } /** @@ -2470,7 +2480,7 @@ break; } disk_round_stats(disk); - disk_stat_dec(disk, in_flight); + disk->in_flight--; } __blk_put_request(req->q, req); /* Do this LAST! The structure may be freed immediately afterwards */ diff -Nru a/drivers/block/paride/pg.c b/drivers/block/paride/pg.c --- a/drivers/block/paride/pg.c Thu Sep 4 15:38:43 2003 +++ b/drivers/block/paride/pg.c Thu Sep 4 15:38:43 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 Thu Sep 4 15:38:31 2003 +++ b/drivers/block/paride/pt.c Thu Sep 4 15:38:31 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 Thu Sep 4 15:38:37 2003 +++ b/drivers/block/rd.c Thu Sep 4 15:38:37 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 Thu Sep 4 15:38:47 2003 +++ b/drivers/block/scsi_ioctl.c Thu Sep 4 15:38:47 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/xd.c b/drivers/block/xd.c --- a/drivers/block/xd.c Thu Sep 4 15:38:42 2003 +++ b/drivers/block/xd.c Thu Sep 4 15:38:42 2003 @@ -1103,5 +1103,5 @@ #endif /* MODULE */ -module_init(xd_init) - +module_init(xd_init); +MODULE_ALIAS_BLOCKDEV_MAJOR(XT_DISK_MAJOR); diff -Nru a/drivers/block/z2ram.c b/drivers/block/z2ram.c --- a/drivers/block/z2ram.c Thu Sep 4 15:38:38 2003 +++ b/drivers/block/z2ram.c Thu Sep 4 15:38:38 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/bluetooth/hci_ldisc.c b/drivers/bluetooth/hci_ldisc.c --- a/drivers/bluetooth/hci_ldisc.c Thu Sep 4 15:38:41 2003 +++ b/drivers/bluetooth/hci_ldisc.c Thu Sep 4 15:38:41 2003 @@ -574,3 +574,4 @@ MODULE_AUTHOR("Maxim Krasnyansky "); MODULE_DESCRIPTION("Bluetooth HCI UART driver ver " VERSION); MODULE_LICENSE("GPL"); +MODULE_ALIAS_LDISC(N_HCI); diff -Nru a/drivers/cdrom/Kconfig b/drivers/cdrom/Kconfig --- a/drivers/cdrom/Kconfig Thu Sep 4 15:38:43 2003 +++ b/drivers/cdrom/Kconfig Thu Sep 4 15:38:43 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/cdrom/aztcd.c b/drivers/cdrom/aztcd.c --- a/drivers/cdrom/aztcd.c Thu Sep 4 15:38:45 2003 +++ b/drivers/cdrom/aztcd.c Thu Sep 4 15:38:45 2003 @@ -2499,3 +2499,4 @@ } MODULE_LICENSE("GPL"); +MODULE_ALIAS_BLOCKDEV_MAJOR(AZTECH_CDROM_MAJOR); diff -Nru a/drivers/cdrom/cdu31a.c b/drivers/cdrom/cdu31a.c --- a/drivers/cdrom/cdu31a.c Thu Sep 4 15:38:39 2003 +++ b/drivers/cdrom/cdu31a.c Thu Sep 4 15:38:39 2003 @@ -3500,3 +3500,4 @@ module_exit(cdu31a_exit); MODULE_LICENSE("GPL"); +MODULE_ALIAS_BLOCKDEV_MAJOR(CDU31A_CDROM_MAJOR); diff -Nru a/drivers/cdrom/cm206.c b/drivers/cdrom/cm206.c --- a/drivers/cdrom/cm206.c Thu Sep 4 15:38:44 2003 +++ b/drivers/cdrom/cm206.c Thu Sep 4 15:38:44 2003 @@ -1616,7 +1616,7 @@ __setup("cm206=", cm206_setup); #endif /* !MODULE */ - +MODULE_ALIAS_BLOCKDEV_MAJOR(CM206_CDROM_MAJOR); /* * Local variables: diff -Nru a/drivers/cdrom/gscd.c b/drivers/cdrom/gscd.c --- a/drivers/cdrom/gscd.c Thu Sep 4 15:38:28 2003 +++ b/drivers/cdrom/gscd.c Thu Sep 4 15:38:28 2003 @@ -1029,3 +1029,4 @@ MODULE_LICENSE("GPL"); module_init(gscd_init); module_exit(gscd_exit); +MODULE_ALIAS_BLOCKDEV_MAJOR(GOLDSTAR_CDROM_MAJOR); diff -Nru a/drivers/cdrom/mcd.c b/drivers/cdrom/mcd.c --- a/drivers/cdrom/mcd.c Thu Sep 4 15:38:37 2003 +++ b/drivers/cdrom/mcd.c Thu Sep 4 15:38:37 2003 @@ -1559,3 +1559,4 @@ MODULE_AUTHOR("Martin Harriss"); MODULE_LICENSE("GPL"); +MODULE_ALIAS_BLOCKDEV_MAJOR(MITSUMI_CDROM_MAJOR); diff -Nru a/drivers/cdrom/mcdx.c b/drivers/cdrom/mcdx.c --- a/drivers/cdrom/mcdx.c Thu Sep 4 15:38:33 2003 +++ b/drivers/cdrom/mcdx.c Thu Sep 4 15:38:33 2003 @@ -1970,3 +1970,4 @@ } MODULE_LICENSE("GPL"); +MODULE_ALIAS_BLOCKDEV_MAJOR(MITSUMI_X_CDROM_MAJOR); diff -Nru a/drivers/cdrom/optcd.c b/drivers/cdrom/optcd.c --- a/drivers/cdrom/optcd.c Thu Sep 4 15:38:31 2003 +++ b/drivers/cdrom/optcd.c Thu Sep 4 15:38:31 2003 @@ -2102,3 +2102,4 @@ module_exit(optcd_exit); MODULE_LICENSE("GPL"); +MODULE_ALIAS_BLOCKDEV_MAJOR(OPTICS_CDROM_MAJOR); diff -Nru a/drivers/cdrom/sbpcd.c b/drivers/cdrom/sbpcd.c --- a/drivers/cdrom/sbpcd.c Thu Sep 4 15:38:30 2003 +++ b/drivers/cdrom/sbpcd.c Thu Sep 4 15:38:30 2003 @@ -5954,6 +5954,9 @@ } MODULE_LICENSE("GPL"); +/* FIXME: Old modules.conf claims MATSUSHITA_CDROM2_MAJOR and CDROM3, but + AFAICT this doesn't support those majors, so why? --RR 30 Jul 2003 */ +MODULE_ALIAS_BLOCKDEV_MAJOR(MATSUSHITA_CDROM_MAJOR); /*==========================================================================*/ /* diff -Nru a/drivers/cdrom/sjcd.c b/drivers/cdrom/sjcd.c --- a/drivers/cdrom/sjcd.c Thu Sep 4 15:38:39 2003 +++ b/drivers/cdrom/sjcd.c Thu Sep 4 15:38:39 2003 @@ -1813,3 +1813,4 @@ module_exit(sjcd_exit); MODULE_LICENSE("GPL"); +MODULE_ALIAS_BLOCKDEV_MAJOR(SANYO_CDROM_MAJOR); diff -Nru a/drivers/cdrom/sonycd535.c b/drivers/cdrom/sonycd535.c --- a/drivers/cdrom/sonycd535.c Thu Sep 4 15:38:32 2003 +++ b/drivers/cdrom/sonycd535.c Thu Sep 4 15:38:32 2003 @@ -1684,3 +1684,4 @@ MODULE_LICENSE("GPL"); +MODULE_ALIAS_BLOCKDEV_MAJOR(CDU535_CDROM_MAJOR); diff -Nru a/drivers/char/Kconfig b/drivers/char/Kconfig --- a/drivers/char/Kconfig Thu Sep 4 15:38:29 2003 +++ b/drivers/char/Kconfig Thu Sep 4 15:38:29 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 Thu Sep 4 15:38:36 2003 +++ b/drivers/char/agp/Kconfig Thu Sep 4 15:38:36 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 Thu Sep 4 15:38:32 2003 +++ b/drivers/char/agp/agp.h Thu Sep 4 15:38:32 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 Thu Sep 4 15:38:38 2003 +++ b/drivers/char/agp/ali-agp.c Thu Sep 4 15:38:38 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 Thu Sep 4 15:38:48 2003 +++ b/drivers/char/agp/amd-k7-agp.c Thu Sep 4 15:38:48 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 Thu Sep 4 15:38:39 2003 +++ b/drivers/char/agp/amd-k8-agp.c Thu Sep 4 15:38:39 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 Thu Sep 4 15:38:40 2003 +++ b/drivers/char/agp/ati-agp.c Thu Sep 4 15:38:40 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 Thu Sep 4 15:38:40 2003 +++ b/drivers/char/agp/backend.c Thu Sep 4 15:38:40 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,10 +318,20 @@ { } +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"); MODULE_LICENSE("GPL and additional rights"); +MODULE_ALIAS_MISCDEV(AGPGART_MINOR); module_init(agp_init); module_exit(agp_exit); diff -Nru a/drivers/char/agp/frontend.c b/drivers/char/agp/frontend.c --- a/drivers/char/agp/frontend.c Thu Sep 4 15:38:30 2003 +++ b/drivers/char/agp/frontend.c Thu Sep 4 15:38:30 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; @@ -1097,4 +1097,3 @@ { misc_deregister(&agp_miscdev); } - diff -Nru a/drivers/char/agp/generic.c b/drivers/char/agp/generic.c --- a/drivers/char/agp/generic.c Thu Sep 4 15:38:32 2003 +++ b/drivers/char/agp/generic.c Thu Sep 4 15:38:32 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 Thu Sep 4 15:38:33 2003 +++ b/drivers/char/agp/intel-agp.c Thu Sep 4 15:38:33 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 Thu Sep 4 15:38:30 2003 +++ b/drivers/char/agp/nvidia-agp.c Thu Sep 4 15:38:30 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 Thu Sep 4 15:38:29 2003 +++ b/drivers/char/agp/sis-agp.c Thu Sep 4 15:38:29 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 Thu Sep 4 15:38:43 2003 +++ b/drivers/char/agp/via-agp.c Thu Sep 4 15:38:43 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 Thu Sep 4 15:38:43 2003 +++ b/drivers/char/busmouse.c Thu Sep 4 15:38:43 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; @@ -452,4 +452,5 @@ EXPORT_SYMBOL(register_busmouse); EXPORT_SYMBOL(unregister_busmouse); +MODULE_ALIAS_MISCDEV(BUSMOUSE_MINOR); MODULE_LICENSE("GPL"); diff -Nru a/drivers/char/cyclades.c b/drivers/char/cyclades.c --- a/drivers/char/cyclades.c Thu Sep 4 15:38:30 2003 +++ b/drivers/char/cyclades.c Thu Sep 4 15:38:30 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 Thu Sep 4 15:38:35 2003 +++ b/drivers/char/drm/drm_fops.h Thu Sep 4 15:38:35 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 Thu Sep 4 15:38:42 2003 +++ b/drivers/char/drm/drm_stub.h Thu Sep 4 15:38:42 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 Thu Sep 4 15:38:34 2003 +++ b/drivers/char/dsp56k.c Thu Sep 4 15:38:34 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 Thu Sep 4 15:38:32 2003 +++ b/drivers/char/dtlk.c Thu Sep 4 15:38:32 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 Thu Sep 4 15:38:37 2003 +++ b/drivers/char/epca.c Thu Sep 4 15:38:37 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 Thu Sep 4 15:38:31 2003 +++ b/drivers/char/ftape/lowlevel/fdc-io.c Thu Sep 4 15:38:31 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 Thu Sep 4 15:38:32 2003 +++ b/drivers/char/ftape/zftape/zftape-init.c Thu Sep 4 15:38:32 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 Thu Sep 4 15:38:34 2003 +++ b/drivers/char/generic_serial.c Thu Sep 4 15:38:34 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 Thu Sep 4 15:38:48 2003 +++ b/drivers/char/ip2main.c Thu Sep 4 15:38:48 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 Thu Sep 4 15:38:43 2003 +++ b/drivers/char/ipmi/ipmi_devintf.c Thu Sep 4 15:38:43 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 Thu Sep 4 15:38:46 2003 +++ b/drivers/char/ipmi/ipmi_watchdog.c Thu Sep 4 15:38:46 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 Thu Sep 4 15:38:37 2003 +++ b/drivers/char/istallion.c Thu Sep 4 15:38:37 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 Thu Sep 4 15:38:39 2003 +++ b/drivers/char/ite_gpio.c Thu Sep 4 15:38:39 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 Thu Sep 4 15:38:32 2003 +++ b/drivers/char/lcd.c Thu Sep 4 15:38:32 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 Thu Sep 4 15:38:28 2003 +++ b/drivers/char/lp.c Thu Sep 4 15:38:28 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; @@ -965,4 +965,5 @@ module_init(lp_init_module); module_exit(lp_cleanup_module); +MODULE_ALIAS("char-major-" __stringify(LP_MAJOR)); MODULE_LICENSE("GPL"); diff -Nru a/drivers/char/lp_old98.c b/drivers/char/lp_old98.c --- a/drivers/char/lp_old98.c Thu Sep 4 15:38:31 2003 +++ b/drivers/char/lp_old98.c Thu Sep 4 15:38:31 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 Thu Sep 4 15:38:34 2003 +++ b/drivers/char/mem.c Thu Sep 4 15:38:34 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 Thu Sep 4 15:38:45 2003 +++ b/drivers/char/misc.c Thu Sep 4 15:38:45 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 Thu Sep 4 15:38:31 2003 +++ b/drivers/char/n_hdlc.c Thu Sep 4 15:38:31 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; } @@ -982,3 +982,4 @@ MODULE_AUTHOR("Paul Fulghum paulkf@microgate.com"); MODULE_PARM(debuglevel, "i"); MODULE_PARM(maxframe, "i"); +MODULE_ALIAS_LDISC(N_HDLC); diff -Nru a/drivers/char/n_r3964.c b/drivers/char/n_r3964.c --- a/drivers/char/n_r3964.c Thu Sep 4 15:38:45 2003 +++ b/drivers/char/n_r3964.c Thu Sep 4 15:38:45 2003 @@ -1428,4 +1428,4 @@ MODULE_LICENSE("GPL"); - +MODULE_ALIAS_LDISC(N_R3964); diff -Nru a/drivers/char/nvram.c b/drivers/char/nvram.c --- a/drivers/char/nvram.c Thu Sep 4 15:38:32 2003 +++ b/drivers/char/nvram.c Thu Sep 4 15:38:32 2003 @@ -923,3 +923,4 @@ EXPORT_SYMBOL(nvram_check_checksum); EXPORT_SYMBOL(__nvram_set_checksum); EXPORT_SYMBOL(nvram_set_checksum); +MODULE_ALIAS_MISCDEV(NVRAM_MINOR); diff -Nru a/drivers/char/pcxx.c b/drivers/char/pcxx.c --- a/drivers/char/pcxx.c Thu Sep 4 15:38:37 2003 +++ b/drivers/char/pcxx.c Thu Sep 4 15:38:37 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 Thu Sep 4 15:38:46 2003 +++ b/drivers/char/ppdev.c Thu Sep 4 15:38:46 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/pty.c b/drivers/char/pty.c --- a/drivers/char/pty.c Thu Sep 4 15:38:31 2003 +++ b/drivers/char/pty.c Thu Sep 4 15:38:31 2003 @@ -354,7 +354,7 @@ pty_slave_driver->init_termios = tty_std_termios; pty_slave_driver->init_termios.c_cflag = B38400 | CS8 | CREAD; pty_slave_driver->flags = TTY_DRIVER_RESET_TERMIOS | - TTY_DRIVER_REAL_RAW | TTY_DRIVER_NO_DEVFS; + TTY_DRIVER_REAL_RAW; pty_slave_driver->other = pty_driver; tty_set_operations(pty_slave_driver, &pty_ops); diff -Nru a/drivers/char/random.c b/drivers/char/random.c --- a/drivers/char/random.c Thu Sep 4 15:38:29 2003 +++ b/drivers/char/random.c Thu Sep 4 15:38:29 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 Thu Sep 4 15:38:37 2003 +++ b/drivers/char/raw.c Thu Sep 4 15:38:37 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/riscom8.c b/drivers/char/riscom8.c --- a/drivers/char/riscom8.c Thu Sep 4 15:38:33 2003 +++ b/drivers/char/riscom8.c Thu Sep 4 15:38:33 2003 @@ -1036,7 +1036,6 @@ int error; struct riscom_port * port; struct riscom_board * bp; - unsigned long flags; board = RC_BOARD(tty->index); if (board >= RC_NBOARD || !(rc_board[board].flags & RC_BOARD_PRESENT)) diff -Nru a/drivers/char/rtc.c b/drivers/char/rtc.c --- a/drivers/char/rtc.c Thu Sep 4 15:38:32 2003 +++ b/drivers/char/rtc.c Thu Sep 4 15:38:32 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,6 @@ static unsigned int rtc_poll(struct file *file, poll_table *wait); #endif -static 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 +198,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 +210,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 +454,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) { @@ -450,7 +481,7 @@ } case RTC_RD_TIME: /* Read the time/date from RTC */ { - get_rtc_time(&wtime); + rtc_get_rtc_time(&wtime); break; } case RTC_SET_TIME: /* Set the RTC */ @@ -582,6 +613,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 +702,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 +801,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 +860,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 +931,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 +1015,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 +1071,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); @@ -1061,7 +1118,7 @@ p = buf; - get_rtc_time(&tm); + rtc_get_rtc_time(&tm); /* * There is no way to tell if the luser has the RTC set for local @@ -1148,7 +1205,7 @@ return uip; } -static void get_rtc_time(struct rtc_time *rtc_tm) +void rtc_get_rtc_time(struct rtc_time *rtc_tm) { unsigned long uip_watchdog = jiffies; unsigned char ctrl; @@ -1254,6 +1311,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 +1329,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); @@ -1280,3 +1345,4 @@ MODULE_AUTHOR("Paul Gortmaker"); MODULE_LICENSE("GPL"); +MODULE_ALIAS_MISCDEV(RTC_MINOR); diff -Nru a/drivers/char/scx200_gpio.c b/drivers/char/scx200_gpio.c --- a/drivers/char/scx200_gpio.c Thu Sep 4 15:38:28 2003 +++ b/drivers/char/scx200_gpio.c Thu Sep 4 15:38:28 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 Thu Sep 4 15:38:40 2003 +++ b/drivers/char/sonypi.c Thu Sep 4 15:38:40 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 Thu Sep 4 15:38:37 2003 +++ b/drivers/char/sonypi.h Thu Sep 4 15:38:37 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 Thu Sep 4 15:38:40 2003 +++ b/drivers/char/stallion.c Thu Sep 4 15:38:41 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 Thu Sep 4 15:38:40 2003 +++ b/drivers/char/tipar.c Thu Sep 4 15:38:40 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 Thu Sep 4 15:38:33 2003 +++ b/drivers/char/tpqic02.c Thu Sep 4 15:38:33 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 Thu Sep 4 15:38:37 2003 +++ b/drivers/char/tty_io.c Thu Sep 4 15:38:37 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 Thu Sep 4 15:38:31 2003 +++ b/drivers/char/vc_screen.c Thu Sep 4 15:38:31 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 Thu Sep 4 15:38:39 2003 +++ b/drivers/char/watchdog/Kconfig Thu Sep 4 15:38:39 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 Thu Sep 4 15:38:40 2003 +++ b/drivers/char/watchdog/Makefile Thu Sep 4 15:38:40 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 Thu Sep 4 15:38:37 2003 +++ b/drivers/char/watchdog/acquirewdt.c Thu Sep 4 15:38:37 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 Thu Sep 4 15:38:32 2003 +++ b/drivers/char/watchdog/advantechwdt.c Thu Sep 4 15:38:32 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 Thu Sep 4 15:38:48 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 Thu Sep 4 15:38:44 2003 +++ b/drivers/char/watchdog/ib700wdt.c Thu Sep 4 15:38:44 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 Thu Sep 4 15:38:30 2003 +++ b/drivers/char/watchdog/machzwd.c Thu Sep 4 15:38:30 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 Thu Sep 4 15:38:29 2003 +++ b/drivers/char/watchdog/pcwd.c Thu Sep 4 15:38:29 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 Thu Sep 4 15:38:45 2003 +++ b/drivers/char/watchdog/wafer5823wdt.c Thu Sep 4 15:38:45 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,12 @@ * to restart it again. */ -#define WDT_START 0x443 -#define WDT_STOP 0x843 +static int wdt_stop = 0x843; +static int wdt_start = 0x443; -#define WD_TIMO 60 /* 1 minute */ -static int wd_margin = WD_TIMO; +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 +75,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 +101,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 +109,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 +142,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 +191,10 @@ { if (test_and_set_bit(0, &wafwdt_is_open)) return -EBUSY; + + /* + * Activate + */ wafwdt_start(); return 0; } @@ -173,12 +202,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 +232,7 @@ static struct file_operations wafwdt_fops = { .owner = THIS_MODULE, + .llseek = no_llseek, .write = wafwdt_write, .ioctl = wafwdt_ioctl, .open = wafwdt_open, @@ -210,53 +242,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 > 255) { + 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 Thu Sep 4 15:38:34 2003 +++ b/drivers/char/watchdog/wdt.c Thu Sep 4 15:38:34 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 */ @@ -579,4 +579,6 @@ MODULE_AUTHOR("Alan Cox"); MODULE_DESCRIPTION("Driver for ISA ICS watchdog cards (WDT500/501)"); +MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR); +MODULE_ALIAS_MISCDEV(TEMP_MINOR); MODULE_LICENSE("GPL"); diff -Nru a/drivers/char/watchdog/wdt_pci.c b/drivers/char/watchdog/wdt_pci.c --- a/drivers/char/watchdog/wdt_pci.c Thu Sep 4 15:38:38 2003 +++ b/drivers/char/watchdog/wdt_pci.c Thu Sep 4 15:38:38 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 Thu Sep 4 15:38:30 2003 +++ b/drivers/i2c/Kconfig Thu Sep 4 15:38:30 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 Thu Sep 4 15:38:42 2003 +++ b/drivers/i2c/i2c-dev.c Thu Sep 4 15:38:42 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 Thu Sep 4 15:38:39 2003 +++ b/drivers/i2c/i2c-keywest.c Thu Sep 4 15:38:39 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 Thu Sep 4 15:38:44 2003 +++ b/drivers/i2c/i2c-keywest.h Thu Sep 4 15:38:44 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 Thu Sep 4 15:38:33 2003 +++ b/drivers/ide/Kconfig Thu Sep 4 15:38:33 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 @@ -823,6 +834,13 @@ Power Macintoshes and PowerBooks to use DMA (direct memory access) to transfer data to and from memory. Saying Y is safe and improves performance. + +config BLK_DEV_IDE_PMAC_BLINK + bool "Blink laptop LED on drive activity" + depends on BLK_DEV_IDE_PMAC && ADB_PMU + help + This option enables the use of the sleep LED as a hard drive + activity LED. config BLK_DEV_IDEDMA_PMAC_AUTO bool "Use DMA by default" diff -Nru a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c --- a/drivers/ide/ide-cd.c Thu Sep 4 15:38:33 2003 +++ b/drivers/ide/ide-cd.c Thu Sep 4 15:38:33 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; @@ -3318,7 +3318,6 @@ .version = IDECD_VERSION, .media = ide_cdrom, .busy = 0, - .supports_dma = 1, .supports_dsc_overlap = 1, .cleanup = ide_cdrom_cleanup, .do_request = ide_do_rw_cdrom, diff -Nru a/drivers/ide/ide-default.c b/drivers/ide/ide-default.c --- a/drivers/ide/ide-default.c Thu Sep 4 15:38:47 2003 +++ b/drivers/ide/ide-default.c Thu Sep 4 15:38:47 2003 @@ -40,18 +40,12 @@ /* * IDE subdriver functions, registered with ide.c - * - * idedefault *must* support DMA because it will be - * attached before the other drivers are loaded and - * we don't want to lose the DMA status at probe - * time. */ ide_driver_t idedefault_driver = { .name = "ide-default", .version = IDEDEFAULT_VERSION, .attach = idedefault_attach, - .supports_dma = 1, .drives = LIST_HEAD_INIT(idedefault_driver.drives) }; diff -Nru a/drivers/ide/ide-disk.c b/drivers/ide/ide-disk.c --- a/drivers/ide/ide-disk.c Thu Sep 4 15:38:32 2003 +++ b/drivers/ide/ide-disk.c Thu Sep 4 15:38:32 2003 @@ -1716,7 +1716,6 @@ .version = IDEDISK_VERSION, .media = ide_disk, .busy = 0, - .supports_dma = 1, .supports_dsc_overlap = 0, .cleanup = idedisk_cleanup, .flushcache = do_idedisk_flushcache, diff -Nru a/drivers/ide/ide-floppy.c b/drivers/ide/ide-floppy.c --- a/drivers/ide/ide-floppy.c Thu Sep 4 15:38:33 2003 +++ b/drivers/ide/ide-floppy.c Thu Sep 4 15:38:33 2003 @@ -1854,7 +1854,6 @@ .version = IDEFLOPPY_VERSION, .media = ide_floppy, .busy = 0, - .supports_dma = 1, .supports_dsc_overlap = 0, .cleanup = idefloppy_cleanup, .do_request = idefloppy_do_request, diff -Nru a/drivers/ide/ide-io.c b/drivers/ide/ide-io.c --- a/drivers/ide/ide-io.c Thu Sep 4 15:38:43 2003 +++ b/drivers/ide/ide-io.c Thu Sep 4 15:38:43 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 Thu Sep 4 15:38:46 2003 +++ b/drivers/ide/ide-lib.c Thu Sep 4 15:38:46 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 Thu Sep 4 15:38:36 2003 +++ b/drivers/ide/ide-probe.c Thu Sep 4 15:38:36 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,14 @@ 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); + + /* enable led activity for disk drives only */ + if (drive->media == ide_disk && hwif->led_act) + blk_queue_activity_fn(q, hwif->led_act, drive); + + return 0; } /* @@ -1068,10 +1077,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 +1100,6 @@ hwgroup->drive->next = drive; } spin_unlock_irq(&ide_lock); - ide_init_drive(drive); } #if !defined(__mc68000__) && !defined(CONFIG_APUS) && !defined(__sparc__) @@ -1201,6 +1208,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 +1233,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 +1318,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 +1349,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 Thu Sep 4 15:38:31 2003 +++ b/drivers/ide/ide-tape.c Thu Sep 4 15:38:31 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; @@ -6316,7 +6316,6 @@ .version = IDETAPE_VERSION, .media = ide_tape, .busy = 1, - .supports_dma = 1, .supports_dsc_overlap = 1, .cleanup = idetape_cleanup, .do_request = idetape_do_request, diff -Nru a/drivers/ide/ide.c b/drivers/ide/ide.c --- a/drivers/ide/ide.c Thu Sep 4 15:38:31 2003 +++ b/drivers/ide/ide.c Thu Sep 4 15:38:31 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 */ @@ -1373,8 +1359,6 @@ static int set_using_dma (ide_drive_t *drive, int arg) { - if (!DRIVER(drive)->supports_dma) - return -EPERM; if (!drive->id || !(drive->id->capability & 1)) return -EPERM; if (HWIF(drive)->ide_dma_check == NULL) @@ -1658,11 +1642,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 +1858,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, @@ -2416,6 +2404,13 @@ return ide_abort(drive, msg); } +static ide_startstop_t default_start_power_step(ide_drive_t *drive, + struct request *rq) +{ + rq->pm->pm_step = ide_pm_state_completed; + return ide_stopped; +} + static void setup_driver_defaults (ide_driver_t *d) { if (d->cleanup == NULL) d->cleanup = default_cleanup; @@ -2430,6 +2425,8 @@ if (d->capacity == NULL) d->capacity = default_capacity; if (d->special == NULL) d->special = default_special; if (d->attach == NULL) d->attach = default_attach; + if (d->start_power_step == NULL) + d->start_power_step = default_start_power_step; } int ide_register_subdriver (ide_drive_t *drive, ide_driver_t *driver, int version) @@ -2453,9 +2450,6 @@ if ((drive->autotune == IDE_TUNE_DEFAULT) || (drive->autotune == IDE_TUNE_AUTO)) { /* DMA timings and setup moved to ide-probe.c */ - if (!driver->supports_dma && HWIF(drive)->ide_dma_off_quietly) -// HWIF(drive)->ide_dma_off_quietly(drive); - HWIF(drive)->ide_dma_off(drive); drive->dsc_overlap = (drive->next != drive && driver->supports_dsc_overlap); drive->nice1 = 1; } diff -Nru a/drivers/ide/ide_modes.h b/drivers/ide/ide_modes.h --- a/drivers/ide/ide_modes.h Thu Sep 4 15:38:28 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 Thu Sep 4 15:38:30 2003 +++ b/drivers/ide/legacy/ali14xx.c Thu Sep 4 15:38:30 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 Thu Sep 4 15:38:31 2003 +++ b/drivers/ide/legacy/dtc2278.c Thu Sep 4 15:38:31 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 Thu Sep 4 15:38:42 2003 +++ b/drivers/ide/legacy/ht6560b.c Thu Sep 4 15:38:42 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 Thu Sep 4 15:38:28 2003 +++ b/drivers/ide/legacy/macide.c Thu Sep 4 15:38:28 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 Thu Sep 4 15:38:30 2003 +++ b/drivers/ide/legacy/qd65xx.c Thu Sep 4 15:38:30 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 Thu Sep 4 15:38:30 2003 +++ b/drivers/ide/legacy/umc8672.c Thu Sep 4 15:38:30 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 Thu Sep 4 15:38:42 2003 +++ b/drivers/ide/pci/aec62xx.c Thu Sep 4 15:38:42 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 Thu Sep 4 15:38:32 2003 +++ b/drivers/ide/pci/alim15x3.c Thu Sep 4 15:38:32 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 Thu Sep 4 15:38:45 2003 +++ b/drivers/ide/pci/cmd640.c Thu Sep 4 15:38:45 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 Thu Sep 4 15:38:43 2003 +++ b/drivers/ide/pci/cmd64x.c Thu Sep 4 15:38:43 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 Thu Sep 4 15:38:29 2003 +++ b/drivers/ide/pci/cs5520.c Thu Sep 4 15:38:29 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 Thu Sep 4 15:38:32 2003 +++ b/drivers/ide/pci/cs5530.c Thu Sep 4 15:38:32 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 Thu Sep 4 15:38:30 2003 +++ b/drivers/ide/pci/cy82c693.c Thu Sep 4 15:38:30 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/generic.c b/drivers/ide/pci/generic.c --- a/drivers/ide/pci/generic.c Thu Sep 4 15:38:34 2003 +++ b/drivers/ide/pci/generic.c Thu Sep 4 15:38:34 2003 @@ -140,6 +140,7 @@ { PCI_VENDOR_ID_HINT, PCI_DEVICE_ID_HINT_VXPROII_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 6}, { PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C561, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 7}, { PCI_VENDOR_ID_OPTI, PCI_DEVICE_ID_OPTI_82C558, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 8}, + { PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8237_SATA, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 9}, { 0, }, }; diff -Nru a/drivers/ide/pci/generic.h b/drivers/ide/pci/generic.h --- a/drivers/ide/pci/generic.h Thu Sep 4 15:38:30 2003 +++ b/drivers/ide/pci/generic.h Thu Sep 4 15:38:30 2003 @@ -127,6 +127,19 @@ .enablebits = {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, .bootable = ON_BOARD, .extra = 0, + },{ /* 9 */ + .vendor = PCI_VENDOR_ID_VIA, + .device = PCI_DEVICE_ID_VIA_8237_SATA, + .name = "VIA8237SATA", + .init_chipset = init_chipset_generic, + .init_iops = NULL, + .init_hwif = init_hwif_generic, + .init_dma = init_dma_generic, + .channels = 2, + .autodma = AUTODMA, + .enablebits = {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, + .bootable = OFF_BOARD, + .extra = 0, },{ .vendor = 0, .device = 0, diff -Nru a/drivers/ide/pci/hpt34x.c b/drivers/ide/pci/hpt34x.c --- a/drivers/ide/pci/hpt34x.c Thu Sep 4 15:38:32 2003 +++ b/drivers/ide/pci/hpt34x.c Thu Sep 4 15:38:32 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 Thu Sep 4 15:38:36 2003 +++ b/drivers/ide/pci/hpt366.c Thu Sep 4 15:38:36 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 Thu Sep 4 15:38:42 2003 +++ b/drivers/ide/pci/it8172.c Thu Sep 4 15:38:42 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 Thu Sep 4 15:38:33 2003 +++ b/drivers/ide/pci/ns87415.c Thu Sep 4 15:38:33 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 Thu Sep 4 15:38:32 2003 +++ b/drivers/ide/pci/opti621.c Thu Sep 4 15:38:32 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 Thu Sep 4 15:38:40 2003 +++ b/drivers/ide/pci/pdc202xx_new.c Thu Sep 4 15:38:40 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 Thu Sep 4 15:38:46 2003 +++ b/drivers/ide/pci/pdc202xx_old.c Thu Sep 4 15:38:46 2003 @@ -46,7 +46,6 @@ #include #include -#include "ide_modes.h" #include "pdc202xx_old.h" #define PDC202_DEBUG_CABLE 0 @@ -748,9 +747,6 @@ hwif->autodma = 0; hwif->tuneproc = &config_chipset_for_pio; hwif->quirkproc = &pdc202xx_quirkproc; - - if (hwif->pci_dev->device == PCI_DEVICE_ID_PROMISE_20265) - hwif->no_lba48 = (hwif->channel) ? 0 : 1; if (hwif->pci_dev->device != PCI_DEVICE_ID_PROMISE_20246) { hwif->busproc = &pdc202xx_tristate; diff -Nru a/drivers/ide/pci/pdcadma.c b/drivers/ide/pci/pdcadma.c --- a/drivers/ide/pci/pdcadma.c Thu Sep 4 15:38:41 2003 +++ b/drivers/ide/pci/pdcadma.c Thu Sep 4 15:38:41 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 Thu Sep 4 15:38:29 2003 +++ b/drivers/ide/pci/piix.c Thu Sep 4 15:38:29 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 Thu Sep 4 15:38:37 2003 +++ b/drivers/ide/pci/sc1200.c Thu Sep 4 15:38:37 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 Thu Sep 4 15:38:29 2003 +++ b/drivers/ide/pci/serverworks.c Thu Sep 4 15:38:29 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 Thu Sep 4 15:38:32 2003 +++ b/drivers/ide/pci/siimage.c Thu Sep 4 15:38:32 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 Thu Sep 4 15:38:35 2003 +++ b/drivers/ide/pci/siimage.h Thu Sep 4 15:38:35 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 Thu Sep 4 15:38:33 2003 +++ b/drivers/ide/pci/sis5513.c Thu Sep 4 15:38:33 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 Thu Sep 4 15:38:31 2003 +++ b/drivers/ide/pci/sl82c105.c Thu Sep 4 15:38:31 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 Thu Sep 4 15:38:41 2003 +++ b/drivers/ide/pci/slc90e66.c Thu Sep 4 15:38:41 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 Thu Sep 4 15:38:32 2003 +++ b/drivers/ide/pci/triflex.c Thu Sep 4 15:38:32 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 Thu Sep 4 15:38:46 2003 +++ b/drivers/ide/ppc/mpc8xx.c Thu Sep 4 15:38:46 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 Thu Sep 4 15:38:29 2003 +++ b/drivers/ide/ppc/pmac.c Thu Sep 4 15:38:29 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 Thu Sep 4 15:38:30 2003 +++ b/drivers/ieee1394/csr.c Thu Sep 4 15:38:30 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 Thu Sep 4 15:38:37 2003 +++ b/drivers/ieee1394/eth1394.c Thu Sep 4 15:38:37 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 Thu Sep 4 15:38:30 2003 +++ b/drivers/ieee1394/ieee1394_core.c Thu Sep 4 15:38:30 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 Thu Sep 4 15:38:30 2003 +++ b/drivers/ieee1394/ieee1394_core.h Thu Sep 4 15:38:30 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 Thu Sep 4 15:38:31 2003 +++ b/drivers/ieee1394/ieee1394_transactions.c Thu Sep 4 15:38:31 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 Thu Sep 4 15:38:31 2003 +++ b/drivers/ieee1394/ieee1394_transactions.h Thu Sep 4 15:38:31 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 Thu Sep 4 15:38:37 2003 +++ b/drivers/ieee1394/nodemgr.c Thu Sep 4 15:38:37 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 Thu Sep 4 15:38:43 2003 +++ b/drivers/ieee1394/ohci1394.c Thu Sep 4 15:38:43 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 Thu Sep 4 15:38:32 2003 +++ b/drivers/ieee1394/pcilynx.c Thu Sep 4 15:38:32 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 Thu Sep 4 15:38:28 2003 +++ b/drivers/ieee1394/raw1394.c Thu Sep 4 15:38:28 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 Thu Sep 4 15:38:29 2003 +++ b/drivers/ieee1394/raw1394.h Thu Sep 4 15:38:29 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 Thu Sep 4 15:38:30 2003 +++ b/drivers/ieee1394/sbp2.c Thu Sep 4 15:38:30 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 Thu Sep 4 15:38:40 2003 +++ b/drivers/input/evdev.c Thu Sep 4 15:38:40 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 Thu Sep 4 15:38:35 2003 +++ b/drivers/input/input.c Thu Sep 4 15:38:35 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 Thu Sep 4 15:38:34 2003 +++ b/drivers/input/joydev.c Thu Sep 4 15:38:34 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 Thu Sep 4 15:38:45 2003 +++ b/drivers/input/mousedev.c Thu Sep 4 15:38:45 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 Thu Sep 4 15:38:29 2003 +++ b/drivers/input/serio/i8042.c Thu Sep 4 15:38:29 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) @@ -581,6 +582,7 @@ static int __init i8042_check_mux(struct i8042_values *values) { unsigned char param; + static int i8042_check_mux_cookie; int i; /* @@ -588,9 +590,9 @@ */ if (request_irq(values->irq, i8042_interrupt, SA_SHIRQ, - "i8042", i8042_request_irq_cookie)) + "i8042", &i8042_check_mux_cookie)) return -1; - free_irq(values->irq, i8042_request_irq_cookie); + free_irq(values->irq, &i8042_check_mux_cookie); /* * Get rid of bytes in the queue. @@ -653,6 +655,7 @@ static int __init i8042_check_aux(struct i8042_values *values) { unsigned char param; + static int i8042_check_aux_cookie; /* * Check if AUX irq is available. If it isn't, then there is no point @@ -660,9 +663,9 @@ */ if (request_irq(values->irq, i8042_interrupt, SA_SHIRQ, - "i8042", i8042_request_irq_cookie)) + "i8042", &i8042_check_aux_cookie)) return -1; - free_irq(values->irq, i8042_request_irq_cookie); + free_irq(values->irq, &i8042_check_aux_cookie); /* * Get rid of bytes in the queue. diff -Nru a/drivers/input/serio/sa1111ps2.c b/drivers/input/serio/sa1111ps2.c --- a/drivers/input/serio/sa1111ps2.c Thu Sep 4 15:38:33 2003 +++ b/drivers/input/serio/sa1111ps2.c Thu Sep 4 15:38:33 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/serio/serport.c b/drivers/input/serio/serport.c --- a/drivers/input/serio/serport.c Thu Sep 4 15:38:44 2003 +++ b/drivers/input/serio/serport.c Thu Sep 4 15:38:44 2003 @@ -24,6 +24,7 @@ MODULE_AUTHOR("Vojtech Pavlik "); MODULE_DESCRIPTION("Input device TTY line discipline"); MODULE_LICENSE("GPL"); +MODULE_ALIAS_LDISC(N_MOUSE); #define SERPORT_BUSY 1 diff -Nru a/drivers/input/tsdev.c b/drivers/input/tsdev.c --- a/drivers/input/tsdev.c Thu Sep 4 15:38:46 2003 +++ b/drivers/input/tsdev.c Thu Sep 4 15:38:46 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 Thu Sep 4 15:38:46 2003 +++ b/drivers/isdn/Kconfig Thu Sep 4 15:38:46 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 Thu Sep 4 15:38:45 2003 +++ b/drivers/isdn/capi/capi.c Thu Sep 4 15:38:45 2003 @@ -412,7 +412,7 @@ static int handle_recv_skb(struct capiminor *mp, struct sk_buff *skb) { struct sk_buff *nskb; - unsigned int datalen; + int datalen; u16 errcode, datahandle; datalen = skb->len - CAPIMSG_LEN(skb->data); @@ -552,12 +552,12 @@ struct capincci *np; u32 ncci; - if (CAPIMSG_COMMAND(skb->data) == CAPI_CONNECT_B3_CONF) { + if (CAPIMSG_CMD(skb->data) == CAPI_CONNECT_B3_CONF) { u16 info = CAPIMSG_U16(skb->data, 12); // Info field if (info == 0) capincci_alloc(cdev, CAPIMSG_NCCI(skb->data)); } - if (CAPIMSG_COMMAND(skb->data) == CAPI_CONNECT_B3_IND) { + if (CAPIMSG_CMD(skb->data) == CAPI_CONNECT_B3_IND) { capincci_alloc(cdev, CAPIMSG_NCCI(skb->data)); } if (CAPIMSG_COMMAND(skb->data) != CAPI_DATA_B3) { @@ -688,7 +688,7 @@ } mlen = CAPIMSG_LEN(skb->data); if (CAPIMSG_CMD(skb->data) == CAPI_DATA_B3_REQ) { - if (mlen + CAPIMSG_DATALEN(skb->data) != count) { + if ((size_t)(mlen + CAPIMSG_DATALEN(skb->data)) != count) { kfree_skb(skb); return -EINVAL; } @@ -700,7 +700,7 @@ } CAPIMSG_SETAPPID(skb->data, cdev->ap.applid); - if (CAPIMSG_COMMAND(skb->data) == CAPI_DISCONNECT_B3_RESP) { + if (CAPIMSG_CMD(skb->data) == CAPI_DISCONNECT_B3_RESP) { capincci_free(cdev, CAPIMSG_NCCI(skb->data)); } @@ -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/capi/capidrv.c b/drivers/isdn/capi/capidrv.c --- a/drivers/isdn/capi/capidrv.c Thu Sep 4 15:38:33 2003 +++ b/drivers/isdn/capi/capidrv.c Thu Sep 4 15:38:33 2003 @@ -48,7 +48,7 @@ struct capidrv_contr { struct capidrv_contr *next; - + struct module *owner; u32 contrnr; char name[20]; @@ -1816,7 +1816,7 @@ capidrv_bchan *bchan; capidrv_ncci *nccip; int len = skb->len; - size_t msglen; + int msglen; u16 errcode; u16 datahandle; @@ -1844,7 +1844,7 @@ 0 /* Flags */ ); - if (capidrv_add_ack(nccip, datahandle, doack ? skb->len : -1) < 0) + if (capidrv_add_ack(nccip, datahandle, doack ? (int)skb->len : -1) < 0) return 0; capi_cmsg2message(&sendcmsg, sendcmsg.buf); @@ -1990,16 +1990,19 @@ char id[20]; int i; - MOD_INC_USE_COUNT; - sprintf(id, "capidrv-%d", contr); if (!(card = (capidrv_contr *) kmalloc(sizeof(capidrv_contr), GFP_ATOMIC))) { printk(KERN_WARNING "capidrv: (%s) Could not allocate contr-struct.\n", id); - MOD_DEC_USE_COUNT; return -1; } memset(card, 0, sizeof(capidrv_contr)); + card->owner = THIS_MODULE; + if (!try_module_get(card->owner)) { + printk(KERN_WARNING "capidrv: (%s) Could not reserve module\n", id); + kfree(card); + return -1; + } init_timer(&card->listentimer); strcpy(card->name, id); card->contrnr = contr; @@ -2008,8 +2011,8 @@ if (!card->bchans) { printk(KERN_WARNING "capidrv: (%s) Could not allocate bchan-structs.\n", id); + module_put(card->owner); kfree(card); - MOD_DEC_USE_COUNT; return -1; } card->interface.channels = profp->nbchannel; @@ -2042,8 +2045,8 @@ if (!register_isdn(&card->interface)) { printk(KERN_ERR "capidrv: Unable to register contr %s\n", id); kfree(card->bchans); + module_put(card->owner); kfree(card); - MOD_DEC_USE_COUNT; return -1; } card->myid = card->interface.channels; @@ -2153,12 +2156,9 @@ } spin_unlock_irqrestore(&global_lock, flags); + module_put(card->owner); printk(KERN_INFO "%s: now down.\n", card->name); - kfree(card); - - MOD_DEC_USE_COUNT; - return 0; } @@ -2245,8 +2245,6 @@ u32 ncontr, contr; u16 errcode; - MOD_INC_USE_COUNT; - if ((p = strchr(revision, ':')) != 0 && p[1]) { strncpy(rev, p + 2, sizeof(rev)); rev[sizeof(rev)-1] = 0; @@ -2262,7 +2260,6 @@ global.ap.recv_message = capidrv_recv_message; errcode = capi20_register(&global.ap); if (errcode) { - MOD_DEC_USE_COUNT; return -EIO; } @@ -2271,7 +2268,6 @@ errcode = capi20_get_profile(0, &profile); if (errcode != CAPI_NOERROR) { capi20_release(&global.ap); - MOD_DEC_USE_COUNT; return -EIO; } @@ -2285,8 +2281,6 @@ proc_init(); printk(KERN_NOTICE "capidrv: Rev %s: loaded\n", rev); - MOD_DEC_USE_COUNT; - return 0; } diff -Nru a/drivers/isdn/capi/capilib.c b/drivers/isdn/capi/capilib.c --- a/drivers/isdn/capi/capilib.c Thu Sep 4 15:38:45 2003 +++ b/drivers/isdn/capi/capilib.c Thu Sep 4 15:38:45 2003 @@ -29,7 +29,7 @@ static inline void mq_init(struct capilib_ncci * np) { - int i; + u_int i; np->msgidqueue = 0; np->msgidlast = 0; np->nmsg = 0; diff -Nru a/drivers/isdn/capi/kcapi.c b/drivers/isdn/capi/kcapi.c --- a/drivers/isdn/capi/kcapi.c Thu Sep 4 15:38:42 2003 +++ b/drivers/isdn/capi/kcapi.c Thu Sep 4 15:38:42 2003 @@ -72,7 +72,7 @@ static struct work_struct tq_state_notify; static struct work_struct tq_recv_notify; -/* -------- ref counting -------------------------------------- */ +/* -------- controller ref counting -------------------------------------- */ static inline struct capi_ctr * capi_ctr_get(struct capi_ctr *card) @@ -89,6 +89,21 @@ DBG("MOD_COUNT DEC"); } +/* -------- own ref counting -------------------------------------- */ + +static inline void +kcapi_get_ref(void) +{ + if (!try_module_get(THIS_MODULE)) + printk(KERN_WARNING "%s: cannot reserve module\n", __FUNCTION__); +} + +static inline void +kcapi_put_ref(void) +{ + module_put(THIS_MODULE); +} + /* ------------------------------------------------------------- */ static inline struct capi_ctr *get_capi_ctr_by_nr(u16 contr) @@ -209,10 +224,10 @@ { struct capi_notifier *np; - MOD_INC_USE_COUNT; + kcapi_get_ref(); np = (struct capi_notifier *)kmalloc(sizeof(struct capi_notifier), GFP_ATOMIC); if (!np) { - MOD_DEC_USE_COUNT; + kcapi_put_ref(); return -1; } memset(np, 0, sizeof(struct capi_notifier)); @@ -226,9 +241,9 @@ * of devices. Devices can only removed in * user process, not in bh. */ - MOD_INC_USE_COUNT; + kcapi_get_ref(); if (schedule_work(&tq_state_notify) == 0) - MOD_DEC_USE_COUNT; + kcapi_put_ref(); return 0; } @@ -286,9 +301,9 @@ while ((np = notify_dequeue()) != 0) { notify_doit(np); kfree(np); - MOD_DEC_USE_COUNT; + kcapi_put_ref(); } - MOD_DEC_USE_COUNT; + kcapi_put_ref(); } /* -------- Receiver ------------------------------------------ */ @@ -626,19 +641,18 @@ EXPORT_SYMBOL(capi20_put_message); -u16 capi20_get_manufacturer(u32 contr, u8 buf[CAPI_MANUFACTURER_LEN]) +u16 capi20_get_manufacturer(u32 contr, u8 *buf) { struct capi_ctr *card; if (contr == 0) { - strlcpy(buf, capi_manufakturer, sizeof(buf)); + strlcpy(buf, capi_manufakturer, CAPI_MANUFACTURER_LEN); return CAPI_NOERROR; } card = get_capi_ctr_by_nr(contr); if (!card || card->cardstate != CARD_RUNNING) return CAPI_REGNOTINSTALLED; - - strlcpy(buf, card->manu, sizeof(buf)); + strlcpy(buf, card->manu, CAPI_MANUFACTURER_LEN); return CAPI_NOERROR; } @@ -662,19 +676,19 @@ EXPORT_SYMBOL(capi20_get_version); -u16 capi20_get_serial(u32 contr, u8 serial[CAPI_SERIAL_LEN]) +u16 capi20_get_serial(u32 contr, u8 *serial) { struct capi_ctr *card; if (contr == 0) { - strlcpy(serial, driver_serial, sizeof(serial)); + strlcpy(serial, driver_serial, CAPI_SERIAL_LEN); return CAPI_NOERROR; } card = get_capi_ctr_by_nr(contr); if (!card || card->cardstate != CARD_RUNNING) return CAPI_REGNOTINSTALLED; - strlcpy((void *) serial, card->serial, sizeof(serial)); + strlcpy((void *) serial, card->serial, CAPI_SERIAL_LEN); return CAPI_NOERROR; } diff -Nru a/drivers/isdn/hardware/avm/Kconfig b/drivers/isdn/hardware/avm/Kconfig --- a/drivers/isdn/hardware/avm/Kconfig Thu Sep 4 15:38:31 2003 +++ b/drivers/isdn/hardware/avm/Kconfig Thu Sep 4 15:38:31 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/avm/avmcard.h b/drivers/isdn/hardware/avm/avmcard.h --- a/drivers/isdn/hardware/avm/avmcard.h Thu Sep 4 15:38:44 2003 +++ b/drivers/isdn/hardware/avm/avmcard.h Thu Sep 4 15:38:44 2003 @@ -95,8 +95,8 @@ struct avmctrl_info *ctrlinfo; - int nr_controllers; - int nlogcontr; + u_int nr_controllers; + u_int nlogcontr; struct list_head list; } avmcard; diff -Nru a/drivers/isdn/hardware/avm/b1.c b/drivers/isdn/hardware/avm/b1.c --- a/drivers/isdn/hardware/avm/b1.c Thu Sep 4 15:38:43 2003 +++ b/drivers/isdn/hardware/avm/b1.c Thu Sep 4 15:38:43 2003 @@ -148,30 +148,31 @@ card->revision = inb(card->port + B1_REVISION); } +#define FWBUF_SIZE 256 int b1_load_t4file(avmcard *card, capiloaddatapart * t4file) { - unsigned char buf[256]; + unsigned char buf[FWBUF_SIZE]; unsigned char *dp; int i, left; unsigned int base = card->port; dp = t4file->data; left = t4file->len; - while (left > sizeof(buf)) { + while (left > FWBUF_SIZE) { if (t4file->user) { - if (copy_from_user(buf, dp, sizeof(buf))) + if (copy_from_user(buf, dp, FWBUF_SIZE)) return -EFAULT; } else { - memcpy(buf, dp, sizeof(buf)); + memcpy(buf, dp, FWBUF_SIZE); } - for (i = 0; i < sizeof(buf); i++) + for (i = 0; i < FWBUF_SIZE; i++) if (b1_save_put_byte(base, buf[i]) < 0) { printk(KERN_ERR "%s: corrupted firmware file ?\n", card->name); return -EIO; } - left -= sizeof(buf); - dp += sizeof(buf); + left -= FWBUF_SIZE; + dp += FWBUF_SIZE; } if (left) { if (t4file->user) { @@ -192,7 +193,7 @@ int b1_load_config(avmcard *card, capiloaddatapart * config) { - unsigned char buf[256]; + unsigned char buf[FWBUF_SIZE]; unsigned char *dp; unsigned int base = card->port; int i, j, left; @@ -205,21 +206,21 @@ b1_put_byte(base, SEND_CONFIG); b1_put_word(base, left); } - while (left > sizeof(buf)) { + while (left > FWBUF_SIZE) { if (config->user) { - if (copy_from_user(buf, dp, sizeof(buf))) + if (copy_from_user(buf, dp, FWBUF_SIZE)) return -EFAULT; } else { - memcpy(buf, dp, sizeof(buf)); + memcpy(buf, dp, FWBUF_SIZE); } - for (i = 0; i < sizeof(buf); ) { + for (i = 0; i < FWBUF_SIZE; ) { b1_put_byte(base, SEND_CONFIG); for (j=0; j < 4; j++) { b1_put_byte(base, buf[i++]); } } - left -= sizeof(buf); - dp += sizeof(buf); + left -= FWBUF_SIZE; + dp += FWBUF_SIZE; } if (left) { if (config->user) { @@ -785,7 +786,7 @@ char rev[32]; if ((p = strchr(revision, ':')) != 0 && p[1]) { - strlcpy(rev, p + 2, sizeof(rev)); + strlcpy(rev, p + 2, 32); if ((p = strchr(rev, '$')) != 0 && p > rev) *(p-1) = 0; } else diff -Nru a/drivers/isdn/hardware/avm/c4.c b/drivers/isdn/hardware/avm/c4.c --- a/drivers/isdn/hardware/avm/c4.c Thu Sep 4 15:38:35 2003 +++ b/drivers/isdn/hardware/avm/c4.c Thu Sep 4 15:38:35 2003 @@ -189,7 +189,7 @@ { u32 val; unsigned char *dp; - int left; + u_int left; u32 loadoff = 0; dp = t4file->data; @@ -664,7 +664,7 @@ u32 status = c4inmeml(card->mbase+DOORBELL); if (status & DBELL_RESET_HOST) { - int i; + u_int i; c4outmeml(card->mbase+PCI_OUT_INT_MASK, 0x0c); if (card->nlogcontr == 0) return IRQ_HANDLED; @@ -791,7 +791,8 @@ { u8 val[4]; unsigned char *dp; - int left, retval; + u_int left; + int retval; if ((retval = queue_sendconfigword(card, 1)) != 0) return retval; @@ -880,7 +881,7 @@ { avmcard *card = ((avmctrl_info *)(ctrl->driverdata))->card; avmctrl_info *cinfo; - int i; + u_int i; c4_reset(card); @@ -896,7 +897,7 @@ { avmcard *card = pci_get_drvdata(pdev); avmctrl_info *cinfo; - int i; + u_int i; c4_reset(card); diff -Nru a/drivers/isdn/hardware/eicon/capifunc.c b/drivers/isdn/hardware/eicon/capifunc.c --- a/drivers/isdn/hardware/eicon/capifunc.c Thu Sep 4 15:38:43 2003 +++ b/drivers/isdn/hardware/eicon/capifunc.c Thu Sep 4 15:38:43 2003 @@ -22,8 +22,8 @@ #define DBG_MINIMUM (DL_LOG + DL_FTL + DL_ERR) #define DBG_DEFAULT (DBG_MINIMUM + DL_XLOG + DL_REG) -static DIVA_CAPI_ADAPTER *adapter = (DIVA_CAPI_ADAPTER *) NULL; -static APPL *application = (APPL *) NULL; +DIVA_CAPI_ADAPTER *adapter = (DIVA_CAPI_ADAPTER *) NULL; +APPL *application = (APPL *) NULL; byte max_appl = MAX_APPL; static CAPI_MSG *mapped_msg = (CAPI_MSG *) NULL; @@ -45,7 +45,7 @@ static void DIRequest(ENTITY * e); static DESCRIPTOR MAdapter; static DESCRIPTOR DAdapter; -static byte max_adapter = 0; +byte max_adapter = 0; static byte ControllerMap[MAX_DESCRIPTORS + 1]; @@ -111,7 +111,7 @@ /* * Controller mapping */ -static byte MapController(byte Controller) +byte MapController(byte Controller) { byte i; byte MappedController = 0; @@ -750,8 +750,6 @@ void **xbuffer_ptr, **xbuffer_internal; diva_os_spin_lock_magic_t old_irql; - DIVA_LOCK_MODULE; - if (diva_os_in_irq()) { DBG_ERR(("CAPI_REGISTER - in irq context !")) return; @@ -777,6 +775,11 @@ return; /* appl already registered */ } + if (!try_module_get(ctrl->owner)) { + printk(KERN_WARNING "%s: cannot reserve module\n", __FUNCTION__); + return; + } + /* alloc memory */ bnum = rp->level3cnt * rp->datablkcnt; @@ -784,6 +787,7 @@ if (!(DataNCCI = diva_os_malloc(0, bnum * sizeof(word)))) { DBG_ERR(("CAPI_REGISTER - memory allocation failed")) + module_put(ctrl->owner); return; } memset(DataNCCI, 0, bnum * sizeof(word)); @@ -791,6 +795,7 @@ if (!(DataFlags = diva_os_malloc(0, bnum * sizeof(word)))) { DBG_ERR(("CAPI_REGISTER - memory allocation failed")) diva_os_free(0, DataNCCI); + module_put(ctrl->owner); return; } memset(DataFlags, 0, bnum * sizeof(word)); @@ -799,6 +804,7 @@ DBG_ERR(("CAPI_REGISTER - memory allocation failed")) diva_os_free(0, DataNCCI); diva_os_free(0, DataFlags); + module_put(ctrl->owner); return; } memset(ReceiveBuffer, 0, bnum * rp->datablklen); @@ -808,6 +814,7 @@ diva_os_free(0, DataNCCI); diva_os_free(0, DataFlags); diva_os_free(0, ReceiveBuffer); + module_put(ctrl->owner); return; } memset(xbuffer_used, 0, xnum); @@ -818,6 +825,7 @@ diva_os_free(0, DataFlags); diva_os_free(0, ReceiveBuffer); diva_os_free(0, xbuffer_used); + module_put(ctrl->owner); return; } memset(xbuffer_ptr, 0, xnum * sizeof(void *)); @@ -829,6 +837,7 @@ diva_os_free(0, ReceiveBuffer); diva_os_free(0, xbuffer_used); diva_os_free(0, xbuffer_ptr); + module_put(ctrl->owner); return; } memset(xbuffer_internal, 0, xnum * sizeof(void *)); @@ -848,6 +857,7 @@ diva_os_free(0, xbuffer_used); diva_os_free(0, xbuffer_ptr); diva_os_free(0, xbuffer_internal); + module_put(ctrl->owner); return; } } @@ -935,7 +945,7 @@ } diva_os_leave_spin_lock(&api_lock, &old_irql, "release_appl"); - DIVA_UNLOCK_MODULE; + module_put(ctrl->owner); } /* diff -Nru a/drivers/isdn/hardware/eicon/divasi.c b/drivers/isdn/hardware/eicon/divasi.c --- a/drivers/isdn/hardware/eicon/divasi.c Thu Sep 4 15:38:32 2003 +++ b/drivers/isdn/hardware/eicon/divasi.c Thu Sep 4 15:38:32 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/hardware/eicon/platform.h b/drivers/isdn/hardware/eicon/platform.h --- a/drivers/isdn/hardware/eicon/platform.h Thu Sep 4 15:38:40 2003 +++ b/drivers/isdn/hardware/eicon/platform.h Thu Sep 4 15:38:40 2003 @@ -201,8 +201,10 @@ /* ** module locking */ +/* #define DIVA_LOCK_MODULE MOD_INC_USE_COUNT #define DIVA_UNLOCK_MODULE MOD_DEC_USE_COUNT +*/ /* ** Spin Lock framework diff -Nru a/drivers/isdn/hisax/amd7930_fn.c b/drivers/isdn/hisax/amd7930_fn.c --- a/drivers/isdn/hisax/amd7930_fn.c Thu Sep 4 15:38:38 2003 +++ b/drivers/isdn/hisax/amd7930_fn.c Thu Sep 4 15:38:38 2003 @@ -692,7 +692,7 @@ if (cs->debug & L1_DEB_ISAC) debugl1(cs, "Amd7930: dbusy_timer_handler: DSR1=0x%02X, DSR2=0x%02X, DER=0x%04X, cs->tx_skb->len=%u, tx_stat=%u, dtcr=%u, cs->tx_cnt=%u", dsr1, dsr2, der, cs->tx_skb->len, cs->dc.amd7930.tx_xmtlen, dtcr, cs->tx_cnt); - if ((cs->dc.amd7930.tx_xmtlen - dtcr) < cs->tx_cnt) { /* D-Channel Busy */ + if ((int)(cs->dc.amd7930.tx_xmtlen - dtcr) < cs->tx_cnt) { /* D-Channel Busy */ test_and_set_bit(FLG_L1_DBUSY, &cs->HW_Flags); stptr = cs->stlist; while (stptr != NULL) { diff -Nru a/drivers/isdn/hisax/callc.c b/drivers/isdn/hisax/callc.c --- a/drivers/isdn/hisax/callc.c Thu Sep 4 15:38:34 2003 +++ b/drivers/isdn/hisax/callc.c Thu Sep 4 15:38:34 2003 @@ -1758,7 +1758,7 @@ /* protocol specific io commands */ case (ISDN_CMD_PROT_IO): for (st = csta->stlist; st; st = st->next) - if (st->protocol == (ic->arg & 0xFF)) + if ((u_int)st->protocol == (ic->arg & 0xFF)) return(st->l3.l4l3_proto(st, ic)); return(-EINVAL); break; diff -Nru a/drivers/isdn/hisax/diva.c b/drivers/isdn/hisax/diva.c --- a/drivers/isdn/hisax/diva.c Thu Sep 4 15:38:45 2003 +++ b/drivers/isdn/hisax/diva.c Thu Sep 4 15:38:45 2003 @@ -751,17 +751,17 @@ card->para[1] = pnp_port_start(pd, 0); card->para[0] = pnp_irq(pd, 0); if (pdev->function == ISAPNP_FUNCTION(0xA1)) { - if (diva_ipac_isa_probe(cs->card, cs)) + if (diva_ipac_isa_probe(card->cs, card)) return 0; return 1; } else { - if (diva_isac_isa_probe(cs->card, cs)) + if (diva_isac_isa_probe(card->cs, card)) return 0; return 1; - } else { - printk(KERN_ERR "Diva PnP: PnP error card found, no device\n"); - return(0); } + } else { + printk(KERN_ERR "Diva PnP: PnP error card found, no device\n"); + return(0); } pdev++; pnp_c=NULL; diff -Nru a/drivers/isdn/hisax/elsa.c b/drivers/isdn/hisax/elsa.c --- a/drivers/isdn/hisax/elsa.c Thu Sep 4 15:38:30 2003 +++ b/drivers/isdn/hisax/elsa.c Thu Sep 4 15:38:30 2003 @@ -838,7 +838,7 @@ cs->hw.elsa.status |= ELSA_BAD_PWR; } switch (cs->subtyp) { - case ELSA_PCFPRO: bytecnt = 16; break; + case ELSA_PCFPRO: bytecnt = 16; break; } if (!request_io(&cs->rs, cs->hw.elsa.base, bytecnt, "elsa isdn")) goto err; diff -Nru a/drivers/isdn/hisax/elsa_ser.c b/drivers/isdn/hisax/elsa_ser.c --- a/drivers/isdn/hisax/elsa_ser.c Thu Sep 4 15:38:32 2003 +++ b/drivers/isdn/hisax/elsa_ser.c Thu Sep 4 15:38:32 2003 @@ -255,7 +255,7 @@ write_modem(struct BCState *bcs) { int ret=0; struct IsdnCardState *cs = bcs->cs; - int count, len, fp; + u_int count, len, fp; unsigned long flags; if (!bcs->tx_skb) @@ -435,8 +435,8 @@ } void -modem_write_cmd(struct IsdnCardState *cs, u8 *buf, int len) { - int count, fp; +modem_write_cmd(struct IsdnCardState *cs, u8 *buf, u_int len) { + u_int count, fp; u8 *msg = buf; unsigned long flags; diff -Nru a/drivers/isdn/hisax/hfc_2bds0.c b/drivers/isdn/hisax/hfc_2bds0.c --- a/drivers/isdn/hisax/hfc_2bds0.c Thu Sep 4 15:38:29 2003 +++ b/drivers/isdn/hisax/hfc_2bds0.c Thu Sep 4 15:38:29 2003 @@ -264,8 +264,9 @@ hfc_fill_fifo(struct BCState *bcs) { struct IsdnCardState *cs = bcs->cs; - int idx, fcnt; - int count; + u_int idx; + int fcnt; + u_int count; u8 cip; if (!bcs->tx_skb) @@ -636,8 +637,8 @@ static void hfc_fill_dfifo(struct IsdnCardState *cs) { - int idx, fcnt; - int count; + int fcnt; + u_int idx, count; u8 cip; if (!cs->tx_skb) diff -Nru a/drivers/isdn/hisax/hfc_2bs0.c b/drivers/isdn/hisax/hfc_2bs0.c --- a/drivers/isdn/hisax/hfc_2bs0.c Thu Sep 4 15:38:29 2003 +++ b/drivers/isdn/hisax/hfc_2bs0.c Thu Sep 4 15:38:29 2003 @@ -249,8 +249,8 @@ hfc_fill_fifo(struct BCState *bcs) { struct IsdnCardState *cs = bcs->cs; - int idx, fcnt; - int count; + int fcnt; + u_int idx, count; int z1, z2; u8 cip; diff -Nru a/drivers/isdn/hisax/hfc_pci.c b/drivers/isdn/hisax/hfc_pci.c --- a/drivers/isdn/hisax/hfc_pci.c Thu Sep 4 15:38:32 2003 +++ b/drivers/isdn/hisax/hfc_pci.c Thu Sep 4 15:38:32 2003 @@ -487,8 +487,8 @@ static void hfcpci_fill_dfifo(struct IsdnCardState *cs) { - int fcnt; - int count, new_z1, maxlen; + int fcnt, new_z1, maxlen; + u_int count; dfifo_type *df; u8 *src, *dst, new_f1; @@ -533,7 +533,7 @@ src = cs->tx_skb->data; /* source pointer */ dst = df->data + le16_to_cpu(df->za[df->f1 & D_FREG_MASK].z1); maxlen = D_FIFO_SIZE - le16_to_cpu(df->za[df->f1 & D_FREG_MASK].z1); /* end fifo */ - if (maxlen > count) + if (maxlen > (int)count) maxlen = count; /* limit size */ memcpy(dst, src, maxlen); /* first copy */ @@ -559,8 +559,8 @@ hfcpci_fill_fifo(struct BCState *bcs) { struct IsdnCardState *cs = bcs->cs; - int maxlen, fcnt; - int count, new_z1; + int maxlen, fcnt, new_z1; + u_int count; bzfifo_type *bz; u8 *bdata; u8 new_f1, *src, *dst; @@ -591,7 +591,7 @@ fcnt = B_FIFO_SIZE - fcnt; /* remaining bytes to send */ while ((fcnt < 2 * HFCPCI_BTRANS_THRESHOLD) && (bcs->tx_skb)) { - if (bcs->tx_skb->len < B_FIFO_SIZE - fcnt) { + if ((int)bcs->tx_skb->len < (B_FIFO_SIZE - fcnt)) { /* data is suitable for fifo */ count = bcs->tx_skb->len; @@ -601,7 +601,7 @@ src = bcs->tx_skb->data; /* source pointer */ dst = bdata + (le16_to_cpu(*z1t) - B_SUB_VAL); maxlen = (B_FIFO_SIZE + B_SUB_VAL) - le16_to_cpu(*z1t); /* end of fifo */ - if (maxlen > count) + if (maxlen > (int)count) maxlen = count; /* limit size */ memcpy(dst, src, maxlen); /* first copy */ @@ -661,7 +661,7 @@ src = bcs->tx_skb->data; /* source pointer */ dst = bdata + (le16_to_cpu(bz->za[bz->f1].z1) - B_SUB_VAL); maxlen = (B_FIFO_SIZE + B_SUB_VAL) - le16_to_cpu(bz->za[bz->f1].z1); /* end fifo */ - if (maxlen > count) + if (maxlen > (int)count) maxlen = count; /* limit size */ memcpy(dst, src, maxlen); /* first copy */ diff -Nru a/drivers/isdn/hisax/hfc_sx.c b/drivers/isdn/hisax/hfc_sx.c --- a/drivers/isdn/hisax/hfc_sx.c Thu Sep 4 15:38:29 2003 +++ b/drivers/isdn/hisax/hfc_sx.c Thu Sep 4 15:38:29 2003 @@ -145,7 +145,7 @@ count = z2 - z1; if (count <= 0) count += fifo_size; /* free bytes */ - if (count < skb->len+1) return(0); /* no room */ + if (count < (int)(skb->len+1)) return(0); /* no room */ count = fifo_size - count; /* bytes still not send */ if (count > 2 * trans_max) return(0); /* delay too long */ count = skb->len; @@ -182,7 +182,7 @@ if (cs->debug & L1_DEB_ISAC_FIFO) debugl1(cs, "hfcsx_write_fifo %d count(%ld/%d)", fifo, skb->len, count); - if (count < skb->len) { + if (count < (int)skb->len) { if (cs->debug & L1_DEB_ISAC_FIFO) debugl1(cs, "hfcsx_write_fifo %d no fifo mem", fifo); return(0); diff -Nru a/drivers/isdn/hisax/hisax.h b/drivers/isdn/hisax/hisax.h --- a/drivers/isdn/hisax/hisax.h Thu Sep 4 15:38:39 2003 +++ b/drivers/isdn/hisax/hisax.h Thu Sep 4 15:38:39 2003 @@ -265,7 +265,7 @@ struct Layer2 { int tei; int sap; - int maxlen; + u_int maxlen; unsigned long flag; unsigned int vs, va, vr; int rc; diff -Nru a/drivers/isdn/hisax/hisax_fcpcipnp.c b/drivers/isdn/hisax/hisax_fcpcipnp.c --- a/drivers/isdn/hisax/hisax_fcpcipnp.c Thu Sep 4 15:38:40 2003 +++ b/drivers/isdn/hisax/hisax_fcpcipnp.c Thu Sep 4 15:38:40 2003 @@ -38,6 +38,8 @@ #define __debug_variable debug #include "hisax_debug.h" +// #define CONFIG_PNP_CARD 1 + #ifdef CONFIG_HISAX_DEBUG static int debug = 0; MODULE_PARM(debug, "i"); @@ -365,8 +367,8 @@ { struct fritz_adapter *adapter = bcs->adapter; struct sk_buff *skb = bcs->tx_skb; - int count; - int fifo_size = 32; + u_int count; + u_int fifo_size = 32; unsigned long flags; unsigned char *p; diff -Nru a/drivers/isdn/hisax/ipacx.c b/drivers/isdn/hisax/ipacx.c --- a/drivers/isdn/hisax/ipacx.c Thu Sep 4 15:38:34 2003 +++ b/drivers/isdn/hisax/ipacx.c Thu Sep 4 15:38:34 2003 @@ -736,5 +736,6 @@ cs->bc_hw_ops = ipacx_bc_ops; val = ipacx_read_reg(cs, IPACX_ID) & 0x3f; printk(KERN_INFO "HiSax: IPACX Design Id: %#x\n", val); + return 0; } diff -Nru a/drivers/isdn/hisax/isar.c b/drivers/isdn/hisax/isar.c --- a/drivers/isdn/hisax/isar.c Thu Sep 4 15:38:32 2003 +++ b/drivers/isdn/hisax/isar.c Thu Sep 4 15:38:32 2003 @@ -677,7 +677,7 @@ if (!(bcs->hw.isar.reg->bstat & (bcs->hw.isar.dpath == 1 ? BSTAT_RDM1 : BSTAT_RDM2))) return; - if (bcs->tx_skb->len > bcs->hw.isar.mml) { + if (bcs->tx_skb->len > (u_int)bcs->hw.isar.mml) { msb = 0; count = bcs->hw.isar.mml; } else { diff -Nru a/drivers/isdn/hisax/isdnl1.h b/drivers/isdn/hisax/isdnl1.h --- a/drivers/isdn/hisax/isdnl1.h Thu Sep 4 15:38:40 2003 +++ b/drivers/isdn/hisax/isdnl1.h Thu Sep 4 15:38:40 2003 @@ -354,7 +354,7 @@ } static inline unsigned char * -xmit_fill_fifo_b(struct BCState *bcs, int fifo_size, int *count, int *more) +xmit_fill_fifo_b(struct BCState *bcs, u_int fifo_size, int *count, int *more) { struct IsdnCardState *cs = bcs->cs; unsigned char *p; @@ -391,7 +391,7 @@ } static inline unsigned char * -xmit_fill_fifo_d(struct IsdnCardState *cs, int fifo_size, int *count, int *more) +xmit_fill_fifo_d(struct IsdnCardState *cs, u_int fifo_size, int *count, int *more) { unsigned char *p; diff -Nru a/drivers/isdn/hisax/isdnl2.c b/drivers/isdn/hisax/isdnl2.c --- a/drivers/isdn/hisax/isdnl2.c Thu Sep 4 15:38:30 2003 +++ b/drivers/isdn/hisax/isdnl2.c Thu Sep 4 15:38:30 2003 @@ -103,7 +103,7 @@ "EV_L2_FRAME_ERROR", }; -static int l2addrsize(struct Layer2 *l2); +static u_int l2addrsize(struct Layer2 *l2); static void set_peer_busy(struct Layer2 *l2) { @@ -178,14 +178,14 @@ clear_peer_busy(l2); } -inline int +inline u_int l2headersize(struct Layer2 *l2, int ui) { return (((test_bit(FLG_MOD128, &l2->flag) && (!ui)) ? 2 : 1) + (test_bit(FLG_LAPD, &l2->flag) ? 2 : 1)); } -inline int +inline u_int l2addrsize(struct Layer2 *l2) { return (test_bit(FLG_LAPD, &l2->flag) ? 2 : 1); @@ -295,7 +295,7 @@ int iframe_error(struct PStack *st, struct sk_buff *skb) { - int i = l2addrsize(&st->l2) + (test_bit(FLG_MOD128, &st->l2.flag) ? 2 : 1); + u_int i = l2addrsize(&st->l2) + (test_bit(FLG_MOD128, &st->l2.flag) ? 2 : 1); int rsp = *skb->data & 0x2; if (test_bit(FLG_ORIG, &st->l2.flag)) @@ -360,7 +360,7 @@ int FRMR_error(struct PStack *st, struct sk_buff *skb) { - int headers = l2addrsize(&st->l2) + 1; + u_int headers = l2addrsize(&st->l2) + 1; u8 *datap = skb->data + headers; int rsp = *skb->data & 0x2; @@ -1066,8 +1066,8 @@ struct PStack *st = fi->userdata; struct sk_buff *skb = arg; struct Layer2 *l2 = &(st->l2); - int PollFlag, ns, i; - unsigned int nr; + int PollFlag, i; + unsigned int nr, ns; i = l2addrsize(l2); if (test_bit(FLG_MOD128, &l2->flag)) { @@ -1251,8 +1251,7 @@ struct sk_buff *skb, *oskb; struct Layer2 *l2 = &st->l2; u8 header[MAX_HEADER_LEN]; - int i; - int unsigned p1; + int unsigned p1, i; unsigned long flags; if (!cansend(st)) @@ -1632,7 +1631,7 @@ { struct sk_buff *skb = arg; u8 *datap; - int ret = 1, len; + u_int ret = 1, len; int c = 0; switch (pr) { diff -Nru a/drivers/isdn/hisax/l3_1tr6.c b/drivers/isdn/hisax/l3_1tr6.c --- a/drivers/isdn/hisax/l3_1tr6.c Thu Sep 4 15:38:37 2003 +++ b/drivers/isdn/hisax/l3_1tr6.c Thu Sep 4 15:38:37 2003 @@ -302,7 +302,8 @@ l3_1tr6_info(struct l3_process *pc, u8 pr, void *arg) { u8 *p; - int i, tmpcharge = 0; + u_int i; + int tmpcharge = 0; char a_charge[8], tmp[32]; struct sk_buff *skb = arg; @@ -400,7 +401,8 @@ { struct sk_buff *skb = arg; u8 *p; - int i, tmpcharge = 0; + u_int i; + int tmpcharge = 0; char a_charge[8], tmp[32]; StopAllL3Timer(pc); @@ -753,7 +755,8 @@ static void up1tr6(struct PStack *st, int pr, void *arg) { - int i, mt, cr; + u_int i; + int mt, cr; struct l3_process *proc; struct sk_buff *skb = arg; char tmp[80]; @@ -868,7 +871,8 @@ static void down1tr6(struct PStack *st, int pr, void *arg) { - int i, cr; + u_int i; + int cr; struct l3_process *proc; struct Channel *chan; char tmp[80]; @@ -915,7 +919,7 @@ static void man1tr6(struct PStack *st, int pr, void *arg) { - int i; + u_int i; struct l3_process *proc = arg; if (!proc) { diff -Nru a/drivers/isdn/hisax/l3dss1.c b/drivers/isdn/hisax/l3dss1.c --- a/drivers/isdn/hisax/l3dss1.c Thu Sep 4 15:38:32 2003 +++ b/drivers/isdn/hisax/l3dss1.c Thu Sep 4 15:38:32 2003 @@ -736,7 +736,7 @@ p += l; mt = *p++; oldpos = 0; - while ((p - skb->data) < skb->len) { + while ((p - skb->data) < (int)skb->len) { if ((*p & 0xf0) == 0x90) { /* shift codeset */ old_codeset = codeset; codeset = *p & 7; @@ -2923,7 +2923,7 @@ u8 tmp[16]; u8 *p = tmp; int l; - int i; + u_int i; struct l3_process *proc = st->l3.global; proc->callref = skb->data[2]; /* cr flag */ @@ -2961,7 +2961,8 @@ static void dss1up(struct PStack *st, int pr, void *arg) { - int i, mt, cr, cause, callState; + u_int i; + int mt, cr, cause, callState; char *ptr; u8 *p; struct sk_buff *skb = arg; @@ -2998,7 +2999,7 @@ return; } cr = getcallref(skb->data); - if (skb->len < ((skb->data[1] & 0x0f) + 3)) { + if (skb->len < (u_int)((skb->data[1] & 0x0f) + 3)) { l3_debug(st, "dss1up frame too short(%d)", skb->len); dev_kfree_skb(skb); return; @@ -3135,7 +3136,8 @@ static void dss1down(struct PStack *st, int pr, void *arg) { - int i, cr; + u_int i; + int cr; struct l3_process *proc; struct Channel *chan; @@ -3186,29 +3188,29 @@ static void dss1man(struct PStack *st, int pr, void *arg) { - int i; - struct l3_process *proc = arg; - - if (!proc) { - printk(KERN_ERR "HiSax dss1man without proc pr=%04x\n", pr); - return; - } - for (i = 0; i < MANSLLEN; i++) + u_int i; + struct l3_process *proc = arg; + + if (!proc) { + printk(KERN_ERR "HiSax dss1man without proc pr=%04x\n", pr); + return; + } + for (i = 0; i < MANSLLEN; i++) if ((pr == manstatelist[i].primitive) && - ((1 << proc->state) & manstatelist[i].state)) - break; - if (i == MANSLLEN) { - if (st->l3.debug & L3_DEB_STATE) { - l3_debug(st, "cr %d dss1man state %d prim %#x unhandled", - proc->callref & 0x7f, proc->state, pr); - } - } else { - if (st->l3.debug & L3_DEB_STATE) { - l3_debug(st, "cr %d dss1man state %d prim %#x", - proc->callref & 0x7f, proc->state, pr); - } - manstatelist[i].rout(proc, pr, arg); - } + ((1 << proc->state) & manstatelist[i].state)) + break; + if (i == MANSLLEN) { + if (st->l3.debug & L3_DEB_STATE) { + l3_debug(st, "cr %d dss1man state %d prim %#x unhandled", + proc->callref & 0x7f, proc->state, pr); + } + } else { + if (st->l3.debug & L3_DEB_STATE) { + l3_debug(st, "cr %d dss1man state %d prim %#x", + proc->callref & 0x7f, proc->state, pr); + } + manstatelist[i].rout(proc, pr, arg); + } } void diff -Nru a/drivers/isdn/hisax/l3ni1.c b/drivers/isdn/hisax/l3ni1.c --- a/drivers/isdn/hisax/l3ni1.c Thu Sep 4 15:38:30 2003 +++ b/drivers/isdn/hisax/l3ni1.c Thu Sep 4 15:38:30 2003 @@ -685,7 +685,7 @@ p += l; mt = *p++; oldpos = 0; - while ((p - skb->data) < skb->len) { + while ((u_int)(p - skb->data) < skb->len) { if ((*p & 0xf0) == 0x90) { /* shift codeset */ old_codeset = codeset; codeset = *p & 7; @@ -2859,7 +2859,7 @@ u8 tmp[16]; u8 *p = tmp; int l; - int i; + u_int i; struct l3_process *proc = st->l3.global; if ( skb ) @@ -2900,7 +2900,8 @@ static void ni1up(struct PStack *st, int pr, void *arg) { - int i, mt, cr, cause, callState; + u_int i; + int mt, cr, cause, callState; char *ptr; u8 *p; struct sk_buff *skb = arg; @@ -2941,7 +2942,7 @@ return; } cr = getcallref(skb->data); - if (skb->len < ((skb->data[1] & 0x0f) + 3)) { + if (skb->len < (u_int)((skb->data[1] & 0x0f) + 3)) { l3_debug(st, "ni1up frame too short(%d)", skb->len); dev_kfree_skb(skb); return; @@ -3086,7 +3087,8 @@ static void ni1down(struct PStack *st, int pr, void *arg) { - int i, cr; + u_int i; + int cr; struct l3_process *proc; struct Channel *chan; @@ -3137,7 +3139,7 @@ static void ni1man(struct PStack *st, int pr, void *arg) { - int i; + u_int i; struct l3_process *proc = arg; if (!proc) { diff -Nru a/drivers/isdn/hisax/netjet.c b/drivers/isdn/hisax/netjet.c --- a/drivers/isdn/hisax/netjet.c Thu Sep 4 15:38:30 2003 +++ b/drivers/isdn/hisax/netjet.c Thu Sep 4 15:38:30 2003 @@ -729,7 +729,7 @@ static void write_raw(struct BCState *bcs, u_int *buf, int cnt) { u_int mask, val, *p=buf; - u_int i, s_cnt; + int i, s_cnt; if (cnt <= 0) return; diff -Nru a/drivers/isdn/hisax/q931.c b/drivers/isdn/hisax/q931.c --- a/drivers/isdn/hisax/q931.c Thu Sep 4 15:38:32 2003 +++ b/drivers/isdn/hisax/q931.c Thu Sep 4 15:38:32 2003 @@ -446,7 +446,7 @@ { u8 *end; char *dp = dest; - int i, cause; + u_int i, cause; end = p + p[1] + 1; p += 2; @@ -871,7 +871,8 @@ disptext_ni1(char *dest, u8 * p) { char *dp = dest; - int l, tag, len, i; + int l, tag, len; + u_int i; p++; l = *p++ - 1; @@ -1200,7 +1201,7 @@ char *dp; unsigned char pd, cr_l, cr, mt; unsigned char sapi, tei, ftyp; - int i, cset = 0, cs_old = 0, cs_fest = 0; + u_int i, cset = 0, cs_old = 0, cs_fest = 0; int size, finish = 0; if (skb->len < 3) diff -Nru a/drivers/isdn/hisax/sedlbauer.c b/drivers/isdn/hisax/sedlbauer.c --- a/drivers/isdn/hisax/sedlbauer.c Thu Sep 4 15:38:46 2003 +++ b/drivers/isdn/hisax/sedlbauer.c Thu Sep 4 15:38:46 2003 @@ -760,7 +760,7 @@ printk(KERN_ERR "Sedlbauer PnP:some resources are missing %ld/%lx\n", pnp_irq(pd, 0), pnp_port_start(pd, 0)); pnp_device_detach(pd); - goto err; + return 0; } card->para[1] = pnp_port_start(pd, 0); card->para[0] = pnp_irq(pd, 0); @@ -777,7 +777,7 @@ } } else { printk(KERN_ERR "Sedlbauer PnP: PnP error card found, no device\n"); - goto err; + return 0; } } pdev++; diff -Nru a/drivers/isdn/hisax/st5481_b.c b/drivers/isdn/hisax/st5481_b.c --- a/drivers/isdn/hisax/st5481_b.c Thu Sep 4 15:38:32 2003 +++ b/drivers/isdn/hisax/st5481_b.c Thu Sep 4 15:38:32 2003 @@ -31,9 +31,9 @@ struct st5481_b_out *b_out = &bcs->b_out; struct st5481_adapter *adapter = bcs->adapter; struct urb *urb; - unsigned int packet_size,offset; - int len,buf_size,bytes_sent; - int i; + u_int packet_size, bytes_sent; + int len, offset, buf_size; + u_int i; struct sk_buff *skb; if (test_and_set_bit(buf_nr, &b_out->busy)) { diff -Nru a/drivers/isdn/hisax/st5481_d.c b/drivers/isdn/hisax/st5481_d.c --- a/drivers/isdn/hisax/st5481_d.c Thu Sep 4 15:38:33 2003 +++ b/drivers/isdn/hisax/st5481_d.c Thu Sep 4 15:38:33 2003 @@ -294,8 +294,8 @@ { struct st5481_d_out *d_out = &adapter->d_out; struct urb *urb; - unsigned int num_packets, packet_offset; - int len, buf_size, bytes_sent; + unsigned int num_packets; + int len, buf_size, bytes_sent, packet_offset; struct sk_buff *skb; struct usb_iso_packet_descriptor *desc; @@ -341,7 +341,7 @@ desc = &urb->iso_frame_desc[num_packets]; desc->offset = packet_offset; desc->length = SIZE_ISO_PACKETS_D_OUT; - if (len - packet_offset < desc->length) + if (len - packet_offset < (int)desc->length) desc->length = len - packet_offset; num_packets++; packet_offset += desc->length; diff -Nru a/drivers/isdn/i4l/Kconfig b/drivers/isdn/i4l/Kconfig --- a/drivers/isdn/i4l/Kconfig Thu Sep 4 15:38:31 2003 +++ b/drivers/isdn/i4l/Kconfig Thu Sep 4 15:38:31 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_audio.c b/drivers/isdn/i4l/isdn_audio.c --- a/drivers/isdn/i4l/isdn_audio.c Thu Sep 4 15:38:28 2003 +++ b/drivers/isdn/i4l/isdn_audio.c Thu Sep 4 15:38:28 2003 @@ -517,7 +517,6 @@ dtmf_state *s; int silence; int i; - unsigned long flags; int grp[2]; char what; char *p; @@ -551,7 +550,7 @@ *p++ = 0x10; *p = what; skb_trim(skb, 2); - if (skb_headroom(skb) < sizeof(isdn_audio_skb)) { + if ((size_t)skb_headroom(skb) < sizeof(isdnaudio_header)) { printk(KERN_WARNING "isdn_audio: insufficient skb_headroom, dropping\n"); kfree_skb(skb); @@ -559,11 +558,7 @@ } ISDN_AUDIO_SKB_DLECOUNT(skb) = 0; ISDN_AUDIO_SKB_LOCK(skb) = 0; - save_flags(flags); - cli(); isdn_tty_queue_tail(info, skb, 2); - restore_flags(flags); - /* Schedule dequeuing */ if ((dev->modempoll) && (info->rcvsched)) mod_timer(&info->read_timer, jiffies + 4); } else @@ -653,7 +648,6 @@ isdn_audio_put_dle_code(modem_info * info, u_char code) { struct sk_buff *skb; - unsigned long flags; char *p; skb = dev_alloc_skb(2); @@ -666,7 +660,7 @@ p = (char *) skb_put(skb, 2); p[0] = 0x10; p[1] = code; - if (skb_headroom(skb) < sizeof(isdn_audio_skb)) { + if ((size_t)skb_headroom(skb) < sizeof(isdnaudio_header)) { printk(KERN_WARNING "isdn_audio: insufficient skb_headroom, dropping\n"); kfree_skb(skb); @@ -674,10 +668,7 @@ } ISDN_AUDIO_SKB_DLECOUNT(skb) = 0; ISDN_AUDIO_SKB_LOCK(skb) = 0; - save_flags(flags); - cli(); isdn_tty_queue_tail(info, skb, 2); - restore_flags(flags); /* Schedule dequeuing */ if ((dev->modempoll) && (info->rcvsched)) mod_timer(&info->read_timer, jiffies + 4); @@ -691,7 +682,7 @@ what = ' '; - if (s->idx > (info->emu.vpar[2] * 800)) { + if (s->idx > (u_int)(info->emu.vpar[2] * 800)) { s->idx = 0; if (!s->state) { /* silence from beginning of rec */ what = 's'; @@ -699,9 +690,9 @@ what = 'q'; } } - if ((what == 's') || (what == 'q')) { - printk(KERN_DEBUG "ttyI%d: %s\n", info->line, - (what=='s') ? "silence":"quiet"); - isdn_audio_put_dle_code(info, what); - } + if ((what == 's') || (what == 'q')) { + printk(KERN_DEBUG "ttyI%d: %s\n", info->line, + (what=='s') ? "silence":"quiet"); + isdn_audio_put_dle_code(info, what); + } } diff -Nru a/drivers/isdn/i4l/isdn_common.c b/drivers/isdn/i4l/isdn_common.c --- a/drivers/isdn/i4l/isdn_common.c Thu Sep 4 15:38:32 2003 +++ b/drivers/isdn/i4l/isdn_common.c Thu Sep 4 15:38:32 2003 @@ -598,6 +598,7 @@ iif->statcallb = isdn_status_callback; isdn_info_update(); + return(0); } static int @@ -609,6 +610,7 @@ drv->features = drv->interface->features; isdn_v110_add_features(drv); set_global_features(); + return(0); } static int @@ -616,6 +618,7 @@ { fsm_change_state(fi, ST_DRV_LOADED); set_global_features(); + return(0); } static int @@ -646,6 +649,7 @@ drv->stavail += c->arg; spin_unlock_irqrestore(&stat_lock, flags); wake_up_interruptible(&drv->st_waitq); + return 0; } static int @@ -1318,20 +1322,18 @@ isdn_status_read(struct file *file, char *buf, size_t count, loff_t * off) { int retval; - int len = 0; + size_t len = 0; char *p; if (off != &file->f_pos) return -ESPIPE; - lock_kernel(); if (!file->private_data) { - if (file->f_flags & O_NONBLOCK) { - retval = -EAGAIN; - goto out; - } + if (file->f_flags & O_NONBLOCK) + return -EAGAIN; interruptible_sleep_on(&(dev->info_waitq)); } + lock_kernel(); p = isdn_statstr(); file->private_data = 0; if ((len = strlen(p)) <= count) { @@ -1362,12 +1364,10 @@ { unsigned int mask = 0; - lock_kernel(); - poll_wait(file, &(dev->info_waitq), wait); + lock_kernel(); if (file->private_data) mask |= POLLIN | POLLRDNORM; - unlock_kernel(); return mask; } @@ -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) @@ -1464,7 +1464,7 @@ struct isdn_slot *slot = file->private_data; DECLARE_WAITQUEUE(wait, current); unsigned long flags; - int len = 0; + size_t len = 0; if (off != &file->f_pos) return -ESPIPE; @@ -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_net_lib.c b/drivers/isdn/i4l/isdn_net_lib.c --- a/drivers/isdn/i4l/isdn_net_lib.c Thu Sep 4 15:38:29 2003 +++ b/drivers/isdn/i4l/isdn_net_lib.c Thu Sep 4 15:38:29 2003 @@ -758,7 +758,7 @@ isdn_net_getphone(isdn_net_ioctl_phone * phone, char *phones) { isdn_net_dev *idev = isdn_net_findif(phone->name); - int count = 0; + u_int count = 0; char *buf = (char *)__get_free_page(GFP_KERNEL); struct isdn_net_phone *n; diff -Nru a/drivers/isdn/i4l/isdn_net_lib.h b/drivers/isdn/i4l/isdn_net_lib.h --- a/drivers/isdn/i4l/isdn_net_lib.h Thu Sep 4 15:38:30 2003 +++ b/drivers/isdn/i4l/isdn_net_lib.h Thu Sep 4 15:38:30 2003 @@ -133,47 +133,47 @@ /* per ISDN channel (ISDN interface) data */ struct isdn_net_dev_s { - struct isdn_slot *isdn_slot; /* Index to isdn device/channel */ - struct isdn_slot *exclusive; /* NULL if non excl */ - int pre_device; /* Preselected isdn-device */ - int pre_channel; /* Preselected isdn-channel */ - - struct timer_list dial_timer; /* dial events timer */ - struct fsm_inst fi; /* call control state machine */ - int dial_event; /* event in case of timer expiry */ - int dial; /* # of phone number just dialed */ - int outgoing; /* Flag: outgoing call */ - int dialretry; /* Counter for Dialout-retries */ - - int cps; /* current speed of this interface */ - int transcount; /* byte-counter for cps-calculation */ - int last_jiffies; /* when transcount was reset */ - int sqfull; /* Flag: netdev-queue overloaded */ - ulong sqfull_stamp; /* Start-Time of overload */ - - int huptimer; /* Timeout-counter for auto-hangup */ - int charge; /* Counter for charging units */ - int charge_state; /* ChargeInfo state machine */ - unsigned long chargetime; /* Timer for Charging info */ - int chargeint; /* Interval between charge-infos */ - - int pppbind; /* ippp device for bindings */ - - struct sk_buff_head super_tx_queue; /* List of supervisory frames to */ - /* be transmitted asap */ - int frame_cnt; /* number of frames currently */ - /* queued in HL driver */ - struct tasklet_struct tlet; - - isdn_net_local *mlp; /* Ptr to master device for all devs*/ - - struct list_head slaves; /* member of local->slaves */ - struct list_head online; /* member of local->online */ - - char name[10]; /* Name of device */ - struct list_head global_list; /* global list of all isdn_net_devs */ - void *ind_priv; /* interface types can put their - private data here */ + struct isdn_slot *isdn_slot; /* Index to isdn device/channel */ + struct isdn_slot *exclusive; /* NULL if non excl */ + int pre_device; /* Preselected isdn-device */ + int pre_channel; /* Preselected isdn-channel */ + + struct timer_list dial_timer; /* dial events timer */ + struct fsm_inst fi; /* call control state machine */ + int dial_event; /* event in case of timer expiry */ + int dial; /* # of phone number just dialed */ + int outgoing; /* Flag: outgoing call */ + int dialretry; /* Counter for Dialout-retries */ + + int cps; /* current speed of this interface */ + int transcount; /* byte-counter for cps-calculation */ + u_long last_jiffies; /* when transcount was reset */ + int sqfull; /* Flag: netdev-queue overloaded */ + u_long sqfull_stamp; /* Start-Time of overload */ + + int huptimer; /* Timeout-counter for auto-hangup */ + int charge; /* Counter for charging units */ + int charge_state; /* ChargeInfo state machine */ + u_long chargetime; /* Timer for Charging info */ + int chargeint; /* Interval between charge-infos */ + + int pppbind; /* ippp device for bindings */ + + struct sk_buff_head super_tx_queue; /* List of supervisory frames to */ + /* be transmitted asap */ + int frame_cnt; /* number of frames currently */ + /* queued in HL driver */ + struct tasklet_struct tlet; + + isdn_net_local *mlp; /* Ptr to master device for all devs*/ + + struct list_head slaves; /* member of local->slaves */ + struct list_head online; /* member of local->online */ + + char name[10]; /* Name of device */ + struct list_head global_list; /* global list of all isdn_net_devs */ + void *ind_priv; /* interface types can put their + private data here */ }; /* ====================================================================== */ diff -Nru a/drivers/isdn/i4l/isdn_ppp.c b/drivers/isdn/i4l/isdn_ppp.c --- a/drivers/isdn/i4l/isdn_ppp.c Thu Sep 4 15:38:38 2003 +++ b/drivers/isdn/i4l/isdn_ppp.c Thu Sep 4 15:38:38 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/isdn/i4l/isdn_tty.c b/drivers/isdn/i4l/isdn_tty.c --- a/drivers/isdn/i4l/isdn_tty.c Thu Sep 4 15:38:40 2003 +++ b/drivers/isdn/i4l/isdn_tty.c Thu Sep 4 15:38:40 2003 @@ -132,7 +132,7 @@ isdn_tty_readbchan(struct modem_info *info, u_char * buf, u_char * fp, int len) { int count; - int count_pull; + u_int count_pull; int count_put; int dflag; struct sk_buff *skb; @@ -179,7 +179,7 @@ #endif /* No DLE's in buff, so simply copy it */ dflag = 1; - if ((count_pull = skb->len) > len) { + if ((int)(count_pull = skb->len) > len) { count_pull = len; dflag = 0; } @@ -315,7 +315,7 @@ skb_pull(skb, 4); } #ifdef CONFIG_ISDN_AUDIO - if (skb_headroom(skb) < sizeof(isdn_audio_skb)) { + if ((size_t)skb_headroom(skb) < sizeof(isdnaudio_header)) { printk(KERN_WARNING "isdn_audio: insufficient skb_headroom, dropping\n"); kfree_skb(skb); @@ -1728,9 +1728,6 @@ modem_info *info; int retval, line; - /* FIXME. This is not unload-race free AFAICS */ - - MOD_INC_USE_COUNT; line = tty->index; if (line < 0 || line > ISDN_MAX_CHANNELS) @@ -1738,6 +1735,8 @@ info = &isdn_mdm.info[line]; if (isdn_tty_paranoia_check(info, tty->name, "isdn_tty_open")) return -ENODEV; + if (!try_module_get(info->owner)) + printk(KERN_WARNING "%s: cannot reserve module\n", __FUNCTION__); #ifdef ISDN_DEBUG_MODEM_OPEN printk(KERN_DEBUG "isdn_tty_open %s, count = %d\n", tty->name, info->count); @@ -1753,6 +1752,7 @@ #ifdef ISDN_DEBUG_MODEM_OPEN printk(KERN_DEBUG "isdn_tty_open return after startup\n"); #endif + module_put(info->owner); return retval; } retval = isdn_tty_block_til_ready(tty, filp, info); @@ -1760,6 +1760,7 @@ #ifdef ISDN_DEBUG_MODEM_OPEN printk(KERN_DEBUG "isdn_tty_open return after isdn_tty_block_til_ready \n"); #endif + module_put(info->owner); return retval; } #ifdef ISDN_DEBUG_MODEM_OPEN @@ -1779,7 +1780,9 @@ ulong flags; ulong timeout; - if (!info || isdn_tty_paranoia_check(info, tty->name, "isdn_tty_close")) + if (!info) + return; + if (isdn_tty_paranoia_check(info, tty->name, "isdn_tty_close")) goto out; save_flags(flags); @@ -1859,7 +1862,7 @@ printk(KERN_DEBUG "isdn_tty_close normal exit\n"); #endif out: - MOD_DEC_USE_COUNT; + module_put(info->owner); } /* @@ -2036,6 +2039,7 @@ return -3; } #endif + info->owner = THIS_MODULE; init_MUTEX(&info->write_sem); sprintf(info->last_cause, "0000"); sprintf(info->last_num, "none"); @@ -2457,7 +2461,7 @@ (!skb_queue_empty(&info->rpqueue)))) { skb = alloc_skb(strlen(msg) #ifdef CONFIG_ISDN_AUDIO - + sizeof(isdn_audio_skb) + + sizeof(isdnaudio_header) #endif , GFP_ATOMIC); if (!skb) { @@ -2465,7 +2469,7 @@ return; } #ifdef CONFIG_ISDN_AUDIO - skb_reserve(skb, sizeof(isdn_audio_skb)); + skb_reserve(skb, sizeof(isdnaudio_header)); #endif sp = skb_put(skb, strlen(msg)); #ifdef CONFIG_ISDN_AUDIO diff -Nru a/drivers/isdn/i4l/isdn_ttyfax.c b/drivers/isdn/i4l/isdn_ttyfax.c --- a/drivers/isdn/i4l/isdn_ttyfax.c Thu Sep 4 15:38:28 2003 +++ b/drivers/isdn/i4l/isdn_ttyfax.c Thu Sep 4 15:38:29 2003 @@ -265,7 +265,7 @@ __u8 RightMask; __u8 fBit; __u8 Data; - int i; + u_int i; if (!info->fax->bor) { for (i = 0; i < skb->len; i++) { diff -Nru a/drivers/isdn/icn/icn.c b/drivers/isdn/icn/icn.c --- a/drivers/isdn/icn/icn.c Thu Sep 4 15:38:48 2003 +++ b/drivers/isdn/icn/icn.c Thu Sep 4 15:38:48 2003 @@ -43,6 +43,8 @@ static char *revision = "$Revision: 1.65.6.8 $"; +static spinlock_t icn_lock = SPIN_LOCK_UNLOCKED; + static int icn_addcard(int, char *, char *); /* @@ -59,16 +61,15 @@ unsigned long flags; skb_queue_purge(queue); - save_flags(flags); - cli(); + spin_lock_irqsave(&icn_lock, flags); card->xlen[channel] = 0; card->sndcount[channel] = 0; if ((skb = card->xskb[channel])) { card->xskb[channel] = NULL; - restore_flags(flags); + spin_unlock_irqrestore(&icn_lock, flags); dev_kfree_skb(skb); } else - restore_flags(flags); + spin_unlock_irqrestore(&icn_lock, flags); } /* Put a value into a shift-register, highest bit first. @@ -146,8 +147,7 @@ #ifdef MAP_DEBUG printk(KERN_DEBUG "icn_lock_channel %d\n", channel); #endif - save_flags(flags); - cli(); + spin_lock_irqsave(&icn_lock, flags); if ((dev.channel == channel) && (card == dev.mcard)) { dev.chanlock++; retval = 1; @@ -160,7 +160,7 @@ printk(KERN_DEBUG "icn_lock_channel %d FAILED, dc=%d\n", channel, dev.channel); #endif } - restore_flags(flags); + spin_unlock_irqrestore(&icn_lock, flags); return retval; } @@ -175,11 +175,10 @@ #ifdef MAP_DEBUG printk(KERN_DEBUG "icn_release_channel l=%d\n", dev.chanlock); #endif - save_flags(flags); - cli(); + spin_lock_irqsave(&icn_lock, flags); if (dev.chanlock > 0) dev.chanlock--; - restore_flags(flags); + spin_unlock_irqrestore(&icn_lock, flags); } /* @@ -195,19 +194,18 @@ printk(KERN_DEBUG "trymaplock c=%d dc=%d l=%d\n", channel, dev.channel, dev.chanlock); #endif - save_flags(flags); - cli(); + spin_lock_irqsave(&icn_lock, flags); if ((!dev.chanlock) || ((dev.channel == channel) && (dev.mcard == card))) { dev.chanlock++; icn_map_channel(card, channel); - restore_flags(flags); + spin_unlock_irqrestore(&icn_lock, flags); #ifdef MAP_DEBUG printk(KERN_DEBUG "trymaplock %d OK\n", channel); #endif return 1; } - restore_flags(flags); + spin_unlock_irqrestore(&icn_lock, flags); #ifdef MAP_DEBUG printk(KERN_DEBUG "trymaplock %d FAILED\n", channel); #endif @@ -226,13 +224,12 @@ #ifdef MAP_DEBUG printk(KERN_DEBUG "map_release c=%d l=%d\n", channel, dev.chanlock); #endif - save_flags(flags); - cli(); + spin_lock_irqsave(&icn_lock, flags); if (dev.chanlock > 0) dev.chanlock--; if (!dev.chanlock) icn_map_channel(card, channel); - restore_flags(flags); + spin_unlock_irqrestore(&icn_lock, flags); } /* Get Data from the B-Channel, assemble fragmented packets and put them @@ -308,14 +305,13 @@ (card->sndcount[channel] || skb_queue_len(&card->spqueue[channel]) || card->xskb[channel])) { - save_flags(flags); - cli(); + spin_lock_irqsave(&icn_lock, flags); if (card->xmit_lock[channel]) { - restore_flags(flags); + spin_unlock_irqrestore(&icn_lock, flags); break; } card->xmit_lock[channel]++; - restore_flags(flags); + spin_unlock_irqrestore(&icn_lock, flags); skb = card->xskb[channel]; if (!skb) { skb = skb_dequeue(&card->spqueue[channel]); @@ -345,11 +341,10 @@ sbnext; /* switch to next buffer */ icn_maprelease_channel(card, mch & 2); if (!skb->len) { - save_flags(flags); - cli(); + spin_lock_irqsave(&icn_lock, flags); if (card->xskb[channel]) card->xskb[channel] = NULL; - restore_flags(flags); + spin_unlock_irqrestore(&icn_lock, flags); dev_kfree_skb(skb); if (card->xlen[channel]) { cmd.command = ISDN_STAT_BSENT; @@ -359,10 +354,9 @@ card->interface.statcallb(&cmd); } } else { - save_flags(flags); - cli(); + spin_lock_irqsave(&icn_lock, flags); card->xskb[channel] = skb; - restore_flags(flags); + spin_unlock_irqrestore(&icn_lock, flags); } card->xmit_lock[channel] = 0; if (!icn_trymaplock_channel(card, mch)) @@ -393,11 +387,10 @@ } if (card->flags & (ICN_FLAGS_B1ACTIVE | ICN_FLAGS_B2ACTIVE)) { /* schedule b-channel polling again */ - save_flags(flags); - cli(); + spin_lock_irqsave(&icn_lock, flags); mod_timer(&card->rb_timer, jiffies+ICN_TIMER_BCREAD); card->flags |= ICN_FLAGS_RBTIMER; - restore_flags(flags); + spin_unlock_irqrestore(&icn_lock, flags); } else card->flags &= ~ICN_FLAGS_RBTIMER; } @@ -464,9 +457,8 @@ cmd.driver = card->myid; cmd.arg = channel; switch (action) { - case 11: - save_flags(flags); - cli(); + case 11: + spin_lock_irqsave(&icn_lock, flags); icn_free_queue(card,channel); card->rcvidx[channel] = 0; @@ -483,11 +475,10 @@ ncmd.driver = card->myid; ncmd.arg = channel; ncmd.command = ISDN_STAT_BHUP; - restore_flags(flags); + spin_unlock_irqrestore(&icn_lock, flags); card->interface.statcallb(&cmd); } else - restore_flags(flags); - + spin_unlock_irqrestore(&icn_lock, flags); break; case 1: icn_free_queue(card,channel); @@ -498,10 +489,9 @@ card->flags &= ~((channel) ? ICN_FLAGS_B2ACTIVE : ICN_FLAGS_B1ACTIVE); icn_free_queue(card, channel); - save_flags(flags); - cli(); + spin_lock_irqsave(&icn_lock, flags); card->rcvidx[channel] = 0; - restore_flags(flags); + spin_unlock_irqrestore(&icn_lock, flags); break; case 3: { @@ -557,10 +547,9 @@ case 8: card->flags &= ~ICN_FLAGS_B1ACTIVE; icn_free_queue(card, 0); - save_flags(flags); - cli(); + spin_lock_irqsave(&icn_lock, flags); card->rcvidx[0] = 0; - restore_flags(flags); + spin_unlock_irqrestore(&icn_lock, flags); cmd.arg = 0; cmd.driver = card->myid; card->interface.statcallb(&cmd); @@ -571,10 +560,9 @@ cmd.command = ISDN_STAT_BHUP; card->flags &= ~ICN_FLAGS_B2ACTIVE; icn_free_queue(card, 1); - save_flags(flags); - cli(); + spin_lock_irqsave(&icn_lock, flags); card->rcvidx[1] = 0; - restore_flags(flags); + spin_unlock_irqrestore(&icn_lock, flags); cmd.arg = 1; cmd.driver = card->myid; card->interface.statcallb(&cmd); @@ -592,8 +580,7 @@ { ulong flags; - save_flags(flags); - cli(); + spin_lock_irqsave(&icn_lock, flags); *card->msg_buf_write++ = (c == 0xff) ? '\n' : c; if (card->msg_buf_write == card->msg_buf_read) { if (++card->msg_buf_read > card->msg_buf_end) @@ -601,7 +588,7 @@ } if (card->msg_buf_write > card->msg_buf_end) card->msg_buf_write = card->msg_buf; - restore_flags(flags); + spin_unlock_irqrestore(&icn_lock, flags); } static void @@ -683,20 +670,18 @@ if (!(card->flags & ICN_FLAGS_RBTIMER)) { /* schedule b-channel polling */ card->flags |= ICN_FLAGS_RBTIMER; - save_flags(flags); - cli(); + spin_lock_irqsave(&icn_lock, flags); del_timer(&card->rb_timer); card->rb_timer.function = icn_pollbchan; card->rb_timer.data = (unsigned long) card; card->rb_timer.expires = jiffies + ICN_TIMER_BCREAD; add_timer(&card->rb_timer); - restore_flags(flags); + spin_unlock_irqrestore(&icn_lock, flags); } /* schedule again */ - save_flags(flags); - cli(); + spin_lock_irqsave(&icn_lock, flags); mod_timer(&card->st_timer, jiffies+ICN_TIMER_DCREAD); - restore_flags(flags); + spin_unlock_irqrestore(&icn_lock, flags); } /* Append a packet to the transmit buffer-queue. @@ -725,8 +710,7 @@ return 0; if (card->sndcount[channel] > ICN_MAX_SQUEUE) return 0; - save_flags(flags); - cli(); + spin_lock_irqsave(&icn_lock, flags); nskb = skb_clone(skb, GFP_ATOMIC); if (nskb) { /* Push ACK flag as one @@ -738,7 +722,7 @@ } else len = 0; card->sndcount[channel] += len; - restore_flags(flags); + spin_unlock_irqrestore(&icn_lock, flags); } return len; } @@ -860,11 +844,10 @@ #ifdef BOOT_DEBUG printk(KERN_DEBUG "Map Bank 0\n"); #endif - save_flags(flags); - cli(); + spin_lock_irqsave(&icn_lock, flags); icn_map_channel(card, 0); /* Select Bank 0 */ icn_lock_channel(card, 0); /* Lock Bank 0 */ - restore_flags(flags); + spin_unlock_irqrestore(&icn_lock, flags); SLEEP(1); memcpy_toio(dev.shmem, codebuf, ICN_CODE_STAGE1); /* Copy code */ #ifdef BOOT_DEBUG @@ -875,12 +858,11 @@ #ifdef BOOT_DEBUG printk(KERN_DEBUG "Map Bank 8\n"); #endif - save_flags(flags); - cli(); + spin_lock_irqsave(&icn_lock, flags); icn_release_channel(); icn_map_channel(card, 2); /* Select Bank 8 */ icn_lock_channel(card, 2); /* Lock Bank 8 */ - restore_flags(flags); + spin_unlock_irqrestore(&icn_lock, flags); SLEEP(1); memcpy_toio(dev.shmem, codebuf, ICN_CODE_STAGE1); /* Copy code */ #ifdef BOOT_DEBUG @@ -900,11 +882,10 @@ #ifdef BOOT_DEBUG printk(KERN_DEBUG "Map Bank 0\n"); #endif - save_flags(flags); - cli(); + spin_lock_irqsave(&icn_lock, flags); icn_map_channel(card, 0); /* Select Bank 0 */ icn_lock_channel(card, 0); /* Lock Bank 0 */ - restore_flags(flags); + spin_unlock_irqrestore(&icn_lock, flags); SLEEP(1); ret = (icn_check_loader(1)); @@ -931,8 +912,7 @@ if ((ret = verify_area(VERIFY_READ, (void *) buffer, ICN_CODE_STAGE2))) return ret; timer = 0; - save_flags(flags); - cli(); + spin_lock_irqsave(&icn_lock, flags); if (card->secondhalf) { icn_map_channel(card, 2); icn_lock_channel(card, 2); @@ -940,7 +920,7 @@ icn_map_channel(card, 0); icn_lock_channel(card, 0); } - restore_flags(flags); + spin_unlock_irqrestore(&icn_lock, flags); while (left) { if (sbfree) { /* If there is a free buffer... */ cnt = left; @@ -995,8 +975,7 @@ printk(KERN_DEBUG "Proto loaded, install poll-timer %d\n", card->secondhalf); #endif - save_flags(flags); - cli(); + spin_lock_irqsave(&icn_lock, flags); init_timer(&card->st_timer); card->st_timer.expires = jiffies + ICN_TIMER_DCREAD; card->st_timer.function = icn_polldchan; @@ -1011,7 +990,7 @@ add_timer(&card->other->st_timer); card->other->flags |= ICN_FLAGS_RUNNING; } - restore_flags(flags); + spin_unlock_irqrestore(&icn_lock, flags); } icn_maprelease_channel(card, 0); return 0; @@ -1069,8 +1048,7 @@ } else memcpy(msg, buf, count); - save_flags(flags); - cli(); + spin_lock_irqsave(&icn_lock, flags); lastmap_card = dev.mcard; lastmap_channel = dev.channel; icn_map_channel(card, mch); @@ -1092,7 +1070,7 @@ writeb((readb(&cmd_i) + count) & 0xff, &cmd_i); if (lastmap_card) icn_map_channel(lastmap_card, lastmap_channel); - restore_flags(flags); + spin_unlock_irqrestore(&icn_lock, flags); if (len) { mdelay(1); if (loop++ > 20) @@ -1118,8 +1096,7 @@ unsigned long flags; isdn_ctrl cmd; - save_flags(flags); - cli(); + spin_lock_irqsave(&icn_lock, flags); if (card->flags & ICN_FLAGS_RUNNING) { card->flags &= ~ICN_FLAGS_RUNNING; del_timer(&card->st_timer); @@ -1130,7 +1107,7 @@ if (card->doubleS0) icn_stopcard(card->other); } - restore_flags(flags); + spin_unlock_irqrestore(&icn_lock, flags); } static void @@ -1154,7 +1131,7 @@ icn_card *card = cards; while (card) { - if (check_region(card->port, ICN_PORTLEN)) { + if (!request_region(card->port, ICN_PORTLEN, "icn-isdn")) { printk(KERN_WARNING "icn: (%s) ports 0x%03x-0x%03x in use.\n", CID, @@ -1163,6 +1140,7 @@ } else { OUTB_P(0, ICN_RUN); /* Reset Controller */ OUTB_P(0, ICN_MAPRAM); /* Disable RAM */ + release_region(card->port, ICN_PORTLEN); } card = card->next; } @@ -1184,22 +1162,22 @@ switch (c->arg) { case ICN_IOCTL_SETMMIO: if (dev.memaddr != (a & 0x0ffc000)) { - if (check_mem_region(a & 0x0ffc000, 0x4000)) { + if (!request_mem_region(a & 0x0ffc000, 0x4000, "icn-isdn (all cards)")) { printk(KERN_WARNING "icn: memory at 0x%08lx in use.\n", a & 0x0ffc000); return -EINVAL; } + release_mem_region(a & 0x0ffc000, 0x4000); icn_stopallcards(); - save_flags(flags); - cli(); + spin_lock_irqsave(&icn_lock, flags); if (dev.mvalid) { iounmap(dev.shmem); release_mem_region(dev.memaddr, 0x4000); } dev.mvalid = 0; dev.memaddr = a & 0x0ffc000; - restore_flags(flags); + spin_unlock_irqrestore(&icn_lock, flags); printk(KERN_INFO "icn: (%s) mmio set to 0x%08lx\n", CID, @@ -1214,15 +1192,15 @@ a == 0x308 || a == 0x318 || a == 0x328 || a == 0x338 || a == 0x348 || a == 0x358 || a == 0x368) { if (card->port != (unsigned short) a) { - if (check_region((unsigned short) a, ICN_PORTLEN)) { + if (!request_region((unsigned short) a, ICN_PORTLEN, "icn-isdn")) { printk(KERN_WARNING "icn: (%s) ports 0x%03x-0x%03x in use.\n", CID, (int) a, (int) a + ICN_PORTLEN); return -EINVAL; } + release_region((unsigned short) a, ICN_PORTLEN); icn_stopcard(card); - save_flags(flags); - cli(); + spin_lock_irqsave(&icn_lock, flags); if (card->rvalid) release_region(card->port, ICN_PORTLEN); card->port = (unsigned short) a; @@ -1231,7 +1209,7 @@ card->other->port = (unsigned short) a; card->other->rvalid = 0; } - restore_flags(flags); + spin_unlock_irqrestore(&icn_lock, flags); printk(KERN_INFO "icn: (%s) port set to 0x%03x\n", CID, card->port); diff -Nru a/drivers/isdn/sc/card.h b/drivers/isdn/sc/card.h --- a/drivers/isdn/sc/card.h Thu Sep 4 15:38:46 2003 +++ b/drivers/isdn/sc/card.h Thu Sep 4 15:38:46 2003 @@ -94,6 +94,7 @@ int StartOnReset; /* Indicates startproc after reset */ int EngineUp; /* Indicates CommEngine Up */ int trace_mode; /* Indicate if tracing is on */ + spinlock_t lock; /* local lock */ } board; #endif /* CARD_H */ diff -Nru a/drivers/isdn/sc/command.c b/drivers/isdn/sc/command.c --- a/drivers/isdn/sc/command.c Thu Sep 4 15:38:31 2003 +++ b/drivers/isdn/sc/command.c Thu Sep 4 15:38:31 2003 @@ -419,14 +419,13 @@ adapter[card]->EngineUp = 0; - save_flags(flags); - cli(); + spin_lock_irqsave(&adapter[card]->lock, flags); init_timer(&adapter[card]->reset_timer); adapter[card]->reset_timer.function = check_reset; adapter[card]->reset_timer.data = card; adapter[card]->reset_timer.expires = jiffies + CHECKRESET_TIME; add_timer(&adapter[card]->reset_timer); - restore_flags(flags); + spin_unlock_irqrestore(&adapter[card]->lock, flags); outb(0x1,adapter[card]->ioport[SFT_RESET]); diff -Nru a/drivers/isdn/sc/init.c b/drivers/isdn/sc/init.c --- a/drivers/isdn/sc/init.c Thu Sep 4 15:38:40 2003 +++ b/drivers/isdn/sc/init.c Thu Sep 4 15:38:40 2003 @@ -97,11 +97,12 @@ * No, I/O Base has been provided */ for (i = 0 ; i < MAX_IO_REGS - 1 ; i++) { - if(check_region(io[b] + i * 0x400, 1)) { + if(!request_region(io[b] + i * 0x400, 1, "sc test")) { pr_debug("check_region for 0x%x failed\n", io[b] + i * 0x400); io[b] = 0; break; - } + } else + release_region(io[b] + i * 0x400, 1); } /* @@ -136,11 +137,12 @@ last_base = i + IOBASE_OFFSET; pr_debug(" checking 0x%x...", i); for ( j = 0 ; j < MAX_IO_REGS - 1 ; j++) { - if(check_region(i + j * 0x400, 1)) { + if(!request_region(i + j * 0x400, 1, "sc test")) { pr_debug("Failed\n"); found_io = 0; break; - } + } else + release_region(i + j * 0x400, 1); } if(found_io) { @@ -177,9 +179,10 @@ * Just look for a signature and ID the * board model */ - if(!check_region(ram[b], SRAM_PAGESIZE)) { - pr_debug("check_region for RAM base 0x%x succeeded\n", ram[b]); + if(request_region(ram[b], SRAM_PAGESIZE, "sc test")) { + pr_debug("request_region for RAM base 0x%x succeeded\n", ram[b]); model = identify_board(ram[b], io[b]); + release_region(ram[b], SRAM_PAGESIZE); } } else { @@ -189,9 +192,10 @@ */ for (i = SRAM_MIN ; i < SRAM_MAX ; i += SRAM_PAGESIZE) { pr_debug("Checking RAM address 0x%x...\n", i); - if(!check_region(i, SRAM_PAGESIZE)) { + if(request_region(i, SRAM_PAGESIZE, "sc test")) { pr_debug(" check_region succeeded\n"); model = identify_board(i, io[b]); + release_region(i, SRAM_PAGESIZE); if (model >= 0) { pr_debug(" Identified a %s\n", boardname[model]); @@ -201,7 +205,7 @@ pr_debug(" Unidentifed or inaccessible\n"); continue; } - pr_debug(" check_region failed\n"); + pr_debug(" request failed\n"); } } /* @@ -310,6 +314,7 @@ continue; } memset(adapter[cinst], 0, sizeof(board)); + spin_lock_init(&adapter[cinst]->lock); if(!register_isdn(interface)) { /* diff -Nru a/drivers/isdn/sc/message.c b/drivers/isdn/sc/message.c --- a/drivers/isdn/sc/message.c Thu Sep 4 15:38:43 2003 +++ b/drivers/isdn/sc/message.c Thu Sep 4 15:38:43 2003 @@ -55,8 +55,7 @@ /* * Map in the DPM to the base page and copy the message */ - save_flags(flags); - cli(); + spin_lock_irqsave(&adapter[card]->lock, flags); outb((adapter[card]->shmem_magic >> 14) | 0x80, adapter[card]->ioport[adapter[card]->shmem_pgport]); dpm = (DualPortMemory *) adapter[card]->rambase; @@ -64,8 +63,7 @@ MSG_LEN); dpm->rsp_tail = (dpm->rsp_tail+1) % MAX_MESSAGES; inb(adapter[card]->ioport[FIFO_READ]); - restore_flags(flags); - + spin_unlock_irqrestore(&adapter[card]->lock, flags); /* * Tell the board that the message is received */ @@ -152,15 +150,14 @@ /* * Disable interrupts and map in shared memory */ - save_flags(flags); - cli(); + spin_lock_irqsave(&adapter[card]->lock, flags); outb((adapter[card]->shmem_magic >> 14) | 0x80, adapter[card]->ioport[adapter[card]->shmem_pgport]); dpm = (DualPortMemory *) adapter[card]->rambase; /* Fix me */ memcpy_toio(&(dpm->req_queue[dpm->req_head]),&sndmsg,MSG_LEN); dpm->req_head = (dpm->req_head+1) % MAX_MESSAGES; outb(sndmsg.sequence_no, adapter[card]->ioport[FIFO_WRITE]); - restore_flags(flags); + spin_unlock_irqrestore(&adapter[card]->lock, flags); pr_debug("%s: Sent Message seq:%d pid:%d time:%d " "cnt:%d (type,class,code):(%d,%d,%d) " diff -Nru a/drivers/isdn/sc/shmem.c b/drivers/isdn/sc/shmem.c --- a/drivers/isdn/sc/shmem.c Thu Sep 4 15:38:31 2003 +++ b/drivers/isdn/sc/shmem.c Thu Sep 4 15:38:31 2003 @@ -53,18 +53,17 @@ /* * Block interrupts and load the page */ - save_flags(flags); - cli(); + spin_lock_irqsave(&adapter[card]->lock, flags); outb(((adapter[card]->shmem_magic + ch * SRAM_PAGESIZE) >> 14) | 0x80, adapter[card]->ioport[adapter[card]->shmem_pgport]); - pr_debug("%s: set page to %#x\n",adapter[card]->devicename, - ((adapter[card]->shmem_magic + ch * SRAM_PAGESIZE)>>14)|0x80); ret = memcpy_toio(adapter[card]->rambase + ((unsigned long) dest % 0x4000), src, n); + spin_unlock_irqrestore(&adapter[card]->lock, flags); + pr_debug("%s: set page to %#x\n",adapter[card]->devicename, + ((adapter[card]->shmem_magic + ch * SRAM_PAGESIZE)>>14)|0x80); pr_debug("%s: copying %d bytes from %#x to %#x\n",adapter[card]->devicename, n, (unsigned long) src, adapter[card]->rambase + ((unsigned long) dest %0x4000)); - restore_flags(flags); return ret; } @@ -97,19 +96,18 @@ /* * Block interrupts and load the page */ - save_flags(flags); - cli(); + spin_lock_irqsave(&adapter[card]->lock, flags); outb(((adapter[card]->shmem_magic + ch * SRAM_PAGESIZE) >> 14) | 0x80, adapter[card]->ioport[adapter[card]->shmem_pgport]); - pr_debug("%s: set page to %#x\n",adapter[card]->devicename, - ((adapter[card]->shmem_magic + ch * SRAM_PAGESIZE)>>14)|0x80); ret = memcpy_fromio(dest,(void *)(adapter[card]->rambase + ((unsigned long) src % 0x4000)), n); + spin_unlock_irqrestore(&adapter[card]->lock, flags); + pr_debug("%s: set page to %#x\n",adapter[card]->devicename, + ((adapter[card]->shmem_magic + ch * SRAM_PAGESIZE)>>14)|0x80); /* pr_debug("%s: copying %d bytes from %#x to %#x\n", adapter[card]->devicename, n, adapter[card]->rambase + ((unsigned long) src %0x4000), (unsigned long) dest); */ - restore_flags(flags); return ret; } @@ -138,16 +136,15 @@ /* * Block interrupts and load the page */ - save_flags(flags); - cli(); + spin_lock_irqsave(&adapter[card]->lock, flags); outb(((adapter[card]->shmem_magic + ch * SRAM_PAGESIZE) >> 14) | 0x80, adapter[card]->ioport[adapter[card]->shmem_pgport]); - pr_debug("%s: set page to %#x\n",adapter[card]->devicename, - ((adapter[card]->shmem_magic + ch * SRAM_PAGESIZE)>>14)|0x80); ret = memset_io(adapter[card]->rambase + ((unsigned long) dest % 0x4000), c, n); - restore_flags(flags); + pr_debug("%s: set page to %#x\n",adapter[card]->devicename, + ((adapter[card]->shmem_magic + ch * SRAM_PAGESIZE)>>14)|0x80); + spin_unlock_irqrestore(&adapter[card]->lock, flags); return ret; } diff -Nru a/drivers/isdn/sc/timer.c b/drivers/isdn/sc/timer.c --- a/drivers/isdn/sc/timer.c Thu Sep 4 15:38:43 2003 +++ b/drivers/isdn/sc/timer.c Thu Sep 4 15:38:43 2003 @@ -62,8 +62,7 @@ /* Setup the io ports */ setup_ports(card); - save_flags(flags); - cli(); + spin_lock_irqsave(&adapter[card]->lock, flags); outb(adapter[card]->ioport[adapter[card]->shmem_pgport], (adapter[card]->shmem_magic>>14) | 0x80); sig = (unsigned long) *((unsigned long *)(adapter[card]->rambase + SIG_OFFSET)); @@ -71,18 +70,16 @@ /* check the signature */ if(sig == SIGNATURE) { flushreadfifo(card); - restore_flags(flags); + spin_unlock_irqrestore(&adapter[card]->lock, flags); /* See if we need to do a startproc */ if (adapter[card]->StartOnReset) startproc(card); - } - else { + } else { pr_debug("%s: No signature yet, waiting another %d jiffies.\n", adapter[card]->devicename, CHECKRESET_TIME); mod_timer(&adapter[card]->reset_timer, jiffies+CHECKRESET_TIME); + spin_unlock_irqrestore(&adapter[card]->lock, flags); } - restore_flags(flags); - } /* @@ -122,10 +119,9 @@ adapter[card]->phystat = adapter[card]->nphystat; /* Reinitialize the timer */ - save_flags(flags); - cli(); + spin_lock_irqsave(&adapter[card]->lock, flags); mod_timer(&adapter[card]->stat_timer, jiffies+CHECKSTAT_TIME); - restore_flags(flags); + spin_unlock_irqrestore(&adapter[card]->lock, flags); /* Send a new cePhyStatus message */ sendmessage(card, CEPID,ceReqTypePhy,ceReqClass2, @@ -146,11 +142,5 @@ */ void trace_timer(unsigned long data) { - unsigned long flags; - - /* - * Disable interrupts and swap the first page - */ - save_flags(flags); - cli(); + /* not implemented */ } diff -Nru a/drivers/macintosh/adb.c b/drivers/macintosh/adb.c --- a/drivers/macintosh/adb.c Thu Sep 4 15:38:48 2003 +++ b/drivers/macintosh/adb.c Thu Sep 4 15:38:48 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 Thu Sep 4 15:38:32 2003 +++ b/drivers/macintosh/macio_asic.c Thu Sep 4 15:38:32 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 Thu Sep 4 15:38:30 2003 +++ b/drivers/macintosh/mediabay.c Thu Sep 4 15:38:30 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 Thu Sep 4 15:38:44 2003 +++ b/drivers/macintosh/via-pmu.c Thu Sep 4 15:38:44 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) +{ + 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; + 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; +} + +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) { - 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_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; - case PBOOK_WAKE: - (void) pm_send_all(PM_RESUME, (void *)0); + 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 PBOOK_SLEEP_OK; + return -1; } -#endif /* CONFIG_PM */ + +#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 Thu Sep 4 15:38:31 2003 +++ b/drivers/md/md.c Thu Sep 4 15:38:31 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 Thu Sep 4 15:38:35 2003 +++ b/drivers/md/raid0.c Thu Sep 4 15:38:35 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 Thu Sep 4 15:38:30 2003 +++ b/drivers/md/raid5.c Thu Sep 4 15:38:30 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 Thu Sep 4 15:38:34 2003 +++ b/drivers/md/xor.c Thu Sep 4 15:38:34 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 Thu Sep 4 15:38:34 2003 +++ b/drivers/media/common/saa7146_fops.c Thu Sep 4 15:38:34 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 Thu Sep 4 15:38:38 2003 +++ b/drivers/media/common/saa7146_video.c Thu Sep 4 15:38:38 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 Thu Sep 4 15:38:30 2003 +++ b/drivers/media/dvb/dvb-core/dvbdev.c Thu Sep 4 15:38:30 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 Thu Sep 4 15:38:30 2003 +++ b/drivers/media/dvb/frontends/grundig_29504-401.c Thu Sep 4 15:38:30 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 Thu Sep 4 15:38:34 2003 +++ b/drivers/media/dvb/frontends/ves1820.c Thu Sep 4 15:38:34 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 Thu Sep 4 15:38:47 2003 +++ b/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c Thu Sep 4 15:38:47 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 Thu Sep 4 15:38:45 2003 +++ b/drivers/media/dvb/ttusb-dec/dec2000_frontend.c Thu Sep 4 15:38:45 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 Thu Sep 4 15:38:44 2003 +++ b/drivers/media/dvb/ttusb-dec/ttusb_dec.c Thu Sep 4 15:38:44 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 Thu Sep 4 15:38:45 2003 +++ b/drivers/media/video/Kconfig Thu Sep 4 15:38:45 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 Thu Sep 4 15:38:45 2003 +++ b/drivers/media/video/adv7170.c Thu Sep 4 15:38:45 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 Thu Sep 4 15:38:44 2003 +++ b/drivers/media/video/adv7175.c Thu Sep 4 15:38:44 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 Thu Sep 4 15:38:29 2003 +++ b/drivers/media/video/bt819.c Thu Sep 4 15:38:29 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 Thu Sep 4 15:38:28 2003 +++ b/drivers/media/video/bt856.c Thu Sep 4 15:38:28 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 Thu Sep 4 15:38:41 2003 +++ b/drivers/media/video/bttv-driver.c Thu Sep 4 15:38:41 2003 @@ -115,6 +115,7 @@ MODULE_DESCRIPTION("bttv - v4l/v4l2 driver module for bt848/878 based cards"); MODULE_AUTHOR("Ralph Metzler & Marcus Metzler & Gerd Knorr"); MODULE_LICENSE("GPL"); +MODULE_ALIAS_CHARDEV_MAJOR(VIDEO_MAJOR); /* kernel args */ #ifndef MODULE @@ -2758,7 +2759,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 +2895,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 Thu Sep 4 15:38:37 2003 +++ b/drivers/media/video/meye.c Thu Sep 4 15:38:37 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 Thu Sep 4 15:38:35 2003 +++ b/drivers/media/video/meye.h Thu Sep 4 15:38:35 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 Thu Sep 4 15:38:42 2003 +++ b/drivers/media/video/planb.c Thu Sep 4 15:38:42 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 Thu Sep 4 15:38:28 2003 +++ b/drivers/media/video/saa7110.c Thu Sep 4 15:38:28 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 Thu Sep 4 15:38:32 2003 +++ b/drivers/media/video/saa7111.c Thu Sep 4 15:38:32 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 Thu Sep 4 15:38:43 2003 +++ b/drivers/media/video/saa7114.c Thu Sep 4 15:38:43 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 Thu Sep 4 15:38:33 2003 +++ b/drivers/media/video/saa7134/saa7134-oss.c Thu Sep 4 15:38:33 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 Thu Sep 4 15:38:28 2003 +++ b/drivers/media/video/saa7134/saa7134-ts.c Thu Sep 4 15:38:28 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 Thu Sep 4 15:38:30 2003 +++ b/drivers/media/video/saa7134/saa7134-video.c Thu Sep 4 15:38:30 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 Thu Sep 4 15:38:29 2003 +++ b/drivers/media/video/saa7185.c Thu Sep 4 15:38:29 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 Thu Sep 4 15:38:44 2003 +++ b/drivers/media/video/stradis.c Thu Sep 4 15:38:44 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 Thu Sep 4 15:38:44 2003 +++ b/drivers/media/video/tvmixer.c Thu Sep 4 15:38:44 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 Thu Sep 4 15:38:30 2003 +++ b/drivers/media/video/videodev.c Thu Sep 4 15:38:30 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 Thu Sep 4 15:38:37 2003 +++ b/drivers/media/video/vpx3220.c Thu Sep 4 15:38:37 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 Thu Sep 4 15:38:40 2003 +++ b/drivers/media/video/zoran.h Thu Sep 4 15:38:40 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 Thu Sep 4 15:38:35 2003 +++ b/drivers/media/video/zoran_card.c Thu Sep 4 15:38:35 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 Thu Sep 4 15:38:43 2003 +++ b/drivers/media/video/zoran_card.h Thu Sep 4 15:38:43 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 Thu Sep 4 15:38:35 2003 +++ b/drivers/media/video/zoran_device.c Thu Sep 4 15:38:35 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 Thu Sep 4 15:38:40 2003 +++ b/drivers/media/video/zoran_driver.c Thu Sep 4 15:38:40 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 Thu Sep 4 15:38:43 2003 +++ b/drivers/media/video/zoran_procfs.c Thu Sep 4 15:38:43 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/message/fusion/mptscsih.c b/drivers/message/fusion/mptscsih.c --- a/drivers/message/fusion/mptscsih.c Thu Sep 4 15:38:32 2003 +++ b/drivers/message/fusion/mptscsih.c Thu Sep 4 15:38:32 2003 @@ -475,6 +475,8 @@ (struct scatterlist *) SCpnt->request_buffer, SCpnt->use_sg, scsi_to_pci_dma_dir(SCpnt->sc_data_direction)); + if (sges_left == 0) + return FAILED; } else if (SCpnt->request_bufflen) { dma_addr_t buf_dma_addr; scPrivate *my_priv; @@ -3328,9 +3330,8 @@ device, device->id, device->lun, device->channel)); dsprintk((KERN_INFO "sdtr %d wdtr %d ppr %d inq length=%d\n", device->sdtr, device->wdtr, device->ppr, device->inquiry_len)); - dsprintk(("tagged %d queue %d simple %d ordered %d\n", - device->tagged_supported, device->tagged_queue, - device->simple_tags, device->ordered_tags)); + dsprintk(("tagged %d simple %d ordered %d\n", + device->tagged_supported, device->simple_tags, device->ordered_tags)); /* set target parameters, queue depths, set dv flags ? */ if (hd && (hd->Targets != NULL)) { diff -Nru a/drivers/mtd/devices/Kconfig b/drivers/mtd/devices/Kconfig --- a/drivers/mtd/devices/Kconfig Thu Sep 4 15:38:32 2003 +++ b/drivers/mtd/devices/Kconfig Thu Sep 4 15:38:32 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 Thu Sep 4 15:38:32 2003 +++ b/drivers/mtd/maps/ceiva.c Thu Sep 4 15:38:32 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 Thu Sep 4 15:38:30 2003 +++ b/drivers/mtd/maps/pcmciamtd.c Thu Sep 4 15:38:30 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 Thu Sep 4 15:38:39 2003 +++ b/drivers/mtd/mtdchar.c Thu Sep 4 15:38:39 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 Thu Sep 4 15:38:30 2003 +++ b/drivers/mtd/nand/autcpu12.c Thu Sep 4 15:38:30 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 Thu Sep 4 15:38:47 2003 +++ b/drivers/mtd/nand/edb7312.c Thu Sep 4 15:38:47 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 Thu Sep 4 15:38:28 2003 +++ b/drivers/net/3c501.c Thu Sep 4 15:38:28 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 Thu Sep 4 15:38:32 2003 +++ b/drivers/net/3c501.h Thu Sep 4 15:38:32 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 Thu Sep 4 15:38:40 2003 +++ b/drivers/net/3c503.c Thu Sep 4 15:38:40 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 Thu Sep 4 15:38:48 2003 +++ b/drivers/net/3c505.c Thu Sep 4 15:38:48 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 Thu Sep 4 15:38:42 2003 +++ b/drivers/net/3c507.c Thu Sep 4 15:38:42 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 Thu Sep 4 15:38:29 2003 +++ b/drivers/net/3c509.c Thu Sep 4 15:38:29 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,13 +599,12 @@ return 0; out1: - release_region(ioaddr, EL3_IO_EXTENT); #if defined(__ISAPNP__) && !defined(CONFIG_X86_PC9800) if (idev) pnp_device_detach(idev); #endif out: - kfree(dev); + free_netdev(dev); return err; } @@ -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 Thu Sep 4 15:38:30 2003 +++ b/drivers/net/3c515.c Thu Sep 4 15:38:30 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 Thu Sep 4 15:38:33 2003 +++ b/drivers/net/3c523.c Thu Sep 4 15:38:33 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 Thu Sep 4 15:38:35 2003 +++ b/drivers/net/3c527.c Thu Sep 4 15:38:35 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 Thu Sep 4 15:38:28 2003 +++ b/drivers/net/3c59x.c Thu Sep 4 15:38:28 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; @@ -1466,7 +1468,7 @@ free_region: if (vp->must_free_region) release_region(ioaddr, vci->io_size); - kfree (dev); + free_netdev(dev); printk(KERN_ERR PFX "vortex_probe1 fails. Returns %d\n", retval); out: return retval; @@ -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 Thu Sep 4 15:38:33 2003 +++ b/drivers/net/8139cp.c Thu Sep 4 15:38:33 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,14 +1763,16 @@ 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: - kfree(dev); + free_netdev(dev); 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 Thu Sep 4 15:38:28 2003 +++ b/drivers/net/8139too.c Thu Sep 4 15:38:28 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 Thu Sep 4 15:38:29 2003 +++ b/drivers/net/8390.c Thu Sep 4 15:38:30 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 Thu Sep 4 15:38:40 2003 +++ b/drivers/net/8390.h Thu Sep 4 15:38:40 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 Thu Sep 4 15:38:43 2003 +++ b/drivers/net/Kconfig Thu Sep 4 15:38:43 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/Makefile.lib b/drivers/net/Makefile.lib --- a/drivers/net/Makefile.lib Thu Sep 4 15:38:43 2003 +++ b/drivers/net/Makefile.lib Thu Sep 4 15:38:43 2003 @@ -5,6 +5,7 @@ obj-$(CONFIG_ARM_AM79C961A) += crc32.o obj-$(CONFIG_AT1700) += crc32.o obj-$(CONFIG_ATP) += crc32.o +obj-$(CONFIG_BMAC) += crc32.o obj-$(CONFIG_DE2104X) += crc32.o obj-$(CONFIG_DE4X5) += crc32.o obj-$(CONFIG_DECLANCE) += crc32.o diff -Nru a/drivers/net/Space.c b/drivers/net/Space.c --- a/drivers/net/Space.c Thu Sep 4 15:38:29 2003 +++ b/drivers/net/Space.c Thu Sep 4 15:38:29 2003 @@ -32,14 +32,13 @@ */ #include #include +#include +#include #include #include #include #include -#define NEXT_DEV NULL - - /* A unified ethernet device probe. This is the easiest way to have every ethernet adaptor have the name "eth[0123...]". */ @@ -62,7 +61,6 @@ extern int depca_probe(struct net_device *); extern int i82596_probe(struct net_device *); extern int ewrk3_probe(struct net_device *); -extern int de4x5_probe(struct net_device *); extern int el1_probe(struct net_device *); extern int wavelan_probe(struct net_device *); extern int arlan_probe(struct net_device *); @@ -89,7 +87,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); @@ -100,6 +97,15 @@ extern int mac8390_probe(struct net_device *dev); extern int mac89x0_probe(struct net_device *dev); extern int mc32_probe(struct net_device *dev); +#ifdef CONFIG_SDLA +extern struct net_device *sdla_init(void); +#endif +#ifdef CONFIG_COPS +extern struct net_device *cops_probe(int unit); +#endif +#ifdef CONFIG_LTPC +extern struct net_device *ltpc_probe(void); +#endif /* Detachable devices ("pocket adaptors") */ extern int de620_probe(struct net_device *); @@ -108,7 +114,7 @@ extern int iph5526_probe(struct net_device *dev); /* SBNI adapters */ -extern int sbni_probe(struct net_device *); +extern int sbni_probe(void); struct devprobe { @@ -153,12 +159,9 @@ * This is a bit of an artificial separation as there are PCI drivers * that also probe for EISA cards (in the PCI group) and there are ISA * drivers that probe for EISA cards (in the ISA group). These are the - * EISA only driver probes, and also the legacy PCI probes + * legacy EISA only driver probes, and also the legacy PCI probes */ static struct devprobe eisa_probes[] __initdata = { -#ifdef CONFIG_DE4X5 /* DEC DE425, DE434, DE435 adapters */ - {de4x5_probe, 0}, -#endif #ifdef CONFIG_ULTRA32 {ultra32_probe, 0}, #endif @@ -357,135 +360,43 @@ * per bus interface. This drives the legacy devices only for now. */ -static int __init ethif_probe(struct net_device *dev) +static int __init ethif_probe(void) { - unsigned long base_addr = dev->base_addr; + struct net_device *dev; + int err = -ENODEV; + + dev = alloc_etherdev(0); + if (!dev) + return -ENOMEM; + + netdev_boot_setup_check(dev); /* * Backwards compatibility - historically an I/O base of 1 was * used to indicate not to probe for this ethN interface */ - if (base_addr == 1) - return 1; /* ENXIO */ + if (dev->base_addr == 1) { + free_netdev(dev); + return -ENXIO; + } /* * The arch specific probes are 1st so that any on-board ethernet * will be probed before other ISA/EISA/MCA/PCI bus cards. */ - if (probe_list(dev, m68k_probes) == 0) - return 0; - if (probe_list(dev, mips_probes) == 0) - return 0; - if (probe_list(dev, eisa_probes) == 0) - return 0; - if (probe_list(dev, mca_probes) == 0) - return 0; - if (probe_list(dev, isa_probes) == 0) - return 0; - if (probe_list(dev, parport_probes) == 0) - 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 *); -static struct net_device sdla0_dev = { - .name = "sdla0", - .next = NEXT_DEV, - .init = sdla_init, -}; -#undef NEXT_DEV -#define NEXT_DEV (&sdla0_dev) -#endif - -#if defined(CONFIG_LTPC) -extern int ltpc_probe(struct net_device *); -static struct net_device dev_ltpc = { - .name = "lt0", - .next = NEXT_DEV, - .init = ltpc_probe -}; -#undef NEXT_DEV -#define NEXT_DEV (&dev_ltpc) -#endif /* LTPC */ - -#if defined(CONFIG_COPS) -extern int cops_probe(struct net_device *); -static struct net_device cops2_dev = { - .name = "lt2", - .next = NEXT_DEV, - .init = cops_probe, -}; -static struct net_device cops1_dev = { - .name = "lt1", - .next = &cops2_dev, - .init = cops_probe, -}; -static struct net_device cops0_dev = { - .name = "lt0", - .next = &cops1_dev, - .init = cops_probe, -}; -#undef NEXT_DEV -#define NEXT_DEV (&cops0_dev) -#endif /* COPS */ - -static struct net_device eth7_dev = { - .name = "eth%d", - .next = NEXT_DEV, - .init = ethif_probe, -}; -static struct net_device eth6_dev = { - .name = "eth%d", - .next = ð7_dev, - .init = ethif_probe, -}; -static struct net_device eth5_dev = { - .name = "eth%d", - .next = ð6_dev, - .init = ethif_probe, -}; -static struct net_device eth4_dev = { - .name = "eth%d", - .next = ð5_dev, - .init = ethif_probe, -}; -static struct net_device eth3_dev = { - .name = "eth%d", - .next = ð4_dev, - .init = ethif_probe, -}; -static struct net_device eth2_dev = { - .name = "eth%d", - .next = ð3_dev, - .init = ethif_probe, -}; -static struct net_device eth1_dev = { - .name = "eth%d", - .next = ð2_dev, - .init = ethif_probe, -}; -static struct net_device eth0_dev = { - .name = "eth%d", - .next = ð1_dev, - .init = ethif_probe, -}; - -#undef NEXT_DEV -#define NEXT_DEV (ð0_dev) - + if (probe_list(dev, m68k_probes) == 0 || + probe_list(dev, mips_probes) == 0 || + probe_list(dev, eisa_probes) == 0 || + probe_list(dev, mca_probes) == 0 || + probe_list(dev, isa_probes) == 0 || + probe_list(dev, parport_probes) == 0) + err = register_netdev(dev); + + if (err) + free_netdev(dev); + return err; +} #ifdef CONFIG_TR /* Token-ring device probe */ @@ -494,129 +405,82 @@ extern int proteon_probe(struct net_device *); extern int smctr_probe(struct net_device *); -static int -trif_probe(struct net_device *dev) +static __init int trif_probe(void) { - if (1 + struct net_device *dev; + int err = -ENODEV; + + dev = alloc_trdev(0); + if (!dev) + return -ENOMEM; + + netdev_boot_setup_check(dev); + if ( #ifdef CONFIG_IBMTR - && ibmtr_probe(dev) + ibmtr_probe(dev) == 0 || #endif #ifdef CONFIG_SKISA - && sk_isa_probe(dev) + sk_isa_probe(dev) == 0 || #endif #ifdef CONFIG_PROTEON - && proteon_probe(dev) + proteon_probe(dev) == 0 || #endif #ifdef CONFIG_SMCTR - && smctr_probe(dev) + smctr_probe(dev) == 0 || #endif - && 1 ) { - return 1; /* -ENODEV or -EAGAIN would be more accurate. */ - } - return 0; -} -static struct net_device tr7_dev = { - .name = "tr%d", - .next = NEXT_DEV, - .init = trif_probe, -}; -static struct net_device tr6_dev = { - .name = "tr%d", - .next = &tr7_dev, - .init = trif_probe, -}; -static struct net_device tr5_dev = { - .name = "tr%d", - .next = &tr6_dev, - .init = trif_probe, -}; -static struct net_device tr4_dev = { - .name = "tr%d", - .next = &tr5_dev, - .init = trif_probe, -}; -static struct net_device tr3_dev = { - .name = "tr%d", - .next = &tr4_dev, - .init = trif_probe, -}; -static struct net_device tr2_dev = { - .name = "tr%d", - .next = &tr3_dev, - .init = trif_probe, -}; -static struct net_device tr1_dev = { - .name = "tr%d", - .next = &tr2_dev, - .init = trif_probe, -}; -static struct net_device tr0_dev = { - .name = "tr%d", - .next = &tr1_dev, - .init = trif_probe, -}; -#undef NEXT_DEV -#define NEXT_DEV (&tr0_dev) + 0 ) + err = register_netdev(dev); + + if (err) + free_netdev(dev); + return err; -#endif - -#ifdef CONFIG_SBNI -static struct net_device sbni7_dev = { - .name = "sbni7", - .next = NEXT_DEV, - .init = sbni_probe, -}; -static struct net_device sbni6_dev = { - .name = "sbni6", - .next = &sbni7_dev, - .init = sbni_probe, -}; -static struct net_device sbni5_dev = { - .name = "sbni5", - .next = &sbni6_dev, - .init = sbni_probe, -}; -static struct net_device sbni4_dev = { - .name = "sbni4", - .next = &sbni5_dev, - .init = sbni_probe, -}; -static struct net_device sbni3_dev = { - .name = "sbni3", - .next = &sbni4_dev, - .init = sbni_probe, -}; -static struct net_device sbni2_dev = { - .name = "sbni2", - .next = &sbni3_dev, - .init = sbni_probe, -}; -static struct net_device sbni1_dev = { - .name = "sbni1", - .next = &sbni2_dev, - .init = sbni_probe, -}; -static struct net_device sbni0_dev = { - .name = "sbni0", - .next = &sbni1_dev, - .init = sbni_probe, -}; +} +#endif -#undef NEXT_DEV -#define NEXT_DEV (&sbni0_dev) -#endif /* * The loopback device is global so it can be directly referenced * by the network code. Also, it must be first on device list. */ +extern int loopback_init(void); -extern int loopback_init(struct net_device *dev); -struct net_device loopback_dev = { - .name = "lo", - .next = NEXT_DEV, - .init = loopback_init -}; +/* Statically configured drivers -- order matters here. */ +void __init probe_old_netdevs(void) +{ + int num; + + if (loopback_init()) { + printk(KERN_ERR "Network loopback device setup failed\n"); + } + + +#ifdef CONFIG_SBNI + for (num = 0; num < 8; ++num) + if (sbni_probe()) + break; +#endif +#ifdef CONFIG_TR + for (num = 0; num < 8; ++num) + if (trif_probe()) + break; +#endif + for (num = 0; num < 8; ++num) + if (ethif_probe()) + break; +#ifdef CONFIG_COPS + cops_probe(0); + cops_probe(1); + cops_probe(2); +#endif +#ifdef CONFIG_LTPC + ltpc_probe(); +#endif +#ifdef CONFIG_SDLA + sdla_init(); +#endif + +} /* * The @dev_base list is protected by @dev_base_lock and the rtln @@ -637,6 +501,6 @@ * unregister_netdevice(), which must be called with the rtnl * semaphore held. */ -struct net_device *dev_base = &loopback_dev; +struct net_device *dev_base; rwlock_t dev_base_lock = RW_LOCK_UNLOCKED; diff -Nru a/drivers/net/acenic.c b/drivers/net/acenic.c --- a/drivers/net/acenic.c Thu Sep 4 15:38:33 2003 +++ b/drivers/net/acenic.c Thu Sep 4 15:38:33 2003 @@ -685,7 +685,7 @@ } if (pci_enable_device(pdev)) { - kfree(dev); + free_netdev(dev); continue; } @@ -733,7 +733,7 @@ if (register_netdev(dev)) { printk(KERN_ERR "acenic: device registration failed\n"); - kfree(dev); + free_netdev(dev); continue; } @@ -793,7 +793,7 @@ printk(KERN_ERR "%s: Driver compiled without Tigon I" " support - NIC disabled\n", dev->name); ace_init_cleanup(dev); - kfree(dev); + free_netdev(dev); continue; } #endif @@ -803,7 +803,7 @@ * ace_allocate_descriptors() calls * ace_init_cleanup() on error. */ - kfree(dev); + free_netdev(dev); continue; } @@ -820,7 +820,7 @@ /* * ace_init() calls ace_init_cleanup() on error. */ - kfree(dev); + free_netdev(dev); continue; } diff -Nru a/drivers/net/amd8111e.c b/drivers/net/amd8111e.c --- a/drivers/net/amd8111e.c Thu Sep 4 15:38:36 2003 +++ b/drivers/net/amd8111e.c Thu Sep 4 15:38:36 2003 @@ -1927,7 +1927,7 @@ iounmap((void *) lp->mmio); err_free_dev: - kfree(dev); + free_netdev(dev); err_free_reg: pci_release_regions(pdev); diff -Nru a/drivers/net/appletalk/cops.c b/drivers/net/appletalk/cops.c --- a/drivers/net/appletalk/cops.c Thu Sep 4 15:38:34 2003 +++ b/drivers/net/appletalk/cops.c Thu Sep 4 15:38:34 2003 @@ -92,12 +92,8 @@ static int board_type = TANGENT; #endif -#ifdef MODULE static int io = 0x240; /* Default IO for Dayna */ static int irq = 5; /* Default IRQ */ -#else -static int io; /* Default IO for Dayna */ -#endif /* * COPS Autoprobe information. @@ -146,7 +142,7 @@ * Zero terminated list of IO ports to probe. */ -static unsigned int cops_portlist[] = { +static unsigned int ports[] = { 0x240, 0x340, 0x200, 0x210, 0x220, 0x230, 0x260, 0x2A0, 0x300, 0x310, 0x320, 0x330, 0x350, 0x360, 0 @@ -184,7 +180,6 @@ }; /* Index to functions, as function prototypes. */ -extern int cops_probe (struct net_device *dev); static int cops_probe1 (struct net_device *dev, int ioaddr); static int cops_irq (int ioaddr, int board); @@ -208,6 +203,12 @@ static int cops_close (struct net_device *dev); static struct net_device_stats *cops_get_stats (struct net_device *dev); +static void cleanup_card(struct net_device *dev) +{ + if (dev->irq) + free_irq(dev->irq, dev); + release_region(dev->base_addr, COPS_IO_EXTENT); +} /* * Check for a network adaptor of this type, and return '0' iff one exists. @@ -215,31 +216,54 @@ * If dev->base_addr in [1..0x1ff], always return failure. * otherwise go with what we pass in. */ -int __init cops_probe(struct net_device *dev) +struct net_device * __init cops_probe(int unit) { - int i; - int base_addr = dev->base_addr; + struct net_device *dev; + unsigned *port; + int base_addr; + int err = 0; + + dev = alloc_netdev(sizeof(struct cops_local), "lt%d", ltalk_setup); + if (!dev) + return ERR_PTR(-ENOMEM); + + if (unit >= 0) { + sprintf(dev->name, "lt%d", unit); + netdev_boot_setup_check(dev); + irq = dev->irq; + base_addr = dev->base_addr; + } else { + base_addr = dev->base_addr = io; + } SET_MODULE_OWNER(dev); - if(base_addr == 0 && io) - base_addr=io; - - if(base_addr > 0x1ff) /* Check a single specified location. */ - return cops_probe1(dev, base_addr); - else if(base_addr != 0) /* Don't probe at all. */ - return -ENXIO; - - /* FIXME Does this really work for cards which generate irq? - * It's definitely N.G. for polled Tangent. sh - * Dayna cards don't autoprobe well at all, but if your card is - * at IRQ 5 & IO 0x240 we find it every time. ;) JS - */ - for(i=0; cops_portlist[i]; i++) - if(cops_probe1(dev, cops_portlist[i]) == 0) - return 0; - - return -ENODEV; + if (base_addr > 0x1ff) { /* Check a single specified location. */ + err = cops_probe1(dev, base_addr); + } else if (base_addr != 0) { /* Don't probe at all. */ + err = -ENXIO; + } else { + /* FIXME Does this really work for cards which generate irq? + * It's definitely N.G. for polled Tangent. sh + * Dayna cards don't autoprobe well at all, but if your card is + * at IRQ 5 & IO 0x240 we find it every time. ;) JS + */ + for (port = ports; *port && cops_probe1(dev, *port) < 0; port++) + ; + if (!*port) + err = -ENODEV; + } + if (err) + goto out; + err = register_netdev(dev); + if (err) + goto out1; + return dev; +out1: + cleanup_card(dev); +out: + kfree(dev); + return ERR_PTR(err); } /* @@ -268,16 +292,15 @@ * interrupts are typically not reported by the boards, and we must * used AutoIRQ to find them. */ + dev->irq = irq; switch (dev->irq) { case 0: /* COPS AutoIRQ routine */ dev->irq = cops_irq(ioaddr, board); - if(!dev->irq) { - retval = -EINVAL; /* No IRQ found on this port */ - goto err_out; - } - + if (dev->irq) + break; + /* No IRQ found on this port, fallthrough */ case 1: retval = -EINVAL; goto err_out; @@ -302,22 +325,13 @@ } /* Reserve any actual interrupt. */ - if(dev->irq) { + if (dev->irq) { retval = request_irq(dev->irq, &cops_interrupt, 0, dev->name, dev); if (retval) goto err_out; } - dev->base_addr = ioaddr; - - /* Initialize the private device structure. */ - dev->priv = kmalloc(sizeof(struct cops_local), GFP_KERNEL); - if(dev->priv == NULL) { - if (dev->irq) - free_irq(dev->irq, dev); - retval = -ENOMEM; - goto err_out; - } + dev->base_addr = ioaddr; lp = (struct cops_local *)dev->priv; memset(lp, 0, sizeof(struct cops_local)); @@ -326,9 +340,6 @@ /* Copy local board variable to lp struct. */ lp->board = board; - /* Fill in the fields of the device structure with LocalTalk values. */ - ltalk_setup(dev); - dev->hard_start_xmit = cops_send_packet; dev->tx_timeout = cops_timeout; dev->watchdog_timeo = HZ * 2; @@ -1013,7 +1024,7 @@ } #ifdef MODULE -static struct net_device cops0_dev = { .init = cops_probe }; +static struct net_device *cops_dev; MODULE_LICENSE("GPL"); MODULE_PARM(io, "i"); @@ -1022,33 +1033,20 @@ int init_module(void) { - int result, err; - - if(io == 0) + if (io == 0) printk(KERN_WARNING "%s: You shouldn't autoprobe with insmod\n", cardname); - - /* Copy the parameters from insmod into the device structure. */ - cops0_dev.base_addr = io; - cops0_dev.irq = irq; - - err=dev_alloc_name(&cops0_dev, "lt%d"); - if(err < 0) - return err; - - if((result = register_netdev(&cops0_dev)) != 0) - return result; - + cops_dev = cops_probe(-1); + if (IS_ERR(cops_dev)) + return PTR_ERR(cops_dev); return 0; } void cleanup_module(void) { - unregister_netdev(&cops0_dev); - kfree(cops0_dev.priv); - if(cops0_dev.irq) - free_irq(cops0_dev.irq, &cops0_dev); - release_region(cops0_dev.base_addr, COPS_IO_EXTENT); + unregister_netdev(cops_dev); + cleanup_card(cops_dev); + free_netdev(cops_dev); } #endif /* MODULE */ diff -Nru a/drivers/net/appletalk/ltpc.c b/drivers/net/appletalk/ltpc.c --- a/drivers/net/appletalk/ltpc.c Thu Sep 4 15:38:31 2003 +++ b/drivers/net/appletalk/ltpc.c Thu Sep 4 15:38:31 2003 @@ -879,34 +879,6 @@ return 0; } -static int ltpc_init(struct net_device *dev) -{ - /* Initialize the device structure. */ - - /* Fill in the fields of the device structure with ethernet-generic values. */ - ltalk_setup(dev); - dev->hard_start_xmit = ltpc_xmit; - dev->hard_header = ltpc_hard_header; - - dev->priv = kmalloc(sizeof(struct ltpc_private), GFP_KERNEL); - if(!dev->priv) - { - printk(KERN_INFO "%s: could not allocate statistics buffer\n", dev->name); - return -ENOMEM; - } - - memset(dev->priv, 0, sizeof(struct ltpc_private)); - dev->get_stats = ltpc_get_stats; - - /* add the ltpc-specific things */ - dev->do_ioctl = <pc_ioctl; - - dev->set_multicast_list = &set_multicast_list; - dev->mc_list = NULL; - - return 0; -} - static int ltpc_poll_counter; static void ltpc_poll(unsigned long l) @@ -983,35 +955,40 @@ /* initialization stuff */ -static int __init ltpc_probe_dma(int base) +static int __init ltpc_probe_dma(int base, int dma) { - int dma = 0; + int want = (dma == 3) ? 2 : (dma == 1) ? 1 : 3; unsigned long timeout; unsigned long f; - if (!request_dma(1,"ltpc")) { - f=claim_dma_lock(); - disable_dma(1); - clear_dma_ff(1); - set_dma_mode(1,DMA_MODE_WRITE); - set_dma_addr(1,virt_to_bus(ltdmabuf)); - set_dma_count(1,sizeof(struct lt_mem)); - enable_dma(1); - release_dma_lock(f); - dma|=1; - } - if (!request_dma(3,"ltpc")) { - f=claim_dma_lock(); - disable_dma(3); - clear_dma_ff(3); - set_dma_mode(3,DMA_MODE_WRITE); - set_dma_addr(3,virt_to_bus(ltdmabuf)); - set_dma_count(3,sizeof(struct lt_mem)); - enable_dma(3); - release_dma_lock(f); - dma|=2; + if (want & 1) { + if (request_dma(1,"ltpc")) { + want &= ~1; + } else { + f=claim_dma_lock(); + disable_dma(1); + clear_dma_ff(1); + set_dma_mode(1,DMA_MODE_WRITE); + set_dma_addr(1,virt_to_bus(ltdmabuf)); + set_dma_count(1,sizeof(struct lt_mem)); + enable_dma(1); + release_dma_lock(f); + } + } + if (want & 2) { + if (request_dma(3,"ltpc")) { + want &= ~2; + } else { + f=claim_dma_lock(); + disable_dma(3); + clear_dma_ff(3); + set_dma_mode(3,DMA_MODE_WRITE); + set_dma_addr(3,virt_to_bus(ltdmabuf)); + set_dma_count(3,sizeof(struct lt_mem)); + enable_dma(3); + release_dma_lock(f); + } } - /* set up request */ /* FIXME -- do timings better! */ @@ -1037,65 +1014,62 @@ /* release the other dma channel (if we opened both of them) */ - if ( (dma&0x2) && (get_dma_residue(3)==sizeof(struct lt_mem)) ){ - dma&=1; + if ((want & 2) && (get_dma_residue(3)==sizeof(struct lt_mem))) { + want &= ~2; free_dma(3); } - - if ( (dma&0x1) && (get_dma_residue(1)==sizeof(struct lt_mem)) ){ - dma&=0x2; + + if ((want & 1) && (get_dma_residue(1)==sizeof(struct lt_mem))) { + want &= ~1; free_dma(1); } - /* fix up dma number */ - dma|=1; + if (!want) + return 0; - return dma; + return (want & 2) ? 3 : 1; } -int __init ltpc_probe(struct net_device *dev) +struct net_device * __init ltpc_probe(void) { - int err; + struct net_device *dev; + int err = -ENOMEM; int x=0,y=0; int autoirq; unsigned long f; - int portfound=0; unsigned long timeout; + dev = alloc_netdev(sizeof(struct ltpc_private), "lt%d", ltalk_setup); + if (!dev) + goto out; + SET_MODULE_OWNER(dev); /* probe for the I/O port address */ + if (io != 0x240 && request_region(0x220,8,"ltpc")) { x = inb_p(0x220+6); if ( (x!=0xff) && (x>=0xf0) ) { io = 0x220; - portfound=1; - } - else { - release_region(0x220,8); + goto got_port; } + release_region(0x220,8); } - if (io != 0x220 && request_region(0x240,8,"ltpc")) { y = inb_p(0x240+6); if ( (y!=0xff) && (y>=0xf0) ){ io = 0x240; - portfound=1; - } - else { - release_region(0x240,8); + goto got_port; } + release_region(0x240,8); } - if(io && !portfound && request_region(io,8,"ltpc")){ - portfound = 1; - } - if(!portfound) { - /* give up in despair */ - printk(KERN_ERR "LocalTalk card not found; 220 = %02x, 240 = %02x.\n", x,y); - return -1; - } + /* give up in despair */ + printk(KERN_ERR "LocalTalk card not found; 220 = %02x, 240 = %02x.\n", x,y); + err = -ENODEV; + goto out1; + got_port: /* probe for the IRQ line */ if (irq < 2) { unsigned long irq_mask; @@ -1111,22 +1085,21 @@ if (autoirq == 0) { printk(KERN_ERR "ltpc: probe at %#x failed to detect IRQ line.\n", io); - } - else { + } else { irq = autoirq; } } /* allocate a DMA buffer */ ltdmabuf = (unsigned char *) dma_mem_alloc(1000); - - if (ltdmabuf) ltdmacbuf = <dmabuf[800]; - if (!ltdmabuf) { printk(KERN_ERR "ltpc: mem alloc failed\n"); - return -1; + err = -ENOMEM; + goto out2; } + ltdmacbuf = <dmabuf[800]; + if(debug & DEBUG_VERBOSE) { printk("ltdmabuf pointer %08lx\n",(unsigned long) ltdmabuf); } @@ -1154,25 +1127,29 @@ already been specified */ /* well, 0 is a legal DMA channel, but the LTPC card doesn't use it... */ - if (dma == 0) { - dma = ltpc_probe_dma(io); - if (!dma) { /* no dma channel */ - printk(KERN_ERR "No DMA channel found on ltpc card.\n"); - return -1; - } + dma = ltpc_probe_dma(io, dma); + if (!dma) { /* no dma channel */ + printk(KERN_ERR "No DMA channel found on ltpc card.\n"); + err = -ENODEV; + goto out3; } /* print out friendly message */ - if(irq) printk(KERN_INFO "Apple/Farallon LocalTalk-PC card at %03x, IR%d, DMA%d.\n",io,irq,dma); else printk(KERN_INFO "Apple/Farallon LocalTalk-PC card at %03x, DMA%d. Using polled mode.\n",io,dma); - /* seems more logical to do this *after* probing the card... */ - err = ltpc_init(dev); - if (err) return err; + /* Fill in the fields of the device structure with ethernet-generic values. */ + dev->hard_start_xmit = ltpc_xmit; + dev->hard_header = ltpc_hard_header; + dev->get_stats = ltpc_get_stats; + /* add the ltpc-specific things */ + dev->do_ioctl = <pc_ioctl; + + dev->set_multicast_list = &set_multicast_list; + dev->mc_list = NULL; dev->base_addr = io; dev->irq = irq; dev->dma = dma; @@ -1212,6 +1189,7 @@ } else { if( irq ) printk(KERN_ERR "ltpc: IRQ already in use, using polled mode.\n"); + dev->irq = 0; /* polled mode -- 20 times per second */ /* this is really, really slow... should it poll more often? */ init_timer(<pc_timer); @@ -1221,8 +1199,23 @@ ltpc_timer.expires = jiffies + HZ/20; add_timer(<pc_timer); } + err = register_netdev(dev); + if (err) + goto out4; return 0; +out4: + del_timer_sync(<pc_timer); + if (dev->irq) + free_irq(dev->irq, dev); +out3: + free_pages((unsigned long)ltdmabuf, get_order(1000)); +out2: + release_region(io, 8); +out1: + kfree(dev); +out: + return ERR_PTR(err); } #ifndef MODULE @@ -1259,7 +1252,7 @@ __setup("ltpc=", ltpc_setup); #endif /* MODULE */ -static struct net_device dev_ltpc; +static struct net_device *dev_ltpc; #ifdef MODULE @@ -1272,79 +1265,47 @@ int __init init_module(void) { - int err, result; - if(io == 0) printk(KERN_NOTICE "ltpc: Autoprobing is not recommended for modules\n"); - /* Find a name for this unit */ - dev_ltpc.init = ltpc_probe; - err=dev_alloc_name(&dev_ltpc,"lt%d"); - - if(err<0) - return err; - - if ((result = register_netdev(&dev_ltpc)) != 0) { - printk(KERN_DEBUG "could not register Localtalk-PC device\n"); - return result; - } else { - if(debug & DEBUG_VERBOSE) printk("0 from register_netdev\n"); - return 0; - } + dev_ltpc = ltpc_probe(); + if (IS_ERR(dev_ltpc)) + return PTR_ERR(dev_ltpc); + return 0; } #endif static void __exit ltpc_cleanup(void) { - unsigned long timeout; + + if(debug & DEBUG_VERBOSE) printk("unregister_netdev\n"); + unregister_netdev(dev_ltpc); ltpc_timer.data = 0; /* signal the poll routine that we're done */ - if(debug & DEBUG_VERBOSE) printk("freeing irq\n"); + del_timer_sync(<pc_timer); - if(dev_ltpc.irq) { - free_irq(dev_ltpc.irq,&dev_ltpc); - dev_ltpc.irq = 0; - } + if(debug & DEBUG_VERBOSE) printk("freeing irq\n"); - if(del_timer(<pc_timer)) - { - /* either the poll was never started, or a poll is in process */ - if(debug & DEBUG_VERBOSE) printk("waiting\n"); - /* if it's in process, wait a bit for it to finish */ - timeout = jiffies+HZ; - add_timer(<pc_timer); - while(del_timer(<pc_timer) && time_after(timeout, jiffies)) - { - add_timer(<pc_timer); - schedule(); - } - } + if (dev_ltpc->irq) + free_irq(dev_ltpc->irq, dev_ltpc); if(debug & DEBUG_VERBOSE) printk("freeing dma\n"); - if(dev_ltpc.dma) { - free_dma(dev_ltpc.dma); - dev_ltpc.dma = 0; - } + if (dev_ltpc->dma) + free_dma(dev_ltpc->dma); if(debug & DEBUG_VERBOSE) printk("freeing ioaddr\n"); - if(dev_ltpc.base_addr) { - release_region(dev_ltpc.base_addr,8); - dev_ltpc.base_addr = 0; - } + if (dev_ltpc->base_addr) + release_region(dev_ltpc->base_addr,8); + + free_netdev(dev_ltpc); if(debug & DEBUG_VERBOSE) printk("free_pages\n"); free_pages( (unsigned long) ltdmabuf, get_order(1000)); - ltdmabuf=NULL; - ltdmacbuf=NULL; - - if(debug & DEBUG_VERBOSE) printk("unregister_netdev\n"); - - unregister_netdev(&dev_ltpc); if(debug & DEBUG_VERBOSE) printk("returning from cleanup_module\n"); } diff -Nru a/drivers/net/arcnet/arcnet.c b/drivers/net/arcnet/arcnet.c --- a/drivers/net/arcnet/arcnet.c Thu Sep 4 15:38:39 2003 +++ b/drivers/net/arcnet/arcnet.c Thu Sep 4 15:38:39 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 Thu Sep 4 15:38:48 2003 +++ b/drivers/net/arm/ether00.c Thu Sep 4 15:38:48 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/b44.c b/drivers/net/b44.c --- a/drivers/net/b44.c Thu Sep 4 15:38:32 2003 +++ b/drivers/net/b44.c Thu Sep 4 15:38:32 2003 @@ -1834,7 +1834,7 @@ iounmap((void *) bp->regs); err_out_free_dev: - kfree(dev); + free_netdev(dev); err_out_free_res: pci_release_regions(pdev); diff -Nru a/drivers/net/bmac.c b/drivers/net/bmac.c --- a/drivers/net/bmac.c Thu Sep 4 15:38:29 2003 +++ b/drivers/net/bmac.c Thu Sep 4 15:38:29 2003 @@ -1462,7 +1462,7 @@ release_OF_resource(bp->node, 0); out1: pmac_call_feature(PMAC_FTR_BMAC_ENABLE, bp->node, 0, 0); - kfree(dev); + free_netdev(dev); } static int bmac_open(struct net_device *dev) diff -Nru a/drivers/net/dgrs.c b/drivers/net/dgrs.c --- a/drivers/net/dgrs.c Thu Sep 4 15:38:29 2003 +++ b/drivers/net/dgrs.c Thu Sep 4 15:38:29 2003 @@ -1275,7 +1275,7 @@ SET_MODULE_OWNER(dev); if (register_netdev(dev) != 0) { - kfree(dev); + free_netdev(dev); return -EIO; } @@ -1322,7 +1322,7 @@ ret = -EIO; if (register_netdev(devN)) { - kfree(devN); + free_netdev(devN); goto fail; } privN->chan = i+1; diff -Nru a/drivers/net/dl2k.c b/drivers/net/dl2k.c --- a/drivers/net/dl2k.c Thu Sep 4 15:38:32 2003 +++ b/drivers/net/dl2k.c Thu Sep 4 15:38:32 2003 @@ -319,7 +319,7 @@ err_out_dev: #endif - kfree (dev); + free_netdev (dev); err_out_res: pci_release_regions (pdev); diff -Nru a/drivers/net/dummy.c b/drivers/net/dummy.c --- a/drivers/net/dummy.c Thu Sep 4 15:38:33 2003 +++ b/drivers/net/dummy.c Thu Sep 4 15:38:33 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/eepro100.c b/drivers/net/eepro100.c --- a/drivers/net/eepro100.c Thu Sep 4 15:38:38 2003 +++ b/drivers/net/eepro100.c Thu Sep 4 15:38:38 2003 @@ -894,7 +894,7 @@ err_free_unlock: rtnl_unlock(); - kfree(dev); + free_netdev(dev); return -1; } diff -Nru a/drivers/net/epic100.c b/drivers/net/epic100.c --- a/drivers/net/epic100.c Thu Sep 4 15:38:33 2003 +++ b/drivers/net/epic100.c Thu Sep 4 15:38:33 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; @@ -563,7 +565,7 @@ #endif pci_release_regions(pdev); err_out_free_netdev: - kfree(dev); + free_netdev(dev); return -ENODEV; } @@ -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 Thu Sep 4 15:38:43 2003 +++ b/drivers/net/eth16i.c Thu Sep 4 15:38:43 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 Thu Sep 4 15:38:30 2003 +++ b/drivers/net/ethertap.c Thu Sep 4 15:38:30 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 Thu Sep 4 15:38:40 2003 +++ b/drivers/net/fealnx.c Thu Sep 4 15:38:40 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; @@ -687,7 +689,7 @@ err_out_free_rx: pci_free_consistent(pdev, RX_TOTAL_SIZE, np->rx_ring, np->rx_ring_dma); err_out_free_dev: - kfree(dev); + free_netdev(dev); err_out_unmap: #ifndef USE_IO_OPS iounmap((void *)ioaddr); @@ -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 Thu Sep 4 15:38:29 2003 +++ b/drivers/net/fmv18x.c Thu Sep 4 15:38:29 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/hamachi.c b/drivers/net/hamachi.c --- a/drivers/net/hamachi.c Thu Sep 4 15:38:47 2003 +++ b/drivers/net/hamachi.c Thu Sep 4 15:38:47 2003 @@ -785,7 +785,7 @@ pci_free_consistent(pdev, TX_TOTAL_SIZE, hmp->tx_ring, hmp->tx_ring_dma); err_out_cleardev: - kfree (dev); + free_netdev (dev); err_out_iounmap: iounmap((char *)ioaddr); err_out_release: diff -Nru a/drivers/net/hamradio/6pack.c b/drivers/net/hamradio/6pack.c --- a/drivers/net/hamradio/6pack.c Thu Sep 4 15:38:30 2003 +++ b/drivers/net/hamradio/6pack.c Thu Sep 4 15:38:30 2003 @@ -1064,6 +1064,7 @@ MODULE_AUTHOR("Andreas Könsgen "); MODULE_DESCRIPTION("6pack driver for AX.25"); MODULE_LICENSE("GPL"); +MODULE_ALIAS_LDISC(N_6PACK); module_init(sixpack_init_driver); module_exit(sixpack_exit_driver); diff -Nru a/drivers/net/hamradio/Kconfig b/drivers/net/hamradio/Kconfig --- a/drivers/net/hamradio/Kconfig Thu Sep 4 15:38:29 2003 +++ b/drivers/net/hamradio/Kconfig Thu Sep 4 15:38:29 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 Thu Sep 4 15:38:33 2003 +++ b/drivers/net/hamradio/bpqether.c Thu Sep 4 15:38:33 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/mkiss.c b/drivers/net/hamradio/mkiss.c --- a/drivers/net/hamradio/mkiss.c Thu Sep 4 15:38:46 2003 +++ b/drivers/net/hamradio/mkiss.c Thu Sep 4 15:38:46 2003 @@ -935,7 +935,7 @@ MODULE_PARM(ax25_maxdev, "i"); MODULE_PARM_DESC(ax25_maxdev, "number of MKISS devices"); MODULE_LICENSE("GPL"); - +MODULE_ALIAS_LDISC(N_AX25); module_init(mkiss_init_driver); module_exit(mkiss_exit_driver); diff -Nru a/drivers/net/hamradio/yam.c b/drivers/net/hamradio/yam.c --- a/drivers/net/hamradio/yam.c Thu Sep 4 15:38:40 2003 +++ b/drivers/net/hamradio/yam.c Thu Sep 4 15:38:40 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/ioc3-eth.c b/drivers/net/ioc3-eth.c --- a/drivers/net/ioc3-eth.c Thu Sep 4 15:38:29 2003 +++ b/drivers/net/ioc3-eth.c Thu Sep 4 15:38:29 2003 @@ -1512,7 +1512,7 @@ out_res: pci_release_regions(pdev); out_free: - kfree(dev); + free_netdev(dev); return err; } diff -Nru a/drivers/net/irda/Kconfig b/drivers/net/irda/Kconfig --- a/drivers/net/irda/Kconfig Thu Sep 4 15:38:40 2003 +++ b/drivers/net/irda/Kconfig Thu Sep 4 15:38:40 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/irtty-sir.c b/drivers/net/irda/irtty-sir.c --- a/drivers/net/irda/irtty-sir.c Thu Sep 4 15:38:28 2003 +++ b/drivers/net/irda/irtty-sir.c Thu Sep 4 15:38:28 2003 @@ -651,5 +651,6 @@ MODULE_AUTHOR("Dag Brattli "); MODULE_DESCRIPTION("IrDA TTY device driver"); +MODULE_ALIAS_LDISC(N_IRDA); MODULE_LICENSE("GPL"); diff -Nru a/drivers/net/irda/via-ircc.c b/drivers/net/irda/via-ircc.c --- a/drivers/net/irda/via-ircc.c Thu Sep 4 15:38:28 2003 +++ b/drivers/net/irda/via-ircc.c Thu Sep 4 15:38:28 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 Thu Sep 4 15:38:29 2003 +++ b/drivers/net/irda/vlsi_ir.c Thu Sep 4 15:38:29 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 Thu Sep 4 15:38:30 2003 +++ b/drivers/net/ixgb/ixgb_main.c Thu Sep 4 15:38:30 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/lasi_82596.c b/drivers/net/lasi_82596.c --- a/drivers/net/lasi_82596.c Thu Sep 4 15:38:30 2003 +++ b/drivers/net/lasi_82596.c Thu Sep 4 15:38:30 2003 @@ -1543,7 +1543,7 @@ retval = register_netdev(netdevice); if (retval) { printk(KERN_WARNING __FILE__ ": register_netdevice ret'd %d\n", retval); - kfree(netdevice); + free_netdev(netdevice); return -ENODEV; }; if (dev->id.sversion == 0x72) { diff -Nru a/drivers/net/loopback.c b/drivers/net/loopback.c --- a/drivers/net/loopback.c Thu Sep 4 15:38:30 2003 +++ b/drivers/net/loopback.c Thu Sep 4 15:38:30 2003 @@ -55,6 +55,7 @@ #include #include + #define LOOPBACK_OVERHEAD (128 + MAX_HEADER + 16 + 16) /* KISS: just allocate small chunks and copy bits. @@ -152,10 +153,12 @@ } dev->last_rx = jiffies; - stats->rx_bytes+=skb->len; - stats->tx_bytes+=skb->len; - stats->rx_packets++; - stats->tx_packets++; + if (likely(stats)) { + stats->rx_bytes+=skb->len; + stats->tx_bytes+=skb->len; + stats->rx_packets++; + stats->tx_packets++; + } netif_rx(skb); @@ -167,36 +170,35 @@ return (struct net_device_stats *)dev->priv; } -/* Initialize the rest of the LOOPBACK device. */ -int __init loopback_init(struct net_device *dev) -{ - dev->mtu = (16 * 1024) + 20 + 20 + 12; - dev->hard_start_xmit = loopback_xmit; - dev->hard_header = eth_header; - dev->hard_header_cache = eth_header_cache; - dev->header_cache_update= eth_header_cache_update; - dev->hard_header_len = ETH_HLEN; /* 14 */ - dev->addr_len = ETH_ALEN; /* 6 */ - dev->tx_queue_len = 0; - dev->type = ARPHRD_LOOPBACK; /* 0x0001 */ - dev->rebuild_header = eth_rebuild_header; - dev->flags = IFF_LOOPBACK; - dev->features = NETIF_F_SG|NETIF_F_FRAGLIST|NETIF_F_NO_CSUM|NETIF_F_HIGHDMA; - - /* Current netfilter will die with oom linearizing large skbs, - * however this will be cured before 2.5.x is done. - */ - dev->features |= NETIF_F_TSO; +struct net_device loopback_dev = { + .name = "lo", + .mtu = (16 * 1024) + 20 + 20 + 12, + .hard_start_xmit = loopback_xmit, + .hard_header = eth_header, + .hard_header_cache = eth_header_cache, + .header_cache_update = eth_header_cache_update, + .hard_header_len = ETH_HLEN, /* 14 */ + .addr_len = ETH_ALEN, /* 6 */ + .tx_queue_len = 0, + .type = ARPHRD_LOOPBACK, /* 0x0001*/ + .rebuild_header = eth_rebuild_header, + .flags = IFF_LOOPBACK, + .features = NETIF_F_SG|NETIF_F_FRAGLIST + |NETIF_F_NO_CSUM|NETIF_F_HIGHDMA|NETIF_F_TSO, +}; - dev->priv = kmalloc(sizeof(struct net_device_stats), GFP_KERNEL); - if (dev->priv == NULL) - return -ENOMEM; - memset(dev->priv, 0, sizeof(struct net_device_stats)); - dev->get_stats = get_stats; +/* Setup and register the of the LOOPBACK device. */ +int __init loopback_init(void) +{ + struct net_device_stats *stats; - /* - * Fill in the generic fields of the device structure. - */ - - return(0); + /* Can survive without statistics */ + stats = kmalloc(sizeof(struct net_device_stats), GFP_KERNEL); + if (stats) { + memset(stats, 0, sizeof(struct net_device_stats)); + loopback_dev.priv = stats; + loopback_dev.get_stats = &get_stats; + } + + return register_netdev(&loopback_dev); }; diff -Nru a/drivers/net/lp486e.c b/drivers/net/lp486e.c --- a/drivers/net/lp486e.c Thu Sep 4 15:38:31 2003 +++ b/drivers/net/lp486e.c Thu Sep 4 15:38:31 2003 @@ -1324,7 +1324,7 @@ dev->base_addr = io; dev->init = lp486e_probe; if (register_netdev(dev) != 0) { - kfree(dev); + free_netdev(dev); return -EIO; } dev_lp486e = dev; diff -Nru a/drivers/net/natsemi.c b/drivers/net/natsemi.c --- a/drivers/net/natsemi.c Thu Sep 4 15:38:29 2003 +++ b/drivers/net/natsemi.c Thu Sep 4 15:38:29 2003 @@ -766,7 +766,7 @@ i = pci_request_regions(pdev, dev->name); if (i) { - kfree(dev); + free_netdev(dev); return i; } @@ -774,7 +774,7 @@ void *mmio = ioremap (ioaddr, iosize); if (!mmio) { pci_release_regions(pdev); - kfree(dev); + free_netdev(dev); return -ENOMEM; } ioaddr = (unsigned long) mmio; @@ -838,7 +838,7 @@ if (i) { pci_release_regions(pdev); unregister_netdev(dev); - kfree(dev); + free_netdev(dev); pci_set_drvdata(pdev, NULL); return i; } diff -Nru a/drivers/net/ne2k-pci.c b/drivers/net/ne2k-pci.c --- a/drivers/net/ne2k-pci.c Thu Sep 4 15:38:30 2003 +++ b/drivers/net/ne2k-pci.c Thu Sep 4 15:38:30 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 Thu Sep 4 15:38:33 2003 +++ b/drivers/net/ni5010.c Thu Sep 4 15:38:33 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 Thu Sep 4 15:38:30 2003 +++ b/drivers/net/pcmcia/3c574_cs.c Thu Sep 4 15:38:30 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 Thu Sep 4 15:38:45 2003 +++ b/drivers/net/pcmcia/3c589_cs.c Thu Sep 4 15:38:45 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 Thu Sep 4 15:38:35 2003 +++ b/drivers/net/pcmcia/axnet_cs.c Thu Sep 4 15:38:35 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 Thu Sep 4 15:38:39 2003 +++ b/drivers/net/pcmcia/fmvj18x_cs.c Thu Sep 4 15:38:39 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 Thu Sep 4 15:38:35 2003 +++ b/drivers/net/pcmcia/ibmtr_cs.c Thu Sep 4 15:38:35 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 Thu Sep 4 15:38:29 2003 +++ b/drivers/net/pcmcia/nmclan_cs.c Thu Sep 4 15:38:29 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 Thu Sep 4 15:38:43 2003 +++ b/drivers/net/pcmcia/pcnet_cs.c Thu Sep 4 15:38:43 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 Thu Sep 4 15:38:32 2003 +++ b/drivers/net/pcmcia/xirc2ps_cs.c Thu Sep 4 15:38:32 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 Thu Sep 4 15:38:31 2003 +++ b/drivers/net/pcnet32.c Thu Sep 4 15:38:31 2003 @@ -529,6 +529,7 @@ struct net_device *dev; struct pcnet32_access *a = NULL; u8 promaddr[6]; + int ret = -ENODEV; /* reset the chip */ pcnet32_wio_reset(ioaddr); @@ -540,19 +541,15 @@ pcnet32_dwio_reset(ioaddr); if (pcnet32_dwio_read_csr(ioaddr, 0) == 4 && pcnet32_dwio_check(ioaddr)) { a = &pcnet32_dwio; - } else { - release_region(ioaddr, PCNET32_TOTAL_SIZE); - return -ENODEV; - } + } else + goto err_release_region; } chip_version = a->read_csr(ioaddr, 88) | (a->read_csr(ioaddr,89) << 16); if (pcnet32_debug > 2) printk(KERN_INFO " PCnet chip version is %#x.\n", chip_version); - if ((chip_version & 0xfff) != 0x003) { - release_region(ioaddr, PCNET32_TOTAL_SIZE); - return -ENODEV; - } + if ((chip_version & 0xfff) != 0x003) + goto err_release_region; /* initialize variables */ fdx = mii = fset = dxsuflo = ltint = 0; @@ -614,8 +611,7 @@ default: printk(KERN_INFO PFX "PCnet version %#x, no PCnet32 chip.\n", chip_version); - release_region(ioaddr, PCNET32_TOTAL_SIZE); - return -ENODEV; + goto err_release_region; } /* @@ -635,8 +631,8 @@ dev = alloc_etherdev(0); if(!dev) { - release_region(ioaddr, PCNET32_TOTAL_SIZE); - return -ENOMEM; + ret = -ENOMEM; + goto err_release_region; } SET_NETDEV_DEV(dev, &pdev->dev); @@ -708,8 +704,8 @@ dev->base_addr = ioaddr; /* pci_alloc_consistent returns page-aligned memory, so we do not have to check the alignment */ if ((lp = pci_alloc_consistent(pdev, sizeof(*lp), &lp_dma_addr)) == NULL) { - release_region(ioaddr, PCNET32_TOTAL_SIZE); - return -ENOMEM; + ret = -ENOMEM; + goto err_free_netdev; } memset(lp, 0, sizeof(*lp)); @@ -741,9 +737,8 @@ if (!a) { printk(KERN_ERR PFX "No access methods\n"); - pci_free_consistent(lp->pci_dev, sizeof(*lp), lp, lp->dma_addr); - release_region(ioaddr, PCNET32_TOTAL_SIZE); - return -ENODEV; + ret = -ENODEV; + goto err_free_consistent; } lp->a = *a; @@ -785,14 +780,12 @@ mdelay (1); dev->irq = probe_irq_off (irq_mask); - if (dev->irq) - printk(", probed IRQ %d.\n", dev->irq); - else { + if (!dev->irq) { printk(", failed to detect IRQ line.\n"); - pci_free_consistent(lp->pci_dev, sizeof(*lp), lp, lp->dma_addr); - release_region(ioaddr, PCNET32_TOTAL_SIZE); - return -ENODEV; + ret = -ENODEV; + goto err_free_consistent; } + printk(", probed IRQ %d.\n", dev->irq); } /* Set the mii phy_id so that we can query the link state */ @@ -821,6 +814,14 @@ printk(KERN_INFO "%s: registered as %s\n",dev->name, lp->name); cards_found++; return 0; + +err_free_consistent: + pci_free_consistent(lp->pci_dev, sizeof(*lp), lp, lp->dma_addr); +err_free_netdev: + free_netdev(dev); +err_release_region: + release_region(ioaddr, PCNET32_TOTAL_SIZE); + return ret; } @@ -1726,6 +1727,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 +1740,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 +1750,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 +1768,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/ppp_async.c b/drivers/net/ppp_async.c --- a/drivers/net/ppp_async.c Thu Sep 4 15:38:40 2003 +++ b/drivers/net/ppp_async.c Thu Sep 4 15:38:40 2003 @@ -84,7 +84,7 @@ MODULE_PARM(flag_time, "i"); MODULE_PARM_DESC(flag_time, "ppp_async: interval between flagged packets (in clock ticks)"); MODULE_LICENSE("GPL"); - +MODULE_ALIAS_LDISC(N_PPP); /* * Prototypes. diff -Nru a/drivers/net/ppp_generic.c b/drivers/net/ppp_generic.c --- a/drivers/net/ppp_generic.c Thu Sep 4 15:38:45 2003 +++ b/drivers/net/ppp_generic.c Thu Sep 4 15:38:45 2003 @@ -2670,3 +2670,4 @@ EXPORT_SYMBOL(all_ppp_units); /* for debugging */ EXPORT_SYMBOL(all_channels); /* for debugging */ MODULE_LICENSE("GPL"); +MODULE_ALIAS_CHARDEV_MAJOR(PPP_MAJOR); diff -Nru a/drivers/net/ppp_synctty.c b/drivers/net/ppp_synctty.c --- a/drivers/net/ppp_synctty.c Thu Sep 4 15:38:32 2003 +++ b/drivers/net/ppp_synctty.c Thu Sep 4 15:38:32 2003 @@ -759,3 +759,4 @@ module_init(ppp_sync_init); module_exit(ppp_sync_cleanup); MODULE_LICENSE("GPL"); +MODULE_ALIAS_LDISC(N_SYNC_PPP); diff -Nru a/drivers/net/r8169.c b/drivers/net/r8169.c --- a/drivers/net/r8169.c Thu Sep 4 15:38:34 2003 +++ b/drivers/net/r8169.c Thu Sep 4 15:38:34 2003 @@ -454,7 +454,7 @@ pci_disable_device(pdev); err_out: - kfree(dev); + free_netdev(dev); return rc; } @@ -514,7 +514,7 @@ iounmap(ioaddr); pci_release_regions(pdev); pci_disable_device(pdev); - kfree(dev); + free_netdev(dev); return rc; } diff -Nru a/drivers/net/rcpci45.c b/drivers/net/rcpci45.c --- a/drivers/net/rcpci45.c Thu Sep 4 15:38:42 2003 +++ b/drivers/net/rcpci45.c Thu Sep 4 15:38:42 2003 @@ -269,7 +269,7 @@ pci_free_consistent (pdev, MSG_BUF_SIZE, pDpa->msgbuf, pDpa->msgbuf_dma); err_out_free_dev: - kfree (dev); + free_netdev (dev); err_out: card_idx--; return error; diff -Nru a/drivers/net/sb1000.c b/drivers/net/sb1000.c --- a/drivers/net/sb1000.c Thu Sep 4 15:38:29 2003 +++ b/drivers/net/sb1000.c Thu Sep 4 15:38:29 2003 @@ -213,9 +213,11 @@ error = register_netdev(dev); if (error) - goto out_release_regions; + goto out_free_netdev; return 0; + out_free_netdev: + free_netdev(dev); out_release_regions: release_region(ioaddr[1], 16); out_release_region0: diff -Nru a/drivers/net/seeq8005.c b/drivers/net/seeq8005.c --- a/drivers/net/seeq8005.c Thu Sep 4 15:38:41 2003 +++ b/drivers/net/seeq8005.c Thu Sep 4 15:38:41 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 Thu Sep 4 15:38:48 2003 +++ b/drivers/net/sis190.c Thu Sep 4 15:38:48 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_disable; + mmio_start = pci_resource_start(pdev, 0); mmio_end = pci_resource_end(pdev, 0); mmio_flags = pci_resource_flags(pdev, 0); @@ -480,18 +482,18 @@ printk(KERN_ERR PFX "region #0 not an MMIO resource, aborting\n"); rc = -ENODEV; - goto err_out; + goto err_out_disable; } // check for weird/broken PCI region reporting if (mmio_len < SiS190_MIN_IO_SIZE) { printk(KERN_ERR PFX "Invalid PCI region size(s), aborting\n"); rc = -ENODEV; - goto err_out; + goto err_out_disable; } rc = pci_request_regions(pdev, dev->name); if (rc) - goto err_out; + goto err_out_disable; // enable PCI bus-mastering pci_set_master(pdev); @@ -519,10 +521,10 @@ err_out_free_res: pci_release_regions(pdev); -err_out: +err_out_disable: pci_disable_device(pdev); - unregister_netdev(dev); - kfree(dev); +err_out: + free_netdev(dev); return rc; } @@ -536,6 +538,7 @@ static int printed_version = 0; int i, rc; u16 reg31; + int val; assert(pdev != NULL); assert(ent != NULL); @@ -601,7 +604,7 @@ iounmap(ioaddr); pci_release_regions(pdev); pci_disable_device(pdev); - kfree(dev); + free_netdev(dev); return rc; } @@ -620,7 +623,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 +717,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 +779,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 +829,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 +854,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 +900,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 +970,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 +991,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 +999,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 +1033,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 +1056,7 @@ } cur_rx = (cur_rx + 1) % NUM_RX_DESC; - + desc = tp->RxDescArray + cur_rx; } tp->cur_rx = cur_rx; @@ -1111,22 +1131,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 Thu Sep 4 15:38:32 2003 +++ b/drivers/net/sis900.c Thu Sep 4 15:38:32 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); @@ -494,7 +503,7 @@ pci_set_drvdata(pci_dev, NULL); pci_release_regions(pci_dev); err_out: - kfree(net_dev); + free_netdev(net_dev); return ret; } @@ -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 Thu Sep 4 15:38:38 2003 +++ b/drivers/net/sk_mca.c Thu Sep 4 15:38:39 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 Thu Sep 4 15:38:35 2003 +++ b/drivers/net/sk_mca.h Thu Sep 4 15:38:35 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/slip.c b/drivers/net/slip.c --- a/drivers/net/slip.c Thu Sep 4 15:38:48 2003 +++ b/drivers/net/slip.c Thu Sep 4 15:38:48 2003 @@ -1513,3 +1513,4 @@ #endif MODULE_LICENSE("GPL"); +MODULE_ALIAS_LDISC(N_SLIP); diff -Nru a/drivers/net/smc-mca.c b/drivers/net/smc-mca.c --- a/drivers/net/smc-mca.c Thu Sep 4 15:38:29 2003 +++ b/drivers/net/smc-mca.c Thu Sep 4 15:38:29 2003 @@ -132,7 +132,7 @@ struct mca_device *mca_dev = to_mca_device(gen_dev); char slot = mca_dev->slot; unsigned char pos2 = 0xff, pos3 = 0xff, pos4 = 0xff, pos5 = 0xff; - int i; + int i, rc; int adapter = mca_dev->index; int tbase = 0; int tirq = 0; @@ -209,8 +209,9 @@ SET_MODULE_OWNER(dev); SET_NETDEV_DEV(dev, gen_dev); - if((i = register_netdev(dev)) != 0) - return i; + rc = register_netdev(dev); + if (rc) + goto err_free_netdev; printk(KERN_INFO "%s: %s found in slot %d\n", dev->name, smc_mca_adapter_names[adapter], slot + 1); @@ -262,11 +263,15 @@ } } - if (dev->mem_start == 0) /* sanity check, shouldn't happen */ - return -ENODEV; + /* sanity check, shouldn't happen */ + if (dev->mem_start == 0) { + rc = -ENODEV; + goto err_unregister_netdev; + } - if (!request_region(ioaddr, ULTRA_IO_EXTENT, dev->name)) - return -EBUSY; + rc = request_region(ioaddr, ULTRA_IO_EXTENT, dev->name); + if (rc) + goto err_unregister_netdev; reg4 = inb(ioaddr + 4) & 0x7f; outb(reg4, ioaddr + 4); @@ -296,10 +301,10 @@ /* Allocate dev->priv and fill in 8390 specific dev fields. */ - if (ethdev_init(dev)) { + rc = ethdev_init(dev); + if (rc) { printk (", no memory for dev->priv.\n"); - release_region(ioaddr, ULTRA_IO_EXTENT); - return -ENOMEM; + goto err_release_region; } gen_dev->driver_data = dev; @@ -334,6 +339,14 @@ NS8390_init(dev, 0); return 0; + +err_release_region: + release_region(ioaddr, ULTRA_IO_EXTENT); +err_unregister_netdev: + unregister_netdev(dev); +err_free_netdev: + free_netdev(dev); + return rc; } static int ultramca_open(struct net_device *dev) diff -Nru a/drivers/net/starfire.c b/drivers/net/starfire.c --- a/drivers/net/starfire.c Thu Sep 4 15:38:31 2003 +++ b/drivers/net/starfire.c Thu Sep 4 15:38:31 2003 @@ -1070,7 +1070,7 @@ err_out_free_res: pci_release_regions (pdev); err_out_free_netdev: - kfree(dev); + free_netdev(dev); return -ENODEV; } diff -Nru a/drivers/net/sunbmac.c b/drivers/net/sunbmac.c --- a/drivers/net/sunbmac.c Thu Sep 4 15:38:35 2003 +++ b/drivers/net/sunbmac.c Thu Sep 4 15:38:35 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/sundance.c b/drivers/net/sundance.c --- a/drivers/net/sundance.c Thu Sep 4 15:38:37 2003 +++ b/drivers/net/sundance.c Thu Sep 4 15:38:37 2003 @@ -734,7 +734,7 @@ #endif pci_release_regions(pdev); err_out_netdev: - kfree (dev); + free_netdev (dev); return -ENODEV; } diff -Nru a/drivers/net/sungem.c b/drivers/net/sungem.c --- a/drivers/net/sungem.c Thu Sep 4 15:38:46 2003 +++ b/drivers/net/sungem.c Thu Sep 4 15:38:46 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,126 @@ 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; - - 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; + 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_NWAY_RST: - if (!gp->want_autoneg) - return -EINVAL; + return 0; +} - /* Restart link process. */ - spin_lock_irq(&gp->lock); - gem_begin_auto_negotiation(gp, NULL); - spin_unlock_irq(&gp->lock); +static int gem_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) +{ + struct gem *gp = dev->priv; - return 0; + /* Verify the settings we care about. */ + if (cmd->autoneg != AUTONEG_ENABLE && + cmd->autoneg != AUTONEG_DISABLE) + return -EINVAL; - 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; - } + if (cmd->autoneg == AUTONEG_ENABLE && + cmd->advertising == 0) + return -EINVAL; - /* 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; - } + 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); - /* 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; - } + return 0; +} -#if 0 - case ETHTOOL_GREGS: { - struct ethtool_regs regs; - u32 *regbuf; - int r = 0; +static int gem_nway_reset(struct net_device *dev) +{ + struct gem *gp = dev->priv; - 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; + if (!gp->want_autoneg) + return -EINVAL; - if (!gp->hw_running) - return -ENODEV; - useraddr += offsetof(struct ethtool_regs, data); + /* Restart link process. */ + spin_lock_irq(&gp->lock); + gem_begin_auto_negotiation(gp, NULL); + spin_unlock_irq(&gp->lock); - /* 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 0; +} - 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_msglevel = gem_get_msglevel, + .set_msglevel = gem_set_msglevel, +}; static int gem_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) { @@ -2501,10 +2450,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... */ @@ -2677,7 +2622,7 @@ if (err) { printk(KERN_ERR PFX "No usable DMA configuration, " "aborting.\n"); - return err; + goto err_disable_device; } pci_using_dac = 0; } @@ -2688,20 +2633,23 @@ if ((pci_resource_flags(pdev, 0) & IORESOURCE_IO) != 0) { printk(KERN_ERR PFX "Cannot find proper PCI device " "base address, aborting.\n"); - return -ENODEV; + err = -ENODEV; + goto err_disable_device; } dev = alloc_etherdev(sizeof(*gp)); if (!dev) { printk(KERN_ERR PFX "Etherdev alloc failed, aborting.\n"); - return -ENOMEM; + err = -ENOMEM; + goto err_disable_device; } SET_MODULE_OWNER(dev); SET_NETDEV_DEV(dev, &pdev->dev); gp = dev->priv; - if (pci_request_regions(pdev, dev->name)) { + err = pci_request_regions(pdev, dev->name); + if (err) { printk(KERN_ERR PFX "Cannot obtain PCI resources, " "aborting.\n"); goto err_out_free_netdev; @@ -2735,6 +2683,7 @@ if (gp->regs == 0UL) { printk(KERN_ERR PFX "Cannot map device registers, " "aborting.\n"); + err = -EIO; goto err_out_free_res; } @@ -2758,8 +2707,10 @@ /* By default, we start with autoneg */ gp->want_autoneg = 1; - if (gem_check_invariants(gp)) + if (gem_check_invariants(gp)) { + err = -ENODEV; goto err_out_iounmap; + } /* It is guaranteed that the returned buffer will be at least * PAGE_SIZE aligned. @@ -2770,6 +2721,7 @@ if (!gp->init_block) { printk(KERN_ERR PFX "Cannot allocate init block, " "aborting.\n"); + err = -ENOMEM; goto err_out_iounmap; } @@ -2782,6 +2734,7 @@ if (register_netdev(dev)) { printk(KERN_ERR PFX "Cannot register net device, " "aborting.\n"); + err = -ENOMEM; goto err_out_free_consistent; } @@ -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; @@ -2850,9 +2804,10 @@ pci_release_regions(pdev); err_out_free_netdev: - kfree(dev); - - return -ENODEV; + free_netdev(dev); +err_disable_device: + pci_disable_device(pdev); + return err; } diff -Nru a/drivers/net/sungem_phy.c b/drivers/net/sungem_phy.c --- a/drivers/net/sungem_phy.c Thu Sep 4 15:38:31 2003 +++ b/drivers/net/sungem_phy.c Thu Sep 4 15:38:31 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 Thu Sep 4 15:38:31 2003 +++ b/drivers/net/sunhme.c Thu Sep 4 15:38:31 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; @@ -2868,7 +2895,7 @@ sbus_iounmap(hp->tcvregs, TCVR_REG_SIZE); err_out_free_netdev: - kfree(dev); + free_netdev(dev); err_out: return err; @@ -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; @@ -3220,7 +3247,7 @@ if (qp != NULL) qp->happy_meals[qfe_slot] = NULL; - kfree(dev); + free_netdev(dev); err_out: return err; diff -Nru a/drivers/net/sunlance.c b/drivers/net/sunlance.c --- a/drivers/net/sunlance.c Thu Sep 4 15:38:31 2003 +++ b/drivers/net/sunlance.c Thu Sep 4 15:38:31 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 Thu Sep 4 15:38:32 2003 +++ b/drivers/net/sunqe.c Thu Sep 4 15:38:32 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 @@ -918,7 +949,7 @@ i = 4; out: while (i--) - kfree(qe_devs[i]); + free_netdev(qe_devs[i]); return res; } diff -Nru a/drivers/net/tg3.c b/drivers/net/tg3.c --- a/drivers/net/tg3.c Thu Sep 4 15:38:35 2003 +++ b/drivers/net/tg3.c Thu Sep 4 15:38:35 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) { @@ -6864,7 +7740,7 @@ iounmap((void *) tp->regs); err_out_free_dev: - kfree(dev); + free_netdev(dev); err_out_free_res: pci_release_regions(pdev); diff -Nru a/drivers/net/tg3.h b/drivers/net/tg3.h --- a/drivers/net/tg3.h Thu Sep 4 15:38:30 2003 +++ b/drivers/net/tg3.h Thu Sep 4 15:38:30 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/tlan.c b/drivers/net/tlan.c --- a/drivers/net/tlan.c Thu Sep 4 15:38:30 2003 +++ b/drivers/net/tlan.c Thu Sep 4 15:38:30 2003 @@ -670,7 +670,7 @@ pci_free_consistent(priv->pciDev, priv->dmaSize, priv->dmaStorage, priv->dmaStorageDMA ); err_out_free_dev: - kfree(dev); + free_netdev(dev); err_out_regions: if (pdev) pci_release_regions(pdev); @@ -695,7 +695,7 @@ release_region( dev->base_addr, 0x10); unregister_netdev( dev ); TLan_Eisa_Devices = priv->nextDevice; - kfree( dev ); + free_netdev( dev ); tlan_have_eisa--; } } diff -Nru a/drivers/net/tokenring/lanstreamer.c b/drivers/net/tokenring/lanstreamer.c --- a/drivers/net/tokenring/lanstreamer.c Thu Sep 4 15:38:46 2003 +++ b/drivers/net/tokenring/lanstreamer.c Thu Sep 4 15:38:46 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 Thu Sep 4 15:38:41 2003 +++ b/drivers/net/tulip/Kconfig Thu Sep 4 15:38:41 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 Thu Sep 4 15:38:42 2003 +++ b/drivers/net/tulip/de2104x.c Thu Sep 4 15:38:42 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/de4x5.c b/drivers/net/tulip/de4x5.c --- a/drivers/net/tulip/de4x5.c Thu Sep 4 15:38:29 2003 +++ b/drivers/net/tulip/de4x5.c Thu Sep 4 15:38:29 2003 @@ -437,6 +437,9 @@ present. 0.547 08-Nov-01 Use library crc32 functions by + 0.548 30-Aug-03 Big 2.6 cleanup. Ported to PCI/EISA probing and + generic DMA APIs. Fixed DE425 support on Alpha. + ========================================================================= */ @@ -450,6 +453,7 @@ #include #include #include +#include #include #include #include @@ -461,6 +465,8 @@ #include #include #include +#include +#include #include #include @@ -625,13 +631,13 @@ #define DE4X5_EISA_IO_PORTS 0x0c00 /* I/O port base address, slot 0 */ #define DE4X5_EISA_TOTAL_SIZE 0x100 /* I/O address extent */ -#define MAX_EISA_SLOTS 16 -#define EISA_SLOT_INC 0x1000 #define EISA_ALLOWED_IRQ_LIST {5, 9, 10, 11} #define DE4X5_SIGNATURE {"DE425","DE434","DE435","DE450","DE500"} #define DE4X5_NAME_LENGTH 8 +static c_char *de4x5_signatures[] = DE4X5_SIGNATURE; + /* ** Ethernet PROM defines for DC21040 */ @@ -644,7 +650,6 @@ #define PCI_MAX_BUS_NUM 8 #define DE4X5_PCI_TOTAL_SIZE 0x80 /* I/O address extent */ #define DE4X5_CLASS_CODE 0x00020000 /* Network controller, Ethernet */ -#define NO_MORE_PCI -2 /* PCI bus search all done */ /* ** Memory Alignment. Each descriptor is 4 longwords long. To force a @@ -819,7 +824,6 @@ struct timer_list timer; /* Timer info for kernel */ int tmp; /* Temporary global per card */ struct { - void *priv; /* Original kmalloc'd mem addr */ u_long lock; /* Lock the cache accesses */ s32 csr0; /* Saved Bus Mode Register */ s32 csr6; /* Saved Operating Mode Reg. */ @@ -833,7 +837,7 @@ struct sk_buff *skb; /* Save the (re-ordered) skb's */ } cache; struct de4x5_srom srom; /* A copy of the SROM */ - struct net_device *next_module; /* Link to the next module */ + int cfrv; /* Card CFRV copy */ int rx_ovf; /* Check for 'RX overflow' tag */ int useSROM; /* For non-DEC card use SROM */ int useMII; /* Infoblock using the MII */ @@ -850,29 +854,13 @@ u_char *rst; /* Pointer to Type 5 reset info */ u_char ibn; /* Infoblock number */ struct parameters params; /* Command line/ #defined params */ - struct pci_dev *pdev; /* Device cookie for DMA alloc */ + struct device *gendev; /* Generic device */ dma_addr_t dma_rings; /* DMA handle for rings */ int dma_size; /* Size of the DMA area */ char *rx_bufs; /* rx bufs on alpha, sparc, ... */ }; /* -** Kludge to get around the fact that the CSR addresses have different -** offsets in the PCI and EISA boards. Also note that the ethernet address -** PROM is accessed differently. -*/ -static struct de4x5_bus_type { - int bus; - int bus_num; - int device; - int chipset; - struct de4x5_srom srom; - int autosense; - int useSROM; - struct pci_dev *pdev; -} bus; - -/* ** To get around certain poxy cards that don't provide an SROM ** for the second and more DECchip, I have to key off the first ** chip's address. I'll assume there's not a bad SROM iff: @@ -919,7 +907,7 @@ /* ** Private functions */ -static int de4x5_hw_init(struct net_device *dev, u_long iobase, struct pci_dev *pdev); +static int de4x5_hw_init(struct net_device *dev, u_long iobase, struct device *gendev); static int de4x5_init(struct net_device *dev); static int de4x5_sw_reset(struct net_device *dev); static int de4x5_rx(struct net_device *dev); @@ -962,11 +950,11 @@ static void reset_init_sia(struct net_device *dev, s32 sicr, s32 strr, s32 sigr); static int test_ans(struct net_device *dev, s32 irqs, s32 irq_mask, s32 msec); static int test_tp(struct net_device *dev, s32 msec); -static int EISA_signature(char *name, s32 eisa_id); -static int PCI_signature(char *name, struct de4x5_bus_type *lp); -static void DevicePresent(u_long iobase); +static int EISA_signature(char *name, struct device *device); +static int PCI_signature(char *name, struct de4x5_private *lp); +static void DevicePresent(struct net_device *dev, u_long iobase); static void enet_addr_rst(u_long aprom_addr); -static int de4x5_bad_srom(struct de4x5_bus_type *lp); +static int de4x5_bad_srom(struct de4x5_private *lp); static short srom_rd(u_long address, u_char offset); static void srom_latch(u_int command, u_long address); static void srom_command(u_int command, u_long address); @@ -994,12 +982,7 @@ static int get_hw_addr(struct net_device *dev); static void srom_repair(struct net_device *dev, int card); static int test_bad_enet(struct net_device *dev, int status); -static int an_exception(struct de4x5_bus_type *lp); -#if !defined(__sparc_v9__) && !defined(__powerpc__) && !defined(__alpha__) -static void eisa_probe(struct net_device *dev, u_long iobase); -#endif -static void pci_probe(struct net_device *dev, u_long iobase); -static void srom_search(struct pci_dev *pdev); +static int an_exception(struct de4x5_private *lp); static char *build_setup_frame(struct net_device *dev, int mode); static void disable_ast(struct net_device *dev); static void enable_ast(struct net_device *dev, u32 time_out); @@ -1008,7 +991,6 @@ static void gep_wr(s32 data, struct net_device *dev); static void timeout(struct net_device *dev, void (*fn)(u_long data), u_long data, u_long msec); static void yawn(struct net_device *dev, int state); -static void link_modules(struct net_device *dev, struct net_device *tmp); static void de4x5_parse_params(struct net_device *dev); static void de4x5_dbg_open(struct net_device *dev); static void de4x5_dbg_mii(struct net_device *dev, int k); @@ -1028,40 +1010,25 @@ static int type5_infoblock(struct net_device *dev, u_char count, u_char *p); static int compact_infoblock(struct net_device *dev, u_char count, u_char *p); -#ifdef MODULE -static struct net_device *unlink_modules(struct net_device *p); -static struct net_device *insert_device(struct net_device *dev, u_long iobase, - int (*init)(struct net_device *)); -static int count_adapters(void); -static int loading_module = 1; -MODULE_PARM(de4x5_debug, "i"); -MODULE_PARM(dec_only, "i"); -MODULE_PARM(args, "s"); +/* +** Note now that module autoprobing is allowed under EISA and PCI. The +** IRQ lines will not be auto-detected; instead I'll rely on the BIOSes +** to "do the right thing". +*/ + +static int io=0x0;/* EDIT THIS LINE FOR YOUR CONFIGURATION IF NEEDED */ + +module_param(io, int, 0); +module_param(de4x5_debug, int, 0); +module_param(dec_only, int, 0); +module_param(args, charp, 0); + +MODULE_PARM_DESC(io, "de4x5 I/O base address"); MODULE_PARM_DESC(de4x5_debug, "de4x5 debug mask"); MODULE_PARM_DESC(dec_only, "de4x5 probe only for Digital boards (0-1)"); MODULE_PARM_DESC(args, "de4x5 full duplex and media type settings; see de4x5.c for details"); MODULE_LICENSE("GPL"); -# else -static int loading_module; -#endif /* MODULE */ - -static char name[DE4X5_NAME_LENGTH + 1]; -#if !defined(__sparc_v9__) && !defined(__powerpc__) && !defined(__alpha__) -static u_char de4x5_irq[] = EISA_ALLOWED_IRQ_LIST; -static int lastEISA; -# ifdef DE4X5_FORCE_EISA /* Force an EISA bus probe or not */ -static int forceEISA = 1; -# else -static int forceEISA; -# endif -#endif -static int num_de4x5s; -static int cfrv, useSROM; -static int lastPCI = -1; -static struct net_device *lastModule; -static struct pci_dev *pdev; - /* ** List the SROM infoleaf functions and chipsets */ @@ -1115,37 +1082,22 @@ } -/* -** Autoprobing in modules is allowed here. See the top of the file for -** more info. -*/ -int __init -de4x5_probe(struct net_device *dev) -{ - u_long iobase = dev->base_addr; - - pci_probe(dev, iobase); -#if !defined(__sparc_v9__) && !defined(__powerpc__) && !defined(__alpha__) - if ((lastPCI == NO_MORE_PCI) && ((num_de4x5s == 0) || forceEISA)) { - eisa_probe(dev, iobase); - } -#endif - - return (dev->priv ? 0 : -ENODEV); -} - static int __init -de4x5_hw_init(struct net_device *dev, u_long iobase, struct pci_dev *pdev) +de4x5_hw_init(struct net_device *dev, u_long iobase, struct device *gendev) { - struct de4x5_bus_type *lp = &bus; + char name[DE4X5_NAME_LENGTH + 1]; + struct de4x5_private *lp = dev->priv; + struct pci_dev *pdev = NULL; int i, status=0; - char *tmp; - + + gendev->driver_data = dev; + /* Ensure we're not sleeping */ if (lp->bus == EISA) { outb(WAKEUP, PCI_CFPM); } else { - pci_write_config_byte(lp->pdev, PCI_CFDA_PSM, WAKEUP); + pdev = to_pci_dev (gendev); + pci_write_config_byte(pdev, PCI_CFDA_PSM, WAKEUP); } mdelay(10); @@ -1158,11 +1110,11 @@ /* ** Now find out what kind of DC21040/DC21041/DC21140 board we have. */ - useSROM = FALSE; + lp->useSROM = FALSE; if (lp->bus == PCI) { PCI_signature(name, lp); } else { - EISA_signature(name, EISA_ID0); + EISA_signature(name, gendev); } if (*name == '\0') { /* Not found a board signature */ @@ -1170,13 +1122,7 @@ } dev->base_addr = iobase; - if (lp->bus == EISA) { - printk("%s: %s at 0x%04lx (EISA slot %ld)", - dev->name, name, iobase, ((iobase>>12)&0x0f)); - } else { /* PCI port address */ - printk("%s: %s at 0x%04lx (PCI bus %d, device %d)", dev->name, name, - iobase, lp->bus_num, lp->device); - } + printk ("%s: %s at 0x%04lx", gendev->bus_id, name, iobase); printk(", h/w address "); status = get_hw_addr(dev); @@ -1189,38 +1135,12 @@ printk(" which has an Ethernet PROM CRC error.\n"); return -ENXIO; } else { - struct de4x5_private *lp; - - /* - ** Reserve a section of kernel memory for the adapter - ** private area and the TX/RX descriptor rings. - */ - dev->priv = (void *) kmalloc(sizeof(struct de4x5_private) + DE4X5_ALIGN, - GFP_KERNEL); - if (dev->priv == NULL) { - return -ENOMEM; - } - - /* - ** Align to a longword boundary - */ - tmp = dev->priv; - dev->priv = (void *)(((u_long)dev->priv + DE4X5_ALIGN) & ~DE4X5_ALIGN); - lp = (struct de4x5_private *)dev->priv; - memset(dev->priv, 0, sizeof(struct de4x5_private)); - lp->bus = bus.bus; - lp->bus_num = bus.bus_num; - lp->device = bus.device; - lp->chipset = bus.chipset; - lp->cache.priv = tmp; lp->cache.gepc = GEP_INIT; lp->asBit = GEP_SLNK; lp->asPolarity = GEP_SLNK; lp->asBitValid = TRUE; lp->timeout = -1; - lp->useSROM = useSROM; - lp->pdev = pdev; - memcpy((char *)&lp->srom,(char *)&bus.srom,sizeof(struct de4x5_srom)); + lp->gendev = gendev; lp->lock = (spinlock_t) SPIN_LOCK_UNLOCKED; init_timer(&lp->timer); de4x5_parse_params(dev); @@ -1238,16 +1158,15 @@ } } lp->fdx = lp->params.fdx; - sprintf(lp->adapter_name,"%s (%s)", name, dev->name); + sprintf(lp->adapter_name,"%s (%s)", name, gendev->bus_id); lp->dma_size = (NUM_RX_DESC + NUM_TX_DESC) * sizeof(struct de4x5_desc); #if defined(__alpha__) || defined(__powerpc__) || defined(__sparc_v9__) || defined(DE4X5_DO_MEMCPY) lp->dma_size += RX_BUFF_SZ * NUM_RX_DESC + DE4X5_ALIGN; #endif - lp->rx_ring = pci_alloc_consistent(pdev, lp->dma_size, &lp->dma_rings); + lp->rx_ring = dma_alloc_coherent(gendev, lp->dma_size, + &lp->dma_rings, GFP_ATOMIC); if (lp->rx_ring == NULL) { - kfree(lp->cache.priv); - lp->cache.priv = NULL; return -ENOMEM; } @@ -1288,11 +1207,7 @@ #endif barrier(); - - request_region(iobase, (lp->bus == PCI ? DE4X5_PCI_TOTAL_SIZE : - DE4X5_EISA_TOTAL_SIZE), - lp->adapter_name); - + lp->rxRingSize = NUM_RX_DESC; lp->txRingSize = NUM_TX_DESC; @@ -1313,7 +1228,7 @@ create_packet(dev, lp->frame, sizeof(lp->frame)); /* Check if the RX overflow bug needs testing for */ - i = cfrv & 0x000000fe; + i = lp->cfrv & 0x000000fe; if ((lp->chipset == DC21140) && (i == 0x20)) { lp->rx_ovf = 1; } @@ -1350,7 +1265,7 @@ /* The DE4X5-specific entries in the device structure. */ SET_MODULE_OWNER(dev); - SET_NETDEV_DEV(dev, &pdev->dev); + SET_NETDEV_DEV(dev, gendev); dev->open = &de4x5_open; dev->hard_start_xmit = &de4x5_queue_pkt; dev->stop = &de4x5_close; @@ -1361,7 +1276,11 @@ dev->mem_start = 0; /* Fill in the generic fields of the device structure. */ - ether_setup(dev); + if ((status = register_netdev (dev))) { + dma_free_coherent (gendev, lp->dma_size, + lp->rx_ring, lp->dma_rings); + return status; + } /* Let the adapter sleep to save power */ yawn(dev, SLEEP); @@ -1766,9 +1685,9 @@ static inline void de4x5_free_tx_buff(struct de4x5_private *lp, int entry) { - pci_unmap_single(lp->pdev, le32_to_cpu(lp->tx_ring[entry].buf), + dma_unmap_single(lp->gendev, le32_to_cpu(lp->tx_ring[entry].buf), le32_to_cpu(lp->tx_ring[entry].des1) & TD_TBS1, - PCI_DMA_TODEVICE); + DMA_TO_DEVICE); if ((u_long) lp->tx_skb[entry] > 1) dev_kfree_skb_irq(lp->tx_skb[entry]); lp->tx_skb[entry] = NULL; @@ -1987,7 +1906,7 @@ { struct de4x5_private *lp = (struct de4x5_private *)dev->priv; int entry = (lp->tx_new ? lp->tx_new-1 : lp->txRingSize-1); - dma_addr_t buf_dma = pci_map_single(lp->pdev, buf, flags & TD_TBS1, PCI_DMA_TODEVICE); + dma_addr_t buf_dma = dma_map_single(lp->gendev, buf, flags & TD_TBS1, DMA_TO_DEVICE); lp->tx_ring[lp->tx_new].buf = cpu_to_le32(buf_dma); lp->tx_ring[lp->tx_new].des1 &= cpu_to_le32(TD_TER); @@ -2084,194 +2003,128 @@ return; } -#if !defined(__sparc_v9__) && !defined(__powerpc__) && !defined(__alpha__) -/* -** EISA bus I/O device probe. Probe from slot 1 since slot 0 is usually -** the motherboard. Upto 15 EISA devices are supported. -*/ -static void __init -eisa_probe(struct net_device *dev, u_long ioaddr) +#ifdef CONFIG_EISA + +static u_char de4x5_irq[] = EISA_ALLOWED_IRQ_LIST; + +static int __init de4x5_eisa_probe (struct device *gendev) { - int i, maxSlots, status, device; - u_char irq; - u_short vendor; - u32 cfid; - u_long iobase; - struct de4x5_bus_type *lp = &bus; - char name[DE4X5_STRLEN]; + struct eisa_device *edev; + u_long iobase; + u_char irq, regval; + u_short vendor; + u32 cfid; + int status, device; + struct net_device *dev; + struct de4x5_private *lp; - if (lastEISA == MAX_EISA_SLOTS) return;/* No more EISA devices to search */ + edev = to_eisa_device (gendev); + iobase = edev->base_addr; - lp->bus = EISA; - - if (ioaddr == 0) { /* Autoprobing */ - iobase = EISA_SLOT_INC; /* Get the first slot address */ - i = 1; - maxSlots = MAX_EISA_SLOTS; - } else { /* Probe a specific location */ - iobase = ioaddr; - i = (ioaddr >> 12); - maxSlots = i + 1; - } - - for (status = -ENODEV; (ipriv; + cfid = (u32) inl(PCI_CFID); - cfrv = (u_short) inl(PCI_CFRV); + lp->cfrv = (u_short) inl(PCI_CFRV); device = (cfid >> 8) & 0x00ffff00; vendor = (u_short) cfid; /* Read the EISA Configuration Registers */ - irq = inb(EISA_REG0); - irq = de4x5_irq[(irq >> 1) & 0x03]; + regval = inb(EISA_REG0) & (ER0_INTL | ER0_INTT); +#ifdef CONFIG_ALPHA + /* Looks like the Jensen firmware (rev 2.2) doesn't really + * care about the EISA configuration, and thus doesn't + * configure the PLX bridge properly. Oh well... Simply mimic + * the EISA config file to sort it out. */ + + /* EISA REG1: Assert DecChip 21040 HW Reset */ + outb (ER1_IAM | 1, EISA_REG1); + mdelay (1); + + /* EISA REG1: Deassert DecChip 21040 HW Reset */ + outb (ER1_IAM, EISA_REG1); + mdelay (1); + /* EISA REG3: R/W Burst Transfer Enable */ + outb (ER3_BWE | ER3_BRE, EISA_REG3); + + /* 32_bit slave/master, Preempt Time=23 bclks, Unlatched Interrupt */ + outb (ER0_BSW | ER0_BMW | ER0_EPT | regval, EISA_REG0); +#endif + irq = de4x5_irq[(regval >> 1) & 0x03]; + if (is_DC2114x) { - device = ((cfrv & CFRV_RN) < DC2114x_BRK ? DC21142 : DC21143); + device = ((lp->cfrv & CFRV_RN) < DC2114x_BRK ? DC21142 : DC21143); } lp->chipset = device; + lp->bus = EISA; /* Write the PCI Configuration Registers */ outl(PCI_COMMAND_IO | PCI_COMMAND_MASTER, PCI_CFCS); outl(0x00006000, PCI_CFLT); outl(iobase, PCI_CBIO); - DevicePresent(EISA_APROM); + DevicePresent(dev, EISA_APROM); dev->irq = irq; - if ((status = de4x5_hw_init(dev, iobase, NULL)) == 0) { - num_de4x5s++; - if (loading_module) link_modules(lastModule, dev); - lastEISA = i; - return; + + if (!(status = de4x5_hw_init (dev, iobase, gendev))) { + return 0; } - } - if (ioaddr == 0) lastEISA = i; + free_netdev (dev); + release_reg_2: + release_region (iobase + DE4X5_EISA_IO_PORTS, DE4X5_EISA_TOTAL_SIZE); + release_reg_1: + release_region (iobase, DE4X5_EISA_TOTAL_SIZE); - return; + return status; } -#endif /* !(__sparc_v9__) && !(__powerpc__) && !defined(__alpha__) */ -/* -** PCI bus I/O device probe -** NB: PCI I/O accesses and Bus Mastering are enabled by the PCI BIOS, not -** the driver. Some PCI BIOS's, pre V2.1, need the slot + features to be -** enabled by the user first in the set up utility. Hence we just check for -** enabled features and silently ignore the card if they're not. -** -** STOP PRESS: Some BIOS's __require__ the driver to enable the bus mastering -** bit. Here, check for I/O accesses and then set BM. If you put the card in -** a non BM slot, you're on your own (and complain to the PC vendor that your -** PC doesn't conform to the PCI standard)! -** -** This function is only compatible with the *latest* 2.1.x kernels. For 2.0.x -** kernels use the V0.535[n] drivers. -*/ -#define PCI_LAST_DEV 32 - -static void __init -pci_probe(struct net_device *dev, u_long ioaddr) +static int __devexit de4x5_eisa_remove (struct device *device) { - u_char pb, pbus, dev_num, dnum, timer; - u_short vendor, index, status; - u_int irq = 0, device, class = DE4X5_CLASS_CODE; - u_long iobase = 0; /* Clear upper 32 bits in Alphas */ - struct de4x5_bus_type *lp = &bus; - - if (lastPCI == NO_MORE_PCI) return; - - lp->bus = PCI; - lp->bus_num = 0; - - if ((ioaddr < 0x1000) && loading_module) { - pbus = (u_short)(ioaddr >> 8); - dnum = (u_short)(ioaddr & 0xff); - } else { - pbus = 0; - dnum = 0; - } - - for (index=lastPCI+1;(pdev = pci_find_class(class, pdev))!=NULL;index++) { - dev_num = PCI_SLOT(pdev->devfn); - pb = pdev->bus->number; - if ((pbus || dnum) && ((pbus != pb) || (dnum != dev_num))) continue; - - vendor = pdev->vendor; - device = pdev->device << 8; - if (!(is_DC21040 || is_DC21041 || is_DC21140 || is_DC2114x)) continue; - - /* Search for an SROM on this bus */ - if (lp->bus_num != pb) { - lp->bus_num = pb; - srom_search(pdev); - } - - /* Get the chip configuration revision register */ - pci_read_config_dword(pdev, PCI_REVISION_ID, &cfrv); - - /* Set the device number information */ - lp->device = dev_num; - lp->bus_num = pb; - lp->pdev = pdev; - - /* Set the chipset information */ - if (is_DC2114x) { - device = ((cfrv & CFRV_RN) < DC2114x_BRK ? DC21142 : DC21143); - } - lp->chipset = device; + struct net_device *dev; + u_long iobase; - /* Get the board I/O address (64 bits on sparc64) */ - iobase = pci_resource_start(pdev, 0); - - /* Fetch the IRQ to be used */ - irq = pdev->irq; - if ((irq == 0) || (irq == 0xff) || ((int)irq == -1)) continue; - - /* Check if I/O accesses and Bus Mastering are enabled */ - pci_read_config_word(pdev, PCI_COMMAND, &status); -#ifdef __powerpc__ - if (!(status & PCI_COMMAND_IO)) { - status |= PCI_COMMAND_IO; - pci_write_config_word(pdev, PCI_COMMAND, status); - pci_read_config_word(pdev, PCI_COMMAND, &status); - } -#endif /* __powerpc__ */ - if (!(status & PCI_COMMAND_IO)) continue; - - if (!(status & PCI_COMMAND_MASTER)) { - status |= PCI_COMMAND_MASTER; - pci_write_config_word(pdev, PCI_COMMAND, status); - pci_read_config_word(pdev, PCI_COMMAND, &status); - } - if (!(status & PCI_COMMAND_MASTER)) continue; + dev = device->driver_data; + iobase = dev->base_addr; + + unregister_netdev (dev); + free_netdev (dev); + release_region (iobase + DE4X5_EISA_IO_PORTS, DE4X5_EISA_TOTAL_SIZE); + release_region (iobase, DE4X5_EISA_TOTAL_SIZE); - /* Check the latency timer for values >= 0x60 */ - pci_read_config_byte(pdev, PCI_LATENCY_TIMER, &timer); - if (timer < 0x60) { - pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 0x60); - } + return 0; +} - DevicePresent(DE4X5_APROM); - if (check_region(iobase, DE4X5_PCI_TOTAL_SIZE) == 0) { - dev->irq = irq; - if ((status = de4x5_hw_init(dev, iobase, pdev)) == 0) { - num_de4x5s++; - lastPCI = index; - if (loading_module) link_modules(lastModule, dev); - return; - } - } else if (ioaddr != 0) { - printk("%s: region already allocated at 0x%04lx.\n", dev->name, - iobase); - } - } +static struct eisa_device_id de4x5_eisa_ids[] = { + { "DEC4250", 0 }, /* 0 is the board name index... */ + { "" } +}; - lastPCI = NO_MORE_PCI; +static struct eisa_driver de4x5_eisa_driver = { + .id_table = de4x5_eisa_ids, + .driver = { + .name = "de4x5", + .probe = de4x5_eisa_probe, + .remove = __devexit_p (de4x5_eisa_remove), + } +}; +#endif - return; -} +#ifdef CONFIG_PCI /* ** This function searches the current bus (which is >0) for a DECchip with an @@ -2280,21 +2133,21 @@ ** For single port cards this is a time waster... */ static void __init -srom_search(struct pci_dev *dev) +srom_search(struct net_device *dev, struct pci_dev *pdev) { u_char pb; u_short vendor, status; u_int irq = 0, device; u_long iobase = 0; /* Clear upper 32 bits in Alphas */ - int i, j; - struct de4x5_bus_type *lp = &bus; - struct list_head *walk = &dev->bus_list; + int i, j, cfrv; + struct de4x5_private *lp = dev->priv; + struct list_head *walk = &pdev->bus_list; - for (walk = walk->next; walk != &dev->bus_list; walk = walk->next) { + for (walk = walk->next; walk != &pdev->bus_list; walk = walk->next) { struct pci_dev *this_dev = pci_dev_b(walk); /* Skip the pci_bus list entry */ - if (list_entry(walk, struct pci_bus, devices) == dev->bus) continue; + if (list_entry(walk, struct pci_bus, devices) == pdev->bus) continue; vendor = this_dev->vendor; device = this_dev->device << 8; @@ -2326,7 +2179,7 @@ if (!(status & PCI_COMMAND_IO)) continue; /* Search for a valid SROM attached to this DECchip */ - DevicePresent(DE4X5_APROM); + DevicePresent(dev, DE4X5_APROM); for (j=0, i=0; isrom + SROM_HWADD + i); } @@ -2344,25 +2197,170 @@ return; } -static void __init -link_modules(struct net_device *dev, struct net_device *tmp) +/* +** PCI bus I/O device probe +** NB: PCI I/O accesses and Bus Mastering are enabled by the PCI BIOS, not +** the driver. Some PCI BIOS's, pre V2.1, need the slot + features to be +** enabled by the user first in the set up utility. Hence we just check for +** enabled features and silently ignore the card if they're not. +** +** STOP PRESS: Some BIOS's __require__ the driver to enable the bus mastering +** bit. Here, check for I/O accesses and then set BM. If you put the card in +** a non BM slot, you're on your own (and complain to the PC vendor that your +** PC doesn't conform to the PCI standard)! +** +** This function is only compatible with the *latest* 2.1.x kernels. For 2.0.x +** kernels use the V0.535[n] drivers. +*/ + +static int __init de4x5_pci_probe (struct pci_dev *pdev, + const struct pci_device_id *ent) { - struct net_device *p=dev; + u_char pb, pbus = 0, dev_num, dnum = 0, timer; + u_short vendor, status; + u_int irq = 0, device; + u_long iobase = 0; /* Clear upper 32 bits in Alphas */ + int error; + struct net_device *dev; + struct de4x5_private *lp; - if (p) { - while (((struct de4x5_private *)(p->priv))->next_module) { - p = ((struct de4x5_private *)(p->priv))->next_module; + dev_num = PCI_SLOT(pdev->devfn); + pb = pdev->bus->number; + + if (io) { /* probe a single PCI device */ + pbus = (u_short)(io >> 8); + dnum = (u_short)(io & 0xff); + if ((pbus != pb) || (dnum != dev_num)) + return -ENODEV; } - if (dev != tmp) { - ((struct de4x5_private *)(p->priv))->next_module = tmp; - } else { - ((struct de4x5_private *)(p->priv))->next_module = NULL; + vendor = pdev->vendor; + device = pdev->device << 8; + if (!(is_DC21040 || is_DC21041 || is_DC21140 || is_DC2114x)) + return -ENODEV; + + /* Ok, the device seems to be for us. */ + if (!(dev = alloc_etherdev (sizeof (struct de4x5_private)))) + return -ENOMEM; + + lp = dev->priv; + lp->bus = PCI; + lp->bus_num = 0; + + /* Search for an SROM on this bus */ + if (lp->bus_num != pb) { + lp->bus_num = pb; + srom_search(dev, pdev); } - } - return; -} + /* Get the chip configuration revision register */ + pci_read_config_dword(pdev, PCI_REVISION_ID, &lp->cfrv); + + /* Set the device number information */ + lp->device = dev_num; + lp->bus_num = pb; + + /* Set the chipset information */ + if (is_DC2114x) { + device = ((lp->cfrv & CFRV_RN) < DC2114x_BRK ? DC21142 : DC21143); + } + lp->chipset = device; + + /* Get the board I/O address (64 bits on sparc64) */ + iobase = pci_resource_start(pdev, 0); + + /* Fetch the IRQ to be used */ + irq = pdev->irq; + if ((irq == 0) || (irq == 0xff) || ((int)irq == -1)) { + error = -ENODEV; + goto free_dev; + } + + /* Check if I/O accesses and Bus Mastering are enabled */ + pci_read_config_word(pdev, PCI_COMMAND, &status); +#ifdef __powerpc__ + if (!(status & PCI_COMMAND_IO)) { + status |= PCI_COMMAND_IO; + pci_write_config_word(pdev, PCI_COMMAND, status); + pci_read_config_word(pdev, PCI_COMMAND, &status); + } +#endif /* __powerpc__ */ + if (!(status & PCI_COMMAND_IO)) { + error = -ENODEV; + goto free_dev; + } + + if (!(status & PCI_COMMAND_MASTER)) { + status |= PCI_COMMAND_MASTER; + pci_write_config_word(pdev, PCI_COMMAND, status); + pci_read_config_word(pdev, PCI_COMMAND, &status); + } + if (!(status & PCI_COMMAND_MASTER)) { + error = -ENODEV; + goto free_dev; + } + + /* Check the latency timer for values >= 0x60 */ + pci_read_config_byte(pdev, PCI_LATENCY_TIMER, &timer); + if (timer < 0x60) { + pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 0x60); + } + + DevicePresent(dev, DE4X5_APROM); + + if (!request_region (iobase, DE4X5_PCI_TOTAL_SIZE, "de4x5")) { + error = -EBUSY; + goto free_dev; + } + + dev->irq = irq; + + if ((error = de4x5_hw_init(dev, iobase, &pdev->dev))) { + goto release; + } + + return 0; + + release: + release_region (iobase, DE4X5_PCI_TOTAL_SIZE); + free_dev: + free_netdev (dev); + return error; +} + +static void __devexit de4x5_pci_remove (struct pci_dev *pdev) +{ + struct net_device *dev; + u_long iobase; + + dev = pdev->dev.driver_data; + iobase = dev->base_addr; + + unregister_netdev (dev); + free_netdev (dev); + release_region (iobase, DE4X5_PCI_TOTAL_SIZE); +} + +static struct pci_device_id de4x5_pci_tbl[] = { + { PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_TULIP, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, + { PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_TULIP_PLUS, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, 1 }, + { PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_TULIP_FAST, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, 2 }, + { PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_21142, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, 3 }, + { }, +}; + +static struct pci_driver de4x5_pci_driver = { + .name = "de4x5", + .id_table = de4x5_pci_tbl, + .probe = de4x5_pci_probe, + .remove = __devexit_p (de4x5_pci_remove), +}; + +#endif /* ** Auto configure the media here rather than setting the port at compile @@ -3945,34 +3943,20 @@ ** Look for a particular board name in the EISA configuration space */ static int -EISA_signature(char *name, s32 eisa_id) +EISA_signature(char *name, struct device *device) { - static c_char *signatures[] = DE4X5_SIGNATURE; - char ManCode[DE4X5_STRLEN]; - union { - s32 ID; - char Id[4]; - } Eisa; - int i, status = 0, siglen = sizeof(signatures)/sizeof(c_char *); - + int i, status = 0, siglen = sizeof(de4x5_signatures)/sizeof(c_char *); + struct eisa_device *edev; + *name = '\0'; - Eisa.ID = inl(eisa_id); - - ManCode[0]=(((Eisa.Id[0]>>2)&0x1f)+0x40); - ManCode[1]=(((Eisa.Id[1]&0xe0)>>5)+((Eisa.Id[0]&0x03)<<3)+0x40); - ManCode[2]=(((Eisa.Id[2]>>4)&0x0f)+0x30); - ManCode[3]=((Eisa.Id[2]&0x0f)+0x30); - ManCode[4]=(((Eisa.Id[3]>>4)&0x0f)+0x30); - ManCode[5]='\0'; - - for (i=0;iid.driver_data; + + if (i >= 0 && i < siglen) { + strcpy (name, de4x5_signatures[i]); status = 1; - break; - } } - + return status; /* return the device name string */ } @@ -3980,9 +3964,8 @@ ** Look for a particular board name in the PCI configuration space */ static int -PCI_signature(char *name, struct de4x5_bus_type *lp) +PCI_signature(char *name, struct de4x5_private *lp) { - static c_char *de4x5_signatures[] = DE4X5_SIGNATURE; int i, status = 0, siglen = sizeof(de4x5_signatures)/sizeof(c_char *); if (lp->chipset == DC21040) { @@ -4008,10 +3991,10 @@ ))))))); } if (lp->chipset != DC21041) { - useSROM = TRUE; /* card is not recognisably DEC */ + lp->useSROM = TRUE; /* card is not recognisably DEC */ } } else if ((lp->chipset & ~0x00ff) == DC2114x) { - useSROM = TRUE; + lp->useSROM = TRUE; } return status; @@ -4026,10 +4009,10 @@ ** be fixed up later). */ static void -DevicePresent(u_long aprom_addr) +DevicePresent(struct net_device *dev, u_long aprom_addr) { int i, j=0; - struct de4x5_bus_type *lp = &bus; + struct de4x5_private *lp = (struct de4x5_private *) dev->priv; if (lp->chipset == DC21040) { if (lp->bus == EISA) { @@ -4110,7 +4093,7 @@ u_long iobase = dev->base_addr; int broken, i, k, tmp, status = 0; u_short j,chksum; - struct de4x5_bus_type *lp = &bus; + struct de4x5_private *lp = dev->priv; broken = de4x5_bad_srom(lp); @@ -4191,7 +4174,7 @@ ** didn't seem to work here...? */ static int -de4x5_bad_srom(struct de4x5_bus_type *lp) +de4x5_bad_srom(struct de4x5_private *lp) { int i, status = 0; @@ -4225,14 +4208,14 @@ static void srom_repair(struct net_device *dev, int card) { - struct de4x5_bus_type *lp = &bus; + struct de4x5_private *lp = dev->priv; switch(card) { case SMC: - memset((char *)&bus.srom, 0, sizeof(struct de4x5_srom)); + memset((char *)&lp->srom, 0, sizeof(struct de4x5_srom)); memcpy(lp->srom.ieee_addr, (char *)dev->dev_addr, ETH_ALEN); memcpy(lp->srom.info, (char *)&srom_repair_info[SMC-1], 100); - useSROM = TRUE; + lp->useSROM = TRUE; break; } @@ -4246,7 +4229,7 @@ static int test_bad_enet(struct net_device *dev, int status) { - struct de4x5_bus_type *lp = &bus; + struct de4x5_private *lp = dev->priv; int i, tmp; for (tmp=0,i=0; idev_addr[i]; @@ -4279,7 +4262,7 @@ ** List of board exceptions with correctly wired IRQs */ static int -an_exception(struct de4x5_bus_type *lp) +an_exception(struct de4x5_private *lp) { if ((*(u_short *)lp->srom.sub_vendor_id == 0x00c0) && (*(u_short *)lp->srom.sub_system_id == 0x95e0)) { @@ -5312,19 +5295,20 @@ break; } } else { + struct pci_dev *pdev = to_pci_dev (lp->gendev); switch(state) { case WAKEUP: - pci_write_config_byte(lp->pdev, PCI_CFDA_PSM, WAKEUP); + pci_write_config_byte(pdev, PCI_CFDA_PSM, WAKEUP); mdelay(10); break; case SNOOZE: - pci_write_config_byte(lp->pdev, PCI_CFDA_PSM, SNOOZE); + pci_write_config_byte(pdev, PCI_CFDA_PSM, SNOOZE); break; case SLEEP: outl(0, DE4X5_SICR); - pci_write_config_byte(lp->pdev, PCI_CFDA_PSM, SLEEP); + pci_write_config_byte(pdev, PCI_CFDA_PSM, SLEEP); break; } } @@ -5348,9 +5332,6 @@ t = *q; *q = '\0'; -#if !defined(__sparc_v9__) && !defined(__powerpc__) && !defined(__alpha__) - if (strstr(p, "force_eisa") || strstr(p, "FORCE_EISA")) forceEISA = 1; -#endif if (strstr(p, "fdx") || strstr(p, "FDX")) lp->params.fdx = 1; if (strstr(p, "autosense") || strstr(p, "AUTOSENSE")) { @@ -5758,146 +5739,29 @@ return status; } -#ifdef MODULE -/* -** Note now that module autoprobing is allowed under EISA and PCI. The -** IRQ lines will not be auto-detected; instead I'll rely on the BIOSes -** to "do the right thing". -*/ -#define LP(a) ((struct de4x5_private *)(a)) -static struct net_device *mdev = NULL; -static int io=0x0;/* EDIT THIS LINE FOR YOUR CONFIGURATION IF NEEDED */ -MODULE_PARM(io, "i"); -MODULE_PARM_DESC(io, "de4x5 I/O base address"); - -int -init_module(void) +static int __init de4x5_module_init (void) { - int i, num, status = -EIO; - struct net_device *p; + int err = 0; - num = count_adapters(); - - for (i=0; ipriv; - if (lp) { - release_region(p->base_addr, (lp->bus == PCI ? - DE4X5_PCI_TOTAL_SIZE : - DE4X5_EISA_TOTAL_SIZE)); - if (lp->cache.priv) { /* Private area allocated? */ - kfree(lp->cache.priv); /* Free the private area */ - } - if (lp->rx_ring) { - pci_free_consistent(lp->pdev, lp->dma_size, lp->rx_ring, - lp->dma_rings); - } - } - kfree(p); - } else { - status = 0; /* At least one adapter will work */ - lastModule = p; - } - } - - return status; -} - -void -cleanup_module(void) -{ - while (mdev != NULL) { - mdev = unlink_modules(mdev); - } - - return; -} - -static struct net_device * -unlink_modules(struct net_device *p) -{ - struct net_device *next = NULL; - - if (p->priv) { /* Private areas allocated? */ - struct de4x5_private *lp = (struct de4x5_private *)p->priv; - - next = lp->next_module; - if (lp->rx_ring) { - pci_free_consistent(lp->pdev, lp->dma_size, lp->rx_ring, - lp->dma_rings); - } - release_region(p->base_addr, (lp->bus == PCI ? - DE4X5_PCI_TOTAL_SIZE : - DE4X5_EISA_TOTAL_SIZE)); - kfree(lp->cache.priv); /* Free the private area */ - } - unregister_netdev(p); - free_netdev(p); /* Free the device structure */ - - return next; -} - -static int -count_adapters(void) -{ - int i, j=0; - u_short vendor; - u_int class = DE4X5_CLASS_CODE; - u_int device; - -#if !defined(__sparc_v9__) && !defined(__powerpc__) && !defined(__alpha__) - char name[DE4X5_STRLEN]; - u_long iobase = 0x1000; - - for (i=1; ivendor; - device = pdev->device << 8; - if (is_DC21040 || is_DC21041 || is_DC21140 || is_DC2114x) j++; - } - - return j; + return err; } -/* -** If at end of eth device list and can't use current entry, malloc -** one up. If memory could not be allocated, print an error message. -*/ -static struct net_device * __init -insert_device(struct net_device *dev, u_long iobase, int (*init)(struct net_device *)) +static void __exit de4x5_module_exit (void) { - struct net_device *new; - - new = (struct net_device *)kmalloc(sizeof(struct net_device), GFP_KERNEL); - if (new == NULL) { - printk("de4x5.c: Device not initialised, insufficient memory\n"); - return NULL; - } else { - memset((char *)new, 0, sizeof(struct net_device)); - new->base_addr = iobase; /* assign the io address */ - new->init = init; /* initialisation routine */ - } - - return new; +#if CONFIG_PCI + pci_unregister_driver (&de4x5_pci_driver); +#endif +#ifdef CONFIG_EISA + eisa_driver_unregister (&de4x5_eisa_driver); +#endif } -#endif /* MODULE */ - - -/* - * Local variables: - * - * Delete -DMODVERSIONS below if you didn't define this in your kernel - * - * compile-command: "gcc -D__KERNEL__ -DMODULE -I/linux/include -Wall -Wstrict-prototypes -fomit-frame-pointer -fno-strength-reduce -malign-loops=2 -malign-jumps=2 -malign-functions=2 -O2 -m486 -DMODVERSIONS -include /linux/include/linux/modversions.h -c de4x5.c" - * End: - */ +module_init (de4x5_module_init); +module_exit (de4x5_module_exit); diff -Nru a/drivers/net/tulip/dmfe.c b/drivers/net/tulip/dmfe.c --- a/drivers/net/tulip/dmfe.c Thu Sep 4 15:38:44 2003 +++ b/drivers/net/tulip/dmfe.c Thu Sep 4 15:38:44 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 Thu Sep 4 15:38:30 2003 +++ b/drivers/net/tulip/winbond-840.c Thu Sep 4 15:38:30 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 Thu Sep 4 15:38:42 2003 +++ b/drivers/net/tulip/xircom_cb.c Thu Sep 4 15:38:42 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/tun.c b/drivers/net/tun.c --- a/drivers/net/tun.c Thu Sep 4 15:38:33 2003 +++ b/drivers/net/tun.c Thu Sep 4 15:38:33 2003 @@ -640,3 +640,4 @@ module_init(tun_init); module_exit(tun_cleanup); MODULE_LICENSE("GPL"); +MODULE_ALIAS_MISCDEV(TUN_MINOR); diff -Nru a/drivers/net/typhoon.c b/drivers/net/typhoon.c --- a/drivers/net/typhoon.c Thu Sep 4 15:38:38 2003 +++ b/drivers/net/typhoon.c Thu Sep 4 15:38:38 2003 @@ -2455,7 +2455,7 @@ error_out_regions: pci_release_regions(pdev); error_out_dev: - kfree(dev); + free_netdev(dev); error_out: return err; } diff -Nru a/drivers/net/via-rhine.c b/drivers/net/via-rhine.c --- a/drivers/net/via-rhine.c Thu Sep 4 15:38:46 2003 +++ b/drivers/net/via-rhine.c Thu Sep 4 15:38:46 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) @@ -866,7 +868,7 @@ #endif pci_release_regions(pdev); err_out_free_netdev: - kfree (dev); + free_netdev (dev); err_out: return -ENODEV; } @@ -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 Thu Sep 4 15:38:31 2003 +++ b/drivers/net/wan/Kconfig Thu Sep 4 15:38:31 2003 @@ -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 Thu Sep 4 15:38:29 2003 +++ b/drivers/net/wan/cosa.c Thu Sep 4 15:38:29 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 Thu Sep 4 15:38:37 2003 +++ b/drivers/net/wan/cycx_drv.c Thu Sep 4 15:38:37 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 Thu Sep 4 15:38:33 2003 +++ b/drivers/net/wan/cycx_main.c Thu Sep 4 15:38:33 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/wan/dlci.c b/drivers/net/wan/dlci.c --- a/drivers/net/wan/dlci.c Thu Sep 4 15:38:34 2003 +++ b/drivers/net/wan/dlci.c Thu Sep 4 15:38:34 2003 @@ -55,14 +55,13 @@ #include #include -static const char devname[] = "dlci"; static const char version[] = "DLCI driver v0.35, 4 Jan 1997, mike.mclagan@linux.org"; -static struct net_device *open_dev[CONFIG_DLCI_COUNT]; - +static LIST_HEAD(dlci_devs); +static spinlock_t dlci_dev_lock = SPIN_LOCK_UNLOCKED; static char *basename[16]; -int dlci_init(struct net_device *dev); +static void dlci_setup(struct net_device *); /* allow FRAD's to register their name as a valid FRAD */ int register_frad(const char *name) @@ -115,6 +114,7 @@ return(0); } +EXPORT_SYMBOL(unregister_frad); /* * these encapsulate the RFC 1490 requirements as well as @@ -168,6 +168,14 @@ int process, header; dlp = dev->priv; + if (!pskb_may_pull(skb, sizeof(*hdr))) { + printk(KERN_NOTICE "%s: invalid data no header\n", + dev->name); + dlp->stats.rx_errors++; + kfree_skb(skb); + return; + } + hdr = (struct frhdr *) skb->data; process = 0; header = 0; @@ -277,7 +285,7 @@ return(ret); } -int dlci_config(struct net_device *dev, struct dlci_conf *conf, int get) +static int dlci_config(struct net_device *dev, struct dlci_conf *conf, int get) { struct dlci_conf config; struct dlci_local *dlp; @@ -311,7 +319,7 @@ return(0); } -int dlci_dev_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) +static int dlci_dev_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) { struct dlci_local *dlp; @@ -401,21 +409,23 @@ return(&dlp->stats); } -int dlci_add(struct dlci_add *dlci) +static int dlci_add(struct dlci_add *dlci) { - struct net_device *master, *slave; + struct net_device *master, *slave; struct dlci_local *dlp; struct frad_local *flp; int err, i; - char buf[10]; + /* validate slave device */ - slave = __dev_get_by_name(dlci->devname); + slave = dev_get_by_name(dlci->devname); if (!slave) return(-ENODEV); - if (slave->type != ARPHRD_FRAD) + if (slave->type != ARPHRD_FRAD) { + dev_put(slave); return(-EINVAL); + } /* check for registration */ for (i=0;idevname) > strlen(basename[i]))) break; - if (i == sizeof(basename) / sizeof(char *)) + if (i == sizeof(basename) / sizeof(char *)) { + dev_put(slave); return(-EINVAL); - - /* check for too many open devices : should this be dynamic ? */ - for(i=0;iname, buf); - master->init = dlci_init; - master->flags = 0; + } err = register_netdev(master); - if (err < 0) - { + if (err < 0) { + dev_put(slave); kfree(master); return(err); } @@ -459,64 +458,65 @@ dlp = (struct dlci_local *) master->priv; dlp->slave = slave; + dlp->master = master; flp = slave->priv; err = flp ? (*flp->assoc)(slave, master) : -EINVAL; if (err < 0) { unregister_netdev(master); - kfree(master->priv); - kfree(master); + dev_put(slave); + free_netdev(master); return(err); } - strcpy(dlci->devname, buf); - open_dev[i] = master; - MOD_INC_USE_COUNT; + strcpy(dlci->devname, master->name); + + spin_lock_bh(&dlci_dev_lock); + list_add(&dlp->list, &dlci_devs); + spin_unlock_bh(&dlci_dev_lock); + return(0); } -int dlci_del(struct dlci_add *dlci) +static int dlci_del(struct dlci_add *dlci) { struct dlci_local *dlp; struct frad_local *flp; - struct net_device *master, *slave; - int i, err; + struct net_device *master, *slave; + int err; /* validate slave device */ master = __dev_get_by_name(dlci->devname); if (!master) return(-ENODEV); - if (netif_running(master)) + if (netif_running(master)) { return(-EBUSY); + } dlp = master->priv; slave = dlp->slave; flp = slave->priv; err = (*flp->deassoc)(slave, master); - if (err) + if (err) return(err); - unregister_netdev(master); - for(i=0;ilist); + spin_unlock_bh(&dlci_dev_lock); - if (ipriv); + dev_put(slave); free_netdev(master); - MOD_DEC_USE_COUNT; - return(0); } -int dlci_ioctl(unsigned int cmd, void *arg) +static int dlci_ioctl(unsigned int cmd, void *arg) { struct dlci_add add; int err; @@ -548,16 +548,9 @@ return(err); } -int dlci_init(struct net_device *dev) +static void dlci_setup(struct net_device *dev) { - struct dlci_local *dlp; - - dev->priv = kmalloc(sizeof(struct dlci_local), GFP_KERNEL); - if (!dev->priv) - return(-ENOMEM); - - memset(dev->priv, 0, sizeof(struct dlci_local)); - dlp = dev->priv; + struct dlci_local *dlp = dev->priv; dev->flags = 0; dev->open = dlci_open; @@ -573,9 +566,7 @@ dev->type = ARPHRD_DLCI; dev->hard_header_len = sizeof(struct frhdr); dev->addr_len = sizeof(short); - memset(dev->dev_addr, 0, sizeof(dev->dev_addr)); - return(0); } int __init init_dlci(void) @@ -584,9 +575,6 @@ dlci_ioctl_set(dlci_ioctl); printk("%s.\n", version); - - for(i=0;imaster); + dev_put(dlp->slave); + free_netdev(dlp->master); + } + } module_init(init_dlci); diff -Nru a/drivers/net/wan/sbni.c b/drivers/net/wan/sbni.c --- a/drivers/net/wan/sbni.c Thu Sep 4 15:38:32 2003 +++ b/drivers/net/wan/sbni.c Thu Sep 4 15:38:32 2003 @@ -140,6 +140,7 @@ static void timeout_change_level( struct net_device * ); static u32 calc_crc32( u32, u8 *, u32 ); static struct sk_buff * get_rx_buf( struct net_device * ); +static int sbni_init( struct net_device * ); #ifdef CONFIG_SBNI_MULTILINE static int enslave( struct net_device *, struct net_device * ); @@ -205,23 +206,44 @@ } } - -int __init -sbni_probe( struct net_device *dev ) +static void __init sbni_devsetup(struct net_device *dev) { - int i; + ether_setup( dev ); + dev->init = &sbni_init; + dev->open = &sbni_open; + dev->stop = &sbni_close; + dev->hard_start_xmit = &sbni_start_xmit; + dev->get_stats = &sbni_get_stats; + dev->set_multicast_list = &set_multicast_list; + dev->do_ioctl = &sbni_ioctl; + SET_MODULE_OWNER( dev ); +} + +int __init sbni_probe(void) +{ + struct net_device *dev; static unsigned version_printed __initdata = 0; + if( version_printed++ == 0 ) printk( KERN_INFO "%s", version ); - if( !dev ) { /* simple sanity check */ - printk( KERN_ERR "sbni: NULL device!\n" ); - return -ENODEV; + dev = alloc_netdev(sizeof(struct net_local), "sbni%d", sbni_devsetup); + if (!dev) + return -ENOMEM; + + netdev_boot_setup_check(dev); + + if (register_netdev(dev)) { + kfree(dev); + return -ENODEV; } + return 0; +} - SET_MODULE_OWNER( dev ); - +static int __init sbni_init(struct net_device *dev) +{ + int i; if( dev->base_addr ) return sbni_isa_probe( dev ); /* otherwise we have to perform search our adapter */ @@ -338,7 +360,7 @@ dev->base_addr = ioaddr; /* Allocate dev->priv and fill in sbni-specific dev fields. */ - nl = (struct net_local *) kmalloc(sizeof(struct net_local), GFP_KERNEL); + nl = dev->priv; if( !nl ) { printk( KERN_ERR "%s: unable to get memory!\n", dev->name ); release_region( ioaddr, SBNI_IO_EXTENT ); @@ -389,14 +411,6 @@ nl->link = NULL; #endif - dev->open = &sbni_open; - dev->stop = &sbni_close; - dev->hard_start_xmit = &sbni_start_xmit; - dev->get_stats = &sbni_get_stats; - dev->set_multicast_list = &set_multicast_list; - dev->do_ioctl = &sbni_ioctl; - ether_setup( dev ); - sbni_cards[ num++ ] = dev; return dev; } @@ -1478,15 +1492,15 @@ struct net_device *dev; while( num < SBNI_MAX_NUM_CARDS ) { - if( !(dev = kmalloc(sizeof(struct net_device), GFP_KERNEL)) ){ + dev = alloc_netdev(sizeof(struct net_local), + "sbni%d", sbni_devsetup); + if( !dev) { printk( KERN_ERR "sbni: unable to allocate device!\n" ); return -ENOMEM; } - memset( dev, 0, sizeof(struct net_device) ); sprintf( dev->name, "sbni%d", num ); - dev->init = sbni_probe; if( register_netdev( dev ) ) { kfree( dev ); break; @@ -1506,7 +1520,6 @@ if( (dev = sbni_cards[ num ]) != NULL ) { unregister_netdev( dev ); release_region( dev->base_addr, SBNI_IO_EXTENT ); - kfree( dev->priv ); free_netdev( dev ); } } diff -Nru a/drivers/net/wan/sdla.c b/drivers/net/wan/sdla.c --- a/drivers/net/wan/sdla.c Thu Sep 4 15:38:48 2003 +++ b/drivers/net/wan/sdla.c Thu Sep 4 15:38:48 2003 @@ -71,6 +71,8 @@ 0xD0000, 0xD2000, 0xD4000, 0xD6000, 0xD8000, 0xDA000, 0xDC000, 0xDE000, 0xE0000, 0xE2000, 0xE4000, 0xE6000, 0xE8000, 0xEA000, 0xEC000, 0xEE000}; +static spinlock_t sdla_lock = SPIN_LOCK_UNLOCKED; + /********************************************************* * * these are the core routines that access the card itself @@ -79,10 +81,10 @@ #define SDLA_WINDOW(dev,addr) outb((((addr) >> 13) & 0x1F), (dev)->base_addr + SDLA_REG_Z80_WINDOW) -static void sdla_read(struct net_device *dev, int addr, void *buf, short len) +static void __sdla_read(struct net_device *dev, int addr, void *buf, short len) { - unsigned long flags; - char *temp, *base; + char *temp; + const void *base; int offset, bytes; temp = buf; @@ -90,13 +92,10 @@ { offset = addr & SDLA_ADDR_MASK; bytes = offset + len > SDLA_WINDOW_SIZE ? SDLA_WINDOW_SIZE - offset : len; - base = (void *) (dev->mem_start + offset); + base = (const void *) (dev->mem_start + offset); - save_flags(flags); - cli(); SDLA_WINDOW(dev, addr); memcpy(temp, base, bytes); - restore_flags(flags); addr += bytes; temp += bytes; @@ -104,10 +103,19 @@ } } -static void sdla_write(struct net_device *dev, int addr, void *buf, short len) +static void sdla_read(struct net_device *dev, int addr, void *buf, short len) { unsigned long flags; - char *temp, *base; + spin_lock_irqsave(&sdla_lock, flags); + __sdla_read(dev, addr, buf, len); + spin_unlock_irqrestore(&sdla_lock, flags); +} + +static void __sdla_write(struct net_device *dev, int addr, + const void *buf, short len) +{ + const char *temp; + void *base; int offset, bytes; temp = buf; @@ -116,17 +124,27 @@ offset = addr & SDLA_ADDR_MASK; bytes = offset + len > SDLA_WINDOW_SIZE ? SDLA_WINDOW_SIZE - offset : len; base = (void *) (dev->mem_start + offset); - save_flags(flags); - cli(); + SDLA_WINDOW(dev, addr); memcpy(base, temp, bytes); - restore_flags(flags); + addr += bytes; temp += bytes; len -= bytes; } } +static void sdla_write(struct net_device *dev, int addr, + const void *buf, short len) +{ + unsigned long flags; + + spin_lock_irqsave(&sdla_lock, flags); + __sdla_write(dev, addr, buf, len); + spin_unlock_irqrestore(&sdla_lock, flags); +} + + static void sdla_clear(struct net_device *dev) { unsigned long flags; @@ -138,8 +156,7 @@ bytes = SDLA_WINDOW_SIZE; base = (void *) dev->mem_start; - save_flags(flags); - cli(); + spin_lock_irqsave(&sdla_lock, flags); while(len) { SDLA_WINDOW(dev, addr); @@ -148,7 +165,8 @@ addr += bytes; len -= bytes; } - restore_flags(flags); + spin_unlock_irqrestore(&sdla_lock, flags); + } static char sdla_byte(struct net_device *dev, int addr) @@ -158,11 +176,10 @@ temp = (void *) (dev->mem_start + (addr & SDLA_ADDR_MASK)); - save_flags(flags); - cli(); + spin_lock_irqsave(&sdla_lock, flags); SDLA_WINDOW(dev, addr); byte = *temp; - restore_flags(flags); + spin_unlock_irqrestore(&sdla_lock, flags); return(byte); } @@ -414,7 +431,8 @@ struct frad_local *flp; struct sdla_cmd *cmd_buf; unsigned long pflags; - int jiffs, ret, waiting, len; + unsigned long jiffs; + int ret, waiting, len; long window; flp = dev->priv; @@ -423,8 +441,8 @@ ret = 0; len = 0; jiffs = jiffies + HZ; /* 1 second is plenty */ - save_flags(pflags); - cli(); + + spin_lock_irqsave(&sdla_lock, pflags); SDLA_WINDOW(dev, window); cmd_buf->cmd = cmd; cmd_buf->dlci = dlci; @@ -436,7 +454,7 @@ cmd_buf->length = inlen; cmd_buf->opp_flag = 1; - restore_flags(pflags); + spin_unlock_irqrestore(&sdla_lock, pflags); waiting = 1; len = 0; @@ -444,18 +462,17 @@ { if (waiting++ % 3) { - save_flags(pflags); - cli(); + spin_lock_irqsave(&sdla_lock, pflags); SDLA_WINDOW(dev, window); waiting = ((volatile int)(cmd_buf->opp_flag)); - restore_flags(pflags); + spin_unlock_irqrestore(&sdla_lock, pflags); } } if (!waiting) { - save_flags(pflags); - cli(); + + spin_lock_irqsave(&sdla_lock, pflags); SDLA_WINDOW(dev, window); ret = cmd_buf->retval; len = cmd_buf->length; @@ -471,7 +488,7 @@ if (ret) memcpy(&status, cmd_buf->data, len > sizeof(status) ? sizeof(status) : len); - restore_flags(pflags); + spin_unlock_irqrestore(&sdla_lock, pflags); } else ret = SDLA_RET_TIMEOUT; @@ -555,7 +572,6 @@ if (i == CONFIG_DLCI_MAX) return(-EMLINK); /* #### Alan: Comments on this ?? */ - MOD_INC_USE_COUNT; flp->master[i] = master; flp->dlci[i] = -*(short *)(master->dev_addr); @@ -588,7 +604,6 @@ flp->master[i] = NULL; flp->dlci[i] = 0; - MOD_DEC_USE_COUNT; if (netif_running(slave)) { if (flp->config.station == FRAD_STATION_CPE) @@ -688,14 +703,14 @@ ret = sdla_cmd(dev, SDLA_INFORMATION_WRITE, *(short *)(skb->dev->dev_addr), 0, NULL, skb->len, &addr, &size); if (ret == SDLA_RET_OK) { - save_flags(flags); - cli(); + + spin_lock_irqsave(&sdla_lock, flags); SDLA_WINDOW(dev, addr); pbuf = (void *)(((int) dev->mem_start) + (addr & SDLA_ADDR_MASK)); - sdla_write(dev, pbuf->buf_addr, skb->data, skb->len); - SDLA_WINDOW(dev, addr); + __sdla_write(dev, pbuf->buf_addr, skb->data, skb->len); + SDLA_WINDOW(dev, addr); pbuf->opp_flag = 1; - restore_flags(flags); + spin_unlock_irqrestore(&sdla_lock, flags); } break; } @@ -753,8 +768,7 @@ pbufi = NULL; pbuf = NULL; - save_flags(flags); - cli(); + spin_lock_irqsave(&sdla_lock, flags); switch (flp->type) { @@ -821,7 +835,7 @@ case SDLA_S502A: case SDLA_S502E: if (success) - sdla_read(dev, SDLA_502_RCV_BUF + SDLA_502_DATA_OFS, skb_put(skb,len), len); + __sdla_read(dev, SDLA_502_RCV_BUF + SDLA_502_DATA_OFS, skb_put(skb,len), len); SDLA_WINDOW(dev, SDLA_502_RCV_BUF); cmd->opp_flag = 0; @@ -834,9 +848,9 @@ split = addr + len > buf_top + 1 ? len - (buf_top - addr + 1) : 0; len2 = len - split; - sdla_read(dev, addr, skb_put(skb, len2), len2); + __sdla_read(dev, addr, skb_put(skb, len2), len2); if (split) - sdla_read(dev, buf_base, skb_put(skb, split), split); + __sdla_read(dev, buf_base, skb_put(skb, split), split); } /* increment the buffer we're looking at */ @@ -853,7 +867,7 @@ (*dlp->receive)(skb, master); } - restore_flags(flags); + spin_unlock_irqrestore(&sdla_lock, flags); } static irqreturn_t sdla_isr(int irq, void *dev_id, struct pt_regs * regs) @@ -979,8 +993,6 @@ netif_stop_queue(dev); - MOD_DEC_USE_COUNT; - return(0); } @@ -1082,8 +1094,6 @@ netif_start_queue(dev); - MOD_INC_USE_COUNT; - return(0); } @@ -1614,19 +1624,30 @@ return(&flp->stats); } -int __init sdla_init(struct net_device *dev) +static void setup_sdla(struct net_device *dev) { + dev->flags = 0; + dev->type = 0xFFFF; + dev->hard_header_len = 0; + dev->addr_len = 0; + dev->mtu = SDLA_MAX_MTU; +} + +struct net_device * __init sdla_init(void) +{ + struct net_device *dev; struct frad_local *flp; + int err = -ENOMEM; - /* allocate the private data structure */ - flp = kmalloc(sizeof(struct frad_local), GFP_KERNEL); - if (!flp) - return(-ENOMEM); + dev = alloc_netdev(sizeof(struct frad_local), "sdla0", setup_sdla); + if (!dev) + goto out; - memset(flp, 0, sizeof(struct frad_local)); - dev->priv = flp; + SET_MODULE_OWNER(dev); + netdev_boot_setup_check(dev); + + flp = dev->priv; - dev->flags = 0; dev->open = sdla_open; dev->stop = sdla_close; dev->do_ioctl = sdla_ioctl; @@ -1635,12 +1656,6 @@ dev->hard_start_xmit = sdla_transmit; dev->change_mtu = sdla_change_mtu; - dev->type = 0xFFFF; - dev->hard_header_len = 0; - dev->addr_len = 0; - dev->mtu = SDLA_MAX_MTU; - SET_MODULE_OWNER(dev); - flp->activate = sdla_activate; flp->deactivate = sdla_deactivate; flp->assoc = sdla_assoc; @@ -1652,7 +1667,14 @@ flp->timer.data = (unsigned long) dev; flp->timer.function = sdla_poll; - return(0); + err = register_netdev(dev); + if (err) + goto out1; + return dev; +out1: + kfree(dev); +out: + return ERR_PTR(err); } int __init sdla_c_setup(void) @@ -1663,10 +1685,7 @@ } #ifdef MODULE -static struct net_device sdla0 = { - .name = "sdla0", - .init = sdla_init -}; +static struct net_device *sdla0; #endif /* MODULE */ static int __init init_sdla(void) @@ -1675,7 +1694,9 @@ sdla_c_setup(); #ifdef MODULE - result = register_netdev(&sdla0); + sdla0 = sdla_init(); + if (IS_ERR(sdla0)) + result = PTR_ERR(sdla0); #endif return result; } @@ -1683,11 +1704,10 @@ static void __exit exit_sdla(void) { #ifdef MODULE - unregister_netdev(&sdla0); - if (sdla0.priv) - kfree(sdla0.priv); - if (sdla0.irq) - free_irq(sdla0.irq, &sdla0); + unregister_netdev(sdla0); + if (sdla0->irq) + free_irq(sdla0->irq, sdla0); + free_netdev(sdla0); #endif } diff -Nru a/drivers/net/wireless/airo.c b/drivers/net/wireless/airo.c --- a/drivers/net/wireless/airo.c Thu Sep 4 15:38:29 2003 +++ b/drivers/net/wireless/airo.c Thu Sep 4 15:38:29 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,151 @@ 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"); - } + hdrlen = 16; + break; + case 8: + if ((fc&0x300)==0x300){ + hdrlen = 30; + break; + } + 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 (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; - 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); - } + len -= sizeof(micbuf); + skb_trim (skb, len + hdrlen); } - bap_read(apriv,buffer+ETH_ALEN,len,BAP0); + } +#endif + bap_read(apriv,buffer+ETH_ALEN,len,BAP0); #ifdef MICSUPPORT - if (decapsulate(apriv,&micbuf,(etherHead*)buffer,len)) { - dev_kfree_skb_irq (skb); - len = 0; - } + if (decapsulate(apriv,&micbuf,(etherHead*)buffer,len)) { +badmic: + dev_kfree_skb_irq (skb); +#else + if (0) { #endif +badrx: + OUT4500( apriv, EVACK, EV_RX); + goto exitrx; } } - 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 +2943,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 +2992,7 @@ memcpy(mySsid.ssids[i].ssid, ssids[i], mySsid.ssids[i].len); } + mySsid.len = sizeof(mySsid); } status = writeConfigRid(ai, 1); @@ -3692,6 +4170,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 +4636,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 +4654,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 +4677,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 +4743,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 +4764,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 +4821,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 +4931,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 +4950,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 +5007,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 +5044,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 +5067,7 @@ if((rthr < 0) || (rthr > 2312)) { return -EINVAL; } + readConfigRid(local, 1); local->config.rtsThres = rthr; local->need_commit = 1; @@ -4594,6 +5085,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 +5111,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 +5129,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 +5149,7 @@ struct airo_info *local = dev->priv; int commit = 1; + readConfigRid(local, 1); if ((local->config.rmode & 0xff) >= RXMODE_RFMON) commit = 2; @@ -4714,6 +5209,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 +5246,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 +5333,7 @@ if(!(cap_rid.softCap & 2)) { return -EOPNOTSUPP; } + readConfigRid(local, 1); /* Check encryption mode */ switch(local->config.authType) { case AUTH_ENCRYPT: @@ -4892,6 +5390,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 +5410,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 +5434,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 +5469,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 +5608,7 @@ { struct airo_info *local = dev->priv; + readConfigRid(local, 1); if (vwrq->disabled) { if ((local->config.rmode & 0xFF) >= RXMODE_RFMON) { return -EINVAL; @@ -5161,8 +5664,10 @@ char *extra) { struct airo_info *local = dev->priv; + int mode; - int mode = local->config.powerSaveMode; + readConfigRid(local, 1); + mode = local->config.powerSaveMode; if ((vwrq->disabled = (mode == POWERSAVE_CAM))) return 0; if ((vwrq->flags & IW_POWER_TYPE) == IW_POWER_TIMEOUT) { @@ -5191,6 +5696,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 +5714,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 +6524,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 +6614,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 +6642,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 +6663,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 +6736,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 Thu Sep 4 15:38:46 2003 +++ b/drivers/net/wireless/airport.c Thu Sep 4 15:38:46 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/hermes.h b/drivers/net/wireless/hermes.h --- a/drivers/net/wireless/hermes.h Thu Sep 4 15:38:29 2003 +++ b/drivers/net/wireless/hermes.h Thu Sep 4 15:38:29 2003 @@ -302,12 +302,14 @@ #define hermes_read_reg(hw, off) ((hw)->io_space ? \ inw((hw)->iobase + ( (off) << (hw)->reg_spacing )) : \ readw((hw)->iobase + ( (off) << (hw)->reg_spacing ))) -#define hermes_write_reg(hw, off, val) ((hw)->io_space ? \ - outw_p((val), (hw)->iobase + ( (off) << (hw)->reg_spacing )) : \ - writew((val), (hw)->iobase + ( (off) << (hw)->reg_spacing ))) - -#define hermes_read_regn(hw, name) (hermes_read_reg((hw), HERMES_##name)) -#define hermes_write_regn(hw, name, val) (hermes_write_reg((hw), HERMES_##name, (val))) +#define hermes_write_reg(hw, off, val) do { \ + if ((hw)->io_space) \ + outw_p((val), (hw)->iobase + ((off) << (hw)->reg_spacing)); \ + else \ + writew((val), (hw)->iobase + ((off) << (hw)->reg_spacing)); \ + } while (0) +#define hermes_read_regn(hw, name) hermes_read_reg((hw), HERMES_##name) +#define hermes_write_regn(hw, name, val) hermes_write_reg((hw), HERMES_##name, (val)) /* Function prototypes */ void hermes_struct_init(hermes_t *hw, ulong address, int io_space, int reg_spacing); diff -Nru a/drivers/net/wireless/ray_cs.c b/drivers/net/wireless/ray_cs.c --- a/drivers/net/wireless/ray_cs.c Thu Sep 4 15:38:32 2003 +++ b/drivers/net/wireless/ray_cs.c Thu Sep 4 15:38:32 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 Thu Sep 4 15:38:32 2003 +++ b/drivers/net/yellowfin.c Thu Sep 4 15:38:32 2003 @@ -577,7 +577,7 @@ #endif pci_release_regions(pdev); err_out_free_netdev: - kfree (dev); + free_netdev (dev); return -ENODEV; } @@ -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 Thu Sep 4 15:38:46 2003 +++ b/drivers/parport/parport_pc.c Thu Sep 4 15:38:46 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 Thu Sep 4 15:38:35 2003 +++ b/drivers/pci/pci.ids Thu Sep 4 15:38:35 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 Thu Sep 4 15:38:31 2003 +++ b/drivers/pcmcia/cistpl.c Thu Sep 4 15:38:31 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 Thu Sep 4 15:38:41 2003 +++ b/drivers/pcmcia/ds.c Thu Sep 4 15:38:41 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 Thu Sep 4 15:38:33 2003 +++ b/drivers/pcmcia/ricoh.h Thu Sep 4 15:38:33 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 Thu Sep 4 15:38:31 2003 +++ b/drivers/pcmcia/sa1111_generic.c Thu Sep 4 15:38:31 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 Thu Sep 4 15:38:32 2003 +++ b/drivers/pcmcia/ti113x.h Thu Sep 4 15:38:32 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 Thu Sep 4 15:38:47 2003 +++ b/drivers/pcmcia/topic.h Thu Sep 4 15:38:47 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 Thu Sep 4 15:38:37 2003 +++ b/drivers/pcmcia/yenta_socket.c Thu Sep 4 15:38:37 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 Thu Sep 4 15:38:31 2003 +++ b/drivers/pcmcia/yenta_socket.h Thu Sep 4 15:38:31 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 Thu Sep 4 15:38:42 2003 +++ b/drivers/s390/char/tape_char.c Thu Sep 4 15:38:42 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 Thu Sep 4 15:38:35 2003 +++ b/drivers/s390/char/tubio.h Thu Sep 4 15:38:35 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 Thu Sep 4 15:38:31 2003 +++ b/drivers/s390/net/cu3088.c Thu Sep 4 15:38:31 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 Thu Sep 4 15:38:48 2003 +++ b/drivers/s390/net/qeth.c Thu Sep 4 15:38:48 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 Thu Sep 4 15:38:29 2003 +++ b/drivers/sbus/char/bpp.c Thu Sep 4 15:38:29 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 Thu Sep 4 15:38:45 2003 +++ b/drivers/sbus/char/cpwatchdog.c Thu Sep 4 15:38:45 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 Thu Sep 4 15:38:40 2003 +++ b/drivers/sbus/char/display7seg.c Thu Sep 4 15:38:40 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 Thu Sep 4 15:38:31 2003 +++ b/drivers/sbus/char/rtc.c Thu Sep 4 15:38:31 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 Thu Sep 4 15:38:35 2003 +++ b/drivers/sbus/char/vfc_dev.c Thu Sep 4 15:38:35 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 Thu Sep 4 15:38:45 2003 +++ b/drivers/scsi/3w-xxxx.c Thu Sep 4 15:38:45 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 Thu Sep 4 15:38:30 2003 +++ b/drivers/scsi/3w-xxxx.h Thu Sep 4 15:38:30 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/53c700.c b/drivers/scsi/53c700.c --- a/drivers/scsi/53c700.c Thu Sep 4 15:38:30 2003 +++ b/drivers/scsi/53c700.c Thu Sep 4 15:38:30 2003 @@ -1758,7 +1758,7 @@ printk("53c700: scsi%d, command ", SCp->device->host->host_no); print_command(SCp->cmnd); #endif - if(SCp->device->tagged_supported && !SCp->device->tagged_queue + if(SCp->device->tagged_supported && !SCp->device->simple_tags && (hostdata->tag_negotiated &(1<device->id)) == 0 && NCR_700_is_flag_clear(SCp->device, NCR_700_DEV_BEGIN_TAG_QUEUEING)) { /* upper layer has indicated tags are supported. We don't diff -Nru a/drivers/scsi/AM53C974.c b/drivers/scsi/AM53C974.c --- a/drivers/scsi/AM53C974.c Thu Sep 4 15:38:33 2003 +++ b/drivers/scsi/AM53C974.c Thu Sep 4 15:38:33 2003 @@ -1231,8 +1231,8 @@ hostdata->sel_cmd = NULL; hostdata->selecting = 0; #ifdef SCSI2 - if (!hostdata->connected->device->tagged_queue) -#endif + if (!hostdata->conneted->device->simple_tags) +#else hostdata->busy[hostdata->connected->device->id] |= (1 << hostdata->connected->device->lun); /* very strange -- use_sg is sometimes nonzero for request sense commands !! */ if ((hostdata->connected->cmnd[0] == REQUEST_SENSE) && hostdata->connected->use_sg) { @@ -1811,7 +1811,7 @@ case HEAD_OF_QUEUE_TAG: case ORDERED_QUEUE_TAG: case SIMPLE_QUEUE_TAG: - cmd->device->tagged_queue = 0; + cmd->device->simple_tags = 0; hostdata->busy[cmd->device->id] |= (1 << cmd->device->lun); break; default: @@ -1958,7 +1958,7 @@ #endif #ifdef SCSI2 - if (cmd->device->tagged_queue && (tag != TAG_NONE)) { + if (cmd->device->simple_tags && (tag != TAG_NONE)) { tmp[1] = SIMPLE_QUEUE_TAG; if (tag == TAG_NEXT) { /* 0 is TAG_NONE, used to imply no tag for this command */ diff -Nru a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig --- a/drivers/scsi/Kconfig Thu Sep 4 15:38:44 2003 +++ b/drivers/scsi/Kconfig Thu Sep 4 15:38:44 2003 @@ -22,6 +22,17 @@ module if your root file system (the one containing the directory /) is located on a SCSI device. +config SCSI_PROC_FS + bool "legacy /proc/scsi/ support" + depends on SCSI + default y + ---help--- + This option enables support for the various files in + /proc/scsi. In Linux 2.6 this has been superceeded by + files in sysfs but many legacy applications rely on this. + + If unusure say Y. + comment "SCSI support type (disk, tape, CD-ROM)" depends on SCSI @@ -355,7 +366,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 +409,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 @@ -726,13 +737,13 @@ config SCSI_IPS tristate "IBM ServeRAID support" - depends on X86 && PCI && SCSI + depends on PCI && SCSI ---help--- This is support for the IBM ServeRAID hardware RAID controllers. See for more information. If this driver does not work correctly without modification please contact the author by email at - ipslinux@us.ibm.com. + ipslinux@adaptec.com. You can build this driver as a module ( = code which can be inserted in and removed from the running kernel whenever you want), @@ -742,7 +753,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 @@ -989,36 +1000,9 @@ Unless you have an NCR manufactured machine, the chances are that you do not have this SCSI card, so say N. -config SCSI_SYM53C8XX - tristate "SYM53C8XX SCSI support" - depends on PCI && SCSI_SYM53C8XX_2!=y && SCSI - ---help--- - This driver supports all the features of recent 53C8XX chips (used - in PCI SCSI controllers), notably the hardware phase mismatch - feature of the SYM53C896. - - Older versions of the 53C8XX chips are not supported by this - driver. If your system uses either a 810 rev. < 16, a 815, or a 825 - rev. < 16 PCI SCSI processor, you must use the generic NCR53C8XX - driver ("NCR53C8XX SCSI support" above) or configure both the - NCR53C8XX and this SYM53C8XX drivers either as module or linked to - the kernel image. - - When both drivers are linked into the kernel, the SYM53C8XX driver - is called first at initialization and you can use the 'excl=ioaddr' - driver boot option to exclude attachment of adapters by the - SYM53C8XX driver. For example, entering - 'sym53c8xx=excl:0xb400,excl=0xc000' at the lilo prompt prevents - adapters at io address 0xb400 and 0xc000 from being attached by the - SYM53C8XX driver, thus allowing the NCR53C8XX driver to attach them. - The 'excl' option is also supported by the NCR53C8XX driver. - - Please read for more - information. - config SCSI_NCR53C8XX_DEFAULT_TAGS int " default tagged command queue depth" - depends on (SCSI_SYM53C8XX || SCSI_ZALON || SCSI_NCR_Q720) + depends on SCSI_ZALON || SCSI_NCR_Q720 default "8" ---help--- "Tagged command queuing" is a feature of SCSI-2 which improves @@ -1044,7 +1028,7 @@ config SCSI_NCR53C8XX_MAX_TAGS int " maximum number of queued commands" - depends on (SCSI_SYM53C8XX || SCSI_ZALON || SCSI_NCR_Q720) + depends on SCSI_ZALON || SCSI_NCR_Q720 default "32" ---help--- This option allows you to specify the maximum number of commands @@ -1061,7 +1045,7 @@ config SCSI_NCR53C8XX_SYNC int " synchronous transfers frequency in MHz" - depends on (SCSI_SYM53C8XX || SCSI_ZALON || SCSI_NCR_Q720) + depends on SCSI_ZALON || SCSI_NCR_Q720 default "20" ---help--- The SCSI Parallel Interface-2 Standard defines 5 classes of transfer @@ -1095,7 +1079,7 @@ config SCSI_NCR53C8XX_PROFILE bool " enable profiling" - depends on (SCSI_SYM53C8XX || SCSI_ZALON || SCSI_NCR_Q720) + depends on SCSI_ZALON || SCSI_NCR_Q720 help This option allows you to enable profiling information gathering. These statistics are not very accurate due to the low frequency @@ -1104,34 +1088,9 @@ The normal answer therefore is N. -config SCSI_NCR53C8XX_IOMAPPED - bool " use normal IO" - depends on SCSI_SYM53C8XX && !(SCSI_ZALON || SCSI_NCR_Q720) - help - If you say Y here, the driver will use normal IO, as opposed to - memory mapped IO. Memory mapped IO has less latency than normal IO - and works for most Intel-based hardware. Under Linux/Alpha only - normal IO is currently supported by the driver and so, this option - has no effect on those systems. - - The normal answer therefore is N; try Y only if you encounter SCSI - related problems. - -config SCSI_NCR53C8XX_PQS_PDS - bool " include support for the NCR PQS/PDS SCSI card" - depends on SCSI_SYM53C8XX - help - Say Y here if you have a special SCSI adapter produced by NCR - corporation called a PCI Quad SCSI or PCI Dual SCSI. You do not need - this if you do not have one of these adapters. However, since this - device is detected as a specific PCI device, this option is quite - safe. - - The common answer here is N, but answering Y is safe. - config SCSI_NCR53C8XX_NO_DISCONNECT bool " not allow targets to disconnect" - depends on (SCSI_SYM53C8XX || SCSI_ZALON || SCSI_NCR_Q720) && SCSI_NCR53C8XX_DEFAULT_TAGS=0 + depends on (SCSI_ZALON || SCSI_NCR_Q720) && SCSI_NCR53C8XX_DEFAULT_TAGS=0 help This option is only provided for safety if you suspect some SCSI device of yours to not support properly the target-disconnect @@ -1139,29 +1098,9 @@ not allow targets to disconnect is not reasonable if there is more than 1 device on a SCSI bus. The normal answer therefore is N. -config SCSI_NCR53C8XX_SYMBIOS_COMPAT - bool " assume boards are SYMBIOS compatible (EXPERIMENTAL)" - depends on (SCSI_SYM53C8XX || SCSI_ZALON || SCSI_NCR_Q720 ) && EXPERIMENTAL - ---help--- - This option allows you to enable some features depending on GPIO - wiring. These General Purpose Input/Output pins can be used for - vendor specific features or implementation of the standard SYMBIOS - features. Genuine SYMBIOS controllers use GPIO0 in output for - controller LED and GPIO3 bit as a flag indicating - singled-ended/differential interface. The Tekram DC-390U/F boards - uses a different GPIO wiring. - - Your answer to this question is ignored if all your controllers have - NVRAM, since the driver is able to detect the board type from the - NVRAM format. - - If all the controllers in your system are genuine SYMBIOS boards or - use BIOS and drivers from SYMBIOS, you would want to say Y here, - otherwise N. N is the safe answer. - 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 +1128,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 +1141,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 @@ -1298,6 +1237,16 @@ The module will be called qla1280. If you want to compile it as a module, say M here and read . +config SCSI_QLOGIC_1280_PIO + bool "Use PIO instead of MMIO" if !X86_VISWS + depends on SCSI_QLOGIC_1280 + default y if X86_VISWS + help + This instructs the driver to use programmed I/O ports (PIO) instead + of PCI shared memory (MMIO). This can possibly solve some problems + in case your mainboard has memory consistency issues. If unsure, + say N. + config SCSI_QLOGICPTI tristate "PTI Qlogic, ISP Driver" depends on SBUS && SCSI @@ -1314,7 +1263,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 +1330,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/Makefile b/drivers/scsi/Makefile --- a/drivers/scsi/Makefile Thu Sep 4 15:38:42 2003 +++ b/drivers/scsi/Makefile Thu Sep 4 15:38:42 2003 @@ -126,7 +126,8 @@ scsicam.o scsi_error.o scsi_lib.o \ scsi_scan.o scsi_syms.o scsi_sysfs.o \ scsi_devinfo.o -scsi_mod-$(CONFIG_PROC_FS) += scsi_proc.o +scsi_mod-$(CONFIG_SYSCTL) += scsi_sysctl.o +scsi_mod-$(CONFIG_SCSI_PROC_FS) += scsi_proc.o scsi_mod-$(CONFIG_X86_PC9800) += scsi_pc98.o sd_mod-objs := sd.o diff -Nru a/drivers/scsi/NCR5380.c b/drivers/scsi/NCR5380.c --- a/drivers/scsi/NCR5380.c Thu Sep 4 15:38:30 2003 +++ b/drivers/scsi/NCR5380.c Thu Sep 4 15:38:31 2003 @@ -2512,7 +2512,7 @@ case HEAD_OF_QUEUE_TAG: case ORDERED_QUEUE_TAG: case SIMPLE_QUEUE_TAG: - cmd->device->tagged_queue = 0; + cmd->device->simple_tags = 0; hostdata->busy[cmd->device->id] |= (1 << cmd->device->lun); break; default: diff -Nru a/drivers/scsi/a2091.h b/drivers/scsi/a2091.h --- a/drivers/scsi/a2091.h Thu Sep 4 15:38:30 2003 +++ b/drivers/scsi/a2091.h Thu Sep 4 15:38:30 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 Thu Sep 4 15:38:30 2003 +++ b/drivers/scsi/a3000.h Thu Sep 4 15:38:30 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 Thu Sep 4 15:38:32 2003 +++ b/drivers/scsi/aacraid/linit.c Thu Sep 4 15:38:32 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 Thu Sep 4 15:38:31 2003 +++ b/drivers/scsi/advansys.c Thu Sep 4 15:38:31 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, @@ -6360,8 +6362,8 @@ } else { scsi_adjust_queue_depth(device, 0, device->host->cmd_per_lun); } - ASC_DBG3(1, "advansys_slave_configure: shp 0x%lx, id %d, depth %d\n", - (ulong) shp, device->id, device->queue_depth); + ASC_DBG4(1, "advansys_slave_configure: device 0x%lx, boardp 0x%lx, id %d, depth %d\n", + (ulong) device, (ulong) boardp, device->id, device->queue_depth); return 0; } @@ -9352,8 +9354,8 @@ printk("Scsi_Host at addr 0x%lx\n", (ulong) s); printk( -" next 0x%lx, host_busy %u, host_no %d, last_reset %d,\n", - (ulong) s->next, s->host_busy, s->host_no, +" host_busy %u, host_no %d, last_reset %d,\n", + s->host_busy, s->host_no, (unsigned) s->last_reset); #if ASC_LINUX_KERNEL24 @@ -9397,8 +9399,8 @@ printk( " host 0x%lx, device 0x%lx, target %u, lun %u, channel %u,\n", - (ulong) s->host, (ulong) s->device, s->target, s->lun, - s->channel); + (ulong) s->device->host, (ulong) s->device, s->device->id, s->device->lun, + s->device->channel); asc_prt_hex(" CDB", s->cmnd, s->cmd_len); diff -Nru a/drivers/scsi/aha1542.h b/drivers/scsi/aha1542.h --- a/drivers/scsi/aha1542.h Thu Sep 4 15:38:40 2003 +++ b/drivers/scsi/aha1542.h Thu Sep 4 15:38:40 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 Thu Sep 4 15:38:31 2003 +++ b/drivers/scsi/aic7xxx/aic79xx_osm_pci.c Thu Sep 4 15:38:31 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 Thu Sep 4 15:38:31 2003 +++ b/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c Thu Sep 4 15:38:31 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 Thu Sep 4 15:38:47 2003 +++ b/drivers/scsi/amiga7xx.h Thu Sep 4 15:38:47 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/arm/acornscsi.c b/drivers/scsi/arm/acornscsi.c --- a/drivers/scsi/arm/acornscsi.c Thu Sep 4 15:38:34 2003 +++ b/drivers/scsi/arm/acornscsi.c Thu Sep 4 15:38:34 2003 @@ -768,7 +768,7 @@ /* * tagged queueing - allocate a new tag to this command */ - if (SCpnt->device->tagged_queue) { + if (SCpnt->device->simple_tags) { SCpnt->device->current_tag += 1; if (SCpnt->device->current_tag == 0) SCpnt->device->current_tag = 1; @@ -1590,7 +1590,7 @@ */ printk(KERN_NOTICE "scsi%d.%c: disabling tagged queueing\n", host->host->host_no, acornscsi_target(host)); - host->SCpnt->device->tagged_queue = 0; + host->SCpnt->device->simple_tags = 0; set_bit(host->SCpnt->device->id * 8 + host->SCpnt->device->lun, host->busyluns); break; #endif @@ -2935,7 +2935,7 @@ p += sprintf(p, " %d/%d ", scd->id, scd->lun); if (scd->tagged_supported) p += sprintf(p, "%3sabled(%3d) ", - scd->tagged_queue ? "en" : "dis", + scd->simple_tags ? "en" : "dis", scd->current_tag); else p += sprintf(p, "unsupported "); diff -Nru a/drivers/scsi/arm/fas216.c b/drivers/scsi/arm/fas216.c --- a/drivers/scsi/arm/fas216.c Thu Sep 4 15:38:32 2003 +++ b/drivers/scsi/arm/fas216.c Thu Sep 4 15:38:32 2003 @@ -1819,7 +1819,7 @@ /* * tagged queuing - allocate a new tag to this command */ - if (SCpnt->device->tagged_queue && SCpnt->cmnd[0] != REQUEST_SENSE && + if (SCpnt->device->simple_tags && SCpnt->cmnd[0] != REQUEST_SENSE && SCpnt->cmnd[0] != INQUIRY) { SCpnt->device->current_tag += 1; if (SCpnt->device->current_tag == 0) @@ -3012,7 +3012,7 @@ p += sprintf(p, " %d/%d ", scd->id, scd->lun); if (scd->tagged_supported) p += sprintf(p, "%3sabled(%3d) ", - scd->tagged_queue ? "en" : "dis", + scd->simple_tags ? "en" : "dis", scd->current_tag); else p += sprintf(p, "unsupported "); diff -Nru a/drivers/scsi/atp870u.h b/drivers/scsi/atp870u.h --- a/drivers/scsi/atp870u.h Thu Sep 4 15:38:29 2003 +++ b/drivers/scsi/atp870u.h Thu Sep 4 15:38:29 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 Thu Sep 4 15:38:42 2003 +++ b/drivers/scsi/bvme6000.h Thu Sep 4 15:38:42 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/cpqfcTSinit.c b/drivers/scsi/cpqfcTSinit.c --- a/drivers/scsi/cpqfcTSinit.c Thu Sep 4 15:38:29 2003 +++ b/drivers/scsi/cpqfcTSinit.c Thu Sep 4 15:38:29 2003 @@ -603,7 +603,7 @@ return -ENOMEM; } // Now build a Scsi_Request to pass down... - ScsiPassThruReq = scsi_allocate_request(ScsiDev); + ScsiPassThruReq = scsi_allocate_request(ScsiDev, GFP_KERNEL); if (ScsiPassThruReq == NULL) { kfree(buf); return -ENOMEM; diff -Nru a/drivers/scsi/cpqfcTSworker.c b/drivers/scsi/cpqfcTSworker.c --- a/drivers/scsi/cpqfcTSworker.c Thu Sep 4 15:38:42 2003 +++ b/drivers/scsi/cpqfcTSworker.c Thu Sep 4 15:38:42 2003 @@ -2878,7 +2878,7 @@ } } -Done: +Done: ; } extern int is_private_data_of_cpqfc(CPQFCHBA *hba, void * pointer); diff -Nru a/drivers/scsi/dc395x.c b/drivers/scsi/dc395x.c --- a/drivers/scsi/dc395x.c Thu Sep 4 15:38:30 2003 +++ b/drivers/scsi/dc395x.c Thu Sep 4 15:38:30 2003 @@ -224,14 +224,14 @@ #define DC395x_SMP_IO_UNLOCK(dev,irq_flags) spin_unlock_irqrestore(((struct Scsi_Host*)dev)->host_lock,irq_flags) -#define DC395x_read8(acb,address) (u8)(inb(acb->IOPortBase + (address))) +#define DC395x_read8(acb,address) (u8)(inb(acb->io_port_base + (address))) #define DC395x_read8_(address, base) (u8)(inb((USHORT)(base) + (address))) -#define DC395x_read16(acb,address) (u16)(inw(acb->IOPortBase + (address))) -#define DC395x_read32(acb,address) (u32)(inl(acb->IOPortBase + (address))) -#define DC395x_write8(acb,address,value) outb((value), acb->IOPortBase + (address)) +#define DC395x_read16(acb,address) (u16)(inw(acb->io_port_base + (address))) +#define DC395x_read32(acb,address) (u32)(inl(acb->io_port_base + (address))) +#define DC395x_write8(acb,address,value) outb((value), acb->io_port_base + (address)) #define DC395x_write8_(address,value,base) outb((value), (USHORT)(base) + (address)) -#define DC395x_write16(acb,address,value) outw((value), acb->IOPortBase + (address)) -#define DC395x_write32(acb,address,value) outl((value), acb->IOPortBase + (address)) +#define DC395x_write16(acb,address,value) outw((value), acb->io_port_base + (address)) +#define DC395x_write32(acb,address,value) outl((value), acb->io_port_base + (address)) #define BUS_ADDR(sg) sg_dma_address(&(sg)) @@ -383,7 +383,8 @@ struct AdapterCtlBlk { struct Scsi_Host *scsi_host; - u16 IOPortBase; + u16 io_port_base; + u16 io_port_len; struct list_head dcb_list; /* head of going dcb list */ struct DeviceCtlBlk *dcb_run_robin; @@ -496,10 +497,6 @@ struct ScsiReqBlk *srb); static inline void set_xfer_rate(struct AdapterCtlBlk *acb, struct DeviceCtlBlk *dcb); -static void init_dcb(struct AdapterCtlBlk *acb, - struct DeviceCtlBlk **pdcb, u8 target, u8 lun); -static void remove_dev(struct AdapterCtlBlk *acb, - struct DeviceCtlBlk *dcb); static void waiting_timeout(unsigned long ptr); @@ -822,6 +819,7 @@ * * @head: The pointer to the head of the list to count the items in. **/ +static unsigned int list_size(struct list_head *head) { unsigned int count = 0; @@ -841,6 +839,7 @@ * @pos: The pointer the dcb for which we are searching for the * following dcb. **/ +static struct DeviceCtlBlk *dcb_get_next( struct list_head *head, struct DeviceCtlBlk *pos) @@ -1449,34 +1448,6 @@ } -/*********************************************************************** - * Function static int dc395x_slave_alloc() - * - * Purpose: Allocate DCB - ***********************************************************************/ -static int dc395x_slave_alloc(struct scsi_device *sdp) -{ - struct AdapterCtlBlk *acb; - struct DeviceCtlBlk *dummy; - - acb = (struct AdapterCtlBlk *) sdp->host->hostdata; - - init_dcb(acb, &dummy, sdp->id, sdp->lun); - - return dummy ? 0 : -ENOMEM; -} - - -static void dc395x_slave_destroy(struct scsi_device *sdp) -{ - struct AdapterCtlBlk *acb; - struct DeviceCtlBlk *dcb; - - acb = (struct AdapterCtlBlk *) sdp->host->hostdata; - dcb = find_dcb(acb, sdp->id, sdp->lun); - - remove_dev(acb, dcb); -} /* @@ -1635,7 +1606,6 @@ dcb->sync_offset = 0; dcb->dev_mode = eeprom->target[dcb->target_id].cfg0; - /*dcb->AdpMode = eeprom->channel_cfg; */ period_index = eeprom->target[dcb->target_id].period & 0x07; dcb->min_nego_period = clock_period[period_index]; if (!(dcb->dev_mode & NTC_DO_WIDE_NEGO) @@ -1824,7 +1794,6 @@ { if (timer_pending(&acb->selto_timer)) return; - init_timer(&acb->selto_timer); acb->selto_timer.function = selection_timeout_missed; acb->selto_timer.data = (unsigned long) acb; if (time_before @@ -4049,40 +4018,8 @@ } -/* Dynamic device handling */ - -/* Remove dev (and DCB) */ -static -void remove_dev(struct AdapterCtlBlk *acb, struct DeviceCtlBlk *dcb) -{ - struct DeviceCtlBlk *i; - struct DeviceCtlBlk *tmp; - - dprintkdbg(DBG_0, "remove_dev\n"); - if (list_size(&dcb->srb_going_list) > 1) { - dprintkdbg(DBG_DCB, "Driver won't free DCB (ID %i, LUN %i): 0x%08x because of SRBCnt %i\n", - dcb->target_id, dcb->target_lun, (int) dcb, - list_size(&dcb->srb_going_list)); - return; - } - acb->dcb_map[dcb->target_id] &= ~(1 << dcb->target_lun); - acb->children[dcb->target_id][dcb->target_lun] = NULL; - list_for_each_entry_safe(i, tmp, &acb->dcb_list, list) { - if (dcb == i) { - list_del(&i->list); - break; - } - } - dprintkdbg(DBG_DCB, "Driver about to free DCB (ID %i, LUN %i): %p\n", - dcb->target_id, dcb->target_lun, dcb); - if (dcb == acb->active_dcb) - acb->active_dcb = NULL; - if (dcb == acb->dcb_run_robin) - acb->dcb_run_robin = dcb_get_next(&acb->dcb_list, dcb); - dc395x_kfree(dcb); -} static inline u8 tagq_blacklist(char *name) @@ -4681,58 +4618,55 @@ } -/* - ********************************************************************* - * dc395x_queue_command + + + +/** + * device_alloc - Allocate a new device instance. This create the + * devices instance and sets up all the data items. The adapter + * instance is required to obtain confiuration information for this + * device. This does *not* add this device to the adapters device + * list. + * + * @acb: The adapter to obtain configuration information from. + * @target: The target for the new device. + * @lun: The lun for the new device. * - * Function : void init_dcb - * Purpose : initialize the internal structures for a given DCB - * Inputs : cmd - pointer to this scsi cmd request block structure - ********************************************************************* - */ + * Return the new device if succesfull or NULL on failure. + **/ static -void init_dcb(struct AdapterCtlBlk *acb, struct DeviceCtlBlk **pdcb, - u8 target, u8 lun) +struct DeviceCtlBlk *device_alloc(struct AdapterCtlBlk *acb, u8 target, u8 lun) { struct NvRamType *eeprom = &acb->eeprom; - u8 period_index; + u8 period_index = eeprom->target[target].period & 0x07; struct DeviceCtlBlk *dcb; - struct DeviceCtlBlk *dcb2; - dprintkdbg(DBG_0, "init_dcb..............\n"); dcb = dc395x_kmalloc(sizeof(struct DeviceCtlBlk), GFP_ATOMIC); - /*dcb = find_dcb (acb, target, lun); */ - *pdcb = dcb; - dcb2 = NULL; - if (!dcb) - return; - - INIT_LIST_HEAD(&dcb->srb_waiting_list); + dprintkdbg(DBG_0, "device_alloc: device %p\n", dcb); + if (!dcb) { + return NULL; + } + dcb->acb = NULL; INIT_LIST_HEAD(&dcb->srb_going_list); - if (list_empty(&acb->dcb_list)) - acb->dcb_run_robin = dcb; - list_add_tail(&dcb->list, &acb->dcb_list); - - /* $$$$$$$ */ - dcb->acb = acb; - dcb->target_id = target; - dcb->target_lun = lun; - /* $$$$$$$ */ + INIT_LIST_HEAD(&dcb->srb_waiting_list); dcb->active_srb = NULL; - /* $$$$$$$ */ dcb->tag_mask = 0; - dcb->flag = 0; dcb->max_command = 1; - /* $$$$$$$ */ + dcb->target_id = target; + dcb->target_lun = lun; +#ifndef DC395x_NO_DISCONNECT + dcb->identify_msg = + IDENTIFY(dcb->dev_mode & NTC_DO_DISCONNECT, lun); +#else + dcb->identify_msg = IDENTIFY(0, lun); +#endif dcb->dev_mode = eeprom->target[target].cfg0; - /*dcb->AdpMode = eeprom->channel_cfg; */ dcb->inquiry7 = 0; dcb->sync_mode = 0; - /* $$$$$$$ */ + dcb->min_nego_period = clock_period[period_index]; dcb->sync_period = 0; dcb->sync_offset = 0; - period_index = eeprom->target[target].period & 0x07; - dcb->min_nego_period = clock_period[period_index]; + dcb->flag = 0; #ifndef DC395x_NO_WIDE if ((dcb->dev_mode & NTC_DO_WIDE_NEGO) @@ -4744,318 +4678,166 @@ if (!(lun) || current_sync_offset) dcb->sync_mode |= SYNC_NEGO_ENABLE; #endif - /* $$$$$$$ */ -#ifndef DC395x_NO_DISCONNECT - dcb->identify_msg = - IDENTIFY(dcb->dev_mode & NTC_DO_DISCONNECT, lun); -#else - dcb->identify_msg = IDENTIFY(0, lun); -#endif - /* $$$$$$$ */ if (dcb->target_lun != 0) { /* Copy settings */ - struct DeviceCtlBlk *prevDCB; - list_for_each_entry(prevDCB, &acb->dcb_list, list) - if (prevDCB->target_id == dcb->target_id) + struct DeviceCtlBlk *p; + list_for_each_entry(p, &acb->dcb_list, list) + if (p->target_id == dcb->target_id) break; - dprintkdbg(DBG_KG, + dprintkdbg(DBG_KG, "Copy settings from %02i-%02i to %02i-%02i\n", - prevDCB->target_id, prevDCB->target_lun, + p->target_id, p->target_lun, dcb->target_id, dcb->target_lun); - dcb->sync_mode = prevDCB->sync_mode; - dcb->sync_period = prevDCB->sync_period; - dcb->min_nego_period = prevDCB->min_nego_period; - dcb->sync_offset = prevDCB->sync_offset; - dcb->inquiry7 = prevDCB->inquiry7; - }; - - acb->dcb_map[target] |= (1 << lun); - acb->children[target][lun] = dcb; + dcb->sync_mode = p->sync_mode; + dcb->sync_period = p->sync_period; + dcb->min_nego_period = p->min_nego_period; + dcb->sync_offset = p->sync_offset; + dcb->inquiry7 = p->inquiry7; + } + return dcb; } -#if debug_enabled(DBG_TRACE|DBG_TRACEALL) -/* - * Memory for trace buffers - */ +/** + * adapter_add_device - Adds the device instance to the adaptor instance. + * + * @acb: The adapter device to be updated + * @dcb: A newly created and intialised device instance to add. + **/ static -void free_tracebufs(struct AdapterCtlBlk *acb, int srb_idx) +void adapter_add_device(struct AdapterCtlBlk *acb, struct DeviceCtlBlk *dcb) { - int i; - const unsigned bufs_per_page = PAGE_SIZE / DEBUGTRACEBUFSZ; - for (i = 0; i < srb_idx; i += bufs_per_page) { - /*dprintkl(KERN_DEBUG, "Free tracebuf %p (for %i)\n", */ - /* acb->srb_array[i].debugtrace, i); */ - dc395x_kfree(acb->srb_array[i].debugtrace); - } -} + /* backpointer to adapter */ + dcb->acb = acb; + + /* set run_robin to this device if it is currently empty */ + if (list_empty(&acb->dcb_list)) + acb->dcb_run_robin = dcb; + /* add device to list */ + list_add_tail(&dcb->list, &acb->dcb_list); -static -int alloc_tracebufs(struct AdapterCtlBlk *acb) -{ - const unsigned mem_needed = - (DC395x_MAX_SRB_CNT + 1) * DEBUGTRACEBUFSZ; - int pages = (mem_needed + (PAGE_SIZE - 1)) / PAGE_SIZE; - const unsigned bufs_per_page = PAGE_SIZE / DEBUGTRACEBUFSZ; - int srb_idx = 0; - unsigned i = 0; - unsigned char *ptr; - /*dprintkl(KERN_DEBUG, "Alloc %i pages for tracebufs\n", pages); */ - while (pages--) { - ptr = dc395x_kmalloc(PAGE_SIZE, GFP_KERNEL); - if (!ptr) { - free_tracebufs(acb, srb_idx); - return 1; - } - /*dprintkl(KERN_DEBUG, "Alloc %li bytes at %p for tracebuf %i\n", */ - /* PAGE_SIZE, ptr, srb_idx); */ - i = 0; - while (i < bufs_per_page && srb_idx < DC395x_MAX_SRB_CNT) - acb->srb_array[srb_idx++].debugtrace = - ptr + (i++ * DEBUGTRACEBUFSZ); - } - if (i < bufs_per_page) { - acb->srb.debugtrace = ptr + (i * DEBUGTRACEBUFSZ); - acb->srb.debugtrace[0] = 0; - } else - dprintkl(KERN_DEBUG, "No space for tmsrb tracebuf reserved?!\n"); - return 0; + /* update device maps */ + acb->dcb_map[dcb->target_id] |= (1 << dcb->target_lun); + acb->children[dcb->target_id][dcb->target_lun] = dcb; } -#endif -/* Free SG tables */ -static void free_sg_tables(struct AdapterCtlBlk *acb, int srb_idx) +/** + * adapter_remove_device - Removes the device instance from the adaptor + * instance. The device instance is not check in any way or freed by this. + * The caller is expected to take care of that. This will simply remove the + * device from the adapters data strcutures. + * + * @acb: The adapter device to be updated + * @dcb: A device that has previously been added to the adapter. + **/ +static +void adapter_remove_device(struct AdapterCtlBlk *acb, struct DeviceCtlBlk *dcb) { - int i; - const unsigned srbs_per_page = - PAGE_SIZE / (DC395x_MAX_SG_LISTENTRY * sizeof(struct SGentry)); - for (i = 0; i < srb_idx; i += srbs_per_page) { - /*dprintkl(KERN_DEBUG, "Free SG segs %p (for %i)\n", */ - /* acb->srb_array[i].segment_x, i); */ - dc395x_kfree(acb->srb_array[i].segment_x); - } -} + struct DeviceCtlBlk *i; + struct DeviceCtlBlk *tmp; + dprintkdbg(DBG_0, "adapter_remove_device: Remove device (ID %i, LUN %i): %p\n", + dcb->target_id, dcb->target_lun, dcb); + /* fix up any pointers to this device that we have in the adapter */ + if (acb->active_dcb == dcb) + acb->active_dcb = NULL; + if (acb->dcb_run_robin == dcb) + acb->dcb_run_robin = dcb_get_next(&acb->dcb_list, dcb); -/* - * Allocate SG tables; as we have to pci_map them, an SG list (struct SGentry*) - * should never cross a page boundary */ -static int alloc_sg_tables(struct AdapterCtlBlk *acb) -{ - const unsigned mem_needed = - (DC395x_MAX_SRB_CNT + - 1) * DC395x_MAX_SG_LISTENTRY * sizeof(struct SGentry); - int pages = (mem_needed + (PAGE_SIZE - 1)) / PAGE_SIZE; - const unsigned srbs_per_page = - PAGE_SIZE / (DC395x_MAX_SG_LISTENTRY * sizeof(struct SGentry)); - int srb_idx = 0; - unsigned i = 0; - struct SGentry *ptr; - /*dprintkl(KERN_DEBUG, "Alloc %i pages for SG tables\n", pages); */ - while (pages--) { - ptr = (struct SGentry *) dc395x_kmalloc(PAGE_SIZE, GFP_KERNEL); - if (!ptr) { - free_sg_tables(acb, srb_idx); - return 1; + /* unlink from list */ + list_for_each_entry_safe(i, tmp, &acb->dcb_list, list) + if (dcb == i) { + list_del(&i->list); + break; } - /*dprintkl(KERN_DEBUG, "Alloc %li bytes at %p for SG segments %i\n", */ - /* PAGE_SIZE, ptr, srb_idx); */ - i = 0; - while (i < srbs_per_page && srb_idx < DC395x_MAX_SRB_CNT) - acb->srb_array[srb_idx++].segment_x = - ptr + (i++ * DC395x_MAX_SG_LISTENTRY); - } - if (i < srbs_per_page) - acb->srb.segment_x = - ptr + (i * DC395x_MAX_SG_LISTENTRY); - else - dprintkl(KERN_DEBUG, "No space for tmsrb SG table reserved?!\n"); - return 0; + + /* clear map and children */ + acb->dcb_map[dcb->target_id] &= ~(1 << dcb->target_lun); + acb->children[dcb->target_id][dcb->target_lun] = NULL; + dcb->acb = NULL; } -/* - ******************************************************************** - * scsiio - * init_acb - ******************************************************************** +/** + * adapter_remove_and_free_device - Removes a single device from the adapter + * and then frees the device information. + * + * @acb: The adapter device to be updated + * @dcb: A device that has previously been added to the adapter. */ -static void __init link_srb(struct AdapterCtlBlk *acb) +static +void adapter_remove_and_free_device(struct AdapterCtlBlk *acb, struct DeviceCtlBlk *dcb) { - int i; - - for (i = 0; i < acb->srb_count - 1; i++) - srb_free_insert(acb, &acb->srb_array[i]); + if (list_size(&dcb->srb_going_list) > 1) { + dprintkdbg(DBG_DCB, "adapter_remove_and_free_device: " + "Won't remove because of %i active requests\n", + list_size(&dcb->srb_going_list)); + return; + } + adapter_remove_device(acb, dcb); + dc395x_kfree(dcb); } -/* - *********************************************************************** - * host_init +/** + * adapter_remove_and_free_all_devices - Removes and frees all of the + * devices associated with the specified adapter. * - * Function : static void init_acb - * Purpose : initialize the internal structures for a given SCSI host - * Inputs : host - pointer to this host adapter's structure - *********************************************************************** - */ + * @acb: The adapter from which all devices should be removed. + **/ static -int __init init_acb(struct Scsi_Host *host, u32 io_port, u8 irq) +void adapter_remove_and_free_all_devices(struct AdapterCtlBlk* acb) { - struct AdapterCtlBlk *acb = (struct AdapterCtlBlk *)host->hostdata; - struct NvRamType *eeprom = &acb->eeprom; - u16 i; + struct DeviceCtlBlk *dcb; + struct DeviceCtlBlk *tmp; + dprintkdbg(DBG_DCB, "adapter_remove_and_free_all_devices: Free all devices (%i devices)\n", + list_size(&acb->dcb_list)); - host->max_cmd_len = 24; - host->can_queue = DC395x_MAX_CMD_QUEUE; - host->cmd_per_lun = DC395x_MAX_CMD_PER_LUN; - host->this_id = (int) eeprom->scsi_id; - host->io_port = io_port; - host->n_io_port = 0x80; - host->dma_channel = -1; - host->unique_id = io_port; - host->irq = irq; - host->last_reset = jiffies; + list_for_each_entry_safe(dcb, tmp, &acb->dcb_list, list) + adapter_remove_and_free_device(acb, dcb); +} - host->max_id = 16; - if (host->max_id - 1 == eeprom->scsi_id) - host->max_id--; -#ifdef CONFIG_SCSI_MULTI_LUN - if (eeprom->channel_cfg & NAC_SCANLUN) - host->max_lun = 8; - else - host->max_lun = 1; -#else - host->max_lun = 1; -#endif - /* - ******************************** - */ - acb->scsi_host = host; - acb->IOPortBase = (u16) io_port; - acb->dcb_run_robin = NULL; - acb->active_dcb = NULL; - acb->srb_count = DC395x_MAX_SRB_CNT; - acb->scsi_host->this_id = eeprom->scsi_id; - acb->hostid_bit = (1 << acb->scsi_host->this_id); - /*acb->scsi_host->this_lun = 0; */ - acb->irq_level = irq; - acb->tag_max_num = 1 << eeprom->max_tag; - if (acb->tag_max_num > 30) - acb->tag_max_num = 30; - acb->acb_flag = 0; /* RESET_DETECT, RESET_DONE, RESET_DEV */ - acb->scan_devices = 1; - acb->msg_len = 0; - acb->gmode2 = eeprom->channel_cfg; - if (eeprom->channel_cfg & NAC_SCANLUN) - acb->lun_chk = 1; - /* - * link all device's SRB Q of this adapter - */ - if (alloc_sg_tables(acb)) { - dprintkl(KERN_DEBUG, "SG table allocation failed!\n"); - return 1; - } -#if debug_enabled(DBG_TRACE|DBG_TRACEALL) - if (alloc_tracebufs(acb)) { - dprintkl(KERN_DEBUG, "SG trace buffer allocation failed!\n"); - free_sg_tables(acb, DC395x_MAX_SRB_CNT); - return 1; - } -#endif - INIT_LIST_HEAD(&acb->dcb_list); - INIT_LIST_HEAD(&acb->srb_free_list); - link_srb(acb); +/** + * dc395x_slave_alloc - Called by the scsi mid layer to tell us about a new + * scsi device that we need to deal with. We allocate a new device and then + * insert that device into the adapters device list. + * + * @scsi_device: The new scsi device that we need to handle. + **/ +static +int dc395x_slave_alloc(struct scsi_device *scsi_device) +{ + struct AdapterCtlBlk *acb = (struct AdapterCtlBlk *)scsi_device->host->hostdata; + struct DeviceCtlBlk *dcb; - /* - * temp SRB for Q tag used or abort command used - */ - acb->tmp_srb = &acb->srb; - init_timer(&acb->waiting_timer); + dcb = device_alloc(acb, scsi_device->id, scsi_device->lun); + if (!dcb) + return -ENOMEM; + adapter_add_device(acb, dcb); - for (i = 0; i < DC395x_MAX_SCSI_ID; i++) - acb->dcb_map[i] = 0; - dprintkdbg(DBG_0, "acb = %p, pdcb_map = %p, psrb_array = %p\n", acb, - acb->dcb_map, acb->srb_array); - dprintkdbg(DBG_0, "ACB size= %04x, DCB size= %04x, SRB size= %04x\n", - sizeof(struct AdapterCtlBlk), sizeof(struct DeviceCtlBlk), - sizeof(struct ScsiReqBlk)); return 0; } -/*=========================================================================== - Init - ===========================================================================*/ /** - * init_adapter - Initialize the SCSI chip control registers - * - * @host: This hosts adapter strcuture - * @io_port: The base I/O port - * @irq: IRQ + * dc395x_slave_destroy - Called by the scsi mid layer to tell us about a + * device that is going away. * - * Returns 0 if the initialization succeeds, any other value on failure. + * @scsi_device: The new scsi device that we need to handle. **/ static -int __init init_adapter(struct Scsi_Host *host, u32 io_port, u8 irq) +void dc395x_slave_destroy(struct scsi_device *scsi_device) { - struct AdapterCtlBlk *acb = (struct AdapterCtlBlk *)host->hostdata; - struct NvRamType *eeprom = &acb->eeprom; - - if (!request_region(io_port, host->n_io_port, DC395X_NAME)) { - dprintkl(KERN_ERR, "Failed to reserve IO region 0x%x\n", io_port); - return -1; - } - if (request_irq(irq, dc395x_interrupt, SA_SHIRQ, DC395X_NAME, acb)) { - /* release the region we just claimed */ - release_region(io_port, host->n_io_port); - dprintkl(KERN_INFO, "Failed to register IRQ!\n"); - return -1; - } - - acb->IOPortBase = io_port; - - /* selection timeout = 250 ms */ - acb->sel_timeout = DC395x_SEL_TIMEOUT; - - /* Mask all the interrupt */ - DC395x_write8(acb, TRM_S1040_DMA_INTEN, 0x00); - DC395x_write8(acb, TRM_S1040_SCSI_INTEN, 0x00); - - /* Reset SCSI module */ - DC395x_write16(acb, TRM_S1040_SCSI_CONTROL, DO_RSTMODULE); - - /* Reset PCI/DMA module */ - DC395x_write8(acb, TRM_S1040_DMA_CONTROL, DMARESETMODULE); - udelay(20); - - /* program configuration 0 */ - acb->config = HCC_AUTOTERM | HCC_PARITY; - if (DC395x_read8(acb, TRM_S1040_GEN_STATUS) & WIDESCSI) - acb->config |= HCC_WIDE_CARD; - - if (eeprom->channel_cfg & NAC_POWERON_SCSI_RESET) - acb->config |= HCC_SCSI_RESET; - - if (acb->config & HCC_SCSI_RESET) { - dprintkl(KERN_INFO, "Performing initial SCSI bus reset\n"); - DC395x_write8(acb, TRM_S1040_SCSI_CONTROL, DO_RSTSCSI); - - /*while (!( DC395x_read8(acb, TRM_S1040_SCSI_INTSTATUS) & INT_SCSIRESET )); */ - /*spin_unlock_irq (&io_request_lock); */ - udelay(500); + struct AdapterCtlBlk *acb = (struct AdapterCtlBlk *)scsi_device->host->hostdata; + struct DeviceCtlBlk *dcb = find_dcb(acb, scsi_device->id, scsi_device->lun); + if (dcb) + adapter_remove_and_free_device(acb, dcb); +} - acb->scsi_host->last_reset = - jiffies + HZ / 2 + - HZ * acb->eeprom.delay_time; - /*spin_lock_irq (&io_request_lock); */ - } - set_basic_config(acb); - return 0; -} /** @@ -5363,20 +5145,161 @@ } + + /** - * print_config - print adapter connection and termination + * print_eeprom_settings - output the eeprom settings + * to the kernel log so people can see what they were. + * + * @eeprom: The eeprom data strucutre to show details for. + **/ +static +void __init print_eeprom_settings(struct NvRamType *eeprom) +{ + dprintkl(KERN_INFO, "Used settings: AdapterID=%02i, Speed=%i(%02i.%01iMHz), dev_mode=0x%02x\n", + eeprom->scsi_id, + eeprom->target[0].period, + clock_speed[eeprom->target[0].period] / 10, + clock_speed[eeprom->target[0].period] % 10, + eeprom->target[0].cfg0); + dprintkl(KERN_INFO, " AdaptMode=0x%02x, Tags=%i(%02i), DelayReset=%is\n", + eeprom->channel_cfg, + eeprom->max_tag, + 1 << eeprom->max_tag, + eeprom->delay_time); +} + + + +#if debug_enabled(DBG_TRACE|DBG_TRACEALL) +/* + * Memory for trace buffers + */ +static +void free_tracebufs(struct AdapterCtlBlk *acb) +{ + int i; + const unsigned bufs_per_page = PAGE_SIZE / DEBUGTRACEBUFSZ; + + for (i = 0; i < srb_idx; i += bufs_per_page) + if (acb->srb_array[i].debugtrace) + dc395x_kfree(acb->srb_array[i].debugtrace); +} + + +static +int alloc_tracebufs(struct AdapterCtlBlk *acb) +{ + const unsigned mem_needed = + (DC395x_MAX_SRB_CNT + 1) * DEBUGTRACEBUFSZ; + int pages = (mem_needed + (PAGE_SIZE - 1)) / PAGE_SIZE; + const unsigned bufs_per_page = PAGE_SIZE / DEBUGTRACEBUFSZ; + int srb_idx = 0; + unsigned i = 0; + unsigned char *ptr; + + for (i = 0; i < DC395x_MAX_SRB_CNT; i++) + acb->srb_array[i].debugtrace = NULL; + + while (pages--) { + ptr = dc395x_kmalloc(PAGE_SIZE, GFP_KERNEL); + if (!ptr) { + free_tracebufs(acb); + return 1; + } + /*dprintkl(KERN_DEBUG, "Alloc %li bytes at %p for tracebuf %i\n", */ + /* PAGE_SIZE, ptr, srb_idx); */ + i = 0; + while (i < bufs_per_page && srb_idx < DC395x_MAX_SRB_CNT) + acb->srb_array[srb_idx++].debugtrace = + ptr + (i++ * DEBUGTRACEBUFSZ); + } + if (i < bufs_per_page) { + acb->srb.debugtrace = ptr + (i * DEBUGTRACEBUFSZ); + acb->srb.debugtrace[0] = 0; + } else + dprintkl(KERN_DEBUG, "No space for tmsrb tracebuf reserved?!\n"); + return 0; +} +#else +static void free_tracebufs(struct AdapterCtlBlk *acb) {} +static int alloc_tracebufs(struct AdapterCtlBlk *acb) { return 0; } +#endif + +/* Free SG tables */ +static +void adapter_sg_tables_free(struct AdapterCtlBlk *acb) +{ + int i; + const unsigned srbs_per_page = PAGE_SIZE/(DC395x_MAX_SG_LISTENTRY + *sizeof(struct SGentry)); + + for (i = 0; i < DC395x_MAX_SRB_CNT; i += srbs_per_page) + if (acb->srb_array[i].segment_x) + dc395x_kfree(acb->srb_array[i].segment_x); +} + + +/* + * Allocate SG tables; as we have to pci_map them, an SG list (struct SGentry*) + * should never cross a page boundary */ +static +int __init adapter_sg_tables_alloc(struct AdapterCtlBlk *acb) +{ + const unsigned mem_needed = (DC395x_MAX_SRB_CNT+1) + *DC395x_MAX_SG_LISTENTRY + *sizeof(struct SGentry); + int pages = (mem_needed+(PAGE_SIZE-1))/PAGE_SIZE; + const unsigned srbs_per_page = PAGE_SIZE/(DC395x_MAX_SG_LISTENTRY + *sizeof(struct SGentry)); + int srb_idx = 0; + unsigned i = 0; + struct SGentry *ptr; + + for (i = 0; i < DC395x_MAX_SRB_CNT; i++) + acb->srb_array[i].segment_x = NULL; + + dprintkdbg(DBG_1, "Allocate %i pages for SG tables\n", pages); + while (pages--) { + ptr = (struct SGentry *)dc395x_kmalloc(PAGE_SIZE, GFP_KERNEL); + if (!ptr) { + adapter_sg_tables_free(acb); + return 1; + } + dprintkdbg(DBG_1, "Allocate %li bytes at %p for SG segments %i\n", + PAGE_SIZE, ptr, srb_idx); + i = 0; + while (i < srbs_per_page && srb_idx < DC395x_MAX_SRB_CNT) + acb->srb_array[srb_idx++].segment_x = + ptr + (i++ * DC395x_MAX_SG_LISTENTRY); + } + if (i < srbs_per_page) + acb->srb.segment_x = + ptr + (i * DC395x_MAX_SG_LISTENTRY); + else + dprintkl(KERN_DEBUG, "No space for tmsrb SG table reserved?!\n"); + return 0; +} + + + +/** + * adapter_print_config - print adapter connection and termination * config * - * @acb: adapter control block + * The io port in the adapter needs to have been set before calling + * this function. + * + * @acb: The adapter to print the information for. **/ static -void __init print_config(struct AdapterCtlBlk *acb) +void __init adapter_print_config(struct AdapterCtlBlk *acb) { u8 bval; bval = DC395x_read8(acb, TRM_S1040_GEN_STATUS); - dprintkl(KERN_INFO, "%c: Connectors: ", - ((bval & WIDESCSI) ? 'W' : ' ')); + dprintkl(KERN_INFO, "%s Connectors: ", + ((bval & WIDESCSI) ? "(Wide)" : "")); if (!(bval & CON5068)) printk("ext%s ", !(bval & EXT68HIGH) ? "68" : "50"); if (!(bval & CON68)) @@ -5403,77 +5326,290 @@ /** - * print_eeprom_settings - output the eeprom settings - * to the kernel log so people can see what they were. + * adapter_init_params - Initialize the various parameters in the + * adapter structure. Note that the pointer to the scsi_host is set + * early (when this instance is created) and the io_port and irq + * values are set later after they have been reserved. This just gets + * everything set to a good starting position. * - * @eeprom: The eeprom data strucutre to show details for. + * The eeprom structure in the adapter needs to have been set before + * calling this function. + * + * @acb: The adapter to initialize. **/ static -void __init print_eeprom_settings(struct NvRamType *eeprom) +void __init adapter_init_params(struct AdapterCtlBlk *acb) { - dprintkl(KERN_INFO, "Used settings: AdapterID=%02i, Speed=%i(%02i.%01iMHz), dev_mode=0x%02x\n", - eeprom->scsi_id, - eeprom->target[0].period, - clock_speed[eeprom->target[0].period] / 10, - clock_speed[eeprom->target[0].period] % 10, - eeprom->target[0].cfg0); - dprintkl(KERN_INFO, " AdaptMode=0x%02x, Tags=%i(%02i), DelayReset=%is\n", - eeprom->channel_cfg, - eeprom->max_tag, - 1 << eeprom->max_tag, - eeprom->delay_time); + struct NvRamType *eeprom = &acb->eeprom; + int i; + + /* NOTE: acb->scsi_host is set at scsi_host/acb creation time */ + /* NOTE: acb->io_port_base is set at port registration time */ + /* NOTE: acb->io_port_len is set at port registration time */ + + INIT_LIST_HEAD(&acb->dcb_list); + acb->dcb_run_robin = NULL; + acb->active_dcb = NULL; + + INIT_LIST_HEAD(&acb->srb_free_list); + /* temp SRB for Q tag used or abort command used */ + acb->tmp_srb = &acb->srb; + init_timer(&acb->waiting_timer); + init_timer(&acb->selto_timer); + + acb->srb_count = DC395x_MAX_SRB_CNT; + + acb->sel_timeout = DC395x_SEL_TIMEOUT; /* timeout=250ms */ + /* NOTE: acb->irq_level is set at IRQ registration time */ + + acb->tag_max_num = 1 << eeprom->max_tag; + if (acb->tag_max_num > 30) + acb->tag_max_num = 30; + + acb->acb_flag = 0; /* RESET_DETECT, RESET_DONE, RESET_DEV */ + acb->gmode2 = eeprom->channel_cfg; + acb->config = 0; /* NOTE: actually set in adapter_init_chip */ + + if (eeprom->channel_cfg & NAC_SCANLUN) + acb->lun_chk = 1; + acb->scan_devices = 1; + + acb->scsi_host->this_id = eeprom->scsi_id; + acb->hostid_bit = (1 << acb->scsi_host->this_id); + + for (i = 0; i < DC395x_MAX_SCSI_ID; i++) + acb->dcb_map[i] = 0; + + acb->msg_len = 0; + + /* link static array of srbs into the srb free list */ + for (i = 0; i < acb->srb_count - 1; i++) + srb_free_insert(acb, &acb->srb_array[i]); } -/* - ********************************************************************* - * DC395x_detect +/** + * adapter_init_host - Initialize the scsi host instance based on + * values that we have already stored in the adapter instance. There's + * some mention that a lot of these are deprecated, so we won't use + * them (we'll use the ones in the adapter instance) but we'll fill + * them in in case something else needs them. * - * Function : static int host_init (struct Scsi_Host *host) - * Purpose : initialize the internal structures for a given SCSI host - * Inputs : host - pointer to this host adapter's structure/ - * Preconditions : when this function is called, the chip_type - * field of the acb structure MUST have been set. - ********************************************************************* - */ + * The eeprom structure, irq and io ports in the adapter need to have + * been set before calling this function. + * + * @host: The scsi host instance to fill in the values for. + **/ static -struct Scsi_Host *__init host_init(Scsi_Host_Template * host_template, - u32 io_port, u8 irq) +void __init adapter_init_scsi_host(struct Scsi_Host *host) { - struct Scsi_Host *host; - struct AdapterCtlBlk *acb; + struct AdapterCtlBlk *acb = (struct AdapterCtlBlk *)host->hostdata; + struct NvRamType *eeprom = &acb->eeprom; + + host->max_cmd_len = 24; + host->can_queue = DC395x_MAX_CMD_QUEUE; + host->cmd_per_lun = DC395x_MAX_CMD_PER_LUN; + host->this_id = (int)eeprom->scsi_id; + host->io_port = acb->io_port_base; + host->n_io_port = acb->io_port_len; + host->dma_channel = -1; + host->unique_id = acb->io_port_base; + host->irq = acb->irq_level; + host->last_reset = jiffies; - host = scsi_host_alloc(host_template, sizeof(struct AdapterCtlBlk)); - if (!host) { - dprintkl(KERN_INFO, "scsi_host_alloc failed\n"); + host->max_id = 16; + if (host->max_id - 1 == eeprom->scsi_id) + host->max_id--; + +#ifdef CONFIG_SCSI_MULTI_LUN + if (eeprom->channel_cfg & NAC_SCANLUN) + host->max_lun = 8; + else + host->max_lun = 1; +#else + host->max_lun = 1; +#endif + +} + + +/** + * adapter_init_chip - Get the chip into a know state and figure out + * some of the settings that apply to this adapter. + * + * The io port in the adapter needs to have been set before calling + * this function. The config will be configured correctly on return. + * + * @acb: The adapter which we are to init. + **/ +void __init adapter_init_chip(struct AdapterCtlBlk *acb) +{ + struct NvRamType *eeprom = &acb->eeprom; + + /* Mask all the interrupt */ + DC395x_write8(acb, TRM_S1040_DMA_INTEN, 0x00); + DC395x_write8(acb, TRM_S1040_SCSI_INTEN, 0x00); + + /* Reset SCSI module */ + DC395x_write16(acb, TRM_S1040_SCSI_CONTROL, DO_RSTMODULE); + + /* Reset PCI/DMA module */ + DC395x_write8(acb, TRM_S1040_DMA_CONTROL, DMARESETMODULE); + udelay(20); + + /* program configuration 0 */ + acb->config = HCC_AUTOTERM | HCC_PARITY; + if (DC395x_read8(acb, TRM_S1040_GEN_STATUS) & WIDESCSI) + acb->config |= HCC_WIDE_CARD; + + if (eeprom->channel_cfg & NAC_POWERON_SCSI_RESET) + acb->config |= HCC_SCSI_RESET; + + if (acb->config & HCC_SCSI_RESET) { + dprintkl(KERN_INFO, "Performing initial SCSI bus reset\n"); + DC395x_write8(acb, TRM_S1040_SCSI_CONTROL, DO_RSTSCSI); + + /*while (!( DC395x_read8(acb, TRM_S1040_SCSI_INTSTATUS) & INT_SCSIRESET )); */ + /*spin_unlock_irq (&io_request_lock); */ + udelay(500); + + acb->scsi_host->last_reset = + jiffies + HZ / 2 + + HZ * acb->eeprom.delay_time; + + /*spin_lock_irq (&io_request_lock); */ + } +} + + +/** + * init_adapter - Grab the resource for the card, setup the adapter + * information, set the card into a known state, create the various + * tables etc etc. This basically gets all adapter information all up + * to date, intialised and gets the chip in sync with it. + * + * @host: This hosts adapter structure + * @io_port: The base I/O port + * @irq: IRQ + * + * Returns 0 if the initialization succeeds, any other value on + * failure. + **/ +static +int __init adapter_init(struct AdapterCtlBlk *acb, u32 io_port, u32 io_port_len, u8 irq) +{ + if (!request_region(io_port, io_port_len, DC395X_NAME)) { + dprintkl(KERN_ERR, "Failed to reserve IO region 0x%x\n", io_port); goto failed; } - acb = (struct AdapterCtlBlk *)host->hostdata; + /* store port base to indicate we have registered it */ + acb->io_port_base = io_port; + acb->io_port_len = io_port_len; + + if (request_irq(irq, dc395x_interrupt, SA_SHIRQ, DC395X_NAME, acb)) { + /* release the region we just claimed */ + dprintkl(KERN_INFO, "Failed to register IRQ\n"); + goto failed; + } + /* store irq to indicate we have registered it */ + acb->irq_level = irq; + /* get eeprom configuration information and command line settings etc */ check_eeprom(&acb->eeprom, (u16)io_port); print_eeprom_settings(&acb->eeprom); - if (init_acb(host, io_port, irq)) { + /* setup adapter control block */ + adapter_init_params(acb); + + /* display card connectors/termination settings */ + adapter_print_config(acb); + + if (adapter_sg_tables_alloc(acb)) { + dprintkl(KERN_DEBUG, "Memory allocation for SG tables failed\n"); goto failed; } - print_config(acb); - - if (init_adapter(host, io_port, irq)) { - dprintkl(KERN_INFO, "DC395x_initAdapter initial ERROR\n"); + if (alloc_tracebufs(acb)) { + dprintkl(KERN_DEBUG, "Memory allocation for trace buffers failed\n"); goto failed; } + adapter_init_scsi_host(acb->scsi_host); + adapter_init_chip(acb); + set_basic_config(acb); - return host; + dprintkdbg(DBG_0, "adapter_init: acb=%p, pdcb_map=%p " + "psrb_array=%p ACB size=%04x, DCB size=%04x " + "SRB size=%04x\n", + acb, acb->dcb_map, acb->srb_array, sizeof(struct AdapterCtlBlk), + sizeof(struct DeviceCtlBlk), sizeof(struct ScsiReqBlk)); + return 0; failed: - if (host) - scsi_host_put(host); - return NULL; + if (acb->irq_level) + free_irq(acb->irq_level, acb); + if (acb->io_port_base) + release_region(acb->io_port_base, acb->io_port_len); + adapter_sg_tables_free(acb); + free_tracebufs(acb); + + return 1; } -#undef SEARCH -#undef YESNO -#undef SCANF + +/** + * adapter_uninit_chip - cleanly shut down the scsi controller chip, + * stopping all operations and disabling interrupt generation on the + * card. + * + * @acb: The adapter which we are to shutdown. + **/ +static +void adapter_uninit_chip(struct AdapterCtlBlk *acb) +{ + /* disable interrupts */ + DC395x_write8(acb, TRM_S1040_DMA_INTEN, 0); + DC395x_write8(acb, TRM_S1040_SCSI_INTEN, 0); + + /* reset the scsi bus */ + if (acb->config & HCC_SCSI_RESET) + reset_scsi_bus(acb); + + /* clear any pending interupt state */ + DC395x_read8(acb, TRM_S1040_SCSI_INTSTATUS); +} + + + +/** + * adapter_uninit - Shut down the chip and release any resources that + * we had allocated. Once this returns the adapter should not be used + * anymore. + * + * @acb: The adapter which we are to un-initialize. + **/ +static +void adapter_uninit(struct AdapterCtlBlk *acb) +{ + unsigned long flags; + DC395x_LOCK_IO(acb->scsi_host, flags); + + /* remove timers */ + if (timer_pending(&acb->waiting_timer)) + del_timer(&acb->waiting_timer); + if (timer_pending(&acb->selto_timer)) + del_timer(&acb->selto_timer); + + adapter_uninit_chip(acb); + adapter_remove_and_free_all_devices(acb); + DC395x_UNLOCK_IO(acb->scsi_host, flags); + + if (acb->irq_level) + free_irq(acb->irq_level, acb); + if (acb->io_port_base) + release_region(acb->io_port_base, acb->io_port_len); + + adapter_sg_tables_free(acb); + free_tracebufs(acb); +} /* @@ -5500,6 +5636,7 @@ #undef SPRINTF #define SPRINTF(args...) pos += sprintf(pos, args) +#undef YESNO #define YESNO(YN) \ if (YN) SPRINTF(" Yes ");\ else SPRINTF(" No ") @@ -5526,7 +5663,7 @@ SPRINTF("SCSI Host Nr %i, ", host->host_no); SPRINTF("DC395U/UW/F DC315/U %s\n", (acb->config & HCC_WIDE_CARD) ? "Wide" : ""); - SPRINTF("IOPortBase 0x%04x, ", acb->IOPortBase); + SPRINTF("io_port_base 0x%04x, ", acb->io_port_base); SPRINTF("irq_level 0x%02x, ", acb->irq_level); SPRINTF(" SelTimeout %ims\n", (1638 * acb->sel_timeout) / 1000); @@ -5633,84 +5770,6 @@ } -/** - * chip_shutdown - cleanly shut down the scsi controller chip, - * stopping all operations and disablig interrupt generation on the - * card. - * - * @acb: The scsi adapter control block of the adapter to shut down. - **/ -static -void chip_shutdown(struct AdapterCtlBlk *acb) -{ - /* disable interrupt */ - DC395x_write8(acb, TRM_S1040_DMA_INTEN, 0); - DC395x_write8(acb, TRM_S1040_SCSI_INTEN, 0); - - /* remove timers */ - if (timer_pending(&acb->waiting_timer)) - del_timer(&acb->waiting_timer); - if (timer_pending(&acb->selto_timer)) - del_timer(&acb->selto_timer); - - /* reset the scsi bus */ - if (acb->config & HCC_SCSI_RESET) - reset_scsi_bus(acb); - - /* clear any pending interupt state */ - DC395x_read8(acb, TRM_S1040_SCSI_INTSTATUS); - - /* release chip resources */ -#if debug_enabled(DBG_TRACE|DBG_TRACEALL) - free_tracebufs(acb, DC395x_MAX_SRB_CNT); -#endif - free_sg_tables(acb, DC395x_MAX_SRB_CNT); -} - - -/** - * free_dcbs - Free all of the DCBs. - * - * @acb: Adapter to remove the DCBs for. - **/ -static -void free_dcbs(struct AdapterCtlBlk* acb) -{ - struct DeviceCtlBlk *dcb; - struct DeviceCtlBlk *tmp; - - dprintkdbg(DBG_DCB, "Free %i DCBs\n", list_size(&acb->dcb_list)); - - list_for_each_entry_safe(dcb, tmp, &acb->dcb_list, list) { - dprintkdbg(DBG_DCB, "Free DCB (ID %i, LUN %i): %p\n", - dcb->target_id, dcb->target_lun, dcb); - remove_dev(acb, dcb); - } -} - -/** - * host_release - shutdown device and release resources that were - * allocate for it. Called once for each card as it is shutdown. - * - * @host: The adapter instance to shutdown. - **/ -static -void host_release(struct Scsi_Host *host) -{ - struct AdapterCtlBlk *acb = (struct AdapterCtlBlk *)(host->hostdata); - unsigned long flags; - - dprintkl(KERN_DEBUG, "DC395x release\n"); - - DC395x_LOCK_IO(acb->scsi_host, flags); - chip_shutdown(acb); - free_dcbs(acb); - - free_irq(host->irq, acb); - release_region(host->io_port, host->n_io_port); - - DC395x_UNLOCK_IO(acb->scsi_host, flags); -} /* @@ -5737,6 +5796,22 @@ /** + * banner_display - Display banner on first instance of driver + * initialized. + **/ +static +void banner_display(void) +{ + static int banner_done = 0; + if (!banner_done) + { + dprintkl(KERN_INFO, "%s %s\n", DC395X_BANNER, DC395X_VERSION); + banner_done = 1; + } +} + + +/** * dc395x_init_one - Initialise a single instance of the adapter. * * The PCI layer will call this once for each instance of the adapter @@ -5753,51 +5828,55 @@ int __devinit dc395x_init_one(struct pci_dev *dev, const struct pci_device_id *id) { - unsigned int io_port; - u8 irq; struct Scsi_Host *scsi_host; - static int banner_done = 0; - int error = 0; - - dprintkdbg(DBG_0, "Init one instance of the dc395x\n"); - if (!banner_done) - { - dprintkl(KERN_INFO, "%s %s\n", DC395X_BANNER, DC395X_VERSION); - banner_done = 1; - } + struct AdapterCtlBlk *acb; + unsigned int io_port_base; + unsigned int io_port_len; + u8 irq; + + dprintkdbg(DBG_0, "Init one instance (%s)\n", pci_name(dev)); + banner_display(); if (pci_enable_device(dev)) { dprintkl(KERN_INFO, "PCI Enable device failed.\n"); return -ENODEV; } - - dprintkdbg(DBG_0, "Get resources...\n"); - io_port = pci_resource_start(dev, 0) & PCI_BASE_ADDRESS_IO_MASK; + io_port_base = pci_resource_start(dev, 0) & PCI_BASE_ADDRESS_IO_MASK; + io_port_len = pci_resource_len(dev, 0); irq = dev->irq; - dprintkdbg(DBG_0, "IO_PORT=%04x,IRQ=%x\n", (unsigned int) io_port, irq); + dprintkdbg(DBG_0, "IO_PORT=%04x, IRQ=%x\n", io_port_base, dev->irq); - scsi_host = host_init(&dc395x_driver_template, io_port, irq); - if (!scsi_host) - { - dprintkdbg(DBG_0, "host_init failed\n"); + /* allocate scsi host information (includes out adapter) */ + scsi_host = scsi_host_alloc(&dc395x_driver_template, + sizeof(struct AdapterCtlBlk)); + if (!scsi_host) { + dprintkl(KERN_INFO, "scsi_host_alloc failed\n"); return -ENOMEM; } - ((struct AdapterCtlBlk *)(scsi_host->hostdata))->dev = dev; + acb = (struct AdapterCtlBlk*)scsi_host->hostdata; + acb->scsi_host = scsi_host; + + /* initialise the adapter and everything we need */ + if (adapter_init(acb, io_port_base, io_port_len, irq)) { + dprintkl(KERN_INFO, "DC395x_initAdapter initial ERROR\n"); + scsi_host_put(scsi_host); + return -ENODEV; + } + pci_set_master(dev); - pci_set_drvdata(dev, scsi_host); /* get the scsi mid level to scan for new devices on the bus */ - error = scsi_add_host(scsi_host, &dev->dev); - if (error) { + if (scsi_add_host(scsi_host, &dev->dev)) { dprintkl(KERN_ERR, "scsi_add_host failed\n"); - error = -ENODEV; - host_release(scsi_host); + adapter_uninit(acb); scsi_host_put(scsi_host); - } else - scsi_scan_host(scsi_host); + return -ENODEV; + } + pci_set_drvdata(dev, scsi_host); + scsi_scan_host(scsi_host); - return error; + return 0; } @@ -5809,16 +5888,14 @@ **/ static void __devexit dc395x_remove_one(struct pci_dev *dev) { - struct Scsi_Host *host = pci_get_drvdata(dev); + struct Scsi_Host *scsi_host = pci_get_drvdata(dev); + struct AdapterCtlBlk *acb = (struct AdapterCtlBlk *)(scsi_host->hostdata); dprintkdbg(DBG_0, "Removing instance\n"); - if (!host) { - dprintkl(KERN_ERR, "no host allocated\n"); - return; - } - scsi_remove_host(host); - host_release(host); - scsi_host_put(host); + + scsi_remove_host(scsi_host); + adapter_uninit(acb); + scsi_host_put(scsi_host); pci_set_drvdata(dev, NULL); } diff -Nru a/drivers/scsi/dpt_i2o.c b/drivers/scsi/dpt_i2o.c --- a/drivers/scsi/dpt_i2o.c Thu Sep 4 15:38:43 2003 +++ b/drivers/scsi/dpt_i2o.c Thu Sep 4 15:38:43 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.c b/drivers/scsi/gdth.c --- a/drivers/scsi/gdth.c Thu Sep 4 15:38:37 2003 +++ b/drivers/scsi/gdth.c Thu Sep 4 15:38:37 2003 @@ -4990,7 +4990,7 @@ cmd.u.cache.DeviceNo = res.number; #if LINUX_VERSION_CODE >= 0x020503 sdev = scsi_get_host_dev(gdth_ctr_tab[hanum]); - srp = scsi_allocate_request(sdev); + srp = scsi_allocate_request(sdev, GFP_KERNEL); if (!srp) return -ENOMEM; srp->sr_cmd_len = 12; @@ -5091,7 +5091,7 @@ #if LINUX_VERSION_CODE >= 0x020503 sdev = scsi_get_host_dev(gdth_ctr_tab[hanum]); - srp = scsi_allocate_request(sdev); + srp = scsi_allocate_request(sdev, GFP_KERNEL); if (!srp) return -ENOMEM; srp->sr_cmd_len = 12; @@ -5164,7 +5164,7 @@ #if LINUX_VERSION_CODE >= 0x020503 sdev = scsi_get_host_dev(gdth_ctr_tab[hanum]); - srp = scsi_allocate_request(sdev); + srp = scsi_allocate_request(sdev, GFP_KERNEL); if (!srp) return -ENOMEM; srp->sr_cmd_len = 12; @@ -5253,7 +5253,7 @@ #if LINUX_VERSION_CODE >= 0x020503 sdev = scsi_get_host_dev(gdth_ctr_tab[hanum]); - srp = scsi_allocate_request(sdev); + srp = scsi_allocate_request(sdev, GFP_KERNEL); if (!srp) return -ENOMEM; srp->sr_cmd_len = 12; @@ -5631,7 +5631,7 @@ #if LINUX_VERSION_CODE >= 0x020503 sdev = scsi_get_host_dev(gdth_ctr_tab[hanum]); - srp = scsi_allocate_request(sdev); + srp = scsi_allocate_request(sdev, GFP_KERNEL); if (!srp) return; srp->sr_cmd_len = 12; @@ -5727,7 +5727,7 @@ TRACE2(("gdth_halt(): reset controller %d\n", hanum)); #if LINUX_VERSION_CODE >= 0x020503 sdev = scsi_get_host_dev(gdth_ctr_tab[hanum]); - srp = scsi_allocate_request(sdev); + srp = scsi_allocate_request(sdev, GFP_KERNEL); if (!srp) { #if LINUX_VERSION_CODE >= 0x020100 unregister_reboot_notifier(&gdth_notifier); diff -Nru a/drivers/scsi/gdth.h b/drivers/scsi/gdth.h --- a/drivers/scsi/gdth.h Thu Sep 4 15:38:32 2003 +++ b/drivers/scsi/gdth.h Thu Sep 4 15:38:32 2003 @@ -16,9 +16,6 @@ #include #include -#ifndef NULL -#define NULL 0 -#endif #ifndef TRUE #define TRUE 1 #endif diff -Nru a/drivers/scsi/gdth_proc.c b/drivers/scsi/gdth_proc.c --- a/drivers/scsi/gdth_proc.c Thu Sep 4 15:38:33 2003 +++ b/drivers/scsi/gdth_proc.c Thu Sep 4 15:38:33 2003 @@ -44,7 +44,7 @@ #if LINUX_VERSION_CODE >= 0x020503 sdev = scsi_get_host_dev(gdth_ctr_tab[hanum]); - scp = scsi_allocate_request(sdev); + scp = scsi_allocate_request(sdev, GFP_KERNEL); if (!scp) return -ENOMEM; scp->sr_cmd_len = 12; @@ -797,7 +797,7 @@ #if LINUX_VERSION_CODE >= 0x020503 sdev = scsi_get_host_dev(gdth_ctr_tab[hanum]); - scp = scsi_allocate_request(sdev); + scp = scsi_allocate_request(sdev, GFP_KERNEL); if (!scp) return -ENOMEM; scp->sr_cmd_len = 12; diff -Nru a/drivers/scsi/gvp11.h b/drivers/scsi/gvp11.h --- a/drivers/scsi/gvp11.h Thu Sep 4 15:38:43 2003 +++ b/drivers/scsi/gvp11.h Thu Sep 4 15:38:43 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 Thu Sep 4 15:38:29 2003 +++ b/drivers/scsi/hosts.c Thu Sep 4 15:38:29 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 Thu Sep 4 15:38:31 2003 +++ b/drivers/scsi/hosts.h Thu Sep 4 15:38:31 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 Thu Sep 4 15:38:35 2003 +++ b/drivers/scsi/i91uscsi.h Thu Sep 4 15:38:35 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/ide-scsi.c b/drivers/scsi/ide-scsi.c --- a/drivers/scsi/ide-scsi.c Thu Sep 4 15:38:38 2003 +++ b/drivers/scsi/ide-scsi.c Thu Sep 4 15:38:38 2003 @@ -627,7 +627,6 @@ .version = IDESCSI_VERSION, .media = ide_scsi, .busy = 0, - .supports_dma = 1, .supports_dsc_overlap = 0, .attach = idescsi_attach, .cleanup = idescsi_cleanup, diff -Nru a/drivers/scsi/imm.c b/drivers/scsi/imm.c --- a/drivers/scsi/imm.c Thu Sep 4 15:38:47 2003 +++ b/drivers/scsi/imm.c Thu Sep 4 15:38:47 2003 @@ -86,6 +86,7 @@ int host_no = host->unique_id; printk("Releasing imm%i\n", host_no); + scsi_unregister(host); parport_unregister_device(imm_hosts[host_no].dev); return 0; } diff -Nru a/drivers/scsi/imm.h b/drivers/scsi/imm.h --- a/drivers/scsi/imm.h Thu Sep 4 15:38:28 2003 +++ b/drivers/scsi/imm.h Thu Sep 4 15:38:28 2003 @@ -96,17 +96,17 @@ 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", #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 Thu Sep 4 15:38:35 2003 +++ b/drivers/scsi/ini9100u.h Thu Sep 4 15:38:35 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 Thu Sep 4 15:38:28 2003 +++ b/drivers/scsi/inia100.h Thu Sep 4 15:38:28 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/ips.c b/drivers/scsi/ips.c --- a/drivers/scsi/ips.c Thu Sep 4 15:38:28 2003 +++ b/drivers/scsi/ips.c Thu Sep 4 15:38:28 2003 @@ -199,7 +199,7 @@ #define IPS_VERSION_LOW ".90-BETA" #if !defined(__i386__) && !defined(__ia64__) && !defined(__x86_64__) -#error "This driver has only been tested on the x86/ia64/x86_64 platforms" +#warning "This driver has only been tested on the x86/ia64/x86_64 platforms" #endif #if LINUX_VERSION_CODE <= KERNEL_VERSION(2,5,0) @@ -284,9 +284,9 @@ /* This table describes all ServeRAID Adapters */ static struct pci_device_id ips_pci_table[] = { { 0x1014, 0x002E, PCI_ANY_ID, PCI_ANY_ID, 0, 0 }, - { 0x1014, 0x01BD, PCI_ANY_ID, PCI_ANY_ID, 0, 0 }, - { 0x9005, 0x0250, PCI_ANY_ID, PCI_ANY_ID, 0, 0 }, - { 0, } + { 0x1014, 0x01BD, PCI_ANY_ID, PCI_ANY_ID, 0, 0 }, + { 0x9005, 0x0250, PCI_ANY_ID, PCI_ANY_ID, 0, 0 }, + { 0, } }; MODULE_DEVICE_TABLE( pci, ips_pci_table ); @@ -300,7 +300,7 @@ .name = ips_hot_plug_name, .id_table = ips_pci_table, .probe = ips_insert_device, - .remove = __devexit_p(ips_remove_device), + .remove = __devexit_p(ips_remove_device), }; diff -Nru a/drivers/scsi/mac_scsi.h b/drivers/scsi/mac_scsi.h --- a/drivers/scsi/mac_scsi.h Thu Sep 4 15:38:35 2003 +++ b/drivers/scsi/mac_scsi.h Thu Sep 4 15:38:35 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 Thu Sep 4 15:38:28 2003 +++ b/drivers/scsi/megaraid.c Thu Sep 4 15:38:28 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 Thu Sep 4 15:38:29 2003 +++ b/drivers/scsi/mvme147.h Thu Sep 4 15:38:29 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 Thu Sep 4 15:38:33 2003 +++ b/drivers/scsi/mvme16x.h Thu Sep 4 15:38:33 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/ncr53c8xx.c b/drivers/scsi/ncr53c8xx.c --- a/drivers/scsi/ncr53c8xx.c Thu Sep 4 15:38:31 2003 +++ b/drivers/scsi/ncr53c8xx.c Thu Sep 4 15:38:31 2003 @@ -4357,19 +4357,6 @@ } cp->cmd = cmd; - /*--------------------------------------------------- - ** - ** Enable tagged queue if asked by scsi ioctl - ** - **---------------------------------------------------- - */ -#if 0 /* This stuff was only useful for linux-1.2.13 */ - if (lp && !lp->numtags && cmd->device && cmd->device->tagged_queue) { - lp->numtags = tp->usrtags; - ncr_setup_tags (np, cmd->device->id, cmd->device->lun); - } -#endif - /*---------------------------------------------------- ** ** Build the identify / tag / sdtr message diff -Nru a/drivers/scsi/nsp32.c b/drivers/scsi/nsp32.c --- a/drivers/scsi/nsp32.c Thu Sep 4 15:38:32 2003 +++ b/drivers/scsi/nsp32.c Thu Sep 4 15:38:32 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 Thu Sep 4 15:38:33 2003 +++ b/drivers/scsi/osst.c Thu Sep 4 15:38:33 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 @@ -316,7 +316,7 @@ static int repeat = 0; #endif if (SRpnt == NULL) { - if ((SRpnt = scsi_allocate_request(STp->device)) == NULL) { + if ((SRpnt = scsi_allocate_request(STp->device, GFP_ATOMIC)) == NULL) { printk(KERN_ERR "%s:E: Can't get SCSI request.\n", tape_name(STp)); if (signal_pending(current)) (STp->buffer)->syscall_result = (-EINTR); @@ -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 Thu Sep 4 15:38:39 2003 +++ b/drivers/scsi/pas16.h Thu Sep 4 15:38:39 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 Thu Sep 4 15:38:45 2003 +++ b/drivers/scsi/pci2000.h Thu Sep 4 15:38:45 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 Thu Sep 4 15:38:33 2003 +++ b/drivers/scsi/pci2220i.h Thu Sep 4 15:38:33 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/pcmcia/Kconfig b/drivers/scsi/pcmcia/Kconfig --- a/drivers/scsi/pcmcia/Kconfig Thu Sep 4 15:38:38 2003 +++ b/drivers/scsi/pcmcia/Kconfig Thu Sep 4 15:38:38 2003 @@ -3,7 +3,7 @@ # menu "PCMCIA SCSI adapter support" - depends on SCSI!=n && PCMCIA!=n + depends on SCSI!=n && PCMCIA!=n && MODULES config PCMCIA_AHA152X tristate "Adaptec AHA152X PCMCIA support" diff -Nru a/drivers/scsi/psi240i.h b/drivers/scsi/psi240i.h --- a/drivers/scsi/psi240i.h Thu Sep 4 15:38:43 2003 +++ b/drivers/scsi/psi240i.h Thu Sep 4 15:38:43 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/qla1280.c b/drivers/scsi/qla1280.c --- a/drivers/scsi/qla1280.c Thu Sep 4 15:38:47 2003 +++ b/drivers/scsi/qla1280.c Thu Sep 4 15:38:47 2003 @@ -331,11 +331,17 @@ */ #define QL1280_LUN_SUPPORT 0 #define WATCHDOGTIMER 0 -#define MEMORY_MAPPED_IO 1 + #define DEBUG_QLA1280_INTR 0 #define DEBUG_PRINT_NVRAM 0 #define DEBUG_QLA1280 0 +#ifdef CONFIG_SCSI_QLOGIC_1280_PIO +#define MEMORY_MAPPED_IO 0 +#else +#define MEMORY_MAPPED_IO 1 +#endif + #define UNIQUE_FW_NAME #include "qla1280.h" #include "ql12160_fw.h" /* ISP RISC codes */ @@ -3649,7 +3655,7 @@ (SCSI_TCN_32(cmd) | BIT_7) : SCSI_TCN_32(cmd); /* Enable simple tag queuing if device supports it. */ - if (cmd->device->tagged_queue) + if (cmd->device->simple_tags) pkt->control_flags |= cpu_to_le16(BIT_3); /* Load SCSI command packet. */ @@ -3949,7 +3955,7 @@ (SCSI_TCN_32(cmd) | BIT_7) : SCSI_TCN_32(cmd); /* Enable simple tag queuing if device supports it. */ - if (cmd->device->tagged_queue) + if (cmd->device->simple_tags) pkt->control_flags |= cpu_to_le16(BIT_3); /* Load SCSI command packet. */ @@ -4909,7 +4915,7 @@ } else printk(" Async"); - if (device->tagged_queue) + if (device->simple_tags) printk(", Tagged queuing: depth %d", device->queue_depth); printk("\n"); } diff -Nru a/drivers/scsi/qlogicfc.h b/drivers/scsi/qlogicfc.h --- a/drivers/scsi/qlogicfc.h Thu Sep 4 15:38:32 2003 +++ b/drivers/scsi/qlogicfc.h Thu Sep 4 15:38:32 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 Thu Sep 4 15:38:28 2003 +++ b/drivers/scsi/qlogicisp.h Thu Sep 4 15:38:28 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/scsi.c b/drivers/scsi/scsi.c --- a/drivers/scsi/scsi.c Thu Sep 4 15:38:34 2003 +++ b/drivers/scsi/scsi.c Thu Sep 4 15:38:34 2003 @@ -113,26 +113,21 @@ * * Purpose: Allocate a request descriptor. * - * Arguments: device - device for which we want a request + * Arguments: device - device for which we want a request + * gfp_mask - allocation flags passed to kmalloc * * Lock status: No locks assumed to be held. This function is SMP-safe. * * Returns: Pointer to request block. - * - * Notes: With the new queueing code, it becomes important - * to track the difference between a command and a - * request. A request is a pending item in the queue that - * has not yet reached the top of the queue. - * - * XXX(hch): Need to add a gfp_mask argument. */ -struct scsi_request *scsi_allocate_request(struct scsi_device *sdev) +struct scsi_request *scsi_allocate_request(struct scsi_device *sdev, + int gfp_mask) { const int offset = ALIGN(sizeof(struct scsi_request), 4); const int size = offset + sizeof(struct request); struct scsi_request *sreq; - sreq = kmalloc(size, GFP_ATOMIC); + sreq = kmalloc(size, gfp_mask); if (likely(sreq != NULL)) { memset(sreq, 0, size); sreq->sr_request = (struct request *)(((char *)sreq) + offset); @@ -1006,9 +1001,12 @@ error = scsi_init_hosts(); if (error) goto cleanup_devlist; - error = scsi_sysfs_register(); + error = scsi_init_sysctl(); if (error) goto cleanup_hosts; + error = scsi_sysfs_register(); + if (error) + goto cleanup_sysctl; for (i = 0; i < NR_CPUS; i++) INIT_LIST_HEAD(&done_q[i]); @@ -1018,6 +1016,8 @@ printk(KERN_NOTICE "SCSI subsystem initialized\n"); return 0; +cleanup_sysctl: + scsi_exit_sysctl(); cleanup_hosts: scsi_exit_hosts(); cleanup_devlist: @@ -1034,6 +1034,7 @@ static void __exit exit_scsi(void) { scsi_sysfs_unregister(); + scsi_exit_sysctl(); scsi_exit_hosts(); scsi_exit_devinfo(); devfs_remove("scsi"); diff -Nru a/drivers/scsi/scsi_devinfo.c b/drivers/scsi/scsi_devinfo.c --- a/drivers/scsi/scsi_devinfo.c Thu Sep 4 15:38:32 2003 +++ b/drivers/scsi/scsi_devinfo.c Thu Sep 4 15:38:32 2003 @@ -381,6 +381,7 @@ return scsi_default_dev_flags; } +#ifdef CONFIG_SCSI_PROC_FS /* * proc_scsi_dev_info_read: dump the scsi_dev_info_list via * /proc/scsi/device_info @@ -451,6 +452,7 @@ free_page((unsigned long)buffer); return err; } +#endif /* CONFIG_SCSI_PROC_FS */ module_param_string(dev_flags, scsi_dev_flags, sizeof(scsi_dev_flags), 0); MODULE_PARM_DESC(dev_flags, @@ -471,7 +473,9 @@ struct list_head *lh, *lh_next; struct scsi_dev_info_list *devinfo; +#ifdef CONFIG_SCSI_PROC_FS remove_proc_entry("scsi/device_info", 0); +#endif list_for_each_safe(lh, lh_next, &scsi_dev_info_list) { devinfo = list_entry(lh, struct scsi_dev_info_list, @@ -490,7 +494,9 @@ **/ int scsi_init_devinfo(void) { +#ifdef CONFIG_SCSI_PROC_FS struct proc_dir_entry *p; +#endif int error, i; error = scsi_dev_info_list_add_str(scsi_dev_flags); @@ -507,6 +513,7 @@ goto out; } +#ifdef CONFIG_SCSI_PROC_FS p = create_proc_entry("scsi/device_info", 0, NULL); if (!p) { error = -ENOMEM; @@ -516,6 +523,7 @@ p->owner = THIS_MODULE; p->get_info = proc_scsi_devinfo_read; p->write_proc = proc_scsi_devinfo_write; +#endif /* CONFIG_SCSI_PROC_FS */ out: if (error) diff -Nru a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c --- a/drivers/scsi/scsi_error.c Thu Sep 4 15:38:28 2003 +++ b/drivers/scsi/scsi_error.c Thu Sep 4 15:38:28 2003 @@ -1339,7 +1339,7 @@ **/ static void scsi_eh_lock_door(struct scsi_device *sdev) { - struct scsi_request *sreq = scsi_allocate_request(sdev); + struct scsi_request *sreq = scsi_allocate_request(sdev, GFP_KERNEL); if (unlikely(!sreq)) { printk(KERN_ERR "%s: request allocate failed," diff -Nru a/drivers/scsi/scsi_ioctl.c b/drivers/scsi/scsi_ioctl.c --- a/drivers/scsi/scsi_ioctl.c Thu Sep 4 15:38:46 2003 +++ b/drivers/scsi/scsi_ioctl.c Thu Sep 4 15:38:46 2003 @@ -98,7 +98,7 @@ SCSI_LOG_IOCTL(1, printk("Trying ioctl with scsi command %d\n", *cmd)); - sreq = scsi_allocate_request(sdev); + sreq = scsi_allocate_request(sdev, GFP_KERNEL); if (!sreq) { printk("SCSI internal ioctl failed, no memory\n"); return -ENOMEM; @@ -321,7 +321,7 @@ break; } - sreq = scsi_allocate_request(sdev); + sreq = scsi_allocate_request(sdev, GFP_KERNEL); if (!sreq) { result = -EINTR; goto error; @@ -408,30 +408,6 @@ return 0; case SCSI_IOCTL_GET_BUS_NUMBER: return put_user(sdev->host->host_no, (int *)arg); - /* - * The next two ioctls either need to go or need to be changed to - * pass tagged queueing changes through the low level drivers. - * Simply enabling or disabling tagged queueing without the knowledge - * of the low level driver is a *BAD* thing. - * - * Oct. 10, 2002 - Doug Ledford - */ - case SCSI_IOCTL_TAGGED_ENABLE: - if (!capable(CAP_SYS_ADMIN)) - return -EACCES; - if (!sdev->tagged_supported) - return -EINVAL; - sdev->tagged_queue = 1; - sdev->current_tag = 1; - return 0; - case SCSI_IOCTL_TAGGED_DISABLE: - if (!capable(CAP_SYS_ADMIN)) - return -EACCES; - if (!sdev->tagged_supported) - return -EINVAL; - sdev->tagged_queue = 0; - sdev->current_tag = 0; - return 0; case SCSI_IOCTL_PROBE_HOST: return ioctl_probe(sdev->host, arg); case SCSI_IOCTL_SEND_COMMAND: diff -Nru a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c --- a/drivers/scsi/scsi_lib.c Thu Sep 4 15:38:34 2003 +++ b/drivers/scsi/scsi_lib.c Thu Sep 4 15:38:34 2003 @@ -1454,7 +1454,7 @@ unsigned char *buffer, int len, int timeout, int retries, struct scsi_mode_data *data) { - struct scsi_request *sreq = scsi_allocate_request(sdev); + struct scsi_request *sreq = scsi_allocate_request(sdev, GFP_KERNEL); int ret; if (!sreq) diff -Nru a/drivers/scsi/scsi_logging.h b/drivers/scsi/scsi_logging.h --- a/drivers/scsi/scsi_logging.h Thu Sep 4 15:38:29 2003 +++ b/drivers/scsi/scsi_logging.h Thu Sep 4 15:38:29 2003 @@ -37,39 +37,23 @@ #define SCSI_LOG_HLCOMPLETE_BITS 3 #define SCSI_LOG_IOCTL_BITS 3 +extern unsigned int scsi_logging_level; #ifdef CONFIG_SCSI_LOGGING -extern unsigned int scsi_logging_level; #define SCSI_CHECK_LOGGING(SHIFT, BITS, LEVEL, CMD) \ { \ unsigned int mask = (1 << (BITS)) - 1; \ if (((scsi_logging_level >> (SHIFT)) & mask) > (LEVEL)) \ (CMD); \ } - -#define SCSI_SET_LOGGING(SHIFT, BITS, LEVEL) \ -{ \ - unsigned int mask = ((1 << (BITS)) - 1) << SHIFT; \ - scsi_logging_level = ((scsi_logging_level & ~mask) \ - | ((LEVEL << SHIFT) & mask)); \ -} #else -/* - * With no logging enabled, stub these out so they don't do anything. - */ #define SCSI_CHECK_LOGGING(SHIFT, BITS, LEVEL, CMD) -#define SCSI_SET_LOGGING(SHIFT, BITS, LEVEL) #endif /* CONFIG_SCSI_LOGGING */ /* * These are the macros that are actually used throughout the code to * log events. If logging isn't enabled, they are no-ops and will be * completely absent from the user's code. - * - * The 'set' versions of the macros are really intended to only be called - * from the /proc filesystem, and in production kernels this will be about - * all that is ever used. It could be useful in a debugging environment to - * bump the logging level when certain strange events are detected, however. */ #define SCSI_LOG_ERROR_RECOVERY(LEVEL,CMD) \ SCSI_CHECK_LOGGING(SCSI_LOG_ERROR_SHIFT, SCSI_LOG_ERROR_BITS, LEVEL,CMD); @@ -91,27 +75,5 @@ SCSI_CHECK_LOGGING(SCSI_LOG_HLCOMPLETE_SHIFT, SCSI_LOG_HLCOMPLETE_BITS, LEVEL,CMD); #define SCSI_LOG_IOCTL(LEVEL,CMD) \ SCSI_CHECK_LOGGING(SCSI_LOG_IOCTL_SHIFT, SCSI_LOG_IOCTL_BITS, LEVEL,CMD); - - -#define SCSI_SET_ERROR_RECOVERY_LOGGING(LEVEL) \ - SCSI_SET_LOGGING(SCSI_LOG_ERROR_SHIFT, SCSI_LOG_ERROR_BITS, LEVEL); -#define SCSI_SET_TIMEOUT_LOGGING(LEVEL) \ - SCSI_SET_LOGGING(SCSI_LOG_TIMEOUT_SHIFT, SCSI_LOG_TIMEOUT_BITS, LEVEL); -#define SCSI_SET_SCAN_BUS_LOGGING(LEVEL) \ - SCSI_SET_LOGGING(SCSI_LOG_SCAN_SHIFT, SCSI_LOG_SCAN_BITS, LEVEL); -#define SCSI_SET_MLQUEUE_LOGGING(LEVEL) \ - SCSI_SET_LOGGING(SCSI_LOG_MLQUEUE_SHIFT, SCSI_LOG_MLQUEUE_BITS, LEVEL); -#define SCSI_SET_MLCOMPLETE_LOGGING(LEVEL) \ - SCSI_SET_LOGGING(SCSI_LOG_MLCOMPLETE_SHIFT, SCSI_LOG_MLCOMPLETE_BITS, LEVEL); -#define SCSI_SET_LLQUEUE_LOGGING(LEVEL) \ - SCSI_SET_LOGGING(SCSI_LOG_LLQUEUE_SHIFT, SCSI_LOG_LLQUEUE_BITS, LEVEL); -#define SCSI_SET_LLCOMPLETE_LOGGING(LEVEL) \ - SCSI_SET_LOGGING(SCSI_LOG_LLCOMPLETE_SHIFT, SCSI_LOG_LLCOMPLETE_BITS, LEVEL); -#define SCSI_SET_HLQUEUE_LOGGING(LEVEL) \ - SCSI_SET_LOGGING(SCSI_LOG_HLQUEUE_SHIFT, SCSI_LOG_HLQUEUE_BITS, LEVEL); -#define SCSI_SET_HLCOMPLETE_LOGGING(LEVEL) \ - SCSI_SET_LOGGING(SCSI_LOG_HLCOMPLETE_SHIFT, SCSI_LOG_HLCOMPLETE_BITS, LEVEL); -#define SCSI_SET_IOCTL_LOGGING(LEVEL) \ - SCSI_SET_LOGGING(SCSI_LOG_IOCTL_SHIFT, SCSI_LOG_IOCTL_BITS, LEVEL); #endif /* _SCSI_LOGGING_H */ diff -Nru a/drivers/scsi/scsi_priv.h b/drivers/scsi/scsi_priv.h --- a/drivers/scsi/scsi_priv.h Thu Sep 4 15:38:39 2003 +++ b/drivers/scsi/scsi_priv.h Thu Sep 4 15:38:39 2003 @@ -1,6 +1,17 @@ #ifndef _SCSI_PRIV_H #define _SCSI_PRIV_H +#include +#include + +struct request_queue; +struct scsi_cmnd; +struct scsi_device; +struct scsi_host_template; +struct scsi_request; +struct Scsi_Host; + + /* * These are the values that the owner field can take. * They are used as an indication of who the command belongs to. @@ -98,7 +109,7 @@ extern void scsi_exit_queue(void); /* scsi_proc.c */ -#ifdef CONFIG_PROC_FS +#ifdef CONFIG_SCSI_PROC_FS extern void scsi_proc_hostdir_add(struct scsi_host_template *); extern void scsi_proc_hostdir_rm(struct scsi_host_template *); extern void scsi_proc_host_add(struct Scsi_Host *); @@ -115,11 +126,20 @@ #endif /* CONFIG_PROC_FS */ /* scsi_scan.c */ -int scsi_scan_host_selected(struct Scsi_Host *, unsigned int, unsigned int, - unsigned int, int); +extern int scsi_scan_host_selected(struct Scsi_Host *, unsigned int, + unsigned int, unsigned int, int); extern void scsi_forget_host(struct Scsi_Host *); extern void scsi_free_sdev(struct scsi_device *); extern void scsi_rescan_device(struct device *); + +/* scsi_sysctl.c */ +#ifdef CONFIG_SYSCTL +extern int scsi_init_sysctl(void); +extern void scsi_exit_sysctl(void); +#else +# define scsi_init_sysctl() (0) +# define scsi_exit_sysctl() do { } while (0) +#endif /* CONFIG_SYSCTL */ /* scsi_sysfs.c */ extern int scsi_device_register(struct scsi_device *); diff -Nru a/drivers/scsi/scsi_proc.c b/drivers/scsi/scsi_proc.c --- a/drivers/scsi/scsi_proc.c Thu Sep 4 15:38:29 2003 +++ b/drivers/scsi/scsi_proc.c Thu Sep 4 15:38:29 2003 @@ -37,9 +37,7 @@ /* 4K page size, but our output routines, use some slack for overruns */ #define PROC_BLOCK_SIZE (3*1024) -/* XXX: this shouldn't really be exposed to drivers. */ -struct proc_dir_entry *proc_scsi; -EXPORT_SYMBOL(proc_scsi); +static struct proc_dir_entry *proc_scsi; /* Protect sht->present and sht->proc_dir */ static DECLARE_MUTEX(global_host_template_sem); @@ -235,106 +233,28 @@ char *buffer, *p; int err; - if (!buf || length>PAGE_SIZE) + if (!buf || length > PAGE_SIZE) return -EINVAL; buffer = (char *)__get_free_page(GFP_KERNEL); if (!buffer) return -ENOMEM; - if (copy_from_user(buffer, buf, length)) { - err =-EFAULT; + + err = -EFAULT; + if (copy_from_user(buffer, buf, length)) goto out; - } err = -EINVAL; - if (length < PAGE_SIZE) buffer[length] = '\0'; else if (buffer[PAGE_SIZE-1]) goto out; - if (length < 11 || strncmp("scsi", buffer, 4)) - goto out; - -#ifdef CONFIG_SCSI_LOGGING - /* - * Usage: echo "scsi log token #N" > /proc/scsi/scsi - * where token is one of [error,scan,mlqueue,mlcomplete,llqueue, - * llcomplete,hlqueue,hlcomplete] - */ - if (!strncmp("log", buffer + 5, 3)) { - char *token; - unsigned int level; - - p = buffer + 9; - token = p; - while (*p != ' ' && *p != '\t' && *p != '\0') { - p++; - } - - if (*p == '\0') { - if (strncmp(token, "all", 3) == 0) { - /* - * Turn on absolutely everything. - */ - scsi_logging_level = ~0; - } else if (strncmp(token, "none", 4) == 0) { - /* - * Turn off absolutely everything. - */ - scsi_logging_level = 0; - } else { - goto out; - } - } else { - *p++ = '\0'; - - level = simple_strtoul(p, NULL, 0); - - /* - * Now figure out what to do with it. - */ - if (strcmp(token, "error") == 0) { - SCSI_SET_ERROR_RECOVERY_LOGGING(level); - } else if (strcmp(token, "timeout") == 0) { - SCSI_SET_TIMEOUT_LOGGING(level); - } else if (strcmp(token, "scan") == 0) { - SCSI_SET_SCAN_BUS_LOGGING(level); - } else if (strcmp(token, "mlqueue") == 0) { - SCSI_SET_MLQUEUE_LOGGING(level); - } else if (strcmp(token, "mlcomplete") == 0) { - SCSI_SET_MLCOMPLETE_LOGGING(level); - } else if (strcmp(token, "llqueue") == 0) { - SCSI_SET_LLQUEUE_LOGGING(level); - } else if (strcmp(token, "llcomplete") == 0) { - SCSI_SET_LLCOMPLETE_LOGGING(level); - } else if (strcmp(token, "hlqueue") == 0) { - SCSI_SET_HLQUEUE_LOGGING(level); - } else if (strcmp(token, "hlcomplete") == 0) { - SCSI_SET_HLCOMPLETE_LOGGING(level); - } else if (strcmp(token, "ioctl") == 0) { - SCSI_SET_IOCTL_LOGGING(level); - } else { - goto out; - } - } - - printk(KERN_INFO "scsi logging level set to 0x%8.8x\n", scsi_logging_level); - } -#endif /* CONFIG_SCSI_LOGGING */ - /* * Usage: echo "scsi add-single-device 0 1 2 3" >/proc/scsi/scsi * with "0 1 2 3" replaced by your "Host Channel Id Lun". - * Consider this feature BETA. - * CAUTION: This is not for hotplugging your peripherals. As - * SCSI was not designed for this you could damage your - * hardware ! - * However perhaps it is legal to switch on an - * already connected device. It is perhaps not - * guaranteed this device doesn't corrupt an ongoing data transfer. */ - if (!strncmp("add-single-device", buffer + 5, 17)) { + if (!strncmp("scsi add-single-device", buffer, 22)) { p = buffer + 23; host = simple_strtoul(p, &p, 0); @@ -345,18 +265,12 @@ err = scsi_add_single_device(host, channel, id, lun); if (err >= 0) err = length; + /* * Usage: echo "scsi remove-single-device 0 1 2 3" >/proc/scsi/scsi * with "0 1 2 3" replaced by your "Host Channel Id Lun". - * - * Consider this feature pre-BETA. - * - * CAUTION: This is not for hotplugging your peripherals. As - * SCSI was not designed for this you could damage your - * hardware and thoroughly confuse the SCSI subsystem. - * */ - } else if (!strncmp("remove-single-device", buffer + 5, 20)) { + } else if (!strncmp("scsi remove-single-device", buffer, 25)) { p = buffer + 26; host = simple_strtoul(p, &p, 0); @@ -366,8 +280,8 @@ err = scsi_remove_single_device(host, channel, id, lun); } -out: - + + out: free_page((unsigned long)buffer); return err; } diff -Nru a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c --- a/drivers/scsi/scsi_scan.c Thu Sep 4 15:38:42 2003 +++ b/drivers/scsi/scsi_scan.c Thu Sep 4 15:38:42 2003 @@ -30,6 +30,7 @@ #include #include #include +#include #include "scsi.h" #include "hosts.h" @@ -94,6 +95,13 @@ " between 1 and 16384)"); #endif +/* + * This mutex serializes all scsi scanning activity from kernel- and + * userspace. It could easily be made per-host but I'd like to avoid + * the overhead for now. + */ +static DECLARE_MUTEX(scsi_scan_mutex); + /** * scsi_unlock_floptical - unlock device via a special MODE SENSE command * @sreq: used to send the command @@ -685,7 +693,7 @@ sdev = scsi_alloc_sdev(host, channel, id, lun); if (!sdev) goto out; - sreq = scsi_allocate_request(sdev); + sreq = scsi_allocate_request(sdev, GFP_ATOMIC); if (!sreq) goto out_free_sdev; result = kmalloc(256, GFP_ATOMIC | @@ -898,7 +906,7 @@ if (bflags & BLIST_NOLUN) return 0; - sreq = scsi_allocate_request(sdev); + sreq = scsi_allocate_request(sdev, GFP_ATOMIC); if (!sreq) goto out; @@ -1067,9 +1075,12 @@ struct scsi_device *sdev; int res; + down(&scsi_scan_mutex); res = scsi_probe_and_add_lun(shost, channel, id, lun, NULL, &sdev, 1); if (res != SCSI_SCAN_LUN_PRESENT) sdev = ERR_PTR(-ENODEV); + up(&scsi_scan_mutex); + return sdev; } @@ -1191,11 +1202,14 @@ ((lun != SCAN_WILD_CARD) && (lun > shost->max_lun))) return -EINVAL; + down(&scsi_scan_mutex); if (channel == SCAN_WILD_CARD) for (channel = 0; channel <= shost->max_channel; channel++) scsi_scan_channel(shost, channel, id, lun, rescan); else scsi_scan_channel(shost, channel, id, lun, rescan); + up(&scsi_scan_mutex); + return 0; } diff -Nru a/drivers/scsi/scsi_sysctl.c b/drivers/scsi/scsi_sysctl.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/drivers/scsi/scsi_sysctl.c Thu Sep 4 15:38:48 2003 @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2003 Christoph Hellwig. + * Released under GPL v2. + */ + +#include +#include +#include +#include + +#include "scsi_logging.h" + + +static ctl_table scsi_table[] = { + { .ctl_name = DEV_SCSI_LOGGING_LEVEL, + .procname = "logging_level", + .data = &scsi_logging_level, + .maxlen = sizeof(scsi_logging_level), + .mode = 0644, + .proc_handler = &proc_dointvec }, + { } +}; + +static ctl_table scsi_dir_table[] = { + { .ctl_name = DEV_SCSI, + .procname = "scsi", + .mode = 0555, + .child = scsi_table }, + { } +}; + +static ctl_table scsi_root_table[] = { + { .ctl_name = CTL_DEV, + .procname = "dev", + .mode = 0555, + .child = scsi_dir_table }, + { } +}; + +static struct ctl_table_header *scsi_table_header; + +int __init scsi_init_sysctl(void) +{ + scsi_table_header = register_sysctl_table(scsi_root_table, 1); + if (!scsi_table_header) + return -ENOMEM; + return 0; +} + +void scsi_exit_sysctl(void) +{ + unregister_sysctl_table(scsi_table_header); +} diff -Nru a/drivers/scsi/sd.c b/drivers/scsi/sd.c --- a/drivers/scsi/sd.c Thu Sep 4 15:38:41 2003 +++ b/drivers/scsi/sd.c Thu Sep 4 15:38:41 2003 @@ -370,25 +370,24 @@ if (!scsi_block_when_processing_errors(sdev)) goto error_out; - if (sdev->removable) { + if (sdev->removable || sdkp->write_prot) check_disk_change(inode->i_bdev); - /* - * If the drive is empty, just let the open fail. - */ - retval = -ENOMEDIUM; - if ((!sdkp->media_present) && !(filp->f_flags & O_NDELAY)) - goto error_out; + /* + * If the drive is empty, just let the open fail. + */ + retval = -ENOMEDIUM; + if (sdev->removable && !sdkp->media_present && + !(filp->f_flags & O_NDELAY)) + goto error_out; - /* - * Similarly, if the device has the write protect tab set, - * have the open fail if the user expects to be able to write - * to the thing. - */ - retval = -EROFS; - if ((sdkp->write_prot) && (filp->f_mode & FMODE_WRITE)) - goto error_out; - } + /* + * If the device has the write protect tab set, have the open fail + * if the user expects to be able to write to the thing. + */ + retval = -EROFS; + if (sdkp->write_prot && (filp->f_mode & FMODE_WRITE)) + goto error_out; /* * It is possible that the disk changing stuff resulted in @@ -1174,7 +1173,7 @@ if (!sdp->online) goto out; - sreq = scsi_allocate_request(sdp); + sreq = scsi_allocate_request(sdp, GFP_KERNEL); if (!sreq) { printk(KERN_WARNING "(sd_revalidate_disk:) Request allocation " "failure.\n"); @@ -1355,12 +1354,12 @@ static void sd_shutdown(struct device *dev) { struct scsi_device *sdp = to_scsi_device(dev); - struct scsi_disk *sdkp; + struct scsi_disk *sdkp; struct scsi_request *sreq; int retries, res; - sdkp = dev_get_drvdata(dev); - if (!sdkp) + sdkp = dev_get_drvdata(dev); + if (!sdkp) return; /* this can happen */ if (!sdp->online || !sdkp->WCE) @@ -1369,7 +1368,7 @@ printk(KERN_NOTICE "Synchronizing SCSI cache for disk %s: ", sdkp->disk->disk_name); - sreq = scsi_allocate_request(sdp); + sreq = scsi_allocate_request(sdp, GFP_KERNEL); if (!sreq) { printk("FAILED\n No memory for request\n"); return; diff -Nru a/drivers/scsi/sg.c b/drivers/scsi/sg.c --- a/drivers/scsi/sg.c Thu Sep 4 15:38:33 2003 +++ b/drivers/scsi/sg.c Thu Sep 4 15:38:33 2003 @@ -70,7 +70,7 @@ #include "scsi_logging.h" -#ifdef CONFIG_PROC_FS +#ifdef CONFIG_SCSI_PROC_FS #include static int sg_proc_init(void); static void sg_proc_cleanup(void); @@ -222,7 +222,7 @@ // static void sg_unmap_and(Sg_scatter_hold * schp, int free_also); static Sg_device *sg_get_dev(int dev); static inline unsigned char *sg_scatg2virt(const struct scatterlist *sclp); -#ifdef CONFIG_PROC_FS +#ifdef CONFIG_SCSI_PROC_FS static int sg_last_dev(void); #endif @@ -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; @@ -680,7 +680,7 @@ sg_finish_rem_req(srp); return -ENODEV; } - SRpnt = scsi_allocate_request(sdp->device); + SRpnt = scsi_allocate_request(sdp->device, GFP_ATOMIC); if (SRpnt == NULL) { SCSI_LOG_TIMEOUT(1, printk("sg_write: no mem\n")); sg_finish_rem_req(srp); @@ -1516,18 +1516,18 @@ rc = scsi_register_interface(&sg_interface); if (rc) return rc; -#ifdef CONFIG_PROC_FS +#ifdef CONFIG_SCSI_PROC_FS sg_proc_init(); -#endif /* CONFIG_PROC_FS */ +#endif /* CONFIG_SCSI_PROC_FS */ return 0; } static void __exit exit_sg(void) { -#ifdef CONFIG_PROC_FS +#ifdef CONFIG_SCSI_PROC_FS sg_proc_cleanup(); -#endif /* CONFIG_PROC_FS */ +#endif /* CONFIG_SCSI_PROC_FS */ scsi_unregister_interface(&sg_interface); unregister_chrdev(SCSI_GENERIC_MAJOR, "sg"); if (sg_dev_arr != NULL) { @@ -2225,7 +2225,7 @@ return resp; } -#ifdef CONFIG_PROC_FS +#ifdef CONFIG_SCSI_PROC_FS static Sg_request * sg_get_nth_request(Sg_fd * sfp, int nth) { @@ -2317,7 +2317,7 @@ return res; } -#ifdef CONFIG_PROC_FS +#ifdef CONFIG_SCSI_PROC_FS static Sg_fd * sg_get_nth_sfp(Sg_device * sdp, int nth) { @@ -2548,7 +2548,7 @@ return 0; } -#ifdef CONFIG_PROC_FS +#ifdef CONFIG_SCSI_PROC_FS static int sg_last_dev(void) { @@ -2579,11 +2579,11 @@ return sdp; } -#ifdef CONFIG_PROC_FS +#ifdef CONFIG_SCSI_PROC_FS static struct proc_dir_entry *sg_proc_sgp = NULL; -static char sg_proc_sg_dirname[] = "sg"; +static char sg_proc_sg_dirname[] = "scsi/sg"; static int sg_proc_adio_read(char *buffer, char **start, off_t offset, int size, int *eof, void *data); @@ -2657,10 +2657,6 @@ size : begin + len - offset; \ } while(0) -/* this should _really_ be private to the scsi midlayer. But - /proc/scsi/sg is an established name, so.. */ -extern struct proc_dir_entry *proc_scsi; - static int sg_proc_init(void) { @@ -2670,10 +2666,8 @@ struct proc_dir_entry *pdep; struct sg_proc_leaf * leaf; - if (!proc_scsi) - return 1; sg_proc_sgp = create_proc_entry(sg_proc_sg_dirname, - S_IFDIR | S_IRUGO | S_IXUGO, proc_scsi); + S_IFDIR | S_IRUGO | S_IXUGO, NULL); if (!sg_proc_sgp) return 1; for (k = 0; k < num_leaves; ++k) { @@ -2696,11 +2690,11 @@ int num_leaves = sizeof (sg_proc_leaf_arr) / sizeof (sg_proc_leaf_arr[0]); - if ((!proc_scsi) || (!sg_proc_sgp)) + if (!sg_proc_sgp) return; for (k = 0; k < num_leaves; ++k) remove_proc_entry(sg_proc_leaf_arr[k].name, sg_proc_sgp); - remove_proc_entry(sg_proc_sg_dirname, proc_scsi); + remove_proc_entry(sg_proc_sg_dirname, NULL); } static int @@ -2971,7 +2965,7 @@ PRINT_PROC("%d\t%s\n", sg_version_num, sg_version_str); return 1; } -#endif /* CONFIG_PROC_FS */ +#endif /* CONFIG_SCSI_PROC_FS */ module_init(init_sg); module_exit(exit_sg); diff -Nru a/drivers/scsi/sgiwd93.h b/drivers/scsi/sgiwd93.h --- a/drivers/scsi/sgiwd93.h Thu Sep 4 15:38:32 2003 +++ b/drivers/scsi/sgiwd93.h Thu Sep 4 15:38:32 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 Thu Sep 4 15:38:31 2003 +++ b/drivers/scsi/sr.c Thu Sep 4 15:38:31 2003 @@ -599,7 +599,7 @@ buffer = kmalloc(512, GFP_KERNEL | GFP_DMA); if (!buffer) goto Enomem; - SRpnt = scsi_allocate_request(cd->device); + SRpnt = scsi_allocate_request(cd->device, GFP_KERNEL); if (!SRpnt) goto Enomem; @@ -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, GFP_KERNEL); + 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/sr_ioctl.c b/drivers/scsi/sr_ioctl.c --- a/drivers/scsi/sr_ioctl.c Thu Sep 4 15:38:38 2003 +++ b/drivers/scsi/sr_ioctl.c Thu Sep 4 15:38:38 2003 @@ -82,7 +82,7 @@ int result, err = 0, retries = 0; SDev = cd->device; - SRpnt = scsi_allocate_request(SDev); + SRpnt = scsi_allocate_request(SDev, GFP_KERNEL); if (!SRpnt) { printk(KERN_ERR "Unable to allocate SCSI request in sr_do_ioctl"); err = -ENOMEM; diff -Nru a/drivers/scsi/st.c b/drivers/scsi/st.c --- a/drivers/scsi/st.c Thu Sep 4 15:38:38 2003 +++ b/drivers/scsi/st.c Thu Sep 4 15:38:38 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) */ @@ -374,7 +374,7 @@ unsigned char *bp; if (SRpnt == NULL) { - SRpnt = scsi_allocate_request(STp->device); + SRpnt = scsi_allocate_request(STp->device, GFP_ATOMIC); if (SRpnt == NULL) { DEBC( printk(KERN_ERR "%s: Can't get SCSI request.\n", tape_name(STp)); ); @@ -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 Thu Sep 4 15:38:29 2003 +++ b/drivers/scsi/sun3_scsi.h Thu Sep 4 15:38:29 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/sym53c8xx.c b/drivers/scsi/sym53c8xx.c --- a/drivers/scsi/sym53c8xx.c Thu Sep 4 15:38:39 2003 +++ b/drivers/scsi/sym53c8xx.c Thu Sep 4 15:38:39 2003 @@ -6594,19 +6594,6 @@ } cp->cmd = cmd; - /*--------------------------------------------------- - ** - ** Enable tagged queue if asked by scsi ioctl - ** - **---------------------------------------------------- - */ -#if 0 /* This stuff was only useful for linux-1.2.13 */ - if (lp && !lp->numtags && cmd->device && cmd->device->tagged_queue) { - lp->numtags = tp->usrtags; - ncr_setup_tags (np, cp->target, cp->lun); - } -#endif - /*---------------------------------------------------- ** ** Build the identify / tag / sdtr message diff -Nru a/drivers/scsi/sym53c8xx_2/sym_conf.h b/drivers/scsi/sym53c8xx_2/sym_conf.h --- a/drivers/scsi/sym53c8xx_2/sym_conf.h Thu Sep 4 15:38:42 2003 +++ b/drivers/scsi/sym53c8xx_2/sym_conf.h Thu Sep 4 15:38:42 2003 @@ -131,11 +131,6 @@ /* #define SYM_CONF_IARB_SUPPORT */ /* - * Support for some PCI fix-ups (or assumed so). - */ -#define SYM_CONF_PCI_FIX_UP - -/* * Number of lists for the optimization of the IO timeout handling. * Not used under FreeBSD and Linux. */ diff -Nru a/drivers/scsi/sym53c8xx_2/sym_defs.h b/drivers/scsi/sym53c8xx_2/sym_defs.h --- a/drivers/scsi/sym53c8xx_2/sym_defs.h Thu Sep 4 15:38:32 2003 +++ b/drivers/scsi/sym53c8xx_2/sym_defs.h Thu Sep 4 15:38:32 2003 @@ -74,8 +74,8 @@ #define PCI_ID_SYM53C896 0xb #define PCI_ID_SYM53C895A 0x12 #define PCI_ID_SYM53C875A 0x13 -#define PCI_ID_LSI53C1010 0x20 -#define PCI_ID_LSI53C1010_2 0x21 +#define PCI_ID_LSI53C1010_33 0x20 +#define PCI_ID_LSI53C1010_66 0x21 #define PCI_ID_LSI53C1510D 0xa /* diff -Nru a/drivers/scsi/sym53c8xx_2/sym_fw.c b/drivers/scsi/sym53c8xx_2/sym_fw.c --- a/drivers/scsi/sym53c8xx_2/sym_fw.c Thu Sep 4 15:38:47 2003 +++ b/drivers/scsi/sym53c8xx_2/sym_fw.c Thu Sep 4 15:38:47 2003 @@ -270,13 +270,13 @@ * Remove a couple of work-arounds specific to C1010 if * they are not desirable. See `sym_fw2.h' for more details. */ - if (!(np->device_id == PCI_ID_LSI53C1010_2 && + if (!(np->device_id == PCI_ID_LSI53C1010_66 && np->revision_id < 0x1 && np->pciclk_khz < 60000)) { scripta0->datao_phase[0] = cpu_to_scr(SCR_NO_OP); scripta0->datao_phase[1] = cpu_to_scr(0); } - if (!(np->device_id == PCI_ID_LSI53C1010 && + if (!(np->device_id == PCI_ID_LSI53C1010_33 && /* np->revision_id < 0xff */ 1)) { scripta0->sel_done[0] = cpu_to_scr(SCR_NO_OP); scripta0->sel_done[1] = cpu_to_scr(0); diff -Nru a/drivers/scsi/sym53c8xx_2/sym_glue.c b/drivers/scsi/sym53c8xx_2/sym_glue.c --- a/drivers/scsi/sym53c8xx_2/sym_glue.c Thu Sep 4 15:38:48 2003 +++ b/drivers/scsi/sym53c8xx_2/sym_glue.c Thu Sep 4 15:38:48 2003 @@ -57,7 +57,7 @@ #define NAME53C "sym53c" #define NAME53C8XX "sym53c8xx" -static int __init +static int __devinit pci_get_base_address(struct pci_dev *pdev, int index, u_long *base) { u32 tmp; @@ -77,30 +77,6 @@ #undef PCI_BAR_OFFSET } -/* - * Insert a delay in micro-seconds and milli-seconds. - */ -void sym_udelay(int us) { udelay(us); } -void sym_mdelay(int ms) { mdelay(ms); } - -/* - * SMP threading. - * - * The whole SCSI sub-system under Linux is basically single-threaded. - * Everything, including low-level driver interrupt routine, happens - * with the `io_request_lock' held. - * The sym53c8xx-1.x drivers series ran their interrupt code using a - * spin mutex per controller. This added complexity without improving - * scalability significantly. the sym-2 driver still use a spinlock - * per controller for safety, but basically runs with the damned - * io_request_lock held. - */ - -spinlock_t sym53c8xx_lock = SPIN_LOCK_UNLOCKED; - -#define SYM_LOCK_DRIVER(flags) spin_lock_irqsave(&sym53c8xx_lock, flags) -#define SYM_UNLOCK_DRIVER(flags) spin_unlock_irqrestore(&sym53c8xx_lock,flags) - #define SYM_INIT_LOCK_HCB(np) spin_lock_init((np)->s.host->host_lock); #define SYM_LOCK_HCB(np, flags) \ spin_lock_irqsave((np)->s.host->host_lock, flags) @@ -118,6 +94,9 @@ #define ktime_add(a, o) ((a) + (u_long)(o)) #define ktime_sub(a, o) ((a) - (u_long)(o)) +/* This lock protects only the memory allocation/free. */ +spinlock_t sym53c8xx_lock = SPIN_LOCK_UNLOCKED; + /* * Wrappers to the generic memory allocator. */ @@ -125,58 +104,53 @@ { u_long flags; void *m; - SYM_LOCK_DRIVER(flags); + spin_lock_irqsave(&sym53c8xx_lock, flags); m = sym_calloc_unlocked(size, name); - SYM_UNLOCK_DRIVER(flags); + spin_unlock_irqrestore(&sym53c8xx_lock, flags); return m; } void sym_mfree(void *m, int size, char *name) { u_long flags; - SYM_LOCK_DRIVER(flags); + spin_lock_irqsave(&sym53c8xx_lock, flags); sym_mfree_unlocked(m, size, name); - SYM_UNLOCK_DRIVER(flags); + spin_unlock_irqrestore(&sym53c8xx_lock, flags); } -#ifdef SYM_LINUX_DYNAMIC_DMA_MAPPING - void *__sym_calloc_dma(m_pool_ident_t dev_dmat, int size, char *name) { u_long flags; void *m; - SYM_LOCK_DRIVER(flags); + spin_lock_irqsave(&sym53c8xx_lock, flags); m = __sym_calloc_dma_unlocked(dev_dmat, size, name); - SYM_UNLOCK_DRIVER(flags); + spin_unlock_irqrestore(&sym53c8xx_lock, flags); return m; } void __sym_mfree_dma(m_pool_ident_t dev_dmat, void *m, int size, char *name) { u_long flags; - SYM_LOCK_DRIVER(flags); + spin_lock_irqsave(&sym53c8xx_lock, flags); __sym_mfree_dma_unlocked(dev_dmat, m, size, name); - SYM_UNLOCK_DRIVER(flags); + spin_unlock_irqrestore(&sym53c8xx_lock, flags); } m_addr_t __vtobus(m_pool_ident_t dev_dmat, void *m) { u_long flags; m_addr_t b; - SYM_LOCK_DRIVER(flags); + spin_lock_irqsave(&sym53c8xx_lock, flags); b = __vtobus_unlocked(dev_dmat, m); - SYM_UNLOCK_DRIVER(flags); + spin_unlock_irqrestore(&sym53c8xx_lock, flags); return b; } -#endif /* SYM_LINUX_DYNAMIC_DMA_MAPPING */ - - /* * Map/unmap a PCI memory window. */ #ifndef SYM_OPT_NO_BUS_MEMORY_MAPPING -static u_long __init pci_map_mem(u_long base, u_long size) +static u_long __devinit pci_map_mem(u_long base, u_long size) { u_long page_base = ((u_long) base) & PAGE_MASK; u_long page_offs = ((u_long) base) - page_base; @@ -185,19 +159,13 @@ return page_remapped? (page_remapped + page_offs) : 0UL; } -static void __init pci_unmap_mem(u_long vaddr, u_long size) +static void __devinit pci_unmap_mem(u_long vaddr, u_long size) { if (vaddr) iounmap((void *) (vaddr & PAGE_MASK)); } #endif -/* - * Used to retrieve the host structure when the - * driver is called from the proc FS. - */ -static struct Scsi_Host *first_host = NULL; - #define scsi_data_direction(cmd) (cmd->sc_data_direction) /* @@ -210,11 +178,7 @@ /* * Some type that fit DMA addresses as seen from BUS. */ -#ifndef SYM_LINUX_DYNAMIC_DMA_MAPPING -typedef u_long bus_addr_t; -#else typedef dma_addr_t bus_addr_t; -#endif /* * Used by the eh thread to wait for command completion. @@ -233,10 +197,8 @@ */ struct sym_ucmd { /* Override the SCSI pointer structure */ SYM_QUEHEAD link_cmdq; /* Must stay at offset ZERO */ -#ifdef SYM_LINUX_DYNAMIC_DMA_MAPPING bus_addr_t data_mapping; u_char data_mapped; -#endif struct sym_eh_wait *eh_wait; }; @@ -249,39 +211,18 @@ /* * Deal with DMA mapping/unmapping. */ - -#ifndef SYM_LINUX_DYNAMIC_DMA_MAPPING - -/* Linux versions prior to pci bus iommu kernel interface */ - -#define __unmap_scsi_data(pdev, cmd) do {; } while (0) -#define __map_scsi_single_data(pdev, cmd) (__vtobus(pdev,(cmd)->request_buffer)) -#define __map_scsi_sg_data(pdev, cmd) ((cmd)->use_sg) -#define __sync_scsi_data(pdev, cmd) do {; } while (0) - -#define bus_sg_dma_address(sc) vtobus((sc)->address) -#define bus_sg_dma_len(sc) ((sc)->length) - -#else /* Linux version with pci bus iommu kernel interface */ - #define bus_unmap_sg(pdev, sgptr, sgcnt, dir) \ pci_unmap_sg(pdev, sgptr, sgcnt, dir) - #define bus_unmap_single(pdev, mapping, bufptr, dir) \ pci_unmap_single(pdev, mapping, bufptr, dir) - #define bus_map_single(pdev, bufptr, bufsiz, dir) \ pci_map_single(pdev, bufptr, bufsiz, dir) - #define bus_map_sg(pdev, sgptr, sgcnt, dir) \ pci_map_sg(pdev, sgptr, sgcnt, dir) - #define bus_dma_sync_sg(pdev, sgptr, sgcnt, dir) \ pci_dma_sync_sg(pdev, sgptr, sgcnt, dir) - #define bus_dma_sync_single(pdev, mapping, bufsiz, dir) \ pci_dma_sync_single(pdev, mapping, bufsiz, dir) - #define bus_sg_dma_address(sc) sg_dma_address(sc) #define bus_sg_dma_len(sc) sg_dma_len(sc) @@ -345,8 +286,6 @@ } } -#endif /* SYM_LINUX_DYNAMIC_DMA_MAPPING */ - #define unmap_scsi_data(np, cmd) \ __unmap_scsi_data(np->s.device, cmd) #define map_scsi_single_data(np, cmd) \ @@ -1656,13 +1595,13 @@ copy_info(&info, "Chip " NAME53C "%s, device id 0x%x, " "revision id 0x%x\n", np->s.chip_name, np->device_id, np->revision_id); - copy_info(&info, "On PCI bus %d, device %d, function %d, " + copy_info(&info, "At PCI address %s, " #ifdef __sparc__ "IRQ %s\n", #else "IRQ %d\n", #endif - np->s.bus, (np->s.device_fn & 0xf8) >> 3, np->s.device_fn & 7, + pci_name(np->s.device), #ifdef __sparc__ __irq_itoa(np->s.irq)); #else @@ -1748,7 +1687,6 @@ /* * Ask/tell the system about DMA addressing. */ -#ifdef SYM_LINUX_DYNAMIC_DMA_MAPPING static int sym_setup_bus_dma_mask(hcb_p np) { #if SYM_CONF_DMA_ADDRESSING_MODE == 0 @@ -1780,7 +1718,6 @@ sym_name(np)); return -1; } -#endif /* SYM_LINUX_DYNAMIC_DMA_MAPPING */ /* * Host attach and initialisations. @@ -1791,7 +1728,7 @@ * If all is OK, install interrupt handling and * start the timer daemon. */ -static int __init +static int __devinit sym_attach (struct scsi_host_template *tpnt, int unit, sym_device *dev) { struct host_data *host_data; @@ -1802,15 +1739,14 @@ struct sym_fw *fw; printk(KERN_INFO - "sym%d: <%s> rev 0x%x on pci bus %d device %d function %d " + "sym%d: <%s> rev 0x%x at pci %s " #ifdef __sparc__ "irq %s\n", #else "irq %d\n", #endif unit, dev->chip.name, dev->chip.revision_id, - dev->s.bus, (dev->s.device_fn & 0xf8) >> 3, - dev->s.device_fn & 7, + pci_name(dev->pdev), #ifdef __sparc__ __irq_itoa(dev->s.irq)); #else @@ -1837,7 +1773,6 @@ * We keep track in the HCB of all the resources that * are to be released on error. */ -#ifdef SYM_LINUX_DYNAMIC_DMA_MAPPING np = __sym_calloc_dma(dev->pdev, sizeof(*np), "HCB"); if (np) { np->s.device = dev->pdev; @@ -1845,11 +1780,7 @@ } else goto attach_failed; -#else - np = sym_calloc_dma(sizeof(*np), "HCB"); - if (!np) - goto attach_failed; -#endif + host_data->ncb = np; np->s.host = instance; @@ -1866,8 +1797,6 @@ np->s.unit = unit; np->device_id = dev->chip.device_id; np->revision_id = dev->chip.revision_id; - np->s.bus = dev->s.bus; - np->s.device_fn = dev->s.device_fn; np->features = dev->chip.features; np->clock_divn = dev->chip.nr_divisor; np->maxoffs = dev->chip.offset_max; @@ -1883,10 +1812,8 @@ /* * Ask/tell the system about DMA addressing. */ -#ifdef SYM_LINUX_DYNAMIC_DMA_MAPPING if (sym_setup_bus_dma_mask(np)) goto attach_failed; -#endif /* * Try to map the controller chip to @@ -1987,12 +1914,6 @@ sym_timer (np); /* - * Done. - */ - if (!first_host) - first_host = instance; - - /* * Fill Linux host instance structure * and return success. */ @@ -2039,7 +1960,7 @@ * Detect and try to read SYMBIOS and TEKRAM NVRAM. */ #if SYM_CONF_NVRAM_SUPPORT -static void __init sym_get_nvram(sym_device *devp, sym_nvram *nvp) +static void __devinit sym_get_nvram(sym_device *devp, sym_nvram *nvp) { if (!nvp) return; @@ -2087,37 +2008,6 @@ MODULE_PARM(sym53c8xx, "s"); #endif -static void __init sym53c8xx_print_driver_setup(void) -{ - printf_info (NAME53C8XX ": setup=" - "mpar:%d,spar:%d,tags:%d,sync:%d,burst:%d," - "led:%d,wide:%d,diff:%d,irqm:%d, buschk:%d\n", - sym_driver_setup.pci_parity, - sym_driver_setup.scsi_parity, - sym_driver_setup.max_tag, - sym_driver_setup.min_sync, - sym_driver_setup.burst_order, - sym_driver_setup.scsi_led, - sym_driver_setup.max_wide, - sym_driver_setup.scsi_diff, - sym_driver_setup.irq_mode, - sym_driver_setup.scsi_bus_check); - printf_info (NAME53C8XX ": setup=" - "hostid:%d,offs:%d,luns:%d,pcifix:%d,revprob:%d," - "verb:%d,debug:0x%x,setlle_delay:%d\n", - sym_driver_setup.host_id, - sym_driver_setup.max_offs, - sym_driver_setup.max_lun, - sym_driver_setup.pci_fix_up, - sym_driver_setup.reverse_probe, - sym_driver_setup.verbose, - sym_driver_setup.debug, - sym_driver_setup.settle_delay); -#ifdef DEBUG_2_0_X -MDELAY(5000); -#endif -}; - #define OPT_PCI_PARITY 1 #define OPT_SCSI_PARITY 2 #define OPT_MAX_TAG 3 @@ -2131,15 +2021,13 @@ #define OPT_HOST_ID 11 #define OPT_MAX_OFFS 12 #define OPT_MAX_LUN 13 -#define OPT_PCI_FIX_UP 14 - -#define OPT_REVERSE_PROBE 15 -#define OPT_VERBOSE 16 -#define OPT_DEBUG 17 -#define OPT_SETTLE_DELAY 18 -#define OPT_USE_NVRAM 19 -#define OPT_EXCLUDE 20 -#define OPT_SAFE_SETUP 21 +#define OPT_REVERSE_PROBE 14 +#define OPT_VERBOSE 15 +#define OPT_DEBUG 16 +#define OPT_SETTLE_DELAY 17 +#define OPT_USE_NVRAM 18 +#define OPT_EXCLUDE 19 +#define OPT_SAFE_SETUP 20 static char setup_token[] __initdata = "mpar:" "spar:" @@ -2148,11 +2036,10 @@ "wide:" "diff:" "irqm:" "buschk:" "hostid:" "offset:" - "luns:" "pcifix:" - "revprob:" "verb:" - "debug:" "settle:" - "nvram:" "excl:" - "safe:" + "luns:" "revprob:" + "verb:" "debug:" + "settle:" "nvram:" + "excl:" "safe:" ; #ifdef MODULE @@ -2239,7 +2126,6 @@ __SIMPLE_OPTION(HOST_ID, host_id) __SIMPLE_OPTION(MAX_OFFS, max_offs) __SIMPLE_OPTION(MAX_LUN, max_lun) - __SIMPLE_OPTION(PCI_FIX_UP, pci_fix_up) __SIMPLE_OPTION(REVERSE_PROBE, reverse_probe) __SIMPLE_OPTION(VERBOSE, verbose) __SIMPLE_OPTION(DEBUG, debug) @@ -2269,19 +2155,16 @@ * boards and save data for attaching after all boards have * been detected. */ -static int __init +static int __devinit sym53c8xx_pci_init(struct pci_dev *pdev, sym_device *device) { - u_short vendor_id, device_id, command, status_reg; - u_char cache_line_size; - u_char suggested_cache_line_size = 0; - u_char pci_fix_up = SYM_SETUP_PCI_FIX_UP; + u_short vendor_id, device_id, status_reg; u_char revision; u_int irq; u_long base, base_2; u_long base_c, base_2_c, io_port; int i; - sym_chip *chip; + struct sym_pci_chip *chip; /* Choose some short name for this device */ sprintf(device->s.inst_name, "sym.%d.%d.%d", pdev->bus->number, @@ -2393,25 +2276,6 @@ pci_set_master(pdev); /* - * Read additionnal info from the configuration space. - */ - pci_read_config_byte(pdev, PCI_CACHE_LINE_SIZE, &cache_line_size); - - /* - * If cache line size is not configured, suggest - * a value for well known CPUs. - */ -#if defined(__i386__) && !defined(MODULE) - if (!cache_line_size && boot_cpu_data.x86_vendor == X86_VENDOR_INTEL) { - switch(boot_cpu_data.x86) { - case 4: suggested_cache_line_size = 4; break; - case 6: if (boot_cpu_data.x86_model > 8) break; - case 5: suggested_cache_line_size = 8; break; - } - } -#endif /* __i386__ */ - - /* * Some features are required to be enabled in order to * work around some chip problems. :) ;) * (ITEM 12 of a DEL about the 896 I haven't yet). @@ -2420,31 +2284,12 @@ */ if (device_id == PCI_DEVICE_ID_NCR_53C896 && revision < 0x4) { chip->features |= (FE_WRIE | FE_CLSE); - pci_fix_up |= 3; /* Force appropriate PCI fix-up */ } -#ifdef SYM_CONF_PCI_FIX_UP - /* - * Try to fix up PCI config according to wished features. - */ - if ((pci_fix_up & 1) && (chip->features & FE_CLSE) && - !cache_line_size && suggested_cache_line_size) { - cache_line_size = suggested_cache_line_size; - pci_write_config_byte(pdev, - PCI_CACHE_LINE_SIZE, cache_line_size); - printf_info("%s: PCI_CACHE_LINE_SIZE set to %d.\n", - sym_name(device), cache_line_size); - } - - pci_read_config_word(pdev, PCI_COMMAND, &command); - if ((pci_fix_up & 2) && cache_line_size && - (chip->features & FE_WRIE) && !(command & PCI_COMMAND_INVALIDATE)) { - printf_info("%s: setting PCI_COMMAND_INVALIDATE.\n", - sym_name(device)); - command |= PCI_COMMAND_INVALIDATE; - pci_write_config_word(pdev, PCI_COMMAND, command); + if (chip->features & FE_WRIE) { + if (pci_set_mwi(pdev)) + return -1; } -#endif /* SYM_CONF_PCI_FIX_UP */ /* * Work around for errant bit in 895A. The 66Mhz @@ -2461,8 +2306,7 @@ if (chip->features & FE_66MHZ) { if (!(status_reg & PCI_STATUS_66MHZ)) chip->features &= ~FE_66MHZ; - } - else { + } else { if (status_reg & PCI_STATUS_66MHZ) { status_reg = PCI_STATUS_66MHZ; pci_write_config_word(pdev, PCI_STATUS, status_reg); @@ -2474,8 +2318,6 @@ * Initialise device structure with items required by sym_attach. */ device->pdev = pdev; - device->s.bus = pdev->bus->number; - device->s.device_fn = pdev->devfn; device->s.base = base; device->s.base_2 = base_2; device->s.base_c = base_c; @@ -2487,203 +2329,6 @@ return 0; } -#if 0 -/* - * Detect all 53c8xx hosts and then attach them. - * - * If we are using NVRAM, once all hosts are detected, we need to - * check any NVRAM for boot order in case detect and boot order - * differ and attach them using the order in the NVRAM. - * - * If no NVRAM is found or data appears invalid attach boards in - * the order they are detected. - */ -int __init sym53c8xx_detect(struct scsi_host_template *tpnt) -{ - struct pci_dev *pcidev; - int i, j, chips, hosts, count; - int attach_count = 0; - sym_device *devtbl, *devp; - sym_nvram nvram; -#if SYM_CONF_NVRAM_SUPPORT - sym_nvram nvram0, *nvp; -#endif - - /* - * Initialize driver general stuff. - */ -#ifdef SYM_LINUX_BOOT_COMMAND_LINE_SUPPORT -#ifdef MODULE -if (sym53c8xx) - sym53c8xx_setup(sym53c8xx); -#endif -#ifdef SYM_LINUX_DEBUG_CONTROL_SUPPORT - sym_debug_flags = sym_driver_setup.debug; -#endif - if (boot_verbose >= 2) - sym53c8xx_print_driver_setup(); -#endif /* SYM_LINUX_BOOT_COMMAND_LINE_SUPPORT */ - - /* - * Allocate the device table since we donnot want to - * overflow the kernel stack. - * 1 x 4K PAGE is enough for more than 40 devices for i386. - */ - devtbl = sym_calloc(PAGE_SIZE, "DEVTBL"); - if (!devtbl) - return 0; - - /* - * Detect all NCR PQS/PDS memory controllers. - */ -#ifdef SYM_CONF_PQS_PDS_SUPPORT - sym_detect_pqs_pds(); -#endif - - /* - * Detect all 53c8xx hosts. - * Save the first Symbios NVRAM content if any - * for the boot order. - */ - chips = sizeof(sym_chip_ids) / sizeof(sym_chip_ids[0]); - hosts = PAGE_SIZE / sizeof(*devtbl); -#if SYM_CONF_NVRAM_SUPPORT - nvp = (sym_driver_setup.use_nvram & 0x1) ? &nvram0 : 0; -#endif - j = 0; - count = 0; - pcidev = NULL; - while (1) { - char *msg = ""; - if (count >= hosts) - break; - if (j >= chips) - break; - i = sym_driver_setup.reverse_probe ? chips - 1 - j : j; - pcidev = pci_find_device(PCI_VENDOR_ID_NCR, sym_chip_ids[i], - pcidev); - if (pcidev == NULL) { - ++j; - continue; - } - /* This one is guaranteed by AC to do nothing :-) */ - if (pci_enable_device(pcidev)) - continue; - devp = &devtbl[count]; - devp->host_id = SYM_SETUP_HOST_ID; - if (sym53c8xx_pci_init(pcidev, devp)) { - continue; - } - ++count; -#if SYM_CONF_NVRAM_SUPPORT - if (nvp) { - sym_get_nvram(devp, nvp); - switch(nvp->type) { - case SYM_SYMBIOS_NVRAM: - /* - * Switch to the other nvram buffer, so that - * nvram0 will contain the first Symbios - * format NVRAM content with boot order. - */ - nvp = &nvram; - msg = "with Symbios NVRAM"; - break; - case SYM_TEKRAM_NVRAM: - msg = "with Tekram NVRAM"; - break; - } - } -#endif -#ifdef SYM_CONF_PQS_PDS_SUPPORT - /* - * Match the BUS number for PQS/PDS devices. - * Read the SCSI ID from a special register mapped - * into the configuration space of the individual - * 875s. This register is set up by the PQS bios - */ - for(i = 0; i < SYM_CONF_MAX_PQS_BUS && pqs_bus[i] != -1; i++) { - u_char tmp; - if (pqs_bus[i] == pcidev->bus->number) { - pci_read_config_byte(pcidev, 0x84, &tmp); - devp->pqs_pds = 1; - devp->host_id = tmp; - break; - } - } - if (devp->pqs_pds) - msg = "(NCR PQS/PDS)"; -#endif - if (boot_verbose) - printf_info("%s: 53c%s detected %s\n", - sym_name(devp), devp->chip.name, msg); - } - - /* - * If we have found a SYMBIOS NVRAM, use first the NVRAM boot - * sequence as device boot order. - * check devices in the boot record against devices detected. - * attach devices if we find a match. boot table records that - * do not match any detected devices will be ignored. - * devices that do not match any boot table will not be attached - * here but will attempt to be attached during the device table - * rescan. - */ -#if SYM_CONF_NVRAM_SUPPORT - if (!nvp || nvram0.type != SYM_SYMBIOS_NVRAM) - goto next; - for (i = 0; i < 4; i++) { - Symbios_host *h = &nvram0.data.Symbios.host[i]; - for (j = 0 ; j < count ; j++) { - devp = &devtbl[j]; - if (h->device_fn != devp->s.device_fn || - h->bus_nr != devp->s.bus || - h->device_id != devp->chip.device_id) - continue; - if (devp->attach_done) - continue; - if (h->flags & SYMBIOS_INIT_SCAN_AT_BOOT) { - sym_get_nvram(devp, nvp); - if (!sym_attach (tpnt, attach_count, devp)) - attach_count++; - } - else if (!(sym_driver_setup.use_nvram & 0x80)) - printf_info( - "%s: 53c%s state OFF thus not attached\n", - sym_name(devp), devp->chip.name); - else - continue; - - devp->attach_done = 1; - break; - } - } -next: -#endif - - /* - * Rescan device list to make sure all boards attached. - * Devices without boot records will not be attached yet - * so try to attach them here. - */ - for (i= 0; i < count; i++) { - devp = &devtbl[i]; - if (!devp->attach_done) { - devp->nvram = &nvram; - nvram.type = 0; -#if SYM_CONF_NVRAM_SUPPORT - sym_get_nvram(devp, nvp); -#endif - if (!sym_attach (tpnt, attach_count, devp)) - attach_count++; - } - } - - sym_mfree(devtbl, PAGE_SIZE, "DEVTBL"); - - return attach_count; -} -#endif - /* * Linux release module stuff. @@ -2717,15 +2362,6 @@ return 1; } -#if 0 -int sym53c8xx_release(struct Scsi_Host *host) -{ - sym_detach(((struct host_data *) host->hostdata)->ncb); - - return 0; -} -#endif - MODULE_LICENSE("Dual BSD/GPL"); /* @@ -2734,10 +2370,6 @@ static struct scsi_host_template sym2_template = { .module = THIS_MODULE, .name = "sym53c8xx", -#if 0 - .detect = sym53c8xx_detect, - .release = sym53c8xx_release, -#endif .info = sym53c8xx_info, .queuecommand = sym53c8xx_queue_command, .slave_configure = sym53c8xx_slave_configure, @@ -2839,7 +2471,6 @@ sym_dev.host_id = SYM_SETUP_HOST_ID; if (sym53c8xx_pci_init(pdev, &sym_dev)) return -ENODEV; - printk(KERN_INFO "%s: 53c%s detected\n", sym_name(&sym_dev), sym_dev.chip.name); sym_dev.nvram = &nvram; nvram.type = 0; diff -Nru a/drivers/scsi/sym53c8xx_2/sym_glue.h b/drivers/scsi/sym53c8xx_2/sym_glue.h --- a/drivers/scsi/sym53c8xx_2/sym_glue.h Thu Sep 4 15:38:47 2003 +++ b/drivers/scsi/sym53c8xx_2/sym_glue.h Thu Sep 4 15:38:47 2003 @@ -111,8 +111,6 @@ /* * Configuration addendum for Linux. */ -#define SYM_LINUX_DYNAMIC_DMA_MAPPING - #define SYM_CONF_TIMER_INTERVAL ((HZ+1)/2) #define SYM_OPT_HANDLE_DIR_UNKNOWN @@ -121,10 +119,7 @@ #define SYM_OPT_SNIFF_INQUIRY #define SYM_OPT_LIMIT_COMMAND_REORDERING #define SYM_OPT_ANNOUNCE_TRANSFER_RATE - -#ifdef SYM_LINUX_DYNAMIC_DMA_MAPPING #define SYM_OPT_BUS_DMA_ABSTRACTION -#endif /* * Print a message with severity. @@ -142,8 +137,8 @@ /* * Insert a delay in micro-seconds and milli-seconds. */ -void sym_udelay(int us); -void sym_mdelay(int ms); +#define sym_udelay(us) udelay(us) +#define sym_mdelay(ms) mdelay(ms) /* * Let the compiler know about driver data structure names. @@ -426,9 +421,6 @@ struct Scsi_Host *host; - u_char bus; /* PCI BUS number */ - u_char device_fn; /* PCI BUS device and function */ - vm_offset_t mmio_va; /* MMIO kernel virtual address */ vm_offset_t ram_va; /* RAM kernel virtual address */ u_long io_port; /* IO port address cookie */ @@ -455,8 +447,6 @@ * used as sub-field 's' of another structure. */ typedef struct { - int bus; - u_char device_fn; u_long base; u_long base_2; u_long base_c; @@ -469,12 +459,11 @@ } sym_slot; typedef struct sym_nvram sym_nvram; -typedef struct sym_pci_chip sym_chip; typedef struct { struct pci_dev *pdev; sym_slot s; - sym_chip chip; + struct sym_pci_chip chip; sym_nvram *nvram; u_short device_id; u_char host_id; @@ -496,9 +485,7 @@ #ifdef MODULE #define SYM_MEM_FREE_UNUSED /* Free unused pages immediately */ #endif -#ifdef SYM_LINUX_DYNAMIC_DMA_MAPPING typedef struct pci_dev *m_pool_ident_t; -#endif /* * Include driver soft definitions. @@ -521,19 +508,7 @@ void *sym_calloc(int size, char *name); void sym_mfree(void *m, int size, char *name); -#ifndef SYM_LINUX_DYNAMIC_DMA_MAPPING /* - * Simple case. - * All the memory assummed DMAable and O/S providing virtual - * to bus physical address translation. - */ -#define __sym_calloc_dma(pool_id, size, name) sym_calloc(size, name) -#define __sym_mfree_dma(pool_id, m, size, name) sym_mfree(m, size, name) -#define __vtobus(b, p) virt_to_bus(p) - -#else /* SYM_LINUX_DYNAMIC_DMA_MAPPING */ -/* - * Complex case. * We have to provide the driver memory allocator with methods for * it to maintain virtual to bus physical address translations. */ @@ -560,14 +535,11 @@ } #define sym_m_create_dma_mem_tag(mp) (0) - #define sym_m_delete_dma_mem_tag(mp) do { ; } while (0) void *__sym_calloc_dma(m_pool_ident_t dev_dmat, int size, char *name); void __sym_mfree_dma(m_pool_ident_t dev_dmat, void *m, int size, char *name); m_addr_t __vtobus(m_pool_ident_t dev_dmat, void *m); - -#endif /* SYM_LINUX_DYNAMIC_DMA_MAPPING */ /* * Set the status field of a CAM CCB. diff -Nru a/drivers/scsi/sym53c8xx_2/sym_hipd.c b/drivers/scsi/sym53c8xx_2/sym_hipd.c --- a/drivers/scsi/sym53c8xx_2/sym_hipd.c Thu Sep 4 15:38:28 2003 +++ b/drivers/scsi/sym53c8xx_2/sym_hipd.c Thu Sep 4 15:38:28 2003 @@ -50,7 +50,7 @@ * SUCH DAMAGE. */ -#define SYM_DRIVER_NAME "sym-2.1.16a" +#define SYM_DRIVER_NAME "sym-2.1.17a" #ifdef __FreeBSD__ #include @@ -289,7 +289,7 @@ ((INW(nc_sbdl) & 0xff00) << 10) | /* d15-8 */ INB(nc_sbcl); /* req ack bsy sel atn msg cd io */ - if (!(np->features & FE_WIDE)) + if (!np->maxwide) term &= 0x3ffff; if (term != (2<<7)) { @@ -744,6 +744,12 @@ u32 period; int i; +#ifdef CONFIG_PARISC + unsigned long pdc_period; + char scsi_mode = -1; + struct hardware_path hwpath; +#endif + /* * Wide ? */ @@ -800,6 +806,31 @@ * Btw, 'period' is in tenths of nanoseconds. */ period = (4 * div_10M[0] + np->clock_khz - 1) / np->clock_khz; + +#if defined(CONFIG_PARISC) + /* Host firmware (PDC) keeps a table for crippling SCSI capabilities. + * Many newer machines export one channel of 53c896 chip + * as SE, 50-pin HD. Also used for Multi-initiator SCSI clusters + * to set the SCSI Initiator ID. + */ + get_pci_node_path(np->s.device, &hwpath); + if (pdc_get_initiator(&hwpath, &np->myaddr, &pdc_period, &np->maxwide, &scsi_mode)) + { + if (scsi_mode >= 0) { + /* C3000 PDC reports period/mode */ + SYM_SETUP_SCSI_DIFF = 0; + switch(scsi_mode) { + case 0: np->scsi_mode = SMODE_SE; break; + case 1: np->scsi_mode = SMODE_HVD; break; + case 2: np->scsi_mode = SMODE_LVD; break; + default: break; + } + } + + period = (u32) pdc_period; + } +#endif + if (period <= 250) np->minsync = 10; else if (period <= 303) np->minsync = 11; else if (period <= 500) np->minsync = 12; @@ -862,7 +893,7 @@ * In dual channel mode, contention occurs if internal cycles * are used. Disable internal cycles. */ - if (np->device_id == PCI_ID_LSI53C1010 && + if (np->device_id == PCI_ID_LSI53C1010_33 && np->revision_id < 0x1) np->rv_ccntl0 |= DILS; @@ -1362,17 +1393,17 @@ FE_WIDE|FE_ULTRA|FE_QUAD|FE_CACHE_SET|FE_BOF|FE_DFS|FE_LDSTR|FE_PFEN| FE_RAM|FE_DAC|FE_IO256|FE_NOPM|FE_LEDC|FE_LCKFRQ} , - {PCI_ID_LSI53C1010, 0x00, "1010-33", 6, 31, 7, 8, + {PCI_ID_LSI53C1010_33, 0x00, "1010-33", 6, 31, 7, 8, FE_WIDE|FE_ULTRA3|FE_QUAD|FE_CACHE_SET|FE_BOF|FE_DFBC|FE_LDSTR|FE_PFEN| FE_RAM|FE_RAM8K|FE_64BIT|FE_DAC|FE_IO256|FE_NOPM|FE_LEDC|FE_CRC| FE_C10} , - {PCI_ID_LSI53C1010, 0xff, "1010-33", 6, 31, 7, 8, + {PCI_ID_LSI53C1010_33, 0xff, "1010-33", 6, 31, 7, 8, FE_WIDE|FE_ULTRA3|FE_QUAD|FE_CACHE_SET|FE_BOF|FE_DFBC|FE_LDSTR|FE_PFEN| FE_RAM|FE_RAM8K|FE_64BIT|FE_DAC|FE_IO256|FE_NOPM|FE_LEDC|FE_CRC| FE_C10|FE_U3EN} , - {PCI_ID_LSI53C1010_2, 0xff, "1010-66", 6, 31, 7, 8, + {PCI_ID_LSI53C1010_66, 0xff, "1010-66", 6, 31, 7, 8, FE_WIDE|FE_ULTRA3|FE_QUAD|FE_CACHE_SET|FE_BOF|FE_DFBC|FE_LDSTR|FE_PFEN| FE_RAM|FE_RAM8K|FE_64BIT|FE_DAC|FE_IO256|FE_NOPM|FE_LEDC|FE_66MHZ|FE_CRC| FE_C10|FE_U3EN} @@ -1809,7 +1840,7 @@ /* * For now, disable AIP generation on C1010-66. */ - if (np->device_id == PCI_ID_LSI53C1010_2) + if (np->device_id == PCI_ID_LSI53C1010_66) OUTB (nc_aipcntl1, DISAIP); /* @@ -1819,7 +1850,7 @@ * that from SCRIPTS for each selection/reselection, but * I just don't want. :) */ - if (np->device_id == PCI_ID_LSI53C1010 && + if (np->device_id == PCI_ID_LSI53C1010_33 && np->revision_id < 1) OUTB (nc_stest1, INB(nc_stest1) | 0x30); diff -Nru a/drivers/scsi/sym53c8xx_2/sym_misc.h b/drivers/scsi/sym53c8xx_2/sym_misc.h --- a/drivers/scsi/sym53c8xx_2/sym_misc.h Thu Sep 4 15:38:48 2003 +++ b/drivers/scsi/sym53c8xx_2/sym_misc.h Thu Sep 4 15:38:48 2003 @@ -77,23 +77,8 @@ * should be enough). */ -#if defined __i386__ -#define __READ_BARRIER() \ - __asm__ volatile("lock; addl $0,0(%%esp)": : :"memory") -#define __WRITE_BARRIER() __asm__ volatile ("": : :"memory") -#elif defined __powerpc__ -#define __READ_BARRIER() __asm__ volatile("eieio; sync" : : : "memory") -#define __WRITE_BARRIER() __asm__ volatile("eieio; sync" : : : "memory") -#elif defined __ia64__ -#define __READ_BARRIER() __asm__ volatile("mf.a; mf" : : : "memory") -#define __WRITE_BARRIER() __asm__ volatile("mf.a; mf" : : : "memory") -#elif defined __alpha__ -#define __READ_BARRIER() __asm__ volatile("mb": : :"memory") -#define __WRITE_BARRIER() __asm__ volatile("mb": : :"memory") -#else -#define __READ_BARRIER() mb() -#define __WRITE_BARRIER() mb() -#endif +#define __READ_BARRIER() rmb() +#define __WRITE_BARRIER() wmb() #ifndef MEMORY_READ_BARRIER #define MEMORY_READ_BARRIER() __READ_BARRIER() diff -Nru a/drivers/scsi/sym53c8xx_defs.h b/drivers/scsi/sym53c8xx_defs.h --- a/drivers/scsi/sym53c8xx_defs.h Thu Sep 4 15:38:42 2003 +++ b/drivers/scsi/sym53c8xx_defs.h Thu Sep 4 15:38:42 2003 @@ -259,17 +259,6 @@ #endif /* - * Vendor specific stuff - */ -#ifdef CONFIG_SCSI_NCR53C8XX_SYMBIOS_COMPAT -#define SCSI_NCR_SETUP_LED_PIN (1) -#define SCSI_NCR_SETUP_DIFF_SUPPORT (4) -#else -#define SCSI_NCR_SETUP_LED_PIN (0) -#define SCSI_NCR_SETUP_DIFF_SUPPORT (0) -#endif - -/* * Settle time after reset at boot-up */ #define SCSI_NCR_SETUP_SETTLE_TIME (2) @@ -926,10 +915,10 @@ SCSI_NCR_SETUP_DEFAULT_SYNC, \ 0x00, \ 7, \ - SCSI_NCR_SETUP_LED_PIN, \ + 0, \ 1, \ SCSI_NCR_SETUP_SETTLE_TIME, \ - SCSI_NCR_SETUP_DIFF_SUPPORT, \ + 0, \ 0, \ 1, \ 0, \ diff -Nru a/drivers/scsi/t128.h b/drivers/scsi/t128.h --- a/drivers/scsi/t128.h Thu Sep 4 15:38:31 2003 +++ b/drivers/scsi/t128.h Thu Sep 4 15:38:31 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/8250_acpi.c b/drivers/serial/8250_acpi.c --- a/drivers/serial/8250_acpi.c Thu Sep 4 15:38:46 2003 +++ b/drivers/serial/8250_acpi.c Thu Sep 4 15:38:46 2003 @@ -108,3 +108,6 @@ module_init(acpi_serial_init); module_exit(acpi_serial_exit); + +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("Generic 8250/16x50 ACPI serial driver"); diff -Nru a/drivers/serial/Kconfig b/drivers/serial/Kconfig --- a/drivers/serial/Kconfig Thu Sep 4 15:38:45 2003 +++ b/drivers/serial/Kconfig Thu Sep 4 15:38:45 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 Thu Sep 4 15:38:33 2003 +++ b/drivers/serial/Makefile Thu Sep 4 15:38:33 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 Thu Sep 4 15:38:48 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 Thu Sep 4 15:38:48 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 Thu Sep 4 15:38:29 2003 +++ b/drivers/telephony/ixj.c Thu Sep 4 15:38:29 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 Thu Sep 4 15:38:37 2003 +++ b/drivers/telephony/phonedev.c Thu Sep 4 15:38:37 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 Thu Sep 4 15:38:46 2003 +++ b/drivers/usb/class/audio.c Thu Sep 4 15:38:46 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 Thu Sep 4 15:38:41 2003 +++ b/drivers/usb/class/bluetty.c Thu Sep 4 15:38:41 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 Thu Sep 4 15:38:38 2003 +++ b/drivers/usb/class/cdc-acm.c Thu Sep 4 15:38:38 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 Thu Sep 4 15:38:29 2003 +++ b/drivers/usb/class/usb-midi.c Thu Sep 4 15:38:29 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 Thu Sep 4 15:38:30 2003 +++ b/drivers/usb/class/usblp.c Thu Sep 4 15:38:30 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 Thu Sep 4 15:38:47 2003 +++ b/drivers/usb/core/file.c Thu Sep 4 15:38:47 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 Thu Sep 4 15:38:33 2003 +++ b/drivers/usb/core/hcd-pci.c Thu Sep 4 15:38:33 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 Thu Sep 4 15:38:36 2003 +++ b/drivers/usb/core/hcd.c Thu Sep 4 15:38:36 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 Thu Sep 4 15:38:31 2003 +++ b/drivers/usb/core/hcd.h Thu Sep 4 15:38:31 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 Thu Sep 4 15:38:29 2003 +++ b/drivers/usb/core/inode.c Thu Sep 4 15:38:29 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 Thu Sep 4 15:38:30 2003 +++ b/drivers/usb/core/message.c Thu Sep 4 15:38:30 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 Thu Sep 4 15:38:34 2003 +++ b/drivers/usb/core/usb.c Thu Sep 4 15:38:34 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 Thu Sep 4 15:38:29 2003 +++ b/drivers/usb/gadget/net2280.c Thu Sep 4 15:38:29 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 Thu Sep 4 15:38:40 2003 +++ b/drivers/usb/gadget/net2280.h Thu Sep 4 15:38:40 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 Thu Sep 4 15:38:38 2003 +++ b/drivers/usb/host/ehci-hcd.c Thu Sep 4 15:38:38 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 Thu Sep 4 15:38:29 2003 +++ b/drivers/usb/host/ohci-hcd.c Thu Sep 4 15:38:29 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 Thu Sep 4 15:38:40 2003 +++ b/drivers/usb/host/ohci-pci.c Thu Sep 4 15:38:40 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 Thu Sep 4 15:38:45 2003 +++ b/drivers/usb/host/ohci-q.c Thu Sep 4 15:38:45 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 Thu Sep 4 15:38:34 2003 +++ b/drivers/usb/host/ohci-sa1111.c Thu Sep 4 15:38:34 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 Thu Sep 4 15:38:43 2003 +++ b/drivers/usb/host/uhci-hcd.c Thu Sep 4 15:38:43 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 Thu Sep 4 15:38:35 2003 +++ b/drivers/usb/image/mdc800.c Thu Sep 4 15:38:35 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 Thu Sep 4 15:38:32 2003 +++ b/drivers/usb/image/scanner.h Thu Sep 4 15:38:32 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 Thu Sep 4 15:38:36 2003 +++ b/drivers/usb/input/hid-core.c Thu Sep 4 15:38:36 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 Thu Sep 4 15:38:32 2003 +++ b/drivers/usb/input/hiddev.c Thu Sep 4 15:38:32 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,11 +795,10 @@ 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) +void hiddev_exit(void) { usb_deregister(&hiddev_driver); devfs_remove("usb/hid"); diff -Nru a/drivers/usb/input/kbtab.c b/drivers/usb/input/kbtab.c --- a/drivers/usb/input/kbtab.c Thu Sep 4 15:38:28 2003 +++ b/drivers/usb/input/kbtab.c Thu Sep 4 15:38:28 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 Thu Sep 4 15:38:37 2003 +++ b/drivers/usb/input/powermate.c Thu Sep 4 15:38:37 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 Thu Sep 4 15:38:36 2003 +++ b/drivers/usb/media/dabusb.c Thu Sep 4 15:38:36 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 Thu Sep 4 15:38:32 2003 +++ b/drivers/usb/media/dsbr100.c Thu Sep 4 15:38:32 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 Thu Sep 4 15:38:31 2003 +++ b/drivers/usb/media/ov511.c Thu Sep 4 15:38:31 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 Thu Sep 4 15:38:41 2003 +++ b/drivers/usb/media/pwc-if.c Thu Sep 4 15:38:41 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 Thu Sep 4 15:38:31 2003 +++ b/drivers/usb/media/se401.c Thu Sep 4 15:38:31 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 Thu Sep 4 15:38:43 2003 +++ b/drivers/usb/media/se401.h Thu Sep 4 15:38:43 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 Thu Sep 4 15:38:39 2003 +++ b/drivers/usb/media/stv680.c Thu Sep 4 15:38:39 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 Thu Sep 4 15:38:42 2003 +++ b/drivers/usb/media/stv680.h Thu Sep 4 15:38:42 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 Thu Sep 4 15:38:48 2003 +++ b/drivers/usb/media/usbvideo.c Thu Sep 4 15:38:48 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 Thu Sep 4 15:38:32 2003 +++ b/drivers/usb/media/usbvideo.h Thu Sep 4 15:38:32 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 Thu Sep 4 15:38:32 2003 +++ b/drivers/usb/media/vicam.c Thu Sep 4 15:38:32 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 Thu Sep 4 15:38:32 2003 +++ b/drivers/usb/misc/auerswald.c Thu Sep 4 15:38:32 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 Thu Sep 4 15:38:34 2003 +++ b/drivers/usb/misc/brlvger.c Thu Sep 4 15:38:34 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 Thu Sep 4 15:38:38 2003 +++ b/drivers/usb/misc/rio500.c Thu Sep 4 15:38:38 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 Thu Sep 4 15:38:28 2003 +++ b/drivers/usb/misc/tiglusb.c Thu Sep 4 15:38:28 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 Thu Sep 4 15:38:28 2003 +++ b/drivers/usb/misc/usblcd.c Thu Sep 4 15:38:28 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 Thu Sep 4 15:38:45 2003 +++ b/drivers/usb/misc/usbtest.c Thu Sep 4 15:38:45 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 Thu Sep 4 15:38:28 2003 +++ b/drivers/usb/misc/uss720.c Thu Sep 4 15:38:28 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 Thu Sep 4 15:38:40 2003 +++ b/drivers/usb/net/Kconfig Thu Sep 4 15:38:40 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 Thu Sep 4 15:38:29 2003 +++ b/drivers/usb/net/Makefile Thu Sep 4 15:38:29 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 Thu Sep 4 15:38:42 2003 +++ b/drivers/usb/net/Makefile.mii Thu Sep 4 15:38:42 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 Thu Sep 4 15:38:30 2003 +++ b/drivers/usb/net/ax8817x.c Thu Sep 4 15:38:30 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 Thu Sep 4 15:38:35 2003 +++ b/drivers/usb/net/usbnet.c Thu Sep 4 15:38:35 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 Thu Sep 4 15:38:37 2003 +++ b/drivers/usb/serial/belkin_sa.c Thu Sep 4 15:38:37 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 Thu Sep 4 15:38:44 2003 +++ b/drivers/usb/serial/cyberjack.c Thu Sep 4 15:38:44 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 Thu Sep 4 15:38:33 2003 +++ b/drivers/usb/serial/digi_acceleport.c Thu Sep 4 15:38:33 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 Thu Sep 4 15:38:46 2003 +++ b/drivers/usb/serial/empeg.c Thu Sep 4 15:38:46 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 Thu Sep 4 15:38:42 2003 +++ b/drivers/usb/serial/ftdi_sio.c Thu Sep 4 15:38:42 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 Thu Sep 4 15:38:43 2003 +++ b/drivers/usb/serial/io_16654.h Thu Sep 4 15:38:43 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 Thu Sep 4 15:38:29 2003 +++ b/drivers/usb/serial/io_edgeport.c Thu Sep 4 15:38:29 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 Thu Sep 4 15:38:39 2003 +++ b/drivers/usb/serial/io_edgeport.h Thu Sep 4 15:38:39 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 Thu Sep 4 15:38:47 2003 +++ b/drivers/usb/serial/io_fw_boot.h Thu Sep 4 15:38:47 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 Thu Sep 4 15:38:30 2003 +++ b/drivers/usb/serial/io_fw_boot2.h Thu Sep 4 15:38:30 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 Thu Sep 4 15:38:46 2003 +++ b/drivers/usb/serial/io_fw_down.h Thu Sep 4 15:38:46 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 Thu Sep 4 15:38:31 2003 +++ b/drivers/usb/serial/io_fw_down2.h Thu Sep 4 15:38:31 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 Thu Sep 4 15:38:43 2003 +++ b/drivers/usb/serial/io_fw_down3.h Thu Sep 4 15:38:43 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 Thu Sep 4 15:38:43 2003 +++ b/drivers/usb/serial/io_ionsp.h Thu Sep 4 15:38:43 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 Thu Sep 4 15:38:46 2003 +++ b/drivers/usb/serial/io_ti.c Thu Sep 4 15:38:46 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 Thu Sep 4 15:38:31 2003 +++ b/drivers/usb/serial/io_ti.h Thu Sep 4 15:38:31 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 Thu Sep 4 15:38:41 2003 +++ b/drivers/usb/serial/io_usbvend.h Thu Sep 4 15:38:41 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 Thu Sep 4 15:38:43 2003 +++ b/drivers/usb/serial/ipaq.c Thu Sep 4 15:38:43 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 Thu Sep 4 15:38:33 2003 +++ b/drivers/usb/serial/ir-usb.c Thu Sep 4 15:38:33 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 Thu Sep 4 15:38:29 2003 +++ b/drivers/usb/serial/keyspan.c Thu Sep 4 15:38:29 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 Thu Sep 4 15:38:38 2003 +++ b/drivers/usb/serial/keyspan_pda.c Thu Sep 4 15:38:38 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 Thu Sep 4 15:38:35 2003 +++ b/drivers/usb/serial/keyspan_pda_fw.h Thu Sep 4 15:38:35 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 Thu Sep 4 15:38:35 2003 +++ b/drivers/usb/serial/keyspan_usa26msg.h Thu Sep 4 15:38:35 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 Thu Sep 4 15:38:29 2003 +++ b/drivers/usb/serial/keyspan_usa28msg.h Thu Sep 4 15:38:29 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 Thu Sep 4 15:38:30 2003 +++ b/drivers/usb/serial/keyspan_usa49msg.h Thu Sep 4 15:38:30 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 Thu Sep 4 15:38:35 2003 +++ b/drivers/usb/serial/kl5kusb105.c Thu Sep 4 15:38:35 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 Thu Sep 4 15:38:43 2003 +++ b/drivers/usb/serial/kobil_sct.c Thu Sep 4 15:38:43 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 Thu Sep 4 15:38:39 2003 +++ b/drivers/usb/serial/mct_u232.c Thu Sep 4 15:38:39 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 Thu Sep 4 15:38:43 2003 +++ b/drivers/usb/serial/omninet.c Thu Sep 4 15:38:43 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 Thu Sep 4 15:38:33 2003 +++ b/drivers/usb/serial/pl2303.c Thu Sep 4 15:38:33 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 Thu Sep 4 15:38:30 2003 +++ b/drivers/usb/serial/safe_serial.c Thu Sep 4 15:38:30 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 Thu Sep 4 15:38:32 2003 +++ b/drivers/usb/serial/usb-serial.c Thu Sep 4 15:38:32 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 Thu Sep 4 15:38:31 2003 +++ b/drivers/usb/serial/visor.c Thu Sep 4 15:38:31 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 Thu Sep 4 15:38:43 2003 +++ b/drivers/usb/serial/visor.h Thu Sep 4 15:38:43 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 Thu Sep 4 15:38:32 2003 +++ b/drivers/usb/serial/whiteheat.c Thu Sep 4 15:38:32 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 Thu Sep 4 15:38:30 2003 +++ b/drivers/usb/serial/xircom_pgs_fw.h Thu Sep 4 15:38:30 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 Thu Sep 4 15:38:34 2003 +++ b/drivers/usb/storage/isd200.c Thu Sep 4 15:38:34 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 Thu Sep 4 15:38:42 2003 +++ b/drivers/usb/storage/sddr09.c Thu Sep 4 15:38:42 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 Thu Sep 4 15:38:32 2003 +++ b/drivers/usb/storage/transport.c Thu Sep 4 15:38:32 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 Thu Sep 4 15:38:42 2003 +++ b/drivers/usb/storage/unusual_devs.h Thu Sep 4 15:38:42 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 Thu Sep 4 15:38:31 2003 +++ b/drivers/usb/storage/usb.c Thu Sep 4 15:38:31 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 Thu Sep 4 15:38:38 2003 +++ b/drivers/usb/storage/usb.h Thu Sep 4 15:38:38 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 Thu Sep 4 15:38:33 2003 +++ b/drivers/usb/usb-skeleton.c Thu Sep 4 15:38:33 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 Thu Sep 4 15:38:40 2003 +++ b/drivers/video/68328fb.c Thu Sep 4 15:38:40 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 Thu Sep 4 15:38:29 2003 +++ b/drivers/video/Kconfig Thu Sep 4 15:38:29 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 Thu Sep 4 15:38:29 2003 +++ b/drivers/video/Makefile Thu Sep 4 15:38:29 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 Thu Sep 4 15:38:30 2003 +++ b/drivers/video/controlfb.c Thu Sep 4 15:38:30 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 Thu Sep 4 15:38:28 2003 +++ b/drivers/video/fbmem.c Thu Sep 4 15:38:28 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 Thu Sep 4 15:38:32 2003 +++ b/drivers/video/platinumfb.c Thu Sep 4 15:38:32 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 Thu Sep 4 15:38:40 2003 +++ b/drivers/video/riva/fbdev.c Thu Sep 4 15:38:40 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 Thu Sep 4 15:38:48 2003 +++ b/drivers/video/stifb.c Thu Sep 4 15:38:48 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 Thu Sep 4 15:38:33 2003 +++ b/fs/affs/file.c Thu Sep 4 15:38:33 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 Thu Sep 4 15:38:36 2003 +++ b/fs/afs/callback.c Thu Sep 4 15:38:36 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 Thu Sep 4 15:38:32 2003 +++ b/fs/afs/dir.c Thu Sep 4 15:38:32 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 Thu Sep 4 15:38:30 2003 +++ b/fs/bad_inode.c Thu Sep 4 15:38:30 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 Thu Sep 4 15:38:37 2003 +++ b/fs/bio.c Thu Sep 4 15:38:37 2003 @@ -296,7 +296,7 @@ unsigned int offset) { request_queue_t *q = bdev_get_queue(bio->bi_bdev); - int fail_segments = 0, retried_segments = 0; + int retried_segments = 0; struct bio_vec *bvec; /* @@ -315,18 +315,15 @@ * we might lose a segment or two here, but rather that than * make this too complex. */ -retry_segments: - if (bio_phys_segments(q, bio) >= q->max_phys_segments - || bio_hw_segments(q, bio) >= q->max_hw_segments) - fail_segments = 1; - if (fail_segments) { + while (bio_phys_segments(q, bio) >= q->max_phys_segments + || bio_hw_segments(q, bio) >= q->max_hw_segments) { + if (retried_segments) return 0; bio->bi_flags &= ~(1 << BIO_SEG_VALID); retried_segments = 1; - goto retry_segments; } /* @@ -793,10 +790,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 +802,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 Thu Sep 4 15:38:48 2003 +++ b/fs/block_dev.c Thu Sep 4 15:38:48 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/CHANGES b/fs/cifs/CHANGES --- a/fs/cifs/CHANGES Thu Sep 4 15:38:43 2003 +++ b/fs/cifs/CHANGES Thu Sep 4 15:38:43 2003 @@ -1,3 +1,14 @@ +Version 0.91 +------------ +Fix oops in reopen_files when invalid dentry. drop dentry on server rename +and on revalidate errors. Fix cases where pid is now tgid. Fix return code +on create hard link when server does not support them. + +Version 0.90 +------------ +Fix scheduling while atomic error in getting inode info on newly created file. +Fix truncate of existing files opened with O_CREAT but not O_TRUNC set. + Version 0.89 ------------ Fix oops on write to dead tcp session. Remove error log write for case when file open diff -Nru a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c --- a/fs/cifs/cifsfs.c Thu Sep 4 15:38:35 2003 +++ b/fs/cifs/cifsfs.c Thu Sep 4 15:38:35 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/cifs/cifssmb.c b/fs/cifs/cifssmb.c --- a/fs/cifs/cifssmb.c Thu Sep 4 15:38:30 2003 +++ b/fs/cifs/cifssmb.c Thu Sep 4 15:38:30 2003 @@ -1,7 +1,7 @@ /* * fs/cifs/cifssmb.c * - * Copyright (c) International Business Machines Corp., 2002 + * Copyright (C) International Business Machines Corp., 2002,2003 * Author(s): Steve French (sfrench@us.ibm.com) * * Contains the routines for constructing the SMB PDUs themselves @@ -656,7 +656,7 @@ pSMB->AndXCommand = 0xFF; /* none */ pSMB->Fid = smb_file_id; /* netfid stays le */ - pSMB->Locks[0].Pid = cpu_to_le16(current->pid); + pSMB->Locks[0].Pid = cpu_to_le16(current->tgid); pSMB->Locks[0].Length = cpu_to_le64(len); pSMB->Locks[0].Offset = cpu_to_le64(offset); pSMB->ByteCount = sizeof (LOCKING_ANDX_RANGE); diff -Nru a/fs/cifs/dir.c b/fs/cifs/dir.c --- a/fs/cifs/dir.c Thu Sep 4 15:38:38 2003 +++ b/fs/cifs/dir.c Thu Sep 4 15:38:38 2003 @@ -3,7 +3,7 @@ * * vfs operations that deal with dentries * - * Copyright (c) International Business Machines Corp., 2002 + * Copyright (C) International Business Machines Corp., 2002,2003 * Author(s): Steve French (sfrench@us.ibm.com) * * This library is free software; you can redistribute it and/or modify @@ -134,6 +134,7 @@ struct inode *newinode = NULL; struct cifsFileInfo * pCifsFile = NULL; struct cifsInodeInfo * pCifsInode; + int disposition = FILE_OVERWRITE_IF; xid = GetXid(); @@ -151,6 +152,16 @@ desiredAccess = GENERIC_WRITE; else if ((nd->intent.open.flags & O_ACCMODE) == O_RDWR) desiredAccess = GENERIC_ALL; + + if((nd->intent.open.flags & (O_CREAT | O_EXCL)) == (O_CREAT | O_EXCL)) + disposition = FILE_CREATE; + else if((nd->intent.open.flags & (O_CREAT | O_TRUNC)) == (O_CREAT | O_TRUNC)) + disposition = FILE_OVERWRITE_IF; + else if((nd->intent.open.flags & O_CREAT) == O_CREAT) + disposition = FILE_OPEN_IF; + else { + cFYI(1,("Create flag not set in create function")); + } } /* BB add processing to set equivalent of mode - e.g. via CreateX with ACLs */ @@ -158,7 +169,7 @@ oplock = REQ_OPLOCK; buf = kmalloc(sizeof(FILE_ALL_INFO),GFP_KERNEL); - rc = CIFSSMBOpen(xid, pTcon, full_path, FILE_OVERWRITE_IF, + rc = CIFSSMBOpen(xid, pTcon, full_path, disposition, desiredAccess, CREATE_NOT_DIR, &fileHandle, &oplock, buf, cifs_sb->local_nls); if (rc) { @@ -205,7 +216,7 @@ memset((char *)pCifsFile, 0, sizeof (struct cifsFileInfo)); pCifsFile->netfid = fileHandle; - pCifsFile->pid = current->pid; + pCifsFile->pid = current->tgid; pCifsFile->pInode = newinode; /* pCifsFile->pfile = file; */ /* put in at open time */ write_lock(&GlobalSMBSeslock); @@ -297,6 +308,9 @@ (" parent inode = 0x%p name is: %s and dentry = 0x%p", parent_dir_inode, direntry->d_name.name, direntry)); + if(nd) { /* BB removeme */ + cFYI(1,("In lookup nd flags 0x%x open intent flags 0x%x",nd->flags,nd->intent.open.flags)); + } /* BB removeme BB */ /* BB Add check of incoming data - e.g. frame not longer than maximum SMB - let server check the namelen BB */ /* check whether path exists */ diff -Nru a/fs/cifs/file.c b/fs/cifs/file.c --- a/fs/cifs/file.c Thu Sep 4 15:38:28 2003 +++ b/fs/cifs/file.c Thu Sep 4 15:38:28 2003 @@ -3,7 +3,7 @@ * * vfs operations that deal with files * - * Copyright (c) International Business Machines Corp., 2002 + * Copyright (C) International Business Machines Corp., 2002,2003 * Author(s): Steve French (sfrench@us.ibm.com) * * This library is free software; you can redistribute it and/or modify @@ -144,6 +144,10 @@ list_add(&pCifsFile->tlist,&pTcon->openFileList); pCifsInode = CIFS_I(file->f_dentry->d_inode); if(pCifsInode) { + list_add(&pCifsFile->flist,&pCifsInode->openFileList); + write_unlock(&GlobalSMBSeslock); + write_unlock(&file->f_owner.lock); + if (pTcon->ses->capabilities & CAP_UNIX) rc = cifs_get_inode_info_unix(&file->f_dentry->d_inode, full_path, inode->i_sb); @@ -151,16 +155,16 @@ rc = cifs_get_inode_info(&file->f_dentry->d_inode, full_path, buf, inode->i_sb); - list_add(&pCifsFile->flist,&pCifsInode->openFileList); if(oplock == OPLOCK_EXCLUSIVE) { pCifsInode->clientCanCacheAll = TRUE; pCifsInode->clientCanCacheRead = TRUE; cFYI(1,("Exclusive Oplock granted on inode %p",file->f_dentry->d_inode)); } else if(oplock == OPLOCK_READ) pCifsInode->clientCanCacheRead = TRUE; + } else { + write_unlock(&GlobalSMBSeslock); + write_unlock(&file->f_owner.lock); } - write_unlock(&GlobalSMBSeslock); - write_unlock(&file->f_owner.lock); if(file->f_flags & O_CREAT) { /* time to set mode which we can not set earlier due to problems creating new read-only files */ @@ -221,16 +225,21 @@ if(file) { file->private_data = NULL; read_unlock(&GlobalSMBSeslock); - rc = cifs_open(file->f_dentry->d_inode,file); - read_lock(&GlobalSMBSeslock); - if(rc) { - cFYI(1,("reconnecting file %s failed with %d", - file->f_dentry->d_name.name,rc)); + if(file->f_dentry == 0) { + cFYI(1,("Null dentry for file %p",file)); + read_lock(&GlobalSMBSeslock); } else { - cFYI(1,("reconnection of %s succeeded", - file->f_dentry->d_name.name)); - } - } + rc = cifs_open(file->f_dentry->d_inode,file); + read_lock(&GlobalSMBSeslock); + if(rc) { + cFYI(1,("reconnecting file %s failed with %d", + file->f_dentry->d_name.name,rc)); + } else { + cFYI(1,("reconnection of %s succeeded", + file->f_dentry->d_name.name)); + } + } + } } } read_unlock(&GlobalSMBSeslock); diff -Nru a/fs/cifs/inode.c b/fs/cifs/inode.c --- a/fs/cifs/inode.c Thu Sep 4 15:38:28 2003 +++ b/fs/cifs/inode.c Thu Sep 4 15:38:28 2003 @@ -1,7 +1,7 @@ /* * fs/cifs/inode.c * - * Copyright (c) International Business Machines Corp., 2002 + * Copyright (C) International Business Machines Corp., 2002,2003 * Author(s): Steve French (sfrench@us.ibm.com) * * This library is free software; you can redistribute it and/or modify @@ -345,6 +345,8 @@ if (!rc) { direntry->d_inode->i_nlink--; + } else if (rc == -ENOENT) { + d_drop(direntry); } else if (rc == -ETXTBSY) { int oplock = FALSE; __u16 netfid; @@ -585,12 +587,24 @@ } } - if (cifs_sb->tcon->ses->capabilities & CAP_UNIX) - cifs_get_inode_info_unix(&direntry->d_inode, full_path, + if (cifs_sb->tcon->ses->capabilities & CAP_UNIX) { + rc = cifs_get_inode_info_unix(&direntry->d_inode, full_path, direntry->d_sb); - else - cifs_get_inode_info(&direntry->d_inode, full_path, NULL, + if(rc) { + cFYI(1,("error on getting revalidate info %d",rc)); +/* if(rc != -ENOENT) + rc = 0; */ /* BB should we cache info on certain errors? */ + } + } else { + rc = cifs_get_inode_info(&direntry->d_inode, full_path, NULL, direntry->d_sb); + if(rc) { + cFYI(1,("error on getting revalidate info %d",rc)); +/* if(rc != -ENOENT) + rc = 0; */ /* BB should we cache info on certain errors? */ + } + } + /* should we remap certain errors, access denied?, to zero */ /* BB if not oplocked, invalidate inode pages if mtime has changed */ diff -Nru a/fs/cifs/link.c b/fs/cifs/link.c --- a/fs/cifs/link.c Thu Sep 4 15:38:31 2003 +++ b/fs/cifs/link.c Thu Sep 4 15:38:31 2003 @@ -1,7 +1,7 @@ /* * fs/cifs/link.c * - * Copyright (c) International Business Machines Corp., 2002 + * Copyright (C) International Business Machines Corp., 2002,2003 * Author(s): Steve French (sfrench@us.ibm.com) * * This library is free software; you can redistribute it and/or modify @@ -51,9 +51,12 @@ if (cifs_sb_target->tcon->ses->capabilities & CAP_UNIX) rc = CIFSUnixCreateHardLink(xid, pTcon, fromName, toName, cifs_sb_target->local_nls); - else + else { rc = CIFSCreateHardLink(xid, pTcon, fromName, toName, cifs_sb_target->local_nls); + if(rc == -EIO) + rc = -EOPNOTSUPP; + } /* if (!rc) */ { diff -Nru a/fs/cifs/misc.c b/fs/cifs/misc.c --- a/fs/cifs/misc.c Thu Sep 4 15:38:46 2003 +++ b/fs/cifs/misc.c Thu Sep 4 15:38:46 2003 @@ -1,7 +1,7 @@ /* * fs/cifs/misc.c * - * Copyright (c) International Business Machines Corp., 2002 + * Copyright (c) International Business Machines Corp., 2002,2003 * Author(s): Steve French (sfrench@us.ibm.com) * * This library is free software; you can redistribute it and/or modify @@ -213,7 +213,7 @@ buffer->Command = smb_command; buffer->Flags = 0x00; /* case sensitive */ buffer->Flags2 = SMBFLG2_KNOWS_LONG_NAMES; - tmp = cpu_to_le32(current->pid); + tmp = cpu_to_le32(current->tgid); buffer->Pid = tmp & 0xFFFF; tmp >>= 16; buffer->PidHigh = tmp & 0xFFFF; diff -Nru a/fs/coda/inode.c b/fs/coda/inode.c --- a/fs/coda/inode.c Thu Sep 4 15:38:34 2003 +++ b/fs/coda/inode.c Thu Sep 4 15:38:34 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 Thu Sep 4 15:38:37 2003 +++ b/fs/coda/psdev.c Thu Sep 4 15:38:37 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 Thu Sep 4 15:38:33 2003 +++ b/fs/compat.c Thu Sep 4 15:38:33 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 Thu Sep 4 15:38:45 2003 +++ b/fs/compat_ioctl.c Thu Sep 4 15:38:45 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 Thu Sep 4 15:38:31 2003 +++ b/fs/dnotify.c Thu Sep 4 15:38:31 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 Thu Sep 4 15:38:43 2003 +++ b/fs/ext2/namei.c Thu Sep 4 15:38:43 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 Thu Sep 4 15:38:37 2003 +++ b/fs/ext3/namei.c Thu Sep 4 15:38:37 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 Thu Sep 4 15:38:35 2003 +++ b/fs/ext3/xattr.c Thu Sep 4 15:38:35 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 Thu Sep 4 15:38:39 2003 +++ b/fs/fcntl.c Thu Sep 4 15:38:39 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 Thu Sep 4 15:38:30 2003 +++ b/fs/freevxfs/vxfs_inode.c Thu Sep 4 15:38:30 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 Thu Sep 4 15:38:32 2003 +++ b/fs/hpfs/namei.c Thu Sep 4 15:38:32 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 Thu Sep 4 15:38:37 2003 +++ b/fs/intermezzo/presto.c Thu Sep 4 15:38:37 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 Thu Sep 4 15:38:31 2003 +++ b/fs/intermezzo/vfs.c Thu Sep 4 15:38:31 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 Thu Sep 4 15:38:30 2003 +++ b/fs/jbd/journal.c Thu Sep 4 15:38:30 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 Thu Sep 4 15:38:37 2003 +++ b/fs/jffs/inode-v23.c Thu Sep 4 15:38:37 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 Thu Sep 4 15:38:47 2003 +++ b/fs/jffs2/file.c Thu Sep 4 15:38:47 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 Thu Sep 4 15:38:29 2003 +++ b/fs/jffs2/os-linux.h Thu Sep 4 15:38:29 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 Thu Sep 4 15:38:31 2003 +++ b/fs/jffs2/wbuf.c Thu Sep 4 15:38:31 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 Thu Sep 4 15:38:42 2003 +++ b/fs/nfs/inode.c Thu Sep 4 15:38:42 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 Thu Sep 4 15:38:47 2003 +++ b/fs/nfsd/nfs4proc.c Thu Sep 4 15:38:47 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 Thu Sep 4 15:38:40 2003 +++ b/fs/nfsd/nfs4state.c Thu Sep 4 15:38:40 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 Thu Sep 4 15:38:43 2003 +++ b/fs/nfsd/nfs4xdr.c Thu Sep 4 15:38:43 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 Thu Sep 4 15:38:29 2003 +++ b/fs/open.c Thu Sep 4 15:38:29 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 Thu Sep 4 15:38:44 2003 +++ b/fs/partitions/check.c Thu Sep 4 15:38:44 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 Thu Sep 4 15:38:37 2003 +++ b/fs/proc/base.c Thu Sep 4 15:38:37 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 Thu Sep 4 15:38:35 2003 +++ b/fs/proc/kcore.c Thu Sep 4 15:38:35 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/proc_misc.c b/fs/proc/proc_misc.c --- a/fs/proc/proc_misc.c Thu Sep 4 15:38:30 2003 +++ b/fs/proc/proc_misc.c Thu Sep 4 15:38:30 2003 @@ -356,10 +356,9 @@ .release = seq_release, }; -static int kstat_read_proc(char *page, char **start, off_t off, - int count, int *eof, void *data) +int show_stat(struct seq_file *p, void *v) { - int i, len; + int i; extern unsigned long total_forks; u64 jif; unsigned int sum = 0, user = 0, nice = 0, system = 0, idle = 0, iowait = 0, irq = 0, softirq = 0; @@ -379,10 +378,10 @@ jif = ((u64)now.tv_sec * HZ) + (now.tv_usec/(1000000/HZ)) - jif; do_div(jif, HZ); - for (i = 0 ; i < NR_CPUS; i++) { + for (i = 0; i < NR_CPUS; i++) { int j; - if(!cpu_online(i)) continue; + if (!cpu_online(i)) continue; user += kstat_cpu(i).cpustat.user; nice += kstat_cpu(i).cpustat.nice; system += kstat_cpu(i).cpustat.system; @@ -394,7 +393,7 @@ sum += kstat_cpu(i).irqs[j]; } - len = sprintf(page, "cpu %u %u %u %u %u %u %u\n", + seq_printf(p, "cpu %u %u %u %u %u %u %u\n", jiffies_to_clock_t(user), jiffies_to_clock_t(nice), jiffies_to_clock_t(system), @@ -402,9 +401,9 @@ jiffies_to_clock_t(iowait), jiffies_to_clock_t(irq), jiffies_to_clock_t(softirq)); - for (i = 0 ; i < NR_CPUS; i++){ + for (i = 0; i < NR_CPUS; i++){ if (!cpu_online(i)) continue; - len += sprintf(page + len, "cpu%d %u %u %u %u %u %u %u\n", + seq_printf(p, "cpu%d %u %u %u %u %u %u %u\n", i, jiffies_to_clock_t(kstat_cpu(i).cpustat.user), jiffies_to_clock_t(kstat_cpu(i).cpustat.nice), @@ -414,14 +413,14 @@ jiffies_to_clock_t(kstat_cpu(i).cpustat.irq), jiffies_to_clock_t(kstat_cpu(i).cpustat.softirq)); } - len += sprintf(page + len, "intr %u", sum); + seq_printf(p, "intr %u", sum); #if !defined(CONFIG_PPC64) && !defined(CONFIG_ALPHA) - for (i = 0 ; i < NR_IRQS ; i++) - len += sprintf(page + len, " %u", kstat_irqs(i)); + for (i = 0; i < NR_IRQS; i++) + seq_printf(p, " %u", kstat_irqs(i)); #endif - len += sprintf(page + len, + seq_printf(p, "\nctxt %lu\n" "btime %lu\n" "processes %lu\n" @@ -433,9 +432,39 @@ nr_running(), nr_iowait()); - return proc_calc_metrics(page, start, off, count, eof, len); + return 0; } +static int stat_open(struct inode *inode, struct file *file) +{ + unsigned size = 4096 * (1 + num_online_cpus() / 32); + char *buf; + struct seq_file *m; + int res; + + /* don't ask for more than the kmalloc() max size, currently 128 KB */ + if (size > 128 * 1024) + size = 128 * 1024; + buf = kmalloc(size, GFP_KERNEL); + if (!buf) + return -ENOMEM; + + res = single_open(file, show_stat, NULL); + if (!res) { + m = file->private_data; + m->buf = buf; + m->size = size; + } else + kfree(buf); + return res; +} +static struct file_operations proc_stat_operations = { + .open = stat_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + static int devices_read_proc(char *page, char **start, off_t off, int count, int *eof, void *data) { @@ -626,7 +655,6 @@ #ifdef CONFIG_STRAM_PROC {"stram", stram_read_proc}, #endif - {"stat", kstat_read_proc}, {"devices", devices_read_proc}, {"filesystems", filesystems_read_proc}, {"cmdline", cmdline_read_proc}, @@ -648,6 +676,7 @@ entry->proc_fops = &proc_kmsg_operations; create_seq_entry("cpuinfo", 0, &proc_cpuinfo_operations); create_seq_entry("partitions", 0, &proc_partitions_operations); + create_seq_entry("stat", 0, &proc_stat_operations); create_seq_entry("interrupts", 0, &proc_interrupts_operations); create_seq_entry("slabinfo",S_IWUSR|S_IRUGO,&proc_slabinfo_operations); create_seq_entry("buddyinfo",S_IRUGO, &fragmentation_file_operations); diff -Nru a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c --- a/fs/proc/task_mmu.c Thu Sep 4 15:38:30 2003 +++ b/fs/proc/task_mmu.c Thu Sep 4 15:38:30 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 Thu Sep 4 15:38:31 2003 +++ b/fs/reiserfs/inode.c Thu Sep 4 15:38:31 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 Thu Sep 4 15:38:30 2003 +++ b/fs/smbfs/inode.c Thu Sep 4 15:38:30 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 Thu Sep 4 15:38:38 2003 +++ b/fs/vfat/namei.c Thu Sep 4 15:38:38 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-alpha/semaphore.h b/include/asm-alpha/semaphore.h --- a/include/asm-alpha/semaphore.h Thu Sep 4 15:38:42 2003 +++ b/include/asm-alpha/semaphore.h Thu Sep 4 15:38:42 2003 @@ -88,14 +88,18 @@ static inline void __down(struct semaphore *sem) { - long count = atomic_dec_return(&sem->count); + long count; + might_sleep(); + count = atomic_dec_return(&sem->count); if (unlikely(count < 0)) __down_failed(sem); } static inline int __down_interruptible(struct semaphore *sem) { - long count = atomic_dec_return(&sem->count); + long count; + might_sleep(); + count = atomic_dec_return(&sem->count); if (unlikely(count < 0)) return __down_failed_interruptible(sem); return 0; 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 Thu Sep 4 15:38:48 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 Thu Sep 4 15:38:48 2003 +++ b/include/asm-arm/arch-ebsa285/time.h Thu Sep 4 15:38:48 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 Thu Sep 4 15:38:37 2003 +++ b/include/asm-arm/arch-ebsa285/timex.h Thu Sep 4 15:38:37 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 Thu Sep 4 15:38:33 2003 +++ b/include/asm-arm/arch-iop3xx/iop310.h Thu Sep 4 15:38:33 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 Thu Sep 4 15:38:48 2003 +++ b/include/asm-arm/arch-iop3xx/iop321.h Thu Sep 4 15:38:48 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 Thu Sep 4 15:38:43 2003 +++ b/include/asm-arm/arch-iop3xx/memory.h Thu Sep 4 15:38:43 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 Thu Sep 4 15:38:38 2003 +++ b/include/asm-arm/arch-pxa/pxa-regs.h Thu Sep 4 15:38:38 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 Thu Sep 4 15:38:31 2003 +++ b/include/asm-arm/arch-sa1100/simpad.h Thu Sep 4 15:38:31 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/assembler.h b/include/asm-arm/assembler.h --- a/include/asm-arm/assembler.h Thu Sep 4 15:38:29 2003 +++ b/include/asm-arm/assembler.h Thu Sep 4 15:38:29 2003 @@ -1,18 +1,23 @@ /* - * linux/asm/assembler.h + * linux/include/asm-arm/assembler.h * - * This file contains arm architecture specific defines - * for the different processors. + * Copyright (C) 1996-2000 Russell King * - * Do not include any C declarations in this file - it is included by - * assembler source. + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This file contains arm architecture specific defines + * for the different processors. + * + * Do not include any C declarations in this file - it is included by + * assembler source. */ #ifndef __ASSEMBLY__ #error "Only include this from assembly code" #endif -#include -#include +#include /* * Endian independent macros for shifting bytes within registers. @@ -36,3 +41,63 @@ #define PLD(code...) #endif +#define MODE_USR USR_MODE +#define MODE_FIQ FIQ_MODE +#define MODE_IRQ IRQ_MODE +#define MODE_SVC SVC_MODE + +#define DEFAULT_FIQ MODE_FIQ + +/* + * LOADREGS - ldm with PC in register list (eg, ldmfd sp!, {pc}) + */ +#ifdef __STDC__ +#define LOADREGS(cond, base, reglist...)\ + ldm##cond base,reglist +#else +#define LOADREGS(cond, base, reglist...)\ + ldm/**/cond base,reglist +#endif + +/* + * Build a return instruction for this processor type. + */ +#define RETINSTR(instr, regs...)\ + instr regs + +/* + * Save the current IRQ state and disable IRQs. Note that this macro + * assumes FIQs are enabled, and that the processor is in SVC mode. + */ + .macro save_and_disable_irqs, oldcpsr, temp + mrs \oldcpsr, cpsr + mov \temp, #PSR_I_BIT | MODE_SVC + msr cpsr_c, \temp + .endm + +/* + * Restore interrupt state previously stored in a register. We don't + * guarantee that this will preserve the flags. + */ + .macro restore_irqs, oldcpsr + msr cpsr_c, \oldcpsr + .endm + +/* + * These two are used to save LR/restore PC over a user-based access. + * The old 26-bit architecture requires that we do. On 32-bit + * architecture, we can safely ignore this requirement. + */ + .macro save_lr + .endm + + .macro restore_pc + mov pc, lr + .endm + +#define USER(x...) \ +9999: x; \ + .section __ex_table,"a"; \ + .align 3; \ + .long 9999b,9001f; \ + .previous diff -Nru a/include/asm-arm/atomic.h b/include/asm-arm/atomic.h --- a/include/asm-arm/atomic.h Thu Sep 4 15:38:30 2003 +++ b/include/asm-arm/atomic.h Thu Sep 4 15:38:30 2003 @@ -27,7 +27,7 @@ #define ATOMIC_INIT(i) { (i) } #ifdef __KERNEL__ -#include +#include #define atomic_read(v) ((v)->counter) #define atomic_set(v,i) (((v)->counter) = (i)) diff -Nru a/include/asm-arm/cacheflush.h b/include/asm-arm/cacheflush.h --- a/include/asm-arm/cacheflush.h Thu Sep 4 15:38:44 2003 +++ b/include/asm-arm/cacheflush.h Thu Sep 4 15:38:44 2003 @@ -1,7 +1,7 @@ /* * linux/include/asm-arm/cacheflush.h * - * Copyright (C) 2000-2002 Russell King + * Copyright (C) 1999-2002 Russell King * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as @@ -12,6 +12,275 @@ #include #include -#include + +#include +#include + +/* + * Cache Model + * =========== + */ +#undef _CACHE +#undef MULTI_CACHE + +#if defined(CONFIG_CPU_ARM610) || defined(CONFIG_CPU_ARM710) +# ifdef _CACHE +# define MULTI_CACHE 1 +# else +# define _CACHE v3 +# endif +#endif + +#if defined(CONFIG_CPU_ARM720T) +# ifdef _CACHE +# define MULTI_CACHE 1 +# else +# define _CACHE v4 +# endif +#endif + +#if defined(CONFIG_CPU_ARM920T) || defined(CONFIG_CPU_ARM922T) || \ + defined(CONFIG_CPU_ARM1020) +# define MULTI_CACHE 1 +#endif + +#if defined(CONFIG_CPU_ARM926T) +# ifdef _CACHE +# define MULTI_CACHE 1 +# else +# define _CACHE arm926 +# endif +#endif + +#if defined(CONFIG_CPU_SA110) || defined(CONFIG_CPU_SA1100) +# ifdef _CACHE +# define MULTI_CACHE 1 +# else +# define _CACHE v4wb +# endif +#endif + +#if defined(CONFIG_CPU_XSCALE) +# ifdef _CACHE +# define MULTI_CACHE 1 +# else +# define _CACHE xscale +# endif +#endif + +#if !defined(_CACHE) && !defined(MULTI_CACHE) +#error Unknown cache maintainence model +#endif + +/* + * This flag is used to indicate that the page pointed to by a pte + * is dirty and requires cleaning before returning it to the user. + */ +#define PG_dcache_dirty PG_arch_1 + +/* + * MM Cache Management + * =================== + * + * The arch/arm/mm/cache-*.S and arch/arm/mm/proc-*.S files + * implement these methods. + * + * Start addresses are inclusive and end addresses are exclusive; + * start addresses should be rounded down, end addresses up. + * + * See linux/Documentation/cachetlb.txt for more information. + * Please note that the implementation of these, and the required + * effects are cache-type (VIVT/VIPT/PIPT) specific. + * + * flush_cache_kern_all() + * + * Unconditionally clean and invalidate the entire cache. + * + * flush_cache_user_mm(mm) + * + * Clean and invalidate all user space cache entries + * before a change of page tables. + * + * flush_cache_user_range(start, end, flags) + * + * Clean and invalidate a range of cache entries in the + * specified address space before a change of page tables. + * - start - user start address (inclusive, page aligned) + * - end - user end address (exclusive, page aligned) + * - flags - vma->vm_flags field + * + * coherent_kern_range(start, end) + * + * Ensure coherency between the Icache and the Dcache in the + * region described by start, end. If you have non-snooping + * Harvard caches, you need to implement this function. + * - start - virtual start address + * - end - virtual end address + * + * DMA Cache Coherency + * =================== + * + * dma_inv_range(start, end) + * + * Invalidate (discard) the specified virtual address range. + * May not write back any entries. If 'start' or 'end' + * are not cache line aligned, those lines must be written + * back. + * - start - virtual start address + * - end - virtual end address + * + * dma_clean_range(start, end) + * + * Clean (write back) the specified virtual address range. + * - start - virtual start address + * - end - virtual end address + * + * dma_flush_range(start, end) + * + * Clean and invalidate the specified virtual address range. + * - start - virtual start address + * - end - virtual end address + */ + +struct cpu_cache_fns { + void (*flush_kern_all)(void); + void (*flush_user_all)(void); + void (*flush_user_range)(unsigned long, unsigned long, unsigned int); + + void (*coherent_kern_range)(unsigned long, unsigned long); + void (*flush_kern_dcache_page)(void *); + + void (*dma_inv_range)(unsigned long, unsigned long); + void (*dma_clean_range)(unsigned long, unsigned long); + void (*dma_flush_range)(unsigned long, unsigned long); +}; + +/* + * Select the calling method + */ +#ifdef MULTI_CACHE + +extern struct cpu_cache_fns cpu_cache; + +#define __cpuc_flush_kern_all cpu_cache.flush_kern_all +#define __cpuc_flush_user_all cpu_cache.flush_user_all +#define __cpuc_flush_user_range cpu_cache.flush_user_range +#define __cpuc_coherent_kern_range cpu_cache.coherent_kern_range +#define __cpuc_flush_dcache_page cpu_cache.flush_kern_dcache_page + +/* + * These are private to the dma-mapping API. Do not use directly. + * Their sole purpose is to ensure that data held in the cache + * is visible to DMA, or data written by DMA to system memory is + * visible to the CPU. + */ +#define dmac_inv_range cpu_cache.dma_inv_range +#define dmac_clean_range cpu_cache.dma_clean_range +#define dmac_flush_range cpu_cache.dma_flush_range + +#else + +#define __cpuc_flush_kern_all __glue(_CACHE,_flush_kern_cache_all) +#define __cpuc_flush_user_all __glue(_CACHE,_flush_user_cache_all) +#define __cpuc_flush_user_range __glue(_CACHE,_flush_user_cache_range) +#define __cpuc_coherent_kern_range __glue(_CACHE,_coherent_kern_range) +#define __cpuc_flush_dcache_page __glue(_CACHE,_flush_kern_dcache_page) + +extern void __cpuc_flush_kern_all(void); +extern void __cpuc_flush_user_all(void); +extern void __cpuc_flush_user_range(unsigned long, unsigned long, unsigned int); +extern void __cpuc_coherent_kern_range(unsigned long, unsigned long); +extern void __cpuc_flush_dcache_page(void *); + +/* + * These are private to the dma-mapping API. Do not use directly. + * Their sole purpose is to ensure that data held in the cache + * is visible to DMA, or data written by DMA to system memory is + * visible to the CPU. + */ +#define dmac_inv_range __glue(_CACHE,_dma_inv_range) +#define dmac_clean_range __glue(_CACHE,_dma_clean_range) +#define dmac_flush_range __glue(_CACHE,_dma_flush_range) + +extern void dmac_inv_range(unsigned long, unsigned long); +extern void dmac_clean_range(unsigned long, unsigned long); +extern void dmac_flush_range(unsigned long, unsigned long); + +#endif + +/* + * Convert calls to our calling convention. + */ +#define flush_cache_all() __cpuc_flush_kern_all() + +static inline void flush_cache_mm(struct mm_struct *mm) +{ + if (current->active_mm == mm) + __cpuc_flush_user_all(); +} + +static inline void +flush_cache_range(struct vm_area_struct *vma, unsigned long start, unsigned long end) +{ + if (current->active_mm == vma->vm_mm) + __cpuc_flush_user_range(start & PAGE_MASK, PAGE_ALIGN(end), + vma->vm_flags); +} + +static inline void +flush_cache_page(struct vm_area_struct *vma, unsigned long user_addr) +{ + if (current->active_mm == vma->vm_mm) { + unsigned long addr = user_addr & PAGE_MASK; + __cpuc_flush_user_range(addr, addr + PAGE_SIZE, vma->vm_flags); + } +} + +/* + * Perform necessary cache operations to ensure that data previously + * stored within this range of addresses can be executed by the CPU. + */ +#define flush_icache_range(s,e) __cpuc_coherent_kern_range(s,e) + +/* + * Perform necessary cache operations to ensure that the TLB will + * see data written in the specified area. + */ +#define clean_dcache_area(start,size) cpu_dcache_clean_area(start, size) + +/* + * flush_dcache_page is used when the kernel has written to the page + * cache page at virtual address page->virtual. + * + * If this page isn't mapped (ie, page->mapping = NULL), or it has + * userspace mappings (page->mapping->i_mmap or page->mapping->i_mmap_shared) + * then we _must_ always clean + invalidate the dcache entries associated + * with the kernel mapping. + * + * Otherwise we can defer the operation, and clean the cache when we are + * about to change to user space. This is the same method as used on SPARC64. + * See update_mmu_cache for the user space part. + */ +#define mapping_mapped(map) (!list_empty(&(map)->i_mmap) || \ + !list_empty(&(map)->i_mmap_shared)) + +extern void __flush_dcache_page(struct page *); + +static inline void flush_dcache_page(struct page *page) +{ + if (page->mapping && !mapping_mapped(page->mapping)) + set_bit(PG_dcache_dirty, &page->flags); + else + __flush_dcache_page(page); +} + +#define flush_icache_user_range(vma,page,addr,len) \ + flush_dcache_page(page) + +/* + * We don't appear to need to do anything here. In fact, if we did, we'd + * duplicate cache flushing elsewhere performed by flush_dcache_page(). + */ +#define flush_icache_page(vma,page) do { } while (0) #endif diff -Nru a/include/asm-arm/checksum.h b/include/asm-arm/checksum.h --- a/include/asm-arm/checksum.h Thu Sep 4 15:38:44 2003 +++ b/include/asm-arm/checksum.h Thu Sep 4 15:38:44 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/cpu-multi26.h b/include/asm-arm/cpu-multi26.h --- a/include/asm-arm/cpu-multi26.h Thu Sep 4 15:38:42 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,47 +0,0 @@ -/* - * linux/include/asm-arm/cpu-multi26.h - * - * Copyright (C) 2000 Russell King - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#ifndef __ASSEMBLY__ - -#include - -/* forward-declare task_struct */ -struct task_struct; - -/* - * Don't change this structure - ASM code - * relies on it. - */ -extern struct processor { - /* Set up any processor specifics */ - void (*_proc_init)(void); - /* Disable any processor specifics */ - void (*_proc_fin)(void); - /* set the MEMC hardware mappings */ - void (*_switch_mm)(pgd_t *pgd); - /* XCHG */ - unsigned long (*_xchg_1)(unsigned long x, volatile void *ptr); - unsigned long (*_xchg_4)(unsigned long x, volatile void *ptr); -} processor; - -extern const struct processor arm2_processor_functions; -extern const struct processor arm250_processor_functions; -extern const struct processor arm3_processor_functions; - -#define cpu_proc_init() processor._proc_init() -#define cpu_proc_fin() processor._proc_fin() -#define cpu_do_idle() do { } while (0) -#define cpu_switch_mm(pgd,mm) processor._switch_mm(pgd) -#define cpu_xchg_1(x,ptr) processor._xchg_1(x,ptr) -#define cpu_xchg_4(x,ptr) processor._xchg_4(x,ptr) - -extern void cpu_memc_update_all(pgd_t *pgd); -extern void cpu_memc_update_entry(pgd_t *pgd, unsigned long phys_pte, unsigned long log_addr); - -#endif diff -Nru a/include/asm-arm/dma-mapping.h b/include/asm-arm/dma-mapping.h --- a/include/asm-arm/dma-mapping.h Thu Sep 4 15:38:29 2003 +++ b/include/asm-arm/dma-mapping.h Thu Sep 4 15:38:29 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/domain.h b/include/asm-arm/domain.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/asm-arm/domain.h Thu Sep 4 15:38:41 2003 @@ -0,0 +1,50 @@ +/* + * linux/include/asm-arm/domain.h + * + * Copyright (C) 1999 Russell King. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +#ifndef __ASM_PROC_DOMAIN_H +#define __ASM_PROC_DOMAIN_H + +/* + * Domain numbers + * + * DOMAIN_IO - domain 2 includes all IO only + * DOMAIN_KERNEL - domain 1 includes all kernel memory only + * DOMAIN_USER - domain 0 includes all user memory only + */ +#define DOMAIN_USER 0 +#define DOMAIN_KERNEL 1 +#define DOMAIN_TABLE 1 +#define DOMAIN_IO 2 + +/* + * Domain types + */ +#define DOMAIN_NOACCESS 0 +#define DOMAIN_CLIENT 1 +#define DOMAIN_MANAGER 3 + +#define domain_val(dom,type) ((type) << 2*(dom)) + +#define set_domain(x) \ + do { \ + __asm__ __volatile__( \ + "mcr p15, 0, %0, c3, c0 @ set domain" \ + : : "r" (x)); \ + } while (0) + +#define modify_domain(dom,type) \ + do { \ + struct thread_info *thread = current_thread_info(); \ + unsigned int domain = thread->cpu_domain; \ + domain &= ~domain_val(dom, DOMAIN_MANAGER); \ + thread->cpu_domain = domain | domain_val(dom, type); \ + set_domain(thread->cpu_domain); \ + } while (0) + +#endif diff -Nru a/include/asm-arm/elf.h b/include/asm-arm/elf.h --- a/include/asm-arm/elf.h Thu Sep 4 15:38:44 2003 +++ b/include/asm-arm/elf.h Thu Sep 4 15:38:44 2003 @@ -7,7 +7,6 @@ #include #include -#include #include typedef unsigned long elf_greg_t; @@ -42,6 +41,7 @@ #define ELF_ARCH EM_ARM #define USE_ELF_CORE_DUMP +#define ELF_EXEC_PAGESIZE 4096 /* This is the location that an ET_DYN program is loaded if exec'ed. Typical use of this is to invoke "./ld.so someprog" to test out a new version of @@ -75,5 +75,30 @@ #define ELF_PLATFORM_SIZE 8 extern char elf_platform[]; #define ELF_PLATFORM (elf_platform) + +#ifdef __KERNEL__ + +/* + * 32-bit code is always OK. Some cpus can do 26-bit, some can't. + */ +#define ELF_PROC_OK(x) (ELF_THUMB_OK(x) && ELF_26BIT_OK(x)) + +#define ELF_THUMB_OK(x) \ + (( (elf_hwcap & HWCAP_THUMB) && ((x)->e_entry & 1) == 1) || \ + ((x)->e_entry & 3) == 0) + +#define ELF_26BIT_OK(x) \ + (( (elf_hwcap & HWCAP_26BIT) && (x)->e_flags & EF_ARM_APCS26) || \ + ((x)->e_flags & EF_ARM_APCS26) == 0) + +/* Old NetWinder binaries were compiled in such a way that the iBCS + heuristic always trips on them. Until these binaries become uncommon + enough not to care, don't trust the `ibcs' flag here. In any case + there is no other ELF system currently supported by iBCS. + @@ Could print a warning message to encourage users to upgrade. */ +#define SET_PERSONALITY(ex,ibcs2) \ + set_personality(((ex).e_flags&EF_ARM_APCS26 ?PER_LINUX :PER_LINUX_32BIT)) + +#endif #endif diff -Nru a/include/asm-arm/hardware/amba.h b/include/asm-arm/hardware/amba.h --- a/include/asm-arm/hardware/amba.h Thu Sep 4 15:38:43 2003 +++ b/include/asm-arm/hardware/amba.h Thu Sep 4 15:38:43 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 Thu Sep 4 15:38:47 2003 +++ b/include/asm-arm/hardware/sa1111.h Thu Sep 4 15:38:47 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/locks.h b/include/asm-arm/locks.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/asm-arm/locks.h Thu Sep 4 15:38:45 2003 @@ -0,0 +1,139 @@ +/* + * linux/include/asm-arm/locks.h + * + * Copyright (C) 2000 Russell King + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * Interrupt safe locking assembler. + */ +#ifndef __ASM_PROC_LOCKS_H +#define __ASM_PROC_LOCKS_H + +#define __down_op(ptr,fail) \ + ({ \ + __asm__ __volatile__( \ + "@ down_op\n" \ +" mrs ip, cpsr\n" \ +" orr lr, ip, #128\n" \ +" msr cpsr_c, lr\n" \ +" ldr lr, [%0]\n" \ +" subs lr, lr, %1\n" \ +" str lr, [%0]\n" \ +" msr cpsr_c, ip\n" \ +" movmi ip, %0\n" \ +" blmi " #fail \ + : \ + : "r" (ptr), "I" (1) \ + : "ip", "lr", "cc", "memory"); \ + }) + +#define __down_op_ret(ptr,fail) \ + ({ \ + unsigned int ret; \ + __asm__ __volatile__( \ + "@ down_op_ret\n" \ +" mrs ip, cpsr\n" \ +" orr lr, ip, #128\n" \ +" msr cpsr_c, lr\n" \ +" ldr lr, [%1]\n" \ +" subs lr, lr, %2\n" \ +" str lr, [%1]\n" \ +" msr cpsr_c, ip\n" \ +" movmi ip, %1\n" \ +" movpl ip, #0\n" \ +" blmi " #fail "\n" \ +" mov %0, ip" \ + : "=&r" (ret) \ + : "r" (ptr), "I" (1) \ + : "ip", "lr", "cc", "memory"); \ + ret; \ + }) + +#define __up_op(ptr,wake) \ + ({ \ + __asm__ __volatile__( \ + "@ up_op\n" \ +" mrs ip, cpsr\n" \ +" orr lr, ip, #128\n" \ +" msr cpsr_c, lr\n" \ +" ldr lr, [%0]\n" \ +" adds lr, lr, %1\n" \ +" str lr, [%0]\n" \ +" msr cpsr_c, ip\n" \ +" movle ip, %0\n" \ +" blle " #wake \ + : \ + : "r" (ptr), "I" (1) \ + : "ip", "lr", "cc", "memory"); \ + }) + +/* + * The value 0x01000000 supports up to 128 processors and + * lots of processes. BIAS must be chosen such that sub'ing + * BIAS once per CPU will result in the long remaining + * negative. + */ +#define RW_LOCK_BIAS 0x01000000 +#define RW_LOCK_BIAS_STR "0x01000000" + +#define __down_op_write(ptr,fail) \ + ({ \ + __asm__ __volatile__( \ + "@ down_op_write\n" \ +" mrs ip, cpsr\n" \ +" orr lr, ip, #128\n" \ +" msr cpsr_c, lr\n" \ +" ldr lr, [%0]\n" \ +" subs lr, lr, %1\n" \ +" str lr, [%0]\n" \ +" msr cpsr_c, ip\n" \ +" movne ip, %0\n" \ +" blne " #fail \ + : \ + : "r" (ptr), "I" (RW_LOCK_BIAS) \ + : "ip", "lr", "cc", "memory"); \ + }) + +#define __up_op_write(ptr,wake) \ + ({ \ + __asm__ __volatile__( \ + "@ up_op_read\n" \ +" mrs ip, cpsr\n" \ +" orr lr, ip, #128\n" \ +" msr cpsr_c, lr\n" \ +" ldr lr, [%0]\n" \ +" adds lr, lr, %1\n" \ +" str lr, [%0]\n" \ +" msr cpsr_c, ip\n" \ +" movcs ip, %0\n" \ +" blcs " #wake \ + : \ + : "r" (ptr), "I" (RW_LOCK_BIAS) \ + : "ip", "lr", "cc", "memory"); \ + }) + +#define __down_op_read(ptr,fail) \ + __down_op(ptr, fail) + +#define __up_op_read(ptr,wake) \ + ({ \ + __asm__ __volatile__( \ + "@ up_op_read\n" \ +" mrs ip, cpsr\n" \ +" orr lr, ip, #128\n" \ +" msr cpsr_c, lr\n" \ +" ldr lr, [%0]\n" \ +" adds lr, lr, %1\n" \ +" str lr, [%0]\n" \ +" msr cpsr_c, ip\n" \ +" moveq ip, %0\n" \ +" bleq " #wake \ + : \ + : "r" (ptr), "I" (1) \ + : "ip", "lr", "cc", "memory"); \ + }) + +#endif diff -Nru a/include/asm-arm/memory.h b/include/asm-arm/memory.h --- a/include/asm-arm/memory.h Thu Sep 4 15:38:45 2003 +++ b/include/asm-arm/memory.h Thu Sep 4 15:38:45 2003 @@ -15,6 +15,8 @@ #include #include +#ifndef __ASSEMBLY__ + /* * PFNs are used to describe any physical page; this means * PFN 0 == physical address 0. @@ -118,5 +120,7 @@ * We should really eliminate virt_to_bus() here - it's deprecated. */ #define page_to_bus(page) (virt_to_bus(page_address(page))) + +#endif #endif diff -Nru a/include/asm-arm/page.h b/include/asm-arm/page.h --- a/include/asm-arm/page.h Thu Sep 4 15:38:30 2003 +++ b/include/asm-arm/page.h Thu Sep 4 15:38:30 2003 @@ -1,9 +1,27 @@ +/* + * linux/include/asm-arm/page.h + * + * Copyright (C) 1995-2003 Russell King + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ #ifndef _ASMARM_PAGE_H #define _ASMARM_PAGE_H #include +/* PAGE_SHIFT determines the page size */ +#define PAGE_SHIFT 12 +#define PAGE_SIZE (1UL << PAGE_SHIFT) +#define PAGE_MASK (~(PAGE_SIZE-1)) + #ifdef __KERNEL__ + +/* to align the pointer to the (next) page boundary */ +#define PAGE_ALIGN(addr) (((addr)+PAGE_SIZE-1)&PAGE_MASK) + #ifndef __ASSEMBLY__ #include @@ -119,10 +137,12 @@ */ typedef struct { unsigned long pte; } pte_t; typedef struct { unsigned long pmd; } pmd_t; +typedef struct { unsigned long pgd[2]; } pgd_t; typedef struct { unsigned long pgprot; } pgprot_t; #define pte_val(x) ((x).pte) #define pmd_val(x) ((x).pmd) +#define pgd_val(x) ((x).pgd[0]) #define pgprot_val(x) ((x).pgprot) #define __pte(x) ((pte_t) { (x) } ) @@ -135,10 +155,12 @@ */ typedef unsigned long pte_t; typedef unsigned long pmd_t; +typedef unsigned long pgd_t[2]; typedef unsigned long pgprot_t; #define pte_val(x) (x) #define pmd_val(x) (x) +#define pgd_val(x) ((x)[0]) #define pgprot_val(x) (x) #define __pte(x) (x) @@ -146,19 +168,6 @@ #define __pgprot(x) (x) #endif /* STRICT_MM_TYPECHECKS */ -#endif /* !__ASSEMBLY__ */ -#endif /* __KERNEL__ */ - -#include - -#define PAGE_SIZE (1UL << PAGE_SHIFT) -#define PAGE_MASK (~(PAGE_SIZE-1)) - -/* to align the pointer to the (next) page boundary */ -#define PAGE_ALIGN(addr) (((addr)+PAGE_SIZE-1)&PAGE_MASK) - -#ifdef __KERNEL__ -#ifndef __ASSEMBLY__ /* Pure 2^n version of get_order */ static inline int get_order(unsigned long size) diff -Nru a/include/asm-arm/param.h b/include/asm-arm/param.h --- a/include/asm-arm/param.h Thu Sep 4 15:38:35 2003 +++ b/include/asm-arm/param.h Thu Sep 4 15:38:35 2003 @@ -11,7 +11,6 @@ #define __ASM_PARAM_H #include /* for HZ */ -#include /* for EXEC_PAGE_SIZE */ #ifndef __KERNEL_HZ #define __KERNEL_HZ 100 @@ -24,6 +23,8 @@ #else # define HZ 100 #endif + +#define EXEC_PAGESIZE 4096 #ifndef NGROUPS #define NGROUPS 32 diff -Nru a/include/asm-arm/pci.h b/include/asm-arm/pci.h --- a/include/asm-arm/pci.h Thu Sep 4 15:38:31 2003 +++ b/include/asm-arm/pci.h Thu Sep 4 15:38:31 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/pgalloc.h b/include/asm-arm/pgalloc.h --- a/include/asm-arm/pgalloc.h Thu Sep 4 15:38:45 2003 +++ b/include/asm-arm/pgalloc.h Thu Sep 4 15:38:45 2003 @@ -11,7 +11,8 @@ #define _ASMARM_PGALLOC_H #include -#include +#include +#include /* * Since we have only two-level page tables, these are trivial @@ -27,5 +28,105 @@ #define pgd_free(pgd) free_pgd_slow(pgd) #define check_pgt_cache() do { } while (0) + +/* + * Allocate one PTE table. + * + * This actually allocates two hardware PTE tables, but we wrap this up + * into one table thus: + * + * +------------+ + * | h/w pt 0 | + * +------------+ + * | h/w pt 1 | + * +------------+ + * | Linux pt 0 | + * +------------+ + * | Linux pt 1 | + * +------------+ + */ +static inline pte_t * +pte_alloc_one_kernel(struct mm_struct *mm, unsigned long addr) +{ + pte_t *pte; + + pte = (pte_t *)__get_free_page(GFP_KERNEL|__GFP_REPEAT); + if (pte) { + clear_page(pte); + clean_dcache_area(pte, sizeof(pte_t) * PTRS_PER_PTE); + pte += PTRS_PER_PTE; + } + + return pte; +} + +static inline struct page * +pte_alloc_one(struct mm_struct *mm, unsigned long addr) +{ + struct page *pte; + + pte = alloc_pages(GFP_KERNEL|__GFP_REPEAT, 0); + if (pte) { + void *page = page_address(pte); + clear_page(page); + clean_dcache_area(page, sizeof(pte_t) * PTRS_PER_PTE); + } + + return pte; +} + +/* + * Free one PTE table. + */ +static inline void pte_free_kernel(pte_t *pte) +{ + if (pte) { + pte -= PTRS_PER_PTE; + free_page((unsigned long)pte); + } +} + +static inline void pte_free(struct page *pte) +{ + __free_page(pte); +} + +/* + * Populate the pmdp entry with a pointer to the pte. This pmd is part + * of the mm address space. + * + * Ensure that we always set both PMD entries. + */ +static inline void +pmd_populate_kernel(struct mm_struct *mm, pmd_t *pmdp, pte_t *ptep) +{ + unsigned long pte_ptr = (unsigned long)ptep; + unsigned long pmdval; + + BUG_ON(mm != &init_mm); + + /* + * The pmd must be loaded with the physical + * address of the PTE table + */ + pte_ptr -= PTRS_PER_PTE * sizeof(void *); + pmdval = __pa(pte_ptr) | _PAGE_KERNEL_TABLE; + pmdp[0] = __pmd(pmdval); + pmdp[1] = __pmd(pmdval + 256 * sizeof(pte_t)); + flush_pmd_entry(pmdp); +} + +static inline void +pmd_populate(struct mm_struct *mm, pmd_t *pmdp, struct page *ptep) +{ + unsigned long pmdval; + + BUG_ON(mm == &init_mm); + + pmdval = page_to_pfn(ptep) << PAGE_SHIFT | _PAGE_USER_TABLE; + pmdp[0] = __pmd(pmdval); + pmdp[1] = __pmd(pmdval + 256 * sizeof(pte_t)); + flush_pmd_entry(pmdp); +} #endif diff -Nru a/include/asm-arm/pgtable.h b/include/asm-arm/pgtable.h --- a/include/asm-arm/pgtable.h Thu Sep 4 15:38:31 2003 +++ b/include/asm-arm/pgtable.h Thu Sep 4 15:38:31 2003 @@ -1,7 +1,7 @@ /* * linux/include/asm-arm/pgtable.h * - * Copyright (C) 2000-2002 Russell King + * Copyright (C) 1995-2002 Russell King * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as @@ -16,15 +16,24 @@ #include /* + * We pull a couple of tricks here: + * 1. We wrap the PMD into the PGD. + * 2. We lie about the size of the PTE and PGD. + * Even though we have 256 PTE entries and 4096 PGD entries, we tell + * Linux that we actually have 512 PTE entries and 2048 PGD entries. + * Each "Linux" PGD entry is made up of two hardware PGD entries, and + * each PTE table is actually two hardware PTE tables. + */ +#define PTRS_PER_PTE 512 +#define PTRS_PER_PMD 1 +#define PTRS_PER_PGD 2048 + +/* * PMD_SHIFT determines the size of the area a second-level page table can map * PGDIR_SHIFT determines what a third-level page table entry can map */ #define PMD_SHIFT 20 -#ifdef CONFIG_CPU_32 #define PGDIR_SHIFT 21 -#else -#define PGDIR_SHIFT 20 -#endif #define LIBRARY_TEXT_START 0x0c000000 @@ -47,6 +56,117 @@ #define USER_PTRS_PER_PGD ((TASK_SIZE/PGDIR_SIZE) - FIRST_USER_PGD_NR) /* + * Hardware page table definitions. + * + * + Level 1 descriptor (PMD) + * - common + */ +#define PMD_TYPE_MASK (3 << 0) +#define PMD_TYPE_FAULT (0 << 0) +#define PMD_TYPE_TABLE (1 << 0) +#define PMD_TYPE_SECT (2 << 0) +#define PMD_BIT4 (1 << 4) +#define PMD_DOMAIN(x) ((x) << 5) +#define PMD_PROTECTION (1 << 9) /* v5 */ +/* + * - section + */ +#define PMD_SECT_BUFFERABLE (1 << 2) +#define PMD_SECT_CACHEABLE (1 << 3) +#define PMD_SECT_AP_WRITE (1 << 10) +#define PMD_SECT_AP_READ (1 << 11) +#define PMD_SECT_TEX(x) ((x) << 12) /* v5 */ +#define PMD_SECT_APX (1 << 15) /* v6 */ +#define PMD_SECT_S (1 << 16) /* v6 */ +#define PMD_SECT_nG (1 << 17) /* v6 */ + +#define PMD_SECT_UNCACHED (0) +#define PMD_SECT_BUFFERED (PMD_SECT_BUFFERABLE) +#define PMD_SECT_WT (PMD_SECT_CACHEABLE) +#define PMD_SECT_WB (PMD_SECT_CACHEABLE | PMD_SECT_BUFFERABLE) +#define PMD_SECT_MINICACHE (PMD_SECT_TEX(1) | PMD_SECT_CACHEABLE) +#define PMD_SECT_WBWA (PMD_SECT_TEX(1) | PMD_SECT_CACHEABLE | PMD_SECT_BUFFERABLE) + +/* + * - coarse table (not used) + */ + +/* + * + Level 2 descriptor (PTE) + * - common + */ +#define PTE_TYPE_MASK (3 << 0) +#define PTE_TYPE_FAULT (0 << 0) +#define PTE_TYPE_LARGE (1 << 0) +#define PTE_TYPE_SMALL (2 << 0) +#define PTE_TYPE_EXT (3 << 0) /* v5 */ +#define PTE_BUFFERABLE (1 << 2) +#define PTE_CACHEABLE (1 << 3) + +/* + * - extended small page/tiny page + */ +#define PTE_EXT_AP_UNO_SRO (0 << 4) +#define PTE_EXT_AP_UNO_SRW (1 << 4) +#define PTE_EXT_AP_URO_SRW (2 << 4) +#define PTE_EXT_AP_URW_SRW (3 << 4) +#define PTE_EXT_TEX(x) ((x) << 6) /* v5 */ + +/* + * - small page + */ +#define PTE_SMALL_AP_UNO_SRO (0x00 << 4) +#define PTE_SMALL_AP_UNO_SRW (0x55 << 4) +#define PTE_SMALL_AP_URO_SRW (0xaa << 4) +#define PTE_SMALL_AP_URW_SRW (0xff << 4) +#define PTE_AP_READ PTE_SMALL_AP_URO_SRW +#define PTE_AP_WRITE PTE_SMALL_AP_UNO_SRW + +/* + * "Linux" PTE definitions. + * + * We keep two sets of PTEs - the hardware and the linux version. + * This allows greater flexibility in the way we map the Linux bits + * onto the hardware tables, and allows us to have YOUNG and DIRTY + * bits. + * + * The PTE table pointer refers to the hardware entries; the "Linux" + * entries are stored 1024 bytes below. + */ +#define L_PTE_PRESENT (1 << 0) +#define L_PTE_FILE (1 << 1) /* only when !PRESENT */ +#define L_PTE_YOUNG (1 << 1) +#define L_PTE_BUFFERABLE (1 << 2) /* matches PTE */ +#define L_PTE_CACHEABLE (1 << 3) /* matches PTE */ +#define L_PTE_USER (1 << 4) +#define L_PTE_WRITE (1 << 5) +#define L_PTE_EXEC (1 << 6) +#define L_PTE_DIRTY (1 << 7) + +#ifndef __ASSEMBLY__ + +#include + +#define _PAGE_USER_TABLE (PMD_TYPE_TABLE | PMD_BIT4 | PMD_DOMAIN(DOMAIN_USER)) +#define _PAGE_KERNEL_TABLE (PMD_TYPE_TABLE | PMD_BIT4 | PMD_DOMAIN(DOMAIN_KERNEL)) + +/* + * The following macros handle the cache and bufferable bits... + */ +#define _L_PTE_DEFAULT L_PTE_PRESENT | L_PTE_YOUNG +#define _L_PTE_READ L_PTE_USER | L_PTE_EXEC | L_PTE_CACHEABLE | L_PTE_BUFFERABLE + +#define PAGE_NONE __pgprot(_L_PTE_DEFAULT) +#define PAGE_COPY __pgprot(_L_PTE_DEFAULT | _L_PTE_READ) +#define PAGE_SHARED __pgprot(_L_PTE_DEFAULT | _L_PTE_READ | L_PTE_WRITE) +#define PAGE_READONLY __pgprot(_L_PTE_DEFAULT | _L_PTE_READ) +#define PAGE_KERNEL __pgprot(_L_PTE_DEFAULT | L_PTE_CACHEABLE | L_PTE_BUFFERABLE | L_PTE_DIRTY | L_PTE_WRITE | L_PTE_EXEC) + +#define _PAGE_CHG_MASK (PAGE_MASK | L_PTE_DIRTY | L_PTE_YOUNG) + +#endif /* __ASSEMBLY__ */ + +/* * The table below defines the page protection levels that we insert into our * Linux page table version. These get translated into the best that the * architecture can perform. Note that on most ARM hardware: @@ -86,9 +206,82 @@ #define pte_none(pte) (!pte_val(pte)) #define pte_clear(ptep) set_pte((ptep), __pte(0)) #define pte_page(pte) (pfn_to_page(pte_pfn(pte))) +#define pte_offset_kernel(dir,addr) (pmd_page_kernel(*(dir)) + __pte_index(addr)) +#define pte_offset_map(dir,addr) (pmd_page_kernel(*(dir)) + __pte_index(addr)) +#define pte_offset_map_nested(dir,addr) (pmd_page_kernel(*(dir)) + __pte_index(addr)) +#define pte_unmap(pte) do { } while (0) +#define pte_unmap_nested(pte) do { } while (0) + +#define set_pte(ptep, pte) cpu_set_pte(ptep,pte) + +/* + * The following only work if pte_present() is true. + * Undefined behaviour if not.. + */ +#define pte_present(pte) (pte_val(pte) & L_PTE_PRESENT) +#define pte_read(pte) (pte_val(pte) & L_PTE_USER) +#define pte_write(pte) (pte_val(pte) & L_PTE_WRITE) +#define pte_exec(pte) (pte_val(pte) & L_PTE_EXEC) +#define pte_dirty(pte) (pte_val(pte) & L_PTE_DIRTY) +#define pte_young(pte) (pte_val(pte) & L_PTE_YOUNG) + +/* + * The following only works if pte_present() is not true. + */ +#define pte_file(pte) (pte_val(pte) & L_PTE_FILE) +#define pte_to_pgoff(x) (pte_val(x) >> 2) +#define pgoff_to_pte(x) __pte(((x) << 2) | L_PTE_FILE) + +#define PTE_FILE_MAX_BITS 30 + +#define PTE_BIT_FUNC(fn,op) \ +static inline pte_t pte_##fn(pte_t pte) { pte_val(pte) op; return pte; } + +/*PTE_BIT_FUNC(rdprotect, &= ~L_PTE_USER);*/ +/*PTE_BIT_FUNC(mkread, |= L_PTE_USER);*/ +PTE_BIT_FUNC(wrprotect, &= ~L_PTE_WRITE); +PTE_BIT_FUNC(mkwrite, |= L_PTE_WRITE); +PTE_BIT_FUNC(exprotect, &= ~L_PTE_EXEC); +PTE_BIT_FUNC(mkexec, |= L_PTE_EXEC); +PTE_BIT_FUNC(mkclean, &= ~L_PTE_DIRTY); +PTE_BIT_FUNC(mkdirty, |= L_PTE_DIRTY); +PTE_BIT_FUNC(mkold, &= ~L_PTE_YOUNG); +PTE_BIT_FUNC(mkyoung, |= L_PTE_YOUNG); + +/* + * Mark the prot value as uncacheable and unbufferable. + */ +#define pgprot_noncached(prot) __pgprot(pgprot_val(prot) & ~(L_PTE_CACHEABLE | L_PTE_BUFFERABLE)) +#define pgprot_writecombine(prot) __pgprot(pgprot_val(prot) & ~L_PTE_CACHEABLE) #define pmd_none(pmd) (!pmd_val(pmd)) #define pmd_present(pmd) (pmd_val(pmd)) +#define pmd_bad(pmd) (pmd_val(pmd) & 2) + +#define set_pmd(pmdp,pmd) \ + do { \ + *pmdp = pmd; \ + flush_pmd_entry(pmdp); \ + } while (0) + +#define pmd_clear(pmdp) \ + do { \ + pmdp[0] = __pmd(0); \ + pmdp[1] = __pmd(0); \ + clean_pmd_entry(pmdp); \ + } while (0) + +static inline pte_t *pmd_page_kernel(pmd_t pmd) +{ + unsigned long ptr; + + ptr = pmd_val(pmd) & ~(PTRS_PER_PTE * sizeof(void *) - 1); + ptr += PTRS_PER_PTE * sizeof(void *); + + return __va(ptr); +} + +#define pmd_page(pmd) virt_to_page(__va(pmd_val(pmd))) /* * Permanent address of a page. We never have highmem, so this is trivial. @@ -129,8 +322,6 @@ /* Find an entry in the third-level page table.. */ #define __pte_index(addr) (((addr) >> PAGE_SHIFT) & (PTRS_PER_PTE - 1)) -#include - static inline pte_t pte_modify(pte_t pte, pgprot_t newprot) { pte_val(pte) = (pte_val(pte) & _PAGE_CHG_MASK) | pgprot_val(newprot); @@ -163,6 +354,8 @@ remap_page_range(vma,from,phys,size,prot) typedef pte_t *pte_addr_t; + +#define pgtable_cache_init() do { } while (0) #endif /* !__ASSEMBLY__ */ diff -Nru a/include/asm-arm/proc-armo/assembler.h b/include/asm-arm/proc-armo/assembler.h --- a/include/asm-arm/proc-armo/assembler.h Thu Sep 4 15:38:37 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,106 +0,0 @@ -/* - * linux/asm-arm/proc-armo/assembler.h - * - * Copyright (C) 1996 Russell King - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * This file contains arm architecture specific defines - * for the different processors - */ -#define MODE_USR USR26_MODE -#define MODE_FIQ FIQ26_MODE -#define MODE_IRQ IRQ26_MODE -#define MODE_SVC SVC26_MODE - -#define DEFAULT_FIQ MODE_FIQ - -#ifdef __STDC__ -#define LOADREGS(cond, base, reglist...)\ - ldm##cond base,reglist^ - -#define RETINSTR(instr, regs...)\ - instr##s regs -#else -#define LOADREGS(cond, base, reglist...)\ - ldm/**/cond base,reglist^ - -#define RETINSTR(instr, regs...)\ - instr/**/s regs -#endif - -#define MODENOP\ - mov r0, r0 - -#define MODE(savereg,tmpreg,mode) \ - mov savereg, pc; \ - bic tmpreg, savereg, $0x0c000003; \ - orr tmpreg, tmpreg, $mode; \ - teqp tmpreg, $0 - -#define RESTOREMODE(savereg) \ - teqp savereg, $0 - -#define SAVEIRQS(tmpreg) - -#define RESTOREIRQS(tmpreg) - -#define DISABLEIRQS(tmpreg)\ - teqp pc, $0x08000003 - -#define ENABLEIRQS(tmpreg)\ - teqp pc, $0x00000003 - -#define USERMODE(tmpreg)\ - teqp pc, $0x00000000;\ - mov r0, r0 - -#define SVCMODE(tmpreg)\ - teqp pc, $0x00000003;\ - mov r0, r0 - - -/* - * Save the current IRQ state and disable IRQs - * Note that this macro assumes FIQs are enabled, and - * that the processor is in SVC mode. - */ - .macro save_and_disable_irqs, oldcpsr, temp - mov \oldcpsr, pc - orr \temp, \oldcpsr, #0x08000000 - teqp \temp, #0 - .endm - -/* - * Restore interrupt state previously stored in - * a register - * ** Actually do nothing on Arc - hope that the caller uses a MOVS PC soon - * after! - */ - .macro restore_irqs, oldcpsr - @ This be restore_irqs - .endm - -/* - * These two are used to save LR/restore PC over a user-based access. - * The old 26-bit architecture requires that we do. On 32-bit - * architecture, we can safely ignore this requirement. - */ - .macro save_lr - str lr, [sp, #-4]! - .endm - - .macro restore_pc - ldmfd sp!, {pc}^ - .endm - -#define USER(x...) \ -9999: x; \ - .section __ex_table,"a"; \ - .align 3; \ - .long 9999b,9001f; \ - .previous - - diff -Nru a/include/asm-arm/proc-armo/cache.h b/include/asm-arm/proc-armo/cache.h --- a/include/asm-arm/proc-armo/cache.h Thu Sep 4 15:38:30 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,28 +0,0 @@ -/* - * linux/include/asm-arm/proc-armo/cache.h - * - * Copyright (C) 1999-2001 Russell King - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * Cache handling for 26-bit ARM processors. - */ -#define flush_cache_all() do { } while (0) -#define flush_cache_mm(mm) do { } while (0) -#define flush_cache_range(vma,start,end) do { } while (0) -#define flush_cache_page(vma,vmaddr) do { } while (0) - -#define invalidate_dcache_range(start,end) do { } while (0) -#define clean_dcache_range(start,end) do { } while (0) -#define flush_dcache_range(start,end) do { } while (0) -#define flush_dcache_page(page) do { } while (0) -#define clean_dcache_entry(_s) do { } while (0) -#define clean_cache_entry(_start) do { } while (0) - -#define flush_icache_range(start,end) do { } while (0) -#define flush_icache_page(vma,page) do { } while (0) - -/* DAG: ARM3 will flush cache on MEMC updates anyway? so don't bother */ -#define clean_cache_area(_start,_size) do { } while (0) diff -Nru a/include/asm-arm/proc-armo/elf.h b/include/asm-arm/proc-armo/elf.h --- a/include/asm-arm/proc-armo/elf.h Thu Sep 4 15:38:28 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,15 +0,0 @@ -/* - * ELF definitions for 26-bit CPUs - */ - -#define ELF_EXEC_PAGESIZE 32768 - -#ifdef __KERNEL__ - -/* We can only execute 26-bit code. */ -#define ELF_PROC_OK(x) \ - ((x)->e_flags & EF_ARM_APCS26) - -#define SET_PERSONALITY(ex,ibcs2) set_personality(PER_LINUX) - -#endif diff -Nru a/include/asm-arm/proc-armo/locks.h b/include/asm-arm/proc-armo/locks.h --- a/include/asm-arm/proc-armo/locks.h Thu Sep 4 15:38:33 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,161 +0,0 @@ -/* - * linux/include/asm-arm/proc-armo/locks.h - * - * Copyright (C) 2000 Russell King - * Fixes for 26 bit machines, (C) 2000 Dave Gilbert - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * Interrupt safe locking assembler. - */ -#ifndef __ASM_PROC_LOCKS_H -#define __ASM_PROC_LOCKS_H - -/* Decrements by 1, fails if value < 0 */ -#define __down_op(ptr,fail) \ - ({ \ - __asm__ __volatile__ ( \ - "@ atomic down operation\n" \ -" mov ip, pc\n" \ -" orr lr, ip, #0x08000000\n" \ -" teqp lr, #0\n" \ -" ldr lr, [%0]\n" \ -" and ip, ip, #0x0c000003\n" \ -" subs lr, lr, #1\n" \ -" str lr, [%0]\n" \ -" orrmi ip, ip, #0x80000000 @ set N\n" \ -" teqp ip, #0\n" \ -" movmi ip, %0\n" \ -" blmi " #fail \ - : \ - : "r" (ptr) \ - : "ip", "lr", "cc"); \ - }) - -#define __down_op_ret(ptr,fail) \ - ({ \ - unsigned int result; \ - __asm__ __volatile__ ( \ -" @ down_op_ret\n" \ -" mov ip, pc\n" \ -" orr lr, ip, #0x08000000\n" \ -" teqp lr, #0\n" \ -" ldr lr, [%1]\n" \ -" and ip, ip, #0x0c000003\n" \ -" subs lr, lr, #1\n" \ -" str lr, [%1]\n" \ -" orrmi ip, ip, #0x80000000 @ set N\n" \ -" teqp ip, #0\n" \ -" movmi ip, %1\n" \ -" movpl ip, #0\n" \ -" blmi " #fail "\n" \ -" mov %0, ip" \ - : "=&r" (result) \ - : "r" (ptr) \ - : "ip", "lr", "cc"); \ - result; \ - }) - -#define __up_op(ptr,wake) \ - ({ \ - __asm__ __volatile__ ( \ - "@ up_op\n" \ -" mov ip, pc\n" \ -" orr lr, ip, #0x08000000\n" \ -" teqp lr, #0\n" \ -" ldr lr, [%0]\n" \ -" and ip, ip, #0x0c000003\n" \ -" adds lr, lr, #1\n" \ -" str lr, [%0]\n" \ -" orrle ip, ip, #0x80000000 @ set N - should this be mi ??? DAG ! \n" \ -" teqp ip, #0\n" \ -" movmi ip, %0\n" \ -" blmi " #wake \ - : \ - : "r" (ptr) \ - : "ip", "lr", "cc"); \ - }) - -/* - * The value 0x01000000 supports up to 128 processors and - * lots of processes. BIAS must be chosen such that sub'ing - * BIAS once per CPU will result in the long remaining - * negative. - */ -#define RW_LOCK_BIAS 0x01000000 -#define RW_LOCK_BIAS_STR "0x01000000" - -/* Decrements by RW_LOCK_BIAS rather than 1, fails if value != 0 */ -#define __down_op_write(ptr,fail) \ - ({ \ - __asm__ __volatile__( \ - "@ down_op_write\n" \ -" mov ip, pc\n" \ -" orr lr, ip, #0x08000000\n" \ -" teqp lr, #0\n" \ -" and ip, ip, #0x0c000003\n" \ -\ -" ldr lr, [%0]\n" \ -" subs lr, lr, %1\n" \ -" str lr, [%0]\n" \ -\ -" orreq ip, ip, #0x40000000 @ set Z \n"\ -" teqp ip, #0\n" \ -" movne ip, %0\n" \ -" blne " #fail \ - : \ - : "r" (ptr), "I" (RW_LOCK_BIAS) \ - : "ip", "lr", "cc"); \ - }) - -/* Increments by RW_LOCK_BIAS, wakes if value >= 0 */ -#define __up_op_write(ptr,wake) \ - ({ \ - __asm__ __volatile__( \ - "@ up_op_read\n" \ -" mov ip, pc\n" \ -" orr lr, ip, #0x08000000\n" \ -" teqp lr, #0\n" \ -\ -" ldr lr, [%0]\n" \ -" and ip, ip, #0x0c000003\n" \ -" adds lr, lr, %1\n" \ -" str lr, [%0]\n" \ -\ -" orrcs ip, ip, #0x20000000 @ set C\n" \ -" teqp ip, #0\n" \ -" movcs ip, %0\n" \ -" blcs " #wake \ - : \ - : "r" (ptr), "I" (RW_LOCK_BIAS) \ - : "ip", "lr", "cc"); \ - }) - -#define __down_op_read(ptr,fail) \ - __down_op(ptr, fail) - -#define __up_op_read(ptr,wake) \ - ({ \ - __asm__ __volatile__( \ - "@ up_op_read\n" \ -" mov ip, pc\n" \ -" orr lr, ip, #0x08000000\n" \ -" teqp lr, #0\n" \ -\ -" ldr lr, [%0]\n" \ -" and ip, ip, #0x0c000003\n" \ -" adds lr, lr, %1\n" \ -" str lr, [%0]\n" \ -\ -" orreq ip, ip, #0x40000000 @ Set Z \n" \ -" teqp ip, #0\n" \ -" moveq ip, %0\n" \ -" bleq " #wake \ - : \ - : "r" (ptr), "I" (1) \ - : "ip", "lr", "cc"); \ - }) - -#endif diff -Nru a/include/asm-arm/proc-armo/page.h b/include/asm-arm/proc-armo/page.h --- a/include/asm-arm/proc-armo/page.h Thu Sep 4 15:38:31 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,40 +0,0 @@ -/* - * linux/include/asm-arm/proc-armo/page.h - * - * Copyright (C) 1995-2002 Russell King - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#ifndef __ASM_PROC_PAGE_H -#define __ASM_PROC_PAGE_H - -#include - -/* PAGE_SHIFT determines the page size. This is configurable. */ -#if defined(CONFIG_PAGESIZE_16) -#define PAGE_SHIFT 14 /* 16K */ -#else /* default */ -#define PAGE_SHIFT 15 /* 32K */ -#endif - -#define EXEC_PAGESIZE 32768 - -#ifndef __ASSEMBLY__ -#ifdef STRICT_MM_TYPECHECKS - -typedef struct { unsigned long pgd; } pgd_t; - -#define pgd_val(x) ((x).pgd) - -#else - -typedef unsigned long pgd_t; - -#define pgd_val(x) (x) - -#endif -#endif /* __ASSEMBLY__ */ - -#endif /* __ASM_PROC_PAGE_H */ diff -Nru a/include/asm-arm/proc-armo/pgalloc.h b/include/asm-arm/proc-armo/pgalloc.h --- a/include/asm-arm/proc-armo/pgalloc.h Thu Sep 4 15:38:42 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,44 +0,0 @@ -/* - * linux/include/asm-arm/proc-armo/pgalloc.h - * - * Copyright (C) 2001-2002 Russell King - * - * Page table allocation/freeing primitives for 26-bit ARM processors. - */ - -#include - -extern kmem_cache_t *pte_cache; - -static inline pte_t * -pte_alloc_one_kernel(struct mm_struct *mm, unsigned long addr) -{ - return kmem_cache_alloc(pte_cache, GFP_KERNEL); -} - -static inline void pte_free_kernel(pte_t *pte) -{ - if (pte) - kmem_cache_free(pte_cache, pte); -} - -/* - * Populate the pmdp entry with a pointer to the pte. This pmd is part - * of the mm address space. - * - * If 'mm' is the init tasks mm, then we are doing a vmalloc, and we - * need to set stuff up correctly for it. - */ -static inline void -pmd_populate_kernel(struct mm_struct *mm, pmd_t *pmdp, pte_t *ptep) -{ - set_pmd(pmdp, __mk_pmd(ptep, _PAGE_TABLE)); -} - -/* - * We use the old 2.5.5-rmk1 hack for this. - * This is not truly correct, but should be functional. - */ -#define pte_alloc_one(mm,addr) ((struct page *)pte_alloc_one_kernel(mm,addr)) -#define pte_free(pte) pte_free_kernel((pte_t *)pte) -#define pmd_populate(mm,pmdp,ptep) pmd_populate_kernel(mm,pmdp,(pte_t *)ptep) diff -Nru a/include/asm-arm/proc-armo/pgtable.h b/include/asm-arm/proc-armo/pgtable.h --- a/include/asm-arm/proc-armo/pgtable.h Thu Sep 4 15:38:31 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,106 +0,0 @@ -/* - * linux/include/asm-arm/proc-armo/pgtable.h - * - * Copyright (C) 1995-2002 Russell King - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * 18-Oct-1997 RMK Now two-level (32x32) - */ -#ifndef __ASM_PROC_PGTABLE_H -#define __ASM_PROC_PGTABLE_H - -/* - * entries per page directory level: they are two-level, so - * we don't really have any PMD directory. - */ -#define PTRS_PER_PTE 32 -#define PTRS_PER_PMD 1 -#define PTRS_PER_PGD 32 - -/* - * The vmalloc() routines leaves a hole of 4kB between each vmalloced - * area for the same reason. ;) - */ -#define VMALLOC_START 0x01a00000 -#define VMALLOC_VMADDR(x) ((unsigned long)(x)) -#define VMALLOC_END 0x01c00000 - -#define _PAGE_TABLE (0x01) - -#define pmd_bad(pmd) ((pmd_val(pmd) & 0xfc000002)) -#define set_pmd(pmdp,pmd) ((*(pmdp)) = (pmd)) -#define pmd_clear(pmdp) set_pmd(pmdp, __pmd(0)) - -static inline pmd_t __mk_pmd(pte_t *ptep, unsigned long prot) -{ - unsigned long pte_ptr = (unsigned long)ptep; - pmd_t pmd; - - pmd_val(pmd) = __virt_to_phys(pte_ptr) | prot; - - return pmd; -} - -static inline unsigned long pmd_page(pmd_t pmd) -{ - return __phys_to_virt(pmd_val(pmd) & ~_PAGE_TABLE); -} - -#define pte_offset_kernel(dir,addr) (pmd_page_kernel(*(dir)) + __pte_index(addr)) -#define pte_offset_map(dir,addr) (pmd_page_kernel(*(dir)) + __pte_index(addr)) -#define pte_offset_map_nested(dir,addr) (pmd_page_kernel(*(dir)) + __pte_index(addr)) -#define pte_unmap(pte) do { } while (0) -#define pte_unmap_nested(pte) do { } while (0) - -#define set_pte(pteptr, pteval) ((*(pteptr)) = (pteval)) - -#define _PAGE_PRESENT 0x01 -#define _PAGE_READONLY 0x02 -#define _PAGE_NOT_USER 0x04 -#define _PAGE_OLD 0x08 -#define _PAGE_CLEAN 0x10 - -/* -- present -- -- !dirty -- --- !write --- ---- !user --- */ -#define PAGE_NONE __pgprot(_PAGE_PRESENT | _PAGE_CLEAN | _PAGE_READONLY | _PAGE_NOT_USER) -#define PAGE_SHARED __pgprot(_PAGE_PRESENT | _PAGE_CLEAN ) -#define PAGE_COPY __pgprot(_PAGE_PRESENT | _PAGE_CLEAN | _PAGE_READONLY ) -#define PAGE_READONLY __pgprot(_PAGE_PRESENT | _PAGE_CLEAN | _PAGE_READONLY ) -#define PAGE_KERNEL __pgprot(_PAGE_PRESENT | _PAGE_NOT_USER) - -#define _PAGE_CHG_MASK (PAGE_MASK | _PAGE_OLD | _PAGE_CLEAN) - - -/* - * The following only work if pte_present() is true. - * Undefined behaviour if not.. - */ -#define pte_present(pte) (pte_val(pte) & _PAGE_PRESENT) -#define pte_read(pte) (!(pte_val(pte) & _PAGE_NOT_USER)) -#define pte_write(pte) (!(pte_val(pte) & _PAGE_READONLY)) -#define pte_exec(pte) (!(pte_val(pte) & _PAGE_NOT_USER)) -#define pte_dirty(pte) (!(pte_val(pte) & _PAGE_CLEAN)) -#define pte_young(pte) (!(pte_val(pte) & _PAGE_OLD)) - -static inline pte_t pte_wrprotect(pte_t pte) { pte_val(pte) |= _PAGE_READONLY; return pte; } -static inline pte_t pte_rdprotect(pte_t pte) { pte_val(pte) |= _PAGE_NOT_USER; return pte; } -static inline pte_t pte_exprotect(pte_t pte) { pte_val(pte) |= _PAGE_NOT_USER; return pte; } -static inline pte_t pte_mkclean(pte_t pte) { pte_val(pte) |= _PAGE_CLEAN; return pte; } -static inline pte_t pte_mkold(pte_t pte) { pte_val(pte) |= _PAGE_OLD; return pte; } - -static inline pte_t pte_mkwrite(pte_t pte) { pte_val(pte) &= ~_PAGE_READONLY; return pte; } -static inline pte_t pte_mkread(pte_t pte) { pte_val(pte) &= ~_PAGE_NOT_USER; return pte; } -static inline pte_t pte_mkexec(pte_t pte) { pte_val(pte) &= ~_PAGE_NOT_USER; return pte; } -static inline pte_t pte_mkdirty(pte_t pte) { pte_val(pte) &= ~_PAGE_CLEAN; return pte; } -static inline pte_t pte_mkyoung(pte_t pte) { pte_val(pte) &= ~_PAGE_OLD; return pte; } - -/* - * We don't store cache state bits in the page table here. - */ -#define pgprot_noncached(prot) (prot) - -extern void pgtable_cache_init(void); - -#endif /* __ASM_PROC_PGTABLE_H */ 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 Thu Sep 4 15:38:30 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,63 +0,0 @@ -/* - * linux/include/asm-arm/proc-armo/processor.h - * - * Copyright (C) 1996 Russell King. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * Changelog: - * 27-06-1996 RMK Created - * 10-10-1996 RMK Brought up to date with SA110 - * 26-09-1996 RMK Added 'EXTRA_THREAD_STRUCT*' - * 28-09-1996 RMK Moved start_thread into the processor dependencies - * 11-01-1998 RMK Added new uaccess_t - * 09-09-1998 PJB Delete redundant `wp_works_ok' - * 30-05-1999 PJB Save sl across context switches - */ -#ifndef __ASM_PROC_PROCESSOR_H -#define __ASM_PROC_PROCESSOR_H - -#include - -#define KERNEL_STACK_SIZE 4096 - -typedef struct { - void (*put_byte)(void); /* Special calling convention */ - void (*get_byte)(void); /* Special calling convention */ - void (*put_half)(void); /* Special calling convention */ - void (*get_half)(void); /* Special calling convention */ - void (*put_word)(void); /* Special calling convention */ - void (*get_word)(void); /* Special calling convention */ - unsigned long (*copy_from_user)(void *to, const void *from, unsigned long sz); - unsigned long (*copy_to_user)(void *to, const void *from, unsigned long sz); - unsigned long (*clear_user)(void *addr, unsigned long sz); - unsigned long (*strncpy_from_user)(char *to, const char *from, unsigned long sz); - unsigned long (*strnlen_user)(const char *s, long n); -} uaccess_t; - -extern uaccess_t uaccess_user, uaccess_kernel; - -#define EXTRA_THREAD_STRUCT \ - uaccess_t *uaccess; /* User access functions*/ - -#define EXTRA_THREAD_STRUCT_INIT \ - uaccess: &uaccess_kernel, - -#define start_thread(regs,pc,sp) \ -({ \ - unsigned long *stack = (unsigned long *)sp; \ - set_fs(USER_DS); \ - memzero(regs->uregs, sizeof (regs->uregs)); \ - regs->ARM_pc = pc; /* pc */ \ - regs->ARM_sp = sp; /* sp */ \ - regs->ARM_r2 = stack[2]; /* r2 (envp) */ \ - regs->ARM_r1 = stack[1]; /* r1 (argv) */ \ - regs->ARM_r0 = stack[0]; /* r0 (argc) */ \ -}) - -#define KSTK_EIP(tsk) (((unsigned long *)(4096+(unsigned long)(tsk)))[1020]) -#define KSTK_ESP(tsk) (((unsigned long *)(4096+(unsigned long)(tsk)))[1018]) - -#endif diff -Nru a/include/asm-arm/proc-armo/ptrace.h b/include/asm-arm/proc-armo/ptrace.h --- a/include/asm-arm/proc-armo/ptrace.h Thu Sep 4 15:38:32 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,98 +0,0 @@ -/* - * linux/include/asm-arm/proc-armo/ptrace.h - * - * Copyright (C) 1996-2001 Russell King - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#ifndef __ASM_PROC_PTRACE_H -#define __ASM_PROC_PTRACE_H - -#define USR26_MODE 0x00000000 -#define FIQ26_MODE 0x00000001 -#define IRQ26_MODE 0x00000002 -#define SVC26_MODE 0x00000003 -#define USR_MODE USR26_MODE -#define FIQ_MODE FIQ26_MODE -#define IRQ_MODE IRQ26_MODE -#define SVC_MODE SVC26_MODE -#define MODE_MASK 0x00000003 -#define PSR_F_BIT 0x04000000 -#define PSR_I_BIT 0x08000000 -#define PSR_V_BIT 0x10000000 -#define PSR_C_BIT 0x20000000 -#define PSR_Z_BIT 0x40000000 -#define PSR_N_BIT 0x80000000 -#define PCMASK 0xfc000003 - -#ifndef __ASSEMBLY__ - -/* this struct defines the way the registers are stored on the - stack during a system call. */ - -struct pt_regs { - long uregs[17]; -}; - -#define ARM_pc uregs[15] -#define ARM_lr uregs[14] -#define ARM_sp uregs[13] -#define ARM_ip uregs[12] -#define ARM_fp uregs[11] -#define ARM_r10 uregs[10] -#define ARM_r9 uregs[9] -#define ARM_r8 uregs[8] -#define ARM_r7 uregs[7] -#define ARM_r6 uregs[6] -#define ARM_r5 uregs[5] -#define ARM_r4 uregs[4] -#define ARM_r3 uregs[3] -#define ARM_r2 uregs[2] -#define ARM_r1 uregs[1] -#define ARM_r0 uregs[0] -#define ARM_ORIG_r0 uregs[16] - -#ifdef __KERNEL__ - -#define processor_mode(regs) \ - ((regs)->ARM_pc & MODE_MASK) - -#define user_mode(regs) \ - (processor_mode(regs) == USR26_MODE) - -#define thumb_mode(regs) (0) - -#define interrupts_enabled(regs) \ - (!((regs)->ARM_pc & PSR_I_BIT)) - -#define fast_interrupts_enabled(regs) \ - (!((regs)->ARM_pc & PSR_F_BIT)) - -#define condition_codes(regs) \ - ((regs)->ARM_pc & (PSR_V_BIT|PSR_C_BIT|PSR_Z_BIT|PSR_N_BIT)) - -/* Are the current registers suitable for user mode? - * (used to maintain security in signal handlers) - */ -static inline int valid_user_regs(struct pt_regs *regs) -{ - if (user_mode(regs) && - (regs->ARM_pc & (PSR_F_BIT | PSR_I_BIT)) == 0) - return 1; - - /* - * force it to be something sensible - */ - regs->ARM_pc &= ~(MODE_MASK | PSR_F_BIT | PSR_I_BIT); - - return 0; -} - -#endif /* __KERNEL__ */ - -#endif /* __ASSEMBLY__ */ - -#endif - diff -Nru a/include/asm-arm/proc-armo/shmparam.h b/include/asm-arm/proc-armo/shmparam.h --- a/include/asm-arm/proc-armo/shmparam.h Thu Sep 4 15:38:29 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,19 +0,0 @@ -/* - * linux/include/asm-arm/proc-armo/shmparam.h - * - * Copyright (C) 1996 Russell King - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * definitions for the shared process memory on the ARM3 - */ -#ifndef __ASM_PROC_SHMPARAM_H -#define __ASM_PROC_SHMPARAM_H - -#ifndef SHMMAX -#define SHMMAX 0x003fa000 -#endif - -#endif diff -Nru a/include/asm-arm/proc-armo/system.h b/include/asm-arm/proc-armo/system.h --- a/include/asm-arm/proc-armo/system.h Thu Sep 4 15:38:31 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,128 +0,0 @@ -/* - * linux/include/asm-arm/proc-armo/system.h - * - * Copyright (C) 1995, 1996 Russell King - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#ifndef __ASM_PROC_SYSTEM_H -#define __ASM_PROC_SYSTEM_H - -#define vectors_base() (0) - -static inline unsigned long __xchg(unsigned long x, volatile void *ptr, int size) -{ - extern void __bad_xchg(volatile void *, int); - - switch (size) { - case 1: return cpu_xchg_1(x, ptr); - case 4: return cpu_xchg_4(x, ptr); - default: __bad_xchg(ptr, size); - } - return 0; -} - -/* - * We need to turn the caches off before calling the reset vector - RiscOS - * messes up if we don't - */ -#define proc_hard_reset() cpu_proc_fin() - -/* - * A couple of speedups for the ARM - */ - -/* - * Save the current interrupt enable state & disable IRQs - */ -#define local_save_flags_cli(x) \ - do { \ - unsigned long temp; \ - __asm__ __volatile__( \ -" mov %0, pc @ save_flags_cli\n" \ -" orr %1, %0, #0x08000000\n" \ -" and %0, %0, #0x0c000000\n" \ -" teqp %1, #0\n" \ - : "=r" (x), "=r" (temp) \ - : \ - : "memory"); \ - } while (0) - -/* - * Enable IRQs - */ -#define local_irq_enable() \ - do { \ - unsigned long temp; \ - __asm__ __volatile__( \ -" mov %0, pc @ sti\n" \ -" bic %0, %0, #0x08000000\n" \ -" teqp %0, #0\n" \ - : "=r" (temp) \ - : \ - : "memory"); \ - } while(0) - -/* - * Disable IRQs - */ -#define local_irq_disable() \ - do { \ - unsigned long temp; \ - __asm__ __volatile__( \ -" mov %0, pc @ cli\n" \ -" orr %0, %0, #0x08000000\n" \ -" teqp %0, #0\n" \ - : "=r" (temp) \ - : \ - : "memory"); \ - } while(0) - -#define __clf() do { \ - unsigned long temp; \ - __asm__ __volatile__( \ -" mov %0, pc @ clf\n" \ -" orr %0, %0, #0x04000000\n" \ -" teqp %0, #0\n" \ - : "=r" (temp)); \ - } while(0) - -#define __stf() do { \ - unsigned long temp; \ - __asm__ __volatile__( \ -" mov %0, pc @ stf\n" \ -" bic %0, %0, #0x04000000\n" \ -" teqp %0, #0\n" \ - : "=r" (temp)); \ - } while(0) - -/* - * save current IRQ & FIQ state - */ -#define local_save_flags(x) \ - do { \ - __asm__ __volatile__( \ -" mov %0, pc @ save_flags\n" \ -" and %0, %0, #0x0c000000\n" \ - : "=r" (x)); \ - } while (0) - -/* - * restore saved IRQ & FIQ state - */ -#define local_irq_restore(x) \ - do { \ - unsigned long temp; \ - __asm__ __volatile__( \ -" mov %0, pc @ restore_flags\n" \ -" bic %0, %0, #0x0c000000\n" \ -" orr %0, %0, %1\n" \ -" teqp %0, #0\n" \ - : "=&r" (temp) \ - : "r" (x) \ - : "memory"); \ - } while (0) - -#endif diff -Nru a/include/asm-arm/proc-armo/tlbflush.h b/include/asm-arm/proc-armo/tlbflush.h --- a/include/asm-arm/proc-armo/tlbflush.h Thu Sep 4 15:38:37 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,63 +0,0 @@ -/* - * TLB flushing: - * - * - flush_tlb_all() flushes all processes TLBs - * - flush_tlb_mm(mm) flushes the specified mm context TLB's - * - flush_tlb_page(vma, vmaddr) flushes one page - * - flush_tlb_range(vma, start, end) flushes a range of pages - */ -#define flush_tlb_all() memc_update_all() -#define flush_tlb_mm(mm) memc_update_mm(mm) -#define flush_tlb_range(vma,start,end) \ - do { memc_update_mm(vma->vm_mm); (void)(start); (void)(end); } while (0) -#define flush_tlb_page(vma, vmaddr) do { } while (0) - -/* - * The following handle the weird MEMC chip - */ -static inline void memc_update_all(void) -{ - struct task_struct *p; - - cpu_memc_update_all(init_mm.pgd); - for_each_task(p) { - if (!p->mm) - continue; - cpu_memc_update_all(p->mm->pgd); - } - processor._set_pgd(current->active_mm->pgd); -} - -static inline void memc_update_mm(struct mm_struct *mm) -{ - cpu_memc_update_all(mm->pgd); - - if (mm == current->active_mm) - processor._set_pgd(mm->pgd); -} - -static inline void -memc_clear(struct mm_struct *mm, struct page *page) -{ - cpu_memc_update_entry(mm->pgd, (unsigned long) page_address(page), 0); - - if (mm == current->active_mm) - processor._set_pgd(mm->pgd); -} - -static inline void -memc_update_addr(struct mm_struct *mm, pte_t pte, unsigned long vaddr) -{ - cpu_memc_update_entry(mm->pgd, pte_val(pte), vaddr); - - if (mm == current->active_mm) - processor._set_pgd(mm->pgd); -} - -static inline void -update_mmu_cache(struct vm_area_struct *vma, unsigned long addr, pte_t pte) -{ - struct mm_struct *mm = vma->vm_mm; - memc_update_addr(mm, pte, addr); -} - diff -Nru a/include/asm-arm/proc-armo/uaccess.h b/include/asm-arm/proc-armo/uaccess.h --- a/include/asm-arm/proc-armo/uaccess.h Thu Sep 4 15:38:32 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,138 +0,0 @@ -/* - * linux/include/asm-arm/proc-armo/segment.h - * - * Copyright (C) 1996 Russell King - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -/* - * The fs functions are implemented on the ARM2 and ARM3 architectures - * manually. - * Use *_user functions to access user memory with faulting behaving - * as though the user is accessing the memory. - * Use set_fs(get_ds()) and then the *_user functions to allow them to - * access kernel memory. - */ - -/* - * These are the values used to represent the user `fs' and the kernel `ds' - */ -#define KERNEL_DS 0x03000000 -#define USER_DS 0x02000000 - -extern uaccess_t uaccess_user, uaccess_kernel; - -static inline void set_fs (mm_segment_t fs) -{ - current->addr_limit = fs; - current->thread.uaccess = fs == USER_DS ? &uaccess_user : &uaccess_kernel; -} - -#define __range_ok(addr,size) ({ \ - unsigned long flag, sum; \ - __asm__ __volatile__("subs %1, %0, %3; cmpcs %1, %2; movcs %0, #0" \ - : "=&r" (flag), "=&r" (sum) \ - : "r" (addr), "Ir" (size), "0" (current->addr_limit) \ - : "cc"); \ - flag; }) - -#define __addr_ok(addr) ({ \ - unsigned long flag; \ - __asm__ __volatile__("cmp %2, %0; movlo %0, #0" \ - : "=&r" (flag) \ - : "0" (current->addr_limit), "r" (addr) \ - : "cc"); \ - (flag == 0); }) - -#define __put_user_asm_byte(x,addr,err) \ - __asm__ __volatile__( \ - " mov r0, %1\n" \ - " mov r1, %2\n" \ - " mov r2, %0\n" \ - " mov lr, pc\n" \ - " mov pc, %3\n" \ - " mov %0, r2\n" \ - : "=r" (err) \ - : "r" (x), "r" (addr), "r" (current->thread.uaccess->put_byte), \ - "0" (err) \ - : "r0", "r1", "r2", "lr") - -#define __put_user_asm_half(x,addr,err) \ - __asm__ __volatile__( \ - " mov r0, %1\n" \ - " mov r1, %2\n" \ - " mov r2, %0\n" \ - " mov lr, pc\n" \ - " mov pc, %3\n" \ - " mov %0, r2\n" \ - : "=r" (err) \ - : "r" (x), "r" (addr), "r" (current->thread.uaccess->put_half), \ - "0" (err) \ - : "r0", "r1", "r2", "lr") - -#define __put_user_asm_word(x,addr,err) \ - __asm__ __volatile__( \ - " mov r0, %1\n" \ - " mov r1, %2\n" \ - " mov r2, %0\n" \ - " mov lr, pc\n" \ - " mov pc, %3\n" \ - " mov %0, r2\n" \ - : "=r" (err) \ - : "r" (x), "r" (addr), "r" (current->thread.uaccess->put_word), \ - "0" (err) \ - : "r0", "r1", "r2", "lr") - -#define __get_user_asm_byte(x,addr,err) \ - __asm__ __volatile__( \ - " mov r0, %2\n" \ - " mov r1, %0\n" \ - " mov lr, pc\n" \ - " mov pc, %3\n" \ - " mov %0, r1\n" \ - " mov %1, r0\n" \ - : "=r" (err), "=r" (x) \ - : "r" (addr), "r" (current->thread.uaccess->get_byte), "0" (err) \ - : "r0", "r1", "r2", "lr") - -#define __get_user_asm_half(x,addr,err) \ - __asm__ __volatile__( \ - " mov r0, %2\n" \ - " mov r1, %0\n" \ - " mov lr, pc\n" \ - " mov pc, %3\n" \ - " mov %0, r1\n" \ - " mov %1, r0\n" \ - : "=r" (err), "=r" (x) \ - : "r" (addr), "r" (current->thread.uaccess->get_half), "0" (err) \ - : "r0", "r1", "r2", "lr") - -#define __get_user_asm_word(x,addr,err) \ - __asm__ __volatile__( \ - " mov r0, %2\n" \ - " mov r1, %0\n" \ - " mov lr, pc\n" \ - " mov pc, %3\n" \ - " mov %0, r1\n" \ - " mov %1, r0\n" \ - : "=r" (err), "=r" (x) \ - : "r" (addr), "r" (current->thread.uaccess->get_word), "0" (err) \ - : "r0", "r1", "r2", "lr") - -#define __do_copy_from_user(to,from,n) \ - (n) = current->thread.uaccess->copy_from_user((to),(from),(n)) - -#define __do_copy_to_user(to,from,n) \ - (n) = current->thread.uaccess->copy_to_user((to),(from),(n)) - -#define __do_clear_user(addr,sz) \ - (sz) = current->thread.uaccess->clear_user((addr),(sz)) - -#define __do_strncpy_from_user(dst,src,count,res) \ - (res) = current->thread.uaccess->strncpy_from_user(dst,src,count) - -#define __do_strnlen_user(s,n,res) \ - (res) = current->thread.uaccess->strnlen_user(s,n) diff -Nru a/include/asm-arm/proc-armv/assembler.h b/include/asm-arm/proc-armv/assembler.h --- a/include/asm-arm/proc-armv/assembler.h Thu Sep 4 15:38:46 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,74 +0,0 @@ -/* - * linux/asm-arm/proc-armv/assembler.h - * - * Copyright (C) 1996-2000 Russell King - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * This file contains ARM processor specifics for - * the ARM6 and better processors. - */ -#define MODE_USR USR_MODE -#define MODE_FIQ FIQ_MODE -#define MODE_IRQ IRQ_MODE -#define MODE_SVC SVC_MODE - -#define DEFAULT_FIQ MODE_FIQ - -/* - * LOADREGS - ldm with PC in register list (eg, ldmfd sp!, {pc}) - */ -#ifdef __STDC__ -#define LOADREGS(cond, base, reglist...)\ - ldm##cond base,reglist -#else -#define LOADREGS(cond, base, reglist...)\ - ldm/**/cond base,reglist -#endif - -/* - * Build a return instruction for this processor type. - */ -#define RETINSTR(instr, regs...)\ - instr regs - -/* - * Save the current IRQ state and disable IRQs. Note that this macro - * assumes FIQs are enabled, and that the processor is in SVC mode. - */ - .macro save_and_disable_irqs, oldcpsr, temp - mrs \oldcpsr, cpsr - mov \temp, #PSR_I_BIT | MODE_SVC - msr cpsr_c, \temp - .endm - -/* - * Restore interrupt state previously stored in a register. We don't - * guarantee that this will preserve the flags. - */ - .macro restore_irqs, oldcpsr - msr cpsr_c, \oldcpsr - .endm - -/* - * These two are used to save LR/restore PC over a user-based access. - * The old 26-bit architecture requires that we do. On 32-bit - * architecture, we can safely ignore this requirement. - */ - .macro save_lr - .endm - - .macro restore_pc - mov pc, lr - .endm - -#define USER(x...) \ -9999: x; \ - .section __ex_table,"a"; \ - .align 3; \ - .long 9999b,9001f; \ - .previous - - diff -Nru a/include/asm-arm/proc-armv/cache.h b/include/asm-arm/proc-armv/cache.h --- a/include/asm-arm/proc-armv/cache.h Thu Sep 4 15:38:33 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,278 +0,0 @@ -/* - * linux/include/asm-arm/proc-armv/cache.h - * - * Copyright (C) 1999-2002 Russell King - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#include -#include - -/* - * Cache Model - * =========== - */ -#undef _CACHE -#undef MULTI_CACHE - -#if defined(CONFIG_CPU_ARM610) || defined(CONFIG_CPU_ARM710) -# ifdef _CACHE -# define MULTI_CACHE 1 -# else -# define _CACHE v3 -# endif -#endif - -#if defined(CONFIG_CPU_ARM720T) -# ifdef _CACHE -# define MULTI_CACHE 1 -# else -# define _CACHE v4 -# endif -#endif - -#if defined(CONFIG_CPU_ARM920T) || defined(CONFIG_CPU_ARM922T) || \ - defined(CONFIG_CPU_ARM1020) -# define MULTI_CACHE 1 -#endif - -#if defined(CONFIG_CPU_ARM926T) -# ifdef _CACHE -# define MULTI_CACHE 1 -# else -# define _CACHE arm926 -# endif -#endif - -#if defined(CONFIG_CPU_SA110) || defined(CONFIG_CPU_SA1100) -# ifdef _CACHE -# define MULTI_CACHE 1 -# else -# define _CACHE v4wb -# endif -#endif - -#if defined(CONFIG_CPU_XSCALE) -# ifdef _CACHE -# define MULTI_CACHE 1 -# else -# define _CACHE xscale -# endif -#endif - -#if !defined(_CACHE) && !defined(MULTI_CACHE) -#error Unknown cache maintainence model -#endif - -/* - * This flag is used to indicate that the page pointed to by a pte - * is dirty and requires cleaning before returning it to the user. - */ -#define PG_dcache_dirty PG_arch_1 - -/* - * MM Cache Management - * =================== - * - * The arch/arm/mm/cache-*.S and arch/arm/mm/proc-*.S files - * implement these methods. - * - * Start addresses are inclusive and end addresses are exclusive; - * start addresses should be rounded down, end addresses up. - * - * See linux/Documentation/cachetlb.txt for more information. - * Please note that the implementation of these, and the required - * effects are cache-type (VIVT/VIPT/PIPT) specific. - * - * flush_cache_kern_all() - * - * Unconditionally clean and invalidate the entire cache. - * - * flush_cache_user_mm(mm) - * - * Clean and invalidate all user space cache entries - * before a change of page tables. - * - * flush_cache_user_range(start, end, flags) - * - * Clean and invalidate a range of cache entries in the - * specified address space before a change of page tables. - * - start - user start address (inclusive, page aligned) - * - end - user end address (exclusive, page aligned) - * - flags - vma->vm_flags field - * - * coherent_kern_range(start, end) - * - * Ensure coherency between the Icache and the Dcache in the - * region described by start, end. If you have non-snooping - * Harvard caches, you need to implement this function. - * - start - virtual start address - * - end - virtual end address - * - * DMA Cache Coherency - * =================== - * - * dma_inv_range(start, end) - * - * Invalidate (discard) the specified virtual address range. - * May not write back any entries. If 'start' or 'end' - * are not cache line aligned, those lines must be written - * back. - * - start - virtual start address - * - end - virtual end address - * - * dma_clean_range(start, end) - * - * Clean (write back) the specified virtual address range. - * - start - virtual start address - * - end - virtual end address - * - * dma_flush_range(start, end) - * - * Clean and invalidate the specified virtual address range. - * - start - virtual start address - * - end - virtual end address - */ - -struct cpu_cache_fns { - void (*flush_kern_all)(void); - void (*flush_user_all)(void); - void (*flush_user_range)(unsigned long, unsigned long, unsigned int); - - void (*coherent_kern_range)(unsigned long, unsigned long); - void (*flush_kern_dcache_page)(void *); - - void (*dma_inv_range)(unsigned long, unsigned long); - void (*dma_clean_range)(unsigned long, unsigned long); - void (*dma_flush_range)(unsigned long, unsigned long); -}; - -/* - * Select the calling method - */ -#ifdef MULTI_CACHE - -extern struct cpu_cache_fns cpu_cache; - -#define __cpuc_flush_kern_all cpu_cache.flush_kern_all -#define __cpuc_flush_user_all cpu_cache.flush_user_all -#define __cpuc_flush_user_range cpu_cache.flush_user_range -#define __cpuc_coherent_kern_range cpu_cache.coherent_kern_range -#define __cpuc_flush_dcache_page cpu_cache.flush_kern_dcache_page - -/* - * These are private to the dma-mapping API. Do not use directly. - * Their sole purpose is to ensure that data held in the cache - * is visible to DMA, or data written by DMA to system memory is - * visible to the CPU. - */ -#define dmac_inv_range cpu_cache.dma_inv_range -#define dmac_clean_range cpu_cache.dma_clean_range -#define dmac_flush_range cpu_cache.dma_flush_range - -#else - -#define __cpuc_flush_kern_all __glue(_CACHE,_flush_kern_cache_all) -#define __cpuc_flush_user_all __glue(_CACHE,_flush_user_cache_all) -#define __cpuc_flush_user_range __glue(_CACHE,_flush_user_cache_range) -#define __cpuc_coherent_kern_range __glue(_CACHE,_coherent_kern_range) -#define __cpuc_flush_dcache_page __glue(_CACHE,_flush_kern_dcache_page) - -extern void __cpuc_flush_kern_all(void); -extern void __cpuc_flush_user_all(void); -extern void __cpuc_flush_user_range(unsigned long, unsigned long, unsigned int); -extern void __cpuc_coherent_kern_range(unsigned long, unsigned long); -extern void __cpuc_flush_dcache_page(void *); - -/* - * These are private to the dma-mapping API. Do not use directly. - * Their sole purpose is to ensure that data held in the cache - * is visible to DMA, or data written by DMA to system memory is - * visible to the CPU. - */ -#define dmac_inv_range __glue(_CACHE,_dma_inv_range) -#define dmac_clean_range __glue(_CACHE,_dma_clean_range) -#define dmac_flush_range __glue(_CACHE,_dma_flush_range) - -extern void dmac_inv_range(unsigned long, unsigned long); -extern void dmac_clean_range(unsigned long, unsigned long); -extern void dmac_flush_range(unsigned long, unsigned long); - -#endif - -/* - * Convert calls to our calling convention. - */ -#define flush_cache_all() __cpuc_flush_kern_all() - -static inline void flush_cache_mm(struct mm_struct *mm) -{ - if (current->active_mm == mm) - __cpuc_flush_user_all(); -} - -static inline void -flush_cache_range(struct vm_area_struct *vma, unsigned long start, unsigned long end) -{ - if (current->active_mm == vma->vm_mm) - __cpuc_flush_user_range(start & PAGE_MASK, PAGE_ALIGN(end), - vma->vm_flags); -} - -static inline void -flush_cache_page(struct vm_area_struct *vma, unsigned long user_addr) -{ - if (current->active_mm == vma->vm_mm) { - unsigned long addr = user_addr & PAGE_MASK; - __cpuc_flush_user_range(addr, addr + PAGE_SIZE, vma->vm_flags); - } -} - -/* - * Perform necessary cache operations to ensure that data previously - * stored within this range of addresses can be executed by the CPU. - */ -#define flush_icache_range(s,e) __cpuc_coherent_kern_range(s,e) - -/* - * Perform necessary cache operations to ensure that the TLB will - * see data written in the specified area. - */ -#define clean_dcache_area(start,size) cpu_dcache_clean_area(start, size) - -/* - * flush_dcache_page is used when the kernel has written to the page - * cache page at virtual address page->virtual. - * - * If this page isn't mapped (ie, page->mapping = NULL), or it has - * userspace mappings (page->mapping->i_mmap or page->mapping->i_mmap_shared) - * then we _must_ always clean + invalidate the dcache entries associated - * with the kernel mapping. - * - * Otherwise we can defer the operation, and clean the cache when we are - * about to change to user space. This is the same method as used on SPARC64. - * See update_mmu_cache for the user space part. - */ -#define mapping_mapped(map) (!list_empty(&(map)->i_mmap) || \ - !list_empty(&(map)->i_mmap_shared)) - -extern void __flush_dcache_page(struct page *); - -static inline void flush_dcache_page(struct page *page) -{ - if (page->mapping && !mapping_mapped(page->mapping)) - set_bit(PG_dcache_dirty, &page->flags); - else - __flush_dcache_page(page); -} - -#define flush_icache_user_range(vma,page,addr,len) \ - flush_dcache_page(page) - -/* - * We don't appear to need to do anything here. In fact, if we did, we'd - * duplicate cache flushing elsewhere performed by flush_dcache_page(). - */ -#define flush_icache_page(vma,page) do { } while (0) diff -Nru a/include/asm-arm/proc-armv/domain.h b/include/asm-arm/proc-armv/domain.h --- a/include/asm-arm/proc-armv/domain.h Thu Sep 4 15:38:41 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,50 +0,0 @@ -/* - * linux/include/asm-arm/proc-armv/domain.h - * - * Copyright (C) 1999 Russell King. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#ifndef __ASM_PROC_DOMAIN_H -#define __ASM_PROC_DOMAIN_H - -/* - * Domain numbers - * - * DOMAIN_IO - domain 2 includes all IO only - * DOMAIN_KERNEL - domain 1 includes all kernel memory only - * DOMAIN_USER - domain 0 includes all user memory only - */ -#define DOMAIN_USER 0 -#define DOMAIN_KERNEL 1 -#define DOMAIN_TABLE 1 -#define DOMAIN_IO 2 - -/* - * Domain types - */ -#define DOMAIN_NOACCESS 0 -#define DOMAIN_CLIENT 1 -#define DOMAIN_MANAGER 3 - -#define domain_val(dom,type) ((type) << 2*(dom)) - -#define set_domain(x) \ - do { \ - __asm__ __volatile__( \ - "mcr p15, 0, %0, c3, c0 @ set domain" \ - : : "r" (x)); \ - } while (0) - -#define modify_domain(dom,type) \ - do { \ - struct thread_info *thread = current_thread_info(); \ - unsigned int domain = thread->cpu_domain; \ - domain &= ~domain_val(dom, DOMAIN_MANAGER); \ - thread->cpu_domain = domain | domain_val(dom, type); \ - set_domain(thread->cpu_domain); \ - } while (0) - -#endif diff -Nru a/include/asm-arm/proc-armv/elf.h b/include/asm-arm/proc-armv/elf.h --- a/include/asm-arm/proc-armv/elf.h Thu Sep 4 15:38:40 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,30 +0,0 @@ -/* - * ELF definitions for 32-bit CPUs - */ - -#define ELF_EXEC_PAGESIZE 4096 - -#ifdef __KERNEL__ - -/* - * 32-bit code is always OK. Some cpus can do 26-bit, some can't. - */ -#define ELF_PROC_OK(x) (ELF_THUMB_OK(x) && ELF_26BIT_OK(x)) - -#define ELF_THUMB_OK(x) \ - (( (elf_hwcap & HWCAP_THUMB) && ((x)->e_entry & 1) == 1) || \ - ((x)->e_entry & 3) == 0) - -#define ELF_26BIT_OK(x) \ - (( (elf_hwcap & HWCAP_26BIT) && (x)->e_flags & EF_ARM_APCS26) || \ - ((x)->e_flags & EF_ARM_APCS26) == 0) - -/* Old NetWinder binaries were compiled in such a way that the iBCS - heuristic always trips on them. Until these binaries become uncommon - enough not to care, don't trust the `ibcs' flag here. In any case - there is no other ELF system currently supported by iBCS. - @@ Could print a warning message to encourage users to upgrade. */ -#define SET_PERSONALITY(ex,ibcs2) \ - set_personality(((ex).e_flags&EF_ARM_APCS26 ?PER_LINUX :PER_LINUX_32BIT)) - -#endif diff -Nru a/include/asm-arm/proc-armv/locks.h b/include/asm-arm/proc-armv/locks.h --- a/include/asm-arm/proc-armv/locks.h Thu Sep 4 15:38:45 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,139 +0,0 @@ -/* - * linux/include/asm-arm/proc-armv/locks.h - * - * Copyright (C) 2000 Russell King - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * Interrupt safe locking assembler. - */ -#ifndef __ASM_PROC_LOCKS_H -#define __ASM_PROC_LOCKS_H - -#define __down_op(ptr,fail) \ - ({ \ - __asm__ __volatile__( \ - "@ down_op\n" \ -" mrs ip, cpsr\n" \ -" orr lr, ip, #128\n" \ -" msr cpsr_c, lr\n" \ -" ldr lr, [%0]\n" \ -" subs lr, lr, %1\n" \ -" str lr, [%0]\n" \ -" msr cpsr_c, ip\n" \ -" movmi ip, %0\n" \ -" blmi " #fail \ - : \ - : "r" (ptr), "I" (1) \ - : "ip", "lr", "cc", "memory"); \ - }) - -#define __down_op_ret(ptr,fail) \ - ({ \ - unsigned int ret; \ - __asm__ __volatile__( \ - "@ down_op_ret\n" \ -" mrs ip, cpsr\n" \ -" orr lr, ip, #128\n" \ -" msr cpsr_c, lr\n" \ -" ldr lr, [%1]\n" \ -" subs lr, lr, %2\n" \ -" str lr, [%1]\n" \ -" msr cpsr_c, ip\n" \ -" movmi ip, %1\n" \ -" movpl ip, #0\n" \ -" blmi " #fail "\n" \ -" mov %0, ip" \ - : "=&r" (ret) \ - : "r" (ptr), "I" (1) \ - : "ip", "lr", "cc", "memory"); \ - ret; \ - }) - -#define __up_op(ptr,wake) \ - ({ \ - __asm__ __volatile__( \ - "@ up_op\n" \ -" mrs ip, cpsr\n" \ -" orr lr, ip, #128\n" \ -" msr cpsr_c, lr\n" \ -" ldr lr, [%0]\n" \ -" adds lr, lr, %1\n" \ -" str lr, [%0]\n" \ -" msr cpsr_c, ip\n" \ -" movle ip, %0\n" \ -" blle " #wake \ - : \ - : "r" (ptr), "I" (1) \ - : "ip", "lr", "cc", "memory"); \ - }) - -/* - * The value 0x01000000 supports up to 128 processors and - * lots of processes. BIAS must be chosen such that sub'ing - * BIAS once per CPU will result in the long remaining - * negative. - */ -#define RW_LOCK_BIAS 0x01000000 -#define RW_LOCK_BIAS_STR "0x01000000" - -#define __down_op_write(ptr,fail) \ - ({ \ - __asm__ __volatile__( \ - "@ down_op_write\n" \ -" mrs ip, cpsr\n" \ -" orr lr, ip, #128\n" \ -" msr cpsr_c, lr\n" \ -" ldr lr, [%0]\n" \ -" subs lr, lr, %1\n" \ -" str lr, [%0]\n" \ -" msr cpsr_c, ip\n" \ -" movne ip, %0\n" \ -" blne " #fail \ - : \ - : "r" (ptr), "I" (RW_LOCK_BIAS) \ - : "ip", "lr", "cc", "memory"); \ - }) - -#define __up_op_write(ptr,wake) \ - ({ \ - __asm__ __volatile__( \ - "@ up_op_read\n" \ -" mrs ip, cpsr\n" \ -" orr lr, ip, #128\n" \ -" msr cpsr_c, lr\n" \ -" ldr lr, [%0]\n" \ -" adds lr, lr, %1\n" \ -" str lr, [%0]\n" \ -" msr cpsr_c, ip\n" \ -" movcs ip, %0\n" \ -" blcs " #wake \ - : \ - : "r" (ptr), "I" (RW_LOCK_BIAS) \ - : "ip", "lr", "cc", "memory"); \ - }) - -#define __down_op_read(ptr,fail) \ - __down_op(ptr, fail) - -#define __up_op_read(ptr,wake) \ - ({ \ - __asm__ __volatile__( \ - "@ up_op_read\n" \ -" mrs ip, cpsr\n" \ -" orr lr, ip, #128\n" \ -" msr cpsr_c, lr\n" \ -" ldr lr, [%0]\n" \ -" adds lr, lr, %1\n" \ -" str lr, [%0]\n" \ -" msr cpsr_c, ip\n" \ -" moveq ip, %0\n" \ -" bleq " #wake \ - : \ - : "r" (ptr), "I" (1) \ - : "ip", "lr", "cc", "memory"); \ - }) - -#endif diff -Nru a/include/asm-arm/proc-armv/page.h b/include/asm-arm/proc-armv/page.h --- a/include/asm-arm/proc-armv/page.h Thu Sep 4 15:38:39 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,37 +0,0 @@ -/* - * linux/include/asm-arm/proc-armv/page.h - * - * Copyright (C) 1995-2002 Russell King - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#ifndef __ASM_PROC_PAGE_H -#define __ASM_PROC_PAGE_H - -/* PAGE_SHIFT determines the page size */ -#define PAGE_SHIFT 12 - -#define EXEC_PAGESIZE 4096 - -#ifndef __ASSEMBLY__ -#ifdef STRICT_MM_TYPECHECKS - -typedef struct { - unsigned long pgd0; - unsigned long pgd1; -} pgd_t; - -#define pgd_val(x) ((x).pgd0) - -#else - -typedef unsigned long pgd_t[2]; - -#define pgd_val(x) ((x)[0]) - -#endif -#endif /* __ASSEMBLY__ */ - -#endif /* __ASM_PROC_PAGE_H */ diff -Nru a/include/asm-arm/proc-armv/pgalloc.h b/include/asm-arm/proc-armv/pgalloc.h --- a/include/asm-arm/proc-armv/pgalloc.h Thu Sep 4 15:38:35 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,110 +0,0 @@ -/* - * linux/include/asm-arm/proc-armv/pgalloc.h - * - * Copyright (C) 2001-2002 Russell King - * - * Page table allocation/freeing primitives for 32-bit ARM processors. - */ -#include -#include -#include "pgtable.h" - -/* - * Allocate one PTE table. - * - * This actually allocates two hardware PTE tables, but we wrap this up - * into one table thus: - * - * +------------+ - * | h/w pt 0 | - * +------------+ - * | h/w pt 1 | - * +------------+ - * | Linux pt 0 | - * +------------+ - * | Linux pt 1 | - * +------------+ - */ -static inline pte_t * -pte_alloc_one_kernel(struct mm_struct *mm, unsigned long addr) -{ - pte_t *pte; - - pte = (pte_t *)__get_free_page(GFP_KERNEL|__GFP_REPEAT); - if (pte) { - clear_page(pte); - clean_dcache_area(pte, sizeof(pte_t) * PTRS_PER_PTE); - pte += PTRS_PER_PTE; - } - - return pte; -} - -static inline struct page * -pte_alloc_one(struct mm_struct *mm, unsigned long addr) -{ - struct page *pte; - - pte = alloc_pages(GFP_KERNEL|__GFP_REPEAT, 0); - if (pte) { - void *page = page_address(pte); - clear_page(page); - clean_dcache_area(page, sizeof(pte_t) * PTRS_PER_PTE); - } - - return pte; -} - -/* - * Free one PTE table. - */ -static inline void pte_free_kernel(pte_t *pte) -{ - if (pte) { - pte -= PTRS_PER_PTE; - free_page((unsigned long)pte); - } -} - -static inline void pte_free(struct page *pte) -{ - __free_page(pte); -} - -/* - * Populate the pmdp entry with a pointer to the pte. This pmd is part - * of the mm address space. - * - * Ensure that we always set both PMD entries. - */ -static inline void -pmd_populate_kernel(struct mm_struct *mm, pmd_t *pmdp, pte_t *ptep) -{ - unsigned long pte_ptr = (unsigned long)ptep; - unsigned long pmdval; - - BUG_ON(mm != &init_mm); - - /* - * The pmd must be loaded with the physical - * address of the PTE table - */ - pte_ptr -= PTRS_PER_PTE * sizeof(void *); - pmdval = __pa(pte_ptr) | _PAGE_KERNEL_TABLE; - pmdp[0] = __pmd(pmdval); - pmdp[1] = __pmd(pmdval + 256 * sizeof(pte_t)); - flush_pmd_entry(pmdp); -} - -static inline void -pmd_populate(struct mm_struct *mm, pmd_t *pmdp, struct page *ptep) -{ - unsigned long pmdval; - - BUG_ON(mm == &init_mm); - - pmdval = page_to_pfn(ptep) << PAGE_SHIFT | _PAGE_USER_TABLE; - pmdp[0] = __pmd(pmdval); - pmdp[1] = __pmd(pmdval + 256 * sizeof(pte_t)); - flush_pmd_entry(pmdp); -} diff -Nru a/include/asm-arm/proc-armv/pgtable.h b/include/asm-arm/proc-armv/pgtable.h --- a/include/asm-arm/proc-armv/pgtable.h Thu Sep 4 15:38:29 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,217 +0,0 @@ -/* - * linux/include/asm-arm/proc-armv/pgtable.h - * - * Copyright (C) 1995-2002 Russell King - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * 12-Jan-1997 RMK Altered flushing routines to use function pointers - * now possible to combine ARM6, ARM7 and StrongARM versions. - * 17-Apr-1999 RMK Now pass an area size to clean_cache_area and - * flush_icache_area. - */ -#ifndef __ASM_PROC_PGTABLE_H -#define __ASM_PROC_PGTABLE_H - -/* - * We pull a couple of tricks here: - * 1. We wrap the PMD into the PGD. - * 2. We lie about the size of the PTE and PGD. - * Even though we have 256 PTE entries and 4096 PGD entries, we tell - * Linux that we actually have 512 PTE entries and 2048 PGD entries. - * Each "Linux" PGD entry is made up of two hardware PGD entries, and - * each PTE table is actually two hardware PTE tables. - */ -#define PTRS_PER_PTE 512 -#define PTRS_PER_PMD 1 -#define PTRS_PER_PGD 2048 - -/* - * Hardware page table definitions. - * - * + Level 1 descriptor (PMD) - * - common - */ -#define PMD_TYPE_MASK (3 << 0) -#define PMD_TYPE_FAULT (0 << 0) -#define PMD_TYPE_TABLE (1 << 0) -#define PMD_TYPE_SECT (2 << 0) -#define PMD_BIT4 (1 << 4) -#define PMD_DOMAIN(x) ((x) << 5) -#define PMD_PROTECTION (1 << 9) /* v5 */ -/* - * - section - */ -#define PMD_SECT_BUFFERABLE (1 << 2) -#define PMD_SECT_CACHEABLE (1 << 3) -#define PMD_SECT_AP_WRITE (1 << 10) -#define PMD_SECT_AP_READ (1 << 11) -#define PMD_SECT_TEX(x) ((x) << 12) /* v5 */ -#define PMD_SECT_APX (1 << 15) /* v6 */ -#define PMD_SECT_S (1 << 16) /* v6 */ -#define PMD_SECT_nG (1 << 17) /* v6 */ - -#define PMD_SECT_UNCACHED (0) -#define PMD_SECT_BUFFERED (PMD_SECT_BUFFERABLE) -#define PMD_SECT_WT (PMD_SECT_CACHEABLE) -#define PMD_SECT_WB (PMD_SECT_CACHEABLE | PMD_SECT_BUFFERABLE) -#define PMD_SECT_MINICACHE (PMD_SECT_TEX(1) | PMD_SECT_CACHEABLE) -#define PMD_SECT_WBWA (PMD_SECT_TEX(1) | PMD_SECT_CACHEABLE | PMD_SECT_BUFFERABLE) - -/* - * - coarse table (not used) - */ - -/* - * + Level 2 descriptor (PTE) - * - common - */ -#define PTE_TYPE_MASK (3 << 0) -#define PTE_TYPE_FAULT (0 << 0) -#define PTE_TYPE_LARGE (1 << 0) -#define PTE_TYPE_SMALL (2 << 0) -#define PTE_TYPE_EXT (3 << 0) /* v5 */ -#define PTE_BUFFERABLE (1 << 2) -#define PTE_CACHEABLE (1 << 3) - -/* - * - extended small page/tiny page - */ -#define PTE_EXT_AP_UNO_SRO (0 << 4) -#define PTE_EXT_AP_UNO_SRW (1 << 4) -#define PTE_EXT_AP_URO_SRW (2 << 4) -#define PTE_EXT_AP_URW_SRW (3 << 4) -#define PTE_EXT_TEX(x) ((x) << 6) /* v5 */ - -/* - * - small page - */ -#define PTE_SMALL_AP_UNO_SRO (0x00 << 4) -#define PTE_SMALL_AP_UNO_SRW (0x55 << 4) -#define PTE_SMALL_AP_URO_SRW (0xaa << 4) -#define PTE_SMALL_AP_URW_SRW (0xff << 4) -#define PTE_AP_READ PTE_SMALL_AP_URO_SRW -#define PTE_AP_WRITE PTE_SMALL_AP_UNO_SRW - -/* - * "Linux" PTE definitions. - * - * We keep two sets of PTEs - the hardware and the linux version. - * This allows greater flexibility in the way we map the Linux bits - * onto the hardware tables, and allows us to have YOUNG and DIRTY - * bits. - * - * The PTE table pointer refers to the hardware entries; the "Linux" - * entries are stored 1024 bytes below. - */ -#define L_PTE_PRESENT (1 << 0) -#define L_PTE_FILE (1 << 1) /* only when !PRESENT */ -#define L_PTE_YOUNG (1 << 1) -#define L_PTE_BUFFERABLE (1 << 2) /* matches PTE */ -#define L_PTE_CACHEABLE (1 << 3) /* matches PTE */ -#define L_PTE_USER (1 << 4) -#define L_PTE_WRITE (1 << 5) -#define L_PTE_EXEC (1 << 6) -#define L_PTE_DIRTY (1 << 7) - -#ifndef __ASSEMBLY__ - -#include - -#define _PAGE_USER_TABLE (PMD_TYPE_TABLE | PMD_BIT4 | PMD_DOMAIN(DOMAIN_USER)) -#define _PAGE_KERNEL_TABLE (PMD_TYPE_TABLE | PMD_BIT4 | PMD_DOMAIN(DOMAIN_KERNEL)) - -#define pmd_bad(pmd) (pmd_val(pmd) & 2) - -#define set_pmd(pmdp,pmd) \ - do { \ - *pmdp = pmd; \ - flush_pmd_entry(pmdp); \ - } while (0) - -#define pmd_clear(pmdp) \ - do { \ - pmdp[0] = __pmd(0); \ - pmdp[1] = __pmd(0); \ - clean_pmd_entry(pmdp); \ - } while (0) - -static inline pte_t *pmd_page_kernel(pmd_t pmd) -{ - unsigned long ptr; - - ptr = pmd_val(pmd) & ~(PTRS_PER_PTE * sizeof(void *) - 1); - ptr += PTRS_PER_PTE * sizeof(void *); - - return __va(ptr); -} - -#define pmd_page(pmd) virt_to_page(__va(pmd_val(pmd))) - -#define pte_offset_kernel(dir,addr) (pmd_page_kernel(*(dir)) + __pte_index(addr)) -#define pte_offset_map(dir,addr) (pmd_page_kernel(*(dir)) + __pte_index(addr)) -#define pte_offset_map_nested(dir,addr) (pmd_page_kernel(*(dir)) + __pte_index(addr)) -#define pte_unmap(pte) do { } while (0) -#define pte_unmap_nested(pte) do { } while (0) - -#define set_pte(ptep, pte) cpu_set_pte(ptep,pte) - -/* - * The following macros handle the cache and bufferable bits... - */ -#define _L_PTE_DEFAULT L_PTE_PRESENT | L_PTE_YOUNG -#define _L_PTE_READ L_PTE_USER | L_PTE_EXEC | L_PTE_CACHEABLE | L_PTE_BUFFERABLE - -#define PAGE_NONE __pgprot(_L_PTE_DEFAULT) -#define PAGE_COPY __pgprot(_L_PTE_DEFAULT | _L_PTE_READ) -#define PAGE_SHARED __pgprot(_L_PTE_DEFAULT | _L_PTE_READ | L_PTE_WRITE) -#define PAGE_READONLY __pgprot(_L_PTE_DEFAULT | _L_PTE_READ) -#define PAGE_KERNEL __pgprot(_L_PTE_DEFAULT | L_PTE_CACHEABLE | L_PTE_BUFFERABLE | L_PTE_DIRTY | L_PTE_WRITE | L_PTE_EXEC) - -#define _PAGE_CHG_MASK (PAGE_MASK | L_PTE_DIRTY | L_PTE_YOUNG) - - -/* - * The following only work if pte_present() is true. - * Undefined behaviour if not.. - */ -#define pte_present(pte) (pte_val(pte) & L_PTE_PRESENT) -#define pte_read(pte) (pte_val(pte) & L_PTE_USER) -#define pte_write(pte) (pte_val(pte) & L_PTE_WRITE) -#define pte_exec(pte) (pte_val(pte) & L_PTE_EXEC) -#define pte_dirty(pte) (pte_val(pte) & L_PTE_DIRTY) -#define pte_young(pte) (pte_val(pte) & L_PTE_YOUNG) -#define pte_file(pte) (pte_val(pte) & L_PTE_FILE) - -#define PTE_BIT_FUNC(fn,op) \ -static inline pte_t pte_##fn(pte_t pte) { pte_val(pte) op; return pte; } - -/*PTE_BIT_FUNC(rdprotect, &= ~L_PTE_USER);*/ -/*PTE_BIT_FUNC(mkread, |= L_PTE_USER);*/ -PTE_BIT_FUNC(wrprotect, &= ~L_PTE_WRITE); -PTE_BIT_FUNC(mkwrite, |= L_PTE_WRITE); -PTE_BIT_FUNC(exprotect, &= ~L_PTE_EXEC); -PTE_BIT_FUNC(mkexec, |= L_PTE_EXEC); -PTE_BIT_FUNC(mkclean, &= ~L_PTE_DIRTY); -PTE_BIT_FUNC(mkdirty, |= L_PTE_DIRTY); -PTE_BIT_FUNC(mkold, &= ~L_PTE_YOUNG); -PTE_BIT_FUNC(mkyoung, |= L_PTE_YOUNG); - -/* - * Mark the prot value as uncacheable and unbufferable. - */ -#define pgprot_noncached(prot) __pgprot(pgprot_val(prot) & ~(L_PTE_CACHEABLE | L_PTE_BUFFERABLE)) -#define pgprot_writecombine(prot) __pgprot(pgprot_val(prot) & ~L_PTE_CACHEABLE) - -#define pgtable_cache_init() do { } while (0) - -#define pte_to_pgoff(x) (pte_val(x) >> 2) -#define pgoff_to_pte(x) __pte(((x) << 2) | L_PTE_FILE) - -#define PTE_FILE_MAX_BITS 30 - -#endif /* __ASSEMBLY__ */ - -#endif /* __ASM_PROC_PGTABLE_H */ diff -Nru a/include/asm-arm/proc-armv/processor.h b/include/asm-arm/proc-armv/processor.h --- a/include/asm-arm/proc-armv/processor.h Thu Sep 4 15:38:46 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,51 +0,0 @@ -/* - * linux/include/asm-arm/proc-armv/processor.h - * - * Copyright (C) 1996-1999 Russell King. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * Changelog: - * 20-09-1996 RMK Created - * 26-09-1996 RMK Added 'EXTRA_THREAD_STRUCT*' - * 28-09-1996 RMK Moved start_thread into the processor dependencies - * 09-09-1998 PJB Delete redundant `wp_works_ok' - * 30-05-1999 PJB Save sl across context switches - * 31-07-1999 RMK Added 'domain' stuff - */ -#ifndef __ASM_PROC_PROCESSOR_H -#define __ASM_PROC_PROCESSOR_H - -#include - -#define KERNEL_STACK_SIZE PAGE_SIZE - -#define INIT_EXTRA_THREAD_INFO \ - .cpu_domain = domain_val(DOMAIN_USER, DOMAIN_MANAGER) | \ - domain_val(DOMAIN_KERNEL, DOMAIN_MANAGER) | \ - domain_val(DOMAIN_IO, DOMAIN_CLIENT) - -#define start_thread(regs,pc,sp) \ -({ \ - unsigned long *stack = (unsigned long *)sp; \ - set_fs(USER_DS); \ - memzero(regs->uregs, sizeof(regs->uregs)); \ - if (current->personality & ADDR_LIMIT_32BIT) \ - regs->ARM_cpsr = USR_MODE; \ - else \ - regs->ARM_cpsr = USR26_MODE; \ - if (elf_hwcap & HWCAP_THUMB && pc & 1) \ - regs->ARM_cpsr |= PSR_T_BIT; \ - regs->ARM_pc = pc & ~1; /* pc */ \ - regs->ARM_sp = sp; /* sp */ \ - regs->ARM_r2 = stack[2]; /* r2 (envp) */ \ - regs->ARM_r1 = stack[1]; /* r1 (argv) */ \ - regs->ARM_r0 = stack[0]; /* r0 (argc) */ \ -}) - -#define KSTK_EIP(tsk) (((unsigned long *)(4096+(unsigned long)(tsk)->thread_info))[1019]) -#define KSTK_ESP(tsk) (((unsigned long *)(4096+(unsigned long)(tsk)->thread_info))[1017]) - -#endif diff -Nru a/include/asm-arm/proc-armv/ptrace.h b/include/asm-arm/proc-armv/ptrace.h --- a/include/asm-arm/proc-armv/ptrace.h Thu Sep 4 15:38:34 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,143 +0,0 @@ -/* - * linux/include/asm-arm/proc-armv/ptrace.h - * - * Copyright (C) 1996-1999 Russell King - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#ifndef __ASM_PROC_PTRACE_H -#define __ASM_PROC_PTRACE_H - -#include - -/* - * PSR bits - */ -#define USR26_MODE 0x00000000 -#define FIQ26_MODE 0x00000001 -#define IRQ26_MODE 0x00000002 -#define SVC26_MODE 0x00000003 -#define USR_MODE 0x00000010 -#define FIQ_MODE 0x00000011 -#define IRQ_MODE 0x00000012 -#define SVC_MODE 0x00000013 -#define ABT_MODE 0x00000017 -#define UND_MODE 0x0000001b -#define SYSTEM_MODE 0x0000001f -#define MODE32_BIT 0x00000010 -#define MODE_MASK 0x0000001f -#define PSR_T_BIT 0x00000020 -#define PSR_F_BIT 0x00000040 -#define PSR_I_BIT 0x00000080 -#define PSR_J_BIT 0x01000000 -#define PSR_Q_BIT 0x08000000 -#define PSR_V_BIT 0x10000000 -#define PSR_C_BIT 0x20000000 -#define PSR_Z_BIT 0x40000000 -#define PSR_N_BIT 0x80000000 -#define PCMASK 0 - -/* - * Groups of PSR bits - */ -#define PSR_f 0xff000000 /* Flags */ -#define PSR_s 0x00ff0000 /* Status */ -#define PSR_x 0x0000ff00 /* Extension */ -#define PSR_c 0x000000ff /* Control */ - -/* - * CR1 bits - */ -#define CR1_M 0x00000001 /* MMU */ -#define CR1_A 0x00000002 /* Alignment fault */ -#define CR1_C 0x00000004 /* Dcache */ -#define CR1_W 0x00000008 /* Write buffer */ -#define CR1_P 0x00000010 /* Prog32 */ -#define CR1_D 0x00000020 /* Data32 */ -#define CR1_L 0x00000040 /* Late abort */ -#define CR1_B 0x00000080 /* Big endian */ -#define CR1_S 0x00000100 /* System protection */ -#define CR1_R 0x00000200 /* ROM protection */ -#define CR1_F 0x00000400 -#define CR1_Z 0x00000800 /* BTB enable */ -#define CR1_I 0x00001000 /* Icache */ -#define CR1_V 0x00002000 /* Vector relocation */ -#define CR1_RR 0x00004000 /* Round Robin */ - -#ifndef __ASSEMBLY__ - -/* this struct defines the way the registers are stored on the - stack during a system call. */ - -struct pt_regs { - long uregs[18]; -}; - -#define ARM_cpsr uregs[16] -#define ARM_pc uregs[15] -#define ARM_lr uregs[14] -#define ARM_sp uregs[13] -#define ARM_ip uregs[12] -#define ARM_fp uregs[11] -#define ARM_r10 uregs[10] -#define ARM_r9 uregs[9] -#define ARM_r8 uregs[8] -#define ARM_r7 uregs[7] -#define ARM_r6 uregs[6] -#define ARM_r5 uregs[5] -#define ARM_r4 uregs[4] -#define ARM_r3 uregs[3] -#define ARM_r2 uregs[2] -#define ARM_r1 uregs[1] -#define ARM_r0 uregs[0] -#define ARM_ORIG_r0 uregs[17] - -#ifdef __KERNEL__ - -#define user_mode(regs) \ - (((regs)->ARM_cpsr & 0xf) == 0) - -#ifdef CONFIG_ARM_THUMB -#define thumb_mode(regs) \ - (((regs)->ARM_cpsr & PSR_T_BIT)) -#else -#define thumb_mode(regs) (0) -#endif - -#define processor_mode(regs) \ - ((regs)->ARM_cpsr & MODE_MASK) - -#define interrupts_enabled(regs) \ - (!((regs)->ARM_cpsr & PSR_I_BIT)) - -#define fast_interrupts_enabled(regs) \ - (!((regs)->ARM_cpsr & PSR_F_BIT)) - -#define condition_codes(regs) \ - ((regs)->ARM_cpsr & (PSR_V_BIT|PSR_C_BIT|PSR_Z_BIT|PSR_N_BIT)) - -/* Are the current registers suitable for user mode? - * (used to maintain security in signal handlers) - */ -static inline int valid_user_regs(struct pt_regs *regs) -{ - if (user_mode(regs) && - (regs->ARM_cpsr & (PSR_F_BIT|PSR_I_BIT)) == 0) - return 1; - - /* - * Force CPSR to something logical... - */ - regs->ARM_cpsr &= PSR_f | PSR_s | PSR_x | PSR_T_BIT | MODE32_BIT; - - return 0; -} - -#endif /* __KERNEL__ */ - -#endif /* __ASSEMBLY__ */ - -#endif - diff -Nru a/include/asm-arm/proc-armv/shmparam.h b/include/asm-arm/proc-armv/shmparam.h --- a/include/asm-arm/proc-armv/shmparam.h Thu Sep 4 15:38:33 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,20 +0,0 @@ -/* - * linux/include/asm-arm/proc-armv/shmparam.h - * - * Copyright (C) 1996 Russell King - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * definitions for the shared process memory on ARM v3 or v4 - * processors - */ -#ifndef __ASM_PROC_SHMPARAM_H -#define __ASM_PROC_SHMPARAM_H - -#ifndef SHMMAX -#define SHMMAX 0x01000000 -#endif - -#endif diff -Nru a/include/asm-arm/proc-armv/system.h b/include/asm-arm/proc-armv/system.h --- a/include/asm-arm/proc-armv/system.h Thu Sep 4 15:38:29 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,215 +0,0 @@ -/* - * linux/include/asm-arm/proc-armv/system.h - * - * Copyright (C) 1996 Russell King - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#ifndef __ASM_PROC_SYSTEM_H -#define __ASM_PROC_SYSTEM_H - -#include - -#define set_cr(x) \ - __asm__ __volatile__( \ - "mcr p15, 0, %0, c1, c0, 0 @ set CR" \ - : : "r" (x) : "cc") - -#define get_cr() \ - ({ \ - unsigned int __val; \ - __asm__ __volatile__( \ - "mrc p15, 0, %0, c1, c0, 0 @ get CR" \ - : "=r" (__val) : : "cc"); \ - __val; \ - }) - -#define CR_M (1 << 0) /* MMU enable */ -#define CR_A (1 << 1) /* Alignment abort enable */ -#define CR_C (1 << 2) /* Dcache enable */ -#define CR_W (1 << 3) /* Write buffer enable */ -#define CR_P (1 << 4) /* 32-bit exception handler */ -#define CR_D (1 << 5) /* 32-bit data address range */ -#define CR_L (1 << 6) /* Implementation defined */ -#define CR_B (1 << 7) /* Big endian */ -#define CR_S (1 << 8) /* System MMU protection */ -#define CR_R (1 << 9) /* ROM MMU protection */ -#define CR_F (1 << 10) /* Implementation defined */ -#define CR_Z (1 << 11) /* Implementation defined */ -#define CR_I (1 << 12) /* Icache enable */ -#define CR_V (1 << 13) /* Vectors relocated to 0xffff0000 */ -#define CR_RR (1 << 14) /* Round Robin cache replacement */ -#define CR_L4 (1 << 15) /* LDR pc can set T bit */ -#define CR_DT (1 << 16) -#define CR_IT (1 << 18) -#define CR_ST (1 << 19) -#define CR_FI (1 << 21) -#define CR_U (1 << 22) /* Unaligned access operation */ -#define CR_XP (1 << 23) /* Extended page tables */ -#define CR_VE (1 << 24) /* Vectored interrupts */ - -extern unsigned long cr_no_alignment; /* defined in entry-armv.S */ -extern unsigned long cr_alignment; /* defined in entry-armv.S */ - -#if __LINUX_ARM_ARCH__ >= 4 -#define vectors_base() ((cr_alignment & CR_V) ? 0xffff0000 : 0) -#else -#define vectors_base() (0) -#endif - -/* - * Save the current interrupt enable state & disable IRQs - */ -#define local_irq_save(x) \ - ({ \ - unsigned long temp; \ - (void) (&temp == &x); \ - __asm__ __volatile__( \ - "mrs %0, cpsr @ local_irq_save\n" \ -" orr %1, %0, #128\n" \ -" msr cpsr_c, %1" \ - : "=r" (x), "=r" (temp) \ - : \ - : "memory", "cc"); \ - }) - -/* - * Enable IRQs - */ -#define local_irq_enable() \ - ({ \ - unsigned long temp; \ - __asm__ __volatile__( \ - "mrs %0, cpsr @ local_irq_enable\n" \ -" bic %0, %0, #128\n" \ -" msr cpsr_c, %0" \ - : "=r" (temp) \ - : \ - : "memory", "cc"); \ - }) - -/* - * Disable IRQs - */ -#define local_irq_disable() \ - ({ \ - unsigned long temp; \ - __asm__ __volatile__( \ - "mrs %0, cpsr @ local_irq_disable\n" \ -" orr %0, %0, #128\n" \ -" msr cpsr_c, %0" \ - : "=r" (temp) \ - : \ - : "memory", "cc"); \ - }) - -/* - * Enable FIQs - */ -#define __stf() \ - ({ \ - unsigned long temp; \ - __asm__ __volatile__( \ - "mrs %0, cpsr @ stf\n" \ -" bic %0, %0, #64\n" \ -" msr cpsr_c, %0" \ - : "=r" (temp) \ - : \ - : "memory", "cc"); \ - }) - -/* - * Disable FIQs - */ -#define __clf() \ - ({ \ - unsigned long temp; \ - __asm__ __volatile__( \ - "mrs %0, cpsr @ clf\n" \ -" orr %0, %0, #64\n" \ -" msr cpsr_c, %0" \ - : "=r" (temp) \ - : \ - : "memory", "cc"); \ - }) - -/* - * Save the current interrupt enable state. - */ -#define local_save_flags(x) \ - ({ \ - __asm__ __volatile__( \ - "mrs %0, cpsr @ local_save_flags" \ - : "=r" (x) : : "memory", "cc"); \ - }) - -/* - * restore saved IRQ & FIQ state - */ -#define local_irq_restore(x) \ - __asm__ __volatile__( \ - "msr cpsr_c, %0 @ local_irq_restore\n" \ - : \ - : "r" (x) \ - : "memory", "cc") - -#if defined(CONFIG_CPU_SA1100) || defined(CONFIG_CPU_SA110) -/* - * On the StrongARM, "swp" is terminally broken since it bypasses the - * cache totally. This means that the cache becomes inconsistent, and, - * since we use normal loads/stores as well, this is really bad. - * Typically, this causes oopsen in filp_close, but could have other, - * more disasterous effects. There are two work-arounds: - * 1. Disable interrupts and emulate the atomic swap - * 2. Clean the cache, perform atomic swap, flush the cache - * - * We choose (1) since its the "easiest" to achieve here and is not - * dependent on the processor type. - */ -#define swp_is_buggy -#endif - -static inline unsigned long __xchg(unsigned long x, volatile void *ptr, int size) -{ - extern void __bad_xchg(volatile void *, int); - unsigned long ret; -#ifdef swp_is_buggy - unsigned long flags; -#endif - - switch (size) { -#ifdef swp_is_buggy - case 1: - local_irq_save(flags); - ret = *(volatile unsigned char *)ptr; - *(volatile unsigned char *)ptr = x; - local_irq_restore(flags); - break; - - case 4: - local_irq_save(flags); - ret = *(volatile unsigned long *)ptr; - *(volatile unsigned long *)ptr = x; - local_irq_restore(flags); - break; -#else - case 1: __asm__ __volatile__ ("swpb %0, %1, [%2]" - : "=&r" (ret) - : "r" (x), "r" (ptr) - : "memory", "cc"); - break; - case 4: __asm__ __volatile__ ("swp %0, %1, [%2]" - : "=&r" (ret) - : "r" (x), "r" (ptr) - : "memory", "cc"); - break; -#endif - default: __bad_xchg(ptr, size), ret = 0; - } - - return ret; -} - -#endif diff -Nru a/include/asm-arm/proc-armv/tlbflush.h b/include/asm-arm/proc-armv/tlbflush.h --- a/include/asm-arm/proc-armv/tlbflush.h Thu Sep 4 15:38:41 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,410 +0,0 @@ -/* - * linux/include/asm-arm/proc-armv/tlbflush.h - * - * Copyright (C) 1999-2003 Russell King - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#include -#include - -#define TLB_V3_PAGE (1 << 0) -#define TLB_V4_U_PAGE (1 << 1) -#define TLB_V4_D_PAGE (1 << 2) -#define TLB_V4_I_PAGE (1 << 3) -#define TLB_V6_U_PAGE (1 << 4) -#define TLB_V6_D_PAGE (1 << 5) -#define TLB_V6_I_PAGE (1 << 6) - -#define TLB_V3_FULL (1 << 8) -#define TLB_V4_U_FULL (1 << 9) -#define TLB_V4_D_FULL (1 << 10) -#define TLB_V4_I_FULL (1 << 11) -#define TLB_V6_U_FULL (1 << 12) -#define TLB_V6_D_FULL (1 << 13) -#define TLB_V6_I_FULL (1 << 14) - -#define TLB_V6_U_ASID (1 << 16) -#define TLB_V6_D_ASID (1 << 17) -#define TLB_V6_I_ASID (1 << 18) - -#define TLB_DCLEAN (1 << 30) -#define TLB_WB (1 << 31) - -/* - * MMU TLB Model - * ============= - * - * We have the following to choose from: - * v3 - ARMv3 - * v4 - ARMv4 without write buffer - * v4wb - ARMv4 with write buffer without I TLB flush entry instruction - * v4wbi - ARMv4 with write buffer with I TLB flush entry instruction - * v6wbi - ARMv6 with write buffer with I TLB flush entry instruction - */ -#undef _TLB -#undef MULTI_TLB - -#define v3_tlb_flags (TLB_V3_FULL | TLB_V3_PAGE) - -#if defined(CONFIG_CPU_ARM610) || defined(CONFIG_CPU_ARM710) -# define v3_possible_flags v3_tlb_flags -# define v3_always_flags v3_tlb_flags -# ifdef _TLB -# define MULTI_TLB 1 -# else -# define _TLB v3 -# endif -#else -# define v3_possible_flags 0 -# define v3_always_flags (-1UL) -#endif - -#define v4_tlb_flags (TLB_V4_U_FULL | TLB_V4_U_PAGE) - -#if defined(CONFIG_CPU_ARM720T) -# define v4_possible_flags v4_tlb_flags -# define v4_always_flags v4_tlb_flags -# ifdef _TLB -# define MULTI_TLB 1 -# else -# define _TLB v4 -# endif -#else -# define v4_possible_flags 0 -# define v4_always_flags (-1UL) -#endif - -#define v4wbi_tlb_flags (TLB_WB | TLB_DCLEAN | \ - TLB_V4_I_FULL | TLB_V4_D_FULL | \ - TLB_V4_I_PAGE | TLB_V4_D_PAGE) - -#if defined(CONFIG_CPU_ARM920T) || defined(CONFIG_CPU_ARM922T) || \ - defined(CONFIG_CPU_ARM926T) || defined(CONFIG_CPU_ARM1020) || \ - defined(CONFIG_CPU_XSCALE) -# define v4wbi_possible_flags v4wbi_tlb_flags -# define v4wbi_always_flags v4wbi_tlb_flags -# ifdef _TLB -# define MULTI_TLB 1 -# else -# define _TLB v4wbi -# endif -#else -# define v4wbi_possible_flags 0 -# define v4wbi_always_flags (-1UL) -#endif - -#define v4wb_tlb_flags (TLB_WB | TLB_DCLEAN | \ - TLB_V4_I_FULL | TLB_V4_D_FULL | \ - TLB_V4_D_PAGE) - -#if defined(CONFIG_CPU_SA110) || defined(CONFIG_CPU_SA1100) -# define v4wb_possible_flags v4wb_tlb_flags -# define v4wb_always_flags v4wb_tlb_flags -# ifdef _TLB -# define MULTI_TLB 1 -# else -# define _TLB v4wb -# endif -#else -# define v4wb_possible_flags 0 -# define v4wb_always_flags (-1UL) -#endif - -#define v6wbi_tlb_flags (TLB_WB | TLB_DCLEAN | \ - TLB_V6_I_FULL | TLB_V6_D_FULL | \ - TLB_V6_I_PAGE | TLB_V6_D_PAGE | \ - TLB_V6_I_ASID | TLB_V6_D_ASID) - -#if defined(CONFIG_CPU_V6) -# define v6wbi_possible_flags v6wbi_tlb_flags -# define v6wbi_always_flags v6wbi_tlb_flags -# ifdef _TLB -# define MULTI_TLB 1 -# else -# define _TLB v6wbi -# endif -#else -# define v6wbi_possible_flags 0 -# define v6wbi_always_flags (-1UL) -#endif - -#ifndef _TLB -#error Unknown TLB model -#endif - -#ifndef __ASSEMBLY__ - -struct cpu_tlb_fns { - void (*flush_user_range)(unsigned long, unsigned long, struct vm_area_struct *); - void (*flush_kern_range)(unsigned long, unsigned long); - unsigned long tlb_flags; -}; - -/* - * Select the calling method - */ -#ifdef MULTI_TLB - -#define __cpu_flush_user_tlb_range cpu_tlb.flush_user_range -#define __cpu_flush_kern_tlb_range cpu_tlb.flush_kern_range - -#else - -#define __cpu_flush_user_tlb_range __glue(_TLB,_flush_user_tlb_range) -#define __cpu_flush_kern_tlb_range __glue(_TLB,_flush_kern_tlb_range) - -extern void __cpu_flush_user_tlb_range(unsigned long, unsigned long, struct vm_area_struct *); -extern void __cpu_flush_kern_tlb_range(unsigned long, unsigned long); - -#endif - -extern struct cpu_tlb_fns cpu_tlb; - -#define __cpu_tlb_flags cpu_tlb.tlb_flags - -/* - * TLB Management - * ============== - * - * The arch/arm/mm/tlb-*.S files implement these methods. - * - * The TLB specific code is expected to perform whatever tests it - * needs to determine if it should invalidate the TLB for each - * call. Start addresses are inclusive and end addresses are - * exclusive; it is safe to round these addresses down. - * - * flush_tlb_all() - * - * Invalidate the entire TLB. - * - * flush_tlb_mm(mm) - * - * Invalidate all TLB entries in a particular address - * space. - * - mm - mm_struct describing address space - * - * flush_tlb_range(mm,start,end) - * - * Invalidate a range of TLB entries in the specified - * address space. - * - mm - mm_struct describing address space - * - start - start address (may not be aligned) - * - end - end address (exclusive, may not be aligned) - * - * flush_tlb_page(vaddr,vma) - * - * Invalidate the specified page in the specified address range. - * - vaddr - virtual address (may not be aligned) - * - vma - vma_struct describing address range - * - * flush_kern_tlb_page(kaddr) - * - * Invalidate the TLB entry for the specified page. The address - * will be in the kernels virtual memory space. Current uses - * only require the D-TLB to be invalidated. - * - kaddr - Kernel virtual memory address - */ - -/* - * We optimise the code below by: - * - building a set of TLB flags that might be set in __cpu_tlb_flags - * - building a set of TLB flags that will always be set in __cpu_tlb_flags - * - if we're going to need __cpu_tlb_flags, access it once and only once - * - * This allows us to build optimal assembly for the single-CPU type case, - * and as close to optimal given the compiler constrants for multi-CPU - * case. We could do better for the multi-CPU case if the compiler - * implemented the "%?" method, but this has been discontinued due to too - * many people getting it wrong. - */ -#define possible_tlb_flags (v3_possible_flags | \ - v4_possible_flags | \ - v4wbi_possible_flags | \ - v4wb_possible_flags | \ - v6wbi_possible_flags) - -#define always_tlb_flags (v3_always_flags & \ - v4_always_flags & \ - v4wbi_always_flags & \ - v4wb_always_flags & \ - v6wbi_always_flags) - -#define tlb_flag(f) ((always_tlb_flags & (f)) || (__tlb_flag & possible_tlb_flags & (f))) - -static inline void flush_tlb_all(void) -{ - const int zero = 0; - const unsigned int __tlb_flag = __cpu_tlb_flags; - - if (tlb_flag(TLB_WB)) - asm("mcr%? p15, 0, %0, c7, c10, 4" : : "r" (zero)); - - if (tlb_flag(TLB_V3_FULL)) - asm("mcr%? p15, 0, %0, c6, c0, 0" : : "r" (zero)); - if (tlb_flag(TLB_V4_U_FULL | TLB_V6_U_FULL)) - asm("mcr%? p15, 0, %0, c8, c7, 0" : : "r" (zero)); - if (tlb_flag(TLB_V4_D_FULL | TLB_V6_D_FULL)) - asm("mcr%? p15, 0, %0, c8, c6, 0" : : "r" (zero)); - if (tlb_flag(TLB_V4_I_FULL | TLB_V6_I_FULL)) - asm("mcr%? p15, 0, %0, c8, c5, 0" : : "r" (zero)); -} - -static inline void flush_tlb_mm(struct mm_struct *mm) -{ - const int zero = 0; - const int asid = ASID(mm); - const unsigned int __tlb_flag = __cpu_tlb_flags; - - if (tlb_flag(TLB_WB)) - asm("mcr%? p15, 0, %0, c7, c10, 4" : : "r" (zero)); - - if (mm == current->active_mm) { - if (tlb_flag(TLB_V3_FULL)) - asm("mcr%? p15, 0, %0, c6, c0, 0" : : "r" (zero)); - if (tlb_flag(TLB_V4_U_FULL)) - asm("mcr%? p15, 0, %0, c8, c7, 0" : : "r" (zero)); - if (tlb_flag(TLB_V4_D_FULL)) - asm("mcr%? p15, 0, %0, c8, c6, 0" : : "r" (zero)); - if (tlb_flag(TLB_V4_I_FULL)) - asm("mcr%? p15, 0, %0, c8, c5, 0" : : "r" (zero)); - } - - if (tlb_flag(TLB_V6_U_ASID)) - asm("mcr%? p15, 0, %0, c8, c7, 2" : : "r" (asid)); - if (tlb_flag(TLB_V6_D_ASID)) - asm("mcr%? p15, 0, %0, c8, c6, 2" : : "r" (asid)); - if (tlb_flag(TLB_V6_I_ASID)) - asm("mcr%? p15, 0, %0, c8, c5, 2" : : "r" (asid)); -} - -static inline void -flush_tlb_page(struct vm_area_struct *vma, unsigned long uaddr) -{ - const int zero = 0; - const unsigned int __tlb_flag = __cpu_tlb_flags; - - uaddr = (uaddr & PAGE_MASK) | ASID(vma->vm_mm); - - if (tlb_flag(TLB_WB)) - asm("mcr%? p15, 0, %0, c7, c10, 4" : : "r" (zero)); - - if (vma->vm_mm == current->active_mm) { - if (tlb_flag(TLB_V3_PAGE)) - asm("mcr%? p15, 0, %0, c6, c0, 0" : : "r" (uaddr)); - if (tlb_flag(TLB_V4_U_PAGE)) - asm("mcr%? p15, 0, %0, c8, c7, 1" : : "r" (uaddr)); - if (tlb_flag(TLB_V4_D_PAGE)) - asm("mcr%? p15, 0, %0, c8, c6, 1" : : "r" (uaddr)); - if (tlb_flag(TLB_V4_I_PAGE)) - asm("mcr%? p15, 0, %0, c8, c5, 1" : : "r" (uaddr)); - if (!tlb_flag(TLB_V4_I_PAGE) && tlb_flag(TLB_V4_I_FULL)) - asm("mcr%? p15, 0, %0, c8, c5, 0" : : "r" (zero)); - } - - if (tlb_flag(TLB_V6_U_PAGE)) - asm("mcr%? p15, 0, %0, c8, c7, 1" : : "r" (uaddr)); - if (tlb_flag(TLB_V6_D_PAGE)) - asm("mcr%? p15, 0, %0, c8, c6, 1" : : "r" (uaddr)); - if (tlb_flag(TLB_V6_I_PAGE)) - asm("mcr%? p15, 0, %0, c8, c5, 1" : : "r" (uaddr)); -} - -static inline void flush_tlb_kernel_page(unsigned long kaddr) -{ - const int zero = 0; - const unsigned int __tlb_flag = __cpu_tlb_flags; - - kaddr &= PAGE_MASK; - - if (tlb_flag(TLB_WB)) - asm("mcr%? p15, 0, %0, c7, c10, 4" : : "r" (zero)); - - if (tlb_flag(TLB_V3_PAGE)) - asm("mcr%? p15, 0, %0, c6, c0, 0" : : "r" (kaddr)); - if (tlb_flag(TLB_V4_U_PAGE)) - asm("mcr%? p15, 0, %0, c8, c7, 1" : : "r" (kaddr)); - if (tlb_flag(TLB_V4_D_PAGE)) - asm("mcr%? p15, 0, %0, c8, c6, 1" : : "r" (kaddr)); - if (tlb_flag(TLB_V4_I_PAGE)) - asm("mcr%? p15, 0, %0, c8, c5, 1" : : "r" (kaddr)); - if (!tlb_flag(TLB_V4_I_PAGE) && tlb_flag(TLB_V4_I_FULL)) - asm("mcr%? p15, 0, %0, c8, c5, 0" : : "r" (zero)); - - if (tlb_flag(TLB_V6_U_PAGE)) - asm("mcr%? p15, 0, %0, c8, c7, 1" : : "r" (kaddr)); - if (tlb_flag(TLB_V6_D_PAGE)) - asm("mcr%? p15, 0, %0, c8, c6, 1" : : "r" (kaddr)); - if (tlb_flag(TLB_V6_I_PAGE)) - asm("mcr%? p15, 0, %0, c8, c5, 1" : : "r" (kaddr)); -} - -/* - * flush_pmd_entry - * - * Flush a PMD entry (word aligned, or double-word aligned) to - * RAM if the TLB for the CPU we are running on requires this. - * This is typically used when we are creating PMD entries. - * - * clean_pmd_entry - * - * Clean (but don't drain the write buffer) if the CPU requires - * these operations. This is typically used when we are removing - * PMD entries. - */ -static inline void flush_pmd_entry(pmd_t *pmd) -{ - const unsigned int zero = 0; - const unsigned int __tlb_flag = __cpu_tlb_flags; - - if (tlb_flag(TLB_DCLEAN)) - asm("mcr%? p15, 0, %0, c7, c10, 1 @ flush_pmd" - : : "r" (pmd)); - if (tlb_flag(TLB_WB)) - asm("mcr%? p15, 0, %0, c7, c10, 4 @ flush_pmd" - : : "r" (zero)); -} - -static inline void clean_pmd_entry(pmd_t *pmd) -{ - const unsigned int __tlb_flag = __cpu_tlb_flags; - - if (tlb_flag(TLB_DCLEAN)) - asm("mcr%? p15, 0, %0, c7, c10, 1 @ flush_pmd" - : : "r" (pmd)); -} - -#undef tlb_flag -#undef always_tlb_flags -#undef possible_tlb_flags - -/* - * Convert calls to our calling convention. - */ -#define flush_tlb_range(vma,start,end) __cpu_flush_user_tlb_range(start,end,vma) -#define flush_tlb_kernel_range(s,e) __cpu_flush_kern_tlb_range(s,e) - -/* - * if PG_dcache_dirty is set for the page, we need to ensure that any - * cache entries for the kernels virtual memory range are written - * back to the page. - */ -extern void update_mmu_cache(struct vm_area_struct *vma, unsigned long addr, pte_t pte); - -/* - * ARM processors do not cache TLB tables in RAM. - */ -#define flush_tlb_pgtables(mm,start,end) do { } while (0) - -/* - * Old ARM MEMC stuff. This supports the reversed mapping handling that - * we have on the older 26-bit machines. We don't have a MEMC chip, so... - */ -#define memc_update_all() do { } while (0) -#define memc_update_mm(mm) do { } while (0) -#define memc_update_addr(mm,pte,log) do { } while (0) -#define memc_clear(mm,physaddr) do { } while (0) - -#endif diff -Nru a/include/asm-arm/proc-armv/uaccess.h b/include/asm-arm/proc-armv/uaccess.h --- a/include/asm-arm/proc-armv/uaccess.h Thu Sep 4 15:38:28 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,189 +0,0 @@ -/* - * linux/include/asm-arm/proc-armv/uaccess.h - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#include -#include - -/* - * Note that this is actually 0x1,0000,0000 - */ -#define KERNEL_DS 0x00000000 -#define USER_DS TASK_SIZE - -static inline void set_fs (mm_segment_t fs) -{ - current_thread_info()->addr_limit = fs; - modify_domain(DOMAIN_KERNEL, fs ? DOMAIN_CLIENT : DOMAIN_MANAGER); -} - -/* We use 33-bit arithmetic here... */ -#define __range_ok(addr,size) ({ \ - unsigned long flag, sum; \ - __asm__("adds %1, %2, %3; sbcccs %1, %1, %0; movcc %0, #0" \ - : "=&r" (flag), "=&r" (sum) \ - : "r" (addr), "Ir" (size), "0" (current_thread_info()->addr_limit) \ - : "cc"); \ - flag; }) - -#define __addr_ok(addr) ({ \ - unsigned long flag; \ - __asm__("cmp %2, %0; movlo %0, #0" \ - : "=&r" (flag) \ - : "0" (current_thread_info()->addr_limit), "r" (addr) \ - : "cc"); \ - (flag == 0); }) - -#define __put_user_asm_byte(x,__pu_addr,err) \ - __asm__ __volatile__( \ - "1: strbt %1,[%2],#0\n" \ - "2:\n" \ - " .section .fixup,\"ax\"\n" \ - " .align 2\n" \ - "3: mov %0, %3\n" \ - " b 2b\n" \ - " .previous\n" \ - " .section __ex_table,\"a\"\n" \ - " .align 3\n" \ - " .long 1b, 3b\n" \ - " .previous" \ - : "+r" (err) \ - : "r" (x), "r" (__pu_addr), "i" (-EFAULT) \ - : "cc") - -#ifndef __ARMEB__ -#define __put_user_asm_half(x,__pu_addr,err) \ -({ \ - unsigned long __temp = (unsigned long)(x); \ - __put_user_asm_byte(__temp, __pu_addr, err); \ - __put_user_asm_byte(__temp >> 8, __pu_addr + 1, err); \ -}) -#else -#define __put_user_asm_half(x,__pu_addr,err) \ -({ \ - unsigned long __temp = (unsigned long)(x); \ - __put_user_asm_byte(__temp >> 8, __pu_addr, err); \ - __put_user_asm_byte(__temp, __pu_addr + 1, err); \ -}) -#endif - -#define __put_user_asm_word(x,__pu_addr,err) \ - __asm__ __volatile__( \ - "1: strt %1,[%2],#0\n" \ - "2:\n" \ - " .section .fixup,\"ax\"\n" \ - " .align 2\n" \ - "3: mov %0, %3\n" \ - " b 2b\n" \ - " .previous\n" \ - " .section __ex_table,\"a\"\n" \ - " .align 3\n" \ - " .long 1b, 3b\n" \ - " .previous" \ - : "+r" (err) \ - : "r" (x), "r" (__pu_addr), "i" (-EFAULT) \ - : "cc") - -#ifndef __ARMEB__ -#define __reg_oper0 "%R2" -#define __reg_oper1 "%Q2" -#else -#define __reg_oper0 "%Q2" -#define __reg_oper1 "%R2" -#endif - -#define __put_user_asm_dword(x,__pu_addr,err) \ - __asm__ __volatile__( \ - "1: strt " __reg_oper1 ", [%1], #4\n" \ - "2: strt " __reg_oper0 ", [%1], #0\n" \ - "3:\n" \ - " .section .fixup,\"ax\"\n" \ - " .align 2\n" \ - "4: mov %0, %3\n" \ - " b 3b\n" \ - " .previous\n" \ - " .section __ex_table,\"a\"\n" \ - " .align 3\n" \ - " .long 1b, 4b\n" \ - " .long 2b, 4b\n" \ - " .previous" \ - : "+r" (err), "+r" (__pu_addr) \ - : "r" (x), "i" (-EFAULT) \ - : "cc") - -#define __get_user_asm_byte(x,addr,err) \ - __asm__ __volatile__( \ - "1: ldrbt %1,[%2],#0\n" \ - "2:\n" \ - " .section .fixup,\"ax\"\n" \ - " .align 2\n" \ - "3: mov %0, %3\n" \ - " mov %1, #0\n" \ - " b 2b\n" \ - " .previous\n" \ - " .section __ex_table,\"a\"\n" \ - " .align 3\n" \ - " .long 1b, 3b\n" \ - " .previous" \ - : "+r" (err), "=&r" (x) \ - : "r" (addr), "i" (-EFAULT) \ - : "cc") - -#ifndef __ARMEB__ -#define __get_user_asm_half(x,__gu_addr,err) \ -({ \ - unsigned long __b1, __b2; \ - __get_user_asm_byte(__b1, __gu_addr, err); \ - __get_user_asm_byte(__b2, __gu_addr + 1, err); \ - (x) = __b1 | (__b2 << 8); \ -}) -#else -#define __get_user_asm_half(x,__gu_addr,err) \ -({ \ - unsigned long __b1, __b2; \ - __get_user_asm_byte(__b1, __gu_addr, err); \ - __get_user_asm_byte(__b2, __gu_addr + 1, err); \ - (x) = (__b1 << 8) | __b2; \ -}) -#endif - -#define __get_user_asm_word(x,addr,err) \ - __asm__ __volatile__( \ - "1: ldrt %1,[%2],#0\n" \ - "2:\n" \ - " .section .fixup,\"ax\"\n" \ - " .align 2\n" \ - "3: mov %0, %3\n" \ - " mov %1, #0\n" \ - " b 2b\n" \ - " .previous\n" \ - " .section __ex_table,\"a\"\n" \ - " .align 3\n" \ - " .long 1b, 3b\n" \ - " .previous" \ - : "+r" (err), "=&r" (x) \ - : "r" (addr), "i" (-EFAULT) \ - : "cc") - -extern unsigned long __arch_copy_from_user(void *to, const void *from, unsigned long n); -#define __do_copy_from_user(to,from,n) \ - (n) = __arch_copy_from_user(to,from,n) - -extern unsigned long __arch_copy_to_user(void *to, const void *from, unsigned long n); -#define __do_copy_to_user(to,from,n) \ - (n) = __arch_copy_to_user(to,from,n) - -extern unsigned long __arch_clear_user(void *addr, unsigned long n); -#define __do_clear_user(addr,sz) \ - (sz) = __arch_clear_user(addr,sz) - -extern unsigned long __arch_strncpy_from_user(char *to, const char *from, unsigned long count); -#define __do_strncpy_from_user(dst,src,count,res) \ - (res) = __arch_strncpy_from_user(dst,src,count) - -extern unsigned long __arch_strnlen_user(const char *s, long n); -#define __do_strnlen_user(s,n,res) \ - (res) = __arch_strnlen_user(s,n) diff -Nru a/include/asm-arm/proc-fns.h b/include/asm-arm/proc-fns.h --- a/include/asm-arm/proc-fns.h Thu Sep 4 15:38:35 2003 +++ b/include/asm-arm/proc-fns.h Thu Sep 4 15:38:35 2003 @@ -21,11 +21,6 @@ #undef MULTI_CPU #undef CPU_NAME -#ifdef CONFIG_CPU_26 -# define CPU_INCLUDE_NAME "asm/cpu-multi26.h" -# define MULTI_CPU -#endif - /* * CPU_NAME - the prefix for CPU related functions */ diff -Nru a/include/asm-arm/processor.h b/include/asm-arm/processor.h --- a/include/asm-arm/processor.h Thu Sep 4 15:38:33 2003 +++ b/include/asm-arm/processor.h Thu Sep 4 15:38:33 2003 @@ -1,7 +1,7 @@ /* * linux/include/asm-arm/processor.h * - * Copyright (C) 1995 Russell King + * Copyright (C) 1995-1999 Russell King * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as @@ -27,9 +27,10 @@ #include #include #include -#include #include +#define KERNEL_STACK_SIZE PAGE_SIZE + union debug_insn { u32 arm; u16 thumb; @@ -56,6 +57,24 @@ #define INIT_THREAD { } +#define start_thread(regs,pc,sp) \ +({ \ + unsigned long *stack = (unsigned long *)sp; \ + set_fs(USER_DS); \ + memzero(regs->uregs, sizeof(regs->uregs)); \ + if (current->personality & ADDR_LIMIT_32BIT) \ + regs->ARM_cpsr = USR_MODE; \ + else \ + regs->ARM_cpsr = USR26_MODE; \ + if (elf_hwcap & HWCAP_THUMB && pc & 1) \ + regs->ARM_cpsr |= PSR_T_BIT; \ + regs->ARM_pc = pc & ~1; /* pc */ \ + regs->ARM_sp = sp; /* sp */ \ + regs->ARM_r2 = stack[2]; /* r2 (envp) */ \ + regs->ARM_r1 = stack[1]; /* r1 (argv) */ \ + regs->ARM_r0 = stack[0]; /* r0 (argc) */ \ +}) + /* Forward declaration, a strange C thing */ struct task_struct; @@ -73,6 +92,9 @@ * Create a new kernel thread */ extern int kernel_thread(int (*fn)(void *), void *arg, unsigned long flags); + +#define KSTK_EIP(tsk) (((unsigned long *)(4096+(unsigned long)(tsk)->thread_info))[1019]) +#define KSTK_ESP(tsk) (((unsigned long *)(4096+(unsigned long)(tsk)->thread_info))[1017]) /* * Prefetching support - only ARMv5. diff -Nru a/include/asm-arm/ptrace.h b/include/asm-arm/ptrace.h --- a/include/asm-arm/ptrace.h Thu Sep 4 15:38:37 2003 +++ b/include/asm-arm/ptrace.h Thu Sep 4 15:38:37 2003 @@ -1,6 +1,17 @@ +/* + * linux/include/asm-arm/ptrace.h + * + * Copyright (C) 1996-2003 Russell King + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ #ifndef __ASM_ARM_PTRACE_H #define __ASM_ARM_PTRACE_H +#include + #define PTRACE_GETREGS 12 #define PTRACE_SETREGS 13 #define PTRACE_GETFPREGS 14 @@ -8,9 +19,112 @@ #define PTRACE_OLDSETOPTIONS 21 -#include +/* + * PSR bits + */ +#define USR26_MODE 0x00000000 +#define FIQ26_MODE 0x00000001 +#define IRQ26_MODE 0x00000002 +#define SVC26_MODE 0x00000003 +#define USR_MODE 0x00000010 +#define FIQ_MODE 0x00000011 +#define IRQ_MODE 0x00000012 +#define SVC_MODE 0x00000013 +#define ABT_MODE 0x00000017 +#define UND_MODE 0x0000001b +#define SYSTEM_MODE 0x0000001f +#define MODE32_BIT 0x00000010 +#define MODE_MASK 0x0000001f +#define PSR_T_BIT 0x00000020 +#define PSR_F_BIT 0x00000040 +#define PSR_I_BIT 0x00000080 +#define PSR_J_BIT 0x01000000 +#define PSR_Q_BIT 0x08000000 +#define PSR_V_BIT 0x10000000 +#define PSR_C_BIT 0x20000000 +#define PSR_Z_BIT 0x40000000 +#define PSR_N_BIT 0x80000000 +#define PCMASK 0 + +/* + * Groups of PSR bits + */ +#define PSR_f 0xff000000 /* Flags */ +#define PSR_s 0x00ff0000 /* Status */ +#define PSR_x 0x0000ff00 /* Extension */ +#define PSR_c 0x000000ff /* Control */ #ifndef __ASSEMBLY__ + +/* this struct defines the way the registers are stored on the + stack during a system call. */ + +struct pt_regs { + long uregs[18]; +}; + +#define ARM_cpsr uregs[16] +#define ARM_pc uregs[15] +#define ARM_lr uregs[14] +#define ARM_sp uregs[13] +#define ARM_ip uregs[12] +#define ARM_fp uregs[11] +#define ARM_r10 uregs[10] +#define ARM_r9 uregs[9] +#define ARM_r8 uregs[8] +#define ARM_r7 uregs[7] +#define ARM_r6 uregs[6] +#define ARM_r5 uregs[5] +#define ARM_r4 uregs[4] +#define ARM_r3 uregs[3] +#define ARM_r2 uregs[2] +#define ARM_r1 uregs[1] +#define ARM_r0 uregs[0] +#define ARM_ORIG_r0 uregs[17] + +#ifdef __KERNEL__ + +#define user_mode(regs) \ + (((regs)->ARM_cpsr & 0xf) == 0) + +#ifdef CONFIG_ARM_THUMB +#define thumb_mode(regs) \ + (((regs)->ARM_cpsr & PSR_T_BIT)) +#else +#define thumb_mode(regs) (0) +#endif + +#define processor_mode(regs) \ + ((regs)->ARM_cpsr & MODE_MASK) + +#define interrupts_enabled(regs) \ + (!((regs)->ARM_cpsr & PSR_I_BIT)) + +#define fast_interrupts_enabled(regs) \ + (!((regs)->ARM_cpsr & PSR_F_BIT)) + +#define condition_codes(regs) \ + ((regs)->ARM_cpsr & (PSR_V_BIT|PSR_C_BIT|PSR_Z_BIT|PSR_N_BIT)) + +/* Are the current registers suitable for user mode? + * (used to maintain security in signal handlers) + */ +static inline int valid_user_regs(struct pt_regs *regs) +{ + if (user_mode(regs) && + (regs->ARM_cpsr & (PSR_F_BIT|PSR_I_BIT)) == 0) + return 1; + + /* + * Force CPSR to something logical... + */ + regs->ARM_cpsr &= PSR_f | PSR_s | PSR_x | PSR_T_BIT | MODE32_BIT; + + return 0; +} + +#endif /* __KERNEL__ */ + #define pc_pointer(v) \ ((v) & ~PCMASK) diff -Nru a/include/asm-arm/semaphore.h b/include/asm-arm/semaphore.h --- a/include/asm-arm/semaphore.h Thu Sep 4 15:38:34 2003 +++ b/include/asm-arm/semaphore.h Thu Sep 4 15:38:34 2003 @@ -10,7 +10,7 @@ #include #include -#include +#include struct semaphore { atomic_t count; @@ -88,7 +88,7 @@ #if WAITQUEUE_DEBUG CHECK_MAGIC(sem->__magic); #endif - + might_sleep(); __down_op(sem, __down_failed); } @@ -101,7 +101,7 @@ #if WAITQUEUE_DEBUG CHECK_MAGIC(sem->__magic); #endif - + might_sleep(); return __down_op_ret(sem, __down_interruptible_failed); } diff -Nru a/include/asm-arm/shmparam.h b/include/asm-arm/shmparam.h --- a/include/asm-arm/shmparam.h Thu Sep 4 15:38:34 2003 +++ b/include/asm-arm/shmparam.h Thu Sep 4 15:38:34 2003 @@ -1,8 +1,6 @@ #ifndef _ASMARM_SHMPARAM_H #define _ASMARM_SHMPARAM_H -#include - /* * This should be the size of the virtually indexed cache/ways, * or page size, whichever is greater since the cache aliases diff -Nru a/include/asm-arm/system.h b/include/asm-arm/system.h --- a/include/asm-arm/system.h Thu Sep 4 15:38:30 2003 +++ b/include/asm-arm/system.h Thu Sep 4 15:38:30 2003 @@ -4,6 +4,45 @@ #ifdef __KERNEL__ #include + +#define CPU_ARCH_UNKNOWN 0 +#define CPU_ARCH_ARMv3 1 +#define CPU_ARCH_ARMv4 2 +#define CPU_ARCH_ARMv4T 3 +#define CPU_ARCH_ARMv5 4 +#define CPU_ARCH_ARMv5T 5 +#define CPU_ARCH_ARMv5TE 6 +#define CPU_ARCH_ARMv6 7 + +/* + * CR1 bits (CP#15 CR1) + */ +#define CR_M (1 << 0) /* MMU enable */ +#define CR_A (1 << 1) /* Alignment abort enable */ +#define CR_C (1 << 2) /* Dcache enable */ +#define CR_W (1 << 3) /* Write buffer enable */ +#define CR_P (1 << 4) /* 32-bit exception handler */ +#define CR_D (1 << 5) /* 32-bit data address range */ +#define CR_L (1 << 6) /* Implementation defined */ +#define CR_B (1 << 7) /* Big endian */ +#define CR_S (1 << 8) /* System MMU protection */ +#define CR_R (1 << 9) /* ROM MMU protection */ +#define CR_F (1 << 10) /* Implementation defined */ +#define CR_Z (1 << 11) /* Implementation defined */ +#define CR_I (1 << 12) /* Icache enable */ +#define CR_V (1 << 13) /* Vectors relocated to 0xffff0000 */ +#define CR_RR (1 << 14) /* Round Robin cache replacement */ +#define CR_L4 (1 << 15) /* LDR pc can set T bit */ +#define CR_DT (1 << 16) +#define CR_IT (1 << 18) +#define CR_ST (1 << 19) +#define CR_FI (1 << 21) +#define CR_U (1 << 22) /* Unaligned access operation */ +#define CR_XP (1 << 23) /* Extended page tables */ +#define CR_VE (1 << 24) /* Vectored interrupts */ + +#ifndef __ASSEMBLY__ + #include struct thread_info; @@ -34,21 +73,30 @@ extern asmlinkage void __backtrace(void); -#define CPU_ARCH_UNKNOWN 0 -#define CPU_ARCH_ARMv3 1 -#define CPU_ARCH_ARMv4 2 -#define CPU_ARCH_ARMv4T 3 -#define CPU_ARCH_ARMv5 4 -#define CPU_ARCH_ARMv5T 5 -#define CPU_ARCH_ARMv5TE 6 -#define CPU_ARCH_ARMv6 7 - extern int cpu_architecture(void); -/* - * Include processor dependent parts - */ -#include +#define set_cr(x) \ + __asm__ __volatile__( \ + "mcr p15, 0, %0, c1, c0, 0 @ set CR" \ + : : "r" (x) : "cc") + +#define get_cr() \ + ({ \ + unsigned int __val; \ + __asm__ __volatile__( \ + "mrc p15, 0, %0, c1, c0, 0 @ get CR" \ + : "=r" (__val) : : "cc"); \ + __val; \ + }) + +extern unsigned long cr_no_alignment; /* defined in entry-armv.S */ +extern unsigned long cr_alignment; /* defined in entry-armv.S */ + +#if __LINUX_ARM_ARCH__ >= 4 +#define vectors_base() ((cr_alignment & CR_V) ? 0xffff0000 : 0) +#else +#define vectors_base() (0) +#endif #define mb() __asm__ __volatile__ ("" : : : "memory") #define rmb() mb() @@ -75,6 +123,102 @@ mb(); \ } while (0) +/* + * Save the current interrupt enable state & disable IRQs + */ +#define local_irq_save(x) \ + ({ \ + unsigned long temp; \ + (void) (&temp == &x); \ + __asm__ __volatile__( \ + "mrs %0, cpsr @ local_irq_save\n" \ +" orr %1, %0, #128\n" \ +" msr cpsr_c, %1" \ + : "=r" (x), "=r" (temp) \ + : \ + : "memory", "cc"); \ + }) + +/* + * Enable IRQs + */ +#define local_irq_enable() \ + ({ \ + unsigned long temp; \ + __asm__ __volatile__( \ + "mrs %0, cpsr @ local_irq_enable\n" \ +" bic %0, %0, #128\n" \ +" msr cpsr_c, %0" \ + : "=r" (temp) \ + : \ + : "memory", "cc"); \ + }) + +/* + * Disable IRQs + */ +#define local_irq_disable() \ + ({ \ + unsigned long temp; \ + __asm__ __volatile__( \ + "mrs %0, cpsr @ local_irq_disable\n" \ +" orr %0, %0, #128\n" \ +" msr cpsr_c, %0" \ + : "=r" (temp) \ + : \ + : "memory", "cc"); \ + }) + +/* + * Enable FIQs + */ +#define __stf() \ + ({ \ + unsigned long temp; \ + __asm__ __volatile__( \ + "mrs %0, cpsr @ stf\n" \ +" bic %0, %0, #64\n" \ +" msr cpsr_c, %0" \ + : "=r" (temp) \ + : \ + : "memory", "cc"); \ + }) + +/* + * Disable FIQs + */ +#define __clf() \ + ({ \ + unsigned long temp; \ + __asm__ __volatile__( \ + "mrs %0, cpsr @ clf\n" \ +" orr %0, %0, #64\n" \ +" msr cpsr_c, %0" \ + : "=r" (temp) \ + : \ + : "memory", "cc"); \ + }) + +/* + * Save the current interrupt enable state. + */ +#define local_save_flags(x) \ + ({ \ + __asm__ __volatile__( \ + "mrs %0, cpsr @ local_save_flags" \ + : "=r" (x) : : "memory", "cc"); \ + }) + +/* + * restore saved IRQ & FIQ state + */ +#define local_irq_restore(x) \ + __asm__ __volatile__( \ + "msr cpsr_c, %0 @ local_irq_restore\n" \ + : \ + : "r" (x) \ + : "memory", "cc") + #ifdef CONFIG_SMP #error SMP not supported @@ -100,7 +244,66 @@ flags & PSR_I_BIT; \ }) +#if defined(CONFIG_CPU_SA1100) || defined(CONFIG_CPU_SA110) +/* + * On the StrongARM, "swp" is terminally broken since it bypasses the + * cache totally. This means that the cache becomes inconsistent, and, + * since we use normal loads/stores as well, this is really bad. + * Typically, this causes oopsen in filp_close, but could have other, + * more disasterous effects. There are two work-arounds: + * 1. Disable interrupts and emulate the atomic swap + * 2. Clean the cache, perform atomic swap, flush the cache + * + * We choose (1) since its the "easiest" to achieve here and is not + * dependent on the processor type. + */ +#define swp_is_buggy +#endif + +static inline unsigned long __xchg(unsigned long x, volatile void *ptr, int size) +{ + extern void __bad_xchg(volatile void *, int); + unsigned long ret; +#ifdef swp_is_buggy + unsigned long flags; +#endif + + switch (size) { +#ifdef swp_is_buggy + case 1: + local_irq_save(flags); + ret = *(volatile unsigned char *)ptr; + *(volatile unsigned char *)ptr = x; + local_irq_restore(flags); + break; + + case 4: + local_irq_save(flags); + ret = *(volatile unsigned long *)ptr; + *(volatile unsigned long *)ptr = x; + local_irq_restore(flags); + break; +#else + case 1: __asm__ __volatile__ ("swpb %0, %1, [%2]" + : "=&r" (ret) + : "r" (x), "r" (ptr) + : "memory", "cc"); + break; + case 4: __asm__ __volatile__ ("swp %0, %1, [%2]" + : "=&r" (ret) + : "r" (x), "r" (ptr) + : "memory", "cc"); + break; +#endif + default: __bad_xchg(ptr, size), ret = 0; + } + + return ret; +} + #endif /* CONFIG_SMP */ + +#endif /* __ASSEMBLY__ */ #endif /* __KERNEL__ */ diff -Nru a/include/asm-arm/thread_info.h b/include/asm-arm/thread_info.h --- a/include/asm-arm/thread_info.h Thu Sep 4 15:38:33 2003 +++ b/include/asm-arm/thread_info.h Thu Sep 4 15:38:33 2003 @@ -18,9 +18,9 @@ struct exec_domain; #include -#include #include #include +#include typedef unsigned long mm_segment_t; @@ -55,17 +55,19 @@ union fp_state fpstate; }; -#define INIT_THREAD_INFO(tsk) \ -{ \ - .task = &tsk, \ - .exec_domain = &default_exec_domain, \ - .flags = 0, \ - .preempt_count = 1, \ - .addr_limit = KERNEL_DS, \ - .restart_block = { \ - .fn = do_no_restart_syscall, \ - }, \ - INIT_EXTRA_THREAD_INFO, \ +#define INIT_THREAD_INFO(tsk) \ +{ \ + .task = &tsk, \ + .exec_domain = &default_exec_domain, \ + .flags = 0, \ + .preempt_count = 1, \ + .addr_limit = KERNEL_DS, \ + .cpu_domain = domain_val(DOMAIN_USER, DOMAIN_MANAGER) | \ + domain_val(DOMAIN_KERNEL, DOMAIN_MANAGER) | \ + domain_val(DOMAIN_IO, DOMAIN_CLIENT), \ + .restart_block = { \ + .fn = do_no_restart_syscall, \ + }, \ } #define init_thread_info (init_thread_union.thread_info) diff -Nru a/include/asm-arm/tlbflush.h b/include/asm-arm/tlbflush.h --- a/include/asm-arm/tlbflush.h Thu Sep 4 15:38:31 2003 +++ b/include/asm-arm/tlbflush.h Thu Sep 4 15:38:41 2003 @@ -1,7 +1,7 @@ /* * linux/include/asm-arm/tlbflush.h * - * Copyright (C) 2000-2002 Russell King + * Copyright (C) 1999-2003 Russell King * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as @@ -10,6 +10,397 @@ #ifndef _ASMARM_TLBFLUSH_H #define _ASMARM_TLBFLUSH_H -#include +#include +#include + +#define TLB_V3_PAGE (1 << 0) +#define TLB_V4_U_PAGE (1 << 1) +#define TLB_V4_D_PAGE (1 << 2) +#define TLB_V4_I_PAGE (1 << 3) +#define TLB_V6_U_PAGE (1 << 4) +#define TLB_V6_D_PAGE (1 << 5) +#define TLB_V6_I_PAGE (1 << 6) + +#define TLB_V3_FULL (1 << 8) +#define TLB_V4_U_FULL (1 << 9) +#define TLB_V4_D_FULL (1 << 10) +#define TLB_V4_I_FULL (1 << 11) +#define TLB_V6_U_FULL (1 << 12) +#define TLB_V6_D_FULL (1 << 13) +#define TLB_V6_I_FULL (1 << 14) + +#define TLB_V6_U_ASID (1 << 16) +#define TLB_V6_D_ASID (1 << 17) +#define TLB_V6_I_ASID (1 << 18) + +#define TLB_DCLEAN (1 << 30) +#define TLB_WB (1 << 31) + +/* + * MMU TLB Model + * ============= + * + * We have the following to choose from: + * v3 - ARMv3 + * v4 - ARMv4 without write buffer + * v4wb - ARMv4 with write buffer without I TLB flush entry instruction + * v4wbi - ARMv4 with write buffer with I TLB flush entry instruction + * v6wbi - ARMv6 with write buffer with I TLB flush entry instruction + */ +#undef _TLB +#undef MULTI_TLB + +#define v3_tlb_flags (TLB_V3_FULL | TLB_V3_PAGE) + +#if defined(CONFIG_CPU_ARM610) || defined(CONFIG_CPU_ARM710) +# define v3_possible_flags v3_tlb_flags +# define v3_always_flags v3_tlb_flags +# ifdef _TLB +# define MULTI_TLB 1 +# else +# define _TLB v3 +# endif +#else +# define v3_possible_flags 0 +# define v3_always_flags (-1UL) +#endif + +#define v4_tlb_flags (TLB_V4_U_FULL | TLB_V4_U_PAGE) + +#if defined(CONFIG_CPU_ARM720T) +# define v4_possible_flags v4_tlb_flags +# define v4_always_flags v4_tlb_flags +# ifdef _TLB +# define MULTI_TLB 1 +# else +# define _TLB v4 +# endif +#else +# define v4_possible_flags 0 +# define v4_always_flags (-1UL) +#endif + +#define v4wbi_tlb_flags (TLB_WB | TLB_DCLEAN | \ + TLB_V4_I_FULL | TLB_V4_D_FULL | \ + TLB_V4_I_PAGE | TLB_V4_D_PAGE) + +#if defined(CONFIG_CPU_ARM920T) || defined(CONFIG_CPU_ARM922T) || \ + defined(CONFIG_CPU_ARM926T) || defined(CONFIG_CPU_ARM1020) || \ + defined(CONFIG_CPU_XSCALE) +# define v4wbi_possible_flags v4wbi_tlb_flags +# define v4wbi_always_flags v4wbi_tlb_flags +# ifdef _TLB +# define MULTI_TLB 1 +# else +# define _TLB v4wbi +# endif +#else +# define v4wbi_possible_flags 0 +# define v4wbi_always_flags (-1UL) +#endif + +#define v4wb_tlb_flags (TLB_WB | TLB_DCLEAN | \ + TLB_V4_I_FULL | TLB_V4_D_FULL | \ + TLB_V4_D_PAGE) + +#if defined(CONFIG_CPU_SA110) || defined(CONFIG_CPU_SA1100) +# define v4wb_possible_flags v4wb_tlb_flags +# define v4wb_always_flags v4wb_tlb_flags +# ifdef _TLB +# define MULTI_TLB 1 +# else +# define _TLB v4wb +# endif +#else +# define v4wb_possible_flags 0 +# define v4wb_always_flags (-1UL) +#endif + +#define v6wbi_tlb_flags (TLB_WB | TLB_DCLEAN | \ + TLB_V6_I_FULL | TLB_V6_D_FULL | \ + TLB_V6_I_PAGE | TLB_V6_D_PAGE | \ + TLB_V6_I_ASID | TLB_V6_D_ASID) + +#if defined(CONFIG_CPU_V6) +# define v6wbi_possible_flags v6wbi_tlb_flags +# define v6wbi_always_flags v6wbi_tlb_flags +# ifdef _TLB +# define MULTI_TLB 1 +# else +# define _TLB v6wbi +# endif +#else +# define v6wbi_possible_flags 0 +# define v6wbi_always_flags (-1UL) +#endif + +#ifndef _TLB +#error Unknown TLB model +#endif + +#ifndef __ASSEMBLY__ + +struct cpu_tlb_fns { + void (*flush_user_range)(unsigned long, unsigned long, struct vm_area_struct *); + void (*flush_kern_range)(unsigned long, unsigned long); + unsigned long tlb_flags; +}; + +/* + * Select the calling method + */ +#ifdef MULTI_TLB + +#define __cpu_flush_user_tlb_range cpu_tlb.flush_user_range +#define __cpu_flush_kern_tlb_range cpu_tlb.flush_kern_range + +#else + +#define __cpu_flush_user_tlb_range __glue(_TLB,_flush_user_tlb_range) +#define __cpu_flush_kern_tlb_range __glue(_TLB,_flush_kern_tlb_range) + +extern void __cpu_flush_user_tlb_range(unsigned long, unsigned long, struct vm_area_struct *); +extern void __cpu_flush_kern_tlb_range(unsigned long, unsigned long); + +#endif + +extern struct cpu_tlb_fns cpu_tlb; + +#define __cpu_tlb_flags cpu_tlb.tlb_flags + +/* + * TLB Management + * ============== + * + * The arch/arm/mm/tlb-*.S files implement these methods. + * + * The TLB specific code is expected to perform whatever tests it + * needs to determine if it should invalidate the TLB for each + * call. Start addresses are inclusive and end addresses are + * exclusive; it is safe to round these addresses down. + * + * flush_tlb_all() + * + * Invalidate the entire TLB. + * + * flush_tlb_mm(mm) + * + * Invalidate all TLB entries in a particular address + * space. + * - mm - mm_struct describing address space + * + * flush_tlb_range(mm,start,end) + * + * Invalidate a range of TLB entries in the specified + * address space. + * - mm - mm_struct describing address space + * - start - start address (may not be aligned) + * - end - end address (exclusive, may not be aligned) + * + * flush_tlb_page(vaddr,vma) + * + * Invalidate the specified page in the specified address range. + * - vaddr - virtual address (may not be aligned) + * - vma - vma_struct describing address range + * + * flush_kern_tlb_page(kaddr) + * + * Invalidate the TLB entry for the specified page. The address + * will be in the kernels virtual memory space. Current uses + * only require the D-TLB to be invalidated. + * - kaddr - Kernel virtual memory address + */ + +/* + * We optimise the code below by: + * - building a set of TLB flags that might be set in __cpu_tlb_flags + * - building a set of TLB flags that will always be set in __cpu_tlb_flags + * - if we're going to need __cpu_tlb_flags, access it once and only once + * + * This allows us to build optimal assembly for the single-CPU type case, + * and as close to optimal given the compiler constrants for multi-CPU + * case. We could do better for the multi-CPU case if the compiler + * implemented the "%?" method, but this has been discontinued due to too + * many people getting it wrong. + */ +#define possible_tlb_flags (v3_possible_flags | \ + v4_possible_flags | \ + v4wbi_possible_flags | \ + v4wb_possible_flags | \ + v6wbi_possible_flags) + +#define always_tlb_flags (v3_always_flags & \ + v4_always_flags & \ + v4wbi_always_flags & \ + v4wb_always_flags & \ + v6wbi_always_flags) + +#define tlb_flag(f) ((always_tlb_flags & (f)) || (__tlb_flag & possible_tlb_flags & (f))) + +static inline void flush_tlb_all(void) +{ + const int zero = 0; + const unsigned int __tlb_flag = __cpu_tlb_flags; + + if (tlb_flag(TLB_WB)) + asm("mcr%? p15, 0, %0, c7, c10, 4" : : "r" (zero)); + + if (tlb_flag(TLB_V3_FULL)) + asm("mcr%? p15, 0, %0, c6, c0, 0" : : "r" (zero)); + if (tlb_flag(TLB_V4_U_FULL | TLB_V6_U_FULL)) + asm("mcr%? p15, 0, %0, c8, c7, 0" : : "r" (zero)); + if (tlb_flag(TLB_V4_D_FULL | TLB_V6_D_FULL)) + asm("mcr%? p15, 0, %0, c8, c6, 0" : : "r" (zero)); + if (tlb_flag(TLB_V4_I_FULL | TLB_V6_I_FULL)) + asm("mcr%? p15, 0, %0, c8, c5, 0" : : "r" (zero)); +} + +static inline void flush_tlb_mm(struct mm_struct *mm) +{ + const int zero = 0; + const int asid = ASID(mm); + const unsigned int __tlb_flag = __cpu_tlb_flags; + + if (tlb_flag(TLB_WB)) + asm("mcr%? p15, 0, %0, c7, c10, 4" : : "r" (zero)); + + if (mm == current->active_mm) { + if (tlb_flag(TLB_V3_FULL)) + asm("mcr%? p15, 0, %0, c6, c0, 0" : : "r" (zero)); + if (tlb_flag(TLB_V4_U_FULL)) + asm("mcr%? p15, 0, %0, c8, c7, 0" : : "r" (zero)); + if (tlb_flag(TLB_V4_D_FULL)) + asm("mcr%? p15, 0, %0, c8, c6, 0" : : "r" (zero)); + if (tlb_flag(TLB_V4_I_FULL)) + asm("mcr%? p15, 0, %0, c8, c5, 0" : : "r" (zero)); + } + + if (tlb_flag(TLB_V6_U_ASID)) + asm("mcr%? p15, 0, %0, c8, c7, 2" : : "r" (asid)); + if (tlb_flag(TLB_V6_D_ASID)) + asm("mcr%? p15, 0, %0, c8, c6, 2" : : "r" (asid)); + if (tlb_flag(TLB_V6_I_ASID)) + asm("mcr%? p15, 0, %0, c8, c5, 2" : : "r" (asid)); +} + +static inline void +flush_tlb_page(struct vm_area_struct *vma, unsigned long uaddr) +{ + const int zero = 0; + const unsigned int __tlb_flag = __cpu_tlb_flags; + + uaddr = (uaddr & PAGE_MASK) | ASID(vma->vm_mm); + + if (tlb_flag(TLB_WB)) + asm("mcr%? p15, 0, %0, c7, c10, 4" : : "r" (zero)); + + if (vma->vm_mm == current->active_mm) { + if (tlb_flag(TLB_V3_PAGE)) + asm("mcr%? p15, 0, %0, c6, c0, 0" : : "r" (uaddr)); + if (tlb_flag(TLB_V4_U_PAGE)) + asm("mcr%? p15, 0, %0, c8, c7, 1" : : "r" (uaddr)); + if (tlb_flag(TLB_V4_D_PAGE)) + asm("mcr%? p15, 0, %0, c8, c6, 1" : : "r" (uaddr)); + if (tlb_flag(TLB_V4_I_PAGE)) + asm("mcr%? p15, 0, %0, c8, c5, 1" : : "r" (uaddr)); + if (!tlb_flag(TLB_V4_I_PAGE) && tlb_flag(TLB_V4_I_FULL)) + asm("mcr%? p15, 0, %0, c8, c5, 0" : : "r" (zero)); + } + + if (tlb_flag(TLB_V6_U_PAGE)) + asm("mcr%? p15, 0, %0, c8, c7, 1" : : "r" (uaddr)); + if (tlb_flag(TLB_V6_D_PAGE)) + asm("mcr%? p15, 0, %0, c8, c6, 1" : : "r" (uaddr)); + if (tlb_flag(TLB_V6_I_PAGE)) + asm("mcr%? p15, 0, %0, c8, c5, 1" : : "r" (uaddr)); +} + +static inline void flush_tlb_kernel_page(unsigned long kaddr) +{ + const int zero = 0; + const unsigned int __tlb_flag = __cpu_tlb_flags; + + kaddr &= PAGE_MASK; + + if (tlb_flag(TLB_WB)) + asm("mcr%? p15, 0, %0, c7, c10, 4" : : "r" (zero)); + + if (tlb_flag(TLB_V3_PAGE)) + asm("mcr%? p15, 0, %0, c6, c0, 0" : : "r" (kaddr)); + if (tlb_flag(TLB_V4_U_PAGE)) + asm("mcr%? p15, 0, %0, c8, c7, 1" : : "r" (kaddr)); + if (tlb_flag(TLB_V4_D_PAGE)) + asm("mcr%? p15, 0, %0, c8, c6, 1" : : "r" (kaddr)); + if (tlb_flag(TLB_V4_I_PAGE)) + asm("mcr%? p15, 0, %0, c8, c5, 1" : : "r" (kaddr)); + if (!tlb_flag(TLB_V4_I_PAGE) && tlb_flag(TLB_V4_I_FULL)) + asm("mcr%? p15, 0, %0, c8, c5, 0" : : "r" (zero)); + + if (tlb_flag(TLB_V6_U_PAGE)) + asm("mcr%? p15, 0, %0, c8, c7, 1" : : "r" (kaddr)); + if (tlb_flag(TLB_V6_D_PAGE)) + asm("mcr%? p15, 0, %0, c8, c6, 1" : : "r" (kaddr)); + if (tlb_flag(TLB_V6_I_PAGE)) + asm("mcr%? p15, 0, %0, c8, c5, 1" : : "r" (kaddr)); +} + +/* + * flush_pmd_entry + * + * Flush a PMD entry (word aligned, or double-word aligned) to + * RAM if the TLB for the CPU we are running on requires this. + * This is typically used when we are creating PMD entries. + * + * clean_pmd_entry + * + * Clean (but don't drain the write buffer) if the CPU requires + * these operations. This is typically used when we are removing + * PMD entries. + */ +static inline void flush_pmd_entry(pmd_t *pmd) +{ + const unsigned int zero = 0; + const unsigned int __tlb_flag = __cpu_tlb_flags; + + if (tlb_flag(TLB_DCLEAN)) + asm("mcr%? p15, 0, %0, c7, c10, 1 @ flush_pmd" + : : "r" (pmd)); + if (tlb_flag(TLB_WB)) + asm("mcr%? p15, 0, %0, c7, c10, 4 @ flush_pmd" + : : "r" (zero)); +} + +static inline void clean_pmd_entry(pmd_t *pmd) +{ + const unsigned int __tlb_flag = __cpu_tlb_flags; + + if (tlb_flag(TLB_DCLEAN)) + asm("mcr%? p15, 0, %0, c7, c10, 1 @ flush_pmd" + : : "r" (pmd)); +} + +#undef tlb_flag +#undef always_tlb_flags +#undef possible_tlb_flags + +/* + * Convert calls to our calling convention. + */ +#define flush_tlb_range(vma,start,end) __cpu_flush_user_tlb_range(start,end,vma) +#define flush_tlb_kernel_range(s,e) __cpu_flush_kern_tlb_range(s,e) + +/* + * if PG_dcache_dirty is set for the page, we need to ensure that any + * cache entries for the kernels virtual memory range are written + * back to the page. + */ +extern void update_mmu_cache(struct vm_area_struct *vma, unsigned long addr, pte_t pte); + +/* + * ARM processors do not cache TLB tables in RAM. + */ +#define flush_tlb_pgtables(mm,start,end) do { } while (0) + +#endif #endif diff -Nru a/include/asm-arm/uaccess.h b/include/asm-arm/uaccess.h --- a/include/asm-arm/uaccess.h Thu Sep 4 15:38:38 2003 +++ b/include/asm-arm/uaccess.h Thu Sep 4 15:38:38 2003 @@ -1,3 +1,10 @@ +/* + * linux/include/asm-arm/uaccess.h + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ #ifndef _ASMARM_UACCESS_H #define _ASMARM_UACCESS_H @@ -6,6 +13,8 @@ */ #include #include +#include +#include #define VERIFY_READ 0 #define VERIFY_WRITE 1 @@ -30,11 +39,39 @@ extern int fixup_exception(struct pt_regs *regs); +/* + * Note that this is actually 0x1,0000,0000 + */ +#define KERNEL_DS 0x00000000 +#define USER_DS TASK_SIZE + #define get_ds() (KERNEL_DS) #define get_fs() (current_thread_info()->addr_limit) + +static inline void set_fs (mm_segment_t fs) +{ + current_thread_info()->addr_limit = fs; + modify_domain(DOMAIN_KERNEL, fs ? DOMAIN_CLIENT : DOMAIN_MANAGER); +} + #define segment_eq(a,b) ((a) == (b)) -#include +#define __addr_ok(addr) ({ \ + unsigned long flag; \ + __asm__("cmp %2, %0; movlo %0, #0" \ + : "=&r" (flag) \ + : "0" (current_thread_info()->addr_limit), "r" (addr) \ + : "cc"); \ + (flag == 0); }) + +/* We use 33-bit arithmetic here... */ +#define __range_ok(addr,size) ({ \ + unsigned long flag, sum; \ + __asm__("adds %1, %2, %3; sbcccs %1, %1, %0; movcc %0, #0" \ + : "=&r" (flag), "=&r" (sum) \ + : "r" (addr), "Ir" (size), "0" (current_thread_info()->addr_limit) \ + : "cc"); \ + flag; }) #define access_ok(type,addr,size) (__range_ok(addr,size) == 0) @@ -125,17 +162,71 @@ (x) = (__typeof__(*(ptr)))__gu_val; \ } while (0) +#define __get_user_asm_byte(x,addr,err) \ + __asm__ __volatile__( \ + "1: ldrbt %1,[%2],#0\n" \ + "2:\n" \ + " .section .fixup,\"ax\"\n" \ + " .align 2\n" \ + "3: mov %0, %3\n" \ + " mov %1, #0\n" \ + " b 2b\n" \ + " .previous\n" \ + " .section __ex_table,\"a\"\n" \ + " .align 3\n" \ + " .long 1b, 3b\n" \ + " .previous" \ + : "+r" (err), "=&r" (x) \ + : "r" (addr), "i" (-EFAULT) \ + : "cc") + +#ifndef __ARMEB__ +#define __get_user_asm_half(x,__gu_addr,err) \ +({ \ + unsigned long __b1, __b2; \ + __get_user_asm_byte(__b1, __gu_addr, err); \ + __get_user_asm_byte(__b2, __gu_addr + 1, err); \ + (x) = __b1 | (__b2 << 8); \ +}) +#else +#define __get_user_asm_half(x,__gu_addr,err) \ +({ \ + unsigned long __b1, __b2; \ + __get_user_asm_byte(__b1, __gu_addr, err); \ + __get_user_asm_byte(__b2, __gu_addr + 1, err); \ + (x) = (__b1 << 8) | __b2; \ +}) +#endif + +#define __get_user_asm_word(x,addr,err) \ + __asm__ __volatile__( \ + "1: ldrt %1,[%2],#0\n" \ + "2:\n" \ + " .section .fixup,\"ax\"\n" \ + " .align 2\n" \ + "3: mov %0, %3\n" \ + " mov %1, #0\n" \ + " b 2b\n" \ + " .previous\n" \ + " .section __ex_table,\"a\"\n" \ + " .align 3\n" \ + " .long 1b, 3b\n" \ + " .previous" \ + : "+r" (err), "=&r" (x) \ + : "r" (addr), "i" (-EFAULT) \ + : "cc") + extern int __put_user_1(void *, unsigned int); extern int __put_user_2(void *, unsigned int); extern int __put_user_4(void *, unsigned int); extern int __put_user_8(void *, unsigned long long); extern int __put_user_bad(void); -#define __put_user_x(__r1,__p,__e,__s,__i...) \ +#define __put_user_x(__r1,__p,__e,__s) \ __asm__ __volatile__ ("bl __put_user_" #__s \ : "=&r" (__e) \ : "0" (__p), "r" (__r1) \ - : __i, "cc") + : "ip", "lr", "cc") #define put_user(x,p) \ ({ \ @@ -144,16 +235,16 @@ register int __e asm("r0"); \ switch (sizeof(*(__p))) { \ case 1: \ - __put_user_x(__r1, __p, __e, 1, "ip", "lr"); \ + __put_user_x(__r1, __p, __e, 1); \ break; \ case 2: \ - __put_user_x(__r1, __p, __e, 2, "ip", "lr"); \ + __put_user_x(__r1, __p, __e, 2); \ break; \ case 4: \ - __put_user_x(__r1, __p, __e, 4, "ip", "lr"); \ + __put_user_x(__r1, __p, __e, 4); \ break; \ case 8: \ - __put_user_x(__r1, __p, __e, 8, "ip", "lr"); \ + __put_user_x(__r1, __p, __e, 8); \ break; \ default: __e = __put_user_bad(); break; \ } \ @@ -186,10 +277,93 @@ } \ } while (0) +#define __put_user_asm_byte(x,__pu_addr,err) \ + __asm__ __volatile__( \ + "1: strbt %1,[%2],#0\n" \ + "2:\n" \ + " .section .fixup,\"ax\"\n" \ + " .align 2\n" \ + "3: mov %0, %3\n" \ + " b 2b\n" \ + " .previous\n" \ + " .section __ex_table,\"a\"\n" \ + " .align 3\n" \ + " .long 1b, 3b\n" \ + " .previous" \ + : "+r" (err) \ + : "r" (x), "r" (__pu_addr), "i" (-EFAULT) \ + : "cc") + +#ifndef __ARMEB__ +#define __put_user_asm_half(x,__pu_addr,err) \ +({ \ + unsigned long __temp = (unsigned long)(x); \ + __put_user_asm_byte(__temp, __pu_addr, err); \ + __put_user_asm_byte(__temp >> 8, __pu_addr + 1, err); \ +}) +#else +#define __put_user_asm_half(x,__pu_addr,err) \ +({ \ + unsigned long __temp = (unsigned long)(x); \ + __put_user_asm_byte(__temp >> 8, __pu_addr, err); \ + __put_user_asm_byte(__temp, __pu_addr + 1, err); \ +}) +#endif + +#define __put_user_asm_word(x,__pu_addr,err) \ + __asm__ __volatile__( \ + "1: strt %1,[%2],#0\n" \ + "2:\n" \ + " .section .fixup,\"ax\"\n" \ + " .align 2\n" \ + "3: mov %0, %3\n" \ + " b 2b\n" \ + " .previous\n" \ + " .section __ex_table,\"a\"\n" \ + " .align 3\n" \ + " .long 1b, 3b\n" \ + " .previous" \ + : "+r" (err) \ + : "r" (x), "r" (__pu_addr), "i" (-EFAULT) \ + : "cc") + +#ifndef __ARMEB__ +#define __reg_oper0 "%R2" +#define __reg_oper1 "%Q2" +#else +#define __reg_oper0 "%Q2" +#define __reg_oper1 "%R2" +#endif + +#define __put_user_asm_dword(x,__pu_addr,err) \ + __asm__ __volatile__( \ + "1: strt " __reg_oper1 ", [%1], #4\n" \ + "2: strt " __reg_oper0 ", [%1], #0\n" \ + "3:\n" \ + " .section .fixup,\"ax\"\n" \ + " .align 2\n" \ + "4: mov %0, %3\n" \ + " b 3b\n" \ + " .previous\n" \ + " .section __ex_table,\"a\"\n" \ + " .align 3\n" \ + " .long 1b, 4b\n" \ + " .long 2b, 4b\n" \ + " .previous" \ + : "+r" (err), "+r" (__pu_addr) \ + : "r" (x), "i" (-EFAULT) \ + : "cc") + +extern unsigned long __arch_copy_from_user(void *to, const void *from, unsigned long n); +extern unsigned long __arch_copy_to_user(void *to, const void *from, unsigned long n); +extern unsigned long __arch_clear_user(void *addr, unsigned long n); +extern unsigned long __arch_strncpy_from_user(char *to, const char *from, unsigned long count); +extern unsigned long __arch_strnlen_user(const char *s, long n); + static __inline__ unsigned long copy_from_user(void *to, const void *from, unsigned long n) { if (access_ok(VERIFY_READ, from, n)) - __do_copy_from_user(to, from, n); + n = __arch_copy_from_user(to, from, n); else /* security hole - plug it */ memzero(to, n); return n; @@ -197,49 +371,44 @@ static __inline__ unsigned long __copy_from_user(void *to, const void *from, unsigned long n) { - __do_copy_from_user(to, from, n); - return n; + return __arch_copy_from_user(to, from, n); } static __inline__ unsigned long copy_to_user(void *to, const void *from, unsigned long n) { if (access_ok(VERIFY_WRITE, to, n)) - __do_copy_to_user(to, from, n); + n = __arch_copy_to_user(to, from, n); return n; } static __inline__ unsigned long __copy_to_user(void *to, const void *from, unsigned long n) { - __do_copy_to_user(to, from, n); - return n; + return __arch_copy_to_user(to, from, n); } static __inline__ unsigned long clear_user (void *to, unsigned long n) { if (access_ok(VERIFY_WRITE, to, n)) - __do_clear_user(to, n); + n = __arch_clear_user(to, n); return n; } static __inline__ unsigned long __clear_user (void *to, unsigned long n) { - __do_clear_user(to, n); - return n; + return __arch_clear_user(to, n); } static __inline__ long strncpy_from_user (char *dst, const char *src, long count) { long res = -EFAULT; if (access_ok(VERIFY_READ, src, 1)) - __do_strncpy_from_user(dst, src, count, res); + res = __arch_strncpy_from_user(dst, src, count); return res; } static __inline__ long __strncpy_from_user (char *dst, const char *src, long count) { - long res; - __do_strncpy_from_user(dst, src, count, res); - return res; + return __arch_strncpy_from_user(dst, src, count); } #define strlen_user(s) strnlen_user(s, ~0UL >> 1) @@ -249,7 +418,7 @@ unsigned long res = 0; if (__addr_ok(s)) - __do_strnlen_user(s, n, res); + res = __arch_strnlen_user(s, n); return res; } diff -Nru a/include/asm-arm/unistd.h b/include/asm-arm/unistd.h --- a/include/asm-arm/unistd.h Thu Sep 4 15:38:45 2003 +++ b/include/asm-arm/unistd.h Thu Sep 4 15:38:45 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 Thu Sep 4 15:38:33 2003 +++ b/include/asm-arm/xor.h Thu Sep 4 15:38:33 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 Thu Sep 4 15:38:36 2003 +++ b/include/asm-arm26/processor.h Thu Sep 4 15:38:36 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/semaphore.h b/include/asm-arm26/semaphore.h --- a/include/asm-arm26/semaphore.h Thu Sep 4 15:38:47 2003 +++ b/include/asm-arm26/semaphore.h Thu Sep 4 15:38:47 2003 @@ -84,7 +84,7 @@ #if WAITQUEUE_DEBUG CHECK_MAGIC(sem->__magic); #endif - + might_sleep(); __down_op(sem, __down_failed); } @@ -97,7 +97,7 @@ #if WAITQUEUE_DEBUG CHECK_MAGIC(sem->__magic); #endif - + might_sleep(); return __down_op_ret(sem, __down_interruptible_failed); } diff -Nru a/include/asm-arm26/xor.h b/include/asm-arm26/xor.h --- a/include/asm-arm26/xor.h Thu Sep 4 15:38:32 2003 +++ b/include/asm-arm26/xor.h Thu Sep 4 15:38:32 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-cris/semaphore.h b/include/asm-cris/semaphore.h --- a/include/asm-cris/semaphore.h Thu Sep 4 15:38:32 2003 +++ b/include/asm-cris/semaphore.h Thu Sep 4 15:38:32 2003 @@ -79,6 +79,7 @@ #if WAITQUEUE_DEBUG CHECK_MAGIC(sem->__magic); #endif + might_sleep(); /* atomically decrement the semaphores count, and if its negative, we wait */ local_save_flags(flags); @@ -104,6 +105,7 @@ #if WAITQUEUE_DEBUG CHECK_MAGIC(sem->__magic); #endif + might_sleep(); /* atomically decrement the semaphores count, and if its negative, we wait */ local_save_flags(flags); diff -Nru a/include/asm-h8300/aki3068net/ne.h b/include/asm-h8300/aki3068net/ne.h --- a/include/asm-h8300/aki3068net/ne.h Thu Sep 4 15:38:45 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 Thu Sep 4 15:38:40 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 Thu Sep 4 15:38:33 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 Thu Sep 4 15:38:48 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 Thu Sep 4 15:38:40 2003 +++ b/include/asm-h8300/h8max/machine-depend.h Thu Sep 4 15:38:40 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 Thu Sep 4 15:38:29 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 Thu Sep 4 15:38:46 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 Thu Sep 4 15:38:30 2003 +++ b/include/asm-h8300/ide.h Thu Sep 4 15:38:30 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 Thu Sep 4 15:38:30 2003 +++ b/include/asm-h8300/irq.h Thu Sep 4 15:38:30 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 Thu Sep 4 15:38:31 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 Thu Sep 4 15:38:35 2003 +++ b/include/asm-h8300/pci.h Thu Sep 4 15:38:35 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-h8300/semaphore.h b/include/asm-h8300/semaphore.h --- a/include/asm-h8300/semaphore.h Thu Sep 4 15:38:33 2003 +++ b/include/asm-h8300/semaphore.h Thu Sep 4 15:38:33 2003 @@ -90,6 +90,7 @@ #if WAITQUEUE_DEBUG CHECK_MAGIC(sem->__magic); #endif + might_sleep(); count = &(sem->count); __asm__ __volatile__( @@ -117,6 +118,7 @@ #if WAITQUEUE_DEBUG CHECK_MAGIC(sem->__magic); #endif + might_sleep(); count = &(sem->count); __asm__ __volatile__( diff -Nru a/include/asm-i386/apic.h b/include/asm-i386/apic.h --- a/include/asm-i386/apic.h Thu Sep 4 15:38:47 2003 +++ b/include/asm-i386/apic.h Thu Sep 4 15:38:47 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 Thu Sep 4 15:38:30 2003 +++ b/include/asm-i386/bugs.h Thu Sep 4 15:38:30 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 Thu Sep 4 15:38:48 2003 @@ -0,0 +1,115 @@ + +#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_HPET_EMULATE_RTC +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_HPET_EMULATE_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 Thu Sep 4 15:38:41 2003 +++ b/include/asm-i386/i387.h Thu Sep 4 15:38:41 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 Thu Sep 4 15:38:29 2003 +++ b/include/asm-i386/processor.h Thu Sep 4 15:38:29 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 Thu Sep 4 15:38:37 2003 +++ b/include/asm-i386/smp.h Thu Sep 4 15:38:37 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/termios.h b/include/asm-i386/termios.h --- a/include/asm-i386/termios.h Thu Sep 4 15:38:35 2003 +++ b/include/asm-i386/termios.h Thu Sep 4 15:38:35 2003 @@ -58,6 +58,7 @@ #define N_HCI 15 /* Bluetooth HCI UART */ #ifdef __KERNEL__ +#include /* intr=^C quit=^\ erase=del kill=^U eof=^D vtime=\0 vmin=\1 sxtc=\0 @@ -101,6 +102,8 @@ #define user_termios_to_kernel_termios(k, u) copy_from_user(k, u, sizeof(struct termios)) #define kernel_termios_to_user_termios(u, k) copy_to_user(u, k, sizeof(struct termios)) +#define MODULE_ALIAS_LDISC(ldisc) \ + MODULE_ALIAS("tty-ldisc-" __stringify(ldisc)) #endif /* __KERNEL__ */ #endif /* _I386_TERMIOS_H */ diff -Nru a/include/asm-i386/timer.h b/include/asm-i386/timer.h --- a/include/asm-i386/timer.h Thu Sep 4 15:38:31 2003 +++ b/include/asm-i386/timer.h Thu Sep 4 15:38:31 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 Thu Sep 4 15:38:33 2003 +++ b/include/asm-ia64/hw_irq.h Thu Sep 4 15:38:33 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 Thu Sep 4 15:38:45 2003 +++ b/include/asm-ia64/pci.h Thu Sep 4 15:38:45 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/semaphore.h b/include/asm-ia64/semaphore.h --- a/include/asm-ia64/semaphore.h Thu Sep 4 15:38:33 2003 +++ b/include/asm-ia64/semaphore.h Thu Sep 4 15:38:33 2003 @@ -73,6 +73,7 @@ #if WAITQUEUE_DEBUG CHECK_MAGIC(sem->__magic); #endif + might_sleep(); if (atomic_dec_return(&sem->count) < 0) __down(sem); } @@ -89,6 +90,7 @@ #if WAITQUEUE_DEBUG CHECK_MAGIC(sem->__magic); #endif + might_sleep(); if (atomic_dec_return(&sem->count) < 0) ret = __down_interruptible(sem); return ret; diff -Nru a/include/asm-ia64/unistd.h b/include/asm-ia64/unistd.h --- a/include/asm-ia64/unistd.h Thu Sep 4 15:38:29 2003 +++ b/include/asm-ia64/unistd.h Thu Sep 4 15:38:29 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 Thu Sep 4 15:38:48 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 Thu Sep 4 15:38:48 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/semaphore.h b/include/asm-m68k/semaphore.h --- a/include/asm-m68k/semaphore.h Thu Sep 4 15:38:47 2003 +++ b/include/asm-m68k/semaphore.h Thu Sep 4 15:38:47 2003 @@ -89,7 +89,7 @@ #if WAITQUEUE_DEBUG CHECK_MAGIC(sem->__magic); #endif - + might_sleep(); __asm__ __volatile__( "| atomic down operation\n\t" "subql #1,%0@\n\t" @@ -112,7 +112,7 @@ #if WAITQUEUE_DEBUG CHECK_MAGIC(sem->__magic); #endif - + might_sleep(); __asm__ __volatile__( "| atomic interruptible down operation\n\t" "subql #1,%1@\n\t" diff -Nru a/include/asm-m68k/system.h b/include/asm-m68k/system.h --- a/include/asm-m68k/system.h Thu Sep 4 15:38:40 2003 +++ b/include/asm-m68k/system.h Thu Sep 4 15:38:40 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 Thu Sep 4 15:38:35 2003 +++ b/include/asm-m68knommu/irq.h Thu Sep 4 15:38:35 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 Thu Sep 4 15:38:48 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 Thu Sep 4 15:38:48 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-m68knommu/semaphore.h b/include/asm-m68knommu/semaphore.h --- a/include/asm-m68knommu/semaphore.h Thu Sep 4 15:38:37 2003 +++ b/include/asm-m68knommu/semaphore.h Thu Sep 4 15:38:37 2003 @@ -88,7 +88,7 @@ #if WAITQUEUE_DEBUG CHECK_MAGIC(sem->__magic); #endif - + might_sleep(); __asm__ __volatile__( "| atomic down operation\n\t" "movel %0, %%a1\n\t" @@ -108,7 +108,7 @@ #if WAITQUEUE_DEBUG CHECK_MAGIC(sem->__magic); #endif - + might_sleep(); __asm__ __volatile__( "| atomic down operation\n\t" "movel %1, %%a1\n\t" diff -Nru a/include/asm-mips/semaphore.h b/include/asm-mips/semaphore.h --- a/include/asm-mips/semaphore.h Thu Sep 4 15:38:32 2003 +++ b/include/asm-mips/semaphore.h Thu Sep 4 15:38:32 2003 @@ -88,6 +88,7 @@ #if WAITQUEUE_DEBUG CHECK_MAGIC(sem->__magic); #endif + might_sleep(); if (atomic_dec_return(&sem->count) < 0) __down(sem); } @@ -103,6 +104,7 @@ #if WAITQUEUE_DEBUG CHECK_MAGIC(sem->__magic); #endif + might_sleep(); if (atomic_dec_return(&sem->count) < 0) ret = __down_interruptible(sem); return ret; diff -Nru a/include/asm-parisc/semaphore.h b/include/asm-parisc/semaphore.h --- a/include/asm-parisc/semaphore.h Thu Sep 4 15:38:28 2003 +++ b/include/asm-parisc/semaphore.h Thu Sep 4 15:38:28 2003 @@ -84,7 +84,7 @@ #if WAITQUEUE_DEBUG CHECK_MAGIC(sem->__magic); #endif - + might_sleep(); spin_lock_irq(&sem->sentry); if (sem->count > 0) { sem->count--; @@ -100,7 +100,7 @@ #if WAITQUEUE_DEBUG CHECK_MAGIC(sem->__magic); #endif - + might_sleep(); spin_lock_irq(&sem->sentry); if (sem->count > 0) { sem->count--; diff -Nru a/include/asm-ppc/cpm_8260.h b/include/asm-ppc/cpm_8260.h --- a/include/asm-ppc/cpm_8260.h Thu Sep 4 15:38:33 2003 +++ b/include/asm-ppc/cpm_8260.h Thu Sep 4 15:38:33 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/ibm44x.h b/include/asm-ppc/ibm44x.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/asm-ppc/ibm44x.h Thu Sep 4 15:38:48 2003 @@ -0,0 +1,435 @@ +/* + * include/asm-ppc/ibm44x.h + * + * PPC44x definitions + * + * Matt Porter + * + * Copyright 2002-2003 MontaVista Software 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 (at your + * option) any later version. + */ + +#ifdef __KERNEL__ +#ifndef __ASM_IBM44x_H__ +#define __ASM_IBM44x_H__ + +#include + +#ifndef __ASSEMBLY__ +/* + * Data structure defining board information maintained by the boot + * ROM on IBM's "Ebony" evaluation board. An effort has been made to + * keep the field names consistent with the 8xx 'bd_t' board info + * structures. + * + * Ebony firmware stores MAC addresses in the F/W VPD area. The + * firmware must store the other dynamic values in NVRAM like on + * the previous 40x systems so they should be accessible if we + * really want them. + */ +typedef struct board_info { + unsigned char bi_enetaddr[2][6]; /* EMAC addresses */ + unsigned int bi_opb_busfreq; /* OPB clock in Hz */ + int bi_iic_fast[2]; /* Use fast i2c mode */ +} bd_t; +#endif /* __ASSEMBLY__ */ + +#ifndef NR_BOARD_IRQS +#define NR_BOARD_IRQS 0 +#endif + +#define _IO_BASE isa_io_base +#define _ISA_MEM_BASE isa_mem_base +#define PCI_DRAM_OFFSET pci_dram_offset + +/* TLB entry offset/size used for pinning kernel lowmem */ +#define PPC44x_PIN_SHIFT 28 +#define PPC44x_PIN_SIZE (1 << PPC44x_PIN_SHIFT) + +/* Lowest TLB slot consumed by the default pinned TLBs */ +#define PPC44x_LOW_SLOT 62 + +/* + * Standard 4GB "page" definitions + */ +#define PPC44x_IO_PAGE 0x0000000100000000ULL +#define PPC44x_PCICFG_PAGE 0x0000000200000000ULL +#define PPC44x_PCIIO_PAGE PPC44x_PCICFG_PAGE +#define PPC44x_PCIMEM_PAGE 0x0000000300000000ULL + +/* + * 36-bit trap ranges + */ +#define PPC44x_IO_LO 0x40000000 +#define PPC44x_IO_HI 0x40001000 +#define PPC44x_PCICFG_LO 0x0ec00000 +#define PPC44x_PCICFG_HI 0x0ec7ffff +#define PPC44x_PCIMEM_LO 0x80002000 +#define PPC44x_PCIMEM_HI 0xffffffff + +/* + * The "residual" board information structure the boot loader passes + * into the kernel. + */ +#ifndef __ASSEMBLY__ + +/* + * SPRN definitions + */ +#define SPRN_CPC0_GPIO 0xe5/BEARLRL + +/* + * DCRN definitions + */ + +#ifdef CONFIG_440GX +/* SDRs */ +#define DCRN_SDR_CONFIG_ADDR 0xe +#define DCRN_SDR_CONFIG_DATA 0xf +#define DCRN_SDR_PFC0 0x4100 +#define DCRN_SDR_PFC1 0x4101 +#define DCRN_SDR_MFR 0x4300 +#define DCRN_SDR_MFR_TAH0 0x80000000 /* TAHOE0 Enable */ +#define DCRN_SDR_MFR_TAH1 0x40000000 /* TAHOE1 Enable */ +#define DCRN_SDR_MFR_PCM 0x10000000 /* PPC440GP irq compat mode */ +#define DCRN_SDR_MFR_ECS 0x08000000 /* EMAC int clk */ +#define DCRN_SDR_MFR_T0TXFL 0x00080000 +#define DCRN_SDR_MFR_T0TXFH 0x00040000 +#define DCRN_SDR_MFR_T1TXFL 0x00020000 +#define DCRN_SDR_MFR_T1TXFH 0x00010000 +#define DCRN_SDR_MFR_E0TXFL 0x00008000 +#define DCRN_SDR_MFR_E0TXFH 0x00004000 +#define DCRN_SDR_MFR_E0RXFL 0x00002000 +#define DCRN_SDR_MFR_E0RXFH 0x00001000 +#define DCRN_SDR_MFR_E1TXFL 0x00000800 +#define DCRN_SDR_MFR_E1TXFH 0x00000400 +#define DCRN_SDR_MFR_E1RXFL 0x00000200 +#define DCRN_SDR_MFR_E1RXFH 0x00000100 +#define DCRN_SDR_MFR_E2TXFL 0x00000080 +#define DCRN_SDR_MFR_E2TXFH 0x00000040 +#define DCRN_SDR_MFR_E2RXFL 0x00000020 +#define DCRN_SDR_MFR_E2RXFH 0x00000010 +#define DCRN_SDR_MFR_E3TXFL 0x00000008 +#define DCRN_SDR_MFR_E3TXFH 0x00000004 +#define DCRN_SDR_MFR_E3RXFL 0x00000002 +#define DCRN_SDR_MFR_E3RXFH 0x00000001 + +/* SDR read/write helper macros */ +#define SDR_READ(offset) ({\ + mtdcr(DCRN_SDR_CONFIG_ADDR, offset); \ + mfdcr(DCRN_SDR_CONFIG_DATA);}) +#define SDR_WRITE(offset, data) ({\ + mtdcr(DCRN_SDR_CONFIG_ADDR, offset); \ + mtdcr(DCRN_SDR_CONFIG_DATA,data);}) +#endif /* CONFIG_440GX */ + +/* Base DCRNs */ +#define DCRN_DMA0_BASE 0x100 +#define DCRN_DMA1_BASE 0x108 +#define DCRN_DMA2_BASE 0x110 +#define DCRN_DMA3_BASE 0x118 +#define DCRN_DMASR_BASE 0x120 +#define DCRNCAP_DMA_SG 1 /* have DMA scatter/gather capability */ +#define DCRN_MAL_BASE 0x180 + +/* UIC */ +#define DCRN_UIC0_BASE 0xc0 +#define DCRN_UIC1_BASE 0xd0 +#define UIC0 DCRN_UIC0_BASE +#define UIC1 DCRN_UIC1_BASE + +#define DCRN_UIC_SR(base) (base + 0x0) +#define DCRN_UIC_ER(base) (base + 0x2) +#define DCRN_UIC_CR(base) (base + 0x3) +#define DCRN_UIC_PR(base) (base + 0x4) +#define DCRN_UIC_TR(base) (base + 0x5) +#define DCRN_UIC_MSR(base) (base + 0x6) +#define DCRN_UIC_VR(base) (base + 0x7) +#define DCRN_UIC_VCR(base) (base + 0x8) + +#define UIC0_UIC1NC 30 /* UIC1 non-critical interrupt */ +#define UIC0_UIC1CR 31 /* UIC1 critical interrupt */ + +/* 440GP MAL DCRs */ +#define DCRN_MALCR(base) (base + 0x0) /* Configuration */ +#define DCRN_MALESR(base) (base + 0x1) /* Error Status */ +#define DCRN_MALIER(base) (base + 0x2) /* Interrupt Enable */ +#define DCRN_MALTXCASR(base) (base + 0x4) /* Tx Channel Active Set */ +#define DCRN_MALTXCARR(base) (base + 0x5) /* Tx Channel Active Reset */ +#define DCRN_MALTXEOBISR(base) (base + 0x6) /* Tx End of Buffer Interrupt Status */ +#define DCRN_MALTXDEIR(base) (base + 0x7) /* Tx Descriptor Error Interrupt */ +#define DCRN_MALRXCASR(base) (base + 0x10) /* Rx Channel Active Set */ +#define DCRN_MALRXCARR(base) (base + 0x11) /* Rx Channel Active Reset */ +#define DCRN_MALRXEOBISR(base) (base + 0x12) /* Rx End of Buffer Interrupt Status */ +#define DCRN_MALRXDEIR(base) (base + 0x13) /* Rx Descriptor Error Interrupt */ +#define DCRN_MALTXCTP0R(base) (base + 0x20) /* Channel Tx 0 Channel Table Pointer */ +#define DCRN_MALTXCTP1R(base) (base + 0x21) /* Channel Tx 1 Channel Table Pointer */ +#define DCRN_MALTXCTP2R(base) (base + 0x22) /* Channel Tx 2 Channel Table Pointer */ +#define DCRN_MALTXCTP3R(base) (base + 0x23) /* Channel Tx 3 Channel Table Pointer */ +#define DCRN_MALRXCTP0R(base) (base + 0x40) /* Channel Rx 0 Channel Table Pointer */ +#define DCRN_MALRXCTP1R(base) (base + 0x41) /* Channel Rx 1 Channel Table Pointer */ +#define DCRN_MALRCBS0(base) (base + 0x60) /* Channel Rx 0 Channel Buffer Size */ +#define DCRN_MALRCBS1(base) (base + 0x61) /* Channel Rx 1 Channel Buffer Size */ + +/* Compatibility DCRN's */ +#define DCRN_MALRXCTP2R(base) ((base) + 0x42) /* Channel Rx 2 Channel Table Pointer */ +#define DCRN_MALRXCTP3R(base) ((base) + 0x43) /* Channel Rx 3 Channel Table Pointer */ +#define DCRN_MALTXCTP4R(base) ((base) + 0x24) /* Channel Tx 4 Channel Table Pointer */ +#define DCRN_MALTXCTP5R(base) ((base) + 0x25) /* Channel Tx 5 Channel Table Pointer */ +#define DCRN_MALTXCTP6R(base) ((base) + 0x26) /* Channel Tx 6 Channel Table Pointer */ +#define DCRN_MALTXCTP7R(base) ((base) + 0x27) /* Channel Tx 7 Channel Table Pointer */ +#define DCRN_MALRCBS2(base) ((base) + 0x62) /* Channel Rx 2 Channel Buffer Size */ +#define DCRN_MALRCBS3(base) ((base) + 0x63) /* Channel Rx 3 Channel Buffer Size */ + + +#define MALCR_MMSR 0x80000000 /* MAL Software reset */ +#define MALCR_PLBP_1 0x00400000 /* MAL reqest priority: */ +#define MALCR_PLBP_2 0x00800000 /* lowsest is 00 */ +#define MALCR_PLBP_3 0x00C00000 /* highest */ +#define MALCR_GA 0x00200000 /* Guarded Active Bit */ +#define MALCR_OA 0x00100000 /* Ordered Active Bit */ +#define MALCR_PLBLE 0x00080000 /* PLB Lock Error Bit */ +#define MALCR_PLBLT_1 0x00040000 /* PLB Latency Timer */ +#define MALCR_PLBLT_2 0x00020000 +#define MALCR_PLBLT_3 0x00010000 +#define MALCR_PLBLT_4 0x00008000 +#ifdef CONFIG_440GP +#define MALCR_PLBLT_DEFAULT 0x00330000 /* PLB Latency Timer default */ +#else +#define MALCR_PLBLT_DEFAULT 0x00ff0000 /* PLB Latency Timer default */ +#endif +#define MALCR_PLBB 0x00004000 /* PLB Burst Deactivation Bit */ +#define MALCR_OPBBL 0x00000080 /* OPB Lock Bit */ +#define MALCR_EOPIE 0x00000004 /* End Of Packet Interrupt Enable */ +#define MALCR_LEA 0x00000002 /* Locked Error Active */ +#define MALCR_MSD 0x00000001 /* MAL Scroll Descriptor Bit */ +/* DCRN_MALESR */ +#define MALESR_EVB 0x80000000 /* Error Valid Bit */ +#define MALESR_CIDRX 0x40000000 /* Channel ID Receive */ +#define MALESR_DE 0x00100000 /* Descriptor Error */ +#define MALESR_OEN 0x00080000 /* OPB Non-Fullword Error */ +#define MALESR_OTE 0x00040000 /* OPB Timeout Error */ +#define MALESR_OSE 0x00020000 /* OPB Slave Error */ +#define MALESR_PEIN 0x00010000 /* PLB Bus Error Indication */ +#define MALESR_DEI 0x00000010 /* Descriptor Error Interrupt */ +#define MALESR_ONEI 0x00000008 /* OPB Non-Fullword Error Interrupt */ +#define MALESR_OTEI 0x00000004 /* OPB Timeout Error Interrupt */ +#define MALESR_OSEI 0x00000002 /* OPB Slace Error Interrupt */ +#define MALESR_PBEI 0x00000001 /* PLB Bus Error Interrupt */ +/* DCRN_MALIER */ +#define MALIER_DE 0x00000010 /* Descriptor Error Interrupt Enable */ +#define MALIER_NE 0x00000008 /* OPB Non-word Transfer Int Enable */ +#define MALIER_TE 0x00000004 /* OPB Time Out Error Interrupt Enable */ +#define MALIER_OPBE 0x00000002 /* OPB Slave Error Interrupt Enable */ +#define MALIER_PLBE 0x00000001 /* PLB Error Interrupt Enable */ +/* DCRN_MALTXEOBISR */ +#define MALOBISR_CH0 0x80000000 /* EOB channel 1 bit */ +#define MALOBISR_CH2 0x40000000 /* EOB channel 2 bit */ + +/* 440GP PLB Arbiter DCRs */ +#define DCRN_PLB0_REVID 0x082 /* PLB Arbiter Revision ID */ +#define DCRN_PLB0_ACR 0x083 /* PLB Arbiter Control */ +#define DCRN_PLB0_BESR 0x084 /* PLB Error Status */ +#define DCRN_PLB0_BEARL 0x086 /* PLB Error Address Low */ +#define DCRN_PLB0_BEAR DCRN_PLB0_BEARL /* 40x compatibility */ +#define DCRN_PLB0_BEARH 0x087 /* PLB Error Address High */ + +/* 440GP Clock, PM, chip control */ +#define DCRN_CPC0_SR 0x0b0 +#define DCRN_CPC0_ER 0x0b1 +#define DCRN_CPC0_FR 0x0b2 +#define DCRN_CPC0_SYS0 0x0e0 +#define DCRN_CPC0_SYS1 0x0e1 +#define DCRN_CPC0_CUST0 0x0e2 +#define DCRN_CPC0_CUST1 0x0e3 +#define DCRN_CPC0_STRP0 0x0e4 +#define DCRN_CPC0_STRP1 0x0e5 +#define DCRN_CPC0_STRP2 0x0e6 +#define DCRN_CPC0_STRP3 0x0e7 +#define DCRN_CPC0_GPIO 0x0e8 +#define DCRN_CPC0_PLB 0x0e9 +#define DCRN_CPC0_CR1 0x0ea +#define DCRN_CPC0_CR0 0x0eb +#define DCRN_CPC0_MIRQ0 0x0ec +#define DCRN_CPC0_MIRQ1 0x0ed +#define DCRN_CPC0_JTAGID 0x0ef + +/* 440GP DMA controller DCRs */ +#define DCRN_DMACR0 (DCRN_DMA0_BASE + 0x0) /* DMA Channel Control 0 */ +#define DCRN_DMACT0 (DCRN_DMA0_BASE + 0x1) /* DMA Count 0 */ +#define DCRN_DMASAH0 (DCRN_DMA0_BASE + 0x2) /* DMA Src Addr High 0 */ +#define DCRN_DMASA0 (DCRN_DMA0_BASE + 0x3) /* DMA Src Addr Low 0 */ +#define DCRN_DMADAH0 (DCRN_DMA0_BASE + 0x4) /* DMA Dest Addr High 0 */ +#define DCRN_DMADA0 (DCRN_DMA0_BASE + 0x5) /* DMA Dest Addr Low 0 */ +#define DCRN_ASGH0 (DCRN_DMA0_BASE + 0x6) /* DMA SG Desc Addr High 0 */ +#define DCRN_ASG0 (DCRN_DMA0_BASE + 0x7) /* DMA SG Desc Addr Low 0 */ + +#define DCRN_DMACR1 (DCRN_DMA1_BASE + 0x0) /* DMA Channel Control 1 */ +#define DCRN_DMACT1 (DCRN_DMA1_BASE + 0x1) /* DMA Count 1 */ +#define DCRN_DMASAH1 (DCRN_DMA1_BASE + 0x2) /* DMA Src Addr High 1 */ +#define DCRN_DMASA1 (DCRN_DMA1_BASE + 0x3) /* DMA Src Addr Low 1 */ +#define DCRN_DMADAH1 (DCRN_DMA1_BASE + 0x4) /* DMA Dest Addr High 1 */ +#define DCRN_DMADA1 (DCRN_DMA1_BASE + 0x5) /* DMA Dest Addr Low 1 */ +#define DCRN_ASGH1 (DCRN_DMA1_BASE + 0x6) /* DMA SG Desc Addr High 1 */ +#define DCRN_ASG1 (DCRN_DMA1_BASE + 0x7) /* DMA SG Desc Addr Low 1 */ + +#define DCRN_DMACR2 (DCRN_DMA2_BASE + 0x0) /* DMA Channel Control 2 */ +#define DCRN_DMACT2 (DCRN_DMA2_BASE + 0x1) /* DMA Count 2 */ +#define DCRN_DMASAH2 (DCRN_DMA2_BASE + 0x2) /* DMA Src Addr High 2 */ +#define DCRN_DMASA2 (DCRN_DMA2_BASE + 0x3) /* DMA Src Addr Low 2 */ +#define DCRN_DMADAH2 (DCRN_DMA2_BASE + 0x4) /* DMA Dest Addr High 2 */ +#define DCRN_DMADA2 (DCRN_DMA2_BASE + 0x5) /* DMA Dest Addr Low 2 */ +#define DCRN_ASGH2 (DCRN_DMA2_BASE + 0x6) /* DMA SG Desc Addr High 2 */ +#define DCRN_ASG2 (DCRN_DMA2_BASE + 0x7) /* DMA SG Desc Addr Low 2 */ + +#define DCRN_DMACR3 (DCRN_DMA3_BASE + 0x0) /* DMA Channel Control 3 */ +#define DCRN_DMACT3 (DCRN_DMA3_BASE + 0x1) /* DMA Count 3 */ +#define DCRN_DMASAH3 (DCRN_DMA3_BASE + 0x2) /* DMA Src Addr High 3 */ +#define DCRN_DMASA3 (DCRN_DMA3_BASE + 0x3) /* DMA Src Addr Low 3 */ +#define DCRN_DMADAH3 (DCRN_DMA3_BASE + 0x4) /* DMA Dest Addr High 3 */ +#define DCRN_DMADA3 (DCRN_DMA3_BASE + 0x5) /* DMA Dest Addr Low 3 */ +#define DCRN_ASGH3 (DCRN_DMA3_BASE + 0x6) /* DMA SG Desc Addr High 3 */ +#define DCRN_ASG3 (DCRN_DMA3_BASE + 0x7) /* DMA SG Desc Addr Low 3 */ + +#define DCRN_DMASR (DCRN_DMASR_BASE + 0x0) /* DMA Status Register */ +#define DCRN_ASGC (DCRN_DMASR_BASE + 0x3) /* DMA Scatter/Gather Command */ +#define DCRN_SLP (DCRN_DMASR_BASE + 0x5) /* DMA Sleep Register */ +#define DCRN_POL (DCRN_DMASR_BASE + 0x6) /* DMA Polarity Register */ + +/* 440GP DRAM controller DCRs */ +#define DCRN_SDRAM0_CFGADDR 0x010 +#define DCRN_SDRAM0_CFGDATA 0x011 + +#define SDRAM0_B0CR 0x40 +#define SDRAM0_B1CR 0x44 +#define SDRAM0_B2CR 0x48 +#define SDRAM0_B3CR 0x4c + +#define SDRAM_CONFIG_BANK_ENABLE 0x00000001 +#define SDRAM_CONFIG_SIZE_MASK 0x000e0000 +#define SDRAM_CONFIG_BANK_SIZE(reg) ((reg & SDRAM_CONFIG_SIZE_MASK) >> 17) +#define SDRAM_CONFIG_SIZE_8M 0x00000001 +#define SDRAM_CONFIG_SIZE_16M 0x00000002 +#define SDRAM_CONFIG_SIZE_32M 0x00000003 +#define SDRAM_CONFIG_SIZE_64M 0x00000004 +#define SDRAM_CONFIG_SIZE_128M 0x00000005 +#define SDRAM_CONFIG_SIZE_256M 0x00000006 +#define SDRAM_CONFIG_SIZE_512M 0x00000007 +#define PPC44x_MEM_SIZE_8M 0x00800000 +#define PPC44x_MEM_SIZE_16M 0x01000000 +#define PPC44x_MEM_SIZE_32M 0x02000000 +#define PPC44x_MEM_SIZE_64M 0x04000000 +#define PPC44x_MEM_SIZE_128M 0x08000000 +#define PPC44x_MEM_SIZE_256M 0x10000000 +#define PPC44x_MEM_SIZE_512M 0x20000000 + +/* + * PCI-X definitions + */ +#define PCIX0_REG_BASE 0x20ec80000ULL +#define PCIX0_REG_SIZE 0x200 + +#define PCIX0_VENDID 0x000 +#define PCIX0_DEVID 0x002 +#define PCIX0_COMMAND 0x004 +#define PCIX0_STATUS 0x006 +#define PCIX0_REVID 0x008 +#define PCIX0_CLS 0x009 +#define PCIX0_CACHELS 0x00c +#define PCIX0_LATTIM 0x00d +#define PCIX0_HDTYPE 0x00e +#define PCIX0_BIST 0x00f +#define PCIX0_BAR0L 0x010 +#define PCIX0_BAR0H 0x014 +#define PCIX0_BAR1 0x018 +#define PCIX0_BAR2L 0x01c +#define PCIX0_BAR2H 0x020 +#define PCIX0_BAR3 0x024 +#define PCIX0_CISPTR 0x028 +#define PCIX0_SBSYSVID 0x02c +#define PCIX0_SBSYSID 0x02e +#define PCIX0_EROMBA 0x030 +#define PCIX0_CAP 0x034 +#define PCIX0_RES0 0x035 +#define PCIX0_RES1 0x036 +#define PCIX0_RES2 0x038 +#define PCIX0_INTLN 0x03c +#define PCIX0_INTPN 0x03d +#define PCIX0_MINGNT 0x03e +#define PCIX0_MAXLTNCY 0x03f +#define PCIX0_BRDGOPT1 0x040 +#define PCIX0_BRDGOPT2 0x044 +#define PCIX0_ERREN 0x050 +#define PCIX0_ERRSTS 0x054 +#define PCIX0_PLBBESR 0x058 +#define PCIX0_PLBBEARL 0x05c +#define PCIX0_PLBBEARH 0x060 +#define PCIX0_POM0LAL 0x068 +#define PCIX0_POM0LAH 0x06c +#define PCIX0_POM0SA 0x070 +#define PCIX0_POM0PCIAL 0x074 +#define PCIX0_POM0PCIAH 0x078 +#define PCIX0_POM1LAL 0x07c +#define PCIX0_POM1LAH 0x080 +#define PCIX0_POM1SA 0x084 +#define PCIX0_POM1PCIAL 0x088 +#define PCIX0_POM1PCIAH 0x08c +#define PCIX0_POM2SA 0x090 +#define PCIX0_PIM0SAL 0x098 +#define PCIX0_PIM0SA PCIX0_PIM0SAL +#define PCIX0_PIM0LAL 0x09c +#define PCIX0_PIM0LAH 0x0a0 +#define PCIX0_PIM1SA 0x0a4 +#define PCIX0_PIM1LAL 0x0a8 +#define PCIX0_PIM1LAH 0x0ac +#define PCIX0_PIM2SAL 0x0b0 +#define PCIX0_PIM2SA PCIX0_PIM2SAL +#define PCIX0_PIM2LAL 0x0b4 +#define PCIX0_PIM2LAH 0x0b8 +#define PCIX0_OMCAPID 0x0c0 +#define PCIX0_OMNIPTR 0x0c1 +#define PCIX0_OMMC 0x0c2 +#define PCIX0_OMMA 0x0c4 +#define PCIX0_OMMUA 0x0c8 +#define PCIX0_OMMDATA 0x0cc +#define PCIX0_OMMEOI 0x0ce +#define PCIX0_PMCAPID 0x0d0 +#define PCIX0_PMNIPTR 0x0d1 +#define PCIX0_PMC 0x0d2 +#define PCIX0_PMCSR 0x0d4 +#define PCIX0_PMCSRBSE 0x0d6 +#define PCIX0_PMDATA 0x0d7 +#define PCIX0_PMSCRR 0x0d8 +#define PCIX0_CAPID 0x0dc +#define PCIX0_NIPTR 0x0dd +#define PCIX0_CMD 0x0de +#define PCIX0_STS 0x0e0 +#define PCIX0_IDR 0x0e4 +#define PCIX0_CID 0x0e8 +#define PCIX0_RID 0x0ec +#define PCIX0_PIM0SAH 0x0f8 +#define PCIX0_PIM2SAH 0x0fc +#define PCIX0_MSGIL 0x100 +#define PCIX0_MSGIH 0x104 +#define PCIX0_MSGOL 0x108 +#define PCIX0_MSGOH 0x10c +#define PCIX0_IM 0x1f8 + +#define IIC_OWN 0x55 +#define IIC_CLOCK 50 + +#undef NR_UICS +#define NR_UICS 2 +#define UIC_CASCADE_MASK 0x0003 /* bits 30 & 31 */ + +#define BD_EMAC_ADDR(e,i) bi_enetaddr[e][i] + +#include + +#endif /* __ASSEMBLY__ */ +#endif /* __ASM_IBM44x_H__ */ +#endif /* __KERNEL__ */ diff -Nru a/include/asm-ppc/ibm4xx.h b/include/asm-ppc/ibm4xx.h --- a/include/asm-ppc/ibm4xx.h Thu Sep 4 15:38:34 2003 +++ b/include/asm-ppc/ibm4xx.h Thu Sep 4 15:38:34 2003 @@ -122,7 +122,25 @@ #define PCI_DRAM_OFFSET 0 #endif +#elif CONFIG_44x + +#if defined(CONFIG_EBONY) +#include +#endif + +#if defined(CONFIG_OCOTEA) +#include +#endif #endif /* CONFIG_40x */ + +#ifndef __ASSEMBLY__ +/* + * The "residual" board information structure the boot loader passes + * into the kernel. + */ +extern bd_t __res; +#endif + #endif /* __ASM_IBM4XX_H__ */ #endif /* __KERNEL__ */ diff -Nru a/include/asm-ppc/io.h b/include/asm-ppc/io.h --- a/include/asm-ppc/io.h Thu Sep 4 15:38:43 2003 +++ b/include/asm-ppc/io.h Thu Sep 4 15:38:43 2003 @@ -4,9 +4,11 @@ #include #include +#include #include #include +#include #define SIO_CONFIG_RA 0x398 #define SIO_CONFIG_RD 0x399 @@ -22,7 +24,7 @@ #define PREP_ISA_MEM_BASE 0xc0000000 #define PREP_PCI_DRAM_OFFSET 0x80000000 -#if defined(CONFIG_40x) +#if defined(CONFIG_4xx) #include #elif defined(CONFIG_8xx) #include @@ -197,14 +199,17 @@ * Map in an area of physical address space, for accessing * I/O devices etc. */ -extern void *__ioremap(unsigned long address, unsigned long size, +extern void *__ioremap(phys_addr_t address, unsigned long size, unsigned long flags); -extern void *ioremap(unsigned long address, unsigned long size); +extern void *ioremap(phys_addr_t address, unsigned long size); +#ifdef CONFIG_44x +extern void *ioremap64(unsigned long long address, unsigned long size); +#endif #define ioremap_nocache(addr, size) ioremap((addr), (size)) extern void iounmap(void *addr); extern unsigned long iopa(unsigned long addr); extern unsigned long mm_ptov(unsigned long addr) __attribute__ ((const)); -extern void io_block_mapping(unsigned long virt, unsigned long phys, +extern void io_block_mapping(unsigned long virt, phys_addr_t phys, unsigned int size, int flags); /* diff -Nru a/include/asm-ppc/irq.h b/include/asm-ppc/irq.h --- a/include/asm-ppc/irq.h Thu Sep 4 15:38:29 2003 +++ b/include/asm-ppc/irq.h Thu Sep 4 15:38:29 2003 @@ -71,11 +71,11 @@ return (irq); } -#elif defined(CONFIG_440) -#include +#elif defined(CONFIG_44x) +#include -#define NR_UIC_IRQS 64 -#define NR_IRQS (NR_UIC_IRQS + NR_BOARD_IRQS) +#define NR_UIC_IRQS 32 +#define NR_IRQS ((NR_UIC_IRQS * NR_UICS) + NR_BOARD_IRQS) static __inline__ int irq_canonicalize(int irq) diff -Nru a/include/asm-ppc/macio.h b/include/asm-ppc/macio.h --- a/include/asm-ppc/macio.h Thu Sep 4 15:38:30 2003 +++ b/include/asm-ppc/macio.h Thu Sep 4 15:38:30 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/mmu.h b/include/asm-ppc/mmu.h --- a/include/asm-ppc/mmu.h Thu Sep 4 15:38:44 2003 +++ b/include/asm-ppc/mmu.h Thu Sep 4 15:38:44 2003 @@ -10,6 +10,18 @@ #ifndef __ASSEMBLY__ +/* + * Define physical address type. Machines using split size + * virtual/physical addressing like 32-bit virtual / 36-bit + * physical need a larger than native word size type. -Matt + */ +#ifndef CONFIG_PTE_64BIT +typedef unsigned long phys_addr_t; +#else +typedef unsigned long long phys_addr_t; +extern phys_addr_t fixup_bigphys_addr(phys_addr_t, phys_addr_t); +#endif + /* Default "unsigned long" context */ typedef unsigned long mm_context_t; @@ -319,6 +331,56 @@ #define TLB_I 0x00000004 /* Caching is inhibited */ #define TLB_M 0x00000002 /* Memory is coherent */ #define TLB_G 0x00000001 /* Memory is guarded from prefetch */ + +/* + * PPC440 support + */ +#define PPC44x_MMUCR_TID 0x000000ff +#define PPC44x_MMUCR_STS 0x00010000 + +#define PPC44x_TLB_PAGEID 0 +#define PPC44x_TLB_XLAT 1 +#define PPC44x_TLB_ATTRIB 2 + +/* Page identification fields */ +#define PPC44x_TLB_EPN_MASK 0xfffffc00 /* Effective Page Number */ +#define PPC44x_TLB_VALID 0x00000200 /* Valid flag */ +#define PPC44x_TLB_TS 0x00000100 /* Translation address space */ +#define PPC44x_TLB_PAGESZ_MASK 0x000000f0 +#define PPC44x_TLB_PAGESZ(x) (x << 4) +#define PPC44x_PAGESZ_1K 0 +#define PPC44x_PAGESZ_4K 1 +#define PPC44x_PAGESZ_16K 2 +#define PPC44x_PAGESZ_64K 3 +#define PPC44x_PAGESZ_256K 4 +#define PPC44x_PAGESZ_1M 5 +#define PPC44x_PAGESZ_16M 7 +#define PPC44x_PAGESZ_256M 9 + +/* Translation fields */ +#define PPC44x_TLB_RPN_MASK 0xfffffc00 /* Real Page Number */ +#define PPC44x_TLB_ERPN_MASK 0x0000000f + +/* Storage attribute and access control fields */ +#define PPC44x_TLB_ATTR_MASK 0x0000ff80 +#define PPC44x_TLB_U0 0x00008000 /* User 0 */ +#define PPC44x_TLB_U1 0x00004000 /* User 1 */ +#define PPC44x_TLB_U2 0x00002000 /* User 2 */ +#define PPC44x_TLB_U3 0x00001000 /* User 3 */ +#define PPC44x_TLB_W 0x00000800 /* Caching is write-through */ +#define PPC44x_TLB_I 0x00000400 /* Caching is inhibited */ +#define PPC44x_TLB_M 0x00000200 /* Memory is coherent */ +#define PPC44x_TLB_G 0x00000100 /* Memory is guarded */ +#define PPC44x_TLB_E 0x00000080 /* Memory is guarded */ + +#define PPC44x_TLB_PERM_MASK 0x0000003f +#define PPC44x_TLB_UX 0x00000020 /* User execution */ +#define PPC44x_TLB_UW 0x00000010 /* User write */ +#define PPC44x_TLB_UR 0x00000008 /* User read */ +#define PPC44x_TLB_SX 0x00000004 /* Super execution */ +#define PPC44x_TLB_SW 0x00000002 /* Super write */ +#define PPC44x_TLB_SR 0x00000001 /* Super read */ + #endif /* _PPC_MMU_H_ */ #endif /* __KERNEL__ */ diff -Nru a/include/asm-ppc/of_device.h b/include/asm-ppc/of_device.h --- a/include/asm-ppc/of_device.h Thu Sep 4 15:38:36 2003 +++ b/include/asm-ppc/of_device.h Thu Sep 4 15:38:36 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/page.h b/include/asm-ppc/page.h --- a/include/asm-ppc/page.h Thu Sep 4 15:38:31 2003 +++ b/include/asm-ppc/page.h Thu Sep 4 15:38:31 2003 @@ -4,7 +4,12 @@ /* PAGE_SHIFT determines the page size */ #define PAGE_SHIFT 12 #define PAGE_SIZE (1UL << PAGE_SHIFT) -#define PAGE_MASK (~(PAGE_SIZE-1)) + +/* + * Subtle: this is an int (not an unsigned long) and so it + * gets extended to 64 bits the way want (i.e. with 1s). -- paulus + */ +#define PAGE_MASK (~((1 << PAGE_SHIFT) - 1)) #ifdef __KERNEL__ #include @@ -15,13 +20,27 @@ #ifndef __ASSEMBLY__ -#define STRICT_MM_TYPECHECKS +/* + * The basic type of a PTE - 64 bits for those CPUs with > 32 bit + * physical addressing. For now this just the IBM PPC440. + */ +#ifdef CONFIG_PTE_64BIT +typedef unsigned long long pte_basic_t; +#define PTE_SHIFT (PAGE_SHIFT - 3) /* 512 ptes per page */ +#define PTE_FMT "%16Lx" +#else +typedef unsigned long pte_basic_t; +#define PTE_SHIFT (PAGE_SHIFT - 2) /* 1024 ptes per page */ +#define PTE_FMT "%.8lx" +#endif + +#undef STRICT_MM_TYPECHECKS #ifdef STRICT_MM_TYPECHECKS /* * These are used to make use of C type-checking.. */ -typedef struct { unsigned long pte; } pte_t; +typedef struct { pte_basic_t pte; } pte_t; typedef struct { unsigned long pmd; } pmd_t; typedef struct { unsigned long pgd; } pgd_t; typedef struct { unsigned long pgprot; } pgprot_t; @@ -40,7 +59,7 @@ /* * .. while these make it easier on the compiler */ -typedef unsigned long pte_t; +typedef pte_basic_t pte_t; typedef unsigned long pmd_t; typedef unsigned long pgd_t; typedef unsigned long pgprot_t; @@ -123,6 +142,7 @@ #define pfn_to_page(pfn) (mem_map + ((pfn) - PPC_PGSTART)) #define page_to_pfn(page) ((unsigned long)((page) - mem_map) + PPC_PGSTART) #define virt_to_page(kaddr) pfn_to_page(__pa(kaddr) >> PAGE_SHIFT) +#define page_to_virt(page) __va(page_to_pfn(page) << PAGE_SHIFT) #define pfn_valid(pfn) (((pfn) - PPC_PGSTART) < max_mapnr) #define virt_addr_valid(kaddr) pfn_valid(__pa(kaddr) >> PAGE_SHIFT) diff -Nru a/include/asm-ppc/pgalloc.h b/include/asm-ppc/pgalloc.h --- a/include/asm-ppc/pgalloc.h Thu Sep 4 15:38:28 2003 +++ b/include/asm-ppc/pgalloc.h Thu Sep 4 15:38:28 2003 @@ -20,10 +20,17 @@ #define __pmd_free_tlb(tlb,x) do { } while (0) #define pgd_populate(mm, pmd, pte) BUG() +#ifndef CONFIG_BOOKE #define pmd_populate_kernel(mm, pmd, pte) \ (pmd_val(*(pmd)) = __pa(pte) | _PMD_PRESENT) #define pmd_populate(mm, pmd, pte) \ (pmd_val(*(pmd)) = (page_to_pfn(pte) << PAGE_SHIFT) | _PMD_PRESENT) +#else +#define pmd_populate_kernel(mm, pmd, pte) \ + (pmd_val(*(pmd)) = (unsigned long)pte | _PMD_PRESENT) +#define pmd_populate(mm, pmd, pte) \ + (pmd_val(*(pmd)) = (unsigned long)page_to_virt(pte) | _PMD_PRESENT) +#endif extern pte_t *pte_alloc_one_kernel(struct mm_struct *mm, unsigned long addr); extern struct page *pte_alloc_one(struct mm_struct *mm, unsigned long addr); diff -Nru a/include/asm-ppc/pgtable.h b/include/asm-ppc/pgtable.h --- a/include/asm-ppc/pgtable.h Thu Sep 4 15:38:30 2003 +++ b/include/asm-ppc/pgtable.h Thu Sep 4 15:38:30 2003 @@ -65,13 +65,23 @@ * and ITLB, respectively (see "mmu.h" for definitions). */ -/* PMD_SHIFT determines the size of the area mapped by the second-level page tables */ -#define PMD_SHIFT 22 +/* + * The normal case is that PTEs are 32-bits and we have a 1-page + * 1024-entry pgdir pointing to 1-page 1024-entry PTE pages. -- paulus + * + * For any >32-bit physical address platform, we can use the following + * two level page table layout where the pgdir is 8KB and the MS 13 bits + * are an index to the second level table. The combined pgdir/pmd first + * level has 2048 entries and the second level has 512 64-bit PTE entries. + * -Matt + */ +/* PMD_SHIFT determines the size of the area mapped by the PTE pages */ +#define PMD_SHIFT (PAGE_SHIFT + PTE_SHIFT) #define PMD_SIZE (1UL << PMD_SHIFT) #define PMD_MASK (~(PMD_SIZE-1)) -/* PGDIR_SHIFT determines what a third-level page table entry can map */ -#define PGDIR_SHIFT 22 +/* PGDIR_SHIFT determines what a top-level page table entry can map */ +#define PGDIR_SHIFT PMD_SHIFT #define PGDIR_SIZE (1UL << PGDIR_SHIFT) #define PGDIR_MASK (~(PGDIR_SIZE-1)) @@ -79,9 +89,10 @@ * entries per page directory level: our page-table tree is two-level, so * we don't really have any PMD directory. */ -#define PTRS_PER_PTE 1024 +#define PTRS_PER_PTE (1 << PTE_SHIFT) #define PTRS_PER_PMD 1 -#define PTRS_PER_PGD 1024 +#define PTRS_PER_PGD (1 << (32 - PGDIR_SHIFT)) + #define USER_PTRS_PER_PGD (TASK_SIZE / PGDIR_SIZE) #define FIRST_USER_PGD_NR 0 @@ -89,7 +100,7 @@ #define KERNEL_PGD_PTRS (PTRS_PER_PGD-USER_PGD_PTRS) #define pte_ERROR(e) \ - printk("%s:%d: bad pte %08lx.\n", __FILE__, __LINE__, pte_val(e)) + printk("%s:%d: bad pte "PTE_FMT".\n", __FILE__, __LINE__, pte_val(e)) #define pmd_ERROR(e) \ printk("%s:%d: bad pmd %08lx.\n", __FILE__, __LINE__, pmd_val(e)) #define pgd_ERROR(e) \ @@ -113,7 +124,11 @@ * of RAM. -- Cort */ #define VMALLOC_OFFSET (0x1000000) /* 16M */ +#ifdef CONFIG_44x +#define VMALLOC_START (((_ALIGN((long)high_memory, PPC44x_PIN_SIZE) + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1))) +#else #define VMALLOC_START ((((long)high_memory + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1))) +#endif #define VMALLOC_VMADDR(x) ((unsigned long)(x)) #define VMALLOC_END ioremap_bot @@ -170,6 +185,44 @@ #define _PMD_SIZE_16M 0x0e0 #define PMD_PAGE_SIZE(pmdval) (1024 << (((pmdval) & _PMD_SIZE) >> 4)) +#elif defined(CONFIG_44x) +/* + * Definitions for PPC440 + * + * Because of the 3 word TLB entries to support 36-bit addressing, + * the attribute are difficult to map in such a fashion that they + * are easily loaded during exception processing. I decided to + * organize the entry so the ERPN is the only portion in the + * upper word of the PTE and the attribute bits below are packed + * in as sensibly as they can be in the area below a 4KB page size + * oriented RPN. This at least makes it easy to load the RPN and + * ERPN fields in the TLB. -Matt + * + * Note that these bits preclude future use of a page size + * less than 4KB. + */ +#define _PAGE_PRESENT 0x00000001 /* S: PTE valid */ +#define _PAGE_RW 0x00000002 /* S: Write permission */ +#define _PAGE_DIRTY 0x00000004 /* S: Page dirty */ +#define _PAGE_ACCESSED 0x00000008 /* S: Page referenced */ +#define _PAGE_HWWRITE 0x00000010 /* H: Dirty & RW */ +#define _PAGE_HWEXEC 0x00000020 /* H: Execute permission */ +#define _PAGE_USER 0x00000040 /* S: User page */ +#define _PAGE_ENDIAN 0x00000080 /* H: E bit */ +#define _PAGE_GUARDED 0x00000100 /* H: G bit */ +#define _PAGE_COHERENT 0x00000200 /* H: M bit */ +#define _PAGE_FILE 0x00000400 /* S: nonlinear file mapping */ +#define _PAGE_NO_CACHE 0x00000400 /* H: I bit */ +#define _PAGE_WRITETHRU 0x00000800 /* H: W bit */ + +/* TODO: Add large page lowmem mapping support */ +#define _PMD_PRESENT 0 +#define _PMD_PRESENT_MASK (PAGE_MASK) +#define _PMD_BAD (~PAGE_MASK) + +/* ERPN in a PTE never gets cleared, ignore it */ +#define _PTE_NONE_MASK 0xffffffff00000000ULL + #elif defined(CONFIG_8xx) /* Definitions for 8xx embedded chips. */ #define _PAGE_PRESENT 0x0001 /* Page is valid */ @@ -270,7 +323,11 @@ #define _PAGE_BASE (_PAGE_PRESENT | _PAGE_ACCESSED) #define _PAGE_WRENABLE (_PAGE_RW | _PAGE_DIRTY | _PAGE_HWWRITE) +#ifndef CONFIG_44x #define _PAGE_KERNEL (_PAGE_BASE | _PAGE_SHARED | _PAGE_WRENABLE) +#else +#define _PAGE_KERNEL (_PAGE_BASE | _PAGE_SHARED | _PAGE_WRENABLE | _PAGE_GUARDED) +#endif #ifdef CONFIG_PPC_STD_MMU /* On standard PPC MMU, no user access implies kernel read/write access, @@ -283,7 +340,7 @@ #define _PAGE_IO (_PAGE_KERNEL | _PAGE_NO_CACHE | _PAGE_GUARDED) #define _PAGE_RAM (_PAGE_KERNEL | _PAGE_HWEXEC) -#if defined(CONFIG_KGDB) || defined(CONFIG_XMON) +#if defined(CONFIG_KGDB) || defined(CONFIG_XMON) || defined(CONFIG_BDI_SWITCH) /* We want the debuggers to be able to set breakpoints anywhere, so * don't write protect the kernel text */ #define _PAGE_RAM_TEXT _PAGE_RAM @@ -420,6 +477,8 @@ * * pte_update clears and sets bit atomically, and returns * the old pte value. + * The ((unsigned long)(p+1) - 4) hack is to get to the least-significant + * 32 bits of the PTE regardless of whether PTEs are 32 or 64 bits. */ static inline unsigned long pte_update(pte_t *p, unsigned long clr, unsigned long set) @@ -434,7 +493,7 @@ " stwcx. %1,0,%3\n\ bne- 1b" : "=&r" (old), "=&r" (tmp), "=m" (*p) - : "r" (p), "r" (clr), "r" (set), "m" (*p) + : "r" ((unsigned long)(p+1) - 4), "r" (clr), "r" (set), "m" (*p) : "cc" ); return old; } @@ -485,11 +544,25 @@ #define pte_same(A,B) (((pte_val(A) ^ pte_val(B)) & ~_PAGE_HASHPTE) == 0) +/* + * Note that on Book E processors, the pmd contains the kernel virtual + * (lowmem) address of the pte page. The physical address is less useful + * because everything runs with translation enabled (even the TLB miss + * handler). On everything else the pmd contains the physical address + * of the pte page. -- paulus + */ +#ifndef CONFIG_BOOKE #define pmd_page_kernel(pmd) \ ((unsigned long) __va(pmd_val(pmd) & PAGE_MASK)) #define pmd_page(pmd) \ (mem_map + (pmd_val(pmd) >> PAGE_SHIFT)) - +#else +#define pmd_page_kernel(pmd) \ + ((unsigned long) (pmd_val(pmd) & PAGE_MASK)) +#define pmd_page(pmd) \ + (mem_map + (__pa(pmd_val(pmd)) >> PAGE_SHIFT)) +#endif + /* to find an entry in a kernel page-table-directory */ #define pgd_offset_k(address) pgd_offset(&init_mm, address) @@ -516,7 +589,8 @@ #define pte_unmap(pte) kunmap_atomic(pte, KM_PTE0) #define pte_unmap_nested(pte) kunmap_atomic(pte, KM_PTE1) -extern pgd_t swapper_pg_dir[1024]; +extern pgd_t swapper_pg_dir[PTRS_PER_PGD]; + extern void paging_init(void); /* diff -Nru a/include/asm-ppc/ppc_asm.h b/include/asm-ppc/ppc_asm.h --- a/include/asm-ppc/ppc_asm.h Thu Sep 4 15:38:29 2003 +++ b/include/asm-ppc/ppc_asm.h Thu Sep 4 15:38:29 2003 @@ -107,7 +107,7 @@ bdnz 0b #endif -#if !defined(CONFIG_440) +#if !defined(CONFIG_44x) /* * On APUS (Amiga PowerPC cpu upgrade board), we don't know the * physical base address of RAM at compile time. @@ -125,7 +125,7 @@ .align 1; \ .long 0b; \ .previous -#else /* CONFIG_440 */ +#else /* CONFIG_44x */ #define tophys(rd,rs) \ mr rd,rs @@ -133,7 +133,7 @@ #define tovirt(rd,rs) \ mr rd,rs -#endif /* CONFIG_440 */ +#endif /* CONFIG_44x */ /* * On 64-bit cpus, we use the rfid instruction instead of rfi, but diff -Nru a/include/asm-ppc/processor.h b/include/asm-ppc/processor.h --- a/include/asm-ppc/processor.h Thu Sep 4 15:38:28 2003 +++ b/include/asm-ppc/processor.h Thu Sep 4 15:38:28 2003 @@ -3,6 +3,12 @@ #define __ASM_PPC_PROCESSOR_H /* + * The Book E definitions are hacked into here for 440 right + * now. This whole thing needs regorganized (maybe two files) + * so that it becomes readable. -Matt + */ + +/* * Default implementation of macro that returns current * instruction pointer ("program counter"). */ @@ -45,6 +51,11 @@ #define MSR_RI (1<<1) /* Recoverable Exception */ #define MSR_LE (1<<0) /* Little Endian */ +#ifdef CONFIG_BOOKE +#define MSR_IS MSR_IR /* Instruction Space */ +#define MSR_DS MSR_DR /* Data Space */ +#endif + #ifdef CONFIG_APUS_FAST_EXCEPT #define MSR_ (MSR_ME|MSR_IP|MSR_RI) #else @@ -93,8 +104,13 @@ #define SPRN_CDBCR 0x3D7 /* Cache Debug Control Register */ #define SPRN_CTR 0x009 /* Count Register */ #define SPRN_DABR 0x3F5 /* Data Address Breakpoint Register */ +#ifndef CONFIG_BOOKE #define SPRN_DAC1 0x3F6 /* Data Address Compare 1 */ #define SPRN_DAC2 0x3F7 /* Data Address Compare 2 */ +#else +#define SPRN_DAC1 0x13C /* Book E Data Address Compare 1 */ +#define SPRN_DAC2 0x13D /* Book E Data Address Compare 2 */ +#endif /* CONFIG_BOOKE */ #define SPRN_DAR 0x013 /* Data Address Register */ #define SPRN_DBAT0L 0x219 /* Data BAT 0 Lower Register */ #define SPRN_DBAT0U 0x218 /* Data BAT 0 Upper Register */ @@ -146,7 +162,11 @@ #define DBCR_SDA 0x00000004 /* Second DAC Enable */ #define DBCR_JOI 0x00000002 /* JTAG Serial Outbound Int. Enable */ #define DBCR_JII 0x00000001 /* JTAG Serial Inbound Int. Enable */ +#ifndef CONFIG_BOOKE #define SPRN_DBCR0 0x3F2 /* Debug Control Register 0 */ +#else +#define SPRN_DBCR0 0x134 /* Book E Debug Control Register 0 */ +#endif /* CONFIG_BOOKE */ #define DBCR0_EDM 0x80000000 /* External Debug Mode */ #define DBCR0_IDM 0x40000000 /* Internal Debug Mode */ #define DBCR0_RST 0x30000000 /* all the bits in the RST field */ @@ -169,11 +189,18 @@ #define DBCR0_IA12T 0x00008000 /* Instr Addr 1-2 range Toggle */ #define DBCR0_IA34T 0x00004000 /* Instr Addr 3-4 range Toggle */ #define DBCR0_FT 0x00000001 /* Freeze Timers on debug event */ +#ifndef CONFIG_BOOKE #define SPRN_DBCR1 0x3BD /* Debug Control Register 1 */ #define SPRN_DBSR 0x3F0 /* Debug Status Register */ #define DBSR_IC 0x80000000 /* Instruction Completion */ #define DBSR_BT 0x40000000 /* Branch taken */ #define DBSR_TIE 0x10000000 /* Trap Instruction debug Event */ +#else +#define SPRN_DBCR1 0x135 /* Book E Debug Control Register 1 */ +#define SPRN_DBSR 0x130 /* Book E Debug Status Register */ +#define DBSR_IC 0x08000000 /* Book E Instruction Completion */ +#define DBSR_TIE 0x01000000 /* Book E Trap Instruction Event */ +#endif /* CONFIG_BOOKE */ #define SPRN_DCCR 0x3FA /* Data Cache Cacheability Register */ #define DCCR_NOCACHE 0 /* Noncacheable */ #define DCCR_CACHE 1 /* Cacheable */ @@ -181,7 +208,11 @@ #define SPRN_DCWR 0x3BA /* Data Cache Write-thru Register */ #define DCWR_COPY 0 /* Copy-back */ #define DCWR_WRITE 1 /* Write-through */ +#ifndef CONFIG_BOOKE #define SPRN_DEAR 0x3D5 /* Data Error Address Register */ +#else +#define SPRN_DEAR 0x03D /* Book E Data Error Address Register */ +#endif /* CONFIG_BOOKE */ #define SPRN_DEC 0x016 /* Decrement Register */ #define SPRN_DER 0x095 /* Debug Enable Regsiter */ #define DER_RSTE 0x40000000 /* Reset Interrupt */ @@ -206,12 +237,16 @@ #define SPRN_DMISS 0x3D0 /* Data TLB Miss Register */ #define SPRN_DSISR 0x012 /* Data Storage Interrupt Status Register */ #define SPRN_EAR 0x11A /* External Address Register */ +#ifndef CONFIG_BOOKE #define SPRN_ESR 0x3D4 /* Exception Syndrome Register */ +#else +#define SPRN_ESR 0x03E /* Book E Exception Syndrome Register */ +#endif /* CONFIG_BOOKE */ #define ESR_MCI 0x80000000 /* 405 Machine Check - Instruction */ -#define ESR_IMCP 0x80000000 /* 403 Inst. Mach. Check - Protection */ -#define ESR_IMCN 0x40000000 /* 403 Inst. Mach. Check - Non-config */ -#define ESR_IMCB 0x20000000 /* 403 Inst. Mach. Check - Bus error */ -#define ESR_IMCT 0x10000000 /* 403 Inst. Mach. Check - Timeout */ +#define ESR_IMCP 0x80000000 /* Instr. Machine Check - Protection */ +#define ESR_IMCN 0x40000000 /* Instr. Machine Check - Non-config */ +#define ESR_IMCB 0x20000000 /* Instr. Machine Check - Bus error */ +#define ESR_IMCT 0x10000000 /* Instr. Machine Check - Timeout */ #define ESR_PIL 0x08000000 /* Program Exception - Illegal */ #define ESR_PPR 0x04000000 /* Program Exception - Priveleged */ #define ESR_PTR 0x02000000 /* Program Exception - Trap */ @@ -266,8 +301,13 @@ #define HID1_SYNCBE (1<<11) /* 7450 ABE for sync, eieio */ #define HID1_ABE (1<<10) /* 7450 Address Broadcast Enable */ #define SPRN_IABR 0x3F2 /* Instruction Address Breakpoint Register */ +#ifndef CONFIG_BOOKE #define SPRN_IAC1 0x3F4 /* Instruction Address Compare 1 */ #define SPRN_IAC2 0x3F5 /* Instruction Address Compare 2 */ +#else +#define SPRN_IAC1 0x138 /* Book E Instruction Address Compare 1 */ +#define SPRN_IAC2 0x139 /* Book E Instruction Address Compare 2 */ +#endif /* CONFIG_BOOKE */ #define SPRN_IBAT0L 0x211 /* Instruction BAT 0 Lower Register */ #define SPRN_IBAT0U 0x210 /* Instruction BAT 0 Upper Register */ #define SPRN_IBAT1L 0x213 /* Instruction BAT 1 Lower Register */ @@ -358,8 +398,13 @@ #define SPRN_PBL2 0x3FE /* Protection Bound Lower 2 */ #define SPRN_PBU1 0x3FD /* Protection Bound Upper 1 */ #define SPRN_PBU2 0x3FF /* Protection Bound Upper 2 */ +#ifndef CONFIG_BOOKE #define SPRN_PID 0x3B1 /* Process ID */ #define SPRN_PIR 0x3FF /* Processor Identification Register */ +#else +#define SPRN_PID 0x030 /* Book E Process ID */ +#define SPRN_PIR 0x11E /* Book E Processor Identification Register */ +#endif /* CONFIG_BOOKE */ #define SPRN_PIT 0x3DB /* Programmable Interval Timer */ #define SPRN_PMC1 0x3B9 /* Performance Counter Register 1 */ #define SPRN_PMC2 0x3BA /* Performance Counter Register 2 */ @@ -375,6 +420,7 @@ #define SGR_NORMAL 0 #define SGR_GUARDED 1 #define SPRN_SIA 0x3BB /* Sampled Instruction Address Register */ +#define SPRN_SLER 0x3BB /* Little-endian real mode */ #define SPRN_SPRG0 0x110 /* Special Purpose Register General 0 */ #define SPRN_SPRG1 0x111 /* Special Purpose Register General 1 */ #define SPRN_SPRG2 0x112 /* Special Purpose Register General 2 */ @@ -387,6 +433,7 @@ #define SPRN_SRR1 0x01B /* Save/Restore Register 1 */ #define SPRN_SRR2 0x3DE /* Save/Restore Register 2 */ #define SPRN_SRR3 0x3DF /* Save/Restore Register 3 */ +#define SPRN_SU0R 0x3BC /* "User 0" real mode */ #define SPRN_TBHI 0x3DC /* Time Base High (4xx) */ #define SPRN_TBHU 0x3CC /* Time Base High User-mode (4xx) */ #define SPRN_TBLO 0x3DD /* Time Base Low (4xx) */ @@ -395,7 +442,11 @@ #define SPRN_TBRU 0x10D /* Time Base Read Upper Register (user, R/O) */ #define SPRN_TBWL 0x11C /* Time Base Lower Register (super, R/W) */ #define SPRN_TBWU 0x11D /* Time Base Upper Register (super, R/W) */ +#ifndef CONFIG_BOOKE #define SPRN_TCR 0x3DA /* Timer Control Register */ +#else +#define SPRN_TCR 0x154 /* Book E Timer Control Register */ +#endif #define TCR_WP(x) (((x)&0x3)<<30) /* WDT Period */ #define TCR_WP_MASK TCR_WP(3) #define WP_2_17 0 /* 2^17 clocks */ @@ -410,6 +461,7 @@ #define WRC_SYSTEM 3 /* System reset will occur */ #define TCR_WIE 0x08000000 /* WDT Interrupt Enable */ #define TCR_PIE 0x04000000 /* PIT Interrupt Enable */ +#define TCR_DIE TCR_PIE /* DEC Interrupt Enable */ #define TCR_FP(x) (((x)&0x3)<<24) /* FIT Period */ #define TCR_FP_MASK TCR_FP(3) #define FP_2_9 0 /* 2^9 clocks */ @@ -431,7 +483,11 @@ #define SPRN_THRM3 0x3FE /* Thermal Management Register 3 */ #define THRM3_E (1<<0) #define SPRN_TLBMISS 0x3D4 /* 980 7450 TLB Miss Register */ +#ifndef CONFIG_BOOKE #define SPRN_TSR 0x3D8 /* Timer Status Register */ +#else +#define SPRN_TSR 0x150 /* Book E Timer Status Register */ +#endif /* CONFIG_BOOKE */ #define TSR_ENW 0x80000000 /* Enable Next Watchdog */ #define TSR_WIS 0x40000000 /* WDT Interrupt Status */ #define TSR_WRS(x) (((x)&0x3)<<28) /* WDT Reset Status */ @@ -440,6 +496,7 @@ #define WRS_CHIP 2 /* WDT forced chip reset */ #define WRS_SYSTEM 3 /* WDT forced system reset */ #define TSR_PIS 0x08000000 /* PIT Interrupt Status */ +#define TSR_DIS TSR_PIS /* DEC Interrupt Status */ #define TSR_FIS 0x04000000 /* FIT Interrupt Status */ #define SPRN_UMMCR0 0x3A8 /* User Monitor Mode Control Register 0 */ #define SPRN_UMMCR1 0x3AC /* User Monitor Mode Control Register 0 */ @@ -452,6 +509,45 @@ #define SPRN_XER 0x001 /* Fixed Point Exception Register */ #define SPRN_ZPR 0x3B0 /* Zone Protection Register */ +/* Book E definitions */ +#define SPRN_DECAR 0x036 /* Decrementer Auto Reload Register */ +#define SPRN_CSRR0 0x03A /* Critical Save and Restore Register 0 */ +#define SPRN_CSRR1 0x03B /* Critical Save and Restore Register 1 */ +#define SPRN_IVPR 0x03F /* Interrupt Vector Prefix Register */ +#define SPRN_USPRG0 0x100 /* User Special Purpose Register General 0 */ +#define SPRN_SPRG4R 0x104 /* Special Purpose Register General 4 Read */ +#define SPRN_SPRG5R 0x105 /* Special Purpose Register General 5 Read */ +#define SPRN_SPRG6R 0x106 /* Special Purpose Register General 6 Read */ +#define SPRN_SPRG7R 0x107 /* Special Purpose Register General 7 Read */ +#define SPRN_SPRG4W 0x114 /* Special Purpose Register General 4 Write */ +#define SPRN_SPRG5W 0x115 /* Special Purpose Register General 5 Write */ +#define SPRN_SPRG6W 0x116 /* Special Purpose Register General 6 Write */ +#define SPRN_SPRG7W 0x117 /* Special Purpose Register General 7 Write */ +#define SPRN_DBCR2 0x136 /* Debug Control Register 2 */ +#define SPRN_IAC3 0x13A /* Instruction Address Compare 3 */ +#define SPRN_IAC4 0x13B /* Instruction Address Compare 4 */ +#define SPRN_DVC1 0x13E /* */ +#define SPRN_DVC2 0x13F /* */ +#define SPRN_IVOR0 0x190 /* Interrupt Vector Offset Register 0 */ +#define SPRN_IVOR1 0x191 /* Interrupt Vector Offset Register 1 */ +#define SPRN_IVOR2 0x192 /* Interrupt Vector Offset Register 2 */ +#define SPRN_IVOR3 0x193 /* Interrupt Vector Offset Register 3 */ +#define SPRN_IVOR4 0x194 /* Interrupt Vector Offset Register 4 */ +#define SPRN_IVOR5 0x195 /* Interrupt Vector Offset Register 5 */ +#define SPRN_IVOR6 0x196 /* Interrupt Vector Offset Register 6 */ +#define SPRN_IVOR7 0x197 /* Interrupt Vector Offset Register 7 */ +#define SPRN_IVOR8 0x198 /* Interrupt Vector Offset Register 8 */ +#define SPRN_IVOR9 0x199 /* Interrupt Vector Offset Register 9 */ +#define SPRN_IVOR10 0x19a /* Interrupt Vector Offset Register 10 */ +#define SPRN_IVOR11 0x19b /* Interrupt Vector Offset Register 11 */ +#define SPRN_IVOR12 0x19c /* Interrupt Vector Offset Register 12 */ +#define SPRN_IVOR13 0x19d /* Interrupt Vector Offset Register 13 */ +#define SPRN_IVOR14 0x19e /* Interrupt Vector Offset Register 14 */ +#define SPRN_IVOR15 0x19f /* Interrupt Vector Offset Register 15 */ +#define SPRN_MMUCR 0x3b2 /* MMU Control Register */ + +#define ESR_ST 0x00800000 /* Store Operation */ + /* Short-hand versions for a number of the above SPRNs */ #define CTR SPRN_CTR /* Counter Register */ @@ -524,6 +620,16 @@ #define SPRG5 SPRN_SPRG5 #define SPRG6 SPRN_SPRG6 #define SPRG7 SPRN_SPRG7 +#define SPRG4R SPRN_SPRG4R /* Book E Supervisor Private Registers */ +#define SPRG5R SPRN_SPRG5R +#define SPRG6R SPRN_SPRG6R +#define SPRG7R SPRN_SPRG7R +#define SPRG4W SPRN_SPRG4W +#define SPRG5W SPRN_SPRG5W +#define SPRG6W SPRN_SPRG6W +#define SPRG7W SPRN_SPRG7W +#define CSRR0 SPRN_CSRR0 /* Critical Save and Restore Register 0 */ +#define CSRR1 SPRN_CSRR1 /* Critical Save and Restore Register 1 */ #define SRR0 SPRN_SRR0 /* Save and Restore Register 0 */ #define SRR1 SPRN_SRR1 /* Save and Restore Register 1 */ #define SRR2 SPRN_SRR2 /* Save and Restore Register 2 */ @@ -557,6 +663,51 @@ #define PVR_MAJ(pvr) (((pvr) >> 4) & 0xF) /* Major revision field */ #define PVR_MIN(pvr) (((pvr) >> 0) & 0xF) /* Minor revision field */ +/* Processor Version Numbers */ + +#define PVR_403GA 0x00200000 +#define PVR_403GB 0x00200100 +#define PVR_403GC 0x00200200 +#define PVR_403GCX 0x00201400 +#define PVR_405GP 0x40110000 +#define PVR_STB03XXX 0x40310000 +#define PVR_NP405H 0x41410000 +#define PVR_NP405L 0x41610000 +#define PVR_440GP_RB 0x40120440 +#define PVR_440GP_RC1 0x40120481 +#define PVR_440GP_RC2 0x40200481 +#define PVR_440GX_RC1 0x51b21850 +#define PVR_601 0x00010000 +#define PVR_602 0x00050000 +#define PVR_603 0x00030000 +#define PVR_603e 0x00060000 +#define PVR_603ev 0x00070000 +#define PVR_603r 0x00071000 +#define PVR_604 0x00040000 +#define PVR_604e 0x00090000 +#define PVR_604r 0x000A0000 +#define PVR_620 0x00140000 +#define PVR_740 0x00080000 +#define PVR_750 PVR_740 +#define PVR_740P 0x10080000 +#define PVR_750P PVR_740P +#define PVR_7400 0x000C0000 +#define PVR_7410 0x800C0000 +#define PVR_7450 0x80000000 +/* + * For the 8xx processors, all of them report the same PVR family for + * the PowerPC core. The various versions of these processors must be + * differentiated by the version number in the Communication Processor + * Module (CPM). + */ +#define PVR_821 0x00500000 +#define PVR_823 PVR_821 +#define PVR_850 PVR_821 +#define PVR_860 PVR_821 +#define PVR_8240 0x00810100 +#define PVR_8245 0x80811014 +#define PVR_8260 PVR_8240 + /* We only need to define a new _MACH_xxx for machines which are part of * a configuration which supports more than one type of different machine. * This is currently limited to CONFIG_PPC_MULTIPLATFORM and CHRP/PReP/PMac. -- Tom @@ -654,6 +805,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 Thu Sep 4 15:38:40 2003 +++ b/include/asm-ppc/prom.h Thu Sep 4 15:38:40 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/serial.h b/include/asm-ppc/serial.h --- a/include/asm-ppc/serial.h Thu Sep 4 15:38:45 2003 +++ b/include/asm-ppc/serial.h Thu Sep 4 15:38:45 2003 @@ -28,7 +28,7 @@ #include #elif defined(CONFIG_SPRUCE) #include -#elif defined(CONFIG_40x) +#elif defined(CONFIG_4xx) #include #else diff -Nru a/include/asm-ppc/tlbflush.h b/include/asm-ppc/tlbflush.h --- a/include/asm-ppc/tlbflush.h Thu Sep 4 15:38:30 2003 +++ b/include/asm-ppc/tlbflush.h Thu Sep 4 15:38:30 2003 @@ -19,17 +19,23 @@ #if defined(CONFIG_4xx) +#ifndef CONFIG_44x +#define __tlbia() asm volatile ("sync; tlbia; isync" : : : "memory") +#else +#define __tlbia _tlbia +#endif + static inline void flush_tlb_mm(struct mm_struct *mm) - { _tlbia(); } + { __tlbia(); } static inline void flush_tlb_page(struct vm_area_struct *vma, unsigned long vmaddr) { _tlbie(vmaddr); } static inline void flush_tlb_range(struct vm_area_struct *vma, unsigned long start, unsigned long end) - { _tlbia(); } + { __tlbia(); } static inline void flush_tlb_kernel_range(unsigned long start, unsigned long end) - { _tlbia(); } + { __tlbia(); } #elif defined(CONFIG_8xx) #define __tlbia() asm volatile ("tlbia; sync" : : : "memory") diff -Nru a/include/asm-ppc/unistd.h b/include/asm-ppc/unistd.h --- a/include/asm-ppc/unistd.h Thu Sep 4 15:38:30 2003 +++ b/include/asm-ppc/unistd.h Thu Sep 4 15:38:30 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-s390/semaphore.h b/include/asm-s390/semaphore.h --- a/include/asm-s390/semaphore.h Thu Sep 4 15:38:28 2003 +++ b/include/asm-s390/semaphore.h Thu Sep 4 15:38:28 2003 @@ -60,6 +60,7 @@ static inline void down(struct semaphore * sem) { + might_sleep(); if (atomic_dec_return(&sem->count) < 0) __down(sem); } @@ -68,6 +69,7 @@ { int ret = 0; + might_sleep(); if (atomic_dec_return(&sem->count) < 0) ret = __down_interruptible(sem); return ret; diff -Nru a/include/asm-sh/semaphore.h b/include/asm-sh/semaphore.h --- a/include/asm-sh/semaphore.h Thu Sep 4 15:38:47 2003 +++ b/include/asm-sh/semaphore.h Thu Sep 4 15:38:47 2003 @@ -107,6 +107,7 @@ CHECK_MAGIC(sem->__magic); #endif + might_sleep(); if (atomic_dec_return(&sem->count) < 0) ret = __down_interruptible(sem); return ret; diff -Nru a/include/asm-sparc/pci.h b/include/asm-sparc/pci.h --- a/include/asm-sparc/pci.h Thu Sep 4 15:38:40 2003 +++ b/include/asm-sparc/pci.h Thu Sep 4 15:38:40 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/semaphore.h b/include/asm-sparc/semaphore.h --- a/include/asm-sparc/semaphore.h Thu Sep 4 15:38:47 2003 +++ b/include/asm-sparc/semaphore.h Thu Sep 4 15:38:47 2003 @@ -71,6 +71,7 @@ #if WAITQUEUE_DEBUG CHECK_MAGIC(sem->__magic); #endif + might_sleep(); ptr = &(sem->count.counter); increment = 1; @@ -107,6 +108,7 @@ #if WAITQUEUE_DEBUG CHECK_MAGIC(sem->__magic); #endif + might_sleep(); ptr = &(sem->count.counter); increment = 1; diff -Nru a/include/asm-sparc/smp.h b/include/asm-sparc/smp.h --- a/include/asm-sparc/smp.h Thu Sep 4 15:38:30 2003 +++ b/include/asm-sparc/smp.h Thu Sep 4 15:38:30 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/termios.h b/include/asm-sparc/termios.h --- a/include/asm-sparc/termios.h Thu Sep 4 15:38:33 2003 +++ b/include/asm-sparc/termios.h Thu Sep 4 15:38:33 2003 @@ -73,6 +73,7 @@ #define N_HCI 15 /* Bluetooth HCI UART */ #ifdef __KERNEL__ +#include /* * c_cc characters in the termio structure. Oh, how I love being @@ -167,6 +168,9 @@ } \ 0; \ }) + +#define MODULE_ALIAS_LDISC(ldisc) \ + MODULE_ALIAS("tty-ldisc-" __stringify(ldisc)) #endif /* __KERNEL__ */ diff -Nru a/include/asm-sparc/unistd.h b/include/asm-sparc/unistd.h --- a/include/asm-sparc/unistd.h Thu Sep 4 15:38:29 2003 +++ b/include/asm-sparc/unistd.h Thu Sep 4 15:38:29 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 Thu Sep 4 15:38:40 2003 +++ b/include/asm-sparc64/siginfo.h Thu Sep 4 15:38:40 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/termios.h b/include/asm-sparc64/termios.h --- a/include/asm-sparc64/termios.h Thu Sep 4 15:38:30 2003 +++ b/include/asm-sparc64/termios.h Thu Sep 4 15:38:30 2003 @@ -73,6 +73,7 @@ #define N_HCI 15 /* Bluetooth HCI UART */ #ifdef __KERNEL__ +#include /* * c_cc characters in the termio structure. Oh, how I love being @@ -166,6 +167,9 @@ } \ 0; \ }) + +#define MODULE_ALIAS_LDISC(ldisc) \ + MODULE_ALIAS("tty-ldisc-" __stringify(ldisc)) #endif /* __KERNEL__ */ diff -Nru a/include/asm-sparc64/unistd.h b/include/asm-sparc64/unistd.h --- a/include/asm-sparc64/unistd.h Thu Sep 4 15:38:30 2003 +++ b/include/asm-sparc64/unistd.h Thu Sep 4 15:38:30 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-v850/semaphore.h b/include/asm-v850/semaphore.h --- a/include/asm-v850/semaphore.h Thu Sep 4 15:38:32 2003 +++ b/include/asm-v850/semaphore.h Thu Sep 4 15:38:32 2003 @@ -57,6 +57,7 @@ extern inline void down (struct semaphore * sem) { + might_sleep(); if (atomic_dec_return (&sem->count) < 0) __down (sem); } @@ -64,6 +65,7 @@ extern inline int down_interruptible (struct semaphore * sem) { int ret = 0; + might_sleep(); if (atomic_dec_return (&sem->count) < 0) ret = __down_interruptible (sem); return ret; diff -Nru a/include/asm-x86_64/bitops.h b/include/asm-x86_64/bitops.h --- a/include/asm-x86_64/bitops.h Thu Sep 4 15:38:32 2003 +++ b/include/asm-x86_64/bitops.h Thu Sep 4 15:38:32 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 Thu Sep 4 15:38:44 2003 +++ b/include/asm-x86_64/ia32.h Thu Sep 4 15:38:44 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 Thu Sep 4 15:38:33 2003 +++ b/include/asm-x86_64/mpspec.h Thu Sep 4 15:38:33 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 Thu Sep 4 15:38:40 2003 +++ b/include/asm-x86_64/percpu.h Thu Sep 4 15:38:40 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 Thu Sep 4 15:38:46 2003 +++ b/include/asm-x86_64/processor.h Thu Sep 4 15:38:46 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/semaphore.h b/include/asm-x86_64/semaphore.h --- a/include/asm-x86_64/semaphore.h Thu Sep 4 15:38:28 2003 +++ b/include/asm-x86_64/semaphore.h Thu Sep 4 15:38:28 2003 @@ -118,6 +118,7 @@ #if WAITQUEUE_DEBUG CHECK_MAGIC(sem->__magic); #endif + might_sleep(); __asm__ __volatile__( "# atomic down operation\n\t" @@ -144,6 +145,7 @@ #if WAITQUEUE_DEBUG CHECK_MAGIC(sem->__magic); #endif + might_sleep(); __asm__ __volatile__( "# atomic interruptible down operation\n\t" diff -Nru a/include/asm-x86_64/smp.h b/include/asm-x86_64/smp.h --- a/include/asm-x86_64/smp.h Thu Sep 4 15:38:28 2003 +++ b/include/asm-x86_64/smp.h Thu Sep 4 15:38:28 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 Thu Sep 4 15:38:35 2003 +++ b/include/asm-x86_64/suspend.h Thu Sep 4 15:38:35 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 Thu Sep 4 15:38:40 2003 +++ b/include/asm-x86_64/topology.h Thu Sep 4 15:38:40 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 Thu Sep 4 15:38:30 2003 +++ b/include/linux/blkdev.h Thu Sep 4 15:38:30 2003 @@ -12,6 +12,8 @@ #include #include #include +#include +#include #include @@ -243,6 +245,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 +286,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 +304,8 @@ */ void *queuedata; + void *activity_data; + /* * queue needs bounce pages for pages above this limit */ @@ -504,6 +510,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) { @@ -666,6 +673,11 @@ } \ ) #endif - + +#define MODULE_ALIAS_BLOCKDEV(major,minor) \ + MODULE_ALIAS("block-major-" __stringify(major) "-" __stringify(minor)) +#define MODULE_ALIAS_BLOCKDEV_MAJOR(major) \ + MODULE_ALIAS("block-major-" __stringify(major) "-*") + #endif diff -Nru a/include/linux/cyclomx.h b/include/linux/cyclomx.h --- a/include/linux/cyclomx.h Thu Sep 4 15:38:34 2003 +++ b/include/linux/cyclomx.h Thu Sep 4 15:38:34 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 Thu Sep 4 15:38:29 2003 +++ b/include/linux/cycx_cfm.h Thu Sep 4 15:38:29 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 Thu Sep 4 15:38:32 2003 +++ b/include/linux/cycx_drv.h Thu Sep 4 15:38:32 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/device.h b/include/linux/device.h --- a/include/linux/device.h Thu Sep 4 15:38:44 2003 +++ b/include/linux/device.h Thu Sep 4 15:38:44 2003 @@ -398,4 +398,9 @@ #define dev_warn(dev, format, arg...) \ dev_printk(KERN_WARNING , dev , format , ## arg) +/* Create alias, so I can be autoloaded. */ +#define MODULE_ALIAS_CHARDEV(major,minor) \ + MODULE_ALIAS("char-major-" __stringify(major) "-" __stringify(minor)) +#define MODULE_ALIAS_CHARDEV_MAJOR(major) \ + MODULE_ALIAS("char-major-" __stringify(major) "-*") #endif /* _DEVICE_H_ */ diff -Nru a/include/linux/ethtool.h b/include/linux/ethtool.h --- a/include/linux/ethtool.h Thu Sep 4 15:38:31 2003 +++ b/include/linux/ethtool.h Thu Sep 4 15:38:31 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 Thu Sep 4 15:38:31 2003 +++ b/include/linux/fs.h Thu Sep 4 15:38:31 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 *); @@ -1371,10 +1390,6 @@ extern int simple_fill_super(struct super_block *, int, struct tree_descr *); extern int simple_pin_fs(char *name, struct vfsmount **mount, int *count); extern void simple_release_fs(struct vfsmount **mount, int *count); - -#ifdef CONFIG_BLK_DEV_INITRD -extern unsigned int real_root_dev; -#endif extern int inode_change_ok(struct inode *, struct iattr *); extern int inode_setattr(struct inode *, struct iattr *); diff -Nru a/include/linux/genhd.h b/include/linux/genhd.h --- a/include/linux/genhd.h Thu Sep 4 15:38:30 2003 +++ b/include/linux/genhd.h Thu Sep 4 15:38:30 2003 @@ -75,7 +75,6 @@ unsigned read_merges, write_merges; unsigned read_ticks, write_ticks; unsigned io_ticks; - int in_flight; unsigned time_in_queue; }; @@ -101,6 +100,7 @@ unsigned sync_io; /* RAID */ unsigned long stamp, stamp_idle; + int in_flight; #ifdef CONFIG_SMP struct disk_stats *dkstats; #else @@ -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/hiddev.h b/include/linux/hiddev.h --- a/include/linux/hiddev.h Thu Sep 4 15:38:31 2003 +++ b/include/linux/hiddev.h Thu Sep 4 15:38:31 2003 @@ -207,7 +207,7 @@ struct hid_usage *usage, __s32 value, struct pt_regs *regs); void hiddev_report_event(struct hid_device *hid, struct hid_report *report); int __init hiddev_init(void); -void __exit hiddev_exit(void); +void hiddev_exit(void); #else static inline int hiddev_connect(struct hid_device *hid) { return -1; } static inline void hiddev_disconnect(struct hid_device *hid) { } diff -Nru a/include/linux/ide.h b/include/linux/ide.h --- a/include/linux/ide.h Thu Sep 4 15:38:32 2003 +++ b/include/linux/ide.h Thu Sep 4 15:38:32 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; /* @@ -1213,7 +1218,6 @@ const char *version; u8 media; unsigned busy : 1; - unsigned supports_dma : 1; unsigned supports_dsc_overlap : 1; int (*cleanup)(ide_drive_t *); int (*shutdown)(ide_drive_t *); @@ -1242,21 +1246,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 +1263,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 +1760,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 +1779,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/if_frad.h b/include/linux/if_frad.h --- a/include/linux/if_frad.h Thu Sep 4 15:38:28 2003 +++ b/include/linux/if_frad.h Thu Sep 4 15:38:28 2003 @@ -155,9 +155,11 @@ struct dlci_local { struct net_device_stats stats; - struct net_device *slave; + struct net_device *master; + struct net_device *slave; struct dlci_conf config; int configured; + struct list_head list; /* callback function */ void (*receive)(struct sk_buff *skb, struct net_device *); diff -Nru a/include/linux/initrd.h b/include/linux/initrd.h --- a/include/linux/initrd.h Thu Sep 4 15:38:45 2003 +++ b/include/linux/initrd.h Thu Sep 4 15:38:45 2003 @@ -16,3 +16,5 @@ /* free_initrd_mem always gets called with the next two as arguments.. */ extern unsigned long initrd_start, initrd_end; extern void free_initrd_mem(unsigned long, unsigned long); + +extern unsigned int real_root_dev; diff -Nru a/include/linux/ipv6_route.h b/include/linux/ipv6_route.h --- a/include/linux/ipv6_route.h Thu Sep 4 15:38:30 2003 +++ b/include/linux/ipv6_route.h Thu Sep 4 15:38:30 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/isdn/capilli.h b/include/linux/isdn/capilli.h --- a/include/linux/isdn/capilli.h Thu Sep 4 15:38:32 2003 +++ b/include/linux/isdn/capilli.h Thu Sep 4 15:38:32 2003 @@ -54,7 +54,7 @@ int count, int *eof, struct capi_ctr *card); /* filled in before calling ready callback */ - u8 manu[CAPI_MANUFACTURER_LEN]; /* CAPI_GET_MANUFACTURER */ + u8 manu[CAPI_MANUFACTURER_LEN]; /* CAPI_GET_MANUFACTURER */ capi_version version; /* CAPI_GET_VERSION */ capi_profile profile; /* CAPI_GET_PROFILE */ u8 serial[CAPI_SERIAL_LEN]; /* CAPI_GET_SERIAL */ diff -Nru a/include/linux/isdn.h b/include/linux/isdn.h --- a/include/linux/isdn.h Thu Sep 4 15:38:47 2003 +++ b/include/linux/isdn.h Thu Sep 4 15:38:47 2003 @@ -258,13 +258,13 @@ * variables. Of course, we need to check skb_headroom prior to * any access. */ -typedef struct isdn_audio_skb { +typedef struct _isdnaudio_header { unsigned short dle_count; unsigned char lock; -} isdn_audio_skb; +} isdnaudio_header; -#define ISDN_AUDIO_SKB_DLECOUNT(skb) (((isdn_audio_skb*)skb->head)->dle_count) -#define ISDN_AUDIO_SKB_LOCK(skb) (((isdn_audio_skb*)skb->head)->lock) +#define ISDN_AUDIO_SKB_DLECOUNT(skb) (((isdnaudio_header*)skb->head)->dle_count) +#define ISDN_AUDIO_SKB_LOCK(skb) (((isdnaudio_header*)skb->head)->lock) #endif /* Private data of AT-command-interpreter */ @@ -291,6 +291,7 @@ /* Private data (similar to async_struct in ) */ typedef struct modem_info { int magic; + struct module *owner; int flags; /* defined in tty.h */ int x_char; /* xon/xoff character */ int mcr; /* Modem control register */ diff -Nru a/include/linux/kdev_t.h b/include/linux/kdev_t.h --- a/include/linux/kdev_t.h Thu Sep 4 15:38:43 2003 +++ b/include/linux/kdev_t.h Thu Sep 4 15:38:43 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/kernel.h b/include/linux/kernel.h --- a/include/linux/kernel.h Thu Sep 4 15:38:28 2003 +++ b/include/linux/kernel.h Thu Sep 4 15:38:28 2003 @@ -52,8 +52,10 @@ #ifdef CONFIG_DEBUG_SPINLOCK_SLEEP void __might_sleep(char *file, int line); #define might_sleep() __might_sleep(__FILE__, __LINE__) +#define might_sleep_if(cond) do { if (unlikely(cond)) might_sleep(); } while (0) #else #define might_sleep() do {} while(0) +#define might_sleep_if(cond) do {} while (0) #endif extern struct notifier_block *panic_notifier_list; diff -Nru a/include/linux/miscdevice.h b/include/linux/miscdevice.h --- a/include/linux/miscdevice.h Thu Sep 4 15:38:37 2003 +++ b/include/linux/miscdevice.h Thu Sep 4 15:38:37 2003 @@ -1,5 +1,7 @@ #ifndef _LINUX_MISCDEVICE_H #define _LINUX_MISCDEVICE_H +#include +#include #define BUSMOUSE_MINOR 0 #define PSMOUSE_MINOR 1 @@ -48,4 +50,7 @@ extern int misc_register(struct miscdevice * misc); extern int misc_deregister(struct miscdevice * misc); +#define MODULE_ALIAS_MISCDEV(minor) \ + MODULE_ALIAS("char-major-" __stringify(MISC_MAJOR) \ + "-" __stringify(minor)) #endif diff -Nru a/include/linux/mmzone.h b/include/linux/mmzone.h --- a/include/linux/mmzone.h Thu Sep 4 15:38:35 2003 +++ b/include/linux/mmzone.h Thu Sep 4 15:38:35 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 Thu Sep 4 15:38:32 2003 +++ b/include/linux/net.h Thu Sep 4 15:38:32 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 Thu Sep 4 15:38:45 2003 +++ b/include/linux/netdevice.h Thu Sep 4 15:38:45 2003 @@ -37,9 +37,6 @@ #ifdef __KERNEL__ #include -#ifdef CONFIG_NET_PROFILE -#include -#endif struct divert_blk; struct vlan_group; @@ -168,9 +165,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); /* @@ -498,6 +495,7 @@ extern struct net_device *dev_base; /* All devices */ extern rwlock_t dev_base_lock; /* Device list lock */ +extern void probe_old_netdevs(void); extern int netdev_boot_setup_add(char *name, struct ifmap *map); extern int netdev_boot_setup_check(struct net_device *dev); extern struct net_device *dev_getbyhwaddr(unsigned short type, char *hwaddr); @@ -830,6 +828,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 Thu Sep 4 15:38:48 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 Thu Sep 4 15:38:48 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 Thu Sep 4 15:38:35 2003 +++ b/include/linux/netfilter_bridge.h Thu Sep 4 15:38:35 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 Thu Sep 4 15:38:48 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 Thu Sep 4 15:38:48 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 Thu Sep 4 15:38:48 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 Thu Sep 4 15:38:38 2003 +++ b/include/linux/nfsd/nfsfh.h Thu Sep 4 15:38:38 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 Thu Sep 4 15:38:29 2003 +++ b/include/linux/nfsd/state.h Thu Sep 4 15:38:29 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/page-flags.h b/include/linux/page-flags.h --- a/include/linux/page-flags.h Thu Sep 4 15:38:40 2003 +++ b/include/linux/page-flags.h Thu Sep 4 15:38:40 2003 @@ -191,6 +191,8 @@ #define PageSlab(page) test_bit(PG_slab, &(page)->flags) #define SetPageSlab(page) set_bit(PG_slab, &(page)->flags) #define ClearPageSlab(page) clear_bit(PG_slab, &(page)->flags) +#define TestClearPageSlab(page) test_and_clear_bit(PG_slab, &(page)->flags) +#define TestSetPageSlab(page) test_and_set_bit(PG_slab, &(page)->flags) #ifdef CONFIG_HIGHMEM #define PageHighMem(page) test_bit(PG_highmem, &(page)->flags) diff -Nru a/include/linux/pci_ids.h b/include/linux/pci_ids.h --- a/include/linux/pci_ids.h Thu Sep 4 15:38:32 2003 +++ b/include/linux/pci_ids.h Thu Sep 4 15:38:32 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 Thu Sep 4 15:38:34 2003 +++ b/include/linux/personality.h Thu Sep 4 15:38:34 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 Thu Sep 4 15:38:29 2003 +++ b/include/linux/pmu.h Thu Sep 4 15:38:29 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 Thu Sep 4 15:38:28 2003 +++ b/include/linux/proc_fs.h Thu Sep 4 15:38:28 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/rtc.h b/include/linux/rtc.h --- a/include/linux/rtc.h Thu Sep 4 15:38:28 2003 +++ b/include/linux/rtc.h Thu Sep 4 15:38:28 2003 @@ -101,6 +101,7 @@ int rtc_register(rtc_task_t *task); int rtc_unregister(rtc_task_t *task); int rtc_control(rtc_task_t *t, unsigned int cmd, unsigned long arg); +void rtc_get_rtc_time(struct rtc_time *rtc_tm); #endif /* __KERNEL__ */ diff -Nru a/include/linux/sched.h b/include/linux/sched.h --- a/include/linux/sched.h Thu Sep 4 15:38:29 2003 +++ b/include/linux/sched.h Thu Sep 4 15:38:29 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 Thu Sep 4 15:38:30 2003 +++ b/include/linux/serial_core.h Thu Sep 4 15:38:30 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 Thu Sep 4 15:38:37 2003 +++ b/include/linux/skbuff.h Thu Sep 4 15:38:37 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 */ @@ -389,6 +389,7 @@ */ static inline struct sk_buff *skb_share_check(struct sk_buff *skb, int pri) { + might_sleep_if(pri & __GFP_WAIT); if (skb_shared(skb)) { struct sk_buff *nskb = skb_clone(skb, pri); kfree_skb(skb); @@ -419,6 +420,7 @@ */ static inline struct sk_buff *skb_unshare(struct sk_buff *skb, int pri) { + might_sleep_if(pri & __GFP_WAIT); if (skb_cloned(skb)) { struct sk_buff *nskb = skb_copy(skb, pri); kfree_skb(skb); /* Free our shared copy */ @@ -1195,7 +1197,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 Thu Sep 4 15:38:32 2003 +++ b/include/linux/sonypi.h Thu Sep 4 15:38:32 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/sysctl.h b/include/linux/sysctl.h --- a/include/linux/sysctl.h Thu Sep 4 15:38:35 2003 +++ b/include/linux/sysctl.h Thu Sep 4 15:38:35 2003 @@ -603,7 +603,8 @@ DEV_HWMON=2, DEV_PARPORT=3, DEV_RAID=4, - DEV_MAC_HID=5 + DEV_MAC_HID=5, + DEV_SCSI=6, }; /* /proc/sys/dev/cdrom */ @@ -662,6 +663,11 @@ DEV_MAC_HID_MOUSE_BUTTON2_KEYCODE=4, DEV_MAC_HID_MOUSE_BUTTON3_KEYCODE=5, DEV_MAC_HID_ADB_MOUSE_SENDS_KEYCODES=6 +}; + +/* /proc/sys/dev/scsi */ +enum { + DEV_SCSI_LOGGING_LEVEL=1, }; /* /proc/sys/abi */ diff -Nru a/include/linux/tpqic02.h b/include/linux/tpqic02.h --- a/include/linux/tpqic02.h Thu Sep 4 15:38:30 2003 +++ b/include/linux/tpqic02.h Thu Sep 4 15:38:30 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 Thu Sep 4 15:38:34 2003 +++ b/include/linux/tty.h Thu Sep 4 15:38:34 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 Thu Sep 4 15:38:32 2003 +++ b/include/linux/usb.h Thu Sep 4 15:38:33 2003 @@ -329,7 +329,7 @@ { int actual; actual = snprintf (buf, size, "usb-%s-%s", dev->bus->bus_name, dev->devpath); - return (actual >= size) ? -1 : actual; + return (actual >= (int)size) ? -1 : actual; } /*-------------------------------------------------------------------------*/ @@ -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 Thu Sep 4 15:38:33 2003 +++ b/include/linux/usb_gadget.h Thu Sep 4 15:38:33 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 Thu Sep 4 15:38:48 2003 +++ b/include/linux/videodev.h Thu Sep 4 15:38:48 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 Thu Sep 4 15:38:35 2003 +++ b/include/linux/wait.h Thu Sep 4 15:38:35 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 Thu Sep 4 15:38:39 2003 +++ b/include/net/ax25.h Thu Sep 4 15:38:39 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 Thu Sep 4 15:38:32 2003 +++ b/include/net/ip6_tunnel.h Thu Sep 4 15:38:32 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 Thu Sep 4 15:38:42 2003 +++ b/include/net/ipv6.h Thu Sep 4 15:38:42 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 Thu Sep 4 15:38:37 2003 +++ b/include/net/irda/vlsi_ir.h Thu Sep 4 15:38:37 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/include/net/profile.h b/include/net/profile.h --- a/include/net/profile.h Thu Sep 4 15:38:29 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,312 +0,0 @@ -#include /* for CONFIG_NET_PROFILE */ -#ifndef _NET_PROFILE_H_ -#define _NET_PROFILE_H_ 1 - -#ifdef CONFIG_NET_PROFILE - -#include -#include -#include -#include - -#ifdef CONFIG_X86_TSC -#include -#endif - -struct net_profile_slot -{ - char id[16]; - struct net_profile_slot *next; - struct timeval entered; - struct timeval accumulator; - struct timeval irq; - int hits; - int active; - int underflow; -}; - -extern atomic_t net_profile_active; -extern struct timeval net_profile_adjust; -extern void net_profile_irq_adjust(struct timeval *entered, struct timeval* leaved); - -#ifdef CONFIG_X86_TSC - -static inline void net_profile_stamp(struct timeval *pstamp) -{ - rdtsc(pstamp->tv_usec, pstamp->tv_sec); -} - -static inline void net_profile_accumulate(struct timeval *entered, - struct timeval *leaved, - struct timeval *acc) -{ - __asm__ __volatile__ ("subl %2,%0\n\t" - "sbbl %3,%1\n\t" - "addl %4,%0\n\t" - "adcl %5,%1\n\t" - "subl net_profile_adjust+4,%0\n\t" - "sbbl $0,%1\n\t" - : "=r" (acc->tv_usec), "=r" (acc->tv_sec) - : "g" (entered->tv_usec), "g" (entered->tv_sec), - "g" (leaved->tv_usec), "g" (leaved->tv_sec), - "0" (acc->tv_usec), "1" (acc->tv_sec)); -} - -static inline void net_profile_sub(struct timeval *sub, - struct timeval *acc) -{ - __asm__ __volatile__ ("subl %2,%0\n\t" - "sbbl %3,%1\n\t" - : "=r" (acc->tv_usec), "=r" (acc->tv_sec) - : "g" (sub->tv_usec), "g" (sub->tv_sec), - "0" (acc->tv_usec), "1" (acc->tv_sec)); -} - -static inline void net_profile_add(struct timeval *add, - struct timeval *acc) -{ - __asm__ __volatile__ ("addl %2,%0\n\t" - "adcl %3,%1\n\t" - : "=r" (acc->tv_usec), "=r" (acc->tv_sec) - : "g" (add->tv_usec), "g" (add->tv_sec), - "0" (acc->tv_usec), "1" (acc->tv_sec)); -} - - -#elif defined (__alpha__) - -extern __u32 alpha_lo; -extern long alpha_hi; - -/* On alpha cycle counter has only 32 bits :-( :-( */ - -static inline void net_profile_stamp(struct timeval *pstamp) -{ - __u32 result; - __asm__ __volatile__ ("rpcc %0" : "r="(result)); - if (result <= alpha_lo) - alpha_hi++; - alpha_lo = result; - pstamp->tv_sec = alpha_hi; - pstamp->tv_usec = alpha_lo; -} - -static inline void net_profile_accumulate(struct timeval *entered, - struct timeval *leaved, - struct timeval *acc) -{ - time_t usecs = acc->tv_usec + leaved->tv_usec - entered->tv_usec - - net_profile_adjust.tv_usec; - time_t secs = acc->tv_sec + leaved->tv_sec - entered->tv_sec; - - if (usecs >= 0x100000000L) { - usecs -= 0x100000000L; - secs++; - } else if (usecs < -0x100000000L) { - usecs += 0x200000000L; - secs -= 2; - } else if (usecs < 0) { - usecs += 0x100000000L; - secs--; - } - acc->tv_sec = secs; - acc->tv_usec = usecs; -} - -static inline void net_profile_sub(struct timeval *entered, - struct timeval *leaved) -{ - time_t usecs = leaved->tv_usec - entered->tv_usec; - time_t secs = leaved->tv_sec - entered->tv_sec; - - if (usecs < 0) { - usecs += 0x100000000L; - secs--; - } - leaved->tv_sec = secs; - leaved->tv_usec = usecs; -} - -static inline void net_profile_add(struct timeval *entered, struct timeval *leaved) -{ - time_t usecs = leaved->tv_usec + entered->tv_usec; - time_t secs = leaved->tv_sec + entered->tv_sec; - - if (usecs >= 0x100000000L) { - usecs -= 0x100000000L; - secs++; - } - leaved->tv_sec = secs; - leaved->tv_usec = usecs; -} - - -#else - -static inline void net_profile_stamp(struct timeval *pstamp) -{ - /* Not "fast" counterpart! On architectures without - cpu clock "fast" routine is absolutely useless in this - situation. do_gettimeofday still says something on slow-slow-slow - boxes, though it eats more cpu time than the subject of - investigation :-) :-) - */ - do_gettimeofday(pstamp); -} - -static inline void net_profile_accumulate(struct timeval *entered, - struct timeval *leaved, - struct timeval *acc) -{ - time_t usecs = acc->tv_usec + leaved->tv_usec - entered->tv_usec - - net_profile_adjust.tv_usec; - time_t secs = acc->tv_sec + leaved->tv_sec - entered->tv_sec; - - if (usecs >= 1000000) { - usecs -= 1000000; - secs++; - } else if (usecs < -1000000) { - usecs += 2000000; - secs -= 2; - } else if (usecs < 0) { - usecs += 1000000; - secs--; - } - acc->tv_sec = secs; - acc->tv_usec = usecs; -} - -static inline void net_profile_sub(struct timeval *entered, - struct timeval *leaved) -{ - time_t usecs = leaved->tv_usec - entered->tv_usec; - time_t secs = leaved->tv_sec - entered->tv_sec; - - if (usecs < 0) { - usecs += 1000000; - secs--; - } - leaved->tv_sec = secs; - leaved->tv_usec = usecs; -} - -static inline void net_profile_add(struct timeval *entered, struct timeval *leaved) -{ - time_t usecs = leaved->tv_usec + entered->tv_usec; - time_t secs = leaved->tv_sec + entered->tv_sec; - - if (usecs >= 1000000) { - usecs -= 1000000; - secs++; - } - leaved->tv_sec = secs; - leaved->tv_usec = usecs; -} - - - -#endif - -static inline void net_profile_enter(struct net_profile_slot *s) -{ - unsigned long flags; - - save_flags(flags); - cli(); - if (s->active++ == 0) { - net_profile_stamp(&s->entered); - atomic_inc(&net_profile_active); - } - restore_flags(flags); -} - -static inline void net_profile_leave_irq(struct net_profile_slot *s) -{ - unsigned long flags; - - save_flags(flags); - cli(); - if (--s->active <= 0) { - if (s->active == 0) { - struct timeval curr_pstamp; - net_profile_stamp(&curr_pstamp); - net_profile_accumulate(&s->entered, &curr_pstamp, &s->accumulator); - if (!atomic_dec_and_test(&net_profile_active)) - net_profile_irq_adjust(&s->entered, &curr_pstamp); - } else { - s->underflow++; - } - } - s->hits++; - restore_flags(flags); -} - -static inline void net_profile_leave(struct net_profile_slot *s) -{ - unsigned long flags; - save_flags(flags); - cli(); - if (--s->active <= 0) { - if (s->active == 0) { - struct timeval curr_pstamp; - net_profile_stamp(&curr_pstamp); - net_profile_accumulate(&s->entered, &curr_pstamp, &s->accumulator); - atomic_dec(&net_profile_active); - } else { - s->underflow++; - } - } - s->hits++; - restore_flags(flags); -} - - -#define NET_PROFILE_ENTER(slot) net_profile_enter(&net_prof_##slot) -#define NET_PROFILE_LEAVE(slot) net_profile_leave(&net_prof_##slot) -#define NET_PROFILE_LEAVE_IRQ(slot) net_profile_leave_irq(&net_prof_##slot) - -#define NET_PROFILE_SKB_CLEAR(skb) ({ \ - skb->pstamp.tv_usec = 0; \ -}) - -#define NET_PROFILE_SKB_INIT(skb) ({ \ - net_profile_stamp(&skb->pstamp); \ -}) - -#define NET_PROFILE_SKB_PASSED(skb, slot) ({ \ - if (skb->pstamp.tv_usec) { \ - struct timeval cur_pstamp = skb->pstamp; \ - net_profile_stamp(&skb->pstamp); \ - net_profile_accumulate(&cur_pstamp, &skb->pstamp, &net_prof_##slot.accumulator); \ - net_prof_##slot.hits++; \ - }}) - -#define NET_PROFILE_DECL(slot) \ - extern struct net_profile_slot net_prof_##slot; - -#define NET_PROFILE_DEFINE(slot) \ - struct net_profile_slot net_prof_##slot = { #slot, }; - -#define NET_PROFILE_REGISTER(slot) net_profile_register(&net_prof_##slot) -#define NET_PROFILE_UNREGISTER(slot) net_profile_unregister(&net_prof_##slot) - -extern int net_profile_init(void); -extern int net_profile_register(struct net_profile_slot *); -extern int net_profile_unregister(struct net_profile_slot *); - -#else - -#define NET_PROFILE_ENTER(slot) do { /* nothing */ } while(0) -#define NET_PROFILE_LEAVE(slot) do { /* nothing */ } while(0) -#define NET_PROFILE_LEAVE_IRQ(slot) do { /* nothing */ } while(0) -#define NET_PROFILE_SKB_CLEAR(skb) do { /* nothing */ } while(0) -#define NET_PROFILE_SKB_INIT(skb) do { /* nothing */ } while(0) -#define NET_PROFILE_SKB_PASSED(skb, slot) do { /* nothing */ } while(0) -#define NET_PROFILE_DECL(slot) -#define NET_PROFILE_DEFINE(slot) -#define NET_PROFILE_REGISTER(slot) do { /* nothing */ } while(0) -#define NET_PROFILE_UNREGISTER(slot) do { /* nothing */ } while(0) - -#endif - -#endif diff -Nru a/include/scsi/scsi_device.h b/include/scsi/scsi_device.h --- a/include/scsi/scsi_device.h Thu Sep 4 15:38:29 2003 +++ b/include/scsi/scsi_device.h Thu Sep 4 15:38:29 2003 @@ -74,8 +74,6 @@ unsigned wdtr:1; /* Device supports WDTR messages */ unsigned ppr:1; /* Device supports PPR messages */ unsigned tagged_supported:1; /* Supports SCSI-II tagged queuing */ - unsigned tagged_queue:1;/* This is going away!!!! Look at simple_tags - instead!!! Please fix your driver now!! */ unsigned simple_tags:1; /* simple queue tag messages are enabled */ unsigned ordered_tags:1;/* ordered queue tag messages are enabled */ unsigned single_lun:1; /* Indicates we should only allow I/O to diff -Nru a/include/scsi/scsi_request.h b/include/scsi/scsi_request.h --- a/include/scsi/scsi_request.h Thu Sep 4 15:38:47 2003 +++ b/include/scsi/scsi_request.h Thu Sep 4 15:38:47 2003 @@ -45,7 +45,7 @@ level driver) of this request */ }; -extern struct scsi_request *scsi_allocate_request(struct scsi_device *); +extern struct scsi_request *scsi_allocate_request(struct scsi_device *, int); extern void scsi_release_request(struct scsi_request *); extern void scsi_wait_req(struct scsi_request *, const void *cmnd, void *buffer, unsigned bufflen, diff -Nru a/init/Kconfig b/init/Kconfig --- a/init/Kconfig Thu Sep 4 15:38:42 2003 +++ b/init/Kconfig Thu Sep 4 15:38:42 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 "Select only drivers expected to compile cleanly" 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 Thu Sep 4 15:38:30 2003 +++ b/init/main.c Thu Sep 4 15:38:30 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 Thu Sep 4 15:38:28 2003 +++ b/ipc/msg.c Thu Sep 4 15:38:28 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 Thu Sep 4 15:38:32 2003 +++ b/ipc/sem.c Thu Sep 4 15:38:32 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 Thu Sep 4 15:38:34 2003 +++ b/ipc/shm.c Thu Sep 4 15:38:34 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 Thu Sep 4 15:38:32 2003 +++ b/ipc/util.c Thu Sep 4 15:38:32 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 Thu Sep 4 15:38:30 2003 +++ b/kernel/Makefile Thu Sep 4 15:38:30 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 Thu Sep 4 15:38:34 2003 +++ b/kernel/compat.c Thu Sep 4 15:38:34 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/configs.c b/kernel/configs.c --- a/kernel/configs.c Thu Sep 4 15:38:32 2003 +++ b/kernel/configs.c Thu Sep 4 15:38:32 2003 @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include @@ -41,75 +42,59 @@ /**************************************************/ /* globals and useful constants */ -static char *IKCONFIG_NAME = "ikconfig"; -static char *IKCONFIG_VERSION = "0.5"; +static const char IKCONFIG_NAME[] = "ikconfig"; +static const char IKCONFIG_VERSION[] = "0.6"; -static int ikconfig_current_size = 0; -static struct proc_dir_entry *ikconfig_dir, *current_config, *built_with; - -static int -ikconfig_permission_current(struct inode *inode, int op, struct nameidata *nd) -{ - /* anyone can read the device, no one can write to it */ - return (op == MAY_READ) ? 0 : -EACCES; -} +static int ikconfig_size; +static struct proc_dir_entry *ikconfig_dir; static ssize_t -ikconfig_output_current(struct file *file, char *buf, - size_t len, loff_t * offset) -{ - int i, limit; - int cnt; - - limit = (ikconfig_current_size > len) ? len : ikconfig_current_size; - for (i = file->f_pos, cnt = 0; - i < ikconfig_current_size && cnt < limit; i++, cnt++) { - if (put_user(ikconfig_config[i], buf + cnt)) - return -EFAULT; - } - file->f_pos = i; - return cnt; -} - -static int -ikconfig_open_current(struct inode *inode, struct file *file) +ikconfig_read(struct file *file, char __user *buf, + size_t len, loff_t *offset) { - if (file->f_mode & FMODE_READ) { - inode->i_size = ikconfig_current_size; - file->f_pos = 0; - } - return 0; -} + loff_t pos = *offset; + ssize_t count; + + if (pos >= ikconfig_size) + return 0; + + count = min(len, (size_t)(ikconfig_size - pos)); + if(copy_to_user(buf, ikconfig_config + pos, count)) + return -EFAULT; -static int -ikconfig_close_current(struct inode *inode, struct file *file) -{ - return 0; + *offset += count; + return count; } -static struct file_operations ikconfig_file_ops = { - .read = ikconfig_output_current, - .open = ikconfig_open_current, - .release = ikconfig_close_current, -}; - -static struct inode_operations ikconfig_inode_ops = { - .permission = ikconfig_permission_current, +static struct file_operations config_fops = { + .owner = THIS_MODULE, + .read = ikconfig_read, }; /***************************************************/ -/* proc_read_built_with: let people read the info */ +/* built_with_show: let people read the info */ /* we have on the tools used to build this kernel */ -static int -proc_read_built_with(char *page, char **start, - off_t off, int count, int *eof, void *data) +static int builtwith_show(struct seq_file *seq, void *v) +{ + seq_printf(seq, + "Kernel: %s\nCompiler: %s\nVersion_in_Makefile: %s\n", + ikconfig_built_with, LINUX_COMPILER, UTS_RELEASE); + return 0; +} + +static int built_with_open(struct inode *inode, struct file *file) { - *eof = 1; - return sprintf(page, - "Kernel: %s\nCompiler: %s\nVersion_in_Makefile: %s\n", - ikconfig_built_with, LINUX_COMPILER, UTS_RELEASE); + return single_open(file, builtwith_show, PDE(inode)->data); } + +static struct file_operations builtwith_fops = { + .owner = THIS_MODULE, + .open = built_with_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; /***************************************************/ /* ikconfig_init: start up everything we need to */ @@ -117,41 +102,33 @@ int __init ikconfig_init(void) { - int result = 0; + struct proc_dir_entry *entry; printk(KERN_INFO "ikconfig %s with /proc/ikconfig\n", IKCONFIG_VERSION); /* create the ikconfig directory */ ikconfig_dir = proc_mkdir(IKCONFIG_NAME, NULL); - if (ikconfig_dir == NULL) { - result = -ENOMEM; + if (ikconfig_dir == NULL) goto leave; - } ikconfig_dir->owner = THIS_MODULE; /* create the current config file */ - current_config = create_proc_entry("config", S_IFREG | S_IRUGO, - ikconfig_dir); - if (current_config == NULL) { - result = -ENOMEM; + entry = create_proc_entry("config", S_IFREG | S_IRUGO, ikconfig_dir); + if (!entry) goto leave2; - } - current_config->proc_iops = &ikconfig_inode_ops; - current_config->proc_fops = &ikconfig_file_ops; - current_config->owner = THIS_MODULE; - ikconfig_current_size = strlen(ikconfig_config); - current_config->size = ikconfig_current_size; + + entry->proc_fops = &config_fops; + entry->size = ikconfig_size = strlen(ikconfig_config); /* create the "built with" file */ - built_with = create_proc_read_entry("built_with", 0444, ikconfig_dir, - proc_read_built_with, NULL); - if (built_with == NULL) { - result = -ENOMEM; + entry = create_proc_entry("built_with", S_IFREG | S_IRUGO, + ikconfig_dir); + if (!entry) goto leave3; - } - built_with->owner = THIS_MODULE; - goto leave; + entry->proc_fops = &builtwith_fops; + + return 0; leave3: /* remove the file from proc */ @@ -162,7 +139,7 @@ remove_proc_entry(IKCONFIG_NAME, NULL); leave: - return result; + return -ENOMEM; } /***************************************************/ diff -Nru a/kernel/exit.c b/kernel/exit.c --- a/kernel/exit.c Thu Sep 4 15:38:43 2003 +++ b/kernel/exit.c Thu Sep 4 15:38:43 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 Thu Sep 4 15:38:29 2003 +++ b/kernel/fork.c Thu Sep 4 15:38:29 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 Thu Sep 4 15:38:31 2003 +++ b/kernel/futex.c Thu Sep 4 15:38:31 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 Thu Sep 4 15:38:28 2003 +++ b/kernel/ksyms.c Thu Sep 4 15:38:28 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 Thu Sep 4 15:38:34 2003 +++ b/kernel/posix-timers.c Thu Sep 4 15:38:34 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 Thu Sep 4 15:38:42 2003 +++ b/kernel/sched.c Thu Sep 4 15:38:42 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 Thu Sep 4 15:38:29 2003 +++ b/kernel/sys.c Thu Sep 4 15:38:29 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/sysctl.c b/kernel/sysctl.c --- a/kernel/sysctl.c Thu Sep 4 15:38:29 2003 +++ b/kernel/sysctl.c Thu Sep 4 15:38:29 2003 @@ -35,6 +35,7 @@ #include #include #include +#include #include #ifdef CONFIG_ROOT_NFS diff -Nru a/kernel/timer.c b/kernel/timer.c --- a/kernel/timer.c Thu Sep 4 15:38:43 2003 +++ b/kernel/timer.c Thu Sep 4 15:38:43 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 Thu Sep 4 15:38:28 2003 +++ b/mm/fremap.c Thu Sep 4 15:38:28 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 Thu Sep 4 15:38:33 2003 +++ b/mm/memory.c Thu Sep 4 15:38:33 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/mremap.c b/mm/mremap.c --- a/mm/mremap.c Thu Sep 4 15:38:35 2003 +++ b/mm/mremap.c Thu Sep 4 15:38:35 2003 @@ -420,7 +420,7 @@ if (flags & MREMAP_MAYMOVE) { if (!(flags & MREMAP_FIXED)) { unsigned long map_flags = 0; - if (vma->vm_flags & VM_SHARED) + if (vma->vm_flags & VM_MAYSHARE) map_flags |= MAP_SHARED; new_addr = get_unmapped_area(vma->vm_file, 0, new_len, diff -Nru a/mm/page_alloc.c b/mm/page_alloc.c --- a/mm/page_alloc.c Thu Sep 4 15:38:29 2003 +++ b/mm/page_alloc.c Thu Sep 4 15:38:29 2003 @@ -220,6 +220,7 @@ 1 << PG_locked | 1 << PG_active | 1 << PG_reclaim | + 1 << PG_slab | 1 << PG_writeback ))) bad_page(function, page); if (PageDirty(page)) @@ -542,8 +543,7 @@ int do_retry; struct reclaim_state reclaim_state; - if (wait) - might_sleep(); + might_sleep_if(wait); cold = 0; if (gfp_mask & __GFP_COLD) diff -Nru a/mm/rmap.c b/mm/rmap.c --- a/mm/rmap.c Thu Sep 4 15:38:45 2003 +++ b/mm/rmap.c Thu Sep 4 15:38:45 2003 @@ -503,8 +503,7 @@ struct pte_chain *ret; struct pte_chain **pte_chainp; - if (gfp_flags & __GFP_WAIT) - might_sleep(); + might_sleep_if(gfp_flags & __GFP_WAIT); pte_chainp = &get_cpu_var(local_pte_chain); if (*pte_chainp) { diff -Nru a/mm/slab.c b/mm/slab.c --- a/mm/slab.c Thu Sep 4 15:38:42 2003 +++ b/mm/slab.c Thu Sep 4 15:38:42 2003 @@ -787,7 +787,8 @@ * vm_scan(). Shouldn't be a worry. */ while (i--) { - ClearPageSlab(page); + if (!TestClearPageSlab(page)) + BUG(); page++; } sub_page_state(nr_slab, nr_freed); @@ -1813,8 +1814,7 @@ static inline void cache_alloc_debugcheck_before(kmem_cache_t *cachep, int flags) { - if (flags & __GFP_WAIT) - might_sleep(); + might_sleep_if(flags & __GFP_WAIT); #if DEBUG kmem_flagcheck(cachep, flags); #endif diff -Nru a/mm/swapfile.c b/mm/swapfile.c --- a/mm/swapfile.c Thu Sep 4 15:38:30 2003 +++ b/mm/swapfile.c Thu Sep 4 15:38:30 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 Thu Sep 4 15:38:30 2003 +++ b/mm/vmscan.c Thu Sep 4 15:38:30 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 Thu Sep 4 15:38:29 2003 +++ b/net/Kconfig Thu Sep 4 15:38:29 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 @@ -264,6 +272,19 @@ 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" source "net/decnet/netfilter/Kconfig" @@ -655,7 +676,6 @@ source "net/sched/Kconfig" -#bool 'Network code profiler' CONFIG_NET_PROFILE endmenu menu "Network testing" diff -Nru a/net/appletalk/aarp.c b/net/appletalk/aarp.c --- a/net/appletalk/aarp.c Thu Sep 4 15:38:45 2003 +++ b/net/appletalk/aarp.c Thu Sep 4 15:38:45 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 Thu Sep 4 15:38:44 2003 +++ b/net/appletalk/atalk_proc.c Thu Sep 4 15:38:44 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 Thu Sep 4 15:38:47 2003 +++ b/net/appletalk/ddp.c Thu Sep 4 15:38:47 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/addr.c b/net/atm/addr.c --- a/net/atm/addr.c Thu Sep 4 15:38:29 2003 +++ b/net/atm/addr.c Thu Sep 4 15:38:29 2003 @@ -118,23 +118,24 @@ { unsigned long flags; struct atm_dev_addr *walk; - int total; + int total = 0, error; + struct sockaddr_atmsvc *tmp_buf, *tmp_bufp; + spin_lock_irqsave(&dev->lock, flags); - total = 0; - for (walk = dev->local; walk; walk = walk->next) { + for (walk = dev->local; walk; walk = walk->next) total += sizeof(struct sockaddr_atmsvc); - if (total > size) { - spin_unlock_irqrestore(&dev->lock, flags); - return -E2BIG; - } - if (copy_to_user(u_buf,&walk->addr, - sizeof(struct sockaddr_atmsvc))) { - spin_unlock_irqrestore(&dev->lock, flags); - return -EFAULT; - } - u_buf++; + tmp_buf = tmp_bufp = kmalloc(total, GFP_ATOMIC); + if (!tmp_buf) { + spin_unlock_irqrestore(&dev->lock, flags); + return -ENOMEM; } + for (walk = dev->local; walk; walk = walk->next) + memcpy(tmp_bufp++, &walk->addr, sizeof(struct sockaddr_atmsvc)); spin_unlock_irqrestore(&dev->lock, flags); - return total; + error = total > size ? -E2BIG : total; + if (copy_to_user(u_buf, tmp_buf, total < size ? total : size)) + error = -EFAULT; + kfree(tmp_buf); + return error; } diff -Nru a/net/atm/common.c b/net/atm/common.c --- a/net/atm/common.c Thu Sep 4 15:38:48 2003 +++ b/net/atm/common.c Thu Sep 4 15:38:48 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 Thu Sep 4 15:38:45 2003 +++ b/net/ax25/af_ax25.c Thu Sep 4 15:38:45 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 Thu Sep 4 15:38:30 2003 +++ b/net/ax25/ax25_dev.c Thu Sep 4 15:38:30 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 Thu Sep 4 15:38:39 2003 +++ b/net/ax25/ax25_route.c Thu Sep 4 15:38:39 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 Thu Sep 4 15:38:30 2003 +++ b/net/ax25/ax25_uid.c Thu Sep 4 15:38:30 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 Thu Sep 4 15:38:30 2003 +++ b/net/bluetooth/af_bluetooth.c Thu Sep 4 15:38:30 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 Thu Sep 4 15:38:39 2003 +++ b/net/bluetooth/bnep/core.c Thu Sep 4 15:38:39 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 Thu Sep 4 15:38:39 2003 +++ b/net/bluetooth/l2cap.c Thu Sep 4 15:38:39 2003 @@ -41,7 +41,6 @@ #include #include #include -#include #include #include #include @@ -200,7 +199,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/core.c b/net/bluetooth/rfcomm/core.c --- a/net/bluetooth/rfcomm/core.c Thu Sep 4 15:38:28 2003 +++ b/net/bluetooth/rfcomm/core.c Thu Sep 4 15:38:28 2003 @@ -1794,7 +1794,7 @@ if (p->next != &s->dlcs) return p->next; - for (p = s->list.next; p != &session_list; p = p->next) { + list_for_each(p, &session_list) { s = list_entry(p, struct rfcomm_session, list); __list_for_each(pp, &s->dlcs) { seq->private = s; diff -Nru a/net/bluetooth/rfcomm/sock.c b/net/bluetooth/rfcomm/sock.c --- a/net/bluetooth/rfcomm/sock.c Thu Sep 4 15:38:38 2003 +++ b/net/bluetooth/rfcomm/sock.c Thu Sep 4 15:38:38 2003 @@ -39,7 +39,6 @@ #include #include #include -#include #include #include #include @@ -114,7 +113,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 +130,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/bluetooth/sco.c b/net/bluetooth/sco.c --- a/net/bluetooth/sco.c Thu Sep 4 15:38:31 2003 +++ b/net/bluetooth/sco.c Thu Sep 4 15:38:31 2003 @@ -41,7 +41,6 @@ #include #include #include -#include #include #include #include diff -Nru a/net/bridge/Makefile b/net/bridge/Makefile --- a/net/bridge/Makefile Thu Sep 4 15:38:45 2003 +++ b/net/bridge/Makefile Thu Sep 4 15:38:45 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 Thu Sep 4 15:38:31 2003 +++ b/net/bridge/br_forward.c Thu Sep 4 15:38:31 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 Thu Sep 4 15:38:31 2003 +++ b/net/bridge/netfilter/Kconfig Thu Sep 4 15:38:31 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 Thu Sep 4 15:38:37 2003 +++ b/net/bridge/netfilter/Makefile Thu Sep 4 15:38:37 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 Thu Sep 4 15:38:48 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 Thu Sep 4 15:38:48 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/Makefile b/net/core/Makefile --- a/net/core/Makefile Thu Sep 4 15:38:45 2003 +++ b/net/core/Makefile Thu Sep 4 15:38:45 2003 @@ -11,6 +11,5 @@ obj-$(CONFIG_NETFILTER) += netfilter.o obj-$(CONFIG_NET_DIVERT) += dv.o -obj-$(CONFIG_NET_PROFILE) += profile.o obj-$(CONFIG_NET_PKTGEN) += pktgen.o obj-$(CONFIG_NET_RADIO) += wireless.o diff -Nru a/net/core/dev.c b/net/core/dev.c --- a/net/core/dev.c Thu Sep 4 15:38:34 2003 +++ b/net/core/dev.c Thu Sep 4 15:38:34 2003 @@ -99,7 +99,6 @@ #include #include #include -#include #include #include #include @@ -128,9 +127,6 @@ */ #undef OFFLINE_SAMPLE -NET_PROFILE_DEFINE(dev_queue_xmit) -NET_PROFILE_DEFINE(softnet_process) - /* * The list of packet types we will receive (as opposed to discard) * and the routines to invoke. @@ -845,11 +841,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 +1202,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 +1351,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 +1381,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 +1529,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 +1649,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 +1664,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 +1702,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 +1903,7 @@ while (*pos < NR_CPUS) if (cpu_online(*pos)) { - rc = &netdev_rx_stat[*pos]; + rc = &per_cpu(netdev_rx_stat, *pos); break; } else ++*pos; @@ -2986,7 +2977,6 @@ */ static int __init net_dev_init(void) { - struct net_device *dev, **dp; int i, rc = -ENOMEM; BUG_ON(!dev_boot_phase); @@ -3021,87 +3011,14 @@ atomic_set(&queue->backlog_dev.refcnt, 1); } -#ifdef CONFIG_NET_PROFILE - net_profile_init(); - NET_PROFILE_REGISTER(dev_queue_xmit); - NET_PROFILE_REGISTER(softnet_process); -#endif - #ifdef OFFLINE_SAMPLE samp_timer.expires = jiffies + (10 * HZ); add_timer(&samp_timer); #endif - /* - * Add the devices. - * If the call to dev->init fails, the dev is removed - * from the chain disconnecting the device until the - * next reboot. - * - * NB At boot phase networking is dead. No locking is required. - * But we still preserve dev_base_lock for sanity. - */ - - dp = &dev_base; - while ((dev = *dp) != NULL) { - spin_lock_init(&dev->queue_lock); - spin_lock_init(&dev->xmit_lock); -#ifdef CONFIG_NET_FASTROUTE - dev->fastpath_lock = RW_LOCK_UNLOCKED; -#endif - dev->xmit_lock_owner = -1; - dev->iflink = -1; - dev_hold(dev); - - /* - * Allocate name. If the init() fails - * the name will be reissued correctly. - */ - if (strchr(dev->name, '%')) - dev_alloc_name(dev, dev->name); - - /* - * Check boot time settings for the device. - */ - netdev_boot_setup_check(dev); - - if ( (dev->init && dev->init(dev)) || - netdev_register_sysfs(dev) ) { - /* - * It failed to come up. It will be unhooked later. - * dev_alloc_name can now advance to next suitable - * name that is checked next. - */ - dp = &dev->next; - } else { - dp = &dev->next; - dev->ifindex = dev_new_index(); - dev->reg_state = NETREG_REGISTERED; - if (dev->iflink == -1) - dev->iflink = dev->ifindex; - if (!dev->rebuild_header) - dev->rebuild_header = default_rebuild_header; - dev_init_scheduler(dev); - set_bit(__LINK_STATE_PRESENT, &dev->state); - } - } - - /* - * Unhook devices that failed to come up - */ - dp = &dev_base; - while ((dev = *dp) != NULL) { - if (dev->reg_state != NETREG_REGISTERED) { - write_lock_bh(&dev_base_lock); - *dp = dev->next; - write_unlock_bh(&dev_base_lock); - dev_put(dev); - } else { - dp = &dev->next; - } - } - dev_boot_phase = 0; + + probe_old_netdevs(); open_softirq(NET_TX_SOFTIRQ, net_tx_action, NULL); open_softirq(NET_RX_SOFTIRQ, net_rx_action, NULL); diff -Nru a/net/core/ethtool.c b/net/core/ethtool.c --- a/net/core/ethtool.c Thu Sep 4 15:38:31 2003 +++ b/net/core/ethtool.c Thu Sep 4 15:38:31 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/link_watch.c b/net/core/link_watch.c --- a/net/core/link_watch.c Thu Sep 4 15:38:28 2003 +++ b/net/core/link_watch.c Thu Sep 4 15:38:28 2003 @@ -11,7 +11,6 @@ * */ -#include #include #include #include diff -Nru a/net/core/netfilter.c b/net/core/netfilter.c --- a/net/core/netfilter.c Thu Sep 4 15:38:33 2003 +++ b/net/core/netfilter.c Thu Sep 4 15:38:33 2003 @@ -101,7 +101,7 @@ if (down_interruptible(&nf_sockopt_mutex) != 0) return -EINTR; - for (i = nf_sockopts.next; i != &nf_sockopts; i = i->next) { + list_for_each(i, &nf_sockopts) { struct nf_sockopt_ops *ops = (struct nf_sockopt_ops *)i; if (ops->pf == reg->pf && (overlap(ops->set_optmin, ops->set_optmax, @@ -296,7 +296,7 @@ if (down_interruptible(&nf_sockopt_mutex) != 0) return -EINTR; - for (i = nf_sockopts.next; i != &nf_sockopts; i = i->next) { + list_for_each(i, &nf_sockopts) { ops = (struct nf_sockopt_ops *)i; if (ops->pf == pf) { if (get) { @@ -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/profile.c b/net/core/profile.c --- a/net/core/profile.c Thu Sep 4 15:38:47 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,294 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include - -#ifdef CONFIG_NET_PROFILE - -atomic_t net_profile_active; -struct timeval net_profile_adjust; - -NET_PROFILE_DEFINE(total); - -struct net_profile_slot *net_profile_chain = &net_prof_total; - -#ifdef __alpha__ -__u32 alpha_lo; -long alpha_hi; - -static void alpha_tick(unsigned long); - -static struct timer_list alpha_timer = TIMER_INITIALIZER(alpha_tick, 0, 0); - -void alpha_tick(unsigned long dummy) -{ - struct timeval dummy_stamp; - net_profile_stamp(&dummy_stamp); - alpha_timer.expires = jiffies + 4*HZ; - add_timer(&alpha_timer); -} - -#endif - -void net_profile_irq_adjust(struct timeval *entered, struct timeval* leaved) -{ - struct net_profile_slot *s; - - net_profile_sub(entered, leaved); - for (s = net_profile_chain; s; s = s->next) { - if (s->active) - net_profile_add(leaved, &s->irq); - } -} - - -#ifdef CONFIG_PROC_FS -static int profile_read_proc(char *buffer, char **start, off_t offset, - int length, int *eof, void *data) -{ - off_t pos=0; - off_t begin=0; - int len=0; - struct net_profile_slot *s; - - len+= sprintf(buffer, "Slot Hits Hi Lo OnIrqHi OnIrqLo Ufl\n"); - - if (offset == 0) { - cli(); - net_prof_total.active = 1; - atomic_inc(&net_profile_active); - NET_PROFILE_LEAVE(total); - sti(); - } - for (s = net_profile_chain; s; s = s->next) { - struct net_profile_slot tmp; - - cli(); - tmp = *s; - - /* Wrong, but pretty close to truth */ - - s->accumulator.tv_sec = 0; - s->accumulator.tv_usec = 0; - s->irq.tv_sec = 0; - s->irq.tv_usec = 0; - s->hits = 0; - s->underflow = 0; - /* Repair active count, it is possible, only if code has a bug */ - if (s->active) { - s->active = 0; - atomic_dec(&net_profile_active); - } - sti(); - - net_profile_sub(&tmp.irq, &tmp.accumulator); - - len += sprintf(buffer+len,"%-15s %-10d %-10ld %-10lu %-10lu %-10lu %d/%d", - tmp.id, - tmp.hits, - tmp.accumulator.tv_sec, - tmp.accumulator.tv_usec, - tmp.irq.tv_sec, - tmp.irq.tv_usec, - tmp.underflow, tmp.active); - - buffer[len++]='\n'; - - pos=begin+len; - if(posoffset+length) - goto done; - } - *eof = 1; - -done: - *start=buffer+(offset-begin); - len-=(offset-begin); - if(len>length) - len=length; - if (len < 0) - len = 0; - if (offset == 0) { - cli(); - net_prof_total.active = 0; - net_prof_total.hits = 0; - net_profile_stamp(&net_prof_total.entered); - sti(); - } - return len; -} -#endif - -struct iphdr whitehole_iph; -int whitehole_count; - -static int whitehole_xmit(struct sk_buff *skb, struct net_device *dev) -{ - struct net_device_stats *stats; - - stats = (struct net_device_stats *)dev->priv; - stats->tx_packets++; - stats->tx_bytes+=skb->len; - - dev_kfree_skb(skb); - return 0; -} - -static void whitehole_inject(unsigned long); -int whitehole_init(struct net_device *dev); - -static struct timer_list whitehole_timer = - TIMER_INITIALIZER(whitehole_inject, 0, 0); - -static struct net_device whitehole_dev = { - .name = "whitehole", - .init = whitehole_init, -}; - -static int whitehole_open(struct net_device *dev) -{ - whitehole_count = 100000; - whitehole_timer.expires = jiffies + 5*HZ; - add_timer(&whitehole_timer); - return 0; -} - -static int whitehole_close(struct net_device *dev) -{ - del_timer(&whitehole_timer); - return 0; -} - -static void whitehole_inject(unsigned long dummy) -{ - struct net_device_stats *stats = (struct net_device_stats *)whitehole_dev.priv; - extern int netdev_dropping; - - do { - struct iphdr *iph; - struct sk_buff *skb = alloc_skb(128, GFP_ATOMIC); - if (!skb) - break; - skb_reserve(skb, 32); - iph = (struct iphdr*)skb_put(skb, sizeof(*iph)); - skb->mac.raw = ((u8*)iph) - 14; - memcpy(iph, &whitehole_iph, sizeof(*iph)); - skb->protocol = __constant_htons(ETH_P_IP); - skb->dev = &whitehole_dev; - skb->pkt_type = PACKET_HOST; - stats->rx_packets++; - stats->rx_bytes += skb->len; - netif_rx(skb); - whitehole_count--; - } while (netdev_dropping == 0 && whitehole_count>0); - if (whitehole_count > 0) { - whitehole_timer.expires = jiffies + 1; - add_timer(&whitehole_timer); - } -} - -static struct net_device_stats *whitehole_get_stats(struct net_device *dev) -{ - struct net_device_stats *stats = (struct net_device_stats *) dev->priv; - return stats; -} - -int __init whitehole_init(struct net_device *dev) -{ - dev->priv = kmalloc(sizeof(struct net_device_stats), GFP_KERNEL); - if (dev->priv == NULL) - return -ENOBUFS; - memset(dev->priv, 0, sizeof(struct net_device_stats)); - dev->get_stats = whitehole_get_stats; - dev->hard_start_xmit = whitehole_xmit; - dev->open = whitehole_open; - dev->stop = whitehole_close; - ether_setup(dev); - dev->tx_queue_len = 0; - dev->flags |= IFF_NOARP; - dev->flags &= ~(IFF_BROADCAST|IFF_MULTICAST); - dev->iflink = 0; - whitehole_iph.ihl = 5; - whitehole_iph.version = 4; - whitehole_iph.ttl = 2; - whitehole_iph.saddr = in_aton("193.233.7.21"); - whitehole_iph.daddr = in_aton("193.233.7.10"); - whitehole_iph.tot_len = htons(20); - whitehole_iph.check = ip_compute_csum((void *)&whitehole_iph, 20); - return 0; -} - -int net_profile_register(struct net_profile_slot *slot) -{ - cli(); - slot->next = net_profile_chain; - net_profile_chain = slot; - sti(); - return 0; -} - -int net_profile_unregister(struct net_profile_slot *slot) -{ - struct net_profile_slot **sp, *s; - - for (sp = &net_profile_chain; (s = *sp) != NULL; sp = &s->next) { - if (s == slot) { - cli(); - *sp = s->next; - sti(); - return 0; - } - } - return -ESRCH; -} - - -int __init net_profile_init(void) -{ - int i; - -#ifdef CONFIG_PROC_FS - create_proc_read_entry("net/profile", 0, 0, profile_read_proc, NULL); -#endif - - register_netdevice(&whitehole_dev); - - printk("Evaluating net profiler cost ..."); -#ifdef __alpha__ - alpha_tick(0); -#endif - for (i=0; i<1024; i++) { - NET_PROFILE_ENTER(total); - NET_PROFILE_LEAVE(total); - } - if (net_prof_total.accumulator.tv_sec) { - printk(" too high!\n"); - } else { - net_profile_adjust.tv_usec = net_prof_total.accumulator.tv_usec>>10; - printk("%ld units\n", net_profile_adjust.tv_usec); - } - net_prof_total.hits = 0; - net_profile_stamp(&net_prof_total.entered); - return 0; -} - -#endif diff -Nru a/net/core/scm.c b/net/core/scm.c --- a/net/core/scm.c Thu Sep 4 15:38:32 2003 +++ b/net/core/scm.c Thu Sep 4 15:38:32 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 Thu Sep 4 15:38:40 2003 +++ b/net/core/skbuff.c Thu Sep 4 15:38:40 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 Thu Sep 4 15:38:35 2003 +++ b/net/decnet/af_decnet.c Thu Sep 4 15:38:35 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/decnet/dn_dev.c b/net/decnet/dn_dev.c --- a/net/decnet/dn_dev.c Thu Sep 4 15:38:31 2003 +++ b/net/decnet/dn_dev.c Thu Sep 4 15:38:31 2003 @@ -35,7 +35,6 @@ #include #include #include -#include #include #include #include diff -Nru a/net/econet/af_econet.c b/net/econet/af_econet.c --- a/net/econet/af_econet.c Thu Sep 4 15:38:34 2003 +++ b/net/econet/af_econet.c Thu Sep 4 15:38:34 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 Thu Sep 4 15:38:30 2003 +++ b/net/ipv4/af_inet.c Thu Sep 4 15:38:30 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 Thu Sep 4 15:38:45 2003 +++ b/net/ipv4/icmp.c Thu Sep 4 15:38:45 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 Thu Sep 4 15:38:47 2003 +++ b/net/ipv4/igmp.c Thu Sep 4 15:38:47 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 Thu Sep 4 15:38:47 2003 +++ b/net/ipv4/ip_output.c Thu Sep 4 15:38:47 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 Thu Sep 4 15:38:44 2003 +++ b/net/ipv4/ipvs/ip_vs_conn.c Thu Sep 4 15:38:44 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_ctl.c b/net/ipv4/ipvs/ip_vs_ctl.c --- a/net/ipv4/ipvs/ip_vs_ctl.c Thu Sep 4 15:38:44 2003 +++ b/net/ipv4/ipvs/ip_vs_ctl.c Thu Sep 4 15:38:44 2003 @@ -31,7 +31,6 @@ #include #include #include -#include #include #include 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 Thu Sep 4 15:38:43 2003 +++ b/net/ipv4/ipvs/ip_vs_dh.c Thu Sep 4 15:38:43 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 Thu Sep 4 15:38:44 2003 +++ b/net/ipv4/ipvs/ip_vs_lblc.c Thu Sep 4 15:38:44 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 Thu Sep 4 15:38:43 2003 +++ b/net/ipv4/ipvs/ip_vs_lblcr.c Thu Sep 4 15:38:43 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 Thu Sep 4 15:38:40 2003 +++ b/net/ipv4/ipvs/ip_vs_sh.c Thu Sep 4 15:38:40 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 Thu Sep 4 15:38:28 2003 +++ b/net/ipv4/ipvs/ip_vs_sync.c Thu Sep 4 15:38:28 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 Thu Sep 4 15:38:43 2003 +++ b/net/ipv4/netfilter/Kconfig Thu Sep 4 15:38:43 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 Thu Sep 4 15:38:30 2003 +++ b/net/ipv4/netfilter/Makefile Thu Sep 4 15:38:30 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 Thu Sep 4 15:38:42 2003 +++ b/net/ipv4/netfilter/arp_tables.c Thu Sep 4 15:38:42 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 Thu Sep 4 15:38:40 2003 +++ b/net/ipv4/netfilter/arpt_mangle.c Thu Sep 4 15:38:40 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 Thu Sep 4 15:38:28 2003 +++ b/net/ipv4/netfilter/arptable_filter.c Thu Sep 4 15:38:28 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 Thu Sep 4 15:38:28 2003 +++ b/net/ipv4/netfilter/ip_conntrack_core.c Thu Sep 4 15:38:28 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 Thu Sep 4 15:38:42 2003 +++ b/net/ipv4/netfilter/ip_conntrack_ftp.c Thu Sep 4 15:38:42 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 Thu Sep 4 15:38:42 2003 +++ b/net/ipv4/netfilter/ip_conntrack_irc.c Thu Sep 4 15:38:42 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 Thu Sep 4 15:38:33 2003 +++ b/net/ipv4/netfilter/ip_conntrack_standalone.c Thu Sep 4 15:38:33 2003 @@ -14,7 +14,6 @@ #include #include #include -#include #include #define ASSERT_READ_LOCK(x) MUST_BE_READ_LOCKED(&ip_conntrack_lock) @@ -151,8 +150,7 @@ } /* Now iterate through expecteds. */ - for (e = ip_conntrack_expect_list.next; - e != &ip_conntrack_expect_list; e = e->next) { + list_for_each(e, &ip_conntrack_expect_list) { unsigned int last_len; struct ip_conntrack_expect *expect = (struct ip_conntrack_expect *)e; @@ -320,7 +318,7 @@ struct list_head *i; WRITE_LOCK(&ip_conntrack_lock); - for (i = protocol_list.next; i != &protocol_list; i = i->next) { + list_for_each(i, &protocol_list) { if (((struct ip_conntrack_protocol *)i)->proto == proto->proto) { ret = -EBUSY; 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 Thu Sep 4 15:38:31 2003 +++ b/net/ipv4/netfilter/ip_conntrack_tftp.c Thu Sep 4 15:38:31 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 Thu Sep 4 15:38:42 2003 +++ b/net/ipv4/netfilter/ip_fw_compat_masq.c Thu Sep 4 15:38:42 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 Thu Sep 4 15:38:30 2003 +++ b/net/ipv4/netfilter/ip_nat_amanda.c Thu Sep 4 15:38:30 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 Thu Sep 4 15:38:30 2003 +++ b/net/ipv4/netfilter/ip_nat_core.c Thu Sep 4 15:38:30 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); } @@ -160,8 +157,8 @@ continue; } - if ((mr->range[i].flags & IP_NAT_RANGE_PROTO_SPECIFIED) - && proto->in_range(&newtuple, IP_NAT_MANIP_SRC, + if (!(mr->range[i].flags & IP_NAT_RANGE_PROTO_SPECIFIED) + || proto->in_range(&newtuple, IP_NAT_MANIP_SRC, &mr->range[i].min, &mr->range[i].max)) return 1; } @@ -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 Thu Sep 4 15:38:39 2003 +++ b/net/ipv4/netfilter/ip_nat_ftp.c Thu Sep 4 15:38:39 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 Thu Sep 4 15:38:30 2003 +++ b/net/ipv4/netfilter/ip_nat_helper.c Thu Sep 4 15:38:30 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 Thu Sep 4 15:38:47 2003 +++ b/net/ipv4/netfilter/ip_nat_irc.c Thu Sep 4 15:38:47 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 Thu Sep 4 15:38:32 2003 +++ b/net/ipv4/netfilter/ip_nat_rule.c Thu Sep 4 15:38:32 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 Thu Sep 4 15:38:42 2003 +++ b/net/ipv4/netfilter/ip_nat_snmp_basic.c Thu Sep 4 15:38:42 2003 @@ -50,13 +50,14 @@ #include #include #include -#include #include #include #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 +1358,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 Thu Sep 4 15:38:42 2003 +++ b/net/ipv4/netfilter/ip_nat_standalone.c Thu Sep 4 15:38:42 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) @@ -272,7 +271,7 @@ struct list_head *i; WRITE_LOCK(&ip_nat_lock); - for (i = protos.next; i != &protos; i = i->next) { + list_for_each(i, &protos) { if (((struct ip_nat_protocol *)i)->protonum == proto->protonum) { ret = -EBUSY; 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 Thu Sep 4 15:38:31 2003 +++ b/net/ipv4/netfilter/ip_nat_tftp.c Thu Sep 4 15:38:31 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 Thu Sep 4 15:38:30 2003 +++ b/net/ipv4/netfilter/ip_tables.c Thu Sep 4 15:38:30 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 Thu Sep 4 15:38:43 2003 +++ b/net/ipv4/netfilter/ipchains_core.c Thu Sep 4 15:38:43 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 Thu Sep 4 15:38:32 2003 +++ b/net/ipv4/netfilter/ipfwadm_core.c Thu Sep 4 15:38:32 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 Thu Sep 4 15:38:48 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 Thu Sep 4 15:38:45 2003 +++ b/net/ipv4/netfilter/ipt_DSCP.c Thu Sep 4 15:38:45 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 Thu Sep 4 15:38:47 2003 +++ b/net/ipv4/netfilter/ipt_ECN.c Thu Sep 4 15:38:47 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 Thu Sep 4 15:38:43 2003 +++ b/net/ipv4/netfilter/ipt_LOG.c Thu Sep 4 15:38:43 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 Thu Sep 4 15:38:35 2003 +++ b/net/ipv4/netfilter/ipt_MARK.c Thu Sep 4 15:38:35 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 Thu Sep 4 15:38:37 2003 +++ b/net/ipv4/netfilter/ipt_MASQUERADE.c Thu Sep 4 15:38:37 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 Thu Sep 4 15:38:47 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 Thu Sep 4 15:38:48 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 Thu Sep 4 15:38:32 2003 +++ b/net/ipv4/netfilter/ipt_REDIRECT.c Thu Sep 4 15:38:32 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 Thu Sep 4 15:38:43 2003 +++ b/net/ipv4/netfilter/ipt_REJECT.c Thu Sep 4 15:38:43 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 Thu Sep 4 15:38:48 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 Thu Sep 4 15:38:34 2003 +++ b/net/ipv4/netfilter/ipt_TCPMSS.c Thu Sep 4 15:38:34 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 Thu Sep 4 15:38:29 2003 +++ b/net/ipv4/netfilter/ipt_TOS.c Thu Sep 4 15:38:29 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 Thu Sep 4 15:38:32 2003 +++ b/net/ipv4/netfilter/ipt_ULOG.c Thu Sep 4 15:38:32 2003 @@ -36,7 +36,6 @@ */ #include -#include #include #include #include @@ -46,7 +45,6 @@ #include #include #include -#include #include #include #include @@ -55,7 +53,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 Thu Sep 4 15:38:38 2003 +++ b/net/ipv4/netfilter/ipt_ah.c Thu Sep 4 15:38:38 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 Thu Sep 4 15:38:44 2003 +++ b/net/ipv4/netfilter/ipt_conntrack.c Thu Sep 4 15:38:44 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 Thu Sep 4 15:38:39 2003 +++ b/net/ipv4/netfilter/ipt_dscp.c Thu Sep 4 15:38:39 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 Thu Sep 4 15:38:33 2003 +++ b/net/ipv4/netfilter/ipt_ecn.c Thu Sep 4 15:38:33 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 Thu Sep 4 15:38:34 2003 +++ b/net/ipv4/netfilter/ipt_esp.c Thu Sep 4 15:38:34 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 Thu Sep 4 15:38:40 2003 +++ b/net/ipv4/netfilter/ipt_helper.c Thu Sep 4 15:38:40 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 Thu Sep 4 15:38:48 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 Thu Sep 4 15:38:29 2003 +++ b/net/ipv4/netfilter/ipt_limit.c Thu Sep 4 15:38:29 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 Thu Sep 4 15:38:29 2003 +++ b/net/ipv4/netfilter/ipt_mac.c Thu Sep 4 15:38:29 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 Thu Sep 4 15:38:48 2003 +++ b/net/ipv4/netfilter/ipt_mark.c Thu Sep 4 15:38:48 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 Thu Sep 4 15:38:30 2003 +++ b/net/ipv4/netfilter/ipt_multiport.c Thu Sep 4 15:38:30 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 Thu Sep 4 15:38:45 2003 +++ b/net/ipv4/netfilter/ipt_owner.c Thu Sep 4 15:38:45 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 Thu Sep 4 15:38:31 2003 +++ b/net/ipv4/netfilter/ipt_physdev.c Thu Sep 4 15:38:31 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 Thu Sep 4 15:38:48 2003 +++ b/net/ipv4/netfilter/ipt_state.c Thu Sep 4 15:38:48 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 Thu Sep 4 15:38:29 2003 +++ b/net/ipv4/netfilter/ipt_tcpmss.c Thu Sep 4 15:38:29 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 Thu Sep 4 15:38:45 2003 +++ b/net/ipv4/netfilter/ipt_tos.c Thu Sep 4 15:38:45 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 Thu Sep 4 15:38:37 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 Thu Sep 4 15:38:32 2003 +++ b/net/ipv4/netfilter/iptable_filter.c Thu Sep 4 15:38:32 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 Thu Sep 4 15:38:43 2003 +++ b/net/ipv4/netfilter/iptable_mangle.c Thu Sep 4 15:38:43 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 Thu Sep 4 15:38:47 2003 +++ b/net/ipv4/route.c Thu Sep 4 15:38:47 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/ipv4/udp.c b/net/ipv4/udp.c --- a/net/ipv4/udp.c Thu Sep 4 15:38:30 2003 +++ b/net/ipv4/udp.c Thu Sep 4 15:38:30 2003 @@ -1349,64 +1349,65 @@ /* ------------------------------------------------------------------------ */ #ifdef CONFIG_PROC_FS -static __inline__ struct sock *udp_get_bucket(struct seq_file *seq, loff_t *pos) +static struct sock *udp_get_first(struct seq_file *seq) { - int i; struct sock *sk; - struct hlist_node *node; - loff_t l = *pos; struct udp_iter_state *state = seq->private; - for (; state->bucket < UDP_HTABLE_SIZE; ++state->bucket) { - i = 0; + for (state->bucket = 0; state->bucket < UDP_HTABLE_SIZE; ++state->bucket) { + struct hlist_node *node; sk_for_each(sk, node, &udp_hash[state->bucket]) { - if (sk->sk_family != state->family) { - ++i; - continue; - } - if (l--) { - ++i; - continue; - } - *pos = i; - goto out; + if (sk->sk_family == state->family) + goto found; } } sk = NULL; -out: +found: return sk; } +static struct sock *udp_get_next(struct seq_file *seq, struct sock *sk) +{ + struct udp_iter_state *state = seq->private; + + do { + sk = sk_next(sk); +try_again: + ; + } while (sk && sk->sk_family != state->family); + + if (!sk && ++state->bucket < UDP_HTABLE_SIZE) { + sk = sk_head(&udp_hash[state->bucket]); + goto try_again; + } + return sk; +} + +static struct sock *udp_get_idx(struct seq_file *seq, loff_t pos) +{ + struct sock *sk = udp_get_first(seq); + + if (sk) + while(pos && (sk = udp_get_next(seq, sk)) != NULL) + --pos; + return pos ? NULL : sk; +} + static void *udp_seq_start(struct seq_file *seq, loff_t *pos) { read_lock(&udp_hash_lock); - return *pos ? udp_get_bucket(seq, pos) : (void *)1; + return *pos ? udp_get_idx(seq, *pos-1) : (void *)1; } static void *udp_seq_next(struct seq_file *seq, void *v, loff_t *pos) { struct sock *sk; - struct hlist_node *node; - struct udp_iter_state *state; - - if (v == (void *)1) { - sk = udp_get_bucket(seq, pos); - goto out; - } - state = seq->private; + if (v == (void *)1) + sk = udp_get_idx(seq, 0); + else + sk = udp_get_next(seq, v); - sk = v; - sk_for_each_continue(sk, node) - if (sk->sk_family == state->family) - goto out; - - if (++state->bucket >= UDP_HTABLE_SIZE) - goto out; - - *pos = 0; - sk = udp_get_bucket(seq, pos); -out: ++*pos; return sk; } diff -Nru a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c --- a/net/ipv6/addrconf.c Thu Sep 4 15:38:45 2003 +++ b/net/ipv6/addrconf.c Thu Sep 4 15:38:45 2003 @@ -57,7 +57,6 @@ #include #include -#include #include #include diff -Nru a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c --- a/net/ipv6/af_inet6.c Thu Sep 4 15:38:35 2003 +++ b/net/ipv6/af_inet6.c Thu Sep 4 15:38:35 2003 @@ -40,7 +40,6 @@ #include #include #include -#include #include #include @@ -893,3 +892,5 @@ } module_exit(inet6_exit); #endif /* MODULE */ + +MODULE_ALIAS_NETPROTO(PF_INET6); diff -Nru a/net/ipv6/ah6.c b/net/ipv6/ah6.c --- a/net/ipv6/ah6.c Thu Sep 4 15:38:39 2003 +++ b/net/ipv6/ah6.c Thu Sep 4 15:38:39 2003 @@ -28,7 +28,6 @@ #include #include #include -#include #include #include #include diff -Nru a/net/ipv6/icmp.c b/net/ipv6/icmp.c --- a/net/ipv6/icmp.c Thu Sep 4 15:38:31 2003 +++ b/net/ipv6/icmp.c Thu Sep 4 15:38:31 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 Thu Sep 4 15:38:30 2003 +++ b/net/ipv6/ip6_flowlabel.c Thu Sep 4 15:38:30 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 Thu Sep 4 15:38:29 2003 +++ b/net/ipv6/ip6_output.c Thu Sep 4 15:38:29 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 Thu Sep 4 15:38:29 2003 +++ b/net/ipv6/ip6_tunnel.c Thu Sep 4 15:38:29 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 Thu Sep 4 15:38:40 2003 +++ b/net/ipv6/ipv6_syms.c Thu Sep 4 15:38:40 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 Thu Sep 4 15:38:43 2003 +++ b/net/ipv6/mcast.c Thu Sep 4 15:38:43 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 Thu Sep 4 15:38:43 2003 +++ b/net/ipv6/netfilter/Kconfig Thu Sep 4 15:38:43 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 Thu Sep 4 15:38:43 2003 +++ b/net/ipv6/netfilter/ip6_tables.c Thu Sep 4 15:38:43 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 Thu Sep 4 15:38:44 2003 +++ b/net/ipv6/netfilter/ip6t_MARK.c Thu Sep 4 15:38:44 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 Thu Sep 4 15:38:28 2003 +++ b/net/ipv6/netfilter/ip6t_eui64.c Thu Sep 4 15:38:28 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 Thu Sep 4 15:38:46 2003 +++ b/net/ipv6/netfilter/ip6t_length.c Thu Sep 4 15:38:46 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 Thu Sep 4 15:38:30 2003 +++ b/net/ipv6/netfilter/ip6t_limit.c Thu Sep 4 15:38:30 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 Thu Sep 4 15:38:44 2003 +++ b/net/ipv6/netfilter/ip6t_mac.c Thu Sep 4 15:38:44 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 Thu Sep 4 15:38:48 2003 +++ b/net/ipv6/netfilter/ip6t_mark.c Thu Sep 4 15:38:48 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 Thu Sep 4 15:38:47 2003 +++ b/net/ipv6/netfilter/ip6t_multiport.c Thu Sep 4 15:38:47 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 Thu Sep 4 15:38:29 2003 +++ b/net/ipv6/netfilter/ip6table_filter.c Thu Sep 4 15:38:29 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 Thu Sep 4 15:38:32 2003 +++ b/net/ipv6/netfilter/ip6table_mangle.c Thu Sep 4 15:38:32 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 Thu Sep 4 15:38:40 2003 +++ b/net/ipv6/route.c Thu Sep 4 15:38:40 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 Thu Sep 4 15:38:30 2003 +++ b/net/ipv6/xfrm6_policy.c Thu Sep 4 15:38:30 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 Thu Sep 4 15:38:30 2003 +++ b/net/ipx/af_ipx.c Thu Sep 4 15:38:30 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 Thu Sep 4 15:38:31 2003 +++ b/net/irda/af_irda.c Thu Sep 4 15:38:31 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 Thu Sep 4 15:38:45 2003 +++ b/net/irda/irsyms.c Thu Sep 4 15:38:45 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 Thu Sep 4 15:38:31 2003 +++ b/net/key/af_key.c Thu Sep 4 15:38:31 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 Thu Sep 4 15:38:42 2003 +++ b/net/llc/llc_mac.c Thu Sep 4 15:38:42 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 Thu Sep 4 15:38:32 2003 +++ b/net/llc/llc_main.c Thu Sep 4 15:38:32 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 Thu Sep 4 15:38:29 2003 +++ b/net/llc/llc_proc.c Thu Sep 4 15:38:29 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 Thu Sep 4 15:38:34 2003 +++ b/net/netlink/af_netlink.c Thu Sep 4 15:38:34 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; + long 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) { + long i = (long)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 Thu Sep 4 15:38:32 2003 +++ b/net/netlink/netlink_dev.c Thu Sep 4 15:38:32 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 Thu Sep 4 15:38:34 2003 +++ b/net/netrom/af_netrom.c Thu Sep 4 15:38:34 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 Thu Sep 4 15:38:32 2003 +++ b/net/netsyms.c Thu Sep 4 15:38:32 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 Thu Sep 4 15:38:39 2003 +++ b/net/packet/af_packet.c Thu Sep 4 15:38:39 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 Thu Sep 4 15:38:34 2003 +++ b/net/rose/af_rose.c Thu Sep 4 15:38:34 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 Thu Sep 4 15:38:28 2003 +++ b/net/rxrpc/krxiod.c Thu Sep 4 15:38:28 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 Thu Sep 4 15:38:30 2003 +++ b/net/rxrpc/krxsecd.c Thu Sep 4 15:38:30 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 Thu Sep 4 15:38:30 2003 +++ b/net/rxrpc/krxtimod.c Thu Sep 4 15:38:30 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/sysctl.c b/net/rxrpc/sysctl.c --- a/net/rxrpc/sysctl.c Thu Sep 4 15:38:32 2003 +++ b/net/rxrpc/sysctl.c Thu Sep 4 15:38:32 2003 @@ -14,7 +14,6 @@ #include #include #include -#include #include #include #include diff -Nru a/net/sched/sch_generic.c b/net/sched/sch_generic.c --- a/net/sched/sch_generic.c Thu Sep 4 15:38:29 2003 +++ b/net/sched/sch_generic.c Thu Sep 4 15:38:29 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 Thu Sep 4 15:38:48 2003 +++ b/net/sctp/socket.c Thu Sep 4 15:38:48 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 Thu Sep 4 15:38:31 2003 +++ b/net/sunrpc/rpc_pipe.c Thu Sep 4 15:38:31 2003 @@ -10,7 +10,6 @@ */ #include #include -#include #include #include #include diff -Nru a/net/sunrpc/stats.c b/net/sunrpc/stats.c --- a/net/sunrpc/stats.c Thu Sep 4 15:38:48 2003 +++ b/net/sunrpc/stats.c Thu Sep 4 15:38:48 2003 @@ -20,7 +20,6 @@ #include #include #include -#include #define RPCDBG_FACILITY RPCDBG_MISC diff -Nru a/net/sunrpc/svcsock.c b/net/sunrpc/svcsock.c --- a/net/sunrpc/svcsock.c Thu Sep 4 15:38:29 2003 +++ b/net/sunrpc/svcsock.c Thu Sep 4 15:38:29 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 Thu Sep 4 15:38:29 2003 +++ b/net/sunrpc/sysctl.c Thu Sep 4 15:38:29 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 Thu Sep 4 15:38:43 2003 +++ b/net/sunrpc/timer.c Thu Sep 4 15:38:43 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 Thu Sep 4 15:38:39 2003 +++ b/net/sunrpc/xprt.c Thu Sep 4 15:38:39 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 Thu Sep 4 15:38:37 2003 +++ b/net/unix/af_unix.c Thu Sep 4 15:38:37 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 Thu Sep 4 15:38:46 2003 +++ b/net/wanrouter/af_wanpipe.c Thu Sep 4 15:38:46 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 Thu Sep 4 15:38:45 2003 +++ b/net/x25/af_x25.c Thu Sep 4 15:38:45 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 Thu Sep 4 15:38:36 2003 +++ b/net/xfrm/xfrm_user.c Thu Sep 4 15:38:36 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 Thu Sep 4 15:38:47 2003 +++ b/scripts/kconfig/Makefile Thu Sep 4 15:38:47 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 Thu Sep 4 15:38:31 2003 +++ b/scripts/kconfig/symbol.c Thu Sep 4 15:38:31 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 Thu Sep 4 15:38:32 2003 +++ b/security/capability.c Thu Sep 4 15:38:32 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/Kconfig b/security/selinux/Kconfig --- a/security/selinux/Kconfig Thu Sep 4 15:38:29 2003 +++ b/security/selinux/Kconfig Thu Sep 4 15:38:29 2003 @@ -3,11 +3,14 @@ depends on SECURITY default n help - This enables NSA Security-Enhanced Linux (SELinux). + This selects NSA Security-Enhanced Linux (SELinux). You will also need a policy configuration and a labeled filesystem. You can obtain the policy compiler (checkpolicy), the utility for labeling filesystems (setfiles), and an example policy configuration from http://www.nsa.gov/selinux. + SELinux needs to be explicitly enabled on the kernel command line with + selinux=1. If you specify selinux=0 or do not use this parameter, + SELinux will not be enabled. If you are unsure how to answer this question, answer N. config SECURITY_SELINUX_DEVELOP diff -Nru a/security/selinux/hooks.c b/security/selinux/hooks.c --- a/security/selinux/hooks.c Thu Sep 4 15:38:45 2003 +++ b/security/selinux/hooks.c Thu Sep 4 15:38:45 2003 @@ -73,6 +73,15 @@ __setup("enforcing=", enforcing_setup); #endif +int selinux_enabled = 0; + +static int __init selinux_enabled_setup(char *str) +{ + selinux_enabled = simple_strtol(str, NULL, 0); + return 1; +} +__setup("selinux=", selinux_enabled_setup); + /* Original (dummy) security module. */ static struct security_operations *original_ops = NULL; @@ -1332,31 +1341,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 +1362,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 +1371,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 +1426,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 +1463,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 +1510,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 +1519,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 +2058,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 +3115,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) { @@ -3353,6 +3355,11 @@ __init int selinux_init(void) { struct task_security_struct *tsec; + + if (!selinux_enabled) { + printk(KERN_INFO "SELinux: Not enabled at boot.\n"); + return 0; + } printk(KERN_INFO "SELinux: Initializing.\n"); diff -Nru a/security/selinux/include/objsec.h b/security/selinux/include/objsec.h --- a/security/selinux/include/objsec.h Thu Sep 4 15:38:32 2003 +++ b/security/selinux/include/objsec.h Thu Sep 4 15:38:32 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/selinuxfs.c b/security/selinux/selinuxfs.c --- a/security/selinux/selinuxfs.c Thu Sep 4 15:38:48 2003 +++ b/security/selinux/selinuxfs.c Thu Sep 4 15:38:48 2003 @@ -17,6 +17,8 @@ #include "security.h" #include "objsec.h" +extern int selinux_enabled; + /* Check whether a task is allowed to use a security operation. */ int task_has_security(struct task_struct *tsk, u32 perms) @@ -587,7 +589,7 @@ static int __init init_sel_fs(void) { - return register_filesystem(&sel_fs_type); + return selinux_enabled ? register_filesystem(&sel_fs_type) : 0; } __initcall(init_sel_fs); diff -Nru a/security/selinux/ss/avtab.c b/security/selinux/ss/avtab.c --- a/security/selinux/ss/avtab.c Thu Sep 4 15:38:40 2003 +++ b/security/selinux/ss/avtab.c Thu Sep 4 15:38:40 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 Thu Sep 4 15:38:38 2003 +++ b/security/selinux/ss/ebitmap.c Thu Sep 4 15:38:38 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 Thu Sep 4 15:38:45 2003 +++ b/security/selinux/ss/global.h Thu Sep 4 15:38:45 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 Thu Sep 4 15:38:32 2003 +++ b/security/selinux/ss/policydb.c Thu Sep 4 15:38:32 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 Thu Sep 4 15:38:30 2003 +++ b/sound/core/control.c Thu Sep 4 15:38:30 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 Thu Sep 4 15:38:29 2003 +++ b/sound/core/hwdep.c Thu Sep 4 15:38:29 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 Thu Sep 4 15:38:38 2003 +++ b/sound/core/oss/mixer_oss.c Thu Sep 4 15:38:38 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 Thu Sep 4 15:38:43 2003 +++ b/sound/core/oss/pcm_oss.c Thu Sep 4 15:38:43 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 Thu Sep 4 15:38:31 2003 +++ b/sound/core/pcm_native.c Thu Sep 4 15:38:32 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 Thu Sep 4 15:38:30 2003 +++ b/sound/core/rawmidi.c Thu Sep 4 15:38:30 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 Thu Sep 4 15:38:42 2003 +++ b/sound/core/seq/oss/seq_oss.c Thu Sep 4 15:38:42 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 Thu Sep 4 15:38:39 2003 +++ b/sound/core/sound.c Thu Sep 4 15:38:39 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/Kconfig b/sound/oss/Kconfig --- a/sound/oss/Kconfig Thu Sep 4 15:38:43 2003 +++ b/sound/oss/Kconfig Thu Sep 4 15:38:43 2003 @@ -1145,10 +1145,18 @@ config SOUND_FORTE tristate "ForteMedia FM801 driver" depends on SOUND_PRIME!=n && PCI + help + Say Y or M if you want driver support for the ForteMedia FM801 PCI + audio controller (Abit AU10, Genius Sound Maker, HP Workstation + zx2000, and others). config SOUND_RME96XX tristate "RME Hammerfall (RME96XX) support" depends on SOUND_PRIME!=n && PCI + help + Say Y or M if you have a Hammerfall or Hammerfall light + multichannel card from RME. If you want to acess advanced + features of the card, read Documentation/sound/rme96xx. config SOUND_AD1980 tristate "AD1980 front/back switch plugin" diff -Nru a/sound/oss/ad1889.c b/sound/oss/ad1889.c --- a/sound/oss/ad1889.c Thu Sep 4 15:38:32 2003 +++ b/sound/oss/ad1889.c Thu Sep 4 15:38:32 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 Thu Sep 4 15:38:42 2003 +++ b/sound/oss/ali5455.c Thu Sep 4 15:38:42 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 Thu Sep 4 15:38:38 2003 +++ b/sound/oss/au1000.c Thu Sep 4 15:38:38 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 Thu Sep 4 15:38:30 2003 +++ b/sound/oss/btaudio.c Thu Sep 4 15:38:30 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 Thu Sep 4 15:38:35 2003 +++ b/sound/oss/cmpci.c Thu Sep 4 15:38:35 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 Thu Sep 4 15:38:47 2003 +++ b/sound/oss/cs4281/cs4281m.c Thu Sep 4 15:38:47 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 Thu Sep 4 15:38:28 2003 +++ b/sound/oss/cs46xx.c Thu Sep 4 15:38:28 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 Thu Sep 4 15:38:30 2003 +++ b/sound/oss/dmasound/dmasound_core.c Thu Sep 4 15:38:30 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 Thu Sep 4 15:38:29 2003 +++ b/sound/oss/emu10k1/audio.c Thu Sep 4 15:38:29 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 Thu Sep 4 15:38:48 2003 +++ b/sound/oss/emu10k1/midi.c Thu Sep 4 15:38:48 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 Thu Sep 4 15:38:40 2003 +++ b/sound/oss/emu10k1/mixer.c Thu Sep 4 15:38:40 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 Thu Sep 4 15:38:47 2003 +++ b/sound/oss/es1370.c Thu Sep 4 15:38:47 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 Thu Sep 4 15:38:40 2003 +++ b/sound/oss/es1371.c Thu Sep 4 15:38:40 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 Thu Sep 4 15:38:30 2003 +++ b/sound/oss/esssolo1.c Thu Sep 4 15:38:30 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 Thu Sep 4 15:38:42 2003 +++ b/sound/oss/hal2.c Thu Sep 4 15:38:42 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 Thu Sep 4 15:38:41 2003 +++ b/sound/oss/i810_audio.c Thu Sep 4 15:38:41 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 Thu Sep 4 15:38:30 2003 +++ b/sound/oss/ite8172.c Thu Sep 4 15:38:30 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 Thu Sep 4 15:38:43 2003 +++ b/sound/oss/maestro.c Thu Sep 4 15:38:43 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 Thu Sep 4 15:38:44 2003 +++ b/sound/oss/maestro3.c Thu Sep 4 15:38:44 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 Thu Sep 4 15:38:37 2003 +++ b/sound/oss/msnd_pinnacle.c Thu Sep 4 15:38:37 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 Thu Sep 4 15:38:40 2003 +++ b/sound/oss/nec_vrc5477.c Thu Sep 4 15:38:40 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 Thu Sep 4 15:38:32 2003 +++ b/sound/oss/rme96xx.c Thu Sep 4 15:38:32 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 Thu Sep 4 15:38:33 2003 +++ b/sound/oss/sonicvibes.c Thu Sep 4 15:38:33 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 Thu Sep 4 15:38:33 2003 +++ b/sound/oss/soundcard.c Thu Sep 4 15:38:33 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 Thu Sep 4 15:38:35 2003 +++ b/sound/oss/swarm_cs4297a.c Thu Sep 4 15:38:35 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 Thu Sep 4 15:38:41 2003 +++ b/sound/oss/trident.c Thu Sep 4 15:38:41 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 Thu Sep 4 15:38:31 2003 +++ b/sound/oss/via82cxxx_audio.c Thu Sep 4 15:38:31 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 Thu Sep 4 15:38:35 2003 +++ b/sound/oss/vwsnd.c Thu Sep 4 15:38:35 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 Thu Sep 4 15:38:37 2003 +++ b/sound/oss/ymfpci.c Thu Sep 4 15:38:37 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 Thu Sep 4 15:38:29 2003 +++ b/sound/pcmcia/vx/vx_entry.c Thu Sep 4 15:38:29 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 Thu Sep 4 15:38:45 2003 +++ b/sound/ppc/keywest.c Thu Sep 4 15:38:45 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 Thu Sep 4 15:38:46 2003 +++ b/sound/sound_core.c Thu Sep 4 15:38:46 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;