summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--arch/arm/Kconfig7
-rw-r--r--arch/arm/Makefile186
-rw-r--r--arch/arm/boot/Makefile156
-rw-r--r--arch/arm/boot/bootp/Makefile4
-rw-r--r--arch/arm/boot/compressed/Makefile24
-rw-r--r--arch/arm/kernel/dma-isa.c1
-rw-r--r--arch/arm/kernel/dma.c1
-rw-r--r--arch/arm/kernel/ecard.c48
-rw-r--r--arch/arm/kernel/irq.c3
-rw-r--r--arch/arm/kernel/plx90x0.c1
-rw-r--r--arch/arm/kernel/time-acorn.c1
-rw-r--r--arch/arm/kernel/time.c1
-rw-r--r--arch/arm/kernel/via82c505.c1
-rw-r--r--arch/arm/mach-adifcc/arch.c2
-rw-r--r--arch/arm/mach-adifcc/irq.c1
-rw-r--r--arch/arm/mach-anakin/irq.c1
-rw-r--r--arch/arm/mach-arc/dma.c1
-rw-r--r--arch/arm/mach-arc/oldlatches.c1
-rw-r--r--arch/arm/mach-clps711x/autcpu12.c1
-rw-r--r--arch/arm/mach-clps711x/cdb89712.c1
-rw-r--r--arch/arm/mach-clps711x/dma.c8
-rw-r--r--arch/arm/mach-clps711x/fortunet.c3
-rw-r--r--arch/arm/mach-clps711x/mm.c1
-rw-r--r--arch/arm/mach-clps711x/p720t.c1
-rw-r--r--arch/arm/mach-clps711x/time.c2
-rw-r--r--arch/arm/mach-ebsa110/time.c1
-rw-r--r--arch/arm/mach-epxa10db/arch.c3
-rw-r--r--arch/arm/mach-epxa10db/dma.c8
-rw-r--r--arch/arm/mach-epxa10db/time.c2
-rw-r--r--arch/arm/mach-footbridge/cats-hw.c1
-rw-r--r--arch/arm/mach-footbridge/dc21285.c1
-rw-r--r--arch/arm/mach-footbridge/dma.c1
-rw-r--r--arch/arm/mach-footbridge/irq.c2
-rw-r--r--arch/arm/mach-footbridge/isa-irq.c1
-rw-r--r--arch/arm/mach-footbridge/mm.c1
-rw-r--r--arch/arm/mach-footbridge/netwinder-hw.c1
-rw-r--r--arch/arm/mach-ftvpci/core.c1
-rw-r--r--arch/arm/mach-integrator/arch.c2
-rw-r--r--arch/arm/mach-integrator/dma.c1
-rw-r--r--arch/arm/mach-integrator/pci.c1
-rw-r--r--arch/arm/mach-integrator/pci_v3.c1
-rw-r--r--arch/arm/mach-integrator/time.c2
-rw-r--r--arch/arm/mach-iop310/arch.c2
-rw-r--r--arch/arm/mach-iop310/iop310-irq.c1
-rw-r--r--arch/arm/mach-iop310/iop310-pci.c2
-rw-r--r--arch/arm/mach-iop310/iq80310-irq.c4
-rw-r--r--arch/arm/mach-iop310/iq80310-time.c3
-rw-r--r--arch/arm/mach-iop310/xs80200-irq.c2
-rw-r--r--arch/arm/mach-pxa/dma.c1
-rw-r--r--arch/arm/mach-pxa/idp.c2
-rw-r--r--arch/arm/mach-pxa/irq.c1
-rw-r--r--arch/arm/mach-pxa/lubbock.c2
-rw-r--r--arch/arm/mach-pxa/pm.c1
-rw-r--r--arch/arm/mach-rpc/dma.c1
-rw-r--r--arch/arm/mach-sa1100/adsbitsy.c2
-rw-r--r--arch/arm/mach-sa1100/assabet.c1
-rw-r--r--arch/arm/mach-sa1100/dma.c2
-rw-r--r--arch/arm/mach-sa1100/flexanet.c1
-rw-r--r--arch/arm/mach-sa1100/graphicsclient.c2
-rw-r--r--arch/arm/mach-sa1100/graphicsmaster.c2
-rw-r--r--arch/arm/mach-sa1100/h3600.c1
-rw-r--r--arch/arm/mach-sa1100/irq.c2
-rw-r--r--arch/arm/mach-sa1100/neponset.c2
-rw-r--r--arch/arm/mach-sa1100/pm.c2
-rw-r--r--arch/arm/mach-sa1100/sa1111.c2
-rw-r--r--arch/arm/mach-sa1100/stork.c1
-rw-r--r--arch/arm/mach-sa1100/system3.c1
-rw-r--r--arch/arm/mach-shark/dma.c3
-rw-r--r--arch/arm/mach-tbox/core.c1
-rw-r--r--arch/arm/mm/Makefile23
-rw-r--r--arch/arm/mm/alignment.c2
-rw-r--r--arch/arm/mm/fault-armv.c72
-rw-r--r--arch/arm/mm/init.c1
-rw-r--r--arch/arm/mm/mm-armv.c29
-rw-r--r--arch/arm/mm/proc-arm1020.S8
-rw-r--r--arch/arm/mm/proc-arm6_7.S30
-rw-r--r--arch/arm/mm/proc-arm720.S10
-rw-r--r--arch/arm/mm/proc-arm920.S8
-rw-r--r--arch/arm/mm/proc-arm922.S8
-rw-r--r--arch/arm/mm/proc-arm926.S8
-rw-r--r--arch/arm/mm/proc-sa110.S12
-rw-r--r--arch/arm/mm/proc-syms.c6
-rw-r--r--arch/arm/mm/proc-xscale.S8
-rw-r--r--arch/arm/mm/tlb-v4wb.S57
-rw-r--r--arch/arm/mm/tlb-v4wbi.S68
-rw-r--r--arch/arm/tools/Makefile5
-rw-r--r--drivers/acorn/block/mfmhd.c126
-rw-r--r--drivers/acorn/net/ether1.c5
-rw-r--r--drivers/acorn/net/ether3.c5
-rw-r--r--drivers/acorn/net/etherh.c4
-rw-r--r--drivers/acorn/scsi/acornscsi.c282
-rw-r--r--drivers/acorn/scsi/arxescsi.c264
-rw-r--r--drivers/acorn/scsi/cumana_1.c308
-rw-r--r--drivers/acorn/scsi/cumana_2.c313
-rw-r--r--drivers/acorn/scsi/ecoscsi.c1
-rw-r--r--drivers/acorn/scsi/eesox.c337
-rw-r--r--drivers/acorn/scsi/fas216.c1565
-rw-r--r--drivers/acorn/scsi/fas216.h14
-rw-r--r--drivers/acorn/scsi/oak.c256
-rw-r--r--drivers/acorn/scsi/powertec.c348
-rw-r--r--drivers/acorn/scsi/queue.c22
-rw-r--r--drivers/acorn/scsi/queue.h9
-rw-r--r--drivers/char/raw.c1
-rw-r--r--drivers/pci/setup-bus.c2
-rw-r--r--drivers/pcmcia/i82092.c1
-rw-r--r--drivers/pcmcia/i82365.c15
-rw-r--r--fs/autofs/autofs_i.h1
-rw-r--r--fs/lockd/mon.c41
-rw-r--r--fs/lockd/xdr.c9
-rw-r--r--fs/lockd/xdr4.c9
-rw-r--r--fs/nfs/nfs2xdr.c21
-rw-r--r--include/asm-arm/ecard.h17
-rw-r--r--include/asm-arm/proc-armv/cache.h8
-rw-r--r--include/asm-arm/proc-armv/pgalloc.h20
-rw-r--r--include/asm-arm/proc-armv/pgtable.h11
-rw-r--r--include/asm-i386/unistd.h1
-rw-r--r--init/main.c2
-rw-r--r--kernel/module.c21
118 files changed, 2417 insertions, 2511 deletions
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index f45561d04695..4637eccd0d87 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -222,7 +222,7 @@ config SA1111
config FORCE_MAX_ZONEORDER
int
- depends on ASSABET_NEPONSET || SA1100_ADSBITSY || SA1100_BADGE4 || SA1100_CONSUS || SA1100_GRAPHICSMASTER || SA1100_JORNADA720 || ARCH_LUBBOCK || SA1100_PFS168 || SA1100_PT_SYSTEM3 || SA1100_XP860
+ depends on SA1111
default "9"
comment "Processor Type"
@@ -1043,11 +1043,6 @@ config KBDMOUSE
depends on ARCH_ACORN && BUSMOUSE=y && !ARCH_RPC
default y
-config RPCMOUSE
- bool
- depends on ARCH_ACORN && BUSMOUSE=y && ARCH_RPC
- default y
-
source "drivers/media/Kconfig"
source "fs/Kconfig"
diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index 1eab6ab76d79..ba4f87eef389 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -34,14 +34,12 @@ apcs-$(CONFIG_CPU_26) :=-mapcs-26 -mcpu=arm3
# Note that GCC is lame - it doesn't numerically define an
# architecture version macro, but instead defines a whole
# series of macros.
-arch-y :=
arch-$(CONFIG_CPU_32v3) :=-D__LINUX_ARM_ARCH__=3 -march=armv3
arch-$(CONFIG_CPU_32v4) :=-D__LINUX_ARM_ARCH__=4 -march=armv4
arch-$(CONFIG_CPU_32v5) :=-D__LINUX_ARM_ARCH__=5 -march=armv5
arch-$(CONFIG_CPU_XSCALE) :=-D__LINUX_ARM_ARCH__=5 -march=armv4 -Wa,-mxscale #-march=armv5te
# This selects how we optimise for the processor.
-tune-y :=
tune-$(CONFIG_CPU_ARM610) :=-mtune=arm610
tune-$(CONFIG_CPU_ARM710) :=-mtune=arm710
tune-$(CONFIG_CPU_ARM720T) :=-mtune=arm7tdmi
@@ -58,123 +56,67 @@ CFLAGS_BOOT :=$(apcs-y) $(arch-y) $(tune-y) -mshort-load-bytes -msoft-float -Wa,
CFLAGS +=$(apcs-y) $(arch-y) $(tune-y) -mshort-load-bytes -msoft-float -Wa,-mno-fpu
AFLAGS +=$(apcs-y) $(arch-y) -mno-fpu -msoft-float -Wa,-mno-fpu
+#Default value
+DATAADDR := .
+
ifeq ($(CONFIG_CPU_26),y)
PROCESSOR := armo
HEAD := arch/arm/mach-arc/head.o arch/arm/kernel/init_task.o
LDFLAGS_BLOB += --oformat elf26-littlearm
ifeq ($(CONFIG_ROM_KERNEL),y)
- DATAADDR = 0x02080000
- TEXTADDR = 0x03800000
+ DATAADDR := 0x02080000
+ textaddr-y := 0x03800000
else
- TEXTADDR = 0x02080000
+ textaddr-y := 0x02080000
endif
endif
ifeq ($(CONFIG_CPU_32),y)
-PROCESSOR = armv
+PROCESSOR := armv
HEAD := arch/arm/kernel/head.o arch/arm/kernel/init_task.o
-TEXTADDR = 0xC0008000
LDFLAGS_BLOB += --oformat elf32-littlearm
-endif
-
-ifeq ($(CONFIG_ARCH_ARCA5K),y)
-MACHINE = arc
-endif
-
-ifeq ($(CONFIG_ARCH_RPC),y)
-MACHINE = rpc
-endif
-
-ifeq ($(CONFIG_ARCH_EBSA110),y)
-MACHINE = ebsa110
-endif
-
-ifeq ($(CONFIG_ARCH_CLPS7500),y)
-MACHINE = clps7500
-INCDIR = cl7500
-endif
-
-ifeq ($(CONFIG_FOOTBRIDGE),y)
-MACHINE = footbridge
-INCDIR = ebsa285
-endif
-
-ifeq ($(CONFIG_ARCH_CO285),y)
-TEXTADDR = 0x60008000
-MACHINE = footbridge
-INCDIR = ebsa285
-endif
-
-ifeq ($(CONFIG_ARCH_FTVPCI),y)
-MACHINE = ftvpci
-INCDIR = nexuspci
-endif
-
-ifeq ($(CONFIG_ARCH_TBOX),y)
-MACHINE = tbox
-endif
-
-ifeq ($(CONFIG_ARCH_SHARK),y)
-MACHINE = shark
-endif
-
+textaddr-y := 0xC0008000
+endif
+
+ machine-$(CONFIG_ARCH_ARCA5K) := arc
+ machine-$(CONFIG_ARCH_RPC) := rpc
+ machine-$(CONFIG_ARCH_EBSA110) := ebsa110
+ machine-$(CONFIG_ARCH_CLPS7500) := clps7500
+ incdir-$(CONFIG_ARCH_CLPS7500) := cl7500
+ machine-$(CONFIG_FOOTBRIDGE) := footbridge
+ incdir-$(CONFIG_FOOTBRIDGE) := ebsa285
+textaddr-$(CONFIG_ARCH_CO285) := 0x60008000
+ machine-$(CONFIG_ARCH_CO285) := footbridge
+ incdir-$(CONFIG_ARCH_CO285) := ebsa285
+ machine-$(CONFIG_ARCH_FTVPCI) := ftvpci
+ incdir-$(CONFIG_ARCH_FTVPCI) := nexuspci
+ machine-$(CONFIG_ARCH_TBOX) := tbox
+ machine-$(CONFIG_ARCH_SHARK) := shark
+ machine-$(CONFIG_ARCH_SA1100) := sa1100
ifeq ($(CONFIG_ARCH_SA1100),y)
-ifeq ($(CONFIG_SA1111),y)
# SA1111 DMA bug: we don't want the kernel to live in precious DMA-able memory
-TEXTADDR = 0xc0208000
-endif
-MACHINE = sa1100
-endif
-
-ifeq ($(CONFIG_ARCH_PXA),y)
-MACHINE = pxa
-endif
-
-ifeq ($(CONFIG_ARCH_L7200),y)
-MACHINE = l7200
-endif
-
-ifeq ($(CONFIG_ARCH_INTEGRATOR),y)
-MACHINE = integrator
-endif
-
-ifeq ($(CONFIG_ARCH_CAMELOT),y)
-MACHINE = epxa10db
-endif
-
-ifeq ($(CONFIG_ARCH_CLPS711X),y)
-TEXTADDR = 0xc0028000
-MACHINE = clps711x
-endif
-
-ifeq ($(CONFIG_ARCH_FORTUNET),y)
-TEXTADDR = 0xc0008000
-endif
-
-ifeq ($(CONFIG_ARCH_ANAKIN),y)
-MACHINE = anakin
-endif
-
-ifeq ($(CONFIG_ARCH_IOP310),y)
-MACHINE = iop310
-endif
-
-ifeq ($(CONFIG_ARCH_ADIFCC),y)
-MACHINE = adifcc
-endif
-
+textaddr-$(CONFIG_SA1111) := 0xc0208000
+endif
+ machine-$(CONFIG_ARCH_PXA) := pxa
+ machine-$(CONFIG_ARCH_L7200) := l7200
+ machine-$(CONFIG_ARCH_INTEGRATOR) := integrator
+ machine-$(CONFIG_ARCH_CAMELOT) := epxa10db
+textaddr-$(CONFIG_ARCH_CLPS711X) := 0xc0028000
+ machine-$(CONFIG_ARCH_CLPS711X) := clps711x
+textaddr-$(CONFIG_ARCH_FORTUNET) := 0xc0008000
+ machine-$(CONFIG_ARCH_ANAKIN) := anakin
+ machine-$(CONFIG_ARCH_IOP310) := iop310
+ machine-$(CONFIG_ARCH_ADIFCC) := adifcc
+
+MACHINE := $(machine-y)
+TEXTADDR := $(textaddr-y)
+ifeq ($(incdir-y),)
+incdir-y := $(MACHINE)
+endif
+INCDIR := $(incdir-y)
+
export MACHINE PROCESSOR TEXTADDR GZFLAGS CFLAGS_BOOT
-# Only set INCDIR if its not already defined above
-# Grr, ?= doesn't work as all the other assignment operators do. Make bug?
-ifeq ($(origin INCDIR), undefined)
-INCDIR :=$(MACHINE)
-endif
-
-ifeq ($(origin DATAADDR), undefined)
-DATAADDR := .
-endif
-
# Do we have FASTFPE?
FASTFPE :=arch/arm/fastfpe
ifeq ($(FASTFPE),$(wildcard $(FASTFPE)))
@@ -194,7 +136,10 @@ drivers-$(CONFIG_ARCH_L7200) += drivers/acorn/char/
libs-y += arch/arm/lib/
-makeboot = $(call descend,arch/arm/boot,$(1))
+# Default target when executing plain make
+all: zImage
+
+makeboot =$(Q)$(MAKE) -f scripts/Makefile.build obj=arch/arm/boot $(1)
# Update machine arch and proc symlinks if something which affects
# them changed. We use .arch and .proc to indicate when they were
@@ -217,13 +162,17 @@ prepare: maketools
.PHONY: maketools FORCE
maketools: include/asm-arm/.arch include/asm-arm/.proc \
include/asm-arm/constants.h include/linux/version.h FORCE
- +@$(call descend,arch/arm/tools, include/asm-arm/mach-types.h)
+ $(Q)$(MAKE) -f scripts/Makefile.build obj=arch/arm/tools include/asm-arm/mach-types.h
+
+# Convert bzImage to zImage
+bzImage: vmlinux
+ $(call makeboot,arch/arm/boot/zImage)
zImage Image bootpImage: vmlinux
- +@$(call makeboot,arch/arm/boot/$@)
+ $(call makeboot,arch/arm/boot/$@)
-bzImage zinstall install: vmlinux
- +@$(call makeboot,$@)
+zinstall install: vmlinux
+ $(call makeboot,$@)
MRPROPER_FILES += \
include/asm-arm/arch include/asm-arm/.arch \
@@ -233,15 +182,15 @@ MRPROPER_FILES += \
# We use MRPROPER_FILES and CLEAN_FILES now
archmrproper:
-archclean: FORCE
- +@$(call makeboot,clean)
+archclean:
+ $(Q)$(MAKE) -f scripts/Makefile.clean obj=arch/arm/boot
# My testing targets (that short circuit a few dependencies)
-zImg:; +@$(call makeboot, zImage)
-Img:; +@$(call makeboot, Image)
-i:; +@$(call makeboot, install)
-zi:; +@$(call makeboot, zinstall)
-bp:; +@$(call makeboot, bootpImage)
+zImg:; $(call makeboot, arch/arm/boot/zImage)
+Img:; $(call makeboot, arch/arm/boot/Image)
+bp:; $(call makeboot, arch/arm/boot/bootpImage)
+i:; $(call makeboot, install)
+zi:; $(call makeboot, zinstall)
#
# Configuration targets. Use these to select a
@@ -261,10 +210,9 @@ bp:; +@$(call makeboot, bootpImage)
arch/$(ARCH)/kernel/asm-offsets.s: include/asm include/linux/version.h \
include/config/MARKER
+ @:
-include/asm-$(ARCH)/constants.h.tmp: arch/$(ARCH)/kernel/asm-offsets.s
- @$(generate-asm-offsets.h) < $< > $@
-
-include/asm-$(ARCH)/constants.h: include/asm-$(ARCH)/constants.h.tmp
+include/asm-$(ARCH)/constants.h: arch/$(ARCH)/kernel/asm-offsets.s
@echo -n ' Generating $@'
+ @$(generate-asm-offsets.h) < $< > $@.tmp
@$(update-if-changed)
diff --git a/arch/arm/boot/Makefile b/arch/arm/boot/Makefile
index 6c5a970afb58..61eeee5c544f 100644
--- a/arch/arm/boot/Makefile
+++ b/arch/arm/boot/Makefile
@@ -13,132 +13,81 @@
# PARAMS_PHYS must be with 4MB of ZRELADDR
# INITRD_PHYS must be in RAM
-ifeq ($(CONFIG_CPU_26),y)
-ZRELADDR = 0x02080000
-PARAMS_PHYS = 0x0207c000
-INITRD_PHYS = 0x02180000
-endif
-
-ifeq ($(CONFIG_ARCH_RPC),y)
-ZRELADDR = 0x10008000
-PARAMS_PHYS = 0x10000100
-INITRD_PHYS = 0x18000000
-endif
-
-ifeq ($(CONFIG_ARCH_CLPS7500),y)
-ZRELADDR = 0x10008000
-endif
-
-ifeq ($(CONFIG_ARCH_EBSA110),y)
-ZRELADDR = 0x00008000
-PARAMS_PHYS = 0x00000400
-INITRD_PHYS = 0x00800000
-endif
-
-ifeq ($(CONFIG_ARCH_SHARK),y)
-ZTEXTADDR = 0x08508000
-ZRELADDR = 0x08008000
-endif
-
-ifeq ($(CONFIG_FOOTBRIDGE),y)
-ZRELADDR = 0x00008000
-PARAMS_PHYS = 0x00000100
-INITRD_PHYS = 0x00800000
-endif
-
-ifeq ($(CONFIG_ARCH_INTEGRATOR),y)
-ZRELADDR = 0x00008000
-PARAMS_PHYS = 0x00000100
-INITRD_PHYS = 0x00800000
-endif
-
-ifeq ($(CONFIG_ARCH_CAMELOT),y)
-ZRELADDR = 0x00008000
-endif
-
-ifeq ($(CONFIG_ARCH_NEXUSPCI),y)
-ZRELADDR = 0x40008000
-endif
-
-ifeq ($(CONFIG_ARCH_L7200),y)
-ZRELADDR = 0xf0008000
-endif
-
+ zreladdr-$(CONFIG_CPU_26) := 0x02080000
+params_phys-$(CONFIG_CPU_26) := 0x0207c000
+initrd_phys-$(CONFIG_CPU_26) := 0x02180000
+ zreladdr-$(CONFIG_ARCH_RPC) := 0x10008000
+params_phys-$(CONFIG_ARCH_RPC) := 0x10000100
+initrd_phys-$(CONFIG_ARCH_RPC) := 0x18000000
+ zreladdr-$(CONFIG_ARCH_CLPS7500) := 0x10008000
+ zreladdr-$(CONFIG_ARCH_CLPS7500) := 0x10008000
+ zreladdr-$(CONFIG_ARCH_EBSA110) := 0x00008000
+params_phys-$(CONFIG_ARCH_EBSA110) := 0x00000400
+initrd_phys-$(CONFIG_ARCH_EBSA110) := 0x00800000
+ ztextaddr-$(CONFIG_ARCH_SHARK) := 0x08508000
+ zreladdr-$(CONFIG_ARCH_SHARK) := 0x08008000
+ zreladdr-$(CONFIG_FOOTBRIDGE) := 0x00008000
+params_phys-$(CONFIG_FOOTBRIDGE) := 0x00000100
+initrd_phys-$(CONFIG_FOOTBRIDGE) := 0x00800000
+ zreladdr-$(CONFIG_ARCH_INTEGRATOR) := 0x00008000
+params_phys-$(CONFIG_ARCH_INTEGRATOR) := 0x00000100
+initrd_phys-$(CONFIG_ARCH_INTEGRATOR) := 0x00800000
+ zreladdr-$(CONFIG_ARCH_CAMELOT) := 0x00008000
+ zreladdr-$(CONFIG_ARCH_NEXUSPCI) := 0x40008000
+ zreladdr-$(CONFIG_ARCH_L7200) := 0xf0008000
# The standard locations for stuff on CLPS711x type processors
-ifeq ($(CONFIG_ARCH_CLPS711X),y)
-ZRELADDR = 0xc0028000
-PARAMS_PHYS = 0xc0000100
-endif
-
+ zreladdr-$(CONFIG_ARCH_CLPS711X) := 0xc0028000
+params_phys-$(CONFIG_ARCH_CLPS711X) := 0xc0000100
# Should probably have some agreement on these...
-ifeq ($(CONFIG_ARCH_P720T),y)
-INITRD_PHYS = 0xc0400000
-endif
-ifeq ($(CONFIG_ARCH_CDB89712),y)
-INITRD_PHYS = 0x00700000
-endif
-
+initrd_phys-$(CONFIG_ARCH_P720T) := 0xc0400000
+initrd_phys-$(CONFIG_ARCH_CDB89712) := 0x00700000
+ zreladdr-$(CONFIG_ARCH_SA1100) := 0xc0008000
ifeq ($(CONFIG_ARCH_SA1100),y)
-ZRELADDR = 0xc0008000
-# No defconfig file to move this into...
-#ifeq ($(CONFIG_SA1100_YOPY),y)
-# ZTEXTADDR = 0x00080000
-# ZBSSADDR = 0xc0200000
-#endif
-ifeq ($(CONFIG_SA1111),y)
- ZRELADDR = 0xc0208000
-endif
-endif
-
-ifeq ($(CONFIG_ARCH_PXA),y)
-ZRELADDR = 0xa0008000
-endif
-
-ifeq ($(CONFIG_ARCH_ANAKIN),y)
-ZRELADDR = 0x20008000
-endif
-
-ifeq ($(CONFIG_ARCH_IQ80310),y)
-ZRELADDR = 0xa0008000
-endif
-
-ifeq ($(CONFIG_ARCH_ADIFCC),y)
-ZRELADDR = 0xc0008000
+ zreladdr-$(CONFIG_SA1111) := 0xc0208000
endif
+ zreladdr-$(CONFIG_ARCH_PXA) := 0xa0008000
+ zreladdr-$(CONFIG_ARCH_ANAKIN) := 0x20008000
+ zreladdr-$(CONFIG_ARCH_IQ80310) := 0xa0008000
+ zreladdr-$(CONFIG_ARCH_ADIFCC) := 0xc0008000
+ZRELADDR := $(zreladdr-y)
+ZTEXTADDR := $(ztextaddr-y)
+PARAMS_PHYS := $(params_phys-y)
+INITRD_PHYS := $(initrd_phys-y)
#
# We now have a PIC decompressor implementation. Decompressors running
# from RAM should not define ZTEXTADDR. Decompressors running directly
# from ROM or Flash must define ZTEXTADDR (preferably via the config)
-#
+# FIXME: Previous assignment to ztextaddr-y is lost here. See SHARK
ifeq ($(CONFIG_ZBOOT_ROM),y)
-ZTEXTADDR =$(CONFIG_ZBOOT_ROM_TEXT)
-ZBSSADDR =$(CONFIG_ZBOOT_ROM_BSS)
+ZTEXTADDR := $(CONFIG_ZBOOT_ROM_TEXT)
+ZBSSADDR := $(CONFIG_ZBOOT_ROM_BSS)
else
-ZTEXTADDR =0
-ZBSSADDR =ALIGN(4)
+ZTEXTADDR := 0
+ZBSSADDR := ALIGN(4)
endif
export ZTEXTADDR ZBSSADDR ZRELADDR INITRD_PHYS PARAMS_PHYS
-include $(TOPDIR)/Rules.make
+EXTRA_TARGETS := Image zImage bootpImage
$(obj)/Image: vmlinux FORCE
$(call if_changed,objcopy)
-
-bzImage: $(obj)/zImage
+ @echo ' Kernel: $@ is ready'
$(obj)/zImage: $(obj)/compressed/vmlinux FORCE
$(call if_changed,objcopy)
+ @echo ' Kernel: $@ is ready'
$(obj)/bootpImage: $(obj)/bootp/bootp FORCE
$(call if_changed,objcopy)
+ @echo ' Kernel: $@ is ready'
$(obj)/compressed/vmlinux: vmlinux FORCE
- +@$(call descend,arch/arm/boot/compressed, $(obj)/compressed/vmlinux)
+ $(Q)$(MAKE) -f scripts/Makefile.build obj=$(obj)/compressed $@
$(obj)/bootp/bootp: $(obj)/zImage initrd FORCE
- +@$(call descend,arch/arm/boot/bootp, $(obj)/bootp/bootp)
+ $(Q)$(MAKE) -f scripts/Makefile.build obj=$(obj)/compressed $@
.PHONY: initrd
initrd:
@@ -157,19 +106,16 @@ zinstall: $(obj)/zImage
$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION) \
$(obj)/zImage System.map "$(INSTALL_PATH)"
-clean:
- $(RM) $(addprefix $(obj)/,Image zImage bootpImage)
- +@$(call descend,arch/arm/boot/bootp, clean)
- +@$(call descend,arch/arm/boot/compressed, clean)
+clean-files := $(addprefix $(obj)/,Image zImage bootpImage)
+subdir- := bootp compressed
archhelp:
- @echo '* bzImage/zImage- Compressed kernel image (arch/$(ARCH)/boot/zImage)'
+ @echo '* zImage - Compressed kernel image (arch/$(ARCH)/boot/zImage)'
@echo ' Image - Uncompressed kernel image (arch/$(ARCH)/boot/Image)'
@echo ' bootpImage - Combined zImage and initial RAM disk'
+ @echo ' initrd - Create an initial image'
@echo ' install - Install uncompressed kernel'
@echo ' zinstall - Install compressed kernel'
@echo ' Install using (your) ~/bin/installkernel or'
@echo ' (distribution) /sbin/installkernel or'
@echo ' install to $$(INSTALL_PATH) and run lilo'
-
-
diff --git a/arch/arm/boot/bootp/Makefile b/arch/arm/boot/bootp/Makefile
index b4304dc33d55..f24cbc2be4ac 100644
--- a/arch/arm/boot/bootp/Makefile
+++ b/arch/arm/boot/bootp/Makefile
@@ -9,8 +9,6 @@ ZLDFLAGS =-p -X -T $(obj)/bootp.lds \
EXTRA_TARGETS := bootp
-include $(TOPDIR)/Rules.make
-
# Note that bootp.lds picks up kernel.o and initrd.o
$(obj)/bootp: $(addprefix $(obj)/,init.o kernel.o initrd.o bootp.lds)
$(LD) $(ZLDFLAGS) -o $@ $(obj)/init.o
@@ -22,5 +20,3 @@ $(obj)/initrd.o: $(INITRD)
$(LD) -r -s -o $@ -b binary $(INITRD)
.PHONY: $(INITRD) $(ZSYSTEM)
-
-clean:; $(RM) $(obj)/bootp
diff --git a/arch/arm/boot/compressed/Makefile b/arch/arm/boot/compressed/Makefile
index 2afc113f2fbe..4b34de447ecf 100644
--- a/arch/arm/boot/compressed/Makefile
+++ b/arch/arm/boot/compressed/Makefile
@@ -63,28 +63,30 @@ ifeq ($(CONFIG_CPU_XSCALE),y)
OBJS += head-xscale.o
endif
-SEDFLAGS = s/TEXT_START/$(ZTEXTADDR)/;s/LOAD_ADDR/$(ZRELADDR)/;\
-s/BSS_START/$(ZBSSADDR)/;s#OBJ#$(obj)#
+SEDFLAGS = s/TEXT_START/$(ZTEXTADDR)/;s/LOAD_ADDR/$(ZRELADDR)/;s/BSS_START/$(ZBSSADDR)/
-EXTRA_TARGETS := vmlinux piggy.o font.o head.o $(OBJS)
+EXTRA_TARGETS := vmlinux vmlinux.lds piggy piggy.gz\
+ piggy.o font.o head.o $(OBJS)
EXTRA_CFLAGS := $(CFLAGS_BOOT) -fpic
EXTRA_AFLAGS := -traditional
-include $(TOPDIR)/Rules.make
-
LDFLAGS_vmlinux := -p -X \
$(shell $(CC) $(CFLAGS) --print-libgcc-file-name) -T
$(obj)/vmlinux: $(obj)/vmlinux.lds $(obj)/$(HEAD) $(obj)/piggy.o \
- $(addprefix $(obj)/, $(OBJS))
+ $(addprefix $(obj)/, $(OBJS)) FORCE
$(call if_changed,ld)
+ @:
+
+$(obj)/piggy: vmlinux FORCE
+ $(call if_changed,objcopy)
-$(obj)/piggy: vmlinux; $(call if_changed,objcopy)
-$(obj)/piggy.gz: $(obj)/piggy; $(call if_changed,gzip)
+$(obj)/piggy.gz: $(obj)/piggy FORCE
+ $(call if_changed,gzip)
LDFLAGS_piggy.o := -r -b binary
-$(obj)/piggy.o: $(obj)/piggy.gz
+$(obj)/piggy.o: $(obj)/piggy.gz FORCE
$(call if_changed,ld)
CFLAGS_font.o := -Dstatic=
@@ -93,9 +95,7 @@ $(obj)/font.o: $(FONTC)
$(obj)/vmlinux.lds: $(obj)/vmlinux.lds.in Makefile arch/arm/boot/Makefile .config
@sed "$(SEDFLAGS)" < $< > $@
-.PHONY: clean
-clean:
- rm -f $(addprefix $(obj)/,vmlinux core piggy* vmlinux.lds)
+clean-files := $(addprefix $(obj)/,vmlinux piggy* vmlinux.lds)
$(obj)/misc.o: $(obj)/misc.c include/asm/arch/uncompress.h lib/inflate.c
diff --git a/arch/arm/kernel/dma-isa.c b/arch/arm/kernel/dma-isa.c
index 2125bb6a1282..d75e8a9923e7 100644
--- a/arch/arm/kernel/dma-isa.c
+++ b/arch/arm/kernel/dma-isa.c
@@ -16,7 +16,6 @@
* arch/arm/kernel/dma-ebsa285.c
* Copyright (C) 1998 Phil Blundell
*/
-#include <linux/sched.h>
#include <linux/ioport.h>
#include <linux/init.h>
#include <linux/pci.h>
diff --git a/arch/arm/kernel/dma.c b/arch/arm/kernel/dma.c
index 6717f735136a..0e4b21e03427 100644
--- a/arch/arm/kernel/dma.c
+++ b/arch/arm/kernel/dma.c
@@ -13,7 +13,6 @@
*/
#include <linux/module.h>
#include <linux/slab.h>
-#include <linux/sched.h>
#include <linux/mman.h>
#include <linux/init.h>
#include <linux/spinlock.h>
diff --git a/arch/arm/kernel/ecard.c b/arch/arm/kernel/ecard.c
index 2b291c31ff8b..1206e7d9fd66 100644
--- a/arch/arm/kernel/ecard.c
+++ b/arch/arm/kernel/ecard.c
@@ -989,42 +989,6 @@ nomem:
return rc;
}
-static ecard_t *finding_pos;
-
-void ecard_startfind(void)
-{
- finding_pos = NULL;
-}
-
-ecard_t *ecard_find(int cid, const card_ids *cids)
-{
- if (!finding_pos)
- finding_pos = cards;
- else
- finding_pos = finding_pos->next;
-
- for (; finding_pos; finding_pos = finding_pos->next) {
- if (finding_pos->claimed)
- continue;
-
- if (finding_pos->dev.driver)
- continue;
-
- if (!cids) {
- if ((finding_pos->cid.id ^ cid) == 0)
- break;
- } else {
- const struct ecard_id *id;
-
- id = ecard_match_device(cids, finding_pos);
- if (id)
- break;
- }
- }
-
- return finding_pos;
-}
-
/*
* Initialise the expansion card system.
* Locate all hardware - interrupt management and
@@ -1087,10 +1051,15 @@ static int ecard_drv_probe(struct device *dev)
struct expansion_card *ec = ECARD_DEV(dev);
struct ecard_driver *drv = ECARD_DRV(dev->driver);
const struct ecard_id *id;
+ int ret;
id = ecard_match_device(drv->id_table, ec);
- return drv->probe(ec, id);
+ ecard_claim(ec);
+ ret = drv->probe(ec, id);
+ if (ret)
+ ecard_release(ec);
+ return ret;
}
static int ecard_drv_remove(struct device *dev)
@@ -1099,6 +1068,7 @@ static int ecard_drv_remove(struct device *dev)
struct ecard_driver *drv = ECARD_DRV(dev->driver);
drv->remove(ec);
+ ecard_release(ec);
return 0;
}
@@ -1144,12 +1114,8 @@ static int ecard_bus_init(void)
postcore_initcall(ecard_bus_init);
-EXPORT_SYMBOL(ecard_startfind);
-EXPORT_SYMBOL(ecard_find);
EXPORT_SYMBOL(ecard_readchunk);
EXPORT_SYMBOL(ecard_address);
-
EXPORT_SYMBOL(ecard_register_driver);
EXPORT_SYMBOL(ecard_remove_driver);
-
EXPORT_SYMBOL(ecard_bus_type);
diff --git a/arch/arm/kernel/irq.c b/arch/arm/kernel/irq.c
index 1fa4f5fb25f7..a7cd6b892ffa 100644
--- a/arch/arm/kernel/irq.c
+++ b/arch/arm/kernel/irq.c
@@ -20,7 +20,6 @@
#include <linux/config.h>
#include <linux/kernel_stat.h>
#include <linux/signal.h>
-#include <linux/sched.h>
#include <linux/ioport.h>
#include <linux/interrupt.h>
#include <linux/ptrace.h>
@@ -661,7 +660,7 @@ unsigned int probe_irq_mask(unsigned long irqs)
unsigned int mask = 0, i;
spin_lock_irq(&irq_controller_lock);
- for(i = 0; i < 16 && i < NR_IRQS; i++)
+ for (i = 0; i < 16 && i < NR_IRQS; i++)
if (irq_desc[i].probing && irq_desc[i].triggered)
mask |= 1 << i;
spin_unlock_irq(&irq_controller_lock);
diff --git a/arch/arm/kernel/plx90x0.c b/arch/arm/kernel/plx90x0.c
index f843e12267ed..60d7d3566af4 100644
--- a/arch/arm/kernel/plx90x0.c
+++ b/arch/arm/kernel/plx90x0.c
@@ -14,7 +14,6 @@
#include <linux/kernel.h>
#include <linux/pci.h>
#include <linux/init.h>
-#include <linux/sched.h>
#include <asm/hardware.h>
#include <asm/io.h>
diff --git a/arch/arm/kernel/time-acorn.c b/arch/arm/kernel/time-acorn.c
index eb637801c7a5..8772035bfc7f 100644
--- a/arch/arm/kernel/time-acorn.c
+++ b/arch/arm/kernel/time-acorn.c
@@ -12,7 +12,6 @@
* 10-Oct-1996 RMK Brought up to date with arch-sa110eval
* 04-Dec-1997 RMK Updated for new arch/arm/time.c
*/
-#include <linux/sched.h>
#include <linux/interrupt.h>
#include <linux/init.h>
diff --git a/arch/arm/kernel/time.c b/arch/arm/kernel/time.c
index 655b7ed1c8e0..2af6dbda06d5 100644
--- a/arch/arm/kernel/time.c
+++ b/arch/arm/kernel/time.c
@@ -18,7 +18,6 @@
*/
#include <linux/config.h>
#include <linux/module.h>
-#include <linux/sched.h>
#include <linux/kernel.h>
#include <linux/interrupt.h>
#include <linux/time.h>
diff --git a/arch/arm/kernel/via82c505.c b/arch/arm/kernel/via82c505.c
index 345b9b6c73da..a4ac16dbb756 100644
--- a/arch/arm/kernel/via82c505.c
+++ b/arch/arm/kernel/via82c505.c
@@ -1,5 +1,4 @@
#include <linux/config.h>
-#include <linux/sched.h>
#include <linux/kernel.h>
#include <linux/pci.h>
#include <linux/ptrace.h>
diff --git a/arch/arm/mach-adifcc/arch.c b/arch/arm/mach-adifcc/arch.c
index 9c715a9635fd..bfc59556d9da 100644
--- a/arch/arm/mach-adifcc/arch.c
+++ b/arch/arm/mach-adifcc/arch.c
@@ -11,7 +11,7 @@
#include <linux/init.h>
#include <linux/major.h>
#include <linux/fs.h>
-#include <asm/types.h>
+
#include <asm/setup.h>
#include <asm/memory.h>
#include <asm/hardware.h>
diff --git a/arch/arm/mach-adifcc/irq.c b/arch/arm/mach-adifcc/irq.c
index e8e659a54ef4..29cd529832b8 100644
--- a/arch/arm/mach-adifcc/irq.c
+++ b/arch/arm/mach-adifcc/irq.c
@@ -13,7 +13,6 @@
* support for PCI though.
*/
#include <linux/init.h>
-#include <linux/sched.h>
#include <linux/interrupt.h>
#include <asm/mach/irq.h>
diff --git a/arch/arm/mach-anakin/irq.c b/arch/arm/mach-anakin/irq.c
index 46cd97f56ff1..fcf335fadc58 100644
--- a/arch/arm/mach-anakin/irq.c
+++ b/arch/arm/mach-anakin/irq.c
@@ -12,7 +12,6 @@
*/
#include <linux/ptrace.h>
-#include <linux/sched.h>
#include <linux/interrupt.h>
#include <linux/init.h>
diff --git a/arch/arm/mach-arc/dma.c b/arch/arm/mach-arc/dma.c
index a49785206265..43c5a8d35210 100644
--- a/arch/arm/mach-arc/dma.c
+++ b/arch/arm/mach-arc/dma.c
@@ -10,7 +10,6 @@
* DMA functions specific to Archimedes and A5000 architecture
*/
#include <linux/config.h>
-#include <linux/sched.h>
#include <linux/init.h>
#include <asm/dma.h>
diff --git a/arch/arm/mach-arc/oldlatches.c b/arch/arm/mach-arc/oldlatches.c
index c7237c40db92..5f797e6eee14 100644
--- a/arch/arm/mach-arc/oldlatches.c
+++ b/arch/arm/mach-arc/oldlatches.c
@@ -13,7 +13,6 @@
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
-#include <linux/sched.h>
#include <asm/io.h>
#include <asm/hardware.h>
diff --git a/arch/arm/mach-clps711x/autcpu12.c b/arch/arm/mach-clps711x/autcpu12.c
index c4c28fb1a1ae..1cb34fa33d23 100644
--- a/arch/arm/mach-clps711x/autcpu12.c
+++ b/arch/arm/mach-clps711x/autcpu12.c
@@ -22,7 +22,6 @@
#include <linux/types.h>
#include <linux/string.h>
#include <linux/blk.h>
-#include <linux/sched.h>
#include <linux/mm.h>
#include <asm/hardware.h>
diff --git a/arch/arm/mach-clps711x/cdb89712.c b/arch/arm/mach-clps711x/cdb89712.c
index 56083b9a5b08..d51668d267fa 100644
--- a/arch/arm/mach-clps711x/cdb89712.c
+++ b/arch/arm/mach-clps711x/cdb89712.c
@@ -21,7 +21,6 @@
#include <linux/init.h>
#include <linux/types.h>
#include <linux/string.h>
-#include <linux/sched.h>
#include <linux/mm.h>
#include <asm/hardware.h>
diff --git a/arch/arm/mach-clps711x/dma.c b/arch/arm/mach-clps711x/dma.c
index 90857e1d452b..af5a4de38eac 100644
--- a/arch/arm/mach-clps711x/dma.c
+++ b/arch/arm/mach-clps711x/dma.c
@@ -17,17 +17,9 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#include <linux/sched.h>
-#include <linux/slab.h>
-#include <linux/mman.h>
#include <linux/init.h>
-#include <asm/page.h>
-#include <asm/pgtable.h>
#include <asm/dma.h>
-#include <asm/io.h>
-#include <asm/hardware.h>
-
#include <asm/mach/dma.h>
void __init arch_dma_init(dma_t *dma)
diff --git a/arch/arm/mach-clps711x/fortunet.c b/arch/arm/mach-clps711x/fortunet.c
index 8037ea85e489..31ea65434883 100644
--- a/arch/arm/mach-clps711x/fortunet.c
+++ b/arch/arm/mach-clps711x/fortunet.c
@@ -21,8 +21,6 @@
*/
#include <linux/config.h>
#include <linux/types.h>
-#include <linux/sched.h>
-#include <linux/interrupt.h>
#include <linux/init.h>
#include <linux/blk.h>
@@ -32,7 +30,6 @@
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
-#include <asm/mach/amba_kmi.h>
extern void clps711x_map_io(void);
extern void clps711x_init_irq(void);
diff --git a/arch/arm/mach-clps711x/mm.c b/arch/arm/mach-clps711x/mm.c
index a61e9b05dfb8..8c7d11e0be78 100644
--- a/arch/arm/mach-clps711x/mm.c
+++ b/arch/arm/mach-clps711x/mm.c
@@ -20,7 +20,6 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <linux/kernel.h>
-#include <linux/sched.h>
#include <linux/mm.h>
#include <linux/init.h>
#include <linux/config.h>
diff --git a/arch/arm/mach-clps711x/p720t.c b/arch/arm/mach-clps711x/p720t.c
index 4de13d3d0f5d..b99cccfb773b 100644
--- a/arch/arm/mach-clps711x/p720t.c
+++ b/arch/arm/mach-clps711x/p720t.c
@@ -22,7 +22,6 @@
#include <linux/init.h>
#include <linux/types.h>
#include <linux/string.h>
-#include <linux/sched.h>
#include <linux/mm.h>
#include <asm/hardware.h>
diff --git a/arch/arm/mach-clps711x/time.c b/arch/arm/mach-clps711x/time.c
index 30613131141c..caedd7b5bf23 100644
--- a/arch/arm/mach-clps711x/time.c
+++ b/arch/arm/mach-clps711x/time.c
@@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#include <linux/sched.h>
+#include <linux/timex.h>
#include <linux/init.h>
#include <asm/hardware.h>
diff --git a/arch/arm/mach-ebsa110/time.c b/arch/arm/mach-ebsa110/time.c
index c842f06b0e2a..989ab98a8d97 100644
--- a/arch/arm/mach-ebsa110/time.c
+++ b/arch/arm/mach-ebsa110/time.c
@@ -7,7 +7,6 @@
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
-#include <linux/sched.h>
#include <linux/init.h>
#include <asm/io.h>
diff --git a/arch/arm/mach-epxa10db/arch.c b/arch/arm/mach-epxa10db/arch.c
index f30d0176784e..71c2257dfd50 100644
--- a/arch/arm/mach-epxa10db/arch.c
+++ b/arch/arm/mach-epxa10db/arch.c
@@ -19,12 +19,9 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <linux/types.h>
-#include <linux/sched.h>
-#include <linux/interrupt.h>
#include <linux/init.h>
#include <asm/hardware.h>
-#include <asm/irq.h>
#include <asm/setup.h>
#include <asm/mach-types.h>
diff --git a/arch/arm/mach-epxa10db/dma.c b/arch/arm/mach-epxa10db/dma.c
index 2edf62a11fe0..0151e9f1c066 100644
--- a/arch/arm/mach-epxa10db/dma.c
+++ b/arch/arm/mach-epxa10db/dma.c
@@ -18,17 +18,9 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#include <linux/sched.h>
-#include <linux/slab.h>
-#include <linux/mman.h>
#include <linux/init.h>
-#include <asm/page.h>
-#include <asm/pgtable.h>
#include <asm/dma.h>
-#include <asm/io.h>
-#include <asm/hardware.h>
-
#include <asm/mach/dma.h>
void __init arch_dma_init(dma_t *dma)
diff --git a/arch/arm/mach-epxa10db/time.c b/arch/arm/mach-epxa10db/time.c
index d4ca520e382f..0c8b9cf7c7b7 100644
--- a/arch/arm/mach-epxa10db/time.c
+++ b/arch/arm/mach-epxa10db/time.c
@@ -9,13 +9,11 @@
* published by the Free Software Foundation.
*/
#include <linux/kernel.h>
-#include <linux/sched.h>
#include <linux/init.h>
#include <asm/hardware.h>
-
extern int (*set_rtc)(void);
static int epxa10db_set_rtc(void)
diff --git a/arch/arm/mach-footbridge/cats-hw.c b/arch/arm/mach-footbridge/cats-hw.c
index 160b0307fa92..0aec69fb00ad 100644
--- a/arch/arm/mach-footbridge/cats-hw.c
+++ b/arch/arm/mach-footbridge/cats-hw.c
@@ -5,7 +5,6 @@
*
* Copyright (C) 1998, 1999 Russell King, Phil Blundell
*/
-#include <linux/sched.h>
#include <linux/ioport.h>
#include <linux/kernel.h>
#include <linux/init.h>
diff --git a/arch/arm/mach-footbridge/dc21285.c b/arch/arm/mach-footbridge/dc21285.c
index cbe4ba754bdb..fb0ac649543f 100644
--- a/arch/arm/mach-footbridge/dc21285.c
+++ b/arch/arm/mach-footbridge/dc21285.c
@@ -8,7 +8,6 @@
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
-#include <linux/sched.h>
#include <linux/kernel.h>
#include <linux/pci.h>
#include <linux/ptrace.h>
diff --git a/arch/arm/mach-footbridge/dma.c b/arch/arm/mach-footbridge/dma.c
index 7cdbf92f1c83..a6b1396b0951 100644
--- a/arch/arm/mach-footbridge/dma.c
+++ b/arch/arm/mach-footbridge/dma.c
@@ -11,7 +11,6 @@
* ISA DMA controllers.
*/
#include <linux/config.h>
-#include <linux/sched.h>
#include <linux/init.h>
#include <asm/dma.h>
diff --git a/arch/arm/mach-footbridge/irq.c b/arch/arm/mach-footbridge/irq.c
index df59f879d8fc..d4d2662ab040 100644
--- a/arch/arm/mach-footbridge/irq.c
+++ b/arch/arm/mach-footbridge/irq.c
@@ -14,9 +14,7 @@
* 26-Jan-1999 PJB Don't use IACK on CATS
* 16-Mar-1999 RMK Added autodetect of ISA PICs
*/
-#include <linux/sched.h>
#include <linux/ioport.h>
-#include <linux/interrupt.h>
#include <linux/init.h>
#include <asm/mach/irq.h>
diff --git a/arch/arm/mach-footbridge/isa-irq.c b/arch/arm/mach-footbridge/isa-irq.c
index 7808e0b2a9a7..1f021054d732 100644
--- a/arch/arm/mach-footbridge/isa-irq.c
+++ b/arch/arm/mach-footbridge/isa-irq.c
@@ -14,7 +14,6 @@
* 26-Jan-1999 PJB Don't use IACK on CATS
* 16-Mar-1999 RMK Added autodetect of ISA PICs
*/
-#include <linux/sched.h>
#include <linux/ioport.h>
#include <linux/interrupt.h>
#include <linux/init.h>
diff --git a/arch/arm/mach-footbridge/mm.c b/arch/arm/mach-footbridge/mm.c
index e9054bf77c2a..400932cfdead 100644
--- a/arch/arm/mach-footbridge/mm.c
+++ b/arch/arm/mach-footbridge/mm.c
@@ -11,7 +11,6 @@
*/
#include <linux/config.h>
#include <linux/kernel.h>
-#include <linux/sched.h>
#include <linux/mm.h>
#include <linux/init.h>
diff --git a/arch/arm/mach-footbridge/netwinder-hw.c b/arch/arm/mach-footbridge/netwinder-hw.c
index 587fb687476d..c81775b1a42d 100644
--- a/arch/arm/mach-footbridge/netwinder-hw.c
+++ b/arch/arm/mach-footbridge/netwinder-hw.c
@@ -7,7 +7,6 @@
*/
#include <linux/config.h>
#include <linux/module.h>
-#include <linux/sched.h>
#include <linux/ioport.h>
#include <linux/kernel.h>
#include <linux/delay.h>
diff --git a/arch/arm/mach-ftvpci/core.c b/arch/arm/mach-ftvpci/core.c
index 5fec4ef21b68..ea6d5c34e87f 100644
--- a/arch/arm/mach-ftvpci/core.c
+++ b/arch/arm/mach-ftvpci/core.c
@@ -9,7 +9,6 @@
* 2 of the License, or (at your option) any later version.
*/
#include <linux/kernel.h>
-#include <linux/sched.h>
#include <linux/mm.h>
#include <linux/init.h>
diff --git a/arch/arm/mach-integrator/arch.c b/arch/arm/mach-integrator/arch.c
index be2ac9afcc96..0a1fd15cf64a 100644
--- a/arch/arm/mach-integrator/arch.c
+++ b/arch/arm/mach-integrator/arch.c
@@ -19,8 +19,6 @@
*/
#include <linux/config.h>
#include <linux/types.h>
-#include <linux/sched.h>
-#include <linux/interrupt.h>
#include <linux/init.h>
#include <asm/hardware.h>
diff --git a/arch/arm/mach-integrator/dma.c b/arch/arm/mach-integrator/dma.c
index a53feed419d2..aae6f23cd72b 100644
--- a/arch/arm/mach-integrator/dma.c
+++ b/arch/arm/mach-integrator/dma.c
@@ -18,7 +18,6 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#include <linux/sched.h>
#include <linux/slab.h>
#include <linux/mman.h>
#include <linux/init.h>
diff --git a/arch/arm/mach-integrator/pci.c b/arch/arm/mach-integrator/pci.c
index 0c23671a70e7..58683093b818 100644
--- a/arch/arm/mach-integrator/pci.c
+++ b/arch/arm/mach-integrator/pci.c
@@ -21,7 +21,6 @@
*
* PCI functions for Integrator
*/
-#include <linux/sched.h>
#include <linux/kernel.h>
#include <linux/pci.h>
#include <linux/ptrace.h>
diff --git a/arch/arm/mach-integrator/pci_v3.c b/arch/arm/mach-integrator/pci_v3.c
index 7c87676a73d8..2abfa3b524d5 100644
--- a/arch/arm/mach-integrator/pci_v3.c
+++ b/arch/arm/mach-integrator/pci_v3.c
@@ -21,7 +21,6 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <linux/config.h>
-#include <linux/sched.h>
#include <linux/kernel.h>
#include <linux/pci.h>
#include <linux/ptrace.h>
diff --git a/arch/arm/mach-integrator/time.c b/arch/arm/mach-integrator/time.c
index fc32a809d9f3..39606096fbd6 100644
--- a/arch/arm/mach-integrator/time.c
+++ b/arch/arm/mach-integrator/time.c
@@ -8,7 +8,7 @@
* published by the Free Software Foundation.
*/
#include <linux/kernel.h>
-#include <linux/sched.h>
+#include <linux/time.h>
#include <linux/init.h>
#include <asm/hardware.h>
diff --git a/arch/arm/mach-iop310/arch.c b/arch/arm/mach-iop310/arch.c
index 9ff7a4c2963c..401ef090e50d 100644
--- a/arch/arm/mach-iop310/arch.c
+++ b/arch/arm/mach-iop310/arch.c
@@ -13,7 +13,7 @@
#include <linux/init.h>
#include <linux/major.h>
#include <linux/fs.h>
-#include <asm/types.h>
+
#include <asm/setup.h>
#include <asm/system.h>
#include <asm/memory.h>
diff --git a/arch/arm/mach-iop310/iop310-irq.c b/arch/arm/mach-iop310/iop310-irq.c
index 653482d1191a..67639c9142cc 100644
--- a/arch/arm/mach-iop310/iop310-irq.c
+++ b/arch/arm/mach-iop310/iop310-irq.c
@@ -14,7 +14,6 @@
*
*/
#include <linux/init.h>
-#include <linux/sched.h>
#include <linux/interrupt.h>
#include <asm/mach/irq.h>
diff --git a/arch/arm/mach-iop310/iop310-pci.c b/arch/arm/mach-iop310/iop310-pci.c
index 50faa6fecfcd..d5585f12430c 100644
--- a/arch/arm/mach-iop310/iop310-pci.c
+++ b/arch/arm/mach-iop310/iop310-pci.c
@@ -11,10 +11,8 @@
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
-#include <linux/sched.h>
#include <linux/kernel.h>
#include <linux/pci.h>
-#include <linux/interrupt.h>
#include <linux/slab.h>
#include <linux/mm.h>
#include <linux/init.h>
diff --git a/arch/arm/mach-iop310/iq80310-irq.c b/arch/arm/mach-iop310/iq80310-irq.c
index e9ff595590e7..7fdd36e1c1f4 100644
--- a/arch/arm/mach-iop310/iq80310-irq.c
+++ b/arch/arm/mach-iop310/iq80310-irq.c
@@ -14,10 +14,6 @@
* Moved demux from asm to C - DS
* Fixes for various revision boards - DS
*/
-#include <linux/kernel_stat.h>
-#include <linux/sched.h>
-#include <linux/interrupt.h>
-#include <linux/smp.h>
#include <linux/init.h>
#include <asm/irq.h>
diff --git a/arch/arm/mach-iop310/iq80310-time.c b/arch/arm/mach-iop310/iq80310-time.c
index 1151c6b3db28..42311bca889d 100644
--- a/arch/arm/mach-iop310/iq80310-time.c
+++ b/arch/arm/mach-iop310/iq80310-time.c
@@ -11,14 +11,11 @@
* published by the Free Software Foundation.
*
*/
-#include <linux/module.h>
-#include <linux/sched.h>
#include <linux/kernel.h>
#include <linux/interrupt.h>
#include <linux/time.h>
#include <linux/init.h>
#include <linux/timex.h>
-#include <linux/smp.h>
#include <asm/hardware.h>
#include <asm/io.h>
diff --git a/arch/arm/mach-iop310/xs80200-irq.c b/arch/arm/mach-iop310/xs80200-irq.c
index 2d3af7c6b02e..d5d5784df8f8 100644
--- a/arch/arm/mach-iop310/xs80200-irq.c
+++ b/arch/arm/mach-iop310/xs80200-irq.c
@@ -11,8 +11,6 @@
* published by the Free Software Foundation.
*/
#include <linux/init.h>
-#include <linux/sched.h>
-#include <linux/interrupt.h>
#include <asm/mach/irq.h>
#include <asm/irq.h>
diff --git a/arch/arm/mach-pxa/dma.c b/arch/arm/mach-pxa/dma.c
index e2c141ca9619..69ee386d94e6 100644
--- a/arch/arm/mach-pxa/dma.c
+++ b/arch/arm/mach-pxa/dma.c
@@ -15,7 +15,6 @@
#include <linux/module.h>
#include <linux/init.h>
#include <linux/kernel.h>
-#include <linux/sched.h>
#include <linux/errno.h>
#include <asm/system.h>
diff --git a/arch/arm/mach-pxa/idp.c b/arch/arm/mach-pxa/idp.c
index e07988986b17..71b64a6d9fcc 100644
--- a/arch/arm/mach-pxa/idp.c
+++ b/arch/arm/mach-pxa/idp.c
@@ -17,9 +17,7 @@
#include <linux/major.h>
#include <linux/fs.h>
#include <linux/interrupt.h>
-#include <linux/sched.h>
-#include <asm/types.h>
#include <asm/setup.h>
#include <asm/memory.h>
#include <asm/mach-types.h>
diff --git a/arch/arm/mach-pxa/irq.c b/arch/arm/mach-pxa/irq.c
index 67fdf38f8e69..81c6e8a72496 100644
--- a/arch/arm/mach-pxa/irq.c
+++ b/arch/arm/mach-pxa/irq.c
@@ -14,7 +14,6 @@
#include <linux/init.h>
#include <linux/module.h>
-#include <linux/sched.h>
#include <linux/interrupt.h>
#include <linux/ptrace.h>
diff --git a/arch/arm/mach-pxa/lubbock.c b/arch/arm/mach-pxa/lubbock.c
index c58183dc334d..336f55987d09 100644
--- a/arch/arm/mach-pxa/lubbock.c
+++ b/arch/arm/mach-pxa/lubbock.c
@@ -16,9 +16,7 @@
#include <linux/major.h>
#include <linux/fs.h>
#include <linux/interrupt.h>
-#include <linux/sched.h>
-#include <asm/types.h>
#include <asm/setup.h>
#include <asm/memory.h>
#include <asm/mach-types.h>
diff --git a/arch/arm/mach-pxa/pm.c b/arch/arm/mach-pxa/pm.c
index a52714acfd8b..8e738ed14e12 100644
--- a/arch/arm/mach-pxa/pm.c
+++ b/arch/arm/mach-pxa/pm.c
@@ -15,7 +15,6 @@
#include <linux/init.h>
#include <linux/pm.h>
#include <linux/slab.h>
-#include <linux/sched.h>
#include <linux/interrupt.h>
#include <linux/sysctl.h>
#include <linux/errno.h>
diff --git a/arch/arm/mach-rpc/dma.c b/arch/arm/mach-rpc/dma.c
index e81acb720463..dab328a0d6ab 100644
--- a/arch/arm/mach-rpc/dma.c
+++ b/arch/arm/mach-rpc/dma.c
@@ -9,7 +9,6 @@
*
* DMA functions specific to RiscPC architecture
*/
-#include <linux/sched.h>
#include <linux/slab.h>
#include <linux/mman.h>
#include <linux/init.h>
diff --git a/arch/arm/mach-sa1100/adsbitsy.c b/arch/arm/mach-sa1100/adsbitsy.c
index d5eb9b677449..d677abeea697 100644
--- a/arch/arm/mach-sa1100/adsbitsy.c
+++ b/arch/arm/mach-sa1100/adsbitsy.c
@@ -11,8 +11,6 @@
*/
#include <linux/kernel.h>
#include <linux/init.h>
-#include <linux/sched.h>
-#include <linux/interrupt.h>
#include <linux/ptrace.h>
#include <linux/ioport.h>
#include <linux/serial_core.h>
diff --git a/arch/arm/mach-sa1100/assabet.c b/arch/arm/mach-sa1100/assabet.c
index d538b98d4284..6d775017ab7b 100644
--- a/arch/arm/mach-sa1100/assabet.c
+++ b/arch/arm/mach-sa1100/assabet.c
@@ -13,7 +13,6 @@
#include <linux/config.h>
#include <linux/init.h>
#include <linux/kernel.h>
-#include <linux/sched.h>
#include <linux/tty.h>
#include <linux/module.h>
#include <linux/errno.h>
diff --git a/arch/arm/mach-sa1100/dma.c b/arch/arm/mach-sa1100/dma.c
index 11e0121b1b84..8366f546a0d8 100644
--- a/arch/arm/mach-sa1100/dma.c
+++ b/arch/arm/mach-sa1100/dma.c
@@ -11,8 +11,8 @@
*/
#include <linux/module.h>
+#include <linux/interrupt.h>
#include <linux/init.h>
-#include <linux/sched.h>
#include <linux/spinlock.h>
#include <linux/errno.h>
diff --git a/arch/arm/mach-sa1100/flexanet.c b/arch/arm/mach-sa1100/flexanet.c
index 3135f09aa12e..0a40c7831515 100644
--- a/arch/arm/mach-sa1100/flexanet.c
+++ b/arch/arm/mach-sa1100/flexanet.c
@@ -11,7 +11,6 @@
*/
#include <linux/init.h>
#include <linux/kernel.h>
-#include <linux/sched.h>
#include <linux/tty.h>
#include <linux/module.h>
#include <linux/errno.h>
diff --git a/arch/arm/mach-sa1100/graphicsclient.c b/arch/arm/mach-sa1100/graphicsclient.c
index 9c69428bb048..eb420d53a93d 100644
--- a/arch/arm/mach-sa1100/graphicsclient.c
+++ b/arch/arm/mach-sa1100/graphicsclient.c
@@ -11,8 +11,6 @@
*/
#include <linux/kernel.h>
#include <linux/init.h>
-#include <linux/sched.h>
-#include <linux/interrupt.h>
#include <linux/ptrace.h>
#include <asm/hardware.h>
diff --git a/arch/arm/mach-sa1100/graphicsmaster.c b/arch/arm/mach-sa1100/graphicsmaster.c
index d3eddf63205e..db88613a49ce 100644
--- a/arch/arm/mach-sa1100/graphicsmaster.c
+++ b/arch/arm/mach-sa1100/graphicsmaster.c
@@ -9,8 +9,6 @@
*/
#include <linux/kernel.h>
#include <linux/init.h>
-#include <linux/sched.h>
-#include <linux/interrupt.h>
#include <linux/ptrace.h>
#include <linux/ioport.h>
diff --git a/arch/arm/mach-sa1100/h3600.c b/arch/arm/mach-sa1100/h3600.c
index 41e19e37d0c0..dd875ba0b559 100644
--- a/arch/arm/mach-sa1100/h3600.c
+++ b/arch/arm/mach-sa1100/h3600.c
@@ -23,7 +23,6 @@
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/tty.h>
-#include <linux/sched.h>
#include <linux/pm.h>
#include <linux/serial_core.h>
diff --git a/arch/arm/mach-sa1100/irq.c b/arch/arm/mach-sa1100/irq.c
index c0440f8c8c37..46f3baf9cabf 100644
--- a/arch/arm/mach-sa1100/irq.c
+++ b/arch/arm/mach-sa1100/irq.c
@@ -11,8 +11,6 @@
*/
#include <linux/init.h>
#include <linux/module.h>
-#include <linux/sched.h>
-#include <linux/interrupt.h>
#include <linux/ioport.h>
#include <linux/ptrace.h>
diff --git a/arch/arm/mach-sa1100/neponset.c b/arch/arm/mach-sa1100/neponset.c
index 71c60c3c1467..23a681189b96 100644
--- a/arch/arm/mach-sa1100/neponset.c
+++ b/arch/arm/mach-sa1100/neponset.c
@@ -4,8 +4,6 @@
*/
#include <linux/kernel.h>
#include <linux/init.h>
-#include <linux/sched.h>
-#include <linux/interrupt.h>
#include <linux/ptrace.h>
#include <linux/tty.h>
#include <linux/ioport.h>
diff --git a/arch/arm/mach-sa1100/pm.c b/arch/arm/mach-sa1100/pm.c
index 76e0da5b973e..2e99c722be48 100644
--- a/arch/arm/mach-sa1100/pm.c
+++ b/arch/arm/mach-sa1100/pm.c
@@ -26,8 +26,6 @@
#include <linux/module.h>
#include <linux/init.h>
#include <linux/pm.h>
-#include <linux/sched.h>
-#include <linux/interrupt.h>
#include <linux/sysctl.h>
#include <linux/errno.h>
#include <linux/device.h>
diff --git a/arch/arm/mach-sa1100/sa1111.c b/arch/arm/mach-sa1100/sa1111.c
index 54a40462b2dc..3d2d93c6ea84 100644
--- a/arch/arm/mach-sa1100/sa1111.c
+++ b/arch/arm/mach-sa1100/sa1111.c
@@ -18,8 +18,6 @@
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/delay.h>
-#include <linux/sched.h>
-#include <linux/interrupt.h>
#include <linux/ptrace.h>
#include <linux/errno.h>
#include <linux/ioport.h>
diff --git a/arch/arm/mach-sa1100/stork.c b/arch/arm/mach-sa1100/stork.c
index 703a513a94d0..0c34c9d61bb8 100644
--- a/arch/arm/mach-sa1100/stork.c
+++ b/arch/arm/mach-sa1100/stork.c
@@ -14,7 +14,6 @@
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/tty.h>
-#include <linux/sched.h>
#include <linux/delay.h>
#include <asm/hardware.h>
diff --git a/arch/arm/mach-sa1100/system3.c b/arch/arm/mach-sa1100/system3.c
index d0dc614b0b87..6e47c1cda8eb 100644
--- a/arch/arm/mach-sa1100/system3.c
+++ b/arch/arm/mach-sa1100/system3.c
@@ -37,7 +37,6 @@
#include <linux/config.h>
#include <linux/init.h>
#include <linux/kernel.h>
-#include <linux/sched.h>
#include <linux/tty.h>
#include <linux/module.h>
#include <linux/errno.h>
diff --git a/arch/arm/mach-shark/dma.c b/arch/arm/mach-shark/dma.c
index 1a73aa9187ca..835989a02918 100644
--- a/arch/arm/mach-shark/dma.c
+++ b/arch/arm/mach-shark/dma.c
@@ -9,12 +9,9 @@
*/
#include <linux/config.h>
-#include <linux/sched.h>
#include <linux/init.h>
#include <asm/dma.h>
-#include <asm/io.h>
-
#include <asm/mach/dma.h>
void __init arch_dma_init(dma_t *dma)
diff --git a/arch/arm/mach-tbox/core.c b/arch/arm/mach-tbox/core.c
index 64555b92d34c..e9099444b2c2 100644
--- a/arch/arm/mach-tbox/core.c
+++ b/arch/arm/mach-tbox/core.c
@@ -7,7 +7,6 @@
* Extra MM routines for the Tbox architecture
*/
#include <linux/kernel.h>
-#include <linux/sched.h>
#include <linux/mm.h>
#include <linux/init.h>
diff --git a/arch/arm/mm/Makefile b/arch/arm/mm/Makefile
index 88ca1a91ef0a..8d4045d105ee 100644
--- a/arch/arm/mm/Makefile
+++ b/arch/arm/mm/Makefile
@@ -22,24 +22,21 @@ obj-$(CONFIG_DISCONTIGMEM) += discontig.o
p-$(CONFIG_CPU_26) += proc-arm2_3.o
# ARMv3
-p-$(CONFIG_CPU_ARM610) += proc-arm6_7.o tlb-v3.o copypage-v3.o
-p-$(CONFIG_CPU_ARM710) += proc-arm6_7.o tlb-v3.o copypage-v3.o
+p-$(CONFIG_CPU_ARM610) += proc-arm6_7.o tlb-v3.o copypage-v3.o
+p-$(CONFIG_CPU_ARM710) += proc-arm6_7.o tlb-v3.o copypage-v3.o
# ARMv4
-p-$(CONFIG_CPU_ARM720T) += proc-arm720.o tlb-v4.o copypage-v4wt.o abort-lv4t.o
-p-$(CONFIG_CPU_ARM920T) += proc-arm920.o tlb-v4wb.o copypage-v4wb.o abort-ev4t.o
-p-$(CONFIG_CPU_ARM922T) += proc-arm922.o tlb-v4wb.o copypage-v4wb.o abort-ev4t.o
-p-$(CONFIG_CPU_ARM1020) += proc-arm1020.o tlb-v4wb.o copypage-v4wb.o abort-ev4t.o
-p-$(CONFIG_CPU_SA110) += proc-sa110.o tlb-v4wb.o copypage-v4wb.o abort-ev4.o minicache.o
-p-$(CONFIG_CPU_SA1100) += proc-sa110.o tlb-v4wb.o copypage-v4mc.o abort-ev4.o minicache.o
+p-$(CONFIG_CPU_ARM720T) += proc-arm720.o tlb-v4.o copypage-v4wt.o abort-lv4t.o
+p-$(CONFIG_CPU_ARM920T) += proc-arm920.o tlb-v4wbi.o copypage-v4wb.o abort-ev4t.o
+p-$(CONFIG_CPU_ARM922T) += proc-arm922.o tlb-v4wbi.o copypage-v4wb.o abort-ev4t.o
+p-$(CONFIG_CPU_ARM1020) += proc-arm1020.o tlb-v4wbi.o copypage-v4wb.o abort-ev4t.o
+p-$(CONFIG_CPU_SA110) += proc-sa110.o tlb-v4wb.o copypage-v4wb.o abort-ev4.o minicache.o
+p-$(CONFIG_CPU_SA1100) += proc-sa110.o tlb-v4wb.o copypage-v4mc.o abort-ev4.o minicache.o
# ARMv5
-p-$(CONFIG_CPU_ARM926T) += proc-arm926.o tlb-v4wb.o copypage-v4wb.o abort-ev5tej.o
-p-$(CONFIG_CPU_XSCALE) += proc-xscale.o tlb-v4wb.o copypage-xscale.o abort-xscale.o minicache.o
+p-$(CONFIG_CPU_ARM926T) += proc-arm926.o tlb-v4wbi.o copypage-v4wb.o abort-ev5tej.o
+p-$(CONFIG_CPU_XSCALE) += proc-xscale.o tlb-v4wbi.o copypage-xscale.o abort-xscale.o minicache.o
obj-y += $(sort $(p-y))
include $(TOPDIR)/Rules.make
-
-# Special dependencies
-$(obj)/$(p-y): include/asm-arm/constants.h
diff --git a/arch/arm/mm/alignment.c b/arch/arm/mm/alignment.c
index db227d31264c..5c9ff8269e44 100644
--- a/arch/arm/mm/alignment.c
+++ b/arch/arm/mm/alignment.c
@@ -11,7 +11,6 @@
#include <linux/config.h>
#include <linux/compiler.h>
#include <linux/signal.h>
-#include <linux/sched.h>
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/string.h>
@@ -19,7 +18,6 @@
#include <linux/ptrace.h>
#include <linux/mman.h>
#include <linux/mm.h>
-#include <linux/interrupt.h>
#include <linux/proc_fs.h>
#include <linux/bitops.h>
#include <linux/init.h>
diff --git a/arch/arm/mm/fault-armv.c b/arch/arm/mm/fault-armv.c
index f8ad035fdf01..940b75d75bb9 100644
--- a/arch/arm/mm/fault-armv.c
+++ b/arch/arm/mm/fault-armv.c
@@ -131,21 +131,22 @@ do_PrefetchAbort(unsigned long addr, struct pt_regs *regs)
* We take the easy way out of this problem - we make the
* PTE uncacheable. However, we leave the write buffer on.
*/
-static void adjust_pte(struct vm_area_struct *vma, unsigned long address)
+static int adjust_pte(struct vm_area_struct *vma, unsigned long address)
{
pgd_t *pgd;
pmd_t *pmd;
pte_t *pte, entry;
+ int ret = 0;
pgd = pgd_offset(vma->vm_mm, address);
if (pgd_none(*pgd))
- return;
+ goto no_pgd;
if (pgd_bad(*pgd))
goto bad_pgd;
pmd = pmd_offset(pgd, address);
if (pmd_none(*pmd))
- return;
+ goto no_pmd;
if (pmd_bad(*pmd))
goto bad_pmd;
@@ -161,23 +162,64 @@ static void adjust_pte(struct vm_area_struct *vma, unsigned long address)
pte_val(entry) &= ~L_PTE_CACHEABLE;
set_pte(pte, entry);
flush_tlb_page(vma, address);
+ ret = 1;
}
pte_unmap(pte);
- return;
+ return ret;
bad_pgd:
pgd_ERROR(*pgd);
pgd_clear(pgd);
- return;
+no_pgd:
+ return 0;
bad_pmd:
pmd_ERROR(*pmd);
pmd_clear(pmd);
- return;
+no_pmd:
+ return 0;
+}
+
+void __flush_dcache_page(struct page *page)
+{
+ struct mm_struct *mm = current->active_mm;
+ struct list_head *l;
+ unsigned long kaddr = (unsigned long)page_address(page);
+
+ cpu_cache_clean_invalidate_range(kaddr, kaddr + PAGE_SIZE, 0);
+
+ if (!page->mapping)
+ return;
+
+ /*
+ * With a VIVT cache, we need to also write back
+ * and invalidate any user data.
+ */
+ list_for_each(l, &page->mapping->i_mmap_shared) {
+ struct vm_area_struct *mpnt;
+ unsigned long off;
+
+ mpnt = list_entry(l, struct vm_area_struct, shared);
+
+ /*
+ * If this VMA is not in our MM, we can ignore it.
+ */
+ if (mpnt->vm_mm != mm)
+ continue;
+
+ if (page->index < mpnt->vm_pgoff)
+ continue;
+
+ off = page->index - mpnt->vm_pgoff;
+ if (off >= (mpnt->vm_end - mpnt->vm_start) >> PAGE_SHIFT)
+ continue;
+
+ flush_cache_page(mpnt, off);
+ }
}
static void
-make_coherent(struct vm_area_struct *vma, unsigned long addr, struct page *page)
+make_coherent(struct vm_area_struct *vma, unsigned long addr, struct page *page, int dirty)
{
struct list_head *l;
struct mm_struct *mm = vma->vm_mm;
@@ -213,14 +255,17 @@ make_coherent(struct vm_area_struct *vma, unsigned long addr, struct page *page)
if (off >= (mpnt->vm_end - mpnt->vm_start) >> PAGE_SHIFT)
continue;
+ off = mpnt->vm_start + (off << PAGE_SHIFT);
+
/*
* Ok, it is within mpnt. Fix it up.
*/
- adjust_pte(mpnt, mpnt->vm_start + (off << PAGE_SHIFT));
- aliases ++;
+ aliases += adjust_pte(mpnt, off);
}
if (aliases)
adjust_pte(vma, addr);
+ else
+ flush_cache_page(vma, addr);
}
/*
@@ -245,9 +290,12 @@ void update_mmu_cache(struct vm_area_struct *vma, unsigned long addr, pte_t pte)
return;
page = pfn_to_page(pfn);
if (page->mapping) {
- if (test_and_clear_bit(PG_dcache_dirty, &page->flags))
- __flush_dcache_page(page);
+ int dirty = test_and_clear_bit(PG_dcache_dirty, &page->flags);
+ unsigned long kaddr = (unsigned long)page_address(page);
+
+ if (dirty)
+ cpu_cache_clean_invalidate_range(kaddr, kaddr + PAGE_SIZE, 0);
- make_coherent(vma, addr, page);
+ make_coherent(vma, addr, page, dirty);
}
}
diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c
index ff3347e2669f..2775beae8d03 100644
--- a/arch/arm/mm/init.c
+++ b/arch/arm/mm/init.c
@@ -9,7 +9,6 @@
*/
#include <linux/config.h>
#include <linux/signal.h>
-#include <linux/sched.h>
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/string.h>
diff --git a/arch/arm/mm/mm-armv.c b/arch/arm/mm/mm-armv.c
index a0bc8550cf08..33e0237223f9 100644
--- a/arch/arm/mm/mm-armv.c
+++ b/arch/arm/mm/mm-armv.c
@@ -9,7 +9,6 @@
*
* Page table sludge for ARM v3 and v4 processor architectures.
*/
-#include <linux/sched.h>
#include <linux/mm.h>
#include <linux/init.h>
#include <linux/bootmem.h>
@@ -166,14 +165,13 @@ free:
static inline void
alloc_init_section(unsigned long virt, unsigned long phys, int prot)
{
- pmd_t *pmdp, pmd;
+ pmd_t *pmdp;
pmdp = pmd_offset(pgd_offset_k(virt), virt);
if (virt & (1 << 20))
pmdp++;
- pmd_val(pmd) = phys | prot;
- set_pmd(pmdp, pmd);
+ set_pmd(pmdp, __pmd(phys | prot));
}
/*
@@ -186,19 +184,20 @@ alloc_init_section(unsigned long virt, unsigned long phys, int prot)
static inline void
alloc_init_page(unsigned long virt, unsigned long phys, unsigned int prot_l1, pgprot_t prot)
{
- pmd_t *pmdp, pmd;
+ pmd_t *pmdp;
pte_t *ptep;
pmdp = pmd_offset(pgd_offset_k(virt), virt);
if (pmd_none(*pmdp)) {
+ unsigned long pmdval;
ptep = alloc_bootmem_low_pages(2 * PTRS_PER_PTE *
sizeof(pte_t));
- pmd_val(pmd) = __pa(ptep) | prot_l1;
- set_pmd(pmdp, pmd);
- pmd_val(pmd) += 256 * sizeof(pte_t);
- set_pmd(pmdp + 1, pmd);
+ pmdval = __pa(ptep) | prot_l1;
+ pmdp[0] = __pmd(pmdval);
+ pmdp[1] = __pmd(pmdval + 256 * sizeof(pte_t));
+ cpu_flush_pmd(pmdp);
}
ptep = pte_offset_kernel(pmdp, virt);
@@ -360,8 +359,9 @@ static void __init create_mapping(struct map_desc *md)
*/
void setup_mm_for_reboot(char mode)
{
+ unsigned long pmdval;
pgd_t *pgd;
- pmd_t pmd;
+ pmd_t *pmd;
int i;
if (current->mm && current->mm->pgd)
@@ -370,10 +370,11 @@ void setup_mm_for_reboot(char mode)
pgd = init_mm.pgd;
for (i = 0; i < FIRST_USER_PGD_NR + USER_PTRS_PER_PGD; i++) {
- pmd_val(pmd) = (i << PGDIR_SHIFT) |
- PMD_SECT_AP_WRITE | PMD_SECT_AP_READ |
- PMD_TYPE_SECT;
- set_pmd(pmd_offset(pgd + i, i << PGDIR_SHIFT), pmd);
+ pmdval = (i << PGDIR_SHIFT) |
+ PMD_SECT_AP_WRITE | PMD_SECT_AP_READ |
+ PMD_BIT4 | PMD_TYPE_SECT;
+ pmd = pmd_offset(pgd + i, i << PGDIR_SHIFT);
+ set_pmd(pmd, __pmd(pmdval));
}
}
diff --git a/arch/arm/mm/proc-arm1020.S b/arch/arm/mm/proc-arm1020.S
index c07da1b6e873..9e936e435f18 100644
--- a/arch/arm/mm/proc-arm1020.S
+++ b/arch/arm/mm/proc-arm1020.S
@@ -365,17 +365,15 @@ ENTRY(cpu_arm1020_set_pgd)
mov pc, lr
/*
- * cpu_arm1020_set_pmd(pmdp, pmd)
+ * cpu_arm1020_flush_pmd(pmdp)
*
* Set a level 1 translation table entry, and clean it out of
* any caches such that the MMUs can load it correctly.
*
* pmdp: pointer to PMD entry
- * pmd: PMD value to store
*/
.align 5
-ENTRY(cpu_arm1020_set_pmd)
- str r1, [r0]
+ENTRY(cpu_arm1020_flush_pmd)
#ifndef CONFIG_CPU_DCACHE_DISABLE
mcr p15, 0, r0, c7, c10, 4
mcr p15, 0, r0, c7, c10, 1 @ clean D entry (drain is done by TLB fns)
@@ -515,7 +513,7 @@ arm1020_processor_functions:
/* pgtable */
.word cpu_arm1020_set_pgd
- .word cpu_arm1020_set_pmd
+ .word cpu_arm1020_flush_pmd
.word cpu_arm1020_set_pte
.size arm1020_processor_functions, . - arm1020_processor_functions
diff --git a/arch/arm/mm/proc-arm6_7.S b/arch/arm/mm/proc-arm6_7.S
index 1b1055d27614..0405e3b21603 100644
--- a/arch/arm/mm/proc-arm6_7.S
+++ b/arch/arm/mm/proc-arm6_7.S
@@ -234,34 +234,14 @@ ENTRY(cpu_arm7_set_pgd)
mov pc, lr
/*
- * Function: arm6_set_pmd ()
+ * Function: arm6_flush_pmd(pmdp)
*
* Params : r0 = Address to set
- * : r1 = value to set
- *
- * Purpose : Set a PMD and flush it out of any WB cache
- */
-ENTRY(cpu_arm6_set_pmd)
- and r2, r1, #11
- teq r2, #1
- teqne r2, #9
- teqne r2, #10
- orreq r1, r1, #16 @ Updatable = 1 if Page table/Cacheable section
- str r1, [r0]
- mov pc, lr
-
-/*
- * Function: arm7_set_pmd ()
- *
- * Params : r0 = Address to set
- * : r1 = value to set
*
* Purpose : Set a PMD and flush it out of any WB cache
*/
-ENTRY(cpu_arm7_set_pmd)
- tst r1, #3
- orrne r1, r1, #16 @ Updatable bit is always set on ARM7
- str r1, [r0]
+ENTRY(cpu_arm6_flush_pmd)
+ENTRY(cpu_arm7_flush_pmd)
mov pc, lr
/*
@@ -368,7 +348,7 @@ ENTRY(arm6_processor_functions)
/* pgtable */
.word cpu_arm6_set_pgd
- .word cpu_arm6_set_pmd
+ .word cpu_arm6_flush_pmd
.word cpu_arm6_set_pte
.size arm6_processor_functions, . - arm6_processor_functions
@@ -402,7 +382,7 @@ ENTRY(arm7_processor_functions)
/* pgtable */
.word cpu_arm7_set_pgd
- .word cpu_arm7_set_pmd
+ .word cpu_arm7_flush_pmd
.word cpu_arm7_set_pte
.size arm7_processor_functions, . - arm7_processor_functions
diff --git a/arch/arm/mm/proc-arm720.S b/arch/arm/mm/proc-arm720.S
index ab4152a7ed39..f3396cbdd79a 100644
--- a/arch/arm/mm/proc-arm720.S
+++ b/arch/arm/mm/proc-arm720.S
@@ -115,17 +115,13 @@ ENTRY(cpu_arm720_set_pgd)
mov pc, lr
/*
- * Function: arm720_set_pmd ()
+ * Function: arm720_flush_pmd(pmdp)
*
* Params : r0 = Address to set
- * : r1 = value to set
*
* Purpose : Set a PMD and flush it out of any WB cache
*/
-ENTRY(cpu_arm720_set_pmd)
- tst r1, #3
- orrne r1, r1, #16 @ Updatable bit is
- str r1, [r0] @ always set on ARM720
+ENTRY(cpu_arm720_flush_pmd)
mov pc, lr
/*
@@ -222,7 +218,7 @@ ENTRY(arm720_processor_functions)
/* pgtable */
.word cpu_arm720_set_pgd
- .word cpu_arm720_set_pmd
+ .word cpu_arm720_flush_pmd
.word cpu_arm720_set_pte
.size arm720_processor_functions, . - arm720_processor_functions
diff --git a/arch/arm/mm/proc-arm920.S b/arch/arm/mm/proc-arm920.S
index 59ebba740113..46206021205e 100644
--- a/arch/arm/mm/proc-arm920.S
+++ b/arch/arm/mm/proc-arm920.S
@@ -368,17 +368,15 @@ ENTRY(cpu_arm920_set_pgd)
mov pc, lr
/*
- * cpu_arm920_set_pmd(pmdp, pmd)
+ * cpu_arm920_flush_pmd(pmdp)
*
* Set a level 1 translation table entry, and clean it out of
* any caches such that the MMUs can load it correctly.
*
* pmdp: pointer to PMD entry
- * pmd: PMD value to store
*/
.align 5
-ENTRY(cpu_arm920_set_pmd)
- str r1, [r0]
+ENTRY(cpu_arm920_flush_pmd)
mcr p15, 0, r0, c7, c10, 1 @ clean D entry
mcr p15, 0, r0, c7, c10, 4 @ drain WB
mov pc, lr
@@ -503,7 +501,7 @@ arm920_processor_functions:
/* pgtable */
.word cpu_arm920_set_pgd
- .word cpu_arm920_set_pmd
+ .word cpu_arm920_flush_pmd
.word cpu_arm920_set_pte
.size arm920_processor_functions, . - arm920_processor_functions
diff --git a/arch/arm/mm/proc-arm922.S b/arch/arm/mm/proc-arm922.S
index e213895147f5..d74cf416cc27 100644
--- a/arch/arm/mm/proc-arm922.S
+++ b/arch/arm/mm/proc-arm922.S
@@ -369,17 +369,15 @@ ENTRY(cpu_arm922_set_pgd)
mov pc, lr
/*
- * cpu_arm922_set_pmd(pmdp, pmd)
+ * cpu_arm922_flush_pmd(pmdp)
*
* Set a level 1 translation table entry, and clean it out of
* any caches such that the MMUs can load it correctly.
*
* pmdp: pointer to PMD entry
- * pmd: PMD value to store
*/
.align 5
-ENTRY(cpu_arm922_set_pmd)
- str r1, [r0]
+ENTRY(cpu_arm922_flush_pmd)
mcr p15, 0, r0, c7, c10, 1 @ clean D entry
mcr p15, 0, r0, c7, c10, 4 @ drain WB
mov pc, lr
@@ -502,7 +500,7 @@ arm922_processor_functions:
/* pgtable */
.word cpu_arm922_set_pgd
- .word cpu_arm922_set_pmd
+ .word cpu_arm922_flush_pmd
.word cpu_arm922_set_pte
.size arm922_processor_functions, . - arm922_processor_functions
diff --git a/arch/arm/mm/proc-arm926.S b/arch/arm/mm/proc-arm926.S
index 78f6c9996290..766103efa986 100644
--- a/arch/arm/mm/proc-arm926.S
+++ b/arch/arm/mm/proc-arm926.S
@@ -350,17 +350,15 @@ ENTRY(cpu_arm926_set_pgd)
mov pc, lr
/*
- * cpu_arm926_set_pmd(pmdp, pmd)
+ * cpu_arm926_flush_pmd(pmdp)
*
* Set a level 1 translation table entry, and clean it out of
* any caches such that the MMUs can load it correctly.
*
* pmdp: pointer to PMD entry
- * pmd: PMD value to store
*/
.align 5
-ENTRY(cpu_arm926_set_pmd)
- str r1, [r0]
+ENTRY(cpu_arm926_flush_pmd)
#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH
mcr p15, 0, r0, c7, c10, 1 @ clean D entry
#endif
@@ -500,7 +498,7 @@ arm926_processor_functions:
/* pgtable */
.word cpu_arm926_set_pgd
- .word cpu_arm926_set_pmd
+ .word cpu_arm926_flush_pmd
.word cpu_arm926_set_pte
.size arm926_processor_functions, . - arm926_processor_functions
diff --git a/arch/arm/mm/proc-sa110.S b/arch/arm/mm/proc-sa110.S
index 69a111109b9c..fec7e5e8576b 100644
--- a/arch/arm/mm/proc-sa110.S
+++ b/arch/arm/mm/proc-sa110.S
@@ -425,18 +425,16 @@ ENTRY(cpu_sa1100_set_pgd)
mov pc, lr
/*
- * cpu_sa110_set_pmd(pmdp, pmd)
+ * cpu_sa110_flush_pmd(pmdp)
*
* Set a level 1 translation table entry, and clean it out of
* any caches such that the MMUs can load it correctly.
*
* pmdp: pointer to PMD entry
- * pmd: PMD value to store
*/
.align 5
-ENTRY(cpu_sa110_set_pmd)
-ENTRY(cpu_sa1100_set_pmd)
- str r1, [r0]
+ENTRY(cpu_sa110_flush_pmd)
+ENTRY(cpu_sa1100_flush_pmd)
mcr p15, 0, r0, c7, c10, 1 @ clean D entry
mcr p15, 0, r0, c7, c10, 4 @ drain WB
mov pc, lr
@@ -544,7 +542,7 @@ ENTRY(sa110_processor_functions)
/* pgtable */
.word cpu_sa110_set_pgd
- .word cpu_sa110_set_pmd
+ .word cpu_sa110_flush_pmd
.word cpu_sa110_set_pte
.size sa110_processor_functions, . - sa110_processor_functions
@@ -584,7 +582,7 @@ ENTRY(sa1100_processor_functions)
/* pgtable */
.word cpu_sa1100_set_pgd
- .word cpu_sa1100_set_pmd
+ .word cpu_sa1100_flush_pmd
.word cpu_sa1100_set_pte
.size sa1100_processor_functions, . - sa1100_processor_functions
diff --git a/arch/arm/mm/proc-syms.c b/arch/arm/mm/proc-syms.c
index fe84d27a9681..47c5448e619f 100644
--- a/arch/arm/mm/proc-syms.c
+++ b/arch/arm/mm/proc-syms.c
@@ -1,7 +1,7 @@
/*
* linux/arch/arm/mm/proc-syms.c
*
- * Copyright (C) 2000 Russell King
+ * Copyright (C) 2000-2002 Russell King
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -15,6 +15,8 @@
#include <asm/proc-fns.h>
#include <asm/tlbflush.h>
+EXPORT_SYMBOL(__flush_dcache_page);
+
#ifndef MULTI_CPU
EXPORT_SYMBOL(cpu_cache_clean_invalidate_all);
EXPORT_SYMBOL(cpu_cache_clean_invalidate_range);
@@ -25,7 +27,7 @@ EXPORT_SYMBOL(cpu_dcache_invalidate_range);
EXPORT_SYMBOL(cpu_icache_invalidate_range);
EXPORT_SYMBOL(cpu_icache_invalidate_page);
EXPORT_SYMBOL(cpu_set_pgd);
-EXPORT_SYMBOL(cpu_set_pmd);
+EXPORT_SYMBOL(cpu_flush_pmd);
EXPORT_SYMBOL(cpu_set_pte);
#else
EXPORT_SYMBOL(processor);
diff --git a/arch/arm/mm/proc-xscale.S b/arch/arm/mm/proc-xscale.S
index 2d4bbb5b91d3..c8f2b34b59d1 100644
--- a/arch/arm/mm/proc-xscale.S
+++ b/arch/arm/mm/proc-xscale.S
@@ -573,17 +573,15 @@ ENTRY(cpu_xscale_set_pgd)
cpwait_ret lr, ip
/*
- * cpu_xscale_set_pmd(pmdp, pmd)
+ * cpu_xscale_flush_pmd(pmdp)
*
* Set a level 1 translation table entry, and clean it out of
* any caches such that the MMUs can load it correctly.
*
* pmdp: pointer to PMD entry
- * pmd: PMD value to store
*/
.align 5
-ENTRY(cpu_xscale_set_pmd)
- str r1, [r0]
+ENTRY(cpu_xscale_flush_pmd)
mov ip, #0
mcr p15, 0, r0, c7, c10, 1 @ Clean D cache line
mcr p15, 0, ip, c7, c10, 4 @ Drain Write (& Fill) Buffer
@@ -721,7 +719,7 @@ ENTRY(xscale_processor_functions)
/* pgtable */
.word cpu_xscale_set_pgd
- .word cpu_xscale_set_pmd
+ .word cpu_xscale_flush_pmd
.word cpu_xscale_set_pte
.size xscale_processor_functions, . - xscale_processor_functions
diff --git a/arch/arm/mm/tlb-v4wb.S b/arch/arm/mm/tlb-v4wb.S
index 90ca6c7597a3..3444855fb646 100644
--- a/arch/arm/mm/tlb-v4wb.S
+++ b/arch/arm/mm/tlb-v4wb.S
@@ -7,10 +7,10 @@
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
- * ARM architecture version 4 and version 5 TLB handling functions.
- * These assume a split I/D TLBs, with a write buffer.
+ * ARM architecture version 4 TLB handling functions.
+ * These assume a split I/D TLBs w/o I TLB entry, with a write buffer.
*
- * Processors: ARM920 ARM922 ARM926 SA110 SA1100 SA1110 XScale
+ * Processors: SA110 SA1100 SA1110
*/
#include <linux/linkage.h>
#include <linux/init.h>
@@ -67,50 +67,6 @@ ENTRY(v4wb_flush_kern_tlb_range)
blo 1b
mov pc, lr
-/*
- * These two are optimised for ARM920, ARM922, ARM926, Xscale
- */
-
-/*
- * v4wb_flush_user_tlb_range(start, end, mm)
- *
- * Invalidate a range of TLB entries in the specified address space.
- *
- * - start - range start address
- * - end - range end address
- * - mm - mm_struct describing address space
- */
- .align 5
-ENTRY(v4wbi_flush_user_tlb_range)
- vma_vm_mm ip, r2
- act_mm r3 @ get current->active_mm
- eors r3, ip, r3 @ == mm ?
- movne pc, lr @ no, we dont do anything
- mov r3, #0
- mcr p15, 0, r3, c7, c10, 4 @ drain WB
- vma_vm_flags r2, r2
- bic r0, r0, #0x0ff
- bic r0, r0, #0xf00
-1: tst r2, #VM_EXEC
- mcrne p15, 0, r0, c8, c5, 1 @ invalidate I TLB entry
- mcr p15, 0, r0, c8, c6, 1 @ invalidate D TLB entry
- add r0, r0, #PAGE_SZ
- cmp r0, r1
- blo 1b
- mov pc, lr
-
-ENTRY(v4wbi_flush_kern_tlb_range)
- mov r3, #0
- mcr p15, 0, r3, c7, c10, 4 @ drain WB
- bic r0, r0, #0x0ff
- bic r0, r0, #0xf00
-1: mcr p15, 0, r0, c8, c5, 1 @ invalidate I TLB entry
- mcr p15, 0, r0, c8, c6, 1 @ invalidate D TLB entry
- add r0, r0, #PAGE_SZ
- cmp r0, r1
- blo 1b
- mov pc, lr
-
__INIT
.type v4wb_tlb_fns, #object
@@ -119,10 +75,3 @@ ENTRY(v4wb_tlb_fns)
.long v4wb_flush_kern_tlb_range
.long v4wb_tlb_flags
.size v4wb_tlb_fns, . - v4wb_tlb_fns
-
- .type v4wbi_tlb_fns, #object
-ENTRY(v4wbi_tlb_fns)
- .long v4wbi_flush_user_tlb_range
- .long v4wbi_flush_kern_tlb_range
- .long v4wbi_tlb_flags
- .size v4wbi_tlb_fns, . - v4wbi_tlb_fns
diff --git a/arch/arm/mm/tlb-v4wbi.S b/arch/arm/mm/tlb-v4wbi.S
new file mode 100644
index 000000000000..ecbdcd0b981a
--- /dev/null
+++ b/arch/arm/mm/tlb-v4wbi.S
@@ -0,0 +1,68 @@
+/*
+ * linux/arch/arm/mm/tlbv4wbi.S
+ *
+ * Copyright (C) 1997-2002 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * ARM architecture version 4 and version 5 TLB handling functions.
+ * These assume a split I/D TLBs, with a write buffer.
+ *
+ * Processors: ARM920 ARM922 ARM926 XScale
+ */
+#include <linux/linkage.h>
+#include <linux/init.h>
+#include <asm/constants.h>
+#include <asm/tlbflush.h>
+#include "proc-macros.S"
+
+/*
+ * v4wb_flush_user_tlb_range(start, end, mm)
+ *
+ * Invalidate a range of TLB entries in the specified address space.
+ *
+ * - start - range start address
+ * - end - range end address
+ * - mm - mm_struct describing address space
+ */
+ .align 5
+ENTRY(v4wbi_flush_user_tlb_range)
+ vma_vm_mm ip, r2
+ act_mm r3 @ get current->active_mm
+ eors r3, ip, r3 @ == mm ?
+ movne pc, lr @ no, we dont do anything
+ mov r3, #0
+ mcr p15, 0, r3, c7, c10, 4 @ drain WB
+ vma_vm_flags r2, r2
+ bic r0, r0, #0x0ff
+ bic r0, r0, #0xf00
+1: tst r2, #VM_EXEC
+ mcrne p15, 0, r0, c8, c5, 1 @ invalidate I TLB entry
+ mcr p15, 0, r0, c8, c6, 1 @ invalidate D TLB entry
+ add r0, r0, #PAGE_SZ
+ cmp r0, r1
+ blo 1b
+ mov pc, lr
+
+ENTRY(v4wbi_flush_kern_tlb_range)
+ mov r3, #0
+ mcr p15, 0, r3, c7, c10, 4 @ drain WB
+ bic r0, r0, #0x0ff
+ bic r0, r0, #0xf00
+1: mcr p15, 0, r0, c8, c5, 1 @ invalidate I TLB entry
+ mcr p15, 0, r0, c8, c6, 1 @ invalidate D TLB entry
+ add r0, r0, #PAGE_SZ
+ cmp r0, r1
+ blo 1b
+ mov pc, lr
+
+ __INIT
+
+ .type v4wbi_tlb_fns, #object
+ENTRY(v4wbi_tlb_fns)
+ .long v4wbi_flush_user_tlb_range
+ .long v4wbi_flush_kern_tlb_range
+ .long v4wbi_tlb_flags
+ .size v4wbi_tlb_fns, . - v4wbi_tlb_fns
diff --git a/arch/arm/tools/Makefile b/arch/arm/tools/Makefile
index 69e89827a523..1c8014bdeb10 100644
--- a/arch/arm/tools/Makefile
+++ b/arch/arm/tools/Makefile
@@ -4,9 +4,6 @@
# Copyright (C) 2001 Russell King
#
-include $(TOPDIR)/Rules.make
-
include/asm-arm/mach-types.h: $(obj)/mach-types $(obj)/gen-mach-types
@echo ' Generating $@'
- @awk -f $(obj)/gen-mach-types $(obj)/mach-types > $@
-
+ @$(AWK) -f $(obj)/gen-mach-types $(obj)/mach-types > $@
diff --git a/drivers/acorn/block/mfmhd.c b/drivers/acorn/block/mfmhd.c
index bd2294d8d4de..01287e5452a4 100644
--- a/drivers/acorn/block/mfmhd.c
+++ b/drivers/acorn/block/mfmhd.c
@@ -161,13 +161,6 @@ struct hd_geometry {
/*#define DEBUG */
#endif
/*
- * List of card types that we recognise
- */
-static const card_ids mfm_cids[] = {
- { MANU_ACORN, PROD_ACORN_MFM },
- { 0xffff, 0xffff }
-};
-/*
* End of configuration
*/
@@ -1230,8 +1223,6 @@ static struct block_device_operations mfm_fops =
.ioctl = mfm_ioctl,
};
-static struct expansion_card *ecs;
-
/*
* See if there is a controller at the address presently at mfm_addr
*
@@ -1266,44 +1257,18 @@ static int mfm_probecontroller (unsigned int mfm_addr)
return 1;
}
-/*
- * Look for a MFM controller - first check the motherboard, then the podules
- * The podules have an extra interrupt enable that needs to be played with
- *
- * The HDC is accessed at MEDIUM IOC speeds.
- */
-static int __init mfm_init (void)
+static int mfm_do_init(unsigned char irqmask)
{
- unsigned char irqmask;
- int i;
-
- if (mfm_probecontroller(ONBOARD_MFM_ADDRESS)) {
- mfm_addr = ONBOARD_MFM_ADDRESS;
- mfm_IRQPollLoc = IOC_IRQSTATB;
- mfm_irqenable = 0;
- mfm_irq = IRQ_HARDDISK;
- irqmask = 0x08; /* IL3 pin */
- } else {
- ecs = ecard_find(0, mfm_cids);
- if (!ecs) {
- mfm_addr = 0;
- return -1;
- }
-
- mfm_addr = ecard_address(ecs, ECARD_IOC, ECARD_MEDIUM) + 0x800;
- mfm_IRQPollLoc = ioaddr(mfm_addr + 0x400);
- mfm_irqenable = mfm_IRQPollLoc;
- mfm_irq = ecs->irq;
- irqmask = 0x08;
-
- ecard_claim(ecs);
- }
+ int i, ret;
printk("mfm: found at address %08X, interrupt %d\n", mfm_addr, mfm_irq);
+
+ ret = -EBUSY;
if (!request_region (mfm_addr, 10, "mfm"))
goto out1;
- if (register_blkdev(MAJOR_NR, "mfm", &mfm_fops)) {
+ ret = register_blkdev(MAJOR_NR, "mfm", &mfm_fops);
+ if (ret) {
printk("mfm_init: unable to get major number %d\n", MAJOR_NR);
goto out2;
}
@@ -1319,8 +1284,10 @@ static int __init mfm_init (void)
lastspecifieddrive = -1;
mfm_drives = mfm_initdrives();
- if (!mfm_drives)
+ if (!mfm_drives) {
+ ret = -ENODEV;
goto out3;
+ }
for (i = 0; i < mfm_drives; i++) {
struct gendisk *disk = alloc_disk(64);
@@ -1335,7 +1302,8 @@ static int __init mfm_init (void)
printk("mfm: detected %d hard drive%s\n", mfm_drives,
mfm_drives == 1 ? "" : "s");
- if (request_irq(mfm_irq, mfm_interrupt_handler, SA_INTERRUPT, "MFM harddisk", NULL)) {
+ ret = request_irq(mfm_irq, mfm_interrupt_handler, SA_INTERRUPT, "MFM harddisk", NULL);
+ if (ret) {
printk("mfm: unable to get IRQ%d\n", mfm_irq);
goto out4;
}
@@ -1359,19 +1327,17 @@ out3:
out2:
release_region(mfm_addr, 10);
out1:
- ecard_release(ecs);
- return -1;
+ return ret;
Enomem:
while (i--)
put_disk(mfm_gendisk[i]);
goto out3;
}
-static void __exit mfm_exit(void)
+static void mfm_do_exit(void)
{
int i;
- if (ecs && mfm_irqenable)
- outw (0, mfm_irqenable); /* Required to enable IRQs from MFM podule */
+
free_irq(mfm_irq, NULL);
for (i = 0; i < mfm_drives; i++) {
del_gendisk(mfm_gendisk[i]);
@@ -1379,12 +1345,72 @@ static void __exit mfm_exit(void)
}
blk_cleanup_queue(&mfm_queue);
unregister_blkdev(MAJOR_NR, "mfm");
- if (ecs)
- ecard_release(ecs);
if (mfm_addr)
release_region(mfm_addr, 10);
}
+static int __devinit mfm_probe(struct expansion_card *ec, struct ecard_id *id)
+{
+ if (mfm_addr)
+ return -EBUSY;
+
+ mfm_addr = ecard_address(ec, ECARD_IOC, ECARD_MEDIUM) + 0x800;
+ mfm_IRQPollLoc = ioaddr(mfm_addr + 0x400);
+ mfm_irqenable = mfm_IRQPollLoc;
+ mfm_irq = ec->irq;
+
+ return mfm_do_init(0x08);
+}
+
+static void __devexit mfm_remove(struct expansion_card *ec)
+{
+ outw (0, mfm_irqenable); /* Required to enable IRQs from MFM podule */
+ mfm_do_exit();
+}
+
+static const struct ecard_id mfm_cids[] = {
+ { MANU_ACORN, PROD_ACORN_MFM },
+ { 0xffff, 0xffff },
+};
+
+static struct ecard_driver mfm_driver = {
+ .probe = mfm_probe,
+ .remove = __devexit(mfm_remove),
+ .id_table = mfm_cids,
+ .drv = {
+ .name = "mfm",
+ },
+};
+
+/*
+ * Look for a MFM controller - first check the motherboard, then the podules
+ * The podules have an extra interrupt enable that needs to be played with
+ *
+ * The HDC is accessed at MEDIUM IOC speeds.
+ */
+static int __init mfm_init (void)
+{
+ unsigned char irqmask;
+
+ if (mfm_probecontroller(ONBOARD_MFM_ADDRESS)) {
+ mfm_addr = ONBOARD_MFM_ADDRESS;
+ mfm_IRQPollLoc = IOC_IRQSTATB;
+ mfm_irqenable = 0;
+ mfm_irq = IRQ_HARDDISK;
+ return mfm_do_init(0x08); /* IL3 pin */
+ } else {
+ return ecard_register_driver(&mfm_driver);
+ }
+}
+
+static void __exit mfm_exit(void)
+{
+ if (mfm_addr == ONBOARD_MFM_ADDRESS)
+ mfm_do_exit();
+ else
+ ecard_unregister_driver(&mfm_driver);
+}
+
module_init(mfm_init)
module_exit(mfm_exit)
MODULE_LICENSE("GPL");
diff --git a/drivers/acorn/net/ether1.c b/drivers/acorn/net/ether1.c
index d20d361c85a6..16baa4718194 100644
--- a/drivers/acorn/net/ether1.c
+++ b/drivers/acorn/net/ether1.c
@@ -1021,8 +1021,6 @@ ether1_probe(struct expansion_card *ec, const struct ecard_id *id)
ether1_banner();
- ecard_claim(ec);
-
dev = init_etherdev(NULL, sizeof(struct ether1_priv));
if (!dev) {
ret = -ENOMEM;
@@ -1077,7 +1075,6 @@ release:
unregister_netdev(dev);
kfree(dev);
out:
- ecard_release(ec);
return ret;
}
@@ -1092,8 +1089,6 @@ static void __devexit ether1_remove(struct expansion_card *ec)
release_region(dev->base_addr, 16);
release_region(dev->base_addr + 0x800, 4096);
kfree(dev);
-
- ecard_release(ec);
}
static const struct ecard_id ether1_ids[] = {
diff --git a/drivers/acorn/net/ether3.c b/drivers/acorn/net/ether3.c
index e14949425351..5400ea3ba100 100644
--- a/drivers/acorn/net/ether3.c
+++ b/drivers/acorn/net/ether3.c
@@ -830,8 +830,6 @@ ether3_probe(struct expansion_card *ec, const struct ecard_id *id)
ether3_banner();
- ecard_claim(ec);
-
dev = init_etherdev(NULL, sizeof(struct dev_priv));
if (!dev) {
ret = -ENOMEM;
@@ -918,7 +916,6 @@ free:
unregister_netdev(dev);
kfree(dev);
out:
- ecard_release(ec);
return ret;
}
@@ -931,8 +928,6 @@ static void __devexit ether3_remove(struct expansion_card *ec)
unregister_netdev(dev);
release_region(dev->base_addr, 128);
kfree(dev);
-
- ecard_release(ec);
}
static const struct ecard_id ether3_ids[] = {
diff --git a/drivers/acorn/net/etherh.c b/drivers/acorn/net/etherh.c
index 4ffe92dd478f..4cabcdab7e37 100644
--- a/drivers/acorn/net/etherh.c
+++ b/drivers/acorn/net/etherh.c
@@ -568,8 +568,6 @@ etherh_probe(struct expansion_card *ec, const struct ecard_id *id)
etherh_banner();
- ecard_claim(ec);
-
dev = init_etherdev(NULL, sizeof(struct etherh_priv));
if (!dev) {
ret = -ENOMEM;
@@ -725,7 +723,6 @@ free:
kfree(dev->priv);
kfree(dev);
out:
- ecard_release(ec);
return ret;
}
@@ -744,7 +741,6 @@ static void __devexit etherh_remove(struct expansion_card *ec)
ec->ops = NULL;
kfree(ec->irq_data);
- ecard_release(ec);
}
static const struct ecard_id etherh_ids[] = {
diff --git a/drivers/acorn/scsi/acornscsi.c b/drivers/acorn/scsi/acornscsi.c
index ad7469425a94..099c22550153 100644
--- a/drivers/acorn/scsi/acornscsi.c
+++ b/drivers/acorn/scsi/acornscsi.c
@@ -109,10 +109,7 @@
* If not set, then use PIO mode (not currently supported).
*/
#define USE_DMAC
-/*
- * List of devices that the driver will recognise
- */
-#define ACORNSCSI_LIST { MANU_ACORN, PROD_ACORN_SCSI }
+
/*
* ====================================================================================
*/
@@ -2832,148 +2829,6 @@ int acornscsi_reset(Scsi_Cmnd *SCpnt, unsigned int reset_flags)
/*==============================================================================================
* initialisation & miscellaneous support
*/
-static struct expansion_card *ecs[MAX_ECARDS];
-
-/*
- * Prototype: void acornscsi_init(AS_Host *host)
- * Purpose : initialise the AS_Host structure for one interface & setup hardware
- * Params : host - host to setup
- */
-static
-void acornscsi_host_init(AS_Host *host)
-{
- memset(&host->stats, 0, sizeof (host->stats));
- queue_initialise(&host->queues.issue);
- queue_initialise(&host->queues.disconnected);
- msgqueue_initialise(&host->scsi.msgs);
-
- acornscsi_resetcard(host);
-}
-
-int acornscsi_detect(Scsi_Host_Template * tpnt)
-{
- static const card_ids acornscsi_cids[] = { ACORNSCSI_LIST, { 0xffff, 0xffff } };
- int i, count = 0;
- struct Scsi_Host *instance;
- AS_Host *host;
-
- tpnt->proc_name = "acornscsi";
-
- for (i = 0; i < MAX_ECARDS; i++)
- ecs[i] = NULL;
-
- ecard_startfind();
-
- while(1) {
- ecs[count] = ecard_find(0, acornscsi_cids);
- if (!ecs[count])
- break;
-
- if (ecs[count]->irq == 0xff) {
- printk("scsi: WD33C93 does not have IRQ enabled - ignoring\n");
- continue;
- }
-
- ecard_claim(ecs[count]); /* Must claim here - card produces irq on reset */
-
- instance = scsi_register(tpnt, sizeof(AS_Host));
- if (!instance) {
- ecard_release(ecs[count]);
- break;
- }
-
- host = (AS_Host *)instance->hostdata;
-
- instance->io_port = ecard_address(ecs[count], ECARD_MEMC, 0);
- instance->irq = ecs[count]->irq;
-
- host->host = instance;
- host->scsi.io_port = ioaddr(instance->io_port + 0x800);
- host->scsi.irq = instance->irq;
- host->card.io_intr = POD_SPACE(instance->io_port) + 0x800;
- host->card.io_page = POD_SPACE(instance->io_port) + 0xc00;
- host->card.io_ram = ioaddr(instance->io_port);
- host->dma.io_port = instance->io_port + 0xc00;
- host->dma.io_intr_clear = POD_SPACE(instance->io_port) + 0x800;
-
- ecs[count]->irqaddr = (char *)ioaddr(host->card.io_intr);
- ecs[count]->irqmask = 0x0a;
-
- if (!request_region(instance->io_port + 0x800, 2, "acornscsi(sbic)"))
- goto err_1;
- if (!request_region(host->card.io_intr, 1, "acornscsi(intr)"))
- goto err_2;
- if (!request_region(host->card.io_page, 1, "acornscsi(page)"))
- goto err_3;
-#ifdef USE_DMAC
- if (!request_region(host->dma.io_port, 256, "acornscsi(dmac)"))
- goto err_4;
-#endif
- if (!request_region(instance->io_port, 2048, "acornscsi(ram)"))
- goto err_5;
-
- if (request_irq(host->scsi.irq, acornscsi_intr, SA_INTERRUPT, "acornscsi", host)) {
- printk(KERN_CRIT "scsi%d: IRQ%d not free, interrupts disabled\n",
- instance->host_no, host->scsi.irq);
- host->scsi.irq = NO_IRQ;
- }
-
- acornscsi_host_init(host);
-
- ++count;
- }
- return count;
-
-err_5:
-#ifdef USE_DMAC
- release_region(host->dma.io_port, 256);
-#endif
-err_4:
- release_region(host->card.io_page, 1);
-err_3:
- release_region(host->card.io_intr, 1);
-err_2:
- release_region(instance->io_port + 0x800, 2);
-err_1:
- scsi_unregister(instance);
- return 0;
-}
-
-/*
- * Function: int acornscsi_release(struct Scsi_Host *host)
- * Purpose : release all resources used by this adapter
- * Params : host - driver structure to release
- * Returns : nothing of any consequence
- */
-int acornscsi_release(struct Scsi_Host *instance)
-{
- AS_Host *host = (AS_Host *)instance->hostdata;
- int i;
-
- /*
- * Put card into RESET state
- */
- outb(0x80, host->card.io_page);
-
- if (host->scsi.irq != NO_IRQ)
- free_irq(host->scsi.irq, host);
-
- release_region(instance->io_port + 0x800, 2);
- release_region(host->card.io_intr, 1);
- release_region(host->card.io_page, 1);
- release_region(host->dma.io_port, 256);
- release_region(instance->io_port, 2048);
-
- for (i = 0; i < MAX_ECARDS; i++)
- if (ecs[i] && instance->io_port == ecard_address(ecs[i], ECARD_MEMC, 0))
- ecard_release(ecs[i]);
-
- msgqueue_free(&host->scsi.msgs);
- queue_free(&host->queues.disconnected);
- queue_free(&host->queues.issue);
-
- return 0;
-}
/*
* Function: char *acornscsi_info(struct Scsi_Host *host)
@@ -3126,10 +2981,9 @@ static Scsi_Host_Template acornscsi_template = {
.module = THIS_MODULE,
.proc_info = acornscsi_proc_info,
.name = "AcornSCSI",
- .detect = acornscsi_detect,
- .release = acornscsi_release,
.info = acornscsi_info,
.queuecommand = acornscsi_queuecmd,
+#warning fixme
.abort = acornscsi_abort,
.reset = acornscsi_reset,
.can_queue = 16,
@@ -3137,22 +2991,137 @@ static Scsi_Host_Template acornscsi_template = {
.sg_tablesize = SG_ALL,
.cmd_per_lun = 2,
.unchecked_isa_dma = 0,
- .use_clustering = DISABLE_CLUSTERING
+ .use_clustering = DISABLE_CLUSTERING,
+ .proc_name = "acornscsi",
};
-static int __init acornscsi_init(void)
+static int __devinit
+acornscsi_probe(struct expansion_card *ec, const struct ecard_id *id)
{
- scsi_register_host(&acornscsi_template);
- if (acornscsi_template.present)
- return 0;
+ struct Scsi_Host *host;
+ AS_Host *ashost;
+ int ret = -ENOMEM;
+
+ host = scsi_register(&acornscsi_template, sizeof(AS_Host));
+ if (!host)
+ goto out;
- scsi_unregister_host(&acornscsi_template);
- return -ENODEV;
+ ashost = (AS_Host *)host->hostdata;
+
+ host->io_port = ecard_address(ec, ECARD_MEMC, 0);
+ host->irq = ec->irq;
+
+ ashost->host = host;
+ ashost->scsi.io_port = ioaddr(host->io_port + 0x800);
+ ashost->scsi.irq = host->irq;
+ ashost->card.io_intr = POD_SPACE(host->io_port) + 0x800;
+ ashost->card.io_page = POD_SPACE(host->io_port) + 0xc00;
+ ashost->card.io_ram = ioaddr(host->io_port);
+ ashost->dma.io_port = host->io_port + 0xc00;
+ ashost->dma.io_intr_clear = POD_SPACE(host->io_port) + 0x800;
+
+ ec->irqaddr = (char *)ioaddr(ashost->card.io_intr);
+ ec->irqmask = 0x0a;
+
+ ret = -EBUSY;
+ if (!request_region(host->io_port + 0x800, 2, "acornscsi(sbic)"))
+ goto err_1;
+ if (!request_region(ashost->card.io_intr, 1, "acornscsi(intr)"))
+ goto err_2;
+ if (!request_region(ashost->card.io_page, 1, "acornscsi(page)"))
+ goto err_3;
+#ifdef USE_DMAC
+ if (!request_region(ashost->dma.io_port, 256, "acornscsi(dmac)"))
+ goto err_4;
+#endif
+ if (!request_region(host->io_port, 2048, "acornscsi(ram)"))
+ goto err_5;
+
+ ret = request_irq(host->irq, acornscsi_intr, SA_INTERRUPT, "acornscsi", ashost);
+ if (ret) {
+ printk(KERN_CRIT "scsi%d: IRQ%d not free: %d\n",
+ host->host_no, ashost->scsi.irq, ret);
+ goto err_6;
+ }
+
+ memset(&ashost->stats, 0, sizeof (ashost->stats));
+ queue_initialise(&ashost->queues.issue);
+ queue_initialise(&ashost->queues.disconnected);
+ msgqueue_initialise(&ashost->scsi.msgs);
+
+ acornscsi_resetcard(ashost);
+
+ ret = scsi_add_host(host);
+ if (ret == 0)
+ goto out;
+
+ free_irq(host->irq, ashost);
+ err_6:
+ release_region(host->io_port, 2048);
+ err_5:
+#ifdef USE_DMAC
+ release_region(ashost->dma.io_port, 256);
+#endif
+ err_4:
+ release_region(ashost->card.io_page, 1);
+ err_3:
+ release_region(ashost->card.io_intr, 1);
+ err_2:
+ release_region(host->io_port + 0x800, 2);
+ err_1:
+ scsi_unregister(host);
+ out:
+ return ret;
+}
+
+static void __devexit acornscsi_remove(struct expansion_card *ec)
+{
+ struct Scsi_Host *host = ecard_get_drvdata(ec);
+ AS_Host *ashost = (AS_Host *)host->hostdata;
+
+ ecard_set_drvdata(ec, NULL);
+ scsi_remove_host(host);
+
+ /*
+ * Put card into RESET state
+ */
+ outb(0x80, ashost->card.io_page);
+
+ free_irq(host->irq, ashost);
+
+ release_region(host->io_port + 0x800, 2);
+ release_region(ashost->card.io_intr, 1);
+ release_region(ashost->card.io_page, 1);
+ release_region(ashost->dma.io_port, 256);
+ release_region(host->io_port, 2048);
+
+ msgqueue_free(&ashost->scsi.msgs);
+ queue_free(&ashost->queues.disconnected);
+ queue_free(&ashost->queues.issue);
+}
+
+static const struct ecard_id acornscsi_cids[] = {
+ { MANU_ACORN, PROD_ACORN_SCSI },
+ { 0xffff, 0xffff },
+};
+
+static struct ecard_driver acornscsi_driver = {
+ .probe = acornscsi_probe,
+ .remove = __devexit_p(acornscsi_remove),
+ .id_table = acornscsi_cids,
+ .drv = {
+ .name = "acornscsi",
+ },
+};
+
+static int __init acornscsi_init(void)
+{
+ return ecard_register_driver(&acornscsi_driver);
}
static void __exit acornscsi_exit(void)
{
- scsi_unregister_host(&acornscsi_template);
+ ecard_remove_driver(&acornscsi_driver);
}
module_init(acornscsi_init);
@@ -3161,4 +3130,3 @@ module_exit(acornscsi_exit);
MODULE_AUTHOR("Russell King");
MODULE_DESCRIPTION("AcornSCSI driver");
MODULE_LICENSE("GPL");
-
diff --git a/drivers/acorn/scsi/arxescsi.c b/drivers/acorn/scsi/arxescsi.c
index d2ab33346cbe..aa6454f0a2c3 100644
--- a/drivers/acorn/scsi/arxescsi.c
+++ b/drivers/acorn/scsi/arxescsi.c
@@ -37,21 +37,29 @@
#include "../../scsi/scsi.h"
#include "../../scsi/hosts.h"
-#include "arxescsi.h"
#include "fas216.h"
-/* Hmm - this should go somewhere else */
-#define BUS_ADDR(x) ((((unsigned long)(x)) << 2) + IO_BASE)
+struct arxescsi_info {
+ FAS216_Info info;
-/* Configuration */
-#define ARXESCSI_XTALFREQ 24
-#define ARXESCSI_ASYNC_PERIOD 200
-#define ARXESCSI_SYNC_DEPTH 0
+ /* other info... */
+ unsigned int cstatus; /* card status register */
+ unsigned int dmaarea; /* Pseudo DMA area */
+};
-/*
- * List of devices that the driver will recognise
- */
-#define ARXESCSI_LIST { MANU_ARXE, PROD_ARXE_SCSI }
+#define CSTATUS_IRQ (1 << 0)
+#define CSTATUS_DRQ (1 << 0)
+
+#ifndef CAN_QUEUE
+#define CAN_QUEUE 1
+#endif
+
+#ifndef CMD_PER_LUN
+#define CMD_PER_LUN 1
+#endif
+
+/* Hmm - this should go somewhere else */
+#define BUS_ADDR(x) ((((unsigned long)(x)) << 2) + IO_BASE)
/*
* Version
@@ -60,8 +68,6 @@
#define VER_MINOR 1
#define VER_PATCH 1
-static struct expansion_card *ecs[MAX_ECARDS];
-
/*
* Function: int arxescsi_dma_setup(host, SCpnt, direction, min_type)
* Purpose : initialises DMA/PIO
@@ -85,7 +91,7 @@ arxescsi_dma_setup(struct Scsi_Host *host, Scsi_Pointer *SCp,
/* Faster transfer routines, written by SH to speed up the loops */
-static __inline__ unsigned char getb(unsigned int address, unsigned int reg)
+static inline unsigned char getb(unsigned int address, unsigned int reg)
{
unsigned char value;
@@ -96,7 +102,7 @@ static __inline__ unsigned char getb(unsigned int address, unsigned int reg)
return value;
}
-static __inline__ unsigned int getw(unsigned int address, unsigned int reg)
+static inline unsigned int getw(unsigned int address, unsigned int reg)
{
unsigned int value;
@@ -109,7 +115,7 @@ static __inline__ unsigned int getw(unsigned int address, unsigned int reg)
return value;
}
-static __inline__ void putw(unsigned int address, unsigned int reg, unsigned long value)
+static inline void putw(unsigned int address, unsigned int reg, unsigned long value)
{
__asm__ __volatile__(
"mov %0, %0, lsl #16\n\t"
@@ -157,7 +163,7 @@ void arxescsi_pseudo_dma_write(unsigned char *addr, unsigned int io)
void arxescsi_dma_pseudo(struct Scsi_Host *host, Scsi_Pointer *SCp,
fasdmadir_t direction, int transfer)
{
- ARXEScsi_Info *info = (ARXEScsi_Info *)host->hostdata;
+ struct arxescsi_info *info = (struct arxescsi_info *)host->hostdata;
unsigned int length, io, error=0;
unsigned char *addr;
@@ -248,106 +254,6 @@ static void arxescsi_dma_stop(struct Scsi_Host *host, Scsi_Pointer *SCp)
}
/*
- * Function: int arxescsi_detect(Scsi_Host_Template * tpnt)
- * Purpose : initialises ARXE SCSI driver
- * Params : tpnt - template for this SCSI adapter
- * Returns : >0 if host found, 0 otherwise.
- */
-int arxescsi_detect(Scsi_Host_Template *tpnt)
-{
- static const card_ids arxescsi_cids[] = { ARXESCSI_LIST, { 0xffff, 0xffff} };
- int count = 0;
- struct Scsi_Host *host;
-
- tpnt->proc_name = "arxescsi";
- memset(ecs, 0, sizeof (ecs));
-
- ecard_startfind();
-
- while (1) {
- ARXEScsi_Info *info;
-
- ecs[count] = ecard_find(0, arxescsi_cids);
- if (!ecs[count])
- break;
-
- ecard_claim(ecs[count]);
-
- host = scsi_register(tpnt, sizeof (ARXEScsi_Info));
- if (!host) {
- ecard_release(ecs[count]);
- break;
- }
-
- host->io_port = ecard_address(ecs[count], ECARD_MEMC, 0) + 0x0800;
- host->irq = NO_IRQ;
- host->dma_channel = NO_DMA;
- host->can_queue = 0; /* no command queueing */
- info = (ARXEScsi_Info *)host->hostdata;
-
- info->info.scsi.io_port = host->io_port;
- info->info.scsi.irq = host->irq;
- info->info.scsi.io_shift = 3;
- info->info.ifcfg.clockrate = ARXESCSI_XTALFREQ;
- info->info.ifcfg.select_timeout = 255;
- info->info.ifcfg.asyncperiod = ARXESCSI_ASYNC_PERIOD;
- info->info.ifcfg.sync_max_depth = ARXESCSI_SYNC_DEPTH;
- info->info.ifcfg.cntl3 = CNTL3_FASTSCSI | CNTL3_FASTCLK;
- info->info.ifcfg.disconnect_ok = 0;
- info->info.ifcfg.wide_max_size = 0;
- info->info.dma.setup = arxescsi_dma_setup;
- info->info.dma.pseudo = arxescsi_dma_pseudo;
- info->info.dma.stop = arxescsi_dma_stop;
- info->dmaarea = host->io_port + 128;
- info->cstatus = host->io_port + 384;
-
- ecs[count]->irqaddr = (unsigned char *)BUS_ADDR(host->io_port);
- ecs[count]->irqmask = CSTATUS_IRQ;
-
- if (!request_region(host->io_port, 120, "arxescsi-fas")) {
- ecard_release(ecs[count]);
- scsi_unregister(host);
- break;
- }
-
- if (!request_region(host->io_port + 128, 384, "arxescsi-dma")) {
- ecard_release(ecs[count]);
- release_region(host->io_port, 120);
- scsi_unregister(host);
- break;
- }
-
- printk("scsi%d: Has no interrupts - using polling mode\n",
- host->host_no);
-
- fas216_init(host);
- ++count;
- }
- return count;
-}
-
-/*
- * Function: int arxescsi_release(struct Scsi_Host * host)
- * Purpose : releases all resources used by this adapter
- * Params : host - driver host structure to return info for.
- * Returns : nothing
- */
-int arxescsi_release(struct Scsi_Host *host)
-{
- int i;
-
- fas216_release(host);
-
- release_region(host->io_port, 120);
- release_region(host->io_port + 128, 384);
-
- for (i = 0; i < MAX_ECARDS; i++)
- if (ecs[i] && host->io_port == (ecard_address(ecs[i], ECARD_MEMC, 0) + 0x0800))
- ecard_release(ecs[i]);
- return 0;
-}
-
-/*
* Function: const char *arxescsi_info(struct Scsi_Host * host)
* Purpose : returns a descriptive string about this interface,
* Params : host - driver host structure to return info for.
@@ -355,7 +261,7 @@ int arxescsi_release(struct Scsi_Host *host)
*/
const char *arxescsi_info(struct Scsi_Host *host)
{
- ARXEScsi_Info *info = (ARXEScsi_Info *)host->hostdata;
+ struct arxescsi_info *info = (struct arxescsi_info *)host->hostdata;
static char string[100], *p;
p = string;
@@ -385,14 +291,14 @@ int arxescsi_proc_info(char *buffer, char **start, off_t offset,
{
int pos, begin;
struct Scsi_Host *host;
- ARXEScsi_Info *info;
+ struct arxescsi_info *info;
Scsi_Device *scd;
host = scsi_host_hn_get(host_no);
if (!host)
return 0;
- info = (ARXEScsi_Info *)host->hostdata;
+ info = (struct arxescsi_info *)host->hostdata;
if (inout == 1)
return -EINVAL;
@@ -424,22 +330,122 @@ int arxescsi_proc_info(char *buffer, char **start, off_t offset,
return pos;
}
-static Scsi_Host_Template arxescsi_template = ARXEScsi;
+static Scsi_Host_Template arxescsi_template = {
+ .proc_info = arxescsi_proc_info,
+ .name = "ARXE SCSI card",
+ .info = arxescsi_info,
+ .command = fas216_command,
+ .queuecommand = fas216_queue_command,
+ .eh_host_reset_handler = fas216_eh_host_reset,
+ .eh_bus_reset_handler = fas216_eh_bus_reset,
+ .eh_device_reset_handler = fas216_eh_device_reset,
+ .eh_abort_handler = fas216_eh_abort,
+ .can_queue = 0,
+ .this_id = 7,
+ .sg_tablesize = SG_ALL,
+ .cmd_per_lun = CMD_PER_LUN,
+ .use_clustering = DISABLE_CLUSTERING,
+ .proc_name = "arxescsi",
+};
+
+static int __devinit
+arxescsi_probe(struct expansion_card *ec, const struct ecard_id *id)
+{
+ struct Scsi_Host *host;
+ struct arxescsi_info *info;
+ int ret = -ENOMEM;
-static int __init init_arxe_scsi_driver(void)
+ host = scsi_register(&arxescsi_template, sizeof(struct arxescsi_info));
+ if (!host)
+ goto out;
+
+ host->io_port = ecard_address(ec, ECARD_MEMC, 0) + 0x0800;
+ host->irq = NO_IRQ;
+ host->dma_channel = NO_DMA;
+
+ info = (struct arxescsi_info *)host->hostdata;
+ info->info.scsi.io_port = host->io_port;
+ info->info.scsi.irq = host->irq;
+ info->info.scsi.io_shift = 3;
+ info->info.ifcfg.clockrate = 24; /* MHz */
+ info->info.ifcfg.select_timeout = 255;
+ info->info.ifcfg.asyncperiod = 200; /* ns */
+ info->info.ifcfg.sync_max_depth = 0;
+ info->info.ifcfg.cntl3 = CNTL3_FASTSCSI | CNTL3_FASTCLK;
+ info->info.ifcfg.disconnect_ok = 0;
+ info->info.ifcfg.wide_max_size = 0;
+ info->info.dma.setup = arxescsi_dma_setup;
+ info->info.dma.pseudo = arxescsi_dma_pseudo;
+ info->info.dma.stop = arxescsi_dma_stop;
+ info->dmaarea = host->io_port + 128;
+ info->cstatus = host->io_port + 384;
+
+ ec->irqaddr = (unsigned char *)BUS_ADDR(host->io_port);
+ ec->irqmask = CSTATUS_IRQ;
+
+ if (!request_region(host->io_port, 120, "arxescsi-fas")) {
+ ret = -EBUSY;
+ goto out_free;
+ }
+
+ if (!request_region(host->io_port + 128, 384, "arxescsi-dma")) {
+ ret = -EBUSY;
+ goto out_release;
+ }
+
+ printk("scsi%d: Has no interrupts - using polling mode\n",
+ host->host_no);
+
+ fas216_init(host);
+
+ ret = scsi_add_host(host);
+ if (ret == 0)
+ goto out;
+
+ release_region(host->io_port + 128, 384);
+ out_release:
+ release_region(host->io_port, 120);
+ out_free:
+ scsi_unregister(host);
+ out:
+ return ret;
+}
+
+static void __devexit arxescsi_release(struct expansion_card *ec)
{
- arxescsi_template.module = THIS_MODULE;
- scsi_register_host(&arxescsi_template);
- if (arxescsi_template.present)
- return 0;
+ struct Scsi_Host *host = ecard_get_drvdata(ec);
+
+ ecard_set_drvdata(ec, NULL);
+ scsi_remove_host(host);
+ fas216_release(host);
+
+ release_region(host->io_port + 128, 384);
+ release_region(host->io_port, 120);
+ scsi_unregister(host);
+}
- scsi_unregister_host(&arxescsi_template);
- return -ENODEV;
+static const struct ecard_id arxescsi_cids[] = {
+ { MANU_ARXE, PROD_ARXE_SCSI },
+ { 0xffff, 0xffff },
+};
+
+static struct ecard_driver arxescsi_driver = {
+ .probe = arxescsi_probe,
+ .remove = __devexit_p(arxescsi_remove),
+ .id_table = arxescsi_cids,
+ .drv = {
+ .name = "arxescsi",
+ },
+};
+
+static int __init init_arxe_scsi_driver(void)
+{
+ return ecard_register_driver(&arxescsi_driver);
}
static void __exit exit_arxe_scsi_driver(void)
{
- scsi_unregister_host(&arxescsi_template);
+ ecard_remove_driver(&arxescsi_driver);
}
module_init(init_arxe_scsi_driver);
diff --git a/drivers/acorn/scsi/cumana_1.c b/drivers/acorn/scsi/cumana_1.c
index 2f722722d07d..308e438198a4 100644
--- a/drivers/acorn/scsi/cumana_1.c
+++ b/drivers/acorn/scsi/cumana_1.c
@@ -1,56 +1,13 @@
-#define AUTOSENSE
-#define PSEUDO_DMA
-
/*
* Generic Generic NCR5380 driver
*
- * Copyright 1995, Russell King
- *
- * ALPHA RELEASE 1.
- *
- * For more information, please consult
- *
- * NCR 5380 Family
- * SCSI Protocol Controller
- * Databook
- *
- * NCR Microelectronics
- * 1635 Aeroplaza Drive
- * Colorado Springs, CO 80916
- * 1+ (719) 578-3400
- * 1+ (800) 334-5454
- */
-
-
-/*
- * Options :
- *
- * PARITY - enable parity checking. Not supported.
- *
- * SCSI2 - enable support for SCSI-II tagged queueing. Untested.
- *
- * USLEEP - enable support for devices that don't disconnect. Untested.
- */
-
-/*
- * $Log: cumana_1.c,v $
- * Revision 1.3 1998/05/03 20:45:32 alan
- * ARM SCSI update. This adds the eesox driver and massively updates the
- * Cumana driver. The folks who bought cumana arent anal retentive all
- * docs are secret weenies so now there are docs ..
- *
- * Revision 1.2 1998/03/08 05:49:46 davem
- * Merge to 2.1.89
- *
- * Revision 1.1 1998/02/23 02:45:22 davem
- * Merge to 2.1.88
- *
+ * Copyright 1995-2002, Russell King
*/
-
#include <linux/module.h>
#include <linux/signal.h>
#include <linux/sched.h>
#include <linux/ioport.h>
+#include <linux/delay.h>
#include <linux/blk.h>
#include <linux/init.h>
@@ -64,28 +21,19 @@
#include <scsi/scsicam.h>
-#define CUMANASCSI_PUBLIC_RELEASE 1
-
-static const card_ids cumanascsi_cids[] = {
- { MANU_CUMANA, PROD_CUMANA_SCSI_1 },
- { 0xffff, 0xffff }
-};
-
-#define NCR5380_implementation_fields \
- int port, ctrl
-
-#define NCR5380_local_declare() \
- struct Scsi_Host *_instance
-
-#define NCR5380_setup(instance) \
- _instance = instance
+#define AUTOSENSE
+#define PSEUDO_DMA
-#define NCR5380_read(reg) cumanascsi_read(_instance, reg)
-#define NCR5380_write(reg, value) cumanascsi_write(_instance, reg, value)
+#define CUMANASCSI_PUBLIC_RELEASE 1
-#define NCR5380_intr cumanascsi_intr
-#define NCR5380_queue_command cumanascsi_queue_command
-#define NCR5380_proc_info cumanascsi_proc_info
+#define NCR5380_implementation_fields int port, ctrl
+#define NCR5380_local_declare() struct Scsi_Host *_instance
+#define NCR5380_setup(instance) _instance = instance
+#define NCR5380_read(reg) cumanascsi_read(_instance, reg)
+#define NCR5380_write(reg, value) cumanascsi_write(_instance, reg, value)
+#define NCR5380_intr cumanascsi_intr
+#define NCR5380_queue_command cumanascsi_queue_command
+#define NCR5380_proc_info cumanascsi_proc_info
int NCR5380_proc_info(char *buffer, char **start, off_t offset,
int length, int hostno, int inout);
@@ -95,112 +43,13 @@ int NCR5380_proc_info(char *buffer, char **start, off_t offset,
#include "../../scsi/NCR5380.h"
-/*
- * Function : cumanascsi_setup(char *str, int *ints)
- *
- * Purpose : LILO command line initialization of the overrides array,
- *
- * Inputs : str - unused, ints - array of integer parameters with ints[0]
- * equal to the number of ints.
- *
- */
-
void cumanascsi_setup(char *str, int *ints)
{
}
-#define CUMANA_ADDRESS(card) (ecard_address((card), ECARD_IOC, ECARD_SLOW) + 0x800)
-#define CUMANA_IRQ(card) ((card)->irq)
-/*
- * Function : int cumanascsi_detect(Scsi_Host_Template * tpnt)
- *
- * Purpose : initializes cumana NCR5380 driver based on the
- * command line / compile time port and irq definitions.
- *
- * Inputs : tpnt - template for this SCSI adapter.
- *
- * Returns : 1 if a host adapter was found, 0 if not.
- *
- */
-static struct expansion_card *ecs[4];
-
-int cumanascsi_detect(Scsi_Host_Template * tpnt)
+const char *cumanascsi_info(struct Scsi_Host *spnt)
{
- int count = 0;
- struct Scsi_Host *instance;
-
- tpnt->proc_name = "CumanaSCSI-1";
-
- memset (ecs, 0, sizeof (ecs));
-
- while(1) {
- if((ecs[count] = ecard_find(0, cumanascsi_cids)) == NULL)
- break;
-
- instance = scsi_register (tpnt, sizeof(struct NCR5380_hostdata));
- if (!instance)
- break;
- instance->io_port = CUMANA_ADDRESS(ecs[count]);
- instance->irq = CUMANA_IRQ(ecs[count]);
-
- NCR5380_init(instance, 0);
- ecard_claim(ecs[count]);
-
- instance->n_io_port = 255;
- if ( !(request_region (instance->io_port, instance->n_io_port, "CumanaSCSI-1")) ) {
- ecard_release(ecs[count]);
- scsi_unregister(instance);
- break;
- }
-
- ((struct NCR5380_hostdata *)instance->hostdata)->ctrl = 0;
- outb(0x00, instance->io_port - 577);
-
- if (instance->irq != IRQ_NONE)
- if (request_irq(instance->irq, cumanascsi_intr, SA_INTERRUPT, "CumanaSCSI-1", NULL)) {
- printk("scsi%d: IRQ%d not free, interrupts disabled\n",
- instance->host_no, instance->irq);
- instance->irq = IRQ_NONE;
- }
-
- if (instance->irq == IRQ_NONE) {
- printk("scsi%d: interrupts not enabled. for better interactive performance,\n", instance->host_no);
- printk("scsi%d: please jumper the board for a free IRQ.\n", instance->host_no);
- }
-
- printk("scsi%d: at port %lX irq", instance->host_no, instance->io_port);
- if (instance->irq == IRQ_NONE)
- printk ("s disabled");
- else
- printk (" %d", instance->irq);
- printk(" options CAN_QUEUE=%d CMD_PER_LUN=%d release=%d",
- tpnt->can_queue, tpnt->cmd_per_lun, CUMANASCSI_PUBLIC_RELEASE);
- printk("\nscsi%d:", instance->host_no);
- NCR5380_print_options(instance);
- printk("\n");
-
- ++count;
- }
- return count;
-}
-
-int cumanascsi_release (struct Scsi_Host *shpnt)
-{
- int i;
-
- if (shpnt->irq != IRQ_NONE)
- free_irq (shpnt->irq, NULL);
- if (shpnt->io_port)
- release_region (shpnt->io_port, shpnt->n_io_port);
-
- for (i = 0; i < 4; i++)
- if (shpnt->io_port == CUMANA_ADDRESS(ecs[i]))
- ecard_release (ecs[i]);
- return 0;
-}
-
-const char * cumanascsi_info (struct Scsi_Host *spnt) {
- return "";
+ return "";
}
#ifdef NOT_EFFICIENT
@@ -219,8 +68,8 @@ const char * cumanascsi_info (struct Scsi_Host *spnt) {
#define L(v) (((v)<<16)|((v) & 0x0000ffff))
#define H(v) (((v)>>16)|((v) & 0xffff0000))
-static inline int NCR5380_pwrite(struct Scsi_Host *instance, unsigned char *addr,
- int len)
+static inline int
+NCR5380_pwrite(struct Scsi_Host *instance, unsigned char *addr, int len)
{
int *ctrl = &((struct NCR5380_hostdata *)instance->hostdata)->ctrl;
int oldctrl = *ctrl;
@@ -289,8 +138,8 @@ end:
return len;
}
-static inline int NCR5380_pread(struct Scsi_Host *instance, unsigned char *addr,
- int len)
+static inline int
+NCR5380_pread(struct Scsi_Host *instance, unsigned char *addr, int len)
{
int *ctrl = &((struct NCR5380_hostdata *)instance->hostdata)->ctrl;
int oldctrl = *ctrl;
@@ -367,25 +216,25 @@ end:
static char cumanascsi_read(struct Scsi_Host *instance, int reg)
{
- int iobase = instance->io_port;
- int i;
- int *ctrl = &((struct NCR5380_hostdata *)instance->hostdata)->ctrl;
+ unsigned int iobase = instance->io_port;
+ int i;
+ int *ctrl = &((struct NCR5380_hostdata *)instance->hostdata)->ctrl;
- CTRL(iobase, 0);
- i = inb(iobase + 64 + reg);
- CTRL(iobase, 0x40);
+ CTRL(iobase, 0);
+ i = inb(iobase + 64 + reg);
+ CTRL(iobase, 0x40);
- return i;
+ return i;
}
static void cumanascsi_write(struct Scsi_Host *instance, int reg, int value)
{
- int iobase = instance->io_port;
- int *ctrl = &((struct NCR5380_hostdata *)instance->hostdata)->ctrl;
+ int iobase = instance->io_port;
+ int *ctrl = &((struct NCR5380_hostdata *)instance->hostdata)->ctrl;
- CTRL(iobase, 0);
- outb(value, iobase + 64 + reg);
- CTRL(iobase, 0x40);
+ CTRL(iobase, 0);
+ outb(value, iobase + 64 + reg);
+ CTRL(iobase, 0x40);
}
#undef CTRL
@@ -395,8 +244,6 @@ static void cumanascsi_write(struct Scsi_Host *instance, int reg, int value)
static Scsi_Host_Template cumanascsi_template = {
.module = THIS_MODULE,
.name = "Cumana 16-bit SCSI",
- .detect = cumanascsi_detect,
- .release = cumanascsi_release,
.info = cumanascsi_info,
.queuecommand = cumanascsi_queue_command,
.eh_abort_handler = NCR5380_abort,
@@ -408,26 +255,101 @@ static Scsi_Host_Template cumanascsi_template = {
.sg_tablesize = SG_ALL,
.cmd_per_lun = 2,
.unchecked_isa_dma = 0,
- .use_clustering = DISABLE_CLUSTERING
+ .use_clustering = DISABLE_CLUSTERING,
+ .proc_name = "CumanaSCSI-1",
};
-static int __init cumanascsi_init(void)
+static int __devinit
+cumanascsi1_probe(struct expansion_card *ec, struct ecard_ids *id)
{
- scsi_register_host(&cumanascsi_template);
- if (cumanascsi_template.present)
- return 0;
+ struct Scsi_Host *host;
+ int ret = -ENOMEM;
+
+ host = scsi_register (tpnt, sizeof(struct NCR5380_hostdata));
+ if (!host)
+ goto out;
+
+ host->io_port = ecard_address(ec, ECARD_IOC, ECARD_SLOW) + 0x800;
+ host->irq = ec->irq;
+
+ NCR5380_init(host, 0);
- scsi_unregister_host(&cumanascsi_template);
- return -ENODEV;
+ host->n_io_port = 255;
+ if (!(request_region(host->io_port, host->n_io_port, "CumanaSCSI-1"))) {
+ ret = -EBUSY;
+ goto out_free;
+ }
+
+ ((struct NCR5380_hostdata *)host->hostdata)->ctrl = 0;
+ outb(0x00, host->io_port - 577);
+
+ ret = request_irq(host->irq, cumanascsi_intr, SA_INTERRUPT,
+ "CumanaSCSI-1", host);
+ if (ret) {
+ printk("scsi%d: IRQ%d not free: %d\n",
+ host->host_no, host->irq, ret);
+ goto out_release;
+ }
+
+ printk("scsi%d: at port 0x%08lx irq %d",
+ host->host_no, host->io_port, host->irq);
+ printk(" options CAN_QUEUE=%d CMD_PER_LUN=%d release=%d",
+ tpnt->can_queue, tpnt->cmd_per_lun, CUMANASCSI_PUBLIC_RELEASE);
+ printk("\nscsi%d:", host->host_no);
+ NCR5380_print_options(host);
+ printk("\n");
+
+ ret = scsi_add_host(host);
+ if (ret == 0)
+ goto out;
+
+ free_irq(host->irq, host);
+ out_release:
+ release_region(host->io_port, host->n_io_port);
+ out_free:
+ scsi_unregister(host);
+ out:
+ return ret;
+}
+
+static void __devexit cumanascsi1_remove(struct expansion_card *ec)
+{
+ struct Scsi_Host *host = ecard_get_drvdata(ec);
+
+ ecard_set_drvdata(ec, NULL);
+
+ scsi_remove_host(host);
+ free_irq(host->irq, host);
+ release_region(host->io_port, host->n_io_port);
+ scsi_remove(host);
+}
+
+static const struct ecard_ids cumanascsi1_cids[] = {
+ { MANU_CUMANA, PROD_CUMANA_SCSI_1 },
+ { 0xffff, 0xffff }
+};
+
+static struct ecard_driver cumanascsi1_driver = {
+ .probe = cumanascsi1_probe,
+ .remove = __devexit_p(cumanascsi1_remove),
+ .id_table = cumanascsi1_cids,
+ .drv = {
+ .name = "cumanascsi1",
+ },
+};
+
+static int __init cumanascsi_init(void)
+{
+ return ecard_register_driver(&cumanascsi1_driver);
}
static void __exit cumanascsi_exit(void)
{
- scsi_unregister_host(&cumanascsi_template);
+ ecard_remove_driver(&cumanascsi1_driver);
}
module_init(cumanascsi_init);
module_exit(cumanascsi_exit);
+MODULE_DESCRIPTION("Cumana SCSI-1 driver for Acorn machines");
MODULE_LICENSE("GPL");
-
diff --git a/drivers/acorn/scsi/cumana_2.c b/drivers/acorn/scsi/cumana_2.c
index a1a245890c2f..33aa30401b1a 100644
--- a/drivers/acorn/scsi/cumana_2.c
+++ b/drivers/acorn/scsi/cumana_2.c
@@ -1,7 +1,7 @@
/*
* linux/drivers/acorn/scsi/cumana_2.c
*
- * Copyright (C) 1997-2000 Russell King
+ * Copyright (C) 1997-2002 Russell King
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -42,16 +42,6 @@
#include <scsi/scsicam.h>
-/* Configuration */
-#define CUMANASCSI2_XTALFREQ 40
-#define CUMANASCSI2_ASYNC_PERIOD 200
-#define CUMANASCSI2_SYNC_DEPTH 7
-
-/*
- * List of devices that the driver will recognise
- */
-#define CUMANASCSI2_LIST { MANU_CUMANA, PROD_CUMANA_SCSI_2 }
-
#define CUMANASCSI2_STATUS (0)
#define STATUS_INT (1 << 0)
#define STATUS_DRQ (1 << 1)
@@ -73,15 +63,12 @@
#define CUMANASCSI2_FAS216_OFFSET (0xc0)
#define CUMANASCSI2_FAS216_SHIFT 0
+#define CUMANASCSI2_FAS216_SIZE (16)
/*
* Version
*/
-#define VER_MAJOR 0
-#define VER_MINOR 0
-#define VER_PATCH 4
-
-static struct expansion_card *ecs[MAX_ECARDS];
+#define VERSION "1.00 (13/11/2002 2.5.47)"
/*
* Use term=0,1,0,0,0 to turn terminators on/off
@@ -90,16 +77,15 @@ static int term[MAX_ECARDS] = { 1, 1, 1, 1, 1, 1, 1, 1 };
#define NR_SG 256
-typedef struct {
+struct cumanascsi2_info {
FAS216_Info info;
- /* other info... */
unsigned int status; /* card status register */
unsigned int alatch; /* Control register */
unsigned int terms; /* Terminator state */
unsigned int dmaarea; /* Pseudo DMA area */
struct scatterlist sg[NR_SG]; /* Scatter DMA list */
-} CumanaScsi2_Info;
+};
#define CSTATUS_IRQ (1 << 0)
#define CSTATUS_DRQ (1 << 1)
@@ -129,12 +115,8 @@ cumanascsi_2_irqdisable(struct expansion_card *ec, int irqnr)
}
static const expansioncard_ops_t cumanascsi_2_ops = {
- cumanascsi_2_irqenable,
- cumanascsi_2_irqdisable,
- NULL,
- NULL,
- NULL,
- NULL
+ .irqenable = cumanascsi_2_irqenable,
+ .irqdisable = cumanascsi_2_irqdisable,
};
/* Prototype: void cumanascsi_2_terminator_ctl(host, on_off)
@@ -145,7 +127,7 @@ static const expansioncard_ops_t cumanascsi_2_ops = {
static void
cumanascsi_2_terminator_ctl(struct Scsi_Host *host, int on_off)
{
- CumanaScsi2_Info *info = (CumanaScsi2_Info *)host->hostdata;
+ struct cumanascsi2_info *info = (struct cumanascsi2_info *)host->hostdata;
if (on_off) {
info->terms = 1;
@@ -182,7 +164,7 @@ static fasdmatype_t
cumanascsi_2_dma_setup(struct Scsi_Host *host, Scsi_Pointer *SCp,
fasdmadir_t direction, fasdmatype_t min_type)
{
- CumanaScsi2_Info *info = (CumanaScsi2_Info *)host->hostdata;
+ struct cumanascsi2_info *info = (struct cumanascsi2_info *)host->hostdata;
int dmach = host->dma_channel;
outb(ALATCH_DIS_DMA, info->alatch);
@@ -233,7 +215,7 @@ static void
cumanascsi_2_dma_pseudo(struct Scsi_Host *host, Scsi_Pointer *SCp,
fasdmadir_t direction, int transfer)
{
- CumanaScsi2_Info *info = (CumanaScsi2_Info *)host->hostdata;
+ struct cumanascsi2_info *info = (struct cumanascsi2_info *)host->hostdata;
unsigned int length;
unsigned char *addr;
@@ -307,129 +289,13 @@ end:
static void
cumanascsi_2_dma_stop(struct Scsi_Host *host, Scsi_Pointer *SCp)
{
- CumanaScsi2_Info *info = (CumanaScsi2_Info *)host->hostdata;
+ struct cumanascsi2_info *info = (struct cumanascsi2_info *)host->hostdata;
if (host->dma_channel != NO_DMA) {
outb(ALATCH_DIS_DMA, info->alatch);
disable_dma(host->dma_channel);
}
}
-/* Prototype: int cumanascsi_2_detect(Scsi_Host_Template * tpnt)
- * Purpose : initialises Cumana SCSI 2 driver
- * Params : tpnt - template for this SCSI adapter
- * Returns : >0 if host found, 0 otherwise.
- */
-int
-cumanascsi_2_detect(Scsi_Host_Template *tpnt)
-{
- static const card_ids cumanascsi_2_cids[] =
- { CUMANASCSI2_LIST, { 0xffff, 0xffff} };
- int count = 0;
- struct Scsi_Host *host;
-
- tpnt->proc_name = "cumanascs2";
- memset(ecs, 0, sizeof (ecs));
-
- ecard_startfind();
-
- while (1) {
- CumanaScsi2_Info *info;
-
- ecs[count] = ecard_find(0, cumanascsi_2_cids);
- if (!ecs[count])
- break;
-
- ecard_claim(ecs[count]);
-
- host = scsi_register(tpnt, sizeof (CumanaScsi2_Info));
- if (!host) {
- ecard_release(ecs[count]);
- break;
- }
-
- host->io_port = ecard_address(ecs[count], ECARD_MEMC, 0);
- host->irq = ecs[count]->irq;
- host->dma_channel = ecs[count]->dma;
- info = (CumanaScsi2_Info *)host->hostdata;
-
- info->terms = term[count] ? 1 : 0;
- cumanascsi_2_terminator_ctl(host, info->terms);
-
- info->info.scsi.io_port = host->io_port + CUMANASCSI2_FAS216_OFFSET;
- info->info.scsi.io_shift = CUMANASCSI2_FAS216_SHIFT;
- info->info.scsi.irq = host->irq;
- info->info.ifcfg.clockrate = CUMANASCSI2_XTALFREQ;
- info->info.ifcfg.select_timeout = 255;
- info->info.ifcfg.asyncperiod = CUMANASCSI2_ASYNC_PERIOD;
- info->info.ifcfg.sync_max_depth = CUMANASCSI2_SYNC_DEPTH;
- info->info.ifcfg.cntl3 = CNTL3_BS8 | CNTL3_FASTSCSI | CNTL3_FASTCLK;
- info->info.ifcfg.disconnect_ok = 1;
- info->info.ifcfg.wide_max_size = 0;
- info->info.dma.setup = cumanascsi_2_dma_setup;
- info->info.dma.pseudo = cumanascsi_2_dma_pseudo;
- info->info.dma.stop = cumanascsi_2_dma_stop;
- info->dmaarea = host->io_port + CUMANASCSI2_PSEUDODMA;
- info->status = host->io_port + CUMANASCSI2_STATUS;
- info->alatch = host->io_port + CUMANASCSI2_ALATCH;
-
- ecs[count]->irqaddr = (unsigned char *)ioaddr(info->status);
- ecs[count]->irqmask = STATUS_INT;
- ecs[count]->irq_data = (void *)info->alatch;
- ecs[count]->ops = (expansioncard_ops_t *)&cumanascsi_2_ops;
-
- if (!request_region(host->io_port + CUMANASCSI2_FAS216_OFFSET,
- 16 << CUMANASCSI2_FAS216_SHIFT, "cumanascsi2-fas")) {
- scsi_unregister(host);
- ecard_release(ecs[count]);
- break;
- }
-
-
- if (host->irq != NO_IRQ &&
- request_irq(host->irq, cumanascsi_2_intr,
- SA_INTERRUPT, "cumanascsi2", host)) {
- printk("scsi%d: IRQ%d not free, interrupts disabled\n",
- host->host_no, host->irq);
- host->irq = NO_IRQ;
- info->info.scsi.irq = NO_IRQ;
- }
-
- if (host->dma_channel != NO_DMA &&
- request_dma(host->dma_channel, "cumanascsi2")) {
- printk("scsi%d: DMA%d not free, DMA disabled\n",
- host->host_no, host->dma_channel);
- host->dma_channel = NO_DMA;
- }
-
- fas216_init(host);
- ++count;
- }
- return count;
-}
-
-/* Prototype: int cumanascsi_2_release(struct Scsi_Host * host)
- * Purpose : releases all resources used by this adapter
- * Params : host - driver host structure to return info for.
- */
-int cumanascsi_2_release(struct Scsi_Host *host)
-{
- int i;
-
- fas216_release(host);
-
- if (host->irq != NO_IRQ)
- free_irq(host->irq, host);
- if (host->dma_channel != NO_DMA)
- free_dma(host->dma_channel);
- release_region(host->io_port + CUMANASCSI2_FAS216_OFFSET,
- 16 << CUMANASCSI2_FAS216_SHIFT);
-
- for (i = 0; i < MAX_ECARDS; i++)
- if (ecs[i] && host->io_port == ecard_address (ecs[i], ECARD_MEMC, 0))
- ecard_release (ecs[i]);
- return 0;
-}
-
/* Prototype: const char *cumanascsi_2_info(struct Scsi_Host * host)
* Purpose : returns a descriptive string about this interface,
* Params : host - driver host structure to return info for.
@@ -437,15 +303,14 @@ int cumanascsi_2_release(struct Scsi_Host *host)
*/
const char *cumanascsi_2_info(struct Scsi_Host *host)
{
- CumanaScsi2_Info *info = (CumanaScsi2_Info *)host->hostdata;
+ struct cumanascsi2_info *info = (struct cumanascsi2_info *)host->hostdata;
static char string[100], *p;
p = string;
p += sprintf(p, "%s ", host->hostt->name);
p += fas216_info(&info->info, p);
- p += sprintf(p, "v%d.%d.%d terminators o%s",
- VER_MAJOR, VER_MINOR, VER_PATCH,
- info->terms ? "n" : "ff");
+ p += sprintf(p, "v%s terminators o%s",
+ VERSION, info->terms ? "n" : "ff");
return string;
}
@@ -499,7 +364,7 @@ int cumanascsi_2_proc_info (char *buffer, char **start, off_t offset,
{
int pos, begin;
struct Scsi_Host *host;
- CumanaScsi2_Info *info;
+ struct cumanascsi2_info *info;
Scsi_Device *scd;
host = scsi_host_hn_get(host_no);
@@ -509,12 +374,12 @@ int cumanascsi_2_proc_info (char *buffer, char **start, off_t offset,
if (inout == 1)
return cumanascsi_2_set_proc_info(host, buffer, length);
- info = (CumanaScsi2_Info *)host->hostdata;
+ info = (struct cumanascsi2_info *)host->hostdata;
begin = 0;
pos = sprintf(buffer,
- "Cumana SCSI II driver version %d.%d.%d\n",
- VER_MAJOR, VER_MINOR, VER_PATCH);
+ "Cumana SCSI II driver version v%s\n",
+ VERSION);
pos += fas216_print_host(&info->info, buffer + pos);
pos += sprintf(buffer + pos, "Term : o%s\n",
@@ -556,35 +421,148 @@ static Scsi_Host_Template cumanascsi2_template = {
.module = THIS_MODULE,
.proc_info = cumanascsi_2_proc_info,
.name = "Cumana SCSI II",
- .detect = cumanascsi_2_detect,
- .release = cumanascsi_2_release,
.info = cumanascsi_2_info,
- .can_queue = 1,
- .this_id = 7,
- .sg_tablesize = SG_ALL,
- .cmd_per_lun = 1,
- .use_clustering = DISABLE_CLUSTERING,
.command = fas216_command,
.queuecommand = fas216_queue_command,
.eh_host_reset_handler = fas216_eh_host_reset,
.eh_bus_reset_handler = fas216_eh_bus_reset,
.eh_device_reset_handler = fas216_eh_device_reset,
.eh_abort_handler = fas216_eh_abort,
+ .can_queue = 1,
+ .this_id = 7,
+ .sg_tablesize = SG_ALL,
+ .cmd_per_lun = 1,
+ .use_clustering = DISABLE_CLUSTERING,
+ .proc_name = "cumanascsi2",
};
-static int __init cumanascsi2_init(void)
+static int __devinit
+cumanascsi2_probe(struct expansion_card *ec, const struct ecard_id *id)
{
- scsi_register_host(&cumanascsi2_template);
- if (cumanascsi2_template.present)
- return 0;
+ struct Scsi_Host *host;
+ struct cumanascsi2_info *info;
+ int ret = -ENOMEM;
+
+ host = scsi_register(&cumanascsi2_template, sizeof (struct cumanascsi2_info));
+ if (!host)
+ goto out;
+
+ host->io_port = ecard_address(ec, ECARD_MEMC, 0);
+ host->irq = ec->irq;
+ host->dma_channel = ec->dma;
+
+ if (!request_region(host->io_port + CUMANASCSI2_FAS216_OFFSET,
+ CUMANASCSI2_FAS216_SIZE, "cumanascsi2-fas")) {
+ ret = -EBUSY;
+ goto out_free;
+ }
+
+ ecard_set_drvdata(ec, host);
+
+ info = (struct cumanascsi2_info *)host->hostdata;
+ info->dmaarea = host->io_port + CUMANASCSI2_PSEUDODMA;
+ info->status = host->io_port + CUMANASCSI2_STATUS;
+ info->alatch = host->io_port + CUMANASCSI2_ALATCH;
+
+ ec->irqaddr = (unsigned char *)ioaddr(info->status);
+ ec->irqmask = STATUS_INT;
+ ec->irq_data = (void *)info->alatch;
+ ec->ops = (expansioncard_ops_t *)&cumanascsi_2_ops;
+
+ cumanascsi_2_terminator_ctl(host, term[ec->slot_no]);
+
+ info->info.scsi.io_port = host->io_port + CUMANASCSI2_FAS216_OFFSET;
+ info->info.scsi.io_shift = CUMANASCSI2_FAS216_SHIFT;
+ info->info.scsi.irq = host->irq;
+ info->info.ifcfg.clockrate = 40; /* MHz */
+ info->info.ifcfg.select_timeout = 255;
+ info->info.ifcfg.asyncperiod = 200; /* ns */
+ info->info.ifcfg.sync_max_depth = 7;
+ info->info.ifcfg.cntl3 = CNTL3_BS8 | CNTL3_FASTSCSI | CNTL3_FASTCLK;
+ info->info.ifcfg.disconnect_ok = 1;
+ info->info.ifcfg.wide_max_size = 0;
+ info->info.dma.setup = cumanascsi_2_dma_setup;
+ info->info.dma.pseudo = cumanascsi_2_dma_pseudo;
+ info->info.dma.stop = cumanascsi_2_dma_stop;
+
+ ret = request_irq(host->irq, cumanascsi_2_intr,
+ SA_INTERRUPT, "cumanascsi2", host);
+ if (ret) {
+ printk("scsi%d: IRQ%d not free: %d\n",
+ host->host_no, host->irq, ret);
+ goto out_region;
+ }
+
+ if (host->dma_channel != NO_DMA) {
+ if (request_dma(host->dma_channel, "cumanascsi2")) {
+ printk("scsi%d: DMA%d not free, using PIO\n",
+ host->host_no, host->dma_channel);
+ host->dma_channel = NO_DMA;
+ } else {
+ set_dma_speed(host->dma_channel, 180);
+ }
+ }
+
+ fas216_init(host);
+
+ ret = scsi_add_host(host);
+ if (ret == 0)
+ goto out;
- scsi_unregister_host(&cumanascsi2_template);
- return -ENODEV;
+ fas216_release(host);
+
+ if (host->dma_channel != NO_DMA)
+ free_dma(host->dma_channel);
+ free_irq(host->irq, host);
+ out_region:
+ release_region(host->io_port + CUMANASCSI2_FAS216_OFFSET,
+ CUMANASCSI2_FAS216_SIZE);
+ out_free:
+ scsi_unregister(host);
+
+ out:
+ return ret;
+}
+
+static void __devexit cumanascsi2_remove(struct expansion_card *ec)
+{
+ struct Scsi_Host *host = ecard_get_drvdata(ec);
+
+ ecard_set_drvdata(ec, NULL);
+ scsi_remove_host(host);
+ fas216_release(host);
+
+ if (host->dma_channel != NO_DMA)
+ free_dma(host->dma_channel);
+ free_irq(host->irq, host);
+ release_region(host->io_port + CUMANASCSI2_FAS216_OFFSET,
+ CUMANASCSI2_FAS216_SIZE);
+
+ scsi_unregister(host);
+}
+
+static const struct ecard_id cumanascsi2_cids[] = {
+ { MANU_CUMANA, PROD_CUMANA_SCSI_2 },
+ { 0xffff, 0xffff },
+};
+
+static struct ecard_driver cumanascsi2_driver = {
+ .probe = cumanascsi2_probe,
+ .remove = __devexit_p(cumanascsi2_remove),
+ .id_table = cumanascsi2_cids,
+ .drv = {
+ .name = "cumanascsi2",
+ },
+};
+
+static int __init cumanascsi2_init(void)
+{
+ return ecard_register_driver(&cumanascsi2_driver);
}
static void __exit cumanascsi2_exit(void)
{
- scsi_unregister_host(&cumanascsi2_template);
+ ecard_remove_driver(&cumanascsi2_driver);
}
module_init(cumanascsi2_init);
@@ -595,4 +573,3 @@ MODULE_DESCRIPTION("Cumana SCSI-2 driver for Acorn machines");
MODULE_PARM(term, "1-8i");
MODULE_PARM_DESC(term, "SCSI bus termination");
MODULE_LICENSE("GPL");
-
diff --git a/drivers/acorn/scsi/ecoscsi.c b/drivers/acorn/scsi/ecoscsi.c
index 9a8e70376295..e1fe32536477 100644
--- a/drivers/acorn/scsi/ecoscsi.c
+++ b/drivers/acorn/scsi/ecoscsi.c
@@ -45,6 +45,7 @@
#include <linux/signal.h>
#include <linux/sched.h>
#include <linux/ioport.h>
+#include <linux/delay.h>
#include <linux/init.h>
#include <linux/blk.h>
diff --git a/drivers/acorn/scsi/eesox.c b/drivers/acorn/scsi/eesox.c
index 047e8db0431d..dc1da2c312bc 100644
--- a/drivers/acorn/scsi/eesox.c
+++ b/drivers/acorn/scsi/eesox.c
@@ -1,7 +1,7 @@
/*
* linux/drivers/acorn/scsi/eesox.c
*
- * Copyright (C) 1997-2000 Russell King
+ * Copyright (C) 1997-2002 Russell King
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -48,18 +48,9 @@
#include <scsi/scsicam.h>
-/* Configuration */
-#define EESOX_XTALFREQ 40
-#define EESOX_ASYNC_PERIOD 200
-#define EESOX_SYNC_DEPTH 7
-
-/*
- * List of devices that the driver will recognise
- */
-#define EESOXSCSI_LIST { MANU_EESOX, PROD_EESOX_SCSI2 }
-
#define EESOX_FAS216_OFFSET 0xc00
#define EESOX_FAS216_SHIFT 3
+#define EESOX_FAS216_SIZE (16 << EESOX_FAS216_SHIFT)
#define EESOX_STATUS 0xa00
#define EESOX_STAT_INTR 0x01
@@ -75,11 +66,7 @@
/*
* Version
*/
-#define VER_MAJOR 0
-#define VER_MINOR 0
-#define VER_PATCH 3
-
-static struct expansion_card *ecs[MAX_ECARDS];
+#define VERSION "1.00 (13/11/2002 2.5.47)"
/*
* Use term=0,1,0,0,0 to turn terminators on/off
@@ -88,19 +75,14 @@ static int term[MAX_ECARDS] = { 1, 1, 1, 1, 1, 1, 1, 1 };
#define NR_SG 256
-struct control {
- unsigned int io_port;
- unsigned int control;
-};
-
-typedef struct {
+struct eesoxscsi_info {
FAS216_Info info;
- struct control control;
-
+ unsigned int ctl_port;
+ unsigned int control;
unsigned int dmaarea; /* Pseudo DMA area */
struct scatterlist sg[NR_SG]; /* Scatter DMA list */
-} EESOXScsi_Info;
+};
/* Prototype: void eesoxscsi_irqenable(ec, irqnr)
* Purpose : Enable interrupts on EESOX SCSI card
@@ -110,11 +92,11 @@ typedef struct {
static void
eesoxscsi_irqenable(struct expansion_card *ec, int irqnr)
{
- struct control *control = (struct control *)ec->irq_data;
+ struct eesoxscsi_info *info = (struct eesoxscsi_info *)ec->irq_data;
- control->control |= EESOX_INTR_ENABLE;
+ info->control |= EESOX_INTR_ENABLE;
- outb(control->control, control->io_port);
+ outb(info->control, info->ctl_port);
}
/* Prototype: void eesoxscsi_irqdisable(ec, irqnr)
@@ -125,20 +107,16 @@ eesoxscsi_irqenable(struct expansion_card *ec, int irqnr)
static void
eesoxscsi_irqdisable(struct expansion_card *ec, int irqnr)
{
- struct control *control = (struct control *)ec->irq_data;
+ struct eesoxscsi_info *info = (struct eesoxscsi_info *)ec->irq_data;
- control->control &= ~EESOX_INTR_ENABLE;
+ info->control &= ~EESOX_INTR_ENABLE;
- outb(control->control, control->io_port);
+ outb(info->control, info->ctl_port);
}
static const expansioncard_ops_t eesoxscsi_ops = {
- eesoxscsi_irqenable,
- eesoxscsi_irqdisable,
- NULL,
- NULL,
- NULL,
- NULL
+ .irqenable = eesoxscsi_irqenable,
+ .irqdisable = eesoxscsi_irqdisable,
};
/* Prototype: void eesoxscsi_terminator_ctl(*host, on_off)
@@ -149,16 +127,16 @@ static const expansioncard_ops_t eesoxscsi_ops = {
static void
eesoxscsi_terminator_ctl(struct Scsi_Host *host, int on_off)
{
- EESOXScsi_Info *info = (EESOXScsi_Info *)host->hostdata;
+ struct eesoxscsi_info *info = (struct eesoxscsi_info *)host->hostdata;
unsigned long flags;
spin_lock_irqsave(host->host_lock, flags);
if (on_off)
- info->control.control |= EESOX_TERM_ENABLE;
+ info->control |= EESOX_TERM_ENABLE;
else
- info->control.control &= ~EESOX_TERM_ENABLE;
+ info->control &= ~EESOX_TERM_ENABLE;
- outb(info->control.control, info->control.io_port);
+ outb(info->control, info->ctl_port);
spin_unlock_irqrestore(host->host_lock, flags);
}
@@ -188,7 +166,7 @@ static fasdmatype_t
eesoxscsi_dma_setup(struct Scsi_Host *host, Scsi_Pointer *SCp,
fasdmadir_t direction, fasdmatype_t min_type)
{
- EESOXScsi_Info *info = (EESOXScsi_Info *)host->hostdata;
+ struct eesoxscsi_info *info = (struct eesoxscsi_info *)host->hostdata;
int dmach = host->dma_channel;
if (dmach != NO_DMA &&
@@ -224,7 +202,7 @@ static void
eesoxscsi_dma_pseudo(struct Scsi_Host *host, Scsi_Pointer *SCp,
fasdmadir_t dir, int transfer_size)
{
- EESOXScsi_Info *info = (EESOXScsi_Info *)host->hostdata;
+ struct eesoxscsi_info *info = (struct eesoxscsi_info *)host->hostdata;
unsigned int status;
unsigned int length = SCp->this_residual;
union {
@@ -321,116 +299,6 @@ eesoxscsi_dma_stop(struct Scsi_Host *host, Scsi_Pointer *SCp)
disable_dma(host->dma_channel);
}
-/* Prototype: int eesoxscsi_detect(Scsi_Host_Template * tpnt)
- * Purpose : initialises EESOX SCSI driver
- * Params : tpnt - template for this SCSI adapter
- * Returns : >0 if host found, 0 otherwise.
- */
-int
-eesoxscsi_detect(Scsi_Host_Template *tpnt)
-{
- static const card_ids eesoxscsi_cids[] =
- { EESOXSCSI_LIST, { 0xffff, 0xffff} };
- int count = 0;
- struct Scsi_Host *host;
-
- tpnt->proc_name = "eesox";
- memset(ecs, 0, sizeof (ecs));
-
- ecard_startfind();
-
- while(1) {
- EESOXScsi_Info *info;
-
- ecs[count] = ecard_find(0, eesoxscsi_cids);
- if (!ecs[count])
- break;
-
- ecard_claim(ecs[count]);
-
- host = scsi_register(tpnt, sizeof (EESOXScsi_Info));
- if (!host) {
- ecard_release(ecs[count]);
- break;
- }
-
- host->io_port = ecard_address(ecs[count], ECARD_IOC, ECARD_FAST);
- host->irq = ecs[count]->irq;
- host->dma_channel = ecs[count]->dma;
- info = (EESOXScsi_Info *)host->hostdata;
-
- info->control.io_port = host->io_port + EESOX_CONTROL;
- info->control.control = term[count] ? EESOX_TERM_ENABLE : 0;
- outb(info->control.control, info->control.io_port);
-
- ecs[count]->irqaddr = (unsigned char *)
- ioaddr(host->io_port + EESOX_STATUS);
- ecs[count]->irqmask = EESOX_STAT_INTR;
- ecs[count]->irq_data = &info->control;
- ecs[count]->ops = (expansioncard_ops_t *)&eesoxscsi_ops;
-
- info->info.scsi.io_port = host->io_port + EESOX_FAS216_OFFSET;
- info->info.scsi.io_shift = EESOX_FAS216_SHIFT;
- info->info.scsi.irq = host->irq;
- info->info.ifcfg.clockrate = EESOX_XTALFREQ;
- info->info.ifcfg.select_timeout = 255;
- info->info.ifcfg.asyncperiod = EESOX_ASYNC_PERIOD;
- info->info.ifcfg.sync_max_depth = EESOX_SYNC_DEPTH;
- info->info.ifcfg.cntl3 = CNTL3_BS8 | CNTL3_FASTSCSI | CNTL3_FASTCLK;
- info->info.ifcfg.disconnect_ok = 1;
- info->info.ifcfg.wide_max_size = 0;
- info->info.dma.setup = eesoxscsi_dma_setup;
- info->info.dma.pseudo = eesoxscsi_dma_pseudo;
- info->info.dma.stop = eesoxscsi_dma_stop;
- info->dmaarea = host->io_port + EESOX_DMA_OFFSET;
-
- request_region(host->io_port + EESOX_FAS216_OFFSET,
- 16 << EESOX_FAS216_SHIFT, "eesox2-fas");
-
- if (host->irq != NO_IRQ &&
- request_irq(host->irq, eesoxscsi_intr,
- SA_INTERRUPT, "eesox", host)) {
- printk("scsi%d: IRQ%d not free, interrupts disabled\n",
- host->host_no, host->irq);
- host->irq = NO_IRQ;
- }
-
- if (host->dma_channel != NO_DMA &&
- request_dma(host->dma_channel, "eesox")) {
- printk("scsi%d: DMA%d not free, DMA disabled\n",
- host->host_no, host->dma_channel);
- host->dma_channel = NO_DMA;
- }
-
- fas216_init(host);
- ++count;
- }
- return count;
-}
-
-/* Prototype: int eesoxscsi_release(struct Scsi_Host * host)
- * Purpose : releases all resources used by this adapter
- * Params : host - driver host structure to return info for.
- */
-int eesoxscsi_release(struct Scsi_Host *host)
-{
- int i;
-
- fas216_release(host);
-
- if (host->irq != NO_IRQ)
- free_irq(host->irq, host);
- if (host->dma_channel != NO_DMA)
- free_dma(host->dma_channel);
- release_region(host->io_port + EESOX_FAS216_OFFSET, 16 << EESOX_FAS216_SHIFT);
-
- for (i = 0; i < MAX_ECARDS; i++)
- if (ecs[i] &&
- host->io_port == ecard_address(ecs[i], ECARD_IOC, ECARD_FAST))
- ecard_release(ecs[i]);
- return 0;
-}
-
/* Prototype: const char *eesoxscsi_info(struct Scsi_Host * host)
* Purpose : returns a descriptive string about this interface,
* Params : host - driver host structure to return info for.
@@ -438,15 +306,15 @@ int eesoxscsi_release(struct Scsi_Host *host)
*/
const char *eesoxscsi_info(struct Scsi_Host *host)
{
- EESOXScsi_Info *info = (EESOXScsi_Info *)host->hostdata;
+ struct eesoxscsi_info *info = (struct eesoxscsi_info *)host->hostdata;
static char string[100], *p;
p = string;
p += sprintf(p, "%s ", host->hostt->name);
p += fas216_info(&info->info, p);
- p += sprintf(p, "v%d.%d.%d terminators o%s",
- VER_MAJOR, VER_MINOR, VER_PATCH,
- info->control.control & EESOX_TERM_ENABLE ? "n" : "ff");
+ p += sprintf(p, "v%s terminators o%s",
+ VERSION,
+ info->control & EESOX_TERM_ENABLE ? "n" : "ff");
return string;
}
@@ -500,7 +368,7 @@ int eesoxscsi_proc_info(char *buffer, char **start, off_t offset,
{
int pos, begin;
struct Scsi_Host *host;
- EESOXScsi_Info *info;
+ struct eesoxscsi_info *info;
Scsi_Device *scd;
host = scsi_host_hn_get(host_no);
@@ -510,28 +378,28 @@ int eesoxscsi_proc_info(char *buffer, char **start, off_t offset,
if (inout == 1)
return eesoxscsi_set_proc_info(host, buffer, length);
- info = (EESOXScsi_Info *)host->hostdata;
+ info = (struct eesoxscsi_info *)host->hostdata;
begin = 0;
pos = sprintf(buffer,
- "EESOX SCSI driver version %d.%d.%d\n",
- VER_MAJOR, VER_MINOR, VER_PATCH);
+ "EESOX SCSI driver version v%s\n",
+ VERSION);
pos += fas216_print_host(&info->info, buffer + pos);
pos += sprintf(buffer + pos, "Term : o%s\n",
- info->control.control & EESOX_TERM_ENABLE ? "n" : "ff");
+ info->control & EESOX_TERM_ENABLE ? "n" : "ff");
pos += fas216_print_stats(&info->info, buffer + pos);
- pos += sprintf (buffer+pos, "\nAttached devices:\n");
+ pos += sprintf(buffer+pos, "\nAttached devices:\n");
for (scd = host->host_queue; scd; scd = scd->next) {
int len;
- proc_print_scsidevice (scd, buffer, &len, pos);
+ proc_print_scsidevice(scd, buffer, &len, pos);
pos += len;
- pos += sprintf (buffer+pos, "Extensions: ");
+ pos += sprintf(buffer+pos, "Extensions: ");
if (scd->tagged_supported)
- pos += sprintf (buffer+pos, "TAG %sabled [%d] ",
+ pos += sprintf(buffer+pos, "TAG %sabled [%d] ",
scd->tagged_queue ? "en" : "dis",
scd->current_tag);
pos += sprintf (buffer+pos, "\n");
@@ -553,35 +421,144 @@ static Scsi_Host_Template eesox_template = {
.module = THIS_MODULE,
.proc_info = eesoxscsi_proc_info,
.name = "EESOX SCSI",
- .detect = eesoxscsi_detect,
- .release = eesoxscsi_release,
.info = eesoxscsi_info,
- .can_queue = 1,
- .this_id = 7,
- .sg_tablesize = SG_ALL,
- .cmd_per_lun = 1,
- .use_clustering = DISABLE_CLUSTERING,
.command = fas216_command,
.queuecommand = fas216_queue_command,
.eh_host_reset_handler = fas216_eh_host_reset,
.eh_bus_reset_handler = fas216_eh_bus_reset,
.eh_device_reset_handler = fas216_eh_device_reset,
.eh_abort_handler = fas216_eh_abort,
+ .can_queue = 1,
+ .this_id = 7,
+ .sg_tablesize = SG_ALL,
+ .cmd_per_lun = 1,
+ .use_clustering = DISABLE_CLUSTERING,
+ .proc_name = "eesox",
};
-static int __init eesox_init(void)
+static int __devinit
+eesoxscsi_probe(struct expansion_card *ec, const struct ecard_id *id)
{
- scsi_register_host(&eesox_template);
- if (eesox_template.present)
- return 0;
+ struct Scsi_Host *host;
+ struct eesoxscsi_info *info;
+ int ret = -ENOMEM;
+
+ host = scsi_register(&eesox_template,
+ sizeof(struct eesoxscsi_info));
+ if (!host)
+ goto out;
+
+ host->io_port = ecard_address(ec, ECARD_IOC, ECARD_FAST);
+ host->irq = ec->irq;
+ host->dma_channel = ec->dma;
+
+ if (!request_region(host->io_port + EESOX_FAS216_OFFSET,
+ EESOX_FAS216_SIZE, "eesox2-fas")) {
+ ret = -EBUSY;
+ goto out_free;
+ }
+
+ ecard_set_drvdata(ec, host);
+
+ info = (struct eesoxscsi_info *)host->hostdata;
+ info->ctl_port = host->io_port + EESOX_CONTROL;
+ info->control = term[ec->slot_no] ? EESOX_TERM_ENABLE : 0;
+ outb(info->control, info->ctl_port);
+
+ ec->irqaddr = (unsigned char *)ioaddr(host->io_port + EESOX_STATUS);
+ ec->irqmask = EESOX_STAT_INTR;
+ ec->irq_data = info;
+ ec->ops = (expansioncard_ops_t *)&eesoxscsi_ops;
+
+ info->info.scsi.io_port = host->io_port + EESOX_FAS216_OFFSET;
+ info->info.scsi.io_shift = EESOX_FAS216_SHIFT;
+ info->info.scsi.irq = host->irq;
+ info->info.ifcfg.clockrate = 40; /* MHz */
+ info->info.ifcfg.select_timeout = 255;
+ info->info.ifcfg.asyncperiod = 200; /* ns */
+ info->info.ifcfg.sync_max_depth = 7;
+ info->info.ifcfg.cntl3 = CNTL3_BS8 | CNTL3_FASTSCSI | CNTL3_FASTCLK;
+ info->info.ifcfg.disconnect_ok = 1;
+ info->info.ifcfg.wide_max_size = 0;
+ info->info.dma.setup = eesoxscsi_dma_setup;
+ info->info.dma.pseudo = eesoxscsi_dma_pseudo;
+ info->info.dma.stop = eesoxscsi_dma_stop;
+ info->dmaarea = host->io_port + EESOX_DMA_OFFSET;
+
+ ret = request_irq(host->irq, eesoxscsi_intr,
+ SA_INTERRUPT, "eesox", host);
+ if (ret) {
+ printk("scsi%d: IRQ%d not free: %d\n",
+ host->host_no, host->irq, ret);
+ goto out_region;
+ }
+
+ if (host->dma_channel != NO_DMA) {
+ if (request_dma(host->dma_channel, "eesox")) {
+ printk("scsi%d: DMA%d not free, DMA disabled\n",
+ host->host_no, host->dma_channel);
+ host->dma_channel = NO_DMA;
+ } else {
+ set_dma_speed(host->dma_channel, 180);
+ }
+ }
- scsi_unregister_host(&eesox_template);
- return -ENODEV;
+ fas216_init(host);
+ ret = scsi_add_host(host);
+ if (ret == 0)
+ goto out;
+
+ fas216_release(host);
+
+ if (host->dma_channel != NO_DMA)
+ free_dma(host->dma_channel);
+ free_irq(host->irq, host);
+ out_region:
+ release_region(host->io_port + EESOX_FAS216_OFFSET,
+ EESOX_FAS216_SIZE);
+ out_free:
+ scsi_unregister(host);
+ out:
+ return ret;
+}
+
+static void __devexit eesoxscsi_remove(struct expansion_card *ec)
+{
+ struct Scsi_Host *host = ecard_get_drvdata(ec);
+
+ ecard_set_drvdata(ec, NULL);
+ scsi_remove_host(host);
+ fas216_release(host);
+
+ if (host->dma_channel != NO_DMA)
+ free_dma(host->dma_channel);
+ free_irq(host->irq, host);
+ release_region(host->io_port + EESOX_FAS216_OFFSET, EESOX_FAS216_SIZE);
+ scsi_unregister(host);
+}
+
+static const struct ecard_id eesoxscsi_cids[] = {
+ { MANU_EESOX, PROD_EESOX_SCSI2 },
+ { 0xffff, 0xffff },
+};
+
+static struct ecard_driver eesoxscsi_driver = {
+ .probe = eesoxscsi_probe,
+ .remove = __devexit_p(eesoxscsi_remove),
+ .id_table = eesoxscsi_cids,
+ .drv = {
+ .name = "eesoxscsi",
+ },
+};
+
+static int __init eesox_init(void)
+{
+ return ecard_register_driver(&eesoxscsi_driver);
}
static void __exit eesox_exit(void)
{
- scsi_unregister_host(&eesox_template);
+ ecard_remove_driver(&eesoxscsi_driver);
}
module_init(eesox_init);
diff --git a/drivers/acorn/scsi/fas216.c b/drivers/acorn/scsi/fas216.c
index 77bd624a7b95..158f1be92658 100644
--- a/drivers/acorn/scsi/fas216.c
+++ b/drivers/acorn/scsi/fas216.c
@@ -93,14 +93,18 @@
#undef SCSI2_TAG
#undef DEBUG_CONNECT
-#undef DEBUG_BUSSERVICE
-#undef DEBUG_FUNCTIONDONE
#undef DEBUG_MESSAGES
#undef CHECK_STRUCTURE
-static struct { int stat, ssr, isr, ph; } list[8];
-static int ptr;
+#define LOG_CONNECT (1 << 0)
+#define LOG_BUSSERVICE (1 << 1)
+#define LOG_FUNCTIONDONE (1 << 2)
+#define LOG_MESSAGES (1 << 3)
+#define LOG_BUFFER (1 << 4)
+#define LOG_ERROR (1 << 8)
+
+static int level_mask = LOG_ERROR;
static void fas216_dumpstate(FAS216_Info *info)
{
@@ -120,6 +124,13 @@ static void fas216_dumpstate(FAS216_Info *info)
inb(REG_CNTL3(info)), inb(REG_CTCH(info)));
}
+static void print_SCp(Scsi_Pointer *SCp, const char *prefix, const char *suffix)
+{
+ printk("%sptr %p this_residual 0x%x buffer %p buffers_residual 0x%x%s",
+ prefix, SCp->ptr, SCp->this_residual, SCp->buffer,
+ SCp->buffers_residual, suffix);
+}
+
static void fas216_dumpinfo(FAS216_Info *info)
{
static int used = 0;
@@ -140,9 +151,7 @@ static void fas216_dumpinfo(FAS216_Info *info)
info->scsi.type, info->scsi.phase,
info->scsi.reconnected.target,
info->scsi.reconnected.lun, info->scsi.reconnected.tag);
- printk(" SCp={ ptr=%p this_residual=%X buffer=%p buffers_residual=%X }\n",
- info->scsi.SCp.ptr, info->scsi.SCp.this_residual,
- info->scsi.SCp.buffer, info->scsi.SCp.buffers_residual);
+ print_SCp(&info->scsi.SCp, " SCp={ ", " }\n");
printk(" msgs async_stp=%X disconnectable=%d aborting=%d }\n",
info->scsi.async_stp,
info->scsi.disconnectable, info->scsi.aborting);
@@ -156,7 +165,7 @@ static void fas216_dumpinfo(FAS216_Info *info)
info->ifcfg.clockrate, info->ifcfg.select_timeout,
info->ifcfg.asyncperiod, info->ifcfg.sync_max_depth);
for (i = 0; i < 8; i++) {
- printk(" busyluns[%d]=%X dev[%d]={ disconnect_ok=%d stp=%X sof=%X sync_state=%X }\n",
+ printk(" busyluns[%d]=%08lx dev[%d]={ disconnect_ok=%d stp=%X sof=%X sync_state=%X }\n",
i, info->busyluns[i], i,
info->device[i].disconnect_ok, info->device[i].stp,
info->device[i].sof, info->device[i].sync_state);
@@ -229,29 +238,73 @@ static char fas216_target(FAS216_Info *info)
return 'H';
}
+static void fas216_log(FAS216_Info *info, int level, char *fmt, ...)
+{
+ va_list args;
+ static char buf[1024];
+
+ if (level != 0 && !(level & level_mask))
+ return;
+
+ va_start(args, fmt);
+ vsnprintf(buf, sizeof(buf), fmt, args);
+ va_end(args);
+
+ printk("scsi%d.%c: %s\n", info->host->host_no, fas216_target(info), buf);
+}
+
+#define PH_SIZE 32
+
+static struct { int stat, ssr, isr, ph; } ph_list[PH_SIZE];
+static int ph_ptr;
+
static void add_debug_list(int stat, int ssr, int isr, int ph)
{
- list[ptr].stat = stat;
- list[ptr].ssr = ssr;
- list[ptr].isr = isr;
- list[ptr].ph = ph;
+ ph_list[ph_ptr].stat = stat;
+ ph_list[ph_ptr].ssr = ssr;
+ ph_list[ph_ptr].isr = isr;
+ ph_list[ph_ptr].ph = ph;
- ptr = (ptr + 1) & 7;
+ ph_ptr = (ph_ptr + 1) & (PH_SIZE-1);
+}
+
+static struct { int command; void *from; } cmd_list[8];
+static int cmd_ptr;
+
+static void fas216_cmd(FAS216_Info *info, unsigned int command)
+{
+ cmd_list[cmd_ptr].command = command;
+ cmd_list[cmd_ptr].from = __builtin_return_address(0);
+
+ cmd_ptr = (cmd_ptr + 1) & 7;
+
+ outb(command, REG_CMD(info));
}
static void print_debug_list(void)
{
int i;
- i = ptr;
+ i = ph_ptr;
- printk(KERN_ERR "SCSI IRQ trail: ");
+ printk(KERN_ERR "SCSI IRQ trail\n");
do {
- printk("%02X:%02X:%02X:%1X ",
- list[i].stat, list[i].ssr,
- list[i].isr, list[i].ph);
+ printk(" %02x:%02x:%02x:%1x",
+ ph_list[i].stat, ph_list[i].ssr,
+ ph_list[i].isr, ph_list[i].ph);
+ i = (i + 1) & (PH_SIZE - 1);
+ if (((i ^ ph_ptr) & 7) == 0)
+ printk("\n");
+ } while (i != ph_ptr);
+ if ((i ^ ph_ptr) & 7)
+ printk("\n");
+
+ i = cmd_ptr;
+ printk(KERN_ERR "FAS216 commands: ");
+ do {
+ printk("%02x:%p ", cmd_list[i].command, cmd_list[i].from);
i = (i + 1) & 7;
- } while (i != ptr);
+ } while (i != cmd_ptr);
printk("\n");
}
@@ -299,10 +352,9 @@ fas216_get_last_msg(FAS216_Info *info, int pos)
packed_msg = msg->msg[0];
}
-#ifdef DEBUG_MESSAGES
- printk("Message: %04X found at position %02X\n",
- packed_msg, pos);
-#endif
+ fas216_log(info, LOG_MESSAGES,
+ "Message: %04x found at position %02x\n", packed_msg, pos);
+
return packed_msg;
}
@@ -313,8 +365,7 @@ fas216_get_last_msg(FAS216_Info *info, int pos)
* : ns - period in ns (between subsequent bytes)
* Returns : Value suitable for REG_STP
*/
-static int
-fas216_syncperiod(FAS216_Info *info, int ns)
+static int fas216_syncperiod(FAS216_Info *info, int ns)
{
int value = (info->ifcfg.clockrate * ns) / 1000;
@@ -336,8 +387,7 @@ fas216_syncperiod(FAS216_Info *info, int ns)
* a transfer period >= 200ns - otherwise the chip will violate
* the SCSI timings.
*/
-static void
-fas216_set_sync(FAS216_Info *info, int target)
+static void fas216_set_sync(FAS216_Info *info, int target)
{
outb(info->device[target].sof, REG_SOF(info));
outb(info->device[target].stp, REG_STP(info));
@@ -365,9 +415,9 @@ fas216_set_sync(FAS216_Info *info, int target)
* Using the correct method assures compatibility with wide data
* transfers and future enhancements.
*
- * We will always initiate a synchronous transfer negociation request on
+ * We will always initiate a synchronous transfer negotiation request on
* every INQUIRY or REQUEST SENSE message, unless the target itself has
- * at some point performed a synchronous transfer negociation request, or
+ * at some point performed a synchronous transfer negotiation request, or
* we have synchronous transfers disabled for this device.
*/
@@ -376,8 +426,7 @@ fas216_set_sync(FAS216_Info *info, int target)
* Params : info - state structure for interface
* : msg - message from target
*/
-static void
-fas216_handlesync(FAS216_Info *info, char *msg)
+static void fas216_handlesync(FAS216_Info *info, char *msg)
{
struct fas216_device *dev = &info->device[info->SCpnt->target];
enum { sync, async, none, reject } res = none;
@@ -393,7 +442,7 @@ fas216_handlesync(FAS216_Info *info, char *msg)
* message with a MESSAGE REJECT message.
*
* Hence, if we get this condition, we disable
- * negociation for this device.
+ * negotiation for this device.
*/
if (dev->sync_state == neg_inprogress) {
dev->sync_state = neg_invalid;
@@ -411,14 +460,14 @@ fas216_handlesync(FAS216_Info *info, char *msg)
res = reject;
break;
- /* We were not negociating a synchronous transfer,
- * but the device sent us a negociation request.
+ /* We were not negotiating a synchronous transfer,
+ * but the device sent us a negotiation request.
* Honour the request by sending back a SDTR
* message containing our capability, limited by
* the targets capability.
*/
default:
- outb(CMD_SETATN, REG_CMD(info));
+ fas216_cmd(info, CMD_SETATN);
if (msg[4] > info->ifcfg.sync_max_depth)
msg[4] = info->ifcfg.sync_max_depth;
if (msg[3] < 1000 / info->ifcfg.clockrate)
@@ -437,7 +486,7 @@ fas216_handlesync(FAS216_Info *info, char *msg)
res = sync;
break;
- /* We initiated the synchronous transfer negociation,
+ /* We initiated the synchronous transfer negotiation,
* and have successfully received a response from the
* target. The synchronous transfer agreement has been
* reached. Note: if the values returned are out of our
@@ -466,7 +515,7 @@ fas216_handlesync(FAS216_Info *info, char *msg)
break;
case reject:
- outb(CMD_SETATN, REG_CMD(info));
+ fas216_cmd(info, CMD_SETATN);
msgqueue_flush(&info->scsi.msgs);
msgqueue_addmsg(&info->scsi.msgs, 1, MESSAGE_REJECT);
info->scsi.phase = PHASE_MSGOUT_EXPECT;
@@ -488,8 +537,7 @@ fas216_handlesync(FAS216_Info *info, char *msg)
* Params : info - state structure for interface
* : msg - message from target
*/
-static void
-fas216_handlewide(FAS216_Info *info, char *msg)
+static void fas216_handlewide(FAS216_Info *info, char *msg)
{
struct fas216_device *dev = &info->device[info->SCpnt->target];
enum { wide, bit8, none, reject } res = none;
@@ -505,7 +553,7 @@ fas216_handlewide(FAS216_Info *info, char *msg)
* WDTR message with a MESSAGE REJECT message.
*
* Hence, if we get this condition, we never
- * reattempt negociation for this device.
+ * reattempt negotiation for this device.
*/
if (dev->wide_state == neg_inprogress) {
dev->wide_state = neg_invalid;
@@ -523,14 +571,14 @@ fas216_handlewide(FAS216_Info *info, char *msg)
res = reject;
break;
- /* We were not negociating a wide data transfer,
- * but the device sent is a negociation request.
+ /* We were not negotiating a wide data transfer,
+ * but the device sent is a negotiation request.
* Honour the request by sending back a WDTR
* message containing our capability, limited by
* the targets capability.
*/
default:
- outb(CMD_SETATN, REG_CMD(info));
+ fas216_cmd(info, CMD_SETATN);
if (msg[3] > info->ifcfg.wide_max_size)
msg[3] = info->ifcfg.wide_max_size;
@@ -542,7 +590,7 @@ fas216_handlewide(FAS216_Info *info, char *msg)
res = wide;
break;
- /* We initiated the wide data transfer negociation,
+ /* We initiated the wide data transfer negotiation,
* and have successfully received a response from the
* target. The synchronous transfer agreement has been
* reached. Note: if the values returned are out of our
@@ -567,7 +615,7 @@ fas216_handlewide(FAS216_Info *info, char *msg)
break;
case reject:
- outb(CMD_SETATN, REG_CMD(info));
+ fas216_cmd(info, CMD_SETATN);
msgqueue_flush(&info->scsi.msgs);
msgqueue_addmsg(&info->scsi.msgs, 1, MESSAGE_REJECT);
info->scsi.phase = PHASE_MSGOUT_EXPECT;
@@ -586,13 +634,14 @@ fas216_handlewide(FAS216_Info *info, char *msg)
* Params : info - interface's local pointer to update
* bytes_transferred - number of bytes transferred
*/
-static void
-fas216_updateptrs(FAS216_Info *info, int bytes_transferred)
+static void fas216_updateptrs(FAS216_Info *info, int bytes_transferred)
{
Scsi_Pointer *SCp = &info->scsi.SCp;
fas216_checkmagic(info);
+ BUG_ON(bytes_transferred < 0);
+
info->SCpnt->request_bufflen -= bytes_transferred;
while (bytes_transferred != 0) {
@@ -623,8 +672,7 @@ fas216_updateptrs(FAS216_Info *info, int bytes_transferred)
* direction - direction to transfer data (DMA_OUT/DMA_IN)
* Notes : this is incredibly slow
*/
-static void
-fas216_pio(FAS216_Info *info, fasdmadir_t direction)
+static void fas216_pio(FAS216_Info *info, fasdmadir_t direction)
{
fas216_checkmagic(info);
@@ -634,53 +682,94 @@ fas216_pio(FAS216_Info *info, fasdmadir_t direction)
put_next_SCp_byte(&info->scsi.SCp, inb(REG_FF(info)));
}
+static void fas216_cleanuptransfer(FAS216_Info *info)
+{
+ unsigned long total, residual, fifo;
+
+ if (info->dma.transfer_type == fasdma_real_all)
+ total = info->SCpnt->request_bufflen;
+ else
+ total = info->scsi.SCp.this_residual;
+
+ residual = inb(REG_CTCL(info)) + (inb(REG_CTCM(info)) << 8) +
+ (inb(REG_CTCH(info)) << 16);
+
+ fifo = inb(REG_CFIS(info)) & CFIS_CF;
+
+ fas216_log(info, LOG_BUFFER, "cleaning up from previous "
+ "transfer: length 0x%06x, residual 0x%x, fifo %d",
+ total, residual, fifo);
+
+ /*
+ * If we were performing Data-Out, the transfer counter
+ * counts down each time a byte is transferred by the
+ * host to the FIFO. This means we must include the
+ * bytes left in the FIFO from the transfer counter.
+ */
+ if (info->scsi.phase == PHASE_DATAOUT) {
+ residual += fifo;
+ fifo = 0;
+ }
+
+ if (info->dma.transfer_type != fasdma_none &&
+ info->dma.transfer_type != fasdma_pio) {
+ fas216_updateptrs(info, total - residual);
+ }
+
+ /*
+ * If we were performing Data-In, then the FIFO counter
+ * contains the number of bytes not transferred via DMA
+ * from the on-board FIFO. Read them manually.
+ */
+ if (info->scsi.phase == PHASE_DATAIN) {
+ while (fifo && info->scsi.SCp.ptr) {
+ *info->scsi.SCp.ptr = inb(REG_FF(info));
+ fas216_updateptrs(info, 1);
+ fifo--;
+ }
+ }
+
+ info->dma.transfer_type = fasdma_none;
+}
+
/* Function: void fas216_starttransfer(FAS216_Info *info,
* fasdmadir_t direction)
* Purpose : Start a DMA/PIO transfer off of/on to card
* Params : info - interface from which device disconnected from
* direction - transfer direction (DMA_OUT/DMA_IN)
*/
-static void
-fas216_starttransfer(FAS216_Info *info, fasdmadir_t direction, int flush_fifo)
+static void fas216_starttransfer(FAS216_Info *info, fasdmadir_t direction)
{
fasdmatype_t dmatype;
+ int phase = (direction == DMA_OUT) ? PHASE_DATAOUT : PHASE_DATAIN;
fas216_checkmagic(info);
- info->scsi.phase = (direction == DMA_OUT) ?
- PHASE_DATAOUT : PHASE_DATAIN;
-
- if (info->dma.transfer_type != fasdma_none &&
- info->dma.transfer_type != fasdma_pio) {
- unsigned long total, residual;
+ if (phase != info->scsi.phase) {
+ info->scsi.phase = phase;
- if (info->dma.transfer_type == fasdma_real_all)
- total = info->SCpnt->request_bufflen;
- else
- total = info->scsi.SCp.this_residual;
-
- residual = (inb(REG_CFIS(info)) & CFIS_CF) +
- inb(REG_CTCL(info)) +
- (inb(REG_CTCM(info)) << 8) +
- (inb(REG_CTCH(info)) << 16);
- fas216_updateptrs(info, total - residual);
+ if (direction == DMA_OUT)
+ fas216_cmd(info, CMD_FLUSHFIFO);
+ } else {
+ fas216_cleanuptransfer(info);
}
- info->dma.transfer_type = fasdma_none;
+
+ fas216_log(info, LOG_BUFFER,
+ "starttransfer: buffer %p length 0x%06x reqlen 0x%06x",
+ info->scsi.SCp.ptr, info->scsi.SCp.this_residual,
+ info->SCpnt->request_bufflen);
if (!info->scsi.SCp.ptr) {
- printk("scsi%d.%c: null buffer passed to "
- "fas216_starttransfer\n", info->host->host_no,
- fas216_target(info));
+ fas216_log(info, LOG_ERROR, "null buffer passed to "
+ "fas216_starttransfer");
+ print_SCp(&info->scsi.SCp, "SCp: ", "\n");
+ print_SCp(&info->SCpnt->SCp, "Cmnd SCp: ", "\n");
return;
}
- /* flush FIFO */
- if (flush_fifo)
- outb(CMD_FLUSHFIFO, REG_CMD(info));
-
/*
- * Default to PIO mode or DMA mode if we have a synchronous
- * transfer agreement.
+ * Default to PIO mode or DMA mode if we have
+ * a synchronous transfer agreement.
*/
if (info->device[info->SCpnt->target].sof && info->dma.setup)
dmatype = fasdma_real_all;
@@ -694,41 +783,45 @@ fas216_starttransfer(FAS216_Info *info, fasdmadir_t direction, int flush_fifo)
switch (dmatype) {
case fasdma_pio:
+ fas216_log(info, LOG_BUFFER, "PIO transfer");
outb(0, REG_SOF(info));
outb(info->scsi.async_stp, REG_STP(info));
outb(info->scsi.SCp.this_residual, REG_STCL(info));
outb(info->scsi.SCp.this_residual >> 8, REG_STCM(info));
outb(info->scsi.SCp.this_residual >> 16, REG_STCH(info));
- outb(CMD_TRANSFERINFO, REG_CMD(info));
+ fas216_cmd(info, CMD_TRANSFERINFO);
fas216_pio(info, direction);
break;
case fasdma_pseudo:
+ fas216_log(info, LOG_BUFFER, "pseudo transfer");
outb(info->scsi.SCp.this_residual, REG_STCL(info));
outb(info->scsi.SCp.this_residual >> 8, REG_STCM(info));
outb(info->scsi.SCp.this_residual >> 16, REG_STCH(info));
- outb(CMD_TRANSFERINFO | CMD_WITHDMA, REG_CMD(info));
+ fas216_cmd(info, CMD_TRANSFERINFO | CMD_WITHDMA);
info->dma.pseudo(info->host, &info->scsi.SCp,
direction, info->SCpnt->transfersize);
break;
case fasdma_real_block:
+ fas216_log(info, LOG_BUFFER, "block dma transfer");
outb(info->scsi.SCp.this_residual, REG_STCL(info));
outb(info->scsi.SCp.this_residual >> 8, REG_STCM(info));
outb(info->scsi.SCp.this_residual >> 16, REG_STCH(info));
- outb(CMD_TRANSFERINFO | CMD_WITHDMA, REG_CMD(info));
+ fas216_cmd(info, CMD_TRANSFERINFO | CMD_WITHDMA);
break;
case fasdma_real_all:
+ fas216_log(info, LOG_BUFFER, "total dma transfer");
outb(info->SCpnt->request_bufflen, REG_STCL(info));
outb(info->SCpnt->request_bufflen >> 8, REG_STCM(info));
outb(info->SCpnt->request_bufflen >> 16, REG_STCH(info));
- outb(CMD_TRANSFERINFO | CMD_WITHDMA, REG_CMD(info));
+ fas216_cmd(info, CMD_TRANSFERINFO | CMD_WITHDMA);
break;
default:
- printk(KERN_ERR "scsi%d.%d: invalid FAS216 DMA type\n",
- info->host->host_no, fas216_target(info));
+ fas216_log(info, LOG_BUFFER | LOG_ERROR,
+ "invalid FAS216 DMA type");
break;
}
}
@@ -737,51 +830,49 @@ fas216_starttransfer(FAS216_Info *info, fasdmadir_t direction, int flush_fifo)
* Purpose : Stop a DMA transfer onto / off of the card
* Params : info - interface from which device disconnected from
*/
-static void
-fas216_stoptransfer(FAS216_Info *info)
+static void fas216_stoptransfer(FAS216_Info *info)
{
fas216_checkmagic(info);
- if (info->dma.transfer_type != fasdma_none &&
- info->dma.transfer_type != fasdma_pio) {
- unsigned long total, residual;
-
- if ((info->dma.transfer_type == fasdma_real_all ||
- info->dma.transfer_type == fasdma_real_block) &&
- info->dma.stop)
- info->dma.stop(info->host, &info->scsi.SCp);
+ if ((info->dma.transfer_type == fasdma_real_all ||
+ info->dma.transfer_type == fasdma_real_block) &&
+ info->dma.stop)
+ info->dma.stop(info->host, &info->scsi.SCp);
- if (info->dma.transfer_type == fasdma_real_all)
- total = info->SCpnt->request_bufflen;
- else
- total = info->scsi.SCp.this_residual;
+ fas216_cleanuptransfer(info);
- residual = (inb(REG_CFIS(info)) & CFIS_CF) +
- inb(REG_CTCL(info)) +
- (inb(REG_CTCM(info)) << 8) +
- (inb(REG_CTCH(info)) << 16);
- fas216_updateptrs(info, total - residual);
- info->dma.transfer_type = fasdma_none;
- }
if (info->scsi.phase == PHASE_DATAOUT)
- outb(CMD_FLUSHFIFO, REG_CMD(info));
+ fas216_cmd(info, CMD_FLUSHFIFO);
+}
+
+static void fas216_aborttransfer(FAS216_Info *info)
+{
+ fas216_checkmagic(info);
+
+ if ((info->dma.transfer_type == fasdma_real_all ||
+ info->dma.transfer_type == fasdma_real_block) &&
+ info->dma.stop)
+ info->dma.stop(info->host, &info->scsi.SCp);
+
+ info->dma.transfer_type = fasdma_none;
+ fas216_cmd(info, CMD_FLUSHFIFO);
}
/* Function: void fas216_disconnected_intr(FAS216_Info *info)
* Purpose : handle device disconnection
* Params : info - interface from which device disconnected from
*/
-static void
-fas216_disconnect_intr(FAS216_Info *info)
+static void fas216_disconnect_intr(FAS216_Info *info)
{
fas216_checkmagic(info);
-#ifdef DEBUG_CONNECT
- printk("scsi%d.%c: disconnect phase=%02X\n", info->host->host_no,
- fas216_target(info), info->scsi.phase);
-#endif
+ fas216_log(info, LOG_CONNECT, "disconnect phase=%02x",
+ info->scsi.phase);
+
msgqueue_flush(&info->scsi.msgs);
+ fas216_cmd(info, CMD_ENABLESEL);
+
switch (info->scsi.phase) {
case PHASE_SELECTION: /* while selecting - no target */
case PHASE_SELSTEPS:
@@ -789,7 +880,6 @@ fas216_disconnect_intr(FAS216_Info *info)
break;
case PHASE_MSGIN_DISCONNECT: /* message in - disconnecting */
- outb(CMD_ENABLESEL, REG_CMD(info));
info->scsi.disconnectable = 1;
info->scsi.reconnected.tag = 0;
info->scsi.phase = PHASE_IDLE;
@@ -841,19 +931,16 @@ fas216_reselected_intr(FAS216_Info *info)
info->device[SCpnt->target].sync_state = neg_wait;
}
-#ifdef DEBUG_CONNECT
- printk("scsi%d.%c: reconnect phase=%02X\n", info->host->host_no,
- fas216_target(info), info->scsi.phase);
-#endif
+ fas216_log(info, LOG_CONNECT, "reconnect phase=%02X", info->scsi.phase);
if ((inb(REG_CFIS(info)) & CFIS_CF) != 2) {
printk(KERN_ERR "scsi%d.H: incorrect number of bytes after reselect\n",
info->host->host_no);
- outb(CMD_SETATN, REG_CMD(info));
- outb(CMD_MSGACCEPTED, REG_CMD(info));
+ fas216_cmd(info, CMD_SETATN);
msgqueue_flush(&info->scsi.msgs);
msgqueue_addmsg(&info->scsi.msgs, 1, INITIATOR_ERROR);
info->scsi.phase = PHASE_MSGOUT_EXPECT;
+ fas216_cmd(info, CMD_MSGACCEPTED);
return;
}
@@ -877,11 +964,11 @@ fas216_reselected_intr(FAS216_Info *info)
* Something went wrong - send an initiator error to
* the target.
*/
- outb(CMD_SETATN, REG_CMD(info));
- outb(CMD_MSGACCEPTED, REG_CMD(info));
+ fas216_cmd(info, CMD_SETATN);
msgqueue_flush(&info->scsi.msgs);
msgqueue_addmsg(&info->scsi.msgs, 1, INITIATOR_ERROR);
info->scsi.phase = PHASE_MSGOUT_EXPECT;
+ fas216_cmd(info, CMD_MSGACCEPTED);
return;
}
@@ -903,6 +990,9 @@ fas216_reselected_intr(FAS216_Info *info)
info->scsi.reconnected.lun = identify_msg;
info->scsi.reconnected.tag = 0;
+ /* set up for synchronous transfers */
+ fas216_set_sync(info, target);
+
ok = 0;
if (info->scsi.disconnectable && info->SCpnt &&
info->SCpnt->target == target && info->SCpnt->lun == identify_msg)
@@ -922,12 +1012,12 @@ fas216_reselected_intr(FAS216_Info *info)
* record of this command, we can't send
* an INITIATOR DETECTED ERROR message.
*/
- outb(CMD_SETATN, REG_CMD(info));
+ fas216_cmd(info, CMD_SETATN);
msgqueue_addmsg(&info->scsi.msgs, 1, ABORT);
info->scsi.phase = PHASE_MSGOUT_EXPECT;
}
- outb(CMD_MSGACCEPTED, REG_CMD(info));
+ fas216_cmd(info, CMD_MSGACCEPTED);
}
/* Function: void fas216_finish_reconnect(FAS216_Info *info)
@@ -939,28 +1029,20 @@ fas216_finish_reconnect(FAS216_Info *info)
{
fas216_checkmagic(info);
-#ifdef DEBUG_CONNECT
- printk("Connected: %1X %1X %02X, reconnected: %1X %1X %02X\n",
+ fas216_log(info, LOG_CONNECT, "Connected: %1x %1x %02x, reconnected: %1x %1x %02x",
info->SCpnt->target, info->SCpnt->lun, info->SCpnt->tag,
info->scsi.reconnected.target, info->scsi.reconnected.lun,
info->scsi.reconnected.tag);
-#endif
if (info->scsi.disconnectable && info->SCpnt) {
info->scsi.disconnectable = 0;
if (info->SCpnt->target == info->scsi.reconnected.target &&
info->SCpnt->lun == info->scsi.reconnected.lun &&
info->SCpnt->tag == info->scsi.reconnected.tag) {
-#ifdef DEBUG_CONNECT
- printk("scsi%d.%c: reconnected",
- info->host->host_no, fas216_target(info));
-#endif
+ fas216_log(info, LOG_CONNECT, "reconnected");
} else {
queue_add_cmd_tail(&info->queues.disconnected, info->SCpnt);
-#ifdef DEBUG_CONNECT
- printk("scsi%d.%c: had to move command to disconnected queue\n",
- info->host->host_no, fas216_target(info));
-#endif
+ fas216_log(info, LOG_CONNECT, "had to move command to disconnected queue");
info->SCpnt = NULL;
}
}
@@ -969,20 +1051,19 @@ fas216_finish_reconnect(FAS216_Info *info)
info->scsi.reconnected.target,
info->scsi.reconnected.lun,
info->scsi.reconnected.tag);
-#ifdef DEBUG_CONNECT
- printk("scsi%d.%c: had to get command",
- info->host->host_no, fas216_target(info));
-#endif
+ fas216_log(info, LOG_CONNECT, "had to get command");
}
if (!info->SCpnt) {
- outb(CMD_SETATN, REG_CMD(info));
+ fas216_cmd(info, CMD_SETATN);
msgqueue_flush(&info->scsi.msgs);
+
#if 0
if (info->scsi.reconnected.tag)
msgqueue_addmsg(&info->scsi.msgs, 2, ABORT_TAG, info->scsi.reconnected.tag);
else
#endif
msgqueue_addmsg(&info->scsi.msgs, 1, ABORT);
+
info->scsi.phase = PHASE_MSGOUT_EXPECT;
info->scsi.aborting = 1;
} else {
@@ -990,122 +1071,14 @@ fas216_finish_reconnect(FAS216_Info *info)
* Restore data pointer from SAVED data pointer
*/
info->scsi.SCp = info->SCpnt->SCp;
-#ifdef DEBUG_CONNECT
- printk(", data pointers: [%p, %X]",
+ fas216_log(info, LOG_CONNECT, "data pointers: [%p, %X]",
info->scsi.SCp.ptr, info->scsi.SCp.this_residual);
-#endif
- }
-#ifdef DEBUG_CONNECT
- printk("\n");
-#endif
-}
-
-static int fas216_wait_cmd(FAS216_Info *info, int cmd)
-{
- int tout;
- int stat;
-
- outb(cmd, REG_CMD(info));
-
- for (tout = 1000; tout; tout -= 1) {
- stat = inb(REG_STAT(info));
- if (stat & STAT_INT)
- break;
- udelay(1);
}
-
- return stat;
-}
-
-static int fas216_get_msg_byte(FAS216_Info *info)
-{
- int stat;
-
- stat = fas216_wait_cmd(info, CMD_MSGACCEPTED);
-
- if ((stat & STAT_INT) == 0)
- goto timedout;
-
- if ((stat & STAT_BUSMASK) != STAT_MESGIN)
- goto unexpected_phase_change;
-
- inb(REG_INST(info));
-
- stat = fas216_wait_cmd(info, CMD_TRANSFERINFO);
-
- if ((stat & STAT_INT) == 0)
- goto timedout;
-
- if ((stat & STAT_BUSMASK) != STAT_MESGIN)
- goto unexpected_phase_change;
-
- inb(REG_INST(info));
-
- return inb(REG_FF(info));
-
-timedout:
- printk("scsi%d.%c: timed out waiting for message byte\n",
- info->host->host_no, fas216_target(info));
- return -1;
-
-unexpected_phase_change:
- printk("scsi%d.%c: unexpected phase change: status = %02X\n",
- info->host->host_no, fas216_target(info), stat);
-
- return -2;
}
-/* Function: void fas216_message(FAS216_Info *info)
- * Purpose : handle a function done interrupt from FAS216 chip
- * Params : info - interface which caused function done interrupt
- */
-static void fas216_message(FAS216_Info *info)
+static void fas216_parse_message(FAS216_Info *info, unsigned char *message, int msglen)
{
- unsigned char *message = info->scsi.message;
- unsigned int msglen = 1, i;
- int msgbyte = 0;
-
- fas216_checkmagic(info);
-
- message[0] = inb(REG_FF(info));
-
- if (message[0] == EXTENDED_MESSAGE) {
- msgbyte = fas216_get_msg_byte(info);
-
- if (msgbyte >= 0) {
- message[1] = msgbyte;
-
- for (msglen = 2; msglen < message[1] + 2; msglen++) {
- msgbyte = fas216_get_msg_byte(info);
-
- if (msgbyte >= 0)
- message[msglen] = msgbyte;
- else
- break;
- }
- }
- }
-
- info->scsi.msglen = msglen;
-
-#ifdef DEBUG_MESSAGES
- {
- int i;
-
- printk("scsi%d.%c: message in: ",
- info->host->host_no, fas216_target(info));
- for (i = 0; i < msglen; i++)
- printk("%02X ", message[i]);
- printk("\n");
- }
-#endif
-
- if (info->scsi.phase == PHASE_RECONNECTED) {
- if (message[0] == SIMPLE_QUEUE_TAG)
- info->scsi.reconnected.tag = message[1];
- fas216_finish_reconnect(info);
- info->scsi.phase = PHASE_MSGIN;
- }
+ int i;
switch (message[0]) {
case COMMAND_COMPLETE:
@@ -1131,11 +1104,9 @@ static void fas216_message(FAS216_Info *info)
*/
info->SCpnt->SCp = info->scsi.SCp;
info->SCpnt->SCp.sent_command = 0;
-#if defined (DEBUG_MESSAGES) || defined (DEBUG_CONNECT)
- printk("scsi%d.%c: save data pointers: [%p, %X]\n",
- info->host->host_no, fas216_target(info),
+ fas216_log(info, LOG_CONNECT | LOG_MESSAGES | LOG_BUFFER,
+ "save data pointers: [%p, %X]",
info->scsi.SCp.ptr, info->scsi.SCp.this_residual);
-#endif
break;
case RESTORE_POINTERS:
@@ -1146,11 +1117,9 @@ static void fas216_message(FAS216_Info *info)
* Restore current data pointer from SAVED data pointer
*/
info->scsi.SCp = info->SCpnt->SCp;
-#if defined (DEBUG_MESSAGES) || defined (DEBUG_CONNECT)
- printk("scsi%d.%c: restore data pointers: [%p, %X]\n",
- info->host->host_no, fas216_target(info),
+ fas216_log(info, LOG_CONNECT | LOG_MESSAGES | LOG_BUFFER,
+ "restore data pointers: [%p, 0x%x]",
info->scsi.SCp.ptr, info->scsi.SCp.this_residual);
-#endif
break;
case DISCONNECT:
@@ -1174,8 +1143,7 @@ static void fas216_message(FAS216_Info *info)
break;
default:
- printk("scsi%d.%c: reject, last message %04X\n",
- info->host->host_no, fas216_target(info),
+ fas216_log(info, 0, "reject, last message 0x%04x",
fas216_get_last_msg(info, info->scsi.msgin_fifo));
}
break;
@@ -1188,9 +1156,7 @@ static void fas216_message(FAS216_Info *info)
goto unrecognised;
/* handled above - print a warning since this is untested */
- printk("scsi%d.%c: reconnect queue tag %02X\n",
- info->host->host_no, fas216_target(info),
- message[1]);
+ fas216_log(info, 0, "reconnect queue tag 0x%02x", message[1]);
break;
case EXTENDED_MESSAGE:
@@ -1198,11 +1164,11 @@ static void fas216_message(FAS216_Info *info)
goto unrecognised;
switch (message[2]) {
- case EXTENDED_SDTR: /* Sync transfer negociation request/reply */
+ case EXTENDED_SDTR: /* Sync transfer negotiation request/reply */
fas216_handlesync(info, message);
break;
- case EXTENDED_WDTR: /* Wide transfer negociation request/reply */
+ case EXTENDED_WDTR: /* Wide transfer negotiation request/reply */
fas216_handlewide(info, message);
break;
@@ -1214,12 +1180,10 @@ static void fas216_message(FAS216_Info *info)
default:
goto unrecognised;
}
- outb(CMD_MSGACCEPTED, REG_CMD(info));
return;
unrecognised:
- printk("scsi%d.%c: unrecognised message, rejecting\n",
- info->host->host_no, fas216_target(info));
+ fas216_log(info, 0, "unrecognised message, rejecting");
printk("scsi%d.%c: message was", info->host->host_no, fas216_target(info));
for (i = 0; i < msglen; i++)
printk("%s%02X", i & 31 ? " " : "\n ", message[i]);
@@ -1230,14 +1194,138 @@ unrecognised:
* I can't use SETATN since the chip gives me an
* invalid command interrupt when I do. Weird.
*/
-outb(CMD_NOP, REG_CMD(info));
+fas216_cmd(info, CMD_NOP);
fas216_dumpstate(info);
- outb(CMD_SETATN, REG_CMD(info));
+ fas216_cmd(info, CMD_SETATN);
msgqueue_flush(&info->scsi.msgs);
msgqueue_addmsg(&info->scsi.msgs, 1, MESSAGE_REJECT);
info->scsi.phase = PHASE_MSGOUT_EXPECT;
fas216_dumpstate(info);
- outb(CMD_MSGACCEPTED, REG_CMD(info));
+}
+
+static int fas216_wait_cmd(FAS216_Info *info, int cmd)
+{
+ int tout;
+ int stat;
+
+ fas216_cmd(info, cmd);
+
+ for (tout = 1000; tout; tout -= 1) {
+ stat = inb(REG_STAT(info));
+ if (stat & (STAT_INT|STAT_PARITYERROR))
+ break;
+ udelay(1);
+ }
+
+ return stat;
+}
+
+static int fas216_get_msg_byte(FAS216_Info *info)
+{
+ unsigned int stat = fas216_wait_cmd(info, CMD_MSGACCEPTED);
+
+ if ((stat & STAT_INT) == 0)
+ goto timedout;
+
+ if ((stat & STAT_BUSMASK) != STAT_MESGIN)
+ goto unexpected_phase_change;
+
+ inb(REG_INST(info));
+
+ stat = fas216_wait_cmd(info, CMD_TRANSFERINFO);
+
+ if ((stat & STAT_INT) == 0)
+ goto timedout;
+
+ if (stat & STAT_PARITYERROR)
+ goto parity_error;
+
+ if ((stat & STAT_BUSMASK) != STAT_MESGIN)
+ goto unexpected_phase_change;
+
+ inb(REG_INST(info));
+
+ return inb(REG_FF(info));
+
+timedout:
+ fas216_log(info, LOG_ERROR, "timed out waiting for message byte");
+ return -1;
+
+unexpected_phase_change:
+ fas216_log(info, LOG_ERROR, "unexpected phase change: status = %02x", stat);
+ return -2;
+
+parity_error:
+ fas216_log(info, LOG_ERROR, "parity error during message in phase");
+ return -3;
+}
+
+/* Function: void fas216_message(FAS216_Info *info)
+ * Purpose : handle a function done interrupt from FAS216 chip
+ * Params : info - interface which caused function done interrupt
+ */
+static void fas216_message(FAS216_Info *info)
+{
+ unsigned char *message = info->scsi.message;
+ unsigned int msglen = 1;
+ int msgbyte = 0;
+
+ fas216_checkmagic(info);
+
+ message[0] = inb(REG_FF(info));
+
+ if (message[0] == EXTENDED_MESSAGE) {
+ msgbyte = fas216_get_msg_byte(info);
+
+ if (msgbyte >= 0) {
+ message[1] = msgbyte;
+
+ for (msglen = 2; msglen < message[1] + 2; msglen++) {
+ msgbyte = fas216_get_msg_byte(info);
+
+ if (msgbyte >= 0)
+ message[msglen] = msgbyte;
+ else
+ break;
+ }
+ }
+ }
+
+ if (msgbyte == -3)
+ goto parity_error;
+
+ info->scsi.msglen = msglen;
+
+#ifdef DEBUG_MESSAGES
+ {
+ int i;
+
+ printk("scsi%d.%c: message in: ",
+ info->host->host_no, fas216_target(info));
+ for (i = 0; i < msglen; i++)
+ printk("%02X ", message[i]);
+ printk("\n");
+ }
+#endif
+
+ if (info->scsi.phase == PHASE_RECONNECTED) {
+ if (message[0] == SIMPLE_QUEUE_TAG)
+ info->scsi.reconnected.tag = message[1];
+ fas216_finish_reconnect(info);
+ info->scsi.phase = PHASE_MSGIN;
+ }
+
+ fas216_parse_message(info, message, msglen);
+ fas216_cmd(info, CMD_MSGACCEPTED);
+ return;
+
+parity_error:
+ fas216_cmd(info, CMD_SETATN);
+ msgqueue_flush(&info->scsi.msgs);
+ msgqueue_addmsg(&info->scsi.msgs, 1, MSG_PARITY_ERROR);
+ info->scsi.phase = PHASE_MSGOUT_EXPECT;
+ fas216_cmd(info, CMD_MSGACCEPTED);
+ return;
}
/* Function: void fas216_send_command(FAS216_Info *info)
@@ -1250,14 +1338,14 @@ static void fas216_send_command(FAS216_Info *info)
fas216_checkmagic(info);
- outb(CMD_NOP|CMD_WITHDMA, REG_CMD(info));
- outb(CMD_FLUSHFIFO, REG_CMD(info));
+ fas216_cmd(info, CMD_NOP|CMD_WITHDMA);
+ fas216_cmd(info, CMD_FLUSHFIFO);
/* load command */
for (i = info->scsi.SCp.sent_command; i < info->SCpnt->cmd_len; i++)
outb(info->SCpnt->cmnd[i], REG_FF(info));
- outb(CMD_TRANSFERINFO, REG_CMD(info));
+ fas216_cmd(info, CMD_TRANSFERINFO);
info->scsi.phase = PHASE_COMMAND;
}
@@ -1273,7 +1361,7 @@ static void fas216_send_messageout(FAS216_Info *info, int start)
fas216_checkmagic(info);
- outb(CMD_FLUSHFIFO, REG_CMD(info));
+ fas216_cmd(info, CMD_FLUSHFIFO);
if (tot_msglen) {
struct message *msg;
@@ -1291,7 +1379,7 @@ static void fas216_send_messageout(FAS216_Info *info, int start)
} else
outb(NOP, REG_FF(info));
- outb(CMD_TRANSFERINFO, REG_CMD(info));
+ fas216_cmd(info, CMD_TRANSFERINFO);
info->scsi.phase = PHASE_MSGOUT;
}
@@ -1306,10 +1394,9 @@ static void fas216_busservice_intr(FAS216_Info *info, unsigned int stat, unsigne
{
fas216_checkmagic(info);
-#ifdef DEBUG_BUSSERVICE
- printk("scsi%d.%c: bus service: stat=%02X ssr=%02X phase=%02X\n",
- info->host->host_no, fas216_target(info), stat, ssr, info->scsi.phase);
-#endif
+ fas216_log(info, LOG_BUSSERVICE,
+ "bus service: stat=%02x ssr=%02x phase=%02x",
+ stat, ssr, info->scsi.phase);
switch (info->scsi.phase) {
case PHASE_SELECTION:
@@ -1337,7 +1424,7 @@ static void fas216_busservice_intr(FAS216_Info *info, unsigned int stat, unsigne
break;
}
- outb(CMD_NOP, REG_CMD(info));
+ fas216_cmd(info, CMD_NOP);
#define STATE(st,ph) ((ph) << 3 | (st))
/* This table describes the legal SCSI state transitions,
@@ -1352,11 +1439,11 @@ static void fas216_busservice_intr(FAS216_Info *info, unsigned int stat, unsigne
case STATE(STAT_DATAIN, PHASE_MSGOUT): /* Message Out -> Data In */
case STATE(STAT_DATAIN, PHASE_COMMAND): /* Command -> Data In */
case STATE(STAT_DATAIN, PHASE_MSGIN): /* Message In -> Data In */
- fas216_starttransfer(info, DMA_IN, 0);
+ fas216_starttransfer(info, DMA_IN);
return;
case STATE(STAT_DATAOUT, PHASE_DATAOUT):/* Data Out -> Data Out */
- fas216_starttransfer(info, DMA_OUT, 0);
+ fas216_starttransfer(info, DMA_OUT);
return;
/* Reselmsgin -> Data Out */
@@ -1366,7 +1453,7 @@ static void fas216_busservice_intr(FAS216_Info *info, unsigned int stat, unsigne
case STATE(STAT_DATAOUT, PHASE_MSGOUT): /* Message Out -> Data Out */
case STATE(STAT_DATAOUT, PHASE_COMMAND):/* Command -> Data Out */
case STATE(STAT_DATAOUT, PHASE_MSGIN): /* Message In -> Data Out */
- fas216_starttransfer(info, DMA_OUT, 1);
+ fas216_starttransfer(info, DMA_OUT);
return;
/* Reselmsgin -> Status */
@@ -1381,7 +1468,7 @@ static void fas216_busservice_intr(FAS216_Info *info, unsigned int stat, unsigne
case STATE(STAT_STATUS, PHASE_COMMAND): /* Command -> Status */
case STATE(STAT_STATUS, PHASE_MSGIN): /* Message In -> Status */
status:
- outb(CMD_INITCMDCOMPLETE, REG_CMD(info));
+ fas216_cmd(info, CMD_INITCMDCOMPLETE);
info->scsi.phase = PHASE_STATUS;
return;
@@ -1392,8 +1479,8 @@ static void fas216_busservice_intr(FAS216_Info *info, unsigned int stat, unsigne
case STATE(STAT_MESGIN, PHASE_SELSTEPS):/* Sel w/ steps -> Message In */
case STATE(STAT_MESGIN, PHASE_MSGOUT): /* Message Out -> Message In */
info->scsi.msgin_fifo = inb(REG_CFIS(info)) & CFIS_CF;
- outb(CMD_FLUSHFIFO, REG_CMD(info));
- outb(CMD_TRANSFERINFO, REG_CMD(info));
+ fas216_cmd(info, CMD_FLUSHFIFO);
+ fas216_cmd(info, CMD_TRANSFERINFO);
info->scsi.phase = PHASE_MSGIN;
return;
@@ -1401,7 +1488,7 @@ static void fas216_busservice_intr(FAS216_Info *info, unsigned int stat, unsigne
case STATE(STAT_MESGIN, PHASE_RECONNECTED):
case STATE(STAT_MESGIN, PHASE_MSGIN):
info->scsi.msgin_fifo = inb(REG_CFIS(info)) & CFIS_CF;
- outb(CMD_TRANSFERINFO, REG_CMD(info));
+ fas216_cmd(info, CMD_TRANSFERINFO);
return;
/* Reselmsgin -> Command */
@@ -1412,11 +1499,43 @@ static void fas216_busservice_intr(FAS216_Info *info, unsigned int stat, unsigne
fas216_send_command(info);
info->scsi.phase = PHASE_COMMAND;
return;
- /* Selection -> Message Out */
+
+
+ /*
+ * Selection -> Message Out
+ */
case STATE(STAT_MESGOUT, PHASE_SELECTION):
fas216_send_messageout(info, 1);
return;
- /* Any -> Message Out */
+
+ /*
+ * Message Out -> Message Out
+ */
+ case STATE(STAT_MESGOUT, PHASE_SELSTEPS):
+ case STATE(STAT_MESGOUT, PHASE_MSGOUT):
+ /*
+ * If we get another message out phase, this usually
+ * means some parity error occurred. Resend complete
+ * set of messages. If we have more than one byte to
+ * send, we need to assert ATN again.
+ */
+ if (info->device[info->SCpnt->target].parity_check) {
+ /*
+ * We were testing... good, the device
+ * supports parity checking.
+ */
+ info->device[info->SCpnt->target].parity_check = 0;
+ info->device[info->SCpnt->target].parity_enabled = 1;
+ outb(info->scsi.cfg[0], REG_CNTL1(info));
+ }
+
+ if (msgqueue_msglength(&info->scsi.msgs) > 1)
+ fas216_cmd(info, CMD_SETATN);
+ /*FALLTHROUGH*/
+
+ /*
+ * Any -> Message Out
+ */
case STATE(STAT_MESGOUT, PHASE_MSGOUT_EXPECT):
fas216_send_messageout(info, 0);
return;
@@ -1435,30 +1554,15 @@ static void fas216_busservice_intr(FAS216_Info *info, unsigned int stat, unsigne
printk(KERN_ERR "scsi%d.%c: "
"target trying to receive more command bytes\n",
info->host->host_no, fas216_target(info));
- outb(CMD_SETATN, REG_CMD(info));
+ fas216_cmd(info, CMD_SETATN);
outb(15, REG_STCL(info));
outb(0, REG_STCM(info));
outb(0, REG_STCH(info));
- outb(CMD_PADBYTES | CMD_WITHDMA, REG_CMD(info));
+ fas216_cmd(info, CMD_PADBYTES | CMD_WITHDMA);
msgqueue_flush(&info->scsi.msgs);
msgqueue_addmsg(&info->scsi.msgs, 1, INITIATOR_ERROR);
info->scsi.phase = PHASE_MSGOUT_EXPECT;
return;
-
- /* Selection -> Message Out */
- case STATE(STAT_MESGOUT, PHASE_SELSTEPS):
- case STATE(STAT_MESGOUT, PHASE_MSGOUT): /* Message Out -> Message Out */
- /* If we get another message out phase, this
- * usually means some parity error occurred.
- * Resend complete set of messages. If we have
- * more than 1 byte to send, we need to assert
- * ATN again.
- */
- if (msgqueue_msglength(&info->scsi.msgs) > 1)
- outb(CMD_SETATN, REG_CMD(info));
-
- fas216_send_messageout(info, 0);
- return;
}
if (info->scsi.phase == PHASE_MSGIN_DISCONNECT) {
@@ -1466,11 +1570,11 @@ static void fas216_busservice_intr(FAS216_Info *info, unsigned int stat, unsigne
info->host->host_no, fas216_target(info),
fas216_bus_phase(stat));
msgqueue_flush(&info->scsi.msgs);
- outb(CMD_SETATN, REG_CMD(info));
+ fas216_cmd(info, CMD_SETATN);
msgqueue_addmsg(&info->scsi.msgs, 1, INITIATOR_ERROR);
info->scsi.phase = PHASE_MSGOUT_EXPECT;
info->scsi.aborting = 1;
- outb(CMD_TRANSFERINFO, REG_CMD(info));
+ fas216_cmd(info, CMD_TRANSFERINFO);
return;
}
printk(KERN_ERR "scsi%d.%c: bus phase %s after %s?\n",
@@ -1481,9 +1585,7 @@ static void fas216_busservice_intr(FAS216_Info *info, unsigned int stat, unsigne
return;
bad_is:
- printk("scsi%d.%c: bus service at step %d?\n",
- info->host->host_no, fas216_target(info),
- ssr & IS_BITS);
+ fas216_log(info, 0, "bus service at step %d?", ssr & IS_BITS);
print_debug_list();
fas216_done(info, DID_ERROR);
@@ -1497,39 +1599,88 @@ bad_is:
*/
static void fas216_funcdone_intr(FAS216_Info *info, unsigned int stat, unsigned int ssr)
{
- int status, message;
+ unsigned int fifo_len = inb(REG_CFIS(info)) & CFIS_CF;
+ unsigned int status, message;
fas216_checkmagic(info);
-#ifdef DEBUG_FUNCTIONDONE
- printk("scsi%d.%c: function done: stat=%X ssr=%X phase=%02X\n",
- info->host->host_no, fas216_target(info), stat, ssr, info->scsi.phase);
-#endif
+ fas216_log(info, LOG_FUNCTIONDONE,
+ "function done: stat=%02x ssr=%02x phase=%02x",
+ stat, ssr, info->scsi.phase);
+
switch (info->scsi.phase) {
case PHASE_STATUS: /* status phase - read status and msg */
+ if (fifo_len != 2) {
+ fas216_log(info, 0, "odd number of bytes in FIFO: %d", fifo_len);
+ }
status = inb(REG_FF(info));
message = inb(REG_FF(info));
info->scsi.SCp.Message = message;
info->scsi.SCp.Status = status;
info->scsi.phase = PHASE_DONE;
- outb(CMD_MSGACCEPTED, REG_CMD(info));
+ fas216_cmd(info, CMD_MSGACCEPTED);
break;
case PHASE_IDLE: /* reselected? */
case PHASE_MSGIN: /* message in phase */
case PHASE_RECONNECTED: /* reconnected command */
if ((stat & STAT_BUSMASK) == STAT_MESGIN) {
- info->scsi.msgin_fifo = inb(REG_CFIS(info)) & CFIS_CF;
+ info->scsi.msgin_fifo = fifo_len;
fas216_message(info);
break;
}
default:
- printk("scsi%d.%c: internal phase %s for function done?"
- " What do I do with this?\n",
- info->host->host_no, fas216_target(info),
- fas216_drv_phase(info));
+ fas216_log(info, 0, "internal phase %s for function done?"
+ " What do I do with this?",
+ fas216_target(info), fas216_drv_phase(info));
+ }
+}
+
+static void fas216_bus_reset(FAS216_Info *info)
+{
+ neg_t sync_state, wide_state;
+ int i;
+
+ msgqueue_flush(&info->scsi.msgs);
+
+ info->scsi.reconnected.target = 0;
+ info->scsi.reconnected.lun = 0;
+ info->scsi.reconnected.tag = 0;
+
+ if (info->ifcfg.wide_max_size == 0)
+ wide_state = neg_invalid;
+ else
+#ifdef SCSI2_WIDE
+ wide_state = neg_wait;
+#else
+ wide_state = neg_invalid;
+#endif
+
+ if (info->host->dma_channel == NO_DMA || !info->dma.setup)
+ sync_state = neg_invalid;
+ else
+#ifdef SCSI2_SYNC
+ sync_state = neg_wait;
+#else
+ sync_state = neg_invalid;
+#endif
+
+ info->scsi.phase = PHASE_IDLE;
+ info->SCpnt = NULL; /* bug! */
+
+ for (i = 0; i < 8; i++) {
+ info->device[i].disconnect_ok = info->ifcfg.disconnect_ok;
+ info->device[i].sync_state = sync_state;
+ info->device[i].wide_state = wide_state;
+ info->device[i].period = info->ifcfg.asyncperiod / 4;
+ info->device[i].stp = info->scsi.async_stp;
+ info->device[i].sof = 0;
+ info->device[i].wide_xfer = 0;
}
+
+ info->rst_bus_status = 1;
+ wake_up(&info->eh_wait);
}
/* Function: void fas216_intr(struct Scsi_Host *instance)
@@ -1551,11 +1702,13 @@ void fas216_intr(struct Scsi_Host *instance)
if (stat & STAT_INT) {
if (isr & INST_BUSRESET) {
- printk(KERN_DEBUG "scsi%d.H: bus reset detected\n", instance->host_no);
- scsi_report_bus_reset(instance, 0);
+ fas216_log(info, 0, "bus reset detected");
+ fas216_bus_reset(info);
+ scsi_report_bus_reset(info->host, 0);
} else if (isr & INST_ILLEGALCMD) {
- printk(KERN_CRIT "scsi%d.H: illegal command given\n", instance->host_no);
+ fas216_log(info, LOG_ERROR, "illegal command given\n");
fas216_dumpstate(info);
+ print_debug_list();
} else if (isr & INST_DISCONNECT)
fas216_disconnect_intr(info);
else if (isr & INST_RESELECTED) /* reselected */
@@ -1565,108 +1718,123 @@ void fas216_intr(struct Scsi_Host *instance)
else if (isr & INST_FUNCDONE) /* function done */
fas216_funcdone_intr(info, stat, ssr);
else
- printk("scsi%d.%c: unknown interrupt received:"
- " phase %s isr %02X ssr %02X stat %02X\n",
- instance->host_no, fas216_target(info),
+ fas216_log(info, 0, "unknown interrupt received:"
+ " phase %s isr %02X ssr %02X stat %02X",
fas216_drv_phase(info), isr, ssr, stat);
}
}
-/* Function: void fas216_kick(FAS216_Info *info)
- * Purpose : kick a command to the interface - interface should be idle
- * Params : info - our host interface to kick
- * Notes : Interrupts are always disabled!
- */
-static void fas216_kick(FAS216_Info *info)
+static void __fas216_start_command(FAS216_Info *info, Scsi_Cmnd *SCpnt)
{
- Scsi_Cmnd *SCpnt = NULL;
- int tot_msglen, from_queue = 0, disconnect_ok;
+ int tot_msglen;
- fas216_checkmagic(info);
+ /* following what the ESP driver says */
+ outb(0, REG_STCL(info));
+ outb(0, REG_STCM(info));
+ outb(0, REG_STCH(info));
+ fas216_cmd(info, CMD_NOP | CMD_WITHDMA);
- /*
- * Obtain the next command to process.
- */
- do {
- if (info->reqSCpnt) {
- SCpnt = info->reqSCpnt;
- info->reqSCpnt = NULL;
- break;
- }
+ /* flush FIFO */
+ fas216_cmd(info, CMD_FLUSHFIFO);
- if (info->origSCpnt) {
- SCpnt = info->origSCpnt;
- info->origSCpnt = NULL;
- break;
+ /* load bus-id and timeout */
+ outb(BUSID(SCpnt->target), REG_SDID(info));
+ outb(info->ifcfg.select_timeout, REG_STIM(info));
+
+ /* synchronous transfers */
+ fas216_set_sync(info, SCpnt->target);
+
+ tot_msglen = msgqueue_msglength(&info->scsi.msgs);
+
+#ifdef DEBUG_MESSAGES
+ {
+ struct message *msg;
+ int msgnr = 0, i;
+
+ printk("scsi%d.%c: message out: ",
+ info->host->host_no, '0' + SCpnt->target);
+ while ((msg = msgqueue_getmsg(&info->scsi.msgs, msgnr++)) != NULL) {
+ printk("{ ");
+ for (i = 0; i < msg->length; i++)
+ printk("%02x ", msg->msg[i]);
+ printk("} ");
}
+ printk("\n");
+ }
+#endif
- /* retrieve next command */
- if (!SCpnt) {
- SCpnt = queue_remove_exclude(&info->queues.issue,
- info->busyluns);
- from_queue = 1;
- break;
+ if (tot_msglen == 1 || tot_msglen == 3) {
+ /*
+ * We have an easy message length to send...
+ */
+ struct message *msg;
+ int msgnr = 0, i;
+
+ info->scsi.phase = PHASE_SELSTEPS;
+
+ /* load message bytes */
+ while ((msg = msgqueue_getmsg(&info->scsi.msgs, msgnr++)) != NULL) {
+ for (i = 0; i < msg->length; i++)
+ outb(msg->msg[i], REG_FF(info));
+ msg->fifo = tot_msglen - (inb(REG_CFIS(info)) & CFIS_CF);
}
- } while (0);
- if (!SCpnt) /* no command pending - just exit */
- return;
+ /* load command */
+ for (i = 0; i < SCpnt->cmd_len; i++)
+ outb(SCpnt->cmnd[i], REG_FF(info));
- if (info->scsi.disconnectable && info->SCpnt) {
- queue_add_cmd_tail(&info->queues.disconnected, info->SCpnt);
- info->scsi.disconnectable = 0;
- info->SCpnt = NULL;
- printk("scsi%d.%c: moved command to disconnected queue\n",
- info->host->host_no, fas216_target(info));
+ if (tot_msglen == 1)
+ fas216_cmd(info, CMD_SELECTATN);
+ else
+ fas216_cmd(info, CMD_SELECTATN3);
+ } else {
+ /*
+ * We have an unusual number of message bytes to send.
+ * Load first byte into fifo, and issue SELECT with ATN and
+ * stop steps.
+ */
+ struct message *msg = msgqueue_getmsg(&info->scsi.msgs, 0);
+
+ outb(msg->msg[0], REG_FF(info));
+ msg->fifo = 1;
+
+ fas216_cmd(info, CMD_SELECTATNSTOP);
+ }
+}
+
+/*
+ * Decide whether we need to perform a parity test on this device.
+ * Can also be used to force parity error conditions during initial
+ * information transfer phase (message out) for test purposes.
+ */
+static int parity_test(FAS216_Info *info, int target)
+{
+#if 0
+ if (target == 3) {
+ info->device[3].parity_check = 0;
+ return 1;
}
+#endif
+ return info->device[target].parity_check;
+}
+
+static void fas216_start_command(FAS216_Info *info, Scsi_Cmnd *SCpnt)
+{
+ int disconnect_ok;
+
+ if (parity_test(info, SCpnt->target))
+ outb(info->scsi.cfg[0] | CNTL1_PTE, REG_CNTL1(info));
+ else
+ outb(info->scsi.cfg[0], REG_CNTL1(info));
/*
* claim host busy
*/
info->scsi.phase = PHASE_SELECTION;
- info->SCpnt = SCpnt;
info->scsi.SCp = SCpnt->SCp;
+ info->SCpnt = SCpnt;
info->dma.transfer_type = fasdma_none;
-#ifdef DEBUG_CONNECT
- printk("scsi%d.%c: starting cmd %02X",
- info->host->host_no, '0' + SCpnt->target,
- SCpnt->cmnd[0]);
-#endif
-
- if (from_queue) {
-#ifdef SCSI2_TAG
- /*
- * tagged queuing - allocate a new tag to this command
- */
- if (SCpnt->device->tagged_queue && SCpnt->cmnd[0] != REQUEST_SENSE &&
- SCpnt->cmnd[0] != INQUIRY) {
- SCpnt->device->current_tag += 1;
- if (SCpnt->device->current_tag == 0)
- SCpnt->device->current_tag = 1;
- SCpnt->tag = SCpnt->device->current_tag;
- } else
-#endif
- set_bit(SCpnt->target * 8 + SCpnt->lun, info->busyluns);
-
- info->stats.removes += 1;
- switch (SCpnt->cmnd[0]) {
- case WRITE_6:
- case WRITE_10:
- case WRITE_12:
- info->stats.writes += 1;
- break;
- case READ_6:
- case READ_10:
- case READ_12:
- info->stats.reads += 1;
- break;
- default:
- info->stats.miscs += 1;
- break;
- }
- }
-
/*
* Don't allow request sense commands to disconnect.
*/
@@ -1710,14 +1878,68 @@ static void fas216_kick(FAS216_Info *info)
#endif
} while (0);
+ __fas216_start_command(info, SCpnt);
+}
+
+static void fas216_allocate_tag(FAS216_Info *info, Scsi_Cmnd *SCpnt)
+{
+#ifdef SCSI2_TAG
+ /*
+ * tagged queuing - allocate a new tag to this command
+ */
+ if (SCpnt->device->tagged_queue && SCpnt->cmnd[0] != REQUEST_SENSE &&
+ SCpnt->cmnd[0] != INQUIRY) {
+ SCpnt->device->current_tag += 1;
+ if (SCpnt->device->current_tag == 0)
+ SCpnt->device->current_tag = 1;
+ SCpnt->tag = SCpnt->device->current_tag;
+ } else
+#endif
+ set_bit(SCpnt->target * 8 + SCpnt->lun, info->busyluns);
+
+ info->stats.removes += 1;
+ switch (SCpnt->cmnd[0]) {
+ case WRITE_6:
+ case WRITE_10:
+ case WRITE_12:
+ info->stats.writes += 1;
+ break;
+ case READ_6:
+ case READ_10:
+ case READ_12:
+ info->stats.reads += 1;
+ break;
+ default:
+ info->stats.miscs += 1;
+ break;
+ }
+}
+
+static void fas216_do_bus_device_reset(FAS216_Info *info, Scsi_Cmnd *SCpnt)
+{
+ struct message *msg;
+
+ /*
+ * claim host busy
+ */
+ info->scsi.phase = PHASE_SELECTION;
+ info->scsi.SCp = SCpnt->SCp;
+ info->SCpnt = SCpnt;
+ info->dma.transfer_type = fasdma_none;
+
+ fas216_log(info, LOG_ERROR, "sending bus device reset");
+
+ msgqueue_flush(&info->scsi.msgs);
+ msgqueue_addmsg(&info->scsi.msgs, 1, BUS_DEVICE_RESET);
+
/* following what the ESP driver says */
outb(0, REG_STCL(info));
outb(0, REG_STCM(info));
outb(0, REG_STCH(info));
- outb(CMD_NOP | CMD_WITHDMA, REG_CMD(info));
+ fas216_cmd(info, CMD_NOP | CMD_WITHDMA);
/* flush FIFO */
- outb(CMD_FLUSHFIFO, REG_CMD(info));
+ fas216_cmd(info, CMD_FLUSHFIFO);
/* load bus-id and timeout */
outb(BUSID(SCpnt->target), REG_SDID(info));
@@ -1726,68 +1948,110 @@ static void fas216_kick(FAS216_Info *info)
/* synchronous transfers */
fas216_set_sync(info, SCpnt->target);
- tot_msglen = msgqueue_msglength(&info->scsi.msgs);
+ msg = msgqueue_getmsg(&info->scsi.msgs, 0);
-#ifdef DEBUG_MESSAGES
- {
- struct message *msg;
- int msgnr = 0, i;
+ outb(BUS_DEVICE_RESET, REG_FF(info));
+ msg->fifo = 1;
- printk("scsi%d.%c: message out: ",
- info->host->host_no, '0' + SCpnt->target);
- while ((msg = msgqueue_getmsg(&info->scsi.msgs, msgnr++)) != NULL) {
- printk("{ ");
- for (i = 0; i < msg->length; i++)
- printk("%02x ", msg->msg[i]);
- printk("} ");
+ fas216_cmd(info, CMD_SELECTATNSTOP);
+}
+
+/* Function: void fas216_kick(FAS216_Info *info)
+ * Purpose : kick a command to the interface - interface should be idle
+ * Params : info - our host interface to kick
+ * Notes : Interrupts are always disabled!
+ */
+static void fas216_kick(FAS216_Info *info)
+{
+ Scsi_Cmnd *SCpnt = NULL;
+#define TYPE_OTHER 0
+#define TYPE_RESET 1
+#define TYPE_QUEUE 2
+ int where_from = TYPE_OTHER;
+
+ fas216_checkmagic(info);
+
+ /*
+ * Obtain the next command to process.
+ */
+ do {
+ if (info->rstSCpnt) {
+ SCpnt = info->rstSCpnt;
+ /* don't remove it */
+ where_from = TYPE_RESET;
+ break;
}
- printk("\n");
- }
-#endif
- if (tot_msglen == 1 || tot_msglen == 3) {
- /*
- * We have an easy message length to send...
- */
- struct message *msg;
- int msgnr = 0, i;
+ if (info->reqSCpnt) {
+ SCpnt = info->reqSCpnt;
+ info->reqSCpnt = NULL;
+ break;
+ }
- info->scsi.phase = PHASE_SELSTEPS;
+ if (info->origSCpnt) {
+ SCpnt = info->origSCpnt;
+ info->origSCpnt = NULL;
+ break;
+ }
- /* load message bytes */
- while ((msg = msgqueue_getmsg(&info->scsi.msgs, msgnr++)) != NULL) {
- for (i = 0; i < msg->length; i++)
- outb(msg->msg[i], REG_FF(info));
- msg->fifo = tot_msglen - (inb(REG_CFIS(info)) & CFIS_CF);
+ /* retrieve next command */
+ if (!SCpnt) {
+ SCpnt = queue_remove_exclude(&info->queues.issue,
+ info->busyluns);
+ where_from = TYPE_QUEUE;
+ break;
}
+ } while (0);
- /* load command */
- for (i = 0; i < SCpnt->cmd_len; i++)
- outb(SCpnt->cmnd[i], REG_FF(info));
+ if (!SCpnt) /* no command pending - just exit */
+ return;
- if (tot_msglen == 1)
- outb(CMD_SELECTATN, REG_CMD(info));
- else
- outb(CMD_SELECTATN3, REG_CMD(info));
- } else {
- /*
- * We have an unusual number of message bytes to send.
- * Load first byte into fifo, and issue SELECT with ATN and
- * stop steps.
- */
- struct message *msg = msgqueue_getmsg(&info->scsi.msgs, 0);
+ if (info->scsi.disconnectable && info->SCpnt) {
+ fas216_log(info, LOG_CONNECT,
+ "moved command for %d to disconnected queue",
+ info->SCpnt->target);
+ queue_add_cmd_tail(&info->queues.disconnected, info->SCpnt);
+ info->scsi.disconnectable = 0;
+ info->SCpnt = NULL;
+ }
- outb(msg->msg[0], REG_FF(info));
- msg->fifo = 1;
+#if defined(DEBUG_CONNECT) || defined(DEBUG_MESSAGES)
+ printk("scsi%d.%c: starting ",
+ info->host->host_no, '0' + SCpnt->target);
+ print_command(SCpnt->cmnd);
+#endif
- outb(CMD_SELECTATNSTOP, REG_CMD(info));
+ switch (where_from) {
+ case TYPE_QUEUE:
+ fas216_allocate_tag(info, SCpnt);
+ case TYPE_OTHER:
+ fas216_start_command(info, SCpnt);
+ break;
+ case TYPE_RESET:
+ fas216_do_bus_device_reset(info, SCpnt);
+ break;
}
-#ifdef DEBUG_CONNECT
- printk(", data pointers [%p, %X]\n",
+ fas216_log(info, LOG_CONNECT, "select: data pointers [%p, %X]",
info->scsi.SCp.ptr, info->scsi.SCp.this_residual);
-#endif
- /* should now get either DISCONNECT or (FUNCTION DONE with BUS SERVICE) intr */
+
+ /*
+ * should now get either DISCONNECT or
+ * (FUNCTION DONE with BUS SERVICE) interrupt
+ */
+}
+
+/*
+ * Clean up from issuing a BUS DEVICE RESET message to a device.
+ */
+static void
+fas216_devicereset_done(FAS216_Info *info, Scsi_Cmnd *SCpnt, unsigned int result)
+{
+ fas216_log(info, LOG_ERROR, "fas216 device reset complete");
+
+ info->rstSCpnt = NULL;
+ info->rst_dev_status = 1;
+ wake_up(&info->eh_wait);
}
/* Function: void fas216_rq_sns_done(info, SCpnt, result)
@@ -1799,11 +2063,9 @@ static void fas216_kick(FAS216_Info *info)
static void
fas216_rq_sns_done(FAS216_Info *info, Scsi_Cmnd *SCpnt, unsigned int result)
{
-#ifdef DEBUG_CONNECT
- printk("scsi%d.%c: request sense complete, result=%04X%02X%02X\n",
- info->host->host_no, '0' + SCpnt->target, result,
- SCpnt->SCp.Message, SCpnt->SCp.Status);
-#endif
+ fas216_log(info, LOG_CONNECT,
+ "request sense complete, result=0x%04x%02x%02x",
+ result, SCpnt->SCp.Message, SCpnt->SCp.Status);
if (result != DID_OK || SCpnt->SCp.Status != GOOD)
/*
@@ -1812,7 +2074,8 @@ fas216_rq_sns_done(FAS216_Info *info, Scsi_Cmnd *SCpnt, unsigned int result)
* confuse the higher levels.
*/
memset(SCpnt->sense_buffer, 0, sizeof(SCpnt->sense_buffer));
-
+//printk("scsi%d.%c: sense buffer: ", info->host->host_no, '0' + SCpnt->target);
+//{ int i; for (i = 0; i < 32; i++) printk("%02x ", SCpnt->sense_buffer[i]); printk("\n"); }
/*
* Note that we don't set SCpnt->result, since that should
* reflect the status of the command that we were asked by
@@ -1850,10 +2113,11 @@ fas216_std_done(FAS216_Info *info, Scsi_Cmnd *SCpnt, unsigned int result)
goto done;
/*
- * If the command returned CHECK_CONDITION status,
- * request the sense information.
+ * If the command returned CHECK_CONDITION or COMMAND_TERMINATED
+ * status, request the sense information.
*/
- if (info->scsi.SCp.Status == CHECK_CONDITION)
+ if (status_byte(SCpnt->result) == CHECK_CONDITION ||
+ status_byte(SCpnt->result) == COMMAND_TERMINATED)
goto request_sense;
/*
@@ -1888,8 +2152,15 @@ fas216_std_done(FAS216_Info *info, Scsi_Cmnd *SCpnt, unsigned int result)
}
}
-done: SCpnt->scsi_done(SCpnt);
- return;
+done:
+ if (SCpnt->scsi_done) {
+ SCpnt->scsi_done(SCpnt);
+ return;
+ }
+
+ panic("scsi%d.H: null scsi_done function in fas216_done",
+ info->host->host_no);
+
request_sense:
memset(SCpnt->cmnd, 0, sizeof (SCpnt->cmnd));
@@ -1928,6 +2199,7 @@ static void fas216_done(FAS216_Info *info, unsigned int result)
{
void (*fn)(FAS216_Info *, Scsi_Cmnd *, unsigned int);
Scsi_Cmnd *SCpnt;
+ unsigned long flags;
fas216_checkmagic(info);
@@ -1938,12 +2210,8 @@ static void fas216_done(FAS216_Info *info, unsigned int result)
info->SCpnt = NULL;
info->scsi.phase = PHASE_IDLE;
- if (!SCpnt->scsi_done)
- goto no_done;
-
if (info->scsi.aborting) {
- printk("scsi%d.%c: uncaught abort - returning DID_ABORT\n",
- info->host->host_no, fas216_target(info));
+ fas216_log(info, 0, "uncaught abort - returning DID_ABORT");
result = DID_ABORT;
info->scsi.aborting = 0;
}
@@ -1966,21 +2234,23 @@ static void fas216_done(FAS216_Info *info, unsigned int result)
* the sense information, fas216_kick will re-assert the busy
* status.
*/
+ info->device[SCpnt->target].parity_check = 0;
clear_bit(SCpnt->target * 8 + SCpnt->lun, info->busyluns);
fn = (void (*)(FAS216_Info *, Scsi_Cmnd *, unsigned int))SCpnt->host_scribble;
fn(info, SCpnt, result);
- if (info->scsi.irq != NO_IRQ)
- fas216_kick(info);
+ if (info->scsi.irq != NO_IRQ) {
+ spin_lock_irqsave(&info->host_lock, flags);
+ if (info->scsi.phase == PHASE_IDLE)
+ fas216_kick(info);
+ spin_unlock_irqrestore(&info->host_lock, flags);
+ }
return;
no_command:
panic("scsi%d.H: null command in fas216_done",
info->host->host_no);
-no_done:
- panic("scsi%d.H: null scsi_done function in fas216_done",
- info->host->host_no);
}
/* Function: int fas216_queue_command(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *))
@@ -1998,9 +2268,9 @@ int fas216_queue_command(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *))
fas216_checkmagic(info);
#ifdef DEBUG_CONNECT
- printk("scsi%d.%c: received queuable command (%p) %02X\n",
- SCpnt->host->host_no, '0' + SCpnt->target,
- SCpnt, SCpnt->cmnd[0]);
+ printk("scsi%d.H: received command for id %d (%p) ",
+ SCpnt->host->host_no, SCpnt->target, SCpnt);
+ print_command(SCpnt->cmnd);
#endif
SCpnt->scsi_done = done;
@@ -2012,6 +2282,8 @@ int fas216_queue_command(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *))
info->stats.queues += 1;
SCpnt->tag = 0;
+ spin_lock(&info->host_lock);
+
/*
* Add command into execute queue and let it complete under
* whatever scheme we're using.
@@ -2022,8 +2294,14 @@ int fas216_queue_command(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *))
* If we successfully added the command,
* kick the interface to get it moving.
*/
- if (result == 0 && (!info->SCpnt || info->scsi.disconnectable))
+ if (result == 0 && info->scsi.phase == PHASE_IDLE)
fas216_kick(info);
+ spin_unlock(&info->host_lock);
+
+#ifdef DEBUG_CONNECT
+ printk("scsi%d.H: queue %s\n", info->host->host_no,
+ result ? "failure" : "success");
+#endif
return result;
}
@@ -2092,23 +2370,41 @@ int fas216_command(Scsi_Cmnd *SCpnt)
return SCpnt->result;
}
-enum res_abort {
- res_failed, /* unable to abort */
+/*
+ * Error handler timeout function. Indicate that we timed out,
+ * and wake up any error handler process so it can continue.
+ */
+static void fas216_eh_timer(unsigned long data)
+{
+ FAS216_Info *info = (FAS216_Info *)data;
+
+ fas216_log(info, LOG_ERROR, "error handling timed out\n");
+
+ del_timer(&info->eh_timer);
+
+ if (info->rst_bus_status == 0)
+ info->rst_bus_status = -1;
+ if (info->rst_dev_status == 0)
+ info->rst_dev_status = -1;
+
+ wake_up(&info->eh_wait);
+}
+
+enum res_find {
+ res_failed, /* not found */
res_success, /* command on issue queue */
- res_success_clear, /* command marked tgt/lun busy */
res_hw_abort /* command on disconnected dev */
};
/*
- * Prototype: enum res_abort fas216_do_abort(FAS216_Info *info, Scsi_Cmnd *SCpnt)
+ * Prototype: enum res_find fas216_do_abort(FAS216_Info *info, Scsi_Cmnd *SCpnt)
* Purpose : decide how to abort a command
* Params : SCpnt - command to abort
* Returns : abort status
*/
-static enum res_abort
-fas216_do_abort(FAS216_Info *info, Scsi_Cmnd *SCpnt)
+static enum res_find fas216_find_command(FAS216_Info *info, Scsi_Cmnd *SCpnt)
{
- enum res_abort res = res_failed;
+ enum res_find res = res_failed;
if (queue_remove_cmd(&info->queues.issue, SCpnt)) {
/*
@@ -2156,8 +2452,9 @@ fas216_do_abort(FAS216_Info *info, Scsi_Cmnd *SCpnt)
* been set.
*/
info->origSCpnt = NULL;
+ clear_bit(SCpnt->target * 8 + SCpnt->lun, info->busyluns);
printk("waiting for execution ");
- res = res_success_clear;
+ res = res_success;
} else
printk("unknown ");
@@ -2179,22 +2476,15 @@ int fas216_eh_abort(Scsi_Cmnd *SCpnt)
info->stats.aborts += 1;
+ printk(KERN_WARNING "scsi%d: abort command ", info->host->host_no);
+ print_command(SCpnt->data_cmnd);
+
print_debug_list();
fas216_dumpstate(info);
- fas216_dumpinfo(info);
- printk(KERN_WARNING "scsi%d: abort ", info->host->host_no);
-
- switch (fas216_do_abort(info, SCpnt)) {
- /*
- * We managed to find the command and cleared it out.
- * We do not expect the command to be executing on the
- * target, but we have set the busylun bit.
- */
- case res_success_clear:
- printk("clear ");
- clear_bit(SCpnt->target * 8 + SCpnt->lun, info->busyluns);
+ printk(KERN_WARNING "scsi%d: abort %p ", info->host->host_no, SCpnt);
+ switch (fas216_find_command(info, SCpnt)) {
/*
* We found the command, and cleared it out. Either
* the command is still known to be executing on the
@@ -2225,132 +2515,161 @@ int fas216_eh_abort(Scsi_Cmnd *SCpnt)
return result;
}
-/* Function: void fas216_reset_state(FAS216_Info *info)
- * Purpose : Initialise driver internal state
- * Params : info - state to initialise
+/* Function: int fas216_eh_device_reset(Scsi_Cmnd *SCpnt)
+ * Purpose : Reset the device associated with this command
+ * Params : SCpnt - command specifing device to reset
+ * Returns : FAILED if unable to reset
+ * Notes : We won't be re-entered, so we'll only have one device
+ * reset on the go at one time.
*/
-static void fas216_reset_state(FAS216_Info *info)
+int fas216_eh_device_reset(Scsi_Cmnd *SCpnt)
{
- neg_t sync_state, wide_state;
- int i;
+ FAS216_Info *info = (FAS216_Info *)SCpnt->host->hostdata;
+ unsigned long flags;
+ int i, res = FAILED, target = SCpnt->target;
- fas216_checkmagic(info);
+ fas216_log(info, LOG_ERROR, "device reset for target %d", target);
- /*
- * Clear out all stale info in our state structure
- */
- memset(info->busyluns, 0, sizeof(info->busyluns));
- msgqueue_flush(&info->scsi.msgs);
- info->scsi.reconnected.target = 0;
- info->scsi.reconnected.lun = 0;
- info->scsi.reconnected.tag = 0;
- info->scsi.disconnectable = 0;
- info->scsi.aborting = 0;
- info->scsi.phase = PHASE_IDLE;
- info->scsi.async_stp =
- fas216_syncperiod(info, info->ifcfg.asyncperiod);
+ spin_lock_irqsave(&info->host_lock, flags);
- if (info->ifcfg.wide_max_size == 0)
- wide_state = neg_invalid;
- else
-#ifdef SCSI2_WIDE
- wide_state = neg_wait;
-#else
- wide_state = neg_invalid;
-#endif
+ do {
+ /*
+ * If we are currently connected to a device, and
+ * it is the device we want to reset, there is
+ * nothing we can do here. Chances are it is stuck,
+ * and we need a bus reset.
+ */
+ if (info->SCpnt && !info->scsi.disconnectable &&
+ info->SCpnt->target == SCpnt->target)
+ break;
- if (info->host->dma_channel == NO_DMA || !info->dma.setup)
- sync_state = neg_invalid;
- else
-#ifdef SCSI2_SYNC
- sync_state = neg_wait;
-#else
- sync_state = neg_invalid;
-#endif
+ /*
+ * We're going to be resetting this device. Remove
+ * all pending commands from the driver. By doing
+ * so, we guarantee that we won't touch the command
+ * structures except to process the reset request.
+ */
+ queue_remove_all_target(&info->queues.issue, target);
+ queue_remove_all_target(&info->queues.disconnected, target);
+ if (info->origSCpnt && info->origSCpnt->target == target)
+ info->origSCpnt = NULL;
+ if (info->reqSCpnt && info->reqSCpnt->target == target)
+ info->reqSCpnt = NULL;
+ for (i = 0; i < 8; i++)
+ clear_bit(target * 8 + i, info->busyluns);
- for (i = 0; i < 8; i++) {
- info->device[i].disconnect_ok = info->ifcfg.disconnect_ok;
- info->device[i].sync_state = sync_state;
- info->device[i].wide_state = wide_state;
- info->device[i].period = info->ifcfg.asyncperiod / 4;
- info->device[i].stp = info->scsi.async_stp;
- info->device[i].sof = 0;
- info->device[i].wide_xfer = 0;
- }
+ /*
+ * Hijack this SCSI command structure to send
+ * a bus device reset message to this device.
+ */
+ SCpnt->host_scribble = (void *)fas216_devicereset_done;
- /*
- * Drain all commands on disconnected queue
- */
- while (queue_remove(&info->queues.disconnected) != NULL);
+ info->rst_dev_status = 0;
+ info->rstSCpnt = SCpnt;
- /*
- * Remove executing commands.
- */
- info->SCpnt = NULL;
- info->reqSCpnt = NULL;
- info->origSCpnt = NULL;
-}
+ if (info->scsi.phase == PHASE_IDLE)
+ fas216_kick(info);
-/* Function: int fas216_eh_device_reset(Scsi_Cmnd *SCpnt)
- * Purpose : Reset the device associated with this command
- * Params : SCpnt - command specifing device to reset
- * Returns : FAILED if unable to reset
- */
-int fas216_eh_device_reset(Scsi_Cmnd *SCpnt)
-{
- FAS216_Info *info = (FAS216_Info *)SCpnt->host->hostdata;
+ mod_timer(&info->eh_timer, 30 * HZ);
+ spin_unlock_irqrestore(&info->host_lock, flags);
- printk("scsi%d.%c: %s: called\n",
- info->host->host_no, '0' + SCpnt->target, __FUNCTION__);
- return FAILED;
+ /*
+ * Wait up to 30 seconds for the reset to complete.
+ */
+ wait_event(info->eh_wait, info->rst_dev_status);
+
+ del_timer_sync(&info->eh_timer);
+ spin_lock_irqsave(&info->host_lock, flags);
+ info->rstSCpnt = NULL;
+
+ if (info->rst_dev_status == 1)
+ res = SUCCESS;
+ } while (0);
+
+ SCpnt->host_scribble = NULL;
+ spin_unlock_irqrestore(&info->host_lock, flags);
+
+ fas216_log(info, LOG_ERROR, "device reset complete: %s\n",
+ res == SUCCESS ? "success" : "failed");
+
+ return res;
}
/* Function: int fas216_eh_bus_reset(Scsi_Cmnd *SCpnt)
* Purpose : Reset the bus associated with the command
* Params : SCpnt - command specifing bus to reset
* Returns : FAILED if unable to reset
- * Notes : io_request_lock is taken, and irqs are disabled
+ * Notes : Further commands are blocked.
*/
int fas216_eh_bus_reset(Scsi_Cmnd *SCpnt)
{
FAS216_Info *info = (FAS216_Info *)SCpnt->host->hostdata;
- int result = FAILED;
+ unsigned long flags;
+ Scsi_Device *SDpnt;
fas216_checkmagic(info);
+ fas216_log(info, LOG_ERROR, "resetting bus");
info->stats.bus_resets += 1;
- printk("scsi%d.%c: %s: resetting bus\n",
- info->host->host_no, '0' + SCpnt->target, __FUNCTION__);
+ spin_lock_irqsave(&info->host_lock, flags);
/*
- * Attempt to stop all activity on this interface.
+ * Stop all activity on this interface.
*/
+ fas216_aborttransfer(info);
outb(info->scsi.cfg[2], REG_CNTL3(info));
- fas216_stoptransfer(info);
/*
- * Clear any pending interrupts
+ * Clear any pending interrupts.
*/
while (inb(REG_STAT(info)) & STAT_INT)
inb(REG_INST(info));
+ info->rst_bus_status = 0;
+
/*
- * Reset the SCSI bus
+ * For each attached hard-reset device, clear out
+ * all command structures. Leave the running
+ * command in place.
*/
- outb(CMD_RESETSCSI, REG_CMD(info));
- udelay(5);
+ for (SDpnt = info->host->host_queue; SDpnt; SDpnt = SDpnt->next) {
+ int i;
+
+ if (SDpnt->soft_reset)
+ continue;
+
+ queue_remove_all_target(&info->queues.issue, SDpnt->id);
+ queue_remove_all_target(&info->queues.disconnected, SDpnt->id);
+ if (info->origSCpnt && info->origSCpnt->target == SDpnt->id)
+ info->origSCpnt = NULL;
+ if (info->reqSCpnt && info->reqSCpnt->target == SDpnt->id)
+ info->reqSCpnt = NULL;
+ info->SCpnt = NULL;
+
+ for (i = 0; i < 8; i++)
+ clear_bit(SDpnt->id * 8 + i, info->busyluns);
+ }
/*
- * Clear reset interrupt
+ * Reset the SCSI bus. Device cleanup happens in
+ * the interrupt handler.
*/
- if (inb(REG_STAT(info)) & STAT_INT &&
- inb(REG_INST(info)) & INST_BUSRESET)
- result = SUCCESS;
+ fas216_cmd(info, CMD_RESETSCSI);
- fas216_reset_state(info);
+ mod_timer(&info->eh_timer, jiffies + HZ);
+ spin_unlock_irqrestore(&info->host_lock, flags);
- return result;
+ /*
+ * Wait one second for the interrupt.
+ */
+ wait_event(info->eh_wait, info->rst_bus_status);
+ del_timer_sync(&info->eh_timer);
+
+ fas216_log(info, LOG_ERROR, "bus reset complete: %s\n",
+ info->rst_bus_status == 1 ? "success" : "failed");
+
+ return info->rst_bus_status == 1 ? SUCCESS : FAILED;
}
/* Function: void fas216_init_chip(FAS216_Info *info)
@@ -2387,7 +2706,7 @@ int fas216_eh_host_reset(Scsi_Cmnd *SCpnt)
/*
* Reset the SCSI chip.
*/
- outb(CMD_RESETCHIP, REG_CMD(info));
+ fas216_cmd(info, CMD_RESETCHIP);
/*
* Ugly ugly ugly!
@@ -2396,13 +2715,13 @@ int fas216_eh_host_reset(Scsi_Cmnd *SCpnt)
* IRQs after the sleep.
*/
spin_unlock_irq(info->host->host_lock);
- scsi_sleep(25*HZ/100);
+ scsi_sleep(50 * HZ/100);
spin_lock_irq(info->host->host_lock);
/*
* Release the SCSI reset.
*/
- outb(CMD_NOP, REG_CMD(info));
+ fas216_cmd(info, CMD_NOP);
fas216_init_chip(info);
@@ -2509,6 +2828,44 @@ static int fas216_detect_type(FAS216_Info *info)
return TYPE_NCR53C9x;
}
+/* Function: void fas216_reset_state(FAS216_Info *info)
+ * Purpose : Initialise driver internal state
+ * Params : info - state to initialise
+ */
+static void fas216_reset_state(FAS216_Info *info)
+{
+ int i;
+
+ fas216_checkmagic(info);
+
+ fas216_bus_reset(info);
+
+ /*
+ * Clear out all stale info in our state structure
+ */
+ memset(info->busyluns, 0, sizeof(info->busyluns));
+ info->scsi.disconnectable = 0;
+ info->scsi.aborting = 0;
+
+ for (i = 0; i < 8; i++) {
+ info->device[i].parity_enabled = 0;
+ info->device[i].parity_check = 1;
+ }
+
+ /*
+ * Drain all commands on disconnected queue
+ */
+ while (queue_remove(&info->queues.disconnected) != NULL);
+
+ /*
+ * Remove executing commands.
+ */
+ info->SCpnt = NULL;
+ info->reqSCpnt = NULL;
+ info->rstSCpnt = NULL;
+ info->origSCpnt = NULL;
+}
+
/* Function: int fas216_init(struct Scsi_Host *instance)
* Purpose : initialise FAS/NCR/AMD SCSI ic.
* Params : instance - a driver-specific filled-out structure
@@ -2519,12 +2876,22 @@ int fas216_init(struct Scsi_Host *instance)
FAS216_Info *info = (FAS216_Info *)instance->hostdata;
int type;
- info->magic_start = MAGIC;
- info->magic_end = MAGIC;
- info->host = instance;
- info->scsi.cfg[0] = instance->this_id;
- info->scsi.cfg[1] = CNTL2_ENF | CNTL2_S2FE;
- info->scsi.cfg[2] = info->ifcfg.cntl3 | CNTL3_ADIDCHK | CNTL3_G2CB;
+ info->magic_start = MAGIC;
+ info->magic_end = MAGIC;
+ info->host = instance;
+ info->scsi.cfg[0] = instance->this_id | CNTL1_PERE;
+ info->scsi.cfg[1] = CNTL2_ENF | CNTL2_S2FE;
+ info->scsi.cfg[2] = info->ifcfg.cntl3 | CNTL3_ADIDCHK | CNTL3_G2CB;
+ info->scsi.async_stp = fas216_syncperiod(info, info->ifcfg.asyncperiod);
+
+ info->rst_dev_status = -1;
+ info->rst_bus_status = -1;
+ init_waitqueue_head(&info->eh_wait);
+ init_timer(&info->eh_timer);
+ info->eh_timer.data = (unsigned long)info;
+ info->eh_timer.function = fas216_eh_timer;
+
+ spin_lock_init(&info->host_lock);
memset(&info->stats, 0, sizeof(info->stats));
@@ -2561,7 +2928,7 @@ int fas216_init(struct Scsi_Host *instance)
* scsi standard says wait 250ms
*/
spin_unlock_irq(info->host->host_lock);
- scsi_sleep(25*HZ/100);
+ scsi_sleep(100*HZ/100);
spin_lock_irq(info->host->host_lock);
outb(info->scsi.cfg[0], REG_CNTL1(info));
@@ -2621,7 +2988,6 @@ int fas216_info(FAS216_Info *info, char *buffer)
int fas216_print_host(FAS216_Info *info, char *buffer)
{
-
return sprintf(buffer,
"\n"
"Chip : %s\n"
@@ -2634,8 +3000,9 @@ int fas216_print_host(FAS216_Info *info, char *buffer)
int fas216_print_stats(FAS216_Info *info, char *buffer)
{
- return sprintf(buffer,
- "\n"
+ char *p = buffer;
+
+ p += sprintf(p, "\n"
"Command Statistics:\n"
" Queued : %u\n"
" Issued : %u\n"
@@ -2652,6 +3019,8 @@ int fas216_print_stats(FAS216_Info *info, char *buffer)
info->stats.writes, info->stats.miscs,
info->stats.disconnects, info->stats.aborts,
info->stats.bus_resets, info->stats.host_resets);
+
+ return p - buffer;
}
int fas216_print_device(FAS216_Info *info, Scsi_Device *scd, char *buffer)
@@ -2670,7 +3039,9 @@ int fas216_print_device(FAS216_Info *info, Scsi_Device *scd, char *buffer)
scd->tagged_queue ? "en" : "dis",
scd->current_tag);
- p += sprintf(p, "\n Transfers : %d-bit ",
+ p += sprintf(p, "%s\n", dev->parity_enabled ? "parity" : "");
+
+ p += sprintf(p, " Transfers : %d-bit ",
8 << dev->wide_xfer);
if (dev->sof)
diff --git a/drivers/acorn/scsi/fas216.h b/drivers/acorn/scsi/fas216.h
index 7d11ef613dc2..6fa9cdd572a5 100644
--- a/drivers/acorn/scsi/fas216.h
+++ b/drivers/acorn/scsi/fas216.h
@@ -214,10 +214,22 @@ typedef enum {
typedef struct {
unsigned long magic_start;
+ spinlock_t host_lock;
struct Scsi_Host *host; /* host */
Scsi_Cmnd *SCpnt; /* currently processing command */
Scsi_Cmnd *origSCpnt; /* original connecting command */
Scsi_Cmnd *reqSCpnt; /* request sense command */
+ Scsi_Cmnd *rstSCpnt; /* reset command */
+ Scsi_Cmnd *pending_SCpnt[8]; /* per-device pending commands */
+ int next_pending; /* next pending device */
+
+ /*
+ * Error recovery
+ */
+ wait_queue_head_t eh_wait;
+ struct timer_list eh_timer;
+ unsigned int rst_dev_status;
+ unsigned int rst_bus_status;
/* driver information */
struct {
@@ -281,6 +293,8 @@ typedef struct {
/* per-device info */
struct fas216_device {
unsigned char disconnect_ok:1; /* device can disconnect */
+ unsigned char parity_enabled:1; /* parity checking enabled */
+ unsigned char parity_check:1; /* need to check parity checking */
unsigned char period; /* sync xfer period in (*4ns) */
unsigned char stp; /* synchronous transfer period */
unsigned char sof; /* synchronous offset register */
diff --git a/drivers/acorn/scsi/oak.c b/drivers/acorn/scsi/oak.c
index 922deb68a7cf..b415da7bfff6 100644
--- a/drivers/acorn/scsi/oak.c
+++ b/drivers/acorn/scsi/oak.c
@@ -1,55 +1,14 @@
-#define AUTOSENSE
-/*#define PSEUDO_DMA*/
-
/*
* Oak Generic NCR5380 driver
*
- * Copyright 1995, Russell King
- *
- * ALPHA RELEASE 1.
- *
- * For more information, please consult
- *
- * NCR 5380 Family
- * SCSI Protocol Controller
- * Databook
- *
- * NCR Microelectronics
- * 1635 Aeroplaza Drive
- * Colorado Springs, CO 80916
- * 1+ (719) 578-3400
- * 1+ (800) 334-5454
- */
-
-/*
- * Options :
- *
- * PARITY - enable parity checking. Not supported.
- *
- * SCSI2 - enable support for SCSI-II tagged queueing. Untested.
- *
- * USLEEP - enable support for devices that don't disconnect. Untested.
- */
-
-/*
- * $Log: oak.c,v $
- * Revision 1.3 1998/05/03 20:45:37 alan
- * ARM SCSI update. This adds the eesox driver and massively updates the
- * Cumana driver. The folks who bought cumana arent anal retentive all
- * docs are secret weenies so now there are docs ..
- *
- * Revision 1.2 1998/03/08 05:49:48 davem
- * Merge to 2.1.89
- *
- * Revision 1.1 1998/02/23 02:45:27 davem
- * Merge to 2.1.88
- *
+ * Copyright 1995-2002, Russell King
*/
#include <linux/module.h>
#include <linux/signal.h>
#include <linux/sched.h>
#include <linux/ioport.h>
+#include <linux/delay.h>
#include <linux/blk.h>
#include <linux/init.h>
@@ -60,6 +19,9 @@
#include "../../scsi/scsi.h"
#include "../../scsi/hosts.h"
+#define AUTOSENSE
+/*#define PSEUDO_DMA*/
+
#define OAKSCSI_PUBLIC_RELEASE 1
#define NCR5380_read(reg) oakscsi_read(_instance, reg)
@@ -71,14 +33,9 @@
int NCR5380_proc_info(char *buffer, char **start, off_t offset,
int length, int hostno, int inout);
-#define NCR5380_implementation_fields \
- int port, ctrl
-
-#define NCR5380_local_declare() \
- struct Scsi_Host *_instance
-
-#define NCR5380_setup(instance) \
- _instance = instance
+#define NCR5380_implementation_fields int port, ctrl
+#define NCR5380_local_declare() struct Scsi_Host *_instance
+#define NCR5380_setup(instance) _instance = instance
#define BOARD_NORMAL 0
#define BOARD_NCR53C400 1
@@ -88,106 +45,9 @@ int NCR5380_proc_info(char *buffer, char **start, off_t offset,
#undef START_DMA_INITIATOR_RECEIVE_REG
#define START_DMA_INITIATOR_RECEIVE_REG (7 + 128)
-static const card_ids oakscsi_cids[] = {
- { MANU_OAK, PROD_OAK_SCSI },
- { 0xffff, 0xffff }
-};
-
-#define OAK_ADDRESS(card) (ecard_address((card), ECARD_MEMC, 0))
-#define OAK_IRQ(card) (IRQ_NONE)
-/*
- * Function : int oakscsi_detect(Scsi_Host_Template * tpnt)
- *
- * Purpose : initializes oak NCR5380 driver based on the
- * command line / compile time port and irq definitions.
- *
- * Inputs : tpnt - template for this SCSI adapter.
- *
- * Returns : 1 if a host adapter was found, 0 if not.
- *
- */
-static struct expansion_card *ecs[4];
-
-int oakscsi_detect(Scsi_Host_Template * tpnt)
-{
- int count = 0;
- struct Scsi_Host *instance;
-
- tpnt->proc_name = "oakscsi";
-
- memset (ecs, 0, sizeof (ecs));
-
- ecard_startfind ();
-
- while(1) {
- if ((ecs[count] = ecard_find(0, oakscsi_cids)) == NULL)
- break;
-
- instance = scsi_register (tpnt, sizeof(struct NCR5380_hostdata));
- if (!instance)
- break;
- instance->io_port = OAK_ADDRESS(ecs[count]);
- instance->irq = OAK_IRQ(ecs[count]);
-
- NCR5380_init(instance, 0);
- ecard_claim(ecs[count]);
-
- instance->n_io_port = 255;
- if (!request_region (instance->io_port, instance->n_io_port, "Oak SCSI")) {
- ecard_release(ecs[count]);
- scsi_unregister(instance);
- break;
- }
-
- if (instance->irq != IRQ_NONE)
- if (request_irq(instance->irq, oakscsi_intr, SA_INTERRUPT, "Oak SCSI", NULL)) {
- printk("scsi%d: IRQ%d not free, interrupts disabled\n",
- instance->host_no, instance->irq);
- instance->irq = IRQ_NONE;
- }
-
- if (instance->irq != IRQ_NONE) {
- printk("scsi%d: eek! Interrupts enabled, but I don't think\n", instance->host_no);
- printk("scsi%d: that the board had an interrupt!\n", instance->host_no);
- }
-
- printk("scsi%d: at port %lX irq", instance->host_no, instance->io_port);
- if (instance->irq == IRQ_NONE)
- printk ("s disabled");
- else
- printk (" %d", instance->irq);
- printk(" options CAN_QUEUE=%d CMD_PER_LUN=%d release=%d",
- tpnt->can_queue, tpnt->cmd_per_lun, OAKSCSI_PUBLIC_RELEASE);
- printk("\nscsi%d:", instance->host_no);
- NCR5380_print_options(instance);
- printk("\n");
-
- ++count;
- }
-#ifdef MODULE
- if(count == 0)
- printk("No oak scsi devices found\n");
-#endif
- return count;
-}
-
-int oakscsi_release (struct Scsi_Host *shpnt)
+const char * oakscsi_info (struct Scsi_Host *spnt)
{
- int i;
-
- if (shpnt->irq != IRQ_NONE)
- free_irq (shpnt->irq, NULL);
- if (shpnt->io_port)
- release_region (shpnt->io_port, shpnt->n_io_port);
-
- for (i = 0; i < 4; i++)
- if (shpnt->io_port == OAK_ADDRESS(ecs[i]))
- ecard_release (ecs[i]);
- return 0;
-}
-
-const char * oakscsi_info (struct Scsi_Host *spnt) {
- return "";
+ return "";
}
#define STAT(p) inw(p + 144)
@@ -255,37 +115,95 @@ printk("reading %p len %d\n", addr, len);
#include "../../scsi/NCR5380.c"
static Scsi_Host_Template oakscsi_template = {
- .module = THIS_MODULE,
- .proc_info = oakscsi_proc_info,
- .name = "Oak 16-bit SCSI",
- .detect = oakscsi_detect,
- .release = oakscsi_release,
- .info = oakscsi_info,
- .queuecommand = oakscsi_queue_command,
+ .module = THIS_MODULE,
+ .proc_info = oakscsi_proc_info,
+ .name = "Oak 16-bit SCSI",
+ .info = oakscsi_info,
+ .queuecommand = oakscsi_queue_command,
.eh_abort_handler = NCR5380_abort,
.eh_device_reset_handler= NCR5380_device_reset,
.eh_bus_reset_handler = NCR5380_bus_reset,
.eh_host_reset_handler = NCR5380_host_reset,
- .can_queue = 16,
- .this_id = 7,
- .sg_tablesize = SG_ALL,
- .cmd_per_lun = 2,
- .use_clustering = DISABLE_CLUSTERING
+ .can_queue = 16,
+ .this_id = 7,
+ .sg_tablesize = SG_ALL,
+ .cmd_per_lun = 2,
+ .use_clustering = DISABLE_CLUSTERING,
+ .proc_name = "oakscsi",
};
-static int __init oakscsi_init(void)
+static int __devinit
+oakscsi_probe(struct expansion_card *ec, const struct ecard_id *id)
+{
+ struct Scsi_Host *host;
+ int ret = -ENOMEM;
+
+ host = scsi_register (tpnt, sizeof(struct NCR5380_hostdata));
+ if (!host)
+ goto out;
+
+ host->io_port = ecard_address(ec, ECARD_MEMC, 0)
+ host->irq = IRQ_NONE;
+ host->n_io_port = 255;
+
+ ret = -EBUSY;
+ if (!request_region (host->io_port, host->n_io_port, "Oak SCSI"))
+ goto unreg;
+
+ NCR5380_init(host, 0);
+
+ printk("scsi%d: at port 0x%08lx irqs disabled",
+ host->host_no, host->io_port);
+ printk(" options CAN_QUEUE=%d CMD_PER_LUN=%d release=%d",
+ tpnt->can_queue, tpnt->cmd_per_lun, OAKSCSI_PUBLIC_RELEASE);
+ printk("\nscsi%d:", host->host_no);
+ NCR5380_print_options(host);
+ printk("\n");
+
+ ret = scsi_add_host(host);
+ if (ret == 0)
+ goto out;
+
+ release_region(host->io_port, host->n_io_port);
+ unreg:
+ scsi_unregister(host);
+ out:
+ return ret;
+}
+
+static void __devexit oakscsi_remove(struct expansion_card *ec)
{
- scsi_register_host(&oakscsi_template);
- if (oakscsi_template.present)
- return 0;
+ struct Scsi_Host *host = ecard_get_drvdata(ec);
+
+ ecard_set_drvdata(ec, NULL);
+ scsi_remove_host(host);
+
+ release_region(host->io_port, host->n_io_port);
+ scsi_unregister(host);
+}
+
+static const struct ecard_id oakscsi_cids[] = {
+ { MANU_OAK, PROD_OAK_SCSI },
+ { 0xffff, 0xffff }
+};
- scsi_unregister_host(&oakscsi_template);
- return -ENODEV;
+static struct ecard_driver oakscsi_driver = {
+ .probe = oakscsi_probe,
+ .remove = __devexit_p(oakscsi_remove),
+ .id_table = oakscsi_cids,
+ .drv = {
+ .name = "oakscsi",
+ },
+};
+
+static int __init oakscsi_init(void)
+{
+ return ecard_register_driver(&oakscsi_driver);
}
static void __exit oakscsi_exit(void)
{
- scsi_unregister_host(&oakscsi_template);
+ ecard_remove_driver(&oakscsi_driver);
}
module_init(oakscsi_init);
diff --git a/drivers/acorn/scsi/powertec.c b/drivers/acorn/scsi/powertec.c
index 2f6fd8885a3d..ab5907151d68 100644
--- a/drivers/acorn/scsi/powertec.c
+++ b/drivers/acorn/scsi/powertec.c
@@ -1,23 +1,11 @@
/*
* linux/drivers/acorn/scsi/powertec.c
*
- * Copyright (C) 1997-2000 Russell King
+ * Copyright (C) 1997-2002 Russell King
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
- *
- * This driver is based on experimentation. Hence, it may have made
- * assumptions about the particular card that I have available, and
- * may not be reliable!
- *
- * Changelog:
- * 01-10-1997 RMK Created, READONLY version.
- * 15-02-1998 RMK Added DMA support and hardware definitions.
- * 15-04-1998 RMK Only do PIO if FAS216 will allow it.
- * 02-05-1998 RMK Moved DMA sg list into per-interface structure.
- * 27-06-1998 RMK Changed asm/delay.h to linux/delay.h
- * 02-04-2000 RMK Updated for new error handling code.
*/
#include <linux/module.h>
#include <linux/blk.h>
@@ -45,18 +33,9 @@
#include <scsi/scsicam.h>
-/* Configuration */
-#define POWERTEC_XTALFREQ 40
-#define POWERTEC_ASYNC_PERIOD 200
-#define POWERTEC_SYNC_DEPTH 7
-
-/*
- * List of devices that the driver will recognise
- */
-#define POWERTECSCSI_LIST { MANU_ALSYSTEMS, PROD_ALSYS_SCSIATAPI }
-
#define POWERTEC_FAS216_OFFSET 0xc00
#define POWERTEC_FAS216_SHIFT 4
+#define POWERTEC_FAS216_SIZE (16 << POWERTEC_FAS216_SHIFT)
#define POWERTEC_INTR_STATUS 0x800
#define POWERTEC_INTR_BIT 0x80
@@ -71,33 +50,22 @@
#define POWERTEC_INTR_ENABLE 1
#define POWERTEC_INTR_DISABLE 0
-/*
- * Version
- */
-#define VER_MAJOR 0
-#define VER_MINOR 0
-#define VER_PATCH 5
-
-static struct expansion_card *ecs[MAX_ECARDS];
+#define VERSION "1.00 (13/11/2002 2.5.47)"
/*
- * Use term=0,1,0,0,0 to turn terminators on/off
+ * Use term=0,1,0,0,0 to turn terminators on/off.
+ * One entry per slot.
*/
static int term[MAX_ECARDS] = { 1, 1, 1, 1, 1, 1, 1, 1 };
#define NR_SG 256
-typedef struct {
- FAS216_Info info;
-
- struct {
- unsigned int term_port;
- unsigned int terms;
- } control;
-
- /* other info... */
- struct scatterlist sg[NR_SG]; /* Scatter DMA list */
-} PowerTecScsi_Info;
+struct powertec_info {
+ FAS216_Info info;
+ unsigned int term_port;
+ unsigned int term_ctl;
+ struct scatterlist sg[NR_SG];
+};
/* Prototype: void powertecscsi_irqenable(ec, irqnr)
* Purpose : Enable interrupts on Powertec SCSI card
@@ -124,12 +92,8 @@ powertecscsi_irqdisable(struct expansion_card *ec, int irqnr)
}
static const expansioncard_ops_t powertecscsi_ops = {
- powertecscsi_irqenable,
- powertecscsi_irqdisable,
- NULL,
- NULL,
- NULL,
- NULL
+ .irqenable = powertecscsi_irqenable,
+ .irqdisable = powertecscsi_irqdisable,
};
/* Prototype: void powertecscsi_terminator_ctl(host, on_off)
@@ -140,14 +104,10 @@ static const expansioncard_ops_t powertecscsi_ops = {
static void
powertecscsi_terminator_ctl(struct Scsi_Host *host, int on_off)
{
- PowerTecScsi_Info *info = (PowerTecScsi_Info *)host->hostdata;
-
- if (on_off)
- info->control.terms = POWERTEC_TERM_ENABLE;
- else
- info->control.terms = 0;
+ struct powertec_info *info = (struct powertec_info *)host->hostdata;
- outb(info->control.terms, info->control.term_port);
+ info->term_ctl = on_off ? POWERTEC_TERM_ENABLE : 0;
+ outb(info->term_ctl, info->term_port);
}
/* Prototype: void powertecscsi_intr(irq, *dev_id, *regs)
@@ -176,7 +136,7 @@ static fasdmatype_t
powertecscsi_dma_setup(struct Scsi_Host *host, Scsi_Pointer *SCp,
fasdmadir_t direction, fasdmatype_t min_type)
{
- PowerTecScsi_Info *info = (PowerTecScsi_Info *)host->hostdata;
+ struct powertec_info *info = (struct powertec_info *)host->hostdata;
int dmach = host->dma_channel;
if (dmach != NO_DMA &&
@@ -220,122 +180,6 @@ powertecscsi_dma_stop(struct Scsi_Host *host, Scsi_Pointer *SCp)
disable_dma(host->dma_channel);
}
-/* Prototype: int powertecscsi_detect(Scsi_Host_Template * tpnt)
- * Purpose : initialises PowerTec SCSI driver
- * Params : tpnt - template for this SCSI adapter
- * Returns : >0 if host found, 0 otherwise.
- */
-int
-powertecscsi_detect(Scsi_Host_Template *tpnt)
-{
- static const card_ids powertecscsi_cids[] =
- { POWERTECSCSI_LIST, { 0xffff, 0xffff} };
- int count = 0;
- struct Scsi_Host *host;
-
- tpnt->proc_name = "powertec";
- memset(ecs, 0, sizeof (ecs));
-
- ecard_startfind();
-
- while (1) {
- PowerTecScsi_Info *info;
-
- ecs[count] = ecard_find(0, powertecscsi_cids);
- if (!ecs[count])
- break;
-
- ecard_claim(ecs[count]);
-
- host = scsi_register(tpnt, sizeof (PowerTecScsi_Info));
- if (!host) {
- ecard_release(ecs[count]);
- break;
- }
-
- host->io_port = ecard_address(ecs[count], ECARD_IOC, ECARD_FAST);
- host->irq = ecs[count]->irq;
- host->dma_channel = ecs[count]->dma;
- info = (PowerTecScsi_Info *)host->hostdata;
-
- if (host->dma_channel != NO_DMA)
- set_dma_speed(host->dma_channel, 180);
-
- info->control.term_port = host->io_port + POWERTEC_TERM_CONTROL;
- info->control.terms = term[count] ? POWERTEC_TERM_ENABLE : 0;
- powertecscsi_terminator_ctl(host, info->control.terms);
-
- info->info.scsi.io_port =
- host->io_port + POWERTEC_FAS216_OFFSET;
- info->info.scsi.io_shift= POWERTEC_FAS216_SHIFT;
- info->info.scsi.irq = host->irq;
- info->info.ifcfg.clockrate = POWERTEC_XTALFREQ;
- info->info.ifcfg.select_timeout = 255;
- info->info.ifcfg.asyncperiod = POWERTEC_ASYNC_PERIOD;
- info->info.ifcfg.sync_max_depth = POWERTEC_SYNC_DEPTH;
- info->info.ifcfg.cntl3 = CNTL3_BS8 | CNTL3_FASTSCSI | CNTL3_FASTCLK;
- info->info.ifcfg.disconnect_ok = 1;
- info->info.ifcfg.wide_max_size = 0;
- info->info.dma.setup = powertecscsi_dma_setup;
- info->info.dma.pseudo = NULL;
- info->info.dma.stop = powertecscsi_dma_stop;
-
- ecs[count]->irqaddr = (unsigned char *)
- ioaddr(host->io_port + POWERTEC_INTR_STATUS);
- ecs[count]->irqmask = POWERTEC_INTR_BIT;
- ecs[count]->irq_data = (void *)
- (host->io_port + POWERTEC_INTR_CONTROL);
- ecs[count]->ops = (expansioncard_ops_t *)&powertecscsi_ops;
-
- request_region(host->io_port + POWERTEC_FAS216_OFFSET,
- 16 << POWERTEC_FAS216_SHIFT, "powertec2-fas");
-
- if (host->irq != NO_IRQ &&
- request_irq(host->irq, powertecscsi_intr,
- SA_INTERRUPT, "powertec", host)) {
- printk("scsi%d: IRQ%d not free, interrupts disabled\n",
- host->host_no, host->irq);
- host->irq = NO_IRQ;
- info->info.scsi.irq = NO_IRQ;
- }
-
- if (host->dma_channel != NO_DMA &&
- request_dma(host->dma_channel, "powertec")) {
- printk("scsi%d: DMA%d not free, DMA disabled\n",
- host->host_no, host->dma_channel);
- host->dma_channel = NO_DMA;
- }
-
- fas216_init(host);
- ++count;
- }
- return count;
-}
-
-/* Prototype: int powertecscsi_release(struct Scsi_Host * host)
- * Purpose : releases all resources used by this adapter
- * Params : host - driver host structure to return info for.
- */
-int powertecscsi_release(struct Scsi_Host *host)
-{
- int i;
-
- fas216_release(host);
-
- if (host->irq != NO_IRQ)
- free_irq(host->irq, host);
- if (host->dma_channel != NO_DMA)
- free_dma(host->dma_channel);
- release_region(host->io_port + POWERTEC_FAS216_OFFSET,
- 16 << POWERTEC_FAS216_SHIFT);
-
- for (i = 0; i < MAX_ECARDS; i++)
- if (ecs[i] &&
- host->io_port == ecard_address(ecs[i], ECARD_IOC, ECARD_FAST))
- ecard_release(ecs[i]);
- return 0;
-}
-
/* Prototype: const char *powertecscsi_info(struct Scsi_Host * host)
* Purpose : returns a descriptive string about this interface,
* Params : host - driver host structure to return info for.
@@ -343,15 +187,14 @@ int powertecscsi_release(struct Scsi_Host *host)
*/
const char *powertecscsi_info(struct Scsi_Host *host)
{
- PowerTecScsi_Info *info = (PowerTecScsi_Info *)host->hostdata;
+ struct powertec_info *info = (struct powertec_info *)host->hostdata;
static char string[100], *p;
p = string;
p += sprintf(p, "%s ", host->hostt->name);
p += fas216_info(&info->info, p);
- p += sprintf(p, "v%d.%d.%d terminators o%s",
- VER_MAJOR, VER_MINOR, VER_PATCH,
- info->control.terms ? "n" : "ff");
+ p += sprintf(p, "v%s terminators o%s",
+ VERSION, info->term_ctl ? "n" : "ff");
return string;
}
@@ -405,7 +248,7 @@ int powertecscsi_proc_info(char *buffer, char **start, off_t offset,
{
int pos, begin;
struct Scsi_Host *host;
- PowerTecScsi_Info *info;
+ struct powertec_info *info;
Scsi_Device *scd;
host = scsi_host_hn_get(host_no);
@@ -415,16 +258,14 @@ int powertecscsi_proc_info(char *buffer, char **start, off_t offset,
if (inout == 1)
return powertecscsi_set_proc_info(host, buffer, length);
- info = (PowerTecScsi_Info *)host->hostdata;
+ info = (struct powertec_info *)host->hostdata;
begin = 0;
- pos = sprintf(buffer,
- "PowerTec SCSI driver version %d.%d.%d\n",
- VER_MAJOR, VER_MINOR, VER_PATCH);
+ pos = sprintf(buffer, "PowerTec SCSI driver v%s\n", VERSION);
pos += fas216_print_host(&info->info, buffer + pos);
pos += sprintf(buffer + pos, "Term : o%s\n",
- info->control.terms ? "n" : "ff");
+ info->term_ctl ? "n" : "ff");
pos += fas216_print_stats(&info->info, buffer + pos);
@@ -453,35 +294,147 @@ static Scsi_Host_Template powertecscsi_template = {
.module = THIS_MODULE,
.proc_info = powertecscsi_proc_info,
.name = "PowerTec SCSI",
- .detect = powertecscsi_detect,
- .release = powertecscsi_release,
.info = powertecscsi_info,
- .can_queue = 1,
- .this_id = 7,
- .sg_tablesize = SG_ALL,
- .cmd_per_lun = 1,
- .use_clustering = ENABLE_CLUSTERING,
.command = fas216_command,
.queuecommand = fas216_queue_command,
.eh_host_reset_handler = fas216_eh_host_reset,
.eh_bus_reset_handler = fas216_eh_bus_reset,
.eh_device_reset_handler = fas216_eh_device_reset,
.eh_abort_handler = fas216_eh_abort,
+
+ .can_queue = 1,
+ .this_id = 7,
+ .sg_tablesize = SG_ALL,
+ .cmd_per_lun = 1,
+ .use_clustering = ENABLE_CLUSTERING,
+ .proc_name = "powertec",
};
-static int __init powertecscsi_init(void)
+static int __devinit
+powertecscsi_probe(struct expansion_card *ec, const struct ecard_id *id)
{
- scsi_register_host(&powertecscsi_template);
- if (powertecscsi_template.present)
- return 0;
+ struct Scsi_Host *host;
+ struct powertec_info *info;
+ int ret = -ENOMEM;
+
+ host = scsi_register(&powertecscsi_template,
+ sizeof (struct powertec_info));
+ if (!host)
+ goto out;
+
+ host->io_port = ecard_address(ec, ECARD_IOC, ECARD_FAST);
+ host->irq = ec->irq;
+ host->dma_channel = ec->dma;
+
+ if (!request_region(host->io_port + POWERTEC_FAS216_OFFSET,
+ POWERTEC_FAS216_SIZE, "powertec2-fas")) {
+ ret = -EBUSY;
+ goto out_free;
+ }
+
+ ec->irqaddr = (unsigned char *)
+ ioaddr(host->io_port + POWERTEC_INTR_STATUS);
+ ec->irqmask = POWERTEC_INTR_BIT;
+ ec->irq_data = (void *)(host->io_port + POWERTEC_INTR_CONTROL);
+ ec->ops = (expansioncard_ops_t *)&powertecscsi_ops;
+
+ ecard_set_drvdata(ec, host);
+
+ info = (struct powertec_info *)host->hostdata;
+ info->term_port = host->io_port + POWERTEC_TERM_CONTROL;
+ powertecscsi_terminator_ctl(host, term[ec->slot_no]);
+
+ info->info.scsi.io_port = host->io_port + POWERTEC_FAS216_OFFSET;
+ info->info.scsi.io_shift = POWERTEC_FAS216_SHIFT;
+ info->info.scsi.irq = host->irq;
+ info->info.ifcfg.clockrate = 40; /* MHz */
+ info->info.ifcfg.select_timeout = 255;
+ info->info.ifcfg.asyncperiod = 200; /* ns */
+ info->info.ifcfg.sync_max_depth = 7;
+ info->info.ifcfg.cntl3 = CNTL3_BS8 | CNTL3_FASTSCSI | CNTL3_FASTCLK;
+ info->info.ifcfg.disconnect_ok = 1;
+ info->info.ifcfg.wide_max_size = 0;
+ info->info.dma.setup = powertecscsi_dma_setup;
+ info->info.dma.pseudo = NULL;
+ info->info.dma.stop = powertecscsi_dma_stop;
+
+ ret = request_irq(host->irq, powertecscsi_intr,
+ SA_INTERRUPT, "powertec", host);
+ if (ret) {
+ printk("scsi%d: IRQ%d not free: %d\n",
+ host->host_no, host->irq, ret);
+ goto out_region;
+ }
+
+ if (host->dma_channel != NO_DMA) {
+ if (request_dma(host->dma_channel, "powertec")) {
+ printk("scsi%d: DMA%d not free, using PIO\n",
+ host->host_no, host->dma_channel);
+ host->dma_channel = NO_DMA;
+ } else {
+ set_dma_speed(host->dma_channel, 180);
+ }
+ }
+
+ fas216_init(host);
- scsi_unregister_host(&powertecscsi_template);
- return -ENODEV;
+ ret = scsi_add_host(host);
+ if (ret == 0)
+ goto out;
+
+ fas216_release(host);
+
+ if (host->dma_channel != NO_DMA)
+ free_dma(host->dma_channel);
+ free_irq(host->irq, host);
+ out_region:
+ release_region(host->io_port + POWERTEC_FAS216_OFFSET,
+ POWERTEC_FAS216_SIZE);
+ out_free:
+ scsi_unregister(host);
+
+ out:
+ return ret;
+}
+
+static void __devexit powertecscsi_remove(struct expansion_card *ec)
+{
+ struct Scsi_Host *host = ecard_get_drvdata(ec);
+
+ ecard_set_drvdata(ec, NULL);
+ scsi_remove_host(host);
+ fas216_release(host);
+
+ if (host->dma_channel != NO_DMA)
+ free_dma(host->dma_channel);
+ free_irq(host->irq, host);
+ release_region(host->io_port + POWERTEC_FAS216_OFFSET,
+ POWERTEC_FAS216_SIZE);
+ scsi_unregister(host);
+}
+
+static const struct ecard_id powertecscsi_cids[] = {
+ { MANU_ALSYSTEMS, PROD_ALSYS_SCSIATAPI },
+ { 0xffff, 0xffff },
+};
+
+static struct ecard_driver powertecscsi_driver = {
+ .probe = powertecscsi_probe,
+ .remove = __devexit_p(powertecscsi_remove),
+ .id_table = powertecscsi_cids,
+ .drv = {
+ .name = "powertecscsi",
+ },
+};
+
+static int __init powertecscsi_init(void)
+{
+ return ecard_register_driver(&powertecscsi_driver);
}
static void __exit powertecscsi_exit(void)
{
- scsi_unregister_host(&powertecscsi_template);
+ ecard_remove_driver(&powertecscsi_driver);
}
module_init(powertecscsi_init);
@@ -492,4 +445,3 @@ MODULE_DESCRIPTION("Powertec SCSI driver");
MODULE_PARM(term, "1-8i");
MODULE_PARM_DESC(term, "SCSI bus termination");
MODULE_LICENSE("GPL");
-
diff --git a/drivers/acorn/scsi/queue.c b/drivers/acorn/scsi/queue.c
index 82e247e1fb16..b7e585490122 100644
--- a/drivers/acorn/scsi/queue.c
+++ b/drivers/acorn/scsi/queue.c
@@ -229,6 +229,27 @@ Scsi_Cmnd *queue_remove_tgtluntag (Queue_t *queue, int target, int lun, int tag)
}
/*
+ * Function: queue_remove_all_target(queue, target)
+ * Purpose : remove all SCSI commands from the queue for a specified target
+ * Params : queue - queue to remove command from
+ * target - target device id
+ * Returns : nothing
+ */
+void queue_remove_all_target(Queue_t *queue, int target)
+{
+ unsigned long flags;
+ struct list_head *l;
+
+ spin_lock_irqsave(&queue->queue_lock, flags);
+ list_for_each(l, &queue->head) {
+ QE_t *q = list_entry(l, QE_t, list);
+ if (q->SCpnt->target == target)
+ __queue_remove(queue, l);
+ }
+ spin_unlock_irqrestore(&queue->queue_lock, flags);
+}
+
+/*
* Function: int queue_probetgtlun (queue, target, lun)
* Purpose : check to see if we have a command in the queue for the specified
* target/lun.
@@ -290,6 +311,7 @@ EXPORT_SYMBOL(queue_remove);
EXPORT_SYMBOL(queue_remove_exclude);
EXPORT_SYMBOL(queue_remove_tgtluntag);
EXPORT_SYMBOL(queue_remove_cmd);
+EXPORT_SYMBOL(queue_remove_all_target);
EXPORT_SYMBOL(queue_probetgtlun);
MODULE_AUTHOR("Russell King");
diff --git a/drivers/acorn/scsi/queue.h b/drivers/acorn/scsi/queue.h
index 508b42ec7a1e..0c9dec4c1716 100644
--- a/drivers/acorn/scsi/queue.h
+++ b/drivers/acorn/scsi/queue.h
@@ -74,6 +74,15 @@ extern int __queue_add(Queue_t *queue, Scsi_Cmnd *SCpnt, int head);
extern Scsi_Cmnd *queue_remove_tgtluntag (Queue_t *queue, int target, int lun, int tag);
/*
+ * Function: queue_remove_all_target(queue, target)
+ * Purpose : remove all SCSI commands from the queue for a specified target
+ * Params : queue - queue to remove command from
+ * target - target device id
+ * Returns : nothing
+ */
+extern void queue_remove_all_target(Queue_t *queue, int target);
+
+/*
* Function: int queue_probetgtlun (queue, target, lun)
* Purpose : check to see if we have a command in the queue for the specified
* target/lun.
diff --git a/drivers/char/raw.c b/drivers/char/raw.c
index 0b79a7605bb5..3cdd71e836d0 100644
--- a/drivers/char/raw.c
+++ b/drivers/char/raw.c
@@ -15,6 +15,7 @@
#include <linux/module.h>
#include <linux/raw.h>
#include <linux/capability.h>
+#include <linux/uio.h>
#include <asm/uaccess.h>
diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c
index adc5ed2942f5..52248c5e2bf5 100644
--- a/drivers/pci/setup-bus.c
+++ b/drivers/pci/setup-bus.c
@@ -105,7 +105,7 @@ pci_setup_bridge(struct pci_bus *bus)
pcibios_fixup_pbus_ranges(bus, &ranges);
DBGC((KERN_INFO "PCI: Bus %d, bridge: %s\n",
- bus->number, bridge->name));
+ bus->number, bridge->dev.name));
/* Set up the top and bottom of the PCI I/O segment for this bus. */
if (bus->resource[0]->flags & IORESOURCE_IO) {
diff --git a/drivers/pcmcia/i82092.c b/drivers/pcmcia/i82092.c
index 28f30334a398..153c70fc982b 100644
--- a/drivers/pcmcia/i82092.c
+++ b/drivers/pcmcia/i82092.c
@@ -15,6 +15,7 @@
#include <linux/pci.h>
#include <linux/init.h>
#include <linux/workqueue.h>
+#include <linux/interrupt.h>
#include <pcmcia/cs_types.h>
#include <pcmcia/ss.h>
diff --git a/drivers/pcmcia/i82365.c b/drivers/pcmcia/i82365.c
index ba1e22985ba8..8c2cd91ad6c3 100644
--- a/drivers/pcmcia/i82365.c
+++ b/drivers/pcmcia/i82365.c
@@ -47,6 +47,7 @@
#include <linux/delay.h>
#include <linux/proc_fs.h>
#include <linux/workqueue.h>
+#include <linux/interrupt.h>
#include <asm/irq.h>
#include <asm/io.h>
#include <asm/bitops.h>
@@ -76,12 +77,12 @@ static const char *version =
#define DEBUG(n, args...) do { } while (0)
#endif
-static void irq_count(int, void *, struct pt_regs *);
+static void i365_count_irq(int, void *, struct pt_regs *);
static inline int _check_irq(int irq, int flags)
{
- if (request_irq(irq, irq_count, flags, "x", irq_count) != 0)
+ if (request_irq(irq, i365_count_irq, flags, "x", i365_count_irq) != 0)
return -1;
- free_irq(irq, irq_count);
+ free_irq(irq, i365_count_irq);
return 0;
}
@@ -533,7 +534,7 @@ static u_int __init set_bridge_opts(u_short s, u_short ns)
static volatile u_int irq_hits;
static u_short irq_sock;
-static void irq_count(int irq, void *dev, struct pt_regs *regs)
+static void i365_count_irq(int irq, void *dev, struct pt_regs *regs)
{
i365_get(irq_sock, I365_CSC);
irq_hits++;
@@ -543,13 +544,13 @@ static void irq_count(int irq, void *dev, struct pt_regs *regs)
static u_int __init test_irq(u_short sock, int irq)
{
DEBUG(2, " testing ISA irq %d\n", irq);
- if (request_irq(irq, irq_count, 0, "scan", irq_count) != 0)
+ if (request_irq(irq, i365_count_irq, 0, "scan", i365_count_irq) != 0)
return 1;
irq_hits = 0; irq_sock = sock;
__set_current_state(TASK_UNINTERRUPTIBLE);
schedule_timeout(HZ/100);
if (irq_hits) {
- free_irq(irq, irq_count);
+ free_irq(irq, i365_count_irq);
DEBUG(2, " spurious hit!\n");
return 1;
}
@@ -559,7 +560,7 @@ static u_int __init test_irq(u_short sock, int irq)
i365_bset(sock, I365_GENCTL, I365_CTL_SW_IRQ);
udelay(1000);
- free_irq(irq, irq_count);
+ free_irq(irq, i365_count_irq);
/* mask all interrupts */
i365_set(sock, I365_CSCINT, 0);
diff --git a/fs/autofs/autofs_i.h b/fs/autofs/autofs_i.h
index b448e1f5a32f..67365387c9ae 100644
--- a/fs/autofs/autofs_i.h
+++ b/fs/autofs/autofs_i.h
@@ -25,6 +25,7 @@
#include <linux/wait.h>
#include <linux/dcache.h>
#include <linux/namei.h>
+#include <linux/mount.h>
#include <asm/uaccess.h>
#ifdef DEBUG
diff --git a/fs/lockd/mon.c b/fs/lockd/mon.c
index 4b916a21da80..9875e30ec594 100644
--- a/fs/lockd/mon.c
+++ b/fs/lockd/mon.c
@@ -135,16 +135,12 @@ out_destroy:
* XDR functions for NSM.
*/
-static int
-xdr_encode_mon(struct rpc_rqst *rqstp, u32 *p, struct nsm_args *argp)
+static u32 *
+xdr_encode_common(struct rpc_rqst *rqstp, u32 *p, struct nsm_args *argp)
{
char buffer[20];
u32 addr = ntohl(argp->addr);
- dprintk("nsm: xdr_encode_mon(%08x, %d, %d, %d)\n",
- htonl(argp->addr), htonl(argp->prog),
- htonl(argp->vers), htonl(argp->proc));
-
/*
* Use the dotted-quad IP address of the remote host as
* identifier. Linux statd always looks up the canonical
@@ -155,19 +151,34 @@ xdr_encode_mon(struct rpc_rqst *rqstp, u32 *p, struct nsm_args *argp)
(addr>>8) & 0xff, (addr) & 0xff);
if (!(p = xdr_encode_string(p, buffer))
|| !(p = xdr_encode_string(p, system_utsname.nodename)))
- return -EIO;
+ return ERR_PTR(-EIO);
*p++ = htonl(argp->prog);
*p++ = htonl(argp->vers);
*p++ = htonl(argp->proc);
- /* This is the private part. Needed only for SM_MON call */
- if (rqstp->rq_task->tk_msg.rpc_proc == SM_MON) {
- *p++ = argp->addr;
- *p++ = argp->vers;
- *p++ = argp->proto;
- *p++ = 0;
- }
+ return p;
+}
+
+static int
+xdr_encode_mon(struct rpc_rqst *rqstp, u32 *p, struct nsm_args *argp)
+{
+ p = xdr_encode_common(rqstp, p, argp);
+ if (IS_ERR(p))
+ return PTR_ERR(p);
+ *p++ = argp->addr;
+ *p++ = argp->vers;
+ *p++ = argp->proto;
+ *p++ = 0;
+ rqstp->rq_slen = xdr_adjust_iovec(rqstp->rq_svec, p);
+ return 0;
+}
+static int
+xdr_encode_unmon(struct rpc_rqst *rqstp, u32 *p, struct nsm_args *argp)
+{
+ p = xdr_encode_common(rqstp, p, argp);
+ if (IS_ERR(p))
+ return PTR_ERR(p);
rqstp->rq_slen = xdr_adjust_iovec(rqstp->rq_svec, p);
return 0;
}
@@ -209,7 +220,7 @@ static struct rpc_procinfo nsm_procedures[] = {
},
[SM_UNMON] = {
.p_proc = SM_UNMON,
- .p_encode = (kxdrproc_t) xdr_encode_mon,
+ .p_encode = (kxdrproc_t) xdr_encode_unmon,
.p_decode = (kxdrproc_t) xdr_decode_stat,
.p_bufsiz = MAX(SM_mon_id_sz, SM_unmonres_sz) << 2,
},
diff --git a/fs/lockd/xdr.c b/fs/lockd/xdr.c
index be810e09def1..5d4b339df1e5 100644
--- a/fs/lockd/xdr.c
+++ b/fs/lockd/xdr.c
@@ -379,18 +379,13 @@ nlmsvc_encode_void(struct svc_rqst *rqstp, u32 *p, void *dummy)
/*
* Now, the client side XDR functions
*/
-static int
-nlmclt_encode_void(struct rpc_rqst *req, u32 *p, void *ptr)
-{
- req->rq_slen = xdr_adjust_iovec(req->rq_svec, p);
- return 0;
-}
-
+#ifdef NLMCLNT_SUPPORT_SHARES
static int
nlmclt_decode_void(struct rpc_rqst *req, u32 *p, void *ptr)
{
return 0;
}
+#endif
static int
nlmclt_encode_testargs(struct rpc_rqst *req, u32 *p, nlm_args *argp)
diff --git a/fs/lockd/xdr4.c b/fs/lockd/xdr4.c
index 1191feef76bf..389aadcd9208 100644
--- a/fs/lockd/xdr4.c
+++ b/fs/lockd/xdr4.c
@@ -382,18 +382,13 @@ nlm4svc_encode_void(struct svc_rqst *rqstp, u32 *p, void *dummy)
/*
* Now, the client side XDR functions
*/
-static int
-nlm4clt_encode_void(struct rpc_rqst *req, u32 *p, void *ptr)
-{
- req->rq_slen = xdr_adjust_iovec(req->rq_svec, p);
- return 0;
-}
-
+#ifdef NLMCLNT_SUPPORT_SHARES
static int
nlm4clt_decode_void(struct rpc_rqst *req, u32 *p, void *ptr)
{
return 0;
}
+#endif
static int
nlm4clt_encode_testargs(struct rpc_rqst *req, u32 *p, nlm_args *argp)
diff --git a/fs/nfs/nfs2xdr.c b/fs/nfs/nfs2xdr.c
index 2ebc61910a76..287716bd3f51 100644
--- a/fs/nfs/nfs2xdr.c
+++ b/fs/nfs/nfs2xdr.c
@@ -44,7 +44,6 @@ extern int nfs_stat_to_errno(int stat);
#define NFS_info_sz 5
#define NFS_entry_sz NFS_filename_sz+3
-#define NFS_enc_void_sz 0
#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
@@ -56,7 +55,6 @@ extern int nfs_stat_to_errno(int stat);
#define NFS_symlinkargs_sz NFS_diropargs_sz+NFS_path_sz+NFS_sattr_sz
#define NFS_readdirargs_sz NFS_fhandle_sz+2
-#define NFS_dec_void_sz 0
#define NFS_attrstat_sz 1+NFS_fattr_sz
#define NFS_diropres_sz 1+NFS_fhandle_sz+NFS_fattr_sz
#define NFS_readlinkres_sz 1
@@ -155,16 +153,6 @@ xdr_encode_sattr(u32 *p, struct iattr *attr)
* NFS encode functions
*/
/*
- * Encode void argument
- */
-static int
-nfs_xdr_enc_void(struct rpc_rqst *req, u32 *p, void *dummy)
-{
- req->rq_slen = xdr_adjust_iovec(req->rq_svec, p);
- return 0;
-}
-
-/*
* Encode file handle argument
* GETATTR, READLINK, STATFS
*/
@@ -463,15 +451,6 @@ nfs_decode_dirent(u32 *p, struct nfs_entry *entry, int plus)
* NFS XDR decode functions
*/
/*
- * Decode void reply
- */
-static int
-nfs_xdr_dec_void(struct rpc_rqst *req, u32 *p, void *dummy)
-{
- return 0;
-}
-
-/*
* Decode simple status reply
*/
static int
diff --git a/include/asm-arm/ecard.h b/include/asm-arm/ecard.h
index 7c719a206399..1c9ecdadecd9 100644
--- a/include/asm-arm/ecard.h
+++ b/include/asm-arm/ecard.h
@@ -53,6 +53,9 @@
#define MANU_SERPORT 0x003f
#define PROD_SERPORT_DSPORT 0x00b9
+#define MANU_ARXE 0x0041
+#define PROD_ARXE_SCSI 0x00be
+
#define MANU_I3 0x0046
#define PROD_I3_ETHERLAN500 0x00d4
#define PROD_I3_ETHERLAN600 0x00ec
@@ -95,11 +98,11 @@ typedef enum { /* Speed for ECARD_IOC space */
ECARD_SYNC = 3
} card_speed_t;
-typedef struct ecard_id { /* Card ID structure */
+struct ecard_id { /* Card ID structure */
unsigned short manufacturer;
unsigned short product;
void *data;
-} card_ids;
+};
struct in_ecid { /* Packed card ID information */
unsigned short product; /* Product code */
@@ -178,16 +181,6 @@ struct in_chunk_dir {
#define ecard_release(ec) ((ec)->claimed = 0)
/*
- * Start finding cards from the top of the list
- */
-extern void ecard_startfind (void);
-
-/*
- * Find an expansion card with the correct cid, product and manufacturer code
- */
-extern struct expansion_card *ecard_find (int cid, const card_ids *ids);
-
-/*
* Read a chunk from an expansion card
* cd : where to put read data
* ec : expansion card info struct
diff --git a/include/asm-arm/proc-armv/cache.h b/include/asm-arm/proc-armv/cache.h
index fe678c2b0d7e..216987fe30ef 100644
--- a/include/asm-arm/proc-armv/cache.h
+++ b/include/asm-arm/proc-armv/cache.h
@@ -93,11 +93,7 @@
#define mapping_mapped(map) (!list_empty(&(map)->i_mmap) || \
!list_empty(&(map)->i_mmap_shared))
-static inline void __flush_dcache_page(struct page *page)
-{
- unsigned long virt = (unsigned long)page_address(page);
- cpu_cache_clean_invalidate_range(virt, virt + PAGE_SIZE, 0);
-}
+extern void __flush_dcache_page(struct page *);
static inline void flush_dcache_page(struct page *page)
{
@@ -116,8 +112,6 @@ static inline void flush_dcache_page(struct page *page)
*/
#define flush_icache_page(vma,page) do { } while (0)
-#define clean_dcache_entry(_s) cpu_dcache_clean_entry((unsigned long)(_s))
-
/*
* I cache coherency stuff.
*
diff --git a/include/asm-arm/proc-armv/pgalloc.h b/include/asm-arm/proc-armv/pgalloc.h
index 53e760417601..4440be79d5ac 100644
--- a/include/asm-arm/proc-armv/pgalloc.h
+++ b/include/asm-arm/proc-armv/pgalloc.h
@@ -96,7 +96,7 @@ static inline void
pmd_populate_kernel(struct mm_struct *mm, pmd_t *pmdp, pte_t *ptep)
{
unsigned long pte_ptr = (unsigned long)ptep;
- pmd_t pmd;
+ unsigned long pmdval;
BUG_ON(mm != &init_mm);
@@ -105,21 +105,21 @@ pmd_populate_kernel(struct mm_struct *mm, pmd_t *pmdp, pte_t *ptep)
* address of the PTE table
*/
pte_ptr -= PTRS_PER_PTE * sizeof(void *);
- pmd_val(pmd) = __pa(pte_ptr) | _PAGE_KERNEL_TABLE;
- set_pmd(pmdp, pmd);
- pmd_val(pmd) += 256 * sizeof(pte_t);
- set_pmd(pmdp + 1, pmd);
+ pmdval = __pa(pte_ptr) | _PAGE_KERNEL_TABLE;
+ pmdp[0] = __pmd(pmdval);
+ pmdp[1] = __pmd(pmdval + 256 * sizeof(pte_t));
+ cpu_flush_pmd(pmdp);
}
static inline void
pmd_populate(struct mm_struct *mm, pmd_t *pmdp, struct page *ptep)
{
- pmd_t pmd;
+ unsigned long pmdval;
BUG_ON(mm == &init_mm);
- pmd_val(pmd) = __pa(page_address(ptep)) | _PAGE_USER_TABLE;
- set_pmd(pmdp, pmd);
- pmd_val(pmd) += 256 * sizeof(pte_t);
- set_pmd(pmdp + 1, pmd);
+ pmdval = page_to_pfn(ptep) << PAGE_SHIFT | _PAGE_USER_TABLE;
+ pmdp[0] = __pmd(pmdval);
+ pmdp[1] = __pmd(pmdval + 256 * sizeof(pte_t));
+ cpu_flush_pmd(pmdp);
}
diff --git a/include/asm-arm/proc-armv/pgtable.h b/include/asm-arm/proc-armv/pgtable.h
index ea268a27e9a5..34c898876c5a 100644
--- a/include/asm-arm/proc-armv/pgtable.h
+++ b/include/asm-arm/proc-armv/pgtable.h
@@ -115,16 +115,17 @@
#include <asm/proc/domain.h>
-#define _PAGE_USER_TABLE (PMD_TYPE_TABLE | PMD_DOMAIN(DOMAIN_USER))
-#define _PAGE_KERNEL_TABLE (PMD_TYPE_TABLE | PMD_DOMAIN(DOMAIN_KERNEL))
+#define _PAGE_USER_TABLE (PMD_TYPE_TABLE | PMD_BIT4 | PMD_DOMAIN(DOMAIN_USER))
+#define _PAGE_KERNEL_TABLE (PMD_TYPE_TABLE | PMD_BIT4 | PMD_DOMAIN(DOMAIN_KERNEL))
#define pmd_bad(pmd) (pmd_val(pmd) & 2)
-#define set_pmd(pmdp,pmd) cpu_set_pmd(pmdp, pmd)
+#define set_pmd(pmdp,pmd) do { *pmdp = pmd; cpu_flush_pmd(pmdp); } while (0)
static inline void pmd_clear(pmd_t *pmdp)
{
- set_pmd(pmdp, __pmd(0));
- set_pmd(pmdp + 1, __pmd(0));
+ pmdp[0], __pmd(0));
+ pmdp[1], __pmd(0));
+ cpu_flush_pmd(pmdp);
}
static inline pte_t *pmd_page_kernel(pmd_t pmd)
diff --git a/include/asm-i386/unistd.h b/include/asm-i386/unistd.h
index 181d009c30c1..794068cb7c7f 100644
--- a/include/asm-i386/unistd.h
+++ b/include/asm-i386/unistd.h
@@ -262,6 +262,7 @@
#define __NR_sys_epoll_ctl 255
#define __NR_sys_epoll_wait 256
#define __NR_remap_file_pages 257
+#define __NR_set_tid_address 258
/* user-visible error numbers are in the range -1 - -124: see <asm-i386/errno.h> */
diff --git a/init/main.c b/init/main.c
index 39d3522d3750..f9230123ec87 100644
--- a/init/main.c
+++ b/init/main.c
@@ -63,6 +63,7 @@ extern void init_IRQ(void);
extern void init_modules(void);
extern void sock_init(void);
extern void fork_init(unsigned long);
+extern void extable_init(void);
extern void mca_init(void);
extern void sbus_init(void);
extern void sysctl_init(void);
@@ -394,6 +395,7 @@ asmlinkage void __init start_kernel(void)
printk("Kernel command line: %s\n", saved_command_line);
parse_options(command_line);
trap_init();
+ extable_init();
rcu_init();
init_IRQ();
sched_init();
diff --git a/kernel/module.c b/kernel/module.c
index 9d998fd9cf07..82aa7ebe6694 100644
--- a/kernel/module.c
+++ b/kernel/module.c
@@ -1098,6 +1098,15 @@ sys_init_module(void *umod,
list_add(&mod->extable.list, &extables);
spin_unlock_irq(&modlist_lock);
+ /* Note, setting the mod->live to 1 here is safe because we haven't
+ * linked the module into the system's kernel symbol table yet,
+ * which means that the only way any other kernel code can call
+ * into this module right now is if this module hands out entry
+ * pointers to the other code. We assume that no module hands out
+ * entry pointers to the rest of the kernel unless it is ready to
+ * have them used.
+ */
+ mod->live = 1;
/* Start the module */
ret = mod->init ? mod->init() : 0;
if (ret < 0) {
@@ -1110,9 +1119,10 @@ sys_init_module(void *umod,
/* Mark it "live" so that they can force
deletion later, and we don't keep getting
woken on every decrement. */
- mod->live = 1;
- } else
+ } else {
+ mod->live = 0;
free_module(mod);
+ }
up(&module_mutex);
return ret;
}
@@ -1127,7 +1137,6 @@ sys_init_module(void *umod,
mod->module_init = NULL;
/* All ok! */
- mod->live = 1;
up(&module_mutex);
return 0;
}
@@ -1179,7 +1188,7 @@ struct seq_operations modules_op = {
.show = m_show
};
-static int __init init(void)
+void __init extable_init(void)
{
/* Add kernel symbols to symbol table */
kernel_symbols.num_syms = (__stop___ksymtab - __start___ksymtab);
@@ -1190,12 +1199,8 @@ static int __init init(void)
kernel_extable.num_entries = (__stop___ex_table -__start___ex_table);
kernel_extable.entry = __start___ex_table;
list_add(&kernel_extable.list, &extables);
- return 0;
}
/* Obsolete lvalue for broken code which asks about usage */
int module_dummy_usage = 1;
EXPORT_SYMBOL(module_dummy_usage);
-
-/* Call this at boot */
-__initcall(init);