# 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.4 -> 1.1630 # arch/i386/kernel/process.c 1.62 -> 1.63 # include/acpi/acglobal.h 1.28 -> 1.29 # drivers/video/aty/radeon_monitor.c 1.4 -> 1.5 # drivers/net/8139too.c 1.85 -> 1.86 # include/asm-parisc/ioctl.h 1.3 -> 1.4 # drivers/net/tulip/timer.c 1.7 -> 1.8 # drivers/char/viocons.c 1.2 -> 1.3 # fs/nfs/read.c 1.34 -> 1.36 # sound/pcmcia/Makefile 1.1 -> 1.2 # fs/ufs/super.c 1.38 -> 1.39 # arch/m68knommu/kernel/syscalltable.S 1.4 -> 1.5 # arch/sparc64/kernel/smp.c 1.66 -> 1.67 # include/acpi/acpixf.h 1.25 -> 1.26 # drivers/net/3c59x.c 1.43.1.2 -> 1.49 # drivers/scsi/megaraid.c 1.59 -> 1.61 # drivers/net/eexpress.c 1.16 -> 1.17 # sound/pci/emu10k1/emu10k1.c 1.14 -> 1.15 # arch/arm/common/sa1111-pcibuf.c 1.11 -> 1.12 # include/asm-x86_64/smp.h 1.16 -> 1.17 # include/asm-alpha/pci.h 1.19 -> 1.20 # include/asm-parisc/semaphore.h 1.6 -> 1.7 # drivers/ide/legacy/macide.c 1.5 -> 1.6 # arch/parisc/kernel/pci.c 1.15 -> 1.16 # drivers/scsi/sym53c8xx_2/sym_hipd.c 1.15 -> 1.16 # drivers/scsi/libata-core.c 1.22 -> 1.25 # include/linux/dm-ioctl.h 1.4 -> 1.5 # drivers/scsi/sata_sil.c 1.10 -> 1.12 # include/asm-parisc/unistd.h 1.11 -> 1.12 # arch/parisc/kernel/head64.S 1.4 -> 1.5 # sound/core/seq/oss/seq_oss_midi.c 1.9 -> 1.11 # fs/adfs/super.c 1.27 -> 1.28 # drivers/media/dvb/frontends/tda1004x.c 1.8 -> 1.9 # drivers/scsi/scsi_error.c 1.69 -> 1.71 # drivers/net/3c501.c 1.21 -> 1.22 # arch/x86_64/kernel/traps.c 1.34 -> 1.35 # drivers/md/dm-crypt.c 1.3 -> 1.5 # include/acpi/acutils.h 1.29 -> 1.30 # fs/nfs/nfs4state.c 1.17 -> 1.19 # fs/libfs.c 1.30 -> 1.31 # sound/pci/emu10k1/emupcm.c 1.16 -> 1.18 # drivers/parisc/eisa.c 1.9 -> 1.10 # sound/pci/Makefile 1.15 -> 1.19 # arch/x86_64/mm/fault.c 1.21 -> 1.22 # sound/drivers/opl3/Makefile 1.14 -> 1.16 # include/asm-ppc64/unistd.h 1.26 -> 1.27 # sound/pci/korg1212/korg1212.c 1.27 -> 1.29 # arch/m68k/kernel/entry.S 1.14 -> 1.15 # include/linux/cdrom.h 1.16 -> 1.17 # sound/pci/ac97/ac97_patch.h 1.13 -> 1.14 # arch/sparc/kernel/setup.c 1.25 -> 1.26 # drivers/md/raid6main.c 1.4 -> 1.6 # sound/ppc/tumbler.c 1.16 -> 1.20 # sound/core/seq/oss/seq_oss_synth.c 1.12 -> 1.13 # include/asm-arm/dma-mapping.h 1.8 -> 1.9 # drivers/net/tulip/de4x5.c 1.35 -> 1.36 # drivers/net/wan/cosa.c 1.29 -> 1.30 # fs/lockd/clntproc.c 1.9 -> 1.10 # drivers/net/bagetlance.c 1.10 -> 1.11 # sound/synth/Makefile 1.12 -> 1.13 # include/linux/libata.h 1.9 -> 1.12 # drivers/net/irda/vlsi_ir.c 1.29 -> 1.30 # drivers/char/Kconfig 1.30 -> 1.31 # drivers/net/forcedeth.c 1.6 -> 1.7 # include/asm-i386/edd.h 1.7 -> 1.8 # drivers/net/hamradio/baycom_ser_hdx.c 1.12 -> 1.13 # arch/x86_64/ia32/ia32_binfmt.c 1.22 -> 1.23 # drivers/net/bmac.c 1.19 -> 1.20 # drivers/message/fusion/mptctl.c 1.18 -> 1.19 # include/scsi/scsi_device.h 1.11 -> 1.14 # fs/cramfs/inode.c 1.36 -> 1.37 # drivers/scsi/oktagon_esp.c 1.13 -> 1.14 # drivers/mtd/devices/blkmtd.c 1.37 -> 1.38 # drivers/net/3c509.c 1.45 -> 1.46 # arch/x86_64/kernel/setup.c 1.30 -> 1.31 # sound/sparc/cs4231.c 1.12 -> 1.13 # net/ipv4/ipconfig.c 1.36 -> 1.37 # arch/parisc/defconfig 1.8 -> 1.9 # sound/pci/ice1712/ice1712.h 1.11 -> 1.13 # include/asm-x86_64/page.h 1.11 -> 1.12 # fs/open.c 1.56 -> 1.57 # drivers/acpi/parser/psscope.c 1.12 -> 1.13 # drivers/net/natsemi.c 1.57 -> 1.58 # drivers/scsi/hosts.c 1.96 -> 1.97 # include/sound/memalloc.h 1.3 -> 1.6 # net/Kconfig 1.28.1.2 -> 1.32 # sound/arm/sa11xx-uda1341.c 1.13 -> 1.14 # arch/i386/lib/Makefile 1.12 -> 1.13 # drivers/scsi/53c700.h 1.15 -> 1.16 # net/sunrpc/sysctl.c 1.8 -> 1.9 # drivers/net/hp-plus.c 1.13 -> 1.14 # drivers/scsi/cpqfcTSinit.c 1.43 -> 1.44 # drivers/net/sb1000.c 1.24 -> 1.25 # drivers/message/fusion/lsi/mpi_init.h 1.4 -> 1.5 # init/initramfs.c 1.14 -> 1.15 # drivers/net/wd.c 1.16 -> 1.17 # drivers/net/myri_sbus.c 1.18 -> 1.19 # fs/nfs/mount_clnt.c 1.7 -> 1.8 # arch/ppc64/kernel/pmac_smp.c 1.2 -> 1.3 # arch/x86_64/lib/io.c 1.2 -> 1.4 # mm/page_alloc.c 1.190 -> 1.195 # mm/readahead.c 1.40 -> 1.41 # arch/ia64/ia32/ia32_support.c 1.13 -> 1.14 # sound/core/seq/oss/seq_oss_init.c 1.6 -> 1.7 # drivers/acpi/utilities/uteval.c 1.21 -> 1.22 # arch/alpha/kernel/alpha_ksyms.c 1.35 -> 1.36 # sound/pci/cs46xx/cs46xx_lib.c 1.41 -> 1.44 # init/do_mounts_initrd.c 1.6 -> 1.7 # drivers/acpi/hardware/hwsleep.c 1.24 -> 1.25 # arch/sparc/kernel/sparc_ksyms.c 1.26 -> 1.27 # Documentation/sound/alsa/ALSA-Configuration.txt 1.28 -> 1.33 # sound/drivers/vx/vx_pcm.c 1.2 -> 1.3 # Documentation/scsi/sym53c8xx_2.txt 1.3 -> 1.4 # drivers/net/tokenring/skisa.c 1.15 -> 1.16 # arch/i386/kernel/head.S 1.30 -> 1.31 # include/linux/nfs_page.h 1.12 -> 1.13 # arch/s390/kernel/syscalls.S 1.7 -> 1.8 # drivers/net/fec.c 1.8 -> 1.9 # drivers/net/tulip/pnic2.c 1.2 -> 1.3 # sound/pci/ice1712/delta.c 1.11 -> 1.12 # include/asm-ia64/machvec_hpzx1.h 1.7 -> 1.8 # drivers/block/ll_rw_blk.c 1.231 -> 1.235 # sound/core/seq/seq_memory.c 1.9 -> 1.10 # sound/drivers/vx/Makefile 1.1 -> 1.2 # drivers/net/wireless/airo.c 1.84 -> 1.85 # drivers/acpi/utilities/utglobal.c 1.33 -> 1.34 # include/asm-ia64/unistd.h 1.38 -> 1.39 # drivers/net/8390.c 1.18.1.1 -> 1.20 # drivers/char/watchdog/pcwd_pci.c 1.1 -> 1.2 # sound/isa/sscape.c 1.10 -> 1.12 # drivers/net/smc-mca.c 1.13 -> 1.14 # arch/sparc/kernel/sun4d_smp.c 1.13 -> 1.14 # arch/s390/appldata/appldata_mem.c 1.1 -> 1.2 # include/acpi/acobject.h 1.22 -> 1.23 # sound/core/seq/seq_clientmgr.c 1.23 -> 1.24 # fs/coda/dir.c 1.26 -> 1.27 # drivers/ieee1394/sbp2.c 1.64 -> 1.65 # drivers/net/lasi_82596.c 1.23 -> 1.25 # include/asm-i386/module.h 1.9 -> 1.10 # sound/pci/ac97/ak4531_codec.c 1.6 -> 1.7 # drivers/net/tlan.c 1.30 -> 1.31 # fs/smbfs/inode.c 1.46 -> 1.48 # drivers/message/fusion/lsi/mpi.h 1.5 -> 1.6 # drivers/char/watchdog/eurotechwdt.c 1.17 -> 1.18 # mm/vmscan.c 1.178 -> 1.198 # include/asm-parisc/io.h 1.6 -> 1.7 # sound/pci/ac97/ac97_pcm.c 1.10 -> 1.11 # fs/proc/proc_misc.c 1.95 -> 1.96 # sound/isa/cmi8330.c 1.20 -> 1.23 # arch/sparc64/kernel/pci_iommu.c 1.9 -> 1.10 # arch/m68k/bvme6000/bvmeints.c 1.5 -> 1.6 # arch/sparc/kernel/process.c 1.35 -> 1.36 # drivers/net/smc-ultra.c 1.19 -> 1.20 # drivers/scsi/dc395x.c 1.26 -> 1.32 # drivers/net/sk98lin/skge.c 1.36 -> 1.37 # drivers/net/loopback.c 1.12 -> 1.13 # arch/ia64/hp/common/sba_iommu.c 1.37 -> 1.38 # arch/i386/Kconfig 1.104 -> 1.109 # drivers/cdrom/cdrom.c 1.48 -> 1.49 # include/scsi/scsi_host.h 1.13 -> 1.14 # drivers/message/fusion/lsi/mpi_targ.h 1.5 -> 1.6 # arch/ia64/sn/kernel/irq.c 1.20 -> 1.21 # drivers/scsi/53c700.c 1.46 -> 1.50 # Documentation/sound/alsa/DocBook/alsa-driver-api.tmpl 1.3 -> 1.4 # include/asm-parisc/grfioctl.h 1.1 -> 1.2 # drivers/message/fusion/lsi/mpi_fc.h 1.4 -> 1.5 # arch/x86_64/kernel/x8664_ksyms.c 1.26 -> 1.28 # arch/m68k/kernel/sys_m68k.c 1.7 -> 1.8 # include/linux/udf_fs.h 1.9 -> 1.10 # include/asm-sparc64/unistd.h 1.28 -> 1.29 # drivers/message/fusion/mptbase.h 1.15 -> 1.18 # include/asm-sparc64/pci.h 1.18 -> 1.19 # sound/isa/opti9xx/opti92x-ad1848.c 1.24 -> 1.28 # drivers/acpi/parser/psparse.c 1.24 -> 1.25 # arch/x86_64/pci/Makefile 1.5 -> 1.6 # arch/x86_64/lib/Makefile 1.11 -> 1.12 # init/main.c 1.125 -> 1.126 # arch/i386/kernel/traps.c 1.65 -> 1.66 # include/asm-i386/topology.h 1.8 -> 1.9 # include/linux/lockd/lockd.h 1.7 -> 1.9 # include/asm-sparc/sbus.h 1.5 -> 1.6 # drivers/scsi/sata_via.c 1.5 -> 1.6 # arch/i386/kernel/Makefile 1.55 -> 1.57 # drivers/parisc/ccio-dma.c 1.15 -> 1.17 # drivers/mca/mca-bus.c 1.5 -> 1.6 # include/asm-generic/pci-dma-compat.h 1.3 -> 1.4 # Documentation/scsi/st.txt 1.13 -> 1.14 # sound/core/init.c 1.23 -> 1.25 # sound/sparc/amd7930.c 1.7 -> 1.8 # include/asm-sparc64/sbus.h 1.3 -> 1.4 # drivers/char/watchdog/machzwd.c 1.29 -> 1.30 # scripts/modpost.c 1.19 -> 1.20 # drivers/char/watchdog/sc1200wdt.c 1.10 -> 1.11 # arch/parisc/kernel/pacache.S 1.3 -> 1.4 # drivers/scsi/scsi_sysfs.c 1.39 -> 1.43 # fs/ufs/inode.c 1.21 -> 1.22 # arch/i386/kernel/vmlinux.lds.S 1.32 -> 1.33 # drivers/md/raid5.c 1.84 -> 1.86 # drivers/net/tulip/winbond-840.c 1.39 -> 1.40 # arch/x86_64/mm/init.c 1.25 -> 1.26 # arch/mips/mm/dma-noncoherent.c 1.1 -> 1.2 # arch/parisc/configs/a500_defconfig 1.1 -> 1.2 # arch/parisc/kernel/vmlinux.lds.S 1.16 -> 1.17 # drivers/char/synclinkmp.c 1.26 -> 1.27 # arch/x86_64/kernel/acpi/boot.c 1.15 -> 1.16 # security/dummy.c 1.32 -> 1.33 # sound/i2c/other/Makefile 1.2 -> 1.3 # drivers/net/ne2k-pci.c 1.19.1.1 -> 1.21 # sound/isa/cs423x/cs4231_lib.c 1.18 -> 1.21 # arch/parisc/kernel/entry.S 1.13 -> 1.14 # drivers/net/tulip/21142.c 1.10 -> 1.11 # drivers/char/watchdog/amd7xx_tco.c 1.14 -> 1.15 # drivers/net/hp.c 1.11 -> 1.12 # arch/i386/kernel/pci-dma.c 1.11 -> 1.12 # include/linux/blkdev.h 1.136 -> 1.138 # drivers/block/Kconfig 1.18 -> 1.19 # drivers/net/fc/iph5526.c 1.31 -> 1.32 # drivers/message/fusion/mptbase.c 1.18 -> 1.20 # drivers/block/cciss_scsi.c 1.18 -> 1.19 # drivers/ieee1394/ieee1394_core.c 1.53 -> 1.54 # drivers/net/pcmcia/3c574_cs.c 1.29 -> 1.30 # arch/x86_64/kernel/ioport.c 1.12 -> 1.13 # sound/pci/ice1712/ews.c 1.10 -> 1.11 # drivers/parisc/ccio-rm-dma.c 1.6 -> 1.7 # drivers/macintosh/mediabay.c 1.11 -> 1.12 # drivers/net/ethertap.c 1.12 -> 1.13 # drivers/net/rrunner.c 1.23 -> 1.25 # drivers/net/wireless/Kconfig 1.19 -> 1.20 # drivers/net/wan/comx-hw-munich.c 1.16 -> 1.17 # drivers/net/tulip/interrupt.c 1.23 -> 1.25 # drivers/media/dvb/frontends/alps_tdlb7.c 1.10 -> 1.11 # drivers/scsi/sr.c 1.99 -> 1.100 # drivers/net/wan/dscc4.c 1.59 -> 1.60 # drivers/net/starfire.c 1.34 -> 1.35 # arch/v850/kernel/rte_mb_a_pci.c 1.8 -> 1.9 # sound/drivers/vx/vx_mixer.c 1.1 -> 1.2 # include/linux/fs.h 1.287 -> 1.291 # drivers/net/tokenring/abyss.c 1.14 -> 1.15 # drivers/scsi/ini9100u.c 1.21 -> 1.22 # drivers/char/watchdog/alim1535_wdt.c 1.4 -> 1.5 # drivers/net/wireless/atmel.c 1.10 -> 1.11 # include/asm-parisc/keyboard.h 1.3 -> (deleted) # include/asm-ia64/hardirq.h 1.14 -> 1.15 # drivers/net/tulip/media.c 1.11 -> 1.12 # include/sound/emu10k1.h 1.23 -> 1.26 # drivers/md/dm-ioctl.c 1.31 -> 1.33 # fs/sysv/dir.c 1.15 -> 1.16 # drivers/net/pcnet32.c 1.45.1.16 -> 1.52 # fs/udf/dir.c 1.13 -> 1.15 # drivers/pci/pci.c 1.62 -> 1.63 # arch/sparc/kernel/smp.c 1.13 -> 1.14 # drivers/eisa/eisa-bus.c 1.14 -> 1.15 # drivers/net/Makefile 1.68.1.5 -> 1.73 # arch/x86_64/kernel/setup64.c 1.19 -> 1.20 # arch/alpha/kernel/smp.c 1.39 -> 1.40 # fs/lockd/svclock.c 1.7 -> 1.9 # drivers/char/watchdog/cpu5wdt.c 1.7 -> 1.8 # drivers/md/md.c 1.204 -> 1.205 # arch/x86_64/ia32/Makefile 1.20 -> 1.21 # arch/ia64/sn/io/machvec/pci_dma.c 1.26 -> 1.28 # arch/h8300/kernel/syscalls.S 1.3 -> 1.4 # arch/i386/mach-default/Makefile 1.8 -> 1.9 # drivers/net/sunlance.c 1.19 -> 1.20 # drivers/scsi/ncr53c8xx.c 1.37 -> 1.38 # Documentation/sound/alsa/DocBook/writing-an-alsa-driver.tmpl 1.21 -> 1.23 # include/linux/fb.h 1.62 -> 1.63 # drivers/net/ne2k_cbus.c 1.4 -> 1.5 # sound/usb/usbmixer.c 1.20 -> 1.21 # include/asm-ia64/sn/router.h 1.7 -> 1.8 # drivers/scsi/u14-34f.c 1.30 -> 1.31 # include/sound/sndmagic.h 1.17 -> 1.19 # arch/x86_64/kernel/mpparse.c 1.20 -> 1.21 # include/asm-parisc/superio.h 1.2 -> 1.3 # include/sound/cs46xx.h 1.13 -> 1.14 # sound/pci/emu10k1/emu10k1_callback.c 1.4 -> 1.5 # drivers/message/fusion/lsi/mpi_ioc.h 1.4 -> 1.5 # drivers/message/fusion/linux_compat.h 1.10 -> 1.11 # include/asm-v850/pci.h 1.4 -> 1.5 # fs/jffs2/super.c 1.28 -> 1.29 # fs/ext3/acl.c 1.15 -> 1.16 # sound/pci/rme9652/hdsp.c 1.29 -> 1.32 # sound/pci/ice1712/ice1712.c 1.25 -> 1.29 # drivers/net/sunhme.c 1.44 -> 1.45 # drivers/scsi/scsi_devinfo.c 1.7 -> 1.10 # arch/parisc/hpux/entry_hpux.S 1.3 -> 1.4 # include/asm-parisc/md.h 1.1 -> (deleted) # fs/afs/inode.c 1.9 -> 1.10 # arch/sparc64/kernel/setup.c 1.50 -> 1.51 # arch/i386/kernel/edd.c 1.20 -> 1.21 # drivers/scsi/aic7xxx/Kconfig.aic7xxx 1.12 -> 1.13 # sound/pci/ice1712/aureon.c 1.4 -> 1.5 # fs/hfs/super.c 1.26 -> 1.27 # drivers/net/atari_pamsnet.c 1.14 -> 1.15 # Documentation/i386/zero-page.txt 1.5 -> 1.6 # drivers/char/pcmcia/synclink_cs.c 1.30 -> 1.31 # sound/pci/Kconfig 1.13 -> 1.25 # arch/x86_64/kernel/entry.S 1.17 -> 1.18 # sound/pci/emu10k1/emuproc.c 1.9 -> 1.10 # include/asm-parisc/ide.h 1.10 -> 1.11 # include/linux/nfs_fs.h 1.64 -> 1.69 # sound/pci/rme96.c 1.22 -> 1.24 # drivers/net/wan/lapbether.c 1.20 -> 1.21 # drivers/char/synclink.c 1.48 -> 1.49 # arch/i386/kernel/asm-offsets.c 1.1 -> 1.2 # drivers/scsi/sym53c8xx_2/sym_hipd.h 1.4 -> 1.5 # arch/ppc/platforms/chrp_smp.c 1.9 -> 1.10 # fs/lockd/svc4proc.c 1.10 -> 1.12 # ipc/sem.c 1.26 -> 1.27 # include/sound/version.h 1.71 -> 1.72 # sound/pci/ac97/ac97_codec.c 1.61 -> 1.65 # sound/drivers/mpu401/mpu401_uart.c 1.18 -> 1.19 # fs/nfs/nfs2xdr.c 1.30 -> 1.31 # include/asm-ia64/machvec_sn2.h 1.11 -> 1.12 # drivers/net/yellowfin.c 1.28 -> 1.29 # arch/i386/mach-voyager/voyager_smp.c 1.18 -> 1.19 # init/do_mounts.c 1.61 -> 1.63 # include/sound/ymfpci.h 1.9 -> 1.10 # drivers/scsi/sym53c8xx_2/sym_defs.h 1.2 -> 1.3 # include/asm-ppc64/pci.h 1.19 -> 1.20 # arch/mips/mm/dma-coherent.c 1.1 -> 1.2 # drivers/scsi/aacraid/linit.c 1.26 -> 1.27 # net/sunrpc/clnt.c 1.50 -> 1.52 # include/asm-parisc/dma-mapping.h 1.5 -> 1.6 # fs/udf/truncate.c 1.7 -> 1.8 # arch/s390/kernel/sys_s390.c 1.9 -> 1.10 # drivers/net/pcmcia/xirc2ps_cs.c 1.30 -> 1.31 # Documentation/devices.txt 1.11 -> 1.12 # arch/i386/kernel/trampoline.S 1.8 -> 1.9 # sound/isa/wavefront/wavefront_synth.c 1.13 -> 1.14 # drivers/acpi/tables.c 1.21 -> 1.22 # arch/ia64/kernel/irq_ia64.c 1.17 -> 1.18 # mm/fadvise.c 1.10 -> 1.11 # drivers/char/watchdog/advantechwdt.c 1.21 -> 1.22 # drivers/net/at1700.c 1.20 -> 1.21 # kernel/signal.c 1.102 -> 1.103 # arch/m68k/mac/via.c 1.7 -> 1.8 # drivers/video/fm2fb.c 1.24 -> 1.25 # sound/isa/dt019x.c 1.19 -> 1.20 # sound/parisc/harmony.c 1.3 -> 1.5 # fs/afs/super.c 1.9 -> 1.10 # drivers/acpi/namespace/nseval.c 1.21 -> 1.22 # drivers/net/ne3210.c 1.12 -> 1.13 # fs/ufs/util.c 1.10 -> 1.11 # include/asm-x86_64/io.h 1.11 -> 1.12 # sound/core/pcm_lib.c 1.27 -> 1.29 # drivers/net/dl2k.c 1.31 -> 1.32 # sound/pci/trident/trident_synth.c 1.6 -> 1.7 # drivers/macintosh/Kconfig 1.4 -> 1.5 # include/asm-x86_64/pci.h 1.15 -> 1.16 # include/asm-i386/pci.h 1.26 -> 1.27 # sound/isa/es18xx.c 1.25 -> 1.28 # sound/usb/usbquirks.h 1.20 -> 1.23 # arch/parisc/kernel/hardware.c 1.5 -> 1.6 # sound/isa/gus/gus_pcm.c 1.11 -> 1.14 # drivers/message/fusion/scsi3.h 1.4 -> 1.5 # drivers/net/b44.c 1.14 -> 1.15 # drivers/scsi/aic7xxx/Kconfig.aic79xx 1.8 -> 1.9 # sound/ppc/Kconfig 1.1 -> 1.2 # arch/x86_64/ia32/sys_ia32.c 1.52 -> 1.53 # arch/sparc64/kernel/process.c 1.48 -> 1.49 # fs/udf/udfdecl.h 1.13 -> 1.14 # drivers/net/sis900.c 1.49 -> 1.50 # arch/x86_64/kernel/pci-gart.c 1.29 -> 1.31 # include/linux/usb.h 1.95 -> 1.96 # include/linux/usb_gadget.h 1.7 -> 1.8 # drivers/net/sunhme.h 1.6 -> 1.7 # drivers/net/wan/comx.c 1.21 -> 1.22 # sound/isa/sb/sb8_main.c 1.6 -> 1.9 # fs/super.c 1.114 -> 1.115 # drivers/ide/ide-cd.c 1.72 -> 1.73 # arch/ia64/pci/pci.c 1.41 -> 1.43 # sound/pci/rme9652/rme9652.c 1.24 -> 1.26 # arch/x86_64/ia32/ia32entry.S 1.28 -> 1.29 # drivers/net/tun.c 1.29 -> 1.30 # fs/fat/inode.c 1.88 -> 1.89 # fs/binfmt_elf.c 1.68 -> 1.69 # drivers/net/ne.c 1.18.1.1 -> 1.20 # mm/memory.c 1.153 -> 1.154 # sound/pci/ice1712/ice1724.c 1.18 -> 1.21 # drivers/net/ni5010.c 1.13 -> 1.14 # drivers/md/dm.h 1.12 -> 1.13 # drivers/net/e1000/e1000_ethtool.c 1.39 -> 1.40 # drivers/net/hplance.c 1.9 -> 1.10 # drivers/net/epic100.c 1.36 -> 1.37 # drivers/net/pcmcia/com20020_cs.c 1.17 -> 1.18 # drivers/video/modedb.c 1.10 -> 1.11 # include/linux/pci.h 1.119 -> 1.121 # drivers/net/hydra.c 1.12.1.2 -> 1.14 # arch/ia64/kernel/iosapic.c 1.35 -> 1.36 # arch/ia64/kernel/mca.c 1.59 -> 1.60 # sound/core/seq/seq_fifo.c 1.5 -> 1.6 # sound/isa/sb/sb16_main.c 1.11 -> 1.14 # include/asm-parisc/namei.h 1.1 -> 1.2 # arch/m68k/mac/oss.c 1.5 -> 1.6 # include/asm-m68k/unistd.h 1.10 -> 1.11 # arch/ia64/kernel/process.c 1.51 -> 1.52 # fs/readdir.c 1.24 -> 1.25 # arch/i386/kernel/setup.c 1.108 -> 1.110 # drivers/md/dm-stripe.c 1.9 -> 1.12 # drivers/char/watchdog/sc520_wdt.c 1.16 -> 1.17 # drivers/macintosh/therm_pm72.h 1.1 -> 1.2 # arch/m68k/kernel/ints.c 1.7 -> 1.8 # drivers/atm/idt77252.c 1.22 -> 1.23 # include/sound/pcm.h 1.18 -> 1.21 # fs/nfs/dir.c 1.68 -> 1.71 # drivers/acpi/dispatcher/dsmethod.c 1.19 -> 1.20 # arch/ia64/hp/sim/simserial.c 1.22 -> 1.23 # fs/nfs/nfs3proc.c 1.33 -> 1.35 # drivers/net/tokenring/smctr.c 1.28 -> 1.30 # include/asm-h8300/unistd.h 1.3 -> 1.4 # drivers/media/video/video-buf.c 1.15 -> 1.16 # drivers/message/fusion/isense.c 1.8 -> 1.9 # arch/x86_64/ia32/vsyscall.S 1.2 -> (deleted) # drivers/scsi/scsi_lib.c 1.120 -> 1.123 # drivers/message/fusion/mptlan.c 1.13 -> 1.16 # drivers/message/fusion/mptctl.h 1.7 -> 1.8 # drivers/message/fusion/lsi/mpi_raid.h 1.5 -> 1.6 # sound/pci/ice1712/amp.c 1.3 -> 1.4 # drivers/net/appletalk/cops.c 1.19 -> 1.20 # arch/m68k/q40/config.c 1.16 -> 1.17 # fs/coda/inode.c 1.34 -> 1.36 # net/sunrpc/pmap_clnt.c 1.8 -> 1.9 # fs/ncpfs/inode.c 1.48 -> 1.49 # arch/i386/boot/tools/build.c 1.3 -> 1.4 # net/core/dev.c 1.129.1.5 -> 1.133 # arch/ia64/sn/io/sn2/shub_intr.c 1.9 -> 1.10 # arch/ppc/platforms/pmac_smp.c 1.17 -> 1.18 # sound/pcmcia/Kconfig 1.2 -> 1.6 # drivers/message/fusion/lsi/mpi_lan.h 1.4 -> 1.5 # drivers/scsi/scsi.c 1.136.1.1 -> 1.139 # include/asm-m68knommu/unistd.h 1.3 -> 1.4 # drivers/usb/core/usb.c 1.152 -> 1.153 # arch/i386/mach-es7000/Makefile 1.1 -> 1.2 # fs/ufs/util.h 1.8 -> 1.9 # drivers/ieee1394/dma.c 1.7 -> 1.8 # drivers/acpi/namespace/nsalloc.c 1.19 -> 1.20 # drivers/net/mac89x0.c 1.14 -> 1.15 # drivers/char/watchdog/wdt.c 1.26 -> 1.28 # Documentation/sound/alsa/Joystick.txt 1.2 -> 1.3 # sound/pci/emu10k1/emufx.c 1.37 -> 1.39 # drivers/acpi/power.c 1.19 -> 1.20 # drivers/scsi/pcmcia/qlogic_stub.c 1.20 -> 1.26 # include/asm-parisc/floppy.h 1.1 -> 1.2 # drivers/net/pcmcia/ibmtr_cs.c 1.23 -> 1.24 # Documentation/DMA-mapping.txt 1.17 -> 1.18 # fs/ext3/dir.c 1.16 -> 1.17 # include/sound/ac97_codec.h 1.30 -> 1.31 # drivers/atm/fore200e.h 1.1 -> 1.2 # drivers/net/sunbmac.c 1.21 -> 1.22 # drivers/message/fusion/lsi/mpi_cnfg.h 1.5 -> 1.6 # include/asm-ia64/machvec.h 1.18 -> 1.19 # fs/ext2/dir.c 1.22 -> 1.23 # net/sunrpc/sched.c 1.30 -> 1.31 # drivers/net/mac8390.c 1.16 -> 1.17 # fs/lockd/host.c 1.6 -> 1.7 # drivers/md/raid0.c 1.43 -> 1.44 # include/acpi/acmacros.h 1.24 -> 1.25 # fs/cifs/cifsfs.c 1.35 -> 1.36 # drivers/char/watchdog/w83627hf_wdt.c 1.3 -> 1.4 # drivers/scsi/sym53c8xx_comm.h 1.15 -> 1.16 # drivers/md/dm-linear.c 1.7 -> 1.9 # drivers/net/tg3.c 1.120.1.16 -> 1.126 # arch/i386/mm/discontig.c 1.15 -> 1.16 # fs/reiserfs/dir.c 1.20 -> 1.21 # arch/x86_64/kernel/process.c 1.25 -> 1.27 # include/linux/mmzone.h 1.52 -> 1.54 # arch/i386/boot/setup.S 1.26 -> 1.27 # sound/pci/bt87x.c 1.1 -> 1.3 # include/linux/ufs_fs_i.h 1.3 -> 1.4 # drivers/net/3c527.c 1.21 -> 1.22 # sound/oss/wavfront.c 1.15 -> 1.17 # arch/m68k/mac/psc.c 1.5 -> 1.6 # drivers/net/a2065.c 1.17 -> 1.18 # drivers/net/amd8111e.c 1.12.1.1 -> 1.15 # fs/Kconfig 1.44 -> 1.46 # drivers/net/tokenring/tms380tr.c 1.19 -> 1.20 # include/linux/sunrpc/timer.h 1.6 -> 1.7 # drivers/net/hamradio/baycom_ser_fdx.c 1.13 -> 1.14 # drivers/block/loop.c 1.122 -> 1.124 # arch/parisc/configs/c3000_defconfig 1.1 -> 1.2 # sound/parisc/Kconfig 1.1 -> 1.2 # include/sound/trident.h 1.10 -> 1.11 # include/acpi/actypes.h 1.32 -> 1.33 # drivers/scsi/aacraid/sa.c 1.7 -> 1.8 # include/asm-x86_64/vsyscall32.h 1.2 -> 1.3 # net/sunrpc/auth_unix.c 1.12 -> 1.13 # drivers/net/arm/ether1.c 1.18 -> 1.19 # sound/pci/azt3328.c 1.9 -> 1.11 # drivers/acpi/events/evgpe.c 1.18 -> 1.19 # drivers/net/declance.c 1.19 -> 1.20 # fs/udf/file.c 1.16 -> 1.17 # sound/pci/ice1712/hoontech.c 1.2 -> 1.3 # drivers/net/tulip/tulip_core.c 1.52 -> 1.54 # sound/pci/maestro3.c 1.30 -> 1.32 # drivers/net/atari_bionet.c 1.13 -> 1.14 # include/sound/asequencer.h 1.7 -> 1.8 # MAINTAINERS 1.196.1.1 -> 1.199 # drivers/scsi/sata_svw.c 1.8 -> 1.10 # fs/jffs/inode-v23.c 1.59 -> 1.60 # drivers/net/zorro8390.c 1.9.1.1 -> 1.11 # drivers/net/sundance.c 1.53 -> 1.54 # sound/pci/intel8x0.c 1.61 -> 1.71 # sound/isa/es1688/es1688_lib.c 1.10 -> 1.13 # drivers/scsi/sym53c8xx_2/sym_nvram.c 1.3 -> 1.4 # sound/pci/ice1712/revo.c 1.4 -> 1.5 # fs/udf/misc.c 1.6 -> 1.7 # arch/x86_64/lib/iodebug.c 1.1 -> (deleted) # include/net/irda/vlsi_ir.h 1.12 -> 1.13 # mm/mempool.c 1.17 -> 1.18 # mm/mmap.c 1.102 -> 1.103 # sound/usb/usbaudio.h 1.19 -> 1.20 # sound/pci/ac97/Makefile 1.14 -> 1.15 # drivers/video/i810/i810_main.h 1.11 -> 1.12 # drivers/char/watchdog/w83877f_wdt.c 1.22 -> 1.23 # include/asm-mips/dma-mapping.h 1.4 -> 1.5 # arch/cris/kernel/process.c 1.14 -> 1.15 # drivers/message/fusion/lsi/mpi_type.h 1.3 -> 1.4 # drivers/message/i2o/i2o_core.c 1.23 -> 1.24 # fs/read_write.c 1.35 -> 1.36 # arch/sparc64/kernel/sys_sparc32.c 1.90 -> 1.91 # arch/x86_64/ia32/syscall32.c 1.5 -> 1.6 # drivers/net/typhoon.c 1.13 -> 1.14 # include/linux/compiler.h 1.23 -> 1.24 # sound/pci/trident/trident_main.c 1.28 -> 1.31 # sound/isa/ad1816a/ad1816a_lib.c 1.10 -> 1.13 # drivers/scsi/st.c 1.79 -> 1.80 # fs/qnx4/dir.c 1.7 -> 1.8 # include/asm-i386/unistd.h 1.33 -> 1.34 # drivers/net/ariadne.c 1.14 -> 1.15 # init/do_mounts.h 1.11 -> 1.12 # fs/udf/super.c 1.38 -> 1.39 # drivers/net/eepro100.c 1.68 -> 1.72 # include/asm-sh/pci.h 1.16 -> 1.17 # fs/nfs/file.c 1.33 -> 1.35 # include/sound/asound.h 1.21 -> 1.22 # include/asm-x86_64/calling.h 1.7 -> 1.8 # include/acpi/amlcode.h 1.18 -> 1.19 # drivers/net/wan/comx-hw-locomx.c 1.9 -> 1.10 # drivers/net/ac3200.c 1.16 -> 1.17 # drivers/message/fusion/Makefile 1.12 -> 1.13 # Makefile 1.463 -> 1.464 # drivers/parisc/superio.c 1.9 -> 1.10 # sound/pci/cmipci.c 1.36 -> 1.39 # drivers/base/map.c 1.2 -> 1.3 # arch/ia64/kernel/head.S 1.17 -> 1.18 # include/asm-x86_64/acpi.h 1.6 -> 1.7 # fs/lockd/svcproc.c 1.11 -> 1.13 # drivers/net/pcmcia/fmvj18x_cs.c 1.30 -> 1.31 # fs/udf/osta_udf.h 1.5 -> 1.6 # arch/i386/defconfig 1.106 -> 1.108 # drivers/net/stnic.c 1.9 -> 1.10 # net/sunrpc/xprt.c 1.76 -> 1.80 # drivers/net/pcmcia/smc91c92_cs.c 1.28 -> 1.29 # include/asm-m68k/irq.h 1.7 -> 1.8 # arch/x86_64/defconfig 1.33 -> 1.34 # arch/ppc64/mm/numa.c 1.20 -> 1.21 # sound/core/pcm_memory.c 1.13 -> 1.15 # fs/affs/super.c 1.41 -> 1.42 # sound/core/sgbuf.c 1.6 -> 1.9 # sound/pci/trident/trident_memory.c 1.6 -> 1.8 # drivers/scsi/scsi_priv.h 1.31 -> 1.32 # sound/pci/es1938.c 1.26 -> 1.28 # include/linux/device-mapper.h 1.4 -> 1.6 # drivers/net/tulip/pnic.c 1.9 -> 1.10 # drivers/video/console/fbcon.c 1.111 -> 1.112 # drivers/char/watchdog/sbc60xxwdt.c 1.35 -> 1.36 # sound/core/Makefile 1.32 -> 1.40 # include/linux/topology.h 1.3 -> 1.4 # include/asm-mips/pci.h 1.16 -> 1.17 # include/asm-x86_64/thread_info.h 1.14 -> 1.15 # include/linux/page-flags.h 1.43 -> 1.45 # net/sunrpc/xdr.c 1.17 -> 1.18 # drivers/parisc/lba_pci.c 1.9 -> 1.10 # drivers/net/fealnx.c 1.33 -> 1.34 # sound/pci/es1968.c 1.33 -> 1.35 # arch/ia64/sn/io/hwgfs/ramfs.c 1.4 -> 1.5 # drivers/net/8390.h 1.13 -> 1.14 # drivers/net/3c503.c 1.17 -> 1.18 # include/sound/pcm_oss.h 1.6 -> 1.7 # drivers/scsi/sata_promise.c 1.23 -> 1.25 # drivers/pci/probe.c 1.60 -> 1.61 # CREDITS 1.107 -> 1.108 # init/do_mounts_rd.c 1.9 -> 1.10 # sound/pci/sonicvibes.c 1.25 -> 1.27 # drivers/net/82596.c 1.17 -> 1.18 # drivers/scsi/constants.c 1.14 -> 1.15 # sound/core/Kconfig 1.2 -> 1.3 # arch/mips/mm/dma-ip27.c 1.1 -> 1.2 # fs/lockd/mon.c 1.9 -> 1.10 # drivers/net/7990.c 1.9 -> 1.10 # Documentation/filesystems/ufs.txt 1.1 -> 1.2 # kernel/module.c 1.104 -> 1.105 # include/linux/security.h 1.30 -> 1.31 # include/asm-parisc/pci.h 1.12 -> 1.13 # sound/usb/Kconfig 1.2 -> 1.4 # sound/drivers/Kconfig 1.1 -> 1.6 # drivers/ieee1394/dv1394.c 1.40 -> 1.41 # sound/usb/usbaudio.c 1.61 -> 1.69 # include/asm-ia64/dma-mapping.h 1.2 -> 1.3 # arch/ia64/sn/io/sn2/pcibr/pcibr_intr.c 1.17 -> 1.18 # include/asm-ppc/pci.h 1.24 -> 1.25 # include/linux/sunrpc/xprt.h 1.28 -> 1.31 # fs/nfs/nfsroot.c 1.13 -> 1.14 # arch/ia64/lib/swiotlb.c 1.16 -> 1.17 # include/asm-sparc/pci.h 1.13 -> 1.14 # drivers/net/eepro.c 1.21 -> 1.23 # arch/x86_64/kernel/Makefile 1.32 -> 1.33 # init/do_mounts_devfs.c 1.5 -> 1.6 # fs/nfs/write.c 1.46 -> 1.49 # sound/sparc/Kconfig 1.1 -> 1.2 # drivers/char/watchdog/alim7101_wdt.c 1.12 -> 1.13 # arch/i386/kernel/cpu/mcheck/mce.c 1.4 -> 1.5 # include/asm-i386/pgtable.h 1.39 -> 1.40 # include/acpi/acconfig.h 1.50 -> 1.51 # fs/nfs/nfs4proc.c 1.43 -> 1.46 # drivers/net/oaknet.c 1.6 -> 1.7 # include/sound/info.h 1.11 -> 1.12 # drivers/scsi/sd.c 1.141 -> 1.142 # drivers/net/seeq8005.c 1.15 -> 1.16 # drivers/parisc/sba_iommu.c 1.12 -> 1.14 # drivers/macintosh/therm_pm72.c 1.1 -> 1.2 # fs/minix/dir.c 1.14 -> 1.15 # arch/m68k/hp300/time.c 1.6 -> 1.7 # drivers/net/smc9194.c 1.20 -> 1.21 # arch/i386/kernel/bootflag.c 1.3 -> 1.4 # drivers/net/gt96100eth.c 1.13 -> 1.14 # drivers/net/arm/am79c961a.c 1.15 -> 1.16 # drivers/net/3c507.c 1.15 -> 1.16 # drivers/media/dvb/frontends/sp887x.c 1.8 -> 1.9 # sound/core/pcm_misc.c 1.9 -> 1.10 # drivers/net/tokenring/olympic.c 1.28 -> 1.29 # arch/x86_64/kernel/vsyscall.c 1.13 -> 1.14 # mm/slab.c 1.120 -> 1.121 # include/linux/module.h 1.72 -> 1.74 # drivers/md/dm.c 1.38 -> 1.39 # fs/nfs/inode.c 1.96 -> 1.105 # drivers/net/tulip/xircom_cb.c 1.19 -> 1.20 # fs/ext2/acl.c 1.10 -> 1.11 # arch/x86_64/Kconfig 1.44 -> 1.45 # sound/pci/fm801.c 1.24 -> 1.27 # drivers/scsi/scsi_scan.c 1.115 -> 1.117 # kernel/sched.c 1.247 -> 1.248 # drivers/scsi/aacraid/rkt.c 1.2 -> 1.3 # drivers/acpi/executer/exmutex.c 1.13 -> 1.14 # drivers/net/es3210.c 1.11 -> 1.12 # arch/i386/mach-pc9800/Makefile 1.1 -> 1.2 # include/linux/ufs_fs.h 1.8 -> 1.9 # drivers/char/watchdog/wdt977.c 1.22 -> 1.23 # arch/x86_64/lib/csum-copy.S 1.5 -> 1.6 # drivers/scsi/Makefile 1.54 -> 1.57 # drivers/net/tulip/de2104x.c 1.26 -> 1.27 # drivers/block/Makefile 1.23 -> 1.24 # drivers/acpi/osl.c 1.45 -> 1.46 # drivers/net/cs89x0.c 1.21 -> 1.22 # include/linux/lockd/debug.h 1.2 -> 1.3 # drivers/scsi/st.h 1.16 -> 1.17 # sound/pci/ens1370.c 1.43 -> 1.45 # fs/ufs/dir.c 1.14 -> 1.15 # arch/h8300/kernel/sys_h8300.c 1.4 -> 1.5 # arch/x86_64/mm/numa.c 1.7 -> 1.8 # fs/udf/udf_sb.h 1.7 -> 1.8 # arch/sparc64/kernel/sparc64_ksyms.c 1.63 -> 1.64 # include/asm-x86_64/system.h 1.19 -> 1.20 # include/linux/nfs_xdr.h 1.45 -> 1.46 # kernel/timer.c 1.76 -> 1.77 # sound/pci/via82xx.c 1.74 -> 1.83 # drivers/net/eth16i.c 1.16 -> 1.17 # drivers/video/dnfb.c 1.23 -> 1.24 # arch/m68k/mac/macints.c 1.12 -> 1.13 # sound/core/seq/seq_midi.c 1.12 -> 1.15 # arch/i386/mach-visws/Makefile 1.6 -> 1.7 # drivers/ieee1394/dma.h 1.4 -> 1.5 # drivers/ieee1394/ohci1394.c 1.59 -> 1.60 # drivers/net/smc-ultra32.c 1.10 -> 1.11 # include/linux/dma-mapping.h 1.1 -> 1.2 # fs/freevxfs/vxfs_super.c 1.19 -> 1.20 # drivers/net/Kconfig 1.56.1.11 -> 1.61 # drivers/net/sun3lance.c 1.19 -> 1.20 # arch/sparc/kernel/sun4m_smp.c 1.11 -> 1.12 # Documentation/filesystems/udf.txt 1.3 -> 1.4 # sound/core/oss/pcm_oss.c 1.42 -> 1.45 # fs/udf/namei.c 1.27 -> 1.28 # drivers/scsi/eata.c 1.35 -> 1.36 # sound/drivers/opl4/Makefile 1.1 -> 1.3 # sound/isa/Kconfig 1.5 -> 1.9 # arch/i386/kernel/acpi/boot.c 1.50 -> 1.51 # net/sunrpc/sunrpc_syms.c 1.28 -> 1.29 # arch/parisc/kernel/sys_parisc.c 1.15 -> 1.16 # sound/pci/ymfpci/ymfpci_main.c 1.29 -> 1.31 # drivers/scsi/sym53c8xx_2/sym_misc.c 1.3 -> 1.4 # drivers/net/arm/etherh.c 1.20 -> 1.21 # arch/ppc64/kernel/misc.S 1.71 -> 1.72 # drivers/parport/parport_gsc.c 1.13 -> 1.14 # arch/m68k/q40/q40ints.c 1.18 -> 1.19 # arch/x86_64/Makefile 1.37 -> 1.38 # include/asm-x86_64/proto.h 1.19 -> 1.20 # drivers/video/fbmon.c 1.11 -> 1.12 # arch/parisc/kernel/drivers.c 1.10 -> 1.11 # include/asm-i386/acpi.h 1.13 -> 1.15 # fs/nfs/direct.c 1.4 -> 1.5 # sound/usb/usbmidi.c 1.24 -> 1.27 # sound/pci/emu10k1/memory.c 1.9 -> 1.11 # drivers/net/tulip/dmfe.c 1.36 -> 1.37 # fs/bfs/dir.c 1.21 -> 1.22 # fs/proc/inode.c 1.26 -> 1.27 # drivers/scsi/Kconfig 1.56 -> 1.60 # sound/drivers/vx/vx_core.c 1.4 -> 1.6 # include/asm-generic/dma-mapping.h 1.4 -> 1.5 # sound/arm/Kconfig 1.1 -> 1.2 # arch/i386/lib/iodebug.c 1.2 -> (deleted) # include/linux/device.h 1.115 -> 1.116 # arch/m68knommu/kernel/sys_m68k.c 1.2 -> 1.3 # arch/ppc/kernel/ppc_ksyms.c 1.52 -> 1.53 # drivers/net/e2100.c 1.15 -> 1.16 # drivers/net/lne390.c 1.11 -> 1.12 # sound/pci/ice1712/prodigy.c 1.3 -> 1.4 # drivers/char/watchdog/ib700wdt.c 1.26 -> 1.27 # arch/ppc/kernel/misc.S 1.52 -> 1.53 # arch/ppc/platforms/pmac_feature.c 1.22 -> 1.23 # fs/nfs/pagelist.c 1.15 -> 1.16 # drivers/net/sb1250-mac.c 1.9 -> 1.10 # include/asm-ia64/pci.h 1.24 -> 1.25 # include/asm-x86_64/msr.h 1.7 -> 1.8 # arch/parisc/kernel/pci-dma.c 1.7 -> 1.9 # drivers/net/sgiseeq.c 1.17 -> 1.18 # fs/udf/unicode.c 1.4 -> 1.5 # drivers/char/genrtc.c 1.11 -> 1.12 # sound/pci/ac97/ac97_patch.c 1.32 -> 1.37 # fs/nfs/proc.c 1.28 -> 1.31 # init/do_mounts_md.c 1.4 -> 1.6 # arch/m68k/mac/iop.c 1.10 -> 1.11 # kernel/kthread.c 1.1 -> 1.2 # sound/pci/als4000.c 1.20 -> 1.23 # sound/pci/ali5451/ali5451.c 1.33 -> 1.35 # drivers/char/applicom.c 1.10 -> 1.11 # drivers/net/tulip/eeprom.c 1.9 -> 1.10 # drivers/char/watchdog/wafer5823wdt.c 1.14 -> 1.15 # drivers/acpi/executer/excreate.c 1.19 -> 1.20 # net/core/Makefile 1.18 -> 1.19 # include/linux/netdevice.h 1.70.1.1 -> 1.73 # security/selinux/hooks.c 1.25 -> 1.26 # drivers/net/tokenring/madgemc.c 1.19 -> 1.20 # arch/ppc/kernel/smp.c 1.41 -> 1.42 # fs/nfs/unlink.c 1.8 -> 1.9 # drivers/scsi/BusLogic.c 1.29 -> 1.30 # arch/ia64/Kconfig 1.62 -> 1.63 # drivers/net/hamradio/baycom_par.c 1.11 -> 1.12 # drivers/net/pcmcia/3c589_cs.c 1.26 -> 1.27 # include/asm-ppc64/mmzone.h 1.15 -> 1.16 # sound/pci/cs4281.c 1.32 -> 1.34 # include/asm-ia64/sal.h 1.21 -> 1.23 # mm/truncate.c 1.11 -> 1.12 # sound/usb/usbmixer_maps.c 1.4 -> 1.5 # include/linux/kernel_stat.h 1.13 -> 1.14 # include/linux/compat_ioctl.h 1.16 -> 1.17 # drivers/net/tokenring/proteon.c 1.8 -> 1.9 # arch/ia64/kernel/sal.c 1.7 -> 1.9 # drivers/net/sungem.c 1.52 -> 1.53 # drivers/acpi/namespace/nsaccess.c 1.24 -> 1.25 # drivers/parisc/gsc.c 1.3 -> 1.4 # drivers/acpi/sleep/poweroff.c 1.1 -> 1.2 # sound/isa/ad1848/ad1848_lib.c 1.18 -> 1.21 # drivers/net/isa-skeleton.c 1.11 -> 1.12 # drivers/scsi/dc395x.h 1.3 -> 1.4 # sound/pci/emu10k1/emu10k1_main.c 1.19 -> 1.21 # arch/x86_64/ia32/ia32_signal.c 1.18 -> 1.19 # drivers/net/via-rhine.c 1.49 -> 1.51 # include/asm-x86_64/processor.h 1.29 -> 1.30 # sound/core/memalloc.c 1.16 -> 1.24 # drivers/net/arm/ether3.c 1.20 -> 1.21 # drivers/md/dm-table.c 1.32 -> 1.34 # drivers/scsi/sym53c8xx_2/sym_fw.c 1.4 -> 1.5 # drivers/net/tokenring/3c359.c 1.18 -> 1.19 # drivers/net/plip.c 1.19 -> 1.20 # arch/parisc/kernel/smp.c 1.9 -> 1.10 # drivers/md/dm-target.c 1.10 -> 1.13 # kernel/workqueue.c 1.15 -> 1.16 # include/scsi/scsi.h 1.17 -> 1.20 # arch/sparc/kernel/ioport.c 1.13 -> 1.14 # fs/inode.c 1.109 -> 1.110 # arch/parisc/configs/712_defconfig 1.1 -> 1.2 # arch/parisc/kernel/process.c 1.14 -> 1.16 # sound/pci/rme32.c 1.22 -> 1.24 # drivers/net/e100.c 1.8 -> 1.10 # arch/i386/kernel/i386_ksyms.c 1.57 -> 1.58 # include/asm-i386/io.h 1.25 -> 1.26 # drivers/atm/fore200e.c 1.23 -> 1.24 # drivers/net/atp.c 1.16 -> 1.17 # fs/proc/kmsg.c 1.5 -> 1.6 # fs/nfs/nfs4xdr.c 1.39 -> 1.41 # arch/ia64/sn/io/sn2/pciio.c 1.15 -> 1.16 # drivers/block/scsi_ioctl.c 1.40 -> 1.41 # drivers/net/ne2.c 1.13 -> 1.14 # drivers/net/hamradio/baycom_epp.c 1.21 -> 1.22 # drivers/net/apne.c 1.13 -> 1.14 # fs/proc/generic.c 1.25 -> 1.26 # drivers/scsi/sym53c8xx_2/sym_glue.h 1.16 -> 1.17 # drivers/scsi/sym53c8xx_2/sym53c8xx.h 1.11 -> 1.12 # drivers/char/sn_serial.c 1.5 -> 1.8 # drivers/net/hamachi.c 1.31 -> 1.32 # arch/parisc/kernel/parisc_ksyms.c 1.16 -> 1.17 # include/linux/sunrpc/xdr.h 1.13 -> 1.14 # drivers/message/fusion/mptscsih.h 1.20 -> 1.21 # drivers/scsi/sym53c8xx_2/sym_misc.h 1.2 -> 1.3 # sound/drivers/mpu401/Makefile 1.15 -> 1.16 # arch/sparc64/kernel/sbus.c 1.14 -> 1.15 # include/linux/loop.h 1.20 -> 1.21 # sound/core/pcm.c 1.22 -> 1.24 # drivers/scsi/qlogicfas.c 1.24 -> 1.34 # arch/m68k/sun3/sun3ints.c 1.8 -> 1.9 # include/asm-i386/dma-mapping.h 1.2 -> 1.3 # arch/x86_64/kernel/smpboot.c 1.23 -> 1.24 # fs/nfs/nfs3xdr.c 1.27 -> 1.29 # fs/ufs/namei.c 1.23 -> 1.24 # arch/ia64/sn/io/sn2/pcibr/pcibr_dvr.c 1.29 -> 1.30 # drivers/net/wireless/orinoco.c 1.26 -> 1.27 # sound/ppc/pmac.c 1.17 -> 1.18 # arch/m68k/amiga/amiints.c 1.8 -> 1.9 # drivers/message/fusion/Kconfig 1.3.1.1 -> 1.5 # include/asm-s390/unistd.h 1.20 -> 1.21 # drivers/scsi/aacraid/rx.c 1.7 -> 1.8 # fs/block_dev.c 1.153 -> 1.155 # drivers/net/sis190.c 1.18 -> 1.19 # Documentation/kernel-parameters.txt 1.41 -> 1.42 # fs/udf/inode.c 1.35 -> 1.36 # arch/parisc/kernel/module.c 1.8 -> 1.9 # drivers/net/wireless/Makefile 1.15 -> 1.16 # include/asm-m68k/bitops.h 1.10 -> 1.11 # drivers/scsi/sym53c8xx_2/sym_glue.c 1.40 -> 1.42 # drivers/net/sk_g16.c 1.15 -> 1.16 # drivers/message/fusion/mptscsih.c 1.34 -> 1.37 # include/linux/sunrpc/debug.h 1.4 -> 1.6 # (new) -> 1.3 sound/pcmcia/pdaudiocf/pdaudiocf.h # (new) -> 1.3 drivers/net/wireless/prism54/islpci_dev.c # (new) -> 1.1 sound/pci/au88x0/au88x0_a3d.h # (new) -> 1.1 sound/pci/mixart/Makefile # (new) -> 1.3 sound/pci/mixart/mixart.h # (new) -> 1.2 drivers/net/wireless/prism54/islpci_eth.c # (new) -> 1.1 drivers/scsi/scsi_transport_fc.c # (new) -> 1.1 sound/pci/au88x0/au88x0_game.c # (new) -> 1.1 sound/pci/au88x0/au8820.h # (new) -> 1.1 Documentation/networking/netconsole.txt # (new) -> 1.1 arch/x86_64/ia32/vsyscall-sigreturn.S # (new) -> 1.1 include/linux/netpoll.h # (new) -> 1.1 drivers/message/fusion/lsi/mpi_inb.h # (new) -> 1.2 drivers/net/wireless/prism54/islpci_mgt.h # (new) -> 1.1 arch/x86_64/pci/mmconfig.c # (new) -> 1.3 drivers/scsi/qlogicfas.h # (new) -> 1.1 sound/pci/au88x0/au8810.c # (new) -> 1.1 arch/parisc/configs/b180_defconfig # (new) -> 1.5 include/scsi/scsi_transport_spi.h # (new) -> 1.1 sound/pci/au88x0/au8830.c # (new) -> 1.1 sound/pci/au88x0/au88x0_mixer.c # (new) -> 1.1 sound/pci/au88x0/au88x0_sb.h # (new) -> 1.1 sound/pcmcia/pdaudiocf/pdaudiocf_core.c # (new) -> 1.3 sound/pcmcia/pdaudiocf/pdaudiocf.c # (new) -> 1.3 drivers/net/wireless/prism54/isl_ioctl.c # (new) -> 1.1 sound/pci/mixart/mixart_mixer.h # (new) -> 1.1 include/scsi/scsi_transport_fc.h # (new) -> 1.1 drivers/parisc/iommu-helpers.h # (new) -> 1.1 sound/pci/au88x0/au88x0_xtalk.h # (new) -> 1.2 drivers/net/wireless/prism54/islpci_dev.h # (new) -> 1.1 sound/pcmcia/pdaudiocf/Makefile # (new) -> 1.1 drivers/message/fusion/lsi/mpi_tool.h # (new) -> 1.1 sound/pci/au88x0/au8830.h # (new) -> 1.2 sound/pci/mixart/mixart_mixer.c # (new) -> 1.2 drivers/net/wireless/prism54/Makefile # (new) -> 1.4 drivers/net/netconsole.c # (new) -> 1.2 drivers/net/wireless/prism54/islpci_hotplug.c # (new) -> 1.5 drivers/scsi/scsi_transport_spi.c # (new) -> 1.1 drivers/net/wireless/prism54/isl_38xx.c # (new) -> 1.1 sound/pci/au88x0/au88x0_pcm.c # (new) -> 1.2 sound/pci/au88x0/au88x0.c # (new) -> 1.1 sound/pci/au88x0/au88x0_a3d.c # (new) -> 1.1 sound/pci/au88x0/au88x0_eqdata.c # (new) -> 1.2 drivers/net/wireless/prism54/isl_ioctl.h # (new) -> 1.1 sound/pci/au88x0/au88x0_wt.h # (new) -> 1.1 sound/pci/intel8x0m.c # (new) -> 1.2 drivers/scsi/sata_vsc.c # (new) -> 1.1 sound/pci/atiixp.c # (new) -> 1.1 sound/pcmcia/pdaudiocf/pdaudiocf_pcm.c # (new) -> 1.2 sound/i2c/other/ak4117.c # (new) -> 1.1 sound/pci/au88x0/au88x0.h # (new) -> 1.1 sound/pci/au88x0/Makefile # (new) -> 1.1 drivers/net/wireless/prism54/isl_oid.h # (new) -> 1.1 sound/pci/mixart/mixart_core.h # (new) -> 1.1 arch/ia64/configs/zx1_defconfig # (new) -> 1.2 sound/pcmcia/pdaudiocf/pdaudiocf_irq.c # (new) -> 1.1 Documentation/sound/alsa/MIXART.txt # (new) -> 1.1 sound/pci/au88x0/au8810.h # (new) -> 1.3 drivers/net/wireless/prism54/islpci_mgt.c # (new) -> 1.1 sound/pci/au88x0/au88x0_synth.c # (new) -> 1.6 sound/pci/mixart/mixart.c # (new) -> 1.1 include/sound/ak4117.h # (new) -> 1.1 sound/pci/au88x0/au88x0_mpu401.c # (new) -> 1.1 sound/pci/au88x0/au88x0_eq.h # (new) -> 1.1 sound/pci/au88x0/au8820.c # (new) -> 1.1 sound/pci/au88x0/au88x0_xtalk.c # (new) -> 1.2 drivers/block/carmel.c # (new) -> 1.1 sound/pci/au88x0/au88x0_a3ddata.c # (new) -> 1.1 include/scsi/scsi_transport.h # (new) -> 1.1 arch/x86_64/ia32/vsyscall-sysenter.S # (new) -> 1.1 drivers/scsi/sym53c8xx_2/sym_nvram.h # (new) -> 1.1 sound/pci/au88x0/au88x0_eq.c # (new) -> 1.1 drivers/net/wireless/prism54/islpci_eth.h # (new) -> 1.1 sound/pci/au88x0/au88x0_core.c # (new) -> 1.1 drivers/net/wireless/prism54/oid_mgt.c # (new) -> 1.1 sound/pci/mixart/mixart_hwdep.h # (new) -> 1.1 drivers/net/wireless/prism54/oid_mgt.h # (new) -> 1.7 net/core/netpoll.c # (new) -> 1.6 sound/pci/mixart/mixart_core.c # (new) -> 1.1 drivers/message/fusion/lsi/mpi_sas.h # (new) -> 1.1 arch/x86_64/ia32/vsyscall-syscall.S # (new) -> 1.5 sound/pci/mixart/mixart_hwdep.c # (new) -> 1.1 drivers/net/wireless/prism54/isl_38xx.h # # The following is the BitKeeper ChangeSet Log # -------------------------------------------- # 04/03/10 torvalds@ppc970.osdl.org 1.1608.83.7 # Linux 2.6.4 # -------------------------------------------- # 04/03/10 jgarzik@redhat.com 1.1611 # Merge redhat.com:/spare/repo/linux-2.5 # into redhat.com:/spare/repo/netdev-2.6/netpoll # -------------------------------------------- # 04/03/10 benh@kernel.crashing.org 1.1608.83.8 # [PATCH] G5 temperature control update # # This makes the temperature control code more robust, putting less # pressure on i2c, and work around occasional misconfiguration of the ADC # chips leading to incorrect temperature readings. # -------------------------------------------- # 04/03/10 len.brown@intel.com 1.1608.1.39 # Merge intel.com:/home/lenb/bk/linux-2.6.4 # into intel.com:/home/lenb/src/linux-acpi-test-2.6.4 # -------------------------------------------- # 04/03/10 jgarzik@redhat.com 1.1608.55.32 # Merge redhat.com:/spare/repo/linux-2.5 # into redhat.com:/spare/repo/libata-2.5 # -------------------------------------------- # 04/03/10 jejb@mulgrave.(none) 1.1608.85.1 # Merge qboosh/emoore conflict # -------------------------------------------- # 04/03/10 len.brown@intel.com 1.1557.76.8 # Delete (void)func() casts considered cruft in Linux style. # # GCC's inability to warn when return values are ignored has conditioned # Linux programmers into thinking that this is actually normal. # # delete some #define's -- suggested by Matt Wilcox # -------------------------------------------- # 04/03/10 len.brown@intel.com 1.1557.76.9 # [ACPI] fix printk and build warning from previous csets # -------------------------------------------- # 04/03/10 len.brown@intel.com 1.1608.1.40 # merge 2.6.3 into 2.6.4 # -------------------------------------------- # 04/03/10 ak@suse.de 1.1608.83.9 # [PATCH] x86-64 merge for 2.6.4 # # The biggest new feature is fixed 32bit vsyscall (SYSCALL+SYSENTER) # support, mostly from Jakub Jelinek. This increases 32bit syscall # performance greatly (latency halved and better). The SYSENTER for Intel # support required some infrastructure changes, but seems to work now too. # # The 64bit vsyscall vtime() just references xtime.tv_sec now. This # should make it a lot faster too. # # A fix for some Intel IA32e systems. Also a few long standing bugs in # NMI like exception handlers were fixed. # # And a lot of other bug fixes. # # Full changeLog: # - Clean up 32bit address room limit handling, fix 3gb personality # - Move memcpy_{from,to}io export to ksyms.c file. This seems to work # around a toolchain bug (Andreas Gruenbacher) # - Update defconfig # - ACPI merges from i386 (SBF should work now, acpi=strict) # - Implement mmconfig support based on i386 code (untested) # - Fix i386/x86-64 pci source file sharing # - Implement ptrace access for 32bit vsyscall page # - Always initialize all 32bit SYSENTER/SYSCALL MSRs. # - Export run time cache line size to generic kernel # - Remove explicit CPUID in ia32 syscall code # - Fill in most of boot_cpu_data early # - Remove unused PER_LINUX32 setup # - Fix syscall trace in fast 32bit calls (Suresh B. Siddha) # - Tighten first line of the oops again. # - Set up ptrace registers correctly for debug,ss,double fault exceptions # - Fix 64bit bug in sys_time64 # - Optimize time syscall/vsyscall to only read xtime # - Fix csum_partial_copy_nocheck # - Remove last traces of FPU emulation # - Check properly for rescheduling in exceptions with own stack # - Harden exception stack entries (#SS,#NMI,#MC,#DF,#DB) against bogus GS # - Use an exception stack for machine checks # - Handle TIF_SINGLESTEP properly in kernel exit # - Add exception stack for debug handler # - Disable X86_HT for Opteron optimized builds because it pulls in ACPI_BOOT # - Fix CONFIG_ACPI_BOOT compilation without CONFIG_ACPI # - Fix eflags handling in SYSENTER path (Jakub Jelinek) # - Use atomic counter for enable/disable_hlt # - Support 32bit SYSENTER vsyscall too (Jakub Jelinek) # - Don't redefine Dprintk # - Change some cpu/apic id arrays to char # - Support arbitary cpu<->apicid in hard_smp_processor_id (Surresh B Sidda) # - Move K8 erratum #100 workaround into slow path of page fault handler. # - Fix 32bit cdrom direct access ioctls (Jens Axboe) # - Enable 32bit vsyscalls by default # - Fix 32bit vsyscalls (Jakub Jelinek) # -------------------------------------------- # 04/03/10 ak@suse.de 1.1608.83.10 # [PATCH] Fix a 64bit bug in kobject module request # # From Takashi Iwai # # kobj_lookup had a 64bit bug, which caused the request of a unknown # character device to burn CPU instead of failing quickly. # -------------------------------------------- # 04/03/10 davidm@tiger.hpl.hp.com 1.1608.81.36 # Merge tiger.hpl.hp.com:/data1/bk/vanilla/linux-2.5 # into tiger.hpl.hp.com:/data1/bk/lia64/to-linus-2.5 # -------------------------------------------- # 04/03/10 kaneshige.kenji@jp.fujitsu.com 1.1608.81.37 # ia64: don't unmask iosapic interrupts by default # # In ia64 kernel, IOSAPIC's RTEs for PCI interrupts are unmasked at the # boot time before installing device drivers. I think it is very dangerous. # If some PCI devices without device driver generate interrupts, interrupts # are generated repeatedly because these interrupt requests are never # cleared. I think RTEs for PCI interrupts should be unmasked by device # driver. This patch fixes the problem. # -------------------------------------------- # 04/03/11 willy@debian.org 1.1608.81.38 # [PATCH] ia64: Convert to use the generic drivers/Kconfig mechanism. # # -------------------------------------------- # 04/03/11 jbarnes@sgi.com 1.1608.81.39 # [PATCH] ia64: fix misc. sn2 warnings # # This patch fixes a few warnings that have cropped up in the sn2 code: # - hwgfs function prototype mismatch # - pconn uninitialized in pciio.c # - printk formatting fixes in pcibr_dvr.c # - kill volatile qualifier in pcibr_intr.c # -------------------------------------------- # 04/03/12 sfr@canb.auug.org.au 1.1608.83.11 # [PATCH] fix PPC64 iSeries virtual console devices # # While playing with udev, I discovered that the virtual console # devices on iSeries had there minor numbers off by one i.e. /dev/tty1 # was minor 2! # # This fixes it. # -------------------------------------------- # 04/03/12 axboe@suse.de 1.1608.83.12 # [PATCH] user data -> request mapping # # This patch allows you to map a request with user data for io, similarly # to what you can do with bio_map_user() already to a bio. However, this # goes one step further and populates the request so the user only has to # fill in the cdb (almost) and put it on the queue for execution. Patch # converts sg_io() to use it, next patch I'll send adapts cdrom layer to # use it for zero copy cdda dma extraction. # -------------------------------------------- # 04/03/12 axboe@suse.de 1.1608.83.13 # [PATCH] CDROMREADAUDIO dma support # # This small patch builds on top of the blk_rq_map_user() patch just sent, # and enables us to easily support DMA for CDROMREADAUDIO cdda extraction. # It's quite amazing how much cool stuff you can with the new block layer # :-) # # Patch has intelligent fall back from multi frame dma to single frame # dma, and further to old-style pio ripping in case of hardware problems. # -------------------------------------------- # 04/03/12 anton@samba.org 1.1608.83.14 # [PATCH] fix ppc64 in kernel syscalls # # Thanks to some great debugging work by Olaf Hering and Marcus Meissner # it has been noticed that the current ppc64 syscall code is corrupting # 4 bytes past errno. Why we even bothered to set errno beats me, its # unusable in the kernel. # # Since we had to reinstate the inline syscall code we can go back to # using it for those few syscalls that we call. Especially now with # Randy's syscall prototype cleanup we should be calling them directly # but we can do that sometime later. # -------------------------------------------- # 04/03/12 benh@kernel.crashing.org 1.1608.83.15 # [PATCH] ppc32: Fix G5 config space access lockup # # Fix a typo in the code that prevents lockup on config space access # to sleeping devices on ppc32/G5. Please apply. # -------------------------------------------- # 04/03/12 akpm@osdl.org 1.1608.83.16 # [PATCH] print kernel version in oops messages # # From: Arjan van de Ven # # Unfortunatly a large portion of the oops reports lack the basic # information about what kernel version the oops is for; it's trivial to just # print this in the oops as well to improve the usefulness of bugreports... # -------------------------------------------- # 04/03/12 akpm@osdl.org 1.1608.83.17 # [PATCH] ppc64: fix initialisation of NUMA arrays # # From: Anton Blanchard # # We were hitting problems on machines with cpu_possible != cpu_online when # NUMA was enabled. The debug checks would trip during scheduler init # because we iterate through all possible cpus whereas we only set up NUMA # information for online cpus. # # Longer term we should have a cpu_up hook which sets up its NUMA information # but for now we initalise all possible cpus and memory to node 0. # -------------------------------------------- # 04/03/12 akpm@osdl.org 1.1608.83.18 # [PATCH] Clean up sys_ioperm stubs # # From: Brian Gerst # # Remove stubs for sys_ioperm for non-x86 arches, using sys_ni_syscall # instead where applicable. Support for sys_ioperm is unconditionally no for # non-x86 arches. # -------------------------------------------- # 04/03/12 akpm@osdl.org 1.1608.83.19 # [PATCH] readdir() cleanups # # From: # # cramfs and freevxfs explicitly mark themselves readonly (as other r/o fs # do). # # afs marked noatime (ACKed by maintainer) # # filesystems that do not do update_atime() in their ->readdir() had been # explicitly marked nodiratime. NOTE: cifs, coda and ncpfs almost certainly # need full noatime as we currently have in nfs and afs. # # update_atime() call shifted to callers of ->readdir() and out of # ->readdir() instances. Bugs caught: # # dcache_readdir() updated atime only if it reached EOF. # # bfs_readdir() - ditto. # # qnx4_readdir() - ditto. # -------------------------------------------- # 04/03/12 akpm@osdl.org 1.1608.83.20 # [PATCH] adaptive lazy readahead # # From: Suparna Bhattacharya # # From: Ram Pai # # Pipelined readahead behaviour is suitable for sequential reads, but not for # large random reads (typical of database workloads), where lazy readahead # provides a big performance boost. # # One option (suggested by Andrew Morton) would be to have the application # pass hints to turn off readahead by setting the readahead window to zero # using posix_fadvise64(POSIX_FADV_RANDOM), and to special-case that in # do_generic_mapping_read to completely bypass the readahead logic and # instead read in all the pages needed directly. # # This was the idea I started with. But then I thought, we can do a still # better job ? How about adapting the readahead algorithm to lazy-read or # non-lazy-read based on the past i/o patterns ? # # The overall idea is to keep track of average number of contiguous pages # accessed in a file. If the average at any given time is above ra->pages # the pattern is sequential. If not the pattern is random. If pattern is # sequential do non-lazy-readahead( read as soon as the first page in the # active window is touched) else do lazy-readahead. # # I have studied the behaviour of this patch using my user-level simulator. # It adapts pretty well. # # Note from Suparna: This appears to bring streaming AIO read performance for # large (64KB) random AIO reads back to sane values (since the lazy readahead # backout in the mainline). # -------------------------------------------- # 04/03/12 akpm@osdl.org 1.1608.83.21 # [PATCH] read-only support for UFS2 # # From: Niraj Kumar # # This patch adds read-only support for ufs2 (used in FreeBSD 5.x) variant of # ufs filesystem. For filesystem specific tools, see # http://ufs-linux.sourceforge.com . # -------------------------------------------- # 04/03/12 akpm@osdl.org 1.1608.83.22 # [PATCH] fb_console_init fix # # From: James Simmons # # This patch fixes fb_console_init from being called twice. I still need to # fix set_con2fb but this helps but this is still important to get in. # -------------------------------------------- # 04/03/12 akpm@osdl.org 1.1608.83.23 # [PATCH] time interpolator fix # # From: john stultz # # In developing the ia64-cyclone patch, which implements a cyclone based time # interpolator, I found the following bug which could cause time # inconsistencies. # # In update_wall_time_one_tick(), which is called each timer interrupt, we # call time_interpolator_update(delta_nsec) where delta_nsec is approximately # NSEC_PER_SEC/HZ. This directly correlates with the changes to xtime which # occurs in update_wall_time_one_tick(). # # However in update_wall_time(), on a second overflow, we again call # time_interpolator_update(NSEC_PER_SEC). However while the components of # xtime are being changed, the overall value of xtime does not (nsec is # decremented NSEC_PER_SEC and sec is incremented). Thus this call to # time_interpolator_update is incorrect. # # This patch removes the incorrect call to time_interpolator_update and was # found to resolve the time inconsistencies I had seen while developing the # ia64-cyclone patch. # -------------------------------------------- # 04/03/12 akpm@osdl.org 1.1608.83.24 # [PATCH] teach /proc/kmsg about O_NONBLOCK # # If there's nothing available and the file is O_NONBLOCK, return -EAGAIN. # # This is a bit grubby - really we should push the file* down into do_syslog() # and handle it inside the spinlock. # -------------------------------------------- # 04/03/12 akpm@osdl.org 1.1608.83.25 # [PATCH] remove __io_virt_debug # # From: Brian Gerst # # Drivers should all be converted to use ioremap() or isa_*() by now. # -------------------------------------------- # 04/03/12 akpm@osdl.org 1.1608.83.26 # [PATCH] genrtc: cleanups # # From: "Randy.Dunlap" # # From: Luiz Fernando Capitulino # # remove ifdef/endif in rtc_generic_init(). # use returned error code; # -------------------------------------------- # 04/03/12 akpm@osdl.org 1.1608.83.27 # [PATCH] i386 very early memory detection cleanup patch # # From: "H. Peter Anvin" # # This patch cleans up the very early memory setup on the i386 platform. In # particular, it removes the hard-coded 8 MB limit completely by dynamically # creating the early-boot pagetables rather than having them hard coded. # # While I was at it, I changed head.S so that it always sets up a local GDT; # this means among other things that SMP and VISWS are no longer special # cases, and is conceptually cleaner to boot. The VISWS people have # confirmed it works on VISWS. # # It also uses a separate entrypoint for non-boot processors since this is # completely kernel-internal anyway. This eliminates the need to set %bx on # boot. (If you think this is a bad idea I can eliminate this change; it # just seemed cleaner to me to do it this way.) # # Additionally, zero bss with rep;stosl rather that rep;stosb. # -------------------------------------------- # 04/03/12 akpm@osdl.org 1.1608.83.28 # [PATCH] Allow X86_MCE_NONFATAL to be a module # # From: Herbert Xu # # By allowing X86_MCE_NONFATAL to be a module, it can be included in # distribution kernels without upsetting those with strange hardware. # -------------------------------------------- # 04/03/12 akpm@osdl.org 1.1608.83.29 # [PATCH] dm: endio method # # From: Joe Thornber # # Add an endio method to targets. This method is allowed to request another # shot at failed ios (think multipath). Context can be passed between the map # method and the endio method. # -------------------------------------------- # 04/03/12 akpm@osdl.org 1.1608.83.30 # [PATCH] dm: list_for_each_entry audit # # From: Joe Thornber # # Audit for list_for_each_*entry* # -------------------------------------------- # 04/03/12 akpm@osdl.org 1.1608.83.31 # [PATCH] dm: default queue limits # # From: Joe Thornber # # Fill in missing queue limitations when table is complete instead of enforcing # the "default" limits on every dm device. Problem noticed by Mike Christie. # # [Christophe Saout] # -------------------------------------------- # 04/03/12 akpm@osdl.org 1.1608.83.32 # [PATCH] dm: list targets cmd # # From: Joe Thornber # # List targets ioctl. [Patrick Caulfield] # -------------------------------------------- # 04/03/12 akpm@osdl.org 1.1608.83.33 # [PATCH] dm: stripe width fix # # dm-stripe.c: The stripe width must be at least the page size. # -------------------------------------------- # 04/03/12 akpm@osdl.org 1.1608.83.34 # [PATCH] selinux: clean up binary mount data # # From: James Morris # # selinux is currently inspecting the filesystem name ("nfs" vs "coda" vs # watever) to work out whether it needs to hanbdle binary mount data. # # Eliminate all that by adding a flag to file_system_type.fs_flags. # -------------------------------------------- # 04/03/12 akpm@osdl.org 1.1608.83.35 # [PATCH] UDF filesystem update # # From: Ben Fennema # # - added udf 2.5 #defines # # - fixed prealloc discard race # # - fixed several bugs in inode_getblk # # - added S_IFSOCK support # # - fix unicode encoding bug # # - change partition allocation from kmalloc to vmalloc for large # allocations # -------------------------------------------- # 04/03/12 akpm@osdl.org 1.1608.83.36 # [PATCH] kbuild: Remove CFLAGS assignment in i386/mach-*/Makefile # # From: Sam Ravnborg # # The EXTRA_CFLAGS assignments in the following files are a left-over from # the early 2.5 days where the source was not compiled from the root of the # source tree. # # Removing these wrong assignments fixes # http://bugme.osdl.org/show_bug.cgi?id=2210 # # A script named 'kernel' in the .. directory no longer halt compilation. # -------------------------------------------- # 04/03/12 akpm@osdl.org 1.1608.83.37 # [PATCH] NUMA-aware zonelist builder # # From: # # The attached patch is NUMA-aware zonelist builder patch, which sorts # zonelist in the order that near-node first, far-node last. In lse-tech and # linux-ia64, where most of NUMA people resides, no objections are raised so # far. # # The patch adds NUMA-specific version of build_zonelists which calls # find_next_best_node to select the next-nearest node to add to zonelist. # # The patch has no effect on flat NUMA platform. # -------------------------------------------- # 04/03/12 akpm@osdl.org 1.1608.83.38 # [PATCH] Redundant unplug_timer deletion # # From: "Chen, Kenneth W" # # The only path to get to del_timer call in __generic_unplug_device() is when # blk_remove_plug() returns 1, and in that case it already removed the # unplug_timer. # # Patch to remove this redundant call. # -------------------------------------------- # 04/03/12 akpm@osdl.org 1.1608.83.39 # [PATCH] compiler.h scoping fixes # # From: Ville Nuorvala # # There are a few kernel-only things in compiler.h which should have been # placed inside __KERNEL__. # -------------------------------------------- # 04/03/12 akpm@osdl.org 1.1608.83.40 # [PATCH] Fix elf mapping of the zero page # # From: William Lee Irwin III # # Using PAGE_SIZE rather than 4096 so that mmap() granularity is honored by # whatever non-i386 architectures use MMAP_PAGE_ZERO. # -------------------------------------------- # 04/03/12 akpm@osdl.org 1.1608.83.41 # [PATCH] kbuild: Cause `make clean' to remove more files # # From: Sam Ravnborg # # Make the difference between 'make clean' and 'make distclean/mrproper' more # explicit. # # make clean now removes all generated files except .config* and .version. # The result is much easier to understand now. # # make clean deletes all generated files (except .config* and .version). # make mrproper deletes configuration and all temporary files left by patch, # editors and the like. # # Example output: # > make mrproper # CLEAN init # CLEAN usr # CLEAN scripts/kconfig # CLEAN scripts # CLEAN .tmp_versions include/config # CLEAN include/asm-i386/asm_offsets.h include/linux/autoconf.h include/linux/version.h include/asm .tmp_versions # CLEAN .version .config # # Form the list of files/directories deleted during make clean, removed all # references that is no longer relevant for the current kernel. # -------------------------------------------- # 04/03/12 akpm@osdl.org 1.1608.83.42 # [PATCH] LOOP_CHANGE_FD ioctl # # From: Arjan van de Ven # # The patch below (written by Al Viro) solves a nasty chicken-and-egg issue # for operating system installers (well at least anaconda but the problem # domain is not exclusive to that) # # The basic problem is this: # # - The small first stage installer locates the image file of the second # stage installer (which has X and all the graphical stuff); this image can # be on the same CD, but it can come via NFS, http or ftp or ... as well. # # - The first stage installer loop-back mounts this image and gives control # to the second stage installer by calling some binary there. # # - The graphical installer then asks the user all those questions and # starts installing packages. Again the packages can come from the CD but # also from NFS or http or ... # # Now in case of a CD install, once all requested packages from the first CD # are installed, the installer wants to unmount and eject the CD and prompt # the user to put CD 2 in....... EXCEPT that the unmount can't work since # the installer is actually running from a loopback mount of this cd. # # The solution is a "LOOP_CHANGE_FD" ioctl, where basically the installer # copies the image to the harddisk (which can only be done late since only # late the target harddisk is mkfs'd) and then magically switches the backing # store FD from underneath the loop device to the one on the target harddisk # (and thus unbusying the CD mount). # # This is obviously only allowed if the size of the new image is identical # and if the loop image is read-only in the first place. It's the # responsibility of root to make sure the contents is the same (but that's of # the give-root-enough-rope kind) # -------------------------------------------- # 04/03/12 akpm@osdl.org 1.1608.83.43 # [PATCH] loop setup race fix # # From: Chris Mason # # There's a race in loopback setup, it's easiest to trigger with one or more # procs doing loopback mounts at the same time. The problem is that # fs/block_dev.c:do_open() only calls bdev_set_size on the first open. # Picture two procs: # # proc1: mount -o loop file1 mnt1 # proc2: mount -o loop file2 mnt2 # # proc1 proc2 # open /dev/loop0 # bd_openers now 1 # do_open # bd_set_size(bdev, 0) # loop unbound, so bdev size is 0 # open /dev/loop0 # bd_openers now 2 # loop_set_fd # disk capacity now correct, but # # bdev not updated # mount /dev/loop0 /mnt # do_open # # Because bd_openers != 0 for the last do_open, bd_set_size is not called # again and a size of 0 is used. This eventually leads to an oops when the # loop device is unmounted, because fsync_bdev calls block_write_full_page # who decides every page on the block device is outside i_size and unmaps # them. # # When ext2 or reiserfs try to sync a metadata buffer, we get an oops on # because the buffers are no longer mapped. # # The patch below changes loop_set_fd and loop_clr_fd to also manipulate the # size of the block device, which fixes things for me. # -------------------------------------------- # 04/03/12 akpm@osdl.org 1.1608.83.44 # [PATCH] kbuild: fix usage with directories containing '.o' # # From: Sam Ravnborg # # From: Daniel Mack , me # # modpost unconditionally searched for ".o" assuming this is always the # suffix of the module. This fails in two cases: # # a) when building external modules where any directory include ".o" in # the name. One example is a directory named: .../cvs.alsa.org/... # # b) when someone names a kernel directory so it contains ".o". One # example is drivers/scsi/aic.ok/... # # case b) was triggered by renaming the directory for aic7xxx, and modifying # Makefile and Kconfig. This caused make modules to fail. # -------------------------------------------- # 04/03/12 akpm@osdl.org 1.1608.83.45 # [PATCH] Remove unneeded unlock in ipc/sem.c # # From: Manfred Spraul # # sem_revalidate checks that a semaphore array didn't disappear while the # code was running without the semaphore array spinlock. If the array # disappeared, then it will return without holding a lock. find_undo calls # sem_revalidate and then sem_unlock, even if sem_revalidate failed. The # sem_unlock call must be removed. # # Mingming Cao reported a spinlock deadlock with sysv semaphores. A # superflous unlock doesn't explain the deadlock, but it's obviously a bug. # -------------------------------------------- # 04/03/12 akpm@osdl.org 1.1608.83.46 # [PATCH] /proc data corruption check # # From: Arjan van de Ven # # If someone removes a /proc directory which still has subdirectories it will # lead to very nasty things (dentries remaining on hash chains etc etc etc). # The BUG_ON in the patch below will catch this nasty situation. # -------------------------------------------- # 04/03/12 akpm@osdl.org 1.1608.83.47 # [PATCH] Enable i810 fb on x86-64 # # From: Andi Kleen # # i810fb most likely is needed on x86-64 too because there are Intel chipsets # for it now. So far it only linked on i386, fix this. # -------------------------------------------- # 04/03/12 akpm@osdl.org 1.1608.83.48 # [PATCH] Remove arbitrary #acl entries limits on ext[23] when reading # # From: Andreas Gruenbacher # # Remove the arbitrary limit of 32 ACL entries on ext[23] when reading from # disk. This change is backward compatible; we need to have this change in # to be able to also allow writing big ACLs. # # The second patch that removes the ACL entry limit for writes is not # included. I don't want to push that patch now, because large ACLs would # cause 2.4 and current 2.6 kernels to fail. My plan is to remove the second # limit later, in a half-year or year or so. # -------------------------------------------- # 04/03/12 akpm@osdl.org 1.1608.83.49 # [PATCH] watchdog: moduleparam-patches # # From: Wim Van Sebroeck # # Convert last set of watchdog drivers to new moduleparam system. # -------------------------------------------- # 04/03/12 akpm@osdl.org 1.1608.83.50 # [PATCH] AMD ELAN Kconfig fix # # From: Adrian Bunk # # - remove an MELAN entry that was forgotten in the i386 processor # selection menu # # - s/CONFIG_MELAN/CONFIG_X86_ELAN/ was missing in module.h # -------------------------------------------- # 04/03/12 akpm@osdl.org 1.1608.83.51 # [PATCH] fadvise(POSIX_FADV_DONTNEED) fixups # # From: WU Fengguang # # - In sys_fadvise64_64(): if the start and/or end offsets do not fall on # page boundaries, preserve the partial pages. The thinking here is that it # is better to preserve needed memory than to not shoot down unneeded memory. # # - In invalidate_mapping_pages(): we were invalidating an entire pagevec's # worth of pages each time around, even if that went beyond the part of the # file which the caller asked to be invalidated. Fix that up. # -------------------------------------------- # 04/03/12 akpm@osdl.org 1.1608.83.52 # [PATCH] Fix and harden validate_mm # # From: Andi Kleen # # I was debugging some code that corrupted the vma rb lists and for that I # fixed validate_mm to not be recursive and do some more checks. # # It's slower now, but that shouldn't be a problem. # # Also make it non static to allow easier checks elsewhere. # -------------------------------------------- # 04/03/12 akpm@osdl.org 1.1608.83.53 # [PATCH] current_is_keventd() speedup # # From: Srivatsa Vaddagiri # # current_is_keventd() doesn't need to search across all the CPUs to identify # itself. # -------------------------------------------- # 04/03/12 akpm@osdl.org 1.1608.83.54 # [PATCH] Fix rootfs on ramdisk # # From: vda # # Add a missing test for the "root=/dev/ram" kernel boot option. It's just an # alias for /dev/ram0, but it worked in 2.4... # -------------------------------------------- # 04/03/12 akpm@osdl.org 1.1608.83.55 # [PATCH] Fix reading the last block on a bdev # # From: Chris Mason # # This patch fixes a problem we're hitting on ia64 with page sizes > 4k. # # When the page size is greater than the block size, and parts of the page # fall past the end of the device, readpage will fail because # blkdev_get_block returns -EIO for blocks past i_size. # # The attached patch changes blkdev_get_block to return holes when reading # past the end of the device, which allows us to read that last valid 4k # block and then fill the rest of the page with zeros. Writes will still # fail with -EIO. # -------------------------------------------- # 04/03/12 akpm@osdl.org 1.1608.83.56 # [PATCH] wavfront.c needs syscalls.h # # sound/oss/wavfront.c: In function `wavefront_download_firmware': # sound/oss/wavfront.c:2524: warning: implicit declaration of function `sys_open' # sound/oss/wavfront.c:2533: warning: implicit declaration of function `sys_read' # sound/oss/wavfront.c:2582: warning: implicit declaration of function `sys_close # -------------------------------------------- # 04/03/12 akpm@osdl.org 1.1608.83.57 # [PATCH] EDD: Get Legacy Parameters # # From: Matt Domsch # # Patch below from Patrick J. LoPresti and myself. Patrick describes: # # Why this patch? The problem is that the legacy BIOS interface # (INT13/AH=3D08) for querying the disk geometry returns different values # than the extended INT13 interface which the EDD code currently uses. This # is because the legacy interface only provides a 10-bit cylinder field, so # modern BIOSes "lie" about the head/sector counts in order to make more of # the disk visible within the first 1024 cylinders. # # Many non-Linux applications, including the stock Windows boot loader, DOS # fdisk, etc., rely upon the legacy interface and geometry. So it is useful # to be able to obtain the legacy values from a running Linux kernel. # # What this patch does is to add new entries under # /sys/firmware/edd/int13_devXX named "legacy_cylinders", "legacy_heads", and # "legacy_sectors". These provide the geometry given by the legacy # INT13/AH=3D08 BIOS interface, just like the current "default_cylinders" # etc. provide the the geometry given by the INT13/AH=3D48 interface. # # Without this patch, I cannot use Linux to partition a drive and install # Windows, which happens to be my application. # # - Pat # http://unattended.sourceforge.net/ # # In addition, this adds two buggy BIOS workarounds in the EDD int13 # calls as suggested by Ralf Brown's interrupt list. # # I'm also interested in moving this code out of arch/i386/kernel/edd.c and # include/asm-i386/edd.h, as I believe it is applicable on x86-64 as well. # However, there's no good place under drivers/ to put edd.c when it's not # tied to a bus, but to several CPU architectures and their firmwares... # Maybe a new directory drivers/firmware? # -------------------------------------------- # 04/03/12 akpm@osdl.org 1.1608.83.58 # [PATCH] cciss: init section fix # # From: "Randy.Dunlap" # # cciss_scsi_detect() can be called after init (for TAPE support). # -------------------------------------------- # 04/03/12 akpm@osdl.org 1.1608.83.59 # [PATCH] add nowarn to a few pte chain allocators # # From: Arjan van de Ven # # Several of the pte_chain_alloc() allocators that use GFP_ATOMIC have a # fallback for failure that sleeps; they thus need to not warn on failure.. # Seen during a big fork on a busy system. # -------------------------------------------- # 04/03/12 akpm@osdl.org 1.1608.83.60 # [PATCH] Disable Macintosh device drivers for all but PPC || MAC # # From: Marc-Christian Petersen # # The attached patch is needed to stop showing us "Macintosh device drivers" # for all architectures via menuconfig || xconfig || gconfig. It's only # necessary for PPC and/or MAC. # # ACKed by benh. # -------------------------------------------- # 04/03/12 akpm@osdl.org 1.1608.83.61 # [PATCH] Applicom warning # # From: Geert Uytterhoeven # # Add missing include (needed for struct inode) # -------------------------------------------- # 04/03/12 akpm@osdl.org 1.1608.83.62 # [PATCH] Fix CONFIG_NVRAM dependencies # # From: Geert Uytterhoeven # # Make CONFIG_NVRAM depend on the prerequisites that are explicitly checked # for in drivers/char/nvram.c, or on CONFIG_GENERIC_NVRAM (for PPC). # -------------------------------------------- # 04/03/12 akpm@osdl.org 1.1608.83.63 # [PATCH] module.h __attribute_used__ fix # # From: Rusty Russell # # Someone added __attribute_used__ throughout module.h, but didn't remove the # ", unused". Looks like some arch/gcc combos still consider it unused, and # discard the fn. # -------------------------------------------- # 04/03/12 akpm@osdl.org 1.1608.83.64 # [PATCH] fix raid0 readahead size # # From: Arjan van de Ven # # Readahead of raid0 was suboptimal; it read only 1 stride ahead. The # problem with this is that while it will keep all spindles busy, it will not # actually manage to make larger IO's, eg each disk would just do the chunk # size IO. Doing at least 2 chunks is more than appropriate so that each # spindle will get a chance to merge IO's. # # (Neil fixed raid6 and raid6 too) # -------------------------------------------- # 04/03/12 akpm@osdl.org 1.1608.83.65 # [PATCH] Fix NULL pointer dereference in blkmtd.c # # From: Michel Marti # # The blkmtd driver oopses in add_device(). The following trivial patch # fixes this. # -------------------------------------------- # 04/03/12 akpm@osdl.org 1.1608.83.66 # [PATCH] fbdev: monitor detection fixes # # From: James Simmons , # Kronos # # Various fixes and enhancements to the monitor hardware detection code. The # only driver that uses it is the radeon driver. # # Old EDID parsing code was very verbose, half of the patch address this (ie. # print lots of stuff iff DEBUG). The other big change is the FB_MODE_IS_* # stuff: we really need a way to know the origin of a video mode. In this way # we can select video mode that comes from EDID instead of VESA or GTF. # # Drivers other than radeonfb won't be affected because they cannot (yet) get # EDID from the monitor and don't use EDID related code. # -------------------------------------------- # 04/03/12 akpm@osdl.org 1.1608.83.67 # [PATCH] m68k: __test_and_set_bit() # # From: Geert Uytterhoeven # # Add missing implementation for non-atomic __test_and_set_bit() # -------------------------------------------- # 04/03/12 akpm@osdl.org 1.1608.83.68 # [PATCH] m68k: Amiga Framemaster II fb sysfsification # # From: Geert Uytterhoeven # # Amiga Framemaster II fb: Add sysfs support (from James Simmons) # -------------------------------------------- # 04/03/12 akpm@osdl.org 1.1608.83.69 # [PATCH] Apollo fb sysfsification # # From: Geert Uytterhoeven # # Apollo fb: Add sysfs support (from James Simmons) # -------------------------------------------- # 04/03/12 akpm@osdl.org 1.1608.83.70 # [PATCH] m68k: Macintosh IDE fixes # # From: Geert Uytterhoeven # # Mac IDE: Make sure the core IDE driver doesn't try to request the MMIO # ports a second time, since this will fail. # -------------------------------------------- # 04/03/12 akpm@osdl.org 1.1608.83.71 # [PATCH] m68k: interrupt management cleanups # # From: Geert Uytterhoeven # # M68k interrupt management: rename routines to not confuse them with # syscalls # # - sys_{request,free}_irq() -> cpu_{request,free}_irq() # # - q40_sys_default_handler[] -> q40_default_handler # # - sys_default_handler() -> default_handler() # -------------------------------------------- # 04/03/12 akpm@osdl.org 1.1608.83.72 # [PATCH] Add barriers to avoid race in mempool_alloc/free # # From: Chris Mason # # mempool_alloc() and mempool_free() check pool->curr_nr without any locks # held. This can lead to skipping a wakeup when there are people waiting, # and sleeping when there are free elements in the pool. # # I can't trigger this reliably, but sooner or later someone on ppc is # probably going to hit it. # -------------------------------------------- # 04/03/12 akpm@osdl.org 1.1608.83.73 # [PATCH] synclinkmp.c update # # From: Paul Fulghum # # Patch for synclinkmp.c # # * Track driver API changes # * Remove cast (kernel janitor) # * Replace page_free call with kfree (to match kmalloc allocation) # -------------------------------------------- # 04/03/12 akpm@osdl.org 1.1608.83.74 # [PATCH] synclink_cs.c update # # From: Paul Fulghum # # * Track driver API changes # * Remove cast (kernel janitor) # -------------------------------------------- # 04/03/12 akpm@osdl.org 1.1608.83.75 # [PATCH] synclink.c update # # From: Paul Fulghum # # * track driver API changes # * remove cast (kernel janitor) # -------------------------------------------- # 04/03/12 akpm@osdl.org 1.1608.83.76 # [PATCH] vm: per-zone vmscan instrumentation # # To check on zone balancing, split the /proc/vmstat:pgsteal, pgreclaim pgalloc # and pgscan stats into per-zone counters. # # Additionally, split the pgscan stats into pgscan_direct and pgscan_kswapd to # see who's doing how much scanning. # # And add a metric for the number of slab objects which were scanned. # -------------------------------------------- # 04/03/12 akpm@osdl.org 1.1608.83.77 # [PATCH] return remaining jiffies from blk_congestion_wait() # # Teach blk_congestion_wait() to return the number of jiffies remaining. This # is for debug, but it is also nicely consistent. # -------------------------------------------- # 04/03/12 akpm@osdl.org 1.1608.83.78 # [PATCH] Narrow blk_congestion_wait races # # From: Nick Piggin # # The addition of the smp_mb and the other change is to try to close the # window for races a bit. Obviously they can still happen, it's a racy # interface and it doesn't matter much. # -------------------------------------------- # 04/03/12 akpm@osdl.org 1.1608.83.79 # [PATCH] mm/vmscan.c: remove unused priority argument. # # From: Nikita Danilov # # Now that decision to reclaim mapped memory is taken on the basis of # zone->prev_priority, priority argument is no longer needed. # -------------------------------------------- # 04/03/12 akpm@osdl.org 1.1608.83.80 # [PATCH] kswapd throttling fixes # # The logic in balance_pgdat() is all bollixed up. # # - the incoming arg `nr_pages' should be used to determine if we're being # asked to free a specific number of pages, not `to_free'. # # - local variable `to_free' is not appropriate for the determination of # whether we failed to bring all zones to appropriate free pages levels. # # Fix this by correctly calculating `all_zones_ok' and then use # all_zones_ok to determine whether we need to throttle kswapd. # # So the logic now is: # # # for (increasing priority) { # # all_zones_ok = 1; # # for (all zones) { # to_reclaim = number of pages to try to reclaim # from this zone; # max_scan = number of pages to scan in this pass # (gets larger as `priority' decreases) # /* # * set `reclaimed' to the number of pages which were # * actually freed up # */ # reclaimed = scan(max_scan pages); # reclaimed += shrink_slab(); # # to_free -= reclaimed; /* for the `nr_pages>0' case */ # # /* # * If this scan failed to reclaim `to_reclaim' or more # * pages, we're getting into trouble. Need to scan # * some more, and throttle kswapd. Note that this # * zone may now have sufficient free pages due to # * freeing activity by some other process. That's # * OK - we'll pick that info up on the next pass # * through the loop. # */ # if (reclaimed < to_reclaim) # all_zones_ok = 0; # } # if (to_free > 0) # continue; /* swsusp: need to do more work */ # if (all_zones_ok) # break; /* kswapd is done */ # /* # * OK, kswapd is getting into trouble. Take a nap, then take # * another pass across the zones. # */ # blk_congestion_wait(); # } # -------------------------------------------- # 04/03/12 akpm@osdl.org 1.1608.83.81 # [PATCH] vmscan: preserve page referenced info in refill_inactive() # # From: Nick Piggin # # If refill_inactive_zone() is running in its dont-reclaim-mapped-memory mode # we are tossing away the referenced infomation on active mapped pages. # # So put that info back if we're not going to deactivate the page. # -------------------------------------------- # 04/03/12 akpm@osdl.org 1.1608.83.82 # [PATCH] shrink_slab: math precision fix # # From: Nick Piggin # # In shrink_slab(), do the multiply before the divide to avoid losing # precision. # -------------------------------------------- # 04/03/12 akpm@osdl.org 1.1608.83.83 # [PATCH] vm: shrink slab evenly in try_to_free_pages() # # From: Nick Piggin # # In try_to_free_pages(), put even pressure on the slab even if we have # reclaimed enough pages from the LRU. # -------------------------------------------- # 04/03/12 akpm@osdl.org 1.1608.83.84 # [PATCH] vmscan: fix calculation of number of pages scanned # # From: Nick Piggin # # The logic which calculates the numberof pages which were scanned is mucked # up. Fix. # -------------------------------------------- # 04/03/12 akpm@osdl.org 1.1608.83.85 # [PATCH] vm: scan slab in response to highmem scanning # # The patch which went in six months or so back which said "only reclaim slab # if we're scanning lowmem pagecache" was wrong. I must have been asleep at # the time. # # We do need to scan slab in response to highmem page reclaim as well. Because # all the math is based around the total amount of memory in the machine, and # we know that if we're performing highmem page reclaim then the lower zones # have no free memory. # -------------------------------------------- # 04/03/12 akpm@osdl.org 1.1608.83.86 # [PATCH] vmscan: zone balancing fix # # We currently have a problem with the balancing of reclaim between zones: much # more reclaim happens against highmem than against lowmem. # # This patch partially fixes this by changing the direct reclaim path so it # does not bale out of the zone walk after having reclaimed sufficient pages # from highmem: go on to reclaim from lowmem regardless of how many pages we # reclaimed from lowmem. # -------------------------------------------- # 04/03/12 akpm@osdl.org 1.1608.83.87 # [PATCH] vmscan: drive everything via nr_to_scan # # Page reclaim is currently a bit schitzo: sometimes we say "go and scan this # many pages and tell me how many pages were freed" and at other times we say # "go and scan this many pages, but stop if you freed this many". # # It makes the logic harder to control and to understand. This patch coverts # everything into the "go and scan this many pages and tell me how many pages # were freed" model. # # It doesn't seem to affect performance much either way. # -------------------------------------------- # 04/03/12 akpm@osdl.org 1.1608.83.88 # [PATCH] Balance inter-zone scan rates # # When page reclaim is working out how many pages to san in a zone (max-scan) # it presently rounds that number up if it looks too small - for work batching. # # Problem is, this can result in excessive scanning against small zones which # have few inactive pages. So remove it. # # Not that it is possible for max_scan to be zero. That's OK - it'll become # non-zero as the priority increases. # -------------------------------------------- # 04/03/12 akpm@osdl.org 1.1608.83.89 # [PATCH] vmscan: avoid bogus throttling # # - If max_scan evaluates to zero due to a very small inactive list and high # `priority' numbers, we don't want to thrlttle yet. # # - In balance_pgdat(), we may end up not scanning any pages because all # zones happened to be above pages_high. Avoid throttling in this case too. # -------------------------------------------- # 04/03/12 akpm@osdl.org 1.1608.83.90 # [PATCH] kswapd: avoid unnecessary reclaiming from higher zones # # Currently kswapd walks across all zones in dma->normal->highmem order, # performing proportional scanning until all zones are OK. This means that # pressure against ZONE_NORMAL causes unnecessary reclaim of ZONE_HIGHMEM. # # To fix that up we change kswapd so that it walks the zones in the # high->normal->dma direction, skipping zones which are OK. Once it encounters # a zone which needs some reclaim kswapd will perform proportional scanning # against that zone as well as all the succeeding lower zones. # # We scan the lower zones even if they have sufficient free pages. This is # because # # a) the lower zone may be above pages_high, but because of the incremental # min, the lower zone may still not be eligible for allocations. That's bad # because cache in that lower zone will then not be scanned at the correct # rate. # # b) pages in this lower zone are usable for allocations against the higher # zone. So we do want to san all the relevant zones at an equal rate. # -------------------------------------------- # 04/03/12 akpm@osdl.org 1.1608.83.91 # [PATCH] kswapd: fix lumpy page reclaim # # As kswapd is now scanning zones in the highmem->normal->dma direction it can # get into competition with the page allocator: kswapd keep on trying to free # pages from highmem, then kswapd moves onto lowmem. By the time kswapd has # done proportional scanning in lowmem, someone has come in and allocated a few # pages from highmem. So kswapd goes back and frees some highmem, then some # lowmem again. But nobody has allocated any lowmem yet. So we keep on and on # scanning lowmem in response to highmem page allocations. # # With a simple `dd' on a 1G box we get: # # r b swpd free buff cache si so bi bo in cs us sy wa id # 0 3 0 59340 4628 922348 0 0 4 28188 1072 808 0 10 46 44 # 0 3 0 29932 4660 951760 0 0 0 30752 1078 441 1 6 30 64 # 0 3 0 57568 4556 924052 0 0 0 30748 1075 478 0 8 43 49 # 0 3 0 29664 4584 952176 0 0 0 30752 1075 472 0 6 34 60 # 0 3 0 5304 4620 976280 0 0 4 40484 1073 456 1 7 52 41 # 0 3 0 104856 4508 877112 0 0 0 18452 1074 97 0 7 67 26 # 0 3 0 70768 4540 911488 0 0 0 35876 1078 746 0 7 34 59 # 1 2 0 42544 4568 939680 0 0 0 21524 1073 556 0 5 43 51 # 0 3 0 5520 4608 976428 0 0 4 37924 1076 836 0 7 41 51 # 0 2 0 4848 4632 976812 0 0 32 12308 1092 94 0 1 33 66 # # Simple fix: go back to scanning the zones in the dma->normal->highmem # direction so we meet the page allocator in the middle somewhere. # # r b swpd free buff cache si so bi bo in cs us sy wa id # 1 3 0 5152 3468 976548 0 0 4 37924 1071 650 0 8 64 28 # 1 2 0 4888 3496 976588 0 0 0 23576 1075 726 0 6 66 27 # 0 3 0 5336 3532 976348 0 0 0 31264 1072 708 0 8 60 32 # 0 3 0 6168 3560 975504 0 0 0 40992 1072 683 0 6 63 31 # 0 3 0 4560 3580 976844 0 0 0 18448 1073 233 0 4 59 37 # 0 3 0 5840 3624 975712 0 0 4 26660 1072 800 1 8 46 45 # 0 3 0 4816 3648 976640 0 0 0 40992 1073 526 0 6 47 47 # 0 3 0 5456 3672 976072 0 0 0 19984 1070 320 0 5 60 35 # -------------------------------------------- # 04/03/12 akpm@osdl.org 1.1608.83.92 # [PATCH] fix the kswapd zone scanning algorithm # # This removes a vestige of the old algorithm. We don't want to skip zones if # all_zones_ok is true: we've already precalculated which zones need scanning # and this just stops us from ever performing kswapd reclaim from the DMA zone. # -------------------------------------------- # 04/03/12 akpm@osdl.org 1.1608.83.93 # [PATCH] vmscan: less throttling of page allocators and kswapd # # This is just a random unsubstantiated tuning tweak: don't immediately # throttle page allocators and kwapd when the going is getting heavier: scan a # bit more of the LRU before throttling. # -------------------------------------------- # 04/03/12 akpm@osdl.org 1.1608.83.94 # [PATCH] vmscan: batch up inactive list scanning work # # From: Nick Piggin # # Use a "refill_counter" for inactive list scanning, similar to the one used # for active list scanning. This batches up scanning now that we precisely # balance ratios, and don't round up the amount to be done. # # No observed benefits, but I imagine it would lower the acquisition # frequency of the lru locks in some cases, and make codepaths more efficient # in general due to cache niceness. # -------------------------------------------- # 04/03/12 akpm@osdl.org 1.1608.83.95 # [PATCH] fix vm-batch-inactive-scanning.patch # # - prevent nr_scan_inactive from going negative # # - compare `count' with SWAP_CLUSTER_MAX, not `max_scan' # # - Use ">= SWAP_CLUSTER_MAX", not "> SWAP_CLUSTER_MAX". # -------------------------------------------- # 04/03/12 akpm@osdl.org 1.1608.83.96 # [PATCH] vm: balance inactive zone refill rates # # The current refill logic in refill_inactive_zone() takes an arbitrarily large # number of pages and chops it down to SWAP_CLUSTER_MAX*4, regardless of the # size of the zone. # # This has the effect of reducing the amount of refilling of large zones # proportionately much more than of small zones. # # We made this change in may 2003 and I'm damned if I remember why. let's put # it back so we don't truncate the refill count and see what happens. # -------------------------------------------- # 04/03/12 akpm@osdl.org 1.1608.83.97 # [PATCH] vmscan: add lru_to_page() helper # # From: Nick Piggin # # Add a little helper macro for a common list extraction operation in vmscan.c # -------------------------------------------- # 04/03/12 akpm@osdl.org 1.1608.83.98 # [PATCH] slab: avoid higher-order allocations # # From: Manfred Spraul # # At present slab is using 2-order allocations for the size-2048 cache. Of # course, this can affect networking quite seriously. # # The patch ensures that slab will never use more than a 1-order allocation # for objects which have a size of less than 2*PAGE_SIZE. # -------------------------------------------- # 04/03/12 torvalds@ppc970.osdl.org 1.1608.83.99 # Revert attribute_used changes in module.h. They were wrong. # # Cset exclude: akpm@osdl.org|ChangeSet|20040312161945|47751 # -------------------------------------------- # 04/03/12 torvalds@ppc970.osdl.org 1.1608.81.40 # Merge http://lia64.bkbits.net/to-linus-2.5 # into ppc970.osdl.org:/home/torvalds/v2.5/linux # -------------------------------------------- # 04/03/12 torvalds@ppc970.osdl.org 1.1608.81.41 # Merge bk://linux-scsi.bkbits.net/scsi-for-linus-2.6 # into ppc970.osdl.org:/home/torvalds/v2.5/linux # -------------------------------------------- # 04/03/12 jgarzik@redhat.com 1.1608.86.1 # [wireless] Add new Prism54 wireless driver. # -------------------------------------------- # 04/03/12 jgarzik@redhat.com 1.1608.86.2 # [wireless prism54] remove WIRELESS_EXT ifdefs # -------------------------------------------- # 04/03/12 trivial@rustcorp.com.au 1.1608.81.42 # [PATCH] drivers_net_wireless_airo.c '< 0' comparison make sense # # From: # # The sense of the comparison was signed, but the code was testing # an unsigned variable for less-than-zero. # -------------------------------------------- # 04/03/12 manfred@colorfullife.com 1.1608.81.43 # [PATCH] forcedeth update # # Andrew de Quincey added wol support to forcedeth. # The patch also renames additional function, to help analyzing backtraces. # -------------------------------------------- # 04/03/12 rddunlap@osdl.org 1.1608.81.44 # [PATCH] eepro init section usage # # eepro_print_info() can be __init. # -------------------------------------------- # 04/03/12 rddunlap@osdl.org 1.1608.81.45 # [PATCH] smctr: fix init section usage # # smctr_chk_mca() can be __init. # -------------------------------------------- # 04/03/12 brazilnut@us.ibm.com 1.1608.81.46 # [PATCH] pcnet32 correct names for changes # # This patch corrects the names of contributors of changes to the pcnet32 # driver. # -------------------------------------------- # 04/03/12 brazilnut@us.ibm.com 1.1608.81.47 # [PATCH] netdevice.h add netif_msg_init helper # # This patch adds a helper function to initialize the debug bit mask # for use with netif_msg_*. When the debug_value is out of range # it returns the default_msg_enable_bits. Tested IA32. # -------------------------------------------- # 04/03/12 arjanv@redhat.com 1.1608.81.48 # [PATCH] xirc2ps ethtool fix # # patch below adds bus_info for xirc2ps_cs; anaconda depends on this info to # be there. # -------------------------------------------- # 04/03/12 torvalds@ppc970.osdl.org 1.1608.87.1 # Merge bk://gkernel.bkbits.net/prism54-2.5 # into ppc970.osdl.org:/home/torvalds/v2.5/linux # -------------------------------------------- # 04/03/12 rddunlap@osdl.org 1.1608.81.49 # [PATCH] use netdev_priv() in appletalk & fc # -------------------------------------------- # 04/03/12 rddunlap@osdl.org 1.1608.81.50 # [PATCH] use netdev_priv() in /hamradio/ # -------------------------------------------- # 04/03/12 rddunlap@osdl.org 1.1608.81.51 # [PATCH] use netdev_priv() in 3com net drivers # -------------------------------------------- # 04/03/12 rddunlap@osdl.org 1.1608.81.52 # [PATCH] use netdev_priv() in net/ lance drivers # -------------------------------------------- # 04/03/12 rddunlap@osdl.org 1.1608.81.53 # [PATCH] use netdev_priv() in net/arm drivers # -------------------------------------------- # 04/03/12 rddunlap@osdl.org 1.1608.81.54 # [PATCH] use netdev_priv() in net/ intel drivers # -------------------------------------------- # 04/03/12 rddunlap@osdl.org 1.1608.81.55 # [PATCH] use netdev_priv() in net/pcmcia/ drivers # -------------------------------------------- # 04/03/12 rddunlap@osdl.org 1.1608.81.56 # [PATCH] use netdev_priv() in net/tulip drivers # -------------------------------------------- # 04/03/12 rddunlap@osdl.org 1.1608.81.57 # [PATCH] use netdev_priv() in net/tokenring/ drivers # -------------------------------------------- # 04/03/12 rddunlap@osdl.org 1.1608.81.58 # [PATCH] use netdev_priv() in net/wireless/ drivers # -------------------------------------------- # 04/03/12 rddunlap@osdl.org 1.1608.81.59 # [PATCH] use netdev_priv() in tap/tun/plip/loop/skel # -------------------------------------------- # 04/03/12 rddunlap@osdl.org 1.1608.81.60 # [PATCH] use netdev_priv() in fusion/mptlan # -------------------------------------------- # 04/03/12 rddunlap@osdl.org 1.1608.81.61 # [PATCH] use netdev_priv() in net/wan drivers # -------------------------------------------- # 04/03/12 rddunlap@osdl.org 1.1608.81.62 # [PATCH] use netdev_priv() in drivers/net/ (others) # -------------------------------------------- # 04/03/12 rene.herman@keyaccess.nl 1.1608.81.63 # [PATCH] 8139too assertions # -------------------------------------------- # 04/03/12 jgarzik@redhat.com 1.1608.87.2 # Add Promise SX8 (carmel) block driver. # -------------------------------------------- # 04/03/12 jgarzik@redhat.com 1.1608.55.33 # Merge redhat.com:/spare/repo/linux-2.5 # into redhat.com:/spare/repo/libata-2.5 # -------------------------------------------- # 04/03/12 jgarzik@redhat.com 1.1612 # Merge redhat.com:/spare/repo/netdev-2.6/netpoll # into redhat.com:/spare/repo/netconsole-2.5 # -------------------------------------------- # 04/03/12 jgarzik@redhat.com 1.1608.81.64 # Merge kernel.bkbits.net:net-drivers-2.5 # into redhat.com:/spare/repo/net-drivers-2.5 # -------------------------------------------- # 04/03/12 torvalds@ppc970.osdl.org 1.1613 # Merge bk://kernel.bkbits.net/jgarzik/netconsole-2.5 # into ppc970.osdl.org:/home/torvalds/v2.5/linux # -------------------------------------------- # 04/03/12 torvalds@ppc970.osdl.org 1.1614 # Merge bk://gkernel.bkbits.net/libata-2.5 # into ppc970.osdl.org:/home/torvalds/v2.5/linux # -------------------------------------------- # 04/03/12 jejb@mulgrave.(none) 1.1615 # MPT Fusion driver 3.01.01 update # # From: Moore, Eric Dean # # This is an update for the MPT Fusion drivers 2.6 kernel. # Version 3.01.01. # # This is a fix for poor performance in RAID Volumes. # The dvStatus was being cleared for hidden physical disks # when mptscsih_slave_destroy is called. # # Also, I have fixed the warning comming from mptscsih_reset_timeouts. # -------------------------------------------- # 04/03/12 markh@osdl.org 1.1616 # [PATCH] aacraid driver patch # # I submitted a patch last month for the aacraid driver's reset handler. # I left out setting function pointers in the adapter_ops structure for # the adapter_check_health element. # -------------------------------------------- # 04/03/12 willy@debian.org 1.1617 # [PATCH] sym2 2.1.18i # # - Correct a typo "mvram" -> "nvram". # - Re-do the PQS/PDS support which I'd #if 0 out. Should even work on # multiple-domain boxes now ;-) # - Move all the nvram definitions to sym_nvram.h (from Gerard's 2.1.19-pre3) # - hcb_p -> struct sym_hcb * # - sdev_p -> struct sym_device * # - Delete a lot of unused macros from sym_misc.h # - Move READ_BARRIER and WRITE_BARRIER definitions to sym_glue.h # - SYM_CONF_NVRAM_WRITE_SUPPORT (from Gerard's 2.1.19-pre3). Not enabled # yet. # - Fix some -W warnings (some courtesy of Adrian Bunk). # -------------------------------------------- # 04/03/12 markh@osdl.org 1.1618 # [PATCH] add adapter support to aacraid driver (update) # # Mark S. said that there was another adapter added, and that they changed # the names of some boards. Here is the updated version. # -------------------------------------------- # 04/03/12 James.Bottomley@steeleye.com 1.1619 # [PATCH] add device quiescing to the SCSI API # # This patch adds the ability to quiesce a SCSI device. The idea is that # user issued commands (including filesystem ones) would get blocked, # while mid-layer and device issued ones would be allowed to proceed. # This is for things like Domain Validation which like to operate on an # otherwise quiet device. # # There is one big change: to get all of this to happen correctly, # scsi_do_req() has to queue on the *head* of the request queue, not the # tail as it was doing previously. The reason is that deferred requests # block the queue, so anything needing executing after a deferred request # has to go in front of it. I don't think there are any untoward # consequences of this. # -------------------------------------------- # 04/03/12 James.Bottomley@steeleye.com 1.1620 # [PATCH] more SPI transport attribute updates # # This does three things # # - Fix the signedness of the bit attributes (otherwise they show up as -1 # when on, not 1) # - Make the period adjust to the closest value rather than ignoring # values it doesn't understand. # - Add a visibility field to attributes, so drivers can get rid of # attributes they're never going to care about # -------------------------------------------- # 04/03/12 James.Bottomley@steeleye.com 1.1621 # [PATCH] update the 53c700 use of transport attributes # # This patch just brings it up to date with the previous transport # attribute patch, moving it to the model where it sets the min/max of the # attribute if asked for something outside its range. It also only makes # period and offset visible (it doesn't care about any of the others). # -------------------------------------------- # 04/03/12 scott.feldman@intel.com 1.1608.81.65 # [netdrvr e100] fix stray skb pointer # # * Not setting cb->skb = NULL after releasing skb to OS or during # initialization of cbs. Reported by Deepak Saxena # [dsaxena@plexity.net]. # -------------------------------------------- # 04/03/13 len.brown@intel.com 1.1608.1.41 # [ACPI] SMP poweroff (David Shaohua Li) # http://bugzilla.kernel.org/show_bug.cgi?id=1141 # -------------------------------------------- # 04/03/13 len.brown@intel.com 1.1608.1.42 # [ACPI] ACPICA 20040311 from Bob Moore # # Fixed a problem where errors occurring during the parse phase of control # method execution did not abort cleanly. For example, objects created # and installed in the namespace were not deleted. This caused all # subsequent invocations of the method to return the AE_ALREADY_EXISTS # exception. # # Implemented a mechanism to force a control method to "Serialized" # execution if the method attempts to create namespace objects. # (The root of the AE_ALREADY_EXISTS problem.) # # Implemented support for the predefined _OSI "internal" control method. # Initial supported strings are "Linux", "Windows 2000", "Windows 2001", # and "Windows 2001.1", and can be easily upgraded for new strings as # necessary. This feature allows Linux to execute # the fully tested, "Windows" code path through the ASL code # # Global Lock Support: Now allows multiple acquires and releases with any # internal thread. Removed concept of "owning thread" for this special # mutex. # # Fixed two functions that were inappropriately declaring large objects on # the CPU stack: ps_parse_loop() and ns_evaluate_relative(). # Reduces the stack usage during method execution considerably. # # Fixed a problem in the ACPI 2.0 FACS descriptor (actbl2.h) where the # S4Bios_f field was incorrectly defined as UINT32 instead of UINT32_BIT. # # Fixed a problem where acpi_ev_gpe_detect() would fault # if there were no GPEs defined on the machine. # # Implemented two runtime options: One to force all control method # execution to "Serialized" to mimic Windows behavior, another to disable # _OSI support if it causes problems on a given machine. # -------------------------------------------- # 04/03/13 jgarzik@redhat.com 1.1614.1.1 # [blk carmel] fix bug, minor cleanups # # * the scan-channels message seemed to always give invalid output. # Look at the constant, and discover we are sending another # message entirely. Fix the constant (CARM_MSG_IOCTL). # # * s/MISC_SYNC_TIME/MISC_SET_TIME/ # # * list some additional messages # # * bump version number # -------------------------------------------- # 04/03/13 len.brown@intel.com 1.1614.2.1 # Merge intel.com:/home/lenb/bk/linux-2.6.5 # into intel.com:/home/lenb/src/linux-acpi-test-2.6.5 # -------------------------------------------- # 04/03/13 len.brown@intel.com 1.1614.2.2 # Merge intel.com:/home/lenb/src/linux-acpi-test-2.6.4 # into intel.com:/home/lenb/src/linux-acpi-test-2.6.5 # -------------------------------------------- # 04/03/13 len.brown@intel.com 1.1608.1.43 # [ACPI] add boot parameters "acpi_osi=" and "acpi_serialize" # acpi_osi= will disable the _OSI method -- which by default # tells the BIOS to behave as if Windows is the OS. # acpi_serialize is for debugging AE_ALREADY_EXISTS failures # -------------------------------------------- # 04/03/13 len.brown@intel.com 1.1614.2.3 # Merge intel.com:/home/lenb/src/linux-acpi-test-2.6.4 # into intel.com:/home/lenb/src/linux-acpi-test-2.6.5 # -------------------------------------------- # 04/03/13 jgarzik@redhat.com 1.1614.3.1 # Merge redhat.com:/spare/repo/linux-2.5 # into redhat.com:/spare/repo/net-drivers-2.5 # -------------------------------------------- # 04/03/13 James.Bottomley@steeleye.com 1.1622 # [PATCH] Add Domain Validation to the SPI transport class # # Domain Validation is a fairly essential element to the SCSI Parallel # Interface (although if you look very few drivers actually do it). The # premise is that the Parallel Bus, being a transmission line, might not # be correctly tuned to the transfers you want do perform. DV probes the # parameters of the transport until it finds a setting that works (for the # interested, see http://www.t10.org/ftp/t10/drafts/sdv/sdv-r08b.pdf) # # The current code employs rather simplistic DV heuristics, although those # can be improved over time. The change in scsi_scan.c is so that DV may # be done easily from the slave_configure routine, which is the most # natural place to begin. # -------------------------------------------- # 04/03/13 torvalds@ppc970.osdl.org 1.1614.1.2 # Merge bk://gkernel.bkbits.net/net-drivers-2.5 # into ppc970.osdl.org:/home/torvalds/v2.5/linux # -------------------------------------------- # 04/03/13 perex@suse.cz 1.1614.4.1 # Merge suse.cz:/home/perex/bk/linux-sound/linux-2.5 # into suse.cz:/home/perex/bk/linux-sound/linux-sound # -------------------------------------------- # 04/03/13 perex@suse.cz 1.1614.4.2 # ALSA CVS update - Clemens Ladisch # ALSA sequencer # remove superfluous call to snd_seq_event_port_detach # -------------------------------------------- # 04/03/13 perex@suse.cz 1.1614.4.3 # ALSA CVS update - Clemens Ladisch # ALSA sequencer,ALSA<-OSS sequencer # use wrapper function for DELETE_PORT ioctl calls # -------------------------------------------- # 04/03/13 perex@suse.cz 1.1614.4.4 # ALSA CVS update - Clemens Ladisch # USB generic driver # use MIN_PACKS_URB as lower bound for nrpacks parameter # -------------------------------------------- # 04/03/13 perex@suse.cz 1.1614.4.5 # ALSA CVS update - Clemens Ladisch # USB generic driver # show one decimal place of momentary frequency in proc file # -------------------------------------------- # 04/03/13 perex@suse.cz 1.1614.4.6 # ALSA CVS update - Clemens Ladisch # USB generic driver # prevent twenty-seconds wait when unplugging USB MIDI device with a port subscription # -------------------------------------------- # 04/03/13 perex@suse.cz 1.1614.4.7 # ALSA CVS update - Takashi Iwai # VIA82xx driver # restrict the PCM sample rates to 32, 44.1 and 48kHz when the SPDIF # switch is on. # -------------------------------------------- # 04/03/13 perex@suse.cz 1.1614.4.8 # ALSA CVS update - Jaroslav Kysela # DT019x driver # Fixed warnings # -------------------------------------------- # 04/03/13 perex@suse.cz 1.1614.4.9 # ALSA CVS update - Takashi Iwai # VIA82xx driver # patch was applied wrongly. fixed the rate restriction of spdif output # again. # -------------------------------------------- # 04/03/13 perex@suse.cz 1.1614.4.10 # ALSA CVS update - Takashi Iwai # Documentation,PCI drivers,au88x0 driver # added the au88x0 drivers for Aureal soundcards by Manuel Jander # -------------------------------------------- # 04/03/13 perex@suse.cz 1.1614.4.11 # ALSA CVS update - Takashi Iwai # PPC Tumbler driver # added input source switch to select mic/line-in. # -------------------------------------------- # 04/03/13 perex@suse.cz 1.1614.4.12 # ALSA CVS update - Takashi Iwai # Documentation # changed the description of the buffer allocation routines # for the new designed functions. # -------------------------------------------- # 04/03/13 perex@suse.cz 1.1614.4.13 # ALSA CVS update - Takashi Iwai # Documentation # fixed the files to include. # -------------------------------------------- # 04/03/13 perex@suse.cz 1.1614.4.14 # ALSA CVS update - Takashi Iwai # USB generic driver # added fix and workaround for the mixer problem on SB Extigy. # -------------------------------------------- # 04/03/13 perex@suse.cz 1.1614.4.15 # ALSA CVS update - Takashi Iwai # PPC Tumbler driver # fixed the info callback of mixer input source (for enum type). # -------------------------------------------- # 04/03/13 perex@suse.cz 1.1614.4.16 # ALSA CVS update - Takashi Iwai # au88x0 driver # removed EXPORT_NO_SYMBOLS. # -------------------------------------------- # 04/03/13 perex@suse.cz 1.1614.4.17 # ALSA CVS update - Takashi Iwai # EMU10K1/EMU10K2 driver # disabled Dell OEM Emu10k1x from the pci id list. # the board isn't compatible with the normal emu10k1. # -------------------------------------------- # 04/03/13 perex@suse.cz 1.1614.4.18 # ALSA CVS update - Takashi Iwai # MIXART driver # fixed the compile warning. # -------------------------------------------- # 04/03/13 perex@suse.cz 1.1614.4.19 # ALSA CVS update - Takashi Iwai # Documentation,PCI drivers,ATIIXP driver # added snd-atiixp driver for the ATI IXP150/200/250 AC97 controllers. # -------------------------------------------- # 04/03/13 perex@suse.cz 1.1614.4.20 # ALSA CVS update - Takashi Iwai # Documentation,PCI drivers,Intel8x0-modem driver # added Intel-compatible onboard MC97 modem driver # by Sasha Khapyorsky # -------------------------------------------- # 04/03/13 perex@suse.cz 1.1614.4.21 # ALSA CVS update - Takashi Iwai # ALSA Core # added the new magic numbers for atiixp and au88x0 drivers. # -------------------------------------------- # 04/03/13 perex@suse.cz 1.1614.4.22 # ALSA CVS update - Takashi Iwai # ALSA Core # fixed the wrong release of id proc file. # -------------------------------------------- # 04/03/13 James.Bottomley@steeleye.com 1.1623 # [PATCH] Fix removable USB drive oops # # The actual problem reported was because there wasn't a corresponding # check on transport_classdev.class in the unregister. # # However, on closer inspection I also turned up a nasty thinko in the # reference counting. For reasons best known to the class code authors, # class devices have to obtain their own references to the devices they're # attached to which they release again in their .release routines, so you # have to remember to do a get_device() in the correct place after the # class_device_add(). I put comments in the code so that, hopefully, we # can avoid the problem in future. # -------------------------------------------- # 04/03/13 wim@iguana.be 1.1614.1.3 # [WATCHDOG] v2.6.4 pcwd_pci-v1.00_20040313-patch # # Two small fixes: # * Make cards_found a global variable so that if we remove the # pci device we can count down. # * If we can't find a correct I/O address for the card, then we # should disable the card again. # -------------------------------------------- # 04/03/13 wim@iguana.be 1.1614.1.4 # WATCHDOG] v2.6.4 wdt977-v0.03-patch # # Version 0.03 of wdt977.c - Changes that were made are: # * Extract the stop code in a seperate function (wdt977_stop) # * Extract the start code in a seperate function (wdt977_start) # * Rename kick_wdog to wdt977_keepalive for consistency # * Extract the watchdog's status code to a seperate function (wdt977_get_status) # * Change the way we deal with the watchdog timeout: # Up till now we used timeoutM (in minutes) as the correct value and then # calculated timeout as being timeoutM*60 or *timeoutM*120 (depending on # wether or not we have the netwinder hardware bug). # # From now on timeout is the correct value and we calculate timeoutM out # of it. Because of this we start with checking wether or not we have a # correct timeout value (if not we reset it to the default value) and we # automatically calculate timeoutM. Each time we change timeout with a # correct timeout value, we recalculate timeoutM. # * Extended ioctl code with WDIOC_SETOPTIONS and updated the watchdog_info structure # * Added notifier support # # Code has been tested by Woody # -------------------------------------------- # 04/03/13 wim@iguana.be 1.1614.1.5 # [WATCHDOG] v2.6.4 notifier_block-patches # # Remove unnecessary initialization in notifier_block # -------------------------------------------- # 04/03/13 trond.myklebust@fys.uio.no 1.1614.5.1 # NFSv2/v3/v4: New attribute revalidation code that no # longer relies on ctime for correctness in avoiding # update races. # # VFS: allow filesystems to disable inode_update_time() on # a per-inode basis. # -------------------------------------------- # 04/03/13 trond.myklebust@fys.uio.no 1.1614.5.2 # NFSv2/v3/v4: New file writeout strategy. Defer writes until a flush # is requested by the application (or memory pressure). # -------------------------------------------- # 04/03/13 trond.myklebust@fys.uio.no 1.1614.5.3 # Configuration: simplify configuration options. Automatically select RPCSEC_GSS # if NFSv4 is selected. Remove need for user to select SUNRPC_GSS, and the # crypto options. # Make NFSv3 a recommended option. # -------------------------------------------- # 04/03/13 trond.myklebust@fys.uio.no 1.1614.5.4 # NFSv2/v3: Ensure that we only use GETATTR+STATFS (NFSv2) and FSINFO (NFSv3) when # mounting. This should allow us to use AUTH_SYS credentials when mounting, # (even when the user requests RPCSEC_GSS authentication) due to the hack # described in RFC2623. # # Remove the broken NFS_INO_FAKE_ROOT hack. # -------------------------------------------- # 04/03/13 trond.myklebust@fys.uio.no 1.1614.5.5 # NFSv2/v3/v4: Ensure that fsync() flushes all writebacks to disk rather than just the # ones labelled as belonging to our file. This fixes a bug in which msync(MS_SYNC) # will fail to flush the pages to disk. # -------------------------------------------- # 04/03/13 trond.myklebust@fys.uio.no 1.1614.5.6 # NFSv2/v3/v4: A patch by Greg Banks that fixes the "VFS: Busy inodes after unmount." # problem. # -------------------------------------------- # 04/03/13 trond.myklebust@fys.uio.no 1.1614.5.7 # RPC: Make XIDs unique on a per-transport basis rather than globally unique. Gets rid # of an unnecessary global spinlock. # -------------------------------------------- # 04/03/13 trond.myklebust@fys.uio.no 1.1614.5.8 # RPC: Sync rpc_set_timeo() up to the 2.4.x version. In particular, this will # ensure that the timeout shift is clamped to a maximum value of 8. # # RPC: Fix by Olaf Kirch to the rpc scheduler to ensure sync tasks respect the # "intr" mount flag. # -------------------------------------------- # 04/03/13 trond.myklebust@fys.uio.no 1.1614.5.9 # RPC: Ensure that we have the correct capabilities when binding a socket to a reserved # port. Fixes a privilege bug when CONFIG_SECURITY is set. # RPC: When trying to reconnect to a TCP port, try to bind() to the last used port number # in order to ensure that the servers NFS replay cache recognizes this as being the # same mount as before. # -------------------------------------------- # 04/03/13 trond.myklebust@fys.uio.no 1.1614.5.10 # RPC,NFSv2/v3/v4: Ensure that xprt_create_proto() and rpc_create_client() return # full error codes. Should allow the "mount" program to print more useful error # diagnostics. # -------------------------------------------- # 04/03/13 trond.myklebust@fys.uio.no 1.1614.5.11 # NFSv2/v3/v4: Parenthesize #defines in nfs?xdr.c. Fix an off-by-one error on the value # of compound_decode_hdr_maxsz. # NFSv4: fix a printk() typo (spotted by Linda Dunaphant). # NFSv4: Ensure that nfs4_open_reclaim() copies the value of the new stateid back into # the shared nfsv4 state structure. # NFSv4: Don't leak NFS4ERR_WRONGSEC errors back into nfs_lookup(). # RPC,NFS,Lockd: Mark the debugging code as "unlikely" so that gcc moves it out of the # mainline code paths. # -------------------------------------------- # 04/03/13 trond.myklebust@fys.uio.no 1.1614.5.12 # NFSv2/v3 locking: Patch by Patrice Dumas to implement nlmsvc_proc_granted_res. # When a server receives that callback it should deallocate the corresponding blocked # lock using the nlmsvc_grant_reply function. # -------------------------------------------- # 04/03/13 trond.myklebust@fys.uio.no 1.1614.5.13 # NFSv2/v3 locking: Patch by Patrice Dumas that adds a check to ensure we really # were requesting a blocking lock when we get a reply from the server asking us to # block. # -------------------------------------------- # 04/03/13 trond.myklebust@fys.uio.no 1.1614.5.14 # NFSv2/v3 locking: Patch by Patrice Dumas to ensure that the server index blocks uniquely # by using the client address in addition to the value of the NLM cookie field. # -------------------------------------------- # 04/03/13 trond.myklebust@fys.uio.no 1.1614.5.15 # NFSv2/v3 locking: A patch to ensure that blocks which are not going to time out # are placed last on the ordered list nlm_block (problem reported by Olaf # Kirch). # -------------------------------------------- # 04/03/13 trond.myklebust@fys.uio.no 1.1614.5.16 # RPC,NFSv3: remove the redundant "memset()" in call_encode(). Fix up the only places # where this causes a padding error: xdr_encode_fhandle() and unx_marshal() # -------------------------------------------- # 04/03/13 trond.myklebust@fys.uio.no 1.1614.5.17 # RPC: patch by Chuck Lever to make the number of RPC slots a tunable parameter. # This is wanted in order to allow the NFS client to send more requests before # is has to block and wait for replies. # This is mainly useful if you have a WAN and want to ensure that the bandwidth # is being used efficiently. # -------------------------------------------- # 04/03/13 trond.myklebust@fys.uio.no 1.1614.5.18 # NFSv2: Fix up NFSv2 reads so that they report when the server returned a short # read due to EOF. # -------------------------------------------- # 04/03/13 trond.myklebust@fys.uio.no 1.1614.5.19 # NFSv4: Fix a list corruption in the NFSv4 state engine. # -------------------------------------------- # 04/03/13 trond.myklebust@fys.uio.no 1.1614.5.20 # NFS: From the suse kenrel RPM: handle ENOMEM from nfs_fhget(). # -------------------------------------------- # 04/03/13 trond.myklebust@fys.uio.no 1.1614.5.21 # From: # # Forward-port from 2.4: # # The following patch pulls an NFS server IP address off root_server_path # (handed out via the DHCP root-path option), if it is present. For example, # you can do this sort of thing in dhcpd.conf: # # root-path = 192.168.1.33:/tftpboot/yip.zImage # # This lets you mount your root filesystem off a different machine than you # booted from, without needing to use kernel command-line parameters. # # The patch appears to be backwards compatible. # # RFC2132 says this about the root-path option: # # This option specifies the path-name that contains the client's root # disk. The path is formatted as a character string consisting of # characters from the NVT ASCII character set. # # This is sufficiently vague to allow the path-name to include an IP-address. # Also, I found some documentation for FreeBSD saying it does this too, so it # must be right, because those FreeBSD guys are really smart... :-) # # The only downside of the patch is that the summary that ipconfig prints can # be a little odd when the kernel command line overrides whatever ipconfig gets # from (say) DHCP. The address from the kernel command line seems to get # stripped off early, so ipconfig reports it, but it doesn't report the kernel # command line NFS path, since that's handled a bit later... This small # cosmetic problem looks difficult to "fix" without rewriting quite a bit of # stuff... # -------------------------------------------- # 04/03/13 trond.myklebust@fys.uio.no 1.1614.5.22 # akpm@odsl.org: For complex reasons it is not possible to hold i_sem in nfs_update_inode(). # Hence the i_size_write() in there is deadlocky. Go back to the old way. # -------------------------------------------- # 04/03/13 trond.myklebust@fys.uio.no 1.1614.1.6 # Merge http://nfsclient.bkbits.net/linux-2.5 # into fys.uio.no:/home/linux/bitkeeper/nfsclient-2.5 # -------------------------------------------- # 04/03/13 akpm@osdl.org 1.1614.6.1 # [PATCH] ppc64: fix NUMA compile with large cpumasks # # From: Anton Blanchard # # The recent NUMA changes fail to compile with large cpumasks, we need to use # a temporary to get around the type checking. # -------------------------------------------- # 04/03/13 akpm@osdl.org 1.1614.6.2 # [PATCH] Use 64-bit counters for scheduler stats # # From: Kingsley Cheung # # A number of scheduler counters wrap around after 47 days. The context-switch # counter can wrap around after considerably less time. # # Convert them to 64-bit values. # -------------------------------------------- # 04/03/13 akpm@osdl.org 1.1614.6.3 # [PATCH] Manfred's patch to distribute boot allocations across nodes # # From: Anton Blanchard # # Distribute boot time memory allocations across all nodes, from Manfred # Spraul. # # We want to spread memory across nodes to avoid all allocations ending # up on node 0. # # Spreading boot time allocations around also helps us to avoid node 0 # becoming the hot node. # # I took it for a spin: # # buddyinfo before: # Node 7, 0 2 1 1 0 2 1 2 1 2 1 2 741 # Node 6, 0 0 0 2 0 2 1 1 2 2 2 2 1002 # Node 5, 0 0 0 2 0 2 1 2 1 2 2 2 2006 # Node 4, 0 0 0 2 0 2 1 2 1 2 2 2 2006 # Node 3, 0 0 0 2 0 2 1 2 1 2 2 2 2006 # Node 2, 0 0 0 2 0 2 1 2 1 2 2 2 2006 # Node 1, 0 0 0 2 0 2 1 1 2 2 2 2 1002 # Node 0, 0 0 38 7 0 1 1 1 0 0 0 0 1998 # # buddyinfo after: # Node 7, 0 1 0 1 1 1 1 0 0 0 1 2 738 # Node 6, 0 1 0 1 1 1 0 1 0 0 2 2 1002 # Node 5, 0 0 0 1 1 1 1 0 0 0 2 2 2006 # Node 4, 0 1 0 1 0 1 1 0 0 0 2 2 2006 # Node 3, 0 0 0 1 0 1 1 0 0 0 2 2 2005 # Node 2, 0 1 0 0 0 0 0 1 0 0 2 2 2006 # Node 1, 0 2 1 1 0 1 1 1 0 0 2 2 1002 # Node 0, 0 20 45 8 3 0 1 1 1 1 0 1 2004 # # Change in free memory due to patch: # # Node 7 -54.08 MB # Node 6 -6.33 MB # Node 5 -6.09 MB # Node 4 -6.14 MB # Node 3 -22.15 MB # Node 2 -6.05 MB # Node 1 -6.12 MB # Node 0 107.35 MB # # As you can see we gained over 100MB on node 0. # -------------------------------------------- # 04/03/13 akpm@osdl.org 1.1614.6.4 # [PATCH] further __KERNEL_SYSCALLS__ removal # # From: Arnd Bergmann # # Dave Jones already removed some of the useless __KERNEL_SYSCALLS__ defines # in various files, this gets rid of almost all the others. Replacing # execve() is nontrivial, so I left those in for now. # # For all the other system calls that are currently used from inside the # kernel, calling the sys_* function directly should always have an identical # effect. # -------------------------------------------- # 04/03/13 akpm@osdl.org 1.1614.6.5 # [PATCH] use wait_task_inactive() in kthread_bind() # # From: Rusty Russell # # Make it clear that the reason we do wait_task_inactive is because # kthread_bind frobs with k->thread_info->cpu, which is only legal because # the task is definitely not running. # # We can't use the normal migration thread code here, because it doesn't let # us bind to cpus which are offline yet, and also because we use this to # start the migration threads themselves. # -------------------------------------------- # 04/03/13 akpm@osdl.org 1.1614.6.6 # [PATCH] md: use "shedule_timeout()" instead of yield() # # From: NeilBrown # # Use "shedule_timeout()" instead of yield() as it seems to wait for less # time. # -------------------------------------------- # 04/03/13 akpm@osdl.org 1.1614.6.7 # [PATCH] md: allow assembling of partitioned arrays at boot time. # # From: NeilBrown # # kernel parameters: # # raid=partitionable # will make all auto-detected md arrays partitionable # # md=d.... # will assemble an array as a partitionable array. # -------------------------------------------- # 04/03/13 akpm@osdl.org 1.1614.6.8 # [PATCH] Work around an AMD768MPX erratum # # From: Andi Kleen # # This patch has been in the SuSE 2.4 kernel forever, but for some reason # never made it mainline. # # It works around the infamous "only works stable when a mouse is plugged in" # problem some AMD 768MPX Dual Athlon chipsets have. The problem happens # because the chipset can hang when PCI prefetch strides from a RAM page into # the VGA text buffer. When a PS2 mouse is plugged in the BIOS reserves a # page before the VGA text buffer, which stops the prefetch early. # # This patch always reserves this page when the chipset could be AMD768MPX. # This can be only done early in bootmem setup. Because it's difficult to # scan the PCI bus that early it just always reserves this page when the CPU # is an Athlon. Normally it should not make a difference because the BIOS # will have reserved that page anyways when a PS/2 mouse is plugged in. # -------------------------------------------- # 04/03/13 trond.myklebust@fys.uio.no 1.1614.1.7 # Merge http://nfsclient.bkbits.net/linux-2.5 # into fys.uio.no:/home/linux/bitkeeper/nfsclient-2.5 # -------------------------------------------- # 04/03/14 James.Bottomley@steeleye.com 1.1624 # [PATCH] Add Domain Validation to 53c700 driver # # This simply throws out the 53c700 driver's optimistic setting of the # best possible transport parameters and replaces it with DV # determination. It also adds a missing report_bus_reset() callback and # finally does a delayed DV on device errors. # -------------------------------------------- # 04/03/14 akpm@osdl.org 1.1614.6.9 # [PATCH] DMA: Fill gaping hole in DMA API interfaces. # # From: "David S. Miller" # # Currently, for an existing DMA mapping, there is a way to transfer buffer # ownership back to the cpu, yet there is no way to give it back to the device # again explicitly. The latter really is needed on platforms where the PCI # subsystem does not snoop the cpu caches, MIPS is one example. # # Many drivers were expecting the existing DMA sync interface to handle both # directions, which was wrong. # # Now, with this change, we have explicit interfaces for DMA syncing to/from # the device and the cpu. # -------------------------------------------- # 04/03/14 akpm@osdl.org 1.1614.6.10 # [PATCH] module unload deadlock fix # # From: Rusty Russell # # From: Andrea Arcangeli # # We should drop module sem before calling mod->exit, for practical reasons: # too many module exit functions oops or hang, resulting in a permenantly held # module sem, which blocks all module ops including lsmod. # -------------------------------------------- # 04/03/14 akpm@osdl.org 1.1614.6.11 # [PATCH] gcc-3.5 libata build fix # # drivers/scsi/sata_vsc.c: In function `vsc_sata_interrupt': # include/linux/libata.h:414: sorry, unimplemented: inlining failed in call to 'ata_host_intr': function body not available # drivers/scsi/sata_vsc.c:187: sorry, unimplemented: called from here # -------------------------------------------- # 04/03/14 torvalds@ppc970.osdl.org 1.1625 # Merge bk://linux-scsi.bkbits.net/scsi-for-linus-2.6 # into ppc970.osdl.org:/home/torvalds/v2.5/linux # -------------------------------------------- # 04/03/14 torvalds@ppc970.osdl.org 1.1626 # Merge bk://linux-acpi.bkbits.net/linux-acpi-release-2.6.5 # into ppc970.osdl.org:/home/torvalds/v2.5/linux # -------------------------------------------- # 04/03/14 torvalds@ppc970.osdl.org 1.1627 # Merge http://linux-sound.bkbits.net/linux-sound # into ppc970.osdl.org:/home/torvalds/v2.5/linux # -------------------------------------------- # 04/03/14 willy@debian.org 1.1628 # [PATCH] PA-RISC update # # Updates for 2.6.4 for PARISC: # # - defconfigs (Randolph Chung) # - copyright updates (Grant Grundler) # - Fix DOS hole in sys_clone (James Bottomley) # - missing hardware ID (Andy Walker) # - disable interrupts during cache-flushes (LaMont Jones) # - Fix crash on machines with <256MB ram (Randolph Chung) # - Make SuckyIO IDE work better (Randolph Chung) # - Align data_start so the extable is writable (Randolph Chung) # - Extensive rewrite of virtual merging code (James Bottomley) # - Fix EISA, non-PCI module builds (Matthew Wilcox) # - Fix Elroy PCI config space byte & word writes (Grant Grundler) # - Eliminate a warning in parport_gsc (Helge Deller) # - Fix endian problem with ide mmio macros (Randolph Chung) # - Delete asm/keyboard.h (Matthew Wilcox) # - Delete asm/md.h (Grant Grundler) # - Eliminate a warning in ALSA harmony (Matthew Wilcox) # -------------------------------------------- # 04/03/14 trond.myklebust@fys.uio.no 1.1629 # Merge http://nfsclient.bkbits.net/linux-2.5 # into fys.uio.no:/home/linux/bitkeeper/nfsclient-2.5 # -------------------------------------------- # 04/03/14 akpm@osdl.org 1.1628.1.1 # [PATCH] move consistent_dma_mask to the generic device # # From: James Bottomley # # pci_dev.consistent_dma_mask was introduced to get around problems in the # IA64 Altix machine. # # Now, we have a use for it in x86: the aacraid needs coherent memory in a # 31 bit address range (2GB). Unfortunately, x86 is converted to the dma # model, so it can't see the pci_dev by the time coherent memory is # allocated. # # The solution to all of this is to move pci_dev.consistent_dma_mask to # dev.coherent_dma_mask and make x86 use it in the dma_alloc_coherent() # calls. # # This should allow me to make the aacraid set the coherent mask instead # of using it's current dma_mask juggling. # -------------------------------------------- # 04/03/14 akpm@osdl.org 1.1628.1.2 # [PATCH] s390: update for altered page_state structure # # From: Olaf Hering # # This patch is needed on s390. # -------------------------------------------- # 04/03/14 akpm@osdl.org 1.1628.1.3 # [PATCH] __kill_pg_info() return value fix # # Fix a bug which was spotted by Alex Lyashkov # # The fairly unobvious coding in __kill_pg_info() will cause a zero value to be # incorrectly returned if the second or succeeding call to # group_send_sig_info() returns an error. # -------------------------------------------- # 04/03/14 James.Bottomley@SteelEye.com 1.1628.1.4 # [PATCH] Fix voyager to boot again # # The very early memory detection patch broke voyager. # # This fixes it again. # -------------------------------------------- # 04/03/14 torvalds@ppc970.osdl.org 1.1630 # Merge http://nfsclient.bkbits.net/linux-2.5 # into ppc970.osdl.org:/home/torvalds/v2.5/linux # -------------------------------------------- # diff -Nru a/CREDITS b/CREDITS --- a/CREDITS Sun Mar 14 14:20:08 2004 +++ b/CREDITS Sun Mar 14 14:20:08 2004 @@ -975,8 +975,7 @@ E: bfennema@falcon.csc.calpoly.edu W: http://www.csc.calpoly.edu/~bfennema D: UDF filesystem -S: 21760 Irma Lyle Drive -S: Los Gatos, CA 95033-8942 +S: (ask for current address) S: USA N: Jürgen Fischer diff -Nru a/Documentation/DMA-mapping.txt b/Documentation/DMA-mapping.txt --- a/Documentation/DMA-mapping.txt Sun Mar 14 14:20:07 2004 +++ b/Documentation/DMA-mapping.txt Sun Mar 14 14:20:07 2004 @@ -283,7 +283,7 @@ in order to get correct behavior on all platforms. - Streaming DMA mappings which are usually mapped for one DMA transfer, - unmapped right after it (unless you use pci_dma_sync below) and for which + unmapped right after it (unless you use pci_dma_sync_* below) and for which hardware can optimize for sequential accesses. This of "streaming" as "asynchronous" or "outside the coherency @@ -543,14 +543,30 @@ all bus addresses. If you need to use the same streaming DMA region multiple times and touch -the data in between the DMA transfers, just map it with -pci_map_{single,sg}, and after each DMA transfer call either: +the data in between the DMA transfers, the buffer needs to be synced +properly in order for the cpu and device to see the most uptodate and +correct copy of the DMA buffer. - pci_dma_sync_single(dev, dma_handle, size, direction); +So, firstly, just map it with pci_map_{single,sg}, and after each DMA +transfer call either: + + pci_dma_sync_single_for_cpu(dev, dma_handle, size, direction); or: - pci_dma_sync_sg(dev, sglist, nents, direction); + pci_dma_sync_sg_for_cpu(dev, sglist, nents, direction); + +as appropriate. + +Then, if you wish to let the device get at the DMA area again, +finish accessing the data with the cpu, and then before actually +giving the buffer to the hardware call either: + + pci_dma_sync_single_for_device(dev, dma_handle, size, direction); + +or: + + pci_dma_sync_sg_for_device(dev, sglist, nents, direction); as appropriate. @@ -590,8 +606,9 @@ * the DMA transfer with the CPU first * so that we see updated contents. */ - pci_dma_sync_single(cp->pdev, cp->rx_dma, cp->rx_len, - PCI_DMA_FROMDEVICE); + pci_dma_sync_single_for_cpu(cp->pdev, cp->rx_dma, + cp->rx_len, + PCI_DMA_FROMDEVICE); /* Now it is safe to examine the buffer. */ hp = (struct my_card_header *) cp->rx_buf; @@ -601,7 +618,13 @@ pass_to_upper_layers(cp->rx_buf); make_and_setup_new_rx_buf(cp); } else { - /* Just give the buffer back to the card. */ + /* Just sync the buffer and give it back + * to the card. + */ + pci_dma_sync_single_for_device(cp->pdev, + cp->rx_dma, + cp->rx_len, + PCI_DMA_FROMDEVICE); give_rx_buf_to_card(cp); } } @@ -709,12 +732,21 @@ When the DMA transfer is complete, invoke: - void pci_dac_dma_sync_single(struct pci_dev *pdev, - dma64_addr_t dma_addr, - size_t len, int direction); + void pci_dac_dma_sync_single_for_cpu(struct pci_dev *pdev, + dma64_addr_t dma_addr, + size_t len, int direction); This must be done before the CPU looks at the buffer again. -This interface behaves identically to pci_dma_sync_{single,sg}(). +This interface behaves identically to pci_dma_sync_{single,sg}_for_cpu(). + +And likewise, if you wish to let the device get back at the buffer after +the cpu has read/written it, invoke: + + void pci_dac_dma_sync_single_for_device(struct pci_dev *pdev, + dma64_addr_t dma_addr, + size_t len, int direction); + +before letting the device access the DMA area again. If you need to get back to the PAGE/OFFSET tuple from a dma64_addr_t the following interfaces are provided: diff -Nru a/Documentation/devices.txt b/Documentation/devices.txt --- a/Documentation/devices.txt Sun Mar 14 14:20:07 2004 +++ b/Documentation/devices.txt Sun Mar 14 14:20:07 2004 @@ -2046,6 +2046,21 @@ 1 = /dev/gpib1 Second GPIB bus ... +160 block Carmel 8-port SATA Disks on First Controller + 0 = /dev/carmel/0 SATA disk 0 whole disk + 1 = /dev/carmel/0p1 SATA disk 0 partition 1 + ... + 31 = /dev/carmel/0p31 SATA disk 0 partition 31 + + 32 = /dev/carmel/1 SATA disk 1 whole disk + 64 = /dev/carmel/2 SATA disk 2 whole disk + ... + 224 = /dev/carmel/7 SATA disk 7 whole disk + + Partitions are handled in the same way as for IDE + disks (see major number 3) except that the limit on + partitions is 31. + 161 char IrCOMM devices (IrDA serial/parallel emulation) 0 = /dev/ircomm0 First IrCOMM device 1 = /dev/ircomm1 Second IrCOMM device @@ -2053,6 +2068,21 @@ 16 = /dev/irlpt0 First IrLPT device 17 = /dev/irlpt1 Second IrLPT device ... + +161 block Carmel 8-port SATA Disks on Second Controller + 0 = /dev/carmel/8 SATA disk 8 whole disk + 1 = /dev/carmel/8p1 SATA disk 8 partition 1 + ... + 31 = /dev/carmel/8p31 SATA disk 8 partition 31 + + 32 = /dev/carmel/9 SATA disk 9 whole disk + 64 = /dev/carmel/10 SATA disk 10 whole disk + ... + 224 = /dev/carmel/15 SATA disk 15 whole disk + + Partitions are handled in the same way as for IDE + disks (see major number 3) except that the limit on + partitions is 31. 162 char Raw block device interface 0 = /dev/rawctl Raw I/O control device diff -Nru a/Documentation/filesystems/udf.txt b/Documentation/filesystems/udf.txt --- a/Documentation/filesystems/udf.txt Sun Mar 14 14:20:08 2004 +++ b/Documentation/filesystems/udf.txt Sun Mar 14 14:20:08 2004 @@ -1,7 +1,7 @@ * * ./Documentation/filesystems/udf.txt * -UDF Filesystem version 0.9.5 +UDF Filesystem version 0.9.8.1 If you encounter problems with reading UDF discs using this driver, please report them to linux_udf@hpesjro.fc.hp.com, which is the @@ -16,7 +16,7 @@ gid= Set the default group. umask= Set the default umask. uid= Set the default user. - bs= Set the block size. + bs= Set the block size. unhide Show otherwise hidden files. undelete Show deleted files in lists. adinicb Embed data in the inode (default) @@ -47,15 +47,11 @@ ------------------------------------------------------------------------------- -For more information see: - http://www.trylinux.com/projects/udf/index.html - For the latest version and toolset see: - http://www.csc.calpoly.edu/~bfennema/udf.html http://linux-udf.sourceforge.net/ Documentation on UDF and ECMA 167 is available FREE from: - http://www.osta.org/ - http://www.ecma.ch/ + http://www.osta.org/ + http://www.ecma-international.org/ Ben Fennema diff -Nru a/Documentation/filesystems/ufs.txt b/Documentation/filesystems/ufs.txt --- a/Documentation/filesystems/ufs.txt Sun Mar 14 14:20:08 2004 +++ b/Documentation/filesystems/ufs.txt Sun Mar 14 14:20:08 2004 @@ -20,6 +20,9 @@ 44bsd used in FreeBSD, NetBSD, OpenBSD supported os read-write + ufs2 used in FreeBSD 5.x + supported os read-only + sun used in SunOS (Solaris) supported as read-write diff -Nru a/Documentation/i386/zero-page.txt b/Documentation/i386/zero-page.txt --- a/Documentation/i386/zero-page.txt Sun Mar 14 14:20:06 2004 +++ b/Documentation/i386/zero-page.txt Sun Mar 14 14:20:06 2004 @@ -75,7 +75,7 @@ 0x2cc 4 bytes DISK80_SIG_BUFFER (setup.S) 0x2d0 - 0x600 E820MAP 0x600 - 0x7ff EDDBUF (setup.S) for disk signature read sector -0x600 - 0x7d3 EDDBUF (setup.S) for edd data +0x600 - 0x7eb EDDBUF (setup.S) for edd data 0x800 string, 2K max COMMAND_LINE, the kernel commandline as copied using CL_OFFSET. diff -Nru a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt --- a/Documentation/kernel-parameters.txt Sun Mar 14 14:20:09 2004 +++ b/Documentation/kernel-parameters.txt Sun Mar 14 14:20:09 2004 @@ -116,6 +116,10 @@ acpi_irq_isa= [HW,ACPI] If irq_balance, Mark listed IRQs used by ISA Format: ,... + acpi_osi= [HW,ACPI] empty param disables _OSI + + acpi_serialize [HW,ACPI] force serialization of AML methods + ad1816= [HW,OSS] Format: ,,, See also Documentation/sound/oss/AD1816. diff -Nru a/Documentation/networking/netconsole.txt b/Documentation/networking/netconsole.txt --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/Documentation/networking/netconsole.txt Sun Mar 14 14:20:09 2004 @@ -0,0 +1,57 @@ + +started by Ingo Molnar , 2001.09.17 +2.6 port and netpoll api by Matt Mackall , Sep 9 2003 + +Please send bug reports to Matt Mackall + +This module logs kernel printk messages over UDP allowing debugging of +problem where disk logging fails and serial consoles are impractical. + +It can be used either built-in or as a module. As a built-in, +netconsole initializes immediately after NIC cards and will bring up +the specified interface as soon as possible. While this doesn't allow +capture of early kernel panics, it does capture most of the boot +process. + +It takes a string configuration parameter "netconsole" in the +following format: + + netconsole=[src-port]@[src-ip]/[],[tgt-port]@/[tgt-macaddr] + + where + src-port source for UDP packets (defaults to 6665) + src-ip source IP to use (interface address) + dev network interface (eth0) + tgt-port port for logging agent (6666) + tgt-ip IP address for logging agent + tgt-macaddr ethernet MAC address for logging agent (broadcast) + +Examples: + + linux netconsole=4444@10.0.0.1/eth1,9353@10.0.0.2/12:34:56:78:9a:bc + + or + + insmod netconsole netconsole=@/,@10.0.0.2/ + +Built-in netconsole starts immediately after the TCP stack is +initialized and attempts to bring up the supplied dev at the supplied +address. + +The remote host can run either 'netcat -u -l -p ' or syslogd. + +WARNING: the default target ethernet setting uses the broadcast +ethernet address to send packets, which can cause increased load on +other systems on the same ethernet segment. + +NOTE: the network device (eth1 in the above case) can run any kind +of other network traffic, netconsole is not intrusive. Netconsole +might cause slight delays in other traffic if the volume of kernel +messages is high, but should have no other impact. + +Netconsole was designed to be as instantaneous as possible, to +enable the logging of even the most critical kernel bugs. It works +from IRQ contexts as well, and does not enable interrupts while +sending packets. Due to these unique needs, configuration can not +be more automatic, and some fundamental limitations will remain: +only IP networks, UDP packets and ethernet devices are supported. diff -Nru a/Documentation/scsi/st.txt b/Documentation/scsi/st.txt --- a/Documentation/scsi/st.txt Sun Mar 14 14:20:06 2004 +++ b/Documentation/scsi/st.txt Sun Mar 14 14:20:06 2004 @@ -2,7 +2,7 @@ The driver is currently maintained by Kai Mäkisara (email Kai.Makisara@kolumbus.fi) -Last modified: Thu Feb 19 21:57:30 2004 by makisara +Last modified: Wed Feb 25 14:09:08 2004 by makisara BASICS @@ -36,8 +36,9 @@ manager. The changes persist until the defaults again come into effect. -3. Up to four modes can be defined and selected using the minor number -(bits 5 and 6). Mode 0 corresponds to the defaults discussed +3. By default, up to four modes can be defined and selected using the minor +number (bits 5 and 6). The number of modes can be changed by changing +ST_NBR_MODE_BITS in st.h. Mode 0 corresponds to the defaults discussed above. Additional modes are dormant until they are defined by the system manager (root). When specification of a new mode is started, the configuration of mode 0 is used to provide a starting point for @@ -107,7 +108,7 @@ dev_upper non-rew mode dev-lower 20 - 8 7 6 5 4 0 The non-rewind bit is always bit 7 (the uppermost bit in the lowermost -byte). The bits defining the mode are next to the non-rewind bits. The +byte). The bits defining the mode are below the non-rewind bit. The remaining bits define the tape device number. This numbering is backward compatible with the numbering used when the minor number was only 8 bits wide. @@ -117,10 +118,10 @@ The driver creates the directory /sys/class/scsi_tape and populates it with directories corresponding to the existing tape devices. There are autorewind -and non-rewind entries for each mode. The names are stxmy and stxmyn, where x -is the tape number and y is the mode. For example, the directories for the -first tape device are (assuming four modes): st0m0 st0m0n st0m1 st0m1n -st0m2 st0m2n st0m3 st0m3n. +and non-rewind entries for each mode. The names are stxy and nstxy, where x +is the tape number and y a character corresponding to the mode (none, l, m, +a). For example, the directories for the first tape device are (assuming four +modes): st0 nst0 st0l nst0l st0m nst0m st0a nst0a. Each directory contains the entries: default_blksize default_compression default_density defined dev device driver. The file 'defined' contains 1 @@ -130,7 +131,7 @@ 'device' and 'driver' point to the SCSI device and driver entries. A link named 'tape' is made from the SCSI device directory to the class -directory corresponding to the mode 0 auto-rewind device (e.g., st0m0). +directory corresponding to the mode 0 auto-rewind device (e.g., st0). BSD AND SYS V SEMANTICS diff -Nru a/Documentation/scsi/sym53c8xx_2.txt b/Documentation/scsi/sym53c8xx_2.txt --- a/Documentation/scsi/sym53c8xx_2.txt Sun Mar 14 14:20:06 2004 +++ b/Documentation/scsi/sym53c8xx_2.txt Sun Mar 14 14:20:06 2004 @@ -567,7 +567,7 @@ nvram:n do not look for serial NVRAM nvram:y test controllers for onboard serial NVRAM (alternate binary form) - mvram= + nvram= 0x01 look for NVRAM (equivalent to nvram=y) 0x02 ignore NVRAM "Synchronous negotiation" parameters for all devices 0x04 ignore NVRAM "Wide negotiation" parameter for all devices @@ -661,7 +661,7 @@ The 'nvram' boot option can be entered in hexadecimal form in order to ignore some options configured in the NVRAM, as follow: -mvram= +nvram= 0x01 look for NVRAM (equivalent to nvram=y) 0x02 ignore NVRAM "Synchronous negotiation" parameters for all devices 0x04 ignore NVRAM "Wide negotiation" parameter for all devices diff -Nru a/Documentation/sound/alsa/ALSA-Configuration.txt b/Documentation/sound/alsa/ALSA-Configuration.txt --- a/Documentation/sound/alsa/ALSA-Configuration.txt Sun Mar 14 14:20:06 2004 +++ b/Documentation/sound/alsa/ALSA-Configuration.txt Sun Mar 14 14:20:06 2004 @@ -112,7 +112,8 @@ - value is used for /proc/asound filesystem - this value can be used by applications for identification of card if user does not want identify card with index number - enable - enable card (only first card is enabled by default) + enable - enable card. (all cards enabled for PCI and ISA PnP cards + as default.) Module snd-ad1816a ------------------ @@ -178,6 +179,42 @@ Module supports up to 8 cards, autoprobe and PnP. + Module snd-atiixp + ----------------- + + Module for ATI IXP 150/200/250 AC97 controllers. + + ac97_clock - AC'97 clock (defalut = 48000) + spdif_aclink - S/PDIF transfer over AC-link (default = 1) + + This module supports up to 8 cards and autoprobe. + + Module snd-au8810, snd-au8820, snd-au8830 + ----------------------------------------- + + Module for Aureal Vortex, Vortex2 and Advantage device. + + pcifix - Control PCI workarounds + 0 = Disable all workarounds + 1 = Force the PCI latency of the Aureal card to 0xff + 2 = Force the Extend PCI#2 Internal Master for Efficient + Handling of Dummy Requests on the VIA KT133 AGP Bridge + 3 = Force both settings + 255 = Autodetect what is required (default) + + This module supports all ADB PCM channels, ac97 mixer, SPDIF, hardware + EQ, mpu401, gameport. A3D and wavetable support are still in development. + Development and reverse engineering work is being coordinated at + http://savannah.nongnu.org/projects/openvortex/ + SPDIF output has a copy of the AC97 codec output, unless you use the + "spdif" pcm device, which allows raw data passthru. + The hardware EQ hardware and SPDIF is only present in the Vortex2 and + Advantage. + + Note: Some ALSA mixer applicactions don't handle the SPDIF samplerate + control correctly. If you have problems regarding this, try + another ALSA compliant mixer (alsamixer works). + Module snd-azt2320 ------------------ @@ -608,6 +645,7 @@ 1 = use headphone control as master 2 = swap headphone and master controls 3 = for AD1985, turn on OMS bit and use headphone + 4 = for ALC65x, turn on the jack sense mode Module supports autoprobe and multiple bus-master chips (max 8). @@ -627,6 +665,15 @@ The power-management is supported. + Module snd-intel8x0m + -------------------- + + Module for Intel ICH (i8x0) chipset MC97 modems. + + ac97_clock - AC'97 codec clock base (0 = auto-detect) + + This module supports up to 8 cards and autoprobe. + Module snd-interwave -------------------- @@ -692,6 +739,15 @@ The power-management is supported. + Module snd-mixart + ----------------- + + Module for Digigram miXart8 soundcards. + + Module supports multiple cards. + Note: One miXart8 board will be represented as 4 alsa cards. + See MIXART.txt for details. + Module snd-mpu401 ----------------- @@ -1169,6 +1225,16 @@ Module supports autoprobe and multiple chips (max 8). The power-management is supported. + + Module snd-pdaudiocf + -------------------- + + Module for Sound Core PDAudioCF soundcard. + + irq_mask - IRQ mask (PCMCIA type) + irq_list - List of available interrupts for this soundcard + + Note: the driver is build only when CONFIG_ISA is set. Configuring Non-ISAPNP Cards diff -Nru a/Documentation/sound/alsa/DocBook/alsa-driver-api.tmpl b/Documentation/sound/alsa/DocBook/alsa-driver-api.tmpl --- a/Documentation/sound/alsa/DocBook/alsa-driver-api.tmpl Sun Mar 14 14:20:06 2004 +++ b/Documentation/sound/alsa/DocBook/alsa-driver-api.tmpl Sun Mar 14 14:20:06 2004 @@ -49,7 +49,6 @@ !Esound/core/memory.c !Iinclude/sound/sndmagic.h !Esound/core/memalloc.c -!Esound/core/sgbuf.c PCM API @@ -71,6 +70,7 @@ AC97 Codec API !Esound/pci/ac97/ac97_codec.c +!Esound/pci/ac97/ac97_pcm.c MIDI API diff -Nru a/Documentation/sound/alsa/DocBook/writing-an-alsa-driver.tmpl b/Documentation/sound/alsa/DocBook/writing-an-alsa-driver.tmpl --- a/Documentation/sound/alsa/DocBook/writing-an-alsa-driver.tmpl Sun Mar 14 14:20:06 2004 +++ b/Documentation/sound/alsa/DocBook/writing-an-alsa-driver.tmpl Sun Mar 14 14:20:06 2004 @@ -18,8 +18,8 @@ - Mar. 26, 2003 - 0.3 + Mar. 6, 2004 + 0.3.1 @@ -30,7 +30,7 @@ - Copyright (c) 2002, 2003 Takashi Iwai tiwai@suse.de + Copyright (c) 2002-2004 Takashi Iwai tiwai@suse.de @@ -111,18 +111,18 @@ One is the the trees provided as a tarball or via cvs from the - ALSA's ftp site, and another is the 2.5 (or later) Linux kernel + ALSA's ftp site, and another is the 2.6 (or later) Linux kernel tree. To synchronize both, the ALSA driver tree is split to two different trees: alsa-kernel and alsa-driver. The former - contains purely the source codes for the Linux 2.5 (or later) - tree. This tree is designed only for compilation on 2.5 or + contains purely the source codes for the Linux 2.6 (or later) + tree. This tree is designed only for compilation on 2.6 or later environment. The latter, alsa-driver, contains many subtle files for compiling the ALSA driver on the outside of Linux kernel like configure script, the wrapper functions for older, 2.2 and 2.4 kernels, to adapt the latest kernel API, and additional drivers which are still in development or in tests. The drivers in alsa-driver tree will be moved to - alsa-kernel (eventually 2.5 kernel tree) once when they are + alsa-kernel (eventually 2.6 kernel tree) once when they are finished and confirmed to work fine. @@ -346,7 +346,7 @@
oss directory - The OSS/Lite source files are stored here on Linux 2.5 (or + The OSS/Lite source files are stored here on Linux 2.6 (or later) tree. (In the ALSA driver tarball, it's empty, of course :)
@@ -1815,7 +1815,7 @@ Oh, one thing was forgotten. If you have no exported symbols, - you need to declare it on 2.2 or 2.4 kernels (on 2.5 kernels + you need to declare it on 2.2 or 2.4 kernels (on 2.6 kernels it's not necessary, though). @@ -2075,8 +2075,9 @@ snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_mychip_capture_ops); /* pre-allocation of buffers */ - snd_pcm_lib_preallocate_pci_pages_for_all(chip->pci, pcm, - 64*1024, 64*1024); + snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV, + snd_dma_pci_data(chip->pci), + 64*1024, 64*1024); return 0; } ]]> @@ -2202,8 +2203,9 @@ pci, pcm, - 64*1024, 64*1024); + snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV, + snd_dma_pci_data(chip->pci), + 64*1024, 64*1024); ]]> @@ -3769,14 +3771,20 @@ value.enumerated.items = 4; - if (uinfo->value.enumerated.item > 3) - uinfo->value.enumerated.item = 3; - strcpy(uinfo->value.enumerated.name, - texts[uinfo->value.enumerated.item]); + snd_ctl_elem_info_t *uinfo) + { + static char *texts[4] = { + "First", "Second", "Third", "Fourth" + }; + uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; + uinfo->count = 1; + uinfo->value.enumerated.items = 4; + if (uinfo->value.enumerated.item > 3) + uinfo->value.enumerated.item = 3; + strcpy(uinfo->value.enumerated.name, + texts[uinfo->value.enumerated.item]); + return 0; + } ]]> @@ -4718,7 +4726,8 @@ @@ -4728,8 +4737,25 @@ size to be changed via prealloc proc file. The allocator will try to get as the large area as possible within the given size. - There are different versions of pre-allocator for different - buses. + + + + The second argument (type) and the third argument (device pointer) + are dependent on the bus. + In the case of ISA bus, pass snd_dma_isa_data() + as the third argument with SNDRV_DMA_TYPE_DEV type. + For the continuous buffer unrelated to the bus can be pre-allocated + with SNDRV_DMA_TYPE_CONTINUOUS type and the + snd_dma_continuous_data(GFP_KERNEL) device pointer, + whereh GFP_KERNEL is the kernel allocation flag to + use. For the SBUS, SNDRV_DMA_TYPE_SBUS and + snd_dma_sbus_data(sbus_dev) are used instead. + For the PCI scatter-gather buffers, use + SNDRV_DMA_TYPE_DEV_SG with + snd_dma_pci_data(pci) + (see the section + Non-Contiguous Buffers + ). @@ -4936,11 +4962,13 @@ For creating the SG-buffer handler, call - snd_pcm_lib_preallocate_sg_pages() or - snd_pcm_lib_preallocate_sg_pages_for_all() + snd_pcm_lib_preallocate_pages() or + snd_pcm_lib_preallocate_pages_for_all() + with SNDRV_DMA_TYPE_DEV_SG in the PCM constructor like other PCI pre-allocator. - You need to pass the - pci_dev struct pointer of the chip. + You need to pass the snd_dma_pci_data(pci), + where pci is the struct pci_dev pointer + of the chip as well. The snd_sg_buf_t instance is created as substream->dma_private. You can cast the pointer like: @@ -5274,7 +5302,7 @@ - For keeping the readability of 2.5 source code, it's recommended to + For keeping the readability of 2.6 source code, it's recommended to separate the above ifdef condition as the patch file in alsa-driver directory. See alsa-driver/pci/ali5451.c for example. @@ -5606,7 +5634,7 @@ tree. Then the driver is evaluated, audited and tested by developers and users. After a certain time, the driver will go to alsa-kernel tree and eventually integrated into - Linux 2.5 tree. + Linux 2.6 tree. @@ -5642,61 +5670,44 @@ - Modify alsa-driver/acore/Makefile + Create the Kconfig entry - Here define the dependent modules. + Add the new entry of Kconfig for your xyz driver. - If the driver supports PCM, snd-pcm.o, - snd-timer.o and snd-page-alloc.o - will be needed. - - - For rawmidi, snd-rawmidi.o is needed in addition. - The MIDI stuff is also related to the sequencer. - You'll need to modify alsa-driver/acore/seq/Makefile. + the line, select SND_PCM, specifies that the driver xyz supports + PCM. In addition to SND_PCM, the following components are + supported for select command: + SND_RAWMIDI, SND_TIMER, SND_HWDEP, SND_MPU401_UART, + SND_OPL3_LIB, SND_OPL4_LIB, SND_VX_LIB, SND_AC97_CODEC. + Add the select command for each supported component. - For OPL3, snd-hwdep.o is needed, too. - It's involved with the sequencer, and as well as rawmidi, - you'll need to modify alsa-driver/acore/seq/Makefile - and acore/seq/instr/Makefile in addition. - Also, a new entry is necessary in - alsa-driver/drivers/opl3/Makefile. + Note that some selections imply the lowlevel selections. + For example, PCM includes TIMER, MPU401_UART includes RAWMIDI, + AC97_CODEC includes PCM, and OPL3_LIB includes HWDEP. + You don't need to give the lowlevel selections again. - - - - Modify alsa-driver/utils/Modules.dep + For the details of Kconfig script, refer to the kbuild + documentation. - - Add the module definition for configure, here. - The beginning of the line must be a vertical bar, following - the card module name (snd-xyz) and the list of its all - dependent modules. - - - - - - - @@ -5724,7 +5735,7 @@ @@ -5739,13 +5750,13 @@ Sample Makefile for a driver xyz - Modify alsa-driver/acore/Makefile + Create the Kconfig entry This procedure is as same as in the last section. - - - - - - Modify alsa-driver/utils/Modules.dep - - - - - - - - diff -Nru a/Documentation/sound/alsa/Joystick.txt b/Documentation/sound/alsa/Joystick.txt --- a/Documentation/sound/alsa/Joystick.txt Sun Mar 14 14:20:07 2004 +++ b/Documentation/sound/alsa/Joystick.txt Sun Mar 14 14:20:07 2004 @@ -43,7 +43,8 @@ ens1370 joystick 0 = disable (default), 1 = enable ens1371 joystick_port 0 = disable (default), 1 = auto-detect, manual: 0x200, 0x208, 0x210, 0x218 - cmipci joystick 0 = disable (default), 1 = enable + cmipci joystick_port 0 = disable (default), 1 = auto-detect, + manual: any address (e.g. 0x200) cs4281 N/A N/A cs46xx N/A N/A es1938 N/A N/A diff -Nru a/Documentation/sound/alsa/MIXART.txt b/Documentation/sound/alsa/MIXART.txt --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/Documentation/sound/alsa/MIXART.txt Sun Mar 14 14:20:09 2004 @@ -0,0 +1,96 @@ + Alsa driver for Digigram miXart8 and miXart8AES/EBU soundcards + Digigram + + +GENERAL +======= + +The miXart8 is a multichannel audio processing and mixing soundcard +that has 4 stereo audio inputs and 4 stereo audio outputs. +The miXart8AES/EBU is the same with a add-on card that offers further +4 digital stereo audio inputs and outputs. +Furthermore the add-on card offers external clock synchronisation +(AES/EBU, Word Clock, Time Code and Video Synchro) + +The mainboard has a PowerPC that offers onboard mpeg encoding and +decoding, samplerate conversions and various effects. + +The driver don't work properly at all until the certain firmwares +are loaded, i.e. no PCM nor mixer devices will appear. +Use the mixartloader that can be found in the alsa-tools package. + + +VERSION 0.1.0 +============= + +One miXart8 board will be represented as 4 alsa cards, each with 1 +stereo analog capture 'pcm0c' and 1 stereo analog playback 'pcm0p' device. +With a miXart8AES/EBU there is in addition 1 stereo digital input +'pcm1c' and 1 stereo digital output 'pcm1p' per card. + +Formats +------- +U8, S16_LE, S16_BE, S24_3LE, S24_3BE, FLOAT_LE, FLOAT_BE +Sample rates : 8000 - 48000 Hz continously + +Playback +-------- +For instance the playback devices are configured to have max. 4 +substreams performing hardware mixing. This could be changed to a +maximum of 24 substreams if wished. +Mono files will be played on the left and right channel. Each channel +can be muted for each stream to use 8 analog/digital outputs seperately. + +Capture +------- +There is one substream per capture device. For instance only stereo +formats are supported. + +Mixer +----- + and : analog volume control of playback and capture PCM. + and : digital volume control of each analog substream. + and : digital volume control of each AES/EBU substream. + : Loopback from 'pcm0c' to 'pcm0p' with digital volume +and mute control. + +Rem : for best audio quality try to keep a 0 attenuation on the PCM +and AES volume controls which is set by 219 in the range from 0 to 255 +(about 86% with alsamixer) + + +NOT YET IMPLEMENTED +=================== + +- external clock support (AES/EBU, Word Clock, Time Code, Video Sync) +- MPEG audio formats +- mono record +- on-board effects and samplerate conversions +- linked streams + + +FIRMWARE +======== + +For loading the firmware automatically after the module is loaded, use +the post-install command. For example, add the following entry to +/etc/modprobe.conf for miXart driver: + + install snd-mixart /sbin/modprobe --first-time -i snd-mixart && \ + /usr/bin/mixartloader +(for 2.2/2.4 kernels, add "post-install snd-mixart /usr/bin/vxloader" to + /etc/modules.conf, instead.) + +The firmware binaries are installed on /usr/share/alsa/firmware +(or /usr/local/share/alsa/firmware, depending to the prefix option of +configure). There will be a miXart.conf file, which define the dsp image +files. + +The firmware files are copyright by Digigram SA + + +COPYRIGHT +========= + +Copyright (c) 2003 Digigram SA +Distributalbe under GPL. diff -Nru a/MAINTAINERS b/MAINTAINERS --- a/MAINTAINERS Sun Mar 14 14:20:07 2004 +++ b/MAINTAINERS Sun Mar 14 14:20:07 2004 @@ -2037,8 +2037,6 @@ UDF FILESYSTEM P: Ben Fennema M: bfennema@falcon.csc.calpoly.edu -P: Dave Boynton -M: dave@trylinux.com L: linux_udf@hpesjro.fc.hp.com W: http://linux-udf.sourceforge.net S: Maintained diff -Nru a/Makefile b/Makefile --- a/Makefile Sun Mar 14 14:20:07 2004 +++ b/Makefile Sun Mar 14 14:20:07 2004 @@ -757,26 +757,15 @@ # Any core files spread around are deleted as well # make distclean Remove editor backup files, patch leftover files and the like -# Files removed with 'make clean' -CLEAN_FILES += vmlinux System.map MC* +# Directories & files removed with 'make clean' +CLEAN_DIRS += $(MODVERDIR) include/config include2 +CLEAN_FILES += vmlinux System.map \ + include/linux/autoconf.h include/linux/version.h \ + include/asm include/linux/modversions.h \ + kernel.spec .tmp* # Files removed with 'make mrproper' -MRPROPER_FILES += \ - include/linux/autoconf.h include/linux/version.h \ - .version .config .config.old config.in config.old \ - .menuconfig.log \ - include/asm \ - .hdepend include/linux/modversions.h \ - tags TAGS cscope* kernel.spec \ - .tmp* - -# Directories removed with 'make mrproper' -MRPROPER_DIRS += \ - $(MODVERDIR) \ - .tmp_export-objs \ - include/config \ - include/linux/modules \ - include2 +MRPROPER_FILES += .version .config .config.old tags TAGS cscope* # clean - Delete all intermediate files # @@ -785,28 +774,36 @@ $(clean-dirs): $(Q)$(MAKE) $(clean)=$(patsubst _clean_%,%,$@) -quiet_cmd_rmclean = RM $$(CLEAN_FILES) -cmd_rmclean = rm -f $(CLEAN_FILES) +clean: rm-dirs := $(wildcard $(CLEAN_DIRS)) +mrproper: rm-dirs := $(wildcard $(MRPROPER_DIRS)) +quiet_cmd_rmdirs = $(if $(rm-dirs),CLEAN $(rm-dirs)) + cmd_rmdirs = rm -rf $(rm-dirs) + +clean: rm-files := $(wildcard $(CLEAN_FILES)) +mrproper: rm-files := $(wildcard $(MRPROPER_FILES)) +quiet_cmd_rmfiles = $(if $(rm-files),CLEAN $(rm-files)) + cmd_rmfiles = rm -rf $(rm-files) + clean: archclean $(clean-dirs) - $(call cmd,rmclean) + $(call cmd,rmdirs) + $(call cmd,rmfiles) @find . $(RCS_FIND_IGNORE) \ \( -name '*.[oas]' -o -name '*.ko' -o -name '.*.cmd' \ -o -name '.*.d' -o -name '.*.tmp' -o -name '*.mod.c' \) \ -type f -print | xargs rm -f -# mrproper - delete configuration + modules + core files +# mrproper # -quiet_cmd_mrproper = RM $$(MRPROPER_DIRS) + $$(MRPROPER_FILES) -cmd_mrproper = rm -rf $(MRPROPER_DIRS) && rm -f $(MRPROPER_FILES) -mrproper distclean: clean archmrproper - @echo ' Making $@ in the srctree' +distclean: mrproper +mrproper: clean archmrproper + $(call cmd,rmdirs) + $(call cmd,rmfiles) @find . $(RCS_FIND_IGNORE) \ \( -name '*.orig' -o -name '*.rej' -o -name '*~' \ -o -name '*.bak' -o -name '#*#' -o -name '.*.orig' \ -o -name '.*.rej' -o -size 0 \ -o -name '*%' -o -name '.*.cmd' -o -name 'core' \) \ -type f -print | xargs rm -f - $(call cmd,mrproper) # Generate tags for editors # --------------------------------------------------------------------------- diff -Nru a/arch/alpha/kernel/alpha_ksyms.c b/arch/alpha/kernel/alpha_ksyms.c --- a/arch/alpha/kernel/alpha_ksyms.c Sun Mar 14 14:20:06 2004 +++ b/arch/alpha/kernel/alpha_ksyms.c Sun Mar 14 14:20:06 2004 @@ -35,9 +35,6 @@ #include #include -#define __KERNEL_SYSCALLS__ -#include - extern struct hwrpb_struct *hwrpb; extern void dump_thread(struct pt_regs *, struct user *); extern spinlock_t rtc_lock; diff -Nru a/arch/alpha/kernel/smp.c b/arch/alpha/kernel/smp.c --- a/arch/alpha/kernel/smp.c Sun Mar 14 14:20:06 2004 +++ b/arch/alpha/kernel/smp.c Sun Mar 14 14:20:06 2004 @@ -39,9 +39,6 @@ #include #include -#define __KERNEL_SYSCALLS__ -#include - #include "proto.h" #include "irq_impl.h" diff -Nru a/arch/arm/common/sa1111-pcibuf.c b/arch/arm/common/sa1111-pcibuf.c --- a/arch/arm/common/sa1111-pcibuf.c Sun Mar 14 14:20:05 2004 +++ b/arch/arm/common/sa1111-pcibuf.c Sun Mar 14 14:20:05 2004 @@ -457,8 +457,8 @@ local_irq_restore(flags); } -void sa1111_dma_sync_single(struct device *dev, dma_addr_t dma_addr, - size_t size, enum dma_data_direction dir) +void sa1111_dma_sync_single_for_cpu(struct device *dev, dma_addr_t dma_addr, + size_t size, enum dma_data_direction dir) { unsigned long flags; @@ -472,8 +472,44 @@ local_irq_restore(flags); } -void sa1111_dma_sync_sg(struct device *dev, struct scatterlist *sg, - int nents, enum dma_data_direction dir) +void sa1111_dma_sync_single_for_device(struct device *dev, dma_addr_t dma_addr, + size_t size, enum dma_data_direction dir) +{ + unsigned long flags; + + dev_dbg(dev, "%s(ptr=%08lx,size=%d,dir=%x)\n", + __func__, dma_addr, size, dir); + + local_irq_save(flags); + + sync_single(dev, dma_addr, size, dir); + + local_irq_restore(flags); +} + +void sa1111_dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg, + int nents, enum dma_data_direction dir) +{ + unsigned long flags; + int i; + + dev_dbg(dev, "%s(sg=%p,nents=%d,dir=%x)\n", + __func__, sg, nents, dir); + + local_irq_save(flags); + + for (i = 0; i < nents; i++, sg++) { + dma_addr_t dma_addr = sg->dma_address; + unsigned int length = sg->length; + + sync_single(dev, dma_addr, length, dir); + } + + local_irq_restore(flags); +} + +void sa1111_dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg, + int nents, enum dma_data_direction dir) { unsigned long flags; int i; @@ -497,8 +533,10 @@ EXPORT_SYMBOL(sa1111_unmap_single); EXPORT_SYMBOL(sa1111_map_sg); EXPORT_SYMBOL(sa1111_unmap_sg); -EXPORT_SYMBOL(sa1111_dma_sync_single); -EXPORT_SYMBOL(sa1111_dma_sync_sg); +EXPORT_SYMBOL(sa1111_dma_sync_single_for_cpu); +EXPORT_SYMBOL(sa1111_dma_sync_single_for_device); +EXPORT_SYMBOL(sa1111_dma_sync_sg_for_cpu); +EXPORT_SYMBOL(sa1111_dma_sync_sg_for_device); /* **************************************** */ diff -Nru a/arch/cris/kernel/process.c b/arch/cris/kernel/process.c --- a/arch/cris/kernel/process.c Sun Mar 14 14:20:07 2004 +++ b/arch/cris/kernel/process.c Sun Mar 14 14:20:07 2004 @@ -91,8 +91,6 @@ * This file handles the architecture-dependent parts of process handling.. */ -#define __KERNEL_SYSCALLS__ - #include #include #include diff -Nru a/arch/h8300/kernel/sys_h8300.c b/arch/h8300/kernel/sys_h8300.c --- a/arch/h8300/kernel/sys_h8300.c Sun Mar 14 14:20:08 2004 +++ b/arch/h8300/kernel/sys_h8300.c Sun Mar 14 14:20:08 2004 @@ -260,11 +260,6 @@ return -EINVAL; } -asmlinkage long sys_ioperm(unsigned long from, unsigned long num, int on) -{ - return -ENOSYS; -} - /* sys_cacheflush -- no support. */ asmlinkage int sys_cacheflush (unsigned long addr, int scope, int cache, unsigned long len) diff -Nru a/arch/h8300/kernel/syscalls.S b/arch/h8300/kernel/syscalls.S --- a/arch/h8300/kernel/syscalls.S Sun Mar 14 14:20:06 2004 +++ b/arch/h8300/kernel/syscalls.S Sun Mar 14 14:20:06 2004 @@ -116,7 +116,7 @@ .long SYMBOL_NAME(sys_ni_syscall) /* old profil syscall holder */ .long SYMBOL_NAME(sys_statfs) .long SYMBOL_NAME(sys_fstatfs) /* 100 */ - .long SYMBOL_NAME(sys_ioperm) + .long SYMBOL_NAME(sys_ni_syscall) /* ioperm for i386 */ .long SYMBOL_NAME(sys_socketcall) .long SYMBOL_NAME(sys_syslog) .long SYMBOL_NAME(sys_setitimer) diff -Nru a/arch/i386/Kconfig b/arch/i386/Kconfig --- a/arch/i386/Kconfig Sun Mar 14 14:20:06 2004 +++ b/arch/i386/Kconfig Sun Mar 14 14:20:06 2004 @@ -269,9 +269,6 @@ use of some extended instructions, and passes appropriate optimization flags to GCC. -config MELAN - bool "Elan" - config MCRUSOE bool "Crusoe" help @@ -552,7 +549,7 @@ the 386 and 486, so nearly everyone can say Y here. config X86_MCE_NONFATAL - bool "Check for non-fatal errors on AMD Athlon/Duron / Intel Pentium 4" + tristate "Check for non-fatal errors on AMD Athlon/Duron / Intel Pentium 4" depends on X86_MCE help Enabling this feature starts a timer that triggers every 5 seconds which @@ -1241,17 +1238,6 @@ allocation as well as poisoning memory on free to catch use of freed memory. -config DEBUG_IOVIRT - bool "Memory mapped I/O debugging" - depends on DEBUG_KERNEL - help - Say Y here to get warned whenever an attempt is made to do I/O on - obviously invalid addresses such as those generated when ioremap() - calls are forgotten. Memory mapped I/O will go through an extra - check to catch access to unmapped ISA addresses, an access method - that can still be used by old drivers that are being ported from - 2.0/2.2. - config MAGIC_SYSRQ bool "Magic SysRq key" depends on DEBUG_KERNEL @@ -1348,7 +1334,7 @@ config X86_TRAMPOLINE bool - depends on SMP || X86_VISWS + depends on X86_SMP || (X86_VOYAGER && SMP) default y config PC diff -Nru a/arch/i386/boot/setup.S b/arch/i386/boot/setup.S --- a/arch/i386/boot/setup.S Sun Mar 14 14:20:07 2004 +++ b/arch/i386/boot/setup.S Sun Mar 14 14:20:07 2004 @@ -51,6 +51,8 @@ * projects 1572D, 1484D, 1386D, 1226DT * disk signature read by Matt Domsch * and Andrew Wilks September 2003 + * legacy CHS retreival by Patrick J. LoPresti + * March 2004 */ #include @@ -592,7 +594,11 @@ pushw %ds popw %es movw $EDDBUF, %bx - int $0x13 + pushw %dx # work around buggy BIOSes + stc # work around buggy BIOSes + int $0x13 + sti # work around buggy BIOSes + popw %dx jc disk_sig_done movl (EDDBUF+MBR_SIG_OFFSET), %eax movl %eax, (DISK80_SIG_BUFFER) # store success @@ -603,32 +609,34 @@ # This consists of two calls: # int 13h ah=41h "Check Extensions Present" # int 13h ah=48h "Get Device Parameters" +# int 13h ah=08h "Legacy Get Device Parameters" # # A buffer of size EDDMAXNR*(EDDEXTSIZE+EDDPARMSIZE) is reserved for our use # in the empty_zero_page at EDDBUF. The first four bytes of which are # used to store the device number, interface support map and version -# results from fn41. The following 74 bytes are used to store -# the results from fn48. Starting from device 80h, fn41, then fn48 +# results from fn41. The next four bytes are used to store the legacy +# cylinders, heads, and sectors from fn08. The following 74 bytes are used to +# store the results from fn48. Starting from device 80h, fn41, then fn48 # are called and their results stored in EDDBUF+n*(EDDEXTSIZE+EDDPARMIZE). # Then the pointer is incremented to store the data for the next call. # This repeats until either a device doesn't exist, or until EDDMAXNR # devices have been stored. -# The one tricky part is that ds:si always points four bytes into -# the structure, and the fn41 results are stored at offsets +# The one tricky part is that ds:si always points EDDEXTSIZE bytes into +# the structure, and the fn41 and fn08 results are stored at offsets # from there. This removes the need to increment the pointer for # every store, and leaves it ready for the fn48 call. # A second one-byte buffer, EDDNR, in the empty_zero_page stores # the number of BIOS devices which exist, up to EDDMAXNR. # In setup.c, copy_edd() stores both empty_zero_page buffers away -# for later use, as they would get overwritten otherwise. +# for later use, as they would get overwritten otherwise. # This code is sensitive to the size of the structs in edd.h -edd_start: +edd_start: # %ds points to the bootsector # result buffer for fn48 - movw $EDDBUF+EDDEXTSIZE, %si # in ds:si, fn41 results - # kept just before that + movw $EDDBUF+EDDEXTSIZE, %si # in ds:si, fn41 results + # kept just before that movb $0, (EDDNR) # zero value at EDDNR - movb $0x80, %dl # BIOS device 0x80 + movb $0x80, %dl # BIOS device 0x80 edd_check_ext: movb $CHECKEXTENSIONSPRESENT, %ah # Function 41 @@ -636,30 +644,56 @@ int $0x13 # make the call jc edd_done # no more BIOS devices - cmpw $EDDMAGIC2, %bx # is magic right? + cmpw $EDDMAGIC2, %bx # is magic right? jne edd_next # nope, next... - movb %dl, %ds:-4(%si) # store device number - movb %ah, %ds:-3(%si) # store version - movw %cx, %ds:-2(%si) # store extensions + movb %dl, %ds:-8(%si) # store device number + movb %ah, %ds:-7(%si) # store version + movw %cx, %ds:-6(%si) # store extensions incb (EDDNR) # note that we stored something - -edd_get_device_params: + +edd_get_device_params: movw $EDDPARMSIZE, %ds:(%si) # put size - movb $GETDEVICEPARAMETERS, %ah # Function 48 + movw $0x0, %ds:2(%si) # work around buggy BIOSes + movb $GETDEVICEPARAMETERS, %ah # Function 48 int $0x13 # make the call # Don't check for fail return # it doesn't matter. +edd_get_legacy_chs: + xorw %ax, %ax + movw %ax, %ds:-4(%si) + movw %ax, %ds:-2(%si) + # Ralf Brown's Interrupt List says to set ES:DI to + # 0000h:0000h "to guard against BIOS bugs" + pushw %es + movw %ax, %es + movw %ax, %di + pushw %dx # legacy call clobbers %dl + movb $LEGACYGETDEVICEPARAMETERS, %ah # Function 08 + int $0x13 # make the call + jc edd_legacy_done # failed + movb %cl, %al # Low 6 bits are max + andb $0x3F, %al # sector number + movb %al, %ds:-1(%si) # Record max sect + movb %dh, %ds:-2(%si) # Record max head number + movb %ch, %al # Low 8 bits of max cyl + shr $6, %cl + movb %cl, %ah # High 2 bits of max cyl + movw %ax, %ds:-4(%si) + +edd_legacy_done: + popw %dx + popw %es movw %si, %ax # increment si addw $EDDPARMSIZE+EDDEXTSIZE, %ax movw %ax, %si edd_next: - incb %dl # increment to next device - cmpb $EDDMAXNR, (EDDNR) # Out of space? + incb %dl # increment to next device + cmpb $EDDMAXNR, (EDDNR) # Out of space? jb edd_check_ext # keep looping - -edd_done: + +edd_done: #endif # Now we want to move to protected mode ... diff -Nru a/arch/i386/boot/tools/build.c b/arch/i386/boot/tools/build.c --- a/arch/i386/boot/tools/build.c Sun Mar 14 14:20:07 2004 +++ b/arch/i386/boot/tools/build.c Sun Mar 14 14:20:07 2004 @@ -150,10 +150,8 @@ sz = sb.st_size; fprintf (stderr, "System is %d kB\n", sz/1024); sys_size = (sz + 15) / 16; - /* 0x40000*16 = 4.0 MB, reasonable estimate for the current maximum */ - if (sys_size > (is_big_kernel ? 0x40000 : DEF_SYSSIZE)) - die("System is too big. Try using %smodules.", - is_big_kernel ? "" : "bzImage or "); + if (!is_big_kernel && sys_size > DEF_SYSSIZE) + die("System is too big. Try using bzImage or modules."); while (sz > 0) { int l, n; diff -Nru a/arch/i386/kernel/acpi/boot.c b/arch/i386/kernel/acpi/boot.c --- a/arch/i386/kernel/acpi/boot.c Sun Mar 14 14:20:08 2004 +++ b/arch/i386/kernel/acpi/boot.c Sun Mar 14 14:20:08 2004 @@ -128,7 +128,9 @@ return 0; } -#endif /* CONFIG_PCI_MMCONFIG */ +#else +#define acpi_parse_mcfg NULL +#endif /* !CONFIG_PCI_MMCONFIG */ #ifdef CONFIG_X86_LOCAL_APIC static int __init @@ -424,6 +426,8 @@ hpet_address); return 0; } +#else +#define acpi_parse_hpet NULL #endif /* detect the location of the ACPI PM Timer */ @@ -454,6 +458,8 @@ printk(KERN_INFO PREFIX "PM-Timer IO Port: %#x\n", pmtmr_ioport); return 0; } +#else +#define acpi_parse_fadt NULL #endif @@ -666,7 +672,7 @@ return error; } - (void) acpi_table_parse(ACPI_BOOT, acpi_parse_sbf); + acpi_table_parse(ACPI_BOOT, acpi_parse_sbf); /* * blacklist may disable ACPI entirely @@ -683,19 +689,9 @@ */ acpi_process_madt(); -#ifdef CONFIG_X86_PM_TIMER acpi_table_parse(ACPI_FADT, acpi_parse_fadt); -#endif - -#ifdef CONFIG_HPET_TIMER - (void) acpi_table_parse(ACPI_HPET, acpi_parse_hpet); -#endif - -#ifdef CONFIG_PCI_MMCONFIG - error = acpi_table_parse(ACPI_MCFG, acpi_parse_mcfg); - if (error) - printk(KERN_ERR PREFIX "Error %d parsing MCFG\n", error); -#endif + acpi_table_parse(ACPI_HPET, acpi_parse_hpet); + acpi_table_parse(ACPI_MCFG, acpi_parse_mcfg); return 0; } diff -Nru a/arch/i386/kernel/asm-offsets.c b/arch/i386/kernel/asm-offsets.c --- a/arch/i386/kernel/asm-offsets.c Sun Mar 14 14:20:07 2004 +++ b/arch/i386/kernel/asm-offsets.c Sun Mar 14 14:20:07 2004 @@ -4,9 +4,11 @@ * to extract and format the required data. */ +#include #include #include #include "sigframe.h" +#include #define DEFINE(sym, val) \ asm volatile("\n->" #sym " %0 " #val : : "i" (val)) @@ -28,4 +30,6 @@ DEFINE(RT_SIGFRAME_sigcontext, offsetof (struct rt_sigframe, uc.uc_mcontext)); + + DEFINE(PAGE_SIZE_asm, PAGE_SIZE); } diff -Nru a/arch/i386/kernel/bootflag.c b/arch/i386/kernel/bootflag.c --- a/arch/i386/kernel/bootflag.c Sun Mar 14 14:20:08 2004 +++ b/arch/i386/kernel/bootflag.c Sun Mar 14 14:20:08 2004 @@ -48,7 +48,7 @@ if(!parity(v)) v|=SBF_PARITY; - printk(KERN_INFO "Simple Boot Flag 0x%x\n", v); + printk(KERN_INFO "Simple Boot Flag at 0x%x set to 0x%x\n", sbf_port, v); spin_lock_irqsave(&rtc_lock, flags); CMOS_WRITE(v, sbf_port); diff -Nru a/arch/i386/kernel/cpu/mcheck/mce.c b/arch/i386/kernel/cpu/mcheck/mce.c --- a/arch/i386/kernel/cpu/mcheck/mce.c Sun Mar 14 14:20:08 2004 +++ b/arch/i386/kernel/cpu/mcheck/mce.c Sun Mar 14 14:20:08 2004 @@ -7,6 +7,7 @@ #include #include #include +#include #include #include @@ -17,6 +18,8 @@ int mce_disabled __initdata = 0; int nr_mce_banks; + +EXPORT_SYMBOL_GPL(nr_mce_banks); /* non-fatal.o */ /* Handle unconfigured int18 (should never happen) */ static asmlinkage void unexpected_machine_check(struct pt_regs * regs, long error_code) diff -Nru a/arch/i386/kernel/edd.c b/arch/i386/kernel/edd.c --- a/arch/i386/kernel/edd.c Sun Mar 14 14:20:06 2004 +++ b/arch/i386/kernel/edd.c Sun Mar 14 14:20:06 2004 @@ -1,8 +1,9 @@ /* * linux/arch/i386/kernel/edd.c - * Copyright (C) 2002, 2003 Dell Inc. + * Copyright (C) 2002, 2003, 2004 Dell Inc. * by Matt Domsch * disk80 signature by Matt Domsch, Andrew Wilks, and Sandeep K. Shandilya + * legacy CHS by Patrick J. LoPresti * * BIOS Enhanced Disk Drive Services (EDD) * conformant to T13 Committee www.t13.org @@ -60,7 +61,7 @@ MODULE_DESCRIPTION("sysfs interface to BIOS EDD information"); MODULE_LICENSE("GPL"); -#define EDD_VERSION "0.12 2004-Jan-26" +#define EDD_VERSION "0.13 2004-Mar-09" #define EDD_DEVICE_NAME_SIZE 16 #define REPORT_URL "http://linux.dell.com/edd/results.html" @@ -231,7 +232,7 @@ edd_show_raw_data(struct edd_device *edev, char *buf) { struct edd_info *info = edd_dev_get_info(edev); - ssize_t len = sizeof (*info) - 4; + ssize_t len = sizeof (info->params); if (!edev || !info || !buf) { return -EINVAL; } @@ -240,10 +241,10 @@ len = info->params.length; /* In case of buggy BIOSs */ - if (len > (sizeof(*info) - 4)) - len = sizeof(*info) - 4; + if (len > (sizeof(info->params))) + len = sizeof(info->params); - memcpy(buf, ((char *)info) + 4, len); + memcpy(buf, &info->params, len); return len; } @@ -321,6 +322,45 @@ } static ssize_t +edd_show_legacy_cylinders(struct edd_device *edev, char *buf) +{ + struct edd_info *info = edd_dev_get_info(edev); + char *p = buf; + if (!edev || !info || !buf) { + return -EINVAL; + } + + p += snprintf(p, left, "0x%x\n", info->legacy_cylinders); + return (p - buf); +} + +static ssize_t +edd_show_legacy_heads(struct edd_device *edev, char *buf) +{ + struct edd_info *info = edd_dev_get_info(edev); + char *p = buf; + if (!edev || !info || !buf) { + return -EINVAL; + } + + p += snprintf(p, left, "0x%x\n", info->legacy_heads); + return (p - buf); +} + +static ssize_t +edd_show_legacy_sectors(struct edd_device *edev, char *buf) +{ + struct edd_info *info = edd_dev_get_info(edev); + char *p = buf; + if (!edev || !info || !buf) { + return -EINVAL; + } + + p += snprintf(p, left, "0x%x\n", info->legacy_sectors); + return (p - buf); +} + +static ssize_t edd_show_default_cylinders(struct edd_device *edev, char *buf) { struct edd_info *info = edd_dev_get_info(edev); @@ -384,6 +424,33 @@ */ static int +edd_has_legacy_cylinders(struct edd_device *edev) +{ + struct edd_info *info = edd_dev_get_info(edev); + if (!edev || !info) + return -EINVAL; + return info->legacy_cylinders > 0; +} + +static int +edd_has_legacy_heads(struct edd_device *edev) +{ + struct edd_info *info = edd_dev_get_info(edev); + if (!edev || !info) + return -EINVAL; + return info->legacy_heads > 0; +} + +static int +edd_has_legacy_sectors(struct edd_device *edev) +{ + struct edd_info *info = edd_dev_get_info(edev); + if (!edev || !info) + return -EINVAL; + return info->legacy_sectors > 0; +} + +static int edd_has_default_cylinders(struct edd_device *edev) { struct edd_info *info = edd_dev_get_info(edev); @@ -452,6 +519,12 @@ static EDD_DEVICE_ATTR(extensions, 0444, edd_show_extensions, NULL); static EDD_DEVICE_ATTR(info_flags, 0444, edd_show_info_flags, NULL); static EDD_DEVICE_ATTR(sectors, 0444, edd_show_sectors, NULL); +static EDD_DEVICE_ATTR(legacy_cylinders, 0444, edd_show_legacy_cylinders, + edd_has_legacy_cylinders); +static EDD_DEVICE_ATTR(legacy_heads, 0444, edd_show_legacy_heads, + edd_has_legacy_heads); +static EDD_DEVICE_ATTR(legacy_sectors, 0444, edd_show_legacy_sectors, + edd_has_legacy_sectors); static EDD_DEVICE_ATTR(default_cylinders, 0444, edd_show_default_cylinders, edd_has_default_cylinders); static EDD_DEVICE_ATTR(default_heads, 0444, edd_show_default_heads, @@ -478,6 +551,9 @@ /* These attributes are conditional and only added for some devices. */ static struct edd_attribute * edd_attrs[] = { + &edd_attr_legacy_cylinders, + &edd_attr_legacy_heads, + &edd_attr_legacy_sectors, &edd_attr_default_cylinders, &edd_attr_default_heads, &edd_attr_default_sectors_per_track, diff -Nru a/arch/i386/kernel/head.S b/arch/i386/kernel/head.S --- a/arch/i386/kernel/head.S Sun Mar 14 14:20:06 2004 +++ b/arch/i386/kernel/head.S Sun Mar 14 14:20:06 2004 @@ -17,7 +17,7 @@ #include #include #include - +#include #define OLD_CL_MAGIC_ADDR 0x90020 #define OLD_CL_MAGIC 0xA33F @@ -40,49 +40,89 @@ #define X86_VENDOR_ID CPU_PARAMS+36 /* offset dependent on NCAPINTS */ /* - * Initialize page tables + * This is how much memory *in addition to the memory covered up to + * and including _end* we need mapped initially. We need one bit for + * each possible page, but only in low memory, which means + * 2^32/4096/8 = 128K worst case (4G/4G split.) + * + * Modulo rounding, each megabyte assigned here requires a kilobyte of + * memory, which is currently unreclaimed. + * + * This should be a multiple of a page. */ -#define INIT_PAGE_TABLES \ - movl $pg0 - __PAGE_OFFSET, %edi; \ - /* "007" doesn't mean with license to kill, but PRESENT+RW+USER */ \ - movl $007, %eax; \ -2: stosl; \ - add $0x1000, %eax; \ - cmp $empty_zero_page - __PAGE_OFFSET, %edi; \ - jne 2b; +#define INIT_MAP_BEYOND_END (128*1024) + /* - * swapper_pg_dir is the main page directory, address 0x00101000 - * - * On entry, %esi points to the real-mode code as a 32-bit pointer. + * 32-bit kernel entrypoint; only used by the boot CPU. On entry, + * %esi points to the real-mode code as a 32-bit pointer. + * CS and DS must be 4 GB flat segments, but we don't depend on + * any particular GDT layout, because we load our own as soon as we + * can. */ ENTRY(startup_32) -#ifdef CONFIG_X86_VISWS /* - * On SGI Visual Workstations boot CPU starts in protected mode. + * Set segments to known values. */ - orw %bx, %bx - jnz 1f - INIT_PAGE_TABLES - movl $swapper_pg_dir - __PAGE_OFFSET, %eax - movl %eax, %cr3 - lgdt boot_gdt -1: -#endif + cld + lgdt boot_gdt_descr - __PAGE_OFFSET + movl $(__BOOT_DS),%eax + movl %eax,%ds + movl %eax,%es + movl %eax,%fs + movl %eax,%gs /* - * Set segments to known values + * Initialize page tables. This creates a PDE and a set of page + * tables, which are located immediately beyond _end. The variable + * init_pg_tables_end is set up to point to the first "safe" location. + * + * Warning: don't use %esi or the stack in this code. However, %esp + * can be used as a GPR if you really need it... */ +page_pde_offset = (__PAGE_OFFSET >> 20); + + movl $(pg0 - __PAGE_OFFSET), %edi + movl $(swapper_pg_dir - __PAGE_OFFSET), %edx + movl $0x007, %eax /* 0x007 = PRESENT+RW+USER */ +10: + leal 0x007(%edi),%ecx /* Create PDE entry */ + movl %ecx,(%edx) /* Store identity PDE entry */ + movl %ecx,page_pde_offset(%edx) /* Store kernel PDE entry */ + addl $4,%edx + movl $1024, %ecx +11: + stosl + addl $0x1000,%eax + loop 11b + /* End condition: we must map up to and including INIT_MAP_BEYOND_END */ + /* bytes beyond the end of our own page tables; the +0x007 is the attribute bits */ + leal (INIT_MAP_BEYOND_END+0x007)(%edi),%ebp + cmpl %ebp,%eax + jb 10b + movl %edi,(init_pg_tables_end - __PAGE_OFFSET) + +#ifdef CONFIG_SMP + xorl %ebx,%ebx /* This is the boot CPU (BSP) */ + jmp 3f + +/* + * Non-boot CPU entry point; entered from trampoline.S + * We can't lgdt here, because lgdt itself uses a data segment, but + * we know the trampoline has already loaded the boot_gdt_table GDT + * for us. + */ +ENTRY(startup_32_smp) cld movl $(__BOOT_DS),%eax movl %eax,%ds movl %eax,%es movl %eax,%fs movl %eax,%gs -#ifdef CONFIG_SMP - orw %bx,%bx - jz 1f + + xorl %ebx,%ebx + incl %ebx /* This is a secondary processor (AP) */ /* * New page tables may be in 4Mbyte page mode and may @@ -99,37 +139,40 @@ * not yet offset PAGE_OFFSET.. */ #define cr4_bits mmu_cr4_features-__PAGE_OFFSET - cmpl $0,cr4_bits - je 3f + movl cr4_bits,%edx + andl %edx,%edx + jz 3f movl %cr4,%eax # Turn on paging options (PSE,PAE,..) - orl cr4_bits,%eax + orl %edx,%eax movl %eax,%cr4 - jmp 3f -1: -#endif - INIT_PAGE_TABLES + +3: +#endif /* CONFIG_SMP */ + /* * Enable paging */ -3: movl $swapper_pg_dir-__PAGE_OFFSET,%eax movl %eax,%cr3 /* set the page table pointer.. */ movl %cr0,%eax orl $0x80000000,%eax movl %eax,%cr0 /* ..and set paging (PG) bit */ - jmp 1f /* flush the prefetch-queue */ -1: - movl $1f,%eax - jmp *%eax /* make sure eip is relocated */ + ljmp $__BOOT_CS,$1f /* Clear prefetch and normalize %eip */ 1: /* Set up the stack pointer */ lss stack_start,%esp -#ifdef CONFIG_SMP - orw %bx,%bx - jz 1f /* Initial CPU cleans BSS */ +/* + * Initialize eflags. Some BIOS's leave bits like NT set. This would + * confuse the debugger if this code is traced. + * XXX - best to initialize before switching to protected mode. + */ pushl $0 popfl + +#ifdef CONFIG_SMP + andl %ebx,%ebx + jz 1f /* Initial CPU cleans BSS */ jmp checkCPUtype 1: #endif /* CONFIG_SMP */ @@ -142,21 +185,15 @@ movl $__bss_start,%edi movl $__bss_stop,%ecx subl %edi,%ecx - rep - stosb + shrl $2,%ecx + rep ; stosl /* * start system 32-bit setup. We need to re-do some of the things done * in 16-bit mode for the "real" operations. */ call setup_idt -/* - * Initialize eflags. Some BIOS's leave bits like NT set. This would - * confuse the debugger if this code is traced. - * XXX - best to initialize before switching to protected mode. - */ - pushl $0 - popfl + /* * Copy bootup parameters out of the way. First 2kB of * _empty_zero_page is for boot parameters, second 2kB @@ -273,7 +310,7 @@ call initialize_secondary jmp L6 1: -#endif +#endif /* CONFIG_SMP */ call start_kernel L6: jmp L6 # main should never return here, but @@ -309,6 +346,8 @@ * and the kernel moved to PAGE_OFFSET. Interrupts * are enabled elsewhere, when we can be relatively * sure everything is ok. + * + * Warning: %esi is live across this function. */ setup_idt: lea ignore_int,%edx @@ -332,7 +371,7 @@ /* This is the default interrupt "handler" :-) */ int_msg: - .asciz "Unknown interrupt\n" + .asciz "Unknown interrupt or fault at EIP %p %p %p\n" ALIGN ignore_int: cld @@ -344,9 +383,13 @@ movl $(__KERNEL_DS),%eax movl %eax,%ds movl %eax,%es + pushl 16(%esp) + pushl 24(%esp) + pushl 32(%esp) + pushl 40(%esp) pushl $int_msg call printk - popl %eax + addl $(5*4),%esp popl %ds popl %es popl %edx @@ -361,10 +404,17 @@ * segment size, and 32-bit linear address value: */ +.globl boot_gdt_descr .globl idt_descr .globl cpu_gdt_descr ALIGN +# early boot GDT descriptor (must use 1:1 address mapping) + .word 0 # 32 bit align gdt_desc.address +boot_gdt_descr: + .word __BOOT_DS+7 + .long boot_gdt_table - __PAGE_OFFSET + .word 0 # 32-bit align idt_desc.address idt_descr: .word IDT_ENTRIES*8-1 # idt contains 256 entries @@ -379,41 +429,25 @@ .fill NR_CPUS-1,8,0 # space for the other GDT descriptors /* - * This is initialized to create an identity-mapping at 0-8M (for bootup - * purposes) and another mapping of the 0-8M area at virtual address - * PAGE_OFFSET. + * swapper_pg_dir is the main page directory, address 0x00101000 + * + * This is initialized to create an identity-mapping at 0 (for bootup + * purposes) and another mapping at virtual address PAGE_OFFSET. The + * values put here should be all invalid (zero); the valid + * entries are created dynamically at boot time. + * + * The code creates enough page tables to map 0-_end, the page tables + * themselves, plus INIT_MAP_BEYOND_END bytes; see comment at beginning. */ .org 0x1000 ENTRY(swapper_pg_dir) - .long 0x00102007 - .long 0x00103007 - .fill BOOT_USER_PGD_PTRS-2,4,0 - /* default: 766 entries */ - .long 0x00102007 - .long 0x00103007 - /* default: 254 entries */ - .fill BOOT_KERNEL_PGD_PTRS-2,4,0 + .fill 1024,4,0 -/* - * The page tables are initialized to only 8MB here - the final page - * tables are set up later depending on memory size. - */ .org 0x2000 -ENTRY(pg0) - -.org 0x3000 -ENTRY(pg1) - -/* - * empty_zero_page must immediately follow the page tables ! (The - * initialization loop counts until empty_zero_page) - */ - -.org 0x4000 ENTRY(empty_zero_page) + .fill 4096,1,0 -.org 0x5000 - +.org 0x3000 /* * Real beginning of normal "text" segment */ @@ -428,20 +462,19 @@ .data /* - * The Global Descriptor Table contains 28 quadwords, per-CPU. - */ -#if defined(CONFIG_SMP) || defined(CONFIG_X86_VISWS) -/* * The boot_gdt_table must mirror the equivalent in setup.S and is - * used only by the trampoline for booting other CPUs + * used only for booting. */ .align L1_CACHE_BYTES ENTRY(boot_gdt_table) .fill GDT_ENTRY_BOOT_CS,8,0 .quad 0x00cf9a000000ffff /* kernel 4GB code at 0x00000000 */ .quad 0x00cf92000000ffff /* kernel 4GB data at 0x00000000 */ -#endif - .align L1_CACHE_BYTES + +/* + * The Global Descriptor Table contains 28 quadwords, per-CPU. + */ + .align PAGE_SIZE_asm ENTRY(cpu_gdt_table) .quad 0x0000000000000000 /* NULL descriptor */ .quad 0x0000000000000000 /* 0x0b reserved */ @@ -488,4 +521,3 @@ #ifdef CONFIG_SMP .fill (NR_CPUS-1)*GDT_ENTRIES,8,0 /* other CPU's GDT */ #endif - diff -Nru a/arch/i386/kernel/i386_ksyms.c b/arch/i386/kernel/i386_ksyms.c --- a/arch/i386/kernel/i386_ksyms.c Sun Mar 14 14:20:08 2004 +++ b/arch/i386/kernel/i386_ksyms.c Sun Mar 14 14:20:08 2004 @@ -88,10 +88,6 @@ EXPORT_SYMBOL(cpu_khz); EXPORT_SYMBOL(apm_info); -#ifdef CONFIG_DEBUG_IOVIRT -EXPORT_SYMBOL(__io_virt_debug); -#endif - EXPORT_SYMBOL_NOVERS(__down_failed); EXPORT_SYMBOL_NOVERS(__down_failed_interruptible); EXPORT_SYMBOL_NOVERS(__down_failed_trylock); diff -Nru a/arch/i386/kernel/pci-dma.c b/arch/i386/kernel/pci-dma.c --- a/arch/i386/kernel/pci-dma.c Sun Mar 14 14:20:06 2004 +++ b/arch/i386/kernel/pci-dma.c Sun Mar 14 14:20:06 2004 @@ -20,8 +20,9 @@ /* ignore region specifiers */ gfp &= ~(__GFP_DMA | __GFP_HIGHMEM); - if (dev == NULL || (*dev->dma_mask < 0xffffffff)) + if (dev == NULL || (dev->coherent_dma_mask < 0xffffffff)) gfp |= GFP_DMA; + ret = (void *)__get_free_pages(gfp, get_order(size)); if (ret != NULL) { diff -Nru a/arch/i386/kernel/process.c b/arch/i386/kernel/process.c --- a/arch/i386/kernel/process.c Sun Mar 14 14:20:05 2004 +++ b/arch/i386/kernel/process.c Sun Mar 14 14:20:05 2004 @@ -28,6 +28,7 @@ #include #include #include +#include #include #include #include @@ -222,7 +223,7 @@ if (regs->xcs & 3) printk(" ESP: %04x:%08lx",0xffff & regs->xss,regs->esp); - printk(" EFLAGS: %08lx %s\n",regs->eflags, print_tainted()); + printk(" EFLAGS: %08lx %s (%s)\n",regs->eflags, print_tainted(),UTS_RELEASE); printk("EAX: %08lx EBX: %08lx ECX: %08lx EDX: %08lx\n", regs->eax,regs->ebx,regs->ecx,regs->edx); printk("ESI: %08lx EDI: %08lx EBP: %08lx", diff -Nru a/arch/i386/kernel/setup.c b/arch/i386/kernel/setup.c --- a/arch/i386/kernel/setup.c Sun Mar 14 14:20:07 2004 +++ b/arch/i386/kernel/setup.c Sun Mar 14 14:20:07 2004 @@ -50,6 +50,11 @@ #include "setup_arch_pre.h" #include "mach_resources.h" +/* This value is set up by the early boot code to point to the value + immediately after the boot time page tables. It contains a *physical* + address, and must not be in the .bss segment! */ +unsigned long init_pg_tables_end __initdata = ~0UL; + int disable_pse __initdata = 0; static inline char * __init machine_specific_memory_setup(void); @@ -115,7 +120,6 @@ extern void dmi_scan_machine(void); extern void generic_apic_probe(char *); extern int root_mountflags; -extern char _end[]; unsigned long saved_videomode; @@ -790,7 +794,7 @@ * partially used pages are not usable - thus * we are rounding upwards: */ - start_pfn = PFN_UP(__pa(_end)); + start_pfn = PFN_UP(init_pg_tables_end); find_max_pfn(); @@ -828,6 +832,13 @@ */ reserve_bootmem(0, PAGE_SIZE); + /* could be an AMD 768MPX chipset. Reserve a page before VGA to prevent + PCI prefetch into it (errata #56). Usually the page is reserved anyways, + unless you have no PS/2 mouse plugged in. */ + if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD && + boot_cpu_data.x86 == 6) + reserve_bootmem(0xa0000 - 4096, 4096); + #ifdef CONFIG_SMP /* * But first pinch a few for the stack/trampoline stuff @@ -1102,7 +1113,7 @@ init_mm.start_code = (unsigned long) _text; init_mm.end_code = (unsigned long) _etext; init_mm.end_data = (unsigned long) _edata; - init_mm.brk = (unsigned long) _end; + init_mm.brk = init_pg_tables_end + PAGE_OFFSET; code_resource.start = virt_to_phys(_text); code_resource.end = virt_to_phys(_etext)-1; diff -Nru a/arch/i386/kernel/trampoline.S b/arch/i386/kernel/trampoline.S --- a/arch/i386/kernel/trampoline.S Sun Mar 14 14:20:07 2004 +++ b/arch/i386/kernel/trampoline.S Sun Mar 14 14:20:07 2004 @@ -23,9 +23,13 @@ * and IP is zero. Thus, data addresses need to be absolute * (no relocation) and are taken with regard to r_base. * - * If you work on this file, check the object module with objdump - * --full-contents --reloc to make sure there are no relocation - * entries except for the gdt one.. + * If you work on this file, check the object module with + * objdump --reloc to make sure there are no relocation + * entries except for: + * + * TYPE VALUE + * R_386_32 startup_32_smp + * R_386_32 boot_gdt_table */ #include @@ -42,7 +46,6 @@ mov %cs, %ax # Code and data in the same place mov %ax, %ds - mov $1, %bx # Flag an SMP trampoline cli # We should be safe anyway movl $0xA5A5A5A5, trampoline_data - r_base @@ -54,22 +57,18 @@ xor %ax, %ax inc %ax # protected mode (PE) bit lmsw %ax # into protected mode - jmp flush_instr -flush_instr: - ljmpl $__BOOT_CS, $0x00100000 - # jump to startup_32 in arch/i386/kernel/head.S + # flush prefetch and jump to startup_32_smp in arch/i386/kernel/head.S + ljmpl $__BOOT_CS, $(startup_32_smp-__PAGE_OFFSET) -boot_idt: - .word 0 # idt limit = 0 - .word 0, 0 # idt base = 0L - -# -# NOTE: here we actually use CPU#0's GDT - but that is OK, we reload -# the proper GDT shortly after booting up the secondary CPUs. -# -ENTRY(boot_gdt) + # These need to be in the same 64K segment as the above; + # hence we don't use the boot_gdt_descr defined in head.S +boot_gdt: .word __BOOT_DS + 7 # gdt limit - .long boot_gdt_table-__PAGE_OFFSET # gdt base = gdt (first SMP CPU) + .long boot_gdt_table-__PAGE_OFFSET # gdt base + +boot_idt: + .word 0 # idt limit = 0 + .long 0 # idt base = 0L .globl trampoline_end trampoline_end: diff -Nru a/arch/i386/kernel/traps.c b/arch/i386/kernel/traps.c --- a/arch/i386/kernel/traps.c Sun Mar 14 14:20:06 2004 +++ b/arch/i386/kernel/traps.c Sun Mar 14 14:20:06 2004 @@ -25,6 +25,7 @@ #include #include #include +#include #ifdef CONFIG_EISA #include @@ -175,9 +176,10 @@ ss = regs->xss & 0xffff; } print_modules(); - printk("CPU: %d\nEIP: %04x:[<%08lx>] %s\nEFLAGS: %08lx\n", - smp_processor_id(), 0xffff & regs->xcs, regs->eip, print_tainted(), regs->eflags); - + printk("CPU: %d\nEIP: %04x:[<%08lx>] %s\nEFLAGS: %08lx" + " (%s) \n", + smp_processor_id(), 0xffff & regs->xcs, regs->eip, + print_tainted(), regs->eflags, UTS_RELEASE); print_symbol("EIP is at %s\n", regs->eip); printk("eax: %08lx ebx: %08lx ecx: %08lx edx: %08lx\n", regs->eax, regs->ebx, regs->ecx, regs->edx); diff -Nru a/arch/i386/kernel/vmlinux.lds.S b/arch/i386/kernel/vmlinux.lds.S --- a/arch/i386/kernel/vmlinux.lds.S Sun Mar 14 14:20:06 2004 +++ b/arch/i386/kernel/vmlinux.lds.S Sun Mar 14 14:20:06 2004 @@ -105,9 +105,14 @@ __bss_start = .; /* BSS */ .bss : { *(.bss) } + . = ALIGN(4); __bss_stop = .; _end = . ; + + /* This is where the kernel creates the early boot page tables */ + . = ALIGN(4096); + pg0 = .; /* Sections to be discarded */ /DISCARD/ : { diff -Nru a/arch/i386/lib/Makefile b/arch/i386/lib/Makefile --- a/arch/i386/lib/Makefile Sun Mar 14 14:20:06 2004 +++ b/arch/i386/lib/Makefile Sun Mar 14 14:20:06 2004 @@ -9,4 +9,3 @@ lib-$(CONFIG_X86_USE_3DNOW) += mmx.o lib-$(CONFIG_HAVE_DEC_LOCK) += dec_and_lock.o -lib-$(CONFIG_DEBUG_IOVIRT) += iodebug.o diff -Nru a/arch/i386/lib/iodebug.c b/arch/i386/lib/iodebug.c --- a/arch/i386/lib/iodebug.c Sun Mar 14 14:20:08 2004 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,11 +0,0 @@ -#include - -void * __io_virt_debug(unsigned long x, const char *file, int line) -{ - if (x < PAGE_OFFSET) { - printk("io mapaddr 0x%05lx not valid at %s:%d!\n", x, file, line); - return __va(x); - } - return (void *)x; -} - diff -Nru a/arch/i386/mach-default/Makefile b/arch/i386/mach-default/Makefile --- a/arch/i386/mach-default/Makefile Sun Mar 14 14:20:06 2004 +++ b/arch/i386/mach-default/Makefile Sun Mar 14 14:20:06 2004 @@ -2,6 +2,4 @@ # Makefile for the linux kernel. # -EXTRA_CFLAGS += -I../kernel - obj-y := setup.o topology.o diff -Nru a/arch/i386/mach-es7000/Makefile b/arch/i386/mach-es7000/Makefile --- a/arch/i386/mach-es7000/Makefile Sun Mar 14 14:20:07 2004 +++ b/arch/i386/mach-es7000/Makefile Sun Mar 14 14:20:07 2004 @@ -2,6 +2,4 @@ # Makefile for the linux kernel. # -EXTRA_CFLAGS += -I../kernel - obj-y := setup.o topology.o es7000.o diff -Nru a/arch/i386/mach-pc9800/Makefile b/arch/i386/mach-pc9800/Makefile --- a/arch/i386/mach-pc9800/Makefile Sun Mar 14 14:20:08 2004 +++ b/arch/i386/mach-pc9800/Makefile Sun Mar 14 14:20:08 2004 @@ -2,6 +2,4 @@ # Makefile for the linux kernel. # -EXTRA_CFLAGS += -I../kernel - obj-y := setup.o topology.o diff -Nru a/arch/i386/mach-visws/Makefile b/arch/i386/mach-visws/Makefile --- a/arch/i386/mach-visws/Makefile Sun Mar 14 14:20:08 2004 +++ b/arch/i386/mach-visws/Makefile Sun Mar 14 14:20:08 2004 @@ -2,8 +2,6 @@ # Makefile for the linux kernel. # -EXTRA_CFLAGS += -I../kernel - obj-y := setup.o traps.o reboot.o obj-$(CONFIG_X86_VISWS_APIC) += visws_apic.o 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 Sun Mar 14 14:20:07 2004 +++ b/arch/i386/mach-voyager/voyager_smp.c Sun Mar 14 14:20:07 2004 @@ -623,7 +623,9 @@ ((virt_to_phys(page_table_copies)) & PAGE_MASK) | _PAGE_RW | _PAGE_USER | _PAGE_PRESENT; #else - ((unsigned long *)swapper_pg_dir)[0] = 0x102007; + ((unsigned long *)swapper_pg_dir)[0] = + (virt_to_phys(pg0) & PAGE_MASK) + | _PAGE_RW | _PAGE_USER | _PAGE_PRESENT; #endif if(quad_boot) { diff -Nru a/arch/i386/mm/discontig.c b/arch/i386/mm/discontig.c --- a/arch/i386/mm/discontig.c Sun Mar 14 14:20:07 2004 +++ b/arch/i386/mm/discontig.c Sun Mar 14 14:20:07 2004 @@ -66,7 +66,7 @@ extern void one_highpage_init(struct page *, int, int); extern struct e820map e820; -extern char _end; +extern unsigned long init_pg_tables_end; extern unsigned long highend_pfn, highstart_pfn; extern unsigned long max_low_pfn; extern unsigned long totalram_pages; @@ -237,7 +237,7 @@ reserve_pages = calculate_numa_remap_pages(); /* partially used pages are not usable - thus round upwards */ - system_start_pfn = min_low_pfn = PFN_UP(__pa(&_end)); + system_start_pfn = min_low_pfn = PFN_UP(init_pg_tables_end); find_max_pfn(); system_max_low_pfn = max_low_pfn = find_max_low_pfn(); diff -Nru a/arch/ia64/Kconfig b/arch/ia64/Kconfig --- a/arch/ia64/Kconfig Sun Mar 14 14:20:08 2004 +++ b/arch/ia64/Kconfig Sun Mar 14 14:20:08 2004 @@ -416,92 +416,13 @@ source "drivers/pcmcia/Kconfig" -source "drivers/parport/Kconfig" - endif endmenu -source "drivers/base/Kconfig" - -if !IA64_HP_SIM - -source "drivers/mtd/Kconfig" - -source "drivers/pnp/Kconfig" - -source "drivers/block/Kconfig" - -source "drivers/ide/Kconfig" - -source "drivers/ieee1394/Kconfig" - -source "drivers/message/i2o/Kconfig" - -source "drivers/md/Kconfig" - -source "drivers/message/fusion/Kconfig" - -endif - - -source "drivers/scsi/Kconfig" - -source "net/Kconfig" - - -if !IA64_HP_SIM - -source "drivers/isdn/Kconfig" - -source "drivers/cdrom/Kconfig" - -# -# input before char - char/joystick depends on it. As does USB. -# -source "drivers/input/Kconfig" - -source "drivers/char/Kconfig" - -source "drivers/i2c/Kconfig" - -#source drivers/misc/Config.in -source "drivers/media/Kconfig" - -endif - - -menu "Block devices" - depends on IA64_HP_SIM - -config BLK_DEV_LOOP - tristate "Loopback device support" - -config BLK_DEV_NBD - tristate "Network block device support" - depends on NET - -config BLK_DEV_RAM - tristate "RAM disk support" - -config BLK_DEV_RAM_SIZE - int "Default RAM disk size" - depends on BLK_DEV_RAM - default "4096" - -endmenu +source "drivers/Kconfig" source "fs/Kconfig" - -if !IA64_HP_SIM - -source "drivers/video/Kconfig" - -source "sound/Kconfig" - -source "drivers/usb/Kconfig" - -endif source "lib/Kconfig" diff -Nru a/arch/ia64/configs/zx1_defconfig b/arch/ia64/configs/zx1_defconfig --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/ia64/configs/zx1_defconfig Sun Mar 14 14:20:09 2004 @@ -0,0 +1,1078 @@ +# +# Automatically generated make config: don't edit +# + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y +# CONFIG_CLEAN_COMPILE is not set +CONFIG_STANDALONE=y +CONFIG_BROKEN=y +CONFIG_BROKEN_ON_SMP=y + +# +# General setup +# +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +CONFIG_BSD_PROCESS_ACCT=y +CONFIG_SYSCTL=y +CONFIG_LOG_BUF_SHIFT=17 +CONFIG_HOTPLUG=y +# 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 +# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set + +# +# Loadable module support +# +# CONFIG_MODULES is not set + +# +# Processor type and features +# +CONFIG_IA64=y +CONFIG_64BIT=y +CONFIG_MMU=y +CONFIG_RWSEM_XCHGADD_ALGORITHM=y +CONFIG_TIME_INTERPOLATION=y +CONFIG_EFI=y +# CONFIG_ITANIUM is not set +CONFIG_MCKINLEY=y +# CONFIG_IA64_GENERIC is not set +# CONFIG_IA64_DIG is not set +CONFIG_IA64_HP_ZX1=y +# CONFIG_IA64_SGI_SN2 is not set +# CONFIG_IA64_HP_SIM is not set +# CONFIG_IA64_PAGE_SIZE_4KB is not set +# CONFIG_IA64_PAGE_SIZE_8KB is not set +CONFIG_IA64_PAGE_SIZE_16KB=y +# CONFIG_IA64_PAGE_SIZE_64KB is not set +CONFIG_ACPI=y +CONFIG_ACPI_INTERPRETER=y +CONFIG_ACPI_KERNEL_CONFIG=y +CONFIG_IA64_L1_CACHE_SHIFT=7 +# CONFIG_MCKINLEY_ASTEP_SPECIFIC is not set +# CONFIG_NUMA is not set +CONFIG_VIRTUAL_MEM_MAP=y +CONFIG_IA64_MCA=y +# CONFIG_IA64_CYCLONE is not set +CONFIG_PM=y +CONFIG_IOSAPIC=y +CONFIG_FORCE_MAX_ZONEORDER=18 +# CONFIG_HUGETLB_PAGE_SIZE_4GB is not set +# CONFIG_HUGETLB_PAGE_SIZE_1GB is not set +# CONFIG_HUGETLB_PAGE_SIZE_256MB is not set +CONFIG_HUGETLB_PAGE_SIZE_64MB=y +# CONFIG_HUGETLB_PAGE_SIZE_16MB is not set +# CONFIG_HUGETLB_PAGE_SIZE_4MB is not set +# CONFIG_HUGETLB_PAGE_SIZE_1MB is not set +# CONFIG_HUGETLB_PAGE_SIZE_256KB is not set +CONFIG_IA64_PAL_IDLE=y +CONFIG_SMP=y +CONFIG_NR_CPUS=16 +# CONFIG_PREEMPT is not set +CONFIG_HAVE_DEC_LOCK=y +CONFIG_IA32_SUPPORT=y +CONFIG_COMPAT=y +CONFIG_PERFMON=y +CONFIG_IA64_PALINFO=y +CONFIG_EFI_VARS=y +CONFIG_BINFMT_ELF=y +CONFIG_BINFMT_MISC=y + +# +# ACPI (Advanced Configuration and Power Interface) Support +# +CONFIG_ACPI_BOOT=y +CONFIG_ACPI_BUTTON=y +CONFIG_ACPI_FAN=y +CONFIG_ACPI_PROCESSOR=y +CONFIG_ACPI_THERMAL=y +# CONFIG_ACPI_DEBUG is not set +CONFIG_ACPI_BUS=y +CONFIG_ACPI_POWER=y +CONFIG_ACPI_PCI=y +CONFIG_ACPI_SYSTEM=y +# CONFIG_ACPI_RELAXED_AML is not set +CONFIG_PCI=y +CONFIG_PCI_DOMAINS=y +CONFIG_PCI_LEGACY_PROC=y +CONFIG_PCI_NAMES=y + +# +# PCI Hotplug Support +# +CONFIG_HOTPLUG_PCI=y +# CONFIG_HOTPLUG_PCI_FAKE is not set +CONFIG_HOTPLUG_PCI_ACPI=y +# CONFIG_HOTPLUG_PCI_CPCI is not set +# CONFIG_HOTPLUG_PCI_PCIE is not set +# CONFIG_HOTPLUG_PCI_SHPC is not set + +# +# PCMCIA/CardBus support +# +# CONFIG_PCMCIA is not set + +# +# Parallel port support +# +# CONFIG_PARPORT is not set + +# +# Generic Driver Options +# +# CONFIG_FW_LOADER is not set + +# +# Memory Technology Devices (MTD) +# +# CONFIG_MTD is not set + +# +# Plug and Play support +# + +# +# Block devices +# +# CONFIG_BLK_DEV_FD is not set +# CONFIG_BLK_CPQ_DA is not set +# CONFIG_BLK_CPQ_CISS_DA is not set +# CONFIG_BLK_DEV_DAC960 is not set +# CONFIG_BLK_DEV_UMEM is not set +CONFIG_BLK_DEV_LOOP=y +# CONFIG_BLK_DEV_CRYPTOLOOP is not set +# CONFIG_BLK_DEV_NBD is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_SIZE=4096 +CONFIG_BLK_DEV_INITRD=y +# CONFIG_DCSSBLK is not set + +# +# ATA/ATAPI/MFM/RLL support +# +CONFIG_IDE=y +CONFIG_BLK_DEV_IDE=y + +# +# Please see Documentation/ide.txt for help/info on IDE drives +# +CONFIG_BLK_DEV_IDEDISK=y +# CONFIG_IDEDISK_MULTI_MODE is not set +# 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 +# CONFIG_IDE_TASKFILE_IO is not set + +# +# IDE chipset support/bugfixes +# +CONFIG_IDE_GENERIC=y +CONFIG_BLK_DEV_IDEPCI=y +CONFIG_IDEPCI_SHARE_IRQ=y +# CONFIG_BLK_DEV_OFFBOARD is not set +CONFIG_BLK_DEV_GENERIC=y +# CONFIG_BLK_DEV_OPTI621 is not set +CONFIG_BLK_DEV_IDEDMA_PCI=y +# CONFIG_BLK_DEV_IDEDMA_FORCED is not set +# CONFIG_IDEDMA_PCI_AUTO is not set +CONFIG_BLK_DEV_ADMA=y +# CONFIG_BLK_DEV_AEC62XX is not set +# CONFIG_BLK_DEV_ALI15X3 is not set +# CONFIG_BLK_DEV_AMD74XX is not set +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_CS5530 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_PDC202XX_OLD is not set +# CONFIG_BLK_DEV_PDC202XX_NEW is not set +# CONFIG_BLK_DEV_SVWKS is not set +# CONFIG_BLK_DEV_SIIMAGE is not set +# CONFIG_BLK_DEV_SLC90E66 is not set +# CONFIG_BLK_DEV_TRM290 is not set +# CONFIG_BLK_DEV_VIA82CXXX is not set +CONFIG_BLK_DEV_IDEDMA=y +# CONFIG_IDEDMA_IVB is not set +# CONFIG_IDEDMA_AUTO is not set +# CONFIG_DMA_NONPCI is not set +# CONFIG_BLK_DEV_HD is not set + +# +# IEEE 1394 (FireWire) support +# +# CONFIG_IEEE1394 is not set + +# +# I2O device support +# + +# +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set + +# +# Fusion MPT device support +# +CONFIG_FUSION=y +CONFIG_FUSION_BOOT=y +CONFIG_FUSION_MAX_SGE=40 + +# +# SCSI device support +# +CONFIG_SCSI=y +CONFIG_SCSI_PROC_FS=y + +# +# SCSI support type (disk, tape, CD-ROM) +# +CONFIG_BLK_DEV_SD=y +CONFIG_CHR_DEV_ST=y +CONFIG_CHR_DEV_OSST=y +CONFIG_BLK_DEV_SR=y +CONFIG_BLK_DEV_SR_VENDOR=y +CONFIG_CHR_DEV_SG=y + +# +# Some SCSI devices (e.g. CD jukebox) support multiple LUNs +# +CONFIG_SCSI_MULTI_LUN=y +CONFIG_SCSI_REPORT_LUNS=y +CONFIG_SCSI_CONSTANTS=y +CONFIG_SCSI_LOGGING=y + +# +# SCSI low-level drivers +# +# CONFIG_BLK_DEV_3W_XXXX_RAID is not set +# CONFIG_SCSI_ACARD is not set +# CONFIG_SCSI_AACRAID is not set +# CONFIG_SCSI_AIC7XXX is not set +# CONFIG_SCSI_AIC7XXX_OLD is not set +# CONFIG_SCSI_AIC79XX is not set +# CONFIG_SCSI_ADVANSYS is not set +CONFIG_SCSI_MEGARAID=y +# CONFIG_SCSI_SATA is not set +# CONFIG_SCSI_BUSLOGIC is not set +# CONFIG_SCSI_CPQFCTS is not set +# CONFIG_SCSI_DMX3191D is not set +# CONFIG_SCSI_EATA is not set +# CONFIG_SCSI_EATA_PIO is not set +# CONFIG_SCSI_FUTURE_DOMAIN is not set +# CONFIG_SCSI_GDTH is not set +# CONFIG_SCSI_IPS is not set +# CONFIG_SCSI_INITIO is not set +# CONFIG_SCSI_INIA100 is not set +CONFIG_SCSI_SYM53C8XX_2=y +CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE=1 +CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS=16 +CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64 +# CONFIG_SCSI_SYM53C8XX_IOMAPPED is not set +# CONFIG_SCSI_PCI2000 is not set +# CONFIG_SCSI_PCI2220I is not set +# CONFIG_SCSI_QLOGIC_ISP is not set +# CONFIG_SCSI_QLOGIC_FC is not set +CONFIG_SCSI_QLOGIC_1280=y +CONFIG_SCSI_QLA2XXX=y +# CONFIG_SCSI_QLA21XX is not set +# CONFIG_SCSI_QLA22XX is not set +# CONFIG_SCSI_QLA2300 is not set +# CONFIG_SCSI_QLA2322 is not set +# CONFIG_SCSI_QLA6312 is not set +# CONFIG_SCSI_QLA6322 is not set +# CONFIG_SCSI_DC395x is not set +# CONFIG_SCSI_DC390T is not set +# CONFIG_SCSI_DEBUG is not set + +# +# Networking support +# +CONFIG_NET=y + +# +# Networking options +# +CONFIG_PACKET=y +# CONFIG_PACKET_MMAP is not set +# CONFIG_NETLINK_DEV is not set +CONFIG_UNIX=y +# CONFIG_NET_KEY is not set +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +# CONFIG_IP_ADVANCED_ROUTER is not set +# CONFIG_IP_PNP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_IP_MROUTE 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_INET_IPCOMP is not set + +# +# IP: Virtual Server Configuration +# +# CONFIG_IP_VS is not set +# CONFIG_IPV6 is not set +# CONFIG_DECNET is not set +# CONFIG_BRIDGE is not set +CONFIG_NETFILTER=y +# CONFIG_NETFILTER_DEBUG 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=y +# CONFIG_IP_NF_ARPFILTER is not set +# CONFIG_IP_NF_ARP_MANGLE is not set +# CONFIG_IP_NF_COMPAT_IPCHAINS is not set +# CONFIG_IP_NF_COMPAT_IPFWADM 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_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_ATALK 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 +# +# CONFIG_NET_SCHED is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +CONFIG_NETDEVICES=y + +# +# ARCnet devices +# +# CONFIG_ARCNET is not set +CONFIG_DUMMY=y +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set + +# +# Ethernet (10 or 100Mbit) +# +CONFIG_NET_ETHERNET=y +CONFIG_MII=y +# CONFIG_HAPPYMEAL is not set +# CONFIG_SUNGEM is not set +# CONFIG_NET_VENDOR_3COM is not set + +# +# Tulip family network device support +# +CONFIG_NET_TULIP=y +# CONFIG_DE2104X is not set +CONFIG_TULIP=y +CONFIG_TULIP_MWI=y +CONFIG_TULIP_MMIO=y +CONFIG_TULIP_NAPI=y +CONFIG_TULIP_NAPI_HW_MITIGATION=y +# CONFIG_DE4X5 is not set +# CONFIG_WINBOND_840 is not set +# CONFIG_DM9102 is not set +# CONFIG_HP100 is not set +CONFIG_NET_PCI=y +# CONFIG_PCNET32 is not set +# CONFIG_AMD8111_ETH is not set +# CONFIG_ADAPTEC_STARFIRE is not set +# CONFIG_B44 is not set +# CONFIG_FORCEDETH is not set +# CONFIG_DGRS is not set +# CONFIG_EEPRO100 is not set +CONFIG_E100=y +# CONFIG_E100_NAPI is not set +# 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 +# CONFIG_SUNDANCE is not set +# CONFIG_VIA_RHINE is not set + +# +# Ethernet (1000 Mbit) +# +# CONFIG_ACENIC is not set +# CONFIG_DL2K is not set +CONFIG_E1000=y +# CONFIG_E1000_NAPI is not set +# CONFIG_NS83820 is not set +# 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 + +# +# 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 + +# +# Wireless LAN (non-hamradio) +# +# CONFIG_NET_RADIO is not set + +# +# Token Ring devices +# +# CONFIG_TR is not set +# CONFIG_NET_FC is not set +# CONFIG_SHAPER is not set + +# +# Wan interfaces +# +# CONFIG_WAN is not set + +# +# Amateur Radio support +# +# CONFIG_HAMRADIO is not set + +# +# IrDA (infrared) support +# +# CONFIG_IRDA is not set + +# +# Bluetooth support +# +# CONFIG_BT is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN is not set + +# +# Input device support +# +CONFIG_INPUT=y + +# +# Userland interfaces +# +CONFIG_INPUT_MOUSEDEV=y +CONFIG_INPUT_MOUSEDEV_PSAUX=y +CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 +CONFIG_INPUT_JOYDEV=y +# CONFIG_INPUT_TSDEV is not set +CONFIG_INPUT_EVDEV=y +# CONFIG_INPUT_EVBUG is not set + +# +# Input I/O drivers +# +# CONFIG_GAMEPORT is not set +CONFIG_SOUND_GAMEPORT=y +CONFIG_SERIO=y +# CONFIG_SERIO_I8042 is not set +# CONFIG_SERIO_SERPORT is not set +# CONFIG_SERIO_CT82C710 is not set +# CONFIG_SERIO_PCIPS2 is not set + +# +# Input Device Drivers +# +# CONFIG_INPUT_KEYBOARD is not set +# CONFIG_INPUT_MOUSE is not set +# CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TOUCHSCREEN is not set +# CONFIG_INPUT_MISC is not set + +# +# Character devices +# +CONFIG_VT=y +CONFIG_VT_CONSOLE=y +CONFIG_HW_CONSOLE=y +# CONFIG_SERIAL_NONSTANDARD is not set + +# +# Serial drivers +# +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y +CONFIG_SERIAL_8250_HCDP=y +CONFIG_SERIAL_8250_ACPI=y +CONFIG_SERIAL_8250_NR_UARTS=8 +CONFIG_SERIAL_8250_EXTENDED=y +CONFIG_SERIAL_8250_SHARE_IRQ=y +# CONFIG_SERIAL_8250_DETECT_IRQ is not set +# CONFIG_SERIAL_8250_MULTIPORT is not set +# CONFIG_SERIAL_8250_RSA is not set + +# +# Non-8250 serial port support +# +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +CONFIG_UNIX98_PTYS=y +CONFIG_LEGACY_PTYS=y +CONFIG_LEGACY_PTY_COUNT=256 + +# +# Mice +# +# CONFIG_BUSMOUSE is not set +# CONFIG_QIC02_TAPE is not set + +# +# IPMI +# +# CONFIG_IPMI_HANDLER is not set + +# +# Watchdog Cards +# +# CONFIG_WATCHDOG is not set +# CONFIG_HW_RANDOM is not set +# CONFIG_NVRAM is not set +# CONFIG_GEN_RTC is not set +CONFIG_EFI_RTC=y +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set +# CONFIG_APPLICOM is not set + +# +# Ftape, the floppy tape device driver +# +# CONFIG_FTAPE is not set +CONFIG_AGP=y +CONFIG_AGP_HP_ZX1=y +CONFIG_DRM=y +# CONFIG_DRM_TDFX is not set +# CONFIG_DRM_GAMMA is not set +# CONFIG_DRM_R128 is not set +CONFIG_DRM_RADEON=y +# CONFIG_DRM_MGA is not set +# CONFIG_DRM_SIS is not set +# CONFIG_RAW_DRIVER is not set + +# +# I2C support +# +CONFIG_I2C=y +CONFIG_I2C_CHARDEV=y + +# +# I2C Algorithms +# +CONFIG_I2C_ALGOBIT=y +CONFIG_I2C_ALGOPCF=y + +# +# I2C Hardware Bus support +# +# CONFIG_I2C_ALI1535 is not set +# CONFIG_I2C_ALI15X3 is not set +# CONFIG_I2C_AMD756 is not set +# CONFIG_I2C_AMD8111 is not set +# CONFIG_I2C_ELV is not set +# CONFIG_I2C_I801 is not set +# CONFIG_I2C_I810 is not set +# CONFIG_I2C_ISA is not set +# CONFIG_I2C_NFORCE2 is not set +# CONFIG_I2C_PARPORT_LIGHT is not set +# CONFIG_I2C_PROSAVAGE is not set +# CONFIG_I2C_SAVAGE4 is not set +# CONFIG_SCx200_ACB is not set +# CONFIG_I2C_SIS5595 is not set +# CONFIG_I2C_SIS630 is not set +# CONFIG_I2C_SIS96X is not set +# CONFIG_I2C_VELLEMAN is not set +# CONFIG_I2C_VIA is not set +# CONFIG_I2C_VIAPRO is not set +# CONFIG_I2C_VOODOO3 is not set + +# +# I2C Hardware Sensors Chip support +# +# CONFIG_I2C_SENSOR is not set +# CONFIG_SENSORS_ADM1021 is not set +# CONFIG_SENSORS_ASB100 is not set +# CONFIG_SENSORS_EEPROM is not set +# CONFIG_SENSORS_FSCHER is not set +# CONFIG_SENSORS_GL518SM is not set +# CONFIG_SENSORS_IT87 is not set +# CONFIG_SENSORS_LM75 is not set +# CONFIG_SENSORS_LM78 is not set +# CONFIG_SENSORS_LM83 is not set +# CONFIG_SENSORS_LM85 is not set +# CONFIG_SENSORS_LM90 is not set +# CONFIG_SENSORS_VIA686A is not set +# CONFIG_SENSORS_W83781D is not set +# CONFIG_SENSORS_W83L785TS is not set +# CONFIG_I2C_DEBUG_CORE is not set +# CONFIG_I2C_DEBUG_BUS is not set +# CONFIG_I2C_DEBUG_CHIP is not set + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# Digital Video Broadcasting Devices +# +# CONFIG_DVB is not set + +# +# File systems +# +CONFIG_EXT2_FS=y +CONFIG_EXT2_FS_XATTR=y +# CONFIG_EXT2_FS_POSIX_ACL is not set +# CONFIG_EXT2_FS_SECURITY is not set +CONFIG_EXT3_FS=y +CONFIG_EXT3_FS_XATTR=y +# CONFIG_EXT3_FS_POSIX_ACL is not set +# CONFIG_EXT3_FS_SECURITY is not set +CONFIG_JBD=y +# CONFIG_JBD_DEBUG is not set +CONFIG_FS_MBCACHE=y +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set +# CONFIG_XFS_FS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_ROMFS_FS is not set +# CONFIG_QUOTA is not set +CONFIG_AUTOFS_FS=y +# CONFIG_AUTOFS4_FS is not set + +# +# CD-ROM/DVD Filesystems +# +CONFIG_ISO9660_FS=y +CONFIG_JOLIET=y +# CONFIG_ZISOFS is not set +CONFIG_UDF_FS=y + +# +# DOS/FAT/NT Filesystems +# +CONFIG_FAT_FS=y +CONFIG_MSDOS_FS=y +CONFIG_VFAT_FS=y +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +CONFIG_PROC_KCORE=y +# CONFIG_DEVFS_FS is not set +# CONFIG_DEVPTS_FS_XATTR is not set +CONFIG_TMPFS=y +CONFIG_HUGETLBFS=y +CONFIG_HUGETLB_PAGE=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_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_CRAMFS is not set +# CONFIG_VXFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set + +# +# Network File Systems +# +CONFIG_NFS_FS=y +CONFIG_NFS_V3=y +CONFIG_NFS_V4=y +# CONFIG_NFS_DIRECTIO is not set +CONFIG_NFSD=y +CONFIG_NFSD_V3=y +# CONFIG_NFSD_V4 is not set +# CONFIG_NFSD_TCP is not set +CONFIG_LOCKD=y +CONFIG_LOCKD_V4=y +CONFIG_EXPORTFS=y +CONFIG_SUNRPC=y +CONFIG_SUNRPC_GSS=y +# 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_AFS_FS is not set + +# +# Partition Types +# +CONFIG_PARTITION_ADVANCED=y +# CONFIG_ACORN_PARTITION is not set +# CONFIG_OSF_PARTITION is not set +# CONFIG_AMIGA_PARTITION is not set +# CONFIG_ATARI_PARTITION is not set +# CONFIG_MAC_PARTITION is not set +CONFIG_MSDOS_PARTITION=y +# CONFIG_BSD_DISKLABEL is not set +# CONFIG_MINIX_SUBPARTITION is not set +# CONFIG_SOLARIS_X86_PARTITION 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 +CONFIG_EFI_PARTITION=y + +# +# Native Language Support +# +CONFIG_NLS=y +CONFIG_NLS_DEFAULT="iso8859-1" +CONFIG_NLS_CODEPAGE_437=y +CONFIG_NLS_CODEPAGE_737=y +CONFIG_NLS_CODEPAGE_775=y +CONFIG_NLS_CODEPAGE_850=y +CONFIG_NLS_CODEPAGE_852=y +CONFIG_NLS_CODEPAGE_855=y +CONFIG_NLS_CODEPAGE_857=y +CONFIG_NLS_CODEPAGE_860=y +CONFIG_NLS_CODEPAGE_861=y +CONFIG_NLS_CODEPAGE_862=y +CONFIG_NLS_CODEPAGE_863=y +CONFIG_NLS_CODEPAGE_864=y +CONFIG_NLS_CODEPAGE_865=y +CONFIG_NLS_CODEPAGE_866=y +CONFIG_NLS_CODEPAGE_869=y +CONFIG_NLS_CODEPAGE_936=y +CONFIG_NLS_CODEPAGE_950=y +CONFIG_NLS_CODEPAGE_932=y +CONFIG_NLS_CODEPAGE_949=y +CONFIG_NLS_CODEPAGE_874=y +CONFIG_NLS_ISO8859_8=y +# CONFIG_NLS_CODEPAGE_1250 is not set +CONFIG_NLS_CODEPAGE_1251=y +CONFIG_NLS_ISO8859_1=y +CONFIG_NLS_ISO8859_2=y +CONFIG_NLS_ISO8859_3=y +CONFIG_NLS_ISO8859_4=y +CONFIG_NLS_ISO8859_5=y +CONFIG_NLS_ISO8859_6=y +CONFIG_NLS_ISO8859_7=y +CONFIG_NLS_ISO8859_9=y +CONFIG_NLS_ISO8859_13=y +CONFIG_NLS_ISO8859_14=y +CONFIG_NLS_ISO8859_15=y +CONFIG_NLS_KOI8_R=y +CONFIG_NLS_KOI8_U=y +CONFIG_NLS_UTF8=y + +# +# Graphics support +# +CONFIG_FB=y +# CONFIG_FB_CIRRUS is not set +# CONFIG_FB_PM2 is not set +# CONFIG_FB_CYBER2000 is not set +# CONFIG_FB_IMSTT is not set +# CONFIG_FB_RIVA is not set +# CONFIG_FB_MATROX is not set +# CONFIG_FB_RADEON_OLD is not set +CONFIG_FB_RADEON=y +CONFIG_FB_RADEON_I2C=y +CONFIG_FB_RADEON_DEBUG=y +# CONFIG_FB_ATY128 is not set +# CONFIG_FB_ATY is not set +# CONFIG_FB_SIS is not set +# CONFIG_FB_NEOMAGIC is not set +# CONFIG_FB_KYRO is not set +# CONFIG_FB_3DFX is not set +# CONFIG_FB_VOODOO1 is not set +# CONFIG_FB_TRIDENT is not set +# CONFIG_FB_PM3 is not set +# CONFIG_FB_VIRTUAL is not set + +# +# Console display driver support +# +CONFIG_VGA_CONSOLE=y +# CONFIG_MDA_CONSOLE is not set +CONFIG_DUMMY_CONSOLE=y +CONFIG_FRAMEBUFFER_CONSOLE=y +CONFIG_PCI_CONSOLE=y +# CONFIG_FONTS is not set +CONFIG_FONT_8x8=y +CONFIG_FONT_8x16=y + +# +# Logo configuration +# +CONFIG_LOGO=y +# CONFIG_LOGO_LINUX_MONO is not set +# CONFIG_LOGO_LINUX_VGA16 is not set +CONFIG_LOGO_LINUX_CLUT224=y + +# +# Sound +# +CONFIG_SOUND=y + +# +# Advanced Linux Sound Architecture +# +CONFIG_SND=y +CONFIG_SND_SEQUENCER=y +# CONFIG_SND_SEQ_DUMMY is not set +CONFIG_SND_OSSEMUL=y +CONFIG_SND_MIXER_OSS=y +CONFIG_SND_PCM_OSS=y +CONFIG_SND_SEQUENCER_OSS=y +# CONFIG_SND_VERBOSE_PRINTK is not set +# CONFIG_SND_DEBUG is not set + +# +# Generic devices +# +# CONFIG_SND_DUMMY is not set +# CONFIG_SND_VIRMIDI is not set +# CONFIG_SND_MTPAV is not set +# CONFIG_SND_SERIAL_U16550 is not set +# CONFIG_SND_MPU401 is not set + +# +# PCI devices +# +# CONFIG_SND_ALI5451 is not set +# CONFIG_SND_AZT3328 is not set +# CONFIG_SND_BT87X is not set +# CONFIG_SND_CS46XX is not set +# CONFIG_SND_CS4281 is not set +# CONFIG_SND_EMU10K1 is not set +# CONFIG_SND_KORG1212 is not set +# CONFIG_SND_NM256 is not set +# CONFIG_SND_RME32 is not set +# CONFIG_SND_RME96 is not set +# CONFIG_SND_RME9652 is not set +# CONFIG_SND_HDSP is not set +# CONFIG_SND_TRIDENT is not set +# CONFIG_SND_YMFPCI is not set +# CONFIG_SND_ALS4000 is not set +# CONFIG_SND_CMIPCI is not set +# CONFIG_SND_ENS1370 is not set +# CONFIG_SND_ENS1371 is not set +# CONFIG_SND_ES1938 is not set +# CONFIG_SND_ES1968 is not set +# CONFIG_SND_MAESTRO3 is not set +CONFIG_SND_FM801=y +# CONFIG_SND_ICE1712 is not set +# CONFIG_SND_ICE1724 is not set +# CONFIG_SND_INTEL8X0 is not set +# CONFIG_SND_SONICVIBES is not set +# CONFIG_SND_VIA82XX is not set +# CONFIG_SND_VX222 is not set + +# +# ALSA USB devices +# +# CONFIG_SND_USB_AUDIO is not set + +# +# Open Sound System +# +# CONFIG_SOUND_PRIME is not set + +# +# USB support +# +CONFIG_USB=y +# CONFIG_USB_DEBUG is not set + +# +# Miscellaneous USB options +# +# CONFIG_USB_DEVICEFS is not set +CONFIG_USB_BANDWIDTH=y +# CONFIG_USB_DYNAMIC_MINORS is not set + +# +# USB Host Controller Drivers +# +CONFIG_USB_EHCI_HCD=y +CONFIG_USB_OHCI_HCD=y +CONFIG_USB_UHCI_HCD=y + +# +# USB Device Class drivers +# +# CONFIG_USB_AUDIO is not set +# CONFIG_USB_BLUETOOTH_TTY is not set +# CONFIG_USB_MIDI is not set +# CONFIG_USB_ACM is not set +# CONFIG_USB_PRINTER is not set +CONFIG_USB_STORAGE=y +# CONFIG_USB_STORAGE_DEBUG is not set +# CONFIG_USB_STORAGE_DATAFAB is not set +# CONFIG_USB_STORAGE_FREECOM is not set +# CONFIG_USB_STORAGE_ISD200 is not set +# CONFIG_USB_STORAGE_DPCM is not set +# CONFIG_USB_STORAGE_HP8200e is not set +# CONFIG_USB_STORAGE_SDDR09 is not set +# CONFIG_USB_STORAGE_SDDR55 is not set +# CONFIG_USB_STORAGE_JUMPSHOT is not set + +# +# USB Human Interface Devices (HID) +# +CONFIG_USB_HID=y +CONFIG_USB_HIDINPUT=y +# CONFIG_HID_FF is not set +CONFIG_USB_HIDDEV=y +# CONFIG_USB_AIPTEK is not set +# CONFIG_USB_WACOM is not set +# CONFIG_USB_KBTAB is not set +# CONFIG_USB_POWERMATE is not set +# CONFIG_USB_XPAD is not set + +# +# USB Imaging devices +# +# CONFIG_USB_MDC800 is not set +# CONFIG_USB_MICROTEK is not set +# CONFIG_USB_HPUSBSCSI is not set + +# +# USB Multimedia devices +# +# CONFIG_USB_DABUSB is not set + +# +# Video4Linux support is needed for USB Multimedia device support +# + +# +# USB Network adaptors +# +# CONFIG_USB_CATC is not set +# CONFIG_USB_KAWETH is not set +# CONFIG_USB_PEGASUS is not set +# CONFIG_USB_RTL8150 is not set +# CONFIG_USB_USBNET is not set + +# +# USB port drivers +# + +# +# USB Serial Converter support +# +# CONFIG_USB_SERIAL is not set + +# +# USB Miscellaneous drivers +# +# CONFIG_USB_EMI62 is not set +# CONFIG_USB_EMI26 is not set +# CONFIG_USB_TIGL is not set +# CONFIG_USB_AUERSWALD is not set +# CONFIG_USB_RIO500 is not set +# CONFIG_USB_LEGOTOWER is not set +# CONFIG_USB_BRLVGER is not set +# CONFIG_USB_LCD is not set +# CONFIG_USB_LED is not set + +# +# USB Gadget Support +# +# CONFIG_USB_GADGET is not set + +# +# Library routines +# +CONFIG_CRC32=y + +# +# Profiling support +# +# CONFIG_PROFILING is not set + +# +# Kernel hacking +# +CONFIG_IA64_GRANULE_16MB=y +# CONFIG_IA64_GRANULE_64MB is not set +CONFIG_DEBUG_KERNEL=y +CONFIG_IA64_PRINT_HAZARDS=y +# CONFIG_DISABLE_VHPT is not set +CONFIG_MAGIC_SYSRQ=y +# CONFIG_DEBUG_SLAB is not set +# CONFIG_DEBUG_SPINLOCK is not set +# CONFIG_DEBUG_SPINLOCK_SLEEP is not set +# CONFIG_IA64_DEBUG_CMPXCHG is not set +# CONFIG_IA64_DEBUG_IRQ is not set +# CONFIG_DEBUG_INFO is not set + +# +# Security options +# +# CONFIG_SECURITY is not set + +# +# Cryptographic options +# +# CONFIG_CRYPTO is not set 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 Sun Mar 14 14:20:06 2004 +++ b/arch/ia64/hp/common/sba_iommu.c Sun Mar 14 14:20:06 2004 @@ -1479,7 +1479,6 @@ #ifdef FULL_VALID_PDIR unsigned long index; #endif - unsigned int i; /* ** Firmware programs the base and size of a "safe IOVA space" @@ -1574,18 +1573,6 @@ /* Enable IOVA translation */ WRITE_REG(ioc->ibase | 1, ioc->ioc_hpa + IOC_IBASE); READ_REG(ioc->ioc_hpa + IOC_IBASE); - - /* Clear ROPE(N)_CONFIG AO bit. - ** Disables "NT Ordering" (~= !"Relaxed Ordering") - ** Overrides bit 1 in DMA Hint Sets. - ** Improves netperf UDP_STREAM by ~10% for tg3 on bcm5701. - */ - for (i=0; i<(8*8); i+=8) { - unsigned long rope_config; - rope_config = READ_REG(ioc->ioc_hpa + IOC_ROPE0_CFG + i); - rope_config &= ~IOC_ROPE_AO; - WRITE_REG(rope_config, ioc->ioc_hpa + IOC_ROPE0_CFG + i); - } } static void __init @@ -1659,26 +1646,25 @@ static void __init ioc_zx1_init(struct ioc *ioc) { + unsigned long rope_config; + unsigned int i; + if (ioc->rev < 0x20) panic(PFX "IOC 2.0 or later required for IOMMU support\n"); - ioc->dma_mask = 0xFFFFFFFFFFUL; + /* 38 bit memory controller + extra bit for range displaced by MMIO */ + ioc->dma_mask = (0x1UL << 39) - 1; - if (!iovp_shift) { - /* 64k is max iommu page size */ - iovp_shift = min(PAGE_SHIFT, 16); - iovp_size = (1 << iovp_shift); - iovp_mask = ~(iovp_size - 1); - } -} - -static void __init -ioc_sx1000_init(struct ioc *ioc) -{ - if (!iovp_shift) { - iovp_shift = 12; /* 4K for now */ - iovp_size = (1 << iovp_shift); - iovp_mask = ~(iovp_size - 1); + /* + ** Clear ROPE(N)_CONFIG AO bit. + ** Disables "NT Ordering" (~= !"Relaxed Ordering") + ** Overrides bit 1 in DMA Hint Sets. + ** Improves netperf UDP_STREAM by ~10% for tg3 on bcm5701. + */ + for (i=0; i<(8*8); i+=8) { + rope_config = READ_REG(ioc->ioc_hpa + IOC_ROPE0_CFG + i); + rope_config &= ~IOC_ROPE_AO; + WRITE_REG(rope_config, ioc->ioc_hpa + IOC_ROPE0_CFG + i); } } @@ -1692,8 +1678,6 @@ static struct ioc_iommu ioc_iommu_info[] __initdata = { { ZX1_IOC_ID, "zx1", ioc_zx1_init }, - { REO_IOC_ID, "REO", ioc_sx1000_init }, - { SX1000_IOC_ID, "sx1000", ioc_sx1000_init }, }; static struct ioc * __init @@ -1718,11 +1702,6 @@ ioc->rev = READ_REG(ioc->ioc_hpa + IOC_FCLASS) & 0xFFUL; ioc->dma_mask = 0xFFFFFFFFFFFFFFFFUL; /* conservative */ - if (iovp_shift) { - iovp_size = (1 << iovp_shift); - iovp_mask = ~(iovp_size - 1); - } - for (info = ioc_iommu_info; info < ioc_iommu_info + ARRAY_SIZE(ioc_iommu_info); info++) { if (ioc->func_id == info->func_id) { ioc->name = info->name; @@ -1730,6 +1709,10 @@ (info->init)(ioc); } } + + iovp_size = (1 << iovp_shift); + iovp_mask = ~(iovp_size - 1); + DBG_INIT("%s: PAGE_SIZE %ldK, iovp_size %ldK\n", __FUNCTION__, PAGE_SIZE >> 10, iovp_size >> 10); @@ -1929,9 +1912,20 @@ * For HWP0001, only SBA appears in ACPI namespace. It encloses the PCI * root bridges, and its CSR space includes the IOC function. */ - if (strncmp("HWP0001", dev_info->hardware_id.value, 7) == 0) + if (strncmp("HWP0001", dev_info->hardware_id.value, 7) == 0) { hpa += ZX1_IOC_OFFSET; + /* zx1 based systems default to kernel page size iommu pages */ + if (!iovp_shift) + iovp_shift = min(PAGE_SHIFT, 16); + } ACPI_MEM_FREE(dev_info); + + /* + * default anything not caught above or specified on cmdline to 4k + * iommu page size + */ + if (!iovp_shift) + iovp_shift = 12; ioc = ioc_init(hpa, device->handle); if (!ioc) diff -Nru a/arch/ia64/hp/sim/simserial.c b/arch/ia64/hp/sim/simserial.c --- a/arch/ia64/hp/sim/simserial.c Sun Mar 14 14:20:07 2004 +++ b/arch/ia64/hp/sim/simserial.c Sun Mar 14 14:20:07 2004 @@ -636,7 +636,6 @@ #ifdef SIMSERIAL_DEBUG printk("rs_close: hung_up\n"); #endif - MOD_DEC_USE_COUNT; local_irq_restore(flags); return; } @@ -661,7 +660,6 @@ state->count = 0; } if (state->count) { - MOD_DEC_USE_COUNT; local_irq_restore(flags); return; } @@ -686,7 +684,6 @@ } info->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING); wake_up_interruptible(&info->close_wait); - MOD_DEC_USE_COUNT; } /* @@ -874,17 +871,12 @@ int retval, line; unsigned long page; - MOD_INC_USE_COUNT; line = tty->index; - if ((line < 0) || (line >= NR_PORTS)) { - MOD_DEC_USE_COUNT; + if ((line < 0) || (line >= NR_PORTS)) return -ENODEV; - } retval = get_async_struct(line, &info); - if (retval) { - MOD_DEC_USE_COUNT; + if (retval) return retval; - } tty->driver_data = info; info->tty = tty; @@ -895,10 +887,8 @@ if (!tmp_buf) { page = get_zeroed_page(GFP_KERNEL); - if (!page) { - /* MOD_DEC_USE_COUNT; "info->tty" will cause this? */ + if (!page) return -ENOMEM; - } if (tmp_buf) free_page(page); else @@ -912,7 +902,6 @@ (info->flags & ASYNC_CLOSING)) { if (info->flags & ASYNC_CLOSING) interruptible_sleep_on(&info->close_wait); - /* MOD_DEC_USE_COUNT; "info->tty" will cause this? */ #ifdef SERIAL_DO_RESTART return ((info->flags & ASYNC_HUP_NOTIFY) ? -EAGAIN : -ERESTARTSYS); @@ -926,7 +915,6 @@ */ retval = startup(info); if (retval) { - /* MOD_DEC_USE_COUNT; "info->tty" will cause this? */ return retval; } @@ -1042,6 +1030,7 @@ /* Initialize the tty_driver structure */ + hp_simserial_driver->owner = THIS_MODULE; hp_simserial_driver->driver_name = "simserial"; hp_simserial_driver->name = "ttyS"; hp_simserial_driver->major = TTY_MAJOR; diff -Nru a/arch/ia64/ia32/ia32_support.c b/arch/ia64/ia32/ia32_support.c --- a/arch/ia64/ia32/ia32_support.c Sun Mar 14 14:20:06 2004 +++ b/arch/ia64/ia32/ia32_support.c Sun Mar 14 14:20:06 2004 @@ -134,8 +134,6 @@ regs->r17 = (_TSS << 48) | (_LDT << 32) | (__u32) regs->r17; regs->r30 = load_desc(_LDT); /* LDTD */ load_TLS(&t->thread, smp_processor_id()); - - put_cpu(); } /* diff -Nru a/arch/ia64/kernel/head.S b/arch/ia64/kernel/head.S --- a/arch/ia64/kernel/head.S Sun Mar 14 14:20:07 2004 +++ b/arch/ia64/kernel/head.S Sun Mar 14 14:20:07 2004 @@ -816,7 +816,7 @@ br.ret.sptk.many rp END(ia64_delay_loop) -GLOBAL_ENTRY(ia64_invoke_kernel_thread_helper) +GLOBAL_ENTRY(start_kernel_thread) .prologue .save rp, r0 // this is the end of the call-chain .body @@ -827,7 +827,7 @@ mov out0 = r8 br.call.sptk.many rp = sys_exit;; 1: br.sptk.few 1b // not reached -END(ia64_invoke_kernel_thread_helper) +END(start_kernel_thread) #ifdef CONFIG_IA64_BRL_EMU diff -Nru a/arch/ia64/kernel/iosapic.c b/arch/ia64/kernel/iosapic.c --- a/arch/ia64/kernel/iosapic.c Sun Mar 14 14:20:07 2004 +++ b/arch/ia64/kernel/iosapic.c Sun Mar 14 14:20:07 2004 @@ -170,7 +170,7 @@ } static void -set_rte (unsigned int vector, unsigned int dest) +set_rte (unsigned int vector, unsigned int dest, int mask) { unsigned long pol, trigger, dmode; u32 low32, high32; @@ -205,6 +205,7 @@ low32 = ((pol << IOSAPIC_POLARITY_SHIFT) | (trigger << IOSAPIC_TRIGGER_SHIFT) | (dmode << IOSAPIC_DELIVERY_SHIFT) | + ((mask ? 1 : 0) << IOSAPIC_MASK_SHIFT) | vector); /* dest contains both id and eid */ @@ -509,7 +510,7 @@ (trigger == IOSAPIC_EDGE ? "edge" : "level"), dest, vector); /* program the IOSAPIC routing table */ - set_rte(vector, dest); + set_rte(vector, dest, 0); return vector; } @@ -557,7 +558,7 @@ (trigger == IOSAPIC_EDGE ? "edge" : "level"), dest, vector); /* program the IOSAPIC routing table */ - set_rte(vector, dest); + set_rte(vector, dest, 0); return vector; } @@ -583,7 +584,7 @@ trigger == IOSAPIC_EDGE ? "edge" : "level", dest, vector); /* program the IOSAPIC routing table */ - set_rte(vector, dest); + set_rte(vector, dest, 0); } void __init @@ -669,7 +670,7 @@ /* direct the interrupt vector to the running cpu id */ dest = (ia64_getreg(_IA64_REG_CR_LID) >> 16) & 0xffff; #endif - set_rte(vector, dest); + set_rte(vector, dest, 1); printk(KERN_INFO "IOSAPIC: vector %d -> CPU 0x%04x, enabled\n", vector, dest); diff -Nru a/arch/ia64/kernel/irq_ia64.c b/arch/ia64/kernel/irq_ia64.c --- a/arch/ia64/kernel/irq_ia64.c Sun Mar 14 14:20:07 2004 +++ b/arch/ia64/kernel/irq_ia64.c Sun Mar 14 14:20:07 2004 @@ -57,6 +57,21 @@ }; EXPORT_SYMBOL(isa_irq_to_vector_map); +static inline void +irq_enter (void) +{ + preempt_count() += HARDIRQ_OFFSET; +} + +static inline void +irq_exit (void) +{ + preempt_count() -= IRQ_EXIT_OFFSET; + if (!in_interrupt() && local_softirq_pending()) + do_softirq(); + preempt_enable_no_resched(); +} + int ia64_alloc_vector (void) { diff -Nru a/arch/ia64/kernel/mca.c b/arch/ia64/kernel/mca.c --- a/arch/ia64/kernel/mca.c Sun Mar 14 14:20:07 2004 +++ b/arch/ia64/kernel/mca.c Sun Mar 14 14:20:07 2004 @@ -103,8 +103,6 @@ static ia64_mc_info_t ia64_mc_info; -extern struct hw_interrupt_type irq_type_iosapic_level; - struct ia64_mca_tlb_info ia64_mca_tlb_list[NR_CPUS]; #define MAX_CPE_POLL_INTERVAL (15*60*HZ) /* 15 minutes */ @@ -1253,7 +1251,6 @@ if (irq_to_vector(irq) == cpev) { desc = irq_descp(irq); desc->status |= IRQ_PER_CPU; - desc->handler = &irq_type_iosapic_level; setup_irq(irq, &mca_cpe_irqaction); } ia64_mca_register_cpev(cpev); diff -Nru a/arch/ia64/kernel/process.c b/arch/ia64/kernel/process.c --- a/arch/ia64/kernel/process.c Sun Mar 14 14:20:07 2004 +++ b/arch/ia64/kernel/process.c Sun Mar 14 14:20:07 2004 @@ -574,8 +574,8 @@ pid_t kernel_thread (int (*fn)(void *), void *arg, unsigned long flags) { - extern void ia64_invoke_kernel_thread_helper (void); - unsigned long *helper_fptr = (unsigned long *) &ia64_invoke_kernel_thread_helper; + extern void start_kernel_thread (void); + unsigned long *helper_fptr = (unsigned long *) &start_kernel_thread; struct { struct switch_stack sw; struct pt_regs pt; diff -Nru a/arch/ia64/kernel/sal.c b/arch/ia64/kernel/sal.c --- a/arch/ia64/kernel/sal.c Sun Mar 14 14:20:08 2004 +++ b/arch/ia64/kernel/sal.c Sun Mar 14 14:20:08 2004 @@ -10,7 +10,6 @@ #include #include -#include #include #include @@ -21,6 +20,12 @@ spinlock_t sal_lock __cacheline_aligned = SPIN_LOCK_UNLOCKED; unsigned long sal_platform_features; +unsigned short sal_revision; +unsigned short sal_version; + +#define SAL_MAJOR(x) ((x) >> 8) +#define SAL_MINOR(x) ((x) & 0xff) + static struct { void *addr; /* function entry point */ void *gpval; /* gp value to use */ @@ -86,13 +91,98 @@ ia64_sal = (ia64_sal_handler) &pdesc; } +static void __init +check_versions (struct ia64_sal_systab *systab) +{ + sal_revision = (systab->sal_rev_major << 8) | systab->sal_rev_minor; + sal_version = (systab->sal_b_rev_major << 8) | systab->sal_b_rev_minor; + + /* Check for broken firmware */ + if ((sal_revision == SAL_VERSION_CODE(49, 29)) + && (sal_version == SAL_VERSION_CODE(49, 29))) + { + /* + * Old firmware for zx2000 prototypes have this weird version number, + * reset it to something sane. + */ + sal_revision = SAL_VERSION_CODE(2, 8); + sal_version = SAL_VERSION_CODE(0, 0); + } +} + +static void __init +sal_desc_entry_point (void *p) +{ + struct ia64_sal_desc_entry_point *ep = p; + ia64_pal_handler_init(__va(ep->pal_proc)); + ia64_sal_handler_init(__va(ep->sal_proc), __va(ep->gp)); +} + +#ifdef CONFIG_SMP +static void __init +set_smp_redirect (int flag) +{ + if (no_int_routing) + smp_int_redirect &= ~flag; + else + smp_int_redirect |= flag; +} +#else +#define set_smp_redirect(flag) do { } while (0) +#endif + +static void __init +sal_desc_platform_feature (void *p) +{ + struct ia64_sal_desc_platform_feature *pf = p; + sal_platform_features = pf->feature_mask; + + printk(KERN_INFO "SAL Platform features:"); + if (!sal_platform_features) { + printk(" None\n"); + return; + } + + if (sal_platform_features & IA64_SAL_PLATFORM_FEATURE_BUS_LOCK) + printk(" BusLock"); + if (sal_platform_features & IA64_SAL_PLATFORM_FEATURE_IRQ_REDIR_HINT) { + printk(" IRQ_Redirection"); + set_smp_redirect(SMP_IRQ_REDIRECTION); + } + if (sal_platform_features & IA64_SAL_PLATFORM_FEATURE_IPI_REDIR_HINT) { + printk(" IPI_Redirection"); + set_smp_redirect(SMP_IPI_REDIRECTION); + } + if (sal_platform_features & IA64_SAL_PLATFORM_FEATURE_ITC_DRIFT) + printk(" ITC_Drift"); + printk("\n"); +} + +#ifdef CONFIG_SMP +static void __init +sal_desc_ap_wakeup (void *p) +{ + struct ia64_sal_desc_ap_wakeup *ap = p; + + switch (ap->mechanism) { + case IA64_SAL_AP_EXTERNAL_INT: + ap_wakeup_vector = ap->vector; + printk(KERN_INFO "SAL: AP wakeup using external interrupt " + "vector 0x%lx\n", ap_wakeup_vector); + break; + default: + printk(KERN_ERR "SAL: AP wakeup mechanism unsupported!\n"); + break; + } +} +#else +static void __init sal_desc_ap_wakeup(void *p) { } +#endif void __init ia64_sal_init (struct ia64_sal_systab *systab) { - unsigned long min, max; char *p; - struct ia64_sal_desc_entry_point *ep; int i; if (!systab) { @@ -103,85 +193,34 @@ if (strncmp(systab->signature, "SST_", 4) != 0) printk(KERN_ERR "bad signature in system table!"); - /* - * revisions are coded in BCD, so %x does the job for us - */ - printk(KERN_INFO "SAL v%x.%x: oem=%.32s, product=%.32s\n", - systab->sal_rev_major, systab->sal_rev_minor, - systab->oem_id, systab->product_id); + check_versions(systab); - min = ~0UL; - max = 0; + /* revisions are coded in BCD, so %x does the job for us */ + printk(KERN_INFO "SAL %x.%x: %.32s %.32s%sversion %x.%x\n", + SAL_MAJOR(sal_revision), SAL_MINOR(sal_revision), + systab->oem_id, systab->product_id, + systab->product_id[0] ? " " : "", + SAL_MAJOR(sal_version), SAL_MINOR(sal_version)); p = (char *) (systab + 1); for (i = 0; i < systab->entry_count; i++) { /* - * The first byte of each entry type contains the type descriptor. + * The first byte of each entry type contains the type + * descriptor. */ switch (*p) { - case SAL_DESC_ENTRY_POINT: - ep = (struct ia64_sal_desc_entry_point *) p; - printk(KERN_INFO "SAL: entry: pal_proc=0x%lx, sal_proc=0x%lx\n", - ep->pal_proc, ep->sal_proc); - ia64_pal_handler_init(__va(ep->pal_proc)); - ia64_sal_handler_init(__va(ep->sal_proc), __va(ep->gp)); + case SAL_DESC_ENTRY_POINT: + sal_desc_entry_point(p); break; - - case SAL_DESC_PTC: + case SAL_DESC_PLATFORM_FEATURE: + sal_desc_platform_feature(p); + break; + case SAL_DESC_PTC: ia64_ptc_domain_info = (ia64_sal_desc_ptc_t *)p; break; - - case SAL_DESC_AP_WAKEUP: -#ifdef CONFIG_SMP - { - struct ia64_sal_desc_ap_wakeup *ap = (void *) p; - - switch (ap->mechanism) { - case IA64_SAL_AP_EXTERNAL_INT: - ap_wakeup_vector = ap->vector; - printk(KERN_INFO "SAL: AP wakeup using external interrupt " - "vector 0x%lx\n", ap_wakeup_vector); - break; - - default: - printk(KERN_ERR "SAL: AP wakeup mechanism unsupported!\n"); - break; - } - break; - } -#endif - case SAL_DESC_PLATFORM_FEATURE: - { - struct ia64_sal_desc_platform_feature *pf = (void *) p; - sal_platform_features = pf->feature_mask; - printk(KERN_INFO "SAL: Platform features "); - - if (pf->feature_mask & IA64_SAL_PLATFORM_FEATURE_BUS_LOCK) - printk("BusLock "); - if (pf->feature_mask & IA64_SAL_PLATFORM_FEATURE_IRQ_REDIR_HINT) { - printk("IRQ_Redirection "); -#ifdef CONFIG_SMP - if (no_int_routing) - smp_int_redirect &= ~SMP_IRQ_REDIRECTION; - else - smp_int_redirect |= SMP_IRQ_REDIRECTION; -#endif - } - if (pf->feature_mask & IA64_SAL_PLATFORM_FEATURE_IPI_REDIR_HINT) { - printk("IPI_Redirection "); -#ifdef CONFIG_SMP - if (no_int_routing) - smp_int_redirect &= ~SMP_IPI_REDIRECTION; - else - smp_int_redirect |= SMP_IPI_REDIRECTION; -#endif - } - if (pf->feature_mask & IA64_SAL_PLATFORM_FEATURE_ITC_DRIFT) - printk("ITC_Drift "); - printk("\n"); - break; - } - + case SAL_DESC_AP_WAKEUP: + sal_desc_ap_wakeup(p); + break; } p += SAL_DESC_SIZE(*p); } diff -Nru a/arch/ia64/lib/swiotlb.c b/arch/ia64/lib/swiotlb.c --- a/arch/ia64/lib/swiotlb.c Sun Mar 14 14:20:08 2004 +++ b/arch/ia64/lib/swiotlb.c Sun Mar 14 14:20:08 2004 @@ -47,7 +47,7 @@ #define IO_TLB_SHIFT 11 /* - * Used to do a quick range check in swiotlb_unmap_single and swiotlb_sync_single, to see + * Used to do a quick range check in swiotlb_unmap_single and swiotlb_sync_single_*, to see * if the memory was in fact allocated by this API. */ static char *io_tlb_start, *io_tlb_end; @@ -381,11 +381,24 @@ * * If you perform a swiotlb_map_single() but wish to interrogate the buffer using the cpu, * yet do not wish to teardown the PCI dma mapping, you must call this function before - * doing so. At the next point you give the PCI dma address back to the card, the device - * again owns the buffer. + * doing so. At the next point you give the PCI dma address back to the card, you must + * first perform a swiotlb_dma_sync_for_device, and then the device again owns the buffer */ void -swiotlb_sync_single (struct device *hwdev, dma_addr_t dev_addr, size_t size, int dir) +swiotlb_sync_single_for_cpu (struct device *hwdev, dma_addr_t dev_addr, size_t size, int dir) +{ + char *dma_addr = phys_to_virt(dev_addr); + + if (dir == DMA_NONE) + BUG(); + if (dma_addr >= io_tlb_start && dma_addr < io_tlb_end) + sync_single(hwdev, dma_addr, size, dir); + else if (dir == DMA_FROM_DEVICE) + mark_clean(dma_addr, size); +} + +void +swiotlb_sync_single_for_device (struct device *hwdev, dma_addr_t dev_addr, size_t size, int dir) { char *dma_addr = phys_to_virt(dev_addr); @@ -456,11 +469,24 @@ * Make physical memory consistent for a set of streaming mode DMA translations after a * transfer. * - * The same as swiotlb_dma_sync_single but for a scatter-gather list, same rules and + * The same as swiotlb_sync_single_* but for a scatter-gather list, same rules and * usage. */ void -swiotlb_sync_sg (struct device *hwdev, struct scatterlist *sg, int nelems, int dir) +swiotlb_sync_sg_for_cpu (struct device *hwdev, struct scatterlist *sg, int nelems, int dir) +{ + int i; + + if (dir == DMA_NONE) + BUG(); + + for (i = 0; i < nelems; i++, sg++) + if (sg->dma_address != SG_ENT_PHYS_ADDRESS(sg)) + sync_single(hwdev, (void *) sg->dma_address, sg->dma_length, dir); +} + +void +swiotlb_sync_sg_for_device (struct device *hwdev, struct scatterlist *sg, int nelems, int dir) { int i; @@ -488,8 +514,10 @@ EXPORT_SYMBOL(swiotlb_unmap_single); EXPORT_SYMBOL(swiotlb_map_sg); EXPORT_SYMBOL(swiotlb_unmap_sg); -EXPORT_SYMBOL(swiotlb_sync_single); -EXPORT_SYMBOL(swiotlb_sync_sg); +EXPORT_SYMBOL(swiotlb_sync_single_for_cpu); +EXPORT_SYMBOL(swiotlb_sync_single_for_device); +EXPORT_SYMBOL(swiotlb_sync_sg_for_cpu); +EXPORT_SYMBOL(swiotlb_sync_sg_for_device); EXPORT_SYMBOL(swiotlb_alloc_coherent); EXPORT_SYMBOL(swiotlb_free_coherent); EXPORT_SYMBOL(swiotlb_dma_supported); diff -Nru a/arch/ia64/pci/pci.c b/arch/ia64/pci/pci.c --- a/arch/ia64/pci/pci.c Sun Mar 14 14:20:07 2004 +++ b/arch/ia64/pci/pci.c Sun Mar 14 14:20:07 2004 @@ -57,17 +57,16 @@ ((u64)(seg << 24) | (u64)(bus << 16) | \ (u64)(devfn << 8) | (u64)(reg)) - static int pci_sal_read (int seg, int bus, int devfn, int reg, int len, u32 *value) { int result = 0; u64 data = 0; - if (!value || (seg > 255) || (bus > 255) || (devfn > 255) || (reg > 255)) + if ((seg > 255) || (bus > 255) || (devfn > 255) || (reg > 255)) return -EINVAL; - result = ia64_sal_pci_config_read(PCI_SAL_ADDRESS(seg, bus, devfn, reg), len, &data); + result = ia64_sal_pci_config_read(PCI_SAL_ADDRESS(seg, bus, devfn, reg), 0, len, &data); *value = (u32) data; @@ -80,15 +79,62 @@ if ((seg > 255) || (bus > 255) || (devfn > 255) || (reg > 255)) return -EINVAL; - return ia64_sal_pci_config_write(PCI_SAL_ADDRESS(seg, bus, devfn, reg), len, value); + return ia64_sal_pci_config_write(PCI_SAL_ADDRESS(seg, bus, devfn, reg), 0, len, value); } -struct pci_raw_ops pci_sal_ops = { +static struct pci_raw_ops pci_sal_ops = { .read = pci_sal_read, .write = pci_sal_write }; -struct pci_raw_ops *raw_pci_ops = &pci_sal_ops; /* default to SAL */ +/* SAL 3.2 adds support for extended config space. */ + +#define PCI_SAL_EXT_ADDRESS(seg, bus, devfn, reg) \ + ((u64)(seg << 28) | (u64)(bus << 20) | \ + (u64)(devfn << 12) | (u64)(reg)) + +static int +pci_sal_ext_read (int seg, int bus, int devfn, int reg, int len, u32 *value) +{ + int result = 0; + u64 data = 0; + + if ((seg > 65535) || (bus > 255) || (devfn > 255) || (reg > 4095)) + return -EINVAL; + + result = ia64_sal_pci_config_read(PCI_SAL_EXT_ADDRESS(seg, bus, devfn, reg), 1, len, &data); + + *value = (u32) data; + + return result; +} + +static int +pci_sal_ext_write (int seg, int bus, int devfn, int reg, int len, u32 value) +{ + if ((seg > 65535) || (bus > 255) || (devfn > 255) || (reg > 4095)) + return -EINVAL; + + return ia64_sal_pci_config_write(PCI_SAL_EXT_ADDRESS(seg, bus, devfn, reg), 1, len, value); +} + +static struct pci_raw_ops pci_sal_ext_ops = { + .read = pci_sal_ext_read, + .write = pci_sal_ext_write +}; + +struct pci_raw_ops *raw_pci_ops = &pci_sal_ops; /* default to SAL < 3.2 */ + +static int __init +pci_set_sal_ops (void) +{ + if (sal_version >= SAL_VERSION_CODE(3, 2)) { + raw_pci_ops = &pci_sal_ext_ops; + } + return 0; +} + +arch_initcall(pci_set_sal_ops); static int @@ -139,7 +185,8 @@ } static int __devinit -alloc_resource (char *name, struct resource *root, unsigned long start, unsigned long end, unsigned long flags) +alloc_resource (char *name, struct resource *root, unsigned long start, unsigned long end, + unsigned long flags) { struct resource *res; diff -Nru a/arch/ia64/sn/io/hwgfs/ramfs.c b/arch/ia64/sn/io/hwgfs/ramfs.c --- a/arch/ia64/sn/io/hwgfs/ramfs.c Sun Mar 14 14:20:07 2004 +++ b/arch/ia64/sn/io/hwgfs/ramfs.c Sun Mar 14 14:20:07 2004 @@ -84,7 +84,7 @@ return hwgfs_mknod(dir, dentry, mode | S_IFDIR, 0); } -static int hwgfs_create(struct inode *dir, struct dentry *dentry, int mode) +static int hwgfs_create(struct inode *dir, struct dentry *dentry, int mode, struct nameidata *unused) { return hwgfs_mknod(dir, dentry, mode | S_IFREG, 0); } diff -Nru a/arch/ia64/sn/io/machvec/pci_dma.c b/arch/ia64/sn/io/machvec/pci_dma.c --- a/arch/ia64/sn/io/machvec/pci_dma.c Sun Mar 14 14:20:06 2004 +++ b/arch/ia64/sn/io/machvec/pci_dma.c Sun Mar 14 14:20:06 2004 @@ -152,7 +152,7 @@ * pcibr_dmatrans_addr ignores a missing PCIIO_DMA_A64 flag on * PCI-X buses. */ - if (hwdev->consistent_dma_mask == ~0UL) + if (hwdev->dev.coherent_dma_mask == ~0UL) *dma_handle = pcibr_dmatrans_addr(vhdl, NULL, phys_addr, size, PCIIO_DMA_CMD | PCIIO_DMA_A64); else { @@ -169,7 +169,7 @@ } } - if (!*dma_handle || *dma_handle > hwdev->consistent_dma_mask) { + if (!*dma_handle || *dma_handle > hwdev->dev.coherent_dma_mask) { if (dma_map) { pcibr_dmamap_done(dma_map); pcibr_dmamap_free(dma_map); @@ -437,7 +437,8 @@ } /** - * sn_pci_dma_sync_single - make sure all DMAs have completed + * sn_pci_dma_sync_single_* - make sure all DMAs or CPU accesses + * have completed * @hwdev: device to sync * @dma_handle: DMA address to sync * @size: size of region @@ -448,14 +449,19 @@ * anything on our platform. */ void -sn_pci_dma_sync_single(struct pci_dev *hwdev, dma_addr_t dma_handle, size_t size, int direction) +sn_pci_dma_sync_single_for_cpu(struct pci_dev *hwdev, dma_addr_t dma_handle, size_t size, int direction) { return; +} +void +sn_pci_dma_sync_single_for_device(struct pci_dev *hwdev, dma_addr_t dma_handle, size_t size, int direction) +{ + return; } /** - * sn_pci_dma_sync_sg - make sure all DMAs have completed + * sn_pci_dma_sync_sg_* - make sure all DMAs or CPU accesses have completed * @hwdev: device to sync * @sg: scatterlist to sync * @nents: number of entries in the scatterlist @@ -466,10 +472,15 @@ * on our platform. */ void -sn_pci_dma_sync_sg(struct pci_dev *hwdev, struct scatterlist *sg, int nents, int direction) +sn_pci_dma_sync_sg_for_cpu(struct pci_dev *hwdev, struct scatterlist *sg, int nents, int direction) { return; +} +void +sn_pci_dma_sync_sg_for_device(struct pci_dev *hwdev, struct scatterlist *sg, int nents, int direction) +{ + return; } /** @@ -602,28 +613,51 @@ EXPORT_SYMBOL(sn_dma_unmap_sg); void -sn_dma_sync_single(struct device *dev, dma_addr_t dma_handle, size_t size, +sn_dma_sync_single_for_cpu(struct device *dev, dma_addr_t dma_handle, size_t size, + int direction) +{ + BUG_ON(dev->bus != &pci_bus_type); + + sn_pci_dma_sync_single_for_cpu(to_pci_dev(dev), dma_handle, size, (int)direction); +} +EXPORT_SYMBOL(sn_dma_sync_single_for_cpu); + +void +sn_dma_sync_single_for_device(struct device *dev, dma_addr_t dma_handle, size_t size, int direction) { BUG_ON(dev->bus != &pci_bus_type); - sn_pci_dma_sync_single(to_pci_dev(dev), dma_handle, size, (int)direction); + sn_pci_dma_sync_single_for_device(to_pci_dev(dev), dma_handle, size, (int)direction); +} +EXPORT_SYMBOL(sn_dma_sync_single_for_device); + +void +sn_dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg, int nelems, + int direction) +{ + BUG_ON(dev->bus != &pci_bus_type); + + sn_pci_dma_sync_sg_for_cpu(to_pci_dev(dev), sg, nelems, (int)direction); } -EXPORT_SYMBOL(sn_dma_sync_single); +EXPORT_SYMBOL(sn_dma_sync_sg_for_cpu); void -sn_dma_sync_sg(struct device *dev, struct scatterlist *sg, int nelems, +sn_dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg, int nelems, int direction) { BUG_ON(dev->bus != &pci_bus_type); - sn_pci_dma_sync_sg(to_pci_dev(dev), sg, nelems, (int)direction); + sn_pci_dma_sync_sg_for_device(to_pci_dev(dev), sg, nelems, (int)direction); } -EXPORT_SYMBOL(sn_dma_sync_sg); +EXPORT_SYMBOL(sn_dma_sync_sg_for_device); EXPORT_SYMBOL(sn_pci_unmap_single); EXPORT_SYMBOL(sn_pci_map_single); -EXPORT_SYMBOL(sn_pci_dma_sync_single); +EXPORT_SYMBOL(sn_pci_dma_sync_single_for_cpu); +EXPORT_SYMBOL(sn_pci_dma_sync_single_for_device); +EXPORT_SYMBOL(sn_pci_dma_sync_sg_for_cpu); +EXPORT_SYMBOL(sn_pci_dma_sync_sg_for_device); EXPORT_SYMBOL(sn_pci_map_sg); EXPORT_SYMBOL(sn_pci_unmap_sg); EXPORT_SYMBOL(sn_pci_alloc_consistent); diff -Nru a/arch/ia64/sn/io/sn2/pcibr/pcibr_dvr.c b/arch/ia64/sn/io/sn2/pcibr/pcibr_dvr.c --- a/arch/ia64/sn/io/sn2/pcibr/pcibr_dvr.c Sun Mar 14 14:20:08 2004 +++ b/arch/ia64/sn/io/sn2/pcibr/pcibr_dvr.c Sun Mar 14 14:20:08 2004 @@ -2501,7 +2501,7 @@ if (pcibr_soft->bs_pcix_num_funcs) { if (pcibr_soft->bs_pcix_num_funcs > NUM_RBAR) { printk(KERN_WARNING - "%lx: Must oversubscribe Read Buffer Attribute Registers" + "%s: Must oversubscribe Read Buffer Attribute Registers" "(RBAR). Bus has %d RBARs but %d funcs need them.\n", pcibr_soft->bs_name, NUM_RBAR, pcibr_soft->bs_pcix_num_funcs); percent_allowed = 0; @@ -2603,7 +2603,7 @@ memset(buffer, 0, 1024); vsnprintf(buffer, 1024, format, ap); va_end(ap); - printk("", "%s", buffer); + printk("%s", buffer); kfree(buffer); } } diff -Nru a/arch/ia64/sn/io/sn2/pcibr/pcibr_intr.c b/arch/ia64/sn/io/sn2/pcibr/pcibr_intr.c --- a/arch/ia64/sn/io/sn2/pcibr/pcibr_intr.c Sun Mar 14 14:20:08 2004 +++ b/arch/ia64/sn/io/sn2/pcibr/pcibr_intr.c Sun Mar 14 14:20:08 2004 @@ -101,7 +101,7 @@ { nasid_t nasid; int wid_num; - volatile struct sn_flush_device_list *p; + struct sn_flush_device_list *p; int i,j; int bwin; unsigned long flags; diff -Nru a/arch/ia64/sn/io/sn2/pciio.c b/arch/ia64/sn/io/sn2/pciio.c --- a/arch/ia64/sn/io/sn2/pciio.c Sun Mar 14 14:20:08 2004 +++ b/arch/ia64/sn/io/sn2/pciio.c Sun Mar 14 14:20:08 2004 @@ -822,7 +822,7 @@ pciio_info_t pciio_info) { char name[32]; - vertex_hdl_t pconn; + vertex_hdl_t pconn = NULL; if (!pciio_info) return; @@ -835,7 +835,6 @@ hwgraph_vertex_unref(pconn); hwgraph_vertex_destroy(pconn); - } /*ARGSUSED */ diff -Nru a/arch/ia64/sn/io/sn2/shub_intr.c b/arch/ia64/sn/io/sn2/shub_intr.c --- a/arch/ia64/sn/io/sn2/shub_intr.c Sun Mar 14 14:20:07 2004 +++ b/arch/ia64/sn/io/sn2/shub_intr.c Sun Mar 14 14:20:07 2004 @@ -200,7 +200,6 @@ int cpuphys, slice; nasid_t nasid; unsigned long xtalk_addr; - void *bridge = intr->bi_soft->bs_base; int irq; int i; int old_cpu; @@ -237,13 +236,13 @@ for (bit = 0; bit < 8; bit++) { if (intr->bi_ibits & (1 << bit) ) { /* Disable interrupts. */ - pcireg_intr_enable_bit_clr(bridge, bit); + pcireg_intr_enable_bit_clr(intr->bi_soft, bit); /* Reset Host address (Interrupt destination) */ - pcireg_intr_addr_addr_set(bridge, bit, xtalk_addr); + pcireg_intr_addr_addr_set(intr->bi_soft, bit, xtalk_addr); /* Enable interrupt */ - pcireg_intr_enable_bit_set(bridge, bit); + pcireg_intr_enable_bit_set(intr->bi_soft, bit); /* Force an interrupt, just in case. */ - pcireg_force_intr_set(bridge, bit); + pcireg_force_intr_set(intr->bi_soft, bit); } } irq = intr->bi_irq; diff -Nru a/arch/ia64/sn/kernel/irq.c b/arch/ia64/sn/kernel/irq.c --- a/arch/ia64/sn/kernel/irq.c Sun Mar 14 14:20:06 2004 +++ b/arch/ia64/sn/kernel/irq.c Sun Mar 14 14:20:06 2004 @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include @@ -118,10 +119,11 @@ } static void -sn_set_affinity_irq(unsigned int irq, unsigned long cpu) +sn_set_affinity_irq(unsigned int irq, cpumask_t mask) { #ifdef CONFIG_SMP int redir = 0; + int cpu; struct sn_intr_list_t *p = sn_intr_list[irq]; pcibr_intr_t intr; extern void sn_shub_redirect_intr(pcibr_intr_t intr, unsigned long cpu); @@ -135,7 +137,9 @@ if (intr == NULL) return; + cpu = first_cpu(mask); sn_shub_redirect_intr(intr, cpu); + irq = irq & 0xff; /* strip off redirect bit, if someone stuck it on. */ (void) set_irq_affinity_info(irq, cpu_physical_id(intr->bi_cpu), redir); #endif /* CONFIG_SMP */ } diff -Nru a/arch/m68k/amiga/amiints.c b/arch/m68k/amiga/amiints.c --- a/arch/m68k/amiga/amiints.c Sun Mar 14 14:20:09 2004 +++ b/arch/m68k/amiga/amiints.c Sun Mar 14 14:20:09 2004 @@ -197,7 +197,7 @@ } if (irq >= IRQ_AMIGA_AUTO) - return sys_request_irq(irq - IRQ_AMIGA_AUTO, handler, + return cpu_request_irq(irq - IRQ_AMIGA_AUTO, handler, flags, devname, dev_id); if (irq >= IRQ_AMIGA_CIAB) @@ -244,7 +244,7 @@ } if (irq >= IRQ_AMIGA_AUTO) - sys_free_irq(irq - IRQ_AMIGA_AUTO, dev_id); + cpu_free_irq(irq - IRQ_AMIGA_AUTO, dev_id); if (irq >= IRQ_AMIGA_CIAB) { cia_free_irq(&ciab_base, irq - IRQ_AMIGA_CIAB, dev_id); diff -Nru a/arch/m68k/bvme6000/bvmeints.c b/arch/m68k/bvme6000/bvmeints.c --- a/arch/m68k/bvme6000/bvmeints.c Sun Mar 14 14:20:06 2004 +++ b/arch/m68k/bvme6000/bvmeints.c Sun Mar 14 14:20:06 2004 @@ -73,7 +73,7 @@ */ if (irq >= VEC_INT1 && irq <= VEC_INT7) - return sys_request_irq(irq - VEC_SPUR, handler, flags, + return cpu_request_irq(irq - VEC_SPUR, handler, flags, devname, dev_id); #endif if (!(irq_tab[irq].flags & IRQ_FLG_STD)) { @@ -103,7 +103,7 @@ } #if 0 if (irq >= VEC_INT1 && irq <= VEC_INT7) { - sys_free_irq(irq - VEC_SPUR, dev_id); + cpu_free_irq(irq - VEC_SPUR, dev_id); return; } #endif diff -Nru a/arch/m68k/hp300/time.c b/arch/m68k/hp300/time.c --- a/arch/m68k/hp300/time.c Sun Mar 14 14:20:08 2004 +++ b/arch/m68k/hp300/time.c Sun Mar 14 14:20:08 2004 @@ -68,7 +68,7 @@ asm volatile(" movpw %0,%1@(5)" : : "d" (INTVAL), "a" (CLOCKBASE)); - sys_request_irq(6, hp300_tick, IRQ_FLG_STD, "timer tick", vector); + cpu_request_irq(6, hp300_tick, IRQ_FLG_STD, "timer tick", vector); out_8(CLOCKBASE + CLKCR2, 0x1); /* select CR1 */ out_8(CLOCKBASE + CLKCR1, 0x40); /* enable irq */ diff -Nru a/arch/m68k/kernel/entry.S b/arch/m68k/kernel/entry.S --- a/arch/m68k/kernel/entry.S Sun Mar 14 14:20:05 2004 +++ b/arch/m68k/kernel/entry.S Sun Mar 14 14:20:05 2004 @@ -528,7 +528,7 @@ .long sys_ni_syscall /* old profil syscall holder */ .long sys_statfs .long sys_fstatfs /* 100 */ - .long sys_ioperm + .long sys_ni_syscall /* ioperm for i386 */ .long sys_socketcall .long sys_syslog .long sys_setitimer diff -Nru a/arch/m68k/kernel/ints.c b/arch/m68k/kernel/ints.c --- a/arch/m68k/kernel/ints.c Sun Mar 14 14:20:07 2004 +++ b/arch/m68k/kernel/ints.c Sun Mar 14 14:20:07 2004 @@ -137,8 +137,8 @@ EXPORT_SYMBOL(free_irq); -int sys_request_irq(unsigned int irq, - irqreturn_t (*handler)(int, void *, struct pt_regs *), +int cpu_request_irq(unsigned int irq, + irqreturn_t (*handler)(int, void *, struct pt_regs *), unsigned long flags, const char *devname, void *dev_id) { if (irq < IRQ1 || irq > IRQ7) { @@ -169,7 +169,7 @@ return 0; } -void sys_free_irq(unsigned int irq, void *dev_id) +void cpu_free_irq(unsigned int irq, void *dev_id) { if (irq < IRQ1 || irq > IRQ7) { printk("%s: Incorrect IRQ %d\n", __FUNCTION__, irq); diff -Nru a/arch/m68k/kernel/sys_m68k.c b/arch/m68k/kernel/sys_m68k.c --- a/arch/m68k/kernel/sys_m68k.c Sun Mar 14 14:20:06 2004 +++ b/arch/m68k/kernel/sys_m68k.c Sun Mar 14 14:20:06 2004 @@ -261,12 +261,6 @@ return -EINVAL; } -asmlinkage long sys_ioperm(unsigned long from, unsigned long num, int on) -{ - return -ENOSYS; -} - - /* Convert virtual (user) address VADDR to physical address PADDR */ #define virt_to_phys_040(vaddr) \ ({ \ diff -Nru a/arch/m68k/mac/iop.c b/arch/m68k/mac/iop.c --- a/arch/m68k/mac/iop.c Sun Mar 14 14:20:08 2004 +++ b/arch/m68k/mac/iop.c Sun Mar 14 14:20:08 2004 @@ -317,7 +317,7 @@ { if (iop_ism_present) { if (oss_present) { - sys_request_irq(OSS_IRQLEV_IOPISM, iop_ism_irq, + cpu_request_irq(OSS_IRQLEV_IOPISM, iop_ism_irq, IRQ_FLG_LOCK, "ISM IOP", (void *) IOP_NUM_ISM); oss_irq_enable(IRQ_MAC_ADB); diff -Nru a/arch/m68k/mac/macints.c b/arch/m68k/mac/macints.c --- a/arch/m68k/mac/macints.c Sun Mar 14 14:20:08 2004 +++ b/arch/m68k/mac/macints.c Sun Mar 14 14:20:08 2004 @@ -261,7 +261,8 @@ if (psc_present) psc_register_interrupts(); if (baboon_present) baboon_register_interrupts(); iop_register_interrupts(); - sys_request_irq(7, mac_nmi_handler, IRQ_FLG_LOCK, "NMI", mac_nmi_handler); + cpu_request_irq(7, mac_nmi_handler, IRQ_FLG_LOCK, "NMI", + mac_nmi_handler); #ifdef DEBUG_MACINTS printk("mac_init_IRQ(): Done!\n"); #endif @@ -507,7 +508,7 @@ #endif if (irq < VIA1_SOURCE_BASE) { - return sys_request_irq(irq, handler, flags, devname, dev_id); + return cpu_request_irq(irq, handler, flags, devname, dev_id); } if (irq >= NUM_MAC_SOURCES) { @@ -544,7 +545,7 @@ #endif if (irq < VIA1_SOURCE_BASE) { - return sys_free_irq(irq, dev_id); + return cpu_free_irq(irq, dev_id); } if (irq >= NUM_MAC_SOURCES) { diff -Nru a/arch/m68k/mac/oss.c b/arch/m68k/mac/oss.c --- a/arch/m68k/mac/oss.c Sun Mar 14 14:20:07 2004 +++ b/arch/m68k/mac/oss.c Sun Mar 14 14:20:07 2004 @@ -67,15 +67,15 @@ void __init oss_register_interrupts(void) { - sys_request_irq(OSS_IRQLEV_SCSI, oss_irq, IRQ_FLG_LOCK, + cpu_request_irq(OSS_IRQLEV_SCSI, oss_irq, IRQ_FLG_LOCK, "scsi", (void *) oss); - sys_request_irq(OSS_IRQLEV_IOPSCC, mac_scc_dispatch, IRQ_FLG_LOCK, + cpu_request_irq(OSS_IRQLEV_IOPSCC, mac_scc_dispatch, IRQ_FLG_LOCK, "scc", mac_scc_dispatch); - sys_request_irq(OSS_IRQLEV_NUBUS, oss_nubus_irq, IRQ_FLG_LOCK, + cpu_request_irq(OSS_IRQLEV_NUBUS, oss_nubus_irq, IRQ_FLG_LOCK, "nubus", (void *) oss); - sys_request_irq(OSS_IRQLEV_SOUND, oss_irq, IRQ_FLG_LOCK, + cpu_request_irq(OSS_IRQLEV_SOUND, oss_irq, IRQ_FLG_LOCK, "sound", (void *) oss); - sys_request_irq(OSS_IRQLEV_VIA1, via1_irq, IRQ_FLG_LOCK, + cpu_request_irq(OSS_IRQLEV_VIA1, via1_irq, IRQ_FLG_LOCK, "via1", (void *) via1); } diff -Nru a/arch/m68k/mac/psc.c b/arch/m68k/mac/psc.c --- a/arch/m68k/mac/psc.c Sun Mar 14 14:20:07 2004 +++ b/arch/m68k/mac/psc.c Sun Mar 14 14:20:07 2004 @@ -117,14 +117,10 @@ void __init psc_register_interrupts(void) { - sys_request_irq(3, psc_irq, IRQ_FLG_LOCK, "psc3", - (void *) 0x30); - sys_request_irq(4, psc_irq, IRQ_FLG_LOCK, "psc4", - (void *) 0x40); - sys_request_irq(5, psc_irq, IRQ_FLG_LOCK, "psc5", - (void *) 0x50); - sys_request_irq(6, psc_irq, IRQ_FLG_LOCK, "psc6", - (void *) 0x60); + cpu_request_irq(3, psc_irq, IRQ_FLG_LOCK, "psc3", (void *) 0x30); + cpu_request_irq(4, psc_irq, IRQ_FLG_LOCK, "psc4", (void *) 0x40); + cpu_request_irq(5, psc_irq, IRQ_FLG_LOCK, "psc5", (void *) 0x50); + cpu_request_irq(6, psc_irq, IRQ_FLG_LOCK, "psc6", (void *) 0x60); } /* diff -Nru a/arch/m68k/mac/via.c b/arch/m68k/mac/via.c --- a/arch/m68k/mac/via.c Sun Mar 14 14:20:07 2004 +++ b/arch/m68k/mac/via.c Sun Mar 14 14:20:07 2004 @@ -260,24 +260,27 @@ void __init via_register_interrupts(void) { if (via_alt_mapping) { - sys_request_irq(IRQ_AUTO_1, via1_irq, IRQ_FLG_LOCK|IRQ_FLG_FAST, - "software", (void *) via1); - sys_request_irq(IRQ_AUTO_6, via1_irq, IRQ_FLG_LOCK|IRQ_FLG_FAST, - "via1", (void *) via1); + cpu_request_irq(IRQ_AUTO_1, via1_irq, + IRQ_FLG_LOCK|IRQ_FLG_FAST, "software", + (void *) via1); + cpu_request_irq(IRQ_AUTO_6, via1_irq, + IRQ_FLG_LOCK|IRQ_FLG_FAST, "via1", + (void *) via1); } else { - sys_request_irq(IRQ_AUTO_1, via1_irq, IRQ_FLG_LOCK|IRQ_FLG_FAST, - "via1", (void *) via1); + cpu_request_irq(IRQ_AUTO_1, via1_irq, + IRQ_FLG_LOCK|IRQ_FLG_FAST, "via1", + (void *) via1); #if 0 /* interferes with serial on some machines */ if (!psc_present) { - sys_request_irq(IRQ_AUTO_6, mac_bang, IRQ_FLG_LOCK, + cpu_request_irq(IRQ_AUTO_6, mac_bang, IRQ_FLG_LOCK, "Off Switch", mac_bang); } #endif } - sys_request_irq(IRQ_AUTO_2, via2_irq, IRQ_FLG_LOCK|IRQ_FLG_FAST, + cpu_request_irq(IRQ_AUTO_2, via2_irq, IRQ_FLG_LOCK|IRQ_FLG_FAST, "via2", (void *) via2); if (!psc_present) { - sys_request_irq(IRQ_AUTO_4, mac_scc_dispatch, IRQ_FLG_LOCK, + cpu_request_irq(IRQ_AUTO_4, mac_scc_dispatch, IRQ_FLG_LOCK, "scc", mac_scc_dispatch); } request_irq(IRQ_MAC_NUBUS, via_nubus_irq, IRQ_FLG_LOCK|IRQ_FLG_FAST, diff -Nru a/arch/m68k/q40/config.c b/arch/m68k/q40/config.c --- a/arch/m68k/q40/config.c Sun Mar 14 14:20:07 2004 +++ b/arch/m68k/q40/config.c Sun Mar 14 14:20:07 2004 @@ -40,7 +40,7 @@ extern void floppy_setup(char *str, int *ints); extern irqreturn_t q40_process_int (int level, struct pt_regs *regs); -extern irqreturn_t (*q40_sys_default_handler[]) (int, void *, struct pt_regs *); /* added just for debugging */ +extern irqreturn_t (*q40_default_handler[]) (int, void *, struct pt_regs *); /* added just for debugging */ extern void q40_init_IRQ (void); extern void q40_free_irq (unsigned int, void *); extern int show_q40_interrupts (struct seq_file *, void *); @@ -185,7 +185,7 @@ mach_request_irq = q40_request_irq; enable_irq = q40_enable_irq; disable_irq = q40_disable_irq; - mach_default_handler = &q40_sys_default_handler; + mach_default_handler = &q40_default_handler; mach_get_model = q40_get_model; mach_get_hardware_list = q40_get_hardware_list; diff -Nru a/arch/m68k/q40/q40ints.c b/arch/m68k/q40/q40ints.c --- a/arch/m68k/q40/q40ints.c Sun Mar 14 14:20:08 2004 +++ b/arch/m68k/q40/q40ints.c Sun Mar 14 14:20:08 2004 @@ -46,10 +46,8 @@ irqreturn_t q40_irq2_handler (int, void *, struct pt_regs *fp); -extern irqreturn_t (*q40_sys_default_handler[]) (int, void *, struct pt_regs *); - static irqreturn_t q40_defhand (int irq, void *dev_id, struct pt_regs *fp); -static irqreturn_t sys_default_handler(int lev, void *dev_id, struct pt_regs *regs); +static irqreturn_t default_handler(int lev, void *dev_id, struct pt_regs *regs); #define DEVNAME_SIZE 24 @@ -96,7 +94,8 @@ } /* setup handler for ISA ints */ - sys_request_irq(IRQ2,q40_irq2_handler, 0, "q40 ISA and master chip", NULL); + cpu_request_irq(IRQ2, q40_irq2_handler, 0, "q40 ISA and master chip", + NULL); /* now enable some ints.. */ master_outb(1,EXT_ENABLE_REG); /* ISA IRQ 5-15 */ @@ -153,8 +152,8 @@ } else { /* Q40_IRQ_SAMPLE :somewhat special actions required here ..*/ - sys_request_irq(4,handler,flags,devname,dev_id); - sys_request_irq(6,handler,flags,devname,dev_id); + cpu_request_irq(4, handler, flags, devname, dev_id); + cpu_request_irq(6, handler, flags, devname, dev_id); return 0; } } @@ -192,8 +191,8 @@ } else { /* == Q40_IRQ_SAMPLE */ - sys_free_irq(4,dev_id); - sys_free_irq(6,dev_id); + cpu_free_irq(4, dev_id); + cpu_free_irq(6, dev_id); } } @@ -417,16 +416,16 @@ else master_outb(-1,KEYBOARD_UNLOCK_REG); return IRQ_NONE; } -static irqreturn_t sys_default_handler(int lev, void *dev_id, struct pt_regs *regs) +static irqreturn_t default_handler(int lev, void *dev_id, struct pt_regs *regs) { printk ("Uninitialised interrupt level %d\n", lev); return IRQ_NONE; } - irqreturn_t (*q40_sys_default_handler[SYS_IRQS]) (int, void *, struct pt_regs *) = { - sys_default_handler,sys_default_handler,sys_default_handler,sys_default_handler, - sys_default_handler,sys_default_handler,sys_default_handler,sys_default_handler - }; +irqreturn_t (*q40_default_handler[SYS_IRQS])(int, void *, struct pt_regs *) = { + default_handler, default_handler, default_handler, default_handler, + default_handler, default_handler, default_handler, default_handler +}; void q40_enable_irq (unsigned int irq) diff -Nru a/arch/m68k/sun3/sun3ints.c b/arch/m68k/sun3/sun3ints.c --- a/arch/m68k/sun3/sun3ints.c Sun Mar 14 14:20:08 2004 +++ b/arch/m68k/sun3/sun3ints.c Sun Mar 14 14:20:08 2004 @@ -153,8 +153,8 @@ for(i = 0; i < SYS_IRQS; i++) { if(dev_names[i]) - sys_request_irq(i, sun3_default_handler[i], - 0, dev_names[i], NULL); + cpu_request_irq(i, sun3_default_handler[i], 0, + dev_names[i], NULL); } for(i = 0; i < 192; i++) @@ -178,7 +178,8 @@ dev_names[irq] = devname; /* setting devname would be nice */ - sys_request_irq(irq, sun3_default_handler[irq], 0, devname, NULL); + cpu_request_irq(irq, sun3_default_handler[irq], 0, devname, + NULL); return 0; } else { diff -Nru a/arch/m68knommu/kernel/sys_m68k.c b/arch/m68knommu/kernel/sys_m68k.c --- a/arch/m68knommu/kernel/sys_m68k.c Sun Mar 14 14:20:08 2004 +++ b/arch/m68knommu/kernel/sys_m68k.c Sun Mar 14 14:20:08 2004 @@ -193,12 +193,6 @@ return -EINVAL; } -asmlinkage long sys_ioperm(unsigned long from, unsigned long num, int on) -{ - return -ENOSYS; -} - - /* sys_cacheflush -- flush (part of) the processor cache. */ asmlinkage int sys_cacheflush (unsigned long addr, int scope, int cache, unsigned long len) diff -Nru a/arch/m68knommu/kernel/syscalltable.S b/arch/m68knommu/kernel/syscalltable.S --- a/arch/m68knommu/kernel/syscalltable.S Sun Mar 14 14:20:05 2004 +++ b/arch/m68knommu/kernel/syscalltable.S Sun Mar 14 14:20:05 2004 @@ -120,7 +120,7 @@ .long sys_ni_syscall /* old profil syscall holder */ .long sys_statfs .long sys_fstatfs /* 100 */ - .long sys_ioperm + .long sys_ni_syscall /* ioperm for i386 */ .long sys_socketcall .long sys_syslog .long sys_setitimer diff -Nru a/arch/mips/mm/dma-coherent.c b/arch/mips/mm/dma-coherent.c --- a/arch/mips/mm/dma-coherent.c Sun Mar 14 14:20:07 2004 +++ b/arch/mips/mm/dma-coherent.c Sun Mar 14 14:20:07 2004 @@ -119,30 +119,55 @@ EXPORT_SYMBOL(dma_unmap_sg); -void dma_sync_single(struct device *dev, dma_addr_t dma_handle, size_t size, +void dma_sync_single_for_cpu(struct device *dev, dma_addr_t dma_handle, size_t size, enum dma_data_direction direction) { BUG_ON(direction == DMA_NONE); } -EXPORT_SYMBOL(dma_sync_single); +EXPORT_SYMBOL(dma_sync_single_for_cpu); -void dma_sync_single_range(struct device *dev, dma_addr_t dma_handle, +void dma_sync_single_for_device(struct device *dev, dma_addr_t dma_handle, size_t size, + enum dma_data_direction direction) +{ + BUG_ON(direction == DMA_NONE); +} + +EXPORT_SYMBOL(dma_sync_single_for_device); + +void dma_sync_single_range_for_cpu(struct device *dev, dma_addr_t dma_handle, + unsigned long offset, size_t size, + enum dma_data_direction direction) +{ + BUG_ON(direction == DMA_NONE); +} + +EXPORT_SYMBOL(dma_sync_single_range_for_cpu); + +void dma_sync_single_range_for_device(struct device *dev, dma_addr_t dma_handle, unsigned long offset, size_t size, enum dma_data_direction direction) { BUG_ON(direction == DMA_NONE); } -EXPORT_SYMBOL(dma_sync_single_range); +EXPORT_SYMBOL(dma_sync_single_range_for_device); -void dma_sync_sg(struct device *dev, struct scatterlist *sg, int nelems, +void dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg, int nelems, enum dma_data_direction direction) { BUG_ON(direction == DMA_NONE); } -EXPORT_SYMBOL(dma_sync_sg); +EXPORT_SYMBOL(dma_sync_sg_for_cpu); + +void dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg, int nelems, + enum dma_data_direction direction) +{ + BUG_ON(direction == DMA_NONE); +} + +EXPORT_SYMBOL(dma_sync_sg_for_device); int dma_supported(struct device *dev, u64 mask) { @@ -204,12 +229,20 @@ EXPORT_SYMBOL(pci_dac_dma_to_offset); -void pci_dac_dma_sync_single(struct pci_dev *pdev, +void pci_dac_dma_sync_single_for_cpu(struct pci_dev *pdev, + dma64_addr_t dma_addr, size_t len, int direction) +{ + BUG_ON(direction == PCI_DMA_NONE); +} + +EXPORT_SYMBOL(pci_dac_dma_sync_single_for_cpu); + +void pci_dac_dma_sync_single_for_device(struct pci_dev *pdev, dma64_addr_t dma_addr, size_t len, int direction) { BUG_ON(direction == PCI_DMA_NONE); } -EXPORT_SYMBOL(pci_dac_dma_sync_single); +EXPORT_SYMBOL(pci_dac_dma_sync_single_for_device); #endif /* CONFIG_PCI */ diff -Nru a/arch/mips/mm/dma-ip27.c b/arch/mips/mm/dma-ip27.c --- a/arch/mips/mm/dma-ip27.c Sun Mar 14 14:20:08 2004 +++ b/arch/mips/mm/dma-ip27.c Sun Mar 14 14:20:08 2004 @@ -125,30 +125,55 @@ EXPORT_SYMBOL(dma_unmap_sg); -void dma_sync_single(struct device *dev, dma_addr_t dma_handle, size_t size, +void dma_sync_single_for_cpu(struct device *dev, dma_addr_t dma_handle, size_t size, enum dma_data_direction direction) { BUG_ON(direction == DMA_NONE); } -EXPORT_SYMBOL(dma_sync_single); +EXPORT_SYMBOL(dma_sync_single_for_cpu); -void dma_sync_single_range(struct device *dev, dma_addr_t dma_handle, +void dma_sync_single_for_device(struct device *dev, dma_addr_t dma_handle, size_t size, + enum dma_data_direction direction) +{ + BUG_ON(direction == DMA_NONE); +} + +EXPORT_SYMBOL(dma_sync_single_for_device); + +void dma_sync_single_range_for_cpu(struct device *dev, dma_addr_t dma_handle, + unsigned long offset, size_t size, + enum dma_data_direction direction) +{ + BUG_ON(direction == DMA_NONE); +} + +EXPORT_SYMBOL(dma_sync_single_range_for_cpu); + +void dma_sync_single_range_for_device(struct device *dev, dma_addr_t dma_handle, unsigned long offset, size_t size, enum dma_data_direction direction) { BUG_ON(direction == DMA_NONE); } -EXPORT_SYMBOL(dma_sync_single_range); +EXPORT_SYMBOL(dma_sync_single_range_for_device); -void dma_sync_sg(struct device *dev, struct scatterlist *sg, int nelems, +void dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg, int nelems, enum dma_data_direction direction) { BUG_ON(direction == DMA_NONE); } -EXPORT_SYMBOL(dma_sync_sg); +EXPORT_SYMBOL(dma_sync_sg_for_cpu); + +void dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg, int nelems, + enum dma_data_direction direction) +{ + BUG_ON(direction == DMA_NONE); +} + +EXPORT_SYMBOL(dma_sync_sg_for_device); int dma_supported(struct device *dev, u64 mask) { @@ -208,10 +233,18 @@ EXPORT_SYMBOL(pci_dac_dma_to_offset); -void pci_dac_dma_sync_single(struct pci_dev *pdev, +void pci_dac_dma_sync_single_for_cpu(struct pci_dev *pdev, + dma64_addr_t dma_addr, size_t len, int direction) +{ + BUG_ON(direction == PCI_DMA_NONE); +} + +EXPORT_SYMBOL(pci_dac_dma_sync_single_for_cpu); + +void pci_dac_dma_sync_single_for_device(struct pci_dev *pdev, dma64_addr_t dma_addr, size_t len, int direction) { BUG_ON(direction == PCI_DMA_NONE); } -EXPORT_SYMBOL(pci_dac_dma_sync_single); +EXPORT_SYMBOL(pci_dac_dma_sync_single_for_device); diff -Nru a/arch/mips/mm/dma-noncoherent.c b/arch/mips/mm/dma-noncoherent.c --- a/arch/mips/mm/dma-noncoherent.c Sun Mar 14 14:20:06 2004 +++ b/arch/mips/mm/dma-noncoherent.c Sun Mar 14 14:20:06 2004 @@ -226,7 +226,7 @@ EXPORT_SYMBOL(dma_unmap_sg); -void dma_sync_single(struct device *dev, dma_addr_t dma_handle, size_t size, +void dma_sync_single_for_cpu(struct device *dev, dma_addr_t dma_handle, size_t size, enum dma_data_direction direction) { unsigned long addr; @@ -237,9 +237,35 @@ __dma_sync(addr, size, direction); } -EXPORT_SYMBOL(dma_sync_single); +EXPORT_SYMBOL(dma_sync_single_for_cpu); -void dma_sync_single_range(struct device *dev, dma_addr_t dma_handle, +void dma_sync_single_for_device(struct device *dev, dma_addr_t dma_handle, size_t size, + enum dma_data_direction direction) +{ + unsigned long addr; + + BUG_ON(direction == DMA_NONE); + + addr = dma_handle + PAGE_OFFSET; + __dma_sync(addr, size, direction); +} + +EXPORT_SYMBOL(dma_sync_single_for_device); + +void dma_sync_single_range_for_cpu(struct device *dev, dma_addr_t dma_handle, + unsigned long offset, size_t size, enum dma_data_direction direction) +{ + unsigned long addr; + + BUG_ON(direction == DMA_NONE); + + addr = dma_handle + offset + PAGE_OFFSET; + __dma_sync(addr, size, direction); +} + +EXPORT_SYMBOL(dma_sync_single_range_for_cpu); + +void dma_sync_single_range_for_device(struct device *dev, dma_addr_t dma_handle, unsigned long offset, size_t size, enum dma_data_direction direction) { unsigned long addr; @@ -250,9 +276,9 @@ __dma_sync(addr, size, direction); } -EXPORT_SYMBOL(dma_sync_single_range); +EXPORT_SYMBOL(dma_sync_single_range_for_device); -void dma_sync_sg(struct device *dev, struct scatterlist *sg, int nelems, +void dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg, int nelems, enum dma_data_direction direction) { int i; @@ -265,7 +291,22 @@ sg->length, direction); } -EXPORT_SYMBOL(dma_sync_sg); +EXPORT_SYMBOL(dma_sync_sg_for_cpu); + +void dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg, int nelems, + enum dma_data_direction direction) +{ + int i; + + BUG_ON(direction == DMA_NONE); + + /* Make sure that gcc doesn't leave the empty loop body. */ + for (i = 0; i < nelems; i++, sg++) + __dma_sync((unsigned long)page_address(sg->page), + sg->length, direction); +} + +EXPORT_SYMBOL(dma_sync_sg_for_device); int dma_supported(struct device *dev, u64 mask) { @@ -329,7 +370,17 @@ EXPORT_SYMBOL(pci_dac_dma_to_offset); -void pci_dac_dma_sync_single(struct pci_dev *pdev, +void pci_dac_dma_sync_single_for_cpu(struct pci_dev *pdev, + dma64_addr_t dma_addr, size_t len, int direction) +{ + BUG_ON(direction == PCI_DMA_NONE); + + dma_cache_wback_inv(dma_addr + PAGE_OFFSET, len); +} + +EXPORT_SYMBOL(pci_dac_dma_sync_single_for_cpu); + +void pci_dac_dma_sync_single_for_device(struct pci_dev *pdev, dma64_addr_t dma_addr, size_t len, int direction) { BUG_ON(direction == PCI_DMA_NONE); @@ -337,6 +388,6 @@ dma_cache_wback_inv(dma_addr + PAGE_OFFSET, len); } -EXPORT_SYMBOL(pci_dac_dma_sync_single); +EXPORT_SYMBOL(pci_dac_dma_sync_single_for_device); #endif /* CONFIG_PCI */ diff -Nru a/arch/parisc/configs/712_defconfig b/arch/parisc/configs/712_defconfig --- a/arch/parisc/configs/712_defconfig Sun Mar 14 14:20:08 2004 +++ b/arch/parisc/configs/712_defconfig Sun Mar 14 14:20:08 2004 @@ -22,6 +22,7 @@ # CONFIG_BSD_PROCESS_ACCT is not set CONFIG_SYSCTL=y CONFIG_LOG_BUF_SHIFT=15 +# CONFIG_HOTPLUG is not set # CONFIG_IKCONFIG is not set # CONFIG_EMBEDDED is not set CONFIG_KALLSYMS=y @@ -30,6 +31,7 @@ CONFIG_IOSCHED_NOOP=y CONFIG_IOSCHED_AS=y CONFIG_IOSCHED_DEADLINE=y +# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set # # Loadable module support @@ -64,7 +66,6 @@ # CONFIG_PCI is not set # CONFIG_CHASSIS_LCD_LED is not set # CONFIG_PDC_CHASSIS is not set -# CONFIG_HOTPLUG is not set # # Executable file formats @@ -79,6 +80,7 @@ # # Generic Driver Options # +CONFIG_DEBUG_DRIVER=y # # Memory Technology Devices (MTD) @@ -99,7 +101,6 @@ # # Plug and Play support # -# CONFIG_PNP is not set # # Block devices @@ -110,7 +111,6 @@ CONFIG_BLK_DEV_CRYPTOLOOP=y # CONFIG_BLK_DEV_NBD is not set # CONFIG_BLK_DEV_RAM is not set -# CONFIG_BLK_DEV_INITRD is not set # # ATA/ATAPI/MFM/RLL support @@ -144,7 +144,6 @@ # # SCSI low-level drivers # -# CONFIG_SCSI_AIC7XXX is not set # CONFIG_SCSI_AIC7XXX_OLD is not set # CONFIG_SCSI_EATA_PIO is not set # CONFIG_SCSI_PPA is not set @@ -170,13 +169,21 @@ # # Fusion MPT device support # -# CONFIG_FUSION is not set + +# +# IEEE 1394 (FireWire) support +# +# CONFIG_IEEE1394 is not set # # I2O device support # # +# Macintosh device drivers +# + +# # Networking support # CONFIG_NET=y @@ -287,7 +294,7 @@ # # ISDN subsystem # -# CONFIG_ISDN_BOOL is not set +# CONFIG_ISDN is not set # # Telephony Support @@ -318,8 +325,8 @@ CONFIG_SOUND_GAMEPORT=y CONFIG_SERIO=y # CONFIG_SERIO_SERPORT is not set -# CONFIG_SERIO_CT82C710 is not set # CONFIG_SERIO_PARKBD is not set +CONFIG_SERIO_GSCPS2=y # CONFIG_HP_SDC is not set # @@ -331,15 +338,17 @@ # CONFIG_KEYBOARD_XTKBD is not set # CONFIG_KEYBOARD_NEWTON is not set # CONFIG_KEYBOARD_HIL_OLD is not set +# CONFIG_KEYBOARD_HIL is not set CONFIG_INPUT_MOUSE=y # CONFIG_MOUSE_PS2 is not set # CONFIG_MOUSE_SERIAL is not set +# CONFIG_MOUSE_HIL is not set # CONFIG_INPUT_JOYSTICK is not set # CONFIG_INPUT_TOUCHSCREEN is not set CONFIG_INPUT_MISC=y # CONFIG_INPUT_PCSPKR is not set # CONFIG_INPUT_UINPUT is not set -CONFIG_INPUT_GSC=y +# CONFIG_HP_SDC_RTC is not set # # Character devices @@ -370,31 +379,14 @@ CONFIG_SERIAL_CORE=y CONFIG_SERIAL_CORE_CONSOLE=y CONFIG_UNIX98_PTYS=y -CONFIG_UNIX98_PTY_COUNT=256 +CONFIG_LEGACY_PTYS=y +CONFIG_LEGACY_PTY_COUNT=256 CONFIG_PRINTER=y # CONFIG_LP_CONSOLE is not set # CONFIG_PPDEV is not set # CONFIG_TIPAR is not set # -# I2C support -# -# CONFIG_I2C is not set - -# -# I2C Algorithms -# - -# -# I2C Hardware Bus support -# - -# -# I2C Hardware Sensors Chip support -# -# CONFIG_I2C_SENSOR is not set - -# # Mice # # CONFIG_BUSMOUSE is not set @@ -425,6 +417,15 @@ # CONFIG_RAW_DRIVER is not set # +# I2C support +# +# CONFIG_I2C is not set + +# +# Misc devices +# + +# # Multimedia devices # # CONFIG_VIDEO_DEV is not set @@ -444,7 +445,6 @@ # # Console display driver support # -# CONFIG_VGA_CONSOLE is not set # CONFIG_MDA_CONSOLE is not set CONFIG_STI_CONSOLE=y CONFIG_DUMMY_CONSOLE_COLUMNS=160 @@ -475,6 +475,11 @@ # # +# USB Gadget Support +# +# CONFIG_USB_GADGET is not set + +# # File systems # CONFIG_EXT2_FS=y @@ -511,7 +516,6 @@ # CONFIG_PROC_FS=y CONFIG_PROC_KCORE=y -CONFIG_DEVPTS_FS=y # CONFIG_DEVPTS_FS_XATTR is not set CONFIG_TMPFS=y # CONFIG_HUGETLB_PAGE is not set @@ -520,6 +524,7 @@ # # Miscellaneous filesystems # +# CONFIG_HFSPLUS_FS is not set # CONFIG_CRAMFS is not set # CONFIG_VXFS_FS is not set # CONFIG_HPFS_FS is not set @@ -549,11 +554,11 @@ # # CONFIG_PARTITION_ADVANCED is not set CONFIG_MSDOS_PARTITION=y -CONFIG_NLS=y # # Native Language Support # +CONFIG_NLS=y CONFIG_NLS_DEFAULT="iso8859-1" # CONFIG_NLS_CODEPAGE_437 is not set # CONFIG_NLS_CODEPAGE_737 is not set @@ -628,6 +633,7 @@ # CONFIG_CRYPTO_AES is not set # CONFIG_CRYPTO_CAST5 is not set # CONFIG_CRYPTO_CAST6 is not set +# CONFIG_CRYPTO_ARC4 is not set # CONFIG_CRYPTO_DEFLATE is not set # CONFIG_CRYPTO_TEST is not set diff -Nru a/arch/parisc/configs/a500_defconfig b/arch/parisc/configs/a500_defconfig --- a/arch/parisc/configs/a500_defconfig Sun Mar 14 14:20:06 2004 +++ b/arch/parisc/configs/a500_defconfig Sun Mar 14 14:20:06 2004 @@ -23,6 +23,7 @@ # CONFIG_BSD_PROCESS_ACCT is not set CONFIG_SYSCTL=y CONFIG_LOG_BUF_SHIFT=16 +CONFIG_HOTPLUG=y CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y CONFIG_EMBEDDED=y @@ -72,7 +73,6 @@ # CONFIG_SUPERIO is not set CONFIG_CHASSIS_LCD_LED=y # CONFIG_PDC_CHASSIS is not set -CONFIG_HOTPLUG=y # # PCMCIA/CardBus support @@ -102,6 +102,7 @@ # Generic Driver Options # # CONFIG_FW_LOADER is not set +CONFIG_DEBUG_DRIVER=y # # Memory Technology Devices (MTD) @@ -116,7 +117,6 @@ # # Plug and Play support # -# CONFIG_PNP is not set # # Block devices @@ -195,9 +195,15 @@ CONFIG_SCSI_QLOGIC_FC=m # CONFIG_SCSI_QLOGIC_FC_FIRMWARE is not set CONFIG_SCSI_QLOGIC_1280=m +CONFIG_SCSI_QLA2XXX=y +# CONFIG_SCSI_QLA21XX is not set +# CONFIG_SCSI_QLA22XX is not set +CONFIG_SCSI_QLA2300=m +CONFIG_SCSI_QLA2322=m +CONFIG_SCSI_QLA6312=m +CONFIG_SCSI_QLA6322=m # CONFIG_SCSI_DC395x is not set # CONFIG_SCSI_DC390T is not set -# CONFIG_SCSI_NSP32 is not set CONFIG_SCSI_DEBUG=m # @@ -215,6 +221,7 @@ CONFIG_MD_RAID0=y CONFIG_MD_RAID1=y # CONFIG_MD_RAID5 is not set +# CONFIG_MD_RAID6 is not set # CONFIG_MD_MULTIPATH is not set # CONFIG_BLK_DEV_DM is not set @@ -227,14 +234,17 @@ CONFIG_FUSION_CTL=m # -# IEEE 1394 (FireWire) support (EXPERIMENTAL) +# IEEE 1394 (FireWire) support # # CONFIG_IEEE1394 is not set # # I2O device support # -# CONFIG_I2O is not set + +# +# Macintosh device drivers +# # # Networking support @@ -362,7 +372,7 @@ # # Network testing # -# CONFIG_NET_PKTGEN is not set +CONFIG_NET_PKTGEN=m CONFIG_NETDEVICES=y # @@ -391,9 +401,10 @@ # CONFIG_NET_TULIP=y CONFIG_DE2104X=m -CONFIG_TULIP=y +CONFIG_TULIP=m # CONFIG_TULIP_MWI is not set CONFIG_TULIP_MMIO=y +# CONFIG_TULIP_NAPI is not set # CONFIG_DE4X5 is not set # CONFIG_WINBOND_840 is not set # CONFIG_DM9102 is not set @@ -405,10 +416,12 @@ # CONFIG_AMD8111_ETH is not set # CONFIG_ADAPTEC_STARFIRE is not set # CONFIG_B44 is not set +# CONFIG_FORCEDETH is not set # CONFIG_DGRS is not set CONFIG_EEPRO100=m # CONFIG_EEPRO100_PIO is not set CONFIG_E100=m +CONFIG_E100_NAPI=y # CONFIG_FEALNX is not set CONFIG_NATSEMI=m # CONFIG_NE2K_PCI is not set @@ -418,6 +431,7 @@ # CONFIG_8139TOO_TUNE_TWISTER is not set # CONFIG_8139TOO_8129 is not set # CONFIG_8139_OLD_RX_RESET is not set +CONFIG_8139_RXBUF_IDX=1 # CONFIG_SIS900 is not set CONFIG_EPIC100=m # CONFIG_SUNDANCE is not set @@ -482,13 +496,13 @@ CONFIG_PLX_HERMES=m CONFIG_TMD_HERMES=m CONFIG_PCI_HERMES=m +# CONFIG_ATMEL is not set # # Wireless 802.11b Pcmcia/Cardbus cards support # CONFIG_PCMCIA_HERMES=m CONFIG_AIRO_CS=m -# CONFIG_PCMCIA_ATMEL is not set # CONFIG_PCMCIA_WL3501 is not set CONFIG_NET_WIRELESS=y @@ -535,7 +549,7 @@ # # ISDN subsystem # -# CONFIG_ISDN_BOOL is not set +# CONFIG_ISDN is not set # # Telephony Support @@ -602,25 +616,7 @@ CONFIG_SERIAL_CORE=y CONFIG_SERIAL_CORE_CONSOLE=y CONFIG_UNIX98_PTYS=y -CONFIG_UNIX98_PTY_COUNT=256 - -# -# I2C support -# -# CONFIG_I2C is not set - -# -# I2C Algorithms -# - -# -# I2C Hardware Bus support -# - -# -# I2C Hardware Sensors Chip support -# -# CONFIG_I2C_SENSOR is not set +# CONFIG_LEGACY_PTYS is not set # # Mice @@ -659,6 +655,15 @@ CONFIG_MAX_RAW_DEVS=256 # +# I2C support +# +# CONFIG_I2C is not set + +# +# Misc devices +# + +# # Multimedia devices # # CONFIG_VIDEO_DEV is not set @@ -676,7 +681,6 @@ # # Console display driver support # -# CONFIG_VGA_CONSOLE is not set # CONFIG_MDA_CONSOLE is not set # CONFIG_STI_CONSOLE is not set CONFIG_DUMMY_CONSOLE_COLUMNS=160 @@ -692,6 +696,10 @@ # USB support # # CONFIG_USB is not set + +# +# USB Gadget Support +# # CONFIG_USB_GADGET is not set # @@ -711,6 +719,7 @@ CONFIG_XFS_FS=m # CONFIG_XFS_RT is not set # CONFIG_XFS_QUOTA is not set +# CONFIG_XFS_SECURITY is not set # CONFIG_XFS_POSIX_ACL is not set # CONFIG_MINIX_FS is not set # CONFIG_ROMFS_FS is not set @@ -740,7 +749,6 @@ CONFIG_PROC_FS=y CONFIG_PROC_KCORE=y # CONFIG_DEVFS_FS is not set -CONFIG_DEVPTS_FS=y # CONFIG_DEVPTS_FS_XATTR is not set # CONFIG_TMPFS is not set # CONFIG_HUGETLBFS is not set @@ -753,6 +761,7 @@ # CONFIG_ADFS_FS is not set # CONFIG_AFFS_FS is not set # CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set # CONFIG_BEFS_FS is not set # CONFIG_BFS_FS is not set # CONFIG_EFS_FS is not set @@ -876,6 +885,7 @@ CONFIG_CRYPTO_AES=m CONFIG_CRYPTO_CAST5=m CONFIG_CRYPTO_CAST6=m +# CONFIG_CRYPTO_ARC4 is not set CONFIG_CRYPTO_DEFLATE=m CONFIG_CRYPTO_TEST=m diff -Nru a/arch/parisc/configs/b180_defconfig b/arch/parisc/configs/b180_defconfig --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/parisc/configs/b180_defconfig Sun Mar 14 14:20:09 2004 @@ -0,0 +1,776 @@ +# +# Automatically generated make config: don't edit +# +CONFIG_PARISC=y +CONFIG_MMU=y +CONFIG_STACK_GROWSUP=y +CONFIG_RWSEM_GENERIC_SPINLOCK=y + +# +# Code maturity level options +# +# CONFIG_EXPERIMENTAL is not set +CONFIG_CLEAN_COMPILE=y +CONFIG_STANDALONE=y +CONFIG_BROKEN_ON_SMP=y + +# +# General setup +# +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +# CONFIG_BSD_PROCESS_ACCT is not set +CONFIG_SYSCTL=y +CONFIG_LOG_BUF_SHIFT=15 +# CONFIG_HOTPLUG is not set +# 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 +# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set + +# +# Loadable module support +# +CONFIG_MODULES=y +# CONFIG_MODULE_UNLOAD is not set +CONFIG_OBSOLETE_MODPARM=y +# CONFIG_KMOD is not set + +# +# Processor type and features +# +# CONFIG_PA7000 is not set +# CONFIG_PA7100LC is not set +CONFIG_PA7200=y +# CONFIG_PA8X00 is not set +CONFIG_PA11=y +# CONFIG_64BIT is not set +# CONFIG_SMP is not set +# CONFIG_PREEMPT is not set +# CONFIG_HPUX is not set + +# +# Bus options (PCI, PCMCIA, EISA, GSC, ISA) +# +CONFIG_GSC=y +# CONFIG_HPPB is not set +# CONFIG_IOMMU_CCIO is not set +CONFIG_GSC_LASI=y +CONFIG_GSC_WAX=y +CONFIG_EISA=y +CONFIG_EISA_NAMES=y +CONFIG_ISA=y +CONFIG_PCI=y +CONFIG_PCI_LEGACY_PROC=y +CONFIG_PCI_NAMES=y +CONFIG_GSC_DINO=y +# CONFIG_PCI_LBA is not set +# CONFIG_CHASSIS_LCD_LED is not set +# CONFIG_PDC_CHASSIS is not set + +# +# Executable file formats +# +CONFIG_BINFMT_ELF=y +# CONFIG_BINFMT_MISC is not set + +# +# Device Drivers +# + +# +# Generic Driver Options +# +CONFIG_DEBUG_DRIVER=y + +# +# Memory Technology Devices (MTD) +# +# CONFIG_MTD is not set + +# +# Parallel port support +# +CONFIG_PARPORT=y +CONFIG_PARPORT_PC=y +CONFIG_PARPORT_PC_CML1=y +# CONFIG_PARPORT_SERIAL is not set +CONFIG_PARPORT_GSC=y +# CONFIG_PARPORT_OTHER is not set +# CONFIG_PARPORT_1284 is not set + +# +# Plug and Play support +# +# CONFIG_PNP is not set + +# +# Block devices +# +# CONFIG_BLK_DEV_FD is not set +# CONFIG_BLK_DEV_XD is not set +# CONFIG_PARIDE is not set +# CONFIG_BLK_CPQ_DA is not set +# CONFIG_BLK_CPQ_CISS_DA is not set +# CONFIG_BLK_DEV_DAC960 is not set +CONFIG_BLK_DEV_LOOP=y +CONFIG_BLK_DEV_CRYPTOLOOP=y +# CONFIG_BLK_DEV_NBD is not set +# CONFIG_BLK_DEV_RAM is not set + +# +# ATA/ATAPI/MFM/RLL support +# +# CONFIG_IDE is not set + +# +# SCSI device support +# +CONFIG_SCSI=y +CONFIG_SCSI_PROC_FS=y + +# +# SCSI support type (disk, tape, CD-ROM) +# +CONFIG_BLK_DEV_SD=y +CONFIG_CHR_DEV_ST=y +# CONFIG_CHR_DEV_OSST is not set +CONFIG_BLK_DEV_SR=y +# CONFIG_BLK_DEV_SR_VENDOR is not set +CONFIG_CHR_DEV_SG=y + +# +# Some SCSI devices (e.g. CD jukebox) support multiple LUNs +# +# CONFIG_SCSI_MULTI_LUN is not set +# CONFIG_SCSI_REPORT_LUNS is not set +# CONFIG_SCSI_CONSTANTS is not set +# CONFIG_SCSI_LOGGING is not set + +# +# SCSI low-level drivers +# +# CONFIG_BLK_DEV_3W_XXXX_RAID is not set +# CONFIG_SCSI_7000FASST is not set +# CONFIG_SCSI_ACARD is not set +# CONFIG_SCSI_AHA152X is not set +# CONFIG_SCSI_AHA1542 is not set +# CONFIG_SCSI_AHA1740 is not set +# CONFIG_SCSI_AIC7XXX is not set +# CONFIG_SCSI_AIC7XXX_OLD is not set +# CONFIG_SCSI_AIC79XX is not set +# CONFIG_SCSI_ADVANSYS is not set +# CONFIG_SCSI_IN2000 is not set +# CONFIG_SCSI_MEGARAID is not set +# CONFIG_SCSI_BUSLOGIC is not set +# CONFIG_SCSI_CPQFCTS is not set +# CONFIG_SCSI_DMX3191D is not set +# CONFIG_SCSI_DTC3280 is not set +# CONFIG_SCSI_EATA is not set +# CONFIG_SCSI_EATA_PIO is not set +# CONFIG_SCSI_FUTURE_DOMAIN is not set +# CONFIG_SCSI_GDTH is not set +# CONFIG_SCSI_GENERIC_NCR5380 is not set +# CONFIG_SCSI_GENERIC_NCR5380_MMIO is not set +# CONFIG_SCSI_IPS is not set +# CONFIG_SCSI_INIA100 is not set +# CONFIG_SCSI_PPA is not set +# CONFIG_SCSI_IMM is not set +# CONFIG_SCSI_NCR53C406A is not set +CONFIG_SCSI_LASI700=y +CONFIG_53C700_MEM_MAPPED=y +CONFIG_53C700_LE_ON_BE=y +CONFIG_SCSI_SYM53C8XX_2=y +CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE=0 +CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS=16 +CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64 +# CONFIG_SCSI_SYM53C8XX_IOMAPPED is not set +# CONFIG_SCSI_ZALON is not set +# CONFIG_SCSI_PAS16 is not set +# CONFIG_SCSI_PSI240I is not set +# CONFIG_SCSI_QLOGIC_FAS is not set +# CONFIG_SCSI_QLOGIC_ISP is not set +# CONFIG_SCSI_QLOGIC_FC is not set +# CONFIG_SCSI_QLOGIC_1280 is not set +CONFIG_SCSI_QLA2XXX=y +# CONFIG_SCSI_QLA21XX is not set +# CONFIG_SCSI_QLA22XX is not set +# CONFIG_SCSI_QLA2300 is not set +# CONFIG_SCSI_QLA2322 is not set +# CONFIG_SCSI_QLA6312 is not set +# CONFIG_SCSI_QLA6322 is not set +# CONFIG_SCSI_SIM710 is not set +# CONFIG_SCSI_SYM53C416 is not set +# CONFIG_SCSI_DC390T is not set +# CONFIG_SCSI_T128 is not set +# CONFIG_SCSI_U14_34F is not set +# CONFIG_SCSI_NSP32 is not set +# CONFIG_SCSI_DEBUG is not set + +# +# Old CD-ROM drivers (not SCSI, not IDE) +# +# CONFIG_CD_NO_IDESCSI is not set + +# +# Multi-device support (RAID and LVM) +# +CONFIG_MD=y +CONFIG_BLK_DEV_MD=y +CONFIG_MD_LINEAR=y +CONFIG_MD_RAID0=y +CONFIG_MD_RAID1=y +CONFIG_MD_RAID5=y +# CONFIG_MD_MULTIPATH is not set +# CONFIG_BLK_DEV_DM is not set + +# +# Fusion MPT device support +# +# CONFIG_FUSION is not set + +# +# IEEE 1394 (FireWire) support +# +# CONFIG_IEEE1394 is not set + +# +# I2O device support +# +# CONFIG_I2O is not set + +# +# Macintosh device drivers +# + +# +# Networking support +# +CONFIG_NET=y + +# +# Networking options +# +CONFIG_PACKET=y +CONFIG_PACKET_MMAP=y +CONFIG_NETLINK_DEV=y +CONFIG_UNIX=y +# CONFIG_NET_KEY is not set +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_PNP=y +# CONFIG_IP_PNP_DHCP is not set +CONFIG_IP_PNP_BOOTP=y +# CONFIG_IP_PNP_RARP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_IP_MROUTE is not set +CONFIG_INET_ECN=y +# CONFIG_SYN_COOKIES is not set +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set +# CONFIG_DECNET is not set +# CONFIG_BRIDGE is not set +# CONFIG_NETFILTER is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +CONFIG_NETDEVICES=y + +# +# ARCnet devices +# +# CONFIG_ARCNET is not set +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set + +# +# Ethernet (10 or 100Mbit) +# +CONFIG_NET_ETHERNET=y +# CONFIG_MII is not set +# CONFIG_LASI_82596 is not set +# CONFIG_HAPPYMEAL is not set +# CONFIG_SUNGEM is not set +# CONFIG_NET_VENDOR_3COM is not set +# CONFIG_LANCE is not set +# CONFIG_NET_VENDOR_SMC is not set +# CONFIG_NET_VENDOR_RACAL is not set + +# +# Tulip family network device support +# +CONFIG_NET_TULIP=y +CONFIG_TULIP=y +# CONFIG_TULIP_MMIO is not set +# CONFIG_TULIP_NAPI is not set +# CONFIG_DE4X5 is not set +# CONFIG_WINBOND_840 is not set +# CONFIG_DM9102 is not set +# CONFIG_DEPCA is not set +# CONFIG_HP100 is not set +# CONFIG_NET_ISA is not set +# CONFIG_NET_PCI is not set +# CONFIG_NET_POCKET is not set + +# +# Ethernet (1000 Mbit) +# +# CONFIG_ACENIC is not set +# CONFIG_DL2K is not set +# CONFIG_E1000 is not set +# CONFIG_NS83820 is not set +# CONFIG_HAMACHI 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_PLIP is not set +CONFIG_PPP=y +# CONFIG_PPP_FILTER is not set +# CONFIG_PPP_ASYNC is not set +# CONFIG_PPP_SYNC_TTY is not set +# CONFIG_PPP_DEFLATE is not set +# CONFIG_PPP_BSDCOMP is not set +# CONFIG_SLIP is not set + +# +# Wireless LAN (non-hamradio) +# +CONFIG_NET_RADIO=y + +# +# Obsolete Wireless cards support (pre-802.11) +# +# CONFIG_STRIP is not set +# CONFIG_ARLAN is not set +# CONFIG_WAVELAN is not set + +# +# Wireless 802.11b ISA/PCI cards support +# +# CONFIG_AIRO is not set +# CONFIG_HERMES is not set +CONFIG_NET_WIRELESS=y + +# +# Token Ring devices +# +# CONFIG_TR is not set +# CONFIG_NET_FC is not set + +# +# Wan interfaces +# +# CONFIG_WAN is not set + +# +# Amateur Radio support +# +# CONFIG_HAMRADIO is not set + +# +# IrDA (infrared) support +# +# CONFIG_IRDA is not set + +# +# Bluetooth support +# +# CONFIG_BT is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN is not set + +# +# Telephony Support +# +# CONFIG_PHONE is not set + +# +# Input device support +# +CONFIG_INPUT=y + +# +# Userland interfaces +# +CONFIG_INPUT_MOUSEDEV=y +CONFIG_INPUT_MOUSEDEV_PSAUX=y +CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_TSDEV is not set +CONFIG_INPUT_EVDEV=y +# CONFIG_INPUT_EVBUG is not set + +# +# Input I/O drivers +# +# CONFIG_GAMEPORT is not set +CONFIG_SOUND_GAMEPORT=y +CONFIG_SERIO=y +# CONFIG_SERIO_SERPORT is not set +# CONFIG_SERIO_PARKBD is not set +CONFIG_SERIO_GSCPS2=y +# CONFIG_HP_SDC is not set +# CONFIG_SERIO_PCIPS2 is not set + +# +# Input Device Drivers +# +CONFIG_INPUT_KEYBOARD=y +# CONFIG_KEYBOARD_ATKBD is not set +# CONFIG_KEYBOARD_SUNKBD is not set +# CONFIG_KEYBOARD_XTKBD is not set +# CONFIG_KEYBOARD_NEWTON is not set +# CONFIG_KEYBOARD_HIL_OLD is not set +# CONFIG_KEYBOARD_HIL is not set +CONFIG_INPUT_MOUSE=y +# CONFIG_MOUSE_PS2 is not set +# CONFIG_MOUSE_SERIAL is not set +# CONFIG_MOUSE_INPORT is not set +# CONFIG_MOUSE_LOGIBM is not set +# CONFIG_MOUSE_PC110PAD is not set +# CONFIG_MOUSE_HIL is not set +# CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TOUCHSCREEN is not set +CONFIG_INPUT_MISC=y +# CONFIG_INPUT_PCSPKR is not set +# CONFIG_INPUT_UINPUT is not set +# CONFIG_HP_SDC_RTC is not set + +# +# Character devices +# +CONFIG_VT=y +CONFIG_VT_CONSOLE=y +CONFIG_HW_CONSOLE=y +# CONFIG_SERIAL_NONSTANDARD is not set + +# +# Serial drivers +# +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y +CONFIG_SERIAL_8250_NR_UARTS=4 +CONFIG_SERIAL_8250_EXTENDED=y +CONFIG_SERIAL_8250_MANY_PORTS=y +CONFIG_SERIAL_8250_SHARE_IRQ=y +# CONFIG_SERIAL_8250_DETECT_IRQ is not set +# CONFIG_SERIAL_8250_MULTIPORT is not set +# CONFIG_SERIAL_8250_RSA is not set + +# +# Non-8250 serial port support +# +# CONFIG_SERIAL_MUX is not set +# CONFIG_PDC_CONSOLE is not set +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +CONFIG_UNIX98_PTYS=y +CONFIG_LEGACY_PTYS=y +CONFIG_LEGACY_PTY_COUNT=256 +CONFIG_PRINTER=y +# CONFIG_LP_CONSOLE is not set +# CONFIG_PPDEV is not set +# CONFIG_TIPAR is not set + +# +# Mice +# +# CONFIG_BUSMOUSE is not set +# CONFIG_QIC02_TAPE is not set + +# +# IPMI +# +# CONFIG_IPMI_HANDLER is not set + +# +# Watchdog Cards +# +# CONFIG_WATCHDOG is not set +# CONFIG_NVRAM is not set +CONFIG_GEN_RTC=y +# CONFIG_GEN_RTC_X is not set +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set +# CONFIG_APPLICOM is not set + +# +# Ftape, the floppy tape device driver +# +# CONFIG_FTAPE is not set +# CONFIG_AGP is not set +# CONFIG_DRM is not set +# CONFIG_RAW_DRIVER is not set + +# +# I2C support +# +# CONFIG_I2C is not set + +# +# Misc devices +# + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# Digital Video Broadcasting Devices +# +# CONFIG_DVB is not set + +# +# Graphics support +# +CONFIG_FB=y +# CONFIG_FB_PM2 is not set +# CONFIG_FB_CYBER2000 is not set +# CONFIG_FB_IMSTT is not set +CONFIG_FB_STI=y +# CONFIG_FB_RIVA is not set +# CONFIG_FB_MATROX is not set +# CONFIG_FB_RADEON_OLD is not set +# CONFIG_FB_RADEON is not set +# CONFIG_FB_ATY128 is not set +# CONFIG_FB_ATY is not set +# CONFIG_FB_SIS is not set +# CONFIG_FB_NEOMAGIC is not set +# CONFIG_FB_KYRO is not set +# CONFIG_FB_3DFX is not set +# CONFIG_FB_VOODOO1 is not set +# CONFIG_FB_TRIDENT is not set +# CONFIG_FB_VIRTUAL is not set + +# +# Console display driver support +# +# CONFIG_MDA_CONSOLE is not set +CONFIG_STI_CONSOLE=y +CONFIG_DUMMY_CONSOLE_COLUMNS=160 +CONFIG_DUMMY_CONSOLE_ROWS=64 +CONFIG_DUMMY_CONSOLE=y +CONFIG_FRAMEBUFFER_CONSOLE=y +CONFIG_PCI_CONSOLE=y +# CONFIG_FONTS is not set +CONFIG_FONT_8x8=y +CONFIG_FONT_8x16=y + +# +# Logo configuration +# +CONFIG_LOGO=y +CONFIG_LOGO_LINUX_MONO=y +CONFIG_LOGO_LINUX_VGA16=y +CONFIG_LOGO_LINUX_CLUT224=y +CONFIG_LOGO_PARISC_CLUT224=y + +# +# Sound +# +# CONFIG_SOUND is not set + +# +# USB support +# +# CONFIG_USB is not set + +# +# USB Gadget Support +# +# CONFIG_USB_GADGET is not set + +# +# File systems +# +CONFIG_EXT2_FS=y +# CONFIG_EXT2_FS_XATTR is not set +CONFIG_EXT3_FS=y +# CONFIG_EXT3_FS_XATTR is not set +CONFIG_JBD=y +# CONFIG_JBD_DEBUG is not set +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set +# CONFIG_XFS_FS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_ROMFS_FS is not set +# CONFIG_QUOTA is not set +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set + +# +# CD-ROM/DVD Filesystems +# +CONFIG_ISO9660_FS=y +CONFIG_JOLIET=y +# CONFIG_ZISOFS is not set +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +# CONFIG_FAT_FS is not set +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +CONFIG_PROC_KCORE=y +# CONFIG_DEVPTS_FS_XATTR is not set +CONFIG_TMPFS=y +# CONFIG_HUGETLB_PAGE is not set +CONFIG_RAMFS=y + +# +# Miscellaneous filesystems +# +# CONFIG_HFSPLUS_FS is not set +# CONFIG_CRAMFS is not set +# CONFIG_VXFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set + +# +# Network File Systems +# +CONFIG_NFS_FS=y +CONFIG_NFS_V3=y +CONFIG_NFSD=y +CONFIG_NFSD_V3=y +CONFIG_ROOT_NFS=y +CONFIG_LOCKD=y +CONFIG_LOCKD_V4=y +CONFIG_EXPORTFS=y +CONFIG_SUNRPC=y +# CONFIG_SMB_FS is not set +# CONFIG_CIFS is not set +# CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set + +# +# Partition Types +# +# CONFIG_PARTITION_ADVANCED is not set +CONFIG_MSDOS_PARTITION=y + +# +# Native Language Support +# +CONFIG_NLS=y +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 + +# +# Kernel hacking +# +CONFIG_DEBUG_KERNEL=y +# CONFIG_DEBUG_SLAB is not set +CONFIG_MAGIC_SYSRQ=y +CONFIG_FRAME_POINTER=y +# CONFIG_DEBUG_INFO is not set + +# +# Security options +# +CONFIG_SECURITY=y +# CONFIG_SECURITY_NETWORK is not set +CONFIG_SECURITY_CAPABILITIES=y +# CONFIG_SECURITY_SELINUX is not set + +# +# Cryptographic options +# +CONFIG_CRYPTO=y +# CONFIG_CRYPTO_HMAC is not set +# CONFIG_CRYPTO_NULL is not set +# CONFIG_CRYPTO_MD4 is not set +# CONFIG_CRYPTO_MD5 is not set +# CONFIG_CRYPTO_SHA1 is not set +# CONFIG_CRYPTO_SHA256 is not set +# CONFIG_CRYPTO_SHA512 is not set +# CONFIG_CRYPTO_DES is not set +# CONFIG_CRYPTO_BLOWFISH is not set +# CONFIG_CRYPTO_TWOFISH is not set +# CONFIG_CRYPTO_SERPENT is not set +# CONFIG_CRYPTO_AES is not set +# CONFIG_CRYPTO_CAST5 is not set +# CONFIG_CRYPTO_CAST6 is not set +# CONFIG_CRYPTO_ARC4 is not set +# CONFIG_CRYPTO_DEFLATE is not set +# CONFIG_CRYPTO_TEST is not set + +# +# Library routines +# +CONFIG_CRC32=y diff -Nru a/arch/parisc/configs/c3000_defconfig b/arch/parisc/configs/c3000_defconfig --- a/arch/parisc/configs/c3000_defconfig Sun Mar 14 14:20:07 2004 +++ b/arch/parisc/configs/c3000_defconfig Sun Mar 14 14:20:07 2004 @@ -23,6 +23,7 @@ # CONFIG_BSD_PROCESS_ACCT is not set CONFIG_SYSCTL=y CONFIG_LOG_BUF_SHIFT=16 +CONFIG_HOTPLUG=y CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y CONFIG_EMBEDDED=y @@ -71,7 +72,6 @@ CONFIG_SUPERIO=y # CONFIG_CHASSIS_LCD_LED is not set # CONFIG_PDC_CHASSIS is not set -CONFIG_HOTPLUG=y # # PCMCIA/CardBus support @@ -101,6 +101,7 @@ # Generic Driver Options # CONFIG_FW_LOADER=y +CONFIG_DEBUG_DRIVER=y # # Memory Technology Devices (MTD) @@ -128,7 +129,6 @@ # CONFIG_BLK_DEV_CRYPTOLOOP is not set # CONFIG_BLK_DEV_NBD is not set # CONFIG_BLK_DEV_RAM is not set -# CONFIG_BLK_DEV_INITRD is not set # # ATA/ATAPI/MFM/RLL support @@ -153,6 +153,7 @@ # # IDE chipset support/bugfixes # +CONFIG_IDE_GENERIC=y CONFIG_BLK_DEV_IDEPCI=y CONFIG_IDEPCI_SHARE_IRQ=y # CONFIG_BLK_DEV_OFFBOARD is not set @@ -161,7 +162,6 @@ CONFIG_BLK_DEV_IDEDMA_PCI=y # CONFIG_BLK_DEV_IDEDMA_FORCED is not set # CONFIG_IDEDMA_PCI_AUTO is not set -# 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 @@ -252,11 +252,13 @@ CONFIG_SCSI_QLOGIC_FC=m # CONFIG_SCSI_QLOGIC_FC_FIRMWARE is not set CONFIG_SCSI_QLOGIC_1280=m -CONFIG_SCSI_QLA2XXX_CONFIG=y -CONFIG_SCSI_QLA2XXX=m +CONFIG_SCSI_QLA2XXX=y # CONFIG_SCSI_QLA21XX is not set # CONFIG_SCSI_QLA22XX is not set -CONFIG_SCSI_QLA23XX=m +CONFIG_SCSI_QLA2300=m +CONFIG_SCSI_QLA2322=m +CONFIG_SCSI_QLA6312=m +CONFIG_SCSI_QLA6322=m # CONFIG_SCSI_DC395x is not set # CONFIG_SCSI_DC390T is not set # CONFIG_SCSI_NSP32 is not set @@ -280,8 +282,9 @@ CONFIG_MD_RAID1=y # CONFIG_MD_RAID5 is not set # CONFIG_MD_RAID6 is not set -# CONFIG_MD_MULTIPATH is not set -# CONFIG_BLK_DEV_DM is not set +CONFIG_MD_MULTIPATH=y +CONFIG_BLK_DEV_DM=y +# CONFIG_DM_CRYPT is not set # # Fusion MPT device support @@ -292,7 +295,7 @@ CONFIG_FUSION_CTL=m # -# IEEE 1394 (FireWire) support (EXPERIMENTAL) +# IEEE 1394 (FireWire) support # # CONFIG_IEEE1394 is not set @@ -302,6 +305,10 @@ # CONFIG_I2O is not set # +# Macintosh device drivers +# + +# # Networking support # CONFIG_NET=y @@ -457,6 +464,7 @@ CONFIG_TULIP=y # CONFIG_TULIP_MWI is not set # CONFIG_TULIP_MMIO is not set +# CONFIG_TULIP_NAPI is not set CONFIG_DE4X5=m CONFIG_WINBOND_840=m # CONFIG_DM9102 is not set @@ -474,6 +482,7 @@ CONFIG_EEPRO100=m # CONFIG_EEPRO100_PIO is not set CONFIG_E100=m +# CONFIG_E100_NAPI is not set # CONFIG_FEALNX is not set CONFIG_NATSEMI=m # CONFIG_NE2K_PCI is not set @@ -483,6 +492,7 @@ # CONFIG_8139TOO_TUNE_TWISTER is not set # CONFIG_8139TOO_8129 is not set # CONFIG_8139_OLD_RX_RESET is not set +CONFIG_8139_RXBUF_IDX=1 # CONFIG_SIS900 is not set # CONFIG_EPIC100 is not set # CONFIG_SUNDANCE is not set @@ -571,7 +581,7 @@ # # ISDN subsystem # -# CONFIG_ISDN_BOOL is not set +# CONFIG_ISDN is not set # # Telephony Support @@ -652,7 +662,8 @@ CONFIG_SERIAL_CORE=y CONFIG_SERIAL_CORE_CONSOLE=y CONFIG_UNIX98_PTYS=y -CONFIG_UNIX98_PTY_COUNT=256 +CONFIG_LEGACY_PTYS=y +CONFIG_LEGACY_PTY_COUNT=256 # # Mice @@ -696,6 +707,10 @@ # CONFIG_I2C is not set # +# Misc devices +# + +# # Multimedia devices # # CONFIG_VIDEO_DEV is not set @@ -716,6 +731,7 @@ CONFIG_FB_STI=y # CONFIG_FB_RIVA is not set # CONFIG_FB_MATROX is not set +# CONFIG_FB_RADEON_OLD is not set # CONFIG_FB_RADEON is not set # CONFIG_FB_ATY128 is not set # CONFIG_FB_ATY is not set @@ -731,7 +747,6 @@ # # Console display driver support # -# CONFIG_VGA_CONSOLE is not set # CONFIG_MDA_CONSOLE is not set CONFIG_STI_CONSOLE=y CONFIG_DUMMY_CONSOLE_COLUMNS=160 @@ -823,7 +838,6 @@ # USB Imaging devices # CONFIG_USB_MDC800=m -CONFIG_USB_SCANNER=m CONFIG_USB_MICROTEK=m CONFIG_USB_HPUSBSCSI=m @@ -867,6 +881,10 @@ # CONFIG_USB_LCD is not set # CONFIG_USB_LED is not set # CONFIG_USB_TEST is not set + +# +# USB Gadget Support +# # CONFIG_USB_GADGET is not set # @@ -883,6 +901,7 @@ CONFIG_XFS_FS=m # CONFIG_XFS_RT is not set # CONFIG_XFS_QUOTA is not set +# CONFIG_XFS_SECURITY is not set # CONFIG_XFS_POSIX_ACL is not set # CONFIG_MINIX_FS is not set # CONFIG_ROMFS_FS is not set @@ -912,7 +931,6 @@ CONFIG_PROC_FS=y CONFIG_PROC_KCORE=y # CONFIG_DEVFS_FS is not set -CONFIG_DEVPTS_FS=y # CONFIG_DEVPTS_FS_XATTR is not set CONFIG_TMPFS=y # CONFIG_HUGETLBFS is not set @@ -925,6 +943,7 @@ # CONFIG_ADFS_FS is not set # CONFIG_AFFS_FS is not set # CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set # CONFIG_BEFS_FS is not set # CONFIG_BFS_FS is not set # CONFIG_EFS_FS is not set @@ -1046,6 +1065,7 @@ CONFIG_CRYPTO_AES=m CONFIG_CRYPTO_CAST5=m CONFIG_CRYPTO_CAST6=m +# CONFIG_CRYPTO_ARC4 is not set CONFIG_CRYPTO_DEFLATE=m CONFIG_CRYPTO_TEST=m diff -Nru a/arch/parisc/defconfig b/arch/parisc/defconfig --- a/arch/parisc/defconfig Sun Mar 14 14:20:06 2004 +++ b/arch/parisc/defconfig Sun Mar 14 14:20:06 2004 @@ -22,6 +22,7 @@ # CONFIG_BSD_PROCESS_ACCT is not set CONFIG_SYSCTL=y CONFIG_LOG_BUF_SHIFT=15 +# CONFIG_HOTPLUG is not set CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y # CONFIG_EMBEDDED is not set @@ -31,6 +32,7 @@ CONFIG_IOSCHED_NOOP=y CONFIG_IOSCHED_AS=y CONFIG_IOSCHED_DEADLINE=y +# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set # # Loadable module support @@ -71,7 +73,6 @@ CONFIG_SUPERIO=y CONFIG_CHASSIS_LCD_LED=y CONFIG_PDC_CHASSIS=y -# CONFIG_HOTPLUG is not set # # Executable file formats @@ -86,6 +87,7 @@ # # Generic Driver Options # +# CONFIG_DEBUG_DRIVER is not set # # Memory Technology Devices (MTD) @@ -108,7 +110,6 @@ # # Plug and Play support # -# CONFIG_PNP is not set # # Block devices @@ -195,8 +196,16 @@ # CONFIG_SCSI_QLOGIC_ISP is not set # CONFIG_SCSI_QLOGIC_FC is not set # CONFIG_SCSI_QLOGIC_1280 is not set +CONFIG_SCSI_QLA2XXX=y +# CONFIG_SCSI_QLA21XX is not set +# CONFIG_SCSI_QLA22XX is not set +# CONFIG_SCSI_QLA2300 is not set +# CONFIG_SCSI_QLA2322 is not set +# CONFIG_SCSI_QLA6312 is not set +# CONFIG_SCSI_QLA6322 is not set # CONFIG_SCSI_SIM710 is not set # CONFIG_SCSI_DC395x is not set +# CONFIG_SCSI_DC390T is not set # CONFIG_SCSI_NSP32 is not set # CONFIG_SCSI_DEBUG is not set @@ -209,6 +218,7 @@ CONFIG_MD_RAID0=y CONFIG_MD_RAID1=y CONFIG_MD_RAID5=y +# CONFIG_MD_RAID6 is not set # CONFIG_MD_MULTIPATH is not set # CONFIG_BLK_DEV_DM is not set @@ -218,7 +228,7 @@ # CONFIG_FUSION is not set # -# IEEE 1394 (FireWire) support (EXPERIMENTAL) +# IEEE 1394 (FireWire) support # # CONFIG_IEEE1394 is not set @@ -228,6 +238,10 @@ # CONFIG_I2O is not set # +# Macintosh device drivers +# + +# # Networking support # CONFIG_NET=y @@ -319,6 +333,7 @@ CONFIG_TULIP=y # CONFIG_TULIP_MWI is not set # CONFIG_TULIP_MMIO is not set +# CONFIG_TULIP_NAPI is not set # CONFIG_DE4X5 is not set # CONFIG_WINBOND_840 is not set # CONFIG_DM9102 is not set @@ -330,6 +345,7 @@ # CONFIG_ADAPTEC_STARFIRE is not set # CONFIG_AC3200 is not set # CONFIG_B44 is not set +# CONFIG_FORCEDETH is not set # CONFIG_DGRS is not set # CONFIG_EEPRO100 is not set # CONFIG_E100 is not set @@ -386,6 +402,7 @@ # CONFIG_AIRO=y # CONFIG_HERMES is not set +# CONFIG_ATMEL is not set CONFIG_NET_WIRELESS=y # @@ -419,7 +436,7 @@ # # ISDN subsystem # -# CONFIG_ISDN_BOOL is not set +# CONFIG_ISDN is not set # # Telephony Support @@ -450,10 +467,10 @@ CONFIG_SOUND_GAMEPORT=y CONFIG_SERIO=y # CONFIG_SERIO_SERPORT is not set -# CONFIG_SERIO_CT82C710 is not set # CONFIG_SERIO_PARKBD is not set +CONFIG_SERIO_GSCPS2=y CONFIG_HP_SDC=y -# CONFIG_HIL_MLC is not set +CONFIG_HIL_MLC=y # CONFIG_SERIO_PCIPS2 is not set # @@ -464,10 +481,11 @@ # CONFIG_KEYBOARD_SUNKBD is not set # CONFIG_KEYBOARD_XTKBD is not set # CONFIG_KEYBOARD_NEWTON is not set -# CONFIG_KEYBOARD_HIL_OLD is not set +CONFIG_KEYBOARD_HIL=y CONFIG_INPUT_MOUSE=y # CONFIG_MOUSE_PS2 is not set # CONFIG_MOUSE_SERIAL is not set +# CONFIG_MOUSE_HIL is not set CONFIG_INPUT_JOYSTICK=y # CONFIG_JOYSTICK_IFORCE is not set # CONFIG_JOYSTICK_WARRIOR is not set @@ -485,7 +503,6 @@ CONFIG_INPUT_MISC=y # CONFIG_INPUT_PCSPKR is not set # CONFIG_INPUT_UINPUT is not set -CONFIG_INPUT_GSC=y CONFIG_HP_SDC_RTC=y # @@ -517,31 +534,14 @@ CONFIG_SERIAL_CORE=y CONFIG_SERIAL_CORE_CONSOLE=y CONFIG_UNIX98_PTYS=y -CONFIG_UNIX98_PTY_COUNT=256 +CONFIG_LEGACY_PTYS=y +CONFIG_LEGACY_PTY_COUNT=256 CONFIG_PRINTER=y # CONFIG_LP_CONSOLE is not set # CONFIG_PPDEV is not set # CONFIG_TIPAR is not set # -# I2C support -# -# CONFIG_I2C is not set - -# -# I2C Algorithms -# - -# -# I2C Hardware Bus support -# - -# -# I2C Hardware Sensors Chip support -# -# CONFIG_I2C_SENSOR is not set - -# # Mice # # CONFIG_BUSMOUSE is not set @@ -572,6 +572,15 @@ # CONFIG_RAW_DRIVER is not set # +# I2C support +# +# CONFIG_I2C is not set + +# +# Misc devices +# + +# # Multimedia devices # # CONFIG_VIDEO_DEV is not set @@ -585,16 +594,19 @@ # Graphics support # CONFIG_FB=y +# CONFIG_FB_PM2 is not set # CONFIG_FB_CYBER2000 is not set # CONFIG_FB_IMSTT is not set CONFIG_FB_STI=y # CONFIG_FB_RIVA is not set # CONFIG_FB_MATROX is not set +# CONFIG_FB_RADEON_OLD is not set # CONFIG_FB_RADEON is not set # CONFIG_FB_ATY128 is not set # CONFIG_FB_ATY is not set # CONFIG_FB_SIS is not set # CONFIG_FB_NEOMAGIC is not set +# CONFIG_FB_KYRO is not set # CONFIG_FB_3DFX is not set # CONFIG_FB_VOODOO1 is not set # CONFIG_FB_TRIDENT is not set @@ -603,7 +615,6 @@ # # Console display driver support # -# CONFIG_VGA_CONSOLE is not set # CONFIG_MDA_CONSOLE is not set CONFIG_STI_CONSOLE=y CONFIG_DUMMY_CONSOLE_COLUMNS=160 @@ -686,7 +697,6 @@ # USB Imaging devices # # CONFIG_USB_MDC800 is not set -# CONFIG_USB_SCANNER is not set # CONFIG_USB_MICROTEK is not set # CONFIG_USB_HPUSBSCSI is not set @@ -721,11 +731,19 @@ # # USB Miscellaneous drivers # +# CONFIG_USB_EMI62 is not set +# CONFIG_USB_EMI26 is not set # CONFIG_USB_TIGL is not set # CONFIG_USB_AUERSWALD is not set # CONFIG_USB_RIO500 is not set +# CONFIG_USB_LEGOTOWER is not set # CONFIG_USB_BRLVGER is not set # CONFIG_USB_LCD is not set +# CONFIG_USB_LED is not set + +# +# USB Gadget Support +# # CONFIG_USB_GADGET is not set # @@ -766,7 +784,6 @@ CONFIG_PROC_FS=y CONFIG_PROC_KCORE=y # CONFIG_DEVFS_FS is not set -CONFIG_DEVPTS_FS=y # CONFIG_DEVPTS_FS_XATTR is not set CONFIG_TMPFS=y # CONFIG_HUGETLB_PAGE is not set @@ -778,6 +795,7 @@ # CONFIG_ADFS_FS is not set # CONFIG_AFFS_FS is not set # CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set # CONFIG_BEFS_FS is not set # CONFIG_BFS_FS is not set # CONFIG_EFS_FS is not set @@ -809,7 +827,6 @@ # CONFIG_CIFS is not set # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set -# CONFIG_INTERMEZZO_FS is not set # CONFIG_AFS_FS is not set # @@ -817,11 +834,11 @@ # # CONFIG_PARTITION_ADVANCED is not set CONFIG_MSDOS_PARTITION=y -CONFIG_NLS=y # # Native Language Support # +CONFIG_NLS=y CONFIG_NLS_DEFAULT="iso8859-1" # CONFIG_NLS_CODEPAGE_437 is not set # CONFIG_NLS_CODEPAGE_737 is not set @@ -899,6 +916,7 @@ # CONFIG_CRYPTO_AES is not set # CONFIG_CRYPTO_CAST5 is not set # CONFIG_CRYPTO_CAST6 is not set +# CONFIG_CRYPTO_ARC4 is not set # CONFIG_CRYPTO_DEFLATE is not set # CONFIG_CRYPTO_TEST is not set diff -Nru a/arch/parisc/hpux/entry_hpux.S b/arch/parisc/hpux/entry_hpux.S --- a/arch/parisc/hpux/entry_hpux.S Sun Mar 14 14:20:06 2004 +++ b/arch/parisc/hpux/entry_hpux.S Sun Mar 14 14:20:06 2004 @@ -1,10 +1,22 @@ -/* +/* syscall table for HPUX specific syscalls * - * Linux/PARISC Project (http://www.parisc-linux.org/) + * Linux/PA-RISC Project (http://www.parisc-linux.org/) + * Copyright (C) 1999 Matthew Wilcox * - * modified by Matthew Wilcox 1999-07-26 + * 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 diff -Nru a/arch/parisc/kernel/drivers.c b/arch/parisc/kernel/drivers.c --- a/arch/parisc/kernel/drivers.c Sun Mar 14 14:20:08 2004 +++ b/arch/parisc/kernel/drivers.c Sun Mar 14 14:20:08 2004 @@ -618,6 +618,7 @@ tmp1); /* make the generic dma mask a pointer to the parisc one */ dev->dev.dma_mask = &dev->dma_mask; + dev->dev.coherent_dma_mask = dev->dma_mask; pr_debug("device_register(%s)\n", dev->dev.bus_id); device_register(&dev->dev); } diff -Nru a/arch/parisc/kernel/entry.S b/arch/parisc/kernel/entry.S --- a/arch/parisc/kernel/entry.S Sun Mar 14 14:20:06 2004 +++ b/arch/parisc/kernel/entry.S Sun Mar 14 14:20:06 2004 @@ -533,7 +533,7 @@ ldil L%CLONE_UNTRACED, %r26 ldo CLONE_VM(%r26), %r26 /* Force CLONE_VM since only init_mm */ or %r26, %r24, %r26 /* will have kernel mappings. */ - copy %r0, %r25 /* stack_start */ + ldi 1, %r25 /* stack_start, signals kernel thread */ stw %r0, -52(%r30) /* user_tid */ #ifdef __LP64__ ldo -16(%r30),%r29 /* Reference param save area */ diff -Nru a/arch/parisc/kernel/hardware.c b/arch/parisc/kernel/hardware.c --- a/arch/parisc/kernel/hardware.c Sun Mar 14 14:20:07 2004 +++ b/arch/parisc/kernel/hardware.c Sun Mar 14 14:20:07 2004 @@ -333,8 +333,9 @@ {HPHW_A_DMA, 0x01F, 0x00089, 0x80, "SkyHawk 100/120 FW-SCSI"}, {HPHW_A_DMA, 0x027, 0x00089, 0x80, "Piranha 100 FW-SCSI"}, {HPHW_A_DMA, 0x032, 0x00089, 0x80, "Raven T' Core FW-SCSI"}, - {HPHW_A_DMA, 0x03b, 0x00089, 0x80, "Raven U/L2 Core FW-SCSI"}, - {HPHW_A_DMA, 0x03d, 0x00089, 0x80, "Merlin 160 Core FW-SCSI"}, + {HPHW_A_DMA, 0x03B, 0x00089, 0x80, "Raven U/L2 Core FW-SCSI"}, + {HPHW_A_DMA, 0x03C, 0x00089, 0x80, "Merlin 132 Core FW-SCSI"}, + {HPHW_A_DMA, 0x03D, 0x00089, 0x80, "Merlin 160 Core FW-SCSI"}, {HPHW_A_DMA, 0x044, 0x00089, 0x80, "Mohawk Core FW-SCSI"}, {HPHW_A_DMA, 0x051, 0x00089, 0x80, "Firehawk FW-SCSI"}, {HPHW_A_DMA, 0x058, 0x00089, 0x80, "FireHawk 200 FW-SCSI"}, diff -Nru a/arch/parisc/kernel/head64.S b/arch/parisc/kernel/head64.S --- a/arch/parisc/kernel/head64.S Sun Mar 14 14:20:05 2004 +++ b/arch/parisc/kernel/head64.S Sun Mar 14 14:20:05 2004 @@ -165,9 +165,9 @@ #endif /* CONFIG_SMP */ /* Save the rfi target address */ - ldo -THREAD_SZ_ALGN(%sp), %r1 - ldd TI_TASK(%r1), %r1 - std %r11, TASK_PT_GR11(%r1) + ldd TI_TASK-THREAD_SZ_ALGN(%sp), %r10 + tophys_r1 %r10 + std %r11, TASK_PT_GR11(%r10) #ifndef CONFIG_PDC_NARROW /* Switch to wide mode; Superdome doesn't support narrow PDC @@ -197,9 +197,9 @@ stext_pdc_ret: /* restore rfi target address*/ - ldo -THREAD_SZ_ALGN(%sp), %r1 - ldd TI_TASK(%r1), %r1 - ldd TASK_PT_GR11(%r1), %r11 + ldd TI_TASK-THREAD_SZ_ALGN(%sp), %r10 + tophys_r1 %r10 + ldd TASK_PT_GR11(%r10), %r11 /* PARANOID: clear user scratch/user space SR's */ mtsp %r0,%sr0 @@ -302,6 +302,7 @@ /* Initialize the SP - monarch sets up smp_init_current_idle_task */ load32 PA(smp_init_current_idle_task),%sp ldd 0(%sp),%sp /* load task address */ + ldd TASK_THREAD_INFO(%sp), %sp mtctl %sp,%cr30 /* store in cr30 */ ldo THREAD_SZ_ALGN(%sp),%sp tophys_r1 %sp diff -Nru a/arch/parisc/kernel/module.c b/arch/parisc/kernel/module.c --- a/arch/parisc/kernel/module.c Sun Mar 14 14:20:09 2004 +++ b/arch/parisc/kernel/module.c Sun Mar 14 14:20:09 2004 @@ -1,25 +1,28 @@ -/* Kernel module help for parisc. +/* Kernel dynamically loadable module help for PARISC. + * + * The best reference for this stuff is probably the Processor- + * Specific ELF Supplement for PA-RISC: + * http://ftp.parisc-linux.org/docs/elf-pa-hp.pdf + * + * Linux/PA-RISC Project (http://www.parisc-linux.org/) + * Copyright (C) 2003 Randolph Chung + * + * + * 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 + */ - 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 - - (c) 2003 Randolph Chung - - The best reference for this stuff is probably the Processor- - Specific ELF Supplement for PA-RISC: - http://ftp.parisc-linux.org/docs/elf-pa-hp.pdf -*/ #include #include #include diff -Nru a/arch/parisc/kernel/pacache.S b/arch/parisc/kernel/pacache.S --- a/arch/parisc/kernel/pacache.S Sun Mar 14 14:20:06 2004 +++ b/arch/parisc/kernel/pacache.S Sun Mar 14 14:20:06 2004 @@ -221,6 +221,7 @@ LDREG ICACHE_STRIDE(%r1),%arg1 LDREG ICACHE_COUNT(%r1),%arg2 LDREG ICACHE_LOOP(%r1),%arg3 + rsm PSW_SM_I,%r22 /* No mmgt ops during loop*/ ADDIB= -1,%arg3,fioneloop /* Preadjust and test */ movb,<,n %arg3,%r31,fisync /* If loop < 0, do sync */ @@ -237,6 +238,7 @@ fisync: sync + mtsm %r22 bv %r0(%r2) nop .exit diff -Nru a/arch/parisc/kernel/parisc_ksyms.c b/arch/parisc/kernel/parisc_ksyms.c --- a/arch/parisc/kernel/parisc_ksyms.c Sun Mar 14 14:20:08 2004 +++ b/arch/parisc/kernel/parisc_ksyms.c Sun Mar 14 14:20:08 2004 @@ -67,8 +67,10 @@ #include EXPORT_SYMBOL(lcopy_to_user); EXPORT_SYMBOL(lcopy_from_user); -EXPORT_SYMBOL(lstrnlen_user); +EXPORT_SYMBOL(lcopy_in_user); +EXPORT_SYMBOL(lstrncpy_from_user); EXPORT_SYMBOL(lclear_user); +EXPORT_SYMBOL(lstrnlen_user); #ifndef __LP64__ /* Needed so insmod can set dp value */ diff -Nru a/arch/parisc/kernel/pci-dma.c b/arch/parisc/kernel/pci-dma.c --- a/arch/parisc/kernel/pci-dma.c Sun Mar 14 14:20:08 2004 +++ b/arch/parisc/kernel/pci-dma.c Sun Mar 14 14:20:08 2004 @@ -372,7 +372,7 @@ ** ISA cards will certainly only support 24-bit DMA addressing. ** Not clear if we can, want, or need to support ISA. */ - if (!dev || *dev->dma_mask != 0xffffffff) + if (!dev || *dev->coherent_dma_mask < 0xffffffff) gfp |= GFP_DMA; #endif return (void *)vaddr; @@ -413,7 +413,7 @@ /* * For PCI_DMA_FROMDEVICE this flush is not necessary for the * simple map/unmap case. However, it IS necessary if if - * pci_dma_sync_single has been called and the buffer reused. + * pci_dma_sync_single_* has been called and the buffer reused. */ flush_kernel_dcache_range((unsigned long) phys_to_virt(dma_handle), size); @@ -453,7 +453,7 @@ return; } -static void pa11_dma_sync_single(struct device *dev, dma_addr_t dma_handle, unsigned long offset, size_t size, enum dma_data_direction direction) +static void pa11_dma_sync_single_for_cpu(struct device *dev, dma_addr_t dma_handle, unsigned long offset, size_t size, enum dma_data_direction direction) { if (direction == DMA_NONE) BUG(); @@ -461,7 +461,25 @@ flush_kernel_dcache_range((unsigned long) phys_to_virt(dma_handle) + offset, size); } -static void pa11_dma_sync_sg(struct device *dev, struct scatterlist *sglist, int nents, enum dma_data_direction direction) +static void pa11_dma_sync_single_for_device(struct device *dev, dma_addr_t dma_handle, unsigned long offset, size_t size, enum dma_data_direction direction) +{ + if (direction == DMA_NONE) + BUG(); + + flush_kernel_dcache_range((unsigned long) phys_to_virt(dma_handle) + offset, size); +} + +static void pa11_dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sglist, int nents, enum dma_data_direction direction) +{ + int i; + + /* once we do combining we'll need to use phys_to_virt(sg_dma_address(sglist)) */ + + for (i = 0; i < nents; i++, sglist++ ) + flush_kernel_dcache_range(sg_virt_addr(sglist), sglist->length); +} + +static void pa11_dma_sync_sg_for_device(struct device *dev, struct scatterlist *sglist, int nents, enum dma_data_direction direction) { int i; @@ -480,8 +498,10 @@ .unmap_single = pa11_dma_unmap_single, .map_sg = pa11_dma_map_sg, .unmap_sg = pa11_dma_unmap_sg, - .dma_sync_single = pa11_dma_sync_single, - .dma_sync_sg = pa11_dma_sync_sg, + .dma_sync_single_for_cpu = pa11_dma_sync_single_for_cpu, + .dma_sync_single_for_device = pa11_dma_sync_single_for_device, + .dma_sync_sg_for_cpu = pa11_dma_sync_sg_for_cpu, + .dma_sync_sg_for_device = pa11_dma_sync_sg_for_device, }; static void *fail_alloc_consistent(struct device *dev, size_t size, @@ -519,8 +539,10 @@ .unmap_single = pa11_dma_unmap_single, .map_sg = pa11_dma_map_sg, .unmap_sg = pa11_dma_unmap_sg, - .dma_sync_single = pa11_dma_sync_single, - .dma_sync_sg = pa11_dma_sync_sg, + .dma_sync_single_cpu = pa11_dma_sync_single_cpu, + .dma_sync_single_device = pa11_dma_sync_single_device, + .dma_sync_sg_cpu = pa11_dma_sync_sg_cpu, + .dma_sync_sg_device = pa11_dma_sync_sg_device, }; diff -Nru a/arch/parisc/kernel/pci.c b/arch/parisc/kernel/pci.c --- a/arch/parisc/kernel/pci.c Sun Mar 14 14:20:05 2004 +++ b/arch/parisc/kernel/pci.c Sun Mar 14 14:20:05 2004 @@ -21,6 +21,7 @@ #include #include #include /* for L1_CACHE_BYTES */ +#include #define DEBUG_RESOURCES 0 #define DEBUG_CONFIG 0 @@ -145,9 +146,13 @@ return str; } - /* Used in drivers/pci/quirks.c */ -struct pci_fixup pcibios_fixups[] = { {0} }; +struct pci_fixup pcibios_fixups[] = { +#ifdef CONFIG_SUPERIO + { PCI_FIXUP_HEADER, PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_87415, superio_fixup_pci }, +#endif + { 0 } +}; /* diff -Nru a/arch/parisc/kernel/process.c b/arch/parisc/kernel/process.c --- a/arch/parisc/kernel/process.c Sun Mar 14 14:20:08 2004 +++ b/arch/parisc/kernel/process.c Sun Mar 14 14:20:08 2004 @@ -32,7 +32,6 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#define __KERNEL_SYSCALLS__ #include #include @@ -251,6 +250,16 @@ struct pt_regs *regs) { int *user_tid = (int *)regs->gr[26]; + + /* usp must be word aligned. This also prevents users from + * passing in the value 1 (which is the signal for a special + * return for a kernel thread) */ + usp = ALIGN(usp, 4); + + /* A zero value for usp means use the current stack */ + if(usp == 0) + usp = regs->gr[30]; + return do_fork(clone_flags & ~CLONE_IDLETASK, usp, regs, 0, user_tid, NULL); } @@ -291,7 +300,7 @@ * We rely on the fact that kernel_thread passes * in zero for usp. */ - if (usp == 0) { + if (usp == 1) { /* kernel thread */ cregs->ksp = (((unsigned long)(ti)) + THREAD_SZ_ALGN); /* Must exit via ret_from_kernel_thread in order diff -Nru a/arch/parisc/kernel/smp.c b/arch/parisc/kernel/smp.c --- a/arch/parisc/kernel/smp.c Sun Mar 14 14:20:08 2004 +++ b/arch/parisc/kernel/smp.c Sun Mar 14 14:20:08 2004 @@ -16,7 +16,6 @@ ** the Free Software Foundation; either version 2 of the License, or ** (at your option) any later version. */ -#define __KERNEL_SYSCALLS__ #undef ENTRY_SYS_CPUS /* syscall support for iCOD-like functionality */ #include diff -Nru a/arch/parisc/kernel/sys_parisc.c b/arch/parisc/kernel/sys_parisc.c --- a/arch/parisc/kernel/sys_parisc.c Sun Mar 14 14:20:08 2004 +++ b/arch/parisc/kernel/sys_parisc.c Sun Mar 14 14:20:08 2004 @@ -242,14 +242,6 @@ return sys_readahead(fd, (loff_t)high << 32 | low, count); } -/* - * This changes the io permissions bitmap in the current task. - */ -asmlinkage long sys_ioperm(unsigned long from, unsigned long num, int turn_on) -{ - return -ENOSYS; -} - asmlinkage unsigned long sys_alloc_hugepages(int key, unsigned long addr, unsigned long len, int prot, int flag) { return -ENOMEM; diff -Nru a/arch/parisc/kernel/vmlinux.lds.S b/arch/parisc/kernel/vmlinux.lds.S --- a/arch/parisc/kernel/vmlinux.lds.S Sun Mar 14 14:20:06 2004 +++ b/arch/parisc/kernel/vmlinux.lds.S Sun Mar 14 14:20:06 2004 @@ -61,6 +61,9 @@ RODATA /* writeable */ + . = ALIGN(4096); /* Make sure this is paged aligned so + that we can properly leave these + as writable */ data_start = .; . = ALIGN(16); /* Exception table */ diff -Nru a/arch/ppc/kernel/misc.S b/arch/ppc/kernel/misc.S --- a/arch/ppc/kernel/misc.S Sun Mar 14 14:20:08 2004 +++ b/arch/ppc/kernel/misc.S Sun Mar 14 14:20:08 2004 @@ -1108,17 +1108,7 @@ li r3,-1; \ blr -#define __NR__exit __NR_exit - -SYSCALL(setsid) -SYSCALL(open) -SYSCALL(read) -SYSCALL(write) -SYSCALL(lseek) -SYSCALL(close) -SYSCALL(dup) SYSCALL(execve) -SYSCALL(waitpid) /* Why isn't this a) automatic, b) written in 'C'? */ .data diff -Nru a/arch/ppc/kernel/ppc_ksyms.c b/arch/ppc/kernel/ppc_ksyms.c --- a/arch/ppc/kernel/ppc_ksyms.c Sun Mar 14 14:20:08 2004 +++ b/arch/ppc/kernel/ppc_ksyms.c Sun Mar 14 14:20:08 2004 @@ -32,8 +32,6 @@ #include #include #include -#define __KERNEL_SYSCALLS__ -#include #include #include #include @@ -189,10 +187,6 @@ EXPORT_SYMBOL(flush_dcache_all); #endif -EXPORT_SYMBOL(open); -EXPORT_SYMBOL(read); -EXPORT_SYMBOL(lseek); -EXPORT_SYMBOL(close); EXPORT_SYMBOL(start_thread); EXPORT_SYMBOL(kernel_thread); diff -Nru a/arch/ppc/kernel/smp.c b/arch/ppc/kernel/smp.c --- a/arch/ppc/kernel/smp.c Sun Mar 14 14:20:08 2004 +++ b/arch/ppc/kernel/smp.c Sun Mar 14 14:20:08 2004 @@ -17,8 +17,6 @@ #include #include #include -#define __KERNEL_SYSCALLS__ -#include #include #include #include diff -Nru a/arch/ppc/platforms/chrp_smp.c b/arch/ppc/platforms/chrp_smp.c --- a/arch/ppc/platforms/chrp_smp.c Sun Mar 14 14:20:07 2004 +++ b/arch/ppc/platforms/chrp_smp.c Sun Mar 14 14:20:07 2004 @@ -16,8 +16,6 @@ #include #include #include -#define __KERNEL_SYSCALLS__ -#include #include #include diff -Nru a/arch/ppc/platforms/pmac_feature.c b/arch/ppc/platforms/pmac_feature.c --- a/arch/ppc/platforms/pmac_feature.c Sun Mar 14 14:20:08 2004 +++ b/arch/ppc/platforms/pmac_feature.c Sun Mar 14 14:20:08 2004 @@ -1360,7 +1360,7 @@ mb(); k2_skiplist[1] = NULL; } else { - k2_skiplist[0] = pdev; + k2_skiplist[1] = pdev; mb(); MACIO_BIC(KEYLARGO_FCR1, K2_FCR1_FW_CLK_ENABLE); } diff -Nru a/arch/ppc/platforms/pmac_smp.c b/arch/ppc/platforms/pmac_smp.c --- a/arch/ppc/platforms/pmac_smp.c Sun Mar 14 14:20:07 2004 +++ b/arch/ppc/platforms/pmac_smp.c Sun Mar 14 14:20:07 2004 @@ -29,8 +29,6 @@ #include #include #include -#define __KERNEL_SYSCALLS__ -#include #include #include #include diff -Nru a/arch/ppc64/kernel/misc.S b/arch/ppc64/kernel/misc.S --- a/arch/ppc64/kernel/misc.S Sun Mar 14 14:20:08 2004 +++ b/arch/ppc64/kernel/misc.S Sun Mar 14 14:20:08 2004 @@ -565,35 +565,6 @@ ld r30,-16(r1) blr - .section ".toc","aw" -.SYSCALL_ERRNO: - .tc errno[TC],errno - - .section ".text" - .align 3 - -#define SYSCALL(name) \ -_GLOBAL(name) \ - li r0,__NR_##name; \ - sc; \ - bnslr; \ - ld r4,.SYSCALL_ERRNO@toc(2); \ - std r3,0(r4); \ - li r3,-1; \ - blr - -#define __NR__exit __NR_exit - -SYSCALL(setsid) -SYSCALL(open) -SYSCALL(read) -SYSCALL(write) -SYSCALL(lseek) -SYSCALL(close) -SYSCALL(dup) -SYSCALL(execve) -SYSCALL(waitpid) - #ifdef CONFIG_PPC_ISERIES /* hack hack hack */ #define ppc_rtas sys_ni_syscall #endif diff -Nru a/arch/ppc64/kernel/pmac_smp.c b/arch/ppc64/kernel/pmac_smp.c --- a/arch/ppc64/kernel/pmac_smp.c Sun Mar 14 14:20:06 2004 +++ b/arch/ppc64/kernel/pmac_smp.c Sun Mar 14 14:20:06 2004 @@ -29,8 +29,6 @@ #include #include #include -#define __KERNEL_SYSCALLS__ -#include #include #include #include diff -Nru a/arch/ppc64/mm/numa.c b/arch/ppc64/mm/numa.c --- a/arch/ppc64/mm/numa.c Sun Mar 14 14:20:07 2004 +++ b/arch/ppc64/mm/numa.c Sun Mar 14 14:20:07 2004 @@ -22,9 +22,17 @@ #define dbg(args...) #endif -int numa_cpu_lookup_table[NR_CPUS] = { [ 0 ... (NR_CPUS - 1)] = -1}; +#ifdef DEBUG_NUMA +#define ARRAY_INITIALISER -1 +#else +#define ARRAY_INITIALISER 0 +#endif + +int numa_cpu_lookup_table[NR_CPUS] = { [ 0 ... (NR_CPUS - 1)] = + ARRAY_INITIALISER}; int numa_memory_lookup_table[MAX_MEMORY >> MEMORY_INCREMENT_SHIFT] = - { [ 0 ... ((MAX_MEMORY >> MEMORY_INCREMENT_SHIFT) - 1)] = -1}; + { [ 0 ... ((MAX_MEMORY >> MEMORY_INCREMENT_SHIFT) - 1)] = + ARRAY_INITIALISER}; cpumask_t numa_cpumask_lookup_table[MAX_NUMNODES]; int nr_cpus_in_node[MAX_NUMNODES] = { [0 ... (MAX_NUMNODES -1)] = 0}; diff -Nru a/arch/s390/appldata/appldata_mem.c b/arch/s390/appldata/appldata_mem.c --- a/arch/s390/appldata/appldata_mem.c Sun Mar 14 14:20:06 2004 +++ b/arch/s390/appldata/appldata_mem.c Sun Mar 14 14:20:06 2004 @@ -54,7 +54,9 @@ u64 freeswap; /* free swap space */ // New in 2.6 --> - u64 pgalloc; /* page allocations */ + u64 pgalloc_high; /* page allocations */ + u64 pgalloc_normal; + u64 pgalloc_dma; u64 pgfault; /* page faults (major+minor) */ u64 pgmajfault; /* page faults (major only) */ // <-- New in 2.6 @@ -69,7 +71,9 @@ P_DEBUG("pgpgout = %8lu KB\n", mem_data->pgpgout); P_DEBUG("pswpin = %8lu Pages\n", mem_data->pswpin); P_DEBUG("pswpout = %8lu Pages\n", mem_data->pswpout); - P_DEBUG("pgalloc = %8lu \n", mem_data->pgalloc); + P_DEBUG("pgalloc_high = %8lu \n", mem_data->pgalloc_high); + P_DEBUG("pgalloc_normal = %8lu \n", mem_data->pgalloc_normal); + P_DEBUG("pgalloc_dma = %8lu \n", mem_data->pgalloc_dma); P_DEBUG("pgfault = %8lu \n", mem_data->pgfault); P_DEBUG("pgmajfault = %8lu \n", mem_data->pgmajfault); P_DEBUG("sharedram = %8lu KB\n", mem_data->sharedram); @@ -105,11 +109,14 @@ mem_data->pgpgout = ps.pgpgout >> 1; mem_data->pswpin = ps.pswpin; mem_data->pswpout = ps.pswpout; - mem_data->pgalloc = ps.pgalloc; + mem_data->pgalloc_high = ps.pgalloc_high; + mem_data->pgalloc_normal = ps.pgalloc_normal; + mem_data->pgalloc_dma = ps.pgalloc_dma; mem_data->pgfault = ps.pgfault; mem_data->pgmajfault = ps.pgmajfault; -P_DEBUG("pgalloc = %lu, pgfree = %lu\n", ps.pgalloc, ps.pgfree); +P_DEBUG("pgalloc_high = %lu, pgalloc_normal = %lu, pgalloc_dma = %lu, pgfree = %lu\n", + ps.pgalloc_high, ps.pgalloc_normal, ps.pgalloc_dma, ps.pgfree); si_meminfo(&val); mem_data->sharedram = val.sharedram; diff -Nru a/arch/s390/kernel/sys_s390.c b/arch/s390/kernel/sys_s390.c --- a/arch/s390/kernel/sys_s390.c Sun Mar 14 14:20:07 2004 +++ b/arch/s390/kernel/sys_s390.c Sun Mar 14 14:20:07 2004 @@ -289,11 +289,6 @@ return error; } -asmlinkage long sys_ioperm(unsigned long from, unsigned long num, int on) -{ - return -ENOSYS; -} - #else /* CONFIG_ARCH_S390X */ asmlinkage int s390x_newuname(struct new_utsname * name) diff -Nru a/arch/s390/kernel/syscalls.S b/arch/s390/kernel/syscalls.S --- a/arch/s390/kernel/syscalls.S Sun Mar 14 14:20:06 2004 +++ b/arch/s390/kernel/syscalls.S Sun Mar 14 14:20:06 2004 @@ -109,7 +109,7 @@ NI_SYSCALL /* old profil syscall */ SYSCALL(sys_statfs,sys_statfs,compat_sys_statfs_wrapper) SYSCALL(sys_fstatfs,sys_fstatfs,compat_sys_fstatfs_wrapper) /* 100 */ -SYSCALL(sys_ioperm,sys_ni_syscall,sys_ni_syscall) +NI_SYSCALL /* ioperm for i386 */ SYSCALL(sys_socketcall,sys_socketcall,compat_sys_socketcall_wrapper) SYSCALL(sys_syslog,sys_syslog,sys32_syslog_wrapper) SYSCALL(sys_setitimer,sys_setitimer,compat_sys_setitimer_wrapper) diff -Nru a/arch/sparc/kernel/ioport.c b/arch/sparc/kernel/ioport.c --- a/arch/sparc/kernel/ioport.c Sun Mar 14 14:20:08 2004 +++ b/arch/sparc/kernel/ioport.c Sun Mar 14 14:20:08 2004 @@ -360,7 +360,7 @@ /* */ -void sbus_dma_sync_single(struct sbus_dev *sdev, dma_addr_t ba, size_t size, int direction) +void sbus_dma_sync_single_for_cpu(struct sbus_dev *sdev, dma_addr_t ba, size_t size, int direction) { #if 0 unsigned long va; @@ -380,9 +380,34 @@ #endif } -void sbus_dma_sync_sg(struct sbus_dev *sdev, struct scatterlist *sg, int n, int direction) +void sbus_dma_sync_single_for_device(struct sbus_dev *sdev, dma_addr_t ba, size_t size, int direction) { - printk("sbus_dma_sync_sg: not implemented yet\n"); +#if 0 + unsigned long va; + struct resource *res; + + /* We do not need the resource, just print a message if invalid. */ + res = _sparc_find_resource(&_sparc_dvma, ba); + if (res == NULL) + panic("sbus_dma_sync_single: 0x%x\n", ba); + + va = page_address(mmu_translate_dvma(ba)); /* XXX higmem */ + /* + * XXX This bogosity will be fixed with the iommu rewrite coming soon + * to a kernel near you. - Anton + */ + /* mmu_inval_dma_area(va, (size + PAGE_SIZE-1) & PAGE_MASK); */ +#endif +} + +void sbus_dma_sync_sg_for_cpu(struct sbus_dev *sdev, struct scatterlist *sg, int n, int direction) +{ + printk("sbus_dma_sync_sg_for_cpu: not implemented yet\n"); +} + +void sbus_dma_sync_sg_for_device(struct sbus_dev *sdev, struct scatterlist *sg, int n, int direction) +{ + printk("sbus_dma_sync_sg_for_device: not implemented yet\n"); } #endif /* CONFIG_SBUS */ @@ -482,7 +507,7 @@ * The 32-bit bus address to use is returned. * * Once the device is given the dma address, the device owns this memory - * until either pci_unmap_single or pci_dma_sync_single is performed. + * until either pci_unmap_single or pci_dma_sync_single_* is performed. */ dma_addr_t pci_map_single(struct pci_dev *hwdev, void *ptr, size_t size, int direction) @@ -591,10 +616,21 @@ * If you perform a pci_map_single() but wish to interrogate the * buffer using the cpu, yet do not wish to teardown the PCI dma * mapping, you must call this function before doing so. At the - * next point you give the PCI dma address back to the card, the + * next point you give the PCI dma address back to the card, you + * must first perform a pci_dma_sync_for_device, and then the * device again owns the buffer. */ -void pci_dma_sync_single(struct pci_dev *hwdev, dma_addr_t ba, size_t size, int direction) +void pci_dma_sync_single_for_cpu(struct pci_dev *hwdev, dma_addr_t ba, size_t size, int direction) +{ + if (direction == PCI_DMA_NONE) + BUG(); + if (direction != PCI_DMA_TODEVICE) { + mmu_inval_dma_area((unsigned long)phys_to_virt(ba), + (size + PAGE_SIZE-1) & PAGE_MASK); + } +} + +void pci_dma_sync_single_for_device(struct pci_dev *hwdev, dma_addr_t ba, size_t size, int direction) { if (direction == PCI_DMA_NONE) BUG(); @@ -607,10 +643,27 @@ /* Make physical memory consistent for a set of streaming * mode DMA translations after a transfer. * - * The same as pci_dma_sync_single but for a scatter-gather list, + * The same as pci_dma_sync_single_* but for a scatter-gather list, * same rules and usage. */ -void pci_dma_sync_sg(struct pci_dev *hwdev, struct scatterlist *sg, int nents, int direction) +void pci_dma_sync_sg_for_cpu(struct pci_dev *hwdev, struct scatterlist *sg, int nents, int direction) +{ + int n; + + if (direction == PCI_DMA_NONE) + BUG(); + if (direction != PCI_DMA_TODEVICE) { + for (n = 0; n < nents; n++) { + if (page_address(sg->page) == NULL) BUG(); + mmu_inval_dma_area( + (unsigned long) page_address(sg->page), + (sg->length + PAGE_SIZE-1) & PAGE_MASK); + sg++; + } + } +} + +void pci_dma_sync_sg_for_device(struct pci_dev *hwdev, struct scatterlist *sg, int nents, int direction) { int n; diff -Nru a/arch/sparc/kernel/process.c b/arch/sparc/kernel/process.c --- a/arch/sparc/kernel/process.c Sun Mar 14 14:20:06 2004 +++ b/arch/sparc/kernel/process.c Sun Mar 14 14:20:06 2004 @@ -9,7 +9,6 @@ * This file handles the architecture-dependent parts of process handling.. */ -#define __KERNEL_SYSCALLS__ #include #include @@ -19,7 +18,6 @@ #include #include #include -#include #include #include #include diff -Nru a/arch/sparc/kernel/setup.c b/arch/sparc/kernel/setup.c --- a/arch/sparc/kernel/setup.c Sun Mar 14 14:20:05 2004 +++ b/arch/sparc/kernel/setup.c Sun Mar 14 14:20:05 2004 @@ -389,11 +389,6 @@ } console_initcall(set_preferred_console); -asmlinkage long sys_ioperm(unsigned long from, unsigned long num, int on) -{ - return -EIO; -} - extern char *sparc_cpu_type[]; extern char *sparc_fpu_type[]; diff -Nru a/arch/sparc/kernel/smp.c b/arch/sparc/kernel/smp.c --- a/arch/sparc/kernel/smp.c Sun Mar 14 14:20:06 2004 +++ b/arch/sparc/kernel/smp.c Sun Mar 14 14:20:06 2004 @@ -33,9 +33,6 @@ #include #include -#define __KERNEL_SYSCALLS__ -#include - #define IRQ_RESCHEDULE 13 #define IRQ_STOP_CPU 14 #define IRQ_CROSS_CALL 15 diff -Nru a/arch/sparc/kernel/sparc_ksyms.c b/arch/sparc/kernel/sparc_ksyms.c --- a/arch/sparc/kernel/sparc_ksyms.c Sun Mar 14 14:20:06 2004 +++ b/arch/sparc/kernel/sparc_ksyms.c Sun Mar 14 14:20:06 2004 @@ -205,8 +205,10 @@ EXPORT_SYMBOL(sbus_unmap_single); EXPORT_SYMBOL(sbus_map_sg); EXPORT_SYMBOL(sbus_unmap_sg); -EXPORT_SYMBOL(sbus_dma_sync_single); -EXPORT_SYMBOL(sbus_dma_sync_sg); +EXPORT_SYMBOL(sbus_dma_sync_single_for_cpu); +EXPORT_SYMBOL(sbus_dma_sync_single_for_device); +EXPORT_SYMBOL(sbus_dma_sync_sg_for_cpu); +EXPORT_SYMBOL(sbus_dma_sync_sg_for_device); EXPORT_SYMBOL(sbus_iounmap); EXPORT_SYMBOL(sbus_ioremap); #endif @@ -218,7 +220,10 @@ EXPORT_SYMBOL(pci_free_consistent); EXPORT_SYMBOL(pci_map_single); EXPORT_SYMBOL(pci_unmap_single); -EXPORT_SYMBOL(pci_dma_sync_single); +EXPORT_SYMBOL(pci_dma_sync_single_for_cpu); +EXPORT_SYMBOL(pci_dma_sync_single_for_device); +EXPORT_SYMBOL(pci_dma_sync_sg_for_cpu); +EXPORT_SYMBOL(pci_dma_sync_sg_for_device); /* Actually, ioremap/iounmap are not PCI specific. But it is ok for drivers. */ EXPORT_SYMBOL(ioremap); EXPORT_SYMBOL(iounmap); diff -Nru a/arch/sparc/kernel/sun4d_smp.c b/arch/sparc/kernel/sun4d_smp.c --- a/arch/sparc/kernel/sun4d_smp.c Sun Mar 14 14:20:06 2004 +++ b/arch/sparc/kernel/sun4d_smp.c Sun Mar 14 14:20:06 2004 @@ -32,9 +32,6 @@ #include #include -#define __KERNEL_SYSCALLS__ -#include - #define IRQ_CROSS_CALL 15 extern ctxd_t *srmmu_ctx_table_phys; diff -Nru a/arch/sparc/kernel/sun4m_smp.c b/arch/sparc/kernel/sun4m_smp.c --- a/arch/sparc/kernel/sun4m_smp.c Sun Mar 14 14:20:08 2004 +++ b/arch/sparc/kernel/sun4m_smp.c Sun Mar 14 14:20:08 2004 @@ -27,9 +27,6 @@ #include #include -#define __KERNEL_SYSCALLS__ -#include - #define IRQ_RESCHEDULE 13 #define IRQ_STOP_CPU 14 #define IRQ_CROSS_CALL 15 diff -Nru a/arch/sparc64/kernel/pci_iommu.c b/arch/sparc64/kernel/pci_iommu.c --- a/arch/sparc64/kernel/pci_iommu.c Sun Mar 14 14:20:06 2004 +++ b/arch/sparc64/kernel/pci_iommu.c Sun Mar 14 14:20:06 2004 @@ -661,7 +661,7 @@ /* Make physical memory consistent for a single * streaming mode DMA translation after a transfer. */ -void pci_dma_sync_single(struct pci_dev *pdev, dma_addr_t bus_addr, size_t sz, int direction) +void pci_dma_sync_single_for_cpu(struct pci_dev *pdev, dma_addr_t bus_addr, size_t sz, int direction) { struct pcidev_cookie *pcp; struct pci_iommu *iommu; @@ -722,7 +722,7 @@ /* Make physical memory consistent for a set of streaming * mode DMA translations after a transfer. */ -void pci_dma_sync_sg(struct pci_dev *pdev, struct scatterlist *sglist, int nelems, int direction) +void pci_dma_sync_sg_for_cpu(struct pci_dev *pdev, struct scatterlist *sglist, int nelems, int direction) { struct pcidev_cookie *pcp; struct pci_iommu *iommu; diff -Nru a/arch/sparc64/kernel/process.c b/arch/sparc64/kernel/process.c --- a/arch/sparc64/kernel/process.c Sun Mar 14 14:20:07 2004 +++ b/arch/sparc64/kernel/process.c Sun Mar 14 14:20:07 2004 @@ -10,7 +10,6 @@ * This file handles the architecture-dependent parts of process handling.. */ -#define __KERNEL_SYSCALLS__ #include #include @@ -22,7 +21,6 @@ #include #include #include -#include #include #include #include @@ -43,6 +41,7 @@ #include #include #include +#include /* #define VERBOSE_SHOWREGS */ diff -Nru a/arch/sparc64/kernel/sbus.c b/arch/sparc64/kernel/sbus.c --- a/arch/sparc64/kernel/sbus.c Sun Mar 14 14:20:08 2004 +++ b/arch/sparc64/kernel/sbus.c Sun Mar 14 14:20:08 2004 @@ -540,7 +540,7 @@ spin_unlock_irqrestore(&iommu->lock, flags); } -void sbus_dma_sync_single(struct sbus_dev *sdev, dma_addr_t base, size_t size, int direction) +void sbus_dma_sync_single_for_cpu(struct sbus_dev *sdev, dma_addr_t base, size_t size, int direction) { struct sbus_iommu *iommu = sdev->bus->iommu; unsigned long flags; @@ -552,7 +552,11 @@ spin_unlock_irqrestore(&iommu->lock, flags); } -void sbus_dma_sync_sg(struct sbus_dev *sdev, struct scatterlist *sg, int nents, int direction) +void sbus_dma_sync_single_for_device(struct sbus_dev *sdev, dma_addr_t base, size_t size, int direction) +{ +} + +void sbus_dma_sync_sg_for_cpu(struct sbus_dev *sdev, struct scatterlist *sg, int nents, int direction) { struct sbus_iommu *iommu = sdev->bus->iommu; unsigned long flags, size; @@ -570,6 +574,10 @@ spin_lock_irqsave(&iommu->lock, flags); strbuf_flush(iommu, base, size >> IO_PAGE_SHIFT); spin_unlock_irqrestore(&iommu->lock, flags); +} + +void sbus_dma_sync_sg_for_device(struct sbus_dev *sdev, struct scatterlist *sg, int nents, int direction) +{ } /* Enable 64-bit DVMA mode for the given device. */ diff -Nru a/arch/sparc64/kernel/setup.c b/arch/sparc64/kernel/setup.c --- a/arch/sparc64/kernel/setup.c Sun Mar 14 14:20:06 2004 +++ b/arch/sparc64/kernel/setup.c Sun Mar 14 14:20:06 2004 @@ -603,11 +603,6 @@ } console_initcall(set_preferred_console); -asmlinkage long sys_ioperm(unsigned long from, unsigned long num, int on) -{ - return -EIO; -} - /* BUFFER is PAGE_SIZE bytes long. */ extern char *sparc_cpu_type; diff -Nru a/arch/sparc64/kernel/smp.c b/arch/sparc64/kernel/smp.c --- a/arch/sparc64/kernel/smp.c Sun Mar 14 14:20:05 2004 +++ b/arch/sparc64/kernel/smp.c Sun Mar 14 14:20:05 2004 @@ -36,9 +36,6 @@ #include #include -#define __KERNEL_SYSCALLS__ -#include - extern int linux_num_cpus; extern void calibrate_delay(void); diff -Nru a/arch/sparc64/kernel/sparc64_ksyms.c b/arch/sparc64/kernel/sparc64_ksyms.c --- a/arch/sparc64/kernel/sparc64_ksyms.c Sun Mar 14 14:20:08 2004 +++ b/arch/sparc64/kernel/sparc64_ksyms.c Sun Mar 14 14:20:08 2004 @@ -213,8 +213,8 @@ EXPORT_SYMBOL(sbus_unmap_single); EXPORT_SYMBOL(sbus_map_sg); EXPORT_SYMBOL(sbus_unmap_sg); -EXPORT_SYMBOL(sbus_dma_sync_single); -EXPORT_SYMBOL(sbus_dma_sync_sg); +EXPORT_SYMBOL(sbus_dma_sync_single_for_cpu); +EXPORT_SYMBOL(sbus_dma_sync_sg_for_cpu); #endif EXPORT_SYMBOL(outsb); EXPORT_SYMBOL(outsw); @@ -232,8 +232,8 @@ EXPORT_SYMBOL(pci_unmap_single); EXPORT_SYMBOL(pci_map_sg); EXPORT_SYMBOL(pci_unmap_sg); -EXPORT_SYMBOL(pci_dma_sync_single); -EXPORT_SYMBOL(pci_dma_sync_sg); +EXPORT_SYMBOL(pci_dma_sync_single_for_cpu); +EXPORT_SYMBOL(pci_dma_sync_sg_for_cpu); EXPORT_SYMBOL(pci_dma_supported); #endif diff -Nru a/arch/sparc64/kernel/sys_sparc32.c b/arch/sparc64/kernel/sys_sparc32.c --- a/arch/sparc64/kernel/sys_sparc32.c Sun Mar 14 14:20:07 2004 +++ b/arch/sparc64/kernel/sys_sparc32.c Sun Mar 14 14:20:07 2004 @@ -282,11 +282,6 @@ __put_user(i->tv_usec, &o->tv_usec))); } -asmlinkage long sys32_ioperm(u32 from, u32 num, int on) -{ - return sys_ioperm((unsigned long)from, (unsigned long)num, on); -} - struct msgbuf32 { s32 mtype; char mtext[1]; }; struct ipc_perm32 diff -Nru a/arch/v850/kernel/rte_mb_a_pci.c b/arch/v850/kernel/rte_mb_a_pci.c --- a/arch/v850/kernel/rte_mb_a_pci.c Sun Mar 14 14:20:06 2004 +++ b/arch/v850/kernel/rte_mb_a_pci.c Sun Mar 14 14:20:06 2004 @@ -687,10 +687,11 @@ If you perform a pci_map_single() but wish to interrogate the buffer using the cpu, yet do not wish to teardown the PCI dma mapping, you must call this function before doing so. At the next - point you give the PCI dma address back to the card, the device - again owns the buffer. */ + point you give the PCI dma address back to the card, you must first + perform a pci_dma_sync_for_device, and then the device again owns + the buffer. */ void -pci_dma_sync_single (struct pci_dev *pdev, dma_addr_t dma_addr, size_t size, +pci_dma_sync_single_for_cpu (struct pci_dev *pdev, dma_addr_t dma_addr, size_t size, int dir) { void *mb_sram_addr = PCI_TO_MB_SRAM (dma_addr); @@ -700,6 +701,22 @@ if (dir == PCI_DMA_FROMDEVICE) memcpy (mapping->cpu_addr, mb_sram_addr, size); else if (dir == PCI_DMA_TODEVICE) + ; /* nothing to do */ + else + panic("pci_dma_sync_single: unsupported sync dir: %d", dir); +} + +void +pci_dma_sync_single_for_device (struct pci_dev *pdev, dma_addr_t dma_addr, size_t size, + int dir) +{ + void *mb_sram_addr = PCI_TO_MB_SRAM (dma_addr); + struct dma_mapping *mapping = find_dma_mapping (mb_sram_addr); + + /* Synchronize the DMA buffer with the CPU buffer if necessary. */ + if (dir == PCI_DMA_FROMDEVICE) + ; /* nothing to do */ + else if (dir == PCI_DMA_TODEVICE) memcpy (mb_sram_addr, mapping->cpu_addr, size); else panic("pci_dma_sync_single: unsupported sync dir: %d", dir); @@ -724,11 +741,18 @@ } /* Make physical memory consistent for a set of streaming mode DMA - translations after a transfer. The same as pci_dma_sync_single but + translations after a transfer. The same as pci_dma_sync_single_* but for a scatter-gather list, same rules and usage. */ void -pci_dma_sync_sg (struct pci_dev *dev, struct scatterlist *sg, int sg_len, +pci_dma_sync_sg_for_cpu (struct pci_dev *dev, struct scatterlist *sg, int sg_len, + int dir) +{ + BUG (); +} + +void +pci_dma_sync_sg_for_device (struct pci_dev *dev, struct scatterlist *sg, int sg_len, int dir) { BUG (); @@ -770,4 +794,5 @@ EXPORT_SYMBOL (pci_unmap_single); EXPORT_SYMBOL (pci_alloc_consistent); EXPORT_SYMBOL (pci_free_consistent); -EXPORT_SYMBOL (pci_dma_sync_single); +EXPORT_SYMBOL (pci_dma_sync_single_for_cpu); +EXPORT_SYMBOL (pci_dma_sync_single_for_device); diff -Nru a/arch/x86_64/Kconfig b/arch/x86_64/Kconfig --- a/arch/x86_64/Kconfig Sun Mar 14 14:20:08 2004 +++ b/arch/x86_64/Kconfig Sun Mar 14 14:20:08 2004 @@ -160,9 +160,10 @@ with major 203 and minors 0 to 31 for /dev/cpu/0/cpuid to /dev/cpu/31/cpuid. +# disable it for opteron optimized builds because it pulls in ACPI_BOOT config X86_HT bool - depends on SMP + depends on SMP && !MK8 default y config MATH_EMULATION @@ -329,6 +330,11 @@ bool depends on PCI default y + +config PCI_MMCONFIG + bool "Support mmconfig PCI config space access" + depends on PCI + select ACPI_BOOT # the drivers/pci/msi.c code needs to be fixed first before enabling config PCI_USE_VECTOR diff -Nru a/arch/x86_64/Makefile b/arch/x86_64/Makefile --- a/arch/x86_64/Makefile Sun Mar 14 14:20:08 2004 +++ b/arch/x86_64/Makefile Sun Mar 14 14:20:08 2004 @@ -63,7 +63,7 @@ libs-y += arch/x86_64/lib/ core-y += arch/x86_64/kernel/ arch/x86_64/mm/ core-$(CONFIG_IA32_EMULATION) += arch/x86_64/ia32/ -drivers-$(CONFIG_PCI) += arch/i386/pci/ +drivers-$(CONFIG_PCI) += arch/x86_64/pci/ drivers-$(CONFIG_OPROFILE) += arch/x86_64/oprofile/ boot := arch/x86_64/boot diff -Nru a/arch/x86_64/defconfig b/arch/x86_64/defconfig --- a/arch/x86_64/defconfig Sun Mar 14 14:20:07 2004 +++ b/arch/x86_64/defconfig Sun Mar 14 14:20:07 2004 @@ -26,7 +26,7 @@ CONFIG_SYSVIPC=y # CONFIG_BSD_PROCESS_ACCT is not set CONFIG_SYSCTL=y -CONFIG_LOG_BUF_SHIFT=18 +CONFIG_LOG_BUF_SHIFT=17 # CONFIG_HOTPLUG is not set CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y @@ -47,7 +47,8 @@ CONFIG_MODULE_FORCE_UNLOAD=y CONFIG_OBSOLETE_MODPARM=y # CONFIG_MODVERSIONS is not set -# CONFIG_KMOD is not set +CONFIG_KMOD=y +CONFIG_STOP_MACHINE=y # # Processor type and features @@ -93,20 +94,19 @@ CONFIG_ACPI_SLEEP=y CONFIG_ACPI_SLEEP_PROC_FS=y CONFIG_ACPI_AC=y -CONFIG_ACPI_BATTERY=y +# CONFIG_ACPI_BATTERY is not set CONFIG_ACPI_BUTTON=y CONFIG_ACPI_FAN=y CONFIG_ACPI_PROCESSOR=y CONFIG_ACPI_THERMAL=y # CONFIG_ACPI_ASUS is not set -CONFIG_ACPI_TOSHIBA=y -CONFIG_ACPI_DEBUG=y +# CONFIG_ACPI_TOSHIBA is not set +# CONFIG_ACPI_DEBUG is not set CONFIG_ACPI_BUS=y CONFIG_ACPI_EC=y CONFIG_ACPI_POWER=y CONFIG_ACPI_PCI=y CONFIG_ACPI_SYSTEM=y -# CONFIG_ACPI_RELAXED_AML is not set # CONFIG_X86_PM_TIMER is not set # @@ -119,16 +119,17 @@ # CONFIG_PCI=y CONFIG_PCI_DIRECT=y -# CONFIG_PCI_LEGACY_PROC is not set +CONFIG_PCI_MMCONFIG=y +CONFIG_PCI_LEGACY_PROC=y # CONFIG_PCI_NAMES is not set # # Executable file formats / Emulations # CONFIG_BINFMT_ELF=y -# CONFIG_BINFMT_MISC is not set +CONFIG_BINFMT_MISC=y CONFIG_IA32_EMULATION=y -# CONFIG_IA32_AOUT is not set +CONFIG_IA32_AOUT=y CONFIG_COMPAT=y CONFIG_UID16=y @@ -139,6 +140,7 @@ # # Generic Driver Options # +# CONFIG_DEBUG_DRIVER is not set # # Memory Technology Devices (MTD) @@ -148,7 +150,14 @@ # # Parallel port support # -# CONFIG_PARPORT is not set +CONFIG_PARPORT=y +CONFIG_PARPORT_PC=y +CONFIG_PARPORT_PC_CML1=y +# CONFIG_PARPORT_SERIAL is not set +# CONFIG_PARPORT_PC_FIFO is not set +# CONFIG_PARPORT_PC_SUPERIO is not set +# CONFIG_PARPORT_OTHER is not set +CONFIG_PARPORT_1284=y # # Plug and Play support @@ -158,6 +167,7 @@ # Block devices # CONFIG_BLK_DEV_FD=y +# CONFIG_PARIDE is not set # CONFIG_BLK_CPQ_DA is not set # CONFIG_BLK_CPQ_CISS_DA is not set # CONFIG_BLK_DEV_DAC960 is not set @@ -165,11 +175,8 @@ CONFIG_BLK_DEV_LOOP=y # CONFIG_BLK_DEV_CRYPTOLOOP is not set # CONFIG_BLK_DEV_NBD is not set -CONFIG_BLK_DEV_RAM=y -CONFIG_BLK_DEV_RAM_SIZE=4096 -CONFIG_BLK_DEV_INITRD=y -CONFIG_LBD=y -# CONFIG_DCSSBLK is not set +# CONFIG_BLK_DEV_RAM is not set +# CONFIG_LBD is not set # # ATA/ATAPI/MFM/RLL support @@ -187,7 +194,7 @@ 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_BLK_DEV_IDESCSI=m # CONFIG_IDE_TASK_IOCTL is not set # CONFIG_IDE_TASKFILE_IO is not set @@ -195,11 +202,12 @@ # IDE chipset support/bugfixes # CONFIG_IDE_GENERIC=y -# CONFIG_BLK_DEV_CMD640 is not set +CONFIG_BLK_DEV_CMD640=y +# CONFIG_BLK_DEV_CMD640_ENHANCED is not set CONFIG_BLK_DEV_IDEPCI=y -# CONFIG_IDEPCI_SHARE_IRQ is not set +CONFIG_IDEPCI_SHARE_IRQ=y # CONFIG_BLK_DEV_OFFBOARD is not set -# CONFIG_BLK_DEV_GENERIC is not set +CONFIG_BLK_DEV_GENERIC=y # CONFIG_BLK_DEV_OPTI621 is not set # CONFIG_BLK_DEV_RZ1000 is not set CONFIG_BLK_DEV_IDEDMA_PCI=y @@ -218,16 +226,16 @@ # 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=y +# CONFIG_BLK_DEV_PIIX is not set # CONFIG_BLK_DEV_NS87415 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 # CONFIG_BLK_DEV_SIIMAGE is not set -# CONFIG_BLK_DEV_SIS5513 is not set +CONFIG_BLK_DEV_SIS5513=y # CONFIG_BLK_DEV_SLC90E66 is not set # CONFIG_BLK_DEV_TRM290 is not set -# CONFIG_BLK_DEV_VIA82CXXX is not set +CONFIG_BLK_DEV_VIA82CXXX=y CONFIG_BLK_DEV_IDEDMA=y # CONFIG_IDEDMA_IVB is not set CONFIG_IDEDMA_AUTO=y @@ -246,8 +254,9 @@ CONFIG_BLK_DEV_SD=y # CONFIG_CHR_DEV_ST is not set # CONFIG_CHR_DEV_OSST is not set -# CONFIG_BLK_DEV_SR is not set -# CONFIG_CHR_DEV_SG is not set +CONFIG_BLK_DEV_SR=m +# CONFIG_BLK_DEV_SR_VENDOR is not set +CONFIG_CHR_DEV_SG=m # # Some SCSI devices (e.g. CD jukebox) support multiple LUNs @@ -260,7 +269,7 @@ # # SCSI low-level drivers # -# CONFIG_BLK_DEV_3W_XXXX_RAID is not set +CONFIG_BLK_DEV_3W_XXXX_RAID=y # CONFIG_SCSI_ACARD is not set # CONFIG_SCSI_AACRAID is not set # CONFIG_SCSI_AIC7XXX is not set @@ -268,7 +277,11 @@ # CONFIG_SCSI_AIC79XX is not set # CONFIG_SCSI_ADVANSYS is not set # CONFIG_SCSI_MEGARAID is not set -# CONFIG_SCSI_SATA is not set +CONFIG_SCSI_SATA=y +# CONFIG_SCSI_SATA_SVW is not set +CONFIG_SCSI_ATA_PIIX=y +# CONFIG_SCSI_SATA_PROMISE is not set +CONFIG_SCSI_SATA_VIA=y # CONFIG_SCSI_BUSLOGIC is not set # CONFIG_SCSI_CPQFCTS is not set # CONFIG_SCSI_DMX3191D is not set @@ -278,6 +291,8 @@ # CONFIG_SCSI_GDTH is not set # CONFIG_SCSI_IPS is not set # CONFIG_SCSI_INIA100 is not set +# CONFIG_SCSI_PPA is not set +# CONFIG_SCSI_IMM is not set # CONFIG_SCSI_SYM53C8XX_2 is not set # CONFIG_SCSI_QLOGIC_ISP is not set # CONFIG_SCSI_QLOGIC_FC is not set @@ -330,37 +345,111 @@ # CONFIG_PACKET=y # CONFIG_PACKET_MMAP is not set -# CONFIG_NETLINK_DEV is not set +CONFIG_NETLINK_DEV=y CONFIG_UNIX=y -# CONFIG_NET_KEY is not set +CONFIG_NET_KEY=m CONFIG_INET=y CONFIG_IP_MULTICAST=y # CONFIG_IP_ADVANCED_ROUTER is not set # CONFIG_IP_PNP is not set # CONFIG_NET_IPIP is not set # CONFIG_NET_IPGRE is not set -# CONFIG_IP_MROUTE is not set +CONFIG_IP_MROUTE=y +# CONFIG_IP_PIMSM_V1 is not set +# CONFIG_IP_PIMSM_V2 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_INET_IPCOMP is not set +CONFIG_INET_AH=m +CONFIG_INET_ESP=m +CONFIG_INET_IPCOMP=m + +# +# IP: Virtual Server Configuration +# +# CONFIG_IP_VS is not set CONFIG_IPV6=y -# CONFIG_IPV6_PRIVACY is not set +CONFIG_IPV6_PRIVACY=y # CONFIG_INET6_AH is not set -# CONFIG_INET6_ESP is not set -# CONFIG_INET6_IPCOMP is not set +CONFIG_INET6_ESP=m +CONFIG_INET6_IPCOMP=m # CONFIG_IPV6_TUNNEL is not set # CONFIG_DECNET is not set # CONFIG_BRIDGE is not set -# CONFIG_NETFILTER is not set +CONFIG_NETFILTER=y +# CONFIG_NETFILTER_DEBUG is not set + +# +# IP: Netfilter Configuration +# +CONFIG_IP_NF_CONNTRACK=m +CONFIG_IP_NF_FTP=m +CONFIG_IP_NF_IRC=m +# CONFIG_IP_NF_TFTP is not set +# CONFIG_IP_NF_AMANDA is not set +# CONFIG_IP_NF_QUEUE is not set +CONFIG_IP_NF_IPTABLES=m +# CONFIG_IP_NF_MATCH_LIMIT is not set +# CONFIG_IP_NF_MATCH_IPRANGE is not set +# CONFIG_IP_NF_MATCH_MAC is not set +# CONFIG_IP_NF_MATCH_PKTTYPE is not set +# CONFIG_IP_NF_MATCH_MARK is not set +# CONFIG_IP_NF_MATCH_MULTIPORT is not set +# CONFIG_IP_NF_MATCH_TOS is not set +# CONFIG_IP_NF_MATCH_RECENT is not set +# CONFIG_IP_NF_MATCH_ECN is not set +# CONFIG_IP_NF_MATCH_DSCP is not set +# CONFIG_IP_NF_MATCH_AH_ESP is not set +# CONFIG_IP_NF_MATCH_LENGTH is not set +# CONFIG_IP_NF_MATCH_TTL is not set +# CONFIG_IP_NF_MATCH_TCPMSS is not set +# CONFIG_IP_NF_MATCH_HELPER is not set +CONFIG_IP_NF_MATCH_STATE=m +CONFIG_IP_NF_MATCH_CONNTRACK=m +# CONFIG_IP_NF_MATCH_OWNER is not set +CONFIG_IP_NF_FILTER=m +CONFIG_IP_NF_TARGET_REJECT=m +CONFIG_IP_NF_NAT=m +CONFIG_IP_NF_NAT_NEEDED=y +CONFIG_IP_NF_TARGET_MASQUERADE=m +# CONFIG_IP_NF_TARGET_REDIRECT is not set +# CONFIG_IP_NF_TARGET_NETMAP is not set +# CONFIG_IP_NF_TARGET_SAME is not set +# CONFIG_IP_NF_NAT_LOCAL is not set +# CONFIG_IP_NF_NAT_SNMP_BASIC is not set +CONFIG_IP_NF_NAT_IRC=m +CONFIG_IP_NF_NAT_FTP=m +CONFIG_IP_NF_MANGLE=m +# CONFIG_IP_NF_TARGET_TOS is not set +# CONFIG_IP_NF_TARGET_ECN is not set +# CONFIG_IP_NF_TARGET_DSCP is not set +CONFIG_IP_NF_TARGET_MARK=m +# CONFIG_IP_NF_TARGET_CLASSIFY is not set +CONFIG_IP_NF_TARGET_LOG=m +# CONFIG_IP_NF_TARGET_ULOG is not set +CONFIG_IP_NF_TARGET_TCPMSS=m +# CONFIG_IP_NF_ARPTABLES is not set +# CONFIG_IP_NF_COMPAT_IPCHAINS is not set +# CONFIG_IP_NF_COMPAT_IPFWADM is not set + +# +# IPv6: Netfilter Configuration +# +# CONFIG_IP6_NF_QUEUE is not set +# CONFIG_IP6_NF_IPTABLES is not set +CONFIG_XFRM=y +CONFIG_XFRM_USER=m # # SCTP Configuration (EXPERIMENTAL) # CONFIG_IPV6_SCTP__=y -# CONFIG_IP_SCTP is not set +CONFIG_IP_SCTP=m +# CONFIG_SCTP_DBG_MSG is not set +# CONFIG_SCTP_DBG_OBJCNT is not set +CONFIG_SCTP_HMAC_NONE=y +# CONFIG_SCTP_HMAC_SHA1 is not set +# CONFIG_SCTP_HMAC_MD5 is not set # CONFIG_ATM is not set # CONFIG_VLAN_8021Q is not set # CONFIG_LLC2 is not set @@ -389,10 +478,11 @@ # ARCnet devices # # CONFIG_ARCNET is not set -# CONFIG_DUMMY is not set +CONFIG_DUMMY=m # CONFIG_BONDING is not set # CONFIG_EQUALIZER is not set -# CONFIG_TUN is not set +CONFIG_TUN=m +CONFIG_ETHERTAP=m # # Ethernet (10 or 100Mbit) @@ -401,7 +491,9 @@ CONFIG_MII=y # CONFIG_HAPPYMEAL is not set # CONFIG_SUNGEM is not set -# CONFIG_NET_VENDOR_3COM is not set +CONFIG_NET_VENDOR_3COM=y +CONFIG_VORTEX=m +# CONFIG_TYPHOON is not set # # Tulip family network device support @@ -409,25 +501,25 @@ # CONFIG_NET_TULIP is not set # CONFIG_HP100 is not set CONFIG_NET_PCI=y -# CONFIG_PCNET32 is not set -CONFIG_AMD8111_ETH=y +CONFIG_PCNET32=y +CONFIG_AMD8111_ETH=m # CONFIG_ADAPTEC_STARFIRE is not set # CONFIG_B44 is not set -CONFIG_FORCEDETH=y +# CONFIG_FORCEDETH is not set # CONFIG_DGRS is not set # CONFIG_EEPRO100 is not set # CONFIG_E100 is not set # CONFIG_FEALNX is not set # CONFIG_NATSEMI is not set # CONFIG_NE2K_PCI is not set -CONFIG_8139CP=m -CONFIG_8139TOO=m +# CONFIG_8139CP is not set +CONFIG_8139TOO=y # CONFIG_8139TOO_PIO is not set # CONFIG_8139TOO_TUNE_TWISTER is not set # CONFIG_8139TOO_8129 is not set # CONFIG_8139_OLD_RX_RESET is not set CONFIG_8139_RXBUF_IDX=2 -# CONFIG_SIS900 is not set +CONFIG_SIS900=m # CONFIG_EPIC100 is not set # CONFIG_SUNDANCE is not set # CONFIG_VIA_RHINE is not set @@ -437,7 +529,7 @@ # # CONFIG_ACENIC is not set # CONFIG_DL2K is not set -CONFIG_E1000=y +CONFIG_E1000=m # CONFIG_E1000_NAPI is not set # CONFIG_NS83820 is not set # CONFIG_HAMACHI is not set @@ -453,7 +545,15 @@ # CONFIG_IXGB is not set # CONFIG_FDDI is not set # CONFIG_HIPPI is not set -# CONFIG_PPP is not set +# CONFIG_PLIP is not set +CONFIG_PPP=m +# CONFIG_PPP_MULTILINK is not set +# CONFIG_PPP_FILTER is not set +# CONFIG_PPP_ASYNC is not set +# CONFIG_PPP_SYNC_TTY is not set +# CONFIG_PPP_DEFLATE is not set +# CONFIG_PPP_BSDCOMP is not set +CONFIG_PPPOE=m # CONFIG_SLIP is not set # @@ -512,7 +612,7 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 # CONFIG_INPUT_JOYDEV is not set # CONFIG_INPUT_TSDEV is not set -CONFIG_INPUT_EVDEV=y +# CONFIG_INPUT_EVDEV is not set # CONFIG_INPUT_EVBUG is not set # @@ -524,6 +624,7 @@ CONFIG_SERIO_I8042=y # CONFIG_SERIO_SERPORT is not set # CONFIG_SERIO_CT82C710 is not set +# CONFIG_SERIO_PARKBD is not set # CONFIG_SERIO_PCIPS2 is not set # @@ -547,7 +648,12 @@ CONFIG_VT=y CONFIG_VT_CONSOLE=y CONFIG_HW_CONSOLE=y -# CONFIG_SERIAL_NONSTANDARD is not set +CONFIG_SERIAL_NONSTANDARD=y +CONFIG_ROCKETPORT=m +# CONFIG_SYNCLINK is not set +# CONFIG_SYNCLINKMP is not set +# CONFIG_N_HDLC is not set +# CONFIG_STALDRV is not set # # Serial drivers @@ -564,13 +670,16 @@ CONFIG_SERIAL_CORE=y CONFIG_SERIAL_CORE_CONSOLE=y CONFIG_UNIX98_PTYS=y -CONFIG_LEGACY_PTYS=y -CONFIG_LEGACY_PTY_COUNT=256 +# CONFIG_LEGACY_PTYS is not set +CONFIG_PRINTER=y +# CONFIG_LP_CONSOLE is not set +# CONFIG_PPDEV is not set +# CONFIG_TIPAR is not set # # Mice # -# CONFIG_BUSMOUSE is not set +CONFIG_BUSMOUSE=y # CONFIG_QIC02_TAPE is not set # @@ -594,12 +703,17 @@ # CONFIG_AGP=y CONFIG_AGP_AMD64=y -CONFIG_AGP_INTEL=y -# CONFIG_DRM is not set +# CONFIG_AGP_INTEL is not set +CONFIG_DRM=y +# CONFIG_DRM_TDFX is not set +# CONFIG_DRM_GAMMA is not set +# CONFIG_DRM_R128 is not set +CONFIG_DRM_RADEON=m +# CONFIG_DRM_SIS is not set # CONFIG_MWAVE is not set -CONFIG_RAW_DRIVER=y +CONFIG_RAW_DRIVER=m CONFIG_MAX_RAW_DEVS=256 -CONFIG_HANGCHECK_TIMER=y +# CONFIG_HANGCHECK_TIMER is not set # # I2C support @@ -607,6 +721,11 @@ # CONFIG_I2C is not set # +# Misc devices +# +# CONFIG_IBM_ASM is not set + +# # Multimedia devices # # CONFIG_VIDEO_DEV is not set @@ -642,10 +761,11 @@ # # Open Sound System # -CONFIG_SOUND_PRIME=y +CONFIG_SOUND_PRIME=m # CONFIG_SOUND_BT878 is not set # CONFIG_SOUND_CMPCI is not set -# CONFIG_SOUND_EMU10K1 is not set +CONFIG_SOUND_EMU10K1=m +# CONFIG_MIDI_EMU10K1 is not set # CONFIG_SOUND_FUSION is not set # CONFIG_SOUND_CS4281 is not set # CONFIG_SOUND_ES1370 is not set @@ -653,12 +773,13 @@ # CONFIG_SOUND_ESSSOLO1 is not set # CONFIG_SOUND_MAESTRO is not set # CONFIG_SOUND_MAESTRO3 is not set -CONFIG_SOUND_ICH=y +CONFIG_SOUND_ICH=m # CONFIG_SOUND_SONICVIBES is not set # CONFIG_SOUND_TRIDENT is not set # CONFIG_SOUND_MSNDCLAS is not set # CONFIG_SOUND_MSNDPIN is not set -# CONFIG_SOUND_VIA82CXXX is not set +CONFIG_SOUND_VIA82CXXX=m +# CONFIG_MIDI_VIA82CXXX is not set # CONFIG_SOUND_OSS is not set # CONFIG_SOUND_ALI5455 is not set # CONFIG_SOUND_FORTE is not set @@ -668,7 +789,151 @@ # # USB support # -# CONFIG_USB is not set +CONFIG_USB=m +# CONFIG_USB_DEBUG is not set + +# +# Miscellaneous USB options +# +CONFIG_USB_DEVICEFS=y +CONFIG_USB_BANDWIDTH=y +# CONFIG_USB_DYNAMIC_MINORS is not set + +# +# USB Host Controller Drivers +# +CONFIG_USB_EHCI_HCD=m +CONFIG_USB_OHCI_HCD=m +CONFIG_USB_UHCI_HCD=m + +# +# USB Device Class drivers +# +# CONFIG_USB_AUDIO is not set +# CONFIG_USB_BLUETOOTH_TTY is not set +# CONFIG_USB_MIDI is not set +# CONFIG_USB_ACM is not set +CONFIG_USB_PRINTER=m +CONFIG_USB_STORAGE=m +# CONFIG_USB_STORAGE_DEBUG is not set +# CONFIG_USB_STORAGE_DATAFAB is not set +# CONFIG_USB_STORAGE_FREECOM is not set +# CONFIG_USB_STORAGE_ISD200 is not set +# CONFIG_USB_STORAGE_DPCM is not set +# CONFIG_USB_STORAGE_HP8200e is not set +# CONFIG_USB_STORAGE_SDDR09 is not set +# CONFIG_USB_STORAGE_SDDR55 is not set +# CONFIG_USB_STORAGE_JUMPSHOT is not set + +# +# USB Human Interface Devices (HID) +# +CONFIG_USB_HID=m +CONFIG_USB_HIDINPUT=y +# CONFIG_HID_FF is not set +# CONFIG_USB_HIDDEV is not set + +# +# USB HID Boot Protocol drivers +# +# CONFIG_USB_KBD is not set +# CONFIG_USB_MOUSE is not set +# CONFIG_USB_AIPTEK is not set +# CONFIG_USB_WACOM is not set +# CONFIG_USB_KBTAB is not set +# CONFIG_USB_POWERMATE is not set +# CONFIG_USB_XPAD is not set + +# +# USB Imaging devices +# +# CONFIG_USB_MDC800 is not set +# CONFIG_USB_MICROTEK is not set +# CONFIG_USB_HPUSBSCSI is not set + +# +# USB Multimedia devices +# +# CONFIG_USB_DABUSB is not set + +# +# Video4Linux support is needed for USB Multimedia device support +# + +# +# USB Network adaptors +# +# CONFIG_USB_CATC is not set +# CONFIG_USB_KAWETH is not set +# CONFIG_USB_PEGASUS is not set +# CONFIG_USB_RTL8150 is not set +CONFIG_USB_USBNET=m + +# +# USB Host-to-Host Cables +# +CONFIG_USB_AN2720=y +CONFIG_USB_BELKIN=y +CONFIG_USB_GENESYS=y +CONFIG_USB_NET1080=y +CONFIG_USB_PL2301=y + +# +# Intelligent USB Devices/Gadgets +# +CONFIG_USB_ARMLINUX=y +CONFIG_USB_EPSON2888=y +# CONFIG_USB_ZAURUS is not set +# CONFIG_USB_CDCETHER is not set + +# +# USB Network Adapters +# +CONFIG_USB_AX8817X=y + +# +# USB port drivers +# +# CONFIG_USB_USS720 is not set + +# +# USB Serial Converter support +# +CONFIG_USB_SERIAL=m +CONFIG_USB_SERIAL_GENERIC=y +CONFIG_USB_SERIAL_BELKIN=m +# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set +# CONFIG_USB_SERIAL_EMPEG is not set +# CONFIG_USB_SERIAL_FTDI_SIO is not set +# CONFIG_USB_SERIAL_VISOR is not set +# CONFIG_USB_SERIAL_IPAQ is not set +# CONFIG_USB_SERIAL_IR is not set +# CONFIG_USB_SERIAL_EDGEPORT is not set +# CONFIG_USB_SERIAL_EDGEPORT_TI is not set +# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set +# CONFIG_USB_SERIAL_KEYSPAN is not set +# CONFIG_USB_SERIAL_KLSI is not set +# CONFIG_USB_SERIAL_KOBIL_SCT is not set +# CONFIG_USB_SERIAL_MCT_U232 is not set +# CONFIG_USB_SERIAL_PL2303 is not set +# CONFIG_USB_SERIAL_SAFE is not set +# CONFIG_USB_SERIAL_CYBERJACK is not set +# CONFIG_USB_SERIAL_XIRCOM is not set +# CONFIG_USB_SERIAL_OMNINET is not set + +# +# USB Miscellaneous drivers +# +# CONFIG_USB_EMI62 is not set +# CONFIG_USB_EMI26 is not set +# CONFIG_USB_TIGL is not set +# CONFIG_USB_AUERSWALD is not set +# CONFIG_USB_RIO500 is not set +# CONFIG_USB_LEGOTOWER is not set +# CONFIG_USB_BRLVGER is not set +# CONFIG_USB_LCD is not set +# CONFIG_USB_LED is not set +# CONFIG_USB_TEST is not set # # USB Gadget Support @@ -680,20 +945,17 @@ # CONFIG_EXT2_FS=y CONFIG_EXT2_FS_XATTR=y -CONFIG_EXT2_FS_POSIX_ACL=y +# CONFIG_EXT2_FS_POSIX_ACL is not set # CONFIG_EXT2_FS_SECURITY is not set CONFIG_EXT3_FS=y -CONFIG_EXT3_FS_XATTR=y -CONFIG_EXT3_FS_POSIX_ACL=y -# CONFIG_EXT3_FS_SECURITY is not set +# CONFIG_EXT3_FS_XATTR is not set CONFIG_JBD=y # CONFIG_JBD_DEBUG is not set CONFIG_FS_MBCACHE=y CONFIG_REISERFS_FS=y # CONFIG_REISERFS_CHECK is not set -# CONFIG_REISERFS_PROC_INFO is not set +CONFIG_REISERFS_PROC_INFO=y # CONFIG_JFS_FS is not set -CONFIG_FS_POSIX_ACL=y # CONFIG_XFS_FS is not set # CONFIG_MINIX_FS is not set # CONFIG_ROMFS_FS is not set @@ -705,14 +967,16 @@ # CD-ROM/DVD Filesystems # CONFIG_ISO9660_FS=y -# CONFIG_JOLIET is not set +CONFIG_JOLIET=y # CONFIG_ZISOFS is not set -# CONFIG_UDF_FS is not set +CONFIG_UDF_FS=m # # DOS/FAT/NT Filesystems # -# CONFIG_FAT_FS is not set +CONFIG_FAT_FS=y +CONFIG_MSDOS_FS=y +CONFIG_VFAT_FS=m # CONFIG_NTFS_FS is not set # @@ -723,8 +987,8 @@ # CONFIG_DEVFS_FS is not set # CONFIG_DEVPTS_FS_XATTR is not set CONFIG_TMPFS=y -CONFIG_HUGETLBFS=y -CONFIG_HUGETLB_PAGE=y +# CONFIG_HUGETLBFS is not set +# CONFIG_HUGETLB_PAGE is not set CONFIG_RAMFS=y # @@ -750,7 +1014,7 @@ CONFIG_NFS_FS=y CONFIG_NFS_V3=y # CONFIG_NFS_V4 is not set -# CONFIG_NFS_DIRECTIO is not set +CONFIG_NFS_DIRECTIO=y CONFIG_NFSD=y CONFIG_NFSD_V3=y # CONFIG_NFSD_V4 is not set @@ -775,7 +1039,45 @@ # # Native Language Support # -# CONFIG_NLS is not set +CONFIG_NLS=y +CONFIG_NLS_DEFAULT="iso8859-1" +CONFIG_NLS_CODEPAGE_437=y +# 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=y +# 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 # # Profiling support @@ -803,9 +1105,28 @@ # # Cryptographic options # -# CONFIG_CRYPTO is not set +CONFIG_CRYPTO=y +CONFIG_CRYPTO_HMAC=y +# CONFIG_CRYPTO_NULL is not set +# CONFIG_CRYPTO_MD4 is not set +CONFIG_CRYPTO_MD5=y +CONFIG_CRYPTO_SHA1=m +# CONFIG_CRYPTO_SHA256 is not set +# CONFIG_CRYPTO_SHA512 is not set +CONFIG_CRYPTO_DES=m +# CONFIG_CRYPTO_BLOWFISH is not set +# CONFIG_CRYPTO_TWOFISH is not set +# CONFIG_CRYPTO_SERPENT is not set +# CONFIG_CRYPTO_AES is not set +# CONFIG_CRYPTO_CAST5 is not set +# CONFIG_CRYPTO_CAST6 is not set +# CONFIG_CRYPTO_ARC4 is not set +CONFIG_CRYPTO_DEFLATE=m +# CONFIG_CRYPTO_TEST is not set # # Library routines # CONFIG_CRC32=y +CONFIG_ZLIB_INFLATE=m +CONFIG_ZLIB_DEFLATE=m diff -Nru a/arch/x86_64/ia32/Makefile b/arch/x86_64/ia32/Makefile --- a/arch/x86_64/ia32/Makefile Sun Mar 14 14:20:06 2004 +++ b/arch/x86_64/ia32/Makefile Sun Mar 14 14:20:06 2004 @@ -11,18 +11,22 @@ obj-$(CONFIG_IA32_AOUT) += ia32_aout.o -$(obj)/syscall32.o: $(src)/syscall32.c $(obj)/vsyscall.so +$(obj)/syscall32.o: $(src)/syscall32.c \ + $(foreach F,sysenter syscall,$(obj)/vsyscall-$F.so) # Teach kbuild about targets -targets := vsyscall.o vsyscall.so +targets := $(foreach F,sysenter syscall,vsyscall-$F.o vsyscall-$F.so) # The DSO images are built using a special linker script -quiet_cmd_vsyscall = SYSCALL $@ - cmd_vsyscall = $(CC) -m32 -nostdlib -shared -s \ +quiet_cmd_syscall = SYSCALL $@ + cmd_syscall = $(CC) -m32 -nostdlib -shared -s \ -Wl,-soname=linux-gate.so.1 -o $@ \ -Wl,-T,$(filter-out FORCE,$^) -$(obj)/vsyscall.so: $(src)/vsyscall.lds $(obj)/vsyscall.o FORCE - $(call if_changed,vsyscall) -AFLAGS_vsyscall.o = -m32 +$(obj)/vsyscall-sysenter.so $(obj)/vsyscall-syscall.so: \ +$(obj)/vsyscall-%.so: $(src)/vsyscall.lds $(obj)/vsyscall-%.o FORCE + $(call if_changed,syscall) + +AFLAGS_vsyscall-sysenter.o = -m32 +AFLAGS_vsyscall-syscall.o = -m32 CFLAGS_ia32_ioctl.o += -Ifs/ diff -Nru a/arch/x86_64/ia32/ia32_binfmt.c b/arch/x86_64/ia32/ia32_binfmt.c --- a/arch/x86_64/ia32/ia32_binfmt.c Sun Mar 14 14:20:06 2004 +++ b/arch/x86_64/ia32/ia32_binfmt.c Sun Mar 14 14:20:06 2004 @@ -32,7 +32,7 @@ #define AT_SYSINFO 32 #define AT_SYSINFO_EHDR 33 -int sysctl_vsyscall32; +int sysctl_vsyscall32 = 1; #define ARCH_DLINFO do { \ if (sysctl_vsyscall32) { \ @@ -46,7 +46,7 @@ #define IA32_EMULATOR 1 -#define ELF_ET_DYN_BASE (IA32_PAGE_OFFSET/3 + 0x1000000) +#define ELF_ET_DYN_BASE (TASK_UNMAPPED_32 + 0x1000000) #undef ELF_ARCH #define ELF_ARCH EM_386 @@ -261,7 +261,6 @@ set_thread_flag(TIF_ABI_PENDING); \ else \ clear_thread_flag(TIF_ABI_PENDING); \ - set_personality((ibcs2)?PER_SVR4:current->personality); \ } while (0) /* Override some function names */ diff -Nru a/arch/x86_64/ia32/ia32_signal.c b/arch/x86_64/ia32/ia32_signal.c --- a/arch/x86_64/ia32/ia32_signal.c Sun Mar 14 14:20:08 2004 +++ b/arch/x86_64/ia32/ia32_signal.c Sun Mar 14 14:20:08 2004 @@ -273,8 +273,6 @@ sigset_t set; unsigned int eax; - set_thread_flag(TIF_IRET); - if (verify_area(VERIFY_READ, frame, sizeof(*frame))) goto badframe; if (__get_user(set.sig[0], &frame->sc.oldmask) @@ -304,8 +302,6 @@ sigset_t set; stack_t st; unsigned int eax; - - set_thread_flag(TIF_IRET); if (verify_area(VERIFY_READ, frame, sizeof(*frame))) goto badframe; diff -Nru a/arch/x86_64/ia32/ia32entry.S b/arch/x86_64/ia32/ia32entry.S --- a/arch/x86_64/ia32/ia32entry.S Sun Mar 14 14:20:07 2004 +++ b/arch/x86_64/ia32/ia32entry.S Sun Mar 14 14:20:07 2004 @@ -12,6 +12,7 @@ #include #include #include +#include #include .macro IA32_ARG_FIXUP noebp=0 @@ -25,6 +26,99 @@ movl %edx,%edx /* zero extension */ .endm + /* clobbers %eax */ + .macro CLEAR_RREGS + xorl %eax,%eax + movq %rax,R11(%rsp) + movq %rax,R10(%rsp) + movq %rax,R9(%rsp) + movq %rax,R8(%rsp) + .endm + +/* + * 32bit SYSENTER instruction entry. + * + * Arguments: + * %eax System call number. + * %ebx Arg1 + * %ecx Arg2 + * %edx Arg3 + * %esi Arg4 + * %edi Arg5 + * %ebp user stack + * 0(%ebp) Arg6 + * + * Interrupts off. + * + * This is purely a fast path. For anything complicated we use the int 0x80 + * path below. Set up a complete hardware stack frame to share code + * with the int 0x80 path. + */ +ENTRY(ia32_sysenter_target) + CFI_STARTPROC + swapgs + movq %gs:pda_kernelstack, %rsp + addq $(PDA_STACKOFFSET),%rsp + sti + movl %ebp,%ebp /* zero extension */ + pushq $__USER32_DS + pushq %rbp + pushfq + movl $VSYSCALL32_SYSEXIT, %r10d + pushq $__USER32_CS + movl %eax, %eax + pushq %r10 + pushq %rax + cld + SAVE_ARGS 0,0,1 + /* no need to do an access_ok check here because rbp has been + 32bit zero extended */ +1: movl (%rbp),%r9d + .section __ex_table,"a" + .quad 1b,ia32_badarg + .previous + GET_THREAD_INFO(%r10) + bt $TIF_SYSCALL_TRACE,threadinfo_flags(%r10) + jc sysenter_tracesys +sysenter_do_call: + cmpl $(IA32_NR_syscalls),%eax + jae ia32_badsys + IA32_ARG_FIXUP 1 + call *ia32_sys_call_table(,%rax,8) + movq %rax,RAX-ARGOFFSET(%rsp) + GET_THREAD_INFO(%r10) + cli + testl $_TIF_ALLWORK_MASK,threadinfo_flags(%r10) + jnz int_ret_from_sys_call + /* clear IF, that popfq doesn't enable interrupts early */ + andl $~0x200,EFLAGS-R11(%rsp) + RESTORE_ARGS 1,24,1,1,1,1 + popfq + popq %rcx /* User %esp */ + movl $VSYSCALL32_SYSEXIT,%edx /* User %eip */ + swapgs + sti /* sti only takes effect after the next instruction */ + /* sysexit */ + .byte 0xf, 0x35 + +sysenter_tracesys: + SAVE_REST + CLEAR_RREGS + movq $-ENOSYS,RAX(%rsp) /* really needed? */ + movq %rsp,%rdi /* &pt_regs -> arg1 */ + call syscall_trace + LOAD_ARGS ARGOFFSET /* reload args from stack in case ptrace changed it */ + RESTORE_REST + movl %ebp, %ebp + /* no need to do an access_ok check here because rbp has been + 32bit zero extended */ +1: movl (%rbp),%r9d + .section __ex_table,"a" + .quad 1b,ia32_badarg + .previous + jmp sysenter_do_call + CFI_ENDPROC + /* * 32bit SYSCALL instruction entry. * @@ -51,7 +145,7 @@ movl %esp,%r8d movq %gs:pda_kernelstack,%rsp sti - SAVE_ARGS 8,1 + SAVE_ARGS 8,1,1 movl %eax,%eax /* zero extension */ movq %rax,ORIG_RAX-ARGOFFSET(%rsp) movq %rcx,RIP-ARGOFFSET(%rsp) @@ -66,47 +160,48 @@ /* hardware stack frame is complete now */ 1: movl (%r8),%r9d .section __ex_table,"a" - .quad 1b,cstar_badarg + .quad 1b,ia32_badarg .previous GET_THREAD_INFO(%r10) bt $TIF_SYSCALL_TRACE,threadinfo_flags(%r10) - jc ia32_tracesys + jc cstar_tracesys cstar_do_call: cmpl $IA32_NR_syscalls,%eax jae ia32_badsys IA32_ARG_FIXUP 1 call *ia32_sys_call_table(,%rax,8) - .globl cstar_sysret - /* label must directly follow call */ -cstar_sysret: movq %rax,RAX-ARGOFFSET(%rsp) GET_THREAD_INFO(%r10) cli testl $_TIF_ALLWORK_MASK,threadinfo_flags(%r10) - jnz 1f - RESTORE_ARGS 1,-ARG_SKIP,1,1 + jnz int_ret_from_sys_call + RESTORE_ARGS 1,-ARG_SKIP,1,1,1 movl RIP-ARGOFFSET(%rsp),%ecx movl EFLAGS-ARGOFFSET(%rsp),%r11d movl RSP-ARGOFFSET(%rsp),%esp swapgs sysretl -1: - btc $TIF_IRET,threadinfo_flags(%r10) - jmp int_ret_from_sys_call - cstar_tracesys: SAVE_REST + CLEAR_RREGS movq $-ENOSYS,RAX(%rsp) /* really needed? */ movq %rsp,%rdi /* &pt_regs -> arg1 */ call syscall_trace LOAD_ARGS ARGOFFSET /* reload args from stack in case ptrace changed it */ RESTORE_REST + movl RSP-ARGOFFSET(%rsp), %r8d + /* no need to do an access_ok check here because r8 has been + 32bit zero extended */ +1: movl (%r8),%r9d + .section __ex_table,"a" + .quad 1b,ia32_badarg + .previous jmp cstar_do_call -cstar_badarg: +ia32_badarg: movq $-EFAULT,%rax - jmp cstar_sysret + jmp ia32_sysret CFI_ENDPROC /* @@ -139,7 +234,7 @@ cld /* note the registers are not zero extended to the sf. this could be a problem. */ - SAVE_ARGS + SAVE_ARGS 0,0,1 GET_THREAD_INFO(%r10) bt $TIF_SYSCALL_TRACE,threadinfo_flags(%r10) jc ia32_tracesys @@ -148,6 +243,7 @@ jae ia32_badsys IA32_ARG_FIXUP call *ia32_sys_call_table(,%rax,8) # xxx: rip relative +ia32_sysret: movq %rax,RAX-ARGOFFSET(%rsp) jmp int_ret_from_sys_call @@ -200,8 +296,7 @@ call *%rax movq %r15, %r11 RESTORE_REST - cmpq $cstar_sysret,%r11 - je int_ret_from_sys_call /* misbalances the call/ret stack. sorry */ + leaq ia32_sysret(%rip),%r11 pushq %r11 ret CFI_ENDPROC 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 Sun Mar 14 14:20:07 2004 +++ b/arch/x86_64/ia32/sys_ia32.c Sun Mar 14 14:20:07 2004 @@ -1876,18 +1876,9 @@ cond_syscall(sys32_ipc) -struct exec_domain ia32_exec_domain = { - .name = "linux/x86", - .pers_low = PER_LINUX32, - .pers_high = PER_LINUX32, -}; - static int __init ia32_init (void) { printk("IA32 emulation $Id: sys_ia32.c,v 1.32 2002/03/24 13:02:28 ak Exp $\n"); - ia32_exec_domain.signal_map = default_exec_domain.signal_map; - ia32_exec_domain.signal_invmap = default_exec_domain.signal_invmap; - register_exec_domain(&ia32_exec_domain); return 0; } diff -Nru a/arch/x86_64/ia32/syscall32.c b/arch/x86_64/ia32/syscall32.c --- a/arch/x86_64/ia32/syscall32.c Sun Mar 14 14:20:07 2004 +++ b/arch/x86_64/ia32/syscall32.c Sun Mar 14 14:20:07 2004 @@ -13,16 +13,22 @@ #include #include -/* 32bit VDSO mapped into user space. */ +/* 32bit VDSOs mapped into user space. */ asm(".section \".init.data\",\"aw\"\n" - "syscall32:\n" - ".incbin \"arch/x86_64/ia32/vsyscall.so\"\n" - "syscall32_end:\n" + "syscall32_syscall:\n" + ".incbin \"arch/x86_64/ia32/vsyscall-syscall.so\"\n" + "syscall32_syscall_end:\n" + "syscall32_sysenter:\n" + ".incbin \"arch/x86_64/ia32/vsyscall-sysenter.so\"\n" + "syscall32_sysenter_end:\n" ".previous"); -extern unsigned char syscall32[], syscall32_end[]; +extern unsigned char syscall32_syscall[], syscall32_syscall_end[]; +extern unsigned char syscall32_sysenter[], syscall32_sysenter_end[]; +extern int sysctl_vsyscall32; char *syscall32_page; +static int use_sysenter __initdata = -1; /* RED-PEN: This knows too much about high level VM */ /* Alternative would be to generate a vma with appropriate backing options @@ -58,8 +64,28 @@ if (!syscall32_page) panic("Cannot allocate syscall32 page"); SetPageReserved(virt_to_page(syscall32_page)); - memcpy(syscall32_page, syscall32, syscall32_end - syscall32); + if (use_sysenter > 0) { + memcpy(syscall32_page, syscall32_sysenter, + syscall32_sysenter_end - syscall32_sysenter); + } else { + memcpy(syscall32_page, syscall32_syscall, + syscall32_syscall_end - syscall32_syscall); + } return 0; } __initcall(init_syscall32); + +void __init syscall32_cpu_init(void) +{ + if (use_sysenter < 0) + use_sysenter = (boot_cpu_data.x86_vendor == X86_VENDOR_INTEL); + + /* Load these always in case some future AMD CPU supports + SYSENTER from compat mode too. */ + wrmsr(MSR_IA32_SYSENTER_CS, __KERNEL_CS, 0); + wrmsr(MSR_IA32_SYSENTER_ESP, 0, 0); + wrmsrl(MSR_IA32_SYSENTER_EIP, ia32_sysenter_target); + + wrmsrl(MSR_CSTAR, ia32_cstar_target); +} diff -Nru a/arch/x86_64/ia32/vsyscall-sigreturn.S b/arch/x86_64/ia32/vsyscall-sigreturn.S --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/x86_64/ia32/vsyscall-sigreturn.S Sun Mar 14 14:20:09 2004 @@ -0,0 +1,120 @@ +/* + * Common code for the sigreturn entry points on the vsyscall page. + * This code uses SYSCALL_ENTER_KERNEL (either syscall or int $0x80) + * to enter the kernel. + * This file is #include'd by vsyscall-*.S to define them after the + * vsyscall entry point. The addresses we get for these entry points + * by doing ".balign 32" must match in both versions of the page. + */ + + .section .text.sigreturn,"ax" + .balign 32 + .globl __kernel_sigreturn + .type __kernel_sigreturn,@function +__kernel_sigreturn: +.LSTART_sigreturn: + popl %eax + movl $__NR_ia32_sigreturn, %eax + SYSCALL_ENTER_KERNEL +.LEND_sigreturn: + .size __kernel_sigreturn,.-.LSTART_sigreturn + + .section .text.rtsigreturn,"ax" + .balign 32 + .globl __kernel_rt_sigreturn + .type __kernel_rt_sigreturn,@function +__kernel_rt_sigreturn: +.LSTART_rt_sigreturn: + movl $__NR_ia32_rt_sigreturn, %eax + SYSCALL_ENTER_KERNEL +.LEND_rt_sigreturn: + .size __kernel_rt_sigreturn,.-.LSTART_rt_sigreturn + + .section .eh_frame,"a",@progbits + .long .LENDFDE2-.LSTARTFDE2 /* Length FDE */ +.LSTARTFDE2: + .long .LSTARTFDE2-.LSTARTFRAME /* CIE pointer */ + /* HACK: The dwarf2 unwind routines will subtract 1 from the + return address to get an address in the middle of the + presumed call instruction. Since we didn't get here via + a call, we need to include the nop before the real start + to make up for it. */ + .long .LSTART_sigreturn-1-. /* PC-relative start address */ + .long .LEND_sigreturn-.LSTART_sigreturn+1 + .uleb128 0 /* Augmentation length */ + /* What follows are the instructions for the table generation. + We record the locations of each register saved. This is + complicated by the fact that the "CFA" is always assumed to + be the value of the stack pointer in the caller. This means + that we must define the CFA of this body of code to be the + saved value of the stack pointer in the sigcontext. Which + also means that there is no fixed relation to the other + saved registers, which means that we must use DW_CFA_expression + to compute their addresses. It also means that when we + adjust the stack with the popl, we have to do it all over again. */ + +#define do_cfa_expr(offset) \ + .byte 0x0f; /* DW_CFA_def_cfa_expression */ \ + .uleb128 1f-0f; /* length */ \ +0: .byte 0x74; /* DW_OP_breg4 */ \ + .sleb128 offset; /* offset */ \ + .byte 0x06; /* DW_OP_deref */ \ +1: + +#define do_expr(regno, offset) \ + .byte 0x10; /* DW_CFA_expression */ \ + .uleb128 regno; /* regno */ \ + .uleb128 1f-0f; /* length */ \ +0: .byte 0x74; /* DW_OP_breg4 */ \ + .sleb128 offset; /* offset */ \ +1: + + do_cfa_expr(IA32_SIGCONTEXT_esp+4) + do_expr(0, IA32_SIGCONTEXT_eax+4) + do_expr(1, IA32_SIGCONTEXT_ecx+4) + do_expr(2, IA32_SIGCONTEXT_edx+4) + do_expr(3, IA32_SIGCONTEXT_ebx+4) + do_expr(5, IA32_SIGCONTEXT_ebp+4) + do_expr(6, IA32_SIGCONTEXT_esi+4) + do_expr(7, IA32_SIGCONTEXT_edi+4) + do_expr(8, IA32_SIGCONTEXT_eip+4) + + .byte 0x42 /* DW_CFA_advance_loc 2 -- nop; popl eax. */ + + do_cfa_expr(IA32_SIGCONTEXT_esp) + do_expr(0, IA32_SIGCONTEXT_eax) + do_expr(1, IA32_SIGCONTEXT_ecx) + do_expr(2, IA32_SIGCONTEXT_edx) + do_expr(3, IA32_SIGCONTEXT_ebx) + do_expr(5, IA32_SIGCONTEXT_ebp) + do_expr(6, IA32_SIGCONTEXT_esi) + do_expr(7, IA32_SIGCONTEXT_edi) + do_expr(8, IA32_SIGCONTEXT_eip) + + .align 4 +.LENDFDE2: + + .long .LENDFDE3-.LSTARTFDE3 /* Length FDE */ +.LSTARTFDE3: + .long .LSTARTFDE3-.LSTARTFRAME /* CIE pointer */ + /* HACK: See above wrt unwind library assumptions. */ + .long .LSTART_rt_sigreturn-1-. /* PC-relative start address */ + .long .LEND_rt_sigreturn-.LSTART_rt_sigreturn+1 + .uleb128 0 /* Augmentation */ + /* What follows are the instructions for the table generation. + We record the locations of each register saved. This is + slightly less complicated than the above, since we don't + modify the stack pointer in the process. */ + + do_cfa_expr(IA32_RT_SIGFRAME_sigcontext-4 + IA32_SIGCONTEXT_esp) + do_expr(0, IA32_RT_SIGFRAME_sigcontext-4 + IA32_SIGCONTEXT_eax) + do_expr(1, IA32_RT_SIGFRAME_sigcontext-4 + IA32_SIGCONTEXT_ecx) + do_expr(2, IA32_RT_SIGFRAME_sigcontext-4 + IA32_SIGCONTEXT_edx) + do_expr(3, IA32_RT_SIGFRAME_sigcontext-4 + IA32_SIGCONTEXT_ebx) + do_expr(5, IA32_RT_SIGFRAME_sigcontext-4 + IA32_SIGCONTEXT_ebp) + do_expr(6, IA32_RT_SIGFRAME_sigcontext-4 + IA32_SIGCONTEXT_esi) + do_expr(7, IA32_RT_SIGFRAME_sigcontext-4 + IA32_SIGCONTEXT_edi) + do_expr(8, IA32_RT_SIGFRAME_sigcontext-4 + IA32_SIGCONTEXT_eip) + + .align 4 +.LENDFDE3: diff -Nru a/arch/x86_64/ia32/vsyscall-syscall.S b/arch/x86_64/ia32/vsyscall-syscall.S --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/x86_64/ia32/vsyscall-syscall.S Sun Mar 14 14:20:09 2004 @@ -0,0 +1,68 @@ +/* + * Code for the vsyscall page. This version uses the syscall instruction. + */ + +#include +#include +#include + + .text + .section .text.vsyscall,"ax" + .globl __kernel_vsyscall + .type __kernel_vsyscall,@function +__kernel_vsyscall: +.LSTART_vsyscall: + push %ebp +.Lpush_ebp: + movl %ecx, %ebp + syscall + movl $__USER32_DS, %ecx + movl %ecx, %ss + movl %ebp, %ecx + popl %ebp +.Lpop_ebp: + ret +.LEND_vsyscall: + .size __kernel_vsyscall,.-.LSTART_vsyscall + + .section .eh_frame,"a",@progbits +.LSTARTFRAME: + .long .LENDCIE-.LSTARTCIE +.LSTARTCIE: + .long 0 /* CIE ID */ + .byte 1 /* Version number */ + .string "zR" /* NUL-terminated augmentation string */ + .uleb128 1 /* Code alignment factor */ + .sleb128 -4 /* Data alignment factor */ + .byte 8 /* Return address register column */ + .uleb128 1 /* Augmentation value length */ + .byte 0x1b /* DW_EH_PE_pcrel|DW_EH_PE_sdata4. */ + .byte 0x0c /* DW_CFA_def_cfa */ + .uleb128 4 + .uleb128 4 + .byte 0x88 /* DW_CFA_offset, column 0x8 */ + .uleb128 1 + .align 4 +.LENDCIE: + + .long .LENDFDE1-.LSTARTFDE1 /* Length FDE */ +.LSTARTFDE1: + .long .LSTARTFDE1-.LSTARTFRAME /* CIE pointer */ + .long .LSTART_vsyscall-. /* PC-relative start address */ + .long .LEND_vsyscall-.LSTART_vsyscall + .uleb128 0 /* Augmentation length */ + /* What follows are the instructions for the table generation. + We have to record all changes of the stack pointer. */ + .byte 0x40 + .Lpush_ebp-.LSTART_vsyscall /* DW_CFA_advance_loc */ + .byte 0x0e /* DW_CFA_def_cfa_offset */ + .uleb128 8 + .byte 0x85, 0x02 /* DW_CFA_offset %ebp -8 */ + .byte 0x40 + .Lpop_ebp-.Lpush_ebp /* DW_CFA_advance_loc */ + .byte 0xc5 /* DW_CFA_restore %ebp */ + .byte 0x0e /* DW_CFA_def_cfa_offset */ + .uleb128 4 + .align 4 +.LENDFDE1: + +#define SYSCALL_ENTER_KERNEL syscall +#include "vsyscall-sigreturn.S" diff -Nru a/arch/x86_64/ia32/vsyscall-sysenter.S b/arch/x86_64/ia32/vsyscall-sysenter.S --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/x86_64/ia32/vsyscall-sysenter.S Sun Mar 14 14:20:09 2004 @@ -0,0 +1,94 @@ +/* + * Code for the vsyscall page. This version uses the sysenter instruction. + */ + +#include +#include + + .text + .section .text.vsyscall,"ax" + .globl __kernel_vsyscall + .type __kernel_vsyscall,@function +__kernel_vsyscall: +.LSTART_vsyscall: + push %ecx +.Lpush_ecx: + push %edx +.Lpush_edx: + push %ebp +.Lenter_kernel: + movl %esp,%ebp + sysenter + .space 7,0x90 + jmp .Lenter_kernel + /* 16: System call normal return point is here! */ + pop %ebp +.Lpop_ebp: + pop %edx +.Lpop_edx: + pop %ecx +.Lpop_ecx: + ret +.LEND_vsyscall: + .size __kernel_vsyscall,.-.LSTART_vsyscall + + .section .eh_frame,"a",@progbits +.LSTARTFRAME: + .long .LENDCIE-.LSTARTCIE +.LSTARTCIE: + .long 0 /* CIE ID */ + .byte 1 /* Version number */ + .string "zR" /* NUL-terminated augmentation string */ + .uleb128 1 /* Code alignment factor */ + .sleb128 -4 /* Data alignment factor */ + .byte 8 /* Return address register column */ + .uleb128 1 /* Augmentation value length */ + .byte 0x1b /* DW_EH_PE_pcrel|DW_EH_PE_sdata4. */ + .byte 0x0c /* DW_CFA_def_cfa */ + .uleb128 4 + .uleb128 4 + .byte 0x88 /* DW_CFA_offset, column 0x8 */ + .uleb128 1 + .align 4 +.LENDCIE: + + .long .LENDFDE1-.LSTARTFDE1 /* Length FDE */ +.LSTARTFDE1: + .long .LSTARTFDE1-.LSTARTFRAME /* CIE pointer */ + .long .LSTART_vsyscall-. /* PC-relative start address */ + .long .LEND_vsyscall-.LSTART_vsyscall + .uleb128 0 /* Augmentation length */ + /* What follows are the instructions for the table generation. + We have to record all changes of the stack pointer. */ + .byte 0x04 /* DW_CFA_advance_loc4 */ + .long .Lpush_ecx-.LSTART_vsyscall + .byte 0x0e /* DW_CFA_def_cfa_offset */ + .byte 0x08 /* RA at offset 8 now */ + .byte 0x04 /* DW_CFA_advance_loc4 */ + .long .Lpush_edx-.Lpush_ecx + .byte 0x0e /* DW_CFA_def_cfa_offset */ + .byte 0x0c /* RA at offset 12 now */ + .byte 0x04 /* DW_CFA_advance_loc4 */ + .long .Lenter_kernel-.Lpush_edx + .byte 0x0e /* DW_CFA_def_cfa_offset */ + .byte 0x10 /* RA at offset 16 now */ + .byte 0x85, 0x04 /* DW_CFA_offset %ebp -16 */ + /* Finally the epilogue. */ + .byte 0x04 /* DW_CFA_advance_loc4 */ + .long .Lpop_ebp-.Lenter_kernel + .byte 0x0e /* DW_CFA_def_cfa_offset */ + .byte 0x12 /* RA at offset 12 now */ + .byte 0xc5 /* DW_CFA_restore %ebp */ + .byte 0x04 /* DW_CFA_advance_loc4 */ + .long .Lpop_edx-.Lpop_ebp + .byte 0x0e /* DW_CFA_def_cfa_offset */ + .byte 0x08 /* RA at offset 8 now */ + .byte 0x04 /* DW_CFA_advance_loc4 */ + .long .Lpop_ecx-.Lpop_edx + .byte 0x0e /* DW_CFA_def_cfa_offset */ + .byte 0x04 /* RA at offset 4 now */ + .align 4 +.LENDFDE1: + +#define SYSCALL_ENTER_KERNEL int $0x80 +#include "vsyscall-sigreturn.S" diff -Nru a/arch/x86_64/ia32/vsyscall.S b/arch/x86_64/ia32/vsyscall.S --- a/arch/x86_64/ia32/vsyscall.S Sun Mar 14 14:20:07 2004 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,172 +0,0 @@ -/* - * Code for the vsyscall page. This version uses the syscall instruction. - */ - -#include -#include - - .text - .section .text.vsyscall,"ax" - .globl __kernel_vsyscall - .type __kernel_vsyscall,@function -__kernel_vsyscall: -.LSTART_vsyscall: - push %ebp -.Lpush_ebp: - movl %ecx, %ebp - syscall - popl %ebp -.Lpop_ebp: - ret -.LEND_vsyscall: - .size __kernel_vsyscall,.-.LSTART_vsyscall - - .section .text.sigreturn,"ax" - .balign 32 - .globl __kernel_sigreturn - .type __kernel_sigreturn,@function -__kernel_sigreturn: -.LSTART_sigreturn: - popl %eax - movl $__NR_ia32_sigreturn, %eax - syscall -.LEND_sigreturn: - .size __kernel_sigreturn,.-.LSTART_sigreturn - - .section .text.rtsigreturn,"ax" - .balign 32 - .globl __kernel_rt_sigreturn - .type __kernel_rt_sigreturn,@function -__kernel_rt_sigreturn: -.LSTART_rt_sigreturn: - movl $__NR_ia32_rt_sigreturn, %eax - syscall -.LEND_rt_sigreturn: - .size __kernel_rt_sigreturn,.-.LSTART_rt_sigreturn - - .section .eh_frame,"a",@progbits -.LSTARTFRAME: - .long .LENDCIE-.LSTARTCIE -.LSTARTCIE: - .long 0 /* CIE ID */ - .byte 1 /* Version number */ - .string "zR" /* NUL-terminated augmentation string */ - .uleb128 1 /* Code alignment factor */ - .sleb128 -4 /* Data alignment factor */ - .byte 8 /* Return address register column */ - .uleb128 1 /* Augmentation value length */ - .byte 0x1b /* DW_EH_PE_pcrel|DW_EH_PE_sdata4. */ - .byte 0x0c /* DW_CFA_def_cfa */ - .uleb128 4 - .uleb128 4 - .byte 0x88 /* DW_CFA_offset, column 0x8 */ - .uleb128 1 - .align 4 -.LENDCIE: - - .long .LENDFDE1-.LSTARTFDE1 /* Length FDE */ -.LSTARTFDE1: - .long .LSTARTFDE1-.LSTARTFRAME /* CIE pointer */ - .long .LSTART_vsyscall-. /* PC-relative start address */ - .long .LEND_vsyscall-.LSTART_vsyscall - .uleb128 0 /* Augmentation length */ - /* What follows are the instructions for the table generation. - We have to record all changes of the stack pointer. */ - .byte 0x40 + .Lpush_ebp-.LSTART_vsyscall /* DW_CFA_advance_loc */ - .byte 0x0e /* DW_CFA_def_cfa_offset */ - .uleb128 8 - .byte 0x85, 0x02 /* DW_CFA_offset %ebp -8 */ - .byte 0x40 + .Lpop_ebp-.Lpush_ebp /* DW_CFA_advance_loc */ - .byte 0xc5 /* DW_CFA_restore %ebp */ - .byte 0x0e /* DW_CFA_def_cfa_offset */ - .uleb128 4 - .align 4 -.LENDFDE1: - - .long .LENDFDE2-.LSTARTFDE2 /* Length FDE */ -.LSTARTFDE2: - .long .LSTARTFDE2-.LSTARTFRAME /* CIE pointer */ - /* HACK: The dwarf2 unwind routines will subtract 1 from the - return address to get an address in the middle of the - presumed call instruction. Since we didn't get here via - a call, we need to include the nop before the real start - to make up for it. */ - .long .LSTART_sigreturn-1-. /* PC-relative start address */ - .long .LEND_sigreturn-.LSTART_sigreturn+1 - .uleb128 0 /* Augmentation length */ - /* What follows are the instructions for the table generation. - We record the locations of each register saved. This is - complicated by the fact that the "CFA" is always assumed to - be the value of the stack pointer in the caller. This means - that we must define the CFA of this body of code to be the - saved value of the stack pointer in the sigcontext. Which - also means that there is no fixed relation to the other - saved registers, which means that we must use DW_CFA_expression - to compute their addresses. It also means that when we - adjust the stack with the popl, we have to do it all over again. */ - -#define do_cfa_expr(offset) \ - .byte 0x0f; /* DW_CFA_def_cfa_expression */ \ - .uleb128 1f-0f; /* length */ \ -0: .byte 0x74; /* DW_OP_breg4 */ \ - .sleb128 offset; /* offset */ \ - .byte 0x06; /* DW_OP_deref */ \ -1: - -#define do_expr(regno, offset) \ - .byte 0x10; /* DW_CFA_expression */ \ - .uleb128 regno; /* regno */ \ - .uleb128 1f-0f; /* length */ \ -0: .byte 0x74; /* DW_OP_breg4 */ \ - .sleb128 offset; /* offset */ \ -1: - - do_cfa_expr(IA32_SIGCONTEXT_esp+4) - do_expr(0, IA32_SIGCONTEXT_eax+4) - do_expr(1, IA32_SIGCONTEXT_ecx+4) - do_expr(2, IA32_SIGCONTEXT_edx+4) - do_expr(3, IA32_SIGCONTEXT_ebx+4) - do_expr(5, IA32_SIGCONTEXT_ebp+4) - do_expr(6, IA32_SIGCONTEXT_esi+4) - do_expr(7, IA32_SIGCONTEXT_edi+4) - do_expr(8, IA32_SIGCONTEXT_eip+4) - - .byte 0x42 /* DW_CFA_advance_loc 2 -- nop; popl eax. */ - - do_cfa_expr(IA32_SIGCONTEXT_esp) - do_expr(0, IA32_SIGCONTEXT_eax) - do_expr(1, IA32_SIGCONTEXT_ecx) - do_expr(2, IA32_SIGCONTEXT_edx) - do_expr(3, IA32_SIGCONTEXT_ebx) - do_expr(5, IA32_SIGCONTEXT_ebp) - do_expr(6, IA32_SIGCONTEXT_esi) - do_expr(7, IA32_SIGCONTEXT_edi) - do_expr(8, IA32_SIGCONTEXT_eip) - - .align 4 -.LENDFDE2: - - .long .LENDFDE3-.LSTARTFDE3 /* Length FDE */ -.LSTARTFDE3: - .long .LSTARTFDE3-.LSTARTFRAME /* CIE pointer */ - /* HACK: See above wrt unwind library assumptions. */ - .long .LSTART_rt_sigreturn-1-. /* PC-relative start address */ - .long .LEND_rt_sigreturn-.LSTART_rt_sigreturn+1 - .uleb128 0 /* Augmentation */ - /* What follows are the instructions for the table generation. - We record the locations of each register saved. This is - slightly less complicated than the above, since we don't - modify the stack pointer in the process. */ - - do_cfa_expr(IA32_RT_SIGFRAME_sigcontext-4 + IA32_SIGCONTEXT_esp) - do_expr(0, IA32_RT_SIGFRAME_sigcontext-4 + IA32_SIGCONTEXT_eax) - do_expr(1, IA32_RT_SIGFRAME_sigcontext-4 + IA32_SIGCONTEXT_ecx) - do_expr(2, IA32_RT_SIGFRAME_sigcontext-4 + IA32_SIGCONTEXT_edx) - do_expr(3, IA32_RT_SIGFRAME_sigcontext-4 + IA32_SIGCONTEXT_ebx) - do_expr(5, IA32_RT_SIGFRAME_sigcontext-4 + IA32_SIGCONTEXT_ebp) - do_expr(6, IA32_RT_SIGFRAME_sigcontext-4 + IA32_SIGCONTEXT_esi) - do_expr(7, IA32_RT_SIGFRAME_sigcontext-4 + IA32_SIGCONTEXT_edi) - do_expr(8, IA32_RT_SIGFRAME_sigcontext-4 + IA32_SIGCONTEXT_eip) - - .align 4 -.LENDFDE3: diff -Nru a/arch/x86_64/kernel/Makefile b/arch/x86_64/kernel/Makefile --- a/arch/x86_64/kernel/Makefile Sun Mar 14 14:20:08 2004 +++ b/arch/x86_64/kernel/Makefile Sun Mar 14 14:20:08 2004 @@ -8,10 +8,9 @@ ptrace.o i8259.o ioport.o ldt.o setup.o time.o sys_x86_64.o \ x8664_ksyms.o i387.o syscall.o vsyscall.o \ setup64.o bootflag.o e820.o reboot.o warmreboot.o -obj-y += mce.o +obj-y += mce.o acpi/ obj-$(CONFIG_MTRR) += ../../i386/kernel/cpu/mtrr/ -obj-$(CONFIG_ACPI) += acpi/ obj-$(CONFIG_X86_MSR) += msr.o obj-$(CONFIG_MICROCODE) += microcode.o obj-$(CONFIG_X86_CPUID) += cpuid.o diff -Nru a/arch/x86_64/kernel/acpi/boot.c b/arch/x86_64/kernel/acpi/boot.c --- a/arch/x86_64/kernel/acpi/boot.c Sun Mar 14 14:20:06 2004 +++ b/arch/x86_64/kernel/acpi/boot.c Sun Mar 14 14:20:06 2004 @@ -78,6 +78,31 @@ return NULL; } +#ifdef CONFIG_PCI_MMCONFIG +static int __init acpi_parse_mcfg(unsigned long phys_addr, unsigned long size) +{ + struct acpi_table_mcfg *mcfg; + + if (!phys_addr || !size) + return -EINVAL; + + mcfg = (struct acpi_table_mcfg *) __acpi_map_table(phys_addr, size); + if (!mcfg) { + printk(KERN_WARNING PREFIX "Unable to map MCFG\n"); + return -ENODEV; + } + + if (mcfg->base_reserved) { + printk(KERN_ERR PREFIX "MMCONFIG not in low 4GB of memory\n"); + return -ENODEV; + } + + pci_mmcfg_base_addr = mcfg->base_address; + + return 0; +} +#endif /* CONFIG_PCI_MMCONFIG */ + #ifdef CONFIG_X86_LOCAL_APIC static u64 acpi_lapic_addr __initdata = APIC_DEFAULT_PHYS_BASE; @@ -234,6 +259,24 @@ #endif /*CONFIG_X86_IO_APIC*/ +static int __init acpi_parse_sbf(unsigned long phys_addr, unsigned long size) +{ + struct acpi_table_sbf *sb; + + if (!phys_addr || !size) + return -EINVAL; + + sb = (struct acpi_table_sbf *) __acpi_map_table(phys_addr, size); + if (!sb) { + printk(KERN_WARNING PREFIX "Unable to map SBF\n"); + return -ENODEV; + } + + sbf_port = sb->sbf_cmos; /* Save CMOS port */ + + return 0; +} + #ifdef CONFIG_HPET_TIMER static int __init acpi_parse_hpet ( @@ -404,6 +447,8 @@ return result; } + (void) acpi_table_parse(ACPI_BOOT, acpi_parse_sbf); + result = acpi_blacklisted(); if (result) { printk(KERN_WARNING PREFIX "BIOS listed in blacklist, disabling ACPI support\n"); @@ -548,6 +593,12 @@ result = acpi_table_parse(ACPI_HPET, acpi_parse_hpet); if (result < 0) printk("ACPI: no HPET table found (%d).\n", result); +#endif + +#ifdef CONFIG_PCI_MMCONFIG + result = acpi_table_parse(ACPI_MCFG, acpi_parse_mcfg); + if (result) + printk(KERN_ERR PREFIX "Error %d parsing MCFG\n", result); #endif return 0; diff -Nru a/arch/x86_64/kernel/entry.S b/arch/x86_64/kernel/entry.S --- a/arch/x86_64/kernel/entry.S Sun Mar 14 14:20:07 2004 +++ b/arch/x86_64/kernel/entry.S Sun Mar 14 14:20:07 2004 @@ -226,7 +226,7 @@ /* Handle a signal */ sysret_signal: sti - testl $(_TIF_SIGPENDING|_TIF_NOTIFY_RESUME),%edx + testl $(_TIF_SIGPENDING|_TIF_NOTIFY_RESUME|_TIF_SINGLESTEP),%edx jz 1f /* Really a signal */ @@ -307,7 +307,7 @@ jmp int_restore_rest int_signal: - testl $(_TIF_NOTIFY_RESUME|_TIF_SIGPENDING),%edx + testl $(_TIF_NOTIFY_RESUME|_TIF_SIGPENDING|_TIF_SINGLESTEP),%edx jz 1f movq %rsp,%rdi # &ptregs -> arg1 xorl %esi,%esi # oldset -> arg2 @@ -489,7 +489,7 @@ jmp retint_check retint_signal: - testl $(_TIF_SIGPENDING|_TIF_NOTIFY_RESUME),%edx + testl $(_TIF_SIGPENDING|_TIF_NOTIFY_RESUME|_TIF_SINGLESTEP),%edx jz retint_swapgs sti SAVE_REST @@ -572,6 +572,24 @@ jmp error_entry .endm + /* error code is on the stack already */ + /* handle NMI like exceptions that can happen everywhere */ + .macro paranoidentry sym + SAVE_ALL + cld + movl $1,%ebx + movl $MSR_GS_BASE,%ecx + rdmsr + testl %edx,%edx + js 1f + swapgs + xorl %ebx,%ebx +1: movq %rsp,%rdi + movq ORIG_RAX(%rsp),%rsi + movq $-1,ORIG_RAX(%rsp) + call \sym + .endm + /* * Exception entry point. This expects an error code/orig_rax on the stack * and the exception handler in %rax. @@ -625,6 +643,7 @@ movq ORIG_RAX(%rsp),%rsi /* get error code */ movq $-1,ORIG_RAX(%rsp) call *%rax + /* ebx: no swapgs flag (1: don't need swapgs, 0: need it) */ error_exit: movl %ebx,%eax RESTORE_REST @@ -776,48 +795,59 @@ zeroentry do_simd_coprocessor_error ENTRY(device_not_available) - CFI_STARTPROC - pushq $-1 #error code - SAVE_ALL - movl $1,%ebx - testl $3,CS(%rsp) - je 1f - xorl %ebx,%ebx - swapgs -1: movq %cr0,%rax - leaq math_state_restore(%rip),%rcx - leaq math_emulate(%rip),%rdx - testl $0x4,%eax - cmoveq %rcx,%rdx - call *%rdx - jmp error_exit - CFI_ENDPROC + zeroentry math_state_restore + /* runs on exception stack */ ENTRY(debug) - zeroentry do_debug + CFI_STARTPROC + pushq $0 + CFI_ADJUST_CFA_OFFSET 8 + paranoidentry do_debug +paranoid_stack_switch: + testq %rax,%rax + jz paranoid_exit + /* switch back to process stack to restore the state ptrace touched */ + movq %rax,%rsp + jmp paranoid_exit + CFI_ENDPROC + /* runs on exception stack */ ENTRY(nmi) CFI_STARTPROC pushq $-1 - SAVE_ALL - /* NMI could happen inside the critical section of a swapgs, - so it is needed to use this expensive way to check. */ - movl $MSR_GS_BASE,%ecx - rdmsr - xorl %ebx,%ebx - testl %edx,%edx - js 1f - swapgs - movl $1,%ebx -1: movq %rsp,%rdi # regs -> arg1 - call do_nmi - /* XXX: should do preemption checks here */ + CFI_ADJUST_CFA_OFFSET 8 + paranoidentry do_nmi + /* ebx: no swapgs flag */ +paranoid_exit: + testl $3,CS(%rsp) + jnz paranoid_userspace + testl %ebx,%ebx /* swapgs needed? */ + jnz paranoid_restore +paranoid_swapgs: cli - testl %ebx,%ebx - jz 2f swapgs -2: RESTORE_ALL 8 +paranoid_restore: + RESTORE_ALL 8 iretq +paranoid_userspace: + cli + GET_THREAD_INFO(%rcx) + movl threadinfo_flags(%rcx),%edx + testl $_TIF_NEED_RESCHED,%edx + jnz paranoid_resched + testl $(_TIF_SIGPENDING|_TIF_NOTIFY_RESUME|_TIF_SINGLESTEP),%edx + jnz paranoid_signal + jmp paranoid_swapgs +paranoid_resched: + sti + call schedule + jmp paranoid_exit +paranoid_signal: + sti + xorl %esi,%esi /* oldset */ + movq %rsp,%rdi /* &pt_regs */ + call do_notify_resume + jmp paranoid_exit CFI_ENDPROC ENTRY(int3) @@ -838,8 +868,10 @@ ENTRY(reserved) zeroentry do_reserved + /* runs on exception stack */ ENTRY(double_fault) - errorentry do_double_fault + paranoidentry do_double_fault + jmp paranoid_stack_switch ENTRY(invalid_TSS) errorentry do_invalid_TSS @@ -847,8 +879,10 @@ ENTRY(segment_not_present) errorentry do_segment_not_present + /* runs on exception stack */ ENTRY(stack_segment) - errorentry do_stack_segment + paranoidentry do_stack_segment + jmp paranoid_stack_switch ENTRY(general_protection) errorentry do_general_protection @@ -862,8 +896,14 @@ ENTRY(spurious_interrupt_bug) zeroentry do_spurious_interrupt_bug + /* runs on exception stack */ ENTRY(machine_check) - zeroentry do_machine_check + CFI_STARTPROC + pushq $0 + CFI_ADJUST_CFA_OFFSET 8 + paranoidentry do_machine_check + jmp paranoid_exit + CFI_ENDPROC ENTRY(call_debug) zeroentry do_call_debug diff -Nru a/arch/x86_64/kernel/ioport.c b/arch/x86_64/kernel/ioport.c --- a/arch/x86_64/kernel/ioport.c Sun Mar 14 14:20:06 2004 +++ b/arch/x86_64/kernel/ioport.c Sun Mar 14 14:20:06 2004 @@ -95,7 +95,5 @@ 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; } diff -Nru a/arch/x86_64/kernel/mpparse.c b/arch/x86_64/kernel/mpparse.c --- a/arch/x86_64/kernel/mpparse.c Sun Mar 14 14:20:06 2004 +++ b/arch/x86_64/kernel/mpparse.c Sun Mar 14 14:20:06 2004 @@ -880,6 +880,7 @@ void __init mp_config_ioapic_for_sci(int irq) { +#ifdef CONFIG_ACPI_INTERPRETER int ioapic; int ioapic_pin; struct acpi_table_madt *madt; @@ -939,6 +940,7 @@ */ io_apic_set_pci_routing(ioapic, ioapic_pin, irq, (flags.trigger == 1 ? 0 : 1), (flags.polarity == 1 ? 0 : 1)); +#endif } #ifdef CONFIG_ACPI_PCI diff -Nru a/arch/x86_64/kernel/pci-gart.c b/arch/x86_64/kernel/pci-gart.c --- a/arch/x86_64/kernel/pci-gart.c Sun Mar 14 14:20:07 2004 +++ b/arch/x86_64/kernel/pci-gart.c Sun Mar 14 14:20:07 2004 @@ -50,6 +50,12 @@ #endif int iommu_merge = 0; int iommu_sac_force = 0; + +/* If this is disabled the IOMMU will use an optimized flushing strategy + of only flushing when an mapping is reused. With it true the GART is flushed + for every mapping. Problem is that doing the lazy flush seems to trigger + bugs with some popular PCI cards, in particular 3ware (but has been also + also seen with Qlogic at least). */ int iommu_fullflush = 1; #define MAX_NB 8 @@ -177,7 +183,7 @@ gfp |= GFP_DMA; dma_mask = 0xffffffff; } else { - dma_mask = hwdev->consistent_dma_mask; + dma_mask = hwdev->dev.coherent_dma_mask; } if (dma_mask == 0) diff -Nru a/arch/x86_64/kernel/process.c b/arch/x86_64/kernel/process.c --- a/arch/x86_64/kernel/process.c Sun Mar 14 14:20:07 2004 +++ b/arch/x86_64/kernel/process.c Sun Mar 14 14:20:07 2004 @@ -16,7 +16,6 @@ * This file handles the architecture-dependent parts of process handling.. */ -#define __KERNEL_SYSCALLS__ #include #include @@ -25,7 +24,6 @@ #include #include #include -#include #include #include #include @@ -53,7 +51,7 @@ unsigned long kernel_thread_flags = CLONE_VM | CLONE_UNTRACED; -int hlt_counter; +atomic_t hlt_counter = ATOMIC_INIT(0); /* * Powermanagement idle function, if any.. @@ -62,14 +60,14 @@ void disable_hlt(void) { - hlt_counter++; + atomic_inc(&hlt_counter); } EXPORT_SYMBOL(disable_hlt); void enable_hlt(void) { - hlt_counter--; + atomic_dec(&hlt_counter); } EXPORT_SYMBOL(enable_hlt); @@ -80,7 +78,7 @@ */ void default_idle(void) { - if (!hlt_counter) { + if (!atomic_read(&hlt_counter)) { local_irq_disable(); if (!need_resched()) safe_halt(); diff -Nru a/arch/x86_64/kernel/setup.c b/arch/x86_64/kernel/setup.c --- a/arch/x86_64/kernel/setup.c Sun Mar 14 14:20:06 2004 +++ b/arch/x86_64/kernel/setup.c Sun Mar 14 14:20:06 2004 @@ -218,6 +218,11 @@ if (!memcmp(from, "acpi=ht", 7)) { acpi_ht = 1; } + + /* acpi=strict disables out-of-spec workarounds */ + else if (!memcmp(from, "acpi=strict", 11)) { + acpi_strict = 1; + } #endif if (!memcmp(from, "nolapic", 7) || @@ -793,13 +798,12 @@ char *model_names[16]; }; -/* - * This does the hard work of actually picking apart the CPU stuff... - */ -void __init identify_cpu(struct cpuinfo_x86 *c) +/* Do some early cpuid on the boot CPU to get some parameter that are + needed before check_bugs. Everything advanced is in identify_cpu + below. */ +void __init early_identify_cpu(struct cpuinfo_x86 *c) { - int i; - u32 xlvl, tfms; + u32 tfms; c->loops_per_jiffy = loops_per_jiffy; c->x86_cache_size = -1; @@ -807,6 +811,7 @@ c->x86_model = c->x86_mask = 0; /* So far unknown... */ c->x86_vendor_id[0] = '\0'; /* Unset */ c->x86_model_id[0] = '\0'; /* Unset */ + c->x86_clflush_size = 64; memset(&c->x86_capability, 0, sizeof c->x86_capability); /* Get vendor name */ @@ -816,6 +821,7 @@ (int *)&c->x86_vendor_id[4]); get_cpu_vendor(c); + /* Initialize the standard set of capabilities */ /* Note that the vendor-specific code below might override */ @@ -837,6 +843,17 @@ /* Have CPUID level 0 only - unheard of */ c->x86 = 4; } +} + +/* + * This does the hard work of actually picking apart the CPU stuff... + */ +void __init identify_cpu(struct cpuinfo_x86 *c) +{ + int i; + u32 xlvl; + + early_identify_cpu(c); /* AMD-defined flags: level 0x80000001 */ xlvl = cpuid_eax(0x80000000); @@ -853,7 +870,6 @@ if ( xlvl >= 0x80860001 ) c->x86_capability[2] = cpuid_edx(0x80860001); } - /* * Vendor-specific initialization. In this section we diff -Nru a/arch/x86_64/kernel/setup64.c b/arch/x86_64/kernel/setup64.c --- a/arch/x86_64/kernel/setup64.c Sun Mar 14 14:20:06 2004 +++ b/arch/x86_64/kernel/setup64.c Sun Mar 14 14:20:06 2004 @@ -202,7 +202,7 @@ wrmsrl(MSR_LSTAR, system_call); #ifdef CONFIG_IA32_EMULATION - wrmsrl(MSR_CSTAR, ia32_cstar_target); + syscall32_cpu_init (); #endif /* Flags to clear on syscall */ @@ -274,6 +274,9 @@ asm volatile("pushfq ; popq %%rax ; btr $14,%%rax ; pushq %%rax ; popfq" ::: "eax"); + if (cpu == 0) + early_identify_cpu(&boot_cpu_data); + syscall_init(); wrmsrl(MSR_FS_BASE, 0); @@ -287,7 +290,8 @@ */ for (v = 0; v < N_EXCEPTION_STACKS; v++) { if (cpu) { - estacks = (char *)__get_free_pages(GFP_ATOMIC, 0); + estacks = (char *)__get_free_pages(GFP_ATOMIC, + EXCEPTION_STACK_ORDER); if (!estacks) panic("Cannot allocate exception stack %ld %d\n", v, cpu); diff -Nru a/arch/x86_64/kernel/smpboot.c b/arch/x86_64/kernel/smpboot.c --- a/arch/x86_64/kernel/smpboot.c Sun Mar 14 14:20:08 2004 +++ b/arch/x86_64/kernel/smpboot.c Sun Mar 14 14:20:08 2004 @@ -55,11 +55,16 @@ /* Number of siblings per CPU package */ int smp_num_siblings = 1; -int phys_proc_id[NR_CPUS]; /* Package ID of each logical CPU */ +char phys_proc_id[NR_CPUS]; /* Package ID of each logical CPU */ /* Bitmask of currently online CPUs */ cpumask_t cpu_online_map; +/* which CPU (physical APIC ID) maps to which logical CPU number */ +volatile char x86_apicid_to_cpu[NR_CPUS]; +/* which logical CPU number maps to which CPU (physical APIC ID) */ +volatile char x86_cpu_to_apicid[NR_CPUS]; + static cpumask_t cpu_callin_map; cpumask_t cpu_callout_map; static cpumask_t smp_commenced_mask; @@ -70,7 +75,7 @@ /* Set when the idlers are all forked */ int smp_threads_ready; -int cpu_sibling_map[NR_CPUS] __cacheline_aligned; +char cpu_sibling_map[NR_CPUS] __cacheline_aligned; /* * Trampoline 80x86 program as an array. @@ -574,6 +579,9 @@ if (IS_ERR(idle)) panic("failed fork for CPU %d", cpu); wake_up_forked_process(idle); + x86_cpu_to_apicid[cpu] = apicid; + x86_apicid_to_cpu[apicid] = cpu; + /* * We remove it from the pidhash and the runqueue @@ -885,7 +893,7 @@ break; } } - if (cpu_sibling_map[cpu] == NO_PROC_ID) { + if (cpu_sibling_map[cpu] == (char)NO_PROC_ID) { smp_num_siblings = 1; printk(KERN_WARNING "WARNING: No sibling found for CPU %d.\n", cpu); } diff -Nru a/arch/x86_64/kernel/traps.c b/arch/x86_64/kernel/traps.c --- a/arch/x86_64/kernel/traps.c Sun Mar 14 14:20:05 2004 +++ b/arch/x86_64/kernel/traps.c Sun Mar 14 14:20:05 2004 @@ -351,24 +351,19 @@ void __die(const char * str, struct pt_regs * regs, long err) { - int nl = 0; static int die_counter; - printk(KERN_EMERG "%s: %04lx [%u]\n", str, err & 0xffff,++die_counter); - notify_die(DIE_OOPS, (char *)str, regs, err, 255, SIGSEGV); + printk(KERN_EMERG "%s: %04lx [%u] ", str, err & 0xffff,++die_counter); #ifdef CONFIG_PREEMPT printk("PREEMPT "); - nl = 1; #endif #ifdef CONFIG_SMP printk("SMP "); - nl = 1; #endif #ifdef CONFIG_DEBUG_PAGEALLOC printk("DEBUG_PAGEALLOC"); - nl = 1; #endif - if (nl) printk("\n"); + notify_die(DIE_OOPS, (char *)str, regs, err, 255, SIGSEGV); show_registers(regs); /* Executive summary in case the oops scrolled away */ printk("RIP "); @@ -475,14 +470,27 @@ DO_ERROR( 5, SIGSEGV, "bounds", bounds) DO_ERROR_INFO( 6, SIGILL, "invalid operand", invalid_op, ILL_ILLOPN, regs->rip) DO_ERROR( 7, SIGSEGV, "device not available", device_not_available) -DO_ERROR( 8, SIGSEGV, "double fault", double_fault) DO_ERROR( 9, SIGFPE, "coprocessor segment overrun", coprocessor_segment_overrun) DO_ERROR(10, SIGSEGV, "invalid TSS", invalid_TSS) DO_ERROR(11, SIGBUS, "segment not present", segment_not_present) -DO_ERROR(12, SIGBUS, "stack segment", stack_segment) DO_ERROR_INFO(17, SIGBUS, "alignment check", alignment_check, BUS_ADRALN, get_cr2()) DO_ERROR(18, SIGSEGV, "reserved", reserved) +#define DO_ERROR_STACK(trapnr, signr, str, name) \ +asmlinkage unsigned long do_##name(struct pt_regs * regs, long error_code) \ +{ \ + struct pt_regs *pr = ((struct pt_regs *)(current->thread.rsp0))-1; \ + if (notify_die(DIE_TRAP, str, regs, error_code, trapnr, signr) == NOTIFY_BAD) \ + return 0; \ + if (regs->cs & 3) \ + memcpy(pr, regs, sizeof(struct pt_regs)); \ + do_trap(trapnr, signr, str, regs, error_code, NULL); \ + return (regs->cs & 3) ? (unsigned long)pr : 0; \ +} + +DO_ERROR_STACK(12, SIGBUS, "stack segment", stack_segment) +DO_ERROR_STACK( 8, SIGSEGV, "double fault", double_fault) + asmlinkage void do_general_protection(struct pt_regs * regs, long error_code) { conditional_sti(regs); @@ -596,12 +604,18 @@ inb(0x71); /* dummy */ } -asmlinkage void do_debug(struct pt_regs * regs, long error_code) +/* runs on IST stack. */ +asmlinkage unsigned long do_debug(struct pt_regs * regs, unsigned long error_code) { + struct pt_regs *processregs; unsigned long condition; struct task_struct *tsk = current; siginfo_t info; + processregs = (struct pt_regs *)(current->thread.rsp0)-1; + if (regs->cs & 3) + memcpy(processregs, regs, sizeof(struct pt_regs)); + #ifdef CONFIG_CHECKING { /* RED-PEN interaction with debugger - could destroy gs */ @@ -658,17 +672,21 @@ force_sig_info(SIGTRAP, &info, tsk); clear_dr7: asm volatile("movq %0,%%db7"::"r"(0UL)); - notify_die(DIE_DEBUG, "debug", regs, error_code, 1, SIGTRAP); - return; + notify_die(DIE_DEBUG, "debug", regs, condition, 1, SIGTRAP); +out: + return (regs->cs & 3) ? (unsigned long)processregs : 0; clear_TF_reenable: + printk("clear_tf_reenable\n"); set_tsk_thread_flag(tsk, TIF_SINGLESTEP); clear_TF: /* RED-PEN could cause spurious errors */ - if (notify_die(DIE_DEBUG, "debug2", regs, error_code, 1, SIGTRAP) != NOTIFY_BAD) + if (notify_die(DIE_DEBUG, "debug2", regs, condition, 1, SIGTRAP) + != NOTIFY_BAD) regs->eflags &= ~TF_MASK; - return; + + goto out; } /* @@ -730,7 +748,7 @@ force_sig_info(SIGFPE, &info, task); } -asmlinkage void do_coprocessor_error(struct pt_regs * regs, long error_code) +asmlinkage void do_coprocessor_error(struct pt_regs * regs) { conditional_sti(regs); math_error((void *)regs->rip); @@ -789,8 +807,7 @@ force_sig_info(SIGFPE, &info, task); } -asmlinkage void do_simd_coprocessor_error(struct pt_regs * regs, - long error_code) +asmlinkage void do_simd_coprocessor_error(struct pt_regs * regs) { conditional_sti(regs); simd_math_error((void *)regs->rip); @@ -818,11 +835,6 @@ me->thread_info->status |= TS_USEDFPU; } -asmlinkage void math_emulate(void) -{ - BUG(); -} - void do_call_debug(struct pt_regs *regs) { notify_die(DIE_CALL, "debug call", regs, 0, 255, SIGINT); @@ -831,7 +843,7 @@ void __init trap_init(void) { set_intr_gate(0,÷_error); - set_intr_gate(1,&debug); + set_intr_gate_ist(1,&debug,DEBUG_STACK); set_intr_gate_ist(2,&nmi,NMI_STACK); set_system_gate(3,&int3); /* int3-5 can be called from all */ set_system_gate(4,&overflow); @@ -848,7 +860,7 @@ set_intr_gate(15,&spurious_interrupt_bug); set_intr_gate(16,&coprocessor_error); set_intr_gate(17,&alignment_check); - set_intr_gate(18,&machine_check); + set_intr_gate_ist(18,&machine_check, MCE_STACK); set_intr_gate(19,&simd_coprocessor_error); #ifdef CONFIG_IA32_EMULATION diff -Nru a/arch/x86_64/kernel/vsyscall.c b/arch/x86_64/kernel/vsyscall.c --- a/arch/x86_64/kernel/vsyscall.c Sun Mar 14 14:20:08 2004 +++ b/arch/x86_64/kernel/vsyscall.c Sun Mar 14 14:20:08 2004 @@ -31,9 +31,6 @@ * broken programs will segfault and there's no security risk until we choose to * fix it. * - * Add HPET support (port from 2.4). Still needed? - * Nop out vsyscall syscall to avoid anchor for buffer overflows when sysctl off. - * * These are not urgent things that we need to address only before shipping the first * production binary kernels. */ @@ -89,7 +86,7 @@ if (t < __vxtime.last_tsc) t = __vxtime.last_tsc; usec += ((t - __vxtime.last_tsc) * __vxtime.tsc_quot) >> 32; - /* See comment in x86_64 do_gettimeopfday. */ + /* See comment in x86_64 do_gettimeofday. */ } else { usec += ((readl(fix_to_virt(VSYSCALL_HPET) + 0xf0) - __vxtime.last) * __vxtime.quot) >> 32; @@ -106,6 +103,7 @@ *tz = __sys_tz; } + static force_inline int gettimeofday(struct timeval *tv, struct timezone *tz) { int ret; @@ -115,6 +113,15 @@ return ret; } +static force_inline long time_syscall(long *t) +{ + long secs; + asm volatile("syscall" + : "=a" (secs) + : "0" (__NR_time),"D" (t) : __syscall_clobber); + return secs; +} + static int __vsyscall(0) vgettimeofday(struct timeval * tv, struct timezone * tz) { if (unlikely(!__sysctl_vsyscall)) @@ -126,16 +133,15 @@ return 0; } -static time_t __vsyscall(1) vtime(time_t * t) +/* This will break when the xtime seconds get inaccurate, but that is + * unlikely */ +static time_t __vsyscall(1) vtime(time_t *t) { - struct timeval tv; if (unlikely(!__sysctl_vsyscall)) - gettimeofday(&tv, NULL); - else - do_vgettimeofday(&tv); - if (t) - *t = tv.tv_sec; - return tv.tv_sec; + return time_syscall(t); + else if (t) + *t = __xtime.tv_sec; + return __xtime.tv_sec; } static long __vsyscall(2) venosys_0(void) diff -Nru a/arch/x86_64/kernel/x8664_ksyms.c b/arch/x86_64/kernel/x8664_ksyms.c --- a/arch/x86_64/kernel/x8664_ksyms.c Sun Mar 14 14:20:06 2004 +++ b/arch/x86_64/kernel/x8664_ksyms.c Sun Mar 14 14:20:06 2004 @@ -63,10 +63,6 @@ EXPORT_SYMBOL(pm_power_off); EXPORT_SYMBOL(get_cmos_time); -#ifdef CONFIG_IO_DEBUG -EXPORT_SYMBOL(__io_virt_debug); -#endif - EXPORT_SYMBOL_NOVERS(__down_failed); EXPORT_SYMBOL_NOVERS(__down_failed_interruptible); EXPORT_SYMBOL_NOVERS(__down_failed_trylock); @@ -225,3 +221,6 @@ #endif EXPORT_SYMBOL(sys_ioctl); + +EXPORT_SYMBOL(memcpy_toio); +EXPORT_SYMBOL(memcpy_fromio); diff -Nru a/arch/x86_64/lib/Makefile b/arch/x86_64/lib/Makefile --- a/arch/x86_64/lib/Makefile Sun Mar 14 14:20:06 2004 +++ b/arch/x86_64/lib/Makefile Sun Mar 14 14:20:06 2004 @@ -9,5 +9,4 @@ thunk.o io.o clear_page.o copy_page.o bitstr.o lib-y += memcpy.o memmove.o memset.o copy_user.o -lib-$(CONFIG_IO_DEBUG) += iodebug.o lib-$(CONFIG_HAVE_DEC_LOCK) += dec_and_lock.o diff -Nru a/arch/x86_64/lib/csum-copy.S b/arch/x86_64/lib/csum-copy.S --- a/arch/x86_64/lib/csum-copy.S Sun Mar 14 14:20:08 2004 +++ b/arch/x86_64/lib/csum-copy.S Sun Mar 14 14:20:08 2004 @@ -220,10 +220,14 @@ /* Exception handlers. Very simple, zeroing is done in the wrappers */ .Lbad_source: movq (%rsp),%rax + testq %rax,%rax + jz .Lende movl $-EFAULT,(%rax) jmp .Lende .Lbad_dest: movq 8(%rsp),%rax + testq %rax,%rax + jz .Lende movl $-EFAULT,(%rax) jmp .Lende diff -Nru a/arch/x86_64/lib/io.c b/arch/x86_64/lib/io.c --- a/arch/x86_64/lib/io.c Sun Mar 14 14:20:06 2004 +++ b/arch/x86_64/lib/io.c Sun Mar 14 14:20:06 2004 @@ -4,14 +4,10 @@ void *memcpy_toio(void *dst,const void*src,unsigned len) { - return __inline_memcpy(__io_virt(dst),src,len); + return __inline_memcpy(dst,src,len); } void *memcpy_fromio(void *dst,const void*src,unsigned len) { - return __inline_memcpy(dst,__io_virt(src),len); + return __inline_memcpy(dst,src,len); } - -EXPORT_SYMBOL(memcpy_toio); -EXPORT_SYMBOL(memcpy_fromio); - diff -Nru a/arch/x86_64/lib/iodebug.c b/arch/x86_64/lib/iodebug.c --- a/arch/x86_64/lib/iodebug.c Sun Mar 14 14:20:07 2004 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,11 +0,0 @@ -#include - -void * __io_virt_debug(unsigned long x, const char *file, int line) -{ - if (x < PAGE_OFFSET) { - printk("io mapaddr 0x%05lx not valid at %s:%d!\n", x, file, line); - return __va(x); - } - return (void *)x; -} - diff -Nru a/arch/x86_64/mm/fault.c b/arch/x86_64/mm/fault.c --- a/arch/x86_64/mm/fault.c Sun Mar 14 14:20:05 2004 +++ b/arch/x86_64/mm/fault.c Sun Mar 14 14:20:05 2004 @@ -280,15 +280,6 @@ if (unlikely(in_atomic() || !mm)) goto bad_area_nosemaphore; - /* Work around K8 erratum #100 - K8 in compat mode occasionally jumps to illegal addresses >4GB. - We catch this here in the page fault handler because these - addresses are not reachable. Just detect this case and return. - Any code segment in LDT is compatibility mode. */ - if ((regs->cs == __USER32_CS || (regs->cs & (1<<2))) && - (address >> 32)) - return; - again: down_read(&mm->mmap_sem); @@ -371,6 +362,16 @@ /* User mode accesses just cause a SIGSEGV */ if (error_code & 4) { if (is_prefetch(regs, address)) + return; + + /* Work around K8 erratum #100 K8 in compat mode + occasionally jumps to illegal addresses >4GB. We + catch this here in the page fault handler because + these addresses are not reachable. Just detect this + case and return. Any code segment in LDT is + compatibility mode. */ + if ((regs->cs == __USER32_CS || (regs->cs & (1<<2))) && + (address >> 32)) return; if (exception_trace && !unhandled_signal(tsk, SIGSEGV)) { diff -Nru a/arch/x86_64/mm/init.c b/arch/x86_64/mm/init.c --- a/arch/x86_64/mm/init.c Sun Mar 14 14:20:06 2004 +++ b/arch/x86_64/mm/init.c Sun Mar 14 14:20:06 2004 @@ -37,7 +37,9 @@ #include #include +#ifndef Dprintk #define Dprintk(x...) +#endif extern char _stext[]; @@ -577,3 +579,32 @@ } __initcall(x8664_sysctl_init); #endif + +/* Pseudo VMAs to allow ptrace access for the vsyscall pages. x86-64 has two + different ones: one for 32bit and one for 64bit. Use the appropiate + for the target task. */ + +static struct vm_area_struct gate_vma = { + .vm_start = VSYSCALL_START, + .vm_end = VSYSCALL_END, + .vm_page_prot = PAGE_READONLY +}; + +static struct vm_area_struct gate32_vma = { + .vm_start = VSYSCALL32_BASE, + .vm_end = VSYSCALL32_END, + .vm_page_prot = PAGE_READONLY +}; + +struct vm_area_struct *get_gate_vma(struct task_struct *tsk) +{ + return test_tsk_thread_flag(tsk, TIF_IA32) ? &gate32_vma : &gate_vma; +} + +int in_gate_area(struct task_struct *task, unsigned long addr) +{ + struct vm_area_struct *vma = &gate_vma; + if (test_tsk_thread_flag(task, TIF_IA32)) + vma = &gate32_vma; + return (addr >= vma->vm_start) && (addr < vma->vm_end); +} diff -Nru a/arch/x86_64/mm/numa.c b/arch/x86_64/mm/numa.c --- a/arch/x86_64/mm/numa.c Sun Mar 14 14:20:08 2004 +++ b/arch/x86_64/mm/numa.c Sun Mar 14 14:20:08 2004 @@ -14,7 +14,9 @@ #include #include +#ifndef Dprintk #define Dprintk(x...) +#endif struct pglist_data *node_data[MAXNODE]; bootmem_data_t plat_node_bdata[MAX_NUMNODES]; diff -Nru a/arch/x86_64/pci/Makefile b/arch/x86_64/pci/Makefile --- a/arch/x86_64/pci/Makefile Sun Mar 14 14:20:06 2004 +++ b/arch/x86_64/pci/Makefile Sun Mar 14 14:20:06 2004 @@ -1,29 +1,22 @@ # # Makefile for X86_64 specific PCI routines # -# Reuse the i386 PCI subsystem using symlinks +# Reuse the i386 PCI subsystem # +CFLAGS += -I arch/i386/pci + obj-y := i386.o obj-$(CONFIG_PCI_DIRECT)+= direct.o obj-y += fixup.o obj-$(CONFIG_ACPI_PCI) += acpi.o obj-y += legacy.o irq.o common.o +# mmconfig has a 64bit special +obj-$(CONFIG_PCI_MMCONFIG) += mmconfig.o -$(obj)/direct.c: $(obj)/pci.h - @ln -sf ../../i386/pci/direct.c $(obj)/direct.c -$(obj)/legacy.c: $(obj)/pci.h - @ln -sf ../../i386/pci/legacy.c $(obj)/legacy.c -$(obj)/common.c: $(obj)/pci.h - @ln -sf ../../i386/pci/common.c $(obj)/common.c -$(obj)/acpi.c: $(obj)/pci.h - @ln -sf ../../i386/pci/acpi.c $(obj)/acpi.c -$(obj)/pci.h: - @ln -sf ../../i386/pci/pci.h $(obj)/pci.h -$(obj)/irq.c: $(obj)/pci.h - @ln -sf ../../i386/pci/irq.c $(obj)/irq.c -$(obj)/fixup.c: $(obj)/pci.h - @ln -sf ../../i386/pci/fixup.c $(obj)/fixup.c -$(obj)/i386.c: $(obj)/pci.h - @ln -sf ../../i386/pci/i386.c $(obj)/i386.c - -clean-files += i386.c legacy.c fixup.c acpi.c irq.c pci.h common.c direct.c +direct-y += ../../i386/pci/direct.o +acpi-y += ../../i386/pci/acpi.o +legacy-y += ../../i386/pci/legacy.o +irq-y += ../../i386/pci/irq.o +common-y += ../../i386/pci/common.o +fixup-y += ../../i386/pci/fixup.o +i386-y += ../../i386/pci/i386.o diff -Nru a/arch/x86_64/pci/mmconfig.c b/arch/x86_64/pci/mmconfig.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/x86_64/pci/mmconfig.c Sun Mar 14 14:20:09 2004 @@ -0,0 +1,98 @@ +/* + * mmconfig.c - Low-level direct PCI config space access via MMCONFIG + * + * This is an 64bit optimized version that always keeps the full mmconfig + * space mapped. This allows lockless config space operation. + */ + +#include +#include +#include "pci.h" + +#define MMCONFIG_APER_SIZE (256*1024*1024) + +/* The physical address of the MMCONFIG aperture. Set from ACPI tables. */ +u32 pci_mmcfg_base_addr; + +/* Static virtual mapping of the MMCONFIG aperture */ +char *pci_mmcfg_virt; + +static inline char *pci_dev_base(int bus, int devfn) +{ + return pci_mmcfg_virt + ((bus << 20) | (devfn << 12)); +} + +static int pci_mmcfg_read(int seg, int bus, int devfn, int reg, int len, u32 *value) +{ + char *addr = pci_dev_base(bus, devfn); + + if (unlikely(!value || (bus > 255) || (devfn > 255) || (reg > 4095))) + return -EINVAL; + + switch (len) { + case 1: + *value = readb(addr + reg); + break; + case 2: + *value = readw(addr + reg); + break; + case 4: + *value = readl(addr + reg); + break; + } + + return 0; +} + +static int pci_mmcfg_write(int seg, int bus, int devfn, int reg, int len, u32 value) +{ + char *addr = pci_dev_base(bus,devfn); + + if (unlikely((bus > 255) || (devfn > 255) || (reg > 4095))) + return -EINVAL; + + switch (len) { + case 1: + writeb(value, addr + reg); + break; + case 2: + writew(value, addr + reg); + break; + case 4: + writel(value, addr + reg); + break; + } + + /* Dummy read to flush PCI write */ + readl(addr); + + return 0; +} + +static struct pci_raw_ops pci_mmcfg = { + .read = pci_mmcfg_read, + .write = pci_mmcfg_write, +}; + +static int __init pci_mmcfg_init(void) +{ + if ((pci_probe & PCI_PROBE_MMCONF) == 0) + return 0; + if (!pci_mmcfg_base_addr) + return 0; + + /* RED-PEN i386 doesn't do _nocache right now */ + pci_mmcfg_virt = ioremap_nocache(pci_mmcfg_base_addr, MMCONFIG_APER_SIZE); + if (!pci_mmcfg_virt) { + printk("PCI: Cannot map mmconfig aperture\n"); + return 0; + } + + printk(KERN_INFO "PCI: Using MMCONFIG at %lx\n", pci_mmcfg_base_addr); + raw_pci_ops = &pci_mmcfg; + pci_probe = (pci_probe & ~PCI_PROBE_MASK) | PCI_PROBE_MMCONF; + + return 0; +} + +arch_initcall(pci_mmcfg_init); diff -Nru a/drivers/acpi/dispatcher/dsmethod.c b/drivers/acpi/dispatcher/dsmethod.c --- a/drivers/acpi/dispatcher/dsmethod.c Sun Mar 14 14:20:07 2004 +++ b/drivers/acpi/dispatcher/dsmethod.c Sun Mar 14 14:20:07 2004 @@ -106,7 +106,7 @@ /* Create a mutex for the method if there is a concurrency limit */ - if ((obj_desc->method.concurrency != INFINITE_CONCURRENCY) && + if ((obj_desc->method.concurrency != ACPI_INFINITE_CONCURRENCY) && (!obj_desc->method.semaphore)) { status = acpi_os_create_semaphore (obj_desc->method.concurrency, obj_desc->method.concurrency, @@ -300,34 +300,37 @@ return_ACPI_STATUS (status); } - /* 1) Parse: Create a new walk state for the preempting walk */ + if (!(obj_desc->method.method_flags & AML_METHOD_INTERNAL_ONLY)) { + /* 1) Parse: Create a new walk state for the preempting walk */ - next_walk_state = acpi_ds_create_walk_state (obj_desc->method.owning_id, - op, obj_desc, NULL); - if (!next_walk_state) { - return_ACPI_STATUS (AE_NO_MEMORY); - } + next_walk_state = acpi_ds_create_walk_state (obj_desc->method.owning_id, + op, obj_desc, NULL); + if (!next_walk_state) { + return_ACPI_STATUS (AE_NO_MEMORY); + } - /* Create and init a Root Node */ - op = acpi_ps_create_scope_op (); - if (!op) { - status = AE_NO_MEMORY; - goto cleanup; - } + /* Create and init a Root Node */ - status = acpi_ds_init_aml_walk (next_walk_state, op, method_node, - obj_desc->method.aml_start, obj_desc->method.aml_length, - NULL, NULL, 1); - if (ACPI_FAILURE (status)) { - acpi_ds_delete_walk_state (next_walk_state); - goto cleanup; - } + op = acpi_ps_create_scope_op (); + if (!op) { + status = AE_NO_MEMORY; + goto cleanup; + } + + status = acpi_ds_init_aml_walk (next_walk_state, op, method_node, + obj_desc->method.aml_start, obj_desc->method.aml_length, + NULL, NULL, 1); + if (ACPI_FAILURE (status)) { + acpi_ds_delete_walk_state (next_walk_state); + goto cleanup; + } - /* Begin AML parse */ + /* Begin AML parse */ - status = acpi_ps_parse_aml (next_walk_state); - acpi_ps_delete_parse_tree (op); + status = acpi_ps_parse_aml (next_walk_state); + acpi_ps_delete_parse_tree (op); + } /* 2) Execute: Create a new state for the preempting walk */ @@ -337,7 +340,6 @@ status = AE_NO_MEMORY; goto cleanup; } - /* * The resolved arguments were put on the previous walk state's operand * stack. Operands on the previous walk state stack always @@ -369,16 +371,25 @@ ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Starting nested execution, newstate=%p\n", next_walk_state)); + if (obj_desc->method.method_flags & AML_METHOD_INTERNAL_ONLY) { + status = obj_desc->method.implementation (next_walk_state); + return_ACPI_STATUS (status); + } + return_ACPI_STATUS (AE_OK); /* On error, we must delete the new walk state */ cleanup: + if (next_walk_state->method_desc) { + /* Decrement the thread count on the method parse tree */ + + next_walk_state->method_desc->method.thread_count--; + } (void) acpi_ds_terminate_control_method (next_walk_state); acpi_ds_delete_walk_state (next_walk_state); return_ACPI_STATUS (status); - } @@ -500,10 +511,30 @@ } } - /* Decrement the thread count on the method parse tree */ + if (walk_state->method_desc->method.thread_count) { + ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, + "*** Not deleting method namespace, there are still %d threads\n", + walk_state->method_desc->method.thread_count)); + } - walk_state->method_desc->method.thread_count--; if (!walk_state->method_desc->method.thread_count) { + /* + * Support to dynamically change a method from not_serialized to + * Serialized if it appears that the method is written foolishly and + * does not support multiple thread execution. The best example of this + * is if such a method creates namespace objects and blocks. A second + * thread will fail with an AE_ALREADY_EXISTS exception + * + * This code is here because we must wait until the last thread exits + * before creating the synchronization semaphore. + */ + if ((walk_state->method_desc->method.concurrency == 1) && + (!walk_state->method_desc->method.semaphore)) { + status = acpi_os_create_semaphore (1, + 1, + &walk_state->method_desc->method.semaphore); + } + /* * There are no more threads executing this method. Perform * additional cleanup. diff -Nru a/drivers/acpi/events/evgpe.c b/drivers/acpi/events/evgpe.c --- a/drivers/acpi/events/evgpe.c Sun Mar 14 14:20:07 2004 +++ b/drivers/acpi/events/evgpe.c Sun Mar 14 14:20:07 2004 @@ -149,6 +149,11 @@ ACPI_FUNCTION_NAME ("ev_gpe_detect"); + /* Check for the case where there are no GPEs */ + + if (!gpe_xrupt_list) { + return (int_status); + } /* Examine all GPE blocks attached to this interrupt level */ diff -Nru a/drivers/acpi/executer/excreate.c b/drivers/acpi/executer/excreate.c --- a/drivers/acpi/executer/excreate.c Sun Mar 14 14:20:08 2004 +++ b/drivers/acpi/executer/excreate.c Sun Mar 14 14:20:08 2004 @@ -587,27 +587,33 @@ obj_desc->method.aml_start = aml_start; obj_desc->method.aml_length = aml_length; - /* disassemble the method flags */ - + /* + * Disassemble the method flags. Split off the Arg Count + * for efficiency + */ method_flags = (u8) operand[1]->integer.value; - obj_desc->method.method_flags = method_flags; - obj_desc->method.param_count = (u8) (method_flags & METHOD_FLAGS_ARG_COUNT); + obj_desc->method.method_flags = (u8) (method_flags & ~AML_METHOD_ARG_COUNT); + obj_desc->method.param_count = (u8) (method_flags & AML_METHOD_ARG_COUNT); /* * Get the concurrency count. If required, a semaphore will be * created for this method when it is parsed. */ - if (method_flags & METHOD_FLAGS_SERIALIZED) { + if (acpi_gbl_all_methods_serialized) { + obj_desc->method.concurrency = 1; + obj_desc->method.method_flags |= AML_METHOD_SERIALIZED; + } + else if (method_flags & AML_METHOD_SERIALIZED) { /* * ACPI 1.0: Concurrency = 1 * ACPI 2.0: Concurrency = (sync_level (in method declaration) + 1) */ obj_desc->method.concurrency = (u8) - (((method_flags & METHOD_FLAGS_SYNCH_LEVEL) >> 4) + 1); + (((method_flags & AML_METHOD_SYNCH_LEVEL) >> 4) + 1); } else { - obj_desc->method.concurrency = INFINITE_CONCURRENCY; + obj_desc->method.concurrency = ACPI_INFINITE_CONCURRENCY; } /* Attach the new object to the method Node */ diff -Nru a/drivers/acpi/executer/exmutex.c b/drivers/acpi/executer/exmutex.c --- a/drivers/acpi/executer/exmutex.c Sun Mar 14 14:20:08 2004 +++ b/drivers/acpi/executer/exmutex.c Sun Mar 14 14:20:08 2004 @@ -176,15 +176,18 @@ /* * Support for multiple acquires by the owning thread */ + if (obj_desc->mutex.owner_thread) { + /* Special case for Global Lock, allow all threads */ - if ((obj_desc->mutex.owner_thread) && - (obj_desc->mutex.owner_thread->thread_id == walk_state->thread->thread_id)) { - /* - * The mutex is already owned by this thread, - * just increment the acquisition depth - */ - obj_desc->mutex.acquisition_depth++; - return_ACPI_STATUS (AE_OK); + if ((obj_desc->mutex.owner_thread->thread_id == walk_state->thread->thread_id) || + (obj_desc->mutex.semaphore == acpi_gbl_global_lock_semaphore)) { + /* + * The mutex is already owned by this thread, + * just increment the acquisition depth + */ + obj_desc->mutex.acquisition_depth++; + return_ACPI_STATUS (AE_OK); + } } /* Acquire the mutex, wait if necessary */ @@ -254,9 +257,12 @@ return_ACPI_STATUS (AE_AML_INTERNAL); } - /* The Mutex is owned, but this thread must be the owner */ - - if (obj_desc->mutex.owner_thread->thread_id != walk_state->thread->thread_id) { + /* + * The Mutex is owned, but this thread must be the owner. + * Special case for Global Lock, any thread can release + */ + if ((obj_desc->mutex.owner_thread->thread_id != walk_state->thread->thread_id) && + (obj_desc->mutex.semaphore != acpi_gbl_global_lock_semaphore)) { ACPI_REPORT_ERROR (( "Thread %X cannot release Mutex [%4.4s] acquired by thread %X\n", walk_state->thread->thread_id, diff -Nru a/drivers/acpi/hardware/hwsleep.c b/drivers/acpi/hardware/hwsleep.c --- a/drivers/acpi/hardware/hwsleep.c Sun Mar 14 14:20:06 2004 +++ b/drivers/acpi/hardware/hwsleep.c Sun Mar 14 14:20:06 2004 @@ -394,7 +394,7 @@ * ******************************************************************************/ -acpi_status +acpi_status asmlinkage acpi_enter_sleep_state_s4bios ( void) { diff -Nru a/drivers/acpi/namespace/nsaccess.c b/drivers/acpi/namespace/nsaccess.c --- a/drivers/acpi/namespace/nsaccess.c Sun Mar 14 14:20:08 2004 +++ b/drivers/acpi/namespace/nsaccess.c Sun Mar 14 14:20:08 2004 @@ -105,8 +105,15 @@ "Entering predefined entries into namespace\n")); for (init_val = acpi_gbl_pre_defined_names; init_val->name; init_val++) { + /* _OSI is optional for now, will be permanent later */ + + if (!ACPI_STRCMP (init_val->name, "_OSI") && !acpi_gbl_create_osi_method) { + continue; + } + status = acpi_ns_lookup (NULL, init_val->name, init_val->type, - ACPI_IMODE_LOAD_PASS2, ACPI_NS_NO_UPSEARCH, NULL, &new_node); + ACPI_IMODE_LOAD_PASS2, ACPI_NS_NO_UPSEARCH, + NULL, &new_node); if (ACPI_FAILURE (status) || (!new_node)) /* Must be on same line for code converter */ { ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, @@ -122,7 +129,8 @@ if (init_val->val) { status = acpi_os_predefined_override (init_val, &val); if (ACPI_FAILURE (status)) { - ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Could not override predefined %s\n", + ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, + "Could not override predefined %s\n", init_val->name)); } @@ -147,15 +155,20 @@ */ switch (init_val->type) { case ACPI_TYPE_METHOD: - obj_desc->method.param_count = - (u8) ACPI_STRTOUL (val, NULL, 10); + obj_desc->method.param_count = (u8) ACPI_STRTOUL + (val, NULL, 10); obj_desc->common.flags |= AOPOBJ_DATA_VALID; -#if defined (ACPI_NO_METHOD_EXECUTION) || defined (ACPI_CONSTANT_EVAL_ONLY) +#if defined (_ACPI_ASL_COMPILER) || defined (_ACPI_DUMP_App) - /* Compiler cheats by putting parameter count in the owner_iD */ + /* i_aSL Compiler cheats by putting parameter count in the owner_iD */ new_node->owner_id = obj_desc->method.param_count; +#else + /* Mark this as a very SPECIAL method */ + + obj_desc->method.method_flags = AML_METHOD_INTERNAL_ONLY; + obj_desc->method.implementation = acpi_ut_osi_implementation; #endif break; @@ -180,8 +193,8 @@ case ACPI_TYPE_MUTEX: obj_desc->mutex.node = new_node; - obj_desc->mutex.sync_level = - (u16) ACPI_STRTOUL (val, NULL, 10); + obj_desc->mutex.sync_level = (u16) ACPI_STRTOUL + (val, NULL, 10); if (ACPI_STRCMP (init_val->name, "_GL_") == 0) { /* @@ -213,6 +226,7 @@ default: + ACPI_REPORT_ERROR (("Unsupported initial type value %X\n", init_val->type)); acpi_ut_remove_reference (obj_desc); diff -Nru a/drivers/acpi/namespace/nsalloc.c b/drivers/acpi/namespace/nsalloc.c --- a/drivers/acpi/namespace/nsalloc.c Sun Mar 14 14:20:07 2004 +++ b/drivers/acpi/namespace/nsalloc.c Sun Mar 14 14:20:07 2004 @@ -334,10 +334,11 @@ node->owner_id = owner_id; node->type = (u8) type; - ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, "%4.4s (%s) added to %4.4s (%s) %p at %p\n", - acpi_ut_get_node_name (node), acpi_ut_get_type_name (node->type), + ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, + "%4.4s (%s) [Node %p Owner %X] added to %4.4s (%s) [Node %p]\n", + acpi_ut_get_node_name (node), acpi_ut_get_type_name (node->type), node, owner_id, acpi_ut_get_node_name (parent_node), acpi_ut_get_type_name (parent_node->type), - parent_node, node)); + parent_node)); /* * Increment the reference count(s) of all parents up to diff -Nru a/drivers/acpi/namespace/nseval.c b/drivers/acpi/namespace/nseval.c --- a/drivers/acpi/namespace/nseval.c Sun Mar 14 14:20:07 2004 +++ b/drivers/acpi/namespace/nseval.c Sun Mar 14 14:20:07 2004 @@ -82,11 +82,11 @@ union acpi_operand_object **params, union acpi_operand_object **return_object) { - struct acpi_namespace_node *prefix_node; acpi_status status; + struct acpi_namespace_node *prefix_node; struct acpi_namespace_node *node = NULL; + union acpi_generic_state *scope_info; char *internal_path = NULL; - union acpi_generic_state scope_info; ACPI_FUNCTION_TRACE ("ns_evaluate_relative"); @@ -106,6 +106,11 @@ return_ACPI_STATUS (status); } + scope_info = acpi_ut_create_generic_state (); + if (!scope_info) { + goto cleanup1; + } + /* Get the prefix handle and Node */ status = acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE); @@ -122,8 +127,8 @@ /* Lookup the name in the namespace */ - scope_info.scope.node = prefix_node; - status = acpi_ns_lookup (&scope_info, internal_path, ACPI_TYPE_ANY, + scope_info->scope.node = prefix_node; + status = acpi_ns_lookup (scope_info, internal_path, ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE, ACPI_NS_NO_UPSEARCH, NULL, &node); @@ -148,7 +153,9 @@ pathname)); cleanup: + acpi_ut_delete_generic_state (scope_info); +cleanup1: ACPI_MEM_FREE (internal_path); return_ACPI_STATUS (status); } diff -Nru a/drivers/acpi/osl.c b/drivers/acpi/osl.c --- a/drivers/acpi/osl.c Sun Mar 14 14:20:08 2004 +++ b/drivers/acpi/osl.c Sun Mar 14 14:20:08 2004 @@ -1012,3 +1012,39 @@ } __setup("acpi_os_name=", acpi_os_name_setup); + +/* + * _OSI control + * empty string disables _OSI + * TBD additional string adds to _OSI + */ +int __init +acpi_osi_setup(char *str) +{ + if (str == NULL || *str == '\0') { + printk(KERN_INFO PREFIX "_OSI method disabled\n"); + acpi_gbl_create_osi_method = FALSE; + } else + { + /* TBD */ + printk(KERN_ERR PREFIX "_OSI additional string ignored -- %s\n", str); + } + + return 1; +} + +__setup("acpi_osi=", acpi_osi_setup); + +/* enable serialization to combat AE_ALREADY_EXISTS errors */ +int __init +acpi_serialize_setup(char *str) +{ + printk(KERN_INFO PREFIX "serialize enabled\n"); + + acpi_gbl_all_methods_serialized = TRUE; + + return 1; +} + +__setup("acpi_serialize", acpi_serialize_setup); + diff -Nru a/drivers/acpi/parser/psparse.c b/drivers/acpi/parser/psparse.c --- a/drivers/acpi/parser/psparse.c Sun Mar 14 14:20:06 2004 +++ b/drivers/acpi/parser/psparse.c Sun Mar 14 14:20:06 2004 @@ -426,7 +426,7 @@ acpi_status status = AE_OK; union acpi_parse_object *op = NULL; /* current op */ union acpi_parse_object *arg = NULL; - union acpi_parse_object pre_op; + union acpi_parse_object *pre_op = NULL; struct acpi_parse_state *parser_state; u8 *aml_op_start = NULL; @@ -547,8 +547,17 @@ /* Create Op structure and append to parent's argument list */ if (walk_state->op_info->flags & AML_NAMED) { - pre_op.common.value.arg = NULL; - pre_op.common.aml_opcode = walk_state->opcode; + /* Allocate a new pre_op if necessary */ + + if (!pre_op) { + pre_op = acpi_ps_alloc_op (walk_state->opcode); + if (!pre_op) { + return_ACPI_STATUS (AE_NO_MEMORY); + } + } + + pre_op->common.value.arg = NULL; + pre_op->common.aml_opcode = walk_state->opcode; /* * Get and append arguments until we find the node that contains @@ -562,7 +571,7 @@ goto close_this_op; } - acpi_ps_append_arg (&pre_op, arg); + acpi_ps_append_arg (pre_op, arg); INCREMENT_ARG_LIST (walk_state->arg_types); } @@ -603,7 +612,7 @@ goto close_this_op; } - acpi_ps_append_arg (op, pre_op.common.value.arg); + acpi_ps_append_arg (op, pre_op->common.value.arg); acpi_gbl_depth++; if (op->common.aml_opcode == AML_REGION_OP) { @@ -854,6 +863,10 @@ acpi_ps_complete_this_op (walk_state, op); op = NULL; + if (pre_op) { + acpi_ps_free_op (pre_op); + pre_op = NULL; + } switch (status) { case AE_OK: @@ -1118,6 +1131,27 @@ else if (status != AE_OK) { ACPI_REPORT_METHOD_ERROR ("Method execution failed", walk_state->method_node, NULL, status); + + /* Check for possible multi-thread reentrancy problem */ + + if ((status == AE_ALREADY_EXISTS) && + (!walk_state->method_desc->method.semaphore)) { + /* + * This method is marked not_serialized, but it tried to create a named + * object, causing the second thread entrance to fail. We will workaround + * this by marking the method permanently as Serialized. + */ + walk_state->method_desc->method.method_flags |= AML_METHOD_SERIALIZED; + walk_state->method_desc->method.concurrency = 1; + } + } + + if (walk_state->method_desc) { + /* Decrement the thread count on the method parse tree */ + + if (walk_state->method_desc->method.thread_count) { + walk_state->method_desc->method.thread_count--; + } } /* We are done with this walk, move on to the parent if any */ diff -Nru a/drivers/acpi/parser/psscope.c b/drivers/acpi/parser/psscope.c --- a/drivers/acpi/parser/psscope.c Sun Mar 14 14:20:06 2004 +++ b/drivers/acpi/parser/psscope.c Sun Mar 14 14:20:06 2004 @@ -167,7 +167,6 @@ return_ACPI_STATUS (AE_NO_MEMORY); } - scope->common.data_type = ACPI_DESC_TYPE_STATE_PSCOPE; scope->parse_scope.op = op; scope->parse_scope.arg_list = remaining_args; @@ -178,13 +177,11 @@ acpi_ut_push_generic_state (&parser_state->scope, scope); - if (arg_count == ACPI_VAR_ARGS) { /* multiple arguments */ scope->parse_scope.arg_end = parser_state->pkg_end; } - else { /* single argument */ @@ -241,7 +238,6 @@ acpi_ut_delete_generic_state (scope); } - else { /* empty parse stack, prepare to fetch next opcode */ @@ -250,7 +246,6 @@ *arg_count = 0; } - ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "Popped Op %p Args %X\n", *op, *arg_count)); return_VOID; } @@ -275,13 +270,13 @@ { union acpi_generic_state *scope; + ACPI_FUNCTION_TRACE_PTR ("ps_cleanup_scope", parser_state); if (!parser_state) { - return; + return_VOID; } - /* Delete anything on the scope stack */ diff -Nru a/drivers/acpi/power.c b/drivers/acpi/power.c --- a/drivers/acpi/power.c Sun Mar 14 14:20:07 2004 +++ b/drivers/acpi/power.c Sun Mar 14 14:20:07 2004 @@ -23,6 +23,18 @@ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ +/* + * ACPI power-managed devices may be controlled in two ways: + * 1. via "Device Specific (D-State) Control" + * 2. via "Power Resource Control". + * This module is used to manage devices relying on Power Resource Control. + * + * An ACPI "power resource object" describes a software controllable power + * plane, clock plane, or other resource used by a power managed device. + * A device may rely on multiple power resources, and a power resource + * may be shared by multiple devices. + */ + #include #include #include diff -Nru a/drivers/acpi/sleep/poweroff.c b/drivers/acpi/sleep/poweroff.c --- a/drivers/acpi/sleep/poweroff.c Sun Mar 14 14:20:08 2004 +++ b/drivers/acpi/sleep/poweroff.c Sun Mar 14 14:20:08 2004 @@ -8,11 +8,14 @@ #include #include #include +#include static void acpi_power_off (void) { printk("%s called\n",__FUNCTION__); + /* Some SMP machines only can poweroff in boot CPU */ + set_cpus_allowed(current, cpumask_of_cpu(0)); acpi_enter_sleep_state_prep(ACPI_STATE_S5); ACPI_DISABLE_IRQS(); acpi_enter_sleep_state(ACPI_STATE_S5); diff -Nru a/drivers/acpi/tables.c b/drivers/acpi/tables.c --- a/drivers/acpi/tables.c Sun Mar 14 14:20:07 2004 +++ b/drivers/acpi/tables.c Sun Mar 14 14:20:07 2004 @@ -386,8 +386,13 @@ for (i = 0; i < sdt_count; i++) { if (sdt_entry[i].id != id) continue; - handler(sdt_entry[i].pa, sdt_entry[i].size); count++; + if (count == 1) + handler(sdt_entry[i].pa, sdt_entry[i].size); + + else + printk(KERN_WARNING PREFIX "%d duplicate %s table ignored.\n", + count, acpi_table_signatures[id]); } return count; diff -Nru a/drivers/acpi/utilities/uteval.c b/drivers/acpi/utilities/uteval.c --- a/drivers/acpi/utilities/uteval.c Sun Mar 14 14:20:06 2004 +++ b/drivers/acpi/utilities/uteval.c Sun Mar 14 14:20:06 2004 @@ -53,6 +53,62 @@ /******************************************************************************* * + * FUNCTION: acpi_ut_osi_implementation + * + * PARAMETERS: walk_state - Current walk state + * + * RETURN: Status + * + * DESCRIPTION: Implementation of _OSI predefined control method + * Supported = _OSI (String) + * + ******************************************************************************/ + +acpi_status +acpi_ut_osi_implementation ( + struct acpi_walk_state *walk_state) +{ + union acpi_operand_object *string_desc; + union acpi_operand_object *return_desc; + acpi_native_uint i; + + + ACPI_FUNCTION_TRACE ("ut_osi_implementation"); + + + /* Validate the string input argument */ + + string_desc = walk_state->arguments[0].object; + if (!string_desc || (string_desc->common.type != ACPI_TYPE_STRING)) { + return_ACPI_STATUS (AE_TYPE); + } + + /* Create a return object (Default value = 0) */ + + return_desc = acpi_ut_create_internal_object (ACPI_TYPE_INTEGER); + if (!return_desc) { + return_ACPI_STATUS (AE_NO_MEMORY); + } + + /* Compare input string to table of supported strings */ + + for (i = 0; i < ACPI_NUM_OSI_STRINGS; i++) { + if (!ACPI_STRCMP (string_desc->string.pointer, + (char *) acpi_gbl_valid_osi_strings[i])) { + /* This string is supported */ + + return_desc->integer.value = 0xFFFFFFFF; + break; + } + } + + walk_state->return_desc = return_desc; + return_ACPI_STATUS (AE_CTRL_TERMINATE); +} + + +/******************************************************************************* + * * FUNCTION: acpi_ut_evaluate_object * * PARAMETERS: prefix_node - Starting node diff -Nru a/drivers/acpi/utilities/utglobal.c b/drivers/acpi/utilities/utglobal.c --- a/drivers/acpi/utilities/utglobal.c Sun Mar 14 14:20:06 2004 +++ b/drivers/acpi/utilities/utglobal.c Sun Mar 14 14:20:06 2004 @@ -185,6 +185,15 @@ "_S3D", "_S4D"}; +/* Strings supported by the _OSI predefined (internal) method */ + +const char *acpi_gbl_valid_osi_strings[ACPI_NUM_OSI_STRINGS] = { + "Linux", + "Windows 2000", + "Windows 2001", + "Windows 2001.1"}; + + /****************************************************************************** * * Namespace globals @@ -195,14 +204,10 @@ /* * Predefined ACPI Names (Built-in to the Interpreter) * - * Initial values are currently supported only for types String and Number. - * Both are specified as strings in this table. - * * NOTES: - * 1) _SB_ is defined to be a device to allow _SB_/_INI to be run + * 1) _SB_ is defined to be a device to allow \_SB_._INI to be run * during the initialization sequence. */ - const struct acpi_predefined_names acpi_gbl_pre_defined_names[] = { {"_GPE", ACPI_TYPE_LOCAL_SCOPE, NULL}, {"_PR_", ACPI_TYPE_LOCAL_SCOPE, NULL}, @@ -213,7 +218,7 @@ {"_OS_", ACPI_TYPE_STRING, ACPI_OS_NAME}, {"_GL_", ACPI_TYPE_MUTEX, "0"}, -#if defined (ACPI_NO_METHOD_EXECUTION) || defined (ACPI_CONSTANT_EVAL_ONLY) +#if !defined (ACPI_NO_METHOD_EXECUTION) || defined (ACPI_CONSTANT_EVAL_ONLY) {"_OSI", ACPI_TYPE_METHOD, "1"}, #endif {NULL, ACPI_TYPE_ANY, NULL} /* Table terminator */ @@ -224,7 +229,6 @@ * Properties of the ACPI Object Types, both internal and external. * The table is indexed by values of acpi_object_type */ - const u8 acpi_gbl_ns_properties[] = { ACPI_NS_NORMAL, /* 00 Any */ @@ -303,10 +307,8 @@ * ******************************************************************************/ - struct acpi_table_list acpi_gbl_table_lists[NUM_ACPI_TABLE_TYPES]; - struct acpi_table_support acpi_gbl_table_data[NUM_ACPI_TABLE_TYPES] = { /*********** Name, Signature, Global typed pointer Signature size, Type How many allowed?, Contains valid AML? */ @@ -470,9 +472,8 @@ * * The type ACPI_TYPE_ANY (Untyped) is used as a "don't care" when searching; when * stored in a table it really means that we have thus far seen no evidence to - * indicatewhat type is actually going to be stored for this entry. + * indicate what type is actually going to be stored for this entry. */ - static const char acpi_gbl_bad_type[] = "UNDEFINED"; #define TYPE_NAME_LENGTH 12 /* Maximum length of each string */ @@ -776,6 +777,11 @@ ACPI_FUNCTION_TRACE ("ut_init_globals"); + + /* Runtime configuration */ + + acpi_gbl_create_osi_method = TRUE; + acpi_gbl_all_methods_serialized = FALSE; /* Memory allocation and cache lists */ diff -Nru a/drivers/atm/fore200e.c b/drivers/atm/fore200e.c --- a/drivers/atm/fore200e.c Sun Mar 14 14:20:08 2004 +++ b/drivers/atm/fore200e.c Sun Mar 14 14:20:08 2004 @@ -482,11 +482,19 @@ static void -fore200e_pca_dma_sync(struct fore200e* fore200e, u32 dma_addr, int size, int direction) +fore200e_pca_dma_sync_for_cpu(struct fore200e* fore200e, u32 dma_addr, int size, int direction) { DPRINTK(3, "PCI DVMA sync: dma_addr = 0x%08x, size = %d, direction = %d\n", dma_addr, size, direction); - pci_dma_sync_single((struct pci_dev*)fore200e->bus_dev, dma_addr, size, direction); + pci_dma_sync_single_for_cpu((struct pci_dev*)fore200e->bus_dev, dma_addr, size, direction); +} + +static void +fore200e_pca_dma_sync_for_device(struct fore200e* fore200e, u32 dma_addr, int size, int direction) +{ + DPRINTK(3, "PCI DVMA sync: dma_addr = 0x%08x, size = %d, direction = %d\n", dma_addr, size, direction); + + pci_dma_sync_single_for_device((struct pci_dev*)fore200e->bus_dev, dma_addr, size, direction); } @@ -761,11 +769,19 @@ static void -fore200e_sba_dma_sync(struct fore200e* fore200e, u32 dma_addr, int size, int direction) +fore200e_sba_dma_sync_for_cpu(struct fore200e* fore200e, u32 dma_addr, int size, int direction) { DPRINTK(3, "SBUS DVMA sync: dma_addr = 0x%08x, size = %d, direction = %d\n", dma_addr, size, direction); - sbus_dma_sync_single((struct sbus_dev*)fore200e->bus_dev, dma_addr, size, direction); + sbus_dma_sync_single_for_cpu((struct sbus_dev*)fore200e->bus_dev, dma_addr, size, direction); +} + +static void +fore200e_sba_dma_sync_for_device(struct fore200e* fore200e, u32 dma_addr, int size, int direction) +{ + DPRINTK(3, "SBUS DVMA sync: dma_addr = 0x%08x, size = %d, direction = %d\n", dma_addr, size, direction); + + sbus_dma_sync_single_for_device((struct sbus_dev*)fore200e->bus_dev, dma_addr, size, direction); } @@ -1149,10 +1165,13 @@ /* rebuild rx buffer address from rsd handle */ buffer = FORE200E_HDL2BUF(rpd->rsd[ i ].handle); - /* ensure DMA synchronisation */ - fore200e->bus->dma_sync(fore200e, buffer->data.dma_addr, rpd->rsd[ i ].length, FORE200E_DMA_FROMDEVICE); + /* Make device DMA transfer visible to CPU. */ + fore200e->bus->dma_sync_for_cpu(fore200e, buffer->data.dma_addr, rpd->rsd[ i ].length, FORE200E_DMA_FROMDEVICE); memcpy(skb_put(skb, rpd->rsd[ i ].length), buffer->data.align_addr, rpd->rsd[ i ].length); + + /* Now let the device get at it again. */ + fore200e->bus->dma_sync_for_device(fore200e, buffer->data.dma_addr, rpd->rsd[ i ].length, FORE200E_DMA_FROMDEVICE); } DPRINTK(3, "rx skb: len = %d, truesize = %d\n", skb->len, skb->truesize); @@ -1584,8 +1603,9 @@ tasklet_enable(&fore200e->tasklet); - /* ensure DMA synchronisation */ - fore200e->bus->dma_sync(fore200e, tpd->tsd[ 0 ].buffer, tpd->tsd[ 0 ].length, FORE200E_DMA_TODEVICE); + /* The dma_map call above implies a dma_sync so the device can use it, + * thus no explicit dma_sync call is necessary here. + */ DPRINTK(3, "tx on %d.%d.%d:%d, len = %u (%u)\n", vcc->itf, vcc->vpi, vcc->vci, fore200e_atm2fore_aal(vcc->qos.aal), @@ -2918,7 +2938,8 @@ fore200e_pca_write, fore200e_pca_dma_map, fore200e_pca_dma_unmap, - fore200e_pca_dma_sync, + fore200e_pca_dma_sync_for_cpu, + fore200e_pca_dma_sync_for_device, fore200e_pca_dma_chunk_alloc, fore200e_pca_dma_chunk_free, fore200e_pca_detect, @@ -2940,7 +2961,8 @@ fore200e_sba_write, fore200e_sba_dma_map, fore200e_sba_dma_unmap, - fore200e_sba_dma_sync, + fore200e_sba_dma_sync_for_cpu, + fore200e_sba_dma_sync_for_device, fore200e_sba_dma_chunk_alloc, fore200e_sba_dma_chunk_free, fore200e_sba_detect, diff -Nru a/drivers/atm/fore200e.h b/drivers/atm/fore200e.h --- a/drivers/atm/fore200e.h Sun Mar 14 14:20:07 2004 +++ b/drivers/atm/fore200e.h Sun Mar 14 14:20:07 2004 @@ -801,7 +801,8 @@ void (*write)(u32, volatile u32*); u32 (*dma_map)(struct fore200e*, void*, int, int); void (*dma_unmap)(struct fore200e*, u32, int, int); - void (*dma_sync)(struct fore200e*, u32, int, int); + void (*dma_sync_for_cpu)(struct fore200e*, u32, int, int); + void (*dma_sync_for_device)(struct fore200e*, u32, int, int); int (*dma_chunk_alloc)(struct fore200e*, struct chunk*, int, int, int); void (*dma_chunk_free)(struct fore200e*, struct chunk*); struct fore200e* (*detect)(const struct fore200e_bus*, int); diff -Nru a/drivers/atm/idt77252.c b/drivers/atm/idt77252.c --- a/drivers/atm/idt77252.c Sun Mar 14 14:20:07 2004 +++ b/drivers/atm/idt77252.c Sun Mar 14 14:20:07 2004 @@ -1064,8 +1064,8 @@ vcc = vc->rx_vcc; - pci_dma_sync_single(card->pcidev, IDT77252_PRV_PADDR(skb), - skb->end - skb->data, PCI_DMA_FROMDEVICE); + pci_dma_sync_single_for_cpu(card->pcidev, IDT77252_PRV_PADDR(skb), + skb->end - skb->data, PCI_DMA_FROMDEVICE); if ((vcc->qos.aal == ATM_AAL0) || (vcc->qos.aal == ATM_AAL34)) { @@ -1902,6 +1902,9 @@ { u32 handle = IDT77252_PRV_POOL(skb); int err; + + pci_dma_sync_single_for_device(card->pcidev, IDT77252_PRV_PADDR(skb), + skb->end - skb->data, PCI_DMA_FROMDEVICE); err = push_rx_skb(card, skb, POOL_QUEUE(handle)); if (err) { diff -Nru a/drivers/base/map.c b/drivers/base/map.c --- a/drivers/base/map.c Sun Mar 14 14:20:07 2004 +++ b/drivers/base/map.c Sun Mar 14 14:20:07 2004 @@ -96,7 +96,7 @@ { struct kobject *kobj; struct probe *p; - unsigned best = ~0U; + unsigned long best = ~0UL; retry: down_read(domain->sem); diff -Nru a/drivers/block/Kconfig b/drivers/block/Kconfig --- a/drivers/block/Kconfig Sun Mar 14 14:20:06 2004 +++ b/drivers/block/Kconfig Sun Mar 14 14:20:06 2004 @@ -292,6 +292,15 @@ If unsure, say N. +config BLK_DEV_CARMEL + tristate "Promise SATA SX8 (carmel) support" + depends on PCI + ---help--- + Saying Y or M here will enable support for the + Promise SATA SX8 ("carmel") controllers. + + Use devices /dev/carmel/$N and /dev/carmel/$Np$M. + config BLK_DEV_RAM tristate "RAM disk support" ---help--- diff -Nru a/drivers/block/Makefile b/drivers/block/Makefile --- a/drivers/block/Makefile Sun Mar 14 14:20:08 2004 +++ b/drivers/block/Makefile Sun Mar 14 14:20:08 2004 @@ -40,3 +40,5 @@ obj-$(CONFIG_BLK_DEV_CRYPTOLOOP) += cryptoloop.o obj-$(CONFIG_VIODASD) += viodasd.o +obj-$(CONFIG_BLK_DEV_CARMEL) += carmel.o + diff -Nru a/drivers/block/carmel.c b/drivers/block/carmel.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/drivers/block/carmel.c Sun Mar 14 14:20:09 2004 @@ -0,0 +1,1731 @@ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +MODULE_AUTHOR("Jeff Garzik"); +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("Promise SX8 (carmel) block driver"); + +#if 0 +#define CARM_DEBUG +#define CARM_VERBOSE_DEBUG +#else +#undef CARM_DEBUG +#undef CARM_VERBOSE_DEBUG +#endif +#undef CARM_NDEBUG + +#define DRV_NAME "carmel" +#define DRV_VERSION "0.7" +#define PFX DRV_NAME ": " + +#define NEXT_RESP(idx) ((idx + 1) % RMSG_Q_LEN) + +/* 0xf is just arbitrary, non-zero noise; this is sorta like poisoning */ +#define TAG_ENCODE(tag) (((tag) << 16) | 0xf) +#define TAG_DECODE(tag) (((tag) >> 16) & 0x1f) +#define TAG_VALID(tag) ((((tag) & 0xf) == 0xf) && (TAG_DECODE(tag) < 32)) + +/* note: prints function name for you */ +#ifdef CARM_DEBUG +#define DPRINTK(fmt, args...) printk(KERN_ERR "%s: " fmt, __FUNCTION__, ## args) +#ifdef CARM_VERBOSE_DEBUG +#define VPRINTK(fmt, args...) printk(KERN_ERR "%s: " fmt, __FUNCTION__, ## args) +#else +#define VPRINTK(fmt, args...) +#endif /* CARM_VERBOSE_DEBUG */ +#else +#define DPRINTK(fmt, args...) +#define VPRINTK(fmt, args...) +#endif /* CARM_DEBUG */ + +#ifdef CARM_NDEBUG +#define assert(expr) +#else +#define assert(expr) \ + if(unlikely(!(expr))) { \ + printk(KERN_ERR "Assertion failed! %s,%s,%s,line=%d\n", \ + #expr,__FILE__,__FUNCTION__,__LINE__); \ + } +#endif + +/* defines only for the constants which don't work well as enums */ +struct carm_host; + +enum { + /* adapter-wide limits */ + CARM_MAX_PORTS = 8, + CARM_SHM_SIZE = (4096 << 7), + CARM_MINORS_PER_MAJOR = 256 / CARM_MAX_PORTS, + CARM_MAX_WAIT_Q = CARM_MAX_PORTS + 1, + + /* command message queue limits */ + CARM_MAX_REQ = 64, /* max command msgs per host */ + CARM_MAX_Q = 1, /* one command at a time */ + CARM_MSG_LOW_WATER = (CARM_MAX_REQ / 4), /* refill mark */ + + /* S/G limits, host-wide and per-request */ + CARM_MAX_REQ_SG = 32, /* max s/g entries per request */ + CARM_SG_BOUNDARY = 0xffffUL, /* s/g segment boundary */ + CARM_MAX_HOST_SG = 600, /* max s/g entries per host */ + CARM_SG_LOW_WATER = (CARM_MAX_HOST_SG / 4), /* re-fill mark */ + + /* hardware registers */ + CARM_IHQP = 0x1c, + CARM_INT_STAT = 0x10, /* interrupt status */ + CARM_INT_MASK = 0x14, /* interrupt mask */ + CARM_HMUC = 0x18, /* host message unit control */ + RBUF_ADDR_LO = 0x20, /* response msg DMA buf low 32 bits */ + RBUF_ADDR_HI = 0x24, /* response msg DMA buf high 32 bits */ + RBUF_BYTE_SZ = 0x28, + CARM_RESP_IDX = 0x2c, + CARM_CMS0 = 0x30, /* command message size reg 0 */ + CARM_LMUC = 0x48, + CARM_HMPHA = 0x6c, + CARM_INITC = 0xb5, + + /* bits in CARM_INT_{STAT,MASK} */ + INT_RESERVED = 0xfffffff0, + INT_WATCHDOG = (1 << 3), /* watchdog timer */ + INT_Q_OVERFLOW = (1 << 2), /* cmd msg q overflow */ + INT_Q_AVAILABLE = (1 << 1), /* cmd msg q has free space */ + INT_RESPONSE = (1 << 0), /* response msg available */ + INT_ACK_MASK = INT_WATCHDOG | INT_Q_OVERFLOW, + INT_DEF_MASK = INT_RESERVED | INT_Q_OVERFLOW | + INT_RESPONSE, + + /* command messages, and related register bits */ + CARM_HAVE_RESP = 0x01, + CARM_MSG_READ = 1, + CARM_MSG_WRITE = 2, + CARM_MSG_VERIFY = 3, + CARM_MSG_GET_CAPACITY = 4, + CARM_MSG_FLUSH = 5, + CARM_MSG_IOCTL = 6, + CARM_MSG_ARRAY = 8, + CARM_MSG_MISC = 9, + CARM_CME = (1 << 2), + CARM_RME = (1 << 1), + CARM_WZBC = (1 << 0), + CARM_RMI = (1 << 0), + CARM_Q_FULL = (1 << 3), + CARM_MSG_SIZE = 288, + CARM_Q_LEN = 48, + + /* CARM_MSG_IOCTL messages */ + CARM_IOC_SCAN_CHAN = 5, /* scan channels for devices */ + CARM_IOC_GET_TCQ = 13, /* get tcq/ncq depth */ + CARM_IOC_SET_TCQ = 14, /* set tcq/ncq depth */ + + IOC_SCAN_CHAN_NODEV = 0x1f, + IOC_SCAN_CHAN_OFFSET = 0x40, + + /* CARM_MSG_ARRAY messages */ + CARM_ARRAY_INFO = 0, + + ARRAY_NO_EXIST = (1 << 31), + + /* response messages */ + RMSG_SZ = 8, /* sizeof(struct carm_response) */ + RMSG_Q_LEN = 48, /* resp. msg list length */ + RMSG_OK = 1, /* bit indicating msg was successful */ + /* length of entire resp. msg buffer */ + RBUF_LEN = RMSG_SZ * RMSG_Q_LEN, + + PDC_SHM_SIZE = (4096 << 7), /* length of entire h/w buffer */ + + /* CARM_MSG_MISC messages */ + MISC_GET_FW_VER = 2, + MISC_ALLOC_MEM = 3, + MISC_SET_TIME = 5, + + /* MISC_GET_FW_VER feature bits */ + FW_VER_4PORT = (1 << 2), /* 1=4 ports, 0=8 ports */ + FW_VER_NON_RAID = (1 << 1), /* 1=non-RAID firmware, 0=RAID */ + FW_VER_ZCR = (1 << 0), /* zero channel RAID (whatever that is) */ + + /* carm_host flags */ + FL_DAC = (1 << 0), + FL_NON_RAID = FW_VER_NON_RAID, + FL_4PORT = FW_VER_4PORT, + FL_FW_VER_MASK = (FW_VER_NON_RAID | FW_VER_4PORT), +}; + +enum scatter_gather_types { + SGT_32BIT = 0, + SGT_64BIT = 1, +}; + +enum host_states { + HST_INVALID, /* invalid state; never used */ + HST_ALLOC_BUF, /* setting up master SHM area */ + HST_ERROR, /* we never leave here */ + HST_PORT_SCAN, /* start dev scan */ + HST_DEV_SCAN_START, /* start per-device probe */ + HST_DEV_SCAN, /* continue per-device probe */ + HST_DEV_ACTIVATE, /* activate devices we found */ + HST_PROBE_FINISHED, /* probe is complete */ + HST_PROBE_START, /* initiate probe */ + HST_SYNC_TIME, /* tell firmware what time it is */ + HST_GET_FW_VER, /* get firmware version, adapter port cnt */ +}; + +#ifdef CARM_DEBUG +static const char *state_name[] = { + "HST_INVALID", + "HST_ALLOC_BUF", + "HST_ERROR", + "HST_PORT_SCAN", + "HST_DEV_SCAN_START", + "HST_DEV_SCAN", + "HST_DEV_ACTIVATE", + "HST_PROBE_FINISHED", + "HST_PROBE_START", + "HST_SYNC_TIME", + "HST_GET_FW_VER", +}; +#endif + +struct carm_port { + unsigned int port_no; + unsigned int n_queued; + struct gendisk *disk; + struct carm_host *host; + + /* attached device characteristics */ + u64 capacity; + char name[41]; + u16 dev_geom_head; + u16 dev_geom_sect; + u16 dev_geom_cyl; +}; + +struct carm_request { + unsigned int tag; + int n_elem; + unsigned int msg_type; + unsigned int msg_subtype; + unsigned int msg_bucket; + struct request *rq; + struct carm_port *port; + struct scatterlist sg[CARM_MAX_REQ_SG]; +}; + +struct carm_host { + unsigned long flags; + void *mmio; + void *shm; + dma_addr_t shm_dma; + int major; + spinlock_t lock; + struct pci_dev *pdev; + unsigned int state; + u32 fw_ver; + + request_queue_t *oob_q; + unsigned int n_oob; + + unsigned int hw_sg_used; + + unsigned int resp_idx; + + unsigned int wait_q_prod; + unsigned int wait_q_cons; + request_queue_t *wait_q[CARM_MAX_WAIT_Q]; + + unsigned int n_msgs; + u64 msg_alloc; + struct carm_request req[CARM_MAX_REQ]; + void *msg_base; + dma_addr_t msg_dma; + + int cur_scan_dev; + unsigned long dev_active; + unsigned long dev_present; + struct carm_port port[CARM_MAX_PORTS]; + + struct work_struct fsm_task; + + struct semaphore probe_sem; +}; + +struct carm_response { + u32 ret_handle; + u32 status; +} __attribute__((packed)); + +struct carm_msg_sg { + u32 start; + u32 len; +} __attribute__((packed)); + +struct carm_msg_rw { + u8 type; + u8 id; + u8 sg_count; + u8 sg_type; + u32 handle; + u32 lba; + u16 lba_count; + u16 lba_high; + struct carm_msg_sg sg[32]; +} __attribute__((packed)); + +struct carm_msg_allocbuf { + u8 type; + u8 subtype; + u8 n_sg; + u8 sg_type; + u32 handle; + u32 addr; + u32 len; + u32 evt_pool; + u32 n_evt; + u32 rbuf_pool; + u32 n_rbuf; + u32 msg_pool; + u32 n_msg; + struct carm_msg_sg sg[8]; +} __attribute__((packed)); + +struct carm_msg_ioctl { + u8 type; + u8 subtype; + u8 array_id; + u8 reserved1; + u32 handle; + u32 data_addr; + u32 reserved2; +} __attribute__((packed)); + +struct carm_msg_sync_time { + u8 type; + u8 subtype; + u16 reserved1; + u32 handle; + u32 reserved2; + u32 timestamp; +} __attribute__((packed)); + +struct carm_msg_get_fw_ver { + u8 type; + u8 subtype; + u16 reserved1; + u32 handle; + u32 data_addr; + u32 reserved2; +} __attribute__((packed)); + +struct carm_fw_ver { + u32 version; + u8 features; + u8 reserved1; + u16 reserved2; +} __attribute__((packed)); + +struct carm_array_info { + u32 size; + + u16 size_hi; + u16 stripe_size; + + u32 mode; + + u16 stripe_blk_sz; + u16 reserved1; + + u16 cyl; + u16 head; + + u16 sect; + u8 array_id; + u8 reserved2; + + char name[40]; + + u32 array_status; + + /* device list continues beyond this point? */ +} __attribute__((packed)); + +static int carm_init_one (struct pci_dev *pdev, const struct pci_device_id *ent); +static void carm_remove_one (struct pci_dev *pdev); +static int carm_bdev_ioctl(struct inode *ino, struct file *fil, + unsigned int cmd, unsigned long arg); + +static struct pci_device_id carm_pci_tbl[] = { + { PCI_VENDOR_ID_PROMISE, 0x8000, PCI_ANY_ID, PCI_ANY_ID, 0, 0, }, + { PCI_VENDOR_ID_PROMISE, 0x8002, PCI_ANY_ID, PCI_ANY_ID, 0, 0, }, + { } /* terminate list */ +}; +MODULE_DEVICE_TABLE(pci, carm_pci_tbl); + +static struct pci_driver carm_driver = { + .name = DRV_NAME, + .id_table = carm_pci_tbl, + .probe = carm_init_one, + .remove = carm_remove_one, +}; + +static struct block_device_operations carm_bd_ops = { + .owner = THIS_MODULE, + .ioctl = carm_bdev_ioctl, +}; + +static unsigned int carm_host_id; + + + +static int carm_bdev_ioctl(struct inode *ino, struct file *fil, + unsigned int cmd, unsigned long arg) +{ + void __user *usermem = (void *) arg; + struct carm_port *port = ino->i_bdev->bd_disk->private_data; + struct hd_geometry geom; + + switch (cmd) { + case HDIO_GETGEO: + if (!usermem) + return -EINVAL; + + geom.heads = (u8) port->dev_geom_head; + geom.sectors = (u8) port->dev_geom_sect; + geom.cylinders = port->dev_geom_cyl; + geom.start = get_start_sect(ino->i_bdev); + + if (copy_to_user(usermem, &geom, sizeof(geom))) + return -EFAULT; + return 0; + + default: + break; + } + + return -EOPNOTSUPP; +} + +static inline unsigned long msecs_to_jiffies(unsigned long msecs) +{ + return ((HZ * msecs + 999) / 1000); +} + +static void msleep(unsigned long msecs) +{ + set_current_state(TASK_UNINTERRUPTIBLE); + schedule_timeout(msecs_to_jiffies(msecs)); +} + +static const u32 msg_sizes[] = { 32, 64, 128, CARM_MSG_SIZE }; + +static inline int carm_lookup_bucket(u32 msg_size) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(msg_sizes); i++) + if (msg_size <= msg_sizes[i]) + return i; + + return -ENOENT; +} + +static void carm_init_buckets(void *mmio) +{ + unsigned int i; + + for (i = 0; i < ARRAY_SIZE(msg_sizes); i++) + writel(msg_sizes[i], mmio + CARM_CMS0 + (4 * i)); +} + +static inline void *carm_ref_msg(struct carm_host *host, + unsigned int msg_idx) +{ + return host->msg_base + (msg_idx * CARM_MSG_SIZE); +} + +static inline dma_addr_t carm_ref_msg_dma(struct carm_host *host, + unsigned int msg_idx) +{ + return host->msg_dma + (msg_idx * CARM_MSG_SIZE); +} + +static int carm_send_msg(struct carm_host *host, + struct carm_request *crq) +{ + void *mmio = host->mmio; + u32 msg = (u32) carm_ref_msg_dma(host, crq->tag); + u32 cm_bucket = crq->msg_bucket; + u32 tmp; + int rc = 0; + + VPRINTK("ENTER\n"); + + tmp = readl(mmio + CARM_HMUC); + if (tmp & CARM_Q_FULL) { +#if 0 + tmp = readl(mmio + CARM_INT_MASK); + tmp |= INT_Q_AVAILABLE; + writel(tmp, mmio + CARM_INT_MASK); + readl(mmio + CARM_INT_MASK); /* flush */ +#endif + DPRINTK("host msg queue full\n"); + rc = -EBUSY; + } else { + writel(msg | (cm_bucket << 1), mmio + CARM_IHQP); + readl(mmio + CARM_IHQP); /* flush */ + } + + return rc; +} + +static struct carm_request *carm_get_request(struct carm_host *host) +{ + unsigned int i; + + /* obey global hardware limit on S/G entries */ + if (host->hw_sg_used >= (CARM_MAX_HOST_SG - CARM_MAX_REQ_SG)) + return NULL; + + for (i = 0; i < CARM_MAX_Q; i++) + if ((host->msg_alloc & (1ULL << i)) == 0) { + struct carm_request *crq = &host->req[i]; + crq->port = NULL; + crq->n_elem = 0; + + host->msg_alloc |= (1ULL << i); + host->n_msgs++; + + assert(host->n_msgs <= CARM_MAX_REQ); + return crq; + } + + DPRINTK("no request available, returning NULL\n"); + return NULL; +} + +static int carm_put_request(struct carm_host *host, struct carm_request *crq) +{ + assert(crq->tag < CARM_MAX_Q); + + if (unlikely((host->msg_alloc & (1ULL << crq->tag)) == 0)) + return -EINVAL; /* tried to clear a tag that was not active */ + + assert(host->hw_sg_used >= crq->n_elem); + + host->msg_alloc &= ~(1ULL << crq->tag); + host->hw_sg_used -= crq->n_elem; + host->n_msgs--; + + return 0; +} + +static struct carm_request *carm_get_special(struct carm_host *host) +{ + unsigned long flags; + struct carm_request *crq = NULL; + struct request *rq; + int tries = 5000; + + while (tries-- > 0) { + spin_lock_irqsave(&host->lock, flags); + crq = carm_get_request(host); + spin_unlock_irqrestore(&host->lock, flags); + + if (crq) + break; + msleep(10); + } + + if (!crq) + return NULL; + + rq = blk_get_request(host->oob_q, WRITE /* bogus */, GFP_KERNEL); + if (!rq) { + spin_lock_irqsave(&host->lock, flags); + carm_put_request(host, crq); + spin_unlock_irqrestore(&host->lock, flags); + return NULL; + } + + crq->rq = rq; + return crq; +} + +static int carm_array_info (struct carm_host *host, unsigned int array_idx) +{ + struct carm_msg_ioctl *ioc; + unsigned int idx; + u32 msg_data; + dma_addr_t msg_dma; + struct carm_request *crq; + int rc; + + crq = carm_get_special(host); + if (!crq) { + rc = -ENOMEM; + goto err_out; + } + + idx = crq->tag; + + ioc = carm_ref_msg(host, idx); + msg_dma = carm_ref_msg_dma(host, idx); + msg_data = (u32) (msg_dma + sizeof(struct carm_array_info)); + + crq->msg_type = CARM_MSG_ARRAY; + crq->msg_subtype = CARM_ARRAY_INFO; + rc = carm_lookup_bucket(sizeof(struct carm_msg_ioctl) + + sizeof(struct carm_array_info)); + BUG_ON(rc < 0); + crq->msg_bucket = (u32) rc; + + memset(ioc, 0, sizeof(*ioc)); + ioc->type = CARM_MSG_ARRAY; + ioc->subtype = CARM_ARRAY_INFO; + ioc->array_id = (u8) array_idx; + ioc->handle = cpu_to_le32(TAG_ENCODE(idx)); + ioc->data_addr = cpu_to_le32(msg_data); + + spin_lock_irq(&host->lock); + assert(host->state == HST_DEV_SCAN_START || + host->state == HST_DEV_SCAN); + spin_unlock_irq(&host->lock); + + DPRINTK("blk_insert_request, tag == %u\n", idx); + blk_insert_request(host->oob_q, crq->rq, 1, crq, 0); + + return 0; + +err_out: + spin_lock_irq(&host->lock); + host->state = HST_ERROR; + spin_unlock_irq(&host->lock); + return rc; +} + +typedef unsigned int (*carm_sspc_t)(struct carm_host *, unsigned int, void *); + +static int carm_send_special (struct carm_host *host, carm_sspc_t func) +{ + struct carm_request *crq; + struct carm_msg_ioctl *ioc; + void *mem; + unsigned int idx, msg_size; + int rc; + + crq = carm_get_special(host); + if (!crq) + return -ENOMEM; + + idx = crq->tag; + + mem = carm_ref_msg(host, idx); + + msg_size = func(host, idx, mem); + + ioc = mem; + crq->msg_type = ioc->type; + crq->msg_subtype = ioc->subtype; + rc = carm_lookup_bucket(msg_size); + BUG_ON(rc < 0); + crq->msg_bucket = (u32) rc; + + DPRINTK("blk_insert_request, tag == %u\n", idx); + blk_insert_request(host->oob_q, crq->rq, 1, crq, 0); + + return 0; +} + +static unsigned int carm_fill_sync_time(struct carm_host *host, + unsigned int idx, void *mem) +{ + struct timeval tv; + struct carm_msg_sync_time *st = mem; + + do_gettimeofday(&tv); + + memset(st, 0, sizeof(*st)); + st->type = CARM_MSG_MISC; + st->subtype = MISC_SET_TIME; + st->handle = cpu_to_le32(TAG_ENCODE(idx)); + st->timestamp = cpu_to_le32(tv.tv_sec); + + return sizeof(struct carm_msg_sync_time); +} + +static unsigned int carm_fill_alloc_buf(struct carm_host *host, + unsigned int idx, void *mem) +{ + struct carm_msg_allocbuf *ab = mem; + + memset(ab, 0, sizeof(*ab)); + ab->type = CARM_MSG_MISC; + ab->subtype = MISC_ALLOC_MEM; + ab->handle = cpu_to_le32(TAG_ENCODE(idx)); + ab->n_sg = 1; + ab->sg_type = SGT_32BIT; + ab->addr = cpu_to_le32(host->shm_dma + (PDC_SHM_SIZE >> 1)); + ab->len = cpu_to_le32(PDC_SHM_SIZE >> 1); + ab->evt_pool = cpu_to_le32(host->shm_dma + (16 * 1024)); + ab->n_evt = cpu_to_le32(1024); + ab->rbuf_pool = cpu_to_le32(host->shm_dma); + ab->n_rbuf = cpu_to_le32(RMSG_Q_LEN); + ab->msg_pool = cpu_to_le32(host->shm_dma + RBUF_LEN); + ab->n_msg = cpu_to_le32(CARM_Q_LEN); + ab->sg[0].start = cpu_to_le32(host->shm_dma + (PDC_SHM_SIZE >> 1)); + ab->sg[0].len = cpu_to_le32(65536); + + return sizeof(struct carm_msg_allocbuf); +} + +static unsigned int carm_fill_scan_channels(struct carm_host *host, + unsigned int idx, void *mem) +{ + struct carm_msg_ioctl *ioc = mem; + u32 msg_data = (u32) (carm_ref_msg_dma(host, idx) + + IOC_SCAN_CHAN_OFFSET); + + memset(ioc, 0, sizeof(*ioc)); + ioc->type = CARM_MSG_IOCTL; + ioc->subtype = CARM_IOC_SCAN_CHAN; + ioc->handle = cpu_to_le32(TAG_ENCODE(idx)); + ioc->data_addr = cpu_to_le32(msg_data); + + /* fill output data area with "no device" default values */ + mem += IOC_SCAN_CHAN_OFFSET; + memset(mem, IOC_SCAN_CHAN_NODEV, CARM_MAX_PORTS); + + return IOC_SCAN_CHAN_OFFSET + CARM_MAX_PORTS; +} + +static unsigned int carm_fill_get_fw_ver(struct carm_host *host, + unsigned int idx, void *mem) +{ + struct carm_msg_get_fw_ver *ioc = mem; + u32 msg_data = (u32) (carm_ref_msg_dma(host, idx) + sizeof(*ioc)); + + memset(ioc, 0, sizeof(*ioc)); + ioc->type = CARM_MSG_MISC; + ioc->subtype = MISC_GET_FW_VER; + ioc->handle = cpu_to_le32(TAG_ENCODE(idx)); + ioc->data_addr = cpu_to_le32(msg_data); + + return sizeof(struct carm_msg_get_fw_ver) + + sizeof(struct carm_fw_ver); +} + +static inline void carm_end_request_queued(struct carm_host *host, + struct carm_request *crq, + int uptodate) +{ + struct request *req = crq->rq; + int rc; + + rc = end_that_request_first(req, uptodate, req->hard_nr_sectors); + assert(rc == 0); + + end_that_request_last(req); + + rc = carm_put_request(host, crq); + assert(rc == 0); +} + +static inline void carm_push_q (struct carm_host *host, request_queue_t *q) +{ + unsigned int idx = host->wait_q_prod % CARM_MAX_WAIT_Q; + + blk_stop_queue(q); + VPRINTK("STOPPED QUEUE %p\n", q); + + host->wait_q[idx] = q; + host->wait_q_prod++; + BUG_ON(host->wait_q_prod == host->wait_q_cons); /* overrun */ +} + +static inline request_queue_t *carm_pop_q(struct carm_host *host) +{ + unsigned int idx; + + if (host->wait_q_prod == host->wait_q_cons) + return NULL; + + idx = host->wait_q_cons % CARM_MAX_WAIT_Q; + host->wait_q_cons++; + + return host->wait_q[idx]; +} + +static inline void carm_round_robin(struct carm_host *host) +{ + request_queue_t *q = carm_pop_q(host); + if (q) { + blk_start_queue(q); + VPRINTK("STARTED QUEUE %p\n", q); + } +} + +static inline void carm_end_rq(struct carm_host *host, struct carm_request *crq, + int is_ok) +{ + carm_end_request_queued(host, crq, is_ok); + if (CARM_MAX_Q == 1) + carm_round_robin(host); + else if ((host->n_msgs <= CARM_MSG_LOW_WATER) && + (host->hw_sg_used <= CARM_SG_LOW_WATER)) { + carm_round_robin(host); + } +} + +static void carm_oob_rq_fn(request_queue_t *q) +{ + struct carm_host *host = q->queuedata; + struct carm_request *crq; + struct request *rq; + int rc; + + while (1) { + DPRINTK("get req\n"); + rq = elv_next_request(q); + if (!rq) + break; + + blkdev_dequeue_request(rq); + + crq = rq->special; + assert(crq != NULL); + assert(crq->rq == rq); + + crq->n_elem = 0; + + DPRINTK("send req\n"); + rc = carm_send_msg(host, crq); + if (rc) { + blk_requeue_request(q, rq); + carm_push_q(host, q); + return; /* call us again later, eventually */ + } + } +} + +static void carm_rq_fn(request_queue_t *q) +{ + struct carm_port *port = q->queuedata; + struct carm_host *host = port->host; + struct carm_msg_rw *msg; + struct carm_request *crq; + struct request *rq; + struct scatterlist *sg; + int writing = 0, pci_dir, i, n_elem, rc; + u32 tmp; + unsigned int msg_size; + +queue_one_request: + VPRINTK("get req\n"); + rq = elv_next_request(q); + if (!rq) + return; + + crq = carm_get_request(host); + if (!crq) { + carm_push_q(host, q); + return; /* call us again later, eventually */ + } + crq->rq = rq; + + blkdev_dequeue_request(rq); + + if (rq_data_dir(rq) == WRITE) { + writing = 1; + pci_dir = PCI_DMA_TODEVICE; + } else { + pci_dir = PCI_DMA_FROMDEVICE; + } + + /* get scatterlist from block layer */ + sg = &crq->sg[0]; + n_elem = blk_rq_map_sg(q, rq, sg); + if (n_elem <= 0) { + carm_end_rq(host, crq, 0); + return; /* request with no s/g entries? */ + } + + /* map scatterlist to PCI bus addresses */ + n_elem = pci_map_sg(host->pdev, sg, n_elem, pci_dir); + if (n_elem <= 0) { + carm_end_rq(host, crq, 0); + return; /* request with no s/g entries? */ + } + crq->n_elem = n_elem; + crq->port = port; + host->hw_sg_used += n_elem; + + /* + * build read/write message + */ + + VPRINTK("build msg\n"); + msg = (struct carm_msg_rw *) carm_ref_msg(host, crq->tag); + + if (writing) { + msg->type = CARM_MSG_WRITE; + crq->msg_type = CARM_MSG_WRITE; + } else { + msg->type = CARM_MSG_READ; + crq->msg_type = CARM_MSG_READ; + } + + msg->id = port->port_no; + msg->sg_count = n_elem; + msg->sg_type = SGT_32BIT; + msg->handle = cpu_to_le32(TAG_ENCODE(crq->tag)); + msg->lba = cpu_to_le32(rq->sector & 0xffffffff); + tmp = (rq->sector >> 16) >> 16; + msg->lba_high = cpu_to_le16( (u16) tmp ); + msg->lba_count = cpu_to_le16(rq->nr_sectors); + + msg_size = sizeof(struct carm_msg_rw) - sizeof(msg->sg); + for (i = 0; i < n_elem; i++) { + struct carm_msg_sg *carm_sg = &msg->sg[i]; + carm_sg->start = cpu_to_le32(sg_dma_address(&crq->sg[i])); + carm_sg->len = cpu_to_le32(sg_dma_len(&crq->sg[i])); + msg_size += sizeof(struct carm_msg_sg); + } + + rc = carm_lookup_bucket(msg_size); + BUG_ON(rc < 0); + crq->msg_bucket = (u32) rc; + + /* + * queue read/write message to hardware + */ + + VPRINTK("send msg, tag == %u\n", crq->tag); + rc = carm_send_msg(host, crq); + if (rc) { + carm_put_request(host, crq); + blk_requeue_request(q, rq); + carm_push_q(host, q); + return; /* call us again later, eventually */ + } + + goto queue_one_request; +} + +static void carm_handle_array_info(struct carm_host *host, + struct carm_request *crq, u8 *mem, + int is_ok) +{ + struct carm_port *port; + u8 *msg_data = mem + sizeof(struct carm_array_info); + struct carm_array_info *desc = (struct carm_array_info *) msg_data; + u64 lo, hi; + int cur_port; + size_t slen; + + DPRINTK("ENTER\n"); + + carm_end_rq(host, crq, is_ok); + + if (!is_ok) + goto out; + if (le32_to_cpu(desc->array_status) & ARRAY_NO_EXIST) + goto out; + + cur_port = host->cur_scan_dev; + + /* should never occur */ + if ((cur_port < 0) || (cur_port >= CARM_MAX_PORTS)) { + printk(KERN_ERR PFX "BUG: cur_scan_dev==%d, array_id==%d\n", + cur_port, (int) desc->array_id); + goto out; + } + + port = &host->port[cur_port]; + + lo = (u64) le32_to_cpu(desc->size); + hi = (u64) le32_to_cpu(desc->size_hi); + + port->capacity = lo | (hi << 32); + port->dev_geom_head = le16_to_cpu(desc->head); + port->dev_geom_sect = le16_to_cpu(desc->sect); + port->dev_geom_cyl = le16_to_cpu(desc->cyl); + + host->dev_active |= (1 << cur_port); + + strncpy(port->name, desc->name, sizeof(port->name)); + port->name[sizeof(port->name) - 1] = 0; + slen = strlen(port->name); + while (slen && (port->name[slen - 1] == ' ')) { + port->name[slen - 1] = 0; + slen--; + } + + printk(KERN_INFO DRV_NAME "(%s): port %u device %Lu sectors\n", + pci_name(host->pdev), port->port_no, port->capacity); + printk(KERN_INFO DRV_NAME "(%s): port %u device \"%s\"\n", + pci_name(host->pdev), port->port_no, port->name); + +out: + assert(host->state == HST_DEV_SCAN); + schedule_work(&host->fsm_task); +} + +static void carm_handle_scan_chan(struct carm_host *host, + struct carm_request *crq, u8 *mem, + int is_ok) +{ + u8 *msg_data = mem + IOC_SCAN_CHAN_OFFSET; + unsigned int i, dev_count = 0; + int new_state = HST_DEV_SCAN_START; + + DPRINTK("ENTER\n"); + + carm_end_rq(host, crq, is_ok); + + if (!is_ok) { + new_state = HST_ERROR; + goto out; + } + + /* TODO: scan and support non-disk devices */ + for (i = 0; i < 8; i++) + if (msg_data[i] == 0) { /* direct-access device (disk) */ + host->dev_present |= (1 << i); + dev_count++; + } + + printk(KERN_INFO DRV_NAME "(%s): found %u interesting devices\n", + pci_name(host->pdev), dev_count); + +out: + assert(host->state == HST_PORT_SCAN); + host->state = new_state; + schedule_work(&host->fsm_task); +} + +static void carm_handle_generic(struct carm_host *host, + struct carm_request *crq, int is_ok, + int cur_state, int next_state) +{ + DPRINTK("ENTER\n"); + + carm_end_rq(host, crq, is_ok); + + assert(host->state == cur_state); + if (is_ok) + host->state = next_state; + else + host->state = HST_ERROR; + schedule_work(&host->fsm_task); +} + +static inline void carm_handle_rw(struct carm_host *host, + struct carm_request *crq, int is_ok) +{ + int pci_dir; + + VPRINTK("ENTER\n"); + + if (rq_data_dir(crq->rq) == WRITE) + pci_dir = PCI_DMA_TODEVICE; + else + pci_dir = PCI_DMA_FROMDEVICE; + + pci_unmap_sg(host->pdev, &crq->sg[0], crq->n_elem, pci_dir); + + carm_end_rq(host, crq, is_ok); +} + +static inline void carm_handle_resp(struct carm_host *host, + u32 ret_handle_le, u32 status) +{ + u32 handle = le32_to_cpu(ret_handle_le); + unsigned int msg_idx; + struct carm_request *crq; + int is_ok = (status == RMSG_OK); + u8 *mem; + + VPRINTK("ENTER, handle == 0x%x\n", handle); + + if (unlikely(!TAG_VALID(handle))) { + printk(KERN_ERR DRV_NAME "(%s): BUG: invalid tag 0x%x\n", + pci_name(host->pdev), handle); + return; + } + + msg_idx = TAG_DECODE(handle); + VPRINTK("tag == %u\n", msg_idx); + + crq = &host->req[msg_idx]; + + /* fast path */ + if (likely(crq->msg_type == CARM_MSG_READ || + crq->msg_type == CARM_MSG_WRITE)) { + carm_handle_rw(host, crq, is_ok); + return; + } + + mem = carm_ref_msg(host, msg_idx); + + switch (crq->msg_type) { + case CARM_MSG_IOCTL: { + switch (crq->msg_subtype) { + case CARM_IOC_SCAN_CHAN: + carm_handle_scan_chan(host, crq, mem, is_ok); + break; + default: + /* unknown / invalid response */ + goto err_out; + } + break; + } + + case CARM_MSG_MISC: { + switch (crq->msg_subtype) { + case MISC_ALLOC_MEM: + carm_handle_generic(host, crq, is_ok, + HST_ALLOC_BUF, HST_SYNC_TIME); + break; + case MISC_SET_TIME: + carm_handle_generic(host, crq, is_ok, + HST_SYNC_TIME, HST_GET_FW_VER); + break; + case MISC_GET_FW_VER: { + struct carm_fw_ver *ver = (struct carm_fw_ver *) + mem + sizeof(struct carm_msg_get_fw_ver); + if (is_ok) { + host->fw_ver = le32_to_cpu(ver->version); + host->flags |= (ver->features & FL_FW_VER_MASK); + } + carm_handle_generic(host, crq, is_ok, + HST_GET_FW_VER, HST_PORT_SCAN); + break; + } + default: + /* unknown / invalid response */ + goto err_out; + } + break; + } + + case CARM_MSG_ARRAY: { + switch (crq->msg_subtype) { + case CARM_ARRAY_INFO: + carm_handle_array_info(host, crq, mem, is_ok); + break; + default: + /* unknown / invalid response */ + goto err_out; + } + break; + } + + default: + /* unknown / invalid response */ + goto err_out; + } + + return; + +err_out: + printk(KERN_WARNING DRV_NAME "(%s): BUG: unhandled message type %d/%d\n", + pci_name(host->pdev), crq->msg_type, crq->msg_subtype); + carm_end_rq(host, crq, 0); +} + +static inline void carm_handle_responses(struct carm_host *host) +{ + void *mmio = host->mmio; + struct carm_response *resp = (struct carm_response *) host->shm; + unsigned int work = 0; + unsigned int idx = host->resp_idx % RMSG_Q_LEN; + + while (1) { + u32 status = le32_to_cpu(resp[idx].status); + + if (status == 0xffffffff) { + VPRINTK("ending response on index %u\n", idx); + writel(idx << 3, mmio + CARM_RESP_IDX); + break; + } + + /* response to a message we sent */ + else if ((status & (1 << 31)) == 0) { + VPRINTK("handling msg response on index %u\n", idx); + carm_handle_resp(host, resp[idx].ret_handle, status); + resp[idx].status = 0xffffffff; + } + + /* asynchronous events the hardware throws our way */ + else if ((status & 0xff000000) == (1 << 31)) { + u8 *evt_type_ptr = (u8 *) &resp[idx]; + u8 evt_type = *evt_type_ptr; + printk(KERN_WARNING DRV_NAME "(%s): unhandled event type %d\n", + pci_name(host->pdev), (int) evt_type); + resp[idx].status = 0xffffffff; + } + + idx = NEXT_RESP(idx); + work++; + } + + VPRINTK("EXIT, work==%u\n", work); + host->resp_idx += work; +} + +static irqreturn_t carm_interrupt(int irq, void *__host, struct pt_regs *regs) +{ + struct carm_host *host = __host; + void *mmio; + u32 mask; + int handled = 0; + unsigned long flags; + + if (!host) { + VPRINTK("no host\n"); + return IRQ_NONE; + } + + spin_lock_irqsave(&host->lock, flags); + + mmio = host->mmio; + + /* reading should also clear interrupts */ + mask = readl(mmio + CARM_INT_STAT); + + if (mask == 0 || mask == 0xffffffff) { + VPRINTK("no work, mask == 0x%x\n", mask); + goto out; + } + + if (mask & INT_ACK_MASK) + writel(mask, mmio + CARM_INT_STAT); + + if (unlikely(host->state == HST_INVALID)) { + VPRINTK("not initialized yet, mask = 0x%x\n", mask); + goto out; + } + + if (mask & CARM_HAVE_RESP) { + handled = 1; + carm_handle_responses(host); + } + +out: + spin_unlock_irqrestore(&host->lock, flags); + VPRINTK("EXIT\n"); + return IRQ_RETVAL(handled); +} + +static void carm_fsm_task (void *_data) +{ + struct carm_host *host = _data; + unsigned long flags; + unsigned int state; + int rc, i, next_dev; + int reschedule = 0; + int new_state = HST_INVALID; + + spin_lock_irqsave(&host->lock, flags); + state = host->state; + spin_unlock_irqrestore(&host->lock, flags); + + DPRINTK("ENTER, state == %s\n", state_name[state]); + + switch (state) { + case HST_PROBE_START: + new_state = HST_ALLOC_BUF; + reschedule = 1; + break; + + case HST_ALLOC_BUF: + rc = carm_send_special(host, carm_fill_alloc_buf); + if (rc) { + new_state = HST_ERROR; + reschedule = 1; + } + break; + + case HST_SYNC_TIME: + rc = carm_send_special(host, carm_fill_sync_time); + if (rc) { + new_state = HST_ERROR; + reschedule = 1; + } + break; + + case HST_GET_FW_VER: + rc = carm_send_special(host, carm_fill_get_fw_ver); + if (rc) { + new_state = HST_ERROR; + reschedule = 1; + } + break; + + case HST_PORT_SCAN: + rc = carm_send_special(host, carm_fill_scan_channels); + if (rc) { + new_state = HST_ERROR; + reschedule = 1; + } + break; + + case HST_DEV_SCAN_START: + host->cur_scan_dev = -1; + new_state = HST_DEV_SCAN; + reschedule = 1; + break; + + case HST_DEV_SCAN: + next_dev = -1; + for (i = host->cur_scan_dev + 1; i < CARM_MAX_PORTS; i++) + if (host->dev_present & (1 << i)) { + next_dev = i; + break; + } + + if (next_dev >= 0) { + host->cur_scan_dev = next_dev; + rc = carm_array_info(host, next_dev); + if (rc) { + new_state = HST_ERROR; + reschedule = 1; + } + } else { + new_state = HST_DEV_ACTIVATE; + reschedule = 1; + } + break; + + case HST_DEV_ACTIVATE: { + int activated = 0; + for (i = 0; i < CARM_MAX_PORTS; i++) + if (host->dev_active & (1 << i)) { + struct carm_port *port = &host->port[i]; + struct gendisk *disk = port->disk; + + set_capacity(disk, port->capacity); + add_disk(disk); + activated++; + } + + printk(KERN_INFO DRV_NAME "(%s): %d ports activated\n", + pci_name(host->pdev), activated); + + new_state = HST_PROBE_FINISHED; + reschedule = 1; + break; + } + + case HST_PROBE_FINISHED: + up(&host->probe_sem); + break; + + case HST_ERROR: + /* FIXME: TODO */ + break; + + default: + /* should never occur */ + printk(KERN_ERR PFX "BUG: unknown state %d\n", state); + assert(0); + break; + } + + if (new_state != HST_INVALID) { + spin_lock_irqsave(&host->lock, flags); + host->state = new_state; + spin_unlock_irqrestore(&host->lock, flags); + } + if (reschedule) + schedule_work(&host->fsm_task); +} + +static int carm_init_wait(void *mmio, u32 bits, unsigned int test_bit) +{ + unsigned int i; + + for (i = 0; i < 50000; i++) { + u32 tmp = readl(mmio + CARM_LMUC); + udelay(100); + + if (test_bit) { + if ((tmp & bits) == bits) + return 0; + } else { + if ((tmp & bits) == 0) + return 0; + } + + cond_resched(); + } + + printk(KERN_ERR PFX "carm_init_wait timeout, bits == 0x%x, test_bit == %s\n", + bits, test_bit ? "yes" : "no"); + return -EBUSY; +} + +static void carm_init_responses(struct carm_host *host) +{ + void *mmio = host->mmio; + unsigned int i; + struct carm_response *resp = (struct carm_response *) host->shm; + + for (i = 0; i < RMSG_Q_LEN; i++) + resp[i].status = 0xffffffff; + + writel(0, mmio + CARM_RESP_IDX); +} + +static int carm_init_host(struct carm_host *host) +{ + void *mmio = host->mmio; + u32 tmp; + u8 tmp8; + int rc; + + DPRINTK("ENTER\n"); + + writel(0, mmio + CARM_INT_MASK); + + tmp8 = readb(mmio + CARM_INITC); + if (tmp8 & 0x01) { + tmp8 &= ~0x01; + writeb(tmp8, CARM_INITC); + readb(mmio + CARM_INITC); /* flush */ + + DPRINTK("snooze...\n"); + msleep(5000); + } + + tmp = readl(mmio + CARM_HMUC); + if (tmp & CARM_CME) { + DPRINTK("CME bit present, waiting\n"); + rc = carm_init_wait(mmio, CARM_CME, 1); + if (rc) { + DPRINTK("EXIT, carm_init_wait 1 failed\n"); + return rc; + } + } + if (tmp & CARM_RME) { + DPRINTK("RME bit present, waiting\n"); + rc = carm_init_wait(mmio, CARM_RME, 1); + if (rc) { + DPRINTK("EXIT, carm_init_wait 2 failed\n"); + return rc; + } + } + + tmp &= ~(CARM_RME | CARM_CME); + writel(tmp, mmio + CARM_HMUC); + readl(mmio + CARM_HMUC); /* flush */ + + rc = carm_init_wait(mmio, CARM_RME | CARM_CME, 0); + if (rc) { + DPRINTK("EXIT, carm_init_wait 3 failed\n"); + return rc; + } + + carm_init_buckets(mmio); + + writel(host->shm_dma & 0xffffffff, mmio + RBUF_ADDR_LO); + writel((host->shm_dma >> 16) >> 16, mmio + RBUF_ADDR_HI); + writel(RBUF_LEN, mmio + RBUF_BYTE_SZ); + + tmp = readl(mmio + CARM_HMUC); + tmp |= (CARM_RME | CARM_CME | CARM_WZBC); + writel(tmp, mmio + CARM_HMUC); + readl(mmio + CARM_HMUC); /* flush */ + + rc = carm_init_wait(mmio, CARM_RME | CARM_CME, 1); + if (rc) { + DPRINTK("EXIT, carm_init_wait 4 failed\n"); + return rc; + } + + writel(0, mmio + CARM_HMPHA); + writel(INT_DEF_MASK, mmio + CARM_INT_MASK); + + carm_init_responses(host); + + /* start initialization, probing state machine */ + spin_lock_irq(&host->lock); + assert(host->state == HST_INVALID); + host->state = HST_PROBE_START; + spin_unlock_irq(&host->lock); + schedule_work(&host->fsm_task); + + DPRINTK("EXIT\n"); + return 0; +} + +static int carm_init_disks(struct carm_host *host) +{ + unsigned int i; + int rc = 0; + + for (i = 0; i < CARM_MAX_PORTS; i++) { + struct gendisk *disk; + request_queue_t *q; + struct carm_port *port; + + port = &host->port[i]; + port->host = host; + port->port_no = i; + + disk = alloc_disk(CARM_MINORS_PER_MAJOR); + if (!disk) { + rc = -ENOMEM; + break; + } + + port->disk = disk; + sprintf(disk->disk_name, DRV_NAME "%u_%u", carm_host_id, i); + sprintf(disk->devfs_name, DRV_NAME "/%u_%u", carm_host_id, i); + disk->major = host->major; + disk->first_minor = i * CARM_MINORS_PER_MAJOR; + disk->fops = &carm_bd_ops; + disk->private_data = port; + + q = blk_init_queue(carm_rq_fn, &host->lock); + if (!q) { + rc = -ENOMEM; + break; + } + disk->queue = q; + blk_queue_max_hw_segments(q, CARM_MAX_REQ_SG); + blk_queue_max_phys_segments(q, CARM_MAX_REQ_SG); + blk_queue_segment_boundary(q, CARM_SG_BOUNDARY); + + q->queuedata = port; + } + + return rc; +} + +static void carm_free_disks(struct carm_host *host) +{ + unsigned int i; + + for (i = 0; i < CARM_MAX_PORTS; i++) { + struct gendisk *disk = host->port[i].disk; + if (disk) { + request_queue_t *q = disk->queue; + if (q) + blk_cleanup_queue(q); + put_disk(disk); + } + } +} + +static int carm_init_shm(struct carm_host *host) +{ + host->shm = pci_alloc_consistent(host->pdev, CARM_SHM_SIZE, + &host->shm_dma); + if (!host->shm) + return -ENOMEM; + + host->msg_base = host->shm + RBUF_LEN; + host->msg_dma = host->shm_dma + RBUF_LEN; + + memset(host->shm, 0xff, RBUF_LEN); + memset(host->msg_base, 0, PDC_SHM_SIZE - RBUF_LEN); + + return 0; +} + +static int carm_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) +{ + static unsigned int printed_version; + struct carm_host *host; + unsigned int pci_dac; + int rc; + request_queue_t *q; + unsigned int i; + + if (!printed_version++) + printk(KERN_DEBUG DRV_NAME " version " DRV_VERSION "\n"); + + rc = pci_enable_device(pdev); + if (rc) + return rc; + + rc = pci_request_regions(pdev, DRV_NAME); + if (rc) + goto err_out; + +#if IF_64BIT_DMA_IS_POSSIBLE /* grrrr... */ + rc = pci_set_dma_mask(pdev, 0xffffffffffffffffULL); + if (!rc) { + rc = pci_set_consistent_dma_mask(pdev, 0xffffffffffffffffULL); + if (rc) { + printk(KERN_ERR DRV_NAME "(%s): consistent DMA mask failure\n", + pci_name(pdev)); + goto err_out_regions; + } + pci_dac = 1; + } else { +#endif + rc = pci_set_dma_mask(pdev, 0xffffffffULL); + if (rc) { + printk(KERN_ERR DRV_NAME "(%s): DMA mask failure\n", + pci_name(pdev)); + goto err_out_regions; + } + pci_dac = 0; +#if IF_64BIT_DMA_IS_POSSIBLE /* grrrr... */ + } +#endif + + host = kmalloc(sizeof(*host), GFP_KERNEL); + if (!host) { + printk(KERN_ERR DRV_NAME "(%s): memory alloc failure\n", + pci_name(pdev)); + rc = -ENOMEM; + goto err_out_regions; + } + + memset(host, 0, sizeof(*host)); + host->pdev = pdev; + host->flags = pci_dac ? FL_DAC : 0; + spin_lock_init(&host->lock); + INIT_WORK(&host->fsm_task, carm_fsm_task, host); + init_MUTEX_LOCKED(&host->probe_sem); + + for (i = 0; i < ARRAY_SIZE(host->req); i++) + host->req[i].tag = i; + + host->mmio = ioremap(pci_resource_start(pdev, 0), + pci_resource_len(pdev, 0)); + if (!host->mmio) { + printk(KERN_ERR DRV_NAME "(%s): MMIO alloc failure\n", + pci_name(pdev)); + rc = -ENOMEM; + goto err_out_kfree; + } + + rc = carm_init_shm(host); + if (rc) { + printk(KERN_ERR DRV_NAME "(%s): DMA SHM alloc failure\n", + pci_name(pdev)); + goto err_out_iounmap; + } + + q = blk_init_queue(carm_oob_rq_fn, &host->lock); + if (!q) { + printk(KERN_ERR DRV_NAME "(%s): OOB queue alloc failure\n", + pci_name(pdev)); + rc = -ENOMEM; + goto err_out_pci_free; + } + host->oob_q = q; + q->queuedata = host; + + rc = register_blkdev(0, DRV_NAME); + if (rc < 0) + goto err_out_free_oob; + host->major = rc; + + devfs_mk_dir(DRV_NAME); + + rc = carm_init_disks(host); + if (rc) + goto err_out_blkdev_disks; + + pci_set_master(pdev); + + rc = request_irq(pdev->irq, carm_interrupt, SA_SHIRQ, DRV_NAME, host); + if (rc) { + printk(KERN_ERR DRV_NAME "(%s): irq alloc failure\n", + pci_name(pdev)); + goto err_out_blkdev_disks; + } + + rc = carm_init_host(host); + if (rc) + goto err_out_free_irq; + + DPRINTK("waiting for probe_sem\n"); + down(&host->probe_sem); + + /* TODO: wait for probing to end */ + + printk(KERN_ERR DRV_NAME "(%s): registered host, %d ports, mmio %lx\n", + pci_name(pdev), (int) CARM_MAX_PORTS, + pci_resource_start(pdev, 0)); + carm_host_id++; + pci_set_drvdata(pdev, host); + return 0; + +err_out_free_irq: + free_irq(pdev->irq, host); +err_out_blkdev_disks: + carm_free_disks(host); + unregister_blkdev(host->major, DRV_NAME); +err_out_free_oob: + blk_cleanup_queue(host->oob_q); +err_out_pci_free: + pci_free_consistent(pdev, CARM_SHM_SIZE, host->shm, host->shm_dma); +err_out_iounmap: + iounmap(host->mmio); +err_out_kfree: + kfree(host); +err_out_regions: + pci_release_regions(pdev); +err_out: + pci_disable_device(pdev); + return rc; +} + +static void carm_remove_one (struct pci_dev *pdev) +{ + struct carm_host *host = pci_get_drvdata(pdev); + + if (!host) { + printk(KERN_ERR PFX "BUG: no host data for PCI(%s)\n", + pci_name(pdev)); + return; + } + + free_irq(pdev->irq, host); + carm_free_disks(host); + devfs_remove(DRV_NAME); + unregister_blkdev(host->major, DRV_NAME); + blk_cleanup_queue(host->oob_q); + pci_free_consistent(pdev, CARM_SHM_SIZE, host->shm, host->shm_dma); + iounmap(host->mmio); + kfree(host); + pci_release_regions(pdev); + pci_disable_device(pdev); +} + +static int __init carm_init(void) +{ + return pci_module_init(&carm_driver); +} + +static void __exit carm_exit(void) +{ + pci_unregister_driver(&carm_driver); +} + +module_init(carm_init); +module_exit(carm_exit); + + diff -Nru a/drivers/block/cciss_scsi.c b/drivers/block/cciss_scsi.c --- a/drivers/block/cciss_scsi.c Sun Mar 14 14:20:06 2004 +++ b/drivers/block/cciss_scsi.c Sun Mar 14 14:20:06 2004 @@ -693,7 +693,7 @@ scsi_cmd_free(ctlr, cp); } -static int __init +static int cciss_scsi_detect(int ctlr) { struct Scsi_Host *sh; diff -Nru a/drivers/block/ll_rw_blk.c b/drivers/block/ll_rw_blk.c --- a/drivers/block/ll_rw_blk.c Sun Mar 14 14:20:06 2004 +++ b/drivers/block/ll_rw_blk.c Sun Mar 14 14:20:06 2004 @@ -28,6 +28,11 @@ #include #include +/* + * for max sense size + */ +#include + static void blk_unplug_work(void *data); static void blk_unplug_timeout(unsigned long data); @@ -104,6 +109,7 @@ bit = (rw == WRITE) ? BDI_write_congested : BDI_read_congested; clear_bit(bit, &q->backing_dev_info.state); + smp_mb__after_clear_bit(); if (waitqueue_active(wqh)) wake_up(wqh); } @@ -1136,8 +1142,6 @@ if (!blk_remove_plug(q)) return; - del_timer(&q->unplug_timer); - /* * was plugged, fire request_fn if queue has stuff to do */ @@ -1543,7 +1547,6 @@ if (rl->count[rw] < queue_congestion_off_threshold(q)) clear_queue_congested(q, rw); if (rl->count[rw]+1 <= q->nr_requests) { - smp_mb(); if (waitqueue_active(&rl->wait[rw])) wake_up(&rl->wait[rw]); if (!waitqueue_active(&rl->wait[rw])) @@ -1625,6 +1628,7 @@ rq->rl = rl; rq->waiting = NULL; rq->special = NULL; + rq->data_len = 0; rq->data = NULL; rq->sense = NULL; @@ -1770,6 +1774,144 @@ EXPORT_SYMBOL(blk_insert_request); +/** + * blk_rq_map_user - map user data to a request, for REQ_BLOCK_PC usage + * @q: request queue where request should be inserted + * @rw: READ or WRITE data + * @ubuf: the user buffer + * @len: length of user data + * + * Description: + * Data will be mapped directly for zero copy io, if possible. Otherwise + * a kernel bounce buffer is used. + * + * A matching blk_rq_unmap_user() must be issued at the end of io, while + * still in process context. + */ +struct request *blk_rq_map_user(request_queue_t *q, int rw, void __user *ubuf, + unsigned int len) +{ + struct request *rq = NULL; + char *buf = NULL; + struct bio *bio; + int ret; + + rq = blk_get_request(q, rw, __GFP_WAIT); + if (!rq) + return ERR_PTR(-ENOMEM); + + bio = bio_map_user(q, NULL, (unsigned long) ubuf, len, rw == READ); + if (!bio) { + int bytes = (len + 511) & ~511; + + buf = kmalloc(bytes, q->bounce_gfp | GFP_USER); + if (!buf) { + ret = -ENOMEM; + goto fault; + } + + if (rw == WRITE) { + if (copy_from_user(buf, ubuf, len)) { + ret = -EFAULT; + goto fault; + } + } else + memset(buf, 0, len); + } + + rq->bio = rq->biotail = bio; + if (rq->bio) + blk_rq_bio_prep(q, rq, bio); + + rq->buffer = rq->data = buf; + rq->data_len = len; + return rq; +fault: + if (buf) + kfree(buf); + if (bio) + bio_unmap_user(bio, 1); + if (rq) + blk_put_request(rq); + + return ERR_PTR(ret); +} + +EXPORT_SYMBOL(blk_rq_map_user); + +/** + * blk_rq_unmap_user - unmap a request with user data + * @rq: request to be unmapped + * @ubuf: user buffer + * @ulen: length of user buffer + * + * Description: + * Unmap a request previously mapped by blk_rq_map_user(). + */ +int blk_rq_unmap_user(struct request *rq, void __user *ubuf, unsigned int ulen) +{ + const int read = rq_data_dir(rq) == READ; + int ret = 0; + + if (rq->biotail) + bio_unmap_user(rq->biotail, read); + if (rq->buffer) { + if (read && copy_to_user(ubuf, rq->buffer, ulen)) + ret = -EFAULT; + kfree(rq->buffer); + } + + blk_put_request(rq); + return ret; +} + +EXPORT_SYMBOL(blk_rq_unmap_user); + +/** + * blk_execute_rq - insert a request into queue for execution + * @q: queue to insert the request in + * @bd_disk: matching gendisk + * @rq: request to insert + * + * Description: + * Insert a fully prepared request at the back of the io scheduler queue + * for execution. + */ +int blk_execute_rq(request_queue_t *q, struct gendisk *bd_disk, + struct request *rq) +{ + DECLARE_COMPLETION(wait); + char sense[SCSI_SENSE_BUFFERSIZE]; + int err = 0; + + rq->rq_disk = bd_disk; + + /* + * we need an extra reference to the request, so we can look at + * it after io completion + */ + rq->ref_count++; + + if (!rq->sense) { + memset(sense, 0, sizeof(sense)); + rq->sense = sense; + rq->sense_len = 0; + } + + rq->flags |= REQ_NOMERGE; + rq->waiting = &wait; + elv_add_request(q, rq, ELEVATOR_INSERT_BACK, 1); + generic_unplug_device(q); + wait_for_completion(&wait); + + if (rq->errors) + err = -EIO; + + return err; +} + +EXPORT_SYMBOL(blk_execute_rq); + void drive_stat_acct(struct request *rq, int nr_sectors, int new_io) { int rw = rq_data_dir(rq); @@ -1898,15 +2040,17 @@ * If no queues are congested then just wait for the next request to be * returned. */ -void blk_congestion_wait(int rw, long timeout) +long blk_congestion_wait(int rw, long timeout) { + long ret; DEFINE_WAIT(wait); wait_queue_head_t *wqh = &congestion_wqh[rw]; blk_run_queues(); prepare_to_wait(wqh, &wait, TASK_UNINTERRUPTIBLE); - io_schedule_timeout(timeout); + ret = io_schedule_timeout(timeout); finish_wait(wqh, &wait); + return ret; } EXPORT_SYMBOL(blk_congestion_wait); diff -Nru a/drivers/block/loop.c b/drivers/block/loop.c --- a/drivers/block/loop.c Sun Mar 14 14:20:07 2004 +++ b/drivers/block/loop.c Sun Mar 14 14:20:07 2004 @@ -66,6 +66,7 @@ #include #include #include /* for invalidate_bdev() */ +#include #include @@ -148,14 +149,12 @@ &xor_funcs }; -static int -figure_loop_size(struct loop_device *lo) +static loff_t get_loop_size(struct loop_device *lo, struct file *file) { loff_t size, offset, loopsize; - sector_t x; /* Compute loopsize in bytes */ - size = i_size_read(lo->lo_backing_file->f_mapping->host); + size = i_size_read(file->f_mapping->host); offset = lo->lo_offset; loopsize = size - offset; if (lo->lo_sizelimit > 0 && lo->lo_sizelimit < loopsize) @@ -165,8 +164,14 @@ * Unfortunately, if we want to do I/O on the device, * the number of 512-byte sectors has to fit into a sector_t. */ - size = loopsize >> 9; - x = (sector_t)size; + return loopsize >> 9; +} + +static int +figure_loop_size(struct loop_device *lo) +{ + loff_t size = get_loop_size(lo, lo->lo_backing_file); + sector_t x = (sector_t)size; if ((loff_t)x != size) return -EFBIG; @@ -429,12 +434,24 @@ goto out; } +struct switch_request { + struct file *file; + struct completion wait; +}; + +static void do_loop_switch(struct loop_device *, struct switch_request *); + static inline void loop_handle_bio(struct loop_device *lo, struct bio *bio) { int ret; - ret = do_bio_filebacked(lo, bio); - bio_endio(bio, bio->bi_size, ret); + if (unlikely(!bio->bi_bdev)) { + do_loop_switch(lo, bio->bi_private); + bio_put(bio); + } else { + ret = do_bio_filebacked(lo, bio); + bio_endio(bio, bio->bi_size, ret); + } } /* @@ -495,6 +512,103 @@ return 0; } +/* + * loop_switch performs the hard work of switching a backing store. + * First it needs to flush existing IO, it does this by sending a magic + * BIO down the pipe. The completion of this BIO does the actual switch. + */ +static int loop_switch(struct loop_device *lo, struct file *file) +{ + struct switch_request w; + struct bio *bio = bio_alloc(GFP_KERNEL, 1); + if (!bio) + return -ENOMEM; + init_completion(&w.wait); + w.file = file; + bio->bi_private = &w; + bio->bi_bdev = NULL; + loop_make_request(lo->lo_queue, bio); + wait_for_completion(&w.wait); + return 0; +} + +/* + * Do the actual switch; called from the BIO completion routine + */ +static void do_loop_switch(struct loop_device *lo, struct switch_request *p) +{ + struct file *file = p->file; + struct file *old_file = lo->lo_backing_file; + struct address_space *mapping = file->f_mapping; + + mapping_set_gfp_mask(old_file->f_mapping, lo->old_gfp_mask); + lo->lo_backing_file = file; + lo->lo_blocksize = mapping->host->i_blksize; + lo->old_gfp_mask = mapping_gfp_mask(mapping); + mapping_set_gfp_mask(mapping, lo->old_gfp_mask & ~(__GFP_IO|__GFP_FS)); + complete(&p->wait); +} + + +/* + * loop_change_fd switched the backing store of a loopback device to + * a new file. This is useful for operating system installers to free up + * the original file and in High Availability environments to switch to + * an alternative location for the content in case of server meltdown. + * This can only work if the loop device is used read-only, and if the + * new backing store is the same size and type as the old backing store. + */ +static int loop_change_fd(struct loop_device *lo, struct file *lo_file, + struct block_device *bdev, unsigned int arg) +{ + struct file *file, *old_file; + struct inode *inode; + int error; + + error = -ENXIO; + if (lo->lo_state != Lo_bound) + goto out; + + /* the loop device has to be read-only */ + error = -EINVAL; + if (lo->lo_flags != LO_FLAGS_READ_ONLY) + goto out; + + error = -EBADF; + file = fget(arg); + if (!file) + goto out; + + inode = file->f_mapping->host; + old_file = lo->lo_backing_file; + + error = -EINVAL; + + if (!S_ISREG(inode->i_mode) && !S_ISBLK(inode->i_mode)) + goto out_putf; + + /* new backing store needs to support loop (eg sendfile) */ + if (!inode->i_fop->sendfile) + goto out_putf; + + /* size of the new backing store needs to be the same */ + if (get_loop_size(lo, file) != get_loop_size(lo, old_file)) + goto out_putf; + + /* and ... switch */ + error = loop_switch(lo, file); + if (error) + goto out_putf; + + fput(old_file); + return 0; + + out_putf: + fput(file); + out: + return error; +} + static int loop_set_fd(struct loop_device *lo, struct file *lo_file, struct block_device *bdev, unsigned int arg) { @@ -505,6 +619,7 @@ unsigned lo_blocksize; int lo_flags = 0; int error; + loff_t size; /* This is safe, since we have a reference from open(). */ __module_get(THIS_MODULE); @@ -543,6 +658,13 @@ goto out_putf; } + size = get_loop_size(lo, file); + + if ((loff_t)(sector_t)size != size) { + error = -EFBIG; + goto out_putf; + } + if (!(lo_file->f_mode & FMODE_WRITE)) lo_flags |= LO_FLAGS_READ_ONLY; @@ -555,10 +677,7 @@ lo->transfer = NULL; lo->ioctl = NULL; lo->lo_sizelimit = 0; - if (figure_loop_size(lo)) { - error = -EFBIG; - goto out_putf; - } + bd_set_size(bdev,(loff_t)get_capacity(disks[lo->lo_number])<<9); lo->old_gfp_mask = mapping_gfp_mask(mapping); mapping_set_gfp_mask(mapping, lo->old_gfp_mask & ~(__GFP_IO|__GFP_FS)); @@ -571,6 +690,8 @@ blk_queue_make_request(lo->lo_queue, loop_make_request); lo->lo_queue->queuedata = lo; + set_capacity(disks[lo->lo_number], size); + set_blocksize(bdev, lo_blocksize); kernel_thread(loop_thread, lo, CLONE_KERNEL); @@ -660,6 +781,7 @@ memset(lo->lo_file_name, 0, LO_NAME_SIZE); invalidate_bdev(bdev, 0); set_capacity(disks[lo->lo_number], 0); + bd_set_size(bdev, 0); mapping_set_gfp_mask(filp->f_mapping, gfp); lo->lo_state = Lo_unbound; fput(filp); @@ -880,6 +1002,9 @@ switch (cmd) { case LOOP_SET_FD: err = loop_set_fd(lo, file, inode->i_bdev, arg); + break; + case LOOP_CHANGE_FD: + err = loop_change_fd(lo, file, inode->i_bdev, arg); break; case LOOP_CLR_FD: err = loop_clr_fd(lo, inode->i_bdev); diff -Nru a/drivers/block/scsi_ioctl.c b/drivers/block/scsi_ioctl.c --- a/drivers/block/scsi_ioctl.c Sun Mar 14 14:20:08 2004 +++ b/drivers/block/scsi_ioctl.c Sun Mar 14 14:20:08 2004 @@ -24,13 +24,12 @@ #include #include #include -#include #include #include #include #include - +#include /* Command group 3 is reserved and should never be used. */ const unsigned char scsi_command_size[8] = @@ -39,45 +38,9 @@ 16, 12, 10, 10 }; -#define BLK_DEFAULT_TIMEOUT (60 * HZ) - -/* defined in ../scsi/scsi.h ... should it be included? */ -#ifndef SCSI_SENSE_BUFFERSIZE -#define SCSI_SENSE_BUFFERSIZE 64 -#endif - -static int blk_do_rq(request_queue_t *q, struct gendisk *bd_disk, - struct request *rq) -{ - char sense[SCSI_SENSE_BUFFERSIZE]; - DECLARE_COMPLETION(wait); - int err = 0; - - rq->rq_disk = bd_disk; - - /* - * we need an extra reference to the request, so we can look at - * it after io completion - */ - rq->ref_count++; - - if (!rq->sense) { - memset(sense, 0, sizeof(sense)); - rq->sense = sense; - rq->sense_len = 0; - } - - rq->flags |= REQ_NOMERGE; - rq->waiting = &wait; - elv_add_request(q, rq, ELEVATOR_INSERT_BACK, 1); - generic_unplug_device(q); - wait_for_completion(&wait); - - if (rq->errors) - err = -EIO; +EXPORT_SYMBOL(scsi_command_size); - return err; -} +#define BLK_DEFAULT_TIMEOUT (60 * HZ) #include @@ -148,9 +111,7 @@ unsigned long start_time; int reading, writing; struct request *rq; - struct bio *bio; char sense[SCSI_SENSE_BUFFERSIZE]; - void *buffer; if (hdr->interface_id != 'S') return -EINVAL; @@ -167,11 +128,7 @@ return -EIO; reading = writing = 0; - buffer = NULL; - bio = NULL; if (hdr->dxfer_len) { - unsigned int bytes = (hdr->dxfer_len + 511) & ~511; - switch (hdr->dxfer_direction) { default: return -EINVAL; @@ -186,31 +143,13 @@ break; } - /* - * first try to map it into a bio. reading from device will - * be a write to vm. - */ - bio = bio_map_user(q, NULL, (unsigned long) hdr->dxferp, - hdr->dxfer_len, reading); - - /* - * if bio setup failed, fall back to slow approach - */ - if (!bio) { - buffer = kmalloc(bytes, q->bounce_gfp | GFP_USER); - if (!buffer) - return -ENOMEM; - - if (writing) { - if (copy_from_user(buffer, hdr->dxferp, - hdr->dxfer_len)) - goto out_buffer; - } else - memset(buffer, 0, hdr->dxfer_len); - } - } + rq = blk_rq_map_user(q, writing ? WRITE : READ, hdr->dxferp, + hdr->dxfer_len); - rq = blk_get_request(q, writing ? WRITE : READ, __GFP_WAIT); + if (IS_ERR(rq)) + return PTR_ERR(rq); + } else + rq = blk_get_request(q, READ, __GFP_WAIT); /* * fill in request structure @@ -226,14 +165,6 @@ rq->flags |= REQ_BLOCK_PC; - rq->bio = rq->biotail = NULL; - - if (bio) - blk_rq_bio_prep(q, rq, bio); - - rq->data = buffer; - rq->data_len = hdr->dxfer_len; - rq->timeout = (hdr->timeout * HZ) / 1000; if (!rq->timeout) rq->timeout = q->sg_timeout; @@ -246,10 +177,7 @@ * (if he doesn't check that is his problem). * N.B. a non-zero SCSI status is _not_ necessarily an error. */ - blk_do_rq(q, bd_disk, rq); - - if (bio) - bio_unmap_user(bio, reading); + blk_execute_rq(q, bd_disk, rq); /* write to all output members */ hdr->status = rq->errors; @@ -271,22 +199,12 @@ hdr->sb_len_wr = len; } - blk_put_request(rq); - - if (buffer) { - if (reading) - if (copy_to_user(hdr->dxferp, buffer, hdr->dxfer_len)) - goto out_buffer; - - kfree(buffer); - } + if (blk_rq_unmap_user(rq, hdr->dxferp, hdr->dxfer_len)) + return -EFAULT; /* may not have succeeded, but output values written to control * structure (struct sg_io_hdr). */ return 0; -out_buffer: - kfree(buffer); - return -EFAULT; } #define FORMAT_UNIT_TIMEOUT (2 * 60 * 60 * HZ) @@ -369,7 +287,7 @@ rq->data_len = bytes; rq->flags |= REQ_BLOCK_PC; - blk_do_rq(q, bd_disk, rq); + blk_execute_rq(q, bd_disk, rq); err = rq->errors & 0xff; /* only 8 bit SCSI status */ if (err) { if (rq->sense_len && rq->sense) { @@ -447,6 +365,8 @@ old_cdb = hdr.cmdp; hdr.cmdp = cdb; err = sg_io(q, bd_disk, &hdr); + if (err == -EFAULT) + break; hdr.cmdp = old_cdb; if (copy_to_user((struct sg_io_hdr *) arg, &hdr, sizeof(hdr))) @@ -457,10 +377,9 @@ struct cdrom_generic_command cgc; struct sg_io_hdr hdr; - if (copy_from_user(&cgc, (struct cdrom_generic_command *) arg, sizeof(cgc))) { - err = -EFAULT; + err = -EFAULT; + if (copy_from_user(&cgc, (struct cdrom_generic_command *) arg, sizeof(cgc))) break; - } cgc.timeout = clock_t_to_jiffies(cgc.timeout); memset(&hdr, 0, sizeof(hdr)); hdr.interface_id = 'S'; @@ -493,7 +412,10 @@ hdr.timeout = cgc.timeout; hdr.cmdp = cgc.cmd; hdr.cmd_len = sizeof(cgc.cmd); + err = sg_io(q, bd_disk, &hdr); + if (err == -EFAULT) + break; if (hdr.status) err = -EIO; @@ -529,7 +451,7 @@ rq->cmd[0] = GPCMD_START_STOP_UNIT; rq->cmd[4] = 0x02 + (close != 0); rq->cmd_len = 6; - err = blk_do_rq(q, bd_disk, rq); + err = blk_execute_rq(q, bd_disk, rq); blk_put_request(rq); break; default: @@ -541,4 +463,3 @@ } EXPORT_SYMBOL(scsi_cmd_ioctl); -EXPORT_SYMBOL(scsi_command_size); diff -Nru a/drivers/cdrom/cdrom.c b/drivers/cdrom/cdrom.c --- a/drivers/cdrom/cdrom.c Sun Mar 14 14:20:06 2004 +++ b/drivers/cdrom/cdrom.c Sun Mar 14 14:20:06 2004 @@ -406,6 +406,11 @@ if (CDROM_CAN(CDC_MRW_W)) cdi->exit = cdrom_mrw_exit; + if (cdi->disk) + cdi->cdda_method = CDDA_BPC_FULL; + else + cdi->cdda_method = CDDA_OLD; + cdinfo(CD_REG_UNREG, "drive \"/dev/%s\" registered\n", cdi->name); spin_lock(&cdrom_lock); cdi->next = topCdromPtr; @@ -1788,6 +1793,149 @@ return cdo->generic_packet(cdi, cgc); } +static int cdrom_read_cdda_old(struct cdrom_device_info *cdi, __u8 __user *ubuf, + int lba, int nframes) +{ + struct cdrom_generic_command cgc; + int nr, ret; + + memset(&cgc, 0, sizeof(cgc)); + + /* + * start with will ra.nframes size, back down if alloc fails + */ + nr = nframes; + do { + cgc.buffer = kmalloc(CD_FRAMESIZE_RAW * nr, GFP_KERNEL); + if (cgc.buffer) + break; + + nr >>= 1; + } while (nr); + + if (!nr) + return -ENOMEM; + + if (!access_ok(VERIFY_WRITE, ubuf, nframes * CD_FRAMESIZE_RAW)) { + kfree(cgc.buffer); + return -EFAULT; + } + + cgc.data_direction = CGC_DATA_READ; + while (nframes > 0) { + if (nr > nframes) + nr = nframes; + + ret = cdrom_read_block(cdi, &cgc, lba, nr, 1, CD_FRAMESIZE_RAW); + if (ret) + break; + __copy_to_user(ubuf, cgc.buffer, CD_FRAMESIZE_RAW * nr); + ubuf += CD_FRAMESIZE_RAW * nr; + nframes -= nr; + lba += nr; + } + kfree(cgc.buffer); + return 0; +} + +static int cdrom_read_cdda_bpc(struct cdrom_device_info *cdi, __u8 __user *ubuf, + int lba, int nframes) +{ + request_queue_t *q = cdi->disk->queue; + struct request *rq; + unsigned int len; + int nr, ret = 0; + + if (!q) + return -ENXIO; + + while (nframes) { + nr = nframes; + if (cdi->cdda_method == CDDA_BPC_SINGLE) + nr = 1; + if (nr * CD_FRAMESIZE_RAW > (q->max_sectors << 9)) + nr = (q->max_sectors << 9) / CD_FRAMESIZE_RAW; + + len = nr * CD_FRAMESIZE_RAW; + + rq = blk_rq_map_user(q, READ, ubuf, len); + if (IS_ERR(rq)) + return PTR_ERR(rq); + + memset(rq->cmd, 0, sizeof(rq->cmd)); + rq->cmd[0] = GPCMD_READ_CD; + rq->cmd[1] = 1 << 2; + rq->cmd[2] = (lba >> 24) & 0xff; + rq->cmd[3] = (lba >> 16) & 0xff; + rq->cmd[4] = (lba >> 8) & 0xff; + rq->cmd[5] = lba & 0xff; + rq->cmd[6] = (nr >> 16) & 0xff; + rq->cmd[7] = (nr >> 8) & 0xff; + rq->cmd[8] = nr & 0xff; + rq->cmd[9] = 0xf8; + + rq->cmd_len = 12; + rq->flags |= REQ_BLOCK_PC; + rq->timeout = 60 * HZ; + + if (blk_execute_rq(q, cdi->disk, rq)) { + struct request_sense *s = rq->sense; + ret = -EIO; + cdi->last_sense = s->sense_key; + } + + if (blk_rq_unmap_user(rq, ubuf, len)) + ret = -EFAULT; + + if (ret) + break; + + nframes -= nr; + lba += nr; + } + + return ret; +} + +static int cdrom_read_cdda(struct cdrom_device_info *cdi, __u8 __user *ubuf, + int lba, int nframes) +{ + int ret; + + if (cdi->cdda_method == CDDA_OLD) + return cdrom_read_cdda_old(cdi, ubuf, lba, nframes); + +retry: + /* + * for anything else than success and io error, we need to retry + */ + ret = cdrom_read_cdda_bpc(cdi, ubuf, lba, nframes); + if (!ret || ret != -EIO) + return ret; + + /* + * I've seen drives get sense 4/8/3 udma crc errors on multi + * frame dma, so drop to single frame dma if we need to + */ + if (cdi->cdda_method == CDDA_BPC_FULL && nframes > 1) { + printk("cdrom: dropping to single frame dma\n"); + cdi->cdda_method = CDDA_BPC_SINGLE; + goto retry; + } + + /* + * so we have an io error of some sort with multi frame dma. if the + * condition wasn't a hardware error + * problems, not for any error + */ + if (cdi->last_sense != 0x04 && cdi->last_sense != 0x0b) + return ret; + + printk("cdrom: dropping to old style cdda (sense=%x)\n", cdi->last_sense); + cdi->cdda_method = CDDA_OLD; + return cdrom_read_cdda_old(cdi, ubuf, lba, nframes); +} + /* Just about every imaginable ioctl is supported in the Uniform layer * these days. ATAPI / SCSI specific code now mainly resides in * mmc_ioct(). @@ -2280,7 +2428,7 @@ } case CDROMREADAUDIO: { struct cdrom_read_audio ra; - int lba, nr; + int lba; IOCTL_IN(arg, struct cdrom_read_audio, ra); @@ -2297,40 +2445,7 @@ if (lba < 0 || ra.nframes <= 0 || ra.nframes > CD_FRAMES) return -EINVAL; - /* - * start with will ra.nframes size, back down if alloc fails - */ - nr = ra.nframes; - do { - cgc.buffer = kmalloc(CD_FRAMESIZE_RAW * nr, GFP_KERNEL); - if (cgc.buffer) - break; - - nr >>= 1; - } while (nr); - - if (!nr) - return -ENOMEM; - - if (!access_ok(VERIFY_WRITE, ra.buf, ra.nframes*CD_FRAMESIZE_RAW)) { - kfree(cgc.buffer); - return -EFAULT; - } - cgc.data_direction = CGC_DATA_READ; - while (ra.nframes > 0) { - if (nr > ra.nframes) - nr = ra.nframes; - - ret = cdrom_read_block(cdi, &cgc, lba, nr, 1, CD_FRAMESIZE_RAW); - if (ret) - break; - __copy_to_user(ra.buf, cgc.buffer, CD_FRAMESIZE_RAW*nr); - ra.buf += CD_FRAMESIZE_RAW * nr; - ra.nframes -= nr; - lba += nr; - } - kfree(cgc.buffer); - return ret; + return cdrom_read_cdda(cdi, ra.buf, lba, ra.nframes); } case CDROMSUBCHNL: { struct cdrom_subchnl q; diff -Nru a/drivers/char/Kconfig b/drivers/char/Kconfig --- a/drivers/char/Kconfig Sun Mar 14 14:20:06 2004 +++ b/drivers/char/Kconfig Sun Mar 14 14:20:06 2004 @@ -740,6 +740,7 @@ config NVRAM tristate "/dev/nvram support" + depends on ATARI || X86 || X86_64 || ARM || GENERIC_NVRAM ---help--- If you say Y here and create a character special file /dev/nvram with major number 10 and minor number 144 using mknod ("man mknod"), diff -Nru a/drivers/char/applicom.c b/drivers/char/applicom.c --- a/drivers/char/applicom.c Sun Mar 14 14:20:08 2004 +++ b/drivers/char/applicom.c Sun Mar 14 14:20:08 2004 @@ -29,6 +29,7 @@ #include #include #include +#include #include #include diff -Nru a/drivers/char/genrtc.c b/drivers/char/genrtc.c --- a/drivers/char/genrtc.c Sun Mar 14 14:20:08 2004 +++ b/drivers/char/genrtc.c Sun Mar 14 14:20:08 2004 @@ -466,6 +466,17 @@ return len; } +static int __init gen_rtc_proc_init(void) +{ + struct proc_dir_entry *r; + + r = create_proc_read_entry("driver/rtc", 0, 0, gen_rtc_read_proc, NULL); + if (!r) + return -ENOMEM; + return 0; +} +#else +static inline int gen_rtc_proc_init(void) { return 0; } #endif /* CONFIG_PROC_FS */ @@ -498,15 +509,14 @@ printk(KERN_INFO "Generic RTC Driver v%s\n", RTC_VERSION); retval = misc_register(&rtc_gen_dev); - if(retval < 0) + if (retval < 0) return retval; -#ifdef CONFIG_PROC_FS - if((create_proc_read_entry ("driver/rtc", 0, 0, gen_rtc_read_proc, NULL)) == NULL){ + retval = gen_rtc_proc_init(); + if (retval) { misc_deregister(&rtc_gen_dev); - return -ENOMEM; + return retval; } -#endif return 0; } diff -Nru a/drivers/char/pcmcia/synclink_cs.c b/drivers/char/pcmcia/synclink_cs.c --- a/drivers/char/pcmcia/synclink_cs.c Sun Mar 14 14:20:07 2004 +++ b/drivers/char/pcmcia/synclink_cs.c Sun Mar 14 14:20:07 2004 @@ -1,7 +1,7 @@ /* * linux/drivers/char/pcmcia/synclink_cs.c * - * $Id: synclink_cs.c,v 4.15 2003/09/05 15:26:02 paulkf Exp $ + * $Id: synclink_cs.c,v 4.21 2004/03/08 15:29:23 paulkf Exp $ * * Device driver for Microgate SyncLink PC Card * multiprotocol serial adapter. @@ -489,7 +489,7 @@ MODULE_LICENSE("GPL"); static char *driver_name = "SyncLink PC Card driver"; -static char *driver_version = "$Revision: 4.15 $"; +static char *driver_version = "$Revision: 4.21 $"; static struct tty_driver *serial_driver; @@ -4233,12 +4233,13 @@ info->if_ptr = &info->pppdev; info->netdev = info->pppdev.dev = d; - sppp_attach(&info->pppdev); - d->base_addr = info->io_base; d->irq = info->irq_level; d->priv = info; + sppp_attach(&info->pppdev); + mgslpc_setup(d); + if (register_netdev(d)) { printk(KERN_WARNING "%s: register_netdev failed.\n", d->name); sppp_detach(info->netdev); @@ -4413,7 +4414,7 @@ int mgslpc_sppp_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) { - MGSLPC_INFO *info = (MGSLPC_INFO *)dev->priv; + MGSLPC_INFO *info = dev->priv; if (debug_level >= DEBUG_LEVEL_INFO) printk("%s(%d):mgslpc_ioctl %s cmd=%08X\n", __FILE__,__LINE__, info->netname, cmd ); diff -Nru a/drivers/char/sn_serial.c b/drivers/char/sn_serial.c --- a/drivers/char/sn_serial.c Sun Mar 14 14:20:08 2004 +++ b/drivers/char/sn_serial.c Sun Mar 14 14:20:08 2004 @@ -82,7 +82,6 @@ static unsigned long sn_interrupt_timeout; extern u64 master_node_bedrock_address; - static int sn_debug_printf(const char *fmt, ...); #undef DEBUG @@ -105,7 +104,6 @@ static struct sn_sal_ops *sn_func; /* Prototypes */ -static void __init sn_sal_serial_console_init(void); static int snt_hw_puts(const char *, int); static int snt_poll_getc(void); static int snt_poll_input_pending(void); @@ -921,9 +919,6 @@ printk(KERN_ERR "sn_serial: Unable to register tty driver\n"); return retval; } -#ifdef CONFIG_SGI_L1_SERIAL_CONSOLE - sn_sal_serial_console_init(); -#endif /* CONFIG_SGI_L1_SERIAL_CONSOLE */ return 0; } @@ -952,6 +947,7 @@ sn_sal_console_write(struct console *co, const char *s, unsigned count) { unsigned long flags; + const char *s1; BUG_ON(!sn_sal_is_asynch); @@ -959,15 +955,36 @@ * oops, kdb, panic, etc. make sure they get it. */ if (spin_is_locked(&sn_sal_lock)) { synch_flush_xmit(); + /* Output '\r' before each '\n' */ + while ((s1 = memchr(s, '\n', count)) != NULL) { + sn_func->sal_puts(s, s1 - s); + sn_func->sal_puts("\r\n", 2); + count -= s1 + 1 - s; + s = s1 + 1; + } sn_func->sal_puts(s, count); } else if (in_interrupt()) { spin_lock_irqsave(&sn_sal_lock, flags); synch_flush_xmit(); spin_unlock_irqrestore(&sn_sal_lock, flags); + /* Output '\r' before each '\n' */ + while ((s1 = memchr(s, '\n', count)) != NULL) { + sn_func->sal_puts(s, s1 - s); + sn_func->sal_puts("\r\n", 2); + count -= s1 + 1 - s; + s = s1 + 1; + } sn_func->sal_puts(s, count); } else + /* Output '\r' before each '\n' */ + while ((s1 = memchr(s, '\n', count)) != NULL) { + sn_sal_write(NULL, 0, s, s1 - s); + sn_sal_write(NULL, 0, "\r\n", 2); + count -= s1 + 1 - s; + s = s1 + 1; + } sn_sal_write(NULL, 0, s, count); } @@ -993,7 +1010,7 @@ .index = -1 }; -static void __init +static int __init sn_sal_serial_console_init(void) { if (ia64_platform_is("sn2")) { @@ -1001,6 +1018,8 @@ sn_debug_printf("sn_sal_serial_console_init : register console\n"); register_console(&sal_console); } + return 0; } +console_initcall(sn_sal_serial_console_init); #endif /* CONFIG_SGI_L1_SERIAL_CONSOLE */ diff -Nru a/drivers/char/synclink.c b/drivers/char/synclink.c --- a/drivers/char/synclink.c Sun Mar 14 14:20:07 2004 +++ b/drivers/char/synclink.c Sun Mar 14 14:20:07 2004 @@ -1,7 +1,7 @@ /* * linux/drivers/char/synclink.c * - * $Id: synclink.c,v 4.16 2003/09/05 15:26:02 paulkf Exp $ + * $Id: synclink.c,v 4.21 2004/03/08 15:29:22 paulkf Exp $ * * Device driver for Microgate SyncLink ISA and PCI * high speed multiprotocol serial adapters. @@ -909,7 +909,7 @@ MODULE_PARM(txholdbufs,"1-" __MODULE_STRING(MAX_TOTAL_DEVICES) "i"); static char *driver_name = "SyncLink serial driver"; -static char *driver_version = "$Revision: 4.16 $"; +static char *driver_version = "$Revision: 4.21 $"; static int synclink_init_one (struct pci_dev *dev, const struct pci_device_id *ent); @@ -7846,13 +7846,14 @@ info->if_ptr = &info->pppdev; info->netdev = info->pppdev.dev = d; - sppp_attach(&info->pppdev); - d->base_addr = info->io_base; d->irq = info->irq_level; d->dma = info->dma_level; d->priv = info; + sppp_attach(&info->pppdev); + mgsl_setup(d); + if (register_netdev(d)) { printk(KERN_WARNING "%s: register_netdev failed.\n", d->name); sppp_detach(info->netdev); @@ -8022,7 +8023,7 @@ int mgsl_sppp_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) { - struct mgsl_struct *info = (struct mgsl_struct *)dev->priv; + struct mgsl_struct *info = dev->priv; if (debug_level >= DEBUG_LEVEL_INFO) printk("%s(%d):mgsl_ioctl %s cmd=%08X\n", __FILE__,__LINE__, info->netname, cmd ); diff -Nru a/drivers/char/synclinkmp.c b/drivers/char/synclinkmp.c --- a/drivers/char/synclinkmp.c Sun Mar 14 14:20:06 2004 +++ b/drivers/char/synclinkmp.c Sun Mar 14 14:20:06 2004 @@ -1,5 +1,5 @@ /* - * $Id: synclinkmp.c,v 4.14 2003/09/05 15:26:03 paulkf Exp $ + * $Id: synclinkmp.c,v 4.19 2004/03/08 15:29:23 paulkf Exp $ * * Device driver for Microgate SyncLink Multiport * high speed multiprotocol serial adapter. @@ -494,7 +494,7 @@ MODULE_PARM(dosyncppp,"1-" __MODULE_STRING(MAX_DEVICES) "i"); static char *driver_name = "SyncLink MultiPort driver"; -static char *driver_version = "$Revision: 4.14 $"; +static char *driver_version = "$Revision: 4.19 $"; static int synclinkmp_init_one(struct pci_dev *dev,const struct pci_device_id *ent); static void synclinkmp_remove_one(struct pci_dev *dev); @@ -1653,11 +1653,12 @@ info->if_ptr = &info->pppdev; info->netdev = info->pppdev.dev = d; - sppp_attach(&info->pppdev); - d->irq = info->irq_level; d->priv = info; + sppp_attach(&info->pppdev); + cb_setup(d); + if (register_netdev(d)) { printk(KERN_WARNING "%s: register_netdev failed.\n", d->name); sppp_detach(info->netdev); @@ -1828,7 +1829,7 @@ static int sppp_cb_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) { - SLMP_INFO *info = (SLMP_INFO *)dev->priv; + SLMP_INFO *info = dev->priv; if (debug_level >= DEBUG_LEVEL_INFO) printk("%s(%d):ioctl %s cmd=%08X\n", __FILE__,__LINE__, info->netname, cmd ); @@ -2604,7 +2605,7 @@ del_timer(&info->status_timer); if (info->tx_buf) { - free_page((unsigned long) info->tx_buf); + kfree(info->tx_buf); info->tx_buf = 0; } diff -Nru a/drivers/char/viocons.c b/drivers/char/viocons.c --- a/drivers/char/viocons.c Sun Mar 14 14:20:05 2004 +++ b/drivers/char/viocons.c Sun Mar 14 14:20:05 2004 @@ -1365,6 +1365,7 @@ viotty_driver->driver_name = "vioconsole"; viotty_driver->devfs_name = "vcs/"; viotty_driver->name = "tty"; + viotty_driver->name_base = 1; viotty_driver->major = TTY_MAJOR; viotty_driver->minor_start = 1; viotty_driver->type = TTY_DRIVER_TYPE_CONSOLE; diff -Nru a/drivers/char/watchdog/advantechwdt.c b/drivers/char/watchdog/advantechwdt.c --- a/drivers/char/watchdog/advantechwdt.c Sun Mar 14 14:20:07 2004 +++ b/drivers/char/watchdog/advantechwdt.c Sun Mar 14 14:20:07 2004 @@ -256,8 +256,6 @@ static struct notifier_block advwdt_notifier = { .notifier_call = advwdt_notify_sys, - .next = NULL, - .priority = 0, }; static int __init diff -Nru a/drivers/char/watchdog/alim1535_wdt.c b/drivers/char/watchdog/alim1535_wdt.c --- a/drivers/char/watchdog/alim1535_wdt.c Sun Mar 14 14:20:06 2004 +++ b/drivers/char/watchdog/alim1535_wdt.c Sun Mar 14 14:20:06 2004 @@ -385,8 +385,6 @@ static struct notifier_block ali_notifier = { .notifier_call = ali_notify_sys, - .next = NULL, - .priority = 0, }; /* diff -Nru a/drivers/char/watchdog/alim7101_wdt.c b/drivers/char/watchdog/alim7101_wdt.c --- a/drivers/char/watchdog/alim7101_wdt.c Sun Mar 14 14:20:08 2004 +++ b/drivers/char/watchdog/alim7101_wdt.c Sun Mar 14 14:20:08 2004 @@ -303,8 +303,6 @@ static struct notifier_block wdt_notifier= { .notifier_call = wdt_notify_sys, - .next = 0, - .priority = 0, }; static void __exit alim7101_wdt_unload(void) diff -Nru a/drivers/char/watchdog/amd7xx_tco.c b/drivers/char/watchdog/amd7xx_tco.c --- a/drivers/char/watchdog/amd7xx_tco.c Sun Mar 14 14:20:06 2004 +++ b/drivers/char/watchdog/amd7xx_tco.c Sun Mar 14 14:20:06 2004 @@ -365,25 +365,6 @@ unregister_reboot_notifier(&amdtco_notifier); } - -#ifndef MODULE -static int __init amdtco_setup(char *str) -{ - int ints[4]; - - str = get_options (str, ARRAY_SIZE(ints), ints); - if (ints[0] > 0) - timeout = ints[1]; - - if (!timeout || timeout > MAX_TIMEOUT) - timeout = MAX_TIMEOUT; - - return 1; -} - -__setup("amd7xx_tco=", amdtco_setup); -#endif - module_init(amdtco_init); module_exit(amdtco_exit); diff -Nru a/drivers/char/watchdog/cpu5wdt.c b/drivers/char/watchdog/cpu5wdt.c --- a/drivers/char/watchdog/cpu5wdt.c Sun Mar 14 14:20:06 2004 +++ b/drivers/char/watchdog/cpu5wdt.c Sun Mar 14 14:20:06 2004 @@ -20,6 +20,7 @@ */ #include +#include #include #include #include @@ -295,11 +296,11 @@ MODULE_LICENSE("GPL"); MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR); -MODULE_PARM(port, "i"); +module_param(port, int, 0); MODULE_PARM_DESC(port, "base address of watchdog card, default is 0x91"); -MODULE_PARM(verbose, "i"); +module_param(verbose, int, 0); MODULE_PARM_DESC(verbose, "be verbose, default is 0 (no)"); -MODULE_PARM(ticks, "i"); +module_param(ticks, int, 0); MODULE_PARM_DESC(ticks, "count down ticks, default is 10000"); diff -Nru a/drivers/char/watchdog/eurotechwdt.c b/drivers/char/watchdog/eurotechwdt.c --- a/drivers/char/watchdog/eurotechwdt.c Sun Mar 14 14:20:06 2004 +++ b/drivers/char/watchdog/eurotechwdt.c Sun Mar 14 14:20:06 2004 @@ -43,6 +43,7 @@ #include #include #include +#include #include #include #include @@ -77,7 +78,7 @@ static int nowayout = 0; #endif -MODULE_PARM(nowayout,"i"); +module_param(nowayout, int, 0); MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CONFIG_WATCHDOG_NOWAYOUT)"); /* @@ -94,41 +95,11 @@ #define WDT_TIMER_CFG 0xf3 -#ifndef MODULE - -/** - * eurwdt_setup: - * @str: command line string - * - * Setup options. The board isn't really probe-able so we have to - * get the user to tell us the configuration. Sane people build it - * modular but the others come here. - */ - -static int __init eurwdt_setup(char *str) -{ - int ints[4]; - -str = get_options (str, ARRAY_SIZE(ints), ints); - - if (ints[0] > 0) { - io = ints[1]; - if (ints[0] > 1) - irq = ints[2]; - } - - return 1; -} - -__setup("eurwdt=", eurwdt_setup); - -#endif /* !MODULE */ - -MODULE_PARM(io, "i"); +module_param(io, int, 0); MODULE_PARM_DESC(io, "Eurotech WDT io port (default=0x3f0)"); -MODULE_PARM(irq, "i"); +module_param(irq, int, 0); MODULE_PARM_DESC(irq, "Eurotech WDT irq (default=10)"); -MODULE_PARM(ev, "s"); +module_param(ev, charp, 0); MODULE_PARM_DESC(ev, "Eurotech WDT event type (default is `int')"); diff -Nru a/drivers/char/watchdog/ib700wdt.c b/drivers/char/watchdog/ib700wdt.c --- a/drivers/char/watchdog/ib700wdt.c Sun Mar 14 14:20:08 2004 +++ b/drivers/char/watchdog/ib700wdt.c Sun Mar 14 14:20:08 2004 @@ -284,8 +284,6 @@ static struct notifier_block ibwdt_notifier = { .notifier_call = ibwdt_notify_sys, - .next = NULL, - .priority = 0, }; static int __init ibwdt_init(void) diff -Nru a/drivers/char/watchdog/machzwd.c b/drivers/char/watchdog/machzwd.c --- a/drivers/char/watchdog/machzwd.c Sun Mar 14 14:20:06 2004 +++ b/drivers/char/watchdog/machzwd.c Sun Mar 14 14:20:06 2004 @@ -447,8 +447,6 @@ */ static struct notifier_block zf_notifier = { .notifier_call = zf_notify_sys, - .next = NULL, - .priority = 0, }; static void __init zf_show_action(int act) diff -Nru a/drivers/char/watchdog/pcwd_pci.c b/drivers/char/watchdog/pcwd_pci.c --- a/drivers/char/watchdog/pcwd_pci.c Sun Mar 14 14:20:06 2004 +++ b/drivers/char/watchdog/pcwd_pci.c Sun Mar 14 14:20:06 2004 @@ -49,7 +49,7 @@ /* Module and version information */ #define WATCHDOG_VERSION "1.00" -#define WATCHDOG_DATE "09/02/2004" +#define WATCHDOG_DATE "13/03/2004" #define WATCHDOG_DRIVER_NAME "PCI-PC Watchdog" #define WATCHDOG_NAME "pcwd_pci" #define PFX WATCHDOG_NAME ": " @@ -82,6 +82,9 @@ #define CMD_READ_WATCHDOG_TIMEOUT 0x18 #define CMD_WRITE_WATCHDOG_TIMEOUT 0x19 +/* We can only use 1 card due to the /dev/watchdog restriction */ +static int cards_found; + /* internal variables */ static int temp_panic; static unsigned long is_active; @@ -505,7 +508,6 @@ static int __devinit pcipcwd_card_init(struct pci_dev *pdev, const struct pci_device_id *ent) { - static int cards_found; int ret = -EIO; int got_fw_rev, fw_rev_major, fw_rev_minor; char fw_ver_str[20]; @@ -527,7 +529,8 @@ if (pci_resource_start(pdev, 0) == 0x0000) { printk(KERN_ERR PFX "No I/O-Address for card detected\n"); - return -ENODEV; + ret = -ENODEV; + goto err_out_disable_device; } pcipcwd_private.pdev = pdev; @@ -643,6 +646,7 @@ unregister_reboot_notifier(&pcipcwd_notifier); pci_release_regions(pdev); pci_disable_device(pdev); + cards_found--; } static struct pci_device_id pcipcwd_pci_tbl[] = { diff -Nru a/drivers/char/watchdog/sbc60xxwdt.c b/drivers/char/watchdog/sbc60xxwdt.c --- a/drivers/char/watchdog/sbc60xxwdt.c Sun Mar 14 14:20:07 2004 +++ b/drivers/char/watchdog/sbc60xxwdt.c Sun Mar 14 14:20:07 2004 @@ -322,8 +322,6 @@ static struct notifier_block wdt_notifier= { .notifier_call = wdt_notify_sys, - .next = NULL, - .priority = 0, }; static void __exit sbc60xxwdt_unload(void) diff -Nru a/drivers/char/watchdog/sc1200wdt.c b/drivers/char/watchdog/sc1200wdt.c --- a/drivers/char/watchdog/sc1200wdt.c Sun Mar 14 14:20:06 2004 +++ b/drivers/char/watchdog/sc1200wdt.c Sun Mar 14 14:20:06 2004 @@ -29,6 +29,7 @@ #include #include +#include #include #include #include @@ -80,13 +81,13 @@ static int isapnp = 1; static struct pnp_dev *wdt_dev; -MODULE_PARM(isapnp, "i"); +module_param(isapnp, int, 0); MODULE_PARM_DESC(isapnp, "When set to 0 driver ISA PnP support will be disabled"); #endif -MODULE_PARM(io, "i"); +module_param(io, int, 0); MODULE_PARM_DESC(io, "io port"); -MODULE_PARM(timeout, "i"); +module_param(timeout, int, 0); MODULE_PARM_DESC(timeout, "range is 0-255 minutes, default is 1"); #ifdef CONFIG_WATCHDOG_NOWAYOUT @@ -95,7 +96,7 @@ static int nowayout = 0; #endif -MODULE_PARM(nowayout,"i"); +module_param(nowayout, int, 0); MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CONFIG_WATCHDOG_NOWAYOUT)"); @@ -453,32 +454,6 @@ #endif release_region(io, io_len); } - - -#ifndef MODULE -static int __init sc1200wdt_setup(char *str) -{ - int ints[4]; - - str = get_options (str, ARRAY_SIZE(ints), ints); - - if (ints[0] > 0) { - io = ints[1]; - if (ints[0] > 1) - timeout = ints[2]; - -#if defined CONFIG_PNP - if (ints[0] > 2) - isapnp = ints[3]; -#endif - } - - return 1; -} - -__setup("sc1200wdt=", sc1200wdt_setup); -#endif /* MODULE */ - module_init(sc1200wdt_init); module_exit(sc1200wdt_exit); diff -Nru a/drivers/char/watchdog/sc520_wdt.c b/drivers/char/watchdog/sc520_wdt.c --- a/drivers/char/watchdog/sc520_wdt.c Sun Mar 14 14:20:07 2004 +++ b/drivers/char/watchdog/sc520_wdt.c Sun Mar 14 14:20:07 2004 @@ -354,8 +354,6 @@ static struct notifier_block wdt_notifier= { .notifier_call = wdt_notify_sys, - .next = NULL, - .priority = 0, }; static void __exit sc520_wdt_unload(void) diff -Nru a/drivers/char/watchdog/w83627hf_wdt.c b/drivers/char/watchdog/w83627hf_wdt.c --- a/drivers/char/watchdog/w83627hf_wdt.c Sun Mar 14 14:20:07 2004 +++ b/drivers/char/watchdog/w83627hf_wdt.c Sun Mar 14 14:20:07 2004 @@ -257,8 +257,6 @@ static struct notifier_block wdt_notifier = { .notifier_call = wdt_notify_sys, - .next = NULL, - .priority = 0, }; static int __init diff -Nru a/drivers/char/watchdog/w83877f_wdt.c b/drivers/char/watchdog/w83877f_wdt.c --- a/drivers/char/watchdog/w83877f_wdt.c Sun Mar 14 14:20:07 2004 +++ b/drivers/char/watchdog/w83877f_wdt.c Sun Mar 14 14:20:07 2004 @@ -341,8 +341,6 @@ static struct notifier_block wdt_notifier= { .notifier_call = wdt_notify_sys, - .next = NULL, - .priority = 0, }; static void __exit w83877f_wdt_unload(void) diff -Nru a/drivers/char/watchdog/wafer5823wdt.c b/drivers/char/watchdog/wafer5823wdt.c --- a/drivers/char/watchdog/wafer5823wdt.c Sun Mar 14 14:20:08 2004 +++ b/drivers/char/watchdog/wafer5823wdt.c Sun Mar 14 14:20:08 2004 @@ -252,8 +252,6 @@ static struct notifier_block wafwdt_notifier = { .notifier_call = wafwdt_notify_sys, - .next = NULL, - .priority = 0, }; static int __init wafwdt_init(void) diff -Nru a/drivers/char/watchdog/wdt.c b/drivers/char/watchdog/wdt.c --- a/drivers/char/watchdog/wdt.c Sun Mar 14 14:20:07 2004 +++ b/drivers/char/watchdog/wdt.c Sun Mar 14 14:20:07 2004 @@ -34,6 +34,7 @@ #include #include #include +#include #include #include #include @@ -70,43 +71,12 @@ static int nowayout = 0; #endif -MODULE_PARM(nowayout,"i"); +module_param(nowayout, int, 0); MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CONFIG_WATCHDOG_NOWAYOUT)"); -#ifndef MODULE - -/** - * wdt_setup: - * @str: command line string - * - * Setup options. The board isn't really probe-able so we have to - * get the user to tell us the configuration. Sane people build it - * modular but the others come here. - */ - -static int __init wdt_setup(char *str) -{ - int ints[4]; - - str = get_options (str, ARRAY_SIZE(ints), ints); - - if (ints[0] > 0) - { - io = ints[1]; - if(ints[0] > 1) - irq = ints[2]; - } - - return 1; -} - -__setup("wdt=", wdt_setup); - -#endif /* !MODULE */ - -MODULE_PARM(io, "i"); +module_param(io, int, 0); MODULE_PARM_DESC(io, "WDT io port (default=0x240)"); -MODULE_PARM(irq, "i"); +module_param(irq, int, 0); MODULE_PARM_DESC(irq, "WDT irq (default=11)"); /* @@ -489,8 +459,6 @@ static struct notifier_block wdt_notifier= { .notifier_call = wdt_notify_sys, - .next = NULL, - .priority = 0, }; /** diff -Nru a/drivers/char/watchdog/wdt977.c b/drivers/char/watchdog/wdt977.c --- a/drivers/char/watchdog/wdt977.c Sun Mar 14 14:20:08 2004 +++ b/drivers/char/watchdog/wdt977.c Sun Mar 14 14:20:08 2004 @@ -1,5 +1,5 @@ /* - * Wdt977 0.02: A Watchdog Device for Netwinder W83977AF chip + * Wdt977 0.03: A Watchdog Device for Netwinder W83977AF chip * * (c) Copyright 1998 Rebel.com (Woody Suwalski ) * @@ -29,24 +29,27 @@ #include #include #include +#include +#include #include #include #include #include +#define PFX "Wdt977: " #define WATCHDOG_MINOR 130 -#define DEFAULT_TIMEOUT 1 /* default timeout = 1 minute */ +#define DEFAULT_TIMEOUT 60 /* default timeout in seconds */ -static int timeout = DEFAULT_TIMEOUT*60; /* TO in seconds from user */ -static int timeoutM = DEFAULT_TIMEOUT; /* timeout in minutes */ +static int timeout = DEFAULT_TIMEOUT; +static int timeoutM; /* timeout in minutes */ static unsigned long timer_alive; static int testmode; static char expect_close; module_param(timeout, int, 0); -MODULE_PARM_DESC(timeout,"Watchdog timeout in seconds (60..15300), default=60"); +MODULE_PARM_DESC(timeout,"Watchdog timeout in seconds (60..15300), default=" __MODULE_STRING(DEFAULT_TIMEOUT) ")"); module_param(testmode, int, 0); MODULE_PARM_DESC(testmode,"Watchdog testmode (1 = no reboot), default=0"); @@ -59,21 +62,102 @@ module_param(nowayout, int, 0); MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CONFIG_WATCHDOG_NOWAYOUT)"); +/* + * Start the watchdog + */ -/* This is kicking the watchdog by simply re-writing the timeout to reg. 0xF2 */ -static int kick_wdog(void) +static int wdt977_start(void) { - /* - * Refresh the timer. + /* unlock the SuperIO chip */ + outb(0x87,0x370); + outb(0x87,0x370); + + /* select device Aux2 (device=8) and set watchdog regs F2, F3 and F4 + * F2 has the timeout in minutes + * F3 could be set to the POWER LED blink (with GP17 set to PowerLed) + * at timeout, and to reset timer on kbd/mouse activity (not impl.) + * F4 is used to just clear the TIMEOUT'ed state (bit 0) */ + outb(0x07,0x370); + outb(0x08,0x371); + outb(0xF2,0x370); + outb(timeoutM,0x371); + outb(0xF3,0x370); + outb(0x00,0x371); /* another setting is 0E for kbd/mouse/LED */ + outb(0xF4,0x370); + outb(0x00,0x371); + + /* at last select device Aux1 (dev=7) and set GP16 as a watchdog output */ + /* in test mode watch the bit 1 on F4 to indicate "triggered" */ + if (!testmode) + { + outb(0x07,0x370); + outb(0x07,0x371); + outb(0xE6,0x370); + outb(0x08,0x371); + } + /* lock the SuperIO chip */ + outb(0xAA,0x370); + + printk(KERN_INFO PFX "activated.\n"); + + return 0; +} + +/* + * Stop the watchdog + */ + +static int wdt977_stop(void) +{ + /* unlock the SuperIO chip */ + outb(0x87,0x370); + outb(0x87,0x370); + + /* select device Aux2 (device=8) and set watchdog regs F2,F3 and F4 + * F3 is reset to its default state + * F4 can clear the TIMEOUT'ed state (bit 0) - back to default + * We can not use GP17 as a PowerLed, as we use its usage as a RedLed + */ + outb(0x07,0x370); + outb(0x08,0x371); + outb(0xF2,0x370); + outb(0xFF,0x371); + outb(0xF3,0x370); + outb(0x00,0x371); + outb(0xF4,0x370); + outb(0x00,0x371); + outb(0xF2,0x370); + outb(0x00,0x371); + + /* at last select device Aux1 (dev=7) and set GP16 as a watchdog output */ + outb(0x07,0x370); + outb(0x07,0x371); + outb(0xE6,0x370); + outb(0x08,0x371); + + /* lock the SuperIO chip */ + outb(0xAA,0x370); + + printk(KERN_INFO PFX "shutdown.\n"); + + return 0; +} + +/* + * Send a keepalive ping to the watchdog + * This is done by simply re-writing the timeout to reg. 0xF2 + */ + +static int wdt977_keepalive(void) +{ /* unlock the SuperIO chip */ outb(0x87,0x370); outb(0x87,0x370); /* select device Aux2 (device=8) and kicks watchdog reg F2 */ /* F2 has the timeout in minutes */ - outb(0x07,0x370); outb(0x08,0x371); outb(0xF2,0x370); @@ -85,77 +169,77 @@ return 0; } - /* - * Allow only one person to hold it open + * Set the watchdog timeout value */ -static int wdt977_open(struct inode *inode, struct file *file) +static int wdt977_set_timeout(int t) { - - if( test_and_set_bit(0,&timer_alive) ) - return -EBUSY; + int tmrval; /* convert seconds to minutes, rounding up */ - timeoutM = timeout + 59; - timeoutM /= 60; - - if (nowayout) - { - __module_get(THIS_MODULE); + tmrval = (t + 59) / 60; - /* do not permit disabling the watchdog by writing 0 to reg. 0xF2 */ - if (!timeoutM) timeoutM = DEFAULT_TIMEOUT; - } - - if (machine_is_netwinder()) - { + if (machine_is_netwinder()) { /* we have a hw bug somewhere, so each 977 minute is actually only 30sec * this limits the max timeout to half of device max of 255 minutes... */ - timeoutM += timeoutM; + tmrval += tmrval; } - /* max timeout value = 255 minutes (0xFF). Write 0 to disable WatchDog. */ - if (timeoutM > 255) timeoutM = 255; + if ((tmrval < 1) || (tmrval > 255)) + return -EINVAL; - /* convert seconds to minutes */ - printk(KERN_INFO "Wdt977 Watchdog activated: timeout = %d sec, nowayout = %i, testmode = %i.\n", - machine_is_netwinder() ? (timeoutM>>1)*60 : timeoutM*60, - nowayout, testmode); + /* timeout is the timeout in seconds, timeoutM is the timeout in minutes) */ + timeout = t; + timeoutM = tmrval; + return 0; +} + +/* + * Get the watchdog status + */ + +static int wdt977_get_status(int *status) +{ + int new_status; + + *status=0; /* unlock the SuperIO chip */ outb(0x87,0x370); outb(0x87,0x370); - /* select device Aux2 (device=8) and set watchdog regs F2, F3 and F4 - * F2 has the timeout in minutes - * F3 could be set to the POWER LED blink (with GP17 set to PowerLed) - * at timeout, and to reset timer on kbd/mouse activity (not impl.) - * F4 is used to just clear the TIMEOUT'ed state (bit 0) - */ + /* select device Aux2 (device=8) and read watchdog reg F4 */ outb(0x07,0x370); outb(0x08,0x371); - outb(0xF2,0x370); - outb(timeoutM,0x371); - outb(0xF3,0x370); - outb(0x00,0x371); /* another setting is 0E for kbd/mouse/LED */ outb(0xF4,0x370); - outb(0x00,0x371); - - /* at last select device Aux1 (dev=7) and set GP16 as a watchdog output */ - /* in test mode watch the bit 1 on F4 to indicate "triggered" */ - if (!testmode) - { - outb(0x07,0x370); - outb(0x07,0x371); - outb(0xE6,0x370); - outb(0x08,0x371); - } + new_status = inb(0x371); /* lock the SuperIO chip */ outb(0xAA,0x370); + if (new_status & 1) + *status |= WDIOF_CARDRESET; + + return 0; +} + + +/* + * /dev/watchdog handling + */ + +static int wdt977_open(struct inode *inode, struct file *file) +{ + /* If the watchdog is alive we don't need to start it again */ + if( test_and_set_bit(0,&timer_alive) ) + return -EBUSY; + + if (nowayout) + __module_get(THIS_MODULE); + + wdt977_start(); return 0; } @@ -167,40 +251,11 @@ */ if (expect_close == 42) { - /* unlock the SuperIO chip */ - outb(0x87,0x370); - outb(0x87,0x370); - - /* select device Aux2 (device=8) and set watchdog regs F2,F3 and F4 - * F3 is reset to its default state - * F4 can clear the TIMEOUT'ed state (bit 0) - back to default - * We can not use GP17 as a PowerLed, as we use its usage as a RedLed - */ - outb(0x07,0x370); - outb(0x08,0x371); - outb(0xF2,0x370); - outb(0xFF,0x371); - outb(0xF3,0x370); - outb(0x00,0x371); - outb(0xF4,0x370); - outb(0x00,0x371); - outb(0xF2,0x370); - outb(0x00,0x371); - - /* at last select device Aux1 (dev=7) and set GP16 as a watchdog output */ - outb(0x07,0x370); - outb(0x07,0x371); - outb(0xE6,0x370); - outb(0x08,0x371); - - /* lock the SuperIO chip */ - outb(0xAA,0x370); - + wdt977_stop(); clear_bit(0,&timer_alive); - - printk(KERN_INFO "Wdt977 Watchdog: shutdown\n"); } else { - printk(KERN_CRIT "WDT device closed unexpectedly. WDT will not stop!\n"); + printk(KERN_CRIT PFX "Unexpected close, not stopping watchdog!\n"); + wdt977_keepalive(); } expect_close = 0; return 0; @@ -240,7 +295,7 @@ } } - kick_wdog(); + wdt977_keepalive(); } return count; } @@ -257,14 +312,19 @@ */ static struct watchdog_info ident = { - .options = WDIOF_SETTIMEOUT, - .identity = "Winbond 83977", + .options = WDIOF_SETTIMEOUT | + WDIOF_MAGICCLOSE | + WDIOF_KEEPALIVEPING, + .firmware_version = 1, + .identity = "Winbond 83977", }; static int wdt977_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) { - int temp; + int status; + int new_options, retval = -EINVAL; + int new_timeout; switch(cmd) { @@ -272,62 +332,59 @@ return -ENOIOCTLCMD; case WDIOC_GETSUPPORT: - return copy_to_user((struct watchdog_info *)arg, &ident, + return copy_to_user((struct watchdog_info *)arg, &ident, sizeof(ident)) ? -EFAULT : 0; + case WDIOC_GETSTATUS: + wdt977_get_status(&status); + return put_user(status, (int *) arg); + case WDIOC_GETBOOTSTATUS: return put_user(0, (int *) arg); - case WDIOC_GETSTATUS: - /* unlock the SuperIO chip */ - outb(0x87,0x370); - outb(0x87,0x370); + case WDIOC_KEEPALIVE: + wdt977_keepalive(); + return 0; - /* select device Aux2 (device=8) and read watchdog reg F4 */ - outb(0x07,0x370); - outb(0x08,0x371); - outb(0xF4,0x370); - temp = inb(0x371); + case WDIOC_SETOPTIONS: + if (get_user (new_options, (int *) arg)) + return -EFAULT; - /* lock the SuperIO chip */ - outb(0xAA,0x370); + if (new_options & WDIOS_DISABLECARD) { + wdt977_stop(); + retval = 0; + } - /* return info if "expired" in test mode */ - return put_user(temp & 1, (int *) arg); + if (new_options & WDIOS_ENABLECARD) { + wdt977_start(); + retval = 0; + } - case WDIOC_KEEPALIVE: - kick_wdog(); - return 0; + return retval; case WDIOC_SETTIMEOUT: - if (copy_from_user(&temp, (int *) arg, sizeof(int))) + if (get_user(new_timeout, (int *) arg)) return -EFAULT; - /* convert seconds to minutes, rounding up */ - temp += 59; - temp /= 60; - - /* we have a hw bug somewhere, so each 977 minute is actually only 30sec - * this limits the max timeout to half of device max of 255 minutes... - */ - if (machine_is_netwinder()) - { - temp += temp; - } + if (wdt977_set_timeout(new_timeout)) + return -EINVAL; - /* Sanity check */ - if (temp < 0 || temp > 255) - return -EINVAL; + wdt977_keepalive(); + /* Fall */ - if (!temp && nowayout) - return -EINVAL; + case WDIOC_GETTIMEOUT: + return put_user(timeout, (int *)arg); - timeoutM = temp; - kick_wdog(); - return 0; } } +static int wdt977_notify_sys(struct notifier_block *this, unsigned long code, + void *unused) +{ + if(code==SYS_DOWN || code==SYS_HALT) + wdt977_stop(); + return NOTIFY_DONE; +} static struct file_operations wdt977_fops= { @@ -345,21 +402,48 @@ .fops = &wdt977_fops, }; +static struct notifier_block wdt977_notifier = { + .notifier_call = wdt977_notify_sys, +}; + static int __init nwwatchdog_init(void) { int retval; if (!machine_is_netwinder()) return -ENODEV; + /* Check that the timeout value is within it's range ; if not reset to the default */ + if (wdt977_set_timeout(timeout)) { + wdt977_set_timeout(DEFAULT_TIMEOUT); + printk(KERN_INFO PFX "timeout value must be 60dev.parent = root->dev; edev->dev.bus = &eisa_bus_type; edev->dev.dma_mask = &edev->dma_mask; + edev->dev.coherent_dma_mask = edev->dma_mask; sprintf (edev->dev.bus_id, "%02X:%02X", root->bus_nr, slot); for (i = 0; i < EISA_MAX_RESOURCES; i++) { diff -Nru a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c --- a/drivers/ide/ide-cd.c Sun Mar 14 14:20:07 2004 +++ b/drivers/ide/ide-cd.c Sun Mar 14 14:20:07 2004 @@ -2931,6 +2931,7 @@ if (!CDROM_CONFIG_FLAGS(drive)->mrw_w) devinfo->mask |= CDC_MRW_W; + devinfo->disk = drive->disk; return register_cdrom(devinfo); } diff -Nru a/drivers/ide/legacy/macide.c b/drivers/ide/legacy/macide.c --- a/drivers/ide/legacy/macide.c Sun Mar 14 14:20:05 2004 +++ b/drivers/ide/legacy/macide.c Sun Mar 14 14:20:05 2004 @@ -94,6 +94,7 @@ void macide_init(void) { hw_regs_t hw; + ide_hwif_t *hwif; int index = -1; switch (macintosh_config->ide_type) { @@ -102,21 +103,21 @@ 0, 0, macide_ack_intr, // quadra_ide_iops, IRQ_NUBUS_F); - index = ide_register_hw(&hw, NULL); + index = ide_register_hw(&hw, &hwif); break; case MAC_IDE_PB: ide_setup_ports(&hw, IDE_BASE, macide_offsets, 0, 0, macide_ack_intr, // macide_pb_iops, IRQ_NUBUS_C); - index = ide_register_hw(&hw, NULL); + index = ide_register_hw(&hw, &hwif); break; case MAC_IDE_BABOON: ide_setup_ports(&hw, BABOON_BASE, macide_offsets, 0, 0, NULL, // macide_baboon_iops, IRQ_BABOON_1); - index = ide_register_hw(&hw, NULL); + index = ide_register_hw(&hw, &hwif); if (index == -1) break; if (macintosh_config->ident == MAC_MODEL_PB190) { @@ -141,6 +142,7 @@ } if (index != -1) { + hwif->mmio = 2; if (macintosh_config->ide_type == MAC_IDE_QUADRA) printk(KERN_INFO "ide%d: Macintosh Quadra IDE interface\n", index); else if (macintosh_config->ide_type == MAC_IDE_PB) diff -Nru a/drivers/ieee1394/dma.c b/drivers/ieee1394/dma.c --- a/drivers/ieee1394/dma.c Sun Mar 14 14:20:07 2004 +++ b/drivers/ieee1394/dma.c Sun Mar 14 14:20:07 2004 @@ -168,7 +168,7 @@ return sg_dma_address(sg) + rem; } -void dma_region_sync(struct dma_region *dma, unsigned long offset, unsigned long len) +void dma_region_sync_for_cpu(struct dma_region *dma, unsigned long offset, unsigned long len) { int first, last; unsigned long rem; @@ -179,7 +179,21 @@ first = dma_region_find(dma, offset, &rem); last = dma_region_find(dma, offset + len - 1, &rem); - pci_dma_sync_sg(dma->dev, &dma->sglist[first], last - first + 1, dma->direction); + pci_dma_sync_sg_for_cpu(dma->dev, &dma->sglist[first], last - first + 1, dma->direction); +} + +void dma_region_sync_for_device(struct dma_region *dma, unsigned long offset, unsigned long len) +{ + int first, last; + unsigned long rem; + + if (!len) + len = 1; + + first = dma_region_find(dma, offset, &rem); + last = dma_region_find(dma, offset + len - 1, &rem); + + pci_dma_sync_sg_for_device(dma->dev, &dma->sglist[first], last - first + 1, dma->direction); } /* nopage() handler for mmap access */ diff -Nru a/drivers/ieee1394/dma.h b/drivers/ieee1394/dma.h --- a/drivers/ieee1394/dma.h Sun Mar 14 14:20:08 2004 +++ b/drivers/ieee1394/dma.h Sun Mar 14 14:20:08 2004 @@ -60,8 +60,10 @@ /* unmap and free the buffer */ void dma_region_free(struct dma_region *dma); -/* sync the IO bus' view of the buffer with the CPU's view */ -void dma_region_sync(struct dma_region *dma, unsigned long offset, unsigned long len); +/* sync the CPU's view of the buffer */ +void dma_region_sync_for_cpu(struct dma_region *dma, unsigned long offset, unsigned long len); +/* sync the IO bus' view of the buffer */ +void dma_region_sync_for_device(struct dma_region *dma, unsigned long offset, unsigned long len); /* map the buffer into a user space process */ int dma_region_mmap(struct dma_region *dma, struct file *file, struct vm_area_struct *vma); diff -Nru a/drivers/ieee1394/dv1394.c b/drivers/ieee1394/dv1394.c --- a/drivers/ieee1394/dv1394.c Sun Mar 14 14:20:08 2004 +++ b/drivers/ieee1394/dv1394.c Sun Mar 14 14:20:08 2004 @@ -553,7 +553,7 @@ *(f->frame_end_branch) = cpu_to_le32(f->descriptor_pool_dma | f->first_n_descriptors); /* make the latest version of this frame visible to the PCI card */ - dma_region_sync(&video->dv_buf, f->data - (unsigned long) video->dv_buf.kvirt, video->frame_size); + dma_region_sync_for_device(&video->dv_buf, f->data - (unsigned long) video->dv_buf.kvirt, video->frame_size); /* lock against DMA interrupt */ spin_lock_irqsave(&video->spinlock, irq_flags); @@ -2033,9 +2033,9 @@ struct packet *p = dma_region_i(&video->packet_buf, struct packet, video->current_packet); /* make sure we are seeing the latest changes to p */ - dma_region_sync(&video->packet_buf, - (unsigned long) p - (unsigned long) video->packet_buf.kvirt, - sizeof(struct packet)); + dma_region_sync_for_cpu(&video->packet_buf, + (unsigned long) p - (unsigned long) video->packet_buf.kvirt, + sizeof(struct packet)); packet_length = le16_to_cpu(p->data_length); packet_time = le16_to_cpu(p->timestamp); diff -Nru a/drivers/ieee1394/ieee1394_core.c b/drivers/ieee1394/ieee1394_core.c --- a/drivers/ieee1394/ieee1394_core.c Sun Mar 14 14:20:06 2004 +++ b/drivers/ieee1394/ieee1394_core.c Sun Mar 14 14:20:06 2004 @@ -1201,7 +1201,8 @@ EXPORT_SYMBOL(dma_region_init); EXPORT_SYMBOL(dma_region_alloc); EXPORT_SYMBOL(dma_region_free); -EXPORT_SYMBOL(dma_region_sync); +EXPORT_SYMBOL(dma_region_sync_for_cpu); +EXPORT_SYMBOL(dma_region_sync_for_device); EXPORT_SYMBOL(dma_region_mmap); EXPORT_SYMBOL(dma_region_offset_to_bus); diff -Nru a/drivers/ieee1394/ohci1394.c b/drivers/ieee1394/ohci1394.c --- a/drivers/ieee1394/ohci1394.c Sun Mar 14 14:20:08 2004 +++ b/drivers/ieee1394/ohci1394.c Sun Mar 14 14:20:08 2004 @@ -1732,7 +1732,7 @@ /* OK, the block is finished... */ /* sync our view of the block */ - dma_region_sync(&iso->data_buf, recv->block_dma*recv->buf_stride, recv->buf_stride); + dma_region_sync_for_cpu(&iso->data_buf, recv->block_dma*recv->buf_stride, recv->buf_stride); /* reset the DMA descriptor */ im->status = recv->buf_stride; @@ -1789,7 +1789,7 @@ } /* sync our view of the buffer */ - dma_region_sync(&iso->data_buf, iso->pkt_dma * recv->buf_stride, recv->buf_stride); + dma_region_sync_for_cpu(&iso->data_buf, iso->pkt_dma * recv->buf_stride, recv->buf_stride); /* record the per-packet info */ { @@ -2016,7 +2016,7 @@ sy = info->sy; /* sync up the card's view of the buffer */ - dma_region_sync(&iso->data_buf, offset, len); + dma_region_sync_for_device(&iso->data_buf, offset, len); /* append first_packet to the DMA chain */ /* by linking the previous descriptor to it */ diff -Nru a/drivers/ieee1394/sbp2.c b/drivers/ieee1394/sbp2.c --- a/drivers/ieee1394/sbp2.c Sun Mar 14 14:20:06 2004 +++ b/drivers/ieee1394/sbp2.c Sun Mar 14 14:20:06 2004 @@ -1948,12 +1948,12 @@ SBP2_ORB_DEBUG("sending command orb %p, total orbs = %x", command_orb, global_outstanding_command_orbs); - pci_dma_sync_single(hi->host->pdev, command->command_orb_dma, - sizeof(struct sbp2_command_orb), - PCI_DMA_BIDIRECTIONAL); - pci_dma_sync_single(hi->host->pdev, command->sge_dma, - sizeof(command->scatter_gather_element), - PCI_DMA_BIDIRECTIONAL); + pci_dma_sync_single_for_device(hi->host->pdev, command->command_orb_dma, + sizeof(struct sbp2_command_orb), + PCI_DMA_BIDIRECTIONAL); + pci_dma_sync_single_for_device(hi->host->pdev, command->sge_dma, + sizeof(command->scatter_gather_element), + PCI_DMA_BIDIRECTIONAL); /* * Check to see if there are any previous orbs to use */ @@ -1994,9 +1994,9 @@ cpu_to_be32(command->command_orb_dma); /* Tells hardware that this pointer is valid */ scsi_id->last_orb->next_ORB_hi = 0x0; - pci_dma_sync_single(hi->host->pdev, scsi_id->last_orb_dma, - sizeof(struct sbp2_command_orb), - PCI_DMA_BIDIRECTIONAL); + pci_dma_sync_single_for_device(hi->host->pdev, scsi_id->last_orb_dma, + sizeof(struct sbp2_command_orb), + PCI_DMA_BIDIRECTIONAL); /* * Ring the doorbell @@ -2358,12 +2358,12 @@ if (command) { SBP2_DEBUG("Found status for command ORB"); - pci_dma_sync_single(hi->host->pdev, command->command_orb_dma, - sizeof(struct sbp2_command_orb), - PCI_DMA_BIDIRECTIONAL); - pci_dma_sync_single(hi->host->pdev, command->sge_dma, - sizeof(command->scatter_gather_element), - PCI_DMA_BIDIRECTIONAL); + pci_dma_sync_single_for_cpu(hi->host->pdev, command->command_orb_dma, + sizeof(struct sbp2_command_orb), + PCI_DMA_BIDIRECTIONAL); + pci_dma_sync_single_for_cpu(hi->host->pdev, command->sge_dma, + sizeof(command->scatter_gather_element), + PCI_DMA_BIDIRECTIONAL); SBP2_ORB_DEBUG("matched command orb %p", &command->command_orb); outstanding_orb_decr; @@ -2534,12 +2534,12 @@ SBP2_DEBUG("Found pending command to complete"); lh = scsi_id->sbp2_command_orb_inuse.next; command = list_entry(lh, struct sbp2_command_info, list); - pci_dma_sync_single(hi->host->pdev, command->command_orb_dma, - sizeof(struct sbp2_command_orb), - PCI_DMA_BIDIRECTIONAL); - pci_dma_sync_single(hi->host->pdev, command->sge_dma, - sizeof(command->scatter_gather_element), - PCI_DMA_BIDIRECTIONAL); + pci_dma_sync_single_for_cpu(hi->host->pdev, command->command_orb_dma, + sizeof(struct sbp2_command_orb), + PCI_DMA_BIDIRECTIONAL); + pci_dma_sync_single_for_cpu(hi->host->pdev, command->sge_dma, + sizeof(command->scatter_gather_element), + PCI_DMA_BIDIRECTIONAL); sbp2util_mark_command_completed(scsi_id, command); if (command->Current_SCpnt) { void (*done)(Scsi_Cmnd *) = command->Current_done; @@ -2699,14 +2699,14 @@ command = sbp2util_find_command_for_SCpnt(scsi_id, SCpnt); if (command) { SBP2_DEBUG("Found command to abort"); - pci_dma_sync_single(hi->host->pdev, - command->command_orb_dma, - sizeof(struct sbp2_command_orb), - PCI_DMA_BIDIRECTIONAL); - pci_dma_sync_single(hi->host->pdev, - command->sge_dma, - sizeof(command->scatter_gather_element), - PCI_DMA_BIDIRECTIONAL); + pci_dma_sync_single_for_cpu(hi->host->pdev, + command->command_orb_dma, + sizeof(struct sbp2_command_orb), + PCI_DMA_BIDIRECTIONAL); + pci_dma_sync_single_for_cpu(hi->host->pdev, + command->sge_dma, + sizeof(command->scatter_gather_element), + PCI_DMA_BIDIRECTIONAL); sbp2util_mark_command_completed(scsi_id, command); if (command->Current_SCpnt) { void (*done)(Scsi_Cmnd *) = command->Current_done; diff -Nru a/drivers/macintosh/Kconfig b/drivers/macintosh/Kconfig --- a/drivers/macintosh/Kconfig Sun Mar 14 14:20:07 2004 +++ b/drivers/macintosh/Kconfig Sun Mar 14 14:20:07 2004 @@ -1,5 +1,6 @@ menu "Macintosh device drivers" + depends on PPC || MAC config ADB bool "Apple Desktop Bus (ADB) support" diff -Nru a/drivers/macintosh/mediabay.c b/drivers/macintosh/mediabay.c --- a/drivers/macintosh/mediabay.c Sun Mar 14 14:20:06 2004 +++ b/drivers/macintosh/mediabay.c Sun Mar 14 14:20:06 2004 @@ -10,8 +10,6 @@ * as published by the Free Software Foundation; either version * 2 of the License, or (at your option) any later version. */ -#define __KERNEL_SYSCALLS__ - #include #include #include @@ -21,7 +19,6 @@ #include #include #include -#include #include #include #include diff -Nru a/drivers/macintosh/therm_pm72.c b/drivers/macintosh/therm_pm72.c --- a/drivers/macintosh/therm_pm72.c Sun Mar 14 14:20:08 2004 +++ b/drivers/macintosh/therm_pm72.c Sun Mar 14 14:20:08 2004 @@ -2,7 +2,7 @@ * Device driver for the thermostats & fan controller of the * Apple G5 "PowerMac7,2" desktop machines. * - * (c) Copyright IBM Corp. 2003 + * (c) Copyright IBM Corp. 2003-2004 * * Maintained by: Benjamin Herrenschmidt * @@ -45,7 +45,7 @@ * - Add things like /sbin/overtemp for non-critical * overtemp conditions so userland can take some policy * decisions, like slewing down CPUs - * - Deal with fan failures + * - Deal with fan and i2c failures in a better way * * History: * @@ -63,9 +63,16 @@ * - Move back statics definitions to .c file * - Avoid calling schedule_timeout with a negative number * - * Dev. 18, 2003 : 0.8 + * Dec. 18, 2003 : 0.8 * - Fix typo when reading back fan speed on 2 CPU machines * + * Mar. 11, 2004 : 0.9 + * - Rework code accessing the ADC chips, make it more robust and + * closer to the chip spec. Also make sure it is configured properly, + * I've seen yet unexplained cases where on startup, I would have stale + * values in the configuration register + * - Switch back to use of target fan speed for PID, thus lowering + * pressure on i2c */ #include @@ -94,14 +101,14 @@ #include "therm_pm72.h" -#define VERSION "0.8" +#define VERSION "0.9" #undef DEBUG #ifdef DEBUG #define DBG(args...) printk(args) #else -#define DBG(args...) +#define DBG(args...) do { } while(0) #endif @@ -194,14 +201,76 @@ /* * Here are the i2c chip access wrappers */ -static int read_smon_adc(struct i2c_client *chip, int chan) + +static void initialize_adc(struct cpu_pid_state *state) +{ + int rc; + u8 buf[2]; + + /* Read ADC the configuration register and cache it. We + * also make sure Config2 contains proper values, I've seen + * cases where we got stale grabage in there, thus preventing + * proper reading of conv. values + */ + + /* Clear Config2 */ + buf[0] = 5; + buf[1] = 0; + i2c_master_send(state->monitor, buf, 2); + + /* Read & cache Config1 */ + buf[0] = 1; + rc = i2c_master_send(state->monitor, buf, 1); + if (rc > 0) { + rc = i2c_master_recv(state->monitor, buf, 1); + if (rc > 0) { + state->adc_config = buf[0]; + DBG("ADC config reg: %02x\n", state->adc_config); + /* Disable shutdown mode */ + state->adc_config &= 0xfe; + buf[0] = 1; + buf[1] = state->adc_config; + rc = i2c_master_send(state->monitor, buf, 2); + } + } + if (rc <= 0) + printk(KERN_ERR "therm_pm72: Error reading ADC config" + " register !\n"); +} + +static int read_smon_adc(struct cpu_pid_state *state, int chan) { - int ctrl; + int rc, data, tries = 0; + u8 buf[2]; - ctrl = i2c_smbus_read_byte_data(chip, 1); - i2c_smbus_write_byte_data(chip, 1, (ctrl & 0x1f) | (chan << 5)); - wait_ms(1); - return le16_to_cpu(i2c_smbus_read_word_data(chip, 4)) >> 6; + for (;;) { + /* Set channel */ + buf[0] = 1; + buf[1] = (state->adc_config & 0x1f) | (chan << 5); + rc = i2c_master_send(state->monitor, buf, 2); + if (rc <= 0) + goto error; + /* Wait for convertion */ + wait_ms(1); + /* Switch to data register */ + buf[0] = 4; + rc = i2c_master_send(state->monitor, buf, 1); + if (rc <= 0) + goto error; + /* Read result */ + rc = i2c_master_recv(state->monitor, buf, 2); + if (rc < 0) + goto error; + data = ((u16)buf[0]) << 8 | (u16)buf[1]; + return data >> 6; + error: + DBG("Error reading ADC, retrying...\n"); + if (++tries > 10) { + printk(KERN_ERR "therm_pm72: Error reading ADC !\n"); + return -1; + } + wait_ms(10); + } } static int fan_read_reg(int reg, unsigned char *buf, int nb) @@ -460,9 +529,13 @@ DBG(" current rpm: %d\n", state->rpm); /* Get some sensor readings and scale it */ - temp = read_smon_adc(state->monitor, 1); - voltage = read_smon_adc(state->monitor, 3); - current_a = read_smon_adc(state->monitor, 4); + temp = read_smon_adc(state, 1); + if (temp == -1) { + state->overtemp++; + return; + } + voltage = read_smon_adc(state, 3); + current_a = read_smon_adc(state, 4); /* Fixup temperature according to diode calibration */ @@ -476,7 +549,8 @@ * full blown immediately and try to trigger a shutdown */ if (temp >= ((state->mpu.tmax + 8) << 16)) { - printk(KERN_WARNING "Warning ! CPU %d temperature way above maximum (%d) !\n", + printk(KERN_WARNING "Warning ! CPU %d temperature way above maximum" + " (%d) !\n", state->index, temp >> 16); state->overtemp = CPU_MAX_OVERTEMP; } else if (temp > (state->mpu.tmax << 16)) @@ -613,6 +687,7 @@ state->first = 1; state->rpm = 1000; state->overtemp = 0; + state->adc_config = 0x00; if (index == 0) state->monitor = attach_i2c_chip(SUPPLY_MONITOR_ID, "CPU0_monitor"); @@ -941,8 +1016,17 @@ DBG("main_control_loop started\n"); + down(&driver_lock); + /* Set the PCI fan once for now */ set_pwm_fan(SLOTS_FAN_PWM_ID, SLOTS_FAN_DEFAULT_PWM); + + /* Initialize ADCs */ + initialize_adc(&cpu_state[0]); + if (cpu_state[1].monitor != NULL) + initialize_adc(&cpu_state[1]); + + up(&driver_lock); while (state == state_attached) { unsigned long elapsed, start; diff -Nru a/drivers/macintosh/therm_pm72.h b/drivers/macintosh/therm_pm72.h --- a/drivers/macintosh/therm_pm72.h Sun Mar 14 14:20:07 2004 +++ b/drivers/macintosh/therm_pm72.h Sun Mar 14 14:20:07 2004 @@ -85,7 +85,7 @@ * I'm not sure which of these Apple's algorithm is supposed * to use */ -#define RPM_PID_USE_ACTUAL_SPEED 1 +#define RPM_PID_USE_ACTUAL_SPEED 0 /* * i2c IDs. Currently, we hard code those and assume that @@ -220,6 +220,7 @@ s32 current_a; s32 last_temp; int first; + u8 adc_config; }; /* diff -Nru a/drivers/mca/mca-bus.c b/drivers/mca/mca-bus.c --- a/drivers/mca/mca-bus.c Sun Mar 14 14:20:06 2004 +++ b/drivers/mca/mca-bus.c Sun Mar 14 14:20:06 2004 @@ -106,6 +106,7 @@ sprintf (mca_dev->dev.bus_id, "%02d:%02X", bus, mca_dev->slot); mca_dev->dma_mask = mca_bus->default_dma_mask; mca_dev->dev.dma_mask = &mca_dev->dma_mask; + mca_dev->dev.coherent_dma_mask = mca_dev->dma_mask; if (device_register(&mca_dev->dev)) return 0; diff -Nru a/drivers/md/dm-crypt.c b/drivers/md/dm-crypt.c --- a/drivers/md/dm-crypt.c Sun Mar 14 14:20:05 2004 +++ b/drivers/md/dm-crypt.c Sun Mar 14 14:20:05 2004 @@ -621,7 +621,8 @@ return clone; } -static int crypt_map(struct dm_target *ti, struct bio *bio) +static int crypt_map(struct dm_target *ti, struct bio *bio, + union map_info *map_context) { struct crypt_config *cc = (struct crypt_config *) ti->private; struct crypt_io *io = mempool_alloc(cc->io_pool, GFP_NOIO); @@ -739,6 +740,7 @@ static struct target_type crypt_target = { .name = "crypt", + .version= {1, 0, 0}, .module = THIS_MODULE, .ctr = crypt_ctr, .dtr = crypt_dtr, diff -Nru a/drivers/md/dm-ioctl.c b/drivers/md/dm-ioctl.c --- a/drivers/md/dm-ioctl.c Sun Mar 14 14:20:06 2004 +++ b/drivers/md/dm-ioctl.c Sun Mar 14 14:20:06 2004 @@ -33,6 +33,14 @@ struct dm_table *new_map; }; +struct vers_iter { + size_t param_size; + struct dm_target_versions *vers, *old_vers; + char *end; + uint32_t flags; +}; + + #define NUM_BUCKETS 64 #define MASK_BUCKETS (NUM_BUCKETS - 1) static struct list_head _name_buckets[NUM_BUCKETS]; @@ -88,30 +96,24 @@ *---------------------------------------------------------------*/ static struct hash_cell *__get_name_cell(const char *str) { - struct list_head *tmp; struct hash_cell *hc; unsigned int h = hash_str(str); - list_for_each (tmp, _name_buckets + h) { - hc = list_entry(tmp, struct hash_cell, name_list); + list_for_each_entry (hc, _name_buckets + h, name_list) if (!strcmp(hc->name, str)) return hc; - } return NULL; } static struct hash_cell *__get_uuid_cell(const char *str) { - struct list_head *tmp; struct hash_cell *hc; unsigned int h = hash_str(str); - list_for_each (tmp, _uuid_buckets + h) { - hc = list_entry(tmp, struct hash_cell, uuid_list); + list_for_each_entry (hc, _uuid_buckets + h, uuid_list) if (!strcmp(hc->uuid, str)) return hc; - } return NULL; } @@ -415,6 +417,80 @@ return 0; } +static void list_version_get_needed(struct target_type *tt, void *param) +{ + int *needed = param; + + *needed += strlen(tt->name); + *needed += sizeof(tt->version); + *needed += ALIGN_MASK; +} + +static void list_version_get_info(struct target_type *tt, void *param) +{ + struct vers_iter *info = param; + + /* Check space - it might have changed since the first iteration */ + if ((char *)info->vers + sizeof(tt->version) + strlen(tt->name) + 1 > + info->end) { + + info->flags = DM_BUFFER_FULL_FLAG; + return; + } + + if (info->old_vers) + info->old_vers->next = (uint32_t) ((void *)info->vers - + (void *)info->old_vers); + info->vers->version[0] = tt->version[0]; + info->vers->version[1] = tt->version[1]; + info->vers->version[2] = tt->version[2]; + info->vers->next = 0; + strcpy(info->vers->name, tt->name); + + info->old_vers = info->vers; + info->vers = align_ptr(((void *) ++info->vers) + strlen(tt->name) + 1); +} + +static int list_versions(struct dm_ioctl *param, size_t param_size) +{ + size_t len, needed = 0; + struct dm_target_versions *vers; + struct vers_iter iter_info; + + /* + * Loop through all the devices working out how much + * space we need. + */ + dm_target_iterate(list_version_get_needed, &needed); + + /* + * Grab our output buffer. + */ + vers = get_result_buffer(param, param_size, &len); + if (len < needed) { + param->flags |= DM_BUFFER_FULL_FLAG; + goto out; + } + param->data_size = param->data_start + needed; + + iter_info.param_size = param_size; + iter_info.old_vers = NULL; + iter_info.vers = vers; + iter_info.flags = 0; + iter_info.end = (char *)vers+len; + + /* + * Now loop through filling out the names & versions. + */ + dm_target_iterate(list_version_get_info, &iter_info); + param->flags |= iter_info.flags; + + out: + return 0; +} + + + static int check_name(const char *name) { if (strchr(name, '/')) { @@ -935,6 +1011,7 @@ unsigned int count = 0; struct list_head *tmp; size_t len, needed; + struct dm_dev *dd; struct dm_target_deps *deps; deps = get_result_buffer(param, param_size, &len); @@ -942,7 +1019,7 @@ /* * Count the devices. */ - list_for_each(tmp, dm_table_get_devices(table)) + list_for_each (tmp, dm_table_get_devices(table)) count++; /* @@ -959,10 +1036,8 @@ */ deps->count = count; count = 0; - list_for_each(tmp, dm_table_get_devices(table)) { - struct dm_dev *dd = list_entry(tmp, struct dm_dev, list); + list_for_each_entry (dd, dm_table_get_devices(table), list) deps->dev[count++] = huge_encode_dev(dd->bdev->bd_dev); - } param->data_size = param->data_start + needed; } @@ -1045,7 +1120,9 @@ {DM_TABLE_LOAD_CMD, table_load}, {DM_TABLE_CLEAR_CMD, table_clear}, {DM_TABLE_DEPS_CMD, table_deps}, - {DM_TABLE_STATUS_CMD, table_status} + {DM_TABLE_STATUS_CMD, table_status}, + + {DM_LIST_VERSIONS_CMD, list_versions} }; return (cmd >= ARRAY_SIZE(_ioctls)) ? NULL : _ioctls[cmd].fn; @@ -1119,7 +1196,9 @@ param->flags &= ~DM_BUFFER_FULL_FLAG; /* Ignores parameters */ - if (cmd == DM_REMOVE_ALL_CMD || cmd == DM_LIST_DEVICES_CMD) + if (cmd == DM_REMOVE_ALL_CMD || + cmd == DM_LIST_DEVICES_CMD || + cmd == DM_LIST_VERSIONS_CMD) return 0; /* Unless creating, either name or uuid but not both */ diff -Nru a/drivers/md/dm-linear.c b/drivers/md/dm-linear.c --- a/drivers/md/dm-linear.c Sun Mar 14 14:20:07 2004 +++ b/drivers/md/dm-linear.c Sun Mar 14 14:20:07 2004 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2001 Sistina Software (UK) Limited. + * Copyright (C) 2001-2003 Sistina Software (UK) Limited. * * This file is released under the GPL. */ @@ -65,7 +65,8 @@ kfree(lc); } -static int linear_map(struct dm_target *ti, struct bio *bio) +static int linear_map(struct dm_target *ti, struct bio *bio, + union map_info *map_context) { struct linear_c *lc = (struct linear_c *) ti->private; @@ -96,6 +97,7 @@ static struct target_type linear_target = { .name = "linear", + .version= {1, 0, 1}, .module = THIS_MODULE, .ctr = linear_ctr, .dtr = linear_dtr, diff -Nru a/drivers/md/dm-stripe.c b/drivers/md/dm-stripe.c --- a/drivers/md/dm-stripe.c Sun Mar 14 14:20:07 2004 +++ b/drivers/md/dm-stripe.c Sun Mar 14 14:20:07 2004 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2001 Sistina Software (UK) Limited. + * Copyright (C) 2001-2003 Sistina Software (UK) Limited. * * This file is released under the GPL. */ @@ -97,7 +97,8 @@ /* * chunk_size is a power of two */ - if (!chunk_size || (chunk_size & (chunk_size - 1))) { + if (!chunk_size || (chunk_size & (chunk_size - 1)) || + (chunk_size < (PAGE_SIZE >> SECTOR_SHIFT))) { ti->error = "dm-stripe: Invalid chunk size"; return -EINVAL; } @@ -166,7 +167,8 @@ kfree(sc); } -static int stripe_map(struct dm_target *ti, struct bio *bio) +static int stripe_map(struct dm_target *ti, struct bio *bio, + union map_info *map_context) { struct stripe_c *sc = (struct stripe_c *) ti->private; @@ -211,6 +213,7 @@ static struct target_type stripe_target = { .name = "striped", + .version= {1, 0, 1}, .module = THIS_MODULE, .ctr = stripe_ctr, .dtr = stripe_dtr, diff -Nru a/drivers/md/dm-table.c b/drivers/md/dm-table.c --- a/drivers/md/dm-table.c Sun Mar 14 14:20:08 2004 +++ b/drivers/md/dm-table.c Sun Mar 14 14:20:08 2004 @@ -329,13 +329,11 @@ */ static struct dm_dev *find_device(struct list_head *l, dev_t dev) { - struct list_head *tmp; + struct dm_dev *dd; - list_for_each(tmp, l) { - struct dm_dev *dd = list_entry(tmp, struct dm_dev, list); + list_for_each_entry (dd, l, list) if (dd->bdev->bd_dev == dev) return dd; - } return NULL; } @@ -631,14 +629,20 @@ return 0; } -static void set_default_limits(struct io_restrictions *rs) +static void check_for_valid_limits(struct io_restrictions *rs) { - rs->max_sectors = MAX_SECTORS; - rs->max_phys_segments = MAX_PHYS_SEGMENTS; - rs->max_hw_segments = MAX_HW_SEGMENTS; - rs->hardsect_size = 1 << SECTOR_SHIFT; - rs->max_segment_size = MAX_SEGMENT_SIZE; - rs->seg_boundary_mask = -1; + if (!rs->max_sectors) + rs->max_sectors = MAX_SECTORS; + if (!rs->max_phys_segments) + rs->max_phys_segments = MAX_PHYS_SEGMENTS; + if (!rs->max_hw_segments) + rs->max_hw_segments = MAX_HW_SEGMENTS; + if (!rs->hardsect_size) + rs->hardsect_size = 1 << SECTOR_SHIFT; + if (!rs->max_segment_size) + rs->max_segment_size = MAX_SEGMENT_SIZE; + if (!rs->seg_boundary_mask) + rs->seg_boundary_mask = -1; } int dm_table_add_target(struct dm_table *t, const char *type, @@ -653,7 +657,6 @@ tgt = t->targets + t->num_targets; memset(tgt, 0, sizeof(*tgt)); - set_default_limits(&tgt->limits); if (!len) { tgt->error = "zero-length target"; @@ -737,6 +740,8 @@ { int r = 0; unsigned int leaf_nodes; + + check_for_valid_limits(&t->limits); /* how many indexes will the btree have ? */ leaf_nodes = dm_div_up(t->num_targets, KEYS_PER_NODE); diff -Nru a/drivers/md/dm-target.c b/drivers/md/dm-target.c --- a/drivers/md/dm-target.c Sun Mar 14 14:20:08 2004 +++ b/drivers/md/dm-target.c Sun Mar 14 14:20:08 2004 @@ -25,15 +25,11 @@ static inline struct tt_internal *__find_target_type(const char *name) { - struct list_head *tih; struct tt_internal *ti; - list_for_each(tih, &_targets) { - ti = list_entry(tih, struct tt_internal, list); - + list_for_each_entry (ti, &_targets, list) if (!strcmp(name, ti->tt.name)) return ti; - } return NULL; } @@ -100,6 +96,20 @@ return ti; } + +int dm_target_iterate(void (*iter_func)(struct target_type *tt, + void *param), void *param) +{ + struct tt_internal *ti; + + down_read(&_lock); + list_for_each_entry (ti, &_targets, list) + iter_func(&ti->tt, param); + up_read(&_lock); + + return 0; +} + int dm_register_target(struct target_type *t) { int rv = 0; @@ -157,13 +167,15 @@ /* empty */ } -static int io_err_map(struct dm_target *ti, struct bio *bio) +static int io_err_map(struct dm_target *ti, struct bio *bio, + union map_info *map_context) { return -EIO; } static struct target_type error_target = { .name = "error", + .version = {1, 0, 1}, .ctr = io_err_ctr, .dtr = io_err_dtr, .map = io_err_map, diff -Nru a/drivers/md/dm.c b/drivers/md/dm.c --- a/drivers/md/dm.c Sun Mar 14 14:20:08 2004 +++ b/drivers/md/dm.c Sun Mar 14 14:20:08 2004 @@ -21,6 +21,9 @@ static unsigned int major = 0; static unsigned int _major = 0; +/* + * One of these is allocated per bio. + */ struct dm_io { struct mapped_device *md; int error; @@ -29,6 +32,16 @@ }; /* + * One of these is allocated per target within a bio. Hopefully + * this will be simplified out one day. + */ +struct target_io { + struct dm_io *io; + struct dm_target *ti; + union map_info info; +}; + +/* * Bits for the md->flags field. */ #define DMF_BLOCK_IO 0 @@ -59,6 +72,7 @@ * io objects are allocated from here. */ mempool_t *io_pool; + mempool_t *tio_pool; /* * Event handling. @@ -69,6 +83,7 @@ #define MIN_IOS 256 static kmem_cache_t *_io_cache; +static kmem_cache_t *_tio_cache; static __init int local_init(void) { @@ -80,9 +95,18 @@ if (!_io_cache) return -ENOMEM; + /* allocate a slab for the target ios */ + _tio_cache = kmem_cache_create("dm_tio", sizeof(struct target_io), + 0, 0, NULL, NULL); + if (!_tio_cache) { + kmem_cache_destroy(_io_cache); + return -ENOMEM; + } + _major = major; r = register_blkdev(_major, _name); if (r < 0) { + kmem_cache_destroy(_tio_cache); kmem_cache_destroy(_io_cache); return r; } @@ -95,6 +119,7 @@ static void local_exit(void) { + kmem_cache_destroy(_tio_cache); kmem_cache_destroy(_io_cache); if (unregister_blkdev(_major, _name) < 0) @@ -184,6 +209,16 @@ mempool_free(io, md->io_pool); } +static inline struct target_io *alloc_tio(struct mapped_device *md) +{ + return mempool_alloc(md->tio_pool, GFP_NOIO); +} + +static inline void free_tio(struct mapped_device *md, struct target_io *tio) +{ + mempool_free(tio, md->tio_pool); +} + /* * Add the bio to the list of deferred io. */ @@ -232,17 +267,30 @@ static int clone_endio(struct bio *bio, unsigned int done, int error) { - struct dm_io *io = bio->bi_private; + int r = 0; + struct target_io *tio = bio->bi_private; + struct dm_io *io = tio->io; + dm_endio_fn endio = tio->ti->type->end_io; if (bio->bi_size) return 1; + if (endio) { + r = endio(tio->ti, bio, error, &tio->info); + if (r < 0) + error = r; + + else if (r > 0) + /* the target wants another shot at the io */ + return 1; + } + + free_tio(io->md, tio); dec_pending(io, error); bio_put(bio); - return 0; + return r; } - static sector_t max_io_len(struct mapped_device *md, sector_t sector, struct dm_target *ti) { @@ -263,7 +311,8 @@ return len; } -static void __map_bio(struct dm_target *ti, struct bio *clone, struct dm_io *io) +static void __map_bio(struct dm_target *ti, struct bio *clone, + struct target_io *tio) { int r; @@ -273,22 +322,25 @@ BUG_ON(!clone->bi_size); clone->bi_end_io = clone_endio; - clone->bi_private = io; + clone->bi_private = tio; /* * Map the clone. If r == 0 we don't need to do * anything, the target has assumed ownership of * this io. */ - atomic_inc(&io->io_count); - r = ti->type->map(ti, clone); + atomic_inc(&tio->io->io_count); + r = ti->type->map(ti, clone, &tio->info); if (r > 0) /* the bio has been remapped so dispatch it */ generic_make_request(clone); - else if (r < 0) + else if (r < 0) { /* error the io and bail out */ + struct dm_io *io = tio->io; + free_tio(tio->io->md, tio); dec_pending(io, -EIO); + } } struct clone_info { @@ -348,6 +400,15 @@ struct bio *clone, *bio = ci->bio; struct dm_target *ti = dm_table_find_target(ci->md->map, ci->sector); sector_t len = 0, max = max_io_len(ci->md, ci->sector, ti); + struct target_io *tio; + + /* + * Allocate a target io object. + */ + tio = alloc_tio(ci->md); + tio->io = ci->io; + tio->ti = ti; + memset(&tio->info, 0, sizeof(tio->info)); if (ci->sector_count <= max) { /* @@ -356,7 +417,7 @@ */ clone = clone_bio(bio, ci->sector, ci->idx, bio->bi_vcnt - ci->idx, ci->sector_count); - __map_bio(ti, clone, ci->io); + __map_bio(ti, clone, tio); ci->sector_count = 0; } else if (to_sector(bio->bi_io_vec[ci->idx].bv_len) <= max) { @@ -379,7 +440,7 @@ } clone = clone_bio(bio, ci->sector, ci->idx, i - ci->idx, len); - __map_bio(ti, clone, ci->io); + __map_bio(ti, clone, tio); ci->sector += len; ci->sector_count -= len; @@ -394,7 +455,7 @@ clone = split_bvec(bio, ci->sector, ci->idx, bv->bv_offset, max); - __map_bio(ti, clone, ci->io); + __map_bio(ti, clone, tio); ci->sector += max; ci->sector_count -= max; @@ -403,7 +464,11 @@ len = to_sector(bv->bv_len) - max; clone = split_bvec(bio, ci->sector, ci->idx, bv->bv_offset + to_bytes(max), len); - __map_bio(ti, clone, ci->io); + tio = alloc_tio(ci->md); + tio->io = ci->io; + tio->ti = ti; + memset(&tio->info, 0, sizeof(tio->info)); + __map_bio(ti, clone, tio); ci->sector += len; ci->sector_count -= len; @@ -441,6 +506,16 @@ *---------------------------------------------------------------*/ +static inline void __dm_request(struct mapped_device *md, struct bio *bio) +{ + if (!md->map) { + bio_io_error(bio, bio->bi_size); + return; + } + + __split_bio(md, bio); +} + /* * The request function that just remaps the bio built up by * dm_merge_bvec. @@ -479,12 +554,7 @@ down_read(&md->lock); } - if (!md->map) { - bio_io_error(bio, bio->bi_size); - return 0; - } - - __split_bio(md, bio); + __dm_request(md, bio); up_read(&md->lock); return 0; } @@ -574,9 +644,14 @@ if (!md->io_pool) goto bad2; + md->tio_pool = mempool_create(MIN_IOS, mempool_alloc_slab, + mempool_free_slab, _tio_cache); + if (!md->tio_pool) + goto bad3; + md->disk = alloc_disk(1); if (!md->disk) - goto bad3; + goto bad4; md->disk->major = _major; md->disk->first_minor = minor; @@ -592,7 +667,8 @@ return md; - + bad4: + mempool_destroy(md->tio_pool); bad3: mempool_destroy(md->io_pool); bad2: @@ -606,6 +682,7 @@ static void free_dev(struct mapped_device *md) { free_minor(md->disk->first_minor); + mempool_destroy(md->tio_pool); mempool_destroy(md->io_pool); del_gendisk(md->disk); put_disk(md->disk); @@ -644,13 +721,13 @@ { request_queue_t *q = md->queue; sector_t size; - md->map = t; size = dm_table_get_size(t); __set_size(md->disk, size); if (size == 0) return 0; + md->map = t; dm_table_event_callback(md->map, event_callback, md); dm_table_get(t); @@ -710,16 +787,16 @@ } /* - * Requeue the deferred bios by calling generic_make_request. + * Process the deferred bios */ -static void flush_deferred_io(struct bio *c) +static void __flush_deferred_io(struct mapped_device *md, struct bio *c) { struct bio *n; while (c) { n = c->bi_next; c->bi_next = NULL; - generic_make_request(c); + __dm_request(md, c); c = n; } } @@ -814,10 +891,11 @@ dm_table_resume_targets(md->map); clear_bit(DMF_SUSPENDED, &md->flags); clear_bit(DMF_BLOCK_IO, &md->flags); + def = bio_list_get(&md->deferred); + __flush_deferred_io(md, def); up_write(&md->lock); - flush_deferred_io(def); blk_run_queues(); return 0; diff -Nru a/drivers/md/dm.h b/drivers/md/dm.h --- a/drivers/md/dm.h Sun Mar 14 14:20:07 2004 +++ b/drivers/md/dm.h Sun Mar 14 14:20:07 2004 @@ -123,6 +123,8 @@ void dm_target_exit(void); struct target_type *dm_get_target_type(const char *name); void dm_put_target_type(struct target_type *t); +int dm_target_iterate(void (*iter_func)(struct target_type *tt, + void *param), void *param); /*----------------------------------------------------------------- diff -Nru a/drivers/md/md.c b/drivers/md/md.c --- a/drivers/md/md.c Sun Mar 14 14:20:06 2004 +++ b/drivers/md/md.c Sun Mar 14 14:20:06 2004 @@ -57,7 +57,7 @@ #ifndef MODULE -static void autostart_arrays (void); +static void autostart_arrays (int part); #endif static mdk_personality_t *pers[MAX_PERSONALITY]; @@ -1447,7 +1447,7 @@ return 1; } -static int mdp_major = 0; +int mdp_major = 0; static struct kobject *md_probe(dev_t dev, int *part, void *data) { @@ -1792,7 +1792,7 @@ * * If "unit" is allocated, then bump its reference count */ -static void autorun_devices(void) +static void autorun_devices(int part) { struct list_head candidates; struct list_head *tmp; @@ -1825,7 +1825,12 @@ bdevname(rdev0->bdev, b), rdev0->preferred_minor); break; } - dev = MKDEV(MD_MAJOR, rdev0->preferred_minor); + if (part) + dev = MKDEV(mdp_major, + rdev0->preferred_minor << MdpMinorShift); + else + dev = MKDEV(MD_MAJOR, rdev0->preferred_minor); + md_probe(dev, NULL, NULL); mddev = mddev_find(dev); if (!mddev) { @@ -1922,7 +1927,7 @@ /* * possibly return codes */ - autorun_devices(); + autorun_devices(0); return 0; } @@ -2407,7 +2412,7 @@ #ifndef MODULE case RAID_AUTORUN: err = 0; - autostart_arrays(); + autostart_arrays(arg); goto done; #endif default:; @@ -3577,7 +3582,7 @@ } -static void autostart_arrays(void) +static void autostart_arrays(int part) { char b[BDEVNAME_SIZE]; mdk_rdev_t *rdev; @@ -3602,7 +3607,7 @@ } dev_cnt = 0; - autorun_devices(); + autorun_devices(part); } #endif diff -Nru a/drivers/md/raid0.c b/drivers/md/raid0.c --- a/drivers/md/raid0.c Sun Mar 14 14:20:07 2004 +++ b/drivers/md/raid0.c Sun Mar 14 14:20:07 2004 @@ -313,8 +313,8 @@ /* calculate the max read-ahead size. * For read-ahead of large files to be effective, we need to - * readahead at least a whole stripe. i.e. number of devices - * multiplied by chunk size. + * readahead at least twice a whole stripe. i.e. number of devices + * multiplied by chunk size times 2. * If an individual device has an ra_pages greater than the * chunk size, then we will not drive that device as hard as it * wants. We consider this a configuration error: a larger @@ -322,8 +322,8 @@ */ { int stripe = mddev->raid_disks * mddev->chunk_size / PAGE_CACHE_SIZE; - if (mddev->queue->backing_dev_info.ra_pages < stripe) - mddev->queue->backing_dev_info.ra_pages = stripe; + if (mddev->queue->backing_dev_info.ra_pages < 2* stripe) + mddev->queue->backing_dev_info.ra_pages = 2* stripe; } diff -Nru a/drivers/md/raid5.c b/drivers/md/raid5.c --- a/drivers/md/raid5.c Sun Mar 14 14:20:06 2004 +++ b/drivers/md/raid5.c Sun Mar 14 14:20:06 2004 @@ -1409,7 +1409,8 @@ /* make sure we don't swamp the stripe cache if someone else * is trying to get access */ - yield(); + set_current_state(TASK_UNINTERRUPTIBLE); + schedule_timeout(1); } spin_lock(&sh->lock); set_bit(STRIPE_SYNCING, &sh->state); @@ -1602,14 +1603,14 @@ print_raid5_conf(conf); - /* read-ahead size must cover a whole stripe, which is - * (n-1) * chunksize where 'n' is the number of raid devices + /* read-ahead size must cover two whole stripes, which is + * 2 * (n-1) * chunksize where 'n' is the number of raid devices */ { int stripe = (mddev->raid_disks-1) * mddev->chunk_size / PAGE_CACHE_SIZE; - if (mddev->queue->backing_dev_info.ra_pages < stripe) - mddev->queue->backing_dev_info.ra_pages = stripe; + if (mddev->queue->backing_dev_info.ra_pages < 2 * stripe) + mddev->queue->backing_dev_info.ra_pages = 2 * stripe; } /* Ok, everything is just fine now */ diff -Nru a/drivers/md/raid6main.c b/drivers/md/raid6main.c --- a/drivers/md/raid6main.c Sun Mar 14 14:20:05 2004 +++ b/drivers/md/raid6main.c Sun Mar 14 14:20:06 2004 @@ -1571,7 +1571,8 @@ /* make sure we don't swamp the stripe cache if someone else * is trying to get access */ - yield(); + set_current_state(TASK_UNINTERRUPTIBLE); + schedule_timeout(1); } spin_lock(&sh->lock); set_bit(STRIPE_SYNCING, &sh->state); @@ -1771,14 +1772,14 @@ print_raid6_conf(conf); - /* read-ahead size must cover a whole stripe, which is - * (n-2) * chunksize where 'n' is the number of raid devices + /* read-ahead size must cover two whole stripes, which is + * 2 * (n-2) * chunksize where 'n' is the number of raid devices */ { int stripe = (mddev->raid_disks-2) * mddev->chunk_size / PAGE_CACHE_SIZE; - if (mddev->queue->backing_dev_info.ra_pages < stripe) - mddev->queue->backing_dev_info.ra_pages = stripe; + if (mddev->queue->backing_dev_info.ra_pages < 2 * stripe) + mddev->queue->backing_dev_info.ra_pages = 2 * stripe; } /* Ok, everything is just fine now */ diff -Nru a/drivers/media/dvb/frontends/alps_tdlb7.c b/drivers/media/dvb/frontends/alps_tdlb7.c --- a/drivers/media/dvb/frontends/alps_tdlb7.c Sun Mar 14 14:20:06 2004 +++ b/drivers/media/dvb/frontends/alps_tdlb7.c Sun Mar 14 14:20:06 2004 @@ -29,8 +29,6 @@ */ - -#define __KERNEL_SYSCALLS__ #include #include #include @@ -58,8 +56,6 @@ #define SP8870_FIRMWARE_OFFSET 0x0A -static int errno; - static struct dvb_frontend_info tdlb7_info = { .name = "Alps TDLB7", .type = FE_OFDM, @@ -174,13 +170,13 @@ loff_t filesize; char *dp; - fd = open(fn, 0, 0); + fd = sys_open(fn, 0, 0); if (fd == -1) { printk("%s: unable to open '%s'.\n", __FUNCTION__, fn); return -EIO; } - filesize = lseek(fd, 0L, 2); + filesize = sys_lseek(fd, 0L, 2); if (filesize <= 0 || filesize < SP8870_FIRMWARE_OFFSET + SP8870_FIRMWARE_SIZE) { printk("%s: firmware filesize to small '%s'\n", __FUNCTION__, fn); sys_close(fd); @@ -194,8 +190,8 @@ return -EIO; } - lseek(fd, SP8870_FIRMWARE_OFFSET, 0); - if (read(fd, dp, SP8870_FIRMWARE_SIZE) != SP8870_FIRMWARE_SIZE) { + sys_lseek(fd, SP8870_FIRMWARE_OFFSET, 0); + if (sys_read(fd, dp, SP8870_FIRMWARE_SIZE) != SP8870_FIRMWARE_SIZE) { printk("%s: failed to read '%s'.\n",__FUNCTION__, fn); vfree(dp); sys_close(fd); diff -Nru a/drivers/media/dvb/frontends/sp887x.c b/drivers/media/dvb/frontends/sp887x.c --- a/drivers/media/dvb/frontends/sp887x.c Sun Mar 14 14:20:08 2004 +++ b/drivers/media/dvb/frontends/sp887x.c Sun Mar 14 14:20:08 2004 @@ -12,7 +12,6 @@ next 0x4000 loaded. This may change in future versions. */ -#define __KERNEL_SYSCALLS__ #include #include #include @@ -68,8 +67,6 @@ FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_RECOVER }; -static int errno; - static int i2c_writebytes (struct dvb_frontend *fe, u8 addr, u8 *buf, u8 len) { @@ -216,13 +213,13 @@ // Load the firmware set_fs(get_ds()); - fd = open(sp887x_firmware, 0, 0); + fd = sys_open(sp887x_firmware, 0, 0); if (fd < 0) { printk(KERN_WARNING "%s: Unable to open firmware %s\n", __FUNCTION__, sp887x_firmware); return -EIO; } - filesize = lseek(fd, 0L, 2); + filesize = sys_lseek(fd, 0L, 2); if (filesize <= 0) { printk(KERN_WARNING "%s: Firmware %s is empty\n", __FUNCTION__, sp887x_firmware); @@ -244,8 +241,8 @@ // read it! // read the first 16384 bytes from the file // ignore the first 10 bytes - lseek(fd, 10, 0); - if (read(fd, firmware, fw_size) != fw_size) { + sys_lseek(fd, 10, 0); + if (sys_read(fd, firmware, fw_size) != fw_size) { printk(KERN_WARNING "%s: Failed to read firmware\n", __FUNCTION__); vfree(firmware); sys_close(fd); diff -Nru a/drivers/media/dvb/frontends/tda1004x.c b/drivers/media/dvb/frontends/tda1004x.c --- a/drivers/media/dvb/frontends/tda1004x.c Sun Mar 14 14:20:05 2004 +++ b/drivers/media/dvb/frontends/tda1004x.c Sun Mar 14 14:20:05 2004 @@ -32,7 +32,6 @@ */ -#define __KERNEL_SYSCALLS__ #include #include #include @@ -41,7 +40,6 @@ #include #include #include -#include #include #include #include "dvb_frontend.h" @@ -399,13 +397,13 @@ // Load the firmware set_fs(get_ds()); - fd = open(tda1004x_firmware, 0, 0); + fd = sys_open(tda1004x_firmware, 0, 0); if (fd < 0) { printk("%s: Unable to open firmware %s\n", __FUNCTION__, tda1004x_firmware); return -EIO; } - filesize = lseek(fd, 0L, 2); + filesize = sys_lseek(fd, 0L, 2); if (filesize <= 0) { printk("%s: Firmware %s is empty\n", __FUNCTION__, tda1004x_firmware); @@ -436,8 +434,8 @@ } // read it! - lseek(fd, fw_offset, 0); - if (read(fd, firmware, fw_size) != fw_size) { + sys_lseek(fd, fw_offset, 0); + if (sys_read(fd, firmware, fw_size) != fw_size) { printk("%s: Failed to read firmware\n", __FUNCTION__); vfree(firmware); sys_close(fd); diff -Nru a/drivers/media/video/video-buf.c b/drivers/media/video/video-buf.c --- a/drivers/media/video/video-buf.c Sun Mar 14 14:20:07 2004 +++ b/drivers/media/video/video-buf.c Sun Mar 14 14:20:07 2004 @@ -215,7 +215,7 @@ BUG(); if (!dma->bus_addr) - pci_dma_sync_sg(dev,dma->sglist,dma->nr_pages,dma->direction); + pci_dma_sync_sg_for_cpu(dev,dma->sglist,dma->nr_pages,dma->direction); return 0; } diff -Nru a/drivers/message/fusion/Kconfig b/drivers/message/fusion/Kconfig --- a/drivers/message/fusion/Kconfig Sun Mar 14 14:20:09 2004 +++ b/drivers/message/fusion/Kconfig Sun Mar 14 14:20:09 2004 @@ -3,7 +3,7 @@ config FUSION tristate "Fusion MPT (base + ScsiHost) drivers" - depends on BLK_DEV_SD && PCI + depends on PCI ---help--- LSI Logic Fusion(TM) Message Passing Technology (MPT) device support provides high performance SCSI host initiator, and LAN [1] interface @@ -14,41 +14,6 @@ [1] LAN is not supported on parallel SCSI medium. - These drivers require a Fusion MPT compatible PCI adapter installed - in the host system. MPT adapters contain specialized I/O processors - to handle I/O workload, and more importantly to offload this work - from the host CPU(s). - - If you have Fusion MPT hardware and want to use it, you can say - Y or M here to add MPT (base + ScsiHost) drivers. - = build lib (fusion), and link [static] into the kernel [2] - proper - = compiled as [dynamic] modules [3] named: (mptbase, - mptscsih) - - [2] In order enable capability to boot the linux kernel - natively from a Fusion MPT target device, you MUST - answer Y here! (currently requires CONFIG_BLK_DEV_SD) - [3] To compile this support as modules, choose M here. - - If unsure, say N. - - If you say Y or M here you will get a choice of these - additional protocol and support module options: Module Name: - Enhanced SCSI error reporting (isense) - Fusion MPT misc device (ioctl) driver (mptctl) - Fusion MPT LAN driver (mptlan) - - --- - Fusion MPT is trademark of LSI Logic Corporation, and its - architecture is based on LSI Logic's Message Passing Interface (MPI) - specification. - -config FUSION_BOOT - bool - depends on FUSION=y - default y - config FUSION_MAX_SGE int "Maximum number of scatter gather entries" depends on FUSION @@ -62,7 +27,6 @@ necessary (or recommended) unless the user will be running large I/O's via the raw interface. -# How can we force these options to module or nothing? config FUSION_ISENSE tristate "Enhanced SCSI error reporting" depends on MODULES && FUSION && m @@ -132,17 +96,4 @@ If unsure whether you really want or need this, say N. - NOTES: This feature is NOT available nor supported for linux-2.2.x - kernels. You must be building a linux-2.3.x or linux-2.4.x kernel - in order to configure this option. - Support for building this feature into the linux kernel is not - yet available. - -# if [ "$CONFIG_FUSION_LAN" != "n" ]; then -# define_bool CONFIG_NET_FC y -# fi -# These be define_tristate, but we leave them define_bool -# for backward compatibility with pre-linux-2.2.15 kernels. -# (Bugzilla:fibrebugs, #384) endmenu - diff -Nru a/drivers/message/fusion/Makefile b/drivers/message/fusion/Makefile --- a/drivers/message/fusion/Makefile Sun Mar 14 14:20:07 2004 +++ b/drivers/message/fusion/Makefile Sun Mar 14 14:20:07 2004 @@ -17,10 +17,16 @@ # Fusion MPT drivers; recognized debug defines... # MPT general: -#EXTRA_CFLAGS += -DDEBUG +#EXTRA_CFLAGS += -DMPT_DEBUG_SCSI #EXTRA_CFLAGS += -DMPT_DEBUG #EXTRA_CFLAGS += -DMPT_DEBUG_MSG_FRAME #EXTRA_CFLAGS += -DMPT_DEBUG_SG + +# This is a temporary fix for the reply/request fifo +# for some 64bit archs. Uncommenting this line +# will place the fifo's in 32bit space +#EXTRA_CFLAGS += -DMPTBASE_MEM_ALLOC_FIFO_FIX + # # driver/module specifics... # diff -Nru a/drivers/message/fusion/isense.c b/drivers/message/fusion/isense.c --- a/drivers/message/fusion/isense.c Sun Mar 14 14:20:07 2004 +++ b/drivers/message/fusion/isense.c Sun Mar 14 14:20:07 2004 @@ -5,7 +5,7 @@ * Error Report logging output. This module implements SCSI-3 * Opcode lookup and a sorted table of SCSI-3 ASC/ASCQ strings. * - * Copyright (c) 1991-2003 Steven J. Ralston + * Copyright (c) 1991-2004 Steven J. Ralston * Written By: Steven J. Ralston * (yes I wrote some of the orig. code back in 1991!) * (mailto:sjralston1@netscape.net) @@ -66,7 +66,7 @@ #endif #define MODULEAUTHOR "Steven J. Ralston" -#define COPYRIGHT "Copyright (c) 2001-2003 " MODULEAUTHOR +#define COPYRIGHT "Copyright (c) 2001-2004 " MODULEAUTHOR #include "mptbase.h" #include "isense.h" diff -Nru a/drivers/message/fusion/linux_compat.h b/drivers/message/fusion/linux_compat.h --- a/drivers/message/fusion/linux_compat.h Sun Mar 14 14:20:06 2004 +++ b/drivers/message/fusion/linux_compat.h Sun Mar 14 14:20:06 2004 @@ -15,25 +15,7 @@ #define rwlock_init(x) do { *(x) = RW_LOCK_UNLOCKED; } while(0) #endif -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) -#define SET_NICE(current,x) do {(current)->nice = (x);} while (0) -#else -#define SET_NICE(current,x) -#endif - -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0) -#define pci_enable_device(pdev) (0) -#define SCSI_DATA_UNKNOWN 0 -#define SCSI_DATA_WRITE 1 -#define SCSI_DATA_READ 2 -#define SCSI_DATA_NONE 3 -#endif - - -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,4) -#define pci_set_dma_mask(pdev, mask) (0) -#define scsi_set_pci_device(sh, pdev) (0) -#endif +#define SET_NICE(current,x) do {(current)->nice = (x);} while (0) #if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,0) # if LINUX_VERSION_CODE < KERNEL_VERSION(2,2,18) @@ -147,31 +129,9 @@ /* PCI/driver subsystem { */ -#if 0 /* FIXME Don't know what to use to check for the proper kernel version */ -#define DEVICE_COUNT_RESOURCE 6 -#define PCI_BASEADDR_FLAGS(idx) base_address[idx] -#define PCI_BASEADDR_START(idx) base_address[idx] & ~0xFUL -/* - * We have to keep track of the original value using - * a temporary, and not by just sticking pdev->base_address[x] - * back. pdev->base_address[x] is an opaque cookie that can - * be used by the PCI implementation on a given Linux port - * for any purpose. -DaveM - */ -#define PCI_BASEADDR_SIZE(__pdev, __idx) \ -({ unsigned int size, tmp; \ - pci_read_config_dword(__pdev, PCI_BASE_ADDRESS_0 + (4*(__idx)), &tmp); \ - pci_write_config_dword(__pdev, PCI_BASE_ADDRESS_0 + (4*(__idx)), 0xffffffff); \ - pci_read_config_dword(__pdev, PCI_BASE_ADDRESS_0 + (4*(__idx)), &size); \ - pci_write_config_dword(__pdev, PCI_BASE_ADDRESS_0 + (4*(__idx)), tmp); \ - (4 - size); \ -}) -#else #define PCI_BASEADDR_FLAGS(idx) resource[idx].flags #define PCI_BASEADDR_START(idx) resource[idx].start #define PCI_BASEADDR_SIZE(dev,idx) (dev)->resource[idx].end - (dev)->resource[idx].start + 1 -#endif /* } ifndef 0 */ - /* Compatability for the 2.3.x PCI DMA API. */ #ifndef PCI_DMA_BIDIRECTIONAL @@ -227,54 +187,10 @@ /*}-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ #endif /* PCI_DMA_BIDIRECTIONAL */ -/* - * With the new command queuing code in the SCSI mid-layer we no longer have - * to hold the io_request_lock spin lock when calling the scsi_done routine. - * For now we only do this with the 2.5.1 kernel or newer. - */ -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,1) - #define MPT_HOST_LOCK(flags) - #define MPT_HOST_UNLOCK(flags) -#else - #define MPT_HOST_LOCK(flags) \ - spin_lock_irqsave(&io_request_lock, flags) - #define MPT_HOST_UNLOCK(flags) \ - spin_unlock_irqrestore(&io_request_lock, flags) -#endif - -/* - * We use our new error handling code if the kernel version is 2.4.18 or newer. - */ -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,18) - #define MPT_SCSI_USE_NEW_EH -#endif -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,41) #define mpt_work_struct work_struct #define MPT_INIT_WORK(_task, _func, _data) INIT_WORK(_task, _func, _data) -#else -#define mpt_work_struct tq_struct -#define MPT_INIT_WORK(_task, _func, _data) \ -({ (_task)->sync = 0; \ - (_task)->routine = (_func); \ - (_task)->data = (void *) (_data); \ -}) -#endif - -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,28) -#define mptscsih_sync_irq(_irq) synchronize_irq(_irq) -#else -#define mptscsih_sync_irq(_irq) synchronize_irq() -#endif - -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,58) -#define mpt_inc_use_count() -#define mpt_dec_use_count() -#else -#define mpt_inc_use_count() MOD_INC_USE_COUNT -#define mpt_dec_use_count() MOD_DEC_USE_COUNT -#endif - +#define mpt_sync_irq(_irq) synchronize_irq(_irq) /*}-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ #endif /* _LINUX_COMPAT_H */ diff -Nru a/drivers/message/fusion/lsi/mpi.h b/drivers/message/fusion/lsi/mpi.h --- a/drivers/message/fusion/lsi/mpi.h Sun Mar 14 14:20:06 2004 +++ b/drivers/message/fusion/lsi/mpi.h Sun Mar 14 14:20:06 2004 @@ -1,12 +1,12 @@ /* - * Copyright (c) 2000-2002 LSI Logic Corporation. + * Copyright (c) 2000-2003 LSI Logic Corporation. * * - * Name: MPI.H + * Name: mpi.h * Title: MPI Message independent structures and definitions * Creation Date: July 27, 2000 * - * MPI.H Version: 01.02.07 + * mpi.h Version: 01.05.xx * * Version History * --------------- @@ -48,6 +48,10 @@ * 05-31-02 01.02.05 Bumped MPI_HEADER_VERSION_UNIT. * 07-12-02 01.02.06 Added define for MPI_FUNCTION_MAILBOX. * 09-16-02 01.02.07 Bumped value for MPI_HEADER_VERSION_UNIT. + * 11-15-02 01.02.08 Added define MPI_IOCSTATUS_TARGET_INVALID_IO_INDEX and + * obsoleted define MPI_IOCSTATUS_TARGET_INVALID_IOCINDEX. + * 04-01-03 01.02.09 New IOCStatus code: MPI_IOCSTATUS_FC_EXCHANGE_CANCELED + * 06-26-03 01.02.10 Bumped MPI_HEADER_VERSION_UNIT value. * -------------------------------------------------------------------------- */ @@ -62,7 +66,7 @@ *****************************************************************************/ #define MPI_VERSION_MAJOR (0x01) -#define MPI_VERSION_MINOR (0x02) +#define MPI_VERSION_MINOR (0x05) #define MPI_VERSION_MAJOR_MASK (0xFF00) #define MPI_VERSION_MAJOR_SHIFT (8) #define MPI_VERSION_MINOR_MASK (0x00FF) @@ -73,10 +77,12 @@ #define MPI_VERSION_01_00 (0x0100) #define MPI_VERSION_01_01 (0x0101) #define MPI_VERSION_01_02 (0x0102) +#define MPI_VERSION_01_03 (0x0103) +#define MPI_VERSION_01_05 (0x0105) /* Note: The major versions of 0xe0 through 0xff are reserved */ /* versioning for this MPI header set */ -#define MPI_HEADER_VERSION_UNIT (0x09) +#define MPI_HEADER_VERSION_UNIT (0x00) #define MPI_HEADER_VERSION_DEV (0x00) #define MPI_HEADER_VERSION_UNIT_MASK (0xFF00) #define MPI_HEADER_VERSION_UNIT_SHIFT (8) @@ -171,6 +177,8 @@ #define MPI_REPLY_POST_FIFO_OFFSET (0x00000044) #define MPI_REPLY_FREE_FIFO_OFFSET (0x00000044) +#define MPI_HI_PRI_REQUEST_QUEUE_OFFSET (0x00000048) + /***************************************************************************** @@ -230,10 +238,6 @@ #define MPI_FUNCTION_TARGET_ASSIST (0x0B) #define MPI_FUNCTION_TARGET_STATUS_SEND (0x0C) #define MPI_FUNCTION_TARGET_MODE_ABORT (0x0D) -#define MPI_FUNCTION_TARGET_FC_BUF_POST_LINK_SRVC (0x0E) /* obsolete name */ -#define MPI_FUNCTION_TARGET_FC_RSP_LINK_SRVC (0x0F) /* obsolete name */ -#define MPI_FUNCTION_TARGET_FC_EX_SEND_LINK_SRVC (0x10) /* obsolete name */ -#define MPI_FUNCTION_TARGET_FC_ABORT (0x11) /* obsolete name */ #define MPI_FUNCTION_FC_LINK_SRVC_BUF_POST (0x0E) #define MPI_FUNCTION_FC_LINK_SRVC_RSP (0x0F) #define MPI_FUNCTION_FC_EX_LINK_SRVC_SEND (0x10) @@ -251,16 +255,46 @@ #define MPI_FUNCTION_MAILBOX (0x19) +#define MPI_FUNCTION_SMP_PASSTHROUGH (0x1A) +#define MPI_FUNCTION_SAS_IO_UNIT_CONTROL (0x1B) + +#define MPI_DIAG_BUFFER_POST (0x1D) +#define MPI_DIAG_RELEASE (0x1E) + +#define MPI_FUNCTION_SCSI_IO_32 (0x1F) + #define MPI_FUNCTION_LAN_SEND (0x20) #define MPI_FUNCTION_LAN_RECEIVE (0x21) #define MPI_FUNCTION_LAN_RESET (0x22) +#define MPI_FUNCTION_INBAND_BUFFER_POST (0x28) +#define MPI_FUNCTION_INBAND_SEND (0x29) +#define MPI_FUNCTION_INBAND_RSP (0x2A) +#define MPI_FUNCTION_INBAND_ABORT (0x2B) + #define MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET (0x40) #define MPI_FUNCTION_IO_UNIT_RESET (0x41) #define MPI_FUNCTION_HANDSHAKE (0x42) #define MPI_FUNCTION_REPLY_FRAME_REMOVAL (0x43) +/* standard version format */ +typedef struct _MPI_VERSION_STRUCT +{ + U8 Dev; /* 00h */ + U8 Unit; /* 01h */ + U8 Minor; /* 02h */ + U8 Major; /* 03h */ +} MPI_VERSION_STRUCT, MPI_POINTER PTR_MPI_VERSION_STRUCT, + MpiVersionStruct_t, MPI_POINTER pMpiVersionStruct; + +typedef union _MPI_VERSION_FORMAT +{ + MPI_VERSION_STRUCT Struct; + U32 Word; +} MPI_VERSION_FORMAT, MPI_POINTER PTR_MPI_VERSION_FORMAT, + MpiVersionFormat_t, MPI_POINTER pMpiVersionFormat_t; + /***************************************************************************** * @@ -573,44 +607,54 @@ /* Common IOCStatus values for all replies */ /****************************************************************************/ -#define MPI_IOCSTATUS_SUCCESS (0x0000) -#define MPI_IOCSTATUS_INVALID_FUNCTION (0x0001) -#define MPI_IOCSTATUS_BUSY (0x0002) -#define MPI_IOCSTATUS_INVALID_SGL (0x0003) -#define MPI_IOCSTATUS_INTERNAL_ERROR (0x0004) -#define MPI_IOCSTATUS_RESERVED (0x0005) -#define MPI_IOCSTATUS_INSUFFICIENT_RESOURCES (0x0006) -#define MPI_IOCSTATUS_INVALID_FIELD (0x0007) -#define MPI_IOCSTATUS_INVALID_STATE (0x0008) +#define MPI_IOCSTATUS_SUCCESS (0x0000) +#define MPI_IOCSTATUS_INVALID_FUNCTION (0x0001) +#define MPI_IOCSTATUS_BUSY (0x0002) +#define MPI_IOCSTATUS_INVALID_SGL (0x0003) +#define MPI_IOCSTATUS_INTERNAL_ERROR (0x0004) +#define MPI_IOCSTATUS_RESERVED (0x0005) +#define MPI_IOCSTATUS_INSUFFICIENT_RESOURCES (0x0006) +#define MPI_IOCSTATUS_INVALID_FIELD (0x0007) +#define MPI_IOCSTATUS_INVALID_STATE (0x0008) +#define MPI_IOCSTATUS_OP_STATE_NOT_SUPPORTED (0x0009) /****************************************************************************/ /* Config IOCStatus values */ /****************************************************************************/ -#define MPI_IOCSTATUS_CONFIG_INVALID_ACTION (0x0020) -#define MPI_IOCSTATUS_CONFIG_INVALID_TYPE (0x0021) -#define MPI_IOCSTATUS_CONFIG_INVALID_PAGE (0x0022) -#define MPI_IOCSTATUS_CONFIG_INVALID_DATA (0x0023) -#define MPI_IOCSTATUS_CONFIG_NO_DEFAULTS (0x0024) -#define MPI_IOCSTATUS_CONFIG_CANT_COMMIT (0x0025) +#define MPI_IOCSTATUS_CONFIG_INVALID_ACTION (0x0020) +#define MPI_IOCSTATUS_CONFIG_INVALID_TYPE (0x0021) +#define MPI_IOCSTATUS_CONFIG_INVALID_PAGE (0x0022) +#define MPI_IOCSTATUS_CONFIG_INVALID_DATA (0x0023) +#define MPI_IOCSTATUS_CONFIG_NO_DEFAULTS (0x0024) +#define MPI_IOCSTATUS_CONFIG_CANT_COMMIT (0x0025) /****************************************************************************/ /* SCSIIO Reply (SPI & FCP) initiator values */ /****************************************************************************/ -#define MPI_IOCSTATUS_SCSI_RECOVERED_ERROR (0x0040) -#define MPI_IOCSTATUS_SCSI_INVALID_BUS (0x0041) -#define MPI_IOCSTATUS_SCSI_INVALID_TARGETID (0x0042) -#define MPI_IOCSTATUS_SCSI_DEVICE_NOT_THERE (0x0043) -#define MPI_IOCSTATUS_SCSI_DATA_OVERRUN (0x0044) -#define MPI_IOCSTATUS_SCSI_DATA_UNDERRUN (0x0045) -#define MPI_IOCSTATUS_SCSI_IO_DATA_ERROR (0x0046) -#define MPI_IOCSTATUS_SCSI_PROTOCOL_ERROR (0x0047) -#define MPI_IOCSTATUS_SCSI_TASK_TERMINATED (0x0048) -#define MPI_IOCSTATUS_SCSI_RESIDUAL_MISMATCH (0x0049) -#define MPI_IOCSTATUS_SCSI_TASK_MGMT_FAILED (0x004A) -#define MPI_IOCSTATUS_SCSI_IOC_TERMINATED (0x004B) -#define MPI_IOCSTATUS_SCSI_EXT_TERMINATED (0x004C) +#define MPI_IOCSTATUS_SCSI_RECOVERED_ERROR (0x0040) +#define MPI_IOCSTATUS_SCSI_INVALID_BUS (0x0041) +#define MPI_IOCSTATUS_SCSI_INVALID_TARGETID (0x0042) +#define MPI_IOCSTATUS_SCSI_DEVICE_NOT_THERE (0x0043) +#define MPI_IOCSTATUS_SCSI_DATA_OVERRUN (0x0044) +#define MPI_IOCSTATUS_SCSI_DATA_UNDERRUN (0x0045) +#define MPI_IOCSTATUS_SCSI_IO_DATA_ERROR (0x0046) +#define MPI_IOCSTATUS_SCSI_PROTOCOL_ERROR (0x0047) +#define MPI_IOCSTATUS_SCSI_TASK_TERMINATED (0x0048) +#define MPI_IOCSTATUS_SCSI_RESIDUAL_MISMATCH (0x0049) +#define MPI_IOCSTATUS_SCSI_TASK_MGMT_FAILED (0x004A) +#define MPI_IOCSTATUS_SCSI_IOC_TERMINATED (0x004B) +#define MPI_IOCSTATUS_SCSI_EXT_TERMINATED (0x004C) + +/****************************************************************************/ +/* For use by SCSI Initiator and SCSI Target end-to-end data protection */ +/****************************************************************************/ + +#define MPI_IOCSTATUS_EEDP_CRC_ERROR (0x004D) +#define MPI_IOCSTATUS_EEDP_LBA_TAG_ERROR (0x004E) +#define MPI_IOCSTATUS_EEDP_APP_TAG_ERROR (0x004F) + /****************************************************************************/ /* SCSI (SPI & FCP) target values */ @@ -618,7 +662,8 @@ #define MPI_IOCSTATUS_TARGET_PRIORITY_IO (0x0060) #define MPI_IOCSTATUS_TARGET_INVALID_PORT (0x0061) -#define MPI_IOCSTATUS_TARGET_INVALID_IOCINDEX (0x0062) +#define MPI_IOCSTATUS_TARGET_INVALID_IOCINDEX (0x0062) /* obsolete */ +#define MPI_IOCSTATUS_TARGET_INVALID_IO_INDEX (0x0062) #define MPI_IOCSTATUS_TARGET_ABORTED (0x0063) #define MPI_IOCSTATUS_TARGET_NO_CONN_RETRYABLE (0x0064) #define MPI_IOCSTATUS_TARGET_NO_CONNECTION (0x0065) @@ -626,7 +671,7 @@ #define MPI_IOCSTATUS_TARGET_STS_DATA_NOT_SENT (0x006B) /****************************************************************************/ -/* Additional FCP target values */ +/* Additional FCP target values (obsolete) */ /****************************************************************************/ #define MPI_IOCSTATUS_TARGET_FC_ABORTED (0x0066) /* obsolete */ @@ -642,6 +687,7 @@ #define MPI_IOCSTATUS_FC_RX_ID_INVALID (0x0067) #define MPI_IOCSTATUS_FC_DID_INVALID (0x0068) #define MPI_IOCSTATUS_FC_NODE_LOGGED_OUT (0x0069) +#define MPI_IOCSTATUS_FC_EXCHANGE_CANCELED (0x006C) /****************************************************************************/ /* LAN values */ @@ -656,6 +702,25 @@ #define MPI_IOCSTATUS_LAN_PARTIAL_PACKET (0x0086) #define MPI_IOCSTATUS_LAN_CANCELED (0x0087) +/****************************************************************************/ +/* Serial Attached SCSI values */ +/****************************************************************************/ + +#define MPI_IOCSTATUS_SAS_SMP_REQUEST_FAILED (0x0090) + +/****************************************************************************/ +/* Inband values */ +/****************************************************************************/ + +#define MPI_IOCSTATUS_INBAND_ABORTED (0x0098) +#define MPI_IOCSTATUS_INBAND_NO_CONNECTION (0x0099) + +/****************************************************************************/ +/* Diagnostic Tools values */ +/****************************************************************************/ + +#define MPI_IOCSTATUS_DIAGNOSTIC_RELEASED (0x00A0) + /****************************************************************************/ /* IOCStatus flag to indicate that log info is available */ @@ -669,9 +734,12 @@ /****************************************************************************/ #define MPI_IOCLOGINFO_TYPE_MASK (0xF0000000) +#define MPI_IOCLOGINFO_TYPE_SHIFT (28) #define MPI_IOCLOGINFO_TYPE_NONE (0x0) #define MPI_IOCLOGINFO_TYPE_SCSI (0x1) #define MPI_IOCLOGINFO_TYPE_FC (0x2) +#define MPI_IOCLOGINFO_TYPE_SAS (0x3) +#define MPI_IOCLOGINFO_TYPE_ISCSI (0x4) #define MPI_IOCLOGINFO_LOG_DATA_MASK (0x0FFFFFFF) diff -Nru a/drivers/message/fusion/lsi/mpi_cnfg.h b/drivers/message/fusion/lsi/mpi_cnfg.h --- a/drivers/message/fusion/lsi/mpi_cnfg.h Sun Mar 14 14:20:07 2004 +++ b/drivers/message/fusion/lsi/mpi_cnfg.h Sun Mar 14 14:20:07 2004 @@ -1,12 +1,12 @@ /* - * Copyright (c) 2000-2002 LSI Logic Corporation. + * Copyright (c) 2000-2003 LSI Logic Corporation. * * - * Name: MPI_CNFG.H + * Name: mpi_cnfg.h * Title: MPI Config message, structures, and Pages * Creation Date: July 27, 2000 * - * MPI_CNFG.H Version: 01.02.09 + * mpi_cnfg.h Version: 01.05.xx * * Version History * --------------- @@ -127,7 +127,24 @@ * MPI_SCSIDEVPAGE1_CONF_EXTENDED_PARAMS_ENABLE. * Added new config page: CONFIG_PAGE_SCSI_DEVICE_3. * Modified MPI_FCPORTPAGE5_FLAGS_ defines. - * 09-16-02 01.02.09 Added more MPI_SCSIDEVPAGE1_CONF_FORCE_PPR_MSG define. + * 09-16-02 01.02.09 Added MPI_SCSIDEVPAGE1_CONF_FORCE_PPR_MSG define. + * 11-15-02 01.02.10 Added ConnectedID defines for CONFIG_PAGE_SCSI_PORT_0. + * Added more Flags defines for CONFIG_PAGE_FC_PORT_1. + * Added more Flags defines for CONFIG_PAGE_FC_DEVICE_0. + * 04-01-03 01.02.11 Added RR_TOV field and additional Flags defines for + * CONFIG_PAGE_FC_PORT_1. + * Added define MPI_FCPORTPAGE5_FLAGS_DISABLE to disable + * an alias. + * Added more device id defines. + * 06-26-03 01.02.12 Added MPI_IOUNITPAGE1_IR_USE_STATIC_VOLUME_ID define. + * Added TargetConfig and IDConfig fields to + * CONFIG_PAGE_SCSI_PORT_1. + * Added more PortFlags defines for CONFIG_PAGE_SCSI_PORT_2 + * to control DV. + * Added more Flags defines for CONFIG_PAGE_FC_PORT_1. + * In CONFIG_PAGE_FC_DEVICE_0, replaced Reserved1 field + * with ADISCHardALPA. + * Added MPI_FC_DEVICE_PAGE0_PROT_FCP_RETRY define. * -------------------------------------------------------------------------- */ @@ -159,6 +176,19 @@ } ConfigPageHeaderUnion, MPI_POINTER pConfigPageHeaderUnion, fCONFIG_PAGE_HEADER_UNION, MPI_POINTER PTR_CONFIG_PAGE_HEADER_UNION; +typedef struct _CONFIG_EXTENDED_PAGE_HEADER +{ + U8 PageVersion; /* 00h */ + U8 Reserved1; /* 01h */ + U8 PageNumber; /* 02h */ + U8 PageType; /* 03h */ + U16 ExtPageLength; /* 04h */ + U8 ExtPageType; /* 06h */ + U8 Reserved2; /* 07h */ +} fCONFIG_EXTENDED_PAGE_HEADER, MPI_POINTER PTR_CONFIG_EXTENDED_PAGE_HEADER, + ConfigExtendedPageHeader_t, MPI_POINTER pConfigExtendedPageHeader_t; + + /**************************************************************************** * PageType field values @@ -180,12 +210,23 @@ #define MPI_CONFIG_PAGETYPE_RAID_VOLUME (0x08) #define MPI_CONFIG_PAGETYPE_MANUFACTURING (0x09) #define MPI_CONFIG_PAGETYPE_RAID_PHYSDISK (0x0A) +#define MPI_CONFIG_PAGETYPE_INBAND (0x0B) +#define MPI_CONFIG_PAGETYPE_EXTENDED (0x0F) #define MPI_CONFIG_PAGETYPE_MASK (0x0F) #define MPI_CONFIG_TYPENUM_MASK (0x0FFF) /**************************************************************************** +* ExtPageType field values +****************************************************************************/ +#define MPI_CONFIG_EXTPAGETYPE_SAS_IO_UNIT (0x10) +#define MPI_CONFIG_EXTPAGETYPE_SAS_EXPANDER (0x11) +#define MPI_CONFIG_EXTPAGETYPE_SAS_DEVICE (0x12) +#define MPI_CONFIG_EXTPAGETYPE_SAS_PHY (0x13) + + +/**************************************************************************** * PageAddress field values ****************************************************************************/ #define MPI_SCSI_PORT_PGAD_PORT_MASK (0x000000FF) @@ -219,6 +260,24 @@ #define MPI_PHYSDISK_PGAD_PHYSDISKNUM_MASK (0x000000FF) #define MPI_PHYSDISK_PGAD_PHYSDISKNUM_SHIFT (0) +#define MPI_SAS_DEVICE_PGAD_FORM_MASK (0xF0000000) +#define MPI_SAS_DEVICE_PGAD_FORM_SHIFT (28) +#define MPI_SAS_DEVICE_PGAD_FORM_GET_NEXT_HANDLE (0x00000000) +#define MPI_SAS_DEVICE_PGAD_FORM_BUS_TARGET_ID (0x00000001) +#define MPI_SAS_DEVICE_PGAD_FORM_HANDLE (0x00000002) +#define MPI_SAS_DEVICE_PGAD_GNH_HANDLE_MASK (0x0000FFFF) +#define MPI_SAS_DEVICE_PGAD_GNH_HANDLE_SHIFT (0) +#define MPI_SAS_DEVICE_PGAD_BT_BUS_MASK (0x0000FF00) +#define MPI_SAS_DEVICE_PGAD_BT_BUS_SHIFT (8) +#define MPI_SAS_DEVICE_PGAD_BT_TID_MASK (0x000000FF) +#define MPI_SAS_DEVICE_PGAD_BT_TID_SHIFT (0) +#define MPI_SAS_DEVICE_PGAD_H_HANDLE_MASK (0x0000FFFF) +#define MPI_SAS_DEVICE_PGAD_H_HANDLE_SHIFT (0) + +#define MPI_SAS_PHY_PGAD_PHY_NUMBER_MASK (0x00FF0000) +#define MPI_SAS_PHY_PGAD_PHY_NUMBER_SHIFT (16) +#define MPI_SAS_PHY_PGAD_DEVHANDLE_MASK (0x0000FFFF) +#define MPI_SAS_PHY_PGAD_DEVHANDLE_SHIFT (0) /**************************************************************************** @@ -230,7 +289,8 @@ U8 Reserved; /* 01h */ U8 ChainOffset; /* 02h */ U8 Function; /* 03h */ - U8 Reserved1[3]; /* 04h */ + U16 ExtPageLength; /* 04h */ + U8 ExtPageType; /* 06h */ U8 MsgFlags; /* 07h */ U32 MsgContext; /* 08h */ U8 Reserved2[8]; /* 0Ch */ @@ -260,7 +320,8 @@ U8 Reserved; /* 01h */ U8 MsgLength; /* 02h */ U8 Function; /* 03h */ - U8 Reserved1[3]; /* 04h */ + U16 ExtPageLength; /* 04h */ + U8 ExtPageType; /* 06h */ U8 MsgFlags; /* 07h */ U32 MsgContext; /* 08h */ U8 Reserved2[2]; /* 0Ch */ @@ -281,23 +342,22 @@ /**************************************************************************** * Manufacturing Config pages ****************************************************************************/ +#define MPI_MANUFACTPAGE_VENDORID_LSILOGIC (0x1000) +/* Fibre Channel */ #define MPI_MANUFACTPAGE_DEVICEID_FC909 (0x0621) #define MPI_MANUFACTPAGE_DEVICEID_FC919 (0x0624) #define MPI_MANUFACTPAGE_DEVICEID_FC929 (0x0622) #define MPI_MANUFACTPAGE_DEVICEID_FC919X (0x0628) #define MPI_MANUFACTPAGE_DEVICEID_FC929X (0x0626) - +/* SCSI */ #define MPI_MANUFACTPAGE_DEVID_53C1030 (0x0030) #define MPI_MANUFACTPAGE_DEVID_53C1030ZC (0x0031) #define MPI_MANUFACTPAGE_DEVID_1030_53C1035 (0x0032) #define MPI_MANUFACTPAGE_DEVID_1030ZC_53C1035 (0x0033) #define MPI_MANUFACTPAGE_DEVID_53C1035 (0x0040) #define MPI_MANUFACTPAGE_DEVID_53C1035ZC (0x0041) - -#define MPI_MANUFACTPAGE_DEVID_SA2010 (0x0804) -#define MPI_MANUFACTPAGE_DEVID_SA2010ZC (0x0805) -#define MPI_MANUFACTPAGE_DEVID_SA2020 (0x0806) -#define MPI_MANUFACTPAGE_DEVID_SA2020ZC (0x0807) +/* SAS */ +#define MPI_MANUFACTPAGE_DEVID_SAS1064 (0x0050) typedef struct _CONFIG_PAGE_MANUFACTURING_0 @@ -381,8 +441,8 @@ U8 InfoOffset1; /* 0Ah */ U8 InfoSize1; /* 0Bh */ U8 InquirySize; /* 0Ch */ - U8 Reserved2; /* 0Dh */ - U16 Reserved3; /* 0Eh */ + U8 Flags; /* 0Dh */ + U16 Reserved2; /* 0Eh */ U8 InquiryData[56]; /* 10h */ U32 ISVolumeSettings; /* 48h */ U32 IMEVolumeSettings; /* 4Ch */ @@ -390,7 +450,30 @@ } fCONFIG_PAGE_MANUFACTURING_4, MPI_POINTER PTR_CONFIG_PAGE_MANUFACTURING_4, ManufacturingPage4_t, MPI_POINTER pManufacturingPage4_t; -#define MPI_MANUFACTURING4_PAGEVERSION (0x00) +#define MPI_MANUFACTURING4_PAGEVERSION (0x01) + +/* defines for the Flags field */ +#define MPI_MANPAGE4_IR_NO_MIX_SAS_SATA (0x01) + + +typedef struct _CONFIG_PAGE_MANUFACTURING_5 +{ + fCONFIG_PAGE_HEADER Header; /* 00h */ + U64 BaseWWID; /* 04h */ +} fCONFIG_PAGE_MANUFACTURING_5, MPI_POINTER PTR_CONFIG_PAGE_MANUFACTURING_5, + ManufacturingPage5_t, MPI_POINTER pManufacturingPage5_t; + +#define MPI_MANUFACTURING5_PAGEVERSION (0x00) + + +typedef struct _CONFIG_PAGE_MANUFACTURING_6 +{ + fCONFIG_PAGE_HEADER Header; /* 00h */ + U32 ProductSpecificInfo;/* 04h */ +} fCONFIG_PAGE_MANUFACTURING_6, MPI_POINTER PTR_CONFIG_PAGE_MANUFACTURING_6, + ManufacturingPage6_t, MPI_POINTER pManufacturingPage6_t; + +#define MPI_MANUFACTURING6_PAGEVERSION (0x00) /**************************************************************************** @@ -414,16 +497,18 @@ } fCONFIG_PAGE_IO_UNIT_1, MPI_POINTER PTR_CONFIG_PAGE_IO_UNIT_1, IOUnitPage1_t, MPI_POINTER pIOUnitPage1_t; -#define MPI_IOUNITPAGE1_PAGEVERSION (0x00) +#define MPI_IOUNITPAGE1_PAGEVERSION (0x01) /* IO Unit Page 1 Flags defines */ - #define MPI_IOUNITPAGE1_MULTI_FUNCTION (0x00000000) #define MPI_IOUNITPAGE1_SINGLE_FUNCTION (0x00000001) #define MPI_IOUNITPAGE1_MULTI_PATHING (0x00000002) #define MPI_IOUNITPAGE1_SINGLE_PATHING (0x00000000) +#define MPI_IOUNITPAGE1_IR_USE_STATIC_VOLUME_ID (0x00000004) +#define MPI_IOUNITPAGE1_DISABLE_QUEUE_FULL_HANDLING (0x00000020) #define MPI_IOUNITPAGE1_DISABLE_IR (0x00000040) #define MPI_IOUNITPAGE1_FORCE_32 (0x00000080) +#define MPI_IOUNITPAGE1_NATIVE_COMMAND_Q_DISABLE (0x00000100) typedef struct _MPI_ADAPTER_INFO @@ -453,6 +538,11 @@ #define MPI_IOUNITPAGE2_FLAGS_COLOR_VIDEO_DISABLE (0x00000008) #define MPI_IOUNITPAGE2_FLAGS_DONT_HOOK_INT_40 (0x00000010) +#define MPI_IOUNITPAGE2_FLAGS_DEV_LIST_DISPLAY_MASK (0x000000E0) +#define MPI_IOUNITPAGE2_FLAGS_INSTALLED_DEV_DISPLAY (0x00000000) +#define MPI_IOUNITPAGE2_FLAGS_ADAPTER_DISPLAY (0x00000020) +#define MPI_IOUNITPAGE2_FLAGS_ADAPTER_DEV_DISPLAY (0x00000040) + /* * Host code (drivers, BIOS, utilities, etc.) should leave this define set to @@ -515,6 +605,12 @@ #define MPI_IOCPAGE1_PAGEVERSION (0x01) +/* defines for the Flags field */ +#define MPI_IOCPAGE1_EEDP_HOST_SUPPORTS_DIF (0x08000000) +#define MPI_IOCPAGE1_EEDP_MODE_MASK (0x07000000) +#define MPI_IOCPAGE1_EEDP_MODE_OFF (0x00000000) +#define MPI_IOCPAGE1_EEDP_MODE_T10 (0x01000000) +#define MPI_IOCPAGE1_EEDP_MODE_LSI_1 (0x02000000) #define MPI_IOCPAGE1_REPLY_COALESCING (0x00000001) #define MPI_IOCPAGE1_PCISLOTNUM_UNKNOWN (0xFF) @@ -655,7 +751,7 @@ typedef struct _CONFIG_PAGE_IOC_5 { - fCONFIG_PAGE_HEADER Header; /* 00h */ + fCONFIG_PAGE_HEADER Header; /* 00h */ U32 Reserved1; /* 04h */ U8 NumHotSpares; /* 08h */ U8 Reserved2; /* 09h */ @@ -667,6 +763,57 @@ #define MPI_IOCPAGE5_PAGEVERSION (0x00) +/**************************************************************************** +* BIOS Port Config Pages +****************************************************************************/ + +typedef struct _CONFIG_PAGE_BIOS_1 +{ + fCONFIG_PAGE_HEADER Header; /* 00h */ + U32 BiosOptions; /* 04h */ + U32 IOCSettings; /* 08h */ + U32 Reserved1; /* 0Ch */ + U32 DeviceSettings; /* 10h */ + U16 NumberOfDevices; /* 14h */ + U16 Reserved2; /* 16h */ + U16 IOTimeoutBlockDevicesNonRM; /* 18h */ + U16 IOTimeoutSequential; /* 1Ah */ + U16 IOTimeoutOther; /* 1Ch */ + U16 IOTimeoutBlockDevicesRM; /* 1Eh */ +} fCONFIG_PAGE_BIOS_1, MPI_POINTER PTR_CONFIG_PAGE_BIOS_1, + BIOSPage1_t, MPI_POINTER pBIOSPage1_t; + +#define MPI_BIOSPAGE1_PAGEVERSION (0x00) + +/* values for the BiosOptions field */ +#define MPI_BIOSPAGE1_OPTIONS_SPI_ENABLE (0x00000400) +#define MPI_BIOSPAGE1_OPTIONS_FC_ENABLE (0x00000200) +#define MPI_BIOSPAGE1_OPTIONS_SAS_ENABLE (0x00000100) +#define MPI_BIOSPAGE1_OPTIONS_DISABLE_BIOS (0x00000001) + +/* values for the IOCSettings field */ +#define MPI_BIOSPAGE1_IOCSET_MASK_SPINUP_DELAY (0x00000F00) +#define MPI_BIOSPAGE1_IOCSET_SHIFT_SPINUP_DELAY (8) + +#define MPI_BIOSPAGE1_IOCSET_MASK_RM_SETTING (0x000000C0) +#define MPI_BIOSPAGE1_IOCSET_NONE_RM_SETTING (0x00000000) +#define MPI_BIOSPAGE1_IOCSET_BOOT_RM_SETTING (0x00000040) +#define MPI_BIOSPAGE1_IOCSET_MEDIA_RM_SETTING (0x00000080) + +#define MPI_BIOSPAGE1_IOCSET_MASK_ADAPTER_SUPPORT (0x00000030) +#define MPI_BIOSPAGE1_IOCSET_NO_SUPPORT (0x00000000) +#define MPI_BIOSPAGE1_IOCSET_BIOS_SUPPORT (0x00000010) +#define MPI_BIOSPAGE1_IOCSET_OS_SUPPORT (0x00000020) +#define MPI_BIOSPAGE1_IOCSET_ALL_SUPPORT (0x00000030) + +#define MPI_BIOSPAGE1_IOCSET_ALTERNATE_CHS (0x00000008) + +/* values for the DeviceSettings field */ +#define MPI_BIOSPAGE1_DEVSET_DISABLE_SEQ_LUN (0x00000008) +#define MPI_BIOSPAGE1_DEVSET_DISABLE_RM_LUN (0x00000004) +#define MPI_BIOSPAGE1_DEVSET_DISABLE_NON_RM_LUN (0x00000002) +#define MPI_BIOSPAGE1_DEVSET_DISABLE_OTHER_LUN (0x00000001) + /**************************************************************************** * SCSI Port Config Pages @@ -686,7 +833,27 @@ #define MPI_SCSIPORTPAGE0_CAP_DT (0x00000002) #define MPI_SCSIPORTPAGE0_CAP_QAS (0x00000004) #define MPI_SCSIPORTPAGE0_CAP_MIN_SYNC_PERIOD_MASK (0x0000FF00) +#define MPI_SCSIPORTPAGE0_SYNC_ASYNC (0x00) +#define MPI_SCSIPORTPAGE0_SYNC_5 (0x32) +#define MPI_SCSIPORTPAGE0_SYNC_10 (0x19) +#define MPI_SCSIPORTPAGE0_SYNC_20 (0x0C) +#define MPI_SCSIPORTPAGE0_SYNC_33_33 (0x0B) +#define MPI_SCSIPORTPAGE0_SYNC_40 (0x0A) +#define MPI_SCSIPORTPAGE0_SYNC_80 (0x09) +#define MPI_SCSIPORTPAGE0_SYNC_160 (0x08) +#define MPI_SCSIPORTPAGE0_SYNC_UNKNOWN (0xFF) + +#define MPI_SCSIPORTPAGE0_CAP_SHIFT_MIN_SYNC_PERIOD (8) +#define MPI_SCSIPORTPAGE0_CAP_GET_MIN_SYNC_PERIOD(Cap) \ + ( ((Cap) & MPI_SCSIPORTPAGE0_CAP_MASK_MIN_SYNC_PERIOD) \ + >> MPI_SCSIPORTPAGE0_CAP_SHIFT_MIN_SYNC_PERIOD \ + ) #define MPI_SCSIPORTPAGE0_CAP_MAX_SYNC_OFFSET_MASK (0x00FF0000) +#define MPI_SCSIPORTPAGE0_CAP_SHIFT_MAX_SYNC_OFFSET (16) +#define MPI_SCSIPORTPAGE0_CAP_GET_MAX_SYNC_OFFSET(Cap) \ + ( ((Cap) & MPI_SCSIPORTPAGE0_CAP_MASK_MAX_SYNC_OFFSET) \ + >> MPI_SCSIPORTPAGE0_CAP_SHIFT_MAX_SYNC_OFFSET \ + ) #define MPI_SCSIPORTPAGE0_CAP_WIDE (0x20000000) #define MPI_SCSIPORTPAGE0_CAP_AIP (0x80000000) @@ -694,6 +861,10 @@ #define MPI_SCSIPORTPAGE0_PHY_SIGNAL_HVD (0x01) #define MPI_SCSIPORTPAGE0_PHY_SIGNAL_SE (0x02) #define MPI_SCSIPORTPAGE0_PHY_SIGNAL_LVD (0x03) +#define MPI_SCSIPORTPAGE0_PHY_MASK_CONNECTED_ID (0xFF000000) +#define MPI_SCSIPORTPAGE0_PHY_SHIFT_CONNECTED_ID (24) +#define MPI_SCSIPORTPAGE0_PHY_BUS_FREE_CONNECTED_ID (0xFE) +#define MPI_SCSIPORTPAGE0_PHY_UNKNOWN_CONNECTED_ID (0xFF) typedef struct _CONFIG_PAGE_SCSI_PORT_1 @@ -701,13 +872,22 @@ fCONFIG_PAGE_HEADER Header; /* 00h */ U32 Configuration; /* 04h */ U32 OnBusTimerValue; /* 08h */ + U8 TargetConfig; /* 0Ch */ + U8 Reserved1; /* 0Dh */ + U16 IDConfig; /* 0Eh */ } fCONFIG_PAGE_SCSI_PORT_1, MPI_POINTER PTR_CONFIG_PAGE_SCSI_PORT_1, SCSIPortPage1_t, MPI_POINTER pSCSIPortPage1_t; -#define MPI_SCSIPORTPAGE1_PAGEVERSION (0x02) +#define MPI_SCSIPORTPAGE1_PAGEVERSION (0x03) +/* Configuration values */ #define MPI_SCSIPORTPAGE1_CFG_PORT_SCSI_ID_MASK (0x000000FF) #define MPI_SCSIPORTPAGE1_CFG_PORT_RESPONSE_ID_MASK (0xFFFF0000) +#define MPI_SCSIPORTPAGE1_CFG_SHIFT_PORT_RESPONSE_ID (16) + +/* TargetConfig values */ +#define MPI_SCSIPORTPAGE1_TARGCONFIG_TARG_ONLY (0x01) +#define MPI_SCSIPORTPAGE1_TARGCONFIG_INIT_TARG (0x02) typedef struct _MPI_DEVICE_INFO @@ -727,13 +907,21 @@ } fCONFIG_PAGE_SCSI_PORT_2, MPI_POINTER PTR_CONFIG_PAGE_SCSI_PORT_2, SCSIPortPage2_t, MPI_POINTER pSCSIPortPage2_t; -#define MPI_SCSIPORTPAGE2_PAGEVERSION (0x01) +#define MPI_SCSIPORTPAGE2_PAGEVERSION (0x02) +/* PortFlags values */ #define MPI_SCSIPORTPAGE2_PORT_FLAGS_SCAN_HIGH_TO_LOW (0x00000001) #define MPI_SCSIPORTPAGE2_PORT_FLAGS_AVOID_SCSI_RESET (0x00000004) #define MPI_SCSIPORTPAGE2_PORT_FLAGS_ALTERNATE_CHS (0x00000008) #define MPI_SCSIPORTPAGE2_PORT_FLAGS_TERMINATION_DISABLE (0x00000010) +#define MPI_SCSIPORTPAGE2_PORT_FLAGS_DV_MASK (0x00000060) +#define MPI_SCSIPORTPAGE2_PORT_FLAGS_FULL_DV (0x00000000) +#define MPI_SCSIPORTPAGE2_PORT_FLAGS_BASIC_DV_ONLY (0x00000020) +#define MPI_SCSIPORTPAGE2_PORT_FLAGS_OFF_DV (0x00000060) + + +/* PortSettings values */ #define MPI_SCSIPORTPAGE2_PORT_HOST_ID_MASK (0x0000000F) #define MPI_SCSIPORTPAGE2_PORT_MASK_INIT_HBA (0x00000030) #define MPI_SCSIPORTPAGE2_PORT_DISABLE_INIT_HBA (0x00000000) @@ -741,7 +929,11 @@ #define MPI_SCSIPORTPAGE2_PORT_OS_INIT_HBA (0x00000020) #define MPI_SCSIPORTPAGE2_PORT_BIOS_OS_INIT_HBA (0x00000030) #define MPI_SCSIPORTPAGE2_PORT_REMOVABLE_MEDIA (0x000000C0) +#define MPI_SCSIPORTPAGE2_PORT_RM_NONE (0x00000000) +#define MPI_SCSIPORTPAGE2_PORT_RM_BOOT_ONLY (0x00000040) +#define MPI_SCSIPORTPAGE2_PORT_RM_WITH_MEDIA (0x00000080) #define MPI_SCSIPORTPAGE2_PORT_SPINUP_DELAY_MASK (0x00000F00) +#define MPI_SCSIPORTPAGE2_PORT_SHIFT_SPINUP_DELAY (8) #define MPI_SCSIPORTPAGE2_PORT_MASK_NEGO_MASTER_SETTINGS (0x00003000) #define MPI_SCSIPORTPAGE2_PORT_NEGO_MASTER_SETTINGS (0x00000000) #define MPI_SCSIPORTPAGE2_PORT_NONE_MASTER_SETTINGS (0x00001000) @@ -778,7 +970,9 @@ #define MPI_SCSIDEVPAGE0_NP_RTI (0x00000040) #define MPI_SCSIDEVPAGE0_NP_PCOMP_EN (0x00000080) #define MPI_SCSIDEVPAGE0_NP_NEG_SYNC_PERIOD_MASK (0x0000FF00) +#define MPI_SCSIDEVPAGE0_NP_SHIFT_SYNC_PERIOD (8) #define MPI_SCSIDEVPAGE0_NP_NEG_SYNC_OFFSET_MASK (0x00FF0000) +#define MPI_SCSIDEVPAGE0_NP_SHIFT_SYNC_OFFSET (16) #define MPI_SCSIDEVPAGE0_NP_WIDE (0x20000000) #define MPI_SCSIDEVPAGE0_NP_AIP (0x80000000) @@ -808,7 +1002,9 @@ #define MPI_SCSIDEVPAGE1_RP_RTI (0x00000040) #define MPI_SCSIDEVPAGE1_RP_PCOMP_EN (0x00000080) #define MPI_SCSIDEVPAGE1_RP_MIN_SYNC_PERIOD_MASK (0x0000FF00) +#define MPI_SCSIDEVPAGE1_RP_SHIFT_MIN_SYNC_PERIOD (8) #define MPI_SCSIDEVPAGE1_RP_MAX_SYNC_OFFSET_MASK (0x00FF0000) +#define MPI_SCSIDEVPAGE1_RP_SHIFT_MAX_SYNC_OFFSET (16) #define MPI_SCSIDEVPAGE1_RP_WIDE (0x20000000) #define MPI_SCSIDEVPAGE1_RP_AIP (0x80000000) @@ -915,7 +1111,7 @@ #define MPI_FCPORTPAGE0_FLAGS_ALIAS_ALPA_SUPPORTED (0x00000010) #define MPI_FCPORTPAGE0_FLAGS_ALIAS_WWN_SUPPORTED (0x00000020) -#define MPI_FCPORTPAGE0_FLAGS_FABRIC_WWN_VALID (0x00000030) +#define MPI_FCPORTPAGE0_FLAGS_FABRIC_WWN_VALID (0x00000040) #define MPI_FCPORTPAGE0_FLAGS_ATTACH_TYPE_MASK (0x00000F00) #define MPI_FCPORTPAGE0_FLAGS_ATTACH_NO_INIT (0x00000000) @@ -954,13 +1150,19 @@ #define MPI_FCPORTPAGE0_SUPPORT_CLASS_2 (0x00000002) #define MPI_FCPORTPAGE0_SUPPORT_CLASS_3 (0x00000004) -#define MPI_FCPORTPAGE0_SUPPORT_1GBIT_SPEED (0x00000001) /* (SNIA)HBA_PORTSPEED_1GBIT 1 1 GBit/sec */ -#define MPI_FCPORTPAGE0_SUPPORT_2GBIT_SPEED (0x00000002) /* (SNIA)HBA_PORTSPEED_2GBIT 2 2 GBit/sec */ -#define MPI_FCPORTPAGE0_SUPPORT_10GBIT_SPEED (0x00000004) /* (SNIA)HBA_PORTSPEED_10GBIT 4 10 GBit/sec */ +#define MPI_FCPORTPAGE0_SUPPORT_SPEED_UKNOWN (0x00000000) /* (SNIA)HBA_PORTSPEED_UNKNOWN 0 Unknown - transceiver incapable of reporting */ +#define MPI_FCPORTPAGE0_SUPPORT_1GBIT_SPEED (0x00000001) /* (SNIA)HBA_PORTSPEED_1GBIT 1 1 GBit/sec */ +#define MPI_FCPORTPAGE0_SUPPORT_2GBIT_SPEED (0x00000002) /* (SNIA)HBA_PORTSPEED_2GBIT 2 2 GBit/sec */ +#define MPI_FCPORTPAGE0_SUPPORT_10GBIT_SPEED (0x00000004) /* (SNIA)HBA_PORTSPEED_10GBIT 4 10 GBit/sec */ +#define MPI_FCPORTPAGE0_SUPPORT_4GBIT_SPEED (0x00000008) /* (SNIA)HBA_PORTSPEED_4GBIT 8 4 GBit/sec */ +#define MPI_FCPORTPAGE0_CURRENT_SPEED_UKNOWN MPI_FCPORTPAGE0_SUPPORT_SPEED_UKNOWN #define MPI_FCPORTPAGE0_CURRENT_SPEED_1GBIT MPI_FCPORTPAGE0_SUPPORT_1GBIT_SPEED #define MPI_FCPORTPAGE0_CURRENT_SPEED_2GBIT MPI_FCPORTPAGE0_SUPPORT_2GBIT_SPEED #define MPI_FCPORTPAGE0_CURRENT_SPEED_10GBIT MPI_FCPORTPAGE0_SUPPORT_10GBIT_SPEED +#define MPI_FCPORTPAGE0_CURRENT_SPEED_4GBIT MPI_FCPORTPAGE0_SUPPORT_4GBIT_SPEED +#define MPI_FCPORTPAGE0_CURRENT_SPEED_NOT_NEGOTIATED (0x00008000) /* (SNIA)HBA_PORTSPEED_NOT_NEGOTIATED (1<<15) Speed not established */ + typedef struct _CONFIG_PAGE_FC_PORT_1 @@ -974,15 +1176,25 @@ U8 TopologyConfig; /* 1Ah */ U8 AltConnector; /* 1Bh */ U8 NumRequestedAliases; /* 1Ch */ - U8 Reserved1; /* 1Dh */ - U16 Reserved2; /* 1Eh */ + U8 RR_TOV; /* 1Dh */ + U8 InitiatorDeviceTimeout; /* 1Eh */ + U8 InitiatorIoPendTimeout; /* 1Fh */ } fCONFIG_PAGE_FC_PORT_1, MPI_POINTER PTR_CONFIG_PAGE_FC_PORT_1, FCPortPage1_t, MPI_POINTER pFCPortPage1_t; -#define MPI_FCPORTPAGE1_PAGEVERSION (0x04) +#define MPI_FCPORTPAGE1_PAGEVERSION (0x06) #define MPI_FCPORTPAGE1_FLAGS_EXT_FCP_STATUS_EN (0x08000000) #define MPI_FCPORTPAGE1_FLAGS_IMMEDIATE_ERROR_REPLY (0x04000000) +#define MPI_FCPORTPAGE1_FLAGS_FORCE_USE_NOSEEPROM_WWNS (0x02000000) +#define MPI_FCPORTPAGE1_FLAGS_VERBOSE_RESCAN_EVENTS (0x01000000) +#define MPI_FCPORTPAGE1_FLAGS_TARGET_MODE_OXID (0x00800000) +#define MPI_FCPORTPAGE1_FLAGS_PORT_OFFLINE (0x00400000) +#define MPI_FCPORTPAGE1_FLAGS_SOFT_ALPA_FALLBACK (0x00200000) +#define MPI_FCPORTPAGE1_FLAGS_MASK_RR_TOV_UNITS (0x00000070) +#define MPI_FCPORTPAGE1_FLAGS_SUPPRESS_PROT_REG (0x00000008) +#define MPI_FCPORTPAGE1_FLAGS_PLOGI_ON_LOGO (0x00000004) +#define MPI_FCPORTPAGE1_FLAGS_MAINTAIN_LOGINS (0x00000002) #define MPI_FCPORTPAGE1_FLAGS_SORT_BY_DID (0x00000001) #define MPI_FCPORTPAGE1_FLAGS_SORT_BY_WWN (0x00000000) @@ -993,6 +1205,11 @@ #define MPI_FCPORTPAGE1_FLAGS_PROT_LAN ((U32)MPI_PORTFACTS_PROTOCOL_LAN << MPI_FCPORTPAGE1_FLAGS_PROT_SHIFT) #define MPI_FCPORTPAGE1_FLAGS_PROT_LOGBUSADDR ((U32)MPI_PORTFACTS_PROTOCOL_LOGBUSADDR << MPI_FCPORTPAGE1_FLAGS_PROT_SHIFT) +#define MPI_FCPORTPAGE1_FLAGS_NONE_RR_TOV_UNITS (0x00000000) +#define MPI_FCPORTPAGE1_FLAGS_THOUSANDTH_RR_TOV_UNITS (0x00000010) +#define MPI_FCPORTPAGE1_FLAGS_TENTH_RR_TOV_UNITS (0x00000030) +#define MPI_FCPORTPAGE1_FLAGS_TEN_RR_TOV_UNITS (0x00000050) + #define MPI_FCPORTPAGE1_HARD_ALPA_NOT_USED (0xFF) #define MPI_FCPORTPAGE1_LCONFIG_SPEED_MASK (0x0F) @@ -1009,6 +1226,8 @@ #define MPI_FCPORTPAGE1_ALT_CONN_UNKNOWN (0x00) +#define MPI_FCPORTPAGE1_INITIATOR_DEV_TIMEOUT_MASK (0x7F) + typedef struct _CONFIG_PAGE_FC_PORT_2 { @@ -1108,12 +1327,13 @@ } fCONFIG_PAGE_FC_PORT_5, MPI_POINTER PTR_CONFIG_PAGE_FC_PORT_5, FCPortPage5_t, MPI_POINTER pFCPortPage5_t; -#define MPI_FCPORTPAGE5_PAGEVERSION (0x01) +#define MPI_FCPORTPAGE5_PAGEVERSION (0x02) #define MPI_FCPORTPAGE5_FLAGS_ALPA_ACQUIRED (0x01) #define MPI_FCPORTPAGE5_FLAGS_HARD_ALPA (0x02) #define MPI_FCPORTPAGE5_FLAGS_HARD_WWNN (0x04) #define MPI_FCPORTPAGE5_FLAGS_HARD_WWPN (0x08) +#define MPI_FCPORTPAGE5_FLAGS_DISABLE (0x10) typedef struct _CONFIG_PAGE_FC_PORT_6 { @@ -1322,7 +1542,7 @@ U8 Flags; /* 19h */ U16 BBCredit; /* 1Ah */ U16 MaxRxFrameSize; /* 1Ch */ - U8 Reserved1; /* 1Eh */ + U8 ADISCHardALPA; /* 1Eh */ U8 PortNumber; /* 1Fh */ U8 FcPhLowestVersion; /* 20h */ U8 FcPhHighestVersion; /* 21h */ @@ -1331,13 +1551,16 @@ } fCONFIG_PAGE_FC_DEVICE_0, MPI_POINTER PTR_CONFIG_PAGE_FC_DEVICE_0, FCDevicePage0_t, MPI_POINTER pFCDevicePage0_t; -#define MPI_FC_DEVICE_PAGE0_PAGEVERSION (0x02) +#define MPI_FC_DEVICE_PAGE0_PAGEVERSION (0x03) #define MPI_FC_DEVICE_PAGE0_FLAGS_TARGETID_BUS_VALID (0x01) +#define MPI_FC_DEVICE_PAGE0_FLAGS_PLOGI_INVALID (0x02) +#define MPI_FC_DEVICE_PAGE0_FLAGS_PRLI_INVALID (0x04) #define MPI_FC_DEVICE_PAGE0_PROT_IP (0x01) #define MPI_FC_DEVICE_PAGE0_PROT_FCP_TARGET (0x02) #define MPI_FC_DEVICE_PAGE0_PROT_FCP_INITIATOR (0x04) +#define MPI_FC_DEVICE_PAGE0_PROT_FCP_RETRY (0x08) #define MPI_FC_DEVICE_PAGE0_PGAD_PORT_MASK (MPI_FC_DEVICE_PGAD_PORT_MASK) #define MPI_FC_DEVICE_PAGE0_PGAD_FORM_MASK (MPI_FC_DEVICE_PGAD_FORM_MASK) @@ -1348,6 +1571,7 @@ #define MPI_FC_DEVICE_PAGE0_PGAD_BUS_SHIFT (MPI_FC_DEVICE_PGAD_BT_BUS_SHIFT) #define MPI_FC_DEVICE_PAGE0_PGAD_TID_MASK (MPI_FC_DEVICE_PGAD_BT_TID_MASK) +#define MPI_FC_DEVICE_PAGE0_HARD_ALPA_UNKNOWN (0xFF) /**************************************************************************** * RAID Volume Config Pages @@ -1564,6 +1788,318 @@ #define MPI_LAN_PAGE1_DEV_STATE_RESET (0x00) #define MPI_LAN_PAGE1_DEV_STATE_OPERATIONAL (0x01) + + +/**************************************************************************** +* Inband Config Pages +****************************************************************************/ + +typedef struct _CONFIG_PAGE_INBAND_0 +{ + fCONFIG_PAGE_HEADER Header; /* 00h */ + MPI_VERSION_FORMAT InbandVersion; /* 04h */ + U16 MaximumBuffers; /* 08h */ + U16 Reserved1; /* 0Ah */ +} fCONFIG_PAGE_INBAND_0, MPI_POINTER PTR_CONFIG_PAGE_INBAND_0, + InbandPage0_t, MPI_POINTER pInbandPage0_t; + +#define MPI_INBAND_PAGEVERSION (0x00) + + + +/**************************************************************************** +* SAS IO Unit Config Pages +****************************************************************************/ + +typedef struct _MPI_SAS_IO_UNIT0_PHY_DATA +{ + U8 Port; /* 00h */ + U8 PortFlags; /* 01h */ + U8 PhyFlags; /* 02h */ + U8 NegotiatedLinkRate; /* 03h */ + U32 ControllerPhyDeviceInfo;/* 04h */ + U16 AttachedDeviceHandle; /* 08h */ + U16 ControllerDevHandle; /* 0Ah */ + U32 Reserved2; /* 0Ch */ +} MPI_SAS_IO_UNIT0_PHY_DATA, MPI_POINTER PTR_MPI_SAS_IO_UNIT0_PHY_DATA, + SasIOUnit0PhyData, MPI_POINTER pSasIOUnit0PhyData; + +/* + * Host code (drivers, BIOS, utilities, etc.) should leave this define set to + * one and check Header.PageLength at runtime. + */ +#ifndef MPI_SAS_IOUNIT0_PHY_MAX +#define MPI_SAS_IOUNIT0_PHY_MAX (1) +#endif + +typedef struct _CONFIG_PAGE_SAS_IO_UNIT_0 +{ + fCONFIG_EXTENDED_PAGE_HEADER Header; /* 00h */ + U32 Reserved1; /* 08h */ + U8 NumPhys; /* 0Ch */ + U8 Reserved2; /* 0Dh */ + U16 Reserved3; /* 0Eh */ + MPI_SAS_IO_UNIT0_PHY_DATA PhyData[MPI_SAS_IOUNIT0_PHY_MAX]; /* 10h */ +} fCONFIG_PAGE_SAS_IO_UNIT_0, MPI_POINTER PTR_CONFIG_PAGE_SAS_IO_UNIT_0, + SasIOUnitPage0_t, MPI_POINTER pSasIOUnitPage0_t; + +#define MPI_SASIOUNITPAGE0_PAGEVERSION (0x00) + +/* values for SAS IO Unit Page 0 PortFlags */ +#define MPI_SAS_IOUNIT0_PORT_FLAGS_DISCOVERY_IN_PROGRESS (0x08) +#define MPI_SAS_IOUNIT0_PORT_FLAGS_0_TARGET_IOC_NUM (0x00) +#define MPI_SAS_IOUNIT0_PORT_FLAGS_1_TARGET_IOC_NUM (0x04) +#define MPI_SAS_IOUNIT0_PORT_FLAGS_WAIT_FOR_PORTENABLE (0x02) +#define MPI_SAS_IOUNIT0_PORT_FLAGS_AUTO_PORT_CONFIG (0x01) + +/* values for SAS IO Unit Page 0 PhyFlags */ +#define MPI_SAS_IOUNIT0_PHY_FLAGS_PHY_DISABLED (0x04) +#define MPI_SAS_IOUNIT0_PHY_FLAGS_TX_INVERT (0x02) +#define MPI_SAS_IOUNIT0_PHY_FLAGS_RX_INVERT (0x01) + +/* values for SAS IO Unit Page 0 NegotiatedLinkRate */ +#define MPI_SAS_IOUNIT0_RATE_UNKNOWN (0x00) +#define MPI_SAS_IOUNIT0_RATE_PHY_DISABLED (0x01) +#define MPI_SAS_IOUNIT0_RATE_FAILED_SPEED_NEGOTIATION (0x02) +#define MPI_SAS_IOUNIT0_RATE_SATA_OOB_COMPLETE (0x03) +#define MPI_SAS_IOUNIT0_RATE_1_5 (0x08) +#define MPI_SAS_IOUNIT0_RATE_3_0 (0x09) + +/* see mpi_sas.h for values for SAS IO Unit Page 0 ControllerPhyDeviceInfo values */ + + +typedef struct _MPI_SAS_IO_UNIT1_PHY_DATA +{ + U8 Port; /* 00h */ + U8 PortFlags; /* 01h */ + U8 PhyFlags; /* 02h */ + U8 MaxMinLinkRate; /* 03h */ + U32 ControllerPhyDeviceInfo;/* 04h */ + U32 Reserved1; /* 08h */ +} MPI_SAS_IO_UNIT1_PHY_DATA, MPI_POINTER PTR_MPI_SAS_IO_UNIT1_PHY_DATA, + SasIOUnit1PhyData, MPI_POINTER pSasIOUnit1PhyData; + +/* + * Host code (drivers, BIOS, utilities, etc.) should leave this define set to + * one and check Header.PageLength at runtime. + */ +#ifndef MPI_SAS_IOUNIT1_PHY_MAX +#define MPI_SAS_IOUNIT1_PHY_MAX (1) +#endif + +typedef struct _CONFIG_PAGE_SAS_IO_UNIT_1 +{ + fCONFIG_EXTENDED_PAGE_HEADER Header; /* 00h */ + U32 Reserved1; /* 08h */ + U8 NumPhys; /* 0Ch */ + U8 Reserved2; /* 0Dh */ + U16 Reserved3; /* 0Eh */ + MPI_SAS_IO_UNIT1_PHY_DATA PhyData[MPI_SAS_IOUNIT1_PHY_MAX]; /* 10h */ +} fCONFIG_PAGE_SAS_IO_UNIT_1, MPI_POINTER PTR_CONFIG_PAGE_SAS_IO_UNIT_1, + SasIOUnitPage1_t, MPI_POINTER pSasIOUnitPage1_t; + +#define MPI_SASIOUNITPAGE1_PAGEVERSION (0x00) + +/* values for SAS IO Unit Page 0 PortFlags */ +#define MPI_SAS_IOUNIT1_PORT_FLAGS_0_TARGET_IOC_NUM (0x00) +#define MPI_SAS_IOUNIT1_PORT_FLAGS_1_TARGET_IOC_NUM (0x04) +#define MPI_SAS_IOUNIT1_PORT_FLAGS_WAIT_FOR_PORTENABLE (0x02) +#define MPI_SAS_IOUNIT1_PORT_FLAGS_AUTO_PORT_CONFIG (0x01) + +/* values for SAS IO Unit Page 0 PhyFlags */ +#define MPI_SAS_IOUNIT1_PHY_FLAGS_PHY_DISABLE (0x04) +#define MPI_SAS_IOUNIT1_PHY_FLAGS_TX_INVERT (0x02) +#define MPI_SAS_IOUNIT1_PHY_FLAGS_RX_INVERT (0x01) + +/* values for SAS IO Unit Page 0 MaxMinLinkRate */ +#define MPI_SAS_IOUNIT1_MAX_RATE_MASK (0xF0) +#define MPI_SAS_IOUNIT1_MAX_RATE_1_5 (0x80) +#define MPI_SAS_IOUNIT1_MAX_RATE_3_0 (0x90) +#define MPI_SAS_IOUNIT1_MIN_RATE_MASK (0x0F) +#define MPI_SAS_IOUNIT1_MIN_RATE_1_5 (0x08) +#define MPI_SAS_IOUNIT1_MIN_RATE_3_0 (0x09) + +/* see mpi_sas.h for values for SAS IO Unit Page 1 ControllerPhyDeviceInfo values */ + + +typedef struct _CONFIG_PAGE_SAS_IO_UNIT_2 +{ + fCONFIG_EXTENDED_PAGE_HEADER Header; /* 00h */ + U32 Reserved1; /* 08h */ + U16 MaxPersistentIDs; /* 0Ch */ + U16 NumPersistentIDsUsed; /* 0Eh */ + U8 Status; /* 10h */ + U8 Flags; /* 11h */ + U16 Reserved2; /* 12h */ +} fCONFIG_PAGE_SAS_IO_UNIT_2, MPI_POINTER PTR_CONFIG_PAGE_SAS_IO_UNIT_2, + SasIOUnitPage2_t, MPI_POINTER pSasIOUnitPage2_t; + +#define MPI_SASIOUNITPAGE2_PAGEVERSION (0x00) + +/* values for SAS IO Unit Page 2 Status field */ +#define MPI_SAS_IOUNIT2_STATUS_DISABLED_PERSISTENT_MAPPINGS (0x02) +#define MPI_SAS_IOUNIT2_STATUS_FULL_PERSISTENT_MAPPINGS (0x01) + +/* values for SAS IO Unit Page 2 Flags field */ +#define MPI_SAS_IOUNIT2_FLAGS_DISABLE_PERSISTENT_MAPPINGS (0x01) + + +typedef struct _CONFIG_PAGE_SAS_IO_UNIT_3 +{ + fCONFIG_EXTENDED_PAGE_HEADER Header; /* 00h */ + U32 Reserved1; /* 08h */ + U32 MaxInvalidDwordCount; /* 0Ch */ + U32 InvalidDwordCountTime; /* 10h */ + U32 MaxRunningDisparityErrorCount; /* 14h */ + U32 RunningDisparityErrorTime; /* 18h */ + U32 MaxLossDwordSynchCount; /* 1Ch */ + U32 LossDwordSynchCountTime; /* 20h */ + U32 MaxPhyResetProblemCount; /* 24h */ + U32 PhyResetProblemTime; /* 28h */ +} fCONFIG_PAGE_SAS_IO_UNIT_3, MPI_POINTER PTR_CONFIG_PAGE_SAS_IO_UNIT_3, + SasIOUnitPage3_t, MPI_POINTER pSasIOUnitPage3_t; + +#define MPI_SASIOUNITPAGE3_PAGEVERSION (0x00) + + +typedef struct _CONFIG_PAGE_SAS_EXPANDER_0 +{ + fCONFIG_EXTENDED_PAGE_HEADER Header; /* 00h */ + U32 Reserved1; /* 08h */ + U64 SASAddress; /* 0Ch */ + U32 Reserved2; /* 14h */ + U16 DevHandle; /* 18h */ + U16 ParentDevHandle; /* 1Ah */ + U16 ExpanderChangeCount; /* 1Ch */ + U16 ExpanderRouteIndexes; /* 1Eh */ + U8 NumPhys; /* 20h */ + U8 SASLevel; /* 21h */ + U8 Flags; /* 22h */ + U8 Reserved3; /* 23h */ +} fCONFIG_PAGE_SAS_EXPANDER_0, MPI_POINTER PTR_CONFIG_PAGE_SAS_EXPANDER_0, + SasExpanderPage0_t, MPI_POINTER pSasExpanderPage0_t; + +#define MPI_SASEXPANDER0_PAGEVERSION (0x00) + +/* values for SAS Expander Page 0 Flags field */ +#define MPI_SAS_EXPANDER0_FLAGS_ROUTE_TABLE_CONFIG (0x02) +#define MPI_SAS_EXPANDER0_FLAGS_CONFIG_IN_PROGRESS (0x01) + + +typedef struct _CONFIG_PAGE_SAS_DEVICE_0 +{ + fCONFIG_EXTENDED_PAGE_HEADER Header; /* 00h */ + U32 Reserved1; /* 08h */ + U64 SASAddress; /* 0Ch */ + U32 Reserved2; /* 14h */ + U16 DevHandle; /* 18h */ + U8 TargetID; /* 1Ah */ + U8 Bus; /* 1Bh */ + U32 DeviceInfo; /* 1Ch */ + U16 Flags; /* 20h */ + U8 PhysicalPort; /* 22h */ + U8 Reserved3; /* 23h */ +} fCONFIG_PAGE_SAS_DEVICE_0, MPI_POINTER PTR_CONFIG_PAGE_SAS_DEVICE_0, + SasDevicePage0_t, MPI_POINTER pSasDevicePage0_t; + +#define MPI_SASDEVICE0_PAGEVERSION (0x00) + +/* values for SAS Device Page 0 Flags field */ +#define MPI_SAS_DEVICE0_FLAGS_MAPPING_PERSISTENT (0x04) +#define MPI_SAS_DEVICE0_FLAGS_DEVICE_MAPPED (0x02) +#define MPI_SAS_DEVICE0_FLAGS_DEVICE_PRESENT (0x01) + +/* see mpi_sas.h for values for SAS Device Page 0 DeviceInfo values */ + + +typedef struct _CONFIG_PAGE_SAS_DEVICE_1 +{ + fCONFIG_EXTENDED_PAGE_HEADER Header; /* 00h */ + U32 Reserved1; /* 08h */ + U64 SASAddress; /* 0Ch */ + U32 Reserved2; /* 14h */ + U16 DevHandle; /* 18h */ + U8 TargetID; /* 1Ah */ + U8 Bus; /* 1Bh */ + U8 InitialRegDeviceFIS[20];/* 1Ch */ +} fCONFIG_PAGE_SAS_DEVICE_1, MPI_POINTER PTR_CONFIG_PAGE_SAS_DEVICE_1, + SasDevicePage1_t, MPI_POINTER pSasDevicePage1_t; + +#define MPI_SASDEVICE1_PAGEVERSION (0x00) + + +typedef struct _CONFIG_PAGE_SAS_PHY_0 +{ + fCONFIG_EXTENDED_PAGE_HEADER Header; /* 00h */ + U32 Reserved1; /* 08h */ + U64 SASAddress; /* 0Ch */ + U16 AttachedDevHandle; /* 14h */ + U8 AttachedPhyIdentifier; /* 16h */ + U8 Reserved2; /* 17h */ + U32 AttachedDeviceInfo; /* 18h */ + U8 ProgrammedLinkRate; /* 20h */ + U8 HwLinkRate; /* 21h */ + U8 ChangeCount; /* 22h */ + U8 Reserved3; /* 23h */ + U32 PhyInfo; /* 24h */ +} fCONFIG_PAGE_SAS_PHY_0, MPI_POINTER PTR_CONFIG_PAGE_SAS_PHY_0, + SasPhyPage0_t, MPI_POINTER pSasPhyPage0_t; + +#define MPI_SASPHY0_PAGEVERSION (0x00) + +/* values for SAS PHY Page 0 ProgrammedLinkRate field */ +#define MPI_SAS_PHY0_PRATE_MAX_RATE_MASK (0xF0) +#define MPI_SAS_PHY0_PRATE_MAX_RATE_NOT_PROGRAMMABLE (0x00) +#define MPI_SAS_PHY0_PRATE_MAX_RATE_1_5 (0x80) +#define MPI_SAS_PHY0_PRATE_MAX_RATE_3_0 (0x90) +#define MPI_SAS_PHY0_PRATE_MIN_RATE_MASK (0x0F) +#define MPI_SAS_PHY0_PRATE_MIN_RATE_NOT_PROGRAMMABLE (0x00) +#define MPI_SAS_PHY0_PRATE_MIN_RATE_1_5 (0x08) +#define MPI_SAS_PHY0_PRATE_MIN_RATE_3_0 (0x09) + +/* values for SAS PHY Page 0 HwLinkRate field */ +#define MPI_SAS_PHY0_HWRATE_MAX_RATE_MASK (0xF0) +#define MPI_SAS_PHY0_HWRATE_MAX_RATE_1_5 (0x80) +#define MPI_SAS_PHY0_HWRATE_MAX_RATE_3_0 (0x90) +#define MPI_SAS_PHY0_HWRATE_MIN_RATE_MASK (0x0F) +#define MPI_SAS_PHY0_HWRATE_MIN_RATE_1_5 (0x08) +#define MPI_SAS_PHY0_HWRATE_MIN_RATE_3_0 (0x09) + +/* values for SAS PHY Page 0 PhyInfo field */ +#define MPI_SAS_PHY0_PHYINFO_SATA_PORT_ACTIVE (0x00004000) +#define MPI_SAS_PHY0_PHYINFO_SATA_PORT_SELECTOR (0x00002000) +#define MPI_SAS_PHY0_PHYINFO_VIRTUAL_PHY (0x00001000) + +#define MPI_SAS_PHY0_PHYINFO_MASK_PARTIAL_PATHWAY_TIME (0x00000F00) +#define MPI_SAS_PHY0_PHYINFO_SHIFT_PARTIAL_PATHWAY_TIME (8) + +#define MPI_SAS_PHY0_PHYINFO_MASK_ROUTING_ATTRIBUTE (0x000000F0) +#define MPI_SAS_PHY0_PHYINFO_DIRECT_ROUTING (0x00000000) +#define MPI_SAS_PHY0_PHYINFO_SUBTRACTIVE_ROUTING (0x00000010) +#define MPI_SAS_PHY0_PHYINFO_TABLE_ROUTING (0x00000020) + +#define MPI_SAS_PHY0_PHYINFO_MASK_LINK_RATE (0x0000000F) +#define MPI_SAS_PHY0_PHYINFO_UNKNOWN_LINK_RATE (0x00000000) +#define MPI_SAS_PHY0_PHYINFO_PHY_DISABLED (0x00000001) +#define MPI_SAS_PHY0_PHYINFO_NEGOTIATION_FAILED (0x00000002) +#define MPI_SAS_PHY0_PHYINFO_SATA_OOB_COMPLETE (0x00000003) +#define MPI_SAS_PHY0_PHYINFO_RATE_1_5 (0x00000008) +#define MPI_SAS_PHY0_PHYINFO_RATE_3_0 (0x00000009) + + +typedef struct _CONFIG_PAGE_SAS_PHY_1 +{ + fCONFIG_EXTENDED_PAGE_HEADER Header; /* 00h */ + U32 Reserved1; /* 08h */ + U32 InvalidDwordCount; /* 0Ch */ + U32 RunningDisparityErrorCount; /* 10h */ + U32 LossDwordSynchCount; /* 14h */ + U32 PhyResetProblemCount; /* 18h */ +} fCONFIG_PAGE_SAS_PHY_1, MPI_POINTER PTR_CONFIG_PAGE_SAS_PHY_1, + SasPhyPage1_t, MPI_POINTER pSasPhyPage1_t; + +#define MPI_SASPHY1_PAGEVERSION (0x00) + #endif diff -Nru a/drivers/message/fusion/lsi/mpi_fc.h b/drivers/message/fusion/lsi/mpi_fc.h --- a/drivers/message/fusion/lsi/mpi_fc.h Sun Mar 14 14:20:06 2004 +++ b/drivers/message/fusion/lsi/mpi_fc.h Sun Mar 14 14:20:06 2004 @@ -1,12 +1,12 @@ /* - * Copyright (c) 2000-2002 LSI Logic Corporation. + * Copyright (c) 2000-2003 LSI Logic Corporation. * * - * Name: MPI_FC.H + * Name: mpi_fc.h * Title: MPI Fibre Channel messages and structures * Creation Date: June 12, 2000 * - * MPI_FC.H Version: 01.02.03 + * mpi_fc.h Version: 01.05.xx * * Version History * --------------- @@ -45,7 +45,7 @@ /***************************************************************************** * -* F C T a r g e t M o d e M e s s a g e s +* F C D i r e c t A c c e s s M e s s a g e s * *****************************************************************************/ @@ -334,6 +334,7 @@ FcPrimitiveSendRequest_t, MPI_POINTER pFcPrimitiveSendRequest_t; #define MPI_FC_PRIM_SEND_FLAGS_PORT_MASK (0x01) +#define MPI_FC_PRIM_SEND_FLAGS_ML_RESET_LINK (0x02) #define MPI_FC_PRIM_SEND_FLAGS_RESET_LINK (0x04) #define MPI_FC_PRIM_SEND_FLAGS_STOP_SEND (0x08) #define MPI_FC_PRIM_SEND_FLAGS_SEND_ONCE (0x10) diff -Nru a/drivers/message/fusion/lsi/mpi_inb.h b/drivers/message/fusion/lsi/mpi_inb.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/drivers/message/fusion/lsi/mpi_inb.h Sun Mar 14 14:20:09 2004 @@ -0,0 +1,220 @@ +/* + * Copyright (c) 2003 LSI Logic Corporation. + * + * + * Name: mpi_inb.h + * Title: MPI Inband structures and definitions + * Creation Date: September 30, 2003 + * + * mpi_inb.h Version: 01.03.xx + * + * Version History + * --------------- + * + * Date Version Description + * -------- -------- ------------------------------------------------------ + * ??-??-?? 01.03.01 Original release. + * -------------------------------------------------------------------------- + */ + +#ifndef MPI_INB_H +#define MPI_INB_H + +/****************************************************************************** +* +* I n b a n d M e s s a g e s +* +*******************************************************************************/ + + +/****************************************************************************/ +/* Inband Buffer Post Request */ +/****************************************************************************/ + +typedef struct _MSG_INBAND_BUFFER_POST_REQUEST +{ + U8 Reserved1; /* 00h */ + U8 BufferCount; /* 01h */ + U8 ChainOffset; /* 02h */ + U8 Function; /* 03h */ + U16 Reserved2; /* 04h */ + U8 Reserved3; /* 06h */ + U8 MsgFlags; /* 07h */ + U32 MsgContext; /* 08h */ + U32 Reserved4; /* 0Ch */ + SGE_TRANS_SIMPLE_UNION SGL; /* 10h */ +} MSG_INBAND_BUFFER_POST_REQUEST, MPI_POINTER PTR_MSG_INBAND_BUFFER_POST_REQUEST, + MpiInbandBufferPostRequest_t , MPI_POINTER pMpiInbandBufferPostRequest_t; + + +typedef struct _WWN_FC_FORMAT +{ + U64 NodeName; /* 00h */ + U64 PortName; /* 08h */ +} WWN_FC_FORMAT, MPI_POINTER PTR_WWN_FC_FORMAT, + WwnFcFormat_t, MPI_POINTER pWwnFcFormat_t; + +typedef struct _WWN_SAS_FORMAT +{ + U64 WorldWideID; /* 00h */ + U32 Reserved1; /* 08h */ + U32 Reserved2; /* 0Ch */ +} WWN_SAS_FORMAT, MPI_POINTER PTR_WWN_SAS_FORMAT, + WwnSasFormat_t, MPI_POINTER pWwnSasFormat_t; + +typedef union _WWN_INBAND_FORMAT +{ + WWN_FC_FORMAT Fc; + WWN_SAS_FORMAT Sas; +} WWN_INBAND_FORMAT, MPI_POINTER PTR_WWN_INBAND_FORMAT, + WwnInbandFormat, MPI_POINTER pWwnInbandFormat; + + +/* Inband Buffer Post reply message */ + +typedef struct _MSG_INBAND_BUFFER_POST_REPLY +{ + U16 Reserved1; /* 00h */ + U8 MsgLength; /* 02h */ + U8 Function; /* 03h */ + U16 Reserved2; /* 04h */ + U8 Reserved3; /* 06h */ + U8 MsgFlags; /* 07h */ + U32 MsgContext; /* 08h */ + U16 Reserved4; /* 0Ch */ + U16 IOCStatus; /* 0Eh */ + U32 IOCLogInfo; /* 10h */ + U32 TransferLength; /* 14h */ + U32 TransactionContext; /* 18h */ + WWN_INBAND_FORMAT Wwn; /* 1Ch */ + U32 IOCIdentifier[4]; /* 2Ch */ +} MSG_INBAND_BUFFER_POST_REPLY, MPI_POINTER PTR_MSG_INBAND_BUFFER_POST_REPLY, + MpiInbandBufferPostReply_t, MPI_POINTER pMpiInbandBufferPostReply_t; + + +/****************************************************************************/ +/* Inband Send Request */ +/****************************************************************************/ + +typedef struct _MSG_INBAND_SEND_REQUEST +{ + U16 Reserved1; /* 00h */ + U8 ChainOffset; /* 02h */ + U8 Function; /* 03h */ + U16 Reserved2; /* 04h */ + U8 Reserved3; /* 06h */ + U8 MsgFlags; /* 07h */ + U32 MsgContext; /* 08h */ + U32 Reserved4; /* 0Ch */ + WWN_INBAND_FORMAT Wwn; /* 10h */ + U32 Reserved5; /* 20h */ + SGE_IO_UNION SGL; /* 24h */ +} MSG_INBAND_SEND_REQUEST, MPI_POINTER PTR_MSG_INBAND_SEND_REQUEST, + MpiInbandSendRequest_t , MPI_POINTER pMpiInbandSendRequest_t; + + +/* Inband Send reply message */ + +typedef struct _MSG_INBAND_SEND_REPLY +{ + U16 Reserved1; /* 00h */ + U8 MsgLength; /* 02h */ + U8 Function; /* 03h */ + U16 Reserved2; /* 04h */ + U8 Reserved3; /* 06h */ + U8 MsgFlags; /* 07h */ + U32 MsgContext; /* 08h */ + U16 Reserved4; /* 0Ch */ + U16 IOCStatus; /* 0Eh */ + U32 IOCLogInfo; /* 10h */ + U32 ResponseLength; /* 14h */ +} MSG_INBAND_SEND_REPLY, MPI_POINTER PTR_MSG_INBAND_SEND_REPLY, + MpiInbandSendReply_t, MPI_POINTER pMpiInbandSendReply_t; + + +/****************************************************************************/ +/* Inband Response Request */ +/****************************************************************************/ + +typedef struct _MSG_INBAND_RSP_REQUEST +{ + U16 Reserved1; /* 00h */ + U8 ChainOffset; /* 02h */ + U8 Function; /* 03h */ + U16 Reserved2; /* 04h */ + U8 Reserved3; /* 06h */ + U8 MsgFlags; /* 07h */ + U32 MsgContext; /* 08h */ + U32 Reserved4; /* 0Ch */ + WWN_INBAND_FORMAT Wwn; /* 10h */ + U32 IOCIdentifier[4]; /* 20h */ + U32 ResponseLength; /* 30h */ + SGE_IO_UNION SGL; /* 34h */ +} MSG_INBAND_RSP_REQUEST, MPI_POINTER PTR_MSG_INBAND_RSP_REQUEST, + MpiInbandRspRequest_t , MPI_POINTER pMpiInbandRspRequest_t; + + +/* Inband Response reply message */ + +typedef struct _MSG_INBAND_RSP_REPLY +{ + U16 Reserved1; /* 00h */ + U8 MsgLength; /* 02h */ + U8 Function; /* 03h */ + U16 Reserved2; /* 04h */ + U8 Reserved3; /* 06h */ + U8 MsgFlags; /* 07h */ + U32 MsgContext; /* 08h */ + U16 Reserved4; /* 0Ch */ + U16 IOCStatus; /* 0Eh */ + U32 IOCLogInfo; /* 10h */ +} MSG_INBAND_RSP_REPLY, MPI_POINTER PTR_MSG_INBAND_RSP_REPLY, + MpiInbandRspReply_t, MPI_POINTER pMpiInbandRspReply_t; + + +/****************************************************************************/ +/* Inband Abort Request */ +/****************************************************************************/ + +typedef struct _MSG_INBAND_ABORT_REQUEST +{ + U8 Reserved1; /* 00h */ + U8 AbortType; /* 01h */ + U8 ChainOffset; /* 02h */ + U8 Function; /* 03h */ + U16 Reserved2; /* 04h */ + U8 Reserved3; /* 06h */ + U8 MsgFlags; /* 07h */ + U32 MsgContext; /* 08h */ + U32 Reserved4; /* 0Ch */ + U32 ContextToAbort; /* 10h */ +} MSG_INBAND_ABORT_REQUEST, MPI_POINTER PTR_MSG_INBAND_ABORT_REQUEST, + MpiInbandAbortRequest_t , MPI_POINTER pMpiInbandAbortRequest_t; + +#define MPI_INBAND_ABORT_TYPE_ALL_BUFFERS (0x00) +#define MPI_INBAND_ABORT_TYPE_EXACT_BUFFER (0x01) +#define MPI_INBAND_ABORT_TYPE_SEND_REQUEST (0x02) +#define MPI_INBAND_ABORT_TYPE_RESPONSE_REQUEST (0x03) + + +/* Inband Abort reply message */ + +typedef struct _MSG_INBAND_ABORT_REPLY +{ + U8 Reserved1; /* 00h */ + U8 AbortType; /* 01h */ + U8 MsgLength; /* 02h */ + U8 Function; /* 03h */ + U16 Reserved2; /* 04h */ + U8 Reserved3; /* 06h */ + U8 MsgFlags; /* 07h */ + U32 MsgContext; /* 08h */ + U16 Reserved4; /* 0Ch */ + U16 IOCStatus; /* 0Eh */ + U32 IOCLogInfo; /* 10h */ +} MSG_INBAND_ABORT_REPLY, MPI_POINTER PTR_MSG_INBAND_ABORT_REPLY, + MpiInbandAbortReply_t, MPI_POINTER pMpiInbandAbortReply_t; + + +#endif + diff -Nru a/drivers/message/fusion/lsi/mpi_init.h b/drivers/message/fusion/lsi/mpi_init.h --- a/drivers/message/fusion/lsi/mpi_init.h Sun Mar 14 14:20:06 2004 +++ b/drivers/message/fusion/lsi/mpi_init.h Sun Mar 14 14:20:06 2004 @@ -1,12 +1,12 @@ /* - * Copyright (c) 2000-2002 LSI Logic Corporation. + * Copyright (c) 2000-2003 LSI Logic Corporation. * * - * Name: MPI_INIT.H + * Name: mpi_init.h * Title: MPI initiator mode messages and structures * Creation Date: June 8, 2000 * - * MPI_INIT.H Version: 01.02.05 + * mpi_init.h Version: 01.05.xx * * Version History * --------------- @@ -31,6 +31,8 @@ * 10-04-01 01.02.04 Added defines for SEP request Action field. * 05-31-02 01.02.05 Added MPI_SCSIIO_MSGFLGS_CMD_DETERMINES_DATA_DIR define * for SCSI IO requests. + * 11-15-02 01.02.06 Added special extended SCSI Status defines for FCP. + * 06-26-03 01.02.07 Added MPI_SCSI_STATUS_FCPEXT_UNASSIGNED define. * -------------------------------------------------------------------------- */ @@ -45,7 +47,7 @@ *****************************************************************************/ /****************************************************************************/ -/* SCSI IO messages and assocaited structures */ +/* SCSI IO messages and associated structures */ /****************************************************************************/ typedef struct _MSG_SCSI_IO_REQUEST @@ -78,6 +80,16 @@ #define MPI_SCSIIO_MSGFLGS_SENSE_LOC_HOST (0x00) #define MPI_SCSIIO_MSGFLGS_SENSE_LOC_IOC (0x02) #define MPI_SCSIIO_MSGFLGS_CMD_DETERMINES_DATA_DIR (0x04) +#define MPI_SCSIIO_MSGFLGS_EEDP_TYPE_MASK (0xE0) +#define MPI_SCSIIO_MSGFLGS_EEDP_NONE (0x00) +#define MPI_SCSIIO_MSGFLGS_EEDP_RDPROTECT_T10 (0x20) +#define MPI_SCSIIO_MSGFLGS_EEDP_VRPROTECT_T10 (0x40) +#define MPI_SCSIIO_MSGFLGS_EEDP_WRPROTECT_T10 (0x60) +#define MPI_SCSIIO_MSGFLGS_EEDP_520_READ_MODE1 (0x20) +#define MPI_SCSIIO_MSGFLGS_EEDP_520_WRITE_MODE1 (0x40) +#define MPI_SCSIIO_MSGFLGS_EEDP_8_9_READ_MODE1 (0x60) +#define MPI_SCSIIO_MSGFLGS_EEDP_8_9_WRITE_MODE1 (0x80) + /* SCSI IO LUN fields */ @@ -153,6 +165,10 @@ #define MPI_SCSI_STATUS_TASK_SET_FULL (0x28) #define MPI_SCSI_STATUS_ACA_ACTIVE (0x30) +#define MPI_SCSI_STATUS_FCPEXT_DEVICE_LOGGED_OUT (0x80) +#define MPI_SCSI_STATUS_FCPEXT_NO_LINK (0x81) +#define MPI_SCSI_STATUS_FCPEXT_UNASSIGNED (0x82) + /* SCSI IO Reply SCSIState values */ @@ -176,6 +192,33 @@ /****************************************************************************/ +/* SCSI IO 32 Request message structure */ +/****************************************************************************/ + +typedef struct _MSG_SCSI_IO32_REQUEST +{ + U8 TargetID; /* 00h */ + U8 Bus; /* 01h */ + U8 ChainOffset; /* 02h */ + U8 Function; /* 03h */ + U8 CDBLength; /* 04h */ + U8 SenseBufferLength; /* 05h */ + U8 Reserved; /* 06h */ + U8 MsgFlags; /* 07h */ + U32 MsgContext; /* 08h */ + U8 LUN[8]; /* 0Ch */ + U32 Control; /* 14h */ + U8 CDB[32]; /* 18h */ + U32 DataLength; /* 38h */ + U32 SenseBufferLowAddr; /* 3Ch */ + SGE_IO_UNION SGL; /* 40h */ +} MSG_SCSI_IO32_REQUEST, MPI_POINTER PTR_MSG_SCSI_IO32_REQUEST, + SCSIIO32Request_t, MPI_POINTER pSCSIIO32Request_t; + +/* SCSI IO 32 uses the same defines as above for SCSI IO */ + + +/****************************************************************************/ /* SCSI Task Management messages */ /****************************************************************************/ @@ -203,6 +246,7 @@ #define MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET (0x03) #define MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS (0x04) #define MPI_SCSITASKMGMT_TASKTYPE_LOGICAL_UNIT_RESET (0x05) +#define MPI_SCSITASKMGMT_TASKTYPE_CLEAR_TASK_SET (0x06) /* MsgFlags bits */ #define MPI_SCSITASKMGMT_MSGFLAGS_TARGET_RESET_OPTION (0x00) diff -Nru a/drivers/message/fusion/lsi/mpi_ioc.h b/drivers/message/fusion/lsi/mpi_ioc.h --- a/drivers/message/fusion/lsi/mpi_ioc.h Sun Mar 14 14:20:06 2004 +++ b/drivers/message/fusion/lsi/mpi_ioc.h Sun Mar 14 14:20:06 2004 @@ -1,12 +1,12 @@ /* - * Copyright (c) 2000-2002 LSI Logic Corporation. + * Copyright (c) 2000-2003 LSI Logic Corporation. * * - * Name: MPI_IOC.H + * Name: mpi_ioc.h * Title: MPI IOC, Port, Event, FW Download, and FW Upload messages * Creation Date: August 11, 2000 * - * MPI_IOC.H Version: 01.02.06 + * mpi_ioc.h Version: 01.05.xx * * Version History * --------------- @@ -55,6 +55,8 @@ * 05-31-02 01.02.06 Added define for * MPI_IOCFACTS_EXCEPT_RAID_CONFIG_INVALID. * Added AliasIndex to EVENT_DATA_LOGOUT structure. + * 04-01-03 01.02.07 Added defines for MPI_FW_HEADER_SIGNATURE_. + * 06-26-03 01.02.08 Added new values to the product family defines. * -------------------------------------------------------------------------- */ @@ -87,19 +89,21 @@ U8 Reserved1[2]; /* 0Eh */ U32 HostMfaHighAddr; /* 10h */ U32 SenseBufferHighAddr; /* 14h */ + U32 ReplyFifoHostSignalingAddr; /* 18h */ } MSG_IOC_INIT, MPI_POINTER PTR_MSG_IOC_INIT, IOCInit_t, MPI_POINTER pIOCInit_t; /* WhoInit values */ -#define MPI_WHOINIT_NO_ONE (0x00) -#define MPI_WHOINIT_SYSTEM_BIOS (0x01) -#define MPI_WHOINIT_ROM_BIOS (0x02) -#define MPI_WHOINIT_PCI_PEER (0x03) -#define MPI_WHOINIT_HOST_DRIVER (0x04) -#define MPI_WHOINIT_MANUFACTURER (0x05) +#define MPI_WHOINIT_NO_ONE (0x00) +#define MPI_WHOINIT_SYSTEM_BIOS (0x01) +#define MPI_WHOINIT_ROM_BIOS (0x02) +#define MPI_WHOINIT_PCI_PEER (0x03) +#define MPI_WHOINIT_HOST_DRIVER (0x04) +#define MPI_WHOINIT_MANUFACTURER (0x05) /* Flags values */ -#define MPI_IOCINIT_FLAGS_DISCARD_FW_IMAGE (0x01) +#define MPI_IOCINIT_FLAGS_DISCARD_FW_IMAGE (0x01) +#define MPI_IOCINIT_FLAGS_REPLY_FIFO_HOST_SIGNAL (0x02) typedef struct _MSG_IOC_INIT_REPLY { @@ -179,8 +183,10 @@ U8 MaxDevices; /* 2Eh */ U8 MaxBuses; /* 2Fh */ U32 FWImageSize; /* 30h */ - U32 Reserved4; /* 34h */ + U32 IOCCapabilities; /* 34h */ MPI_FW_VERSION FWVersion; /* 38h */ + U16 HighPriorityQueueDepth; /* 3Ch */ + U16 Reserved2; /* 3Eh */ } MSG_IOC_FACTS_REPLY, MPI_POINTER PTR_MSG_IOC_FACTS_REPLY, IOCFactsReply_t, MPI_POINTER pIOCFactsReply_t; @@ -192,12 +198,22 @@ #define MPI_IOCFACTS_EXCEPT_CONFIG_CHECKSUM_FAIL (0x0001) #define MPI_IOCFACTS_EXCEPT_RAID_CONFIG_INVALID (0x0002) +#define MPI_IOCFACTS_EXCEPT_FW_CHECKSUM_FAIL (0x0004) +#define MPI_IOCFACTS_EXCEPT_PERSISTENT_TABLE_FULL (0x0008) #define MPI_IOCFACTS_FLAGS_FW_DOWNLOAD_BOOT (0x01) #define MPI_IOCFACTS_EVENTSTATE_DISABLED (0x00) #define MPI_IOCFACTS_EVENTSTATE_ENABLED (0x01) +#define MPI_IOCFACTS_CAPABILITY_HIGH_PRI_Q (0x00000001) +#define MPI_IOCFACTS_CAPABILITY_REPLY_HOST_SIGNAL (0x00000002) +#define MPI_IOCFACTS_CAPABILITY_QUEUE_FULL_HANDLING (0x00000004) +#define MPI_IOCFACTS_CAPABILITY_DIAG_TRACE_BUFFER (0x00000008) +#define MPI_IOCFACTS_CAPABILITY_SNAPSHOT_BUFFER (0x00000010) +#define MPI_IOCFACTS_CAPABILITY_EXTENDED_BUFFER (0x00000020) +#define MPI_IOCFACTS_CAPABILITY_EEDP (0x00000040) + /***************************************************************************** @@ -253,6 +269,8 @@ #define MPI_PORTFACTS_PORTTYPE_INACTIVE (0x00) #define MPI_PORTFACTS_PORTTYPE_SCSI (0x01) #define MPI_PORTFACTS_PORTTYPE_FC (0x10) +#define MPI_PORTFACTS_PORTTYPE_ISCSI (0x20) +#define MPI_PORTFACTS_PORTTYPE_SAS (0x30) /* ProtocolFlags values */ @@ -386,6 +404,10 @@ #define MPI_EVENT_INTEGRATED_RAID (0x0000000B) #define MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE (0x0000000C) #define MPI_EVENT_ON_BUS_TIMER_EXPIRED (0x0000000D) +#define MPI_EVENT_QUEUE_FULL (0x0000000E) +#define MPI_EVENT_SAS_DEVICE_STATUS_CHANGE (0x0000000F) +#define MPI_EVENT_SAS_SES (0x00000010) +#define MPI_EVENT_PERSISTENT_TABLE_FULL (0x00000011) /* AckRequired field values */ @@ -433,6 +455,39 @@ #define MPI_EVENT_SCSI_DEV_STAT_RC_NOT_RESPONDING (0x04) #define MPI_EVENT_SCSI_DEV_STAT_RC_SMART_DATA (0x05) +/* SAS Device Status Change Event data */ + +typedef struct _EVENT_DATA_SAS_DEVICE_STATUS_CHANGE +{ + U8 TargetID; /* 00h */ + U8 Bus; /* 01h */ + U8 ReasonCode; /* 02h */ + U8 Reserved; /* 03h */ + U8 ASC; /* 04h */ + U8 ASCQ; /* 05h */ + U16 DevHandle; /* 06h */ + U32 DeviceInfo; /* 08h */ +} EVENT_DATA_SAS_DEVICE_STATUS_CHANGE, + MPI_POINTER PTR_EVENT_DATA_SAS_DEVICE_STATUS_CHANGE, + MpiEventDataSasDeviceStatusChange_t, + MPI_POINTER pMpiEventDataSasDeviceStatusChange_t; + +/* MPI SAS Device Status Change Event data ReasonCode values */ +#define MPI_EVENT_SAS_DEV_STAT_RC_ADDED (0x03) +#define MPI_EVENT_SAS_DEV_STAT_RC_NOT_RESPONDING (0x04) +#define MPI_EVENT_SAS_DEV_STAT_RC_SMART_DATA (0x05) +#define MPI_EVENT_SAS_DEV_STAT_RC_NO_PERSIST_ADDED (0x06) + +/* SCSI Event data for Queue Full event */ + +typedef struct _EVENT_DATA_QUEUE_FULL +{ + U8 TargetID; /* 00h */ + U8 Bus; /* 01h */ + U16 CurrentDepth; /* 02h */ +} EVENT_DATA_QUEUE_FULL, MPI_POINTER PTR_EVENT_DATA_QUEUE_FULL, + EventDataQueueFull_t, MPI_POINTER pEventDataQueueFull_t; + /* MPI Link Status Change Event data */ typedef struct _EVENT_DATA_LINK_STATUS @@ -538,6 +593,7 @@ #define MPI_FW_DOWNLOAD_ITYPE_FW (0x01) #define MPI_FW_DOWNLOAD_ITYPE_BIOS (0x02) #define MPI_FW_DOWNLOAD_ITYPE_NVDATA (0x03) +#define MPI_FW_DOWNLOAD_ITYPE_BOOTLOADER (0x04) typedef struct _FWDownloadTCSGE @@ -590,6 +646,7 @@ #define MPI_FW_UPLOAD_ITYPE_FW_FLASH (0x01) #define MPI_FW_UPLOAD_ITYPE_BIOS_FLASH (0x02) #define MPI_FW_UPLOAD_ITYPE_NVDATA (0x03) +#define MPI_FW_UPLOAD_ITYPE_BOOTLOADER (0x04) typedef struct _FWUploadTCSGE { @@ -653,6 +710,11 @@ #define MPI_FW_HEADER_PID_TYPE_MASK (0xF000) #define MPI_FW_HEADER_PID_TYPE_SCSI (0x0000) #define MPI_FW_HEADER_PID_TYPE_FC (0x1000) +#define MPI_FW_HEADER_PID_TYPE_SAS (0x2000) + +#define MPI_FW_HEADER_SIGNATURE_0 (0x5AEAA55A) +#define MPI_FW_HEADER_SIGNATURE_1 (0xA55AEAA5) +#define MPI_FW_HEADER_SIGNATURE_2 (0x5AA55AEA) #define MPI_FW_HEADER_PID_PROD_MASK (0x0F00) #define MPI_FW_HEADER_PID_PROD_INITIATOR_SCSI (0x0100) @@ -663,6 +725,7 @@ #define MPI_FW_HEADER_PID_PROD_CTX_SCSI (0x0600) #define MPI_FW_HEADER_PID_FAMILY_MASK (0x00FF) +/* SCSI */ #define MPI_FW_HEADER_PID_FAMILY_1030A0_SCSI (0x0001) #define MPI_FW_HEADER_PID_FAMILY_1030B0_SCSI (0x0002) #define MPI_FW_HEADER_PID_FAMILY_1030B1_SCSI (0x0003) @@ -673,9 +736,17 @@ #define MPI_FW_HEADER_PID_FAMILY_1020C0_SCSI (0x0008) #define MPI_FW_HEADER_PID_FAMILY_1035A0_SCSI (0x0009) #define MPI_FW_HEADER_PID_FAMILY_1035B0_SCSI (0x000A) +#define MPI_FW_HEADER_PID_FAMILY_1030TA0_SCSI (0x000B) +#define MPI_FW_HEADER_PID_FAMILY_1020TA0_SCSI (0x000C) +/* Fibre Channel */ #define MPI_FW_HEADER_PID_FAMILY_909_FC (0x0000) #define MPI_FW_HEADER_PID_FAMILY_919_FC (0x0001) #define MPI_FW_HEADER_PID_FAMILY_919X_FC (0x0002) +#define MPI_FW_HEADER_PID_FAMILY_919XL_FC (0x0003) +#define MPI_FW_HEADER_PID_FAMILY_949_FC (0x0004) +#define MPI_FW_HEADER_PID_FAMILY_959_FC (0x0005) +/* SAS */ +#define MPI_FW_HEADER_PID_FAMILY_1064_SAS (0x0001) typedef struct _MPI_EXT_IMAGE_HEADER { @@ -694,5 +765,6 @@ #define MPI_EXT_IMAGE_TYPE_UNSPECIFIED (0x00) #define MPI_EXT_IMAGE_TYPE_FW (0x01) #define MPI_EXT_IMAGE_TYPE_NVDATA (0x03) +#define MPI_EXT_IMAGE_TYPE_BOOTLOADER (0x04) #endif diff -Nru a/drivers/message/fusion/lsi/mpi_lan.h b/drivers/message/fusion/lsi/mpi_lan.h --- a/drivers/message/fusion/lsi/mpi_lan.h Sun Mar 14 14:20:07 2004 +++ b/drivers/message/fusion/lsi/mpi_lan.h Sun Mar 14 14:20:07 2004 @@ -1,12 +1,12 @@ /* - * Copyright (c) 2000-2002 LSI Logic Corporation. + * Copyright (c) 2000-2003 LSI Logic Corporation. * * - * Name: MPI_LAN.H + * Name: mpi_lan.h * Title: MPI LAN messages and structures * Creation Date: June 30, 2000 * - * MPI_LAN.H Version: 01.02.01 + * mpi_lan.h Version: 01.05.xx * * Version History * --------------- diff -Nru a/drivers/message/fusion/lsi/mpi_raid.h b/drivers/message/fusion/lsi/mpi_raid.h --- a/drivers/message/fusion/lsi/mpi_raid.h Sun Mar 14 14:20:07 2004 +++ b/drivers/message/fusion/lsi/mpi_raid.h Sun Mar 14 14:20:07 2004 @@ -1,12 +1,12 @@ /* - * Copyright (c) 2001-2002 LSI Logic Corporation. + * Copyright (c) 2001-2003 LSI Logic Corporation. * * - * Name: MPI_RAID.H + * Name: mpi_raid.h * Title: MPI RAID message and structures * Creation Date: February 27, 2001 * - * MPI_RAID.H Version: 01.02.07 + * mpi_raid.h Version: 01.05.xx * * Version History * --------------- @@ -25,6 +25,9 @@ * MPI_RAID_ACTION_INACTIVATE_VOLUME, and * MPI_RAID_ACTION_ADATA_INACTIVATE_ALL. * 07-12-02 01.02.07 Added structures for Mailbox request and reply. + * 11-15-02 01.02.08 Added missing MsgContext field to MSG_MAILBOX_REQUEST. + * 04-01-03 01.02.09 New action data option flag for + * MPI_RAID_ACTION_DELETE_VOLUME. * -------------------------------------------------------------------------- */ @@ -40,7 +43,7 @@ /****************************************************************************/ -/* RAID Volume Request */ +/* RAID Action Request */ /****************************************************************************/ typedef struct _MSG_RAID_ACTION @@ -90,6 +93,9 @@ #define MPI_RAID_ACTION_ADATA_KEEP_PHYS_DISKS (0x00000000) #define MPI_RAID_ACTION_ADATA_DEL_PHYS_DISKS (0x00000001) +#define MPI_RAID_ACTION_ADATA_KEEP_LBA0 (0x00000000) +#define MPI_RAID_ACTION_ADATA_ZERO_LBA0 (0x00000002) + /* ActionDataWord defines for use with MPI_RAID_ACTION_ACTIVATE_VOLUME action */ #define MPI_RAID_ACTION_ADATA_INACTIVATE_ALL (0x00000001) @@ -184,7 +190,7 @@ /****************************************************************************/ -/* Mailbox request structure */ +/* Mailbox reqeust structure */ /****************************************************************************/ typedef struct _MSG_MAILBOX_REQUEST @@ -195,6 +201,7 @@ U16 Reserved2; U8 Reserved3; U8 MsgFlags; + U32 MsgContext; U8 Command[10]; U16 Reserved4; SGE_IO_UNION SGL; diff -Nru a/drivers/message/fusion/lsi/mpi_sas.h b/drivers/message/fusion/lsi/mpi_sas.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/drivers/message/fusion/lsi/mpi_sas.h Sun Mar 14 14:20:09 2004 @@ -0,0 +1,181 @@ +/* + * Copyright (c) 2003 LSI Logic Corporation. + * + * + * Name: mpi_sas.h + * Title: MPI Serial Attached SCSI structures and definitions + * Creation Date: April 23, 2003 + * + * mpi_sas.h Version: 01.05.xx + * + * Version History + * --------------- + * + * Date Version Description + * -------- -------- ------------------------------------------------------ + * xx-yy-zz 01.05.01 Original release. + * -------------------------------------------------------------------------- + */ + +#ifndef MPI_SAS_H +#define MPI_SAS_H + +/***************************************************************************** +* +* S e r i a l A t t a c h e d S C S I M e s s a g e s +* +*****************************************************************************/ + +/****************************************************************************/ +/* Serial Management Protocol Passthrough Request */ +/****************************************************************************/ + +typedef struct _MSG_SMP_PASSTHROUGH_REQUEST +{ + U8 PassthroughFlags; /* 00h */ + U8 PhysicalPort; /* 01h */ + U8 ChainOffset; /* 02h */ + U8 Function; /* 03h */ + U16 RequestDataLength; /* 04h */ + U8 ConnectionRate; /* 06h */ + U8 MsgFlags; /* 07h */ + U32 MsgContext; /* 08h */ + U32 Reserved1; /* 0Ch */ + U64 SASAddress; /* 10h */ + U32 Reserved2; /* 18h */ + U32 Reserved3; /* 1Ch */ + SGE_SIMPLE_UNION SGL; /* 20h */ +} MSG_SMP_PASSTHROUGH_REQUEST, MPI_POINTER PTR_MSG_SMP_PASSTHROUGH_REQUEST, + SmpPassthroughRequest_t, MPI_POINTER pSmpPassthroughRequest_t; + +#define MPI_SMP_PT_REQ_PT_FLAGS_IMMEDIATE (0x80) + +#define MPI_SMP_PT_REQ_CONNECT_RATE_NEGOTIATED (0x00) +#define MPI_SMP_PT_REQ_CONNECT_RATE_1_5 (0x08) +#define MPI_SMP_PT_REQ_CONNECT_RATE_3_0 (0x09) + + +/* Serial Management Protocol Passthrough Reply */ +typedef struct _MSG_SMP_PASSTHROUGH_REPLY +{ + U8 PassthroughFlags; /* 00h */ + U8 PhysicalPort; /* 01h */ + U8 MsgLength; /* 02h */ + U8 Function; /* 03h */ + U16 ResponseDataLength; /* 04h */ + U8 Reserved1; /* 06h */ + U8 MsgFlags; /* 07h */ + U32 MsgContext; /* 08h */ + U8 Reserved2; /* 0Ch */ + U8 SASStatus; /* 0Dh */ + U16 IOCStatus; /* 0Eh */ + U32 IOCLogInfo; /* 10h */ + U32 Reserved3; /* 14h */ + U8 ResponseData[4]; /* 18h */ +} MSG_SMP_PASSTHROUGH_REPLY, MPI_POINTER PTR_MSG_SMP_PASSTHROUGH_REPLY, + SmpPassthroughReply_t, MPI_POINTER pSmpPassthroughReply_t; + +#define MPI_SMP_PT_REPLY_PT_FLAGS_IMMEDIATE (0x80) + +/* values for the SASStatus field */ +#define MPI_SASSTATUS_SUCCESS (0x00) +#define MPI_SASSTATUS_UNKNOWN_ERROR (0x01) +#define MPI_SASSTATUS_INVALID_FRAME (0x02) +#define MPI_SASSTATUS_UTC_BAD_DEST (0x03) +#define MPI_SASSTATUS_UTC_BREAK_RECEIVED (0x04) +#define MPI_SASSTATUS_UTC_CONNECT_RATE_NOT_SUPPORTED (0x05) +#define MPI_SASSTATUS_UTC_PORT_LAYER_REQUEST (0x06) +#define MPI_SASSTATUS_UTC_PROTOCOL_NOT_SUPPORTED (0x07) +#define MPI_SASSTATUS_UTC_STP_RESOURCES_BUSY (0x08) +#define MPI_SASSTATUS_UTC_WRONG_DESTINATION (0x09) +#define MPI_SASSTATUS_SHORT_INFORMATION_UNIT (0x0A) +#define MPI_SASSTATUS_LONG_INFORMATION_UNIT (0x0B) +#define MPI_SASSTATUS_XFER_RDY_INCORRECT_WRITE_DATA (0x0C) +#define MPI_SASSTATUS_XFER_RDY_REQUEST_OFFSET_ERROR (0x0D) +#define MPI_SASSTATUS_XFER_RDY_NOT_EXPECTED (0x0E) +#define MPI_SASSTATUS_DATA_INCORRECT_DATA_LENGTH (0x0F) +#define MPI_SASSTATUS_DATA_TOO_MUCH_READ_DATA (0x10) +#define MPI_SASSTATUS_DATA_OFFSET_ERROR (0x11) +#define MPI_SASSTATUS_SDSF_NAK_RECEIVED (0x12) +#define MPI_SASSTATUS_SDSF_CONNECTION_FAILED (0x13) +#define MPI_SASSTATUS_INITIATOR_RESPONSE_TIMEOUT (0x14) + + +/* + * Values for the SAS DeviceInfo field used in SAS Device Status Change Event + * data and SAS IO Unit Configuration pages. + */ +#define MPI_SAS_DEVICE_INFO_ATAPI_DEVICE (0x00002000) +#define MPI_SAS_DEVICE_INFO_LSI_DEVICE (0x00001000) +#define MPI_SAS_DEVICE_INFO_DIRECT_ATTACH (0x00000800) +#define MPI_SAS_DEVICE_INFO_SSP_TARGET (0x00000400) +#define MPI_SAS_DEVICE_INFO_STP_TARGET (0x00000200) +#define MPI_SAS_DEVICE_INFO_SMP_TARGET (0x00000100) +#define MPI_SAS_DEVICE_INFO_SATA_DEVICE (0x00000080) +#define MPI_SAS_DEVICE_INFO_SSP_INITIATOR (0x00000040) +#define MPI_SAS_DEVICE_INFO_STP_INITIATOR (0x00000020) +#define MPI_SAS_DEVICE_INFO_SMP_INITIATOR (0x00000010) +#define MPI_SAS_DEVICE_INFO_SATA_HOST (0x00000008) + +#define MPI_SAS_DEVICE_INFO_MASK_DEVICE_TYPE (0x00000007) +#define MPI_SAS_DEVICE_INFO_NO_DEVICE (0x00000000) +#define MPI_SAS_DEVICE_INFO_END_DEVICE (0x00000001) +#define MPI_SAS_DEVICE_INFO_EDGE_EXPANDER (0x00000002) +#define MPI_SAS_DEVICE_INFO_FANOUT_EXPANDER (0x00000003) + + +/****************************************************************************/ +/* SAS IO Unit Control Request */ +/****************************************************************************/ + +typedef struct _MSG_SAS_IOUNIT_CONTROL_REQUEST +{ + U8 Operation; /* 00h */ + U8 Reserved1; /* 01h */ + U8 ChainOffset; /* 02h */ + U8 Function; /* 03h */ + U16 Reserved2; /* 04h */ + U8 Reserved3; /* 06h */ + U8 MsgFlags; /* 07h */ + U32 MsgContext; /* 08h */ + U8 TargetID; /* 0Ch */ + U8 Bus; /* 0Dh */ + U8 PhyNum; /* 0Eh */ + U8 Reserved4; /* 0Fh */ + U32 Reserved5; /* 10h */ + U64 SASAddress; /* 14h */ + U32 Reserved6; /* 1Ch */ +} MSG_SAS_IOUNIT_CONTROL_REQUEST, MPI_POINTER PTR_MSG_SAS_IOUNIT_CONTROL_REQUEST, + SasIoUnitControlRequest_t, MPI_POINTER pSasIoUnitControlRequest_t; + +/* values for the ... field */ +#define MPI_SAS_OP_CLEAR_NOT_PRESENT (0x01) +#define MPI_SAS_OP_CLEAR_ALL (0x02) +#define MPI_SAS_OP_MAP (0x03) +#define MPI_SAS_OP_MOVE (0x04) +#define MPI_SAS_OP_CLEAR (0x05) +#define MPI_SAS_OP_PHY_LINK_RESET (0x06) +#define MPI_SAS_OP_PHY_HARD_RESET (0x07) +#define MPI_SAS_OP_PHY_CLEAR_ERROR_LOG (0x08) + + +/* SAS IO Unit Control Reply */ +typedef struct _MSG_SAS_IOUNIT_CONTROL_REPLY +{ + U8 Operation; /* 00h */ + U8 Reserved1; /* 01h */ + U8 MsgLength; /* 02h */ + U8 Function; /* 03h */ + U16 Reserved2; /* 04h */ + U8 Reserved3; /* 06h */ + U8 MsgFlags; /* 07h */ + U32 MsgContext; /* 08h */ + U16 Reserved4; /* 0Ch */ + U16 IOCStatus; /* 0Eh */ + U32 IOCLogInfo; /* 10h */ +} MSG_SAS_IOUNIT_CONTROL_REPLY, MPI_POINTER PTR_MSG_SAS_IOUNIT_CONTROL_REPLY, + SasIoUnitControlReply_t, MPI_POINTER pSasIoUnitControlReply_t; + +#endif + + diff -Nru a/drivers/message/fusion/lsi/mpi_targ.h b/drivers/message/fusion/lsi/mpi_targ.h --- a/drivers/message/fusion/lsi/mpi_targ.h Sun Mar 14 14:20:06 2004 +++ b/drivers/message/fusion/lsi/mpi_targ.h Sun Mar 14 14:20:06 2004 @@ -1,12 +1,12 @@ /* - * Copyright (c) 2000-2002 LSI Logic Corporation. + * Copyright (c) 2000-2003 LSI Logic Corporation. * * - * Name: MPI_TARG.H + * Name: mpi_targ.h * Title: MPI Target mode messages and structures * Creation Date: June 22, 2000 * - * MPI_TARG.H Version: 01.02.07 + * mpi_targ.h Version: 01.05.xx * * Version History * --------------- @@ -41,6 +41,8 @@ * Added AliasIndex field to MPI_TARGET_FCP_CMD_BUFFER. * 09-16-02 01.02.07 Added flags for confirmed completion. * Added PRIORITY_REASON_TARGET_BUSY. + * 11-15-02 01.02.08 Added AliasID field to MPI_TARGET_SCSI_SPI_CMD_BUFFER. + * 04-01-03 01.02.09 Added OptionalOxid field to MPI_TARGET_FCP_CMD_BUFFER. * -------------------------------------------------------------------------- */ @@ -171,7 +173,7 @@ U32 FcpDl; /* 1Ch */ U8 AliasIndex; /* 20h */ U8 Reserved1; /* 21h */ - U16 Reserved2; /* 22h */ + U16 OptionalOxid; /* 22h */ } MPI_TARGET_FCP_CMD_BUFFER, MPI_POINTER PTR_MPI_TARGET_FCP_CMD_BUFFER, MpiTargetFcpCmdBuffer, MPI_POINTER pMpiTargetFcpCmdBuffer; @@ -190,6 +192,10 @@ U8 TaskManagementFlags; /* 12h */ U8 AdditionalCDBLength; /* 13h */ U8 CDB[16]; /* 14h */ + /* Alias ID */ + U8 AliasID; /* 24h */ + U8 Reserved1; /* 25h */ + U16 Reserved2; /* 26h */ } MPI_TARGET_SCSI_SPI_CMD_BUFFER, MPI_POINTER PTR_MPI_TARGET_SCSI_SPI_CMD_BUFFER, MpiTargetScsiSpiCmdBuffer, MPI_POINTER pMpiTargetScsiSpiCmdBuffer; diff -Nru a/drivers/message/fusion/lsi/mpi_tool.h b/drivers/message/fusion/lsi/mpi_tool.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/drivers/message/fusion/lsi/mpi_tool.h Sun Mar 14 14:20:09 2004 @@ -0,0 +1,305 @@ +/* + * Copyright (c) 2001-2003 LSI Logic Corporation. + * + * + * Name: mpi_tool.h + * Title: MPI Toolbox structures and definitions + * Creation Date: July 30, 2001 + * + * mpi_tool.h Version: 01.05.xx + * + * Version History + * --------------- + * + * Date Version Description + * -------- -------- ------------------------------------------------------ + * 08-08-01 01.02.01 Original release. + * 08-29-01 01.02.02 Added DIAG_DATA_UPLOAD_HEADER and related defines. + * -------------------------------------------------------------------------- + */ + +#ifndef MPI_TOOL_H +#define MPI_TOOL_H + +#define MPI_TOOLBOX_CLEAN_TOOL (0x00) +#define MPI_TOOLBOX_MEMORY_MOVE_TOOL (0x01) +#define MPI_TOOLBOX_DIAG_DATA_UPLOAD_TOOL (0x02) +#define MPI_TOOLBOX_ISTWI_READ_WRITE_TOOL (0x03) +#define MPI_TOOLBOX_FC_MANAGEMENT_TOOL (0x04) + + +/****************************************************************************/ +/* Toolbox reply */ +/****************************************************************************/ + +typedef struct _MSG_TOOLBOX_REPLY +{ + U8 Tool; /* 00h */ + U8 Reserved; /* 01h */ + U8 MsgLength; /* 02h */ + U8 Function; /* 03h */ + U16 Reserved1; /* 04h */ + U8 Reserved2; /* 06h */ + U8 MsgFlags; /* 07h */ + U32 MsgContext; /* 08h */ + U16 Reserved3; /* 0Ch */ + U16 IOCStatus; /* 0Eh */ + U32 IOCLogInfo; /* 10h */ +} MSG_TOOLBOX_REPLY, MPI_POINTER PTR_MSG_TOOLBOX_REPLY, + ToolboxReply_t, MPI_POINTER pToolboxReply_t; + + +/****************************************************************************/ +/* Toolbox Clean Tool request */ +/****************************************************************************/ + +typedef struct _MSG_TOOLBOX_CLEAN_REQUEST +{ + U8 Tool; /* 00h */ + U8 Reserved; /* 01h */ + U8 ChainOffset; /* 02h */ + U8 Function; /* 03h */ + U16 Reserved1; /* 04h */ + U8 Reserved2; /* 06h */ + U8 MsgFlags; /* 07h */ + U32 MsgContext; /* 08h */ + U32 Flags; /* 0Ch */ +} MSG_TOOLBOX_CLEAN_REQUEST, MPI_POINTER PTR_MSG_TOOLBOX_CLEAN_REQUEST, + ToolboxCleanRequest_t, MPI_POINTER pToolboxCleanRequest_t; + +#define MPI_TOOLBOX_CLEAN_NVSRAM (0x00000001) +#define MPI_TOOLBOX_CLEAN_SEEPROM (0x00000002) +#define MPI_TOOLBOX_CLEAN_FLASH (0x00000004) +#define MPI_TOOLBOX_CLEAN_BOOTLOADER (0x04000000) +#define MPI_TOOLBOX_CLEAN_FW_BACKUP (0x08000000) +#define MPI_TOOLBOX_CLEAN_FW_CURRENT (0x10000000) +#define MPI_TOOLBOX_CLEAN_OTHER_PERSIST_PAGES (0x20000000) +#define MPI_TOOLBOX_CLEAN_PERSIST_MANUFACT_PAGES (0x40000000) +#define MPI_TOOLBOX_CLEAN_BOOT_SERVICES (0x80000000) + + +/****************************************************************************/ +/* Toolbox Memory Move request */ +/****************************************************************************/ + +typedef struct _MSG_TOOLBOX_MEM_MOVE_REQUEST +{ + U8 Tool; /* 00h */ + U8 Reserved; /* 01h */ + U8 ChainOffset; /* 02h */ + U8 Function; /* 03h */ + U16 Reserved1; /* 04h */ + U8 Reserved2; /* 06h */ + U8 MsgFlags; /* 07h */ + U32 MsgContext; /* 08h */ + SGE_SIMPLE_UNION SGL; /* 0Ch */ +} MSG_TOOLBOX_MEM_MOVE_REQUEST, MPI_POINTER PTR_MSG_TOOLBOX_MEM_MOVE_REQUEST, + ToolboxMemMoveRequest_t, MPI_POINTER pToolboxMemMoveRequest_t; + + +/****************************************************************************/ +/* Toolbox Diagnostic Data Upload request */ +/****************************************************************************/ + +typedef struct _MSG_TOOLBOX_DIAG_DATA_UPLOAD_REQUEST +{ + U8 Tool; /* 00h */ + U8 Reserved; /* 01h */ + U8 ChainOffset; /* 02h */ + U8 Function; /* 03h */ + U16 Reserved1; /* 04h */ + U8 Reserved2; /* 06h */ + U8 MsgFlags; /* 07h */ + U32 MsgContext; /* 08h */ + U32 Flags; /* 0Ch */ + U32 Reserved3; /* 10h */ + SGE_SIMPLE_UNION SGL; /* 14h */ +} MSG_TOOLBOX_DIAG_DATA_UPLOAD_REQUEST, MPI_POINTER PTR_MSG_TOOLBOX_DIAG_DATA_UPLOAD_REQUEST, + ToolboxDiagDataUploadRequest_t, MPI_POINTER pToolboxDiagDataUploadRequest_t; + +typedef struct _DIAG_DATA_UPLOAD_HEADER +{ + U32 DiagDataLength; /* 00h */ + U8 FormatCode; /* 04h */ + U8 Reserved; /* 05h */ + U16 Reserved1; /* 06h */ +} DIAG_DATA_UPLOAD_HEADER, MPI_POINTER PTR_DIAG_DATA_UPLOAD_HEADER, + DiagDataUploadHeader_t, MPI_POINTER pDiagDataUploadHeader_t; + +#define MPI_TB_DIAG_FORMAT_SCSI_PRINTF_1 (0x01) +#define MPI_TB_DIAG_FORMAT_SCSI_2 (0x02) +#define MPI_TB_DIAG_FORMAT_SCSI_3 (0x03) +#define MPI_TB_DIAG_FORMAT_FC_TRACE_1 (0x04) + + +/****************************************************************************/ +/* Toolbox ISTWI Read Write request */ +/****************************************************************************/ + +typedef struct _MSG_TOOLBOX_ISTWI_READ_WRITE_REQUEST +{ + U8 Tool; /* 00h */ + U8 Reserved; /* 01h */ + U8 ChainOffset; /* 02h */ + U8 Function; /* 03h */ + U16 Reserved1; /* 04h */ + U8 Reserved2; /* 06h */ + U8 MsgFlags; /* 07h */ + U32 MsgContext; /* 08h */ + U8 Flags; /* 0Ch */ + U8 BusNum; /* 0Dh */ + U16 Reserved3; /* 0Eh */ + U8 NumAddressBytes; /* 10h */ + U8 Reserved4; /* 11h */ + U16 DataLength; /* 12h */ + U8 DeviceAddr; /* 14h */ + U8 Addr1; /* 15h */ + U8 Addr2; /* 16h */ + U8 Addr3; /* 17h */ + U32 Reserved5; /* 18h */ + SGE_SIMPLE_UNION SGL; /* 1Ch */ +} MSG_TOOLBOX_ISTWI_READ_WRITE_REQUEST, MPI_POINTER PTR_MSG_TOOLBOX_ISTWI_READ_WRITE_REQUEST, + ToolboxIstwiReadWriteRequest_t, MPI_POINTER pToolboxIstwiReadWriteRequest_t; + +#define MPI_TB_ISTWI_FLAGS_WRITE (0x00) +#define MPI_TB_ISTWI_FLAGS_READ (0x01) + + +/****************************************************************************/ +/* Toolbox FC Management request */ +/****************************************************************************/ + +/* ActionInfo for Bus and TargetId */ +typedef struct _MPI_TB_FC_MANAGE_BUS_TID_AI +{ + U16 Reserved; /* 00h */ + U8 Bus; /* 02h */ + U8 TargetId; /* 03h */ +} MPI_TB_FC_MANAGE_BUS_TID_AI, MPI_POINTER PTR_MPI_TB_FC_MANAGE_BUS_TID_AI, + MpiTbFcManageBusTidAi_t, MPI_POINTER pMpiTbFcManageBusTidAi_t; + +/* ActionInfo for port identifier */ +typedef struct _MPI_TB_FC_MANAGE_PID_AI +{ + U32 PortIdentifier; /* 00h */ +} MPI_TB_FC_MANAGE_PID_AI, MPI_POINTER PTR_MPI_TB_FC_MANAGE_PID_AI, + MpiTbFcManagePidAi_t, MPI_POINTER pMpiTbFcManagePidAi_t; + +/* union of ActionInfo */ +typedef union _MPI_TB_FC_MANAGE_AI_UNION +{ + MPI_TB_FC_MANAGE_BUS_TID_AI BusTid; + MPI_TB_FC_MANAGE_PID_AI Port; +} MPI_TB_FC_MANAGE_AI_UNION, MPI_POINTER PTR_MPI_TB_FC_MANAGE_AI_UNION, + MpiTbFcManageAiUnion_t, MPI_POINTER pMpiTbFcManageAiUnion_t; + +typedef struct _MSG_TOOLBOX_FC_MANAGE_REQUEST +{ + U8 Tool; /* 00h */ + U8 Reserved; /* 01h */ + U8 ChainOffset; /* 02h */ + U8 Function; /* 03h */ + U16 Reserved1; /* 04h */ + U8 Reserved2; /* 06h */ + U8 MsgFlags; /* 07h */ + U32 MsgContext; /* 08h */ + U8 Action; /* 0Ch */ + U8 Reserved3; /* 0Dh */ + U16 Reserved4; /* 0Eh */ + MPI_TB_FC_MANAGE_AI_UNION ActionInfo; /* 10h */ +} MSG_TOOLBOX_FC_MANAGE_REQUEST, MPI_POINTER PTR_MSG_TOOLBOX_FC_MANAGE_REQUEST, + ToolboxFcManageRequest_t, MPI_POINTER pToolboxFcManageRequest_t; + +/* defines for the Action field */ +#define MPI_TB_FC_MANAGE_ACTION_DISC_ALL (0x00) +#define MPI_TB_FC_MANAGE_ACTION_DISC_PID (0x01) +#define MPI_TB_FC_MANAGE_ACTION_DISC_BUS_TID (0x02) + + +/****************************************************************************/ +/* Diagnostic Buffer Post request */ +/****************************************************************************/ + +typedef struct _MSG_DIAG_BUFFER_POST_REQUEST +{ + U8 TraceLevel; /* 00h */ + U8 BufferType; /* 01h */ + U8 ChainOffset; /* 02h */ + U8 Function; /* 03h */ + U16 Reserved1; /* 04h */ + U8 Reserved2; /* 06h */ + U8 MsgFlags; /* 07h */ + U32 MsgContext; /* 08h */ + U32 ExtendedType; /* 0Ch */ + U32 BufferLength; /* 10h */ + U32 ProductSpecific[4]; /* 14h */ + U32 Reserved3; /* 18h */ + SGE_SIMPLE_UNION SGL; /* 28h */ +} MSG_DIAG_BUFFER_POST_REQUEST, MPI_POINTER PTR_MSG_DIAG_BUFFER_POST_REQUEST, + DiagBufferPostRequest_t, MPI_POINTER pDiagBufferPostRequest_t; + +#define MPI_DIAG_BUF_TYPE_TRACE (0x00) +#define MPI_DIAG_BUF_TYPE_SNAPSHOT (0x01) +#define MPI_DIAG_BUF_TYPE_EXTENDED (0x02) + +#define MPI_DIAG_EXTENDED_QTAG (0x00000001) + + +/* Diagnostic Buffer Post reply */ +typedef struct _MSG_DIAG_BUFFER_POST_REPLY +{ + U8 Reserved1; /* 00h */ + U8 BufferType; /* 01h */ + U8 MsgLength; /* 02h */ + U8 Function; /* 03h */ + U16 Reserved2; /* 04h */ + U8 Reserved3; /* 06h */ + U8 MsgFlags; /* 07h */ + U32 MsgContext; /* 08h */ + U16 Reserved4; /* 0Ch */ + U16 IOCStatus; /* 0Eh */ + U32 IOCLogInfo; /* 10h */ + U32 TransferLength; /* 14h */ +} MSG_DIAG_BUFFER_POST_REPLY, MPI_POINTER PTR_MSG_DIAG_BUFFER_POST_REPLY, + DiagBufferPostReply_t, MPI_POINTER pDiagBufferPostReply_t; + + +/****************************************************************************/ +/* Diagnostic Release request */ +/****************************************************************************/ + +typedef struct _MSG_DIAG_RELEASE_REQUEST +{ + U8 Reserved1; /* 00h */ + U8 BufferType; /* 01h */ + U8 ChainOffset; /* 02h */ + U8 Function; /* 03h */ + U16 Reserved2; /* 04h */ + U8 Reserved3; /* 06h */ + U8 MsgFlags; /* 07h */ + U32 MsgContext; /* 08h */ +} MSG_DIAG_RELEASE_REQUEST, MPI_POINTER PTR_MSG_DIAG_RELEASE_REQUEST, + DiagReleaseRequest_t, MPI_POINTER pDiagReleaseRequest_t; + + +/* Diagnostic Release reply */ +typedef struct _MSG_DIAG_RELEASE_REPLY +{ + U8 Reserved1; /* 00h */ + U8 BufferType; /* 01h */ + U8 MsgLength; /* 02h */ + U8 Function; /* 03h */ + U16 Reserved2; /* 04h */ + U8 Reserved3; /* 06h */ + U8 MsgFlags; /* 07h */ + U32 MsgContext; /* 08h */ + U16 Reserved4; /* 0Ch */ + U16 IOCStatus; /* 0Eh */ + U32 IOCLogInfo; /* 10h */ +} MSG_DIAG_RELEASE_REPLY, MPI_POINTER PTR_MSG_DIAG_RELEASE_REPLY, + DiagReleaseReply_t, MPI_POINTER pDiagReleaseReply_t; + + +#endif + + diff -Nru a/drivers/message/fusion/lsi/mpi_type.h b/drivers/message/fusion/lsi/mpi_type.h --- a/drivers/message/fusion/lsi/mpi_type.h Sun Mar 14 14:20:07 2004 +++ b/drivers/message/fusion/lsi/mpi_type.h Sun Mar 14 14:20:07 2004 @@ -1,12 +1,12 @@ /* - * Copyright (c) 2000-2002 LSI Logic Corporation. + * Copyright (c) 2000-2003 LSI Logic Corporation. * * - * Name: MPI_TYPE.H + * Name: mpi_type.h * Title: MPI Basic type definitions * Creation Date: June 6, 2000 * - * MPI Version: 01.02.01 + * mpi_type.h Version: 01.05.xx * * Version History * --------------- diff -Nru a/drivers/message/fusion/mptbase.c b/drivers/message/fusion/mptbase.c --- a/drivers/message/fusion/mptbase.c Sun Mar 14 14:20:06 2004 +++ b/drivers/message/fusion/mptbase.c Sun Mar 14 14:20:06 2004 @@ -44,7 +44,7 @@ * for gobs of hard work fixing and optimizing LAN code. * THANK YOU! * - * Copyright (c) 1999-2003 LSI Logic Corporation + * Copyright (c) 1999-2004 LSI Logic Corporation * Originally By: Steven J. Ralston * (mailto:sjralston1@netscape.net) * (mailto:mpt_linux_developer@lsil.com) @@ -209,8 +209,8 @@ static int GetIoUnitPage2(MPT_ADAPTER *ioc); static int mpt_GetScsiPortSettings(MPT_ADAPTER *ioc, int portnum); static int mpt_readScsiDevicePageHeaders(MPT_ADAPTER *ioc, int portnum); -static int mpt_findImVolumes(MPT_ADAPTER *ioc); static void mpt_read_ioc_pg_1(MPT_ADAPTER *ioc); +static void mpt_read_ioc_pg_4(MPT_ADAPTER *ioc); static void mpt_timer_expired(unsigned long data); static int SendEventNotification(MPT_ADAPTER *ioc, u8 EvSwitch); static int SendEventAck(MPT_ADAPTER *ioc, EventNotificationReply_t *evnp); @@ -347,14 +347,14 @@ MPT_FRAME_HDR *mf; MPT_FRAME_HDR *mr; u32 pa; - int req_idx = -1; + int req_idx; int cb_idx; int type; int freeme; - int count = 0; ioc = bus_id; +#ifdef MPT_DEBUG_IRQ /* * Verify ioc pointer is ok */ @@ -369,6 +369,7 @@ return IRQ_NONE; } } +#endif /* * Drain the reply FIFO! @@ -521,17 +522,7 @@ spin_unlock_irqrestore(&ioc->FreeQlock, flags); } - count++; - dirqprintk((MYIOC_s_INFO_FMT "ISR processed frame #%d\n", ioc->name, count)); mb(); - - if (count >= MPT_MAX_REPLIES_PER_ISR) { - dirqprintk((MYIOC_s_INFO_FMT "ISR processed %d replies.", - ioc->name, count)); - dirqprintk((" Giving this ISR a break!\n")); - return IRQ_HANDLED; - } - } /* drain reply FIFO */ return IRQ_HANDLED; @@ -605,7 +596,8 @@ } else if (func == MPI_FUNCTION_EVENT_ACK) { dprintk((MYIOC_s_INFO_FMT "mpt_base_reply, EventAck reply received\n", ioc->name)); - } else if (func == MPI_FUNCTION_CONFIG) { + } else if (func == MPI_FUNCTION_CONFIG || + func == MPI_FUNCTION_TOOLBOX) { CONFIGPARMS *pCfg; unsigned long flags; @@ -714,11 +706,7 @@ MptCallbacks[i] = cbfunc; MptDriverClass[i] = dclass; MptEvHandlers[i] = NULL; - MptDeviceDriverHandlers[i] = NULL; last_drv_idx = i; - if (cbfunc != mpt_base_reply) { - mpt_inc_use_count(); - } break; } } @@ -745,10 +733,6 @@ last_drv_idx++; if (isense_idx != -1 && isense_idx <= cb_idx) isense_idx++; - - if (cb_idx != mpt_base_index) { - mpt_dec_use_count(); - } } } @@ -890,7 +874,7 @@ MPT_FRAME_HDR* mpt_get_msg_frame(int handle, int iocid) { - MPT_FRAME_HDR *mf = NULL; + MPT_FRAME_HDR *mf; MPT_ADAPTER *iocp; unsigned long flags; @@ -922,6 +906,8 @@ iocp->mfcnt++; #endif } + else + mf = NULL; spin_unlock_irqrestore(&iocp->FreeQlock, flags); #ifdef MFCNT @@ -986,7 +972,11 @@ mf_dma_addr = iocp->req_frames_low_dma + req_offset; CHIPREG_WRITE32(&iocp->chip->RequestFifo, mf_dma_addr); + } else { + printk (KERN_ERR + "mpt_put_msg_frame: Invalid iocid=%d\n", iocid); } + } /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ @@ -1135,7 +1125,7 @@ ((reqBytes/4)<chip->IntStatus, 0); - if ((r = WaitForDoorbellAck(iocp, 1, sleepFlag)) < 0) { + if ((r = WaitForDoorbellAck(iocp, 5, sleepFlag)) < 0) { return -2; } @@ -1162,7 +1152,7 @@ (req_as_bytes[(ii*4) + 2] << 16) | (req_as_bytes[(ii*4) + 3] << 24)); CHIPREG_WRITE32(&iocp->chip->Doorbell, word); - if ((r = WaitForDoorbellAck(iocp, 1, sleepFlag)) < 0) { + if ((r = WaitForDoorbellAck(iocp, 5, sleepFlag)) < 0) { r = -3; break; } @@ -1190,10 +1180,12 @@ MPT_ADAPTER * mpt_adapter_find_first(void) { - MPT_ADAPTER *this = NULL; + MPT_ADAPTER *this; if (! Q_IS_EMPTY(&MptAdapters)) this = MptAdapters.head; + else + this = NULL; return this; } @@ -1208,10 +1200,12 @@ MPT_ADAPTER * mpt_adapter_find_next(MPT_ADAPTER *prev) { - MPT_ADAPTER *next = NULL; + MPT_ADAPTER *next; if (prev && (prev->forw != (MPT_ADAPTER*)&MptAdapters.head)) next = prev->forw; + else + next = NULL; return next; } @@ -1272,10 +1266,12 @@ int ii; int r = -ENODEV; u64 mask = 0xffffffffffffffffULL; + u8 revision; + u8 pcixcmd; if (pci_enable_device(pdev)) return r; - + if (!pci_set_dma_mask(pdev, mask)) { dprintk((KERN_INFO MYNAM ": 64 BIT PCI BUS DMA ADDRESSING SUPPORTED\n")); @@ -1296,12 +1292,30 @@ printk(KERN_ERR MYNAM ": ERROR - Insufficient memory to add adapter!\n"); return -ENOMEM; } - memset(ioc, 0, sizeof(*ioc)); + memset(ioc, 0, sizeof(MPT_ADAPTER)); ioc->alloc_total = sizeof(MPT_ADAPTER); ioc->req_sz = MPT_DEFAULT_FRAME_SIZE; /* avoid div by zero! */ - ioc->reply_sz = ioc->req_sz; + ioc->reply_sz = MPT_REPLY_FRAME_SIZE; ioc->pcidev = pdev; + +#if defined(MPTBASE_MEM_ALLOC_FIFO_FIX) + memcpy(&ioc->pcidev32,ioc->pcidev,sizeof(struct pci_dev)); + if (pci_set_dma_mask(&ioc->pcidev32, 0xFFFFFFFF)) { + dprintk((KERN_INFO MYNAM + ": error setting 32bit mask\n")); + kfree(ioc); + return -ENODEV; + } + + if (pci_set_consistent_dma_mask(&ioc->pcidev32, 0xFFFFFFFF)) { + dprintk((KERN_INFO MYNAM + ": error setting 32bit mask\n")); + kfree(ioc); + return -ENODEV; + } +#endif + ioc->diagPending = 0; spin_lock_init(&ioc->diagLock); @@ -1412,48 +1426,45 @@ } else if (pdev->device == MPI_MANUFACTPAGE_DEVICEID_FC929X) { ioc->chip_type = FC929X; - ioc->prod_name = "LSIFC929X"; - { + pci_read_config_byte(pdev, PCI_CLASS_REVISION, &revision); + if (revision < XL_929) { + ioc->prod_name = "LSIFC929X"; /* 929X Chip Fix. Set Split transactions level - * for PCIX. Set bits 5 - 6 to zero, turn on bit 4. - */ - u16 pcixcmd = 0; - pci_read_config_word(pdev, 0x6a, &pcixcmd); - pcixcmd &= 0xFF9F; - pcixcmd |= 0x0010; - pci_write_config_word(pdev, 0x6a, pcixcmd); + * for PCIX. Set MOST bits to zero. + */ + pci_read_config_byte(pdev, 0x6a, &pcixcmd); + pcixcmd &= 0x8F; + pci_write_config_byte(pdev, 0x6a, pcixcmd); + } else { + ioc->prod_name = "LSIFC929XL"; + /* 929XL Chip Fix. Set MMRBC to 0x08. + */ + pci_read_config_byte(pdev, 0x6a, &pcixcmd); + pcixcmd |= 0x08; + pci_write_config_byte(pdev, 0x6a, pcixcmd); } } else if (pdev->device == MPI_MANUFACTPAGE_DEVICEID_FC919X) { ioc->chip_type = FC919X; ioc->prod_name = "LSIFC919X"; - { - /* 919X Chip Fix. Set Split transactions level - * for PCIX. Set bits 5 - 6 to zero, turn on bit 4. - */ - u16 pcixcmd = 0; - pci_read_config_word(pdev, 0x6a, &pcixcmd); - pcixcmd &= 0xFF9F; - pcixcmd |= 0x0010; - pci_write_config_word(pdev, 0x6a, pcixcmd); - } + /* 919X Chip Fix. Set Split transactions level + * for PCIX. Set MOST bits to zero. + */ + pci_read_config_byte(pdev, 0x6a, &pcixcmd); + pcixcmd &= 0x8F; + pci_write_config_byte(pdev, 0x6a, pcixcmd); } else if (pdev->device == MPI_MANUFACTPAGE_DEVID_53C1030) { ioc->chip_type = C1030; ioc->prod_name = "LSI53C1030"; - { - u8 revision; - - /* 1030 Chip Fix. Disable Split transactions - * for PCIX. Set bits 4 - 6 to zero if Rev < C0( = 8) - */ - pci_read_config_byte(pdev, PCI_CLASS_REVISION, &revision); - if (revision < 0x08) { - u16 pcixcmd = 0; - pci_read_config_word(pdev, 0x6a, &pcixcmd); - pcixcmd &= 0xFF8F; - pci_write_config_word(pdev, 0x6a, pcixcmd); - } + /* 1030 Chip Fix. Disable Split transactions + * for PCIX. Set MOST bits to zero if Rev < C0( = 8). + */ + pci_read_config_byte(pdev, PCI_CLASS_REVISION, &revision); + if (revision < C0_1030) { + pci_read_config_byte(pdev, 0x6a, &pcixcmd); + pcixcmd &= 0x8F; + pci_write_config_byte(pdev, 0x6a, pcixcmd); } } else if (pdev->device == MPI_MANUFACTPAGE_DEVID_1030_53C1035) { @@ -1515,17 +1526,18 @@ || (ioc->chip_type == C1035) || (ioc->chip_type == FC929X)) mpt_detect_bound_ports(ioc, pdev); - if ((r = mpt_do_ioc_recovery(ioc, MPT_HOSTEVENT_IOC_BRINGUP, CAN_SLEEP)) != 0) { - printk(KERN_WARNING MYNAM ": WARNING - %s did not initialize properly! (%d)\n", - ioc->name, r); - } + if ((r = mpt_do_ioc_recovery(ioc, + MPT_HOSTEVENT_IOC_BRINGUP, CAN_SLEEP)) != 0) { + printk(KERN_WARNING MYNAM + ": WARNING - %s did not initialize properly! (%d)\n", + ioc->name, r); - if(r != 0 ) { Q_DEL_ITEM(ioc); mpt_adapters[ioc->id] = NULL; free_irq(ioc->pci_irq, ioc); iounmap(mem); kfree(ioc); + pci_set_drvdata(pdev, NULL); return r; } @@ -1565,6 +1577,7 @@ CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF); ioc->active = 0; + mpt_sync_irq(pdev->irq); /* Clear any lingering interrupt */ CHIPREG_WRITE32(&ioc->chip->IntStatus, 0); @@ -1574,7 +1587,6 @@ Q_DEL_ITEM(ioc); mpt_adapter_dispose(ioc); - mptscsih_sync_irq(pdev->irq); pci_set_drvdata(pdev, NULL); } @@ -1755,20 +1767,23 @@ int r; int ii; int handlers; + int ret = 0; + int reset_alt_ioc_active = 0; printk(KERN_INFO MYNAM ": Initiating %s %s\n", ioc->name, reason==MPT_HOSTEVENT_IOC_BRINGUP ? "bringup" : "recovery"); - /* Disable reply interrupts */ + /* Disable reply interrupts (also blocks FreeQ) */ CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF); ioc->active = 0; - /* NOTE: Access to IOC's request FreeQ is now blocked! */ if (ioc->alt_ioc) { - /* Disable alt-IOC's reply interrupts for a bit ... */ + if (ioc->alt_ioc->active) + reset_alt_ioc_active = 1; + + /* Disable alt-IOC's reply interrupts (and FreeQ) for a bit ... */ CHIPREG_WRITE32(&ioc->alt_ioc->chip->IntMask, 0xFFFFFFFF); ioc->alt_ioc->active = 0; - /* NOTE: Access to alt-IOC's request FreeQ is now blocked! */ } hard = 1; @@ -1776,15 +1791,29 @@ hard = 0; if ((hard_reset_done = MakeIocReady(ioc, hard, sleepFlag)) < 0) { - printk(KERN_WARNING MYNAM ": %s NOT READY WARNING!\n", - ioc->name); + if (hard_reset_done == -4) { + printk(KERN_WARNING MYNAM ": %s Owned by PEER..skipping!\n", + ioc->name); + + if (reset_alt_ioc_active && ioc->alt_ioc) { + /* (re)Enable alt-IOC! (reply interrupt, FreeQ) */ + dprintk((KERN_INFO MYNAM ": alt-%s reply irq re-enabled\n", + ioc->alt_ioc->name)); + CHIPREG_WRITE32(&ioc->alt_ioc->chip->IntMask, ~(MPI_HIM_RIM)); + ioc->alt_ioc->active = 1; + } + + } else { + printk(KERN_WARNING MYNAM ": %s NOT READY WARNING!\n", + ioc->name); + } return -1; } /* hard_reset_done = 0 if a soft reset was performed * and 1 if a hard reset was performed. */ - if (hard_reset_done && ioc->alt_ioc) { + if (hard_reset_done && reset_alt_ioc_active && ioc->alt_ioc) { if ((r = MakeIocReady(ioc->alt_ioc, 0, sleepFlag)) == 0) alt_ioc_ready = 1; else @@ -1793,42 +1822,55 @@ ioc->alt_ioc->name, r); } - /* Get IOC facts! */ + /* Get IOC facts! Allow 1 retry */ if ((r = GetIocFacts(ioc, sleepFlag, reason)) != 0) - return -2; - if (reason == MPT_HOSTEVENT_IOC_BRINGUP) { + r = GetIocFacts(ioc, sleepFlag, reason); + + if (r) { + ret = -2; + } else if (reason == MPT_HOSTEVENT_IOC_BRINGUP) { MptDisplayIocCapabilities(ioc); } if (alt_ioc_ready) { - if ((r = GetIocFacts(ioc->alt_ioc, sleepFlag, reason)) != 0) - return -2; - if (reason == MPT_HOSTEVENT_IOC_BRINGUP) { + if ((r = GetIocFacts(ioc->alt_ioc, sleepFlag, reason)) != 0) { + /* Retry - alt IOC was initialized once + */ + r = GetIocFacts(ioc->alt_ioc, sleepFlag, reason); + } + if (r) { + alt_ioc_ready = 0; + reset_alt_ioc_active = 0; + } else if (reason == MPT_HOSTEVENT_IOC_BRINGUP) { MptDisplayIocCapabilities(ioc->alt_ioc); } } - /* - * Prime reply & request queues! + /* Prime reply & request queues! * (mucho alloc's) Must be done prior to * init as upper addresses are needed for init. + * If fails, continue with alt-ioc processing */ - if ((r = PrimeIocFifos(ioc)) != 0) - return -3; + if ((ret == 0) && ((r = PrimeIocFifos(ioc)) != 0)) + ret = -3; - // May need to check/upload firmware & data here! - if ((r = SendIocInit(ioc, sleepFlag)) != 0) - return -4; + /* May need to check/upload firmware & data here! + * If fails, continue with alt-ioc processing + */ + if ((ret == 0) && ((r = SendIocInit(ioc, sleepFlag)) != 0)) + ret = -4; // NEW! if (alt_ioc_ready && ((r = PrimeIocFifos(ioc->alt_ioc)) != 0)) { printk(KERN_WARNING MYNAM ": alt-%s: (%d) FIFO mgmt alloc WARNING!\n", ioc->alt_ioc->name, r); alt_ioc_ready = 0; + reset_alt_ioc_active = 0; } if (alt_ioc_ready) { if ((r = SendIocInit(ioc->alt_ioc, sleepFlag)) != 0) { alt_ioc_ready = 0; + reset_alt_ioc_active = 0; printk(KERN_WARNING MYNAM ": alt-%s: (%d) init failure WARNING!\n", ioc->alt_ioc->name, r); @@ -1840,9 +1882,14 @@ ddlprintk((MYIOC_s_INFO_FMT "firmware upload required!\n", ioc->name)); - r = mpt_do_upload(ioc, sleepFlag); - if (r != 0) - printk(KERN_WARNING MYNAM ": firmware upload failure!\n"); + /* Controller is not operational, cannot do upload + */ + if (ret == 0) { + r = mpt_do_upload(ioc, sleepFlag); + if (r != 0) + printk(KERN_WARNING MYNAM ": firmware upload failure!\n"); + } + /* Handle the alt IOC too */ if ((alt_ioc_ready) && (ioc->alt_ioc->upload_fw)){ ddlprintk((MYIOC_s_INFO_FMT @@ -1855,12 +1902,13 @@ } } + if (ret == 0) { + /* Enable! (reply interrupt) */ + CHIPREG_WRITE32(&ioc->chip->IntMask, ~(MPI_HIM_RIM)); + ioc->active = 1; + } - /* Enable! (reply interrupt) */ - CHIPREG_WRITE32(&ioc->chip->IntMask, ~(MPI_HIM_RIM)); - ioc->active = 1; - - if (ioc->alt_ioc) { + if (reset_alt_ioc_active && ioc->alt_ioc) { /* (re)Enable alt-IOC! (reply interrupt) */ dprintk((KERN_INFO MYNAM ": alt-%s reply irq re-enabled\n", ioc->alt_ioc->name)); @@ -1872,7 +1920,7 @@ * Enable MPT base driver management of EventNotification * and EventAck handling. */ - if (!ioc->facts.EventState) + if ((ret == 0) && (!ioc->facts.EventState)) (void) SendEventNotification(ioc, 1); /* 1=Enable EventNotification */ if (ioc->alt_ioc && alt_ioc_ready && !ioc->alt_ioc->facts.EventState) @@ -1886,7 +1934,7 @@ * routine calls HardResetHandler, which calls into here again, * and we try GetLanConfigPages again... */ - if (reason == MPT_HOSTEVENT_IOC_BRINGUP) { + if ((ret == 0) && (reason == MPT_HOSTEVENT_IOC_BRINGUP)) { if ((int)ioc->chip_type <= (int)FC929) { /* * Pre-fetch FC port WWN and stuff... @@ -1928,6 +1976,8 @@ /* Check, and possibly reset, the coalescing value */ mpt_read_ioc_pg_1(ioc); + + mpt_read_ioc_pg_4(ioc); } GetIoUnitPage2(ioc); @@ -1942,24 +1992,24 @@ if (hard_reset_done) { r = handlers = 0; for (ii=MPT_MAX_PROTOCOL_DRIVERS-1; ii; ii--) { - if (MptResetHandlers[ii]) { + if ((ret == 0) && MptResetHandlers[ii]) { dprintk((MYIOC_s_INFO_FMT "Calling IOC post_reset handler #%d\n", ioc->name, ii)); r += (*(MptResetHandlers[ii]))(ioc, MPT_IOC_POST_RESET); handlers++; + } - if (alt_ioc_ready) { - dprintk((MYIOC_s_INFO_FMT "Calling alt-%s post_reset handler #%d\n", - ioc->name, ioc->alt_ioc->name, ii)); - r += (*(MptResetHandlers[ii]))(ioc->alt_ioc, MPT_IOC_POST_RESET); - handlers++; - } + if (alt_ioc_ready && MptResetHandlers[ii]) { + dprintk((MYIOC_s_INFO_FMT "Calling alt-%s post_reset handler #%d\n", + ioc->name, ioc->alt_ioc->name, ii)); + r += (*(MptResetHandlers[ii]))(ioc->alt_ioc, MPT_IOC_POST_RESET); + handlers++; } } /* FIXME? Examine results here? */ } - return 0; + return ret; } /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ @@ -2114,6 +2164,15 @@ kfree(this->spi_data.pIocPg3); this->spi_data.pIocPg3 = NULL; } + + if (freeup && this->spi_data.pIocPg4 != NULL) { + sz = this->spi_data.IocPg4Sz; + pci_free_consistent(this->pcidev, sz, + this->spi_data.pIocPg4, + this->spi_data.IocPg4_dma); + this->spi_data.pIocPg4 = NULL; + this->alloc_total -= sz; + } } } @@ -2429,7 +2488,7 @@ * 1 byte in size, so we can just fire it off as is. */ r = mpt_handshake_req_reply_wait(ioc, req_sz, (u32*)&get_facts, - reply_sz, (u16*)facts, 3 /*seconds*/, sleepFlag); + reply_sz, (u16*)facts, 5 /*seconds*/, sleepFlag); if (r != 0) return r; @@ -2510,7 +2569,7 @@ */ ioc->req_sz = MIN(MPT_DEFAULT_FRAME_SIZE, facts->RequestFrameSize * 4); ioc->req_depth = MIN(MPT_MAX_REQ_DEPTH, facts->GlobalCredits); - ioc->reply_sz = ioc->req_sz; + ioc->reply_sz = MPT_REPLY_FRAME_SIZE; ioc->reply_depth = MIN(MPT_DEFAULT_REPLY_DEPTH, facts->ReplyQueueDepth); dprintk((MYIOC_s_INFO_FMT "reply_sz=%3d, reply_depth=%4d\n", @@ -2578,7 +2637,7 @@ * 1 byte in size, so we can just fire it off as is. */ ii = mpt_handshake_req_reply_wait(ioc, req_sz, (u32*)&get_pfacts, - reply_sz, (u16*)pfacts, 3 /*seconds*/, sleepFlag); + reply_sz, (u16*)pfacts, 5 /*seconds*/, sleepFlag); if (ii != 0) return ii; @@ -2651,6 +2710,8 @@ /* ioc_init.MsgFlags = 0; */ /* ioc_init.MsgContext = cpu_to_le32(0x00000000); */ ioc_init.ReplyFrameSize = cpu_to_le16(ioc->reply_sz); /* in BYTES */ + + ioc->facts.RequestFrameSize = ioc_init.ReplyFrameSize; if (sizeof(dma_addr_t) == sizeof(u64)) { /* Save the upper 32-bits of the request @@ -2663,6 +2724,9 @@ ioc_init.HostMfaHighAddr = cpu_to_le32(0); ioc_init.SenseBufferHighAddr = cpu_to_le32(0); } + + ioc->facts.CurrentHostMfaHighAddr = ioc_init.HostMfaHighAddr; + ioc->facts.CurrentSenseBufferHighAddr = ioc_init.SenseBufferHighAddr; dprintk((MYIOC_s_INFO_FMT "Sending IOCInit (req @ %p)\n", ioc->name, &ioc_init)); @@ -2773,8 +2837,8 @@ void * mpt_alloc_fw_memory(MPT_ADAPTER *ioc, int size, int *frags, int *alloc_sz) { - fw_image_t **cached_fw = NULL; - u8 *mem = NULL; + fw_image_t **cached_fw; + u8 *mem; dma_addr_t fw_dma; int alloc_total = 0; int bytes_left, bytes, num_frags; @@ -2922,7 +2986,7 @@ u8 reply[sizeof(FWUploadReply_t)]; FWUpload_t *prequest; FWUploadReply_t *preply; - FWUploadTCSGE_t *ptcsge = NULL; + FWUploadTCSGE_t *ptcsge; int sgeoffset; int ii, sz, reply_sz; int cmdStatus, freeMem = 0; @@ -3054,16 +3118,16 @@ static int mpt_downloadboot(MPT_ADAPTER *ioc, int sleepFlag) { - MpiFwHeader_t *FwHdr = NULL; + MpiFwHeader_t *FwHdr; MpiExtImageHeader_t *ExtHdr; - fw_image_t **pCached = NULL; + fw_image_t **pCached=NULL; int fw_sz; u32 diag0val; #ifdef MPT_DEBUG u32 diag1val = 0; #endif int count = 0; - u32 *ptru32 = NULL; + u32 *ptru32; u32 diagRwData; u32 nextImage; u32 ext_offset; @@ -3097,11 +3161,11 @@ pCached = (fw_image_t **)ioc->cached_fw; else if (ioc->alt_ioc && (ioc->alt_ioc->cached_fw != NULL)) pCached = (fw_image_t **)ioc->alt_ioc->cached_fw; + else + return -2; ddlprintk((MYIOC_s_INFO_FMT "DbGb2: FW Image @ %p\n", ioc->name, pCached)); - if (!pCached) - return -2; /* Write magic sequence to WriteSequence register * until enter diagnostic mode @@ -3351,6 +3415,7 @@ SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, sleepFlag); if (sleepFlag == CAN_SLEEP) { + set_current_state(TASK_INTERRUPTIBLE); schedule_timeout(HZ); } else { mdelay (1000); @@ -3551,11 +3616,11 @@ } else { /* Wait for FW to reload and for board * to go to the READY state. - * Maximum wait is 30 seconds. + * Maximum wait is 60 seconds. * If fail, no error will check again * with calling program. */ - for (count = 0; count < 30; count ++) { + for (count = 0; count < 60; count ++) { doorbell = CHIPREG_READ32(&ioc->chip->Doorbell); doorbell &= MPI_IOC_STATE_MASK; @@ -3673,7 +3738,7 @@ dprintk((KERN_WARNING MYNAM ": %s: Sending IOC reset(0x%02x)!\n", ioc->name, reset_type)); CHIPREG_WRITE32(&ioc->chip->Doorbell, reset_type<reply_frames == NULL) { sz = (ioc->reply_sz * ioc->reply_depth) + 128; +#if defined(MPTBASE_MEM_ALLOC_FIFO_FIX) + mem = pci_alloc_consistent(&ioc->pcidev32, sz, &ioc->reply_alloc_dma); +#else mem = pci_alloc_consistent(ioc->pcidev, sz, &ioc->reply_alloc_dma); +#endif if (mem == NULL) goto out_fail; @@ -3778,7 +3847,11 @@ */ sz = ((sz + 0x1000UL - 1UL) / 0x1000) * 0x1000; +#if defined(MPTBASE_MEM_ALLOC_FIFO_FIX) + mem = pci_alloc_consistent(&ioc->pcidev32, sz, &ioc->req_alloc_dma); +#else mem = pci_alloc_consistent(ioc->pcidev, sz, &ioc->req_alloc_dma); +#endif if (mem == NULL) goto out_fail; @@ -3894,8 +3967,8 @@ /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ /** - * mpt_handshake_req_reply_wait - Send MPT request to and receive reply from - * IOC via doorbell handshake method. + * mpt_handshake_req_reply_wait - Send MPT request to and receive reply + * from IOC via doorbell handshake method. * @ioc: Pointer to MPT_ADAPTER structure * @reqBytes: Size of the request in bytes * @req: Pointer to MPT request frame @@ -3955,7 +4028,7 @@ * our handshake request. */ CHIPREG_WRITE32(&ioc->chip->IntStatus, 0); - if (!failcnt && (t = WaitForDoorbellAck(ioc, 2, sleepFlag)) < 0) + if (!failcnt && (t = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0) failcnt++; if (!failcnt) { @@ -3973,7 +4046,7 @@ (req_as_bytes[(ii*4) + 3] << 24)); CHIPREG_WRITE32(&ioc->chip->Doorbell, word); - if ((t = WaitForDoorbellAck(ioc, 2, sleepFlag)) < 0) + if ((t = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0) failcnt++; } @@ -4137,7 +4210,7 @@ } else { hs_reply[u16cnt++] = le16_to_cpu(CHIPREG_READ32(&ioc->chip->Doorbell) & 0x0000FFFF); CHIPREG_WRITE32(&ioc->chip->IntStatus, 0); - if ((t = WaitForDoorbellInt(ioc, 2, sleepFlag)) < 0) + if ((t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0) failcnt++; else { hs_reply[u16cnt++] = le16_to_cpu(CHIPREG_READ32(&ioc->chip->Doorbell) & 0x0000FFFF); @@ -4154,7 +4227,7 @@ * reply 16 bits at a time. */ for (u16cnt=2; !failcnt && u16cnt < (2 * mptReply->MsgLength); u16cnt++) { - if ((t = WaitForDoorbellInt(ioc, 2, sleepFlag)) < 0) + if ((t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0) failcnt++; hword = le16_to_cpu(CHIPREG_READ32(&ioc->chip->Doorbell) & 0x0000FFFF); /* don't overflow our IOC hs_reply[] buffer! */ @@ -4163,7 +4236,7 @@ CHIPREG_WRITE32(&ioc->chip->IntStatus, 0); } - if (!failcnt && (t = WaitForDoorbellInt(ioc, 2, sleepFlag)) < 0) + if (!failcnt && (t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0) failcnt++; CHIPREG_WRITE32(&ioc->chip->IntStatus, 0); @@ -4466,7 +4539,7 @@ static int mpt_GetScsiPortSettings(MPT_ADAPTER *ioc, int portnum) { - u8 *pbuf = NULL; + u8 *pbuf; dma_addr_t buf_dma; CONFIGPARMS cfg; ConfigPageHeader_t header; @@ -4528,6 +4601,9 @@ pPP0->Capabilities = le32_to_cpu(pPP0->Capabilities); pPP0->PhysicalInterface = le32_to_cpu(pPP0->PhysicalInterface); + if ( (pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_QAS) == 0 ) + ioc->spi_data.noQas |= MPT_TARGET_NO_NEGO_QAS; + ioc->spi_data.maxBusWidth = pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_WIDE ? 1 : 0; data = pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_MAX_SYNC_OFFSET_MASK; if (data) { @@ -4552,7 +4628,6 @@ } if (pbuf) { pci_free_consistent(ioc->pcidev, header.PageLength * 4, pbuf, buf_dma); - pbuf = NULL; } } } @@ -4589,6 +4664,8 @@ /* Save the Port Page 2 data * (reformat into a 32bit quantity) */ + data = le32_to_cpu(pPP2->PortFlags) & MPI_SCSIPORTPAGE2_PORT_FLAGS_DV_MASK; + ioc->spi_data.PortFlags = data; for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) { pdevice = &pPP2->DeviceSettings[ii]; data = (le16_to_cpu(pdevice->DeviceFlags) << 16) | @@ -4598,7 +4675,6 @@ } pci_free_consistent(ioc->pcidev, header.PageLength * 4, pbuf, buf_dma); - pbuf = NULL; } } @@ -4671,11 +4747,12 @@ * -EFAULT if read of config page header fails or data pointer not NULL * -ENOMEM if pci_alloc failed */ -static int +int mpt_findImVolumes(MPT_ADAPTER *ioc) { - IOCPage2_t *pIoc2 = NULL; - ConfigPageIoc2RaidVol_t *pIocRv = NULL; + IOCPage2_t *pIoc2; + u8 *mem; + ConfigPageIoc2RaidVol_t *pIocRv; dma_addr_t ioc2_dma; CONFIGPARMS cfg; ConfigPageHeader_t header; @@ -4685,9 +4762,6 @@ u8 nVols, nPhys; u8 vid, vbus, vioc; - if (ioc->spi_data.pIocPg3) - return -EFAULT; - /* Read IOCP2 header then the page. */ header.PageVersion = 0; @@ -4716,11 +4790,22 @@ if (mpt_config(ioc, &cfg) != 0) goto done_and_free; + if ( (mem = (u8 *)ioc->spi_data.pIocPg2) == NULL ) { + mem = kmalloc(iocpage2sz, GFP_ATOMIC); + if (mem) { + ioc->spi_data.pIocPg2 = (IOCPage2_t *) mem; + } else { + goto done_and_free; + } + } + memcpy(mem, (u8 *)pIoc2, iocpage2sz); + /* Identify RAID Volume Id's */ nVols = pIoc2->NumActiveVolumes; if ( nVols == 0) { - /* No RAID Volumes. Done. + /* No RAID Volume. */ + goto done_and_free; } else { /* At least 1 RAID Volume */ @@ -4745,17 +4830,14 @@ /* Identify Hidden Physical Disk Id's */ nPhys = pIoc2->NumActivePhysDisks; if (nPhys == 0) { - /* No physical disks. Done. + /* No physical disks. */ } else { mpt_read_ioc_pg_3(ioc); } done_and_free: - if (pIoc2) { - pci_free_consistent(ioc->pcidev, iocpage2sz, pIoc2, ioc2_dma); - pIoc2 = NULL; - } + pci_free_consistent(ioc->pcidev, iocpage2sz, pIoc2, ioc2_dma); return rc; } @@ -4763,7 +4845,7 @@ int mpt_read_ioc_pg_3(MPT_ADAPTER *ioc) { - IOCPage3_t *pIoc3 = NULL; + IOCPage3_t *pIoc3; u8 *mem; CONFIGPARMS cfg; ConfigPageHeader_t header; @@ -4816,18 +4898,66 @@ } } - if (pIoc3) { - pci_free_consistent(ioc->pcidev, iocpage3sz, pIoc3, ioc3_dma); - pIoc3 = NULL; - } + pci_free_consistent(ioc->pcidev, iocpage3sz, pIoc3, ioc3_dma); return 0; } static void +mpt_read_ioc_pg_4(MPT_ADAPTER *ioc) +{ + IOCPage4_t *pIoc4; + CONFIGPARMS cfg; + ConfigPageHeader_t header; + dma_addr_t ioc4_dma; + int iocpage4sz; + + /* Read and save IOC Page 4 + */ + header.PageVersion = 0; + header.PageLength = 0; + header.PageNumber = 4; + header.PageType = MPI_CONFIG_PAGETYPE_IOC; + cfg.hdr = &header; + cfg.physAddr = -1; + cfg.pageAddr = 0; + cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER; + cfg.dir = 0; + cfg.timeout = 0; + if (mpt_config(ioc, &cfg) != 0) + return; + + if (header.PageLength == 0) + return; + + if ( (pIoc4 = ioc->spi_data.pIocPg4) == NULL ) { + iocpage4sz = (header.PageLength + 4) * 4; /* Allow 4 additional SEP's */ + pIoc4 = pci_alloc_consistent(ioc->pcidev, iocpage4sz, &ioc4_dma); + if (!pIoc4) + return; + } else { + ioc4_dma = ioc->spi_data.IocPg4_dma; + iocpage4sz = ioc->spi_data.IocPg4Sz; + } + + /* Read the Page into dma memory. + */ + cfg.physAddr = ioc4_dma; + cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT; + if (mpt_config(ioc, &cfg) == 0) { + ioc->spi_data.pIocPg4 = (IOCPage4_t *) pIoc4; + ioc->spi_data.IocPg4_dma = ioc4_dma; + ioc->spi_data.IocPg4Sz = iocpage4sz; + } else { + pci_free_consistent(ioc->pcidev, iocpage4sz, pIoc4, ioc4_dma); + ioc->spi_data.pIocPg4 = NULL; + } +} + +static void mpt_read_ioc_pg_1(MPT_ADAPTER *ioc) { - IOCPage1_t *pIoc1 = NULL; + IOCPage1_t *pIoc1; CONFIGPARMS cfg; ConfigPageHeader_t header; dma_addr_t ioc1_dma; @@ -4903,10 +5033,7 @@ } } - if (pIoc1) { - pci_free_consistent(ioc->pcidev, iocpage1sz, pIoc1, ioc1_dma); - pIoc1 = NULL; - } + pci_free_consistent(ioc->pcidev, iocpage1sz, pIoc1, ioc1_dma); return; } @@ -5022,9 +5149,8 @@ pReq->Reserved = 0; pReq->ChainOffset = 0; pReq->Function = MPI_FUNCTION_CONFIG; - pReq->Reserved1[0] = 0; - pReq->Reserved1[1] = 0; - pReq->Reserved1[2] = 0; + pReq->ExtPageLength = 0; + pReq->ExtPageType = 0; pReq->MsgFlags = 0; for (ii=0; ii < 8; ii++) pReq->Reserved2[ii] = 0; @@ -5083,6 +5209,112 @@ } /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ +/** + * mpt_toolbox - Generic function to issue toolbox message + * @ioc - Pointer to an adapter structure + * @cfg - Pointer to a toolbox structure. Struct contains + * action, page address, direction, physical address + * and pointer to a configuration page header + * Page header is updated. + * + * Returns 0 for success + * -EPERM if not allowed due to ISR context + * -EAGAIN if no msg frames currently available + * -EFAULT for non-successful reply or no reply (timeout) + */ +int +mpt_toolbox(MPT_ADAPTER *ioc, CONFIGPARMS *pCfg) +{ + ToolboxIstwiReadWriteRequest_t *pReq; + MPT_FRAME_HDR *mf; + unsigned long flags; + int rc; + int flagsLength; + int in_isr; + + /* (Bugzilla:fibrebugs, #513) + * Bug fix (part 1)! 20010905 -sralston + * Prevent calling wait_event() (below), if caller happens + * to be in ISR context, because that is fatal! + */ + in_isr = in_interrupt(); + if (in_isr) { + dcprintk((MYIOC_s_WARN_FMT "toobox request not allowed in ISR context!\n", + ioc->name)); + return -EPERM; + } + + /* Get and Populate a free Frame + */ + if ((mf = mpt_get_msg_frame(mpt_base_index, ioc->id)) == NULL) { + dcprintk((MYIOC_s_WARN_FMT "mpt_toolbox: no msg frames!\n", + ioc->name)); + return -EAGAIN; + } + pReq = (ToolboxIstwiReadWriteRequest_t *)mf; + pReq->Tool = pCfg->action; + pReq->Reserved = 0; + pReq->ChainOffset = 0; + pReq->Function = MPI_FUNCTION_TOOLBOX; + pReq->Reserved1 = 0; + pReq->Reserved2 = 0; + pReq->MsgFlags = 0; + pReq->Flags = pCfg->dir; + pReq->BusNum = 0; + pReq->Reserved3 = 0; + pReq->NumAddressBytes = 0x01; + pReq->Reserved4 = 0; + pReq->DataLength = 0x04; + pReq->DeviceAddr = 0xB0; + pReq->Addr1 = 0; + pReq->Addr2 = 0; + pReq->Addr3 = 0; + pReq->Reserved5 = 0; + + /* Add a SGE to the config request. + */ + + flagsLength = MPT_SGE_FLAGS_SSIMPLE_READ | 4; + + mpt_add_sge((char *)&pReq->SGL, flagsLength, pCfg->physAddr); + + dcprintk((MYIOC_s_INFO_FMT "Sending Toolbox request, Tool=%x\n", + ioc->name, pReq->Tool)); + + /* Append pCfg pointer to end of mf + */ + *((void **) (((u8 *) mf) + (ioc->req_sz - sizeof(void *)))) = (void *) pCfg; + + /* Initalize the timer + */ + init_timer(&pCfg->timer); + pCfg->timer.data = (unsigned long) ioc; + pCfg->timer.function = mpt_timer_expired; + pCfg->wait_done = 0; + + /* Set the timer; ensure 10 second minimum */ + if (pCfg->timeout < 10) + pCfg->timer.expires = jiffies + HZ*10; + else + pCfg->timer.expires = jiffies + HZ*pCfg->timeout; + + /* Add to end of Q, set timer and then issue this command */ + spin_lock_irqsave(&ioc->FreeQlock, flags); + Q_ADD_TAIL(&ioc->configQ.head, &pCfg->linkage, Q_ITEM); + spin_unlock_irqrestore(&ioc->FreeQlock, flags); + + add_timer(&pCfg->timer); + mpt_put_msg_frame(mpt_base_index, ioc->id, mf); + wait_event(mpt_waitq, pCfg->wait_done); + + /* mf has been freed - do not access */ + + rc = pCfg->status; + + return rc; +} + +/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ /* * mpt_timer_expired - Call back for timer process. * Used only internal config functionality. @@ -5124,9 +5356,12 @@ dprintk((KERN_WARNING MYNAM ": IOC %s_reset routed to MPT base driver!\n", - reset_phase==MPT_IOC_PRE_RESET ? "pre" : "post")); + reset_phase==MPT_IOC_SETUP_RESET ? "setup" : ( + reset_phase==MPT_IOC_PRE_RESET ? "pre" : "post"))); - if (reset_phase == MPT_IOC_PRE_RESET) { + if (reset_phase == MPT_IOC_SETUP_RESET) { + ; + } else if (reset_phase == MPT_IOC_PRE_RESET) { /* If the internal config Q is not empty - * delete timer. MF resources will be freed when * the FIFO's are primed. @@ -5590,7 +5825,7 @@ int rc; unsigned long flags; - dprintk((MYIOC_s_INFO_FMT "HardResetHandler Entered!\n", ioc->name)); + dtmprintk((MYIOC_s_INFO_FMT "HardResetHandler Entered!\n", ioc->name)); #ifdef MFCNT printk(MYIOC_s_INFO_FMT "HardResetHandler Entered!\n", ioc->name); printk("MF count 0x%x !\n", ioc->mfcnt); @@ -5611,6 +5846,29 @@ /* FIXME: If do_ioc_recovery fails, repeat.... */ + /* The SCSI driver needs to adjust timeouts on all current + * commands prior to the diagnostic reset being issued. + * Prevents timeouts occuring during a diagnostic reset...very bad. + * For all other protocol drivers, this is a no-op. + */ + { + int ii; + int r = 0; + + for (ii=MPT_MAX_PROTOCOL_DRIVERS-1; ii; ii--) { + if (MptResetHandlers[ii]) { + dtmprintk((MYIOC_s_INFO_FMT "Calling IOC reset_setup handler #%d\n", + ioc->name, ii)); + r += (*(MptResetHandlers[ii]))(ioc, MPT_IOC_SETUP_RESET); + if (ioc->alt_ioc) { + dtmprintk((MYIOC_s_INFO_FMT "Calling alt-%s setup reset handler #%d\n", + ioc->name, ioc->alt_ioc->name, ii)); + r += (*(MptResetHandlers[ii]))(ioc->alt_ioc, MPT_IOC_SETUP_RESET); + } + } + } + } + if ((rc = mpt_do_ioc_recovery(ioc, MPT_HOSTEVENT_IOC_RECOVER, sleepFlag)) != 0) { printk(KERN_WARNING MYNAM ": WARNING - (%d) Cannot recover %s\n", rc, ioc->name); @@ -5625,7 +5883,7 @@ ioc->alt_ioc->diagPending = 0; spin_unlock_irqrestore(&ioc->diagLock, flags); - dprintk((MYIOC_s_INFO_FMT "HardResetHandler rc = %d!\n", ioc->name, rc)); + dtmprintk((MYIOC_s_INFO_FMT "HardResetHandler rc = %d!\n", ioc->name, rc)); return rc; } @@ -5634,7 +5892,7 @@ static char * EventDescriptionStr(u8 event, u32 evData0) { - char *ds = NULL; + char *ds; switch(event) { case MPI_EVENT_NONE: @@ -5839,109 +6097,11 @@ "FCP Initiator", "FCP Target", "LAN", "MPI Message Layer", "FC Link", "Context Manager", "Invalid Field Offset", "State Change Info" }; - char *desc = "unknown"; u8 subcl = (log_info >> 24) & 0x7; - u32 SubCl = log_info & 0x27000000; - - switch(log_info) { -/* FCP Initiator */ - case MPI_IOCLOGINFO_FC_INIT_ERROR_OUT_OF_ORDER_FRAME: - desc = "Received an out of order frame - unsupported"; - break; - case MPI_IOCLOGINFO_FC_INIT_ERROR_BAD_START_OF_FRAME: - desc = "Bad start of frame primative"; - break; - case MPI_IOCLOGINFO_FC_INIT_ERROR_BAD_END_OF_FRAME: - desc = "Bad end of frame primative"; - break; - case MPI_IOCLOGINFO_FC_INIT_ERROR_OVER_RUN: - desc = "Receiver hardware detected overrun"; - break; - case MPI_IOCLOGINFO_FC_INIT_ERROR_RX_OTHER: - desc = "Other errors caught by IOC which require retries"; - break; - case MPI_IOCLOGINFO_FC_INIT_ERROR_SUBPROC_DEAD: - desc = "Main processor could not initialize sub-processor"; - break; -/* FC Target */ - case MPI_IOCLOGINFO_FC_TARGET_NO_PDISC: - desc = "Not sent because we are waiting for a PDISC from the initiator"; - break; - case MPI_IOCLOGINFO_FC_TARGET_NO_LOGIN: - desc = "Not sent because we are not logged in to the remote node"; - break; - case MPI_IOCLOGINFO_FC_TARGET_DOAR_KILLED_BY_LIP: - desc = "Data Out, Auto Response, not sent due to a LIP"; - break; - case MPI_IOCLOGINFO_FC_TARGET_DIAR_KILLED_BY_LIP: - desc = "Data In, Auto Response, not sent due to a LIP"; - break; - case MPI_IOCLOGINFO_FC_TARGET_DIAR_MISSING_DATA: - desc = "Data In, Auto Response, missing data frames"; - break; - case MPI_IOCLOGINFO_FC_TARGET_DONR_KILLED_BY_LIP: - desc = "Data Out, No Response, not sent due to a LIP"; - break; - case MPI_IOCLOGINFO_FC_TARGET_WRSP_KILLED_BY_LIP: - desc = "Auto-response after a write not sent due to a LIP"; - break; - case MPI_IOCLOGINFO_FC_TARGET_DINR_KILLED_BY_LIP: - desc = "Data In, No Response, not completed due to a LIP"; - break; - case MPI_IOCLOGINFO_FC_TARGET_DINR_MISSING_DATA: - desc = "Data In, No Response, missing data frames"; - break; - case MPI_IOCLOGINFO_FC_TARGET_MRSP_KILLED_BY_LIP: - desc = "Manual Response not sent due to a LIP"; - break; - case MPI_IOCLOGINFO_FC_TARGET_NO_CLASS_3: - desc = "Not sent because remote node does not support Class 3"; - break; - case MPI_IOCLOGINFO_FC_TARGET_LOGIN_NOT_VALID: - desc = "Not sent because login to remote node not validated"; - break; - case MPI_IOCLOGINFO_FC_TARGET_FROM_OUTBOUND: - desc = "Cleared from the outbound queue after a logout"; - break; - case MPI_IOCLOGINFO_FC_TARGET_WAITING_FOR_DATA_IN: - desc = "Cleared waiting for data after a logout"; - break; -/* LAN */ - case MPI_IOCLOGINFO_FC_LAN_TRANS_SGL_MISSING: - desc = "Transaction Context Sgl Missing"; - break; - case MPI_IOCLOGINFO_FC_LAN_TRANS_WRONG_PLACE: - desc = "Transaction Context found before an EOB"; - break; - case MPI_IOCLOGINFO_FC_LAN_TRANS_RES_BITS_SET: - desc = "Transaction Context value has reserved bits set"; - break; - case MPI_IOCLOGINFO_FC_LAN_WRONG_SGL_FLAG: - desc = "Invalid SGL Flags"; - break; -/* FC Link */ - case MPI_IOCLOGINFO_FC_LINK_LOOP_INIT_TIMEOUT: - desc = "Loop initialization timed out"; - break; - case MPI_IOCLOGINFO_FC_LINK_ALREADY_INITIALIZED: - desc = "Another system controller already initialized the loop"; - break; - case MPI_IOCLOGINFO_FC_LINK_LINK_NOT_ESTABLISHED: - desc = "Not synchronized to signal or still negotiating (possible cable problem)"; - break; - case MPI_IOCLOGINFO_FC_LINK_CRC_ERROR: - desc = "CRC check detected error on received frame"; - break; - } +// u32 SubCl = log_info & 0x27000000; printk(MYIOC_s_INFO_FMT "LogInfo(0x%08x): SubCl={%s}", ioc->name, log_info, subcl_str[subcl]); - if (SubCl == MPI_IOCLOGINFO_FC_INVALID_FIELD_BYTE_OFFSET) - printk(", byte_offset=%d\n", log_info & MPI_IOCLOGINFO_FC_INVALID_FIELD_MAX_OFFSET); - else if (SubCl == MPI_IOCLOGINFO_FC_STATE_CHANGE) - printk("\n"); /* StateChg in LogInfo & 0x00FFFFFF, above */ - else - printk("\n" KERN_INFO " %s\n", desc); } /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ @@ -6021,7 +6181,6 @@ isense_idx = last_drv_idx; r = 1; } - mpt_inc_use_count(); return r; } @@ -6040,7 +6199,6 @@ mpt_ScsiOpcodesPtr = NULL; printk(KERN_INFO MYNAM ": English readable SCSI-3 strings disabled)-:\n"); isense_idx = -1; - mpt_dec_use_count(); } /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ @@ -6072,6 +6230,8 @@ EXPORT_SYMBOL(mpt_stm_index); EXPORT_SYMBOL(mpt_HardResetHandler); EXPORT_SYMBOL(mpt_config); +EXPORT_SYMBOL(mpt_toolbox); +EXPORT_SYMBOL(mpt_findImVolumes); EXPORT_SYMBOL(mpt_read_ioc_pg_3); EXPORT_SYMBOL(mpt_alloc_fw_memory); EXPORT_SYMBOL(mpt_free_fw_memory); diff -Nru a/drivers/message/fusion/mptbase.h b/drivers/message/fusion/mptbase.h --- a/drivers/message/fusion/mptbase.h Sun Mar 14 14:20:06 2004 +++ b/drivers/message/fusion/mptbase.h Sun Mar 14 14:20:06 2004 @@ -8,7 +8,7 @@ * Credits: * (see mptbase.c) * - * Copyright (c) 1999-2003 LSI Logic Corporation + * Copyright (c) 1999-2004 LSI Logic Corporation * Originally By: Steven J. Ralston * (mailto:sjralston1@netscape.net) * (mailto:mpt_linux_developer@lsil.com) @@ -68,6 +68,7 @@ #include "lsi/mpi_fc.h" /* Fibre Channel (lowlevel) support */ #include "lsi/mpi_targ.h" /* SCSI/FCP Target protcol support */ +#include "lsi/mpi_tool.h" /* Tools support */ #include "lsi/fc_log.h" /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ @@ -77,11 +78,11 @@ #endif #ifndef COPYRIGHT -#define COPYRIGHT "Copyright (c) 1999-2003 " MODULEAUTHOR +#define COPYRIGHT "Copyright (c) 1999-2004 " MODULEAUTHOR #endif -#define MPT_LINUX_VERSION_COMMON "3.00.03" -#define MPT_LINUX_PACKAGE_NAME "@(#)mptlinux-3.00.03" +#define MPT_LINUX_VERSION_COMMON "3.01.01" +#define MPT_LINUX_PACKAGE_NAME "@(#)mptlinux-3.01.01" #define WHAT_MAGIC_STRING "@" "(" "#" ")" #define show_mptmod_ver(s,ver) \ @@ -93,10 +94,10 @@ */ #define MPT_MAX_ADAPTERS 18 #define MPT_MAX_PROTOCOL_DRIVERS 16 -#define MPT_MAX_BUS 1 +#define MPT_MAX_BUS 1 /* Do not change */ #define MPT_MAX_FC_DEVICES 255 #define MPT_MAX_SCSI_DEVICES 16 -#define MPT_LAST_LUN 31 +#define MPT_LAST_LUN 255 #define MPT_SENSE_BUFFER_ALLOC 64 /* allow for 256 max sense alloc, but only 255 max request */ #if MPT_SENSE_BUFFER_ALLOC >= 256 @@ -127,6 +128,8 @@ #define MPT_MAX_FRAME_SIZE 128 #define MPT_DEFAULT_FRAME_SIZE 128 +#define MPT_REPLY_FRAME_SIZE 0x40 /* Must be a multiple of 8 */ + #define MPT_SG_REQ_128_SCALE 1 #define MPT_SG_REQ_96_SCALE 2 #define MPT_SG_REQ_64_SCALE 4 @@ -150,6 +153,9 @@ #define MPT_NARROW 0 #define MPT_WIDE 1 +#define C0_1030 0x08 +#define XL_929 0x01 + #ifdef __KERNEL__ /* { */ /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ @@ -185,8 +191,8 @@ void (*remove) (struct pci_dev *dev); void (*shutdown) (struct device * dev); #ifdef CONFIG_PM - int (*suspend) (struct pci_dev *dev, u32 state); int (*resume) (struct pci_dev *dev); + int (*suspend) (struct pci_dev *dev, u32 state); #endif }; @@ -201,9 +207,6 @@ u32 arg1; u32 pad; void *argp1; -#ifndef MPT_SCSI_USE_NEW_EH - void *argp2; -#endif } linkage; /* * NOTE: When request frames are free, on the linkage structure @@ -255,6 +258,7 @@ MPIHeader_t hdr; SCSIIORequest_t scsireq; SCSIIOReply_t sreply; + ConfigReply_t configreply; MPIDefaultReply_t reply; MPT_FRAME_TRACKER frame; } u; @@ -408,12 +412,9 @@ ScsiCmndTracker SentQ; ScsiCmndTracker DoneQ; u32 num_luns; -//--- LUN split here? - u32 luns; /* Max LUNs is 32 */ - u8 inq_data[SCSI_STD_INQUIRY_BYTES]; /* 36 */ - u8 pad0[4]; - u8 inq00_data[20]; - u8 pad1[4]; + u32 luns[8]; /* Max LUNs is 256 */ + u8 pad[4]; + u8 inq_data[8]; /* IEEE Registered Extended Identifier obtained via INQUIRY VPD page 0x83 */ /* NOTE: Do not separate uniq_prepad and uniq_data @@ -421,26 +422,17 @@ u8 uniq_prepad[8]; u8 uniq_data[20]; u8 pad2[4]; - u8 inqC3_data[12]; - u8 pad3[4]; - u8 inqC9_data[12]; - u8 pad4[4]; - u8 dev_vol_name[64]; } VirtDevice; /* * Fibre Channel (SCSI) target device and associated defines... */ -#define MPT_TARGET_DEFAULT_DV_STATUS 0 -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,55) -#define MPT_TARGET_FLAGS_CONFIGURED 0x02 -#define MPT_TARGET_FLAGS_Q_YES 0x08 -#else +#define MPT_TARGET_DEFAULT_DV_STATUS 0x00 #define MPT_TARGET_FLAGS_VALID_NEGO 0x01 #define MPT_TARGET_FLAGS_VALID_INQUIRY 0x02 #define MPT_TARGET_FLAGS_Q_YES 0x08 #define MPT_TARGET_FLAGS_VALID_56 0x10 -#endif +#define MPT_TARGET_FLAGS_SAF_TE_ISSUED 0x20 #define MPT_TARGET_NO_NEGO_WIDE 0x01 #define MPT_TARGET_NO_NEGO_SYNC 0x02 @@ -539,8 +531,13 @@ /* #define MPT_SCSICFG_BLK_NEGO 0x10 WriteSDP1 with WDTR and SDTR disabled */ typedef struct _ScsiCfgData { + u32 PortFlags; int *nvram; /* table of device NVRAM values */ + IOCPage2_t *pIocPg2; /* table of Raid Volumes */ IOCPage3_t *pIocPg3; /* table of physical disks */ + IOCPage4_t *pIocPg4; /* SEP devices addressing */ + dma_addr_t IocPg4_dma; /* Phys Addr of IOCPage4 data */ + int IocPg4Sz; /* IOCPage4 size */ u8 dvStatus[MPT_MAX_SCSI_DEVICES]; int isRaid; /* bit field, 1 if RAID */ u8 minSyncFactor; /* 0xFF if async */ @@ -554,7 +551,8 @@ u8 dvScheduled; /* 1 if scheduled */ u8 forceDv; /* 1 to force DV scheduling */ u8 noQas; /* Disable QAS for this adapter */ - u8 rsvd[2]; + u8 Saf_Te; /* 1 to force all Processors as SAF-TE if Inquiry data length is too short to check for SAF-TE */ + u8 rsvd[1]; } ScsiCfgData; typedef struct _fw_image { @@ -610,6 +608,9 @@ u32 sense_buf_low_dma; int mtrr_reg; struct pci_dev *pcidev; /* struct pci_dev pointer */ +#if defined(MPTBASE_MEM_ALLOC_FIFO_FIX) + struct pci_dev pcidev32; /* struct pci_dev pointer */ +#endif u8 *memmap; /* mmap address */ struct Scsi_Host *sh; /* Scsi Host pointer */ ScsiCfgData spi_data; /* Scsi config. data */ @@ -622,6 +623,12 @@ int eventTypes; /* Event logging parameters */ int eventContext; /* Next event context */ int eventLogSize; /* Max number of cached events */ +#ifdef MPTSCSIH_DBG_TIMEOUT + int timeout_hard; + int timeout_delta; + int timeout_cnt; + int timeout_maxcnt; +#endif struct _mpt_ioctl_events *events; /* pointer to event log */ fw_image_t **cached_fw; /* Pointer to FW SG List */ Q_TRACKER configQ; /* linked list of config. requests */ @@ -665,6 +672,7 @@ /* reset_phase defs */ #define MPT_IOC_PRE_RESET 0 #define MPT_IOC_POST_RESET 1 +#define MPT_IOC_SETUP_RESET 2 /* * Invent MPT host event (super-set of MPI Events) @@ -880,14 +888,12 @@ #define MPT_NVRAM_WIDE_DISABLE (0x00100000) #define MPT_NVRAM_BOOT_CHOICE (0x00200000) -#ifdef MPT_SCSI_USE_NEW_EH /* The TM_STATE variable is used to provide strict single threading of TM * requests as well as communicate TM error conditions. */ #define TM_STATE_NONE (0) #define TM_STATE_IN_PROGRESS (1) #define TM_STATE_ERROR (2) -#endif typedef struct _MPT_SCSI_HOST { MPT_ADAPTER *ioc; @@ -928,12 +934,8 @@ u8 is_spi; /* Parallel SCSI i/f */ u8 negoNvram; /* DV disabled, nego NVRAM */ u8 is_multipath; /* Multi-path compatible */ -#ifdef MPT_SCSI_USE_NEW_EH u8 tmState; u8 rsvd[1]; -#else - u8 rsvd[2]; -#endif MPT_FRAME_HDR *tmPtr; /* Ptr to TM request*/ MPT_FRAME_HDR *cmdPtr; /* Ptr to nonOS request */ struct scsi_cmnd *abortSCpnt; @@ -1033,8 +1035,10 @@ extern void mpt_print_ioc_summary(MPT_ADAPTER *ioc, char *buf, int *size, int len, int showlan); extern int mpt_HardResetHandler(MPT_ADAPTER *ioc, int sleepFlag); extern int mpt_config(MPT_ADAPTER *ioc, CONFIGPARMS *cfg); +extern int mpt_toolbox(MPT_ADAPTER *ioc, CONFIGPARMS *cfg); extern void *mpt_alloc_fw_memory(MPT_ADAPTER *ioc, int size, int *frags, int *alloc_sz); extern void mpt_free_fw_memory(MPT_ADAPTER *ioc, fw_image_t **alt_img); +extern int mpt_findImVolumes(MPT_ADAPTER *ioc); extern int mpt_read_ioc_pg_3(MPT_ADAPTER *ioc); /* diff -Nru a/drivers/message/fusion/mptctl.c b/drivers/message/fusion/mptctl.c --- a/drivers/message/fusion/mptctl.c Sun Mar 14 14:20:06 2004 +++ b/drivers/message/fusion/mptctl.c Sun Mar 14 14:20:06 2004 @@ -29,7 +29,7 @@ * * (see also mptbase.c) * - * Copyright (c) 1999-2003 LSI Logic Corporation + * Copyright (c) 1999-2004 LSI Logic Corporation * Originally By: Steven J. Ralston, Noah Romer * (mailto:sjralston1@netscape.net) * (mailto:mpt_linux_developer@lsil.com) @@ -82,6 +82,7 @@ #include #include #include +#include #include #include @@ -91,7 +92,7 @@ #include "../../scsi/scsi.h" #include "../../scsi/hosts.h" -#define COPYRIGHT "Copyright (c) 1999-2003 LSI Logic Corporation" +#define COPYRIGHT "Copyright (c) 1999-2004 LSI Logic Corporation" #define MODULEAUTHOR "Steven J. Ralston, Noah Romer, Pamela Delaney" #include "mptbase.h" #include "mptctl.h" @@ -260,6 +261,7 @@ iocStatus = reply->u.reply.IOCStatus & MPI_IOCSTATUS_MASK; if (iocStatus == MPI_IOCSTATUS_SCSI_TASK_MGMT_FAILED) { if (ioc->ioctl->status & MPT_IOCTL_STATUS_TIMER_ACTIVE) { + ioc->ioctl->reset &= ~MPTCTL_RESET_OK; del_timer (&ioc->ioctl->timer); ioc->ioctl->timer.expires = jiffies + HZ; add_timer(&ioc->ioctl->timer); @@ -456,7 +458,7 @@ unsigned long flags; spin_lock_irqsave(&hd->ioc->FreeQlock, flags); -#ifdef MPT_SCSI_USE_NEW_EH + if (hd->tmState == TM_STATE_NONE) { hd->tmState = TM_STATE_IN_PROGRESS; hd->tmPending = 1; @@ -465,15 +467,7 @@ spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags); return -EBUSY; } -#else - if (hd->tmPending) { - spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags); - return -EBUSY; - } else { - hd->tmPending = 1; - spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags); - } -#endif + return 0; } @@ -488,14 +482,10 @@ return; spin_lock_irqsave(&ioc->FreeQlock, flags); -#ifdef MPT_SCSI_USE_NEW_EH + hd->tmState = TM_STATE_ERROR; hd->tmPending = 0; spin_unlock_irqrestore(&ioc->FreeQlock, flags); -#else - hd->tmPending = 0; - spin_unlock_irqrestore(&ioc->FreeQlock, flags); -#endif return; } @@ -513,9 +503,12 @@ { MPT_IOCTL *ioctl = ioc->ioctl; dctlprintk((KERN_INFO MYNAM ": IOC %s_reset routed to IOCTL driver!\n", - reset_phase==MPT_IOC_PRE_RESET ? "pre" : "post")); + reset_phase==MPT_IOC_SETUP_RESET ? "setup" : ( + reset_phase==MPT_IOC_PRE_RESET ? "pre" : "post"))); - if (reset_phase == MPT_IOC_PRE_RESET){ + if (reset_phase == MPT_IOC_SETUP_RESET){ + ; + } else if (reset_phase == MPT_IOC_PRE_RESET){ /* Someone has called the reset handler to * do a hard reset. No more replies from the FW. @@ -532,13 +525,15 @@ } } else { + ioctl->tmPtr = NULL; + /* Set the status and continue IOCTL * processing. All memory will be free'd * by originating thread after wake_up is * called. */ if (ioctl && (ioctl->status & MPT_IOCTL_STATUS_TIMER_ACTIVE)){ - ioctl->status = MPT_IOCTL_STATUS_DID_IOCRESET; + ioctl->status |= MPT_IOCTL_STATUS_DID_IOCRESET; /* Wake up the calling process */ @@ -620,7 +615,11 @@ return -ENODEV; } - + if (!iocp->active) { + printk(KERN_ERR "%s::mptctl_ioctl() @%d - Controller disabled.\n", + __FILE__, __LINE__); + return -EFAULT; + } /* Handle those commands that are just returning * information stored in the driver. @@ -691,7 +690,7 @@ return -ENODEV; /* (-6) No such device or address */ } - if (mpt_HardResetHandler(iocp, NO_SLEEP) != 0) { + if (mpt_HardResetHandler(iocp, CAN_SLEEP) != 0) { printk (KERN_ERR "%s@%d::mptctl_do_reset - reset failed.\n", __FILE__, __LINE__); return -1; @@ -1254,10 +1253,10 @@ /* Fill in the data and return the structure to the calling * program */ - if (ioc->chip_type == C1030) - karg.adapterType = MPT_IOCTL_INTERFACE_SCSI; - else + if ((int)ioc->chip_type <= (int) FC929) karg.adapterType = MPT_IOCTL_INTERFACE_FC; + else + karg.adapterType = MPT_IOCTL_INTERFACE_SCSI; port = karg.hdr.port; @@ -1307,7 +1306,8 @@ /* Set the Version Strings. */ - strlcpy (karg.driverVersion, MPT_LINUX_PACKAGE_NAME, MPT_IOCTL_VERSION_LENGTH); + strncpy (karg.driverVersion, MPT_LINUX_PACKAGE_NAME, MPT_IOCTL_VERSION_LENGTH); + karg.driverVersion[MPT_IOCTL_VERSION_LENGTH-1]='\0'; karg.busChangeEvent = 0; karg.hostId = ioc->pfacts[port].PortSCSIID; @@ -1343,15 +1343,18 @@ MPT_ADAPTER *ioc; struct Scsi_Host *sh; MPT_SCSI_HOST *hd; + VirtDevice *vdev; char *pmem; int *pdata; + IOCPage2_t *pIoc2; int iocnum; int numDevices = 0; unsigned int max_id; - int ii, jj, lun; + int id, jj, indexed_lun, lun_index; + u32 lun; int maxWordsLeft; int numBytes; - u8 port; + u8 port, devType, bus_id; dctlprintk(("mptctl_gettargetinfo called.\n")); if (copy_from_user(&karg, uarg, sizeof(struct mpt_ioctl_targetinfo))) { @@ -1418,27 +1421,59 @@ * sh->max_id = maximum target ID + 1 */ if (hd && hd->Targets) { - ii = 0; - while (ii <= max_id) { - if (hd->Targets[ii]) { - for (jj = 0; jj <= MPT_LAST_LUN; jj++) { - lun = (1 << jj); - if (hd->Targets[ii]->luns & lun) { - numDevices++; - *pdata = (jj << 16) | ii; - --maxWordsLeft; - - pdata++; - - if (maxWordsLeft <= 0) - break; + mpt_findImVolumes(ioc); + pIoc2 = ioc->spi_data.pIocPg2; + for ( id = 0; id <= max_id; id++ ) { + if ( pIoc2 && pIoc2->NumActiveVolumes && + ( id == pIoc2->RaidVolume[0].VolumeID ) ) { + if (maxWordsLeft <= 0) { + printk(KERN_ERR "mptctl_gettargetinfo - " + "buffer is full but volume is available on ioc %d\n, numDevices=%d", iocnum, numDevices); + goto data_space_full; + } + if ( ( pIoc2->RaidVolume[0].Flags & MPI_IOCPAGE2_FLAG_VOLUME_INACTIVE ) == 0 ) + devType = 0x80; + else + devType = 0xC0; + bus_id = pIoc2->RaidVolume[0].VolumeBus; + numDevices++; + *pdata = ( (devType << 24) | (bus_id << 8) | id ); + dctlprintk((KERN_ERR "mptctl_gettargetinfo - " + "volume ioc=%d target=%x numDevices=%d pdata=%p\n", iocnum, *pdata, numDevices, pdata)); + pdata++; + --maxWordsLeft; + } else { + vdev = hd->Targets[id]; + if (vdev) { + for (jj = 0; jj <= MPT_LAST_LUN; jj++) { + lun_index = (jj >> 5); + indexed_lun = (jj % 32); + lun = (1 << indexed_lun); + if (vdev->luns[lun_index] & lun) { + if (maxWordsLeft <= 0) { + printk(KERN_ERR + "mptctl_gettargetinfo - " + "buffer is full but more targets are available on ioc %d numDevices=%d\n", + iocnum, numDevices); + goto data_space_full; + } + bus_id = vdev->bus_id; + numDevices++; + *pdata = ( (jj << 16) | (bus_id << 8) | id ); + dctlprintk((KERN_ERR + "mptctl_gettargetinfo - " + "target ioc=%d target=%x numDevices=%d pdata=%p\n", + iocnum, *pdata, numDevices, pdata)); + pdata++; + --maxWordsLeft; + } } } } - ii++; } } } +data_space_full: karg.numDevices = numDevices; /* Copy part of the data from kernel memory to user memory @@ -1507,8 +1542,10 @@ #else karg.chip_type = ioc->chip_type; #endif - strlcpy (karg.name, ioc->name, MPT_MAX_NAME); - strlcpy (karg.product, ioc->prod_name, MPT_PRODUCT_LENGTH); + strncpy (karg.name, ioc->name, MPT_MAX_NAME); + karg.name[MPT_MAX_NAME-1]='\0'; + strncpy (karg.product, ioc->prod_name, MPT_PRODUCT_LENGTH); + karg.product[MPT_PRODUCT_LENGTH-1]='\0'; /* Copy the data from kernel memory to user memory */ @@ -1806,22 +1843,20 @@ MPT_FRAME_HDR *mf = NULL; MPIHeader_t *hdr; char *psge; - MptSge_t *this_sge = NULL; - MptSge_t *sglbuf = NULL; struct buflist bufIn; /* data In buffer */ struct buflist bufOut; /* data Out buffer */ - dma_addr_t sglbuf_dma; - dma_addr_t dma_addr; + dma_addr_t dma_addr_in; + dma_addr_t dma_addr_out; int dir; /* PCI data direction */ int sgSize = 0; /* Num SG elements */ - int this_alloc; - int iocnum, flagsLength; - int sz, rc = 0; - int msgContext; + int iocnum, flagsLength; + int sz, rc = 0; + int msgContext; int tm_flags_set = 0; u16 req_idx; dctlprintk(("mptctl_do_mpt_command called.\n")); + bufIn.kptr = bufOut.kptr = NULL; if (((iocnum = mpt_verify_adapter(karg.hdr.iocnum, &ioc)) < 0) || (ioc == NULL)) { @@ -1848,7 +1883,7 @@ if (karg.dataOutSize > 0) sz += sizeof(dma_addr_t) + sizeof(u32); - if ( sz > ioc->req_sz) { + if (sz > ioc->req_sz) { printk(KERN_ERR "%s@%d::mptctl_do_mpt_command - " "Request frame too large (%d) maximum (%d)\n", __FILE__, __LINE__, sz, ioc->req_sz); @@ -1891,6 +1926,9 @@ switch (hdr->Function) { case MPI_FUNCTION_IOC_FACTS: case MPI_FUNCTION_PORT_FACTS: + karg.dataOutSize = karg.dataInSize = 0; + break; + case MPI_FUNCTION_CONFIG: case MPI_FUNCTION_FC_COMMON_TRANSPORT_SEND: case MPI_FUNCTION_FC_EX_LINK_SRVC_SEND: @@ -1928,12 +1966,14 @@ */ if (karg.maxSenseBytes > MPT_SENSE_BUFFER_SIZE) pScsiReq->SenseBufferLength = MPT_SENSE_BUFFER_SIZE; + else + pScsiReq->SenseBufferLength = karg.maxSenseBytes; pScsiReq->SenseBufferLowAddr = cpu_to_le32(ioc->sense_buf_low_dma + (req_idx * MPT_SENSE_BUFFER_ALLOC)); - if ( (hd = (MPT_SCSI_HOST *) ioc->sh->hostdata)) { + if ((hd = (MPT_SCSI_HOST *) ioc->sh->hostdata)) { if (hd->Targets) pTarget = hd->Targets[target]; } @@ -1944,11 +1984,10 @@ /* Have the IOCTL driver set the direction based * on the dataOutSize (ordering issue with Sparc). */ - if (karg.dataOutSize > 0 ) { + if (karg.dataOutSize > 0) { scsidir = MPI_SCSIIO_CONTROL_WRITE; dataSize = karg.dataOutSize; - } - else { + } else { scsidir = MPI_SCSIIO_CONTROL_READ; dataSize = karg.dataInSize; } @@ -1990,6 +2029,8 @@ */ if (karg.maxSenseBytes > MPT_SENSE_BUFFER_SIZE) pScsiReq->SenseBufferLength = MPT_SENSE_BUFFER_SIZE; + else + pScsiReq->SenseBufferLength = karg.maxSenseBytes; pScsiReq->SenseBufferLowAddr = cpu_to_le32(ioc->sense_buf_low_dma @@ -2001,11 +2042,10 @@ /* Have the IOCTL driver set the direction based * on the dataOutSize (ordering issue with Sparc). */ - if (karg.dataOutSize > 0 ) { + if (karg.dataOutSize > 0) { scsidir = MPI_SCSIIO_CONTROL_WRITE; dataSize = karg.dataOutSize; - } - else { + } else { scsidir = MPI_SCSIIO_CONTROL_READ; dataSize = karg.dataInSize; } @@ -2033,7 +2073,7 @@ __FILE__, __LINE__); rc = -EFAULT; goto done_free_mem; - } else if (mptctl_set_tm_flags(hd) != 0) { + } else if (mptctl_set_tm_flags(hd) != 0) { rc = -EPERM; goto done_free_mem; } @@ -2107,7 +2147,7 @@ * preceede the data in (read) SGE. psgList is used to free the * allocated memory. */ - psge = (char *) ( ((int *) mf) + karg.dataSgeOffset); + psge = (char *) (((int *) mf) + karg.dataSgeOffset); flagsLength = 0; /* bufIn and bufOut are used for user to kernel space transfers @@ -2115,30 +2155,18 @@ bufIn.kptr = bufOut.kptr = NULL; bufIn.len = bufOut.len = 0; - if (karg.dataOutSize > 0 ) + if (karg.dataOutSize > 0) sgSize ++; - if (karg.dataInSize > 0 ) + if (karg.dataInSize > 0) sgSize ++; if (sgSize > 0) { - /* Allocate memory for the SGL. - * Used to free kernel memory once - * the MF is freed. - */ - sglbuf = pci_alloc_consistent (ioc->pcidev, - sgSize*sizeof(MptSge_t), &sglbuf_dma); - if (sglbuf == NULL) { - rc = -ENOMEM; - goto done_free_mem; - } - this_sge = sglbuf; - /* Set up the dataOut memory allocation */ if (karg.dataOutSize > 0) { dir = PCI_DMA_TODEVICE; - if (karg.dataInSize > 0 ) { + if (karg.dataInSize > 0) { flagsLength = ( MPI_SGE_FLAGS_SIMPLE_ELEMENT | MPI_SGE_FLAGS_DIRECTION | mpt_addr_size() ) @@ -2147,22 +2175,25 @@ flagsLength = MPT_SGE_FLAGS_SSIMPLE_WRITE; } flagsLength |= karg.dataOutSize; - - this_alloc = karg.dataOutSize; - bufOut.len = this_alloc; + bufOut.len = karg.dataOutSize; bufOut.kptr = pci_alloc_consistent( - ioc->pcidev, this_alloc, &dma_addr); + ioc->pcidev, bufOut.len, &dma_addr_out); if (bufOut.kptr == NULL) { rc = -ENOMEM; goto done_free_mem; } else { + /* Set up this SGE. + * Copy to MF and to sglbuf + */ + mpt_add_sge(psge, flagsLength, dma_addr_out); + psge += (sizeof(u32) + sizeof(dma_addr_t)); + /* Copy user data to kernel space. */ if (copy_from_user(bufOut.kptr, karg.dataOutBufPtr, bufOut.len)) { - printk(KERN_ERR "%s@%d::mptctl_do_mpt_command - Unable " "to read user data " @@ -2171,16 +2202,6 @@ rc = -EFAULT; goto done_free_mem; } - - /* Set up this SGE. - * Copy to MF and to sglbuf - */ - mpt_add_sge(psge, flagsLength, dma_addr); - psge += (sizeof(u32) + sizeof(dma_addr_t)); - - this_sge->FlagsLength = flagsLength; - this_sge->Address = dma_addr; - this_sge++; } } @@ -2189,10 +2210,10 @@ flagsLength = MPT_SGE_FLAGS_SSIMPLE_READ; flagsLength |= karg.dataInSize; - this_alloc = karg.dataInSize; - bufIn.len = this_alloc; + bufIn.len = karg.dataInSize; bufIn.kptr = pci_alloc_consistent(ioc->pcidev, - this_alloc, &dma_addr); + bufIn.len, &dma_addr_in); + if (bufIn.kptr == NULL) { rc = -ENOMEM; goto done_free_mem; @@ -2200,11 +2221,7 @@ /* Set up this SGE * Copy to MF and to sglbuf */ - mpt_add_sge(psge, flagsLength, dma_addr); - - this_sge->FlagsLength = flagsLength; - this_sge->Address = dma_addr; - this_sge++; + mpt_add_sge(psge, flagsLength, dma_addr_in); } } } else { @@ -2228,7 +2245,7 @@ if (hdr->Function == MPI_FUNCTION_SCSI_TASK_MGMT) { rc = mpt_send_handshake_request(mptctl_id, ioc->id, - sizeof(SCSITaskMgmt_t), (u32*)mf, NO_SLEEP); + sizeof(SCSITaskMgmt_t), (u32*)mf, CAN_SLEEP); if (rc == 0) { wait_event(mptctl_wait, ioc->ioctl->wait_done); } else { @@ -2236,45 +2253,41 @@ tm_flags_set= 0; del_timer(&ioc->ioctl->timer); ioc->ioctl->status &= ~MPT_IOCTL_STATUS_TIMER_ACTIVE; - ioc->ioctl->status = MPT_IOCTL_STATUS_TM_FAILED; + ioc->ioctl->status |= MPT_IOCTL_STATUS_TM_FAILED; + mpt_free_msg_frame(mptctl_id, ioc->id, mf); } } else { mpt_put_msg_frame(mptctl_id, ioc->id, mf); wait_event(mptctl_wait, ioc->ioctl->wait_done); } - /* The command is complete. * Return data to the user. + mf = NULL; + + /* MF Cleanup: + * If command failed and failure triggered a diagnostic reset + * OR a diagnostic reset happens during command processing, + * no data, messaging queues are reset (mf cannot be accessed), + * and status is DID_IOCRESET * - * If command completed, mf has been freed so cannot - * use this memory. + * If a user-requested bus reset fails to be handshaked, then + * mf is returned to free queue and status is TM_FAILED. * - * If timeout, a recovery mechanism has been called. - * Need to free the mf. + * Otherise, the command completed and the mf was freed + # by ISR (mf cannot be touched). */ if (ioc->ioctl->status & MPT_IOCTL_STATUS_DID_IOCRESET) { - - /* A timeout - there is no data to return to the - * the user other than an error. - * The timer callback deleted the + /* The timer callback deleted the * timer and reset the adapter queues. */ printk(KERN_WARNING "%s@%d::mptctl_do_mpt_command - " "Timeout Occurred on IOCTL! Reset IOC.\n", __FILE__, __LINE__); tm_flags_set= 0; rc = -ETIME; - - /* Free memory and return to the calling function - */ - goto done_free_mem; } else if (ioc->ioctl->status & MPT_IOCTL_STATUS_TM_FAILED) { - /* User TM request failed! + /* User TM request failed! mf has not been freed. */ rc = -ENODATA; } else { - /* Callback freed request frame. - */ - mf = NULL; - /* If a valid reply frame, copy to the user. * Offset 2: reply length in U32's */ @@ -2332,42 +2345,31 @@ } done_free_mem: - /* Clear status bits. - */ - ioc->ioctl->status = 0; + /* Clear all status bits except TMTIMER_ACTIVE, this bit is cleared + * upon completion of the TM command. + * ioc->ioctl->status = 0; + */ + ioc->ioctl->status &= ~(MPT_IOCTL_STATUS_TIMER_ACTIVE | MPT_IOCTL_STATUS_TM_FAILED | + MPT_IOCTL_STATUS_COMMAND_GOOD | MPT_IOCTL_STATUS_SENSE_VALID | + MPT_IOCTL_STATUS_RF_VALID | MPT_IOCTL_STATUS_DID_IOCRESET); if (tm_flags_set) mptctl_free_tm_flags(ioc); - if (sglbuf) { - this_sge = sglbuf; - - /* Free the allocated memory. - */ - if (bufOut.kptr != NULL ) { - dma_addr = this_sge->Address; - this_sge++; /* go to next structure */ - this_alloc = bufOut.len; - pci_free_consistent(ioc->pcidev, - this_alloc, (void *) bufOut.kptr, dma_addr); - } - - if (bufIn.kptr != NULL ) { - dma_addr = this_sge->Address; - this_alloc = bufIn.len; - - pci_free_consistent(ioc->pcidev, - this_alloc, (void *) bufIn.kptr, dma_addr); - } - - this_alloc = sgSize * sizeof(MptSge_t); + /* Free the allocated memory. + */ + if (bufOut.kptr != NULL) { pci_free_consistent(ioc->pcidev, - this_alloc, (void *) sglbuf, sglbuf_dma); + bufOut.len, (void *) bufOut.kptr, dma_addr_out); + } + if (bufIn.kptr != NULL) { + pci_free_consistent(ioc->pcidev, + bufIn.len, (void *) bufIn.kptr, dma_addr_in); } - /* mf will be null if allocation failed OR - * if command completed OK (callback freed) + /* mf is null if command issued successfully + * otherwise, failure occured after mf acquired. */ if (mf) mpt_free_msg_frame(mptctl_id, ioc->id, mf); @@ -2405,7 +2407,7 @@ */ if (data_size == sizeof(hp_host_info_t)) cim_rev = 1; - else if (data_size == (sizeof(hp_host_info_t) + 12)) + else if (data_size == sizeof(hp_host_info_rev0_t)) cim_rev = 0; /* obsolete */ else return -EFAULT; @@ -2478,7 +2480,7 @@ cfg.dir = 0; /* read */ cfg.timeout = 10; - strlcpy(karg.serial_number, " ", sizeof(karg.serial_number)); + strncpy(karg.serial_number, " ", 24); if (mpt_config(ioc, &cfg) == 0) { if (cfg.hdr->PageLength > 0) { /* Issue the second config page request */ @@ -2489,9 +2491,10 @@ cfg.physAddr = buf_dma; if (mpt_config(ioc, &cfg) == 0) { ManufacturingPage0_t *pdata = (ManufacturingPage0_t *) pbuf; - if (strlen(pdata->BoardTracerNumber) > 1) - strlcpy(karg.serial_number, pdata->BoardTracerNumber, - sizeof(karg.serial_number)); + if (strlen(pdata->BoardTracerNumber) > 1) { + strncpy(karg.serial_number, pdata->BoardTracerNumber, 24); + karg.serial_number[24-1]='\0'; + } } pci_free_consistent(ioc->pcidev, hdr.PageLength * 4, pbuf, buf_dma); pbuf = NULL; @@ -2535,6 +2538,20 @@ } } + cfg.pageAddr = 0; + cfg.action = MPI_TOOLBOX_ISTWI_READ_WRITE_TOOL; + cfg.dir = MPI_TB_ISTWI_FLAGS_READ; + cfg.timeout = 10; + pbuf = pci_alloc_consistent(ioc->pcidev, 4, &buf_dma); + if (pbuf) { + cfg.physAddr = buf_dma; + if ((mpt_toolbox(ioc, &cfg)) == 0) { + karg.rsvd = *(u32 *)pbuf; + } + pci_free_consistent(ioc->pcidev, 4, pbuf, buf_dma); + pbuf = NULL; + } + /* Copy the data from kernel memory to user memory */ if (copy_to_user((char *)arg, &karg, @@ -2736,6 +2753,19 @@ * to ensure the structure contents is properly processed by mptctl. */ static int +compat_mptctl_ioctl(unsigned int fd, unsigned int cmd, + unsigned long arg, struct file *filp) +{ + int ret; + + lock_kernel(); + dctlprintk((KERN_INFO MYNAM "::compat_mptctl_ioctl() called\n")); + ret = mptctl_ioctl(filp->f_dentry->d_inode, filp, cmd, arg); + unlock_kernel(); + return ret; +} + +static int compat_mptfwxfer_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg, struct file *filp) { @@ -2875,30 +2905,30 @@ } #ifdef CONFIG_COMPAT - err = register_ioctl32_conversion(MPTIOCINFO, NULL); + err = register_ioctl32_conversion(MPTIOCINFO, compat_mptctl_ioctl); if (++where && err) goto out_fail; - err = register_ioctl32_conversion(MPTIOCINFO1, NULL); + err = register_ioctl32_conversion(MPTIOCINFO1, compat_mptctl_ioctl); if (++where && err) goto out_fail; - err = register_ioctl32_conversion(MPTTARGETINFO, NULL); + err = register_ioctl32_conversion(MPTTARGETINFO, compat_mptctl_ioctl); if (++where && err) goto out_fail; - err = register_ioctl32_conversion(MPTTEST, NULL); + err = register_ioctl32_conversion(MPTTEST, compat_mptctl_ioctl); if (++where && err) goto out_fail; - err = register_ioctl32_conversion(MPTEVENTQUERY, NULL); + err = register_ioctl32_conversion(MPTEVENTQUERY, compat_mptctl_ioctl); if (++where && err) goto out_fail; - err = register_ioctl32_conversion(MPTEVENTENABLE, NULL); + err = register_ioctl32_conversion(MPTEVENTENABLE, compat_mptctl_ioctl); if (++where && err) goto out_fail; - err = register_ioctl32_conversion(MPTEVENTREPORT, NULL); + err = register_ioctl32_conversion(MPTEVENTREPORT, compat_mptctl_ioctl); if (++where && err) goto out_fail; - err = register_ioctl32_conversion(MPTHARDRESET, NULL); + err = register_ioctl32_conversion(MPTHARDRESET, compat_mptctl_ioctl); if (++where && err) goto out_fail; err = register_ioctl32_conversion(MPTCOMMAND32, compat_mpt_command); if (++where && err) goto out_fail; err = register_ioctl32_conversion(MPTFWDOWNLOAD32, compat_mptfwxfer_ioctl); if (++where && err) goto out_fail; - err = register_ioctl32_conversion(HP_GETHOSTINFO, NULL); + err = register_ioctl32_conversion(HP_GETHOSTINFO, compat_mptctl_ioctl); if (++where && err) goto out_fail; - err = register_ioctl32_conversion(HP_GETTARGETINFO, NULL); + err = register_ioctl32_conversion(HP_GETTARGETINFO, compat_mptctl_ioctl); if (++where && err) goto out_fail; #endif diff -Nru a/drivers/message/fusion/mptctl.h b/drivers/message/fusion/mptctl.h --- a/drivers/message/fusion/mptctl.h Sun Mar 14 14:20:07 2004 +++ b/drivers/message/fusion/mptctl.h Sun Mar 14 14:20:07 2004 @@ -15,7 +15,7 @@ * * (see also mptbase.c) * - * Copyright (c) 1999-2003 LSI Logic Corporation + * Copyright (c) 1999-2004 LSI Logic Corporation * Originally By: Steven J. Ralston * (mailto:sjralston1@netscape.net) * (mailto:mpt_linux_developer@lsil.com) @@ -342,6 +342,7 @@ #define CPQFCTS_IOC_MAGIC 'Z' #define HP_IOC_MAGIC 'Z' #define HP_GETHOSTINFO _IOR(HP_IOC_MAGIC, 20, hp_host_info_t) +#define HP_GETHOSTINFO1 _IOR(HP_IOC_MAGIC, 20, hp_host_info_rev0_t) #define HP_GETTARGETINFO _IOR(HP_IOC_MAGIC, 21, hp_target_info_t) /* All HP IOCTLs must include this header @@ -357,7 +358,7 @@ /* * Header: * iocnum required (input) - * host ignored + * host ignored * channe ignored * id ignored * lun ignored @@ -371,9 +372,9 @@ u8 devfn; u8 bus; ushort host_no; /* SCSI Host number, if scsi driver not loaded*/ - u8 fw_version[16]; /* string */ + u8 fw_version[16]; /* string */ u8 serial_number[24]; /* string */ - u32 ioc_status; + u32 ioc_status; u32 bus_phys_width; u32 base_io_addr; u32 rsvd; @@ -382,10 +383,33 @@ unsigned int timeouts; /* num timeouts */ } hp_host_info_t; +/* replace ulongs with uints, need to preserve backwards + * compatibility. + */ +typedef struct _hp_host_info_rev0 { + hp_header_t hdr; + u16 vendor; + u16 device; + u16 subsystem_vendor; + u16 subsystem_id; + u8 devfn; + u8 bus; + ushort host_no; /* SCSI Host number, if scsi driver not loaded*/ + u8 fw_version[16]; /* string */ + u8 serial_number[24]; /* string */ + u32 ioc_status; + u32 bus_phys_width; + u32 base_io_addr; + u32 rsvd; + unsigned long hard_resets; /* driver initiated resets */ + unsigned long soft_resets; /* ioc, external resets */ + unsigned long timeouts; /* num timeouts */ +} hp_host_info_rev0_t; + /* * Header: * iocnum required (input) - * host required + * host required * channel required (bus number) * id required * lun ignored diff -Nru a/drivers/message/fusion/mptlan.c b/drivers/message/fusion/mptlan.c --- a/drivers/message/fusion/mptlan.c Sun Mar 14 14:20:07 2004 +++ b/drivers/message/fusion/mptlan.c Sun Mar 14 14:20:07 2004 @@ -23,7 +23,7 @@ * * (see also mptbase.c) * - * Copyright (c) 2000-2003 LSI Logic Corporation + * Copyright (c) 2000-2004 LSI Logic Corporation * Originally By: Noah Romer * (mailto:mpt_linux_developer@lsil.com) * @@ -337,15 +337,18 @@ mpt_lan_ioc_reset(MPT_ADAPTER *ioc, int reset_phase) { struct net_device *dev = mpt_landev[ioc->id]; - struct mpt_lan_priv *priv = (struct mpt_lan_priv *) dev->priv; + struct mpt_lan_priv *priv = netdev_priv(dev); dlprintk((KERN_INFO MYNAM ": IOC %s_reset routed to LAN driver!\n", - reset_phase==MPT_IOC_PRE_RESET ? "pre" : "post")); + reset_phase==MPT_IOC_SETUP_RESET ? "setup" : ( + reset_phase==MPT_IOC_PRE_RESET ? "pre" : "post"))); if (priv->mpt_rxfidx == NULL) return (1); - if (reset_phase == MPT_IOC_PRE_RESET) { + if (reset_phase == MPT_IOC_SETUP_RESET) { + ; + } else if (reset_phase == MPT_IOC_PRE_RESET) { int i; unsigned long flags; @@ -406,7 +409,7 @@ static int mpt_lan_open(struct net_device *dev) { - struct mpt_lan_priv *priv = (struct mpt_lan_priv *) dev->priv; + struct mpt_lan_priv *priv = netdev_priv(dev); int i; if (mpt_lan_reset(dev) != 0) { @@ -497,7 +500,7 @@ { MPT_FRAME_HDR *mf; LANResetRequest_t *pResetReq; - struct mpt_lan_priv *priv = (struct mpt_lan_priv *)dev->priv; + struct mpt_lan_priv *priv = netdev_priv(dev); mf = mpt_get_msg_frame(LanCtx, priv->mpt_dev->id); @@ -526,7 +529,7 @@ static int mpt_lan_close(struct net_device *dev) { - struct mpt_lan_priv *priv = (struct mpt_lan_priv *) dev->priv; + struct mpt_lan_priv *priv = netdev_priv(dev); MPT_ADAPTER *mpt_dev = priv->mpt_dev; unsigned int timeout; int i; @@ -587,7 +590,7 @@ static struct net_device_stats * mpt_lan_get_stats(struct net_device *dev) { - struct mpt_lan_priv *priv = (struct mpt_lan_priv *)dev->priv; + struct mpt_lan_priv *priv = netdev_priv(dev); return (struct net_device_stats *) &priv->stats; } @@ -607,7 +610,7 @@ static void mpt_lan_tx_timeout(struct net_device *dev) { - struct mpt_lan_priv *priv = (struct mpt_lan_priv *) dev->priv; + struct mpt_lan_priv *priv = netdev_priv(dev); MPT_ADAPTER *mpt_dev = priv->mpt_dev; if (mpt_dev->active) { @@ -621,7 +624,7 @@ static int mpt_lan_send_turbo(struct net_device *dev, u32 tmsg) { - struct mpt_lan_priv *priv = (struct mpt_lan_priv *) dev->priv; + struct mpt_lan_priv *priv = netdev_priv(dev); MPT_ADAPTER *mpt_dev = priv->mpt_dev; struct sk_buff *sent; unsigned long flags; @@ -654,7 +657,7 @@ static int mpt_lan_send_reply(struct net_device *dev, LANSendReply_t *pSendRep) { - struct mpt_lan_priv *priv = (struct mpt_lan_priv *) dev->priv; + struct mpt_lan_priv *priv = netdev_priv(dev); MPT_ADAPTER *mpt_dev = priv->mpt_dev; struct sk_buff *sent; unsigned long flags; @@ -727,7 +730,7 @@ static int mpt_lan_sdu_send (struct sk_buff *skb, struct net_device *dev) { - struct mpt_lan_priv *priv = (struct mpt_lan_priv *) dev->priv; + struct mpt_lan_priv *priv = netdev_priv(dev); MPT_ADAPTER *mpt_dev = priv->mpt_dev; MPT_FRAME_HDR *mf; LANSendRequest_t *pSendReq; @@ -955,11 +958,13 @@ return -ENOMEM; } - pci_dma_sync_single(mpt_dev->pcidev, priv->RcvCtl[ctx].dma, - priv->RcvCtl[ctx].len, PCI_DMA_FROMDEVICE); + pci_dma_sync_single_for_cpu(mpt_dev->pcidev, priv->RcvCtl[ctx].dma, + priv->RcvCtl[ctx].len, PCI_DMA_FROMDEVICE); memcpy(skb_put(skb, len), old_skb->data, len); + pci_dma_sync_single_for_device(mpt_dev->pcidev, priv->RcvCtl[ctx].dma, + priv->RcvCtl[ctx].len, PCI_DMA_FROMDEVICE); goto out; } @@ -1113,12 +1118,17 @@ // IOC_AND_NETDEV_NAMES_s_s(dev), // i, l)); - pci_dma_sync_single(mpt_dev->pcidev, - priv->RcvCtl[ctx].dma, - priv->RcvCtl[ctx].len, - PCI_DMA_FROMDEVICE); + pci_dma_sync_single_for_cpu(mpt_dev->pcidev, + priv->RcvCtl[ctx].dma, + priv->RcvCtl[ctx].len, + PCI_DMA_FROMDEVICE); memcpy(skb_put(skb, l), old_skb->data, l); + pci_dma_sync_single_for_device(mpt_dev->pcidev, + priv->RcvCtl[ctx].dma, + priv->RcvCtl[ctx].len, + PCI_DMA_FROMDEVICE); + priv->mpt_rxfidx[++priv->mpt_rxfidx_tail] = ctx; szrem -= l; } @@ -1136,11 +1146,18 @@ return -ENOMEM; } - pci_dma_sync_single(mpt_dev->pcidev, priv->RcvCtl[ctx].dma, - priv->RcvCtl[ctx].len, PCI_DMA_FROMDEVICE); + pci_dma_sync_single_for_cpu(mpt_dev->pcidev, + priv->RcvCtl[ctx].dma, + priv->RcvCtl[ctx].len, + PCI_DMA_FROMDEVICE); memcpy(skb_put(skb, len), old_skb->data, len); + pci_dma_sync_single_for_device(mpt_dev->pcidev, + priv->RcvCtl[ctx].dma, + priv->RcvCtl[ctx].len, + PCI_DMA_FROMDEVICE); + spin_lock_irqsave(&priv->rxfidx_lock, flags); priv->mpt_rxfidx[++priv->mpt_rxfidx_tail] = ctx; spin_unlock_irqrestore(&priv->rxfidx_lock, flags); @@ -1369,7 +1386,7 @@ dev->mtu = MPT_LAN_MTU; - priv = (struct mpt_lan_priv *) dev->priv; + priv = netdev_priv(dev); priv->mpt_dev = mpt_dev; priv->pnum = pnum; diff -Nru a/drivers/message/fusion/mptscsih.c b/drivers/message/fusion/mptscsih.c --- a/drivers/message/fusion/mptscsih.c Sun Mar 14 14:20:09 2004 +++ b/drivers/message/fusion/mptscsih.c Sun Mar 14 14:20:09 2004 @@ -21,7 +21,7 @@ * * (see mptbase.c) * - * Copyright (c) 1999-2003 LSI Logic Corporation + * Copyright (c) 1999-2004 LSI Logic Corporation * Original author: Steven J. Ralston * (mailto:sjralston1@netscape.net) * (mailto:mpt_linux_developer@lsil.com) @@ -165,17 +165,19 @@ static MPT_FRAME_HDR *mptscsih_search_pendingQ(MPT_SCSI_HOST *hd, int scpnt_idx); static void post_pendingQ_commands(MPT_SCSI_HOST *hd); -static int mptscsih_TMHandler(MPT_SCSI_HOST *hd, u8 type, u8 target, u8 lun, int ctx2abort, ulong timeout, int sleepFlag); -static int mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 target, u8 lun, int ctx2abort, ulong timeout, int sleepFlag); +static int mptscsih_TMHandler(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun, int ctx2abort, ulong timeout, int sleepFlag); +static int mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun, int ctx2abort, ulong timeout, int sleepFlag); static int mptscsih_ioc_reset(MPT_ADAPTER *ioc, int post_reset); static int mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply); -static void mptscsih_target_settings(MPT_SCSI_HOST *hd, VirtDevice *target, Scsi_Device *sdev); +static void mptscsih_initTarget(MPT_SCSI_HOST *hd, int bus_id, int target_id, u8 lun, char *data, int dlen); +void mptscsih_setTargetNegoParms(MPT_SCSI_HOST *hd, VirtDevice *target, char byte56); static void mptscsih_set_dvflags(MPT_SCSI_HOST *hd, SCSIIORequest_t *pReq); static void mptscsih_setDevicePage1Flags (u8 width, u8 factor, u8 offset, int *requestedPtr, int *configurationPtr, u8 flags); static void mptscsih_no_negotiate(MPT_SCSI_HOST *hd, int target_id); static int mptscsih_writeSDP1(MPT_SCSI_HOST *hd, int portnum, int target, int flags); +static int mptscsih_writeIOCPage4(MPT_SCSI_HOST *hd, int target_id, int bus); static int mptscsih_scandv_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *r); static void mptscsih_timer_expired(unsigned long data); static void mptscsih_taskmgmt_timeout(unsigned long data); @@ -190,7 +192,7 @@ static void mptscsih_domainValidation(void *hd); static int mptscsih_is_phys_disk(MPT_ADAPTER *ioc, int id); static void mptscsih_qas_check(MPT_SCSI_HOST *hd, int id); -static int mptscsih_doDv(MPT_SCSI_HOST *hd, int portnum, int target); +static int mptscsih_doDv(MPT_SCSI_HOST *hd, int channel, int target); static void mptscsih_dv_parms(MPT_SCSI_HOST *hd, DVPARAMETERS *dv,void *pPage); static void mptscsih_fillbuf(char *buffer, int size, int index, int width); #endif @@ -200,8 +202,8 @@ static int __init mptscsih_init (void); static void __exit mptscsih_exit (void); -static int __devinit mptscsih_probe (struct pci_dev *, const struct pci_device_id *); -static void __devexit mptscsih_remove(struct pci_dev *); +static int mptscsih_probe (struct pci_dev *, const struct pci_device_id *); +static void mptscsih_remove(struct pci_dev *); static void mptscsih_shutdown(struct device *); #ifdef CONFIG_PM static int mptscsih_suspend(struct pci_dev *pdev, u32 state); @@ -214,7 +216,6 @@ */ static int mpt_scsi_hosts = 0; -static atomic_t queue_depth; static int ScsiDoneCtx = -1; static int ScsiTaskCtx = -1; @@ -243,6 +244,10 @@ static struct mptscsih_driver_setup driver_setup = MPTSCSIH_DRIVER_SETUP; +#ifdef MPTSCSIH_DBG_TIMEOUT +static Scsi_Cmnd *foo_to[8]; +#endif + /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ /* see mptscsih.h */ @@ -438,10 +443,10 @@ static inline int mptscsih_getFreeChainBuffer(MPT_SCSI_HOST *hd, int *retIndex) { - MPT_FRAME_HDR *chainBuf = NULL; + MPT_FRAME_HDR *chainBuf; unsigned long flags; - int rc = FAILED; - int chain_idx = MPT_HOST_NO_CHAIN; + int rc; + int chain_idx; spin_lock_irqsave(&hd->ioc->FreeQlock, flags); if (!Q_IS_EMPTY(&hd->FreeChainQ)) { @@ -454,6 +459,10 @@ chain_idx = offset / hd->ioc->req_sz; rc = SUCCESS; } + else { + rc = FAILED; + chain_idx = MPT_HOST_NO_CHAIN; + } spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags); @@ -506,13 +515,12 @@ /* Map the data portion, if any. * sges_left = 0 if no data transfer. */ - sges_left = SCpnt->use_sg; - if (SCpnt->use_sg) { + if ( (sges_left = SCpnt->use_sg) ) { sges_left = pci_map_sg(hd->ioc->pcidev, (struct scatterlist *) SCpnt->request_buffer, SCpnt->use_sg, scsi_to_pci_dma_dir(SCpnt->sc_data_direction)); - if (sges_left == 0) + if (sges_left == 0) return FAILED; } else if (SCpnt->request_bufflen) { dma_addr_t buf_dma_addr; @@ -729,50 +737,67 @@ hd = (MPT_SCSI_HOST *) ioc->sh->hostdata; - if ((mf == NULL) || - (mf >= MPT_INDEX_2_MFPTR(ioc, ioc->req_depth))) { - printk(MYIOC_s_ERR_FMT "%s req frame ptr! (=%p)!\n", - ioc->name, mf?"BAD":"NULL", (void *) mf); - return 0; - } - req_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx); sc = hd->ScsiLookup[req_idx]; if (sc == NULL) { + MPIHeader_t *hdr = (MPIHeader_t *)mf; + /* Remark: writeSDP1 will use the ScsiDoneCtx * If a SCSI I/O cmd, device disabled by OS and * completion done. Cannot touch sc struct. Just free mem. */ - atomic_dec(&queue_depth); + if (hdr->Function == MPI_FUNCTION_SCSI_IO_REQUEST) + printk(MYIOC_s_ERR_FMT "NULL ScsiCmd ptr!\n", + ioc->name); mptscsih_freeChainBuffers(hd, req_idx); return 1; } - dmfprintk((MYIOC_s_INFO_FMT "ScsiDone (mf=%p,mr=%p,sc=%p,idx=%d)\n", - ioc->name, mf, mr, sc, req_idx)); - - atomic_dec(&queue_depth); + dmfprintk((MYIOC_s_INFO_FMT + "ScsiDone (mf=%p,mr=%p,sc=%p,idx=%d)\n", + ioc->name, mf, mr, sc, req_idx)); sc->result = DID_OK << 16; /* Set default reply as OK */ pScsiReq = (SCSIIORequest_t *) mf; pScsiReply = (SCSIIOReply_t *) mr; +#ifdef MPTSCSIH_DBG_TIMEOUT + if (ioc->timeout_cnt > 0) { + int ii, left = 0; + + for (ii=0; ii < 8; ii++) { + if (sc == foo_to[ii]) { + printk(MYIOC_s_INFO_FMT "complete (%p, %ld)\n", + ioc->name, sc, jiffies); + foo_to[ii] = NULL; + } + if (foo_to[ii] != NULL) + left++; + } + + if (left == 0) { + ioc->timeout_maxcnt = 0; + ioc->timeout_cnt = 0; + } + } +#endif + if (pScsiReply == NULL) { /* special context reply handling */ ; } else { u32 xfer_cnt; u16 status; - u8 scsi_state; + u8 scsi_state, scsi_status; status = le16_to_cpu(pScsiReply->IOCStatus) & MPI_IOCSTATUS_MASK; scsi_state = pScsiReply->SCSIState; - dsprintk((KERN_NOTICE " Uh-Oh! (%d:%d:%d) mf=%p, mr=%p, sc=%p\n", + dprintk((KERN_NOTICE " Uh-Oh! (%d:%d:%d) mf=%p, mr=%p, sc=%p\n", ioc->id, pScsiReq->TargetID, pScsiReq->LUN[1], mf, mr, sc)); - dsprintk((KERN_NOTICE " IOCStatus=%04xh, SCSIState=%02xh" + dprintk((KERN_NOTICE " IOCStatus=%04xh, SCSIState=%02xh" ", SCSIStatus=%02xh, IOCLogInfo=%08xh\n", status, scsi_state, pScsiReply->SCSIStatus, le32_to_cpu(pScsiReply->IOCLogInfo))); @@ -780,14 +805,6 @@ if (scsi_state & MPI_SCSI_STATE_AUTOSENSE_VALID) copy_sense_data(sc, hd, mf, pScsiReply); - /* - * Look for + dump FCP ResponseInfo[]! - */ - if (scsi_state & MPI_SCSI_STATE_RESPONSE_INFO_VALID) { - dprintk((KERN_NOTICE " FCP_ResponseInfo=%08xh\n", - le32_to_cpu(pScsiReply->ResponseInfo))); - } - switch(status) { case MPI_IOCSTATUS_BUSY: /* 0x0002 */ /* CHECKME! @@ -827,52 +844,45 @@ case MPI_IOCSTATUS_SCSI_RESIDUAL_MISMATCH: /* 0x0049 */ case MPI_IOCSTATUS_SCSI_DATA_UNDERRUN: /* 0x0045 */ /* - * YIKES! I just discovered that SCSI IO which - * returns check condition, SenseKey=05 (ILLEGAL REQUEST) - * and ASC/ASCQ=94/01 (LSI Logic RAID vendor specific), - * comes down this path! * Do upfront check for valid SenseData and give it * precedence! */ - sc->result = (DID_OK << 16) | pScsiReply->SCSIStatus; - if (scsi_state == 0) { - ; - } else if (scsi_state & MPI_SCSI_STATE_AUTOSENSE_VALID) { + scsi_status = pScsiReply->SCSIStatus; + sc->result = (DID_OK << 16) | scsi_status; + xfer_cnt = le32_to_cpu(pScsiReply->TransferCount); + if (scsi_state & MPI_SCSI_STATE_AUTOSENSE_VALID) { /* Have already saved the status and sense data */ ; - } else if (scsi_state & (MPI_SCSI_STATE_AUTOSENSE_FAILED | MPI_SCSI_STATE_NO_SCSI_STATUS)) { - /* What to do? - */ - sc->result = DID_SOFT_ERROR << 16; - } - else if (scsi_state & MPI_SCSI_STATE_TERMINATED) { - /* Not real sure here either... */ - sc->result = DID_RESET << 16; + } else { + if ( (xfer_cnt == 0) || (sc->underflow > xfer_cnt)) { + sc->result = DID_SOFT_ERROR << 16; + } + if (scsi_state & (MPI_SCSI_STATE_AUTOSENSE_FAILED | MPI_SCSI_STATE_NO_SCSI_STATUS)) { + /* What to do? + */ + sc->result = DID_SOFT_ERROR << 16; + } + else if (scsi_state & MPI_SCSI_STATE_TERMINATED) { + /* Not real sure here either... */ + sc->result = DID_RESET << 16; + } } /* Give report and update residual count. */ - xfer_cnt = le32_to_cpu(pScsiReply->TransferCount); dprintk((KERN_NOTICE " sc->underflow={report ERR if < %02xh bytes xfer'd}\n", sc->underflow)); dprintk((KERN_NOTICE " ActBytesXferd=%02xh\n", xfer_cnt)); sc->resid = sc->request_bufflen - xfer_cnt; dprintk((KERN_NOTICE " SET sc->resid=%02xh\n", sc->resid)); - - if(sc->underflow > xfer_cnt) { - printk(MYIOC_s_INFO_FMT - "SCSI data underrun: underflow=%02x, xfercnt=%02x\n", - ioc->name, sc->underflow, xfer_cnt); - sc->result = DID_SOFT_ERROR << 16; - } - + /* Report Queue Full */ - if (sc->result == MPI_SCSI_STATUS_TASK_SET_FULL) + if (scsi_status == MPI_SCSI_STATUS_TASK_SET_FULL) mptscsih_report_queue_full(sc, pScsiReply, pScsiReq); - + break; case MPI_IOCSTATUS_SCSI_RECOVERED_ERROR: /* 0x0040 */ @@ -965,9 +975,7 @@ hd->ScsiLookup[req_idx] = NULL; - MPT_HOST_LOCK(flags); sc->scsi_done(sc); /* Issue the command callback */ - MPT_HOST_UNLOCK(flags); /* Free Chain buffers */ mptscsih_freeChainBuffers(hd, req_idx); @@ -988,7 +996,7 @@ /* Flush the doneQ. */ - dprintk((KERN_INFO MYNAM ": flush_doneQ called\n")); + dtmprintk((KERN_INFO MYNAM ": flush_doneQ called\n")); while (1) { spin_lock_irqsave(&hd->freedoneQlock, flags); if (Q_IS_EMPTY(&hd->doneQ)) { @@ -1013,9 +1021,7 @@ /* Do the OS callback. */ - MPT_HOST_LOCK(flags); SCpnt->scsi_done(SCpnt); - MPT_HOST_UNLOCK(flags); } return; @@ -1055,6 +1061,26 @@ return; } +static void +mptscsih_reset_timeouts (MPT_SCSI_HOST *hd) +{ + Scsi_Cmnd *SCpnt; + int ii; + int max = hd->ioc->req_depth; + + + for (ii= 0; ii < max; ii++) { + if ((SCpnt = hd->ScsiLookup[ii]) != NULL) { + /* calling mod_timer() panics in 2.6 kernel... + * need to investigate + */ +// mod_timer(&SCpnt->eh_timeout, jiffies + (HZ * 60)); + dtmprintk((MYIOC_s_WARN_FMT "resetting SCpnt=%p timeout + 60HZ", + (hd && hd->ioc) ? hd->ioc->name : "ioc?", SCpnt)); + } + } +} + /* * mptscsih_flush_running_cmds - For each command found, search * Scsi_Host instance taskQ and reply to OS. @@ -1068,23 +1094,24 @@ static void mptscsih_flush_running_cmds(MPT_SCSI_HOST *hd) { - Scsi_Cmnd *SCpnt = NULL; - MPT_FRAME_HDR *mf = NULL; + Scsi_Cmnd *SCpnt; + MPT_FRAME_HDR *mf; + MPT_DONE_Q *buffer; int ii; int max = hd->ioc->req_depth; + unsigned long flags; dprintk((KERN_INFO MYNAM ": flush_ScsiLookup called\n")); for (ii= 0; ii < max; ii++) { if ((SCpnt = hd->ScsiLookup[ii]) != NULL) { /* Command found. - * - * Search pendingQ, if found, - * delete from Q. If found, do not decrement - * queue_depth, command never posted. */ - if (mptscsih_search_pendingQ(hd, ii) == NULL) - atomic_dec(&queue_depth); + + /* Search pendingQ, if found, + * delete from Q. + */ + mptscsih_search_pendingQ(hd, ii); /* Null ScsiLookup index */ @@ -1111,15 +1138,39 @@ } SCpnt->result = DID_RESET << 16; SCpnt->host_scribble = NULL; - MPT_HOST_LOCK(flags); - SCpnt->scsi_done(SCpnt); /* Issue the command callback */ - MPT_HOST_UNLOCK(flags); /* Free Chain buffers */ mptscsih_freeChainBuffers(hd, ii); /* Free Message frames */ mpt_free_msg_frame(ScsiDoneCtx, hd->ioc->id, mf); + +#if 1 + /* Post to doneQ, do not reply until POST phase + * of reset handler....prevents new commands from + * being queued. + */ + spin_lock_irqsave(&hd->freedoneQlock, flags); + if (!Q_IS_EMPTY(&hd->freeQ)) { + buffer = hd->freeQ.head; + Q_DEL_ITEM(buffer); + + /* Set the Scsi_Cmnd pointer + */ + buffer->argp = (void *)SCpnt; + + /* Add to the doneQ + */ + Q_ADD_TAIL(&hd->doneQ.head, buffer, MPT_DONE_Q); + spin_unlock_irqrestore(&hd->freedoneQlock, flags); + } else { + spin_unlock_irqrestore(&hd->freedoneQlock, flags); + SCpnt->scsi_done(SCpnt); + } +#else + SCpnt->scsi_done(SCpnt); /* Issue the command callback */ +#endif + } } @@ -1147,8 +1198,8 @@ int ii; int max = hd->ioc->req_depth; - dsprintk((KERN_INFO MYNAM ": search_running target %d lun %d max %d numIos %d\n", - target, lun, max, atomic_read(&queue_depth))); + dsprintk((KERN_INFO MYNAM ": search_running target %d lun %d max %d\n", + target, lun, max)); for (ii=0; ii < max; ii++) { if (hd->ScsiLookup[ii] != NULL) { @@ -1161,11 +1212,6 @@ if ((mf->TargetID != ((u8)target)) || (mf->LUN[1] != ((u8) lun))) continue; - /* If cmd pended, do not decrement queue_depth, command never posted. - */ - if (mptscsih_search_pendingQ(hd, ii) == NULL) - atomic_dec(&queue_depth); - /* Cleanup */ hd->ScsiLookup[ii] = NULL; @@ -1177,73 +1223,6 @@ return; } -#ifdef DROP_TEST -/* mptscsih_flush_drop_test - Free resources and do callback if - * DROP_TEST enabled. - * - * @hd: Pointer to a SCSI HOST structure - * - * Returns: None. - * - * Must be called while new I/Os are being queued. - */ -static void -mptscsih_flush_drop_test (MPT_SCSI_HOST *hd) -{ - Scsi_Cmnd *sc; - unsigned long flags; - u16 req_idx; - - /* Free resources for the drop test MF - * and chain buffers. - */ - if (dropMfPtr) { - req_idx = le16_to_cpu(dropMfPtr->u.frame.hwhdr.msgctxu.fld.req_idx); - sc = hd->ScsiLookup[req_idx]; - if (sc == NULL) { - printk(MYIOC_s_ERR_FMT "Drop Test: NULL ScsiCmd ptr!\n", - ioc->name); - } else { - /* unmap OS resources, set status, do callback - * free driver resources - */ - if (sc->use_sg) { - pci_unmap_sg(ioc->pcidev, (struct scatterlist *) sc->request_buffer, - sc->use_sg, scsi_to_pci_dma_dir(sc->sc_data_direction)); - } else if (sc->request_bufflen) { - scPrivate *my_priv; - - my_priv = (scPrivate *) &sc->SCp; - pci_unmap_single(ioc->pcidev, (dma_addr_t)(ulong)my_priv->p1, - sc->request_bufflen, - scsi_to_pci_dma_dir(sc->sc_data_direction)); - } - - sc->host_scribble = NULL; - sc->result = DID_RESET << 16; - hd->ScsiLookup[req_idx] = NULL; - atomic_dec(&queue_depth); - MPT_HOST_LOCK(flags); - sc->scsi_done(sc); /* Issue callback */ - MPT_HOST_UNLOCK(flags); - } - - mptscsih_freeChainBuffers(hd, req_idx); - mpt_free_msg_frame(ScsiDoneCtx, ioc->id, dropMfPtr); - printk(MYIOC_s_INFO_FMT "Free'd Dropped cmd (%p)\n", - hd->ioc->name, sc); - printk(MYIOC_s_INFO_FMT "mf (%p) reqidx (%4x)\n", - hd->ioc->name, dropMfPtr, req_idx); - printk(MYIOC_s_INFO_FMT "Num Tot (%d) Good (%d) Bad (%d) \n", - hd->ioc->name, dropTestNum, - dropTestOK, dropTestBad); - } - dropMfPtr = NULL; - - return; -} -#endif - /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ /* * mptscsih_initChainBuffers - Allocate memory for and initialize @@ -1263,18 +1242,15 @@ /* ReqToChain size must equal the req_depth * index = req_idx */ - sz = hd->ioc->req_depth * sizeof(int); if (hd->ReqToChain == NULL) { + sz = hd->ioc->req_depth * sizeof(int); mem = kmalloc(sz, GFP_ATOMIC); if (mem == NULL) return -1; hd->ReqToChain = (int *) mem; - } else { - mem = (u8 *) hd->ReqToChain; } -/* memset(mem, 0xFF, sz); */ - for(ii=0;iiioc->req_depth;ii++) + for (ii = 0; ii < hd->ioc->req_depth; ii++) hd->ReqToChain[ii] = MPT_HOST_NO_CHAIN; /* ChainToChain size must equal the total number @@ -1322,7 +1298,11 @@ if (hd->ChainBuffer == NULL) { /* Allocate free chain buffer pool */ +#if defined(MPTBASE_MEM_ALLOC_FIFO_FIX) + mem = pci_alloc_consistent(&hd->ioc->pcidev32, sz, &hd->ChainBufferDMA); +#else mem = pci_alloc_consistent(hd->ioc->pcidev, sz, &hd->ChainBufferDMA); +#endif if (mem == NULL) return -1; @@ -1405,310 +1385,333 @@ * */ -static int __devinit +static int mptscsih_probe(struct pci_dev *pdev, const struct pci_device_id *id) { - struct Scsi_Host *sh = NULL; - MPT_SCSI_HOST *hd = NULL; + struct Scsi_Host *sh; + MPT_SCSI_HOST *hd; MPT_ADAPTER *ioc = pci_get_drvdata(pdev); - int portnum; MPT_DONE_Q *freedoneQ; unsigned long flags; int sz, ii; int numSGE = 0; int scale; + int ioc_cap; u8 *mem; int error=0; - for (portnum=0; portnum < ioc->facts.NumberOfPorts; portnum++) { - /* 20010215 -sralston - * Added sanity check on SCSI Initiator-mode enabled - * for this MPT adapter. - */ - if (!(ioc->pfacts[portnum].ProtocolFlags & - MPI_PORTFACTS_PROTOCOL_INITIATOR)) { - printk(MYIOC_s_WARN_FMT - "Skipping because SCSI Initiator mode is NOT enabled!\n", - ioc->name); - continue; - } - - /* 20010202 -sralston - * Added sanity check on readiness of the MPT adapter. - */ - if (ioc->last_state != MPI_IOC_STATE_OPERATIONAL) { - printk(MYIOC_s_WARN_FMT - "Skipping because it's not operational!\n", - ioc->name); - continue; - } - - sh = scsi_host_alloc(&driver_template, sizeof(MPT_SCSI_HOST)); - if (sh != NULL) { - spin_lock_irqsave(&ioc->FreeQlock, flags); - - /* Attach the SCSI Host to the IOC structure - */ - ioc->sh = sh; - - sh->io_port = 0; - sh->n_io_port = 0; - sh->irq = 0; - - /* set 16 byte cdb's */ - sh->max_cmd_len = 16; - - /* Yikes! This is important! - * Otherwise, by default, linux - * only scans target IDs 0-7! - * pfactsN->MaxDevices unreliable - * (not supported in early - * versions of the FW). - * max_id = 1 + actual max id, - * max_lun = 1 + actual last lun, - * see hosts.h :o( - */ - if ((int)ioc->chip_type > (int)FC929) { - sh->max_id = MPT_MAX_SCSI_DEVICES; - } else { - /* For FC, increase the queue depth - * from MPT_SCSI_CAN_QUEUE (31) - * to MPT_FC_CAN_QUEUE (63). - */ - sh->can_queue = MPT_FC_CAN_QUEUE; - sh->max_id = - MPT_MAX_FC_DEVICES<256 ? MPT_MAX_FC_DEVICES : 255; - } - - sh->max_lun = MPT_LAST_LUN + 1; - sh->max_sectors = MPT_SCSI_MAX_SECTORS; - sh->this_id = ioc->pfacts[portnum].PortSCSIID; - - /* Required entry. - */ - sh->unique_id = ioc->id; - - /* Verify that we won't exceed the maximum - * number of chain buffers - * We can optimize: ZZ = req_sz/sizeof(SGE) - * For 32bit SGE's: - * numSGE = 1 + (ZZ-1)*(maxChain -1) + ZZ - * + (req_sz - 64)/sizeof(SGE) - * A slightly different algorithm is required for - * 64bit SGEs. - */ - scale = ioc->req_sz/(sizeof(dma_addr_t) + sizeof(u32)); - if (sizeof(dma_addr_t) == sizeof(u64)) { - numSGE = (scale - 1) * - (ioc->facts.MaxChainDepth-1) + scale + - (ioc->req_sz - 60) / (sizeof(dma_addr_t) + - sizeof(u32)); - } else { - numSGE = 1 + (scale - 1) * - (ioc->facts.MaxChainDepth-1) + scale + - (ioc->req_sz - 64) / (sizeof(dma_addr_t) + - sizeof(u32)); - } - - if (numSGE < sh->sg_tablesize) { - /* Reset this value */ - dprintk((MYIOC_s_INFO_FMT - "Resetting sg_tablesize to %d from %d\n", - ioc->name, numSGE, sh->sg_tablesize)); - sh->sg_tablesize = numSGE; - } - - /* Set the pci device pointer in Scsi_Host structure. - */ - scsi_set_device(sh, &ioc->pcidev->dev); - - spin_unlock_irqrestore(&ioc->FreeQlock, flags); - - hd = (MPT_SCSI_HOST *) sh->hostdata; - hd->ioc = ioc; - hd->max_sge = sh->sg_tablesize; - - if ((int)ioc->chip_type > (int)FC929) - hd->is_spi = 1; + /* 20010202 -sralston + * Added sanity check on readiness of the MPT adapter. + */ + if (ioc->last_state != MPI_IOC_STATE_OPERATIONAL) { + printk(MYIOC_s_WARN_FMT + "Skipping because it's not operational!\n", + ioc->name); + return -ENODEV; + } - if (DmpService && (ioc->chip_type == FC919 || - ioc->chip_type == FC929)) { - hd->is_multipath = 1; - } - hd->port = 0; /* FIXME! */ + if (!ioc->active) { + printk(MYIOC_s_WARN_FMT "Skipping because it's disabled!\n", + ioc->name); + return -ENODEV; + } - /* SCSI needs Scsi_Cmnd lookup table! - * (with size equal to req_depth*PtrSz!) - */ - sz = hd->ioc->req_depth * sizeof(void *); - mem = kmalloc(sz, GFP_ATOMIC); - if (mem == NULL) { - error = -ENOMEM; - goto mptscsih_probe_failed; - } + /* Sanity check - ensure at least 1 port is INITIATOR capable + */ + ioc_cap = 0; + for (ii=0; ii < ioc->facts.NumberOfPorts; ii++) { + if (ioc->pfacts[ii].ProtocolFlags & + MPI_PORTFACTS_PROTOCOL_INITIATOR) + ioc_cap ++; + } - memset(mem, 0, sz); - hd->ScsiLookup = (struct scsi_cmnd **) mem; + if (!ioc_cap) { + printk(MYIOC_s_WARN_FMT + "Skipping ioc=%p because SCSI Initiator mode is NOT enabled!\n", + ioc->name, ioc); + return -ENODEV; + } - dprintk((MYIOC_s_INFO_FMT "ScsiLookup @ %p, sz=%d\n", - ioc->name, hd->ScsiLookup, sz)); + sh = scsi_host_alloc(&driver_template, sizeof(MPT_SCSI_HOST)); + + if (!sh) { + printk(MYIOC_s_WARN_FMT + "Unable to register controller with SCSI subsystem\n", + ioc->name); + return -1; + } + + spin_lock_irqsave(&ioc->FreeQlock, flags); - if (mptscsih_initChainBuffers(hd, 1) < 0) { - error = -EINVAL; - goto mptscsih_probe_failed; - } + /* Attach the SCSI Host to the IOC structure + */ + ioc->sh = sh; - /* Allocate memory for free and doneQ's - */ - sz = sh->can_queue * sizeof(MPT_DONE_Q); - mem = kmalloc(sz, GFP_ATOMIC); - if (mem == NULL) { - error = -ENOMEM; - goto mptscsih_probe_failed; - } + sh->io_port = 0; + sh->n_io_port = 0; + sh->irq = 0; + + /* set 16 byte cdb's */ + sh->max_cmd_len = 16; + + /* Yikes! This is important! + * Otherwise, by default, linux + * only scans target IDs 0-7! + * pfactsN->MaxDevices unreliable + * (not supported in early + * versions of the FW). + * max_id = 1 + actual max id, + * max_lun = 1 + actual last lun, + * see hosts.h :o( + */ + if ((int)ioc->chip_type > (int)FC929) { + sh->max_id = MPT_MAX_SCSI_DEVICES; + } else { + /* For FC, increase the queue depth + * from MPT_SCSI_CAN_QUEUE (31) + * to MPT_FC_CAN_QUEUE (63). + */ + sh->can_queue = MPT_FC_CAN_QUEUE; + sh->max_id = + MPT_MAX_FC_DEVICES<256 ? MPT_MAX_FC_DEVICES : 255; + } + + sh->max_lun = MPT_LAST_LUN + 1; + sh->max_sectors = MPT_SCSI_MAX_SECTORS; + sh->max_channel = 0; + sh->this_id = ioc->pfacts[0].PortSCSIID; + + /* Required entry. + */ + sh->unique_id = ioc->id; + + /* Verify that we won't exceed the maximum + * number of chain buffers + * We can optimize: ZZ = req_sz/sizeof(SGE) + * For 32bit SGE's: + * numSGE = 1 + (ZZ-1)*(maxChain -1) + ZZ + * + (req_sz - 64)/sizeof(SGE) + * A slightly different algorithm is required for + * 64bit SGEs. + */ + scale = ioc->req_sz/(sizeof(dma_addr_t) + sizeof(u32)); + if (sizeof(dma_addr_t) == sizeof(u64)) { + numSGE = (scale - 1) * + (ioc->facts.MaxChainDepth-1) + scale + + (ioc->req_sz - 60) / (sizeof(dma_addr_t) + + sizeof(u32)); + } else { + numSGE = 1 + (scale - 1) * + (ioc->facts.MaxChainDepth-1) + scale + + (ioc->req_sz - 64) / (sizeof(dma_addr_t) + + sizeof(u32)); + } + + if (numSGE < sh->sg_tablesize) { + /* Reset this value */ + dprintk((MYIOC_s_INFO_FMT + "Resetting sg_tablesize to %d from %d\n", + ioc->name, numSGE, sh->sg_tablesize)); + sh->sg_tablesize = numSGE; + } - memset(mem, 0xFF, sz); - hd->memQ = mem; + /* Set the pci device pointer in Scsi_Host structure. + */ + scsi_set_device(sh, &ioc->pcidev->dev); - /* Initialize the free, done and pending Qs. - */ - Q_INIT(&hd->freeQ, MPT_DONE_Q); - Q_INIT(&hd->doneQ, MPT_DONE_Q); - Q_INIT(&hd->pendingQ, MPT_DONE_Q); - spin_lock_init(&hd->freedoneQlock); - - mem = hd->memQ; - for (ii=0; ii < sh->can_queue; ii++) { - freedoneQ = (MPT_DONE_Q *) mem; - Q_ADD_TAIL(&hd->freeQ.head, freedoneQ, MPT_DONE_Q); - mem += sizeof(MPT_DONE_Q); - } + spin_unlock_irqrestore(&ioc->FreeQlock, flags); - /* Initialize this Scsi_Host - * internal task Q. - */ - Q_INIT(&hd->taskQ, MPT_FRAME_HDR); - hd->taskQcnt = 0; + hd = (MPT_SCSI_HOST *) sh->hostdata; + hd->ioc = ioc; + hd->max_sge = sh->sg_tablesize; + + if ((int)ioc->chip_type > (int)FC929) + hd->is_spi = 1; + + if (DmpService && (ioc->chip_type == FC919 || + ioc->chip_type == FC929)) { + hd->is_multipath = 1; + } + + /* SCSI needs Scsi_Cmnd lookup table! + * (with size equal to req_depth*PtrSz!) + */ + sz = hd->ioc->req_depth * sizeof(void *); + mem = kmalloc(sz, GFP_ATOMIC); + if (mem == NULL) { + error = -ENOMEM; + goto mptscsih_probe_failed; + } - /* Allocate memory for the device structures. - * A non-Null pointer at an offset - * indicates a device exists. - * max_id = 1 + maximum id (hosts.h) - */ - sz = sh->max_id * sizeof(void *); - mem = kmalloc(sz, GFP_ATOMIC); - if (mem == NULL) { - error = -ENOMEM; - goto mptscsih_probe_failed; - } + memset(mem, 0, sz); + hd->ScsiLookup = (struct scsi_cmnd **) mem; - memset(mem, 0, sz); - hd->Targets = (VirtDevice **) mem; + dprintk((MYIOC_s_INFO_FMT "ScsiLookup @ %p, sz=%d\n", + ioc->name, hd->ScsiLookup, sz)); + + if (mptscsih_initChainBuffers(hd, 1) < 0) { + error = -EINVAL; + goto mptscsih_probe_failed; + } + + /* Allocate memory for free and doneQ's + */ + sz = sh->can_queue * sizeof(MPT_DONE_Q); + mem = kmalloc(sz, GFP_ATOMIC); + if (mem == NULL) { + error = -ENOMEM; + goto mptscsih_probe_failed; + } - dprintk((KERN_INFO - " Targets @ %p, sz=%d\n", hd->Targets, sz)); + memset(mem, 0xFF, sz); + hd->memQ = mem; + /* Initialize the free, done and pending Qs. + */ + Q_INIT(&hd->freeQ, MPT_DONE_Q); + Q_INIT(&hd->doneQ, MPT_DONE_Q); + Q_INIT(&hd->pendingQ, MPT_DONE_Q); + spin_lock_init(&hd->freedoneQlock); + + mem = hd->memQ; + for (ii=0; ii < sh->can_queue; ii++) { + freedoneQ = (MPT_DONE_Q *) mem; + Q_ADD_TAIL(&hd->freeQ.head, freedoneQ, MPT_DONE_Q); + mem += sizeof(MPT_DONE_Q); + } + + /* Initialize this Scsi_Host + * internal task Q. + */ + Q_INIT(&hd->taskQ, MPT_FRAME_HDR); + hd->taskQcnt = 0; + + /* Allocate memory for the device structures. + * A non-Null pointer at an offset + * indicates a device exists. + * max_id = 1 + maximum id (hosts.h) + */ + sz = sh->max_id * sizeof(void *); + mem = kmalloc(sz, GFP_ATOMIC); + if (mem == NULL) { + error = -ENOMEM; + goto mptscsih_probe_failed; + } - /* Clear the TM flags - */ - hd->tmPending = 0; - hd->tmState = TM_STATE_NONE; - hd->resetPending = 0; - hd->abortSCpnt = NULL; - hd->tmPtr = NULL; - hd->numTMrequests = 0; + memset(mem, 0, sz); + hd->Targets = (VirtDevice **) mem; - /* Clear the pointer used to store - * single-threaded commands, i.e., those - * issued during a bus scan, dv and - * configuration pages. - */ - hd->cmdPtr = NULL; + dprintk((KERN_INFO + " Targets @ %p, sz=%d\n", hd->Targets, sz)); - /* Initialize this SCSI Hosts' timers - * To use, set the timer expires field - * and add_timer - */ - init_timer(&hd->timer); - hd->timer.data = (unsigned long) hd; - hd->timer.function = mptscsih_timer_expired; - - init_timer(&hd->TMtimer); - hd->TMtimer.data = (unsigned long) hd; - hd->TMtimer.function = mptscsih_taskmgmt_timeout; - hd->qtag_tick = jiffies; + /* Clear the TM flags + */ + hd->tmPending = 0; + hd->tmState = TM_STATE_NONE; + hd->resetPending = 0; + hd->abortSCpnt = NULL; + hd->tmPtr = NULL; + hd->numTMrequests = 0; + + /* Clear the pointer used to store + * single-threaded commands, i.e., those + * issued during a bus scan, dv and + * configuration pages. + */ + hd->cmdPtr = NULL; - /* Moved Earlier Pam D */ - /* ioc->sh = sh; */ + /* Initialize this SCSI Hosts' timers + * To use, set the timer expires field + * and add_timer + */ + init_timer(&hd->timer); + hd->timer.data = (unsigned long) hd; + hd->timer.function = mptscsih_timer_expired; + + init_timer(&hd->TMtimer); + hd->TMtimer.data = (unsigned long) hd; + hd->TMtimer.function = mptscsih_taskmgmt_timeout; + hd->qtag_tick = jiffies; + + /* Moved Earlier Pam D */ + /* ioc->sh = sh; */ + +#ifdef MPTSCSIH_DBG_TIMEOUT + hd->ioc->timeout_hard = 0; + hd->ioc->timeout_delta = 30 * HZ; + hd->ioc->timeout_maxcnt = 0; + hd->ioc->timeout_cnt = 0; + for (ii=0; ii < 8; ii++) + foo_to[ii] = NULL; +#endif + if (hd->is_spi) { + /* Update with the driver setup + * values. + */ + if (hd->ioc->spi_data.maxBusWidth > + driver_setup.max_width) { + hd->ioc->spi_data.maxBusWidth = + driver_setup.max_width; + } - if (hd->is_spi) { - /* Update with the driver setup - * values. - */ - if (hd->ioc->spi_data.maxBusWidth > - driver_setup.max_width) { - hd->ioc->spi_data.maxBusWidth = - driver_setup.max_width; - } + if (hd->ioc->spi_data.minSyncFactor < + driver_setup.min_sync_fac) { + hd->ioc->spi_data.minSyncFactor = + driver_setup.min_sync_fac; + } - if (hd->ioc->spi_data.minSyncFactor < - driver_setup.min_sync_fac) { - hd->ioc->spi_data.minSyncFactor = - driver_setup.min_sync_fac; - } + if (hd->ioc->spi_data.minSyncFactor == MPT_ASYNC) { + hd->ioc->spi_data.maxSyncOffset = 0; + } - if (hd->ioc->spi_data.minSyncFactor == MPT_ASYNC) { - hd->ioc->spi_data.maxSyncOffset = 0; - } + hd->ioc->spi_data.Saf_Te = driver_setup.saf_te; - hd->negoNvram = 0; + hd->negoNvram = 0; #ifndef MPTSCSIH_ENABLE_DOMAIN_VALIDATION - hd->negoNvram = MPT_SCSICFG_USE_NVRAM; + hd->negoNvram = MPT_SCSICFG_USE_NVRAM; #endif - if (driver_setup.dv == 0) { - hd->negoNvram = MPT_SCSICFG_USE_NVRAM; - } - - hd->ioc->spi_data.forceDv = 0; - for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) { - hd->ioc->spi_data.dvStatus[ii] = - MPT_SCSICFG_NEGOTIATE; - } - - if (hd->negoNvram == 0) { - for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) - hd->ioc->spi_data.dvStatus[ii] |= - MPT_SCSICFG_DV_NOT_DONE; - } + if (driver_setup.dv == 0) { + hd->negoNvram = MPT_SCSICFG_USE_NVRAM; + } - ddvprintk((MYIOC_s_INFO_FMT - "dv %x width %x factor %x \n", - hd->ioc->name, driver_setup.dv, - driver_setup.max_width, - driver_setup.min_sync_fac)); + hd->ioc->spi_data.forceDv = 0; + for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) { + hd->ioc->spi_data.dvStatus[ii] = + MPT_SCSICFG_NEGOTIATE; + } - } + if (hd->negoNvram == 0) { + for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) + hd->ioc->spi_data.dvStatus[ii] |= + MPT_SCSICFG_DV_NOT_DONE; + } - mpt_scsi_hosts++; + ddvprintk((MYIOC_s_INFO_FMT + "dv %x width %x factor %x saf_te %x\n", + hd->ioc->name, driver_setup.dv, + driver_setup.max_width, + driver_setup.min_sync_fac, + driver_setup.saf_te)); + } - error = scsi_add_host (sh, &ioc->pcidev->dev); - if(error) { - dprintk((KERN_ERR MYNAM, - "scsi_add_host failed\n")); - goto mptscsih_probe_failed; - } + mpt_scsi_hosts++; - scsi_scan_host(sh); - return 0; - } /* scsi_host_alloc */ + error = scsi_add_host (sh, &ioc->pcidev->dev); + if(error) { + dprintk((KERN_ERR MYNAM + "scsi_add_host failed\n")); + goto mptscsih_probe_failed; + } - } /* for each adapter port */ + scsi_scan_host(sh); + return 0; mptscsih_probe_failed: mptscsih_remove(pdev); return error; + } /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ @@ -1718,7 +1721,7 @@ * * */ -static void __devexit +static void mptscsih_remove(struct pci_dev *pdev) { MPT_ADAPTER *ioc = pci_get_drvdata(pdev); @@ -1920,7 +1923,7 @@ static struct mpt_pci_driver mptscsih_driver = { .probe = mptscsih_probe, - .remove = __devexit_p(mptscsih_remove), + .remove = mptscsih_remove, .shutdown = mptscsih_shutdown, #ifdef CONFIG_PM .suspend = mptscsih_suspend, @@ -2023,7 +2026,7 @@ const char * mptscsih_info(struct Scsi_Host *SChost) { - MPT_SCSI_HOST *h = NULL; + MPT_SCSI_HOST *h; int size = 0; if (info_kbuf == NULL) @@ -2099,101 +2102,20 @@ return ((info.pos > info.offset) ? info.pos - info.offset : 0); } -struct mptscsih_usrcmd { - ulong target; - ulong lun; - ulong data; - ulong cmd; -}; - -#define UC_GET_SPEED 0x10 - -static void mptscsih_exec_user_cmd(MPT_ADAPTER *ioc, struct mptscsih_usrcmd *uc) +#ifndef MPTSCSIH_DBG_TIMEOUT +static int mptscsih_user_command(MPT_ADAPTER *ioc, char *pbuf, int len) { - CONFIGPARMS cfg; - dma_addr_t cfg_dma_addr = -1; - ConfigPageHeader_t header; - - dprintk(("exec_user_command: ioc %p cmd %ld target=%ld\n", - ioc, uc->cmd, uc->target)); - - switch (uc->cmd) { - case UC_GET_SPEED: - { - SCSIDevicePage0_t *pData = NULL; - - if (ioc->spi_data.sdp0length == 0) - return; - - pData = (SCSIDevicePage0_t *)pci_alloc_consistent(ioc->pcidev, - ioc->spi_data.sdp0length * 4, &cfg_dma_addr); - - if (pData == NULL) - return; - - header.PageVersion = ioc->spi_data.sdp0version; - header.PageLength = ioc->spi_data.sdp0length; - header.PageNumber = 0; - header.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE; - - cfg.hdr = &header; - cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT; - cfg.dir = 0; - cfg.pageAddr = (u32) uc->target; /* bus << 8 | target */ - cfg.physAddr = cfg_dma_addr; - - if (mpt_config(ioc, &cfg) == 0) { - u32 np = le32_to_cpu(pData->NegotiatedParameters); - u32 tmp = np & MPI_SCSIDEVPAGE0_NP_WIDE; - - printk("Target %d: %s;", - (u32) uc->target, - tmp ? "Wide" : "Narrow"); - - tmp = np & MPI_SCSIDEVPAGE0_NP_NEG_SYNC_OFFSET_MASK; - if (tmp) { - u32 speed = 0; - printk(" Synchronous"); - tmp = (tmp >> 16); - printk(" (Offset=0x%x", tmp); - tmp = np & MPI_SCSIDEVPAGE0_NP_NEG_SYNC_PERIOD_MASK; - tmp = (tmp >> 8); - printk(" Factor=0x%x)", tmp); - if (tmp <= MPT_ULTRA320) - speed=160; - else if (tmp <= MPT_ULTRA160) - speed=80; - else if (tmp <= MPT_ULTRA2) - speed=40; - else if (tmp <= MPT_ULTRA) - speed=20; - else if (tmp <= MPT_FAST) - speed=10; - else if (tmp <= MPT_SCSI) - speed=5; - - if (np & MPI_SCSIDEVPAGE0_NP_WIDE) - speed*=2; - - printk(" %dMB/sec\n", speed); - - } else - printk(" Asynchronous.\n"); - } else { - printk("failed\n" ); - } - - pci_free_consistent(ioc->pcidev, ioc->spi_data.sdp0length * 4, - pData, cfg_dma_addr); - } - break; - } + /* Not yet implemented */ + return len; } - +#else #define is_digit(c) ((c) >= '0' && (c) <= '9') #define digit_to_bin(c) ((c) - '0') #define is_space(c) ((c) == ' ' || (c) == '\t') +#define UC_DBG_TIMEOUT 0x01 +#define UC_DBG_HARDRESET 0x02 + static int skip_spaces(char *ptr, int len) { int cnt, c; @@ -2242,50 +2164,66 @@ static int mptscsih_user_command(MPT_ADAPTER *ioc, char *buffer, int length) { - char *ptr = buffer; - struct mptscsih_usrcmd cmd, *uc = &cmd; - ulong target; - int arg_len; - int len = length; + char *ptr = buffer; + char btmp[24]; /* REMOVE */ + int arg_len; + int len = length; + int cmd; + ulong number = 1; + ulong delta = 10; - uc->target = uc->cmd = uc->lun = uc->data = 0; - if ((len > 0) && (ptr[len -1] == '\n')) --len; - if ((arg_len = is_keyword(ptr, len, "getspeed")) != 0) - uc->cmd = UC_GET_SPEED; - else - arg_len = 0; - - dprintk(("user_command: arg_len=%d, cmd=%ld\n", arg_len, uc->cmd)); + if (len < 22) { + strncpy(btmp, buffer, len); + btmp[len+1]='\0'; + } else { + strncpy(btmp, buffer, 22); + btmp[23]='\0'; + } + printk("user_command: ioc %d, buffer %s, length %d\n", + ioc->id, btmp, length); - if (!arg_len) + if ((arg_len = is_keyword(ptr, len, "timeout")) != 0) + cmd = UC_DBG_TIMEOUT; + else if ((arg_len = is_keyword(ptr, len, "hardreset")) != 0) + cmd = UC_DBG_HARDRESET; + else return -EINVAL; ptr += arg_len; len -= arg_len; - switch(uc->cmd) { - case UC_GET_SPEED: + switch(cmd) { + case UC_DBG_TIMEOUT: SKIP_SPACES(1); - GET_INT_ARG(target); - uc->target = target; + GET_INT_ARG(number); + SKIP_SPACES(1); + GET_INT_ARG(delta); break; } - dprintk(("user_command: target=%ld len=%d\n", uc->target, len)); + printk("user_command: cnt=%ld delta=%ld\n", number, delta); if (len) return -EINVAL; else { - /* process this command ... - */ - mptscsih_exec_user_cmd(ioc, uc); + if (cmd == UC_DBG_HARDRESET) { + ioc->timeout_hard = 1; + } else if (cmd == UC_DBG_TIMEOUT) { + /* process this command ... + */ + ioc->timeout_maxcnt = 0; + ioc->timeout_delta = delta < 2 ? 2 : delta; + ioc->timeout_cnt = 0; + ioc->timeout_maxcnt = number < 8 ? number: 8; + } } /* Not yet implemented */ return length; } +#endif /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ /** @@ -2303,7 +2241,7 @@ int mptscsih_proc_info(struct Scsi_Host *host, char *buffer, char **start, off_t offset, int length, int func) { - MPT_ADAPTER *ioc = NULL; + MPT_ADAPTER *ioc; MPT_SCSI_HOST *hd = NULL; int size = 0; @@ -2334,49 +2272,8 @@ /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ - static int max_qd = 1; #define ADD_INDEX_LOG(req_ent) do { } while(0) -#ifdef DROP_TEST -#define DROP_IOC 1 /* IOC to force failures */ -#define DROP_TARGET 3 /* Target ID to force failures */ -#define DROP_THIS_CMD 10000 /* iteration to drop command */ -static int dropCounter = 0; -static int dropTestOK = 0; /* num did good */ -static int dropTestBad = 0; /* num did bad */ -static int dropTestNum = 0; /* total = good + bad + incomplete */ -static int numTotCmds = 0; -static MPT_FRAME_HDR *dropMfPtr = NULL; -static int numTMrequested = 0; -#endif - -/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ -/* - * mptscsih_put_msgframe - Wrapper routine to post message frame to F/W. - * @context: Call back context (ScsiDoneCtx, ScsiScanDvCtx) - * @id: IOC id number - * @mf: Pointer to message frame - * - * Handles the call to mptbase for posting request and queue depth - * tracking. - * - * Returns none. - */ -static inline void -mptscsih_put_msgframe(int context, int id, MPT_FRAME_HDR *mf) -{ - /* Main banana... */ - atomic_inc(&queue_depth); - if (atomic_read(&queue_depth) > max_qd) { - max_qd = atomic_read(&queue_depth); - dprintk((KERN_INFO MYNAM ": Queue depth now %d.\n", max_qd)); - } - - mpt_put_msg_frame(context, id, mf); - - return; -} - /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ /** * mptscsih_qcmd - Primary Fusion MPT SCSI initiator IO start routine. @@ -2396,7 +2293,7 @@ MPT_FRAME_HDR *mf; SCSIIORequest_t *pScsiReq; VirtDevice *pTarget; - MPT_DONE_Q *buffer = NULL; + MPT_DONE_Q *buffer; unsigned long flags; int target; int lun; @@ -2424,9 +2321,14 @@ if (hd->resetPending) { /* Prevent new commands from being issued - * while reloading the FW. + * while reloading the FW. Reset timer to 60 seconds, + * as the FW can take some time to come ready. + * For New EH, cmds on doneQ posted to FW. */ did_errcode = 1; + mod_timer(&SCpnt->eh_timeout, jiffies + (HZ * 60)); + dtmprintk((MYIOC_s_WARN_FMT "qcmd: SCpnt=%p timeout + 60HZ\n", + (hd && hd->ioc) ? hd->ioc->name : "ioc?", SCpnt)); goto did_error; } @@ -2481,8 +2383,8 @@ /* Use the above information to set up the message frame */ - pScsiReq->TargetID = target; - pScsiReq->Bus = hd->port; + pScsiReq->TargetID = (u8) target; + pScsiReq->Bus = (u8) SCpnt->device->channel; pScsiReq->ChainOffset = 0; pScsiReq->Function = MPI_FUNCTION_SCSI_IO_REQUEST; pScsiReq->CDBLength = SCpnt->cmd_len; @@ -2501,12 +2403,14 @@ /* * Write SCSI CDB into the message - * Should write from cmd_len up to 16, but skip for performance reasons. */ cmd_len = SCpnt->cmd_len; for (ii=0; ii < cmd_len; ii++) pScsiReq->CDB[ii] = SCpnt->cmnd[ii]; + for (ii=cmd_len; ii < 16; ii++) + pScsiReq->CDB[ii] = 0; + /* DataLength */ pScsiReq->DataLength = cpu_to_le32(datalen); @@ -2532,39 +2436,6 @@ hd->ScsiLookup[my_idx] = SCpnt; SCpnt->host_scribble = NULL; -#ifdef DROP_TEST - numTotCmds++; - /* If the IOC number and target match, increment - * counter. If counter matches DROP_THIS, do not - * issue command to FW to force a reset. - * Save the MF pointer so we can free resources - * when task mgmt completes. - */ - if ((hd->ioc->id == DROP_IOC) && (target == DROP_TARGET)) { - dropCounter++; - - if (dropCounter == DROP_THIS_CMD) { - dropCounter = 0; - - /* If global is set, then we are already - * doing something - so keep issuing commands. - */ - if (dropMfPtr == NULL) { - dropTestNum++; - dropMfPtr = mf; - atomic_inc(&queue_depth); - printk(MYIOC_s_INFO_FMT - "Dropped SCSI cmd (%p)\n", - hd->ioc->name, SCpnt); - printk("mf (%p) req (%4x) tot cmds (%d)\n", - mf, my_idx, numTotCmds); - - return 0; - } - } - } -#endif - /* SCSI specific processing */ issueCmd = 1; if (hd->is_spi) { @@ -2617,8 +2488,20 @@ } } +#ifdef MPTSCSIH_DBG_TIMEOUT + if (hd->ioc->timeout_cnt < hd->ioc->timeout_maxcnt) { + foo_to[hd->ioc->timeout_cnt] = SCpnt; + hd->ioc->timeout_cnt++; + //mod_timer(&SCpnt->eh_timeout, jiffies + hd->ioc->timeout_delta); + issueCmd = 0; + printk(MYIOC_s_WARN_FMT + "to pendingQ: (sc=%p, mf=%p, time=%ld)\n", + hd->ioc->name, SCpnt, mf, jiffies); + } +#endif + if (issueCmd) { - mptscsih_put_msgframe(ScsiDoneCtx, hd->ioc->id, mf); + mpt_put_msg_frame(ScsiDoneCtx, hd->ioc->id, mf); dmfprintk((MYIOC_s_INFO_FMT "Issued SCSI cmd (%p) mf=%p idx=%d\n", hd->ioc->name, SCpnt, mf, my_idx)); } else { @@ -2660,6 +2543,8 @@ SCpnt->result = (DID_BUS_BUSY << 16); spin_lock_irqsave(&hd->freedoneQlock, flags); if (!Q_IS_EMPTY(&hd->freeQ)) { + dtmprintk((MYIOC_s_WARN_FMT "SCpnt=%p to doneQ\n", + (hd && hd->ioc) ? hd->ioc->name : "ioc?", SCpnt)); buffer = hd->freeQ.head; Q_DEL_ITEM(buffer); @@ -2692,7 +2577,7 @@ static void mptscsih_freeChainBuffers(MPT_SCSI_HOST *hd, int req_idx) { - MPT_FRAME_HDR *chain = NULL; + MPT_FRAME_HDR *chain; unsigned long flags; int chain_idx; int next; @@ -2755,9 +2640,9 @@ * Returns 0 for SUCCESS or -1 if FAILED. */ static int -mptscsih_TMHandler(MPT_SCSI_HOST *hd, u8 type, u8 target, u8 lun, int ctx2abort, ulong timeout, int sleepFlag) +mptscsih_TMHandler(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun, int ctx2abort, ulong timeout, int sleepFlag) { - MPT_ADAPTER *ioc = NULL; + MPT_ADAPTER *ioc; int rc = -1; int doTask = 1; u32 ioc_raw_state; @@ -2770,19 +2655,18 @@ return 0; ioc = hd->ioc; - dtmprintk((MYIOC_s_INFO_FMT "TMHandler Entered!\n", ioc->name)); - if (ioc == NULL) { printk(KERN_ERR MYNAM " TMHandler" " NULL ioc!\n"); - return 0; + return FAILED; } + dtmprintk((MYIOC_s_INFO_FMT "TMHandler Entered!\n", ioc->name)); // SJR - CHECKME - Can we avoid this here? // (mpt_HardResetHandler has this check...) spin_lock_irqsave(&ioc->diagLock, flags); if ((ioc->diagPending) || (ioc->alt_ioc && ioc->alt_ioc->diagPending)) { spin_unlock_irqrestore(&ioc->diagLock, flags); - return 0; + return FAILED; } spin_unlock_irqrestore(&ioc->diagLock, flags); @@ -2792,6 +2676,37 @@ if (hd->numTMrequests > MPT_HOST_TOO_MANY_TM) doTask = 0; + /* Wait a fixed amount of time for the TM pending flag to be cleared. + * If we time out and not bus reset, then we return a FAILED status to the caller. + * The call to mptscsih_tm_pending_wait() will set the pending flag if we are + * successful. Otherwise, reload the FW. + */ + if (mptscsih_tm_pending_wait(hd) == FAILED) { + if (type == MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK) { + dtmprintk((KERN_WARNING MYNAM ": %s: TMHandler abort: " + "Timed out waiting for last TM (%d) to complete! \n", + hd->ioc->name, hd->tmPending)); + return FAILED; + } else if (type == MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET) { + dtmprintk((KERN_WARNING MYNAM ": %s: TMHandler target reset: " + "Timed out waiting for last TM (%d) to complete! \n", + hd->ioc->name, hd->tmPending)); + return FAILED; + } else if (type == MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS) { + dtmprintk((KERN_WARNING MYNAM ": %s: TMHandler bus reset: " + "Timed out waiting for last TM (%d) to complete! \n", + hd->ioc->name, hd->tmPending)); + if (hd->tmPending & (1 << MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS)) + return FAILED; + + doTask = 0; + } + } else { + spin_lock_irqsave(&hd->ioc->FreeQlock, flags); + hd->tmPending |= (1 << type); + spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags); + } + /* Is operational? */ ioc_raw_state = mpt_GetIocState(hd->ioc, 0); @@ -2799,7 +2714,7 @@ #ifdef MPT_DEBUG_RESET if ((ioc_raw_state & MPI_IOC_STATE_MASK) != MPI_IOC_STATE_OPERATIONAL) { printk(MYIOC_s_WARN_FMT - "TM Handler: IOC Not operational! state 0x%x Calling HardResetHandler\n", + "TM Handler: IOC Not operational(0x%x)!\n", hd->ioc->name, ioc_raw_state); } #endif @@ -2811,23 +2726,24 @@ */ if (hd->hard_resets < -1) hd->hard_resets++; - rc = mptscsih_IssueTaskMgmt(hd, type, target, lun, ctx2abort, timeout, sleepFlag); + rc = mptscsih_IssueTaskMgmt(hd, type, channel, target, lun, ctx2abort, timeout, sleepFlag); if (rc) { printk(MYIOC_s_INFO_FMT "Issue of TaskMgmt failed!\n", hd->ioc->name); } else { dtmprintk((MYIOC_s_INFO_FMT "Issue of TaskMgmt Successful!\n", hd->ioc->name)); } } -#ifdef DROP_TEST - numTMrequested++; - if (numTMrequested > 5) { - rc = 0; /* set to 1 to force a hard reset */ - numTMrequested = 0; - } + +#ifdef MPTSCSIH_DBG_TIMEOUT + if (hd->ioc->timeout_hard) + rc = 1; #endif - if (rc || ioc->reload_fw || (ioc->alt_ioc && ioc->alt_ioc->reload_fw)) { - dtmprintk((MYIOC_s_INFO_FMT "Falling through to HardReset! \n", + /* Only fall through to the HRH if this is a bus reset + */ + if ((type == MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS) && (rc || + ioc->reload_fw || (ioc->alt_ioc && ioc->alt_ioc->reload_fw))) { + dtmprintk((MYIOC_s_INFO_FMT "Calling HardReset! \n", hd->ioc->name)); rc = mpt_HardResetHandler(hd->ioc, sleepFlag); } @@ -2857,7 +2773,7 @@ * else other non-zero value returned. */ static int -mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 target, u8 lun, int ctx2abort, ulong timeout, int sleepFlag) +mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun, int ctx2abort, ulong timeout, int sleepFlag) { MPT_FRAME_HDR *mf; SCSITaskMgmt_t *pScsiTm; @@ -2879,7 +2795,7 @@ */ pScsiTm = (SCSITaskMgmt_t *) mf; pScsiTm->TargetID = target; - pScsiTm->Bus = hd->port; + pScsiTm->Bus = channel; pScsiTm->ChainOffset = 0; pScsiTm->Function = MPI_FUNCTION_SCSI_TASK_MGMT; @@ -2953,8 +2869,11 @@ return FAILED; } - printk(KERN_WARNING MYNAM ": %s: >> Attempting task abort! (sc=%p, numIOs=%d)\n", - hd->ioc->name, SCpnt, atomic_read(&queue_depth)); + if (hd->resetPending) + return FAILED; + + printk(KERN_WARNING MYNAM ": %s: >> Attempting task abort! (sc=%p)\n", + hd->ioc->name, SCpnt); if (hd->timeouts < -1) hd->timeouts++; @@ -2968,38 +2887,21 @@ search_doneQ_for_cmd(hd, SCpnt); SCpnt->result = DID_RESET << 16; - SCpnt->scsi_done(SCpnt); dtmprintk((KERN_WARNING MYNAM ": %s: mptscsih_abort: " "Command not in the active list! (sc=%p)\n", hd->ioc->name, SCpnt)); return SUCCESS; } - /* Wait a fixed amount of time for the TM pending flag to be cleared. - * If we time out, then we return a FAILED status to the caller. This - * call to mptscsih_tm_pending_wait() will set the pending flag if we are - * successful. - */ - spin_unlock_irq(host_lock); - if (mptscsih_tm_pending_wait(hd) == FAILED){ - dtmprintk((KERN_WARNING MYNAM ": %s: mptscsih_abort: " - "Timed out waiting for previous TM to complete! " - "(sc = %p)\n", - hd->ioc->name, SCpnt)); - spin_lock_irq(host_lock); - return FAILED; - } - spin_lock_irq(host_lock); - /* If this command is pended, then timeout/hang occurred * during DV. Post command and flush pending Q * and then following up with the reset request. */ if ((mf = mptscsih_search_pendingQ(hd, scpnt_idx)) != NULL) { - mptscsih_put_msgframe(ScsiDoneCtx, hd->ioc->id, mf); + mpt_put_msg_frame(ScsiDoneCtx, hd->ioc->id, mf); post_pendingQ_commands(hd); dtmprintk((KERN_WARNING MYNAM ": %s: mptscsih_abort: " - "Found command in pending queue! (sc=%p)\n", + "Posting pended cmd! (sc=%p)\n", hd->ioc->name, SCpnt)); } @@ -3017,7 +2919,7 @@ spin_unlock_irq(host_lock); if (mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK, - SCpnt->device->id, SCpnt->device->lun, + SCpnt->device->channel, SCpnt->device->id, SCpnt->device->lun, ctx2abort, (HZ*2) /* 2 second timeout */,CAN_SLEEP) < 0) { @@ -3064,31 +2966,21 @@ return FAILED; } - printk(KERN_WARNING MYNAM ": %s: >> Attempting target reset! (sc=%p, numIOs=%d)\n", - hd->ioc->name, SCpnt, atomic_read(&queue_depth)); + if (hd->resetPending) + return FAILED; - /* Unsupported for SCSI. Suppored for FCP + printk(KERN_WARNING MYNAM ": %s: >> Attempting target reset! (sc=%p)\n", + hd->ioc->name, SCpnt); + + /* Unsupported for SCSI. Supported for FCP */ if (hd->is_spi) return FAILED; - /* Wait a fixed amount of time for the TM pending flag to be cleared. - * If we time out, then we return a FAILED status to the caller. This - * call to mptscsih_tm_pending_wait() will set the pending flag if we are - * successful. - */ spin_unlock_irq(host_lock); - if (mptscsih_tm_pending_wait(hd) == FAILED) { - dtmprintk((KERN_WARNING MYNAM ": %s: mptscsih_dev_reset: " - "Timed out waiting for previous TM to complete! " - "(sc = %p)\n", - hd->ioc->name, SCpnt)); - spin_lock_irq(host_lock); - return FAILED; - } - if (mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET, - SCpnt->device->id, 0, 0, (HZ*5) /* 5 second timeout */, CAN_SLEEP) + SCpnt->device->channel, SCpnt->device->id, + 0, 0, (HZ*5) /* 5 second timeout */, CAN_SLEEP) < 0){ /* The TM request failed and the subsequent FW-reload failed! * Fatal error case. @@ -3129,30 +3021,19 @@ return FAILED; } - printk(KERN_WARNING MYNAM ": %s: >> Attempting bus reset! (sc=%p, numIOs=%d)\n", - hd->ioc->name, SCpnt, atomic_read(&queue_depth)); + printk(KERN_WARNING MYNAM ": %s: >> Attempting bus reset! (sc=%p)\n", + hd->ioc->name, SCpnt); if (hd->timeouts < -1) hd->timeouts++; - /* Wait a fixed amount of time for the TM pending flag to be cleared. - * If we time out, then we return a FAILED status to the caller. This - * call to mptscsih_tm_pending_wait() will set the pending flag if we are - * successful. - */ - spin_unlock_irq(host_lock); - if (mptscsih_tm_pending_wait(hd) == FAILED) { - dtmprintk((KERN_WARNING MYNAM ": %s: mptscsih_bus_reset: " - "Timed out waiting for previous TM to complete! " - "(sc = %p)\n", - hd->ioc->name, SCpnt)); - spin_lock_irq(host_lock); - return FAILED; - } - /* We are now ready to execute the task management request. */ + spin_unlock_irq(host_lock); +// printk("testing start : mptscsih_schedule_reset\n"); +// mptscsih_schedule_reset(hd); +// printk("testing end: mptscsih_schedule_reset\n"); if (mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS, - 0, 0, 0, (HZ*5) /* 5 second timeout */, CAN_SLEEP) + SCpnt->device->channel, 0, 0, 0, (HZ*5) /* 5 second timeout */, CAN_SLEEP) < 0){ /* The TM request failed and the subsequent FW-reload failed! @@ -3197,8 +3078,6 @@ printk(KERN_WARNING MYNAM ": %s: >> Attempting host reset! (sc=%p)\n", hd->ioc->name, SCpnt); - printk(KERN_WARNING MYNAM ": %s: IOs outstanding = %d\n", - hd->ioc->name, atomic_read(&queue_depth)); /* If our attempts to reset the host failed, then return a failed * status. The host will be taken off line by the SCSI mid-layer. @@ -3274,7 +3153,7 @@ { SCSITaskMgmtReply_t *pScsiTmReply; SCSITaskMgmt_t *pScsiTmReq; - MPT_SCSI_HOST *hd = NULL; + MPT_SCSI_HOST *hd; unsigned long flags; u8 tmType = 0; @@ -3325,10 +3204,7 @@ */ if (tmType == MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK) hd->abortSCpnt = NULL; -#ifdef DROP_TEST - if (dropMfPtr) - dropTestBad++; -#endif + /* If an internal command is present * or the TM failed - reload the FW. * FC FW may respond FAILED to an ABORT @@ -3349,17 +3225,9 @@ hd->abortSCpnt = NULL; flush_doneQ(hd); -#ifdef DROP_TEST - if (dropMfPtr) - dropTestOK++; -#endif } } -#ifdef DROP_TEST - mptscsih_flush_drop_test(hd); -#endif - hd->tmPtr = NULL; spin_lock_irqsave(&ioc->FreeQlock, flags); hd->tmPending = 0; @@ -3438,15 +3306,14 @@ hd = (MPT_SCSI_HOST *)host->hostdata; - if (hd == NULL) - return ENODEV; + return -ENODEV; if ((vdev = hd->Targets[device->id]) == NULL) { if ((vdev = kmalloc(sizeof(VirtDevice), GFP_ATOMIC)) == NULL) { printk(MYIOC_s_ERR_FMT "slave_alloc kmalloc(%d) FAILED!\n", - hd->ioc->name, (int)sizeof(VirtDevice)); - return ENOMEM; + hd->ioc->name, (int)sizeof(VirtDevice)); + return -ENOMEM; } else { memset(vdev, 0, sizeof(VirtDevice)); rwlock_init(&vdev->VdevLock); @@ -3476,9 +3343,10 @@ struct Scsi_Host *host = device->host; MPT_SCSI_HOST *hd; VirtDevice *vdev; + int raid_volume=0; hd = (MPT_SCSI_HOST *)host->hostdata; - + if (hd == NULL) return; @@ -3489,8 +3357,8 @@ if ((vdev = hd->Targets[device->id]) != NULL) { vdev->num_luns--; - if (vdev->luns & (1 << device->lun)) - vdev->luns &= ~(1 << device->lun); + if (vdev->luns[0] & (1 << device->lun)) + vdev->luns[0] &= ~(1 << device->lun); /* Free device structure only if number of luns is 0. */ @@ -3498,21 +3366,33 @@ kfree(hd->Targets[device->id]); hd->Targets[device->id] = NULL; - if (hd->is_spi) { - hd->ioc->spi_data.dvStatus[device->id] = MPT_SCSICFG_NEGOTIATE; + if (!hd->is_spi) + return; - if (hd->negoNvram == 0) - hd->ioc->spi_data.dvStatus[device->id] |= MPT_SCSICFG_DV_NOT_DONE; + if((hd->ioc->spi_data.isRaid) && (hd->ioc->spi_data.pIocPg3)) { + int i; + for(i=0;iioc->spi_data.pIocPg3->NumPhysDisks && + raid_volume==0;i++) + + if(device->id == + hd->ioc->spi_data.pIocPg3->PhysDisk[i].PhysDiskNum) { + raid_volume=1; + hd->ioc->spi_data.forceDv |= + MPT_SCSICFG_RELOAD_IOC_PG3; + } + } - /* Don't alter isRaid, not allowed to move - * volumes on a running system. - */ - if (hd->ioc->spi_data.isRaid & (1 << (device->id))) - hd->ioc->spi_data.forceDv |= MPT_SCSICFG_RELOAD_IOC_PG3; + if(!raid_volume){ + hd->ioc->spi_data.dvStatus[device->id] = + MPT_SCSICFG_NEGOTIATE; + + if (hd->negoNvram == 0) + hd->ioc->spi_data.dvStatus[device->id] + |= MPT_SCSICFG_DV_NOT_DONE; } } } - + return; } @@ -3525,205 +3405,76 @@ int mptscsih_slave_configure(Scsi_Device *device) { - struct Scsi_Host *host = device->host; - VirtDevice *vdev; - MPT_SCSI_HOST *hd; - - hd = (MPT_SCSI_HOST *)host->hostdata; - - dsprintk((KERN_INFO "slave_configure: device @ %p, id=%d, LUN=%d, channel=%d\n", - 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 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)) { - vdev = hd->Targets[device->id]; - - if (vdev && !(vdev->tflags & MPT_TARGET_FLAGS_CONFIGURED)) { - /* Configure only the first discovered LUN - */ - vdev->raidVolume = 0; - if (hd->is_spi && (hd->ioc->spi_data.isRaid & (1 << (device->id)))) { - vdev->raidVolume = 1; - ddvtprintk((KERN_INFO "RAID Volume @ id %d\n", device->id)); - } - - mptscsih_target_settings(hd, vdev, device); + struct Scsi_Host *sh = device->host; + VirtDevice *pTarget; + MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)sh->hostdata; - vdev->tflags |= MPT_TARGET_FLAGS_CONFIGURED; - } + if ((hd == NULL) || (hd->Targets == NULL)) { + return 0; + } - if (vdev) { - /* set the queue depth for all devices - */ - if (!device->tagged_supported || - !(vdev->tflags & MPT_TARGET_FLAGS_Q_YES)) { + dsprintk((MYIOC_s_INFO_FMT + "device @ %p, id=%d, LUN=%d, channel=%d\n", + hd->ioc->name, device, device->id, device->lun, device->channel)); + dsprintk((MYIOC_s_INFO_FMT + "sdtr %d wdtr %d ppr %d inq length=%d\n", + hd->ioc->name, device->sdtr, device->wdtr, + device->ppr, device->inquiry_len)); + + if (device->id > sh->max_id) { + /* error case, should never happen */ + scsi_adjust_queue_depth(device, 0, 1); + goto slave_configure_exit; + } + + pTarget = hd->Targets[device->id]; + + if (pTarget == NULL) { + /* error case - don't know about this device */ + scsi_adjust_queue_depth(device, 0, 1); + goto slave_configure_exit; + } + + mptscsih_initTarget(hd, device->channel, device->id, device->lun, + device->inquiry, device->inquiry_len ); + scsi_adjust_queue_depth(device, MSG_SIMPLE_TAG, + MPT_SCSI_CMD_PER_DEV_HIGH); + if ( hd->is_spi ) { + if (pTarget->tflags & MPT_TARGET_FLAGS_VALID_INQUIRY) { + if (!(pTarget->tflags & MPT_TARGET_FLAGS_Q_YES)) scsi_adjust_queue_depth(device, 0, 1); - } else if (vdev->type == 0x00 - && (vdev->minSyncFactor <= MPT_ULTRA160 || !hd->is_spi)) { + else if (((pTarget->inq_data[0] & 0x1f) == 0x00) + && (pTarget->minSyncFactor <= MPT_ULTRA160 )) scsi_adjust_queue_depth(device, MSG_SIMPLE_TAG, - MPT_SCSI_CMD_PER_DEV_HIGH); - } else { + MPT_SCSI_CMD_PER_DEV_HIGH); + else scsi_adjust_queue_depth(device, MSG_SIMPLE_TAG, - MPT_SCSI_CMD_PER_DEV_LOW); - } - - vdev->luns |= (1 << device->lun); - vdev->tflags |= MPT_TARGET_FLAGS_CONFIGURED; - } - } - return 0; -} -/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ -/* - * Update the target negotiation parameters based on the - * the Inquiry data, adapter capabilities, and NVRAM settings. - * - */ -static void -mptscsih_target_settings(MPT_SCSI_HOST *hd, VirtDevice *target, Scsi_Device *sdev) -{ - ScsiCfgData *pspi_data = &hd->ioc->spi_data; - int id = (int) target->target_id; - int nvram; - u8 width = MPT_NARROW; - u8 factor = MPT_ASYNC; - u8 offset = 0; - u8 nfactor; - u8 noQas = 1; - - ddvtprintk((KERN_INFO "set Target: (id %d) \n", id)); - - if (!hd->is_spi) { - /* FC - only care about QTag support - */ - if (sdev->tagged_supported) - target->tflags |= MPT_TARGET_FLAGS_Q_YES; - return; - } - - /* SCSI - Set flags based on Inquiry data - */ - if (sdev->scsi_level < 2) { - width = 0; - factor = MPT_ULTRA2; - offset = pspi_data->maxSyncOffset; - } else { - width = sdev->wdtr; - if (sdev->sdtr) { - if (sdev->ppr) { - /* U320 requires IU capability */ - if ((sdev->inquiry_len > 56) && (sdev->inquiry[56] & 0x01)) - factor = MPT_ULTRA320; - else - factor = MPT_ULTRA160; - } else - factor = MPT_ULTRA2; - - /* If RAID, never disable QAS - * else if non RAID, do not disable - * QAS if bit 1 is set - * bit 1 QAS support, non-raid only - * bit 0 IU support - */ - if ((target->raidVolume == 1) || - ((sdev->inquiry_len > 56) && (sdev->inquiry[56] & 0x02))) - noQas = 0; - - offset = pspi_data->maxSyncOffset; - + MPT_SCSI_CMD_PER_DEV_LOW); } else { - factor = MPT_ASYNC; - offset = 0; + /* error case - No Inq. Data */ + scsi_adjust_queue_depth(device, 0, 1); } } - /* Update tflags based on NVRAM settings. (SCSI only) - */ - if (pspi_data->nvram && (pspi_data->nvram[id] != MPT_HOST_NVRAM_INVALID)) { - nvram = pspi_data->nvram[id]; - nfactor = (nvram & MPT_NVRAM_SYNC_MASK) >> 8; - - if (width) - width = nvram & MPT_NVRAM_WIDE_DISABLE ? 0 : 1; - - if (offset > 0) { - /* Ensure factor is set to the - * maximum of: adapter, nvram, inquiry - */ - if (nfactor) { - if (nfactor < pspi_data->minSyncFactor ) - nfactor = pspi_data->minSyncFactor; - - factor = MAX (factor, nfactor); - if (factor == MPT_ASYNC) - offset = 0; - } else { - offset = 0; - factor = MPT_ASYNC; - } - } else - factor = MPT_ASYNC; - } - - /* Make sure data is consistent - */ - if ((!width) && (factor < MPT_ULTRA2)) - factor = MPT_ULTRA2; - - /* Save the data to the target structure. - */ - target->minSyncFactor = factor; - target->maxOffset = offset; - target->maxWidth = width; - if (sdev->tagged_supported) - target->tflags |= MPT_TARGET_FLAGS_Q_YES; - - /* Disable unused features. - */ - target->negoFlags = pspi_data->noQas; - if (!width) - target->negoFlags |= MPT_TARGET_NO_NEGO_WIDE; - - if (!offset) - target->negoFlags |= MPT_TARGET_NO_NEGO_SYNC; + dsprintk((MYIOC_s_INFO_FMT + "Queue depth=%d, tflags=%x\n", + hd->ioc->name, device->queue_depth, pTarget->tflags)); - if (noQas) - target->negoFlags |= MPT_TARGET_NO_NEGO_QAS; + dsprintk((MYIOC_s_INFO_FMT + "negoFlags=%x, maxOffset=%x, SyncFactor=%x\n", + hd->ioc->name, pTarget->negoFlags, pTarget->maxOffset, pTarget->minSyncFactor)); - /* GEM, processor WORKAROUND - */ - target->type = sdev->inquiry[0] & 0x1F; - if ((target->type == 0x03) || (target->type > 0x08)){ - target->negoFlags |= (MPT_TARGET_NO_NEGO_WIDE | MPT_TARGET_NO_NEGO_SYNC); - pspi_data->dvStatus[id] |= MPT_SCSICFG_BLK_NEGO; - } +slave_configure_exit: - /* Disable QAS if mixed configuration case - */ - if ((noQas) && (!pspi_data->noQas) && (target->type == 0x00)){ - VirtDevice *vdev; - int ii; + dsprintk((MYIOC_s_INFO_FMT + "tagged %d, simple %d, ordered %d\n", + hd->ioc->name,device->tagged_supported, device->simple_tags, + device->ordered_tags)); - ddvtprintk((KERN_INFO "Disabling QAS!\n")); - pspi_data->noQas = MPT_TARGET_NO_NEGO_QAS; - for (ii = 0; ii < id; ii++) { - vdev = hd->Targets[id]; - if (vdev != NULL) - vdev->negoFlags |= MPT_TARGET_NO_NEGO_QAS; - } - } - - ddvtprintk((KERN_INFO "Final settings id %d: dvstatus 0x%x\n", sdev->id, pspi_data->dvStatus[id])); - ddvtprintk(("wide %d, factor 0x%x offset 0x%x neg flags 0x%x flags 0x%x\n", - width, factor, offset, target->negoFlags, target->tflags)); - - return; + return 0; } + /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ /* * Private routines... @@ -3789,11 +3540,10 @@ thisIo.SCSIStatus = pScsiReply->SCSIStatus; thisIo.DoDisplay = 1; if (hd->is_multipath) - sprintf(devFoo, "%d:%d:%d \"%s\"", + sprintf(devFoo, "%d:%d:%d", hd->ioc->id, pReq->TargetID, - pReq->LUN[1], - target->dev_vol_name); + pReq->LUN[1]); else sprintf(devFoo, "%d:%d:%d", hd->ioc->id, sc->device->id, sc->device->lun); thisIo.DevIDStr = devFoo; @@ -3842,7 +3592,7 @@ unsigned long flags; MPT_DONE_Q *buffer; MPT_FRAME_HDR *mf = NULL; - MPT_FRAME_HDR *cmdMfPtr = NULL; + MPT_FRAME_HDR *cmdMfPtr; ddvtprintk((MYIOC_s_INFO_FMT ": search_pendingQ ...", hd->ioc->name)); cmdMfPtr = MPT_INDEX_2_MFPTR(hd->ioc, scpnt_idx); @@ -3911,7 +3661,7 @@ continue; } - mptscsih_put_msgframe(ScsiDoneCtx, hd->ioc->id, mf); + mpt_put_msg_frame(ScsiDoneCtx, hd->ioc->id, mf); #if defined(MPT_DEBUG_DV) || defined(MPT_DEBUG_DV_TINY) { @@ -3930,12 +3680,13 @@ static int mptscsih_ioc_reset(MPT_ADAPTER *ioc, int reset_phase) { - MPT_SCSI_HOST *hd = NULL; + MPT_SCSI_HOST *hd; unsigned long flags; dtmprintk((KERN_WARNING MYNAM ": IOC %s_reset routed to SCSI host driver!\n", - reset_phase==MPT_IOC_PRE_RESET ? "pre" : "post")); + reset_phase==MPT_IOC_SETUP_RESET ? "setup" : ( + reset_phase==MPT_IOC_PRE_RESET ? "pre" : "post"))); /* If a FW reload request arrives after base installed but * before all scsi hosts have been attached, then an alt_ioc @@ -3946,9 +3697,8 @@ else hd = (MPT_SCSI_HOST *) ioc->sh->hostdata; - if (reset_phase == MPT_IOC_PRE_RESET) { - dtmprintk((MYIOC_s_WARN_FMT "Do Pre-Diag Reset handling\n", - ioc->name)); + if (reset_phase == MPT_IOC_SETUP_RESET) { + dtmprintk((MYIOC_s_WARN_FMT "Setup-Diag Reset\n", ioc->name)); /* Clean Up: * 1. Set Hard Reset Pending Flag @@ -3956,6 +3706,11 @@ */ hd->resetPending = 1; + mptscsih_reset_timeouts (hd); + + } else if (reset_phase == MPT_IOC_PRE_RESET) { + dtmprintk((MYIOC_s_WARN_FMT "Pre-Diag Reset\n", ioc->name)); + /* 2. Flush running commands * Clean drop test code - if compiled * Clean ScsiLookup (and associated memory) @@ -3964,9 +3719,6 @@ /* 2a. Drop Test Command. */ -#ifdef DROP_TEST - mptscsih_flush_drop_test(hd); -#endif /* 2b. Reply to OS all known outstanding I/O commands. */ @@ -3979,7 +3731,6 @@ if (hd->cmdPtr) { del_timer(&hd->timer); mpt_free_msg_frame(ScsiScanDvCtx, ioc->id, hd->cmdPtr); - atomic_dec(&queue_depth); } /* 2d. If a task management has not completed, @@ -3990,12 +3741,14 @@ mpt_free_msg_frame(ScsiTaskCtx, ioc->id, hd->tmPtr); } - dtmprintk((MYIOC_s_WARN_FMT "Pre-Reset handling complete.\n", - ioc->name)); +#ifdef MPTSCSIH_DBG_TIMEOUT + ioc->timeout_hard = 0; +#endif + + dtmprintk((MYIOC_s_WARN_FMT "Pre-Reset complete.\n", ioc->name)); } else { - dtmprintk((MYIOC_s_WARN_FMT "Do Post-Diag Reset handling\n", - ioc->name)); + dtmprintk((MYIOC_s_WARN_FMT "Post-Diag Reset\n", ioc->name)); /* Once a FW reload begins, all new OS commands are * redirected to the doneQ w/ a reset status. @@ -4052,10 +3805,6 @@ */ flush_doneQ(hd); - dtmprintk((MYIOC_s_WARN_FMT "Post-Reset handling complete.\n", - ioc->name)); - - /* 8. Set flag to force DV and re-read IOC Page 3 */ if (hd->is_spi) { @@ -4063,6 +3812,8 @@ ddvtprintk(("Set reload IOC Pg3 Flag\n")); } + dtmprintk((MYIOC_s_WARN_FMT "Post-Reset complete.\n", ioc->name)); + } return 1; /* currently means nothing really */ @@ -4571,6 +4322,268 @@ } /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ + +/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ +/* + * mptscsih_initTarget - Target, LUN alloc/free functionality. + * @hd: Pointer to MPT_SCSI_HOST structure + * @bus_id: Bus number (?) + * @target_id: SCSI target id + * @lun: SCSI LUN id + * @data: Pointer to data + * @dlen: Number of INQUIRY bytes + * + * NOTE: It's only SAFE to call this routine if data points to + * sane & valid STANDARD INQUIRY data! + * + * Allocate and initialize memory for this target. + * Save inquiry data. + * + */ +static void +mptscsih_initTarget(MPT_SCSI_HOST *hd, int bus_id, int target_id, u8 lun, char *data, int dlen) +{ + int indexed_lun, lun_index; + VirtDevice *vdev; + char data_56; + + dprintk((MYIOC_s_INFO_FMT "initTarget bus=%d id=%d lun=%d hd=%p\n", + hd->ioc->name, bus_id, target_id, lun, hd)); + + /* Is LUN supported? If so, upper 3 bits will be 0 + * in first byte of inquiry data. + */ + if (data[0] & 0xe0) + return; + + vdev = hd->Targets[target_id]; + + lun_index = (lun >> 5); /* 32 luns per lun_index */ + indexed_lun = (lun % 32); + vdev->luns[lun_index] |= (1 << indexed_lun); + + vdev->raidVolume = 0; + if (hd->is_spi) { + if (hd->ioc->spi_data.isRaid & (1 << target_id)) { + vdev->raidVolume = 1; + ddvtprintk((KERN_INFO "RAID Volume @ id %d\n", target_id)); + } + } + + if (!(vdev->tflags & MPT_TARGET_FLAGS_VALID_INQUIRY)) { + if ( dlen > 8 ) { + memcpy (vdev->inq_data, data, 8); + } else { + memcpy (vdev->inq_data, data, dlen); + } + vdev->tflags |= MPT_TARGET_FLAGS_VALID_INQUIRY; + + /* If LUN 0, tape and have not done DV, set the DV flag. + */ + if (hd->is_spi && (lun == 0) && (data[0] == SCSI_TYPE_TAPE)) { + ScsiCfgData *pSpi = &hd->ioc->spi_data; + if (pSpi->dvStatus[target_id] & MPT_SCSICFG_DV_NOT_DONE) + pSpi->dvStatus[target_id] |= MPT_SCSICFG_NEED_DV; + } + + if ( (data[0] == SCSI_TYPE_PROC) && + !(vdev->tflags & MPT_TARGET_FLAGS_SAF_TE_ISSUED )) { + if ( dlen > 49 ) { + vdev->tflags |= MPT_TARGET_FLAGS_VALID_INQUIRY; + if ( data[44] == 'S' && + data[45] == 'A' && + data[46] == 'F' && + data[47] == '-' && + data[48] == 'T' && + data[49] == 'E' ) { + vdev->tflags |= MPT_TARGET_FLAGS_SAF_TE_ISSUED; + mptscsih_writeIOCPage4(hd, target_id, bus_id); + } + } else { + /* Treat all Processors as SAF-TE if + * command line option is set */ + if ( hd->ioc->spi_data.Saf_Te ) { + vdev->tflags |= MPT_TARGET_FLAGS_SAF_TE_ISSUED; + mptscsih_writeIOCPage4(hd, target_id, bus_id); + } + } + } + + data_56 = 0; + if (dlen > 56) { + if ( (!(vdev->tflags & MPT_TARGET_FLAGS_VALID_56))) { + /* Update the target capabilities + */ + data_56 = data[56]; + vdev->tflags |= MPT_TARGET_FLAGS_VALID_56; + } + } + mptscsih_setTargetNegoParms(hd, vdev, data_56); + } + + dprintk((KERN_INFO " target = %p\n", vdev)); + return; +} + +/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ +/* + * Update the target negotiation parameters based on the + * the Inquiry data, adapter capabilities, and NVRAM settings. + * + */ +void mptscsih_setTargetNegoParms(MPT_SCSI_HOST *hd, VirtDevice *target, char byte56) +{ + ScsiCfgData *pspi_data = &hd->ioc->spi_data; + int id = (int) target->target_id; + int nvram; + char canQ = 0; + VirtDevice *vdev; + int ii; + u8 width = MPT_NARROW; + u8 factor = MPT_ASYNC; + u8 offset = 0; + u8 version, nfactor; + u8 noQas = 1; + + if (!hd->is_spi) { + if (target->tflags & MPT_TARGET_FLAGS_VALID_INQUIRY) { + if (target->inq_data[7] & 0x02) + target->tflags |= MPT_TARGET_FLAGS_Q_YES; + } + return; + } + + target->negoFlags = pspi_data->noQas; + + /* noQas == 0 => device supports QAS. Need byte 56 of Inq to determine + * support. If available, default QAS to off and allow enabling. + * If not available, default QAS to on, turn off for non-disks. + */ + + /* Set flags based on Inquiry data + */ + if (target->tflags & MPT_TARGET_FLAGS_VALID_INQUIRY) { + version = target->inq_data[2] & 0x07; + if (version < 2) { + width = 0; + factor = MPT_ULTRA2; + offset = pspi_data->maxSyncOffset; + } else { + if (target->inq_data[7] & 0x20) { + width = 1; + } + + if (target->inq_data[7] & 0x10) { + /* bits 2 & 3 show DT support + */ + if ((byte56 & 0x04) == 0) + factor = MPT_ULTRA2; + else if ((byte56 & 0x03) == 0) + factor = MPT_ULTRA160; + else + factor = MPT_ULTRA320; + offset = pspi_data->maxSyncOffset; + + /* If RAID, never disable QAS + * else if non RAID, do not disable + * QAS if bit 1 is set + * bit 1 QAS support, non-raid only + * bit 0 IU support + */ + if ((target->raidVolume == 1) || ((byte56 & 0x02) != 0)) + noQas = 0; + } else { + factor = MPT_ASYNC; + offset = 0; + } + } + + if (target->inq_data[7] & 0x02) { + canQ = 1; + } + + /* Update tflags based on NVRAM settings. (SCSI only) + */ + if (pspi_data->nvram && (pspi_data->nvram[id] != MPT_HOST_NVRAM_INVALID)) { + nvram = pspi_data->nvram[id]; + nfactor = (nvram & MPT_NVRAM_SYNC_MASK) >> 8; + + if (width) + width = nvram & MPT_NVRAM_WIDE_DISABLE ? 0 : 1; + + if (offset > 0) { + /* Ensure factor is set to the + * maximum of: adapter, nvram, inquiry + */ + if (nfactor) { + if (nfactor < pspi_data->minSyncFactor ) + nfactor = pspi_data->minSyncFactor; + + factor = MAX (factor, nfactor); + if (factor == MPT_ASYNC) + offset = 0; + } else { + offset = 0; + factor = MPT_ASYNC; + } + } else { + factor = MPT_ASYNC; + } + } + + /* Make sure data is consistent + */ + if ((!width) && (factor < MPT_ULTRA2)) { + factor = MPT_ULTRA2; + } + + /* Save the data to the target structure. + */ + target->minSyncFactor = factor; + target->maxOffset = offset; + target->maxWidth = width; + if (canQ) { + target->tflags |= MPT_TARGET_FLAGS_Q_YES; + } + + target->tflags |= MPT_TARGET_FLAGS_VALID_NEGO; + + /* Disable unused features. + */ + if (!width) + target->negoFlags |= MPT_TARGET_NO_NEGO_WIDE; + + if (!offset) + target->negoFlags |= MPT_TARGET_NO_NEGO_SYNC; + + /* GEM, processor WORKAROUND + */ + if (((target->inq_data[0] & 0x1F) == 0x03) + || ((target->inq_data[0] & 0x1F) > 0x08)) { + target->negoFlags |= (MPT_TARGET_NO_NEGO_WIDE | MPT_TARGET_NO_NEGO_SYNC); + pspi_data->dvStatus[id] |= MPT_SCSICFG_BLK_NEGO; + } else { + if (noQas && (pspi_data->noQas == 0)) { + pspi_data->noQas |= MPT_TARGET_NO_NEGO_QAS; + target->negoFlags |= MPT_TARGET_NO_NEGO_QAS; + + /* Disable QAS in a mixed configuration case + */ + +// ddvtprintk((KERN_INFO "Disabling QAS!\n")); + for (ii = 0; ii < id; ii++) { + if ( (vdev = hd->Targets[ii]) ) { + vdev->negoFlags |= MPT_TARGET_NO_NEGO_QAS; + } + } + } + } + } + + return; +} + +/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ /* If DV disabled (negoNvram set to USE_NVARM) or if not LUN 0, return. * Else set the NEED_DV flag after Read Capacity Issued (disks) * or Mode Sense (cdroms). @@ -4581,7 +4594,7 @@ static void mptscsih_set_dvflags(MPT_SCSI_HOST *hd, SCSIIORequest_t *pReq) { u8 cmd; - + if ((pReq->LUN[1] != 0) || (hd->negoNvram != 0)) return; @@ -4609,16 +4622,14 @@ /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ /* - * If no Target (old) or Target unconfigured (new) and bus reset on 1st I/O, - * set the flag to prevent any future negotiations to this device. + * If no Target, bus reset on 1st I/O. Set the flag to + * prevent any future negotiations to this device. */ static void mptscsih_no_negotiate(MPT_SCSI_HOST *hd, int target_id) { - if (hd->Targets) { - VirtDevice *vdev = hd->Targets[target_id]; - if ((vdev == NULL) || !(vdev->tflags & MPT_TARGET_FLAGS_CONFIGURED)) - hd->ioc->spi_data.dvStatus[target_id] |= MPT_SCSICFG_BLK_NEGO; - } + + if ((hd->Targets) && (hd->Targets[target_id] == NULL)) + hd->ioc->spi_data.dvStatus[target_id] |= MPT_SCSICFG_BLK_NEGO; return; } @@ -4691,9 +4702,9 @@ mptscsih_writeSDP1(MPT_SCSI_HOST *hd, int portnum, int target_id, int flags) { MPT_ADAPTER *ioc = hd->ioc; - Config_t *pReq = NULL; - SCSIDevicePage1_t *pData = NULL; - VirtDevice *pTarget = NULL; + Config_t *pReq; + SCSIDevicePage1_t *pData; + VirtDevice *pTarget; MPT_FRAME_HDR *mf; dma_addr_t dataDma; u16 req_idx; @@ -4784,13 +4795,11 @@ /* If id is not a raid volume, get the updated * transmission settings from the target structure. */ - if (hd->Targets && (pTarget = hd->Targets[id]) && !pTarget->raidVolume - && (pTarget->tflags & MPT_TARGET_FLAGS_CONFIGURED)) { + if (hd->Targets && (pTarget = hd->Targets[id]) && !pTarget->raidVolume) { width = pTarget->maxWidth; factor = pTarget->minSyncFactor; offset = pTarget->maxOffset; negoFlags = pTarget->negoFlags; - pTarget = NULL; } if (flags & MPT_SCSICFG_BLK_NEGO) @@ -4832,9 +4841,8 @@ pReq->Reserved = 0; pReq->ChainOffset = 0; pReq->Function = MPI_FUNCTION_CONFIG; - pReq->Reserved1[0] = 0; - pReq->Reserved1[1] = 0; - pReq->Reserved1[2] = 0; + pReq->ExtPageLength = 0; + pReq->ExtPageType = 0; pReq->MsgFlags = 0; for (ii=0; ii < 8; ii++) { pReq->Reserved2[ii] = 0; @@ -4861,14 +4869,93 @@ pData->Reserved = 0; pData->Configuration = cpu_to_le32(configuration); - dsprintk((MYIOC_s_INFO_FMT + dprintk((MYIOC_s_INFO_FMT "write SDP1: id %d pgaddr 0x%x req 0x%x config 0x%x\n", ioc->name, id, (id | (bus<<8)), requested, configuration)); - mptscsih_put_msgframe(ScsiDoneCtx, ioc->id, mf); + mpt_put_msg_frame(ScsiDoneCtx, ioc->id, mf); + } + + return 0; +} + +/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ +/* mptscsih_writeIOCPage4 - write IOC Page 4 + * @hd: Pointer to a SCSI Host Structure + * @target_id: write IOC Page4 for this ID & Bus + * + * Return: -EAGAIN if unable to obtain a Message Frame + * or 0 if success. + * + * Remark: We do not wait for a return, write pages sequentially. + */ +static int +mptscsih_writeIOCPage4(MPT_SCSI_HOST *hd, int target_id, int bus) +{ + MPT_ADAPTER *ioc = hd->ioc; + Config_t *pReq; + IOCPage4_t *IOCPage4Ptr; + MPT_FRAME_HDR *mf; + dma_addr_t dataDma; + u16 req_idx; + u32 frameOffset; + u32 flagsLength; + int ii; + + /* Get a MF for this command. + */ + if ((mf = mpt_get_msg_frame(ScsiDoneCtx, ioc->id)) == NULL) { + dprintk((MYIOC_s_WARN_FMT "writeIOCPage4 : no msg frames!\n", + ioc->name)); + return -EAGAIN; + } + + ddvprintk((MYIOC_s_INFO_FMT "writeIOCPage4 (mf=%p, id=%d)\n", + ioc->name, mf, target_id)); + + /* Set the request and the data pointers. + * Place data at end of MF. + */ + pReq = (Config_t *)mf; + + req_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx); + frameOffset = ioc->req_sz - sizeof(IOCPage4_t); + + /* Complete the request frame (same for all requests). + */ + pReq->Action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT; + pReq->Reserved = 0; + pReq->ChainOffset = 0; + pReq->Function = MPI_FUNCTION_CONFIG; + pReq->ExtPageLength = 0; + pReq->ExtPageType = 0; + pReq->MsgFlags = 0; + for (ii=0; ii < 8; ii++) { + pReq->Reserved2[ii] = 0; } + IOCPage4Ptr = ioc->spi_data.pIocPg4; + dataDma = ioc->spi_data.IocPg4_dma; + ii = IOCPage4Ptr->ActiveSEP++; + IOCPage4Ptr->SEP[ii].SEPTargetID = target_id; + IOCPage4Ptr->SEP[ii].SEPBus = bus; + pReq->Header = IOCPage4Ptr->Header; + pReq->PageAddress = cpu_to_le32(target_id | (bus << 8 )); + + /* Add a SGE to the config request. + */ + flagsLength = MPT_SGE_FLAGS_SSIMPLE_WRITE | + (IOCPage4Ptr->Header.PageLength + ii) * 4; + + mpt_add_sge((char *)&pReq->PageBufferSGE, flagsLength, dataDma); + + dsprintk((MYIOC_s_INFO_FMT + "writeIOCPage4: pgaddr 0x%x\n", + ioc->name, (target_id | (bus<<8)))); + + mpt_put_msg_frame(ScsiDoneCtx, ioc->id, mf); + return 0; } @@ -4982,8 +5069,6 @@ ddvprintk((MYIOC_s_INFO_FMT "ScanDvComplete (mf=%p,mr=%p,idx=%d)\n", hd->ioc->name, mf, mr, req_idx)); - atomic_dec(&queue_depth); - hd->pLocal = &hd->localReply; hd->pLocal->scsiStatus = 0; @@ -5042,7 +5127,7 @@ u8 *sense_data; int sz; - /* save sense data in global & target structure + /* save sense data in global structure */ completionCode = MPT_SCANDV_SENSE; hd->pLocal->scsiStatus = pReply->SCSIStatus; @@ -5215,7 +5300,7 @@ hd->cmdPtr = mf; add_timer(&hd->timer); - mptscsih_put_msgframe(ScsiScanDvCtx, hd->ioc->id, mf); + mpt_put_msg_frame(ScsiScanDvCtx, hd->ioc->id, mf); wait_event(scandv_waitq, scandv_wait_done); if ((hd->pLocal == NULL) || (hd->pLocal->completion != MPT_SCANDV_GOOD)) @@ -5452,7 +5537,7 @@ hd->cmdPtr = mf; add_timer(&hd->timer); - mptscsih_put_msgframe(ScsiScanDvCtx, hd->ioc->id, mf); + mpt_put_msg_frame(ScsiScanDvCtx, hd->ioc->id, mf); wait_event(scandv_waitq, scandv_wait_done); if (hd->pLocal) { @@ -5490,7 +5575,7 @@ mptscsih_synchronize_cache(MPT_SCSI_HOST *hd, int portnum) { MPT_ADAPTER *ioc= hd->ioc; - VirtDevice *pTarget = NULL; + VirtDevice *pTarget; SCSIDevicePage1_t *pcfg1Data = NULL; INTERNAL_CMD iocmd; CONFIGPARMS cfg; @@ -5498,7 +5583,8 @@ ConfigPageHeader_t header1; int bus = 0; int id = 0; - int lun = 0; + int lun; + int indexed_lun, lun_index; int hostId = ioc->pfacts[portnum].PortSCSIID; int max_id; int requested, configuration, data; @@ -5593,7 +5679,9 @@ for (lun=0; lun <= MPT_LAST_LUN; lun++) { /* If LUN present, issue the command */ - if (pTarget->luns & (1<> 5); /* 32 luns per lun_index */ + indexed_lun = (lun % 32); + if (pTarget->luns[lun_index] & (1<Targets == NULL) @@ -5843,15 +5931,15 @@ * Return: None. */ static int -mptscsih_doDv(MPT_SCSI_HOST *hd, int portnum, int id) +mptscsih_doDv(MPT_SCSI_HOST *hd, int bus_number, int id) { MPT_ADAPTER *ioc = hd->ioc; - VirtDevice *pTarget = NULL; - SCSIDevicePage1_t *pcfg1Data = NULL; - SCSIDevicePage0_t *pcfg0Data = NULL; - u8 *pbuf1 = NULL; - u8 *pbuf2 = NULL; - u8 *pDvBuf = NULL; + VirtDevice *pTarget; + SCSIDevicePage1_t *pcfg1Data; + SCSIDevicePage0_t *pcfg0Data; + u8 *pbuf1; + u8 *pbuf2; + u8 *pDvBuf; dma_addr_t dvbuf_dma = -1; dma_addr_t buf1_dma = -1; dma_addr_t buf2_dma = -1; @@ -5871,6 +5959,7 @@ int patt; int repeat; int retcode = 0; + int nfactor = MPT_ULTRA320; char firstPass = 1; char doFallback = 0; char readPage0; @@ -5883,14 +5972,17 @@ if (ioc->spi_data.sdp0length == 0) return 0; - if (id == ioc->pfacts[portnum].PortSCSIID) + /* If multiple buses are used, require that the initiator + * id be the same on all buses. + */ + if (id == ioc->pfacts[0].PortSCSIID) return 0; lun = 0; - bus = 0; + bus = (u8) bus_number; ddvtprintk((MYIOC_s_NOTE_FMT - "DV started: numIOs %d bus=%d, id %d dv @ %p\n", - ioc->name, atomic_read(&queue_depth), bus, id, &dv)); + "DV started: bus=%d, id %d dv @ %p\n", + ioc->name, bus, id, &dv)); /* Prep DV structure */ @@ -5916,11 +6008,11 @@ iocmd.rsvd = iocmd.rsvd2 = 0; pTarget = hd->Targets[id]; - if (pTarget && (pTarget->tflags & MPT_TARGET_FLAGS_CONFIGURED)) { + if (pTarget && (pTarget->tflags & MPT_TARGET_FLAGS_VALID_INQUIRY)) { /* Another GEM workaround. Check peripheral device type, * if PROCESSOR, quit DV. */ - if ((pTarget->type == 0x03) || (pTarget->type > 0x08)) { + if (((pTarget->inq_data[0] & 0x1F) == 0x03) || ((pTarget->inq_data[0] & 0x1F) > 0x08)) { pTarget->negoFlags |= (MPT_TARGET_NO_NEGO_WIDE | MPT_TARGET_NO_NEGO_SYNC); return 0; } @@ -5992,24 +6084,34 @@ /* Skip this ID? Set cfg.hdr to force config page write */ - if ((ioc->spi_data.nvram[id] != MPT_HOST_NVRAM_INVALID) && - (!(ioc->spi_data.nvram[id] & MPT_NVRAM_ID_SCAN_ENABLE))) { + { + ScsiCfgData *pspi_data = &hd->ioc->spi_data; + if (pspi_data->nvram && (pspi_data->nvram[id] != MPT_HOST_NVRAM_INVALID)) { + /* Set the factor from nvram */ + nfactor = (pspi_data->nvram[id] & MPT_NVRAM_SYNC_MASK) >> 8; + if (nfactor < pspi_data->minSyncFactor ) + nfactor = pspi_data->minSyncFactor; - ddvprintk((MYIOC_s_NOTE_FMT "DV Skipped: bus, id, lun (%d, %d, %d)\n", - ioc->name, bus, id, lun)); + if (!(pspi_data->nvram[id] & MPT_NVRAM_ID_SCAN_ENABLE) || + (pspi_data->PortFlags == MPI_SCSIPORTPAGE2_PORT_FLAGS_OFF_DV) ) { - dv.cmd = MPT_SET_MAX; - mptscsih_dv_parms(hd, &dv, (void *)pcfg1Data); - cfg.hdr = &header1; - /* Double writes to SDP1 can cause problems, - * skip save of the final negotiated settings to - * SCSI device page 1. - */ - cfg.physAddr = cfg1_dma_addr; - cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT; - cfg.dir = 1; - mpt_config(hd->ioc, &cfg); - goto target_done; + ddvprintk((MYIOC_s_NOTE_FMT "DV Skipped: bus, id, lun (%d, %d, %d)\n", + ioc->name, bus, id, lun)); + + dv.cmd = MPT_SET_MAX; + mptscsih_dv_parms(hd, &dv, (void *)pcfg1Data); + cfg.hdr = &header1; + + /* Save the final negotiated settings to + * SCSI device page 1. + */ + cfg.physAddr = cfg1_dma_addr; + cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT; + cfg.dir = 1; + mpt_config(hd->ioc, &cfg); + goto target_done; + } + } } /* Finish iocmd inititialization - hidden or visible disk? */ @@ -6059,7 +6161,7 @@ sz = SCSI_STD_INQUIRY_BYTES; rc = MPT_SCANDV_GOOD; while (1) { - ddvprintk((MYIOC_s_NOTE_FMT "DV: Start Basic test.\n", ioc->name)); + ddvprintk((MYIOC_s_NOTE_FMT "DV: Start Basic test on id=%d\n", ioc->name, id)); retcode = 0; dv.cmd = MPT_SET_MIN; mptscsih_dv_parms(hd, &dv, (void *)pcfg1Data); @@ -6131,6 +6233,14 @@ } } + /* Reset the size for disks + */ + inq0 = (*pbuf1) & 0x1F; + if ((inq0 == 0) && pTarget && !pTarget->raidVolume) { + sz = 0x40; + iocmd.size = sz; + } + /* Another GEM workaround. Check peripheral device type, * if PROCESSOR, quit DV. */ @@ -6140,6 +6250,28 @@ if (mptscsih_do_cmd(hd, &iocmd) < 0) goto target_done; + if (sz == 0x40) { + if ((pTarget->maxWidth == 1) && (pTarget->maxOffset) && (nfactor < 0x0A) + && (pTarget->minSyncFactor > 0x09)) { + if ((pbuf1[56] & 0x04) == 0) + ; + else if ((pbuf1[56] & 0x01) == 1) { + pTarget->minSyncFactor = + nfactor > MPT_ULTRA320 ? nfactor : MPT_ULTRA320; + } else { + pTarget->minSyncFactor = + nfactor > MPT_ULTRA160 ? nfactor : MPT_ULTRA160; + } + + dv.max.factor = pTarget->minSyncFactor; + + if ((pbuf1[56] & 0x02) == 0) { + pTarget->negoFlags |= MPT_TARGET_NO_NEGO_QAS; + hd->ioc->spi_data.noQas = MPT_TARGET_NO_NEGO_QAS; + } + } + } + if (doFallback) dv.cmd = MPT_FALLBACK; else @@ -6223,7 +6355,7 @@ firstPass = 0; } } - ddvprintk((MYIOC_s_NOTE_FMT "DV: Basic test completed OK.\n", ioc->name)); + ddvprintk((MYIOC_s_NOTE_FMT "DV: Basic test on id=%d completed OK.\n", ioc->name, id)); inq0 = (*pbuf1) & 0x1F; /* Continue only for disks @@ -6231,6 +6363,9 @@ if (inq0 != 0) goto target_done; + if ( ioc->spi_data.PortFlags == MPI_SCSIPORTPAGE2_PORT_FLAGS_BASIC_DV_ONLY ) + goto target_done; + /* Start the Enhanced Test. * 0) issue TUR to clear out check conditions * 1) read capacity of echo (regular) buffer @@ -6671,8 +6806,8 @@ if (pDvBuf) pci_free_consistent(ioc->pcidev, dv_alloc, pDvBuf, dvbuf_dma); - ddvtprintk((MYIOC_s_INFO_FMT "DV Done. IOs outstanding = %d\n", - ioc->name, atomic_read(&queue_depth))); + ddvtprintk((MYIOC_s_INFO_FMT "DV Done.\n", + ioc->name)); return retcode; } @@ -6687,9 +6822,9 @@ static void mptscsih_dv_parms(MPT_SCSI_HOST *hd, DVPARAMETERS *dv,void *pPage) { - VirtDevice *pTarget = NULL; - SCSIDevicePage0_t *pPage0 = NULL; - SCSIDevicePage1_t *pPage1 = NULL; + VirtDevice *pTarget; + SCSIDevicePage0_t *pPage0; + SCSIDevicePage1_t *pPage1; int val = 0, data, configuration; u8 width = 0; u8 offset = 0; @@ -6841,7 +6976,6 @@ factor = MPT_ULTRA; width = MPT_WIDE; } else if ((factor == MPT_ULTRA) && width) { - factor = MPT_ULTRA; width = MPT_NARROW; } else if (factor < MPT_FAST) { factor = MPT_FAST; @@ -7072,9 +7206,9 @@ /* Commandline Parsing routines and defines. * * insmod format: - * insmod mptscsih mptscsih="width:1 dv:n factor:0x09" + * insmod mptscsih mptscsih="width:1 dv:n factor:0x09 saf-te:1" * boot format: - * mptscsih=width:1,dv:n,factor:0x8 + * mptscsih=width:1,dv:n,factor:0x8,saf-te:1 * */ #ifdef MODULE @@ -7087,11 +7221,13 @@ "dv:" "width:" "factor:" - ; /* DONNOT REMOVE THIS ';' */ + "saf-te:" + ; /* DO NOT REMOVE THIS ';' */ #define OPT_DV 1 #define OPT_MAX_WIDTH 2 #define OPT_MIN_SYNC_FACTOR 3 +#define OPT_SAF_TE 4 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ static int @@ -7146,6 +7282,10 @@ case OPT_MIN_SYNC_FACTOR: driver_setup.min_sync_fac = val; + break; + + case OPT_SAF_TE: + driver_setup.saf_te = val; break; default: diff -Nru a/drivers/message/fusion/mptscsih.h b/drivers/message/fusion/mptscsih.h --- a/drivers/message/fusion/mptscsih.h Sun Mar 14 14:20:08 2004 +++ b/drivers/message/fusion/mptscsih.h Sun Mar 14 14:20:08 2004 @@ -15,7 +15,7 @@ * * (see also mptbase.c) * - * Copyright (c) 1999-2003 LSI Logic Corporation + * Copyright (c) 1999-2004 LSI Logic Corporation * Originally By: Steven J. Ralston * (mailto:netscape.net) * (mailto:mpt_linux_developer@lsil.com) @@ -70,11 +70,7 @@ * Try to keep these at 2^N-1 */ #define MPT_FC_CAN_QUEUE 127 -#if defined MPT_SCSI_USE_NEW_EH - #define MPT_SCSI_CAN_QUEUE 127 -#else - #define MPT_SCSI_CAN_QUEUE 63 -#endif +#define MPT_SCSI_CAN_QUEUE 127 #define MPT_SCSI_CMD_PER_DEV_HIGH 31 #define MPT_SCSI_CMD_PER_DEV_LOW 7 @@ -98,7 +94,7 @@ #define MPT_SCSI_SG_DEPTH 40 #endif -/* To disable domain validation, comment the +/* To disable domain validation, uncomment the * following line. No effect for FC devices. * For SCSI devices, driver will negotiate to * NVRAM settings (if available) or to maximum adapter @@ -114,12 +110,14 @@ #define MPTSCSIH_DOMAIN_VALIDATION 1 #define MPTSCSIH_MAX_WIDTH 1 #define MPTSCSIH_MIN_SYNC 0x08 +#define MPTSCSIH_SAF_TE 0 struct mptscsih_driver_setup { u8 dv; u8 max_width; u8 min_sync_fac; + u8 saf_te; }; @@ -128,6 +126,7 @@ MPTSCSIH_DOMAIN_VALIDATION, \ MPTSCSIH_MAX_WIDTH, \ MPTSCSIH_MIN_SYNC, \ + MPTSCSIH_SAF_TE, \ } diff -Nru a/drivers/message/fusion/scsi3.h b/drivers/message/fusion/scsi3.h --- a/drivers/message/fusion/scsi3.h Sun Mar 14 14:20:07 2004 +++ b/drivers/message/fusion/scsi3.h Sun Mar 14 14:20:07 2004 @@ -4,7 +4,7 @@ * (Ultimately) SCSI-3 definitions; for now, inheriting * SCSI-2 definitions. * - * Copyright (c) 1996-2003 Steven J. Ralston + * Copyright (c) 1996-2004 Steven J. Ralston * Written By: Steven J. Ralston (19960517) * (mailto:sjralston1@netscape.net) * (mailto:mpt_linux_developer@lsil.com) diff -Nru a/drivers/message/i2o/i2o_core.c b/drivers/message/i2o/i2o_core.c --- a/drivers/message/i2o/i2o_core.c Sun Mar 14 14:20:07 2004 +++ b/drivers/message/i2o/i2o_core.c Sun Mar 14 14:20:07 2004 @@ -1179,7 +1179,7 @@ * the processor */ - pci_dma_sync_single(c->pdev, c->page_frame_map, MSG_FRAME_SIZE, PCI_DMA_FROMDEVICE); + pci_dma_sync_single_for_cpu(c->pdev, c->page_frame_map, MSG_FRAME_SIZE, PCI_DMA_FROMDEVICE); /* * Despatch it diff -Nru a/drivers/mtd/devices/blkmtd.c b/drivers/mtd/devices/blkmtd.c --- a/drivers/mtd/devices/blkmtd.c Sun Mar 14 14:20:06 2004 +++ b/drivers/mtd/devices/blkmtd.c Sun Mar 14 14:20:06 2004 @@ -664,12 +664,12 @@ } memset(dev, 0, sizeof(struct blkmtd_dev)); + dev->blkdev = bdev; atomic_set(&(dev->blkdev->bd_inode->i_mapping->truncate_count), 0); if(!readonly) { init_MUTEX(&dev->wrbuf_mutex); } - dev->blkdev = bdev; dev->mtd_info.size = dev->blkdev->bd_inode->i_size & PAGE_MASK; /* Setup the MTD structure */ diff -Nru a/drivers/net/3c501.c b/drivers/net/3c501.c --- a/drivers/net/3c501.c Sun Mar 14 14:20:05 2004 +++ b/drivers/net/3c501.c Sun Mar 14 14:20:05 2004 @@ -306,7 +306,7 @@ printk(KERN_DEBUG "%s", version); memset(dev->priv, 0, sizeof(struct net_local)); - lp=dev->priv; + lp = netdev_priv(dev); spin_lock_init(&lp->lock); /* @@ -341,7 +341,7 @@ { int retval; int ioaddr = dev->base_addr; - struct net_local *lp = (struct net_local *)dev->priv; + struct net_local *lp = netdev_priv(dev); unsigned long flags; if (el_debug > 2) @@ -371,7 +371,7 @@ static void el_timeout(struct net_device *dev) { - struct net_local *lp = (struct net_local *)dev->priv; + struct net_local *lp = netdev_priv(dev); int ioaddr = dev->base_addr; if (el_debug) @@ -411,7 +411,7 @@ static int el_start_xmit(struct sk_buff *skb, struct net_device *dev) { - struct net_local *lp = (struct net_local *)dev->priv; + struct net_local *lp = netdev_priv(dev); int ioaddr = dev->base_addr; unsigned long flags; @@ -524,7 +524,7 @@ int axsr; /* Aux. status reg. */ ioaddr = dev->base_addr; - lp = (struct net_local *)dev->priv; + lp = netdev_priv(dev); spin_lock(&lp->lock); @@ -698,7 +698,7 @@ static void el_receive(struct net_device *dev) { - struct net_local *lp = (struct net_local *)dev->priv; + struct net_local *lp = netdev_priv(dev); int ioaddr = dev->base_addr; int pkt_len; struct sk_buff *skb; @@ -764,7 +764,7 @@ static void el_reset(struct net_device *dev) { - struct net_local *lp = (struct net_local *)dev->priv; + struct net_local *lp = netdev_priv(dev); int ioaddr = dev->base_addr; if (el_debug> 2) @@ -828,7 +828,7 @@ static struct net_device_stats *el1_get_stats(struct net_device *dev) { - struct net_local *lp = (struct net_local *)dev->priv; + struct net_local *lp = netdev_priv(dev); return &lp->stats; } diff -Nru a/drivers/net/3c503.c b/drivers/net/3c503.c --- a/drivers/net/3c503.c Sun Mar 14 14:20:07 2004 +++ b/drivers/net/3c503.c Sun Mar 14 14:20:08 2004 @@ -337,6 +337,9 @@ dev->open = &el2_open; dev->stop = &el2_close; dev->ethtool_ops = &netdev_ethtool_ops; +#ifdef CONFIG_NET_POLL_CONTROLLER + dev->poll_controller = ei_poll; +#endif if (dev->mem_start) printk("%s: %s - %dkB RAM, 8kB shared mem window at %#6lx-%#6lx.\n", diff -Nru a/drivers/net/3c507.c b/drivers/net/3c507.c --- a/drivers/net/3c507.c Sun Mar 14 14:20:08 2004 +++ b/drivers/net/3c507.c Sun Mar 14 14:20:08 2004 @@ -441,7 +441,7 @@ if (net_debug) printk(version); - lp = dev->priv; + lp = netdev_priv(dev); memset(lp, 0, sizeof(*lp)); spin_lock_init(&lp->lock); @@ -471,7 +471,7 @@ static void el16_tx_timeout (struct net_device *dev) { - struct net_local *lp = (struct net_local *) dev->priv; + struct net_local *lp = netdev_priv(dev); int ioaddr = dev->base_addr; unsigned long shmem = dev->mem_start; @@ -501,7 +501,7 @@ static int el16_send_packet (struct sk_buff *skb, struct net_device *dev) { - struct net_local *lp = (struct net_local *) dev->priv; + struct net_local *lp = netdev_priv(dev); int ioaddr = dev->base_addr; unsigned long flags; short length = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN; @@ -546,7 +546,7 @@ } ioaddr = dev->base_addr; - lp = (struct net_local *)dev->priv; + lp = netdev_priv(dev); shmem = dev->mem_start; spin_lock(&lp->lock); @@ -660,7 +660,7 @@ closed. */ static struct net_device_stats *el16_get_stats(struct net_device *dev) { - struct net_local *lp = (struct net_local *)dev->priv; + struct net_local *lp = netdev_priv(dev); /* ToDo: decide if there are any useful statistics from the SCB. */ @@ -670,7 +670,7 @@ /* Initialize the Rx-block list. */ static void init_rx_bufs(struct net_device *dev) { - struct net_local *lp = (struct net_local *)dev->priv; + struct net_local *lp = netdev_priv(dev); unsigned long write_ptr; unsigned short SCB_base = SCB_BASE; @@ -713,7 +713,7 @@ static void init_82586_mem(struct net_device *dev) { - struct net_local *lp = (struct net_local *)dev->priv; + struct net_local *lp = netdev_priv(dev); short ioaddr = dev->base_addr; unsigned long shmem = dev->mem_start; @@ -771,7 +771,7 @@ static void hardware_send_packet(struct net_device *dev, void *buf, short length, short pad) { - struct net_local *lp = (struct net_local *)dev->priv; + struct net_local *lp = netdev_priv(dev); short ioaddr = dev->base_addr; ushort tx_block = lp->tx_head; unsigned long write_ptr = dev->mem_start + tx_block; @@ -820,7 +820,7 @@ static void el16_rx(struct net_device *dev) { - struct net_local *lp = (struct net_local *)dev->priv; + struct net_local *lp = netdev_priv(dev); unsigned long shmem = dev->mem_start; ushort rx_head = lp->rx_head; ushort rx_tail = lp->rx_tail; diff -Nru a/drivers/net/3c509.c b/drivers/net/3c509.c --- a/drivers/net/3c509.c Sun Mar 14 14:20:06 2004 +++ b/drivers/net/3c509.c Sun Mar 14 14:20:06 2004 @@ -304,7 +304,7 @@ static int __init el3_common_init(struct net_device *dev) { - struct el3_private *lp = dev->priv; + struct el3_private *lp = netdev_priv(dev); short i; int err; @@ -355,7 +355,7 @@ static void el3_common_remove (struct net_device *dev) { - struct el3_private *lp = dev->priv; + struct el3_private *lp = netdev_priv(dev); (void) lp; /* Keep gcc quiet... */ #ifdef CONFIG_PM @@ -575,7 +575,7 @@ dev->base_addr = ioaddr; dev->irq = irq; dev->if_port = if_port; - lp = dev->priv; + lp = netdev_priv(dev); #if defined(__ISAPNP__) && !defined(CONFIG_X86_PC9800) lp->dev = &idev->dev; #endif @@ -671,7 +671,7 @@ dev->base_addr = ioaddr; dev->irq = irq; dev->if_port = if_port; - lp = dev->priv; + lp = netdev_priv(dev); lp->dev = device; lp->type = EL3_MCA; device->driver_data = dev; @@ -732,7 +732,7 @@ dev->base_addr = ioaddr; dev->irq = irq; dev->if_port = if_port; - lp = dev->priv; + lp = netdev_priv(dev); lp->dev = device; lp->type = EL3_EISA; eisa_set_drvdata (edev, dev); @@ -829,7 +829,7 @@ static void el3_tx_timeout (struct net_device *dev) { - struct el3_private *lp = (struct el3_private *)dev->priv; + struct el3_private *lp = netdev_priv(dev); int ioaddr = dev->base_addr; /* Transmitter timeout, serious problems. */ @@ -849,7 +849,7 @@ static int el3_start_xmit(struct sk_buff *skb, struct net_device *dev) { - struct el3_private *lp = (struct el3_private *)dev->priv; + struct el3_private *lp = netdev_priv(dev); int ioaddr = dev->base_addr; unsigned long flags; @@ -943,7 +943,7 @@ return IRQ_NONE; } - lp = (struct el3_private *)dev->priv; + lp = netdev_priv(dev); spin_lock(&lp->lock); ioaddr = dev->base_addr; @@ -975,7 +975,7 @@ outw(AckIntr | RxEarly, ioaddr + EL3_CMD); } if (status & TxComplete) { /* Really Tx error. */ - struct el3_private *lp = (struct el3_private *)dev->priv; + struct el3_private *lp = netdev_priv(dev); short tx_status; int i = 4; @@ -1022,7 +1022,7 @@ static struct net_device_stats * el3_get_stats(struct net_device *dev) { - struct el3_private *lp = (struct el3_private *)dev->priv; + struct el3_private *lp = netdev_priv(dev); unsigned long flags; /* @@ -1043,7 +1043,7 @@ */ static void update_stats(struct net_device *dev) { - struct el3_private *lp = (struct el3_private *)dev->priv; + struct el3_private *lp = netdev_priv(dev); int ioaddr = dev->base_addr; if (el3_debug > 5) @@ -1073,7 +1073,7 @@ static int el3_rx(struct net_device *dev) { - struct el3_private *lp = (struct el3_private *)dev->priv; + struct el3_private *lp = netdev_priv(dev); int ioaddr = dev->base_addr; short rx_status; @@ -1145,7 +1145,7 @@ set_multicast_list(struct net_device *dev) { unsigned long flags; - struct el3_private *lp = (struct el3_private *)dev->priv; + struct el3_private *lp = netdev_priv(dev); int ioaddr = dev->base_addr; if (el3_debug > 1) { @@ -1172,7 +1172,7 @@ el3_close(struct net_device *dev) { int ioaddr = dev->base_addr; - struct el3_private *lp = (struct el3_private *)dev->priv; + struct el3_private *lp = netdev_priv(dev); if (el3_debug > 2) printk("%s: Shutting down ethercard.\n", dev->name); @@ -1317,7 +1317,7 @@ netdev_ethtool_ioctl (struct net_device *dev, void *useraddr) { u32 ethcmd; - struct el3_private *lp = dev->priv; + struct el3_private *lp = netdev_priv(dev); /* dev_ioctl() in ../../net/core/dev.c has already checked capable(CAP_NET_ADMIN), so don't bother with that here. */ @@ -1558,7 +1558,7 @@ return -EINVAL; dev = (struct net_device *)pdev->data; - lp = (struct el3_private *)dev->priv; + lp = netdev_priv(dev); ioaddr = dev->base_addr; spin_lock_irqsave(&lp->lock, flags); @@ -1585,7 +1585,7 @@ return -EINVAL; dev = (struct net_device *)pdev->data; - lp = (struct el3_private *)dev->priv; + lp = netdev_priv(dev); ioaddr = dev->base_addr; spin_lock_irqsave(&lp->lock, flags); diff -Nru a/drivers/net/3c527.c b/drivers/net/3c527.c --- a/drivers/net/3c527.c Sun Mar 14 14:20:07 2004 +++ b/drivers/net/3c527.c Sun Mar 14 14:20:07 2004 @@ -226,7 +226,7 @@ static void cleanup_card(struct net_device *dev) { - struct mc32_local *lp=dev->priv; + struct mc32_local *lp = netdev_priv(dev); unsigned slot = lp->slot; mca_mark_as_unused(slot); mca_set_adapter_name(slot, NULL); @@ -307,7 +307,7 @@ int i, err; u8 POS; u32 base; - struct mc32_local *lp = dev->priv; + struct mc32_local *lp = netdev_priv(dev); static u16 mca_io_bases[]={ 0x7280,0x7290, 0x7680,0x7690, @@ -573,7 +573,7 @@ static int mc32_command_nowait(struct net_device *dev, u16 cmd, void *data, int len) { - struct mc32_local *lp = (struct mc32_local *)dev->priv; + struct mc32_local *lp = netdev_priv(dev); int ioaddr = dev->base_addr; int ret = -1; @@ -619,7 +619,7 @@ static int mc32_command(struct net_device *dev, u16 cmd, void *data, int len) { - struct mc32_local *lp = (struct mc32_local *)dev->priv; + struct mc32_local *lp = netdev_priv(dev); int ioaddr = dev->base_addr; int ret = 0; @@ -671,7 +671,7 @@ static void mc32_start_transceiver(struct net_device *dev) { - struct mc32_local *lp = (struct mc32_local *)dev->priv; + struct mc32_local *lp = netdev_priv(dev); int ioaddr = dev->base_addr; /* Ignore RX overflow on device closure */ @@ -706,7 +706,7 @@ static void mc32_halt_transceiver(struct net_device *dev) { - struct mc32_local *lp = (struct mc32_local *)dev->priv; + struct mc32_local *lp = netdev_priv(dev); int ioaddr = dev->base_addr; mc32_ready_poll(dev); @@ -743,7 +743,7 @@ static int mc32_load_rx_ring(struct net_device *dev) { - struct mc32_local *lp = (struct mc32_local *)dev->priv; + struct mc32_local *lp = netdev_priv(dev); int i; u16 rx_base; volatile struct skb_header *p; @@ -792,7 +792,7 @@ static void mc32_flush_rx_ring(struct net_device *dev) { - struct mc32_local *lp = (struct mc32_local *)dev->priv; + struct mc32_local *lp = netdev_priv(dev); int i; for(i=0; i < RX_RING_LEN; i++) @@ -824,7 +824,7 @@ static void mc32_load_tx_ring(struct net_device *dev) { - struct mc32_local *lp = (struct mc32_local *)dev->priv; + struct mc32_local *lp = netdev_priv(dev); volatile struct skb_header *p; int i; u16 tx_base; @@ -861,7 +861,7 @@ static void mc32_flush_tx_ring(struct net_device *dev) { - struct mc32_local *lp = (struct mc32_local *)dev->priv; + struct mc32_local *lp = netdev_priv(dev); int i; for (i=0; i < TX_RING_LEN; i++) @@ -899,7 +899,7 @@ static int mc32_open(struct net_device *dev) { int ioaddr = dev->base_addr; - struct mc32_local *lp = (struct mc32_local *)dev->priv; + struct mc32_local *lp = netdev_priv(dev); u8 one=1; u8 regs; u16 descnumbuffs[2] = {TX_RING_LEN, RX_RING_LEN}; @@ -1022,7 +1022,7 @@ static int mc32_send_packet(struct sk_buff *skb, struct net_device *dev) { - struct mc32_local *lp = (struct mc32_local *)dev->priv; + struct mc32_local *lp = netdev_priv(dev); u32 head = atomic_read(&lp->tx_ring_head); volatile struct skb_header *p, *np; @@ -1092,7 +1092,7 @@ static void mc32_update_stats(struct net_device *dev) { - struct mc32_local *lp = (struct mc32_local *)dev->priv; + struct mc32_local *lp = netdev_priv(dev); volatile struct mc32_stats *st = lp->stats; u32 rx_errors=0; @@ -1143,7 +1143,7 @@ static void mc32_rx_ring(struct net_device *dev) { - struct mc32_local *lp=dev->priv; + struct mc32_local *lp = netdev_priv(dev); volatile struct skb_header *p; u16 rx_ring_tail; u16 rx_old_tail; @@ -1236,7 +1236,7 @@ static void mc32_tx_ring(struct net_device *dev) { - struct mc32_local *lp=(struct mc32_local *)dev->priv; + struct mc32_local *lp = netdev_priv(dev); volatile struct skb_header *np; /* @@ -1333,7 +1333,7 @@ } ioaddr = dev->base_addr; - lp = (struct mc32_local *)dev->priv; + lp = netdev_priv(dev); /* See whats cooking */ @@ -1450,7 +1450,7 @@ static int mc32_close(struct net_device *dev) { - struct mc32_local *lp = (struct mc32_local *)dev->priv; + struct mc32_local *lp = netdev_priv(dev); int ioaddr = dev->base_addr; u8 regs; @@ -1499,7 +1499,7 @@ static struct net_device_stats *mc32_get_stats(struct net_device *dev) { - struct mc32_local *lp = (struct mc32_local *)dev->priv; + struct mc32_local *lp = netdev_priv(dev); mc32_update_stats(dev); return &lp->net_stats; @@ -1531,7 +1531,7 @@ static void do_mc32_set_multicast_list(struct net_device *dev, int retry) { - struct mc32_local *lp = (struct mc32_local *)dev->priv; + struct mc32_local *lp = netdev_priv(dev); u16 filt = (1<<2); /* Save Bad Packets, for stats purposes */ if (dev->flags&IFF_PROMISC) diff -Nru a/drivers/net/3c59x.c b/drivers/net/3c59x.c --- a/drivers/net/3c59x.c Sun Mar 14 14:20:05 2004 +++ b/drivers/net/3c59x.c Sun Mar 14 14:20:05 2004 @@ -927,6 +927,18 @@ static int vortex_cards_found; +#ifdef CONFIG_NET_POLL_CONTROLLER +static void poll_vortex(struct net_device *dev) +{ + struct vortex_private *vp = (struct vortex_private *)dev->priv; + unsigned long flags; + local_save_flags(flags); + local_irq_disable(); + (vp->full_bus_master_rx ? boomerang_interrupt:vortex_interrupt)(dev->irq,dev,NULL); + local_irq_restore(flags); +} +#endif + #ifdef CONFIG_PM static int vortex_suspend (struct pci_dev *pdev, u32 state) @@ -1013,7 +1025,7 @@ BUG(); } - vp = dev->priv; + vp = netdev_priv(dev); ioaddr = dev->base_addr; unregister_netdev (dev); @@ -1115,7 +1127,7 @@ } SET_MODULE_OWNER(dev); SET_NETDEV_DEV(dev, gendev); - vp = dev->priv; + vp = netdev_priv(dev); option = global_options; @@ -1463,6 +1475,9 @@ dev->set_multicast_list = set_rx_mode; dev->tx_timeout = vortex_tx_timeout; dev->watchdog_timeo = (watchdog * HZ) / 1000; +#ifdef CONFIG_NET_POLL_CONTROLLER + dev->poll_controller = poll_vortex; +#endif if (pdev && vp->enable_wol) { vp->pm_state_valid = 1; pci_save_state(VORTEX_PCI(vp), vp->power_state); @@ -1516,7 +1531,7 @@ vortex_up(struct net_device *dev) { long ioaddr = dev->base_addr; - struct vortex_private *vp = (struct vortex_private *)dev->priv; + struct vortex_private *vp = netdev_priv(dev); unsigned int config; int i; @@ -1714,7 +1729,7 @@ static int vortex_open(struct net_device *dev) { - struct vortex_private *vp = (struct vortex_private *)dev->priv; + struct vortex_private *vp = netdev_priv(dev); int i; int retval; @@ -1772,7 +1787,7 @@ vortex_timer(unsigned long data) { struct net_device *dev = (struct net_device *)data; - struct vortex_private *vp = (struct vortex_private *)dev->priv; + struct vortex_private *vp = netdev_priv(dev); long ioaddr = dev->base_addr; int next_tick = 60*HZ; int ok = 0; @@ -1898,7 +1913,7 @@ static void vortex_tx_timeout(struct net_device *dev) { - struct vortex_private *vp = (struct vortex_private *)dev->priv; + struct vortex_private *vp = netdev_priv(dev); long ioaddr = dev->base_addr; printk(KERN_ERR "%s: transmit timed out, tx_status %2.2x status %4.4x.\n", @@ -1968,7 +1983,7 @@ static void vortex_error(struct net_device *dev, int status) { - struct vortex_private *vp = (struct vortex_private *)dev->priv; + struct vortex_private *vp = netdev_priv(dev); long ioaddr = dev->base_addr; int do_tx_reset = 0, reset_mask = 0; unsigned char tx_status = 0; @@ -2070,7 +2085,7 @@ static int vortex_start_xmit(struct sk_buff *skb, struct net_device *dev) { - struct vortex_private *vp = (struct vortex_private *)dev->priv; + struct vortex_private *vp = netdev_priv(dev); long ioaddr = dev->base_addr; /* Put out the doubleword header... */ @@ -2125,7 +2140,7 @@ static int boomerang_start_xmit(struct sk_buff *skb, struct net_device *dev) { - struct vortex_private *vp = (struct vortex_private *)dev->priv; + struct vortex_private *vp = netdev_priv(dev); long ioaddr = dev->base_addr; /* Calculate the next Tx descriptor entry. */ int entry = vp->cur_tx % TX_RING_SIZE; @@ -2225,7 +2240,7 @@ vortex_interrupt(int irq, void *dev_id, struct pt_regs *regs) { struct net_device *dev = dev_id; - struct vortex_private *vp = (struct vortex_private *)dev->priv; + struct vortex_private *vp = netdev_priv(dev); long ioaddr; int status; int work_done = max_interrupt_work; @@ -2330,7 +2345,7 @@ boomerang_interrupt(int irq, void *dev_id, struct pt_regs *regs) { struct net_device *dev = dev_id; - struct vortex_private *vp = (struct vortex_private *)dev->priv; + struct vortex_private *vp = netdev_priv(dev); long ioaddr; int status; int work_done = max_interrupt_work; @@ -2455,7 +2470,7 @@ static int vortex_rx(struct net_device *dev) { - struct vortex_private *vp = (struct vortex_private *)dev->priv; + struct vortex_private *vp = netdev_priv(dev); long ioaddr = dev->base_addr; int i; short rx_status; @@ -2525,7 +2540,7 @@ static int boomerang_rx(struct net_device *dev) { - struct vortex_private *vp = (struct vortex_private *)dev->priv; + struct vortex_private *vp = netdev_priv(dev); int entry = vp->cur_rx % RX_RING_SIZE; long ioaddr = dev->base_addr; int rx_status; @@ -2562,11 +2577,12 @@ if (pkt_len < rx_copybreak && (skb = dev_alloc_skb(pkt_len + 2)) != 0) { skb->dev = dev; skb_reserve(skb, 2); /* Align IP on 16 byte boundaries */ - pci_dma_sync_single(VORTEX_PCI(vp), dma, PKT_BUF_SZ, PCI_DMA_FROMDEVICE); + pci_dma_sync_single_for_cpu(VORTEX_PCI(vp), dma, PKT_BUF_SZ, PCI_DMA_FROMDEVICE); /* 'skb_put()' points to the start of sk_buff data area. */ memcpy(skb_put(skb, pkt_len), vp->rx_skbuff[entry]->tail, pkt_len); + pci_dma_sync_single_for_device(VORTEX_PCI(vp), dma, PKT_BUF_SZ, PCI_DMA_FROMDEVICE); vp->rx_copy++; } else { /* Pass up the skbuff already on the Rx ring. */ @@ -2627,7 +2643,7 @@ rx_oom_timer(unsigned long arg) { struct net_device *dev = (struct net_device *)arg; - struct vortex_private *vp = (struct vortex_private *)dev->priv; + struct vortex_private *vp = netdev_priv(dev); spin_lock_irq(&vp->lock); if ((vp->cur_rx - vp->dirty_rx) == RX_RING_SIZE) /* This test is redundant, but makes me feel good */ @@ -2642,7 +2658,7 @@ static void vortex_down(struct net_device *dev) { - struct vortex_private *vp = (struct vortex_private *)dev->priv; + struct vortex_private *vp = netdev_priv(dev); long ioaddr = dev->base_addr; netif_stop_queue (dev); @@ -2678,7 +2694,7 @@ static int vortex_close(struct net_device *dev) { - struct vortex_private *vp = (struct vortex_private *)dev->priv; + struct vortex_private *vp = netdev_priv(dev); long ioaddr = dev->base_addr; int i; @@ -2740,7 +2756,7 @@ dump_tx_ring(struct net_device *dev) { if (vortex_debug > 0) { - struct vortex_private *vp = (struct vortex_private *)dev->priv; + struct vortex_private *vp = netdev_priv(dev); long ioaddr = dev->base_addr; if (vp->full_bus_master_tx) { @@ -2773,7 +2789,7 @@ static struct net_device_stats *vortex_get_stats(struct net_device *dev) { - struct vortex_private *vp = (struct vortex_private *)dev->priv; + struct vortex_private *vp = netdev_priv(dev); unsigned long flags; if (netif_device_present(dev)) { /* AKPM: Used to be netif_running */ @@ -2793,7 +2809,7 @@ */ static void update_stats(long ioaddr, struct net_device *dev) { - struct vortex_private *vp = (struct vortex_private *)dev->priv; + struct vortex_private *vp = netdev_priv(dev); int old_window = inw(ioaddr + EL3_CMD); if (old_window == 0xffff) /* Chip suspended or ejected. */ @@ -2834,7 +2850,7 @@ static void vortex_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info) { - struct vortex_private *vp = dev->priv; + struct vortex_private *vp = netdev_priv(dev); strcpy(info->driver, DRV_NAME); strcpy(info->version, DRV_VERSION); @@ -2855,7 +2871,7 @@ static int vortex_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) { - struct vortex_private *vp = (struct vortex_private *)dev->priv; + struct vortex_private *vp = netdev_priv(dev); long ioaddr = dev->base_addr; struct mii_ioctl_data *data = (struct mii_ioctl_data *)&rq->ifr_data; int phy = vp->phys[0] & 0x1f; @@ -2942,7 +2958,7 @@ static int mdio_read(struct net_device *dev, int phy_id, int location) { - struct vortex_private *vp = (struct vortex_private *)dev->priv; + struct vortex_private *vp = netdev_priv(dev); int i; long ioaddr = dev->base_addr; int read_cmd = (0xf6 << 10) | (phy_id << 5) | location; @@ -2976,7 +2992,7 @@ static void mdio_write(struct net_device *dev, int phy_id, int location, int value) { - struct vortex_private *vp = (struct vortex_private *)dev->priv; + struct vortex_private *vp = netdev_priv(dev); long ioaddr = dev->base_addr; int write_cmd = 0x50020000 | (phy_id << 23) | (location << 18) | value; long mdio_addr = ioaddr + Wn4_PhysicalMgmt; @@ -3010,7 +3026,7 @@ /* Set Wake-On-LAN mode and put the board into D3 (power-down) state. */ static void acpi_set_WOL(struct net_device *dev) { - struct vortex_private *vp = (struct vortex_private *)dev->priv; + struct vortex_private *vp = netdev_priv(dev); long ioaddr = dev->base_addr; /* Power up on: 1==Downloaded Filter, 2==Magic Packets, 4==Link Status. */ @@ -3036,7 +3052,7 @@ BUG(); } - vp = dev->priv; + vp = netdev_priv(dev); /* AKPM: FIXME: we should have * if (vp->cb_fn_base) iounmap(vp->cb_fn_base); diff -Nru a/drivers/net/7990.c b/drivers/net/7990.c --- a/drivers/net/7990.c Sun Mar 14 14:20:08 2004 +++ b/drivers/net/7990.c Sun Mar 14 14:20:08 2004 @@ -99,7 +99,7 @@ /* Set up the Lance Rx and Tx rings and the init block */ static void lance_init_ring (struct net_device *dev) { - struct lance_private *lp = (struct lance_private *) dev->priv; + struct lance_private *lp = netdev_priv(dev); volatile struct lance_init_block *ib = lp->init_block; volatile struct lance_init_block *aib; /* for LANCE_ADDR computations */ int leptr; @@ -216,7 +216,7 @@ static int lance_reset (struct net_device *dev) { - struct lance_private *lp = (struct lance_private *)dev->priv; + struct lance_private *lp = netdev_priv(dev); int status; DECLARE_LL; @@ -236,7 +236,7 @@ static int lance_rx (struct net_device *dev) { - struct lance_private *lp = (struct lance_private *) dev->priv; + struct lance_private *lp = netdev_priv(dev); volatile struct lance_init_block *ib = lp->init_block; volatile struct lance_rx_desc *rd; unsigned char bits; @@ -316,7 +316,7 @@ static int lance_tx (struct net_device *dev) { - struct lance_private *lp = (struct lance_private *) dev->priv; + struct lance_private *lp = netdev_priv(dev); volatile struct lance_init_block *ib = lp->init_block; volatile struct lance_tx_desc *td; int i, j; @@ -401,7 +401,7 @@ lance_interrupt (int irq, void *dev_id, struct pt_regs *regs) { struct net_device *dev = (struct net_device *)dev_id; - struct lance_private *lp = (struct lance_private *)dev->priv; + struct lance_private *lp = netdev_priv(dev); int csr0; DECLARE_LL; @@ -457,7 +457,7 @@ int lance_open (struct net_device *dev) { - struct lance_private *lp = (struct lance_private *)dev->priv; + struct lance_private *lp = netdev_priv(dev); int res; DECLARE_LL; @@ -474,7 +474,7 @@ int lance_close (struct net_device *dev) { - struct lance_private *lp = (struct lance_private *) dev->priv; + struct lance_private *lp = netdev_priv(dev); DECLARE_LL; netif_stop_queue (dev); @@ -499,7 +499,7 @@ int lance_start_xmit (struct sk_buff *skb, struct net_device *dev) { - struct lance_private *lp = (struct lance_private *)dev->priv; + struct lance_private *lp = netdev_priv(dev); volatile struct lance_init_block *ib = lp->init_block; int entry, skblen, len; static int outs; @@ -556,7 +556,7 @@ struct net_device_stats *lance_get_stats (struct net_device *dev) { - struct lance_private *lp = (struct lance_private *) dev->priv; + struct lance_private *lp = netdev_priv(dev); return &lp->stats; } @@ -564,7 +564,7 @@ /* taken from the depca driver via a2065.c */ static void lance_load_multicast (struct net_device *dev) { - struct lance_private *lp = (struct lance_private *) dev->priv; + struct lance_private *lp = netdev_priv(dev); volatile struct lance_init_block *ib = lp->init_block; volatile u16 *mcast_table = (u16 *)&ib->filter; struct dev_mc_list *dmi=dev->mc_list; @@ -601,7 +601,7 @@ void lance_set_multicast (struct net_device *dev) { - struct lance_private *lp = (struct lance_private *) dev->priv; + struct lance_private *lp = netdev_priv(dev); volatile struct lance_init_block *ib = lp->init_block; int stopped; DECLARE_LL; diff -Nru a/drivers/net/8139too.c b/drivers/net/8139too.c --- a/drivers/net/8139too.c Sun Mar 14 14:20:05 2004 +++ b/drivers/net/8139too.c Sun Mar 14 14:20:05 2004 @@ -968,12 +968,11 @@ if (i < 0) return i; + assert (dev != NULL); tp = dev->priv; + assert (tp != NULL); ioaddr = tp->mmio_addr; - assert (ioaddr != NULL); - assert (dev != NULL); - assert (tp != NULL); addr_len = read_eeprom (ioaddr, 0, 8) == 0x8129 ? 8 : 6; for (i = 0; i < 3; i++) diff -Nru a/drivers/net/82596.c b/drivers/net/82596.c --- a/drivers/net/82596.c Sun Mar 14 14:20:08 2004 +++ b/drivers/net/82596.c Sun Mar 14 14:20:08 2004 @@ -458,7 +458,7 @@ static void i596_display_data(struct net_device *dev) { - struct i596_private *lp = (struct i596_private *) dev->priv; + struct i596_private *lp = netdev_priv(dev); struct i596_cmd *cmd; struct i596_rfd *rfd; struct i596_rbd *rbd; @@ -528,7 +528,7 @@ static inline void init_rx_bufs(struct net_device *dev) { - struct i596_private *lp = (struct i596_private *)dev->priv; + struct i596_private *lp = netdev_priv(dev); int i; struct i596_rfd *rfd; struct i596_rbd *rbd; @@ -579,7 +579,7 @@ static inline void remove_rx_bufs(struct net_device *dev) { - struct i596_private *lp = (struct i596_private *)dev->priv; + struct i596_private *lp = netdev_priv(dev); struct i596_rbd *rbd; int i; @@ -593,7 +593,7 @@ static void rebuild_rx_bufs(struct net_device *dev) { - struct i596_private *lp = (struct i596_private *) dev->priv; + struct i596_private *lp = netdev_priv(dev); int i; /* Ensure rx frame/buffer descriptors are tidy */ @@ -612,7 +612,7 @@ static int init_i596_mem(struct net_device *dev) { - struct i596_private *lp = (struct i596_private *) dev->priv; + struct i596_private *lp = netdev_priv(dev); #if !defined(ENABLE_MVME16x_NET) && !defined(ENABLE_BVME6000_NET) short ioaddr = dev->base_addr; #endif @@ -765,7 +765,7 @@ static inline int i596_rx(struct net_device *dev) { - struct i596_private *lp = (struct i596_private *)dev->priv; + struct i596_private *lp = netdev_priv(dev); struct i596_rfd *rfd; struct i596_rbd *rbd; int frames = 0; @@ -960,7 +960,7 @@ static void i596_add_cmd(struct net_device *dev, struct i596_cmd *cmd) { - struct i596_private *lp = (struct i596_private *) dev->priv; + struct i596_private *lp = netdev_priv(dev); int ioaddr = dev->base_addr; unsigned long flags; @@ -1030,7 +1030,7 @@ static void i596_tx_timeout (struct net_device *dev) { - struct i596_private *lp = (struct i596_private *) dev->priv; + struct i596_private *lp = netdev_priv(dev); int ioaddr = dev->base_addr; /* Transmitter timeout, serious problems. */ @@ -1059,7 +1059,7 @@ static int i596_start_xmit(struct sk_buff *skb, struct net_device *dev) { - struct i596_private *lp = (struct i596_private *) dev->priv; + struct i596_private *lp = netdev_priv(dev); struct tx_cmd *tx_cmd; struct i596_tbd *tbd; short length = skb->len; @@ -1245,7 +1245,7 @@ dev->priv = (void *)(dev->mem_start); - lp = (struct i596_private *) dev->priv; + lp = netdev_priv(dev); DEB(DEB_INIT,printk(KERN_DEBUG "%s: lp at 0x%08lx (%d bytes), lp->scb at 0x%08lx\n", dev->name, (unsigned long)lp, sizeof(struct i596_private), (unsigned long)&lp->scb)); @@ -1305,7 +1305,7 @@ } ioaddr = dev->base_addr; - lp = (struct i596_private *) dev->priv; + lp = netdev_priv(dev); spin_lock (&lp->lock); @@ -1448,7 +1448,7 @@ static int i596_close(struct net_device *dev) { - struct i596_private *lp = (struct i596_private *) dev->priv; + struct i596_private *lp = netdev_priv(dev); unsigned long flags; netif_stop_queue(dev); @@ -1495,7 +1495,7 @@ static struct net_device_stats * i596_get_stats(struct net_device *dev) { - struct i596_private *lp = (struct i596_private *) dev->priv; + struct i596_private *lp = netdev_priv(dev); return &lp->stats; } @@ -1506,7 +1506,7 @@ static void set_multicast_list(struct net_device *dev) { - struct i596_private *lp = (struct i596_private *) dev->priv; + struct i596_private *lp = netdev_priv(dev); int config = 0, cnt; DEB(DEB_MULTI,printk(KERN_DEBUG "%s: set multicast list, %d entries, promisc %s, allmulti %s\n", diff -Nru a/drivers/net/8390.c b/drivers/net/8390.c --- a/drivers/net/8390.c Sun Mar 14 14:20:06 2004 +++ b/drivers/net/8390.c Sun Mar 14 14:20:06 2004 @@ -516,6 +516,15 @@ return IRQ_RETVAL(nr_serviced > 0); } +#ifdef CONFIG_NET_POLL_CONTROLLER +void ei_poll(struct net_device *dev) +{ + disable_irq(dev->irq); + ei_interrupt(dev->irq, dev, NULL); + enable_irq(dev->irq); +} +#endif + /** * ei_tx_err - handle transmitter error * @dev: network device which threw the exception @@ -1124,6 +1133,9 @@ EXPORT_SYMBOL(ei_open); EXPORT_SYMBOL(ei_close); EXPORT_SYMBOL(ei_interrupt); +#ifdef CONFIG_NET_POLL_CONTROLLER +EXPORT_SYMBOL(ei_poll); +#endif EXPORT_SYMBOL(ei_tx_timeout); EXPORT_SYMBOL(NS8390_init); EXPORT_SYMBOL(__alloc_ei_netdev); diff -Nru a/drivers/net/8390.h b/drivers/net/8390.h --- a/drivers/net/8390.h Sun Mar 14 14:20:07 2004 +++ b/drivers/net/8390.h Sun Mar 14 14:20:07 2004 @@ -39,6 +39,10 @@ #define ei_debug 1 #endif +#ifdef CONFIG_NET_POLL_CONTROLLER +extern void ei_poll(struct net_device *dev); +#endif + extern void NS8390_init(struct net_device *dev, int startp); extern int ei_open(struct net_device *dev); extern int ei_close(struct net_device *dev); diff -Nru a/drivers/net/Kconfig b/drivers/net/Kconfig --- a/drivers/net/Kconfig Sun Mar 14 14:20:08 2004 +++ b/drivers/net/Kconfig Sun Mar 14 14:20:08 2004 @@ -2495,6 +2495,13 @@ To compile this driver as a module, choose M here: the module will be called shaper. If unsure, say N. +config NETCONSOLE + tristate "Network console logging support (EXPERIMENTAL)" + depends on NETDEVICES && EXPERIMENTAL + ---help--- + If you want to log kernel messages over the network, enable this. + See Documentation/networking/netconsole.txt for details. + source "drivers/net/wan/Kconfig" source "drivers/net/pcmcia/Kconfig" diff -Nru a/drivers/net/Makefile b/drivers/net/Makefile --- a/drivers/net/Makefile Sun Mar 14 14:20:06 2004 +++ b/drivers/net/Makefile Sun Mar 14 14:20:06 2004 @@ -188,3 +188,4 @@ obj-$(CONFIG_HAMRADIO) += hamradio/ obj-$(CONFIG_IRDA) += irda/ +obj-$(CONFIG_NETCONSOLE) += netconsole.o diff -Nru a/drivers/net/a2065.c b/drivers/net/a2065.c --- a/drivers/net/a2065.c Sun Mar 14 14:20:07 2004 +++ b/drivers/net/a2065.c Sun Mar 14 14:20:07 2004 @@ -164,7 +164,7 @@ /* Setup the Lance Rx and Tx rings */ static void lance_init_ring (struct net_device *dev) { - struct lance_private *lp = (struct lance_private *) dev->priv; + struct lance_private *lp = netdev_priv(dev); volatile struct lance_init_block *ib = lp->init_block; volatile struct lance_init_block *aib; /* for LANCE_ADDR computations */ int leptr; @@ -265,7 +265,7 @@ static int lance_rx (struct net_device *dev) { - struct lance_private *lp = (struct lance_private *) dev->priv; + struct lance_private *lp = netdev_priv(dev); volatile struct lance_init_block *ib = lp->init_block; volatile struct lance_regs *ll = lp->ll; volatile struct lance_rx_desc *rd; @@ -342,7 +342,7 @@ static int lance_tx (struct net_device *dev) { - struct lance_private *lp = (struct lance_private *) dev->priv; + struct lance_private *lp = netdev_priv(dev); volatile struct lance_init_block *ib = lp->init_block; volatile struct lance_regs *ll = lp->ll; volatile struct lance_tx_desc *td; @@ -433,7 +433,7 @@ dev = (struct net_device *) dev_id; - lp = (struct lance_private *) dev->priv; + lp = netdev_priv(dev); ll = lp->ll; ll->rap = LE_CSR0; /* LANCE Controller Status */ @@ -481,7 +481,7 @@ static int lance_open (struct net_device *dev) { - struct lance_private *lp = (struct lance_private *)dev->priv; + struct lance_private *lp = netdev_priv(dev); volatile struct lance_regs *ll = lp->ll; int ret; @@ -506,7 +506,7 @@ static int lance_close (struct net_device *dev) { - struct lance_private *lp = (struct lance_private *) dev->priv; + struct lance_private *lp = netdev_priv(dev); volatile struct lance_regs *ll = lp->ll; netif_stop_queue(dev); @@ -522,7 +522,7 @@ static inline int lance_reset (struct net_device *dev) { - struct lance_private *lp = (struct lance_private *)dev->priv; + struct lance_private *lp = netdev_priv(dev); volatile struct lance_regs *ll = lp->ll; int status; @@ -545,7 +545,7 @@ static void lance_tx_timeout(struct net_device *dev) { - struct lance_private *lp = (struct lance_private *) dev->priv; + struct lance_private *lp = netdev_priv(dev); volatile struct lance_regs *ll = lp->ll; printk(KERN_ERR "%s: transmit timed out, status %04x, reset\n", @@ -556,7 +556,7 @@ static int lance_start_xmit (struct sk_buff *skb, struct net_device *dev) { - struct lance_private *lp = (struct lance_private *)dev->priv; + struct lance_private *lp = netdev_priv(dev); volatile struct lance_regs *ll = lp->ll; volatile struct lance_init_block *ib = lp->init_block; int entry, skblen, len; @@ -624,7 +624,7 @@ static struct net_device_stats *lance_get_stats (struct net_device *dev) { - struct lance_private *lp = (struct lance_private *) dev->priv; + struct lance_private *lp = netdev_priv(dev); return &lp->stats; } @@ -632,7 +632,7 @@ /* taken from the depca driver */ static void lance_load_multicast (struct net_device *dev) { - struct lance_private *lp = (struct lance_private *) dev->priv; + struct lance_private *lp = netdev_priv(dev); volatile struct lance_init_block *ib = lp->init_block; volatile u16 *mcast_table = (u16 *)&ib->filter; struct dev_mc_list *dmi=dev->mc_list; @@ -668,7 +668,7 @@ static void lance_set_multicast (struct net_device *dev) { - struct lance_private *lp = (struct lance_private *) dev->priv; + struct lance_private *lp = netdev_priv(dev); volatile struct lance_init_block *ib = lp->init_block; volatile struct lance_regs *ll = lp->ll; @@ -748,7 +748,7 @@ } SET_MODULE_OWNER(dev); - priv = dev->priv; + priv = netdev_priv(dev); r1->name = dev->name; r2->name = dev->name; diff -Nru a/drivers/net/ac3200.c b/drivers/net/ac3200.c --- a/drivers/net/ac3200.c Sun Mar 14 14:20:07 2004 +++ b/drivers/net/ac3200.c Sun Mar 14 14:20:07 2004 @@ -276,6 +276,9 @@ dev->open = &ac_open; dev->stop = &ac_close_card; +#ifdef CONFIG_NET_POLL_CONTROLLER + dev->poll_controller = ei_poll; +#endif NS8390_init(dev, 0); return 0; out1: diff -Nru a/drivers/net/amd8111e.c b/drivers/net/amd8111e.c --- a/drivers/net/amd8111e.c Sun Mar 14 14:20:07 2004 +++ b/drivers/net/amd8111e.c Sun Mar 14 14:20:07 2004 @@ -174,7 +174,7 @@ */ static int amd8111e_mdio_read(struct net_device * dev, int phy_id, int reg_num) { - struct amd8111e_priv* lp = dev->priv; + struct amd8111e_priv* lp = netdev_priv(dev); unsigned int reg_val; amd8111e_read_phy(lp,phy_id,reg_num,®_val); @@ -187,7 +187,7 @@ */ static void amd8111e_mdio_write(struct net_device * dev, int phy_id, int reg_num, int val) { - struct amd8111e_priv* lp = dev->priv; + struct amd8111e_priv* lp = netdev_priv(dev); amd8111e_write_phy(lp, phy_id, reg_num, val); } @@ -197,7 +197,7 @@ */ static void amd8111e_set_ext_phy(struct net_device *dev) { - struct amd8111e_priv *lp = (struct amd8111e_priv *)dev->priv; + struct amd8111e_priv *lp = netdev_priv(dev); u32 bmcr,advert,tmp; /* Determine mii register values to set the speed */ @@ -239,7 +239,7 @@ */ static int amd8111e_free_skbs(struct net_device *dev) { - struct amd8111e_priv *lp = (struct amd8111e_priv *)dev->priv; + struct amd8111e_priv *lp = netdev_priv(dev); struct sk_buff* rx_skbuff; int i; @@ -272,7 +272,7 @@ */ static inline void amd8111e_set_rx_buff_len(struct net_device* dev) { - struct amd8111e_priv* lp = dev->priv; + struct amd8111e_priv* lp = netdev_priv(dev); unsigned int mtu = dev->mtu; if (mtu > ETH_DATA_LEN){ @@ -290,7 +290,7 @@ */ static int amd8111e_init_ring(struct net_device *dev) { - struct amd8111e_priv *lp = (struct amd8111e_priv *)dev->priv; + struct amd8111e_priv *lp = netdev_priv(dev); int i; lp->rx_idx = lp->tx_idx = 0; @@ -371,7 +371,7 @@ unsigned int timeout; unsigned int event_count; - struct amd8111e_priv *lp = dev->priv; + struct amd8111e_priv *lp = netdev_priv(dev); void* mmio = lp->mmio; struct amd8111e_coalesce_conf * coal_conf = &lp->coal_conf; @@ -429,7 +429,7 @@ */ static int amd8111e_restart(struct net_device *dev) { - struct amd8111e_priv *lp = (struct amd8111e_priv* )dev->priv; + struct amd8111e_priv *lp = netdev_priv(dev); void * mmio = lp->mmio; int i,reg_val; @@ -663,7 +663,7 @@ */ static int amd8111e_tx(struct net_device *dev) { - struct amd8111e_priv* lp = dev->priv; + struct amd8111e_priv* lp = netdev_priv(dev); int tx_index = lp->tx_complete_idx & TX_RING_DR_MOD_MASK; int status; /* Complete all the transmit packet */ @@ -705,7 +705,7 @@ */ static int amd8111e_rx(struct net_device *dev) { - struct amd8111e_priv *lp = dev->priv; + struct amd8111e_priv *lp = netdev_priv(dev); struct sk_buff *skb,*new_skb; int rx_index = lp->rx_idx & RX_RING_DR_MOD_MASK; int min_pkt_len, status; @@ -809,7 +809,7 @@ */ static int amd8111e_link_change(struct net_device* dev) { - struct amd8111e_priv *lp = dev->priv; + struct amd8111e_priv *lp = netdev_priv(dev); int status0,speed; /* read the link change */ @@ -871,7 +871,7 @@ */ static struct net_device_stats *amd8111e_get_stats(struct net_device * dev) { - struct amd8111e_priv *lp = dev->priv; + struct amd8111e_priv *lp = netdev_priv(dev); void * mmio = lp->mmio; unsigned long flags; /* struct net_device_stats *prev_stats = &lp->prev_stats; */ @@ -966,7 +966,7 @@ */ static int amd8111e_calc_coalesce(struct net_device *dev) { - struct amd8111e_priv *lp = dev->priv; + struct amd8111e_priv *lp = netdev_priv(dev); struct amd8111e_coalesce_conf * coal_conf = &lp->coal_conf; int tx_pkt_rate; int rx_pkt_rate; @@ -1102,7 +1102,7 @@ { struct net_device * dev = (struct net_device *) dev_id; - struct amd8111e_priv *lp = dev->priv; + struct amd8111e_priv *lp = netdev_priv(dev); void * mmio = lp->mmio; unsigned int intr0; unsigned int handled = 1; @@ -1153,12 +1153,23 @@ return IRQ_RETVAL(handled); } +#ifdef CONFIG_NET_POLL_CONTROLLER +static void amd8111e_poll(struct net_device *dev) +{ + unsigned long flags; + local_save_flags(flags); + local_irq_disable(); + amd8111e_interrupt(0, dev, NULL); + local_irq_restore(flags); +} +#endif + /* This function closes the network interface and updates the statistics so that most recent statistics will be available after the interface is down. */ static int amd8111e_close(struct net_device * dev) { - struct amd8111e_priv *lp = dev->priv; + struct amd8111e_priv *lp = netdev_priv(dev); netif_stop_queue(dev); spin_lock_irq(&lp->lock); @@ -1185,7 +1196,7 @@ */ static int amd8111e_open(struct net_device * dev ) { - struct amd8111e_priv *lp = (struct amd8111e_priv *)dev->priv; + struct amd8111e_priv *lp = netdev_priv(dev); if(dev->irq ==0 || request_irq(dev->irq, amd8111e_interrupt, SA_SHIRQ, dev->name, dev)) @@ -1231,7 +1242,7 @@ static int amd8111e_start_xmit(struct sk_buff *skb, struct net_device * dev) { - struct amd8111e_priv *lp = dev->priv; + struct amd8111e_priv *lp = netdev_priv(dev); int tx_index; unsigned long flags; @@ -1338,7 +1349,7 @@ static void amd8111e_set_multicast_list(struct net_device *dev) { struct dev_mc_list* mc_ptr; - struct amd8111e_priv *lp = dev->priv; + struct amd8111e_priv *lp = netdev_priv(dev); u32 mc_filter[2] ; int i,bit_num; if(dev->flags & IFF_PROMISC){ @@ -1388,7 +1399,7 @@ static int amd8111e_ethtool_ioctl(struct net_device* dev, void* useraddr) { - struct amd8111e_priv *lp = dev->priv; + struct amd8111e_priv *lp = netdev_priv(dev); struct pci_dev *pci_dev = lp->pci_dev; u32 ethcmd; @@ -1510,7 +1521,7 @@ static int amd8111e_ioctl(struct net_device * dev , struct ifreq *ifr, int cmd) { struct mii_ioctl_data *data = (struct mii_ioctl_data *)&ifr->ifr_data; - struct amd8111e_priv *lp = dev->priv; + struct amd8111e_priv *lp = netdev_priv(dev); int err; u32 mii_regval; @@ -1554,7 +1565,7 @@ */ int amd8111e_change_mtu(struct net_device *dev, int new_mtu) { - struct amd8111e_priv *lp = dev->priv; + struct amd8111e_priv *lp = netdev_priv(dev); int err; if ((new_mtu < AMD8111E_MIN_MTU) || (new_mtu > AMD8111E_MAX_MTU)) @@ -1584,7 +1595,7 @@ #if AMD8111E_VLAN_TAG_USED static void amd8111e_vlan_rx_register(struct net_device *dev, struct vlan_group *grp) { - struct amd8111e_priv *lp = dev->priv; + struct amd8111e_priv *lp = netdev_priv(dev); spin_lock_irq(&lp->lock); lp->vlgrp = grp; spin_unlock_irq(&lp->lock); @@ -1592,7 +1603,7 @@ static void amd8111e_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid) { - struct amd8111e_priv *lp = dev->priv; + struct amd8111e_priv *lp = netdev_priv(dev); spin_lock_irq(&lp->lock); if (lp->vlgrp) lp->vlgrp->vlan_devices[vid] = NULL; @@ -1623,7 +1634,7 @@ static void amd8111e_tx_timeout(struct net_device *dev) { - struct amd8111e_priv* lp = dev->priv; + struct amd8111e_priv* lp = netdev_priv(dev); int err; printk(KERN_ERR "%s: transmit timed out, resetting\n", @@ -1637,7 +1648,7 @@ static int amd8111e_suspend(struct pci_dev *pci_dev, u32 state) { struct net_device *dev = pci_get_drvdata(pci_dev); - struct amd8111e_priv *lp = dev->priv; + struct amd8111e_priv *lp = netdev_priv(dev); if (!netif_running(dev)) return 0; @@ -1680,7 +1691,7 @@ static int amd8111e_resume(struct pci_dev *pci_dev) { struct net_device *dev = pci_get_drvdata(pci_dev); - struct amd8111e_priv *lp = dev->priv; + struct amd8111e_priv *lp = netdev_priv(dev); if (!netif_running(dev)) return 0; @@ -1719,7 +1730,7 @@ } static void amd8111e_config_ipg(struct net_device* dev) { - struct amd8111e_priv *lp = dev->priv; + struct amd8111e_priv *lp = netdev_priv(dev); struct ipg_info* ipg_data = &lp->ipg_data; void * mmio = lp->mmio; unsigned int prev_col_cnt = ipg_data->col_cnt; @@ -1841,7 +1852,7 @@ dev->vlan_rx_kill_vid = amd8111e_vlan_rx_kill_vid; #endif - lp = dev->priv; + lp = netdev_priv(dev); lp->pci_dev = pdev; lp->amd8111e_net_dev = dev; lp->pm_cap = pm_cap; @@ -1884,6 +1895,9 @@ dev->irq =pdev->irq; dev->tx_timeout = amd8111e_tx_timeout; dev->watchdog_timeo = AMD8111E_TX_TIMEOUT; +#ifdef CONFIG_NET_POLL_CONTROLLER + dev->poll_controller = amd8111e_poll; +#endif #if AMD8111E_VLAN_TAG_USED dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX; diff -Nru a/drivers/net/apne.c b/drivers/net/apne.c --- a/drivers/net/apne.c Sun Mar 14 14:20:08 2004 +++ b/drivers/net/apne.c Sun Mar 14 14:20:08 2004 @@ -333,6 +333,9 @@ ei_status.get_8390_hdr = &apne_get_8390_hdr; dev->open = &apne_open; dev->stop = &apne_close; +#ifdef CONFIG_NET_POLL_CONTROLLER + dev->poll_controller = ei_poll; +#endif NS8390_init(dev, 0); pcmcia_ack_int(pcmcia_get_intreq()); /* ack PCMCIA int req */ diff -Nru a/drivers/net/appletalk/cops.c b/drivers/net/appletalk/cops.c --- a/drivers/net/appletalk/cops.c Sun Mar 14 14:20:07 2004 +++ b/drivers/net/appletalk/cops.c Sun Mar 14 14:20:07 2004 @@ -333,7 +333,7 @@ dev->base_addr = ioaddr; - lp = (struct cops_local *)dev->priv; + lp = netdev_priv(dev); memset(lp, 0, sizeof(struct cops_local)); spin_lock_init(&lp->lock); @@ -422,7 +422,7 @@ */ static int cops_open(struct net_device *dev) { - struct cops_local *lp = (struct cops_local *)dev->priv; + struct cops_local *lp = netdev_priv(dev); if(dev->irq==0) { @@ -456,7 +456,7 @@ */ static int cops_jumpstart(struct net_device *dev) { - struct cops_local *lp = (struct cops_local *)dev->priv; + struct cops_local *lp = netdev_priv(dev); /* * Once the card has the firmware loaded and has acquired @@ -490,7 +490,7 @@ */ static void cops_reset(struct net_device *dev, int sleep) { - struct cops_local *lp = (struct cops_local *)dev->priv; + struct cops_local *lp = netdev_priv(dev); int ioaddr=dev->base_addr; if(lp->board==TANGENT) @@ -525,7 +525,7 @@ { struct ifreq ifr; struct ltfirmware *ltf= (struct ltfirmware *)&ifr.ifr_data; - struct cops_local *lp=(struct cops_local *)dev->priv; + struct cops_local *lp = netdev_priv(dev); int ioaddr=dev->base_addr; int length, i = 0; @@ -618,7 +618,7 @@ */ static int cops_nodeid (struct net_device *dev, int nodeid) { - struct cops_local *lp = (struct cops_local *) dev->priv; + struct cops_local *lp = netdev_priv(dev); int ioaddr = dev->base_addr; if(lp->board == DAYNA) @@ -730,7 +730,7 @@ int boguscount = 0; ioaddr = dev->base_addr; - lp = (struct cops_local *)dev->priv; + lp = netdev_priv(dev); if(lp->board==DAYNA) { @@ -765,7 +765,7 @@ int pkt_len = 0; int rsp_type = 0; struct sk_buff *skb = NULL; - struct cops_local *lp = dev->priv; + struct cops_local *lp = netdev_priv(dev); int ioaddr = dev->base_addr; int boguscount = 0; unsigned long flags; @@ -869,7 +869,7 @@ static void cops_timeout(struct net_device *dev) { - struct cops_local *lp = (struct cops_local *)dev->priv; + struct cops_local *lp = netdev_priv(dev); int ioaddr = dev->base_addr; lp->stats.tx_errors++; @@ -891,7 +891,7 @@ static int cops_send_packet(struct sk_buff *skb, struct net_device *dev) { - struct cops_local *lp = (struct cops_local *)dev->priv; + struct cops_local *lp = netdev_priv(dev); int ioaddr = dev->base_addr; unsigned long flags; @@ -966,7 +966,7 @@ static int cops_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) { - struct cops_local *lp = (struct cops_local *)dev->priv; + struct cops_local *lp = netdev_priv(dev); struct sockaddr_at *sa = (struct sockaddr_at *)&ifr->ifr_addr; struct atalk_addr *aa = (struct atalk_addr *)&lp->node_addr; @@ -1002,7 +1002,7 @@ static int cops_close(struct net_device *dev) { - struct cops_local *lp = (struct cops_local *)dev->priv; + struct cops_local *lp = netdev_priv(dev); /* If we were running polled, yank the timer. */ @@ -1019,7 +1019,7 @@ */ static struct net_device_stats *cops_get_stats(struct net_device *dev) { - struct cops_local *lp = (struct cops_local *)dev->priv; + struct cops_local *lp = netdev_priv(dev); return &lp->stats; } diff -Nru a/drivers/net/ariadne.c b/drivers/net/ariadne.c --- a/drivers/net/ariadne.c Sun Mar 14 14:20:07 2004 +++ b/drivers/net/ariadne.c Sun Mar 14 14:20:07 2004 @@ -184,7 +184,7 @@ } SET_MODULE_OWNER(dev); - priv = dev->priv; + priv = netdev_priv(dev); r1->name = dev->name; r2->name = dev->name; @@ -333,7 +333,7 @@ static void ariadne_init_ring(struct net_device *dev) { - struct ariadne_private *priv = (struct ariadne_private *)dev->priv; + struct ariadne_private *priv = netdev_priv(dev); volatile struct lancedata *lancedata = (struct lancedata *)dev->mem_start; int i; @@ -379,7 +379,7 @@ static int ariadne_close(struct net_device *dev) { - struct ariadne_private *priv = (struct ariadne_private *)dev->priv; + struct ariadne_private *priv = netdev_priv(dev); volatile struct Am79C960 *lance = (struct Am79C960*)dev->base_addr; netif_stop_queue(dev); @@ -434,7 +434,7 @@ if (!(lance->RDP & INTR)) /* Check if any interrupt has been */ return IRQ_NONE; /* generated by the board. */ - priv = (struct ariadne_private *)dev->priv; + priv = netdev_priv(dev); boguscnt = 10; while ((csr0 = lance->RDP) & (ERR|RINT|TINT) && --boguscnt >= 0) { @@ -589,7 +589,7 @@ static int ariadne_start_xmit(struct sk_buff *skb, struct net_device *dev) { - struct ariadne_private *priv = (struct ariadne_private *)dev->priv; + struct ariadne_private *priv = netdev_priv(dev); volatile struct Am79C960 *lance = (struct Am79C960*)dev->base_addr; int entry; unsigned long flags; @@ -697,7 +697,7 @@ static int ariadne_rx(struct net_device *dev) { - struct ariadne_private *priv = (struct ariadne_private *)dev->priv; + struct ariadne_private *priv = netdev_priv(dev); int entry = priv->cur_rx % RX_RING_SIZE; int i; @@ -787,7 +787,7 @@ static struct net_device_stats *ariadne_get_stats(struct net_device *dev) { - struct ariadne_private *priv = (struct ariadne_private *)dev->priv; + struct ariadne_private *priv = netdev_priv(dev); volatile struct Am79C960 *lance = (struct Am79C960*)dev->base_addr; short saved_addr; unsigned long flags; diff -Nru a/drivers/net/arm/am79c961a.c b/drivers/net/arm/am79c961a.c --- a/drivers/net/arm/am79c961a.c Sun Mar 14 14:20:08 2004 +++ b/drivers/net/arm/am79c961a.c Sun Mar 14 14:20:08 2004 @@ -196,7 +196,7 @@ static void am79c961_init_for_open(struct net_device *dev) { - struct dev_priv *priv = (struct dev_priv *)dev->priv; + struct dev_priv *priv = netdev_priv(dev); unsigned long flags; unsigned char *p; u_int hdr_addr, first_free_addr; @@ -271,7 +271,7 @@ static void am79c961_timer(unsigned long data) { struct net_device *dev = (struct net_device *)data; - struct dev_priv *priv = (struct dev_priv *)dev->priv; + struct dev_priv *priv = netdev_priv(dev); unsigned int lnkstat, carrier; lnkstat = read_ireg(dev->base_addr, ISALED0) & ISALED0_LNKST; @@ -291,7 +291,7 @@ static int am79c961_open(struct net_device *dev) { - struct dev_priv *priv = (struct dev_priv *)dev->priv; + struct dev_priv *priv = netdev_priv(dev); int ret; memset (&priv->stats, 0, sizeof (priv->stats)); @@ -318,7 +318,7 @@ static int am79c961_close(struct net_device *dev) { - struct dev_priv *priv = (struct dev_priv *)dev->priv; + struct dev_priv *priv = netdev_priv(dev); unsigned long flags; del_timer_sync(&priv->timer); @@ -341,7 +341,7 @@ */ static struct net_device_stats *am79c961_getstats (struct net_device *dev) { - struct dev_priv *priv = (struct dev_priv *)dev->priv; + struct dev_priv *priv = netdev_priv(dev); return &priv->stats; } @@ -365,7 +365,7 @@ */ static void am79c961_setmulticastlist (struct net_device *dev) { - struct dev_priv *priv = (struct dev_priv *)dev->priv; + struct dev_priv *priv = netdev_priv(dev); unsigned long flags; unsigned short multi_hash[4], mode; int i, stopped; @@ -444,7 +444,7 @@ static int am79c961_sendpacket(struct sk_buff *skb, struct net_device *dev) { - struct dev_priv *priv = (struct dev_priv *)dev->priv; + struct dev_priv *priv = netdev_priv(dev); unsigned int hdraddr, bufaddr; unsigned int head; unsigned long flags; @@ -593,7 +593,7 @@ am79c961_interrupt(int irq, void *dev_id, struct pt_regs *regs) { struct net_device *dev = (struct net_device *)dev_id; - struct dev_priv *priv = (struct dev_priv *)dev->priv; + struct dev_priv *priv = netdev_priv(dev); u_int status, n = 100; int handled = 0; @@ -630,7 +630,7 @@ static int am79c961_hw_init(struct net_device *dev) { - struct dev_priv *priv = (struct dev_priv *)dev->priv; + struct dev_priv *priv = netdev_priv(dev); spin_lock_irq(&priv->chip_lock); write_rreg (dev->base_addr, CSR0, CSR0_STOP); @@ -662,7 +662,7 @@ if (!dev) goto out; - priv = dev->priv; + priv = netdev_priv(dev); /* * Fixed address and IRQ lines here. diff -Nru a/drivers/net/arm/ether1.c b/drivers/net/arm/ether1.c --- a/drivers/net/arm/ether1.c Sun Mar 14 14:20:07 2004 +++ b/drivers/net/arm/ether1.c Sun Mar 14 14:20:07 2004 @@ -447,7 +447,7 @@ static int ether1_init_for_open (struct net_device *dev) { - struct ether1_priv *priv = (struct ether1_priv *)dev->priv; + struct ether1_priv *priv = netdev_priv(dev); int i, status, addr, next, next2; int failures = 0; unsigned long timeout; @@ -616,7 +616,7 @@ static int ether1_txalloc (struct net_device *dev, int size) { - struct ether1_priv *priv = (struct ether1_priv *)dev->priv; + struct ether1_priv *priv = netdev_priv(dev); int start, tail; size = (size + 1) & ~1; @@ -642,7 +642,7 @@ static int ether1_open (struct net_device *dev) { - struct ether1_priv *priv = (struct ether1_priv *)dev->priv; + struct ether1_priv *priv = netdev_priv(dev); if (!is_valid_ether_addr(dev->dev_addr)) { printk(KERN_WARNING "%s: invalid ethernet MAC address\n", @@ -668,7 +668,7 @@ static void ether1_timeout(struct net_device *dev) { - struct ether1_priv *priv = (struct ether1_priv *)dev->priv; + struct ether1_priv *priv = netdev_priv(dev); printk(KERN_WARNING "%s: transmit timeout, network cable problem?\n", dev->name); @@ -686,7 +686,7 @@ static int ether1_sendpacket (struct sk_buff *skb, struct net_device *dev) { - struct ether1_priv *priv = (struct ether1_priv *)dev->priv; + struct ether1_priv *priv = netdev_priv(dev); int tmp, tst, nopaddr, txaddr, tbdaddr, dataddr; unsigned long flags; tx_t tx; @@ -762,7 +762,7 @@ static void ether1_xmit_done (struct net_device *dev) { - struct ether1_priv *priv = (struct ether1_priv *)dev->priv; + struct ether1_priv *priv = netdev_priv(dev); nop_t nop; int caddr, tst; @@ -863,7 +863,7 @@ static void ether1_recv_done (struct net_device *dev) { - struct ether1_priv *priv = (struct ether1_priv *)dev->priv; + struct ether1_priv *priv = netdev_priv(dev); int status; int nexttail, rbdaddr; rbd_t rbd; @@ -919,7 +919,7 @@ ether1_interrupt (int irq, void *dev_id, struct pt_regs *regs) { struct net_device *dev = (struct net_device *)dev_id; - struct ether1_priv *priv = (struct ether1_priv *)dev->priv; + struct ether1_priv *priv = netdev_priv(dev); int status; status = ether1_inw (dev, SCB_ADDR, scb_t, scb_status, NORMALIRQS); @@ -978,7 +978,7 @@ static struct net_device_stats * ether1_getstats (struct net_device *dev) { - struct ether1_priv *priv = (struct ether1_priv *)dev->priv; + struct ether1_priv *priv = netdev_priv(dev); return &priv->stats; } @@ -1030,7 +1030,7 @@ request_region(dev->base_addr, 16, dev->name); request_region(dev->base_addr + 0x800, 4096, dev->name); - priv = (struct ether1_priv *)dev->priv; + priv = netdev_priv(dev); if ((priv->bus_type = ether1_reset(dev)) == 0) { ret = -ENODEV; goto release; diff -Nru a/drivers/net/arm/ether3.c b/drivers/net/arm/ether3.c --- a/drivers/net/arm/ether3.c Sun Mar 14 14:20:08 2004 +++ b/drivers/net/arm/ether3.c Sun Mar 14 14:20:08 2004 @@ -121,7 +121,7 @@ static int ether3_setbuffer(struct net_device *dev, buffer_rw_t read, int start) { - struct dev_priv *priv = (struct dev_priv *)dev->priv; + struct dev_priv *priv = netdev_priv(dev); int timeout = 1000; ether3_outw(priv->regs.config1 | CFG1_LOCBUFMEM, REG_CONFIG1); @@ -180,7 +180,7 @@ ether3_ledoff(unsigned long data) { struct net_device *dev = (struct net_device *)data; - struct dev_priv *priv = (struct dev_priv *)dev->priv; + struct dev_priv *priv = netdev_priv(dev); ether3_outw(priv->regs.config2 |= CFG2_CTRLO, REG_CONFIG2); } @@ -280,7 +280,7 @@ static int __init ether3_init_2(struct net_device *dev) { - struct dev_priv *priv = (struct dev_priv *)dev->priv; + struct dev_priv *priv = netdev_priv(dev); int i; priv->regs.config1 = CFG1_RECVCOMPSTAT0|CFG1_DMABURST8; @@ -330,7 +330,7 @@ static void ether3_init_for_open(struct net_device *dev) { - struct dev_priv *priv = (struct dev_priv *)dev->priv; + struct dev_priv *priv = netdev_priv(dev); int i; memset(&priv->stats, 0, sizeof(struct net_device_stats)); @@ -434,7 +434,7 @@ static int ether3_close(struct net_device *dev) { - struct dev_priv *priv = (struct dev_priv *)dev->priv; + struct dev_priv *priv = netdev_priv(dev); netif_stop_queue(dev); @@ -457,7 +457,7 @@ */ static struct net_device_stats *ether3_getstats(struct net_device *dev) { - struct dev_priv *priv = (struct dev_priv *)dev->priv; + struct dev_priv *priv = netdev_priv(dev); return &priv->stats; } @@ -469,7 +469,7 @@ */ static void ether3_setmulticastlist(struct net_device *dev) { - struct dev_priv *priv = (struct dev_priv *)dev->priv; + struct dev_priv *priv = netdev_priv(dev); priv->regs.config1 &= ~CFG1_RECVPROMISC; @@ -487,7 +487,7 @@ static void ether3_timeout(struct net_device *dev) { - struct dev_priv *priv = (struct dev_priv *)dev->priv; + struct dev_priv *priv = netdev_priv(dev); unsigned long flags; del_timer(&priv->timer); @@ -518,7 +518,7 @@ static int ether3_sendpacket(struct sk_buff *skb, struct net_device *dev) { - struct dev_priv *priv = (struct dev_priv *)dev->priv; + struct dev_priv *priv = netdev_priv(dev); unsigned long flags; unsigned int length = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN; unsigned int ptr, next_ptr; @@ -594,7 +594,7 @@ printk("eth3irq: %d ", irq); #endif - priv = (struct dev_priv *)dev->priv; + priv = netdev_priv(dev); status = ether3_inw(REG_STATUS); @@ -844,7 +844,7 @@ goto free; } - priv = (struct dev_priv *) dev->priv; + priv = netdev_priv(dev); init_timer(&priv->timer); /* Reset card... diff -Nru a/drivers/net/arm/etherh.c b/drivers/net/arm/etherh.c --- a/drivers/net/arm/etherh.c Sun Mar 14 14:20:08 2004 +++ b/drivers/net/arm/etherh.c Sun Mar 14 14:20:08 2004 @@ -144,7 +144,7 @@ static void etherh_setif(struct net_device *dev) { - struct etherh_priv *eh = (struct etherh_priv *)dev->priv; + struct etherh_priv *eh = netdev_priv(dev); struct ei_device *ei_local = &eh->eidev; unsigned long addr, flags; @@ -188,7 +188,7 @@ static int etherh_getifstat(struct net_device *dev) { - struct etherh_priv *eh = (struct etherh_priv *)dev->priv; + struct etherh_priv *eh = netdev_priv(dev); struct ei_device *ei_local = &eh->eidev; int stat = 0; @@ -256,7 +256,7 @@ static void etherh_reset(struct net_device *dev) { - struct ei_device *ei_local = (struct ei_device *) dev->priv; + struct ei_device *ei_local = netdev_priv(dev); outb_p(E8390_NODMA+E8390_PAGE0+E8390_STOP, dev->base_addr); @@ -283,7 +283,7 @@ static void etherh_block_output (struct net_device *dev, int count, const unsigned char *buf, int start_page) { - struct ei_device *ei_local = (struct ei_device *) dev->priv; + struct ei_device *ei_local = netdev_priv(dev); unsigned int addr, dma_addr; unsigned long dma_start; @@ -349,7 +349,7 @@ static void etherh_block_input (struct net_device *dev, int count, struct sk_buff *skb, int ring_offset) { - struct ei_device *ei_local = (struct ei_device *) dev->priv; + struct ei_device *ei_local = netdev_priv(dev); unsigned int addr, dma_addr; unsigned char *buf; @@ -390,7 +390,7 @@ static void etherh_get_header (struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_page) { - struct ei_device *ei_local = (struct ei_device *) dev->priv; + struct ei_device *ei_local = netdev_priv(dev); unsigned int addr, dma_addr; if (ei_local->dmaing) { @@ -432,7 +432,7 @@ static int etherh_open(struct net_device *dev) { - struct ei_device *ei_local = (struct ei_device *) dev->priv; + struct ei_device *ei_local = netdev_priv(dev); if (!is_valid_ether_addr(dev->dev_addr)) { printk(KERN_WARNING "%s: invalid ethernet MAC address\n", @@ -557,7 +557,7 @@ goto out; } - eh = dev->priv; + eh = netdev_priv(dev); spin_lock_init(&eh->eidev.page_lock); @@ -653,7 +653,7 @@ break; } - ei_local = (struct ei_device *) dev->priv; + ei_local = netdev_priv(dev); if (ec->cid.product == PROD_ANT_ETHERM) { ei_local->tx_start_page = ETHERM_TX_START_PAGE; ei_local->stop_page = ETHERM_STOP_PAGE; diff -Nru a/drivers/net/at1700.c b/drivers/net/at1700.c --- a/drivers/net/at1700.c Sun Mar 14 14:20:07 2004 +++ b/drivers/net/at1700.c Sun Mar 14 14:20:07 2004 @@ -241,7 +241,7 @@ static void cleanup_card(struct net_device *dev) { #ifdef CONFIG_MCA - struct net_local *lp = dev->priv; + struct net_local *lp = netdev_priv(dev); if (lp->mca_slot) mca_mark_as_unused(lp->mca_slot); #endif @@ -319,8 +319,8 @@ char at1700_irqmap[8] = {3, 4, 5, 9, 10, 11, 14, 15}; unsigned int i, irq, is_fmv18x = 0, is_at1700 = 0; int slot, ret = -ENODEV; - struct net_local *lp = dev->priv; - + struct net_local *lp = netdev_priv(dev); + #ifndef CONFIG_X86_PC9800 if (!request_region(ioaddr, AT1700_IO_EXTENT, dev->name)) return -EBUSY; @@ -618,7 +618,7 @@ static int net_open(struct net_device *dev) { - struct net_local *lp = (struct net_local *)dev->priv; + struct net_local *lp = netdev_priv(dev); int ioaddr = dev->base_addr; /* Set the configuration register 0 to 32K 100ns. byte-wide memory, 16 bit @@ -649,7 +649,7 @@ static void net_tx_timeout (struct net_device *dev) { - struct net_local *lp = (struct net_local *)dev->priv; + struct net_local *lp = netdev_priv(dev); int ioaddr = dev->base_addr; printk ("%s: transmit timed out with status %04x, %s?\n", dev->name, @@ -683,7 +683,7 @@ static int net_send_packet (struct sk_buff *skb, struct net_device *dev) { - struct net_local *lp = (struct net_local *) dev->priv; + struct net_local *lp = netdev_priv(dev); int ioaddr = dev->base_addr; short length = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN; short len = skb->len; @@ -748,7 +748,7 @@ } ioaddr = dev->base_addr; - lp = (struct net_local *)dev->priv; + lp = netdev_priv(dev); spin_lock (&lp->lock); @@ -808,7 +808,7 @@ static void net_rx(struct net_device *dev) { - struct net_local *lp = (struct net_local *)dev->priv; + struct net_local *lp = netdev_priv(dev); int ioaddr = dev->base_addr; int boguscount = 5; @@ -891,7 +891,7 @@ /* The inverse routine to net_open(). */ static int net_close(struct net_device *dev) { - struct net_local *lp = (struct net_local *)dev->priv; + struct net_local *lp = netdev_priv(dev); int ioaddr = dev->base_addr; netif_stop_queue(dev); @@ -919,7 +919,7 @@ static struct net_device_stats * net_get_stats(struct net_device *dev) { - struct net_local *lp = (struct net_local *)dev->priv; + struct net_local *lp = netdev_priv(dev); return &lp->stats; } @@ -931,7 +931,7 @@ set_rx_mode(struct net_device *dev) { int ioaddr = dev->base_addr; - struct net_local *lp = (struct net_local *)dev->priv; + struct net_local *lp = netdev_priv(dev); unsigned char mc_filter[8]; /* Multicast hash filter */ unsigned long flags; int i; diff -Nru a/drivers/net/atari_bionet.c b/drivers/net/atari_bionet.c --- a/drivers/net/atari_bionet.c Sun Mar 14 14:20:07 2004 +++ b/drivers/net/atari_bionet.c Sun Mar 14 14:20:07 2004 @@ -408,7 +408,7 @@ */ static int bionet_open(struct net_device *dev) { - struct net_local *lp = (struct net_local *)dev->priv; + struct net_local *lp = netdev_priv(dev); if (bionet_debug > 0) printk("bionet_open\n"); @@ -433,7 +433,7 @@ static int bionet_send_packet(struct sk_buff *skb, struct net_device *dev) { - struct net_local *lp = (struct net_local *)dev->priv; + struct net_local *lp = netdev_priv(dev); unsigned long flags; /* Block a timer-based transmit from overlapping. This could better be @@ -499,7 +499,7 @@ */ static void bionet_poll_rx(struct net_device *dev) { - struct net_local *lp = (struct net_local *)dev->priv; + struct net_local *lp = netdev_priv(dev); int boguscount = 10; int pkt_len, status; unsigned long flags; @@ -601,7 +601,7 @@ static void bionet_tick(unsigned long data) { struct net_device *dev = (struct net_device *)data; - struct net_local *lp = (struct net_local *)dev->priv; + struct net_local *lp = netdev_priv(dev); if( bionet_debug > 0 && (lp->open_time++ & 7) == 8 ) printk("bionet_tick: %ld\n", lp->open_time); @@ -616,7 +616,7 @@ */ static int bionet_close(struct net_device *dev) { - struct net_local *lp = (struct net_local *)dev->priv; + struct net_local *lp = netdev_priv(dev); if (bionet_debug > 0) printk("bionet_close, open_time=%ld\n", lp->open_time); @@ -638,7 +638,7 @@ */ static struct net_device_stats *net_get_stats(struct net_device *dev) { - struct net_local *lp = (struct net_local *)dev->priv; + struct net_local *lp = netdev_priv(dev); return &lp->stats; } diff -Nru a/drivers/net/atari_pamsnet.c b/drivers/net/atari_pamsnet.c --- a/drivers/net/atari_pamsnet.c Sun Mar 14 14:20:06 2004 +++ b/drivers/net/atari_pamsnet.c Sun Mar 14 14:20:06 2004 @@ -667,7 +667,7 @@ */ static int pamsnet_open(struct net_device *dev) { - struct net_local *lp = (struct net_local *)dev->priv; + struct net_local *lp = netdev_priv(dev); if (pamsnet_debug > 0) printk("pamsnet_open\n"); @@ -696,7 +696,7 @@ static int pamsnet_send_packet(struct sk_buff *skb, struct net_device *dev) { - struct net_local *lp = (struct net_local *)dev->priv; + struct net_local *lp = netdev_priv(dev); unsigned long flags; /* Block a timer-based transmit from overlapping. This could better be @@ -742,7 +742,7 @@ */ static void pamsnet_poll_rx(struct net_device *dev) { - struct net_local *lp = (struct net_local *)dev->priv; + struct net_local *lp = netdev_priv(dev); int boguscount; int pkt_len; struct sk_buff *skb; @@ -817,7 +817,7 @@ static void pamsnet_tick(unsigned long data) { struct net_device *dev = (struct net_device *)data; - struct net_local *lp = (struct net_local *)dev->priv; + struct net_local *lp = netdev_priv(dev); if( pamsnet_debug > 0 && (lp->open_time++ & 7) == 8 ) printk("pamsnet_tick: %ld\n", lp->open_time); @@ -832,7 +832,7 @@ */ static int pamsnet_close(struct net_device *dev) { - struct net_local *lp = (struct net_local *)dev->priv; + struct net_local *lp = netdev_priv(dev); if (pamsnet_debug > 0) printk("pamsnet_close, open_time=%ld\n", lp->open_time); @@ -859,7 +859,7 @@ */ static struct net_device_stats *net_get_stats(struct net_device *dev) { - struct net_local *lp = (struct net_local *)dev->priv; + struct net_local *lp = netdev_priv(dev); return &lp->stats; } diff -Nru a/drivers/net/atp.c b/drivers/net/atp.c --- a/drivers/net/atp.c Sun Mar 14 14:20:08 2004 +++ b/drivers/net/atp.c Sun Mar 14 14:20:08 2004 @@ -335,7 +335,7 @@ /* Reset the ethernet hardware and activate the printer pass-through. */ write_reg_high(ioaddr, CMR1, CMR1h_RESET | CMR1h_MUX); - lp = (struct net_local *)dev->priv; + lp = netdev_priv(dev); lp->chip_type = RTL8002; lp->addr_mode = CMR2h_Normal; spin_lock_init(&lp->lock); @@ -432,7 +432,7 @@ */ static int net_open(struct net_device *dev) { - struct net_local *lp = (struct net_local *)dev->priv; + struct net_local *lp = netdev_priv(dev); int ret; /* The interrupt line is turned off (tri-stated) when the device isn't in @@ -458,7 +458,7 @@ the hardware may have been temporarily detached. */ static void hardware_init(struct net_device *dev) { - struct net_local *lp = (struct net_local *)dev->priv; + struct net_local *lp = netdev_priv(dev); long ioaddr = dev->base_addr; int i; @@ -541,7 +541,7 @@ static void tx_timeout(struct net_device *dev) { - struct net_local *np = (struct net_local *)dev->priv; + struct net_local *np = netdev_priv(dev); long ioaddr = dev->base_addr; printk(KERN_WARNING "%s: Transmit timed out, %s?\n", dev->name, @@ -557,7 +557,7 @@ static int atp_send_packet(struct sk_buff *skb, struct net_device *dev) { - struct net_local *lp = (struct net_local *)dev->priv; + struct net_local *lp = netdev_priv(dev); long ioaddr = dev->base_addr; int length; unsigned long flags; @@ -611,7 +611,7 @@ return IRQ_NONE; } ioaddr = dev->base_addr; - lp = (struct net_local *)dev->priv; + lp = netdev_priv(dev); spin_lock(&lp->lock); @@ -726,7 +726,7 @@ { struct net_device *dev = (struct net_device *)data; long ioaddr = dev->base_addr; - struct net_local *lp = (struct net_local *)dev->priv; + struct net_local *lp = netdev_priv(dev); int tickssofar = jiffies - lp->last_rx_time; int i; @@ -740,7 +740,7 @@ for (i = 0; i < 6; i++) if (read_cmd_byte(ioaddr, PAR0 + i) != atp_timed_dev->dev_addr[i]) { - struct net_local *lp = (struct net_local *)atp_timed_dev->priv; + struct net_local *lp = netdev_priv(atp_timed_dev); write_reg_byte(ioaddr, PAR0 + i, atp_timed_dev->dev_addr[i]); if (i == 2) lp->stats.tx_errors++; @@ -762,7 +762,7 @@ /* We have a good packet(s), get it/them out of the buffers. */ static void net_rx(struct net_device *dev) { - struct net_local *lp = (struct net_local *)dev->priv; + struct net_local *lp = netdev_priv(dev); long ioaddr = dev->base_addr; struct rx_header rx_head; @@ -838,7 +838,7 @@ static int net_close(struct net_device *dev) { - struct net_local *lp = (struct net_local *)dev->priv; + struct net_local *lp = netdev_priv(dev); long ioaddr = dev->base_addr; netif_stop_queue(dev); @@ -863,7 +863,7 @@ static struct net_device_stats * net_get_stats(struct net_device *dev) { - struct net_local *lp = (struct net_local *)dev->priv; + struct net_local *lp = netdev_priv(dev); return &lp->stats; } @@ -873,7 +873,7 @@ static void set_rx_mode_8002(struct net_device *dev) { - struct net_local *lp = (struct net_local *)dev->priv; + struct net_local *lp = netdev_priv(dev); long ioaddr = dev->base_addr; if ( dev->mc_count > 0 || (dev->flags & (IFF_ALLMULTI|IFF_PROMISC))) { @@ -890,7 +890,7 @@ static void set_rx_mode_8012(struct net_device *dev) { - struct net_local *lp = (struct net_local *)dev->priv; + struct net_local *lp = netdev_priv(dev); long ioaddr = dev->base_addr; unsigned char new_mode, mc_filter[8]; /* Multicast hash filter */ int i; diff -Nru a/drivers/net/b44.c b/drivers/net/b44.c --- a/drivers/net/b44.c Sun Mar 14 14:20:07 2004 +++ b/drivers/net/b44.c Sun Mar 14 14:20:07 2004 @@ -667,6 +667,10 @@ dest_desc->ctrl = ctrl; dest_desc->addr = src_desc->addr; src_map->skb = NULL; + + pci_dma_sync_single_for_device(bp->pdev, src_desc->addr, + RX_PKT_BUF_SZ, + PCI_DMA_FROMDEVICE); } static int b44_rx(struct b44 *bp, int budget) @@ -686,9 +690,9 @@ struct rx_header *rh; u16 len; - pci_dma_sync_single(bp->pdev, map, - RX_PKT_BUF_SZ, - PCI_DMA_FROMDEVICE); + pci_dma_sync_single_for_cpu(bp->pdev, map, + RX_PKT_BUF_SZ, + PCI_DMA_FROMDEVICE); rh = (struct rx_header *) skb->data; len = cpu_to_le16(rh->len); if ((len > (RX_PKT_BUF_SZ - bp->rx_offset)) || diff -Nru a/drivers/net/bagetlance.c b/drivers/net/bagetlance.c --- a/drivers/net/bagetlance.c Sun Mar 14 14:20:06 2004 +++ b/drivers/net/bagetlance.c Sun Mar 14 14:20:06 2004 @@ -594,7 +594,7 @@ return( 0 ); probe_ok: - lp = (struct lance_private *)dev->priv; + lp = netdev_priv(dev); MEM = (struct lance_memory *)memaddr; IO = lp->iobase = (struct lance_ioreg *)ioaddr; dev->base_addr = (unsigned long)ioaddr; /* informational only */ @@ -736,7 +736,7 @@ static int lance_open( struct net_device *dev ) -{ struct lance_private *lp = (struct lance_private *)dev->priv; +{ struct lance_private *lp = netdev_priv(dev); struct lance_ioreg *IO = lp->iobase; int i; @@ -778,7 +778,7 @@ static void lance_init_ring( struct net_device *dev ) -{ struct lance_private *lp = (struct lance_private *)dev->priv; +{ struct lance_private *lp = netdev_priv(dev); int i; unsigned offset; @@ -834,7 +834,7 @@ static int lance_start_xmit( struct sk_buff *skb, struct net_device *dev ) -{ struct lance_private *lp = (struct lance_private *)dev->priv; +{ struct lance_private *lp = netdev_priv(dev); struct lance_ioreg *IO = lp->iobase; int entry, len; struct lance_tx_head *head; @@ -988,7 +988,7 @@ return IRQ_NONE; } - lp = (struct lance_private *)dev->priv; + lp = netdev_priv(dev); IO = lp->iobase; AREG = CSR0; @@ -1101,7 +1101,7 @@ static int lance_rx( struct net_device *dev ) -{ struct lance_private *lp = (struct lance_private *)dev->priv; +{ struct lance_private *lp = netdev_priv(dev); int entry = lp->cur_rx & RX_RING_MOD_MASK; int i; @@ -1225,7 +1225,7 @@ static int lance_close( struct net_device *dev ) -{ struct lance_private *lp = (struct lance_private *)dev->priv; +{ struct lance_private *lp = netdev_priv(dev); struct lance_ioreg *IO = lp->iobase; dev->start = 0; @@ -1247,7 +1247,7 @@ static struct net_device_stats *lance_get_stats( struct net_device *dev ) { - struct lance_private *lp = (struct lance_private *)dev->priv; + struct lance_private *lp = netdev_priv(dev); return &lp->stats; } @@ -1261,7 +1261,7 @@ static void set_multicast_list( struct net_device *dev ) -{ struct lance_private *lp = (struct lance_private *)dev->priv; +{ struct lance_private *lp = netdev_priv(dev); struct lance_ioreg *IO = lp->iobase; if (!dev->start) @@ -1303,7 +1303,7 @@ static int lance_set_mac_address( struct net_device *dev, void *addr ) -{ struct lance_private *lp = (struct lance_private *)dev->priv; +{ struct lance_private *lp = netdev_priv(dev); struct sockaddr *saddr = addr; int i; diff -Nru a/drivers/net/bmac.c b/drivers/net/bmac.c --- a/drivers/net/bmac.c Sun Mar 14 14:20:06 2004 +++ b/drivers/net/bmac.c Sun Mar 14 14:20:06 2004 @@ -226,7 +226,7 @@ static void bmac_enable_and_reset_chip(struct net_device *dev) { - struct bmac_data *bp = (struct bmac_data *) dev->priv; + struct bmac_data *bp = netdev_priv(dev); volatile struct dbdma_regs *rd = bp->rx_dma; volatile struct dbdma_regs *td = bp->tx_dma; @@ -310,7 +310,7 @@ static void bmac_init_registers(struct net_device *dev) { - struct bmac_data *bp = (struct bmac_data *) dev->priv; + struct bmac_data *bp = netdev_priv(dev); volatile unsigned short regValue; unsigned short *pWord16; int i; @@ -405,7 +405,7 @@ static void bmac_start_chip(struct net_device *dev) { - struct bmac_data *bp = (struct bmac_data *) dev->priv; + struct bmac_data *bp = netdev_priv(dev); volatile struct dbdma_regs *rd = bp->rx_dma; unsigned short oldConfig; @@ -425,7 +425,7 @@ bmac_init_phy(struct net_device *dev) { unsigned int addr; - struct bmac_data *bp = (struct bmac_data *) dev->priv; + struct bmac_data *bp = netdev_priv(dev); printk(KERN_DEBUG "phy registers:"); for (addr = 0; addr < 32; ++addr) { @@ -458,7 +458,7 @@ static int bmac_suspend(struct macio_dev *mdev, u32 state) { struct net_device* dev = macio_get_drvdata(mdev); - struct bmac_data *bp = dev->priv; + struct bmac_data *bp = netdev_priv(dev); unsigned long flags; unsigned short config; int i; @@ -508,7 +508,7 @@ static int bmac_resume(struct macio_dev *mdev) { struct net_device* dev = macio_get_drvdata(mdev); - struct bmac_data *bp = dev->priv; + struct bmac_data *bp = netdev_priv(dev); /* see if this is enough */ if (bp->opened) @@ -525,7 +525,7 @@ static int bmac_set_address(struct net_device *dev, void *addr) { - struct bmac_data *bp = (struct bmac_data *) dev->priv; + struct bmac_data *bp = netdev_priv(dev); unsigned char *p = addr; unsigned short *pWord16; unsigned long flags; @@ -550,7 +550,7 @@ static inline void bmac_set_timeout(struct net_device *dev) { - struct bmac_data *bp = (struct bmac_data *) dev->priv; + struct bmac_data *bp = netdev_priv(dev); unsigned long flags; spin_lock_irqsave(&bp->lock, flags); @@ -656,7 +656,7 @@ static int bmac_transmit_packet(struct sk_buff *skb, struct net_device *dev) { - struct bmac_data *bp = (struct bmac_data *) dev->priv; + struct bmac_data *bp = netdev_priv(dev); volatile struct dbdma_regs *td = bp->tx_dma; int i; @@ -692,7 +692,7 @@ static irqreturn_t bmac_rxdma_intr(int irq, void *dev_id, struct pt_regs *regs) { struct net_device *dev = (struct net_device *) dev_id; - struct bmac_data *bp = (struct bmac_data *) dev->priv; + struct bmac_data *bp = netdev_priv(dev); volatile struct dbdma_regs *rd = bp->rx_dma; volatile struct dbdma_cmd *cp; int i, nb, stat; @@ -769,7 +769,7 @@ static irqreturn_t bmac_txdma_intr(int irq, void *dev_id, struct pt_regs *regs) { struct net_device *dev = (struct net_device *) dev_id; - struct bmac_data *bp = (struct bmac_data *) dev->priv; + struct bmac_data *bp = netdev_priv(dev); volatile struct dbdma_cmd *cp; int stat; unsigned long flags; @@ -822,7 +822,7 @@ static struct net_device_stats *bmac_stats(struct net_device *dev) { - struct bmac_data *p = (struct bmac_data *) dev->priv; + struct bmac_data *p = netdev_priv(dev); return &p->stats; } @@ -995,7 +995,7 @@ static void bmac_set_multicast(struct net_device *dev) { struct dev_mc_list *dmi; - struct bmac_data *bp = (struct bmac_data *) dev->priv; + struct bmac_data *bp = netdev_priv(dev); int num_addrs = dev->mc_count; unsigned short rx_cfg; int i; @@ -1086,7 +1086,7 @@ static irqreturn_t bmac_misc_intr(int irq, void *dev_id, struct pt_regs *regs) { struct net_device *dev = (struct net_device *) dev_id; - struct bmac_data *bp = (struct bmac_data *)dev->priv; + struct bmac_data *bp = netdev_priv(dev); unsigned int status = bmread(dev, STATUS); if (miscintcount++ < 10) { XXDEBUG(("bmac_misc_intr\n")); @@ -1232,7 +1232,7 @@ static void bmac_reset_and_enable(struct net_device *dev) { - struct bmac_data *bp = dev->priv; + struct bmac_data *bp = netdev_priv(dev); unsigned long flags; struct sk_buff *skb; unsigned char *data; @@ -1288,7 +1288,7 @@ return -ENOMEM; } - bp = (struct bmac_data *) dev->priv; + bp = netdev_priv(dev); SET_MODULE_OWNER(dev); SET_NETDEV_DEV(dev, &mdev->ofdev.dev); macio_set_drvdata(mdev, dev); @@ -1408,7 +1408,7 @@ static int bmac_open(struct net_device *dev) { - struct bmac_data *bp = (struct bmac_data *) dev->priv; + struct bmac_data *bp = netdev_priv(dev); /* XXDEBUG(("bmac: enter open\n")); */ /* reset the chip */ bp->opened = 1; @@ -1420,7 +1420,7 @@ static int bmac_close(struct net_device *dev) { - struct bmac_data *bp = (struct bmac_data *) dev->priv; + struct bmac_data *bp = netdev_priv(dev); volatile struct dbdma_regs *rd = bp->rx_dma; volatile struct dbdma_regs *td = bp->tx_dma; unsigned short config; @@ -1469,7 +1469,7 @@ static void bmac_start(struct net_device *dev) { - struct bmac_data *bp = dev->priv; + struct bmac_data *bp = netdev_priv(dev); int i; struct sk_buff *skb; unsigned long flags; @@ -1495,7 +1495,7 @@ static int bmac_output(struct sk_buff *skb, struct net_device *dev) { - struct bmac_data *bp = dev->priv; + struct bmac_data *bp = netdev_priv(dev); skb_queue_tail(bp->queue, skb); bmac_start(dev); return 0; @@ -1504,7 +1504,7 @@ static void bmac_tx_timeout(unsigned long data) { struct net_device *dev = (struct net_device *) data; - struct bmac_data *bp = (struct bmac_data *) dev->priv; + struct bmac_data *bp = netdev_priv(dev); volatile struct dbdma_regs *td = bp->tx_dma; volatile struct dbdma_regs *rd = bp->rx_dma; volatile struct dbdma_cmd *cp; @@ -1630,7 +1630,7 @@ static int __devexit bmac_remove(struct macio_dev *mdev) { struct net_device *dev = macio_get_drvdata(mdev); - struct bmac_data *bp = dev->priv; + struct bmac_data *bp = netdev_priv(dev); unregister_netdev(dev); diff -Nru a/drivers/net/cs89x0.c b/drivers/net/cs89x0.c --- a/drivers/net/cs89x0.c Sun Mar 14 14:20:08 2004 +++ b/drivers/net/cs89x0.c Sun Mar 14 14:20:08 2004 @@ -399,7 +399,7 @@ static int __init cs89x0_probe1(struct net_device *dev, int ioaddr, int modular) { - struct net_local *lp = (struct net_local *)dev->priv; + struct net_local *lp = netdev_priv(dev); static unsigned version_printed; int i; unsigned rev_type = 0; @@ -735,7 +735,7 @@ static void get_dma_channel(struct net_device *dev) { - struct net_local *lp = (struct net_local *)dev->priv; + struct net_local *lp = netdev_priv(dev); if (lp->dma) { dev->dma = lp->dma; @@ -757,7 +757,7 @@ static void write_dma(struct net_device *dev, int chip_type, int dma) { - struct net_local *lp = (struct net_local *)dev->priv; + struct net_local *lp = netdev_priv(dev); if ((lp->isa_config & ANY_ISA_DMA) == 0) return; if (chip_type == CS8900) { @@ -770,7 +770,7 @@ static void set_dma_cfg(struct net_device *dev) { - struct net_local *lp = (struct net_local *)dev->priv; + struct net_local *lp = netdev_priv(dev); if (lp->use_dma) { if ((lp->isa_config & ANY_ISA_DMA) == 0) { @@ -793,7 +793,7 @@ static int dma_bufcfg(struct net_device *dev) { - struct net_local *lp = (struct net_local *)dev->priv; + struct net_local *lp = netdev_priv(dev); if (lp->use_dma) return (lp->isa_config & ANY_ISA_DMA)? RX_DMA_ENBL : 0; else @@ -804,7 +804,7 @@ dma_busctl(struct net_device *dev) { int retval = 0; - struct net_local *lp = (struct net_local *)dev->priv; + struct net_local *lp = netdev_priv(dev); if (lp->use_dma) { if (lp->isa_config & ANY_ISA_DMA) retval |= RESET_RX_DMA; /* Reset the DMA pointer */ @@ -820,7 +820,7 @@ static void dma_rx(struct net_device *dev) { - struct net_local *lp = (struct net_local *)dev->priv; + struct net_local *lp = netdev_priv(dev); struct sk_buff *skb; int status, length; unsigned char *bp = lp->rx_dma_ptr; @@ -882,7 +882,7 @@ void __init reset_chip(struct net_device *dev) { - struct net_local *lp = (struct net_local *)dev->priv; + struct net_local *lp = netdev_priv(dev); int ioaddr = dev->base_addr; int reset_start_time; @@ -912,7 +912,7 @@ static void control_dc_dc(struct net_device *dev, int on_not_off) { - struct net_local *lp = (struct net_local *)dev->priv; + struct net_local *lp = netdev_priv(dev); unsigned int selfcontrol; int timenow = jiffies; /* control the DC to DC convertor in the SelfControl register. @@ -940,7 +940,7 @@ static int detect_tp(struct net_device *dev) { - struct net_local *lp = (struct net_local *)dev->priv; + struct net_local *lp = netdev_priv(dev); int timenow = jiffies; int fdx; @@ -1055,7 +1055,7 @@ static int detect_aui(struct net_device *dev) { - struct net_local *lp = (struct net_local *)dev->priv; + struct net_local *lp = netdev_priv(dev); if (net_debug > 1) printk("%s: Attempting AUI\n", dev->name); control_dc_dc(dev, 0); @@ -1071,7 +1071,7 @@ static int detect_bnc(struct net_device *dev) { - struct net_local *lp = (struct net_local *)dev->priv; + struct net_local *lp = netdev_priv(dev); if (net_debug > 1) printk("%s: Attempting BNC\n", dev->name); control_dc_dc(dev, 1); @@ -1117,7 +1117,7 @@ static int net_open(struct net_device *dev) { - struct net_local *lp = (struct net_local *)dev->priv; + struct net_local *lp = netdev_priv(dev); int result = 0; int i; int ret; @@ -1358,7 +1358,7 @@ static int net_send_packet(struct sk_buff *skb, struct net_device *dev) { - struct net_local *lp = (struct net_local *)dev->priv; + struct net_local *lp = netdev_priv(dev); if (net_debug > 3) { printk("%s: sent %d byte packet of type %x\n", @@ -1419,7 +1419,7 @@ int handled = 0; ioaddr = dev->base_addr; - lp = (struct net_local *)dev->priv; + lp = netdev_priv(dev); /* we MUST read all the events out of the ISQ, otherwise we'll never get interrupted again. As a consequence, we can't have any limit @@ -1517,7 +1517,7 @@ static void net_rx(struct net_device *dev) { - struct net_local *lp = (struct net_local *)dev->priv; + struct net_local *lp = netdev_priv(dev); struct sk_buff *skb; int status, length; @@ -1573,7 +1573,7 @@ static int net_close(struct net_device *dev) { - struct net_local *lp = (struct net_local *)dev->priv; + struct net_local *lp = netdev_priv(dev); netif_stop_queue(dev); @@ -1600,7 +1600,7 @@ static struct net_device_stats * net_get_stats(struct net_device *dev) { - struct net_local *lp = (struct net_local *)dev->priv; + struct net_local *lp = netdev_priv(dev); unsigned long flags; spin_lock_irqsave(&lp->lock, flags); @@ -1614,7 +1614,7 @@ static void set_multicast_list(struct net_device *dev) { - struct net_local *lp = (struct net_local *)dev->priv; + struct net_local *lp = netdev_priv(dev); unsigned long flags; spin_lock_irqsave(&lp->lock, flags); @@ -1758,7 +1758,7 @@ dev->irq = irq; dev->base_addr = io; - lp = dev->priv; + lp = netdev_priv(dev); #if ALLOW_DMA if (use_dma) { diff -Nru a/drivers/net/declance.c b/drivers/net/declance.c --- a/drivers/net/declance.c Sun Mar 14 14:20:07 2004 +++ b/drivers/net/declance.c Sun Mar 14 14:20:07 2004 @@ -433,7 +433,7 @@ /* Setup the Lance Rx and Tx rings */ static void lance_init_ring(struct net_device *dev) { - struct lance_private *lp = (struct lance_private *) dev->priv; + struct lance_private *lp = netdev_priv(dev); volatile struct lance_init_block *ib; int leptr; int i; @@ -530,7 +530,7 @@ static int lance_rx(struct net_device *dev) { - struct lance_private *lp = (struct lance_private *) dev->priv; + struct lance_private *lp = netdev_priv(dev); volatile struct lance_init_block *ib; volatile struct lance_rx_desc *rd = 0; unsigned char bits; @@ -617,7 +617,7 @@ static void lance_tx(struct net_device *dev) { - struct lance_private *lp = (struct lance_private *) dev->priv; + struct lance_private *lp = netdev_priv(dev); volatile struct lance_init_block *ib; volatile struct lance_regs *ll = lp->ll; volatile struct lance_tx_desc *td; @@ -709,7 +709,7 @@ lance_interrupt(const int irq, void *dev_id, struct pt_regs *regs) { struct net_device *dev = (struct net_device *) dev_id; - struct lance_private *lp = (struct lance_private *) dev->priv; + struct lance_private *lp = netdev_priv(dev); volatile struct lance_regs *ll = lp->ll; int csr0; @@ -757,7 +757,7 @@ static int lance_open(struct net_device *dev) { volatile struct lance_init_block *ib = (struct lance_init_block *) (dev->mem_start); - struct lance_private *lp = (struct lance_private *) dev->priv; + struct lance_private *lp = netdev_priv(dev); volatile struct lance_regs *ll = lp->ll; int status = 0; @@ -822,7 +822,7 @@ static int lance_close(struct net_device *dev) { - struct lance_private *lp = (struct lance_private *) dev->priv; + struct lance_private *lp = netdev_priv(dev); volatile struct lance_regs *ll = lp->ll; netif_stop_queue(dev); @@ -856,7 +856,7 @@ static inline int lance_reset(struct net_device *dev) { - struct lance_private *lp = (struct lance_private *) dev->priv; + struct lance_private *lp = netdev_priv(dev); volatile struct lance_regs *ll = lp->ll; int status; @@ -873,7 +873,7 @@ static void lance_tx_timeout(struct net_device *dev) { - struct lance_private *lp = (struct lance_private *) dev->priv; + struct lance_private *lp = netdev_priv(dev); volatile struct lance_regs *ll = lp->ll; printk(KERN_ERR "%s: transmit timed out, status %04x, reset\n", @@ -884,7 +884,7 @@ static int lance_start_xmit(struct sk_buff *skb, struct net_device *dev) { - struct lance_private *lp = (struct lance_private *) dev->priv; + struct lance_private *lp = netdev_priv(dev); volatile struct lance_regs *ll = lp->ll; volatile struct lance_init_block *ib = (struct lance_init_block *) (dev->mem_start); int entry, skblen, len; @@ -936,7 +936,7 @@ static struct net_device_stats *lance_get_stats(struct net_device *dev) { - struct lance_private *lp = (struct lance_private *) dev->priv; + struct lance_private *lp = netdev_priv(dev); return &lp->stats; } @@ -982,7 +982,7 @@ static void lance_set_multicast(struct net_device *dev) { - struct lance_private *lp = (struct lance_private *) dev->priv; + struct lance_private *lp = netdev_priv(dev); volatile struct lance_init_block *ib; volatile struct lance_regs *ll = lp->ll; @@ -1048,7 +1048,7 @@ * alloc_etherdev ensures the data structures used by the LANCE * are aligned. */ - lp = (struct lance_private *) dev->priv; + lp = netdev_priv(dev); spin_lock_init(&lp->lock); lp->type = type; @@ -1287,7 +1287,7 @@ { while (root_lance_dev) { struct net_device *dev = root_lance_dev; - struct lance_private *lp = (struct lance_private *)dev->priv; + struct lance_private *lp = netdev_priv(dev); unregister_netdev(dev); #ifdef CONFIG_TC if (lp->slot >= 0) diff -Nru a/drivers/net/dl2k.c b/drivers/net/dl2k.c --- a/drivers/net/dl2k.c Sun Mar 14 14:20:07 2004 +++ b/drivers/net/dl2k.c Sun Mar 14 14:20:07 2004 @@ -874,8 +874,6 @@ frame_status = le64_to_cpu (desc->status); if (--cnt < 0) break; - pci_dma_sync_single (np->pdev, desc->fraginfo, np->rx_buf_sz, - PCI_DMA_FROMDEVICE); /* Update rx error statistics, drop packet. */ if (frame_status & RFS_Errors) { np->stats.rx_errors++; @@ -898,6 +896,10 @@ skb_put (skb = np->rx_skbuff[entry], pkt_len); np->rx_skbuff[entry] = NULL; } else if ((skb = dev_alloc_skb (pkt_len + 2)) != NULL) { + pci_dma_sync_single_for_cpu(np->pdev, + desc->fraginfo, + np->rx_buf_sz, + PCI_DMA_FROMDEVICE); skb->dev = dev; /* 16 byte align the IP header */ skb_reserve (skb, 2); @@ -905,6 +907,10 @@ np->rx_skbuff[entry]->tail, pkt_len, 0); skb_put (skb, pkt_len); + pci_dma_sync_single_for_device(np->pdev, + desc->fraginfo, + np->rx_buf_sz, + PCI_DMA_FROMDEVICE); } skb->protocol = eth_type_trans (skb, dev); #if 0 diff -Nru a/drivers/net/e100.c b/drivers/net/e100.c --- a/drivers/net/e100.c Sun Mar 14 14:20:08 2004 +++ b/drivers/net/e100.c Sun Mar 14 14:20:08 2004 @@ -158,7 +158,7 @@ #define DRV_NAME "e100" -#define DRV_VERSION "3.0.16" +#define DRV_VERSION "3.0.17" #define DRV_DESCRIPTION "Intel(R) PRO/100 Network Driver" #define DRV_COPYRIGHT "Copyright(c) 1999-2004 Intel Corporation" #define PFX DRV_NAME ": " @@ -1285,6 +1285,7 @@ le16_to_cpu(cb->u.tcb.tbd.size), PCI_DMA_TODEVICE); dev_kfree_skb_any(cb->skb); + cb->skb = NULL; tx_cleaned = 1; } cb->status = 0; @@ -1347,6 +1348,7 @@ cb->dma_addr = nic->cbs_dma_addr + i * sizeof(struct cb); cb->link = cpu_to_le32(nic->cbs_dma_addr + ((i+1) % count) * sizeof(struct cb)); + cb->skb = NULL; } nic->cb_to_use = nic->cb_to_send = nic->cb_to_clean = nic->cbs; @@ -1387,8 +1389,8 @@ (u32 *)&prev_rfd->link); wmb(); prev_rfd->command &= ~cpu_to_le16(cb_el); - pci_dma_sync_single(nic->pdev, rx->prev->dma_addr, - sizeof(struct rfd), PCI_DMA_TODEVICE); + pci_dma_sync_single_for_device(nic->pdev, rx->prev->dma_addr, + sizeof(struct rfd), PCI_DMA_TODEVICE); } return 0; @@ -1405,8 +1407,8 @@ return -EAGAIN; /* Need to sync before taking a peek at cb_complete bit */ - pci_dma_sync_single(nic->pdev, rx->dma_addr, - sizeof(struct rfd), PCI_DMA_FROMDEVICE); + pci_dma_sync_single_for_cpu(nic->pdev, rx->dma_addr, + sizeof(struct rfd), PCI_DMA_FROMDEVICE); rfd_status = le16_to_cpu(rfd->status); DPRINTK(RX_STATUS, DEBUG, "status=0x%04X\n", rfd_status); @@ -1421,11 +1423,8 @@ actual_size = RFD_BUF_LEN - sizeof(struct rfd); /* Get data */ - pci_dma_sync_single(nic->pdev, rx->dma_addr, - sizeof(struct rfd) + actual_size, - PCI_DMA_FROMDEVICE); pci_unmap_single(nic->pdev, rx->dma_addr, - RFD_BUF_LEN, PCI_DMA_FROMDEVICE); + RFD_BUF_LEN, PCI_DMA_FROMDEVICE); /* Pull off the RFD and put the actual data (minus eth hdr) */ skb_reserve(skb, sizeof(struct rfd)); diff -Nru a/drivers/net/e1000/e1000_ethtool.c b/drivers/net/e1000/e1000_ethtool.c --- a/drivers/net/e1000/e1000_ethtool.c Sun Mar 14 14:20:07 2004 +++ b/drivers/net/e1000/e1000_ethtool.c Sun Mar 14 14:20:07 2004 @@ -1191,16 +1191,16 @@ for(i = 0; i < 64; i++) { e1000_create_lbtest_frame(txdr->buffer_info[i].skb, 1024); - pci_dma_sync_single(pdev, txdr->buffer_info[i].dma, - txdr->buffer_info[i].length, - PCI_DMA_TODEVICE); + pci_dma_sync_single_for_device(pdev, txdr->buffer_info[i].dma, + txdr->buffer_info[i].length, + PCI_DMA_TODEVICE); } E1000_WRITE_REG(&adapter->hw, TDT, i); msec_delay(200); - pci_dma_sync_single(pdev, rxdr->buffer_info[0].dma, - rxdr->buffer_info[0].length, PCI_DMA_FROMDEVICE); + pci_dma_sync_single_for_cpu(pdev, rxdr->buffer_info[0].dma, + rxdr->buffer_info[0].length, PCI_DMA_FROMDEVICE); return e1000_check_lbtest_frame(rxdr->buffer_info[0].skb, 1024); } diff -Nru a/drivers/net/e2100.c b/drivers/net/e2100.c --- a/drivers/net/e2100.c Sun Mar 14 14:20:08 2004 +++ b/drivers/net/e2100.c Sun Mar 14 14:20:08 2004 @@ -269,6 +269,9 @@ ei_status.get_8390_hdr = &e21_get_8390_hdr; dev->open = &e21_open; dev->stop = &e21_close; +#ifdef CONFIG_NET_POLL_CONTROLLER + dev->poll_controller = ei_poll; +#endif NS8390_init(dev, 0); return 0; diff -Nru a/drivers/net/eepro.c b/drivers/net/eepro.c --- a/drivers/net/eepro.c Sun Mar 14 14:20:08 2004 +++ b/drivers/net/eepro.c Sun Mar 14 14:20:08 2004 @@ -662,7 +662,7 @@ { struct eepro_local * lp; - lp = dev->priv; + lp = netdev_priv(dev); lp->xmt_ram = RAM_SIZE - lp->rcv_ram; if (lp->eepro == LAN595FX_10ISA) { @@ -680,9 +680,9 @@ } /* prints boot-time info */ -static void eepro_print_info (struct net_device *dev) +static void __init eepro_print_info (struct net_device *dev) { - struct eepro_local * lp = dev->priv; + struct eepro_local * lp = netdev_priv(dev); int i; const char * ifmap[] = {"AUI", "10Base2", "10BaseT"}; @@ -769,7 +769,7 @@ if ((inb(ioaddr + ID_REG) & R_ROBIN_BITS) != (counter + 0x40)) goto exit; - lp = (struct eepro_local *)dev->priv; + lp = netdev_priv(dev); memset(lp, 0, sizeof(struct eepro_local)); lp->xmt_bar = XMT_BAR_PRO; lp->xmt_lower_limit_reg = XMT_LOWER_LIMIT_REG_PRO; @@ -932,7 +932,7 @@ unsigned short temp_reg, old8, old9; int irqMask; int i, ioaddr = dev->base_addr; - struct eepro_local *lp = (struct eepro_local *)dev->priv; + struct eepro_local *lp = netdev_priv(dev); if (net_debug > 3) printk(KERN_DEBUG "%s: entering eepro_open routine.\n", dev->name); @@ -1106,7 +1106,7 @@ static void eepro_tx_timeout (struct net_device *dev) { - struct eepro_local *lp = (struct eepro_local *) dev->priv; + struct eepro_local *lp = netdev_priv(dev); int ioaddr = dev->base_addr; /* if (net_debug > 1) */ @@ -1122,7 +1122,7 @@ static int eepro_send_packet(struct sk_buff *skb, struct net_device *dev) { - struct eepro_local *lp = (struct eepro_local *)dev->priv; + struct eepro_local *lp = netdev_priv(dev); unsigned long flags; int ioaddr = dev->base_addr; short length = skb->len; @@ -1187,7 +1187,7 @@ return IRQ_NONE; } - lp = (struct eepro_local *)dev->priv; + lp = netdev_priv(dev); spin_lock(&lp->lock); @@ -1235,7 +1235,7 @@ static int eepro_close(struct net_device *dev) { - struct eepro_local *lp = (struct eepro_local *)dev->priv; + struct eepro_local *lp = netdev_priv(dev); int ioaddr = dev->base_addr; short temp_reg; @@ -1280,7 +1280,7 @@ static struct net_device_stats * eepro_get_stats(struct net_device *dev) { - struct eepro_local *lp = (struct eepro_local *)dev->priv; + struct eepro_local *lp = netdev_priv(dev); return &lp->stats; } @@ -1290,7 +1290,7 @@ static void set_multicast_list(struct net_device *dev) { - struct eepro_local *lp = (struct eepro_local *)dev->priv; + struct eepro_local *lp = netdev_priv(dev); short ioaddr = dev->base_addr; unsigned short mode; struct dev_mc_list *dmi=dev->mc_list; @@ -1424,7 +1424,7 @@ { int i; unsigned short retval = 0; - struct eepro_local *lp = dev->priv; + struct eepro_local *lp = netdev_priv(dev); short ee_addr = ioaddr + lp->eeprom_reg; int read_cmd = location | EE_READ_CMD; short ctrl_val = EECS ; @@ -1468,7 +1468,7 @@ static int hardware_send_packet(struct net_device *dev, void *buf, short length) { - struct eepro_local *lp = (struct eepro_local *)dev->priv; + struct eepro_local *lp = netdev_priv(dev); short ioaddr = dev->base_addr; unsigned status, tx_available, last, end; @@ -1553,7 +1553,7 @@ static void eepro_rx(struct net_device *dev) { - struct eepro_local *lp = (struct eepro_local *)dev->priv; + struct eepro_local *lp = netdev_priv(dev); short ioaddr = dev->base_addr; short boguscount = 20; short rcv_car = lp->rx_start; @@ -1651,7 +1651,7 @@ static void eepro_transmit_interrupt(struct net_device *dev) { - struct eepro_local *lp = (struct eepro_local *)dev->priv; + struct eepro_local *lp = netdev_priv(dev); short ioaddr = dev->base_addr; short boguscount = 25; short xmt_status; diff -Nru a/drivers/net/eepro100.c b/drivers/net/eepro100.c --- a/drivers/net/eepro100.c Sun Mar 14 14:20:07 2004 +++ b/drivers/net/eepro100.c Sun Mar 14 14:20:07 2004 @@ -654,6 +654,23 @@ return -ENODEV; } +#ifdef CONFIG_NET_POLL_CONTROLLER +/* + * Polling 'interrupt' - used by things like netconsole to send skbs + * without having to re-enable interrupts. It's not called while + * the interrupt routine is executing. + */ + +static void poll_speedo (struct net_device *dev) +{ + /* disable_irq is not very nice, but with the funny lockless design + we have no other choice. */ + disable_irq(dev->irq); + speedo_interrupt (dev->irq, dev, NULL); + enable_irq(dev->irq); +} +#endif + static int __devinit speedo_found1(struct pci_dev *pdev, long ioaddr, int card_idx, int acpi_idle_state) { @@ -839,7 +856,7 @@ dev->irq = pdev->irq; - sp = dev->priv; + sp = netdev_priv(dev); sp->pdev = pdev; sp->msg_enable = DEBUG; sp->acpi_pwr = acpi_idle_state; @@ -885,6 +902,9 @@ dev->get_stats = &speedo_get_stats; dev->set_multicast_list = &set_rx_mode; dev->do_ioctl = &speedo_ioctl; +#ifdef CONFIG_NET_POLL_CONTROLLER + dev->poll_controller = &poll_speedo; +#endif if (register_netdevice(dev)) goto err_free_unlock; @@ -995,7 +1015,7 @@ static int speedo_open(struct net_device *dev) { - struct speedo_private *sp = (struct speedo_private *)dev->priv; + struct speedo_private *sp = netdev_priv(dev); long ioaddr = dev->base_addr; int retval; @@ -1082,7 +1102,7 @@ /* Start the chip hardware after a full reset. */ static void speedo_resume(struct net_device *dev) { - struct speedo_private *sp = dev->priv; + struct speedo_private *sp = netdev_priv(dev); long ioaddr = dev->base_addr; /* Start with a Tx threshold of 256 (0x..20.... 8 byte units). */ @@ -1162,7 +1182,7 @@ static void speedo_rx_soft_reset(struct net_device *dev) { - struct speedo_private *sp = dev->priv; + struct speedo_private *sp = netdev_priv(dev); struct RxFD *rfd; long ioaddr; @@ -1194,7 +1214,7 @@ static void speedo_timer(unsigned long data) { struct net_device *dev = (struct net_device *)data; - struct speedo_private *sp = (struct speedo_private *)dev->priv; + struct speedo_private *sp = netdev_priv(dev); long ioaddr = dev->base_addr; int phy_num = sp->phy[0] & 0x1f; @@ -1239,7 +1259,7 @@ static void speedo_show_state(struct net_device *dev) { - struct speedo_private *sp = (struct speedo_private *)dev->priv; + struct speedo_private *sp = netdev_priv(dev); int i; if (netif_msg_pktdata(sp)) { @@ -1282,7 +1302,7 @@ static void speedo_init_rx_ring(struct net_device *dev) { - struct speedo_private *sp = (struct speedo_private *)dev->priv; + struct speedo_private *sp = netdev_priv(dev); struct RxFD *rxf, *last_rxf = NULL; dma_addr_t last_rxf_dma = 0 /* to shut up the compiler */; int i; @@ -1306,8 +1326,8 @@ skb_reserve(skb, sizeof(struct RxFD)); if (last_rxf) { last_rxf->link = cpu_to_le32(sp->rx_ring_dma[i]); - pci_dma_sync_single(sp->pdev, last_rxf_dma, - sizeof(struct RxFD), PCI_DMA_TODEVICE); + pci_dma_sync_single_for_device(sp->pdev, last_rxf_dma, + sizeof(struct RxFD), PCI_DMA_TODEVICE); } last_rxf = rxf; last_rxf_dma = sp->rx_ring_dma[i]; @@ -1316,21 +1336,21 @@ /* This field unused by i82557. */ rxf->rx_buf_addr = 0xffffffff; rxf->count = cpu_to_le32(PKT_BUF_SZ << 16); - pci_dma_sync_single(sp->pdev, sp->rx_ring_dma[i], - sizeof(struct RxFD), PCI_DMA_TODEVICE); + pci_dma_sync_single_for_device(sp->pdev, sp->rx_ring_dma[i], + sizeof(struct RxFD), PCI_DMA_TODEVICE); } sp->dirty_rx = (unsigned int)(i - RX_RING_SIZE); /* Mark the last entry as end-of-list. */ last_rxf->status = cpu_to_le32(0xC0000002); /* '2' is flag value only. */ - pci_dma_sync_single(sp->pdev, sp->rx_ring_dma[RX_RING_SIZE-1], - sizeof(struct RxFD), PCI_DMA_TODEVICE); + pci_dma_sync_single_for_device(sp->pdev, sp->rx_ring_dma[RX_RING_SIZE-1], + sizeof(struct RxFD), PCI_DMA_TODEVICE); sp->last_rxf = last_rxf; sp->last_rxf_dma = last_rxf_dma; } static void speedo_purge_tx(struct net_device *dev) { - struct speedo_private *sp = (struct speedo_private *)dev->priv; + struct speedo_private *sp = netdev_priv(dev); int entry; while ((int)(sp->cur_tx - sp->dirty_tx) > 0) { @@ -1362,7 +1382,7 @@ static void reset_mii(struct net_device *dev) { - struct speedo_private *sp = (struct speedo_private *)dev->priv; + struct speedo_private *sp = netdev_priv(dev); /* Reset the MII transceiver, suggested by Fred Young @ scalable.com. */ if ((sp->phy[0] & 0x8000) == 0) { @@ -1385,7 +1405,7 @@ static void speedo_tx_timeout(struct net_device *dev) { - struct speedo_private *sp = (struct speedo_private *)dev->priv; + struct speedo_private *sp = netdev_priv(dev); long ioaddr = dev->base_addr; int status = inw(ioaddr + SCBStatus); unsigned long flags; @@ -1447,7 +1467,7 @@ static int speedo_start_xmit(struct sk_buff *skb, struct net_device *dev) { - struct speedo_private *sp = (struct speedo_private *)dev->priv; + struct speedo_private *sp = netdev_priv(dev); long ioaddr = dev->base_addr; int entry; @@ -1518,7 +1538,7 @@ static void speedo_tx_buffer_gc(struct net_device *dev) { unsigned int dirty_tx; - struct speedo_private *sp = (struct speedo_private *)dev->priv; + struct speedo_private *sp = netdev_priv(dev); dirty_tx = sp->dirty_tx; while ((int)(sp->cur_tx - dirty_tx) > 0) { @@ -1585,7 +1605,7 @@ unsigned int handled = 0; ioaddr = dev->base_addr; - sp = (struct speedo_private *)dev->priv; + sp = netdev_priv(dev); #ifndef final_version /* A lock to prevent simultaneous entry on SMP machines. */ @@ -1677,7 +1697,7 @@ static inline struct RxFD *speedo_rx_alloc(struct net_device *dev, int entry) { - struct speedo_private *sp = (struct speedo_private *)dev->priv; + struct speedo_private *sp = netdev_priv(dev); struct RxFD *rxf; struct sk_buff *skb; /* Get a fresh skbuff to replace the consumed one. */ @@ -1696,29 +1716,29 @@ skb->dev = dev; skb_reserve(skb, sizeof(struct RxFD)); rxf->rx_buf_addr = 0xffffffff; - pci_dma_sync_single(sp->pdev, sp->rx_ring_dma[entry], - sizeof(struct RxFD), PCI_DMA_TODEVICE); + pci_dma_sync_single_for_device(sp->pdev, sp->rx_ring_dma[entry], + sizeof(struct RxFD), PCI_DMA_TODEVICE); return rxf; } static inline void speedo_rx_link(struct net_device *dev, int entry, struct RxFD *rxf, dma_addr_t rxf_dma) { - struct speedo_private *sp = (struct speedo_private *)dev->priv; + struct speedo_private *sp = netdev_priv(dev); rxf->status = cpu_to_le32(0xC0000001); /* '1' for driver use only. */ rxf->link = 0; /* None yet. */ rxf->count = cpu_to_le32(PKT_BUF_SZ << 16); sp->last_rxf->link = cpu_to_le32(rxf_dma); sp->last_rxf->status &= cpu_to_le32(~0xC0000000); - pci_dma_sync_single(sp->pdev, sp->last_rxf_dma, - sizeof(struct RxFD), PCI_DMA_TODEVICE); + pci_dma_sync_single_for_device(sp->pdev, sp->last_rxf_dma, + sizeof(struct RxFD), PCI_DMA_TODEVICE); sp->last_rxf = rxf; sp->last_rxf_dma = rxf_dma; } static int speedo_refill_rx_buf(struct net_device *dev, int force) { - struct speedo_private *sp = (struct speedo_private *)dev->priv; + struct speedo_private *sp = netdev_priv(dev); int entry; struct RxFD *rxf; @@ -1760,7 +1780,7 @@ static void speedo_refill_rx_buffers(struct net_device *dev, int force) { - struct speedo_private *sp = (struct speedo_private *)dev->priv; + struct speedo_private *sp = netdev_priv(dev); /* Refill the RX ring. */ while ((int)(sp->cur_rx - sp->dirty_rx) > 0 && @@ -1770,7 +1790,7 @@ static int speedo_rx(struct net_device *dev) { - struct speedo_private *sp = (struct speedo_private *)dev->priv; + struct speedo_private *sp = netdev_priv(dev); int entry = sp->cur_rx % RX_RING_SIZE; int rx_work_limit = sp->dirty_rx + RX_RING_SIZE - sp->cur_rx; int alloc_ok = 1; @@ -1783,8 +1803,8 @@ int status; int pkt_len; - pci_dma_sync_single(sp->pdev, sp->rx_ring_dma[entry], - sizeof(struct RxFD), PCI_DMA_FROMDEVICE); + pci_dma_sync_single_for_cpu(sp->pdev, sp->rx_ring_dma[entry], + sizeof(struct RxFD), PCI_DMA_FROMDEVICE); status = le32_to_cpu(sp->rx_ringp[entry]->status); pkt_len = le32_to_cpu(sp->rx_ringp[entry]->count) & 0x3fff; @@ -1830,8 +1850,9 @@ skb->dev = dev; skb_reserve(skb, 2); /* Align IP on 16 byte boundaries */ /* 'skb_put()' points to the start of sk_buff data area. */ - pci_dma_sync_single(sp->pdev, sp->rx_ring_dma[entry], - sizeof(struct RxFD) + pkt_len, PCI_DMA_FROMDEVICE); + pci_dma_sync_single_for_cpu(sp->pdev, sp->rx_ring_dma[entry], + sizeof(struct RxFD) + pkt_len, + PCI_DMA_FROMDEVICE); #if 1 || USE_IP_CSUM /* Packet is in one chunk -- we can copy + cksum. */ @@ -1841,6 +1862,9 @@ memcpy(skb_put(skb, pkt_len), sp->rx_skbuff[entry]->tail, pkt_len); #endif + pci_dma_sync_single_for_device(sp->pdev, sp->rx_ring_dma[entry], + sizeof(struct RxFD) + pkt_len, + PCI_DMA_FROMDEVICE); npkts++; } else { /* Pass up the already-filled skbuff. */ @@ -1855,7 +1879,8 @@ npkts++; sp->rx_ringp[entry] = NULL; pci_unmap_single(sp->pdev, sp->rx_ring_dma[entry], - PKT_BUF_SZ + sizeof(struct RxFD), PCI_DMA_FROMDEVICE); + PKT_BUF_SZ + sizeof(struct RxFD), + PCI_DMA_FROMDEVICE); } skb->protocol = eth_type_trans(skb, dev); netif_rx(skb); @@ -1884,7 +1909,7 @@ speedo_close(struct net_device *dev) { long ioaddr = dev->base_addr; - struct speedo_private *sp = (struct speedo_private *)dev->priv; + struct speedo_private *sp = netdev_priv(dev); int i; netdevice_stop(dev); @@ -1962,7 +1987,7 @@ static struct net_device_stats * speedo_get_stats(struct net_device *dev) { - struct speedo_private *sp = (struct speedo_private *)dev->priv; + struct speedo_private *sp = netdev_priv(dev); long ioaddr = dev->base_addr; /* Update only if the previous dump finished. */ @@ -1995,7 +2020,7 @@ static int netdev_ethtool_ioctl(struct net_device *dev, void *useraddr) { u32 ethcmd; - struct speedo_private *sp = dev->priv; + struct speedo_private *sp = netdev_priv(dev); if (copy_from_user(ðcmd, useraddr, sizeof(ethcmd))) return -EFAULT; @@ -2070,7 +2095,7 @@ static int speedo_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) { - struct speedo_private *sp = (struct speedo_private *)dev->priv; + struct speedo_private *sp = netdev_priv(dev); struct mii_ioctl_data *data = (struct mii_ioctl_data *)&rq->ifr_data; int phy = sp->phy[0] & 0x1f; int saved_acpi; @@ -2121,7 +2146,7 @@ */ static void set_rx_mode(struct net_device *dev) { - struct speedo_private *sp = (struct speedo_private *)dev->priv; + struct speedo_private *sp = netdev_priv(dev); long ioaddr = dev->base_addr; struct descriptor *last_cmd; char new_rx_mode; @@ -2287,8 +2312,8 @@ mc_setup_frm->link = cpu_to_le32(TX_RING_ELEM_DMA(sp, (entry + 1) % TX_RING_SIZE)); - pci_dma_sync_single(sp->pdev, mc_blk->frame_dma, - mc_blk->len, PCI_DMA_TODEVICE); + pci_dma_sync_single_for_device(sp->pdev, mc_blk->frame_dma, + mc_blk->len, PCI_DMA_TODEVICE); wait_for_cmd_done(dev); clear_suspend(last_cmd); @@ -2313,7 +2338,7 @@ static int eepro100_suspend(struct pci_dev *pdev, u32 state) { struct net_device *dev = pci_get_drvdata (pdev); - struct speedo_private *sp = (struct speedo_private *)dev->priv; + struct speedo_private *sp = netdev_priv(dev); long ioaddr = dev->base_addr; pci_save_state(pdev, sp->pm_state); @@ -2333,7 +2358,7 @@ static int eepro100_resume(struct pci_dev *pdev) { struct net_device *dev = pci_get_drvdata (pdev); - struct speedo_private *sp = (struct speedo_private *)dev->priv; + struct speedo_private *sp = netdev_priv(dev); long ioaddr = dev->base_addr; pci_restore_state(pdev, sp->pm_state); @@ -2363,7 +2388,7 @@ static void __devexit eepro100_remove_one (struct pci_dev *pdev) { struct net_device *dev = pci_get_drvdata (pdev); - struct speedo_private *sp = (struct speedo_private *)dev->priv; + struct speedo_private *sp = netdev_priv(dev); unregister_netdev(dev); diff -Nru a/drivers/net/eexpress.c b/drivers/net/eexpress.c --- a/drivers/net/eexpress.c Sun Mar 14 14:20:05 2004 +++ b/drivers/net/eexpress.c Sun Mar 14 14:20:05 2004 @@ -452,7 +452,7 @@ { int ret; unsigned short ioaddr = dev->base_addr; - struct net_local *lp = (struct net_local *)dev->priv; + struct net_local *lp = netdev_priv(dev); #if NET_DEBUG > 6 printk(KERN_DEBUG "%s: eexp_open()\n", dev->name); @@ -515,7 +515,7 @@ static int eexp_close(struct net_device *dev) { unsigned short ioaddr = dev->base_addr; - struct net_local *lp = dev->priv; + struct net_local *lp = netdev_priv(dev); int irq = dev->irq; @@ -541,7 +541,7 @@ static struct net_device_stats *eexp_stats(struct net_device *dev) { - struct net_local *lp = (struct net_local *)dev->priv; + struct net_local *lp = netdev_priv(dev); return &lp->stats; } @@ -553,7 +553,7 @@ static void unstick_cu(struct net_device *dev) { - struct net_local *lp = (struct net_local *)dev->priv; + struct net_local *lp = netdev_priv(dev); unsigned short ioaddr = dev->base_addr; if (lp->started) @@ -627,7 +627,7 @@ static void eexp_timeout(struct net_device *dev) { - struct net_local *lp = (struct net_local *)dev->priv; + struct net_local *lp = netdev_priv(dev); #ifdef CONFIG_SMP unsigned long flags; #endif @@ -667,7 +667,7 @@ */ static int eexp_xmit(struct sk_buff *buf, struct net_device *dev) { - struct net_local *lp = (struct net_local *)dev->priv; + struct net_local *lp = netdev_priv(dev); short length = buf->len; #ifdef CONFIG_SMP unsigned long flags; @@ -728,7 +728,7 @@ unsigned short status) { unsigned short ack_cmd = SCB_ack(status); - struct net_local *lp = (struct net_local *)dev->priv; + struct net_local *lp = netdev_priv(dev); unsigned short ioaddr = dev->base_addr; if ((dev->flags & IFF_UP) && !(lp->started & STARTED_CU)) { short diag_status, tdr_status; @@ -806,7 +806,7 @@ return IRQ_NONE; } - lp = (struct net_local *)dev->priv; + lp = netdev_priv(dev); ioaddr = dev->base_addr; spin_lock(&lp->lock); @@ -925,7 +925,7 @@ static void eexp_hw_rx_pio(struct net_device *dev) { - struct net_local *lp = (struct net_local *)dev->priv; + struct net_local *lp = netdev_priv(dev); unsigned short rx_block = lp->rx_ptr; unsigned short boguscount = lp->num_rx_bufs; unsigned short ioaddr = dev->base_addr; @@ -1022,7 +1022,7 @@ static void eexp_hw_tx_pio(struct net_device *dev, unsigned short *buf, unsigned short len) { - struct net_local *lp = (struct net_local *)dev->priv; + struct net_local *lp = netdev_priv(dev); unsigned short ioaddr = dev->base_addr; if (LOCKUP16 || lp->width) { @@ -1090,7 +1090,7 @@ unsigned int memory_size; int i; unsigned short xsum = 0; - struct net_local *lp = dev->priv; + struct net_local *lp = netdev_priv(dev); printk("%s: EtherExpress 16 at %#x ",dev->name,ioaddr); @@ -1262,7 +1262,7 @@ static unsigned short eexp_hw_lasttxstat(struct net_device *dev) { - struct net_local *lp = (struct net_local *)dev->priv; + struct net_local *lp = netdev_priv(dev); unsigned short tx_block = lp->tx_reap; unsigned short status; @@ -1332,7 +1332,7 @@ static void eexp_hw_txrestart(struct net_device *dev) { - struct net_local *lp = (struct net_local *)dev->priv; + struct net_local *lp = netdev_priv(dev); unsigned short ioaddr = dev->base_addr; lp->last_tx_restart = lp->tx_link; @@ -1377,7 +1377,7 @@ static void eexp_hw_txinit(struct net_device *dev) { - struct net_local *lp = (struct net_local *)dev->priv; + struct net_local *lp = netdev_priv(dev); unsigned short tx_block = TX_BUF_START; unsigned short curtbuf; unsigned short ioaddr = dev->base_addr; @@ -1419,7 +1419,7 @@ static void eexp_hw_rxinit(struct net_device *dev) { - struct net_local *lp = (struct net_local *)dev->priv; + struct net_local *lp = netdev_priv(dev); unsigned short rx_block = lp->rx_buf_start; unsigned short ioaddr = dev->base_addr; @@ -1478,7 +1478,7 @@ static void eexp_hw_init586(struct net_device *dev) { - struct net_local *lp = (struct net_local *)dev->priv; + struct net_local *lp = netdev_priv(dev); unsigned short ioaddr = dev->base_addr; int i; @@ -1639,7 +1639,7 @@ eexp_set_multicast(struct net_device *dev) { unsigned short ioaddr = dev->base_addr; - struct net_local *lp = (struct net_local *)dev->priv; + struct net_local *lp = netdev_priv(dev); int kick = 0, i; if ((dev->flags & IFF_PROMISC) != lp->was_promisc) { outw(CONF_PROMISC & ~31, ioaddr+SM_PTR); diff -Nru a/drivers/net/epic100.c b/drivers/net/epic100.c --- a/drivers/net/epic100.c Sun Mar 14 14:20:07 2004 +++ b/drivers/net/epic100.c Sun Mar 14 14:20:07 2004 @@ -1199,8 +1199,6 @@ short pkt_len = (status >> 16) - 4; struct sk_buff *skb; - pci_dma_sync_single(ep->pci_dev, ep->rx_ring[entry].bufaddr, - ep->rx_buf_sz, PCI_DMA_FROMDEVICE); if (pkt_len > PKT_BUF_SZ - 4) { printk(KERN_ERR "%s: Oversized Ethernet frame, status %x " "%d bytes.\n", @@ -1213,6 +1211,10 @@ && (skb = dev_alloc_skb(pkt_len + 2)) != NULL) { skb->dev = dev; skb_reserve(skb, 2); /* 16 byte align the IP header */ + pci_dma_sync_single_for_cpu(ep->pci_dev, + ep->rx_ring[entry].bufaddr, + ep->rx_buf_sz, + PCI_DMA_FROMDEVICE); #if 1 /* HAS_IP_COPYSUM */ eth_copy_and_sum(skb, ep->rx_skbuff[entry]->tail, pkt_len, 0); skb_put(skb, pkt_len); @@ -1220,6 +1222,10 @@ memcpy(skb_put(skb, pkt_len), ep->rx_skbuff[entry]->tail, pkt_len); #endif + pci_dma_sync_single_for_device(ep->pci_dev, + ep->rx_ring[entry].bufaddr, + ep->rx_buf_sz, + PCI_DMA_FROMDEVICE); } else { pci_unmap_single(ep->pci_dev, ep->rx_ring[entry].bufaddr, diff -Nru a/drivers/net/es3210.c b/drivers/net/es3210.c --- a/drivers/net/es3210.c Sun Mar 14 14:20:08 2004 +++ b/drivers/net/es3210.c Sun Mar 14 14:20:08 2004 @@ -298,6 +298,9 @@ dev->open = &es_open; dev->stop = &es_close; +#ifdef CONFIG_NET_POLL_CONTROLLER + dev->poll_controller = ei_poll; +#endif NS8390_init(dev, 0); return 0; out1: diff -Nru a/drivers/net/eth16i.c b/drivers/net/eth16i.c --- a/drivers/net/eth16i.c Sun Mar 14 14:20:08 2004 +++ b/drivers/net/eth16i.c Sun Mar 14 14:20:08 2004 @@ -486,7 +486,7 @@ static int __init eth16i_probe1(struct net_device *dev, int ioaddr) { - struct eth16i_local *lp = dev->priv; + struct eth16i_local *lp = netdev_priv(dev); static unsigned version_printed; int retval; @@ -950,7 +950,7 @@ static int eth16i_open(struct net_device *dev) { - struct eth16i_local *lp = (struct eth16i_local *)dev->priv; + struct eth16i_local *lp = netdev_priv(dev); int ioaddr = dev->base_addr; /* Powerup the chip */ @@ -986,7 +986,7 @@ static int eth16i_close(struct net_device *dev) { - struct eth16i_local *lp = (struct eth16i_local *)dev->priv; + struct eth16i_local *lp = netdev_priv(dev); int ioaddr = dev->base_addr; eth16i_reset(dev); @@ -1012,7 +1012,7 @@ static void eth16i_timeout(struct net_device *dev) { - struct eth16i_local *lp = (struct eth16i_local *)dev->priv; + struct eth16i_local *lp = netdev_priv(dev); int ioaddr = dev->base_addr; /* If we get here, some higher level has decided that @@ -1053,7 +1053,7 @@ static int eth16i_tx(struct sk_buff *skb, struct net_device *dev) { - struct eth16i_local *lp = (struct eth16i_local *)dev->priv; + struct eth16i_local *lp = netdev_priv(dev); int ioaddr = dev->base_addr; int status = 0; ushort length = skb->len; @@ -1130,7 +1130,7 @@ static void eth16i_rx(struct net_device *dev) { - struct eth16i_local *lp = (struct eth16i_local *)dev->priv; + struct eth16i_local *lp = netdev_priv(dev); int ioaddr = dev->base_addr; int boguscount = MAX_RX_LOOP; @@ -1232,7 +1232,7 @@ int handled = 0; ioaddr = dev->base_addr; - lp = (struct eth16i_local *)dev->priv; + lp = netdev_priv(dev); /* Turn off all interrupts from adapter */ outw(ETH16I_INTR_OFF, ioaddr + TX_INTR_REG); @@ -1340,7 +1340,7 @@ static void eth16i_reset(struct net_device *dev) { - struct eth16i_local *lp = (struct eth16i_local *)dev->priv; + struct eth16i_local *lp = netdev_priv(dev); int ioaddr = dev->base_addr; if(eth16i_debug > 1) @@ -1372,7 +1372,7 @@ static struct net_device_stats *eth16i_get_stats(struct net_device *dev) { - struct eth16i_local *lp = (struct eth16i_local *)dev->priv; + struct eth16i_local *lp = netdev_priv(dev); return &lp->stats; } diff -Nru a/drivers/net/ethertap.c b/drivers/net/ethertap.c --- a/drivers/net/ethertap.c Sun Mar 14 14:20:06 2004 +++ b/drivers/net/ethertap.c Sun Mar 14 14:20:06 2004 @@ -121,7 +121,7 @@ static int ethertap_open(struct net_device *dev) { - struct net_local *lp = (struct net_local*)dev->priv; + struct net_local *lp = netdev_priv(dev); if (ethertap_debug > 2) printk(KERN_DEBUG "%s: Doing ethertap_open()...", dev->name); @@ -150,7 +150,7 @@ static void set_multicast_list(struct net_device *dev) { unsigned groups = ~0; - struct net_local *lp = (struct net_local *)dev->priv; + struct net_local *lp = netdev_priv(dev); if (!(dev->flags&(IFF_NOARP|IFF_PROMISC|IFF_ALLMULTI))) { struct dev_mc_list *dmi; @@ -176,7 +176,7 @@ static int ethertap_start_xmit(struct sk_buff *skb, struct net_device *dev) { - struct net_local *lp = (struct net_local *)dev->priv; + struct net_local *lp = netdev_priv(dev); #ifdef CONFIG_ETHERTAP_MC struct ethhdr *eth = (struct ethhdr*)skb->data; #endif @@ -234,7 +234,7 @@ static __inline__ int ethertap_rx_skb(struct sk_buff *skb, struct net_device *dev) { - struct net_local *lp = (struct net_local *)dev->priv; + struct net_local *lp = netdev_priv(dev); #ifdef CONFIG_ETHERTAP_MC struct ethhdr *eth = (struct ethhdr*)(skb->data + 2); #endif @@ -320,7 +320,7 @@ static int ethertap_close(struct net_device *dev) { - struct net_local *lp = (struct net_local *)dev->priv; + struct net_local *lp = netdev_priv(dev); struct sock *sk = lp->nl; if (ethertap_debug > 2) @@ -338,7 +338,7 @@ static struct net_device_stats *ethertap_get_stats(struct net_device *dev) { - struct net_local *lp = (struct net_local *)dev->priv; + struct net_local *lp = netdev_priv(dev); return &lp->stats; } diff -Nru a/drivers/net/fc/iph5526.c b/drivers/net/fc/iph5526.c --- a/drivers/net/fc/iph5526.c Sun Mar 14 14:20:06 2004 +++ b/drivers/net/fc/iph5526.c Sun Mar 14 14:20:06 2004 @@ -238,7 +238,7 @@ static int __init iph5526_probe_pci(struct net_device *dev) { - struct fc_info *fi = (struct fc_info *)dev->priv; + struct fc_info *fi = netdev_priv(dev); fi->dev = dev; dev->base_addr = fi->base_addr; dev->irq = fi->irq; @@ -2908,7 +2908,7 @@ static void iph5526_timeout(struct net_device *dev) { - struct fc_info *fi = (struct fc_info*)dev->priv; + struct fc_info *fi = netdev_priv(dev); printk(KERN_WARNING "%s: timed out on send.\n", dev->name); fi->fc_stats.rx_dropped++; dev->trans_start = jiffies; @@ -2917,7 +2917,7 @@ static int iph5526_send_packet(struct sk_buff *skb, struct net_device *dev) { - struct fc_info *fi = (struct fc_info*)dev->priv; + struct fc_info *fi = netdev_priv(dev); int status = 0; short type = 0; u_long flags; @@ -3688,7 +3688,7 @@ static struct net_device_stats * iph5526_get_stats(struct net_device *dev) { -struct fc_info *fi = (struct fc_info*)dev->priv; +struct fc_info *fi = netdev_priv(dev); return (struct net_device_stats *) &fi->fc_stats; } diff -Nru a/drivers/net/fealnx.c b/drivers/net/fealnx.c --- a/drivers/net/fealnx.c Sun Mar 14 14:20:07 2004 +++ b/drivers/net/fealnx.c Sun Mar 14 14:20:07 2004 @@ -1647,10 +1647,6 @@ printk(KERN_DEBUG " netdev_rx() normal Rx pkt length %d" " status %x.\n", pkt_len, rx_status); #endif - pci_dma_sync_single(np->pci_dev, np->cur_rx->buffer, - np->rx_buf_sz, PCI_DMA_FROMDEVICE); - pci_unmap_single(np->pci_dev, np->cur_rx->buffer, - np->rx_buf_sz, PCI_DMA_FROMDEVICE); /* Check if the packet is long enough to accept without copying to a minimally-sized skbuff. */ @@ -1658,6 +1654,10 @@ (skb = dev_alloc_skb(pkt_len + 2)) != NULL) { skb->dev = dev; skb_reserve(skb, 2); /* 16 byte align the IP header */ + pci_dma_sync_single_for_cpu(np->pci_dev, + np->cur_rx->buffer, + np->rx_buf_sz, + PCI_DMA_FROMDEVICE); /* Call copy + cksum if available. */ #if ! defined(__alpha__) @@ -1668,7 +1668,15 @@ memcpy(skb_put(skb, pkt_len), np->cur_rx->skbuff->tail, pkt_len); #endif + pci_dma_sync_single_for_device(np->pci_dev, + np->cur_rx->buffer, + np->rx_buf_sz, + PCI_DMA_FROMDEVICE); } else { + pci_unmap_single(np->pci_dev, + np->cur_rx->buffer, + np->rx_buf_sz, + PCI_DMA_FROMDEVICE); skb_put(skb = np->cur_rx->skbuff, pkt_len); np->cur_rx->skbuff = NULL; if (np->really_rx_count == RX_RING_SIZE) @@ -1689,8 +1697,10 @@ if (skb != NULL) { skb->dev = dev; /* Mark as being used by this device. */ - np->cur_rx->buffer = pci_map_single(np->pci_dev, skb->tail, - np->rx_buf_sz, PCI_DMA_FROMDEVICE); + np->cur_rx->buffer = pci_map_single(np->pci_dev, + skb->tail, + np->rx_buf_sz, + PCI_DMA_FROMDEVICE); np->cur_rx->skbuff = skb; ++np->really_rx_count; } diff -Nru a/drivers/net/fec.c b/drivers/net/fec.c --- a/drivers/net/fec.c Sun Mar 14 14:20:06 2004 +++ b/drivers/net/fec.c Sun Mar 14 14:20:06 2004 @@ -269,7 +269,7 @@ volatile fec_t *fecp; volatile cbd_t *bdp; - fep = dev->priv; + fep = netdev_priv(dev); fecp = (volatile fec_t*)dev->base_addr; if (!fep->link) { @@ -349,7 +349,7 @@ static void fec_timeout(struct net_device *dev) { - struct fec_enet_private *fep = dev->priv; + struct fec_enet_private *fep = netdev_priv(dev); printk("%s: transmit timed out.\n", dev->name); fep->stats.tx_errors++; @@ -445,7 +445,7 @@ volatile cbd_t *bdp; struct sk_buff *skb; - fep = dev->priv; + fep = netdev_priv(dev); spin_lock(&fep->lock); bdp = fep->dirty_tx; @@ -524,7 +524,7 @@ ushort pkt_len; __u8 *data; - fep = dev->priv; + fep = netdev_priv(dev); fecp = (volatile fec_t*)dev->base_addr; /* First, grab all of the stats for the incoming packet. @@ -645,7 +645,7 @@ mii_list_t *mip; uint mii_reg; - fep = (struct fec_enet_private *)dev->priv; + fep = netdev_priv(dev); ep = fec_hwp; mii_reg = ep->fec_mii_data; @@ -675,7 +675,7 @@ /* Add PHY address to register command. */ - fep = dev->priv; + fep = netdev_priv(dev); regval |= fep->phy_addr << 23; retval = 0; @@ -720,7 +720,7 @@ static void mii_parse_sr(uint mii_reg, struct net_device *dev) { - struct fec_enet_private *fep = dev->priv; + struct fec_enet_private *fep = netdev_priv(dev); volatile uint *s = &(fep->phy_status); *s &= ~(PHY_STAT_LINK | PHY_STAT_FAULT | PHY_STAT_ANC); @@ -735,7 +735,7 @@ static void mii_parse_cr(uint mii_reg, struct net_device *dev) { - struct fec_enet_private *fep = dev->priv; + struct fec_enet_private *fep = netdev_priv(dev); volatile uint *s = &(fep->phy_status); *s &= ~(PHY_CONF_ANE | PHY_CONF_LOOP); @@ -748,7 +748,7 @@ static void mii_parse_anar(uint mii_reg, struct net_device *dev) { - struct fec_enet_private *fep = dev->priv; + struct fec_enet_private *fep = netdev_priv(dev); volatile uint *s = &(fep->phy_status); *s &= ~(PHY_CONF_SPMASK); @@ -774,7 +774,7 @@ static void mii_parse_lxt970_csr(uint mii_reg, struct net_device *dev) { - struct fec_enet_private *fep = dev->priv; + struct fec_enet_private *fep = netdev_priv(dev); volatile uint *s = &(fep->phy_status); *s &= ~(PHY_STAT_SPMASK); @@ -841,7 +841,7 @@ static void mii_parse_lxt971_sr2(uint mii_reg, struct net_device *dev) { - struct fec_enet_private *fep = dev->priv; + struct fec_enet_private *fep = netdev_priv(dev); volatile uint *s = &(fep->phy_status); *s &= ~(PHY_STAT_SPMASK | PHY_STAT_LINK | PHY_STAT_ANC); @@ -919,7 +919,7 @@ static void mii_parse_qs6612_pcr(uint mii_reg, struct net_device *dev) { - struct fec_enet_private *fep = dev->priv; + struct fec_enet_private *fep = netdev_priv(dev); volatile uint *s = &(fep->phy_status); *s &= ~(PHY_STAT_SPMASK); @@ -983,7 +983,7 @@ static void mii_parse_am79c874_dr(uint mii_reg, struct net_device *dev) { - struct fec_enet_private *fep = dev->priv; + struct fec_enet_private *fep = netdev_priv(dev); volatile uint *s = &(fep->phy_status); *s &= ~(PHY_STAT_SPMASK | PHY_STAT_ANC); @@ -1280,7 +1280,7 @@ static void mii_display_status(struct net_device *dev) { - struct fec_enet_private *fep = dev->priv; + struct fec_enet_private *fep = netdev_priv(dev); volatile uint *s = &(fep->phy_status); if (!fep->link && !fep->old_link) { @@ -1316,7 +1316,7 @@ static void mii_display_config(struct net_device *dev) { - struct fec_enet_private *fep = dev->priv; + struct fec_enet_private *fep = netdev_priv(dev); volatile uint *s = &(fep->phy_status); printk("%s: config: auto-negotiation ", dev->name); @@ -1347,7 +1347,7 @@ static void mii_relink(struct net_device *dev) { - struct fec_enet_private *fep = dev->priv; + struct fec_enet_private *fep = netdev_priv(dev); int duplex; fep->link = (fep->phy_status & PHY_STAT_LINK) ? 1 : 0; @@ -1372,7 +1372,7 @@ static void mii_queue_relink(uint mii_reg, struct net_device *dev) { - struct fec_enet_private *fep = dev->priv; + struct fec_enet_private *fep = netdev_priv(dev); INIT_WORK(&fep->phy_task, (void*)mii_relink, dev); schedule_work(&fep->phy_task); @@ -1380,7 +1380,7 @@ static void mii_queue_config(uint mii_reg, struct net_device *dev) { - struct fec_enet_private *fep = dev->priv; + struct fec_enet_private *fep = netdev_priv(dev); INIT_WORK(&fep->phy_task, (void*)mii_display_config, dev); schedule_work(&fep->phy_task); @@ -1403,7 +1403,7 @@ struct fec_enet_private *fep; int i; - fep = dev->priv; + fep = netdev_priv(dev); fep->phy_id |= (mii_reg & 0xffff); printk("fec: PHY @ 0x%x, ID 0x%08x", fep->phy_addr, fep->phy_id); @@ -1431,7 +1431,7 @@ volatile fec_t *fecp; uint phytype; - fep = dev->priv; + fep = netdev_priv(dev); fecp = fec_hwp; if (fep->phy_addr < 32) { @@ -1466,7 +1466,7 @@ #endif { struct net_device *dev = dev_id; - struct fec_enet_private *fep = dev->priv; + struct fec_enet_private *fep = netdev_priv(dev); fec_phy_ack_intr(); @@ -1482,7 +1482,7 @@ static int fec_enet_open(struct net_device *dev) { - struct fec_enet_private *fep = dev->priv; + struct fec_enet_private *fep = netdev_priv(dev); /* I should reset the ring buffers here, but I don't yet know * a simple way to do that. @@ -1531,7 +1531,7 @@ static struct net_device_stats *fec_enet_get_stats(struct net_device *dev) { - struct fec_enet_private *fep = (struct fec_enet_private *)dev->priv; + struct fec_enet_private *fep = netdev_priv(dev); return &fep->stats; } @@ -1557,7 +1557,7 @@ unsigned int i, j, bit, data, crc; unsigned char hash; - fep = (struct fec_enet_private *)dev->priv; + fep = netdev_priv(dev); ep = fec_hwp; if (dev->flags&IFF_PROMISC) { @@ -1643,7 +1643,7 @@ */ int __init fec_enet_init(struct net_device *dev) { - struct fec_enet_private *fep = dev->priv; + struct fec_enet_private *fep = netdev_priv(dev); unsigned long mem_addr; volatile cbd_t *bdp; cbd_t *cbd_base; @@ -1807,7 +1807,7 @@ fecp = fec_hwp; - fep = dev->priv; + fep = netdev_priv(dev); /* Whack a reset. We should wait for this. */ @@ -1924,7 +1924,7 @@ struct fec_enet_private *fep; fecp = fec_hwp; - fep = dev->priv; + fep = netdev_priv(dev); fecp->fec_x_cntrl = 0x01; /* Graceful transmit stop */ diff -Nru a/drivers/net/forcedeth.c b/drivers/net/forcedeth.c --- a/drivers/net/forcedeth.c Sun Mar 14 14:20:06 2004 +++ b/drivers/net/forcedeth.c Sun Mar 14 14:20:06 2004 @@ -11,6 +11,7 @@ * countries. * * Copyright (C) 2003 Manfred Spraul + * Copyright (C) 2004 Andrew de Quincey (wol support) * * 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 @@ -28,7 +29,7 @@ * * Changelog: * 0.01: 05 Oct 2003: First release that compiles without warnings. - * 0.02: 05 Oct 2003: Fix bug for drain_tx: do not try to free NULL skbs. + * 0.02: 05 Oct 2003: Fix bug for nv_drain_tx: do not try to free NULL skbs. * Check all PCI BARs for the register window. * udelay added to mii_rw. * 0.03: 06 Oct 2003: Initialize dev->irq. @@ -37,7 +38,7 @@ * 0.06: 10 Oct 2003: MAC Address read updated, pff flag generation updated, * irq mask updated * 0.07: 14 Oct 2003: Further irq mask updates. - * 0.08: 20 Oct 2003: rx_desc.Length initialization added, alloc_rx refill + * 0.08: 20 Oct 2003: rx_desc.Length initialization added, nv_alloc_rx refill * added into irq handler, NULL check for drain_ring. * 0.09: 20 Oct 2003: Basic link speed irq implementation. Only handle the * requested interrupt sources. @@ -47,7 +48,7 @@ * 0.12: 23 Oct 2003: Cleanups for release. * 0.13: 25 Oct 2003: Limit for concurrent tx packets increased to 10. * Set link speed correctly. start rx before starting - * tx (start_rx sets the link speed). + * tx (nv_start_rx sets the link speed). * 0.14: 25 Oct 2003: Nic dependant irq mask. * 0.15: 08 Nov 2003: fix smp deadlock with set_multicast_list during * open. @@ -58,7 +59,7 @@ * 0.18: 17 Nov 2003: fix oops due to late initialization of dev_stats * 0.19: 29 Nov 2003: Handle RxNoBuf, detect & handle invalid mac * addresses, really stop rx if already running - * in start_rx, clean up a bit. + * in nv_start_rx, clean up a bit. * (C) Carl-Daniel Hailfinger * 0.20: 07 Dec 2003: alloc fixes * 0.21: 12 Jan 2004: additional alloc fix, nic polling fix. @@ -66,6 +67,8 @@ * on close. * (C) Carl-Daniel Hailfinger, Manfred Spraul * 0.23: 26 Jan 2004: various small cleanups + * 0.24: 27 Feb 2004: make driver even less anonymous in backtraces + * 0.25: 09 Mar 2004: wol support * * Known bugs: * We suspect that on some hardware no TX done interrupts are generated. @@ -77,7 +80,7 @@ * DEV_NEED_TIMERIRQ will not harm you on sane hardware, only generating a few * superfluous timer interrupts from the nic. */ -#define FORCEDETH_VERSION "0.23" +#define FORCEDETH_VERSION "0.25" #include #include @@ -232,6 +235,7 @@ #define NVREG_WAKEUPFLAGS_ACCEPT_MAGPAT 0x01 #define NVREG_WAKEUPFLAGS_ACCEPT_WAKEUPPAT 0x02 #define NVREG_WAKEUPFLAGS_ACCEPT_LINKCHANGE 0x04 +#define NVREG_WAKEUPFLAGS_ENABLE 0x1111 NvRegPatternCRC = 0x204, NvRegPatternMask = 0x208, @@ -340,6 +344,7 @@ u32 linkspeed; int duplex; int phyaddr; + int wolenabled; /* General data: RO fields */ dma_addr_t ring_addr; @@ -468,12 +473,12 @@ return retval; } -static void start_rx(struct net_device *dev) +static void nv_start_rx(struct net_device *dev) { struct fe_priv *np = get_nvpriv(dev); u8 *base = get_hwbase(dev); - dprintk(KERN_DEBUG "%s: start_rx\n", dev->name); + dprintk(KERN_DEBUG "%s: nv_start_rx\n", dev->name); /* Already running? Stop it. */ if (readl(base + NvRegReceiverControl) & NVREG_RCVCTL_START) { writel(0, base + NvRegReceiverControl); @@ -485,48 +490,48 @@ pci_push(base); } -static void stop_rx(struct net_device *dev) +static void nv_stop_rx(struct net_device *dev) { u8 *base = get_hwbase(dev); - dprintk(KERN_DEBUG "%s: stop_rx\n", dev->name); + dprintk(KERN_DEBUG "%s: nv_stop_rx\n", dev->name); writel(0, base + NvRegReceiverControl); reg_delay(dev, NvRegReceiverStatus, NVREG_RCVSTAT_BUSY, 0, NV_RXSTOP_DELAY1, NV_RXSTOP_DELAY1MAX, - KERN_INFO "stop_rx: ReceiverStatus remained busy"); + KERN_INFO "nv_stop_rx: ReceiverStatus remained busy"); udelay(NV_RXSTOP_DELAY2); writel(0, base + NvRegLinkSpeed); } -static void start_tx(struct net_device *dev) +static void nv_start_tx(struct net_device *dev) { u8 *base = get_hwbase(dev); - dprintk(KERN_DEBUG "%s: start_tx\n", dev->name); + dprintk(KERN_DEBUG "%s: nv_start_tx\n", dev->name); writel(NVREG_XMITCTL_START, base + NvRegTransmitterControl); pci_push(base); } -static void stop_tx(struct net_device *dev) +static void nv_stop_tx(struct net_device *dev) { u8 *base = get_hwbase(dev); - dprintk(KERN_DEBUG "%s: stop_tx\n", dev->name); + dprintk(KERN_DEBUG "%s: nv_stop_tx\n", dev->name); writel(0, base + NvRegTransmitterControl); reg_delay(dev, NvRegTransmitterStatus, NVREG_XMITSTAT_BUSY, 0, NV_TXSTOP_DELAY1, NV_TXSTOP_DELAY1MAX, - KERN_INFO "stop_tx: TransmitterStatus remained busy"); + KERN_INFO "nv_stop_tx: TransmitterStatus remained busy"); udelay(NV_TXSTOP_DELAY2); writel(0, base + NvRegUnknownTransmitterReg); } -static void txrx_reset(struct net_device *dev) +static void nv_txrx_reset(struct net_device *dev) { u8 *base = get_hwbase(dev); - dprintk(KERN_DEBUG "%s: txrx_reset\n", dev->name); + dprintk(KERN_DEBUG "%s: nv_txrx_reset\n", dev->name); writel(NVREG_TXRXCTL_BIT2 | NVREG_TXRXCTL_RESET, base + NvRegTxRxControl); pci_push(base); udelay(NV_TXRX_RESET_DELAY); @@ -551,9 +556,10 @@ return &np->stats; } -static int nv_ethtool_ioctl (struct net_device *dev, void *useraddr) +static int nv_ethtool_ioctl(struct net_device *dev, void *useraddr) { struct fe_priv *np = get_nvpriv(dev); + u8 *base = get_hwbase(dev); u32 ethcmd; if (copy_from_user(ðcmd, useraddr, sizeof (ethcmd))) @@ -580,6 +586,39 @@ return -EFAULT; return 0; } + case ETHTOOL_GWOL: + { + struct ethtool_wolinfo wolinfo; + memset(&wolinfo, 0, sizeof(wolinfo)); + wolinfo.supported = WAKE_MAGIC; + + spin_lock_irq(&np->lock); + if (np->wolenabled) + wolinfo.wolopts = WAKE_MAGIC; + spin_unlock_irq(&np->lock); + + if (copy_to_user(useraddr, &wolinfo, sizeof(wolinfo))) + return -EFAULT; + return 0; + } + case ETHTOOL_SWOL: + { + struct ethtool_wolinfo wolinfo; + if (copy_from_user(&wolinfo, useraddr, sizeof(wolinfo))) + return -EFAULT; + + spin_lock_irq(&np->lock); + if (wolinfo.wolopts == 0) { + writel(0, base + NvRegWakeUpFlags); + np->wolenabled = 0; + } + if (wolinfo.wolopts & WAKE_MAGIC) { + writel(NVREG_WAKEUPFLAGS_ENABLE, base + NvRegWakeUpFlags); + np->wolenabled = 1; + } + spin_unlock_irq(&np->lock); + return 0; + } default: break; @@ -603,11 +642,11 @@ } /* - * alloc_rx: fill rx ring entries. + * nv_alloc_rx: fill rx ring entries. * Return 1 if the allocations for the skbs failed and the * rx engine is without Available descriptors */ -static int alloc_rx(struct net_device *dev) +static int nv_alloc_rx(struct net_device *dev) { struct fe_priv *np = get_nvpriv(dev); unsigned int refill_rx = np->refill_rx; @@ -633,7 +672,7 @@ np->rx_ring[nr].Length = cpu_to_le16(RX_NIC_BUFSIZE); wmb(); np->rx_ring[nr].Flags = cpu_to_le16(NV_RX_AVAIL); - dprintk(KERN_DEBUG "%s: alloc_rx: Packet %d marked as Available\n", + dprintk(KERN_DEBUG "%s: nv_alloc_rx: Packet %d marked as Available\n", dev->name, refill_rx); refill_rx++; } @@ -643,13 +682,13 @@ return 0; } -static void do_rx_refill(unsigned long data) +static void nv_do_rx_refill(unsigned long data) { struct net_device *dev = (struct net_device *) data; struct fe_priv *np = get_nvpriv(dev); disable_irq(dev->irq); - if (alloc_rx(dev)) { + if (nv_alloc_rx(dev)) { spin_lock(&np->lock); if (!np->in_shutdown) mod_timer(&np->oom_kick, jiffies + OOM_REFILL); @@ -658,7 +697,7 @@ enable_irq(dev->irq); } -static int init_ring(struct net_device *dev) +static int nv_init_ring(struct net_device *dev) { struct fe_priv *np = get_nvpriv(dev); int i; @@ -673,10 +712,10 @@ for (i = 0; i < RX_RING; i++) { np->rx_ring[i].Flags = 0; } - return alloc_rx(dev); + return nv_alloc_rx(dev); } -static void drain_tx(struct net_device *dev) +static void nv_drain_tx(struct net_device *dev) { struct fe_priv *np = get_nvpriv(dev); int i; @@ -693,7 +732,7 @@ } } -static void drain_rx(struct net_device *dev) +static void nv_drain_rx(struct net_device *dev) { struct fe_priv *np = get_nvpriv(dev); int i; @@ -712,8 +751,8 @@ static void drain_ring(struct net_device *dev) { - drain_tx(dev); - drain_rx(dev); + nv_drain_tx(dev); + nv_drain_rx(dev); } /* @@ -759,11 +798,11 @@ } /* - * tx_done: check for completed packets, release the skbs. + * nv_tx_done: check for completed packets, release the skbs. * * Caller must own np->lock. */ -static void tx_done(struct net_device *dev) +static void nv_tx_done(struct net_device *dev) { struct fe_priv *np = get_nvpriv(dev); @@ -773,7 +812,7 @@ prd = &np->tx_ring[i]; - dprintk(KERN_DEBUG "%s: tx_done: looking at packet %d, Flags 0x%x.\n", + dprintk(KERN_DEBUG "%s: nv_tx_done: looking at packet %d, Flags 0x%x.\n", dev->name, np->nic_tx, prd->Flags); if (prd->Flags & cpu_to_le16(NV_TX_VALID)) break; @@ -814,26 +853,26 @@ spin_lock_irq(&np->lock); /* 1) stop tx engine */ - stop_tx(dev); + nv_stop_tx(dev); /* 2) check that the packets were not sent already: */ - tx_done(dev); + nv_tx_done(dev); /* 3) if there are dead entries: clear everything */ if (np->next_tx != np->nic_tx) { printk(KERN_DEBUG "%s: tx_timeout: dead entries!\n", dev->name); - drain_tx(dev); + nv_drain_tx(dev); np->next_tx = np->nic_tx = 0; writel((u32) (np->ring_addr + RX_RING*sizeof(struct ring_desc)), base + NvRegTxRingPhysAddr); netif_wake_queue(dev); } /* 4) restart tx engine */ - start_tx(dev); + nv_start_tx(dev); spin_unlock_irq(&np->lock); } -static void rx_process(struct net_device *dev) +static void nv_rx_process(struct net_device *dev) { struct fe_priv *np = get_nvpriv(dev); @@ -847,7 +886,7 @@ i = np->cur_rx % RX_RING; prd = &np->rx_ring[i]; - dprintk(KERN_DEBUG "%s: rx_process: looking at packet %d, Flags 0x%x.\n", + dprintk(KERN_DEBUG "%s: nv_rx_process: looking at packet %d, Flags 0x%x.\n", dev->name, np->cur_rx, prd->Flags); if (prd->Flags & cpu_to_le16(NV_RX_AVAIL)) @@ -915,7 +954,7 @@ skb_put(skb, len); skb->protocol = eth_type_trans(skb, dev); - dprintk(KERN_DEBUG "%s: rx_process: packet %d with %d bytes, proto %d accepted.\n", + dprintk(KERN_DEBUG "%s: nv_rx_process: packet %d with %d bytes, proto %d accepted.\n", dev->name, np->cur_rx, len, skb->protocol); netif_rx(skb); dev->last_rx = jiffies; @@ -990,24 +1029,24 @@ addr[0] |= NVREG_MCASTADDRA_FORCE; pff |= NVREG_PFF_ALWAYS; spin_lock_irq(&np->lock); - stop_rx(dev); + nv_stop_rx(dev); writel(addr[0], base + NvRegMulticastAddrA); writel(addr[1], base + NvRegMulticastAddrB); writel(mask[0], base + NvRegMulticastMaskA); writel(mask[1], base + NvRegMulticastMaskB); writel(pff, base + NvRegPacketFilterFlags); - start_rx(dev); + nv_start_rx(dev); spin_unlock_irq(&np->lock); } -static int update_linkspeed(struct net_device *dev) +static int nv_update_linkspeed(struct net_device *dev) { struct fe_priv *np = get_nvpriv(dev); int adv, lpa, newls, newdup; adv = mii_rw(dev, np->phyaddr, MII_ADVERTISE, MII_READ); lpa = mii_rw(dev, np->phyaddr, MII_LPA, MII_READ); - dprintk(KERN_DEBUG "%s: update_linkspeed: PHY advertises 0x%04x, lpa 0x%04x.\n", + dprintk(KERN_DEBUG "%s: nv_update_linkspeed: PHY advertises 0x%04x, lpa 0x%04x.\n", dev->name, adv, lpa); /* FIXME: handle parallel detection properly, handle gigabit ethernet */ @@ -1037,7 +1076,7 @@ return 0; } -static void link_irq(struct net_device *dev) +static void nv_link_irq(struct net_device *dev) { struct fe_priv *np = get_nvpriv(dev); u8 *base = get_hwbase(dev); @@ -1050,29 +1089,29 @@ miival = mii_rw(dev, np->phyaddr, MII_BMSR, MII_READ); if (miival & BMSR_ANEGCOMPLETE) { - update_linkspeed(dev); + nv_update_linkspeed(dev); if (netif_carrier_ok(dev)) { - stop_rx(dev); + nv_stop_rx(dev); } else { netif_carrier_on(dev); printk(KERN_INFO "%s: link up.\n", dev->name); } writel(NVREG_MISC1_FORCE | ( np->duplex ? 0 : NVREG_MISC1_HD), base + NvRegMisc1); - start_rx(dev); + nv_start_rx(dev); } else { if (netif_carrier_ok(dev)) { netif_carrier_off(dev); printk(KERN_INFO "%s: link down.\n", dev->name); - stop_rx(dev); + nv_stop_rx(dev); } writel(np->linkspeed, base + NvRegLinkSpeed); pci_push(base); } } -static irqreturn_t nic_irq(int foo, void *data, struct pt_regs *regs) +static irqreturn_t nv_nic_irq(int foo, void *data, struct pt_regs *regs) { struct net_device *dev = (struct net_device *) data; struct fe_priv *np = get_nvpriv(dev); @@ -1080,7 +1119,7 @@ u32 events; int i; - dprintk(KERN_DEBUG "%s: nic_irq\n", dev->name); + dprintk(KERN_DEBUG "%s: nv_nic_irq\n", dev->name); for (i=0; ; i++) { events = readl(base + NvRegIrqStatus) & NVREG_IRQSTAT_MASK; @@ -1092,13 +1131,13 @@ if (events & (NVREG_IRQ_TX1|NVREG_IRQ_TX2|NVREG_IRQ_TX_ERR)) { spin_lock(&np->lock); - tx_done(dev); + nv_tx_done(dev); spin_unlock(&np->lock); } if (events & (NVREG_IRQ_RX|NVREG_IRQ_RX_NOBUF)) { - rx_process(dev); - if (alloc_rx(dev)) { + nv_rx_process(dev); + if (nv_alloc_rx(dev)) { spin_lock(&np->lock); if (!np->in_shutdown) mod_timer(&np->oom_kick, jiffies + OOM_REFILL); @@ -1108,7 +1147,7 @@ if (events & NVREG_IRQ_LINK) { spin_lock(&np->lock); - link_irq(dev); + nv_link_irq(dev); spin_unlock(&np->lock); } if (events & (NVREG_IRQ_TX_ERR)) { @@ -1127,31 +1166,32 @@ if (!np->in_shutdown) mod_timer(&np->nic_poll, jiffies + POLL_WAIT); - printk(KERN_DEBUG "%s: too many iterations (%d) in nic_irq.\n", dev->name, i); + printk(KERN_DEBUG "%s: too many iterations (%d) in nv_nic_irq.\n", dev->name, i); spin_unlock(&np->lock); break; } } - dprintk(KERN_DEBUG "%s: nic_irq completed\n", dev->name); + dprintk(KERN_DEBUG "%s: nv_nic_irq completed\n", dev->name); return IRQ_RETVAL(i); } -static void do_nic_poll(unsigned long data) +static void nv_do_nic_poll(unsigned long data) { struct net_device *dev = (struct net_device *) data; struct fe_priv *np = get_nvpriv(dev); u8 *base = get_hwbase(dev); disable_irq(dev->irq); + /* FIXME: Do we need synchronize_irq(dev->irq) here? */ /* * reenable interrupts on the nic, we have to do this before calling - * nic_irq because that may decide to do otherwise + * nv_nic_irq because that may decide to do otherwise */ writel(np->irqmask, base + NvRegIrqMask); pci_push(base); - nic_irq((int) 0, (void *) data, (struct pt_regs *) NULL); + nv_nic_irq((int) 0, (void *) data, (struct pt_regs *) NULL); enable_irq(dev->irq); } @@ -1173,12 +1213,12 @@ writel(0, base + NvRegAdapterControl); writel(0, base + NvRegLinkSpeed); writel(0, base + NvRegUnknownTransmitterReg); - txrx_reset(dev); + nv_txrx_reset(dev); writel(0, base + NvRegUnknownSetupReg6); /* 2) initialize descriptor rings */ np->in_shutdown = 0; - oom = init_ring(dev); + oom = nv_init_ring(dev); /* 3) set mac address */ { @@ -1224,7 +1264,7 @@ np->phyaddr = i; spin_lock_irq(&np->lock); - update_linkspeed(dev); + nv_update_linkspeed(dev); spin_unlock_irq(&np->lock); break; @@ -1279,7 +1319,7 @@ writel(NVREG_IRQSTAT_MASK, base + NvRegIrqStatus); pci_push(base); - ret = request_irq(dev->irq, &nic_irq, SA_SHIRQ, dev->name, dev); + ret = request_irq(dev->irq, &nv_nic_irq, SA_SHIRQ, dev->name, dev); if (ret) goto out_drain; @@ -1291,8 +1331,8 @@ writel(0, base + NvRegMulticastMaskA); writel(0, base + NvRegMulticastMaskB); writel(NVREG_PFF_ALWAYS|NVREG_PFF_MYADDR, base + NvRegPacketFilterFlags); - start_rx(dev); - start_tx(dev); + nv_start_rx(dev); + nv_start_tx(dev); netif_start_queue(dev); if (oom) mod_timer(&np->oom_kick, jiffies + OOM_REFILL); @@ -1326,8 +1366,8 @@ netif_stop_queue(dev); spin_lock_irq(&np->lock); - stop_tx(dev); - stop_rx(dev); + nv_stop_tx(dev); + nv_stop_rx(dev); base = get_hwbase(dev); /* disable interrupts on the nic or we will lock up */ @@ -1341,6 +1381,9 @@ drain_ring(dev); + if (np->wolenabled) + nv_start_rx(dev); + /* FIXME: power down nic */ return 0; @@ -1367,10 +1410,10 @@ init_timer(&np->oom_kick); np->oom_kick.data = (unsigned long) dev; - np->oom_kick.function = &do_rx_refill; /* timer handler */ + np->oom_kick.function = &nv_do_rx_refill; /* timer handler */ init_timer(&np->nic_poll); np->nic_poll.data = (unsigned long) dev; - np->nic_poll.function = &do_nic_poll; /* timer handler */ + np->nic_poll.function = &nv_do_nic_poll; /* timer handler */ err = pci_enable_device(pci_dev); if (err) { @@ -1458,6 +1501,10 @@ dprintk(KERN_DEBUG "%s: MAC Address %02x:%02x:%02x:%02x:%02x:%02x\n", pci_name(pci_dev), dev->dev_addr[0], dev->dev_addr[1], dev->dev_addr[2], dev->dev_addr[3], dev->dev_addr[4], dev->dev_addr[5]); + + /* disable WOL */ + writel(0, base + NvRegWakeUpFlags); + np->wolenabled = 0; np->tx_flags = cpu_to_le16(NV_TX_LASTPACKET|NV_TX_LASTPACKET1|NV_TX_VALID); if (id->driver_data & DEV_NEED_LASTPACKET1) diff -Nru a/drivers/net/gt96100eth.c b/drivers/net/gt96100eth.c --- a/drivers/net/gt96100eth.c Sun Mar 14 14:20:08 2004 +++ b/drivers/net/gt96100eth.c Sun Mar 14 14:20:08 2004 @@ -277,7 +277,7 @@ static void dump_tx_desc(int dbg_lvl, struct net_device *dev, int i) { - struct gt96100_private *gp = (struct gt96100_private *)dev->priv; + struct gt96100_private *gp = netdev_priv(dev); gt96100_td_t *td = &gp->tx_ring[i]; dbg(dbg_lvl, "Tx descriptor at 0x%08lx:\n", virt_to_phys(td)); @@ -292,7 +292,7 @@ static void dump_rx_desc(int dbg_lvl, struct net_device *dev, int i) { - struct gt96100_private *gp = (struct gt96100_private *)dev->priv; + struct gt96100_private *gp = netdev_priv(dev); gt96100_rd_t *rd = &gp->rx_ring[i]; dbg(dbg_lvl, "Rx descriptor at 0x%08lx:\n", virt_to_phys(rd)); @@ -332,7 +332,7 @@ static void dump_tx_ring(struct net_device *dev) { - struct gt96100_private *gp = (struct gt96100_private *)dev->priv; + struct gt96100_private *gp = netdev_priv(dev); int i; dbg(0, "%s: txno/txni/cnt=%d/%d/%d\n", __FUNCTION__, @@ -345,7 +345,7 @@ static void dump_rx_ring(struct net_device *dev) { - struct gt96100_private *gp = (struct gt96100_private *)dev->priv; + struct gt96100_private *gp = netdev_priv(dev); int i; dbg(0, "%s: rxno=%d\n", __FUNCTION__, gp->rx_next_out); @@ -359,7 +359,7 @@ dump_MII(int dbg_lvl, struct net_device *dev) { int i, val; - struct gt96100_private *gp = (struct gt96100_private *)dev->priv; + struct gt96100_private *gp = netdev_priv(dev); if (dbg_lvl <= GT96100_DEBUG) { for (i=0; i<7; i++) { @@ -419,7 +419,7 @@ static int gt96100_add_hash_entry(struct net_device *dev, unsigned char* addr) { - struct gt96100_private *gp = (struct gt96100_private *)dev->priv; + struct gt96100_private *gp = netdev_priv(dev); //u16 hashResult, stmp; //unsigned char ctmp, hash_ea[6]; u32 tblEntry1, tblEntry0, *tblEntryAddr; @@ -544,7 +544,7 @@ static void abort(struct net_device *dev, u32 abort_bits) { - struct gt96100_private *gp = (struct gt96100_private *)dev->priv; + struct gt96100_private *gp = netdev_priv(dev); int timedout = 100; // wait up to 100 msec for hard stop to complete dbg(3, "%s\n", __FUNCTION__); @@ -582,7 +582,7 @@ static void hard_stop(struct net_device *dev) { - struct gt96100_private *gp = (struct gt96100_private *)dev->priv; + struct gt96100_private *gp = netdev_priv(dev); dbg(3, "%s\n", __FUNCTION__); @@ -598,7 +598,7 @@ static void enable_ether_irq(struct net_device *dev) { - struct gt96100_private *gp = (struct gt96100_private *)dev->priv; + struct gt96100_private *gp = netdev_priv(dev); u32 intMask; /* * route ethernet interrupt to GT_SERINT0 for port 0, @@ -631,7 +631,7 @@ static void disable_ether_irq(struct net_device *dev) { - struct gt96100_private *gp = (struct gt96100_private *)dev->priv; + struct gt96100_private *gp = netdev_priv(dev); u32 intMask; int intr_mask_reg = (gp->port_num == 0) ? GT96100_SERINT0_MASK : GT96100_INT0_HIGH_MASK; @@ -745,7 +745,7 @@ goto out1; } - gp = dev->priv; + gp = netdev_priv(dev); memset(gp, 0, sizeof(*gp)); // clear it @@ -839,7 +839,7 @@ static void reset_tx(struct net_device *dev) { - struct gt96100_private *gp = (struct gt96100_private *)dev->priv; + struct gt96100_private *gp = netdev_priv(dev); int i; abort(dev, sdcmrAT); @@ -877,7 +877,7 @@ static void reset_rx(struct net_device *dev) { - struct gt96100_private *gp = (struct gt96100_private *)dev->priv; + struct gt96100_private *gp = netdev_priv(dev); int i; abort(dev, sdcmrAR); @@ -934,7 +934,7 @@ static int gt96100_init(struct net_device *dev) { - struct gt96100_private *gp = (struct gt96100_private *)dev->priv; + struct gt96100_private *gp = netdev_priv(dev); u32 tmp; u16 mii_reg; @@ -1115,7 +1115,7 @@ static int gt96100_tx(struct sk_buff *skb, struct net_device *dev) { - struct gt96100_private *gp = (struct gt96100_private *)dev->priv; + struct gt96100_private *gp = netdev_priv(dev); unsigned long flags; int nextIn; @@ -1187,7 +1187,7 @@ static int gt96100_rx(struct net_device *dev, u32 status) { - struct gt96100_private *gp = (struct gt96100_private *)dev->priv; + struct gt96100_private *gp = netdev_priv(dev); struct sk_buff *skb; int pkt_len, nextOut, cdp; gt96100_rd_t *rd; @@ -1296,7 +1296,7 @@ static void gt96100_tx_complete(struct net_device *dev, u32 status) { - struct gt96100_private *gp = (struct gt96100_private *)dev->priv; + struct gt96100_private *gp = netdev_priv(dev); int nextOut, cdp; gt96100_td_t *td; u32 cmdstat; @@ -1385,7 +1385,7 @@ gt96100_interrupt(int irq, void *dev_id, struct pt_regs *regs) { struct net_device *dev = (struct net_device *)dev_id; - struct gt96100_private *gp = (struct gt96100_private *)dev->priv; + struct gt96100_private *gp = netdev_priv(dev); u32 status; int handled = 0; @@ -1486,7 +1486,7 @@ static void gt96100_tx_timeout(struct net_device *dev) { - struct gt96100_private *gp = (struct gt96100_private *)dev->priv; + struct gt96100_private *gp = netdev_priv(dev); unsigned long flags; spin_lock_irqsave(&gp->lock, flags); @@ -1511,7 +1511,7 @@ static void gt96100_set_rx_mode(struct net_device *dev) { - struct gt96100_private *gp = (struct gt96100_private *)dev->priv; + struct gt96100_private *gp = netdev_priv(dev); unsigned long flags; //struct dev_mc_list *mcptr; @@ -1555,7 +1555,7 @@ static struct net_device_stats * gt96100_get_stats(struct net_device *dev) { - struct gt96100_private *gp = (struct gt96100_private *)dev->priv; + struct gt96100_private *gp = netdev_priv(dev); unsigned long flags; dbg(3, "%s: dev=%p\n", __FUNCTION__, dev); diff -Nru a/drivers/net/hamachi.c b/drivers/net/hamachi.c --- a/drivers/net/hamachi.c Sun Mar 14 14:20:08 2004 +++ b/drivers/net/hamachi.c Sun Mar 14 14:20:08 2004 @@ -1498,8 +1498,10 @@ if (desc_status & DescOwn) break; - pci_dma_sync_single(hmp->pci_dev, desc->addr, hmp->rx_buf_sz, - PCI_DMA_FROMDEVICE); + pci_dma_sync_single_for_cpu(hmp->pci_dev, + desc->addr, + hmp->rx_buf_sz, + PCI_DMA_FROMDEVICE); buf_addr = desc_to_virt(desc->addr); frame_status = le32_to_cpu(get_unaligned((s32*)&(buf_addr[data_size - 12]))); if (hamachi_debug > 4) @@ -1563,6 +1565,10 @@ #endif skb->dev = dev; skb_reserve(skb, 2); /* 16 byte align the IP header */ + pci_dma_sync_single_for_cpu(hmp->pci_dev, + hmp->rx_ring[entry].addr, + hmp->rx_buf_sz, + PCI_DMA_FROMDEVICE); /* Call copy + cksum if available. */ #if 1 || USE_IP_COPYSUM eth_copy_and_sum(skb, @@ -1572,10 +1578,14 @@ memcpy(skb_put(skb, pkt_len), hmp->rx_ring_dma + entry*sizeof(*desc), pkt_len); #endif + pci_dma_sync_single_for_device(hmp->pci_dev, + hmp->rx_ring[entry].addr, + hmp->rx_buf_sz, + PCI_DMA_FROMDEVICE); } else { pci_unmap_single(hmp->pci_dev, - hmp->rx_ring[entry].addr, - hmp->rx_buf_sz, PCI_DMA_FROMDEVICE); + hmp->rx_ring[entry].addr, + hmp->rx_buf_sz, PCI_DMA_FROMDEVICE); skb_put(skb = hmp->rx_skbuff[entry], pkt_len); hmp->rx_skbuff[entry] = NULL; } diff -Nru a/drivers/net/hamradio/baycom_epp.c b/drivers/net/hamradio/baycom_epp.c --- a/drivers/net/hamradio/baycom_epp.c Sun Mar 14 14:20:08 2004 +++ b/drivers/net/hamradio/baycom_epp.c Sun Mar 14 14:20:08 2004 @@ -646,7 +646,7 @@ static void do_rxpacket(struct net_device *dev) { - struct baycom_state *bc = (struct baycom_state *)dev->priv; + struct baycom_state *bc = netdev_priv(dev); struct sk_buff *skb; unsigned char *cp; unsigned pktlen; @@ -705,7 +705,7 @@ static int receive(struct net_device *dev, int cnt) { - struct baycom_state *bc = (struct baycom_state *)dev->priv; + struct baycom_state *bc = netdev_priv(dev); struct parport *pp = bc->pdev->port; unsigned int bitbuf, notbitstream, bitstream, numbits, state; unsigned char tmp[128]; @@ -790,7 +790,7 @@ int cnt, cnt2; baycom_paranoia_check_void(dev, "epp_bh"); - bc = (struct baycom_state *)dev->priv; + bc = netdev_priv(dev); if (!bc->work_running) return; baycom_int_freq(bc); @@ -908,7 +908,7 @@ struct baycom_state *bc; baycom_paranoia_check(dev, "baycom_send_packet", 0); - bc = (struct baycom_state *)dev->priv; + bc = netdev_priv(dev); if (skb->data[0] != 0) { do_kiss_params(bc, skb->data, skb->len); dev_kfree_skb(skb); @@ -944,7 +944,7 @@ struct baycom_state *bc; baycom_paranoia_check(dev, "baycom_get_stats", NULL); - bc = (struct baycom_state *)dev->priv; + bc = netdev_priv(dev); /* * Get the current statistics. This may be called with the * card open or closed. @@ -960,7 +960,7 @@ struct baycom_state *bc; baycom_paranoia_check_void(dev, "epp_wakeup"); - bc = (struct baycom_state *)dev->priv; + bc = netdev_priv(dev); printk(KERN_DEBUG "baycom_epp: %s: why am I being woken up?\n", dev->name); if (!parport_claim(bc->pdev)) printk(KERN_DEBUG "baycom_epp: %s: I'm broken.\n", dev->name); @@ -987,7 +987,7 @@ unsigned long tstart; baycom_paranoia_check(dev, "epp_open", -ENXIO); - bc = (struct baycom_state *)dev->priv; + bc = netdev_priv(dev); pp = parport_find_base(dev->base_addr); if (!pp) { printk(KERN_ERR "%s: parport at 0x%lx unknown\n", bc_drvname, dev->base_addr); @@ -1102,7 +1102,7 @@ unsigned char tmp[1]; baycom_paranoia_check(dev, "epp_close", -EINVAL); - bc = (struct baycom_state *)dev->priv; + bc = netdev_priv(dev); pp = bc->pdev->port; bc->work_running = 0; flush_scheduled_work(); @@ -1163,7 +1163,7 @@ struct hdlcdrv_ioctl hi; baycom_paranoia_check(dev, "baycom_ioctl", -EINVAL); - bc = (struct baycom_state *)dev->priv; + bc = netdev_priv(dev); if (cmd != SIOCDEVPRIVATE) return -ENOIOCTLCMD; if (get_user(cmd, (int *)ifr->ifr_data)) @@ -1290,7 +1290,7 @@ /* * not a real probe! only initialize data structures */ - bc = (struct baycom_state *)dev->priv; + bc = netdev_priv(dev); /* * initialize the baycom_state struct */ @@ -1351,7 +1351,7 @@ static void __init baycom_epp_dev_setup(struct net_device *dev) { - struct baycom_state *bc = dev->priv; + struct baycom_state *bc = netdev_priv(dev); /* * initialize part of the baycom_state struct @@ -1415,7 +1415,7 @@ struct net_device *dev = baycom_device[i]; if (dev) { - struct baycom_state *bc = dev->priv; + struct baycom_state *bc = netdev_priv(dev); if (bc->magic == BAYCOM_MAGIC) { unregister_netdev(dev); free_netdev(dev); diff -Nru a/drivers/net/hamradio/baycom_par.c b/drivers/net/hamradio/baycom_par.c --- a/drivers/net/hamradio/baycom_par.c Sun Mar 14 14:20:08 2004 +++ b/drivers/net/hamradio/baycom_par.c Sun Mar 14 14:20:08 2004 @@ -272,7 +272,7 @@ static void par96_interrupt(int irq, void *dev_id, struct pt_regs *regs) { struct net_device *dev = (struct net_device *)dev_id; - struct baycom_state *bc = (struct baycom_state *)dev->priv; + struct baycom_state *bc = netdev_priv(dev); if (!dev || !bc || bc->hdrv.magic != HDLCDRV_MAGIC) return; @@ -302,7 +302,7 @@ static void par96_wakeup(void *handle) { struct net_device *dev = (struct net_device *)handle; - struct baycom_state *bc = (struct baycom_state *)dev->priv; + struct baycom_state *bc = netdev_priv(dev); printk(KERN_DEBUG "baycom_par: %s: why am I being woken up?\n", dev->name); if (!parport_claim(bc->pdev)) @@ -313,7 +313,7 @@ static int par96_open(struct net_device *dev) { - struct baycom_state *bc = (struct baycom_state *)dev->priv; + struct baycom_state *bc = netdev_priv(dev); struct parport *pp; if (!dev || !bc) @@ -362,7 +362,7 @@ static int par96_close(struct net_device *dev) { - struct baycom_state *bc = (struct baycom_state *)dev->priv; + struct baycom_state *bc = netdev_priv(dev); struct parport *pp; if (!dev || !bc) @@ -424,7 +424,7 @@ printk(KERN_ERR "bc_ioctl: invalid device struct\n"); return -EINVAL; } - bc = (struct baycom_state *)dev->priv; + bc = netdev_priv(dev); if (cmd != SIOCDEVPRIVATE) return -ENOIOCTLCMD; @@ -524,7 +524,7 @@ if (IS_ERR(dev)) break; - bc = (struct baycom_state *)dev->priv; + bc = netdev_priv(dev); if (set_hw && baycom_setmode(bc, mode[i])) set_hw = 0; found++; diff -Nru a/drivers/net/hamradio/baycom_ser_fdx.c b/drivers/net/hamradio/baycom_ser_fdx.c --- a/drivers/net/hamradio/baycom_ser_fdx.c Sun Mar 14 14:20:07 2004 +++ b/drivers/net/hamradio/baycom_ser_fdx.c Sun Mar 14 14:20:07 2004 @@ -281,7 +281,7 @@ static irqreturn_t ser12_interrupt(int irq, void *dev_id, struct pt_regs *regs) { struct net_device *dev = (struct net_device *)dev_id; - struct baycom_state *bc = (struct baycom_state *)dev->priv; + struct baycom_state *bc = netdev_priv(dev); struct timeval tv; unsigned char iir, msr; unsigned int txcount = 0; @@ -407,7 +407,7 @@ static int ser12_open(struct net_device *dev) { - struct baycom_state *bc = (struct baycom_state *)dev->priv; + struct baycom_state *bc = netdev_priv(dev); enum uart u; if (!dev || !bc) @@ -466,7 +466,7 @@ static int ser12_close(struct net_device *dev) { - struct baycom_state *bc = (struct baycom_state *)dev->priv; + struct baycom_state *bc = netdev_priv(dev); if (!dev || !bc) return -EINVAL; @@ -536,7 +536,7 @@ printk(KERN_ERR "bc_ioctl: invalid device struct\n"); return -EINVAL; } - bc = (struct baycom_state *)dev->priv; + bc = netdev_priv(dev); if (cmd != SIOCDEVPRIVATE) return -ENOIOCTLCMD; @@ -644,7 +644,7 @@ if (IS_ERR(dev)) break; - bc = (struct baycom_state *)dev->priv; + bc = netdev_priv(dev); if (set_hw && baycom_setmode(bc, mode[i])) set_hw = 0; bc->baud = baud[i]; diff -Nru a/drivers/net/hamradio/baycom_ser_hdx.c b/drivers/net/hamradio/baycom_ser_hdx.c --- a/drivers/net/hamradio/baycom_ser_hdx.c Sun Mar 14 14:20:06 2004 +++ b/drivers/net/hamradio/baycom_ser_hdx.c Sun Mar 14 14:20:06 2004 @@ -375,7 +375,7 @@ static irqreturn_t ser12_interrupt(int irq, void *dev_id, struct pt_regs *regs) { struct net_device *dev = (struct net_device *)dev_id; - struct baycom_state *bc = (struct baycom_state *)dev->priv; + struct baycom_state *bc = netdev_priv(dev); unsigned char iir; if (!dev || !bc || bc->hdrv.magic != HDLCDRV_MAGIC) @@ -468,7 +468,7 @@ static int ser12_open(struct net_device *dev) { - struct baycom_state *bc = (struct baycom_state *)dev->priv; + struct baycom_state *bc = netdev_priv(dev); enum uart u; if (!dev || !bc) @@ -511,7 +511,7 @@ static int ser12_close(struct net_device *dev) { - struct baycom_state *bc = (struct baycom_state *)dev->priv; + struct baycom_state *bc = netdev_priv(dev); if (!dev || !bc) return -EINVAL; @@ -576,7 +576,7 @@ printk(KERN_ERR "bc_ioctl: invalid device struct\n"); return -EINVAL; } - bc = (struct baycom_state *)dev->priv; + bc = netdev_priv(dev); if (cmd != SIOCDEVPRIVATE) return -ENOIOCTLCMD; @@ -681,7 +681,7 @@ if (IS_ERR(dev)) break; - bc = (struct baycom_state *)dev->priv; + bc = netdev_priv(dev); if (set_hw && baycom_setmode(bc, mode[i])) set_hw = 0; found++; diff -Nru a/drivers/net/hp-plus.c b/drivers/net/hp-plus.c --- a/drivers/net/hp-plus.c Sun Mar 14 14:20:06 2004 +++ b/drivers/net/hp-plus.c Sun Mar 14 14:20:06 2004 @@ -236,6 +236,9 @@ dev->open = &hpp_open; dev->stop = &hpp_close; +#ifdef CONFIG_NET_POLL_CONTROLLER + dev->poll_controller = ei_poll; +#endif ei_status.name = name; ei_status.word16 = 0; /* Agggghhhhh! Debug time: 2 days! */ diff -Nru a/drivers/net/hp.c b/drivers/net/hp.c --- a/drivers/net/hp.c Sun Mar 14 14:20:06 2004 +++ b/drivers/net/hp.c Sun Mar 14 14:20:06 2004 @@ -207,6 +207,9 @@ dev->base_addr = ioaddr + NIC_OFFSET; dev->open = &hp_open; dev->stop = &hp_close; +#ifdef CONFIG_NET_POLL_CONTROLLER + dev->poll_controller = ei_poll; +#endif ei_status.name = name; ei_status.word16 = wordmode; diff -Nru a/drivers/net/hplance.c b/drivers/net/hplance.c --- a/drivers/net/hplance.c Sun Mar 14 14:20:07 2004 +++ b/drivers/net/hplance.c Sun Mar 14 14:20:07 2004 @@ -63,7 +63,7 @@ static void cleanup_card(struct net_device *dev) { - struct hplance_private *lp = dev->priv; + struct hplance_private *lp = netdev_priv(dev); dio_unconfig_board(lp->scode); } @@ -97,7 +97,7 @@ dio_config_board(scode); hplance_init(dev, scode); if (!register_netdev(dev)) { - struct hplance_private *lp = dev->priv; + struct hplance_private *lp = netdev_priv(dev); lp->next_module = root_hplance_dev; root_hplance_dev = lp; return dev; @@ -141,7 +141,7 @@ printk("%c%2.2x", i == 0 ? ' ' : ':', dev->dev_addr[i]); } - lp = (struct hplance_private *)dev->priv; + lp = netdev_priv(dev); lp->lance.name = (char*)name; /* discards const, shut up gcc */ lp->lance.ll = (struct lance_regs *)(va + HPLANCE_REGOFF); lp->lance.init_block = (struct lance_init_block *)(va + HPLANCE_MEMOFF); /* CPU addr */ @@ -195,7 +195,7 @@ static int hplance_open(struct net_device *dev) { int status; - struct hplance_private *lp = (struct hplance_private *)dev->priv; + struct hplance_private *lp = netdev_priv(dev); struct hplance_reg *hpregs = (struct hplance_reg *)lp->base; status = lance_open(dev); /* call generic lance open code */ @@ -209,7 +209,7 @@ static int hplance_close(struct net_device *dev) { - struct hplance_private *lp = (struct hplance_private *)dev->priv; + struct hplance_private *lp = netdev_priv(dev); struct hplance_reg *hpregs = (struct hplance_reg *)lp->base; out_8(&(hpregs->status), 8); /* disable interrupts at boardlevel */ lance_close(dev); diff -Nru a/drivers/net/hydra.c b/drivers/net/hydra.c --- a/drivers/net/hydra.c Sun Mar 14 14:20:07 2004 +++ b/drivers/net/hydra.c Sun Mar 14 14:20:07 2004 @@ -142,6 +142,10 @@ ei_status.reg_offset = hydra_offsets; dev->open = &hydra_open; dev->stop = &hydra_close; +#ifdef CONFIG_NET_POLL_CONTROLLER + dev->poll_controller = ei_poll; +#endif + NS8390_init(dev, 0); err = register_netdev(dev); diff -Nru a/drivers/net/irda/vlsi_ir.c b/drivers/net/irda/vlsi_ir.c --- a/drivers/net/irda/vlsi_ir.c Sun Mar 14 14:20:06 2004 +++ b/drivers/net/irda/vlsi_ir.c Sun Mar 14 14:20:06 2004 @@ -173,7 +173,7 @@ 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); + pdev->irq, (unsigned)pci_resource_start(pdev, 0), (unsigned long long)pdev->dma_mask); out += sprintf(out, "hw registers: "); for (i = 0; i < 0x20; i++) out += sprintf(out, "%02x", (unsigned)inb((iobase+i))); @@ -566,7 +566,6 @@ return NULL; } rd_set_addr_status(rd, busaddr, 0); - pci_dma_sync_single(pdev, busaddr, len, dir); /* initially, the dma buffer is owned by the CPU */ rd->skb = NULL; } @@ -660,7 +659,7 @@ struct net_device *ndev = (struct net_device *)pci_get_drvdata(r->pdev); vlsi_irda_dev_t *idev = ndev->priv; - pci_dma_sync_single(r->pdev, rd_get_addr(rd), r->len, r->dir); + pci_dma_sync_single_for_cpu(r->pdev, rd_get_addr(rd), r->len, r->dir); /* dma buffer now owned by the CPU */ status = rd_get_status(rd); if (status & RD_RX_ERROR) { @@ -746,7 +745,7 @@ break; /* probably not worth logging? */ } /* give dma buffer back to busmaster */ - pci_dma_prep_single(r->pdev, rd_get_addr(rd), r->len, r->dir); + pci_dma_sync_single_for_device(r->pdev, rd_get_addr(rd), r->len, r->dir); rd_activate(rd); } } @@ -816,7 +815,7 @@ ret = -VLSI_RX_DROP; } rd_set_count(rd, 0); - pci_dma_sync_single(r->pdev, rd_get_addr(rd), r->len, r->dir); + pci_dma_sync_single_for_cpu(r->pdev, rd_get_addr(rd), r->len, r->dir); if (rd->skb) { dev_kfree_skb_any(rd->skb); rd->skb = NULL; @@ -854,7 +853,7 @@ int len; int ret; - pci_dma_sync_single(r->pdev, rd_get_addr(rd), r->len, r->dir); + pci_dma_sync_single_for_cpu(r->pdev, rd_get_addr(rd), r->len, r->dir); /* dma buffer now owned by the CPU */ status = rd_get_status(rd); if (status & RD_TX_UNDRN) @@ -1077,8 +1076,8 @@ } } - /* tx buffer already owned by CPU due to pci_dma_sync_single() either - * after initial pci_map_single or after subsequent tx-completion + /* tx buffer already owned by CPU due to pci_dma_sync_single_for_cpu() + * after subsequent tx-completion */ if (idev->mode == IFF_SIR) { @@ -1120,7 +1119,7 @@ * CPU-driven changes visible from the pci bus). */ - pci_dma_prep_single(r->pdev, rd_get_addr(rd), r->len, r->dir); + pci_dma_sync_single_for_device(r->pdev, rd_get_addr(rd), r->len, r->dir); /* Switching to TX mode here races with the controller * which may stop TX at any time when fetching an inactive descriptor @@ -1248,7 +1247,7 @@ if (rd_is_active(rd)) { rd_set_status(rd, 0); rd_set_count(rd, 0); - pci_dma_sync_single(r->pdev, rd_get_addr(rd), r->len, r->dir); + pci_dma_sync_single_for_cpu(r->pdev, rd_get_addr(rd), r->len, r->dir); if (rd->skb) { dev_kfree_skb_any(rd->skb); rd->skb = NULL; diff -Nru a/drivers/net/isa-skeleton.c b/drivers/net/isa-skeleton.c --- a/drivers/net/isa-skeleton.c Sun Mar 14 14:20:08 2004 +++ b/drivers/net/isa-skeleton.c Sun Mar 14 14:20:08 2004 @@ -303,7 +303,7 @@ } #endif /* jumpered DMA */ - np = (struct net_local *)dev->priv; + np = netdev_priv(dev); spin_lock_init(&np->lock); dev->open = net_open; @@ -326,7 +326,7 @@ static void net_tx_timeout(struct net_device *dev) { - struct net_local *np = (struct net_local *)dev->priv; + struct net_local *np = netdev_priv(dev); printk(KERN_WARNING "%s: transmit timed out, %s?\n", dev->name, tx_done(dev) ? "IRQ conflict" : "network cable problem"); @@ -361,7 +361,7 @@ static int net_open(struct net_device *dev) { - struct net_local *np = (struct net_local *)dev->priv; + struct net_local *np = netdev_priv(dev); int ioaddr = dev->base_addr; /* * This is used if the interrupt line can turned off (shared). @@ -399,7 +399,7 @@ */ static int net_send_packet(struct sk_buff *skb, struct net_device *dev) { - struct net_local *np = (struct net_local *)dev->priv; + struct net_local *np = netdev_priv(dev); int ioaddr = dev->base_addr; short length = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN; unsigned char *buf = skb->data; @@ -465,7 +465,7 @@ */ void net_tx(struct net_device *dev) { - struct net_local *np = (struct net_local *)dev->priv; + struct net_local *np = netdev_priv(dev); int entry; /* This protects us from concurrent execution of @@ -508,7 +508,7 @@ ioaddr = dev->base_addr; - np = (struct net_local *)dev->priv; + np = netdev_priv(dev); status = inw(ioaddr + 0); if (status == 0) @@ -539,7 +539,7 @@ static void net_rx(struct net_device *dev) { - struct net_local *lp = (struct net_local *)dev->priv; + struct net_local *lp = netdev_priv(dev); int ioaddr = dev->base_addr; int boguscount = 10; @@ -591,7 +591,7 @@ static int net_close(struct net_device *dev) { - struct net_local *lp = (struct net_local *)dev->priv; + struct net_local *lp = netdev_priv(dev); int ioaddr = dev->base_addr; lp->open_time = 0; @@ -620,7 +620,7 @@ */ static struct net_device_stats *net_get_stats(struct net_device *dev) { - struct net_local *lp = (struct net_local *)dev->priv; + struct net_local *lp = netdev_priv(dev); short ioaddr = dev->base_addr; /* Update the statistics from the device registers. */ diff -Nru a/drivers/net/lasi_82596.c b/drivers/net/lasi_82596.c --- a/drivers/net/lasi_82596.c Sun Mar 14 14:20:06 2004 +++ b/drivers/net/lasi_82596.c Sun Mar 14 14:20:06 2004 @@ -426,7 +426,7 @@ static inline void MPU_PORT(struct net_device *dev, int c, dma_addr_t x) { - struct i596_private *lp = (struct i596_private *) dev->priv; + struct i596_private *lp = netdev_priv(dev); u32 v = (u32) (c) | (u32) (x); u16 a, b; @@ -481,7 +481,7 @@ static void i596_display_data(struct net_device *dev) { - struct i596_private *lp = (struct i596_private *) dev->priv; + struct i596_private *lp = netdev_priv(dev); struct i596_cmd *cmd; struct i596_rfd *rfd; struct i596_rbd *rbd; @@ -541,7 +541,7 @@ static inline void init_rx_bufs(struct net_device *dev) { - struct i596_private *lp = (struct i596_private *)dev->priv; + struct i596_private *lp = netdev_priv(dev); int i; struct i596_rfd *rfd; struct i596_rbd *rbd; @@ -595,7 +595,7 @@ static inline void remove_rx_bufs(struct net_device *dev) { - struct i596_private *lp = (struct i596_private *)dev->priv; + struct i596_private *lp = netdev_priv(dev); struct i596_rbd *rbd; int i; @@ -612,7 +612,7 @@ static void rebuild_rx_bufs(struct net_device *dev) { - struct i596_private *lp = (struct i596_private *) dev->priv; + struct i596_private *lp = netdev_priv(dev); int i; /* Ensure rx frame/buffer descriptors are tidy */ @@ -633,7 +633,7 @@ static int init_i596_mem(struct net_device *dev) { - struct i596_private *lp = (struct i596_private *) dev->priv; + struct i596_private *lp = netdev_priv(dev); unsigned long flags; disable_irq(dev->irq); /* disable IRQs from LAN */ @@ -727,7 +727,7 @@ static inline int i596_rx(struct net_device *dev) { - struct i596_private *lp = (struct i596_private *)dev->priv; + struct i596_private *lp = netdev_priv(dev); struct i596_rfd *rfd; struct i596_rbd *rbd; int frames = 0; @@ -802,9 +802,10 @@ skb->dev = dev; if (!rx_in_place) { /* 16 byte align the data fields */ - dma_sync_single(lp->dev, (dma_addr_t)WSWAPchar(rbd->b_data), PKT_BUF_SZ, DMA_FROM_DEVICE); + dma_sync_single_for_cpu(lp->dev, (dma_addr_t)WSWAPchar(rbd->b_data), PKT_BUF_SZ, DMA_FROM_DEVICE); skb_reserve(skb, 2); memcpy(skb_put(skb,pkt_len), rbd->v_data, pkt_len); + dma_sync_single_for_device(lp->dev, (dma_addr_t)WSWAPchar(rbd->b_data), PKT_BUF_SZ, DMA_FROM_DEVICE); } skb->len = pkt_len; skb->protocol=eth_type_trans(skb,dev); @@ -939,7 +940,7 @@ static void i596_add_cmd(struct net_device *dev, struct i596_cmd *cmd) { - struct i596_private *lp = (struct i596_private *) dev->priv; + struct i596_private *lp = netdev_priv(dev); unsigned long flags; DEB(DEB_ADDCMD,printk("i596_add_cmd cmd_head %p\n", lp->cmd_head)); @@ -987,7 +988,7 @@ device list */ static int i596_test(struct net_device *dev) { - struct i596_private *lp = (struct i596_private *) dev->priv; + struct i596_private *lp = netdev_priv(dev); volatile int *tint; u32 data; @@ -1041,7 +1042,7 @@ static void i596_tx_timeout (struct net_device *dev) { - struct i596_private *lp = (struct i596_private *) dev->priv; + struct i596_private *lp = netdev_priv(dev); /* Transmitter timeout, serious problems. */ DEB(DEB_ERRORS,printk("%s: transmit timed out, status resetting.\n", @@ -1070,7 +1071,7 @@ static int i596_start_xmit(struct sk_buff *skb, struct net_device *dev) { - struct i596_private *lp = (struct i596_private *) dev->priv; + struct i596_private *lp = netdev_priv(dev); struct tx_cmd *tx_cmd; struct i596_tbd *tbd; short length = skb->len; @@ -1219,7 +1220,7 @@ dev->priv = (void *)(dev->mem_start); - lp = (struct i596_private *) dev->priv; + lp = netdev_priv(dev); DEB(DEB_INIT,printk ("%s: lp at 0x%08lx (%d bytes), lp->scb at 0x%08lx\n", dev->name, (unsigned long)lp, sizeof(struct i596_private), (unsigned long)&lp->scb)); @@ -1249,7 +1250,7 @@ return IRQ_NONE; } - lp = (struct i596_private *) dev->priv; + lp = netdev_priv(dev); spin_lock (&lp->lock); @@ -1395,7 +1396,7 @@ static int i596_close(struct net_device *dev) { - struct i596_private *lp = (struct i596_private *) dev->priv; + struct i596_private *lp = netdev_priv(dev); unsigned long flags; netif_stop_queue(dev); @@ -1429,7 +1430,7 @@ static struct net_device_stats * i596_get_stats(struct net_device *dev) { - struct i596_private *lp = (struct i596_private *) dev->priv; + struct i596_private *lp = netdev_priv(dev); return &lp->stats; } @@ -1440,7 +1441,7 @@ static void set_multicast_list(struct net_device *dev) { - struct i596_private *lp = (struct i596_private *) dev->priv; + struct i596_private *lp = netdev_priv(dev); int config = 0, cnt; DEB(DEB_MULTI,printk("%s: set multicast list, %d entries, promisc %s, allmulti %s\n", dev->name, dev->mc_count, dev->flags & IFF_PROMISC ? "ON" : "OFF", dev->flags & IFF_ALLMULTI ? "ON" : "OFF")); @@ -1540,7 +1541,7 @@ retval = register_netdev(netdevice); if (retval) { - struct i596_private *lp = netdevice->priv; + struct i596_private *lp = netdev_priv(netdevice); printk(KERN_WARNING __FILE__ ": register_netdevice ret'd %d\n", retval); dma_free_noncoherent(lp->dev, sizeof(struct i596_private), (void *)netdevice->mem_start, lp->dma_addr); @@ -1594,7 +1595,7 @@ unregister_netdev(netdevice); - lp = (struct i596_private *) netdevice->priv; + lp = netdev_priv(netdevice); dma_free_noncoherent(lp->dev, sizeof(struct i596_private), (void *)netdevice->mem_start, lp->dma_addr); free_netdev(netdevice); diff -Nru a/drivers/net/lne390.c b/drivers/net/lne390.c --- a/drivers/net/lne390.c Sun Mar 14 14:20:08 2004 +++ b/drivers/net/lne390.c Sun Mar 14 14:20:08 2004 @@ -299,6 +299,9 @@ dev->open = &lne390_open; dev->stop = &lne390_close; +#ifdef CONFIG_NET_POLL_CONTROLLER + dev->poll_controller = ei_poll; +#endif NS8390_init(dev, 0); return 0; cleanup: diff -Nru a/drivers/net/loopback.c b/drivers/net/loopback.c --- a/drivers/net/loopback.c Sun Mar 14 14:20:06 2004 +++ b/drivers/net/loopback.c Sun Mar 14 14:20:06 2004 @@ -123,7 +123,7 @@ */ static int loopback_xmit(struct sk_buff *skb, struct net_device *dev) { - struct net_device_stats *stats = (struct net_device_stats *)dev->priv; + struct net_device_stats *stats = netdev_priv(dev); skb_orphan(skb); diff -Nru a/drivers/net/mac8390.c b/drivers/net/mac8390.c --- a/drivers/net/mac8390.c Sun Mar 14 14:20:07 2004 +++ b/drivers/net/mac8390.c Sun Mar 14 14:20:07 2004 @@ -442,6 +442,9 @@ /* Now fill in our stuff */ dev->open = &mac8390_open; dev->stop = &mac8390_close; +#ifdef CONFIG_NET_POLL_CONTROLLER + dev->poll_controller = ei_poll; +#endif /* GAR, ei_status is actually a macro even though it looks global */ ei_status.name = cardname[type]; diff -Nru a/drivers/net/mac89x0.c b/drivers/net/mac89x0.c --- a/drivers/net/mac89x0.c Sun Mar 14 14:20:07 2004 +++ b/drivers/net/mac89x0.c Sun Mar 14 14:20:07 2004 @@ -225,7 +225,7 @@ goto out; /* Initialize the net_device structure. */ - lp = (struct net_local *)dev->priv; + lp = netdev_priv(dev); /* Fill in the 'dev' fields. */ dev->base_addr = ioaddr; @@ -328,7 +328,7 @@ static int net_open(struct net_device *dev) { - struct net_local *lp = (struct net_local *)dev->priv; + struct net_local *lp = netdev_priv(dev); int i; /* Disable the interrupt for now */ @@ -392,7 +392,7 @@ if (test_and_set_bit(0, (void*)&dev->tbusy) != 0) printk("%s: Transmitter access conflict.\n", dev->name); else { - struct net_local *lp = (struct net_local *)dev->priv; + struct net_local *lp = netdev_priv(dev); unsigned long flags; if (net_debug > 3) @@ -446,7 +446,7 @@ dev->interrupt = 1; ioaddr = dev->base_addr; - lp = (struct net_local *)dev->priv; + lp = netdev_priv(dev); /* we MUST read all the events out of the ISQ, otherwise we'll never get interrupted again. As a consequence, we can't have any limit @@ -505,7 +505,7 @@ static void net_rx(struct net_device *dev) { - struct net_local *lp = (struct net_local *)dev->priv; + struct net_local *lp = netdev_priv(dev); struct sk_buff *skb; int status, length; @@ -571,7 +571,7 @@ static struct net_device_stats * net_get_stats(struct net_device *dev) { - struct net_local *lp = (struct net_local *)dev->priv; + struct net_local *lp = netdev_priv(dev); unsigned long flags; local_irq_save(flags); @@ -585,7 +585,7 @@ static void set_multicast_list(struct net_device *dev) { - struct net_local *lp = (struct net_local *)dev->priv; + struct net_local *lp = netdev_priv(dev); if(dev->flags&IFF_PROMISC) { diff -Nru a/drivers/net/myri_sbus.c b/drivers/net/myri_sbus.c --- a/drivers/net/myri_sbus.c Sun Mar 14 14:20:06 2004 +++ b/drivers/net/myri_sbus.c Sun Mar 14 14:20:06 2004 @@ -435,9 +435,9 @@ /* Check for errors. */ DRX(("rxd[%d]: %p len[%d] csum[%08x] ", entry, rxd, len, csum)); - sbus_dma_sync_single(mp->myri_sdev, - sbus_readl(&rxd->myri_scatters[0].addr), - RX_ALLOC_SIZE, SBUS_DMA_FROMDEVICE); + sbus_dma_sync_single_for_cpu(mp->myri_sdev, + sbus_readl(&rxd->myri_scatters[0].addr), + RX_ALLOC_SIZE, SBUS_DMA_FROMDEVICE); if (len < (ETH_HLEN + MYRI_PAD_LEN) || (skb->data[0] != MYRI_PAD_LEN)) { DRX(("ERROR[")); mp->enet_stats.rx_errors++; @@ -454,6 +454,10 @@ drops++; DRX(("DROP ")); mp->enet_stats.rx_dropped++; + sbus_dma_sync_single_for_device(mp->myri_sdev, + sbus_readl(&rxd->myri_scatters[0].addr), + RX_ALLOC_SIZE, + SBUS_DMA_FROMDEVICE); sbus_writel(RX_ALLOC_SIZE, &rxd->myri_scatters[0].len); sbus_writel(index, &rxd->ctx); sbus_writel(1, &rxd->num_sg); @@ -508,6 +512,10 @@ /* Reuse original ring buffer. */ DRX(("reuse ")); + sbus_dma_sync_single_for_device(mp->myri_sdev, + sbus_readl(&rxd->myri_scatters[0].addr), + RX_ALLOC_SIZE, + SBUS_DMA_FROMDEVICE); sbus_writel(RX_ALLOC_SIZE, &rxd->myri_scatters[0].len); sbus_writel(index, &rxd->ctx); sbus_writel(1, &rxd->num_sg); diff -Nru a/drivers/net/natsemi.c b/drivers/net/natsemi.c --- a/drivers/net/natsemi.c Sun Mar 14 14:20:06 2004 +++ b/drivers/net/natsemi.c Sun Mar 14 14:20:06 2004 @@ -1789,7 +1789,7 @@ skb->dev = dev; /* 16 byte align the IP header */ skb_reserve(skb, 2); - pci_dma_sync_single(np->pci_dev, + pci_dma_sync_single_for_cpu(np->pci_dev, np->rx_dma[entry], np->rx_skbuff[entry]->len, PCI_DMA_FROMDEVICE); @@ -1801,6 +1801,10 @@ memcpy(skb_put(skb, pkt_len), np->rx_skbuff[entry]->tail, pkt_len); #endif + pci_dma_sync_single_for_device(np->pci_dev, + np->rx_dma[entry], + np->rx_skbuff[entry]->len, + PCI_DMA_FROMDEVICE); } else { pci_unmap_single(np->pci_dev, np->rx_dma[entry], np->rx_skbuff[entry]->len, diff -Nru a/drivers/net/ne.c b/drivers/net/ne.c --- a/drivers/net/ne.c Sun Mar 14 14:20:07 2004 +++ b/drivers/net/ne.c Sun Mar 14 14:20:07 2004 @@ -498,6 +498,9 @@ ei_status.priv = 0; dev->open = &ne_open; dev->stop = &ne_close; +#ifdef CONFIG_NET_POLL_CONTROLLER + dev->poll_controller = ei_poll; +#endif NS8390_init(dev, 0); return 0; diff -Nru a/drivers/net/ne2.c b/drivers/net/ne2.c --- a/drivers/net/ne2.c Sun Mar 14 14:20:08 2004 +++ b/drivers/net/ne2.c Sun Mar 14 14:20:08 2004 @@ -509,6 +509,9 @@ dev->open = &ne_open; dev->stop = &ne_close; +#ifdef CONFIG_NET_POLL_CONTROLLER + dev->poll_controller = ei_poll; +#endif NS8390_init(dev, 0); return 0; out: diff -Nru a/drivers/net/ne2k-pci.c b/drivers/net/ne2k-pci.c --- a/drivers/net/ne2k-pci.c Sun Mar 14 14:20:06 2004 +++ b/drivers/net/ne2k-pci.c Sun Mar 14 14:20:06 2004 @@ -359,6 +359,9 @@ dev->open = &ne2k_pci_open; dev->stop = &ne2k_pci_close; dev->ethtool_ops = &ne2k_pci_ethtool_ops; +#ifdef CONFIG_NET_POLL_CONTROLLER + dev->poll_controller = ei_poll; +#endif NS8390_init(dev, 0); i = register_netdev(dev); diff -Nru a/drivers/net/ne2k_cbus.c b/drivers/net/ne2k_cbus.c --- a/drivers/net/ne2k_cbus.c Sun Mar 14 14:20:06 2004 +++ b/drivers/net/ne2k_cbus.c Sun Mar 14 14:20:06 2004 @@ -534,6 +534,9 @@ ei_status.priv = 0; dev->open = &ne_open; dev->stop = &ne_close; +#ifdef CONFIG_NET_POLL_CONTROLLER + dev->poll_controller = ei_poll; +#endif NS8390_init(dev, 0); return 0; diff -Nru a/drivers/net/ne3210.c b/drivers/net/ne3210.c --- a/drivers/net/ne3210.c Sun Mar 14 14:20:07 2004 +++ b/drivers/net/ne3210.c Sun Mar 14 14:20:07 2004 @@ -205,6 +205,9 @@ dev->open = &ne3210_open; dev->stop = &ne3210_close; +#ifdef CONFIG_NET_POLL_CONTROLLER + dev->poll_controller = ei_poll; +#endif dev->if_port = ifmap_val[port_index]; if ((retval = register_netdev (dev))) diff -Nru a/drivers/net/netconsole.c b/drivers/net/netconsole.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/drivers/net/netconsole.c Sun Mar 14 14:20:09 2004 @@ -0,0 +1,127 @@ +/* + * linux/drivers/net/netconsole.c + * + * Copyright (C) 2001 Ingo Molnar + * + * This file contains the implementation of an IRQ-safe, crash-safe + * kernel console implementation that outputs kernel messages to the + * network. + * + * Modification history: + * + * 2001-09-17 started by Ingo Molnar. + * 2003-08-11 2.6 port by Matt Mackall + * simplified options + * generic card hooks + * works non-modular + * 2003-09-07 rewritten with netpoll api + */ + +/**************************************************************** + * 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, 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., 675 Mass Ave, Cambridge, MA 02139, USA. + * + ****************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +MODULE_AUTHOR("Maintainer: Matt Mackall "); +MODULE_DESCRIPTION("Console driver for network interfaces"); +MODULE_LICENSE("GPL"); + +static char config[256]; +module_param_string(netconsole, config, 256, 0); +MODULE_PARM_DESC(netconsole, " netconsole=[src-port]@[src-ip]/[dev],[tgt-port]@/[tgt-macaddr]\n"); + +static struct netpoll np = { + .name = "netconsole", + .dev_name = "eth0", + .local_port = 6665, + .remote_port = 6666, + .remote_mac = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}, +}; +static int configured = 0; + +#define MAX_PRINT_CHUNK 1000 + +static void write_msg(struct console *con, const char *msg, unsigned int len) +{ + int frag, left; + unsigned long flags; + + if (!np.dev) + return; + + local_irq_save(flags); + + for(left = len; left; ) { + frag = min(left, MAX_PRINT_CHUNK); + netpoll_send_udp(&np, msg, frag); + msg += frag; + left -= frag; + } + + local_irq_restore(flags); +} + +static struct console netconsole = { + .flags = CON_ENABLED | CON_PRINTBUFFER, + .write = write_msg +}; + +static int option_setup(char *opt) +{ + configured = !netpoll_parse_options(&np, opt); + return 0; +} + +__setup("netconsole=", option_setup); + +static int init_netconsole(void) +{ + if(strlen(config)) + option_setup(config); + + if(!configured) { + printk("netconsole: not configured, aborting\n"); + return -EINVAL; + } + + if(netpoll_setup(&np)) + return -EINVAL; + + register_console(&netconsole); + printk(KERN_INFO "netconsole: network logging started\n"); + return 0; +} + +static void cleanup_netconsole(void) +{ + unregister_console(&netconsole); + netpoll_cleanup(&np); +} + +module_init(init_netconsole); +module_exit(cleanup_netconsole); diff -Nru a/drivers/net/ni5010.c b/drivers/net/ni5010.c --- a/drivers/net/ni5010.c Sun Mar 14 14:20:07 2004 +++ b/drivers/net/ni5010.c Sun Mar 14 14:20:07 2004 @@ -309,7 +309,7 @@ PRINTK2((KERN_DEBUG "%s: I/O #9 passed!\n", dev->name)); /* DMA is not supported (yet?), so no use detecting it */ - lp = (struct ni5010_local*)dev->priv; + lp = netdev_priv(dev); spin_lock_init(&lp->lock); @@ -484,7 +484,7 @@ PRINTK2((KERN_DEBUG "%s: entering ni5010_interrupt\n", dev->name)); ioaddr = dev->base_addr; - lp = (struct ni5010_local *)dev->priv; + lp = netdev_priv(dev); spin_lock(&lp->lock); status = inb(IE_ISTAT); @@ -527,7 +527,7 @@ /* We have a good packet, get it out of the buffer. */ static void ni5010_rx(struct net_device *dev) { - struct ni5010_local *lp = (struct ni5010_local *)dev->priv; + struct ni5010_local *lp = netdev_priv(dev); int ioaddr = dev->base_addr; unsigned char rcv_stat; struct sk_buff *skb; @@ -592,7 +592,7 @@ static int process_xmt_interrupt(struct net_device *dev) { - struct ni5010_local *lp = (struct ni5010_local *)dev->priv; + struct ni5010_local *lp = netdev_priv(dev); int ioaddr = dev->base_addr; int xmit_stat; @@ -651,7 +651,7 @@ closed. */ static struct net_device_stats *ni5010_get_stats(struct net_device *dev) { - struct ni5010_local *lp = (struct ni5010_local *)dev->priv; + struct ni5010_local *lp = netdev_priv(dev); PRINTK2((KERN_DEBUG "%s: entering ni5010_get_stats\n", dev->name)); @@ -693,7 +693,7 @@ static void hardware_send_packet(struct net_device *dev, char *buf, int length, int pad) { - struct ni5010_local *lp = (struct ni5010_local *)dev->priv; + struct ni5010_local *lp = netdev_priv(dev); int ioaddr = dev->base_addr; unsigned long flags; unsigned int buf_offs; diff -Nru a/drivers/net/oaknet.c b/drivers/net/oaknet.c --- a/drivers/net/oaknet.c Sun Mar 14 14:20:08 2004 +++ b/drivers/net/oaknet.c Sun Mar 14 14:20:08 2004 @@ -192,6 +192,9 @@ dev->open = oaknet_open; dev->stop = oaknet_close; +#ifdef CONFIG_NET_POLL_CONTROLLER + dev->poll_controller = ei_poll; +#endif NS8390_init(dev, FALSE); ret = register_netdev(dev); diff -Nru a/drivers/net/pcmcia/3c574_cs.c b/drivers/net/pcmcia/3c574_cs.c --- a/drivers/net/pcmcia/3c574_cs.c Sun Mar 14 14:20:06 2004 +++ b/drivers/net/pcmcia/3c574_cs.c Sun Mar 14 14:20:06 2004 @@ -283,7 +283,7 @@ dev = alloc_etherdev(sizeof(struct el3_private)); if (!dev) return NULL; - lp = dev->priv; + lp = netdev_priv(dev); link = &lp->link; link->priv = dev; @@ -388,7 +388,7 @@ { client_handle_t handle = link->handle; struct net_device *dev = link->priv; - struct el3_private *lp = dev->priv; + struct el3_private *lp = netdev_priv(dev); tuple_t tuple; cisparse_t parse; unsigned short buf[32]; @@ -733,7 +733,7 @@ /* Reset and restore all of the 3c574 registers. */ static void tc574_reset(struct net_device *dev) { - struct el3_private *lp = (struct el3_private *)dev->priv; + struct el3_private *lp = netdev_priv(dev); int i, ioaddr = dev->base_addr; unsigned long flags; @@ -814,7 +814,7 @@ static int el3_open(struct net_device *dev) { - struct el3_private *lp = (struct el3_private *)dev->priv; + struct el3_private *lp = netdev_priv(dev); dev_link_t *link = &lp->link; if (!DEV_OK(link)) @@ -837,7 +837,7 @@ static void el3_tx_timeout(struct net_device *dev) { - struct el3_private *lp = (struct el3_private *)dev->priv; + struct el3_private *lp = netdev_priv(dev); ioaddr_t ioaddr = dev->base_addr; printk(KERN_NOTICE "%s: Transmit timed out!\n", dev->name); @@ -852,7 +852,7 @@ static void pop_tx_status(struct net_device *dev) { - struct el3_private *lp = (struct el3_private *)dev->priv; + struct el3_private *lp = netdev_priv(dev); ioaddr_t ioaddr = dev->base_addr; int i; @@ -877,7 +877,7 @@ static int el3_start_xmit(struct sk_buff *skb, struct net_device *dev) { ioaddr_t ioaddr = dev->base_addr; - struct el3_private *lp = (struct el3_private *)dev->priv; + struct el3_private *lp = netdev_priv(dev); unsigned long flags; DEBUG(3, "%s: el3_start_xmit(length = %ld) called, " @@ -909,7 +909,7 @@ static irqreturn_t el3_interrupt(int irq, void *dev_id, struct pt_regs *regs) { struct net_device *dev = (struct net_device *) dev_id; - struct el3_private *lp = dev->priv; + struct el3_private *lp = netdev_priv(dev); ioaddr_t ioaddr, status; int work_budget = max_interrupt_work; int handled = 0; @@ -1002,7 +1002,7 @@ static void media_check(unsigned long arg) { struct net_device *dev = (struct net_device *) arg; - struct el3_private *lp = dev->priv; + struct el3_private *lp = netdev_priv(dev); ioaddr_t ioaddr = dev->base_addr; unsigned long flags; unsigned short /* cable, */ media, partner; @@ -1074,7 +1074,7 @@ static struct net_device_stats *el3_get_stats(struct net_device *dev) { - struct el3_private *lp = (struct el3_private *)dev->priv; + struct el3_private *lp = netdev_priv(dev); if (netif_device_present(dev)) { unsigned long flags; @@ -1091,7 +1091,7 @@ */ static void update_stats(struct net_device *dev) { - struct el3_private *lp = (struct el3_private *)dev->priv; + struct el3_private *lp = netdev_priv(dev); ioaddr_t ioaddr = dev->base_addr; u8 rx, tx, up; @@ -1128,7 +1128,7 @@ static int el3_rx(struct net_device *dev, int worklimit) { - struct el3_private *lp = (struct el3_private *)dev->priv; + struct el3_private *lp = netdev_priv(dev); ioaddr_t ioaddr = dev->base_addr; short rx_status; @@ -1190,7 +1190,7 @@ /* Provide ioctl() calls to examine the MII xcvr state. */ static int el3_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) { - struct el3_private *lp = (struct el3_private *)dev->priv; + struct el3_private *lp = netdev_priv(dev); ioaddr_t ioaddr = dev->base_addr; u16 *data = (u16 *)&rq->ifr_data; int phy = lp->phys & 0x1f; @@ -1259,7 +1259,7 @@ static int el3_close(struct net_device *dev) { ioaddr_t ioaddr = dev->base_addr; - struct el3_private *lp = dev->priv; + struct el3_private *lp = netdev_priv(dev); dev_link_t *link = &lp->link; DEBUG(2, "%s: shutting down ethercard.\n", dev->name); diff -Nru a/drivers/net/pcmcia/3c589_cs.c b/drivers/net/pcmcia/3c589_cs.c --- a/drivers/net/pcmcia/3c589_cs.c Sun Mar 14 14:20:08 2004 +++ b/drivers/net/pcmcia/3c589_cs.c Sun Mar 14 14:20:08 2004 @@ -196,7 +196,7 @@ dev = alloc_etherdev(sizeof(struct el3_private)); if (!dev) return NULL; - lp = dev->priv; + lp = netdev_priv(dev); link = &lp->link; link->priv = dev; @@ -304,7 +304,7 @@ { client_handle_t handle = link->handle; struct net_device *dev = link->priv; - struct el3_private *lp = dev->priv; + struct el3_private *lp = netdev_priv(dev); tuple_t tuple; cisparse_t parse; u16 buf[32], *phys_addr; @@ -526,7 +526,7 @@ */ static void tc589_set_xcvr(struct net_device *dev, int if_port) { - struct el3_private *lp = (struct el3_private *)dev->priv; + struct el3_private *lp = netdev_priv(dev); ioaddr_t ioaddr = dev->base_addr; EL3WINDOW(0); @@ -648,7 +648,7 @@ static int el3_open(struct net_device *dev) { - struct el3_private *lp = (struct el3_private *)dev->priv; + struct el3_private *lp = netdev_priv(dev); dev_link_t *link = &lp->link; if (!DEV_OK(link)) @@ -672,7 +672,7 @@ static void el3_tx_timeout(struct net_device *dev) { - struct el3_private *lp = (struct el3_private *)dev->priv; + struct el3_private *lp = netdev_priv(dev); ioaddr_t ioaddr = dev->base_addr; printk(KERN_WARNING "%s: Transmit timed out!\n", dev->name); @@ -687,7 +687,7 @@ static void pop_tx_status(struct net_device *dev) { - struct el3_private *lp = (struct el3_private *)dev->priv; + struct el3_private *lp = netdev_priv(dev); ioaddr_t ioaddr = dev->base_addr; int i; @@ -741,7 +741,7 @@ static irqreturn_t el3_interrupt(int irq, void *dev_id, struct pt_regs *regs) { struct net_device *dev = (struct net_device *) dev_id; - struct el3_private *lp = dev->priv; + struct el3_private *lp = netdev_priv(dev); ioaddr_t ioaddr, status; int i = 0, handled = 1; @@ -826,7 +826,7 @@ static void media_check(unsigned long arg) { struct net_device *dev = (struct net_device *)(arg); - struct el3_private *lp = dev->priv; + struct el3_private *lp = netdev_priv(dev); ioaddr_t ioaddr = dev->base_addr; u16 media, errs; unsigned long flags; @@ -906,7 +906,7 @@ static struct net_device_stats *el3_get_stats(struct net_device *dev) { - struct el3_private *lp = (struct el3_private *)dev->priv; + struct el3_private *lp = netdev_priv(dev); unsigned long flags; dev_link_t *link = &lp->link; @@ -928,7 +928,7 @@ */ static void update_stats(struct net_device *dev) { - struct el3_private *lp = (struct el3_private *)dev->priv; + struct el3_private *lp = netdev_priv(dev); ioaddr_t ioaddr = dev->base_addr; DEBUG(2, "%s: updating the statistics.\n", dev->name); @@ -955,7 +955,7 @@ static int el3_rx(struct net_device *dev) { - struct el3_private *lp = (struct el3_private *)dev->priv; + struct el3_private *lp = netdev_priv(dev); ioaddr_t ioaddr = dev->base_addr; int worklimit = 32; short rx_status; @@ -1009,7 +1009,7 @@ static void set_multicast_list(struct net_device *dev) { - struct el3_private *lp = dev->priv; + struct el3_private *lp = netdev_priv(dev); dev_link_t *link = &lp->link; ioaddr_t ioaddr = dev->base_addr; u16 opts = SetRxFilter | RxStation | RxBroadcast; @@ -1024,7 +1024,7 @@ static int el3_close(struct net_device *dev) { - struct el3_private *lp = dev->priv; + struct el3_private *lp = netdev_priv(dev); dev_link_t *link = &lp->link; ioaddr_t ioaddr = dev->base_addr; diff -Nru a/drivers/net/pcmcia/com20020_cs.c b/drivers/net/pcmcia/com20020_cs.c --- a/drivers/net/pcmcia/com20020_cs.c Sun Mar 14 14:20:07 2004 +++ b/drivers/net/pcmcia/com20020_cs.c Sun Mar 14 14:20:07 2004 @@ -179,7 +179,7 @@ memset(info, 0, sizeof(struct com20020_dev_t)); memset(link, 0, sizeof(struct dev_link_t)); - lp = dev->priv; + lp = netdev_priv(dev); lp->timeout = timeout; lp->backplane = backplane; lp->clockp = clockp; @@ -394,7 +394,7 @@ goto failed; } - lp = dev->priv; + lp = netdev_priv(dev); lp->card_name = "PCMCIA COM20020"; lp->card_flags = ARC_CAN_10MBIT; /* pretend all of them can 10Mbit */ @@ -492,7 +492,7 @@ pcmcia_request_configuration(link->handle, &link->conf); if (link->open) { int ioaddr = dev->base_addr; - struct arcnet_local *lp = (struct arcnet_local *)dev->priv; + struct arcnet_local *lp = netdev_priv(dev); ARCRESET; } } diff -Nru a/drivers/net/pcmcia/fmvj18x_cs.c b/drivers/net/pcmcia/fmvj18x_cs.c --- a/drivers/net/pcmcia/fmvj18x_cs.c Sun Mar 14 14:20:07 2004 +++ b/drivers/net/pcmcia/fmvj18x_cs.c Sun Mar 14 14:20:07 2004 @@ -256,7 +256,7 @@ dev = alloc_etherdev(sizeof(local_info_t)); if (!dev) return NULL; - lp = dev->priv; + lp = netdev_priv(dev); link = &lp->link; link->priv = dev; @@ -394,7 +394,7 @@ { client_handle_t handle = link->handle; struct net_device *dev = link->priv; - local_info_t *lp = dev->priv; + local_info_t *lp = netdev_priv(dev); tuple_t tuple; cisparse_t parse; u_short buf[32]; @@ -803,7 +803,7 @@ static irqreturn_t fjn_interrupt(int irq, void *dev_id, struct pt_regs *regs) { struct net_device *dev = dev_id; - local_info_t *lp = dev->priv; + local_info_t *lp = netdev_priv(dev); ioaddr_t ioaddr; unsigned short tx_stat, rx_stat; @@ -862,7 +862,7 @@ static void fjn_tx_timeout(struct net_device *dev) { - struct local_info_t *lp = (struct local_info_t *)dev->priv; + struct local_info_t *lp = netdev_priv(dev); ioaddr_t ioaddr = dev->base_addr; printk(KERN_NOTICE "%s: transmit timed out with status %04x, %s?\n", @@ -892,7 +892,7 @@ static int fjn_start_xmit(struct sk_buff *skb, struct net_device *dev) { - struct local_info_t *lp = (struct local_info_t *)dev->priv; + struct local_info_t *lp = netdev_priv(dev); ioaddr_t ioaddr = dev->base_addr; short length = skb->len; @@ -966,7 +966,7 @@ static void fjn_reset(struct net_device *dev) { - struct local_info_t *lp = (struct local_info_t *)dev->priv; + struct local_info_t *lp = netdev_priv(dev); ioaddr_t ioaddr = dev->base_addr; int i; @@ -1052,7 +1052,7 @@ static void fjn_rx(struct net_device *dev) { - struct local_info_t *lp = (struct local_info_t *)dev->priv; + struct local_info_t *lp = netdev_priv(dev); ioaddr_t ioaddr = dev->base_addr; int boguscount = 10; /* 5 -> 10: by agy 19940922 */ @@ -1181,7 +1181,7 @@ static int fjn_open(struct net_device *dev) { - struct local_info_t *lp = (struct local_info_t *)dev->priv; + struct local_info_t *lp = netdev_priv(dev); dev_link_t *link = &lp->link; DEBUG(4, "fjn_open('%s').\n", dev->name); @@ -1206,7 +1206,7 @@ static int fjn_close(struct net_device *dev) { - struct local_info_t *lp = (struct local_info_t *)dev->priv; + struct local_info_t *lp = netdev_priv(dev); dev_link_t *link = &lp->link; ioaddr_t ioaddr = dev->base_addr; @@ -1239,7 +1239,7 @@ static struct net_device_stats *fjn_get_stats(struct net_device *dev) { - local_info_t *lp = (local_info_t *)dev->priv; + local_info_t *lp = netdev_priv(dev); return &lp->stats; } /* fjn_get_stats */ @@ -1252,7 +1252,7 @@ static void set_rx_mode(struct net_device *dev) { ioaddr_t ioaddr = dev->base_addr; - struct local_info_t *lp = (struct local_info_t *)dev->priv; + struct local_info_t *lp = netdev_priv(dev); u_char mc_filter[8]; /* Multicast hash filter */ u_long flags; int i; diff -Nru a/drivers/net/pcmcia/ibmtr_cs.c b/drivers/net/pcmcia/ibmtr_cs.c --- a/drivers/net/pcmcia/ibmtr_cs.c Sun Mar 14 14:20:07 2004 +++ b/drivers/net/pcmcia/ibmtr_cs.c Sun Mar 14 14:20:07 2004 @@ -178,7 +178,7 @@ link = &info->link; link->priv = info; - info->ti = dev->priv; + info->ti = netdev_priv(dev); link->io.Attributes1 = IO_DATA_PATH_WIDTH_8; link->io.NumPorts1 = 4; @@ -256,7 +256,7 @@ unregister_netdev(dev); { - struct tok_info *ti = (struct tok_info *)dev->priv; + struct tok_info *ti = netdev_priv(dev); del_timer_sync(&(ti->tr_timer)); } if (link->state & DEV_CONFIG) @@ -287,7 +287,7 @@ client_handle_t handle = link->handle; ibmtr_dev_t *info = link->priv; struct net_device *dev = info->dev; - struct tok_info *ti = dev->priv; + struct tok_info *ti = netdev_priv(dev); tuple_t tuple; cisparse_t parse; win_req_t req; @@ -412,7 +412,7 @@ pcmcia_release_io(link->handle, &link->io); pcmcia_release_irq(link->handle, &link->irq); if (link->win) { - struct tok_info *ti = dev->priv; + struct tok_info *ti = netdev_priv(dev); iounmap((void *)ti->mmio); pcmcia_release_window(link->win); pcmcia_release_window(info->sram_win_handle); diff -Nru a/drivers/net/pcmcia/smc91c92_cs.c b/drivers/net/pcmcia/smc91c92_cs.c --- a/drivers/net/pcmcia/smc91c92_cs.c Sun Mar 14 14:20:07 2004 +++ b/drivers/net/pcmcia/smc91c92_cs.c Sun Mar 14 14:20:07 2004 @@ -327,7 +327,7 @@ dev = alloc_etherdev(sizeof(struct smc_private)); if (!dev) return NULL; - smc = dev->priv; + smc = netdev_priv(dev); link = &smc->link; link->priv = dev; @@ -483,7 +483,7 @@ static int mhz_3288_power(dev_link_t *link) { struct net_device *dev = link->priv; - struct smc_private *smc = dev->priv; + struct smc_private *smc = netdev_priv(dev); u_char tmp; /* Read the ISR twice... */ @@ -505,7 +505,7 @@ static int mhz_mfc_config(dev_link_t *link) { struct net_device *dev = link->priv; - struct smc_private *smc = dev->priv; + struct smc_private *smc = netdev_priv(dev); tuple_t tuple; cisparse_t parse; u_char buf[255]; @@ -618,7 +618,7 @@ static void mot_config(dev_link_t *link) { struct net_device *dev = link->priv; - struct smc_private *smc = dev->priv; + struct smc_private *smc = netdev_priv(dev); ioaddr_t ioaddr = dev->base_addr; ioaddr_t iouart = link->io.BasePort2; @@ -894,7 +894,7 @@ { client_handle_t handle = link->handle; struct net_device *dev = link->priv; - struct smc_private *smc = dev->priv; + struct smc_private *smc = netdev_priv(dev); tuple_t tuple; cisparse_t parse; u_short buf[32]; @@ -1069,7 +1069,7 @@ pcmcia_release_irq(link->handle, &link->irq); if (link->win) { struct net_device *dev = link->priv; - struct smc_private *smc = dev->priv; + struct smc_private *smc = netdev_priv(dev); iounmap(smc->base); pcmcia_release_window(link->win); } @@ -1091,7 +1091,7 @@ { dev_link_t *link = args->client_data; struct net_device *dev = link->priv; - struct smc_private *smc = dev->priv; + struct smc_private *smc = netdev_priv(dev); int i; DEBUG(1, "smc91c92_event(0x%06x)\n", event); @@ -1240,7 +1240,7 @@ static int smc_open(struct net_device *dev) { - struct smc_private *smc = dev->priv; + struct smc_private *smc = netdev_priv(dev); dev_link_t *link = &smc->link; #ifdef PCMCIA_DEBUG @@ -1277,7 +1277,7 @@ static int smc_close(struct net_device *dev) { - struct smc_private *smc = dev->priv; + struct smc_private *smc = netdev_priv(dev); dev_link_t *link = &smc->link; ioaddr_t ioaddr = dev->base_addr; @@ -1314,7 +1314,7 @@ static void smc_hardware_send_packet(struct net_device * dev) { - struct smc_private *smc = dev->priv; + struct smc_private *smc = netdev_priv(dev); struct sk_buff *skb = smc->saved_skb; ioaddr_t ioaddr = dev->base_addr; u_char packet_no; @@ -1379,7 +1379,7 @@ static void smc_tx_timeout(struct net_device *dev) { - struct smc_private *smc = dev->priv; + struct smc_private *smc = netdev_priv(dev); ioaddr_t ioaddr = dev->base_addr; printk(KERN_NOTICE "%s: SMC91c92 transmit timed out, " @@ -1394,7 +1394,7 @@ static int smc_start_xmit(struct sk_buff *skb, struct net_device *dev) { - struct smc_private *smc = dev->priv; + struct smc_private *smc = netdev_priv(dev); ioaddr_t ioaddr = dev->base_addr; u_short num_pages; short time_out, ir; @@ -1460,7 +1460,7 @@ static void smc_tx_err(struct net_device * dev) { - struct smc_private *smc = (struct smc_private *)dev->priv; + struct smc_private *smc = netdev_priv(dev); ioaddr_t ioaddr = dev->base_addr; int saved_packet = inw(ioaddr + PNR_ARR) & 0xff; int packet_no = inw(ioaddr + FIFO_PORTS) & 0x7f; @@ -1504,7 +1504,7 @@ static void smc_eph_irq(struct net_device *dev) { - struct smc_private *smc = dev->priv; + struct smc_private *smc = netdev_priv(dev); ioaddr_t ioaddr = dev->base_addr; u_short card_stats, ephs; @@ -1539,7 +1539,7 @@ static irqreturn_t smc_interrupt(int irq, void *dev_id, struct pt_regs *regs) { struct net_device *dev = dev_id; - struct smc_private *smc = dev->priv; + struct smc_private *smc = netdev_priv(dev); ioaddr_t ioaddr; u_short saved_bank, saved_pointer, mask, status; unsigned int handled = 1; @@ -1657,7 +1657,7 @@ static void smc_rx(struct net_device *dev) { - struct smc_private *smc = (struct smc_private *)dev->priv; + struct smc_private *smc = netdev_priv(dev); ioaddr_t ioaddr = dev->base_addr; int rx_status; int packet_length; /* Caution: not frame length, rather words @@ -1725,7 +1725,7 @@ static struct net_device_stats *smc_get_stats(struct net_device *dev) { - struct smc_private *smc = (struct smc_private *)dev->priv; + struct smc_private *smc = netdev_priv(dev); /* Nothing to update - the 91c92 is a pretty primative chip. */ return &smc->stats; } @@ -1765,7 +1765,7 @@ static void set_rx_mode(struct net_device *dev) { ioaddr_t ioaddr = dev->base_addr; - struct smc_private *smc = dev->priv; + struct smc_private *smc = netdev_priv(dev); u_int multicast_table[ 2 ] = { 0, }; unsigned long flags; u_short rx_cfg_setting; @@ -1804,7 +1804,7 @@ static int s9k_config(struct net_device *dev, struct ifmap *map) { - struct smc_private *smc = dev->priv; + struct smc_private *smc = netdev_priv(dev); if ((map->port != (u_char)(-1)) && (map->port != dev->if_port)) { if (smc->cfg & CFG_MII_SELECT) return -EOPNOTSUPP; @@ -1830,7 +1830,7 @@ */ static void smc_set_xcvr(struct net_device *dev, int if_port) { - struct smc_private *smc = (struct smc_private *)dev->priv; + struct smc_private *smc = netdev_priv(dev); ioaddr_t ioaddr = dev->base_addr; u_short saved_bank; @@ -1855,7 +1855,7 @@ static void smc_reset(struct net_device *dev) { ioaddr_t ioaddr = dev->base_addr; - struct smc_private *smc = dev->priv; + struct smc_private *smc = netdev_priv(dev); int i; DEBUG(0, "%s: smc91c92 reset called.\n", dev->name); @@ -1930,7 +1930,7 @@ static void media_check(u_long arg) { struct net_device *dev = (struct net_device *) arg; - struct smc_private *smc = dev->priv; + struct smc_private *smc = netdev_priv(dev); ioaddr_t ioaddr = dev->base_addr; u_short i, media, saved_bank; u_short link; @@ -2044,7 +2044,7 @@ static int smc_link_ok(struct net_device *dev) { ioaddr_t ioaddr = dev->base_addr; - struct smc_private *smc = dev->priv; + struct smc_private *smc = netdev_priv(dev); if (smc->cfg & CFG_MII_SELECT) { return mii_link_ok(&smc->mii_if); @@ -2109,7 +2109,7 @@ static int smc_ethtool_ioctl (struct net_device *dev, void *useraddr) { u32 ethcmd; - struct smc_private *smc = dev->priv; + struct smc_private *smc = netdev_priv(dev); if (get_user(ethcmd, (u32 *)useraddr)) return -EFAULT; @@ -2202,7 +2202,7 @@ static int smc_ioctl (struct net_device *dev, struct ifreq *rq, int cmd) { - struct smc_private *smc = dev->priv; + struct smc_private *smc = netdev_priv(dev); struct mii_ioctl_data *mii; int rc = 0; u_short saved_bank; diff -Nru a/drivers/net/pcmcia/xirc2ps_cs.c b/drivers/net/pcmcia/xirc2ps_cs.c --- a/drivers/net/pcmcia/xirc2ps_cs.c Sun Mar 14 14:20:07 2004 +++ b/drivers/net/pcmcia/xirc2ps_cs.c Sun Mar 14 14:20:07 2004 @@ -1666,6 +1666,7 @@ struct ethtool_drvinfo *info) { strcpy(info->driver, "xirc2ps_cs"); + sprintf(info->bus_info, "PCMCIA 0x%lx", dev->base_addr); } static struct ethtool_ops netdev_ethtool_ops = { diff -Nru a/drivers/net/pcnet32.c b/drivers/net/pcnet32.c --- a/drivers/net/pcnet32.c Sun Mar 14 14:20:06 2004 +++ b/drivers/net/pcnet32.c Sun Mar 14 14:20:06 2004 @@ -225,10 +225,12 @@ * v1.27b Sep 30 2002 Kent Yoder * Added timer for cable connection state changes. * v1.28 20 Feb 2004 Don Fry - * Jon Lewis , Chinmay Albal + * Jon Mason , Chinmay Albal * Now uses ethtool_ops, netif_msg_* and generic_mii_ioctl. * Fixes bogus 'Bus master arbitration failure', pci_[un]map_single * length errors, and transmit hangs. Cleans up after errors in open. + * Jim Lewis added ethernet loopback test. + * Thomas Munck Steenholdt non-mii ioctl corrections. */ @@ -479,6 +481,14 @@ .reset = pcnet32_dwio_reset }; +#ifdef CONFIG_NET_POLL_CONTROLLER +static void pcnet32_poll_controller(struct net_device *dev) +{ + disable_irq(dev->irq); + pcnet32_interrupt(0, dev, NULL); + enable_irq(dev->irq); +} +#endif static int pcnet32_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) @@ -1106,6 +1116,10 @@ dev->tx_timeout = pcnet32_tx_timeout; dev->watchdog_timeo = (5*HZ); +#ifdef CONFIG_NET_POLL_CONTROLLER + dev->poll_controller = pcnet32_poll_controller; +#endif + /* Fill in the generic fields of the device structure. */ if (register_netdev(dev)) goto err_free_consistent; @@ -1733,13 +1747,17 @@ if (!rx_in_place) { skb_reserve(skb,2); /* 16 byte align */ skb_put(skb,pkt_len); /* Make room */ - pci_dma_sync_single(lp->pci_dev, - lp->rx_dma_addr[entry], - PKT_BUF_SZ-2, - PCI_DMA_FROMDEVICE); + pci_dma_sync_single_for_cpu(lp->pci_dev, + lp->rx_dma_addr[entry], + PKT_BUF_SZ-2, + PCI_DMA_FROMDEVICE); eth_copy_and_sum(skb, (unsigned char *)(lp->rx_skbuff[entry]->tail), pkt_len,0); + pci_dma_sync_single_for_device(lp->pci_dev, + lp->rx_dma_addr[entry], + PKT_BUF_SZ-2, + PCI_DMA_FROMDEVICE); } lp->stats.rx_bytes += skb->len; skb->protocol=eth_type_trans(skb,dev); diff -Nru a/drivers/net/plip.c b/drivers/net/plip.c --- a/drivers/net/plip.c Sun Mar 14 14:20:08 2004 +++ b/drivers/net/plip.c Sun Mar 14 14:20:08 2004 @@ -280,7 +280,7 @@ static void plip_init_netdev(struct net_device *dev) { - struct net_local *nl = dev->priv; + struct net_local *nl = netdev_priv(dev); /* Then, override parts of it */ dev->hard_start_xmit = plip_tx_packet; @@ -323,7 +323,7 @@ static void plip_kick_bh(struct net_device *dev) { - struct net_local *nl = (struct net_local *)dev->priv; + struct net_local *nl = netdev_priv(dev); if (nl->is_deferred) schedule_work(&nl->immediate); @@ -366,7 +366,7 @@ static void plip_bh(struct net_device *dev) { - struct net_local *nl = (struct net_local *)dev->priv; + struct net_local *nl = netdev_priv(dev); struct plip_local *snd = &nl->snd_data; struct plip_local *rcv = &nl->rcv_data; plip_func f; @@ -384,7 +384,7 @@ static void plip_timer_bh(struct net_device *dev) { - struct net_local *nl = (struct net_local *)dev->priv; + struct net_local *nl = netdev_priv(dev); if (!(atomic_read (&nl->kill_timer))) { plip_interrupt (-1, dev, NULL); @@ -917,7 +917,7 @@ return; } - nl = (struct net_local *)dev->priv; + nl = netdev_priv(dev); rcv = &nl->rcv_data; spin_lock_irq (&nl->lock); @@ -961,7 +961,7 @@ static int plip_tx_packet(struct sk_buff *skb, struct net_device *dev) { - struct net_local *nl = (struct net_local *)dev->priv; + struct net_local *nl = netdev_priv(dev); struct plip_local *snd = &nl->snd_data; if (netif_queue_stopped(dev)) @@ -1021,7 +1021,7 @@ unsigned short type, void *daddr, void *saddr, unsigned len) { - struct net_local *nl = (struct net_local *)dev->priv; + struct net_local *nl = netdev_priv(dev); int ret; if ((ret = nl->orig_hard_header(skb, dev, type, daddr, saddr, len)) >= 0) @@ -1033,7 +1033,7 @@ int plip_hard_header_cache(struct neighbour *neigh, struct hh_cache *hh) { - struct net_local *nl = (struct net_local *)neigh->dev->priv; + struct net_local *nl = neigh->dev->priv; int ret; if ((ret = nl->orig_hard_header_cache(neigh, hh)) == 0) @@ -1057,7 +1057,7 @@ static int plip_open(struct net_device *dev) { - struct net_local *nl = (struct net_local *)dev->priv; + struct net_local *nl = netdev_priv(dev); struct in_device *in_dev; /* Grab the port */ @@ -1116,7 +1116,7 @@ static int plip_close(struct net_device *dev) { - struct net_local *nl = (struct net_local *)dev->priv; + struct net_local *nl = netdev_priv(dev); struct plip_local *snd = &nl->snd_data; struct plip_local *rcv = &nl->rcv_data; @@ -1163,7 +1163,7 @@ plip_preempt(void *handle) { struct net_device *dev = (struct net_device *)handle; - struct net_local *nl = (struct net_local *)dev->priv; + struct net_local *nl = netdev_priv(dev); /* Stand our ground if a datagram is on the wire */ if (nl->connection != PLIP_CN_NONE) { @@ -1179,7 +1179,7 @@ plip_wakeup(void *handle) { struct net_device *dev = (struct net_device *)handle; - struct net_local *nl = (struct net_local *)dev->priv; + struct net_local *nl = netdev_priv(dev); if (nl->port_owner) { /* Why are we being woken up? */ @@ -1207,7 +1207,7 @@ static struct net_device_stats * plip_get_stats(struct net_device *dev) { - struct net_local *nl = (struct net_local *)dev->priv; + struct net_local *nl = netdev_priv(dev); struct net_device_stats *r = &nl->enet_stats; return r; @@ -1216,7 +1216,7 @@ static int plip_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) { - struct net_local *nl = (struct net_local *) dev->priv; + struct net_local *nl = netdev_priv(dev); struct plipconf *pc = (struct plipconf *) &rq->ifr_data; switch(pc->pcmd) { @@ -1288,7 +1288,7 @@ "which is fairly inefficient!\n", port->name); } - nl = dev->priv; + nl = netdev_priv(dev); nl->pardev = parport_register_device(port, name, plip_preempt, plip_wakeup, plip_interrupt, 0, dev); @@ -1348,7 +1348,7 @@ for (i=0; i < PLIP_MAX; i++) { if ((dev = dev_plip[i])) { - struct net_local *nl = dev->priv; + struct net_local *nl = netdev_priv(dev); unregister_netdev(dev); if (nl->port_owner) parport_release(nl->pardev); diff -Nru a/drivers/net/rrunner.c b/drivers/net/rrunner.c --- a/drivers/net/rrunner.c Sun Mar 14 14:20:06 2004 +++ b/drivers/net/rrunner.c Sun Mar 14 14:20:06 2004 @@ -108,7 +108,7 @@ goto out2; } - rrpriv = (struct rr_private *)dev->priv; + rrpriv = netdev_priv(dev); SET_MODULE_OWNER(dev); SET_NETDEV_DEV(dev, &pdev->dev); @@ -236,7 +236,7 @@ struct net_device *dev = pci_get_drvdata(pdev); if (dev) { - struct rr_private *rr = dev->priv; + struct rr_private *rr = netdev_priv(dev); if (!(readl(&rr->regs->HostCtrl) & NIC_HALTED)){ printk(KERN_ERR "%s: trying to unload running NIC\n", @@ -308,7 +308,7 @@ u32 start_pc; int i; - rrpriv = (struct rr_private *)dev->priv; + rrpriv = netdev_priv(dev); regs = rrpriv->regs; rr_load_firmware(dev); @@ -524,7 +524,7 @@ u32 sram_size, rev; int i; - rrpriv = (struct rr_private *)dev->priv; + rrpriv = netdev_priv(dev); regs = rrpriv->regs; rev = readl(®s->FwRev); @@ -595,7 +595,7 @@ int ecode = 0; short i; - rrpriv = (struct rr_private *)dev->priv; + rrpriv = netdev_priv(dev); regs = rrpriv->regs; spin_lock_irqsave(&rrpriv->lock, flags); @@ -761,7 +761,7 @@ struct rr_regs *regs; u32 tmp; - rrpriv = (struct rr_private *)dev->priv; + rrpriv = netdev_priv(dev); regs = rrpriv->regs; while (prodidx != eidx){ @@ -960,7 +960,7 @@ static void rx_int(struct net_device *dev, u32 rxlimit, u32 index) { - struct rr_private *rrpriv = (struct rr_private *)dev->priv; + struct rr_private *rrpriv = netdev_priv(dev); struct rr_regs *regs = rrpriv->regs; do { @@ -983,18 +983,26 @@ rx_skb = rrpriv->rx_skbuff[index]; - pci_dma_sync_single(rrpriv->pci_dev, desc->addr.addrlo, - pkt_len, PCI_DMA_FROMDEVICE); - if (pkt_len < PKT_COPY_THRESHOLD) { skb = alloc_skb(pkt_len, GFP_ATOMIC); if (skb == NULL){ printk(KERN_WARNING "%s: Unable to allocate skb (%i bytes), deferring packet\n", dev->name, pkt_len); rrpriv->stats.rx_dropped++; goto defer; - }else + } else { + pci_dma_sync_single_for_cpu(rrpriv->pci_dev, + desc->addr.addrlo, + pkt_len, + PCI_DMA_FROMDEVICE); + memcpy(skb_put(skb, pkt_len), rx_skb->data, pkt_len); + + pci_dma_sync_single_for_device(rrpriv->pci_dev, + desc->addr.addrlo, + pkt_len, + PCI_DMA_FROMDEVICE); + } }else{ struct sk_buff *newskb; @@ -1052,7 +1060,7 @@ struct net_device *dev = (struct net_device *)dev_id; u32 prodidx, rxindex, eidx, txcsmr, rxlimit, txcon; - rrpriv = (struct rr_private *)dev->priv; + rrpriv = netdev_priv(dev); regs = rrpriv->regs; if (!(readl(®s->HostCtrl) & RR_INT)) @@ -1133,7 +1141,7 @@ static void rr_timer(unsigned long data) { struct net_device *dev = (struct net_device *)data; - struct rr_private *rrpriv = (struct rr_private *)dev->priv; + struct rr_private *rrpriv = netdev_priv(dev); struct rr_regs *regs = rrpriv->regs; unsigned long flags; @@ -1160,7 +1168,7 @@ static int rr_open(struct net_device *dev) { - struct rr_private *rrpriv = (struct rr_private *)dev->priv; + struct rr_private *rrpriv = netdev_priv(dev); struct pci_dev *pdev = rrpriv->pci_dev; struct rr_regs *regs; int ecode = 0; @@ -1296,7 +1304,7 @@ short i; int len; - rrpriv = (struct rr_private *)dev->priv; + rrpriv = netdev_priv(dev); regs = rrpriv->regs; printk("%s: dumping NIC TX rings\n", dev->name); @@ -1361,7 +1369,7 @@ netif_stop_queue(dev); - rrpriv = (struct rr_private *)dev->priv; + rrpriv = netdev_priv(dev); regs = rrpriv->regs; /* @@ -1418,7 +1426,7 @@ static int rr_start_xmit(struct sk_buff *skb, struct net_device *dev) { - struct rr_private *rrpriv = (struct rr_private *)dev->priv; + struct rr_private *rrpriv = netdev_priv(dev); struct rr_regs *regs = rrpriv->regs; struct ring_ctrl *txctrl; unsigned long flags; @@ -1488,7 +1496,7 @@ { struct rr_private *rrpriv; - rrpriv = (struct rr_private *)dev->priv; + rrpriv = netdev_priv(dev); return(&rrpriv->stats); } @@ -1511,7 +1519,7 @@ u32 p2len, p2size, nr_seg, revision, io, sram_size; struct eeprom *hw = NULL; - rrpriv = (struct rr_private *)dev->priv; + rrpriv = netdev_priv(dev); regs = rrpriv->regs; if (dev->flags & IFF_UP) @@ -1614,7 +1622,7 @@ unsigned int i; int error = -EOPNOTSUPP; - rrpriv = dev->priv; + rrpriv = netdev_priv(dev); switch(cmd){ case SIOCRRGFW: diff -Nru a/drivers/net/sb1000.c b/drivers/net/sb1000.c --- a/drivers/net/sb1000.c Sun Mar 14 14:20:06 2004 +++ b/drivers/net/sb1000.c Sun Mar 14 14:20:06 2004 @@ -746,7 +746,7 @@ int ioaddr, ns; unsigned int skbsize; struct sk_buff *skb; - struct sb1000_private *lp = (struct sb1000_private *)dev->priv; + struct sb1000_private *lp = netdev_priv(dev); struct net_device_stats *stats = &lp->stats; /* SB1000 frame constants */ @@ -905,7 +905,7 @@ char *name; unsigned char st[5]; int ioaddr[2]; - struct sb1000_private *lp = (struct sb1000_private *)dev->priv; + struct sb1000_private *lp = netdev_priv(dev); const unsigned char Command0[6] = {0x80, 0x26, 0x00, 0x00, 0x00, 0x00}; const int ErrorDpcCounterInitialize = 200; @@ -932,7 +932,7 @@ { char *name; int ioaddr[2], status; - struct sb1000_private *lp = (struct sb1000_private *)dev->priv; + struct sb1000_private *lp = netdev_priv(dev); const unsigned short FirmwareVersion[] = {0x01, 0x01}; ioaddr[0] = dev->base_addr; @@ -998,7 +998,7 @@ short PID[4]; int ioaddr[2], status, frequency; unsigned int stats[5]; - struct sb1000_private *lp = (struct sb1000_private *)dev->priv; + struct sb1000_private *lp = netdev_priv(dev); if (!(dev && dev->flags & IFF_UP)) return -ENODEV; @@ -1092,7 +1092,7 @@ unsigned char st; int ioaddr[2]; struct net_device *dev = (struct net_device *) dev_id; - struct sb1000_private *lp = (struct sb1000_private *)dev->priv; + struct sb1000_private *lp = netdev_priv(dev); const unsigned char Command0[6] = {0x80, 0x2c, 0x00, 0x00, 0x00, 0x00}; const unsigned char Command1[6] = {0x80, 0x2e, 0x00, 0x00, 0x00, 0x00}; @@ -1148,7 +1148,7 @@ static struct net_device_stats *sb1000_stats(struct net_device *dev) { - struct sb1000_private *lp = (struct sb1000_private *)dev->priv; + struct sb1000_private *lp = netdev_priv(dev); return &lp->stats; } @@ -1156,7 +1156,7 @@ { int i; int ioaddr[2]; - struct sb1000_private *lp = (struct sb1000_private *)dev->priv; + struct sb1000_private *lp = netdev_priv(dev); if (sb1000_debug > 2) printk(KERN_DEBUG "%s: Shutting down sb1000.\n", dev->name); diff -Nru a/drivers/net/sb1250-mac.c b/drivers/net/sb1250-mac.c --- a/drivers/net/sb1250-mac.c Sun Mar 14 14:20:08 2004 +++ b/drivers/net/sb1250-mac.c Sun Mar 14 14:20:08 2004 @@ -2080,7 +2080,7 @@ static irqreturn_t sbmac_intr(int irq,void *dev_instance,struct pt_regs *rgs) { struct net_device *dev = (struct net_device *) dev_instance; - struct sbmac_softc *sc = (struct sbmac_softc *) (dev->priv); + struct sbmac_softc *sc = netdev_priv(dev); uint64_t isr; int handled = 0; @@ -2150,7 +2150,7 @@ ********************************************************************* */ static int sbmac_start_tx(struct sk_buff *skb, struct net_device *dev) { - struct sbmac_softc *sc = (struct sbmac_softc *)dev->priv; + struct sbmac_softc *sc = netdev_priv(dev); /* lock eth irq */ spin_lock_irq (&sc->sbm_lock); @@ -2374,7 +2374,7 @@ int i; int err; - sc = (struct sbmac_softc *)dev->priv; + sc = netdev_priv(dev); /* Determine controller base address */ @@ -2454,7 +2454,7 @@ static int sbmac_open(struct net_device *dev) { - struct sbmac_softc *sc = (struct sbmac_softc *)dev->priv; + struct sbmac_softc *sc = netdev_priv(dev); if (debug > 1) { printk(KERN_DEBUG "%s: sbmac_open() irq %d.\n", dev->name, dev->irq); @@ -2609,7 +2609,7 @@ static void sbmac_timer(unsigned long data) { struct net_device *dev = (struct net_device *)data; - struct sbmac_softc *sc = (struct sbmac_softc *)dev->priv; + struct sbmac_softc *sc = netdev_priv(dev); int next_tick = HZ; int mii_status; @@ -2655,7 +2655,7 @@ static void sbmac_tx_timeout (struct net_device *dev) { - struct sbmac_softc *sc = (struct sbmac_softc *) dev->priv; + struct sbmac_softc *sc = netdev_priv(dev); spin_lock_irq (&sc->sbm_lock); @@ -2673,7 +2673,7 @@ static struct net_device_stats *sbmac_get_stats(struct net_device *dev) { - struct sbmac_softc *sc = (struct sbmac_softc *)dev->priv; + struct sbmac_softc *sc = netdev_priv(dev); unsigned long flags; spin_lock_irqsave(&sc->sbm_lock, flags); @@ -2691,7 +2691,7 @@ { unsigned long flags; int msg_flag = 0; - struct sbmac_softc *sc = (struct sbmac_softc *)dev->priv; + struct sbmac_softc *sc = netdev_priv(dev); spin_lock_irqsave(&sc->sbm_lock, flags); if ((dev->flags ^ sc->sbm_devflags) & IFF_PROMISC) { @@ -2726,7 +2726,7 @@ static int sbmac_mii_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) { - struct sbmac_softc *sc = (struct sbmac_softc *)dev->priv; + struct sbmac_softc *sc = netdev_priv(dev); u16 *data = (u16 *)&rq->ifr_data; unsigned long flags; int retval; @@ -2762,7 +2762,7 @@ static int sbmac_close(struct net_device *dev) { - struct sbmac_softc *sc = (struct sbmac_softc *)dev->priv; + struct sbmac_softc *sc = netdev_priv(dev); unsigned long flags; int irq; @@ -2911,7 +2911,7 @@ for (idx = 0; idx < MAX_UNITS; idx++) { dev = dev_sbmac[idx]; if (!dev) { - struct sbmac_softc *sc = dev->priv; + struct sbmac_softc *sc = netdev_priv(dev); unregister_netdev(dev); sbmac_uninitctx(sc); free_netdev(dev); diff -Nru a/drivers/net/seeq8005.c b/drivers/net/seeq8005.c --- a/drivers/net/seeq8005.c Sun Mar 14 14:20:08 2004 +++ b/drivers/net/seeq8005.c Sun Mar 14 14:20:08 2004 @@ -357,7 +357,7 @@ */ static int seeq8005_open(struct net_device *dev) { - struct net_local *lp = (struct net_local *)dev->priv; + struct net_local *lp = netdev_priv(dev); { int irqval = request_irq(dev->irq, &seeq8005_interrupt, 0, "seeq8005", dev); @@ -390,7 +390,7 @@ static int seeq8005_send_packet(struct sk_buff *skb, struct net_device *dev) { - struct net_local *lp = (struct net_local *)dev->priv; + struct net_local *lp = netdev_priv(dev); short length = skb->len; unsigned char *buf; @@ -424,7 +424,7 @@ int handled = 0; ioaddr = dev->base_addr; - lp = (struct net_local *)dev->priv; + lp = netdev_priv(dev); status = inw(SEEQ_STATUS); do { @@ -462,7 +462,7 @@ /* We have a good packet(s), get it/them out of the buffers. */ static void seeq8005_rx(struct net_device *dev) { - struct net_local *lp = (struct net_local *)dev->priv; + struct net_local *lp = netdev_priv(dev); int boguscount = 10; int pkt_hdr; int ioaddr = dev->base_addr; @@ -561,7 +561,7 @@ /* The inverse routine to net_open(). */ static int seeq8005_close(struct net_device *dev) { - struct net_local *lp = (struct net_local *)dev->priv; + struct net_local *lp = netdev_priv(dev); int ioaddr = dev->base_addr; lp->open_time = 0; @@ -583,7 +583,7 @@ closed. */ static struct net_device_stats *seeq8005_get_stats(struct net_device *dev) { - struct net_local *lp = (struct net_local *)dev->priv; + struct net_local *lp = netdev_priv(dev); return &lp->stats; } @@ -618,7 +618,7 @@ void seeq8005_init(struct net_device *dev, int startp) { - struct net_local *lp = (struct net_local *)dev->priv; + struct net_local *lp = netdev_priv(dev); int ioaddr = dev->base_addr; int i; diff -Nru a/drivers/net/sgiseeq.c b/drivers/net/sgiseeq.c --- a/drivers/net/sgiseeq.c Sun Mar 14 14:20:08 2004 +++ b/drivers/net/sgiseeq.c Sun Mar 14 14:20:08 2004 @@ -151,7 +151,7 @@ static int seeq_init_ring(struct net_device *dev) { - struct sgiseeq_private *sp = (struct sgiseeq_private *) dev->priv; + struct sgiseeq_private *sp = netdev_priv(dev); volatile struct sgiseeq_init_block *ib = &sp->srings; int i; @@ -423,7 +423,7 @@ static irqreturn_t sgiseeq_interrupt(int irq, void *dev_id, struct pt_regs *regs) { struct net_device *dev = (struct net_device *) dev_id; - struct sgiseeq_private *sp = (struct sgiseeq_private *) dev->priv; + struct sgiseeq_private *sp = netdev_priv(dev); struct hpc3_ethregs *hregs = sp->hregs; struct sgiseeq_regs *sregs = sp->sregs; @@ -445,7 +445,7 @@ static int sgiseeq_open(struct net_device *dev) { - struct sgiseeq_private *sp = (struct sgiseeq_private *)dev->priv; + struct sgiseeq_private *sp = netdev_priv(dev); struct sgiseeq_regs *sregs = sp->sregs; int err = init_seeq(dev, sp, sregs); @@ -459,7 +459,7 @@ static int sgiseeq_close(struct net_device *dev) { - struct sgiseeq_private *sp = (struct sgiseeq_private *) dev->priv; + struct sgiseeq_private *sp = netdev_priv(dev); struct sgiseeq_regs *sregs = sp->sregs; netif_stop_queue(dev); @@ -472,7 +472,7 @@ static inline int sgiseeq_reset(struct net_device *dev) { - struct sgiseeq_private *sp = (struct sgiseeq_private *) dev->priv; + struct sgiseeq_private *sp = netdev_priv(dev); struct sgiseeq_regs *sregs = sp->sregs; int err; @@ -494,7 +494,7 @@ static int sgiseeq_start_xmit(struct sk_buff *skb, struct net_device *dev) { - struct sgiseeq_private *sp = (struct sgiseeq_private *) dev->priv; + struct sgiseeq_private *sp = netdev_priv(dev); struct hpc3_ethregs *hregs = sp->hregs; unsigned long flags; struct sgiseeq_tx_desc *td; @@ -560,7 +560,7 @@ static struct net_device_stats *sgiseeq_get_stats(struct net_device *dev) { - struct sgiseeq_private *sp = (struct sgiseeq_private *) dev->priv; + struct sgiseeq_private *sp = netdev_priv(dev); return &sp->stats; } @@ -710,7 +710,7 @@ struct net_device *next, *dev = root_sgiseeq_dev; while (dev) { - sp = (struct sgiseeq_private *) dev->priv; + sp = netdev_priv(dev); next = sp->next_module; unregister_netdev(dev); free_irq(dev->irq, dev); diff -Nru a/drivers/net/sis190.c b/drivers/net/sis190.c --- a/drivers/net/sis190.c Sun Mar 14 14:20:09 2004 +++ b/drivers/net/sis190.c Sun Mar 14 14:20:09 2004 @@ -1016,14 +1016,20 @@ 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; skb_reserve(skb, 2); // 16 byte align the IP fields. // + pci_dma_sync_single_for_cpu(tp->pci_dev, + desc->buf_addr, + RX_BUF_SIZE, + PCI_DMA_FROMDEVICE); eth_copy_and_sum(skb, tp->RxBufferRing[cur_rx], pkt_size, 0); + pci_dma_sync_single_for_device(tp->pci_dev, + desc->buf_addr, + RX_BUF_SIZE, + PCI_DMA_FROMDEVICE); skb_put(skb, pkt_size); skb->protocol = eth_type_trans(skb, dev); netif_rx(skb); diff -Nru a/drivers/net/sis900.c b/drivers/net/sis900.c --- a/drivers/net/sis900.c Sun Mar 14 14:20:07 2004 +++ b/drivers/net/sis900.c Sun Mar 14 14:20:07 2004 @@ -1650,9 +1650,6 @@ break; } - pci_dma_sync_single(sis_priv->pci_dev, - sis_priv->rx_ring[entry].bufptr, RX_BUF_SIZE, - PCI_DMA_FROMDEVICE); pci_unmap_single(sis_priv->pci_dev, sis_priv->rx_ring[entry].bufptr, RX_BUF_SIZE, PCI_DMA_FROMDEVICE); diff -Nru a/drivers/net/sk98lin/skge.c b/drivers/net/sk98lin/skge.c --- a/drivers/net/sk98lin/skge.c Sun Mar 14 14:20:06 2004 +++ b/drivers/net/sk98lin/skge.c Sun Mar 14 14:20:06 2004 @@ -2533,12 +2533,6 @@ "Control: %x\nRxStat: %x\n", Control, FrameStat)); - PhysAddr = ((SK_U64) pRxd->VDataHigh) << (SK_U64)32; - PhysAddr |= (SK_U64) pRxd->VDataLow; - pci_dma_sync_single(pAC->PciDev, - (dma_addr_t) PhysAddr, - FrameLength, - PCI_DMA_FROMDEVICE); ReQueueRxBuffer(pAC, pRxPort, pMsg, pRxd->VDataHigh, pRxd->VDataLow); @@ -2559,12 +2553,16 @@ PhysAddr = ((SK_U64) pRxd->VDataHigh) << (SK_U64)32; PhysAddr |= (SK_U64) pRxd->VDataLow; - pci_dma_sync_single(pAC->PciDev, - (dma_addr_t) PhysAddr, - FrameLength, - PCI_DMA_FROMDEVICE); + pci_dma_sync_single_for_cpu(pAC->PciDev, + (dma_addr_t) PhysAddr, + FrameLength, + PCI_DMA_FROMDEVICE); eth_copy_and_sum(pNewMsg, pMsg->data, FrameLength, 0); + pci_dma_sync_single_for_device(pAC->PciDev, + (dma_addr_t) PhysAddr, + FrameLength, + PCI_DMA_FROMDEVICE); ReQueueRxBuffer(pAC, pRxPort, pMsg, pRxd->VDataHigh, pRxd->VDataLow); diff -Nru a/drivers/net/sk_g16.c b/drivers/net/sk_g16.c --- a/drivers/net/sk_g16.c Sun Mar 14 14:20:09 2004 +++ b/drivers/net/sk_g16.c Sun Mar 14 14:20:09 2004 @@ -650,7 +650,7 @@ int sk_addr_flag = 0; /* SK ADDR correct? 1 - no, 0 - yes */ unsigned int rom_addr; /* used to store RAM address used for POS_ADDR */ - struct priv *p = dev->priv; /* SK_G16 private structure */ + struct priv *p = netdev_priv(dev); /* SK_G16 private structure */ if (inb(SK_POS0) != SK_IDLOW || inb(SK_POS1) != SK_IDHIGH) return -ENODEV; @@ -869,7 +869,7 @@ int irqtab[] = SK_IRQS; - struct priv *p = (struct priv *)dev->priv; + struct priv *p = netdev_priv(dev); PRINTK(("## %s: At beginning of SK_open(). CSR0: %#06x\n", SK_NAME, SK_read_reg(CSR0))); @@ -1023,7 +1023,7 @@ { int i; unsigned long flags; - struct priv *p = (struct priv *) dev->priv; + struct priv *p = netdev_priv(dev); struct tmd *tmdp; struct rmd *rmdp; @@ -1196,7 +1196,7 @@ static int SK_send_packet(struct sk_buff *skb, struct net_device *dev) { - struct priv *p = (struct priv *) dev->priv; + struct priv *p = netdev_priv(dev); struct tmd *tmdp; static char pad[64]; @@ -1285,7 +1285,7 @@ { int csr0; struct net_device *dev = dev_id; - struct priv *p = (struct priv *) dev->priv; + struct priv *p = netdev_priv(dev); PRINTK2(("## %s: SK_interrupt(). status: %#06x\n", @@ -1355,7 +1355,7 @@ { int tmdstat; struct tmd *tmdp; - struct priv *p = (struct priv *) dev->priv; + struct priv *p = netdev_priv(dev); PRINTK2(("## %s: SK_txintr() status: %#06x\n", @@ -1469,7 +1469,7 @@ struct rmd *rmdp; int rmdstat; - struct priv *p = (struct priv *) dev->priv; + struct priv *p = netdev_priv(dev); PRINTK2(("## %s: SK_rxintr(). CSR0: %#06x\n", SK_NAME, SK_read_reg(CSR0))); @@ -1653,7 +1653,7 @@ static struct net_device_stats *SK_get_stats(struct net_device *dev) { - struct priv *p = (struct priv *) dev->priv; + struct priv *p = netdev_priv(dev); PRINTK(("## %s: SK_get_stats(). CSR0: %#06x\n", SK_NAME, SK_read_reg(CSR0))); @@ -2030,7 +2030,7 @@ { int i; - struct priv *p = (struct priv *) dev->priv; + struct priv *p = netdev_priv(dev); printk("## %s: RAM Details.\n" "## RAM at %#08x tmdhead: %#08x rmdhead: %#08x initblock: %#08x\n", diff -Nru a/drivers/net/smc-mca.c b/drivers/net/smc-mca.c --- a/drivers/net/smc-mca.c Sun Mar 14 14:20:06 2004 +++ b/drivers/net/smc-mca.c Sun Mar 14 14:20:06 2004 @@ -324,6 +324,9 @@ dev->open = &ultramca_open; dev->stop = &ultramca_close_card; +#ifdef CONFIG_NET_POLL_CONTROLLER + dev->poll_controller = ei_poll; +#endif NS8390_init(dev, 0); diff -Nru a/drivers/net/smc-ultra.c b/drivers/net/smc-ultra.c --- a/drivers/net/smc-ultra.c Sun Mar 14 14:20:06 2004 +++ b/drivers/net/smc-ultra.c Sun Mar 14 14:20:06 2004 @@ -121,6 +121,14 @@ #define ULTRA_IO_EXTENT 32 #define EN0_ERWCNT 0x08 /* Early receive warning count. */ +#ifdef CONFIG_NET_POLL_CONTROLLER +static void ultra_poll(struct net_device *dev) +{ + disable_irq(dev->irq); + ei_interrupt(dev->irq, dev, NULL); + enable_irq(dev->irq); +} +#endif /* Probe for the Ultra. This looks like a 8013 with the station address PROM at I/O ports +8 to +13, with a checksum following. @@ -134,6 +142,9 @@ SET_MODULE_OWNER(dev); +#ifdef CONFIG_NET_POLL_CONTROLLER + dev->poll_controller = &ultra_poll; +#endif if (base_addr > 0x1ff) /* Check a single specified location. */ return ultra_probe1(dev, base_addr); else if (base_addr != 0) /* Don't probe at all. */ @@ -301,6 +312,9 @@ ei_status.reset_8390 = &ultra_reset_8390; dev->open = &ultra_open; dev->stop = &ultra_close_card; +#ifdef CONFIG_NET_POLL_CONTROLLER + dev->poll_controller = ei_poll; +#endif NS8390_init(dev, 0); return 0; diff -Nru a/drivers/net/smc-ultra32.c b/drivers/net/smc-ultra32.c --- a/drivers/net/smc-ultra32.c Sun Mar 14 14:20:08 2004 +++ b/drivers/net/smc-ultra32.c Sun Mar 14 14:20:08 2004 @@ -268,6 +268,9 @@ ei_status.reset_8390 = &ultra32_reset_8390; dev->open = &ultra32_open; dev->stop = &ultra32_close; +#ifdef CONFIG_NET_POLL_CONTROLLER + dev->poll_controller = ei_poll; +#endif NS8390_init(dev, 0); return 0; diff -Nru a/drivers/net/smc9194.c b/drivers/net/smc9194.c --- a/drivers/net/smc9194.c Sun Mar 14 14:20:08 2004 +++ b/drivers/net/smc9194.c Sun Mar 14 14:20:08 2004 @@ -465,7 +465,7 @@ */ static int smc_wait_to_send_packet( struct sk_buff * skb, struct net_device * dev ) { - struct smc_local *lp = (struct smc_local *)dev->priv; + struct smc_local *lp = netdev_priv(dev); unsigned short ioaddr = dev->base_addr; word length; unsigned short numPages; @@ -576,7 +576,7 @@ */ static void smc_hardware_send_packet( struct net_device * dev ) { - struct smc_local *lp = (struct smc_local *)dev->priv; + struct smc_local *lp = netdev_priv(dev); byte packet_no; struct sk_buff * skb = lp->saved_skb; word length; @@ -1150,7 +1150,7 @@ { struct net_device *dev = dev_id; int ioaddr = dev->base_addr; - struct smc_local *lp = (struct smc_local *)dev->priv; + struct smc_local *lp = netdev_priv(dev); byte status; word card_stats; @@ -1274,7 +1274,7 @@ */ static void smc_rcv(struct net_device *dev) { - struct smc_local *lp = (struct smc_local *)dev->priv; + struct smc_local *lp = netdev_priv(dev); int ioaddr = dev->base_addr; int packet_number; word status; @@ -1401,7 +1401,7 @@ static void smc_tx( struct net_device * dev ) { int ioaddr = dev->base_addr; - struct smc_local *lp = (struct smc_local *)dev->priv; + struct smc_local *lp = netdev_priv(dev); byte saved_packet; byte packet_no; word tx_status; @@ -1474,7 +1474,7 @@ . This may be called with the card open or closed. .-------------------------------------------------------------*/ static struct net_device_stats* smc_query_statistics(struct net_device *dev) { - struct smc_local *lp = (struct smc_local *)dev->priv; + struct smc_local *lp = netdev_priv(dev); return &lp->stats; } diff -Nru a/drivers/net/starfire.c b/drivers/net/starfire.c --- a/drivers/net/starfire.c Sun Mar 14 14:20:06 2004 +++ b/drivers/net/starfire.c Sun Mar 14 14:20:06 2004 @@ -1637,10 +1637,13 @@ && (skb = dev_alloc_skb(pkt_len + 2)) != NULL) { skb->dev = dev; skb_reserve(skb, 2); /* 16 byte align the IP header */ - pci_dma_sync_single(np->pci_dev, - np->rx_info[entry].mapping, - pkt_len, PCI_DMA_FROMDEVICE); + pci_dma_sync_single_for_cpu(np->pci_dev, + np->rx_info[entry].mapping, + pkt_len, PCI_DMA_FROMDEVICE); eth_copy_and_sum(skb, np->rx_info[entry].skb->tail, pkt_len, 0); + pci_dma_sync_single_for_device(np->pci_dev, + np->rx_info[entry].mapping, + pkt_len, PCI_DMA_FROMDEVICE); skb_put(skb, pkt_len); } else { pci_unmap_single(np->pci_dev, np->rx_info[entry].mapping, np->rx_buf_sz, PCI_DMA_FROMDEVICE); diff -Nru a/drivers/net/stnic.c b/drivers/net/stnic.c --- a/drivers/net/stnic.c Sun Mar 14 14:20:07 2004 +++ b/drivers/net/stnic.c Sun Mar 14 14:20:07 2004 @@ -124,6 +124,9 @@ dev->irq = IRQ_STNIC; dev->open = &stnic_open; dev->stop = &stnic_close; +#ifdef CONFIG_NET_POLL_CONTROLLER + dev->poll_controller = ei_poll; +#endif /* Snarf the interrupt now. There's no point in waiting since we cannot share and the board will usually be enabled. */ diff -Nru a/drivers/net/sun3lance.c b/drivers/net/sun3lance.c --- a/drivers/net/sun3lance.c Sun Mar 14 14:20:08 2004 +++ b/drivers/net/sun3lance.c Sun Mar 14 14:20:08 2004 @@ -332,7 +332,7 @@ return 0; } - lp = (struct lance_private *)dev->priv; + lp = netdev_priv(dev); /* XXX - leak? */ MEM = dvma_malloc_align(sizeof(struct lance_memory), 0x10000); @@ -402,7 +402,7 @@ static int lance_open( struct net_device *dev ) { - struct lance_private *lp = (struct lance_private *)dev->priv; + struct lance_private *lp = netdev_priv(dev); int i; DPRINTK( 2, ( "%s: lance_open()\n", dev->name )); @@ -439,7 +439,7 @@ static void lance_init_ring( struct net_device *dev ) { - struct lance_private *lp = (struct lance_private *)dev->priv; + struct lance_private *lp = netdev_priv(dev); int i; lp->lock = 0; @@ -499,7 +499,7 @@ static int lance_start_xmit( struct sk_buff *skb, struct net_device *dev ) { - struct lance_private *lp = (struct lance_private *)dev->priv; + struct lance_private *lp = netdev_priv(dev); int entry, len; struct lance_tx_head *head; unsigned long flags; @@ -646,7 +646,7 @@ static irqreturn_t lance_interrupt( int irq, void *dev_id, struct pt_regs *fp) { struct net_device *dev = dev_id; - struct lance_private *lp = dev->priv; + struct lance_private *lp = netdev_priv(dev); int csr0; static int in_interrupt; @@ -772,7 +772,7 @@ /* get packet, toss into skbuff */ static int lance_rx( struct net_device *dev ) { - struct lance_private *lp = (struct lance_private *)dev->priv; + struct lance_private *lp = netdev_priv(dev); int entry = lp->new_rx; /* If we own the next entry, it's a new packet. Send it up. */ @@ -870,7 +870,7 @@ static int lance_close( struct net_device *dev ) { - struct lance_private *lp = (struct lance_private *)dev->priv; + struct lance_private *lp = netdev_priv(dev); netif_stop_queue(dev); @@ -888,7 +888,7 @@ static struct net_device_stats *lance_get_stats( struct net_device *dev ) { - struct lance_private *lp = (struct lance_private *)dev->priv; + struct lance_private *lp = netdev_priv(dev); return &lp->stats; } @@ -904,7 +904,7 @@ /* completely untested on a sun3 */ static void set_multicast_list( struct net_device *dev ) { - struct lance_private *lp = (struct lance_private *)dev->priv; + struct lance_private *lp = netdev_priv(dev); if(netif_queue_stopped(dev)) /* Only possible if board is already started */ diff -Nru a/drivers/net/sunbmac.c b/drivers/net/sunbmac.c --- a/drivers/net/sunbmac.c Sun Mar 14 14:20:07 2004 +++ b/drivers/net/sunbmac.c Sun Mar 14 14:20:07 2004 @@ -849,9 +849,13 @@ copy_skb->dev = bp->dev; skb_reserve(copy_skb, 2); skb_put(copy_skb, len); - sbus_dma_sync_single(bp->bigmac_sdev, - this->rx_addr, len, SBUS_DMA_FROMDEVICE); + sbus_dma_sync_single_for_cpu(bp->bigmac_sdev, + this->rx_addr, len, + SBUS_DMA_FROMDEVICE); eth_copy_and_sum(copy_skb, (unsigned char *)skb->data, len, 0); + sbus_dma_sync_single_for_device(bp->bigmac_sdev, + this->rx_addr, len, + SBUS_DMA_FROMDEVICE); /* Reuse original ring buffer. */ this->rx_flags = diff -Nru a/drivers/net/sundance.c b/drivers/net/sundance.c --- a/drivers/net/sundance.c Sun Mar 14 14:20:07 2004 +++ b/drivers/net/sundance.c Sun Mar 14 14:20:07 2004 @@ -1331,9 +1331,6 @@ if (netif_msg_rx_status(np)) printk(KERN_DEBUG " netdev_rx() status was %8.8x.\n", frame_status); - pci_dma_sync_single(np->pci_dev, desc->frag[0].addr, - np->rx_buf_sz, PCI_DMA_FROMDEVICE); - if (frame_status & 0x001f4000) { /* There was a error. */ if (netif_msg_rx_err(np)) @@ -1363,7 +1360,16 @@ && (skb = dev_alloc_skb(pkt_len + 2)) != NULL) { skb->dev = dev; skb_reserve(skb, 2); /* 16 byte align the IP header */ + pci_dma_sync_single_for_cpu(np->pci_dev, + desc->frag[0].addr, + np->rx_buf_sz, + PCI_DMA_FROMDEVICE); + eth_copy_and_sum(skb, np->rx_skbuff[entry]->tail, pkt_len, 0); + pci_dma_sync_single_for_device(np->pci_dev, + desc->frag[0].addr, + np->rx_buf_sz, + PCI_DMA_FROMDEVICE); skb_put(skb, pkt_len); } else { pci_unmap_single(np->pci_dev, diff -Nru a/drivers/net/sungem.c b/drivers/net/sungem.c --- a/drivers/net/sungem.c Sun Mar 14 14:20:08 2004 +++ b/drivers/net/sungem.c Sun Mar 14 14:20:08 2004 @@ -763,8 +763,9 @@ copy_skb->dev = gp->dev; skb_reserve(copy_skb, 2); skb_put(copy_skb, len); - pci_dma_sync_single(gp->pdev, dma_addr, len, PCI_DMA_FROMDEVICE); + pci_dma_sync_single_for_cpu(gp->pdev, dma_addr, len, PCI_DMA_FROMDEVICE); memcpy(copy_skb->data, skb->data, len); + pci_dma_sync_single_for_device(gp->pdev, dma_addr, len, PCI_DMA_FROMDEVICE); /* We'll reuse the original ring buffer. */ skb = copy_skb; diff -Nru a/drivers/net/sunhme.c b/drivers/net/sunhme.c --- a/drivers/net/sunhme.c Sun Mar 14 14:20:06 2004 +++ b/drivers/net/sunhme.c Sun Mar 14 14:20:06 2004 @@ -273,8 +273,10 @@ ((__hp)->dma_map((__hp)->happy_dev, (__ptr), (__size), (__dir))) #define hme_dma_unmap(__hp, __addr, __size, __dir) \ ((__hp)->dma_unmap((__hp)->happy_dev, (__addr), (__size), (__dir))) -#define hme_dma_sync(__hp, __addr, __size, __dir) \ - ((__hp)->dma_sync((__hp)->happy_dev, (__addr), (__size), (__dir))) +#define hme_dma_sync_for_cpu(__hp, __addr, __size, __dir) \ + ((__hp)->dma_sync_for_cpu((__hp)->happy_dev, (__addr), (__size), (__dir))) +#define hme_dma_sync_for_device(__hp, __addr, __size, __dir) \ + ((__hp)->dma_sync_for_device((__hp)->happy_dev, (__addr), (__size), (__dir))) #else #ifdef CONFIG_SBUS /* SBUS only compilation */ @@ -297,8 +299,10 @@ sbus_map_single((__hp)->happy_dev, (__ptr), (__size), (__dir)) #define hme_dma_unmap(__hp, __addr, __size, __dir) \ sbus_unmap_single((__hp)->happy_dev, (__addr), (__size), (__dir)) -#define hme_dma_sync(__hp, __addr, __size, __dir) \ - sbus_dma_sync_single((__hp)->happy_dev, (__addr), (__size), (__dir)) +#define hme_dma_sync_for_cpu(__hp, __addr, __size, __dir) \ + sbus_dma_sync_single_for_cpu((__hp)->happy_dev, (__addr), (__size), (__dir)) +#define hme_dma_sync_for_device(__hp, __addr, __size, __dir) \ + sbus_dma_sync_single_for_device((__hp)->happy_dev, (__addr), (__size), (__dir)) #else /* PCI only compilation */ #define hme_write32(__hp, __reg, __val) \ @@ -320,8 +324,10 @@ pci_map_single((__hp)->happy_dev, (__ptr), (__size), (__dir)) #define hme_dma_unmap(__hp, __addr, __size, __dir) \ pci_unmap_single((__hp)->happy_dev, (__addr), (__size), (__dir)) -#define hme_dma_sync(__hp, __addr, __size, __dir) \ - pci_dma_sync_single((__hp)->happy_dev, (__addr), (__size), (__dir)) +#define hme_dma_sync_for_cpu(__hp, __addr, __size, __dir) \ + pci_dma_sync_single_for_cpu((__hp)->happy_dev, (__addr), (__size), (__dir)) +#define hme_dma_sync_for_device(__hp, __addr, __size, __dir) \ + pci_dma_sync_single_for_device((__hp)->happy_dev, (__addr), (__size), (__dir)) #endif #endif @@ -2069,8 +2075,9 @@ copy_skb->dev = dev; skb_reserve(copy_skb, 2); skb_put(copy_skb, len); - hme_dma_sync(hp, dma_addr, len, DMA_FROMDEVICE); + hme_dma_sync_for_cpu(hp, dma_addr, len, DMA_FROMDEVICE); memcpy(copy_skb->data, skb->data, len); + hme_dma_sync_for_device(hp, dma_addr, len, DMA_FROMDEVICE); /* Reuse original ring buffer. */ hme_write_rxd(hp, this, @@ -2838,7 +2845,10 @@ hp->write_rxd = sbus_hme_write_rxd; hp->dma_map = (u32 (*)(void *, void *, long, int))sbus_map_single; hp->dma_unmap = (void (*)(void *, u32, long, int))sbus_unmap_single; - hp->dma_sync = (void (*)(void *, u32, long, int))sbus_dma_sync_single; + hp->dma_sync_for_cpu = (void (*)(void *, u32, long, int)) + sbus_dma_sync_single_for_cpu; + hp->dma_sync_for_device = (void (*)(void *, u32, long, int)) + sbus_dma_sync_single_for_device; hp->read32 = sbus_hme_read32; hp->write32 = sbus_hme_write32; #endif @@ -3182,7 +3192,10 @@ hp->write_rxd = pci_hme_write_rxd; hp->dma_map = (u32 (*)(void *, void *, long, int))pci_map_single; hp->dma_unmap = (void (*)(void *, u32, long, int))pci_unmap_single; - hp->dma_sync = (void (*)(void *, u32, long, int))pci_dma_sync_single; + hp->dma_sync_for_cpu = (void (*)(void *, u32, long, int)) + pci_dma_sync_single_for_cpu; + hp->dma_sync_for_device = (void (*)(void *, u32, long, int)) + pci_dma_sync_single_for_device; hp->read32 = pci_hme_read32; hp->write32 = pci_hme_write32; #endif diff -Nru a/drivers/net/sunhme.h b/drivers/net/sunhme.h --- a/drivers/net/sunhme.h Sun Mar 14 14:20:07 2004 +++ b/drivers/net/sunhme.h Sun Mar 14 14:20:07 2004 @@ -406,7 +406,8 @@ void (*write_rxd)(struct happy_meal_rxd *, u32, u32); u32 (*dma_map)(void *, void *, long, int); void (*dma_unmap)(void *, u32, long, int); - void (*dma_sync)(void *, u32, long, int); + void (*dma_sync_for_cpu)(void *, u32, long, int); + void (*dma_sync_for_device)(void *, u32, long, int); #endif /* This is either a sbus_dev or a pci_dev. */ diff -Nru a/drivers/net/sunlance.c b/drivers/net/sunlance.c --- a/drivers/net/sunlance.c Sun Mar 14 14:20:06 2004 +++ b/drivers/net/sunlance.c Sun Mar 14 14:20:06 2004 @@ -313,7 +313,7 @@ /* Setup the Lance Rx and Tx rings */ static void lance_init_ring_dvma(struct net_device *dev) { - struct lance_private *lp = (struct lance_private *) dev->priv; + struct lance_private *lp = netdev_priv(dev); volatile struct lance_init_block *ib = lp->init_block; dma_addr_t aib = lp->init_block_dvma; __u32 leptr; @@ -370,7 +370,7 @@ static void lance_init_ring_pio(struct net_device *dev) { - struct lance_private *lp = (struct lance_private *) dev->priv; + struct lance_private *lp = netdev_priv(dev); volatile struct lance_init_block *ib = lp->init_block; u32 leptr; int i; @@ -500,7 +500,7 @@ static void lance_rx_dvma(struct net_device *dev) { - struct lance_private *lp = (struct lance_private *) dev->priv; + struct lance_private *lp = netdev_priv(dev); volatile struct lance_init_block *ib = lp->init_block; volatile struct lance_rx_desc *rd; u8 bits; @@ -563,7 +563,7 @@ static void lance_tx_dvma(struct net_device *dev) { - struct lance_private *lp = (struct lance_private *) dev->priv; + struct lance_private *lp = netdev_priv(dev); volatile struct lance_init_block *ib = lp->init_block; int i, j; @@ -673,7 +673,7 @@ static void lance_rx_pio(struct net_device *dev) { - struct lance_private *lp = (struct lance_private *) dev->priv; + struct lance_private *lp = netdev_priv(dev); volatile struct lance_init_block *ib = lp->init_block; volatile struct lance_rx_desc *rd; unsigned char bits; @@ -735,7 +735,7 @@ static void lance_tx_pio(struct net_device *dev) { - struct lance_private *lp = (struct lance_private *) dev->priv; + struct lance_private *lp = netdev_priv(dev); volatile struct lance_init_block *ib = lp->init_block; int i, j; @@ -816,7 +816,7 @@ static irqreturn_t lance_interrupt(int irq, void *dev_id, struct pt_regs *regs) { struct net_device *dev = (struct net_device *)dev_id; - struct lance_private *lp = (struct lance_private *)dev->priv; + struct lance_private *lp = netdev_priv(dev); int csr0; sbus_writew(LE_CSR0, lp->lregs + RAP); @@ -915,7 +915,7 @@ static int lance_open(struct net_device *dev) { - struct lance_private *lp = (struct lance_private *)dev->priv; + struct lance_private *lp = netdev_priv(dev); volatile struct lance_init_block *ib = lp->init_block; int status = 0; @@ -968,7 +968,7 @@ static int lance_close(struct net_device *dev) { - struct lance_private *lp = (struct lance_private *) dev->priv; + struct lance_private *lp = netdev_priv(dev); netif_stop_queue(dev); del_timer_sync(&lp->multicast_timer); @@ -981,7 +981,7 @@ static int lance_reset(struct net_device *dev) { - struct lance_private *lp = (struct lance_private *) dev->priv; + struct lance_private *lp = netdev_priv(dev); int status; STOP_LANCE(lp); @@ -1102,7 +1102,7 @@ static void lance_tx_timeout(struct net_device *dev) { - struct lance_private *lp = (struct lance_private *) dev->priv; + struct lance_private *lp = netdev_priv(dev); printk(KERN_ERR "%s: transmit timed out, status %04x, reset\n", dev->name, sbus_readw(lp->lregs + RDP)); @@ -1112,7 +1112,7 @@ static int lance_start_xmit(struct sk_buff *skb, struct net_device *dev) { - struct lance_private *lp = (struct lance_private *) dev->priv; + struct lance_private *lp = netdev_priv(dev); volatile struct lance_init_block *ib = lp->init_block; int entry, skblen, len; @@ -1165,7 +1165,7 @@ static struct net_device_stats *lance_get_stats(struct net_device *dev) { - struct lance_private *lp = (struct lance_private *) dev->priv; + struct lance_private *lp = netdev_priv(dev); return &lp->stats; } @@ -1173,7 +1173,7 @@ /* taken from the depca driver */ static void lance_load_multicast(struct net_device *dev) { - struct lance_private *lp = (struct lance_private *) dev->priv; + struct lance_private *lp = netdev_priv(dev); volatile struct lance_init_block *ib = lp->init_block; volatile u16 *mcast_table = (u16 *) &ib->filter; struct dev_mc_list *dmi = dev->mc_list; @@ -1223,7 +1223,7 @@ static void lance_set_multicast(struct net_device *dev) { - struct lance_private *lp = (struct lance_private *) dev->priv; + struct lance_private *lp = netdev_priv(dev); volatile struct lance_init_block *ib = lp->init_block; u16 mode; @@ -1291,7 +1291,7 @@ /* Ethtool support... */ static void sparc_lance_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info) { - struct lance_private *lp = dev->priv; + struct lance_private *lp = netdev_priv(dev); strcpy(info->driver, "sunlance"); strcpy(info->version, "2.02"); @@ -1325,7 +1325,7 @@ if (!dev) return -ENOMEM; - lp = dev->priv; + lp = netdev_priv(dev); if (sparc_lance_debug && version_printed++ == 0) printk (KERN_INFO "%s", version); diff -Nru a/drivers/net/tg3.c b/drivers/net/tg3.c --- a/drivers/net/tg3.c Sun Mar 14 14:20:07 2004 +++ b/drivers/net/tg3.c Sun Mar 14 14:20:07 2004 @@ -2280,8 +2280,9 @@ copy_skb->dev = tp->dev; skb_reserve(copy_skb, 2); skb_put(copy_skb, len); - pci_dma_sync_single(tp->pdev, dma_addr, len, PCI_DMA_FROMDEVICE); + pci_dma_sync_single_for_cpu(tp->pdev, dma_addr, len, PCI_DMA_FROMDEVICE); memcpy(copy_skb->data, skb->data, len); + pci_dma_sync_single_for_device(tp->pdev, dma_addr, len, PCI_DMA_FROMDEVICE); /* We'll reuse the original ring buffer. */ skb = copy_skb; @@ -2466,6 +2467,13 @@ static int tg3_init_hw(struct tg3 *); static int tg3_halt(struct tg3 *); +#ifdef CONFIG_NET_POLL_CONTROLLER +static void tg3_poll_controller(struct net_device *dev) +{ + tg3_interrupt(dev->irq, dev, NULL); +} +#endif + static void tg3_reset_task(void *_data) { struct tg3 *tp = _data; @@ -7614,6 +7622,9 @@ dev->watchdog_timeo = TG3_TX_TIMEOUT; dev->change_mtu = tg3_change_mtu; dev->irq = pdev->irq; +#ifdef CONFIG_NET_POLL_CONTROLLER + dev->poll_controller = tg3_poll_controller; +#endif err = tg3_get_invariants(tp); if (err) { diff -Nru a/drivers/net/tlan.c b/drivers/net/tlan.c --- a/drivers/net/tlan.c Sun Mar 14 14:20:06 2004 +++ b/drivers/net/tlan.c Sun Mar 14 14:20:06 2004 @@ -814,6 +814,14 @@ } /* TLan_EisaProbe */ +#ifdef CONFIG_NET_POLL_CONTROLLER +static void TLan_Poll(struct net_device *dev) +{ + disable_irq(dev->irq); + TLan_HandleInterrupt(dev->irq, dev, NULL); + enable_irq(dev->irq); +} +#endif @@ -893,6 +901,9 @@ dev->get_stats = &TLan_GetStats; dev->set_multicast_list = &TLan_SetMulticastList; dev->do_ioctl = &TLan_ioctl; +#ifdef CONFIG_NET_POLL_CONTROLLER + dev->poll_controller = &TLan_Poll; +#endif dev->tx_timeout = &TLan_tx_timeout; dev->watchdog_timeo = TX_TIMEOUT; diff -Nru a/drivers/net/tokenring/3c359.c b/drivers/net/tokenring/3c359.c --- a/drivers/net/tokenring/3c359.c Sun Mar 14 14:20:08 2004 +++ b/drivers/net/tokenring/3c359.c Sun Mar 14 14:20:08 2004 @@ -937,15 +937,17 @@ while (xl_priv->rx_ring_tail != temp_ring_loc) { copy_len = xl_priv->xl_rx_ring[xl_priv->rx_ring_tail].upfraglen & 0x7FFF ; frame_length -= copy_len ; - pci_dma_sync_single(xl_priv->pdev,xl_priv->xl_rx_ring[xl_priv->rx_ring_tail].upfragaddr,xl_priv->pkt_buf_sz,PCI_DMA_FROMDEVICE) ; + pci_dma_sync_single_for_cpu(xl_priv->pdev,xl_priv->xl_rx_ring[xl_priv->rx_ring_tail].upfragaddr,xl_priv->pkt_buf_sz,PCI_DMA_FROMDEVICE) ; memcpy(skb_put(skb,copy_len), xl_priv->rx_ring_skb[xl_priv->rx_ring_tail]->data, copy_len) ; + pci_dma_sync_single_for_device(xl_priv->pdev,xl_priv->xl_rx_ring[xl_priv->rx_ring_tail].upfragaddr,xl_priv->pkt_buf_sz,PCI_DMA_FROMDEVICE) ; adv_rx_ring(dev) ; } /* Now we have found the last fragment */ - pci_dma_sync_single(xl_priv->pdev,xl_priv->xl_rx_ring[xl_priv->rx_ring_tail].upfragaddr,xl_priv->pkt_buf_sz,PCI_DMA_FROMDEVICE) ; + pci_dma_sync_single_for_cpu(xl_priv->pdev,xl_priv->xl_rx_ring[xl_priv->rx_ring_tail].upfragaddr,xl_priv->pkt_buf_sz,PCI_DMA_FROMDEVICE) ; memcpy(skb_put(skb,copy_len), xl_priv->rx_ring_skb[xl_priv->rx_ring_tail]->data, frame_length) ; /* memcpy(skb_put(skb,frame_length), bus_to_virt(xl_priv->xl_rx_ring[xl_priv->rx_ring_tail].upfragaddr), frame_length) ; */ + pci_dma_sync_single_for_device(xl_priv->pdev,xl_priv->xl_rx_ring[xl_priv->rx_ring_tail].upfragaddr,xl_priv->pkt_buf_sz,PCI_DMA_FROMDEVICE) ; adv_rx_ring(dev) ; skb->protocol = tr_type_trans(skb,dev) ; netif_rx(skb) ; diff -Nru a/drivers/net/tokenring/abyss.c b/drivers/net/tokenring/abyss.c --- a/drivers/net/tokenring/abyss.c Sun Mar 14 14:20:06 2004 +++ b/drivers/net/tokenring/abyss.c Sun Mar 14 14:20:06 2004 @@ -154,7 +154,7 @@ printk(":%2.2x", dev->dev_addr[i]); printk("\n"); - tp = dev->priv; + tp = netdev_priv(dev); tp->setnselout = abyss_setnselout_pins; tp->sifreadb = abyss_sifreadb; tp->sifreadw = abyss_sifreadw; @@ -188,7 +188,7 @@ static unsigned short abyss_setnselout_pins(struct net_device *dev) { unsigned short val = 0; - struct net_local *tp = (struct net_local *)dev->priv; + struct net_local *tp = netdev_priv(dev); if(tp->DataRate == SPEED_4) val |= 0x01; /* Set 4Mbps */ @@ -398,7 +398,7 @@ unsigned short val; int i; - tp = (struct net_local *)dev->priv; + tp = netdev_priv(dev); ioaddr = dev->base_addr; /* Must enable glue chip first */ diff -Nru a/drivers/net/tokenring/madgemc.c b/drivers/net/tokenring/madgemc.c --- a/drivers/net/tokenring/madgemc.c Sun Mar 14 14:20:08 2004 +++ b/drivers/net/tokenring/madgemc.c Sun Mar 14 14:20:08 2004 @@ -365,7 +365,7 @@ return 0; return -1; } - tp = (struct net_local *)dev->priv; + tp = netdev_priv(dev); /* * The MC16 is physically a 32bit card. However, Madge @@ -504,7 +504,7 @@ unsigned short madgemc_setnselout_pins(struct net_device *dev) { unsigned char reg1; - struct net_local *tp = (struct net_local *)dev->priv; + struct net_local *tp = netdev_priv(dev); reg1 = inb(dev->base_addr + MC_CONTROL_REG1); @@ -731,7 +731,7 @@ } len += sprintf(buf+len, "-------\n"); if (curcard) { - struct net_local *tp = (struct net_local *)dev->priv; + struct net_local *tp = netdev_priv(dev); int i; len += sprintf(buf+len, "Card Revision: %d\n", curcard->cardrev); diff -Nru a/drivers/net/tokenring/olympic.c b/drivers/net/tokenring/olympic.c --- a/drivers/net/tokenring/olympic.c Sun Mar 14 14:20:08 2004 +++ b/drivers/net/tokenring/olympic.c Sun Mar 14 14:20:08 2004 @@ -842,10 +842,13 @@ olympic_priv->rx_ring_skb[rx_ring_last_received] = skb ; netif_rx(skb2) ; } else { - pci_dma_sync_single(olympic_priv->pdev, + pci_dma_sync_single_for_cpu(olympic_priv->pdev, le32_to_cpu(olympic_priv->olympic_rx_ring[rx_ring_last_received].buffer), olympic_priv->pkt_buf_sz,PCI_DMA_FROMDEVICE) ; memcpy(skb_put(skb,length-4),olympic_priv->rx_ring_skb[rx_ring_last_received]->data,length-4) ; + pci_dma_sync_single_for_device(olympic_priv->pdev, + le32_to_cpu(olympic_priv->olympic_rx_ring[rx_ring_last_received].buffer), + olympic_priv->pkt_buf_sz,PCI_DMA_FROMDEVICE) ; skb->protocol = tr_type_trans(skb,dev) ; netif_rx(skb) ; } @@ -854,12 +857,15 @@ olympic_priv->rx_ring_last_received++ ; olympic_priv->rx_ring_last_received &= (OLYMPIC_RX_RING_SIZE -1); rx_ring_last_received = olympic_priv->rx_ring_last_received ; - pci_dma_sync_single(olympic_priv->pdev, + pci_dma_sync_single_for_cpu(olympic_priv->pdev, le32_to_cpu(olympic_priv->olympic_rx_ring[rx_ring_last_received].buffer), olympic_priv->pkt_buf_sz,PCI_DMA_FROMDEVICE) ; rx_desc = &(olympic_priv->olympic_rx_ring[rx_ring_last_received]); cpy_length = (i == 1 ? frag_len : le32_to_cpu(rx_desc->res_length)); memcpy(skb_put(skb, cpy_length), olympic_priv->rx_ring_skb[rx_ring_last_received]->data, cpy_length) ; + pci_dma_sync_single_for_device(olympic_priv->pdev, + le32_to_cpu(olympic_priv->olympic_rx_ring[rx_ring_last_received].buffer), + olympic_priv->pkt_buf_sz,PCI_DMA_FROMDEVICE) ; } while (--i) ; skb_trim(skb,skb->len-4) ; skb->protocol = tr_type_trans(skb,dev); diff -Nru a/drivers/net/tokenring/proteon.c b/drivers/net/tokenring/proteon.c --- a/drivers/net/tokenring/proteon.c Sun Mar 14 14:20:08 2004 +++ b/drivers/net/tokenring/proteon.c Sun Mar 14 14:20:08 2004 @@ -158,7 +158,7 @@ printk(":%2.2x", dev->dev_addr[j]); printk("\n"); - tp = (struct net_local *)dev->priv; + tp = netdev_priv(dev); tp->setnselout = proteon_setnselout_pins; tp->sifreadb = proteon_sifreadb; @@ -316,7 +316,7 @@ static int proteon_open(struct net_device *dev) { - struct net_local *tp = (struct net_local *)dev->priv; + struct net_local *tp = netdev_priv(dev); unsigned short val = 0; int i; diff -Nru a/drivers/net/tokenring/skisa.c b/drivers/net/tokenring/skisa.c --- a/drivers/net/tokenring/skisa.c Sun Mar 14 14:20:06 2004 +++ b/drivers/net/tokenring/skisa.c Sun Mar 14 14:20:06 2004 @@ -175,7 +175,7 @@ printk(":%2.2x", dev->dev_addr[j]); printk("\n"); - tp = (struct net_local *)dev->priv; + tp = netdev_priv(dev); tp->setnselout = sk_isa_setnselout_pins; tp->sifreadb = sk_isa_sifreadb; @@ -332,7 +332,7 @@ static int sk_isa_open(struct net_device *dev) { - struct net_local *tp = (struct net_local *)dev->priv; + struct net_local *tp = netdev_priv(dev); unsigned short val = 0; unsigned short oldval; int i; diff -Nru a/drivers/net/tokenring/smctr.c b/drivers/net/tokenring/smctr.c --- a/drivers/net/tokenring/smctr.c Sun Mar 14 14:20:07 2004 +++ b/drivers/net/tokenring/smctr.c Sun Mar 14 14:20:07 2004 @@ -327,7 +327,7 @@ */ static int smctr_alloc_shared_memory(struct net_device *dev) { - struct net_local *tp = (struct net_local *)dev->priv; + struct net_local *tp = netdev_priv(dev); if(smctr_debug > 10) printk(KERN_DEBUG "%s: smctr_alloc_shared_memory\n", dev->name); @@ -454,7 +454,7 @@ static int smctr_checksum_firmware(struct net_device *dev) { - struct net_local *tp = (struct net_local *)dev->priv; + struct net_local *tp = netdev_priv(dev); __u16 i, checksum = 0; if(smctr_debug > 10) @@ -477,10 +477,10 @@ return (0); } -static int smctr_chk_mca(struct net_device *dev) +static int __init smctr_chk_mca(struct net_device *dev) { #ifdef CONFIG_MCA - struct net_local *tp = (struct net_local *)dev->priv; + struct net_local *tp = netdev_priv(dev); int current_slot; __u8 r1, r2, r3, r4, r5; @@ -631,7 +631,7 @@ static int smctr_chg_rx_mask(struct net_device *dev) { - struct net_local *tp = (struct net_local *)dev->priv; + struct net_local *tp = netdev_priv(dev); int err = 0; if(smctr_debug > 10) @@ -694,7 +694,7 @@ static int smctr_clear_int(struct net_device *dev) { - struct net_local *tp = (struct net_local *)dev->priv; + struct net_local *tp = netdev_priv(dev); outb((tp->trc_mask | CSR_CLRTINT), dev->base_addr + CSR); @@ -716,7 +716,7 @@ */ static int smctr_close(struct net_device *dev) { - struct net_local *tp = (struct net_local *)dev->priv; + struct net_local *tp = netdev_priv(dev); struct sk_buff *skb; int err; @@ -752,7 +752,7 @@ static int smctr_decode_firmware(struct net_device *dev) { - struct net_local *tp = (struct net_local *)dev->priv; + struct net_local *tp = netdev_priv(dev); short bit = 0x80, shift = 12; DECODE_TREE_NODE *tree; short branch, tsize; @@ -823,7 +823,7 @@ */ static int smctr_disable_adapter_ctrl_store(struct net_device *dev) { - struct net_local *tp = (struct net_local *)dev->priv; + struct net_local *tp = netdev_priv(dev); int ioaddr = dev->base_addr; if(smctr_debug > 10) @@ -837,7 +837,7 @@ static int smctr_disable_bic_int(struct net_device *dev) { - struct net_local *tp = (struct net_local *)dev->priv; + struct net_local *tp = netdev_priv(dev); int ioaddr = dev->base_addr; tp->trc_mask = CSR_MSK_ALL | CSR_MSKCBUSY @@ -849,7 +849,7 @@ static int smctr_enable_16bit(struct net_device *dev) { - struct net_local *tp = (struct net_local *)dev->priv; + struct net_local *tp = netdev_priv(dev); __u8 r; if(tp->adapter_bus == BUS_ISA16_TYPE) @@ -869,7 +869,7 @@ */ static int smctr_enable_adapter_ctrl_store(struct net_device *dev) { - struct net_local *tp = (struct net_local *)dev->priv; + struct net_local *tp = netdev_priv(dev); int ioaddr = dev->base_addr; if(smctr_debug > 10) @@ -900,7 +900,7 @@ static int smctr_enable_bic_int(struct net_device *dev) { - struct net_local *tp = (struct net_local *)dev->priv; + struct net_local *tp = netdev_priv(dev); int ioaddr = dev->base_addr; __u8 r; @@ -926,7 +926,7 @@ static int __init smctr_chk_isa(struct net_device *dev) { - struct net_local *tp = (struct net_local *)dev->priv; + struct net_local *tp = netdev_priv(dev); int ioaddr = dev->base_addr; __u8 r1, r2, b, chksum = 0; __u16 r; @@ -1155,7 +1155,7 @@ static int __init smctr_get_boardid(struct net_device *dev, int mca) { - struct net_local *tp = (struct net_local *)dev->priv; + struct net_local *tp = netdev_priv(dev); int ioaddr = dev->base_addr; __u8 r, r1, IdByte; __u16 BoardIdMask; @@ -1273,7 +1273,7 @@ */ static unsigned int smctr_get_num_rx_bdbs(struct net_device *dev) { - struct net_local *tp = (struct net_local *)dev->priv; + struct net_local *tp = netdev_priv(dev); unsigned int mem_used = 0; /* Allocate System Control Blocks. */ @@ -1358,7 +1358,7 @@ static __u8 * smctr_get_rx_pointer(struct net_device *dev, short queue) { - struct net_local *tp = (struct net_local *)dev->priv; + struct net_local *tp = netdev_priv(dev); BDBlock *bdb; bdb = (BDBlock *)((__u32)tp->ram_access @@ -1382,7 +1382,7 @@ */ static struct net_device_stats *smctr_get_stats(struct net_device *dev) { - struct net_local *tp = (struct net_local *)dev->priv; + struct net_local *tp = netdev_priv(dev); return ((struct net_device_stats *)&tp->MacStat); } @@ -1390,7 +1390,7 @@ static FCBlock *smctr_get_tx_fcb(struct net_device *dev, __u16 queue, __u16 bytes_count) { - struct net_local *tp = (struct net_local *)dev->priv; + struct net_local *tp = netdev_priv(dev); FCBlock *pFCB; BDBlock *pbdb; unsigned short alloc_size; @@ -1513,7 +1513,7 @@ static int smctr_init_acbs(struct net_device *dev) { - struct net_local *tp = (struct net_local *)dev->priv; + struct net_local *tp = netdev_priv(dev); unsigned int i; ACBlock *acb; @@ -1557,7 +1557,7 @@ static int smctr_init_adapter(struct net_device *dev) { - struct net_local *tp = (struct net_local *)dev->priv; + struct net_local *tp = netdev_priv(dev); int err; if(smctr_debug > 10) @@ -1640,7 +1640,7 @@ static int smctr_init_card_real(struct net_device *dev) { - struct net_local *tp = (struct net_local *)dev->priv; + struct net_local *tp = netdev_priv(dev); int err = 0; if(smctr_debug > 10) @@ -1716,7 +1716,7 @@ static int smctr_init_rx_bdbs(struct net_device *dev) { - struct net_local *tp = (struct net_local *)dev->priv; + struct net_local *tp = netdev_priv(dev); unsigned int i, j; BDBlock *bdb; __u16 *buf; @@ -1768,7 +1768,7 @@ static int smctr_init_rx_fcbs(struct net_device *dev) { - struct net_local *tp = (struct net_local *)dev->priv; + struct net_local *tp = netdev_priv(dev); unsigned int i, j; FCBlock *fcb; @@ -1818,7 +1818,7 @@ static int smctr_init_shared_memory(struct net_device *dev) { - struct net_local *tp = (struct net_local *)dev->priv; + struct net_local *tp = netdev_priv(dev); unsigned int i; __u32 *iscpb; @@ -1876,7 +1876,7 @@ static int smctr_init_tx_bdbs(struct net_device *dev) { - struct net_local *tp = (struct net_local *)dev->priv; + struct net_local *tp = netdev_priv(dev); unsigned int i, j; BDBlock *bdb; @@ -1906,7 +1906,7 @@ static int smctr_init_tx_fcbs(struct net_device *dev) { - struct net_local *tp = (struct net_local *)dev->priv; + struct net_local *tp = netdev_priv(dev); unsigned int i, j; FCBlock *fcb; @@ -1945,7 +1945,7 @@ static int smctr_internal_self_test(struct net_device *dev) { - struct net_local *tp = (struct net_local *)dev->priv; + struct net_local *tp = netdev_priv(dev); int err; if((err = smctr_issue_test_internal_rom_cmd(dev))) @@ -1998,7 +1998,7 @@ } ioaddr = dev->base_addr; - tp = (struct net_local *)dev->priv; + tp = netdev_priv(dev); if(tp->status == NOT_INITIALIZED) @@ -2471,7 +2471,7 @@ static int smctr_issue_enable_int_cmd(struct net_device *dev, __u16 interrupt_enable_mask) { - struct net_local *tp = (struct net_local *)dev->priv; + struct net_local *tp = netdev_priv(dev); int err; if((err = smctr_wait_while_cbusy(dev))) @@ -2487,7 +2487,7 @@ static int smctr_issue_int_ack(struct net_device *dev, __u16 iack_code, __u16 ibits) { - struct net_local *tp = (struct net_local *)dev->priv; + struct net_local *tp = netdev_priv(dev); if(smctr_wait_while_cbusy(dev)) return (-1); @@ -2503,7 +2503,7 @@ static int smctr_issue_init_timers_cmd(struct net_device *dev) { - struct net_local *tp = (struct net_local *)dev->priv; + struct net_local *tp = netdev_priv(dev); unsigned int i; int err; __u16 *pTimer_Struc = (__u16 *)tp->misc_command_data; @@ -2660,7 +2660,7 @@ static int smctr_issue_init_txrx_cmd(struct net_device *dev) { - struct net_local *tp = (struct net_local *)dev->priv; + struct net_local *tp = netdev_priv(dev); unsigned int i; int err; void **txrx_ptrs = (void *)tp->misc_command_data; @@ -2748,7 +2748,7 @@ static int smctr_issue_remove_cmd(struct net_device *dev) { - struct net_local *tp = (struct net_local *)dev->priv; + struct net_local *tp = netdev_priv(dev); int err; if((err = smctr_wait_while_cbusy(dev))) @@ -2764,7 +2764,7 @@ static int smctr_issue_resume_acb_cmd(struct net_device *dev) { - struct net_local *tp = (struct net_local *)dev->priv; + struct net_local *tp = netdev_priv(dev); int err; if((err = smctr_wait_while_cbusy(dev))) @@ -2782,7 +2782,7 @@ static int smctr_issue_resume_rx_bdb_cmd(struct net_device *dev, __u16 queue) { - struct net_local *tp = (struct net_local *)dev->priv; + struct net_local *tp = netdev_priv(dev); int err; if((err = smctr_wait_while_cbusy(dev))) @@ -2802,7 +2802,7 @@ static int smctr_issue_resume_rx_fcb_cmd(struct net_device *dev, __u16 queue) { - struct net_local *tp = (struct net_local *)dev->priv; + struct net_local *tp = netdev_priv(dev); if(smctr_debug > 10) printk(KERN_DEBUG "%s: smctr_issue_resume_rx_fcb_cmd\n", dev->name); @@ -2824,7 +2824,7 @@ static int smctr_issue_resume_tx_fcb_cmd(struct net_device *dev, __u16 queue) { - struct net_local *tp = (struct net_local *)dev->priv; + struct net_local *tp = netdev_priv(dev); if(smctr_debug > 10) printk(KERN_DEBUG "%s: smctr_issue_resume_tx_fcb_cmd\n", dev->name); @@ -2893,7 +2893,7 @@ static int smctr_issue_write_byte_cmd(struct net_device *dev, short aword_cnt, void *byte) { - struct net_local *tp = (struct net_local *)dev->priv; + struct net_local *tp = netdev_priv(dev); unsigned int iword, ibyte; int err; @@ -2917,7 +2917,7 @@ static int smctr_issue_write_word_cmd(struct net_device *dev, short aword_cnt, void *word) { - struct net_local *tp = (struct net_local *)dev->priv; + struct net_local *tp = netdev_priv(dev); unsigned int i, err; if((err = smctr_wait_while_cbusy(dev))) @@ -2947,7 +2947,7 @@ static int smctr_link_tx_fcbs_to_bdbs(struct net_device *dev) { - struct net_local *tp = (struct net_local *)dev->priv; + struct net_local *tp = netdev_priv(dev); unsigned int i, j; FCBlock *fcb; BDBlock *bdb; @@ -2971,7 +2971,7 @@ static int smctr_load_firmware(struct net_device *dev) { - struct net_local *tp = (struct net_local *)dev->priv; + struct net_local *tp = netdev_priv(dev); __u16 i, checksum = 0; int err = 0; @@ -3071,7 +3071,7 @@ */ static int smctr_lobe_media_test(struct net_device *dev) { - struct net_local *tp = (struct net_local *)dev->priv; + struct net_local *tp = netdev_priv(dev); unsigned int i, perror = 0; unsigned short saved_rcv_mask; @@ -3146,7 +3146,7 @@ static int smctr_lobe_media_test_cmd(struct net_device *dev) { - struct net_local *tp = (struct net_local *)dev->priv; + struct net_local *tp = netdev_priv(dev); int err; if(smctr_debug > 10) @@ -3230,7 +3230,7 @@ static int smctr_make_access_pri(struct net_device *dev, MAC_SUB_VECTOR *tsv) { - struct net_local *tp = (struct net_local *)dev->priv; + struct net_local *tp = netdev_priv(dev); tsv->svi = AUTHORIZED_ACCESS_PRIORITY; tsv->svl = S_AUTHORIZED_ACCESS_PRIORITY; @@ -3255,7 +3255,7 @@ static int smctr_make_auth_funct_class(struct net_device *dev, MAC_SUB_VECTOR *tsv) { - struct net_local *tp = (struct net_local *)dev->priv; + struct net_local *tp = netdev_priv(dev); tsv->svi = AUTHORIZED_FUNCTION_CLASS; tsv->svl = S_AUTHORIZED_FUNCTION_CLASS; @@ -3280,7 +3280,7 @@ static int smctr_make_funct_addr(struct net_device *dev, MAC_SUB_VECTOR *tsv) { - struct net_local *tp = (struct net_local *)dev->priv; + struct net_local *tp = netdev_priv(dev); smctr_get_functional_address(dev); @@ -3298,7 +3298,7 @@ static int smctr_make_group_addr(struct net_device *dev, MAC_SUB_VECTOR *tsv) { - struct net_local *tp = (struct net_local *)dev->priv; + struct net_local *tp = netdev_priv(dev); smctr_get_group_address(dev); @@ -3324,7 +3324,7 @@ static int smctr_make_phy_drop_num(struct net_device *dev, MAC_SUB_VECTOR *tsv) { - struct net_local *tp = (struct net_local *)dev->priv; + struct net_local *tp = netdev_priv(dev); smctr_get_physical_drop_number(dev); @@ -3355,7 +3355,7 @@ static int smctr_make_station_id(struct net_device *dev, MAC_SUB_VECTOR *tsv) { - struct net_local *tp = (struct net_local *)dev->priv; + struct net_local *tp = netdev_priv(dev); smctr_get_station_id(dev); @@ -3393,7 +3393,7 @@ static int smctr_make_ring_station_version(struct net_device *dev, MAC_SUB_VECTOR *tsv) { - struct net_local *tp = (struct net_local *)dev->priv; + struct net_local *tp = netdev_priv(dev); tsv->svi = RING_STATION_VERSION_NUMBER; tsv->svl = S_RING_STATION_VERSION_NUMBER; @@ -3433,7 +3433,7 @@ static int smctr_make_upstream_neighbor_addr(struct net_device *dev, MAC_SUB_VECTOR *tsv) { - struct net_local *tp = (struct net_local *)dev->priv; + struct net_local *tp = netdev_priv(dev); smctr_get_upstream_neighbor_addr(dev); @@ -3485,7 +3485,7 @@ /* Interrupt driven open of Token card. */ static int smctr_open_tr(struct net_device *dev) { - struct net_local *tp = (struct net_local *)dev->priv; + struct net_local *tp = netdev_priv(dev); unsigned long flags; int err; @@ -3618,7 +3618,7 @@ return dev; out1: #ifdef CONFIG_MCA - { struct net_local *tp = (struct net_local *)dev->priv; + { struct net_local *tp = netdev_priv(dev); if (tp->slot_num) mca_mark_as_unused(tp->slot_num); } @@ -3634,7 +3634,7 @@ static int __init smctr_probe1(struct net_device *dev, int ioaddr) { static unsigned version_printed; - struct net_local *tp = dev->priv; + struct net_local *tp = netdev_priv(dev); int err; __u32 *ram; @@ -3654,7 +3654,7 @@ } } - tp = (struct net_local *)dev->priv; + tp = netdev_priv(dev); dev->mem_start = tp->ram_base; dev->mem_end = dev->mem_start + 0x10000; ram = (__u32 *)phys_to_virt(dev->mem_start); @@ -3696,7 +3696,7 @@ static int smctr_process_rx_packet(MAC_HEADER *rmf, __u16 size, struct net_device *dev, __u16 rx_status) { - struct net_local *tp = (struct net_local *)dev->priv; + struct net_local *tp = netdev_priv(dev); struct sk_buff *skb; __u16 rcode, correlator; int err = 0; @@ -3917,7 +3917,7 @@ /* Adapter RAM test. Incremental word ODD boundary data test. */ static int smctr_ram_memory_test(struct net_device *dev) { - struct net_local *tp = (struct net_local *)dev->priv; + struct net_local *tp = netdev_priv(dev); __u16 page, pages_of_ram, start_pattern = 0, word_pattern = 0, word_read = 0, err_word = 0, err_pattern = 0; unsigned int err_offset; @@ -4310,7 +4310,7 @@ */ static int smctr_reset_adapter(struct net_device *dev) { - struct net_local *tp = (struct net_local *)dev->priv; + struct net_local *tp = netdev_priv(dev); int ioaddr = dev->base_addr; /* Reseting the NIC will put it in a halted and un-initialized state. */ smctr_set_trc_reset(ioaddr); @@ -4329,7 +4329,7 @@ static int smctr_restart_tx_chain(struct net_device *dev, short queue) { - struct net_local *tp = (struct net_local *)dev->priv; + struct net_local *tp = netdev_priv(dev); int err = 0; if(smctr_debug > 10) @@ -4347,7 +4347,7 @@ static int smctr_ring_status_chg(struct net_device *dev) { - struct net_local *tp = (struct net_local *)dev->priv; + struct net_local *tp = netdev_priv(dev); if(smctr_debug > 10) printk(KERN_DEBUG "%s: smctr_ring_status_chg\n", dev->name); @@ -4449,7 +4449,7 @@ static int smctr_rx_frame(struct net_device *dev) { - struct net_local *tp = (struct net_local *)dev->priv; + struct net_local *tp = netdev_priv(dev); __u16 queue, status, rx_size, err = 0; __u8 *pbuff; @@ -4516,7 +4516,7 @@ static int smctr_send_dat(struct net_device *dev) { - struct net_local *tp = (struct net_local *)dev->priv; + struct net_local *tp = netdev_priv(dev); unsigned int i, err; MAC_HEADER *tmf; FCBlock *fcb; @@ -4596,7 +4596,7 @@ */ static int smctr_send_packet(struct sk_buff *skb, struct net_device *dev) { - struct net_local *tp = (struct net_local *)dev->priv; + struct net_local *tp = netdev_priv(dev); if(smctr_debug > 10) printk(KERN_DEBUG "%s: smctr_send_packet\n", dev->name); @@ -4621,7 +4621,7 @@ static int smctr_send_lobe_media_test(struct net_device *dev) { - struct net_local *tp = (struct net_local *)dev->priv; + struct net_local *tp = netdev_priv(dev); MAC_SUB_VECTOR *tsv; MAC_HEADER *tmf; FCBlock *fcb; @@ -4917,7 +4917,7 @@ static int smctr_send_rq_init(struct net_device *dev) { - struct net_local *tp = (struct net_local *)dev->priv; + struct net_local *tp = netdev_priv(dev); MAC_HEADER *tmf; MAC_SUB_VECTOR *tsv; FCBlock *fcb; @@ -5001,7 +5001,7 @@ static int smctr_send_tx_forward(struct net_device *dev, MAC_HEADER *rmf, __u16 *tx_fstatus) { - struct net_local *tp = (struct net_local *)dev->priv; + struct net_local *tp = netdev_priv(dev); FCBlock *fcb; unsigned int i; int err; @@ -5065,7 +5065,7 @@ static int smctr_set_auth_access_pri(struct net_device *dev, MAC_SUB_VECTOR *rsv) { - struct net_local *tp = (struct net_local *)dev->priv; + struct net_local *tp = netdev_priv(dev); if(rsv->svl != S_AUTHORIZED_ACCESS_PRIORITY) return (E_SUB_VECTOR_LENGTH_ERROR); @@ -5078,7 +5078,7 @@ static int smctr_set_auth_funct_class(struct net_device *dev, MAC_SUB_VECTOR *rsv) { - struct net_local *tp = (struct net_local *)dev->priv; + struct net_local *tp = netdev_priv(dev); if(rsv->svl != S_AUTHORIZED_FUNCTION_CLASS) return (E_SUB_VECTOR_LENGTH_ERROR); @@ -5139,7 +5139,7 @@ static int smctr_set_local_ring_num(struct net_device *dev, MAC_SUB_VECTOR *rsv) { - struct net_local *tp = (struct net_local *)dev->priv; + struct net_local *tp = netdev_priv(dev); if(rsv->svl != S_LOCAL_RING_NUMBER) return (E_SUB_VECTOR_LENGTH_ERROR); @@ -5153,7 +5153,7 @@ static unsigned short smctr_set_ctrl_attention(struct net_device *dev) { - struct net_local *tp = (struct net_local *)dev->priv; + struct net_local *tp = netdev_priv(dev); int ioaddr = dev->base_addr; if(tp->bic_type == BIC_585_CHIP) @@ -5177,7 +5177,7 @@ static int smctr_set_page(struct net_device *dev, __u8 *buf) { - struct net_local *tp = (struct net_local *)dev->priv; + struct net_local *tp = netdev_priv(dev); __u8 amask; __u32 tptr; @@ -5207,7 +5207,7 @@ */ static int smctr_set_ring_speed(struct net_device *dev) { - struct net_local *tp = (struct net_local *)dev->priv; + struct net_local *tp = netdev_priv(dev); int err; if(tp->media_type == MEDIA_UTP_16) @@ -5235,7 +5235,7 @@ static int smctr_set_rx_look_ahead(struct net_device *dev) { - struct net_local *tp = (struct net_local *)dev->priv; + struct net_local *tp = netdev_priv(dev); __u16 sword, rword; if(smctr_debug > 10) @@ -5278,7 +5278,7 @@ static int smctr_setup_single_cmd(struct net_device *dev, __u16 command, __u16 subcommand) { - struct net_local *tp = (struct net_local *)dev->priv; + struct net_local *tp = netdev_priv(dev); unsigned int err; if(smctr_debug > 10) @@ -5305,7 +5305,7 @@ static int smctr_setup_single_cmd_w_data(struct net_device *dev, __u16 command, __u16 subcommand) { - struct net_local *tp = (struct net_local *)dev->priv; + struct net_local *tp = netdev_priv(dev); tp->acb_head->cmd_done_status = ACB_COMMAND_NOT_DONE; tp->acb_head->cmd = command; @@ -5318,7 +5318,7 @@ static char *smctr_malloc(struct net_device *dev, __u16 size) { - struct net_local *tp = (struct net_local *)dev->priv; + struct net_local *tp = netdev_priv(dev); char *m; m = (char *)(tp->ram_access + tp->sh_mem_used); @@ -5329,7 +5329,7 @@ static int smctr_status_chg(struct net_device *dev) { - struct net_local *tp = (struct net_local *)dev->priv; + struct net_local *tp = netdev_priv(dev); if(smctr_debug > 10) printk(KERN_DEBUG "%s: smctr_status_chg\n", dev->name); @@ -5365,7 +5365,7 @@ static int smctr_trc_send_packet(struct net_device *dev, FCBlock *fcb, __u16 queue) { - struct net_local *tp = (struct net_local *)dev->priv; + struct net_local *tp = netdev_priv(dev); int err = 0; if(smctr_debug > 10) @@ -5386,7 +5386,7 @@ static __u16 smctr_tx_complete(struct net_device *dev, __u16 queue) { - struct net_local *tp = (struct net_local *)dev->priv; + struct net_local *tp = netdev_priv(dev); __u16 status, err = 0; int cstatus; @@ -5441,7 +5441,7 @@ static unsigned short smctr_tx_move_frame(struct net_device *dev, struct sk_buff *skb, __u8 *pbuff, unsigned int bytes) { - struct net_local *tp = (struct net_local *)dev->priv; + struct net_local *tp = netdev_priv(dev); unsigned int ram_usable; __u32 flen, len, offset = 0; __u8 *frag, *page; @@ -5482,7 +5482,7 @@ /* Update the error statistic counters for this adapter. */ static int smctr_update_err_stats(struct net_device *dev) { - struct net_local *tp = (struct net_local *)dev->priv; + struct net_local *tp = netdev_priv(dev); struct tr_statistics *tstat = &tp->MacStat; if(tstat->internal_errors) @@ -5524,7 +5524,7 @@ static int smctr_update_rx_chain(struct net_device *dev, __u16 queue) { - struct net_local *tp = (struct net_local *)dev->priv; + struct net_local *tp = netdev_priv(dev); FCBlock *fcb; BDBlock *bdb; __u16 size, len; @@ -5562,7 +5562,7 @@ static int smctr_update_tx_chain(struct net_device *dev, FCBlock *fcb, __u16 queue) { - struct net_local *tp = (struct net_local *)dev->priv; + struct net_local *tp = netdev_priv(dev); if(smctr_debug > 20) printk(KERN_DEBUG "smctr_update_tx_chain\n"); @@ -5598,7 +5598,7 @@ static int smctr_wait_cmd(struct net_device *dev) { - struct net_local *tp = (struct net_local *)dev->priv; + struct net_local *tp = netdev_priv(dev); unsigned int loop_count = 0x20000; if(smctr_debug > 10) @@ -5623,7 +5623,7 @@ static int smctr_wait_while_cbusy(struct net_device *dev) { - struct net_local *tp = (struct net_local *)dev->priv; + struct net_local *tp = netdev_priv(dev); unsigned int timeout = 0x20000; int ioaddr = dev->base_addr; __u8 r; @@ -5686,7 +5686,7 @@ return dev; out1: #ifdef CONFIG_MCA - { struct net_local *tp = (struct net_local *)dev->priv; + { struct net_local *tp = netdev_priv(dev); if (tp->slot_num) mca_mark_as_unused(tp->slot_num); } @@ -5726,7 +5726,7 @@ unregister_netdev(dev); #ifdef CONFIG_MCA - { struct net_local *tp = dev->priv; + { struct net_local *tp = netdev_priv(dev); if (tp->slot_num) mca_mark_as_unused(tp->slot_num); } diff -Nru a/drivers/net/tokenring/tms380tr.c b/drivers/net/tokenring/tms380tr.c --- a/drivers/net/tokenring/tms380tr.c Sun Mar 14 14:20:07 2004 +++ b/drivers/net/tokenring/tms380tr.c Sun Mar 14 14:20:07 2004 @@ -243,7 +243,7 @@ */ int tms380tr_open(struct net_device *dev) { - struct net_local *tp = (struct net_local *)dev->priv; + struct net_local *tp = netdev_priv(dev); int err; /* init the spinlock */ @@ -313,7 +313,7 @@ static void tms380tr_timer_end_wait(unsigned long data) { struct net_device *dev = (struct net_device*)data; - struct net_local *tp = (struct net_local *)dev->priv; + struct net_local *tp = netdev_priv(dev); if(tp->Sleeping) { @@ -329,7 +329,7 @@ */ static int tms380tr_chipset_init(struct net_device *dev) { - struct net_local *tp = (struct net_local *)dev->priv; + struct net_local *tp = netdev_priv(dev); int err; tms380tr_init_ipb(tp); @@ -364,7 +364,7 @@ */ static void tms380tr_init_net_local(struct net_device *dev) { - struct net_local *tp = (struct net_local *)dev->priv; + struct net_local *tp = netdev_priv(dev); int i; dma_addr_t dmabuf; @@ -492,7 +492,7 @@ unsigned short BufferSize = BUFFER_SIZE; int i; - tp = (struct net_local *)dev->priv; + tp = netdev_priv(dev); tp->ocpl.OPENOptions = 0; tp->ocpl.OPENOptions |= ENABLE_FULL_DUPLEX_SELECTION; @@ -531,7 +531,7 @@ */ static void tms380tr_open_adapter(struct net_device *dev) { - struct net_local *tp = (struct net_local *)dev->priv; + struct net_local *tp = netdev_priv(dev); if(tp->OpenCommandIssued) return; @@ -569,7 +569,7 @@ */ static void tms380tr_exec_cmd(struct net_device *dev, unsigned short Command) { - struct net_local *tp = (struct net_local *)dev->priv; + struct net_local *tp = netdev_priv(dev); tp->CMDqueue |= Command; tms380tr_chk_outstanding_cmds(dev); @@ -596,7 +596,7 @@ */ static int tms380tr_send_packet(struct sk_buff *skb, struct net_device *dev) { - struct net_local *tp = (struct net_local *)dev->priv; + struct net_local *tp = netdev_priv(dev); int err; err = tms380tr_hardware_send_packet(skb, dev); @@ -616,7 +616,7 @@ unsigned long flags; int i; dma_addr_t dmabuf, newbuf; - struct net_local *tp = (struct net_local *)dev->priv; + struct net_local *tp = netdev_priv(dev); /* Try to get a free TPL from the chain. * @@ -715,7 +715,7 @@ static void tms380tr_timer_chk(unsigned long data) { struct net_device *dev = (struct net_device*)data; - struct net_local *tp = (struct net_local*)dev->priv; + struct net_local *tp = netdev_priv(dev); if(tp->HaltInProgress) return; @@ -755,7 +755,7 @@ return IRQ_NONE; } - tp = (struct net_local *)dev->priv; + tp = netdev_priv(dev); irq_type = SIFREADW(SIFSTS); @@ -843,7 +843,7 @@ */ static void tms380tr_reset_interrupt(struct net_device *dev) { - struct net_local *tp = (struct net_local *)dev->priv; + struct net_local *tp = netdev_priv(dev); SSB *ssb = &tp->ssb; /* @@ -929,7 +929,7 @@ */ static void tms380tr_cmd_status_irq(struct net_device *dev) { - struct net_local *tp = (struct net_local *)dev->priv; + struct net_local *tp = netdev_priv(dev); unsigned short ssb_cmd, ssb_parm_0; unsigned short ssb_parm_1; char *open_err = "Open error -"; @@ -1126,7 +1126,7 @@ */ int tms380tr_close(struct net_device *dev) { - struct net_local *tp = (struct net_local *)dev->priv; + struct net_local *tp = netdev_priv(dev); netif_stop_queue(dev); del_timer(&tp->timer); @@ -1172,7 +1172,7 @@ */ static struct net_device_stats *tms380tr_get_stats(struct net_device *dev) { - struct net_local *tp = (struct net_local *)dev->priv; + struct net_local *tp = netdev_priv(dev); return ((struct net_device_stats *)&tp->MacStat); } @@ -1182,7 +1182,7 @@ */ static void tms380tr_set_multicast_list(struct net_device *dev) { - struct net_local *tp = (struct net_local *)dev->priv; + struct net_local *tp = netdev_priv(dev); unsigned int OpenOptions; OpenOptions = tp->ocpl.OPENOptions & @@ -1275,7 +1275,7 @@ */ static int tms380tr_reset_adapter(struct net_device *dev) { - struct net_local *tp = (struct net_local *)dev->priv; + struct net_local *tp = netdev_priv(dev); unsigned short *fw_ptr; unsigned short count, c, count2; const struct firmware *fw_entry = NULL; @@ -1428,7 +1428,7 @@ */ static int tms380tr_init_adapter(struct net_device *dev) { - struct net_local *tp = (struct net_local *)dev->priv; + struct net_local *tp = netdev_priv(dev); const unsigned char SCB_Test[6] = {0x00, 0x00, 0xC1, 0xE2, 0xD4, 0x8B}; const unsigned char SSB_Test[8] = {0xFF, 0xFF, 0xD1, 0xD7, @@ -1541,7 +1541,7 @@ */ static void tms380tr_chk_outstanding_cmds(struct net_device *dev) { - struct net_local *tp = (struct net_local *)dev->priv; + struct net_local *tp = netdev_priv(dev); unsigned long Addr = 0; if(tp->CMDqueue == 0) @@ -1713,7 +1713,7 @@ */ static void tms380tr_ring_status_irq(struct net_device *dev) { - struct net_local *tp = (struct net_local *)dev->priv; + struct net_local *tp = netdev_priv(dev); tp->CurrentRingStatus = be16_to_cpu((unsigned short)tp->ssb.Parm[0]); @@ -1785,7 +1785,7 @@ { int i; unsigned short AdapterCheckBlock[4]; - struct net_local *tp = (struct net_local *)dev->priv; + struct net_local *tp = netdev_priv(dev); tp->AdapterOpenFlag = 0; /* Adapter closed now */ @@ -1941,7 +1941,7 @@ */ static int tms380tr_read_ptr(struct net_device *dev) { - struct net_local *tp = (struct net_local *)dev->priv; + struct net_local *tp = netdev_priv(dev); unsigned short adapterram; tms380tr_read_ram(dev, (unsigned char *)&tp->intptrs.BurnedInAddrPtr, @@ -2031,7 +2031,7 @@ */ static void tms380tr_tx_status_irq(struct net_device *dev) { - struct net_local *tp = (struct net_local *)dev->priv; + struct net_local *tp = netdev_priv(dev); unsigned char HighByte, HighAc, LowAc; TPL *tpl; @@ -2102,7 +2102,7 @@ */ static void tms380tr_rcv_status_irq(struct net_device *dev) { - struct net_local *tp = (struct net_local *)dev->priv; + struct net_local *tp = netdev_priv(dev); unsigned char *ReceiveDataPtr; struct sk_buff *skb; unsigned int Length, Length2; @@ -2293,7 +2293,7 @@ static int tms380tr_set_mac_address(struct net_device *dev, void *addr) { - struct net_local *tp = (struct net_local *)dev->priv; + struct net_local *tp = netdev_priv(dev); struct sockaddr *saddr = addr; if (tp->AdapterOpenFlag || tp->AdapterVirtOpenFlag) { @@ -2327,7 +2327,7 @@ { struct net_local *tp; - tp = (struct net_local *) dev->priv; + tp = netdev_priv(dev); pci_unmap_single(tp->pdev, tp->dmabuffer, sizeof(struct net_local), PCI_DMA_BIDIRECTIONAL); } @@ -2338,7 +2338,7 @@ struct net_local *tms_local; memset(dev->priv, 0, sizeof(struct net_local)); - tms_local = (struct net_local *)dev->priv; + tms_local = netdev_priv(dev); init_waitqueue_head(&tms_local->wait_for_tok_int); tms_local->dmalimit = dmalimit; tms_local->pdev = pdev; diff -Nru a/drivers/net/tulip/21142.c b/drivers/net/tulip/21142.c --- a/drivers/net/tulip/21142.c Sun Mar 14 14:20:06 2004 +++ b/drivers/net/tulip/21142.c Sun Mar 14 14:20:06 2004 @@ -29,7 +29,7 @@ void t21142_timer(unsigned long data) { struct net_device *dev = (struct net_device *)data; - struct tulip_private *tp = (struct tulip_private *)dev->priv; + struct tulip_private *tp = netdev_priv(dev); long ioaddr = dev->base_addr; int csr12 = inl(ioaddr + CSR12); int next_tick = 60*HZ; @@ -103,7 +103,7 @@ void t21142_start_nway(struct net_device *dev) { - struct tulip_private *tp = (struct tulip_private *)dev->priv; + struct tulip_private *tp = netdev_priv(dev); long ioaddr = dev->base_addr; int csr14 = ((tp->sym_advertise & 0x0780) << 9) | ((tp->sym_advertise & 0x0020) << 1) | 0xffbf; @@ -131,7 +131,7 @@ void t21142_lnk_change(struct net_device *dev, int csr5) { - struct tulip_private *tp = (struct tulip_private *)dev->priv; + struct tulip_private *tp = netdev_priv(dev); long ioaddr = dev->base_addr; int csr12 = inl(ioaddr + CSR12); diff -Nru a/drivers/net/tulip/de2104x.c b/drivers/net/tulip/de2104x.c --- a/drivers/net/tulip/de2104x.c Sun Mar 14 14:20:08 2004 +++ b/drivers/net/tulip/de2104x.c Sun Mar 14 14:20:08 2004 @@ -457,9 +457,11 @@ buflen, PCI_DMA_FROMDEVICE); de->rx_skb[rx_tail].skb = copy_skb; } else { - pci_dma_sync_single(de->pdev, mapping, len, PCI_DMA_FROMDEVICE); + pci_dma_sync_single_for_cpu(de->pdev, mapping, len, PCI_DMA_FROMDEVICE); skb_reserve(copy_skb, RX_OFFSET); memcpy(skb_put(copy_skb, len), skb->tail, len); + + pci_dma_sync_single_for_device(de->pdev, mapping, len, PCI_DMA_FROMDEVICE); /* We'll reuse the original ring buffer. */ skb = copy_skb; diff -Nru a/drivers/net/tulip/de4x5.c b/drivers/net/tulip/de4x5.c --- a/drivers/net/tulip/de4x5.c Sun Mar 14 14:20:06 2004 +++ b/drivers/net/tulip/de4x5.c Sun Mar 14 14:20:06 2004 @@ -1086,7 +1086,7 @@ de4x5_hw_init(struct net_device *dev, u_long iobase, struct device *gendev) { char name[DE4X5_NAME_LENGTH + 1]; - struct de4x5_private *lp = dev->priv; + struct de4x5_private *lp = netdev_priv(dev); struct pci_dev *pdev = NULL; int i, status=0; @@ -1294,7 +1294,7 @@ static int de4x5_open(struct net_device *dev) { - struct de4x5_private *lp = (struct de4x5_private *)dev->priv; + struct de4x5_private *lp = netdev_priv(dev); u_long iobase = dev->base_addr; int i, status = 0; s32 omr; @@ -1384,7 +1384,7 @@ static int de4x5_sw_reset(struct net_device *dev) { - struct de4x5_private *lp = (struct de4x5_private *)dev->priv; + struct de4x5_private *lp = netdev_priv(dev); u_long iobase = dev->base_addr; int i, j, status = 0; s32 bmr, omr; @@ -1462,7 +1462,7 @@ static int de4x5_queue_pkt(struct sk_buff *skb, struct net_device *dev) { - struct de4x5_private *lp = (struct de4x5_private *)dev->priv; + struct de4x5_private *lp = netdev_priv(dev); u_long iobase = dev->base_addr; int status = 0; u_long flags = 0; @@ -1551,7 +1551,7 @@ printk ("de4x5_interrupt(): irq %d for unknown device.\n", irq); return IRQ_NONE; } - lp = (struct de4x5_private *)dev->priv; + lp = netdev_priv(dev); spin_lock(&lp->lock); iobase = dev->base_addr; @@ -1610,7 +1610,7 @@ static int de4x5_rx(struct net_device *dev) { - struct de4x5_private *lp = (struct de4x5_private *)dev->priv; + struct de4x5_private *lp = netdev_priv(dev); u_long iobase = dev->base_addr; int entry; s32 status; @@ -1701,7 +1701,7 @@ static int de4x5_tx(struct net_device *dev) { - struct de4x5_private *lp = (struct de4x5_private *)dev->priv; + struct de4x5_private *lp = netdev_priv(dev); u_long iobase = dev->base_addr; int entry; s32 status; @@ -1753,7 +1753,7 @@ static int de4x5_ast(struct net_device *dev) { - struct de4x5_private *lp = (struct de4x5_private *)dev->priv; + struct de4x5_private *lp = netdev_priv(dev); int next_tick = DE4X5_AUTOSENSE_MS; disable_ast(dev); @@ -1776,7 +1776,7 @@ static int de4x5_txur(struct net_device *dev) { - struct de4x5_private *lp = (struct de4x5_private *)dev->priv; + struct de4x5_private *lp = netdev_priv(dev); u_long iobase = dev->base_addr; int omr; @@ -1799,7 +1799,7 @@ static int de4x5_rx_ovfc(struct net_device *dev) { - struct de4x5_private *lp = (struct de4x5_private *)dev->priv; + struct de4x5_private *lp = netdev_priv(dev); u_long iobase = dev->base_addr; int omr; @@ -1820,7 +1820,7 @@ static int de4x5_close(struct net_device *dev) { - struct de4x5_private *lp = (struct de4x5_private *)dev->priv; + struct de4x5_private *lp = netdev_priv(dev); u_long iobase = dev->base_addr; s32 imr, omr; @@ -1856,7 +1856,7 @@ static struct net_device_stats * de4x5_get_stats(struct net_device *dev) { - struct de4x5_private *lp = (struct de4x5_private *)dev->priv; + struct de4x5_private *lp = netdev_priv(dev); u_long iobase = dev->base_addr; lp->stats.rx_missed_errors = (int)(inl(DE4X5_MFC) & (MFC_OVFL | MFC_CNTR)); @@ -1867,7 +1867,7 @@ static void de4x5_local_stats(struct net_device *dev, char *buf, int pkt_len) { - struct de4x5_private *lp = (struct de4x5_private *)dev->priv; + struct de4x5_private *lp = netdev_priv(dev); int i; for (i=1; ipriv; + struct de4x5_private *lp = netdev_priv(dev); int entry = (lp->tx_new ? lp->tx_new-1 : lp->txRingSize-1); dma_addr_t buf_dma = dma_map_single(lp->gendev, buf, flags & TD_TBS1, DMA_TO_DEVICE); @@ -1927,7 +1927,7 @@ static void set_multicast_list(struct net_device *dev) { - struct de4x5_private *lp = (struct de4x5_private *)dev->priv; + struct de4x5_private *lp = netdev_priv(dev); u_long iobase = dev->base_addr; /* First, double check that the adapter is open */ @@ -1957,7 +1957,7 @@ static void SetMulticastFilter(struct net_device *dev) { - struct de4x5_private *lp = (struct de4x5_private *)dev->priv; + struct de4x5_private *lp = netdev_priv(dev); struct dev_mc_list *dmi=dev->mc_list; u_long iobase = dev->base_addr; int i, j, bit, byte; @@ -2036,7 +2036,7 @@ status = -ENOMEM; goto release_reg_2; } - lp = dev->priv; + lp = netdev_priv(dev); cfid = (u32) inl(PCI_CFID); lp->cfrv = (u_short) inl(PCI_CFRV); @@ -2142,7 +2142,7 @@ u_int irq = 0, device; u_long iobase = 0; /* Clear upper 32 bits in Alphas */ int i, j, cfrv; - struct de4x5_private *lp = dev->priv; + struct de4x5_private *lp = netdev_priv(dev); struct list_head *walk = &pdev->bus_list; for (walk = walk->next; walk != &pdev->bus_list; walk = walk->next) { @@ -2245,7 +2245,7 @@ if (!(dev = alloc_etherdev (sizeof (struct de4x5_private)))) return -ENOMEM; - lp = dev->priv; + lp = netdev_priv(dev); lp->bus = PCI; lp->bus_num = 0; @@ -2374,7 +2374,7 @@ static int autoconf_media(struct net_device *dev) { - struct de4x5_private *lp = (struct de4x5_private *)dev->priv; + struct de4x5_private *lp = netdev_priv(dev); u_long iobase = dev->base_addr; int next_tick = DE4X5_AUTOSENSE_MS; @@ -2415,7 +2415,7 @@ static int dc21040_autoconf(struct net_device *dev) { - struct de4x5_private *lp = (struct de4x5_private *)dev->priv; + struct de4x5_private *lp = netdev_priv(dev); u_long iobase = dev->base_addr; int next_tick = DE4X5_AUTOSENSE_MS; s32 imr; @@ -2488,7 +2488,7 @@ int next_state, int suspect_state, int (*fn)(struct net_device *, int)) { - struct de4x5_private *lp = (struct de4x5_private *)dev->priv; + struct de4x5_private *lp = netdev_priv(dev); int next_tick = DE4X5_AUTOSENSE_MS; int linkBad; @@ -2527,7 +2527,7 @@ int (*fn)(struct net_device *, int), int (*asfn)(struct net_device *)) { - struct de4x5_private *lp = (struct de4x5_private *)dev->priv; + struct de4x5_private *lp = netdev_priv(dev); int next_tick = DE4X5_AUTOSENSE_MS; int linkBad; @@ -2569,7 +2569,7 @@ static int dc21041_autoconf(struct net_device *dev) { - struct de4x5_private *lp = (struct de4x5_private *)dev->priv; + struct de4x5_private *lp = netdev_priv(dev); u_long iobase = dev->base_addr; s32 sts, irqs, irq_mask, imr, omr; int next_tick = DE4X5_AUTOSENSE_MS; @@ -2771,7 +2771,7 @@ static int dc21140m_autoconf(struct net_device *dev) { - struct de4x5_private *lp = (struct de4x5_private *)dev->priv; + struct de4x5_private *lp = netdev_priv(dev); int ana, anlpa, cap, cr, slnk, sr; int next_tick = DE4X5_AUTOSENSE_MS; u_long imr, omr, iobase = dev->base_addr; @@ -2955,7 +2955,7 @@ static int dc2114x_autoconf(struct net_device *dev) { - struct de4x5_private *lp = (struct de4x5_private *)dev->priv; + struct de4x5_private *lp = netdev_priv(dev); u_long iobase = dev->base_addr; s32 cr, anlpa, ana, cap, irqs, irq_mask, imr, omr, slnk, sr, sts; int next_tick = DE4X5_AUTOSENSE_MS; @@ -3206,7 +3206,7 @@ static int srom_autoconf(struct net_device *dev) { - struct de4x5_private *lp = (struct de4x5_private *)dev->priv; + struct de4x5_private *lp = netdev_priv(dev); return lp->infoleaf_fn(dev); } @@ -3219,7 +3219,7 @@ static int srom_map_media(struct net_device *dev) { - struct de4x5_private *lp = (struct de4x5_private *)dev->priv; + struct de4x5_private *lp = netdev_priv(dev); lp->fdx = 0; if (lp->infoblock_media == lp->media) @@ -3284,7 +3284,7 @@ static void de4x5_init_connection(struct net_device *dev) { - struct de4x5_private *lp = (struct de4x5_private *)dev->priv; + struct de4x5_private *lp = netdev_priv(dev); u_long iobase = dev->base_addr; u_long flags = 0; @@ -3313,7 +3313,7 @@ static int de4x5_reset_phy(struct net_device *dev) { - struct de4x5_private *lp = (struct de4x5_private *)dev->priv; + struct de4x5_private *lp = netdev_priv(dev); u_long iobase = dev->base_addr; int next_tick = 0; @@ -3347,7 +3347,7 @@ static int test_media(struct net_device *dev, s32 irqs, s32 irq_mask, s32 csr13, s32 csr14, s32 csr15, s32 msec) { - struct de4x5_private *lp = (struct de4x5_private *)dev->priv; + struct de4x5_private *lp = netdev_priv(dev); u_long iobase = dev->base_addr; s32 sts, csr12; @@ -3385,7 +3385,7 @@ static int test_tp(struct net_device *dev, s32 msec) { - struct de4x5_private *lp = (struct de4x5_private *)dev->priv; + struct de4x5_private *lp = netdev_priv(dev); u_long iobase = dev->base_addr; int sisr; @@ -3414,7 +3414,7 @@ static int test_for_100Mb(struct net_device *dev, int msec) { - struct de4x5_private *lp = (struct de4x5_private *)dev->priv; + struct de4x5_private *lp = netdev_priv(dev); int gep = 0, ret = ((lp->chipset & ~0x00ff)==DC2114x? -1 :GEP_SLNK); if (lp->timeout < 0) { @@ -3445,7 +3445,7 @@ static int wait_for_link(struct net_device *dev) { - struct de4x5_private *lp = (struct de4x5_private *)dev->priv; + struct de4x5_private *lp = netdev_priv(dev); if (lp->timeout < 0) { lp->timeout = 1; @@ -3467,7 +3467,7 @@ static int test_mii_reg(struct net_device *dev, int reg, int mask, int pol, long msec) { - struct de4x5_private *lp = (struct de4x5_private *)dev->priv; + struct de4x5_private *lp = netdev_priv(dev); int test; u_long iobase = dev->base_addr; @@ -3491,7 +3491,7 @@ static int is_spd_100(struct net_device *dev) { - struct de4x5_private *lp = (struct de4x5_private *)dev->priv; + struct de4x5_private *lp = netdev_priv(dev); u_long iobase = dev->base_addr; int spd; @@ -3515,7 +3515,7 @@ static int is_100_up(struct net_device *dev) { - struct de4x5_private *lp = (struct de4x5_private *)dev->priv; + struct de4x5_private *lp = netdev_priv(dev); u_long iobase = dev->base_addr; if (lp->useMII) { @@ -3536,7 +3536,7 @@ static int is_10_up(struct net_device *dev) { - struct de4x5_private *lp = (struct de4x5_private *)dev->priv; + struct de4x5_private *lp = netdev_priv(dev); u_long iobase = dev->base_addr; if (lp->useMII) { @@ -3559,7 +3559,7 @@ static int is_anc_capable(struct net_device *dev) { - struct de4x5_private *lp = (struct de4x5_private *)dev->priv; + struct de4x5_private *lp = netdev_priv(dev); u_long iobase = dev->base_addr; if (lp->phy[lp->active].id && (!lp->useSROM || lp->useMII)) { @@ -3578,7 +3578,7 @@ static int ping_media(struct net_device *dev, int msec) { - struct de4x5_private *lp = (struct de4x5_private *)dev->priv; + struct de4x5_private *lp = netdev_priv(dev); u_long iobase = dev->base_addr; int sisr; @@ -3619,7 +3619,7 @@ static struct sk_buff * de4x5_alloc_rx_buff(struct net_device *dev, int index, int len) { - struct de4x5_private *lp = (struct de4x5_private *)dev->priv; + struct de4x5_private *lp = netdev_priv(dev); struct sk_buff *p; #if !defined(__alpha__) && !defined(__powerpc__) && !defined(__sparc_v9__) && !defined(DE4X5_DO_MEMCPY) @@ -3667,7 +3667,7 @@ static void de4x5_free_rx_buffs(struct net_device *dev) { - struct de4x5_private *lp = (struct de4x5_private *)dev->priv; + struct de4x5_private *lp = netdev_priv(dev); int i; for (i=0; irxRingSize; i++) { @@ -3684,7 +3684,7 @@ static void de4x5_free_tx_buffs(struct net_device *dev) { - struct de4x5_private *lp = (struct de4x5_private *)dev->priv; + struct de4x5_private *lp = netdev_priv(dev); int i; for (i=0; itxRingSize; i++) { @@ -3711,7 +3711,7 @@ static void de4x5_save_skbs(struct net_device *dev) { - struct de4x5_private *lp = (struct de4x5_private *)dev->priv; + struct de4x5_private *lp = netdev_priv(dev); u_long iobase = dev->base_addr; s32 omr; @@ -3732,7 +3732,7 @@ static void de4x5_rst_desc_ring(struct net_device *dev) { - struct de4x5_private *lp = (struct de4x5_private *)dev->priv; + struct de4x5_private *lp = netdev_priv(dev); u_long iobase = dev->base_addr; int i; s32 omr; @@ -3765,7 +3765,7 @@ static void de4x5_cache_state(struct net_device *dev, int flag) { - struct de4x5_private *lp = (struct de4x5_private *)dev->priv; + struct de4x5_private *lp = netdev_priv(dev); u_long iobase = dev->base_addr; switch(flag) { @@ -3795,7 +3795,7 @@ static void de4x5_put_cache(struct net_device *dev, struct sk_buff *skb) { - struct de4x5_private *lp = (struct de4x5_private *)dev->priv; + struct de4x5_private *lp = netdev_priv(dev); struct sk_buff *p; if (lp->cache.skb) { @@ -3812,7 +3812,7 @@ static void de4x5_putb_cache(struct net_device *dev, struct sk_buff *skb) { - struct de4x5_private *lp = (struct de4x5_private *)dev->priv; + struct de4x5_private *lp = netdev_priv(dev); struct sk_buff *p = lp->cache.skb; lp->cache.skb = skb; @@ -3824,7 +3824,7 @@ static struct sk_buff * de4x5_get_cache(struct net_device *dev) { - struct de4x5_private *lp = (struct de4x5_private *)dev->priv; + struct de4x5_private *lp = netdev_priv(dev); struct sk_buff *p = lp->cache.skb; if (p) { @@ -3842,7 +3842,7 @@ static int test_ans(struct net_device *dev, s32 irqs, s32 irq_mask, s32 msec) { - struct de4x5_private *lp = (struct de4x5_private *)dev->priv; + struct de4x5_private *lp = netdev_priv(dev); u_long iobase = dev->base_addr; s32 sts, ans; @@ -3870,7 +3870,7 @@ static void de4x5_setup_intr(struct net_device *dev) { - struct de4x5_private *lp = (struct de4x5_private *)dev->priv; + struct de4x5_private *lp = netdev_priv(dev); u_long iobase = dev->base_addr; s32 imr, sts; @@ -3891,7 +3891,7 @@ static void reset_init_sia(struct net_device *dev, s32 csr13, s32 csr14, s32 csr15) { - struct de4x5_private *lp = (struct de4x5_private *)dev->priv; + struct de4x5_private *lp = netdev_priv(dev); u_long iobase = dev->base_addr; RESET_SIA; @@ -4014,7 +4014,7 @@ DevicePresent(struct net_device *dev, u_long aprom_addr) { int i, j=0; - struct de4x5_private *lp = (struct de4x5_private *) dev->priv; + struct de4x5_private *lp = netdev_priv(dev); if (lp->chipset == DC21040) { if (lp->bus == EISA) { @@ -4095,7 +4095,7 @@ u_long iobase = dev->base_addr; int broken, i, k, tmp, status = 0; u_short j,chksum; - struct de4x5_private *lp = dev->priv; + struct de4x5_private *lp = netdev_priv(dev); broken = de4x5_bad_srom(lp); @@ -4210,7 +4210,7 @@ static void srom_repair(struct net_device *dev, int card) { - struct de4x5_private *lp = dev->priv; + struct de4x5_private *lp = netdev_priv(dev); switch(card) { case SMC: @@ -4231,7 +4231,7 @@ static int test_bad_enet(struct net_device *dev, int status) { - struct de4x5_private *lp = dev->priv; + struct de4x5_private *lp = netdev_priv(dev); int i, tmp; for (tmp=0,i=0; idev_addr[i]; @@ -4384,7 +4384,7 @@ static int srom_infoleaf_info(struct net_device *dev) { - struct de4x5_private *lp = (struct de4x5_private *)dev->priv; + struct de4x5_private *lp = netdev_priv(dev); int i, count; u_char *p; @@ -4432,7 +4432,7 @@ static void srom_init(struct net_device *dev) { - struct de4x5_private *lp = (struct de4x5_private *)dev->priv; + struct de4x5_private *lp = netdev_priv(dev); u_char *p = (u_char *)&lp->srom + lp->infoleaf_offset; u_char count; @@ -4477,7 +4477,7 @@ static void srom_exec(struct net_device *dev, u_char *p) { - struct de4x5_private *lp = (struct de4x5_private *)dev->priv; + struct de4x5_private *lp = netdev_priv(dev); u_long iobase = dev->base_addr; u_char count = (p ? *p++ : 0); u_short *w = (u_short *)p; @@ -4514,7 +4514,7 @@ static int dc21140_infoleaf(struct net_device *dev) { - struct de4x5_private *lp = (struct de4x5_private *)dev->priv; + struct de4x5_private *lp = netdev_priv(dev); u_char count = 0; u_char *p = (u_char *)&lp->srom + lp->infoleaf_offset; int next_tick = DE4X5_AUTOSENSE_MS; @@ -4552,7 +4552,7 @@ static int dc21142_infoleaf(struct net_device *dev) { - struct de4x5_private *lp = (struct de4x5_private *)dev->priv; + struct de4x5_private *lp = netdev_priv(dev); u_char count = 0; u_char *p = (u_char *)&lp->srom + lp->infoleaf_offset; int next_tick = DE4X5_AUTOSENSE_MS; @@ -4587,7 +4587,7 @@ static int dc21143_infoleaf(struct net_device *dev) { - struct de4x5_private *lp = (struct de4x5_private *)dev->priv; + struct de4x5_private *lp = netdev_priv(dev); u_char count = 0; u_char *p = (u_char *)&lp->srom + lp->infoleaf_offset; int next_tick = DE4X5_AUTOSENSE_MS; @@ -4625,7 +4625,7 @@ static int compact_infoblock(struct net_device *dev, u_char count, u_char *p) { - struct de4x5_private *lp = (struct de4x5_private *)dev->priv; + struct de4x5_private *lp = netdev_priv(dev); u_char flags, csr6; /* Recursively figure out the info blocks */ @@ -4665,7 +4665,7 @@ static int type0_infoblock(struct net_device *dev, u_char count, u_char *p) { - struct de4x5_private *lp = (struct de4x5_private *)dev->priv; + struct de4x5_private *lp = netdev_priv(dev); u_char flags, csr6, len = (*p & BLOCK_LEN)+1; /* Recursively figure out the info blocks */ @@ -4705,7 +4705,7 @@ static int type1_infoblock(struct net_device *dev, u_char count, u_char *p) { - struct de4x5_private *lp = (struct de4x5_private *)dev->priv; + struct de4x5_private *lp = netdev_priv(dev); u_char len = (*p & BLOCK_LEN)+1; /* Recursively figure out the info blocks */ @@ -4744,7 +4744,7 @@ static int type2_infoblock(struct net_device *dev, u_char count, u_char *p) { - struct de4x5_private *lp = (struct de4x5_private *)dev->priv; + struct de4x5_private *lp = netdev_priv(dev); u_char len = (*p & BLOCK_LEN)+1; /* Recursively figure out the info blocks */ @@ -4785,7 +4785,7 @@ static int type3_infoblock(struct net_device *dev, u_char count, u_char *p) { - struct de4x5_private *lp = (struct de4x5_private *)dev->priv; + struct de4x5_private *lp = netdev_priv(dev); u_char len = (*p & BLOCK_LEN)+1; /* Recursively figure out the info blocks */ @@ -4827,7 +4827,7 @@ static int type4_infoblock(struct net_device *dev, u_char count, u_char *p) { - struct de4x5_private *lp = (struct de4x5_private *)dev->priv; + struct de4x5_private *lp = netdev_priv(dev); u_char flags, csr6, len = (*p & BLOCK_LEN)+1; /* Recursively figure out the info blocks */ @@ -4872,7 +4872,7 @@ static int type5_infoblock(struct net_device *dev, u_char count, u_char *p) { - struct de4x5_private *lp = (struct de4x5_private *)dev->priv; + struct de4x5_private *lp = netdev_priv(dev); u_char len = (*p & BLOCK_LEN)+1; /* Recursively figure out the info blocks */ @@ -5072,7 +5072,7 @@ static int mii_get_phy(struct net_device *dev) { - struct de4x5_private *lp = (struct de4x5_private *)dev->priv; + struct de4x5_private *lp = netdev_priv(dev); u_long iobase = dev->base_addr; int i, j, k, n, limit=sizeof(phy_info)/sizeof(struct phy_table); int id; @@ -5136,7 +5136,7 @@ static char * build_setup_frame(struct net_device *dev, int mode) { - struct de4x5_private *lp = (struct de4x5_private *)dev->priv; + struct de4x5_private *lp = netdev_priv(dev); int i; char *pa = lp->setup_frame; @@ -5176,7 +5176,7 @@ static void disable_ast(struct net_device *dev) { - struct de4x5_private *lp = (struct de4x5_private *)dev->priv; + struct de4x5_private *lp = netdev_priv(dev); del_timer(&lp->timer); @@ -5186,7 +5186,7 @@ static long de4x5_switch_mac_port(struct net_device *dev) { - struct de4x5_private *lp = (struct de4x5_private *)dev->priv; + struct de4x5_private *lp = netdev_priv(dev); u_long iobase = dev->base_addr; s32 omr; @@ -5222,7 +5222,7 @@ static void gep_wr(s32 data, struct net_device *dev) { - struct de4x5_private *lp = (struct de4x5_private *)dev->priv; + struct de4x5_private *lp = netdev_priv(dev); u_long iobase = dev->base_addr; if (lp->chipset == DC21140) { @@ -5237,7 +5237,7 @@ static int gep_rd(struct net_device *dev) { - struct de4x5_private *lp = (struct de4x5_private *)dev->priv; + struct de4x5_private *lp = netdev_priv(dev); u_long iobase = dev->base_addr; if (lp->chipset == DC21140) { @@ -5252,7 +5252,7 @@ static void timeout(struct net_device *dev, void (*fn)(u_long data), u_long data, u_long msec) { - struct de4x5_private *lp = (struct de4x5_private *)dev->priv; + struct de4x5_private *lp = netdev_priv(dev); int dt; /* First, cancel any pending timer events */ @@ -5275,7 +5275,7 @@ static void yawn(struct net_device *dev, int state) { - struct de4x5_private *lp = (struct de4x5_private *)dev->priv; + struct de4x5_private *lp = netdev_priv(dev); u_long iobase = dev->base_addr; if ((lp->chipset == DC21040) || (lp->chipset == DC21140)) return; @@ -5321,7 +5321,7 @@ static void de4x5_parse_params(struct net_device *dev) { - struct de4x5_private *lp = (struct de4x5_private *)dev->priv; + struct de4x5_private *lp = netdev_priv(dev); char *p, *q, t; lp->params.fdx = 0; @@ -5364,7 +5364,7 @@ static void de4x5_dbg_open(struct net_device *dev) { - struct de4x5_private *lp = (struct de4x5_private *)dev->priv; + struct de4x5_private *lp = netdev_priv(dev); int i; if (de4x5_debug & DEBUG_OPEN) { @@ -5415,7 +5415,7 @@ static void de4x5_dbg_mii(struct net_device *dev, int k) { - struct de4x5_private *lp = (struct de4x5_private *)dev->priv; + struct de4x5_private *lp = netdev_priv(dev); u_long iobase = dev->base_addr; if (de4x5_debug & DEBUG_MII) { @@ -5443,7 +5443,7 @@ static void de4x5_dbg_media(struct net_device *dev) { - struct de4x5_private *lp = (struct de4x5_private *)dev->priv; + struct de4x5_private *lp = netdev_priv(dev); if (lp->media != lp->c_media) { if (de4x5_debug & DEBUG_MEDIA) { @@ -5534,7 +5534,7 @@ static int de4x5_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) { - struct de4x5_private *lp = (struct de4x5_private *)dev->priv; + struct de4x5_private *lp = netdev_priv(dev); struct de4x5_ioctl *ioc = (struct de4x5_ioctl *) &rq->ifr_data; u_long iobase = dev->base_addr; int i, j, status = 0; diff -Nru a/drivers/net/tulip/dmfe.c b/drivers/net/tulip/dmfe.c --- a/drivers/net/tulip/dmfe.c Sun Mar 14 14:20:08 2004 +++ b/drivers/net/tulip/dmfe.c Sun Mar 14 14:20:08 2004 @@ -392,7 +392,7 @@ } /* Init system & device */ - db = dev->priv; + db = netdev_priv(dev); /* Allocate Tx/Rx descriptor memory */ db->desc_pool_ptr = pci_alloc_consistent(pdev, sizeof(struct tx_desc) * DESC_ALL_CNT + 0x20, &db->desc_pool_dma_ptr); @@ -466,7 +466,7 @@ static void __devexit dmfe_remove_one (struct pci_dev *pdev) { struct net_device *dev = pci_get_drvdata(pdev); - struct dmfe_board_info *db = dev->priv; + struct dmfe_board_info *db = netdev_priv(dev); DMFE_DBUG(0, "dmfe_remove_one()", 0); @@ -494,7 +494,7 @@ static int dmfe_open(struct DEVICE *dev) { int ret; - struct dmfe_board_info *db = dev->priv; + struct dmfe_board_info *db = netdev_priv(dev); DMFE_DBUG(0, "dmfe_open", 0); @@ -552,7 +552,7 @@ static void dmfe_init_dm910x(struct DEVICE *dev) { - struct dmfe_board_info *db = dev->priv; + struct dmfe_board_info *db = netdev_priv(dev); unsigned long ioaddr = db->ioaddr; DMFE_DBUG(0, "dmfe_init_dm910x()", 0); @@ -618,7 +618,7 @@ static int dmfe_start_xmit(struct sk_buff *skb, struct DEVICE *dev) { - struct dmfe_board_info *db = dev->priv; + struct dmfe_board_info *db = netdev_priv(dev); struct tx_desc *txptr; unsigned long flags; @@ -687,7 +687,7 @@ static int dmfe_stop(struct DEVICE *dev) { - struct dmfe_board_info *db = dev->priv; + struct dmfe_board_info *db = netdev_priv(dev); unsigned long ioaddr = dev->base_addr; DMFE_DBUG(0, "dmfe_stop", 0); @@ -730,7 +730,7 @@ static irqreturn_t dmfe_interrupt(int irq, void *dev_id, struct pt_regs *regs) { struct DEVICE *dev = dev_id; - struct dmfe_board_info *db = (struct dmfe_board_info *) dev->priv; + struct dmfe_board_info *db = netdev_priv(dev); unsigned long ioaddr = dev->base_addr; unsigned long flags; @@ -957,7 +957,7 @@ static struct net_device_stats * dmfe_get_stats(struct DEVICE *dev) { - struct dmfe_board_info *db = (struct dmfe_board_info *)dev->priv; + struct dmfe_board_info *db = netdev_priv(dev); DMFE_DBUG(0, "dmfe_get_stats", 0); return &db->stats; @@ -970,7 +970,7 @@ static void dmfe_set_filter_mode(struct DEVICE * dev) { - struct dmfe_board_info *db = dev->priv; + struct dmfe_board_info *db = netdev_priv(dev); unsigned long flags; DMFE_DBUG(0, "dmfe_set_filter_mode()", 0); @@ -1003,7 +1003,7 @@ static void netdev_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info) { - struct dmfe_board_info *np = dev->priv; + struct dmfe_board_info *np = netdev_priv(dev); strcpy(info->driver, DRV_NAME); strcpy(info->version, DRV_VERSION); @@ -1028,7 +1028,7 @@ u32 tmp_cr8; unsigned char tmp_cr12; struct DEVICE *dev = (struct DEVICE *) data; - struct dmfe_board_info *db = (struct dmfe_board_info *) dev->priv; + struct dmfe_board_info *db = netdev_priv(dev); unsigned long flags; DMFE_DBUG(0, "dmfe_timer()", 0); @@ -1160,7 +1160,7 @@ static void dmfe_dynamic_reset(struct DEVICE *dev) { - struct dmfe_board_info *db = dev->priv; + struct dmfe_board_info *db = netdev_priv(dev); DMFE_DBUG(0, "dmfe_dynamic_reset()", 0); @@ -1358,7 +1358,7 @@ static void send_filter_frame(struct DEVICE *dev, int mc_cnt) { - struct dmfe_board_info *db = dev->priv; + struct dmfe_board_info *db = netdev_priv(dev); struct dev_mc_list *mcptr; struct tx_desc *txptr; u16 * addrptr; diff -Nru a/drivers/net/tulip/eeprom.c b/drivers/net/tulip/eeprom.c --- a/drivers/net/tulip/eeprom.c Sun Mar 14 14:20:08 2004 +++ b/drivers/net/tulip/eeprom.c Sun Mar 14 14:20:08 2004 @@ -136,7 +136,7 @@ static struct mediatable *last_mediatable; static unsigned char *last_ee_data; static int controller_index; - struct tulip_private *tp = (struct tulip_private *)dev->priv; + struct tulip_private *tp = netdev_priv(dev); unsigned char *ee_data = tp->eeprom; int i; diff -Nru a/drivers/net/tulip/interrupt.c b/drivers/net/tulip/interrupt.c --- a/drivers/net/tulip/interrupt.c Sun Mar 14 14:20:06 2004 +++ b/drivers/net/tulip/interrupt.c Sun Mar 14 14:20:06 2004 @@ -63,7 +63,7 @@ int tulip_refill_rx(struct net_device *dev) { - struct tulip_private *tp = (struct tulip_private *)dev->priv; + struct tulip_private *tp = netdev_priv(dev); int entry; int refilled = 0; @@ -109,7 +109,7 @@ int tulip_poll(struct net_device *dev, int *budget) { - struct tulip_private *tp = (struct tulip_private *)dev->priv; + struct tulip_private *tp = netdev_priv(dev); int entry = tp->cur_rx % RX_RING_SIZE; int rx_work_limit = *budget; int received = 0; @@ -191,9 +191,9 @@ && (skb = dev_alloc_skb(pkt_len + 2)) != NULL) { skb->dev = dev; skb_reserve(skb, 2); /* 16 byte align the IP header */ - pci_dma_sync_single(tp->pdev, - tp->rx_buffers[entry].mapping, - pkt_len, PCI_DMA_FROMDEVICE); + pci_dma_sync_single_for_cpu(tp->pdev, + tp->rx_buffers[entry].mapping, + pkt_len, PCI_DMA_FROMDEVICE); #if ! defined(__alpha__) eth_copy_and_sum(skb, tp->rx_buffers[entry].skb->tail, pkt_len, 0); @@ -203,6 +203,9 @@ tp->rx_buffers[entry].skb->tail, pkt_len); #endif + pci_dma_sync_single_for_device(tp->pdev, + tp->rx_buffers[entry].mapping, + pkt_len, PCI_DMA_FROMDEVICE); } else { /* Pass up the skb already on the Rx ring. */ char *temp = skb_put(skb = tp->rx_buffers[entry].skb, pkt_len); @@ -354,7 +357,7 @@ static int tulip_rx(struct net_device *dev) { - struct tulip_private *tp = (struct tulip_private *)dev->priv; + struct tulip_private *tp = netdev_priv(dev); int entry = tp->cur_rx % RX_RING_SIZE; int rx_work_limit = tp->dirty_rx + RX_RING_SIZE - tp->cur_rx; int received = 0; @@ -412,9 +415,9 @@ && (skb = dev_alloc_skb(pkt_len + 2)) != NULL) { skb->dev = dev; skb_reserve(skb, 2); /* 16 byte align the IP header */ - pci_dma_sync_single(tp->pdev, - tp->rx_buffers[entry].mapping, - pkt_len, PCI_DMA_FROMDEVICE); + pci_dma_sync_single_for_cpu(tp->pdev, + tp->rx_buffers[entry].mapping, + pkt_len, PCI_DMA_FROMDEVICE); #if ! defined(__alpha__) eth_copy_and_sum(skb, tp->rx_buffers[entry].skb->tail, pkt_len, 0); @@ -424,6 +427,9 @@ tp->rx_buffers[entry].skb->tail, pkt_len); #endif + pci_dma_sync_single_for_device(tp->pdev, + tp->rx_buffers[entry].mapping, + pkt_len, PCI_DMA_FROMDEVICE); } else { /* Pass up the skb already on the Rx ring. */ char *temp = skb_put(skb = tp->rx_buffers[entry].skb, pkt_len); @@ -465,7 +471,7 @@ { #ifdef __hppa__ int csr12 = inl(dev->base_addr + CSR12) & 0xff; - struct tulip_private *tp = (struct tulip_private *)dev->priv; + struct tulip_private *tp = netdev_priv(dev); if (csr12 != tp->csr12_shadow) { /* ack interrupt */ @@ -490,7 +496,7 @@ irqreturn_t tulip_interrupt(int irq, void *dev_instance, struct pt_regs *regs) { struct net_device *dev = (struct net_device *)dev_instance; - struct tulip_private *tp = (struct tulip_private *)dev->priv; + struct tulip_private *tp = netdev_priv(dev); long ioaddr = dev->base_addr; int csr5; int missed; diff -Nru a/drivers/net/tulip/media.c b/drivers/net/tulip/media.c --- a/drivers/net/tulip/media.c Sun Mar 14 14:20:06 2004 +++ b/drivers/net/tulip/media.c Sun Mar 14 14:20:06 2004 @@ -48,7 +48,7 @@ int tulip_mdio_read(struct net_device *dev, int phy_id, int location) { - struct tulip_private *tp = (struct tulip_private *)dev->priv; + struct tulip_private *tp = netdev_priv(dev); int i; int read_cmd = (0xf6 << 10) | ((phy_id & 0x1f) << 5) | location; int retval = 0; @@ -111,7 +111,7 @@ void tulip_mdio_write(struct net_device *dev, int phy_id, int location, int val) { - struct tulip_private *tp = (struct tulip_private *)dev->priv; + struct tulip_private *tp = netdev_priv(dev); int i; int cmd = (0x5002 << 16) | ((phy_id & 0x1f) << 23) | (location<<18) | (val & 0xffff); long ioaddr = dev->base_addr; @@ -171,7 +171,7 @@ void tulip_select_media(struct net_device *dev, int startup) { long ioaddr = dev->base_addr; - struct tulip_private *tp = (struct tulip_private *)dev->priv; + struct tulip_private *tp = netdev_priv(dev); struct mediatable *mtable = tp->mtable; u32 new_csr6; int i; @@ -374,7 +374,7 @@ */ int tulip_check_duplex(struct net_device *dev) { - struct tulip_private *tp = dev->priv; + struct tulip_private *tp = netdev_priv(dev); unsigned int bmsr, lpa, negotiated, new_csr6; bmsr = tulip_mdio_read(dev, tp->phys[0], MII_BMSR); @@ -420,7 +420,7 @@ void __devinit tulip_find_mii (struct net_device *dev, int board_idx) { - struct tulip_private *tp = dev->priv; + struct tulip_private *tp = netdev_priv(dev); int phyn, phy_idx = 0; int mii_reg0; int mii_advert; diff -Nru a/drivers/net/tulip/pnic.c b/drivers/net/tulip/pnic.c --- a/drivers/net/tulip/pnic.c Sun Mar 14 14:20:07 2004 +++ b/drivers/net/tulip/pnic.c Sun Mar 14 14:20:07 2004 @@ -20,7 +20,7 @@ void pnic_do_nway(struct net_device *dev) { - struct tulip_private *tp = (struct tulip_private *)dev->priv; + struct tulip_private *tp = netdev_priv(dev); long ioaddr = dev->base_addr; u32 phy_reg = inl(ioaddr + 0xB8); u32 new_csr6 = tp->csr6 & ~0x40C40200; @@ -53,7 +53,7 @@ void pnic_lnk_change(struct net_device *dev, int csr5) { - struct tulip_private *tp = (struct tulip_private *)dev->priv; + struct tulip_private *tp = netdev_priv(dev); long ioaddr = dev->base_addr; int phy_reg = inl(ioaddr + 0xB8); @@ -89,7 +89,7 @@ void pnic_timer(unsigned long data) { struct net_device *dev = (struct net_device *)data; - struct tulip_private *tp = (struct tulip_private *)dev->priv; + struct tulip_private *tp = netdev_priv(dev); long ioaddr = dev->base_addr; int next_tick = 60*HZ; diff -Nru a/drivers/net/tulip/pnic2.c b/drivers/net/tulip/pnic2.c --- a/drivers/net/tulip/pnic2.c Sun Mar 14 14:20:06 2004 +++ b/drivers/net/tulip/pnic2.c Sun Mar 14 14:20:06 2004 @@ -84,7 +84,7 @@ void pnic2_timer(unsigned long data) { struct net_device *dev = (struct net_device *)data; - struct tulip_private *tp = (struct tulip_private *)dev->priv; + struct tulip_private *tp = netdev_priv(dev); long ioaddr = dev->base_addr; int next_tick = 60*HZ; @@ -100,7 +100,7 @@ void pnic2_start_nway(struct net_device *dev) { - struct tulip_private *tp = (struct tulip_private *)dev->priv; + struct tulip_private *tp = netdev_priv(dev); long ioaddr = dev->base_addr; int csr14; int csr12; @@ -175,7 +175,7 @@ void pnic2_lnk_change(struct net_device *dev, int csr5) { - struct tulip_private *tp = (struct tulip_private *)dev->priv; + struct tulip_private *tp = netdev_priv(dev); long ioaddr = dev->base_addr; int csr14; diff -Nru a/drivers/net/tulip/timer.c b/drivers/net/tulip/timer.c --- a/drivers/net/tulip/timer.c Sun Mar 14 14:20:05 2004 +++ b/drivers/net/tulip/timer.c Sun Mar 14 14:20:05 2004 @@ -20,7 +20,7 @@ void tulip_timer(unsigned long data) { struct net_device *dev = (struct net_device *)data; - struct tulip_private *tp = (struct tulip_private *)dev->priv; + struct tulip_private *tp = netdev_priv(dev); long ioaddr = dev->base_addr; u32 csr12 = inl(ioaddr + CSR12); int next_tick = 2*HZ; @@ -135,7 +135,7 @@ void mxic_timer(unsigned long data) { struct net_device *dev = (struct net_device *)data; - struct tulip_private *tp = (struct tulip_private *)dev->priv; + struct tulip_private *tp = netdev_priv(dev); long ioaddr = dev->base_addr; int next_tick = 60*HZ; @@ -152,7 +152,7 @@ void comet_timer(unsigned long data) { struct net_device *dev = (struct net_device *)data; - struct tulip_private *tp = (struct tulip_private *)dev->priv; + struct tulip_private *tp = netdev_priv(dev); long ioaddr = dev->base_addr; int next_tick = 60*HZ; diff -Nru a/drivers/net/tulip/tulip_core.c b/drivers/net/tulip/tulip_core.c --- a/drivers/net/tulip/tulip_core.c Sun Mar 14 14:20:07 2004 +++ b/drivers/net/tulip/tulip_core.c Sun Mar 14 14:20:07 2004 @@ -253,7 +253,7 @@ static struct net_device_stats *tulip_get_stats(struct net_device *dev); static int private_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); static void set_rx_mode(struct net_device *dev); - +static void poll_tulip(struct net_device *dev); static void tulip_set_power_state (struct tulip_private *tp, @@ -276,7 +276,7 @@ static void tulip_up(struct net_device *dev) { - struct tulip_private *tp = (struct tulip_private *)dev->priv; + struct tulip_private *tp = netdev_priv(dev); long ioaddr = dev->base_addr; int next_tick = 3*HZ; int i; @@ -499,7 +499,7 @@ static void tulip_tx_timeout(struct net_device *dev) { - struct tulip_private *tp = (struct tulip_private *)dev->priv; + struct tulip_private *tp = netdev_priv(dev); long ioaddr = dev->base_addr; unsigned long flags; @@ -587,7 +587,7 @@ /* Initialize the Rx and Tx rings, along with various 'dev' bits. */ static void tulip_init_ring(struct net_device *dev) { - struct tulip_private *tp = (struct tulip_private *)dev->priv; + struct tulip_private *tp = netdev_priv(dev); int i; tp->susp_rx = 0; @@ -638,7 +638,7 @@ static int tulip_start_xmit(struct sk_buff *skb, struct net_device *dev) { - struct tulip_private *tp = (struct tulip_private *)dev->priv; + struct tulip_private *tp = netdev_priv(dev); int entry; u32 flag; dma_addr_t mapping; @@ -724,7 +724,7 @@ static void tulip_down (struct net_device *dev) { long ioaddr = dev->base_addr; - struct tulip_private *tp = (struct tulip_private *) dev->priv; + struct tulip_private *tp = netdev_priv(dev); unsigned long flags; del_timer_sync (&tp->timer); @@ -764,7 +764,7 @@ static int tulip_close (struct net_device *dev) { long ioaddr = dev->base_addr; - struct tulip_private *tp = (struct tulip_private *) dev->priv; + struct tulip_private *tp = netdev_priv(dev); int i; netif_stop_queue (dev); @@ -811,7 +811,7 @@ static struct net_device_stats *tulip_get_stats(struct net_device *dev) { - struct tulip_private *tp = (struct tulip_private *)dev->priv; + struct tulip_private *tp = netdev_priv(dev); long ioaddr = dev->base_addr; if (netif_running(dev)) { @@ -830,7 +830,7 @@ static int netdev_ethtool_ioctl(struct net_device *dev, void *useraddr) { - struct tulip_private *np = dev->priv; + struct tulip_private *np = netdev_priv(dev); u32 ethcmd; if (copy_from_user(ðcmd, useraddr, sizeof(ethcmd))) @@ -855,7 +855,7 @@ /* Provide ioctl() calls to examine the MII xcvr state. */ static int private_ioctl (struct net_device *dev, struct ifreq *rq, int cmd) { - struct tulip_private *tp = dev->priv; + struct tulip_private *tp = netdev_priv(dev); long ioaddr = dev->base_addr; struct mii_ioctl_data *data = (struct mii_ioctl_data *) & rq->ifr_data; const unsigned int phy_idx = 0; @@ -964,7 +964,7 @@ static void build_setup_frame_hash(u16 *setup_frm, struct net_device *dev) { - struct tulip_private *tp = (struct tulip_private *)dev->priv; + struct tulip_private *tp = netdev_priv(dev); u16 hash_table[32]; struct dev_mc_list *mclist; int i; @@ -995,7 +995,7 @@ static void build_setup_frame_perfect(u16 *setup_frm, struct net_device *dev) { - struct tulip_private *tp = (struct tulip_private *)dev->priv; + struct tulip_private *tp = netdev_priv(dev); struct dev_mc_list *mclist; int i; u16 *eaddrs; @@ -1023,7 +1023,7 @@ static void set_rx_mode(struct net_device *dev) { - struct tulip_private *tp = (struct tulip_private *)dev->priv; + struct tulip_private *tp = netdev_priv(dev); long ioaddr = dev->base_addr; int csr6; @@ -1150,7 +1150,7 @@ static void __devinit tulip_mwi_config (struct pci_dev *pdev, struct net_device *dev) { - struct tulip_private *tp = dev->priv; + struct tulip_private *tp = netdev_priv(dev); u8 cache; u16 pci_command; u32 csr0; @@ -1373,7 +1373,7 @@ * initialize private data structure 'tp' * it is zeroed and aligned in alloc_etherdev */ - tp = dev->priv; + tp = netdev_priv(dev); tp->rx_ring = pci_alloc_consistent(pdev, sizeof(struct tulip_rx_desc) * RX_RING_SIZE + @@ -1618,6 +1618,9 @@ dev->get_stats = tulip_get_stats; dev->do_ioctl = private_ioctl; dev->set_multicast_list = set_rx_mode; +#ifdef CONFIG_NET_POLL_CONTROLLER + dev->poll_controller = &poll_tulip; +#endif if (register_netdev(dev)) goto err_out_free_ring; @@ -1756,7 +1759,7 @@ if (!dev) return; - tp = dev->priv; + tp = netdev_priv(dev); pci_free_consistent (pdev, sizeof (struct tulip_rx_desc) * RX_RING_SIZE + sizeof (struct tulip_tx_desc) * TX_RING_SIZE, @@ -1774,6 +1777,22 @@ /* pci_power_off (pdev, -1); */ } +#ifdef CONFIG_NET_POLL_CONTROLLER +/* + * Polling 'interrupt' - used by things like netconsole to send skbs + * without having to re-enable interrupts. It's not called while + * the interrupt routine is executing. + */ + +static void poll_tulip (struct net_device *dev) +{ + /* disable_irq here is not very nice, but with the lockless + interrupt handler we have no other choice. */ + disable_irq(dev->irq); + tulip_interrupt (dev->irq, dev, NULL); + enable_irq(dev->irq); +} +#endif static struct pci_driver tulip_driver = { .name = DRV_NAME, diff -Nru a/drivers/net/tulip/winbond-840.c b/drivers/net/tulip/winbond-840.c --- a/drivers/net/tulip/winbond-840.c Sun Mar 14 14:20:06 2004 +++ b/drivers/net/tulip/winbond-840.c Sun Mar 14 14:20:06 2004 @@ -1289,9 +1289,9 @@ && (skb = dev_alloc_skb(pkt_len + 2)) != NULL) { skb->dev = dev; skb_reserve(skb, 2); /* 16 byte align the IP header */ - pci_dma_sync_single(np->pci_dev,np->rx_addr[entry], - np->rx_skbuff[entry]->len, - PCI_DMA_FROMDEVICE); + pci_dma_sync_single_for_cpu(np->pci_dev,np->rx_addr[entry], + np->rx_skbuff[entry]->len, + PCI_DMA_FROMDEVICE); /* Call copy + cksum if available. */ #if HAS_IP_COPYSUM eth_copy_and_sum(skb, np->rx_skbuff[entry]->tail, pkt_len, 0); @@ -1300,6 +1300,9 @@ memcpy(skb_put(skb, pkt_len), np->rx_skbuff[entry]->tail, pkt_len); #endif + pci_dma_sync_single_for_device(np->pci_dev,np->rx_addr[entry], + np->rx_skbuff[entry]->len, + PCI_DMA_FROMDEVICE); } else { pci_unmap_single(np->pci_dev,np->rx_addr[entry], np->rx_skbuff[entry]->len, diff -Nru a/drivers/net/tulip/xircom_cb.c b/drivers/net/tulip/xircom_cb.c --- a/drivers/net/tulip/xircom_cb.c Sun Mar 14 14:20:08 2004 +++ b/drivers/net/tulip/xircom_cb.c Sun Mar 14 14:20:08 2004 @@ -178,7 +178,7 @@ static void netdev_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info) { - struct xircom_private *private = dev->priv; + struct xircom_private *private = netdev_priv(dev); strcpy(info->driver, "xircom_cb"); strcpy(info->bus_info, pci_name(private->pdev)); @@ -235,7 +235,7 @@ printk(KERN_ERR "xircom_probe: failed to allocate etherdev\n"); goto device_fail; } - private = dev->priv; + private = netdev_priv(dev); /* Allocate the send/receive buffers */ private->rx_buffer = pci_alloc_consistent(pdev,8192,&private->rx_dma_handle); @@ -312,7 +312,7 @@ static void __devexit xircom_remove(struct pci_dev *pdev) { struct net_device *dev = pci_get_drvdata(pdev); - struct xircom_private *card = dev->priv; + struct xircom_private *card = netdev_priv(dev); enter("xircom_remove"); pci_free_consistent(pdev,8192,card->rx_buffer,card->rx_dma_handle); @@ -328,7 +328,7 @@ static irqreturn_t xircom_interrupt(int irq, void *dev_instance, struct pt_regs *regs) { struct net_device *dev = (struct net_device *) dev_instance; - struct xircom_private *card = (struct xircom_private *) dev->priv; + struct xircom_private *card = netdev_priv(dev); unsigned int status; int i; @@ -385,7 +385,7 @@ int desc; enter("xircom_start_xmit"); - card = (struct xircom_private*)dev->priv; + card = netdev_priv(dev); spin_lock_irqsave(&card->lock,flags); /* First see if we can free some descriptors */ @@ -444,7 +444,7 @@ static int xircom_open(struct net_device *dev) { - struct xircom_private *xp = (struct xircom_private *) dev->priv; + struct xircom_private *xp = netdev_priv(dev); int retval; enter("xircom_open"); printk(KERN_INFO "xircom cardbus adaptor found, registering as %s, using irq %i \n",dev->name,dev->irq); @@ -466,7 +466,7 @@ unsigned long flags; enter("xircom_close"); - card = dev->priv; + card = netdev_priv(dev); netif_stop_queue(dev); /* we don't want new packets */ @@ -495,7 +495,7 @@ static struct net_device_stats *xircom_get_stats(struct net_device *dev) { - struct xircom_private *card = (struct xircom_private *)dev->priv; + struct xircom_private *card = netdev_priv(dev); return &card->stats; } diff -Nru a/drivers/net/tun.c b/drivers/net/tun.c --- a/drivers/net/tun.c Sun Mar 14 14:20:07 2004 +++ b/drivers/net/tun.c Sun Mar 14 14:20:07 2004 @@ -70,7 +70,7 @@ /* Net device start xmit */ static int tun_net_xmit(struct sk_buff *skb, struct net_device *dev) { - struct tun_struct *tun = (struct tun_struct *)dev->priv; + struct tun_struct *tun = netdev_priv(dev); DBG(KERN_INFO "%s: tun_net_xmit %d\n", tun->dev->name, skb->len); @@ -113,14 +113,14 @@ static struct net_device_stats *tun_net_stats(struct net_device *dev) { - struct tun_struct *tun = (struct tun_struct *)dev->priv; + struct tun_struct *tun = netdev_priv(dev); return &tun->stats; } /* Initialize net device. */ static void tun_net_init(struct net_device *dev) { - struct tun_struct *tun = (struct tun_struct *)dev->priv; + struct tun_struct *tun = netdev_priv(dev); switch (tun->flags & TUN_TYPE_MASK) { case TUN_TUN_DEV: @@ -153,7 +153,7 @@ /* Poll */ static unsigned int tun_chr_poll(struct file *file, poll_table * wait) { - struct tun_struct *tun = (struct tun_struct *)file->private_data; + struct tun_struct *tun = file->private_data; unsigned int mask = POLLOUT | POLLWRNORM; if (!tun) @@ -217,7 +217,7 @@ static ssize_t tun_chr_writev(struct file * file, const struct iovec *iv, unsigned long count, loff_t *pos) { - struct tun_struct *tun = (struct tun_struct *)file->private_data; + struct tun_struct *tun = file->private_data; unsigned long i; size_t len; @@ -279,7 +279,7 @@ static ssize_t tun_chr_readv(struct file *file, const struct iovec *iv, unsigned long count, loff_t *pos) { - struct tun_struct *tun = (struct tun_struct *)file->private_data; + struct tun_struct *tun = file->private_data; DECLARE_WAITQUEUE(wait, current); struct sk_buff *skb; ssize_t len, ret = 0; @@ -341,7 +341,7 @@ static void tun_setup(struct net_device *dev) { - struct tun_struct *tun = dev->priv; + struct tun_struct *tun = netdev_priv(dev); skb_queue_head_init(&tun->readq); init_waitqueue_head(&tun->read_wait); @@ -413,7 +413,7 @@ if (!dev) return -ENOMEM; - tun = dev->priv; + tun = netdev_priv(dev); tun->dev = dev; tun->flags = flags; @@ -455,7 +455,7 @@ static int tun_chr_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) { - struct tun_struct *tun = (struct tun_struct *)file->private_data; + struct tun_struct *tun = file->private_data; if (cmd == TUNSETIFF && !tun) { struct ifreq ifr; @@ -527,7 +527,7 @@ static int tun_chr_fasync(int fd, struct file *file, int on) { - struct tun_struct *tun = (struct tun_struct *)file->private_data; + struct tun_struct *tun = file->private_data; int ret; if (!tun) @@ -558,7 +558,7 @@ static int tun_chr_close(struct inode *inode, struct file *file) { - struct tun_struct *tun = (struct tun_struct *)file->private_data; + struct tun_struct *tun = file->private_data; if (!tun) return 0; diff -Nru a/drivers/net/typhoon.c b/drivers/net/typhoon.c --- a/drivers/net/typhoon.c Sun Mar 14 14:20:07 2004 +++ b/drivers/net/typhoon.c Sun Mar 14 14:20:07 2004 @@ -1701,9 +1701,13 @@ (new_skb = dev_alloc_skb(pkt_len + 2)) != NULL) { new_skb->dev = tp->dev; skb_reserve(new_skb, 2); - pci_dma_sync_single(tp->pdev, dma_addr, PKT_BUF_SZ, - PCI_DMA_FROMDEVICE); + pci_dma_sync_single_for_cpu(tp->pdev, dma_addr, + PKT_BUF_SZ, + PCI_DMA_FROMDEVICE); eth_copy_and_sum(new_skb, skb->tail, pkt_len, 0); + pci_dma_sync_single_for_device(tp->pdev, dma_addr, + PKT_BUF_SZ, + PCI_DMA_FROMDEVICE); skb_put(new_skb, pkt_len); typhoon_recycle_rx_skb(tp, idx); } else { diff -Nru a/drivers/net/via-rhine.c b/drivers/net/via-rhine.c --- a/drivers/net/via-rhine.c Sun Mar 14 14:20:08 2004 +++ b/drivers/net/via-rhine.c Sun Mar 14 14:20:08 2004 @@ -615,6 +615,15 @@ break; } +#ifdef CONFIG_NET_POLL_CONTROLLER +static void via_rhine_poll(struct net_device *dev) +{ + disable_irq(dev->irq); + via_rhine_interrupt(dev->irq, (void *)dev, NULL); + enable_irq(dev->irq); +} +#endif + static int __devinit via_rhine_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) { @@ -784,6 +793,9 @@ dev->ethtool_ops = &netdev_ethtool_ops; dev->tx_timeout = via_rhine_tx_timeout; dev->watchdog_timeo = TX_TIMEOUT; +#ifdef CONFIG_NET_POLL_CONTROLLER + dev->poll_controller = via_rhine_poll; +#endif if (np->drv_flags & ReqTxAlign) dev->features |= NETIF_F_SG|NETIF_F_HW_CSUM; @@ -1524,7 +1536,7 @@ (skb = dev_alloc_skb(pkt_len + 2)) != NULL) { skb->dev = dev; skb_reserve(skb, 2); /* 16 byte align the IP header */ - pci_dma_sync_single(np->pdev, np->rx_skbuff_dma[entry], + pci_dma_sync_single_for_cpu(np->pdev, np->rx_skbuff_dma[entry], np->rx_buf_sz, PCI_DMA_FROMDEVICE); /* *_IP_COPYSUM isn't defined anywhere and eth_copy_and_sum @@ -1537,6 +1549,8 @@ memcpy(skb_put(skb, pkt_len), np->rx_skbuff[entry]->tail, pkt_len); #endif + pci_dma_sync_single_for_device(np->pdev, np->rx_skbuff_dma[entry], + np->rx_buf_sz, PCI_DMA_FROMDEVICE); } else { skb = np->rx_skbuff[entry]; if (skb == NULL) { diff -Nru a/drivers/net/wan/comx-hw-locomx.c b/drivers/net/wan/comx-hw-locomx.c --- a/drivers/net/wan/comx-hw-locomx.c Sun Mar 14 14:20:07 2004 +++ b/drivers/net/wan/comx-hw-locomx.c Sun Mar 14 14:20:07 2004 @@ -77,7 +77,7 @@ static int LOCOMX_txe(struct net_device *dev) { - struct comx_channel *ch = dev->priv; + struct comx_channel *ch = netdev_priv(dev); struct locomx_data *hw = ch->HW_privdata; return (!hw->board.chanA.tx_next_skb); @@ -86,8 +86,8 @@ static void locomx_rx(struct z8530_channel *c, struct sk_buff *skb) { - struct net_device *dev=c->netdevice; - struct comx_channel *ch=dev->priv; + struct net_device *dev = c->netdevice; + struct comx_channel *ch = netdev_priv(dev); if (ch->debug_flags & DEBUG_HW_RX) { comx_debug_skb(dev, skb, "locomx_rx receiving"); @@ -97,7 +97,7 @@ static int LOCOMX_send_packet(struct net_device *dev, struct sk_buff *skb) { - struct comx_channel *ch = (struct comx_channel *)dev->priv; + struct comx_channel *ch = netdev_priv(dev); struct locomx_data *hw = ch->HW_privdata; if (ch->debug_flags & DEBUG_HW_TX) { @@ -126,9 +126,9 @@ static void locomx_status_timerfun(unsigned long d) { - struct net_device *dev=(struct net_device *)d; - struct comx_channel *ch=dev->priv; - struct locomx_data *hw=ch->HW_privdata; + struct net_device *dev = (struct net_device *)d; + struct comx_channel *ch = netdev_priv(dev); + struct locomx_data *hw = ch->HW_privdata; if(!(ch->line_status & LINE_UP) && (hw->board.chanA.status & CTS)) { @@ -144,7 +144,7 @@ static int LOCOMX_open(struct net_device *dev) { - struct comx_channel *ch = dev->priv; + struct comx_channel *ch = netdev_priv(dev); struct locomx_data *hw = ch->HW_privdata; struct proc_dir_entry *procfile = ch->procdir->subdir; unsigned long flags; @@ -256,7 +256,7 @@ static int LOCOMX_close(struct net_device *dev) { - struct comx_channel *ch = dev->priv; + struct comx_channel *ch = netdev_priv(dev); struct locomx_data *hw = ch->HW_privdata; struct proc_dir_entry *procfile = ch->procdir->subdir; @@ -376,7 +376,7 @@ static int LOCOMX_init(struct net_device *dev) { - struct comx_channel *ch = (struct comx_channel *)dev->priv; + struct comx_channel *ch = netdev_priv(dev); struct locomx_data *hw; struct proc_dir_entry *new_file; @@ -449,7 +449,7 @@ static int LOCOMX_exit(struct net_device *dev) { - struct comx_channel *ch = (struct comx_channel *)dev->priv; + struct comx_channel *ch = netdev_priv(dev); ch->HW_access_board = NULL; ch->HW_release_board = NULL; diff -Nru a/drivers/net/wan/comx-hw-munich.c b/drivers/net/wan/comx-hw-munich.c --- a/drivers/net/wan/comx-hw-munich.c Sun Mar 14 14:20:06 2004 +++ b/drivers/net/wan/comx-hw-munich.c Sun Mar 14 14:20:06 2004 @@ -373,7 +373,7 @@ void rework_idle_channels(struct net_device *dev) { - struct comx_channel *ch = dev->priv; + struct comx_channel *ch = netdev_priv(dev); struct slicecom_privdata *hw = ch->HW_privdata; munich_board_t *board = slicecom_boards + hw->boardnum; munich_ccb_t *ccb = board->ccb; @@ -731,7 +731,7 @@ { munich_board_t *board = (munich_board_t *) b; struct net_device *dev = board->twins[0]; - struct comx_channel *ch = dev->priv; + struct comx_channel *ch = netdev_priv(dev); unsigned long regs; regs = readl((void *)(&board->bar1[GPDATA])); @@ -765,7 +765,7 @@ static int MUNICH_txe(struct net_device *dev) { - struct comx_channel *ch = dev->priv; + struct comx_channel *ch = netdev_priv(dev); struct slicecom_privdata *hw = ch->HW_privdata; return (hw->busy < TX_DESC_MAX - 1); @@ -905,7 +905,7 @@ #if 0 static int slicecom_reset(struct net_device *dev) { - struct comx_channel *ch = dev->priv; + struct comx_channel *ch = netdev_priv(dev); printk("slicecom_reset: resetting the hardware\n"); @@ -933,7 +933,7 @@ static int MUNICH_send_packet(struct net_device *dev, struct sk_buff *skb) { - struct comx_channel *ch = (struct comx_channel *)dev->priv; + struct comx_channel *ch = netdev_priv(dev); struct slicecom_privdata *hw = ch->HW_privdata; /* Send it to the debug facility too if needed: */ @@ -1085,7 +1085,7 @@ goto go_for_next_interrupt; } - ch = (struct comx_channel *)dev->priv; + ch = netdev_priv(dev); hw = (struct slicecom_privdata *)ch->HW_privdata; // printk("Rx STAT=0x%08x int_info=0x%08x rx_desc_ptr=%d rx_desc.status=0x%01x\n", @@ -1125,7 +1125,7 @@ if (dev != NULL) { - ch = (struct comx_channel *)dev->priv; + ch = netdev_priv(dev); hw = (struct slicecom_privdata *)ch->HW_privdata; rx_status = hw->rx_desc[hw->rx_desc_ptr].status; @@ -1261,7 +1261,7 @@ goto go_for_next_tx_interrupt; } - ch = (struct comx_channel *)dev->priv; + ch = netdev_priv(dev); hw = (struct slicecom_privdata *)ch->HW_privdata; // printk("Tx STAT=0x%08x int_info=0x%08x tiq_ptr=%d\n", stat, int_info.all, board->tiq_ptr ); @@ -1295,7 +1295,7 @@ { int newbusy; - ch = (struct comx_channel *)dev->priv; + ch = netdev_priv(dev); hw = (struct slicecom_privdata *)ch->HW_privdata; /* We don't trust the "Tx available" info from the TIQ, but check */ @@ -1398,7 +1398,7 @@ static int MUNICH_open(struct net_device *dev) { - struct comx_channel *ch = dev->priv; + struct comx_channel *ch = netdev_priv(dev); struct slicecom_privdata *hw = ch->HW_privdata; struct proc_dir_entry *procfile = ch->procdir->subdir; munich_board_t *board; @@ -1891,7 +1891,7 @@ static int MUNICH_close(struct net_device *dev) { - struct comx_channel *ch = dev->priv; + struct comx_channel *ch = netdev_priv(dev); struct slicecom_privdata *hw = ch->HW_privdata; struct proc_dir_entry *procfile = ch->procdir->subdir; munich_board_t *board; @@ -2028,7 +2028,7 @@ static int MUNICH_minden(struct net_device *dev, char *page) { - struct comx_channel *ch = dev->priv; + struct comx_channel *ch = netdev_priv(dev); struct slicecom_privdata *hw = ch->HW_privdata; munich_board_t *board; struct net_device *devp; @@ -2290,7 +2290,7 @@ { struct proc_dir_entry *file = (struct proc_dir_entry *)data; struct net_device *dev = file->parent->data; - struct comx_channel *ch = dev->priv; + struct comx_channel *ch = netdev_priv(dev); struct slicecom_privdata *hw = ch->HW_privdata; munich_board_t *board; @@ -2388,7 +2388,7 @@ { struct proc_dir_entry *entry = (struct proc_dir_entry *)data; struct net_device *dev = (struct net_device *)entry->parent->data; - struct comx_channel *ch = dev->priv; + struct comx_channel *ch = netdev_priv(dev); struct slicecom_privdata *hw = ch->HW_privdata; munich_board_t *board; @@ -2656,7 +2656,7 @@ static int BOARD_init(struct net_device *dev) { - struct comx_channel *ch = (struct comx_channel *)dev->priv; + struct comx_channel *ch = netdev_priv(dev); struct slicecom_privdata *hw; struct proc_dir_entry *new_file; @@ -2772,7 +2772,7 @@ */ static int BOARD_exit(struct net_device *dev) { - struct comx_channel *ch = (struct comx_channel *)dev->priv; + struct comx_channel *ch = netdev_priv(dev); /* Free private data area */ // board = hw->boardnum + (ch->hardware == &pcicomhw ? pcicom_boards : slicecom_boards); diff -Nru a/drivers/net/wan/comx.c b/drivers/net/wan/comx.c --- a/drivers/net/wan/comx.c Sun Mar 14 14:20:07 2004 +++ b/drivers/net/wan/comx.c Sun Mar 14 14:20:07 2004 @@ -119,7 +119,7 @@ int comx_debug(struct net_device *dev, char *fmt, ...) { - struct comx_channel *ch = dev->priv; + struct comx_channel *ch = netdev_priv(dev); char *page,*str; va_list args; int len; @@ -162,7 +162,7 @@ int comx_debug_skb(struct net_device *dev, struct sk_buff *skb, char *msg) { - struct comx_channel *ch = dev->priv; + struct comx_channel *ch = netdev_priv(dev); if (!ch->debug_area) return 0; if (!skb) comx_debug(dev, "%s: %s NULL skb\n\n", dev->name, msg); @@ -175,7 +175,7 @@ char *msg) { int pos = 0; - struct comx_channel *ch = dev->priv; + struct comx_channel *ch = netdev_priv(dev); if (!ch->debug_area) return 0; @@ -207,7 +207,7 @@ static void comx_loadavg_timerfun(unsigned long d) { struct net_device *dev = (struct net_device *)d; - struct comx_channel *ch = dev->priv; + struct comx_channel *ch = netdev_priv(dev); ch->avg_bytes[ch->loadavg_counter] = ch->current_stats->rx_bytes; ch->avg_bytes[ch->loadavg_counter + ch->loadavg_size] = @@ -222,7 +222,7 @@ static void comx_reset_timerfun(unsigned long d) { struct net_device *dev = (struct net_device *)d; - struct comx_channel *ch = dev->priv; + struct comx_channel *ch = netdev_priv(dev); if(!(ch->line_status & (PROTO_LOOP | PROTO_UP))) { if(test_and_set_bit(0,&ch->reset_pending) && ch->HW_reset) { @@ -236,7 +236,7 @@ static int comx_open(struct net_device *dev) { - struct comx_channel *ch = dev->priv; + struct comx_channel *ch = netdev_priv(dev); struct proc_dir_entry *comxdir = ch->procdir->subdir; int ret=0; @@ -268,7 +268,7 @@ static int comx_close(struct net_device *dev) { - struct comx_channel *ch = dev->priv; + struct comx_channel *ch = netdev_priv(dev); struct proc_dir_entry *comxdir = ch->procdir->subdir; int ret = -ENODEV; @@ -303,7 +303,7 @@ void comx_status(struct net_device *dev, int status) { - struct comx_channel *ch = dev->priv; + struct comx_channel *ch = netdev_priv(dev); #if 0 if(status & (PROTO_UP | PROTO_LOOP)) { @@ -321,7 +321,7 @@ static int comx_xmit(struct sk_buff *skb, struct net_device *dev) { - struct comx_channel *ch = dev->priv; + struct comx_channel *ch = netdev_priv(dev); int rc; if (skb->len > dev->mtu + dev->hard_header_len) { @@ -342,7 +342,7 @@ static int comx_header(struct sk_buff *skb, struct net_device *dev, unsigned short type, void *daddr, void *saddr, unsigned len) { - struct comx_channel *ch = dev->priv; + struct comx_channel *ch = netdev_priv(dev); if (ch->LINE_header) { return (ch->LINE_header(skb, dev, type, daddr, saddr, len)); @@ -354,7 +354,7 @@ static int comx_rebuild_header(struct sk_buff *skb) { struct net_device *dev = skb->dev; - struct comx_channel *ch = dev->priv; + struct comx_channel *ch = netdev_priv(dev); if (ch->LINE_rebuild_header) { return(ch->LINE_rebuild_header(skb)); @@ -365,7 +365,7 @@ int comx_rx(struct net_device *dev, struct sk_buff *skb) { - struct comx_channel *ch = dev->priv; + struct comx_channel *ch = netdev_priv(dev); if (ch->debug_flags & DEBUG_COMX_RX) { comx_debug_skb(dev, skb, "comx_rx skb"); @@ -379,7 +379,7 @@ static struct net_device_stats *comx_stats(struct net_device *dev) { - struct comx_channel *ch = (struct comx_channel *)dev->priv; + struct comx_channel *ch = netdev_priv(dev); return ch->current_stats; } @@ -387,7 +387,7 @@ void comx_lineup_func(unsigned long d) { struct net_device *dev = (struct net_device *)d; - struct comx_channel *ch = dev->priv; + struct comx_channel *ch = netdev_priv(dev); del_timer(&ch->lineup_timer); clear_bit(0, &ch->lineup_pending); @@ -405,7 +405,7 @@ static int comx_statistics(struct net_device *dev, char *page) { - struct comx_channel *ch = dev->priv; + struct comx_channel *ch = netdev_priv(dev); int len = 0; int tmp; int i = 0; @@ -472,7 +472,7 @@ static int comx_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) { - struct comx_channel *ch = dev->priv; + struct comx_channel *ch = netdev_priv(dev); if (ch->LINE_ioctl) { return(ch->LINE_ioctl(dev, ifr, cmd)); @@ -535,7 +535,7 @@ { struct proc_dir_entry *file = (struct proc_dir_entry *)data; struct net_device *dev = file->parent->data; - struct comx_channel *ch=(struct comx_channel *)dev->priv; + struct comx_channel *ch = netdev_priv(dev); int len = 0; if (strcmp(file->name, FILENAME_STATUS) == 0) { @@ -599,7 +599,7 @@ { struct proc_dir_entry *entry = (struct proc_dir_entry *)data; struct net_device *dev = (struct net_device *)entry->parent->data; - struct comx_channel *ch=(struct comx_channel *)dev->priv; + struct comx_channel *ch = netdev_priv(dev); char *page; struct comx_hardware *hw = comx_channels; struct comx_protocol *line = comx_lines; @@ -821,7 +821,7 @@ if (register_netdevice(dev)) { goto cleanup_filename_debug; } - ch=dev->priv; + ch = netdev_priv(dev); if((ch->if_ptr = (void *)kmalloc(sizeof(struct ppp_device), GFP_KERNEL)) == NULL) { goto cleanup_register; @@ -874,7 +874,7 @@ lock_kernel(); dev = entry->data; - ch = dev->priv; + ch = netdev_priv(dev); if (dev->flags & IFF_UP) { printk(KERN_ERR "%s: down interface before removing it\n", dev->name); unlock_kernel(); diff -Nru a/drivers/net/wan/cosa.c b/drivers/net/wan/cosa.c --- a/drivers/net/wan/cosa.c Sun Mar 14 14:20:06 2004 +++ b/drivers/net/wan/cosa.c Sun Mar 14 14:20:06 2004 @@ -639,7 +639,7 @@ static int cosa_sppp_open(struct net_device *d) { - struct channel_data *chan = d->priv; + struct channel_data *chan = netdev_priv(d); int err; unsigned long flags; @@ -679,7 +679,7 @@ static int cosa_sppp_tx(struct sk_buff *skb, struct net_device *dev) { - struct channel_data *chan = dev->priv; + struct channel_data *chan = netdev_priv(dev); netif_stop_queue(dev); @@ -690,7 +690,7 @@ static void cosa_sppp_timeout(struct net_device *dev) { - struct channel_data *chan = dev->priv; + struct channel_data *chan = netdev_priv(dev); if (test_bit(RXBIT, &chan->cosa->rxtx)) { chan->stats.rx_errors++; @@ -709,7 +709,7 @@ static int cosa_sppp_close(struct net_device *d) { - struct channel_data *chan = d->priv; + struct channel_data *chan = netdev_priv(d); unsigned long flags; netif_stop_queue(d); @@ -789,7 +789,7 @@ static struct net_device_stats *cosa_net_stats(struct net_device *dev) { - struct channel_data *chan = dev->priv; + struct channel_data *chan = netdev_priv(dev); return &chan->stats; } @@ -807,7 +807,7 @@ { DECLARE_WAITQUEUE(wait, current); unsigned long flags; - struct channel_data *chan = (struct channel_data *)file->private_data; + struct channel_data *chan = file->private_data; struct cosa_data *cosa = chan->cosa; char *kbuf; @@ -881,7 +881,7 @@ const char *buf, size_t count, loff_t *ppos) { DECLARE_WAITQUEUE(wait, current); - struct channel_data *chan = (struct channel_data *)file->private_data; + struct channel_data *chan = file->private_data; struct cosa_data *cosa = chan->cosa; unsigned long flags; char *kbuf; @@ -990,7 +990,7 @@ static int cosa_release(struct inode *inode, struct file *file) { - struct channel_data *channel = (struct channel_data *)file->private_data; + struct channel_data *channel = file->private_data; struct cosa_data *cosa; unsigned long flags; @@ -1205,7 +1205,7 @@ int cmd) { int rv; - struct channel_data *chan = (struct channel_data *)dev->priv; + struct channel_data *chan = netdev_priv(dev); rv = cosa_ioctl_common(chan->cosa, chan, cmd, (unsigned long)ifr->ifr_data); if (rv == -ENOIOCTLCMD) { return sppp_do_ioctl(dev, ifr, cmd); @@ -1216,7 +1216,7 @@ static int cosa_chardev_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) { - struct channel_data *channel = (struct channel_data *)file->private_data; + struct channel_data *channel = file->private_data; struct cosa_data *cosa = channel->cosa; return cosa_ioctl_common(cosa, channel, cmd, arg); } diff -Nru a/drivers/net/wan/dscc4.c b/drivers/net/wan/dscc4.c --- a/drivers/net/wan/dscc4.c Sun Mar 14 14:20:06 2004 +++ b/drivers/net/wan/dscc4.c Sun Mar 14 14:20:06 2004 @@ -652,7 +652,6 @@ goto refill; } pkt_len = TO_SIZE(rx_fd->state2); - pci_dma_sync_single(pdev, rx_fd->data, pkt_len, PCI_DMA_FROMDEVICE); pci_unmap_single(pdev, rx_fd->data, RX_MAX(HDLC_MAX_MRU), PCI_DMA_FROMDEVICE); if ((skb->data[--pkt_len] & FrameOk) == FrameOk) { stats->rx_packets++; diff -Nru a/drivers/net/wan/lapbether.c b/drivers/net/wan/lapbether.c --- a/drivers/net/wan/lapbether.c Sun Mar 14 14:20:07 2004 +++ b/drivers/net/wan/lapbether.c Sun Mar 14 14:20:07 2004 @@ -198,7 +198,7 @@ static void lapbeth_data_transmit(struct net_device *ndev, struct sk_buff *skb) { - struct lapbethdev *lapbeth = ndev->priv; + struct lapbethdev *lapbeth = netdev_priv(ndev); unsigned char *ptr; struct net_device *dev; int size = skb->len; @@ -269,7 +269,7 @@ */ static struct net_device_stats *lapbeth_get_stats(struct net_device *dev) { - struct lapbethdev *lapbeth = (struct lapbethdev *)dev->priv; + struct lapbethdev *lapbeth = netdev_priv(dev); return &lapbeth->stats; } @@ -278,7 +278,7 @@ */ static int lapbeth_set_mac_address(struct net_device *dev, void *addr) { - struct sockaddr *sa = (struct sockaddr *)addr; + struct sockaddr *sa = addr; memcpy(dev->dev_addr, sa->sa_data, dev->addr_len); return 0; } @@ -355,7 +355,7 @@ if (!ndev) goto out; - lapbeth = ndev->priv; + lapbeth = netdev_priv(ndev); lapbeth->axdev = ndev; dev_hold(dev); @@ -397,7 +397,7 @@ unsigned long event, void *ptr) { struct lapbethdev *lapbeth; - struct net_device *dev = (struct net_device *)ptr; + struct net_device *dev = ptr; if (!dev_is_ethdev(dev)) return NOTIFY_DONE; diff -Nru a/drivers/net/wd.c b/drivers/net/wd.c --- a/drivers/net/wd.c Sun Mar 14 14:20:06 2004 +++ b/drivers/net/wd.c Sun Mar 14 14:20:06 2004 @@ -333,6 +333,9 @@ ei_status.get_8390_hdr = &wd_get_8390_hdr; dev->open = &wd_open; dev->stop = &wd_close; +#ifdef CONFIG_NET_POLL_CONTROLLER + dev->poll_controller = ei_poll; +#endif NS8390_init(dev, 0); #if 1 diff -Nru a/drivers/net/wireless/Kconfig b/drivers/net/wireless/Kconfig --- a/drivers/net/wireless/Kconfig Sun Mar 14 14:20:06 2004 +++ b/drivers/net/wireless/Kconfig Sun Mar 14 14:20:06 2004 @@ -307,6 +307,53 @@ It has basic support for Linux wireless extensions and initial micro support for ethtool. +comment "Prism GT/Duette 802.11(a/b/g) PCI/PCMCIA support" + depends on NET_RADIO && PCI +config PRISM54 + tristate 'Intersil Prism GT/Duette/Indigo PCI/PCMCIA' + depends on PCI && NET_RADIO && EXPERIMENTAL && HOTPLUG + select FW_LOADER + ---help--- + Enable PCI and Cardbus support for the following chipset based cards: + + ISL3880 - Prism GT 802.11 b/g + ISL3877 - Prism Indigo 802.11 a + ISL3890 - Prism Duette 802.11 a/b/g + + For a complete list of supported cards visit . + Here is the latest confirmed list of supported cards: + + 3com OfficeConnect 11g Cardbus Card aka 3CRWE154G72 + Allnet ALL0271 PCI Card + Compex WL54G Cardbus Card + Corega CG-WLCB54GT Cardbus Card + D-Link Air Plus Xtreme G A1 Cardbus Card aka DWL-g650 + I-O Data WN-G54/CB Cardbus Card + Kobishi XG-300 aka Z-Com Cardbus Card + Netgear WG511 Cardbus Card + Ovislink WL-5400PCI PCI Card + Peabird WLG-PCI PCI Card + Sitecom WL-100i Cardbus Card + Sitecom WL-110i PCI Card + SMC2802W - EZ Connect g 2.4GHz 54 Mbps Wireless PCI Card + SMC2835W - EZ Connect g 2.4GHz 54 Mbps Wireless Cardbus Card + Z-Com XG-900 PCI Card + Zyxel G-100 Cardbus Card + + If you enable this you will need a firmware file as well. + You will need to copy this to /usr/lib/hotplug/firmware/isl3890. + You can get this non-GPL'd firmware file from the Prism54 project page: + + You will also need the /etc/hotplug/firmware.agent script from + a current hotplug package. + + Note: You need a motherboard with DMA support to use any of these cards + + If you want to compile the driver as a module ( = code which can be + inserted in and removed from the running kernel whenever you want), + say M here and read . The module + will be called prism54.ko. + # yes, this works even when no drivers are selected config NET_WIRELESS bool diff -Nru a/drivers/net/wireless/Makefile b/drivers/net/wireless/Makefile --- a/drivers/net/wireless/Makefile Sun Mar 14 14:20:09 2004 +++ b/drivers/net/wireless/Makefile Sun Mar 14 14:20:09 2004 @@ -26,6 +26,8 @@ obj-$(CONFIG_PCI_ATMEL) += atmel_pci.o obj-$(CONFIG_PCMCIA_ATMEL) += atmel_cs.o +obj-$(CONFIG_PRISM54) += prism54/ + # 16-bit wireless PCMCIA client drivers obj-$(CONFIG_PCMCIA_RAYCS) += ray_cs.o obj-$(CONFIG_PCMCIA_WL3501) += wl3501_cs.o diff -Nru a/drivers/net/wireless/airo.c b/drivers/net/wireless/airo.c --- a/drivers/net/wireless/airo.c Sun Mar 14 14:20:06 2004 +++ b/drivers/net/wireless/airo.c Sun Mar 14 14:20:06 2004 @@ -1505,7 +1505,7 @@ seq = micSeq - (context->window - 33); //Too old of a SEQ number to check. - if ((u32)seq < 0) + if ((s32)seq < 0) return ERROR; if ( seq > 64 ) { diff -Nru a/drivers/net/wireless/atmel.c b/drivers/net/wireless/atmel.c --- a/drivers/net/wireless/atmel.c Sun Mar 14 14:20:06 2004 +++ b/drivers/net/wireless/atmel.c Sun Mar 14 14:20:06 2004 @@ -796,7 +796,7 @@ static int start_tx (struct sk_buff *skb, struct net_device *dev) { - struct atmel_private *priv = (struct atmel_private *)dev->priv; + struct atmel_private *priv = netdev_priv(dev); struct ieee802_11_hdr header; unsigned long flags; u16 buff, frame_ctl, len = (ETH_ZLEN < skb->len) ? skb->len : ETH_ZLEN; @@ -1167,7 +1167,7 @@ static irqreturn_t service_interrupt(int irq, void *dev_id, struct pt_regs *regs) { struct net_device *dev = (struct net_device *) dev_id; - struct atmel_private *priv = (struct atmel_private *) dev->priv; + struct atmel_private *priv = netdev_priv(dev); u8 isr; if (priv->card && priv->present_callback && @@ -1234,13 +1234,13 @@ static struct net_device_stats *atmel_get_stats (struct net_device *dev) { - struct atmel_private *priv = (struct atmel_private *)dev->priv; + struct atmel_private *priv = netdev_priv(dev); return &priv->stats; } static struct iw_statistics *atmel_get_wireless_stats (struct net_device *dev) { - struct atmel_private *priv = (struct atmel_private *)dev->priv; + struct atmel_private *priv = netdev_priv(dev); /* update the link quality here in case we are seeing no beacons at all to drive the process */ @@ -1287,7 +1287,7 @@ static int atmel_open (struct net_device *dev) { - struct atmel_private *priv = (struct atmel_private *) dev->priv; + struct atmel_private *priv = netdev_priv(dev); priv->station_state = STATION_STATE_INITIALIZING; if (!reset_atmel_card(dev)) { priv->station_state = STATION_STATE_DOWN; @@ -1298,7 +1298,7 @@ static int atmel_close (struct net_device *dev) { - struct atmel_private *priv = (struct atmel_private *) dev->priv; + struct atmel_private *priv = netdev_priv(dev); netif_carrier_off(dev); if (netif_running(dev)) @@ -1378,7 +1378,7 @@ static int atmel_read_proc(char *page, char **start, off_t off, int count, int *eof, void *data) { - struct atmel_private *priv = (struct atmel_private *)data; + struct atmel_private *priv = data; int len = atmel_proc_output (page, priv); if (len <= off+count) *eof = 1; *start = page + off; @@ -1406,7 +1406,7 @@ goto err_out_free; } - priv = dev->priv; + priv = netdev_priv(dev); priv->dev = dev; priv->sys_dev = sys_dev; priv->present_callback = card_present; @@ -1525,7 +1525,7 @@ void stop_atmel_card(struct net_device *dev, int freeres) { - struct atmel_private *priv = dev->priv; + struct atmel_private *priv = netdev_priv(dev); /* put a brick on it... */ if (priv->bus_type == BUS_TYPE_PCCARD) @@ -1582,7 +1582,7 @@ struct iw_point *dwrq, char *extra) { - struct atmel_private *priv = dev->priv; + struct atmel_private *priv = netdev_priv(dev); /* Check if we asked for `any' */ if(dwrq->flags == 0) { @@ -1610,7 +1610,7 @@ struct iw_point *dwrq, char *extra) { - struct atmel_private *priv = dev->priv; + struct atmel_private *priv = netdev_priv(dev); /* Get the current SSID */ if (priv->SSID_size == 0) { @@ -1633,7 +1633,7 @@ struct sockaddr *awrq, char *extra) { - struct atmel_private *priv = dev->priv; + struct atmel_private *priv = netdev_priv(dev); memcpy(awrq->sa_data, priv->CurrentBSSID, 6); awrq->sa_family = ARPHRD_ETHER; @@ -1645,7 +1645,7 @@ struct iw_point *dwrq, char *extra) { - struct atmel_private *priv = dev->priv; + struct atmel_private *priv = netdev_priv(dev); /* Basic checking: do we have a key to set ? * Note : with the new API, it's impossible to get a NULL pointer. @@ -1736,7 +1736,7 @@ struct iw_point *dwrq, char *extra) { - struct atmel_private *priv = dev->priv; + struct atmel_private *priv = netdev_priv(dev); int index = (dwrq->flags & IW_ENCODE_INDEX) - 1; if (!priv->wep_is_on) @@ -1776,7 +1776,7 @@ struct iw_param *vwrq, char *extra) { - struct atmel_private *priv = dev->priv; + struct atmel_private *priv = netdev_priv(dev); if (vwrq->fixed == 0) { priv->tx_rate = 3; @@ -1808,7 +1808,7 @@ __u32 *uwrq, char *extra) { - struct atmel_private *priv = dev->priv; + struct atmel_private *priv = netdev_priv(dev); if (*uwrq != IW_MODE_ADHOC && *uwrq != IW_MODE_INFRA) return -EINVAL; @@ -1822,7 +1822,7 @@ __u32 *uwrq, char *extra) { - struct atmel_private *priv = dev->priv; + struct atmel_private *priv = netdev_priv(dev); *uwrq = priv->operating_mode; return 0; @@ -1833,7 +1833,7 @@ struct iw_param *vwrq, char *extra) { - struct atmel_private *priv = dev->priv; + struct atmel_private *priv = netdev_priv(dev); if (priv->auto_tx_rate) { vwrq->fixed = 0; @@ -1855,7 +1855,7 @@ struct iw_param *vwrq, char *extra) { - struct atmel_private *priv = dev->priv; + struct atmel_private *priv = netdev_priv(dev); priv->power_mode = vwrq->disabled ? 0 : 1; return -EINPROGRESS; } @@ -1865,7 +1865,7 @@ struct iw_param *vwrq, char *extra) { - struct atmel_private *priv = dev->priv; + struct atmel_private *priv = netdev_priv(dev); vwrq->disabled = priv->power_mode ? 0 : 1; vwrq->flags = IW_POWER_ON; return 0; @@ -1876,7 +1876,7 @@ struct iw_param *vwrq, char *extra) { - struct atmel_private *priv = dev->priv; + struct atmel_private *priv = netdev_priv(dev); if(!vwrq->disabled && (vwrq->flags & IW_RETRY_LIMIT)) { if(vwrq->flags & IW_RETRY_MAX) @@ -1899,7 +1899,7 @@ struct iw_param *vwrq, char *extra) { - struct atmel_private *priv = dev->priv; + struct atmel_private *priv = netdev_priv(dev); vwrq->disabled = 0; /* Can't be disabled */ @@ -1922,7 +1922,7 @@ struct iw_param *vwrq, char *extra) { - struct atmel_private *priv = dev->priv; + struct atmel_private *priv = netdev_priv(dev); int rthr = vwrq->value; if(vwrq->disabled) @@ -1940,7 +1940,7 @@ struct iw_param *vwrq, char *extra) { - struct atmel_private *priv = dev->priv; + struct atmel_private *priv = netdev_priv(dev); vwrq->value = priv->rts_threshold; vwrq->disabled = (vwrq->value >= 2347); @@ -1954,7 +1954,7 @@ struct iw_param *vwrq, char *extra) { - struct atmel_private *priv = dev->priv; + struct atmel_private *priv = netdev_priv(dev); int fthr = vwrq->value; if(vwrq->disabled) @@ -1973,7 +1973,7 @@ struct iw_param *vwrq, char *extra) { - struct atmel_private *priv = dev->priv; + struct atmel_private *priv = netdev_priv(dev); vwrq->value = priv->frag_threshold; vwrq->disabled = (vwrq->value >= 2346); @@ -1990,7 +1990,7 @@ struct iw_freq *fwrq, char *extra) { - struct atmel_private *priv = dev->priv; + struct atmel_private *priv = netdev_priv(dev); int rc = -EINPROGRESS; /* Call commit handler */ /* If setting by frequency, convert to a channel */ @@ -2024,7 +2024,7 @@ struct iw_freq *fwrq, char *extra) { - struct atmel_private *priv = dev->priv; + struct atmel_private *priv = netdev_priv(dev); fwrq->m = priv->channel; fwrq->e = 0; @@ -2036,7 +2036,7 @@ struct iw_param *vwrq, char *extra) { - struct atmel_private *priv = dev->priv; + struct atmel_private *priv = netdev_priv(dev); /* Note : you may have realised that, as this is a SET operation, * this is privileged and therefore a normal user can't @@ -2074,7 +2074,7 @@ struct iw_point *dwrq, char *extra) { - struct atmel_private *priv = dev->priv; + struct atmel_private *priv = netdev_priv(dev); int i; char *current_ev = extra; struct iw_event iwe; @@ -2126,7 +2126,7 @@ struct iw_point *dwrq, char *extra) { - struct atmel_private *priv = dev->priv; + struct atmel_private *priv = netdev_priv(dev); struct iw_range *range = (struct iw_range *) extra; int k,i,j; @@ -2193,7 +2193,7 @@ struct sockaddr *awrq, char *extra) { - struct atmel_private *priv = dev->priv; + struct atmel_private *priv = netdev_priv(dev); int i; static const u8 bcast[] = { 255, 255, 255, 255, 255, 255 }; @@ -2318,7 +2318,7 @@ static int atmel_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) { int rc = 0; - struct atmel_private *priv = (struct atmel_private *) dev->priv; + struct atmel_private *priv = netdev_priv(dev); atmel_priv_ioctl com; struct iwreq *wrq = (struct iwreq *) rq; unsigned char *new_firmware; @@ -3053,7 +3053,7 @@ static void atmel_management_timer(u_long a) { struct net_device *dev = (struct net_device *) a; - struct atmel_private *priv = (struct atmel_private *)dev->priv; + struct atmel_private *priv = netdev_priv(dev); unsigned long flags; /* Check if the card has been yanked. */ @@ -3297,7 +3297,7 @@ static int probe_atmel_card(struct net_device *dev) { int rc = 0; - struct atmel_private *priv = dev->priv; + struct atmel_private *priv = netdev_priv(dev); /* reset pccard */ if (priv->bus_type == BUS_TYPE_PCCARD) @@ -3486,7 +3486,7 @@ which is the route into the rest of the firmare datastructures. */ int channel; - struct atmel_private *priv = dev->priv; + struct atmel_private *priv = netdev_priv(dev); u8 configuration; /* data to add to the firmware names, in priority order diff -Nru a/drivers/net/wireless/orinoco.c b/drivers/net/wireless/orinoco.c --- a/drivers/net/wireless/orinoco.c Sun Mar 14 14:20:08 2004 +++ b/drivers/net/wireless/orinoco.c Sun Mar 14 14:20:09 2004 @@ -599,7 +599,7 @@ int __orinoco_up(struct net_device *dev) { - struct orinoco_private *priv = dev->priv; + struct orinoco_private *priv = netdev_priv(dev); struct hermes *hw = &priv->hw; int err; @@ -626,7 +626,7 @@ int __orinoco_down(struct net_device *dev) { - struct orinoco_private *priv = dev->priv; + struct orinoco_private *priv = netdev_priv(dev); struct hermes *hw = &priv->hw; int err; @@ -657,7 +657,7 @@ int orinoco_reinit_firmware(struct net_device *dev) { - struct orinoco_private *priv = dev->priv; + struct orinoco_private *priv = netdev_priv(dev); struct hermes *hw = &priv->hw; int err; @@ -685,7 +685,7 @@ static int orinoco_open(struct net_device *dev) { - struct orinoco_private *priv = dev->priv; + struct orinoco_private *priv = netdev_priv(dev); unsigned long flags; int err; @@ -705,7 +705,7 @@ int orinoco_stop(struct net_device *dev) { - struct orinoco_private *priv = dev->priv; + struct orinoco_private *priv = netdev_priv(dev); int err = 0; /* We mustn't use orinoco_lock() here, because we need to be @@ -724,7 +724,7 @@ static int __orinoco_program_rids(struct net_device *dev) { - struct orinoco_private *priv = dev->priv; + struct orinoco_private *priv = netdev_priv(dev); hermes_t *hw = &priv->hw; int err; struct hermes_idstring idbuf; @@ -912,7 +912,7 @@ /* xyzzy */ static int orinoco_reconfigure(struct net_device *dev) { - struct orinoco_private *priv = dev->priv; + struct orinoco_private *priv = netdev_priv(dev); struct hermes *hw = &priv->hw; unsigned long flags; int err = 0; @@ -965,7 +965,7 @@ * schedule_work() */ static void orinoco_reset(struct net_device *dev) { - struct orinoco_private *priv = dev->priv; + struct orinoco_private *priv = netdev_priv(dev); struct hermes *hw = &priv->hw; int err; unsigned long flags; @@ -1070,7 +1070,7 @@ static void orinoco_set_multicast_list(struct net_device *dev) { - struct orinoco_private *priv = dev->priv; + struct orinoco_private *priv = netdev_priv(dev); unsigned long flags; if (orinoco_lock(priv, &flags) != 0) { @@ -1433,7 +1433,7 @@ irqreturn_t orinoco_interrupt(int irq, void *dev_id, struct pt_regs *regs) { struct net_device *dev = (struct net_device *)dev_id; - struct orinoco_private *priv = dev->priv; + struct orinoco_private *priv = netdev_priv(dev); hermes_t *hw = &priv->hw; int count = MAX_IRQLOOPS_PER_IRQ; u16 evstat, events; @@ -1561,7 +1561,7 @@ static void __orinoco_ev_info(struct net_device *dev, hermes_t *hw) { - struct orinoco_private *priv = dev->priv; + struct orinoco_private *priv = netdev_priv(dev); u16 infofid; struct { u16 len; @@ -1662,7 +1662,7 @@ static void __orinoco_ev_rx(struct net_device *dev, hermes_t *hw) { - struct orinoco_private *priv = dev->priv; + struct orinoco_private *priv = netdev_priv(dev); struct net_device_stats *stats = &priv->stats; struct iw_statistics *wstats = &priv->wstats; struct sk_buff *skb = NULL; @@ -1814,7 +1814,7 @@ static void __orinoco_ev_txexc(struct net_device *dev, hermes_t *hw) { - struct orinoco_private *priv = dev->priv; + struct orinoco_private *priv = netdev_priv(dev); struct net_device_stats *stats = &priv->stats; u16 fid = hermes_read_regn(hw, TXCOMPLFID); struct hermes_tx_descriptor desc; @@ -1840,7 +1840,7 @@ static void __orinoco_ev_tx(struct net_device *dev, hermes_t *hw) { - struct orinoco_private *priv = dev->priv; + struct orinoco_private *priv = netdev_priv(dev); struct net_device_stats *stats = &priv->stats; stats->tx_packets++; @@ -1850,7 +1850,7 @@ static void __orinoco_ev_alloc(struct net_device *dev, hermes_t *hw) { - struct orinoco_private *priv = dev->priv; + struct orinoco_private *priv = netdev_priv(dev); u16 fid = hermes_read_regn(hw, ALLOCFID); @@ -1886,7 +1886,7 @@ static void determine_firmware(struct net_device *dev) { - struct orinoco_private *priv = dev->priv; + struct orinoco_private *priv = netdev_priv(dev); hermes_t *hw = &priv->hw; int err; struct sta_id sta_id; @@ -2024,7 +2024,7 @@ static int orinoco_init(struct net_device *dev) { - struct orinoco_private *priv = dev->priv; + struct orinoco_private *priv = netdev_priv(dev); hermes_t *hw = &priv->hw; int err = 0; struct hermes_idstring nickbuf; @@ -2204,7 +2204,7 @@ struct net_device_stats * orinoco_get_stats(struct net_device *dev) { - struct orinoco_private *priv = dev->priv; + struct orinoco_private *priv = netdev_priv(dev); return &priv->stats; } @@ -2212,7 +2212,7 @@ struct iw_statistics * orinoco_get_wireless_stats(struct net_device *dev) { - struct orinoco_private *priv = dev->priv; + struct orinoco_private *priv = netdev_priv(dev); hermes_t *hw = &priv->hw; struct iw_statistics *wstats = &priv->wstats; int err = 0; @@ -2271,7 +2271,7 @@ static inline void orinoco_spy_gather(struct net_device *dev, u_char *mac, int level, int noise) { - struct orinoco_private *priv = (struct orinoco_private *)dev->priv; + struct orinoco_private *priv = netdev_priv(dev); int i; /* Gather wireless spy statistics: for each packet, compare the @@ -2290,7 +2290,7 @@ struct sk_buff *skb, struct hermes_rx_descriptor *desc) { - struct orinoco_private *priv = (struct orinoco_private *)dev->priv; + struct orinoco_private *priv = netdev_priv(dev); /* Using spy support with lots of Rx packets, like in an * infrastructure (AP), will really slow down everything, because @@ -2311,7 +2311,7 @@ static int orinoco_xmit(struct sk_buff *skb, struct net_device *dev) { - struct orinoco_private *priv = (struct orinoco_private *)dev->priv; + struct orinoco_private *priv = netdev_priv(dev); struct net_device_stats *stats = &priv->stats; hermes_t *hw = &priv->hw; int err = 0; @@ -2449,7 +2449,7 @@ static void orinoco_tx_timeout(struct net_device *dev) { - struct orinoco_private *priv = (struct orinoco_private *)dev->priv; + struct orinoco_private *priv = netdev_priv(dev); struct net_device_stats *stats = &priv->stats; struct hermes *hw = &priv->hw; @@ -2466,7 +2466,7 @@ static int orinoco_change_mtu(struct net_device *dev, int new_mtu) { - struct orinoco_private *priv = dev->priv; + struct orinoco_private *priv = netdev_priv(dev); if ( (new_mtu < ORINOCO_MIN_MTU) || (new_mtu > ORINOCO_MAX_MTU) ) return -EINVAL; @@ -2484,7 +2484,7 @@ static void __orinoco_set_multicast_list(struct net_device *dev) { - struct orinoco_private *priv = dev->priv; + struct orinoco_private *priv = netdev_priv(dev); hermes_t *hw = &priv->hw; int err = 0; int promisc, mc_count; @@ -2554,7 +2554,7 @@ static int orinoco_ioctl_getiwrange(struct net_device *dev, struct iw_point *rrq) { - struct orinoco_private *priv = dev->priv; + struct orinoco_private *priv = netdev_priv(dev); int err = 0; int mode; struct iw_range range; @@ -2699,7 +2699,7 @@ static int orinoco_ioctl_setiwencode(struct net_device *dev, struct iw_point *erq) { - struct orinoco_private *priv = dev->priv; + struct orinoco_private *priv = netdev_priv(dev); int index = (erq->flags & IW_ENCODE_INDEX) - 1; int setindex = priv->tx_key; int enable = priv->wep_on; @@ -2794,7 +2794,7 @@ static int orinoco_ioctl_getiwencode(struct net_device *dev, struct iw_point *erq) { - struct orinoco_private *priv = dev->priv; + struct orinoco_private *priv = netdev_priv(dev); int index = (erq->flags & IW_ENCODE_INDEX) - 1; u16 xlen = 0; char keybuf[ORINOCO_MAX_KEY_SIZE]; @@ -2841,7 +2841,7 @@ static int orinoco_ioctl_setessid(struct net_device *dev, struct iw_point *erq) { - struct orinoco_private *priv = dev->priv; + struct orinoco_private *priv = netdev_priv(dev); char essidbuf[IW_ESSID_MAX_SIZE+1]; int err; unsigned long flags; @@ -2874,7 +2874,7 @@ static int orinoco_ioctl_getessid(struct net_device *dev, struct iw_point *erq) { - struct orinoco_private *priv = dev->priv; + struct orinoco_private *priv = netdev_priv(dev); char essidbuf[IW_ESSID_MAX_SIZE+1]; int active; int err = 0; @@ -2907,7 +2907,7 @@ static int orinoco_ioctl_setnick(struct net_device *dev, struct iw_point *nrq) { - struct orinoco_private *priv = dev->priv; + struct orinoco_private *priv = netdev_priv(dev); char nickbuf[IW_ESSID_MAX_SIZE+1]; int err; unsigned long flags; @@ -2935,7 +2935,7 @@ static int orinoco_ioctl_getnick(struct net_device *dev, struct iw_point *nrq) { - struct orinoco_private *priv = dev->priv; + struct orinoco_private *priv = netdev_priv(dev); char nickbuf[IW_ESSID_MAX_SIZE+1]; int err; unsigned long flags; @@ -2957,7 +2957,7 @@ static int orinoco_ioctl_setfreq(struct net_device *dev, struct iw_freq *frq) { - struct orinoco_private *priv = dev->priv; + struct orinoco_private *priv = netdev_priv(dev); int chan = -1; int err; unsigned long flags; @@ -2999,7 +2999,7 @@ static int orinoco_ioctl_getsens(struct net_device *dev, struct iw_param *srq) { - struct orinoco_private *priv = dev->priv; + struct orinoco_private *priv = netdev_priv(dev); hermes_t *hw = &priv->hw; u16 val; int err; @@ -3025,7 +3025,7 @@ static int orinoco_ioctl_setsens(struct net_device *dev, struct iw_param *srq) { - struct orinoco_private *priv = dev->priv; + struct orinoco_private *priv = netdev_priv(dev); int val = srq->value; int err; unsigned long flags; @@ -3047,7 +3047,7 @@ static int orinoco_ioctl_setrts(struct net_device *dev, struct iw_param *rrq) { - struct orinoco_private *priv = dev->priv; + struct orinoco_private *priv = netdev_priv(dev); int val = rrq->value; int err; unsigned long flags; @@ -3070,7 +3070,7 @@ static int orinoco_ioctl_setfrag(struct net_device *dev, struct iw_param *frq) { - struct orinoco_private *priv = dev->priv; + struct orinoco_private *priv = netdev_priv(dev); int err = 0; unsigned long flags; @@ -3105,7 +3105,7 @@ static int orinoco_ioctl_getfrag(struct net_device *dev, struct iw_param *frq) { - struct orinoco_private *priv = dev->priv; + struct orinoco_private *priv = netdev_priv(dev); hermes_t *hw = &priv->hw; int err = 0; u16 val; @@ -3143,7 +3143,7 @@ static int orinoco_ioctl_setrate(struct net_device *dev, struct iw_param *rrq) { - struct orinoco_private *priv = dev->priv; + struct orinoco_private *priv = netdev_priv(dev); int err = 0; int ratemode = -1; int bitrate; /* 100s of kilobits */ @@ -3186,7 +3186,7 @@ static int orinoco_ioctl_getrate(struct net_device *dev, struct iw_param *rrq) { - struct orinoco_private *priv = dev->priv; + struct orinoco_private *priv = netdev_priv(dev); hermes_t *hw = &priv->hw; int err = 0; int ratemode; @@ -3253,7 +3253,7 @@ static int orinoco_ioctl_setpower(struct net_device *dev, struct iw_param *prq) { - struct orinoco_private *priv = dev->priv; + struct orinoco_private *priv = netdev_priv(dev); int err = 0; unsigned long flags; @@ -3306,7 +3306,7 @@ static int orinoco_ioctl_getpower(struct net_device *dev, struct iw_param *prq) { - struct orinoco_private *priv = dev->priv; + struct orinoco_private *priv = netdev_priv(dev); hermes_t *hw = &priv->hw; int err = 0; u16 enable, period, timeout, mcast; @@ -3356,7 +3356,7 @@ #if WIRELESS_EXT > 10 static int orinoco_ioctl_getretry(struct net_device *dev, struct iw_param *rrq) { - struct orinoco_private *priv = dev->priv; + struct orinoco_private *priv = netdev_priv(dev); hermes_t *hw = &priv->hw; int err = 0; u16 short_limit, long_limit, lifetime; @@ -3409,7 +3409,7 @@ static int orinoco_ioctl_setibssport(struct net_device *dev, struct iwreq *wrq) { - struct orinoco_private *priv = dev->priv; + struct orinoco_private *priv = netdev_priv(dev); int val = *( (int *) wrq->u.name ); int err; unsigned long flags; @@ -3429,7 +3429,7 @@ static int orinoco_ioctl_getibssport(struct net_device *dev, struct iwreq *wrq) { - struct orinoco_private *priv = dev->priv; + struct orinoco_private *priv = netdev_priv(dev); int *val = (int *)wrq->u.name; int err; unsigned long flags; @@ -3446,7 +3446,7 @@ static int orinoco_ioctl_setport3(struct net_device *dev, struct iwreq *wrq) { - struct orinoco_private *priv = dev->priv; + struct orinoco_private *priv = netdev_priv(dev); int val = *( (int *) wrq->u.name ); int err = 0; unsigned long flags; @@ -3488,7 +3488,7 @@ static int orinoco_ioctl_getport3(struct net_device *dev, struct iwreq *wrq) { - struct orinoco_private *priv = dev->priv; + struct orinoco_private *priv = netdev_priv(dev); int *val = (int *)wrq->u.name; int err; unsigned long flags; @@ -3507,7 +3507,7 @@ * Jean II */ static int orinoco_ioctl_setspy(struct net_device *dev, struct iw_point *srq) { - struct orinoco_private *priv = dev->priv; + struct orinoco_private *priv = netdev_priv(dev); struct sockaddr address[IW_MAX_SPY]; int number = srq->length; int i; @@ -3554,7 +3554,7 @@ static int orinoco_ioctl_getspy(struct net_device *dev, struct iw_point *srq) { - struct orinoco_private *priv = dev->priv; + struct orinoco_private *priv = netdev_priv(dev); struct sockaddr address[IW_MAX_SPY]; struct iw_quality spy_stat[IW_MAX_SPY]; int number; @@ -3601,7 +3601,7 @@ static int orinoco_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) { - struct orinoco_private *priv = dev->priv; + struct orinoco_private *priv = netdev_priv(dev); struct iwreq *wrq = (struct iwreq *)rq; int err = 0; int tmp; @@ -4057,7 +4057,7 @@ static int orinoco_debug_dump_recs(struct net_device *dev) { - struct orinoco_private *priv = dev->priv; + struct orinoco_private *priv = netdev_priv(dev); hermes_t *hw = &priv->hw; u8 *val8; u16 *val16; @@ -4131,7 +4131,7 @@ dev = alloc_etherdev(sizeof(struct orinoco_private) + sizeof_card); if (!dev) return NULL; - priv = (struct orinoco_private *)dev->priv; + priv = netdev_priv(dev); priv->ndev = dev; if (sizeof_card) priv->card = (void *)((unsigned long)dev->priv + sizeof(struct orinoco_private)); diff -Nru a/drivers/net/wireless/prism54/Makefile b/drivers/net/wireless/prism54/Makefile --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/drivers/net/wireless/prism54/Makefile Sun Mar 14 14:20:09 2004 @@ -0,0 +1,10 @@ +# $Id: Makefile.k26,v 1.7 2004/01/30 16:24:00 ajfa Exp $ + +prism54-objs := islpci_eth.o islpci_mgt.o \ + isl_38xx.o isl_ioctl.o islpci_dev.o \ + islpci_hotplug.o oid_mgt.o + +obj-$(CONFIG_PRISM54) += prism54.o + +EXTRA_CFLAGS = -I$(PWD) #-DCONFIG_PRISM54_WDS + diff -Nru a/drivers/net/wireless/prism54/isl_38xx.c b/drivers/net/wireless/prism54/isl_38xx.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/drivers/net/wireless/prism54/isl_38xx.c Sun Mar 14 14:20:09 2004 @@ -0,0 +1,397 @@ +/* $Header: /var/lib/cvs/prism54-ng/ksrc/isl_38xx.c,v 1.22 2004/02/28 03:06:07 mcgrof Exp $ + * + * Copyright (C) 2002 Intersil Americas Inc. + * Copyright (C) 2003-2004 Luis R. Rodriguez _ + * + * 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 + * + * 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 + * + */ + +#define __KERNEL_SYSCALLS__ + +#include +#include +#include +#include + +#include "isl_38xx.h" +#include + +#include +#include + +#include +#if !defined(CONFIG_FW_LOADER) && !defined(CONFIG_FW_LOADER_MODULE) +#error No Firmware Loading configured in the kernel ! +#endif + +#include "islpci_dev.h" +#include "islpci_mgt.h" + +/****************************************************************************** + Device Interface & Control functions +******************************************************************************/ + +/** + * isl38xx_disable_interrupts - disable all interrupts + * @device: pci memory base address + * + * Instructs the device to disable all interrupt reporting by asserting + * the IRQ line. New events may still show up in the interrupt identification + * register located at offset %ISL38XX_INT_IDENT_REG. + */ +void +isl38xx_disable_interrupts(void *device) +{ + isl38xx_w32_flush(device, 0x00000000, ISL38XX_INT_EN_REG); + udelay(ISL38XX_WRITEIO_DELAY); +} + +void +isl38xx_handle_sleep_request(isl38xx_control_block *control_block, + int *powerstate, void *device_base) +{ + /* device requests to go into sleep mode + * check whether the transmit queues for data and management are empty */ + if (isl38xx_in_queue(control_block, ISL38XX_CB_TX_DATA_LQ)) + /* data tx queue not empty */ + return; + + if (isl38xx_in_queue(control_block, ISL38XX_CB_TX_MGMTQ)) + /* management tx queue not empty */ + return; + + /* check also whether received frames are pending */ + if (isl38xx_in_queue(control_block, ISL38XX_CB_RX_DATA_LQ)) + /* data rx queue not empty */ + return; + + if (isl38xx_in_queue(control_block, ISL38XX_CB_RX_MGMTQ)) + /* management rx queue not empty */ + return; + +#if VERBOSE > SHOW_ERROR_MESSAGES + DEBUG(SHOW_TRACING, "Device going to sleep mode\n"); +#endif + + /* all queues are empty, allow the device to go into sleep mode */ + *powerstate = ISL38XX_PSM_POWERSAVE_STATE; + + /* assert the Sleep interrupt in the Device Interrupt Register */ + isl38xx_w32_flush(device_base, ISL38XX_DEV_INT_SLEEP, + ISL38XX_DEV_INT_REG); + udelay(ISL38XX_WRITEIO_DELAY); +} + +void +isl38xx_handle_wakeup(isl38xx_control_block *control_block, + int *powerstate, void *device_base) +{ + /* device is in active state, update the powerstate flag */ + *powerstate = ISL38XX_PSM_ACTIVE_STATE; + + /* now check whether there are frames pending for the card */ + if (!isl38xx_in_queue(control_block, ISL38XX_CB_TX_DATA_LQ) + && !isl38xx_in_queue(control_block, ISL38XX_CB_TX_MGMTQ)) + return; + +#if VERBOSE > SHOW_ERROR_MESSAGES + DEBUG(SHOW_ANYTHING, "Wake up handler trigger the device\n"); +#endif + + /* either data or management transmit queue has a frame pending + * trigger the device by setting the Update bit in the Device Int reg */ + isl38xx_w32_flush(device_base, ISL38XX_DEV_INT_UPDATE, + ISL38XX_DEV_INT_REG); + udelay(ISL38XX_WRITEIO_DELAY); +} + +void +isl38xx_trigger_device(int asleep, void *device_base) +{ + struct timeval current_time; + u32 reg, counter = 0; + +#if VERBOSE > SHOW_ERROR_MESSAGES + DEBUG(SHOW_FUNCTION_CALLS, "isl38xx trigger device\n"); +#endif + + /* check whether the device is in power save mode */ + if (asleep) { + /* device is in powersave, trigger the device for wakeup */ +#if VERBOSE > SHOW_ERROR_MESSAGES + do_gettimeofday(¤t_time); + DEBUG(SHOW_TRACING, "%08li.%08li Device wakeup triggered\n", + current_time.tv_sec, current_time.tv_usec); +#endif + + DEBUG(SHOW_TRACING, "%08li.%08li Device register read %08x\n", + current_time.tv_sec, current_time.tv_usec, + readl(device_base + ISL38XX_CTRL_STAT_REG)); + udelay(ISL38XX_WRITEIO_DELAY); + + if (reg = readl(device_base + ISL38XX_INT_IDENT_REG), + reg == 0xabadface) { +#if VERBOSE > SHOW_ERROR_MESSAGES + do_gettimeofday(¤t_time); + DEBUG(SHOW_TRACING, + "%08li.%08li Device register abadface\n", + current_time.tv_sec, current_time.tv_usec); +#endif + /* read the Device Status Register until Sleepmode bit is set */ + while (reg = readl(device_base + ISL38XX_CTRL_STAT_REG), + (reg & ISL38XX_CTRL_STAT_SLEEPMODE) == 0) { + udelay(ISL38XX_WRITEIO_DELAY); + counter++; + } + + DEBUG(SHOW_TRACING, + "%08li.%08li Device register read %08x\n", + current_time.tv_sec, current_time.tv_usec, + readl(device_base + ISL38XX_CTRL_STAT_REG)); + udelay(ISL38XX_WRITEIO_DELAY); + +#if VERBOSE > SHOW_ERROR_MESSAGES + do_gettimeofday(¤t_time); + DEBUG(SHOW_TRACING, + "%08li.%08li Device asleep counter %i\n", + current_time.tv_sec, current_time.tv_usec, + counter); +#endif + } + /* assert the Wakeup interrupt in the Device Interrupt Register */ + isl38xx_w32_flush(device_base, ISL38XX_DEV_INT_WAKEUP, + ISL38XX_DEV_INT_REG); + udelay(ISL38XX_WRITEIO_DELAY); + + /* perform another read on the Device Status Register */ + reg = readl(device_base + ISL38XX_CTRL_STAT_REG); + udelay(ISL38XX_WRITEIO_DELAY); + +#if VERBOSE > SHOW_ERROR_MESSAGES + do_gettimeofday(¤t_time); + DEBUG(SHOW_TRACING, "%08li.%08li Device register read %08x\n", + current_time.tv_sec, current_time.tv_usec, reg); +#endif + } else { + /* device is (still) awake */ +#if VERBOSE > SHOW_ERROR_MESSAGES + DEBUG(SHOW_TRACING, "Device is in active state\n"); +#endif + /* trigger the device by setting the Update bit in the Device Int reg */ + + isl38xx_w32_flush(device_base, ISL38XX_DEV_INT_UPDATE, + ISL38XX_DEV_INT_REG); + udelay(ISL38XX_WRITEIO_DELAY); + } +} + +void +isl38xx_interface_reset(void *device_base, dma_addr_t host_address) +{ + u32 reg; + +#if VERBOSE > SHOW_ERROR_MESSAGES + DEBUG(SHOW_FUNCTION_CALLS, "isl38xx_interface_reset \n"); +#endif + + /* load the address of the control block in the device */ + isl38xx_w32_flush(device_base, host_address, ISL38XX_CTRL_BLK_BASE_REG); + udelay(ISL38XX_WRITEIO_DELAY); + + /* set the reset bit in the Device Interrupt Register */ + isl38xx_w32_flush(device_base, ISL38XX_DEV_INT_RESET, + ISL38XX_DEV_INT_REG); + udelay(ISL38XX_WRITEIO_DELAY); + + /* enable the interrupt for detecting initialization */ + + /* Note: Do not enable other interrupts here. We want the + * device to have come up first 100% before allowing any other + * interrupts. */ + reg = ISL38XX_INT_IDENT_INIT; + + isl38xx_w32_flush(device_base, reg, ISL38XX_INT_EN_REG); + udelay(ISL38XX_WRITEIO_DELAY); /* allow complete full reset */ +} + +void +isl38xx_enable_common_interrupts(void *device_base) { + u32 reg; + reg = ( ISL38XX_INT_IDENT_UPDATE | + ISL38XX_INT_IDENT_SLEEP | ISL38XX_INT_IDENT_WAKEUP); + isl38xx_w32_flush(device_base, reg, ISL38XX_INT_EN_REG); + udelay(ISL38XX_WRITEIO_DELAY); +} + +int +isl38xx_upload_firmware(char *fw_id, _REQ_FW_DEV_T dev, void *device_base, + dma_addr_t host_address) +{ + u32 reg, rc; + +#if VERBOSE > SHOW_ERROR_MESSAGES + DEBUG(SHOW_ERROR_MESSAGES, "isl38xx_upload_firmware(0x%lx, 0x%lx)\n", + (long) device_base, (long) host_address); +#endif + + /* clear the RAMBoot and the Reset bit */ + reg = readl(device_base + ISL38XX_CTRL_STAT_REG); + reg &= ~ISL38XX_CTRL_STAT_RESET; + reg &= ~ISL38XX_CTRL_STAT_RAMBOOT; + writel(reg, device_base + ISL38XX_CTRL_STAT_REG); + wmb(); + udelay(ISL38XX_WRITEIO_DELAY); + + /* set the Reset bit without reading the register ! */ + reg |= ISL38XX_CTRL_STAT_RESET; + writel(reg, device_base + ISL38XX_CTRL_STAT_REG); + wmb(); + udelay(ISL38XX_WRITEIO_DELAY); + + /* clear the Reset bit */ + reg &= ~ISL38XX_CTRL_STAT_RESET; + writel(reg, device_base + ISL38XX_CTRL_STAT_REG); + wmb(); + + /* wait a while for the device to reboot */ + mdelay(50); + + { + const struct firmware *fw_entry = 0; + long fw_len; + const u32 *fw_ptr; + + rc = request_firmware(&fw_entry, fw_id, dev); + if (rc) { + printk(KERN_ERR + "%s: request_firmware() failed for '%s'\n", + "prism54", fw_id); + return rc; + } + /* prepare the Direct Memory Base register */ + reg = ISL38XX_DEV_FIRMWARE_ADDRES; + + fw_ptr = (u32 *) fw_entry->data; + fw_len = fw_entry->size; + + if (fw_len % 4) { + printk(KERN_ERR + "%s: firmware '%s' size is not multiple of 32bit, aborting!\n", + "prism54", fw_id); + release_firmware(fw_entry); + return EILSEQ; /* Illegal byte sequence */; + } + + while (fw_len > 0) { + long _fw_len = + (fw_len > + ISL38XX_MEMORY_WINDOW_SIZE) ? + ISL38XX_MEMORY_WINDOW_SIZE : fw_len; + u32 *dev_fw_ptr = device_base + ISL38XX_DIRECT_MEM_WIN; + + /* set the cards base address for writting the data */ + isl38xx_w32_flush(device_base, reg, + ISL38XX_DIR_MEM_BASE_REG); + wmb(); /* be paranoid */ + + /* increment the write address for next iteration */ + reg += _fw_len; + fw_len -= _fw_len; + + /* write the data to the Direct Memory Window 32bit-wise */ + /* memcpy_toio() doesn't guarantee 32bit writes :-| */ + while (_fw_len > 0) { + /* use non-swapping writel() */ + __raw_writel(*fw_ptr, dev_fw_ptr); + fw_ptr++, dev_fw_ptr++; + _fw_len -= 4; + } + + /* flush PCI posting */ + (void) readl(device_base + ISL38XX_PCI_POSTING_FLUSH); + wmb(); /* be paranoid again */ + + BUG_ON(_fw_len != 0); + } + + BUG_ON(fw_len != 0); + + release_firmware(fw_entry); + } + + /* now reset the device + * clear the Reset & ClkRun bit, set the RAMBoot bit */ + reg = readl(device_base + ISL38XX_CTRL_STAT_REG); + reg &= ~ISL38XX_CTRL_STAT_CLKRUN; + reg &= ~ISL38XX_CTRL_STAT_RESET; + reg |= ISL38XX_CTRL_STAT_RAMBOOT; + isl38xx_w32_flush(device_base, reg, ISL38XX_CTRL_STAT_REG); + wmb(); + udelay(ISL38XX_WRITEIO_DELAY); + + /* set the reset bit latches the host override and RAMBoot bits + * into the device for operation when the reset bit is reset */ + reg |= ISL38XX_CTRL_STAT_RESET; + writel(reg, device_base + ISL38XX_CTRL_STAT_REG); + /* don't do flush PCI posting here! */ + wmb(); + udelay(ISL38XX_WRITEIO_DELAY); + + /* clear the reset bit should start the whole circus */ + reg &= ~ISL38XX_CTRL_STAT_RESET; + writel(reg, device_base + ISL38XX_CTRL_STAT_REG); + /* don't do flush PCI posting here! */ + wmb(); + udelay(ISL38XX_WRITEIO_DELAY); + + return 0; +} + +int +isl38xx_in_queue(isl38xx_control_block *cb, int queue) +{ + const s32 delta = (le32_to_cpu(cb->driver_curr_frag[queue]) - + le32_to_cpu(cb->device_curr_frag[queue])); + + /* determine the amount of fragments in the queue depending on the type + * of the queue, either transmit or receive */ + + BUG_ON(delta < 0); /* driver ptr must be ahead of device ptr */ + + switch (queue) { + /* send queues */ + case ISL38XX_CB_TX_MGMTQ: + BUG_ON(delta > ISL38XX_CB_MGMT_QSIZE); + case ISL38XX_CB_TX_DATA_LQ: + case ISL38XX_CB_TX_DATA_HQ: + BUG_ON(delta > ISL38XX_CB_TX_QSIZE); + return delta; + break; + + /* receive queues */ + case ISL38XX_CB_RX_MGMTQ: + BUG_ON(delta > ISL38XX_CB_MGMT_QSIZE); + return ISL38XX_CB_MGMT_QSIZE - delta; + break; + + case ISL38XX_CB_RX_DATA_LQ: + case ISL38XX_CB_RX_DATA_HQ: + BUG_ON(delta > ISL38XX_CB_RX_QSIZE); + return ISL38XX_CB_RX_QSIZE - delta; + break; + } + BUG(); + return 0; +} diff -Nru a/drivers/net/wireless/prism54/isl_38xx.h b/drivers/net/wireless/prism54/isl_38xx.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/drivers/net/wireless/prism54/isl_38xx.h Sun Mar 14 14:20:09 2004 @@ -0,0 +1,179 @@ +/* $Header: /var/lib/cvs/prism54-ng/ksrc/isl_38xx.h,v 1.22 2004/02/28 03:06:07 mcgrof Exp $ + * + * Copyright (C) 2002 Intersil Americas 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 + * + * 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 + * + */ + +#ifndef _ISL_38XX_H +#define _ISL_38XX_H + +#include +#include + +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,75)) +#include +# define _REQ_FW_DEV_T struct device * +#else +# define _REQ_FW_DEV_T char * +#endif + +#include + +#define ISL38XX_CB_RX_QSIZE 8 +#define ISL38XX_CB_TX_QSIZE 32 + +/* ISL38XX Access Point Specific definitions */ +#define ISL38XX_MAX_WDS_LINKS 8 + +/* ISL38xx Client Specific definitions */ +#define ISL38XX_PSM_ACTIVE_STATE 0 +#define ISL38XX_PSM_POWERSAVE_STATE 1 + +/* ISL38XX Host Interface Definitions */ +#define ISL38XX_PCI_MEM_SIZE 0x02000 +#define ISL38XX_MEMORY_WINDOW_SIZE 0x01000 +#define ISL38XX_DEV_FIRMWARE_ADDRES 0x20000 +#define ISL38XX_WRITEIO_DELAY 10 /* in us */ +#define ISL38XX_RESET_DELAY 50 /* in ms */ +#define ISL38XX_WAIT_CYCLE 10 /* in 10ms */ +#define ISL38XX_MAX_WAIT_CYCLES 10 + +/* PCI Memory Area */ +#define ISL38XX_HARDWARE_REG 0x0000 +#define ISL38XX_CARDBUS_CIS 0x0800 +#define ISL38XX_DIRECT_MEM_WIN 0x1000 + +/* Hardware registers */ +#define ISL38XX_DEV_INT_REG 0x0000 +#define ISL38XX_INT_IDENT_REG 0x0010 +#define ISL38XX_INT_ACK_REG 0x0014 +#define ISL38XX_INT_EN_REG 0x0018 +#define ISL38XX_GEN_PURP_COM_REG_1 0x0020 +#define ISL38XX_GEN_PURP_COM_REG_2 0x0024 +#define ISL38XX_CTRL_BLK_BASE_REG ISL38XX_GEN_PURP_COM_REG_1 +#define ISL38XX_DIR_MEM_BASE_REG 0x0030 +#define ISL38XX_CTRL_STAT_REG 0x0078 + +/* High end mobos queue up pci writes, the following + * is used to "read" from after a write to force flush */ +#define ISL38XX_PCI_POSTING_FLUSH ISL38XX_INT_EN_REG + +/** + * isl38xx_w32_flush - PCI iomem write helper + * @base: (host) memory base address of the device + * @val: 32bit value (host order) to write + * @offset: byte offset into @base to write value to + * + * This helper takes care of writing a 32bit datum to the + * specified offset into the device's pci memory space, and making sure + * the pci memory buffers get flushed by performing one harmless read + * from the %ISL38XX_PCI_POSTING_FLUSH offset. + */ +static inline void +isl38xx_w32_flush(void *base, u32 val, unsigned long offset) +{ + writel(val, base + offset); + (void) readl(base + ISL38XX_PCI_POSTING_FLUSH); +} + +/* Device Interrupt register bits */ +#define ISL38XX_DEV_INT_RESET 0x0001 +#define ISL38XX_DEV_INT_UPDATE 0x0002 +#define ISL38XX_DEV_INT_WAKEUP 0x0008 +#define ISL38XX_DEV_INT_SLEEP 0x0010 + +/* Interrupt Identification/Acknowledge/Enable register bits */ +#define ISL38XX_INT_IDENT_UPDATE 0x0002 +#define ISL38XX_INT_IDENT_INIT 0x0004 +#define ISL38XX_INT_IDENT_WAKEUP 0x0008 +#define ISL38XX_INT_IDENT_SLEEP 0x0010 +#define ISL38XX_INT_SOURCES 0x001E + +/* Control/Status register bits */ +#define ISL38XX_CTRL_STAT_SLEEPMODE 0x00000200 +#define ISL38XX_CTRL_STAT_CLKRUN 0x00800000 +#define ISL38XX_CTRL_STAT_RESET 0x10000000 +#define ISL38XX_CTRL_STAT_RAMBOOT 0x20000000 +#define ISL38XX_CTRL_STAT_STARTHALTED 0x40000000 +#define ISL38XX_CTRL_STAT_HOST_OVERRIDE 0x80000000 + +/* Control Block definitions */ +#define ISL38XX_CB_RX_DATA_LQ 0 +#define ISL38XX_CB_TX_DATA_LQ 1 +#define ISL38XX_CB_RX_DATA_HQ 2 +#define ISL38XX_CB_TX_DATA_HQ 3 +#define ISL38XX_CB_RX_MGMTQ 4 +#define ISL38XX_CB_TX_MGMTQ 5 +#define ISL38XX_CB_QCOUNT 6 +#define ISL38XX_CB_MGMT_QSIZE 4 +#define ISL38XX_MIN_QTHRESHOLD 4 /* fragments */ + +/* Memory Manager definitions */ +#define MGMT_FRAME_SIZE 1500 /* >= size struct obj_bsslist */ +#define MGMT_TX_FRAME_COUNT 24 /* max 4 + spare 4 + 8 init */ +#define MGMT_RX_FRAME_COUNT 24 /* 4*4 + spare 8 */ +#define MGMT_FRAME_COUNT (MGMT_TX_FRAME_COUNT + MGMT_RX_FRAME_COUNT) +#define CONTROL_BLOCK_SIZE 1024 /* should be enough */ +#define PSM_FRAME_SIZE 1536 +#define PSM_MINIMAL_STATION_COUNT 64 +#define PSM_FRAME_COUNT PSM_MINIMAL_STATION_COUNT +#define PSM_BUFFER_SIZE PSM_FRAME_SIZE * PSM_FRAME_COUNT +#define MAX_TRAP_RX_QUEUE 4 +#define HOST_MEM_BLOCK CONTROL_BLOCK_SIZE + PSM_BUFFER_SIZE + +/* Fragment package definitions */ +#define FRAGMENT_FLAG_MF 0x0001 +#define MAX_FRAGMENT_SIZE 1536 + +/* In monitor mode frames have a header. I don't know exactly how big those + * frame can be but I've never seen any frame bigger than 1584... : + */ +#define MAX_FRAGMENT_SIZE_RX 1600 + +typedef struct { + u32 address; /* physical address on host */ + u16 size; /* packet size */ + u16 flags; /* set of bit-wise flags */ +} isl38xx_fragment; + +struct isl38xx_cb { + u32 driver_curr_frag[ISL38XX_CB_QCOUNT]; + u32 device_curr_frag[ISL38XX_CB_QCOUNT]; + isl38xx_fragment rx_data_low[ISL38XX_CB_RX_QSIZE]; + isl38xx_fragment tx_data_low[ISL38XX_CB_TX_QSIZE]; + isl38xx_fragment rx_data_high[ISL38XX_CB_RX_QSIZE]; + isl38xx_fragment tx_data_high[ISL38XX_CB_TX_QSIZE]; + isl38xx_fragment rx_data_mgmt[ISL38XX_CB_MGMT_QSIZE]; + isl38xx_fragment tx_data_mgmt[ISL38XX_CB_MGMT_QSIZE]; +}; + +typedef struct isl38xx_cb isl38xx_control_block; + +/* determine number of entries currently in queue */ +int isl38xx_in_queue(isl38xx_control_block *cb, int queue); + +void isl38xx_disable_interrupts(void *); +void isl38xx_enable_common_interrupts(void *); + +void isl38xx_handle_sleep_request(isl38xx_control_block *, int *, + void *); +void isl38xx_handle_wakeup(isl38xx_control_block *, int *, void *); +void isl38xx_trigger_device(int, void *); +void isl38xx_interface_reset(void *, dma_addr_t); + +int isl38xx_upload_firmware(char *, _REQ_FW_DEV_T, void *, dma_addr_t); + +#endif /* _ISL_38XX_H */ diff -Nru a/drivers/net/wireless/prism54/isl_ioctl.c b/drivers/net/wireless/prism54/isl_ioctl.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/drivers/net/wireless/prism54/isl_ioctl.c Sun Mar 14 14:20:09 2004 @@ -0,0 +1,2155 @@ +/* $Header: /var/lib/cvs/prism54-ng/ksrc/isl_ioctl.c,v 1.140 2004/02/28 03:06:07 mcgrof Exp $ + * + * Copyright (C) 2002 Intersil Americas Inc. + * (C) 2003 Aurelien Alleaume + * (C) 2003 Herbert Valerio Riedel + * (C) 2003 Luis R. Rodriguez + * + * 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 + * + * 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 "isl_ioctl.h" +#include "islpci_mgt.h" +#include "isl_oid.h" /* additional types and defs for isl38xx fw */ +#include "oid_mgt.h" + +#include /* New driver API */ + +static int init_mode = CARD_DEFAULT_IW_MODE; +static int init_channel = CARD_DEFAULT_CHANNEL; +static int init_wep = CARD_DEFAULT_WEP; +static int init_filter = CARD_DEFAULT_FILTER; +static int init_authen = CARD_DEFAULT_AUTHEN; +static int init_dot1x = CARD_DEFAULT_DOT1X; +static int init_conformance = CARD_DEFAULT_CONFORMANCE; +static int init_mlme = CARD_DEFAULT_MLME_MODE; + +MODULE_PARM(init_mode, "i"); +MODULE_PARM_DESC(init_mode, + "Set card mode:\n0: Auto\n1: Ad-Hoc\n2: Managed Client (Default)\n3: Master / Access Point\n4: Repeater (Not supported yet)\n5: Secondary (Not supported yet)\n6: Monitor"); + +MODULE_PARM(init_channel, "i"); +MODULE_PARM_DESC(init_channel, + "Check `iwpriv ethx channel` for available channels"); + +MODULE_PARM(init_wep, "i"); +MODULE_PARM(init_filter, "i"); + +MODULE_PARM(init_authen, "i"); +MODULE_PARM_DESC(init_authen, + "Authentication method. Can be of seven types:\n0 0x0000: None\n1 0x0001: DOT11_AUTH_OS (Default)\n2 0x0002: DOT11_AUTH_SK\n3 0x0003: DOT11_AUTH_BOTH"); + +MODULE_PARM(init_dot1x, "i"); +MODULE_PARM_DESC(init_dot1x, + "\n0: None/not set (Default)\n1: DOT11_DOT1X_AUTHENABLED\n2: DOT11_DOT1X_KEYTXENABLED"); + +MODULE_PARM(init_mlme, "i"); +MODULE_PARM_DESC(init_mlme, + "Sets the MAC layer management entity (MLME) mode of operation,\n0: DOT11_MLME_AUTO (Default)\n1: DOT11_MLME_INTERMEDIATE\n2: DOT11_MLME_EXTENDED"); + +/** + * prism54_mib_mode_helper - MIB change mode helper function + * @mib: the &struct islpci_mib object to modify + * @iw_mode: new mode (%IW_MODE_*) + * + * This is a helper function, hence it does not lock. Make sure + * caller deals with locking *if* necessary. This function sets the + * mode-dependent mib values and does the mapping of the Linux + * Wireless API modes to Device firmware modes. It also checks for + * correct valid Linux wireless modes. + */ +int +prism54_mib_mode_helper(islpci_private *priv, u32 iw_mode) +{ + u32 config = INL_CONFIG_MANUALRUN; + u32 mode, bsstype; + + /* For now, just catch early the Repeater and Secondary modes here */ + if (iw_mode == IW_MODE_REPEAT || iw_mode == IW_MODE_SECOND) { + printk(KERN_DEBUG "%s(): Sorry, Repeater mode and Secondary mode " + "are not yet supported by this driver.\n", + __FUNCTION__); + return -EINVAL; + } + + priv->iw_mode = iw_mode; + + switch (iw_mode) { + case IW_MODE_AUTO: + mode = INL_MODE_CLIENT; + bsstype = DOT11_BSSTYPE_ANY; + break; + case IW_MODE_ADHOC: + mode = INL_MODE_CLIENT; + bsstype = DOT11_BSSTYPE_IBSS; + break; + case IW_MODE_INFRA: + mode = INL_MODE_CLIENT; + bsstype = DOT11_BSSTYPE_INFRA; + break; + case IW_MODE_MASTER: + mode = INL_MODE_AP; + bsstype = DOT11_BSSTYPE_INFRA; + break; + case IW_MODE_MONITOR: + mode = INL_MODE_PROMISCUOUS; + bsstype = DOT11_BSSTYPE_ANY; + config |= INL_CONFIG_RXANNEX; + break; + default: + return -EINVAL; + } + + if (init_wds) + config |= INL_CONFIG_WDS; + mgt_set(priv, DOT11_OID_BSSTYPE, &bsstype); + mgt_set(priv, OID_INL_CONFIG, &config); + mgt_set(priv, OID_INL_MODE, &mode); + + return 0; +} + +/** + * prism54_mib_init - fill MIB cache with defaults + * + * this function initializes the struct given as @mib with defaults, + * of which many are retrieved from the global module parameter + * variables. + */ + +void +prism54_mib_init(islpci_private *priv) +{ + u32 t; + struct obj_buffer psm_buffer = { + .size = cpu_to_le32(PSM_BUFFER_SIZE), + .addr = cpu_to_le32(priv->device_psm_buffer) + }; + + mgt_set(priv, DOT11_OID_CHANNEL, &init_channel); + mgt_set(priv, DOT11_OID_AUTHENABLE, &init_authen); + mgt_set(priv, DOT11_OID_PRIVACYINVOKED, &init_wep); + + mgt_set(priv, DOT11_OID_PSMBUFFER, &psm_buffer); + mgt_set(priv, DOT11_OID_EXUNENCRYPTED, &init_filter); + mgt_set(priv, DOT11_OID_DOT1XENABLE, &init_dot1x); + mgt_set(priv, DOT11_OID_MLMEAUTOLEVEL, &init_mlme); + mgt_set(priv, OID_INL_DOT11D_CONFORMANCE, &init_conformance); + + t = 127; + mgt_set(priv, OID_INL_OUTPUTPOWER, &t); + + /* Important: we are setting a default wireless mode and we are + * forcing a valid one, so prism54_mib_mode_helper should just set + * mib values depending on what the wireless mode given is. No need + * for it save old values */ + if (init_mode > IW_MODE_MONITOR || init_mode < IW_MODE_AUTO) { + printk(KERN_DEBUG "%s(): You passed a non-valid init_mode. " + "Using default mode\n", __FUNCTION__); + init_mode = CARD_DEFAULT_IW_MODE; + } + /* This sets all of the mode-dependent values */ + prism54_mib_mode_helper(priv, init_mode); +} + +void +prism54_mib_init_work(islpci_private *priv) +{ + down_write(&priv->mib_sem); + mgt_commit(priv); + up_write(&priv->mib_sem); +} + +/* this will be executed outside of atomic context thanks to + * schedule_work(), thus we can as well use sleeping semaphore + * locking */ +void +prism54_update_stats(islpci_private *priv) +{ + char *data; + int j; + struct obj_bss bss, *bss2; + union oid_res_t r; + + if (down_interruptible(&priv->stats_sem)) + return; + +/* missing stats are : + * iwstatistics.qual.updated + * iwstatistics.discard.nwid + * iwstatistics.discard.fragment + * iwstatistics.discard.misc + * iwstatistics.miss.beacon */ + +/* Noise floor. + * I'm not sure if the unit is dBm. + * Note : If we are not connected, this value seems to be irrevelant. */ + + mgt_get_request(priv, DOT11_OID_NOISEFLOOR, 0, NULL, &r); + priv->local_iwstatistics.qual.noise = r.u; + +/* Get the rssi of the link. To do this we need to retrieve a bss. */ + + /* First get the MAC address of the AP we are associated with. */ + mgt_get_request(priv, DOT11_OID_BSSID, 0, NULL, &r); + data = r.ptr; + + /* copy this MAC to the bss */ + for (j = 0; j < 6; j++) + bss.address[j] = data[j]; + kfree(data); + + /* now ask for the corresponding bss */ + j = mgt_get_request(priv, DOT11_OID_BSSFIND, 0, (void *) &bss, &r); + bss2 = r.ptr; + /* report the rssi and use it to calculate + * link quality through a signal-noise + * ratio */ + priv->local_iwstatistics.qual.level = bss2->rssi; + priv->local_iwstatistics.qual.qual = + bss2->rssi - priv->iwstatistics.qual.noise; + + kfree(bss2); + + /* report that the stats are new */ + priv->local_iwstatistics.qual.updated = 0x7; + +/* Rx : unable to decrypt the MPDU */ + mgt_get_request(priv, DOT11_OID_PRIVRXFAILED, 0, NULL, &r); + priv->local_iwstatistics.discard.code = r.u; + +/* Tx : Max MAC retries num reached */ + mgt_get_request(priv, DOT11_OID_MPDUTXFAILED, 0, NULL, &r); + priv->local_iwstatistics.discard.retries = r.u; + + up(&priv->stats_sem); + + return; +} + +struct iw_statistics * +prism54_get_wireless_stats(struct net_device *ndev) +{ + islpci_private *priv = ndev->priv; + + /* If the stats are being updated return old data */ + if (down_trylock(&priv->stats_sem) == 0) { + memcpy(&priv->iwstatistics, &priv->local_iwstatistics, + sizeof (struct iw_statistics)); + /* They won't be marked updated for the next time */ + priv->local_iwstatistics.qual.updated = 0; + up(&priv->stats_sem); + } else + priv->iwstatistics.qual.updated = 0; + + /* Update our wireless stats, but do not schedule to often + * (max 1 HZ) */ + if ((priv->stats_timestamp == 0) || + time_after(jiffies, priv->stats_timestamp + 1 * HZ)) { + schedule_work(&priv->stats_work); + priv->stats_timestamp = jiffies; + } + + return &priv->iwstatistics; +} + +static int +prism54_commit(struct net_device *ndev, struct iw_request_info *info, + char *cwrq, char *extra) +{ + islpci_private *priv = ndev->priv; + + /* simply re-set the last set SSID, this should commit most stuff */ + + /* Commit in Monitor mode is not necessary, also setting essid + * in Monitor mode does not make sense and isn't allowed for this + * device's firmware */ + if(priv->iw_mode != IW_MODE_MONITOR) + return mgt_set_request(priv, DOT11_OID_SSID, 0, NULL); + return 0; +} + +static int +prism54_get_name(struct net_device *ndev, struct iw_request_info *info, + char *cwrq, char *extra) +{ + islpci_private *priv = ndev->priv; + char *capabilities; + union oid_res_t r; + int rvalue; + + if (islpci_get_state(priv) < PRV_STATE_INIT) { + strncpy(cwrq, "NOT READY!", IFNAMSIZ); + return 0; + } + rvalue = mgt_get_request(priv, OID_INL_PHYCAPABILITIES, 0, NULL, &r); + + switch (r.u) { + case INL_PHYCAP_5000MHZ: + capabilities = "IEEE 802.11a/b/g"; + break; + case INL_PHYCAP_FAA: + capabilities = "IEEE 802.11b/g - FAA Support"; + break; + case INL_PHYCAP_2400MHZ: + default: + capabilities = "IEEE 802.11b/g"; /* Default */ + break; + } + strncpy(cwrq, capabilities, IFNAMSIZ); + return rvalue; +} + +static int +prism54_set_freq(struct net_device *ndev, struct iw_request_info *info, + struct iw_freq *fwrq, char *extra) +{ + islpci_private *priv = ndev->priv; + int rvalue; + u32 c = 0; + + /* prepare the structure for the set object */ + if (fwrq->m < 1000) + /* structure value contains a channel indication */ + c = fwrq->m; + else { + /* structure contains a frequency indication and fwrq->e = 1 */ + int f = fwrq->m / 100000; + + if (fwrq->e != 1) + return -EINVAL; + if ((f >= 2412) && (f <= 2484)) { + while ((c < 14) && (f != frequency_list_bg[c])) + c++; + if (c >= 14) + return -EINVAL; + } else if ((f >= (int) 5170) && (f <= (int) 5320)) { + while ((c < 12) && (f != frequency_list_a[c])) + c++; + if (c >= 12) + return -EINVAL; + } else + return -EINVAL; + c++; + } + + rvalue = mgt_set_request(priv, DOT11_OID_CHANNEL, 0, &c); + + /* Call commit handler */ + return (rvalue ? rvalue : -EINPROGRESS); +} + +static int +prism54_get_freq(struct net_device *ndev, struct iw_request_info *info, + struct iw_freq *fwrq, char *extra) +{ + islpci_private *priv = ndev->priv; + union oid_res_t r; + int rvalue; + + rvalue = mgt_get_request(priv, DOT11_OID_CHANNEL, 0, NULL, &r); + + fwrq->m = r.u; + fwrq->e = 0; + + return rvalue; +} + +static int +prism54_set_mode(struct net_device *ndev, struct iw_request_info *info, + __u32 * uwrq, char *extra) +{ + islpci_private *priv = ndev->priv; + u32 mlmeautolevel = CARD_DEFAULT_MLME_MODE; + + /* Let's see if the user passed a valid Linux Wireless mode */ + if (*uwrq > IW_MODE_MONITOR || *uwrq < IW_MODE_AUTO) { + printk(KERN_DEBUG + "%s: %s() You passed a non-valid init_mode.\n", + priv->ndev->name, __FUNCTION__); + return -EINVAL; + } + + down_write(&priv->mib_sem); + + if (prism54_mib_mode_helper(priv, *uwrq)) { + up_write(&priv->mib_sem); + return -EOPNOTSUPP; + } + + /* the ACL code needs an intermediate mlmeautolevel. The wpa stuff an + * extended one. + */ + if ((*uwrq == IW_MODE_MASTER) && (priv->acl.policy != MAC_POLICY_OPEN)) + mlmeautolevel = DOT11_MLME_INTERMEDIATE; + if (priv->wpa) + mlmeautolevel = DOT11_MLME_EXTENDED; + + mgt_set(priv, DOT11_OID_MLMEAUTOLEVEL, &mlmeautolevel); + + mgt_commit(priv); + priv->ndev->type = (priv->iw_mode == IW_MODE_MONITOR) + ? ARPHRD_IEEE80211 : ARPHRD_ETHER; + up_write(&priv->mib_sem); + + return 0; +} + +/* Use mib cache */ +static int +prism54_get_mode(struct net_device *ndev, struct iw_request_info *info, + __u32 * uwrq, char *extra) +{ + islpci_private *priv = ndev->priv; + + BUG_ON((priv->iw_mode < IW_MODE_AUTO) || (priv->iw_mode > + IW_MODE_MONITOR)); + *uwrq = priv->iw_mode; + + return 0; +} + +/* we use DOT11_OID_EDTHRESHOLD. From what I guess the card will not try to + * emit data if (sensitivity > rssi - noise) (in dBm). + * prism54_set_sens does not seem to work. + */ + +static int +prism54_set_sens(struct net_device *ndev, struct iw_request_info *info, + struct iw_param *vwrq, char *extra) +{ + islpci_private *priv = ndev->priv; + u32 sens; + + /* by default the card sets this to 20. */ + sens = vwrq->disabled ? 20 : vwrq->value; + + /* set the ed threshold. */ + return mgt_set_request(priv, DOT11_OID_EDTHRESHOLD, 0, &sens); +} + +static int +prism54_get_sens(struct net_device *ndev, struct iw_request_info *info, + struct iw_param *vwrq, char *extra) +{ + islpci_private *priv = ndev->priv; + union oid_res_t r; + int rvalue; + + rvalue = mgt_get_request(priv, DOT11_OID_EDTHRESHOLD, 0, NULL, &r); + + vwrq->value = r.u; + vwrq->disabled = (vwrq->value == 0); + vwrq->fixed = 1; + + return rvalue; +} + +static int +prism54_get_range(struct net_device *ndev, struct iw_request_info *info, + struct iw_point *dwrq, char *extra) +{ + struct iw_range *range = (struct iw_range *) extra; + islpci_private *priv = ndev->priv; + char *data; + int i, m, rvalue; + struct obj_frequencies *freq; + union oid_res_t r; + + memset(range, 0, sizeof (struct iw_range)); + dwrq->length = sizeof (struct iw_range); + + /* set the wireless extension version number */ + range->we_version_source = SUPPORTED_WIRELESS_EXT; + range->we_version_compiled = WIRELESS_EXT; + + /* Now the encoding capabilities */ + range->num_encoding_sizes = 3; + /* 64(40) bits WEP */ + range->encoding_size[0] = 5; + /* 128(104) bits WEP */ + range->encoding_size[1] = 13; + /* 256 bits for WPA-PSK */ + range->encoding_size[2] = 32; + /* 4 keys are allowed */ + range->max_encoding_tokens = 4; + + /* we don't know the quality range... */ + range->max_qual.level = 0; + range->max_qual.noise = 0; + range->max_qual.qual = 0; + /* these value describe an average quality. Needs more tweaking... */ + range->avg_qual.level = -80; /* -80 dBm */ + range->avg_qual.noise = 0; /* don't know what to put here */ + range->avg_qual.qual = 0; + + range->sensitivity = 200; + + /* retry limit capabilities */ + range->retry_capa = IW_RETRY_LIMIT | IW_RETRY_LIFETIME; + range->retry_flags = IW_RETRY_LIMIT; + range->r_time_flags = IW_RETRY_LIFETIME; + + /* I don't know the range. Put stupid things here */ + range->min_retry = 1; + range->max_retry = 65535; + range->min_r_time = 1024; + range->max_r_time = 65535 * 1024; + + /* txpower is supported in dBm's */ + range->txpower_capa = IW_TXPOW_DBM; + + if (islpci_get_state(priv) < PRV_STATE_INIT) + return 0; + + /* Request the device for the supported frequencies + * not really revelant since some devices will report the 5 GHz band + * frequencies even if they don't support them. + */ + rvalue = + mgt_get_request(priv, DOT11_OID_SUPPORTEDFREQUENCIES, 0, NULL, &r); + freq = r.ptr; + + range->num_channels = le16_to_cpu(freq->nr); + range->num_frequency = le16_to_cpu(freq->nr); + + /* Frequencies are not listed in the right order. The reordering is probably + * firmware dependant and thus should work for everyone. + */ + m = min(IW_MAX_FREQUENCIES, (int) le16_to_cpu(freq->nr)); + for (i = 0; i < m - 12; i++) { + range->freq[i].m = le16_to_cpu(freq->mhz[12 + i]); + range->freq[i].e = 6; + range->freq[i].i = i + 1; + } + for (i = m - 12; i < m; i++) { + range->freq[i].m = le16_to_cpu(freq->mhz[i - m + 12]); + range->freq[i].e = 6; + range->freq[i].i = i + 23; + } + + kfree(freq); + + rvalue |= mgt_get_request(priv, DOT11_OID_SUPPORTEDRATES, 0, NULL, &r); + data = r.ptr; + + /* We got an array of char. It is NULL terminated. */ + i = 0; + while ((i < IW_MAX_BITRATES) && (*data != 0)) { + /* the result must be in bps. The card gives us 500Kbps */ + range->bitrate[i] = (__s32) (*data >> 1); + range->bitrate[i] *= 1000000; + i++; + data++; + } + + range->num_bitrates = i; + + kfree(r.ptr); + + return rvalue; +} + +/* Set AP address*/ + +static int +prism54_set_wap(struct net_device *ndev, struct iw_request_info *info, + struct sockaddr *awrq, char *extra) +{ + islpci_private *priv = ndev->priv; + char bssid[6]; + int rvalue; + + if (awrq->sa_family != ARPHRD_ETHER) + return -EINVAL; + + /* prepare the structure for the set object */ + memcpy(&bssid[0], awrq->sa_data, 6); + + /* set the bssid -- does this make sense when in AP mode? */ + rvalue = mgt_set_request(priv, DOT11_OID_BSSID, 0, &bssid); + + return (rvalue ? rvalue : -EINPROGRESS); /* Call commit handler */ +} + +/* get AP address*/ + +static int +prism54_get_wap(struct net_device *ndev, struct iw_request_info *info, + struct sockaddr *awrq, char *extra) +{ + islpci_private *priv = ndev->priv; + union oid_res_t r; + int rvalue; + + rvalue = mgt_get_request(priv, DOT11_OID_BSSID, 0, NULL, &r); + + memcpy(awrq->sa_data, r.ptr, 6); + awrq->sa_family = ARPHRD_ETHER; + kfree(r.ptr); + + return rvalue; +} + +static int +prism54_set_scan(struct net_device *dev, struct iw_request_info *info, + struct iw_param *vwrq, char *extra) +{ + /* hehe the device does this automagicaly */ + return 0; +} + +/* a little helper that will translate our data into a card independent + * format that the Wireless Tools will understand. This was inspired by + * the "Aironet driver for 4500 and 4800 series cards" (GPL) + */ + +inline char * +prism54_translate_bss(struct net_device *ndev, char *current_ev, + char *end_buf, struct obj_bss *bss, char noise) +{ + struct iw_event iwe; /* Temporary buffer */ + short cap; + islpci_private *priv = ndev->priv; + + /* The first entry must be the MAC address */ + memcpy(iwe.u.ap_addr.sa_data, bss->address, 6); + iwe.u.ap_addr.sa_family = ARPHRD_ETHER; + iwe.cmd = SIOCGIWAP; + current_ev = + iwe_stream_add_event(current_ev, end_buf, &iwe, IW_EV_ADDR_LEN); + + /* The following entries will be displayed in the same order we give them */ + + /* The ESSID. */ + iwe.u.data.length = bss->ssid.length; + iwe.u.data.flags = 1; + iwe.cmd = SIOCGIWESSID; + current_ev = iwe_stream_add_point(current_ev, end_buf, + &iwe, bss->ssid.octets); + + /* Capabilities */ +#define CAP_ESS 0x01 +#define CAP_IBSS 0x02 +#define CAP_CRYPT 0x10 + + /* Mode */ + cap = le16_to_cpu(bss->capinfo); + iwe.u.mode = 0; + if (cap & CAP_ESS) + iwe.u.mode = IW_MODE_MASTER; + else if (cap & CAP_IBSS) + iwe.u.mode = IW_MODE_ADHOC; + iwe.cmd = SIOCGIWMODE; + if (iwe.u.mode) + current_ev = + iwe_stream_add_event(current_ev, end_buf, &iwe, + IW_EV_UINT_LEN); + + /* Encryption capability */ + if (cap & CAP_CRYPT) + iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY; + else + iwe.u.data.flags = IW_ENCODE_DISABLED; + iwe.u.data.length = 0; + iwe.cmd = SIOCGIWENCODE; + current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, NULL); + + /* Add frequency. (short) bss->channel is the frequency in MHz */ + iwe.u.freq.m = bss->channel; + iwe.u.freq.e = 6; + iwe.cmd = SIOCGIWFREQ; + current_ev = + iwe_stream_add_event(current_ev, end_buf, &iwe, IW_EV_FREQ_LEN); + + /* Add quality statistics */ + iwe.u.qual.level = bss->rssi; + iwe.u.qual.noise = noise; + /* do a simple SNR for quality */ + iwe.u.qual.qual = bss->rssi - noise; + iwe.cmd = IWEVQUAL; + current_ev = + iwe_stream_add_event(current_ev, end_buf, &iwe, IW_EV_QUAL_LEN); + + if (priv->wpa) { + u8 wpa_ie[MAX_WPA_IE_LEN]; + char *buf, *p; + size_t wpa_ie_len; + int i; + + wpa_ie_len = prism54_wpa_ie_get(priv, bss->address, wpa_ie); + if (wpa_ie_len > 0 && + (buf = kmalloc(wpa_ie_len * 2 + 10, GFP_ATOMIC))) { + p = buf; + p += sprintf(p, "wpa_ie="); + for (i = 0; i < wpa_ie_len; i++) { + p += sprintf(p, "%02x", wpa_ie[i]); + } + memset(&iwe, 0, sizeof (iwe)); + iwe.cmd = IWEVCUSTOM; + iwe.u.data.length = strlen(buf); + current_ev = iwe_stream_add_point(current_ev, end_buf, + &iwe, buf); + kfree(buf); + } + } + + return current_ev; +} + +int +prism54_get_scan(struct net_device *ndev, struct iw_request_info *info, + struct iw_point *dwrq, char *extra) +{ + islpci_private *priv = ndev->priv; + int i, rvalue; + struct obj_bsslist *bsslist; + u32 noise = 0; + char *current_ev = extra; + union oid_res_t r; + + if (islpci_get_state(priv) < PRV_STATE_INIT) { + /* device is not ready, fail gently */ + dwrq->length = 0; + return 0; + } + + /* first get the noise value. We will use it to report the link quality */ + rvalue = mgt_get_request(priv, DOT11_OID_NOISEFLOOR, 0, NULL, &r); + noise = r.u; + + /* Ask the device for a list of known bss. We can report at most + * IW_MAX_AP=64 to the range struct. But the device won't repport anything + * if you change the value of MAXBSS=24. Anyway 24 AP It is probably enough. + */ + rvalue |= mgt_get_request(priv, DOT11_OID_BSSLIST, 0, NULL, &r); + bsslist = r.ptr; + + /* ok now, scan the list and translate its info */ + for (i = 0; i < min(IW_MAX_AP, (int) le32_to_cpu(bsslist->nr)); i++) + current_ev = prism54_translate_bss(ndev, current_ev, + extra + IW_SCAN_MAX_DATA, + &(bsslist->bsslist[i]), + noise); + kfree(bsslist); + dwrq->length = (current_ev - extra); + dwrq->flags = 0; /* todo */ + + return rvalue; +} + +static int +prism54_set_essid(struct net_device *ndev, struct iw_request_info *info, + struct iw_point *dwrq, char *extra) +{ + islpci_private *priv = ndev->priv; + struct obj_ssid essid; + + memset(essid.octets, 0, 33); + + /* Check if we were asked for `any' */ + if (dwrq->flags && dwrq->length) { + if (dwrq->length > min(33, IW_ESSID_MAX_SIZE + 1)) + return -E2BIG; + essid.length = dwrq->length - 1; + memcpy(essid.octets, extra, dwrq->length); + } else + essid.length = 0; + + if (priv->iw_mode != IW_MODE_MONITOR) + return mgt_set_request(priv, DOT11_OID_SSID, 0, &essid); + + /* If in monitor mode, just save to mib */ + mgt_set(priv, DOT11_OID_SSID, &essid); + return 0; + +} + +static int +prism54_get_essid(struct net_device *ndev, struct iw_request_info *info, + struct iw_point *dwrq, char *extra) +{ + islpci_private *priv = ndev->priv; + struct obj_ssid *essid; + union oid_res_t r; + int rvalue; + + rvalue = mgt_get_request(priv, DOT11_OID_SSID, 0, NULL, &r); + essid = r.ptr; + + if (essid->length) { + dwrq->flags = 1; /* set ESSID to ON for Wireless Extensions */ + /* if it is to big, trunk it */ + dwrq->length = min(IW_ESSID_MAX_SIZE, essid->length + 1); + } else { + dwrq->flags = 0; + dwrq->length = 0; + } + essid->octets[essid->length] = '\0'; + memcpy(extra, essid->octets, dwrq->length); + kfree(essid); + + return rvalue; +} + +/* Provides no functionality, just completes the ioctl. In essence this is a + * just a cosmetic ioctl. + */ +static int +prism54_set_nick(struct net_device *ndev, struct iw_request_info *info, + struct iw_point *dwrq, char *extra) +{ + islpci_private *priv = ndev->priv; + + if (dwrq->length > IW_ESSID_MAX_SIZE) + return -E2BIG; + + down_write(&priv->mib_sem); + memset(priv->nickname, 0, sizeof (priv->nickname)); + memcpy(priv->nickname, extra, dwrq->length); + up_write(&priv->mib_sem); + + return 0; +} + +static int +prism54_get_nick(struct net_device *ndev, struct iw_request_info *info, + struct iw_point *dwrq, char *extra) +{ + islpci_private *priv = ndev->priv; + + dwrq->length = 0; + + down_read(&priv->mib_sem); + dwrq->length = strlen(priv->nickname) + 1; + memcpy(extra, priv->nickname, dwrq->length); + up_read(&priv->mib_sem); + + return 0; +} + +/* Set the allowed Bitrates */ + +static int +prism54_set_rate(struct net_device *ndev, + struct iw_request_info *info, + struct iw_param *vwrq, char *extra) +{ + + islpci_private *priv = ndev->priv; + u32 rate, profile; + char *data; + int ret, i; + union oid_res_t r; + + if (vwrq->value == -1) { + /* auto mode. No limit. */ + profile = 1; + return mgt_set_request(priv, DOT11_OID_PROFILES, 0, &profile); + } + + if((ret = mgt_get_request(priv, DOT11_OID_SUPPORTEDRATES, 0, NULL, &r))) + return ret; + + rate = (u32) (vwrq->value / 500000); + data = r.ptr; + i = 0; + + while(data[i]) { + if(rate && (data[i] == rate)) { + break; + } + if(vwrq->value == i) { + break; + } + data[i] |= 0x80; + i++; + } + + if(!data[i]) { + return -EINVAL; + } + + data[i] |= 0x80; + data[i + 1] = 0; + + /* Now, check if we want a fixed or auto value */ + if (vwrq->fixed) { + data[0] = data[i]; + data[1] = 0; + } + +/* + i = 0; + printk("prism54 rate: "); + while(data[i]) { + printk("%u ", data[i]); + i++; + } + printk("0\n"); +*/ + profile = -1; + ret = mgt_set_request(priv, DOT11_OID_PROFILES, 0, &profile); + ret |= mgt_set_request(priv, DOT11_OID_EXTENDEDRATES, 0, data); + ret |= mgt_set_request(priv, DOT11_OID_RATES, 0, data); + + kfree(r.ptr); + + return ret; +} + +/* Get the current bit rate */ +static int +prism54_get_rate(struct net_device *ndev, + struct iw_request_info *info, + struct iw_param *vwrq, char *extra) +{ + islpci_private *priv = ndev->priv; + int rvalue; + char *data; + union oid_res_t r; + + /* Get the current bit rate */ + if((rvalue = mgt_get_request(priv, GEN_OID_LINKSTATE, 0, NULL, &r))) + return rvalue; + vwrq->value = r.u * 500000; + + /* request the device for the enabled rates */ + if((rvalue = mgt_get_request(priv, DOT11_OID_RATES, 0, NULL, &r))) + return rvalue; + data = r.ptr; + vwrq->fixed = (data[0] != 0) && (data[1] == 0); + kfree(r.ptr); + + return 0; +} + +static int +prism54_set_rts(struct net_device *ndev, struct iw_request_info *info, + struct iw_param *vwrq, char *extra) +{ + islpci_private *priv = ndev->priv; + + return mgt_set_request(priv, DOT11_OID_RTSTHRESH, 0, &vwrq->value); +} + +static int +prism54_get_rts(struct net_device *ndev, struct iw_request_info *info, + struct iw_param *vwrq, char *extra) +{ + islpci_private *priv = ndev->priv; + union oid_res_t r; + int rvalue; + + /* get the rts threshold */ + rvalue = mgt_get_request(priv, DOT11_OID_RTSTHRESH, 0, NULL, &r); + vwrq->value = r.u; + + return rvalue; +} + +static int +prism54_set_frag(struct net_device *ndev, struct iw_request_info *info, + struct iw_param *vwrq, char *extra) +{ + islpci_private *priv = ndev->priv; + + return mgt_set_request(priv, DOT11_OID_FRAGTHRESH, 0, &vwrq->value); +} + +static int +prism54_get_frag(struct net_device *ndev, struct iw_request_info *info, + struct iw_param *vwrq, char *extra) +{ + islpci_private *priv = ndev->priv; + union oid_res_t r; + int rvalue; + + rvalue = mgt_get_request(priv, DOT11_OID_FRAGTHRESH, 0, NULL, &r); + vwrq->value = r.u; + + return rvalue; +} + +/* Here we have (min,max) = max retries for (small frames, big frames). Where + * big frame <=> bigger than the rts threshold + * small frame <=> smaller than the rts threshold + * This is not really the behavior expected by the wireless tool but it seems + * to be a common behavior in other drivers. + * + * It seems that playing with this tends to hang the card -> DISABLED + */ + +static int +prism54_set_retry(struct net_device *ndev, struct iw_request_info *info, + struct iw_param *vwrq, char *extra) +{ + islpci_private *priv = ndev->priv; + u32 slimit = 0, llimit = 0; /* short and long limit */ + u32 lifetime = 0; + int rvalue = 0; + + if (vwrq->disabled) + /* we cannot disable this feature */ + return -EINVAL; + + if (vwrq->flags & IW_RETRY_LIMIT) { + if (vwrq->flags & IW_RETRY_MIN) + slimit = vwrq->value; + else if (vwrq->flags & IW_RETRY_MAX) + llimit = vwrq->value; + else { + /* we are asked to set both */ + slimit = vwrq->value; + llimit = vwrq->value; + } + } + if (vwrq->flags & IW_RETRY_LIFETIME) + /* Wireless tools use us unit while the device uses 1024 us unit */ + lifetime = vwrq->value / 1024; + + /* now set what is requested */ + + if (slimit != 0) + rvalue = + mgt_set_request(priv, DOT11_OID_SHORTRETRIES, 0, &slimit); + if (llimit != 0) + rvalue |= + mgt_set_request(priv, DOT11_OID_LONGRETRIES, 0, &llimit); + if (lifetime != 0) + rvalue |= + mgt_set_request(priv, DOT11_OID_MAXTXLIFETIME, 0, + &lifetime); + + return rvalue; +} + +static int +prism54_get_retry(struct net_device *ndev, struct iw_request_info *info, + struct iw_param *vwrq, char *extra) +{ + islpci_private *priv = ndev->priv; + union oid_res_t r; + int rvalue = 0; + vwrq->disabled = 0; /* It cannot be disabled */ + + if ((vwrq->flags & IW_RETRY_TYPE) == IW_RETRY_LIFETIME) { + /* we are asked for the life time */ + rvalue = + mgt_get_request(priv, DOT11_OID_MAXTXLIFETIME, 0, NULL, &r); + vwrq->value = r.u * 1024; + vwrq->flags = IW_RETRY_LIFETIME; + } else if ((vwrq->flags & IW_RETRY_MAX)) { + /* we are asked for the long retry limit */ + rvalue |= + mgt_get_request(priv, DOT11_OID_LONGRETRIES, 0, NULL, &r); + vwrq->value = r.u; + vwrq->flags = IW_RETRY_LIMIT | IW_RETRY_MAX; + } else { + /* default. get the short retry limit */ + rvalue |= + mgt_get_request(priv, DOT11_OID_SHORTRETRIES, 0, NULL, &r); + vwrq->value = r.u; + vwrq->flags = IW_RETRY_LIMIT | IW_RETRY_MIN; + } + + return rvalue; +} + +static int +prism54_set_encode(struct net_device *ndev, struct iw_request_info *info, + struct iw_point *dwrq, char *extra) +{ + islpci_private *priv = ndev->priv; + int rvalue = 0, force = 0; + int authen = DOT11_AUTH_OS, invoke = 0, exunencrypt = 0; + union oid_res_t r; + + /* with the new API, it's impossible to get a NULL pointer. + * New version of iwconfig set the IW_ENCODE_NOKEY flag + * when no key is given, but older versions don't. */ + + if (dwrq->length > 0) { + /* we have a key to set */ + int index = (dwrq->flags & IW_ENCODE_INDEX) - 1; + int current_index; + struct obj_key key = { DOT11_PRIV_WEP, 0, "" }; + + /* get the current key index */ + rvalue = mgt_get_request(priv, DOT11_OID_DEFKEYID, 0, NULL, &r); + current_index = r.u; + /* Verify that the key is not marked as invalid */ + if (!(dwrq->flags & IW_ENCODE_NOKEY)) { + key.length = dwrq->length > sizeof (key.key) ? + sizeof (key.key) : dwrq->length; + memcpy(key.key, extra, key.length); + if (key.length == 32) + /* we want WPA-PSK */ + key.type = DOT11_PRIV_TKIP; + if ((index < 0) || (index > 3)) + /* no index provided use the current one */ + index = current_index; + + /* now send the key to the card */ + rvalue |= + mgt_set_request(priv, DOT11_OID_DEFKEYX, index, + &key); + } + /* + * If a valid key is set, encryption should be enabled + * (user may turn it off later). + * This is also how "iwconfig ethX key on" works + */ + if ((index == current_index) && (key.length > 0)) + force = 1; + } else { + int index = (dwrq->flags & IW_ENCODE_INDEX) - 1; + if ((index >= 0) && (index <= 3)) { + /* we want to set the key index */ + rvalue |= + mgt_set_request(priv, DOT11_OID_DEFKEYID, 0, + &index); + } else { + if (!dwrq->flags & IW_ENCODE_MODE) { + /* we cannot do anything. Complain. */ + return -EINVAL; + } + } + } + + /* now read the flags */ + if (dwrq->flags & IW_ENCODE_DISABLED) { + /* Encoding disabled, + * authen = DOT11_AUTH_OS; + * invoke = 0; + * exunencrypt = 0; */ + } + if (dwrq->flags & IW_ENCODE_OPEN) + /* Encode but accept non-encoded packets. No auth */ + invoke = 1; + if ((dwrq->flags & IW_ENCODE_RESTRICTED) || force) { + /* Refuse non-encoded packets. Auth */ + authen = DOT11_AUTH_BOTH; + invoke = 1; + exunencrypt = 1; + } + /* do the change if requested */ + if ((dwrq->flags & IW_ENCODE_MODE) || force) { + rvalue |= + mgt_set_request(priv, DOT11_OID_AUTHENABLE, 0, &authen); + rvalue |= + mgt_set_request(priv, DOT11_OID_PRIVACYINVOKED, 0, &invoke); + rvalue |= + mgt_set_request(priv, DOT11_OID_EXUNENCRYPTED, 0, + &exunencrypt); + } + return rvalue; +} + +static int +prism54_get_encode(struct net_device *ndev, struct iw_request_info *info, + struct iw_point *dwrq, char *extra) +{ + islpci_private *priv = ndev->priv; + struct obj_key *key; + u32 devindex, index = (dwrq->flags & IW_ENCODE_INDEX) - 1; + u32 authen = 0, invoke = 0, exunencrypt = 0; + int rvalue; + union oid_res_t r; + + /* first get the flags */ + rvalue = mgt_get_request(priv, DOT11_OID_AUTHENABLE, 0, NULL, &r); + authen = r.u; + rvalue |= mgt_get_request(priv, DOT11_OID_PRIVACYINVOKED, 0, NULL, &r); + invoke = r.u; + rvalue |= mgt_get_request(priv, DOT11_OID_EXUNENCRYPTED, 0, NULL, &r); + exunencrypt = r.u; + + if (invoke && (authen == DOT11_AUTH_BOTH) && exunencrypt) + dwrq->flags = IW_ENCODE_RESTRICTED; + else if ((authen == DOT11_AUTH_OS) && !exunencrypt) { + if (invoke) + dwrq->flags = IW_ENCODE_OPEN; + else + dwrq->flags = IW_ENCODE_DISABLED; + } else + /* The card should not work in this state */ + dwrq->flags = 0; + + /* get the current device key index */ + rvalue |= mgt_get_request(priv, DOT11_OID_DEFKEYID, 0, NULL, &r); + devindex = r.u; + /* Now get the key, return it */ + if ((index < 0) || (index > 3)) + /* no index provided, use the current one */ + index = devindex; + rvalue |= mgt_get_request(priv, DOT11_OID_DEFKEYX, index, NULL, &r); + key = r.ptr; + dwrq->length = key->length; + memcpy(extra, key->key, dwrq->length); + kfree(key); + /* return the used key index */ + dwrq->flags |= devindex + 1; + + return rvalue; +} + +static int +prism54_get_txpower(struct net_device *ndev, struct iw_request_info *info, + struct iw_param *vwrq, char *extra) +{ + islpci_private *priv = ndev->priv; + union oid_res_t r; + int rvalue; + + rvalue = mgt_get_request(priv, OID_INL_OUTPUTPOWER, 0, NULL, &r); + /* intersil firmware operates in 0.25 dBm (1/4 dBm) */ + vwrq->value = (s32)r.u / 4; + vwrq->fixed = 1; + /* radio is not turned of + * btw: how is possible to turn off only the radio + */ + vwrq->disabled = 0; + + return rvalue; +} + +static int +prism54_set_txpower(struct net_device *ndev, struct iw_request_info *info, + struct iw_param *vwrq, char *extra) +{ + islpci_private *priv = ndev->priv; + s32 u = vwrq->value; + + /* intersil firmware operates in 0.25 dBm (1/4) */ + u *= 4; + if (vwrq->disabled) { + /* don't know how to disable radio */ + printk(KERN_DEBUG + "%s: %s() disabling radio is not yet supported.\n", + priv->ndev->name, __FUNCTION__); + return -ENOTSUPP; + } else if (vwrq->fixed) + /* currently only fixed value is supported */ + return mgt_set_request(priv, OID_INL_OUTPUTPOWER, 0, &u); + else { + printk(KERN_DEBUG + "%s: %s() auto power will be implemented later.\n", + priv->ndev->name, __FUNCTION__); + return -ENOTSUPP; + } +} + +static int +prism54_reset(struct net_device *ndev, struct iw_request_info *info, + __u32 * uwrq, char *extra) +{ + islpci_reset(ndev->priv, 0); + + return 0; +} + +static int +prism54_set_beacon(struct net_device *ndev, struct iw_request_info *info, + __u32 * uwrq, char *extra) +{ + int rvalue = mgt_set_request((islpci_private *) ndev->priv, + DOT11_OID_BEACONPERIOD, 0, uwrq); + + return (rvalue ? rvalue : -EINPROGRESS); +} + +static int +prism54_get_beacon(struct net_device *ndev, struct iw_request_info *info, + __u32 * uwrq, char *extra) +{ + union oid_res_t r; + int rvalue; + + rvalue = + mgt_get_request((islpci_private *) ndev->priv, + DOT11_OID_BEACONPERIOD, 0, NULL, &r); + *uwrq = r.u; + + return rvalue; +} + +void +prism54_acl_init(struct islpci_acl *acl) +{ + sema_init(&acl->sem, 1); + INIT_LIST_HEAD(&acl->mac_list); + acl->size = 0; + acl->policy = MAC_POLICY_OPEN; +} + +static void +prism54_clear_mac(struct islpci_acl *acl) +{ + struct list_head *ptr, *next; + struct mac_entry *entry; + + if (down_interruptible(&acl->sem)) + return; + + if (acl->size == 0) { + up(&acl->sem); + return; + } + + for (ptr = acl->mac_list.next, next = ptr->next; + ptr != &acl->mac_list; ptr = next, next = ptr->next) { + entry = list_entry(ptr, struct mac_entry, _list); + list_del(ptr); + kfree(entry); + } + acl->size = 0; + up(&acl->sem); +} + +void +prism54_acl_clean(struct islpci_acl *acl) +{ + prism54_clear_mac(acl); +} + +static int +prism54_add_mac(struct net_device *ndev, struct iw_request_info *info, + struct sockaddr *awrq, char *extra) +{ + islpci_private *priv = ndev->priv; + struct islpci_acl *acl = &priv->acl; + struct mac_entry *entry; + struct sockaddr *addr = (struct sockaddr *) extra; + + if (addr->sa_family != ARPHRD_ETHER) + return -EOPNOTSUPP; + + entry = kmalloc(sizeof (struct mac_entry), GFP_KERNEL); + if (entry == NULL) + return -ENOMEM; + + memcpy(entry->addr, addr->sa_data, ETH_ALEN); + + if (down_interruptible(&acl->sem)) { + kfree(entry); + return -ERESTARTSYS; + } + list_add_tail(&entry->_list, &acl->mac_list); + acl->size++; + up(&acl->sem); + + return 0; +} + +static int +prism54_del_mac(struct net_device *ndev, struct iw_request_info *info, + struct sockaddr *awrq, char *extra) +{ + islpci_private *priv = ndev->priv; + struct islpci_acl *acl = &priv->acl; + struct mac_entry *entry; + struct list_head *ptr; + struct sockaddr *addr = (struct sockaddr *) extra; + + if (addr->sa_family != ARPHRD_ETHER) + return -EOPNOTSUPP; + + if (down_interruptible(&acl->sem)) + return -ERESTARTSYS; + for (ptr = acl->mac_list.next; ptr != &acl->mac_list; ptr = ptr->next) { + entry = list_entry(ptr, struct mac_entry, _list); + + if (memcmp(entry->addr, addr->sa_data, ETH_ALEN) == 0) { + list_del(ptr); + acl->size--; + kfree(entry); + up(&acl->sem); + return 0; + } + } + up(&acl->sem); + return -EINVAL; +} + +static int +prism54_get_mac(struct net_device *ndev, struct iw_request_info *info, + struct iw_point *dwrq, char *extra) +{ + islpci_private *priv = ndev->priv; + struct islpci_acl *acl = &priv->acl; + struct mac_entry *entry; + struct list_head *ptr; + struct sockaddr *dst = (struct sockaddr *) extra; + + dwrq->length = 0; + + if (down_interruptible(&acl->sem)) + return -ERESTARTSYS; + + for (ptr = acl->mac_list.next; ptr != &acl->mac_list; ptr = ptr->next) { + entry = list_entry(ptr, struct mac_entry, _list); + + memcpy(dst->sa_data, entry->addr, ETH_ALEN); + dst->sa_family = ARPHRD_ETHER; + dwrq->length++; + dst++; + } + up(&acl->sem); + return 0; +} + +/* Setting policy also clears the MAC acl, even if we don't change the defaut + * policy + */ + +static int +prism54_set_policy(struct net_device *ndev, struct iw_request_info *info, + __u32 * uwrq, char *extra) +{ + islpci_private *priv = ndev->priv; + struct islpci_acl *acl = &priv->acl; + u32 mlmeautolevel; + + prism54_clear_mac(acl); + + if ((*uwrq < MAC_POLICY_OPEN) || (*uwrq > MAC_POLICY_REJECT)) + return -EINVAL; + + down_write(&priv->mib_sem); + + acl->policy = *uwrq; + + /* the ACL code needs an intermediate mlmeautolevel */ + if ((priv->iw_mode == IW_MODE_MASTER) && + (acl->policy != MAC_POLICY_OPEN)) + mlmeautolevel = DOT11_MLME_INTERMEDIATE; + else + mlmeautolevel = CARD_DEFAULT_MLME_MODE; + if (priv->wpa) + mlmeautolevel = DOT11_MLME_EXTENDED; + mgt_set(priv, DOT11_OID_MLMEAUTOLEVEL, &mlmeautolevel); + /* restart the card with our new policy */ + mgt_commit(priv); + up_write(&priv->mib_sem); + + return 0; +} + +static int +prism54_get_policy(struct net_device *ndev, struct iw_request_info *info, + __u32 * uwrq, char *extra) +{ + islpci_private *priv = ndev->priv; + struct islpci_acl *acl = &priv->acl; + + *uwrq = acl->policy; + + return 0; +} + +/* Return 1 only if client should be accepted. */ + +static int +prism54_mac_accept(struct islpci_acl *acl, char *mac) +{ + struct list_head *ptr; + struct mac_entry *entry; + int res = 0; + + if (down_interruptible(&acl->sem)) + return -ERESTARTSYS; + + if (acl->policy == MAC_POLICY_OPEN) { + up(&acl->sem); + return 1; + } + + for (ptr = acl->mac_list.next; ptr != &acl->mac_list; ptr = ptr->next) { + entry = list_entry(ptr, struct mac_entry, _list); + if (memcmp(entry->addr, mac, ETH_ALEN) == 0) { + res = 1; + break; + } + } + res = (acl->policy == MAC_POLICY_ACCEPT) ? !res : res; + up(&acl->sem); + + return res; +} + +static int +prism54_kick_all(struct net_device *ndev, struct iw_request_info *info, + struct iw_point *dwrq, char *extra) +{ + struct obj_mlme *mlme; + int rvalue; + + mlme = kmalloc(sizeof (struct obj_mlme), GFP_KERNEL); + if (mlme == NULL) + return -ENOMEM; + + /* Tell the card to kick every client */ + mlme->id = cpu_to_le16(0); + rvalue = mgt_set_request(ndev->priv, DOT11_OID_DISASSOCIATE, 0, mlme); + kfree(mlme); + + return rvalue; +} + +static int +prism54_kick_mac(struct net_device *ndev, struct iw_request_info *info, + struct sockaddr *awrq, char *extra) +{ + struct obj_mlme *mlme; + struct sockaddr *addr = (struct sockaddr *) extra; + int rvalue; + + if (addr->sa_family != ARPHRD_ETHER) + return -EOPNOTSUPP; + + mlme = kmalloc(sizeof (struct obj_mlme), GFP_KERNEL); + if (mlme == NULL) + return -ENOMEM; + + /* Tell the card to only kick the corresponding bastard */ + memcpy(mlme->address, addr->sa_data, ETH_ALEN); + mlme->id = cpu_to_le16(-1); + rvalue = mgt_set_request(ndev->priv, DOT11_OID_DISASSOCIATE, 0, mlme); + + kfree(mlme); + + return rvalue; +} + +/* Translate a TRAP oid into a wireless event. Called in islpci_mgt_receive. */ + +static inline void +format_event(islpci_private *priv, char *dest, const char *str, + const struct obj_mlme *mlme, u16 *length, int error) +{ + const u8 *a = mlme->address; + int n = snprintf(dest, IW_CUSTOM_MAX, + "%s %s %2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X %s", + str, + ((priv->iw_mode == IW_MODE_MASTER) ? "to" : "from"), + a[0], a[1], a[2], a[3], a[4], a[5], + (error ? (mlme->code ? " : REJECTED " : " : ACCEPTED ") + : "")); + BUG_ON(n > IW_CUSTOM_MAX); + *length = n; +} + +static void +send_formatted_event(islpci_private *priv, const char *str, + const struct obj_mlme *mlme, int error) +{ + union iwreq_data wrqu; + + wrqu.data.pointer = kmalloc(IW_CUSTOM_MAX, GFP_KERNEL); + if (!wrqu.data.pointer) + return; + wrqu.data.length = 0; + format_event(priv, wrqu.data.pointer, str, mlme, &wrqu.data.length, + error); + wireless_send_event(priv->ndev, IWEVCUSTOM, &wrqu, wrqu.data.pointer); + kfree(wrqu.data.pointer); +} + +static void +send_simple_event(islpci_private *priv, const char *str) +{ + union iwreq_data wrqu; + int n = strlen(str); + + wrqu.data.pointer = kmalloc(IW_CUSTOM_MAX, GFP_KERNEL); + if (!wrqu.data.pointer) + return; + BUG_ON(n > IW_CUSTOM_MAX); + wrqu.data.length = n; + strcpy(wrqu.data.pointer, str); + wireless_send_event(priv->ndev, IWEVCUSTOM, &wrqu, wrqu.data.pointer); + kfree(wrqu.data.pointer); +} + +static void +link_changed(struct net_device *ndev, u32 bitrate) +{ + islpci_private *priv = ndev->priv; + + if (le32_to_cpu(bitrate)) { + if (priv->iw_mode == IW_MODE_INFRA) { + union iwreq_data uwrq; + prism54_get_wap(ndev, NULL, (struct sockaddr *) &uwrq, + NULL); + wireless_send_event(ndev, SIOCGIWAP, &uwrq, NULL); + } else + send_simple_event(ndev->priv, "Link established"); + } else + send_simple_event(ndev->priv, "Link lost"); +} + +/* Beacon/ProbeResp payload header */ +struct ieee80211_beacon_phdr { + u8 timestamp[8]; + u16 beacon_int; + u16 capab_info; +} __attribute__ ((packed)); + +#define WLAN_EID_GENERIC 0xdd +static u8 wpa_oid[4] = { 0x00, 0x50, 0xf2, 1 }; + +#define MAC2STR(a) (a)[0], (a)[1], (a)[2], (a)[3], (a)[4], (a)[5] +#define MACSTR "%02x:%02x:%02x:%02x:%02x:%02x" + +void +prism54_wpa_ie_add(islpci_private *priv, u8 *bssid, + u8 *wpa_ie, size_t wpa_ie_len) +{ + struct list_head *ptr; + struct islpci_bss_wpa_ie *bss = NULL; + + if (wpa_ie_len > MAX_WPA_IE_LEN) + wpa_ie_len = MAX_WPA_IE_LEN; + + if (down_interruptible(&priv->wpa_sem)) + return; + + /* try to use existing entry */ + list_for_each(ptr, &priv->bss_wpa_list) { + bss = list_entry(ptr, struct islpci_bss_wpa_ie, list); + if (memcmp(bss->bssid, bssid, ETH_ALEN) == 0) { + list_move(&bss->list, &priv->bss_wpa_list); + break; + } + bss = NULL; + } + + if (bss == NULL) { + /* add a new BSS entry; if max number of entries is already + * reached, replace the least recently updated */ + if (priv->num_bss_wpa >= MAX_BSS_WPA_IE_COUNT) { + bss = list_entry(priv->bss_wpa_list.prev, + struct islpci_bss_wpa_ie, list); + list_del(&bss->list); + } else { + bss = kmalloc(sizeof (*bss), GFP_ATOMIC); + if (bss != NULL) { + priv->num_bss_wpa++; + memset(bss, 0, sizeof (*bss)); + } + } + if (bss != NULL) { + memcpy(bss->bssid, bssid, ETH_ALEN); + list_add(&bss->list, &priv->bss_wpa_list); + } + } + + if (bss != NULL) { + memcpy(bss->wpa_ie, wpa_ie, wpa_ie_len); + bss->wpa_ie_len = wpa_ie_len; + bss->last_update = jiffies; + } else { + printk(KERN_DEBUG "Failed to add BSS WPA entry for " MACSTR + "\n", MAC2STR(bssid)); + } + + /* expire old entries from WPA list */ + while (priv->num_bss_wpa > 0) { + bss = list_entry(priv->bss_wpa_list.prev, + struct islpci_bss_wpa_ie, list); + if (!time_after(jiffies, bss->last_update + 60 * HZ)) + break; + + list_del(&bss->list); + priv->num_bss_wpa--; + kfree(bss); + } + + up(&priv->wpa_sem); +} + +size_t +prism54_wpa_ie_get(islpci_private *priv, u8 *bssid, u8 *wpa_ie) +{ + struct list_head *ptr; + struct islpci_bss_wpa_ie *bss = NULL; + size_t len = 0; + + if (down_interruptible(&priv->wpa_sem)) + return 0; + + list_for_each(ptr, &priv->bss_wpa_list) { + bss = list_entry(ptr, struct islpci_bss_wpa_ie, list); + if (memcmp(bss->bssid, bssid, ETH_ALEN) == 0) + break; + bss = NULL; + } + if (bss) { + len = bss->wpa_ie_len; + memcpy(wpa_ie, bss->wpa_ie, len); + } + up(&priv->wpa_sem); + + return len; +} + +void +prism54_wpa_ie_init(islpci_private *priv) +{ + INIT_LIST_HEAD(&priv->bss_wpa_list); + sema_init(&priv->wpa_sem, 1); +} + +void +prism54_wpa_ie_clean(islpci_private *priv) +{ + struct list_head *ptr, *n; + + list_for_each_safe(ptr, n, &priv->bss_wpa_list) { + struct islpci_bss_wpa_ie *bss; + bss = list_entry(ptr, struct islpci_bss_wpa_ie, list); + kfree(bss); + } +} + +static void +prism54_process_bss_data(islpci_private *priv, u32 oid, u8 *addr, + u8 *payload, size_t len) +{ + struct ieee80211_beacon_phdr *hdr; + u8 *pos, *end; + + if (!priv->wpa) + return; + + hdr = (struct ieee80211_beacon_phdr *) payload; + pos = (u8 *) (hdr + 1); + end = payload + len; + while (pos < end) { + if (pos + 2 + pos[1] > end) { + printk(KERN_DEBUG "Parsing Beacon/ProbeResp failed " + "for " MACSTR "\n", MAC2STR(addr)); + return; + } + if (pos[0] == WLAN_EID_GENERIC && pos[1] >= 4 && + memcmp(pos + 2, wpa_oid, 4) == 0) { + prism54_wpa_ie_add(priv, addr, pos, pos[1] + 2); + return; + } + pos += 2 + pos[1]; + } +} + +static void +handle_request(islpci_private *priv, struct obj_mlme *mlme, enum oid_num_t oid) +{ + if (((le16_to_cpu(mlme->state) == DOT11_STATE_AUTHING) || + (le16_to_cpu(mlme->state) == DOT11_STATE_ASSOCING)) + && mgt_mlme_answer(priv)) { + /* Someone is requesting auth and we must respond. Just send back + * the trap with error code set accordingly. + */ + mlme->code = cpu_to_le16(prism54_mac_accept(&priv->acl, + mlme-> + address) ? 0 : 1); + mgt_set_request(priv, oid, 0, mlme); + } +} + +int +prism54_process_trap_helper(islpci_private *priv, enum oid_num_t oid, + char *data) +{ + struct obj_mlme *mlme = (struct obj_mlme *) data; + size_t len; + u8 *payload, *pos = (u8 *) (mlme + 1); + + len = pos[0] | (pos[1] << 8); /* little endian data length */ + payload = pos + 2; + + /* I think all trapable objects are listed here. + * Some oids have a EX version. The difference is that they are emitted + * in DOT11_MLME_EXTENDED mode (set with DOT11_OID_MLMEAUTOLEVEL) + * with more info. + * The few events already defined by the wireless tools are not really + * suited. We use the more flexible custom event facility. + */ + + switch (oid) { + + case GEN_OID_LINKSTATE: + link_changed(priv->ndev, (u32) *data); + break; + + case DOT11_OID_MICFAILURE: + send_simple_event(priv, "Mic failure"); + break; + + case DOT11_OID_DEAUTHENTICATE: + send_formatted_event(priv, "DeAuthenticate request", mlme, 0); + break; + + case DOT11_OID_AUTHENTICATE: + handle_request(priv, mlme, oid); + send_formatted_event(priv, "Authenticate request", mlme, 1); + break; + + case DOT11_OID_DISASSOCIATE: + send_formatted_event(priv, "Disassociate request", mlme, 0); + break; + + case DOT11_OID_ASSOCIATE: + handle_request(priv, mlme, oid); + send_formatted_event(priv, "Associate request", mlme, 1); + break; + + case DOT11_OID_REASSOCIATE: + handle_request(priv, mlme, oid); + send_formatted_event(priv, "ReAssociate request", mlme, 1); + break; + + case DOT11_OID_BEACON: + prism54_process_bss_data(priv, oid, mlme->address, + payload, len); + send_formatted_event(priv, + "Received a beacon from an unkown AP", + mlme, 0); + break; + + case DOT11_OID_PROBE: + /* we received a probe from a client. */ + prism54_process_bss_data(priv, oid, mlme->address, + payload, len); + send_formatted_event(priv, "Received a probe from client", mlme, + 0); + break; + + /* Note : the following should never happen since we don't run the card in + * extended mode. + * Note : "mlme" is actually a "struct obj_mlmeex *" here, but this + * is backward compatible layout-wise with "struct obj_mlme". + */ + + case DOT11_OID_DEAUTHENTICATEEX: + send_formatted_event(priv, "DeAuthenticate request", mlme, 0); + break; + + case DOT11_OID_AUTHENTICATEEX: + handle_request(priv, mlme, oid); + send_formatted_event(priv, "Authenticate request", mlme, 1); + break; + + case DOT11_OID_DISASSOCIATEEX: + send_formatted_event(priv, "Disassociate request", mlme, 0); + break; + + case DOT11_OID_ASSOCIATEEX: + handle_request(priv, mlme, oid); + send_formatted_event(priv, "Associate request", mlme, 1); + break; + + case DOT11_OID_REASSOCIATEEX: + handle_request(priv, mlme, oid); + send_formatted_event(priv, "Reassociate request", mlme, 1); + break; + + default: + return -EINVAL; + } + + return 0; +} + +/* + * Process a device trap. This is called via schedule_work(), outside of + * interrupt context, no locks held. + */ +void +prism54_process_trap(void *data) +{ + struct islpci_mgmtframe *frame = data; + enum oid_num_t n = mgt_oidtonum(frame->header->oid); + + prism54_process_trap_helper(frame->ndev->priv, n, frame->data); + islpci_mgt_release(frame); +} + +int +prism54_set_mac_address(struct net_device *ndev, void *addr) +{ + islpci_private *priv = ndev->priv; + int ret; + + if (ndev->addr_len != 6) + return -EINVAL; + ret = mgt_set_request(priv, GEN_OID_MACADDRESS, 0, + &((struct sockaddr *) addr)->sa_data); + if (!ret) + memcpy(priv->ndev->dev_addr, + &((struct sockaddr *) addr)->sa_data, 6); + + return ret; +} + +int +prism54_ioctl(struct net_device *ndev, struct ifreq *rq, int cmd) +{ + /* should we really support this old stuff ? */ + return -EOPNOTSUPP; +} + +int +prism54_set_wpa(struct net_device *ndev, struct iw_request_info *info, + __u32 * uwrq, char *extra) +{ + islpci_private *priv = ndev->priv; + + down_write(&priv->mib_sem); + + priv->wpa = *uwrq; + if (priv->wpa) { + u32 l = DOT11_MLME_EXTENDED; + mgt_set(priv, DOT11_OID_MLMEAUTOLEVEL, &l); + } + /* restart the card with new level. Needed ? */ + mgt_commit(priv); + up_write(&priv->mib_sem); + + return 0; +} + +int +prism54_get_wpa(struct net_device *ndev, struct iw_request_info *info, + __u32 * uwrq, char *extra) +{ + islpci_private *priv = ndev->priv; + *uwrq = priv->wpa; + return 0; +} + +int +prism54_oid(struct net_device *ndev, struct iw_request_info *info, + __u32 *uwrq, char *extra) +{ + islpci_private *priv = ndev->priv; + + priv->priv_oid = *uwrq; + printk("%s: oid 0x%08X\n", ndev->name, *uwrq); + + return 0; +} + +int +prism54_get_oid(struct net_device *ndev, struct iw_request_info *info, + struct iw_point *data, char *extra) +{ + islpci_private *priv = ndev->priv; + struct islpci_mgmtframe *response = NULL; + int ret = -EIO, response_op = PIMFOR_OP_ERROR; + + printk("%s: get_oid 0x%08X\n", ndev->name, priv->priv_oid); + data->length = 0; + + if (islpci_get_state(priv) >= PRV_STATE_INIT) { + ret = islpci_mgt_transaction(priv->ndev, PIMFOR_OP_GET, priv->priv_oid, extra, 256, &response); + response_op = response->header->operation; + printk("%s: ret: %i\n", ndev->name, ret); + printk("%s: response_op: %i\n", ndev->name, response_op); + if (ret || !response || response->header->operation == PIMFOR_OP_ERROR) { + if (response) { + islpci_mgt_release(response); + } + printk("%s: EIO\n", ndev->name); + ret = -EIO; + } + if (!ret) { + data->length = response->header->length; + memcpy(extra, response->data, data->length); + islpci_mgt_release(response); + printk("%s: len: %i\n", ndev->name, data->length); + } + } + + return ret; +} + +int +prism54_set_oid(struct net_device *ndev, struct iw_request_info *info, + struct iw_point *data, char *extra) +{ + islpci_private *priv = ndev->priv; + struct islpci_mgmtframe *response = NULL; + int ret = 0, response_op = PIMFOR_OP_ERROR; + + printk("%s: set_oid 0x%08X\tlen: %d\n", ndev->name, priv->priv_oid, data->length); + + if (islpci_get_state(priv) >= PRV_STATE_INIT) { + ret = islpci_mgt_transaction(priv->ndev, PIMFOR_OP_SET, priv->priv_oid, extra, data->length, &response); + printk("%s: ret: %i\n", ndev->name, ret); + if (!ret) { + response_op = response->header->operation; + printk("%s: response_op: %i\n", ndev->name, response_op); + islpci_mgt_release(response); + } + if (ret || response_op == PIMFOR_OP_ERROR) { + printk("%s: EIO\n", ndev->name); + ret = -EIO; + } + } + + return ret; +} + +static const iw_handler prism54_handler[] = { + (iw_handler) prism54_commit, /* SIOCSIWCOMMIT */ + (iw_handler) prism54_get_name, /* SIOCGIWNAME */ + (iw_handler) NULL, /* SIOCSIWNWID */ + (iw_handler) NULL, /* SIOCGIWNWID */ + (iw_handler) prism54_set_freq, /* SIOCSIWFREQ */ + (iw_handler) prism54_get_freq, /* SIOCGIWFREQ */ + (iw_handler) prism54_set_mode, /* SIOCSIWMODE */ + (iw_handler) prism54_get_mode, /* SIOCGIWMODE */ + (iw_handler) prism54_set_sens, /* SIOCSIWSENS */ + (iw_handler) prism54_get_sens, /* SIOCGIWSENS */ + (iw_handler) NULL, /* SIOCSIWRANGE */ + (iw_handler) prism54_get_range, /* SIOCGIWRANGE */ + (iw_handler) NULL, /* SIOCSIWPRIV */ + (iw_handler) NULL, /* SIOCGIWPRIV */ + (iw_handler) NULL, /* SIOCSIWSTATS */ + (iw_handler) NULL, /* SIOCGIWSTATS */ + iw_handler_set_spy, /* SIOCSIWSPY */ + iw_handler_get_spy, /* SIOCGIWSPY */ + iw_handler_set_thrspy, /* SIOCSIWTHRSPY */ + iw_handler_get_thrspy, /* SIOCGIWTHRSPY */ + (iw_handler) prism54_set_wap, /* SIOCSIWAP */ + (iw_handler) prism54_get_wap, /* SIOCGIWAP */ + (iw_handler) NULL, /* -- hole -- */ + (iw_handler) NULL, /* SIOCGIWAPLIST depreciated */ + (iw_handler) prism54_set_scan, /* SIOCSIWSCAN */ + (iw_handler) prism54_get_scan, /* SIOCGIWSCAN */ + (iw_handler) prism54_set_essid, /* SIOCSIWESSID */ + (iw_handler) prism54_get_essid, /* SIOCGIWESSID */ + (iw_handler) prism54_set_nick, /* SIOCSIWNICKN */ + (iw_handler) prism54_get_nick, /* SIOCGIWNICKN */ + (iw_handler) NULL, /* -- hole -- */ + (iw_handler) NULL, /* -- hole -- */ + (iw_handler) prism54_set_rate, /* SIOCSIWRATE */ + (iw_handler) prism54_get_rate, /* SIOCGIWRATE */ + (iw_handler) prism54_set_rts, /* SIOCSIWRTS */ + (iw_handler) prism54_get_rts, /* SIOCGIWRTS */ + (iw_handler) prism54_set_frag, /* SIOCSIWFRAG */ + (iw_handler) prism54_get_frag, /* SIOCGIWFRAG */ + (iw_handler) prism54_set_txpower, /* SIOCSIWTXPOW */ + (iw_handler) prism54_get_txpower, /* SIOCGIWTXPOW */ + (iw_handler) prism54_set_retry, /* SIOCSIWRETRY */ + (iw_handler) prism54_get_retry, /* SIOCGIWRETRY */ + (iw_handler) prism54_set_encode, /* SIOCSIWENCODE */ + (iw_handler) prism54_get_encode, /* SIOCGIWENCODE */ + (iw_handler) NULL, /* SIOCSIWPOWER */ + (iw_handler) NULL, /* SIOCGIWPOWER */ +}; + +/* The low order bit identify a SET (0) or a GET (1) ioctl. */ + +#define PRISM54_RESET SIOCIWFIRSTPRIV +#define PRISM54_GET_BEACON SIOCIWFIRSTPRIV+1 +#define PRISM54_SET_BEACON SIOCIWFIRSTPRIV+2 +#define PRISM54_GET_POLICY SIOCIWFIRSTPRIV+3 +#define PRISM54_SET_POLICY SIOCIWFIRSTPRIV+4 +#define PRISM54_GET_MAC SIOCIWFIRSTPRIV+5 +#define PRISM54_ADD_MAC SIOCIWFIRSTPRIV+6 + +#define PRISM54_DEL_MAC SIOCIWFIRSTPRIV+8 + +#define PRISM54_KICK_MAC SIOCIWFIRSTPRIV+10 + +#define PRISM54_KICK_ALL SIOCIWFIRSTPRIV+12 + +#define PRISM54_GET_WPA SIOCIWFIRSTPRIV+13 +#define PRISM54_SET_WPA SIOCIWFIRSTPRIV+14 + +#define PRISM54_OID SIOCIWFIRSTPRIV+16 +#define PRISM54_GET_OID SIOCIWFIRSTPRIV+17 +#define PRISM54_SET_OID SIOCIWFIRSTPRIV+18 + +static const struct iw_priv_args prism54_private_args[] = { +/*{ cmd, set_args, get_args, name } */ + {PRISM54_RESET, 0, 0, "reset"}, + {PRISM54_GET_BEACON, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + "getBeaconPeriod"}, + {PRISM54_SET_BEACON, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, + "setBeaconPeriod"}, + {PRISM54_GET_POLICY, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + "getPolicy"}, + {PRISM54_SET_POLICY, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, + "setPolicy"}, + {PRISM54_GET_MAC, 0, IW_PRIV_TYPE_ADDR | 64, "getMac"}, + {PRISM54_ADD_MAC, IW_PRIV_TYPE_ADDR | IW_PRIV_SIZE_FIXED | 1, 0, + "addMac"}, + {PRISM54_DEL_MAC, IW_PRIV_TYPE_ADDR | IW_PRIV_SIZE_FIXED | 1, 0, + "delMac"}, + {PRISM54_KICK_MAC, IW_PRIV_TYPE_ADDR | IW_PRIV_SIZE_FIXED | 1, 0, + "kickMac"}, + {PRISM54_KICK_ALL, 0, 0, "kickAll"}, + {PRISM54_GET_WPA, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + "get_wpa"}, + {PRISM54_SET_WPA, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, + "set_wpa"}, + {PRISM54_OID, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "oid"}, + {PRISM54_GET_OID, 0, IW_PRIV_TYPE_BYTE | 256, "get_oid"}, + {PRISM54_SET_OID, IW_PRIV_TYPE_BYTE | 256, 0, "set_oid"}, +}; + +static const iw_handler prism54_private_handler[] = { + (iw_handler) prism54_reset, + (iw_handler) prism54_get_beacon, + (iw_handler) prism54_set_beacon, + (iw_handler) prism54_get_policy, + (iw_handler) prism54_set_policy, + (iw_handler) prism54_get_mac, + (iw_handler) prism54_add_mac, + (iw_handler) NULL, + (iw_handler) prism54_del_mac, + (iw_handler) NULL, + (iw_handler) prism54_kick_mac, + (iw_handler) NULL, + (iw_handler) prism54_kick_all, + (iw_handler) prism54_get_wpa, + (iw_handler) prism54_set_wpa, + (iw_handler) NULL, + (iw_handler) prism54_oid, + (iw_handler) prism54_get_oid, + (iw_handler) prism54_set_oid, +}; + +const struct iw_handler_def prism54_handler_def = { + .num_standard = sizeof (prism54_handler) / sizeof (iw_handler), + .num_private = sizeof (prism54_private_handler) / sizeof (iw_handler), + .num_private_args = + sizeof (prism54_private_args) / sizeof (struct iw_priv_args), + .standard = (iw_handler *) prism54_handler, + .private = (iw_handler *) prism54_private_handler, + .private_args = (struct iw_priv_args *) prism54_private_args, +}; + diff -Nru a/drivers/net/wireless/prism54/isl_ioctl.h b/drivers/net/wireless/prism54/isl_ioctl.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/drivers/net/wireless/prism54/isl_ioctl.h Sun Mar 14 14:20:09 2004 @@ -0,0 +1,55 @@ +/* $Header: /var/lib/cvs/prism54-ng/ksrc/isl_ioctl.h,v 1.30 2004/01/30 16:24:00 ajfa Exp $ + * + * Copyright (C) 2002 Intersil Americas Inc. + * (C) 2003 Aurelien Alleaume + * (C) 2003 Luis R. Rodriguez + * + * 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 + * + * 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 + * + */ + +#ifndef _ISL_IOCTL_H +#define _ISL_IOCTL_H + +#include "islpci_mgt.h" +#include "islpci_dev.h" + +#include /* New driver API */ + +#define SUPPORTED_WIRELESS_EXT 16 + +void prism54_mib_init(islpci_private *); +void prism54_mib_init_work(islpci_private *); + +struct iw_statistics *prism54_get_wireless_stats(struct net_device *); +void prism54_update_stats(islpci_private *); + +void prism54_acl_init(struct islpci_acl *); +void prism54_acl_clean(struct islpci_acl *); + +void prism54_process_trap(void *); + +void prism54_wpa_ie_init(islpci_private *priv); +void prism54_wpa_ie_clean(islpci_private *priv); +void prism54_wpa_ie_add(islpci_private *priv, u8 *bssid, + u8 *wpa_ie, size_t wpa_ie_len); +size_t prism54_wpa_ie_get(islpci_private *priv, u8 *bssid, u8 *wpa_ie); + +int prism54_set_mac_address(struct net_device *, void *); + +int prism54_ioctl(struct net_device *, struct ifreq *, int); + +extern const struct iw_handler_def prism54_handler_def; + +#endif /* _ISL_IOCTL_H */ diff -Nru a/drivers/net/wireless/prism54/isl_oid.h b/drivers/net/wireless/prism54/isl_oid.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/drivers/net/wireless/prism54/isl_oid.h Sun Mar 14 14:20:09 2004 @@ -0,0 +1,365 @@ +/* + * $Id: isl_oid.h,v 1.2 2004/01/30 16:24:00 ajfa Exp $ + * + * Copyright (C) 2003 Herbert Valerio Riedel + * + * 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 + * + * 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 + * + */ + +#if !defined(_ISL_OID_H) +#define _ISL_OID_H + +/* + * MIB related constant and structure definitions for communicating + * with the device firmware + */ + +struct obj_ssid { + u8 length; + char octets[33]; +} __attribute__ ((packed)); + +struct obj_key { + u8 type; /* dot11_priv_t */ + u8 length; + char key[32]; +} __attribute__ ((packed)); + +struct obj_mlme { + u8 address[6]; + u16 id; + u16 state; + u16 code; +} __attribute__ ((packed)); + +struct obj_mlmeex { + u8 address[6]; + u16 id; + u16 state; + u16 code; + u16 size; + u8 data[0]; +} __attribute__ ((packed)); + +struct obj_buffer { + u32 size; + u32 addr; /* 32bit bus address */ +} __attribute__ ((packed)); + +struct obj_bss { + u8 address[6]; + int:16; /* padding */ + + char state; + char reserved; + short age; + + char quality; + char rssi; + + struct obj_ssid ssid; + short channel; + char beacon_period; + char dtim_period; + short capinfo; + short rates; + short basic_rates; + int:16; /* padding */ +} __attribute__ ((packed)); + +struct obj_bsslist { + u32 nr; + struct obj_bss bsslist[0]; +} __attribute__ ((packed)); + +struct obj_frequencies { + u16 nr; + u16 mhz[0]; +} __attribute__ ((packed)); + +/* + * in case everything's ok, the inlined function below will be + * optimized away by the compiler... + */ +static inline void +__bug_on_wrong_struct_sizes(void) +{ + BUG_ON(sizeof (struct obj_ssid) != 34); + BUG_ON(sizeof (struct obj_key) != 34); + BUG_ON(sizeof (struct obj_mlme) != 12); + BUG_ON(sizeof (struct obj_mlmeex) != 14); + BUG_ON(sizeof (struct obj_buffer) != 8); + BUG_ON(sizeof (struct obj_bss) != 60); + BUG_ON(sizeof (struct obj_bsslist) != 4); + BUG_ON(sizeof (struct obj_frequencies) != 2); +} + +enum dot11_state_t { + DOT11_STATE_NONE = 0, + DOT11_STATE_AUTHING = 1, + DOT11_STATE_AUTH = 2, + DOT11_STATE_ASSOCING = 3, + + DOT11_STATE_ASSOC = 5, + DOT11_STATE_IBSS = 6, + DOT11_STATE_WDS = 7 +}; + +enum dot11_bsstype_t { + DOT11_BSSTYPE_NONE = 0, + DOT11_BSSTYPE_INFRA = 1, + DOT11_BSSTYPE_IBSS = 2, + DOT11_BSSTYPE_ANY = 3 +}; + +enum dot11_auth_t { + DOT11_AUTH_NONE = 0, + DOT11_AUTH_OS = 1, + DOT11_AUTH_SK = 2, + DOT11_AUTH_BOTH = 3 +}; + +enum dot11_mlme_t { + DOT11_MLME_AUTO = 0, + DOT11_MLME_INTERMEDIATE = 1, + DOT11_MLME_EXTENDED = 2 +}; + +enum dot11_priv_t { + DOT11_PRIV_WEP = 0, + DOT11_PRIV_TKIP = 1 +}; + +/* The dot11d conformance level configures the 802.11d conformance levels. + * The following conformance levels exist:*/ +enum oid_inl_conformance_t { + OID_INL_CONFORMANCE_NONE = 0, /* Perform active scanning */ + OID_INL_CONFORMANCE_STRICT = 1, /* Strictly adhere to 802.11d */ + OID_INL_CONFORMANCE_FLEXIBLE = 2, /* Use passed 802.11d info to + * determine channel AND/OR just make + * assumption that active + * channels are valid channels */ +}; + +enum oid_inl_mode_t { + INL_MODE_NONE = -1, + INL_MODE_PROMISCUOUS = 0, + INL_MODE_CLIENT = 1, + INL_MODE_AP = 2, + INL_MODE_SNIFFER = 3 +}; + +enum oid_inl_config_t { + INL_CONFIG_NOTHING = 0x00, + INL_CONFIG_MANUALRUN = 0x01, + INL_CONFIG_FRAMETRAP = 0x02, + INL_CONFIG_RXANNEX = 0x04, + INL_CONFIG_TXANNEX = 0x08, + INL_CONFIG_WDS = 0x10 +}; + +enum oid_inl_phycap_t { + INL_PHYCAP_2400MHZ = 1, + INL_PHYCAP_5000MHZ = 2, + INL_PHYCAP_FAA = 0x80000000, /* Means card supports the FAA switch */ +}; + +enum oid_num_t { + GEN_OID_MACADDRESS = 0, + GEN_OID_LINKSTATE, + GEN_OID_WATCHDOG, + GEN_OID_MIBOP, + GEN_OID_OPTIONS, + GEN_OID_LEDCONFIG, + + /* 802.11 */ + DOT11_OID_BSSTYPE, + DOT11_OID_BSSID, + DOT11_OID_SSID, + DOT11_OID_STATE, + DOT11_OID_AID, + DOT11_OID_COUNTRYSTRING, + DOT11_OID_SSIDOVERRIDE, + + DOT11_OID_MEDIUMLIMIT, + DOT11_OID_BEACONPERIOD, + DOT11_OID_DTIMPERIOD, + DOT11_OID_ATIMWINDOW, + DOT11_OID_LISTENINTERVAL, + DOT11_OID_CFPPERIOD, + DOT11_OID_CFPDURATION, + + DOT11_OID_AUTHENABLE, + DOT11_OID_PRIVACYINVOKED, + DOT11_OID_EXUNENCRYPTED, + DOT11_OID_DEFKEYID, + DOT11_OID_DEFKEYX, /* DOT11_OID_DEFKEY1,...DOT11_OID_DEFKEY4 */ + DOT11_OID_STAKEY, + DOT11_OID_REKEYTHRESHOLD, + DOT11_OID_STASC, + + DOT11_OID_PRIVTXREJECTED, + DOT11_OID_PRIVRXPLAIN, + DOT11_OID_PRIVRXFAILED, + DOT11_OID_PRIVRXNOKEY, + + DOT11_OID_RTSTHRESH, + DOT11_OID_FRAGTHRESH, + DOT11_OID_SHORTRETRIES, + DOT11_OID_LONGRETRIES, + DOT11_OID_MAXTXLIFETIME, + DOT11_OID_MAXRXLIFETIME, + DOT11_OID_AUTHRESPTIMEOUT, + DOT11_OID_ASSOCRESPTIMEOUT, + + DOT11_OID_ALOFT_TABLE, + DOT11_OID_ALOFT_CTRL_TABLE, + DOT11_OID_ALOFT_RETREAT, + DOT11_OID_ALOFT_PROGRESS, + DOT11_OID_ALOFT_FIXEDRATE, + DOT11_OID_ALOFT_RSSIGRAPH, + DOT11_OID_ALOFT_CONFIG, + + DOT11_OID_VDCFX, + DOT11_OID_MAXFRAMEBURST, + + DOT11_OID_PSM, + DOT11_OID_CAMTIMEOUT, + DOT11_OID_RECEIVEDTIMS, + DOT11_OID_ROAMPREFERENCE, + + DOT11_OID_BRIDGELOCAL, + DOT11_OID_CLIENTS, + DOT11_OID_CLIENTSASSOCIATED, + DOT11_OID_CLIENTX, /* DOT11_OID_CLIENTX,...DOT11_OID_CLIENT2007 */ + + DOT11_OID_CLIENTFIND, + DOT11_OID_WDSLINKADD, + DOT11_OID_WDSLINKREMOVE, + DOT11_OID_EAPAUTHSTA, + DOT11_OID_EAPUNAUTHSTA, + DOT11_OID_DOT1XENABLE, + DOT11_OID_MICFAILURE, + DOT11_OID_REKEYINDICATE, + + DOT11_OID_MPDUTXSUCCESSFUL, + DOT11_OID_MPDUTXONERETRY, + DOT11_OID_MPDUTXMULTIPLERETRIES, + DOT11_OID_MPDUTXFAILED, + DOT11_OID_MPDURXSUCCESSFUL, + DOT11_OID_MPDURXDUPS, + DOT11_OID_RTSSUCCESSFUL, + DOT11_OID_RTSFAILED, + DOT11_OID_ACKFAILED, + DOT11_OID_FRAMERECEIVES, + DOT11_OID_FRAMEERRORS, + DOT11_OID_FRAMEABORTS, + DOT11_OID_FRAMEABORTSPHY, + + DOT11_OID_SLOTTIME, + DOT11_OID_CWMIN, + DOT11_OID_CWMAX, + DOT11_OID_ACKWINDOW, + DOT11_OID_ANTENNARX, + DOT11_OID_ANTENNATX, + DOT11_OID_ANTENNADIVERSITY, + DOT11_OID_CHANNEL, + DOT11_OID_EDTHRESHOLD, + DOT11_OID_PREAMBLESETTINGS, + DOT11_OID_RATES, + DOT11_OID_CCAMODESUPPORTED, + DOT11_OID_CCAMODE, + DOT11_OID_RSSIVECTOR, + DOT11_OID_OUTPUTPOWERTABLE, + DOT11_OID_OUTPUTPOWER, + DOT11_OID_SUPPORTEDRATES, + DOT11_OID_FREQUENCY, + DOT11_OID_SUPPORTEDFREQUENCIES, + DOT11_OID_NOISEFLOOR, + DOT11_OID_FREQUENCYACTIVITY, + DOT11_OID_IQCALIBRATIONTABLE, + DOT11_OID_NONERPPROTECTION, + DOT11_OID_SLOTSETTINGS, + DOT11_OID_NONERPTIMEOUT, + DOT11_OID_PROFILES, + DOT11_OID_EXTENDEDRATES, + + DOT11_OID_DEAUTHENTICATE, + DOT11_OID_AUTHENTICATE, + DOT11_OID_DISASSOCIATE, + DOT11_OID_ASSOCIATE, + DOT11_OID_SCAN, + DOT11_OID_BEACON, + DOT11_OID_PROBE, + DOT11_OID_DEAUTHENTICATEEX, + DOT11_OID_AUTHENTICATEEX, + DOT11_OID_DISASSOCIATEEX, + DOT11_OID_ASSOCIATEEX, + DOT11_OID_REASSOCIATE, + DOT11_OID_REASSOCIATEEX, + + DOT11_OID_NONERPSTATUS, + + DOT11_OID_STATIMEOUT, + DOT11_OID_MLMEAUTOLEVEL, + DOT11_OID_BSSTIMEOUT, + DOT11_OID_ATTACHMENT, + DOT11_OID_PSMBUFFER, + + DOT11_OID_BSSS, + DOT11_OID_BSSX, /*DOT11_OID_BSS1,...,DOT11_OID_BSS64 */ + DOT11_OID_BSSFIND, + DOT11_OID_BSSLIST, + + OID_INL_TUNNEL, + OID_INL_MEMADDR, + OID_INL_MEMORY, + OID_INL_MODE, + OID_INL_COMPONENT_NR, + OID_INL_VERSION, + OID_INL_INTERFACE_ID, + OID_INL_COMPONENT_ID, + OID_INL_CONFIG, + OID_INL_DOT11D_CONFORMANCE, + OID_INL_PHYCAPABILITIES, + OID_INL_OUTPUTPOWER, + + OID_NUM_LAST +}; + +/* We could add more flags. eg: in which mode are they allowed, ro, rw, ...*/ +#define OID_FLAG_CACHED 0x01 +#define OID_FLAG_U32 0x02 +#define OID_FLAG_MLMEEX 0x04 /* this type is special because of a variable + size field when sending. Not yet implemented (not used in driver). */ + +struct oid_t { + enum oid_num_t oid; + short range; /* to define a range of oid */ + short size; /* size of the associated data */ + char flags; +}; + +union oid_res_t { + void *ptr; + u32 u; +}; + +#define IWMAX_BITRATES 20 +#define IWMAX_BSS 24 +#define IWMAX_FREQ 30 + +#endif /* !defined(_ISL_OID_H) */ +/* EOF */ diff -Nru a/drivers/net/wireless/prism54/islpci_dev.c b/drivers/net/wireless/prism54/islpci_dev.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/drivers/net/wireless/prism54/islpci_dev.c Sun Mar 14 14:20:09 2004 @@ -0,0 +1,826 @@ +/* $Header: /var/lib/cvs/prism54-ng/ksrc/islpci_dev.c,v 1.68 2004/02/28 03:06:07 mcgrof Exp $ + * + * Copyright (C) 2002 Intersil Americas Inc. + * Copyright (C) 2003 Herbert Valerio Riedel + * Copyright (C) 2003 Luis R. Rodriguez + * + * 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 + * + * 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 "isl_38xx.h" +#include "isl_ioctl.h" +#include "islpci_dev.h" +#include "islpci_mgt.h" +#include "islpci_eth.h" +#include "oid_mgt.h" + +#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,5,0) +#define prism54_synchronize_irq(irq) synchronize_irq() +#else +#define prism54_synchronize_irq(irq) synchronize_irq(irq) +#endif + +#define ISL3877_IMAGE_FILE "isl3877" +#define ISL3890_IMAGE_FILE "isl3890" + +/* Temporary dummy MAC address to use until firmware is loaded. + * The idea there is that some tools (such as nameif) may query + * the MAC address before the netdev is 'open'. By using a valid + * OUI prefix, they can process the netdev properly. + * Of course, this is not the final/real MAC address. It doesn't + * matter, as you are suppose to be able to change it anytime via + * ndev->set_mac_address. Jean II */ +const unsigned char dummy_mac[6] = { 0x00, 0x30, 0xB4, 0x00, 0x00, 0x00 }; + +/****************************************************************************** + Device Interrupt Handler +******************************************************************************/ + +irqreturn_t +islpci_interrupt(int irq, void *config, struct pt_regs *regs) +{ + u32 reg; + islpci_private *priv = config; + struct net_device *ndev = priv->ndev; + void *device = priv->device_base; + int powerstate = ISL38XX_PSM_POWERSAVE_STATE; + + /* received an interrupt request on a shared IRQ line + * first check whether the device is in sleep mode */ + reg = readl(device + ISL38XX_CTRL_STAT_REG); + if (reg & ISL38XX_CTRL_STAT_SLEEPMODE) + /* device is in sleep mode, IRQ was generated by someone else */ + { + printk(KERN_DEBUG "Assuming someone else called the IRQ\n"); + return IRQ_NONE; + } + + if (islpci_get_state(priv) != PRV_STATE_SLEEP) + powerstate = ISL38XX_PSM_ACTIVE_STATE; + + /* lock the interrupt handler */ + spin_lock(&priv->slock); + + /* check whether there is any source of interrupt on the device */ + reg = readl(device + ISL38XX_INT_IDENT_REG); + + /* also check the contents of the Interrupt Enable Register, because this + * will filter out interrupt sources from other devices on the same irq ! */ + reg &= readl(device + ISL38XX_INT_EN_REG); + reg &= ISL38XX_INT_SOURCES; + + if (reg != 0) { + /* reset the request bits in the Identification register */ + isl38xx_w32_flush(device, reg, ISL38XX_INT_ACK_REG); + +#if VERBOSE > SHOW_ERROR_MESSAGES + DEBUG(SHOW_FUNCTION_CALLS, + "IRQ: Identification register 0x%p 0x%x \n", device, reg); +#endif + + /* check for each bit in the register separately */ + if (reg & ISL38XX_INT_IDENT_UPDATE) { +#if VERBOSE > SHOW_ERROR_MESSAGES + /* Queue has been updated */ + DEBUG(SHOW_TRACING, "IRQ: Update flag \n"); + + DEBUG(SHOW_QUEUE_INDEXES, + "CB drv Qs: [%i][%i][%i][%i][%i][%i]\n", + le32_to_cpu(priv->control_block-> + driver_curr_frag[0]), + le32_to_cpu(priv->control_block-> + driver_curr_frag[1]), + le32_to_cpu(priv->control_block-> + driver_curr_frag[2]), + le32_to_cpu(priv->control_block-> + driver_curr_frag[3]), + le32_to_cpu(priv->control_block-> + driver_curr_frag[4]), + le32_to_cpu(priv->control_block-> + driver_curr_frag[5]) + ); + + DEBUG(SHOW_QUEUE_INDEXES, + "CB dev Qs: [%i][%i][%i][%i][%i][%i]\n", + le32_to_cpu(priv->control_block-> + device_curr_frag[0]), + le32_to_cpu(priv->control_block-> + device_curr_frag[1]), + le32_to_cpu(priv->control_block-> + device_curr_frag[2]), + le32_to_cpu(priv->control_block-> + device_curr_frag[3]), + le32_to_cpu(priv->control_block-> + device_curr_frag[4]), + le32_to_cpu(priv->control_block-> + device_curr_frag[5]) + ); +#endif + + /* cleanup the data low transmit queue */ + islpci_eth_cleanup_transmit(priv, priv->control_block); + + /* device is in active state, update the + * powerstate flag if necessary */ + powerstate = ISL38XX_PSM_ACTIVE_STATE; + + /* check all three queues in priority order + * call the PIMFOR receive function until the + * queue is empty */ + if (isl38xx_in_queue(priv->control_block, + ISL38XX_CB_RX_MGMTQ) != 0) { +#if VERBOSE > SHOW_ERROR_MESSAGES + DEBUG(SHOW_TRACING, + "Received frame in Management Queue\n"); +#endif + islpci_mgt_receive(ndev); + + islpci_mgt_cleanup_transmit(ndev); + + /* Refill slots in receive queue */ + islpci_mgmt_rx_fill(ndev); + + /* no need to trigger the device, next + islpci_mgt_transaction does it */ + } + + while (isl38xx_in_queue(priv->control_block, + ISL38XX_CB_RX_DATA_LQ) != 0) { +#if VERBOSE > SHOW_ERROR_MESSAGES + DEBUG(SHOW_TRACING, + "Received frame in Data Low Queue \n"); +#endif + islpci_eth_receive(priv); + } + + /* check whether the data transmit queues were full */ + if (priv->data_low_tx_full) { + /* check whether the transmit is not full anymore */ + if (ISL38XX_CB_TX_QSIZE - + isl38xx_in_queue(priv->control_block, + ISL38XX_CB_TX_DATA_LQ) >= + ISL38XX_MIN_QTHRESHOLD) { + /* nope, the driver is ready for more network frames */ + netif_wake_queue(priv->ndev); + + /* reset the full flag */ + priv->data_low_tx_full = 0; + } + } + } + + if (reg & ISL38XX_INT_IDENT_INIT) { + /* Device has been initialized */ +#if VERBOSE > SHOW_ERROR_MESSAGES + DEBUG(SHOW_TRACING, + "IRQ: Init flag, device initialized \n"); +#endif + wake_up(&priv->reset_done); + } + + if (reg & ISL38XX_INT_IDENT_SLEEP) { + /* Device intends to move to powersave state */ +#if VERBOSE > SHOW_ERROR_MESSAGES + DEBUG(SHOW_TRACING, "IRQ: Sleep flag \n"); +#endif + isl38xx_handle_sleep_request(priv->control_block, + &powerstate, + priv->device_base); + } + + if (reg & ISL38XX_INT_IDENT_WAKEUP) { + /* Device has been woken up to active state */ +#if VERBOSE > SHOW_ERROR_MESSAGES + DEBUG(SHOW_TRACING, "IRQ: Wakeup flag \n"); +#endif + + isl38xx_handle_wakeup(priv->control_block, + &powerstate, priv->device_base); + } + } + + /* sleep -> ready */ + if (islpci_get_state(priv) == PRV_STATE_SLEEP + && powerstate == ISL38XX_PSM_ACTIVE_STATE) + islpci_set_state(priv, PRV_STATE_READY); + + /* !sleep -> sleep */ + if (islpci_get_state(priv) != PRV_STATE_SLEEP + && powerstate == ISL38XX_PSM_POWERSAVE_STATE) + islpci_set_state(priv, PRV_STATE_SLEEP); + + /* unlock the interrupt handler */ + spin_unlock(&priv->slock); + + return IRQ_HANDLED; +} + +/****************************************************************************** + Network Interface Control & Statistical functions +******************************************************************************/ +static int +islpci_open(struct net_device *ndev) +{ + u32 rc; + islpci_private *priv = ndev->priv; + + printk(KERN_DEBUG "%s: islpci_open()\n", ndev->name); + + /* reset data structures, upload firmware and reset device */ + rc = islpci_reset(priv,1); + if (rc) { + prism54_bring_down(priv); + return rc; /* Returns informative message */ + } + + netif_start_queue(ndev); +/* netif_mark_up( ndev ); */ + + return 0; +} + +static int +islpci_close(struct net_device *ndev) +{ + islpci_private *priv = ndev->priv; + + printk(KERN_DEBUG "%s: islpci_close ()\n", ndev->name); + + netif_stop_queue(ndev); + + return prism54_bring_down(priv); +} + +int +prism54_bring_down(islpci_private *priv) +{ + void *device_base = priv->device_base; + u32 reg; + /* we are going to shutdown the device */ + islpci_set_state(priv, PRV_STATE_PREBOOT); + + /* disable all device interrupts in case they weren't */ + isl38xx_disable_interrupts(priv->device_base); + + /* For safety reasons, we may want to ensure that no DMA transfer is + * currently in progress by emptying the TX and RX queues. */ + + /* wait until interrupts have finished executing on other CPUs */ + prism54_synchronize_irq(priv->pdev->irq); + + reg = readl(device_base + ISL38XX_CTRL_STAT_REG); + reg &= ~(ISL38XX_CTRL_STAT_RESET | ISL38XX_CTRL_STAT_RAMBOOT); + writel(reg, device_base + ISL38XX_CTRL_STAT_REG); + wmb(); + udelay(ISL38XX_WRITEIO_DELAY); + + reg |= ISL38XX_CTRL_STAT_RESET; + writel(reg, device_base + ISL38XX_CTRL_STAT_REG); + wmb(); + udelay(ISL38XX_WRITEIO_DELAY); + + /* clear the Reset bit */ + reg &= ~ISL38XX_CTRL_STAT_RESET; + writel(reg, device_base + ISL38XX_CTRL_STAT_REG); + wmb(); + + /* wait a while for the device to reset */ + set_current_state(TASK_UNINTERRUPTIBLE); + schedule_timeout(50*HZ/1000); + + return 0; +} + +static int +islpci_upload_fw(islpci_private *priv) +{ + islpci_state_t old_state; + u32 rc; + + old_state = islpci_set_state(priv, PRV_STATE_BOOT); + + printk(KERN_DEBUG "%s: uploading firmware...\n", priv->ndev->name); + + rc = isl38xx_upload_firmware(priv->firmware, +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,75)) + &priv->pdev->dev, +#else + pci_name(priv->pdev), +#endif + priv->device_base, + priv->device_host_address); + if (rc) { + /* error uploading the firmware */ + printk(KERN_ERR "%s: could not upload firmware ('%s')\n", + priv->ndev->name, priv->firmware); + + islpci_set_state(priv, old_state); + return rc; + } + + printk(KERN_DEBUG + "%s: firmware uploaded done, now triggering reset...\n", + priv->ndev->name); + + islpci_set_state(priv, PRV_STATE_POSTBOOT); + + return 0; +} + +static int +islpci_reset_if(islpci_private *priv) +{ + long remaining; + int result = -ETIME; + int count; + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) + /* This is 2.6 specific, nicer, shorter, but not in 2.4 yet */ + DEFINE_WAIT(wait); + prepare_to_wait(&priv->reset_done, &wait, TASK_UNINTERRUPTIBLE); +#else + DECLARE_WAITQUEUE(wait, current); + set_current_state(TASK_UNINTERRUPTIBLE); + add_wait_queue(&priv->reset_done, &wait); +#endif + + /* now the last step is to reset the interface */ + isl38xx_interface_reset(priv->device_base, priv->device_host_address); + islpci_set_state(priv, PRV_STATE_PREINIT); + + for(count = 0; count < 2 && result; count++) { + /* The software reset acknowledge needs about 220 msec here. + * Be conservative and wait for up to one second. */ + + remaining = schedule_timeout(HZ); + + if(remaining > 0) { + result = 0; + break; + } + + /* If we're here it's because our IRQ hasn't yet gone through. + * Retry a bit more... + */ + printk(KERN_ERR "%s: device soft reset timed out\n", + priv->ndev->name); + + } + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) + /* 2.6 specific too */ + finish_wait(&priv->reset_done, &wait); +#else + remove_wait_queue(&priv->reset_done, &wait); + set_current_state(TASK_RUNNING); +#endif + + if(result) + return result; + + islpci_set_state(priv, PRV_STATE_INIT); + + /* Now that the device is 100% up, let's allow + * for the other interrupts -- + * NOTE: this is not *yet* true since we've only allowed the + * INIT interrupt on the IRQ line. We can perhaps poll + * the IRQ line until we know for sure the reset went through */ + isl38xx_enable_common_interrupts(priv->device_base); + + prism54_mib_init_work(priv); + + islpci_set_state(priv, PRV_STATE_READY); + + return 0; +} + +int +islpci_reset(islpci_private *priv, int reload_firmware) +{ + isl38xx_control_block *cb = /* volatile not needed */ + (isl38xx_control_block *) priv->control_block; + unsigned counter; + int rc; + + if (reload_firmware) + islpci_set_state(priv, PRV_STATE_PREBOOT); + else + islpci_set_state(priv, PRV_STATE_POSTBOOT); + + printk(KERN_DEBUG "%s: resetting device...\n", priv->ndev->name); + + /* disable all device interrupts in case they weren't */ + isl38xx_disable_interrupts(priv->device_base); + + /* flush all management queues */ + priv->index_mgmt_tx = 0; + priv->index_mgmt_rx = 0; + + /* clear the indexes in the frame pointer */ + for (counter = 0; counter < ISL38XX_CB_QCOUNT; counter++) { + cb->driver_curr_frag[counter] = cpu_to_le32(0); + cb->device_curr_frag[counter] = cpu_to_le32(0); + } + + /* reset the mgmt receive queue */ + for (counter = 0; counter < ISL38XX_CB_MGMT_QSIZE; counter++) { + isl38xx_fragment *frag = &cb->rx_data_mgmt[counter]; + frag->size = MGMT_FRAME_SIZE; + frag->flags = 0; + frag->address = priv->mgmt_rx[counter].pci_addr; + } + + for (counter = 0; counter < ISL38XX_CB_RX_QSIZE; counter++) { + cb->rx_data_low[counter].address = + cpu_to_le32((u32) priv->pci_map_rx_address[counter]); + } + + /* since the receive queues are filled with empty fragments, now we can + * set the corresponding indexes in the Control Block */ + priv->control_block->driver_curr_frag[ISL38XX_CB_RX_DATA_LQ] = + cpu_to_le32(ISL38XX_CB_RX_QSIZE); + priv->control_block->driver_curr_frag[ISL38XX_CB_RX_MGMTQ] = + cpu_to_le32(ISL38XX_CB_MGMT_QSIZE); + + /* reset the remaining real index registers and full flags */ + priv->free_data_rx = 0; + priv->free_data_tx = 0; + priv->data_low_tx_full = 0; + + if (reload_firmware) { /* Should we load the firmware ? */ + /* now that the data structures are cleaned up, upload + * firmware and reset interface */ + rc = islpci_upload_fw(priv); + if (rc) + return rc; + } + + /* finally reset interface */ + rc = islpci_reset_if(priv); + if (!rc) /* If successful */ + return rc; + + printk(KERN_DEBUG "prism54: Your card/socket may be faulty, or IRQ line too busy :(\n"); + return rc; + +} + +struct net_device_stats * +islpci_statistics(struct net_device *ndev) +{ + islpci_private *priv = ndev->priv; + +#if VERBOSE > SHOW_ERROR_MESSAGES + DEBUG(SHOW_FUNCTION_CALLS, "islpci_statistics \n"); +#endif + + return &priv->statistics; +} + +/****************************************************************************** + Network device configuration functions +******************************************************************************/ +int +islpci_alloc_memory(islpci_private *priv) +{ + int counter; + +#if VERBOSE > SHOW_ERROR_MESSAGES + printk(KERN_DEBUG "islpci_alloc_memory\n"); +#endif + + /* remap the PCI device base address to accessable */ + if (!(priv->device_base = + ioremap(pci_resource_start(priv->pdev, 0), + ISL38XX_PCI_MEM_SIZE))) { + /* error in remapping the PCI device memory address range */ + printk(KERN_ERR "PCI memory remapping failed \n"); + return -1; + } + + /* memory layout for consistent DMA region: + * + * Area 1: Control Block for the device interface + * Area 2: Power Save Mode Buffer for temporary frame storage. Be aware that + * the number of supported stations in the AP determines the minimal + * size of the buffer ! + */ + + /* perform the allocation */ + priv->driver_mem_address = pci_alloc_consistent(priv->pdev, + HOST_MEM_BLOCK, + &priv-> + device_host_address); + + if (!priv->driver_mem_address) { + /* error allocating the block of PCI memory */ + printk(KERN_ERR "%s: could not allocate DMA memory, aborting!", + "prism54"); + return -1; + } + + /* assign the Control Block to the first address of the allocated area */ + priv->control_block = + (isl38xx_control_block *) priv->driver_mem_address; + + /* set the Power Save Buffer pointer directly behind the CB */ + priv->device_psm_buffer = + priv->device_host_address + CONTROL_BLOCK_SIZE; + + /* make sure all buffer pointers are initialized */ + for (counter = 0; counter < ISL38XX_CB_QCOUNT; counter++) { + priv->control_block->driver_curr_frag[counter] = cpu_to_le32(0); + priv->control_block->device_curr_frag[counter] = cpu_to_le32(0); + } + + priv->index_mgmt_rx = 0; + memset(priv->mgmt_rx, 0, sizeof(priv->mgmt_rx)); + memset(priv->mgmt_tx, 0, sizeof(priv->mgmt_tx)); + + /* allocate rx queue for management frames */ + if (islpci_mgmt_rx_fill(priv->ndev) < 0) + goto out_free; + + /* now get the data rx skb's */ + memset(priv->data_low_rx, 0, sizeof (priv->data_low_rx)); + memset(priv->pci_map_rx_address, 0, sizeof (priv->pci_map_rx_address)); + + for (counter = 0; counter < ISL38XX_CB_RX_QSIZE; counter++) { + struct sk_buff *skb; + + /* allocate an sk_buff for received data frames storage + * each frame on receive size consists of 1 fragment + * include any required allignment operations */ + if (!(skb = dev_alloc_skb(MAX_FRAGMENT_SIZE_RX + 2))) { + /* error allocating an sk_buff structure elements */ + printk(KERN_ERR "Error allocating skb.\n"); + goto out_free; + } + /* add the new allocated sk_buff to the buffer array */ + priv->data_low_rx[counter] = skb; + + /* map the allocated skb data area to pci */ + priv->pci_map_rx_address[counter] = + pci_map_single(priv->pdev, (void *) skb->data, + MAX_FRAGMENT_SIZE_RX + 2, + PCI_DMA_FROMDEVICE); + if (!priv->pci_map_rx_address[counter]) { + /* error mapping the buffer to device + accessable memory address */ + printk(KERN_ERR "failed to map skb DMA'able\n"); + goto out_free; + } + } + + prism54_acl_init(&priv->acl); + prism54_wpa_ie_init(priv); + if (mgt_init(priv)) + goto out_free; + + return 0; + out_free: + islpci_free_memory(priv); + return -1; +} + +int +islpci_free_memory(islpci_private *priv) +{ + int counter; + + if (priv->device_base) + iounmap(priv->device_base); + priv->device_base = 0; + + /* free consistent DMA area... */ + if (priv->driver_mem_address) + pci_free_consistent(priv->pdev, HOST_MEM_BLOCK, + priv->driver_mem_address, + priv->device_host_address); + + /* clear some dangling pointers */ + priv->driver_mem_address = 0; + priv->device_host_address = 0; + priv->device_psm_buffer = 0; + priv->control_block = 0; + + /* clean up mgmt rx buffers */ + for (counter = 0; counter < ISL38XX_CB_MGMT_QSIZE; counter++) { + struct islpci_membuf *buf = &priv->mgmt_rx[counter]; + if (buf->pci_addr) + pci_unmap_single(priv->pdev, buf->pci_addr, + buf->size, PCI_DMA_FROMDEVICE); + buf->pci_addr = 0; + if (buf->mem) + kfree(buf->mem); + buf->size = 0; + buf->mem = NULL; + } + + /* clean up data rx buffers */ + for (counter = 0; counter < ISL38XX_CB_RX_QSIZE; counter++) { + if (priv->pci_map_rx_address[counter]) + pci_unmap_single(priv->pdev, + priv->pci_map_rx_address[counter], + MAX_FRAGMENT_SIZE_RX + 2, + PCI_DMA_FROMDEVICE); + priv->pci_map_rx_address[counter] = 0; + + if (priv->data_low_rx[counter]) + dev_kfree_skb(priv->data_low_rx[counter]); + priv->data_low_rx[counter] = 0; + } + + /* Free the acces control list and the WPA list */ + prism54_acl_clean(&priv->acl); + prism54_wpa_ie_clean(priv); + mgt_clean(priv); + + return 0; +} + +#if 0 +static void +islpci_set_multicast_list(struct net_device *dev) +{ + /* put device into promisc mode and let network layer handle it */ +} +#endif + +struct net_device * +islpci_setup(struct pci_dev *pdev) +{ + islpci_private *priv; + struct net_device *ndev = alloc_etherdev(sizeof (islpci_private)); + + if (!ndev) + return ndev; + + SET_MODULE_OWNER(ndev); + pci_set_drvdata(pdev, ndev); +#if defined(SET_NETDEV_DEV) + SET_NETDEV_DEV(ndev, &pdev->dev); +#endif + + /* setup the structure members */ + ndev->base_addr = pci_resource_start(pdev, 0); + ndev->irq = pdev->irq; + + /* initialize the function pointers */ + ndev->open = &islpci_open; + ndev->stop = &islpci_close; + ndev->get_stats = &islpci_statistics; + ndev->get_wireless_stats = &prism54_get_wireless_stats; + ndev->do_ioctl = &prism54_ioctl; + ndev->wireless_handlers = + (struct iw_handler_def *) &prism54_handler_def; + + ndev->hard_start_xmit = &islpci_eth_transmit; + /* ndev->set_multicast_list = &islpci_set_multicast_list; */ + ndev->addr_len = ETH_ALEN; + ndev->set_mac_address = &prism54_set_mac_address; + /* Get a non-zero dummy MAC address for nameif. Jean II */ + memcpy(ndev->dev_addr, dummy_mac, 6); + +#ifdef HAVE_TX_TIMEOUT + ndev->watchdog_timeo = ISLPCI_TX_TIMEOUT; + ndev->tx_timeout = &islpci_eth_tx_timeout; +#endif + + /* allocate a private device structure to the network device */ + priv = ndev->priv; + priv->ndev = ndev; + priv->pdev = pdev; + + priv->ndev->type = (priv->iw_mode == IW_MODE_MONITOR) ? + ARPHRD_IEEE80211: ARPHRD_ETHER; + + /* save the start and end address of the PCI memory area */ + ndev->mem_start = (unsigned long) priv->device_base; + ndev->mem_end = ndev->mem_start + ISL38XX_PCI_MEM_SIZE; + +#if VERBOSE > SHOW_ERROR_MESSAGES + DEBUG(SHOW_TRACING, "PCI Memory remapped to 0x%p\n", priv->device_base); +#endif + + init_waitqueue_head(&priv->reset_done); + + /* init the queue read locks, process wait counter */ + sema_init(&priv->mgmt_sem, 1); + priv->mgmt_received = NULL; + init_waitqueue_head(&priv->mgmt_wqueue); + sema_init(&priv->stats_sem, 1); + spin_lock_init(&priv->slock); + + /* init state machine with off#1 state */ + priv->state = PRV_STATE_OFF; + priv->state_off = 1; + + /* initialize workqueue's */ + INIT_WORK(&priv->stats_work, + (void (*)(void *)) prism54_update_stats, priv); + + priv->stats_timestamp = 0; + + /* allocate various memory areas */ + if (islpci_alloc_memory(priv)) + goto do_free_netdev; + + /* select the firmware file depending on the device id */ + switch (pdev->device) { + case PCIDEVICE_ISL3890: + case PCIDEVICE_3COM6001: + strcpy(priv->firmware, ISL3890_IMAGE_FILE); + break; + case PCIDEVICE_ISL3877: + strcpy(priv->firmware, ISL3877_IMAGE_FILE); + break; + + default: + strcpy(priv->firmware, ISL3890_IMAGE_FILE); + break; + } + + if (register_netdev(ndev)) { + DEBUG(SHOW_ERROR_MESSAGES, + "ERROR: register_netdev() failed \n"); + goto do_islpci_free_memory; + } + + return ndev; + + do_islpci_free_memory: + islpci_free_memory(priv); + do_free_netdev: + pci_set_drvdata(pdev, 0); + free_netdev(ndev); + priv = 0; + return NULL; +} + +islpci_state_t +islpci_set_state(islpci_private *priv, islpci_state_t new_state) +{ + islpci_state_t old_state; + + /* lock */ + old_state = priv->state; + + /* this means either a race condition or some serious error in + * the driver code */ + switch (new_state) { + case PRV_STATE_OFF: + priv->state_off++; + default: + priv->state = new_state; + break; + + case PRV_STATE_PREBOOT: + /* there are actually many off-states, enumerated by + * state_off */ + if (old_state == PRV_STATE_OFF) + priv->state_off--; + + /* only if hw_unavailable is zero now it means we either + * were in off#1 state, or came here from + * somewhere else */ + if (!priv->state_off) + priv->state = new_state; + break; + }; +#if 0 + printk(KERN_DEBUG "%s: state transition %d -> %d (off#%d)\n", + priv->ndev->name, old_state, new_state, priv->state_off); +#endif + + /* invariants */ + BUG_ON(priv->state_off < 0); + BUG_ON(priv->state_off && (priv->state != PRV_STATE_OFF)); + BUG_ON(!priv->state_off && (priv->state == PRV_STATE_OFF)); + + /* unlock */ + return old_state; +} diff -Nru a/drivers/net/wireless/prism54/islpci_dev.h b/drivers/net/wireless/prism54/islpci_dev.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/drivers/net/wireless/prism54/islpci_dev.h Sun Mar 14 14:20:09 2004 @@ -0,0 +1,228 @@ +/* $Header: /var/lib/cvs/prism54-ng/ksrc/islpci_dev.h,v 1.53 2004/02/28 03:06:07 mcgrof Exp $ + * + * Copyright (C) 2002 Intersil Americas Inc. + * Copyright (C) 2003 Herbert Valerio Riedel + * Copyright (C) 2003 Luis R. Rodriguez + * + * 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 + * + * 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 + * + */ + +#ifndef _ISLPCI_DEV_H +#define _ISLPCI_DEV_H + +#include +#include +#include +#include + +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,41) +# include +#else +# include +# define work_struct tq_struct +# define INIT_WORK INIT_TQUEUE +# define schedule_work schedule_task +#endif + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,23) +#define free_netdev(x) kfree(x) +#define pci_name(x) x->slot_name +#endif + +#include "isl_38xx.h" +#include "isl_oid.h" +#include "islpci_mgt.h" + +/* some states might not be superflous and may be removed when + design is finalized (hvr) */ +typedef enum { + PRV_STATE_OFF = 0, /* this means hw_unavailable is != 0 */ + PRV_STATE_PREBOOT, /* we are in a pre-boot state (empty RAM) */ + PRV_STATE_BOOT, /* boot state (fw upload, run fw) */ + PRV_STATE_POSTBOOT, /* after boot state, need reset now */ + PRV_STATE_PREINIT, /* pre-init state */ + PRV_STATE_INIT, /* init state (restore MIB backup to device) */ + PRV_STATE_READY, /* driver&device are in operational state */ + PRV_STATE_SLEEP /* device in sleep mode */ +} islpci_state_t; + +/* ACL using MAC address */ +struct mac_entry { + struct list_head _list; + char addr[ETH_ALEN]; +}; + +struct islpci_acl { + enum { MAC_POLICY_OPEN=0, MAC_POLICY_ACCEPT=1, MAC_POLICY_REJECT=2 } policy; + struct list_head mac_list; /* a list of mac_entry */ + int size; /* size of queue */ + struct semaphore sem; /* accessed in ioctls and trap_work */ +}; + +struct islpci_membuf { + int size; /* size of memory */ + void *mem; /* address of memory as seen by CPU */ + dma_addr_t pci_addr; /* address of memory as seen by device */ +}; + +#define MAX_BSS_WPA_IE_COUNT 64 +#define MAX_WPA_IE_LEN 64 +struct islpci_bss_wpa_ie { + struct list_head list; + unsigned long last_update; + u8 bssid[ETH_ALEN]; + u8 wpa_ie[MAX_WPA_IE_LEN]; + size_t wpa_ie_len; + +}; + +typedef struct { + spinlock_t slock; /* generic spinlock; */ + + u32 priv_oid; + + /* our mib cache */ + u32 iw_mode; + struct rw_semaphore mib_sem; + void **mib; + char nickname[IW_ESSID_MAX_SIZE+1]; + + /* Take care of the wireless stats */ + struct work_struct stats_work; + struct semaphore stats_sem; + /* remember when we last updated the stats */ + unsigned long stats_timestamp; + /* The first is accessed under semaphore locking. + * The second is the clean one we return to iwconfig. + */ + struct iw_statistics local_iwstatistics; + struct iw_statistics iwstatistics; + + struct islpci_acl acl; + + /* PCI bus allocation & configuration members */ + struct pci_dev *pdev; /* PCI structure information */ + u32 pci_state[16]; /* used for suspend/resume */ + char firmware[33]; + + void *device_base; /* ioremapped device base address */ + + /* consistent DMA region */ + void *driver_mem_address; /* base DMA address */ + dma_addr_t device_host_address; /* base DMA address (bus address) */ + dma_addr_t device_psm_buffer; /* host memory for PSM buffering (bus address) */ + + /* our network_device structure */ + struct net_device *ndev; + + /* device queue interface members */ + struct isl38xx_cb *control_block; /* device control block + (== driver_mem_address!) */ + + /* Each queue has three indexes: + * free/index_mgmt/data_rx/tx (called index, see below), + * driver_curr_frag, and device_curr_frag (in the control block) + * All indexes are ever-increasing, but interpreted modulo the + * device queue size when used. + * index <= device_curr_frag <= driver_curr_frag at all times + * For rx queues, [index, device_curr_frag) contains fragments + * that the interrupt processing needs to handle (owned by driver). + * [device_curr_frag, driver_curr_frag) is the free space in the + * rx queue, waiting for data (owned by device). The driver + * increments driver_curr_frag to indicate to the device that more + * buffers are available. + * If device_curr_frag == driver_curr_frag, no more rx buffers are + * available, and the rx DMA engine of the device is halted. + * For tx queues, [index, device_curr_frag) contains fragments + * where tx is done; they need to be freed (owned by driver). + * [device_curr_frag, driver_curr_frag) contains the frames + * that are being transferred (owned by device). The driver + * increments driver_curr_frag to indicate that more tx work + * needs to be done. + */ + u32 index_mgmt_rx; /* real index mgmt rx queue */ + u32 index_mgmt_tx; /* read index mgmt tx queue */ + u32 free_data_rx; /* free pointer data rx queue */ + u32 free_data_tx; /* free pointer data tx queue */ + u32 data_low_tx_full; /* full detected flag */ + + /* frame memory buffers for the device queues */ + struct islpci_membuf mgmt_tx[ISL38XX_CB_MGMT_QSIZE]; + struct islpci_membuf mgmt_rx[ISL38XX_CB_MGMT_QSIZE]; + struct sk_buff *data_low_tx[ISL38XX_CB_TX_QSIZE]; + struct sk_buff *data_low_rx[ISL38XX_CB_RX_QSIZE]; + dma_addr_t pci_map_tx_address[ISL38XX_CB_TX_QSIZE]; + dma_addr_t pci_map_rx_address[ISL38XX_CB_RX_QSIZE]; + + /* driver network interface members */ + struct net_device_stats statistics; + + /* wait for a reset interrupt */ + wait_queue_head_t reset_done; + + /* used by islpci_mgt_transaction */ + struct semaphore mgmt_sem; /* serialize access to mailbox and wqueue */ + struct islpci_mgmtframe *mgmt_received; /* mbox for incoming frame */ + wait_queue_head_t mgmt_wqueue; /* waitqueue for mbox */ + + /* state machine */ + islpci_state_t state; + int state_off; /* enumeration of off-state, if 0 then + * we're not in any off-state */ + + /* WPA stuff */ + int wpa; /* WPA mode enabled */ + struct list_head bss_wpa_list; + int num_bss_wpa; + struct semaphore wpa_sem; +} islpci_private; + +static inline islpci_state_t +islpci_get_state(islpci_private *priv) +{ + /* lock */ + return priv->state; + /* unlock */ +} + +islpci_state_t islpci_set_state(islpci_private *priv, islpci_state_t new_state); + +#define ISLPCI_TX_TIMEOUT (2*HZ) + +#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,5,75)) +# define irqreturn_t void +# define IRQ_HANDLED +# define IRQ_NONE +#endif + +irqreturn_t islpci_interrupt(int, void *, struct pt_regs *); + +int prism54_post_setup(islpci_private *, int); +int islpci_reset(islpci_private *, int); + +static inline void +islpci_trigger(islpci_private *priv) +{ + isl38xx_trigger_device(islpci_get_state(priv) == PRV_STATE_SLEEP, + priv->device_base); +} + +struct net_device_stats *islpci_statistics(struct net_device *); + +int prism54_bring_down(islpci_private *); +int islpci_alloc_memory(islpci_private *); +int islpci_free_memory(islpci_private *); +struct net_device *islpci_setup(struct pci_dev *); +#endif /* _ISLPCI_DEV_H */ diff -Nru a/drivers/net/wireless/prism54/islpci_eth.c b/drivers/net/wireless/prism54/islpci_eth.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/drivers/net/wireless/prism54/islpci_eth.c Sun Mar 14 14:20:09 2004 @@ -0,0 +1,429 @@ +/* $Header: /var/lib/cvs/prism54-ng/ksrc/islpci_eth.c,v 1.27 2004/01/30 16:24:00 ajfa Exp $ + * + * Copyright (C) 2002 Intersil Americas 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 + * + * 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 "isl_38xx.h" +#include "islpci_eth.h" +#include "islpci_mgt.h" + +/****************************************************************************** + Network Interface functions +******************************************************************************/ +void +islpci_eth_cleanup_transmit(islpci_private *priv, + isl38xx_control_block *control_block) +{ + struct sk_buff *skb; + u32 index; + + /* compare the control block read pointer with the free pointer */ + while (priv->free_data_tx != + le32_to_cpu(control_block-> + device_curr_frag[ISL38XX_CB_TX_DATA_LQ])) { + /* read the index of the first fragment to be freed */ + index = priv->free_data_tx % ISL38XX_CB_TX_QSIZE; + + /* check for holes in the arrays caused by multi fragment frames + * searching for the last fragment of a frame */ + if (priv->pci_map_tx_address[index] != (dma_addr_t) NULL) { + /* entry is the last fragment of a frame + * free the skb structure and unmap pci memory */ + skb = priv->data_low_tx[index]; + +#if VERBOSE > SHOW_ERROR_MESSAGES + DEBUG(SHOW_TRACING, + "cleanup skb %p skb->data %p skb->len %u truesize %u\n ", + skb, skb->data, skb->len, skb->truesize); +#endif + + pci_unmap_single(priv->pdev, + priv->pci_map_tx_address[index], + skb->len, PCI_DMA_TODEVICE); + dev_kfree_skb_irq(skb); + } + /* increment the free data low queue pointer */ + priv->free_data_tx++; + } +} + +int +islpci_eth_transmit(struct sk_buff *skb, struct net_device *ndev) +{ + islpci_private *priv = ndev->priv; + isl38xx_control_block *cb = priv->control_block; + u32 index; + dma_addr_t pci_map_address; + int frame_size; + isl38xx_fragment *fragment; + int offset; + struct sk_buff *newskb; + int newskb_offset; + unsigned long flags; + unsigned char wds_mac[6]; + u32 curr_frag; + int err = 0; + +#if VERBOSE > SHOW_ERROR_MESSAGES + DEBUG(SHOW_FUNCTION_CALLS, "islpci_eth_transmit \n"); +#endif + + /* lock the driver code */ + spin_lock_irqsave(&priv->slock, flags); + + /* determine the amount of fragments needed to store the frame */ + + frame_size = skb->len < ETH_ZLEN ? ETH_ZLEN : skb->len; + if (init_wds) + frame_size += 6; + + /* check whether the destination queue has enough fragments for the frame */ + curr_frag = le32_to_cpu(cb->driver_curr_frag[ISL38XX_CB_TX_DATA_LQ]); + if (curr_frag - priv->free_data_tx >= ISL38XX_CB_TX_QSIZE) { + printk(KERN_ERR "%s: transmit device queue full when awake\n", + ndev->name); + netif_stop_queue(ndev); + + /* trigger the device */ + isl38xx_w32_flush(priv->device_base, ISL38XX_DEV_INT_UPDATE, + ISL38XX_DEV_INT_REG); + udelay(ISL38XX_WRITEIO_DELAY); + + err = -EBUSY; + goto drop_free; + } + /* Check alignment and WDS frame formatting. The start of the packet should + * be aligned on a 4-byte boundary. If WDS is enabled add another 6 bytes + * and add WDS address information */ + if (((long) skb->data & 0x03) | init_wds) { + /* get the number of bytes to add and re-allign */ + offset = (4 - (long) skb->data) & 0x03; + offset += init_wds ? 6 : 0; + + /* check whether the current skb can be used */ + if (!skb_cloned(skb) && (skb_tailroom(skb) >= offset)) { + unsigned char *src = skb->data; + +#if VERBOSE > SHOW_ERROR_MESSAGES + DEBUG(SHOW_TRACING, "skb offset %i wds %i\n", offset, + init_wds); +#endif + + /* align the buffer on 4-byte boundary */ + skb_reserve(skb, (4 - (long) skb->data) & 0x03); + if (init_wds) { + /* wds requires an additional address field of 6 bytes */ + skb_put(skb, 6); +#ifdef ISLPCI_ETH_DEBUG + printk("islpci_eth_transmit:wds_mac\n"); +#endif + memmove(skb->data + 6, src, skb->len); + memcpy(skb->data, wds_mac, 6); + } else { + memmove(skb->data, src, skb->len); + } + +#if VERBOSE > SHOW_ERROR_MESSAGES + DEBUG(SHOW_TRACING, "memmove %p %p %i \n", skb->data, + src, skb->len); +#endif + } else { + newskb = + dev_alloc_skb(init_wds ? skb->len + 6 : skb->len); + newskb_offset = (4 - (long) newskb->data) & 0x03; + + /* Check if newskb->data is aligned */ + if (newskb_offset) + skb_reserve(newskb, newskb_offset); + + skb_put(newskb, init_wds ? skb->len + 6 : skb->len); + if (init_wds) { + memcpy(newskb->data + 6, skb->data, skb->len); + memcpy(newskb->data, wds_mac, 6); +#ifdef ISLPCI_ETH_DEBUG + printk("islpci_eth_transmit:wds_mac\n"); +#endif + } else + memcpy(newskb->data, skb->data, skb->len); + +#if VERBOSE > SHOW_ERROR_MESSAGES + DEBUG(SHOW_TRACING, "memcpy %p %p %i wds %i\n", + newskb->data, skb->data, skb->len, init_wds); +#endif + + newskb->dev = skb->dev; + dev_kfree_skb(skb); + skb = newskb; + } + } + /* display the buffer contents for debugging */ +#if VERBOSE > SHOW_ERROR_MESSAGES + DEBUG(SHOW_BUFFER_CONTENTS, "\ntx %p ", skb->data); + display_buffer((char *) skb->data, skb->len); +#endif + + /* map the skb buffer to pci memory for DMA operation */ + pci_map_address = pci_map_single(priv->pdev, + (void *) skb->data, skb->len, + PCI_DMA_TODEVICE); + if (pci_map_address == 0) { + printk(KERN_WARNING "%s: cannot map buffer to PCI\n", + ndev->name); + + err = -EIO; + goto drop_free; + } + /* Place the fragment in the control block structure. */ + index = curr_frag % ISL38XX_CB_TX_QSIZE; + fragment = &cb->tx_data_low[index]; + + priv->pci_map_tx_address[index] = pci_map_address; + /* store the skb address for future freeing */ + priv->data_low_tx[index] = skb; + /* set the proper fragment start address and size information */ + fragment->size = cpu_to_le16(frame_size); + fragment->flags = cpu_to_le16(0); /* set to 1 if more fragments */ + fragment->address = cpu_to_le32(pci_map_address); + curr_frag++; + + /* The fragment address in the control block must have been + * written before announcing the frame buffer to device. */ + wmb(); + cb->driver_curr_frag[ISL38XX_CB_TX_DATA_LQ] = cpu_to_le32(curr_frag); + + if (curr_frag - priv->free_data_tx + ISL38XX_MIN_QTHRESHOLD + > ISL38XX_CB_TX_QSIZE) { + /* stop sends from upper layers */ + netif_stop_queue(ndev); + + /* set the full flag for the transmission queue */ + priv->data_low_tx_full = 1; + } + + /* trigger the device */ + islpci_trigger(priv); + + /* unlock the driver code */ + spin_unlock_irqrestore(&priv->slock, flags); + + /* set the transmission time */ + ndev->trans_start = jiffies; + priv->statistics.tx_packets++; + priv->statistics.tx_bytes += skb->len; + + return 0; + + drop_free: + /* free the skbuf structure before aborting */ + dev_kfree_skb(skb); + + priv->statistics.tx_dropped++; + spin_unlock_irqrestore(&priv->slock, flags); + return err; +} + +int +islpci_eth_receive(islpci_private *priv) +{ + struct net_device *ndev = priv->ndev; + isl38xx_control_block *control_block = priv->control_block; + struct sk_buff *skb; + u16 size; + u32 index, offset; + unsigned char *src; + int discard = 0; + +#if VERBOSE > SHOW_ERROR_MESSAGES + DEBUG(SHOW_FUNCTION_CALLS, "islpci_eth_receive \n"); +#endif + + /* the device has written an Ethernet frame in the data area + * of the sk_buff without updating the structure, do it now */ + index = priv->free_data_rx % ISL38XX_CB_RX_QSIZE; + size = le16_to_cpu(control_block->rx_data_low[index].size); + skb = priv->data_low_rx[index]; + offset = ((unsigned long) le32_to_cpu(control_block->rx_data_low[index].address) - + (unsigned long) skb->data) & 3; + +#if VERBOSE > SHOW_ERROR_MESSAGES + DEBUG(SHOW_TRACING, + "frq->addr %x skb->data %p skb->len %u offset %u truesize %u\n ", + control_block->rx_data_low[priv->free_data_rx].address, skb->data, + skb->len, offset, skb->truesize); +#endif + + /* delete the streaming DMA mapping before processing the skb */ + pci_unmap_single(priv->pdev, + priv->pci_map_rx_address[index], + MAX_FRAGMENT_SIZE_RX + 2, PCI_DMA_FROMDEVICE); + + /* update the skb structure and allign the buffer */ + skb_put(skb, size); + if (offset) { + /* shift the buffer allocation offset bytes to get the right frame */ + skb_pull(skb, 2); + skb_put(skb, 2); + } +#if VERBOSE > SHOW_ERROR_MESSAGES + /* display the buffer contents for debugging */ + DEBUG(SHOW_BUFFER_CONTENTS, "\nrx %p ", skb->data); + display_buffer((char *) skb->data, skb->len); +#endif + + /* check whether WDS is enabled and whether the data frame is a WDS frame */ + + if (init_wds) { + /* WDS enabled, check for the wds address on the first 6 bytes of the buffer */ + src = skb->data + 6; + memmove(skb->data, src, skb->len - 6); + skb_trim(skb, skb->len - 6); + } +#if VERBOSE > SHOW_ERROR_MESSAGES + DEBUG(SHOW_TRACING, "Fragment size %i in skb at %p\n", size, skb); + DEBUG(SHOW_TRACING, "Skb data at %p, length %i\n", skb->data, skb->len); + + /* display the buffer contents for debugging */ + DEBUG(SHOW_BUFFER_CONTENTS, "\nrx %p ", skb->data); + display_buffer((char *) skb->data, skb->len); +#endif + + /* do some additional sk_buff and network layer parameters */ + skb->dev = ndev; + + /* take care of monitor mode */ + if (priv->iw_mode == IW_MODE_MONITOR) { + /* The card reports full 802.11 packets but with a 20 bytes + * header and without the FCS. But there a is a bit that + * indicates if the packet is corrupted :-) */ + /* int i; */ + if (skb->data[8] & 0x01){ + /* This one is bad. Drop it !*/ + discard = 1; + /* printk("BAD\n");*/ + } + /* + for(i=0;i<50;i++) + printk("%2.2X:",skb->data[i]); + printk("\n"); + */ + skb_pull(skb, 20); + skb->protocol = htons(ETH_P_802_2); + skb->mac.raw = skb->data; + skb->pkt_type = PACKET_OTHERHOST; + } else + skb->protocol = eth_type_trans(skb, ndev); + + skb->ip_summed = CHECKSUM_NONE; + priv->statistics.rx_packets++; + priv->statistics.rx_bytes += size; + + /* deliver the skb to the network layer */ +#ifdef ISLPCI_ETH_DEBUG + printk + ("islpci_eth_receive:netif_rx %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X\n", + skb->data[0], skb->data[1], skb->data[2], skb->data[3], + skb->data[4], skb->data[5]); +#endif + if (discard) + dev_kfree_skb(skb); + else + netif_rx(skb); + + /* increment the read index for the rx data low queue */ + priv->free_data_rx++; + + /* add one or more sk_buff structures */ + while (index = + le32_to_cpu(control_block-> + driver_curr_frag[ISL38XX_CB_RX_DATA_LQ]), + index - priv->free_data_rx < ISL38XX_CB_RX_QSIZE) { + /* allocate an sk_buff for received data frames storage + * include any required allignment operations */ + if (skb = dev_alloc_skb(MAX_FRAGMENT_SIZE_RX + 2), skb == NULL) { + /* error allocating an sk_buff structure elements */ + DEBUG(SHOW_ERROR_MESSAGES, "Error allocating skb \n"); + break; + } + /* store the new skb structure pointer */ + index = index % ISL38XX_CB_RX_QSIZE; + priv->data_low_rx[index] = skb; + +#if VERBOSE > SHOW_ERROR_MESSAGES + DEBUG(SHOW_TRACING, + "new alloc skb %p skb->data %p skb->len %u index %u truesize %u\n ", + skb, skb->data, skb->len, index, skb->truesize); +#endif + + /* set the streaming DMA mapping for proper PCI bus operation */ + priv->pci_map_rx_address[index] = + pci_map_single(priv->pdev, (void *) skb->data, + MAX_FRAGMENT_SIZE_RX + 2, + PCI_DMA_FROMDEVICE); + if (priv->pci_map_rx_address[index] == (dma_addr_t) NULL) { + /* error mapping the buffer to device accessable memory address */ + DEBUG(SHOW_ERROR_MESSAGES, + "Error mapping DMA address\n"); + + /* free the skbuf structure before aborting */ + dev_kfree_skb((struct sk_buff *) skb); + break; + } + /* update the fragment address */ + control_block->rx_data_low[index].address = cpu_to_le32((u32) + priv-> + pci_map_rx_address + [index]); + wmb(); + + /* increment the driver read pointer */ + add_le32p((u32 *) & control_block-> + driver_curr_frag[ISL38XX_CB_RX_DATA_LQ], 1); + } + + /* trigger the device */ + islpci_trigger(priv); + + return 0; +} + +void +islpci_eth_tx_timeout(struct net_device *ndev) +{ + islpci_private *priv = ndev->priv; + struct net_device_stats *statistics = &priv->statistics; + + /* increment the transmit error counter */ + statistics->tx_errors++; + +#if 0 + /* don't do this here! we are not allowed to sleep since we are in interrupt context */ + if (islpci_reset(priv)) + printk(KERN_ERR "%s: error on TX timeout card reset!\n", + ndev->name); +#endif + + /* netif_wake_queue(ndev); */ + return; +} diff -Nru a/drivers/net/wireless/prism54/islpci_eth.h b/drivers/net/wireless/prism54/islpci_eth.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/drivers/net/wireless/prism54/islpci_eth.h Sun Mar 14 14:20:09 2004 @@ -0,0 +1,31 @@ +/* $Header: /var/lib/cvs/prism54-ng/ksrc/islpci_eth.h,v 1.5 2004/01/12 22:16:32 jmaurer Exp $ + * + * Copyright (C) 2002 Intersil Americas 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 + * + * 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 + * + */ + +#ifndef _ISLPCI_ETH_H +#define _ISLPCI_ETH_H + +#include "isl_38xx.h" +#include "islpci_dev.h" + +void islpci_eth_cleanup_transmit(islpci_private *, isl38xx_control_block *); +int islpci_eth_transmit(struct sk_buff *, struct net_device *); +int islpci_eth_receive(islpci_private *); +void islpci_eth_tx_timeout(struct net_device *); + +#endif /* _ISL_GEN_H */ diff -Nru a/drivers/net/wireless/prism54/islpci_hotplug.c b/drivers/net/wireless/prism54/islpci_hotplug.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/drivers/net/wireless/prism54/islpci_hotplug.c Sun Mar 14 14:20:09 2004 @@ -0,0 +1,428 @@ +/* $Header: /var/lib/cvs/prism54-ng/ksrc/islpci_hotplug.c,v 1.56 2004/02/26 23:33:02 mcgrof Exp $ + * + * Copyright (C) 2002 Intersil Americas Inc. + * Copyright (C) 2003 Herbert Valerio Riedel + * + * 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 + * + * 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 /* For __init, __exit */ + +#include "islpci_dev.h" +#include "islpci_mgt.h" /* for pc_debug */ +#include "isl_oid.h" + +#define DRV_NAME "prism54" +#define DRV_VERSION "1.0.2.2" + +MODULE_AUTHOR("W.Termorshuizen, R.Bastings, H.V.Riedel, prism54.org team"); +MODULE_DESCRIPTION("Intersil 802.11 Wireless LAN adapter"); +MODULE_LICENSE("GPL"); + +/* In this order: vendor, device, subvendor, subdevice, class, class_mask, + * driver_data + * Note: for driver_data we put the device's name + * If you have an update for this please contact prism54-devel@prism54.org + * The latest list can be found at http://prism54.org/supported_cards.php */ +static const struct pci_device_id prism54_id_tbl[] = { + { + PCIVENDOR_3COM, PCIDEVICE_3COM6001, + PCIVENDOR_3COM, PCIDEVICE_3COM6001, + 0, 0, + (unsigned long) "3COM 3CRWE154G72 Wireless LAN adapter"}, + { + PCIVENDOR_INTERSIL, PCIDEVICE_ISL3890, + PCIVENDOR_DLINK, 0x3202UL, + 0, 0, + (unsigned long) "D-Link Air Plus Xtreme G A1 - DWL-g650 A1"}, + { + PCIVENDOR_INTERSIL, PCIDEVICE_ISL3890, + PCIVENDOR_IODATA, 0xd019UL, + 0, 0, + (unsigned long) "I-O Data WN-G54/CB - WN-G54/CB"}, + { + PCIVENDOR_INTERSIL, PCIDEVICE_ISL3890, + PCIVENDOR_NETGEAR, 0x4800UL, + 0, 0, + (unsigned long) "Netgear WG511"}, + { + PCIVENDOR_INTERSIL, PCIDEVICE_ISL3890, + PCIVENDOR_I4, 0x0020UL, + 0, 0, + (unsigned long) "PLANEX GW-DS54G"}, + { + PCIVENDOR_INTERSIL, PCIDEVICE_ISL3890, + PCIVENDOR_SMC, 0x2802UL, + 0, 0, + (unsigned long) "EZ Connect g 2.4GHz 54 Mbps Wireless PCI Card - SMC2802W"}, + { + PCIVENDOR_INTERSIL, PCIDEVICE_ISL3890, + PCIVENDOR_SMC, 0x2835UL, + 0, 0, + (unsigned long) "EZ Connect g 2.4GHz 54 Mbps Wireless Cardbus Adapter - SMC2835W"}, + { + PCIVENDOR_INTERSIL, PCIDEVICE_ISL3890, + PCIVENDOR_INTERSIL, 0x0000UL, /* This was probably a bogus reading... */ + 0, 0, + (unsigned long) "SparkLAN WL-850F"}, + { + PCIVENDOR_INTERSIL, PCIDEVICE_ISL3890, + PCIVENDOR_I4, 0x0014UL, + 0, 0, + (unsigned long) "I4 Z-Com XG-600"}, + { + PCIVENDOR_INTERSIL, PCIDEVICE_ISL3890, + PCIVENDOR_I4, 0x0020UL, + 0, 0, + (unsigned long) "I4 Z-Com XG-900/PLANEX GW-DS54G"}, + { + PCIVENDOR_INTERSIL, PCIDEVICE_ISL3890, + PCIVENDOR_ACCTON, 0xee03UL, + 0, 0, + (unsigned long) "SMC 2802Wv2"}, + { + PCIVENDOR_INTERSIL, PCIDEVICE_ISL3877, + PCI_ANY_ID, PCI_ANY_ID, + 0, 0, + (unsigned long) "Intersil PRISM Indigo Wireless LAN adapter"}, + { /* Default */ + PCIVENDOR_INTERSIL, PCIDEVICE_ISL3890, + PCI_ANY_ID, PCI_ANY_ID, + 0, 0, + (unsigned long) "Intersil PRISM Duette/Prism GT Wireless LAN adapter"}, + {0,} +}; + +/* register the device with the Hotplug facilities of the kernel */ +MODULE_DEVICE_TABLE(pci, prism54_id_tbl); + +static int prism54_probe(struct pci_dev *, const struct pci_device_id *); +static void prism54_remove(struct pci_dev *); +static int prism54_suspend(struct pci_dev *, u32 state); +static int prism54_resume(struct pci_dev *); + +static struct pci_driver prism54_driver = { + .name = DRV_NAME, + .id_table = prism54_id_tbl, + .probe = prism54_probe, + .remove = prism54_remove, + .suspend = prism54_suspend, + .resume = prism54_resume, + /* .enable_wake ; we don't support this yet */ +}; + +static void +prism54_get_card_model(struct net_device *ndev) +{ + islpci_private *priv; + char *modelp; + + priv = ndev->priv; + switch (priv->pdev->subsystem_device) { + case PCIDEVICE_ISL3877: + modelp = "PRISM Indigo"; + break; + case PCIDEVICE_3COM6001: + modelp = "3COM 3CRWE154G72"; + break; + case 0x3202UL: + modelp = "D-Link DWL-g650 A1"; + break; + case 0xd019UL: + modelp = "WN-G54/CB"; + break; + case 0x4800UL: + modelp = "Netgear WG511"; + break; + case 0x2802UL: + modelp = "SMC2802W"; + break; + case 0xee03UL: + modelp = "SMC2802W V2"; + break; + case 0x2835UL: + modelp = "SMC2835W"; + break; + /* Let's leave this one out for now since it seems bogus/wrong + * Even if the manufacturer did use 0x0000UL it may not be correct + * by their part, therefore deserving no name ;) */ + /* case 0x0000UL: + * modelp = "SparkLAN WL-850F"; + * break;*/ + + /* We have two reported for the one below :( */ + case 0x0014UL: + modelp = "XG-600"; + break; + case 0x0020UL: + modelp = "XG-900/GW-DS54G"; + break; +/* Default it */ +/* + case PCIDEVICE_ISL3890: + modelp = "PRISM Duette/GT"; + break; +*/ + default: + modelp = "PRISM Duette/GT"; + } + printk(KERN_DEBUG "%s: %s driver detected card model: %s\n", + ndev->name, DRV_NAME, modelp); + return; +} + +/****************************************************************************** + Module initialization functions +******************************************************************************/ + +int +prism54_probe(struct pci_dev *pdev, const struct pci_device_id *id) +{ + struct net_device *ndev; + u8 latency_tmr; + u32 mem_addr; + islpci_private *priv; + int rvalue; + + /* TRACE(DRV_NAME); */ + + + /* Enable the pci device */ + if (pci_enable_device(pdev)) { + printk(KERN_ERR "%s: pci_enable_device() failed.\n", DRV_NAME); + return -ENODEV; + } + + /* check whether the latency timer is set correctly */ + pci_read_config_byte(pdev, PCI_LATENCY_TIMER, &latency_tmr); +#if VERBOSE > SHOW_ERROR_MESSAGES + DEBUG(SHOW_TRACING, "latency timer: %x\n", latency_tmr); +#endif + if (latency_tmr < PCIDEVICE_LATENCY_TIMER_MIN) { + /* set the latency timer */ + pci_write_config_byte(pdev, PCI_LATENCY_TIMER, + PCIDEVICE_LATENCY_TIMER_VAL); + } + + /* enable PCI DMA */ + if (pci_set_dma_mask(pdev, 0xffffffff)) { + printk(KERN_ERR "%s: 32-bit PCI DMA not supported", DRV_NAME); + goto do_pci_disable_device; + } + + /* 0x40 is the programmable timer to configure the response timeout (TRDY_TIMEOUT) + * 0x41 is the programmable timer to configure the retry timeout (RETRY_TIMEOUT) + * The RETRY_TIMEOUT is used to set the number of retries that the core, as a + * Master, will perform before abandoning a cycle. The default value for + * RETRY_TIMEOUT is 0x80, which far exceeds the PCI 2.1 requirement for new + * devices. A write of zero to the RETRY_TIMEOUT register disables this + * function to allow use with any non-compliant legacy devices that may + * execute more retries. + * + * Writing zero to both these two registers will disable both timeouts and + * *can* solve problems caused by devices that are slow to respond. + */ + pci_write_config_byte(pdev, 0x40, 0); + pci_write_config_byte(pdev, 0x41, 0); + + /* request the pci device I/O regions */ + rvalue = pci_request_regions(pdev, DRV_NAME); + if (rvalue) { + printk(KERN_ERR "%s: pci_request_regions failure (rc=%d)\n", + DRV_NAME, rvalue); + goto do_pci_disable_device; + } + + /* check if the memory window is indeed set */ + rvalue = pci_read_config_dword(pdev, PCI_BASE_ADDRESS_0, &mem_addr); + if (rvalue || !mem_addr) { + printk(KERN_ERR "%s: PCI device memory region not configured; fix your BIOS or CardBus bridge/drivers\n", + DRV_NAME); + goto do_pci_disable_device; + } + + /* enable PCI bus-mastering */ + DEBUG(SHOW_TRACING, "%s: pci_set_master(pdev)\n", DRV_NAME); + pci_set_master(pdev); + + /* setup the network device interface and its structure */ + if (!(ndev = islpci_setup(pdev))) { + /* error configuring the driver as a network device */ + printk(KERN_ERR "%s: could not configure network device\n", + DRV_NAME); + goto do_pci_release_regions; + } + + priv = ndev->priv; + islpci_set_state(priv, PRV_STATE_PREBOOT); /* we are attempting to boot */ + + /* card is in unknown state yet, might have some interrupts pending */ + isl38xx_disable_interrupts(priv->device_base); + + /* request for the interrupt before uploading the firmware */ + rvalue = request_irq(pdev->irq, &islpci_interrupt, + SA_SHIRQ, ndev->name, priv); + + if (rvalue) { + /* error, could not hook the handler to the irq */ + printk(KERN_ERR "%s: could not install IRQ handler\n", + ndev->name); + goto do_unregister_netdev; + } + + /* firmware upload is triggered in islpci_open */ + + /* Pretty card model discovery output */ + prism54_get_card_model(ndev); + + return 0; + + do_unregister_netdev: + unregister_netdev(ndev); + islpci_free_memory(priv); + pci_set_drvdata(pdev, 0); + free_netdev(ndev); + priv = 0; + do_pci_release_regions: + pci_release_regions(pdev); + do_pci_disable_device: + pci_disable_device(pdev); + return -EIO; +} + +/* set by cleanup_module */ +static volatile int __in_cleanup_module = 0; + +/* this one removes one(!!) instance only */ +void +prism54_remove(struct pci_dev *pdev) +{ + struct net_device *ndev = pci_get_drvdata(pdev); + islpci_private *priv = ndev ? ndev->priv : 0; + BUG_ON(!priv); + + if (!__in_cleanup_module) { + printk(KERN_DEBUG "%s: hot unplug detected\n", ndev->name); + islpci_set_state(priv, PRV_STATE_OFF); + } + + printk(KERN_DEBUG "%s: removing device\n", ndev->name); + + unregister_netdev(ndev); + + /* free the interrupt request */ + + if (islpci_get_state(priv) != PRV_STATE_OFF) { + isl38xx_disable_interrupts(priv->device_base); + islpci_set_state(priv, PRV_STATE_OFF); + /* This bellow causes a lockup at rmmod time. It might be + * because some interrupts still linger after rmmod time, + * see bug #17 */ + /* pci_set_power_state(pdev, 3);*/ /* try to power-off */ + } + + free_irq(pdev->irq, priv); + + /* free the PCI memory and unmap the remapped page */ + islpci_free_memory(priv); + + pci_set_drvdata(pdev, 0); + free_netdev(ndev); + priv = 0; + + pci_release_regions(pdev); + + pci_disable_device(pdev); +} + +int +prism54_suspend(struct pci_dev *pdev, u32 state) +{ + struct net_device *ndev = pci_get_drvdata(pdev); + islpci_private *priv = ndev ? ndev->priv : 0; + BUG_ON(!priv); + + printk(KERN_NOTICE "%s: got suspend request (state %d)\n", + ndev->name, state); + + pci_save_state(pdev, priv->pci_state); + + /* tell the device not to trigger interrupts for now... */ + isl38xx_disable_interrupts(priv->device_base); + + /* from now on assume the hardware was already powered down + and don't touch it anymore */ + islpci_set_state(priv, PRV_STATE_OFF); + + netif_stop_queue(ndev); + netif_device_detach(ndev); + + return 0; +} + +int +prism54_resume(struct pci_dev *pdev) +{ + struct net_device *ndev = pci_get_drvdata(pdev); + islpci_private *priv = ndev ? ndev->priv : 0; + BUG_ON(!priv); + + printk(KERN_NOTICE "%s: got resume request\n", ndev->name); + + pci_restore_state(pdev, priv->pci_state); + + /* alright let's go into the PREBOOT state */ + islpci_reset(priv, 1); + + netif_device_attach(ndev); + netif_start_queue(ndev); + + return 0; +} + +static int __init +prism54_module_init(void) +{ + printk(KERN_INFO "Loaded %s driver, version %s\n", + DRV_NAME, DRV_VERSION); + + __bug_on_wrong_struct_sizes (); + + return pci_module_init(&prism54_driver); +} + +/* by the time prism54_module_exit() terminates, as a postcondition + * all instances will have been destroyed by calls to + * prism54_remove() */ +static void __exit +prism54_module_exit(void) +{ + __in_cleanup_module = 1; + + pci_unregister_driver(&prism54_driver); + + printk(KERN_INFO "Unloaded %s driver\n", DRV_NAME); + + __in_cleanup_module = 0; +} + +/* register entry points */ +module_init(prism54_module_init); +module_exit(prism54_module_exit); +/* EOF */ diff -Nru a/drivers/net/wireless/prism54/islpci_mgt.c b/drivers/net/wireless/prism54/islpci_mgt.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/drivers/net/wireless/prism54/islpci_mgt.c Sun Mar 14 14:20:09 2004 @@ -0,0 +1,510 @@ +/* $Header: /var/lib/cvs/prism54-ng/ksrc/islpci_mgt.c,v 1.40 2004/02/01 10:57:23 mcgrof Exp $ + * + * Copyright (C) 2002 Intersil Americas Inc. + * Copyright 2004 Jens Maurer + * + * 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 + * + * 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 "isl_38xx.h" +#include "islpci_mgt.h" +#include "isl_oid.h" /* additional types and defs for isl38xx fw */ +#include "isl_ioctl.h" + +#include + +/****************************************************************************** + Global variable definition section +******************************************************************************/ +int pc_debug = VERBOSE; +MODULE_PARM(pc_debug, "i"); + +/****************************************************************************** + Driver general functions +******************************************************************************/ +void +display_buffer(char *buffer, int length) +{ + if ((pc_debug & SHOW_BUFFER_CONTENTS) == 0) + return; + + while (length > 0) { + printk("[%02x]", *buffer & 255); + length--; + buffer++; + } + + printk("\n"); +} + +/***************************************************************************** + Queue handling for management frames +******************************************************************************/ + + +/* + * Helper function to create a PIMFOR management frame header. + */ +static void +pimfor_encode_header(int operation, u32 oid, u32 length, pimfor_header_t *h) +{ + h->version = PIMFOR_VERSION; + h->operation = operation; + h->device_id = PIMFOR_DEV_ID_MHLI_MIB; + h->flags = 0; + h->oid = cpu_to_be32(oid); + h->length = cpu_to_be32(length); +} + +/* + * Helper function to analyze a PIMFOR management frame header. + */ +static pimfor_header_t * +pimfor_decode_header(void *data, int len) +{ + pimfor_header_t *h = data; + + while ((void *) h < data + len) { + if(h->flags & PIMFOR_FLAG_LITTLE_ENDIAN) { + le32_to_cpus(&h->oid); + le32_to_cpus(&h->length); + } else { + be32_to_cpus(&h->oid); + be32_to_cpus(&h->length); + } + if (h->oid != OID_INL_TUNNEL) + return h; + h++; + } + return NULL; +} + +/* + * Fill the receive queue for management frames with fresh buffers. + */ +int +islpci_mgmt_rx_fill(struct net_device *ndev) +{ + islpci_private *priv = ndev->priv; + isl38xx_control_block *cb = /* volatile not needed */ + (isl38xx_control_block *) priv->control_block; + u32 curr = le32_to_cpu(cb->driver_curr_frag[ISL38XX_CB_RX_MGMTQ]); + +#if VERBOSE > SHOW_ERROR_MESSAGES + DEBUG(SHOW_FUNCTION_CALLS, "islpci_mgmt_rx_fill \n"); +#endif + + while (curr - priv->index_mgmt_rx < ISL38XX_CB_MGMT_QSIZE) { + u32 index = curr % ISL38XX_CB_MGMT_QSIZE; + struct islpci_membuf *buf = &priv->mgmt_rx[index]; + isl38xx_fragment *frag = &cb->rx_data_mgmt[index]; + + if (buf->mem == NULL) { + buf->mem = kmalloc(MGMT_FRAME_SIZE, GFP_ATOMIC); + if (!buf->mem) { + printk(KERN_WARNING "Error allocating management frame.\n"); + return -ENOMEM; + } + buf->size = MGMT_FRAME_SIZE; + } + if (buf->pci_addr == 0) { + buf->pci_addr = pci_map_single(priv->pdev, buf->mem, + MGMT_FRAME_SIZE, + PCI_DMA_FROMDEVICE); + if(!buf->pci_addr) { + printk(KERN_WARNING "Failed to make memory DMA'able\n."); + return -ENOMEM; + } + } + + /* be safe: always reset control block information */ + frag->size = cpu_to_le16(MGMT_FRAME_SIZE); + frag->flags = 0; + frag->address = cpu_to_le32(buf->pci_addr); + curr++; + + /* The fragment address in the control block must have + * been written before announcing the frame buffer to + * device */ + wmb(); + cb->driver_curr_frag[ISL38XX_CB_RX_MGMTQ] = + cpu_to_le32(curr); + } + return 0; +} + +/* + * Create and transmit a management frame using "operation" and "oid", + * with arguments data/length. + * We either return an error and free the frame, or we return 0 and + * islpci_mgt_cleanup_transmit() frees the frame in the tx-done + * interrupt. + */ +static int +islpci_mgt_transmit(struct net_device *ndev, int operation, unsigned long oid, + void *data, int length) +{ + islpci_private *priv = ndev->priv; + isl38xx_control_block *cb = + (isl38xx_control_block *) priv->control_block; + void *p; + int err = -EINVAL; + unsigned long flags; + isl38xx_fragment *frag; + struct islpci_membuf buf; + u32 curr_frag; + int index; + int frag_len = length + PIMFOR_HEADER_SIZE; + +#if VERBOSE > SHOW_ERROR_MESSAGES + DEBUG(SHOW_FUNCTION_CALLS, "islpci_mgt_transmit\n"); +#endif + + if (frag_len > MGMT_FRAME_SIZE) { + printk(KERN_DEBUG "%s: mgmt frame too large %d\n", + ndev->name, frag_len); + goto error; + } + + err = -ENOMEM; + p = buf.mem = kmalloc(frag_len, GFP_KERNEL); + if (!buf.mem) { + printk(KERN_DEBUG "%s: cannot allocate mgmt frame\n", + ndev->name); + goto error; + } + buf.size = frag_len; + + /* create the header directly in the fragment data area */ + pimfor_encode_header(operation, oid, length, (pimfor_header_t *) p); + p += PIMFOR_HEADER_SIZE; + + if (data) + memcpy(p, data, length); + else + memset(p, 0, length); + +#if VERBOSE > SHOW_ERROR_MESSAGES + { + pimfor_header_t *h = buf.mem; + DEBUG(SHOW_PIMFOR_FRAMES, + "PIMFOR: op %i, oid 0x%08lx, device %i, flags 0x%x length 0x%x \n", + h->operation, oid, h->device_id, h->flags, length); + + /* display the buffer contents for debugging */ + display_buffer((char *) h, sizeof (pimfor_header_t)); + display_buffer(p, length); + } +#endif + + err = -ENOMEM; + buf.pci_addr = pci_map_single(priv->pdev, buf.mem, frag_len, + PCI_DMA_TODEVICE); + if (!buf.pci_addr) { + printk(KERN_WARNING "%s: cannot map PCI memory for mgmt\n", + ndev->name); + goto error_free; + } + + /* Protect the control block modifications against interrupts. */ + spin_lock_irqsave(&priv->slock, flags); + curr_frag = le32_to_cpu(cb->driver_curr_frag[ISL38XX_CB_TX_MGMTQ]); + if (curr_frag - priv->index_mgmt_tx >= ISL38XX_CB_MGMT_QSIZE) { + printk(KERN_WARNING "%s: mgmt tx queue is still full\n", + ndev->name); + goto error_unlock; + } + + /* commit the frame to the tx device queue */ + index = curr_frag % ISL38XX_CB_MGMT_QSIZE; + priv->mgmt_tx[index] = buf; + frag = &cb->tx_data_mgmt[index]; + frag->size = cpu_to_le16(frag_len); + frag->flags = 0; /* for any other than the last fragment, set to 1 */ + frag->address = cpu_to_le32(buf.pci_addr); + + /* The fragment address in the control block must have + * been written before announcing the frame buffer to + * device */ + wmb(); + cb->driver_curr_frag[ISL38XX_CB_TX_MGMTQ] = cpu_to_le32(curr_frag+1); + spin_unlock_irqrestore(&priv->slock, flags); + + /* trigger the device */ + islpci_trigger(priv); + return 0; + + error_unlock: + spin_unlock_irqrestore(&priv->slock, flags); + error_free: + kfree(buf.mem); + error: + return err; +} + +/* + * Receive a management frame from the device. + * This can be an arbitrary number of traps, and at most one response + * frame for a previous request sent via islpci_mgt_transmit(). + */ +int +islpci_mgt_receive(struct net_device *ndev) +{ + islpci_private *priv = ndev->priv; + isl38xx_control_block *cb = + (isl38xx_control_block *) priv->control_block; + u32 curr_frag; + +#if VERBOSE > SHOW_ERROR_MESSAGES + DEBUG(SHOW_FUNCTION_CALLS, "islpci_mgt_receive \n"); +#endif + + + /* Only once per interrupt, determine fragment range to + * process. This avoids an endless loop (i.e. lockup) if + * frames come in faster than we can process them. */ + curr_frag = le32_to_cpu(cb->device_curr_frag[ISL38XX_CB_RX_MGMTQ]); + barrier(); + + for ( ; priv->index_mgmt_rx < curr_frag; priv->index_mgmt_rx++) { + pimfor_header_t *header; + u32 index = priv->index_mgmt_rx % ISL38XX_CB_MGMT_QSIZE; + struct islpci_membuf *buf = &priv->mgmt_rx[index]; + u16 frag_len; + int size; + struct islpci_mgmtframe *frame; + + /* I have no idea (and no documentation) if flags != 0 + * is possible. Drop the frame, reuse the buffer. */ + if(le16_to_cpu(cb->rx_data_mgmt[index].flags) != 0) { + printk(KERN_WARNING "%s: unknown flags 0x%04x\n", + ndev->name, + le16_to_cpu(cb->rx_data_mgmt[index].flags)); + continue; + } + + /* The device only returns the size of the header(s) here. */ + frag_len = le16_to_cpu(cb->rx_data_mgmt[index].size); + + /* + * We appear to have no way to tell the device the + * size of a receive buffer. Thus, if this check + * triggers, we likely have kernel heap corruption. */ + if (frag_len > MGMT_FRAME_SIZE) { + printk(KERN_WARNING "%s: Bogus packet size of %d (%#x).\ +n", + ndev->name, frag_len, frag_len); + frag_len = MGMT_FRAME_SIZE; + } + + /* Ensure the results of device DMA are visible to the CPU. */ + pci_dma_sync_single(priv->pdev, buf->pci_addr, + buf->size, PCI_DMA_FROMDEVICE); + + /* Perform endianess conversion for PIMFOR header in-place. */ + header = pimfor_decode_header(buf->mem, frag_len); + if (!header) { + printk(KERN_WARNING "%s: no PIMFOR header found\n", + ndev->name); + continue; + } + + /* The device ID from the PIMFOR packet received from + * the MVC is always 0. We forward a sensible device_id. + * Not that anyone upstream would care... */ + header->device_id = priv->ndev->ifindex; + +#if VERBOSE > SHOW_ERROR_MESSAGES + DEBUG(SHOW_PIMFOR_FRAMES, + "PIMFOR: op %i, oid 0x%08x, device %i, flags 0x%x length 0x%x \n", + header->operation, header->oid, header->device_id, + header->flags, header->length); + + /* display the buffer contents for debugging */ + display_buffer((char *) header, PIMFOR_HEADER_SIZE); + display_buffer((char *) header + PIMFOR_HEADER_SIZE, header->length); +#endif + + /* nobody sends these */ + if (header->flags & PIMFOR_FLAG_APPLIC_ORIGIN) { + printk(KERN_DEBUG "%s: errant PIMFOR application frame\n", + ndev->name); + continue; + } + + /* Determine frame size, skipping OID_INL_TUNNEL headers. */ + size = PIMFOR_HEADER_SIZE + header->length; + frame = kmalloc(sizeof(struct islpci_mgmtframe) + size, + GFP_ATOMIC); + if (!frame) { + printk(KERN_WARNING "%s: Out of memory, cannot handle oid 0x%08x\n", + + ndev->name, header->oid); + continue; + } + frame->ndev = ndev; + memcpy(&frame->buf, header, size); + frame->header = (pimfor_header_t *) frame->buf; + frame->data = frame->buf + PIMFOR_HEADER_SIZE; + +#if VERBOSE > SHOW_ERROR_MESSAGES + DEBUG(SHOW_PIMFOR_FRAMES, + "frame: header: %p, data: %p, size: %d\n", + frame->header, frame->data, size); +#endif + + if (header->operation == PIMFOR_OP_TRAP) { +#if VERBOSE > SHOW_ERROR_MESSAGES + printk(KERN_DEBUG + "TRAP: oid 0x%x, device %i, flags 0x%x length %i\n", + header->oid, header->device_id, header->flags, + header->length); +#endif + + /* Create work to handle trap out of interrupt + * context. */ + INIT_WORK(&frame->ws, prism54_process_trap, frame); + schedule_work(&frame->ws); + + } else { + /* Signal the one waiting process that a response + * has been received. */ + if ((frame = xchg(&priv->mgmt_received, frame)) != NULL) { + printk(KERN_WARNING "%s: mgmt response not collected\n", + ndev->name); + kfree(frame); + } + +#if VERBOSE > SHOW_ERROR_MESSAGES + DEBUG(SHOW_TRACING, + "Wake up Mgmt Queue\n"); +#endif + wake_up(&priv->mgmt_wqueue); + } + + } + + return 0; +} + +/* + * Cleanup the transmit queue by freeing all frames handled by the device. + */ +void +islpci_mgt_cleanup_transmit(struct net_device *ndev) +{ + islpci_private *priv = ndev->priv; + isl38xx_control_block *cb = /* volatile not needed */ + (isl38xx_control_block *) priv->control_block; + u32 curr_frag; + +#if VERBOSE > SHOW_ERROR_MESSAGES + DEBUG(SHOW_FUNCTION_CALLS, "islpci_mgt_cleanup_transmit\n"); +#endif + + /* Only once per cleanup, determine fragment range to + * process. This avoids an endless loop (i.e. lockup) if + * the device became confused, incrementing device_curr_frag + * rapidly. */ + curr_frag = le32_to_cpu(cb->device_curr_frag[ISL38XX_CB_TX_MGMTQ]); + barrier(); + + for ( ; priv->index_mgmt_tx < curr_frag; priv->index_mgmt_tx++) { + int index = priv->index_mgmt_tx % ISL38XX_CB_MGMT_QSIZE; + struct islpci_membuf *buf = &priv->mgmt_tx[index]; + pci_unmap_single(priv->pdev, buf->pci_addr, buf->size, + PCI_DMA_TODEVICE); + buf->pci_addr = 0; + kfree(buf->mem); + buf->mem = NULL; + buf->size = 0; + } +} + +/* + * Perform one request-response transaction to the device. + */ +int +islpci_mgt_transaction(struct net_device *ndev, + int operation, unsigned long oid, + void *senddata, int sendlen, + struct islpci_mgmtframe **recvframe) +{ + islpci_private *priv = ndev->priv; + const long wait_cycle_jiffies = (ISL38XX_WAIT_CYCLE * 10 * HZ) / 1000; + long timeout_left = ISL38XX_MAX_WAIT_CYCLES * wait_cycle_jiffies; + int err; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) + DEFINE_WAIT(wait); +#else + DECLARE_WAITQUEUE(wait, current); +#endif + + if (down_interruptible(&priv->mgmt_sem)) + return -ERESTARTSYS; + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) + prepare_to_wait(&priv->mgmt_wqueue, &wait, TASK_UNINTERRUPTIBLE); +#else + set_current_state(TASK_UNINTERRUPTIBLE); + add_wait_queue(&priv->mgmt_wqueue, &wait); +#endif + err = islpci_mgt_transmit(ndev, operation, oid, senddata, sendlen); + if(err) + goto out; + + err = -ETIMEDOUT; + while (timeout_left > 0) { + int timeleft; + struct islpci_mgmtframe *frame; + + timeleft = schedule_timeout(wait_cycle_jiffies); + frame = xchg(&priv->mgmt_received, NULL); + if (frame) { + *recvframe = frame; + err = 0; + goto out; + } + if(timeleft == 0) { + printk(KERN_DEBUG "%s: timeout waiting for mgmt response %lu, trigging device\n", + ndev->name, timeout_left); + islpci_trigger(priv); + } + timeout_left += timeleft - wait_cycle_jiffies; + } + printk(KERN_WARNING "%s: timeout waiting for mgmt response\n", + ndev->name); + + /* TODO: we should reset the device here */ + out: +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) + finish_wait(&priv->mgmt_wqueue, &wait); +#else + remove_wait_queue(&priv->mgmt_wqueue, &wait); + set_current_state(TASK_RUNNING); +#endif + up(&priv->mgmt_sem); + return err; +} + diff -Nru a/drivers/net/wireless/prism54/islpci_mgt.h b/drivers/net/wireless/prism54/islpci_mgt.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/drivers/net/wireless/prism54/islpci_mgt.h Sun Mar 14 14:20:09 2004 @@ -0,0 +1,166 @@ +/* $Header: /var/lib/cvs/prism54-ng/ksrc/islpci_mgt.h,v 1.22 2004/01/30 16:24:00 ajfa Exp $ + * + * Copyright (C) 2002 Intersil Americas Inc. + * Copyright (C) 2003 Luis R. Rodriguez + * + * 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 + * + * 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 + * + */ + +#ifndef _ISLPCI_MGT_H +#define _ISLPCI_MGT_H + +#include +#include + +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,41) +# include +#else +# include +# define work_struct tq_struct +# define INIT_WORK INIT_TQUEUE +# define schedule_work schedule_task +#endif + +/* + * Function definitions + */ + +#define K_DEBUG(f, m, args...) do { if(f & m) printk(KERN_DEBUG args); } while(0) +#define DEBUG(f, args...) K_DEBUG(f, pc_debug, args) + +#define TRACE(devname) K_DEBUG(SHOW_TRACING, VERBOSE, "%s: -> " __FUNCTION__ "()\n", devname) + +extern int pc_debug; +static const int init_wds = 0; /* help compiler optimize away dead code */ + + +/* General driver definitions */ +#define PCIVENDOR_INTERSIL 0x1260UL +#define PCIVENDOR_3COM 0x10b7UL +#define PCIVENDOR_DLINK 0x1186UL +#define PCIVENDOR_I4 0x17cfUL +#define PCIVENDOR_IODATA 0x10fcUL +#define PCIVENDOR_NETGEAR 0x1385UL +#define PCIVENDOR_SMC 0x10b8UL +#define PCIVENDOR_ACCTON 0x1113UL + +#define PCIDEVICE_ISL3877 0x3877UL +#define PCIDEVICE_ISL3890 0x3890UL +#define PCIDEVICE_3COM6001 0x6001UL +#define PCIDEVICE_LATENCY_TIMER_MIN 0x40 +#define PCIDEVICE_LATENCY_TIMER_VAL 0x50 + +/* Debugging verbose definitions */ +#define SHOW_NOTHING 0x00 /* overrules everything */ +#define SHOW_ANYTHING 0xFF +#define SHOW_ERROR_MESSAGES 0x01 +#define SHOW_TRAPS 0x02 +#define SHOW_FUNCTION_CALLS 0x04 +#define SHOW_TRACING 0x08 +#define SHOW_QUEUE_INDEXES 0x10 +#define SHOW_PIMFOR_FRAMES 0x20 +#define SHOW_BUFFER_CONTENTS 0x40 +#define VERBOSE 0x01 + +/* Default card definitions */ +#define CARD_DEFAULT_CHANNEL 6 +#define CARD_DEFAULT_MODE INL_MODE_CLIENT +#define CARD_DEFAULT_IW_MODE IW_MODE_INFRA +#define CARD_DEFAULT_BSSTYPE DOT11_BSSTYPE_INFRA +#define CARD_DEFAULT_CLIENT_SSID "" +#define CARD_DEFAULT_AP_SSID "default" +#define CARD_DEFAULT_KEY1 "default_key_1" +#define CARD_DEFAULT_KEY2 "default_key_2" +#define CARD_DEFAULT_KEY3 "default_key_3" +#define CARD_DEFAULT_KEY4 "default_key_4" +#define CARD_DEFAULT_WEP 0 +#define CARD_DEFAULT_FILTER 0 +# define CARD_DEFAULT_WDS 0 +#define CARD_DEFAULT_AUTHEN DOT11_AUTH_OS +#define CARD_DEFAULT_DOT1X 0 +#define CARD_DEFAULT_MLME_MODE DOT11_MLME_AUTO +#define CARD_DEFAULT_CONFORMANCE OID_INL_CONFORMANCE_NONE + +/* PIMFOR package definitions */ +#define PIMFOR_ETHERTYPE 0x8828 +#define PIMFOR_HEADER_SIZE 12 +#define PIMFOR_VERSION 1 +#define PIMFOR_OP_GET 0 +#define PIMFOR_OP_SET 1 +#define PIMFOR_OP_RESPONSE 2 +#define PIMFOR_OP_ERROR 3 +#define PIMFOR_OP_TRAP 4 +#define PIMFOR_OP_RESERVED 5 /* till 255 */ +#define PIMFOR_DEV_ID_MHLI_MIB 0 +#define PIMFOR_FLAG_APPLIC_ORIGIN 0x01 +#define PIMFOR_FLAG_LITTLE_ENDIAN 0x02 + +static inline void +add_le32p(u32 * le_number, u32 add) +{ + *le_number = cpu_to_le32(le32_to_cpup(le_number) + add); +} + +void display_buffer(char *, int); + +/* + * Type definition section + * + * the structure defines only the header allowing copyless + * frame handling + */ +typedef struct { + u8 version; + u8 operation; + u32 oid; + u8 device_id; + u8 flags; + u32 length; +} __attribute__ ((packed)) +pimfor_header_t; + +/* A received and interrupt-processed management frame, either for + * schedule_work(prism54_process_trap) or for priv->mgmt_received, + * processed by islpci_mgt_transaction(). */ +struct islpci_mgmtframe { + struct net_device *ndev; /* pointer to network device */ + pimfor_header_t *header; /* payload header, points into buf */ + void *data; /* payload ex header, points into buf */ + struct work_struct ws; /* argument for schedule_work() */ + char buf[0]; /* fragment buffer */ +}; + +int +islpci_mgt_receive(struct net_device *ndev); + +int +islpci_mgmt_rx_fill(struct net_device *ndev); + +void +islpci_mgt_cleanup_transmit(struct net_device *ndev); + +int +islpci_mgt_transaction(struct net_device *ndev, + int operation, unsigned long oid, + void *senddata, int sendlen, + struct islpci_mgmtframe **recvframe); + +static inline void +islpci_mgt_release(struct islpci_mgmtframe *frame) +{ + kfree(frame); +} + +#endif /* _ISLPCI_MGT_H */ diff -Nru a/drivers/net/wireless/prism54/oid_mgt.c b/drivers/net/wireless/prism54/oid_mgt.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/drivers/net/wireless/prism54/oid_mgt.c Sun Mar 14 14:20:09 2004 @@ -0,0 +1,532 @@ +/* + * Copyright (C) 2003 Aurelien Alleaume + * + * 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 + * + * 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 "islpci_dev.h" +#include "islpci_mgt.h" +#include "isl_oid.h" +#include "oid_mgt.h" +#include "isl_ioctl.h" + +/* to convert between channel and freq */ +const int frequency_list_bg[] = { 2412, 2417, 2422, 2427, 2432, 2437, 2442, + 2447, 2452, 2457, 2462, 2467, 2472, 2484 +}; + +const int frequency_list_a[] = { 5170, 5180, 5190, 5200, 5210, 5220, 5230, + 5240, 5260, 5280, 5300, 5320 +}; + +#define OID_U32(x) {x, 0, sizeof(u32), OID_FLAG_U32} +#define OID_U32_C(x) {x, 0, sizeof(u32), OID_FLAG_U32 | OID_FLAG_CACHED} +#define OID_STRUCT(x,s) {x, 0, sizeof(s), 0} +#define OID_STRUCT_C(x,s) {x, 0, sizeof(s), OID_FLAG_CACHED} +#define OID_STRUCT_MLME(x){x, 0, sizeof(struct obj_mlme), 0} +#define OID_STRUCT_MLMEEX(x){x, 0, sizeof(struct obj_mlmeex), OID_FLAG_MLMEEX} + +#define OID_UNKNOWN(x) {x, 0, 0, 0} + +struct oid_t isl_oid[] = { + [GEN_OID_MACADDRESS] = OID_STRUCT(0x00000000, u8[6]), + [GEN_OID_LINKSTATE] = OID_U32(0x00000001), + [GEN_OID_WATCHDOG] = OID_UNKNOWN(0x00000002), + [GEN_OID_MIBOP] = OID_UNKNOWN(0x00000003), + [GEN_OID_OPTIONS] = OID_UNKNOWN(0x00000004), + [GEN_OID_LEDCONFIG] = OID_UNKNOWN(0x00000005), + + /* 802.11 */ + [DOT11_OID_BSSTYPE] = OID_U32_C(0x10000000), + [DOT11_OID_BSSID] = OID_STRUCT_C(0x10000001, u8[6]), + [DOT11_OID_SSID] = OID_STRUCT_C(0x10000002, struct obj_ssid), + [DOT11_OID_STATE] = OID_U32(0x10000003), + [DOT11_OID_AID] = OID_U32(0x10000004), + [DOT11_OID_COUNTRYSTRING] = OID_STRUCT(0x10000005, u8[4]), + [DOT11_OID_SSIDOVERRIDE] = OID_STRUCT_C(0x10000006, struct obj_ssid), + + [DOT11_OID_MEDIUMLIMIT] = OID_U32(0x11000000), + [DOT11_OID_BEACONPERIOD] = OID_U32_C(0x11000001), + [DOT11_OID_DTIMPERIOD] = OID_U32(0x11000002), + [DOT11_OID_ATIMWINDOW] = OID_U32(0x11000003), + [DOT11_OID_LISTENINTERVAL] = OID_U32(0x11000004), + [DOT11_OID_CFPPERIOD] = OID_U32(0x11000005), + [DOT11_OID_CFPDURATION] = OID_U32(0x11000006), + + [DOT11_OID_AUTHENABLE] = OID_U32_C(0x12000000), + [DOT11_OID_PRIVACYINVOKED] = OID_U32_C(0x12000001), + [DOT11_OID_EXUNENCRYPTED] = OID_U32_C(0x12000002), + [DOT11_OID_DEFKEYID] = OID_U32_C(0x12000003), + [DOT11_OID_DEFKEYX] = {0x12000004, 3, sizeof (struct obj_key), OID_FLAG_CACHED}, /* DOT11_OID_DEFKEY1,...DOT11_OID_DEFKEY4 */ + [DOT11_OID_STAKEY] = OID_UNKNOWN(0x12000008), + [DOT11_OID_REKEYTHRESHOLD] = OID_U32(0x12000009), + [DOT11_OID_STASC] = OID_UNKNOWN(0x1200000a), + + [DOT11_OID_PRIVTXREJECTED] = OID_U32(0x1a000000), + [DOT11_OID_PRIVRXPLAIN] = OID_U32(0x1a000001), + [DOT11_OID_PRIVRXFAILED] = OID_U32(0x1a000002), + [DOT11_OID_PRIVRXNOKEY] = OID_U32(0x1a000003), + + [DOT11_OID_RTSTHRESH] = OID_U32_C(0x13000000), + [DOT11_OID_FRAGTHRESH] = OID_U32_C(0x13000001), + [DOT11_OID_SHORTRETRIES] = OID_U32_C(0x13000002), + [DOT11_OID_LONGRETRIES] = OID_U32_C(0x13000003), + [DOT11_OID_MAXTXLIFETIME] = OID_U32_C(0x13000004), + [DOT11_OID_MAXRXLIFETIME] = OID_U32(0x13000005), + [DOT11_OID_AUTHRESPTIMEOUT] = OID_U32(0x13000006), + [DOT11_OID_ASSOCRESPTIMEOUT] = OID_U32(0x13000007), + + [DOT11_OID_ALOFT_TABLE] = OID_UNKNOWN(0x1d000000), + [DOT11_OID_ALOFT_CTRL_TABLE] = OID_UNKNOWN(0x1d000001), + [DOT11_OID_ALOFT_RETREAT] = OID_UNKNOWN(0x1d000002), + [DOT11_OID_ALOFT_PROGRESS] = OID_UNKNOWN(0x1d000003), + [DOT11_OID_ALOFT_FIXEDRATE] = OID_U32(0x1d000004), + [DOT11_OID_ALOFT_RSSIGRAPH] = OID_UNKNOWN(0x1d000005), + [DOT11_OID_ALOFT_CONFIG] = OID_UNKNOWN(0x1d000006), + + [DOT11_OID_VDCFX] = {0x1b000000, 7, 0, 0}, + [DOT11_OID_MAXFRAMEBURST] = OID_U32(0x1b000008), + + [DOT11_OID_PSM] = OID_U32(0x14000000), + [DOT11_OID_CAMTIMEOUT] = OID_U32(0x14000001), + [DOT11_OID_RECEIVEDTIMS] = OID_U32(0x14000002), + [DOT11_OID_ROAMPREFERENCE] = OID_U32(0x14000003), + + [DOT11_OID_BRIDGELOCAL] = OID_U32(0x15000000), + [DOT11_OID_CLIENTS] = OID_U32(0x15000001), + [DOT11_OID_CLIENTSASSOCIATED] = OID_U32(0x15000002), + [DOT11_OID_CLIENTX] = {0x15000003, 2006, 0, 0}, /* DOT11_OID_CLIENTX,...DOT11_OID_CLIENT2007 */ + + [DOT11_OID_CLIENTFIND] = OID_STRUCT(0x150007DB, u8[6]), + [DOT11_OID_WDSLINKADD] = OID_STRUCT(0x150007DC, u8[6]), + [DOT11_OID_WDSLINKREMOVE] = OID_STRUCT(0x150007DD, u8[6]), + [DOT11_OID_EAPAUTHSTA] = OID_STRUCT(0x150007DE, u8[6]), + [DOT11_OID_EAPUNAUTHSTA] = OID_STRUCT(0x150007DF, u8[6]), + [DOT11_OID_DOT1XENABLE] = OID_U32_C(0x150007E0), + [DOT11_OID_MICFAILURE] = OID_UNKNOWN(0x150007E1), + [DOT11_OID_REKEYINDICATE] = OID_UNKNOWN(0x150007E2), + + [DOT11_OID_MPDUTXSUCCESSFUL] = OID_U32(0x16000000), + [DOT11_OID_MPDUTXONERETRY] = OID_U32(0x16000001), + [DOT11_OID_MPDUTXMULTIPLERETRIES] = OID_U32(0x16000002), + [DOT11_OID_MPDUTXFAILED] = OID_U32(0x16000003), + [DOT11_OID_MPDURXSUCCESSFUL] = OID_U32(0x16000004), + [DOT11_OID_MPDURXDUPS] = OID_U32(0x16000005), + [DOT11_OID_RTSSUCCESSFUL] = OID_U32(0x16000006), + [DOT11_OID_RTSFAILED] = OID_U32(0x16000007), + [DOT11_OID_ACKFAILED] = OID_U32(0x16000008), + [DOT11_OID_FRAMERECEIVES] = OID_U32(0x16000009), + [DOT11_OID_FRAMEERRORS] = OID_U32(0x1600000A), + [DOT11_OID_FRAMEABORTS] = OID_U32(0x1600000B), + [DOT11_OID_FRAMEABORTSPHY] = OID_U32(0x1600000C), + + [DOT11_OID_SLOTTIME] = OID_U32(0x17000000), + [DOT11_OID_CWMIN] = OID_U32(0x17000001), + [DOT11_OID_CWMAX] = OID_U32(0x17000002), + [DOT11_OID_ACKWINDOW] = OID_U32(0x17000003), + [DOT11_OID_ANTENNARX] = OID_U32(0x17000004), + [DOT11_OID_ANTENNATX] = OID_U32(0x17000005), + [DOT11_OID_ANTENNADIVERSITY] = OID_U32(0x17000006), + [DOT11_OID_CHANNEL] = OID_U32_C(0x17000007), + [DOT11_OID_EDTHRESHOLD] = OID_U32_C(0x17000008), + [DOT11_OID_PREAMBLESETTINGS] = OID_U32(0x17000009), + [DOT11_OID_RATES] = OID_STRUCT(0x1700000A, u8[IWMAX_BITRATES + 1]), + [DOT11_OID_CCAMODESUPPORTED] = OID_U32(0x1700000B), + [DOT11_OID_CCAMODE] = OID_U32(0x1700000C), + [DOT11_OID_RSSIVECTOR] = OID_U32(0x1700000D), + [DOT11_OID_OUTPUTPOWERTABLE] = OID_U32(0x1700000E), + [DOT11_OID_OUTPUTPOWER] = OID_U32_C(0x1700000F), + [DOT11_OID_SUPPORTEDRATES] = + OID_STRUCT(0x17000010, u8[IWMAX_BITRATES + 1]), + [DOT11_OID_FREQUENCY] = OID_U32_C(0x17000011), + [DOT11_OID_SUPPORTEDFREQUENCIES] = {0x17000012, 0, sizeof (struct + obj_frequencies) + + sizeof (u16) * IWMAX_FREQ, 0}, + + [DOT11_OID_NOISEFLOOR] = OID_U32(0x17000013), + [DOT11_OID_FREQUENCYACTIVITY] = + OID_STRUCT(0x17000014, u8[IWMAX_FREQ + 1]), + [DOT11_OID_IQCALIBRATIONTABLE] = OID_UNKNOWN(0x17000015), + [DOT11_OID_NONERPPROTECTION] = OID_U32(0x17000016), + [DOT11_OID_SLOTSETTINGS] = OID_U32(0x17000017), + [DOT11_OID_NONERPTIMEOUT] = OID_U32(0x17000018), + [DOT11_OID_PROFILES] = OID_U32(0x17000019), + [DOT11_OID_EXTENDEDRATES] = + OID_STRUCT(0x17000020, u8[IWMAX_BITRATES + 1]), + + [DOT11_OID_DEAUTHENTICATE] = OID_STRUCT_MLME(0x18000000), + [DOT11_OID_AUTHENTICATE] = OID_STRUCT_MLME(0x18000001), + [DOT11_OID_DISASSOCIATE] = OID_STRUCT_MLME(0x18000002), + [DOT11_OID_ASSOCIATE] = OID_STRUCT_MLME(0x18000003), + [DOT11_OID_SCAN] = OID_UNKNOWN(0x18000004), + [DOT11_OID_BEACON] = OID_STRUCT_MLMEEX(0x18000005), + [DOT11_OID_PROBE] = OID_STRUCT_MLMEEX(0x18000006), + [DOT11_OID_DEAUTHENTICATEEX] = OID_STRUCT_MLMEEX(0x18000007), + [DOT11_OID_AUTHENTICATEEX] = OID_STRUCT_MLMEEX(0x18000008), + [DOT11_OID_DISASSOCIATEEX] = OID_STRUCT_MLMEEX(0x18000009), + [DOT11_OID_ASSOCIATEEX] = OID_STRUCT_MLMEEX(0x1800000A), + [DOT11_OID_REASSOCIATE] = OID_STRUCT_MLMEEX(0x1800000B), + [DOT11_OID_REASSOCIATEEX] = OID_STRUCT_MLMEEX(0x1800000C), + + [DOT11_OID_NONERPSTATUS] = OID_U32(0x1E000000), + + [DOT11_OID_STATIMEOUT] = OID_U32(0x19000000), + [DOT11_OID_MLMEAUTOLEVEL] = OID_U32_C(0x19000001), + [DOT11_OID_BSSTIMEOUT] = OID_U32(0x19000002), + [DOT11_OID_ATTACHMENT] = OID_UNKNOWN(0x19000003), + [DOT11_OID_PSMBUFFER] = OID_STRUCT_C(0x19000004, struct obj_buffer), + + [DOT11_OID_BSSS] = OID_U32(0x1C000000), + [DOT11_OID_BSSX] = {0x1C000001, 63, sizeof (struct obj_bss), 0}, /*DOT11_OID_BSS1,...,DOT11_OID_BSS64 */ + [DOT11_OID_BSSFIND] = OID_STRUCT(0x1C000042, struct obj_bss), + [DOT11_OID_BSSLIST] = {0x1C000043, 0, sizeof (struct + obj_bsslist) + + sizeof (struct obj_bss[IWMAX_BSS]), 0}, + + [OID_INL_TUNNEL] = OID_UNKNOWN(0xFF020000), + [OID_INL_MEMADDR] = OID_UNKNOWN(0xFF020001), + [OID_INL_MEMORY] = OID_UNKNOWN(0xFF020002), + [OID_INL_MODE] = OID_U32_C(0xFF020003), + [OID_INL_COMPONENT_NR] = OID_UNKNOWN(0xFF020004), + [OID_INL_VERSION] = OID_UNKNOWN(0xFF020005), + [OID_INL_INTERFACE_ID] = OID_UNKNOWN(0xFF020006), + [OID_INL_COMPONENT_ID] = OID_UNKNOWN(0xFF020007), + [OID_INL_CONFIG] = OID_U32_C(0xFF020008), + [OID_INL_DOT11D_CONFORMANCE] = OID_U32_C(0xFF02000C), + [OID_INL_PHYCAPABILITIES] = OID_U32(0xFF02000D), + [OID_INL_OUTPUTPOWER] = OID_U32_C(0xFF02000F), + +}; + +int +mgt_init(islpci_private *priv) +{ + int i; + + priv->mib = kmalloc(OID_NUM_LAST * sizeof (void *), GFP_KERNEL); + if (!priv->mib) + return -ENOMEM; + + memset(priv->mib, 0, OID_NUM_LAST * sizeof (void *)); + + /* Alloc the cache */ + for (i = 0; i < OID_NUM_LAST; i++) { + if (isl_oid[i].flags & OID_FLAG_CACHED) { + priv->mib[i] = kmalloc(isl_oid[i].size * + (isl_oid[i].range + 1), + GFP_KERNEL); + if (!priv->mib[i]) + return -ENOMEM; + memset(priv->mib[i], 0, + isl_oid[i].size * (isl_oid[i].range + 1)); + } else + priv->mib[i] = NULL; + } + + init_rwsem(&priv->mib_sem); + prism54_mib_init(priv); + + return 0; +} + +void +mgt_clean(islpci_private *priv) +{ + int i; + + if (!priv->mib) + return; + for (i = 0; i < OID_NUM_LAST; i++) + if (priv->mib[i]) { + kfree(priv->mib[i]); + priv->mib[i] = NULL; + } + kfree(priv->mib); + priv->mib = NULL; +} + +int +mgt_set_request(islpci_private *priv, enum oid_num_t n, int extra, void *data) +{ + int ret = 0; + struct islpci_mgmtframe *response; + int response_op = PIMFOR_OP_ERROR; + int dlen; + void *cache, *_data = data; + u32 oid, u; + + BUG_ON(OID_NUM_LAST <= n); + BUG_ON(extra > isl_oid[n].range); + + if (!priv->mib) + /* memory has been freed */ + return -1; + + dlen = isl_oid[n].size; + cache = priv->mib[n]; + cache += (cache ? extra * dlen : 0); + oid = isl_oid[n].oid + extra; + + if (data == NULL) + /* we are requested to re-set a cached value */ + _data = cache; + if ((isl_oid[n].flags & OID_FLAG_U32) && data) { + u = cpu_to_le32(*(u32 *) data); + _data = &u; + } + /* If we are going to write to the cache, we don't want anyone to read + * it -> acquire write lock. + * Else we could acquire a read lock to be sure we don't bother the + * commit process (which takes a write lock). But I'm not sure if it's + * needed. + */ + if (cache) + down_write(&priv->mib_sem); + + if (islpci_get_state(priv) >= PRV_STATE_INIT) { + ret = islpci_mgt_transaction(priv->ndev, PIMFOR_OP_SET, oid, + _data, dlen, &response); + if (!ret) { + response_op = response->header->operation; + islpci_mgt_release(response); + } + if (ret || response_op == PIMFOR_OP_ERROR) + ret = -EIO; + } else if (!cache) + ret = -EIO; + + if (cache) { + if (!ret && data) + memcpy(cache, _data, dlen); + up_write(&priv->mib_sem); + } + + return ret; +} + +int +mgt_get_request(islpci_private *priv, enum oid_num_t n, int extra, void *data, + union oid_res_t *res) +{ + + int ret = -EIO; + int reslen = 0; + struct islpci_mgmtframe *response = NULL; + + int dlen; + void *cache, *_res=NULL; + u32 oid; + + BUG_ON(OID_NUM_LAST <= n); + BUG_ON(extra > isl_oid[n].range); + + if (!priv->mib) + /* memory has been freed */ + return -1; + + dlen = isl_oid[n].size; + cache = priv->mib[n]; + cache += cache ? extra * dlen : 0; + oid = isl_oid[n].oid + extra; + reslen = dlen; + + if (cache) + down_read(&priv->mib_sem); + + if (islpci_get_state(priv) >= PRV_STATE_INIT) { + ret = islpci_mgt_transaction(priv->ndev, PIMFOR_OP_GET, + oid, data, dlen, &response); + if (ret || !response || + response->header->operation == PIMFOR_OP_ERROR) { + if (response) + islpci_mgt_release(response); + ret = -EIO; + } + if (!ret) { + _res = response->data; + reslen = response->header->length; + } + } else if (cache) { + _res = cache; + ret = 0; + } + if (isl_oid[n].flags & OID_FLAG_U32) { + if (ret) + res->u = 0; + else + res->u = le32_to_cpu(*(u32 *) _res); + } else { + res->ptr = kmalloc(reslen, GFP_KERNEL); + BUG_ON(res->ptr == NULL); + if (ret) + memset(res->ptr, 0, reslen); + else + memcpy(res->ptr, _res, reslen); + } + + if (cache) + up_read(&priv->mib_sem); + + if (response && !ret) + islpci_mgt_release(response); + + if (reslen > isl_oid[n].size) + printk(KERN_DEBUG + "mgt_get_request(0x%x): received data length was bigger " + "than expected (%d > %d). Memory is probably corrupted... ", + oid, reslen, isl_oid[n].size); + + return ret; +} + +/* lock outside */ +int +mgt_commit_list(islpci_private *priv, enum oid_num_t *l, int n) +{ + int i, ret = 0; + struct islpci_mgmtframe *response; + + for (i = 0; i < n; i++) { + struct oid_t *t = &(isl_oid[l[i]]); + void *data = priv->mib[l[i]]; + int j = 0; + u32 oid = t->oid; + BUG_ON(data == NULL); + while (j <= t->range){ + response = NULL; + ret |= islpci_mgt_transaction(priv->ndev, PIMFOR_OP_SET, + oid, data, t->size, + &response); + if (response) { + ret |= (response->header->operation == + PIMFOR_OP_ERROR); + islpci_mgt_release(response); + } + j++; + oid++; + data += t->size; + } + } + return ret; +} + +/* Lock outside */ + +void +mgt_set(islpci_private *priv, enum oid_num_t n, void *data) +{ + BUG_ON(OID_NUM_LAST <= n); + BUG_ON(priv->mib[n] == NULL); + + memcpy(priv->mib[n], data, isl_oid[n].size); + if (isl_oid[n].flags & OID_FLAG_U32) + *(u32 *) priv->mib[n] = cpu_to_le32(*(u32 *) priv->mib[n]); +} + +/* Commits the cache. If something goes wrong, it restarts the device. Lock + * outside + */ + +static enum oid_num_t commit_part1[] = { + OID_INL_CONFIG, + OID_INL_MODE, + DOT11_OID_BSSTYPE, + DOT11_OID_CHANNEL, + DOT11_OID_MLMEAUTOLEVEL +}; + +static enum oid_num_t commit_part2[] = { + DOT11_OID_SSID, + DOT11_OID_PSMBUFFER, + DOT11_OID_AUTHENABLE, + DOT11_OID_PRIVACYINVOKED, + DOT11_OID_EXUNENCRYPTED, + DOT11_OID_DEFKEYX, /* MULTIPLE */ + DOT11_OID_DEFKEYID, + DOT11_OID_DOT1XENABLE, + OID_INL_DOT11D_CONFORMANCE, + OID_INL_OUTPUTPOWER, +}; + +void +mgt_commit(islpci_private *priv) +{ + int rvalue; + u32 u; + union oid_res_t r; + + if (islpci_get_state(priv) < PRV_STATE_INIT) + return; + + rvalue = mgt_commit_list(priv, commit_part1, + sizeof (commit_part1) / + sizeof (commit_part1[0])); + + if (priv->iw_mode != IW_MODE_MONITOR) + rvalue |= mgt_commit_list(priv, commit_part2, + sizeof (commit_part2) / + sizeof (commit_part2[0])); + + u = OID_INL_MODE; + rvalue |= mgt_commit_list(priv, &u, 1); + + if (rvalue) { + /* some request have failed. The device might be in an + incoherent state. We should reset it ! */ + printk(KERN_DEBUG "%s: mgt_commit has failed. Restart the " + "device \n", priv->ndev->name); + } + + /* update the MAC addr. As it's not cached, no lock will be acquired by + * the mgt_get_request + */ + mgt_get_request(priv, GEN_OID_MACADDRESS, 0, NULL, &r); + memcpy(priv->ndev->dev_addr, r.ptr, 6); + kfree(r.ptr); + +} + +/* This will tell you if you are allowed to answer a mlme(ex) request .*/ + +inline int +mgt_mlme_answer(islpci_private *priv) +{ + u32 mlmeautolevel; + /* Acquire a read lock because if we are in a mode change, it's + * possible to answer true, while the card is leaving master to managed + * mode. Answering to a mlme in this situation could hang the card. + */ + down_read(&priv->mib_sem); + mlmeautolevel = + le32_to_cpu(*(u32 *) priv->mib[DOT11_OID_MLMEAUTOLEVEL]); + up_read(&priv->mib_sem); + + return ((priv->iw_mode == IW_MODE_MASTER) && + (mlmeautolevel >= DOT11_MLME_INTERMEDIATE)); +} + +inline enum oid_num_t +mgt_oidtonum(u32 oid) +{ + int i; + + for (i = 0; i < OID_NUM_LAST - 1; i++) + if (isl_oid[i].oid == oid) + return i; + + printk(KERN_DEBUG "looking for an unknown oid 0x%x", oid); + + return 0; +} diff -Nru a/drivers/net/wireless/prism54/oid_mgt.h b/drivers/net/wireless/prism54/oid_mgt.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/drivers/net/wireless/prism54/oid_mgt.h Sun Mar 14 14:20:09 2004 @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2003 Aurelien Alleaume + * + * 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 + * + * 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 + * + */ + +#if !defined(_OID_MGT_H) +#define _OID_MGT_H + +#include "isl_oid.h" +#include "islpci_dev.h" + +extern struct oid_t isl_oid[]; + +int mgt_init(islpci_private *); + +void mgt_clean(islpci_private *); + +extern const int frequency_list_bg[]; + +extern const int frequency_list_a[]; + +int mgt_set_request(islpci_private *, enum oid_num_t, int, void *); + +int mgt_get_request(islpci_private *, enum oid_num_t, int, void *, + union oid_res_t *); + +int mgt_commit_list(islpci_private *, enum oid_num_t *, int); + +void mgt_set(islpci_private *, enum oid_num_t, void *); + +void mgt_commit(islpci_private *); + +int mgt_mlme_answer(islpci_private *); + +enum oid_num_t mgt_oidtonum(u32 oid); + +#endif /* !defined(_OID_MGT_H) */ +/* EOF */ diff -Nru a/drivers/net/yellowfin.c b/drivers/net/yellowfin.c --- a/drivers/net/yellowfin.c Sun Mar 14 14:20:07 2004 +++ b/drivers/net/yellowfin.c Sun Mar 14 14:20:07 2004 @@ -1124,7 +1124,7 @@ if(!desc->result_status) break; - pci_dma_sync_single(yp->pci_dev, desc->addr, + pci_dma_sync_single_for_cpu(yp->pci_dev, desc->addr, yp->rx_buf_sz, PCI_DMA_FROMDEVICE); desc_status = le32_to_cpu(desc->result_status) >> 16; buf_addr = rx_skb->tail; @@ -1208,6 +1208,9 @@ memcpy(skb_put(skb, pkt_len), rx_skb->tail, pkt_len); #endif + pci_dma_sync_single_for_device(yp->pci_dev, desc->addr, + yp->rx_buf_sz, + PCI_DMA_FROMDEVICE); } skb->protocol = eth_type_trans(skb, dev); netif_rx(skb); diff -Nru a/drivers/net/zorro8390.c b/drivers/net/zorro8390.c --- a/drivers/net/zorro8390.c Sun Mar 14 14:20:07 2004 +++ b/drivers/net/zorro8390.c Sun Mar 14 14:20:07 2004 @@ -227,6 +227,10 @@ ei_status.reg_offset = zorro8390_offsets; dev->open = &zorro8390_open; dev->stop = &zorro8390_close; +#ifdef CONFIG_NET_POLL_CONTROLLER + dev->poll_controller = ei_poll; +#endif + NS8390_init(dev, 0); err = register_netdev(dev); if (err) diff -Nru a/drivers/parisc/ccio-dma.c b/drivers/parisc/ccio-dma.c --- a/drivers/parisc/ccio-dma.c Sun Mar 14 14:20:06 2004 +++ b/drivers/parisc/ccio-dma.c Sun Mar 14 14:20:06 2004 @@ -38,9 +38,8 @@ #include #include #include -#define PCI_DEBUG #include -#undef PCI_DEBUG +#include #include #include /* for L1_CACHE_BYTES */ @@ -63,6 +62,18 @@ #undef DEBUG_CCIO_INIT #undef DEBUG_CCIO_RUN_SG +#ifdef CONFIG_PROC_FS +/* + * CCIO_SEARCH_TIME can help measure how fast the bitmap search is. + * impacts performance though - ditch it if you don't use it. + */ +#define CCIO_SEARCH_TIME +#undef CCIO_MAP_STATS +#else +#undef CCIO_SEARCH_TIME +#undef CCIO_MAP_STATS +#endif + #include #include /* for proc_runway_root */ @@ -219,15 +230,18 @@ struct ioa_registers *ioc_hpa; /* I/O MMU base address */ u8 *res_map; /* resource map, bit == pdir entry */ u64 *pdir_base; /* physical base address */ + u32 pdir_size; /* bytes, function of IOV Space size */ u32 res_hint; /* next available IOVP - circular search */ u32 res_size; /* size of resource map in bytes */ spinlock_t res_lock; -#ifdef CONFIG_PROC_FS +#ifdef CCIO_SEARCH_TIME #define CCIO_SEARCH_SAMPLE 0x100 unsigned long avg_search[CCIO_SEARCH_SAMPLE]; unsigned long avg_idx; /* current index into avg_search */ +#endif +#ifdef CCIO_MAP_STATS unsigned long used_pages; unsigned long msingle_calls; unsigned long msingle_pages; @@ -237,12 +251,10 @@ unsigned long usingle_pages; unsigned long usg_calls; unsigned long usg_pages; - - unsigned short cujo20_bug; #endif + unsigned short cujo20_bug; /* STUFF We don't need in performance path */ - u32 pdir_size; /* in bytes, determined by IOV Space size */ u32 chainid_shift; /* specify bit location of chain_id */ struct ioc *next; /* Linked list of discovered iocs */ const char *name; /* device name from firmware */ @@ -289,11 +301,11 @@ ** If the search wraps around, and passes the res_hint, it will ** cause the kernel to panic anyhow. */ -#define CCIO_SEARCH_LOOP(ioc, res_idx, mask_ptr, size) \ +#define CCIO_SEARCH_LOOP(ioc, res_idx, mask, size) \ for(; res_ptr < res_end; ++res_ptr) { \ - if(0 == (*res_ptr & *mask_ptr)) { \ - *res_ptr |= *mask_ptr; \ - res_idx = (int)((unsigned long)res_ptr - (unsigned long)ioc->res_map); \ + if(0 == (*res_ptr & mask)) { \ + *res_ptr |= mask; \ + res_idx = (unsigned int)((unsigned long)res_ptr - (unsigned long)ioc->res_map); \ ioc->res_hint = res_idx + (size >> 3); \ goto resource_found; \ } \ @@ -302,10 +314,9 @@ #define CCIO_FIND_FREE_MAPPING(ioa, res_idx, mask, size) \ u##size *res_ptr = (u##size *)&((ioc)->res_map[ioa->res_hint & ~((size >> 3) - 1)]); \ u##size *res_end = (u##size *)&(ioc)->res_map[ioa->res_size]; \ - u##size *mask_ptr = (u##size *)&mask; \ - CCIO_SEARCH_LOOP(ioc, res_idx, mask_ptr, size); \ + CCIO_SEARCH_LOOP(ioc, res_idx, mask, size); \ res_ptr = (u##size *)&(ioc)->res_map[0]; \ - CCIO_SEARCH_LOOP(ioa, res_idx, mask_ptr, size); + CCIO_SEARCH_LOOP(ioa, res_idx, mask, size); /* ** Find available bit in this ioa's resource map. @@ -331,40 +342,51 @@ * of available pages for the requested size. */ static int -ccio_alloc_range(struct ioc *ioc, unsigned long pages_needed) +ccio_alloc_range(struct ioc *ioc, size_t size) { - int res_idx; - unsigned long mask; -#ifdef CONFIG_PROC_FS + unsigned int pages_needed = size >> IOVP_SHIFT; + unsigned int res_idx; +#ifdef CCIO_SEARCH_TIME unsigned long cr_start = mfctl(16); #endif - ASSERT(pages_needed); - ASSERT((pages_needed * IOVP_SIZE) <= DMA_CHUNK_SIZE); - ASSERT(pages_needed <= BITS_PER_LONG); - - mask = ~(~0UL >> pages_needed); + BUG_ON(pages_needed == 0); + BUG_ON((pages_needed * IOVP_SIZE) > DMA_CHUNK_SIZE); - DBG_RES("%s() size: %d pages_needed %d mask 0x%08lx\n", - __FUNCTION__, size, pages_needed, mask); + DBG_RES("%s() size: %d pages_needed %d\n", + __FUNCTION__, size, pages_needed); /* ** "seek and ye shall find"...praying never hurts either... ** ggg sacrifices another 710 to the computer gods. */ - if(pages_needed <= 8) { + if (pages_needed <= 8) { + /* + * LAN traffic will not thrash the TLB IFF the same NIC + * uses 8 adjacent pages to map seperate payload data. + * ie the same byte in the resource bit map. + */ +#if 0 + /* FIXME: bit search should shift it's way through + * an unsigned long - not byte at a time. As it is now, + * we effectively allocate this byte to this mapping. + */ + unsigned long mask = ~(~0UL >> pages_needed); CCIO_FIND_FREE_MAPPING(ioc, res_idx, mask, 8); - } else if(pages_needed <= 16) { - CCIO_FIND_FREE_MAPPING(ioc, res_idx, mask, 16); - } else if(pages_needed <= 32) { - CCIO_FIND_FREE_MAPPING(ioc, res_idx, mask, 32); +#else + CCIO_FIND_FREE_MAPPING(ioc, res_idx, 0xff, 8); +#endif + } else if (pages_needed <= 16) { + CCIO_FIND_FREE_MAPPING(ioc, res_idx, 0xffff, 16); + } else if (pages_needed <= 32) { + CCIO_FIND_FREE_MAPPING(ioc, res_idx, ~(unsigned int)0, 32); #ifdef __LP64__ - } else if(pages_needed <= 64) { - CCIO_FIND_FREE_MAPPING(ioc, res_idx, mask, 64); + } else if (pages_needed <= 64) { + CCIO_FIND_FREE_MAPPING(ioc, res_idx, ~0UL, 64); #endif } else { - panic("%s: %s() Too many pages to map. pages_needed: %ld\n", + panic("%s: %s() Too many pages to map. pages_needed: %u\n", __FILE__, __FUNCTION__, pages_needed); } @@ -373,10 +395,10 @@ resource_found: - DBG_RES("%s() res_idx %d mask 0x%08lx res_hint: %d\n", - __FUNCTION__, res_idx, mask, ioc->res_hint); + DBG_RES("%s() res_idx %d res_hint: %d\n", + __FUNCTION__, res_idx, ioc->res_hint); -#ifdef CONFIG_PROC_FS +#ifdef CCIO_SEARCH_TIME { unsigned long cr_end = mfctl(16); unsigned long tmp = cr_end - cr_start; @@ -385,10 +407,10 @@ } ioc->avg_search[ioc->avg_idx++] = cr_start; ioc->avg_idx &= CCIO_SEARCH_SAMPLE - 1; - +#endif +#ifdef CCIO_MAP_STATS ioc->used_pages += pages_needed; #endif - /* ** return the bit address. */ @@ -397,9 +419,8 @@ #define CCIO_FREE_MAPPINGS(ioc, res_idx, mask, size) \ u##size *res_ptr = (u##size *)&((ioc)->res_map[res_idx]); \ - u##size *mask_ptr = (u##size *)&mask; \ - ASSERT((*res_ptr & *mask_ptr) == *mask_ptr); \ - *res_ptr &= ~(*mask_ptr); + BUG_ON((*res_ptr & mask) != mask); \ + *res_ptr &= ~(mask); /** * ccio_free_range - Free pages from the ioc's resource map. @@ -413,32 +434,35 @@ static void ccio_free_range(struct ioc *ioc, dma_addr_t iova, unsigned long pages_mapped) { - unsigned long mask; unsigned long iovp = CCIO_IOVP(iova); unsigned int res_idx = PDIR_INDEX(iovp) >> 3; - ASSERT(pages_mapped); - ASSERT((pages_mapped * IOVP_SIZE) <= DMA_CHUNK_SIZE); - ASSERT(pages_mapped <= BITS_PER_LONG); + BUG_ON(pages_mapped == 0); + BUG_ON((pages_mapped * IOVP_SIZE) > DMA_CHUNK_SIZE); + BUG_ON(pages_mapped > BITS_PER_LONG); - mask = ~(~0UL >> pages_mapped); + DBG_RES("%s(): res_idx: %d pages_mapped %d\n", + __FUNCTION__, res_idx, pages_mapped); - DBG_RES("%s(): res_idx: %d pages_mapped %d mask 0x%08lx\n", - __FUNCTION__, res_idx, pages_mapped, mask); - -#ifdef CONFIG_PROC_FS +#ifdef CCIO_MAP_STATS ioc->used_pages -= pages_mapped; #endif if(pages_mapped <= 8) { +#if 0 + /* see matching comments in alloc_range */ + unsigned long mask = ~(~0UL >> pages_mapped); CCIO_FREE_MAPPINGS(ioc, res_idx, mask, 8); +#else + CCIO_FREE_MAPPINGS(ioc, res_idx, 0xff, 8); +#endif } else if(pages_mapped <= 16) { - CCIO_FREE_MAPPINGS(ioc, res_idx, mask, 16); + CCIO_FREE_MAPPINGS(ioc, res_idx, 0xffff, 16); } else if(pages_mapped <= 32) { - CCIO_FREE_MAPPINGS(ioc, res_idx, mask, 32); + CCIO_FREE_MAPPINGS(ioc, res_idx, ~(unsigned int)0, 32); #ifdef __LP64__ } else if(pages_mapped <= 64) { - CCIO_FREE_MAPPINGS(ioc, res_idx, mask, 64); + CCIO_FREE_MAPPINGS(ioc, res_idx, ~0UL, 64); #endif } else { panic("%s:%s() Too many pages to unmap.\n", __FILE__, @@ -533,13 +557,14 @@ * index are bits 12:19 of the value returned by LCI. */ void CCIO_INLINE -ccio_io_pdir_entry(u64 *pdir_ptr, space_t sid, void * vba, unsigned long hints) +ccio_io_pdir_entry(u64 *pdir_ptr, space_t sid, unsigned long vba, + unsigned long hints) { register unsigned long pa = (volatile unsigned long) vba; register unsigned long ci; /* coherent index */ /* We currently only support kernel addresses */ - ASSERT(sid == KERNEL_SPACE); + BUG_ON(sid != KERNEL_SPACE); mtsp(sid,1); @@ -652,7 +677,7 @@ unsigned int idx = PDIR_INDEX(iovp); char *pdir_ptr = (char *) &(ioc->pdir_base[idx]); - ASSERT(idx < (ioc->pdir_size / sizeof(u64))); + BUG_ON(idx >= (ioc->pdir_size / sizeof(u64))); pdir_ptr[7] = 0; /* clear only VALID bit */ /* ** FIXME: PCX_W platforms don't need FDC/SYNC. (eg C360) @@ -722,7 +747,7 @@ BUG_ON(!dev); ioc = GET_IOC(dev); - ASSERT(size > 0); + BUG_ON(size <= 0); /* save offset bits */ offset = ((unsigned long) addr) & ~IOVP_MASK; @@ -731,12 +756,12 @@ size = ROUNDUP(size + offset, IOVP_SIZE); spin_lock_irqsave(&ioc->res_lock, flags); -#ifdef CONFIG_PROC_FS +#ifdef CCIO_MAP_STATS ioc->msingle_calls++; ioc->msingle_pages += size >> IOVP_SHIFT; #endif - idx = ccio_alloc_range(ioc, (size >> IOVP_SHIFT)); + idx = ccio_alloc_range(ioc, size); iovp = (dma_addr_t)MKIOVP(idx); pdir_start = &(ioc->pdir_base[idx]); @@ -749,7 +774,7 @@ hint |= HINT_SAFE_DMA; while(size > 0) { - ccio_io_pdir_entry(pdir_start, KERNEL_SPACE, addr, hint); + ccio_io_pdir_entry(pdir_start, KERNEL_SPACE, (unsigned long)addr, hint); DBG_RUN(" pdir %p %08x%08x\n", pdir_start, @@ -795,7 +820,7 @@ spin_lock_irqsave(&ioc->res_lock, flags); -#ifdef CONFIG_PROC_FS +#ifdef CCIO_MAP_STATS ioc->usingle_calls++; ioc->usingle_pages += size >> IOVP_SHIFT; #endif @@ -861,180 +886,10 @@ */ #define PIDE_FLAG 0x80000000UL -/** - * ccio_fill_pdir - Insert coalesced scatter/gather chunks into the I/O Pdir. - * @ioc: The I/O Controller. - * @startsg: The scatter/gather list of coalesced chunks. - * @nents: The number of entries in the scatter/gather list. - * @hint: The DMA Hint. - * - * This function inserts the coalesced scatter/gather list chunks into the - * I/O Controller's I/O Pdir. - */ -static CCIO_INLINE int -ccio_fill_pdir(struct ioc *ioc, struct scatterlist *startsg, int nents, - unsigned long hint) -{ - struct scatterlist *dma_sg = startsg; /* pointer to current DMA */ - int n_mappings = 0; - u64 *pdirp = 0; - unsigned long dma_offset = 0; - - dma_sg--; - while (nents-- > 0) { - int cnt = sg_dma_len(startsg); - sg_dma_len(startsg) = 0; - - DBG_RUN_SG(" %d : %08lx/%05x %08lx/%05x\n", nents, - (unsigned long)sg_dma_address(startsg), cnt, - sg_virt_addr(startsg), startsg->length - ); - - /* - ** Look for the start of a new DMA stream - */ - if(sg_dma_address(startsg) & PIDE_FLAG) { - u32 pide = sg_dma_address(startsg) & ~PIDE_FLAG; - dma_offset = (unsigned long) pide & ~IOVP_MASK; - sg_dma_address(startsg) = 0; - dma_sg++; - sg_dma_address(dma_sg) = pide; - pdirp = &(ioc->pdir_base[pide >> IOVP_SHIFT]); - n_mappings++; - } - - /* - ** Look for a VCONTIG chunk - */ - if (cnt) { - unsigned long vaddr = sg_virt_addr(startsg); - ASSERT(pdirp); - - /* Since multiple Vcontig blocks could make up - ** one DMA stream, *add* cnt to dma_len. - */ - sg_dma_len(dma_sg) += cnt; - cnt += dma_offset; - dma_offset=0; /* only want offset on first chunk */ - cnt = ROUNDUP(cnt, IOVP_SIZE); -#ifdef CONFIG_PROC_FS - ioc->msg_pages += cnt >> IOVP_SHIFT; +#ifdef CCIO_MAP_STATS +#define IOMMU_MAP_STATS #endif - do { - ccio_io_pdir_entry(pdirp, KERNEL_SPACE, - (void *)vaddr, hint); - vaddr += IOVP_SIZE; - cnt -= IOVP_SIZE; - pdirp++; - } while (cnt > 0); - } - startsg++; - } - return(n_mappings); -} - -/* -** First pass is to walk the SG list and determine where the breaks are -** in the DMA stream. Allocates PDIR entries but does not fill them. -** Returns the number of DMA chunks. -** -** Doing the fill separate from the coalescing/allocation keeps the -** code simpler. Future enhancement could make one pass through -** the sglist do both. -*/ - -static CCIO_INLINE int -ccio_coalesce_chunks(struct ioc *ioc, struct scatterlist *startsg, int nents) -{ - struct scatterlist *vcontig_sg; /* VCONTIG chunk head */ - unsigned long vcontig_len; /* len of VCONTIG chunk */ - unsigned long vcontig_end; - struct scatterlist *dma_sg; /* next DMA stream head */ - unsigned long dma_offset, dma_len; /* start/len of DMA stream */ - int n_mappings = 0; - - while (nents > 0) { - - /* - ** Prepare for first/next DMA stream - */ - dma_sg = vcontig_sg = startsg; - dma_len = vcontig_len = vcontig_end = startsg->length; - vcontig_end += sg_virt_addr(startsg); - dma_offset = sg_virt_addr(startsg) & ~IOVP_MASK; - - /* PARANOID: clear entries */ - sg_dma_address(startsg) = 0; - sg_dma_len(startsg) = 0; - - /* - ** This loop terminates one iteration "early" since - ** it's always looking one "ahead". - */ - while(--nents > 0) { - unsigned long startsg_end; - - startsg++; - startsg_end = sg_virt_addr(startsg) + - startsg->length; - - /* PARANOID: clear entries */ - sg_dma_address(startsg) = 0; - sg_dma_len(startsg) = 0; - - /* - ** First make sure current dma stream won't - ** exceed DMA_CHUNK_SIZE if we coalesce the - ** next entry. - */ - if(ROUNDUP(dma_len + dma_offset + startsg->length, - IOVP_SIZE) > DMA_CHUNK_SIZE) - break; - - /* - ** Append the next transaction? - */ - if (vcontig_end == sg_virt_addr(startsg)) { - vcontig_len += startsg->length; - vcontig_end += startsg->length; - dma_len += startsg->length; - continue; - } - - /* - ** Not virtually contigous. - ** Terminate prev chunk. - ** Start a new chunk. - ** - ** Once we start a new VCONTIG chunk, dma_offset - ** can't change. And we need the offset from the first - ** chunk - not the last one. Ergo Successive chunks - ** must start on page boundaries and dove tail - ** with its predecessor. - */ - sg_dma_len(vcontig_sg) = vcontig_len; - - vcontig_sg = startsg; - vcontig_len = startsg->length; - break; - } - - /* - ** End of DMA Stream - ** Terminate last VCONTIG block. - ** Allocate space for DMA stream. - */ - sg_dma_len(vcontig_sg) = vcontig_len; - dma_len = ROUNDUP(dma_len + dma_offset, IOVP_SIZE); - sg_dma_address(dma_sg) = - PIDE_FLAG - | (ccio_alloc_range(ioc, (dma_len >> IOVP_SHIFT)) << IOVP_SHIFT) - | dma_offset; - n_mappings++; - } - - return n_mappings; -} +#include "iommu-helpers.h" /** * ccio_map_sg - Map the scatter/gather list into the IOMMU. @@ -1053,6 +908,8 @@ int coalesced, filled = 0; unsigned long flags; unsigned long hint = hint_lookup[(int)direction]; + unsigned long prev_len = 0, current_len = 0; + int i; BUG_ON(!dev); ioc = GET_IOC(dev); @@ -1067,10 +924,13 @@ sg_dma_len(sglist) = sglist->length; return 1; } + + for(i = 0; i < nents; i++) + prev_len += sglist[i].length; spin_lock_irqsave(&ioc->res_lock, flags); -#ifdef CONFIG_PROC_FS +#ifdef CCIO_MAP_STATS ioc->msg_calls++; #endif @@ -1082,7 +942,7 @@ ** w/o this association, we wouldn't have coherent DMA! ** Access to the virtual address is what forces a two pass algorithm. */ - coalesced = ccio_coalesce_chunks(ioc, sglist, nents); + coalesced = iommu_coalesce_chunks(ioc, sglist, nents, ccio_alloc_range); /* ** Program the I/O Pdir @@ -1092,13 +952,19 @@ ** o dma_len will contain the number of bytes to map ** o page/offset contain the virtual address. */ - filled = ccio_fill_pdir(ioc, sglist, nents, hint); + filled = iommu_fill_pdir(ioc, sglist, nents, hint, ccio_io_pdir_entry); spin_unlock_irqrestore(&ioc->res_lock, flags); - ASSERT(coalesced == filled); + BUG_ON(coalesced != filled); + DBG_RUN_SG("%s() DONE %d mappings\n", __FUNCTION__, filled); + for (i = 0; i < filled; i++) + current_len += sg_dma_len(sglist + i); + + BUG_ON(current_len != prev_len); + return filled; } @@ -1123,13 +989,13 @@ DBG_RUN_SG("%s() START %d entries, %08lx,%x\n", __FUNCTION__, nents, sg_virt_addr(sglist), sglist->length); -#ifdef CONFIG_PROC_FS +#ifdef CCIO_MAP_STATS ioc->usg_calls++; #endif while(sg_dma_len(sglist) && nents--) { -#ifdef CONFIG_PROC_FS +#ifdef CCIO_MAP_STATS ioc->usg_pages += sg_dma_len(sglist) >> PAGE_SHIFT; #endif ccio_unmap_single(dev, sg_dma_address(sglist), @@ -1149,8 +1015,10 @@ .unmap_single = ccio_unmap_single, .map_sg = ccio_map_sg, .unmap_sg = ccio_unmap_sg, - .dma_sync_single = NULL, /* NOP for U2/Uturn */ - .dma_sync_sg = NULL, /* ditto */ + .dma_sync_single_for_cpu = NULL, /* NOP for U2/Uturn */ + .dma_sync_single_for_device = NULL, /* NOP for U2/Uturn */ + .dma_sync_sg_for_cpu = NULL, /* ditto */ + .dma_sync_sg_for_device = NULL, /* ditto */ }; #ifdef CONFIG_PROC_FS @@ -1199,18 +1067,18 @@ total_pages * 8, total_pages); if (proc_append(tmp, len, &buf, &offset, &count)) break; - +#ifdef CCIO_MAP_STATS len = sprintf(tmp, "IO PDIR entries : %ld free %ld used (%d%%)\n", total_pages - ioc->used_pages, ioc->used_pages, (int)(ioc->used_pages * 100 / total_pages)); if (proc_append(tmp, len, &buf, &offset, &count)) break; - +#endif len = sprintf(tmp, "Resource bitmap : %d bytes (%d pages)\n", ioc->res_size, total_pages); if (proc_append(tmp, len, &buf, &offset, &count)) break; - +#ifdef CCIO_SEARCH_TIME min = max = ioc->avg_search[0]; for(j = 0; j < CCIO_SEARCH_SAMPLE; ++j) { avg += ioc->avg_search[j]; @@ -1224,7 +1092,8 @@ min, avg, max); if (proc_append(tmp, len, &buf, &offset, &count)) break; - +#endif +#ifdef CCIO_MAP_STATS len = sprintf(tmp, "pci_map_single(): %8ld calls %8ld pages (avg %d/1000)\n", ioc->msingle_calls, ioc->msingle_pages, (int)((ioc->msingle_pages * 1000)/ioc->msingle_calls)); @@ -1250,7 +1119,7 @@ (int)((ioc->usg_pages * 1000)/ioc->usg_calls)); if (proc_append(tmp, len, &buf, &offset, &count)) break; - +#endif /* CCIO_MAP_STATS */ ioc = ioc->next; } @@ -1336,9 +1205,7 @@ struct ioc *ioc = ccio_get_iommu(dev); u8 *res_ptr; -#ifdef CONFIG_PROC_FS ioc->cujo20_bug = 1; -#endif res_ptr = ioc->res_map; idx = PDIR_INDEX(iovp) >> 3; @@ -1429,16 +1296,16 @@ */ iov_order = get_order(iova_space_size) >> (IOVP_SHIFT - PAGE_SHIFT); - ASSERT(iov_order <= (30 - IOVP_SHIFT)); /* iova_space_size <= 1GB */ - ASSERT(iov_order >= (20 - IOVP_SHIFT)); /* iova_space_size >= 1MB */ + BUG_ON(iov_order > (30 - IOVP_SHIFT)); /* iova_space_size <= 1GB */ + BUG_ON(iov_order < (20 - IOVP_SHIFT)); /* iova_space_size >= 1MB */ iova_space_size = 1 << (iov_order + IOVP_SHIFT); ioc->pdir_size = (iova_space_size / IOVP_SIZE) * sizeof(u64); - ASSERT(ioc->pdir_size < 4 * 1024 * 1024); /* max pdir size < 4MB */ + BUG_ON(ioc->pdir_size >= 4 * 1024 * 1024); /* max pdir size < 4MB */ /* Verify it's a power of two */ - ASSERT((1 << get_order(ioc->pdir_size)) == (ioc->pdir_size >> PAGE_SHIFT)); + BUG_ON((1 << get_order(ioc->pdir_size)) != (ioc->pdir_size >> PAGE_SHIFT)); DBG_INIT("%s() hpa 0x%p mem %luMB IOV %dMB (%d bits) PDIR size 0x%0x", __FUNCTION__, ioc->ioc_hpa, physmem>>20, iova_space_size>>20, @@ -1452,7 +1319,7 @@ } memset(ioc->pdir_base, 0, ioc->pdir_size); - ASSERT((((unsigned long)ioc->pdir_base) & PAGE_MASK) == (unsigned long)ioc->pdir_base); + BUG_ON((((unsigned long)ioc->pdir_base) & PAGE_MASK) != (unsigned long)ioc->pdir_base); DBG_INIT(" base %p", ioc->pdir_base); /* resource map size dictated by pdir_size */ @@ -1684,13 +1551,14 @@ if (ioc_count == 0) { - /* XXX: Create separate entries for each ioc */ + /* FIXME: Create separate entries for each ioc */ create_proc_read_entry(MODULE_NAME, S_IRWXU, proc_runway_root, ccio_proc_info, NULL); create_proc_read_entry(MODULE_NAME"-bitmap", S_IRWXU, proc_runway_root, ccio_resource_map, NULL); } - + parisc_vmerge_boundary = IOVP_SIZE; + parisc_vmerge_max_size = BITS_PER_LONG * IOVP_SIZE; ioc_count++; return 0; } diff -Nru a/drivers/parisc/ccio-rm-dma.c b/drivers/parisc/ccio-rm-dma.c --- a/drivers/parisc/ccio-rm-dma.c Sun Mar 14 14:20:06 2004 +++ b/drivers/parisc/ccio-rm-dma.c Sun Mar 14 14:20:06 2004 @@ -151,8 +151,10 @@ ccio_unmap_single, ccio_map_sg, ccio_unmap_sg, - NULL, /* dma_sync_single : NOP for U2 */ - NULL, /* dma_sync_sg : ditto */ + NULL, /* dma_sync_single_for_cpu : NOP for U2 */ + NULL, /* dma_sync_single_for_device : NOP for U2 */ + NULL, /* dma_sync_sg_for_cpu : ditto */ + NULL, /* dma_sync_sg_for_device : ditto */ }; diff -Nru a/drivers/parisc/eisa.c b/drivers/parisc/eisa.c --- a/drivers/parisc/eisa.c Sun Mar 14 14:20:05 2004 +++ b/drivers/parisc/eisa.c Sun Mar 14 14:20:05 2004 @@ -116,6 +116,16 @@ gsc_writel(cpu_to_le32(data), eisa_permute(port)); } +#ifndef CONFIG_PCI +/* We call these directly without PCI. See asm/io.h. */ +EXPORT_SYMBOL(eisa_in8); +EXPORT_SYMBOL(eisa_in16); +EXPORT_SYMBOL(eisa_in32); +EXPORT_SYMBOL(eisa_out8); +EXPORT_SYMBOL(eisa_out16); +EXPORT_SYMBOL(eisa_out32); +#endif + /* Interrupt handling */ /* cached interrupt mask registers */ diff -Nru a/drivers/parisc/gsc.c b/drivers/parisc/gsc.c --- a/drivers/parisc/gsc.c Sun Mar 14 14:20:08 2004 +++ b/drivers/parisc/gsc.c Sun Mar 14 14:20:08 2004 @@ -29,6 +29,11 @@ #include "gsc.h" +/* This sets the vmerge boundary and size, it's here because it has to + * be available on all platforms (zero means no-virtual merging) */ +unsigned long parisc_vmerge_boundary = 0; +unsigned long parisc_vmerge_max_size = 0; + #undef DEBUG #ifdef DEBUG diff -Nru a/drivers/parisc/iommu-helpers.h b/drivers/parisc/iommu-helpers.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/drivers/parisc/iommu-helpers.h Sun Mar 14 14:20:09 2004 @@ -0,0 +1,163 @@ +/** + * iommu_fill_pdir - Insert coalesced scatter/gather chunks into the I/O Pdir. + * @ioc: The I/O Controller. + * @startsg: The scatter/gather list of coalesced chunks. + * @nents: The number of entries in the scatter/gather list. + * @hint: The DMA Hint. + * + * This function inserts the coalesced scatter/gather list chunks into the + * I/O Controller's I/O Pdir. + */ +static inline unsigned int +iommu_fill_pdir(struct ioc *ioc, struct scatterlist *startsg, int nents, + unsigned long hint, + void (*iommu_io_pdir_entry)(u64 *, space_t, unsigned long, + unsigned long)) +{ + struct scatterlist *dma_sg = startsg; /* pointer to current DMA */ + unsigned int n_mappings = 0; + unsigned long dma_offset = 0, dma_len = 0; + u64 *pdirp = NULL; + + /* Horrible hack. For efficiency's sake, dma_sg starts one + * entry below the true start (it is immediately incremented + * in the loop) */ + dma_sg--; + + while (nents-- > 0) { + unsigned long vaddr; + long size; + + DBG_RUN_SG(" %d : %08lx/%05x %08lx/%05x\n", nents, + (unsigned long)sg_dma_address(startsg), cnt, + sg_virt_addr(startsg), startsg->length + ); + + + /* + ** Look for the start of a new DMA stream + */ + + if (sg_dma_address(startsg) & PIDE_FLAG) { + u32 pide = sg_dma_address(startsg) & ~PIDE_FLAG; + + BUG_ON(pdirp && (dma_len != sg_dma_len(dma_sg))); + + dma_sg++; + + dma_len = sg_dma_len(startsg); + sg_dma_len(startsg) = 0; + dma_offset = (unsigned long) pide & ~IOVP_MASK; + n_mappings++; + sg_dma_address(dma_sg) = pide; + pdirp = &(ioc->pdir_base[pide >> IOVP_SHIFT]); + prefetchw(pdirp); + } + + BUG_ON(pdirp == NULL); + + vaddr = sg_virt_addr(startsg); + sg_dma_len(dma_sg) += startsg->length; + size = startsg->length + dma_offset; + dma_offset = 0; +#ifdef IOMMU_MAP_STATS + ioc->msg_pages += startsg->length >> IOVP_SHIFT; +#endif + do { + iommu_io_pdir_entry(pdirp, KERNEL_SPACE, + vaddr, hint); + vaddr += IOVP_SIZE; + size -= IOVP_SIZE; + pdirp++; + } while(unlikely(size > 0)); + startsg++; + } + return(n_mappings); +} + + +/* +** First pass is to walk the SG list and determine where the breaks are +** in the DMA stream. Allocates PDIR entries but does not fill them. +** Returns the number of DMA chunks. +** +** Doing the fill separate from the coalescing/allocation keeps the +** code simpler. Future enhancement could make one pass through +** the sglist do both. +*/ + +static inline unsigned int +iommu_coalesce_chunks(struct ioc *ioc, struct scatterlist *startsg, int nents, + int (*iommu_alloc_range)(struct ioc *, size_t)) +{ + struct scatterlist *contig_sg; /* contig chunk head */ + unsigned long dma_offset, dma_len; /* start/len of DMA stream */ + unsigned int n_mappings = 0; + + while (nents > 0) { + + /* + ** Prepare for first/next DMA stream + */ + contig_sg = startsg; + dma_len = startsg->length; + dma_offset = sg_virt_addr(startsg) & ~IOVP_MASK; + + /* PARANOID: clear entries */ + sg_dma_address(startsg) = 0; + sg_dma_len(startsg) = 0; + + /* + ** This loop terminates one iteration "early" since + ** it's always looking one "ahead". + */ + while(--nents > 0) { + unsigned long prevstartsg_end, startsg_end; + + prevstartsg_end = sg_virt_addr(startsg) + + startsg->length; + + startsg++; + startsg_end = sg_virt_addr(startsg) + + startsg->length; + + /* PARANOID: clear entries */ + sg_dma_address(startsg) = 0; + sg_dma_len(startsg) = 0; + + /* + ** First make sure current dma stream won't + ** exceed DMA_CHUNK_SIZE if we coalesce the + ** next entry. + */ + if(unlikely(ROUNDUP(dma_len + dma_offset + startsg->length, + IOVP_SIZE) > DMA_CHUNK_SIZE)) + break; + + /* + ** Next see if we can append the next chunk (i.e. + ** it must end on one page and begin on another + */ + if (unlikely(((prevstartsg_end | sg_virt_addr(startsg)) & ~PAGE_MASK) != 0)) + break; + + dma_len += startsg->length; + } + + /* + ** End of DMA Stream + ** Terminate last VCONTIG block. + ** Allocate space for DMA stream. + */ + sg_dma_len(contig_sg) = dma_len; + dma_len = ROUNDUP(dma_len + dma_offset, IOVP_SIZE); + sg_dma_address(contig_sg) = + PIDE_FLAG + | (iommu_alloc_range(ioc, dma_len) << IOVP_SHIFT) + | dma_offset; + n_mappings++; + } + + return n_mappings; +} + diff -Nru a/drivers/parisc/lba_pci.c b/drivers/parisc/lba_pci.c --- a/drivers/parisc/lba_pci.c Sun Mar 14 14:20:07 2004 +++ b/drivers/parisc/lba_pci.c Sun Mar 14 14:20:07 2004 @@ -533,10 +533,10 @@ */ LBA_CFG_TR4_ADDR_SETUP(d, tok | pos); switch(size) { - case 1: *(u8 *) data = READ_REG8(d->hba.base_addr + LBA_PCI_CFG_DATA); - break; - case 2: *(u16 *) data = READ_REG16(d->hba.base_addr + LBA_PCI_CFG_DATA); - break; + case 1: *(u8 *) data = READ_REG8(d->hba.base_addr + LBA_PCI_CFG_DATA + (pos & 3)); + break; + case 2: *(u16 *) data = READ_REG16(d->hba.base_addr + LBA_PCI_CFG_DATA + (pos & 2)); + break; case 4: *(u32 *) data = READ_REG32(d->hba.base_addr + LBA_PCI_CFG_DATA); break; } @@ -613,13 +613,14 @@ /* Basic Algorithm */ LBA_CFG_TR4_ADDR_SETUP(d, tok | pos); switch(size) { - case 1: WRITE_REG8 (data, d->hba.base_addr + LBA_PCI_CFG_DATA); + case 1: WRITE_REG8 (data, d->hba.base_addr + LBA_PCI_CFG_DATA + (pos & 3)); break; - case 2: WRITE_REG16(data, d->hba.base_addr + LBA_PCI_CFG_DATA); + case 2: WRITE_REG16(data, d->hba.base_addr + LBA_PCI_CFG_DATA + (pos & 2)); break; case 4: WRITE_REG32(data, d->hba.base_addr + LBA_PCI_CFG_DATA); break; } + /* flush posted write */ lba_t32 = READ_REG32(d->hba.base_addr + LBA_PCI_CFG_ADDR); return 0; } diff -Nru a/drivers/parisc/sba_iommu.c b/drivers/parisc/sba_iommu.c --- a/drivers/parisc/sba_iommu.c Sun Mar 14 14:20:08 2004 +++ b/drivers/parisc/sba_iommu.c Sun Mar 14 14:20:08 2004 @@ -700,7 +700,8 @@ void SBA_INLINE -sba_io_pdir_entry(u64 *pdir_ptr, space_t sid, unsigned long vba) +sba_io_pdir_entry(u64 *pdir_ptr, space_t sid, unsigned long vba, + unsigned long hint) { u64 pa; /* physical address */ register unsigned ci; /* coherent index */ @@ -874,7 +875,7 @@ while (size > 0) { ASSERT(((u8 *)pdir_start)[7] == 0); /* verify availability */ - sba_io_pdir_entry(pdir_start, KERNEL_SPACE, (unsigned long) addr); + sba_io_pdir_entry(pdir_start, KERNEL_SPACE, (unsigned long) addr, 0); DBG_RUN(" pdir 0x%p %02x%02x%02x%02x%02x%02x%02x%02x\n", pdir_start, @@ -1027,243 +1028,15 @@ */ #define PIDE_FLAG 0x80000000UL -#ifdef DEBUG_LARGE_SG_ENTRIES -int dump_run_sg = 0; -#endif - - -/** - * sba_fill_pdir - write allocated SG entries into IO PDIR - * @ioc: IO MMU structure which owns the pdir we are interested in. - * @startsg: list of IOVA/size pairs - * @nents: number of entries in startsg list - * - * Take preprocessed SG list and write corresponding entries - * in the IO PDIR. - */ - -static SBA_INLINE int -sba_fill_pdir( - struct ioc *ioc, - struct scatterlist *startsg, - int nents) -{ - struct scatterlist *dma_sg = startsg; /* pointer to current DMA */ - int n_mappings = 0; - u64 *pdirp = 0; - unsigned long dma_offset = 0; - - dma_sg--; - while (nents-- > 0) { - int cnt = sg_dma_len(startsg); - sg_dma_len(startsg) = 0; - -#ifdef DEBUG_LARGE_SG_ENTRIES - if (dump_run_sg) - printk(KERN_DEBUG " %2d : %08lx/%05x %p/%05x\n", - nents, - (unsigned long) sg_dma_address(startsg), cnt, - sg_virt_addr(startsg), startsg->length - ); -#else - DBG_RUN_SG(" %d : %08lx/%05x %p/%05x\n", - nents, - (unsigned long) sg_dma_address(startsg), cnt, - sg_virt_addr(startsg), startsg->length - ); -#endif - /* - ** Look for the start of a new DMA stream - */ - if (sg_dma_address(startsg) & PIDE_FLAG) { - u32 pide = sg_dma_address(startsg) & ~PIDE_FLAG; - dma_offset = (unsigned long) pide & ~IOVP_MASK; - sg_dma_address(startsg) = 0; - dma_sg++; - sg_dma_address(dma_sg) = pide; - pdirp = &(ioc->pdir_base[pide >> IOVP_SHIFT]); - n_mappings++; - } - - /* - ** Look for a VCONTIG chunk - */ - if (cnt) { - unsigned long vaddr = (unsigned long) sg_virt_addr(startsg); - ASSERT(pdirp); - - /* Since multiple Vcontig blocks could make up - ** one DMA stream, *add* cnt to dma_len. - */ - sg_dma_len(dma_sg) += cnt; - cnt += dma_offset; - dma_offset=0; /* only want offset on first chunk */ - cnt = ROUNDUP(cnt, IOVP_SIZE); #ifdef SBA_COLLECT_STATS - ioc->msg_pages += cnt >> IOVP_SHIFT; -#endif - do { - sba_io_pdir_entry(pdirp, KERNEL_SPACE, vaddr); - vaddr += IOVP_SIZE; - cnt -= IOVP_SIZE; - pdirp++; - } while (cnt > 0); - } - startsg++; - } -#ifdef DEBUG_LARGE_SG_ENTRIES - dump_run_sg = 0; +#define IOMMU_MAP_STATS #endif - return(n_mappings); -} - - -/* -** Two address ranges are DMA contiguous *iff* "end of prev" and -** "start of next" are both on a page boundary. -** -** (shift left is a quick trick to mask off upper bits) -*/ -#define DMA_CONTIG(__X, __Y) \ - (((((unsigned long) __X) | ((unsigned long) __Y)) << (BITS_PER_LONG - PAGE_SHIFT)) == 0UL) - - -/** - * sba_coalesce_chunks - preprocess the SG list - * @ioc: IO MMU structure which owns the pdir we are interested in. - * @startsg: list of IOVA/size pairs - * @nents: number of entries in startsg list - * - * First pass is to walk the SG list and determine where the breaks are - * in the DMA stream. Allocates PDIR entries but does not fill them. - * Returns the number of DMA chunks. - * - * Doing the fill separate from the coalescing/allocation keeps the - * code simpler. Future enhancement could make one pass through - * the sglist do both. - */ -static SBA_INLINE int -sba_coalesce_chunks( struct ioc *ioc, - struct scatterlist *startsg, - int nents) -{ - struct scatterlist *vcontig_sg; /* VCONTIG chunk head */ - unsigned long vcontig_len; /* len of VCONTIG chunk */ - unsigned long vcontig_end; - struct scatterlist *dma_sg; /* next DMA stream head */ - unsigned long dma_offset, dma_len; /* start/len of DMA stream */ - int n_mappings = 0; - - while (nents > 0) { - unsigned long vaddr = (unsigned long) sg_virt_addr(startsg); - - /* - ** Prepare for first/next DMA stream - */ - dma_sg = vcontig_sg = startsg; - dma_len = vcontig_len = vcontig_end = startsg->length; - vcontig_end += vaddr; - dma_offset = vaddr & ~IOVP_MASK; - - /* PARANOID: clear entries */ - sg_dma_address(startsg) = 0; - sg_dma_len(startsg) = 0; - - /* - ** This loop terminates one iteration "early" since - ** it's always looking one "ahead". - */ - while (--nents > 0) { - unsigned long vaddr; /* tmp */ - - startsg++; - - /* PARANOID: clear entries */ - sg_dma_address(startsg) = 0; - sg_dma_len(startsg) = 0; - - /* catch brokenness in SCSI layer */ - ASSERT(startsg->length <= DMA_CHUNK_SIZE); - - /* - ** First make sure current dma stream won't - ** exceed DMA_CHUNK_SIZE if we coalesce the - ** next entry. - */ - if (((dma_len + dma_offset + startsg->length + ~IOVP_MASK) & IOVP_MASK) > DMA_CHUNK_SIZE) - break; - - /* - ** Then look for virtually contiguous blocks. - ** PARISC needs to associate a virtual address - ** with each IO address mapped. The CPU cache is - ** virtually tagged and the IOMMU uses part - ** of the virtual address to participate in - ** CPU cache coherency. - ** - ** append the next transaction? - */ - vaddr = (unsigned long) sg_virt_addr(startsg); - if (vcontig_end == vaddr) - { - vcontig_len += startsg->length; - vcontig_end += startsg->length; - dma_len += startsg->length; - continue; - } +#include "iommu-helpers.h" #ifdef DEBUG_LARGE_SG_ENTRIES - dump_run_sg = (vcontig_len > IOVP_SIZE); +int dump_run_sg = 0; #endif - /* - ** Not virtually contigous. - ** Terminate prev chunk. - ** Start a new chunk. - ** - ** Once we start a new VCONTIG chunk, dma_offset - ** can't change. And we need the offset from the first - ** chunk - not the last one. Ergo Successive chunks - ** must start on page boundaries and dove tail - ** with its predecessor. - */ - sg_dma_len(vcontig_sg) = vcontig_len; - - vcontig_sg = startsg; - vcontig_len = startsg->length; - - /* - ** 3) do the entries end/start on page boundaries? - ** Don't update vcontig_end until we've checked. - */ - if (DMA_CONTIG(vcontig_end, vaddr)) - { - vcontig_end = vcontig_len + vaddr; - dma_len += vcontig_len; - continue; - } else { - break; - } - } - - /* - ** End of DMA Stream - ** Terminate last VCONTIG block. - ** Allocate space for DMA stream. - */ - sg_dma_len(vcontig_sg) = vcontig_len; - dma_len = (dma_len + dma_offset + ~IOVP_MASK) & IOVP_MASK; - ASSERT(dma_len <= DMA_CHUNK_SIZE); - sg_dma_address(dma_sg) = - PIDE_FLAG - | (sba_alloc_range(ioc, dma_len) << IOVP_SHIFT) - | dma_offset; - n_mappings++; - } - - return n_mappings; -} - /** * sba_map_sg - map Scatter/Gather list @@ -1318,7 +1091,7 @@ ** w/o this association, we wouldn't have coherent DMA! ** Access to the virtual address is what forces a two pass algorithm. */ - coalesced = sba_coalesce_chunks(ioc, sglist, nents); + coalesced = iommu_coalesce_chunks(ioc, sglist, nents, sba_alloc_range); /* ** Program the I/O Pdir @@ -1328,7 +1101,7 @@ ** o dma_len will contain the number of bytes to map ** o address contains the virtual address. */ - filled = sba_fill_pdir(ioc, sglist, nents); + filled = iommu_fill_pdir(ioc, sglist, nents, 0, sba_io_pdir_entry); #ifdef ASSERT_PDIR_SANITY if (sba_check_pdir(ioc,"Check after sba_map_sg()")) @@ -1410,8 +1183,10 @@ .unmap_single = sba_unmap_single, .map_sg = sba_map_sg, .unmap_sg = sba_unmap_sg, - .dma_sync_single = NULL, - .dma_sync_sg = NULL, + .dma_sync_single_for_cpu = NULL, + .dma_sync_single_for_device = NULL, + .dma_sync_sg_for_cpu = NULL, + .dma_sync_sg_for_device = NULL, }; @@ -2045,6 +1820,9 @@ create_proc_info_entry("bitmap", 0, proc_runway_root, sba_resource_map); #endif #endif + parisc_vmerge_boundary = IOVP_SIZE; + parisc_vmerge_max_size = IOVP_SIZE * BITS_PER_LONG; + return 0; } diff -Nru a/drivers/parisc/superio.c b/drivers/parisc/superio.c --- a/drivers/parisc/superio.c Sun Mar 14 14:20:07 2004 +++ b/drivers/parisc/superio.c Sun Mar 14 14:20:07 2004 @@ -69,11 +69,15 @@ #include #include #include +#include +#include #include #include #include #include +#define SUPERIO_IDE_MAX_RETRIES 25 + static struct superio_device sio_dev; @@ -161,7 +165,6 @@ printk (KERN_INFO "SuperIO: Found NS87560 Legacy I/O device at %s (IRQ %i) \n", pci_name(pdev),pdev->irq); - /* Find our I/O devices */ pci_read_config_dword (pdev, SIO_SP1BAR, &sio->sp1_base); sio->sp1_base &= ~1; printk (KERN_INFO "SuperIO: Serial port 1 at 0x%x\n", sio->sp1_base); @@ -462,16 +465,72 @@ } -int -superio_get_ide_irq(void) +static u8 superio_ide_inb (unsigned long port); +static unsigned long superio_ide_status[2]; +static unsigned long superio_ide_select[2]; +static unsigned long superio_ide_dma_status[2]; + +void superio_fixup_pci(struct pci_dev *pdev) { - if (sio_dev.irq_region) - return sio_dev.irq_region->data.irqbase + IDE_IRQ; - else - return 0; + u8 prog; + + pdev->class |= 0x5; + pci_write_config_byte(pdev, PCI_CLASS_PROG, pdev->class); + + pci_read_config_byte(pdev, PCI_CLASS_PROG, &prog); + printk("PCI: Enabled native mode for NS87415 (pif=0x%x)\n", prog); } -EXPORT_SYMBOL(superio_get_ide_irq); +/* Because of a defect in Super I/O, all reads of the PCI DMA status + * registers, IDE status register and the IDE select register need to be + * retried + */ +static u8 superio_ide_inb (unsigned long port) +{ + if (port == superio_ide_status[0] || + port == superio_ide_status[1] || + port == superio_ide_select[0] || + port == superio_ide_select[1] || + port == superio_ide_dma_status[0] || + port == superio_ide_dma_status[1]) { + u8 tmp; + int retries = SUPERIO_IDE_MAX_RETRIES; + + /* printk(" [ reading port 0x%x with retry ] ", port); */ + + do { + tmp = inb(port); + if (tmp == 0) + udelay(50); + } while (tmp == 0 && retries-- > 0); + + return tmp; + } + + return inb(port); +} + +void __init superio_ide_init_iops (struct hwif_s *hwif) +{ + u32 base, dmabase; + u8 tmp; + struct pci_dev *pdev = hwif->pci_dev; + u8 port = hwif->channel; + + base = pci_resource_start(pdev, port * 2) & ~3; + dmabase = pci_resource_start(pdev, 4) & ~3; + + superio_ide_status[port] = base + IDE_STATUS_OFFSET; + superio_ide_select[port] = base + IDE_SELECT_OFFSET; + superio_ide_dma_status[port] = dmabase + (!port ? 2 : 0xa); + + /* Clear error/interrupt, enable dma */ + tmp = superio_ide_inb(superio_ide_dma_status[port]); + outb(tmp | 0x66, superio_ide_dma_status[port]); + + /* We need to override inb to workaround a SuperIO errata */ + hwif->INB = superio_ide_inb; +} static int __devinit superio_probe(struct pci_dev *dev, const struct pci_device_id *id) { diff -Nru a/drivers/parport/parport_gsc.c b/drivers/parport/parport_gsc.c --- a/drivers/parport/parport_gsc.c Sun Mar 14 14:20:08 2004 +++ b/drivers/parport/parport_gsc.c Sun Mar 14 14:20:08 2004 @@ -476,7 +476,7 @@ return 0; } -static void __devexit parport_remove_chip(struct parisc_device *dev) +static int __devexit parport_remove_chip(struct parisc_device *dev) { struct parport *p = dev->dev.driver_data; if (p) { @@ -495,6 +495,7 @@ parport_put_port(p); kfree (ops); /* hope no-one cached it */ } + return 0; } static struct parisc_device_id parport_tbl[] = { @@ -508,7 +509,7 @@ .name = "Parallel", .id_table = parport_tbl, .probe = parport_init_chip, - .remove = parport_remove_chip, + .remove = __devexit_p(parport_remove_chip), }; int __devinit parport_gsc_init(void) diff -Nru a/drivers/pci/pci.c b/drivers/pci/pci.c --- a/drivers/pci/pci.c Sun Mar 14 14:20:06 2004 +++ b/drivers/pci/pci.c Sun Mar 14 14:20:06 2004 @@ -686,7 +686,7 @@ if (!pci_dma_supported(dev, mask)) return -EIO; - dev->consistent_dma_mask = mask; + dev->dev.coherent_dma_mask = mask; return 0; } diff -Nru a/drivers/pci/probe.c b/drivers/pci/probe.c --- a/drivers/pci/probe.c Sun Mar 14 14:20:08 2004 +++ b/drivers/pci/probe.c Sun Mar 14 14:20:08 2004 @@ -570,7 +570,6 @@ /* Assume 32-bit PCI; let 64-bit PCI cards (which are far rarer) set this higher, assuming the system even supports it. */ dev->dma_mask = 0xffffffff; - dev->consistent_dma_mask = 0xffffffff; if (pci_setup_device(dev) < 0) { kfree(dev); return NULL; @@ -582,6 +581,7 @@ pci_name_device(dev); dev->dev.dma_mask = &dev->dma_mask; + dev->dev.coherent_dma_mask = 0xffffffffull; return dev; } diff -Nru a/drivers/scsi/53c700.c b/drivers/scsi/53c700.c --- a/drivers/scsi/53c700.c Sun Mar 14 14:20:06 2004 +++ b/drivers/scsi/53c700.c Sun Mar 14 14:20:06 2004 @@ -137,6 +137,9 @@ #include "scsi.h" #include "hosts.h" +#include +#include + #include "53c700.h" /* NOTE: For 64 bit drivers there are points in the code where we use @@ -173,6 +176,8 @@ STATIC struct device_attribute *NCR_700_dev_attrs[]; +STATIC struct scsi_transport_template *NCR_700_transport_template = NULL; + static char *NCR_700_phase[] = { "", "after selection", @@ -236,6 +241,53 @@ NCR_700_MAX_OFFSET }; +/* This translates the SDTR message offset and period to a value + * which can be loaded into the SXFER_REG. + * + * NOTE: According to SCSI-2, the true transfer period (in ns) is + * actually four times this period value */ +static inline __u8 +NCR_700_offset_period_to_sxfer(struct NCR_700_Host_Parameters *hostdata, + __u8 offset, __u8 period) +{ + int XFERP; + + __u8 min_xferp = (hostdata->chip710 + ? NCR_710_MIN_XFERP : NCR_700_MIN_XFERP); + __u8 max_offset = (hostdata->chip710 + ? NCR_710_MAX_OFFSET : NCR_700_MAX_OFFSET); + + if(offset == 0) + return 0; + + if(period < hostdata->min_period) { + printk(KERN_WARNING "53c700: Period %dns is less than this chip's minimum, setting to %d\n", period*4, NCR_700_SDTR_msg[3]*4); + period = hostdata->min_period; + } + XFERP = (period*4 * hostdata->sync_clock)/1000 - 4; + if(offset > max_offset) { + printk(KERN_WARNING "53c700: Offset %d exceeds chip maximum, setting to %d\n", + offset, max_offset); + offset = max_offset; + } + if(XFERP < min_xferp) { + printk(KERN_WARNING "53c700: XFERP %d is less than minium, setting to %d\n", + XFERP, min_xferp); + XFERP = min_xferp; + } + return (offset & 0x0f) | (XFERP & 0x07)<<4; +} + +static inline __u8 +NCR_700_get_SXFER(Scsi_Device *SDp) +{ + struct NCR_700_Host_Parameters *hostdata = + (struct NCR_700_Host_Parameters *)SDp->host->hostdata[0]; + + return NCR_700_offset_period_to_sxfer(hostdata, spi_offset(SDp), + spi_period(SDp)); +} + struct Scsi_Host * NCR_700_detect(Scsi_Host_Template *tpnt, struct NCR_700_Host_Parameters *hostdata) @@ -321,11 +373,13 @@ hostdata->script = script; hostdata->pScript = pScript; - dma_sync_single(hostdata->dev, pScript, sizeof(SCRIPT), DMA_TO_DEVICE); + dma_sync_single_for_device(hostdata->dev, pScript, sizeof(SCRIPT), DMA_TO_DEVICE); hostdata->state = NCR_700_HOST_FREE; hostdata->cmd = NULL; host->max_id = 7; host->max_lun = NCR_700_MAX_LUNS; + BUG_ON(NCR_700_transport_template == NULL); + host->transportt = NCR_700_transport_template; host->unique_id = hostdata->base; host->base = hostdata->base; hostdata->eh_complete = NULL; @@ -520,40 +574,6 @@ hostdata->cmd = NULL; } -/* This translates the SDTR message offset and period to a value - * which can be loaded into the SXFER_REG. - * - * NOTE: According to SCSI-2, the true transfer period (in ns) is - * actually four times this period value */ -STATIC inline __u8 -NCR_700_offset_period_to_sxfer(struct NCR_700_Host_Parameters *hostdata, - __u8 offset, __u8 period) -{ - int XFERP; - __u8 min_xferp = (hostdata->chip710 - ? NCR_710_MIN_XFERP : NCR_700_MIN_XFERP); - __u8 max_offset = (hostdata->chip710 - ? NCR_710_MAX_OFFSET : NCR_700_MAX_OFFSET); - /* NOTE: NCR_700_SDTR_msg[3] contains our offer of the minimum - * period. It is set in NCR_700_chip_setup() */ - if(period < NCR_700_SDTR_msg[3]) { - printk(KERN_WARNING "53c700: Period %dns is less than this chip's minimum, setting to %d\n", period*4, NCR_700_SDTR_msg[3]*4); - period = NCR_700_SDTR_msg[3]; - } - XFERP = (period*4 * hostdata->sync_clock)/1000 - 4; - if(offset > max_offset) { - printk(KERN_WARNING "53c700: Offset %d exceeds chip maximum, setting to %d\n", - offset, max_offset); - offset = max_offset; - } - if(XFERP < min_xferp) { - printk(KERN_WARNING "53c700: XFERP %d is less than minium, setting to %d\n", - XFERP, min_xferp); - XFERP = min_xferp; - } - return (offset & 0x0f) | (XFERP & 0x07)<<4; -} - STATIC inline void NCR_700_unmap(struct NCR_700_Host_Parameters *hostdata, Scsi_Cmnd *SCp, struct NCR_700_command_slot *slot) @@ -724,11 +744,9 @@ * exact details of this calculation which is based on a * setting of the SXFER register */ min_period = 1000*(4+min_xferp)/(4*hostdata->sync_clock); - if(min_period > NCR_700_MIN_PERIOD) { - NCR_700_SDTR_msg[3] = min_period; - } - if(hostdata->chip710) - NCR_700_SDTR_msg[4] = NCR_710_MAX_OFFSET; + hostdata->min_period = NCR_700_MIN_PERIOD; + if(min_period > NCR_700_MIN_PERIOD) + hostdata->min_period = min_period; } STATIC void @@ -777,20 +795,25 @@ if(SCp != NULL && NCR_700_is_flag_set(SCp->device, NCR_700_DEV_BEGIN_SYNC_NEGOTIATION)) { __u8 period = hostdata->msgin[3]; __u8 offset = hostdata->msgin[4]; - __u8 sxfer; - if(offset != 0 && period != 0) - sxfer = NCR_700_offset_period_to_sxfer(hostdata, offset, period); - else - sxfer = 0; + if(offset == 0 || period == 0) { + offset = 0; + period = 0; + } - if(sxfer != NCR_700_get_SXFER(SCp->device)) { - printk(KERN_INFO "scsi%d: (%d:%d) Synchronous at offset %d, period %dns\n", - host->host_no, pun, lun, - offset, period*4); - - NCR_700_set_SXFER(SCp->device, sxfer); + if(NCR_700_is_flag_set(SCp->device, NCR_700_DEV_PRINT_SYNC_NEGOTIATION)) { + if(spi_offset(SCp->device) != 0) + printk(KERN_INFO "scsi%d: (%d:%d) Synchronous at offset %d, period %dns\n", + host->host_no, pun, lun, + offset, period*4); + else + printk(KERN_INFO "scsi%d: (%d:%d) Asynchronous\n", + host->host_no, pun, lun); + NCR_700_clear_flag(SCp->device, NCR_700_DEV_PRINT_SYNC_NEGOTIATION); } + + spi_offset(SCp->device) = offset; + spi_period(SCp->device) = period; NCR_700_set_flag(SCp->device, NCR_700_DEV_NEGOTIATED_SYNC); @@ -870,7 +893,7 @@ case A_REJECT_MSG: if(SCp != NULL && NCR_700_is_flag_set(SCp->device, NCR_700_DEV_BEGIN_SYNC_NEGOTIATION)) { /* Rejected our sync negotiation attempt */ - NCR_700_set_SXFER(SCp->device, 0); + spi_period(SCp->device) = spi_offset(SCp->device) = 0; NCR_700_set_flag(SCp->device, NCR_700_DEV_NEGOTIATED_SYNC); NCR_700_clear_flag(SCp->device, NCR_700_DEV_BEGIN_SYNC_NEGOTIATION); } else if(SCp != NULL && NCR_700_is_flag_set(SCp->device, NCR_700_DEV_BEGIN_TAG_QUEUEING)) { @@ -982,8 +1005,8 @@ SCp->cmnd[7] = hostdata->status[0]; SCp->use_sg = 0; SCp->sc_data_direction = SCSI_DATA_READ; - dma_sync_single(hostdata->dev, slot->pCmd, - SCp->cmd_len, DMA_TO_DEVICE); + dma_sync_single_for_device(hostdata->dev, slot->pCmd, + SCp->cmd_len, DMA_TO_DEVICE); SCp->request_bufflen = sizeof(SCp->sense_buffer); slot->dma_handle = dma_map_single(hostdata->dev, SCp->sense_buffer, sizeof(SCp->sense_buffer), DMA_FROM_DEVICE); slot->SG[0].ins = bS_to_host(SCRIPT_MOVE_DATA_IN | sizeof(SCp->sense_buffer)); @@ -1007,7 +1030,7 @@ // SCp->cmnd[0] == INQUIRY && SCp->use_sg == 0) { // /* Piggy back the tag queueing support // * on this command */ - // dma_sync_single(hostdata->dev, + // dma_sync_single_for_cpu(hostdata->dev, // slot->dma_handle, // SCp->request_bufflen, // DMA_FROM_DEVICE); @@ -1396,6 +1419,8 @@ NCR_700_is_flag_clear(SCp->device, NCR_700_DEV_NEGOTIATED_SYNC)) { memcpy(&hostdata->msgout[count], NCR_700_SDTR_msg, sizeof(NCR_700_SDTR_msg)); + hostdata->msgout[count+3] = spi_period(SCp->device); + hostdata->msgout[count+4] = spi_offset(SCp->device); count += sizeof(NCR_700_SDTR_msg); NCR_700_set_flag(SCp->device, NCR_700_DEV_BEGIN_SYNC_NEGOTIATION); } @@ -1497,6 +1522,8 @@ printk(KERN_ERR "scsi%d: Bus Reset detected, executing command %p, slot %p, dsp %08x[%04x]\n", host->host_no, SCp, SCp == NULL ? NULL : SCp->host_scribble, dsp, dsp - hostdata->pScript); + scsi_report_bus_reset(host, 0); + /* clear all the negotiated parameters */ __shost_for_each_device(SDp, host) SDp->hostdata = 0; @@ -1942,6 +1969,9 @@ wait_for_completion(&complete); spin_lock_irq(SCp->device->host->host_lock); hostdata->eh_complete = NULL; + /* Revalidate the transport parameters of the failing device */ + if(hostdata->fast) + spi_schedule_dv_device(SCp->device); return SUCCESS; } @@ -1967,9 +1997,57 @@ return SUCCESS; } +STATIC void +NCR_700_set_period(struct scsi_device *SDp, int period) +{ + struct NCR_700_Host_Parameters *hostdata = + (struct NCR_700_Host_Parameters *)SDp->host->hostdata[0]; + + if(!hostdata->fast) + return; + + if(period < hostdata->min_period) + period = hostdata->min_period; + + spi_period(SDp) = period; + NCR_700_clear_flag(SDp, NCR_700_DEV_NEGOTIATED_SYNC); + NCR_700_clear_flag(SDp, NCR_700_DEV_BEGIN_SYNC_NEGOTIATION); + NCR_700_set_flag(SDp, NCR_700_DEV_PRINT_SYNC_NEGOTIATION); +} + +STATIC void +NCR_700_set_offset(struct scsi_device *SDp, int offset) +{ + struct NCR_700_Host_Parameters *hostdata = + (struct NCR_700_Host_Parameters *)SDp->host->hostdata[0]; + int max_offset = hostdata->chip710 + ? NCR_710_MAX_OFFSET : NCR_700_MAX_OFFSET; + + if(!hostdata->fast) + return; + + if(offset > max_offset) + offset = max_offset; + + /* if we're currently async, make sure the period is reasonable */ + if(spi_offset(SDp) == 0 && (spi_period(SDp) < hostdata->min_period || + spi_period(SDp) > 0xff)) + spi_period(SDp) = hostdata->min_period; + + spi_offset(SDp) = offset; + NCR_700_clear_flag(SDp, NCR_700_DEV_NEGOTIATED_SYNC); + NCR_700_clear_flag(SDp, NCR_700_DEV_BEGIN_SYNC_NEGOTIATION); + NCR_700_set_flag(SDp, NCR_700_DEV_PRINT_SYNC_NEGOTIATION); +} + + + STATIC int NCR_700_slave_configure(Scsi_Device *SDp) { + struct NCR_700_Host_Parameters *hostdata = + (struct NCR_700_Host_Parameters *)SDp->host->hostdata[0]; + /* to do here: allocate memory; build a queue_full list */ if(SDp->tagged_supported) { /* do TCQ stuff here */ @@ -1977,6 +2055,13 @@ /* initialise to default depth */ scsi_adjust_queue_depth(SDp, 0, SDp->host->cmd_per_lun); } + if(hostdata->fast) { + /* Find the correct offset and period via domain validation */ + spi_dv_device(SDp); + } else { + spi_offset(SDp) = 0; + spi_period(SDp) = 0; + } return 0; } @@ -2033,3 +2118,27 @@ EXPORT_SYMBOL(NCR_700_detect); EXPORT_SYMBOL(NCR_700_release); EXPORT_SYMBOL(NCR_700_intr); + +static struct spi_function_template NCR_700_transport_functions = { + .set_period = NCR_700_set_period, + .show_period = 1, + .set_offset = NCR_700_set_offset, + .show_offset = 1, +}; + +static int __init NCR_700_init(void) +{ + NCR_700_transport_template = spi_attach_transport(&NCR_700_transport_functions); + if(!NCR_700_transport_template) + return -ENODEV; + return 0; +} + +static void __exit NCR_700_exit(void) +{ + spi_release_transport(NCR_700_transport_template); +} + +module_init(NCR_700_init); +module_exit(NCR_700_exit); + diff -Nru a/drivers/scsi/53c700.h b/drivers/scsi/53c700.h --- a/drivers/scsi/53c700.h Sun Mar 14 14:20:06 2004 +++ b/drivers/scsi/53c700.h Sun Mar 14 14:20:06 2004 @@ -99,19 +99,9 @@ #define NCR_700_DEV_NEGOTIATED_SYNC (1<<16) #define NCR_700_DEV_BEGIN_SYNC_NEGOTIATION (1<<17) #define NCR_700_DEV_BEGIN_TAG_QUEUEING (1<<18) -#define NCR_700_DEV_TAG_STARVATION_WARNED (1<<19) +#define NCR_700_DEV_PRINT_SYNC_NEGOTIATION (1<<19) static inline void -NCR_700_set_SXFER(Scsi_Device *SDp, __u8 sxfer) -{ - SDp->hostdata = (void *)(((long)SDp->hostdata & 0xffffff00) | - (sxfer & 0xff)); -} -static inline __u8 NCR_700_get_SXFER(Scsi_Device *SDp) -{ - return (((unsigned long)SDp->hostdata) & 0xff); -} -static inline void NCR_700_set_depth(Scsi_Device *SDp, __u8 depth) { long l = (long)SDp->hostdata; @@ -215,6 +205,7 @@ __u8 tag_negotiated; __u8 rev; __u8 reselection_id; + __u8 min_period; /* Free list, singly linked by ITL_forw elements */ struct NCR_700_command_slot *free_list; @@ -438,6 +429,7 @@ #symbol, A_##symbol##_used[i], val)); \ } \ } + static inline __u8 NCR_700_mem_readb(struct Scsi_Host *host, __u32 reg) diff -Nru a/drivers/scsi/BusLogic.c b/drivers/scsi/BusLogic.c --- a/drivers/scsi/BusLogic.c Sun Mar 14 14:20:08 2004 +++ b/drivers/scsi/BusLogic.c Sun Mar 14 14:20:08 2004 @@ -140,7 +140,7 @@ Name, Copyright Notice, and Electronic Mail Address. */ -static void __init BusLogic_AnnounceDriver(struct BusLogic_HostAdapter *HostAdapter) +static void BusLogic_AnnounceDriver(struct BusLogic_HostAdapter *HostAdapter) { BusLogic_Announce("***** BusLogic SCSI Driver Version " BusLogic_DriverVersion " of " diff -Nru a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig --- a/drivers/scsi/Kconfig Sun Mar 14 14:20:08 2004 +++ b/drivers/scsi/Kconfig Sun Mar 14 14:20:08 2004 @@ -196,6 +196,25 @@ there should be no noticeable performance impact as long as you have logging turned off. +menu "SCSI Transport Attributes" + depends on SCSI + +config SCSI_SPI_ATTRS + tristate "Parallel SCSI (SPI) Transport Attributes" + depends on SCSI + help + If you wish to export transport-specific information about + each attached SCSI device to sysfs, say Y. Otherwise, say N. + +config SCSI_FC_ATTRS + tristate "FiberChannel Transport Attributes" + depends on SCSI + help + If you wish to export transport-specific information about + each attached FiberChannel device to sysfs, say Y. + Otherwise, say N. + +endmenu menu "SCSI low-level drivers" depends on SCSI!=n @@ -438,6 +457,14 @@ If unsure, say N. +config SCSI_SATA_VITESSE + tristate "VITESSE VSC-7174 SATA support" + depends on SCSI_SATA && PCI && EXPERIMENTAL + help + This option enables support for Vitesse VSC7174 Serial ATA. + + If unsure, say N. + config SCSI_BUSLOGIC tristate "BusLogic SCSI support" depends on (PCI || ISA || MCA) && SCSI @@ -845,6 +872,7 @@ config SCSI_NCR_D700 tristate "NCR Dual 700 MCA SCSI support" depends on MCA && SCSI + select SCSI_SPI_ATTRS help This is a driver for the MicroChannel Dual 700 card produced by NCR and commonly used in 345x/35xx/4100 class machines. It always @@ -861,6 +889,7 @@ config SCSI_LASI700 tristate "HP Lasi SCSI support for 53c700/710" depends on GSC && SCSI + select SCSI_SPI_ATTRS help This is a driver for the SCSI controller in the Lasi chip found in many PA-RISC workstations & servers. If you do not know whether you @@ -1212,6 +1241,7 @@ config SCSI_SIM710 tristate "Simple 53c710 SCSI support (Compaq, NCR machines)" depends on (EISA || MCA) && SCSI + select SCSI_SPI_ATTRS ---help--- This driver for NCR53c710 based SCSI host adapters. diff -Nru a/drivers/scsi/Makefile b/drivers/scsi/Makefile --- a/drivers/scsi/Makefile Sun Mar 14 14:20:08 2004 +++ b/drivers/scsi/Makefile Sun Mar 14 14:20:08 2004 @@ -22,6 +22,14 @@ obj-$(CONFIG_SCSI) += scsi_mod.o +# --- NOTE ORDERING HERE --- +# For kernel non-modular link, transport attributes need to +# be initialised before drivers +# -------------------------- +obj-$(CONFIG_SCSI_SPI_ATTRS) += scsi_transport_spi.o +obj-$(CONFIG_SCSI_FC_ATTRS) += scsi_transport_fc.o + + obj-$(CONFIG_SCSI_AMIGA7XX) += amiga7xx.o 53c7xx.o obj-$(CONFIG_A3000_SCSI) += a3000.o wd33c93.o obj-$(CONFIG_A2091_SCSI) += a2091.o wd33c93.o @@ -41,7 +49,7 @@ obj-$(CONFIG_SUN3_SCSI) += sun3_scsi.o sun3_scsi_vme.o obj-$(CONFIG_MVME16x_SCSI) += mvme16x.o 53c7xx.o obj-$(CONFIG_BVME6000_SCSI) += bvme6000.o 53c7xx.o -obj-$(CONFIG_SCSI_SIM710) += sim710.o 53c700.o +obj-$(CONFIG_SCSI_SIM710) += 53c700.o sim710.o obj-$(CONFIG_SCSI_ADVANSYS) += advansys.o obj-$(CONFIG_SCSI_PCI2000) += pci2000.o obj-$(CONFIG_SCSI_PCI2220I) += pci2220i.o @@ -64,7 +72,7 @@ obj-$(CONFIG_SCSI_GENERIC_NCR5380) += g_NCR5380.o obj-$(CONFIG_SCSI_GENERIC_NCR5380_MMIO) += g_NCR5380_mmio.o obj-$(CONFIG_SCSI_NCR53C406A) += NCR53c406a.o -obj-$(CONFIG_SCSI_NCR_D700) += NCR_D700.o 53c700.o +obj-$(CONFIG_SCSI_NCR_D700) += 53c700.o NCR_D700.o obj-$(CONFIG_SCSI_NCR_Q720) += NCR_Q720_mod.o obj-$(CONFIG_SCSI_SYM53C416) += sym53c416.o obj-$(CONFIG_SCSI_QLOGIC_FAS) += qlogicfas.o @@ -107,13 +115,14 @@ obj-$(CONFIG_SCSI_DEBUG) += scsi_debug.o obj-$(CONFIG_SCSI_FCAL) += fcal.o obj-$(CONFIG_SCSI_CPQFCTS) += cpqfc.o -obj-$(CONFIG_SCSI_LASI700) += lasi700.o 53c700.o +obj-$(CONFIG_SCSI_LASI700) += 53c700.o lasi700.o obj-$(CONFIG_SCSI_NSP32) += nsp32.o obj-$(CONFIG_SCSI_SATA_SVW) += libata.o sata_svw.o obj-$(CONFIG_SCSI_ATA_PIIX) += libata.o ata_piix.o obj-$(CONFIG_SCSI_SATA_PROMISE) += libata.o sata_promise.o obj-$(CONFIG_SCSI_SATA_SIL) += libata.o sata_sil.o obj-$(CONFIG_SCSI_SATA_VIA) += libata.o sata_via.o +obj-$(CONFIG_SCSI_SATA_VITESSE) += libata.o sata_vsc.o obj-$(CONFIG_ARM) += arm/ @@ -130,7 +139,7 @@ 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 sr_mod-objs := sr.o sr_ioctl.o sr_vendor.o initio-objs := ini9100u.o i91uscsi.o diff -Nru a/drivers/scsi/aacraid/linit.c b/drivers/scsi/aacraid/linit.c --- a/drivers/scsi/aacraid/linit.c Sun Mar 14 14:20:07 2004 +++ b/drivers/scsi/aacraid/linit.c Sun Mar 14 14:20:07 2004 @@ -99,8 +99,8 @@ { 0x9005, 0x0285, 0x9005, 0x0288, 0, 0, 16 }, /* Adaptec 3230S (Harrier)*/ { 0x9005, 0x0285, 0x9005, 0x0289, 0, 0, 17 }, /* Adaptec 3240S (Tornado)*/ - { 0x9005, 0x0285, 0x9005, 0x028a, 0, 0, 18 }, /* ASR-2020S PCI-X ZCR (Skyhawk)*/ - { 0x9005, 0x0285, 0x9005, 0x028b, 0, 0, 19 }, /* ASR-2020S SO-DIMM PCI-X ZCR(Terminator)*/ + { 0x9005, 0x0285, 0x9005, 0x028a, 0, 0, 18 }, /* ASR-2020 ZCR PCI-X U320 */ + { 0x9005, 0x0285, 0x9005, 0x028b, 0, 0, 19 }, /* ASR-2025 ZCR DIMM U320 */ { 0x9005, 0x0285, 0x9005, 0x0290, 0, 0, 20 }, /* AAR-2410SA PCI SATA 4ch (Jaguar II)*/ { 0x9005, 0x0285, 0x1028, 0x0287, 0, 0, 21 }, /* Perc 320/DC*/ @@ -116,6 +116,8 @@ { 0x9005, 0x0285, 0x0E11, 0x0295, 0, 0, 30 }, /* SATA 6Ch (Bearcat) */ { 0x9005, 0x0286, 0x9005, 0x028c, 0, 0, 31 }, /* ASR-2230S + ASR-2230SLP PCI-X (Lancer) */ + { 0x9005, 0x0285, 0x9005, 0x028e, 0, 0, 32 }, /* ASR-2020SA (ZCR PCI-X SATA) */ + { 0x9005, 0x0285, 0x9005, 0x028f, 0, 0, 33 }, /* ASR-2025SA (ZCR DIMM SATA) */ { 0,} }; MODULE_DEVICE_TABLE(pci, aac_pci_tbl); @@ -145,8 +147,8 @@ { aac_rx_init, "aacraid", "ADAPTEC ", "Adaptec 3230S ", 2 }, /* Adaptec 3230S (Harrier)*/ { aac_rx_init, "aacraid", "ADAPTEC ", "Adaptec 3240S ", 2 }, /* Adaptec 3240S (Tornado)*/ - { aac_rx_init, "aacraid", "ADAPTEC ", "ASR-2020S PCI-X ", 2 }, /* ASR-2020S PCI-X ZCR (Skyhawk)*/ - { aac_rx_init, "aacraid", "ADAPTEC ", "ASR-2020S PCI-X ", 2 }, /* ASR-2020S SO-DIMM PCI-X ZCR(Terminator)*/ + { aac_rx_init, "aacraid", "ADAPTEC ", "ASR-2020ZCR ", 2 }, /* ASR-2020 ZCR PCI-X U320 */ + { aac_rx_init, "aacraid", "ADAPTEC ", "ASR-2025ZCR ", 2 }, /* ASR-2025 ZCR DIMM U320 */ { aac_rx_init, "aacraid", "ADAPTEC ", "AAR-2410SA SATA ", 2 }, /* AAR-2410SA PCI SATA 4ch (Jaguar II)*/ { aac_rx_init, "percraid", "DELL ", "PERC 320/DC ", 2, AAC_QUIRK_31BIT }, /* Perc 320/DC*/ @@ -162,6 +164,8 @@ { aac_rx_init, "aacraid", "ADAPTEC ", "SATA 6Channel ", 1 }, /* SATA 6Ch (Bearcat) */ { aac_rkt_init,"aacraid", "ADAPTEC ", "ASR-2230S PCI-X ", 2 }, /* ASR-2230S + ASR-2230SLP PCI-X (Lancer) */ + { aac_rx_init, "aacraid", "ADAPTEC ", "ASR-2020SA ", 1 }, /* ASR-2020SA (ZCR PCI-X SATA) */ + { aac_rx_init, "aacraid", "ADAPTEC ", "ASR-2025SA ", 1 }, /* ASR-2025SA (ZCR DIMM SATA) */ }; /** diff -Nru a/drivers/scsi/aacraid/rkt.c b/drivers/scsi/aacraid/rkt.c --- a/drivers/scsi/aacraid/rkt.c Sun Mar 14 14:20:08 2004 +++ b/drivers/scsi/aacraid/rkt.c Sun Mar 14 14:20:08 2004 @@ -427,6 +427,7 @@ dev->a_ops.adapter_disable_int = aac_rkt_disable_interrupt; dev->a_ops.adapter_notify = aac_rkt_notify_adapter; dev->a_ops.adapter_sync_cmd = rkt_sync_cmd; + dev->a_ops.adapter_check_health = aac_rkt_check_health; if (aac_init_adapter(dev) == NULL) return -1; diff -Nru a/drivers/scsi/aacraid/rx.c b/drivers/scsi/aacraid/rx.c --- a/drivers/scsi/aacraid/rx.c Sun Mar 14 14:20:09 2004 +++ b/drivers/scsi/aacraid/rx.c Sun Mar 14 14:20:09 2004 @@ -427,6 +427,7 @@ dev->a_ops.adapter_disable_int = aac_rx_disable_interrupt; dev->a_ops.adapter_notify = aac_rx_notify_adapter; dev->a_ops.adapter_sync_cmd = rx_sync_cmd; + dev->a_ops.adapter_check_health = aac_rx_check_health; if (aac_init_adapter(dev) == NULL) return -1; diff -Nru a/drivers/scsi/aacraid/sa.c b/drivers/scsi/aacraid/sa.c --- a/drivers/scsi/aacraid/sa.c Sun Mar 14 14:20:07 2004 +++ b/drivers/scsi/aacraid/sa.c Sun Mar 14 14:20:07 2004 @@ -407,6 +407,7 @@ dev->a_ops.adapter_disable_int = aac_sa_disable_interrupt; dev->a_ops.adapter_notify = aac_sa_notify_adapter; dev->a_ops.adapter_sync_cmd = sa_sync_cmd; + dev->a_ops.adapter_check_health = aac_sa_check_health; dprintk(("FUNCDONE\n")); diff -Nru a/drivers/scsi/aic7xxx/Kconfig.aic79xx b/drivers/scsi/aic7xxx/Kconfig.aic79xx --- a/drivers/scsi/aic7xxx/Kconfig.aic79xx Sun Mar 14 14:20:07 2004 +++ b/drivers/scsi/aic7xxx/Kconfig.aic79xx Sun Mar 14 14:20:07 2004 @@ -4,7 +4,7 @@ # config SCSI_AIC79XX tristate "Adaptec AIC79xx U320 support" - depends on PCI + depends on PCI && SCSI help This driver supports all of Adaptec's Ultra 320 PCI-X based SCSI controllers. diff -Nru a/drivers/scsi/aic7xxx/Kconfig.aic7xxx b/drivers/scsi/aic7xxx/Kconfig.aic7xxx --- a/drivers/scsi/aic7xxx/Kconfig.aic7xxx Sun Mar 14 14:20:06 2004 +++ b/drivers/scsi/aic7xxx/Kconfig.aic7xxx Sun Mar 14 14:20:06 2004 @@ -4,7 +4,7 @@ # config SCSI_AIC7XXX tristate "Adaptec AIC7xxx Fast -> U160 support (New Driver)" - depends on PCI || EISA + depends on (PCI || EISA) && SCSI ---help--- This driver supports all of Adaptec's Fast through Ultra 160 PCI based SCSI controllers as well as the aic7770 based EISA and VLB diff -Nru a/drivers/scsi/constants.c b/drivers/scsi/constants.c --- a/drivers/scsi/constants.c Sun Mar 14 14:20:08 2004 +++ b/drivers/scsi/constants.c Sun Mar 14 14:20:08 2004 @@ -1135,7 +1135,7 @@ static const char * hostbyte_table[]={ "DID_OK", "DID_NO_CONNECT", "DID_BUS_BUSY", "DID_TIME_OUT", "DID_BAD_TARGET", "DID_ABORT", "DID_PARITY", "DID_ERROR", "DID_RESET", "DID_BAD_INTR", -"DID_PASSTHROUGH", "DID_SOFT_ERROR", NULL}; +"DID_PASSTHROUGH", "DID_SOFT_ERROR", "DID_IMM_RETRY", NULL}; void print_hostbyte(int scsiresult) { static int maxcode=0; diff -Nru a/drivers/scsi/cpqfcTSinit.c b/drivers/scsi/cpqfcTSinit.c --- a/drivers/scsi/cpqfcTSinit.c Sun Mar 14 14:20:06 2004 +++ b/drivers/scsi/cpqfcTSinit.c Sun Mar 14 14:20:06 2004 @@ -46,10 +46,6 @@ #include // request_region() prototype #include -#ifdef __alpha__ -#define __KERNEL_SYSCALLS__ -#endif -#include #include #include // ioctl related #include diff -Nru a/drivers/scsi/dc395x.c b/drivers/scsi/dc395x.c --- a/drivers/scsi/dc395x.c Sun Mar 14 14:20:06 2004 +++ b/drivers/scsi/dc395x.c Sun Mar 14 14:20:06 2004 @@ -62,6 +62,10 @@ #include #include +#define DC395X_NAME "dc395x" +#define DC395X_BANNER "Tekram DC395(U/UW/F), DC315(U) - ASIC TRM-S1040" +#define DC395X_VERSION "v2.05, 2004/03/08" + /*--------------------------------------------------------------------------- Features ---------------------------------------------------------------------------*/ @@ -82,22 +86,16 @@ #define DBG_KG 0x0001 #define DBG_0 0x0002 #define DBG_1 0x0004 -#define DBG_DCB 0x0008 -#define DBG_PARSE 0x0010 /* debug command line parsing */ -#define DBG_SGPARANOIA 0x0020 +#define DBG_SG 0x0020 #define DBG_FIFO 0x0040 #define DBG_PIO 0x0080 -#define DBG_RECURSION 0x0100 /* check for excessive recursion */ -#define DBG_MALLOC 0x0200 /* report on memory allocations */ -#define DBG_TRACE 0x0400 -#define DBG_TRACEALL 0x0800 /* * Set set of things to output debugging for. * Undefine to remove all debugging */ -/*#define DEBUG_MASK (DBG_0|DBG_1|DBG_DCB|DBG_PARSE|DBG_SGPARANOIA|DBG_FIFO|DBG_PIO|DBG_TRACE|DBG_TRACEALL)*/ +/*#define DEBUG_MASK (DBG_0|DBG_1|DBG_SG|DBG_FIFO|DBG_PIO)*/ /*#define DEBUG_MASK DBG_0*/ @@ -138,72 +136,6 @@ #endif -/* - * The recursion debugging just counts entries into the driver and - * prints out a messge if it exceeds a certain limit. This variable - * hold the count. - */ -#if debug_enabled(DBG_RECURSION) -static int dbg_in_driver = 0; -#endif - - -/* - * Memory allocation debugging - * Just reports when memory is allocated and/or released. - */ -#if debug_enabled(DBG_MALLOC) -inline void *dc395x_kmalloc(size_t sz, int fl) -{ - void *ptr = kmalloc(sz, fl); - dprintkl(KERN_DEBUG, "Alloc %i bytes @ %p w/ fl %08x\n", sz, ptr, fl); - return ptr; -} -inline void dc395x_kfree(const void *adr) -{ - dprintkl(KERN_DEBUG, "Free mem @ %p\n", adr); - kfree(adr); -} -#else -#define dc395x_kmalloc(sz, fl) kmalloc(sz, fl) -#define dc395x_kfree(adr) kfree(adr) -#endif - - -/* - * Debug/trace stuff - */ -#if debug_enabled(DBG_TRACEALL) -# define TRACEOUTALL(x...) printk ( x) -#else -# define TRACEOUTALL(x...) do {} while (0) -#endif - -#if debug_enabled(DBG_TRACE|DBG_TRACEALL) -# define DEBUGTRACEBUFSZ 512 -static char tracebuf[64]; -static char traceoverflow[8] = { 0, 0, 0, 0, 0, 0, 0, 0 }; -# define TRACEPRINTF(x...) \ - do { \ - int ln = sprintf(tracebuf, x); \ - if (srb->debugpos + ln >= DEBUGTRACEBUFSZ) { \ - srb->debugtrace[srb->debugpos] = 0; \ - srb->debugpos = DEBUGTRACEBUFSZ/5; \ - srb->debugtrace[srb->debugpos++] = '>'; \ - } \ - sprintf(srb->debugtrace + srb->debugpos, "%s", tracebuf); \ - srb->debugpos += ln - 1; \ - } while (0) -# define TRACEOUT(x...) printk (x) -#else -# define TRACEPRINTF(x...) do {} while (0) -# define TRACEOUT(x...) do {} while (0) -#endif - - -/*--------------------------------------------------------------------------- - ---------------------------------------------------------------------------*/ - #ifndef PCI_VENDOR_ID_TEKRAM #define PCI_VENDOR_ID_TEKRAM 0x1DE1 /* Vendor ID */ #endif @@ -212,32 +144,16 @@ #endif - #define DC395x_LOCK_IO(dev,flags) spin_lock_irqsave(((struct Scsi_Host *)dev)->host_lock, flags) #define DC395x_UNLOCK_IO(dev,flags) spin_unlock_irqrestore(((struct Scsi_Host *)dev)->host_lock, flags) -#define DC395x_ACB_INITLOCK(acb) spin_lock_init(&acb->smp_lock) -#define DC395x_ACB_LOCK(acb,acb_flags) if (!acb->lock_level_count[cpuid]) { spin_lock_irqsave(&acb->smp_lock,acb_flags); acb->lock_level_count[cpuid]++; } else { acb->lock_level_count[cpuid]++; } -#define DC395x_ACB_UNLOCK(acb,acb_flags) if (--acb->lock_level_count[cpuid] == 0) { spin_unlock_irqrestore(&acb->smp_lock,acb_flags); } - -#define DC395x_SMP_IO_LOCK(dev,irq_flags) spin_lock_irqsave(((struct Scsi_Host*)dev)->host_lock,irq_flags) -#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->io_port_base + (address))) -#define DC395x_read8_(address, base) (u8)(inb((USHORT)(base) + (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->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)) -#define CPU_ADDR(sg) (page_address((sg).page)+(sg).offset) -#define PAGE_ADDRESS(sg) page_address((sg)->page) - /* cmd->result */ #define RES_TARGET 0x000000FF /* Target State */ #define RES_TARGET_LNX STATUS_MASK /* Only official ... */ @@ -254,20 +170,22 @@ #define SET_RES_DID(who,did) { who &= ~RES_DID; who |= (int)(did) << 16; } #define SET_RES_DRV(who,drv) { who &= ~RES_DRV; who |= (int)(drv) << 24; } -/* -************************************************************************** -*/ #define TAG_NONE 255 +/* + * srb->segement_x is the hw sg list. It is always allocated as a + * DC395x_MAX_SG_LISTENTRY entries in a linear block which does not + * cross a page boundy. + */ +#define SEGMENTX_LEN (sizeof(struct SGentry)*DC395x_MAX_SG_LISTENTRY) + + struct SGentry { u32 address; /* bus! address */ u32 length; }; - -/* - * The SEEPROM structure for TRM_S1040 - */ +/* The SEEPROM structure for TRM_S1040 */ struct NVRamTarget { u8 cfg0; /* Target configuration byte 0 */ u8 period; /* Target period */ @@ -275,7 +193,6 @@ u8 cfg3; /* Target configuration byte 3 */ }; - struct NvRamType { u8 sub_vendor_id[2]; /* 0,1 Sub Vendor ID */ u8 sub_sys_id[2]; /* 2,3 Sub System ID */ @@ -302,28 +219,31 @@ u16 cksum; /* 126,127 */ }; - -/*----------------------------------------------------------------------- - SCSI Request Block - -----------------------------------------------------------------------*/ struct ScsiReqBlk { struct list_head list; /* next/prev ptrs for srb lists */ struct DeviceCtlBlk *dcb; - - /* HW scatter list (up to 64 entries) */ - struct SGentry *segment_x; Scsi_Cmnd *cmd; - unsigned char *virt_addr; /* set by update_sg_list */ + struct SGentry *segment_x; /* Linear array of hw sg entries (up to 64 entries) */ + u32 sg_bus_addr; /* Bus address of sg list (ie, of segment_x) */ - u32 total_xfer_length; - u32 xferred; /* Backup for the already xferred len */ + u8 sg_count; /* No of HW sg entries for this request */ + u8 sg_index; /* Index of HW sg entry for this request */ + u32 total_xfer_length; /* Total number of bytes remaining to be transfered */ + unsigned char *virt_addr; /* Virtual address of current transfer position */ - u32 sg_bus_addr; /* bus address of DC395x scatterlist */ + /* + * The sense buffer handling function, request_sense, uses + * the first hw sg entry (segment_x[0]) and the transfer + * length (total_xfer_length). While doing this it stores the + * original values into the last sg hw list + * (srb->segment_x[DC395x_MAX_SG_LISTENTRY - 1] and the + * total_xfer_length in xferred. These values are restored in + * pci_unmap_srb_sense. This is the only place xferred is used. + */ + u32 xferred; /* Saved copy of total_xfer_length */ u16 state; - u8 sg_count; - u8 sg_index; u8 msgin_buf[6]; u8 msgout_buf[6]; @@ -339,17 +259,8 @@ u8 flag; u8 scsi_phase; - -#if debug_enabled(DBG_TRACE|DBG_TRACEALL) - u16 debugpos; - char *debugtrace; -#endif }; - -/*----------------------------------------------------------------------- - Device Control Block - -----------------------------------------------------------------------*/ struct DeviceCtlBlk { struct list_head list; /* next/prev ptrs for the dcb list */ struct AdapterCtlBlk *acb; @@ -377,9 +288,6 @@ u8 init_tcq_flag; }; -/*----------------------------------------------------------------------- - Adapter Control Block - -----------------------------------------------------------------------*/ struct AdapterCtlBlk { struct Scsi_Host *scsi_host; @@ -423,80 +331,63 @@ }; - - /*--------------------------------------------------------------------------- Forward declarations ---------------------------------------------------------------------------*/ -static void data_out_phase0(struct AdapterCtlBlk *acb, - struct ScsiReqBlk *srb, - u16 * pscsi_status); -static void data_in_phase0(struct AdapterCtlBlk *acb, - struct ScsiReqBlk *srb, - u16 * pscsi_status); -static void command_phase0(struct AdapterCtlBlk *acb, - struct ScsiReqBlk *srb, - u16 * pscsi_status); -static void status_phase0(struct AdapterCtlBlk *acb, - struct ScsiReqBlk *srb, - u16 * pscsi_status); -static void msgout_phase0(struct AdapterCtlBlk *acb, - struct ScsiReqBlk *srb, - u16 * pscsi_status); -static void msgin_phase0(struct AdapterCtlBlk *acb, - struct ScsiReqBlk *srb, - u16 * pscsi_status); -static void data_out_phase1(struct AdapterCtlBlk *acb, - struct ScsiReqBlk *srb, - u16 * pscsi_status); -static void data_in_phase1(struct AdapterCtlBlk *acb, - struct ScsiReqBlk *srb, - u16 * pscsi_status); -static void command_phase1(struct AdapterCtlBlk *acb, - struct ScsiReqBlk *srb, - u16 * pscsi_status); -static void status_phase1(struct AdapterCtlBlk *acb, - struct ScsiReqBlk *srb, - u16 * pscsi_status); -static void msgout_phase1(struct AdapterCtlBlk *acb, - struct ScsiReqBlk *srb, - u16 * pscsi_status); -static void msgin_phase1(struct AdapterCtlBlk *acb, - struct ScsiReqBlk *srb, - u16 * pscsi_status); +static void data_out_phase0(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb, + u16 *pscsi_status); +static void data_in_phase0(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb, + u16 *pscsi_status); +static void command_phase0(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb, + u16 *pscsi_status); +static void status_phase0(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb, + u16 *pscsi_status); +static void msgout_phase0(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb, + u16 *pscsi_status); +static void msgin_phase0(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb, + u16 *pscsi_status); +static void data_out_phase1(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb, + u16 *pscsi_status); +static void data_in_phase1(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb, + u16 *pscsi_status); +static void command_phase1(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb, + u16 *pscsi_status); +static void status_phase1(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb, + u16 *pscsi_status); +static void msgout_phase1(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb, + u16 *pscsi_status); +static void msgin_phase1(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb, + u16 *pscsi_status); static void nop0(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb, - u16 * pscsi_status); -static void nop1(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb, - u16 * pscsi_status); + u16 *pscsi_status); +static void nop1(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb, + u16 *pscsi_status); static void set_basic_config(struct AdapterCtlBlk *acb); static void cleanup_after_transfer(struct AdapterCtlBlk *acb, - struct ScsiReqBlk *srb); + struct ScsiReqBlk *srb); static void reset_scsi_bus(struct AdapterCtlBlk *acb); static void data_io_transfer(struct AdapterCtlBlk *acb, - struct ScsiReqBlk *srb, u16 io_dir); + struct ScsiReqBlk *srb, u16 io_dir); static void disconnect(struct AdapterCtlBlk *acb); static void reselect(struct AdapterCtlBlk *acb); static u8 start_scsi(struct AdapterCtlBlk *acb, struct DeviceCtlBlk *dcb, - struct ScsiReqBlk *srb); -static void build_srb(Scsi_Cmnd * cmd, struct DeviceCtlBlk *dcb, - struct ScsiReqBlk *srb); + struct ScsiReqBlk *srb); +static void build_srb(Scsi_Cmnd *cmd, struct DeviceCtlBlk *dcb, + struct ScsiReqBlk *srb); static void doing_srb_done(struct AdapterCtlBlk *acb, u8 did_code, - Scsi_Cmnd * cmd, u8 force); + Scsi_Cmnd *cmd, u8 force); static void scsi_reset_detect(struct AdapterCtlBlk *acb); -static void pci_unmap_srb(struct AdapterCtlBlk *acb, - struct ScsiReqBlk *srb); +static void pci_unmap_srb(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb); static void pci_unmap_srb_sense(struct AdapterCtlBlk *acb, - struct ScsiReqBlk *srb); + struct ScsiReqBlk *srb); static inline void enable_msgout_abort(struct AdapterCtlBlk *acb, - struct ScsiReqBlk *srb); -static void srb_done(struct AdapterCtlBlk *acb, - struct DeviceCtlBlk *dcb, - struct ScsiReqBlk *srb); -static void request_sense(struct AdapterCtlBlk *acb, - struct DeviceCtlBlk *dcb, - struct ScsiReqBlk *srb); + struct ScsiReqBlk *srb); +static void srb_done(struct AdapterCtlBlk *acb, struct DeviceCtlBlk *dcb, + struct ScsiReqBlk *srb); +static void request_sense(struct AdapterCtlBlk *acb, struct DeviceCtlBlk *dcb, + struct ScsiReqBlk *srb); static inline void set_xfer_rate(struct AdapterCtlBlk *acb, - struct DeviceCtlBlk *dcb); + struct DeviceCtlBlk *dcb); static void waiting_timeout(unsigned long ptr); @@ -504,11 +395,7 @@ Static Data ---------------------------------------------------------------------------*/ static u16 current_sync_offset = 0; -static char monitor_next_irq = 0; -/* - * dc395x_statev = (void *)dc395x_scsi_phase0[phase] - */ static void *dc395x_scsi_phase0[] = { data_out_phase0,/* phase:0 */ data_in_phase0, /* phase:1 */ @@ -520,9 +407,6 @@ msgin_phase0, /* phase:7 */ }; -/* - * dc395x_statev = (void *)dc395x_scsi_phase1[phase] - */ static void *dc395x_scsi_phase1[] = { data_out_phase1,/* phase:0 */ data_in_phase1, /* phase:1 */ @@ -558,8 +442,6 @@ /* real period:48ns,76ns,100ns,124ns,148ns,176ns,200ns,248ns */ static u8 clock_period[] = { 12, 18, 25, 31, 37, 43, 50, 62 }; static u16 clock_speed[] = { 200, 133, 100, 80, 67, 58, 50, 40 }; -/* real period:48ns,72ns,100ns,124ns,148ns,172ns,200ns,248ns */ - /*--------------------------------------------------------------------------- @@ -655,8 +537,9 @@ /* - * Safe settings. If set to zero the the BIOS/default values with command line - * overrides will be used. If set to 1 then safe and slow settings will be used. + * Safe settings. If set to zero the the BIOS/default values with + * command line overrides will be used. If set to 1 then safe and + * slow settings will be used. */ static int use_safe_settings = 0; module_param_named(safe, use_safe_settings, bool, 0); @@ -686,8 +569,7 @@ * set_safe_settings - if the use_safe_settings option is set then * set all values to the safe and slow values. **/ -static -void __init set_safe_settings(void) +static void __init set_safe_settings(void) { if (use_safe_settings) { @@ -706,25 +588,24 @@ * fix_settings - reset any boot parameters which are out of range * back to the default values. **/ -static -void __init fix_settings(void) +static void __init fix_settings(void) { int i; - dprintkdbg(DBG_PARSE, "setup %08x %08x %08x %08x %08x %08x\n", - cfg_data[CFG_ADAPTER_ID].value, - cfg_data[CFG_MAX_SPEED].value, - cfg_data[CFG_DEV_MODE].value, - cfg_data[CFG_ADAPTER_MODE].value, - cfg_data[CFG_TAGS].value, - cfg_data[CFG_RESET_DELAY].value); + dprintkdbg(DBG_1, + "setup: AdapterId=%08x MaxSpeed=%08x DevMode=%08x " + "AdapterMode=%08x Tags=%08x ResetDelay=%08x\n", + cfg_data[CFG_ADAPTER_ID].value, + cfg_data[CFG_MAX_SPEED].value, + cfg_data[CFG_DEV_MODE].value, + cfg_data[CFG_ADAPTER_MODE].value, + cfg_data[CFG_TAGS].value, + cfg_data[CFG_RESET_DELAY].value); for (i = 0; i < CFG_NUM; i++) { - if (cfg_data[i].value < cfg_data[i].min || - cfg_data[i].value > cfg_data[i].max) - { + if (cfg_data[i].value < cfg_data[i].min + || cfg_data[i].value > cfg_data[i].max) cfg_data[i].value = cfg_data[i].def; - } } } @@ -734,8 +615,8 @@ * Mapping from the eeprom delay index value (index into this array) * to the the number of actual seconds that the delay should be for. */ -static -char __initdata eeprom_index_to_delay_map[] = { 1, 3, 5, 10, 16, 30, 60, 120 }; +static char __initdata eeprom_index_to_delay_map[] = + { 1, 3, 5, 10, 16, 30, 60, 120 }; /** @@ -744,25 +625,24 @@ * * @eeprom: The eeprom structure in which we find the delay index to map. **/ -static -void __init eeprom_index_to_delay(struct NvRamType *eeprom) +static void __init eeprom_index_to_delay(struct NvRamType *eeprom) { eeprom->delay_time = eeprom_index_to_delay_map[eeprom->delay_time]; } /** - * delay_to_eeprom_index - Take a delay in seconds and return the closest - * eeprom index which will delay for at least that amount of seconds. + * delay_to_eeprom_index - Take a delay in seconds and return the + * closest eeprom index which will delay for at least that amount of + * seconds. * * @delay: The delay, in seconds, to find the eeprom index for. **/ static int __init delay_to_eeprom_index(int delay) { u8 idx = 0; - while (idx < 7 && eeprom_index_to_delay_map[idx] < delay) { + while (idx < 7 && eeprom_index_to_delay_map[idx] < delay) idx++; - } return idx; } @@ -774,38 +654,34 @@ * * @eeprom: The eeprom data to override with command line options. **/ -static -void __init eeprom_override(struct NvRamType *eeprom) +static void __init eeprom_override(struct NvRamType *eeprom) { u8 id; /* Adapter Settings */ - if (cfg_data[CFG_ADAPTER_ID].value != CFG_PARAM_UNSET) { - eeprom->scsi_id = - (u8)cfg_data[CFG_ADAPTER_ID].value; - } - if (cfg_data[CFG_ADAPTER_MODE].value != CFG_PARAM_UNSET) { - eeprom->channel_cfg = - (u8)cfg_data[CFG_ADAPTER_MODE].value; - } - if (cfg_data[CFG_RESET_DELAY].value != CFG_PARAM_UNSET) { - eeprom->delay_time = - delay_to_eeprom_index(cfg_data[CFG_RESET_DELAY].value); - } - if (cfg_data[CFG_TAGS].value != CFG_PARAM_UNSET) { + if (cfg_data[CFG_ADAPTER_ID].value != CFG_PARAM_UNSET) + eeprom->scsi_id = (u8)cfg_data[CFG_ADAPTER_ID].value; + + if (cfg_data[CFG_ADAPTER_MODE].value != CFG_PARAM_UNSET) + eeprom->channel_cfg = (u8)cfg_data[CFG_ADAPTER_MODE].value; + + if (cfg_data[CFG_RESET_DELAY].value != CFG_PARAM_UNSET) + eeprom->delay_time = delay_to_eeprom_index( + cfg_data[CFG_RESET_DELAY].value); + + if (cfg_data[CFG_TAGS].value != CFG_PARAM_UNSET) eeprom->max_tag = (u8)cfg_data[CFG_TAGS].value; - } /* Device Settings */ for (id = 0; id < DC395x_MAX_SCSI_ID; id++) { - if (cfg_data[CFG_DEV_MODE].value != CFG_PARAM_UNSET) { + if (cfg_data[CFG_DEV_MODE].value != CFG_PARAM_UNSET) eeprom->target[id].cfg0 = - (u8)cfg_data[CFG_DEV_MODE].value; - } - if (cfg_data[CFG_MAX_SPEED].value != CFG_PARAM_UNSET) { + (u8)cfg_data[CFG_DEV_MODE].value; + + if (cfg_data[CFG_MAX_SPEED].value != CFG_PARAM_UNSET) eeprom->target[id].period = - (u8)cfg_data[CFG_MAX_SPEED].value; - } + (u8)cfg_data[CFG_MAX_SPEED].value; + } } @@ -813,39 +689,21 @@ /*--------------------------------------------------------------------------- ---------------------------------------------------------------------------*/ -/** - * list_size - Returns the size (in number of entries) of the - * supplied list. - * - * @head: The pointer to the head of the list to count the items in. - **/ -static -unsigned int list_size(struct list_head *head) +static unsigned int list_size(struct list_head *head) { unsigned int count = 0; struct list_head *pos; list_for_each(pos, head) count++; return count; -} +} -/** - * dcb_get_next - Given a dcb return the next dcb in the list of - * dcb's, wrapping back to the start of the dcb list if required. - * Returns the supplied dcb if there is only one dcb in the list. - * - * @head: The pointer to the head of the list to count the items in. - * @pos: The pointer the dcb for which we are searching for the - * following dcb. - **/ -static -struct DeviceCtlBlk *dcb_get_next( - struct list_head *head, +static struct DeviceCtlBlk *dcb_get_next(struct list_head *head, struct DeviceCtlBlk *pos) { int use_next = 0; - struct DeviceCtlBlk* next = NULL; + struct DeviceCtlBlk* next = NULL; struct DeviceCtlBlk* i; if (list_empty(head)) @@ -870,22 +728,7 @@ } -/* - * Queueing philosphy: - * There are a couple of lists: - * - Waiting: Contains a list of SRBs not yet sent (per DCB) - * - Free: List of free SRB slots - * - * If there are no waiting commands for the DCB, the new one is sent to the bus - * otherwise the oldest one is taken from the Waiting list and the new one is - * queued to the Waiting List - * - * Lists are managed using two pointers and eventually a counter - */ - -/* Nomen est omen ... */ -static inline -void free_tag(struct DeviceCtlBlk *dcb, struct ScsiReqBlk *srb) +static void free_tag(struct DeviceCtlBlk *dcb, struct ScsiReqBlk *srb) { if (srb->tag_number < 255) { dcb->tag_mask &= ~(1 << srb->tag_number); /* free tag mask */ @@ -895,9 +738,8 @@ /* Find cmd in SRB list */ -inline static -struct ScsiReqBlk *find_cmd(Scsi_Cmnd *cmd, - struct list_head *head) +inline static struct ScsiReqBlk *find_cmd(Scsi_Cmnd *cmd, + struct list_head *head) { struct ScsiReqBlk *i; list_for_each_entry(i, head, list) @@ -907,88 +749,59 @@ } -/* - * srb_get_free - Return a free srb from the list of free SRBs that - * is stored with the acb. - */ -static -struct ScsiReqBlk *srb_get_free(struct AdapterCtlBlk *acb) +static struct ScsiReqBlk *srb_get_free(struct AdapterCtlBlk *acb) { struct list_head *head = &acb->srb_free_list; - struct ScsiReqBlk *srb; + struct ScsiReqBlk *srb = NULL; if (!list_empty(head)) { srb = list_entry(head->next, struct ScsiReqBlk, list); list_del(head->next); - dprintkdbg(DBG_0, "srb_get_free: got srb %p\n", srb); - } else { - srb = NULL; - dprintkl(KERN_ERR, "Out of Free SRBs :-(\n"); + dprintkdbg(DBG_0, "srb_get_free: srb=%p\n", srb); } return srb; } -/* - * srb_free_insert - Insert an srb to the head of the free list - * stored in the acb. - */ -static -void srb_free_insert(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb) +static void srb_free_insert(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb) { - dprintkdbg(DBG_0, "srb_free_insert: put srb %p\n", srb); - list_add_tail(&srb->list, &acb->srb_free_list); + dprintkdbg(DBG_0, "srb_free_insert: srb=%p\n", srb); + list_add_tail(&srb->list, &acb->srb_free_list); } -/* - * srb_waiting_insert - Insert an srb to the head of the wiating list - * stored in the dcb. - */ -static -void srb_waiting_insert(struct DeviceCtlBlk *dcb, struct ScsiReqBlk *srb) +static void srb_waiting_insert(struct DeviceCtlBlk *dcb, + struct ScsiReqBlk *srb) { - dprintkdbg(DBG_0, "srb_waiting_insert: srb %p cmd %li\n", srb, srb->cmd->pid); - list_add(&srb->list, &dcb->srb_waiting_list); + dprintkdbg(DBG_0, "srb_waiting_insert: (pid#%li) <%02i-%i> srb=%p\n", + srb->cmd->pid, dcb->target_id, dcb->target_lun, srb); + list_add(&srb->list, &dcb->srb_waiting_list); } -/* - * srb_waiting_append - Append an srb to the tail of the waiting list - * stored in the dcb. - */ -static inline -void srb_waiting_append(struct DeviceCtlBlk *dcb, struct ScsiReqBlk *srb) +static void srb_waiting_append(struct DeviceCtlBlk *dcb, + struct ScsiReqBlk *srb) { - dprintkdbg(DBG_0, "srb_waiting_append: srb %p cmd %li\n", srb, srb->cmd->pid); - list_add_tail(&srb->list, &dcb->srb_waiting_list); + dprintkdbg(DBG_0, "srb_waiting_append: (pid#%li) <%02i-%i> srb=%p\n", + srb->cmd->pid, dcb->target_id, dcb->target_lun, srb); + list_add_tail(&srb->list, &dcb->srb_waiting_list); } -/* - * srb_going_append - Append an srb to the tail of the going list - * stored in the dcb. - */ -static inline -void srb_going_append(struct DeviceCtlBlk *dcb, struct ScsiReqBlk *srb) +static void srb_going_append(struct DeviceCtlBlk *dcb, struct ScsiReqBlk *srb) { - dprintkdbg(DBG_0, "srb_going_append: srb %p\n", srb); - list_add_tail(&srb->list, &dcb->srb_going_list); + dprintkdbg(DBG_0, "srb_going_append: (pid#%li) <%02i-%i> srb=%p\n", + srb->cmd->pid, dcb->target_id, dcb->target_lun, srb); + list_add_tail(&srb->list, &dcb->srb_going_list); } - -/* - * srb_going_remove - Remove an srb from the going list stored in the - * dcb. - */ -static -void srb_going_remove(struct DeviceCtlBlk *dcb, - struct ScsiReqBlk *srb) +static void srb_going_remove(struct DeviceCtlBlk *dcb, struct ScsiReqBlk *srb) { struct ScsiReqBlk *i; struct ScsiReqBlk *tmp; - dprintkdbg(DBG_0, "srb_going_remove: srb %p\n", srb); + dprintkdbg(DBG_0, "srb_going_remove: (pid#%li) <%02i-%i> srb=%p\n", + srb->cmd->pid, dcb->target_id, dcb->target_lun, srb); list_for_each_entry_safe(i, tmp, &dcb->srb_going_list, list) if (i == srb) { @@ -998,17 +811,13 @@ } -/* - * srb_waiting_remove - Remove an srb from the waiting list stored in the - * dcb. - */ -static -void srb_waiting_remove(struct DeviceCtlBlk *dcb, - struct ScsiReqBlk *srb) +static void srb_waiting_remove(struct DeviceCtlBlk *dcb, + struct ScsiReqBlk *srb) { struct ScsiReqBlk *i; struct ScsiReqBlk *tmp; - dprintkdbg(DBG_0, "srb_waiting_remove: srb %p\n", srb); + dprintkdbg(DBG_0, "srb_waiting_remove: (pid#%li) <%02i-%i> srb=%p\n", + srb->cmd->pid, dcb->target_id, dcb->target_lun, srb); list_for_each_entry_safe(i, tmp, &dcb->srb_waiting_list, list) if (i == srb) { @@ -1018,37 +827,28 @@ } -/* - * srb_going_to_waiting_move - Remove an srb from the going list in - * the dcb and insert it at the head of the waiting list in the dcb. - */ -static -void srb_going_to_waiting_move(struct DeviceCtlBlk *dcb, - struct ScsiReqBlk *srb) +static void srb_going_to_waiting_move(struct DeviceCtlBlk *dcb, + struct ScsiReqBlk *srb) { - dprintkdbg(DBG_0, "srb_going_waiting_move: srb %p, pid = %li\n", srb, srb->cmd->pid); + dprintkdbg(DBG_0, + "srb_going_to_waiting_move: (pid#%li) <%02i-%i> srb=%p\n", + srb->cmd->pid, dcb->target_id, dcb->target_lun, srb); list_move(&srb->list, &dcb->srb_waiting_list); } -/* - * srb_waiting_to_going_move - Remove an srb from the waiting list in - * the dcb and insert it at the head of the going list in the dcb. - */ -static -void srb_waiting_to_going_move(struct DeviceCtlBlk *dcb, - struct ScsiReqBlk *srb) -{ - /* Remove from waiting list */ - dprintkdbg(DBG_0, "srb_waiting_to_going: srb %p\n", srb); - TRACEPRINTF("WtG *"); +static void srb_waiting_to_going_move(struct DeviceCtlBlk *dcb, + struct ScsiReqBlk *srb) +{ + dprintkdbg(DBG_0, + "srb_waiting_to_going_move: (pid#%li) <%02i-%i> srb=%p\n", + srb->cmd->pid, dcb->target_id, dcb->target_lun, srb); list_move(&srb->list, &dcb->srb_going_list); } /* Sets the timer to wake us up */ -static -void waiting_set_timer(struct AdapterCtlBlk *acb, unsigned long to) +static void waiting_set_timer(struct AdapterCtlBlk *acb, unsigned long to) { if (timer_pending(&acb->waiting_timer)) return; @@ -1065,8 +865,7 @@ /* Send the next command from the waiting list to the bus */ -static -void waiting_process_next(struct AdapterCtlBlk *acb) +static void waiting_process_next(struct AdapterCtlBlk *acb) { struct DeviceCtlBlk *start = NULL; struct DeviceCtlBlk *pos; @@ -1074,7 +873,7 @@ struct ScsiReqBlk *srb; struct list_head *dcb_list_head = &acb->dcb_list; - if ((acb->active_dcb) + if (acb->active_dcb || (acb->acb_flag & (RESET_DETECT + RESET_DONE + RESET_DEV))) return; @@ -1135,8 +934,9 @@ static void waiting_timeout(unsigned long ptr) { unsigned long flags; - struct AdapterCtlBlk *acb = (struct AdapterCtlBlk *) ptr; - dprintkdbg(DBG_KG, "Debug: Waiting queue woken up by timer.\n"); + struct AdapterCtlBlk *acb = (struct AdapterCtlBlk *)ptr; + dprintkdbg(DBG_1, + "waiting_timeout: Queue woken up by timer. acb=%p\n", acb); DC395x_LOCK_IO(acb->scsi_host, flags); waiting_process_next(acb); DC395x_UNLOCK_IO(acb->scsi_host, flags); @@ -1144,28 +944,17 @@ /* Get the DCB for a given ID/LUN combination */ -static inline -struct DeviceCtlBlk *find_dcb(struct AdapterCtlBlk *acb, u8 id, u8 lun) +static struct DeviceCtlBlk *find_dcb(struct AdapterCtlBlk *acb, u8 id, u8 lun) { return acb->children[id][lun]; } -/*********************************************************************** - * Function: static void send_srb (struct AdapterCtlBlk* acb, struct ScsiReqBlk* srb) - * - * Purpose: Send SCSI Request Block (srb) to adapter (acb) - * - * dc395x_queue_command - * waiting_process_next - * - ***********************************************************************/ -static -void send_srb(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb) +/* Send SCSI Request Block (srb) to adapter (acb) */ +static void send_srb(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb) { - struct DeviceCtlBlk *dcb; + struct DeviceCtlBlk *dcb = srb->dcb; - dcb = srb->dcb; if (dcb->max_command <= list_size(&dcb->srb_going_list) || acb->active_dcb || (acb->acb_flag & (RESET_DETECT + RESET_DONE + RESET_DEV))) { @@ -1174,130 +963,29 @@ return; } - if (!start_scsi(acb, dcb, srb)) { + if (!start_scsi(acb, dcb, srb)) srb_going_append(dcb, srb); - } else { + else { srb_waiting_insert(dcb, srb); waiting_set_timer(acb, HZ / 50); } } -/* - ********************************************************************* - * - * Function: static void build_srb (Scsi_Cmd *cmd, struct DeviceCtlBlk* dcb, struct ScsiReqBlk* srb) - * - * Purpose: Prepare SRB for being sent to Device DCB w/ command *cmd - * - ********************************************************************* - */ -static -void build_srb(Scsi_Cmnd * cmd, struct DeviceCtlBlk *dcb, - struct ScsiReqBlk *srb) -{ - int i, max; - struct SGentry *sgp; - struct scatterlist *sl; - u32 request_size; - int dir; +/* Prepare SRB for being sent to Device DCB w/ command *cmd */ +static void build_srb(Scsi_Cmnd *cmd, struct DeviceCtlBlk *dcb, + struct ScsiReqBlk *srb) +{ + int dir = scsi_to_pci_dma_dir(cmd->sc_data_direction); + dprintkdbg(DBG_0, "build_srb: (pid#%li) <%02i-%i>\n", + cmd->pid, dcb->target_id, dcb->target_lun); - dprintkdbg(DBG_0, "build_srb..............\n"); - /*memset (srb, 0, sizeof (struct ScsiReqBlk)); */ srb->dcb = dcb; srb->cmd = cmd; - /* Find out about direction */ - dir = scsi_to_pci_dma_dir(cmd->sc_data_direction); - - if (cmd->use_sg && dir != PCI_DMA_NONE) { - unsigned int len = 0; - /* TODO: In case usg_sg and the no of segments differ, things - * will probably go wrong. */ - max = srb->sg_count = - pci_map_sg(dcb->acb->dev, - (struct scatterlist *) cmd->request_buffer, - cmd->use_sg, dir); - sgp = srb->segment_x; - request_size = cmd->request_bufflen; - dprintkdbg(DBG_SGPARANOIA, - "BuildSRB: Bufflen = %d, buffer = %p, use_sg = %d\n", - cmd->request_bufflen, cmd->request_buffer, - cmd->use_sg); - dprintkdbg(DBG_SGPARANOIA, - "Mapped %i Segments to %i\n", cmd->use_sg, - srb->sg_count); - sl = (struct scatterlist *) cmd->request_buffer; - - srb->virt_addr = page_address(sl->page); - for (i = 0; i < max; i++) { - u32 busaddr = (u32) sg_dma_address(&sl[i]); - u32 seglen = (u32) sl[i].length; - sgp[i].address = busaddr; - sgp[i].length = seglen; - len += seglen; - dprintkdbg(DBG_SGPARANOIA, - "Setting up sgp %d, address = 0x%08x, length = %d, tot len = %d\n", - i, busaddr, seglen, len); - } - sgp += max - 1; - /* Fixup for last buffer too big as it is allocated on even page boundaries */ - if (len > request_size) { -#if debug_enabled(DBG_KG) || debug_enabled(DBG_SGPARANOIA) - dprintkdbg(DBG_KG|DBG_SGPARANOIA, - "Fixup SG total length: %d->%d, last seg %d->%d\n", - len, request_size, sgp->length, - sgp->length - (len - request_size)); -#endif - sgp->length -= (len - request_size); - len = request_size; - } - /* WIDE padding */ - if (dcb->sync_period & WIDE_SYNC && len % 2) { - len++; - sgp->length++; - } - srb->total_xfer_length = len; /*? */ - /* Hopefully this does not cross a page boundary ... */ - srb->sg_bus_addr = - pci_map_single(dcb->acb->dev, srb->segment_x, - sizeof(struct SGentry) * - DC395x_MAX_SG_LISTENTRY, - PCI_DMA_TODEVICE); - dprintkdbg(DBG_SGPARANOIA, - "Map SG descriptor list %p (%05x) to %08x\n", - srb->segment_x, - sizeof(struct SGentry) * DC395x_MAX_SG_LISTENTRY, - srb->sg_bus_addr); - } else { - if (cmd->request_buffer && dir != PCI_DMA_NONE) { - u32 len = cmd->request_bufflen; /* Actual request size */ - srb->sg_count = 1; - srb->segment_x[0].address = - pci_map_single(dcb->acb->dev, - cmd->request_buffer, len, dir); - /* WIDE padding */ - if (dcb->sync_period & WIDE_SYNC && len % 2) - len++; - srb->segment_x[0].length = len; - srb->total_xfer_length = len; - srb->virt_addr = cmd->request_buffer; - srb->sg_bus_addr = 0; - dprintkdbg(DBG_SGPARANOIA, - "BuildSRB: len = %d, buffer = %p, use_sg = %d, map %08x\n", - len, cmd->request_buffer, cmd->use_sg, - srb->segment_x[0].address); - } else { - srb->sg_count = 0; - srb->total_xfer_length = 0; - srb->sg_bus_addr = 0; - srb->virt_addr = 0; - dprintkdbg(DBG_SGPARANOIA, - "BuildSRB: buflen = %d, buffer = %p, use_sg = %d, NOMAP %08x\n", - cmd->bufflen, cmd->request_buffer, - cmd->use_sg, srb->segment_x[0].address); - } - } - + srb->sg_count = 0; + srb->total_xfer_length = 0; + srb->sg_bus_addr = 0; + srb->virt_addr = 0; srb->sg_index = 0; srb->adapter_status = 0; srb->target_status = 0; @@ -1306,29 +994,80 @@ srb->flag = 0; srb->state = 0; srb->retry_count = 0; - -#if debug_enabled(DBG_TRACE|DBG_TRACEALL) && debug_enabled(DBG_SGPARANOIA) - if ((unsigned long)srb->debugtrace & (DEBUGTRACEBUFSZ - 1)) { - dprintkdbg(DBG_SGPARANOIA, - "SRB %i (%p): debugtrace %p corrupt!\n", - (srb - dcb->acb->srb_array) / - sizeof(struct ScsiReqBlk), srb, srb->debugtrace); - } -#endif -#if debug_enabled(DBG_TRACE|DBG_TRACEALL) - srb->debugpos = 0; - srb->debugtrace = 0; -#endif - TRACEPRINTF("pid %li(%li):%02x %02x..(%i-%i) *", cmd->pid, - jiffies, cmd->cmnd[0], cmd->cmnd[1], - cmd->device->id, cmd->device->lun); srb->tag_number = TAG_NONE; - srb->scsi_phase = PH_BUS_FREE; /* initial phase */ srb->end_message = 0; - return; -} + if (dir == PCI_DMA_NONE || !cmd->request_buffer) { + dprintkdbg(DBG_0, + "build_srb: [0] len=%d buf=%p use_sg=%d !MAP=%08x\n", + cmd->bufflen, cmd->request_buffer, + cmd->use_sg, srb->segment_x[0].address); + } else if (cmd->use_sg) { + int i; + u32 reqlen = cmd->request_bufflen; + struct scatterlist *sl = (struct scatterlist *) + cmd->request_buffer; + struct SGentry *sgp = srb->segment_x; + srb->sg_count = pci_map_sg(dcb->acb->dev, sl, cmd->use_sg, + dir); + dprintkdbg(DBG_0, + "build_srb: [n] len=%d buf=%p use_sg=%d segs=%d\n", + reqlen, cmd->request_buffer, cmd->use_sg, + srb->sg_count); + + srb->virt_addr = page_address(sl->page); + for (i = 0; i < srb->sg_count; i++) { + u32 busaddr = (u32)sg_dma_address(&sl[i]); + u32 seglen = (u32)sl[i].length; + sgp[i].address = busaddr; + sgp[i].length = seglen; + srb->total_xfer_length += seglen; + } + sgp += srb->sg_count - 1; + + /* + * adjust last page if too big as it is allocated + * on even page boundaries + */ + if (srb->total_xfer_length > reqlen) { + sgp->length -= (srb->total_xfer_length - reqlen); + srb->total_xfer_length = reqlen; + } + + /* Fixup for WIDE padding - make sure length is even */ + if (dcb->sync_period & WIDE_SYNC && + srb->total_xfer_length % 2) { + srb->total_xfer_length++; + sgp->length++; + } + + srb->sg_bus_addr = pci_map_single(dcb->acb->dev, + srb->segment_x, + SEGMENTX_LEN, + PCI_DMA_TODEVICE); + + dprintkdbg(DBG_SG, "build_srb: [n] map sg %p->%08x(%05x)\n", + srb->segment_x, srb->sg_bus_addr, SEGMENTX_LEN); + } else { + srb->total_xfer_length = cmd->request_bufflen; + srb->sg_count = 1; + srb->segment_x[0].address = + pci_map_single(dcb->acb->dev, cmd->request_buffer, + srb->total_xfer_length, dir); + + /* Fixup for WIDE padding - make sure length is even */ + if (dcb->sync_period & WIDE_SYNC && srb->total_xfer_length % 2) + srb->total_xfer_length++; + + srb->segment_x[0].length = srb->total_xfer_length; + srb->virt_addr = cmd->request_buffer; + dprintkdbg(DBG_0, + "build_srb: [1] len=%d buf=%p use_sg=%d map=%08x\n", + srb->total_xfer_length, cmd->request_buffer, + cmd->use_sg, srb->segment_x[0].address); + } +} /** @@ -1350,27 +1089,14 @@ * and is expected to be held on return. * **/ -static int -dc395x_queue_command(Scsi_Cmnd *cmd, void (*done)(Scsi_Cmnd *)) +static int dc395x_queue_command(Scsi_Cmnd *cmd, void (*done)(Scsi_Cmnd *)) { struct DeviceCtlBlk *dcb; struct ScsiReqBlk *srb; struct AdapterCtlBlk *acb = (struct AdapterCtlBlk *)cmd->device->host->hostdata; - - dprintkdbg(DBG_0, "Queue Cmd=%02x,Tgt=%d,LUN=%d (pid=%li)\n", - cmd->cmnd[0], - cmd->device->id, - cmd->device->lun, - cmd->pid); - -#if debug_enabled(DBG_RECURSION) - if (dbg_in_driver++ > NORM_REC_LVL) { - dprintkl(KERN_DEBUG, - "%i queue_command () recursion? (pid=%li)\n", - dbg_in_driver, cmd->pid); - } -#endif + dprintkdbg(DBG_0, "queue_command: (pid#%li) <%02i-%i> cmnd=0x%02x\n", + cmd->pid, cmd->device->id, cmd->device->lun, cmd->cmnd[0]); /* Assume BAD_TARGET; will be cleared later */ cmd->result = DID_BAD_TARGET << 16; @@ -1384,8 +1110,8 @@ /* does the specified lun on the specified device exist */ if (!(acb->dcb_map[cmd->device->id] & (1 << cmd->device->lun))) { - dprintkl(KERN_INFO, "Ignore target %02x lun %02x\n", cmd->device->id, - cmd->device->lun); + dprintkl(KERN_INFO, "queue_command: Ignore target <%02i-%i>\n", + cmd->device->id, cmd->device->lun); goto complete; } @@ -1393,9 +1119,8 @@ dcb = find_dcb(acb, cmd->device->id, cmd->device->lun); if (!dcb) { /* should never happen */ - dprintkl(KERN_ERR, "no DCB failed, target %02x lun %02x\n", - cmd->device->id, cmd->device->lun); - dprintkl(KERN_ERR, "No DCB in queuecommand (2)!\n"); + dprintkl(KERN_ERR, "queue_command: No such device <%02i-%i>", + cmd->device->id, cmd->device->lun); goto complete; } @@ -1403,7 +1128,6 @@ cmd->scsi_done = done; cmd->result = 0; - /* get a free SRB */ srb = srb_get_free(acb); if (!srb) { @@ -1411,11 +1135,10 @@ * Return 1 since we are unable to queue this command at this * point in time. */ - dprintkdbg(DBG_0, "No free SRB's in queuecommand\n"); + dprintkdbg(DBG_0, "queue_command: No free srb's\n"); return 1; } - /* build srb for the command */ build_srb(cmd, dcb, srb); if (!list_empty(&dcb->srb_waiting_list)) { @@ -1426,11 +1149,7 @@ /* process immediately */ send_srb(acb, srb); } - dprintkdbg(DBG_1, "... command (pid %li) queued successfully.\n", cmd->pid); - -#if debug_enabled(DBG_RECURSION) - dbg_in_driver-- -#endif + dprintkdbg(DBG_1, "queue_command: (pid#%li) done\n", cmd->pid); return 0; complete: @@ -1440,28 +1159,16 @@ * done when the commad is for things like non existent * devices. */ -#if debug_enabled(DBG_RECURSION) - dbg_in_driver-- -#endif done(cmd); return 0; } - - /* - ********************************************************************* - * - * Function : dc395x_bios_param - * Description: Return the disk geometry for the given SCSI device. - ********************************************************************* + * Return the disk geometry for the given SCSI device. */ -static -int dc395x_bios_param(struct scsi_device *sdev, - struct block_device *bdev, - sector_t capacity, - int *info) +static int dc395x_bios_param(struct scsi_device *sdev, + struct block_device *bdev, sector_t capacity, int *info) { #ifdef CONFIG_SCSI_DC395x_TRMS1040_TRADMAP int heads, sectors, cylinders; @@ -1469,7 +1176,7 @@ int size = capacity; dprintkdbg(DBG_0, "dc395x_bios_param..............\n"); - acb = (struct AdapterCtlBlk *) sdev->host->hostdata; + acb = (struct AdapterCtlBlk *)sdev->host->hostdata; heads = 64; sectors = 32; cylinders = size / (heads * sectors); @@ -1489,12 +1196,8 @@ } -/* - * DC395x register dump - */ -static -void dump_register_info(struct AdapterCtlBlk *acb, struct DeviceCtlBlk *dcb, - struct ScsiReqBlk *srb) +static void dump_register_info(struct AdapterCtlBlk *acb, + struct DeviceCtlBlk *dcb, struct ScsiReqBlk *srb) { u16 pstat; struct pci_dev *dev = acb->dev; @@ -1504,64 +1207,58 @@ if (!srb && dcb) srb = dcb->active_srb; if (srb) { - if (!(srb->cmd)) - dprintkl(KERN_INFO, "dump: SRB %p: cmd %p OOOPS!\n", srb, - srb->cmd); + if (!srb->cmd) + dprintkl(KERN_INFO, "dump: srb=%p cmd=%p OOOPS!\n", + srb, srb->cmd); else - dprintkl(KERN_INFO, "dump: SRB %p: cmd %p pid %li: %02x (%02i-%i)\n", - srb, srb->cmd, srb->cmd->pid, - srb->cmd->cmnd[0], srb->cmd->device->id, - srb->cmd->device->lun); - printk(" SGList %p Cnt %i Idx %i Len %i\n", + dprintkl(KERN_INFO, "dump: srb=%p cmd=%p (pid#%li) " + "cmnd=0x%02x <%02i-%i>\n", + srb, srb->cmd, srb->cmd->pid, + srb->cmd->cmnd[0], srb->cmd->device->id, + srb->cmd->device->lun); + printk(" sglist=%p cnt=%i idx=%i len=%i\n", srb->segment_x, srb->sg_count, srb->sg_index, srb->total_xfer_length); - printk - (" State %04x Status %02x Phase %02x (%sconn.)\n", - srb->state, srb->status, srb->scsi_phase, - (acb->active_dcb) ? "" : "not"); - TRACEOUT(" %s\n", srb->debugtrace); - } - dprintkl(KERN_INFO, "dump: SCSI block\n"); - printk - (" Status %04x FIFOCnt %02x Signals %02x IRQStat %02x\n", - DC395x_read16(acb, TRM_S1040_SCSI_STATUS), - DC395x_read8(acb, TRM_S1040_SCSI_FIFOCNT), - DC395x_read8(acb, TRM_S1040_SCSI_SIGNAL), - DC395x_read8(acb, TRM_S1040_SCSI_INTSTATUS)); - printk - (" Sync %02x Target %02x RSelID %02x SCSICtr %08x\n", - DC395x_read8(acb, TRM_S1040_SCSI_SYNC), - DC395x_read8(acb, TRM_S1040_SCSI_TARGETID), - DC395x_read8(acb, TRM_S1040_SCSI_IDMSG), - DC395x_read32(acb, TRM_S1040_SCSI_COUNTER)); - printk - (" IRQEn %02x Config %04x Cfg2 %02x Cmd %02x SelTO %02x\n", - DC395x_read8(acb, TRM_S1040_SCSI_INTEN), - DC395x_read16(acb, TRM_S1040_SCSI_CONFIG0), - DC395x_read8(acb, TRM_S1040_SCSI_CONFIG2), - DC395x_read8(acb, TRM_S1040_SCSI_COMMAND), - DC395x_read8(acb, TRM_S1040_SCSI_TIMEOUT)); - dprintkl(KERN_INFO, "dump: DMA block\n"); - printk - (" Cmd %04x FIFOCnt %02x FStat %02x IRQStat %02x IRQEn %02x Cfg %04x\n", - DC395x_read16(acb, TRM_S1040_DMA_COMMAND), - DC395x_read8(acb, TRM_S1040_DMA_FIFOCNT), - DC395x_read8(acb, TRM_S1040_DMA_FIFOSTAT), - DC395x_read8(acb, TRM_S1040_DMA_STATUS), - DC395x_read8(acb, TRM_S1040_DMA_INTEN), - DC395x_read16(acb, TRM_S1040_DMA_CONFIG)); - printk(" TCtr %08x CTCtr %08x Addr %08x%08x\n", - DC395x_read32(acb, TRM_S1040_DMA_XCNT), - DC395x_read32(acb, TRM_S1040_DMA_CXCNT), - DC395x_read32(acb, TRM_S1040_DMA_XHIGHADDR), - DC395x_read32(acb, TRM_S1040_DMA_XLOWADDR)); - dprintkl(KERN_INFO, "dump: Misc: GCtrl %02x GStat %02x GTmr %02x\n", - DC395x_read8(acb, TRM_S1040_GEN_CONTROL), - DC395x_read8(acb, TRM_S1040_GEN_STATUS), - DC395x_read8(acb, TRM_S1040_GEN_TIMER)); - dprintkl(KERN_INFO, "dump: PCI Status %04x\n", pstat); - - + printk(" state=0x%04x status=0x%02x phase=0x%02x (%sconn.)\n", + srb->state, srb->status, srb->scsi_phase, + (acb->active_dcb) ? "" : "not"); + } + dprintkl(KERN_INFO, "dump: SCSI{status=0x%04x fifocnt=0x%02x " + "signals=0x%02x irqstat=0x%02x sync=0x%02x target=0x%02x " + "rselid=0x%02x ctr=0x%08x irqen=0x%02x config=0x%04x " + "config2=0x%02x cmd=0x%02x selto=0x%02x}\n", + DC395x_read16(acb, TRM_S1040_SCSI_STATUS), + DC395x_read8(acb, TRM_S1040_SCSI_FIFOCNT), + DC395x_read8(acb, TRM_S1040_SCSI_SIGNAL), + DC395x_read8(acb, TRM_S1040_SCSI_INTSTATUS), + DC395x_read8(acb, TRM_S1040_SCSI_SYNC), + DC395x_read8(acb, TRM_S1040_SCSI_TARGETID), + DC395x_read8(acb, TRM_S1040_SCSI_IDMSG), + DC395x_read32(acb, TRM_S1040_SCSI_COUNTER), + DC395x_read8(acb, TRM_S1040_SCSI_INTEN), + DC395x_read16(acb, TRM_S1040_SCSI_CONFIG0), + DC395x_read8(acb, TRM_S1040_SCSI_CONFIG2), + DC395x_read8(acb, TRM_S1040_SCSI_COMMAND), + DC395x_read8(acb, TRM_S1040_SCSI_TIMEOUT)); + dprintkl(KERN_INFO, "dump: DMA{cmd=0x%04x fifocnt=0x%02x fstat=0x%02x " + "irqstat=0x%02x irqen=0x%02x cfg=0x%04x tctr=0x%08x " + "ctctr=0x%08x addr=0x%08x:0x%08x}\n", + DC395x_read16(acb, TRM_S1040_DMA_COMMAND), + DC395x_read8(acb, TRM_S1040_DMA_FIFOCNT), + DC395x_read8(acb, TRM_S1040_DMA_FIFOSTAT), + DC395x_read8(acb, TRM_S1040_DMA_STATUS), + DC395x_read8(acb, TRM_S1040_DMA_INTEN), + DC395x_read16(acb, TRM_S1040_DMA_CONFIG), + DC395x_read32(acb, TRM_S1040_DMA_XCNT), + DC395x_read32(acb, TRM_S1040_DMA_CXCNT), + DC395x_read32(acb, TRM_S1040_DMA_XHIGHADDR), + DC395x_read32(acb, TRM_S1040_DMA_XLOWADDR)); + dprintkl(KERN_INFO, "dump: gen{gctrl=0x%02x gstat=0x%02x gtmr=0x%02x} " + "pci{status=0x%04x}\n", + DC395x_read8(acb, TRM_S1040_GEN_CONTROL), + DC395x_read8(acb, TRM_S1040_GEN_STATUS), + DC395x_read8(acb, TRM_S1040_GEN_TIMER), + pstat); } @@ -1572,32 +1269,19 @@ u8 fifocnt = DC395x_read8(acb, TRM_S1040_SCSI_FIFOCNT); if (!(fifocnt & 0x40)) dprintkdbg(DBG_FIFO, - "Clr FIFO (%i bytes) on phase %02x in %s\n", + "clear_fifo: (%i bytes) on phase %02x in %s\n", fifocnt & 0x3f, lines, txt); #endif -#if debug_enabled(DBG_TRACE) - if (acb->active_dcb && acb->active_dcb->active_srb) { - struct ScsiReqBlk *srb = acb->active_dcb->active_srb; - TRACEPRINTF("#*"); - } -#endif DC395x_write16(acb, TRM_S1040_SCSI_CONTROL, DO_CLRFIFO); } -/* - ******************************************************************** - * - * DC395x_reset scsi_reset_detect - * - ******************************************************************** - */ static void reset_dev_param(struct AdapterCtlBlk *acb) { struct DeviceCtlBlk *dcb; struct NvRamType *eeprom = &acb->eeprom; + dprintkdbg(DBG_0, "reset_dev_param: acb=%p\n", acb); - dprintkdbg(DBG_0, "reset_dev_param..............\n"); list_for_each_entry(dcb, &acb->dcb_list, list) { u8 period_index; @@ -1616,22 +1300,17 @@ /* - ********************************************************************* - * Function : int dc395x_eh_bus_reset(Scsi_Cmnd *cmd) - * Purpose : perform a hard reset on the SCSI bus - * Inputs : cmd - some command for this host (for fetching hooks) - * Returns : SUCCESS (0x2002) on success, else FAILED (0x2003). - ********************************************************************* + * perform a hard reset on the SCSI bus + * @cmd - some command for this host (for fetching hooks) + * Returns: SUCCESS (0x2002) on success, else FAILED (0x2003). */ -static int dc395x_eh_bus_reset(Scsi_Cmnd * cmd) +static int dc395x_eh_bus_reset(Scsi_Cmnd *cmd) { - struct AdapterCtlBlk *acb; - /*u32 acb_flags=0; */ - - dprintkl(KERN_INFO, "reset requested!\n"); - acb = (struct AdapterCtlBlk *) cmd->device->host->hostdata; - /* mid level guarantees no recursion */ - /*DC395x_ACB_LOCK(acb,acb_flags); */ + struct AdapterCtlBlk *acb = + (struct AdapterCtlBlk *)cmd->device->host->hostdata; + dprintkl(KERN_INFO, + "eh_bus_reset: (pid#%li) target=<%02i-%i> cmd=%p\n", + cmd->pid, cmd->device->id, cmd->device->lun, cmd); if (timer_pending(&acb->waiting_timer)) del_timer(&acb->waiting_timer); @@ -1657,52 +1336,42 @@ */ /* Clear SCSI FIFO */ DC395x_write8(acb, TRM_S1040_DMA_CONTROL, CLRXFIFO); - clear_fifo(acb, "reset"); + clear_fifo(acb, "eh_bus_reset"); /* Delete pending IRQ */ DC395x_read8(acb, TRM_S1040_SCSI_INTSTATUS); set_basic_config(acb); reset_dev_param(acb); doing_srb_done(acb, DID_RESET, cmd, 0); - acb->active_dcb = NULL; - acb->acb_flag = 0; /* RESET_DETECT, RESET_DONE ,RESET_DEV */ waiting_process_next(acb); - /*DC395x_ACB_LOCK(acb,acb_flags); */ return SUCCESS; } /* - ********************************************************************* - * Function : int dc395x_eh_abort(Scsi_Cmnd *cmd) - * Purpose : abort an errant SCSI command - * Inputs : cmd - command to be aborted - * Returns : SUCCESS (0x2002) on success, else FAILED (0x2003). - ********************************************************************* + * abort an errant SCSI command + * @cmd - command to be aborted + * Returns: SUCCESS (0x2002) on success, else FAILED (0x2003). */ -static int dc395x_eh_abort(Scsi_Cmnd * cmd) +static int dc395x_eh_abort(Scsi_Cmnd *cmd) { /* * Look into our command queues: If it has not been sent already, * we remove it and return success. Otherwise fail. */ struct AdapterCtlBlk *acb = - (struct AdapterCtlBlk *) cmd->device->host->hostdata; + (struct AdapterCtlBlk *)cmd->device->host->hostdata; struct DeviceCtlBlk *dcb; struct ScsiReqBlk *srb; - - dprintkl(KERN_INFO, "eh abort: cmd %p (pid %li, %02i-%i) ", - cmd, - cmd->pid, - cmd->device->id, - cmd->device->lun); + dprintkl(KERN_INFO, "eh_abort: (pid#%li) target=<%02i-%i> cmd=%p\n", + cmd->pid, cmd->device->id, cmd->device->lun, cmd); dcb = find_dcb(acb, cmd->device->id, cmd->device->lun); if (!dcb) { - dprintkl(KERN_DEBUG, "abort - no DCB found"); + dprintkl(KERN_DEBUG, "eh_abort: No such device\n"); return FAILED; } @@ -1713,32 +1382,31 @@ pci_unmap_srb(acb, srb); free_tag(dcb, srb); srb_free_insert(acb, srb); - dprintkl(KERN_DEBUG, "abort - command found in waiting commands queue"); + dprintkl(KERN_DEBUG, "eh_abort: Command was waiting\n"); cmd->result = DID_ABORT << 16; return SUCCESS; } srb = find_cmd(cmd, &dcb->srb_going_list); if (srb) { - dprintkl(KERN_DEBUG, "abort - command currently in progress"); + dprintkl(KERN_DEBUG, "eh_abort: Command in progress"); /* XXX: Should abort the command here */ } else { - dprintkl(KERN_DEBUG, "abort - command not found"); + dprintkl(KERN_DEBUG, "eh_abort: Command not found"); } return FAILED; } /* SDTR */ -static -void build_sdtr(struct AdapterCtlBlk *acb, struct DeviceCtlBlk *dcb, +static void build_sdtr(struct AdapterCtlBlk *acb, struct DeviceCtlBlk *dcb, struct ScsiReqBlk *srb) { u8 *ptr = srb->msgout_buf + srb->msg_count; if (srb->msg_count > 1) { dprintkl(KERN_INFO, - "Build_SDTR: msgout_buf BUSY (%i: %02x %02x)\n", - srb->msg_count, srb->msgout_buf[0], - srb->msgout_buf[1]); + "build_sdtr: msgout_buf BUSY (%i: %02x %02x)\n", + srb->msg_count, srb->msgout_buf[0], + srb->msgout_buf[1]); return; } if (!(dcb->dev_mode & NTC_DO_SYNC_NEGO)) { @@ -1754,25 +1422,21 @@ *ptr++ = dcb->sync_offset; /* Transfer period (max. REQ/ACK dist) */ srb->msg_count += 5; srb->state |= SRB_DO_SYNC_NEGO; - TRACEPRINTF("S *"); } -/* SDTR */ -static -void build_wdtr(struct AdapterCtlBlk *acb, struct DeviceCtlBlk *dcb, +/* WDTR */ +static void build_wdtr(struct AdapterCtlBlk *acb, struct DeviceCtlBlk *dcb, struct ScsiReqBlk *srb) { - u8 wide = - ((dcb->dev_mode & NTC_DO_WIDE_NEGO) & (acb-> - config & HCC_WIDE_CARD)) - ? 1 : 0; + u8 wide = ((dcb->dev_mode & NTC_DO_WIDE_NEGO) & + (acb->config & HCC_WIDE_CARD)) ? 1 : 0; u8 *ptr = srb->msgout_buf + srb->msg_count; if (srb->msg_count > 1) { dprintkl(KERN_INFO, - "Build_WDTR: msgout_buf BUSY (%i: %02x %02x)\n", - srb->msg_count, srb->msgout_buf[0], - srb->msgout_buf[1]); + "build_wdtr: msgout_buf BUSY (%i: %02x %02x)\n", + srb->msg_count, srb->msgout_buf[0], + srb->msgout_buf[1]); return; } *ptr++ = MSG_EXTENDED; /* (01h) */ @@ -1781,7 +1445,6 @@ *ptr++ = wide; srb->msg_count += 4; srb->state |= SRB_DO_WIDE_NEGO; - TRACEPRINTF("W *"); } @@ -1809,7 +1472,7 @@ void selection_timeout_missed(unsigned long ptr) { unsigned long flags; - struct AdapterCtlBlk *acb = (struct AdapterCtlBlk *) ptr; + struct AdapterCtlBlk *acb = (struct AdapterCtlBlk *)ptr; struct ScsiReqBlk *srb; dprintkl(KERN_DEBUG, "Chip forgot to produce SelTO IRQ!\n"); if (!acb->active_dcb || !acb->active_dcb->active_srb) { @@ -1818,39 +1481,30 @@ } DC395x_LOCK_IO(acb->scsi_host, flags); srb = acb->active_dcb->active_srb; - TRACEPRINTF("N/TO *"); disconnect(acb); DC395x_UNLOCK_IO(acb->scsi_host, flags); } #endif -/* - * scsiio - * DC395x_DoWaitingSRB srb_done - * send_srb request_sense - */ -static -u8 start_scsi(struct AdapterCtlBlk * acb, struct DeviceCtlBlk * dcb, - struct ScsiReqBlk * srb) +static u8 start_scsi(struct AdapterCtlBlk* acb, struct DeviceCtlBlk* dcb, + struct ScsiReqBlk* srb) { u16 s_stat2, return_code; u8 s_stat, scsicommand, i, identify_message; u8 *ptr; + dprintkdbg(DBG_0, "start_scsi: (pid#%li) <%02i-%i> srb=%p\n", + srb->cmd->pid, dcb->target_id, dcb->target_lun, srb); - dprintkdbg(DBG_0, "start_scsi..............\n"); srb->tag_number = TAG_NONE; /* acb->tag_max_num: had error read in eeprom */ s_stat = DC395x_read8(acb, TRM_S1040_SCSI_SIGNAL); s_stat2 = 0; s_stat2 = DC395x_read16(acb, TRM_S1040_SCSI_STATUS); - TRACEPRINTF("Start %02x *", s_stat); #if 1 if (s_stat & 0x20 /* s_stat2 & 0x02000 */ ) { - dprintkdbg(DBG_KG, - "StartSCSI: pid %li(%02i-%i): BUSY %02x %04x\n", - srb->cmd->pid, dcb->target_id, dcb->target_lun, - s_stat, s_stat2); + dprintkdbg(DBG_KG, "start_scsi: (pid#%li) BUSY %02x %04x\n", + srb->cmd->pid, s_stat, s_stat2); /* * Try anyway? * @@ -1861,41 +1515,32 @@ * Instead let this fail and have the timer make sure the command is * tried again after a short time */ - TRACEPRINTF("^*"); /*selto_timer (acb); */ - /*monitor_next_irq = 1; */ return 1; } #endif if (acb->active_dcb) { - dprintkl(KERN_DEBUG, "We try to start a SCSI command (%li)!\n", - srb->cmd->pid); - dprintkl(KERN_DEBUG, "While another one (%li) is active!!\n", - (acb->active_dcb->active_srb ? acb->active_dcb-> - active_srb->cmd->pid : 0)); - TRACEOUT(" %s\n", srb->debugtrace); - if (acb->active_dcb->active_srb) - TRACEOUT(" %s\n", - acb->active_dcb->active_srb->debugtrace); + dprintkl(KERN_DEBUG, "start_scsi: (pid#%li) Attempt to start a" + "command while another command (pid#%li) is active.", + srb->cmd->pid, + acb->active_dcb->active_srb ? + acb->active_dcb->active_srb->cmd->pid : 0); return 1; } if (DC395x_read16(acb, TRM_S1040_SCSI_STATUS) & SCSIINTERRUPT) { - dprintkdbg(DBG_KG, - "StartSCSI failed (busy) for pid %li(%02i-%i)\n", - srb->cmd->pid, dcb->target_id, dcb->target_lun); - TRACEPRINTF("°*"); + dprintkdbg(DBG_KG, "start_scsi: (pid#%li) Failed (busy)\n", + srb->cmd->pid); return 1; } /* Allow starting of SCSI commands half a second before we allow the mid-level * to queue them again after a reset */ if (time_before(jiffies, acb->scsi_host->last_reset - HZ / 2)) { - dprintkdbg(DBG_KG, - "We were just reset and don't accept commands yet!\n"); + dprintkdbg(DBG_KG, "start_scsi: Refuse cmds (reset wait)\n"); return 1; } /* Flush FIFO */ - clear_fifo(acb, "Start"); + clear_fifo(acb, "start_scsi"); DC395x_write8(acb, TRM_S1040_SCSI_HOSTID, acb->scsi_host->this_id); DC395x_write8(acb, TRM_S1040_SCSI_TARGETID, dcb->target_id); DC395x_write8(acb, TRM_S1040_SCSI_SYNC, dcb->sync_period); @@ -1939,9 +1584,7 @@ } srb->msg_count = 0; } - /* - ** Send identify message - */ + /* Send identify message */ DC395x_write8(acb, TRM_S1040_SCSI_FIFO, identify_message); scsicommand = SCMD_SEL_ATN; @@ -1958,37 +1601,29 @@ tag_number++; } if (tag_number >= dcb->max_command) { - dprintkl(KERN_WARNING, - "Start_SCSI: Out of tags for pid %li (%i-%i)\n", - srb->cmd->pid, srb->cmd->device->id, - srb->cmd->device->lun); + dprintkl(KERN_WARNING, "start_scsi: (pid#%li) " + "Out of tags target=<%02i-%i>)\n", + srb->cmd->pid, srb->cmd->device->id, + srb->cmd->device->lun); srb->state = SRB_READY; DC395x_write16(acb, TRM_S1040_SCSI_CONTROL, DO_HWRESELECT); return 1; } - /* - ** Send Tag id - */ + /* Send Tag id */ DC395x_write8(acb, TRM_S1040_SCSI_FIFO, MSG_SIMPLE_QTAG); DC395x_write8(acb, TRM_S1040_SCSI_FIFO, tag_number); dcb->tag_mask |= tag_mask; srb->tag_number = tag_number; - TRACEPRINTF("Tag %i *", tag_number); - scsicommand = SCMD_SEL_ATN3; srb->state = SRB_START_; } #endif /*polling:*/ - /* - * Send CDB ..command block ......... - */ - dprintkdbg(DBG_KG, - "StartSCSI (pid %li) %02x (%i-%i): Tag %i\n", - srb->cmd->pid, srb->cmd->cmnd[0], - srb->cmd->device->id, srb->cmd->device->lun, - srb->tag_number); + /* Send CDB ..command block ......... */ + dprintkdbg(DBG_KG, "start_scsi: (pid#%li) <%02i-%i> cmnd=0x%02x tag=%i\n", + srb->cmd->pid, srb->cmd->device->id, srb->cmd->device->lun, + srb->cmd->cmnd[0], srb->tag_number); if (srb->flag & AUTO_REQSENSE) { DC395x_write8(acb, TRM_S1040_SCSI_FIFO, REQUEST_SENSE); DC395x_write8(acb, TRM_S1040_SCSI_FIFO, (dcb->target_lun << 5)); @@ -1998,7 +1633,7 @@ sizeof(srb->cmd->sense_buffer)); DC395x_write8(acb, TRM_S1040_SCSI_FIFO, 0); } else { - ptr = (u8 *) srb->cmd->cmnd; + ptr = (u8 *)srb->cmd->cmnd; for (i = 0; i < srb->cmd->cmd_len; i++) DC395x_write8(acb, TRM_S1040_SCSI_FIFO, *ptr++); } @@ -2011,10 +1646,8 @@ * we caught an interrupt (must be reset or reselection ... ) * : Let's process it first! */ - dprintkdbg(DBG_0, "Debug: StartSCSI failed (busy) for pid %li(%02i-%i)!\n", + dprintkdbg(DBG_0, "start_scsi: (pid#%li) <%02i-%i> Failed - busy\n", srb->cmd->pid, dcb->target_id, dcb->target_lun); - /*clear_fifo (acb, "Start2"); */ - /*DC395x_write16 (TRM_S1040_SCSI_CONTROL, DO_HWRESELECT | DO_DATALATCH); */ srb->state = SRB_READY; free_tag(dcb, srb); srb->msg_count = 0; @@ -2032,23 +1665,13 @@ /* it's important for atn stop */ DC395x_write16(acb, TRM_S1040_SCSI_CONTROL, DO_DATALATCH | DO_HWRESELECT); - /* - ** SCSI command - */ - TRACEPRINTF("%02x *", scsicommand); + /* SCSI command */ DC395x_write8(acb, TRM_S1040_SCSI_COMMAND, scsicommand); } return return_code; } -/* - ******************************************************************** - * scsiio - * init_adapter - ******************************************************************** - */ - /** * dc395x_handle_interrupt - Handle an interrupt that has been confirmed to * have been triggered for this card. @@ -2056,37 +1679,29 @@ * @acb: a pointer to the adpter control block * @scsi_status: the status return when we checked the card **/ -static void dc395x_handle_interrupt(struct AdapterCtlBlk *acb, u16 scsi_status) +static void dc395x_handle_interrupt(struct AdapterCtlBlk *acb, + u16 scsi_status) { struct DeviceCtlBlk *dcb; struct ScsiReqBlk *srb; u16 phase; u8 scsi_intstatus; unsigned long flags; - void (*dc395x_statev) (struct AdapterCtlBlk *, struct ScsiReqBlk *, - u16 *); + void (*dc395x_statev)(struct AdapterCtlBlk *, struct ScsiReqBlk *, + u16 *); DC395x_LOCK_IO(acb->scsi_host, flags); /* This acknowledges the IRQ */ scsi_intstatus = DC395x_read8(acb, TRM_S1040_SCSI_INTSTATUS); if ((scsi_status & 0x2007) == 0x2002) - dprintkl(KERN_DEBUG, "COP after COP completed? %04x\n", - scsi_status); -#if 1 /*def DBG_0 */ - if (monitor_next_irq) { - dprintkl(KERN_INFO, - "status=%04x intstatus=%02x\n", scsi_status, - scsi_intstatus); - monitor_next_irq--; - } -#endif - /*DC395x_ACB_LOCK(acb,acb_flags); */ + dprintkl(KERN_DEBUG, + "COP after COP completed? %04x\n", scsi_status); if (debug_enabled(DBG_KG)) { if (scsi_intstatus & INT_SELTIMEOUT) - dprintkdbg(DBG_KG, "Sel Timeout IRQ\n"); + dprintkdbg(DBG_KG, "handle_interrupt: Selection timeout\n"); } - /*dprintkl(KERN_DEBUG, "DC395x_IRQ: intstatus = %02x ", scsi_intstatus); */ + /*dprintkl(KERN_DEBUG, "handle_interrupt: intstatus = 0x%02x ", scsi_intstatus); */ if (timer_pending(&acb->selto_timer)) del_timer(&acb->selto_timer); @@ -2111,8 +1726,8 @@ dcb = acb->active_dcb; if (!dcb) { dprintkl(KERN_DEBUG, - "Oops: BusService (%04x %02x) w/o ActiveDCB!\n", - scsi_status, scsi_intstatus); + "Oops: BusService (%04x %02x) w/o ActiveDCB!\n", + scsi_status, scsi_intstatus); goto out_unlock; } srb = dcb->active_srb; @@ -2120,12 +1735,10 @@ dprintkdbg(DBG_0, "MsgOut Abort Device.....\n"); enable_msgout_abort(acb, srb); } - /* - ************************************************************ - * software sequential machine - ************************************************************ - */ - phase = (u16) srb->scsi_phase; + + /* software sequential machine */ + phase = (u16)srb->scsi_phase; + /* * 62037 or 62137 * call dc395x_scsi_phase0[]... "phase entry" @@ -2139,22 +1752,20 @@ /* nop0, phase:5 PH_BUS_FREE .. initial phase */ /* msgout_phase0, phase:6 */ /* msgin_phase0, phase:7 */ - dc395x_statev = (void *) dc395x_scsi_phase0[phase]; + dc395x_statev = dc395x_scsi_phase0[phase]; dc395x_statev(acb, srb, &scsi_status); + /* - *$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ - * - * if there were any exception occured - * scsi_status will be modify to bus free phase - * new scsi_status transfer out from ... previous dc395x_statev - * - *$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ + * if there were any exception occured scsi_status + * will be modify to bus free phase new scsi_status + * transfer out from ... previous dc395x_statev */ srb->scsi_phase = scsi_status & PHASEMASK; - phase = (u16) scsi_status & PHASEMASK; + phase = (u16)scsi_status & PHASEMASK; + /* - * call dc395x_scsi_phase1[]... "phase entry" - * handle every phase do transfer + * call dc395x_scsi_phase1[]... "phase entry" handle + * every phase to do transfer */ /* data_out_phase1, phase:0 */ /* data_in_phase1, phase:1 */ @@ -2164,30 +1775,22 @@ /* nop1, phase:5 PH_BUS_FREE .. initial phase */ /* msgout_phase1, phase:6 */ /* msgin_phase1, phase:7 */ - dc395x_statev = (void *) dc395x_scsi_phase1[phase]; + dc395x_statev = dc395x_scsi_phase1[phase]; dc395x_statev(acb, srb, &scsi_status); } out_unlock: DC395x_UNLOCK_IO(acb->scsi_host, flags); - return; } -static -irqreturn_t dc395x_interrupt(int irq, void *dev_id, struct pt_regs *regs) +static irqreturn_t dc395x_interrupt(int irq, void *dev_id, + struct pt_regs *regs) { struct AdapterCtlBlk *acb = (struct AdapterCtlBlk *)dev_id; u16 scsi_status; u8 dma_status; irqreturn_t handled = IRQ_NONE; - dprintkdbg(DBG_0, "dc395x_interrupt..............\n"); -#if debug_enabled(DBG_RECURSION) - if (dbg_in_driver++ > NORM_REC_LVL) { - dprintkl(KERN_DEBUG, "%i interrupt recursion?\n", dbg_in_driver); - } -#endif - /* * Check for pending interupt */ @@ -2200,7 +1803,7 @@ } else if (dma_status & 0x20) { /* Error from the DMA engine */ - dprintkl(KERN_INFO, "Interrupt from DMA engine: %02x!\n", dma_status); + dprintkl(KERN_INFO, "Interrupt from DMA engine: 0x%02x!\n", dma_status); #if 0 dprintkl(KERN_INFO, "This means DMA error! Try to handle ...\n"); if (acb->active_dcb) { @@ -2216,135 +1819,75 @@ handled = IRQ_HANDLED; } -#if debug_enabled(DBG_RECURSION) - dbg_in_driver-- -#endif return handled; } -/* - ******************************************************************** - * scsiio - * msgout_phase0: one of dc395x_scsi_phase0[] vectors - * dc395x_statev = (void *)dc395x_scsi_phase0[phase] - * if phase =6 - ******************************************************************** - */ -static -void msgout_phase0(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb, - u16 * pscsi_status) +static void msgout_phase0(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb, + u16 *pscsi_status) { - dprintkdbg(DBG_0, "msgout_phase0.....\n"); - if (srb->state & (SRB_UNEXPECT_RESEL + SRB_ABORT_SENT)) { + dprintkdbg(DBG_0, "msgout_phase0: (pid#%li)\n", srb->cmd->pid); + if (srb->state & (SRB_UNEXPECT_RESEL + SRB_ABORT_SENT)) *pscsi_status = PH_BUS_FREE; /*.. initial phase */ - } + DC395x_write16(acb, TRM_S1040_SCSI_CONTROL, DO_DATALATCH); /* it's important for atn stop */ srb->state &= ~SRB_MSGOUT; - TRACEPRINTF("MOP0 *"); } -/* - ******************************************************************** - * scsiio - * msgout_phase1: one of dc395x_scsi_phase0[] vectors - * dc395x_statev = (void *)dc395x_scsi_phase0[phase] - * if phase =6 - ******************************************************************** - */ -static -void msgout_phase1(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb, - u16 * pscsi_status) +static void msgout_phase1(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb, + u16 *pscsi_status) { u16 i; u8 *ptr; - struct DeviceCtlBlk *dcb; + dprintkdbg(DBG_0, "msgout_phase1: (pid#%li)\n", srb->cmd->pid); - dprintkdbg(DBG_0, "msgout_phase1..............\n"); - TRACEPRINTF("MOP1*"); - dcb = acb->active_dcb; - clear_fifo(acb, "MOP1"); + clear_fifo(acb, "msgout_phase1"); if (!(srb->state & SRB_MSGOUT)) { srb->state |= SRB_MSGOUT; - dprintkl(KERN_DEBUG, "Debug: pid %li: MsgOut Phase unexpected.\n", srb->cmd->pid); /* So what ? */ + dprintkl(KERN_DEBUG, + "msgout_phase1: (pid#%li) Phase unexpected\n", + srb->cmd->pid); /* So what ? */ } if (!srb->msg_count) { - dprintkdbg(DBG_0, "Debug: pid %li: NOP Msg (no output message there).\n", + dprintkdbg(DBG_0, "msgout_phase1: (pid#%li) NOP msg\n", srb->cmd->pid); DC395x_write8(acb, TRM_S1040_SCSI_FIFO, MSG_NOP); DC395x_write16(acb, TRM_S1040_SCSI_CONTROL, DO_DATALATCH); /* it's important for atn stop */ DC395x_write8(acb, TRM_S1040_SCSI_COMMAND, SCMD_FIFO_OUT); - TRACEPRINTF("\\*"); - TRACEOUT(" %s\n", srb->debugtrace); return; } - ptr = (u8 *) srb->msgout_buf; - TRACEPRINTF("(*"); - /*dprintkl(KERN_DEBUG, "Send msg: "); print_msg (ptr, srb->msg_count); */ - /*dprintkl(KERN_DEBUG, "MsgOut: "); */ - for (i = 0; i < srb->msg_count; i++) { - TRACEPRINTF("%02x *", *ptr); + ptr = (u8 *)srb->msgout_buf; + for (i = 0; i < srb->msg_count; i++) DC395x_write8(acb, TRM_S1040_SCSI_FIFO, *ptr++); - } - TRACEPRINTF(")*"); srb->msg_count = 0; - /*printk("\n"); */ - if (/*(dcb->flag & ABORT_DEV_) && */ - (srb->msgout_buf[0] == MSG_ABORT)) + if (srb->msgout_buf[0] == MSG_ABORT) srb->state = SRB_ABORT_SENT; - /*1.25 */ - /*DC395x_write16 (TRM_S1040_SCSI_CONTROL, DO_DATALATCH); *//* it's important for atn stop */ - /* - ** SCSI command - */ - /*TRACEPRINTF (".*"); */ DC395x_write8(acb, TRM_S1040_SCSI_COMMAND, SCMD_FIFO_OUT); } -/* - ******************************************************************** - * scsiio - * command_phase0: one of dc395x_scsi_phase0[] vectors - * dc395x_statev = (void *)dc395x_scsi_phase0[phase] - * if phase =2 - ******************************************************************** - */ -static -void command_phase0(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb, - u16 * pscsi_status) +static void command_phase0(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb, + u16 *pscsi_status) { - TRACEPRINTF("COP0 *"); - /*1.25 */ - /*clear_fifo (acb, COP0); */ + dprintkdbg(DBG_0, "command_phase0: (pid#%li)\n", srb->cmd->pid); DC395x_write16(acb, TRM_S1040_SCSI_CONTROL, DO_DATALATCH); } -/* - ******************************************************************** - * scsiio - * command_phase1: one of dc395x_scsi_phase1[] vectors - * dc395x_statev = (void *)dc395x_scsi_phase1[phase] - * if phase =2 - ******************************************************************** - */ -static -void command_phase1(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb, - u16 * pscsi_status) +static void command_phase1(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb, + u16 *pscsi_status) { struct DeviceCtlBlk *dcb; u8 *ptr; u16 i; + dprintkdbg(DBG_0, "command_phase1: (pid#%li)\n", srb->cmd->pid); - dprintkdbg(DBG_0, "command_phase1..............\n"); - TRACEPRINTF("COP1*"); - clear_fifo(acb, "COP1"); + clear_fifo(acb, "command_phase1"); DC395x_write16(acb, TRM_S1040_SCSI_CONTROL, DO_CLRATN); if (!(srb->flag & AUTO_REQSENSE)) { - ptr = (u8 *) srb->cmd->cmnd; + ptr = (u8 *)srb->cmd->cmnd; for (i = 0; i < srb->cmd->cmd_len; i++) { DC395x_write8(acb, TRM_S1040_SCSI_FIFO, *ptr); ptr++; @@ -2364,22 +1907,24 @@ /* it's important for atn stop */ DC395x_write16(acb, TRM_S1040_SCSI_CONTROL, DO_DATALATCH); /* SCSI command */ - TRACEPRINTF(".*"); DC395x_write8(acb, TRM_S1040_SCSI_COMMAND, SCMD_FIFO_OUT); } -/* Do sanity checks for S/G list */ -static inline void check_sg_list(struct ScsiReqBlk *srb) +/* + * Verify that the remaining space in the hw sg lists is the same as + * the count of remaining bytes in srb->total_xfer_length + */ +static void sg_verify_length(struct ScsiReqBlk *srb) { - if (debug_enabled(DBG_SGPARANOIA)) { + if (debug_enabled(DBG_SG)) { unsigned len = 0; unsigned idx = srb->sg_index; struct SGentry *psge = srb->segment_x + idx; for (; idx < srb->sg_count; psge++, idx++) len += psge->length; if (len != srb->total_xfer_length) - dprintkdbg(DBG_SGPARANOIA, + dprintkdbg(DBG_SG, "Inconsistent SRB S/G lengths (Tot=%i, Count=%i) !!\n", srb->total_xfer_length, len); } @@ -2390,75 +1935,90 @@ * Compute the next Scatter Gather list index and adjust its length * and address if necessary; also compute virt_addr */ -static void update_sg_list(struct ScsiReqBlk *srb, u32 left) +static void sg_update_list(struct ScsiReqBlk *srb, u32 left) { - struct SGentry *psge; - u32 xferred = 0; u8 idx; - Scsi_Cmnd *cmd = srb->cmd; struct scatterlist *sg; + Scsi_Cmnd *cmd = srb->cmd; int segment = cmd->use_sg; + u32 xferred = srb->total_xfer_length - left; /* bytes transfered */ + struct SGentry *psge = srb->segment_x + srb->sg_index; - dprintkdbg(DBG_KG, "Update SG: Total %i, Left %i\n", - srb->total_xfer_length, left); - check_sg_list(srb); - psge = srb->segment_x + srb->sg_index; - /* data that has already been transferred */ - xferred = srb->total_xfer_length - left; - if (srb->total_xfer_length != left) { - /*check_sg_list_TX (srb, xferred); */ - /* Remaining */ - srb->total_xfer_length = left; - /* parsing from last time disconnect SGIndex */ - for (idx = srb->sg_index; idx < srb->sg_count; idx++) { + dprintkdbg(DBG_0, + "sg_update_list: Transfered %i of %i bytes, %i remain\n", + xferred, srb->total_xfer_length, left); + if (xferred == 0) { + /* nothing to update since we did not transfer any data */ + return; + } + + sg_verify_length(srb); + srb->total_xfer_length = left; /* update remaining count */ + for (idx = srb->sg_index; idx < srb->sg_count; idx++) { + if (xferred >= psge->length) { /* Complete SG entries done */ - if (xferred >= psge->length) - xferred -= psge->length; - /* Partial SG entries done */ - else { - psge->length -= xferred; /* residue data length */ - psge->address += xferred; /* residue data pointer */ - srb->sg_index = idx; - pci_dma_sync_single(srb->dcb-> - acb->dev, - srb->sg_bus_addr, - sizeof(struct SGentry) - * - DC395x_MAX_SG_LISTENTRY, - PCI_DMA_TODEVICE); - break; - } - psge++; + xferred -= psge->length; + } else { + /* Partial SG entry done */ + psge->length -= xferred; + psge->address += xferred; + srb->sg_index = idx; + pci_dma_sync_single_for_device(srb->dcb-> + acb->dev, + srb->sg_bus_addr, + SEGMENTX_LEN, + PCI_DMA_TODEVICE); + break; } - check_sg_list(srb); + psge++; } - /* We need the corresponding virtual address sg_to_virt */ - /*dprintkl(KERN_DEBUG, "sg_to_virt: bus %08x -> virt ", psge->address); */ + sg_verify_length(srb); + + /* we need the corresponding virtual address */ if (!segment) { srb->virt_addr += xferred; - /*printk("%p\n", srb->virt_addr); */ return; } + /* We have to walk the scatterlist to find it */ - sg = (struct scatterlist *) cmd->request_buffer; + sg = (struct scatterlist *)cmd->request_buffer; while (segment--) { - /*printk("(%08x)%p ", BUS_ADDR(*sg), PAGE_ADDRESS(sg)); */ unsigned long mask = - ~((unsigned long) sg->length - 1) & PAGE_MASK; - if ((BUS_ADDR(*sg) & mask) == (psge->address & mask)) { - srb->virt_addr = (PAGE_ADDRESS(sg) + ~((unsigned long)sg->length - 1) & PAGE_MASK; + if ((sg_dma_address(sg) & mask) == (psge->address & mask)) { + srb->virt_addr = (page_address(sg->page) + psge->address - (psge->address & PAGE_MASK)); - /*printk("%p\n", srb->virt_addr); */ return; } ++sg; } - dprintkl(KERN_ERR, "sg_to_virt failed!\n"); + + dprintkl(KERN_ERR, "sg_update_list: sg_to_virt failed\n"); srb->virt_addr = 0; } +/* + * We have transfered a single byte (PIO mode?) and need to update + * the count of bytes remaining (total_xfer_length) and update the sg + * entry to either point to next byte in the current sg entry, or of + * already at the end to point to the start of the next sg entry + */ +static void sg_subtract_one(struct ScsiReqBlk *srb) +{ + srb->total_xfer_length--; + srb->segment_x[srb->sg_index].length--; + if (srb->total_xfer_length && + !srb->segment_x[srb->sg_index].length) { + if (debug_enabled(DBG_PIO)) + printk(" (next segment)"); + srb->sg_index++; + sg_update_list(srb, srb->total_xfer_length); + } +} + + /* * cleanup_after_transfer * @@ -2467,27 +2027,21 @@ * Should probably also be called from other places * Best might be to call it in DataXXPhase0, if new phase will differ */ -static -void cleanup_after_transfer(struct AdapterCtlBlk *acb, - struct ScsiReqBlk *srb) +static void cleanup_after_transfer(struct AdapterCtlBlk *acb, + struct ScsiReqBlk *srb) { - TRACEPRINTF(" Cln*"); /*DC395x_write8 (TRM_S1040_DMA_STATUS, FORCEDMACOMP); */ if (DC395x_read16(acb, TRM_S1040_DMA_COMMAND) & 0x0001) { /* read */ if (!(DC395x_read8(acb, TRM_S1040_SCSI_FIFOCNT) & 0x40)) - clear_fifo(acb, "ClnIn"); - + clear_fifo(acb, "cleanup/in"); if (!(DC395x_read8(acb, TRM_S1040_DMA_FIFOSTAT) & 0x80)) DC395x_write8(acb, TRM_S1040_DMA_CONTROL, CLRXFIFO); } else { /* write */ if (!(DC395x_read8(acb, TRM_S1040_DMA_FIFOSTAT) & 0x80)) DC395x_write8(acb, TRM_S1040_DMA_CONTROL, CLRXFIFO); - if (!(DC395x_read8(acb, TRM_S1040_SCSI_FIFOCNT) & 0x40)) - clear_fifo(acb, "ClnOut"); - + clear_fifo(acb, "cleanup/out"); } - /*1.25 */ DC395x_write16(acb, TRM_S1040_SCSI_CONTROL, DO_DATALATCH); } @@ -2497,26 +2051,16 @@ * Seems to be needed for unknown reasons; could be a hardware bug :-( */ #define DC395x_LASTPIO 4 -/* - ******************************************************************** - * scsiio - * data_out_phase0: one of dc395x_scsi_phase0[] vectors - * dc395x_statev = (void *)dc395x_scsi_phase0[phase] - * if phase =0 - ******************************************************************** - */ -static -void data_out_phase0(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb, - u16 * pscsi_status) + + +static void data_out_phase0(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb, + u16 *pscsi_status) { - u16 scsi_status; - u32 d_left_counter = 0; struct DeviceCtlBlk *dcb = srb->dcb; - - dprintkdbg(DBG_0, "data_out_phase0.....\n"); - TRACEPRINTF("DOP0*"); - dcb = srb->dcb; - scsi_status = *pscsi_status; + u16 scsi_status = *pscsi_status; + u32 d_left_counter = 0; + dprintkdbg(DBG_0, "data_out_phase0: (pid#%li) <%02i-%i>\n", + srb->cmd->pid, srb->cmd->device->id, srb->cmd->device->lun); /* * KG: We need to drain the buffers before we draw any conclusions! @@ -2530,12 +2074,14 @@ * KG: Stop DMA engine pushing more data into the SCSI FIFO * If we need more data, the DMA SG list will be freshly set up, anyway */ - dprintkdbg(DBG_PIO, "DOP0: DMA_FCNT: %02x, DMA_FSTAT: %02x, SCSI_FCNT: %02x, CTR %06x, stat %04x, Tot: %06x\n", - DC395x_read8(acb, TRM_S1040_DMA_FIFOCNT), - DC395x_read8(acb, TRM_S1040_DMA_FIFOSTAT), - DC395x_read8(acb, TRM_S1040_SCSI_FIFOCNT), - DC395x_read32(acb, TRM_S1040_SCSI_COUNTER), scsi_status, - srb->total_xfer_length); + dprintkdbg(DBG_PIO, "data_out_phase0: " + "DMA{fifcnt=0x%02x fifostat=0x%02x} " + "SCSI{fifocnt=0x%02x cnt=0x%06x status=0x%04x} total=0x%06x\n", + DC395x_read8(acb, TRM_S1040_DMA_FIFOCNT), + DC395x_read8(acb, TRM_S1040_DMA_FIFOSTAT), + DC395x_read8(acb, TRM_S1040_SCSI_FIFOCNT), + DC395x_read32(acb, TRM_S1040_SCSI_COUNTER), scsi_status, + srb->total_xfer_length); DC395x_write8(acb, TRM_S1040_DMA_CONTROL, STOPDMAXFER | CLRXFIFO); if (!(srb->state & SRB_XFERPAD)) { @@ -2554,31 +2100,21 @@ * if there was some data left in SCSI FIFO */ d_left_counter = - (u32) (DC395x_read8(acb, TRM_S1040_SCSI_FIFOCNT) & - 0x1F); + (u32)(DC395x_read8(acb, TRM_S1040_SCSI_FIFOCNT) & + 0x1F); if (dcb->sync_period & WIDE_SYNC) d_left_counter <<= 1; - dprintkdbg(DBG_KG, - "Debug: SCSI FIFO contains %i %s in DOP0\n", - DC395x_read8(acb, TRM_S1040_SCSI_FIFOCNT), - (dcb-> - sync_period & WIDE_SYNC) ? "words" : - "bytes"); - dprintkdbg(DBG_KG, - "SCSI FIFOCNT %02x, SCSI CTR %08x\n", - DC395x_read8(acb, TRM_S1040_SCSI_FIFOCNT), - DC395x_read32(acb, TRM_S1040_SCSI_COUNTER)); - dprintkdbg(DBG_KG, - "DMA FIFOCNT %04x, FIFOSTAT %02x, DMA CTR %08x\n", - DC395x_read8(acb, TRM_S1040_DMA_FIFOCNT), - DC395x_read8(acb, TRM_S1040_DMA_FIFOSTAT), - DC395x_read32(acb, TRM_S1040_DMA_CXCNT)); - - /* - * if WIDE scsi SCSI FIFOCNT unit is word !!! - * so need to *= 2 - */ + dprintkdbg(DBG_KG, "data_out_phase0: FIFO contains %i %s\n" + "SCSI{fifocnt=0x%02x cnt=0x%08x} " + "DMA{fifocnt=0x%04x cnt=0x%02x ctr=0x%08x}\n", + DC395x_read8(acb, TRM_S1040_SCSI_FIFOCNT), + (dcb->sync_period & WIDE_SYNC) ? "words" : "bytes", + DC395x_read8(acb, TRM_S1040_SCSI_FIFOCNT), + DC395x_read32(acb, TRM_S1040_SCSI_COUNTER), + DC395x_read8(acb, TRM_S1040_DMA_FIFOCNT), + DC395x_read8(acb, TRM_S1040_DMA_FIFOSTAT), + DC395x_read32(acb, TRM_S1040_DMA_CXCNT)); } /* * calculate all the residue data that not yet tranfered @@ -2592,16 +2128,16 @@ if (srb->total_xfer_length > DC395x_LASTPIO) d_left_counter += DC395x_read32(acb, TRM_S1040_SCSI_COUNTER); - TRACEPRINTF("%06x *", d_left_counter); /* Is this a good idea? */ - /*clear_fifo (acb, "DOP1"); */ + /*clear_fifo(acb, "DOP1"); */ /* KG: What is this supposed to be useful for? WIDE padding stuff? */ if (d_left_counter == 1 && dcb->sync_period & WIDE_SYNC && srb->cmd->request_bufflen % 2) { d_left_counter = 0; - dprintkl(KERN_INFO, "DOP0: Discard 1 byte. (%02x)\n", - scsi_status); + dprintkl(KERN_INFO, + "data_out_phase0: Discard 1 byte (0x%02x)\n", + scsi_status); } /* * KG: Oops again. Same thinko as above: The SCSI might have been @@ -2613,19 +2149,9 @@ * KG: This is nonsense: We have been WRITING data to the bus * If the SCSI engine has no bytes left, how should the DMA engine? */ - if ((d_left_counter == - 0) /*|| (scsi_status & SCSIXFERCNT_2_ZERO) ) */ ) { - /* - * int ctr = 6000000; u8 TempDMAstatus; - * do - * { - * TempDMAstatus = DC395x_read8(acb, TRM_S1040_DMA_STATUS); - * } while( !(TempDMAstatus & DMAXFERCOMP) && --ctr); - * if (ctr < 6000000-1) dprintkl(KERN_DEBUG, "DMA should be complete ... in DOP1\n"); - * if (!ctr) dprintkl(KERN_ERR, "Deadlock in DataOutPhase0 !!\n"); - */ + if (d_left_counter == 0) { srb->total_xfer_length = 0; - } else { /* Update SG list */ + } else { /* * if transfer not yet complete * there were some data residue in SCSI FIFO or @@ -2635,18 +2161,18 @@ srb->total_xfer_length - d_left_counter; const int diff = (dcb->sync_period & WIDE_SYNC) ? 2 : 1; - update_sg_list(srb, d_left_counter); + sg_update_list(srb, d_left_counter); /* KG: Most ugly hack! Apparently, this works around a chip bug */ if ((srb->segment_x[srb->sg_index].length == diff && srb->cmd->use_sg) || ((oldxferred & ~PAGE_MASK) == (PAGE_SIZE - diff)) ) { - dprintkl(KERN_INFO, - "Work around chip bug (%i)?\n", diff); + dprintkl(KERN_INFO, "data_out_phase0: " + "Work around chip bug (%i)?\n", diff); d_left_counter = srb->total_xfer_length - diff; - update_sg_list(srb, d_left_counter); + sg_update_list(srb, d_left_counter); /*srb->total_xfer_length -= diff; */ /*srb->virt_addr += diff; */ /*if (srb->cmd->use_sg) */ @@ -2654,71 +2180,30 @@ } } } -#if 0 - if (!(DC395x_read8(acb, TRM_S1040_SCSI_FIFOCNT) & 0x40)) - dprintkl(KERN_DEBUG, - "DOP0(%li): %i bytes in SCSI FIFO! (Clear!)\n", - srb->cmd->pid, - DC395x_read8(acb, TRM_S1040_SCSI_FIFOCNT) & 0x1f); -#endif - /*clear_fifo (acb, "DOP0"); */ - /*DC395x_write8 (TRM_S1040_DMA_CONTROL, CLRXFIFO | ABORTXFER); */ -#if 1 if ((*pscsi_status & PHASEMASK) != PH_DATA_OUT) { - /*dprintkl(KERN_DEBUG, "Debug: Clean up after Data Out ...\n"); */ cleanup_after_transfer(acb, srb); } -#endif - TRACEPRINTF(".*"); } -/* - ******************************************************************** - * scsiio - * data_out_phase1: one of dc395x_scsi_phase0[] vectors - * dc395x_statev = (void *)dc395x_scsi_phase0[phase] - * if phase =0 - * 62037 - ******************************************************************** - */ -static -void data_out_phase1(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb, - u16 * pscsi_status) +static void data_out_phase1(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb, + u16 *pscsi_status) { - - dprintkdbg(DBG_0, "data_out_phase1.....\n"); - /*1.25 */ - TRACEPRINTF("DOP1*"); - clear_fifo(acb, "DOP1"); - /* - ** do prepare befor transfer when data out phase - */ + dprintkdbg(DBG_0, "data_out_phase1: (pid#%li) <%02i-%i>\n", + srb->cmd->pid, srb->cmd->device->id, srb->cmd->device->lun); + clear_fifo(acb, "data_out_phase1"); + /* do prepare before transfer when data out phase */ data_io_transfer(acb, srb, XFERDATAOUT); - TRACEPRINTF(".*"); } -/* - ******************************************************************** - * scsiio - * data_in_phase0: one of dc395x_scsi_phase1[] vectors - * dc395x_statev = (void *)dc395x_scsi_phase1[phase] - * if phase =1 - ******************************************************************** - */ -static -void data_in_phase0(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb, - u16 * pscsi_status) +static void data_in_phase0(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb, + u16 *pscsi_status) { - u16 scsi_status; + u16 scsi_status = *pscsi_status; u32 d_left_counter = 0; - /*struct DeviceCtlBlk* dcb = srb->dcb; */ - /*u8 bval; */ - - dprintkdbg(DBG_0, "data_in_phase0..............\n"); - TRACEPRINTF("DIP0*"); - scsi_status = *pscsi_status; + dprintkdbg(DBG_0, "data_in_phase0: (pid#%li) <%02i-%i>\n", + srb->cmd->pid, srb->cmd->device->id, srb->cmd->device->lun); /* * KG: DataIn is much more tricky than DataOut. When the device is finished @@ -2735,10 +2220,8 @@ */ if (!(srb->state & SRB_XFERPAD)) { if (scsi_status & PARITYERROR) { - dprintkl(KERN_INFO, - "Parity Error (pid %li, target %02i-%i)\n", - srb->cmd->pid, srb->cmd->device->id, - srb->cmd->device->lun); + dprintkl(KERN_INFO, "data_in_phase0: (pid#%li) " + "Parity Error\n", srb->cmd->pid); srb->status |= PARITY_ERROR; } /* @@ -2751,7 +2234,7 @@ #if 0 int ctr = 6000000; dprintkl(KERN_DEBUG, - "DIP0: Wait for DMA FIFO to flush ...\n"); + "DIP0: Wait for DMA FIFO to flush ...\n"); /*DC395x_write8 (TRM_S1040_DMA_CONTROL, STOPDMAXFER); */ /*DC395x_write32 (TRM_S1040_SCSI_COUNTER, 7); */ /*DC395x_write8 (TRM_S1040_SCSI_COMMAND, SCMD_DMA_IN); */ @@ -2766,73 +2249,56 @@ "Deadlock in DIP0 waiting for DMA FIFO empty!!\n"); /*DC395x_write32 (TRM_S1040_SCSI_COUNTER, 0); */ #endif - dprintkdbg(DBG_KG, "DIP0: DMA_FIFO: %02x %02x\n", - DC395x_read8(acb, TRM_S1040_DMA_FIFOCNT), - DC395x_read8(acb, TRM_S1040_DMA_FIFOSTAT)); + dprintkdbg(DBG_KG, "data_in_phase0: " + "DMA{fifocnt=0x%02x fifostat=0x%02x}\n", + DC395x_read8(acb, TRM_S1040_DMA_FIFOCNT), + DC395x_read8(acb, TRM_S1040_DMA_FIFOSTAT)); } /* Now: Check remainig data: The SCSI counters should tell us ... */ d_left_counter = DC395x_read32(acb, TRM_S1040_SCSI_COUNTER) + ((DC395x_read8(acb, TRM_S1040_SCSI_FIFOCNT) & 0x1f) << ((srb->dcb->sync_period & WIDE_SYNC) ? 1 : 0)); - - dprintkdbg(DBG_KG, "SCSI FIFO contains %i %s in DIP0\n", - DC395x_read8(acb, TRM_S1040_SCSI_FIFOCNT) & 0x1f, - (srb->dcb-> - sync_period & WIDE_SYNC) ? "words" : "bytes"); - dprintkdbg(DBG_KG, "SCSI FIFOCNT %02x, SCSI CTR %08x\n", - DC395x_read8(acb, TRM_S1040_SCSI_FIFOCNT), - DC395x_read32(acb, TRM_S1040_SCSI_COUNTER)); - dprintkdbg(DBG_KG, "DMA FIFOCNT %02x,%02x DMA CTR %08x\n", - DC395x_read8(acb, TRM_S1040_DMA_FIFOCNT), - DC395x_read8(acb, TRM_S1040_DMA_FIFOSTAT), - DC395x_read32(acb, TRM_S1040_DMA_CXCNT)); - dprintkdbg(DBG_KG, "Remaining: TotXfer: %i, SCSI FIFO+Ctr: %i\n", - srb->total_xfer_length, d_left_counter); + dprintkdbg(DBG_KG, "data_in_phase0: " + "SCSI{fifocnt=0x%02x%s ctr=0x%08x} " + "DMA{fifocnt=0x%02x fifostat=0x%02x ctr=0x%08x} " + "Remain{totxfer=%i scsi_fifo+ctr=%i}\n", + DC395x_read8(acb, TRM_S1040_SCSI_FIFOCNT), + (srb->dcb->sync_period & WIDE_SYNC) ? "words" : "bytes", + DC395x_read32(acb, TRM_S1040_SCSI_COUNTER), + DC395x_read8(acb, TRM_S1040_DMA_FIFOCNT), + DC395x_read8(acb, TRM_S1040_DMA_FIFOSTAT), + DC395x_read32(acb, TRM_S1040_DMA_CXCNT), + srb->total_xfer_length, d_left_counter); #if DC395x_LASTPIO /* KG: Less than or equal to 4 bytes can not be transfered via DMA, it seems. */ if (d_left_counter && srb->total_xfer_length <= DC395x_LASTPIO) { /*u32 addr = (srb->segment_x[srb->sg_index].address); */ - /*update_sg_list (srb, d_left_counter); */ - dprintkdbg(DBG_PIO, "DIP0: PIO (%i %s) to %p for remaining %i bytes:", - DC395x_read8(acb, TRM_S1040_SCSI_FIFOCNT) & - 0x1f, - (srb->dcb-> - sync_period & WIDE_SYNC) ? "words" : - "bytes", srb->virt_addr, - srb->total_xfer_length); - + /*sg_update_list (srb, d_left_counter); */ + dprintkdbg(DBG_PIO, "data_in_phase0: PIO (%i %s) to " + "%p for remaining %i bytes:", + DC395x_read8(acb, TRM_S1040_SCSI_FIFOCNT) & 0x1f, + (srb->dcb->sync_period & WIDE_SYNC) ? + "words" : "bytes", + srb->virt_addr, + srb->total_xfer_length); if (srb->dcb->sync_period & WIDE_SYNC) DC395x_write8(acb, TRM_S1040_SCSI_CONFIG2, CFG2_WIDEFIFO); - - while (DC395x_read8(acb, TRM_S1040_SCSI_FIFOCNT) != - 0x40) { - u8 byte = - DC395x_read8(acb, TRM_S1040_SCSI_FIFO); + while (DC395x_read8(acb, TRM_S1040_SCSI_FIFOCNT) != 0x40) { + u8 byte = DC395x_read8(acb, TRM_S1040_SCSI_FIFO); *(srb->virt_addr)++ = byte; if (debug_enabled(DBG_PIO)) printk(" %02x", byte); - srb->total_xfer_length--; d_left_counter--; - srb->segment_x[srb->sg_index].length--; - if (srb->total_xfer_length - && !srb->segment_x[srb->sg_index]. - length) { - if (debug_enabled(DBG_PIO)) - printk(" (next segment)"); - srb->sg_index++; - update_sg_list(srb, - d_left_counter); - } + sg_subtract_one(srb); } if (srb->dcb->sync_period & WIDE_SYNC) { -#if 1 /* Read the last byte ... */ +#if 1 + /* Read the last byte ... */ if (srb->total_xfer_length > 0) { - u8 byte = - DC395x_read8 - (acb, TRM_S1040_SCSI_FIFO); + u8 byte = DC395x_read8(acb, TRM_S1040_SCSI_FIFO); *(srb->virt_addr)++ = byte; srb->total_xfer_length--; if (debug_enabled(DBG_PIO)) @@ -2859,8 +2325,8 @@ * if there was some data left in SCSI FIFO */ d_left_counter = - (u32) (DC395x_read8(acb, TRM_S1040_SCSI_FIFOCNT) & - 0x1F); + (u32)(DC395x_read8(acb, TRM_S1040_SCSI_FIFOCNT) & + 0x1F); if (srb->dcb->sync_period & WIDE_SYNC) d_left_counter <<= 1; /* @@ -2870,19 +2336,8 @@ */ } #endif - /*d_left_counter += DC395x_read32(acb, TRM_S1040_SCSI_COUNTER); */ -#if 0 - dprintkl(KERN_DEBUG, - "DIP0: ctr=%08x, DMA_FIFO=%02x,%02x SCSI_FIFO=%02x\n", - d_left_counter, DC395x_read8(acb, TRM_S1040_DMA_FIFOCNT), - DC395x_read8(acb, TRM_S1040_DMA_FIFOSTAT), - DC395x_read8(acb, TRM_S1040_SCSI_FIFOCNT)); - dprintkl(KERN_DEBUG, "DIP0: DMAStat %02x\n", - DC395x_read8(acb, TRM_S1040_DMA_STATUS)); -#endif - /* KG: This should not be needed any more! */ - if ((d_left_counter == 0) + if (d_left_counter == 0 || (scsi_status & SCSIXFERCNT_2_ZERO)) { #if 0 int ctr = 6000000; @@ -2896,12 +2351,6 @@ "Deadlock in DataInPhase0 waiting for DMA!!\n"); srb->total_xfer_length = 0; #endif -#if 0 /*def DBG_KG */ - dprintkl(KERN_DEBUG, - "DIP0: DMA not yet ready: %02x: %i -> %i bytes\n", - DC395x_read8(acb, TRM_S1040_DMA_STATUS), - srb->total_xfer_length, d_left_counter); -#endif srb->total_xfer_length = d_left_counter; } else { /* phase changed */ /* @@ -2912,333 +2361,209 @@ * there were some data residue in SCSI FIFO or * SCSI transfer counter not empty */ - update_sg_list(srb, d_left_counter); + sg_update_list(srb, d_left_counter); } } /* KG: The target may decide to disconnect: Empty FIFO before! */ if ((*pscsi_status & PHASEMASK) != PH_DATA_IN) { - /*dprintkl(KERN_DEBUG, "Debug: Clean up after Data In ...\n"); */ cleanup_after_transfer(acb, srb); } -#if 0 - /* KG: Make sure, no previous transfers are pending! */ - bval = DC395x_read8(acb, TRM_S1040_SCSI_FIFOCNT); - if (!(bval & 0x40)) { - bval &= 0x1f; - dprintkl(KERN_DEBUG, - "DIP0(%li): %i bytes in SCSI FIFO (stat %04x) (left %08x)!!\n", - srb->cmd->pid, bval & 0x1f, scsi_status, - d_left_counter); - if ((d_left_counter == 0) - || (scsi_status & SCSIXFERCNT_2_ZERO)) { - dprintkl(KERN_DEBUG, "Clear FIFO!\n"); - clear_fifo(acb, "DIP0"); - } - } -#endif - /*DC395x_write8 (TRM_S1040_DMA_CONTROL, CLRXFIFO | ABORTXFER); */ - - /*clear_fifo (acb, "DIP0"); */ - /*DC395x_write16 (TRM_S1040_SCSI_CONTROL, DO_DATALATCH); */ - TRACEPRINTF(".*"); } -/* - ******************************************************************** - * scsiio - * data_in_phase1: one of dc395x_scsi_phase0[] vectors - * dc395x_statev = (void *)dc395x_scsi_phase0[phase] - * if phase =1 - ******************************************************************** - */ -static -void data_in_phase1(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb, - u16 * pscsi_status) -{ - dprintkdbg(DBG_0, "data_in_phase1.....\n"); - /* FIFO should be cleared, if previous phase was not DataPhase */ - /*clear_fifo (acb, "DIP1"); */ - /* Allow data in! */ - /*DC395x_write16 (TRM_S1040_SCSI_CONTROL, DO_DATALATCH); */ - TRACEPRINTF("DIP1:*"); - /* - ** do prepare before transfer when data in phase - */ +static void data_in_phase1(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb, + u16 *pscsi_status) +{ + dprintkdbg(DBG_0, "data_in_phase1: (pid#%li) <%02i-%i>\n", + srb->cmd->pid, srb->cmd->device->id, srb->cmd->device->lun); data_io_transfer(acb, srb, XFERDATAIN); - TRACEPRINTF(".*"); } -/* - ******************************************************************** - * scsiio - * data_out_phase1 - * data_in_phase1 - ******************************************************************** - */ -static -void data_io_transfer(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb, - u16 io_dir) +static void data_io_transfer(struct AdapterCtlBlk *acb, + struct ScsiReqBlk *srb, u16 io_dir) { + struct DeviceCtlBlk *dcb = srb->dcb; u8 bval; - struct DeviceCtlBlk *dcb; - - dprintkdbg(DBG_0, "DataIO_transfer %c (pid %li): len = %i, SG: %i/%i\n", - ((io_dir & DMACMD_DIR) ? 'r' : 'w'), srb->cmd->pid, - srb->total_xfer_length, srb->sg_index, - srb->sg_count); - TRACEPRINTF("%05x(%i/%i)*", srb->total_xfer_length, - srb->sg_index, srb->sg_count); - dcb = srb->dcb; - if (srb == acb->tmp_srb) { - dprintkl(KERN_ERR, "Using tmp_srb in DataPhase!\n"); - } - if (srb->sg_index < srb->sg_count) { - if (srb->total_xfer_length > DC395x_LASTPIO) { - u8 dma_status = DC395x_read8(acb, TRM_S1040_DMA_STATUS); - /* - * KG: What should we do: Use SCSI Cmd 0x90/0x92? - * Maybe, even ABORTXFER would be appropriate - */ - if (dma_status & XFERPENDING) { - dprintkl(KERN_DEBUG, "Xfer pending! Expect trouble!!\n"); - dump_register_info(acb, dcb, srb); - DC395x_write8(acb, TRM_S1040_DMA_CONTROL, - CLRXFIFO); - } - /*clear_fifo (acb, "IO"); */ - /* - * load what physical address of Scatter/Gather list table want to be - * transfer - */ - srb->state |= SRB_DATA_XFER; - DC395x_write32(acb, TRM_S1040_DMA_XHIGHADDR, 0); - if (srb->cmd->use_sg) { /* with S/G */ - io_dir |= DMACMD_SG; - DC395x_write32(acb, TRM_S1040_DMA_XLOWADDR, - srb->sg_bus_addr + - sizeof(struct SGentry) * - srb->sg_index); - /* load how many bytes in the Scatter/Gather list table */ - DC395x_write32(acb, TRM_S1040_DMA_XCNT, - ((u32) - (srb->sg_count - - srb->sg_index) << 3)); - } else { /* without S/G */ - io_dir &= ~DMACMD_SG; - DC395x_write32(acb, TRM_S1040_DMA_XLOWADDR, - srb->segment_x[0].address); - DC395x_write32(acb, TRM_S1040_DMA_XCNT, - srb->segment_x[0].length); - } - /* load total transfer length (24bits) max value 16Mbyte */ - DC395x_write32(acb, TRM_S1040_SCSI_COUNTER, - srb->total_xfer_length); - DC395x_write16(acb, TRM_S1040_SCSI_CONTROL, DO_DATALATCH); /* it's important for atn stop */ - if (io_dir & DMACMD_DIR) { /* read */ - DC395x_write8(acb, TRM_S1040_SCSI_COMMAND, - SCMD_DMA_IN); - DC395x_write16(acb, TRM_S1040_DMA_COMMAND, - io_dir); - } else { - DC395x_write16(acb, TRM_S1040_DMA_COMMAND, - io_dir); - DC395x_write8(acb, TRM_S1040_SCSI_COMMAND, - SCMD_DMA_OUT); - } + dprintkdbg(DBG_0, + "data_io_transfer: (pid#%li) <%02i-%i> %c len=%i, sg=(%i/%i)\n", + srb->cmd->pid, srb->cmd->device->id, srb->cmd->device->lun, + ((io_dir & DMACMD_DIR) ? 'r' : 'w'), + srb->total_xfer_length, srb->sg_index, srb->sg_count); + if (srb == acb->tmp_srb) + dprintkl(KERN_ERR, "data_io_transfer: Using tmp_srb!\n"); + if (srb->sg_index >= srb->sg_count) { + /* can't happen? out of bounds error */ + return; + } + if (srb->total_xfer_length > DC395x_LASTPIO) { + u8 dma_status = DC395x_read8(acb, TRM_S1040_DMA_STATUS); + /* + * KG: What should we do: Use SCSI Cmd 0x90/0x92? + * Maybe, even ABORTXFER would be appropriate + */ + if (dma_status & XFERPENDING) { + dprintkl(KERN_DEBUG, "data_io_transfer: Xfer pending! " + "Expect trouble!\n"); + dump_register_info(acb, dcb, srb); + DC395x_write8(acb, TRM_S1040_DMA_CONTROL, CLRXFIFO); } + /* clear_fifo(acb, "IO"); */ + /* + * load what physical address of Scatter/Gather list table + * want to be transfer + */ + srb->state |= SRB_DATA_XFER; + DC395x_write32(acb, TRM_S1040_DMA_XHIGHADDR, 0); + if (srb->cmd->use_sg) { /* with S/G */ + io_dir |= DMACMD_SG; + DC395x_write32(acb, TRM_S1040_DMA_XLOWADDR, + srb->sg_bus_addr + + sizeof(struct SGentry) * + srb->sg_index); + /* load how many bytes in the sg list table */ + DC395x_write32(acb, TRM_S1040_DMA_XCNT, + ((u32)(srb->sg_count - + srb->sg_index) << 3)); + } else { /* without S/G */ + io_dir &= ~DMACMD_SG; + DC395x_write32(acb, TRM_S1040_DMA_XLOWADDR, + srb->segment_x[0].address); + DC395x_write32(acb, TRM_S1040_DMA_XCNT, + srb->segment_x[0].length); + } + /* load total transfer length (24bits) max value 16Mbyte */ + DC395x_write32(acb, TRM_S1040_SCSI_COUNTER, + srb->total_xfer_length); + DC395x_write16(acb, TRM_S1040_SCSI_CONTROL, DO_DATALATCH); /* it's important for atn stop */ + if (io_dir & DMACMD_DIR) { /* read */ + DC395x_write8(acb, TRM_S1040_SCSI_COMMAND, + SCMD_DMA_IN); + DC395x_write16(acb, TRM_S1040_DMA_COMMAND, io_dir); + } else { + DC395x_write16(acb, TRM_S1040_DMA_COMMAND, io_dir); + DC395x_write8(acb, TRM_S1040_SCSI_COMMAND, + SCMD_DMA_OUT); + } + + } #if DC395x_LASTPIO - else if (srb->total_xfer_length > 0) { /* The last four bytes: Do PIO */ - /*clear_fifo (acb, "IO"); */ - /* - * load what physical address of Scatter/Gather list table want to be - * transfer - */ - srb->state |= SRB_DATA_XFER; - /* load total transfer length (24bits) max value 16Mbyte */ - DC395x_write32(acb, TRM_S1040_SCSI_COUNTER, - srb->total_xfer_length); - DC395x_write16(acb, TRM_S1040_SCSI_CONTROL, DO_DATALATCH); /* it's important for atn stop */ - if (io_dir & DMACMD_DIR) { /* read */ - DC395x_write8(acb, TRM_S1040_SCSI_COMMAND, - SCMD_FIFO_IN); - } else { /* write */ - int ln = srb->total_xfer_length; - if (srb->dcb->sync_period & WIDE_SYNC) - DC395x_write8 - (acb, TRM_S1040_SCSI_CONFIG2, - CFG2_WIDEFIFO); - dprintkdbg(DBG_PIO, "DOP1: PIO %i bytes from %p:", - srb->total_xfer_length, - srb->virt_addr); - while (srb->total_xfer_length) { - if (debug_enabled(DBG_PIO)) - printk(" %02x", (unsigned char) *(srb->virt_addr)); - DC395x_write8 - (acb, TRM_S1040_SCSI_FIFO, - *(srb->virt_addr)++); - srb->total_xfer_length--; - srb->segment_x[srb->sg_index]. - length--; - if (srb->total_xfer_length - && !srb->segment_x[srb-> - sg_index]. - length) { - if (debug_enabled(DBG_PIO)) - printk(" (next segment)"); - srb->sg_index++; - update_sg_list(srb, - srb->total_xfer_length); - } - } - if (srb->dcb->sync_period & WIDE_SYNC) { - if (ln % 2) { - DC395x_write8(acb, TRM_S1040_SCSI_FIFO, 0); - if (debug_enabled(DBG_PIO)) - printk(" |00"); - } - DC395x_write8 - (acb, TRM_S1040_SCSI_CONFIG2, 0); - } - /*DC395x_write32(acb, TRM_S1040_SCSI_COUNTER, ln); */ + else if (srb->total_xfer_length > 0) { /* The last four bytes: Do PIO */ + /* + * load what physical address of Scatter/Gather list table + * want to be transfer + */ + srb->state |= SRB_DATA_XFER; + /* load total transfer length (24bits) max value 16Mbyte */ + DC395x_write32(acb, TRM_S1040_SCSI_COUNTER, + srb->total_xfer_length); + DC395x_write16(acb, TRM_S1040_SCSI_CONTROL, DO_DATALATCH); /* it's important for atn stop */ + if (io_dir & DMACMD_DIR) { /* read */ + DC395x_write8(acb, TRM_S1040_SCSI_COMMAND, + SCMD_FIFO_IN); + } else { /* write */ + int ln = srb->total_xfer_length; + if (srb->dcb->sync_period & WIDE_SYNC) + DC395x_write8(acb, TRM_S1040_SCSI_CONFIG2, + CFG2_WIDEFIFO); + dprintkdbg(DBG_PIO, + "data_io_transfer: PIO %i bytes from %p:", + srb->total_xfer_length, srb->virt_addr); + + while (srb->total_xfer_length) { if (debug_enabled(DBG_PIO)) - printk("\n"); - DC395x_write8(acb, TRM_S1040_SCSI_COMMAND, - SCMD_FIFO_OUT); - } - } -#endif /* DC395x_LASTPIO */ - else { /* xfer pad */ + printk(" %02x", (unsigned char) *(srb->virt_addr)); - u8 data = 0, data2 = 0; - if (srb->sg_count) { - srb->adapter_status = H_OVER_UNDER_RUN; - srb->status |= OVER_RUN; + DC395x_write8(acb, TRM_S1040_SCSI_FIFO, + *(srb->virt_addr)++); + + sg_subtract_one(srb); } - /* - * KG: despite the fact that we are using 16 bits I/O ops - * the SCSI FIFO is only 8 bits according to the docs - * (we can set bit 1 in 0x8f to serialize FIFO access ...) - */ - if (dcb->sync_period & WIDE_SYNC) { - DC395x_write32(acb, TRM_S1040_SCSI_COUNTER, 2); - DC395x_write8(acb, TRM_S1040_SCSI_CONFIG2, - CFG2_WIDEFIFO); - if (io_dir & DMACMD_DIR) { /* read */ - data = - DC395x_read8 - (acb, TRM_S1040_SCSI_FIFO); - data2 = - DC395x_read8 - (acb, TRM_S1040_SCSI_FIFO); - /*dprintkl(KERN_DEBUG, "DataIO: Xfer pad: %02x %02x\n", data, data2); */ - } else { - /* Danger, Robinson: If you find KGs scattered over the wide - * disk, the driver or chip is to blame :-( */ - DC395x_write8(acb, TRM_S1040_SCSI_FIFO, - 'K'); - DC395x_write8(acb, TRM_S1040_SCSI_FIFO, - 'G'); + if (srb->dcb->sync_period & WIDE_SYNC) { + if (ln % 2) { + DC395x_write8(acb, TRM_S1040_SCSI_FIFO, 0); + if (debug_enabled(DBG_PIO)) + printk(" |00"); } DC395x_write8(acb, TRM_S1040_SCSI_CONFIG2, 0); + } + /*DC395x_write32(acb, TRM_S1040_SCSI_COUNTER, ln); */ + if (debug_enabled(DBG_PIO)) + printk("\n"); + DC395x_write8(acb, TRM_S1040_SCSI_COMMAND, + SCMD_FIFO_OUT); + } + } +#endif /* DC395x_LASTPIO */ + else { /* xfer pad */ + u8 data = 0, data2 = 0; + if (srb->sg_count) { + srb->adapter_status = H_OVER_UNDER_RUN; + srb->status |= OVER_RUN; + } + /* + * KG: despite the fact that we are using 16 bits I/O ops + * the SCSI FIFO is only 8 bits according to the docs + * (we can set bit 1 in 0x8f to serialize FIFO access ...) + */ + if (dcb->sync_period & WIDE_SYNC) { + DC395x_write32(acb, TRM_S1040_SCSI_COUNTER, 2); + DC395x_write8(acb, TRM_S1040_SCSI_CONFIG2, + CFG2_WIDEFIFO); + if (io_dir & DMACMD_DIR) { + data = DC395x_read8(acb, TRM_S1040_SCSI_FIFO); + data2 = DC395x_read8(acb, TRM_S1040_SCSI_FIFO); } else { - DC395x_write32(acb, TRM_S1040_SCSI_COUNTER, 1); - /* Danger, Robinson: If you find a collection of Ks on your disk - * something broke :-( */ - if (io_dir & DMACMD_DIR) { /* read */ - data = - DC395x_read8 - (acb, TRM_S1040_SCSI_FIFO); - /*dprintkl(KERN_DEBUG, "DataIO: Xfer pad: %02x\n", data); */ - } else { - DC395x_write8(acb, TRM_S1040_SCSI_FIFO, - 'K'); - } + /* Danger, Robinson: If you find KGs + * scattered over the wide disk, the driver + * or chip is to blame :-( */ + DC395x_write8(acb, TRM_S1040_SCSI_FIFO, 'K'); + DC395x_write8(acb, TRM_S1040_SCSI_FIFO, 'G'); } - srb->state |= SRB_XFERPAD; - DC395x_write16(acb, TRM_S1040_SCSI_CONTROL, DO_DATALATCH); /* it's important for atn stop */ - /* - * SCSI command - */ - bval = - (io_dir & DMACMD_DIR) ? SCMD_FIFO_IN : - SCMD_FIFO_OUT; - DC395x_write8(acb, TRM_S1040_SCSI_COMMAND, bval); + DC395x_write8(acb, TRM_S1040_SCSI_CONFIG2, 0); + } else { + DC395x_write32(acb, TRM_S1040_SCSI_COUNTER, 1); + /* Danger, Robinson: If you find a collection of Ks on your disk + * something broke :-( */ + if (io_dir & DMACMD_DIR) + data = DC395x_read8(acb, TRM_S1040_SCSI_FIFO); + else + DC395x_write8(acb, TRM_S1040_SCSI_FIFO, 'K'); } + srb->state |= SRB_XFERPAD; + DC395x_write16(acb, TRM_S1040_SCSI_CONTROL, DO_DATALATCH); /* it's important for atn stop */ + /* SCSI command */ + bval = (io_dir & DMACMD_DIR) ? SCMD_FIFO_IN : SCMD_FIFO_OUT; + DC395x_write8(acb, TRM_S1040_SCSI_COMMAND, bval); } - /*monitor_next_irq = 2; */ - /*printk(" done\n"); */ } -/* - ******************************************************************** - * scsiio - * status_phase0: one of dc395x_scsi_phase0[] vectors - * dc395x_statev = (void *)dc395x_scsi_phase0[phase] - * if phase =3 - ******************************************************************** - */ -static -void status_phase0(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb, - u16 * pscsi_status) +static void status_phase0(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb, + u16 *pscsi_status) { - dprintkdbg(DBG_0, "StatusPhase0 (pid %li)\n", srb->cmd->pid); - TRACEPRINTF("STP0 *"); + dprintkdbg(DBG_0, "status_phase0: (pid#%li) <%02i-%i>\n", + srb->cmd->pid, srb->cmd->device->id, srb->cmd->device->lun); srb->target_status = DC395x_read8(acb, TRM_S1040_SCSI_FIFO); srb->end_message = DC395x_read8(acb, TRM_S1040_SCSI_FIFO); /* get message */ srb->state = SRB_COMPLETED; *pscsi_status = PH_BUS_FREE; /*.. initial phase */ - /*1.25 */ - /*clear_fifo (acb, "STP0"); */ DC395x_write16(acb, TRM_S1040_SCSI_CONTROL, DO_DATALATCH); /* it's important for atn stop */ - /* - ** SCSI command - */ DC395x_write8(acb, TRM_S1040_SCSI_COMMAND, SCMD_MSGACCEPT); } -/* - ******************************************************************** - * scsiio - * status_phase1: one of dc395x_scsi_phase1[] vectors - * dc395x_statev = (void *)dc395x_scsi_phase1[phase] - * if phase =3 - ******************************************************************** - */ -static -void status_phase1(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb, - u16 * pscsi_status) -{ - dprintkdbg(DBG_0, "StatusPhase1 (pid=%li)\n", srb->cmd->pid); - TRACEPRINTF("STP1 *"); - /* Cleanup is now done at the end of DataXXPhase0 */ - /*cleanup_after_transfer (acb, srb); */ - +static void status_phase1(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb, + u16 *pscsi_status) +{ + dprintkdbg(DBG_0, "status_phase1: (pid#%li) <%02i-%i>\n", + srb->cmd->pid, srb->cmd->device->id, srb->cmd->device->lun); srb->state = SRB_STATUS; DC395x_write16(acb, TRM_S1040_SCSI_CONTROL, DO_DATALATCH); /* it's important for atn stop */ - /* - * SCSI command - */ DC395x_write8(acb, TRM_S1040_SCSI_COMMAND, SCMD_COMP); } -/* Message handling */ - -#if 0 -/* Print received message */ -static void print_msg(u8 * msg_buf, u32 len) -{ - int i; - printk(" %02x", msg_buf[0]); - for (i = 1; i < len; i++) - printk(" %02x", msg_buf[i]); - printk("\n"); -} -#endif /* Check if the message is complete */ static inline u8 msgin_completed(u8 * msgbuf, u32 len) @@ -3260,53 +2585,44 @@ /* reject_msg */ -static inline -void msgin_reject(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb) +static inline void msgin_reject(struct AdapterCtlBlk *acb, + struct ScsiReqBlk *srb) { srb->msgout_buf[0] = MESSAGE_REJECT; srb->msg_count = 1; DC395x_ENABLE_MSGOUT; srb->state &= ~SRB_MSGIN; srb->state |= SRB_MSGOUT; - dprintkl(KERN_INFO, - "Reject message %02x from %02i-%i\n", srb->msgin_buf[0], - srb->dcb->target_id, srb->dcb->target_lun); - TRACEPRINTF("\\*"); + dprintkl(KERN_INFO, "msgin_reject: 0x%02x <%02i-%i>\n", + srb->msgin_buf[0], + srb->dcb->target_id, srb->dcb->target_lun); } /* abort command */ -static inline -void enable_msgout_abort(struct AdapterCtlBlk *acb, - struct ScsiReqBlk *srb) +static inline void enable_msgout_abort(struct AdapterCtlBlk *acb, + struct ScsiReqBlk *srb) { srb->msgout_buf[0] = ABORT; srb->msg_count = 1; DC395x_ENABLE_MSGOUT; srb->state &= ~SRB_MSGIN; srb->state |= SRB_MSGOUT; - /* - if (srb->dcb) - srb->dcb->flag &= ~ABORT_DEV_; - */ - TRACEPRINTF("#*"); } -static -struct ScsiReqBlk *msgin_qtag(struct AdapterCtlBlk *acb, - struct DeviceCtlBlk *dcb, - u8 tag) +static struct ScsiReqBlk *msgin_qtag(struct AdapterCtlBlk *acb, + struct DeviceCtlBlk *dcb, u8 tag) { struct ScsiReqBlk *srb = NULL; struct ScsiReqBlk *i; - + dprintkdbg(DBG_0, "msgin_qtag: (pid#%li) tag=%i srb=%p\n", + srb->cmd->pid, tag, srb); - dprintkdbg(DBG_0, "QTag Msg (SRB %p): %i\n", srb, tag); if (!(dcb->tag_mask & (1 << tag))) dprintkl(KERN_DEBUG, - "MsgIn_QTag: tag_mask (%08x) does not reserve tag %i!\n", - dcb->tag_mask, tag); + "msgin_qtag: tag_mask=0x%08x does not reserve tag %i!\n", + dcb->tag_mask, tag); if (list_empty(&dcb->srb_going_list)) goto mingx0; @@ -3319,8 +2635,8 @@ if (!srb) goto mingx0; - dprintkdbg(DBG_0, "pid %li (%i-%i)\n", srb->cmd->pid, - srb->dcb->target_id, srb->dcb->target_lun); + dprintkdbg(DBG_0, "msgin_qtag: (pid#%li) <%02i-%i>\n", + srb->cmd->pid, srb->dcb->target_id, srb->dcb->target_lun); if (dcb->flag & ABORT_DEV_) { /*srb->state = SRB_ABORT_SENT; */ enable_msgout_abort(acb, srb); @@ -3329,20 +2645,6 @@ if (!(srb->state & SRB_DISCONNECT)) goto mingx0; - /* Tag found */ - { - struct ScsiReqBlk *last_srb; - - TRACEPRINTF("[%s]*", dcb->active_srb->debugtrace); - TRACEPRINTF("RTag*"); - /* Just for debugging ... */ - - last_srb = srb; - srb = dcb->active_srb; - TRACEPRINTF("Found.*"); - srb = last_srb; - } - memcpy(srb->msgin_buf, dcb->active_srb->msgin_buf, acb->msg_len); srb->state |= dcb->active_srb->state; srb->state |= SRB_DATA_XFER; @@ -3357,15 +2659,13 @@ srb->msgout_buf[0] = MSG_ABORT_TAG; srb->msg_count = 1; DC395x_ENABLE_MSGOUT; - TRACEPRINTF("?*"); - dprintkl(KERN_DEBUG, "Unknown tag received: %i: abort !!\n", tag); + dprintkl(KERN_DEBUG, "msgin_qtag: Unknown tag %i - abort\n", tag); return srb; } -/* Reprogram registers */ -static inline void -reprogram_regs(struct AdapterCtlBlk *acb, struct DeviceCtlBlk *dcb) +static inline void reprogram_regs(struct AdapterCtlBlk *acb, + struct DeviceCtlBlk *dcb) { DC395x_write8(acb, TRM_S1040_SCSI_TARGETID, dcb->target_id); DC395x_write8(acb, TRM_S1040_SCSI_SYNC, dcb->sync_period); @@ -3375,12 +2675,12 @@ /* set async transfer mode */ -static -void msgin_set_async(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb) +static void msgin_set_async(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb) { struct DeviceCtlBlk *dcb = srb->dcb; - dprintkl(KERN_DEBUG, "Target %02i: No sync transfers\n", dcb->target_id); - TRACEPRINTF("!S *"); + dprintkl(KERN_DEBUG, "msgin_set_async: No sync transfers <%02i-%i>\n", + dcb->target_id, dcb->target_lun); + dcb->sync_mode &= ~(SYNC_NEGO_ENABLE); dcb->sync_mode |= SYNC_NEGO_DONE; /*dcb->sync_period &= 0; */ @@ -3392,26 +2692,23 @@ && !(dcb->sync_mode & WIDE_NEGO_DONE)) { build_wdtr(acb, dcb, srb); DC395x_ENABLE_MSGOUT; - dprintkdbg(DBG_0, "SDTR(rej): Try WDTR anyway ...\n"); + dprintkdbg(DBG_0, "msgin_set_async(rej): Try WDTR anyway\n"); } } /* set sync transfer mode */ -static -void msgin_set_sync(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb) +static void msgin_set_sync(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb) { + struct DeviceCtlBlk *dcb = srb->dcb; u8 bval; int fact; - struct DeviceCtlBlk *dcb = srb->dcb; - /*u8 oldsyncperiod = dcb->sync_period; */ - /*u8 oldsyncoffset = dcb->sync_offset; */ - - dprintkdbg(DBG_1, "Target %02i: Sync: %ins (%02i.%01i MHz) Offset %i\n", - dcb->target_id, srb->msgin_buf[3] << 2, - (250 / srb->msgin_buf[3]), - ((250 % srb->msgin_buf[3]) * 10) / srb->msgin_buf[3], - srb->msgin_buf[4]); + dprintkdbg(DBG_1, "msgin_set_sync: <%02i> Sync: %ins " + "(%02i.%01i MHz) Offset %i\n", + dcb->target_id, srb->msgin_buf[3] << 2, + (250 / srb->msgin_buf[3]), + ((250 % srb->msgin_buf[3]) * 10) / srb->msgin_buf[3], + srb->msgin_buf[4]); if (srb->msgin_buf[4] > 15) srb->msgin_buf[4] = 15; @@ -3430,8 +2727,8 @@ bval++; if (srb->msgin_buf[3] < clock_period[bval]) dprintkl(KERN_INFO, - "Increase sync nego period to %ins\n", - clock_period[bval] << 2); + "msgin_set_sync: Increase sync nego period to %ins\n", + clock_period[bval] << 2); srb->msgin_buf[3] = clock_period[bval]; dcb->sync_period &= 0xf0; dcb->sync_period |= ALT_SYNC | bval; @@ -3443,18 +2740,17 @@ fact = 250; dprintkl(KERN_INFO, - "Target %02i: %s Sync: %ins Offset %i (%02i.%01i MB/s)\n", - dcb->target_id, (fact == 500) ? "Wide16" : "", - dcb->min_nego_period << 2, dcb->sync_offset, - (fact / dcb->min_nego_period), - ((fact % dcb->min_nego_period) * 10 + + "Target %02i: %s Sync: %ins Offset %i (%02i.%01i MB/s)\n", + dcb->target_id, (fact == 500) ? "Wide16" : "", + dcb->min_nego_period << 2, dcb->sync_offset, + (fact / dcb->min_nego_period), + ((fact % dcb->min_nego_period) * 10 + dcb->min_nego_period / 2) / dcb->min_nego_period); - TRACEPRINTF("S%i *", dcb->min_nego_period << 2); if (!(srb->state & SRB_DO_SYNC_NEGO)) { /* Reply with corrected SDTR Message */ - dprintkl(KERN_DEBUG, " .. answer w/ %ins %i\n", - srb->msgin_buf[3] << 2, srb->msgin_buf[4]); + dprintkl(KERN_DEBUG, "msgin_set_sync: answer w/%ins %i\n", + srb->msgin_buf[3] << 2, srb->msgin_buf[4]); memcpy(srb->msgout_buf, srb->msgin_buf, 5); srb->msg_count = 5; @@ -3465,7 +2761,7 @@ && !(dcb->sync_mode & WIDE_NEGO_DONE)) { build_wdtr(acb, dcb, srb); DC395x_ENABLE_MSGOUT; - dprintkdbg(DBG_0, "SDTR: Also try WDTR ...\n"); + dprintkdbg(DBG_0, "msgin_set_sync: Also try WDTR\n"); } } srb->state &= ~SRB_DO_SYNC_NEGO; @@ -3475,14 +2771,12 @@ } -static inline -void msgin_set_nowide(struct AdapterCtlBlk *acb, - struct ScsiReqBlk *srb) +static inline void msgin_set_nowide(struct AdapterCtlBlk *acb, + struct ScsiReqBlk *srb) { struct DeviceCtlBlk *dcb = srb->dcb; - dprintkdbg(DBG_KG, "WDTR got rejected from target %02i\n", - dcb->target_id); - TRACEPRINTF("!W *"); + dprintkdbg(DBG_1, "msgin_set_nowide: <%02i>\n", dcb->target_id); + dcb->sync_period &= ~WIDE_SYNC; dcb->sync_mode &= ~(WIDE_NEGO_ENABLE); dcb->sync_mode |= WIDE_NEGO_DONE; @@ -3492,23 +2786,24 @@ && !(dcb->sync_mode & SYNC_NEGO_DONE)) { build_sdtr(acb, dcb, srb); DC395x_ENABLE_MSGOUT; - dprintkdbg(DBG_0, "WDTR(rej): Try SDTR anyway ...\n"); + dprintkdbg(DBG_0, "msgin_set_nowide: Rejected. Try SDTR anyway\n"); } } -static -void msgin_set_wide(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb) +static void msgin_set_wide(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb) { struct DeviceCtlBlk *dcb = srb->dcb; u8 wide = (dcb->dev_mode & NTC_DO_WIDE_NEGO && acb->config & HCC_WIDE_CARD) ? 1 : 0; + dprintkdbg(DBG_1, "msgin_set_wide: <%02i>\n", dcb->target_id); + if (srb->msgin_buf[3] > wide) srb->msgin_buf[3] = wide; /* Completed */ if (!(srb->state & SRB_DO_WIDE_NEGO)) { dprintkl(KERN_DEBUG, - "Target %02i initiates Wide Nego ...\n", - dcb->target_id); + "msgin_set_wide: Wide nego initiated <%02i>\n", + dcb->target_id); memcpy(srb->msgout_buf, srb->msgin_buf, 4); srb->msg_count = 4; srb->state |= SRB_DO_WIDE_NEGO; @@ -3521,28 +2816,21 @@ else dcb->sync_period &= ~WIDE_SYNC; srb->state &= ~SRB_DO_WIDE_NEGO; - TRACEPRINTF("W%i *", (dcb->sync_period & WIDE_SYNC ? 1 : 0)); /*dcb->sync_mode &= ~(WIDE_NEGO_ENABLE+WIDE_NEGO_DONE); */ - dprintkdbg(DBG_KG, - "Wide transfers (%i bit) negotiated with target %02i\n", - (8 << srb->msgin_buf[3]), dcb->target_id); + dprintkdbg(DBG_1, + "msgin_set_wide: Wide (%i bit) negotiated <%02i>\n", + (8 << srb->msgin_buf[3]), dcb->target_id); reprogram_regs(acb, dcb); if ((dcb->sync_mode & SYNC_NEGO_ENABLE) && !(dcb->sync_mode & SYNC_NEGO_DONE)) { build_sdtr(acb, dcb, srb); DC395x_ENABLE_MSGOUT; - dprintkdbg(DBG_0, "WDTR: Also try SDTR ...\n"); + dprintkdbg(DBG_0, "msgin_set_wide: Also try SDTR.\n"); } } /* - ******************************************************************** - * scsiio - * msgin_phase0: one of dc395x_scsi_phase0[] vectors - * dc395x_statev = (void *)dc395x_scsi_phase0[phase] - * if phase =7 - * * extended message codes: * * code description @@ -3553,25 +2841,15 @@ * 03h WIDE DATA TRANSFER REQUEST * 04h - 7Fh Reserved * 80h - FFh Vendor specific - * - ******************************************************************** */ -static -void msgin_phase0(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb, - u16 * pscsi_status) +static void msgin_phase0(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb, + u16 *pscsi_status) { - struct DeviceCtlBlk *dcb; - - dprintkdbg(DBG_0, "msgin_phase0..............\n"); - TRACEPRINTF("MIP0*"); - dcb = acb->active_dcb; + struct DeviceCtlBlk *dcb = acb->active_dcb; + dprintkdbg(DBG_0, "msgin_phase0: (pid#%li)\n", srb->cmd->pid); srb->msgin_buf[acb->msg_len++] = DC395x_read8(acb, TRM_S1040_SCSI_FIFO); if (msgin_completed(srb->msgin_buf, acb->msg_len)) { - TRACEPRINTF("(%02x)*", srb->msgin_buf[0]); - /*dprintkl(KERN_INFO, "MsgIn:"); */ - /*print_msg (srb->msgin_buf, acb->msg_len); */ - /* Now eval the msg */ switch (srb->msgin_buf[0]) { case DISCONNECT: @@ -3581,7 +2859,6 @@ case SIMPLE_QUEUE_TAG: case HEAD_OF_QUEUE_TAG: case ORDERED_QUEUE_TAG: - TRACEPRINTF("(%02x)*", srb->msgin_buf[1]); srb = msgin_qtag(acb, dcb, srb->msgin_buf[1]); @@ -3605,7 +2882,6 @@ break; case EXTENDED_MESSAGE: - TRACEPRINTF("(%02x)*", srb->msgin_buf[2]); /* SDTR */ if (srb->msgin_buf[1] == 3 && srb->msgin_buf[2] == EXTENDED_SDTR) { @@ -3613,52 +2889,51 @@ break; } /* WDTR */ - if (srb->msgin_buf[1] == 2 && srb->msgin_buf[2] == EXTENDED_WDTR && srb->msgin_buf[3] <= 2) { /* sanity check ... */ + if (srb->msgin_buf[1] == 2 + && srb->msgin_buf[2] == EXTENDED_WDTR + && srb->msgin_buf[3] <= 2) { /* sanity check ... */ msgin_set_wide(acb, srb); break; } msgin_reject(acb, srb); break; - /* Discard wide residual */ case MSG_IGNOREWIDE: - dprintkdbg(DBG_0, "Ignore Wide Residual!\n"); - /*DC395x_write32 (TRM_S1040_SCSI_COUNTER, 1); */ - /*DC395x_read8 (TRM_S1040_SCSI_FIFO); */ + /* Discard wide residual */ + dprintkdbg(DBG_0, "msgin_phase0: Ignore Wide Residual!\n"); break; - /* nothing has to be done */ case COMMAND_COMPLETE: + /* nothing has to be done */ break; + case SAVE_POINTERS: /* - * SAVE POINTER may be ignored as we have the struct ScsiReqBlk* associated with the - * scsi command. Thanks, Gérard, for pointing it out. + * SAVE POINTER may be ignored as we have the struct + * ScsiReqBlk* associated with the scsi command. */ - case SAVE_POINTERS: - dprintkdbg(DBG_0, "SAVE POINTER message received (pid %li: rem.%i) ... ignore :-(\n", - srb->cmd->pid, srb->total_xfer_length); - /*srb->Saved_Ptr = srb->TotalxferredLen; */ + dprintkdbg(DBG_0, "msgin_phase0: (pid#%li) " + "SAVE POINTER rem=%i Ignore\n", + srb->cmd->pid, srb->total_xfer_length); break; - /* The device might want to restart transfer with a RESTORE */ + case RESTORE_POINTERS: - dprintkl(KERN_DEBUG, - "RESTORE POINTER message received ... ignore :-(\n"); - /*dc395x_restore_ptr (acb, srb); */ + dprintkdbg(DBG_0, "msgin_phase0: RESTORE POINTER. Ignore\n"); break; + case ABORT: - dprintkl(KERN_DEBUG, - "ABORT msg received (pid %li %02i-%i)\n", - srb->cmd->pid, dcb->target_id, - dcb->target_lun); + dprintkdbg(DBG_0, "msgin_phase0: (pid#%li) " + "<%02i-%i> ABORT msg\n", + srb->cmd->pid, dcb->target_id, + dcb->target_lun); dcb->flag |= ABORT_DEV_; enable_msgout_abort(acb, srb); break; - /* reject unknown messages */ + default: + /* reject unknown messages */ if (srb->msgin_buf[0] & IDENTIFY_BASE) { - dprintkl(KERN_DEBUG, "Identify Message received?\n"); - /*TRACEOUT (" %s\n", srb->debugtrace); */ + dprintkdbg(DBG_0, "msgin_phase0: Identify msg\n"); srb->msg_count = 1; srb->msgout_buf[0] = dcb->identify_msg; DC395x_ENABLE_MSGOUT; @@ -3666,104 +2941,51 @@ /*break; */ } msgin_reject(acb, srb); - TRACEOUT(" %s\n", srb->debugtrace); } - TRACEPRINTF(".*"); /* Clear counter and MsgIn state */ srb->state &= ~SRB_MSGIN; acb->msg_len = 0; } - - /*1.25 */ - if ((*pscsi_status & PHASEMASK) != PH_MSG_IN) -#if 0 - clear_fifo(acb, "MIP0_"); -#else - TRACEPRINTF("N/Cln *"); -#endif *pscsi_status = PH_BUS_FREE; DC395x_write16(acb, TRM_S1040_SCSI_CONTROL, DO_DATALATCH); /* it's important ... you know! */ DC395x_write8(acb, TRM_S1040_SCSI_COMMAND, SCMD_MSGACCEPT); } -/* - ******************************************************************** - * scsiio - * msgin_phase1: one of dc395x_scsi_phase1[] vectors - * dc395x_statev = (void *)dc395x_scsi_phase1[phase] - * if phase =7 - ******************************************************************** - */ -static -void msgin_phase1(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb, - u16 * pscsi_status) -{ - dprintkdbg(DBG_0, "msgin_phase1..............\n"); - TRACEPRINTF("MIP1 *"); - clear_fifo(acb, "MIP1"); +static void msgin_phase1(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb, + u16 *pscsi_status) +{ + dprintkdbg(DBG_0, "msgin_phase1: (pid#%li)\n", srb->cmd->pid); + clear_fifo(acb, "msgin_phase1"); DC395x_write32(acb, TRM_S1040_SCSI_COUNTER, 1); if (!(srb->state & SRB_MSGIN)) { srb->state &= ~SRB_DISCONNECT; srb->state |= SRB_MSGIN; } DC395x_write16(acb, TRM_S1040_SCSI_CONTROL, DO_DATALATCH); /* it's important for atn stop */ - /* - * SCSI command - */ + /* SCSI command */ DC395x_write8(acb, TRM_S1040_SCSI_COMMAND, SCMD_FIFO_IN); } -/* - ******************************************************************** - * scsiio - * nop0: one of dc395x_scsi_phase1[] ,dc395x_scsi_phase0[] vectors - * dc395x_statev = (void *)dc395x_scsi_phase0[phase] - * dc395x_statev = (void *)dc395x_scsi_phase1[phase] - * if phase =4 ..PH_BUS_FREE - ******************************************************************** - */ -static -void nop0(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb, - u16 * pscsi_status) +static void nop0(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb, + u16 *pscsi_status) { - /*TRACEPRINTF("NOP0 *"); */ } -/* - ******************************************************************** - * scsiio - * nop1: one of dc395x_scsi_phase0[] ,dc395x_scsi_phase1[] vectors - * dc395x_statev = (void *)dc395x_scsi_phase0[phase] - * dc395x_statev = (void *)dc395x_scsi_phase1[phase] - * if phase =5 - ******************************************************************** - */ -static -void nop1(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb, - u16 * pscsi_status) +static void nop1(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb, + u16 *pscsi_status) { - /*TRACEPRINTF("NOP1 *"); */ } -/* - ******************************************************************** - * scsiio - * msgin_phase0 - ******************************************************************** - */ -static -void set_xfer_rate(struct AdapterCtlBlk *acb, struct DeviceCtlBlk *dcb) +static void set_xfer_rate(struct AdapterCtlBlk *acb, struct DeviceCtlBlk *dcb) { struct DeviceCtlBlk *i; - /* - * set all lun device's period , offset - */ + /* set all lun device's period, offset */ if (dcb->identify_msg & 0x07) return; @@ -3782,47 +3004,39 @@ } -/* - ******************************************************************** - * scsiio - * dc395x_interrupt - ******************************************************************** - */ static void disconnect(struct AdapterCtlBlk *acb) { - struct DeviceCtlBlk *dcb; + struct DeviceCtlBlk *dcb = acb->active_dcb; struct ScsiReqBlk *srb; - dprintkdbg(DBG_0, "Disconnect (pid=%li)\n", acb->active_dcb->active_srb->cmd->pid); - dcb = acb->active_dcb; if (!dcb) { - dprintkl(KERN_ERR, "Disc: Exception Disconnect dcb=NULL !!\n "); + dprintkl(KERN_ERR, "disconnect: No such device\n"); udelay(500); /* Suspend queue for a while */ acb->scsi_host->last_reset = jiffies + HZ / 2 + HZ * acb->eeprom.delay_time; - clear_fifo(acb, "DiscEx"); + clear_fifo(acb, "disconnectEx"); DC395x_write16(acb, TRM_S1040_SCSI_CONTROL, DO_HWRESELECT); return; } srb = dcb->active_srb; acb->active_dcb = NULL; - TRACEPRINTF("DISC *"); + dprintkdbg(DBG_0, "disconnect: (pid#%li)\n", srb->cmd->pid); srb->scsi_phase = PH_BUS_FREE; /* initial phase */ - clear_fifo(acb, "Disc"); + clear_fifo(acb, "disconnect"); DC395x_write16(acb, TRM_S1040_SCSI_CONTROL, DO_HWRESELECT); if (srb->state & SRB_UNEXPECT_RESEL) { - dprintkl(KERN_ERR, "Disc: Unexpected Reselection (%i-%i)\n", - dcb->target_id, dcb->target_lun); + dprintkl(KERN_ERR, + "disconnect: Unexpected reselection <%02i-%i>\n", + dcb->target_id, dcb->target_lun); srb->state = 0; waiting_process_next(acb); } else if (srb->state & SRB_ABORT_SENT) { - /*Scsi_Cmnd* cmd = srb->cmd; */ dcb->flag &= ~ABORT_DEV_; acb->scsi_host->last_reset = jiffies + HZ / 2 + 1; - dprintkl(KERN_ERR, "Disc: SRB_ABORT_SENT!\n"); + dprintkl(KERN_ERR, "disconnect: SRB_ABORT_SENT\n"); doing_srb_done(acb, DID_ABORT, srb->cmd, 1); waiting_process_next(acb); } else { @@ -3837,19 +3051,16 @@ if (srb->state != SRB_START_ && srb->state != SRB_MSGOUT) { srb->state = SRB_READY; - dprintkl(KERN_DEBUG, "Unexpected Disconnection (pid %li)!\n", - srb->cmd->pid); + dprintkl(KERN_DEBUG, + "disconnect: (pid#%li) Unexpected\n", + srb->cmd->pid); srb->target_status = SCSI_STAT_SEL_TIMEOUT; - TRACEPRINTF("UnExpD *"); - TRACEOUT("%s\n", srb->debugtrace); goto disc1; } else { /* Normal selection timeout */ - TRACEPRINTF("SlTO *"); - dprintkdbg(DBG_KG, - "Disc: SelTO (pid=%li) for dev %02i-%i\n", - srb->cmd->pid, dcb->target_id, - dcb->target_lun); + dprintkdbg(DBG_KG, "disconnect: (pid#%li) " + "<%02i-%i> SelTO\n", srb->cmd->pid, + dcb->target_id, dcb->target_lun); if (srb->retry_count++ > DC395x_MAX_RETRIES || acb->scan_devices) { srb->target_status = @@ -3858,8 +3069,9 @@ } free_tag(dcb, srb); srb_going_to_waiting_move(dcb, srb); - dprintkdbg(DBG_KG, "Retry pid %li ...\n", - srb->cmd->pid); + dprintkdbg(DBG_KG, + "disconnect: (pid#%li) Retry\n", + srb->cmd->pid); waiting_set_timer(acb, HZ / 20); } } else if (srb->state & SRB_DISCONNECT) { @@ -3867,18 +3079,11 @@ /* * SRB_DISCONNECT (This is what we expect!) */ - /* dprintkl(KERN_DEBUG, "DoWaitingSRB (pid=%li)\n", srb->cmd->pid); */ - TRACEPRINTF("+*"); if (bval & 0x40) { - dprintkdbg(DBG_0, "Debug: DISC: SCSI bus stat %02x: ACK set! Other controllers?\n", + dprintkdbg(DBG_0, "disconnect: SCSI bus stat " + " 0x%02x: ACK set! Other controllers?\n", bval); /* It could come from another initiator, therefore don't do much ! */ - TRACEPRINTF("ACK(%02x) *", bval); - /*dump_register_info (acb, dcb, srb); */ - /*TRACEOUT (" %s\n", srb->debugtrace); */ - /*dcb->flag |= ABORT_DEV_; */ - /*enable_msgout_abort (acb, srb); */ - /*DC395x_write16 (TRM_S1040_SCSI_CONTROL, DO_CLRFIFO | DO_CLRATN | DO_HWRESELECT); */ } else waiting_process_next(acb); } else if (srb->state & SRB_COMPLETED) { @@ -3889,51 +3094,40 @@ free_tag(dcb, srb); dcb->active_srb = NULL; srb->state = SRB_FREE; - /*dprintkl(KERN_DEBUG, "done (pid=%li)\n", srb->cmd->pid); */ srb_done(acb, dcb, srb); } } - return; } -/* - ******************************************************************** - * scsiio - * reselect - ******************************************************************** - */ static void reselect(struct AdapterCtlBlk *acb) { - struct DeviceCtlBlk *dcb; + struct DeviceCtlBlk *dcb = acb->active_dcb; struct ScsiReqBlk *srb = NULL; u16 rsel_tar_lun_id; u8 id, lun; u8 arblostflag = 0; + dprintkdbg(DBG_0, "reselect: acb=%p\n", acb); - dprintkdbg(DBG_0, "reselect..............\n"); - - clear_fifo(acb, "Resel"); + clear_fifo(acb, "reselect"); /*DC395x_write16(acb, TRM_S1040_SCSI_CONTROL, DO_HWRESELECT | DO_DATALATCH); */ /* Read Reselected Target ID and LUN */ rsel_tar_lun_id = DC395x_read16(acb, TRM_S1040_SCSI_TARGETID); - dcb = acb->active_dcb; if (dcb) { /* Arbitration lost but Reselection win */ srb = dcb->active_srb; if (!srb) { - dprintkl(KERN_DEBUG, "Arb lost Resel won, but active_srb == NULL!\n"); + dprintkl(KERN_DEBUG, "reselect: Arb lost Resel won, " + "but active_srb == NULL\n"); DC395x_write16(acb, TRM_S1040_SCSI_CONTROL, DO_DATALATCH); /* it's important for atn stop */ return; } /* Why the if ? */ - if (!(acb->scan_devices)) { - dprintkdbg(DBG_KG, - "Arb lost but Resel win pid %li (%02i-%i) Rsel %04x Stat %04x\n", - srb->cmd->pid, dcb->target_id, - dcb->target_lun, rsel_tar_lun_id, - DC395x_read16(acb, TRM_S1040_SCSI_STATUS)); - TRACEPRINTF("ArbLResel!*"); - /*TRACEOUT (" %s\n", srb->debugtrace); */ + if (!acb->scan_devices) { + dprintkdbg(DBG_KG, "reselect: (pid#%li) <%02i-%i> " + "Arb lost but Resel win rsel=%i stat=0x%04x\n", + srb->cmd->pid, dcb->target_id, + dcb->target_lun, rsel_tar_lun_id, + DC395x_read16(acb, TRM_S1040_SCSI_STATUS)); arblostflag = 1; /*srb->state |= SRB_DISCONNECT; */ @@ -3947,47 +3141,37 @@ } /* Read Reselected Target Id and LUN */ if (!(rsel_tar_lun_id & (IDENTIFY_BASE << 8))) - dprintkl(KERN_DEBUG, "Resel expects identify msg! Got %04x!\n", - rsel_tar_lun_id); + dprintkl(KERN_DEBUG, "reselect: Expects identify msg. " + "Got %i!\n", rsel_tar_lun_id); id = rsel_tar_lun_id & 0xff; lun = (rsel_tar_lun_id >> 8) & 7; dcb = find_dcb(acb, id, lun); if (!dcb) { - dprintkl(KERN_ERR, "Reselect from non existing device (%02i-%i)\n", - id, lun); + dprintkl(KERN_ERR, "reselect: From non existent device " + "<%02i-%i>\n", id, lun); DC395x_write16(acb, TRM_S1040_SCSI_CONTROL, DO_DATALATCH); /* it's important for atn stop */ return; } - acb->active_dcb = dcb; if (!(dcb->dev_mode & NTC_DO_DISCONNECT)) - dprintkl(KERN_DEBUG, "Reselection in spite of forbidden disconnection? (%02i-%i)\n", - dcb->target_id, dcb->target_lun); + dprintkl(KERN_DEBUG, "reselect: in spite of forbidden " + "disconnection? <%02i-%i>\n", + dcb->target_id, dcb->target_lun); - if ((dcb->sync_mode & EN_TAG_QUEUEING) /*&& !arblostflag */ ) { - struct ScsiReqBlk *oldSRB = srb; + if (dcb->sync_mode & EN_TAG_QUEUEING /*&& !arblostflag */) { srb = acb->tmp_srb; -#if debug_enabled(DBG_TRACE|DBG_TRACEALL) - srb->debugpos = 0; - srb->debugtrace[0] = 0; -#endif dcb->active_srb = srb; - if (oldSRB) - TRACEPRINTF("ArbLResel(%li):*", oldSRB->cmd->pid); - /*if (arblostflag) dprintkl(KERN_DEBUG, "Reselect: Wait for Tag ... \n"); */ } else { /* There can be only one! */ srb = dcb->active_srb; - if (srb) - TRACEPRINTF("RSel *"); if (!srb || !(srb->state & SRB_DISCONNECT)) { /* * abort command */ dprintkl(KERN_DEBUG, - "Reselected w/o disconnected cmds from %02i-%i?\n", - dcb->target_id, dcb->target_lun); + "reselect: w/o disconnected cmds <%02i-%i>\n", + dcb->target_id, dcb->target_lun); srb = acb->tmp_srb; srb->state = SRB_UNEXPECT_RESEL; dcb->active_srb = srb; @@ -4000,14 +3184,11 @@ srb->state = SRB_DATA_XFER; } - /*if (arblostflag) TRACEOUT (" %s\n", srb->debugtrace); */ } srb->scsi_phase = PH_BUS_FREE; /* initial phase */ - /* - *********************************************** - ** Program HA ID, target ID, period and offset - *********************************************** - */ + + /* Program HA ID, target ID, period and offset */ + dprintkdbg(DBG_0, "reselect: select <%i>\n", dcb->target_id); DC395x_write8(acb, TRM_S1040_SCSI_HOSTID, acb->scsi_host->this_id); /* host ID */ DC395x_write8(acb, TRM_S1040_SCSI_TARGETID, dcb->target_id); /* target ID */ DC395x_write8(acb, TRM_S1040_SCSI_OFFSET, dcb->sync_offset); /* offset */ @@ -4018,10 +3199,6 @@ } - - - - static inline u8 tagq_blacklist(char *name) { #ifndef DC395x_NO_TAGQ @@ -4038,8 +3215,7 @@ } -static -void disc_tagq_set(struct DeviceCtlBlk *dcb, struct ScsiInqData *ptr) +static void disc_tagq_set(struct DeviceCtlBlk *dcb, struct ScsiInqData *ptr) { /* Check for SCSI format (ANSI and Response data format) */ if ((ptr->Vers & 0x07) >= 2 || (ptr->RDF & 0x0F) == 2) { @@ -4048,7 +3224,7 @@ /*(dcb->dev_mode & NTC_DO_DISCONNECT) */ /* ((dcb->dev_type == TYPE_DISK) || (dcb->dev_type == TYPE_MOD)) && */ - !tagq_blacklist(((char *) ptr) + 8)) { + !tagq_blacklist(((char *)ptr) + 8)) { if (dcb->max_command == 1) dcb->max_command = dcb->acb->tag_max_num; @@ -4060,9 +3236,8 @@ } -static -void add_dev(struct AdapterCtlBlk *acb, struct DeviceCtlBlk *dcb, - struct ScsiInqData *ptr) +static void add_dev(struct AdapterCtlBlk *acb, struct DeviceCtlBlk *dcb, + struct ScsiInqData *ptr) { u8 bval1 = ptr->DevType & SCSI_DEVTYPE; dcb->dev_type = bval1; @@ -4071,59 +3246,45 @@ } -/* - ******************************************************************** - * unmap mapped pci regions from SRB - ******************************************************************** - */ -static -void pci_unmap_srb(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb) +/* unmap mapped pci regions from SRB */ +static void pci_unmap_srb(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb) { - int dir; Scsi_Cmnd *cmd = srb->cmd; - dir = scsi_to_pci_dma_dir(cmd->sc_data_direction); + int dir = scsi_to_pci_dma_dir(cmd->sc_data_direction); if (cmd->use_sg && dir != PCI_DMA_NONE) { /* unmap DC395x SG list */ - dprintkdbg(DBG_SGPARANOIA, - "Unmap SG descriptor list %08x (%05x)\n", - srb->sg_bus_addr, - sizeof(struct SGentry) * DC395x_MAX_SG_LISTENTRY); + dprintkdbg(DBG_SG, "pci_unmap_srb: list=%08x(%05x)\n", + srb->sg_bus_addr, SEGMENTX_LEN); pci_unmap_single(acb->dev, srb->sg_bus_addr, - sizeof(struct SGentry) * - DC395x_MAX_SG_LISTENTRY, + SEGMENTX_LEN, PCI_DMA_TODEVICE); - dprintkdbg(DBG_SGPARANOIA, "Unmap %i SG segments from %p\n", - cmd->use_sg, cmd->request_buffer); + dprintkdbg(DBG_SG, "pci_unmap_srb: segs=%i buffer=%p\n", + cmd->use_sg, cmd->request_buffer); /* unmap the sg segments */ pci_unmap_sg(acb->dev, - (struct scatterlist *) cmd->request_buffer, + (struct scatterlist *)cmd->request_buffer, cmd->use_sg, dir); } else if (cmd->request_buffer && dir != PCI_DMA_NONE) { - dprintkdbg(DBG_SGPARANOIA, "Unmap buffer at %08x (%05x)\n", - srb->segment_x[0].address, cmd->request_bufflen); + dprintkdbg(DBG_SG, "pci_unmap_srb: buffer=%08x(%05x)\n", + srb->segment_x[0].address, cmd->request_bufflen); pci_unmap_single(acb->dev, srb->segment_x[0].address, cmd->request_bufflen, dir); } } -/* - ******************************************************************** - * unmap mapped pci sense buffer from SRB - ******************************************************************** - */ -static -void pci_unmap_srb_sense(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb) +/* unmap mapped pci sense buffer from SRB */ +static void pci_unmap_srb_sense(struct AdapterCtlBlk *acb, + struct ScsiReqBlk *srb) { if (!(srb->flag & AUTO_REQSENSE)) return; /* Unmap sense buffer */ - dprintkdbg(DBG_SGPARANOIA, "Unmap sense buffer from %08x\n", + dprintkdbg(DBG_SG, "pci_unmap_srb_sense: buffer=%08x\n", srb->segment_x[0].address); pci_unmap_single(acb->dev, srb->segment_x[0].address, srb->segment_x[0].length, PCI_DMA_FROMDEVICE); /* Restore SG stuff */ - /*printk ("Auto_ReqSense finished: Restore Counters ...\n"); */ srb->total_xfer_length = srb->xferred; srb->segment_x[0].address = srb->segment_x[DC395x_MAX_SG_LISTENTRY - 1].address; @@ -4133,42 +3294,33 @@ /* - ******************************************************************** - * scsiio - * disconnect - * Complete execution of a SCSI command - * Signal completion to the generic SCSI driver - ******************************************************************** + * Complete execution of a SCSI command + * Signal completion to the generic SCSI driver */ -static -void srb_done(struct AdapterCtlBlk *acb, struct DeviceCtlBlk *dcb, - struct ScsiReqBlk *srb) +static void srb_done(struct AdapterCtlBlk *acb, struct DeviceCtlBlk *dcb, + struct ScsiReqBlk *srb) { u8 tempcnt, status; - Scsi_Cmnd *cmd; + Scsi_Cmnd *cmd = srb->cmd; struct ScsiInqData *ptr; - /*u32 drv_flags=0; */ int dir; - cmd = srb->cmd; - TRACEPRINTF("DONE *"); - dir = scsi_to_pci_dma_dir(cmd->sc_data_direction); - ptr = (struct ScsiInqData *) (cmd->request_buffer); - if (cmd->use_sg) - ptr = - (struct ScsiInqData *) CPU_ADDR(*(struct scatterlist *) - ptr); - dprintkdbg(DBG_SGPARANOIA, - "SRBdone SG=%i (%i/%i), req_buf = %p, adr = %p\n", - cmd->use_sg, srb->sg_index, srb->sg_count, - cmd->request_buffer, ptr); - dprintkdbg(DBG_KG, - "SRBdone (pid %li, target %02i-%i): ", srb->cmd->pid, - srb->cmd->device->id, srb->cmd->device->lun); + if (cmd->use_sg) { + struct scatterlist* sg = (struct scatterlist *)cmd->request_buffer; + ptr = (struct ScsiInqData *)(page_address(sg->page) + sg->offset); + } else { + ptr = (struct ScsiInqData *)(cmd->request_buffer); + } + + dprintkdbg(DBG_1, "srb_done: (pid#%li) <%02i-%i>\n", srb->cmd->pid, + srb->cmd->device->id, srb->cmd->device->lun); + dprintkdbg(DBG_SG, "srb_done: srb=%p sg=%i(%i/%i) buf=%p addr=%p\n", + srb, cmd->use_sg, srb->sg_index, srb->sg_count, + cmd->request_buffer, ptr); status = srb->target_status; if (srb->flag & AUTO_REQSENSE) { - dprintkdbg(DBG_0, "AUTO_REQSENSE1..............\n"); + dprintkdbg(DBG_0, "srb_done: AUTO_REQSENSE1\n"); pci_unmap_srb_sense(acb, srb); /* ** target status.......................... @@ -4176,61 +3328,60 @@ srb->flag &= ~AUTO_REQSENSE; srb->adapter_status = 0; srb->target_status = CHECK_CONDITION << 1; - if (debug_enabled(DBG_KG)) { + if (debug_enabled(DBG_1)) { switch (cmd->sense_buffer[2] & 0x0f) { case NOT_READY: dprintkl(KERN_DEBUG, - "ReqSense: NOT_READY (Cmnd = 0x%02x, Dev = %i-%i, Stat = %i, Scan = %i) ", + "ReqSense: NOT_READY cmnd=0x%02x <%02i-%i> stat=%i scan=%i ", cmd->cmnd[0], dcb->target_id, dcb->target_lun, status, acb->scan_devices); break; case UNIT_ATTENTION: dprintkl(KERN_DEBUG, - "ReqSense: UNIT_ATTENTION (Cmnd = 0x%02x, Dev = %i-%i, Stat = %i, Scan = %i) ", + "ReqSense: UNIT_ATTENTION cmnd=0x%02x <%02i-%i> stat=%i scan=%i ", cmd->cmnd[0], dcb->target_id, dcb->target_lun, status, acb->scan_devices); break; case ILLEGAL_REQUEST: dprintkl(KERN_DEBUG, - "ReqSense: ILLEGAL_REQUEST (Cmnd = 0x%02x, Dev = %i-%i, Stat = %i, Scan = %i) ", + "ReqSense: ILLEGAL_REQUEST cmnd=0x%02x <%02i-%i> stat=%i scan=%i ", cmd->cmnd[0], dcb->target_id, dcb->target_lun, status, acb->scan_devices); break; case MEDIUM_ERROR: dprintkl(KERN_DEBUG, - "ReqSense: MEDIUM_ERROR (Cmnd = 0x%02x, Dev = %i-%i, Stat = %i, Scan = %i) ", + "ReqSense: MEDIUM_ERROR cmnd=0x%02x <%02i-%i> stat=%i scan=%i ", cmd->cmnd[0], dcb->target_id, dcb->target_lun, status, acb->scan_devices); break; case HARDWARE_ERROR: dprintkl(KERN_DEBUG, - "ReqSense: HARDWARE_ERROR (Cmnd = 0x%02x, Dev = %i-%i, Stat = %i, Scan = %i) ", + "ReqSense: HARDWARE_ERROR cmnd=0x%02x <%02i-%i> stat=%i scan=%i ", cmd->cmnd[0], dcb->target_id, dcb->target_lun, status, acb->scan_devices); break; } if (cmd->sense_buffer[7] >= 6) - dprintkl(KERN_DEBUG, - "Sense=%02x, ASC=%02x, ASCQ=%02x (%08x %08x) ", - cmd->sense_buffer[2], cmd->sense_buffer[12], - cmd->sense_buffer[13], - *((unsigned int *) (cmd->sense_buffer + 3)), - *((unsigned int *) (cmd->sense_buffer + 8))); + printk("sense=0x%02x ASC=0x%02x ASCQ=0x%02x " + "(0x%08x 0x%08x)\n", + cmd->sense_buffer[2], cmd->sense_buffer[12], + cmd->sense_buffer[13], + *((unsigned int *)(cmd->sense_buffer + 3)), + *((unsigned int *)(cmd->sense_buffer + 8))); else - dprintkl(KERN_DEBUG, - "Sense=%02x, No ASC/ASCQ (%08x) ", - cmd->sense_buffer[2], - *((unsigned int *) (cmd->sense_buffer + 3))); + printk("sense=0x%02x No ASC/ASCQ (0x%08x)\n", + cmd->sense_buffer[2], + *((unsigned int *)(cmd->sense_buffer + 3))); } if (status == (CHECK_CONDITION << 1)) { cmd->result = DID_BAD_TARGET << 16; goto ckc_e; } - dprintkdbg(DBG_0, "AUTO_REQSENSE2..............\n"); + dprintkdbg(DBG_0, "srb_done: AUTO_REQSENSE2\n"); - if ((srb->total_xfer_length) - && (srb->total_xfer_length >= cmd->underflow)) + if (srb->total_xfer_length + && srb->total_xfer_length >= cmd->underflow) cmd->result = MK_RES_LNX(DRIVER_SENSE, DID_OK, srb->end_message, CHECK_CONDITION); @@ -4253,8 +3404,7 @@ return; } else if (status_byte(status) == QUEUE_FULL) { tempcnt = (u8)list_size(&dcb->srb_going_list); - printk - ("\nDC395x: QUEUE_FULL for dev %02i-%i with %i cmnds\n", + dprintkl(KERN_INFO, "QUEUE_FULL for dev <%02i-%i> with %i cmnds\n", dcb->target_id, dcb->target_lun, tempcnt); if (tempcnt > 1) tempcnt--; @@ -4298,11 +3448,11 @@ if (dir != PCI_DMA_NONE) { if (cmd->use_sg) - pci_dma_sync_sg(acb->dev, - (struct scatterlist *) cmd-> + pci_dma_sync_sg_for_cpu(acb->dev, + (struct scatterlist *)cmd-> request_buffer, cmd->use_sg, dir); else if (cmd->request_buffer) - pci_dma_sync_single(acb->dev, + pci_dma_sync_single_for_cpu(acb->dev, srb->segment_x[0].address, cmd->request_bufflen, dir); } @@ -4336,48 +3486,35 @@ cmd->SCp.buffers_residual = 0; if (debug_enabled(DBG_KG)) { if (srb->total_xfer_length) - dprintkdbg(DBG_KG, "pid %li: %02x (%02i-%i): Missed %i bytes\n", - cmd->pid, cmd->cmnd[0], cmd->device->id, - cmd->device->lun, srb->total_xfer_length); + dprintkdbg(DBG_KG, "srb_done: (pid#%li) <%02i-%i> " + "cmnd=0x%02x Missed %i bytes\n", + cmd->pid, cmd->device->id, cmd->device->lun, + cmd->cmnd[0], srb->total_xfer_length); } srb_going_remove(dcb, srb); /* Add to free list */ if (srb == acb->tmp_srb) - dprintkl(KERN_ERR, "ERROR! Completed Cmnd with tmp_srb!\n"); - else + dprintkl(KERN_ERR, "srb_done: ERROR! Completed cmd with tmp_srb\n"); + else { + dprintkdbg(DBG_0, "srb_done: (pid#%li) done result=0x%08x\n", + cmd->pid, cmd->result); srb_free_insert(acb, srb); - - dprintkdbg(DBG_0, "SRBdone: done pid %li\n", cmd->pid); - if (debug_enabled(DBG_KG)) { - printk(" 0x%08x\n", cmd->result); } - TRACEPRINTF("%08x(%li)*", cmd->result, jiffies); pci_unmap_srb(acb, srb); - /*DC395x_UNLOCK_ACB_NI; */ - cmd->scsi_done(cmd); - /*DC395x_LOCK_ACB_NI; */ - TRACEOUTALL(KERN_INFO " %s\n", srb->debugtrace); + cmd->scsi_done(cmd); waiting_process_next(acb); - return; } -/* - ******************************************************************** - * scsiio - * DC395x_reset - * abort all cmds in our queues - ******************************************************************** - */ -static -void doing_srb_done(struct AdapterCtlBlk *acb, u8 did_flag, - Scsi_Cmnd * cmd, u8 force) +/* abort all cmds in our queues */ +static void doing_srb_done(struct AdapterCtlBlk *acb, u8 did_flag, + Scsi_Cmnd *cmd, u8 force) { struct DeviceCtlBlk *dcb; - dprintkl(KERN_INFO, "doing_srb_done: pids "); + list_for_each_entry(dcb, &acb->dcb_list, list) { struct ScsiReqBlk *srb; struct ScsiReqBlk *tmp; @@ -4390,16 +3527,8 @@ p = srb->cmd; dir = scsi_to_pci_dma_dir(p->sc_data_direction); result = MK_RES(0, did_flag, 0, 0); - - /*result = MK_RES(0,DID_RESET,0,0); */ - TRACEPRINTF("Reset(%li):%08x*", jiffies, result); - printk(" (G)"); -#if 1 /*ndef DC395x_DEBUGTRACE */ - printk("%li(%02i-%i) ", p->pid, + printk("G:%li(%02i-%i) ", p->pid, p->device->id, p->device->lun); -#endif - TRACEOUT("%s\n", srb->debugtrace); - srb_going_remove(dcb, srb); free_tag(dcb, srb); srb_free_insert(acb, srb); @@ -4414,11 +3543,11 @@ } if (!list_empty(&dcb->srb_going_list)) dprintkl(KERN_DEBUG, - "How could the ML send cmnds to the Going queue? (%02i-%i)!!\n", + "How could the ML send cmnds to the Going queue? <%02i-%i>\n", dcb->target_id, dcb->target_lun); if (dcb->tag_mask) dprintkl(KERN_DEBUG, - "tag_mask for %02i-%i should be empty, is %08x!\n", + "tag_mask for <%02i-%i> should be empty, is %08x!\n", dcb->target_id, dcb->target_lun, dcb->tag_mask); @@ -4428,16 +3557,10 @@ p = srb->cmd; result = MK_RES(0, did_flag, 0, 0); - TRACEPRINTF("Reset(%li):%08x*", jiffies, result); - printk(" (W)"); -#if 1 /*ndef DC395x_DEBUGTRACE */ - printk("%li(%i-%i)", p->pid, p->device->id, + printk("W:%li<%02i-%i>", p->pid, p->device->id, p->device->lun); -#endif - TRACEOUT("%s\n", srb->debugtrace); srb_waiting_remove(dcb, srb); srb_free_insert(acb, srb); - p->result = result; pci_unmap_srb_sense(acb, srb); pci_unmap_srb(acb, srb); @@ -4448,41 +3571,26 @@ } } if (!list_empty(&dcb->srb_waiting_list)) - printk - ("\nDC395x: Debug: ML queued %i cmnds again to %02i-%i\n", + dprintkl(KERN_DEBUG, "ML queued %i cmnds again to <%02i-%i>\n", list_size(&dcb->srb_waiting_list), dcb->target_id, dcb->target_lun); - dcb->flag &= ~ABORT_DEV_; } printk("\n"); } -/* - ******************************************************************** - * scsiio - * DC395x_shutdown DC395x_reset - ******************************************************************** - */ static void reset_scsi_bus(struct AdapterCtlBlk *acb) { - /*u32 drv_flags=0; */ - - dprintkdbg(DBG_0, "reset_scsi_bus..............\n"); - - /*DC395x_DRV_LOCK(drv_flags); */ + dprintkdbg(DBG_0, "reset_scsi_bus: acb=%p\n", acb); acb->acb_flag |= RESET_DEV; /* RESET_DETECT, RESET_DONE, RESET_DEV */ - DC395x_write16(acb, TRM_S1040_SCSI_CONTROL, DO_RSTSCSI); - while (!(DC395x_read8(acb, TRM_S1040_SCSI_INTSTATUS) & INT_SCSIRESET)); - /*DC395x_DRV_UNLOCK(drv_flags); */ - return; + while (!(DC395x_read8(acb, TRM_S1040_SCSI_INTSTATUS) & INT_SCSIRESET)) + /* nothing */; } -/* Set basic config */ static void set_basic_config(struct AdapterCtlBlk *acb) { u8 bval; @@ -4508,7 +3616,6 @@ wval = DC395x_read16(acb, TRM_S1040_DMA_CONFIG) & ~DMA_FIFO_CTRL; wval |= DMA_FIFO_HALF_HALF | DMA_ENHANCE /*| DMA_MEM_MULTI_READ */ ; - /*dprintkl(KERN_INFO, "DMA_Config: %04x\n", wval); */ DC395x_write16(acb, TRM_S1040_DMA_CONFIG, wval); /* Clear pending interrupt status */ DC395x_read8(acb, TRM_S1040_SCSI_INTSTATUS); @@ -4520,15 +3627,9 @@ } -/* - ******************************************************************** - * scsiio - * dc395x_interrupt - ******************************************************************** - */ static void scsi_reset_detect(struct AdapterCtlBlk *acb) { - dprintkl(KERN_INFO, "scsi_reset_detect\n"); + dprintkl(KERN_INFO, "scsi_reset_detect: acb=%p\n", acb); /* delay half a second */ if (timer_pending(&acb->waiting_timer)) del_timer(&acb->waiting_timer); @@ -4542,7 +3643,7 @@ jiffies + 5 * HZ / 2 + HZ * acb->eeprom.delay_time; - clear_fifo(acb, "RstDet"); + clear_fifo(acb, "scsi_reset_detect"); set_basic_config(acb); /*1.25 */ /*DC395x_write16(acb, TRM_S1040_SCSI_CONTROL, DO_HWRESELECT); */ @@ -4558,28 +3659,16 @@ acb->acb_flag = 0; waiting_process_next(acb); } - - return; } -/* - ******************************************************************** - * scsiio - * srb_done - ******************************************************************** - */ -static -void request_sense(struct AdapterCtlBlk *acb, struct DeviceCtlBlk *dcb, - struct ScsiReqBlk *srb) +static void request_sense(struct AdapterCtlBlk *acb, struct DeviceCtlBlk *dcb, + struct ScsiReqBlk *srb) { - Scsi_Cmnd *cmd; + Scsi_Cmnd *cmd = srb->cmd; + dprintkdbg(DBG_1, "request_sense: (pid#%li) <%02i-%i>\n", + cmd->pid, cmd->device->id, cmd->device->lun); - cmd = srb->cmd; - dprintkdbg(DBG_KG, - "request_sense for pid %li, target %02i-%i\n", - cmd->pid, cmd->device->id, cmd->device->lun); - TRACEPRINTF("RqSn*"); srb->flag |= AUTO_REQSENSE; srb->adapter_status = 0; srb->target_status = 0; @@ -4600,27 +3689,22 @@ srb->segment_x[0].address = pci_map_single(acb->dev, cmd->sense_buffer, sizeof(cmd->sense_buffer), PCI_DMA_FROMDEVICE); - dprintkdbg(DBG_SGPARANOIA, "Map sense buffer at %p (%05x) to %08x\n", - cmd->sense_buffer, sizeof(cmd->sense_buffer), - srb->segment_x[0].address); + dprintkdbg(DBG_SG, "request_sense: map buffer %p->%08x(%05x)\n", + cmd->sense_buffer, srb->segment_x[0].address, + sizeof(cmd->sense_buffer)); srb->sg_count = 1; srb->sg_index = 0; if (start_scsi(acb, dcb, srb)) { /* Should only happen, if sb. else grabs the bus */ dprintkl(KERN_DEBUG, - "Request Sense failed for pid %li (%02i-%i)!\n", - srb->cmd->pid, dcb->target_id, dcb->target_lun); - TRACEPRINTF("?*"); + "request_sense: (pid#%li) failed <%02i-%i>\n", + srb->cmd->pid, dcb->target_id, dcb->target_lun); srb_going_to_waiting_move(dcb, srb); waiting_set_timer(acb, HZ / 100); } - TRACEPRINTF(".*"); } - - - /** * device_alloc - Allocate a new device instance. This create the * devices instance and sets up all the data items. The adapter @@ -4634,18 +3718,17 @@ * * Return the new device if succesfull or NULL on failure. **/ -static -struct DeviceCtlBlk *device_alloc(struct AdapterCtlBlk *acb, u8 target, u8 lun) +static struct DeviceCtlBlk *device_alloc(struct AdapterCtlBlk *acb, + u8 target, u8 lun) { struct NvRamType *eeprom = &acb->eeprom; u8 period_index = eeprom->target[target].period & 0x07; struct DeviceCtlBlk *dcb; - dcb = dc395x_kmalloc(sizeof(struct DeviceCtlBlk), GFP_ATOMIC); - dprintkdbg(DBG_0, "device_alloc: device %p\n", dcb); - if (!dcb) { + dcb = kmalloc(sizeof(struct DeviceCtlBlk), GFP_ATOMIC); + dprintkdbg(DBG_0, "device_alloc: <%02i-%i>\n", target, lun); + if (!dcb) return NULL; - } dcb->acb = NULL; INIT_LIST_HEAD(&dcb->srb_going_list); INIT_LIST_HEAD(&dcb->srb_waiting_list); @@ -4684,10 +3767,10 @@ list_for_each_entry(p, &acb->dcb_list, list) if (p->target_id == dcb->target_id) break; - dprintkdbg(DBG_KG, - "Copy settings from %02i-%02i to %02i-%02i\n", - p->target_id, p->target_lun, - dcb->target_id, dcb->target_lun); + dprintkdbg(DBG_1, + "device_alloc: <%02i-%i> copy from <%02i-%i>\n", + dcb->target_id, dcb->target_lun, + p->target_id, p->target_lun); dcb->sync_mode = p->sync_mode; dcb->sync_period = p->sync_period; dcb->min_nego_period = p->min_nego_period; @@ -4704,8 +3787,8 @@ * @acb: The adapter device to be updated * @dcb: A newly created and intialised device instance to add. **/ -static -void adapter_add_device(struct AdapterCtlBlk *acb, struct DeviceCtlBlk *dcb) +static void adapter_add_device(struct AdapterCtlBlk *acb, + struct DeviceCtlBlk *dcb) { /* backpointer to adapter */ dcb->acb = acb; @@ -4732,13 +3815,13 @@ * @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) +static void adapter_remove_device(struct AdapterCtlBlk *acb, + struct DeviceCtlBlk *dcb) { 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); + dprintkdbg(DBG_0, "adapter_remove_device: <%02i-%i>\n", + dcb->target_id, dcb->target_lun); /* fix up any pointers to this device that we have in the adapter */ if (acb->active_dcb == dcb) @@ -4767,17 +3850,18 @@ * @acb: The adapter device to be updated * @dcb: A device that has previously been added to the adapter. */ -static -void adapter_remove_and_free_device(struct AdapterCtlBlk *acb, struct DeviceCtlBlk *dcb) +static void adapter_remove_and_free_device(struct AdapterCtlBlk *acb, + struct DeviceCtlBlk *dcb) { 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", + dprintkdbg(DBG_1, "adapter_remove_and_free_device: <%02i-%i> " + "Won't remove because of %i active requests.\n", + dcb->target_id, dcb->target_lun, list_size(&dcb->srb_going_list)); return; } adapter_remove_device(acb, dcb); - dc395x_kfree(dcb); + kfree(dcb); } @@ -4787,12 +3871,11 @@ * * @acb: The adapter from which all devices should be removed. **/ -static -void adapter_remove_and_free_all_devices(struct AdapterCtlBlk* acb) +static void adapter_remove_and_free_all_devices(struct AdapterCtlBlk* acb) { struct DeviceCtlBlk *dcb; struct DeviceCtlBlk *tmp; - dprintkdbg(DBG_DCB, "adapter_remove_and_free_all_devices: Free all devices (%i devices)\n", + dprintkdbg(DBG_1, "adapter_remove_and_free_all_devices: num=%i\n", list_size(&acb->dcb_list)); list_for_each_entry_safe(dcb, tmp, &acb->dcb_list, list) @@ -4807,8 +3890,7 @@ * * @scsi_device: The new scsi device that we need to handle. **/ -static -int dc395x_slave_alloc(struct scsi_device *scsi_device) +static int dc395x_slave_alloc(struct scsi_device *scsi_device) { struct AdapterCtlBlk *acb = (struct AdapterCtlBlk *)scsi_device->host->hostdata; struct DeviceCtlBlk *dcb; @@ -4828,8 +3910,7 @@ * * @scsi_device: The new scsi device that we need to handle. **/ -static -void dc395x_slave_destroy(struct scsi_device *scsi_device) +static void dc395x_slave_destroy(struct scsi_device *scsi_device) { struct AdapterCtlBlk *acb = (struct AdapterCtlBlk *)scsi_device->host->hostdata; struct DeviceCtlBlk *dcb = find_dcb(acb, scsi_device->id, scsi_device->lun); @@ -4847,14 +3928,12 @@ * * @io_port: base I/O address **/ -static -void __init trms1040_wait_30us(u16 io_port) +static void __init trms1040_wait_30us(u16 io_port) { /* ScsiPortStallExecution(30); wait 30 us */ outb(5, io_port + TRM_S1040_GEN_TIMER); while (!(inb(io_port + TRM_S1040_GEN_STATUS) & GTIMEOUT)) /* nothing */ ; - return; } @@ -4866,8 +3945,7 @@ * @cmd: SB + op code (command) to send * @addr: address to send **/ -static -void __init trms1040_write_cmd(u16 io_port, u8 cmd, u8 addr) +static void __init trms1040_write_cmd(u16 io_port, u8 cmd, u8 addr) { int i; u8 send_data; @@ -4912,8 +3990,7 @@ * @addr: offset into EEPROM * @byte: bytes to write **/ -static -void __init trms1040_set_data(u16 io_port, u8 addr, u8 byte) +static void __init trms1040_set_data(u16 io_port, u8 addr, u8 byte) { int i; u8 send_data; @@ -4967,10 +4044,9 @@ * @eeprom: the data to write * @io_port: the base io port **/ -static -void __init trms1040_write_all(struct NvRamType *eeprom, u16 io_port) +static void __init trms1040_write_all(struct NvRamType *eeprom, u16 io_port) { - u8 *b_eeprom = (u8 *) eeprom; + u8 *b_eeprom = (u8 *)eeprom; u8 addr; /* Enable SEEPROM */ @@ -4983,9 +4059,8 @@ trms1040_wait_30us(io_port); /* write */ - for (addr = 0; addr < 128; addr++, b_eeprom++) { + for (addr = 0; addr < 128; addr++, b_eeprom++) trms1040_set_data(io_port, addr, *b_eeprom); - } /* write disable */ trms1040_write_cmd(io_port, 0x04, 0x00); @@ -5009,8 +4084,7 @@ * * Returns the the byte read. **/ -static -u8 __init trms1040_get_data(u16 io_port, u8 addr) +static u8 __init trms1040_get_data(u16 io_port, u8 addr) { int i; u8 read_byte; @@ -5048,10 +4122,9 @@ * @eeprom: where to store the data * @io_port: the base io port **/ -static -void __init trms1040_read_all(struct NvRamType *eeprom, u16 io_port) +static void __init trms1040_read_all(struct NvRamType *eeprom, u16 io_port) { - u8 *b_eeprom = (u8 *) eeprom; + u8 *b_eeprom = (u8 *)eeprom; u8 addr; /* Enable SEEPROM */ @@ -5059,9 +4132,8 @@ io_port + TRM_S1040_GEN_CONTROL); /* read details */ - for (addr = 0; addr < 128; addr++, b_eeprom++) { + for (addr = 0; addr < 128; addr++, b_eeprom++) *b_eeprom = trms1040_get_data(io_port, addr); - } /* Disable SEEPROM */ outb((inb(io_port + TRM_S1040_GEN_CONTROL) & ~EN_EEPROM), @@ -5080,10 +4152,9 @@ * @eeprom: caller allocated strcuture to read the eeprom data into * @io_port: io port to read from **/ -static -void __init check_eeprom(struct NvRamType *eeprom, u16 io_port) +static void __init check_eeprom(struct NvRamType *eeprom, u16 io_port) { - u16 *w_eeprom = (u16 *) eeprom; + u16 *w_eeprom = (u16 *)eeprom; u16 w_addr; u16 cksum; u32 d_addr; @@ -5092,7 +4163,7 @@ trms1040_read_all(eeprom, io_port); /* read eeprom */ cksum = 0; - for (w_addr = 0, w_eeprom = (u16 *) eeprom; w_addr < 64; + for (w_addr = 0, w_eeprom = (u16 *)eeprom; w_addr < 64; w_addr++, w_eeprom++) cksum += *w_eeprom; if (cksum != 0x1234) { @@ -5101,21 +4172,21 @@ * Load a set of defaults into the eeprom buffer */ dprintkl(KERN_WARNING, - "EEProm checksum error: using default values and options.\n"); - eeprom->sub_vendor_id[0] = (u8) PCI_VENDOR_ID_TEKRAM; - eeprom->sub_vendor_id[1] = (u8) (PCI_VENDOR_ID_TEKRAM >> 8); - eeprom->sub_sys_id[0] = (u8) PCI_DEVICE_ID_TEKRAM_TRMS1040; + "EEProm checksum error: using default values and options.\n"); + eeprom->sub_vendor_id[0] = (u8)PCI_VENDOR_ID_TEKRAM; + eeprom->sub_vendor_id[1] = (u8)(PCI_VENDOR_ID_TEKRAM >> 8); + eeprom->sub_sys_id[0] = (u8)PCI_DEVICE_ID_TEKRAM_TRMS1040; eeprom->sub_sys_id[1] = - (u8) (PCI_DEVICE_ID_TEKRAM_TRMS1040 >> 8); + (u8)(PCI_DEVICE_ID_TEKRAM_TRMS1040 >> 8); eeprom->sub_class = 0x00; - eeprom->vendor_id[0] = (u8) PCI_VENDOR_ID_TEKRAM; - eeprom->vendor_id[1] = (u8) (PCI_VENDOR_ID_TEKRAM >> 8); - eeprom->device_id[0] = (u8) PCI_DEVICE_ID_TEKRAM_TRMS1040; + eeprom->vendor_id[0] = (u8)PCI_VENDOR_ID_TEKRAM; + eeprom->vendor_id[1] = (u8)(PCI_VENDOR_ID_TEKRAM >> 8); + eeprom->device_id[0] = (u8)PCI_DEVICE_ID_TEKRAM_TRMS1040; eeprom->device_id[1] = - (u8) (PCI_DEVICE_ID_TEKRAM_TRMS1040 >> 8); + (u8)(PCI_DEVICE_ID_TEKRAM_TRMS1040 >> 8); eeprom->reserved = 0x00; - for (d_addr = 0, d_eeprom = (u32 *) eeprom->target; + for (d_addr = 0, d_eeprom = (u32 *)eeprom->target; d_addr < 16; d_addr++, d_eeprom++) *d_eeprom = 0x00000077; /* cfg3,cfg2,period,cfg0 */ @@ -5130,7 +4201,7 @@ eeprom_override(eeprom); eeprom->cksum = 0x00; - for (w_addr = 0, cksum = 0, w_eeprom = (u16 *) eeprom; + for (w_addr = 0, cksum = 0, w_eeprom = (u16 *)eeprom; w_addr < 63; w_addr++, w_eeprom++) cksum += *w_eeprom; @@ -5145,113 +4216,47 @@ } - - /** * 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) +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); + 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); + 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) +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)); + const unsigned srbs_per_page = PAGE_SIZE/SEGMENTX_LEN; 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); + 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) +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); + *SEGMENTX_LEN; int pages = (mem_needed+(PAGE_SIZE-1))/PAGE_SIZE; - const unsigned srbs_per_page = PAGE_SIZE/(DC395x_MAX_SG_LISTENTRY - *sizeof(struct SGentry)); + const unsigned srbs_per_page = PAGE_SIZE/SEGMENTX_LEN; int srb_idx = 0; unsigned i = 0; struct SGentry *ptr; @@ -5261,13 +4266,13 @@ dprintkdbg(DBG_1, "Allocate %i pages for SG tables\n", pages); while (pages--) { - ptr = (struct SGentry *)dc395x_kmalloc(PAGE_SIZE, GFP_KERNEL); + ptr = (struct SGentry *)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); + 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 = @@ -5292,14 +4297,13 @@ * * @acb: The adapter to print the information for. **/ -static -void __init adapter_print_config(struct AdapterCtlBlk *acb) +static void __init adapter_print_config(struct AdapterCtlBlk *acb) { u8 bval; bval = DC395x_read8(acb, TRM_S1040_GEN_STATUS); - dprintkl(KERN_INFO, "%s Connectors: ", - ((bval & WIDESCSI) ? "(Wide)" : "")); + dprintkl(KERN_INFO, "%sConnectors: ", + ((bval & WIDESCSI) ? "(Wide) " : "")); if (!(bval & CON5068)) printk("ext%s ", !(bval & EXT68HIGH) ? "68" : "50"); if (!(bval & CON68)) @@ -5337,8 +4341,7 @@ * * @acb: The adapter to initialize. **/ -static -void __init adapter_init_params(struct AdapterCtlBlk *acb) +static void __init adapter_init_params(struct AdapterCtlBlk *acb) { struct NvRamType *eeprom = &acb->eeprom; int i; @@ -5400,8 +4403,7 @@ * * @host: The scsi host instance to fill in the values for. **/ -static -void __init adapter_init_scsi_host(struct Scsi_Host *host) +static void __init adapter_init_scsi_host(struct Scsi_Host *host) { struct AdapterCtlBlk *acb = (struct AdapterCtlBlk *)host->hostdata; struct NvRamType *eeprom = &acb->eeprom; @@ -5495,8 +4497,8 @@ * 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) +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); @@ -5528,19 +4530,15 @@ dprintkl(KERN_DEBUG, "Memory allocation for SG tables failed\n"); goto failed; } - 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); - 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)); + dprintkdbg(DBG_0, + "adapter_init: acb=%p, pdcb_map=%p psrb_array=%p " + "size{acb=0x%04x dcb=0x%04x srb=0x%04x}\n", + acb, acb->dcb_map, acb->srb_array, sizeof(struct AdapterCtlBlk), + sizeof(struct DeviceCtlBlk), sizeof(struct ScsiReqBlk)); return 0; failed: @@ -5549,7 +4547,6 @@ 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; } @@ -5562,8 +4559,7 @@ * * @acb: The adapter which we are to shutdown. **/ -static -void adapter_uninit_chip(struct AdapterCtlBlk *acb) +static void adapter_uninit_chip(struct AdapterCtlBlk *acb) { /* disable interrupts */ DC395x_write8(acb, TRM_S1040_DMA_INTEN, 0); @@ -5586,8 +4582,7 @@ * * @acb: The adapter which we are to un-initialize. **/ -static -void adapter_uninit(struct AdapterCtlBlk *acb) +static void adapter_uninit(struct AdapterCtlBlk *acb) { unsigned long flags; DC395x_LOCK_IO(acb->scsi_host, flags); @@ -5608,31 +4603,9 @@ release_region(acb->io_port_base, acb->io_port_len); adapter_sg_tables_free(acb); - free_tracebufs(acb); } -/* - ****************************************************************** - * Function: dc395x_proc_info(char* buffer, char **start, - * off_t offset, int length, int hostno, int inout) - * Purpose: return SCSI Adapter/Device Info - * Input: - * buffer: Pointer to a buffer where to write info - * start : - * offset: - * hostno: Host adapter index - * inout : Read (=0) or set(!=0) info - * Output: - * buffer: contains info length - * - * return value: length of info in buffer - * - ****************************************************************** - */ - -/* KG: dc395x_proc_info taken from driver aha152x.c */ - #undef SPRINTF #define SPRINTF(args...) pos += sprintf(pos, args) @@ -5641,9 +4614,8 @@ if (YN) SPRINTF(" Yes ");\ else SPRINTF(" No ") -static -int dc395x_proc_info(struct Scsi_Host *host, char *buffer, char **start, off_t offset, int length, - int inout) +static int dc395x_proc_info(struct Scsi_Host *host, char *buffer, + char **start, off_t offset, int length, int inout) { struct AdapterCtlBlk *acb = (struct AdapterCtlBlk *)host->hostdata; int spd, spd1; @@ -5741,16 +4713,12 @@ dcb->target_id, dcb->target_lun, list_size(&dcb->srb_going_list)); list_for_each_entry(srb, &dcb->srb_going_list, list) -#if debug_enabled(DBG_TRACE|DBG_TRACEALL) - SPRINTF("\n %s", srb->debugtrace); -#else SPRINTF(" %li", srb->cmd->pid); -#endif if (!list_empty(&dcb->srb_waiting_list) || !list_empty(&dcb->srb_going_list)) SPRINTF("\n"); } - if (debug_enabled(DBG_DCB)) { + if (debug_enabled(DBG_1)) { SPRINTF("DCB list for ACB %p:\n", acb); list_for_each_entry(dcb, &acb->dcb_list, list) { SPRINTF("%p -> ", dcb); @@ -5770,11 +4738,6 @@ } - - -/* - * SCSI host template - */ static Scsi_Host_Template dc395x_driver_template = { .module = THIS_MODULE, .proc_name = DC395X_NAME, @@ -5799,8 +4762,7 @@ * banner_display - Display banner on first instance of driver * initialized. **/ -static -void banner_display(void) +static void banner_display(void) { static int banner_done = 0; if (!banner_done) @@ -5824,9 +4786,8 @@ * * Returns 0 on success, or an error code (-ve) on failure. **/ -static -int __devinit dc395x_init_one(struct pci_dev *dev, - const struct pci_device_id *id) +static int __devinit dc395x_init_one(struct pci_dev *dev, + const struct pci_device_id *id) { struct Scsi_Host *scsi_host; struct AdapterCtlBlk *acb; @@ -5859,7 +4820,7 @@ /* 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"); + dprintkl(KERN_INFO, "adapter init failed\n"); scsi_host_put(scsi_host); return -ENODEV; } @@ -5870,7 +4831,7 @@ if (scsi_add_host(scsi_host, &dev->dev)) { dprintkl(KERN_ERR, "scsi_add_host failed\n"); adapter_uninit(acb); - scsi_host_put(scsi_host); + scsi_host_put(scsi_host); return -ENODEV; } pci_set_drvdata(dev, scsi_host); @@ -5891,7 +4852,7 @@ struct Scsi_Host *scsi_host = pci_get_drvdata(dev); struct AdapterCtlBlk *acb = (struct AdapterCtlBlk *)(scsi_host->hostdata); - dprintkdbg(DBG_0, "Removing instance\n"); + dprintkdbg(DBG_0, "dc395x_remove_one: acb=%p\n", acb); scsi_remove_host(scsi_host); adapter_uninit(acb); @@ -5900,10 +4861,6 @@ } -/* - * Table which identifies the PCI devices which - * are handled by this device driver. - */ static struct pci_device_id dc395x_pci_table[] = { { .vendor = PCI_VENDOR_ID_TEKRAM, @@ -5916,10 +4873,6 @@ MODULE_DEVICE_TABLE(pci, dc395x_pci_table); -/* - * PCI driver operations. - * Tells the PCI sub system what can be done with the card. - */ static struct pci_driver dc395x_driver = { .name = DC395X_NAME, .id_table = dc395x_pci_table, @@ -5933,8 +4886,7 @@ * * Used by both module and built-in driver to initialise this driver. **/ -static -int __init dc395x_module_init(void) +static int __init dc395x_module_init(void) { return pci_module_init(&dc395x_driver); } @@ -5943,8 +4895,7 @@ /** * dc395x_module_exit - Module cleanup function. **/ -static -void __exit dc395x_module_exit(void) +static void __exit dc395x_module_exit(void) { pci_unregister_driver(&dc395x_driver); } diff -Nru a/drivers/scsi/dc395x.h b/drivers/scsi/dc395x.h --- a/drivers/scsi/dc395x.h Sun Mar 14 14:20:08 2004 +++ b/drivers/scsi/dc395x.h Sun Mar 14 14:20:08 2004 @@ -7,18 +7,8 @@ /* (SCSI chip set used Tekram ASIC TRM-S1040) */ /* */ /************************************************************************/ - #ifndef DC395x_H #define DC395x_H - -/************************************************************************/ -/* */ -/* Name, Banner and Version */ -/* */ -/************************************************************************/ -#define DC395X_NAME "dc395x" -#define DC395X_BANNER "Tekram DC395(U/UW/F), DC315(U) - ASIC TRM-S1040" -#define DC395X_VERSION "v2.04, 2003/05/19" /************************************************************************/ /* */ diff -Nru a/drivers/scsi/eata.c b/drivers/scsi/eata.c --- a/drivers/scsi/eata.c Sun Mar 14 14:20:08 2004 +++ b/drivers/scsi/eata.c Sun Mar 14 14:20:08 2004 @@ -1598,17 +1598,17 @@ pci_dir = scsi_to_pci_dma_dir(SCpnt->sc_data_direction); if (DEV2H(cpp->sense_addr)) - pci_dma_sync_single(HD(j)->pdev, DEV2H(cpp->sense_addr), + pci_dma_sync_single_for_cpu(HD(j)->pdev, DEV2H(cpp->sense_addr), DEV2H(cpp->sense_len), PCI_DMA_FROMDEVICE); if (SCpnt->use_sg) - pci_dma_sync_sg(HD(j)->pdev, SCpnt->request_buffer, + pci_dma_sync_sg_for_cpu(HD(j)->pdev, SCpnt->request_buffer, SCpnt->use_sg, pci_dir); if (!DEV2H(cpp->data_len)) pci_dir = PCI_DMA_BIDIRECTIONAL; if (DEV2H(cpp->data_address)) - pci_dma_sync_single(HD(j)->pdev, DEV2H(cpp->data_address), + pci_dma_sync_single_for_cpu(HD(j)->pdev, DEV2H(cpp->data_address), DEV2H(cpp->data_len), pci_dir); } diff -Nru a/drivers/scsi/hosts.c b/drivers/scsi/hosts.c --- a/drivers/scsi/hosts.c Sun Mar 14 14:20:06 2004 +++ b/drivers/scsi/hosts.c Sun Mar 14 14:20:06 2004 @@ -32,6 +32,7 @@ #include #include +#include #include "scsi.h" #include "scsi_priv.h" @@ -221,6 +222,11 @@ shost->max_channel = 0; shost->max_id = 8; shost->max_lun = 8; + + /* Give each shost a default transportt if the driver + * doesn't yet support Transport Attributes */ + if (!shost->transportt) + shost->transportt = &blank_transport_template; /* * All drivers right now should be able to handle 12 byte diff -Nru a/drivers/scsi/ini9100u.c b/drivers/scsi/ini9100u.c --- a/drivers/scsi/ini9100u.c Sun Mar 14 14:20:06 2004 +++ b/drivers/scsi/ini9100u.c Sun Mar 14 14:20:06 2004 @@ -180,15 +180,6 @@ static char *setup_str = (char *) NULL; -static irqreturn_t i91u_intr0(int irq, void *dev_id, struct pt_regs *); -static irqreturn_t i91u_intr1(int irq, void *dev_id, struct pt_regs *); -static irqreturn_t i91u_intr2(int irq, void *dev_id, struct pt_regs *); -static irqreturn_t i91u_intr3(int irq, void *dev_id, struct pt_regs *); -static irqreturn_t i91u_intr4(int irq, void *dev_id, struct pt_regs *); -static irqreturn_t i91u_intr5(int irq, void *dev_id, struct pt_regs *); -static irqreturn_t i91u_intr6(int irq, void *dev_id, struct pt_regs *); -static irqreturn_t i91u_intr7(int irq, void *dev_id, struct pt_regs *); - static void i91u_panic(char *msg); static void i91uSCBPost(BYTE * pHcb, BYTE * pScb); @@ -278,7 +269,7 @@ unsigned long flags; spin_lock_irqsave(dev->host_lock, flags); - tul_isr((HCS *)hreg->base); + tul_isr((HCS *)dev->base); spin_unlock_irqrestore(dev->host_lock, flags); return IRQ_HANDLED; } diff -Nru a/drivers/scsi/libata-core.c b/drivers/scsi/libata-core.c --- a/drivers/scsi/libata-core.c Sun Mar 14 14:20:05 2004 +++ b/drivers/scsi/libata-core.c Sun Mar 14 14:20:05 2004 @@ -141,7 +141,7 @@ } if (is_addr && (tf->flags & ATA_TFLAG_LBA48)) { - outb(tf->hob_feature, ioaddr->error_addr); + outb(tf->hob_feature, ioaddr->feature_addr); outb(tf->hob_nsect, ioaddr->nsect_addr); outb(tf->hob_lbal, ioaddr->lbal_addr); outb(tf->hob_lbam, ioaddr->lbam_addr); @@ -155,7 +155,7 @@ } if (is_addr) { - outb(tf->feature, ioaddr->error_addr); + outb(tf->feature, ioaddr->feature_addr); outb(tf->nsect, ioaddr->nsect_addr); outb(tf->lbal, ioaddr->lbal_addr); outb(tf->lbam, ioaddr->lbam_addr); @@ -199,7 +199,7 @@ } if (is_addr && (tf->flags & ATA_TFLAG_LBA48)) { - writeb(tf->hob_feature, (void *) ioaddr->error_addr); + writeb(tf->hob_feature, (void *) ioaddr->feature_addr); writeb(tf->hob_nsect, (void *) ioaddr->nsect_addr); writeb(tf->hob_lbal, (void *) ioaddr->lbal_addr); writeb(tf->hob_lbam, (void *) ioaddr->lbam_addr); @@ -213,7 +213,7 @@ } if (is_addr) { - writeb(tf->feature, (void *) ioaddr->error_addr); + writeb(tf->feature, (void *) ioaddr->feature_addr); writeb(tf->nsect, (void *) ioaddr->nsect_addr); writeb(tf->lbal, (void *) ioaddr->lbal_addr); writeb(tf->lbam, (void *) ioaddr->lbam_addr); @@ -250,7 +250,7 @@ { DPRINTK("ata%u: cmd 0x%X\n", ap->id, tf->command); - outb(tf->command, ap->ioaddr.cmdstat_addr); + outb(tf->command, ap->ioaddr.command_addr); ata_pause(ap); } @@ -271,7 +271,7 @@ { DPRINTK("ata%u: cmd 0x%X\n", ap->id, tf->command); - writeb(tf->command, (void *) ap->ioaddr.cmdstat_addr); + writeb(tf->command, (void *) ap->ioaddr.command_addr); ata_pause(ap); } @@ -417,7 +417,7 @@ */ u8 ata_check_status_pio(struct ata_port *ap) { - return inb(ap->ioaddr.cmdstat_addr); + return inb(ap->ioaddr.status_addr); } /** @@ -433,7 +433,7 @@ */ u8 ata_check_status_mmio(struct ata_port *ap) { - return readb((void *) ap->ioaddr.cmdstat_addr); + return readb((void *) ap->ioaddr.status_addr); } static const char * udma_str[] = { @@ -1346,12 +1346,6 @@ DPRINTK("ENTER, host %u, port %u\n", ap->id, ap->port_no); - /* set up device control */ - if (ap->flags & ATA_FLAG_MMIO) - writeb(ap->ctl, ioaddr->ctl_addr); - else - outb(ap->ctl, ioaddr->ctl_addr); - /* determine if device 0/1 are present */ if (ap->flags & ATA_FLAG_SATA_RESET) dev0 = 1; @@ -1372,8 +1366,14 @@ /* issue bus reset */ if (ap->flags & ATA_FLAG_SRST) rc = ata_bus_softreset(ap, devmask); - else if ((ap->flags & ATA_FLAG_SATA_RESET) == 0) + else if ((ap->flags & ATA_FLAG_SATA_RESET) == 0) { + /* set up device control */ + if (ap->flags & ATA_FLAG_MMIO) + writeb(ap->ctl, ioaddr->ctl_addr); + else + outb(ap->ctl, ioaddr->ctl_addr); rc = ata_bus_edd(ap); + } if (rc) goto err_out; @@ -1399,6 +1399,14 @@ (ap->device[1].class == ATA_DEV_NONE)) goto err_out; + if (ap->flags & (ATA_FLAG_SATA_RESET | ATA_FLAG_SRST)) { + /* set up device control for ATA_FLAG_SATA_RESET */ + if (ap->flags & ATA_FLAG_MMIO) + writeb(ap->ctl, ioaddr->ctl_addr); + else + outb(ap->ctl, ioaddr->ctl_addr); + } + DPRINTK("EXIT\n"); return; @@ -1445,7 +1453,8 @@ if (ata_dev_present(&ap->device[i])) { ap->device[i].pio_mode = (pio == 3) ? XFER_PIO_3 : XFER_PIO_4; - ap->ops->set_piomode(ap, &ap->device[i], pio); + if (ap->ops->set_piomode) + ap->ops->set_piomode(ap, &ap->device[i], pio); } return; @@ -1509,7 +1518,9 @@ for (i = 0; i < ATA_MAX_DEVICES; i++) if (ata_dev_present(&ap->device[i])) { ap->device[i].udma_mode = udma_mode; - ap->ops->set_udmamode(ap, &ap->device[i], udma_mode); + if (ap->ops->set_udmamode) + ap->ops->set_udmamode(ap, &ap->device[i], + udma_mode); } return; @@ -2369,8 +2380,8 @@ * One if interrupt was handled, zero if not (shared irq). */ -static inline unsigned int ata_host_intr (struct ata_port *ap, - struct ata_queued_cmd *qc) +inline unsigned int ata_host_intr (struct ata_port *ap, + struct ata_queued_cmd *qc) { u8 status, host_stat; unsigned int handled = 0; @@ -2728,7 +2739,7 @@ if (!ap->prd) return -ENOMEM; - DPRINTK("prd alloc, virt %p, dma %x\n", ap->prd, ap->prd_dma); + DPRINTK("prd alloc, virt %p, dma %llx\n", ap->prd, (unsigned long long) ap->prd_dma); return 0; } @@ -3026,12 +3037,14 @@ { ioaddr->data_addr = ioaddr->cmd_addr + ATA_REG_DATA; ioaddr->error_addr = ioaddr->cmd_addr + ATA_REG_ERR; + ioaddr->feature_addr = ioaddr->cmd_addr + ATA_REG_FEATURE; ioaddr->nsect_addr = ioaddr->cmd_addr + ATA_REG_NSECT; ioaddr->lbal_addr = ioaddr->cmd_addr + ATA_REG_LBAL; ioaddr->lbam_addr = ioaddr->cmd_addr + ATA_REG_LBAM; ioaddr->lbah_addr = ioaddr->cmd_addr + ATA_REG_LBAH; ioaddr->device_addr = ioaddr->cmd_addr + ATA_REG_DEVICE; - ioaddr->cmdstat_addr = ioaddr->cmd_addr + ATA_REG_CMD; + ioaddr->status_addr = ioaddr->cmd_addr + ATA_REG_STATUS; + ioaddr->command_addr = ioaddr->cmd_addr + ATA_REG_CMD; } /** @@ -3153,12 +3166,14 @@ if (legacy_mode) { probe_ent->port[0].cmd_addr = 0x1f0; + probe_ent->port[0].altstatus_addr = probe_ent->port[0].ctl_addr = 0x3f6; probe_ent->n_ports = 1; probe_ent->irq = 14; ata_std_ports(&probe_ent->port[0]); probe_ent2->port[0].cmd_addr = 0x170; + probe_ent2->port[0].altstatus_addr = probe_ent2->port[0].ctl_addr = 0x376; probe_ent2->port[0].bmdma_addr = pci_resource_start(pdev, 4)+8; probe_ent2->n_ports = 1; @@ -3173,11 +3188,13 @@ } else { probe_ent->port[0].cmd_addr = pci_resource_start(pdev, 0); ata_std_ports(&probe_ent->port[0]); + probe_ent->port[0].altstatus_addr = probe_ent->port[0].ctl_addr = pci_resource_start(pdev, 1) | ATA_PCI_CTL_OFS; probe_ent->port[1].cmd_addr = pci_resource_start(pdev, 2); ata_std_ports(&probe_ent->port[1]); + probe_ent->port[1].altstatus_addr = probe_ent->port[1].ctl_addr = pci_resource_start(pdev, 3) | ATA_PCI_CTL_OFS; probe_ent->port[1].bmdma_addr = pci_resource_start(pdev, 4) + 8; @@ -3367,4 +3384,4 @@ EXPORT_SYMBOL_GPL(ata_scsi_error); EXPORT_SYMBOL_GPL(ata_scsi_slave_config); EXPORT_SYMBOL_GPL(ata_scsi_release); - +EXPORT_SYMBOL_GPL(ata_host_intr); diff -Nru a/drivers/scsi/megaraid.c b/drivers/scsi/megaraid.c --- a/drivers/scsi/megaraid.c Sun Mar 14 14:20:05 2004 +++ b/drivers/scsi/megaraid.c Sun Mar 14 14:20:05 2004 @@ -261,10 +261,6 @@ "megaraid: Product_info cmd failed with error: %d\n", retval); - pci_dma_sync_single(adapter->dev, prod_info_dma_handle, - sizeof(mega_product_info), - PCI_DMA_FROMDEVICE); - pci_unmap_single(adapter->dev, prod_info_dma_handle, sizeof(mega_product_info), PCI_DMA_FROMDEVICE); } @@ -1651,26 +1647,11 @@ case MEGA_BULK_DATA: pci_unmap_page(adapter->dev, scb->dma_h_bulkdata, scb->cmd->request_bufflen, scb->dma_direction); - - if( scb->dma_direction == PCI_DMA_FROMDEVICE ) { - pci_dma_sync_single(adapter->dev, - scb->dma_h_bulkdata, - scb->cmd->request_bufflen, - PCI_DMA_FROMDEVICE); - } - break; case MEGA_SGLIST: pci_unmap_sg(adapter->dev, scb->cmd->request_buffer, scb->cmd->use_sg, scb->dma_direction); - - if( scb->dma_direction == PCI_DMA_FROMDEVICE ) { - pci_dma_sync_sg(adapter->dev, - scb->cmd->request_buffer, - scb->cmd->use_sg, PCI_DMA_FROMDEVICE); - } - break; default: @@ -1758,14 +1739,6 @@ *buf = (u32)scb->dma_h_bulkdata; *len = (u32)cmd->request_bufflen; } - - if( scb->dma_direction == PCI_DMA_TODEVICE ) { - pci_dma_sync_single(adapter->dev, - scb->dma_h_bulkdata, - cmd->request_bufflen, - PCI_DMA_TODEVICE); - } - return 0; } @@ -1804,11 +1777,6 @@ */ *len = (u32)cmd->request_bufflen; - if( scb->dma_direction == PCI_DMA_TODEVICE ) { - pci_dma_sync_sg(adapter->dev, sgl, cmd->use_sg, - PCI_DMA_TODEVICE); - } - /* Return count of SG requests */ return sgcnt; } @@ -5118,10 +5086,6 @@ if (max_mbox_busy_wait > MBOX_BUSY_WAIT) max_mbox_busy_wait = MBOX_BUSY_WAIT; - error = pci_module_init(&megaraid_pci_driver); - if (error) - return error; - #ifdef CONFIG_PROC_FS mega_proc_dir_entry = proc_mkdir("megaraid", &proc_root); if (!mega_proc_dir_entry) { @@ -5129,6 +5093,13 @@ "megaraid: failed to create megaraid root\n"); } #endif + error = pci_module_init(&megaraid_pci_driver); + if (error) { +#ifdef CONFIG_PROC_FS + remove_proc_entry("megaraid", &proc_root); +#endif + return error; + } /* * Register the driver as a character device, for applications diff -Nru a/drivers/scsi/ncr53c8xx.c b/drivers/scsi/ncr53c8xx.c --- a/drivers/scsi/ncr53c8xx.c Sun Mar 14 14:20:06 2004 +++ b/drivers/scsi/ncr53c8xx.c Sun Mar 14 14:20:06 2004 @@ -5140,9 +5140,10 @@ */ if (cmd->cmnd[0] == 0x12 && !(cmd->cmnd[1] & 0x3) && cmd->cmnd[4] >= 7 && !cmd->use_sg) { - sync_scsi_data(np, cmd); /* SYNC the data */ + sync_scsi_data_for_cpu(np, cmd); /* SYNC the data */ ncr_setup_lcb (np, cmd->device->id, cmd->device->lun, (char *) cmd->request_buffer); + sync_scsi_data_for_device(np, cmd); /* SYNC the data */ } tp->bytes += cp->data_len; diff -Nru a/drivers/scsi/oktagon_esp.c b/drivers/scsi/oktagon_esp.c --- a/drivers/scsi/oktagon_esp.c Sun Mar 14 14:20:06 2004 +++ b/drivers/scsi/oktagon_esp.c Sun Mar 14 14:20:06 2004 @@ -12,7 +12,6 @@ #define USE_BOTTOM_HALF #endif -#define __KERNEL_SYSCALLS__ #include #include @@ -42,8 +41,6 @@ #include #include #endif - -#include /* The controller registers can be found in the Z2 config area at these * offsets: diff -Nru a/drivers/scsi/pcmcia/qlogic_stub.c b/drivers/scsi/pcmcia/qlogic_stub.c --- a/drivers/scsi/pcmcia/qlogic_stub.c Sun Mar 14 14:20:07 2004 +++ b/drivers/scsi/pcmcia/qlogic_stub.c Sun Mar 14 14:20:07 2004 @@ -43,9 +43,11 @@ #include #include #include +#include #include "scsi.h" #include "hosts.h" +#include "../qlogicfas.h" #include #include @@ -57,8 +59,10 @@ extern Scsi_Host_Template qlogicfas_driver_template; extern void qlogicfas_preset(int port, int irq); -extern struct Scsi_Host *__qlogicfas_detect(Scsi_Host_Template *); extern int qlogicfas_bus_reset(Scsi_Cmnd *); +extern irqreturn_t do_ql_ihandl(int irq, void *dev_id, struct pt_regs *regs); + +static char *qlogic_name = "qlogic_cs"; #ifdef PCMCIA_DEBUG static int pc_debug = PCMCIA_DEBUG; @@ -100,6 +104,71 @@ static dev_info_t dev_info = "qlogic_cs"; +static struct Scsi_Host *qlogic_detect(Scsi_Host_Template *host, + dev_link_t *link, int qbase, int qlirq) +{ + int qltyp; /* type of chip */ + int qinitid; + struct Scsi_Host *shost; /* registered host structure */ + qlogicfas_priv_t priv; + + qltyp = inb(qbase + 0xe) & 0xf8; + qinitid = host->this_id; + if (qinitid < 0) + qinitid = 7; /* if no ID, use 7 */ + outb(1, qbase + 8); /* set for PIO pseudo DMA */ + REG0; + outb(0x40 | qlcfg8 | qinitid, qbase + 8); /* (ini) bus id, disable scsi rst */ + outb(qlcfg5, qbase + 5); /* select timer */ + outb(qlcfg9, qbase + 9); /* prescaler */ + +#if QL_RESET_AT_START + outb(3, qbase + 3); + REG1; + /* FIXME: timeout */ + while (inb(qbase + 0xf) & 4) + cpu_relax(); + REG0; +#endif + + host->name = qlogic_name; + shost = scsi_host_alloc(host, sizeof(struct qlogicfas_priv)); + if (!shost) + goto err; + shost->io_port = qbase; + shost->n_io_port = 16; + shost->dma_channel = -1; + if (qlirq != -1) + shost->irq = qlirq; + + priv = (qlogicfas_priv_t)&(shost->hostdata[0]); + priv->qlirq = qlirq; + priv->qbase = qbase; + priv->qinitid = qinitid; + + if (request_irq(qlirq, do_ql_ihandl, 0, qlogic_name, shost)) + goto free_scsi_host; + + sprintf(priv->qinfo, + "Qlogicfas Driver version 0.46, chip %02X at %03X, IRQ %d, TPdma:%d", + qltyp, qbase, qlirq, QL_TURBO_PDMA); + + if (scsi_add_host(shost, NULL)) + goto free_interrupt; + + scsi_scan_host(shost); + + return shost; + +free_interrupt: + free_irq(qlirq, shost); + +free_scsi_host: + scsi_host_put(shost); + +err: + return NULL; +} static dev_link_t *qlogic_attach(void) { scsi_info_t *info; @@ -238,18 +307,19 @@ outb(0x04, link->io.BasePort1 + 0xd); } - /* A bad hack... */ - release_region(link->io.BasePort1, link->io.NumPorts1); + qlogicfas_driver_template.name = qlogic_name; + qlogicfas_driver_template.proc_name = qlogic_name; /* The KXL-810AN has a bigger IO port window */ if (link->io.NumPorts1 == 32) - qlogicfas_preset(link->io.BasePort1 + 16, link->irq.AssignedIRQ); + host = qlogic_detect(&qlogicfas_driver_template, link, + link->io.BasePort1 + 16, link->irq.AssignedIRQ); else - qlogicfas_preset(link->io.BasePort1, link->irq.AssignedIRQ); - - host = __qlogicfas_detect(&qlogicfas_driver_template); + host = qlogic_detect(&qlogicfas_driver_template, link, + link->io.BasePort1, link->irq.AssignedIRQ); + if (!host) { - printk(KERN_INFO "qlogic_cs: no SCSI devices found\n"); + printk(KERN_INFO "%s: no SCSI devices found\n", qlogic_name); goto out; } @@ -257,16 +327,17 @@ link->dev = &info->node; info->host = host; - scsi_add_host(host, NULL); /* XXX handle failure */ - scsi_scan_host(host); - out: link->state &= ~DEV_CONFIG_PENDING; return; cs_failed: cs_error(link->handle, last_fn, last_ret); - qlogic_release(link); + link->dev = NULL; + pcmcia_release_configuration(link->handle); + pcmcia_release_io(link->handle, &link->io); + pcmcia_release_irq(link->handle, &link->irq); + link->state &= ~DEV_CONFIG; return; } /* qlogic_config */ @@ -282,11 +353,13 @@ scsi_remove_host(info->host); link->dev = NULL; + free_irq(link->irq.AssignedIRQ, info->host); + pcmcia_release_configuration(link->handle); pcmcia_release_io(link->handle, &link->io); pcmcia_release_irq(link->handle, &link->irq); - scsi_unregister(info->host); + scsi_host_put(info->host); link->state &= ~DEV_CONFIG; } @@ -340,7 +413,7 @@ static struct pcmcia_driver qlogic_cs_driver = { .owner = THIS_MODULE, .drv = { - .name = "qlogic_cs", + .name = "qlogic_cs", }, .attach = qlogic_attach, .detach = qlogic_detach, @@ -360,5 +433,8 @@ qlogic_detach(dev_list); } +MODULE_AUTHOR("Tom Zerucha, Michael Griffith"); +MODULE_DESCRIPTION("Driver for the PCMCIA Qlogic FAS SCSI controllers"); +MODULE_LICENSE("GPL"); module_init(init_qlogic_cs); module_exit(exit_qlogic_cs); diff -Nru a/drivers/scsi/qlogicfas.c b/drivers/scsi/qlogicfas.c --- a/drivers/scsi/qlogicfas.c Sun Mar 14 14:20:08 2004 +++ b/drivers/scsi/qlogicfas.c Sun Mar 14 14:20:08 2004 @@ -27,7 +27,6 @@ SCSI driver cleanup and audit. This driver still needs work on the following - Non terminating hardware waits - - Support multiple cards at a time - Some layering violations with its pcmcia stub Redistributable under terms of the GNU General Public License @@ -39,92 +38,6 @@ are deemed to be part of the source code. */ -/*----------------------------------------------------------------*/ -/* Configuration */ - -/* Set the following to 2 to use normal interrupt (active high/totempole- - tristate), otherwise use 0 (REQUIRED FOR PCMCIA) for active low, open - drain */ - -#define QL_INT_ACTIVE_HIGH 2 - -/* Set the following to 1 to enable the use of interrupts. Note that 0 tends - to be more stable, but slower (or ties up the system more) */ - -#define QL_USE_IRQ 1 - -/* Set the following to max out the speed of the PIO PseudoDMA transfers, - again, 0 tends to be slower, but more stable. */ - -#define QL_TURBO_PDMA 1 - -/* This should be 1 to enable parity detection */ - -#define QL_ENABLE_PARITY 1 - -/* This will reset all devices when the driver is initialized (during bootup). - The other linux drivers don't do this, but the DOS drivers do, and after - using DOS or some kind of crash or lockup this will bring things back - without requiring a cold boot. It does take some time to recover from a - reset, so it is slower, and I have seen timeouts so that devices weren't - recognized when this was set. */ - -#define QL_RESET_AT_START 0 - -/* crystal frequency in megahertz (for offset 5 and 9) - Please set this for your card. Most Qlogic cards are 40 Mhz. The - Control Concepts ISA (not VLB) is 24 Mhz */ - -#define XTALFREQ 40 - -/**********/ -/* DANGER! modify these at your own risk */ -/* SLOWCABLE can usually be reset to zero if you have a clean setup and - proper termination. The rest are for synchronous transfers and other - advanced features if your device can transfer faster than 5Mb/sec. - If you are really curious, email me for a quick howto until I have - something official */ -/**********/ - -/*****/ -/* config register 1 (offset 8) options */ -/* This needs to be set to 1 if your cabling is long or noisy */ -#define SLOWCABLE 1 - -/*****/ -/* offset 0xc */ -/* This will set fast (10Mhz) synchronous timing when set to 1 - For this to have an effect, FASTCLK must also be 1 */ -#define FASTSCSI 0 - -/* This when set to 1 will set a faster sync transfer rate */ -#define FASTCLK 0 /*(XTALFREQ>25?1:0)*/ - -/*****/ -/* offset 6 */ -/* This is the sync transfer divisor, XTALFREQ/X will be the maximum - achievable data rate (assuming the rest of the system is capable - and set properly) */ -#define SYNCXFRPD 5 /*(XTALFREQ/5)*/ - -/*****/ -/* offset 7 */ -/* This is the count of how many synchronous transfers can take place - i.e. how many reqs can occur before an ack is given. - The maximum value for this is 15, the upper bits can modify - REQ/ACK assertion and deassertion during synchronous transfers - If this is 0, the bus will only transfer asynchronously */ -#define SYNCOFFST 0 -/* for the curious, bits 7&6 control the deassertion delay in 1/2 cycles - of the 40Mhz clock. If FASTCLK is 1, specifying 01 (1/2) will - cause the deassertion to be early by 1/2 clock. Bits 5&4 control - the assertion delay, also in 1/2 clocks (FASTCLK is ignored here). */ - -/*----------------------------------------------------------------*/ -#ifdef PCMCIA -#undef QL_INT_ACTIVE_HIGH -#define QL_INT_ACTIVE_HIGH 0 -#endif #include #include /* to get disk capacity */ @@ -144,42 +57,21 @@ #include "scsi.h" #include "hosts.h" +#include "qlogicfas.h" /*----------------------------------------------------------------*/ -/* driver state info, local to driver */ -static int qbase; /* Port */ -static int qinitid; /* initiator ID */ -static int qabort; /* Flag to cause an abort */ -static int qlirq = -1; /* IRQ being used */ -static char qinfo[80]; /* description */ -static Scsi_Cmnd *qlcmd; /* current command being processed */ - -static int qlcfg5 = (XTALFREQ << 5); /* 15625/512 */ -static int qlcfg6 = SYNCXFRPD; -static int qlcfg7 = SYNCOFFST; -static int qlcfg8 = (SLOWCABLE << 7) | (QL_ENABLE_PARITY << 4); -static int qlcfg9 = ((XTALFREQ + 4) / 5); -static int qlcfgc = (FASTCLK << 3) | (FASTSCSI << 4); - -int qlogicfas_queuecommand(Scsi_Cmnd * cmd, void (*done) (Scsi_Cmnd *)); +int qlcfg5 = (XTALFREQ << 5); /* 15625/512 */ +int qlcfg6 = SYNCXFRPD; +int qlcfg7 = SYNCOFFST; +int qlcfg8 = (SLOWCABLE << 7) | (QL_ENABLE_PARITY << 4); +int qlcfg9 = ((XTALFREQ + 4) / 5); +int qlcfgc = (FASTCLK << 3) | (FASTSCSI << 4); -/*----------------------------------------------------------------*/ -/* The qlogic card uses two register maps - These macros select which one */ -#define REG0 ( outb( inb( qbase + 0xd ) & 0x7f , qbase + 0xd ), outb( 4 , qbase + 0xd )) -#define REG1 ( outb( inb( qbase + 0xd ) | 0x80 , qbase + 0xd ), outb( 0xb4 | QL_INT_ACTIVE_HIGH , qbase + 0xd )) +static char qlogicfas_name[] = "qlogicfas"; -/* following is watchdog timeout in microseconds */ -#define WATCHDOG 5000000 +int qlogicfas_queuecommand(Scsi_Cmnd * cmd, void (*done) (Scsi_Cmnd *)); /*----------------------------------------------------------------*/ -/* the following will set the monitor border color (useful to find - where something crashed or gets stuck at and as a simple profiler) */ - -#if 0 -#define rtrc(i) {inb(0x3da);outb(0x31,0x3c0);outb((i),0x3c0);} -#else -#define rtrc(i) {} -#endif /*----------------------------------------------------------------*/ /* local functions */ @@ -187,9 +79,10 @@ /* error recovery - reset everything */ -static void ql_zap(void) +static void ql_zap(qlogicfas_priv_t priv) { int x; + int qbase = priv->qbase; x = inb(qbase + 0xd); REG0; @@ -203,9 +96,10 @@ * Do a pseudo-dma tranfer */ -static int ql_pdma(int phase, char *request, int reqlen) +static int ql_pdma(qlogicfas_priv_t priv, int phase, char *request, int reqlen) { int j; + int qbase = priv->qbase; j = 0; if (phase & 1) { /* in */ #if QL_TURBO_PDMA @@ -287,23 +181,25 @@ * Wait for interrupt flag (polled - not real hardware interrupt) */ -static int ql_wai(void) +static int ql_wai(qlogicfas_priv_t priv) { int k; + int qbase = priv->qbase; unsigned long i; k = 0; i = jiffies + WATCHDOG; - while (time_before(jiffies, i) && !qabort && !((k = inb(qbase + 4)) & 0xe0)) { + while (time_before(jiffies, i) && !priv->qabort && + !((k = inb(qbase + 4)) & 0xe0)) { barrier(); cpu_relax(); } if (time_after_eq(jiffies, i)) return (DID_TIME_OUT); - if (qabort) - return (qabort == 1 ? DID_ABORT : DID_RESET); + if (priv->qabort) + return (priv->qabort == 1 ? DID_ABORT : DID_RESET); if (k & 0x60) - ql_zap(); + ql_zap(priv); if (k & 0x20) return (DID_PARITY); if (k & 0x40) @@ -318,9 +214,11 @@ static void ql_icmd(Scsi_Cmnd * cmd) { + qlogicfas_priv_t priv = (qlogicfas_priv_t)&(cmd->device->host->hostdata[0]); + int qbase = priv->qbase; unsigned int i; - qabort = 0; + priv->qabort = 0; REG0; /* clearing of interrupts and the fifo is needed */ @@ -341,7 +239,7 @@ /* configurables */ outb(qlcfgc, qbase + 0xc); /* config: no reset interrupt, (initiator) bus id */ - outb(0x40 | qlcfg8 | qinitid, qbase + 8); + outb(0x40 | qlcfg8 | priv->qinitid, qbase + 8); outb(qlcfg7, qbase + 7); outb(qlcfg6, qbase + 6); /**/ outb(qlcfg5, qbase + 5); /* select timer */ @@ -352,7 +250,7 @@ for (i = 0; i < cmd->cmd_len; i++) outb(cmd->cmnd[i], qbase + 2); - qlcmd = cmd; + priv->qlcmd = cmd; outb(0x41, qbase + 3); /* select and send command */ } @@ -372,6 +270,8 @@ struct scatterlist *sglist; /* scatter-gather list pointer */ unsigned int sgcount; /* sg counter */ char *buf; + qlogicfas_priv_t priv = (qlogicfas_priv_t)&(cmd->device->host->hostdata[0]); + int qbase = priv->qbase; rtrc(1) j = inb(qbase + 6); @@ -382,7 +282,7 @@ i |= inb(qbase + 5); /* the 0x10 bit can be set after the 0x08 */ if (i != 0x18) { printk(KERN_ERR "Ql:Bad Interrupt status:%02x\n", i); - ql_zap(); + ql_zap(priv); return (DID_BAD_INTR << 16); } j &= 7; /* j = inb( qbase + 7 ) >> 5; */ @@ -395,7 +295,7 @@ if (j != 3 && j != 4) { printk(KERN_ERR "Ql:Bad sequence for command %d, int %02X, cmdleft = %d\n", j, i, inb(qbase + 7) & 0x1f); - ql_zap(); + ql_zap(priv); return (DID_ERROR << 16); } result = DID_OK; @@ -413,18 +313,19 @@ /* PIO pseudo DMA to buffer or sglist */ REG1; if (!cmd->use_sg) - ql_pdma(phase, cmd->request_buffer, + ql_pdma(priv, phase, cmd->request_buffer, cmd->request_bufflen); else { sgcount = cmd->use_sg; sglist = cmd->request_buffer; while (sgcount--) { - if (qabort) { + if (priv->qabort) { REG0; - return ((qabort == 1 ? DID_ABORT : DID_RESET) << 16); + return ((priv->qabort == 1 ? + DID_ABORT : DID_RESET) << 16); } buf = page_address(sglist->page) + sglist->offset; - if (ql_pdma(phase, buf, sglist->length)) + if (ql_pdma(priv, phase, buf, sglist->length)) break; sglist++; } @@ -435,7 +336,7 @@ * Wait for irq (split into second state of irq handler * if this can take time) */ - if ((k = ql_wai())) + if ((k = ql_wai(priv))) return (k << 16); k = inb(qbase + 5); /* should be 0x10, bus service */ } @@ -446,11 +347,12 @@ k = jiffies + WATCHDOG; - while (time_before(jiffies, k) && !qabort && !(inb(qbase + 4) & 6)) + while (time_before(jiffies, k) && !priv->qabort && + !(inb(qbase + 4) & 6)) cpu_relax(); /* wait for status phase */ if (time_after_eq(jiffies, k)) { - ql_zap(); + ql_zap(priv); return (DID_TIME_OUT << 16); } @@ -458,11 +360,11 @@ while (inb(qbase + 5)) cpu_relax(); /* clear pending ints */ - if (qabort) - return ((qabort == 1 ? DID_ABORT : DID_RESET) << 16); + if (priv->qabort) + return ((priv->qabort == 1 ? DID_ABORT : DID_RESET) << 16); outb(0x11, qbase + 3); /* get status and message */ - if ((k = ql_wai())) + if ((k = ql_wai(priv))) return (k << 16); i = inb(qbase + 5); /* get chip irq stat */ j = inb(qbase + 7) & 0x1f; /* and bytes rec'd */ @@ -479,7 +381,7 @@ } outb(0x12, qbase + 3); /* done, disconnect */ rtrc(1) - if ((k = ql_wai())) + if ((k = ql_wai(priv))) return (k << 16); /* @@ -487,21 +389,19 @@ */ i = inb(qbase + 5); /* should be bus service */ - while (!qabort && ((i & 0x20) != 0x20)) { + while (!priv->qabort && ((i & 0x20) != 0x20)) { barrier(); cpu_relax(); i |= inb(qbase + 5); } rtrc(0) - if (qabort) - return ((qabort == 1 ? DID_ABORT : DID_RESET) << 16); + if (priv->qabort) + return ((priv->qabort == 1 ? DID_ABORT : DID_RESET) << 16); return (result << 16) | (message << 8) | (status & STATUS_MASK); } -#if QL_USE_IRQ - /* * Interrupt handler */ @@ -509,20 +409,23 @@ static void ql_ihandl(int irq, void *dev_id, struct pt_regs *regs) { Scsi_Cmnd *icmd; + struct Scsi_Host *host = (struct Scsi_Host *)dev_id; + qlogicfas_priv_t priv = (qlogicfas_priv_t)&(host->hostdata[0]); + int qbase = priv->qbase; REG0; if (!(inb(qbase + 4) & 0x80)) /* false alarm? */ return; - if (qlcmd == NULL) { /* no command to process? */ + if (priv->qlcmd == NULL) { /* no command to process? */ int i; i = 16; while (i-- && inb(qbase + 5)); /* maybe also ql_zap() */ return; } - icmd = qlcmd; + icmd = priv->qlcmd; icmd->result = ql_pcmd(icmd); - qlcmd = NULL; + priv->qlcmd = NULL; /* * If result is CHECK CONDITION done calls qcommand to request * sense @@ -530,7 +433,7 @@ (icmd->scsi_done) (icmd); } -static irqreturn_t do_ql_ihandl(int irq, void *dev_id, struct pt_regs *regs) +irqreturn_t do_ql_ihandl(int irq, void *dev_id, struct pt_regs *regs) { unsigned long flags; struct Scsi_Host *host = dev_id; @@ -541,17 +444,14 @@ return IRQ_HANDLED; } -#endif - -#if QL_USE_IRQ - /* * Queued command */ int qlogicfas_queuecommand(Scsi_Cmnd * cmd, void (*done) (Scsi_Cmnd *)) { - if (cmd->device->id == qinitid) { + qlogicfas_priv_t priv = (qlogicfas_priv_t)&(cmd->device->host->hostdata[0]); + if (cmd->device->id == priv->qinitid) { cmd->result = DID_BAD_TARGET << 16; done(cmd); return 0; @@ -559,44 +459,27 @@ cmd->scsi_done = done; /* wait for the last command's interrupt to finish */ - while (qlcmd != NULL) { + while (priv->qlcmd != NULL) { barrier(); cpu_relax(); } ql_icmd(cmd); return 0; } -#else -int qlogicfas_queuecommand(Scsi_Cmnd * cmd, void (*done) (Scsi_Cmnd *)) -{ - return 1; -} -#endif - -#ifdef PCMCIA - -/* - * Allow PCMCIA code to preset the port - * port should be 0 and irq to -1 respectively for autoprobing - */ - -void qlogicfas_preset(int port, int irq) -{ - qbase = port; - qlirq = irq; -} - -#endif +#ifndef PCMCIA /* * Look for qlogic card and init if found */ -struct Scsi_Host *__qlogicfas_detect(Scsi_Host_Template *host) +struct Scsi_Host *__qlogicfas_detect(Scsi_Host_Template *host, int qbase, + int qlirq) { int i, j; /* these are only used by IRQ detect */ int qltyp; /* type of chip */ + int qinitid; struct Scsi_Host *hreg; /* registered host structure */ + qlogicfas_priv_t priv; /* Qlogic Cards only exist at 0x230 or 0x330 (the chip itself * decodes the address - I check 230 first since MIDI cards are @@ -609,7 +492,7 @@ if (!qbase) { for (qbase = 0x230; qbase < 0x430; qbase += 0x100) { - if (!request_region(qbase, 0x10, "qlogicfas")) + if (!request_region(qbase, 0x10, qlogicfas_name)) continue; REG1; if (((inb(qbase + 0xe) ^ inb(qbase + 0xe)) == 7) @@ -641,7 +524,6 @@ REG0; #endif -#if QL_USE_IRQ /* * IRQ probe - toggle pin and check request pending */ @@ -668,49 +550,98 @@ } else printk(KERN_INFO "Ql: Using preset IRQ %d\n", qlirq); - if (qlirq >= 0 && !request_irq(qlirq, do_ql_ihandl, 0, "qlogicfas", NULL)) - host->can_queue = 1; -#endif - hreg = scsi_register(host, 0); /* no host data */ + hreg = scsi_host_alloc(host, sizeof(struct qlogicfas_priv)); if (!hreg) goto err_release_mem; + priv = (qlogicfas_priv_t)&(hreg->hostdata[0]); hreg->io_port = qbase; hreg->n_io_port = 16; hreg->dma_channel = -1; if (qlirq != -1) hreg->irq = qlirq; + priv->qbase = qbase; + priv->qlirq = qlirq; + priv->qinitid = qinitid; + priv->shost = hreg; - sprintf(qinfo, + sprintf(priv->qinfo, "Qlogicfas Driver version 0.46, chip %02X at %03X, IRQ %d, TPdma:%d", qltyp, qbase, qlirq, QL_TURBO_PDMA); - host->name = qinfo; + host->name = qlogicfas_name; + + if (request_irq(qlirq, do_ql_ihandl, 0, qlogicfas_name, hreg)) + goto free_scsi_host; + + if (scsi_add_host(hreg, NULL)) + goto free_interrupt; + + scsi_scan_host(hreg); return hreg; +free_interrupt: + free_irq(qlirq, hreg); + +free_scsi_host: + scsi_host_put(hreg); + err_release_mem: release_region(qbase, 0x10); - if (host->can_queue) - free_irq(qlirq, do_ql_ihandl); - return NULL;; - + return NULL; } +#define MAX_QLOGICFAS 8 +static qlogicfas_priv_t cards; +static int iobase[MAX_QLOGICFAS]; +static int irq[MAX_QLOGICFAS] = { [0 ... MAX_QLOGICFAS-1] = -1 }; +MODULE_PARM(iobase, "1-" __MODULE_STRING(MAX_QLOGICFAS) "i"); +MODULE_PARM(irq, "1-" __MODULE_STRING(MAX_QLOGICFAS) "i"); +MODULE_PARM_DESC(iobase, "I/O address"); +MODULE_PARM_DESC(irq, "IRQ"); + int __devinit qlogicfas_detect(Scsi_Host_Template *sht) { - return (__qlogicfas_detect(sht) != NULL); + struct Scsi_Host *shost; + qlogicfas_priv_t priv; + int i, + num = 0; + + for (i = 0; i < MAX_QLOGICFAS; i++) { + shost = __qlogicfas_detect(sht, iobase[num], irq[num]); + if (shost == NULL) { + /* no more devices */ + break; + } + priv = (qlogicfas_priv_t)&(shost->hostdata[0]); + priv->next = cards; + cards = priv; + num++; + } + + return num; } static int qlogicfas_release(struct Scsi_Host *shost) { - if (shost->irq) - free_irq(shost->irq, NULL); + qlogicfas_priv_t priv = (qlogicfas_priv_t)&(shost->hostdata[0]); + int qbase = priv->qbase; + + if (shost->irq) { + REG1; + outb(0, qbase + 0xb); /* disable ints */ + + free_irq(shost->irq, shost); + } if (shost->dma_channel != 0xff) free_dma(shost->dma_channel); if (shost->io_port && shost->n_io_port) release_region(shost->io_port, shost->n_io_port); - scsi_unregister(shost); + scsi_remove_host(shost); + scsi_host_put(shost); + return 0; } +#endif /* ifndef PCMCIA */ /* * Return bios parameters @@ -742,8 +673,9 @@ static int qlogicfas_abort(Scsi_Cmnd * cmd) { - qabort = 1; - ql_zap(); + qlogicfas_priv_t priv = (qlogicfas_priv_t)&(cmd->device->host->hostdata[0]); + priv->qabort = 1; + ql_zap(priv); return SUCCESS; } @@ -755,8 +687,9 @@ int qlogicfas_bus_reset(Scsi_Cmnd * cmd) { - qabort = 2; - ql_zap(); + qlogicfas_priv_t priv = (qlogicfas_priv_t)&(cmd->device->host->hostdata[0]); + priv->qabort = 2; + ql_zap(priv); return SUCCESS; } @@ -784,22 +717,17 @@ static const char *qlogicfas_info(struct Scsi_Host *host) { - return qinfo; + qlogicfas_priv_t priv = (qlogicfas_priv_t)&(host->hostdata[0]); + return priv->qinfo; } -MODULE_AUTHOR("Tom Zerucha, Michael Griffith"); -MODULE_DESCRIPTION("Driver for the Qlogic FAS SCSI controllers"); -MODULE_LICENSE("GPL"); - /* * The driver template is also needed for PCMCIA */ Scsi_Host_Template qlogicfas_driver_template = { .module = THIS_MODULE, - .name = "qlogicfas", - .proc_name = "qlogicfas", - .detect = qlogicfas_detect, - .release = qlogicfas_release, + .name = qlogicfas_name, + .proc_name = qlogicfas_name, .info = qlogicfas_info, .queuecommand = qlogicfas_queuecommand, .eh_abort_handler = qlogicfas_abort, @@ -807,7 +735,7 @@ .eh_device_reset_handler= qlogicfas_device_reset, .eh_host_reset_handler = qlogicfas_host_reset, .bios_param = qlogicfas_biosparam, - .can_queue = 0, + .can_queue = 1, .this_id = -1, .sg_tablesize = SG_ALL, .cmd_per_lun = 1, @@ -815,6 +743,28 @@ }; #ifndef PCMCIA -#define driver_template qlogicfas_driver_template -#include "scsi_module.c" -#endif +static __init int qlogicfas_init(void) +{ + if (!qlogicfas_detect(&qlogicfas_driver_template)) { + /* no cards found */ + return -ENODEV; + } + + return 0; +} + +static __exit void qlogicfas_exit(void) +{ + qlogicfas_priv_t priv; + + for (priv = cards; priv != NULL; priv = priv->next) + qlogicfas_release(priv->shost); +} + +MODULE_AUTHOR("Tom Zerucha, Michael Griffith"); +MODULE_DESCRIPTION("Driver for the Qlogic FAS SCSI controllers"); +MODULE_LICENSE("GPL"); +module_init(qlogicfas_init); +module_exit(qlogicfas_exit); +#endif /* ifndef PCMCIA */ + diff -Nru a/drivers/scsi/qlogicfas.h b/drivers/scsi/qlogicfas.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/drivers/scsi/qlogicfas.h Sun Mar 14 14:20:09 2004 @@ -0,0 +1,124 @@ +/* to be used by qlogicfas and qlogic_cs */ +#ifndef __QLOGICFAS_H +#define __QLOGICFAS_H + +/*----------------------------------------------------------------*/ +/* Configuration */ + +/* Set the following to 2 to use normal interrupt (active high/totempole- + tristate), otherwise use 0 (REQUIRED FOR PCMCIA) for active low, open + drain */ + +#define QL_INT_ACTIVE_HIGH 2 + +/* Set the following to max out the speed of the PIO PseudoDMA transfers, + again, 0 tends to be slower, but more stable. */ + +#define QL_TURBO_PDMA 1 + +/* This should be 1 to enable parity detection */ + +#define QL_ENABLE_PARITY 1 + +/* This will reset all devices when the driver is initialized (during bootup). + The other linux drivers don't do this, but the DOS drivers do, and after + using DOS or some kind of crash or lockup this will bring things back + without requiring a cold boot. It does take some time to recover from a + reset, so it is slower, and I have seen timeouts so that devices weren't + recognized when this was set. */ + +#define QL_RESET_AT_START 0 + +/* crystal frequency in megahertz (for offset 5 and 9) + Please set this for your card. Most Qlogic cards are 40 Mhz. The + Control Concepts ISA (not VLB) is 24 Mhz */ + +#define XTALFREQ 40 + +/**********/ +/* DANGER! modify these at your own risk */ +/* SLOWCABLE can usually be reset to zero if you have a clean setup and + proper termination. The rest are for synchronous transfers and other + advanced features if your device can transfer faster than 5Mb/sec. + If you are really curious, email me for a quick howto until I have + something official */ +/**********/ + +/*****/ +/* config register 1 (offset 8) options */ +/* This needs to be set to 1 if your cabling is long or noisy */ +#define SLOWCABLE 1 + +/*****/ +/* offset 0xc */ +/* This will set fast (10Mhz) synchronous timing when set to 1 + For this to have an effect, FASTCLK must also be 1 */ +#define FASTSCSI 0 + +/* This when set to 1 will set a faster sync transfer rate */ +#define FASTCLK 0 /*(XTALFREQ>25?1:0)*/ + +/*****/ +/* offset 6 */ +/* This is the sync transfer divisor, XTALFREQ/X will be the maximum + achievable data rate (assuming the rest of the system is capable + and set properly) */ +#define SYNCXFRPD 5 /*(XTALFREQ/5)*/ + +/*****/ +/* offset 7 */ +/* This is the count of how many synchronous transfers can take place + i.e. how many reqs can occur before an ack is given. + The maximum value for this is 15, the upper bits can modify + REQ/ACK assertion and deassertion during synchronous transfers + If this is 0, the bus will only transfer asynchronously */ +#define SYNCOFFST 0 +/* for the curious, bits 7&6 control the deassertion delay in 1/2 cycles + of the 40Mhz clock. If FASTCLK is 1, specifying 01 (1/2) will + cause the deassertion to be early by 1/2 clock. Bits 5&4 control + the assertion delay, also in 1/2 clocks (FASTCLK is ignored here). */ + +/*----------------------------------------------------------------*/ +#ifdef PCMCIA +#undef QL_INT_ACTIVE_HIGH +#define QL_INT_ACTIVE_HIGH 0 +#endif + +struct qlogicfas_priv; +typedef struct qlogicfas_priv *qlogicfas_priv_t; +struct qlogicfas_priv { + int qbase; /* Port */ + int qinitid; /* initiator ID */ + int qabort; /* Flag to cause an abort */ + int qlirq; /* IRQ being used */ + char qinfo[80]; /* description */ + Scsi_Cmnd *qlcmd; /* current command being processed */ + struct Scsi_Host *shost; /* pointer back to host */ + qlogicfas_priv_t next; /* next private struct */ +}; + +extern int qlcfg5; +extern int qlcfg6; +extern int qlcfg7; +extern int qlcfg8; +extern int qlcfg9; +extern int qlcfgc; + +/* The qlogic card uses two register maps - These macros select which one */ +#define REG0 ( outb( inb( qbase + 0xd ) & 0x7f , qbase + 0xd ), outb( 4 , qbase + 0xd )) +#define REG1 ( outb( inb( qbase + 0xd ) | 0x80 , qbase + 0xd ), outb( 0xb4 | QL_INT_ACTIVE_HIGH , qbase + 0xd )) + +/* following is watchdog timeout in microseconds */ +#define WATCHDOG 5000000 + +/*----------------------------------------------------------------*/ +/* the following will set the monitor border color (useful to find + where something crashed or gets stuck at and as a simple profiler) */ + +#if 0 +#define rtrc(i) {inb(0x3da);outb(0x31,0x3c0);outb((i),0x3c0);} +#else +#define rtrc(i) {} +#endif +#endif /* __QLOGICFAS_H */ + diff -Nru a/drivers/scsi/sata_promise.c b/drivers/scsi/sata_promise.c --- a/drivers/scsi/sata_promise.c Sun Mar 14 14:20:08 2004 +++ b/drivers/scsi/sata_promise.c Sun Mar 14 14:20:08 2004 @@ -146,10 +146,6 @@ static u32 pdc_sata_scr_read (struct ata_port *ap, unsigned int sc_reg); static void pdc_sata_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val); -static void pdc_sata_set_piomode (struct ata_port *ap, struct ata_device *adev, - unsigned int pio); -static void pdc_sata_set_udmamode (struct ata_port *ap, struct ata_device *adev, - unsigned int udma); static int pdc_sata_init_one (struct pci_dev *pdev, const struct pci_device_id *ent); static void pdc_dma_start(struct ata_queued_cmd *qc); static void pdc20621_dma_start(struct ata_queued_cmd *qc); @@ -200,8 +196,6 @@ static struct ata_port_operations pdc_sata_ops = { .port_disable = ata_port_disable, - .set_piomode = pdc_sata_set_piomode, - .set_udmamode = pdc_sata_set_udmamode, .tf_load = pdc_tf_load_mmio, .tf_read = ata_tf_read_mmio, .check_status = ata_check_status_mmio, @@ -220,8 +214,6 @@ static struct ata_port_operations pdc_20621_ops = { .port_disable = ata_port_disable, - .set_piomode = pdc_sata_set_piomode, - .set_udmamode = pdc_sata_set_udmamode, .tf_load = pdc_tf_load_mmio, .tf_read = ata_tf_read_mmio, .check_status = ata_check_status_mmio, @@ -378,19 +370,6 @@ writel(val, (void *) ap->ioaddr.scr_addr + (sc_reg * 4)); } -static void pdc_sata_set_piomode (struct ata_port *ap, struct ata_device *adev, - unsigned int pio) -{ - /* dummy */ -} - - -static void pdc_sata_set_udmamode (struct ata_port *ap, struct ata_device *adev, - unsigned int udma) -{ - /* dummy */ -} - enum pdc_packet_bits { PDC_PKT_READ = (1 << 2), PDC_PKT_NODATA = (1 << 3), @@ -1172,13 +1151,16 @@ { port->cmd_addr = base; port->data_addr = base; + port->feature_addr = port->error_addr = base + 0x4; port->nsect_addr = base + 0x8; port->lbal_addr = base + 0xc; port->lbam_addr = base + 0x10; port->lbah_addr = base + 0x14; port->device_addr = base + 0x18; - port->cmdstat_addr = base + 0x1c; + port->command_addr = + port->status_addr = base + 0x1c; + port->altstatus_addr = port->ctl_addr = base + 0x38; } diff -Nru a/drivers/scsi/sata_sil.c b/drivers/scsi/sata_sil.c --- a/drivers/scsi/sata_sil.c Sun Mar 14 14:20:05 2004 +++ b/drivers/scsi/sata_sil.c Sun Mar 14 14:20:05 2004 @@ -75,10 +75,6 @@ SIL_QUIRK_UDMA5MAX = (1 << 1), }; -static void sil_set_piomode (struct ata_port *ap, struct ata_device *adev, - unsigned int pio); -static void sil_set_udmamode (struct ata_port *ap, struct ata_device *adev, - unsigned int udma); static int sil_init_one (struct pci_dev *pdev, const struct pci_device_id *ent); static void sil_dev_config(struct ata_port *ap, struct ata_device *dev); static u32 sil_scr_read (struct ata_port *ap, unsigned int sc_reg); @@ -141,8 +137,6 @@ static struct ata_port_operations sil_ops = { .port_disable = ata_port_disable, .dev_config = sil_dev_config, - .set_piomode = sil_set_piomode, - .set_udmamode = sil_set_udmamode, .tf_load = ata_tf_load_mmio, .tf_read = ata_tf_read_mmio, .check_status = ata_check_status_mmio, @@ -287,22 +281,6 @@ } } -static void sil_set_piomode (struct ata_port *ap, struct ata_device *adev, - unsigned int pio) -{ - /* We need empty implementation, the core doesn't test for NULL - * function pointer - */ -} - -static void sil_set_udmamode (struct ata_port *ap, struct ata_device *adev, - unsigned int udma) -{ - /* We need empty implementation, the core doesn't test for NULL - * function pointer - */ -} - static int sil_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) { static int printed_version; @@ -360,12 +338,14 @@ base = (unsigned long) mmio_base; probe_ent->port[0].cmd_addr = base + SIL_IDE0_TF; + probe_ent->port[0].altstatus_addr = probe_ent->port[0].ctl_addr = base + SIL_IDE0_CTL; probe_ent->port[0].bmdma_addr = base + SIL_IDE0_BMDMA; probe_ent->port[0].scr_addr = base + SIL_IDE0_SCR; ata_std_ports(&probe_ent->port[0]); probe_ent->port[1].cmd_addr = base + SIL_IDE1_TF; + probe_ent->port[1].altstatus_addr = probe_ent->port[1].ctl_addr = base + SIL_IDE1_CTL; probe_ent->port[1].bmdma_addr = base + SIL_IDE1_BMDMA; probe_ent->port[1].scr_addr = base + SIL_IDE1_SCR; @@ -373,12 +353,14 @@ if (ent->driver_data == sil_3114) { probe_ent->port[2].cmd_addr = base + SIL_IDE2_TF; + probe_ent->port[2].altstatus_addr = probe_ent->port[2].ctl_addr = base + SIL_IDE2_CTL; probe_ent->port[2].bmdma_addr = base + SIL_IDE2_BMDMA; probe_ent->port[2].scr_addr = base + SIL_IDE2_SCR; ata_std_ports(&probe_ent->port[2]); probe_ent->port[3].cmd_addr = base + SIL_IDE3_TF; + probe_ent->port[3].altstatus_addr = probe_ent->port[3].ctl_addr = base + SIL_IDE3_CTL; probe_ent->port[3].bmdma_addr = base + SIL_IDE3_BMDMA; probe_ent->port[3].scr_addr = base + SIL_IDE3_SCR; diff -Nru a/drivers/scsi/sata_svw.c b/drivers/scsi/sata_svw.c --- a/drivers/scsi/sata_svw.c Sun Mar 14 14:20:07 2004 +++ b/drivers/scsi/sata_svw.c Sun Mar 14 14:20:07 2004 @@ -103,13 +103,13 @@ ata_wait_idle(ap); } if (is_addr && (tf->flags & ATA_TFLAG_LBA48)) { - writew(tf->feature | (((u16)tf->hob_feature) << 8), ioaddr->error_addr); + writew(tf->feature | (((u16)tf->hob_feature) << 8), ioaddr->feature_addr); writew(tf->nsect | (((u16)tf->hob_nsect) << 8), ioaddr->nsect_addr); writew(tf->lbal | (((u16)tf->hob_lbal) << 8), ioaddr->lbal_addr); writew(tf->lbam | (((u16)tf->hob_lbam) << 8), ioaddr->lbam_addr); writew(tf->lbah | (((u16)tf->hob_lbah) << 8), ioaddr->lbah_addr); } else if (is_addr) { - writew(tf->feature, ioaddr->error_addr); + writew(tf->feature, ioaddr->feature_addr); writew(tf->nsect, ioaddr->nsect_addr); writew(tf->lbal, ioaddr->lbal_addr); writew(tf->lbam, ioaddr->lbam_addr); @@ -146,27 +146,9 @@ static u8 k2_stat_check_status(struct ata_port *ap) { - return readl((void *) ap->ioaddr.cmdstat_addr); + return readl((void *) ap->ioaddr.status_addr); } -static void k2_sata_set_piomode (struct ata_port *ap, struct ata_device *adev, - unsigned int pio) -{ - /* We need empty implementation, the core doesn't test for NULL - * function pointer - */ -} - - -static void k2_sata_set_udmamode (struct ata_port *ap, struct ata_device *adev, - unsigned int udma) -{ - /* We need empty implementation, the core doesn't test for NULL - * function pointer - */ -} - - #ifdef CONFIG_PPC_OF /* * k2_sata_proc_info @@ -239,8 +221,6 @@ static struct ata_port_operations k2_sata_ops = { .port_disable = ata_port_disable, - .set_piomode = k2_sata_set_piomode, - .set_udmamode = k2_sata_set_udmamode, .tf_load = k2_sata_tf_load, .tf_read = k2_sata_tf_read, .check_status = k2_stat_check_status, @@ -261,13 +241,16 @@ { port->cmd_addr = base + K2_SATA_TF_CMD_OFFSET; port->data_addr = base + K2_SATA_TF_DATA_OFFSET; + port->feature_addr = port->error_addr = base + K2_SATA_TF_ERROR_OFFSET; port->nsect_addr = base + K2_SATA_TF_NSECT_OFFSET; port->lbal_addr = base + K2_SATA_TF_LBAL_OFFSET; port->lbam_addr = base + K2_SATA_TF_LBAM_OFFSET; port->lbah_addr = base + K2_SATA_TF_LBAH_OFFSET; port->device_addr = base + K2_SATA_TF_DEVICE_OFFSET; - port->cmdstat_addr = base + K2_SATA_TF_CMDSTAT_OFFSET; + port->command_addr = + port->status_addr = base + K2_SATA_TF_CMDSTAT_OFFSET; + port->altstatus_addr = port->ctl_addr = base + K2_SATA_TF_CTL_OFFSET; port->bmdma_addr = base + K2_SATA_DMA_CMD_OFFSET; port->scr_addr = base + K2_SATA_SCR_STATUS_OFFSET; diff -Nru a/drivers/scsi/sata_via.c b/drivers/scsi/sata_via.c --- a/drivers/scsi/sata_via.c Sun Mar 14 14:20:06 2004 +++ b/drivers/scsi/sata_via.c Sun Mar 14 14:20:06 2004 @@ -43,10 +43,6 @@ static int svia_init_one (struct pci_dev *pdev, const struct pci_device_id *ent); static void svia_sata_phy_reset(struct ata_port *ap); static void svia_port_disable(struct ata_port *ap); -static void svia_set_piomode (struct ata_port *ap, struct ata_device *adev, - unsigned int pio); -static void svia_set_udmamode (struct ata_port *ap, struct ata_device *adev, - unsigned int udma); static unsigned int in_module_init = 1; @@ -83,8 +79,6 @@ static struct ata_port_operations svia_sata_ops = { .port_disable = svia_port_disable, - .set_piomode = svia_set_piomode, - .set_udmamode = svia_set_udmamode, .tf_load = ata_tf_load_pio, .tf_read = ata_tf_read_pio, @@ -164,38 +158,6 @@ ata_port_disable(ap); /* FIXME */ -} - -/** - * svia_set_piomode - - * @ap: - * @adev: - * @pio: - * - * LOCKING: - * - */ - -static void svia_set_piomode (struct ata_port *ap, struct ata_device *adev, - unsigned int pio) -{ - /* FIXME: needed? */ -} - -/** - * svia_set_udmamode - - * @ap: - * @adev: - * @udma: - * - * LOCKING: - * - */ - -static void svia_set_udmamode (struct ata_port *ap, struct ata_device *adev, - unsigned int udma) -{ - /* FIXME: needed? */ } /** diff -Nru a/drivers/scsi/sata_vsc.c b/drivers/scsi/sata_vsc.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/drivers/scsi/sata_vsc.c Sun Mar 14 14:20:09 2004 @@ -0,0 +1,392 @@ +/* + * sata_vsc.c - Vitesse VSC7174 4 port DPA SATA + * + * Copyright 2004 SGI + * + * Bits from Jeff Garzik, Copyright RedHat, Inc. + * + * The contents of this file are subject to the Open + * Software License version 1.1 that can be found at + * http://www.opensource.org/licenses/osl-1.1.txt and is included herein + * by reference. + * + * Alternatively, the contents of this file may be used under the terms + * of the GNU General Public License version 2 (the "GPL") as distributed + * in the kernel source COPYING file, in which case the provisions of + * the GPL are applicable instead of the above. If you wish to allow + * the use of your version of this file only under the terms of the + * GPL and not to allow others to use your version of this file under + * the OSL, indicate your decision by deleting the provisions above and + * replace them with the notice and other provisions required by the GPL. + * If you do not delete the provisions above, a recipient may use your + * version of this file under either the OSL or the GPL. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include "scsi.h" +#include "hosts.h" +#include + +#define DRV_NAME "sata_vsc" +#define DRV_VERSION "0.01" + +/* Interrupt register offsets (from chip base address) */ +#define VSC_SATA_INT_STAT_OFFSET 0x00 +#define VSC_SATA_INT_MASK_OFFSET 0x04 + +/* Taskfile registers offsets */ +#define VSC_SATA_TF_CMD_OFFSET 0x00 +#define VSC_SATA_TF_DATA_OFFSET 0x00 +#define VSC_SATA_TF_ERROR_OFFSET 0x04 +#define VSC_SATA_TF_FEATURE_OFFSET 0x06 +#define VSC_SATA_TF_NSECT_OFFSET 0x08 +#define VSC_SATA_TF_LBAL_OFFSET 0x0c +#define VSC_SATA_TF_LBAM_OFFSET 0x10 +#define VSC_SATA_TF_LBAH_OFFSET 0x14 +#define VSC_SATA_TF_DEVICE_OFFSET 0x18 +#define VSC_SATA_TF_STATUS_OFFSET 0x1c +#define VSC_SATA_TF_COMMAND_OFFSET 0x1d +#define VSC_SATA_TF_ALTSTATUS_OFFSET 0x28 +#define VSC_SATA_TF_CTL_OFFSET 0x29 + +/* DMA base */ +#define VSC_SATA_DMA_CMD_OFFSET 0x70 + +/* SCRs base */ +#define VSC_SATA_SCR_STATUS_OFFSET 0x100 +#define VSC_SATA_SCR_ERROR_OFFSET 0x104 +#define VSC_SATA_SCR_CONTROL_OFFSET 0x108 + +/* Port stride */ +#define VSC_SATA_PORT_OFFSET 0x200 + + +static u32 vsc_sata_scr_read (struct ata_port *ap, unsigned int sc_reg) +{ + if (sc_reg > SCR_CONTROL) + return 0xffffffffU; + return readl((void *) ap->ioaddr.scr_addr + (sc_reg * 4)); +} + + +static void vsc_sata_scr_write (struct ata_port *ap, unsigned int sc_reg, + u32 val) +{ + if (sc_reg > SCR_CONTROL) + return; + writel(val, (void *) ap->ioaddr.scr_addr + (sc_reg * 4)); +} + + +static void vsc_intr_mask_update(struct ata_port *ap, u8 ctl) +{ + unsigned long mask_addr; + u8 mask; + + mask_addr = (unsigned long) ap->host_set->mmio_base + + VSC_SATA_INT_MASK_OFFSET + ap->port_no; + mask = readb(mask_addr); + if (ctl & ATA_NIEN) + mask |= 0x80; + else + mask &= 0x7F; + writeb(mask, mask_addr); +} + + +static void vsc_sata_tf_load(struct ata_port *ap, struct ata_taskfile *tf) +{ + struct ata_ioports *ioaddr = &ap->ioaddr; + unsigned int is_addr = tf->flags & ATA_TFLAG_ISADDR; + + /* + * The only thing the ctl register is used for is SRST. + * That is not enabled or disabled via tf_load. + * However, if ATA_NIEN is changed, then we need to change the interrupt register. + */ + if ((tf->ctl & ATA_NIEN) != (ap->last_ctl & ATA_NIEN)) { + ap->last_ctl = tf->ctl; + vsc_intr_mask_update(ap, tf->ctl & ATA_NIEN); + } + if (is_addr && (tf->flags & ATA_TFLAG_LBA48)) { + writew(tf->feature | (((u16)tf->hob_feature) << 8), ioaddr->feature_addr); + writew(tf->nsect | (((u16)tf->hob_nsect) << 8), ioaddr->nsect_addr); + writew(tf->lbal | (((u16)tf->hob_lbal) << 8), ioaddr->lbal_addr); + writew(tf->lbam | (((u16)tf->hob_lbam) << 8), ioaddr->lbam_addr); + writew(tf->lbah | (((u16)tf->hob_lbah) << 8), ioaddr->lbah_addr); + } else if (is_addr) { + writew(tf->feature, ioaddr->feature_addr); + writew(tf->nsect, ioaddr->nsect_addr); + writew(tf->lbal, ioaddr->lbal_addr); + writew(tf->lbam, ioaddr->lbam_addr); + writew(tf->lbah, ioaddr->lbah_addr); + } + + if (tf->flags & ATA_TFLAG_DEVICE) + writeb(tf->device, ioaddr->device_addr); + + ata_wait_idle(ap); +} + + +static void vsc_sata_tf_read(struct ata_port *ap, struct ata_taskfile *tf) +{ + struct ata_ioports *ioaddr = &ap->ioaddr; + u16 nsect, lbal, lbam, lbah; + + nsect = tf->nsect = readw(ioaddr->nsect_addr); + lbal = tf->lbal = readw(ioaddr->lbal_addr); + lbam = tf->lbam = readw(ioaddr->lbam_addr); + lbah = tf->lbah = readw(ioaddr->lbah_addr); + tf->device = readw(ioaddr->device_addr); + + if (tf->flags & ATA_TFLAG_LBA48) { + tf->hob_feature = readb(ioaddr->error_addr); + tf->hob_nsect = nsect >> 8; + tf->hob_lbal = lbal >> 8; + tf->hob_lbam = lbam >> 8; + tf->hob_lbah = lbah >> 8; + } +} + + +/* + * vsc_sata_interrupt + * + * Read the interrupt register and process for the devices that have them pending. + */ +irqreturn_t vsc_sata_interrupt (int irq, void *dev_instance, struct pt_regs *regs) +{ + struct ata_host_set *host_set = dev_instance; + unsigned int i; + unsigned int handled = 0; + u32 int_status; + + spin_lock(&host_set->lock); + + int_status = readl(host_set->mmio_base + VSC_SATA_INT_STAT_OFFSET); + + for (i = 0; i < host_set->n_ports; i++) { + if (int_status & ((u32) 0xFF << (8 * i))) { + struct ata_port *ap; + + ap = host_set->ports[i]; + if (ap && (!(ap->flags & ATA_FLAG_PORT_DISABLED))) { + struct ata_queued_cmd *qc; + + qc = ata_qc_from_tag(ap, ap->active_tag); + if (qc && ((qc->flags & ATA_QCFLAG_POLL) == 0)) + handled += ata_host_intr(ap, qc); + } + } + } + + spin_unlock(&host_set->lock); + + return IRQ_RETVAL(handled); +} + + +static Scsi_Host_Template vsc_sata_sht = { + .module = THIS_MODULE, + .name = DRV_NAME, + .queuecommand = ata_scsi_queuecmd, + .eh_strategy_handler = ata_scsi_error, + .can_queue = ATA_DEF_QUEUE, + .this_id = ATA_SHT_THIS_ID, + .sg_tablesize = LIBATA_MAX_PRD, + .max_sectors = ATA_MAX_SECTORS, + .cmd_per_lun = ATA_SHT_CMD_PER_LUN, + .emulated = ATA_SHT_EMULATED, + .use_clustering = ATA_SHT_USE_CLUSTERING, + .proc_name = DRV_NAME, + .dma_boundary = ATA_DMA_BOUNDARY, + .slave_configure = ata_scsi_slave_config, + .bios_param = ata_std_bios_param, +}; + + +static struct ata_port_operations vsc_sata_ops = { + .port_disable = ata_port_disable, + .tf_load = vsc_sata_tf_load, + .tf_read = vsc_sata_tf_read, + .exec_command = ata_exec_command_mmio, + .check_status = ata_check_status_mmio, + .phy_reset = sata_phy_reset, + .phy_config = pata_phy_config, /* not a typo */ + .bmdma_start = ata_bmdma_start_mmio, + .fill_sg = ata_fill_sg, + .eng_timeout = ata_eng_timeout, + .irq_handler = vsc_sata_interrupt, + .scr_read = vsc_sata_scr_read, + .scr_write = vsc_sata_scr_write, + .port_start = ata_port_start, + .port_stop = ata_port_stop, +}; + +static void vsc_sata_setup_port(struct ata_ioports *port, unsigned long base) +{ + port->cmd_addr = base + VSC_SATA_TF_CMD_OFFSET; + port->data_addr = base + VSC_SATA_TF_DATA_OFFSET; + port->error_addr = base + VSC_SATA_TF_ERROR_OFFSET; + port->feature_addr = base + VSC_SATA_TF_FEATURE_OFFSET; + port->nsect_addr = base + VSC_SATA_TF_NSECT_OFFSET; + port->lbal_addr = base + VSC_SATA_TF_LBAL_OFFSET; + port->lbam_addr = base + VSC_SATA_TF_LBAM_OFFSET; + port->lbah_addr = base + VSC_SATA_TF_LBAH_OFFSET; + port->device_addr = base + VSC_SATA_TF_DEVICE_OFFSET; + port->status_addr = base + VSC_SATA_TF_STATUS_OFFSET; + port->command_addr = base + VSC_SATA_TF_COMMAND_OFFSET; + port->altstatus_addr = base + VSC_SATA_TF_ALTSTATUS_OFFSET; + port->ctl_addr = base + VSC_SATA_TF_CTL_OFFSET; + port->bmdma_addr = base + VSC_SATA_DMA_CMD_OFFSET; + port->scr_addr = base + VSC_SATA_SCR_STATUS_OFFSET; +} + + +static int vsc_sata_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) +{ + static int printed_version; + struct ata_probe_ent *probe_ent = NULL; + unsigned long base; + void *mmio_base; + int rc; + + if (!printed_version++) + printk(KERN_DEBUG DRV_NAME " version " DRV_VERSION "\n"); + + rc = pci_enable_device(pdev); + if (rc) + return rc; + + /* + * Check if we have needed resource mapped. + */ + if (pci_resource_len(pdev, 0) == 0) { + rc = -ENODEV; + goto err_out; + } + + rc = pci_request_regions(pdev, DRV_NAME); + if (rc) + goto err_out; + + /* + * Use 32 bit DMA mask, because 64 bit address support is poor. + */ + rc = pci_set_dma_mask(pdev, 0xFFFFFFFF); + if (rc) + goto err_out_regions; + rc = pci_set_consistent_dma_mask(pdev, 0xFFFFFFFF); + if (rc) + goto err_out_regions; + + probe_ent = kmalloc(sizeof(*probe_ent), GFP_KERNEL); + if (probe_ent == NULL) { + rc = -ENOMEM; + goto err_out_regions; + } + memset(probe_ent, 0, sizeof(*probe_ent)); + probe_ent->pdev = pdev; + INIT_LIST_HEAD(&probe_ent->node); + + mmio_base = ioremap(pci_resource_start(pdev, 0), + pci_resource_len(pdev, 0)); + if (mmio_base == NULL) { + rc = -ENOMEM; + goto err_out_free_ent; + } + base = (unsigned long) mmio_base; + + /* + * Due to a bug in the chip, the default cache line size can't be used + */ + pci_write_config_byte(pdev, PCI_CACHE_LINE_SIZE, 0x80); + + probe_ent->sht = &vsc_sata_sht; + probe_ent->host_flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | + ATA_FLAG_MMIO | ATA_FLAG_SATA_RESET; + probe_ent->port_ops = &vsc_sata_ops; + probe_ent->n_ports = 4; + probe_ent->irq = pdev->irq; + probe_ent->irq_flags = SA_SHIRQ; + probe_ent->mmio_base = mmio_base; + + /* We don't care much about the PIO/UDMA masks, but the core won't like us + * if we don't fill these + */ + probe_ent->pio_mask = 0x1f; + probe_ent->udma_mask = 0x3f; + + /* We have 4 ports per PCI function */ + vsc_sata_setup_port(&probe_ent->port[0], base + 1 * VSC_SATA_PORT_OFFSET); + vsc_sata_setup_port(&probe_ent->port[1], base + 2 * VSC_SATA_PORT_OFFSET); + vsc_sata_setup_port(&probe_ent->port[2], base + 3 * VSC_SATA_PORT_OFFSET); + vsc_sata_setup_port(&probe_ent->port[3], base + 4 * VSC_SATA_PORT_OFFSET); + + pci_set_master(pdev); + + /* FIXME: check ata_device_add return value */ + ata_device_add(probe_ent); + kfree(probe_ent); + + return 0; + +err_out_free_ent: + kfree(probe_ent); +err_out_regions: + pci_release_regions(pdev); +err_out: + pci_disable_device(pdev); + return rc; +} + + +static struct pci_device_id vsc_sata_pci_tbl[] = { + { 0x1725, 0x7174, PCI_ANY_ID, PCI_ANY_ID, 0x10600, 0xFFFFFF, 0 }, + { 0x8086, 0x3200, PCI_ANY_ID, PCI_ANY_ID, 0x10600, 0xFFFFFF, 0 }, + { } +}; + + +static struct pci_driver vsc_sata_pci_driver = { + .name = DRV_NAME, + .id_table = vsc_sata_pci_tbl, + .probe = vsc_sata_init_one, + .remove = ata_pci_remove_one, +}; + + +static int __init vsc_sata_init(void) +{ + int rc; + + rc = pci_module_init(&vsc_sata_pci_driver); + if (rc) + return rc; + + return 0; +} + + +static void __exit vsc_sata_exit(void) +{ + pci_unregister_driver(&vsc_sata_pci_driver); +} + + +MODULE_AUTHOR("Jeremy Higdon"); +MODULE_DESCRIPTION("low-level driver for Vitesse VSC7174 SATA controller"); +MODULE_LICENSE("GPL"); +MODULE_DEVICE_TABLE(pci, vsc_sata_pci_tbl); + +module_init(vsc_sata_init); +module_exit(vsc_sata_exit); diff -Nru a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c --- a/drivers/scsi/scsi.c Sun Mar 14 14:20:07 2004 +++ b/drivers/scsi/scsi.c Sun Mar 14 14:20:07 2004 @@ -104,7 +104,7 @@ "Communications ", "Unknown ", "Unknown ", - "Unknown ", + "RAID ", "Enclosure ", }; @@ -1097,7 +1097,7 @@ struct list_head *lh, *lh_sf; unsigned long flags; - sdev->sdev_state = SDEV_CANCEL; + scsi_device_set_state(sdev, SDEV_CANCEL); spin_lock_irqsave(&sdev->list_lock, flags); list_for_each_entry(scmd, &sdev->cmd_list, list) { diff -Nru a/drivers/scsi/scsi_devinfo.c b/drivers/scsi/scsi_devinfo.c --- a/drivers/scsi/scsi_devinfo.c Sun Mar 14 14:20:06 2004 +++ b/drivers/scsi/scsi_devinfo.c Sun Mar 14 14:20:06 2004 @@ -94,95 +94,93 @@ * The following causes a failed REQUEST SENSE on lun 1 for * seagate controller, which causes SCSI code to reset bus. */ - {"TEXEL", "CD-ROM", "1.06", BLIST_NOLUN}, + {"HP", "C1750A", "3226", BLIST_NOLUN}, /* scanjet iic */ + {"HP", "C1790A", "", BLIST_NOLUN}, /* scanjet iip */ + {"HP", "C2500A", "", BLIST_NOLUN}, /* scanjet iicx */ + {"MEDIAVIS", "CDR-H93MV", "1.31", BLIST_NOLUN}, /* locks up */ + {"MICROTEK", "ScanMaker II", "5.61", BLIST_NOLUN}, /* responds to all lun */ + {"MITSUMI", "CD-R CR-2201CS", "6119", BLIST_NOLUN}, /* locks up */ + {"NEC", "D3856", "0009", BLIST_NOLUN}, {"QUANTUM", "LPS525S", "3110", BLIST_NOLUN}, /* locks up */ {"QUANTUM", "PD1225S", "3110", BLIST_NOLUN}, /* locks up */ {"QUANTUM", "FIREBALL ST4.3S", "0F0C", BLIST_NOLUN}, /* locks up */ - {"MEDIAVIS", "CDR-H93MV", "1.31", BLIST_NOLUN}, /* locks up */ + {"RELISYS", "Scorpio", NULL, BLIST_NOLUN}, /* responds to all lun */ {"SANKYO", "CP525", "6.64", BLIST_NOLUN}, /* causes failed REQ SENSE, extra reset */ - {"HP", "C1750A", "3226", BLIST_NOLUN}, /* scanjet iic */ - {"HP", "C1790A", "", BLIST_NOLUN}, /* scanjet iip */ - {"HP", "C2500A", "", BLIST_NOLUN}, /* scanjet iicx */ + {"TEXEL", "CD-ROM", "1.06", BLIST_NOLUN}, {"YAMAHA", "CDR100", "1.00", BLIST_NOLUN}, /* locks up */ {"YAMAHA", "CDR102", "1.00", BLIST_NOLUN}, /* locks up */ {"YAMAHA", "CRW8424S", "1.0", BLIST_NOLUN}, /* locks up */ {"YAMAHA", "CRW6416S", "1.0c", BLIST_NOLUN}, /* locks up */ - {"MITSUMI", "CD-R CR-2201CS", "6119", BLIST_NOLUN}, /* locks up */ - {"RELISYS", "Scorpio", NULL, BLIST_NOLUN}, /* responds to all lun */ - {"MICROTEK", "ScanMaker II", "5.61", BLIST_NOLUN}, /* responds to all lun */ - {"NEC", "D3856", "0009", BLIST_NOLUN}, /* * Other types of devices that have special flags. */ - {"SONY", "CD-ROM CDU-8001", NULL, BLIST_BORKEN}, - {"TEXEL", "CD-ROM", "1.06", BLIST_BORKEN}, - {"IOMEGA", "Io20S *F", NULL, BLIST_KEY}, - {"INSITE", "Floptical F*8I", NULL, BLIST_KEY}, - {"INSITE", "I325VM", NULL, BLIST_KEY}, - {"LASOUND", "CDX7405", "3.10", BLIST_MAX5LUN | BLIST_SINGLELUN}, - {"MICROP", "4110", NULL, BLIST_NOTQ}, - {"NRC", "MBR-7", NULL, BLIST_FORCELUN | BLIST_SINGLELUN}, - {"NRC", "MBR-7.4", NULL, BLIST_FORCELUN | BLIST_SINGLELUN}, - {"REGAL", "CDC-4X", NULL, BLIST_MAX5LUN | BLIST_SINGLELUN}, - {"NAKAMICH", "MJ-4.8S", NULL, BLIST_FORCELUN | BLIST_SINGLELUN}, - {"NAKAMICH", "MJ-5.16S", NULL, BLIST_FORCELUN | BLIST_SINGLELUN}, - {"PIONEER", "CD-ROM DRM-600", NULL, BLIST_FORCELUN | BLIST_SINGLELUN}, - {"PIONEER", "CD-ROM DRM-602X", NULL, BLIST_FORCELUN | BLIST_SINGLELUN}, - {"PIONEER", "CD-ROM DRM-604X", NULL, BLIST_FORCELUN | BLIST_SINGLELUN}, - {"EMULEX", "MD21/S2 ESDI", NULL, BLIST_SINGLELUN}, + {"ADAPTEC", "AACRAID", NULL, BLIST_FORCELUN}, + {"ADAPTEC", "Adaptec 5400S", NULL, BLIST_FORCELUN}, {"CANON", "IPUBJD", NULL, BLIST_SPARSELUN}, - {"nCipher", "Fastness Crypto", NULL, BLIST_FORCELUN}, - {"DEC", "HSG80", NULL, BLIST_SPARSELUN | BLIST_NOSTARTONADD}, + {"CMD", "CRA-7280", NULL, BLIST_SPARSELUN}, /* CMD RAID Controller */ + {"CNSI", "G7324", NULL, BLIST_SPARSELUN}, /* Chaparral G7324 RAID */ + {"CNSi", "G8324", NULL, BLIST_SPARSELUN}, /* Chaparral G8324 RAID */ {"COMPAQ", "LOGICAL VOLUME", NULL, BLIST_FORCELUN}, {"COMPAQ", "CR3500", NULL, BLIST_FORCELUN}, - {"NEC", "PD-1 ODX654P", NULL, BLIST_FORCELUN | BLIST_SINGLELUN}, - {"MATSHITA", "PD-1", NULL, BLIST_FORCELUN | BLIST_SINGLELUN}, - {"iomega", "jaz 1GB", "J.86", BLIST_NOTQ | BLIST_NOLUN}, - {"TOSHIBA", "CDROM", NULL, BLIST_ISROM}, - {"TOSHIBA", "CD-ROM", NULL, BLIST_ISROM}, - {"MegaRAID", "LD", NULL, BLIST_FORCELUN}, - {"DGC", "RAID", NULL, BLIST_SPARSELUN}, /* Dell PV 650F, storage on LUN 0 */ - {"DGC", "DISK", NULL, BLIST_SPARSELUN}, /* Dell PV 650F, no storage on LUN 0 */ + {"COMPAQ", "MSA1000", NULL, BLIST_SPARSELUN | BLIST_NOSTARTONADD}, + {"COMPAQ", "MSA1000 VOLUME", NULL, BLIST_SPARSELUN | BLIST_NOSTARTONADD}, + {"COMPAQ", "HSV110", NULL, BLIST_SPARSELUN | BLIST_NOSTARTONADD}, + {"DDN", "SAN DataDirector", "*", BLIST_SPARSELUN}, + {"DEC", "HSG80", NULL, BLIST_SPARSELUN | BLIST_NOSTARTONADD}, {"DELL", "PV660F", NULL, BLIST_SPARSELUN}, {"DELL", "PV660F PSEUDO", NULL, BLIST_SPARSELUN}, {"DELL", "PSEUDO DEVICE .", NULL, BLIST_SPARSELUN}, /* Dell PV 530F */ {"DELL", "PV530F", NULL, BLIST_SPARSELUN}, + {"DELL", "PERCRAID", NULL, BLIST_FORCELUN}, + {"DGC", "RAID", NULL, BLIST_SPARSELUN}, /* Dell PV 650F, storage on LUN 0 */ + {"DGC", "DISK", NULL, BLIST_SPARSELUN}, /* Dell PV 650F, no storage on LUN 0 */ {"EMC", "SYMMETRIX", NULL, BLIST_SPARSELUN | BLIST_LARGELUN | BLIST_FORCELUN}, + {"EMULEX", "MD21/S2 ESDI", NULL, BLIST_SINGLELUN}, + {"FSC", "CentricStor", "*", BLIST_SPARSELUN | BLIST_LARGELUN}, + {"Generic", "USB Storage-SMC", "0207", BLIST_FORCELUN}, + {"HITACHI", "DF400", "*", BLIST_SPARSELUN}, + {"HITACHI", "DF500", "*", BLIST_SPARSELUN}, + {"HITACHI", "DF600", "*", BLIST_SPARSELUN}, {"HP", "A6189A", NULL, BLIST_SPARSELUN | BLIST_LARGELUN}, /* HP VA7400 */ {"HP", "OPEN-", "*", BLIST_SPARSELUN | BLIST_LARGELUN}, /* HP XP Arrays */ - {"CMD", "CRA-7280", NULL, BLIST_SPARSELUN}, /* CMD RAID Controller */ - {"CNSI", "G7324", NULL, BLIST_SPARSELUN}, /* Chaparral G7324 RAID */ - {"CNSi", "G8324", NULL, BLIST_SPARSELUN}, /* Chaparral G8324 RAID */ - {"Zzyzx", "RocketStor 500S", NULL, BLIST_SPARSELUN}, - {"Zzyzx", "RocketStor 2000", NULL, BLIST_SPARSELUN}, - {"SONY", "TSL", NULL, BLIST_FORCELUN}, /* DDS3 & DDS4 autoloaders */ - {"DELL", "PERCRAID", NULL, BLIST_FORCELUN}, {"HP", "NetRAID-4M", NULL, BLIST_FORCELUN}, - {"ADAPTEC", "AACRAID", NULL, BLIST_FORCELUN}, - {"ADAPTEC", "Adaptec 5400S", NULL, BLIST_FORCELUN}, - {"COMPAQ", "MSA1000", NULL, BLIST_SPARSELUN | BLIST_NOSTARTONADD}, - {"COMPAQ", "MSA1000 VOLUME", NULL, BLIST_SPARSELUN | BLIST_NOSTARTONADD}, - {"COMPAQ", "HSV110", NULL, BLIST_SPARSELUN | BLIST_NOSTARTONADD}, {"HP", "HSV100", NULL, BLIST_SPARSELUN | BLIST_NOSTARTONADD}, {"HP", "C1557A", NULL, BLIST_FORCELUN}, {"IBM", "AuSaV1S2", NULL, BLIST_FORCELUN}, - {"FSC", "CentricStor", "*", BLIST_SPARSELUN | BLIST_LARGELUN}, - {"DDN", "SAN DataDirector", "*", BLIST_SPARSELUN}, - {"HITACHI", "DF400", "*", BLIST_SPARSELUN}, - {"HITACHI", "DF500", "*", BLIST_SPARSELUN}, - {"HITACHI", "DF600", "*", BLIST_SPARSELUN}, {"IBM", "ProFibre 4000R", "*", BLIST_SPARSELUN | BLIST_LARGELUN}, - {"SUN", "T300", "*", BLIST_SPARSELUN}, - {"SUN", "T4", "*", BLIST_SPARSELUN}, + {"iomega", "jaz 1GB", "J.86", BLIST_NOTQ | BLIST_NOLUN}, + {"IOMEGA", "Io20S *F", NULL, BLIST_KEY}, + {"INSITE", "Floptical F*8I", NULL, BLIST_KEY}, + {"INSITE", "I325VM", NULL, BLIST_KEY}, + {"LASOUND", "CDX7405", "3.10", BLIST_MAX5LUN | BLIST_SINGLELUN}, + {"MATSHITA", "PD-1", NULL, BLIST_FORCELUN | BLIST_SINGLELUN}, + {"MegaRAID", "LD", NULL, BLIST_FORCELUN}, + {"MICROP", "4110", NULL, BLIST_NOTQ}, + {"MYLEX", "DACARMRB", "*", BLIST_SPARSELUN | BLIST_LARGELUN}, + {"nCipher", "Fastness Crypto", NULL, BLIST_FORCELUN}, + {"NAKAMICH", "MJ-4.8S", NULL, BLIST_FORCELUN | BLIST_SINGLELUN}, + {"NAKAMICH", "MJ-5.16S", NULL, BLIST_FORCELUN | BLIST_SINGLELUN}, + {"NEC", "PD-1 ODX654P", NULL, BLIST_FORCELUN | BLIST_SINGLELUN}, + {"NRC", "MBR-7", NULL, BLIST_FORCELUN | BLIST_SINGLELUN}, + {"NRC", "MBR-7.4", NULL, BLIST_FORCELUN | BLIST_SINGLELUN}, + {"PIONEER", "CD-ROM DRM-600", NULL, BLIST_FORCELUN | BLIST_SINGLELUN}, + {"PIONEER", "CD-ROM DRM-602X", NULL, BLIST_FORCELUN | BLIST_SINGLELUN}, + {"PIONEER", "CD-ROM DRM-604X", NULL, BLIST_FORCELUN | BLIST_SINGLELUN}, + {"REGAL", "CDC-4X", NULL, BLIST_MAX5LUN | BLIST_SINGLELUN}, {"SGI", "RAID3", "*", BLIST_SPARSELUN}, {"SGI", "RAID5", "*", BLIST_SPARSELUN}, {"SGI", "TP9100", "*", BLIST_SPARSELUN | BLIST_LARGELUN}, - {"SGI", "TP9300", "*", BLIST_SPARSELUN | BLIST_LARGELUN}, - {"SGI", "TP9400", "*", BLIST_SPARSELUN | BLIST_LARGELUN}, - {"SGI", "TP9500", "*", BLIST_SPARSELUN | BLIST_LARGELUN}, - {"MYLEX", "DACARMRB", "*", BLIST_SPARSELUN | BLIST_LARGELUN}, + {"SONY", "CD-ROM CDU-8001", NULL, BLIST_BORKEN}, + {"SONY", "TSL", NULL, BLIST_FORCELUN}, /* DDS3 & DDS4 autoloaders */ + {"SUN", "T300", "*", BLIST_SPARSELUN}, + {"SUN", "T4", "*", BLIST_SPARSELUN}, + {"TEXEL", "CD-ROM", "1.06", BLIST_BORKEN}, + {"TOSHIBA", "CDROM", NULL, BLIST_ISROM}, + {"TOSHIBA", "CD-ROM", NULL, BLIST_ISROM}, {"XYRATEX", "RS", "*", BLIST_SPARSELUN | BLIST_LARGELUN}, + {"Zzyzx", "RocketStor 500S", NULL, BLIST_SPARSELUN}, + {"Zzyzx", "RocketStor 2000", NULL, BLIST_SPARSELUN}, { NULL, NULL, NULL, 0 }, }; diff -Nru a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c --- a/drivers/scsi/scsi_error.c Sun Mar 14 14:20:05 2004 +++ b/drivers/scsi/scsi_error.c Sun Mar 14 14:20:05 2004 @@ -37,6 +37,8 @@ #define SENSE_TIMEOUT (10*HZ) #endif +#define START_UNIT_TIMEOUT (30*HZ) + /* * These should *probably* be handled by the host itself. * Since it is allowed to sleep, it probably should. @@ -282,6 +284,15 @@ (scmd->sense_buffer[13] == 0x01)) { return NEEDS_RETRY; } + /* + * if the device is not started, we need to wake + * the error handler to start the motor + */ + if (scmd->device->allow_restart && + (scmd->sense_buffer[12] == 0x04) && + (scmd->sense_buffer[13] == 0x02)) { + return FAILED; + } return SUCCESS; /* these three are not supported */ @@ -829,6 +840,105 @@ } /** + * scsi_eh_try_stu - Send START_UNIT to device. + * @scmd: Scsi cmd to send START_UNIT + * + * Return value: + * 0 - Device is ready. 1 - Device NOT ready. + **/ +static int scsi_eh_try_stu(struct scsi_cmnd *scmd) +{ + static unsigned char stu_command[6] = {START_STOP, 0, 0, 0, 1, 0}; + int rtn; + + if (!scmd->device->allow_restart) + return 1; + + memcpy(scmd->cmnd, stu_command, sizeof(stu_command)); + + /* + * zero the sense buffer. the scsi spec mandates that any + * untransferred sense data should be interpreted as being zero. + */ + memset(scmd->sense_buffer, 0, sizeof(scmd->sense_buffer)); + + scmd->request_buffer = NULL; + scmd->request_bufflen = 0; + scmd->use_sg = 0; + scmd->cmd_len = COMMAND_SIZE(scmd->cmnd[0]); + scmd->underflow = 0; + scmd->sc_data_direction = DMA_NONE; + + rtn = scsi_send_eh_cmnd(scmd, START_UNIT_TIMEOUT); + + /* + * when we eventually call scsi_finish, we really wish to complete + * the original request, so let's restore the original data. (db) + */ + scsi_setup_cmd_retry(scmd); + + /* + * hey, we are done. let's look to see what happened. + */ + SCSI_LOG_ERROR_RECOVERY(3, printk("%s: scmd %p rtn %x\n", + __FUNCTION__, scmd, rtn)); + if (rtn == SUCCESS) + return 0; + return 1; +} + + /** + * scsi_eh_stu - send START_UNIT if needed + * @shost: scsi host being recovered. + * @eh_done_q: list_head for processed commands. + * + * Notes: + * If commands are failing due to not ready, initializing command required, + * try revalidating the device, which will end up sending a start unit. + **/ +static int scsi_eh_stu(struct Scsi_Host *shost, + struct list_head *work_q, + struct list_head *done_q) +{ + struct list_head *lh, *lh_sf; + struct scsi_cmnd *scmd, *stu_scmd; + struct scsi_device *sdev; + + shost_for_each_device(sdev, shost) { + stu_scmd = NULL; + list_for_each_entry(scmd, work_q, eh_entry) + if (scmd->device == sdev && SCSI_SENSE_VALID(scmd) && + scsi_check_sense(scmd) == FAILED ) { + stu_scmd = scmd; + break; + } + + if (!stu_scmd) + continue; + + SCSI_LOG_ERROR_RECOVERY(3, printk("%s: Sending START_UNIT to sdev:" + " 0x%p\n", current->comm, sdev)); + + if (!scsi_eh_try_stu(stu_scmd)) { + if (!sdev->online || !scsi_eh_tur(stu_scmd)) { + list_for_each_safe(lh, lh_sf, work_q) { + scmd = list_entry(lh, struct scsi_cmnd, eh_entry); + if (scmd->device == sdev) + scsi_eh_finish_cmd(scmd, done_q); + } + } + } else { + SCSI_LOG_ERROR_RECOVERY(3, + printk("%s: START_UNIT failed to sdev:" + " 0x%p\n", current->comm, sdev)); + } + } + + return list_empty(work_q); +} + + +/** * scsi_eh_bus_device_reset - send bdr if needed * @shost: scsi host being recovered. * @eh_done_q: list_head for processed commands. @@ -1033,7 +1143,9 @@ if (rtn == SUCCESS) { list_for_each_safe(lh, lh_sf, work_q) { scmd = list_entry(lh, struct scsi_cmnd, eh_entry); - if (!scmd->device->online || !scsi_eh_tur(scmd)) + if (!scmd->device->online || + (!scsi_eh_try_stu(scmd) && !scsi_eh_tur(scmd)) || + !scsi_eh_tur(scmd)) scsi_eh_finish_cmd(scmd, done_q); } } else { @@ -1181,6 +1293,8 @@ */ case DID_SOFT_ERROR: goto maybe_retry; + case DID_IMM_RETRY: + return NEEDS_RETRY; case DID_ERROR: if (msg_byte(scmd->result) == COMMAND_COMPLETE && @@ -1401,10 +1515,11 @@ struct list_head *work_q, struct list_head *done_q) { - if (!scsi_eh_bus_device_reset(shost, work_q, done_q)) - if (!scsi_eh_bus_reset(shost, work_q, done_q)) - if (!scsi_eh_host_reset(work_q, done_q)) - scsi_eh_offline_sdevs(work_q, done_q); + if (!scsi_eh_stu(shost, work_q, done_q)) + if (!scsi_eh_bus_device_reset(shost, work_q, done_q)) + if (!scsi_eh_bus_reset(shost, work_q, done_q)) + if (!scsi_eh_host_reset(work_q, done_q)) + scsi_eh_offline_sdevs(work_q, done_q); } /** diff -Nru a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c --- a/drivers/scsi/scsi_lib.c Sun Mar 14 14:20:07 2004 +++ b/drivers/scsi/scsi_lib.c Sun Mar 14 14:20:07 2004 @@ -24,7 +24,7 @@ #include "scsi_logging.h" -#define SG_MEMPOOL_NR 5 +#define SG_MEMPOOL_NR (sizeof(scsi_sg_pools)/sizeof(struct scsi_host_sg_pool)) #define SG_MEMPOOL_SIZE 32 struct scsi_host_sg_pool { @@ -34,9 +34,27 @@ mempool_t *pool; }; +#if (SCSI_MAX_PHYS_SEGMENTS < 32) +#error SCSI_MAX_PHYS_SEGMENTS is too small +#endif + #define SP(x) { x, "sgpool-" #x } -struct scsi_host_sg_pool scsi_sg_pools[SG_MEMPOOL_NR] = { - SP(8), SP(16), SP(32), SP(64), SP(MAX_PHYS_SEGMENTS) +struct scsi_host_sg_pool scsi_sg_pools[] = { + SP(8), + SP(16), + SP(32), +#if (SCSI_MAX_PHYS_SEGMENTS > 32) + SP(64), +#if (SCSI_MAX_PHYS_SEGMENTS > 64) + SP(128), +#if (SCSI_MAX_PHYS_SEGMENTS > 128) + SP(256), +#if (SCSI_MAX_PHYS_SEGMENTS > 256) +#error SCSI_MAX_PHYS_SEGMENTS is too large +#endif +#endif +#endif +#endif }; #undef SP @@ -172,6 +190,10 @@ * like ioctls and character device requests - this is because * we essentially just inject a request into the queue for the * device. + * + * In order to support the scsi_device_quiesce function, we + * now inject requests on the *head* of the device queue + * rather than the tail. */ void scsi_do_req(struct scsi_request *sreq, const void *cmnd, void *buffer, unsigned bufflen, @@ -202,11 +224,9 @@ sreq->sr_cmd_len = COMMAND_SIZE(sreq->sr_cmnd[0]); /* - * At this point, we merely set up the command, stick it in the normal - * request queue, and return. Eventually that request will come to the - * top of the list, and will be dispatched. + * head injection *required* here otherwise quiesce won't work */ - scsi_insert_special_req(sreq, 0); + scsi_insert_special_req(sreq, 1); } static void scsi_wait_done(struct scsi_cmnd *cmd) @@ -558,12 +578,21 @@ case 17 ... 32: cmd->sglist_len = 2; break; +#if (SCSI_MAX_PHYS_SEGMENTS > 32) case 33 ... 64: cmd->sglist_len = 3; break; - case 65 ... MAX_PHYS_SEGMENTS: +#if (SCSI_MAX_PHYS_SEGMENTS > 64) + case 65 ... 128: cmd->sglist_len = 4; break; +#if (SCSI_MAX_PHYS_SEGMENTS > 128) + case 129 ... 256: + cmd->sglist_len = 5; + break; +#endif +#endif +#endif default: return NULL; } @@ -917,6 +946,7 @@ req->current_nr_sectors); /* release the command and kill it */ + scsi_release_buffers(cmd); scsi_put_command(cmd); return BLKPREP_KILL; } @@ -939,7 +969,7 @@ } /* OK, we only allow special commands (i.e. not * user initiated ones */ - specials_only = 1; + specials_only = sdev->sdev_state; } /* @@ -965,6 +995,9 @@ } else if (req->flags & (REQ_CMD | REQ_BLOCK_PC)) { if(unlikely(specials_only)) { + if(specials_only == SDEV_QUIESCE) + return BLKPREP_DEFER; + printk(KERN_ERR "scsi%d (%d:%d): rejecting I/O to device being removed\n", sdev->host->host_no, sdev->id, sdev->lun); return BLKPREP_KILL; @@ -1285,7 +1318,7 @@ blk_queue_prep_rq(q, scsi_prep_fn); blk_queue_max_hw_segments(q, shost->sg_tablesize); - blk_queue_max_phys_segments(q, MAX_PHYS_SEGMENTS); + blk_queue_max_phys_segments(q, SCSI_MAX_PHYS_SEGMENTS); blk_queue_max_sectors(q, shost->max_sectors); blk_queue_bounce_limit(q, scsi_calculate_bounce_limit(shost)); blk_queue_segment_boundary(q, shost->dma_boundary); @@ -1508,3 +1541,95 @@ return ret; } + +/** + * scsi_device_set_state - Take the given device through the device + * state model. + * @sdev: scsi device to change the state of. + * @state: state to change to. + * + * Returns zero if unsuccessful or an error if the requested + * transition is illegal. + **/ +int +scsi_device_set_state(struct scsi_device *sdev, enum scsi_device_state state) +{ + enum scsi_device_state oldstate = sdev->sdev_state; + + /* FIXME: eventually we will enforce all the state model + * transitions here */ + + if(oldstate == state) + return 0; + + switch(state) { + case SDEV_RUNNING: + if(oldstate != SDEV_CREATED && oldstate != SDEV_QUIESCE) + return -EINVAL; + break; + + case SDEV_QUIESCE: + if(oldstate != SDEV_RUNNING) + return -EINVAL; + break; + + default: + break; + } + sdev->sdev_state = state; + + return 0; +} +EXPORT_SYMBOL(scsi_device_set_state); + +/** + * scsi_device_quiesce - Block user issued commands. + * @sdev: scsi device to quiesce. + * + * This works by trying to transition to the SDEV_QUIESCE state + * (which must be a legal transition). When the device is in this + * state, only special requests will be accepted, all others will + * be deferred. Since special requests may also be requeued requests, + * a successful return doesn't guarantee the device will be + * totally quiescent. + * + * Must be called with user context, may sleep. + * + * Returns zero if unsuccessful or an error if not. + **/ +int +scsi_device_quiesce(struct scsi_device *sdev) +{ + int err = scsi_device_set_state(sdev, SDEV_QUIESCE); + if(err) + return err; + + scsi_run_queue(sdev->request_queue); + while(sdev->device_busy) { + schedule_timeout(HZ/5); + scsi_run_queue(sdev->request_queue); + } + return 0; +} +EXPORT_SYMBOL(scsi_device_quiesce); + +/** + * scsi_device_resume - Restart user issued commands to a quiesced device. + * @sdev: scsi device to resume. + * + * Moves the device from quiesced back to running and restarts the + * queues. + * + * Must be called with user context, may sleep. + **/ +void +scsi_device_resume(struct scsi_device *sdev) +{ + if(sdev->sdev_state != SDEV_QUIESCE) + return; + + scsi_device_set_state(sdev, SDEV_RUNNING); + scsi_run_queue(sdev->request_queue); +} +EXPORT_SYMBOL(scsi_device_resume); + diff -Nru a/drivers/scsi/scsi_priv.h b/drivers/scsi/scsi_priv.h --- a/drivers/scsi/scsi_priv.h Sun Mar 14 14:20:07 2004 +++ b/drivers/scsi/scsi_priv.h Sun Mar 14 14:20:07 2004 @@ -155,6 +155,7 @@ extern int scsi_sysfs_add_host(struct Scsi_Host *); extern int scsi_sysfs_register(void); extern void scsi_sysfs_unregister(void); +extern struct scsi_transport_template blank_transport_template; extern struct class sdev_class; extern struct bus_type scsi_bus_type; diff -Nru a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c --- a/drivers/scsi/scsi_scan.c Sun Mar 14 14:20:08 2004 +++ b/drivers/scsi/scsi_scan.c Sun Mar 14 14:20:08 2004 @@ -35,6 +35,7 @@ #include #include #include +#include #include "scsi.h" #include "scsi_priv.h" @@ -192,7 +193,7 @@ struct scsi_device *sdev, *device; unsigned long flags; - sdev = kmalloc(sizeof(*sdev), GFP_ATOMIC); + sdev = kmalloc(sizeof(*sdev) + shost->transportt->size, GFP_ATOMIC); if (!sdev) goto out; @@ -237,6 +238,11 @@ goto out_free_queue; } + if (shost->transportt->setup) { + if (shost->transportt->setup(sdev)) + goto out_cleanup_slave; + } + if (get_device(&sdev->host->shost_gendev)) { device_initialize(&sdev->sdev_gendev); @@ -253,8 +259,15 @@ snprintf(sdev->sdev_classdev.class_id, BUS_ID_SIZE, "%d:%d:%d:%d", sdev->host->host_no, sdev->channel, sdev->id, sdev->lun); + + class_device_initialize(&sdev->transport_classdev); + sdev->transport_classdev.dev = &sdev->sdev_gendev; + sdev->transport_classdev.class = sdev->host->transportt->class; + snprintf(sdev->transport_classdev.class_id, BUS_ID_SIZE, + "%d:%d:%d:%d", sdev->host->host_no, + sdev->channel, sdev->id, sdev->lun); } else - goto out_cleanup_slave; + goto out_cleanup_transport; /* * If there are any same target siblings, add this to the @@ -283,6 +296,9 @@ spin_unlock_irqrestore(shost->host_lock, flags); return sdev; +out_cleanup_transport: + if (shost->transportt->cleanup) + shost->transportt->cleanup(sdev); out_cleanup_slave: if (shost->hostt->slave_destroy) shost->hostt->slave_destroy(sdev); @@ -627,6 +643,10 @@ if (*bflags & BLIST_USE_10_BYTE_MS) sdev->use_10_for_ms = 1; + /* set the device running here so that slave configure + * may do I/O */ + scsi_device_set_state(sdev, SDEV_RUNNING); + if(sdev->host->hostt->slave_configure) sdev->host->hostt->slave_configure(sdev); @@ -744,6 +764,8 @@ } else { if (sdev->host->hostt->slave_destroy) sdev->host->hostt->slave_destroy(sdev); + if (sdev->host->transportt->cleanup) + sdev->host->transportt->cleanup(sdev); put_device(&sdev->sdev_gendev); } out: @@ -1300,5 +1322,7 @@ if (sdev->host->hostt->slave_destroy) sdev->host->hostt->slave_destroy(sdev); + if (sdev->host->transportt->cleanup) + sdev->host->transportt->cleanup(sdev); put_device(&sdev->sdev_gendev); } diff -Nru a/drivers/scsi/scsi_sysfs.c b/drivers/scsi/scsi_sysfs.c --- a/drivers/scsi/scsi_sysfs.c Sun Mar 14 14:20:06 2004 +++ b/drivers/scsi/scsi_sysfs.c Sun Mar 14 14:20:06 2004 @@ -13,6 +13,7 @@ #include #include +#include #include "scsi.h" #include "scsi_priv.h" @@ -58,21 +59,24 @@ * shost_show_function: macro to create an attr function that can be used to * show a non-bit field. */ -#define shost_show_function(field, format_string) \ +#define shost_show_function(name, field, format_string) \ static ssize_t \ -show_##field (struct class_device *class_dev, char *buf) \ +show_##name (struct class_device *class_dev, char *buf) \ { \ struct Scsi_Host *shost = class_to_shost(class_dev); \ - return snprintf (buf, 20, format_string, shost->field); \ + return snprintf (buf, 20, format_string, shost->field); \ } /* * shost_rd_attr: macro to create a function and attribute variable for a * read only field. */ -#define shost_rd_attr(field, format_string) \ - shost_show_function(field, format_string) \ -static CLASS_DEVICE_ATTR(field, S_IRUGO, show_##field, NULL) +#define shost_rd_attr2(name, field, format_string) \ + shost_show_function(name, field, format_string) \ +static CLASS_DEVICE_ATTR(name, S_IRUGO, show_##name, NULL) + +#define shost_rd_attr(field, format_string) \ +shost_rd_attr2(field, field, format_string) /* * Create the actual show/store functions and data structures. @@ -96,6 +100,7 @@ shost_rd_attr(cmd_per_lun, "%hd\n"); shost_rd_attr(sg_tablesize, "%hu\n"); shost_rd_attr(unchecked_isa_dma, "%d\n"); +shost_rd_attr2(proc_name, hostt->proc_name, "%s\n"); static struct class_device_attribute *scsi_sysfs_shost_attrs[] = { &class_device_attr_unique_id, @@ -103,6 +108,7 @@ &class_device_attr_cmd_per_lun, &class_device_attr_sg_tablesize, &class_device_attr_unchecked_isa_dma, + &class_device_attr_proc_name, &class_device_attr_scan, NULL }; @@ -344,13 +350,12 @@ **/ int scsi_sysfs_add_sdev(struct scsi_device *sdev) { - int error = -EINVAL, i; + struct class_device_attribute **attrs; + int error, i; - if (sdev->sdev_state != SDEV_CREATED) + if ((error = scsi_device_set_state(sdev, SDEV_RUNNING)) != 0) return error; - sdev->sdev_state = SDEV_RUNNING; - error = device_add(&sdev->sdev_gendev); if (error) { printk(KERN_INFO "error 1\n"); @@ -362,9 +367,20 @@ printk(KERN_INFO "error 2\n"); goto clean_device; } - + /* take a reference for the sdev_classdev; this is + * released by the sdev_class .release */ get_device(&sdev->sdev_gendev); + if (sdev->transport_classdev.class) { + error = class_device_add(&sdev->transport_classdev); + if (error) + goto clean_device2; + /* take a reference for the transport_classdev; this + * is released by the transport_class .release */ + get_device(&sdev->sdev_gendev); + + } + if (sdev->host->hostt->sdev_attrs) { for (i = 0; sdev->host->hostt->sdev_attrs[i]; i++) { error = attr_add(&sdev->sdev_gendev, @@ -388,11 +404,25 @@ } } + if (sdev->transport_classdev.class) { + attrs = sdev->host->transportt->attrs; + for (i = 0; attrs[i]; i++) { + error = class_device_create_file(&sdev->transport_classdev, + attrs[i]); + if (error) { + scsi_remove_device(sdev); + goto out; + } + } + } + out: return error; -clean_device: - sdev->sdev_state = SDEV_CANCEL; + clean_device2: + class_device_del(&sdev->sdev_classdev); + clean_device: + scsi_device_set_state(sdev, SDEV_CANCEL); device_del(&sdev->sdev_gendev); put_device(&sdev->sdev_gendev); @@ -407,11 +437,15 @@ void scsi_remove_device(struct scsi_device *sdev) { if (sdev->sdev_state == SDEV_RUNNING || sdev->sdev_state == SDEV_CANCEL) { - sdev->sdev_state = SDEV_DEL; + scsi_device_set_state(sdev, SDEV_DEL); class_device_unregister(&sdev->sdev_classdev); + if(sdev->transport_classdev.class) + class_device_unregister(&sdev->transport_classdev); device_del(&sdev->sdev_gendev); if (sdev->host->hostt->slave_destroy) sdev->host->hostt->slave_destroy(sdev); + if (sdev->host->transportt->cleanup) + sdev->host->transportt->cleanup(sdev); put_device(&sdev->sdev_gendev); } } @@ -498,3 +532,7 @@ return 0; } + +/* A blank transport template that is used in drivers that don't + * yet implement Transport Attributes */ +struct scsi_transport_template blank_transport_template = { 0, }; diff -Nru a/drivers/scsi/scsi_transport_fc.c b/drivers/scsi/scsi_transport_fc.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/drivers/scsi/scsi_transport_fc.c Sun Mar 14 14:20:09 2004 @@ -0,0 +1,104 @@ +/* + * FiberChannel transport specific attributes exported to sysfs. + * + * Copyright (c) 2003 Silicon Graphics, Inc. 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 + * (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 + +static void transport_class_release(struct class_device *class_dev); + +struct class fc_transport_class = { + .name = "fc_transport", + .release = transport_class_release, +}; + +static __init int fc_transport_init(void) +{ + return class_register(&fc_transport_class); +} + +static void __exit fc_transport_exit(void) +{ + class_unregister(&fc_transport_class); +} + +static int fc_setup_transport_attrs(struct scsi_device *sdev) +{ + /* FIXME: Callback into the driver */ + fc_node_name(sdev) = -1; + fc_port_name(sdev) = -1; + fc_port_id(sdev) = -1; + + return 0; +} + +static void transport_class_release(struct class_device *class_dev) +{ + struct scsi_device *sdev = transport_class_to_sdev(class_dev); + put_device(&sdev->sdev_gendev); +} + +#define fc_transport_show_function(field, format_string, cast) \ +static ssize_t \ +show_fc_transport_##field (struct class_device *cdev, char *buf) \ +{ \ + struct scsi_device *sdev = transport_class_to_sdev(cdev); \ + struct fc_transport_attrs *tp; \ + tp = (struct fc_transport_attrs *)&sdev->transport_data; \ + return snprintf(buf, 20, format_string, cast tp->field); \ +} + +#define fc_transport_rd_attr(field, format_string) \ + fc_transport_show_function(field, format_string, ) \ +static CLASS_DEVICE_ATTR( field, S_IRUGO, show_fc_transport_##field, NULL) + +#define fc_transport_rd_attr_cast(field, format_string, cast) \ + fc_transport_show_function(field, format_string, (cast)) \ +static CLASS_DEVICE_ATTR( field, S_IRUGO, show_fc_transport_##field, NULL) + +/* the FiberChannel Tranport Attributes: */ +fc_transport_rd_attr_cast(node_name, "0x%llx\n", unsigned long long); +fc_transport_rd_attr_cast(port_name, "0x%llx\n", unsigned long long); +fc_transport_rd_attr(port_id, "0x%06x\n"); + +struct class_device_attribute *fc_transport_attrs[] = { + &class_device_attr_node_name, + &class_device_attr_port_name, + &class_device_attr_port_id, + NULL +}; + +struct scsi_transport_template fc_transport_template = { + .attrs = fc_transport_attrs, + .class = &fc_transport_class, + .setup = &fc_setup_transport_attrs, + .cleanup = NULL, + .size = sizeof(struct fc_transport_attrs) - sizeof(unsigned long), +}; +EXPORT_SYMBOL(fc_transport_template); + +MODULE_AUTHOR("Martin Hicks"); +MODULE_DESCRIPTION("FC Transport Attributes"); +MODULE_LICENSE("GPL"); + +module_init(fc_transport_init); +module_exit(fc_transport_exit); diff -Nru a/drivers/scsi/scsi_transport_spi.c b/drivers/scsi/scsi_transport_spi.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/drivers/scsi/scsi_transport_spi.c Sun Mar 14 14:20:09 2004 @@ -0,0 +1,673 @@ +/* + * Parallel SCSI (SPI) transport specific attributes exported to sysfs. + * + * Copyright (c) 2003 Silicon Graphics, Inc. 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 + * (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 +#include +#include +#include +#include +#include +#include + +#define SPI_PRINTK(x, l, f, a...) printk(l "scsi(%d:%d:%d:%d): " f, (x)->host->host_no, (x)->channel, (x)->id, (x)->lun, ##a) + +static void transport_class_release(struct class_device *class_dev); + +#define SPI_NUM_ATTRS 10 /* increase this if you add attributes */ + +#define SPI_MAX_ECHO_BUFFER_SIZE 4096 + +#define spi_dv_pending(x) (((struct spi_transport_attrs *)&(x)->transport_data)->dv_pending) + +struct spi_internal { + struct scsi_transport_template t; + struct spi_function_template *f; + /* The actual attributes */ + struct class_device_attribute private_attrs[SPI_NUM_ATTRS]; + /* The array of null terminated pointers to attributes + * needed by scsi_sysfs.c */ + struct class_device_attribute *attrs[SPI_NUM_ATTRS + 1]; +}; + +#define to_spi_internal(tmpl) container_of(tmpl, struct spi_internal, t) + +static const char *const ppr_to_ns[] = { + /* The PPR values 0-6 are reserved, fill them in when + * the committee defines them */ + NULL, /* 0x00 */ + NULL, /* 0x01 */ + NULL, /* 0x02 */ + NULL, /* 0x03 */ + NULL, /* 0x04 */ + NULL, /* 0x05 */ + NULL, /* 0x06 */ + "3.125", /* 0x07 */ + "6.25", /* 0x08 */ + "12.5", /* 0x09 */ + "25", /* 0x0a */ + "30.3", /* 0x0b */ + "50", /* 0x0c */ +}; +/* The PPR values at which you calculate the period in ns by multiplying + * by 4 */ +#define SPI_STATIC_PPR 0x0c + +struct class spi_transport_class = { + .name = "spi_transport", + .release = transport_class_release, +}; + +static __init int spi_transport_init(void) +{ + return class_register(&spi_transport_class); +} + +static void __exit spi_transport_exit(void) +{ + class_unregister(&spi_transport_class); +} + +static int spi_setup_transport_attrs(struct scsi_device *sdev) +{ + spi_period(sdev) = -1; /* illegal value */ + spi_offset(sdev) = 0; /* async */ + spi_width(sdev) = 0; /* narrow */ + spi_iu(sdev) = 0; /* no IU */ + spi_dt(sdev) = 0; /* ST */ + spi_qas(sdev) = 0; + spi_wr_flow(sdev) = 0; + spi_rd_strm(sdev) = 0; + spi_rti(sdev) = 0; + spi_pcomp_en(sdev) = 0; + spi_dv_pending(sdev) = 0; + + return 0; +} + +static void transport_class_release(struct class_device *class_dev) +{ + struct scsi_device *sdev = transport_class_to_sdev(class_dev); + put_device(&sdev->sdev_gendev); +} + +#define spi_transport_show_function(field, format_string) \ + \ +static ssize_t \ +show_spi_transport_##field(struct class_device *cdev, char *buf) \ +{ \ + struct scsi_device *sdev = transport_class_to_sdev(cdev); \ + struct spi_transport_attrs *tp; \ + struct spi_internal *i = to_spi_internal(sdev->host->transportt); \ + tp = (struct spi_transport_attrs *)&sdev->transport_data; \ + if (i->f->get_##field) \ + i->f->get_##field(sdev); \ + return snprintf(buf, 20, format_string, tp->field); \ +} + +#define spi_transport_store_function(field, format_string) \ +static ssize_t \ +store_spi_transport_##field(struct class_device *cdev, const char *buf, \ + size_t count) \ +{ \ + int val; \ + struct scsi_device *sdev = transport_class_to_sdev(cdev); \ + struct spi_internal *i = to_spi_internal(sdev->host->transportt); \ + \ + val = simple_strtoul(buf, NULL, 0); \ + i->f->set_##field(sdev, val); \ + return count; \ +} + +#define spi_transport_rd_attr(field, format_string) \ + spi_transport_show_function(field, format_string) \ + spi_transport_store_function(field, format_string) \ +static CLASS_DEVICE_ATTR(field, S_IRUGO | S_IWUSR, \ + show_spi_transport_##field, \ + store_spi_transport_##field) + +/* The Parallel SCSI Tranport Attributes: */ +spi_transport_rd_attr(offset, "%d\n"); +spi_transport_rd_attr(width, "%d\n"); +spi_transport_rd_attr(iu, "%d\n"); +spi_transport_rd_attr(dt, "%d\n"); +spi_transport_rd_attr(qas, "%d\n"); +spi_transport_rd_attr(wr_flow, "%d\n"); +spi_transport_rd_attr(rd_strm, "%d\n"); +spi_transport_rd_attr(rti, "%d\n"); +spi_transport_rd_attr(pcomp_en, "%d\n"); + +/* Translate the period into ns according to the current spec + * for SDTR/PPR messages */ +static ssize_t show_spi_transport_period(struct class_device *cdev, char *buf) + +{ + struct scsi_device *sdev = transport_class_to_sdev(cdev); + struct spi_transport_attrs *tp; + const char *str; + struct spi_internal *i = to_spi_internal(sdev->host->transportt); + + tp = (struct spi_transport_attrs *)&sdev->transport_data; + + if (i->f->get_period) + i->f->get_period(sdev); + + switch(tp->period) { + + case 0x07 ... SPI_STATIC_PPR: + str = ppr_to_ns[tp->period]; + if(!str) + str = "reserved"; + break; + + + case (SPI_STATIC_PPR+1) ... 0xff: + return sprintf(buf, "%d\n", tp->period * 4); + + default: + str = "unknown"; + } + return sprintf(buf, "%s\n", str); +} + +static ssize_t +store_spi_transport_period(struct class_device *cdev, const char *buf, + size_t count) +{ + struct scsi_device *sdev = transport_class_to_sdev(cdev); + struct spi_internal *i = to_spi_internal(sdev->host->transportt); + int j, period = -1; + + for (j = 0; j < SPI_STATIC_PPR; j++) { + int len; + + if(ppr_to_ns[j] == NULL) + continue; + + len = strlen(ppr_to_ns[j]); + + if(strncmp(ppr_to_ns[j], buf, len) != 0) + continue; + + if(buf[len] != '\n') + continue; + + period = j; + break; + } + + if (period == -1) { + int val = simple_strtoul(buf, NULL, 0); + + + /* Should probably check limits here, but this + * gets reasonably close to OK for most things */ + period = val/4; + } + + if (period > 0xff) + period = 0xff; + + i->f->set_period(sdev, period); + + return count; +} + +static CLASS_DEVICE_ATTR(period, S_IRUGO | S_IWUSR, + show_spi_transport_period, + store_spi_transport_period); + +#define DV_SET(x, y) \ + if(i->f->set_##x) \ + i->f->set_##x(sdev, y) + +#define DV_LOOPS 3 +#define DV_TIMEOUT (10*HZ) +#define DV_RETRIES 5 + + +/* This is for read/write Domain Validation: If the device supports + * an echo buffer, we do read/write tests to it */ +static int +spi_dv_device_echo_buffer(struct scsi_request *sreq, u8 *buffer, + u8 *ptr, const int retries) +{ + struct scsi_device *sdev = sreq->sr_device; + int len = ptr - buffer; + int j, k, r; + unsigned int pattern = 0x0000ffff; + + const char spi_write_buffer[] = { + WRITE_BUFFER, 0x0a, 0, 0, 0, 0, 0, len >> 8, len & 0xff, 0 + }; + const char spi_read_buffer[] = { + READ_BUFFER, 0x0a, 0, 0, 0, 0, 0, len >> 8, len & 0xff, 0 + }; + + /* set up the pattern buffer. Doesn't matter if we spill + * slightly beyond since that's where the read buffer is */ + for (j = 0; j < len; ) { + + /* fill the buffer with counting (test a) */ + for ( ; j < min(len, 32); j++) + buffer[j] = j; + k = j; + /* fill the buffer with alternating words of 0x0 and + * 0xffff (test b) */ + for ( ; j < min(len, k + 32); j += 2) { + u16 *word = (u16 *)&buffer[j]; + + *word = (j & 0x02) ? 0x0000 : 0xffff; + } + k = j; + /* fill with crosstalk (alternating 0x5555 0xaaa) + * (test c) */ + for ( ; j < min(len, k + 32); j += 2) { + u16 *word = (u16 *)&buffer[j]; + + *word = (j & 0x02) ? 0x5555 : 0xaaaa; + } + k = j; + /* fill with shifting bits (test d) */ + for ( ; j < min(len, k + 32); j += 4) { + u32 *word = (unsigned int *)&buffer[j]; + u32 roll = (pattern & 0x80000000) ? 1 : 0; + + *word = pattern; + pattern = (pattern << 1) | roll; + } + /* don't bother with random data (test e) */ + } + + for (r = 0; r < retries; r++) { + sreq->sr_cmd_len = 0; /* wait_req to fill in */ + sreq->sr_data_direction = DMA_TO_DEVICE; + scsi_wait_req(sreq, spi_write_buffer, buffer, len, + DV_TIMEOUT, DV_RETRIES); + if(sreq->sr_result) { + SPI_PRINTK(sdev, KERN_ERR, "Write Buffer failure %x\n", sreq->sr_result); + return 0; + } + + memset(ptr, 0, len); + sreq->sr_cmd_len = 0; /* wait_req to fill in */ + sreq->sr_data_direction = DMA_FROM_DEVICE; + scsi_wait_req(sreq, spi_read_buffer, ptr, len, + DV_TIMEOUT, DV_RETRIES); + + if (memcmp(buffer, ptr, len) != 0) + return 0; + } + return 1; +} + +/* This is for the simplest form of Domain Validation: a read test + * on the inquiry data from the device */ +static int +spi_dv_device_compare_inquiry(struct scsi_request *sreq, u8 *buffer, + u8 *ptr, const int retries) +{ + int r; + const int len = sreq->sr_device->inquiry_len; + const char spi_inquiry[] = { + INQUIRY, 0, 0, 0, len, 0 + }; + + for (r = 0; r < retries; r++) { + sreq->sr_cmd_len = 0; /* wait_req to fill in */ + sreq->sr_data_direction = DMA_FROM_DEVICE; + + memset(ptr, 0, len); + + scsi_wait_req(sreq, spi_inquiry, ptr, len, + DV_TIMEOUT, DV_RETRIES); + + /* If we don't have the inquiry data already, the + * first read gets it */ + if (ptr == buffer) { + ptr += len; + --r; + continue; + } + + if (memcmp(buffer, ptr, len) != 0) + /* failure */ + return 0; + } + return 1; +} + +static int +spi_dv_retrain(struct scsi_request *sreq, u8 *buffer, u8 *ptr, + int (*compare_fn)(struct scsi_request *, u8 *, u8 *, int)) +{ + struct spi_internal *i = to_spi_internal(sreq->sr_host->transportt); + struct scsi_device *sdev = sreq->sr_device; + int period, prevperiod = 0; + + + for (;;) { + if (compare_fn(sreq, buffer, ptr, DV_LOOPS)) + /* Successful DV */ + break; + + /* OK, retrain, fallback */ + if (i->f->get_period) + i->f->get_period(sdev); + period = spi_period(sdev); + if (period < 0x0d) + period++; + else + period += period >> 1; + + if (unlikely(period > 0xff || period == prevperiod)) { + /* Total failure; set to async and return */ + SPI_PRINTK(sdev, KERN_ERR, "Domain Validation Failure, dropping back to Asynchronous\n"); + DV_SET(offset, 0); + return 0; + } + SPI_PRINTK(sdev, KERN_ERR, "Domain Validation detected failure, dropping back\n"); + DV_SET(period, period); + prevperiod = period; + } + return 1; +} + +static int +spi_dv_device_get_echo_buffer(struct scsi_request *sreq, u8 *buffer) +{ + int l; + + /* first off do a test unit ready. This can error out + * because of reservations or some other reason. If it + * fails, the device won't let us write to the echo buffer + * so just return failure */ + + const char spi_test_unit_ready[] = { + TEST_UNIT_READY, 0, 0, 0, 0, 0 + }; + + const char spi_read_buffer_descriptor[] = { + READ_BUFFER, 0x0b, 0, 0, 0, 0, 0, 0, 4, 0 + }; + + + sreq->sr_cmd_len = 0; + sreq->sr_data_direction = DMA_NONE; + + /* We send a set of three TURs to clear any outstanding + * unit attention conditions if they exist (Otherwise the + * buffer tests won't be happy). If the TUR still fails + * (reservation conflict, device not ready, etc) just + * skip the write tests */ + for (l = 0; ; l++) { + scsi_wait_req(sreq, spi_test_unit_ready, NULL, 0, + DV_TIMEOUT, DV_RETRIES); + + if(sreq->sr_result) { + if(l >= 3) + return 0; + } else { + /* TUR succeeded */ + break; + } + } + + sreq->sr_cmd_len = 0; + sreq->sr_data_direction = DMA_FROM_DEVICE; + + scsi_wait_req(sreq, spi_read_buffer_descriptor, buffer, 4, + DV_TIMEOUT, DV_RETRIES); + + if (sreq->sr_result) + /* Device has no echo buffer */ + return 0; + + return buffer[3] + ((buffer[2] & 0x1f) << 8); +} + +static void +spi_dv_device_internal(struct scsi_request *sreq, u8 *buffer) +{ + struct spi_internal *i = to_spi_internal(sreq->sr_host->transportt); + struct scsi_device *sdev = sreq->sr_device; + int len = sdev->inquiry_len; + /* first set us up for narrow async */ + DV_SET(offset, 0); + DV_SET(width, 0); + + if (!spi_dv_device_compare_inquiry(sreq, buffer, buffer, DV_LOOPS)) { + SPI_PRINTK(sdev, KERN_ERR, "Domain Validation Initial Inquiry Failed\n"); + /* FIXME: should probably offline the device here? */ + return; + } + + /* test width */ + if (i->f->set_width) { + i->f->set_width(sdev, 1); + + if (!spi_dv_device_compare_inquiry(sreq, buffer, + buffer + len, + DV_LOOPS)) { + SPI_PRINTK(sdev, KERN_ERR, "Wide Transfers Fail\n"); + i->f->set_width(sdev, 0); + } + } + + if (!i->f->set_period) + return; + + /* now set up to the maximum */ + DV_SET(offset, 255); + DV_SET(period, 1); + if (!spi_dv_retrain(sreq, buffer, buffer + len, + spi_dv_device_compare_inquiry)) + return; + + /* OK, now we have our initial speed set by the read only inquiry + * test, now try an echo buffer test (if the device allows it) */ + + if ((len = spi_dv_device_get_echo_buffer(sreq, buffer)) == 0) { + SPI_PRINTK(sdev, KERN_INFO, "Domain Validation skipping write tests\n"); + return; + } + if (len > SPI_MAX_ECHO_BUFFER_SIZE) { + SPI_PRINTK(sdev, KERN_WARNING, "Echo buffer size %d is too big, trimming to %d\n", len, SPI_MAX_ECHO_BUFFER_SIZE); + len = SPI_MAX_ECHO_BUFFER_SIZE; + } + + spi_dv_retrain(sreq, buffer, buffer + len, + spi_dv_device_echo_buffer); +} + + +/** spi_dv_device - Do Domain Validation on the device + * @sdev: scsi device to validate + * + * Performs the domain validation on the given device in the + * current execution thread. Since DV operations may sleep, + * the current thread must have user context. Also no SCSI + * related locks that would deadlock I/O issued by the DV may + * be held. + */ +void +spi_dv_device(struct scsi_device *sdev) +{ + struct scsi_request *sreq = scsi_allocate_request(sdev, GFP_KERNEL); + u8 *buffer; + const int len = SPI_MAX_ECHO_BUFFER_SIZE*2; + + if (unlikely(!sreq)) + return; + + if (unlikely(scsi_device_get(sdev))) + goto out_free_req; + + buffer = kmalloc(len, GFP_KERNEL); + + if (unlikely(!buffer)) + goto out_put; + + memset(buffer, 0, len); + + if (unlikely(scsi_device_quiesce(sdev))) + goto out_free; + + SPI_PRINTK(sdev, KERN_INFO, "Beginning Domain Validation\n"); + + spi_dv_device_internal(sreq, buffer); + + SPI_PRINTK(sdev, KERN_INFO, "Ending Domain Validation\n"); + + scsi_device_resume(sdev); + + out_free: + kfree(buffer); + out_put: + scsi_device_put(sdev); + out_free_req: + scsi_release_request(sreq); +} +EXPORT_SYMBOL(spi_dv_device); + +struct work_queue_wrapper { + struct work_struct work; + struct scsi_device *sdev; +}; + +static void +spi_dv_device_work_wrapper(void *data) +{ + struct work_queue_wrapper *wqw = (struct work_queue_wrapper *)data; + struct scsi_device *sdev = wqw->sdev; + + kfree(wqw); + spi_dv_device(sdev); + spi_dv_pending(sdev) = 0; + scsi_device_put(sdev); +} + + +/** + * spi_schedule_dv_device - schedule domain validation to occur on the device + * @sdev: The device to validate + * + * Identical to spi_dv_device() above, except that the DV will be + * scheduled to occur in a workqueue later. All memory allocations + * are atomic, so may be called from any context including those holding + * SCSI locks. + */ +void +spi_schedule_dv_device(struct scsi_device *sdev) +{ + struct work_queue_wrapper *wqw = + kmalloc(sizeof(struct work_queue_wrapper), GFP_ATOMIC); + + if (unlikely(!wqw)) + return; + + if (unlikely(spi_dv_pending(sdev))) { + kfree(wqw); + return; + } + + if (unlikely(scsi_device_get(sdev))) { + kfree(wqw); + spi_dv_pending(sdev) = 0; + return; + } + + INIT_WORK(&wqw->work, spi_dv_device_work_wrapper, wqw); + wqw->sdev = sdev; + + schedule_work(&wqw->work); +} +EXPORT_SYMBOL(spi_schedule_dv_device); + +#define SETUP_ATTRIBUTE(field) \ + i->private_attrs[count] = class_device_attr_##field; \ + if (!i->f->set_##field) { \ + i->private_attrs[count].attr.mode = S_IRUGO; \ + i->private_attrs[count].store = NULL; \ + } \ + i->attrs[count] = &i->private_attrs[count]; \ + if (i->f->show_##field) \ + count++ + +struct scsi_transport_template * +spi_attach_transport(struct spi_function_template *ft) +{ + struct spi_internal *i = kmalloc(sizeof(struct spi_internal), + GFP_KERNEL); + int count = 0; + if (unlikely(!i)) + return NULL; + + memset(i, 0, sizeof(struct spi_internal)); + + + i->t.attrs = &i->attrs[0]; + i->t.class = &spi_transport_class; + i->t.setup = &spi_setup_transport_attrs; + i->t.size = sizeof(struct spi_transport_attrs) - sizeof(unsigned long); + i->f = ft; + + SETUP_ATTRIBUTE(period); + SETUP_ATTRIBUTE(offset); + SETUP_ATTRIBUTE(width); + SETUP_ATTRIBUTE(iu); + SETUP_ATTRIBUTE(dt); + SETUP_ATTRIBUTE(qas); + SETUP_ATTRIBUTE(wr_flow); + SETUP_ATTRIBUTE(rd_strm); + SETUP_ATTRIBUTE(rti); + SETUP_ATTRIBUTE(pcomp_en); + + /* if you add an attribute but forget to increase SPI_NUM_ATTRS + * this bug will trigger */ + BUG_ON(count > SPI_NUM_ATTRS); + + i->attrs[count] = NULL; + + return &i->t; +} +EXPORT_SYMBOL(spi_attach_transport); + +void spi_release_transport(struct scsi_transport_template *t) +{ + struct spi_internal *i = to_spi_internal(t); + + kfree(i); +} +EXPORT_SYMBOL(spi_release_transport); + + +MODULE_AUTHOR("Martin Hicks"); +MODULE_DESCRIPTION("SPI Transport Attributes"); +MODULE_LICENSE("GPL"); + +module_init(spi_transport_init); +module_exit(spi_transport_exit); diff -Nru a/drivers/scsi/sd.c b/drivers/scsi/sd.c --- a/drivers/scsi/sd.c Sun Mar 14 14:20:08 2004 +++ b/drivers/scsi/sd.c Sun Mar 14 14:20:08 2004 @@ -19,6 +19,9 @@ * not being read in sd_open. Fix problem where removable media * could be ejected after sd_open. * - Douglas Gilbert cleanup for lk 2.5.x + * - Badari Pulavarty , Matthew Wilcox + * , Kurt Garloff : + * Support 32k/1M disks. * * Logging policy (needs CONFIG_SCSI_LOGGING defined): * - setting up transfer: SCSI_LOG_HLQUEUE levels 1 and 2 @@ -61,7 +64,7 @@ * Remaining dev_t-handling stuff */ #define SD_MAJORS 16 -#define SD_DISKS (SD_MAJORS << 4) +#define SD_DISKS 32768 /* anything between 256 and 262144 */ /* * Time out in seconds for disks and Magneto-opticals (which are slower). @@ -121,6 +124,20 @@ .init_command = sd_init_command, }; +/* Device no to disk mapping: + * + * major disc2 disc p1 + * |............|.............|....|....| <- dev_t + * 31 20 19 8 7 4 3 0 + * + * Inside a major, we have 16k disks, however mapped non- + * contiguously. The first 16 disks are for major0, the next + * ones with major1, ... Disk 256 is for major0 again, disk 272 + * for major1, ... + * As we stay compatible with our numbering scheme, we can reuse + * the well-know SCSI majors 8, 65--71, 136--143. + */ + static int sd_major(int major_idx) { switch (major_idx) { @@ -136,6 +153,14 @@ } } +static unsigned int make_sd_dev(unsigned int sd_nr, unsigned int part) +{ + return (part & 0xf) | ((sd_nr & 0xf) << 4) | + (sd_major((sd_nr & 0xf0) >> 4) << 20) | (sd_nr & 0xfff00); +} + +/* reverse mapping dev -> (sd_nr, part) not currently needed */ + #define to_scsi_disk(obj) container_of(obj,struct scsi_disk,kobj); static inline struct scsi_disk *scsi_disk(struct gendisk *disk) @@ -1301,7 +1326,7 @@ struct scsi_disk *sdkp; struct gendisk *gd; u32 index; - int error; + int error, devno; error = -ENODEV; if ((sdp->type != TYPE_DISK) && (sdp->type != TYPE_MOD)) @@ -1319,6 +1344,12 @@ kobject_init(&sdkp->kobj); sdkp->kobj.ktype = &scsi_disk_kobj_type; + /* Note: We can accomodate 64 partitions, but the genhd code + * assumes partitions allocate consecutive minors, which they don't. + * So for now stay with max 16 partitions and leave two spare bits. + * Later, we may change the genhd code and the alloc_disk() call + * and the ->minors assignment here. KG, 2004-02-10 + */ gd = alloc_disk(16); if (!gd) goto out_free; @@ -1339,16 +1370,23 @@ sdkp->index = index; sdkp->openers = 0; - gd->major = sd_major(index >> 4); - gd->first_minor = (index & 15) << 4; + devno = make_sd_dev(index, 0); + gd->major = MAJOR(devno); + gd->first_minor = MINOR(devno); gd->minors = 16; gd->fops = &sd_fops; - if (index >= 26) { + if (index < 26) { + sprintf(gd->disk_name, "sd%c", 'a' + index % 26); + } else if (index < (26*27)) { sprintf(gd->disk_name, "sd%c%c", - 'a' + index/26-1,'a' + index % 26); + 'a' + index / 26 - 1,'a' + index % 26); } else { - sprintf(gd->disk_name, "sd%c", 'a' + index % 26); + const unsigned int m1 = (index / 26 - 1) / 26 - 1; + const unsigned int m2 = (index / 26 - 1) % 26; + const unsigned int m3 = index % 26; + sprintf(gd->disk_name, "sd%c%c%c", + 'a' + m1, 'a' + m2, 'a' + m3); } strcpy(gd->devfs_name, sdp->devfs_name); diff -Nru a/drivers/scsi/sr.c b/drivers/scsi/sr.c --- a/drivers/scsi/sr.c Sun Mar 14 14:20:06 2004 +++ b/drivers/scsi/sr.c Sun Mar 14 14:20:06 2004 @@ -566,10 +566,13 @@ snprintf(disk->devfs_name, sizeof(disk->devfs_name), "%s/cd", sdev->devfs_name); disk->driverfs_dev = &sdev->sdev_gendev; - register_cdrom(&cd->cdi); set_capacity(disk, cd->capacity); disk->private_data = &cd->driver; disk->queue = sdev->request_queue; + cd->cdi.disk = disk; + + if (register_cdrom(&cd->cdi)) + goto fail_put; dev_set_drvdata(dev, cd); add_disk(disk); diff -Nru a/drivers/scsi/st.c b/drivers/scsi/st.c --- a/drivers/scsi/st.c Sun Mar 14 14:20:07 2004 +++ b/drivers/scsi/st.c Sun Mar 14 14:20:07 2004 @@ -17,7 +17,7 @@ Last modified: 18-JAN-1998 Richard Gooch Devfs support */ -static char *verstr = "20040213"; +static char *verstr = "20040226"; #include @@ -121,7 +121,15 @@ }; #endif -static char *st_formats[ST_NBR_MODES] ={"", "l", "m", "a"}; +/* Restrict the number of modes so that names for all are assigned */ +#if ST_NBR_MODES > 16 +#error "Maximum number of modes is 16" +#endif +/* Bit reversed order to get same names for same minors with all + mode counts */ +static char *st_formats[] = { + "", "r", "k", "s", "l", "t", "o", "u", + "m", "v", "p", "x", "a", "y", "q", "z"}; /* The default definitions have been moved to st_options.h */ @@ -3888,8 +3896,11 @@ dev_num); goto out_free_tape; } - snprintf(cdev->kobj.name, KOBJ_NAME_LEN, "%sm%d%s", disk->disk_name, - mode, j ? "n" : ""); + /* Make sure that the minor numbers corresponding to the four + first modes always get the same names */ + i = mode << (4 - ST_NBR_MODE_BITS); + snprintf(cdev->kobj.name, KOBJ_NAME_LEN, "%s%s%s", j ? "n" : "", + disk->disk_name, st_formats[i]); cdev->owner = THIS_MODULE; cdev->ops = &st_fops; @@ -3909,22 +3920,26 @@ } for (mode = 0; mode < ST_NBR_MODES; ++mode) { + /* Make sure that the minor numbers corresponding to the four + first modes always get the same names */ + i = mode << (4 - ST_NBR_MODE_BITS); /* Rewind entry */ - devfs_mk_cdev(MKDEV(SCSI_TAPE_MAJOR, dev_num + (mode << 5)), + devfs_mk_cdev(MKDEV(SCSI_TAPE_MAJOR, TAPE_MINOR(dev_num, mode, 0)), S_IFCHR | S_IRUGO | S_IWUGO, - "%s/mt%s", SDp->devfs_name, st_formats[mode]); + "%s/mt%s", SDp->devfs_name, st_formats[i]); /* No-rewind entry */ - devfs_mk_cdev(MKDEV(SCSI_TAPE_MAJOR, dev_num + (mode << 5) + 128), + devfs_mk_cdev(MKDEV(SCSI_TAPE_MAJOR, TAPE_MINOR(dev_num, mode, 1)), S_IFCHR | S_IRUGO | S_IWUGO, - "%s/mt%sn", SDp->devfs_name, st_formats[mode]); + "%s/mt%sn", SDp->devfs_name, st_formats[i]); } disk->number = devfs_register_tape(SDp->devfs_name); printk(KERN_WARNING "Attached scsi tape %s at scsi%d, channel %d, id %d, lun %d\n", tape_name(tpnt), SDp->host->host_no, SDp->channel, SDp->id, SDp->lun); - printk(KERN_WARNING "%s: try direct i/o: %s, max page reachable by HBA %lu\n", - tape_name(tpnt), tpnt->try_dio ? "yes" : "no", tpnt->max_pfn); + printk(KERN_WARNING "%s: try direct i/o: %s (alignment %d B), max page reachable by HBA %lu\n", + tape_name(tpnt), tpnt->try_dio ? "yes" : "no", + queue_dma_alignment(SDp->request_queue) + 1, tpnt->max_pfn); return 0; @@ -3977,8 +3992,9 @@ sysfs_remove_link(&tpnt->device->sdev_gendev.kobj, "tape"); for (mode = 0; mode < ST_NBR_MODES; ++mode) { - devfs_remove("%s/mt%s", SDp->devfs_name, st_formats[mode]); - devfs_remove("%s/mt%sn", SDp->devfs_name, st_formats[mode]); + j = mode << (4 - ST_NBR_MODE_BITS); + devfs_remove("%s/mt%s", SDp->devfs_name, st_formats[j]); + devfs_remove("%s/mt%sn", SDp->devfs_name, st_formats[j]); for (j=0; j < 2; j++) { class_simple_device_remove(MKDEV(SCSI_TAPE_MAJOR, TAPE_MINOR(i, mode, j))); diff -Nru a/drivers/scsi/st.h b/drivers/scsi/st.h --- a/drivers/scsi/st.h Sun Mar 14 14:20:08 2004 +++ b/drivers/scsi/st.h Sun Mar 14 14:20:08 2004 @@ -50,6 +50,8 @@ struct cdev *cdevs[2]; /* Auto-rewind and non-rewind devices */ } ST_mode; +/* Number of modes can be changed by changing ST_NBR_MODE_BITS. The maximum + number of modes is 16 (ST_NBR_MODE_BITS 4) */ #define ST_NBR_MODE_BITS 2 #define ST_NBR_MODES (1 << ST_NBR_MODE_BITS) #define ST_MODE_SHIFT (7 - ST_NBR_MODE_BITS) diff -Nru a/drivers/scsi/sym53c8xx_2/sym53c8xx.h b/drivers/scsi/sym53c8xx_2/sym53c8xx.h --- a/drivers/scsi/sym53c8xx_2/sym53c8xx.h Sun Mar 14 14:20:08 2004 +++ b/drivers/scsi/sym53c8xx_2/sym53c8xx.h Sun Mar 14 14:20:08 2004 @@ -70,13 +70,6 @@ #define SYM_CONF_DMA_ADDRESSING_MODE CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE /* - * NCR PQS/PDS special device support. - */ -#if 1 -#define SYM_CONF_PQS_PDS_SUPPORT -#endif - -/* * NVRAM support. */ #if 1 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 Sun Mar 14 14:20:07 2004 +++ b/drivers/scsi/sym53c8xx_2/sym_defs.h Sun Mar 14 14:20:07 2004 @@ -127,135 +127,6 @@ }; /* - * Symbios NVRAM data format - */ -#define SYMBIOS_NVRAM_SIZE 368 -#define SYMBIOS_NVRAM_ADDRESS 0x100 - -struct Symbios_nvram { -/* Header 6 bytes */ - u_short type; /* 0x0000 */ - u_short byte_count; /* excluding header/trailer */ - u_short checksum; - -/* Controller set up 20 bytes */ - u_char v_major; /* 0x00 */ - u_char v_minor; /* 0x30 */ - u32 boot_crc; - u_short flags; -#define SYMBIOS_SCAM_ENABLE (1) -#define SYMBIOS_PARITY_ENABLE (1<<1) -#define SYMBIOS_VERBOSE_MSGS (1<<2) -#define SYMBIOS_CHS_MAPPING (1<<3) -#define SYMBIOS_NO_NVRAM (1<<3) /* ??? */ - u_short flags1; -#define SYMBIOS_SCAN_HI_LO (1) - u_short term_state; -#define SYMBIOS_TERM_CANT_PROGRAM (0) -#define SYMBIOS_TERM_ENABLED (1) -#define SYMBIOS_TERM_DISABLED (2) - u_short rmvbl_flags; -#define SYMBIOS_RMVBL_NO_SUPPORT (0) -#define SYMBIOS_RMVBL_BOOT_DEVICE (1) -#define SYMBIOS_RMVBL_MEDIA_INSTALLED (2) - u_char host_id; - u_char num_hba; /* 0x04 */ - u_char num_devices; /* 0x10 */ - u_char max_scam_devices; /* 0x04 */ - u_char num_valid_scam_devices; /* 0x00 */ - u_char flags2; -#define SYMBIOS_AVOID_BUS_RESET (1<<2) - -/* Boot order 14 bytes * 4 */ - struct Symbios_host{ - u_short type; /* 4:8xx / 0:nok */ - u_short device_id; /* PCI device id */ - u_short vendor_id; /* PCI vendor id */ - u_char bus_nr; /* PCI bus number */ - u_char device_fn; /* PCI device/function number << 3*/ - u_short word8; - u_short flags; -#define SYMBIOS_INIT_SCAN_AT_BOOT (1) - u_short io_port; /* PCI io_port address */ - } host[4]; - -/* Targets 8 bytes * 16 */ - struct Symbios_target { - u_char flags; -#define SYMBIOS_DISCONNECT_ENABLE (1) -#define SYMBIOS_SCAN_AT_BOOT_TIME (1<<1) -#define SYMBIOS_SCAN_LUNS (1<<2) -#define SYMBIOS_QUEUE_TAGS_ENABLED (1<<3) - u_char rsvd; - u_char bus_width; /* 0x08/0x10 */ - u_char sync_offset; - u_short sync_period; /* 4*period factor */ - u_short timeout; - } target[16]; -/* Scam table 8 bytes * 4 */ - struct Symbios_scam { - u_short id; - u_short method; -#define SYMBIOS_SCAM_DEFAULT_METHOD (0) -#define SYMBIOS_SCAM_DONT_ASSIGN (1) -#define SYMBIOS_SCAM_SET_SPECIFIC_ID (2) -#define SYMBIOS_SCAM_USE_ORDER_GIVEN (3) - u_short status; -#define SYMBIOS_SCAM_UNKNOWN (0) -#define SYMBIOS_SCAM_DEVICE_NOT_FOUND (1) -#define SYMBIOS_SCAM_ID_NOT_SET (2) -#define SYMBIOS_SCAM_ID_VALID (3) - u_char target_id; - u_char rsvd; - } scam[4]; - - u_char spare_devices[15*8]; - u_char trailer[6]; /* 0xfe 0xfe 0x00 0x00 0x00 0x00 */ -}; -typedef struct Symbios_nvram Symbios_nvram; -typedef struct Symbios_host Symbios_host; -typedef struct Symbios_target Symbios_target; -typedef struct Symbios_scam Symbios_scam; - -/* - * Tekram NvRAM data format. - */ -#define TEKRAM_NVRAM_SIZE 64 -#define TEKRAM_93C46_NVRAM_ADDRESS 0 -#define TEKRAM_24C16_NVRAM_ADDRESS 0x40 - -struct Tekram_nvram { - struct Tekram_target { - u_char flags; -#define TEKRAM_PARITY_CHECK (1) -#define TEKRAM_SYNC_NEGO (1<<1) -#define TEKRAM_DISCONNECT_ENABLE (1<<2) -#define TEKRAM_START_CMD (1<<3) -#define TEKRAM_TAGGED_COMMANDS (1<<4) -#define TEKRAM_WIDE_NEGO (1<<5) - u_char sync_index; - u_short word2; - } target[16]; - u_char host_id; - u_char flags; -#define TEKRAM_MORE_THAN_2_DRIVES (1) -#define TEKRAM_DRIVES_SUP_1GB (1<<1) -#define TEKRAM_RESET_ON_POWER_ON (1<<2) -#define TEKRAM_ACTIVE_NEGATION (1<<3) -#define TEKRAM_IMMEDIATE_SEEK (1<<4) -#define TEKRAM_SCAN_LUNS (1<<5) -#define TEKRAM_REMOVABLE_FLAGS (3<<6) /* 0: disable; */ - /* 1: boot device; 2:all */ - u_char boot_delay_index; - u_char max_tags_index; - u_short flags1; -#define TEKRAM_F2_F6_ENABLED (1) - u_short spare[29]; -}; -typedef struct Tekram_nvram Tekram_nvram; -typedef struct Tekram_target Tekram_target; - -/* * SYM53C8XX IO register data structure. */ struct sym_reg { 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 Sun Mar 14 14:20:08 2004 +++ b/drivers/scsi/sym53c8xx_2/sym_fw.c Sun Mar 14 14:20:08 2004 @@ -135,7 +135,7 @@ * Patch routine for firmware #1. */ static void -sym_fw1_patch(hcb_p np) +sym_fw1_patch(struct sym_hcb *np) { struct sym_fw1a_scr *scripta0; struct sym_fw1b_scr *scriptb0; @@ -176,7 +176,7 @@ * Patch routine for firmware #2. */ static void -sym_fw2_patch(hcb_p np) +sym_fw2_patch(struct sym_hcb *np) { struct sym_fw2a_scr *scripta0; struct sym_fw2b_scr *scriptb0; @@ -282,7 +282,7 @@ * To be done for all firmwares. */ static void -sym_fw_setup_bus_addresses(hcb_p np, struct sym_fw *fw) +sym_fw_setup_bus_addresses(struct sym_hcb *np, struct sym_fw *fw) { u32 *pa; u_short *po; @@ -319,7 +319,7 @@ * Setup routine for firmware #1. */ static void -sym_fw1_setup(hcb_p np, struct sym_fw *fw) +sym_fw1_setup(struct sym_hcb *np, struct sym_fw *fw) { struct sym_fw1a_scr *scripta0; struct sym_fw1b_scr *scriptb0; @@ -343,7 +343,7 @@ * Setup routine for firmware #2. */ static void -sym_fw2_setup(hcb_p np, struct sym_fw *fw) +sym_fw2_setup(struct sym_hcb *np, struct sym_fw *fw) { struct sym_fw2a_scr *scripta0; struct sym_fw2b_scr *scriptb0; @@ -389,7 +389,7 @@ /* * Bind a script to physical addresses. */ -void sym_fw_bind_script (hcb_p np, u32 *start, int len) +void sym_fw_bind_script(struct sym_hcb *np, u32 *start, int len) { u32 opcode, new, old, tmp1, tmp2; u32 *end, *cur; 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 Sun Mar 14 14:20:09 2004 +++ b/drivers/scsi/sym53c8xx_2/sym_glue.c Sun Mar 14 14:20:09 2004 @@ -57,7 +57,9 @@ #include #include #include + #include "sym_glue.h" +#include "sym_nvram.h" #define NAME53C "sym53c" #define NAME53C8XX "sym53c8xx" @@ -212,17 +214,32 @@ return use_sg; } -static void __sync_scsi_data(struct pci_dev *pdev, struct scsi_cmnd *cmd) +static void __sync_scsi_data_for_cpu(struct pci_dev *pdev, struct scsi_cmnd *cmd) { int dma_dir = scsi_to_pci_dma_dir(cmd->sc_data_direction); switch(SYM_UCMD_PTR(cmd)->data_mapped) { case 2: - pci_dma_sync_sg(pdev, cmd->buffer, cmd->use_sg, dma_dir); + pci_dma_sync_sg_for_cpu(pdev, cmd->buffer, cmd->use_sg, dma_dir); break; case 1: - pci_dma_sync_single(pdev, SYM_UCMD_PTR(cmd)->data_mapping, - cmd->request_bufflen, dma_dir); + pci_dma_sync_single_for_cpu(pdev, SYM_UCMD_PTR(cmd)->data_mapping, + cmd->request_bufflen, dma_dir); + break; + } +} + +static void __sync_scsi_data_for_device(struct pci_dev *pdev, struct scsi_cmnd *cmd) +{ + int dma_dir = scsi_to_pci_dma_dir(cmd->sc_data_direction); + + switch(SYM_UCMD_PTR(cmd)->data_mapped) { + case 2: + pci_dma_sync_sg_for_device(pdev, cmd->buffer, cmd->use_sg, dma_dir); + break; + case 1: + pci_dma_sync_single_for_device(pdev, SYM_UCMD_PTR(cmd)->data_mapping, + cmd->request_bufflen, dma_dir); break; } } @@ -233,8 +250,10 @@ __map_scsi_single_data(np->s.device, cmd) #define map_scsi_sg_data(np, cmd) \ __map_scsi_sg_data(np->s.device, cmd) -#define sync_scsi_data(np, cmd) \ - __sync_scsi_data(np->s.device, cmd) +#define sync_scsi_data_for_cpu(np, cmd) \ + __sync_scsi_data_for_cpu(np->s.device, cmd) +#define sync_scsi_data_for_device(np, cmd) \ + __sync_scsi_data_for_device(np->s.device, cmd) /* * Complete a pending CAM CCB. @@ -394,10 +413,11 @@ if (!cmd || cmd->use_sg) return; - sync_scsi_data(np, cmd); + sync_scsi_data_for_cpu(np, cmd); retv = __sym_sniff_inquiry(np, cmd->device->id, cmd->device->lun, (u_char *) cmd->request_buffer, cmd->request_bufflen - resid); + sync_scsi_data_for_device(np, cmd); if (retv < 0) return; else if (retv) @@ -532,7 +552,7 @@ /* * Setup buffers and pointers that address the CDB. */ -static int __inline sym_setup_cdb(struct sym_hcb *np, struct scsi_cmnd *ccb, struct sym_ccb *cp) +static inline int sym_setup_cdb(struct sym_hcb *np, struct scsi_cmnd *ccb, struct sym_ccb *cp) { u32 cmd_ba; int cmd_len; @@ -1281,7 +1301,7 @@ { int verb_len = strlen(verb); - if (len >= strlen(verb) && !memcmp(verb, ptr, verb_len)) + if (len >= verb_len && !memcmp(verb, ptr, verb_len)) return verb_len; else return 0; @@ -1938,7 +1958,7 @@ char *cur = str; char *pc, *pv; unsigned long val; - int i, c; + unsigned int i, c; int xi = 0; while (cur != NULL && (pc = strchr(cur, ':')) != NULL) { @@ -2171,6 +2191,55 @@ return 0; } +/* + * The NCR PQS and PDS cards are constructed as a DEC bridge + * behind which sits a proprietary NCR memory controller and + * either four or two 53c875s as separate devices. We can tell + * if an 875 is part of a PQS/PDS or not since if it is, it will + * be on the same bus as the memory controller. In its usual + * mode of operation, the 875s are slaved to the memory + * controller for all transfers. To operate with the Linux + * driver, the memory controller is disabled and the 875s + * freed to function independently. The only wrinkle is that + * the preset SCSI ID (which may be zero) must be read in from + * a special configuration space register of the 875. + */ +void sym_config_pqs(struct pci_dev *pdev, struct sym_device *sym_dev) +{ + int slot; + + for (slot = 0; slot < 256; slot++) { + u8 tmp; + struct pci_dev *memc = pci_get_slot(pdev->bus, slot); + + if (!memc || memc->vendor != 0x101a || memc->device == 0x0009) { + pci_dev_put(memc); + continue; + } + + /* + * We set these bits in the memory controller once per 875. + * This isn't a problem in practice. + */ + + /* bit 1: allow individual 875 configuration */ + pci_read_config_byte(memc, 0x44, &tmp); + tmp |= 0x2; + pci_write_config_byte(memc, 0x44, tmp); + + /* bit 2: drive individual 875 interrupts to the bus */ + pci_read_config_byte(memc, 0x45, &tmp); + tmp |= 0x4; + pci_write_config_byte(memc, 0x45, tmp); + + pci_read_config_byte(pdev, 0x84, &tmp); + sym_dev->host_id = tmp; + + pci_dev_put(memc); + + break; + } +} /* * Called before unloading the module. @@ -2221,79 +2290,6 @@ #endif }; -#ifdef _SYM_CONF_PQS_PDS_SUPPORT -#if 0 -/* - * Detect all NCR PQS/PDS boards and keep track of their bus nr. - * - * The NCR PQS or PDS card is constructed as a DEC bridge - * behind which sit a proprietary NCR memory controller and - * four or two 53c875s as separate devices. In its usual mode - * of operation, the 875s are slaved to the memory controller - * for all transfers. We can tell if an 875 is part of a - * PQS/PDS or not since if it is, it will be on the same bus - * as the memory controller. To operate with the Linux - * driver, the memory controller is disabled and the 875s - * freed to function independently. The only wrinkle is that - * the preset SCSI ID (which may be zero) must be read in from - * a special configuration space register of the 875 - */ -#ifndef SYM_CONF_MAX_PQS_BUS -#define SYM_CONF_MAX_PQS_BUS 16 -#endif -static int pqs_bus[SYM_CONF_MAX_PQS_BUS] __initdata = { 0 }; - -static void __init sym_detect_pqs_pds(void) -{ - short index; - struct pci_dev *dev = NULL; - - for(index=0; index < SYM_CONF_MAX_PQS_BUS; index++) { - u_char tmp; - - dev = pci_find_device(0x101a, 0x0009, dev); - if (dev == NULL) { - pqs_bus[index] = -1; - break; - } - printf_info(NAME53C8XX ": NCR PQS/PDS memory controller detected on bus %d\n", dev->bus->number); - pci_read_config_byte(dev, 0x44, &tmp); - /* bit 1: allow individual 875 configuration */ - tmp |= 0x2; - pci_write_config_byte(dev, 0x44, tmp); - pci_read_config_byte(dev, 0x45, &tmp); - /* bit 2: drive individual 875 interrupts to the bus */ - tmp |= 0x4; - pci_write_config_byte(dev, 0x45, tmp); - - pqs_bus[index] = dev->bus->number; - } -} -#endif - -static int pqs_probe() -{ -} - -static void pqs_remove() -{ -} - -static struct pci_device_id pqs_id_table[] __devinitdata = { - { 0x101a, 0x0009, }, - { 0, } -}; - -MODULE_DEVICE_TABLE(pci, pqs_id_table); - -static struct pci_driver pqs_driver = { - .name = NAME53C8XX " (PQS)", - .id_table = pqs_id_table, - .probe = pqs_probe, - .remove = __devexit_p(pqs_remove), -}; -#endif /* PQS */ - static int attach_count; static int __devinit sym2_probe(struct pci_dev *pdev, @@ -2318,6 +2314,8 @@ if (sym53c8xx_pci_init(pdev, &sym_dev)) goto free; + sym_config_pqs(pdev, &sym_dev); + sym_get_nvram(&sym_dev, &nvram); instance = sym_attach(&sym2_template, attach_count, &sym_dev); @@ -2406,9 +2404,6 @@ static int __init sym2_init(void) { -#ifdef _SYM_CONF_PQS_PDS_SUPPORT - pci_register_driver(&pqs_driver); -#endif pci_register_driver(&sym2_driver); return 0; } @@ -2416,9 +2411,6 @@ static void __exit sym2_exit(void) { pci_unregister_driver(&sym2_driver); -#ifdef _SYM_CONF_PQS_PDS_SUPPORT - pci_unregister_driver(&pqs_driver); -#endif } module_init(sym2_init); 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 Sun Mar 14 14:20:08 2004 +++ b/drivers/scsi/sym53c8xx_2/sym_glue.h Sun Mar 14 14:20:08 2004 @@ -77,9 +77,9 @@ /* * General driver includes. */ -#include "sym_misc.h" #include "sym_conf.h" #include "sym_defs.h" +#include "sym_misc.h" /* * Configuration addendum for Linux. @@ -113,6 +113,26 @@ #define sym_mdelay(ms) mdelay(ms) /* + * A 'read barrier' flushes any data that have been prefetched + * by the processor due to out of order execution. Such a barrier + * must notably be inserted prior to looking at data that have + * been DMAed, assuming that program does memory READs in proper + * order and that the device ensured proper ordering of WRITEs. + * + * A 'write barrier' prevents any previous WRITEs to pass further + * WRITEs. Such barriers must be inserted each time another agent + * relies on ordering of WRITEs. + * + * Note that, due to posting of PCI memory writes, we also must + * insert dummy PCI read transactions when some ordering involving + * both directions over the PCI does matter. PCI transactions are + * fully ordered in each direction. + */ + +#define MEMORY_READ_BARRIER() rmb() +#define MEMORY_WRITE_BARRIER() wmb() + +/* * Let the compiler know about driver data structure names. */ typedef struct sym_tcb *tcb_p; @@ -413,6 +433,8 @@ char inst_name[16]; }; +struct sym_nvram; + struct sym_device { struct pci_dev *pdev; struct sym_slot s; @@ -420,12 +442,7 @@ struct sym_nvram *nvram; u_short device_id; u_char host_id; -#ifdef SYM_CONF_PQS_PDS_SUPPORT - u_char pqs_pds; -#endif }; - -typedef struct sym_device *sdev_p; /* * The driver definitions (sym_hipd.h) must know about a 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 Sun Mar 14 14:20:05 2004 +++ b/drivers/scsi/sym53c8xx_2/sym_hipd.c Sun Mar 14 14:20:05 2004 @@ -50,13 +50,10 @@ * SUCH DAMAGE. */ -#define SYM_DRIVER_NAME "sym-2.1.18f" +#define SYM_DRIVER_NAME "sym-2.1.18i" -#ifdef __FreeBSD__ -#include -#else #include "sym_glue.h" -#endif +#include "sym_nvram.h" #if 0 #define SYM_DEBUG_GENERIC_SUPPORT @@ -616,8 +613,7 @@ if (dt) { fak = (kpc - 1) / (div_10M[div] << 1) + 1 - 2; /* ret = ((2+fak)*div_10M[div])/np->clock_khz; */ - } - else { + } else { fak = (kpc - 1) / div_10M[div] + 1 - 4; /* ret = ((4+fak)*div_10M[div])/np->clock_khz; */ } @@ -625,8 +621,10 @@ /* * Check against our hardware limits, or bugs :). */ - if (fak < 0) {fak = 0; ret = -1;} - if (fak > 2) {fak = 2; ret = -1;} + if (fak > 2) { + fak = 2; + ret = -1; + } /* * Compute and return sync parameters. @@ -1054,8 +1052,9 @@ sym_nvram_setup_target (np, i, nvram); /* - * For now, guess PPR/DT support from the period - * and BUS width. + * Some single-ended devices may crash on receiving a + * PPR negotiation attempt. Only try PPR if we're in + * LVD mode. */ if (np->features & FE_ULTRA3) { tp->tinfo.user.options |= PPR_OPT_DT; diff -Nru a/drivers/scsi/sym53c8xx_2/sym_hipd.h b/drivers/scsi/sym53c8xx_2/sym_hipd.h --- a/drivers/scsi/sym53c8xx_2/sym_hipd.h Sun Mar 14 14:20:07 2004 +++ b/drivers/scsi/sym53c8xx_2/sym_hipd.h Sun Mar 14 14:20:07 2004 @@ -171,6 +171,15 @@ #define SYM_CONF_MIN_ASYNC (40) /* + * Shortest memory chunk is (1<hcb_ba + offsetof(struct sym_hcb, lbl)) -/* - * NVRAM reading (sym_nvram.c). - */ -#if SYM_CONF_NVRAM_SUPPORT -void sym_nvram_setup_host (hcb_p np, struct sym_nvram *nvram); -void sym_nvram_setup_target (hcb_p np, int target, struct sym_nvram *nvp); -int sym_read_nvram (sdev_p np, struct sym_nvram *nvp); -#else -static inline void sym_nvram_setup_host(hcb_p np, struct sym_nvram *nvram) { } -static inline void sym_nvram_setup_target(hcb_p np, struct sym_nvram *nvram) { } -static inline int sym_read_nvram(sdev_p np, struct sym_nvram *nvp) -{ - nvp->type = 0; - return 0; -} -#endif - /* * FIRMWARES (sym_fw.c) @@ -1257,8 +1234,8 @@ * Set up data pointers used by SCRIPTS. * Called from O/S specific code. */ -static void __inline -sym_setup_data_pointers(hcb_p np, ccb_p cp, int dir) +static inline void sym_setup_data_pointers(struct sym_hcb *np, + struct sym_ccb *cp, int dir) { u32 lastp, goalp; @@ -1321,15 +1298,6 @@ /* * MEMORY ALLOCATOR. */ - -/* - * Shortest memory chunk is (1<inq_byte56; if (inq_version >= 4 && inq_len > 56) - tp->inq_byte56 = inq_data[56]; + inq_byte56 = inq_data[56]; #if 0 printf("XXXXXX [%d] inq_version=%x inq_byte7=%x inq_byte56=%x XXXXX\n", inq_len, inq_version, inq_byte7, inq_byte56); @@ -328,6 +328,7 @@ tp->inq_byte56 != inq_byte56) { tp->inq_version = inq_version; tp->inq_byte7 = inq_byte7; + tp->inq_byte56 = inq_byte56; return 1; } return 0; 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 Sun Mar 14 14:20:08 2004 +++ b/drivers/scsi/sym53c8xx_2/sym_misc.h Sun Mar 14 14:20:08 2004 @@ -54,41 +54,6 @@ #define SYM_MISC_H /* - * A 'read barrier' flushes any data that have been prefetched - * by the processor due to out of order execution. Such a barrier - * must notably be inserted prior to looking at data that have - * been DMAed, assuming that program does memory READs in proper - * order and that the device ensured proper ordering of WRITEs. - * - * A 'write barrier' prevents any previous WRITEs to pass further - * WRITEs. Such barriers must be inserted each time another agent - * relies on ordering of WRITEs. - * - * Note that, due to posting of PCI memory writes, we also must - * insert dummy PCI read transactions when some ordering involving - * both directions over the PCI does matter. PCI transactions are - * fully ordered in each direction. - * - * IA32 processors insert implicit barriers when the processor - * accesses unchacheable either for reading or writing, and - * donnot reorder WRITEs. As a result, some 'read barriers' can - * be avoided (following access to uncacheable), and 'write - * barriers' should be useless (preventing compiler optimizations - * should be enough). - */ - -#define __READ_BARRIER() rmb() -#define __WRITE_BARRIER() wmb() - -#ifndef MEMORY_READ_BARRIER -#define MEMORY_READ_BARRIER() __READ_BARRIER() -#endif -#ifndef MEMORY_WRITE_BARRIER -#define MEMORY_WRITE_BARRIER() __WRITE_BARRIER() -#endif - - -/* * A la VMS/CAM-3 queue management. */ typedef struct sym_quehead { @@ -222,48 +187,11 @@ #define sym_is_bit(p, n) (((u32 *)(p))[(n)>>5] & (1<<((n)&0x1f))) /* - * Portable but silly implemented byte order primitives. - */ -#if BYTE_ORDER == BIG_ENDIAN - -#define __revb16(x) ( (((u16)(x) & (u16)0x00ffU) << 8) | \ - (((u16)(x) & (u16)0xff00U) >> 8) ) -#define __revb32(x) ( (((u32)(x) & 0x000000ffU) << 24) | \ - (((u32)(x) & 0x0000ff00U) << 8) | \ - (((u32)(x) & 0x00ff0000U) >> 8) | \ - (((u32)(x) & 0xff000000U) >> 24) ) - -#define __htole16(v) __revb16(v) -#define __htole32(v) __revb32(v) -#define __le16toh(v) __htole16(v) -#define __le32toh(v) __htole32(v) - -static __inline u16 _htole16(u16 v) { return __htole16(v); } -static __inline u32 _htole32(u32 v) { return __htole32(v); } -#define _le16toh _htole16 -#define _le32toh _htole32 - -#else /* LITTLE ENDIAN */ - -#define __htole16(v) (v) -#define __htole32(v) (v) -#define __le16toh(v) (v) -#define __le32toh(v) (v) - -#define _htole16(v) (v) -#define _htole32(v) (v) -#define _le16toh(v) (v) -#define _le32toh(v) (v) - -#endif /* BYTE_ORDER */ - -/* * The below round up/down macros are to be used with a constant * as argument (sizeof(...) for example), for the compiler to * optimize the whole thing. */ #define _U_(a,m) (a)<=(1< -#else #include "sym_glue.h" -#endif +#include "sym_nvram.h" /* * Some poor and bogus sync table that refers to Tekram NVRAM layout. @@ -246,8 +243,8 @@ } } #else -static void sym_display_Symbios_nvram(struct sym_device *np, Symbios_nvram *nvram) { } -static void sym_display_Tekram_nvram(struct sym_device *np, Tekram_nvram *nvram) { } +static void sym_display_Symbios_nvram(struct sym_device *np, Symbios_nvram *nvram) { (void)np; (void)nvram; } +static void sym_display_Tekram_nvram(struct sym_device *np, Tekram_nvram *nvram) { (void)np; (void)nvram; } #endif /* SYM_CONF_DEBUG_NVRAM */ @@ -382,6 +379,61 @@ S24C16_write_ack(np, ack_data, gpreg, gpcntl); } + +#if SYM_CONF_NVRAM_WRITE_SUPPORT +/* + * Write 'len' bytes starting at 'offset'. + */ +static int sym_write_S24C16_nvram(struct sym_device *np, int offset, + u_char *data, int len) +{ + u_char gpcntl, gpreg; + u_char old_gpcntl, old_gpreg; + u_char ack_data; + int x; + + /* save current state of GPCNTL and GPREG */ + old_gpreg = INB (nc_gpreg); + old_gpcntl = INB (nc_gpcntl); + gpcntl = old_gpcntl & 0x1c; + + /* set up GPREG & GPCNTL to set GPIO0 and GPIO1 in to known state */ + OUTB (nc_gpreg, old_gpreg); + OUTB (nc_gpcntl, gpcntl); + + /* this is to set NVRAM into a known state with GPIO0/1 both low */ + gpreg = old_gpreg; + S24C16_set_bit(np, 0, &gpreg, CLR_CLK); + S24C16_set_bit(np, 0, &gpreg, CLR_BIT); + + /* now set NVRAM inactive with GPIO0/1 both high */ + S24C16_stop(np, &gpreg); + + /* NVRAM has to be written in segments of 16 bytes */ + for (x = 0; x < len ; x += 16) { + do { + S24C16_start(np, &gpreg); + S24C16_write_byte(np, &ack_data, + 0xa0 | (((offset+x) >> 7) & 0x0e), + &gpreg, &gpcntl); + } while (ack_data & 0x01); + + S24C16_write_byte(np, &ack_data, (offset+x) & 0xff, + &gpreg, &gpcntl); + + for (y = 0; y < 16; y++) + S24C16_write_byte(np, &ack_data, data[x+y], + &gpreg, &gpcntl); + S24C16_stop(np, &gpreg); + } + + /* return GPIO0/1 to original states after having accessed NVRAM */ + OUTB (nc_gpcntl, old_gpcntl); + OUTB (nc_gpreg, old_gpreg); + + return 0; +} +#endif /* SYM_CONF_NVRAM_WRITE_SUPPORT */ /* * Read 'len' bytes starting at 'offset'. diff -Nru a/drivers/scsi/sym53c8xx_2/sym_nvram.h b/drivers/scsi/sym53c8xx_2/sym_nvram.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/drivers/scsi/sym53c8xx_2/sym_nvram.h Sun Mar 14 14:20:09 2004 @@ -0,0 +1,216 @@ +/* + * Device driver for the SYMBIOS/LSILOGIC 53C8XX and 53C1010 family + * of PCI-SCSI IO processors. + * + * Copyright (C) 1999-2001 Gerard Roudier + * + * This driver is derived from the Linux sym53c8xx driver. + * Copyright (C) 1998-2000 Gerard Roudier + * + * The sym53c8xx driver is derived from the ncr53c8xx driver that had been + * a port of the FreeBSD ncr driver to Linux-1.2.13. + * + * The original ncr driver has been written for 386bsd and FreeBSD by + * Wolfgang Stanglmeier + * Stefan Esser + * Copyright (C) 1994 Wolfgang Stanglmeier + * + * Other major contributions: + * + * NVRAM detection and reading. + * Copyright (C) 1997 Richard Waltham + * + *----------------------------------------------------------------------------- + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * Where this Software is combined with software released under the terms of + * the GNU Public License ("GPL") and the terms of the GPL would require the + * combined work to also be released under the terms of the GPL, the terms + * and conditions of this License will apply in addition to those of the + * GPL with the exception of any terms or conditions of this License that + * conflict with, or are expressly prohibited by, the GPL. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef SYM_NVRAM_H +#define SYM_NVRAM_H + +#include "sym_conf.h" + +/* + * Symbios NVRAM data format + */ +#define SYMBIOS_NVRAM_SIZE 368 +#define SYMBIOS_NVRAM_ADDRESS 0x100 + +struct Symbios_nvram { +/* Header 6 bytes */ + u_short type; /* 0x0000 */ + u_short byte_count; /* excluding header/trailer */ + u_short checksum; + +/* Controller set up 20 bytes */ + u_char v_major; /* 0x00 */ + u_char v_minor; /* 0x30 */ + u32 boot_crc; + u_short flags; +#define SYMBIOS_SCAM_ENABLE (1) +#define SYMBIOS_PARITY_ENABLE (1<<1) +#define SYMBIOS_VERBOSE_MSGS (1<<2) +#define SYMBIOS_CHS_MAPPING (1<<3) +#define SYMBIOS_NO_NVRAM (1<<3) /* ??? */ + u_short flags1; +#define SYMBIOS_SCAN_HI_LO (1) + u_short term_state; +#define SYMBIOS_TERM_CANT_PROGRAM (0) +#define SYMBIOS_TERM_ENABLED (1) +#define SYMBIOS_TERM_DISABLED (2) + u_short rmvbl_flags; +#define SYMBIOS_RMVBL_NO_SUPPORT (0) +#define SYMBIOS_RMVBL_BOOT_DEVICE (1) +#define SYMBIOS_RMVBL_MEDIA_INSTALLED (2) + u_char host_id; + u_char num_hba; /* 0x04 */ + u_char num_devices; /* 0x10 */ + u_char max_scam_devices; /* 0x04 */ + u_char num_valid_scam_devices; /* 0x00 */ + u_char flags2; +#define SYMBIOS_AVOID_BUS_RESET (1<<2) + +/* Boot order 14 bytes * 4 */ + struct Symbios_host{ + u_short type; /* 4:8xx / 0:nok */ + u_short device_id; /* PCI device id */ + u_short vendor_id; /* PCI vendor id */ + u_char bus_nr; /* PCI bus number */ + u_char device_fn; /* PCI device/function number << 3*/ + u_short word8; + u_short flags; +#define SYMBIOS_INIT_SCAN_AT_BOOT (1) + u_short io_port; /* PCI io_port address */ + } host[4]; + +/* Targets 8 bytes * 16 */ + struct Symbios_target { + u_char flags; +#define SYMBIOS_DISCONNECT_ENABLE (1) +#define SYMBIOS_SCAN_AT_BOOT_TIME (1<<1) +#define SYMBIOS_SCAN_LUNS (1<<2) +#define SYMBIOS_QUEUE_TAGS_ENABLED (1<<3) + u_char rsvd; + u_char bus_width; /* 0x08/0x10 */ + u_char sync_offset; + u_short sync_period; /* 4*period factor */ + u_short timeout; + } target[16]; +/* Scam table 8 bytes * 4 */ + struct Symbios_scam { + u_short id; + u_short method; +#define SYMBIOS_SCAM_DEFAULT_METHOD (0) +#define SYMBIOS_SCAM_DONT_ASSIGN (1) +#define SYMBIOS_SCAM_SET_SPECIFIC_ID (2) +#define SYMBIOS_SCAM_USE_ORDER_GIVEN (3) + u_short status; +#define SYMBIOS_SCAM_UNKNOWN (0) +#define SYMBIOS_SCAM_DEVICE_NOT_FOUND (1) +#define SYMBIOS_SCAM_ID_NOT_SET (2) +#define SYMBIOS_SCAM_ID_VALID (3) + u_char target_id; + u_char rsvd; + } scam[4]; + + u_char spare_devices[15*8]; + u_char trailer[6]; /* 0xfe 0xfe 0x00 0x00 0x00 0x00 */ +}; +typedef struct Symbios_nvram Symbios_nvram; +typedef struct Symbios_host Symbios_host; +typedef struct Symbios_target Symbios_target; +typedef struct Symbios_scam Symbios_scam; + +/* + * Tekram NvRAM data format. + */ +#define TEKRAM_NVRAM_SIZE 64 +#define TEKRAM_93C46_NVRAM_ADDRESS 0 +#define TEKRAM_24C16_NVRAM_ADDRESS 0x40 + +struct Tekram_nvram { + struct Tekram_target { + u_char flags; +#define TEKRAM_PARITY_CHECK (1) +#define TEKRAM_SYNC_NEGO (1<<1) +#define TEKRAM_DISCONNECT_ENABLE (1<<2) +#define TEKRAM_START_CMD (1<<3) +#define TEKRAM_TAGGED_COMMANDS (1<<4) +#define TEKRAM_WIDE_NEGO (1<<5) + u_char sync_index; + u_short word2; + } target[16]; + u_char host_id; + u_char flags; +#define TEKRAM_MORE_THAN_2_DRIVES (1) +#define TEKRAM_DRIVES_SUP_1GB (1<<1) +#define TEKRAM_RESET_ON_POWER_ON (1<<2) +#define TEKRAM_ACTIVE_NEGATION (1<<3) +#define TEKRAM_IMMEDIATE_SEEK (1<<4) +#define TEKRAM_SCAN_LUNS (1<<5) +#define TEKRAM_REMOVABLE_FLAGS (3<<6) /* 0: disable; */ + /* 1: boot device; 2:all */ + u_char boot_delay_index; + u_char max_tags_index; + u_short flags1; +#define TEKRAM_F2_F6_ENABLED (1) + u_short spare[29]; +}; +typedef struct Tekram_nvram Tekram_nvram; +typedef struct Tekram_target Tekram_target; + +/* + * Union of supported NVRAM formats. + */ +struct sym_nvram { + int type; +#define SYM_SYMBIOS_NVRAM (1) +#define SYM_TEKRAM_NVRAM (2) +#if SYM_CONF_NVRAM_SUPPORT + union { + Symbios_nvram Symbios; + Tekram_nvram Tekram; + } data; +#endif +}; + +#if SYM_CONF_NVRAM_SUPPORT +void sym_nvram_setup_host (struct sym_hcb *np, struct sym_nvram *nvram); +void sym_nvram_setup_target (struct sym_hcb *np, int target, struct sym_nvram *nvp); +int sym_read_nvram (struct sym_device *np, struct sym_nvram *nvp); +#else +static inline void sym_nvram_setup_host(struct sym_hcb *np, struct sym_nvram *nvram) { } +static inline void sym_nvram_setup_target(struct sym_hcb *np, struct sym_nvram *nvram) { } +static inline int sym_read_nvram(struct sym_device *np, struct sym_nvram *nvp) +{ + nvp->type = 0; + return 0; +} +#endif + +#endif /* SYM_NVRAM_H */ diff -Nru a/drivers/scsi/sym53c8xx_comm.h b/drivers/scsi/sym53c8xx_comm.h --- a/drivers/scsi/sym53c8xx_comm.h Sun Mar 14 14:20:07 2004 +++ b/drivers/scsi/sym53c8xx_comm.h Sun Mar 14 14:20:07 2004 @@ -703,7 +703,8 @@ #define __unmap_scsi_data(dev, cmd) do {; } while (0) #define __map_scsi_single_data(dev, cmd) (__vtobus(dev,(cmd)->request_buffer)) #define __map_scsi_sg_data(dev, cmd) ((cmd)->use_sg) -#define __sync_scsi_data(dev, cmd) do {; } while (0) +#define __sync_scsi_data_for_cpu(dev, cmd) do {; } while (0) +#define __sync_scsi_data_for_device(dev, cmd) do {; } while (0) #define scsi_sg_dma_address(sc) vtobus((sc)->address) #define scsi_sg_dma_len(sc) ((sc)->length) @@ -767,18 +768,34 @@ return use_sg; } -static void __sync_scsi_data(struct device *dev, Scsi_Cmnd *cmd) +static void __sync_scsi_data_for_cpu(struct device *dev, Scsi_Cmnd *cmd) { enum dma_data_direction dma_dir = (enum dma_data_direction)scsi_to_pci_dma_dir(cmd->sc_data_direction); switch(cmd->__data_mapped) { case 2: - dma_sync_sg(dev, cmd->buffer, cmd->use_sg, dma_dir); + dma_sync_sg_for_cpu(dev, cmd->buffer, cmd->use_sg, dma_dir); break; case 1: - dma_sync_single(dev, cmd->__data_mapping, - cmd->request_bufflen, dma_dir); + dma_sync_single_for_cpu(dev, cmd->__data_mapping, + cmd->request_bufflen, dma_dir); + break; + } +} + +static void __sync_scsi_data_for_device(struct device *dev, Scsi_Cmnd *cmd) +{ + enum dma_data_direction dma_dir = + (enum dma_data_direction)scsi_to_pci_dma_dir(cmd->sc_data_direction); + + switch(cmd->__data_mapped) { + case 2: + dma_sync_sg_for_device(dev, cmd->buffer, cmd->use_sg, dma_dir); + break; + case 1: + dma_sync_single_for_device(dev, cmd->__data_mapping, + cmd->request_bufflen, dma_dir); break; } } @@ -791,7 +808,8 @@ #define unmap_scsi_data(np, cmd) __unmap_scsi_data(np->dev, cmd) #define map_scsi_single_data(np, cmd) __map_scsi_single_data(np->dev, cmd) #define map_scsi_sg_data(np, cmd) __map_scsi_sg_data(np->dev, cmd) -#define sync_scsi_data(np, cmd) __sync_scsi_data(np->dev, cmd) +#define sync_scsi_data_for_cpu(np, cmd) __sync_scsi_data_for_cpu(np->dev, cmd) +#define sync_scsi_data_for_device(np, cmd) __sync_scsi_data_for_device(np->dev, cmd) /*========================================================== ** diff -Nru a/drivers/scsi/u14-34f.c b/drivers/scsi/u14-34f.c --- a/drivers/scsi/u14-34f.c Sun Mar 14 14:20:06 2004 +++ b/drivers/scsi/u14-34f.c Sun Mar 14 14:20:06 2004 @@ -1184,17 +1184,17 @@ pci_dir = scsi_to_pci_dma_dir(SCpnt->sc_data_direction); if (DEV2H(cpp->sense_addr)) - pci_dma_sync_single(HD(j)->pdev, DEV2H(cpp->sense_addr), + pci_dma_sync_single_for_cpu(HD(j)->pdev, DEV2H(cpp->sense_addr), DEV2H(cpp->sense_len), PCI_DMA_FROMDEVICE); if (SCpnt->use_sg) - pci_dma_sync_sg(HD(j)->pdev, SCpnt->request_buffer, + pci_dma_sync_sg_for_cpu(HD(j)->pdev, SCpnt->request_buffer, SCpnt->use_sg, pci_dir); if (!DEV2H(cpp->data_len)) pci_dir = PCI_DMA_BIDIRECTIONAL; if (DEV2H(cpp->data_address)) - pci_dma_sync_single(HD(j)->pdev, DEV2H(cpp->data_address), + pci_dma_sync_single_for_cpu(HD(j)->pdev, DEV2H(cpp->data_address), DEV2H(cpp->data_len), pci_dir); } diff -Nru a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c --- a/drivers/usb/core/usb.c Sun Mar 14 14:20:07 2004 +++ b/drivers/usb/core/usb.c Sun Mar 14 14:20:07 2004 @@ -1297,6 +1297,13 @@ return urb; } +/* XXX DISABLED, no users currently. If you wish to re-enable this + * XXX please determine whether the sync is to transfer ownership of + * XXX the buffer from device to cpu or vice verse, and thusly use the + * XXX appropriate _for_{cpu,device}() method. -DaveM + */ +#if 0 + /** * usb_buffer_dmasync - synchronize DMA and CPU view of buffer(s) * @urb: urb whose transfer_buffer/setup_packet will be synchronized @@ -1325,6 +1332,7 @@ DMA_TO_DEVICE); } } +#endif /** * usb_buffer_unmap - free DMA mapping(s) for an urb @@ -1403,6 +1411,13 @@ usb_pipein (pipe) ? DMA_FROM_DEVICE : DMA_TO_DEVICE); } +/* XXX DISABLED, no users currently. If you wish to re-enable this + * XXX please determine whether the sync is to transfer ownership of + * XXX the buffer from device to cpu or vice verse, and thusly use the + * XXX appropriate _for_{cpu,device}() method. -DaveM + */ +#if 0 + /** * usb_buffer_dmasync_sg - synchronize DMA and CPU view of scatterlist buffer(s) * @dev: device to which the scatterlist will be mapped @@ -1428,6 +1443,7 @@ dma_sync_sg (controller, sg, n_hw_ents, usb_pipein (pipe) ? DMA_FROM_DEVICE : DMA_TO_DEVICE); } +#endif /** * usb_buffer_unmap_sg - free DMA mapping(s) for a scatterlist @@ -1595,11 +1611,15 @@ EXPORT_SYMBOL (usb_buffer_free); EXPORT_SYMBOL (usb_buffer_map); +#if 0 EXPORT_SYMBOL (usb_buffer_dmasync); +#endif EXPORT_SYMBOL (usb_buffer_unmap); EXPORT_SYMBOL (usb_buffer_map_sg); +#if 0 EXPORT_SYMBOL (usb_buffer_dmasync_sg); +#endif EXPORT_SYMBOL (usb_buffer_unmap_sg); MODULE_LICENSE("GPL"); diff -Nru a/drivers/video/aty/radeon_monitor.c b/drivers/video/aty/radeon_monitor.c --- a/drivers/video/aty/radeon_monitor.c Sun Mar 14 14:20:05 2004 +++ b/drivers/video/aty/radeon_monitor.c Sun Mar 14 14:20:05 2004 @@ -757,7 +757,7 @@ && rinfo->mon1_EDID) { struct fb_var_screeninfo var; RTRACE("Parsing EDID data for panel info\n"); - if (parse_edid(rinfo->mon1_EDID, &var) == 0) { + if (fb_parse_edid(rinfo->mon1_EDID, &var) == 0) { if (var.xres >= rinfo->panel_info.xres && var.yres >= rinfo->panel_info.yres) radeon_var_to_panel_info(rinfo, &var); diff -Nru a/drivers/video/console/fbcon.c b/drivers/video/console/fbcon.c --- a/drivers/video/console/fbcon.c Sun Mar 14 14:20:07 2004 +++ b/drivers/video/console/fbcon.c Sun Mar 14 14:20:07 2004 @@ -2345,6 +2345,7 @@ { if (!num_registered_fb) return -ENODEV; + take_over_console(&fb_con, first_fb_vc, last_fb_vc, fbcon_is_default); acquire_console_sem(); if (!fbcon_event_notifier_registered) { @@ -2352,10 +2353,11 @@ fbcon_event_notifier_registered = 1; } release_console_sem(); - return 0; } +#ifdef MODULE + void __exit fb_console_exit(void) { acquire_console_sem(); @@ -2369,6 +2371,8 @@ module_init(fb_console_init); module_exit(fb_console_exit); + +#endif /* * Visible symbols for modules diff -Nru a/drivers/video/dnfb.c b/drivers/video/dnfb.c --- a/drivers/video/dnfb.c Sun Mar 14 14:20:08 2004 +++ b/drivers/video/dnfb.c Sun Mar 14 14:20:08 2004 @@ -103,8 +103,6 @@ #define SWAP(A) ((A>>8) | ((A&0xff) <<8)) -static struct fb_info fb_info; - /* frame buffer operations */ static int dnfb_blank(int blank, struct fb_info *info); @@ -119,7 +117,7 @@ .fb_cursor = soft_cursor, }; -struct fb_var_screeninfo dnfb_var __initdata = { +struct fb_var_screeninfo dnfb_var __devinitdata = { .xres 1280, .yres 1024, .xres_virtual 2048, @@ -130,7 +128,7 @@ .vmode FB_VMODE_NONINTERLACED, }; -static struct fb_fix_screeninfo dnfb_fix __initdata = { +static struct fb_fix_screeninfo dnfb_fix __devinitdata = { .id "Apollo Mono", .smem_start (FRAME_BUFFER_START + IO_BASE), .smem_len FRAME_BUFFER_LEN, @@ -148,7 +146,7 @@ return 0; } -static +static void dnfb_copyarea(struct fb_info *info, const struct fb_copyarea *area) { @@ -224,21 +222,38 @@ out_8(AP_CONTROL_0, NORMAL_MODE); } +/* + * Initialization + */ -unsigned long __init dnfb_init(unsigned long mem_start) +static int __devinit dnfb_probe(struct device *device) { - int err; + struct platform_device *dev = to_platform_device(device); + struct fb_info *info; + int err = 0; + + info = framebuffer_alloc(0, &dev->dev); + if (!info) + return -ENOMEM; + + info->fbops = &dn_fb_ops; + info->fix = dnfb_fix; + info->var = dnfb_var; + info->screen_base = (u_char *) info->fix.smem_start; + + err = fb_alloc_cmap(&info->cmap, 2, 0); + if (err < 0) { + framebuffer_release(info); + return err; + } - fb_info.fbops = &dn_fb_ops; - fb_info.fix = dnfb_fix; - fb_info.var = dnfb_var; - fb_info.screen_base = (u_char *) fb_info.fix.smem_start; - - fb_alloc_cmap(&fb_info.cmap, 2, 0); - - err = register_framebuffer(&fb_info); - if (err < 0) - panic("unable to register apollo frame buffer\n"); + err = register_framebuffer(info); + if (err < 0) { + fb_dealloc_cmap(&info->cmap); + framebuffer_release(info); + return err; + } + dev_set_drvdata(&dev->dev, info); /* now we have registered we can safely setup the hardware */ out_8(AP_CONTROL_3A, RESET_CREG); @@ -249,7 +264,31 @@ out_be16(AP_ROP_1, SWAP(0x3)); printk("apollo frame buffer alive and kicking !\n"); - return mem_start; + return err; +} + +static struct device_driver dnfb_driver = { + .name = "dnfb", + .bus = &platform_bus_type, + .probe = dnfb_probe, +}; + +static struct platform_device dnfb_device = { + .name = "dnfb", +}; + +int __init dnfb_init(void) +{ + int ret; + + ret = driver_register(&dnfb_driver); + + if (!ret) { + ret = platform_device_register(&dnfb_device); + if (ret) + driver_unregister(&dnfb_driver); + } + return ret; } MODULE_LICENSE("GPL"); diff -Nru a/drivers/video/fbmon.c b/drivers/video/fbmon.c --- a/drivers/video/fbmon.c Sun Mar 14 14:20:08 2004 +++ b/drivers/video/fbmon.c Sun Mar 14 14:20:08 2004 @@ -41,6 +41,15 @@ * EDID parser */ +#undef DEBUG /* define this for verbose EDID parsing output */ + +#ifdef DEBUG +#define DPRINTK(fmt, args...) printk(fmt,## args) +#else +#define DPRINTK(fmt, args...) +#endif + + const unsigned char edid_v1_header[] = { 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00 }; @@ -84,203 +93,93 @@ return 1; } -static void parse_vendor_block(unsigned char *block) +static void parse_vendor_block(unsigned char *block, struct fb_monspecs *specs) { - unsigned char c[4]; - - c[0] = ((block[0] & 0x7c) >> 2) + '@'; - c[1] = ((block[0] & 0x03) << 3) + ((block[1] & 0xe0) >> 5) + '@'; - c[2] = (block[1] & 0x1f) + '@'; - c[3] = 0; - printk(" Manufacturer: %s ", c); - printk("Model: %x ", block[2] + (block[3] << 8)); - printk("Serial#: %u\n", block[4] + (block[5] << 8) + - (block[6] << 16) + (block[7] << 24)); - printk(" Year: %u Week %u\n", block[9] + 1990, block[8]); -} - -static void parse_dpms_capabilities(unsigned char flags) -{ - printk(" DPMS: Active %s, Suspend %s, Standby %s\n", + specs->manufacturer[0] = ((block[0] & 0x7c) >> 2) + '@'; + specs->manufacturer[1] = ((block[0] & 0x03) << 3) + + ((block[1] & 0xe0) >> 5) + '@'; + specs->manufacturer[2] = (block[1] & 0x1f) + '@'; + specs->manufacturer[3] = 0; + specs->model = block[2] + (block[3] << 8); + specs->serial = block[4] + (block[5] << 8) + + (block[6] << 16) + (block[7] << 24); + specs->year = block[9] + 1990; + specs->week = block[8]; + DPRINTK(" Manufacturer: %s\n", specs->manufacturer); + DPRINTK(" Model: %x\n", specs->model); + DPRINTK(" Serial#: %u\n", specs->serial); + DPRINTK(" Year: %u Week %u\n", specs->year, specs->week); +} + +static void get_dpms_capabilities(unsigned char flags, + struct fb_monspecs *specs) +{ + specs->dpms = 0; + if (flags & DPMS_ACTIVE_OFF) + specs->dpms |= FB_DPMS_ACTIVE_OFF; + if (flags & DPMS_SUSPEND) + specs->dpms |= FB_DPMS_SUSPEND; + if (flags & DPMS_STANDBY) + specs->dpms |= FB_DPMS_STANDBY; + DPRINTK(" DPMS: Active %s, Suspend %s, Standby %s\n", (flags & DPMS_ACTIVE_OFF) ? "yes" : "no", (flags & DPMS_SUSPEND) ? "yes" : "no", (flags & DPMS_STANDBY) ? "yes" : "no"); } -static void print_chroma(unsigned char *block) +static void get_chroma(unsigned char *block, struct fb_monspecs *specs) { int tmp; + DPRINTK(" Chroma\n"); /* Chromaticity data */ - printk(" Chromaticity: "); tmp = ((block[5] & (3 << 6)) >> 6) | (block[0x7] << 2); tmp *= 1000; tmp += 512; - printk("RedX: 0.%03d ", tmp/1024); + specs->chroma.redx = tmp/1024; + DPRINTK(" RedX: 0.%03d ", specs->chroma.redx); tmp = ((block[5] & (3 << 4)) >> 4) | (block[0x8] << 2); tmp *= 1000; tmp += 512; - printk("RedY: 0.%03d\n", tmp/1024); + specs->chroma.redy = tmp/1024; + DPRINTK("RedY: 0.%03d\n", specs->chroma.redy); tmp = ((block[5] & (3 << 2)) >> 2) | (block[0x9] << 2); tmp *= 1000; tmp += 512; - printk(" GreenX: 0.%03d ", tmp/1024); + specs->chroma.greenx = tmp/1024; + DPRINTK(" GreenX: 0.%03d ", specs->chroma.greenx); tmp = (block[5] & 3) | (block[0xa] << 2); tmp *= 1000; tmp += 512; - printk("GreenY: 0.%03d\n", tmp/1024); + specs->chroma.greeny = tmp/1024; + DPRINTK("GreenY: 0.%03d\n", specs->chroma.greeny); tmp = ((block[6] & (3 << 6)) >> 6) | (block[0xb] << 2); tmp *= 1000; tmp += 512; - printk(" BlueX: 0.%03d ", tmp/1024); + specs->chroma.bluex = tmp/1024; + DPRINTK(" BlueX: 0.%03d ", specs->chroma.bluex); tmp = ((block[6] & (3 << 4)) >> 4) | (block[0xc] << 2); tmp *= 1000; tmp += 512; - printk("BlueY: 0.%03d\n", tmp/1024); + specs->chroma.bluey = tmp/1024; + DPRINTK("BlueY: 0.%03d\n", specs->chroma.bluey); tmp = ((block[6] & (3 << 2)) >> 2) | (block[0xd] << 2); tmp *= 1000; tmp += 512; - printk(" WhiteX: 0.%03d ", tmp/1024); + specs->chroma.whitex = tmp/1024; + DPRINTK(" WhiteX: 0.%03d ", specs->chroma.whitex); tmp = (block[6] & 3) | (block[0xe] << 2); tmp *= 1000; tmp += 512; - printk("WhiteY: 0.%03d\n", tmp/1024); -} - -static void parse_display_block(unsigned char *block) -{ - unsigned char c; - - c = (block[0] & 0x80) >> 7; - if (c) - printk(" Digital Display Input"); - else { - printk(" Analog Display Input: Input Voltage - "); - switch ((block[0] & 0x60) >> 5) { - case 0: - printk("0.700V/0.300V"); - break; - case 1: - printk("0.714V/0.286V"); - break; - case 2: - printk("1.000V/0.400V"); - break; - case 3: - printk("0.700V/0.000V"); - break; - default: - printk("unknown"); - } - printk("\n"); - } - c = (block[0] & 0x10) >> 4; - if (c) - printk(" Configurable signal level\n"); - printk(" Sync: "); - c = block[0] & 0x0f; - if (c & 0x10) - printk("Blank to Blank "); - if (c & 0x08) - printk("Separate "); - if (c & 0x04) - printk("Composite "); - if (c & 0x02) - printk("Sync on Green "); - if (c & 0x01) - printk("Serration on "); - printk("\n"); - - printk(" Max H-size in cm: "); - c = block[1]; - if (c) - printk("%d\n", c); - else - printk("variable\n"); - - printk(" Max V-size in cm: "); - c = block[2]; - if (c) - printk("%d\n", c); - else - printk("variable\n"); - - c = block[3]; - printk(" Gamma: "); - printk("%d.%d\n", (c + 100)/100, (c+100) % 100); - - parse_dpms_capabilities(block[4]); - - switch ((block[4] & 0x18) >> 3) { - case 0: - printk(" Monochrome/Grayscale\n"); - break; - case 1: - printk(" RGB Color Display\n"); - break; - case 2: - printk(" Non-RGB Multicolor Display\n"); - break; - default: - printk(" Unknown\n"); - break; - } - - print_chroma(block); - - c = block[4] & 0x7; - if (c & 0x04) - printk(" Default color format is primary\n"); - if (c & 0x02) - printk(" First DETAILED Timing is preferred\n"); - if (c & 0x01) - printk(" Display is GTF capable\n"); -} - -static void parse_std_md_block(unsigned char *block) -{ - unsigned char c; - - c = block[0]; - if (c&0x80) printk(" 720x400@70Hz\n"); - if (c&0x40) printk(" 720x400@88Hz\n"); - if (c&0x20) printk(" 640x480@60Hz\n"); - if (c&0x10) printk(" 640x480@67Hz\n"); - if (c&0x08) printk(" 640x480@72Hz\n"); - if (c&0x04) printk(" 640x480@75Hz\n"); - if (c&0x02) printk(" 800x600@56Hz\n"); - if (c&0x01) printk(" 800x600@60Hz\n"); - - c = block[1]; - if (c&0x80) printk(" 800x600@72Hz\n"); - if (c&0x40) printk(" 800x600@75Hz\n"); - if (c&0x20) printk(" 832x624@75Hz\n"); - if (c&0x10) printk(" 1024x768@87Hz (interlaced)\n"); - if (c&0x08) printk(" 1024x768@60Hz\n"); - if (c&0x04) printk(" 1024x768@70Hz\n"); - if (c&0x02) printk(" 1024x768@75Hz\n"); - if (c&0x01) printk(" 1280x1024@75Hz\n"); - - c = block[2]; - if (c&0x80) printk(" 1152x870@75Hz\n"); - printk(" Manufacturer's mask: %x\n",c&0x7F); -} - - -static int edid_is_timing_block(unsigned char *block) -{ - if ((block[0] != 0x00) || (block[1] != 0x00) || - (block[2] != 0x00) || (block[4] != 0x00)) - return 1; - else - return 0; + specs->chroma.whitey = tmp/1024; + DPRINTK("WhiteY: 0.%03d\n", specs->chroma.whitey); } static int edid_is_serial_block(unsigned char *block) @@ -323,154 +222,6 @@ return 0; } -static int edid_is_color_block(unsigned char *block) -{ - if ((block[0] == 0x00) && (block[1] == 0x00) && - (block[2] == 0x00) && (block[3] == 0xfb) && - (block[4] == 0x00)) - return 1; - else - return 0; -} - -static int edid_is_std_timings_block(unsigned char *block) -{ - if ((block[0] == 0x00) && (block[1] == 0x00) && - (block[2] == 0x00) && (block[3] == 0xfa) && - (block[4] == 0x00)) - return 1; - else - return 0; -} - -static void parse_serial_block(unsigned char *block) -{ - unsigned char c[13]; - - copy_string(block, c); - printk(" Serial No : %s\n", c); -} - -static void parse_ascii_block(unsigned char *block) -{ - unsigned char c[13]; - - copy_string(block, c); - printk(" %s\n", c); -} - -static void parse_limits_block(unsigned char *block) -{ - printk(" HorizSync : %d-%d KHz\n", H_MIN_RATE, H_MAX_RATE); - printk(" VertRefresh : %d-%d Hz\n", V_MIN_RATE, V_MAX_RATE); - if (MAX_PIXEL_CLOCK != 10*0xff) - printk(" Max Pixelclock: %d MHz\n", (int) MAX_PIXEL_CLOCK); -} - -static void parse_monitor_block(unsigned char *block) -{ - unsigned char c[13]; - - copy_string(block, c); - printk(" Monitor Name : %s\n", c); -} - -static void parse_color_block(unsigned char *block) -{ - printk(" Color Point : unimplemented\n"); -} - -static void parse_std_timing_block(unsigned char *block) -{ - int xres, yres = 0, refresh, ratio, err = 1; - - xres = (block[0] + 31) * 8; - if (xres <= 256) - return; - - ratio = (block[1] & 0xc0) >> 6; - switch (ratio) { - case 0: - yres = xres; - break; - case 1: - yres = (xres * 3)/4; - break; - case 2: - yres = (xres * 4)/5; - break; - case 3: - yres = (xres * 9)/16; - break; - } - refresh = (block[1] & 0x3f) + 60; - printk(" %dx%d@%dHz\n", xres, yres, refresh); - err = 0; -} - -static void parse_dst_timing_block(unsigned char *block) -{ - int i; - - block += 5; - for (i = 0; i < 5; i++, block += STD_TIMING_DESCRIPTION_SIZE) - parse_std_timing_block(block); -} - -static void parse_detailed_timing_block(unsigned char *block) -{ - printk(" %d MHz ", PIXEL_CLOCK/1000000); - printk("%d %d %d %d ", H_ACTIVE, H_ACTIVE + H_SYNC_OFFSET, - H_ACTIVE + H_SYNC_OFFSET + H_SYNC_WIDTH, H_ACTIVE + H_BLANKING); - printk("%d %d %d %d ", V_ACTIVE, V_ACTIVE + V_SYNC_OFFSET, - V_ACTIVE + V_SYNC_OFFSET + V_SYNC_WIDTH, V_ACTIVE + V_BLANKING); - printk("%sHSync %sVSync\n\n", (HSYNC_POSITIVE) ? "+" : "-", - (VSYNC_POSITIVE) ? "+" : "-"); -} - -int parse_edid(unsigned char *edid, struct fb_var_screeninfo *var) -{ - int i; - unsigned char *block; - - if (edid == NULL || var == NULL) - return 1; - - if (!(edid_checksum(edid))) - return 1; - - if (!(edid_check_header(edid))) - return 1; - - block = edid + DETAILED_TIMING_DESCRIPTIONS_START; - - for (i = 0; i < 4; i++, block += DETAILED_TIMING_DESCRIPTION_SIZE) { - if (edid_is_timing_block(block)) { - var->xres = var->xres_virtual = H_ACTIVE; - var->yres = var->yres_virtual = V_ACTIVE; - var->height = var->width = -1; - var->right_margin = H_SYNC_OFFSET; - var->left_margin = (H_ACTIVE + H_BLANKING) - - (H_ACTIVE + H_SYNC_OFFSET + H_SYNC_WIDTH); - var->upper_margin = V_BLANKING - V_SYNC_OFFSET - - V_SYNC_WIDTH; - var->lower_margin = V_SYNC_OFFSET; - var->hsync_len = H_SYNC_WIDTH; - var->vsync_len = V_SYNC_WIDTH; - var->pixclock = PIXEL_CLOCK; - var->pixclock /= 1000; - var->pixclock = KHZ2PICOS(var->pixclock); - - if (HSYNC_POSITIVE) - var->sync |= FB_SYNC_HOR_HIGH_ACT; - if (VSYNC_POSITIVE) - var->sync |= FB_SYNC_VERT_HIGH_ACT; - return 0; - } - } - return 1; -} - static void calc_mode_timings(int xres, int yres, int refresh, struct fb_videomode *mode) { struct fb_var_screeninfo var; @@ -500,45 +251,82 @@ unsigned char c; c = block[0]; - if (c&0x80) - calc_mode_timings(720, 400, 70, &mode[num++]); - if (c&0x40) - calc_mode_timings(720, 400, 88, &mode[num++]); - if (c&0x20) + if (c&0x80) { + calc_mode_timings(720, 400, 70, &mode[num]); + mode[num++].flag = FB_MODE_IS_CALCULATED; + DPRINTK(" 720x400@70Hz\n"); + } + if (c&0x40) { + calc_mode_timings(720, 400, 88, &mode[num]); + mode[num++].flag = FB_MODE_IS_CALCULATED; + DPRINTK(" 720x400@88Hz\n"); + } + if (c&0x20) { mode[num++] = vesa_modes[3]; - if (c&0x10) - calc_mode_timings(640, 480, 67, &mode[num++]); - if (c&0x08) + DPRINTK(" 640x480@60Hz\n"); + } + if (c&0x10) { + calc_mode_timings(640, 480, 67, &mode[num]); + mode[num++].flag = FB_MODE_IS_CALCULATED; + DPRINTK(" 640x480@67Hz\n"); + } + if (c&0x08) { mode[num++] = vesa_modes[4]; - if (c&0x04) + DPRINTK(" 640x480@72Hz\n"); + } + if (c&0x04) { mode[num++] = vesa_modes[5]; - if (c&0x02) + DPRINTK(" 640x480@75Hz\n"); + } + if (c&0x02) { mode[num++] = vesa_modes[7]; - if (c&0x01) + DPRINTK(" 800x600@56Hz\n"); + } + if (c&0x01) { mode[num++] = vesa_modes[8]; + DPRINTK(" 800x600@60Hz\n"); + } c = block[1]; - if (c&0x80) + if (c&0x80) { mode[num++] = vesa_modes[9]; - if (c&0x40) + DPRINTK(" 800x600@72Hz\n"); + } + if (c&0x40) { mode[num++] = vesa_modes[10]; - if (c&0x20) - calc_mode_timings(832, 624, 75, &mode[num++]); - if (c&0x10) + DPRINTK(" 800x600@75Hz\n"); + } + if (c&0x20) { + calc_mode_timings(832, 624, 75, &mode[num]); + mode[num++].flag = FB_MODE_IS_CALCULATED; + DPRINTK(" 832x624@75Hz\n"); + } + if (c&0x10) { mode[num++] = vesa_modes[12]; - if (c&0x08) + DPRINTK(" 1024x768@87Hz Interlaced\n"); + } + if (c&0x08) { mode[num++] = vesa_modes[13]; - if (c&0x04) + DPRINTK(" 1024x768@60Hz\n"); + } + if (c&0x04) { mode[num++] = vesa_modes[14]; - if (c&0x02) + DPRINTK(" 1024x768@70Hz\n"); + } + if (c&0x02) { mode[num++] = vesa_modes[15]; - if (c&0x01) + DPRINTK(" 1024x768@75Hz\n"); + } + if (c&0x01) { mode[num++] = vesa_modes[21]; - + DPRINTK(" 1280x1024@75Hz\n"); + } c = block[2]; - if (c&0x80) + if (c&0x80) { mode[num++] = vesa_modes[17]; - + DPRINTK(" 1152x870@75Hz\n"); + } + DPRINTK(" Manufacturer's mask: %x\n",c&0x7F); return num; } @@ -567,17 +355,17 @@ } refresh = (block[1] & 0x3f) + 60; + DPRINTK(" %dx%d@%dHz\n", xres, yres, refresh); for (i = 0; i < VESA_MODEDB_SIZE; i++) { if (vesa_modes[i].xres == xres && vesa_modes[i].yres == yres && vesa_modes[i].refresh == refresh) { *mode = vesa_modes[i]; - break; - } else { - calc_mode_timings(xres, yres, refresh, mode); - break; + mode->flag |= FB_MODE_IS_STANDARD; + return 1; } } + calc_mode_timings(xres, yres, refresh, mode); return 1; } @@ -615,6 +403,15 @@ mode->refresh = PIXEL_CLOCK/((H_ACTIVE + H_BLANKING) * (V_ACTIVE + V_BLANKING)); mode->vmode = 0; + mode->flag = FB_MODE_IS_DETAILED; + + DPRINTK(" %d MHz ", PIXEL_CLOCK/1000000); + DPRINTK("%d %d %d %d ", H_ACTIVE, H_ACTIVE + H_SYNC_OFFSET, + H_ACTIVE + H_SYNC_OFFSET + H_SYNC_WIDTH, H_ACTIVE + H_BLANKING); + DPRINTK("%d %d %d %d ", V_ACTIVE, V_ACTIVE + V_SYNC_OFFSET, + V_ACTIVE + V_SYNC_OFFSET + V_SYNC_WIDTH, V_ACTIVE + V_BLANKING); + DPRINTK("%sHSync %sVSync\n\n", (HSYNC_POSITIVE) ? "+" : "-", + (VSYNC_POSITIVE) ? "+" : "-"); } /** @@ -647,21 +444,30 @@ *dbsize = 0; + DPRINTK(" Supported VESA Modes\n"); block = edid + ESTABLISHED_TIMING_1; num += get_est_timing(block, &mode[num]); + DPRINTK(" Standard Timings\n"); block = edid + STD_TIMING_DESCRIPTIONS_START; for (i = 0; i < STD_TIMING; i++, block += STD_TIMING_DESCRIPTION_SIZE) num += get_std_timing(block, &mode[num]); + DPRINTK(" Detailed Timings\n"); block = edid + DETAILED_TIMING_DESCRIPTIONS_START; for (i = 0; i < 4; i++, block+= DETAILED_TIMING_DESCRIPTION_SIZE) { + int first = 1; + if (block[0] == 0x00 && block[1] == 0x00) { if (block[3] == 0xfa) { num += get_dst_timing(block + 5, &mode[num]); } } else { get_detailed_timing(block, &mode[num]); + if (first) { + mode[num].flag |= FB_MODE_IS_FIRST; + first = 0; + } num++; } } @@ -694,45 +500,24 @@ kfree(modedb); } -/** - * fb_get_monitor_limits - get monitor operating limits - * @edid: EDID data - * @specs: fb_monspecs structure pointer - * - * DESCRIPTION: - * Gets monitor operating limits from EDID data and places them in - * @specs - */ int fb_get_monitor_limits(unsigned char *edid, struct fb_monspecs *specs) { int i, retval = 1; unsigned char *block; - if (edid == NULL || specs == NULL) - return 1; - - if (!(edid_checksum(edid))) - return 1; - - if (!(edid_check_header(edid))) - return 1; - - memset(specs, 0, sizeof(struct fb_monspecs)); block = edid + DETAILED_TIMING_DESCRIPTIONS_START; - printk("Monitor Operating Limits: "); + DPRINTK(" Monitor Operating Limits: "); for (i = 0; i < 4; i++, block += DETAILED_TIMING_DESCRIPTION_SIZE) { if (edid_is_limits_block(block)) { specs->hfmin = H_MIN_RATE * 1000; specs->hfmax = H_MAX_RATE * 1000; specs->vfmin = V_MIN_RATE; specs->vfmax = V_MAX_RATE; - specs->dclkmax = (MAX_PIXEL_CLOCK != 10*0xff) ? - MAX_PIXEL_CLOCK * 1000000 : 0; + specs->dclkmax = MAX_PIXEL_CLOCK * 1000000; specs->gtf = (GTF_SUPPORT) ? 1 : 0; - specs->dpms = edid[DPMS_FLAGS]; retval = 0; - printk("From EDID\n"); + DPRINTK("From EDID\n"); break; } } @@ -744,7 +529,7 @@ modes = fb_create_modedb(edid, &num_modes); if (!modes) { - printk("None Available\n"); + DPRINTK("None Available\n"); return 1; } @@ -767,15 +552,189 @@ if (specs->vfmin == 0 || specs->vfmin > hz) specs->vfmin = hz; } - printk("Extrapolated\n"); + DPRINTK("Extrapolated\n"); fb_destroy_modedb(modes); } - printk(" H: %d-%dKHz V: %d-%dHz DCLK: %dMHz\n", specs->hfmin/1000, specs->hfmax/1000, - specs->vfmin, specs->vfmax, specs->dclkmax/1000000); + DPRINTK(" H: %d-%dKHz V: %d-%dHz DCLK: %dMHz\n", + specs->hfmin/1000, specs->hfmax/1000, specs->vfmin, + specs->vfmax, specs->dclkmax/1000000); return retval; } -void show_edid(unsigned char *edid) +static void get_monspecs(unsigned char *edid, struct fb_monspecs *specs) +{ + unsigned char c, *block; + + block = edid + EDID_STRUCT_DISPLAY; + + fb_get_monitor_limits(edid, specs); + + c = (block[0] & 0x80) >> 7; + specs->input = 0; + if (c) { + specs->input |= FB_DISP_DDI; + DPRINTK(" Digital Display Input"); + } else { + DPRINTK(" Analog Display Input: Input Voltage - "); + switch ((block[0] & 0x60) >> 5) { + case 0: + DPRINTK("0.700V/0.300V"); + specs->input |= FB_DISP_ANA_700_300; + break; + case 1: + DPRINTK("0.714V/0.286V"); + specs->input |= FB_DISP_ANA_714_286; + break; + case 2: + DPRINTK("1.000V/0.400V"); + specs->input |= FB_DISP_ANA_1000_400; + break; + case 3: + DPRINTK("0.700V/0.000V"); + specs->input |= FB_DISP_ANA_700_000; + break; + default: + DPRINTK("unknown"); + specs->input |= FB_DISP_UNKNOWN; + } + } + DPRINTK("\n Sync: "); + c = (block[0] & 0x10) >> 4; + if (c) + DPRINTK(" Configurable signal level\n"); + c = block[0] & 0x0f; + specs->signal = 0; + if (c & 0x10) { + DPRINTK("Blank to Blank "); + specs->signal |= FB_SIGNAL_BLANK_BLANK; + } + if (c & 0x08) { + DPRINTK("Separate "); + specs->signal |= FB_SIGNAL_SEPARATE; + } + if (c & 0x04) { + DPRINTK("Composite "); + specs->signal |= FB_SIGNAL_COMPOSITE; + } + if (c & 0x02) { + DPRINTK("Sync on Green "); + specs->signal |= FB_SIGNAL_SYNC_ON_GREEN; + } + if (c & 0x01) { + DPRINTK("Serration on "); + specs->signal |= FB_SIGNAL_SERRATION_ON; + } + DPRINTK("\n"); + specs->max_x = block[1]; + specs->max_y = block[2]; + DPRINTK(" Max H-size in cm: "); + if (specs->max_x) + DPRINTK("%d\n", specs->max_x); + else + DPRINTK("variable\n"); + DPRINTK(" Max V-size in cm: "); + if (specs->max_y) + DPRINTK("%d\n", specs->max_y); + else + DPRINTK("variable\n"); + + c = block[3]; + specs->gamma = c+100; + DPRINTK(" Gamma: "); + DPRINTK("%d.%d\n", specs->gamma/100, specs->gamma % 100); + + get_dpms_capabilities(block[4], specs); + + switch ((block[4] & 0x18) >> 3) { + case 0: + DPRINTK(" Monochrome/Grayscale\n"); + specs->input |= FB_DISP_MONO; + break; + case 1: + DPRINTK(" RGB Color Display\n"); + specs->input |= FB_DISP_RGB; + break; + case 2: + DPRINTK(" Non-RGB Multicolor Display\n"); + specs->input |= FB_DISP_MULTI; + break; + default: + DPRINTK(" Unknown\n"); + specs->input |= FB_DISP_UNKNOWN; + break; + } + + get_chroma(block, specs); + + specs->misc = 0; + c = block[4] & 0x7; + if (c & 0x04) { + DPRINTK(" Default color format is primary\n"); + specs->misc |= FB_MISC_PRIM_COLOR; + } + if (c & 0x02) { + DPRINTK(" First DETAILED Timing is preferred\n"); + specs->misc |= FB_MISC_1ST_DETAIL; + } + if (c & 0x01) { + printk(" Display is GTF capable\n"); + specs->gtf = 1; + } +} + +static int edid_is_timing_block(unsigned char *block) +{ + if ((block[0] != 0x00) || (block[1] != 0x00) || + (block[2] != 0x00) || (block[4] != 0x00)) + return 1; + else + return 0; +} + +int fb_parse_edid(unsigned char *edid, struct fb_var_screeninfo *var) +{ + int i; + unsigned char *block; + + if (edid == NULL || var == NULL) + return 1; + + if (!(edid_checksum(edid))) + return 1; + + if (!(edid_check_header(edid))) + return 1; + + block = edid + DETAILED_TIMING_DESCRIPTIONS_START; + + for (i = 0; i < 4; i++, block += DETAILED_TIMING_DESCRIPTION_SIZE) { + if (edid_is_timing_block(block)) { + var->xres = var->xres_virtual = H_ACTIVE; + var->yres = var->yres_virtual = V_ACTIVE; + var->height = var->width = -1; + var->right_margin = H_SYNC_OFFSET; + var->left_margin = (H_ACTIVE + H_BLANKING) - + (H_ACTIVE + H_SYNC_OFFSET + H_SYNC_WIDTH); + var->upper_margin = V_BLANKING - V_SYNC_OFFSET - + V_SYNC_WIDTH; + var->lower_margin = V_SYNC_OFFSET; + var->hsync_len = H_SYNC_WIDTH; + var->vsync_len = V_SYNC_WIDTH; + var->pixclock = PIXEL_CLOCK; + var->pixclock /= 1000; + var->pixclock = KHZ2PICOS(var->pixclock); + + if (HSYNC_POSITIVE) + var->sync |= FB_SYNC_HOR_HIGH_ACT; + if (VSYNC_POSITIVE) + var->sync |= FB_SYNC_VERT_HIGH_ACT; + return 0; + } + } + return 1; +} + +void fb_edid_to_monspecs(unsigned char *edid, struct fb_monspecs *specs) { unsigned char *block; int i; @@ -788,83 +747,52 @@ if (!(edid_check_header(edid))) return; - printk("========================================\n"); - printk("Display Information (EDID)\n"); - printk("========================================\n"); - printk(" EDID Version %d.%d\n", (int) edid[EDID_STRUCT_VERSION], - (int) edid[EDID_STRUCT_REVISION]); - parse_vendor_block(edid + ID_MANUFACTURER_NAME); + memset(specs, 0, sizeof(struct fb_monspecs)); - printk(" Display Characteristics:\n"); - parse_display_block(edid + EDID_STRUCT_DISPLAY); + specs->version = edid[EDID_STRUCT_VERSION]; + specs->revision = edid[EDID_STRUCT_REVISION]; - printk(" Standard Timings\n"); - block = edid + STD_TIMING_DESCRIPTIONS_START; - for (i = 0; i < STD_TIMING; i++, block += STD_TIMING_DESCRIPTION_SIZE) - parse_std_timing_block(block); + DPRINTK("========================================\n"); + DPRINTK("Display Information (EDID)\n"); + DPRINTK("========================================\n"); + DPRINTK(" EDID Version %d.%d\n", (int) specs->version, + (int) specs->revision); - printk(" Supported VESA Modes\n"); - parse_std_md_block(edid + ESTABLISHED_TIMING_1); + parse_vendor_block(edid + ID_MANUFACTURER_NAME, specs); - printk(" Detailed Monitor Information\n"); block = edid + DETAILED_TIMING_DESCRIPTIONS_START; for (i = 0; i < 4; i++, block += DETAILED_TIMING_DESCRIPTION_SIZE) { if (edid_is_serial_block(block)) { - parse_serial_block(block); + copy_string(block, specs->serial_no); + DPRINTK(" Serial Number: %s\n", specs->serial_no); } else if (edid_is_ascii_block(block)) { - parse_ascii_block(block); - } else if (edid_is_limits_block(block)) { - parse_limits_block(block); + copy_string(block, specs->ascii); + DPRINTK(" ASCII Block: %s\n", specs->ascii); } else if (edid_is_monitor_block(block)) { - parse_monitor_block(block); - } else if (edid_is_color_block(block)) { - parse_color_block(block); - } else if (edid_is_std_timings_block(block)) { - parse_dst_timing_block(block); - } else if (edid_is_timing_block(block)) { - parse_detailed_timing_block(block); + copy_string(block, specs->monitor); + DPRINTK(" Monitor Name: %s\n", specs->monitor); } } - printk("========================================\n"); -} -#ifdef CONFIG_PPC_OF -char *get_EDID_from_OF(struct pci_dev *pdev) -{ - static char *propnames[] = - { "DFP,EDID", "LCD,EDID", "EDID", "EDID1", NULL }; - unsigned char *pedid = NULL; - struct device_node *dp; - int i; + DPRINTK(" Display Characteristics:\n"); + get_monspecs(edid, specs); - if (pdev == NULL) - return NULL; - dp = pci_device_to_OF_node(pdev); - while (dp != NULL) { - for (i = 0; propnames[i] != NULL; ++i) { - pedid = (unsigned char *) get_property(dp, propnames[i], NULL); - if (pedid != NULL) - return pedid; - } - dp = dp->child; - } - show_edid(pedid); - return pedid; + specs->modedb = fb_create_modedb(edid, &specs->modedb_len); + DPRINTK("========================================\n"); } -#endif -#ifdef CONFIG_X86 -char *get_EDID_from_BIOS(void *dummy) +char *get_EDID_from_firmware(struct device *dev) { - unsigned char *pedid = edid_info.dummy; - + unsigned char *pedid = NULL; + +#if defined(CONFIG_EDID_FIRMWARE) && defined(CONFIG_X86) + pedid = edid_info.dummy; if (!pedid) return NULL; - show_edid(pedid); - return pedid; -} #endif + return pedid; +} /* * VESA Generalized Timing Formula (GTF) @@ -1179,7 +1107,7 @@ * REQUIRES: * A valid info->monspecs. */ -int fb_validate_mode(struct fb_var_screeninfo *var, struct fb_info *info) +int fb_validate_mode(const struct fb_var_screeninfo *var, struct fb_info *info) { u32 hfreq, vfreq, htotal, vtotal, pixclock; u32 hfmin, hfmax, vfmin, vfmax, dclkmin, dclkmax; @@ -1228,16 +1156,12 @@ -EINVAL : 0; } -EXPORT_SYMBOL(parse_edid); -EXPORT_SYMBOL(show_edid); -#ifdef CONFIG_X86 -EXPORT_SYMBOL(get_EDID_from_BIOS); -#endif -#ifdef CONFIG_PPC_OF -EXPORT_SYMBOL(get_EDID_from_OF); -#endif -EXPORT_SYMBOL(fb_get_monitor_limits); +EXPORT_SYMBOL(fb_parse_edid); +EXPORT_SYMBOL(fb_edid_to_monspecs); +EXPORT_SYMBOL(get_EDID_from_firmware); + EXPORT_SYMBOL(fb_get_mode); EXPORT_SYMBOL(fb_validate_mode); EXPORT_SYMBOL(fb_create_modedb); EXPORT_SYMBOL(fb_destroy_modedb); +EXPORT_SYMBOL(fb_get_monitor_limits); diff -Nru a/drivers/video/fm2fb.c b/drivers/video/fm2fb.c --- a/drivers/video/fm2fb.c Sun Mar 14 14:20:07 2004 +++ b/drivers/video/fm2fb.c Sun Mar 14 14:20:07 2004 @@ -49,7 +49,7 @@ * not assembled with memory for the alpha channel. In this * case it could be possible to add the frame buffer into the * normal memory pool. - * + * * At relative address 0x1ffff8 of the frame buffers base address * there exists a control register with the number of * four control bits. They have the following meaning: @@ -64,7 +64,7 @@ * is not very much information about the FrameMaster II in * the world so I add these information for completeness. * - * JP1 interlace selection (1-2 non interlaced/2-3 interlaced) + * JP1 interlace selection (1-2 non interlaced/2-3 interlaced) * JP2 wait state creation (leave as is!) * JP3 wait state creation (leave as is!) * JP4 modulate composite sync on green output (1-2 composite @@ -127,12 +127,7 @@ static volatile unsigned char *fm2fb_reg; -#define arraysize(x) (sizeof(x)/sizeof(*(x))) - -static struct fb_info fb_info; -static u32 pseudo_palette[17]; - -static struct fb_fix_screeninfo fb_fix __initdata = { +static struct fb_fix_screeninfo fb_fix __devinitdata = { .smem_len = FRAMEMASTER_REG, .type = FB_TYPE_PACKED_PIXELS, .visual = FB_VISUAL_TRUECOLOR, @@ -141,12 +136,12 @@ .accel = FB_ACCEL_NONE, }; -static int fm2fb_mode __initdata = -1; +static int fm2fb_mode __devinitdata = -1; #define FM2FB_MODE_PAL 0 #define FM2FB_MODE_NTSC 1 -static struct fb_var_screeninfo fb_var_modes[] __initdata = { +static struct fb_var_screeninfo fb_var_modes[] __devinitdata = { { /* 768 x 576, 32 bpp (PAL) */ 768, 576, 768, 576, 0, 0, 32, 0, @@ -161,11 +156,10 @@ 33333, 10, 102, 10, 5, 80, 34, FB_SYNC_COMP_HIGH_ACT, 0 } }; - + /* * Interface used by the world */ -int fm2fb_init(void); static int fm2fb_setcolreg(u_int regno, u_int red, u_int green, u_int blue, u_int transp, struct fb_info *info); @@ -174,7 +168,7 @@ static struct fb_ops fm2fb_ops = { .owner = THIS_MODULE, .fb_setcolreg = fm2fb_setcolreg, - .fb_blank = fm2fb_blank, + .fb_blank = fm2fb_blank, .fb_fillrect = cfb_fillrect, .fb_copyarea = cfb_copyarea, .fb_imageblit = cfb_imageblit, @@ -202,7 +196,7 @@ static int fm2fb_setcolreg(u_int regno, u_int red, u_int green, u_int blue, u_int transp, struct fb_info *info) { - if (regno > 15) + if (regno > info->cmap.len) return 1; red >>= 8; green >>= 8; @@ -216,66 +210,91 @@ * Initialisation */ -int __init fm2fb_init(void) +static int __devinit fm2fb_probe(struct zorro_dev *z, + const struct zorro_device_id *id); + +static struct zorro_device_id fm2fb_devices[] __devinitdata = { + { ZORRO_PROD_BSC_FRAMEMASTER_II }, + { ZORRO_PROD_HELFRICH_RAINBOW_II }, + { 0 } +}; + +static struct zorro_driver fm2fb_driver = { + .name = "fm2fb", + .id_table = fm2fb_devices, + .probe = fm2fb_probe, +}; + +static int __devinit fm2fb_probe(struct zorro_dev *z, + const struct zorro_device_id *id) { - struct zorro_dev *z = NULL; + struct fb_info *info; unsigned long *ptr; int is_fm; int x, y; - while ((z = zorro_find_device(ZORRO_WILDCARD, z))) { - if (z->id == ZORRO_PROD_BSC_FRAMEMASTER_II) - is_fm = 1; - else if (z->id == ZORRO_PROD_HELFRICH_RAINBOW_II) - is_fm = 0; - else - continue; - - if (!request_mem_region(z->resource.start, FRAMEMASTER_SIZE, "fm2fb")) - continue; - - /* assigning memory to kernel space */ - fb_fix.smem_start = z->resource.start; - fb_info.screen_base = ioremap(fb_fix.smem_start, FRAMEMASTER_SIZE); - fb_fix.mmio_start = fb_fix.smem_start + FRAMEMASTER_REG; - fm2fb_reg = (unsigned char *)(fb_info.screen_base+FRAMEMASTER_REG); - - strcpy(fb_fix.id, is_fm ? "FrameMaster II" : "Rainbow II"); - - /* make EBU color bars on display */ - ptr = (unsigned long *)fb_fix.smem_start; - for (y = 0; y < 576; y++) { - for (x = 0; x < 96; x++) *ptr++ = 0xffffff;/* white */ - for (x = 0; x < 96; x++) *ptr++ = 0xffff00;/* yellow */ - for (x = 0; x < 96; x++) *ptr++ = 0x00ffff;/* cyan */ - for (x = 0; x < 96; x++) *ptr++ = 0x00ff00;/* green */ - for (x = 0; x < 96; x++) *ptr++ = 0xff00ff;/* magenta */ - for (x = 0; x < 96; x++) *ptr++ = 0xff0000;/* red */ - for (x = 0; x < 96; x++) *ptr++ = 0x0000ff;/* blue */ - for (x = 0; x < 96; x++) *ptr++ = 0x000000;/* black */ - } - fm2fb_blank(0, NULL); - - if (fm2fb_mode == -1) - fm2fb_mode = FM2FB_MODE_PAL; - - fb_info.fbops = &fm2fb_ops; - fb_info.var = fb_var_modes[fm2fb_mode]; - fb_info.screen_base = (char *)fb_fix.smem_start; - fb_info.pseudo_palette = pseudo_palette; - fb_info.fix = fb_fix; - fb_info.flags = FBINFO_FLAG_DEFAULT; + is_fm = z->id == ZORRO_PROD_BSC_FRAMEMASTER_II; + + if (!zorro_request_device(z,"fm2fb")) + return -ENXIO; - /* The below fields will go away !!!! */ - fb_alloc_cmap(&fb_info.cmap, 16, 0); + info = framebuffer_alloc(256 * sizeof(u32), &z->dev); + if (!info) { + zorro_release_device(z); + return -ENOMEM; + } - if (register_framebuffer(&fb_info) < 0) - return -EINVAL; + if (fb_alloc_cmap(&info->cmap, 256, 0) < 0) { + framebuffer_release(info); + zorro_release_device(z); + return -ENOMEM; + } - printk("fb%d: %s frame buffer device\n", fb_info.node, fb_fix.id); - return 0; + /* assigning memory to kernel space */ + fb_fix.smem_start = zorro_resource_start(z); + info->screen_base = ioremap(fb_fix.smem_start, FRAMEMASTER_SIZE); + fb_fix.mmio_start = fb_fix.smem_start + FRAMEMASTER_REG; + fm2fb_reg = (unsigned char *)(info->screen_base+FRAMEMASTER_REG); + + strcpy(fb_fix.id, is_fm ? "FrameMaster II" : "Rainbow II"); + + /* make EBU color bars on display */ + ptr = (unsigned long *)fb_fix.smem_start; + for (y = 0; y < 576; y++) { + for (x = 0; x < 96; x++) *ptr++ = 0xffffff;/* white */ + for (x = 0; x < 96; x++) *ptr++ = 0xffff00;/* yellow */ + for (x = 0; x < 96; x++) *ptr++ = 0x00ffff;/* cyan */ + for (x = 0; x < 96; x++) *ptr++ = 0x00ff00;/* green */ + for (x = 0; x < 96; x++) *ptr++ = 0xff00ff;/* magenta */ + for (x = 0; x < 96; x++) *ptr++ = 0xff0000;/* red */ + for (x = 0; x < 96; x++) *ptr++ = 0x0000ff;/* blue */ + for (x = 0; x < 96; x++) *ptr++ = 0x000000;/* black */ + } + fm2fb_blank(0, info); + + if (fm2fb_mode == -1) + fm2fb_mode = FM2FB_MODE_PAL; + + info->fbops = &fm2fb_ops; + info->var = fb_var_modes[fm2fb_mode]; + info->pseudo_palette = info->par; + info->par = NULL; + info->fix = fb_fix; + info->flags = FBINFO_FLAG_DEFAULT; + + if (register_framebuffer(info) < 0) { + fb_dealloc_cmap(&info->cmap); + framebuffer_release(info); + zorro_release_device(z); + return -EINVAL; } - return -ENXIO; + printk("fb%d: %s frame buffer device\n", info->node, fb_fix.id); + return 0; +} + +int __init fm2fb_init(void) +{ + return zorro_register_driver(&fm2fb_driver); } int __init fm2fb_setup(char *options) @@ -285,7 +304,7 @@ if (!options || !*options) return 0; - while ((this_opt = strsep(&options, ",")) != NULL) { + while ((this_opt = strsep(&options, ",")) != NULL) { if (!strncmp(this_opt, "pal", 3)) fm2fb_mode = FM2FB_MODE_PAL; else if (!strncmp(this_opt, "ntsc", 4)) diff -Nru a/drivers/video/i810/i810_main.h b/drivers/video/i810/i810_main.h --- a/drivers/video/i810/i810_main.h Sun Mar 14 14:20:07 2004 +++ b/drivers/video/i810/i810_main.h Sun Mar 14 14:20:07 2004 @@ -84,7 +84,7 @@ extern void i810fb_load_front (u32 offset, struct fb_info *info); /* Conditionals */ -#if defined(__i386__) +#ifdef CONFIG_X86 inline void flush_cache(void) { asm volatile ("wbinvd":::"memory"); diff -Nru a/drivers/video/modedb.c b/drivers/video/modedb.c --- a/drivers/video/modedb.c Sun Mar 14 14:20:07 2004 +++ b/drivers/video/modedb.c Sun Mar 14 14:20:07 2004 @@ -39,7 +39,7 @@ #define DEFAULT_MODEDB_INDEX 0 -static const struct fb_videomode modedb[] __initdata = { +static const struct fb_videomode modedb[] = { { /* 640x400 @ 70 Hz, 31.5 kHz hsync */ NULL, 70, 640, 400, 39721, 40, 24, 39, 9, 96, 2, @@ -130,11 +130,11 @@ 0, FB_VMODE_NONINTERLACED }, { /* 1400x1050 @ 75,107 Hz, 82,392 kHz +hsync +vsync*/ - "LCD_XGA_75", 75, 1400, 1050, 9271, 120, 56, 13, 0, 112, 3, + NULL, 75, 1400, 1050, 9271, 120, 56, 13, 0, 112, 3, FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED }, { /* 1400x1050 @ 60 Hz, ? kHz +hsync +vsync*/ - "LCD_XGA_60", 60, 1400, 1050, 9259, 128, 40, 12, 0, 112, 3, + NULL, 60, 1400, 1050, 9259, 128, 40, 12, 0, 112, 3, FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED }, { /* 1024x768 @ 85 Hz, 70.24 kHz hsync */ @@ -254,109 +254,128 @@ const struct fb_videomode vesa_modes[] = { /* 0 640x350-85 VESA */ { NULL, 85, 640, 350, 31746, 96, 32, 60, 32, 64, 3, - FB_SYNC_HOR_HIGH_ACT, FB_VMODE_NONINTERLACED }, + FB_SYNC_HOR_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA}, /* 1 640x400-85 VESA */ { NULL, 85, 640, 400, 31746, 96, 32, 41, 01, 64, 3, - FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED }, + FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA }, /* 2 720x400-85 VESA */ { NULL, 85, 721, 400, 28169, 108, 36, 42, 01, 72, 3, - FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED }, + FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA }, /* 3 640x480-60 VESA */ { NULL, 60, 640, 480, 39682, 48, 16, 33, 10, 96, 2, - 0, FB_VMODE_NONINTERLACED }, + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA }, /* 4 640x480-72 VESA */ { NULL, 72, 640, 480, 31746, 128, 24, 29, 9, 40, 2, - 0, FB_VMODE_NONINTERLACED }, + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA }, /* 5 640x480-75 VESA */ { NULL, 75, 640, 480, 31746, 120, 16, 16, 01, 64, 3, - 0, FB_VMODE_NONINTERLACED }, + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA }, /* 6 640x480-85 VESA */ { NULL, 85, 640, 480, 27777, 80, 56, 25, 01, 56, 3, - 0, FB_VMODE_NONINTERLACED }, + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA }, /* 7 800x600-56 VESA */ { NULL, 56, 800, 600, 27777, 128, 24, 22, 01, 72, 2, - FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED }, + FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, + FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA }, /* 8 800x600-60 VESA */ { NULL, 60, 800, 600, 25000, 88, 40, 23, 01, 128, 4, - FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED }, + FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, + FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA }, /* 9 800x600-72 VESA */ { NULL, 72, 800, 600, 20000, 64, 56, 23, 37, 120, 6, - FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED }, + FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, + FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA }, /* 10 800x600-75 VESA */ { NULL, 75, 800, 600, 20202, 160, 16, 21, 01, 80, 3, - FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED }, + FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, + FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA }, /* 11 800x600-85 VESA */ { NULL, 85, 800, 600, 17761, 152, 32, 27, 01, 64, 3, - FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED }, + FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, + FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA }, /* 12 1024x768i-43 VESA */ { NULL, 53, 1024, 768, 22271, 56, 8, 41, 0, 176, 8, - FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, FB_VMODE_INTERLACED }, + FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, + FB_VMODE_INTERLACED, FB_MODE_IS_VESA }, /* 13 1024x768-60 VESA */ { NULL, 60, 1024, 768, 15384, 160, 24, 29, 3, 136, 6, - 0, FB_VMODE_NONINTERLACED }, + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA }, /* 14 1024x768-70 VESA */ { NULL, 70, 1024, 768, 13333, 144, 24, 29, 3, 136, 6, - 0, FB_VMODE_NONINTERLACED }, + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA }, /* 15 1024x768-75 VESA */ { NULL, 75, 1024, 768, 12690, 176, 16, 28, 1, 96, 3, - FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED }, + FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, + FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA }, /* 16 1024x768-85 VESA */ { NULL, 85, 1024, 768, 10582, 208, 48, 36, 1, 96, 3, - FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED }, + FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, + FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA }, /* 17 1152x864-75 VESA */ { NULL, 75, 1153, 864, 9259, 256, 64, 32, 1, 128, 3, - FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED }, + FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, + FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA }, /* 18 1280x960-60 VESA */ { NULL, 60, 1280, 960, 9259, 312, 96, 36, 1, 112, 3, - FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED }, + FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, + FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA }, /* 19 1280x960-85 VESA */ { NULL, 85, 1280, 960, 6734, 224, 64, 47, 1, 160, 3, - FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED }, + FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, + FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA }, /* 20 1280x1024-60 VESA */ { NULL, 60, 1280, 1024, 9259, 248, 48, 38, 1, 112, 3, - FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED }, + FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, + FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA }, /* 21 1280x1024-75 VESA */ { NULL, 75, 1280, 1024, 7407, 248, 16, 38, 1, 144, 3, - FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED }, + FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, + FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA }, /* 22 1280x1024-85 VESA */ { NULL, 85, 1280, 1024, 6349, 224, 64, 44, 1, 160, 3, - FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED }, + FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, + FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA }, /* 23 1600x1200-60 VESA */ { NULL, 60, 1600, 1200, 6172, 304, 64, 46, 1, 192, 3, - FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED }, + FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, + FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA }, /* 24 1600x1200-65 VESA */ { NULL, 65, 1600, 1200, 5698, 304, 64, 46, 1, 192, 3, - FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED }, + FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, + FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA }, /* 25 1600x1200-70 VESA */ { NULL, 70, 1600, 1200, 5291, 304, 64, 46, 1, 192, 3, - FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED }, + FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, + FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA }, /* 26 1600x1200-75 VESA */ { NULL, 75, 1600, 1200, 4938, 304, 64, 46, 1, 192, 3, - FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED }, + FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, + FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA }, /* 27 1600x1200-85 VESA */ { NULL, 85, 1600, 1200, 4357, 304, 64, 46, 1, 192, 3, - FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED }, + FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, + FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA }, /* 28 1792x1344-60 VESA */ { NULL, 60, 1792, 1344, 4882, 328, 128, 46, 1, 200, 3, - FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED }, + FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA }, /* 29 1792x1344-75 VESA */ { NULL, 75, 1792, 1344, 3831, 352, 96, 69, 1, 216, 3, - FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED }, + FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA }, /* 30 1856x1392-60 VESA */ { NULL, 60, 1856, 1392, 4580, 352, 96, 43, 1, 224, 3, - FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED }, + FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA }, /* 31 1856x1392-75 VESA */ { NULL, 75, 1856, 1392, 3472, 352, 128, 104, 1, 224, 3, - FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED }, + FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA }, /* 32 1920x1440-60 VESA */ { NULL, 60, 1920, 1440, 4273, 344, 128, 56, 1, 200, 3, - FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED }, + FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA }, /* 33 1920x1440-75 VESA */ { NULL, 60, 1920, 1440, 3367, 352, 144, 56, 1, 224, 3, - FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED }, + FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA }, }; -static int __init my_atoi(const char *name) +static int my_atoi(const char *name) { int val = 0; @@ -447,11 +466,11 @@ * */ -int __init fb_find_mode(struct fb_var_screeninfo *var, - struct fb_info *info, const char *mode_option, - const struct fb_videomode *db, unsigned int dbsize, - const struct fb_videomode *default_mode, - unsigned int default_bpp) +int fb_find_mode(struct fb_var_screeninfo *var, + struct fb_info *info, const char *mode_option, + const struct fb_videomode *db, unsigned int dbsize, + const struct fb_videomode *default_mode, + unsigned int default_bpp) { int i, j; diff -Nru a/fs/Kconfig b/fs/Kconfig --- a/fs/Kconfig Sun Mar 14 14:20:07 2004 +++ b/fs/Kconfig Sun Mar 14 14:20:07 2004 @@ -1227,6 +1227,9 @@ experimental "UFS file system write support", below. Please read the file for more information. + The recently released UFS2 variant (used in FreeBSD 5.x) is + READ-ONLY supported. + If you only intend to mount files from some other Unix over the network using NFS, you don't need the UFS file system support (but you need NFS file system support obviously). @@ -1302,15 +1305,18 @@ Say Y here if you want your NFS client to be able to speak the newer version 3 of the NFS protocol. - If unsure, say N. + If unsure, say Y. config NFS_V4 bool "Provide NFSv4 client support (EXPERIMENTAL)" depends on NFS_FS && EXPERIMENTAL + select RPCSEC_GSS_KRB5 help Say Y here if you want your NFS client to be able to speak the newer - version 4 of the NFS protocol. This feature is experimental, and - should only be used if you are interested in helping to test NFSv4. + version 4 of the NFS protocol. + + Note: Requires auxiliary userspace daemons which may be found on + http://www.citi.umich.edu/projects/nfsv4/ If unsure, say N. @@ -1419,28 +1425,24 @@ tristate config SUNRPC_GSS - tristate "Provide RPCSEC_GSS authentication (EXPERIMENTAL)" + tristate + +config RPCSEC_GSS_KRB5 + tristate "Secure RPC: Kerberos V mechanism (EXPERIMENTAL)" depends on SUNRPC && EXPERIMENTAL - default SUNRPC if NFS_V4=y + select SUNRPC_GSS + select CRYPTO + select CRYPTO_MD5 + select CRYPTO_DES help - Provides cryptographic authentication for NFS rpc requests. To - make this useful, you must also select at least one rpcsec_gss - mechanism. - Note: You should always select this option if you wish to use + Provides for secure RPC calls by means of a gss-api + mechanism based on Kerberos V5. This is required for NFSv4. -config RPCSEC_GSS_KRB5 - tristate "Kerberos V mechanism for RPCSEC_GSS (EXPERIMENTAL)" - depends on SUNRPC_GSS && CRYPTO_DES && CRYPTO_MD5 - default SUNRPC_GSS if NFS_V4=y - help - Provides a gss-api mechanism based on Kerberos V5 (this is - mandatory for RFC3010-compliant NFSv4 implementations). - Requires a userspace daemon; - see http://www.citi.umich.edu/projects/nfsv4/. + Note: Requires an auxiliary userspace daemon which may be found on + http://www.citi.umich.edu/projects/nfsv4/ - Note: If you select this option, please ensure that you also - enable the MD5 and DES crypto ciphers. + If unsure, say N. config SMB_FS tristate "SMB file system support (to mount Windows shares etc.)" diff -Nru a/fs/adfs/super.c b/fs/adfs/super.c --- a/fs/adfs/super.c Sun Mar 14 14:20:05 2004 +++ b/fs/adfs/super.c Sun Mar 14 14:20:05 2004 @@ -335,6 +335,8 @@ struct adfs_sb_info *asb; struct inode *root; + sb->s_flags |= MS_NODIRATIME; + asb = kmalloc(sizeof(*asb), GFP_KERNEL); if (!asb) return -ENOMEM; diff -Nru a/fs/affs/super.c b/fs/affs/super.c --- a/fs/affs/super.c Sun Mar 14 14:20:07 2004 +++ b/fs/affs/super.c Sun Mar 14 14:20:07 2004 @@ -293,6 +293,7 @@ sb->s_magic = AFFS_SUPER_MAGIC; sb->s_op = &affs_sops; + sb->s_flags |= MS_NODIRATIME; sbi = kmalloc(sizeof(struct affs_sb_info), GFP_KERNEL); if (!sbi) diff -Nru a/fs/afs/inode.c b/fs/afs/inode.c --- a/fs/afs/inode.c Sun Mar 14 14:20:06 2004 +++ b/fs/afs/inode.c Sun Mar 14 14:20:06 2004 @@ -188,6 +188,7 @@ #endif /* okay... it's a new inode */ + inode->i_flags |= S_NOATIME; vnode->flags |= AFS_VNODE_CHANGED; ret = afs_inode_fetch_status(inode); if (ret<0) diff -Nru a/fs/afs/super.c b/fs/afs/super.c --- a/fs/afs/super.c Sun Mar 14 14:20:07 2004 +++ b/fs/afs/super.c Sun Mar 14 14:20:07 2004 @@ -53,6 +53,7 @@ .name = "afs", .get_sb = afs_get_sb, .kill_sb = kill_anon_super, + .fs_flags = FS_BINARY_MOUNTDATA, }; static struct super_operations afs_super_ops = { diff -Nru a/fs/bfs/dir.c b/fs/bfs/dir.c --- a/fs/bfs/dir.c Sun Mar 14 14:20:08 2004 +++ b/fs/bfs/dir.c Sun Mar 14 14:20:08 2004 @@ -65,7 +65,6 @@ brelse(bh); } - update_atime(dir); unlock_kernel(); return 0; } diff -Nru a/fs/binfmt_elf.c b/fs/binfmt_elf.c --- a/fs/binfmt_elf.c Sun Mar 14 14:20:07 2004 +++ b/fs/binfmt_elf.c Sun Mar 14 14:20:07 2004 @@ -830,9 +830,8 @@ and some applications "depend" upon this behavior. Since we do not have the power to recompile these, we emulate the SVr4 behavior. Sigh. */ - /* N.B. Shouldn't the size here be PAGE_SIZE?? */ down_write(¤t->mm->mmap_sem); - error = do_mmap(NULL, 0, 4096, PROT_READ | PROT_EXEC, + error = do_mmap(NULL, 0, PAGE_SIZE, PROT_READ | PROT_EXEC, MAP_FIXED | MAP_PRIVATE, 0); up_write(¤t->mm->mmap_sem); } diff -Nru a/fs/block_dev.c b/fs/block_dev.c --- a/fs/block_dev.c Sun Mar 14 14:20:09 2004 +++ b/fs/block_dev.c Sun Mar 14 14:20:09 2004 @@ -116,9 +116,18 @@ blkdev_get_block(struct inode *inode, sector_t iblock, struct buffer_head *bh, int create) { - if (iblock >= max_block(I_BDEV(inode))) - return -EIO; - + if (iblock >= max_block(I_BDEV(inode))) { + if (create) + return -EIO; + + /* + * for reads, we're just trying to fill a partial page. + * return a hole, they will have to call get_block again + * before they can fill it, and they will get -EIO at that + * time + */ + return 0; + } bh->b_bdev = I_BDEV(inode); bh->b_blocknr = iblock; set_buffer_mapped(bh); @@ -522,7 +531,7 @@ EXPORT_SYMBOL(check_disk_change); -static void bd_set_size(struct block_device *bdev, loff_t size) +void bd_set_size(struct block_device *bdev, loff_t size) { unsigned bsize = bdev_hardsect_size(bdev); @@ -535,6 +544,7 @@ bdev->bd_block_size = bsize; bdev->bd_inode->i_blkbits = blksize_bits(bsize); } +EXPORT_SYMBOL(bd_set_size); static int do_open(struct block_device *bdev, struct file *file) { diff -Nru a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c --- a/fs/cifs/cifsfs.c Sun Mar 14 14:20:07 2004 +++ b/fs/cifs/cifsfs.c Sun Mar 14 14:20:07 2004 @@ -77,6 +77,7 @@ struct cifs_sb_info *cifs_sb; int rc = 0; + sb->s_flags |= MS_NODIRATIME; /* and probably even noatime */ sb->s_fs_info = kmalloc(sizeof(struct cifs_sb_info),GFP_KERNEL); cifs_sb = CIFS_SB(sb); if(cifs_sb == NULL) diff -Nru a/fs/coda/dir.c b/fs/coda/dir.c --- a/fs/coda/dir.c Sun Mar 14 14:20:06 2004 +++ b/fs/coda/dir.c Sun Mar 14 14:20:06 2004 @@ -510,8 +510,10 @@ goto out; ret = -ENOENT; - if (!IS_DEADDIR(host_inode)) + if (!IS_DEADDIR(host_inode)) { ret = host_file->f_op->readdir(host_file, filldir, dirent); + update_atime(host_inode); + } } out: coda_file->f_pos = host_file->f_pos; diff -Nru a/fs/coda/inode.c b/fs/coda/inode.c --- a/fs/coda/inode.c Sun Mar 14 14:20:07 2004 +++ b/fs/coda/inode.c Sun Mar 14 14:20:07 2004 @@ -171,6 +171,7 @@ sbi->sbi_vcomm = vc; sb->s_fs_info = sbi; + sb->s_flags |= MS_NODIRATIME; /* probably even noatime */ sb->s_blocksize = 1024; /* XXXXX what do we put here?? */ sb->s_blocksize_bits = 10; sb->s_magic = CODA_SUPER_MAGIC; @@ -308,5 +309,6 @@ .name = "coda", .get_sb = coda_get_sb, .kill_sb = kill_anon_super, + .fs_flags = FS_BINARY_MOUNTDATA, }; diff -Nru a/fs/cramfs/inode.c b/fs/cramfs/inode.c --- a/fs/cramfs/inode.c Sun Mar 14 14:20:06 2004 +++ b/fs/cramfs/inode.c Sun Mar 14 14:20:06 2004 @@ -201,6 +201,8 @@ struct cramfs_sb_info *sbi; struct inode *root; + sb->s_flags |= MS_RDONLY; + sbi = kmalloc(sizeof(struct cramfs_sb_info), GFP_KERNEL); if (!sbi) return -ENOMEM; diff -Nru a/fs/ext2/acl.c b/fs/ext2/acl.c --- a/fs/ext2/acl.c Sun Mar 14 14:20:08 2004 +++ b/fs/ext2/acl.c Sun Mar 14 14:20:08 2004 @@ -154,10 +154,9 @@ static struct posix_acl * ext2_get_acl(struct inode *inode, int type) { - const size_t max_size = ext2_acl_size(EXT2_ACL_MAX_ENTRIES); struct ext2_inode_info *ei = EXT2_I(inode); int name_index; - char *value; + char *value = NULL; struct posix_acl *acl; int retval; @@ -182,17 +181,21 @@ default: return ERR_PTR(-EINVAL); } - value = kmalloc(max_size, GFP_KERNEL); - if (!value) - return ERR_PTR(-ENOMEM); - - retval = ext2_xattr_get(inode, name_index, "", value, max_size); - acl = ERR_PTR(retval); - if (retval >= 0) + retval = ext2_xattr_get(inode, name_index, "", NULL, 0); + if (retval > 0) { + value = kmalloc(retval, GFP_KERNEL); + if (!value) + return ERR_PTR(-ENOMEM); + retval = ext2_xattr_get(inode, name_index, "", value, retval); + } + if (retval > 0) acl = ext2_acl_from_disk(value, retval); else if (retval == -ENODATA || retval == -ENOSYS) acl = NULL; - kfree(value); + else + acl = ERR_PTR(retval); + if (value) + kfree(value); if (!IS_ERR(acl)) { switch(type) { diff -Nru a/fs/ext2/dir.c b/fs/ext2/dir.c --- a/fs/ext2/dir.c Sun Mar 14 14:20:07 2004 +++ b/fs/ext2/dir.c Sun Mar 14 14:20:07 2004 @@ -310,7 +310,6 @@ done: filp->f_pos = (n << PAGE_CACHE_SHIFT) | offset; filp->f_version = inode->i_version; - update_atime(inode); return 0; } diff -Nru a/fs/ext3/acl.c b/fs/ext3/acl.c --- a/fs/ext3/acl.c Sun Mar 14 14:20:06 2004 +++ b/fs/ext3/acl.c Sun Mar 14 14:20:06 2004 @@ -157,10 +157,9 @@ static struct posix_acl * ext3_get_acl(struct inode *inode, int type) { - const size_t max_size = ext3_acl_size(EXT3_ACL_MAX_ENTRIES); struct ext3_inode_info *ei = EXT3_I(inode); int name_index; - char *value; + char *value = NULL; struct posix_acl *acl; int retval; @@ -185,17 +184,21 @@ default: return ERR_PTR(-EINVAL); } - value = kmalloc(max_size, GFP_KERNEL); - if (!value) - return ERR_PTR(-ENOMEM); - - retval = ext3_xattr_get(inode, name_index, "", value, max_size); - acl = ERR_PTR(retval); + retval = ext3_xattr_get(inode, name_index, "", NULL, 0); + if (retval > 0) { + value = kmalloc(retval, GFP_KERNEL); + if (!value) + return ERR_PTR(-ENOMEM); + retval = ext3_xattr_get(inode, name_index, "", value, retval); + } if (retval > 0) acl = ext3_acl_from_disk(value, retval); else if (retval == -ENODATA || retval == -ENOSYS) acl = NULL; - kfree(value); + else + acl = ERR_PTR(retval); + if (value) + kfree(value); if (!IS_ERR(acl)) { switch(type) { diff -Nru a/fs/ext3/dir.c b/fs/ext3/dir.c --- a/fs/ext3/dir.c Sun Mar 14 14:20:07 2004 +++ b/fs/ext3/dir.c Sun Mar 14 14:20:07 2004 @@ -224,7 +224,6 @@ offset = 0; brelse (bh); } - update_atime(inode); out: return ret; } @@ -506,7 +505,6 @@ } finished: info->last_pos = filp->f_pos; - update_atime(inode); return 0; } diff -Nru a/fs/fat/inode.c b/fs/fat/inode.c --- a/fs/fat/inode.c Sun Mar 14 14:20:07 2004 +++ b/fs/fat/inode.c Sun Mar 14 14:20:07 2004 @@ -778,6 +778,7 @@ sb->s_fs_info = sbi; memset(sbi, 0, sizeof(struct msdos_sb_info)); + sb->s_flags |= MS_NODIRATIME; sb->s_magic = MSDOS_SUPER_MAGIC; sb->s_op = &fat_sops; sb->s_export_op = &fat_export_ops; diff -Nru a/fs/freevxfs/vxfs_super.c b/fs/freevxfs/vxfs_super.c --- a/fs/freevxfs/vxfs_super.c Sun Mar 14 14:20:08 2004 +++ b/fs/freevxfs/vxfs_super.c Sun Mar 14 14:20:08 2004 @@ -145,6 +145,8 @@ u_long bsize; struct inode *root; + sbp->s_flags |= MS_RDONLY; + infp = kmalloc(sizeof(*infp), GFP_KERNEL); if (!infp) { printk(KERN_WARNING "vxfs: unable to allocate incore superblock\n"); diff -Nru a/fs/hfs/super.c b/fs/hfs/super.c --- a/fs/hfs/super.c Sun Mar 14 14:20:06 2004 +++ b/fs/hfs/super.c Sun Mar 14 14:20:06 2004 @@ -268,6 +268,7 @@ } sb->s_op = &hfs_super_operations; + sb->s_flags |= MS_NODIRATIME; init_MUTEX(&sbi->bitmap_lock); res = hfs_mdb_get(sb); diff -Nru a/fs/inode.c b/fs/inode.c --- a/fs/inode.c Sun Mar 14 14:20:08 2004 +++ b/fs/inode.c Sun Mar 14 14:20:08 2004 @@ -1178,6 +1178,8 @@ struct timespec now; int sync_it = 0; + if (IS_NOCMTIME(inode)) + return; if (IS_RDONLY(inode)) return; diff -Nru a/fs/jffs/inode-v23.c b/fs/jffs/inode-v23.c --- a/fs/jffs/inode-v23.c Sun Mar 14 14:20:07 2004 +++ b/fs/jffs/inode-v23.c Sun Mar 14 14:20:07 2004 @@ -70,6 +70,8 @@ struct inode *root_inode; struct jffs_control *c; + sb->s_flags |= MS_NODIRATIME; + D1(printk(KERN_NOTICE "JFFS: Trying to mount device %s.\n", sb->s_id)); diff -Nru a/fs/jffs2/super.c b/fs/jffs2/super.c --- a/fs/jffs2/super.c Sun Mar 14 14:20:06 2004 +++ b/fs/jffs2/super.c Sun Mar 14 14:20:06 2004 @@ -129,6 +129,7 @@ mtd->index, mtd->name)); sb->s_op = &jffs2_super_operations; + sb->s_flags |= MS_NODIRATIME; ret = jffs2_do_fill_super(sb, data, (flags&MS_VERBOSE)?1:0); diff -Nru a/fs/libfs.c b/fs/libfs.c --- a/fs/libfs.c Sun Mar 14 14:20:05 2004 +++ b/fs/libfs.c Sun Mar 14 14:20:05 2004 @@ -155,7 +155,6 @@ } spin_unlock(&dcache_lock); } - update_atime(dentry->d_inode); return 0; } diff -Nru a/fs/lockd/clntproc.c b/fs/lockd/clntproc.c --- a/fs/lockd/clntproc.c Sun Mar 14 14:20:06 2004 +++ b/fs/lockd/clntproc.c Sun Mar 14 14:20:06 2004 @@ -443,7 +443,7 @@ } if (status < 0) return status; - } while (resp->status == NLM_LCK_BLOCKED); + } while (resp->status == NLM_LCK_BLOCKED && req->a_args.block); if (resp->status == NLM_LCK_GRANTED) { fl->fl_u.nfs_fl.state = host->h_state; diff -Nru a/fs/lockd/host.c b/fs/lockd/host.c --- a/fs/lockd/host.c Sun Mar 14 14:20:07 2004 +++ b/fs/lockd/host.c Sun Mar 14 14:20:07 2004 @@ -188,14 +188,14 @@ } } else { xprt = xprt_create_proto(host->h_proto, &host->h_addr, NULL); - if (xprt == NULL) + if (IS_ERR(xprt)) goto forgetit; xprt_set_timeout(&xprt->timeout, 5, nlmsvc_timeout); clnt = rpc_create_client(xprt, host->h_name, &nlm_program, host->h_version, host->h_authflavor); - if (clnt == NULL) { + if (IS_ERR(clnt)) { xprt_destroy(xprt); goto forgetit; } diff -Nru a/fs/lockd/mon.c b/fs/lockd/mon.c --- a/fs/lockd/mon.c Sun Mar 14 14:20:08 2004 +++ b/fs/lockd/mon.c Sun Mar 14 14:20:08 2004 @@ -36,10 +36,11 @@ int status; struct nsm_args args; - status = -EACCES; clnt = nsm_create(); - if (!clnt) + if (IS_ERR(clnt)) { + status = PTR_ERR(clnt); goto out; + } args.addr = host->h_addr.sin_addr.s_addr; args.proto= (host->h_proto<<1) | host->h_server; @@ -104,7 +105,7 @@ nsm_create(void) { struct rpc_xprt *xprt; - struct rpc_clnt *clnt = NULL; + struct rpc_clnt *clnt; struct sockaddr_in sin; sin.sin_family = AF_INET; @@ -112,24 +113,23 @@ sin.sin_port = 0; xprt = xprt_create_proto(IPPROTO_UDP, &sin, NULL); - if (!xprt) - goto out; + if (IS_ERR(xprt)) + return (struct rpc_clnt *)xprt; clnt = rpc_create_client(xprt, "localhost", &nsm_program, SM_VERSION, RPC_AUTH_NULL); - if (!clnt) + if (IS_ERR(clnt)) goto out_destroy; clnt->cl_softrtry = 1; clnt->cl_chatty = 1; clnt->cl_oneshot = 1; xprt->resvport = 1; /* NSM requires a reserved port */ -out: return clnt; out_destroy: xprt_destroy(xprt); - goto out; + return clnt; } /* diff -Nru a/fs/lockd/svc4proc.c b/fs/lockd/svc4proc.c --- a/fs/lockd/svc4proc.c Sun Mar 14 14:20:07 2004 +++ b/fs/lockd/svc4proc.c Sun Mar 14 14:20:07 2004 @@ -453,6 +453,24 @@ } /* + * client sent a GRANTED_RES, let's remove the associated block + */ +static int +nlm4svc_proc_granted_res(struct svc_rqst *rqstp, struct nlm_res *argp, + void *resp) +{ + if (!nlmsvc_ops) + return rpc_success; + + dprintk("lockd: GRANTED_RES called\n"); + + nlmsvc_grant_reply(rqstp, &argp->cookie, argp->status); + return rpc_success; +} + + + +/* * This is the generic lockd callback for async RPC calls */ static u32 @@ -515,7 +533,6 @@ #define nlm4svc_proc_lock_res nlm4svc_proc_null #define nlm4svc_proc_cancel_res nlm4svc_proc_null #define nlm4svc_proc_unlock_res nlm4svc_proc_null -#define nlm4svc_proc_granted_res nlm4svc_proc_null struct nlm_void { int dummy; }; @@ -548,7 +565,7 @@ PROC(lock_res, lockres, norep, res, void, 1), PROC(cancel_res, cancelres, norep, res, void, 1), PROC(unlock_res, unlockres, norep, res, void, 1), - PROC(granted_res, grantedres, norep, res, void, 1), + PROC(granted_res, res, norep, res, void, 1), /* statd callback */ PROC(sm_notify, reboot, void, reboot, void, 1), PROC(none, void, void, void, void, 0), diff -Nru a/fs/lockd/svclock.c b/fs/lockd/svclock.c --- a/fs/lockd/svclock.c Sun Mar 14 14:20:06 2004 +++ b/fs/lockd/svclock.c Sun Mar 14 14:20:06 2004 @@ -64,7 +64,7 @@ if (when != NLM_NEVER) { if ((when += jiffies) == NLM_NEVER) when ++; - while ((b = *bp) && time_before_eq(b->b_when,when)) + while ((b = *bp) && time_before_eq(b->b_when,when) && b->b_when != NLM_NEVER) bp = &b->b_next; } else while ((b = *bp)) @@ -143,14 +143,15 @@ * Find a block with a given NLM cookie. */ static inline struct nlm_block * -nlmsvc_find_block(struct nlm_cookie *cookie) +nlmsvc_find_block(struct nlm_cookie *cookie, struct sockaddr_in *sin) { struct nlm_block *block; for (block = nlm_blocked; block; block = block->b_next) { dprintk("cookie: head of blocked queue %p, block %p\n", nlm_blocked, block); - if (nlm_cookie_match(&block->b_call.a_args.cookie,cookie)) + if (nlm_cookie_match(&block->b_call.a_args.cookie,cookie) + && nlm_cmp_addr(sin, &block->b_host->h_addr)) break; } @@ -566,12 +567,16 @@ struct nlm_rqst *call = (struct nlm_rqst *) task->tk_calldata; struct nlm_block *block; unsigned long timeout; + struct sockaddr_in *peer_addr = RPC_PEERADDR(task->tk_client); dprintk("lockd: GRANT_MSG RPC callback\n"); - dprintk("callback: looking for cookie %x \n", - *(unsigned int *)(call->a_args.cookie.data)); - if (!(block = nlmsvc_find_block(&call->a_args.cookie))) { - dprintk("lockd: no block for cookie %x\n", *(u32 *)(call->a_args.cookie.data)); + dprintk("callback: looking for cookie %x, host (%08x)\n", + *(unsigned int *)(call->a_args.cookie.data), + ntohl(peer_addr->sin_addr.s_addr)); + if (!(block = nlmsvc_find_block(&call->a_args.cookie, peer_addr))) { + dprintk("lockd: no block for cookie %x, host (%08x)\n", + *(u32 *)(call->a_args.cookie.data), + ntohl(peer_addr->sin_addr.s_addr)); return; } @@ -600,18 +605,21 @@ * block. */ void -nlmsvc_grant_reply(struct nlm_cookie *cookie, u32 status) +nlmsvc_grant_reply(struct svc_rqst *rqstp, struct nlm_cookie *cookie, u32 status) { struct nlm_block *block; struct nlm_file *file; - if (!(block = nlmsvc_find_block(cookie))) + dprintk("grant_reply: looking for cookie %x, host (%08x), s=%d \n", + *(unsigned int *)(cookie->data), + ntohl(rqstp->rq_addr.sin_addr.s_addr), status); + if (!(block = nlmsvc_find_block(cookie, &rqstp->rq_addr))) return; file = block->b_file; file->f_count++; down(&file->f_sema); - if ((block = nlmsvc_find_block(cookie)) != NULL) { + if ((block = nlmsvc_find_block(cookie,&rqstp->rq_addr)) != NULL) { if (status == NLM_LCK_DENIED_GRACE_PERIOD) { /* Try again in a couple of seconds */ nlmsvc_insert_block(block, 10 * HZ); diff -Nru a/fs/lockd/svcproc.c b/fs/lockd/svcproc.c --- a/fs/lockd/svcproc.c Sun Mar 14 14:20:07 2004 +++ b/fs/lockd/svcproc.c Sun Mar 14 14:20:07 2004 @@ -479,6 +479,22 @@ } /* + * client sent a GRANTED_RES, let's remove the associated block + */ +static int +nlmsvc_proc_granted_res(struct svc_rqst *rqstp, struct nlm_res *argp, + void *resp) +{ + if (!nlmsvc_ops) + return rpc_success; + + dprintk("lockd: GRANTED_RES called\n"); + + nlmsvc_grant_reply(rqstp, &argp->cookie, argp->status); + return rpc_success; +} + +/* * This is the generic lockd callback for async RPC calls */ static u32 @@ -541,7 +557,6 @@ #define nlmsvc_proc_lock_res nlmsvc_proc_null #define nlmsvc_proc_cancel_res nlmsvc_proc_null #define nlmsvc_proc_unlock_res nlmsvc_proc_null -#define nlmsvc_proc_granted_res nlmsvc_proc_null struct nlm_void { int dummy; }; @@ -576,7 +591,7 @@ PROC(lock_res, lockres, norep, res, void, 1), PROC(cancel_res, cancelres, norep, res, void, 1), PROC(unlock_res, unlockres, norep, res, void, 1), - PROC(granted_res, grantedres, norep, res, void, 1), + PROC(granted_res, res, norep, res, void, 1), /* statd callback */ PROC(sm_notify, reboot, void, reboot, void, 1), PROC(none, void, void, void, void, 1), diff -Nru a/fs/minix/dir.c b/fs/minix/dir.c --- a/fs/minix/dir.c Sun Mar 14 14:20:08 2004 +++ b/fs/minix/dir.c Sun Mar 14 14:20:08 2004 @@ -127,7 +127,6 @@ done: filp->f_pos = (n << PAGE_CACHE_SHIFT) | offset; - update_atime(inode); unlock_kernel(); return 0; } diff -Nru a/fs/ncpfs/inode.c b/fs/ncpfs/inode.c --- a/fs/ncpfs/inode.c Sun Mar 14 14:20:07 2004 +++ b/fs/ncpfs/inode.c Sun Mar 14 14:20:07 2004 @@ -479,6 +479,7 @@ else default_bufsize = 1024; + sb->s_flags |= MS_NODIRATIME; /* probably even noatime */ sb->s_maxbytes = 0xFFFFFFFFU; sb->s_blocksize = 1024; /* Eh... Is this correct? */ sb->s_blocksize_bits = 10; diff -Nru a/fs/nfs/dir.c b/fs/nfs/dir.c --- a/fs/nfs/dir.c Sun Mar 14 14:20:07 2004 +++ b/fs/nfs/dir.c Sun Mar 14 14:20:07 2004 @@ -139,11 +139,13 @@ struct file *file = desc->file; struct inode *inode = file->f_dentry->d_inode; struct rpc_cred *cred = nfs_file_cred(file); + unsigned long timestamp; int error; dfprintk(VFS, "NFS: nfs_readdir_filler() reading cookie %Lu into page %lu.\n", (long long)desc->entry->cookie, page->index); again: + timestamp = jiffies; error = NFS_PROTO(inode)->readdir(file->f_dentry, cred, desc->entry->cookie, page, NFS_SERVER(inode)->dtsize, desc->plus); if (error < 0) { @@ -157,18 +159,21 @@ goto error; } SetPageUptodate(page); + NFS_FLAGS(inode) |= NFS_INO_INVALID_ATIME; /* Ensure consistent page alignment of the data. * Note: assumes we have exclusive access to this mapping either * throught inode->i_sem or some other mechanism. */ - if (page->index == 0) + if (page->index == 0) { invalidate_inode_pages(inode->i_mapping); + NFS_I(inode)->readdir_timestamp = timestamp; + } unlock_page(page); return 0; error: SetPageError(page); unlock_page(page); - invalidate_inode_pages(inode->i_mapping); + nfs_zap_caches(inode); desc->error = error; return -EIO; } @@ -381,6 +386,7 @@ page, NFS_SERVER(inode)->dtsize, desc->plus); + NFS_FLAGS(inode) |= NFS_INO_INVALID_ATIME; desc->page = page; desc->ptr = kmap(page); /* matching kunmap in nfs_do_filldir */ if (desc->error >= 0) { @@ -459,7 +465,15 @@ } res = 0; break; - } else if (res < 0) + } + if (res == -ETOOSMALL && desc->plus) { + NFS_FLAGS(inode) &= ~NFS_INO_ADVISE_RDPLUS; + nfs_zap_caches(inode); + desc->plus = 0; + desc->entry->eof = 0; + continue; + } + if (res < 0) break; res = nfs_do_filldir(desc, dirent, filldir); @@ -481,14 +495,19 @@ * In the case it has, we assume that the dentries are untrustworthy * and may need to be looked up again. */ -static inline -int nfs_check_verifier(struct inode *dir, struct dentry *dentry) +static inline int nfs_check_verifier(struct inode *dir, struct dentry *dentry) { if (IS_ROOT(dentry)) return 1; - if (nfs_revalidate_inode(NFS_SERVER(dir), dir)) + if ((NFS_FLAGS(dir) & NFS_INO_INVALID_ATTR) != 0 + || nfs_attribute_timeout(dir)) return 0; - return time_after(dentry->d_time, NFS_MTIME_UPDATE(dir)); + return nfs_verify_change_attribute(dir, (unsigned long)dentry->d_fsdata); +} + +static inline void nfs_set_verifier(struct dentry * dentry, unsigned long verf) +{ + dentry->d_fsdata = (void *)verf; } /* @@ -528,9 +547,7 @@ /* Don't revalidate a negative dentry if we're creating a new file */ if ((ndflags & LOOKUP_CREATE) && !(ndflags & LOOKUP_CONTINUE)) return 0; - if (!nfs_check_verifier(dir, dentry)) - return 1; - return time_after(jiffies, dentry->d_time + NFS_ATTRTIMEO(dir)); + return !nfs_check_verifier(dir, dentry); } /* @@ -552,6 +569,7 @@ int error; struct nfs_fh fhandle; struct nfs_fattr fattr; + unsigned long verifier; int isopen = 0; parent = dget_parent(dentry); @@ -574,6 +592,9 @@ goto out_bad; } + /* Revalidate parent directory attribute cache */ + nfs_revalidate_inode(NFS_SERVER(dir), dir); + /* Force a full look up iff the parent directory has changed */ if (nfs_check_verifier(dir, dentry)) { if (nfs_lookup_verify_inode(inode, isopen)) @@ -581,6 +602,12 @@ goto out_valid; } + /* + * Note: we're not holding inode->i_sem and so may be racing with + * operations that change the directory. We therefore save the + * change attribute *before* we do the RPC call. + */ + verifier = nfs_save_change_attribute(dir); error = nfs_cached_lookup(dir, dentry, &fhandle, &fattr); if (!error) { if (memcmp(NFS_FH(inode), &fhandle, sizeof(struct nfs_fh))!= 0) @@ -603,6 +630,7 @@ out_valid_renew: nfs_renew_times(dentry); + nfs_set_verifier(dentry, verifier); out_valid: unlock_kernel(); dput(parent); @@ -638,6 +666,11 @@ /* Unhash it, so that ->d_iput() would be called */ return 1; } + if (!(dentry->d_sb->s_flags & MS_ACTIVE)) { + /* Unhash it, so that ancestors of killed async unlink + * files will be cleaned up during umount */ + return 1; + } return 0; } @@ -693,6 +726,8 @@ dentry->d_op = NFS_PROTO(dir)->dentry_ops; lock_kernel(); + /* Revalidate parent directory attribute cache */ + nfs_revalidate_inode(NFS_SERVER(dir), dir); /* If we're doing an exclusive create, optimize away the lookup */ if (nfs_is_exclusive_create(dir, nd)) @@ -715,6 +750,7 @@ error = 0; d_add(dentry, inode); nfs_renew_times(dentry); + nfs_set_verifier(dentry, nfs_save_change_attribute(dir)); out_unlock: unlock_kernel(); out: @@ -768,7 +804,15 @@ /* Open the file on the server */ lock_kernel(); - inode = nfs4_atomic_open(dir, dentry, nd); + /* Revalidate parent directory attribute cache */ + nfs_revalidate_inode(NFS_SERVER(dir), dir); + + if (nd->intent.open.flags & O_CREAT) { + nfs_begin_data_update(dir); + inode = nfs4_atomic_open(dir, dentry, nd); + nfs_end_data_update(dir); + } else + inode = nfs4_atomic_open(dir, dentry, nd); unlock_kernel(); if (IS_ERR(inode)) { error = PTR_ERR(inode); @@ -790,6 +834,7 @@ no_entry: d_add(dentry, inode); nfs_renew_times(dentry); + nfs_set_verifier(dentry, nfs_save_change_attribute(dir)); out: BUG_ON(error > 0); return ERR_PTR(error); @@ -801,13 +846,16 @@ { struct dentry *parent = NULL; struct inode *inode = dentry->d_inode; + struct inode *dir; + unsigned long verifier; int openflags, ret = 0; /* NFS only supports OPEN for regular files */ if (inode && !S_ISREG(inode->i_mode)) goto no_open; parent = dget_parent(dentry); - if (!is_atomic_open(parent->d_inode, nd)) + dir = parent->d_inode; + if (!is_atomic_open(dir, nd)) goto no_open; openflags = nd->intent.open.flags; if (openflags & O_CREAT) { @@ -821,8 +869,16 @@ /* We can't create new files, or truncate existing ones here */ openflags &= ~(O_CREAT|O_TRUNC); + /* + * Note: we're not holding inode->i_sem and so may be racing with + * operations that change the directory. We therefore save the + * change attribute *before* we do the RPC call. + */ lock_kernel(); - ret = nfs4_open_revalidate(parent->d_inode, dentry, openflags); + verifier = nfs_save_change_attribute(dir); + ret = nfs4_open_revalidate(dir, dentry, openflags); + if (!ret) + nfs_set_verifier(dentry, verifier); unlock_kernel(); out: dput(parent); @@ -869,15 +925,20 @@ struct nfs_server *server; struct nfs_entry entry; struct page *page; - unsigned long timestamp = NFS_MTIME_UPDATE(dir); + unsigned long timestamp; int res; if (!NFS_USE_READDIRPLUS(dir)) return -ENOENT; server = NFS_SERVER(dir); - if (server->flags & NFS_MOUNT_NOAC) + /* Don't use readdirplus unless the cache is stable */ + if ((server->flags & NFS_MOUNT_NOAC) != 0 + || nfs_caches_unstable(dir) + || nfs_attribute_timeout(dir)) + return -ENOENT; + if ((NFS_FLAGS(dir) & (NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA)) != 0) return -ENOENT; - nfs_revalidate_inode(server, dir); + timestamp = NFS_I(dir)->readdir_timestamp; entry.fh = fh; entry.fattr = fattr; @@ -931,9 +992,10 @@ if (inode) { d_instantiate(dentry, inode); nfs_renew_times(dentry); - error = 0; + nfs_set_verifier(dentry, nfs_save_change_attribute(dentry->d_parent->d_inode)); + return 0; } - return error; + error = -ENOMEM; out_err: d_drop(dentry); return error; @@ -969,11 +1031,13 @@ * does not pass the create flags. */ lock_kernel(); - nfs_zap_caches(dir); + nfs_begin_data_update(dir); inode = NFS_PROTO(dir)->create(dir, &dentry->d_name, &attr, open_flags); + nfs_end_data_update(dir); if (!IS_ERR(inode)) { d_instantiate(dentry, inode); nfs_renew_times(dentry); + nfs_set_verifier(dentry, nfs_save_change_attribute(dir)); error = 0; } else { error = PTR_ERR(inode); @@ -1004,9 +1068,10 @@ attr.ia_valid = ATTR_MODE; lock_kernel(); - nfs_zap_caches(dir); + nfs_begin_data_update(dir); error = NFS_PROTO(dir)->mknod(dir, &dentry->d_name, &attr, rdev, &fhandle, &fattr); + nfs_end_data_update(dir); if (!error) error = nfs_instantiate(dentry, &fhandle, &fattr); else @@ -1041,9 +1106,10 @@ */ d_drop(dentry); #endif - nfs_zap_caches(dir); + nfs_begin_data_update(dir); error = NFS_PROTO(dir)->mkdir(dir, &dentry->d_name, &attr, &fhandle, &fattr); + nfs_end_data_update(dir); if (!error) error = nfs_instantiate(dentry, &fhandle, &fattr); else @@ -1060,10 +1126,12 @@ dir->i_ino, dentry->d_name.name); lock_kernel(); - nfs_zap_caches(dir); + nfs_begin_data_update(dir); error = NFS_PROTO(dir)->rmdir(dir, &dentry->d_name); - if (!error) + /* Ensure the VFS deletes this inode */ + if (error == 0 && dentry->d_inode != NULL) dentry->d_inode->i_nlink = 0; + nfs_end_data_update(dir); unlock_kernel(); return error; @@ -1119,12 +1187,21 @@ goto out; } while(sdentry->d_inode != NULL); /* need negative lookup */ - nfs_zap_caches(dir); qsilly.name = silly; qsilly.len = strlen(silly); - error = NFS_PROTO(dir)->rename(dir, &dentry->d_name, dir, &qsilly); + nfs_begin_data_update(dir); + if (dentry->d_inode) { + nfs_begin_data_update(dentry->d_inode); + error = NFS_PROTO(dir)->rename(dir, &dentry->d_name, + dir, &qsilly); + nfs_end_data_update(dentry->d_inode); + } else + error = NFS_PROTO(dir)->rename(dir, &dentry->d_name, + dir, &qsilly); + nfs_end_data_update(dir); if (!error) { nfs_renew_times(dentry); + nfs_set_verifier(dentry, nfs_save_change_attribute(dir)); d_move(dentry, sdentry); error = nfs_async_unlink(dentry); /* If we return 0 we don't unlink */ @@ -1156,14 +1233,17 @@ goto out; } - nfs_zap_caches(dir); - if (inode) - NFS_CACHEINV(inode); - error = NFS_PROTO(dir)->remove(dir, &dentry->d_name); - if (error < 0) - goto out; - if (inode) - inode->i_nlink--; + nfs_begin_data_update(dir); + if (inode != NULL) { + nfs_begin_data_update(inode); + error = NFS_PROTO(dir)->remove(dir, &dentry->d_name); + /* The VFS may want to delete this inode */ + if (error == 0) + inode->i_nlink--; + nfs_end_data_update(inode); + } else + error = NFS_PROTO(dir)->remove(dir, &dentry->d_name); + nfs_end_data_update(dir); out: return error; } @@ -1198,9 +1278,10 @@ spin_unlock(&dentry->d_lock); spin_unlock(&dcache_lock); error = nfs_safe_remove(dentry); - if (!error) + if (!error) { nfs_renew_times(dentry); - else if (need_rehash) + nfs_set_verifier(dentry, nfs_save_change_attribute(dir)); + } else if (need_rehash) d_rehash(dentry); unlock_kernel(); return error; @@ -1247,9 +1328,10 @@ qsymname.len = strlen(symname); lock_kernel(); - nfs_zap_caches(dir); + nfs_begin_data_update(dir); error = NFS_PROTO(dir)->symlink(dir, &dentry->d_name, &qsymname, &attr, &sym_fh, &sym_attr); + nfs_end_data_update(dir); if (!error) { error = nfs_instantiate(dentry, &sym_fh, &sym_attr); } else { @@ -1281,9 +1363,12 @@ */ lock_kernel(); d_drop(dentry); - nfs_zap_caches(dir); - NFS_CACHEINV(inode); + + nfs_begin_data_update(dir); + nfs_begin_data_update(inode); error = NFS_PROTO(dir)->link(inode, dir, &dentry->d_name); + nfs_end_data_update(inode); + nfs_end_data_update(dir); unlock_kernel(); return error; } @@ -1388,16 +1473,23 @@ if (new_inode) d_delete(new_dentry); - nfs_zap_caches(new_dir); - nfs_zap_caches(old_dir); + nfs_begin_data_update(old_dir); + nfs_begin_data_update(new_dir); + nfs_begin_data_update(old_inode); error = NFS_PROTO(old_dir)->rename(old_dir, &old_dentry->d_name, new_dir, &new_dentry->d_name); + nfs_end_data_update(old_inode); + nfs_end_data_update(new_dir); + nfs_end_data_update(old_dir); out: if (rehash) d_rehash(rehash); - if (!error && !S_ISDIR(old_inode->i_mode)) - d_move(old_dentry, new_dentry); - nfs_renew_times(new_dentry); + if (!error) { + if (!S_ISDIR(old_inode->i_mode)) + d_move(old_dentry, new_dentry); + nfs_renew_times(new_dentry); + nfs_set_verifier(new_dentry, nfs_save_change_attribute(new_dir)); + } /* new dentry created? */ if (dentry) @@ -1451,7 +1543,8 @@ cred = rpcauth_lookupcred(NFS_CLIENT(inode)->cl_auth, 0); if (cache->cred == cred - && time_before(jiffies, cache->jiffies + NFS_ATTRTIMEO(inode))) { + && time_before(jiffies, cache->jiffies + NFS_ATTRTIMEO(inode)) + && !(NFS_FLAGS(inode) & NFS_INO_INVALID_ATTR)) { if (!(res = cache->err)) { /* Is the mask a subset of an accepted mask? */ if ((cache->mask & mask) == mask) diff -Nru a/fs/nfs/direct.c b/fs/nfs/direct.c --- a/fs/nfs/direct.c Sun Mar 14 14:20:08 2004 +++ b/fs/nfs/direct.c Sun Mar 14 14:20:08 2004 @@ -269,6 +269,7 @@ if (IS_SYNC(inode) || NFS_PROTO(inode)->version == 2 || count <= wsize) wdata.args.stable = NFS_FILE_SYNC; + nfs_begin_data_update(inode); retry: need_commit = 0; tot_bytes = 0; @@ -334,6 +335,8 @@ VERF_SIZE) != 0) goto sync_retry; } + nfs_end_data_update(inode); + NFS_FLAGS(inode) |= NFS_INO_INVALID_DATA; return tot_bytes; diff -Nru a/fs/nfs/file.c b/fs/nfs/file.c --- a/fs/nfs/file.c Sun Mar 14 14:20:07 2004 +++ b/fs/nfs/file.c Sun Mar 14 14:20:07 2004 @@ -104,11 +104,16 @@ dfprintk(VFS, "nfs: flush(%s/%ld)\n", inode->i_sb->s_id, inode->i_ino); + if ((file->f_mode & FMODE_WRITE) == 0) + return 0; lock_kernel(); - status = nfs_wb_file(inode, file); + /* Ensure that data+attribute caches are up to date after close() */ + status = nfs_wb_all(inode); if (!status) { status = file->f_error; file->f_error = 0; + if (!status) + __nfs_revalidate_inode(NFS_SERVER(inode), inode); } unlock_kernel(); return status; @@ -179,7 +184,7 @@ dfprintk(VFS, "nfs: fsync(%s/%ld)\n", inode->i_sb->s_id, inode->i_ino); lock_kernel(); - status = nfs_wb_file(inode, file); + status = nfs_wb_all(inode); if (!status) { status = file->f_error; file->f_error = 0; diff -Nru a/fs/nfs/inode.c b/fs/nfs/inode.c --- a/fs/nfs/inode.c Sun Mar 14 14:20:08 2004 +++ b/fs/nfs/inode.c Sun Mar 14 14:20:08 2004 @@ -47,14 +47,11 @@ * their needs. People that do NFS over a slow network, might for * instance want to reduce it to something closer to 1 for improved * interactive response. - * - * For the moment, though, we instead set it to RPC_MAXREQS, which - * is the maximum number of simultaneous RPC requests on the wire. */ -#define NFS_MAX_READAHEAD RPC_MAXREQS +#define NFS_MAX_READAHEAD (RPC_DEF_SLOT_TABLE - 1) -void nfs_zap_caches(struct inode *); static void nfs_invalidate_inode(struct inode *); +static int nfs_update_inode(struct inode *, struct nfs_fattr *, unsigned long); static struct inode *nfs_alloc_inode(struct super_block *sb); static void nfs_destroy_inode(struct inode *); @@ -118,7 +115,7 @@ { int flags = sync ? FLUSH_WAIT : 0; - nfs_commit_file(inode, NULL, 0, 0, flags); + nfs_commit_inode(inode, 0, 0, flags); } static void @@ -151,6 +148,7 @@ cred = nfsi->cache_access.cred; if (cred) put_rpccred(cred); + BUG_ON(atomic_read(&nfsi->data_updates) != 0); } void @@ -230,50 +228,23 @@ /* * Obtain the root inode of the file system. */ -static int -nfs_get_root(struct inode **rooti, rpc_authflavor_t authflavor, struct super_block *sb, struct nfs_fh *rootfh) +static struct inode * +nfs_get_root(struct super_block *sb, struct nfs_fh *rootfh, struct nfs_fsinfo *fsinfo) { struct nfs_server *server = NFS_SB(sb); - struct nfs_fattr fattr = { }; + struct inode *rooti; int error; - error = server->rpc_ops->getroot(server, rootfh, &fattr); - if (error == -EACCES && authflavor > RPC_AUTH_MAXFLAVOR) { - /* - * Some authentication types (gss/krb5, most notably) - * are such that root won't be able to present a - * credential for GETATTR (ie, getroot()). - * - * We still want the mount to succeed. - * - * So we fake the attr values and mark the inode as such. - * On the first succesful traversal, we fix everything. - * The auth type test isn't quite correct, but whatever. - */ - dfprintk(VFS, "NFS: faking root inode\n"); - - fattr.fileid = 1; - fattr.nlink = 2; /* minimum for a dir */ - fattr.type = NFDIR; - fattr.mode = S_IFDIR|S_IRUGO|S_IXUGO; - fattr.size = 4096; - fattr.du.nfs3.used = 1; - fattr.valid = NFS_ATTR_FATTR|NFS_ATTR_FATTR_V3; - } else if (error < 0) { + error = server->rpc_ops->getroot(server, rootfh, fsinfo); + if (error < 0) { printk(KERN_NOTICE "nfs_get_root: getattr error = %d\n", -error); - *rooti = NULL; /* superfluous ... but safe */ - return error; + return ERR_PTR(error); } - *rooti = nfs_fhget(sb, rootfh, &fattr); - if (error == -EACCES && authflavor > RPC_AUTH_MAXFLAVOR) { - if (*rooti) { - NFS_FLAGS(*rooti) |= NFS_INO_FAKE_ROOT; - NFS_CACHEINV((*rooti)); - error = 0; - } - } - return error; + rooti = nfs_fhget(sb, rootfh, fsinfo->fattr); + if (!rooti) + return ERR_PTR(-ENOMEM); + return rooti; } /* @@ -283,7 +254,7 @@ nfs_sb_init(struct super_block *sb, rpc_authflavor_t authflavor) { struct nfs_server *server; - struct inode *root_inode = NULL; + struct inode *root_inode; struct nfs_fattr fattr; struct nfs_fsinfo fsinfo = { .fattr = &fattr, @@ -299,8 +270,9 @@ sb->s_magic = NFS_SUPER_MAGIC; + root_inode = nfs_get_root(sb, &server->fh, &fsinfo); /* Did getting the root inode fail? */ - if (nfs_get_root(&root_inode, authflavor, sb, &server->fh) < 0) + if (IS_ERR(root_inode)) goto out_no_root; sb->s_root = d_alloc_root(root_inode); if (!sb->s_root) @@ -309,10 +281,6 @@ sb->s_root->d_op = server->rpc_ops->dentry_ops; /* Get some general file system info */ - if (server->rpc_ops->fsinfo(server, &server->fh, &fsinfo) < 0) { - printk(KERN_NOTICE "NFS: cannot retrieve file system info.\n"); - goto out_no_root; - } if (server->namelen == 0 && server->rpc_ops->pathconf(server, &server->fh, &pathinfo) >= 0) server->namelen = pathinfo.max_namelen; @@ -368,13 +336,11 @@ rpc_setbufsize(server->client, server->wsize + 100, server->rsize + 100); return 0; /* Yargs. It didn't work out. */ -out_free_all: - if (root_inode) - iput(root_inode); - return -EINVAL; out_no_root: printk("nfs_read_super: get root inode failed\n"); - goto out_free_all; + if (!IS_ERR(root_inode)) + iput(root_inode); + return -EINVAL; } /* @@ -402,13 +368,13 @@ /* create transport and client */ xprt = xprt_create_proto(tcp ? IPPROTO_TCP : IPPROTO_UDP, &server->addr, &timeparms); - if (xprt == NULL) { + if (IS_ERR(xprt)) { printk(KERN_WARNING "NFS: cannot create RPC transport.\n"); - goto out_fail; + return (struct rpc_clnt *)xprt; } clnt = rpc_create_client(xprt, server->hostname, &nfs_program, server->rpc_ops->version, data->pseudoflavor); - if (clnt == NULL) { + if (IS_ERR(clnt)) { printk(KERN_WARNING "NFS: cannot create RPC client.\n"); goto out_fail; } @@ -421,9 +387,8 @@ return clnt; out_fail: - if (xprt) - xprt_destroy(xprt); - return NULL; + xprt_destroy(xprt); + return clnt; } /* @@ -627,13 +592,17 @@ void nfs_zap_caches(struct inode *inode) { + struct nfs_inode *nfsi = NFS_I(inode); + int mode = inode->i_mode; + NFS_ATTRTIMEO(inode) = NFS_MINATTRTIMEO(inode); NFS_ATTRTIMEO_UPDATE(inode) = jiffies; - invalidate_remote_inode(inode); - memset(NFS_COOKIEVERF(inode), 0, sizeof(NFS_COOKIEVERF(inode))); - NFS_CACHEINV(inode); + if (S_ISREG(mode) || S_ISDIR(mode) || S_ISLNK(mode)) + nfsi->flags |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA; + else + nfsi->flags |= NFS_INO_INVALID_ATTR; } /* @@ -673,9 +642,6 @@ return 0; if (is_bad_inode(inode)) return 0; - /* Force an attribute cache update if inode->i_count == 0 */ - if (!atomic_read(&inode->i_count)) - NFS_CACHEINV(inode); return 1; } @@ -729,7 +695,7 @@ inode->i_ino = hash; /* We can't support update_atime(), since the server will reset it */ - inode->i_flags |= S_NOATIME; + inode->i_flags |= S_NOATIME|S_NOCMTIME; inode->i_mode = fattr->mode; /* Why so? Because we want revalidate for devices/FIFOs, and * that's precisely what we have in nfs_file_inode_operations. @@ -754,10 +720,6 @@ inode->i_atime = fattr->atime; inode->i_mtime = fattr->mtime; inode->i_ctime = fattr->ctime; - nfsi->read_cache_ctime = fattr->ctime; - nfsi->read_cache_mtime = fattr->mtime; - nfsi->cache_mtime_jiffies = fattr->timestamp; - nfsi->read_cache_isize = fattr->size; if (fattr->valid & NFS_ATTR_FATTR_V4) nfsi->change_attr = fattr->change_attr; inode->i_size = nfs_size_to_loff_t(fattr->size); @@ -804,70 +766,50 @@ struct nfs_fattr fattr; int error; + if (attr->ia_valid & ATTR_SIZE) { + if (!S_ISREG(inode->i_mode) || attr->ia_size == i_size_read(inode)) + attr->ia_valid &= ~ATTR_SIZE; + } + /* Optimization: if the end result is no change, don't RPC */ attr->ia_valid &= NFS_VALID_ATTRS; if (attr->ia_valid == 0) return 0; lock_kernel(); - - /* - * Make sure the inode is up-to-date. - */ - error = nfs_revalidate_inode(NFS_SERVER(inode),inode); - if (error) { -#ifdef NFS_PARANOIA -printk("nfs_setattr: revalidate failed, error=%d\n", error); -#endif - goto out; - } - - if (!S_ISREG(inode->i_mode)) { - attr->ia_valid &= ~ATTR_SIZE; - if (attr->ia_valid == 0) - goto out; - } else { - filemap_fdatawrite(inode->i_mapping); - error = nfs_wb_all(inode); - filemap_fdatawait(inode->i_mapping); - if (error) - goto out; - /* Optimize away unnecessary truncates */ - if ((attr->ia_valid & ATTR_SIZE) && i_size_read(inode) == attr->ia_size) - attr->ia_valid &= ~ATTR_SIZE; + nfs_begin_data_update(inode); + /* Write all dirty data if we're changing file permissions or size */ + if ((attr->ia_valid & (ATTR_MODE|ATTR_UID|ATTR_GID|ATTR_SIZE)) != 0) { + if (filemap_fdatawrite(inode->i_mapping) == 0) + filemap_fdatawait(inode->i_mapping); + nfs_wb_all(inode); } - if (!attr->ia_valid) - goto out; - error = NFS_PROTO(inode)->setattr(dentry, &fattr, attr); - if (error) - goto out; - /* - * If we changed the size or mtime, update the inode - * now to avoid invalidating the page cache. - */ - if (attr->ia_valid & ATTR_SIZE) { - if (attr->ia_size != fattr.size) - printk("nfs_setattr: attr=%Ld, fattr=%Ld??\n", - (long long) attr->ia_size, (long long)fattr.size); - vmtruncate(inode, attr->ia_size); + if (error == 0) { + nfs_refresh_inode(inode, &fattr); + if ((attr->ia_valid & ATTR_MODE) != 0) { + int mode; + mode = inode->i_mode & ~S_IALLUGO; + mode |= attr->ia_mode & S_IALLUGO; + inode->i_mode = mode; + } + if ((attr->ia_valid & ATTR_UID) != 0) + inode->i_uid = attr->ia_uid; + if ((attr->ia_valid & ATTR_GID) != 0) + inode->i_gid = attr->ia_gid; + if ((attr->ia_valid & ATTR_SIZE) != 0) { + inode->i_size = attr->ia_size; + vmtruncate(inode, attr->ia_size); + } } - - /* - * If we changed the size or mtime, update the inode - * now to avoid invalidating the page cache. - */ - if (!(fattr.valid & NFS_ATTR_WCC)) { - struct nfs_inode *nfsi = NFS_I(inode); - fattr.pre_size = nfsi->read_cache_isize; - fattr.pre_mtime = nfsi->read_cache_mtime; - fattr.pre_ctime = nfsi->read_cache_ctime; - fattr.valid |= NFS_ATTR_WCC; - } - /* Force an attribute cache update */ - NFS_CACHEINV(inode); - error = nfs_refresh_inode(inode, &fattr); -out: + if ((attr->ia_valid & (ATTR_MODE|ATTR_UID|ATTR_GID)) != 0) { + struct rpc_cred **cred = &NFS_I(inode)->cache_access.cred; + if (*cred) { + put_rpccred(*cred); + *cred = NULL; + } + } + nfs_end_data_update(inode); unlock_kernel(); return error; } @@ -895,7 +837,19 @@ int nfs_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat) { struct inode *inode = dentry->d_inode; - int err = nfs_revalidate_inode(NFS_SERVER(inode), inode); + struct nfs_inode *nfsi = NFS_I(inode); + int need_atime = nfsi->flags & NFS_INO_INVALID_ATIME; + int err; + + if (__IS_FLG(inode, MS_NOATIME)) + need_atime = 0; + else if (__IS_FLG(inode, MS_NODIRATIME) && S_ISDIR(inode->i_mode)) + need_atime = 0; + /* We may force a getattr if the user cares about atime */ + if (need_atime) + err = __nfs_revalidate_inode(NFS_SERVER(inode), inode); + else + err = nfs_revalidate_inode(NFS_SERVER(inode), inode); if (!err) generic_fillattr(inode, stat); return err; @@ -930,8 +884,10 @@ auth = NFS_CLIENT(inode)->cl_auth; cred = rpcauth_lookupcred(auth, 0); filp->private_data = cred; - if (filp->f_mode & FMODE_WRITE) + if ((filp->f_mode & FMODE_WRITE) != 0) { nfs_set_mmcred(inode, cred); + nfs_begin_data_update(inode); + } return 0; } @@ -940,6 +896,8 @@ struct rpc_cred *cred; lock_kernel(); + if ((filp->f_mode & FMODE_WRITE) != 0) + nfs_end_data_update(inode); cred = nfs_file_cred(filp); if (cred) put_rpccred(cred); @@ -956,6 +914,9 @@ { int status = -ESTALE; struct nfs_fattr fattr; + struct nfs_inode *nfsi = NFS_I(inode); + unsigned long verifier; + unsigned int flags; dfprintk(PAGECACHE, "NFS: revalidating (%s/%Ld)\n", inode->i_sb->s_id, (long long)NFS_FILEID(inode)); @@ -965,23 +926,22 @@ goto out_nowait; if (NFS_STALE(inode) && inode != inode->i_sb->s_root->d_inode) goto out_nowait; - if (NFS_FAKE_ROOT(inode)) { - dfprintk(VFS, "NFS: not revalidating fake root\n"); - status = 0; - goto out_nowait; - } while (NFS_REVALIDATING(inode)) { status = nfs_wait_on_inode(inode, NFS_INO_REVALIDATING); if (status < 0) goto out_nowait; - if (time_before(jiffies,NFS_READTIME(inode)+NFS_ATTRTIMEO(inode))) { - status = NFS_STALE(inode) ? -ESTALE : 0; - goto out_nowait; - } + if (NFS_SERVER(inode)->flags & NFS_MOUNT_NOAC) + continue; + if (NFS_FLAGS(inode) & (NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA|NFS_INO_INVALID_ATIME)) + continue; + status = NFS_STALE(inode) ? -ESTALE : 0; + goto out_nowait; } NFS_FLAGS(inode) |= NFS_INO_REVALIDATING; + /* Protect against RPC races by saving the change attribute */ + verifier = nfs_save_change_attribute(inode); status = NFS_PROTO(inode)->getattr(inode, &fattr); if (status) { dfprintk(PAGECACHE, "nfs_revalidate_inode: (%s/%Ld) getattr failed, error=%d\n", @@ -995,13 +955,36 @@ goto out; } - status = nfs_refresh_inode(inode, &fattr); + status = nfs_update_inode(inode, &fattr, verifier); if (status) { dfprintk(PAGECACHE, "nfs_revalidate_inode: (%s/%Ld) refresh failed, error=%d\n", inode->i_sb->s_id, (long long)NFS_FILEID(inode), status); goto out; } + flags = nfsi->flags; + /* + * We may need to keep the attributes marked as invalid if + * we raced with nfs_end_attr_update(). + */ + if (verifier == nfsi->cache_change_attribute) + nfsi->flags &= ~(NFS_INO_INVALID_ATTR|NFS_INO_INVALID_ATIME); + /* Do the page cache invalidation */ + if (flags & NFS_INO_INVALID_DATA) { + if (S_ISREG(inode->i_mode)) { + if (filemap_fdatawrite(inode->i_mapping) == 0) + filemap_fdatawait(inode->i_mapping); + nfs_wb_all(inode); + } + nfsi->flags &= ~NFS_INO_INVALID_DATA; + invalidate_inode_pages2(inode->i_mapping); + memset(NFS_COOKIEVERF(inode), 0, sizeof(NFS_COOKIEVERF(inode))); + dfprintk(PAGECACHE, "NFS: (%s/%Ld) data cache invalidated\n", + inode->i_sb->s_id, + (long long)NFS_FILEID(inode)); + /* This ensures we revalidate dentries */ + nfsi->cache_change_attribute++; + } dfprintk(PAGECACHE, "NFS: (%s/%Ld) revalidation complete\n", inode->i_sb->s_id, (long long)NFS_FILEID(inode)); @@ -1009,41 +992,107 @@ NFS_FLAGS(inode) &= ~NFS_INO_STALE; out: NFS_FLAGS(inode) &= ~NFS_INO_REVALIDATING; - wake_up(&NFS_I(inode)->nfs_i_wait); + wake_up(&nfsi->nfs_i_wait); out_nowait: unlock_kernel(); return status; } -/* - * nfs_fattr_obsolete - Test if attribute data is newer than cached data - * @inode: inode - * @fattr: attributes to test +/** + * nfs_begin_data_update + * @inode - pointer to inode + * Declare that a set of operations will update file data on the server + */ +void nfs_begin_data_update(struct inode *inode) +{ + atomic_inc(&NFS_I(inode)->data_updates); +} + +/** + * nfs_end_data_update + * @inode - pointer to inode + * Declare end of the operations that will update file data + */ +void nfs_end_data_update(struct inode *inode) +{ + struct nfs_inode *nfsi = NFS_I(inode); + + /* Mark the attribute cache for revalidation */ + nfsi->flags |= NFS_INO_INVALID_ATTR; + /* Directories and symlinks: invalidate page cache too */ + if (S_ISDIR(inode->i_mode) || S_ISLNK(inode->i_mode)) + nfsi->flags |= NFS_INO_INVALID_DATA; + nfsi->cache_change_attribute ++; + atomic_dec(&nfsi->data_updates); +} + +/** + * nfs_refresh_inode - verify consistency of the inode attribute cache + * @inode - pointer to inode + * @fattr - updated attributes * - * Avoid stuffing the attribute cache with obsolete information. - * We always accept updates if the attribute cache timed out, or if - * fattr->ctime is newer than our cached value. - * If fattr->ctime matches the cached value, we still accept the update - * if it increases the file size. + * Verifies the attribute cache. If we have just changed the attributes, + * so that fattr carries weak cache consistency data, then it may + * also update the ctime/mtime/change_attribute. */ -static inline -int nfs_fattr_obsolete(struct inode *inode, struct nfs_fattr *fattr) +int nfs_refresh_inode(struct inode *inode, struct nfs_fattr *fattr) { struct nfs_inode *nfsi = NFS_I(inode); - long cdif; + loff_t cur_size, new_isize; + int data_unstable; - if (time_after(jiffies, nfsi->read_cache_jiffies + nfsi->attrtimeo)) - goto out_valid; - cdif = fattr->ctime.tv_sec - nfsi->read_cache_ctime.tv_sec; - if (cdif == 0) - cdif = fattr->ctime.tv_nsec - nfsi->read_cache_ctime.tv_nsec; - if (cdif > 0) - goto out_valid; - /* Ugh... */ - if (cdif == 0 && fattr->size > nfsi->read_cache_isize) - goto out_valid; - return -1; - out_valid: + /* Are we in the process of updating data on the server? */ + data_unstable = nfs_caches_unstable(inode); + + if (fattr->valid & NFS_ATTR_FATTR_V4) { + if ((fattr->valid & NFS_ATTR_PRE_CHANGE) != 0 + && nfsi->change_attr == fattr->pre_change_attr) + nfsi->change_attr = fattr->change_attr; + if (!data_unstable && nfsi->change_attr != fattr->change_attr) + nfsi->flags |= NFS_INO_INVALID_ATTR; + } + + if ((fattr->valid & NFS_ATTR_FATTR) == 0) + return 0; + + /* Has the inode gone and changed behind our back? */ + if (nfsi->fileid != fattr->fileid + || (inode->i_mode & S_IFMT) != (fattr->mode & S_IFMT)) + return -EIO; + + cur_size = i_size_read(inode); + new_isize = nfs_size_to_loff_t(fattr->size); + + /* If we have atomic WCC data, we may update some attributes */ + if ((fattr->valid & NFS_ATTR_WCC) != 0) { + if (timespec_equal(&inode->i_ctime, &fattr->pre_ctime)) + memcpy(&inode->i_ctime, &fattr->ctime, sizeof(inode->i_ctime)); + if (timespec_equal(&inode->i_mtime, &fattr->pre_mtime)) + memcpy(&inode->i_mtime, &fattr->mtime, sizeof(inode->i_mtime)); + } + + /* Verify a few of the more important attributes */ + if (!data_unstable) { + if (!timespec_equal(&inode->i_mtime, &fattr->mtime) + || cur_size != new_isize) + nfsi->flags |= NFS_INO_INVALID_ATTR; + } else if (S_ISREG(inode->i_mode) && new_isize > cur_size) + nfsi->flags |= NFS_INO_INVALID_ATTR; + + /* Have any file permissions changed? */ + if ((inode->i_mode & S_IALLUGO) != (fattr->mode & S_IALLUGO) + || inode->i_uid != fattr->uid + || inode->i_gid != fattr->gid) + nfsi->flags |= NFS_INO_INVALID_ATTR; + + /* Has the link count changed? */ + if (inode->i_nlink != fattr->nlink) + nfsi->flags |= NFS_INO_INVALID_ATTR; + + if (!timespec_equal(&inode->i_atime, &fattr->atime)) + nfsi->flags |= NFS_INO_INVALID_ATIME; + + nfsi->read_cache_jiffies = fattr->timestamp; return 0; } @@ -1059,65 +1108,66 @@ * * A very similar scenario holds for the dir cache. */ -int -__nfs_refresh_inode(struct inode *inode, struct nfs_fattr *fattr) +static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr, unsigned long verifier) { struct nfs_inode *nfsi = NFS_I(inode); __u64 new_size; loff_t new_isize; - int invalid = 0; - int mtime_update = 0; + unsigned int invalid = 0; loff_t cur_isize; + int data_unstable; - dfprintk(VFS, "NFS: refresh_inode(%s/%ld ct=%d info=0x%x)\n", - inode->i_sb->s_id, inode->i_ino, + dfprintk(VFS, "NFS: %s(%s/%ld ct=%d info=0x%x)\n", + __FUNCTION__, inode->i_sb->s_id, inode->i_ino, atomic_read(&inode->i_count), fattr->valid); - /* First successful call after mount, fill real data. */ - if (NFS_FAKE_ROOT(inode)) { - dfprintk(VFS, "NFS: updating fake root\n"); - nfsi->fileid = fattr->fileid; - NFS_FLAGS(inode) &= ~NFS_INO_FAKE_ROOT; - } + if ((fattr->valid & NFS_ATTR_FATTR) == 0) + return 0; if (nfsi->fileid != fattr->fileid) { - printk(KERN_ERR "nfs_refresh_inode: inode number mismatch\n" + printk(KERN_ERR "%s: inode number mismatch\n" "expected (%s/0x%Lx), got (%s/0x%Lx)\n", + __FUNCTION__, inode->i_sb->s_id, (long long)nfsi->fileid, inode->i_sb->s_id, (long long)fattr->fileid); goto out_err; } - /* Throw out obsolete READDIRPLUS attributes */ - if (time_before(fattr->timestamp, NFS_READTIME(inode))) - return 0; /* * Make sure the inode's type hasn't changed. */ if ((inode->i_mode & S_IFMT) != (fattr->mode & S_IFMT)) goto out_changed; - new_size = fattr->size; - new_isize = nfs_size_to_loff_t(fattr->size); - - /* Avoid races */ - if (nfs_fattr_obsolete(inode, fattr)) - goto out_nochange; - /* * Update the read time so we don't revalidate too often. */ nfsi->read_cache_jiffies = fattr->timestamp; - /* - * Note: NFS_CACHE_ISIZE(inode) reflects the state of the cache. - * NOT inode->i_size!!! - */ - if (nfsi->read_cache_isize != new_size) { + /* Are we racing with known updates of the metadata on the server? */ + data_unstable = ! nfs_verify_change_attribute(inode, verifier); + + /* Check if the file size agrees */ + new_size = fattr->size; + new_isize = nfs_size_to_loff_t(fattr->size); + cur_isize = i_size_read(inode); + if (cur_isize != new_size) { #ifdef NFS_DEBUG_VERBOSE printk(KERN_DEBUG "NFS: isize change on %s/%ld\n", inode->i_sb->s_id, inode->i_ino); #endif - invalid = 1; + /* + * If we have pending writebacks, things can get + * messy. + */ + if (S_ISREG(inode->i_mode) && data_unstable) { + if (new_isize > cur_isize) { + inode->i_size = new_isize; + invalid |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA; + } + } else { + inode->i_size = new_isize; + invalid |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA; + } } /* @@ -1125,12 +1175,13 @@ * can change this value in VFS without requiring a * cache revalidation. */ - if (!timespec_equal(&nfsi->read_cache_mtime, &fattr->mtime)) { + if (!timespec_equal(&inode->i_mtime, &fattr->mtime)) { + memcpy(&inode->i_mtime, &fattr->mtime, sizeof(inode->i_mtime)); #ifdef NFS_DEBUG_VERBOSE printk(KERN_DEBUG "NFS: mtime change on %s/%ld\n", inode->i_sb->s_id, inode->i_ino); #endif - invalid = 1; - mtime_update = 1; + if (!data_unstable) + invalid |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA; } if ((fattr->valid & NFS_ATTR_FATTR_V4) @@ -1139,47 +1190,15 @@ printk(KERN_DEBUG "NFS: change_attr change on %s/%ld\n", inode->i_sb->s_id, inode->i_ino); #endif - invalid = 1; - } - - /* Check Weak Cache Consistency data. - * If size and mtime match the pre-operation values, we can - * assume that any attribute changes were caused by our NFS - * operation, so there's no need to invalidate the caches. - */ - if ((fattr->valid & NFS_ATTR_PRE_CHANGE) - && nfsi->change_attr == fattr->pre_change_attr) { - invalid = 0; - } - else if ((fattr->valid & NFS_ATTR_WCC) - && nfsi->read_cache_isize == fattr->pre_size - && timespec_equal(&nfsi->read_cache_mtime, &fattr->pre_mtime)) { - invalid = 0; - } - - /* - * If we have pending writebacks, things can get - * messy. - */ - cur_isize = i_size_read(inode); - if (nfs_have_writebacks(inode) && new_isize < cur_isize) - new_isize = cur_isize; - - nfsi->read_cache_ctime = fattr->ctime; - inode->i_ctime = fattr->ctime; - inode->i_atime = fattr->atime; - - if (mtime_update) { - if (invalid) - nfsi->cache_mtime_jiffies = fattr->timestamp; - nfsi->read_cache_mtime = fattr->mtime; - inode->i_mtime = fattr->mtime; + nfsi->change_attr = fattr->change_attr; + if (!data_unstable) + invalid |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA; } - nfsi->read_cache_isize = new_size; - i_size_write(inode, new_isize); + memcpy(&inode->i_ctime, &fattr->ctime, sizeof(inode->i_ctime)); + memcpy(&inode->i_atime, &fattr->atime, sizeof(inode->i_atime)); - if (inode->i_mode != fattr->mode || + if ((inode->i_mode & S_IALLUGO) != (fattr->mode & S_IALLUGO) || inode->i_uid != fattr->uid || inode->i_gid != fattr->gid) { struct rpc_cred **cred = &NFS_I(inode)->cache_access.cred; @@ -1187,11 +1206,9 @@ put_rpccred(*cred); *cred = NULL; } + invalid |= NFS_INO_INVALID_ATTR; } - if (fattr->valid & NFS_ATTR_FATTR_V4) - nfsi->change_attr = fattr->change_attr; - inode->i_mode = fattr->mode; inode->i_nlink = fattr->nlink; inode->i_uid = fattr->uid; @@ -1207,31 +1224,30 @@ inode->i_blocks = fattr->du.nfs2.blocks; inode->i_blksize = fattr->du.nfs2.blocksize; } - - /* Update attrtimeo value */ - if (invalid) { + + /* Update attrtimeo value if we're out of the unstable period */ + if (invalid & NFS_INO_INVALID_ATTR) { nfsi->attrtimeo = NFS_MINATTRTIMEO(inode); nfsi->attrtimeo_timestamp = jiffies; - 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)) nfsi->attrtimeo = NFS_MAXATTRTIMEO(inode); nfsi->attrtimeo_timestamp = jiffies; } + /* Don't invalidate the data if we were to blame */ + if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) + || S_ISLNK(inode->i_mode))) + invalid &= ~NFS_INO_INVALID_DATA; + nfsi->flags |= invalid; return 0; - out_nochange: - if (!timespec_equal(&fattr->atime, &inode->i_atime)) - inode->i_atime = fattr->atime; - return 0; out_changed: /* * Big trouble! The inode has become a different object. */ #ifdef NFS_PARANOIA - printk(KERN_DEBUG "nfs_refresh_inode: inode %ld mode changed, %07o to %07o\n", - inode->i_ino, inode->i_mode, fattr->mode); + printk(KERN_DEBUG "%s: inode %ld mode changed, %07o to %07o\n", + __FUNCTION__, inode->i_ino, inode->i_mode, fattr->mode); #endif /* * No need to worry about unhashing the dentry, as the @@ -1352,7 +1368,7 @@ .name = "nfs", .get_sb = nfs_get_sb, .kill_sb = nfs_kill_super, - .fs_flags = FS_ODD_RENAME|FS_REVAL_DOT, + .fs_flags = FS_ODD_RENAME|FS_REVAL_DOT|FS_BINARY_MOUNTDATA, }; #ifdef CONFIG_NFS_V4 @@ -1391,8 +1407,8 @@ inode->i_sb->s_id, (long long)NFS_FILEID(inode), state); - list_del(&state->inode_states); - nfs4_put_open_state(state); + BUG_ON(atomic_read(&state->count) != 1); + nfs4_close_state(state, state->state); } /* Now call standard NFS clear_inode() code */ nfs_clear_inode(inode); @@ -1472,17 +1488,19 @@ down_write(&clp->cl_sem); if (clp->cl_rpcclient == NULL) { xprt = xprt_create_proto(proto, &server->addr, &timeparms); - if (xprt == NULL) { + if (IS_ERR(xprt)) { up_write(&clp->cl_sem); printk(KERN_WARNING "NFS: cannot create RPC transport.\n"); + err = PTR_ERR(xprt); goto out_fail; } clnt = rpc_create_client(xprt, server->hostname, &nfs_program, server->rpc_ops->version, authflavour); - if (clnt == NULL) { + if (IS_ERR(clnt)) { up_write(&clp->cl_sem); printk(KERN_WARNING "NFS: cannot create RPC client.\n"); xprt_destroy(xprt); + err = PTR_ERR(clnt); goto out_fail; } clnt->cl_chatty = 1; @@ -1495,14 +1513,17 @@ clear_bit(NFS4CLNT_OK, &clp->cl_state); list_add_tail(&server->nfs4_siblings, &clp->cl_superblocks); clnt = rpc_clone_client(clp->cl_rpcclient); - server->nfs4_state = clp; + if (!IS_ERR(clnt)) + server->nfs4_state = clp; up_write(&clp->cl_sem); clp = NULL; - if (clnt == NULL) { + if (IS_ERR(clnt)) { printk(KERN_WARNING "NFS: cannot create RPC client.\n"); + err = PTR_ERR(clnt); goto out_remove_list; } + err = -ENOMEM; if (server->nfs4_state->cl_idmap == NULL) { printk(KERN_WARNING "NFS: failed to create idmapper.\n"); goto out_shutdown; @@ -1601,7 +1622,7 @@ if (data->version != NFS4_MOUNT_VERSION) { printk("nfs warning: mount version %s than kernel\n", - data->version < NFS_MOUNT_VERSION ? "older" : "newer"); + data->version < NFS4_MOUNT_VERSION ? "older" : "newer"); } p = nfs_copy_user_string(NULL, &data->hostname, 256); @@ -1666,7 +1687,7 @@ .name = "nfs4", .get_sb = nfs4_get_sb, .kill_sb = nfs_kill_super, - .fs_flags = FS_ODD_RENAME|FS_REVAL_DOT, + .fs_flags = FS_ODD_RENAME|FS_REVAL_DOT|FS_BINARY_MOUNTDATA, }; #define nfs4_zero_state(nfsi) \ @@ -1718,6 +1739,7 @@ INIT_LIST_HEAD(&nfsi->dirty); INIT_LIST_HEAD(&nfsi->commit); INIT_RADIX_TREE(&nfsi->nfs_page_tree, GFP_ATOMIC); + atomic_set(&nfsi->data_updates, 0); nfsi->ndirty = 0; nfsi->ncommit = 0; nfsi->npages = 0; diff -Nru a/fs/nfs/mount_clnt.c b/fs/nfs/mount_clnt.c --- a/fs/nfs/mount_clnt.c Sun Mar 14 14:20:06 2004 +++ b/fs/nfs/mount_clnt.c Sun Mar 14 14:20:06 2004 @@ -57,8 +57,9 @@ (unsigned)ntohl(addr->sin_addr.s_addr), path); sprintf(hostname, "%u.%u.%u.%u", NIPQUAD(addr->sin_addr.s_addr)); - if (!(mnt_clnt = mnt_create(hostname, addr, version, protocol))) - return -EACCES; + mnt_clnt = mnt_create(hostname, addr, version, protocol); + if (IS_ERR(mnt_clnt)) + return PTR_ERR(mnt_clnt); call = (version == NFS_MNT3_VERSION) ? MOUNTPROC3_MNT : MNTPROC_MNT; status = rpc_call(mnt_clnt, call, path, &result, 0); @@ -72,13 +73,14 @@ struct rpc_xprt *xprt; struct rpc_clnt *clnt; - if (!(xprt = xprt_create_proto(protocol, srvaddr, NULL))) - return NULL; + xprt = xprt_create_proto(protocol, srvaddr, NULL); + if (IS_ERR(xprt)) + return (struct rpc_clnt *)xprt; clnt = rpc_create_client(xprt, hostname, &mnt_program, version, - RPC_AUTH_NULL); - if (!clnt) { + RPC_AUTH_UNIX); + if (IS_ERR(clnt)) { xprt_destroy(xprt); } else { clnt->cl_softrtry = 1; diff -Nru a/fs/nfs/nfs2xdr.c b/fs/nfs/nfs2xdr.c --- a/fs/nfs/nfs2xdr.c Sun Mar 14 14:20:07 2004 +++ b/fs/nfs/nfs2xdr.c Sun Mar 14 14:20:07 2004 @@ -36,33 +36,33 @@ * Declare the space requirements for NFS arguments and replies as * number of 32bit-words */ -#define NFS_fhandle_sz 8 -#define NFS_sattr_sz 8 -#define NFS_filename_sz 1+(NFS2_MAXNAMLEN>>2) -#define NFS_path_sz 1+(NFS2_MAXPATHLEN>>2) -#define NFS_fattr_sz 17 -#define NFS_info_sz 5 -#define NFS_entry_sz NFS_filename_sz+3 +#define NFS_fhandle_sz (8) +#define NFS_sattr_sz (8) +#define NFS_filename_sz (1+(NFS2_MAXNAMLEN>>2)) +#define NFS_path_sz (1+(NFS2_MAXPATHLEN>>2)) +#define NFS_fattr_sz (17) +#define NFS_info_sz (5) +#define NFS_entry_sz (NFS_filename_sz+3) -#define NFS_diropargs_sz NFS_fhandle_sz+NFS_filename_sz -#define NFS_sattrargs_sz NFS_fhandle_sz+NFS_sattr_sz -#define NFS_readlinkargs_sz NFS_fhandle_sz -#define NFS_readargs_sz NFS_fhandle_sz+3 -#define NFS_writeargs_sz NFS_fhandle_sz+4 -#define NFS_createargs_sz NFS_diropargs_sz+NFS_sattr_sz -#define NFS_renameargs_sz NFS_diropargs_sz+NFS_diropargs_sz -#define NFS_linkargs_sz NFS_fhandle_sz+NFS_diropargs_sz -#define NFS_symlinkargs_sz NFS_diropargs_sz+NFS_path_sz+NFS_sattr_sz -#define NFS_readdirargs_sz NFS_fhandle_sz+2 +#define NFS_diropargs_sz (NFS_fhandle_sz+NFS_filename_sz) +#define NFS_sattrargs_sz (NFS_fhandle_sz+NFS_sattr_sz) +#define NFS_readlinkargs_sz (NFS_fhandle_sz) +#define NFS_readargs_sz (NFS_fhandle_sz+3) +#define NFS_writeargs_sz (NFS_fhandle_sz+4) +#define NFS_createargs_sz (NFS_diropargs_sz+NFS_sattr_sz) +#define NFS_renameargs_sz (NFS_diropargs_sz+NFS_diropargs_sz) +#define NFS_linkargs_sz (NFS_fhandle_sz+NFS_diropargs_sz) +#define NFS_symlinkargs_sz (NFS_diropargs_sz+NFS_path_sz+NFS_sattr_sz) +#define NFS_readdirargs_sz (NFS_fhandle_sz+2) -#define NFS_attrstat_sz 1+NFS_fattr_sz -#define NFS_diropres_sz 1+NFS_fhandle_sz+NFS_fattr_sz -#define NFS_readlinkres_sz 1 -#define NFS_readres_sz 1+NFS_fattr_sz+1 -#define NFS_writeres_sz NFS_attrstat_sz -#define NFS_stat_sz 1 -#define NFS_readdirres_sz 1 -#define NFS_statfsres_sz 1+NFS_info_sz +#define NFS_attrstat_sz (1+NFS_fattr_sz) +#define NFS_diropres_sz (1+NFS_fhandle_sz+NFS_fattr_sz) +#define NFS_readlinkres_sz (1) +#define NFS_readres_sz (1+NFS_fattr_sz+1) +#define NFS_writeres_sz (NFS_attrstat_sz) +#define NFS_stat_sz (1) +#define NFS_readdirres_sz (1) +#define NFS_statfsres_sz (1+NFS_info_sz) /* * Common NFS XDR functions as inlines diff -Nru a/fs/nfs/nfs3proc.c b/fs/nfs/nfs3proc.c --- a/fs/nfs/nfs3proc.c Sun Mar 14 14:20:07 2004 +++ b/fs/nfs/nfs3proc.c Sun Mar 14 14:20:07 2004 @@ -68,20 +68,6 @@ return 1; } -static void -nfs3_write_refresh_inode(struct inode *inode, struct nfs_fattr *fattr) -{ - if (fattr->valid & NFS_ATTR_FATTR) { - if (!(fattr->valid & NFS_ATTR_WCC)) { - fattr->pre_size = NFS_CACHE_ISIZE(inode); - fattr->pre_mtime = NFS_CACHE_MTIME(inode); - fattr->pre_ctime = NFS_CACHE_CTIME(inode); - fattr->valid |= NFS_ATTR_WCC; - } - nfs_refresh_inode(inode, fattr); - } -} - static struct rpc_cred * nfs_cred(struct inode *inode, struct file *filp) { @@ -99,14 +85,18 @@ */ static int nfs3_proc_get_root(struct nfs_server *server, struct nfs_fh *fhandle, - struct nfs_fattr *fattr) + struct nfs_fsinfo *info) { int status; - dprintk("NFS call getroot\n"); - fattr->valid = 0; - status = rpc_call(server->client, NFS3PROC_GETATTR, fhandle, fattr, 0); - dprintk("NFS reply getroot\n"); + dprintk("%s: call fsinfo\n", __FUNCTION__); + info->fattr->valid = 0; + status = rpc_call(server->client_sys, NFS3PROC_FSINFO, fhandle, info, 0); + dprintk("%s: reply fsinfo %d\n", __FUNCTION__, status); + if (!(info->fattr->valid & NFS_ATTR_FATTR)) { + status = rpc_call(server->client_sys, NFS3PROC_GETATTR, fhandle, info->fattr, 0); + dprintk("%s: reply getattr %d\n", __FUNCTION__, status); + } return status; } @@ -280,7 +270,7 @@ msg.rpc_cred = nfs_cred(inode, filp); status = rpc_call_sync(NFS_CLIENT(inode), &msg, rpcflags); if (status >= 0) - nfs3_write_refresh_inode(inode, fattr); + nfs_refresh_inode(inode, fattr); dprintk("NFS reply write: %d\n", status); return status < 0? status : wdata->res.count; } @@ -303,7 +293,7 @@ msg.rpc_cred = nfs_cred(inode, filp); status = rpc_call_sync(NFS_CLIENT(inode), &msg, 0); if (status >= 0) - nfs3_write_refresh_inode(inode, fattr); + nfs_refresh_inode(inode, fattr); dprintk("NFS reply commit: %d\n", status); return status; } @@ -777,12 +767,13 @@ static void nfs3_write_done(struct rpc_task *task) { - struct nfs_write_data *data = (struct nfs_write_data *) task->tk_calldata; + struct nfs_write_data *data; if (nfs3_async_handle_jukebox(task)) return; + data = (struct nfs_write_data *)task->tk_calldata; if (task->tk_status >= 0) - nfs3_write_refresh_inode(data->inode, data->res.fattr); + nfs_refresh_inode(data->inode, data->res.fattr); nfs_writeback_done(task); } @@ -835,12 +826,13 @@ static void nfs3_commit_done(struct rpc_task *task) { - struct nfs_write_data *data = (struct nfs_write_data *) task->tk_calldata; + struct nfs_write_data *data; if (nfs3_async_handle_jukebox(task)) return; + data = (struct nfs_write_data *)task->tk_calldata; if (task->tk_status >= 0) - nfs3_write_refresh_inode(data->inode, data->res.fattr); + nfs_refresh_inode(data->inode, data->res.fattr); nfs_commit_done(task); } diff -Nru a/fs/nfs/nfs3xdr.c b/fs/nfs/nfs3xdr.c --- a/fs/nfs/nfs3xdr.c Sun Mar 14 14:20:08 2004 +++ b/fs/nfs/nfs3xdr.c Sun Mar 14 14:20:08 2004 @@ -33,51 +33,51 @@ * Declare the space requirements for NFS arguments and replies as * number of 32bit-words */ -#define NFS3_fhandle_sz 1+16 -#define NFS3_fh_sz NFS3_fhandle_sz /* shorthand */ -#define NFS3_sattr_sz 15 -#define NFS3_filename_sz 1+(NFS3_MAXNAMLEN>>2) -#define NFS3_path_sz 1+(NFS3_MAXPATHLEN>>2) -#define NFS3_fattr_sz 21 -#define NFS3_wcc_attr_sz 6 -#define NFS3_pre_op_attr_sz 1+NFS3_wcc_attr_sz -#define NFS3_post_op_attr_sz 1+NFS3_fattr_sz -#define NFS3_wcc_data_sz NFS3_pre_op_attr_sz+NFS3_post_op_attr_sz +#define NFS3_fhandle_sz (1+16) +#define NFS3_fh_sz (NFS3_fhandle_sz) /* shorthand */ +#define NFS3_sattr_sz (15) +#define NFS3_filename_sz (1+(NFS3_MAXNAMLEN>>2)) +#define NFS3_path_sz (1+(NFS3_MAXPATHLEN>>2)) +#define NFS3_fattr_sz (21) +#define NFS3_wcc_attr_sz (6) +#define NFS3_pre_op_attr_sz (1+NFS3_wcc_attr_sz) +#define NFS3_post_op_attr_sz (1+NFS3_fattr_sz) +#define NFS3_wcc_data_sz (NFS3_pre_op_attr_sz+NFS3_post_op_attr_sz) #define NFS3_fsstat_sz #define NFS3_fsinfo_sz #define NFS3_pathconf_sz -#define NFS3_entry_sz NFS3_filename_sz+3 +#define NFS3_entry_sz (NFS3_filename_sz+3) -#define NFS3_sattrargs_sz NFS3_fh_sz+NFS3_sattr_sz+3 -#define NFS3_diropargs_sz NFS3_fh_sz+NFS3_filename_sz -#define NFS3_accessargs_sz NFS3_fh_sz+1 -#define NFS3_readlinkargs_sz NFS3_fh_sz -#define NFS3_readargs_sz NFS3_fh_sz+3 -#define NFS3_writeargs_sz NFS3_fh_sz+5 -#define NFS3_createargs_sz NFS3_diropargs_sz+NFS3_sattr_sz -#define NFS3_mkdirargs_sz NFS3_diropargs_sz+NFS3_sattr_sz -#define NFS3_symlinkargs_sz NFS3_diropargs_sz+NFS3_path_sz+NFS3_sattr_sz -#define NFS3_mknodargs_sz NFS3_diropargs_sz+2+NFS3_sattr_sz -#define NFS3_renameargs_sz NFS3_diropargs_sz+NFS3_diropargs_sz -#define NFS3_linkargs_sz NFS3_fh_sz+NFS3_diropargs_sz -#define NFS3_readdirargs_sz NFS3_fh_sz+2 -#define NFS3_commitargs_sz NFS3_fh_sz+3 +#define NFS3_sattrargs_sz (NFS3_fh_sz+NFS3_sattr_sz+3) +#define NFS3_diropargs_sz (NFS3_fh_sz+NFS3_filename_sz) +#define NFS3_accessargs_sz (NFS3_fh_sz+1) +#define NFS3_readlinkargs_sz (NFS3_fh_sz) +#define NFS3_readargs_sz (NFS3_fh_sz+3) +#define NFS3_writeargs_sz (NFS3_fh_sz+5) +#define NFS3_createargs_sz (NFS3_diropargs_sz+NFS3_sattr_sz) +#define NFS3_mkdirargs_sz (NFS3_diropargs_sz+NFS3_sattr_sz) +#define NFS3_symlinkargs_sz (NFS3_diropargs_sz+NFS3_path_sz+NFS3_sattr_sz) +#define NFS3_mknodargs_sz (NFS3_diropargs_sz+2+NFS3_sattr_sz) +#define NFS3_renameargs_sz (NFS3_diropargs_sz+NFS3_diropargs_sz) +#define NFS3_linkargs_sz (NFS3_fh_sz+NFS3_diropargs_sz) +#define NFS3_readdirargs_sz (NFS3_fh_sz+2) +#define NFS3_commitargs_sz (NFS3_fh_sz+3) -#define NFS3_attrstat_sz 1+NFS3_fattr_sz -#define NFS3_wccstat_sz 1+NFS3_wcc_data_sz -#define NFS3_lookupres_sz 1+NFS3_fh_sz+(2 * NFS3_post_op_attr_sz) -#define NFS3_accessres_sz 1+NFS3_post_op_attr_sz+1 -#define NFS3_readlinkres_sz 1+NFS3_post_op_attr_sz -#define NFS3_readres_sz 1+NFS3_post_op_attr_sz+3 -#define NFS3_writeres_sz 1+NFS3_wcc_data_sz+4 -#define NFS3_createres_sz 1+NFS3_fh_sz+NFS3_post_op_attr_sz+NFS3_wcc_data_sz -#define NFS3_renameres_sz 1+(2 * NFS3_wcc_data_sz) -#define NFS3_linkres_sz 1+NFS3_post_op_attr_sz+NFS3_wcc_data_sz -#define NFS3_readdirres_sz 1+NFS3_post_op_attr_sz+2 -#define NFS3_fsstatres_sz 1+NFS3_post_op_attr_sz+13 -#define NFS3_fsinfores_sz 1+NFS3_post_op_attr_sz+12 -#define NFS3_pathconfres_sz 1+NFS3_post_op_attr_sz+6 -#define NFS3_commitres_sz 1+NFS3_wcc_data_sz+2 +#define NFS3_attrstat_sz (1+NFS3_fattr_sz) +#define NFS3_wccstat_sz (1+NFS3_wcc_data_sz) +#define NFS3_lookupres_sz (1+NFS3_fh_sz+(2 * NFS3_post_op_attr_sz)) +#define NFS3_accessres_sz (1+NFS3_post_op_attr_sz+1) +#define NFS3_readlinkres_sz (1+NFS3_post_op_attr_sz) +#define NFS3_readres_sz (1+NFS3_post_op_attr_sz+3) +#define NFS3_writeres_sz (1+NFS3_wcc_data_sz+4) +#define NFS3_createres_sz (1+NFS3_fh_sz+NFS3_post_op_attr_sz+NFS3_wcc_data_sz) +#define NFS3_renameres_sz (1+(2 * NFS3_wcc_data_sz)) +#define NFS3_linkres_sz (1+NFS3_post_op_attr_sz+NFS3_wcc_data_sz) +#define NFS3_readdirres_sz (1+NFS3_post_op_attr_sz+2) +#define NFS3_fsstatres_sz (1+NFS3_post_op_attr_sz+13) +#define NFS3_fsinfores_sz (1+NFS3_post_op_attr_sz+12) +#define NFS3_pathconfres_sz (1+NFS3_post_op_attr_sz+6) +#define NFS3_commitres_sz (1+NFS3_wcc_data_sz+2) /* * Map file type to S_IFMT bits @@ -103,9 +103,7 @@ static inline u32 * xdr_encode_fhandle(u32 *p, struct nfs_fh *fh) { - *p++ = htonl(fh->size); - memcpy(p, fh->data, fh->size); - return p + XDR_QUADLEN(fh->size); + return xdr_encode_array(p, fh->data, fh->size); } static inline u32 * diff -Nru a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c --- a/fs/nfs/nfs4proc.c Sun Mar 14 14:20:08 2004 +++ b/fs/nfs/nfs4proc.c Sun Mar 14 14:20:08 2004 @@ -54,12 +54,24 @@ #define GET_OP(cp,name) &cp->ops[cp->req_nops].u.name #define OPNUM(cp) cp->ops[cp->req_nops].opnum +static int nfs4_proc_fsinfo(struct nfs_server *, struct nfs_fh *, struct nfs_fsinfo *); static int nfs4_async_handle_error(struct rpc_task *, struct nfs_server *); extern u32 *nfs4_decode_dirent(u32 *p, struct nfs_entry *entry, int plus); extern struct rpc_procinfo nfs4_procedures[]; extern nfs4_stateid zero_stateid; +/* Prevent leaks of NFSv4 errors into userland */ +static inline int nfs4_map_errors(int err) +{ + if (err < -1000) { + printk(KERN_WARNING "%s could not handle NFSv4 error %d\n", + __FUNCTION__, -err); + return -EIO; + } + return err; +} + static void nfs4_setup_compound(struct nfs4_compound *cp, struct nfs4_op *ops, struct nfs_server *server, char *tag) @@ -505,6 +517,8 @@ status = rpc_call_sync(server->client, &msg, 0); nfs4_increment_seqid(status, sp); + if (status == 0) + memcpy(&state->stateid, &o_res.stateid, sizeof(state->stateid)); /* Update the inode attributes */ nfs_refresh_inode(inode, &fattr); return status; @@ -689,12 +703,12 @@ retry: fattr->valid = 0; - if (state) + if (sattr->ia_valid & ATTR_SIZE) nfs4_copy_stateid(&arg.stateid, state, 0); - else + else memcpy(&arg.stateid, &zero_stateid, sizeof(arg.stateid)); - status = rpc_call_sync(server->client, &msg, 0); + status = rpc_call_sync(server->client, &msg, 0); if (status) { status = nfs4_handle_error(server, status); if (!status) @@ -822,10 +836,11 @@ static int nfs4_proc_get_root(struct nfs_server *server, struct nfs_fh *fhandle, - struct nfs_fattr *fattr) + struct nfs_fsinfo *info) { struct nfs4_compound compound; struct nfs4_op ops[4]; + struct nfs_fattr * fattr = info->fattr; unsigned char * p; struct qstr q; int status; @@ -869,7 +884,9 @@ break; } out: - return status; + if (status) + return nfs4_map_errors(status); + return nfs4_proc_fsinfo(server, fhandle, info); } static int @@ -883,7 +900,7 @@ nfs4_setup_compound(&compound, ops, NFS_SERVER(inode), "getattr"); nfs4_setup_putfh(&compound, NFS_FH(inode)); nfs4_setup_getattr(&compound, fattr); - return nfs4_call_compound(&compound, NULL, 0); + return nfs4_map_errors(nfs4_call_compound(&compound, NULL, 0)); } /* @@ -969,7 +986,7 @@ if (status >= 0) status = nfs_refresh_inode(dir, &dir_attr); - return status; + return nfs4_map_errors(status); } static int @@ -1016,7 +1033,7 @@ else if (req_access != resp_access) status = -EACCES; } - return status; + return nfs4_map_errors(status); } /* @@ -1052,7 +1069,7 @@ nfs4_setup_compound(&compound, ops, NFS_SERVER(inode), "readlink"); nfs4_setup_putfh(&compound, NFS_FH(inode)); nfs4_setup_readlink(&compound, PAGE_CACHE_SIZE, &page); - return nfs4_call_compound(&compound, NULL, 0); + return nfs4_map_errors(nfs4_call_compound(&compound, NULL, 0)); } static int @@ -1088,14 +1105,10 @@ fattr->valid = 0; status = rpc_call_sync(server->client, &msg, flags); - if (!status) { + if (!status) renew_lease(server, timestamp); - /* Check cache consistency */ - if (fattr->change_attr != NFS_CHANGE_ATTR(inode)) - nfs_zap_caches(inode); - } dprintk("NFS reply read: %d\n", status); - return status; + return nfs4_map_errors(status); } static int @@ -1130,9 +1143,8 @@ fattr->valid = 0; status = rpc_call_sync(server->client, &msg, rpcflags); - NFS_CACHEINV(inode); dprintk("NFS reply write: %d\n", status); - return status; + return nfs4_map_errors(status); } static int @@ -1167,7 +1179,7 @@ fattr->valid = 0; status = rpc_call_sync(server->client, &msg, 0); dprintk("NFS reply commit: %d\n", status); - return status; + return nfs4_map_errors(status); } /* @@ -1234,7 +1246,7 @@ process_cinfo(&dir_cinfo, &dir_attr); nfs_refresh_inode(dir, &dir_attr); } - return status; + return nfs4_map_errors(status); } struct unlink_desc { @@ -1312,7 +1324,7 @@ nfs_refresh_inode(old_dir, &old_dir_attr); nfs_refresh_inode(new_dir, &new_dir_attr); } - return status; + return nfs4_map_errors(status); } static int @@ -1342,7 +1354,7 @@ nfs_refresh_inode(dir, &dir_attr); nfs_refresh_inode(inode, &fattr); } - return status; + return nfs4_map_errors(status); } static int @@ -1373,7 +1385,7 @@ process_cinfo(&dir_cinfo, &dir_attr); nfs_refresh_inode(dir, &dir_attr); } - return status; + return nfs4_map_errors(status); } static int @@ -1403,7 +1415,7 @@ process_cinfo(&dir_cinfo, &dir_attr); nfs_refresh_inode(dir, &dir_attr); } - return status; + return nfs4_map_errors(status); } static int @@ -1421,9 +1433,11 @@ nfs4_setup_putfh(&compound, NFS_FH(dir)); nfs4_setup_readdir(&compound, cookie, NFS_COOKIEVERF(dir), &page, count, dentry); status = nfs4_call_compound(&compound, cred, 0); + if (status == 0) + memcpy(NFS_COOKIEVERF(dir), ops[1].u.readdir.rd_resp_verifier.data, NFS4_VERIFIER_SIZE); unlock_kernel(); - return status; + return nfs4_map_errors(status); } static int @@ -1453,7 +1467,7 @@ process_cinfo(&dir_cinfo, &dir_attr); nfs_refresh_inode(dir, &dir_attr); } - return status; + return nfs4_map_errors(status); } static int @@ -1463,11 +1477,10 @@ struct nfs4_compound compound; struct nfs4_op ops[2]; - memset(fsstat, 0, sizeof(*fsstat)); nfs4_setup_compound(&compound, ops, server, "statfs"); nfs4_setup_putfh(&compound, fhandle); nfs4_setup_statfs(&compound, fsstat); - return nfs4_call_compound(&compound, NULL, 0); + return nfs4_map_errors(nfs4_call_compound(&compound, NULL, 0)); } static int @@ -1480,8 +1493,7 @@ .rpc_resp = fsinfo, }; - memset(fsinfo, 0, sizeof(*fsinfo)); - return rpc_call_sync(server->client, &msg, 0); + return nfs4_map_errors(rpc_call_sync(server->client, &msg, 0)); } static int @@ -1491,11 +1503,10 @@ struct nfs4_compound compound; struct nfs4_op ops[2]; - memset(pathconf, 0, sizeof(*pathconf)); nfs4_setup_compound(&compound, ops, server, "statfs"); nfs4_setup_putfh(&compound, fhandle); nfs4_setup_pathconf(&compound, pathconf); - return nfs4_call_compound(&compound, NULL, 0); + return nfs4_map_errors(nfs4_call_compound(&compound, NULL, 0)); } static void @@ -1517,7 +1528,6 @@ { struct nfs_read_data *data = (struct nfs_read_data *) task->tk_calldata; struct inode *inode = data->inode; - struct nfs_fattr *fattr = data->res.fattr; if (nfs4_async_handle_error(task, NFS_SERVER(inode)) == -EAGAIN) { task->tk_action = nfs4_restart_read; @@ -1525,11 +1535,6 @@ } if (task->tk_status > 0) renew_lease(NFS_SERVER(inode), data->timestamp); - /* Check cache consistency */ - if (fattr->change_attr != NFS_CHANGE_ATTR(inode)) - nfs_zap_caches(inode); - if (fattr->bitmap[1] & FATTR4_WORD1_TIME_ACCESS) - inode->i_atime = fattr->atime; /* Call back common NFS readpage processing */ nfs_readpage_result(task); } @@ -1577,21 +1582,6 @@ } static void -nfs4_write_refresh_inode(struct inode *inode, struct nfs_fattr *fattr) -{ - /* Check cache consistency */ - if (fattr->pre_change_attr != NFS_CHANGE_ATTR(inode)) - nfs_zap_caches(inode); - NFS_CHANGE_ATTR(inode) = fattr->change_attr; - if (fattr->bitmap[1] & FATTR4_WORD1_SPACE_USED) - inode->i_blocks = (fattr->du.nfs3.used + 511) >> 9; - if (fattr->bitmap[1] & FATTR4_WORD1_TIME_METADATA) - inode->i_ctime = fattr->ctime; - if (fattr->bitmap[1] & FATTR4_WORD1_TIME_MODIFY) - inode->i_mtime = fattr->mtime; -} - -static void nfs4_restart_write(struct rpc_task *task) { struct nfs_write_data *data = (struct nfs_write_data *)task->tk_calldata; @@ -1617,7 +1607,6 @@ } if (task->tk_status >= 0) renew_lease(NFS_SERVER(inode), data->timestamp); - nfs4_write_refresh_inode(inode, data->res.fattr); /* Call back common NFS writeback processing */ nfs_writeback_done(task); } @@ -1684,7 +1673,6 @@ task->tk_action = nfs4_restart_write; return; } - nfs4_write_refresh_inode(inode, data->res.fattr); /* Call back common NFS writeback processing */ nfs_commit_done(task); } @@ -1807,6 +1795,7 @@ if (filp->f_mode & FMODE_WRITE) { lock_kernel(); nfs_set_mmcred(inode, state->owner->so_cred); + nfs_begin_data_update(inode); unlock_kernel(); } filp->private_data = state; @@ -1823,6 +1812,11 @@ if (state) nfs4_close_state(state, filp->f_mode); + if (filp->f_mode & FMODE_WRITE) { + lock_kernel(); + nfs_end_data_update(inode); + unlock_kernel(); + } return 0; } @@ -1850,7 +1844,7 @@ { struct nfs4_client *clp = server->nfs4_state; - if (!clp) + if (!clp || task->tk_status >= 0) return 0; switch(task->tk_status) { case -NFS4ERR_STALE_CLIENTID: @@ -1869,6 +1863,7 @@ task->tk_status = 0; return -EAGAIN; } + task->tk_status = nfs4_map_errors(task->tk_status); return 0; } @@ -1946,16 +1941,9 @@ break; case -NFS4ERR_OLD_STATEID: ret = 0; - break; - default: - if (errorcode <= -1000) { - printk(KERN_WARNING "%s could not handle NFSv4 error %d\n", - __FUNCTION__, -errorcode); - ret = -EIO; - } } /* We failed to handle the error */ - return ret; + return nfs4_map_errors(ret); } @@ -2130,7 +2118,7 @@ if (lsp) nfs4_put_lock_state(lsp); up(&state->lock_sema); - return status; + return nfs4_map_errors(status); } int @@ -2175,7 +2163,7 @@ nfs4_put_lock_state(lsp); out: up(&state->lock_sema); - return status; + return nfs4_map_errors(status); } static int @@ -2251,7 +2239,7 @@ nfs4_put_lock_state(lsp); out: up(&state->lock_sema); - return status; + return nfs4_map_errors(status); } static int diff -Nru a/fs/nfs/nfs4state.c b/fs/nfs/nfs4state.c --- a/fs/nfs/nfs4state.c Sun Mar 14 14:20:05 2004 +++ b/fs/nfs/nfs4state.c Sun Mar 14 14:20:05 2004 @@ -411,18 +411,20 @@ return state; } -void -nfs4_put_open_state(struct nfs4_state *state) +static void +__nfs4_put_open_state(struct nfs4_state *state) { struct inode *inode = state->inode; struct nfs4_state_owner *owner = state->owner; int status = 0; - if (!atomic_dec_and_lock(&state->count, &inode->i_lock)) + if (!atomic_dec_and_lock(&state->count, &inode->i_lock)) { + up(&owner->so_sema); return; - list_del(&state->inode_states); + } + if (!list_empty(&state->inode_states)) + list_del(&state->inode_states); spin_unlock(&inode->i_lock); - down(&owner->so_sema); list_del(&state->open_states); if (state->state != 0) { do { @@ -440,6 +442,13 @@ } void +nfs4_put_open_state(struct nfs4_state *state) +{ + down(&state->owner->so_sema); + __nfs4_put_open_state(state); +} + +void nfs4_close_state(struct nfs4_state *state, mode_t mode) { struct inode *inode = state->inode; @@ -479,8 +488,7 @@ status = nfs4_handle_error(NFS_SERVER(inode), status); down(&owner->so_sema); } while (!status); - up(&owner->so_sema); - nfs4_put_open_state(state); + __nfs4_put_open_state(state); } /* @@ -790,7 +798,7 @@ restart_loop: spin_lock(&clp->cl_lock); list_for_each_entry(sp, &clp->cl_state_owners, so_list) { - if (sp->so_generation - generation <= 0) + if (sp->so_generation - generation >= 0) continue; atomic_inc(&sp->so_count); spin_unlock(&clp->cl_lock); diff -Nru a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c --- a/fs/nfs/nfs4xdr.c Sun Mar 14 14:20:08 2004 +++ b/fs/nfs/nfs4xdr.c Sun Mar 14 14:20:08 2004 @@ -69,84 +69,84 @@ /* lock,open owner id: * we currently use size 1 (u32) out of (NFS4_OPAQUE_LIMIT >> 2) */ -#define owner_id_maxsz 1 + 1 -#define compound_encode_hdr_maxsz 3 + (NFS4_MAXTAGLEN >> 2) -#define compound_decode_hdr_maxsz 2 + (NFS4_MAXTAGLEN >> 2) -#define op_encode_hdr_maxsz 1 -#define op_decode_hdr_maxsz 2 -#define encode_putfh_maxsz op_encode_hdr_maxsz + 1 + \ - (NFS4_FHSIZE >> 2) -#define decode_putfh_maxsz op_decode_hdr_maxsz -#define encode_putrootfh_maxsz op_encode_hdr_maxsz -#define decode_putrootfh_maxsz op_decode_hdr_maxsz -#define encode_getfh_maxsz op_encode_hdr_maxsz -#define decode_getfh_maxsz op_decode_hdr_maxsz + 1 + \ - (NFS4_FHSIZE >> 2) -#define encode_getattr_maxsz op_encode_hdr_maxsz + 3 -#define nfs4_fattr_bitmap_maxsz 26 + 2 * ((NFS4_MAXNAMLEN +1) >> 2) -#define decode_getattr_maxsz op_decode_hdr_maxsz + 3 + \ - nfs4_fattr_bitmap_maxsz -#define encode_savefh_maxsz op_encode_hdr_maxsz -#define decode_savefh_maxsz op_decode_hdr_maxsz -#define encode_restorefh_maxsz op_encode_hdr_maxsz -#define decode_restorefh_maxsz op_decode_hdr_maxsz -#define encode_read_getattr_maxsz op_encode_hdr_maxsz + 2 -#define decode_read_getattr_maxsz op_decode_hdr_maxsz + 8 -#define encode_pre_write_getattr_maxsz op_encode_hdr_maxsz + 2 -#define decode_pre_write_getattr_maxsz op_decode_hdr_maxsz + 5 -#define encode_post_write_getattr_maxsz op_encode_hdr_maxsz + 2 -#define decode_post_write_getattr_maxsz op_decode_hdr_maxsz + 13 -#define encode_fsinfo_maxsz op_encode_hdr_maxsz + 2 -#define decode_fsinfo_maxsz op_decode_hdr_maxsz + 11 -#define encode_renew_maxsz op_encode_hdr_maxsz + 3 -#define decode_renew_maxsz op_decode_hdr_maxsz +#define owner_id_maxsz (1 + 1) +#define compound_encode_hdr_maxsz (3 + (NFS4_MAXTAGLEN >> 2)) +#define compound_decode_hdr_maxsz (3 + (NFS4_MAXTAGLEN >> 2)) +#define op_encode_hdr_maxsz (1) +#define op_decode_hdr_maxsz (2) +#define encode_putfh_maxsz (op_encode_hdr_maxsz + 1 + \ + (NFS4_FHSIZE >> 2)) +#define decode_putfh_maxsz (op_decode_hdr_maxsz) +#define encode_putrootfh_maxsz (op_encode_hdr_maxsz) +#define decode_putrootfh_maxsz (op_decode_hdr_maxsz) +#define encode_getfh_maxsz (op_encode_hdr_maxsz) +#define decode_getfh_maxsz (op_decode_hdr_maxsz + 1 + \ + (NFS4_FHSIZE >> 2)) +#define encode_getattr_maxsz (op_encode_hdr_maxsz + 3) +#define nfs4_fattr_bitmap_maxsz (26 + 2 * ((NFS4_MAXNAMLEN +1) >> 2)) +#define decode_getattr_maxsz (op_decode_hdr_maxsz + 3 + \ + nfs4_fattr_bitmap_maxsz) +#define encode_savefh_maxsz (op_encode_hdr_maxsz) +#define decode_savefh_maxsz (op_decode_hdr_maxsz) +#define encode_restorefh_maxsz (op_encode_hdr_maxsz) +#define decode_restorefh_maxsz (op_decode_hdr_maxsz) +#define encode_read_getattr_maxsz (op_encode_hdr_maxsz + 2) +#define decode_read_getattr_maxsz (op_decode_hdr_maxsz + 8) +#define encode_pre_write_getattr_maxsz (op_encode_hdr_maxsz + 2) +#define decode_pre_write_getattr_maxsz (op_decode_hdr_maxsz + 5) +#define encode_post_write_getattr_maxsz (op_encode_hdr_maxsz + 2) +#define decode_post_write_getattr_maxsz (op_decode_hdr_maxsz + 13) +#define encode_fsinfo_maxsz (op_encode_hdr_maxsz + 2) +#define decode_fsinfo_maxsz (op_decode_hdr_maxsz + 11) +#define encode_renew_maxsz (op_encode_hdr_maxsz + 3) +#define decode_renew_maxsz (op_decode_hdr_maxsz) #define encode_setclientid_maxsz \ - op_encode_hdr_maxsz + \ + (op_encode_hdr_maxsz + \ 4 /*server->ip_addr*/ + \ 1 /*Netid*/ + \ 6 /*uaddr*/ + \ - 6 + (NFS4_VERIFIER_SIZE >> 2) + 6 + (NFS4_VERIFIER_SIZE >> 2)) #define decode_setclientid_maxsz \ - op_decode_hdr_maxsz + \ + (op_decode_hdr_maxsz + \ 2 + \ - 1024 /* large value for CLID_INUSE */ + 1024) /* large value for CLID_INUSE */ #define encode_setclientid_confirm_maxsz \ - op_encode_hdr_maxsz + \ - 3 + (NFS4_VERIFIER_SIZE >> 2) + (op_encode_hdr_maxsz + \ + 3 + (NFS4_VERIFIER_SIZE >> 2)) #define decode_setclientid_confirm_maxsz \ - op_decode_hdr_maxsz + (op_decode_hdr_maxsz) -#define NFS4_enc_compound_sz 1024 /* XXX: large enough? */ -#define NFS4_dec_compound_sz 1024 /* XXX: large enough? */ -#define NFS4_enc_read_sz compound_encode_hdr_maxsz + \ +#define NFS4_enc_compound_sz (1024) /* XXX: large enough? */ +#define NFS4_dec_compound_sz (1024) /* XXX: large enough? */ +#define NFS4_enc_read_sz (compound_encode_hdr_maxsz + \ encode_putfh_maxsz + \ encode_read_getattr_maxsz + \ - op_encode_hdr_maxsz + 7 -#define NFS4_dec_read_sz compound_decode_hdr_maxsz + \ + op_encode_hdr_maxsz + 7) +#define NFS4_dec_read_sz (compound_decode_hdr_maxsz + \ decode_putfh_maxsz + \ decode_read_getattr_maxsz + \ - op_decode_hdr_maxsz + 2 -#define NFS4_enc_write_sz compound_encode_hdr_maxsz + \ + op_decode_hdr_maxsz + 2) +#define NFS4_enc_write_sz (compound_encode_hdr_maxsz + \ encode_putfh_maxsz + \ encode_pre_write_getattr_maxsz + \ op_encode_hdr_maxsz + 8 + \ - encode_post_write_getattr_maxsz -#define NFS4_dec_write_sz compound_decode_hdr_maxsz + \ + encode_post_write_getattr_maxsz) +#define NFS4_dec_write_sz (compound_decode_hdr_maxsz + \ decode_putfh_maxsz + \ decode_pre_write_getattr_maxsz + \ op_decode_hdr_maxsz + 4 + \ - decode_post_write_getattr_maxsz -#define NFS4_enc_commit_sz compound_encode_hdr_maxsz + \ + decode_post_write_getattr_maxsz) +#define NFS4_enc_commit_sz (compound_encode_hdr_maxsz + \ encode_putfh_maxsz + \ encode_pre_write_getattr_maxsz + \ op_encode_hdr_maxsz + 3 + \ - encode_post_write_getattr_maxsz -#define NFS4_dec_commit_sz compound_decode_hdr_maxsz + \ + encode_post_write_getattr_maxsz) +#define NFS4_dec_commit_sz (compound_decode_hdr_maxsz + \ decode_putfh_maxsz + \ decode_pre_write_getattr_maxsz + \ op_decode_hdr_maxsz + 2 + \ - decode_post_write_getattr_maxsz -#define NFS4_enc_open_sz compound_encode_hdr_maxsz + \ + decode_post_write_getattr_maxsz) +#define NFS4_enc_open_sz (compound_encode_hdr_maxsz + \ encode_putfh_maxsz + \ encode_savefh_maxsz + \ op_encode_hdr_maxsz + \ @@ -154,107 +154,107 @@ encode_getattr_maxsz + \ encode_getfh_maxsz + \ encode_restorefh_maxsz + \ - encode_getattr_maxsz -#define NFS4_dec_open_sz compound_decode_hdr_maxsz + \ + encode_getattr_maxsz) +#define NFS4_dec_open_sz (compound_decode_hdr_maxsz + \ decode_putfh_maxsz + \ decode_savefh_maxsz + \ op_decode_hdr_maxsz + 4 + 5 + 2 + 3 + \ decode_getattr_maxsz + \ decode_getfh_maxsz + \ decode_restorefh_maxsz + \ - decode_getattr_maxsz + decode_getattr_maxsz) #define NFS4_enc_open_confirm_sz \ - compound_encode_hdr_maxsz + \ + (compound_encode_hdr_maxsz + \ encode_putfh_maxsz + \ - op_encode_hdr_maxsz + 5 -#define NFS4_dec_open_confirm_sz compound_decode_hdr_maxsz + \ + op_encode_hdr_maxsz + 5) +#define NFS4_dec_open_confirm_sz (compound_decode_hdr_maxsz + \ decode_putfh_maxsz + \ - op_decode_hdr_maxsz + 4 -#define NFS4_enc_open_reclaim_sz compound_encode_hdr_maxsz + \ + op_decode_hdr_maxsz + 4) +#define NFS4_enc_open_reclaim_sz (compound_encode_hdr_maxsz + \ encode_putfh_maxsz + \ op_encode_hdr_maxsz + \ 11 + \ - encode_getattr_maxsz -#define NFS4_dec_open_reclaim_sz compound_decode_hdr_maxsz + \ + encode_getattr_maxsz) +#define NFS4_dec_open_reclaim_sz (compound_decode_hdr_maxsz + \ decode_putfh_maxsz + \ op_decode_hdr_maxsz + \ 4 + 5 + 2 + 3 + \ - decode_getattr_maxsz + decode_getattr_maxsz) #define NFS4_enc_open_downgrade_sz \ - compound_encode_hdr_maxsz + \ + (compound_encode_hdr_maxsz + \ encode_putfh_maxsz + \ - op_encode_hdr_maxsz + 7 + op_encode_hdr_maxsz + 7) #define NFS4_dec_open_downgrade_sz \ - compound_decode_hdr_maxsz + \ + (compound_decode_hdr_maxsz + \ decode_putfh_maxsz + \ - op_decode_hdr_maxsz + 4 -#define NFS4_enc_close_sz compound_encode_hdr_maxsz + \ + op_decode_hdr_maxsz + 4) +#define NFS4_enc_close_sz (compound_encode_hdr_maxsz + \ encode_putfh_maxsz + \ - op_encode_hdr_maxsz + 5 -#define NFS4_dec_close_sz compound_decode_hdr_maxsz + \ + op_encode_hdr_maxsz + 5) +#define NFS4_dec_close_sz (compound_decode_hdr_maxsz + \ decode_putfh_maxsz + \ - op_decode_hdr_maxsz + 4 -#define NFS4_enc_setattr_sz compound_encode_hdr_maxsz + \ + op_decode_hdr_maxsz + 4) +#define NFS4_enc_setattr_sz (compound_encode_hdr_maxsz + \ encode_putfh_maxsz + \ op_encode_hdr_maxsz + 4 + \ nfs4_fattr_bitmap_maxsz + \ - encode_getattr_maxsz -#define NFS4_dec_setattr_sz compound_decode_hdr_maxsz + \ + encode_getattr_maxsz) +#define NFS4_dec_setattr_sz (compound_decode_hdr_maxsz + \ decode_putfh_maxsz + \ - op_decode_hdr_maxsz + 3 -#define NFS4_enc_fsinfo_sz compound_encode_hdr_maxsz + \ + op_decode_hdr_maxsz + 3) +#define NFS4_enc_fsinfo_sz (compound_encode_hdr_maxsz + \ encode_putfh_maxsz + \ - encode_fsinfo_maxsz -#define NFS4_dec_fsinfo_sz compound_decode_hdr_maxsz + \ + encode_fsinfo_maxsz) +#define NFS4_dec_fsinfo_sz (compound_decode_hdr_maxsz + \ decode_putfh_maxsz + \ - decode_fsinfo_maxsz -#define NFS4_enc_renew_sz compound_encode_hdr_maxsz + \ - encode_renew_maxsz -#define NFS4_dec_renew_sz compound_decode_hdr_maxsz + \ - decode_renew_maxsz -#define NFS4_enc_setclientid_sz compound_encode_hdr_maxsz + \ - encode_setclientid_maxsz -#define NFS4_dec_setclientid_sz compound_decode_hdr_maxsz + \ - decode_setclientid_maxsz + decode_fsinfo_maxsz) +#define NFS4_enc_renew_sz (compound_encode_hdr_maxsz + \ + encode_renew_maxsz) +#define NFS4_dec_renew_sz (compound_decode_hdr_maxsz + \ + decode_renew_maxsz) +#define NFS4_enc_setclientid_sz (compound_encode_hdr_maxsz + \ + encode_setclientid_maxsz) +#define NFS4_dec_setclientid_sz (compound_decode_hdr_maxsz + \ + decode_setclientid_maxsz) #define NFS4_enc_setclientid_confirm_sz \ - compound_encode_hdr_maxsz + \ + (compound_encode_hdr_maxsz + \ encode_setclientid_confirm_maxsz + \ encode_putrootfh_maxsz + \ - encode_fsinfo_maxsz + encode_fsinfo_maxsz) #define NFS4_dec_setclientid_confirm_sz \ - compound_decode_hdr_maxsz + \ + (compound_decode_hdr_maxsz + \ decode_setclientid_confirm_maxsz + \ decode_putrootfh_maxsz + \ - decode_fsinfo_maxsz -#define NFS4_enc_lock_sz compound_encode_hdr_maxsz + \ + decode_fsinfo_maxsz) +#define NFS4_enc_lock_sz (compound_encode_hdr_maxsz + \ encode_putfh_maxsz + \ encode_getattr_maxsz + \ op_encode_hdr_maxsz + \ 1 + 1 + 2 + 2 + \ 1 + 4 + 1 + 2 + \ - owner_id_maxsz -#define NFS4_dec_lock_sz compound_decode_hdr_maxsz + \ + owner_id_maxsz) +#define NFS4_dec_lock_sz (compound_decode_hdr_maxsz + \ decode_putfh_maxsz + \ decode_getattr_maxsz + \ op_decode_hdr_maxsz + \ 2 + 2 + 1 + 2 + \ - owner_id_maxsz -#define NFS4_enc_lockt_sz compound_encode_hdr_maxsz + \ + owner_id_maxsz) +#define NFS4_enc_lockt_sz (compound_encode_hdr_maxsz + \ encode_putfh_maxsz + \ encode_getattr_maxsz + \ op_encode_hdr_maxsz + \ 1 + 2 + 2 + 2 + \ - owner_id_maxsz -#define NFS4_dec_lockt_sz NFS4_dec_lock_sz -#define NFS4_enc_locku_sz compound_encode_hdr_maxsz + \ + owner_id_maxsz) +#define NFS4_dec_lockt_sz (NFS4_dec_lock_sz) +#define NFS4_enc_locku_sz (compound_encode_hdr_maxsz + \ encode_putfh_maxsz + \ encode_getattr_maxsz + \ op_encode_hdr_maxsz + \ - 1 + 1 + 4 + 2 + 2 -#define NFS4_dec_locku_sz compound_decode_hdr_maxsz + \ + 1 + 1 + 4 + 2 + 2) +#define NFS4_dec_locku_sz (compound_decode_hdr_maxsz + \ decode_putfh_maxsz + \ decode_getattr_maxsz + \ - op_decode_hdr_maxsz + 4 + op_decode_hdr_maxsz + 4) @@ -324,7 +324,7 @@ dprintk("encode_compound: tag=%.*s\n", (int)hdr->taglen, hdr->tag); BUG_ON(hdr->taglen > NFS4_MAXTAGLEN); - RESERVE_SPACE(12+XDR_QUADLEN(hdr->taglen)); + RESERVE_SPACE(12+(XDR_QUADLEN(hdr->taglen)<<2)); WRITE32(hdr->taglen); WRITEMEM(hdr->tag, hdr->taglen); WRITE32(NFS4_MINOR_VERSION); @@ -3165,6 +3165,10 @@ { NFS4ERR_SYMLINK, ELOOP }, { NFS4ERR_OP_ILLEGAL, EOPNOTSUPP }, { NFS4ERR_DEADLOCK, EDEADLK }, + { NFS4ERR_WRONGSEC, EPERM }, /* FIXME: this needs + * to be handled by a + * middle-layer. + */ { -1, EIO } }; @@ -3179,6 +3183,10 @@ for (i = 0; nfs_errtbl[i].stat != -1; i++) { if (nfs_errtbl[i].stat == stat) return nfs_errtbl[i].errno; + } + if (stat < 0) { + /* The server is looney tunes. */ + return ESERVERFAULT; } /* If we cannot translate the error, the recovery routines should * handle it. diff -Nru a/fs/nfs/nfsroot.c b/fs/nfs/nfsroot.c --- a/fs/nfs/nfsroot.c Sun Mar 14 14:20:08 2004 +++ b/fs/nfs/nfsroot.c Sun Mar 14 14:20:08 2004 @@ -166,37 +166,6 @@ /* - * Extract IP address from the parameter string if needed. Note that we - * need to have root_server_addr set _before_ IPConfig gets called as it - * can override it. - */ -static void __init root_nfs_parse_addr(char *name) -{ - int octets = 0; - char *cp, *cq; - - cp = cq = name; - while (octets < 4) { - while (*cp >= '0' && *cp <= '9') - cp++; - if (cp == cq || cp - cq > 3) - break; - if (*cp == '.' || octets == 3) - octets++; - if (octets < 4) - cp++; - cq = cp; - } - if (octets == 4 && (*cp == ':' || *cp == '\0')) { - if (*cp == ':') - *cp++ = '\0'; - root_server_addr = in_aton(name); - strcpy(name, cp); - } -} - - -/* * Parse option string. */ static void __init root_nfs_parse(char *name, char *buf) @@ -345,7 +314,7 @@ line[sizeof(nfs_root_name) - strlen(NFS_ROOT) - 1] = '\0'; sprintf(nfs_root_name, NFS_ROOT, line); } - root_nfs_parse_addr(nfs_root_name); + root_server_addr = root_nfs_parse_addr(nfs_root_name); return 1; } diff -Nru a/fs/nfs/pagelist.c b/fs/nfs/pagelist.c --- a/fs/nfs/pagelist.c Sun Mar 14 14:20:08 2004 +++ b/fs/nfs/pagelist.c Sun Mar 14 14:20:08 2004 @@ -246,7 +246,6 @@ * nfs_scan_list - Scan a list for matching requests * @head: One of the NFS inode request lists * @dst: Destination list - * @file: if set, ensure we match requests from this file * @idx_start: lower bound of page->index to scan * @npages: idx_start + npages sets the upper bound to scan. * @@ -258,7 +257,6 @@ */ int nfs_scan_list(struct list_head *head, struct list_head *dst, - struct file *file, unsigned long idx_start, unsigned int npages) { struct list_head *pos, *tmp; @@ -275,9 +273,6 @@ list_for_each_safe(pos, tmp, head) { req = nfs_list_entry(pos); - - if (file && req->wb_file != file) - continue; if (req->wb_index < idx_start) continue; diff -Nru a/fs/nfs/proc.c b/fs/nfs/proc.c --- a/fs/nfs/proc.c Sun Mar 14 14:20:08 2004 +++ b/fs/nfs/proc.c Sun Mar 14 14:20:08 2004 @@ -49,18 +49,6 @@ extern struct rpc_procinfo nfs_procedures[]; -static void -nfs_write_refresh_inode(struct inode *inode, struct nfs_fattr *fattr) -{ - if (!(fattr->valid & NFS_ATTR_WCC)) { - fattr->pre_size = NFS_CACHE_ISIZE(inode); - fattr->pre_mtime = NFS_CACHE_MTIME(inode); - fattr->pre_ctime = NFS_CACHE_CTIME(inode); - fattr->valid |= NFS_ATTR_WCC; - } - nfs_refresh_inode(inode, fattr); -} - static struct rpc_cred * nfs_cred(struct inode *inode, struct file *filp) { @@ -78,15 +66,33 @@ */ static int nfs_proc_get_root(struct nfs_server *server, struct nfs_fh *fhandle, - struct nfs_fattr *fattr) + struct nfs_fsinfo *info) { - int status; + struct nfs_fattr *fattr = info->fattr; + struct nfs2_fsstat fsinfo; + int status; - dprintk("NFS call getroot\n"); + dprintk("%s: call getattr\n", __FUNCTION__); fattr->valid = 0; - status = rpc_call(server->client, NFSPROC_GETATTR, fhandle, fattr, 0); - dprintk("NFS reply getroot\n"); - return status; + status = rpc_call(server->client_sys, NFSPROC_GETATTR, fhandle, fattr, 0); + dprintk("%s: reply getattr %d\n", __FUNCTION__, status); + if (status) + return status; + dprintk("%s: call statfs\n", __FUNCTION__); + status = rpc_call(server->client_sys, NFSPROC_STATFS, fhandle, &fsinfo, 0); + dprintk("%s: reply statfs %d\n", __FUNCTION__, status); + if (status) + return status; + info->rtmax = NFS_MAXDATA; + info->rtpref = fsinfo.tsize; + info->rtmult = fsinfo.bsize; + info->wtmax = NFS_MAXDATA; + info->wtpref = fsinfo.tsize; + info->wtmult = fsinfo.bsize; + info->dtpref = fsinfo.tsize; + info->maxfilesize = 0x7FFFFFFF; + info->lease_time = 0; + return 0; } /* @@ -180,8 +186,14 @@ msg.rpc_cred = nfs_cred(inode, filp); status = rpc_call_sync(NFS_CLIENT(inode), &msg, flags); - if (status >= 0) + if (status >= 0) { nfs_refresh_inode(inode, fattr); + /* Emulate the eof flag, which isn't normally needed in NFSv2 + * as it is guaranteed to always return the file attributes + */ + if (rdata->args.offset + rdata->args.count >= fattr->size) + rdata->res.eof = 1; + } dprintk("NFS reply read: %d\n", status); return status; } @@ -205,7 +217,7 @@ msg.rpc_cred = nfs_cred(inode, filp); status = rpc_call_sync(NFS_CLIENT(inode), &msg, flags); if (status >= 0) { - nfs_write_refresh_inode(inode, fattr); + nfs_refresh_inode(inode, fattr); wdata->res.count = wdata->args.count; wdata->verf.committed = NFS_FILE_SYNC; } @@ -331,10 +343,8 @@ { struct rpc_message *msg = &task->tk_msg; - if (msg->rpc_argp) { - NFS_CACHEINV(dir->d_inode); + if (msg->rpc_argp) kfree(msg->rpc_argp); - } return 0; } @@ -537,8 +547,14 @@ { struct nfs_read_data *data = (struct nfs_read_data *) task->tk_calldata; - if (task->tk_status >= 0) + if (task->tk_status >= 0) { nfs_refresh_inode(data->inode, data->res.fattr); + /* Emulate the eof flag, which isn't normally needed in NFSv2 + * as it is guaranteed to always return the file attributes + */ + if (data->args.offset + data->args.count >= data->res.fattr->size) + data->res.eof = 1; + } nfs_readpage_result(task); } @@ -584,7 +600,7 @@ struct nfs_write_data *data = (struct nfs_write_data *) task->tk_calldata; if (task->tk_status >= 0) - nfs_write_refresh_inode(data->inode, data->res.fattr); + nfs_refresh_inode(data->inode, data->res.fattr); nfs_writeback_done(task); } diff -Nru a/fs/nfs/read.c b/fs/nfs/read.c --- a/fs/nfs/read.c Sun Mar 14 14:20:05 2004 +++ b/fs/nfs/read.c Sun Mar 14 14:20:05 2004 @@ -121,9 +121,13 @@ } count -= result; rdata.args.pgbase += result; - if (result < rdata.args.count) /* NFSv2ism */ + /* Note: result == 0 should only happen if we're caching + * a write that extends the file and punches a hole. + */ + if (rdata.res.eof != 0 || result == 0) break; } while (count); + NFS_FLAGS(inode) |= NFS_INO_INVALID_ATIME; if (count) memclear_highpage_flush(page, rdata.args.pgbase, count); @@ -266,6 +270,7 @@ dprintk("NFS: %4d nfs_readpage_result, (status %d)\n", task->tk_pid, task->tk_status); + NFS_FLAGS(data->inode) |= NFS_INO_INVALID_ATIME; while (!list_empty(&data->pages)) { struct nfs_page *req = nfs_list_entry(data->pages.next); struct page *page = req->wb_page; diff -Nru a/fs/nfs/unlink.c b/fs/nfs/unlink.c --- a/fs/nfs/unlink.c Sun Mar 14 14:20:08 2004 +++ b/fs/nfs/unlink.c Sun Mar 14 14:20:08 2004 @@ -104,6 +104,7 @@ status = NFS_PROTO(dir->d_inode)->unlink_setup(&msg, dir, &data->name); if (status < 0) goto out_err; + nfs_begin_data_update(dir->d_inode); rpc_call_setup(task, &msg, 0); return; out_err: @@ -126,7 +127,7 @@ if (!dir) return; dir_i = dir->d_inode; - nfs_zap_caches(dir_i); + nfs_end_data_update(dir_i); if (NFS_PROTO(dir_i)->unlink_done(dir, task)) return; put_rpccred(data->cred); diff -Nru a/fs/nfs/write.c b/fs/nfs/write.c --- a/fs/nfs/write.c Sun Mar 14 14:20:08 2004 +++ b/fs/nfs/write.c Sun Mar 14 14:20:08 2004 @@ -74,7 +74,6 @@ static struct nfs_page * nfs_update_request(struct file*, struct inode *, struct page *, unsigned int, unsigned int); -static void nfs_strategy(struct inode *inode); static kmem_cache_t *nfs_wdata_cachep; static mempool_t *nfs_wdata_mempool; @@ -124,6 +123,52 @@ nfs_commit_free(wdata); } +/* Adjust the file length if we're writing beyond the end */ +static void nfs_grow_file(struct page *page, unsigned int offset, unsigned int count) +{ + struct inode *inode = page->mapping->host; + loff_t end, i_size = i_size_read(inode); + unsigned long end_index = (i_size - 1) >> PAGE_CACHE_SHIFT; + + if (i_size > 0 && page->index < end_index) + return; + end = ((loff_t)page->index << PAGE_CACHE_SHIFT) + ((loff_t)offset+count); + if (i_size >= end) + return; + i_size_write(inode, end); +} + +/* We can set the PG_uptodate flag if we see that a write request + * covers the full page. + */ +static void nfs_mark_uptodate(struct page *page, unsigned int base, unsigned int count) +{ + loff_t end_offs; + + if (PageUptodate(page)) + return; + if (base != 0) + return; + if (count == PAGE_CACHE_SIZE) { + SetPageUptodate(page); + return; + } + + end_offs = i_size_read(page->mapping->host) - 1; + if (end_offs < 0) + return; + /* Is this the last page? */ + if (page->index != (unsigned long)(end_offs >> PAGE_CACHE_SHIFT)) + return; + /* This is the last page: set PG_uptodate if we cover the entire + * extent of the data, then zero the rest of the page. + */ + if (count == (unsigned int)(end_offs & (PAGE_CACHE_SIZE - 1)) + 1) { + memclear_highpage_flush(page, count, PAGE_CACHE_SIZE - count); + SetPageUptodate(page); + } +} + /* * Write a page synchronously. * Offset is the data offset within the page. @@ -157,6 +202,7 @@ (long long)NFS_FILEID(inode), count, (long long)(page_offset(page) + offset)); + nfs_begin_data_update(inode); do { if (count < wsize && !swapfile) wdata.args.count = count; @@ -177,43 +223,38 @@ wdata.args.pgbase += result; written += result; count -= result; - - /* - * If we've extended the file, update the inode - * now so we don't invalidate the cache. - */ - if (wdata.args.offset > i_size_read(inode)) - i_size_write(inode, wdata.args.offset); } while (count); + /* Update file length */ + nfs_grow_file(page, offset, written); + /* Set the PG_uptodate flag? */ + nfs_mark_uptodate(page, offset, written); if (PageError(page)) ClearPageError(page); io_error: + nfs_end_data_update(inode); if (wdata.cred) put_rpccred(wdata.cred); return written ? written : result; } -static int -nfs_writepage_async(struct file *file, struct inode *inode, struct page *page, - unsigned int offset, unsigned int count) +static int nfs_writepage_async(struct file *file, struct inode *inode, + struct page *page, unsigned int offset, unsigned int count) { struct nfs_page *req; - loff_t end; int status; req = nfs_update_request(file, inode, page, offset, count); status = (IS_ERR(req)) ? PTR_ERR(req) : 0; if (status < 0) goto out; + /* Update file length */ + nfs_grow_file(page, offset, count); + /* Set the PG_uptodate flag? */ + nfs_mark_uptodate(page, offset, count); nfs_unlock_request(req); - nfs_strategy(inode); - end = ((loff_t)page->index<sync_mode == WB_SYNC_HOLD) @@ -294,7 +335,7 @@ if (is_sync && wbc->sync_mode == WB_SYNC_ALL) { err = nfs_wb_all(inode); } else - nfs_commit_file(inode, NULL, 0, 0, 0); + nfs_commit_inode(inode, 0, 0, 0); out: return err; } @@ -312,8 +353,10 @@ BUG_ON(error == -EEXIST); if (error) return error; - if (!nfsi->npages) + if (!nfsi->npages) { igrab(inode); + nfs_begin_data_update(inode); + } nfsi->npages++; req->wb_count++; return 0; @@ -336,6 +379,7 @@ nfsi->npages--; if (!nfsi->npages) { spin_unlock(&nfs_wreq_lock); + nfs_end_data_update(inode); iput(inode); } else spin_unlock(&nfs_wreq_lock); @@ -421,7 +465,7 @@ * Interruptible by signals only if mounted with intr flag. */ static int -nfs_wait_on_requests(struct inode *inode, struct file *file, unsigned long idx_start, unsigned int npages) +nfs_wait_on_requests(struct inode *inode, unsigned long idx_start, unsigned int npages) { struct nfs_inode *nfsi = NFS_I(inode); struct nfs_page *req; @@ -441,8 +485,6 @@ break; next = req->wb_index + 1; - if (file && req->wb_file != file) - continue; if (!NFS_WBACK_BUSY(req)) continue; @@ -453,7 +495,6 @@ if (error < 0) return error; spin_lock(&nfs_wreq_lock); - next = idx_start; res++; } spin_unlock(&nfs_wreq_lock); @@ -464,7 +505,6 @@ * nfs_scan_dirty - Scan an inode for dirty requests * @inode: NFS inode to scan * @dst: destination list - * @file: if set, ensure we match requests from this file * @idx_start: lower bound of page->index to scan. * @npages: idx_start + npages sets the upper bound to scan. * @@ -472,11 +512,11 @@ * The requests are *not* checked to ensure that they form a contiguous set. */ static int -nfs_scan_dirty(struct inode *inode, struct list_head *dst, struct file *file, unsigned long idx_start, unsigned int npages) +nfs_scan_dirty(struct inode *inode, struct list_head *dst, unsigned long idx_start, unsigned int npages) { struct nfs_inode *nfsi = NFS_I(inode); int res; - res = nfs_scan_list(&nfsi->dirty, dst, file, idx_start, npages); + res = nfs_scan_list(&nfsi->dirty, dst, idx_start, npages); nfsi->ndirty -= res; sub_page_state(nr_dirty,res); if ((nfsi->ndirty == 0) != list_empty(&nfsi->dirty)) @@ -489,7 +529,6 @@ * nfs_scan_commit - Scan an inode for commit requests * @inode: NFS inode to scan * @dst: destination list - * @file: if set, ensure we collect requests from this file only. * @idx_start: lower bound of page->index to scan. * @npages: idx_start + npages sets the upper bound to scan. * @@ -497,11 +536,11 @@ * The requests are *not* checked to ensure that they form a contiguous set. */ static int -nfs_scan_commit(struct inode *inode, struct list_head *dst, struct file *file, unsigned long idx_start, unsigned int npages) +nfs_scan_commit(struct inode *inode, struct list_head *dst, unsigned long idx_start, unsigned int npages) { struct nfs_inode *nfsi = NFS_I(inode); int res; - res = nfs_scan_list(&nfsi->commit, dst, file, idx_start, npages); + res = nfs_scan_list(&nfsi->commit, dst, idx_start, npages); nfsi->ncommit -= res; if ((nfsi->ncommit == 0) != list_empty(&nfsi->commit)) printk(KERN_ERR "NFS: desynchronized value of nfs_i.ncommit.\n"); @@ -600,46 +639,6 @@ return req; } -/* - * This is the strategy routine for NFS. - * It is called by nfs_updatepage whenever the user wrote up to the end - * of a page. - * - * We always try to submit a set of requests in parallel so that the - * server's write code can gather writes. This is mainly for the benefit - * of NFSv2. - * - * We never submit more requests than we think the remote can handle. - * For UDP sockets, we make sure we don't exceed the congestion window; - * for TCP, we limit the number of requests to 8. - * - * NFS_STRATEGY_PAGES gives the minimum number of requests for NFSv2 that - * should be sent out in one go. This is for the benefit of NFSv2 servers - * that perform write gathering. - * - * FIXME: Different servers may have different sweet spots. - * Record the average congestion window in server struct? - */ -#define NFS_STRATEGY_PAGES 8 -static void -nfs_strategy(struct inode *inode) -{ - unsigned int dirty, wpages; - - dirty = NFS_I(inode)->ndirty; - wpages = NFS_SERVER(inode)->wpages; -#if defined(CONFIG_NFS_V3) || defined(CONFIG_NFS_V4) - if (NFS_PROTO(inode)->version == 2) { - if (dirty >= NFS_STRATEGY_PAGES * wpages) - nfs_flush_file(inode, NULL, 0, 0, 0); - } else if (dirty >= wpages) - nfs_flush_file(inode, NULL, 0, 0, 0); -#else - if (dirty >= NFS_STRATEGY_PAGES * wpages) - nfs_flush_file(inode, NULL, 0, 0, 0); -#endif -} - int nfs_flush_incompatible(struct file *file, struct page *page) { @@ -675,7 +674,6 @@ struct dentry *dentry = file->f_dentry; struct inode *inode = page->mapping->host; struct nfs_page *req; - loff_t end; int status = 0; dprintk("NFS: nfs_updatepage(%s/%s %d@%Ld)\n", @@ -696,6 +694,27 @@ return status; } + /* If we're not using byte range locks, and we know the page + * is entirely in cache, it may be more efficient to avoid + * fragmenting write requests. + */ + if (PageUptodate(page) && inode->i_flock == NULL) { + loff_t end_offs = i_size_read(inode) - 1; + unsigned long end_index = end_offs >> PAGE_CACHE_SHIFT; + + count += offset; + offset = 0; + if (unlikely(end_offs < 0)) { + /* Do nothing */ + } else if (page->index == end_index) { + unsigned int pglen; + pglen = (unsigned int)(end_offs & (PAGE_CACHE_SIZE-1)) + 1; + if (count < pglen) + count = pglen; + } else if (page->index < end_index) + count = PAGE_CACHE_SIZE; + } + /* * Try to find an NFS request corresponding to this page * and update it. @@ -714,20 +733,12 @@ goto done; status = 0; - end = ((loff_t)page->index<wb_pgbase == 0 && req->wb_bytes == PAGE_CACHE_SIZE) { - SetPageUptodate(page); - nfs_unlock_request(req); - nfs_strategy(inode); - } else - nfs_unlock_request(req); + + /* Update file length */ + nfs_grow_file(page, offset, count); + /* Set the PG_uptodate flag? */ + nfs_mark_uptodate(page, req->wb_pgbase, req->wb_bytes); + nfs_unlock_request(req); done: dprintk("NFS: nfs_updatepage returns %d (isize %Ld)\n", status, (long long)i_size_read(inode)); @@ -891,10 +902,7 @@ #endif /* - * Update attributes as result of writeback. - * FIXME: There is an inherent race with invalidate_inode_pages and - * writebacks since the page->count is kept > 1 for as long - * as the page has a write request pending. + * Process the nfs_page list */ while (!list_empty(&data->pages)) { req = nfs_list_entry(data->pages.next); @@ -1061,7 +1069,7 @@ } #endif -int nfs_flush_file(struct inode *inode, struct file *file, unsigned long idx_start, +int nfs_flush_inode(struct inode *inode, unsigned long idx_start, unsigned int npages, int how) { LIST_HEAD(head); @@ -1069,7 +1077,7 @@ error = 0; spin_lock(&nfs_wreq_lock); - res = nfs_scan_dirty(inode, &head, file, idx_start, npages); + res = nfs_scan_dirty(inode, &head, idx_start, npages); spin_unlock(&nfs_wreq_lock); if (res) error = nfs_flush_list(&head, NFS_SERVER(inode)->wpages, how); @@ -1079,7 +1087,7 @@ } #if defined(CONFIG_NFS_V3) || defined(CONFIG_NFS_V4) -int nfs_commit_file(struct inode *inode, struct file *file, unsigned long idx_start, +int nfs_commit_inode(struct inode *inode, unsigned long idx_start, unsigned int npages, int how) { LIST_HEAD(head); @@ -1087,9 +1095,9 @@ error = 0; spin_lock(&nfs_wreq_lock); - res = nfs_scan_commit(inode, &head, file, idx_start, npages); + res = nfs_scan_commit(inode, &head, idx_start, npages); if (res) { - res += nfs_scan_commit(inode, &head, NULL, 0, 0); + res += nfs_scan_commit(inode, &head, 0, 0); spin_unlock(&nfs_wreq_lock); error = nfs_commit_list(&head, how); } else @@ -1100,7 +1108,7 @@ } #endif -int nfs_sync_file(struct inode *inode, struct file *file, unsigned long idx_start, +int nfs_sync_inode(struct inode *inode, unsigned long idx_start, unsigned int npages, int how) { int error, @@ -1109,18 +1117,15 @@ wait = how & FLUSH_WAIT; how &= ~FLUSH_WAIT; - if (!inode && file) - inode = file->f_dentry->d_inode; - do { error = 0; if (wait) - error = nfs_wait_on_requests(inode, file, idx_start, npages); + error = nfs_wait_on_requests(inode, idx_start, npages); if (error == 0) - error = nfs_flush_file(inode, file, idx_start, npages, how); + error = nfs_flush_inode(inode, idx_start, npages, how); #if defined(CONFIG_NFS_V3) || defined(CONFIG_NFS_V4) if (error == 0) - error = nfs_commit_file(inode, file, idx_start, npages, how); + error = nfs_commit_inode(inode, idx_start, npages, how); #endif } while (error > 0); return error; diff -Nru a/fs/open.c b/fs/open.c --- a/fs/open.c Sun Mar 14 14:20:06 2004 +++ b/fs/open.c Sun Mar 14 14:20:06 2004 @@ -954,6 +954,7 @@ fd = error; goto out; } +EXPORT_SYMBOL_GPL(sys_open); #ifndef __alpha__ diff -Nru a/fs/proc/generic.c b/fs/proc/generic.c --- a/fs/proc/generic.c Sun Mar 14 14:20:08 2004 +++ b/fs/proc/generic.c Sun Mar 14 14:20:08 2004 @@ -661,6 +661,7 @@ proc_alloc_map); proc_kill_inodes(de); de->nlink = 0; + WARN_ON(de->subdir); if (!atomic_read(&de->count)) free_proc_entry(de); else { diff -Nru a/fs/proc/inode.c b/fs/proc/inode.c --- a/fs/proc/inode.c Sun Mar 14 14:20:08 2004 +++ b/fs/proc/inode.c Sun Mar 14 14:20:08 2004 @@ -231,6 +231,7 @@ { struct inode * root_inode; + s->s_flags |= MS_NODIRATIME; s->s_blocksize = 1024; s->s_blocksize_bits = 10; s->s_magic = PROC_SUPER_MAGIC; diff -Nru a/fs/proc/kmsg.c b/fs/proc/kmsg.c --- a/fs/proc/kmsg.c Sun Mar 14 14:20:08 2004 +++ b/fs/proc/kmsg.c Sun Mar 14 14:20:08 2004 @@ -33,6 +33,8 @@ static ssize_t kmsg_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) { + if ((file->f_flags & O_NONBLOCK) && !do_syslog(9, 0, 0)) + return -EAGAIN; return do_syslog(2, buf, count); } diff -Nru a/fs/proc/proc_misc.c b/fs/proc/proc_misc.c --- a/fs/proc/proc_misc.c Sun Mar 14 14:20:06 2004 +++ b/fs/proc/proc_misc.c Sun Mar 14 14:20:06 2004 @@ -361,7 +361,8 @@ int i; extern unsigned long total_forks; unsigned long jif; - unsigned int sum = 0, user = 0, nice = 0, system = 0, idle = 0, iowait = 0, irq = 0, softirq = 0; + u64 sum = 0, user = 0, nice = 0, system = 0, + idle = 0, iowait = 0, irq = 0, softirq = 0; jif = - wall_to_monotonic.tv_sec; if (wall_to_monotonic.tv_nsec) @@ -381,26 +382,35 @@ sum += kstat_cpu(i).irqs[j]; } - 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), - jiffies_to_clock_t(idle), - jiffies_to_clock_t(iowait), - jiffies_to_clock_t(irq), - jiffies_to_clock_t(softirq)); + seq_printf(p, "cpu %llu %llu %llu %llu %llu %llu %llu\n", + (unsigned long long)jiffies_64_to_clock_t(user), + (unsigned long long)jiffies_64_to_clock_t(nice), + (unsigned long long)jiffies_64_to_clock_t(system), + (unsigned long long)jiffies_64_to_clock_t(idle), + (unsigned long long)jiffies_64_to_clock_t(iowait), + (unsigned long long)jiffies_64_to_clock_t(irq), + (unsigned long long)jiffies_64_to_clock_t(softirq)); for_each_cpu(i) { - seq_printf(p, "cpu%d %u %u %u %u %u %u %u\n", + /* two separate calls here to work around gcc-2.95.3 ICE */ + seq_printf(p, "cpu%d %llu %llu %llu ", i, - jiffies_to_clock_t(kstat_cpu(i).cpustat.user), - jiffies_to_clock_t(kstat_cpu(i).cpustat.nice), - jiffies_to_clock_t(kstat_cpu(i).cpustat.system), - jiffies_to_clock_t(kstat_cpu(i).cpustat.idle), - jiffies_to_clock_t(kstat_cpu(i).cpustat.iowait), - jiffies_to_clock_t(kstat_cpu(i).cpustat.irq), - jiffies_to_clock_t(kstat_cpu(i).cpustat.softirq)); + (unsigned long long) + jiffies_64_to_clock_t(kstat_cpu(i).cpustat.user), + (unsigned long long) + jiffies_64_to_clock_t(kstat_cpu(i).cpustat.nice), + (unsigned long long) + jiffies_64_to_clock_t(kstat_cpu(i).cpustat.system)); + seq_printf(p, "%llu %llu %llu %llu\n", + (unsigned long long) + jiffies_64_to_clock_t(kstat_cpu(i).cpustat.idle), + (unsigned long long) + jiffies_64_to_clock_t(kstat_cpu(i).cpustat.iowait), + (unsigned long long) + jiffies_64_to_clock_t(kstat_cpu(i).cpustat.irq), + (unsigned long long) + jiffies_64_to_clock_t(kstat_cpu(i).cpustat.softirq)); } - seq_printf(p, "intr %u", sum); + seq_printf(p, "intr %llu", (unsigned long long)sum); #if !defined(CONFIG_PPC64) && !defined(CONFIG_ALPHA) for (i = 0; i < NR_IRQS; i++) @@ -408,7 +418,7 @@ #endif seq_printf(p, - "\nctxt %lu\n" + "\nctxt %llu\n" "btime %lu\n" "processes %lu\n" "procs_running %lu\n" diff -Nru a/fs/qnx4/dir.c b/fs/qnx4/dir.c --- a/fs/qnx4/dir.c Sun Mar 14 14:20:07 2004 +++ b/fs/qnx4/dir.c Sun Mar 14 14:20:07 2004 @@ -76,8 +76,6 @@ } brelse(bh); } - update_atime(inode); - out: unlock_kernel(); return 0; diff -Nru a/fs/read_write.c b/fs/read_write.c --- a/fs/read_write.c Sun Mar 14 14:20:07 2004 +++ b/fs/read_write.c Sun Mar 14 14:20:07 2004 @@ -143,6 +143,7 @@ bad: return retval; } +EXPORT_SYMBOL_GPL(sys_lseek); #if !defined(__alpha__) asmlinkage long sys_llseek(unsigned int fd, unsigned long offset_high, @@ -281,6 +282,7 @@ return ret; } +EXPORT_SYMBOL_GPL(sys_read); asmlinkage ssize_t sys_write(unsigned int fd, const char __user * buf, size_t count) { diff -Nru a/fs/readdir.c b/fs/readdir.c --- a/fs/readdir.c Sun Mar 14 14:20:07 2004 +++ b/fs/readdir.c Sun Mar 14 14:20:07 2004 @@ -32,6 +32,7 @@ res = -ENOENT; if (!IS_DEADDIR(inode)) { res = file->f_op->readdir(file, buf, filler); + update_atime(inode); } up(&inode->i_sem); out: diff -Nru a/fs/reiserfs/dir.c b/fs/reiserfs/dir.c --- a/fs/reiserfs/dir.c Sun Mar 14 14:20:07 2004 +++ b/fs/reiserfs/dir.c Sun Mar 14 14:20:07 2004 @@ -186,7 +186,6 @@ filp->f_pos = next_pos; pathrelse (&path_to_entry); reiserfs_check_path(&path_to_entry) ; - update_atime(inode) ; out: reiserfs_write_unlock(inode->i_sb); return ret; diff -Nru a/fs/smbfs/inode.c b/fs/smbfs/inode.c --- a/fs/smbfs/inode.c Sun Mar 14 14:20:06 2004 +++ b/fs/smbfs/inode.c Sun Mar 14 14:20:06 2004 @@ -499,6 +499,7 @@ if (ver != SMB_MOUNT_OLDVERSION && cpu_to_be32(ver) != SMB_MOUNT_ASCII) goto out_wrong_data; + sb->s_flags |= MS_NODIRATIME; sb->s_blocksize = 1024; /* Eh... Is this correct? */ sb->s_blocksize_bits = 10; sb->s_magic = SMB_SUPER_MAGIC; @@ -778,6 +779,7 @@ .name = "smbfs", .get_sb = smb_get_sb, .kill_sb = kill_anon_super, + .fs_flags = FS_BINARY_MOUNTDATA, }; static int __init init_smb_fs(void) diff -Nru a/fs/super.c b/fs/super.c --- a/fs/super.c Sun Mar 14 14:20:07 2004 +++ b/fs/super.c Sun Mar 14 14:20:07 2004 @@ -745,7 +745,7 @@ goto out_mnt; } - error = security_sb_copy_data(fstype, data, secdata); + error = security_sb_copy_data(type, data, secdata); if (error) { sb = ERR_PTR(error); goto out_free_secdata; diff -Nru a/fs/sysv/dir.c b/fs/sysv/dir.c --- a/fs/sysv/dir.c Sun Mar 14 14:20:06 2004 +++ b/fs/sysv/dir.c Sun Mar 14 14:20:06 2004 @@ -116,7 +116,6 @@ done: filp->f_pos = (n << PAGE_CACHE_SHIFT) | offset; - update_atime(inode); unlock_kernel(); return 0; } diff -Nru a/fs/udf/dir.c b/fs/udf/dir.c --- a/fs/udf/dir.c Sun Mar 14 14:20:06 2004 +++ b/fs/udf/dir.c Sun Mar 14 14:20:06 2004 @@ -15,7 +15,7 @@ * ftp://prep.ai.mit.edu/pub/gnu/GPL * Each contributing author retains all rights to their own work. * - * (C) 1998-2001 Ben Fennema + * (C) 1998-2004 Ben Fennema * * HISTORY * @@ -98,7 +98,6 @@ } result = do_udf_readdir(dir, filp, filldir, dirent); - update_atime(dir); unlock_kernel(); return result; } @@ -112,7 +111,7 @@ int block, iblock; loff_t nf_pos = filp->f_pos - 1; int flen; - char fname[255]; + char fname[UDF_NAME_LEN]; char *nameptr; uint16_t liu; uint8_t lfi; diff -Nru a/fs/udf/file.c b/fs/udf/file.c --- a/fs/udf/file.c Sun Mar 14 14:20:07 2004 +++ b/fs/udf/file.c Sun Mar 14 14:20:07 2004 @@ -16,7 +16,7 @@ * Each contributing author retains all rights to their own work. * * (C) 1998-1999 Dave Boynton - * (C) 1998-2001 Ben Fennema + * (C) 1998-2004 Ben Fennema * (C) 1999-2000 Stelias Computing Inc * * HISTORY @@ -247,9 +247,9 @@ { if (filp->f_mode & FMODE_WRITE) { - lock_kernel(); + down(&inode->i_sem); udf_discard_prealloc(inode); - unlock_kernel(); + up(&inode->i_sem); } return 0; } diff -Nru a/fs/udf/inode.c b/fs/udf/inode.c --- a/fs/udf/inode.c Sun Mar 14 14:20:09 2004 +++ b/fs/udf/inode.c Sun Mar 14 14:20:09 2004 @@ -16,7 +16,7 @@ * Each contributing author retains all rights to their own work. * * (C) 1998 Dave Boynton - * (C) 1998-2001 Ben Fennema + * (C) 1998-2004 Ben Fennema * (C) 1999-2000 Stelias Computing Inc * * HISTORY @@ -84,9 +84,9 @@ { if (!(inode->i_sb->s_flags & MS_RDONLY)) { - lock_kernel(); + down(&inode->i_sem); udf_discard_prealloc(inode); - unlock_kernel(); + up(&inode->i_sem); } } @@ -130,15 +130,6 @@ UDF_I_DATA(inode) = NULL; } -void udf_discard_prealloc(struct inode * inode) -{ - if (inode->i_size && inode->i_size != UDF_I_LENEXTENTS(inode) && - UDF_I_ALLOCTYPE(inode) != ICBTAG_FLAG_AD_IN_ICB) - { - udf_truncate_extents(inode); - } -} - static int udf_writepage(struct page *page, struct writeback_control *wbc) { return block_write_full_page(page, udf_get_block, wbc); @@ -516,11 +507,8 @@ else lastblock = 1; } + udf_release_data(cbh); udf_release_data(nbh); - if (!pbh) - pbh = cbh; - else - udf_release_data(cbh); /* if the current extent is not recorded but allocated, get the block in the extent corresponding to the requested block */ @@ -595,7 +583,7 @@ int curr = *c; int blen = ((laarr[curr].extLength & UDF_EXTENT_LENGTH_MASK) + inode->i_sb->s_blocksize - 1) >> inode->i_sb->s_blocksize_bits; - int type = laarr[curr].extLength & ~UDF_EXTENT_LENGTH_MASK; + int8_t etype = (laarr[curr].extLength >> 30); if (blen == 1) ; @@ -612,7 +600,7 @@ if (offset) { - if ((type >> 30) == (EXT_NOT_RECORDED_ALLOCATED >> 30)) + if (etype == (EXT_NOT_RECORDED_ALLOCATED >> 30)) { udf_free_blocks(inode->i_sb, inode, laarr[curr].extLocation, 0, offset); laarr[curr].extLength = EXT_NOT_RECORDED_NOT_ALLOCATED | @@ -621,7 +609,7 @@ laarr[curr].extLocation.partitionReferenceNum = 0; } else - laarr[curr].extLength = type | + laarr[curr].extLength = (etype << 30) | (offset << inode->i_sb->s_blocksize_bits); curr ++; (*c) ++; @@ -629,7 +617,7 @@ } laarr[curr].extLocation.logicalBlockNum = newblocknum; - if ((type >> 30) == (EXT_NOT_RECORDED_NOT_ALLOCATED >> 30)) + if (etype == (EXT_NOT_RECORDED_NOT_ALLOCATED >> 30)) laarr[curr].extLocation.partitionReferenceNum = UDF_I_LOCATION(inode).partitionReferenceNum; laarr[curr].extLength = EXT_RECORDED_ALLOCATED | @@ -638,9 +626,9 @@ if (blen != offset + 1) { - if ((type >> 30) == (EXT_NOT_RECORDED_ALLOCATED >> 30)) + if (etype == (EXT_NOT_RECORDED_ALLOCATED >> 30)) laarr[curr].extLocation.logicalBlockNum += (offset + 1); - laarr[curr].extLength = type | + laarr[curr].extLength = (etype << 30) | ((blen - (offset + 1)) << inode->i_sb->s_blocksize_bits); curr ++; (*endnum) ++; @@ -761,8 +749,8 @@ laarr[i+1].extLength = (laarr[i+1].extLength - (laarr[i].extLength & UDF_EXTENT_LENGTH_MASK) + UDF_EXTENT_LENGTH_MASK) & ~(inode->i_sb->s_blocksize-1); - laarr[i].extLength = (UDF_EXTENT_LENGTH_MASK + 1) - - inode->i_sb->s_blocksize; + laarr[i].extLength = (laarr[i].extLength & UDF_EXTENT_FLAG_MASK) + + (UDF_EXTENT_LENGTH_MASK + 1) - inode->i_sb->s_blocksize; laarr[i+1].extLocation.logicalBlockNum = laarr[i].extLocation.logicalBlockNum + ((laarr[i].extLength & UDF_EXTENT_LENGTH_MASK) >> @@ -781,6 +769,47 @@ } } } + else if (((laarr[i].extLength >> 30) == (EXT_NOT_RECORDED_ALLOCATED >> 30)) && + ((laarr[i+1].extLength >> 30) == (EXT_NOT_RECORDED_NOT_ALLOCATED >> 30))) + { + udf_free_blocks(inode->i_sb, inode, laarr[i].extLocation, 0, + ((laarr[i].extLength & UDF_EXTENT_LENGTH_MASK) + + inode->i_sb->s_blocksize - 1) >> inode->i_sb->s_blocksize_bits); + laarr[i].extLocation.logicalBlockNum = 0; + laarr[i].extLocation.partitionReferenceNum = 0; + + if (((laarr[i].extLength & UDF_EXTENT_LENGTH_MASK) + + (laarr[i+1].extLength & UDF_EXTENT_LENGTH_MASK) + + inode->i_sb->s_blocksize - 1) & ~UDF_EXTENT_LENGTH_MASK) + { + laarr[i+1].extLength = (laarr[i+1].extLength - + (laarr[i].extLength & UDF_EXTENT_LENGTH_MASK) + + UDF_EXTENT_LENGTH_MASK) & ~(inode->i_sb->s_blocksize-1); + laarr[i].extLength = (laarr[i].extLength & UDF_EXTENT_FLAG_MASK) + + (UDF_EXTENT_LENGTH_MASK + 1) - inode->i_sb->s_blocksize; + } + else + { + laarr[i].extLength = laarr[i+1].extLength + + (((laarr[i].extLength & UDF_EXTENT_LENGTH_MASK) + + inode->i_sb->s_blocksize - 1) & ~(inode->i_sb->s_blocksize-1)); + if (*endnum > (i+2)) + memmove(&laarr[i+1], &laarr[i+2], + sizeof(long_ad) * (*endnum - (i+2))); + i --; + (*endnum) --; + } + } + else if ((laarr[i].extLength >> 30) == (EXT_NOT_RECORDED_ALLOCATED >> 30)) + { + udf_free_blocks(inode->i_sb, inode, laarr[i].extLocation, 0, + ((laarr[i].extLength & UDF_EXTENT_LENGTH_MASK) + + inode->i_sb->s_blocksize - 1) >> inode->i_sb->s_blocksize_bits); + laarr[i].extLocation.logicalBlockNum = 0; + laarr[i].extLocation.partitionReferenceNum = 0; + laarr[i].extLength = (laarr[i].extLength & UDF_EXTENT_LENGTH_MASK) | + EXT_NOT_RECORDED_NOT_ALLOCATED; + } } } @@ -1014,7 +1043,7 @@ struct extendedFileEntry *efe; time_t convtime; long convtime_usec; - int offset, alen; + int offset; fe = (struct fileEntry *)bh->b_data; efe = (struct extendedFileEntry *)bh->b_data; @@ -1115,7 +1144,6 @@ UDF_I_LENEATTR(inode) = le32_to_cpu(fe->lengthExtendedAttr); UDF_I_LENALLOC(inode) = le32_to_cpu(fe->lengthAllocDescs); offset = sizeof(struct fileEntry) + UDF_I_LENEATTR(inode); - alen = offset + UDF_I_LENALLOC(inode); } else { @@ -1170,7 +1198,6 @@ UDF_I_LENEATTR(inode) = le32_to_cpu(efe->lengthExtendedAttr); UDF_I_LENALLOC(inode) = le32_to_cpu(efe->lengthAllocDescs); offset = sizeof(struct extendedFileEntry) + UDF_I_LENEATTR(inode); - alen = offset + UDF_I_LENALLOC(inode); } switch (fe->icbTag.fileType) @@ -1211,6 +1238,11 @@ init_special_inode(inode, inode->i_mode | S_IFIFO, 0); break; } + case ICBTAG_FILE_TYPE_SOCKET: + { + init_special_inode(inode, inode->i_mode | S_IFSOCK, 0); + break; + } case ICBTAG_FILE_TYPE_SYMLINK: { inode->i_data.a_ops = &udf_symlink_aops; @@ -1228,19 +1260,16 @@ } if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode)) { - struct buffer_head *tbh = NULL; struct deviceSpec *dsea = (struct deviceSpec *) - udf_get_extendedattr(inode, 12, 1, &tbh); + udf_get_extendedattr(inode, 12, 1); if (dsea) { init_special_inode(inode, inode->i_mode, MKDEV( le32_to_cpu(dsea->majorDeviceIdent), - le32_to_cpu(dsea->minorDeviceIdent) - )); + le32_to_cpu(dsea->minorDeviceIdent))); /* Developer ID ??? */ - udf_release_data(tbh); } else { @@ -1372,17 +1401,16 @@ if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode)) { regid *eid; - struct buffer_head *tbh = NULL; struct deviceSpec *dsea = (struct deviceSpec *) - udf_get_extendedattr(inode, 12, 1, &tbh); + udf_get_extendedattr(inode, 12, 1); if (!dsea) { dsea = (struct deviceSpec *) udf_add_extendedattr(inode, sizeof(struct deviceSpec) + - sizeof(regid), 12, 0x3, &tbh); + sizeof(regid), 12, 0x3); dsea->attrType = 12; dsea->attrSubtype = 1; dsea->attrLength = sizeof(struct deviceSpec) + @@ -1396,8 +1424,6 @@ eid->identSuffix[1] = UDF_OS_ID_LINUX; dsea->majorDeviceIdent = cpu_to_le32(imajor(inode)); dsea->minorDeviceIdent = cpu_to_le32(iminor(inode)); - mark_buffer_dirty_inode(tbh, inode); - udf_release_data(tbh); } if (UDF_I_EFE(inode) == 0) @@ -1493,6 +1519,8 @@ fe->icbTag.fileType = ICBTAG_FILE_TYPE_CHAR; else if (S_ISFIFO(inode->i_mode)) fe->icbTag.fileType = ICBTAG_FILE_TYPE_FIFO; + else if (S_ISSOCK(inode->i_mode)) + fe->icbTag.fileType = ICBTAG_FILE_TYPE_SOCKET; icbflags = UDF_I_ALLOCTYPE(inode) | ((inode->i_mode & S_ISUID) ? ICBTAG_FLAG_SETUID : 0) | @@ -1625,7 +1653,7 @@ int err, loffset; lb_addr obloc = *bloc; - if (!(bloc->logicalBlockNum = udf_new_block(inode->i_sb, inode, + if (!(bloc->logicalBlockNum = udf_new_block(inode->i_sb, NULL, obloc.partitionReferenceNum, obloc.logicalBlockNum, &err))) { return -1; @@ -1833,7 +1861,7 @@ if (!(*extoffset)) *extoffset = sizeof(struct allocExtDesc); ptr = (*bh)->b_data + *extoffset; - alen = le32_to_cpu(((struct allocExtDesc *)(*bh)->b_data)->lengthAllocDescs); + alen = sizeof(struct allocExtDesc) + le32_to_cpu(((struct allocExtDesc *)(*bh)->b_data)->lengthAllocDescs); } switch (UDF_I_ALLOCTYPE(inode)) diff -Nru a/fs/udf/misc.c b/fs/udf/misc.c --- a/fs/udf/misc.c Sun Mar 14 14:20:07 2004 +++ b/fs/udf/misc.c Sun Mar 14 14:20:07 2004 @@ -16,7 +16,7 @@ * Each contributing author retains all rights to their own work. * * (C) 1998 Dave Boynton - * (C) 1998-2001 Ben Fennema + * (C) 1998-2004 Ben Fennema * (C) 1999-2000 Stelias Computing Inc * * HISTORY @@ -34,18 +34,6 @@ #include "udf_i.h" #include "udf_sb.h" -uint32_t -udf64_low32(uint64_t indat) -{ - return indat & 0x00000000FFFFFFFFULL; -} - -uint32_t -udf64_high32(uint64_t indat) -{ - return indat >> 32; -} - extern struct buffer_head * udf_tgetblk(struct super_block *sb, int block) { @@ -66,42 +54,24 @@ extern struct genericFormat * udf_add_extendedattr(struct inode * inode, uint32_t size, uint32_t type, - uint8_t loc, struct buffer_head **bh) + uint8_t loc) { uint8_t *ea = NULL, *ad = NULL; - long_ad eaicb; int offset; + uint16_t crclen; + int i; - *bh = udf_tread(inode->i_sb, inode->i_ino); - - if (UDF_I_EFE(inode) == 0) - { - struct fileEntry *fe; - - fe = (struct fileEntry *)(*bh)->b_data; - eaicb = lela_to_cpu(fe->extendedAttrICB); - offset = sizeof(struct fileEntry); - } - else - { - struct extendedFileEntry *efe; - - efe = (struct extendedFileEntry *)(*bh)->b_data; - eaicb = lela_to_cpu(efe->extendedAttrICB); - offset = sizeof(struct extendedFileEntry); - } - - ea = &(*bh)->b_data[offset]; + ea = UDF_I_DATA(inode); if (UDF_I_LENEATTR(inode)) - offset += UDF_I_LENEATTR(inode); + ad = UDF_I_DATA(inode) + UDF_I_LENEATTR(inode); else + { + ad = ea; size += sizeof(struct extendedAttrHeaderDesc); + } - ad = &(*bh)->b_data[offset]; - if (UDF_I_LENALLOC(inode)) - offset += UDF_I_LENALLOC(inode); - - offset = inode->i_sb->s_blocksize - offset; + offset = inode->i_sb->s_blocksize - udf_file_entry_alloc_offset(inode) - + UDF_I_LENALLOC(inode); /* TODO - Check for FreeEASpace */ @@ -121,7 +91,6 @@ if (le16_to_cpu(eahd->descTag.tagIdent) != TAG_IDENT_EAHD || le32_to_cpu(eahd->descTag.tagLocation) != UDF_I_LOCATION(inode).logicalBlockNum) { - udf_release_data(*bh); return NULL; } } @@ -130,8 +99,11 @@ size -= sizeof(struct extendedAttrHeaderDesc); UDF_I_LENEATTR(inode) += sizeof(struct extendedAttrHeaderDesc); eahd->descTag.tagIdent = cpu_to_le16(TAG_IDENT_EAHD); - eahd->descTag.descVersion = cpu_to_le16(2); - eahd->descTag.tagSerialNum = cpu_to_le16(1); + if (UDF_SB_UDFREV(inode->i_sb) >= 0x0200) + eahd->descTag.descVersion = cpu_to_le16(3); + else + eahd->descTag.descVersion = cpu_to_le16(2); + eahd->descTag.tagSerialNum = cpu_to_le16(UDF_SB_SERIALNUM(inode->i_sb)); eahd->descTag.tagLocation = cpu_to_le32(UDF_I_LOCATION(inode).logicalBlockNum); eahd->impAttrLocation = cpu_to_le32(0xFFFFFFFF); eahd->appAttrLocation = cpu_to_le32(0xFFFFFFFF); @@ -169,45 +141,30 @@ } } /* rewrite CRC + checksum of eahd */ + crclen = sizeof(struct extendedAttrHeaderDesc) - sizeof(tag); + eahd->descTag.descCRCLength = cpu_to_le16(crclen); + eahd->descTag.descCRC = cpu_to_le16(udf_crc((char *)eahd + sizeof(tag), crclen, 0)); + eahd->descTag.tagChecksum = 0; + for (i=0; i<16; i++) + if (i != 4) + eahd->descTag.tagChecksum += ((uint8_t *)&(eahd->descTag))[i]; UDF_I_LENEATTR(inode) += size; return (struct genericFormat *)&ea[offset]; } if (loc & 0x02) { } - udf_release_data(*bh); return NULL; } extern struct genericFormat * -udf_get_extendedattr(struct inode * inode, uint32_t type, uint8_t subtype, - struct buffer_head **bh) +udf_get_extendedattr(struct inode *inode, uint32_t type, uint8_t subtype) { struct genericFormat *gaf; uint8_t *ea = NULL; - long_ad eaicb; uint32_t offset; - *bh = udf_tread(inode->i_sb, inode->i_ino); - - if (UDF_I_EFE(inode) == 0) - { - struct fileEntry *fe; - - fe = (struct fileEntry *)(*bh)->b_data; - eaicb = lela_to_cpu(fe->extendedAttrICB); - if (UDF_I_LENEATTR(inode)) - ea = fe->extendedAttr; - } - else - { - struct extendedFileEntry *efe; - - efe = (struct extendedFileEntry *)(*bh)->b_data; - eaicb = lela_to_cpu(efe->extendedAttrICB); - if (UDF_I_LENEATTR(inode)) - ea = efe->extendedAttr; - } + ea = UDF_I_DATA(inode); if (UDF_I_LENEATTR(inode)) { @@ -218,7 +175,6 @@ if (le16_to_cpu(eahd->descTag.tagIdent) != TAG_IDENT_EAHD || le32_to_cpu(eahd->descTag.tagLocation) != UDF_I_LOCATION(inode).logicalBlockNum) { - udf_release_data(*bh); return NULL; } @@ -237,12 +193,6 @@ else offset += le32_to_cpu(gaf->attrLength); } - } - - udf_release_data(*bh); - if (eaicb.extLength) - { - /* TODO */ } return NULL; } diff -Nru a/fs/udf/namei.c b/fs/udf/namei.c --- a/fs/udf/namei.c Sun Mar 14 14:20:08 2004 +++ b/fs/udf/namei.c Sun Mar 14 14:20:08 2004 @@ -15,7 +15,7 @@ * ftp://prep.ai.mit.edu/pub/gnu/GPL * Each contributing author retains all rights to their own work. * - * (C) 1998-2001 Ben Fennema + * (C) 1998-2004 Ben Fennema * (C) 1999-2000 Stelias Computing Inc * * HISTORY @@ -36,11 +36,11 @@ #include #include -static inline int udf_match(int len, const char * const name, struct qstr *qs) +static inline int udf_match(int len1, const char *name1, int len2, const char *name2) { - if (len != qs->len) + if (len1 != len2) return 0; - return !memcmp(name, qs->name, len); + return !memcmp(name1, name2, len1); } int udf_write_fi(struct inode *inode, struct fileIdentDesc *cfi, @@ -154,8 +154,8 @@ { struct fileIdentDesc *fi=NULL; loff_t f_pos; - int block, flen; - char fname[255]; + int block, namelen; + char name[UDF_NAME_LEN], fname[UDF_NAME_LEN]; char *nameptr; uint8_t lfi; uint16_t liu; @@ -167,6 +167,9 @@ if (!dir) return NULL; + if ( !(namelen = udf_put_filename(dir->i_sb, dentry->d_name.name, name, dentry->d_name.len))) + return NULL; + f_pos = (udf_ext0_offset(dir) >> 2); fibh->soffset = fibh->eoffset = (f_pos & ((dir->i_sb->s_blocksize - 1) >> 2)) << 2; @@ -250,13 +253,10 @@ if (!lfi) continue; - if ((flen = udf_get_filename(dir->i_sb, nameptr, fname, lfi))) + if (udf_match(namelen, name, lfi, nameptr)) { - if (udf_match(flen, fname, &(dentry->d_name))) - { - udf_release_data(bh); - return fi; - } + udf_release_data(bh); + return fi; } } if (fibh->sbh != fibh->ebh) @@ -306,7 +306,7 @@ struct fileIdentDesc cfi, *fi; struct udf_fileident_bh fibh; - if (dentry->d_name.len > UDF_NAME_LEN) + if (dentry->d_name.len > UDF_NAME_LEN-2) return ERR_PTR(-ENAMETOOLONG); lock_kernel(); @@ -353,7 +353,6 @@ char name[UDF_NAME_LEN], fname[UDF_NAME_LEN]; int namelen; loff_t f_pos; - int flen; char *nameptr; loff_t size = (udf_ext0_offset(dir) + dir->i_size) >> 2; int nfidlen; @@ -481,8 +480,7 @@ if (!lfi || !dentry) continue; - if ((flen = udf_get_filename(dir->i_sb, nameptr, fname, lfi)) && - udf_match(flen, fname, &(dentry->d_name))) + if (udf_match(namelen, name, lfi, nameptr)) { if (fibh->sbh != fibh->ebh) udf_release_data(fibh->ebh); @@ -674,8 +672,8 @@ { struct inode * inode; struct udf_fileident_bh fibh; - int err; struct fileIdentDesc cfi, *fi; + int err; if (!old_valid_dev(rdev)) return -EINVAL; @@ -721,8 +719,8 @@ { struct inode * inode; struct udf_fileident_bh fibh; - int err; struct fileIdentDesc cfi, *fi; + int err; lock_kernel(); err = -EMLINK; @@ -1119,8 +1117,8 @@ { struct inode *inode = old_dentry->d_inode; struct udf_fileident_bh fibh; - int err; struct fileIdentDesc cfi, *fi; + int err; lock_kernel(); if (inode->i_nlink >= (256<i_nlink))-1) diff -Nru a/fs/udf/osta_udf.h b/fs/udf/osta_udf.h --- a/fs/udf/osta_udf.h Sun Mar 14 14:20:07 2004 +++ b/fs/udf/osta_udf.h Sun Mar 14 14:20:07 2004 @@ -1,10 +1,10 @@ /* * osta_udf.h * - * This file is based on OSTA UDF(tm) 2.01 (March 15, 2000) + * This file is based on OSTA UDF(tm) 2.50 (April 30, 2003) * http://www.osta.org * - * Copyright (c) 2001-2002 Ben Fennema + * Copyright (c) 2001-2004 Ben Fennema * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -37,12 +37,12 @@ #ifndef _OSTA_UDF_H #define _OSTA_UDF_H 1 -/* OSTA CS0 Charspec (UDF 2.01 2.1.2) */ +/* OSTA CS0 Charspec (UDF 2.50 2.1.2) */ #define UDF_CHAR_SET_TYPE 0 #define UDF_CHAR_SET_INFO "OSTA Compressed Unicode" -/* Entity Identifier (UDF 2.01 2.1.5) */ -/* Identifiers (UDF 2.01 2.1.5.2) */ +/* Entity Identifier (UDF 2.50 2.1.5) */ +/* Identifiers (UDF 2.50 2.1.5.2) */ #define UDF_ID_DEVELOPER "*Linux UDFFS" #define UDF_ID_COMPLIANT "*OSTA UDF Compliant" #define UDF_ID_LV_INFO "*UDF LV Info" @@ -59,8 +59,9 @@ #define UDF_ID_SPARABLE "*UDF Sparable Partition" #define UDF_ID_ALLOC "*UDF Virtual Alloc Tbl" #define UDF_ID_SPARING "*UDF Sparing Table" +#define UDF_ID_METADATA "*UDF Metadata Partition" -/* Identifier Suffix (UDF 2.01 2.1.5.3) */ +/* Identifier Suffix (UDF 2.50 2.1.5.3) */ #define IS_DF_HARD_WRITE_PROTECT 0x01 #define IS_DF_SOFT_WRITE_PROTECT 0x02 @@ -84,8 +85,8 @@ uint8_t impUse[8]; } __attribute__ ((packed)); -/* Logical Volume Integrity Descriptor (UDF 2.01 2.2.6) */ -/* Implementation Use (UDF 2.01 2.2.6.4) */ +/* Logical Volume Integrity Descriptor (UDF 2.50 2.2.6) */ +/* Implementation Use (UDF 2.50 2.2.6.4) */ struct logicalVolIntegrityDescImpUse { regid impIdent; @@ -97,8 +98,8 @@ uint8_t impUse[0]; } __attribute__ ((packed)); -/* Implementation Use Volume Descriptor (UDF 2.01 2.2.7) */ -/* Implementation Use (UDF 2.01 2.2.7.2) */ +/* Implementation Use Volume Descriptor (UDF 2.50 2.2.7) */ +/* Implementation Use (UDF 2.50 2.2.7.2) */ struct impUseVolDescImpUse { charspec LVICharset; @@ -120,7 +121,7 @@ uint16_t partitionNum; } __attribute__ ((packed)); -/* Virtual Partition Map (UDF 2.01 2.2.8) */ +/* Virtual Partition Map (UDF 2.50 2.2.8) */ struct virtualPartitionMap { uint8_t partitionMapType; @@ -132,7 +133,7 @@ uint8_t reserved2[24]; } __attribute__ ((packed)); -/* Sparable Partition Map (UDF 2.01 2.2.9) */ +/* Sparable Partition Map (UDF 2.50 2.2.9) */ struct sparablePartitionMap { uint8_t partitionMapType; @@ -148,25 +149,43 @@ uint32_t locSparingTable[4]; } __attribute__ ((packed)); +/* Metadata Partition Map (UDF 2.4.0 2.2.10) */ +struct metadataPartitionMap +{ + uint8_t partitionMapType; + uint8_t partitionMapLength; + uint8_t reserved1[2]; + regid partIdent; + uint16_t volSeqNum; + uint16_t partitionNum; + uint32_t metadataFileLoc; + uint32_t metadataMirrorFileLoc; + uint32_t metadataBitmapFileLoc; + uint32_t allocUnitSize; + uint16_t alignUnitSize; + uint8_t flags; + uint8_t reserved2[5]; +} __attribute__ ((packed)); + /* Virtual Allocation Table (UDF 1.5 2.2.10) */ struct virtualAllocationTable15 { uint32_t VirtualSector[0]; - regid ident; - uint32_t previousVATICB; + regid vatIdent; + uint32_t previousVATICBLoc; } __attribute__ ((packed)); #define ICBTAG_FILE_TYPE_VAT15 0x00U -/* Virtual Allocation Table (UDF 2.01 2.2.10) */ +/* Virtual Allocation Table (UDF 2.50 2.2.11) */ struct virtualAllocationTable20 { uint16_t lengthHeader; uint16_t lengthImpUse; dstring logicalVolIdent[128]; - uint32_t previousVatICBLoc; - uint32_t numFIDSFiles; - uint32_t numFIDSDirectories; + uint32_t previousVATICBLoc; + uint32_t numFiles; + uint32_t numDirs; uint16_t minReadRevision; uint16_t minWriteRevision; uint16_t maxWriteRevision; @@ -177,7 +196,7 @@ #define ICBTAG_FILE_TYPE_VAT20 0xF8U -/* Sparing Table (UDF 2.01 2.2.11) */ +/* Sparing Table (UDF 2.50 2.2.12) */ struct sparingEntry { uint32_t origLocation; @@ -195,7 +214,12 @@ mapEntry[0]; } __attribute__ ((packed)); -/* struct long_ad ICB - ADImpUse (UDF 2.01 2.2.4.3) */ +/* Metadata File (and Metadata Mirror File) (UDF 2.50 2.2.13.1) */ +#define ICBTAG_FILE_TYPE_MAIN 0xFA +#define ICBTAG_FILE_TYPE_MIRROR 0xFB +#define ICBTAG_FILE_TYPE_BITMAP 0xFC + +/* struct long_ad ICB - ADImpUse (UDF 2.50 2.2.4.3) */ struct allocDescImpUse { uint16_t flags; @@ -204,18 +228,18 @@ #define AD_IU_EXT_ERASED 0x0001 -/* Real-Time Files (UDF 2.01 6.11) */ +/* Real-Time Files (UDF 2.50 6.11) */ #define ICBTAG_FILE_TYPE_REALTIME 0xF9U -/* Implementation Use Extended Attribute (UDF 2.01 3.3.4.5) */ -/* FreeEASpace (UDF 2.01 3.3.4.5.1.1) */ +/* Implementation Use Extended Attribute (UDF 2.50 3.3.4.5) */ +/* FreeEASpace (UDF 2.50 3.3.4.5.1.1) */ struct freeEaSpace { uint16_t headerChecksum; uint8_t freeEASpace[0]; } __attribute__ ((packed)); -/* DVD Copyright Management Information (UDF 2.01 3.3.4.5.1.2) */ +/* DVD Copyright Management Information (UDF 2.50 3.3.4.5.1.2) */ struct DVDCopyrightImpUse { uint16_t headerChecksum; @@ -224,21 +248,21 @@ uint8_t protectionSystemInfo[4]; } __attribute__ ((packed)); -/* Application Use Extended Attribute (UDF 2.01 3.3.4.6) */ -/* FreeAppEASpace (UDF 2.01 3.3.4.6.1) */ +/* Application Use Extended Attribute (UDF 2.50 3.3.4.6) */ +/* FreeAppEASpace (UDF 2.50 3.3.4.6.1) */ struct freeAppEASpace { uint16_t headerChecksum; uint8_t freeEASpace[0]; } __attribute__ ((packed)); -/* UDF Defined System Stream (UDF 2.01 3.3.7) */ +/* UDF Defined System Stream (UDF 2.50 3.3.7) */ #define UDF_ID_UNIQUE_ID "*UDF Unique ID Mapping Data" #define UDF_ID_NON_ALLOC "*UDF Non-Allocatable Space" #define UDF_ID_POWER_CAL "*UDF Power Cal Table" #define UDF_ID_BACKUP "*UDF Backup" -/* Operating System Identifiers (UDF 2.01 6.3) */ +/* Operating System Identifiers (UDF 2.50 6.3) */ #define UDF_OS_CLASS_UNDEF 0x00U #define UDF_OS_CLASS_DOS 0x01U #define UDF_OS_CLASS_OS2 0x02U @@ -254,6 +278,7 @@ #define UDF_OS_ID_DOS 0x00U #define UDF_OS_ID_OS2 0x00U #define UDF_OS_ID_MAC 0x00U +#define UDF_OS_ID_MAX_OSX 0x01U #define UDF_OS_ID_UNIX 0x00U #define UDF_OS_ID_AIX 0x01U #define UDF_OS_ID_SOLARIS 0x02U diff -Nru a/fs/udf/super.c b/fs/udf/super.c --- a/fs/udf/super.c Sun Mar 14 14:20:07 2004 +++ b/fs/udf/super.c Sun Mar 14 14:20:07 2004 @@ -26,7 +26,7 @@ * Each contributing author retains all rights to their own work. * * (C) 1998 Dave Boynton - * (C) 1998-2001 Ben Fennema + * (C) 1998-2004 Ben Fennema * (C) 2000 Stelias Computing Inc * * HISTORY @@ -57,6 +57,7 @@ #include #include #include +#include #include #include @@ -133,7 +134,8 @@ struct udf_inode_info *ei = (struct udf_inode_info *) foo; if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) == - SLAB_CTOR_CONSTRUCTOR) { + SLAB_CTOR_CONSTRUCTOR) + { ei->i_ext.i_data = NULL; inode_init_once(&ei->vfs_inode); } @@ -324,106 +326,106 @@ if (!options) return 1; - while ((p = strsep(&options, ",")) != NULL) { + while ((p = strsep(&options, ",")) != NULL) + { substring_t args[MAX_OPT_ARGS]; int token; if (!*p) continue; token = match_token(p, tokens, args); - switch (token) { - case Opt_novrs: - uopt->novrs = 1; - break; - case Opt_bs: - if (match_int(&args[0], &option)) - return 0; - uopt->blocksize = option; - break; - case Opt_unhide: - uopt->flags |= (1 << UDF_FLAG_UNHIDE); - break; - case Opt_undelete: - uopt->flags |= (1 << UDF_FLAG_UNDELETE); - break; - case Opt_noadinicb: - uopt->flags &= ~(1 << UDF_FLAG_USE_AD_IN_ICB); - break; - case Opt_adinicb: - uopt->flags |= (1 << UDF_FLAG_USE_AD_IN_ICB); - break; - case Opt_shortad: - uopt->flags |= (1 << UDF_FLAG_USE_SHORT_AD); - break; - case Opt_longad: - uopt->flags &= ~(1 << UDF_FLAG_USE_SHORT_AD); - break; - case Opt_gid: - if (match_int(args, &option)) - return 0; - uopt->gid = option; - break; - case Opt_uid: - if (match_int(args, &option)) - return 0; - uopt->uid = option; - break; - case Opt_umask: - if (match_octal(args, &option)) - return 0; - uopt->umask = option; - break; - case Opt_nostrict: - uopt->flags &= ~(1 << UDF_FLAG_STRICT); - break; - case Opt_session: - if (match_int(args, &option)) - return 0; - uopt->session = option; - break; - case Opt_lastblock: - if (match_int(args, &option)) - return 0; - uopt->lastblock = option; - break; - case Opt_anchor: - if (match_int(args, &option)) - return 0; - uopt->anchor = option; - break; - case Opt_volume: - if (match_int(args, &option)) - return 0; - uopt->volume = option; - break; - case Opt_partition: - if (match_int(args, &option)) - return 0; - uopt->partition = option; - break; - case Opt_fileset: - if (match_int(args, &option)) - return 0; - uopt->fileset = option; - break; - case Opt_rootdir: - if (match_int(args, &option)) - return 0; - uopt->rootdir = option; - break; - case Opt_utf8: - uopt->flags |= (1 << UDF_FLAG_UTF8); - break; + switch (token) + { + case Opt_novrs: + uopt->novrs = 1; + case Opt_bs: + if (match_int(&args[0], &option)) + return 0; + uopt->blocksize = option; + break; + case Opt_unhide: + uopt->flags |= (1 << UDF_FLAG_UNHIDE); + break; + case Opt_undelete: + uopt->flags |= (1 << UDF_FLAG_UNDELETE); + break; + case Opt_noadinicb: + uopt->flags &= ~(1 << UDF_FLAG_USE_AD_IN_ICB); + break; + case Opt_adinicb: + uopt->flags |= (1 << UDF_FLAG_USE_AD_IN_ICB); + break; + case Opt_shortad: + uopt->flags |= (1 << UDF_FLAG_USE_SHORT_AD); + break; + case Opt_longad: + uopt->flags &= ~(1 << UDF_FLAG_USE_SHORT_AD); + break; + case Opt_gid: + if (match_int(args, &option)) + return 0; + uopt->gid = option; + break; + case Opt_uid: + if (match_int(args, &option)) + return 0; + uopt->uid = option; + break; + case Opt_umask: + if (match_octal(args, &option)) + return 0; + uopt->umask = option; + break; + case Opt_nostrict: + uopt->flags &= ~(1 << UDF_FLAG_STRICT); + break; + case Opt_session: + if (match_int(args, &option)) + return 0; + uopt->session = option; + break; + case Opt_lastblock: + if (match_int(args, &option)) + return 0; + uopt->lastblock = option; + break; + case Opt_anchor: + if (match_int(args, &option)) + return 0; + uopt->anchor = option; + break; + case Opt_volume: + if (match_int(args, &option)) + return 0; + uopt->volume = option; + break; + case Opt_partition: + if (match_int(args, &option)) + return 0; + uopt->partition = option; + break; + case Opt_fileset: + if (match_int(args, &option)) + return 0; + uopt->fileset = option; + break; + case Opt_rootdir: + if (match_int(args, &option)) + return 0; + uopt->rootdir = option; + break; + case Opt_utf8: + uopt->flags |= (1 << UDF_FLAG_UTF8); + break; #if defined(CONFIG_NLS) || defined(CONFIG_NLS_MODULE) - case Opt_iocharset: - uopt->nls_map = load_nls(args[0].from); - uopt->flags |= (1 << UDF_FLAG_NLS_MAP); - break; + case Opt_iocharset: + uopt->nls_map = load_nls(args[0].from); + uopt->flags |= (1 << UDF_FLAG_NLS_MAP); + break; #endif - default: - printk(KERN_ERR "udf: bad mount option \"%s\" " - "or missing value\n", - p); + default: + printk(KERN_ERR "udf: bad mount option \"%s\" " + "or missing value\n", p); return 0; } } @@ -1651,23 +1653,9 @@ if (UDF_SB_PARTFLAGS(sb, UDF_SB_PARTITION(sb)) & UDF_PART_FLAG_FREED_TABLE) iput(UDF_SB_PARTMAPS(sb)[UDF_SB_PARTITION(sb)].s_fspace.s_table); if (UDF_SB_PARTFLAGS(sb, UDF_SB_PARTITION(sb)) & UDF_PART_FLAG_UNALLOC_BITMAP) - { - for (i=0; i