summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CREDITS2
-rw-r--r--Documentation/BK-usage/bk-kernel-howto.txt2
-rw-r--r--Documentation/binfmt_misc.txt3
-rw-r--r--MAINTAINERS4
-rw-r--r--arch/i386/Kconfig6
-rw-r--r--arch/i386/Makefile4
-rw-r--r--arch/i386/kernel/apic.c14
-rw-r--r--arch/i386/kernel/cpu/cyrix.c4
-rw-r--r--arch/i386/kernel/microcode.c136
-rw-r--r--arch/i386/kernel/msr.c4
-rw-r--r--arch/i386/kernel/reboot.c9
-rw-r--r--arch/i386/kernel/traps.c5
-rw-r--r--arch/i386/math-emu/fpu_trig.c2
-rw-r--r--arch/i386/oprofile/op_model_p4.c12
-rw-r--r--arch/ppc/platforms/4xx/Kconfig8
-rw-r--r--arch/x86_64/defconfig133
-rw-r--r--arch/x86_64/ia32/ia32_binfmt.c3
-rw-r--r--arch/x86_64/kernel/Makefile5
-rw-r--r--arch/x86_64/kernel/aperture.c194
-rw-r--r--arch/x86_64/kernel/nmi.c12
-rw-r--r--arch/x86_64/kernel/pci-dma.c9
-rw-r--r--arch/x86_64/kernel/pci-gart.c484
-rw-r--r--arch/x86_64/kernel/pci-nommu.c25
-rw-r--r--arch/x86_64/kernel/setup64.c23
-rw-r--r--arch/x86_64/kernel/sys_x86_64.c14
-rw-r--r--arch/x86_64/kernel/x8664_ksyms.c1
-rw-r--r--arch/x86_64/mm/k8topology.c43
-rw-r--r--arch/x86_64/mm/numa.c31
-rw-r--r--drivers/block/DAC960.h2
-rw-r--r--drivers/block/cciss.c2
-rw-r--r--drivers/block/cciss_scsi.c3
-rw-r--r--drivers/block/paride/pd.c34
-rw-r--r--drivers/char/agp/agp.h1
-rw-r--r--drivers/char/agp/ali-agp.c16
-rw-r--r--drivers/char/agp/amd-k7-agp.c14
-rw-r--r--drivers/char/agp/backend.c6
-rw-r--r--drivers/char/agp/generic.c14
-rw-r--r--drivers/char/agp/intel-agp.c14
-rw-r--r--drivers/char/agp/nvidia-agp.c16
-rw-r--r--drivers/char/agp/sis-agp.c14
-rw-r--r--drivers/char/agp/sworks-agp.c9
-rw-r--r--drivers/char/agp/uninorth-agp.c15
-rw-r--r--drivers/char/agp/via-agp.c23
-rw-r--r--drivers/char/drm/drm_agpsupport.h58
-rw-r--r--drivers/char/drm/gamma_dma.c47
-rw-r--r--drivers/char/ipmi/ipmi_kcs_intf.c129
-rw-r--r--drivers/char/ipmi/ipmi_watchdog.c5
-rw-r--r--drivers/char/random.c77
-rw-r--r--drivers/char/watchdog/alim7101_wdt.c172
-rw-r--r--drivers/char/watchdog/sc520_wdt.c234
-rw-r--r--drivers/ide/pci/hpt366.c2
-rw-r--r--drivers/ieee1394/sbp2.c6
-rw-r--r--drivers/input/serio/i8042.h4
-rw-r--r--drivers/md/raid5.c2
-rw-r--r--drivers/media/video/bttv-cards.c6
-rw-r--r--drivers/media/video/bttv-driver.c4
-rw-r--r--drivers/media/video/bttvp.h2
-rw-r--r--drivers/message/fusion/mptbase.c2
-rw-r--r--drivers/message/fusion/mptscsih.c1
-rw-r--r--drivers/mtd/devices/blkmtd.c5
-rw-r--r--drivers/net/3c505.c4
-rwxr-xr-xdrivers/net/amd8111e.c12
-rw-r--r--drivers/net/arcnet/arc-rimi.c6
-rw-r--r--drivers/net/meth.c3
-rw-r--r--drivers/net/ppp_generic.c3
-rw-r--r--drivers/net/rrunner.c2
-rw-r--r--drivers/net/tun.c83
-rw-r--r--drivers/net/wan/comx-hw-locomx.c5
-rw-r--r--drivers/net/wan/comx-hw-mixcom.c5
-rw-r--r--drivers/net/wan/comx-hw-munich.c5
-rw-r--r--drivers/net/wan/comx-proto-fr.c5
-rw-r--r--drivers/net/wan/comx-proto-lapb.c5
-rw-r--r--drivers/net/wan/pc300_drv.c3
-rw-r--r--drivers/net/wan/sbni.c11
-rw-r--r--drivers/pcmcia/ds.c8
-rw-r--r--drivers/sbus/char/riowatchdog.c6
-rw-r--r--drivers/scsi/3w-xxxx.c1
-rw-r--r--drivers/scsi/53c700.c1
-rw-r--r--drivers/scsi/NCR53c406a.c5
-rw-r--r--drivers/scsi/aacraid/linit.c1
-rw-r--r--drivers/scsi/aha152x.c19
-rw-r--r--drivers/scsi/aic7xxx/aic79xx_osm.c24
-rw-r--r--drivers/scsi/aic7xxx/aic7xxx_osm.c24
-rw-r--r--drivers/scsi/cpqfcTSinit.c35
-rw-r--r--drivers/scsi/cpqfcTSstructs.h1
-rw-r--r--drivers/scsi/cpqfcTSworker.c63
-rw-r--r--drivers/scsi/dc395x.c257
-rw-r--r--drivers/scsi/dc395x.h1
-rw-r--r--drivers/scsi/esp.c1
-rw-r--r--drivers/scsi/hosts.c67
-rw-r--r--drivers/scsi/ips.c3
-rw-r--r--drivers/scsi/megaraid.c1
-rw-r--r--drivers/scsi/pcmcia/aha152x_stub.c16
-rw-r--r--drivers/scsi/pcmcia/fdomain_stub.c17
-rw-r--r--drivers/scsi/pcmcia/nsp_cs.c17
-rw-r--r--drivers/scsi/pcmcia/nsp_cs.h2
-rw-r--r--drivers/scsi/pcmcia/qlogic_stub.c17
-rw-r--r--drivers/scsi/qla1280.c4349
-rw-r--r--drivers/scsi/qla1280.h938
-rw-r--r--drivers/scsi/qlogicfc.c1
-rw-r--r--drivers/scsi/qlogicpti.c4
-rw-r--r--drivers/scsi/scsi.c73
-rw-r--r--drivers/scsi/scsi_debug.c5
-rw-r--r--drivers/scsi/scsi_error.c7
-rw-r--r--drivers/scsi/scsi_lib.c29
-rw-r--r--drivers/scsi/scsi_module.c2
-rw-r--r--drivers/scsi/scsi_priv.h6
-rw-r--r--drivers/scsi/scsi_proc.c64
-rw-r--r--drivers/scsi/scsi_scan.c8
-rw-r--r--drivers/scsi/scsi_syms.c2
-rw-r--r--drivers/scsi/scsi_sysfs.c121
-rw-r--r--drivers/scsi/sd.c6
-rw-r--r--drivers/scsi/sg.c3
-rw-r--r--drivers/scsi/sr.c79
-rw-r--r--drivers/scsi/st.c40
-rw-r--r--drivers/scsi/st.h2
-rw-r--r--drivers/scsi/sym53c8xx.c1
-rw-r--r--drivers/scsi/sym53c8xx_2/sym_glue.c520
-rw-r--r--drivers/scsi/sym53c8xx_2/sym_glue.h35
-rw-r--r--drivers/usb/storage/usb.c14
-rw-r--r--fs/Kconfig.binfmt3
-rw-r--r--fs/aio.c12
-rw-r--r--fs/befs/btree.c2
-rw-r--r--fs/nfs/nfs2xdr.c2
-rw-r--r--fs/nfsd/nfs3xdr.c4
-rw-r--r--fs/nfsd/nfsxdr.c10
-rw-r--r--fs/partitions/efi.h2
-rw-r--r--fs/partitions/ldm.h4
-rw-r--r--fs/reiserfs/hashes.c13
-rw-r--r--include/asm-generic/tlb.h2
-rw-r--r--include/asm-ppc/smp.h1
-rw-r--r--include/asm-x86_64/bitops.h4
-rw-r--r--include/asm-x86_64/ia32_unistd.h15
-rw-r--r--include/asm-x86_64/io.h6
-rw-r--r--include/asm-x86_64/nmi.h2
-rw-r--r--include/asm-x86_64/pci-direct.h21
-rw-r--r--include/asm-x86_64/pci.h35
-rw-r--r--include/asm-x86_64/percpu.h58
-rw-r--r--include/asm-x86_64/proto.h2
-rw-r--r--include/asm-x86_64/siginfo.h2
-rw-r--r--include/asm-x86_64/unistd.h2
-rw-r--r--include/linux/if_tun.h2
-rw-r--r--include/linux/ipv6.h2
-rw-r--r--include/linux/ppp-comp.h5
-rw-r--r--include/linux/xfrm.h3
-rw-r--r--include/net/dst.h8
-rw-r--r--include/net/ipv6.h4
-rw-r--r--include/net/xfrm.h45
-rw-r--r--include/scsi/scsi_device.h20
-rw-r--r--include/scsi/scsi_host.h27
-rw-r--r--ipc/sem.c10
-rw-r--r--kernel/signal.c6
-rw-r--r--mm/page-writeback.c2
-rw-r--r--mm/page_alloc.c2
-rw-r--r--net/Kconfig1
-rw-r--r--net/core/skbuff.c2
-rw-r--r--net/ipv4/Kconfig5
-rw-r--r--net/ipv4/Makefile2
-rw-r--r--net/ipv4/ipcomp.c1
-rw-r--r--net/ipv4/ipvs/Kconfig2
-rw-r--r--net/ipv4/ipvs/ip_vs_core.c2
-rw-r--r--net/ipv4/route.c2
-rw-r--r--net/ipv4/sysctl_net_ipv4.c1
-rw-r--r--net/ipv4/udp.c9
-rw-r--r--net/ipv4/xfrm4_input.c16
-rw-r--r--net/ipv4/xfrm4_tunnel.c63
-rw-r--r--net/ipv6/Kconfig3
-rw-r--r--net/ipv6/Makefile6
-rw-r--r--net/ipv6/addrconf.c48
-rw-r--r--net/ipv6/ah6.c30
-rw-r--r--net/ipv6/icmp.c8
-rw-r--r--net/ipv6/ip6_output.c98
-rw-r--r--net/ipv6/ip6_tunnel.c13
-rw-r--r--net/ipv6/ipv6_syms.c2
-rw-r--r--net/ipv6/raw.c4
-rw-r--r--net/ipv6/route.c2
-rw-r--r--net/ipv6/tcp_ipv6.c19
-rw-r--r--net/ipv6/udp.c15
-rw-r--r--net/netsyms.c80
-rw-r--r--net/sunrpc/svcsock.c14
-rw-r--r--net/xfrm/Kconfig6
-rw-r--r--net/xfrm/Makefile3
-rw-r--r--net/xfrm/xfrm_export.c75
-rw-r--r--net/xfrm/xfrm_user.c6
-rw-r--r--security/selinux/avc.c1
-rw-r--r--security/selinux/ss/global.h2
-rw-r--r--sound/oss/ad1848.c2
-rw-r--r--sound/oss/gus_wave.c2
-rw-r--r--sound/oss/trident.c2
189 files changed, 4628 insertions, 5436 deletions
diff --git a/CREDITS b/CREDITS
index feb0b30695d9..332dc225d28f 100644
--- a/CREDITS
+++ b/CREDITS
@@ -1988,7 +1988,7 @@ S: Halifax, Nova Scotia
S: Canada B3J 3C8
N: Kai Mäkisara
-E: Kai.Makisara@metla.fi
+E: Kai.Makisara@kolumbus.fi
D: SCSI Tape Driver
N: Asit Mallick
diff --git a/Documentation/BK-usage/bk-kernel-howto.txt b/Documentation/BK-usage/bk-kernel-howto.txt
index 996249fe9fdc..b7b9075d2910 100644
--- a/Documentation/BK-usage/bk-kernel-howto.txt
+++ b/Documentation/BK-usage/bk-kernel-howto.txt
@@ -216,7 +216,7 @@ changes.
3) Include a summary and "diffstat -p1" of each changeset that will be
downloaded, when Linus issues a "bk pull". The author auto-generates
-these summaries using "bk push -nl <parent> 2>&1", to obtain a listing
+these summaries using "bk changes -L <parent>", to obtain a listing
of all the pending-to-send changesets, and their commit messages.
It is important to show Linus what he will be downloading when he issues
diff --git a/Documentation/binfmt_misc.txt b/Documentation/binfmt_misc.txt
index e8e2d7f8d960..e679460447f7 100644
--- a/Documentation/binfmt_misc.txt
+++ b/Documentation/binfmt_misc.txt
@@ -11,6 +11,9 @@ at the beginning of the file with a magic byte sequence (masking out specified
bits) you have supplied. Binfmt_misc can also recognise a filename extension
aka '.com' or '.exe'.
+First you must mount binfmt_misc:
+ mount binfmt_misc -t binfmt_misc /proc/sys/fs/binfmt_misc
+
To actually register a new binary type, you have to set up a string looking like
:name:type:offset:magic:mask:interpreter: (where you can choose the ':' upon
your needs) and echo it to /proc/sys/fs/binfmt_misc/register.
diff --git a/MAINTAINERS b/MAINTAINERS
index 7e98b242ae60..4d0577b47afd 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1636,13 +1636,13 @@ S: Maintained
SCSI SUBSYSTEM
P: James E.J. Bottomley
-M: James.Bottomley@HansenPartnership.com
+M: James.Bottomley@SteelEye.com
L: linux-scsi@vger.kernel.org
S: Maintained
SCSI TAPE DRIVER
P: Kai Mäkisara
-M: Kai.Makisara@metla.fi
+M: Kai.Makisara@kolumbus.fi
L: linux-scsi@vger.kernel.org
S: Maintained
diff --git a/arch/i386/Kconfig b/arch/i386/Kconfig
index 01a3caaa0dfe..2ebf4fff0be9 100644
--- a/arch/i386/Kconfig
+++ b/arch/i386/Kconfig
@@ -276,9 +276,9 @@ config MWINCHIP3D
help
Select this for an IDT Winchip-2A or 3. Linux and GCC
treat this chip as a 586TSC with some extended instructions
- and alignment reqirements. Development kernels also enable
- out of order memory stores for this CPU, which can increase
- performance of some operations.
+ and alignment reqirements. Also enable out of order memory
+ stores for this CPU, which can increase performance of some
+ operations.
config MCYRIXIII
bool "CyrixIII/VIA-C3"
diff --git a/arch/i386/Makefile b/arch/i386/Makefile
index 01f4853083a3..c49b4749cf95 100644
--- a/arch/i386/Makefile
+++ b/arch/i386/Makefile
@@ -38,12 +38,14 @@ cflags-$(CONFIG_MPENTIUMII) += $(call check_gcc,-march=pentium2,-march=i686)
cflags-$(CONFIG_MPENTIUMIII) += $(call check_gcc,-march=pentium3,-march=i686)
cflags-$(CONFIG_MPENTIUM4) += $(call check_gcc,-march=pentium4,-march=i686)
cflags-$(CONFIG_MK6) += $(call check_gcc,-march=k6,-march=i586)
+# Please note, that patches that add -march=athlon-xp and friends are pointless.
+# They make zero difference whatsosever to performance at this time.
cflags-$(CONFIG_MK7) += $(call check_gcc,-march=athlon,-march=i686 $(align)-functions=4)
cflags-$(CONFIG_MK8) += $(call check_gcc,-march=k8,$(call check_gcc,-march=athlon,-march=i686 $(align)-functions=4))
cflags-$(CONFIG_MCRUSOE) += -march=i686 $(align)-functions=0 $(align)-jumps=0 $(align)-loops=0
cflags-$(CONFIG_MWINCHIPC6) += $(call check_gcc,-march=winchip-c6,-march=i586)
cflags-$(CONFIG_MWINCHIP2) += $(call check_gcc,-march=winchip2,-march=i586)
-cflags-$(CONFIG_MWINCHIP3D) += -march=i586
+cflags-$(CONFIG_MWINCHIP3D) += $(call check_gcc,-march=winchip2,-march=i586)
cflags-$(CONFIG_MCYRIXIII) += $(call check_gcc,-march=c3,-march=i486) $(align)-functions=0 $(align)-jumps=0 $(align)-loops=0
cflags-$(CONFIG_MVIAC3_2) += $(call check_gcc,-march=c3-2,-march=i686)
diff --git a/arch/i386/kernel/apic.c b/arch/i386/kernel/apic.c
index b660653dde76..a0b074a52ac7 100644
--- a/arch/i386/kernel/apic.c
+++ b/arch/i386/kernel/apic.c
@@ -61,6 +61,8 @@ static DEFINE_PER_CPU(int, prof_multiplier) = 1;
static DEFINE_PER_CPU(int, prof_old_multiplier) = 1;
static DEFINE_PER_CPU(int, prof_counter) = 1;
+static int enabled_via_apicbase;
+
void enable_NMI_through_LVT0 (void * dummy)
{
unsigned int v, ver;
@@ -190,6 +192,13 @@ void disable_local_APIC(void)
value = apic_read(APIC_SPIV);
value &= ~APIC_SPIV_APIC_ENABLED;
apic_write_around(APIC_SPIV, value);
+
+ if (enabled_via_apicbase) {
+ unsigned int l, h;
+ rdmsr(MSR_IA32_APICBASE, l, h);
+ l &= ~MSR_IA32_APICBASE_ENABLE;
+ wrmsr(MSR_IA32_APICBASE, l, h);
+ }
}
/*
@@ -485,7 +494,6 @@ static struct {
static int lapic_suspend(struct sys_device *dev, u32 state)
{
- unsigned int l, h;
unsigned long flags;
if (!apic_pm_state.active)
@@ -507,9 +515,6 @@ static int lapic_suspend(struct sys_device *dev, u32 state)
local_irq_save(flags);
disable_local_APIC();
- rdmsr(MSR_IA32_APICBASE, l, h);
- l &= ~MSR_IA32_APICBASE_ENABLE;
- wrmsr(MSR_IA32_APICBASE, l, h);
local_irq_restore(flags);
return 0;
}
@@ -636,6 +641,7 @@ static int __init detect_init_APIC (void)
l &= ~MSR_IA32_APICBASE_BASE;
l |= MSR_IA32_APICBASE_ENABLE | APIC_DEFAULT_PHYS_BASE;
wrmsr(MSR_IA32_APICBASE, l, h);
+ enabled_via_apicbase = 1;
}
}
/*
diff --git a/arch/i386/kernel/cpu/cyrix.c b/arch/i386/kernel/cpu/cyrix.c
index a09e70fa105a..a03beb5f6642 100644
--- a/arch/i386/kernel/cpu/cyrix.c
+++ b/arch/i386/kernel/cpu/cyrix.c
@@ -109,7 +109,6 @@ static void __init check_cx686_slop(struct cpuinfo_x86 *c)
static void __init set_cx86_reorder(void)
{
-#ifdef CONFIG_OOSTORE
u8 ccr3;
printk(KERN_INFO "Enable Memory access reorder on Cyrix/NSC processor.\n");
@@ -118,12 +117,9 @@ static void __init set_cx86_reorder(void)
/* Load/Store Serialize to mem access disable (=reorder it)  */
setCx86(CX86_PCR0, getCx86(CX86_PCR0) & ~0x80);
-#ifdef CONFIG_NOHIGHMEM
/* set load/store serialize from 1GB to 4GB */
ccr3 |= 0xe0;
-#endif
setCx86(CX86_CCR3, ccr3);
-#endif
}
static void __init set_cx86_memwb(void)
diff --git a/arch/i386/kernel/microcode.c b/arch/i386/kernel/microcode.c
index 55d072c7eb0f..a58ad2a9f4d2 100644
--- a/arch/i386/kernel/microcode.c
+++ b/arch/i386/kernel/microcode.c
@@ -89,15 +89,6 @@ MODULE_LICENSE("GPL");
#define printf(x...)
#endif
-/* VFS interface */
-static int microcode_open(struct inode *, struct file *);
-static ssize_t microcode_read(struct file *, char *, size_t, loff_t *);
-static ssize_t microcode_write(struct file *, const char *, size_t, loff_t *);
-static int microcode_ioctl(struct inode *, struct file *, unsigned int, unsigned long);
-
-static int do_microcode_update(void);
-static void do_update_one(void *);
-
/* read()/write()/ioctl() are serialized on this */
static DECLARE_RWSEM(microcode_rwsem);
@@ -106,46 +97,6 @@ static unsigned int microcode_num; /* number of chunks in microcode */
static char *mc_applied; /* array of applied microcode blocks */
static unsigned int mc_fsize; /* file size of /dev/cpu/microcode */
-static struct file_operations microcode_fops = {
- .owner = THIS_MODULE,
- .read = microcode_read,
- .write = microcode_write,
- .ioctl = microcode_ioctl,
- .open = microcode_open,
-};
-
-static struct miscdevice microcode_dev = {
- .minor = MICROCODE_MINOR,
- .name = "microcode",
- .devfs_name = "cpu/microcode",
- .fops = &microcode_fops,
-};
-
-static int __init microcode_init(void)
-{
- int error;
-
- error = misc_register(&microcode_dev);
- if (error)
- return error;
-
- printk(KERN_INFO
- "IA-32 Microcode Update Driver: v%s <tigran@veritas.com>\n",
- MICROCODE_VERSION);
- return 0;
-}
-
-static void __exit microcode_exit(void)
-{
- misc_deregister(&microcode_dev);
- kfree(mc_applied);
- printk(KERN_INFO "IA-32 Microcode Update Driver v%s unregistered\n",
- MICROCODE_VERSION);
-}
-
-module_init(microcode_init)
-module_exit(microcode_exit)
-
static int microcode_open(struct inode *unused1, struct file *unused2)
{
return capable(CAP_SYS_RAWIO) ? 0 : -EPERM;
@@ -160,27 +111,6 @@ struct update_req {
int slot;
} update_req[NR_CPUS];
-static int do_microcode_update(void)
-{
- int i, error = 0, err;
- struct microcode *m;
-
- if (on_each_cpu(do_update_one, NULL, 1, 1) != 0) {
- printk(KERN_ERR "microcode: IPI timeout, giving up\n");
- return -EIO;
- }
-
- for (i=0; i<NR_CPUS; i++) {
- err = update_req[i].err;
- error += err;
- if (!err) {
- m = (struct microcode *)mc_applied + i;
- memcpy(m, &microcode[update_req[i].slot], sizeof(struct microcode));
- }
- }
- return error;
-}
-
static void do_update_one(void *unused)
{
int cpu_num = smp_processor_id();
@@ -291,7 +221,28 @@ static void do_update_one(void *unused)
}
-static ssize_t microcode_read(struct file *file, char *buf, size_t len, loff_t *ppos)
+static int do_microcode_update(void)
+{
+ int i, error = 0, err;
+ struct microcode *m;
+
+ if (on_each_cpu(do_update_one, NULL, 1, 1) != 0) {
+ printk(KERN_ERR "microcode: IPI timeout, giving up\n");
+ return -EIO;
+ }
+
+ for (i=0; i<NR_CPUS; i++) {
+ err = update_req[i].err;
+ error += err;
+ if (!err) {
+ m = (struct microcode *)mc_applied + i;
+ memcpy(m, &microcode[update_req[i].slot], sizeof(struct microcode));
+ }
+ }
+ return error;
+}
+
+static ssize_t microcode_read(struct file *file, char __user *buf, size_t len, loff_t *ppos)
{
ssize_t ret = 0;
@@ -310,7 +261,7 @@ out:
return ret;
}
-static ssize_t microcode_write(struct file *file, const char *buf, size_t len, loff_t *ppos)
+static ssize_t microcode_write(struct file *file, const char __user *buf, size_t len, loff_t *ppos)
{
ssize_t ret;
@@ -384,3 +335,44 @@ static int microcode_ioctl(struct inode *inode, struct file *file,
}
return -EINVAL;
}
+
+static struct file_operations microcode_fops = {
+ .owner = THIS_MODULE,
+ .read = microcode_read,
+ .write = microcode_write,
+ .ioctl = microcode_ioctl,
+ .open = microcode_open,
+};
+
+static struct miscdevice microcode_dev = {
+ .minor = MICROCODE_MINOR,
+ .name = "microcode",
+ .devfs_name = "cpu/microcode",
+ .fops = &microcode_fops,
+};
+
+static int __init microcode_init(void)
+{
+ int error;
+
+ error = misc_register(&microcode_dev);
+ if (error)
+ return error;
+
+ printk(KERN_INFO
+ "IA-32 Microcode Update Driver: v%s <tigran@veritas.com>\n",
+ MICROCODE_VERSION);
+ return 0;
+}
+
+static void __exit microcode_exit(void)
+{
+ misc_deregister(&microcode_dev);
+ kfree(mc_applied);
+ printk(KERN_INFO "IA-32 Microcode Update Driver v%s unregistered\n",
+ MICROCODE_VERSION);
+}
+
+module_init(microcode_init)
+module_exit(microcode_exit)
+
diff --git a/arch/i386/kernel/msr.c b/arch/i386/kernel/msr.c
index 9524fea9d035..40a237769f3e 100644
--- a/arch/i386/kernel/msr.c
+++ b/arch/i386/kernel/msr.c
@@ -187,7 +187,7 @@ static loff_t msr_seek(struct file *file, loff_t offset, int orig)
return ret;
}
-static ssize_t msr_read(struct file * file, char * buf,
+static ssize_t msr_read(struct file * file, char __user * buf,
size_t count, loff_t *ppos)
{
u32 *tmp = (u32 *)buf;
@@ -212,7 +212,7 @@ static ssize_t msr_read(struct file * file, char * buf,
return ((char *)tmp) - buf;
}
-static ssize_t msr_write(struct file * file, const char * buf,
+static ssize_t msr_write(struct file * file, const char __user * buf,
size_t count, loff_t *ppos)
{
const u32 *tmp = (const u32 *)buf;
diff --git a/arch/i386/kernel/reboot.c b/arch/i386/kernel/reboot.c
index 77d0daefb75e..4cca4f96cb36 100644
--- a/arch/i386/kernel/reboot.c
+++ b/arch/i386/kernel/reboot.c
@@ -8,6 +8,7 @@
#include <linux/interrupt.h>
#include <linux/mc146818rtc.h>
#include <asm/uaccess.h>
+#include <asm/apic.h>
#include "mach_reboot.h"
/*
@@ -249,6 +250,14 @@ void machine_restart(char * __unused)
* other OSs see a clean IRQ state.
*/
smp_send_stop();
+#elif CONFIG_X86_LOCAL_APIC
+ if (cpu_has_apic) {
+ local_irq_disable();
+ disable_local_APIC();
+ local_irq_enable();
+ }
+#endif
+#ifdef CONFIG_X86_IO_APIC
disable_IO_APIC();
#endif
diff --git a/arch/i386/kernel/traps.c b/arch/i386/kernel/traps.c
index 8759fa4758ff..2edd55db64d0 100644
--- a/arch/i386/kernel/traps.c
+++ b/arch/i386/kernel/traps.c
@@ -629,9 +629,10 @@ void math_error(void *eip)
default:
break;
case 0x001: /* Invalid Op */
- case 0x040: /* Stack Fault */
- case 0x240: /* Stack Fault | Direction */
+ case 0x041: /* Stack Fault */
+ case 0x241: /* Stack Fault | Direction */
info.si_code = FPE_FLTINV;
+ /* Should we clear the SF or let user space do it ???? */
break;
case 0x002: /* Denormalize */
case 0x010: /* Underflow */
diff --git a/arch/i386/math-emu/fpu_trig.c b/arch/i386/math-emu/fpu_trig.c
index f6ceae26cf8d..403cbde1d425 100644
--- a/arch/i386/math-emu/fpu_trig.c
+++ b/arch/i386/math-emu/fpu_trig.c
@@ -1058,7 +1058,7 @@ static void do_fprem(FPU_REG *st0_ptr, u_char st0_tag, int round)
return;
goto fprem_valid;
}
- else if ( (st0_tag == TAG_Empty) | (st1_tag == TAG_Empty) )
+ else if ( (st0_tag == TAG_Empty) || (st1_tag == TAG_Empty) )
{
FPU_stack_underflow();
return;
diff --git a/arch/i386/oprofile/op_model_p4.c b/arch/i386/oprofile/op_model_p4.c
index 188900c1d71b..1b81fc4299cd 100644
--- a/arch/i386/oprofile/op_model_p4.c
+++ b/arch/i386/oprofile/op_model_p4.c
@@ -355,8 +355,8 @@ static struct p4_event_binding p4_events[NUM_EVENTS] = {
#define ESCR_SET_OS_1(escr, os) ((escr) |= (((os) & 1) << 1))
#define ESCR_SET_EVENT_SELECT(escr, sel) ((escr) |= (((sel) & 0x3f) << 25))
#define ESCR_SET_EVENT_MASK(escr, mask) ((escr) |= (((mask) & 0xffff) << 9))
-#define ESCR_READ(escr,high,ev,i) do {rdmsr(ev->bindings[(i)].escr_address, (escr), (high));} while (0);
-#define ESCR_WRITE(escr,high,ev,i) do {wrmsr(ev->bindings[(i)].escr_address, (escr), (high));} while (0);
+#define ESCR_READ(escr,high,ev,i) do {rdmsr(ev->bindings[(i)].escr_address, (escr), (high));} while (0)
+#define ESCR_WRITE(escr,high,ev,i) do {wrmsr(ev->bindings[(i)].escr_address, (escr), (high));} while (0)
#define CCCR_RESERVED_BITS 0x38030FFF
#define CCCR_CLEAR(cccr) ((cccr) &= CCCR_RESERVED_BITS)
@@ -366,13 +366,13 @@ static struct p4_event_binding p4_events[NUM_EVENTS] = {
#define CCCR_SET_PMI_OVF_1(cccr) ((cccr) |= (1<<27))
#define CCCR_SET_ENABLE(cccr) ((cccr) |= (1<<12))
#define CCCR_SET_DISABLE(cccr) ((cccr) &= ~(1<<12))
-#define CCCR_READ(low, high, i) do {rdmsr (p4_counters[(i)].cccr_address, (low), (high));} while (0);
-#define CCCR_WRITE(low, high, i) do {wrmsr (p4_counters[(i)].cccr_address, (low), (high));} while (0);
+#define CCCR_READ(low, high, i) do {rdmsr (p4_counters[(i)].cccr_address, (low), (high));} while (0)
+#define CCCR_WRITE(low, high, i) do {wrmsr (p4_counters[(i)].cccr_address, (low), (high));} while (0)
#define CCCR_OVF_P(cccr) ((cccr) & (1U<<31))
#define CCCR_CLEAR_OVF(cccr) ((cccr) &= (~(1U<<31)))
-#define CTR_READ(l,h,i) do {rdmsr(p4_counters[(i)].counter_address, (l), (h));} while (0);
-#define CTR_WRITE(l,i) do {wrmsr(p4_counters[(i)].counter_address, -(u32)(l), -1);} while (0);
+#define CTR_READ(l,h,i) do {rdmsr(p4_counters[(i)].counter_address, (l), (h));} while (0)
+#define CTR_WRITE(l,i) do {wrmsr(p4_counters[(i)].counter_address, -(u32)(l), -1);} while (0)
#define CTR_OVERFLOW_P(ctr) (!((ctr) & 0x80000000))
diff --git a/arch/ppc/platforms/4xx/Kconfig b/arch/ppc/platforms/4xx/Kconfig
index 4117285dcd97..759a88325c4a 100644
--- a/arch/ppc/platforms/4xx/Kconfig
+++ b/arch/ppc/platforms/4xx/Kconfig
@@ -70,16 +70,16 @@ config NP405H
depends on ASH
default y
-# All 405-based cores have this errata. This leaves out the 403GCX
+# All 405-based cores up until the 405GPR and 405EP have this errata.
config IBM405_ERR77
bool
- depends on 40x && !403GCX
+ depends on 40x && !403GCX && !405GPR
default y
-# All 40x-based cores have this errata.
+# All 40x-based cores, up until the 405GPR and 405EP have this errata.
config IBM405_ERR51
bool
- depends on 40x
+ depends on 40x && !405GPR
default y
config IBM_OCP
diff --git a/arch/x86_64/defconfig b/arch/x86_64/defconfig
index 82ca1cfa9330..3018aafd56fd 100644
--- a/arch/x86_64/defconfig
+++ b/arch/x86_64/defconfig
@@ -22,7 +22,7 @@ CONFIG_SWAP=y
CONFIG_SYSVIPC=y
# CONFIG_BSD_PROCESS_ACCT is not set
CONFIG_SYSCTL=y
-CONFIG_LOG_BUF_SHIFT=16
+CONFIG_LOG_BUF_SHIFT=18
# CONFIG_EMBEDDED is not set
CONFIG_KALLSYMS=y
CONFIG_FUTEX=y
@@ -149,17 +149,12 @@ CONFIG_LBD=y
# ATA/ATAPI/MFM/RLL support
#
CONFIG_IDE=y
-
-#
-# IDE, ATA and ATAPI Block devices
-#
CONFIG_BLK_DEV_IDE=y
#
# Please see Documentation/ide.txt for help/info on IDE drives
#
# CONFIG_BLK_DEV_HD_IDE is not set
-# CONFIG_BLK_DEV_HD is not set
CONFIG_BLK_DEV_IDEDISK=y
CONFIG_IDEDISK_MULTI_MODE=y
# CONFIG_IDEDISK_STROKE is not set
@@ -174,15 +169,16 @@ CONFIG_BLK_DEV_IDECD=y
#
# CONFIG_BLK_DEV_CMD640 is not set
CONFIG_BLK_DEV_IDEPCI=y
-# CONFIG_BLK_DEV_GENERIC is not set
# CONFIG_IDEPCI_SHARE_IRQ is not set
+# CONFIG_BLK_DEV_OFFBOARD is not set
+# CONFIG_BLK_DEV_GENERIC is not set
+# CONFIG_BLK_DEV_OPTI621 is not set
+# CONFIG_BLK_DEV_RZ1000 is not set
CONFIG_BLK_DEV_IDEDMA_PCI=y
# CONFIG_BLK_DEV_IDE_TCQ is not set
-# CONFIG_BLK_DEV_OFFBOARD is not set
# CONFIG_BLK_DEV_IDEDMA_FORCED is not set
CONFIG_IDEDMA_PCI_AUTO=y
# CONFIG_IDEDMA_ONLYDISK is not set
-CONFIG_BLK_DEV_IDEDMA=y
# CONFIG_IDEDMA_PCI_WIP is not set
CONFIG_BLK_DEV_ADMA=y
# CONFIG_BLK_DEV_AEC62XX is not set
@@ -192,23 +188,25 @@ CONFIG_BLK_DEV_AMD74XX=y
# CONFIG_BLK_DEV_TRIFLEX is not set
# CONFIG_BLK_DEV_CY82C693 is not set
# CONFIG_BLK_DEV_CS5520 is not set
+# CONFIG_BLK_DEV_CS5530 is not set
# CONFIG_BLK_DEV_HPT34X is not set
# CONFIG_BLK_DEV_HPT366 is not set
# CONFIG_BLK_DEV_SC1200 is not set
# CONFIG_BLK_DEV_PIIX is not set
# CONFIG_BLK_DEV_NS87415 is not set
-# CONFIG_BLK_DEV_OPTI621 is not set
# CONFIG_BLK_DEV_PDC202XX_OLD is not set
# CONFIG_BLK_DEV_PDC202XX_NEW is not set
-# CONFIG_BLK_DEV_RZ1000 is not set
# CONFIG_BLK_DEV_SVWKS is not set
# CONFIG_BLK_DEV_SIIMAGE is not set
# CONFIG_BLK_DEV_SIS5513 is not set
# CONFIG_BLK_DEV_SLC90E66 is not set
# CONFIG_BLK_DEV_TRM290 is not set
# CONFIG_BLK_DEV_VIA82CXXX is not set
-CONFIG_IDEDMA_AUTO=y
+CONFIG_BLK_DEV_IDEDMA=y
# CONFIG_IDEDMA_IVB is not set
+CONFIG_IDEDMA_AUTO=y
+# CONFIG_DMA_NONPCI is not set
+# CONFIG_BLK_DEV_HD is not set
#
# SCSI device support
@@ -251,7 +249,7 @@ CONFIG_BLK_DEV_SD=y
# CONFIG_SCSI_EATA_PIO is not set
# CONFIG_SCSI_FUTURE_DOMAIN is not set
# CONFIG_SCSI_GDTH is not set
-# CONFIG_SCSI_IPS is not set
+CONFIG_SCSI_IPS=m
# CONFIG_SCSI_INITIO is not set
# CONFIG_SCSI_INIA100 is not set
# CONFIG_SCSI_SYM53C8XX_2 is not set
@@ -301,7 +299,6 @@ CONFIG_NET=y
CONFIG_PACKET=y
# CONFIG_PACKET_MMAP is not set
# CONFIG_NETLINK_DEV is not set
-# CONFIG_NETFILTER is not set
CONFIG_UNIX=y
# CONFIG_NET_KEY is not set
CONFIG_INET=y
@@ -317,12 +314,10 @@ CONFIG_IP_MULTICAST=y
# CONFIG_INET_AH is not set
# CONFIG_INET_ESP is not set
# CONFIG_INET_IPCOMP is not set
-CONFIG_IPV6=y
-CONFIG_IPV6_PRIVACY=y
-# CONFIG_INET6_AH is not set
-# CONFIG_INET6_ESP is not set
-# CONFIG_INET6_IPCOMP is not set
-# CONFIG_IPV6_TUNNEL is not set
+# CONFIG_IPV6 is not set
+# CONFIG_DECNET is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_NETFILTER is not set
# CONFIG_XFRM_USER is not set
#
@@ -333,8 +328,6 @@ CONFIG_IPV6_SCTP__=y
# CONFIG_ATM is not set
# CONFIG_VLAN_8021Q is not set
# CONFIG_LLC is not set
-# CONFIG_DECNET is not set
-# CONFIG_BRIDGE is not set
# CONFIG_X25 is not set
# CONFIG_LAPB is not set
# CONFIG_NET_DIVERT is not set
@@ -546,11 +539,7 @@ CONFIG_UNIX98_PTY_COUNT=256
#
# IPMI
#
-CONFIG_IPMI_HANDLER=y
-CONFIG_IPMI_PANIC_EVENT=y
-CONFIG_IPMI_DEVICE_INTERFACE=y
-CONFIG_IPMI_KCS=y
-CONFIG_IPMI_WATCHDOG=y
+# CONFIG_IPMI_HANDLER is not set
#
# Watchdog Cards
@@ -570,12 +559,7 @@ CONFIG_RTC=y
# CONFIG_FTAPE is not set
CONFIG_AGP=y
CONFIG_AGP_AMD_8151=y
-CONFIG_DRM=y
-# CONFIG_DRM_TDFX is not set
-# CONFIG_DRM_GAMMA is not set
-# CONFIG_DRM_R128 is not set
-CONFIG_DRM_RADEON=y
-# CONFIG_DRM_MGA is not set
+# CONFIG_DRM is not set
# CONFIG_MWAVE is not set
CONFIG_RAW_DRIVER=y
CONFIG_HANGCHECK_TIMER=y
@@ -598,19 +582,25 @@ CONFIG_HANGCHECK_TIMER=y
# File systems
#
CONFIG_EXT2_FS=y
-# CONFIG_EXT2_FS_XATTR is not set
+CONFIG_EXT2_FS_XATTR=y
+CONFIG_EXT2_FS_POSIX_ACL=y
+# CONFIG_EXT2_FS_SECURITY is not set
CONFIG_EXT3_FS=y
-# CONFIG_EXT3_FS_XATTR is not set
+CONFIG_EXT3_FS_XATTR=y
+CONFIG_EXT3_FS_POSIX_ACL=y
+# CONFIG_EXT3_FS_SECURITY is not set
CONFIG_JBD=y
# CONFIG_JBD_DEBUG is not set
+CONFIG_FS_MBCACHE=y
CONFIG_REISERFS_FS=y
# CONFIG_REISERFS_CHECK is not set
# CONFIG_REISERFS_PROC_INFO is not set
-# CONFIG_JFS_FS is not set
-CONFIG_XFS_FS=m
-# CONFIG_XFS_RT is not set
-# CONFIG_XFS_QUOTA is not set
-# CONFIG_XFS_POSIX_ACL is not set
+CONFIG_JFS_FS=y
+CONFIG_JFS_POSIX_ACL=y
+# CONFIG_JFS_DEBUG is not set
+# CONFIG_JFS_STATISTICS is not set
+CONFIG_FS_POSIX_ACL=y
+# CONFIG_XFS_FS is not set
# CONFIG_MINIX_FS is not set
# CONFIG_ROMFS_FS is not set
# CONFIG_QUOTA is not set
@@ -684,6 +674,49 @@ CONFIG_SUNRPC=y
#
# CONFIG_PARTITION_ADVANCED is not set
CONFIG_MSDOS_PARTITION=y
+CONFIG_NLS=y
+
+#
+# Native Language Support
+#
+CONFIG_NLS_DEFAULT="iso8859-1"
+# CONFIG_NLS_CODEPAGE_437 is not set
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+# CONFIG_NLS_CODEPAGE_850 is not set
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+# CONFIG_NLS_ISO8859_1 is not set
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+# CONFIG_NLS_UTF8 is not set
#
# Graphics support
@@ -759,8 +792,10 @@ CONFIG_DEBUG_KERNEL=y
CONFIG_MAGIC_SYSRQ=y
# CONFIG_DEBUG_SPINLOCK is not set
# CONFIG_INIT_DEBUG is not set
+# CONFIG_DEBUG_INFO is not set
# CONFIG_FRAME_POINTER is not set
-# CONFIG_IOMMU_DEBUG is not set
+CONFIG_IOMMU_DEBUG=y
+CONFIG_IOMMU_LEAK=y
CONFIG_MCE_DEBUG=y
#
@@ -771,21 +806,7 @@ CONFIG_MCE_DEBUG=y
#
# Cryptographic options
#
-CONFIG_CRYPTO=y
-# CONFIG_CRYPTO_HMAC is not set
-# CONFIG_CRYPTO_NULL is not set
-# CONFIG_CRYPTO_MD4 is not set
-CONFIG_CRYPTO_MD5=y
-# CONFIG_CRYPTO_SHA1 is not set
-# CONFIG_CRYPTO_SHA256 is not set
-# CONFIG_CRYPTO_SHA512 is not set
-# CONFIG_CRYPTO_DES is not set
-# CONFIG_CRYPTO_BLOWFISH is not set
-# CONFIG_CRYPTO_TWOFISH is not set
-# CONFIG_CRYPTO_SERPENT is not set
-# CONFIG_CRYPTO_AES is not set
-# CONFIG_CRYPTO_DEFLATE is not set
-# CONFIG_CRYPTO_TEST is not set
+# CONFIG_CRYPTO is not set
#
# Library routines
diff --git a/arch/x86_64/ia32/ia32_binfmt.c b/arch/x86_64/ia32/ia32_binfmt.c
index b7f3dcb7e3bf..7b102b1e89ae 100644
--- a/arch/x86_64/ia32/ia32_binfmt.c
+++ b/arch/x86_64/ia32/ia32_binfmt.c
@@ -204,10 +204,9 @@ static inline int elf_core_copy_task_regs(struct task_struct *t, elf_gregset_t*
}
static inline int
-elf_core_copy_task_fpregs(struct task_struct *tsk, struct pt_regs *xregs, elf_fpregset_t *fpu)
+elf_core_copy_task_fpregs(struct task_struct *tsk, struct pt_regs *regs, elf_fpregset_t *fpu)
{
struct _fpstate_ia32 *fpstate = (void*)fpu;
- struct pt_regs *regs = (struct pt_regs *)(tsk->thread.rsp0);
mm_segment_t oldfs = get_fs();
if (!tsk->used_math)
diff --git a/arch/x86_64/kernel/Makefile b/arch/x86_64/kernel/Makefile
index 128cd3867de8..0f560efe9ef6 100644
--- a/arch/x86_64/kernel/Makefile
+++ b/arch/x86_64/kernel/Makefile
@@ -6,7 +6,7 @@ extra-y := head.o head64.o init_task.o
EXTRA_AFLAGS := -traditional
obj-y := process.o semaphore.o signal.o entry.o traps.o irq.o \
ptrace.o i8259.o ioport.o ldt.o setup.o time.o sys_x86_64.o \
- pci-dma.o x8664_ksyms.o i387.o syscall.o vsyscall.o \
+ x8664_ksyms.o i387.o syscall.o vsyscall.o \
setup64.o bluesmoke.o bootflag.o e820.o reboot.o warmreboot.o
obj-$(CONFIG_MTRR) += mtrr/
@@ -19,7 +19,8 @@ obj-$(CONFIG_X86_IO_APIC) += io_apic.o mpparse.o
obj-$(CONFIG_SOFTWARE_SUSPEND) += suspend.o suspend_asm.o
obj-$(CONFIG_EARLY_PRINTK) += early_printk.o
obj-$(CONFIG_GART_IOMMU) += pci-gart.o aperture.o
-obj-$(CONFIG_DUMMY_IOMMU) += pci-nommu.o
+obj-$(CONFIG_DUMMY_IOMMU) += pci-nommu.o pci-dma.o
+
obj-$(CONFIG_MODULES) += module.o
$(obj)/bootflag.c:
diff --git a/arch/x86_64/kernel/aperture.c b/arch/x86_64/kernel/aperture.c
index aedd584b7ae0..36242d20c492 100644
--- a/arch/x86_64/kernel/aperture.c
+++ b/arch/x86_64/kernel/aperture.c
@@ -1,14 +1,14 @@
/*
* Firmware replacement code.
*
- * Work around broken BIOSes that don't set an aperture.
- * The IOMMU code needs an aperture even who no AGP is present in the system.
- * Map the aperture over some low memory. This is cheaper than doing bounce
- * buffering. The memory is lost. This is done at early boot because only
- * the bootmem allocator can allocate 32+MB.
+ * Work around broken BIOSes that don't set an aperture or only set the
+ * aperture in the AGP bridge.
+ * If all fails map the aperture over some low memory. This is cheaper than
+ * doing bounce buffering. The memory is lost. This is done at early boot
+ * because only the bootmem allocator can allocate 32+MB.
*
* Copyright 2002 Andi Kleen, SuSE Labs.
- * $Id: aperture.c,v 1.2 2002/09/19 19:25:32 ak Exp $
+ * $Id: aperture.c,v 1.7 2003/08/01 03:36:18 ak Exp $
*/
#include <linux/config.h>
#include <linux/kernel.h>
@@ -17,6 +17,8 @@
#include <linux/bootmem.h>
#include <linux/mmzone.h>
#include <linux/pci_ids.h>
+#include <linux/pci.h>
+#include <linux/bitops.h>
#include <asm/e820.h>
#include <asm/io.h>
#include <asm/proto.h>
@@ -45,10 +47,10 @@ static u32 __init allocate_aperture(void)
aper_size = (32 * 1024 * 1024) << fallback_aper_order;
/*
- * Aperture has to be naturally aligned it seems. This means an
- * 2GB aperture won't have much changes to succeed in the lower 4GB of
- * memory. Unfortunately we cannot move it up because that would make
- * the IOMMU useless.
+ * Aperture has to be naturally aligned. This means an 2GB aperture won't
+ * have much chances to find a place in the lower 4GB of memory.
+ * Unfortunately we cannot move it up because that would make the
+ * IOMMU useless.
*/
p = __alloc_bootmem_node(nd0, aper_size, aper_size, 0);
if (!p || __pa(p)+aper_size > 0xffffffff) {
@@ -63,21 +65,136 @@ static u32 __init allocate_aperture(void)
return (u32)__pa(p);
}
+static int __init aperture_valid(char *name, u64 aper_base, u32 aper_size)
+{
+ if (!aper_base)
+ return 0;
+ if (aper_size < 64*1024*1024) {
+ printk("Aperture from %s too small (%d MB)\n", name, aper_size>>20);
+ return 0;
+ }
+ if (aper_base + aper_size >= 0xffffffff) {
+ printk("Aperture from %s beyond 4GB. Ignoring.\n",name);
+ return 0;
+ }
+ if (e820_mapped(aper_base, aper_base + aper_size, E820_RAM)) {
+ printk("Aperture from %s pointing to e820 RAM. Ignoring.\n",name);
+ return 0;
+ }
+ return 1;
+}
+
+/* Find a PCI capability */
+static __u32 __init find_cap(int num, int slot, int func, int cap)
+{
+ if (!(read_pci_config_16(num,slot,func,PCI_STATUS) & PCI_STATUS_CAP_LIST))
+ return 0;
+ u8 pos = read_pci_config_byte(num,slot,func,PCI_CAPABILITY_LIST);
+ int bytes;
+ for (bytes = 0; bytes < 48 && pos >= 0x40; bytes++) {
+ pos &= ~3;
+ u8 id = read_pci_config_byte(num,slot,func,pos+PCI_CAP_LIST_ID);
+ if (id == 0xff)
+ break;
+ if (id == cap)
+ return pos;
+ pos = read_pci_config_byte(num,slot,func,pos+PCI_CAP_LIST_NEXT);
+ }
+ return 0;
+}
+
+/* Read a standard AGPv3 bridge header */
+static __u32 __init read_agp(int num, int slot, int func, int cap, u32 *order)
+{
+ printk("AGP bridge at %02x:%02x:%02x\n", num, slot, func);
+ u32 apsizereg = read_pci_config_16(num,slot,func, cap + 0x14);
+
+ if (apsizereg == 0xffffffff) {
+ printk("APSIZE in AGP bridge unreadable\n");
+ return 0;
+ }
+
+ u32 apsize = apsizereg & 0xfff;
+ /* Some BIOS use weird encodings not in the AGPv3 table. */
+ if (apsize & 0xff)
+ apsize |= 0xf00;
+ int nbits = hweight16(apsize);
+ *order = 7 - nbits;
+ if ((int)*order < 0) /* < 32MB */
+ *order = 0;
+
+ u32 aper_low = read_pci_config(num,slot,func, 0x10);
+ u32 aper_hi = read_pci_config(num,slot,func,0x14);
+ u64 aper = (aper_low & ~((1<<22)-1)) | ((u64)aper_hi << 32);
+
+ printk("Aperture from AGP @ %Lx size %u MB (APSIZE %x)\n",
+ aper, 32 << *order, apsizereg);
+
+ if (!aperture_valid("AGP bridge", aper, (32*1024*1024) << *order))
+ return 0;
+ return (u32)aper;
+}
+
+/* Look for an AGP bridge. Windows only expects the aperture in the
+ AGP bridge and some BIOS forget to initialize the Northbridge too.
+ Work around this here.
+
+ Do an PCI bus scan by hand because we're running before the PCI
+ subsystem.
+
+ All K8 AGP bridges are AGPv3 compliant, so we can do this scan
+ generically. It's probably overkill to always scan all slots because
+ the AGP bridges should be always an own bus on the HT hierarchy,
+ but do it here for future safety. */
+static __u32 __init search_agp_bridge(u32 *order, int *valid_agp)
+{
+ int num, slot, func;
+
+ /* Poor man's PCI discovery */
+ for (num = 0; num < 32; num++) {
+ for (slot = 0; slot < 32; slot++) {
+ for (func = 0; func < 8; func++) {
+ u32 class, cap;
+ class = read_pci_config(num,slot,func,
+ PCI_CLASS_REVISION);
+ if (class == 0xffffffff)
+ break;
+
+ switch (class >> 16) {
+ case PCI_CLASS_BRIDGE_HOST:
+ case PCI_CLASS_BRIDGE_OTHER: /* needed? */
+ /* AGP bridge? */
+ cap = find_cap(num,slot,func,PCI_CAP_ID_AGP);
+ if (!cap)
+ break;
+ *valid_agp = 1;
+ return read_agp(num,slot,func,cap,order);
+ }
+
+ /* No multi-function device? */
+ u8 type = read_pci_config_byte(num,slot,func,
+ PCI_HEADER_TYPE);
+ if (!(type & 0x80))
+ break;
+ }
+ }
+ }
+ printk("No AGP bridge found\n");
+ return 0;
+}
+
void __init iommu_hole_init(void)
{
int fix, num;
- u32 aper_size, aper_alloc, aper_order;
+ u32 aper_size, aper_alloc = 0, aper_order;
u64 aper_base;
-
- if (no_iommu)
- return;
- if (end_pfn < (0xffffffff>>PAGE_SHIFT) && !force_mmu)
- return;
+ int valid_agp = 0;
printk("Checking aperture...\n");
fix = 0;
for (num = 24; num < 32; num++) {
+ char name[30];
if (read_pci_config(0, num, 3, 0x00) != NB_ID_3)
continue;
@@ -86,15 +203,12 @@ void __init iommu_hole_init(void)
aper_base = read_pci_config(0, num, 3, 0x94) & 0x7fff;
aper_base <<= 25;
- printk("CPU %d: aperture @ %Lx size %u KB\n", num-24,
- aper_base, aper_size>>10);
- if (!aper_base || aper_base + aper_size >= 0xffffffff) {
- fix = 1;
- break;
- }
+ printk("CPU %d: aperture @ %Lx size %u MB\n", num-24,
+ aper_base, aper_size>>20);
- if (e820_mapped(aper_base, aper_base + aper_size, E820_RAM)) {
- printk("Aperture pointing to e820 RAM. Ignoring.\n");
+ sprintf(name, "northbridge cpu %d", num-24);
+
+ if (!aperture_valid(name, aper_base, aper_size)) {
fix = 1;
break;
}
@@ -103,12 +217,40 @@ void __init iommu_hole_init(void)
if (!fix && !fallback_aper_force)
return;
+ if (!fallback_aper_force)
+ aper_alloc = search_agp_bridge(&aper_order, &valid_agp);
+
+ if (aper_alloc) {
+ /* Got the aperture from the AGP bridge */
+ } else if ((!no_iommu && end_pfn >= 0xffffffff>>PAGE_SHIFT) ||
+ force_iommu ||
+ valid_agp ||
+ fallback_aper_force) {
+ /* When there is a AGP bridge in the system assume the
+ user wants to use the AGP driver too and needs an
+ aperture. However this case (AGP but no good
+ aperture) should only happen with a more broken than
+ usual BIOS, because it would even break Windows. */
+
printk("Your BIOS doesn't leave a aperture memory hole\n");
printk("Please enable the IOMMU option in the BIOS setup\n");
+ printk("This costs you %d MB of RAM\n", 32 << fallback_aper_order);
+
+ aper_order = fallback_aper_order;
aper_alloc = allocate_aperture();
- if (!aper_alloc)
+ if (!aper_alloc) {
+ /* Could disable AGP and IOMMU here, but it's probably
+ not worth it. But the later users cannot deal with
+ bad apertures and turning on the aperture over memory
+ causes very strange problems, so it's better to
+ panic early. */
+ panic("Not enough memory for aperture");
+ }
+ } else {
return;
+ }
+ /* Fix up the north bridges */
for (num = 24; num < 32; num++) {
if (read_pci_config(0, num, 3, 0x00) != NB_ID_3)
continue;
@@ -116,7 +258,7 @@ void __init iommu_hole_init(void)
/* Don't enable translation yet. That is done later.
Assume this BIOS didn't initialise the GART so
just overwrite all previous bits */
- write_pci_config(0, num, 3, 0x90, fallback_aper_order<<1);
+ write_pci_config(0, num, 3, 0x90, aper_order<<1);
write_pci_config(0, num, 3, 0x94, aper_alloc>>25);
}
}
diff --git a/arch/x86_64/kernel/nmi.c b/arch/x86_64/kernel/nmi.c
index aa7a1868c1f3..12e28ccedbc1 100644
--- a/arch/x86_64/kernel/nmi.c
+++ b/arch/x86_64/kernel/nmi.c
@@ -40,6 +40,7 @@
* -1: the lapic NMI watchdog is disabled, but can be enabled
*/
static int nmi_active;
+static int panic_on_timeout;
unsigned int nmi_watchdog = NMI_IO_APIC;
static unsigned int nmi_hz = HZ;
@@ -115,6 +116,14 @@ static int __init setup_nmi_watchdog(char *str)
{
int nmi;
+ if (!strncmp(str,"panic",5)) {
+ panic_on_timeout = 1;
+ str = strchr(str, ',');
+ if (!str)
+ return 1;
+ ++str;
+ }
+
get_option(&str, &nmi);
if (nmi >= NMI_INVALID)
@@ -327,6 +336,8 @@ void nmi_watchdog_tick (struct pt_regs * regs, unsigned reason)
bust_spinlocks(1);
printk("NMI Watchdog detected LOCKUP on CPU%d, registers:\n", cpu);
show_registers(regs);
+ if (panic_on_timeout)
+ panic("nmi watchdog");
printk("console shuts up ...\n");
console_silent();
spin_unlock(&nmi_print_lock);
@@ -374,3 +385,4 @@ EXPORT_SYMBOL(disable_lapic_nmi_watchdog);
EXPORT_SYMBOL(enable_lapic_nmi_watchdog);
EXPORT_SYMBOL(disable_timer_nmi_watchdog);
EXPORT_SYMBOL(enable_timer_nmi_watchdog);
+EXPORT_SYMBOL(touch_nmi_watchdog);
diff --git a/arch/x86_64/kernel/pci-dma.c b/arch/x86_64/kernel/pci-dma.c
index 67a07a9db3b1..43ff84bc076f 100644
--- a/arch/x86_64/kernel/pci-dma.c
+++ b/arch/x86_64/kernel/pci-dma.c
@@ -9,8 +9,6 @@
#include <linux/module.h>
#include <asm/io.h>
-dma_addr_t bad_dma_address = -1UL;
-
/* Map a set of buffers described by scatterlist in streaming
* mode for DMA. This is the scatter-gather version of the
* above pci_map_single interface. Here the scatter gather list
@@ -34,16 +32,9 @@ int pci_map_sg(struct pci_dev *hwdev, struct scatterlist *sg,
BUG_ON(direction == PCI_DMA_NONE);
for (i = 0; i < nents; i++ ) {
struct scatterlist *s = &sg[i];
-
BUG_ON(!s->page);
-
s->dma_address = pci_map_page(hwdev, s->page, s->offset,
s->length, direction);
-
- if (unlikely(s->dma_address == bad_dma_address)) {
- pci_unmap_sg(hwdev, sg, i, direction);
- return 0;
- }
}
return nents;
}
diff --git a/arch/x86_64/kernel/pci-gart.c b/arch/x86_64/kernel/pci-gart.c
index 336989a14a92..b9951a64bab3 100644
--- a/arch/x86_64/kernel/pci-gart.c
+++ b/arch/x86_64/kernel/pci-gart.c
@@ -8,20 +8,8 @@
* See Documentation/DMA-mapping.txt for the interface specification.
*
* Copyright 2002 Andi Kleen, SuSE Labs.
- * $Id: pci-gart.c,v 1.20 2003/03/12 08:23:29 ak Exp $
*/
-/*
- * Notebook:
-
-possible future tuning:
- fast path for sg streaming mappings - only take the locks once.
- more intelligent flush strategy - flush only the NB of the CPU directly
- connected to the device?
- move boundary between IOMMU and AGP in GART dynamically
-
-*/
-
#include <linux/config.h>
#include <linux/types.h>
#include <linux/ctype.h>
@@ -32,6 +20,8 @@ possible future tuning:
#include <linux/spinlock.h>
#include <linux/pci.h>
#include <linux/module.h>
+#include <linux/topology.h>
+#include <asm/atomic.h>
#include <asm/io.h>
#include <asm/mtrr.h>
#include <asm/bitops.h>
@@ -41,6 +31,8 @@ possible future tuning:
#include <asm/kdebug.h>
#include <asm/proto.h>
+dma_addr_t bad_dma_address;
+
unsigned long iommu_bus_base; /* GART remapping area (physical) */
static unsigned long iommu_size; /* size of remapping area bytes */
static unsigned long iommu_pages; /* .. and in pages */
@@ -50,9 +42,13 @@ u32 *iommu_gatt_base; /* Remapping table */
int no_iommu;
static int no_agp;
#ifdef CONFIG_IOMMU_DEBUG
-int force_mmu = 1;
+int panic_on_overflow = 1;
+int force_iommu = 1;
+int sac_force_size = 0;
#else
-int force_mmu = 0;
+int panic_on_overflow = 1; /* for testing */
+int force_iommu = 0;
+int sac_force_size = 256*1024*1024;
#endif
/* Allocation bitmap for the remapping area */
@@ -65,12 +61,18 @@ static unsigned long *iommu_gart_bitmap; /* guarded by iommu_bitmap_lock */
(((x) & 0xfffff000) | (((x) >> 32) << 4) | GPTE_VALID | GPTE_COHERENT)
#define GPTE_DECODE(x) (((x) & 0xfffff000) | (((u64)(x) & 0xff0) << 28))
+#define to_pages(addr,size) \
+ (round_up(((addr) & ~PAGE_MASK) + (size), PAGE_SIZE) >> PAGE_SHIFT)
+
#define for_all_nb(dev) \
- dev=NULL; \
- while ((dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) \
- if (dev->bus->number == 0 && PCI_FUNC(dev->devfn) == 3 && \
+ dev = NULL; \
+ while ((dev = pci_find_device(PCI_VENDOR_ID_AMD, 0x1103, dev))!=NULL)\
+ if (dev->bus->number == 0 && \
(PCI_SLOT(dev->devfn) >= 24) && (PCI_SLOT(dev->devfn) <= 31))
+static struct pci_dev *northbridges[NR_CPUS + 1];
+static u32 northbridge_flush_word[NR_CPUS + 1];
+
#define EMERGENCY_PAGES 32 /* = 128KB */
#ifdef CONFIG_AGP
@@ -85,15 +87,16 @@ AGPEXTERN int agp_memory_reserved;
AGPEXTERN __u32 *agp_gatt_table;
static unsigned long next_bit; /* protected by iommu_bitmap_lock */
+static int need_flush; /* global flush state. set for each gart wrap */
-static unsigned long alloc_iommu(int size, int *flush)
+static unsigned long alloc_iommu(int size)
{
unsigned long offset, flags;
spin_lock_irqsave(&iommu_bitmap_lock, flags);
offset = find_next_zero_string(iommu_gart_bitmap,next_bit,iommu_pages,size);
if (offset == -1) {
- *flush = 1;
+ need_flush = 1;
offset = find_next_zero_string(iommu_gart_bitmap,0,next_bit,size);
}
if (offset != -1) {
@@ -101,7 +104,7 @@ static unsigned long alloc_iommu(int size, int *flush)
next_bit = offset+size;
if (next_bit >= iommu_pages) {
next_bit = 0;
- *flush = 1;
+ need_flush = 1;
}
}
spin_unlock_irqrestore(&iommu_bitmap_lock, flags);
@@ -110,32 +113,59 @@ static unsigned long alloc_iommu(int size, int *flush)
static void free_iommu(unsigned long offset, int size)
{
+ if (size == 1) {
+ clear_bit(offset, iommu_gart_bitmap);
+ return;
+ }
unsigned long flags;
spin_lock_irqsave(&iommu_bitmap_lock, flags);
- clear_bit_string(iommu_gart_bitmap, offset, size);
+ __clear_bit_string(iommu_gart_bitmap, offset, size);
spin_unlock_irqrestore(&iommu_bitmap_lock, flags);
}
-static inline void flush_gart(void)
+/*
+ * Use global flush state to avoid races with multiple flushers.
+ */
+static void __flush_gart(struct pci_dev *dev)
{
- struct pci_dev *nb;
- for_all_nb(nb) {
- u32 flag;
- pci_read_config_dword(nb, 0x9c, &flag); /* could cache this */
- /* could complain for PTE walk errors here (bit 1 of flag) */
- flag |= 1;
- pci_write_config_dword(nb, 0x9c, flag);
+ unsigned long flags;
+ int bus = dev ? dev->bus->number : -1;
+ int flushed = 0;
+ int i;
+
+ spin_lock_irqsave(&iommu_bitmap_lock, flags);
+ /* recheck flush count inside lock */
+ if (need_flush) {
+ for (i = 0; northbridges[i]; i++) {
+ if (bus >= 0 && !(pcibus_to_cpumask(bus) & (1UL << i)))
+ continue;
+ pci_write_config_dword(northbridges[i], 0x9c,
+ northbridge_flush_word[i] | 1);
+ flushed++;
+ }
+ if (!flushed)
+ printk("nothing to flush? %d\n", bus);
+ need_flush = 0;
}
+ spin_unlock_irqrestore(&iommu_bitmap_lock, flags);
}
+static inline void flush_gart(struct pci_dev *dev)
+{
+ if (need_flush)
+ __flush_gart(dev);
+}
+
+/*
+ * Allocate memory for a consistent mapping.
+ * All mappings are consistent here, so this is just a wrapper around
+ * pci_map_single.
+ */
void *pci_alloc_consistent(struct pci_dev *hwdev, size_t size,
dma_addr_t *dma_handle)
{
void *memory;
int gfp = GFP_ATOMIC;
- int i;
- int flush = 0;
- unsigned long iommu_page;
unsigned long dma_mask;
if (hwdev == NULL) {
@@ -149,20 +179,14 @@ void *pci_alloc_consistent(struct pci_dev *hwdev, size_t size,
if (dma_mask < 0xffffffff || no_iommu)
gfp |= GFP_DMA;
- /*
- * First try to allocate continuous and use directly if already
- * in lowmem.
- */
- size = round_up(size, PAGE_SIZE);
memory = (void *)__get_free_pages(gfp, get_order(size));
if (memory == NULL) {
return NULL;
} else {
- int high = 0, mmu;
- if (((unsigned long)virt_to_bus(memory) + size) > dma_mask)
- high = 1;
- mmu = 1;
- if (force_mmu && !(gfp & GFP_DMA))
+ int high, mmu;
+ high = ((unsigned long)virt_to_bus(memory) + size) >= dma_mask;
+ mmu = high;
+ if (force_iommu && !(gfp & GFP_DMA))
mmu = 1;
if (no_iommu) {
if (high) goto error;
@@ -175,27 +199,15 @@ void *pci_alloc_consistent(struct pci_dev *hwdev, size_t size,
}
}
- size >>= PAGE_SHIFT;
-
- iommu_page = alloc_iommu(size, &flush);
- if (iommu_page == -1)
+ *dma_handle = pci_map_single(hwdev, memory, size, 0);
+ if (*dma_handle == bad_dma_address)
goto error;
- /* Fill in the GATT */
- for (i = 0; i < size; i++) {
- unsigned long phys_mem;
- void *mem = memory + i*PAGE_SIZE;
- phys_mem = virt_to_phys(mem);
- BUG_ON(phys_mem & ~PHYSICAL_PAGE_MASK);
- iommu_gatt_base[iommu_page + i] = GPTE_ENCODE(phys_mem);
- }
-
- if (flush)
- flush_gart();
- *dma_handle = iommu_bus_base + (iommu_page << PAGE_SHIFT);
return memory;
- error:
+error:
+ if (panic_on_overflow)
+ panic("pci_map_single: overflow %lu bytes\n", size);
free_pages((unsigned long)memory, get_order(size));
return NULL;
}
@@ -207,25 +219,17 @@ void *pci_alloc_consistent(struct pci_dev *hwdev, size_t size,
void pci_free_consistent(struct pci_dev *hwdev, size_t size,
void *vaddr, dma_addr_t bus)
{
- unsigned long iommu_page;
-
- size = round_up(size, PAGE_SIZE);
- if (bus >= iommu_bus_base && bus <= iommu_bus_base + iommu_size) {
- unsigned pages = size >> PAGE_SHIFT;
- int i;
- iommu_page = (bus - iommu_bus_base) >> PAGE_SHIFT;
- vaddr = __va(GPTE_DECODE(iommu_gatt_base[iommu_page]));
- for (i = 0; i < pages; i++) {
- u64 pte = iommu_gatt_base[iommu_page + i];
- BUG_ON((pte & GPTE_VALID) == 0);
- iommu_gatt_base[iommu_page + i] = 0;
- }
- free_iommu(iommu_page, pages);
- }
+ pci_unmap_single(hwdev, bus, size, 0);
free_pages((unsigned long)vaddr, get_order(size));
}
#ifdef CONFIG_IOMMU_LEAK
+
+#define SET_LEAK(x) if (iommu_leak_tab) \
+ iommu_leak_tab[x] = __builtin_return_address(0);
+#define CLEAR_LEAK(x) if (iommu_leak_tab) \
+ iommu_leak_tab[x] = 0;
+
/* Debugging aid for drivers that don't free their IOMMU tables */
static void **iommu_leak_tab;
static int leak_trace;
@@ -246,9 +250,12 @@ void dump_leak(void)
}
printk("\n");
}
+#else
+#define SET_LEAK(x)
+#define CLEAR_LEAK(x)
#endif
-static void iommu_full(struct pci_dev *dev, void *addr, size_t size, int dir)
+static void iommu_full(struct pci_dev *dev, size_t size, int dir)
{
/*
* Ran out of IOMMU space for this operation. This is very bad.
@@ -261,8 +268,8 @@ static void iommu_full(struct pci_dev *dev, void *addr, size_t size, int dir)
*/
printk(KERN_ERR
- "PCI-DMA: Out of IOMMU space for %p size %lu at device %s[%s]\n",
- addr,size, dev ? dev->dev.name : "?", dev ? pci_name(dev) : "?");
+ "PCI-DMA: Out of IOMMU space for %lu bytes at device %s[%s]\n",
+ size, dev ? dev->dev.name : "?", dev ? dev->slot_name : "?");
if (size > PAGE_SIZE*EMERGENCY_PAGES) {
if (dir == PCI_DMA_FROMDEVICE || dir == PCI_DMA_BIDIRECTIONAL)
@@ -279,24 +286,61 @@ static void iommu_full(struct pci_dev *dev, void *addr, size_t size, int dir)
static inline int need_iommu(struct pci_dev *dev, unsigned long addr, size_t size)
{
u64 mask = dev ? dev->dma_mask : 0xffffffff;
- int high = (~mask & (unsigned long)(addr + size)) != 0;
+ int high = addr + size >= mask;
int mmu = high;
- if (force_mmu)
+ if (force_iommu)
mmu = 1;
if (no_iommu) {
if (high)
- panic("pci_map_single: high address but no IOMMU.\n");
+ panic("PCI-DMA: high address but no IOMMU.\n");
mmu = 0;
}
return mmu;
}
+static inline int nonforced_iommu(struct pci_dev *dev, unsigned long addr, size_t size)
+{
+ u64 mask = dev ? dev->dma_mask : 0xffffffff;
+ int high = addr + size >= mask;
+ int mmu = high;
+ if (no_iommu) {
+ if (high)
+ panic("PCI-DMA: high address but no IOMMU.\n");
+ mmu = 0;
+ }
+ return mmu;
+}
+
+/* Map a single continuous physical area into the IOMMU.
+ * Caller needs to check if the iommu is needed and flush.
+ */
+static dma_addr_t pci_map_area(struct pci_dev *dev, unsigned long phys_mem,
+ size_t size, int dir)
+{
+ unsigned long npages = to_pages(phys_mem, size);
+ unsigned long iommu_page = alloc_iommu(npages);
+ if (iommu_page == -1) {
+ if (!nonforced_iommu(dev, phys_mem, size))
+ return phys_mem;
+ if (panic_on_overflow)
+ panic("pci_map_area overflow %lu bytes\n", size);
+ iommu_full(dev, size, dir);
+ return bad_dma_address;
+ }
+
+ int i;
+ for (i = 0; i < npages; i++) {
+ iommu_gatt_base[iommu_page + i] = GPTE_ENCODE(phys_mem);
+ SET_LEAK(iommu_page + i);
+ phys_mem += PAGE_SIZE;
+ }
+ return iommu_bus_base + iommu_page*PAGE_SIZE + (phys_mem & ~PAGE_MASK);
+}
+
+/* Map a single area into the IOMMU */
dma_addr_t pci_map_single(struct pci_dev *dev, void *addr, size_t size, int dir)
{
- unsigned long iommu_page;
unsigned long phys_mem, bus;
- int i, npages;
- int flush = 0;
BUG_ON(dir == PCI_DMA_NONE);
@@ -304,39 +348,158 @@ dma_addr_t pci_map_single(struct pci_dev *dev, void *addr, size_t size, int dir)
if (!need_iommu(dev, phys_mem, size))
return phys_mem;
- npages = round_up(size + ((u64)addr & ~PAGE_MASK), PAGE_SIZE) >> PAGE_SHIFT;
+ bus = pci_map_area(dev, phys_mem, size, dir);
+ flush_gart(dev);
+ return bus;
+}
- iommu_page = alloc_iommu(npages, &flush);
- if (iommu_page == -1) {
- iommu_full(dev, addr, size, dir);
- return iommu_bus_base;
+/* Fallback for pci_map_sg in case of overflow */
+static int pci_map_sg_nonforce(struct pci_dev *dev, struct scatterlist *sg,
+ int nents, int dir)
+{
+ int i;
+
+#ifdef CONFIG_IOMMU_DEBUG
+ printk(KERN_DEBUG "pci_map_sg overflow\n");
+#endif
+
+ for (i = 0; i < nents; i++ ) {
+ struct scatterlist *s = &sg[i];
+ unsigned long addr = page_to_phys(s->page) + s->offset;
+ if (nonforced_iommu(dev, addr, s->length)) {
+ addr = pci_map_area(dev, addr, s->length, dir);
+ if (addr == bad_dma_address) {
+ if (i > 0)
+ pci_unmap_sg(dev, sg, i, dir);
+ nents = 0;
+ break;
+ }
+ }
+ s->dma_address = addr;
+ }
+ flush_gart(dev);
+ return nents;
+}
+
+/* Map multiple scatterlist entries continuous into the first. */
+static int __pci_map_cont(struct scatterlist *sg, int start, int stopat,
+ struct scatterlist *sout, unsigned long pages)
+{
+ unsigned long iommu_start = alloc_iommu(pages);
+ if (iommu_start == -1)
+ return -1;
+
+ unsigned long iommu_page = iommu_start;
+ int i;
+
+ for (i = start; i < stopat; i++) {
+ struct scatterlist *s = &sg[i];
+ unsigned long start_addr = s->dma_address;
+ BUG_ON(i > 0 && s->offset);
+ if (i == start) {
+ *sout = *s;
+ sout->dma_address = iommu_bus_base;
+ sout->dma_address += iommu_page*PAGE_SIZE + s->offset;
+ } else {
+ sout->length += s->length;
+ }
+ unsigned long addr = start_addr;
+ while (addr < start_addr + s->length) {
+ iommu_gatt_base[iommu_page] = GPTE_ENCODE(addr);
+ SET_LEAK(iommu_page);
+ addr += PAGE_SIZE;
+ iommu_page++;
}
+ BUG_ON(i > 0 && addr % PAGE_SIZE);
+ }
+ BUG_ON(iommu_page - iommu_start != pages);
+ return 0;
+}
- phys_mem &= PAGE_MASK;
- for (i = 0; i < npages; i++, phys_mem += PAGE_SIZE) {
- BUG_ON(phys_mem & ~PHYSICAL_PAGE_MASK);
+static inline int pci_map_cont(struct scatterlist *sg, int start, int stopat,
+ struct scatterlist *sout,
+ unsigned long pages, int need)
+{
+ if (!need) {
+ BUG_ON(stopat - start != 1);
+ *sout = sg[start];
+ return 0;
+ }
+ return __pci_map_cont(sg, start, stopat, sout, pages);
+}
+
+#define PCI_NO_MERGE 0
- /*
- * Set coherent mapping here to avoid needing to flush
- * the caches on mapping.
+/*
+ * DMA map all entries in a scatterlist.
+ * Merge chunks that have page aligned sizes into a continuous mapping.
*/
- iommu_gatt_base[iommu_page + i] = GPTE_ENCODE(phys_mem);
+int pci_map_sg(struct pci_dev *dev, struct scatterlist *sg, int nents, int dir)
+{
+ int i;
+ int out;
+ int start;
+ unsigned long pages = 0;
+ int need = 0;
-#ifdef CONFIG_IOMMU_LEAK
- /* XXX need eventually caller of pci_map_sg */
- if (iommu_leak_tab)
- iommu_leak_tab[iommu_page + i] = __builtin_return_address(0);
-#endif
+ unsigned long size = 0;
+
+ BUG_ON(dir == PCI_DMA_NONE);
+ if (nents == 0)
+ return 0;
+ out = 0;
+ start = 0;
+ for (i = 0; i < nents; i++) {
+ struct scatterlist *s = &sg[i];
+ dma_addr_t addr = page_to_phys(s->page) + s->offset;
+ s->dma_address = addr;
+ BUG_ON(s->length == 0);
+
+ size += s->length;
+
+ /* Handle the previous not yet processed entries */
+ if (i > start) {
+ struct scatterlist *ps = &sg[i-1];
+ /* Can only merge when the last chunk ends on a page
+ boundary. */
+ if (PCI_NO_MERGE || !need || (i-1 > start && ps->offset) ||
+ (ps->offset + ps->length) % PAGE_SIZE) {
+ if (pci_map_cont(sg, start, i, sg+out, pages,
+ need) < 0)
+ goto error;
+ out++;
+ pages = 0;
+ start = i;
+ }
}
- if (flush)
- flush_gart();
- bus = iommu_bus_base + iommu_page*PAGE_SIZE;
- return bus + ((unsigned long)addr & ~PAGE_MASK);
+ need = need_iommu(dev, addr, s->length);
+ pages += to_pages(s->offset, s->length);
+ }
+ if (pci_map_cont(sg, start, i, sg+out, pages, need) < 0)
+ goto error;
+ out++;
+ flush_gart(dev);
+ if (out < nents)
+ sg[out].length = 0;
+ return out;
+
+error:
+ flush_gart(NULL);
+ pci_unmap_sg(dev, sg, nents, dir);
+ /* When it was forced try again unforced */
+ if (force_iommu)
+ return pci_map_sg_nonforce(dev, sg, nents, dir);
+ if (panic_on_overflow)
+ panic("pci_map_sg: overflow on %lu pages\n", pages);
+ iommu_full(dev, pages << PAGE_SHIFT, dir);
+ for (i = 0; i < nents; i++)
+ sg[i].dma_address = bad_dma_address;
+ return 0;
}
/*
- * Free a temporary PCI mapping.
+ * Free a PCI mapping.
*/
void pci_unmap_single(struct pci_dev *hwdev, dma_addr_t dma_addr,
size_t size, int direction)
@@ -347,20 +510,68 @@ void pci_unmap_single(struct pci_dev *hwdev, dma_addr_t dma_addr,
dma_addr > iommu_bus_base + iommu_size)
return;
iommu_page = (dma_addr - iommu_bus_base)>>PAGE_SHIFT;
- npages = round_up(size + (dma_addr & ~PAGE_MASK), PAGE_SIZE) >> PAGE_SHIFT;
+ npages = to_pages(dma_addr, size);
int i;
for (i = 0; i < npages; i++) {
iommu_gatt_base[iommu_page + i] = 0;
-#ifdef CONFIG_IOMMU_LEAK
- if (iommu_leak_tab)
- iommu_leak_tab[iommu_page + i] = 0;
-#endif
+ CLEAR_LEAK(iommu_page + i);
}
free_iommu(iommu_page, npages);
}
+/*
+ * Wrapper for pci_unmap_single working with scatterlists.
+ */
+void pci_unmap_sg(struct pci_dev *dev, struct scatterlist *sg, int nents,
+ int dir)
+{
+ int i;
+ for (i = 0; i < nents; i++) {
+ struct scatterlist *s = &sg[i];
+ if (!s->length)
+ break;
+ pci_unmap_single(dev, s->dma_address, s->length, dir);
+ }
+}
+
+int pci_dma_supported(struct pci_dev *dev, u64 mask)
+{
+ /* Copied from i386. Doesn't make much sense, because it will
+ only work for pci_alloc_consistent.
+ The caller just has to use GFP_DMA in this case. */
+ if (mask < 0x00ffffff)
+ return 0;
+
+ /* Tell the device to use SAC when IOMMU force is on.
+ This allows the driver to use cheaper accesses in some cases.
+
+ Problem with this is that if we overflow the IOMMU area
+ and return DAC as fallback address the device may not handle it correctly.
+ As a compromise we only do this if the IOMMU area is >= 256MB
+ which should make overflow unlikely enough.
+
+ As a special case some controllers have a 39bit address mode
+ that is as efficient as 32bit (aic79xx). Don't force SAC for these.
+ Assume all masks <= 40 bits are of this type. Normally this doesn't
+ make any difference, but gives more gentle handling of IOMMU overflow. */
+ if (force_iommu && (mask > 0xffffffffffULL) && (iommu_size >= sac_force_size)){
+ printk(KERN_INFO "%s: Force SAC with mask %Lx\n", dev->slot_name,mask);
+ return 0;
+ }
+
+ if (no_iommu && (mask < (end_pfn << PAGE_SHIFT)))
+ return 0;
+
+ return 1;
+}
+
+EXPORT_SYMBOL(pci_unmap_sg);
+EXPORT_SYMBOL(pci_map_sg);
EXPORT_SYMBOL(pci_map_single);
EXPORT_SYMBOL(pci_unmap_single);
+EXPORT_SYMBOL(pci_dma_supported);
+EXPORT_SYMBOL(no_iommu);
+EXPORT_SYMBOL(force_iommu);
static __init unsigned long check_iommu_size(unsigned long aper, u64 aper_size)
{
@@ -452,13 +663,12 @@ static __init int init_k8_gatt(struct agp_kern_info *info)
pci_write_config_dword(dev, 0x90, ctl);
}
- flush_gart();
+ flush_gart(NULL);
- printk("PCI-DMA: aperture base @ %x size %u KB\n", aper_base, aper_size>>10);
+ printk("PCI-DMA: aperture base @ %x size %u KB\n",aper_base, aper_size>>10);
return 0;
nommu:
- /* XXX: reject 0xffffffff mask now in pci mapping functions */
printk(KERN_ERR "PCI-DMA: More than 4GB of RAM and no IOMMU\n"
KERN_ERR "PCI-DMA: 32bit PCI IO may malfunction.");
return -1;
@@ -466,11 +676,12 @@ static __init int init_k8_gatt(struct agp_kern_info *info)
extern int agp_amdk8_init(void);
-int __init pci_iommu_init(void)
+static int __init pci_iommu_init(void)
{
struct agp_kern_info info;
unsigned long aper_size;
unsigned long iommu_start;
+ struct pci_dev *dev;
#ifndef CONFIG_AGP_AMD_8151
no_agp = 1;
@@ -482,7 +693,7 @@ int __init pci_iommu_init(void)
(agp_copy_info(&info) < 0);
#endif
- if (no_iommu || (!force_mmu && end_pfn < 0xffffffff>>PAGE_SHIFT)) {
+ if (no_iommu || (!force_iommu && end_pfn < 0xffffffff>>PAGE_SHIFT)) {
printk(KERN_INFO "PCI-DMA: Disabling IOMMU.\n");
no_iommu = 1;
return -1;
@@ -492,7 +703,7 @@ int __init pci_iommu_init(void)
int err = -1;
printk(KERN_INFO "PCI-DMA: Disabling AGP.\n");
no_agp = 1;
- if (force_mmu || end_pfn >= 0xffffffff>>PAGE_SHIFT)
+ if (force_iommu || end_pfn >= 0xffffffff>>PAGE_SHIFT)
err = init_k8_gatt(&info);
if (err < 0) {
printk(KERN_INFO "PCI-DMA: Disabling IOMMU.\n");
@@ -529,25 +740,38 @@ int __init pci_iommu_init(void)
set_bit_string(iommu_gart_bitmap, 0, EMERGENCY_PAGES);
agp_memory_reserved = iommu_size;
- printk(KERN_INFO"PCI-DMA: Reserving %luMB of IOMMU area in the AGP aperture\n",
+ printk(KERN_INFO
+ "PCI-DMA: Reserving %luMB of IOMMU area in the AGP aperture\n",
iommu_size>>20);
iommu_start = aper_size - iommu_size;
iommu_bus_base = info.aper_base + iommu_start;
- iommu_gatt_base = agp_gatt_table + (iommu_start>>PAGE_SHIFT);
bad_dma_address = iommu_bus_base;
+ iommu_gatt_base = agp_gatt_table + (iommu_start>>PAGE_SHIFT);
/*
- * Unmap the IOMMU part of the GART. The alias of the page is always mapped
- * with cache enabled and there is no full cache coherency across the GART
- * remapping. The unmapping avoids automatic prefetches from the CPU
- * allocating cache lines in there. All CPU accesses are done via the
- * direct mapping to the backing memory. The GART address is only used by PCI
+ * Unmap the IOMMU part of the GART. The alias of the page is
+ * always mapped with cache enabled and there is no full cache
+ * coherency across the GART remapping. The unmapping avoids
+ * automatic prefetches from the CPU allocating cache lines in
+ * there. All CPU accesses are done via the direct mapping to
+ * the backing memory. The GART address is only used by PCI
* devices.
*/
clear_kernel_mapping((unsigned long)__va(iommu_bus_base), iommu_size);
- flush_gart();
+ for_all_nb(dev) {
+ u32 flag;
+ int cpu = PCI_SLOT(dev->devfn) - 24;
+ if (cpu >= NR_CPUS)
+ continue;
+ northbridges[cpu] = dev;
+
+ pci_read_config_dword(dev, 0x9c, &flag); /* cache flush word */
+ northbridge_flush_word[cpu] = flag;
+ }
+
+ flush_gart(NULL);
return 0;
}
@@ -561,8 +785,8 @@ fs_initcall(pci_iommu_init);
off don't use the IOMMU
leak turn on simple iommu leak tracing (only when CONFIG_IOMMU_LEAK is on)
memaper[=order] allocate an own aperture over RAM with size 32MB^order.
- noforce don't force IOMMU usage. Should be fastest.
- force Force IOMMU and turn on unmap debugging.
+ noforce don't force IOMMU usage. Default.
+ force Force IOMMU.
*/
__init int iommu_setup(char *opt)
{
@@ -575,15 +799,19 @@ __init int iommu_setup(char *opt)
if (!memcmp(p,"off", 3))
no_iommu = 1;
if (!memcmp(p,"force", 5))
- force_mmu = 1;
+ force_iommu = 1;
if (!memcmp(p,"noforce", 7))
- force_mmu = 0;
+ force_iommu = 0;
if (!memcmp(p, "memaper", 7)) {
fallback_aper_force = 1;
p += 7;
if (*p == '=' && get_option(&p, &arg))
fallback_aper_order = arg;
}
+ if (!memcmp(p, "panic", 5))
+ panic_on_overflow = 1;
+ if (!memcmp(p, "nopanic", 7))
+ panic_on_overflow = 0;
#ifdef CONFIG_IOMMU_LEAK
if (!memcmp(p,"leak", 4)) {
leak_trace = 1;
diff --git a/arch/x86_64/kernel/pci-nommu.c b/arch/x86_64/kernel/pci-nommu.c
index 8240e5557f89..69bd270513e1 100644
--- a/arch/x86_64/kernel/pci-nommu.c
+++ b/arch/x86_64/kernel/pci-nommu.c
@@ -33,15 +33,30 @@ void pci_free_consistent(struct pci_dev *hwdev, size_t size,
free_pages((unsigned long)vaddr, get_order(size));
}
+int pci_dma_supported(struct pci_dev *hwdev, u64 mask)
+{
+ /*
+ * we fall back to GFP_DMA when the mask isn't all 1s,
+ * so we can't guarantee allocations that must be
+ * within a tighter range than GFP_DMA..
+ * RED-PEN this won't work for pci_map_single. Caller has to
+ * use GFP_DMA in the first place.
+ */
+ if (mask < 0x00ffffff)
+ return 0;
+
+ return 1;
+}
-static void __init check_ram(void)
+EXPORT_SYMBOL(pci_dma_supported);
+
+static int __init check_ram(void)
{
if (end_pfn >= 0xffffffff>>PAGE_SHIFT) {
printk(KERN_ERR "WARNING more than 4GB of memory but no IOMMU.\n"
KERN_ERR "WARNING 32bit PCI may malfunction.\n");
- /* Could play with highmem_start_page here to trick some subsystems
- into bounce buffers. Unfortunately that would require setting
- CONFIG_HIGHMEM too.
- */
}
+ return 0;
}
+__initcall(check_ram);
+
diff --git a/arch/x86_64/kernel/setup64.c b/arch/x86_64/kernel/setup64.c
index eff0bf79748b..b192e8c08a83 100644
--- a/arch/x86_64/kernel/setup64.c
+++ b/arch/x86_64/kernel/setup64.c
@@ -131,14 +131,16 @@ void __init setup_per_cpu_areas(void)
size = PERCPU_ENOUGH_ROOM;
#endif
- /* We don't support CPU hotplug, so only allocate as much as needed here */
-
- int maxi = max_t(unsigned, numnodes, num_online_cpus());
-
- for (i = 0; i < maxi; i++) {
+ for (i = 0; i < NR_CPUS; i++) {
+ unsigned char *ptr;
/* If possible allocate on the node of the CPU.
In case it doesn't exist round-robin nodes. */
- unsigned char *ptr = alloc_bootmem_node(NODE_DATA(i % numnodes), size);
+ if (!NODE_DATA(i % numnodes)) {
+ printk("cpu with no node %d, numnodes %d\n", i, numnodes);
+ ptr = alloc_bootmem(size);
+ } else {
+ ptr = alloc_bootmem_node(NODE_DATA(i % numnodes), size);
+ }
if (!ptr)
panic("Cannot allocate cpu data for CPU %d\n", i);
cpu_pda[i].data_offset = ptr - __per_cpu_start;
@@ -158,7 +160,6 @@ void pda_init(int cpu)
pda->me = pda;
pda->cpunumber = cpu;
pda->irqcount = -1;
- pda->data_offset = 0;
pda->kernelstack =
(unsigned long)stack_thread_info() - PDA_STACKOFFSET + THREAD_SIZE;
pda->active_mm = &init_mm;
@@ -170,14 +171,14 @@ void pda_init(int cpu)
pda->irqstackptr = boot_cpu_stack;
level4 = init_level4_pgt;
} else {
+ level4 = (pml4_t *)__get_free_pages(GFP_ATOMIC, 0);
+ if (!level4)
+ panic("Cannot allocate top level page for cpu %d", cpu);
pda->irqstackptr = (char *)
__get_free_pages(GFP_ATOMIC, IRQSTACK_ORDER);
if (!pda->irqstackptr)
- panic("cannot allocate irqstack for cpu %d\n", cpu);
- level4 = (pml4_t *)__get_free_pages(GFP_ATOMIC, 0);
+ panic("cannot allocate irqstack for cpu %d", cpu);
}
- if (!level4)
- panic("Cannot allocate top level page for cpu %d", cpu);
pda->level4_pgt = (unsigned long *)level4;
if (level4 != init_level4_pgt)
diff --git a/arch/x86_64/kernel/sys_x86_64.c b/arch/x86_64/kernel/sys_x86_64.c
index 9e0ffdfd9031..1e3e5941fd69 100644
--- a/arch/x86_64/kernel/sys_x86_64.c
+++ b/arch/x86_64/kernel/sys_x86_64.c
@@ -122,3 +122,17 @@ asmlinkage long wrap_sys_shmat(int shmid, char *shmaddr, int shmflg)
unsigned long raddr;
return sys_shmat(shmid,shmaddr,shmflg,&raddr) ?: (long)raddr;
}
+
+asmlinkage long sys_time64(long * tloc)
+{
+ struct timeval now;
+ int i;
+
+ do_gettimeofday(&now);
+ i = now.tv_sec;
+ if (tloc) {
+ if (put_user(i,tloc))
+ i = -EFAULT;
+ }
+ return i;
+}
diff --git a/arch/x86_64/kernel/x8664_ksyms.c b/arch/x86_64/kernel/x8664_ksyms.c
index 4297388cd1cc..2042d9295796 100644
--- a/arch/x86_64/kernel/x8664_ksyms.c
+++ b/arch/x86_64/kernel/x8664_ksyms.c
@@ -121,6 +121,7 @@ EXPORT_SYMBOL_NOVERS(__read_lock_failed);
EXPORT_SYMBOL(synchronize_irq);
EXPORT_SYMBOL(smp_call_function);
+EXPORT_SYMBOL(cpu_callout_map);
#endif
#ifdef CONFIG_VT
diff --git a/arch/x86_64/mm/k8topology.c b/arch/x86_64/mm/k8topology.c
index 04d716c22552..43df86e4f3ca 100644
--- a/arch/x86_64/mm/k8topology.c
+++ b/arch/x86_64/mm/k8topology.c
@@ -47,6 +47,7 @@ int __init k8_scan_nodes(unsigned long start, unsigned long end)
struct node nodes[MAXNODE];
int nodeid, i, nb;
int found = 0;
+ int nmax;
nb = find_northbridge();
if (nb < 0)
@@ -54,22 +55,28 @@ int __init k8_scan_nodes(unsigned long start, unsigned long end)
printk(KERN_INFO "Scanning NUMA topology in Northbridge %d\n", nb);
- numnodes = (1 << ((read_pci_config(0, nb, 0, 0x60 ) >> 4) & 3));
-
- printk(KERN_INFO "Assuming %d nodes\n", numnodes - 1);
+ nmax = (1 << ((read_pci_config(0, nb, 0, 0x60 ) >> 4) & 3));
+ numnodes = nmax;
memset(&nodes,0,sizeof(nodes));
prevbase = 0;
- for (i = 0; i < numnodes; i++) {
+ for (i = 0; i < 8; i++) {
unsigned long base,limit;
base = read_pci_config(0, nb, 1, 0x40 + i*8);
limit = read_pci_config(0, nb, 1, 0x44 + i*8);
nodeid = limit & 3;
+ if ((base & 3) == 0) {
+ if (i < nmax)
+ printk("Skipping disabled node %d\n", i);
+ continue;
+ }
+
if (!limit) {
- printk(KERN_ERR "Skipping node entry %d (base %lx)\n", i, base);
- return -1;
+ printk(KERN_INFO "Skipping node entry %d (base %lx)\n", i,
+ base);
+ continue;
}
if ((base >> 8) & 3 || (limit >> 8) & 3) {
printk(KERN_ERR "Node %d using interleaving mode %lx/%lx\n",
@@ -77,7 +84,8 @@ int __init k8_scan_nodes(unsigned long start, unsigned long end)
return -1;
}
if ((1UL << nodeid) & nodes_present) {
- printk(KERN_INFO "Node %d already present. Skipping\n", nodeid);
+ printk(KERN_INFO "Node %d already present. Skipping\n",
+ nodeid);
continue;
}
@@ -104,7 +112,7 @@ int __init k8_scan_nodes(unsigned long start, unsigned long end)
if (limit < base) {
printk(KERN_ERR "Node %d bogus settings %lx-%lx.\n",
nodeid, base, limit);
- return -1;
+ continue;
}
/* Could sort here, but pun for now. Should not happen anyroads. */
@@ -135,11 +143,26 @@ int __init k8_scan_nodes(unsigned long start, unsigned long end)
}
printk(KERN_INFO "Using node hash shift of %d\n", memnode_shift);
- for (i = 0; i < numnodes; i++) {
+ for (i = 0; i < MAXNODE; i++) {
if (nodes[i].start != nodes[i].end)
setup_node_bootmem(i, nodes[i].start, nodes[i].end);
}
+ /* There are unfortunately some poorly designed mainboards around
+ that only connect memory to a single CPU. This breaks the 1:1 cpu->node
+ mapping. To avoid this fill in the mapping for all possible
+ CPUs, as the number of CPUs is not known yet.
+ We round robin the existing nodes. */
+ int rr = 0;
+ for (i = 0; i < MAXNODE; i++) {
+ if (nodes_present & (1UL<<i))
+ continue;
+ if ((nodes_present >> rr) == 0)
+ rr = 0;
+ rr = ffz(~nodes_present >> rr);
+ node_data[i] = node_data[rr];
+ rr++;
+ }
+
return 0;
}
-
diff --git a/arch/x86_64/mm/numa.c b/arch/x86_64/mm/numa.c
index 851d1f4afd1d..c9ee3ee2b491 100644
--- a/arch/x86_64/mm/numa.c
+++ b/arch/x86_64/mm/numa.c
@@ -26,8 +26,6 @@ static int numa_off __initdata;
unsigned long nodes_present;
-static int emunodes __initdata;
-
int __init compute_hash_shift(struct node *nodes)
{
int i;
@@ -103,11 +101,8 @@ void __init setup_node_bootmem(int nodeid, unsigned long start, unsigned long en
reserve_bootmem_node(NODE_DATA(nodeid), nodedata_phys, pgdat_size);
reserve_bootmem_node(NODE_DATA(nodeid), bootmap_start, bootmap_pages<<PAGE_SHIFT);
- if (nodeid + 1 > numnodes) {
+ if (nodeid + 1 > numnodes)
numnodes = nodeid + 1;
- printk(KERN_INFO
- "setup_node_bootmem: enlarging numnodes to %d\n", numnodes);
- }
nodes_present |= (1UL << nodeid);
}
@@ -149,26 +144,6 @@ int __init numa_initmem_init(unsigned long start_pfn, unsigned long end_pfn)
printk(KERN_INFO "%s\n",
numa_off ? "NUMA turned off" : "No NUMA configuration found");
- if (!numa_off && emunodes > 0) {
- struct node nodes[MAXNODE];
- unsigned long nodesize = (end_pfn << PAGE_SHIFT) / emunodes;
- int i;
- if (emunodes > MAXNODE)
- emunodes = MAXNODE;
- memset(&nodes, 0, sizeof(nodes));
- printk(KERN_INFO "Faking %d nodes of size %ld MB\n", emunodes, nodesize>>20);
- for (i = 0; i < emunodes; i++) {
- unsigned long end = (i+1)*nodesize;
- if (i == emunodes-1)
- end = end_pfn << PAGE_SHIFT;
- nodes[i].start = i * nodesize;
- nodes[i].end = end;
- setup_node_bootmem(i, nodes[i].start, nodes[i].end);
- }
- memnode_shift = compute_hash_shift(nodes);
- return 0;
- }
-
printk(KERN_INFO "Faking a node at %016lx-%016lx\n",
start_pfn << PAGE_SHIFT,
end_pfn << PAGE_SHIFT);
@@ -176,6 +151,7 @@ int __init numa_initmem_init(unsigned long start_pfn, unsigned long end_pfn)
fake_node = 1;
memnode_shift = 63;
memnodemap[0] = 0;
+ numnodes = 1;
setup_node_bootmem(0, start_pfn<<PAGE_SHIFT, end_pfn<<PAGE_SHIFT);
return -1;
}
@@ -199,13 +175,10 @@ void __init paging_init(void)
}
/* [numa=off] */
-/* [numa=emunodes] */
__init int numa_setup(char *opt)
{
if (!strncmp(opt,"off",3))
numa_off = 1;
- if (isdigit(opt[0]))
- emunodes = simple_strtoul(opt, NULL, 10);
return 1;
}
diff --git a/drivers/block/DAC960.h b/drivers/block/DAC960.h
index b3e7d4ef2024..7eb20b3e2627 100644
--- a/drivers/block/DAC960.h
+++ b/drivers/block/DAC960.h
@@ -65,7 +65,7 @@
*/
#define DAC690_V1_PciDmaMask 0xffffffff
-#define DAC690_V2_PciDmaMask 0xffffffffffffffff
+#define DAC690_V2_PciDmaMask 0xffffffffffffffffULL
/*
Define a Boolean data type.
diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c
index c211537bb529..e16a993f539b 100644
--- a/drivers/block/cciss.c
+++ b/drivers/block/cciss.c
@@ -2457,7 +2457,7 @@ static int __init cciss_init_one(struct pci_dev *pdev,
hba[i]->pdev = pdev;
/* configure PCI DMA stuff */
- if (!pci_set_dma_mask(pdev, (u64) 0xffffffffffffffff))
+ if (!pci_set_dma_mask(pdev, 0xffffffffffffffffULL))
printk("cciss: using DAC cycles\n");
else if (!pci_set_dma_mask(pdev, 0xffffffff))
printk("cciss: not using DAC cycles\n");
diff --git a/drivers/block/cciss_scsi.c b/drivers/block/cciss_scsi.c
index 6951231d4ed5..e3136c14ef4b 100644
--- a/drivers/block/cciss_scsi.c
+++ b/drivers/block/cciss_scsi.c
@@ -896,13 +896,14 @@ cciss_scsi_do_inquiry(ctlr_info_t *c, unsigned char *scsi3addr,
spin_lock_irqsave(CCISS_LOCK(c->ctlr), flags);
cp = scsi_cmd_alloc(c);
spin_unlock_irqrestore(CCISS_LOCK(c->ctlr), flags);
- ei = cp->err_info;
if (cp == NULL) { /* trouble... */
printk("cmd_alloc returned NULL!\n");
return -1;
}
+ ei = cp->err_info;
+
cdb[0] = CISS_INQUIRY;
cdb[1] = 0;
cdb[2] = 0;
diff --git a/drivers/block/paride/pd.c b/drivers/block/paride/pd.c
index 0735bd7375f3..5c254cbc322e 100644
--- a/drivers/block/paride/pd.c
+++ b/drivers/block/paride/pd.c
@@ -654,7 +654,7 @@ static int pd_probe_drive(struct pd_unit *disk)
return pd_identify(disk);
}
-static struct request_queue pd_queue;
+static struct request_queue *pd_queue;
static int pd_detect(void)
{
@@ -704,7 +704,7 @@ static int pd_detect(void)
set_capacity(p, disk->capacity);
disk->gd = p;
p->private_data = disk;
- p->queue = &pd_queue;
+ p->queue = pd_queue;
add_disk(p);
}
}
@@ -782,7 +782,7 @@ static inline void next_request(int success)
spin_lock_irqsave(&pd_lock, saved_flags);
end_request(pd_req, success);
pd_busy = 0;
- do_pd_request(&pd_queue);
+ do_pd_request(pd_queue);
spin_unlock_irqrestore(&pd_lock, saved_flags);
}
@@ -890,20 +890,30 @@ static int __init pd_init(void)
{
if (disable)
return -1;
- if (register_blkdev(major, name))
- return -1;
- blk_init_queue(&pd_queue, do_pd_request, &pd_lock);
- blk_queue_max_sectors(&pd_queue, cluster);
+ pd_queue = blk_init_queue(do_pd_request, &pd_lock);
+ if (!pd_queue)
+ goto out1;
+
+ blk_queue_max_sectors(pd_queue, cluster);
+
+ if (register_blkdev(major, name))
+ goto out2;
printk("%s: %s version %s, major %d, cluster %d, nice %d\n",
name, name, PD_VERSION, major, cluster, nice);
pd_init_units();
- if (!pd_detect()) {
- unregister_blkdev(major, name);
- return -1;
- }
+ if (!pd_detect())
+ goto out3;
+
return 0;
+
+out3:
+ unregister_blkdev(major, name);
+out2:
+ blk_cleanup_queue(pd_queue);
+out1:
+ return -1;
}
static void __exit pd_exit(void)
@@ -920,7 +930,7 @@ static void __exit pd_exit(void)
pi_release(disk->pi);
}
}
- blk_cleanup_queue(&pd_queue);
+ blk_cleanup_queue(pd_queue);
}
MODULE_LICENSE("GPL");
diff --git a/drivers/char/agp/agp.h b/drivers/char/agp/agp.h
index aa9ee0ef61a4..f17fd51b5d35 100644
--- a/drivers/char/agp/agp.h
+++ b/drivers/char/agp/agp.h
@@ -395,6 +395,7 @@ unsigned long agp_generic_mask_memory(unsigned long addr, int type);
#define AGPSTAT 0x4
#define AGPCMD 0x8
#define AGPNISTAT 0xc
+#define AGPCTRL 0x10
#define AGPNEPG 0x16
#define AGPNICMD 0x20
diff --git a/drivers/char/agp/ali-agp.c b/drivers/char/agp/ali-agp.c
index 0f3934f803bc..9f3032bfb990 100644
--- a/drivers/char/agp/ali-agp.c
+++ b/drivers/char/agp/ali-agp.c
@@ -9,8 +9,6 @@
#include <linux/agp_backend.h>
#include "agp.h"
-static int agp_try_unsupported __initdata = 0;
-
static int ali_fetch_size(void)
{
int i;
@@ -292,16 +290,10 @@ static int __init agp_ali_probe(struct pci_dev *pdev,
goto found;
}
- if (!agp_try_unsupported) {
- printk(KERN_ERR PFX
- "Unsupported ALi chipset (device id: %04x),"
- " you might want to try agp_try_unsupported=1.\n",
- pdev->device);
- return -ENODEV;
- }
+ printk(KERN_ERR PFX "Unsupported ALi chipset (device id: %04x)\n",
+ pdev->device);
+ return -ENODEV;
- printk(KERN_WARNING PFX "Trying generic ALi routines"
- " for device id: %04x\n", pdev->device);
found:
bridge = agp_alloc_bridge();
@@ -328,6 +320,7 @@ found:
devs[j].chipset_name = "M1641";
break;
case 0x43:
+ devs[j].chipset_name = "M????";
break;
case 0x47:
devs[j].chipset_name = "M1647";
@@ -397,7 +390,6 @@ static void __exit agp_ali_cleanup(void)
module_init(agp_ali_init);
module_exit(agp_ali_cleanup);
-MODULE_PARM(agp_try_unsupported, "1i");
MODULE_AUTHOR("Dave Jones <davej@codemonkey.org.uk>");
MODULE_LICENSE("GPL and additional rights");
diff --git a/drivers/char/agp/amd-k7-agp.c b/drivers/char/agp/amd-k7-agp.c
index 84790a7df555..51aaf5d4f811 100644
--- a/drivers/char/agp/amd-k7-agp.c
+++ b/drivers/char/agp/amd-k7-agp.c
@@ -11,8 +11,6 @@
#include <linux/mm.h>
#include "agp.h"
-static int agp_try_unsupported __initdata = 0;
-
struct amd_page_map {
unsigned long *real;
unsigned long *remapped;
@@ -404,16 +402,9 @@ static int __init agp_amdk7_probe(struct pci_dev *pdev,
}
}
- if (!agp_try_unsupported) {
- printk(KERN_ERR PFX
- "Unsupported AMD chipset (device id: %04x),"
- " you might want to try agp_try_unsupported=1.\n",
+ printk(KERN_ERR PFX "Unsupported AMD chipset (device id: %04x)\n",
pdev->device);
- return -ENODEV;
- }
-
- printk(KERN_WARNING PFX "Trying generic AMD routines"
- " for device id: %04x\n", pdev->device);
+ return -ENODEV;
found:
bridge = agp_alloc_bridge();
@@ -476,5 +467,4 @@ static void __exit agp_amdk7_cleanup(void)
module_init(agp_amdk7_init);
module_exit(agp_amdk7_cleanup);
-MODULE_PARM(agp_try_unsupported, "1i");
MODULE_LICENSE("GPL and additional rights");
diff --git a/drivers/char/agp/backend.c b/drivers/char/agp/backend.c
index e26057c14e2a..9502d803d230 100644
--- a/drivers/char/agp/backend.c
+++ b/drivers/char/agp/backend.c
@@ -106,7 +106,11 @@ static int agp_find_max(void)
{
long memory, index, result;
- memory = (num_physpages << PAGE_SHIFT) >> 20;
+#if PAGE_SHIFT < 20
+ memory = num_physpages >> (20 - PAGE_SHIFT);
+#else
+ memory = num_physpages << (PAGE_SHIFT - 20);
+#endif
index = 1;
while ((memory > maxes_table[index].mem) && (index < 8))
diff --git a/drivers/char/agp/generic.c b/drivers/char/agp/generic.c
index ed6cdb26e52d..50e74f6d4754 100644
--- a/drivers/char/agp/generic.c
+++ b/drivers/char/agp/generic.c
@@ -459,9 +459,9 @@ static void agp_v3_parse_one(u32 *mode, u32 *cmd, u32 *tmp)
/* Clear out unwanted bits. */
if (*cmd & AGPSTAT3_8X)
- *cmd = ~(AGPSTAT3_4X | AGPSTAT3_RSVD);
+ *cmd &= ~(AGPSTAT3_4X | AGPSTAT3_RSVD);
if (*cmd & AGPSTAT3_4X)
- *cmd = ~(AGPSTAT3_8X | AGPSTAT3_RSVD);
+ *cmd &= ~(AGPSTAT3_8X | AGPSTAT3_RSVD);
}
//FIXME: This doesn't smell right.
@@ -545,7 +545,7 @@ EXPORT_SYMBOL(get_agp_version);
void agp_generic_enable(u32 mode)
{
- u32 command;
+ u32 command, temp;
u32 agp3;
get_agp_version(agp_bridge);
@@ -577,7 +577,13 @@ void agp_generic_enable(u32 mode)
agp_device_command(command, TRUE);
return;
} else {
- printk (KERN_INFO PFX "Device is in legacy mode,"
+ /* Disable calibration cycle in RX91<1> when not in AGP3.0 mode of operation.*/
+ command &= ~(7<<10) ;
+ pci_read_config_dword(agp_bridge->dev, agp_bridge->capndx+AGPCTRL, &temp);
+ temp |= (1<<9);
+ pci_write_config_dword(agp_bridge->dev, agp_bridge->capndx+AGPCTRL, temp);
+
+ printk (KERN_INFO PFX "Device is in legacy mode,"
" falling back to 2.x\n");
}
}
diff --git a/drivers/char/agp/intel-agp.c b/drivers/char/agp/intel-agp.c
index f99aafb56de5..d908c004990b 100644
--- a/drivers/char/agp/intel-agp.c
+++ b/drivers/char/agp/intel-agp.c
@@ -13,9 +13,6 @@
#include <linux/agp_backend.h>
#include "agp.h"
-static int agp_try_unsupported __initdata = 0;
-
-
static struct aper_size_info_fixed intel_i810_sizes[] =
{
{64, 16384, 4},
@@ -1358,15 +1355,9 @@ static int __init agp_intel_probe(struct pci_dev *pdev,
name = "E7205";
break;
default:
- if (!agp_try_unsupported) {
- printk(KERN_ERR PFX
- "Unsupported Intel chipset (device id: %04x),"
- " you might want to try agp_try_unsupported=1.\n",
+ printk(KERN_ERR PFX "Unsupported Intel chipset (device id: %04x)\n",
pdev->device);
- return -ENODEV;
- }
- bridge->driver = &intel_generic_driver;
- break;
+ return -ENODEV;
};
bridge->dev = pdev;
@@ -1485,6 +1476,5 @@ static void __exit agp_intel_cleanup(void)
module_init(agp_intel_init);
module_exit(agp_intel_cleanup);
-MODULE_PARM(agp_try_unsupported, "1i");
MODULE_AUTHOR("Dave Jones <davej@codemonkey.org.uk>");
MODULE_LICENSE("GPL and additional rights");
diff --git a/drivers/char/agp/nvidia-agp.c b/drivers/char/agp/nvidia-agp.c
index ed34f4ffc982..cf76ee9c4090 100644
--- a/drivers/char/agp/nvidia-agp.c
+++ b/drivers/char/agp/nvidia-agp.c
@@ -25,9 +25,6 @@
#define NVIDIA_3_APBASE 0x50
#define NVIDIA_3_APLIMIT 0x54
-
-static int agp_try_unsupported __initdata = 0;
-
static struct _nvidia_private {
struct pci_dev *dev_1;
struct pci_dev *dev_2;
@@ -299,17 +296,9 @@ static int __init agp_nvidia_probe(struct pci_dev *pdev,
nvidia_private.wbc_mask = 0x80000000;
break;
default:
- if (!agp_try_unsupported) {
- printk(KERN_ERR PFX
- "Unsupported NVIDIA chipset (device id: %04x),"
- " you might want to try agp_try_unsupported=1.\n",
+ printk(KERN_ERR PFX "Unsupported NVIDIA chipset (device id: %04x)\n",
pdev->device);
- return -ENODEV;
- }
- printk(KERN_WARNING PFX
- "Trying generic NVIDIA routines for device id: %04x\n",
- pdev->device);
- break;
+ return -ENODEV;
}
bridge = agp_alloc_bridge();
@@ -372,7 +361,6 @@ static void __exit agp_nvidia_cleanup(void)
module_init(agp_nvidia_init);
module_exit(agp_nvidia_cleanup);
-MODULE_PARM(agp_try_unsupported, "1i");
MODULE_LICENSE("GPL and additional rights");
MODULE_AUTHOR("NVIDIA Corporation");
diff --git a/drivers/char/agp/sis-agp.c b/drivers/char/agp/sis-agp.c
index 7ebe1e362f3f..567b0d511add 100644
--- a/drivers/char/agp/sis-agp.c
+++ b/drivers/char/agp/sis-agp.c
@@ -8,8 +8,6 @@
#include <linux/agp_backend.h>
#include "agp.h"
-static int agp_try_unsupported __initdata = 0;
-
static int sis_fetch_size(void)
{
u8 temp_size;
@@ -187,16 +185,9 @@ static int __init agp_sis_probe(struct pci_dev *pdev,
}
}
- if (!agp_try_unsupported) {
- printk(KERN_ERR PFX
- "Unsupported SiS chipset (device id: %04x),"
- " you might want to try agp_try_unsupported=1.\n",
+ printk(KERN_ERR PFX "Unsupported SiS chipset (device id: %04x)\n",
pdev->device);
- return -ENODEV;
- }
-
- printk(KERN_WARNING PFX "Trying generic SiS routines"
- " for device id: %04x\n", pdev->device);
+ return -ENODEV;
found:
bridge = agp_alloc_bridge();
@@ -258,5 +249,4 @@ static void __exit agp_sis_cleanup(void)
module_init(agp_sis_init);
module_exit(agp_sis_cleanup);
-MODULE_PARM(agp_try_unsupported, "1i");
MODULE_LICENSE("GPL and additional rights");
diff --git a/drivers/char/agp/sworks-agp.c b/drivers/char/agp/sworks-agp.c
index 6ad6cd5ff57b..5e9ff6f2107a 100644
--- a/drivers/char/agp/sworks-agp.c
+++ b/drivers/char/agp/sworks-agp.c
@@ -8,8 +8,6 @@
#include <linux/agp_backend.h>
#include "agp.h"
-static int agp_try_unsupported __initdata = 0;
-
struct serverworks_page_map {
unsigned long *real;
unsigned long *remapped;
@@ -457,9 +455,9 @@ static int __init agp_serverworks_probe(struct pci_dev *pdev,
case 0x0007:
break;
default:
- if (!agp_try_unsupported)
- return -ENODEV;
- break;
+ printk(KERN_ERR PFX "Unsupported Serverworks chipset "
+ "(device id: %04x)\n", pdev->device);
+ return -ENODEV;
}
serverworks_private.svrwrks_dev = bridge_dev;
@@ -542,6 +540,5 @@ static void __exit agp_serverworks_cleanup(void)
module_init(agp_serverworks_init);
module_exit(agp_serverworks_cleanup);
-MODULE_PARM(agp_try_unsupported, "1i");
MODULE_LICENSE("GPL and additional rights");
diff --git a/drivers/char/agp/uninorth-agp.c b/drivers/char/agp/uninorth-agp.c
index e4192313d73e..c75ec0120bd5 100644
--- a/drivers/char/agp/uninorth-agp.c
+++ b/drivers/char/agp/uninorth-agp.c
@@ -10,8 +10,6 @@
#include <asm/pci-bridge.h>
#include "agp.h"
-static int agp_try_unsupported __initdata = 0;
-
static int uninorth_fetch_size(void)
{
int i;
@@ -324,15 +322,9 @@ static int __init agp_uninorth_probe(struct pci_dev *pdev,
}
}
- if (!agp_try_unsupported) {
- printk(KERN_ERR PFX "Unsupported Apple chipset"
- " (device id: %04x).\n", pdev->device);
- printk(KERN_ERR PFX "You might want to try"
- " agp_try_unsupported=1\n");
- return -ENODEV;
- }
- printk(KERN_ERR PFX "Trying generic Uninorth routines"
- " for device id %04x\n", pdev->device);
+ printk(KERN_ERR PFX "Unsupported Apple chipset (device id: %04x).\n",
+ pdev->device);
+ return -ENODEV;
found:
bridge = agp_alloc_bridge();
@@ -392,6 +384,5 @@ static void __exit agp_uninorth_cleanup(void)
module_init(agp_uninorth_init);
module_exit(agp_uninorth_cleanup);
-MODULE_PARM(agp_try_unsupported, "1i");
MODULE_AUTHOR("Ben Herrenschmidt & Paul Mackerras");
MODULE_LICENSE("GPL");
diff --git a/drivers/char/agp/via-agp.c b/drivers/char/agp/via-agp.c
index f421458432a3..8726826adbc9 100644
--- a/drivers/char/agp/via-agp.c
+++ b/drivers/char/agp/via-agp.c
@@ -9,9 +9,6 @@
#include <linux/agp_backend.h>
#include "agp.h"
-static int agp_try_unsupported __initdata = 0;
-
-
static int via_fetch_size(void)
{
int i;
@@ -123,6 +120,14 @@ static int via_configure_agp3(void)
/* attbase - aperture GATT base */
pci_write_config_dword(agp_bridge->dev, VIA_AGP3_ATTBASE,
agp_bridge->gatt_bus_addr & 0xfffff000);
+
+ /* 1. Enable GTLB in RX90<7>, all AGP aperture access needs to fetch
+ * translation table first.
+ * 2. Enable AGP aperture in RX91<0>. This bit controls the enabling of the
+ * graphics AGP aperture for the AGP3.0 port.
+ */
+ pci_read_config_dword(agp_bridge->dev, VIA_AGP3_GARTCTRL, &temp);
+ pci_write_config_dword(agp_bridge->dev, VIA_AGP3_GARTCTRL, temp | (3<<7));
return 0;
}
@@ -382,16 +387,9 @@ static int __init agp_via_probe(struct pci_dev *pdev,
}
}
- if (!agp_try_unsupported) {
- printk(KERN_ERR PFX
- "Unsupported VIA chipset (device id: %04x),"
- " you might want to try agp_try_unsupported=1.\n",
+ printk(KERN_ERR PFX "Unsupported VIA chipset (device id: %04x)\n",
pdev->device);
- return -ENODEV;
- }
-
- printk(KERN_WARNING PFX "Trying generic VIA routines"
- " for device id: %04x\n", pdev->device);
+ return -ENODEV;
found:
bridge = agp_alloc_bridge();
@@ -470,6 +468,5 @@ static void __exit agp_via_cleanup(void)
module_init(agp_via_init);
module_exit(agp_via_cleanup);
-MODULE_PARM(agp_try_unsupported, "1i");
MODULE_LICENSE("GPL and additional rights");
MODULE_AUTHOR("Dave Jones <davej@codemonkey.org.uk>");
diff --git a/drivers/char/drm/drm_agpsupport.h b/drivers/char/drm/drm_agpsupport.h
index 67e91b6e5aa0..12c41a051c11 100644
--- a/drivers/char/drm/drm_agpsupport.h
+++ b/drivers/char/drm/drm_agpsupport.h
@@ -105,7 +105,8 @@ int DRM(agp_acquire)(struct inode *inode, struct file *filp,
if (!dev->agp || dev->agp->acquired || !drm_agp->acquire)
return -EINVAL;
- if ((retcode = drm_agp->acquire())) return retcode;
+ if ((retcode = drm_agp->acquire()))
+ return retcode;
dev->agp->acquired = 1;
return 0;
}
@@ -142,7 +143,8 @@ int DRM(agp_release)(struct inode *inode, struct file *filp,
*/
void DRM(agp_do_release)(void)
{
- if (drm_agp->release) drm_agp->release();
+ if (drm_agp->release)
+ drm_agp->release();
}
/**
@@ -200,7 +202,8 @@ int DRM(agp_alloc)(struct inode *inode, struct file *filp,
unsigned long pages;
u32 type;
- if (!dev->agp || !dev->agp->acquired) return -EINVAL;
+ if (!dev->agp || !dev->agp->acquired)
+ return -EINVAL;
if (copy_from_user(&request, (drm_agp_buffer_t *)arg, sizeof(request)))
return -EFAULT;
if (!(entry = DRM(alloc)(sizeof(*entry), DRM_MEM_AGPLISTS)))
@@ -222,11 +225,12 @@ int DRM(agp_alloc)(struct inode *inode, struct file *filp,
entry->pages = pages;
entry->prev = NULL;
entry->next = dev->agp->memory;
- if (dev->agp->memory) dev->agp->memory->prev = entry;
+ if (dev->agp->memory)
+ dev->agp->memory->prev = entry;
dev->agp->memory = entry;
request.handle = entry->handle;
- request.physical = memory->physical;
+ request.physical = memory->physical;
if (copy_to_user((drm_agp_buffer_t *)arg, &request, sizeof(request))) {
dev->agp->memory = entry->next;
@@ -253,7 +257,8 @@ static drm_agp_mem_t *DRM(agp_lookup_entry)(drm_device_t *dev,
drm_agp_mem_t *entry;
for (entry = dev->agp->memory; entry; entry = entry->next) {
- if (entry->handle == handle) return entry;
+ if (entry->handle == handle)
+ return entry;
}
return NULL;
}
@@ -279,12 +284,14 @@ int DRM(agp_unbind)(struct inode *inode, struct file *filp,
drm_agp_mem_t *entry;
int ret;
- if (!dev->agp || !dev->agp->acquired) return -EINVAL;
+ if (!dev->agp || !dev->agp->acquired)
+ return -EINVAL;
if (copy_from_user(&request, (drm_agp_binding_t *)arg, sizeof(request)))
return -EFAULT;
if (!(entry = DRM(agp_lookup_entry)(dev, request.handle)))
return -EINVAL;
- if (!entry->bound) return -EINVAL;
+ if (!entry->bound)
+ return -EINVAL;
ret = DRM(unbind_agp)(entry->memory);
if (ret == 0)
entry->bound = 0;
@@ -320,9 +327,11 @@ int DRM(agp_bind)(struct inode *inode, struct file *filp,
return -EFAULT;
if (!(entry = DRM(agp_lookup_entry)(dev, request.handle)))
return -EINVAL;
- if (entry->bound) return -EINVAL;
+ if (entry->bound)
+ return -EINVAL;
page = (request.offset + PAGE_SIZE - 1) / PAGE_SIZE;
- if ((retcode = DRM(bind_agp)(entry->memory, page))) return retcode;
+ if ((retcode = DRM(bind_agp)(entry->memory, page)))
+ return retcode;
entry->bound = dev->agp->base + (page << PAGE_SHIFT);
DRM_DEBUG("base = 0x%lx entry->bound = 0x%lx\n",
dev->agp->base, entry->bound);
@@ -351,16 +360,23 @@ int DRM(agp_free)(struct inode *inode, struct file *filp,
drm_agp_buffer_t request;
drm_agp_mem_t *entry;
- if (!dev->agp || !dev->agp->acquired) return -EINVAL;
+ if (!dev->agp || !dev->agp->acquired)
+ return -EINVAL;
if (copy_from_user(&request, (drm_agp_buffer_t *)arg, sizeof(request)))
return -EFAULT;
if (!(entry = DRM(agp_lookup_entry)(dev, request.handle)))
return -EINVAL;
- if (entry->bound) DRM(unbind_agp)(entry->memory);
+ if (entry->bound)
+ DRM(unbind_agp)(entry->memory);
+
+ if (entry->prev)
+ entry->prev->next = entry->next;
+ else
+ dev->agp->memory = entry->next;
+
+ if (entry->next)
+ entry->next->prev = entry->prev;
- if (entry->prev) entry->prev->next = entry->next;
- else dev->agp->memory = entry->next;
- if (entry->next) entry->next->prev = entry->prev;
DRM(free_agp)(entry->memory, entry->pages);
DRM(free)(entry, sizeof(*entry), DRM_MEM_AGPLISTS);
return 0;
@@ -415,14 +431,16 @@ void DRM(agp_uninit)(void)
/** Calls drm_agp->allocate_memory() */
struct agp_memory *DRM(agp_allocate_memory)(size_t pages, u32 type)
{
- if (!drm_agp->allocate_memory) return NULL;
+ if (!drm_agp->allocate_memory)
+ return NULL;
return drm_agp->allocate_memory(pages, type);
}
/** Calls drm_agp->free_memory() */
int DRM(agp_free_memory)(struct agp_memory *handle)
{
- if (!handle || !drm_agp->free_memory) return 0;
+ if (!handle || !drm_agp->free_memory)
+ return 0;
drm_agp->free_memory(handle);
return 1;
}
@@ -430,14 +448,16 @@ int DRM(agp_free_memory)(struct agp_memory *handle)
/** Calls drm_agp->bind_memory() */
int DRM(agp_bind_memory)(struct agp_memory *handle, off_t start)
{
- if (!handle || !drm_agp->bind_memory) return -EINVAL;
+ if (!handle || !drm_agp->bind_memory)
+ return -EINVAL;
return drm_agp->bind_memory(handle, start);
}
/** Calls drm_agp->unbind_memory() */
int DRM(agp_unbind_memory)(struct agp_memory *handle)
{
- if (!handle || !drm_agp->unbind_memory) return -EINVAL;
+ if (!handle || !drm_agp->unbind_memory)
+ return -EINVAL;
return drm_agp->unbind_memory(handle);
}
diff --git a/drivers/char/drm/gamma_dma.c b/drivers/char/drm/gamma_dma.c
index 9608c37a1b77..9a8eba82b9dc 100644
--- a/drivers/char/drm/gamma_dma.c
+++ b/drivers/char/drm/gamma_dma.c
@@ -44,9 +44,14 @@ static inline void gamma_dma_dispatch(drm_device_t *dev, unsigned long address,
drm_gamma_private_t *dev_priv =
(drm_gamma_private_t *)dev->dev_private;
mb();
- while ( GAMMA_READ(GAMMA_INFIFOSPACE) < 2);
+ while ( GAMMA_READ(GAMMA_INFIFOSPACE) < 2)
+ cpu_relax();
+
GAMMA_WRITE(GAMMA_DMAADDRESS, address);
- while (GAMMA_READ(GAMMA_GCOMMANDSTATUS) != 4);
+
+ while (GAMMA_READ(GAMMA_GCOMMANDSTATUS) != 4)
+ cpu_relax();
+
GAMMA_WRITE(GAMMA_DMACOUNT, length / 4);
}
@@ -54,16 +59,18 @@ void gamma_dma_quiescent_single(drm_device_t *dev)
{
drm_gamma_private_t *dev_priv =
(drm_gamma_private_t *)dev->dev_private;
- while (GAMMA_READ(GAMMA_DMACOUNT));
+ while (GAMMA_READ(GAMMA_DMACOUNT))
+ cpu_relax();
- while (GAMMA_READ(GAMMA_INFIFOSPACE) < 2);
+ while (GAMMA_READ(GAMMA_INFIFOSPACE) < 2)
+ cpu_relax();
GAMMA_WRITE(GAMMA_FILTERMODE, 1 << 10);
GAMMA_WRITE(GAMMA_SYNC, 0);
do {
while (!GAMMA_READ(GAMMA_OUTFIFOWORDS))
- ;
+ cpu_relax();
} while (GAMMA_READ(GAMMA_OUTPUTFIFO) != GAMMA_SYNC_TAG);
}
@@ -71,9 +78,11 @@ void gamma_dma_quiescent_dual(drm_device_t *dev)
{
drm_gamma_private_t *dev_priv =
(drm_gamma_private_t *)dev->dev_private;
- while (GAMMA_READ(GAMMA_DMACOUNT));
+ while (GAMMA_READ(GAMMA_DMACOUNT))
+ cpu_relax();
- while (GAMMA_READ(GAMMA_INFIFOSPACE) < 3);
+ while (GAMMA_READ(GAMMA_INFIFOSPACE) < 3)
+ cpu_relax();
GAMMA_WRITE(GAMMA_BROADCASTMASK, 3);
GAMMA_WRITE(GAMMA_FILTERMODE, 1 << 10);
@@ -81,12 +90,14 @@ void gamma_dma_quiescent_dual(drm_device_t *dev)
/* Read from first MX */
do {
- while (!GAMMA_READ(GAMMA_OUTFIFOWORDS));
+ while (!GAMMA_READ(GAMMA_OUTFIFOWORDS))
+ cpu_relax();
} while (GAMMA_READ(GAMMA_OUTPUTFIFO) != GAMMA_SYNC_TAG);
/* Read from second MX */
do {
- while (!GAMMA_READ(GAMMA_OUTFIFOWORDS + 0x10000));
+ while (!GAMMA_READ(GAMMA_OUTFIFOWORDS + 0x10000))
+ cpu_relax();
} while (GAMMA_READ(GAMMA_OUTPUTFIFO + 0x10000) != GAMMA_SYNC_TAG);
}
@@ -94,14 +105,15 @@ void gamma_dma_ready(drm_device_t *dev)
{
drm_gamma_private_t *dev_priv =
(drm_gamma_private_t *)dev->dev_private;
- while (GAMMA_READ(GAMMA_DMACOUNT));
+ while (GAMMA_READ(GAMMA_DMACOUNT))
+ cpu_relax();
}
static inline int gamma_dma_is_ready(drm_device_t *dev)
{
drm_gamma_private_t *dev_priv =
(drm_gamma_private_t *)dev->dev_private;
- return(!GAMMA_READ(GAMMA_DMACOUNT));
+ return (!GAMMA_READ(GAMMA_DMACOUNT));
}
irqreturn_t gamma_dma_service(int irq, void *device, struct pt_regs *regs)
@@ -113,7 +125,9 @@ irqreturn_t gamma_dma_service(int irq, void *device, struct pt_regs *regs)
atomic_inc(&dev->counts[6]); /* _DRM_STAT_IRQ */
- while (GAMMA_READ(GAMMA_INFIFOSPACE) < 3);
+ while (GAMMA_READ(GAMMA_INFIFOSPACE) < 3)
+ cpu_relax();
+
GAMMA_WRITE(GAMMA_GDELAYTIMER, 0xc350/2); /* 0x05S */
GAMMA_WRITE(GAMMA_GCOMMANDINTFLAGS, 8);
GAMMA_WRITE(GAMMA_GINTFLAGS, 0x2001);
@@ -824,7 +838,8 @@ void DRM(driver_irq_preinstall)( drm_device_t *dev ) {
drm_gamma_private_t *dev_priv =
(drm_gamma_private_t *)dev->dev_private;
- while(GAMMA_READ(GAMMA_INFIFOSPACE) < 2);
+ while(GAMMA_READ(GAMMA_INFIFOSPACE) < 2)
+ cpu_relax();
GAMMA_WRITE( GAMMA_GCOMMANDMODE, 0x00000004 );
GAMMA_WRITE( GAMMA_GDMACONTROL, 0x00000000 );
@@ -834,7 +849,8 @@ void DRM(driver_irq_postinstall)( drm_device_t *dev ) {
drm_gamma_private_t *dev_priv =
(drm_gamma_private_t *)dev->dev_private;
- while(GAMMA_READ(GAMMA_INFIFOSPACE) < 3);
+ while(GAMMA_READ(GAMMA_INFIFOSPACE) < 3)
+ cpu_relax();
GAMMA_WRITE( GAMMA_GINTENABLE, 0x00002001 );
GAMMA_WRITE( GAMMA_COMMANDINTENABLE, 0x00000008 );
@@ -847,7 +863,8 @@ void DRM(driver_irq_uninstall)( drm_device_t *dev ) {
if (!dev_priv)
return;
- while(GAMMA_READ(GAMMA_INFIFOSPACE) < 3);
+ while(GAMMA_READ(GAMMA_INFIFOSPACE) < 3)
+ cpu_relax();
GAMMA_WRITE( GAMMA_GDELAYTIMER, 0x00000000 );
GAMMA_WRITE( GAMMA_COMMANDINTENABLE, 0x00000000 );
diff --git a/drivers/char/ipmi/ipmi_kcs_intf.c b/drivers/char/ipmi/ipmi_kcs_intf.c
index e47ab34a809f..c28cdfc7bfd0 100644
--- a/drivers/char/ipmi/ipmi_kcs_intf.c
+++ b/drivers/char/ipmi/ipmi_kcs_intf.c
@@ -1018,52 +1018,81 @@ static int init_one_kcs(int kcs_port,
#ifdef CONFIG_ACPI_INTERPRETER
-/* Retrieve the base physical address from ACPI tables. Originally
- from Hewlett-Packard simple bmc.c, a GPL KCS driver. */
-
#include <linux/acpi.h>
struct SPMITable {
- s8 Signature[4];
- u32 Length;
- u8 Revision;
- u8 Checksum;
- s8 OEMID[6];
- s8 OEMTableID[8];
- s8 OEMRevision[4];
- s8 CreatorID[4];
- s8 CreatorRevision[4];
- s16 InterfaceType;
- s16 SpecificationRevision;
- u8 InterruptType;
- u8 GPE;
- s16 Reserved;
- u64 GlobalSystemInterrupt;
- u8 BaseAddress[12];
- u8 UID[4];
-} __attribute__ ((packed));
-
-static unsigned long acpi_find_bmc(void)
-{
- acpi_status status;
- struct acpi_table_header *spmi;
- static unsigned long io_base = 0;
-
- if (io_base != 0)
- return io_base;
+ s8 Signature[4];
+ u32 Length;
+ u8 Revision;
+ u8 Checksum;
+ s8 OEMID[6];
+ s8 OEMTableID[8];
+ s8 OEMRevision[4];
+ s8 CreatorID[4];
+ s8 CreatorRevision[4];
+ u8 InterfaceType[2];
+ s16 SpecificationRevision;
+
+ /*
+ * Bit 0 - SCI interrupt supported
+ * Bit 1 - I/O APIC/SAPIC
+ */
+ u8 InterruptType;
+
+ /* If bit 0 of InterruptType is set, then this is the SCI
+ interrupt in the GPEx_STS register. */
+ u8 GPE;
+
+ s16 Reserved;
+
+ /* If bit 1 of InterruptType is set, then this is the I/O
+ APIC/SAPIC interrupt. */
+ u32 GlobalSystemInterrupt;
+
+ /* The actual register address. */
+ struct acpi_generic_address addr;
+
+ u8 UID[4];
+
+ s8 spmi_id[1]; /* A '\0' terminated array starts here. */
+};
+static int acpi_find_bmc(unsigned long *physaddr, int *port)
+{
+ acpi_status status;
+ struct SPMITable *spmi;
+
status = acpi_get_firmware_table("SPMI", 1,
- ACPI_LOGICAL_ADDRESSING, &spmi);
+ ACPI_LOGICAL_ADDRESSING,
+ (struct acpi_table_header **) &spmi);
+ if (status != AE_OK)
+ goto not_found;
+
+ if (spmi->InterfaceType[0] != 1)
+ /* Not IPMI. */
+ goto not_found;
+
+ if (spmi->InterfaceType[1] != 1)
+ /* Not KCS. */
+ goto not_found;
+
+ if (spmi->addr.address_space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) {
+ *physaddr = spmi->addr.address;
+ printk("ipmi_kcs_intf: Found ACPI-specified state machine"
+ " at memory address 0x%lx\n",
+ (unsigned long) spmi->addr.address);
+ } else if (spmi->addr.address_space_id == ACPI_ADR_SPACE_SYSTEM_IO) {
+ *port = spmi->addr.address;
+ printk("ipmi_kcs_intf: Found ACPI-specified state machine"
+ " at I/O address 0x%lx\n",
+ (int) spmi->addr.address);
+ } else
+ goto not_found; /* Not an address type we recognise. */
- if (status != AE_OK) {
- printk(KERN_ERR "ipmi_kcs: SPMI table not found.\n");
- return 0;
- }
+ return 0;
- memcpy(&io_base, ((struct SPMITable *)spmi)->BaseAddress,
- sizeof(io_base));
-
- return io_base;
+ not_found:
+ return -ENODEV;
}
#endif
@@ -1074,6 +1103,7 @@ static __init int init_ipmi_kcs(void)
int i = 0;
#ifdef CONFIG_ACPI_INTERPRETER
unsigned long physaddr = 0;
+ int port = 0;
#endif
if (initialized)
@@ -1101,20 +1131,19 @@ static __init int init_ipmi_kcs(void)
/* Only try the defaults if enabled and resources are available
(because they weren't already specified above). */
- if (kcs_trydefaults) {
+ if (kcs_trydefaults && (pos == 0)) {
+ rv = -EINVAL;
#ifdef CONFIG_ACPI_INTERPRETER
- if ((physaddr = acpi_find_bmc())) {
- if (!check_mem_region(physaddr, 2)) {
- rv = init_one_kcs(0,
- 0,
- physaddr,
- &(kcs_infos[pos]));
- if (rv == 0)
- pos++;
- }
+ if (rv && (physaddr = acpi_find_bmc(&physaddr, &port) == 0)) {
+ rv = init_one_kcs(port,
+ 0,
+ physaddr,
+ &(kcs_infos[pos]));
+ if (rv == 0)
+ pos++;
}
#endif
- if (!check_region(DEFAULT_IO_PORT, 2)) {
+ if (rv) {
rv = init_one_kcs(DEFAULT_IO_PORT,
0,
0,
diff --git a/drivers/char/ipmi/ipmi_watchdog.c b/drivers/char/ipmi/ipmi_watchdog.c
index 4eab8908181e..185ed6ade2a2 100644
--- a/drivers/char/ipmi/ipmi_watchdog.c
+++ b/drivers/char/ipmi/ipmi_watchdog.c
@@ -559,7 +559,10 @@ static int ipmi_ioctl(struct inode *inode, struct file *file,
case WDIOC_GETSTATUS:
val = 0;
- return copy_to_user((void *) arg, &val, sizeof(val));
+ i = copy_to_user((void *) arg, &val, sizeof(val));
+ if (i)
+ return -EFAULT;
+ return 0;
default:
return -ENOIOCTLCMD;
diff --git a/drivers/char/random.c b/drivers/char/random.c
index 86db1af9e2f0..d7d8f909f3e4 100644
--- a/drivers/char/random.c
+++ b/drivers/char/random.c
@@ -1850,27 +1850,62 @@ static int uuid_strategy(ctl_table *table, int *name, int nlen,
}
ctl_table random_table[] = {
- {RANDOM_POOLSIZE, "poolsize",
- &sysctl_poolsize, sizeof(int), 0644, NULL,
- &proc_do_poolsize, &poolsize_strategy},
- {RANDOM_ENTROPY_COUNT, "entropy_avail",
- NULL, sizeof(int), 0444, NULL,
- &proc_dointvec},
- {RANDOM_READ_THRESH, "read_wakeup_threshold",
- &random_read_wakeup_thresh, sizeof(int), 0644, NULL,
- &proc_dointvec_minmax, &sysctl_intvec, 0,
- &min_read_thresh, &max_read_thresh},
- {RANDOM_WRITE_THRESH, "write_wakeup_threshold",
- &random_write_wakeup_thresh, sizeof(int), 0644, NULL,
- &proc_dointvec_minmax, &sysctl_intvec, 0,
- &min_write_thresh, &max_write_thresh},
- {RANDOM_BOOT_ID, "boot_id",
- &sysctl_bootid, 16, 0444, NULL,
- &proc_do_uuid, &uuid_strategy},
- {RANDOM_UUID, "uuid",
- NULL, 16, 0444, NULL,
- &proc_do_uuid, &uuid_strategy},
- {0}
+ {
+ .ctl_name = RANDOM_POOLSIZE,
+ .procname = "poolsize",
+ .data = &sysctl_poolsize,
+ .maxlen = sizeof(int),
+ .mode = 0644,
+ .proc_handler = &proc_do_poolsize,
+ .strategy = &poolsize_strategy,
+ },
+ {
+ .ctl_name = RANDOM_ENTROPY_COUNT,
+ .procname = "entropy_avail",
+ .maxlen = sizeof(int),
+ .mode = 0444,
+ .proc_handler = &proc_dointvec,
+ },
+ {
+ .ctl_name = RANDOM_READ_THRESH,
+ .procname = "read_wakeup_threshold",
+ .data = &random_read_wakeup_thresh,
+ .maxlen = sizeof(int),
+ .mode = 0644,
+ .proc_handler = &proc_dointvec_minmax,
+ .strategy = &sysctl_intvec,
+ .extra1 = &min_read_thresh,
+ .extra2 = &max_read_thresh,
+ },
+ {
+ .ctl_name = RANDOM_WRITE_THRESH,
+ .procname = "write_wakeup_threshold",
+ .data = &random_write_wakeup_thresh,
+ .maxlen = sizeof(int),
+ .mode = 0644,
+ .proc_handler = &proc_dointvec_minmax,
+ .strategy = &sysctl_intvec,
+ .extra1 = &min_write_thresh,
+ .extra2 = &max_write_thresh,
+ },
+ {
+ .ctl_name = RANDOM_BOOT_ID,
+ .procname = "boot_id",
+ .data = &sysctl_bootid,
+ .maxlen = 16,
+ .mode = 0444,
+ .proc_handler = &proc_do_uuid,
+ .strategy = &uuid_strategy,
+ },
+ {
+ .ctl_name = RANDOM_UUID,
+ .procname = "uuid",
+ .maxlen = 16,
+ .mode = 0444,
+ .proc_handler = &proc_do_uuid,
+ .strategy = &uuid_strategy,
+ },
+ { .ctl_name = 0 }
};
static void sysctl_init_random(struct entropy_store *random_state)
diff --git a/drivers/char/watchdog/alim7101_wdt.c b/drivers/char/watchdog/alim7101_wdt.c
index e98826092f8c..323fc2019e2a 100644
--- a/drivers/char/watchdog/alim7101_wdt.c
+++ b/drivers/char/watchdog/alim7101_wdt.c
@@ -1,26 +1,11 @@
/*
- * ALi M7101 PMU Computer Watchdog Timer driver for Linux 2.4.x
+ * ALi M7101 PMU Computer Watchdog Timer driver
*
- * Based on w83877f_wdt.c by Scott Jennings <management@oro.net>
+ * Based on w83877f_wdt.c by Scott Jennings <linuxdrivers@oro.net>
* and the Cobalt kernel WDT timer driver by Tim Hockin
* <thockin@cobaltnet.com>
*
* (c)2002 Steve Hill <steve@navaho.co.uk>
- *
- * Theory of operation:
- * A Watchdog Timer (WDT) is a hardware circuit that can
- * reset the computer system in case of a software fault.
- * You probably knew that already.
- *
- * Usually a userspace daemon will notify the kernel WDT driver
- * via the /proc/watchdog special device file that userspace is
- * still alive, at regular intervals. When such a notification
- * occurs, the driver will usually tell the hardware watchdog
- * that everything is in order, and that the watchdog should wait
- * for yet another little while to reset the system.
- * If userspace fails (RAM error, kernel bug, whatever), the
- * notifications cease to occur, and the hardware watchdog will
- * reset the system (causing a reboot) after the timeout occurs.
*
* This WDT driver is different from most other Linux WDT
* drivers in that the driver will ping the watchdog by itself,
@@ -30,6 +15,7 @@
*/
#include <linux/module.h>
+#include <linux/moduleparam.h>
#include <linux/types.h>
#include <linux/timer.h>
#include <linux/miscdevice.h>
@@ -38,7 +24,6 @@
#include <linux/notifier.h>
#include <linux/reboot.h>
#include <linux/init.h>
-#include <linux/moduleparam.h>
#include <linux/pci.h>
#include <asm/io.h>
@@ -46,6 +31,7 @@
#include <asm/system.h>
#define OUR_NAME "alim7101_wdt"
+#define PFX OUR_NAME ": "
#define WDT_ENABLE 0x9C
#define WDT_DISABLE 0x8C
@@ -65,13 +51,16 @@
* char to /dev/watchdog every 30 seconds.
*/
-#define WDT_HEARTBEAT (HZ * 30)
+#define WATCHDOG_TIMEOUT 30 /* 30 sec default timeout */
+static int timeout = WATCHDOG_TIMEOUT; /* in seconds, will be multiplied by HZ to get seconds to wait for a ping */
+module_param(timeout, int, 0);
+MODULE_PARM_DESC(timeout, "Watchdog timeout in seconds. (1<=timeout<=3600, default=" __MODULE_STRING(WATCHDOG_TIMEOUT) ")");
static void wdt_timer_ping(unsigned long);
static struct timer_list timer;
static unsigned long next_heartbeat;
static unsigned long wdt_is_open;
-static int wdt_expect_close;
+static char wdt_expect_close;
static struct pci_dev *alim7101_pmu;
#ifdef CONFIG_WATCHDOG_NOWAYOUT
@@ -79,7 +68,7 @@ static int nowayout = 1;
#else
static int nowayout = 0;
#endif
-
+
module_param(nowayout, int, 0);
MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CONFIG_WATCHDOG_NOWAYOUT)");
@@ -90,25 +79,25 @@ MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CON
static void wdt_timer_ping(unsigned long data)
{
/* If we got a heartbeat pulse within the WDT_US_INTERVAL
- * we agree to ping the WDT
+ * we agree to ping the WDT
*/
char tmp;
- if(time_before(jiffies, next_heartbeat))
+ if(time_before(jiffies, next_heartbeat))
{
/* Ping the WDT (this is actually a disarm/arm sequence) */
pci_read_config_byte(alim7101_pmu, 0x92, &tmp);
pci_write_config_byte(alim7101_pmu, ALI_7101_WDT, (tmp & ~ALI_WDT_ARM));
pci_write_config_byte(alim7101_pmu, ALI_7101_WDT, (tmp | ALI_WDT_ARM));
} else {
- printk(KERN_INFO OUR_NAME ": Heartbeat lost! Will not ping the watchdog\n");
+ printk(KERN_WARNING PFX "Heartbeat lost! Will not ping the watchdog\n");
}
/* Re-set the timer interval */
timer.expires = jiffies + WDT_INTERVAL;
add_timer(&timer);
}
-/*
+/*
* Utility routines
*/
@@ -125,7 +114,7 @@ static void wdt_change(int writeval)
static void wdt_startup(void)
{
- next_heartbeat = jiffies + WDT_HEARTBEAT;
+ next_heartbeat = jiffies + (timeout * HZ);
/* We must enable before we kick off the timer in case the timer
occurs as we ping it */
@@ -133,11 +122,11 @@ static void wdt_startup(void)
wdt_change(WDT_ENABLE);
/* Start the timer */
- timer.expires = jiffies + WDT_INTERVAL;
+ timer.expires = jiffies + WDT_INTERVAL;
add_timer(&timer);
- printk(KERN_INFO OUR_NAME ": Watchdog timer is now enabled.\n");
+ printk(KERN_INFO PFX "Watchdog timer is now enabled.\n");
}
static void wdt_turnoff(void)
@@ -145,7 +134,13 @@ static void wdt_turnoff(void)
/* Stop the timer */
del_timer_sync(&timer);
wdt_change(WDT_DISABLE);
- printk(KERN_INFO OUR_NAME ": Watchdog timer is now disabled...\n");
+ printk(KERN_INFO PFX "Watchdog timer is now disabled...\n");
+}
+
+static void wdt_keepalive(void)
+{
+ /* user land ping */
+ next_heartbeat = jiffies + (timeout * HZ);
}
/*
@@ -158,7 +153,7 @@ static ssize_t fop_write(struct file * file, const char * buf, size_t count, lof
if(ppos != &file->f_pos)
return -ESPIPE;
- /* See if we got the magic character */
+ /* See if we got the magic character 'V' and reload the timer */
if(count) {
if (!nowayout) {
size_t ofs;
@@ -173,14 +168,13 @@ static ssize_t fop_write(struct file * file, const char * buf, size_t count, lof
if (get_user(c, buf+ofs))
return -EFAULT;
if (c == 'V')
- wdt_expect_close = 1;
+ wdt_expect_close = 42;
}
}
/* someone wrote to us, we should restart timer */
- next_heartbeat = jiffies + WDT_HEARTBEAT;
- return 1;
- };
- return 0;
+ wdt_keepalive();
+ }
+ return count;
}
static int fop_open(struct inode * inode, struct file * file)
@@ -195,12 +189,14 @@ static int fop_open(struct inode * inode, struct file * file)
static int fop_close(struct inode * inode, struct file * file)
{
- if(wdt_expect_close)
+ if(wdt_expect_close == 42)
wdt_turnoff();
- else
- printk(KERN_INFO OUR_NAME ": device file closed unexpectedly. Will not stop the WDT!\n");
-
+ else {
+ /* wim: shouldn't there be a: del_timer(&timer); */
+ printk(KERN_CRIT PFX "device file closed unexpectedly. Will not stop the WDT!\n");
+ }
clear_bit(0, &wdt_is_open);
+ wdt_expect_close = 0;
return 0;
}
@@ -208,20 +204,58 @@ static int fop_ioctl(struct inode *inode, struct file *file, unsigned int cmd, u
{
static struct watchdog_info ident =
{
- .options = WDIOF_MAGICCLOSE,
+ .options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE,
.firmware_version = 1,
- .identity = "ALiM7101"
+ .identity = "ALiM7101",
};
-
+
switch(cmd)
{
case WDIOC_GETSUPPORT:
return copy_to_user((struct watchdog_info *)arg, &ident, sizeof(ident))?-EFAULT:0;
+ case WDIOC_GETSTATUS:
+ case WDIOC_GETBOOTSTATUS:
+ return put_user(0, (int *)arg);
case WDIOC_KEEPALIVE:
- next_heartbeat = jiffies + WDT_HEARTBEAT;
+ wdt_keepalive();
return 0;
+ case WDIOC_SETOPTIONS:
+ {
+ int new_options, retval = -EINVAL;
+
+ if(get_user(new_options, (int *)arg))
+ return -EFAULT;
+
+ if(new_options & WDIOS_DISABLECARD) {
+ wdt_turnoff();
+ retval = 0;
+ }
+
+ if(new_options & WDIOS_ENABLECARD) {
+ wdt_startup();
+ retval = 0;
+ }
+
+ return retval;
+ }
+ case WDIOC_SETTIMEOUT:
+ {
+ int new_timeout;
+
+ if(get_user(new_timeout, (int *)arg))
+ return -EFAULT;
+
+ if(new_timeout < 1 || new_timeout > 3600) /* arbitrary upper limit */
+ return -EINVAL;
+
+ timeout = new_timeout;
+ wdt_keepalive();
+ /* Fall through */
+ }
+ case WDIOC_GETTIMEOUT:
+ return put_user(timeout, (int *)arg);
default:
- return -ENOTTY;
+ return -ENOIOCTLCMD;
}
}
@@ -231,13 +265,13 @@ static struct file_operations wdt_fops = {
.write= fop_write,
.open= fop_open,
.release= fop_close,
- .ioctl= fop_ioctl
+ .ioctl= fop_ioctl,
};
static struct miscdevice wdt_miscdev = {
.minor=WATCHDOG_MINOR,
.name="watchdog",
- .fops=&wdt_fops
+ .fops=&wdt_fops,
};
/*
@@ -256,21 +290,21 @@ static int wdt_notify_sys(struct notifier_block *this, unsigned long code, void
* reboot with no heartbeat
*/
wdt_change(WDT_ENABLE);
- printk(KERN_INFO OUR_NAME ": Watchdog timer is now enabled with no heartbeat - should reboot in ~1 second.\n");
+ printk(KERN_INFO PFX "Watchdog timer is now enabled with no heartbeat - should reboot in ~1 second.\n");
}
return NOTIFY_DONE;
}
-
+
/*
* The WDT needs to learn about soft shutdowns in order to
- * turn the timebomb registers off.
+ * turn the timebomb registers off.
*/
-
+
static struct notifier_block wdt_notifier=
{
.notifier_call = wdt_notify_sys,
.next = 0,
- .priority = 0
+ .priority = 0,
};
static void __exit alim7101_wdt_unload(void)
@@ -287,10 +321,10 @@ static int __init alim7101_wdt_init(void)
struct pci_dev *ali1543_south;
char tmp;
- printk(KERN_INFO OUR_NAME ": Steve Hill <steve@navaho.co.uk>.\n");
+ printk(KERN_INFO PFX "Steve Hill <steve@navaho.co.uk>.\n");
alim7101_pmu = pci_find_device(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M7101,NULL);
if (!alim7101_pmu) {
- printk(KERN_INFO OUR_NAME ": ALi M7101 PMU not present - WDT not set\n");
+ printk(KERN_INFO PFX "ALi M7101 PMU not present - WDT not set\n");
return -EBUSY;
}
@@ -299,35 +333,53 @@ static int __init alim7101_wdt_init(void)
ali1543_south = pci_find_device(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M1533, NULL);
if (!ali1543_south) {
- printk(KERN_INFO OUR_NAME ": ALi 1543 South-Bridge not present - WDT not set\n");
+ printk(KERN_INFO PFX "ALi 1543 South-Bridge not present - WDT not set\n");
return -EBUSY;
}
pci_read_config_byte(ali1543_south, 0x5e, &tmp);
if ((tmp & 0x1e) != 0x12) {
- printk(KERN_INFO OUR_NAME ": ALi 1543 South-Bridge does not have the correct revision number (???1001?) - WDT not set\n");
+ printk(KERN_INFO PFX "ALi 1543 South-Bridge does not have the correct revision number (???1001?) - WDT not set\n");
return -EBUSY;
}
+ if(timeout < 1 || timeout > 3600) /* arbitrary upper limit */
+ {
+ timeout = WATCHDOG_TIMEOUT;
+ printk(KERN_INFO PFX "timeout value must be 1<=x<=3600, using %d\n",
+ timeout);
+ }
+
init_timer(&timer);
timer.function = wdt_timer_ping;
timer.data = 1;
rc = misc_register(&wdt_miscdev);
- if (rc)
- return rc;
+ if (rc) {
+ printk(KERN_ERR PFX "cannot register miscdev on minor=%d (err=%d)\n",
+ wdt_miscdev.minor, rc);
+ goto err_out;
+ }
rc = register_reboot_notifier(&wdt_notifier);
if (rc) {
- misc_deregister(&wdt_miscdev);
- return rc;
+ printk(KERN_ERR PFX "cannot register reboot notifier (err=%d)\n",
+ rc);
+ goto err_out_miscdev;
}
- printk(KERN_INFO OUR_NAME ": WDT driver for ALi M7101 initialised.\n");
+ printk(KERN_INFO PFX "WDT driver for ALi M7101 initialised. timeout=%d sec (nowayout=%d)\n",
+ timeout, nowayout);
return 0;
+
+err_out_miscdev:
+ misc_deregister(&wdt_miscdev);
+err_out:
+ return rc;
}
module_init(alim7101_wdt_init);
module_exit(alim7101_wdt_unload);
MODULE_AUTHOR("Steve Hill");
+MODULE_DESCRIPTION("ALi M7101 PMU Computer Watchdog Timer driver");
MODULE_LICENSE("GPL");
diff --git a/drivers/char/watchdog/sc520_wdt.c b/drivers/char/watchdog/sc520_wdt.c
index 19979dfe0185..a2ca29f6a896 100644
--- a/drivers/char/watchdog/sc520_wdt.c
+++ b/drivers/char/watchdog/sc520_wdt.c
@@ -1,21 +1,21 @@
/*
- * AMD Elan SC520 processor Watchdog Timer driver for Linux 2.4.x
+ * AMD Elan SC520 processor Watchdog Timer driver
*
* Based on acquirewdt.c by Alan Cox,
- * and sbc60xxwdt.c by Jakob Oestergaard <jakob@ostenfeld.dk>
- *
+ * and sbc60xxwdt.c by Jakob Oestergaard <jakob@unthought.net>
+ *
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
- *
- * The authors do NOT admit liability nor provide warranty for
- * any of this software. This material is provided "AS-IS" in
+ *
+ * The authors do NOT admit liability nor provide warranty for
+ * any of this software. This material is provided "AS-IS" in
* the hope that it may be useful for others.
*
* (c) Copyright 2001 Scott Jennings <linuxdrivers@oro.net>
* 9/27 - 2001 [Initial release]
- *
+ *
* Additional fixes Alan Cox
* - Fixed formatting
* - Removed debug printks
@@ -24,20 +24,21 @@
* - Used ioremap/writew/readw
* - Added NOWAYOUT support
*
- * Theory of operation:
- * A Watchdog Timer (WDT) is a hardware circuit that can
- * reset the computer system in case of a software fault.
- * You probably knew that already.
- *
- * Usually a userspace daemon will notify the kernel WDT driver
- * via the /proc/watchdog special device file that userspace is
- * still alive, at regular intervals. When such a notification
- * occurs, the driver will usually tell the hardware watchdog
- * that everything is in order, and that the watchdog should wait
- * for yet another little while to reset the system.
- * If userspace fails (RAM error, kernel bug, whatever), the
- * notifications cease to occur, and the hardware watchdog will
- * reset the system (causing a reboot) after the timeout occurs.
+ * 4/12 - 2002 Changes by Rob Radez <rob@osinvestor.com>
+ * - Change comments
+ * - Eliminate fop_llseek
+ * - Change CONFIG_WATCHDOG_NOWAYOUT semantics
+ * - Add KERN_* tags to printks
+ * - fix possible wdt_is_open race
+ * - Report proper capabilities in watchdog_info
+ * - Add WDIOC_{GETSTATUS, GETBOOTSTATUS, SETTIMEOUT,
+ * GETTIMEOUT, SETOPTIONS} ioctls
+ * 09/8 - 2003 Changes by Wim Van Sebroeck <wim@iguana.be>
+ * - cleanup of trailing spaces
+ * - added extra printk's for startup problems
+ * - use module_param
+ * - made timeout (the emulated heartbeat) a module_param
+ * - made the keepalive ping an internal subroutine
*
* This WDT driver is different from most other Linux WDT
* drivers in that the driver will ping the watchdog by itself,
@@ -77,7 +78,10 @@
* char to /dev/watchdog every 30 seconds.
*/
-#define WDT_HEARTBEAT (HZ * 30)
+#define WATCHDOG_TIMEOUT 30 /* 30 sec default timeout */
+static int timeout = WATCHDOG_TIMEOUT; /* in seconds, will be multiplied by HZ to get seconds to wait for a ping */
+module_param(timeout, int, 0);
+MODULE_PARM_DESC(timeout, "Watchdog timeout in seconds. (1<=timeout<=3600, default=" __MODULE_STRING(WATCHDOG_TIMEOUT) ")");
/*
* AMD Elan SC520 timeout value is 492us times a power of 2 (0-7)
@@ -95,6 +99,7 @@
#define WDT_WRST_ENB 0x4000 /* [14] Watchdog Timer Reset Enable */
#define OUR_NAME "sc520_wdt"
+#define PFX OUR_NAME ": "
#define WRT_DOG(data) *wdtmrctl=data
@@ -104,7 +109,8 @@ static void wdt_timer_ping(unsigned long);
static struct timer_list timer;
static unsigned long next_heartbeat;
static unsigned long wdt_is_open;
-static int wdt_expect_close;
+static char wdt_expect_close;
+static spinlock_t wdt_spinlock;
#ifdef CONFIG_WATCHDOG_NOWAYOUT
static int nowayout = 1;
@@ -115,7 +121,6 @@ static int nowayout = 0;
module_param(nowayout, int, 0);
MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CONFIG_WATCHDOG_NOWAYOUT)");
-static spinlock_t wdt_spinlock;
/*
* Whack the dog
*/
@@ -123,9 +128,9 @@ static spinlock_t wdt_spinlock;
static void wdt_timer_ping(unsigned long data)
{
/* If we got a heartbeat pulse within the WDT_US_INTERVAL
- * we agree to ping the WDT
+ * we agree to ping the WDT
*/
- if(time_before(jiffies, next_heartbeat))
+ if(time_before(jiffies, next_heartbeat))
{
/* Ping the WDT */
spin_lock(&wdt_spinlock);
@@ -137,11 +142,11 @@ static void wdt_timer_ping(unsigned long data)
timer.expires = jiffies + WDT_INTERVAL;
add_timer(&timer);
} else {
- printk(OUR_NAME ": Heartbeat lost! Will not ping the watchdog\n");
+ printk(KERN_WARNING PFX "Heartbeat lost! Will not ping the watchdog\n");
}
}
-/*
+/*
* Utility routines
*/
@@ -165,14 +170,14 @@ static void wdt_config(int writeval)
static void wdt_startup(void)
{
- next_heartbeat = jiffies + WDT_HEARTBEAT;
+ next_heartbeat = jiffies + (timeout * HZ);
/* Start the timer */
- timer.expires = jiffies + WDT_INTERVAL;
+ timer.expires = jiffies + WDT_INTERVAL;
add_timer(&timer);
wdt_config(WDT_ENB | WDT_WRST_ENB | TIMEOUT_EXPONENT);
- printk(OUR_NAME ": Watchdog timer is now enabled.\n");
+ printk(KERN_INFO PFX "Watchdog timer is now enabled.\n");
}
static void wdt_turnoff(void)
@@ -181,10 +186,15 @@ static void wdt_turnoff(void)
/* Stop the timer */
del_timer(&timer);
wdt_config(0);
- printk(OUR_NAME ": Watchdog timer is now disabled...\n");
+ printk(KERN_INFO PFX "Watchdog timer is now disabled...\n");
}
}
+static void wdt_keepalive(void)
+{
+ /* user land ping */
+ next_heartbeat = jiffies + (timeout * HZ);
+}
/*
* /dev/watchdog handling
@@ -196,62 +206,56 @@ static ssize_t fop_write(struct file * file, const char * buf, size_t count, lof
if(ppos != &file->f_pos)
return -ESPIPE;
- /* See if we got the magic character */
- if(count)
+ /* See if we got the magic character 'V' and reload the timer */
+ if(count)
{
- size_t ofs;
-
- /* note: just in case someone wrote the magic character
- * five months ago... */
- wdt_expect_close = 0;
-
- /* now scan */
- for(ofs = 0; ofs != count; ofs++) {
- char c;
- if (get_user(c, buf + ofs))
- return -EFAULT;
- if(c == 'V')
- wdt_expect_close = 1;
+ if (!nowayout)
+ {
+ size_t ofs;
+
+ /* note: just in case someone wrote the magic character
+ * five months ago... */
+ wdt_expect_close = 0;
+
+ /* now scan */
+ for(ofs = 0; ofs != count; ofs++) {
+ char c;
+ if (get_user(c, buf + ofs))
+ return -EFAULT;
+ if(c == 'V')
+ wdt_expect_close = 42;
+ }
}
/* Well, anyhow someone wrote to us, we should return that favour */
- next_heartbeat = jiffies + WDT_HEARTBEAT;
- return 1;
+ wdt_keepalive();
}
- return 0;
+ return count;
}
static int fop_open(struct inode * inode, struct file * file)
{
- switch(minor(inode->i_rdev))
- {
- case WATCHDOG_MINOR:
- /* Just in case we're already talking to someone... */
- if(test_and_set_bit(0, &wdt_is_open))
- return -EBUSY;
- /* Good, fire up the show */
- wdt_startup();
- if (nowayout)
- __module_get(THIS_MODULE);
-
- return 0;
- default:
- return -ENODEV;
- }
+ /* Just in case we're already talking to someone... */
+ if(test_and_set_bit(0, &wdt_is_open))
+ return -EBUSY;
+ if (nowayout)
+ __module_get(THIS_MODULE);
+
+ /* Good, fire up the show */
+ wdt_startup();
+ return 0;
}
static int fop_close(struct inode * inode, struct file * file)
{
- if(minor(inode->i_rdev) == WATCHDOG_MINOR)
- {
- if(wdt_expect_close)
- wdt_turnoff();
- else {
- del_timer(&timer);
- printk(OUR_NAME ": device file closed unexpectedly. Will not stop the WDT!\n");
- }
+ if(wdt_expect_close == 42)
+ wdt_turnoff();
+ else {
+ del_timer(&timer);
+ printk(KERN_CRIT PFX "device file closed unexpectedly. Will not stop the WDT!\n");
}
clear_bit(0, &wdt_is_open);
+ wdt_expect_close = 0;
return 0;
}
@@ -260,20 +264,58 @@ static int fop_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
{
static struct watchdog_info ident=
{
- .options = WDIOF_MAGICCLOSE,
+ .options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE,
.firmware_version = 1,
- .identity = "SC520"
+ .identity = "SC520",
};
-
+
switch(cmd)
{
default:
return -ENOIOCTLCMD;
case WDIOC_GETSUPPORT:
return copy_to_user((struct watchdog_info *)arg, &ident, sizeof(ident))?-EFAULT:0;
+ case WDIOC_GETSTATUS:
+ case WDIOC_GETBOOTSTATUS:
+ return put_user(0, (int *)arg);
case WDIOC_KEEPALIVE:
- next_heartbeat = jiffies + WDT_HEARTBEAT;
+ wdt_keepalive();
return 0;
+ case WDIOC_SETOPTIONS:
+ {
+ int new_options, retval = -EINVAL;
+
+ if(get_user(new_options, (int *)arg))
+ return -EFAULT;
+
+ if(new_options & WDIOS_DISABLECARD) {
+ wdt_turnoff();
+ retval = 0;
+ }
+
+ if(new_options & WDIOS_ENABLECARD) {
+ wdt_startup();
+ retval = 0;
+ }
+
+ return retval;
+ }
+ case WDIOC_SETTIMEOUT:
+ {
+ int new_timeout;
+
+ if(get_user(new_timeout, (int *)arg))
+ return -EFAULT;
+
+ if(new_timeout < 1 || new_timeout > 3600) /* arbitrary upper limit */
+ return -EINVAL;
+
+ timeout = new_timeout;
+ wdt_keepalive();
+ /* Fall through */
+ }
+ case WDIOC_GETTIMEOUT:
+ return put_user(timeout, (int *)arg);
}
}
@@ -283,13 +325,13 @@ static struct file_operations wdt_fops = {
.write = fop_write,
.open = fop_open,
.release = fop_close,
- .ioctl = fop_ioctl
+ .ioctl = fop_ioctl,
};
static struct miscdevice wdt_miscdev = {
.minor = WATCHDOG_MINOR,
.name = "watchdog",
- .fops = &wdt_fops
+ .fops = &wdt_fops,
};
/*
@@ -299,21 +341,21 @@ static struct miscdevice wdt_miscdev = {
static int wdt_notify_sys(struct notifier_block *this, unsigned long code,
void *unused)
{
- if(code==SYS_DOWN || code==SYS_HALT)
+ if(code==SYS_DOWN || code==SYS_HALT)
wdt_turnoff();
return NOTIFY_DONE;
}
-
+
/*
* The WDT needs to learn about soft shutdowns in order to
- * turn the timebomb registers off.
+ * turn the timebomb registers off.
*/
-
+
static struct notifier_block wdt_notifier=
{
.notifier_call = wdt_notify_sys,
.next = NULL,
- .priority = 0
+ .priority = 0,
};
static void __exit sc520_wdt_unload(void)
@@ -333,27 +375,42 @@ static int __init sc520_wdt_init(void)
spin_lock_init(&wdt_spinlock);
+ if(timeout < 1 || timeout > 3600) /* arbitrary upper limit */
+ {
+ timeout = WATCHDOG_TIMEOUT;
+ printk(KERN_INFO PFX "timeout value must be 1<=x<=3600, using %d\n",
+ timeout);
+ }
+
init_timer(&timer);
timer.function = wdt_timer_ping;
timer.data = 0;
rc = misc_register(&wdt_miscdev);
if (rc)
+ {
+ printk(KERN_ERR PFX "cannot register miscdev on minor=%d (err=%d)\n",
+ wdt_miscdev.minor, rc);
goto err_out_region2;
+ }
rc = register_reboot_notifier(&wdt_notifier);
if (rc)
+ {
+ printk(KERN_ERR PFX "cannot register reboot notifier (err=%d)\n",
+ rc);
goto err_out_miscdev;
+ }
/* get the Base Address Register */
cbar = inl_p(0xfffc);
- printk(OUR_NAME ": CBAR: 0x%08lx\n", cbar);
+ printk(KERN_INFO PFX "CBAR: 0x%08lx\n", cbar);
/* check if MMCR aliasing bit is set */
if (cbar & 0x80000000) {
- printk(OUR_NAME ": MMCR Aliasing enabled.\n");
+ printk(KERN_INFO PFX "MMCR Aliasing enabled.\n");
wdtmrctl = (__u16 *)(cbar & 0x3fffffff);
} else {
- printk(OUR_NAME "!!! WARNING !!!\n"
+ printk(KERN_INFO PFX "!!! WARNING !!!\n"
"\t MMCR Aliasing found NOT enabled!\n"
"\t Using default value of: %p\n"
"\t This has not been tested!\n"
@@ -366,7 +423,8 @@ static int __init sc520_wdt_init(void)
wdtmrctl = (__u16 *)((char *)wdtmrctl + OFFS_WDTMRCTL);
wdtmrctl = ioremap((unsigned long)wdtmrctl, 2);
- printk(KERN_INFO OUR_NAME ": WDT driver for SC520 initialised.\n");
+ printk(KERN_INFO PFX "WDT driver for SC520 initialised. timeout=%d sec (nowayout=%d)\n",
+ timeout,nowayout);
return 0;
diff --git a/drivers/ide/pci/hpt366.c b/drivers/ide/pci/hpt366.c
index 226236ffc39c..ecbb7a9f6299 100644
--- a/drivers/ide/pci/hpt366.c
+++ b/drivers/ide/pci/hpt366.c
@@ -440,7 +440,7 @@ static int hpt3xx_tune_chipset (ide_drive_t *drive, u8 speed)
static void hpt3xx_tune_drive (ide_drive_t *drive, u8 pio)
{
- pio = ide_get_best_pio_mode(drive, pio, 5, NULL);
+ pio = ide_get_best_pio_mode(drive, 255, pio, NULL);
(void) hpt3xx_tune_chipset(drive, (XFER_PIO_0 + pio));
}
diff --git a/drivers/ieee1394/sbp2.c b/drivers/ieee1394/sbp2.c
index e109169af1a2..fb86f80c0326 100644
--- a/drivers/ieee1394/sbp2.c
+++ b/drivers/ieee1394/sbp2.c
@@ -1002,8 +1002,9 @@ static void sbp2_remove_device(struct scsi_id_instance_data *scsi_id)
sbp2scsi_complete_all_commands(scsi_id, DID_NO_CONNECT);
/* Remove it from the scsi layer now */
- if (sdev && scsi_remove_device(sdev))
- SBP2_ERR("scsi_remove_device failed");
+ if (sdev) {
+ scsi_remove_device(sdev);
+ }
sbp2util_remove_command_orb_pool(scsi_id);
@@ -2890,7 +2891,6 @@ static Scsi_Host_Template scsi_driver_template = {
.cmd_per_lun = SBP2_MAX_CMDS_PER_LUN,
.can_queue = SBP2_MAX_SCSI_QUEUE,
.emulated = 1,
- .highmem_io = 1,
};
static int sbp2_module_init(void)
diff --git a/drivers/input/serio/i8042.h b/drivers/input/serio/i8042.h
index f694a2d75acb..3d59eb2e05a7 100644
--- a/drivers/input/serio/i8042.h
+++ b/drivers/input/serio/i8042.h
@@ -103,11 +103,11 @@
#ifdef DEBUG
static unsigned long i8042_start;
-#define dbg_init() do { i8042_start = jiffies; } while (0);
+#define dbg_init() do { i8042_start = jiffies; } while (0)
#define dbg(format, arg...) printk(KERN_DEBUG __FILE__ ": " format " [%d]\n" ,\
## arg, (int) (jiffies - i8042_start))
#else
-#define dbg_init() do { } while (0);
+#define dbg_init() do { } while (0)
#define dbg(format, arg...) do {} while (0)
#endif
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c
index 7ce28244068a..5995ee02775e 100644
--- a/drivers/md/raid5.c
+++ b/drivers/md/raid5.c
@@ -1326,7 +1326,7 @@ static int make_request (request_queue_t *q, struct bio * bi)
(unsigned long long)new_sector,
(unsigned long long)logical_sector);
- sh = get_active_stripe(conf, new_sector, pd_idx, (bi->bi_rw&RWA_MASK));
+ sh = get_active_stripe(conf, new_sector, pd_idx, 0/*(bi->bi_rw&RWA_MASK)*/);
if (sh) {
add_stripe_bio(sh, bi, dd_idx, (bi->bi_rw&RW_MASK));
diff --git a/drivers/media/video/bttv-cards.c b/drivers/media/video/bttv-cards.c
index 7cbfb45bff2d..038ee943a749 100644
--- a/drivers/media/video/bttv-cards.c
+++ b/drivers/media/video/bttv-cards.c
@@ -1211,7 +1211,7 @@ struct tvcard bttv_tvcards[] = {
.tuner_type = -1,
.pll = PLL_28,
.muxsel = { 2 },
- gpiomask: 0
+ .gpiomask = 0
},{
/* Tomasz Pyra <hellfire@sedez.iq.pl> */
.name = "Prolink Pixelview PV-BT878P+ (Rev.4C,8E)",
@@ -1298,7 +1298,7 @@ struct tvcard bttv_tvcards[] = {
},{
.name = "Powercolor MTV878/ MTV878R/ MTV878F",
.video_inputs = 3,
- audio_inputs: 2,
+ .audio_inputs = 2,
.tuner = 0,
.svhs = 2,
.gpiomask = 0x1C800F, // Bit0-2: Audio select, 8-12:remote control 14:remote valid 15:remote reset
@@ -1338,7 +1338,7 @@ struct tvcard bttv_tvcards[] = {
},{
.name = "Jetway TV/Capture JW-TV878-FBK, Kworld KW-TV878RF",
.video_inputs = 4,
- audio_inputs: 3,
+ .audio_inputs = 3,
.tuner = 0,
.svhs = 2,
.gpiomask = 7,
diff --git a/drivers/media/video/bttv-driver.c b/drivers/media/video/bttv-driver.c
index a7f672037ac7..b670fe42d4b4 100644
--- a/drivers/media/video/bttv-driver.c
+++ b/drivers/media/video/bttv-driver.c
@@ -2873,8 +2873,8 @@ static struct file_operations bttv_fops =
static struct video_device bttv_video_template =
{
.name = "UNSET",
- type: VID_TYPE_CAPTURE|VID_TYPE_TUNER|VID_TYPE_OVERLAY|
- VID_TYPE_CLIPPING|VID_TYPE_SCALES,
+ .type = VID_TYPE_CAPTURE|VID_TYPE_TUNER|VID_TYPE_OVERLAY|
+ VID_TYPE_CLIPPING|VID_TYPE_SCALES,
.hardware = VID_HARDWARE_BT848,
.fops = &bttv_fops,
.minor = -1,
diff --git a/drivers/media/video/bttvp.h b/drivers/media/video/bttvp.h
index 5e18bad1fba3..731356b65e3c 100644
--- a/drivers/media/video/bttvp.h
+++ b/drivers/media/video/bttvp.h
@@ -24,7 +24,7 @@
#ifndef _BTTVP_H_
#define _BTTVP_H_
-#include <linux/version.h>
+
#define BTTV_VERSION_CODE KERNEL_VERSION(0,9,11)
#include <linux/types.h>
diff --git a/drivers/message/fusion/mptbase.c b/drivers/message/fusion/mptbase.c
index 4728ee8a0a78..6b1cc1d2a164 100644
--- a/drivers/message/fusion/mptbase.c
+++ b/drivers/message/fusion/mptbase.c
@@ -1279,7 +1279,7 @@ mpt_adapter_install(struct pci_dev *pdev)
u32 psize;
int ii;
int r = -ENODEV;
- u64 mask = 0xffffffffffffffff;
+ u64 mask = 0xffffffffffffffffULL;
if (pci_enable_device(pdev))
return r;
diff --git a/drivers/message/fusion/mptscsih.c b/drivers/message/fusion/mptscsih.c
index b50219c8d5d4..a5a449a4a7d9 100644
--- a/drivers/message/fusion/mptscsih.c
+++ b/drivers/message/fusion/mptscsih.c
@@ -1458,7 +1458,6 @@ mptscsih_detect(Scsi_Host_Template *tpnt)
sh->max_lun = MPT_LAST_LUN + 1;
sh->max_sectors = MPT_SCSI_MAX_SECTORS;
- sh->highmem_io = 1;
sh->this_id = this->pfacts[portnum].PortSCSIID;
/* Required entry.
diff --git a/drivers/mtd/devices/blkmtd.c b/drivers/mtd/devices/blkmtd.c
index 46fc46934743..60a953401c02 100644
--- a/drivers/mtd/devices/blkmtd.c
+++ b/drivers/mtd/devices/blkmtd.c
@@ -287,13 +287,10 @@ static int blkmtd_readpage(mtd_raw_dev_data_t *rawdevice, struct page *page)
return 0;
}
-
static struct address_space_operations blkmtd_aops = {
- writepage: blkmtd_writepage,
- readpage: NULL,
+ .writepage = blkmtd_writepage,
};
-
/* This is the kernel thread that empties the write queue to disk */
static int write_queue_task(void *data)
{
diff --git a/drivers/net/3c505.c b/drivers/net/3c505.c
index de4ebe6d6504..dfd0ed0c486c 100644
--- a/drivers/net/3c505.c
+++ b/drivers/net/3c505.c
@@ -449,18 +449,18 @@ static int send_pcb(struct net_device *dev, pcb_struct * pcb)
case ASF_PCB_ACK:
adapter->send_pcb_semaphore = 0;
return TRUE;
- break;
+
case ASF_PCB_NAK:
#ifdef ELP_DEBUG
printk(KERN_DEBUG "%s: send_pcb got NAK\n", dev->name);
#endif
goto abort;
- break;
}
}
if (elp_debug >= 1)
printk(KERN_DEBUG "%s: timeout waiting for PCB acknowledge (status %02x)\n", dev->name, inb_status(dev->base_addr));
+ goto abort;
sti_abort:
spin_unlock_irqrestore(&adapter->lock, flags);
diff --git a/drivers/net/amd8111e.c b/drivers/net/amd8111e.c
index 48650bbc6337..7c245f7dd66b 100755
--- a/drivers/net/amd8111e.c
+++ b/drivers/net/amd8111e.c
@@ -1940,12 +1940,12 @@ err_disable_pdev:
}
static struct pci_driver amd8111e_driver = {
- name: MODULE_NAME,
- id_table: amd8111e_pci_tbl,
- probe: amd8111e_probe_one,
- remove: __devexit_p(amd8111e_remove_one),
- suspend: amd8111e_suspend,
- resume: amd8111e_resume
+ .name = MODULE_NAME,
+ .id_table = amd8111e_pci_tbl,
+ .probe = amd8111e_probe_one,
+ .remove = __devexit_p(amd8111e_remove_one),
+ .suspend = amd8111e_suspend,
+ .resume = amd8111e_resume
};
static int __init amd8111e_init(void)
diff --git a/drivers/net/arcnet/arc-rimi.c b/drivers/net/arcnet/arc-rimi.c
index db091f95f553..4668ca870292 100644
--- a/drivers/net/arcnet/arc-rimi.c
+++ b/drivers/net/arcnet/arc-rimi.c
@@ -132,9 +132,9 @@ static int __init arcrimi_found(struct net_device *dev)
u_long first_mirror, last_mirror, shmem;
int mirror_size;
- /* reserve the irq */ {
- if (request_irq(dev->irq, &arcnet_interrupt, 0, "arcnet (RIM I)", dev))
- BUGMSG(D_NORMAL, "Can't get IRQ %d!\n", dev->irq);
+ /* reserve the irq */
+ if (request_irq(dev->irq, &arcnet_interrupt, 0, "arcnet (RIM I)", dev)) {
+ BUGMSG(D_NORMAL, "Can't get IRQ %d!\n", dev->irq);
return -ENODEV;
}
diff --git a/drivers/net/meth.c b/drivers/net/meth.c
index eca8974e91df..3a253f16cb88 100644
--- a/drivers/net/meth.c
+++ b/drivers/net/meth.c
@@ -844,9 +844,6 @@ int meth_init_module(void)
printk("meth: error %i registering device \"%s\"\n",
result, meth_devs->name);
else device_present++;
-#ifndef METH_DEBUG
- EXPORT_NO_SYMBOLS;
-#endif
return device_present ? 0 : -ENODEV;
}
diff --git a/drivers/net/ppp_generic.c b/drivers/net/ppp_generic.c
index 606d7bf9842d..f022276d7aba 100644
--- a/drivers/net/ppp_generic.c
+++ b/drivers/net/ppp_generic.c
@@ -2073,7 +2073,8 @@ ppp_ccp_peek(struct ppp *ppp, struct sk_buff *skb, int inbound)
case CCP_CONFACK:
if ((ppp->flags & (SC_CCP_OPEN | SC_CCP_UP)) != SC_CCP_OPEN)
break;
- if (!pskb_may_pull(skb, len = CCP_LENGTH(dp)) + 2)
+ len = CCP_LENGTH(dp);
+ if (!pskb_may_pull(skb, len + 2))
return; /* too short */
dp += CCP_HDRLEN;
len -= CCP_HDRLEN;
diff --git a/drivers/net/rrunner.c b/drivers/net/rrunner.c
index e9e9012bd251..6ca8dda68f26 100644
--- a/drivers/net/rrunner.c
+++ b/drivers/net/rrunner.c
@@ -1641,13 +1641,13 @@ static int rr_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
spin_lock_irqsave(&rrpriv->lock, flags);
i = rr_read_eeprom(rrpriv, 0, image, EEPROM_BYTES);
+ spin_unlock_irqrestore(&rrpriv->lock, flags);
if (i != EEPROM_BYTES){
printk(KERN_ERR "%s: Error reading EEPROM\n",
dev->name);
error = -EFAULT;
goto gf_out;
}
- spin_unlock_irqrestore(&rrpriv->lock, flags);
error = copy_to_user(rq->ifr_data, image, EEPROM_BYTES);
if (error)
error = -EFAULT;
diff --git a/drivers/net/tun.c b/drivers/net/tun.c
index 470ac0908e58..cff9fec672f6 100644
--- a/drivers/net/tun.c
+++ b/drivers/net/tun.c
@@ -51,6 +51,8 @@ static int debug;
/* Network device part of the driver */
+static LIST_HEAD(tun_dev_list);
+
/* Net device open. */
static int tun_net_open(struct net_device *dev)
{
@@ -70,7 +72,7 @@ static int tun_net_xmit(struct sk_buff *skb, struct net_device *dev)
{
struct tun_struct *tun = (struct tun_struct *)dev->priv;
- DBG(KERN_INFO "%s: tun_net_xmit %d\n", tun->name, skb->len);
+ DBG(KERN_INFO "%s: tun_net_xmit %d\n", tun->dev->name, skb->len);
/* Drop packet if interface is not attached */
if (!tun->attached)
@@ -120,7 +122,7 @@ int tun_net_init(struct net_device *dev)
{
struct tun_struct *tun = (struct tun_struct *)dev->priv;
- DBG(KERN_INFO "%s: tun_net_init\n", tun->name);
+ DBG(KERN_INFO "%s: tun_net_init\n", tun->dev->name);
switch (tun->flags & TUN_TYPE_MASK) {
case TUN_TUN_DEV:
@@ -161,7 +163,7 @@ static unsigned int tun_chr_poll(struct file *file, poll_table * wait)
if (!tun)
return -EBADFD;
- DBG(KERN_INFO "%s: tun_chr_poll\n", tun->name);
+ DBG(KERN_INFO "%s: tun_chr_poll\n", tun->dev->name);
poll_wait(file, &tun->read_wait, wait);
@@ -226,7 +228,7 @@ static ssize_t tun_chr_writev(struct file * file, const struct iovec *iv,
if (!tun)
return -EBADFD;
- DBG(KERN_INFO "%s: tun_chr_write %d\n", tun->name, count);
+ DBG(KERN_INFO "%s: tun_chr_write %ld\n", tun->dev->name, count);
for (i = 0, len = 0; i < count; i++) {
if (verify_area(VERIFY_READ, iv[i].iov_base, iv[i].iov_len))
@@ -290,7 +292,7 @@ static ssize_t tun_chr_readv(struct file *file, const struct iovec *iv,
if (!tun)
return -EBADFD;
- DBG(KERN_INFO "%s: tun_chr_read\n", tun->name);
+ DBG(KERN_INFO "%s: tun_chr_read\n", tun->dev->name);
for (i = 0, len = 0; i < count; i++) {
if (verify_area(VERIFY_WRITE, iv[i].iov_base, iv[i].iov_len))
@@ -350,7 +352,7 @@ static void tun_setup(struct net_device *dev)
tun->owner = -1;
dev->init = tun_net_init;
- tun->name = dev->name;
+
SET_MODULE_OWNER(dev);
dev->open = tun_net_open;
dev->hard_start_xmit = tun_net_xmit;
@@ -359,27 +361,40 @@ static void tun_setup(struct net_device *dev)
dev->destructor = (void (*)(struct net_device *))kfree;
}
+static struct tun_struct *tun_get_by_name(const char *name)
+{
+ struct tun_struct *tun;
+
+ ASSERT_RTNL();
+ list_for_each_entry(tun, &tun_dev_list, list) {
+ if (!strncmp(tun->dev->name, name, IFNAMSIZ))
+ return tun;
+ }
+
+ return NULL;
+}
+
static int tun_set_iff(struct file *file, struct ifreq *ifr)
{
struct tun_struct *tun;
- struct net_device *dev;
int err;
- dev = __dev_get_by_name(ifr->ifr_name);
- if (dev) {
- /* Device exist */
- tun = dev->priv;
-
- if (dev->init != tun_net_init || tun->attached)
+ tun = tun_get_by_name(ifr->ifr_name);
+ if (tun) {
+ if (tun->attached)
return -EBUSY;
/* Check permissions */
- if (tun->owner != -1)
- if (current->euid != tun->owner && !capable(CAP_NET_ADMIN))
- return -EPERM;
- } else {
+ if (tun->owner != -1 &&
+ current->euid != tun->owner && !capable(CAP_NET_ADMIN))
+ return -EPERM;
+ }
+ else if (__dev_get_by_name(ifr->ifr_name))
+ return -EINVAL;
+ else {
char *name;
unsigned long flags = 0;
+ struct net_device *dev;
err = -EINVAL;
@@ -420,9 +435,10 @@ static int tun_set_iff(struct file *file, struct ifreq *ifr)
goto failed;
}
+ list_add(&tun->list, &tun_dev_list);
}
- DBG(KERN_INFO "%s: tun_set_iff\n", tun->name);
+ DBG(KERN_INFO "%s: tun_set_iff\n", tun->dev->name);
if (ifr->ifr_flags & IFF_NO_PI)
tun->flags |= TUN_NO_PI;
@@ -433,7 +449,7 @@ static int tun_set_iff(struct file *file, struct ifreq *ifr)
file->private_data = tun;
tun->attached = 1;
- strcpy(ifr->ifr_name, tun->name);
+ strcpy(ifr->ifr_name, tun->dev->name);
return 0;
failed:
return err;
@@ -459,14 +475,15 @@ static int tun_chr_ioctl(struct inode *inode, struct file *file,
if (err)
return err;
- copy_to_user((void *)arg, &ifr, sizeof(ifr));
+ if (copy_to_user((void *)arg, &ifr, sizeof(ifr)))
+ return -EFAULT;
return 0;
}
if (!tun)
return -EBADFD;
- DBG(KERN_INFO "%s: tun_chr_ioctl cmd %d\n", tun->name, cmd);
+ DBG(KERN_INFO "%s: tun_chr_ioctl cmd %d\n", tun->dev->name, cmd);
switch (cmd) {
case TUNSETNOCSUM:
@@ -477,7 +494,7 @@ static int tun_chr_ioctl(struct inode *inode, struct file *file,
tun->flags &= ~TUN_NOCHECKSUM;
DBG(KERN_INFO "%s: checksum %s\n",
- tun->name, arg ? "disabled" : "enabled");
+ tun->dev->name, arg ? "disabled" : "enabled");
break;
case TUNSETPERSIST:
@@ -488,14 +505,14 @@ static int tun_chr_ioctl(struct inode *inode, struct file *file,
tun->flags &= ~TUN_PERSIST;
DBG(KERN_INFO "%s: persist %s\n",
- tun->name, arg ? "disabled" : "enabled");
+ tun->dev->name, arg ? "disabled" : "enabled");
break;
case TUNSETOWNER:
/* Set owner of the device */
tun->owner = (uid_t) arg;
- DBG(KERN_INFO "%s: owner set to %d\n", tun->owner);
+ DBG(KERN_INFO "%s: owner set to %d\n", tun->dev->name, tun->owner);
break;
#ifdef TUN_DEBUG
@@ -519,7 +536,7 @@ static int tun_chr_fasync(int fd, struct file *file, int on)
if (!tun)
return -EBADFD;
- DBG(KERN_INFO "%s: tun_chr_fasync %d\n", tun->name, on);
+ DBG(KERN_INFO "%s: tun_chr_fasync %d\n", tun->dev->name, on);
if ((ret = fasync_helper(fd, file, on, &tun->fasync)) < 0)
return ret;
@@ -549,7 +566,7 @@ static int tun_chr_close(struct inode *inode, struct file *file)
if (!tun)
return 0;
- DBG(KERN_INFO "%s: tun_chr_close\n", tun->name);
+ DBG(KERN_INFO "%s: tun_chr_close\n", tun->dev->name);
tun_chr_fasync(-1, file, 0);
@@ -562,8 +579,10 @@ static int tun_chr_close(struct inode *inode, struct file *file)
/* Drop read queue */
skb_queue_purge(&tun->readq);
- if (!(tun->flags & TUN_PERSIST))
+ if (!(tun->flags & TUN_PERSIST)) {
+ list_del(&tun->list);
unregister_netdevice(tun->dev);
+ }
rtnl_unlock();
@@ -605,7 +624,17 @@ int __init tun_init(void)
void tun_cleanup(void)
{
+ struct tun_struct *tun, *nxt;
+
misc_deregister(&tun_miscdev);
+
+ rtnl_lock();
+ list_for_each_entry_safe(tun, nxt, &tun_dev_list, list) {
+ DBG(KERN_INFO "%s cleaned up\n", tun->dev->name);
+ unregister_netdevice(tun->dev);
+ }
+ rtnl_unlock();
+
}
module_init(tun_init);
diff --git a/drivers/net/wan/comx-hw-locomx.c b/drivers/net/wan/comx-hw-locomx.c
index 320f15874171..45bf7f870848 100644
--- a/drivers/net/wan/comx-hw-locomx.c
+++ b/drivers/net/wan/comx-hw-locomx.c
@@ -339,7 +339,10 @@ static int locomx_write_proc(struct file *file, const char *buffer,
return -ENOMEM;
}
- copy_from_user(page, buffer, count = min_t(unsigned long, count, PAGE_SIZE));
+ if (copy_from_user(page, buffer, count = min_t(unsigned long, count, PAGE_SIZE))) {
+ free_page((unsigned long)page);
+ return -EBADF;
+ }
if (*(page + count - 1) == '\n') {
*(page + count - 1) = 0;
}
diff --git a/drivers/net/wan/comx-hw-mixcom.c b/drivers/net/wan/comx-hw-mixcom.c
index 3b5c7388163e..0881f7e17563 100644
--- a/drivers/net/wan/comx-hw-mixcom.c
+++ b/drivers/net/wan/comx-hw-mixcom.c
@@ -763,7 +763,10 @@ static int mixcom_write_proc(struct file *file, const char *buffer,
return -ENOMEM;
}
- copy_from_user(page, buffer, count = min_t(unsigned long, count, PAGE_SIZE));
+ if (copy_from_user(page, buffer, count = min_t(unsigned long, count, PAGE_SIZE))) {
+ free_page((unsigned long)page);
+ return -EFAULT;
+ }
if (*(page + count - 1) == '\n') {
*(page + count - 1) = 0;
}
diff --git a/drivers/net/wan/comx-hw-munich.c b/drivers/net/wan/comx-hw-munich.c
index 24d62f203b49..911862ed940a 100644
--- a/drivers/net/wan/comx-hw-munich.c
+++ b/drivers/net/wan/comx-hw-munich.c
@@ -2414,7 +2414,10 @@ static int munich_write_proc(struct file *file, const char *buffer,
return -ENOMEM;
/* Copy user data and cut trailing \n */
- copy_from_user(page, buffer, count = min(count, PAGE_SIZE));
+ if (copy_from_user(page, buffer, count = min(count, PAGE_SIZE))) {
+ free_page((unsigned long)page);
+ return -EFAULT;
+ }
if (*(page + count - 1) == '\n')
*(page + count - 1) = 0;
*(page + PAGE_SIZE - 1) = 0;
diff --git a/drivers/net/wan/comx-proto-fr.c b/drivers/net/wan/comx-proto-fr.c
index 3eb97644d3d4..e1c83300548d 100644
--- a/drivers/net/wan/comx-proto-fr.c
+++ b/drivers/net/wan/comx-proto-fr.c
@@ -657,7 +657,10 @@ static int fr_write_proc(struct file *file, const char *buffer,
return -ENOMEM;
}
- copy_from_user(page, buffer, count);
+ if (copy_from_user(page, buffer, count)) {
+ free_page((unsigned long)page);
+ return -EFAULT;
+ }
if (*(page + count - 1) == '\n') {
*(page + count - 1) = 0;
}
diff --git a/drivers/net/wan/comx-proto-lapb.c b/drivers/net/wan/comx-proto-lapb.c
index 0d57623e868f..ae0f5fde7519 100644
--- a/drivers/net/wan/comx-proto-lapb.c
+++ b/drivers/net/wan/comx-proto-lapb.c
@@ -232,7 +232,10 @@ static int comxlapb_write_proc(struct file *file, const char *buffer,
return -ENOMEM;
}
- copy_from_user(page, buffer, count);
+ if (copy_from_user(page, buffer, count)) {
+ free_page((unsigned long)page);
+ return -EFAULT;
+ }
if (*(page + count - 1) == '\n') {
*(page + count - 1) = 0;
}
diff --git a/drivers/net/wan/pc300_drv.c b/drivers/net/wan/pc300_drv.c
index f8a2b3e7c06b..21d1deffca33 100644
--- a/drivers/net/wan/pc300_drv.c
+++ b/drivers/net/wan/pc300_drv.c
@@ -2623,7 +2623,8 @@ int cpc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
sizeof(struct net_device_stats));
if (card->hw.type == PC300_TE)
memcpy(&pc300stats.te_stats,&chan->falc,sizeof(falc_t));
- copy_to_user(arg, &pc300stats, sizeof(pc300stats_t));
+ if (copy_to_user(arg, &pc300stats, sizeof(pc300stats_t)))
+ return -EFAULT;
}
return 0;
}
diff --git a/drivers/net/wan/sbni.c b/drivers/net/wan/sbni.c
index df78c1517e4f..362f28421c01 100644
--- a/drivers/net/wan/sbni.c
+++ b/drivers/net/wan/sbni.c
@@ -1287,8 +1287,9 @@ sbni_ioctl( struct net_device *dev, struct ifreq *ifr, int cmd )
error = verify_area( VERIFY_WRITE, ifr->ifr_data,
sizeof(struct sbni_in_stats) );
if( !error )
- copy_to_user( ifr->ifr_data, &nl->in_stats,
- sizeof(struct sbni_in_stats) );
+ if (copy_to_user( ifr->ifr_data, &nl->in_stats,
+ sizeof(struct sbni_in_stats) ))
+ return -EFAULT;
break;
case SIOCDEVRESINSTATS :
@@ -1307,7 +1308,8 @@ sbni_ioctl( struct net_device *dev, struct ifreq *ifr, int cmd )
error = verify_area( VERIFY_WRITE, ifr->ifr_data,
sizeof flags );
if( !error )
- copy_to_user( ifr->ifr_data, &flags, sizeof flags );
+ if (copy_to_user( ifr->ifr_data, &flags, sizeof flags ))
+ return -EFAULT;
break;
case SIOCDEVSHWSTATE :
@@ -1339,7 +1341,8 @@ sbni_ioctl( struct net_device *dev, struct ifreq *ifr, int cmd )
sizeof slave_name )) != 0 )
return error;
- copy_from_user( slave_name, ifr->ifr_data, sizeof slave_name );
+ if (copy_from_user( slave_name, ifr->ifr_data, sizeof slave_name ))
+ return -EFAULT;
slave_dev = dev_get_by_name( slave_name );
if( !slave_dev || !(slave_dev->flags & IFF_UP) ) {
printk( KERN_ERR "%s: trying to enslave non-active "
diff --git a/drivers/pcmcia/ds.c b/drivers/pcmcia/ds.c
index 5a05ccdb6aa9..31d89c588ec1 100644
--- a/drivers/pcmcia/ds.c
+++ b/drivers/pcmcia/ds.c
@@ -689,7 +689,7 @@ static int ds_ioctl(struct inode * inode, struct file * file,
err = ret = 0;
- if (cmd & IOC_IN) copy_from_user((char *)&buf, (char *)arg, size);
+ if (cmd & IOC_IN) __copy_from_user((char *)&buf, (char *)arg, size);
switch (cmd) {
case DS_ADJUST_RESOURCE_INFO:
@@ -803,9 +803,9 @@ static int ds_ioctl(struct inode * inode, struct file * file,
err = -EIO; break;
}
}
-
- if (cmd & IOC_OUT) copy_to_user((char *)arg, (char *)&buf, size);
-
+
+ if (cmd & IOC_OUT) __copy_to_user((char *)arg, (char *)&buf, size);
+
return err;
} /* ds_ioctl */
diff --git a/drivers/sbus/char/riowatchdog.c b/drivers/sbus/char/riowatchdog.c
index acaa214163e1..f34c4a9dee0f 100644
--- a/drivers/sbus/char/riowatchdog.c
+++ b/drivers/sbus/char/riowatchdog.c
@@ -194,17 +194,11 @@ static ssize_t riowd_write(struct file *file, const char *buf, size_t count, lof
return 0;
}
-static ssize_t riowd_read(struct file *file, char *buffer, size_t count, loff_t *ppos)
-{
- return -EINVAL;
-}
-
static struct file_operations riowd_fops = {
.owner = THIS_MODULE,
.ioctl = riowd_ioctl,
.open = riowd_open,
.write = riowd_write,
- .read = riowd_read,
.release = riowd_release,
};
diff --git a/drivers/scsi/3w-xxxx.c b/drivers/scsi/3w-xxxx.c
index 811f4c95578a..05e491e7a278 100644
--- a/drivers/scsi/3w-xxxx.c
+++ b/drivers/scsi/3w-xxxx.c
@@ -3451,7 +3451,6 @@ static Scsi_Host_Template driver_template = {
.cmd_per_lun = TW_MAX_CMDS_PER_LUN,
.use_clustering = ENABLE_CLUSTERING,
.emulated = 1,
- .highmem_io = 1,
};
#include "scsi_module.c"
diff --git a/drivers/scsi/53c700.c b/drivers/scsi/53c700.c
index c2fce462e847..60bb81d4649b 100644
--- a/drivers/scsi/53c700.c
+++ b/drivers/scsi/53c700.c
@@ -282,7 +282,6 @@ NCR_700_detect(Scsi_Host_Template *tpnt,
tpnt->slave_configure = NCR_700_slave_configure;
tpnt->slave_destroy = NCR_700_slave_destroy;
tpnt->use_blk_tcq = 1;
- tpnt->highmem_io = 1;
if(tpnt->name == NULL)
tpnt->name = "53c700";
diff --git a/drivers/scsi/NCR53c406a.c b/drivers/scsi/NCR53c406a.c
index 9583fda4c924..be58e5a9edb3 100644
--- a/drivers/scsi/NCR53c406a.c
+++ b/drivers/scsi/NCR53c406a.c
@@ -450,6 +450,7 @@ static __inline__ int NCR53c406a_pio_write(unsigned char *request, unsigned int
static int __init NCR53c406a_detect(Scsi_Host_Template * tpnt)
{
+ int present = 0;
struct Scsi_Host *shpnt = NULL;
#ifndef PORT_BASE
int i;
@@ -522,7 +523,7 @@ static int __init NCR53c406a_detect(Scsi_Host_Template * tpnt)
DEB(printk("NCR53c406a: using port_base 0x%x\n", port_base));
- tpnt->present = 1;
+ present = 1;
tpnt->proc_name = "NCR53c406a";
shpnt = scsi_register(tpnt, 0);
@@ -576,7 +577,7 @@ static int __init NCR53c406a_detect(Scsi_Host_Template * tpnt)
sprintf(info_msg, "NCR53c406a at 0x%x, IRQ %d, %s PIO mode.", port_base, irq_level, fast_pio ? "fast" : "slow");
#endif
- return (tpnt->present);
+ return (present);
#if USE_DMA
err_free_irq:
diff --git a/drivers/scsi/aacraid/linit.c b/drivers/scsi/aacraid/linit.c
index 1328bbcbc402..89f88dbf4cf4 100644
--- a/drivers/scsi/aacraid/linit.c
+++ b/drivers/scsi/aacraid/linit.c
@@ -295,7 +295,6 @@ static int aac_detect(Scsi_Host_Template *template)
printk(KERN_WARNING "aacraid: unable to register \"aac\" device.\n");
}
- template->present = aac_count; /* # of cards of this type found */
return aac_count;
}
diff --git a/drivers/scsi/aha152x.c b/drivers/scsi/aha152x.c
index 49a424007ac4..0f4c25439217 100644
--- a/drivers/scsi/aha152x.c
+++ b/drivers/scsi/aha152x.c
@@ -1868,12 +1868,31 @@ static void run(void)
static irqreturn_t intr(int irqno, void *dev_id, struct pt_regs *regs)
{
struct Scsi_Host *shpnt = lookup_irq(irqno);
+ unsigned char rev, dmacntrl0;
if (!shpnt) {
printk(KERN_ERR "aha152x: catched interrupt %d for unknown controller.\n", irqno);
return IRQ_NONE;
}
+ /*
+ * Read a couple of registers that are known to not be all 1's. If
+ * we read all 1's (-1), that means that either:
+ *
+ * a. The host adapter chip has gone bad, and we cannot control it,
+ * OR
+ * b. The host adapter is a PCMCIA card that has been ejected
+ *
+ * In either case, we cannot do anything with the host adapter at
+ * this point in time. So just ignore the interrupt and return.
+ * In the latter case, the interrupt might actually be meant for
+ * someone else sharing this IRQ, and that driver will handle it.
+ */
+ rev = GETPORT(REV);
+ dmacntrl0 = GETPORT(DMACNTRL0);
+ if ((rev == 0xFF) && (dmacntrl0 == 0xFF))
+ return IRQ_NONE;
+
/* no more interrupts from the controller, while we're busy.
INTEN is restored by the BH handler */
CLRBITS(DMACNTRL0, INTEN);
diff --git a/drivers/scsi/aic7xxx/aic79xx_osm.c b/drivers/scsi/aic7xxx/aic79xx_osm.c
index 1b87b2aac104..3857ed2508b8 100644
--- a/drivers/scsi/aic7xxx/aic79xx_osm.c
+++ b/drivers/scsi/aic7xxx/aic79xx_osm.c
@@ -1681,33 +1681,9 @@ Scsi_Host_Template aic79xx_driver_template = {
.this_id = -1,
.cmd_per_lun = 2,
.use_clustering = ENABLE_CLUSTERING,
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,7)
- /*
- * We can only map 16MB per-SG
- * so create a sector limit of
- * "16MB" in 2K sectors.
- */
- .max_sectors = 8192,
-#endif
-#if defined CONFIG_HIGHIO || LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,10)
-/* Assume RedHat Distribution with its different HIGHIO conventions. */
- .can_dma_32 = 1,
- .single_sg_okay = 1,
-#else
- .highmem_io = 1,
-#endif
-#endif
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
.slave_alloc = ahd_linux_slave_alloc,
.slave_configure = ahd_linux_slave_configure,
.slave_destroy = ahd_linux_slave_destroy,
-#else
- .detect = ahd_linux_detect,
- .release = ahd_linux_release,
- .select_queue_depths = ahd_linux_select_queue_depth,
- .use_new_eh_code = 1,
-#endif
};
/**************************** Tasklet Handler *********************************/
diff --git a/drivers/scsi/aic7xxx/aic7xxx_osm.c b/drivers/scsi/aic7xxx/aic7xxx_osm.c
index 8c1e4086a808..599f0e306629 100644
--- a/drivers/scsi/aic7xxx/aic7xxx_osm.c
+++ b/drivers/scsi/aic7xxx/aic7xxx_osm.c
@@ -1307,33 +1307,9 @@ Scsi_Host_Template aic7xxx_driver_template = {
.this_id = -1,
.cmd_per_lun = 2,
.use_clustering = ENABLE_CLUSTERING,
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,7)
- /*
- * We can only map 16MB per-SG
- * so create a sector limit of
- * "16MB" in 2K sectors.
- */
- .max_sectors = 8192,
-#endif
-#if defined CONFIG_HIGHIO || LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,10)
-/* Assume RedHat Distribution with its different HIGHIO conventions. */
- .can_dma_32 = 1,
- .single_sg_okay = 1,
-#else
- .highmem_io = 1,
-#endif
-#endif
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
.slave_alloc = ahc_linux_slave_alloc,
.slave_configure = ahc_linux_slave_configure,
.slave_destroy = ahc_linux_slave_destroy,
-#else
- .detect = ahc_linux_detect,
- .release = ahc_linux_release,
- .select_queue_depths = ahc_linux_select_queue_depth,
- .use_new_eh_code = 1,
-#endif
};
/**************************** Tasklet Handler *********************************/
diff --git a/drivers/scsi/cpqfcTSinit.c b/drivers/scsi/cpqfcTSinit.c
index 9a519af985ce..943778cca0eb 100644
--- a/drivers/scsi/cpqfcTSinit.c
+++ b/drivers/scsi/cpqfcTSinit.c
@@ -549,14 +549,14 @@ void cpqfc_free_private_data(CPQFCHBA *hba, cpqfc_passthru_private_t *data)
hba->private_data_bits+(i/BITS_PER_LONG));
}
-int cpqfcTS_ioctl( Scsi_Device *ScsiDev, int Cmnd, void *arg)
+int cpqfcTS_ioctl( struct scsi_device *ScsiDev, int Cmnd, void *arg)
{
int result = 0;
struct Scsi_Host *HostAdapter = ScsiDev->host;
CPQFCHBA *cpqfcHBAdata = (CPQFCHBA *)HostAdapter->hostdata;
PTACHYON fcChip = &cpqfcHBAdata->fcChip;
PFC_LOGGEDIN_PORT pLoggedInPort = NULL;
- Scsi_Cmnd DumCmnd;
+ struct scsi_cmnd *DumCmnd;
int i, j;
VENDOR_IOCTL_REQ ioc;
cpqfc_passthru_t *vendor_cmd;
@@ -723,13 +723,16 @@ int cpqfcTS_ioctl( Scsi_Device *ScsiDev, int Cmnd, void *arg)
/* DumCmnd.target = ScsiDev->id; */
/* DumCmnd.lun = ScsiDev->lun; */
- DumCmnd.device = ScsiDev;
+ DumCmnd = scsi_get_command (ScsiDev, GFP_KERNEL);
+ if (!DumCmnd)
+ return -ENOMEM;
pLoggedInPort = fcFindLoggedInPort( fcChip,
- &DumCmnd, // search Scsi Nexus
+ DumCmnd, // search Scsi Nexus
0, // DON'T search linked list for FC port id
NULL, // DON'T search linked list for FC WWN
NULL); // DON'T care about end of list
+ scsi_put_command (DumCmnd);
if (pLoggedInPort == NULL) {
result = -ENXIO;
break;
@@ -918,7 +921,8 @@ static int copy_info(struct info_str *info, char *fmt, ...)
int cpqfcTS_proc_info (struct Scsi_Host *host, char *buffer, char **start, off_t offset, int length,
int inout)
{
- Scsi_Cmnd DumCmnd;
+ struct scsi_cmnd *DumCmnd;
+ struct scsi_device *ScsiDev;
int Chan, Targ, i;
struct info_str info;
CPQFCHBA *cpqfcHBA;
@@ -946,13 +950,21 @@ int cpqfcTS_proc_info (struct Scsi_Host *host, char *buffer, char **start, off_t
#define DISPLAY_WWN_INFO
#ifdef DISPLAY_WWN_INFO
+ ScsiDev = scsi_get_host_dev (host);
+ if (!ScsiDev)
+ return -ENOMEM;
+ DumCmnd = scsi_get_command (ScsiDev, GFP_KERNEL);
+ if (!DumCmnd) {
+ scsi_free_host_dev (ScsiDev);
+ return -ENOMEM;
+ }
copy_info(&info, "WWN database: (\"port_id: 000000\" means disconnected)\n");
for ( Chan=0; Chan <= host->max_channel; Chan++) {
- DumCmnd.channel = Chan;
+ DumCmnd->device->channel = Chan;
for (Targ=0; Targ <= host->max_id; Targ++) {
- DumCmnd.target = Targ;
+ DumCmnd->device->id = Targ;
if ((pLoggedInPort = fcFindLoggedInPort( fcChip,
- &DumCmnd, // search Scsi Nexus
+ DumCmnd, // search Scsi Nexus
0, // DON'T search list for FC port id
NULL, // DON'T search list for FC WWN
NULL))){ // DON'T care about end of list
@@ -966,6 +978,9 @@ int cpqfcTS_proc_info (struct Scsi_Host *host, char *buffer, char **start, off_t
}
}
}
+
+ scsi_put_command (DumCmnd);
+ scsi_free_host_dev (ScsiDev);
#endif
@@ -1578,7 +1593,7 @@ int cpqfcTS_TargetDeviceReset( Scsi_Device *ScsiDev,
// Scsi_Request, etc.
// For now, so people don't fall into a hole...
return -ENOTSUPP;
-
+/*
// printk(" ENTERING cpqfcTS_TargetDeviceReset() - flag=%d \n",reset_flags);
if (ScsiDev->host->eh_active) return FAILED;
@@ -1600,7 +1615,7 @@ return -ENOTSUPP;
SCpnt->request->CPQFC_WAITING = NULL;
}
-/*
+
if(driver_byte(SCpnt->result) != 0)
switch(SCpnt->sense_buffer[2] & 0xf) {
case ILLEGAL_REQUEST:
diff --git a/drivers/scsi/cpqfcTSstructs.h b/drivers/scsi/cpqfcTSstructs.h
index c208b98323ef..0bae3298c44b 100644
--- a/drivers/scsi/cpqfcTSstructs.h
+++ b/drivers/scsi/cpqfcTSstructs.h
@@ -696,7 +696,6 @@ typedef struct
ULONG port_id; // a FC 24-bit address of port (lower 8 bits = al_pa)
- Scsi_Cmnd ScsiCmnd; // command buffer for Report Luns
#define REPORT_LUNS_PL 256
UCHAR ReportLunsPayload[REPORT_LUNS_PL];
diff --git a/drivers/scsi/cpqfcTSworker.c b/drivers/scsi/cpqfcTSworker.c
index 553d01543437..b41038baa394 100644
--- a/drivers/scsi/cpqfcTSworker.c
+++ b/drivers/scsi/cpqfcTSworker.c
@@ -30,6 +30,7 @@
#include <linux/interrupt.h>
#include <linux/delay.h>
#include <linux/smp_lock.h>
+#include <linux/pci.h>
#define __KERNEL_SYSCALLS__
@@ -1196,9 +1197,9 @@ void cpqfcTSTerminateExchange(
// have to terminate by SCSI target, NOT port_id.
if( Exchanges->fcExchange[x_ID].Cmnd) // Cmnd in progress?
{
- if( (Exchanges->fcExchange[x_ID].Cmnd->target == ScsiNexus->target)
+ if( (Exchanges->fcExchange[x_ID].Cmnd->device->id == ScsiNexus->target)
&&
- (Exchanges->fcExchange[x_ID].Cmnd->channel == ScsiNexus->channel))
+ (Exchanges->fcExchange[x_ID].Cmnd->device->channel == ScsiNexus->channel))
{
Exchanges->fcExchange[x_ID].status = TerminateStatus;
cpqfcTSPutLinkQue( cpqfcHBAdata, BLS_ABTS, &x_ID ); // timed-out
@@ -2681,7 +2682,7 @@ static void SendLogins( CPQFCHBA *cpqfcHBAdata, __u32 *FabricPortIds )
// D. Deming, 1994, pg 7-19 (ISBN 1-879936-08-9)
static void ScsiReportLunsDone(Scsi_Cmnd *Cmnd)
{
- struct Scsi_Host *HostAdapter = Cmnd->host;
+ struct Scsi_Host *HostAdapter = Cmnd->device->host;
CPQFCHBA *cpqfcHBAdata = (CPQFCHBA *)HostAdapter->hostdata;
PTACHYON fcChip = &cpqfcHBAdata->fcChip;
FC_EXCHANGES *Exchanges = fcChip->Exchanges;
@@ -2887,11 +2888,11 @@ static void
call_scsi_done(Scsi_Cmnd *Cmnd)
{
CPQFCHBA *hba;
- hba = (CPQFCHBA *) Cmnd->host->hostdata;
+ hba = (CPQFCHBA *) Cmnd->device->host->hostdata;
// Was this command a cpqfc passthru ioctl ?
- if (Cmnd->sc_request != NULL && Cmnd->host != NULL &&
- Cmnd->host->hostdata != NULL &&
- is_private_data_of_cpqfc((CPQFCHBA *) Cmnd->host->hostdata,
+ if (Cmnd->sc_request != NULL && Cmnd->device->host != NULL &&
+ Cmnd->device->host->hostdata != NULL &&
+ is_private_data_of_cpqfc((CPQFCHBA *) Cmnd->device->host->hostdata,
Cmnd->sc_request->upper_private_data)) {
cpqfc_free_private_data(hba,
Cmnd->sc_request->upper_private_data);
@@ -2918,7 +2919,8 @@ static void IssueReportLunsCommand(
{
PTACHYON fcChip = &cpqfcHBAdata->fcChip;
PFC_LOGGEDIN_PORT pLoggedInPort;
- Scsi_Cmnd *Cmnd;
+ struct scsi_cmnd *Cmnd = NULL;
+ struct scsi_device *ScsiDev = NULL;
LONG x_ID;
ULONG ulStatus;
UCHAR *ucBuff;
@@ -2942,17 +2944,20 @@ static void IssueReportLunsCommand(
if( !(pLoggedInPort->fcp_info & TARGET_FUNCTION) )
goto Done; // forget it - FC device not a "target"
- // now use the port's Scsi Command buffer for the
- // Report Luns Command
- Cmnd = &pLoggedInPort->ScsiCmnd;
+ ScsiDev = scsi_get_host_dev (cpqfcHBAdata->HostAdapter);
+ if (!ScsiDev)
+ goto Done;
+
+ Cmnd = scsi_get_command (ScsiDev, GFP_KERNEL);
+ if (!Cmnd)
+ goto Done;
+
ucBuff = pLoggedInPort->ReportLunsPayload;
- memset( Cmnd, 0, sizeof(Scsi_Cmnd));
memset( ucBuff, 0, REPORT_LUNS_PL);
Cmnd->scsi_done = ScsiReportLunsDone;
- Cmnd->host = cpqfcHBAdata->HostAdapter;
Cmnd->request_buffer = pLoggedInPort->ReportLunsPayload;
Cmnd->request_bufflen = REPORT_LUNS_PL;
@@ -2962,8 +2967,8 @@ static void IssueReportLunsCommand(
Cmnd->cmnd[9] = (UCHAR)REPORT_LUNS_PL;
Cmnd->cmd_len = 12;
- Cmnd->channel = pLoggedInPort->ScsiNexus.channel;
- Cmnd->target = pLoggedInPort->ScsiNexus.target;
+ Cmnd->device->channel = pLoggedInPort->ScsiNexus.channel;
+ Cmnd->device->id = pLoggedInPort->ScsiNexus.target;
ulStatus = cpqfcTSBuildExchange(
@@ -3003,6 +3008,10 @@ static void IssueReportLunsCommand(
Done:
+ if (Cmnd)
+ scsi_put_command (Cmnd);
+ if (ScsiDev)
+ scsi_free_host_dev (ScsiDev);
}
@@ -3361,22 +3370,22 @@ PFC_LOGGEDIN_PORT fcFindLoggedInPort(
{
// check Linux Scsi Cmnd for channel/target Nexus match
// (all luns are accessed through matching "pLoggedInPort")
- if( (pLoggedInPort->ScsiNexus.target == Cmnd->target)
+ if( (pLoggedInPort->ScsiNexus.target == Cmnd->device->id)
&&
- (pLoggedInPort->ScsiNexus.channel == Cmnd->channel))
+ (pLoggedInPort->ScsiNexus.channel == Cmnd->device->channel))
{
// For "passthru" modes, the IOCTL caller is responsible
// for setting the FCP-LUN addressing
- if (Cmnd->sc_request != NULL && Cmnd->host != NULL &&
- Cmnd->host->hostdata != NULL &&
- is_private_data_of_cpqfc((CPQFCHBA *) Cmnd->host->hostdata,
+ if (Cmnd->sc_request != NULL && Cmnd->device->host != NULL &&
+ Cmnd->device->host->hostdata != NULL &&
+ is_private_data_of_cpqfc((CPQFCHBA *) Cmnd->device->host->hostdata,
Cmnd->sc_request->upper_private_data)) {
/* This is a passthru... */
cpqfc_passthru_private_t *pd;
pd = Cmnd->sc_request->upper_private_data;
Cmnd->SCp.phase = pd->bus;
// Cmnd->SCp.have_data_in = pd->pdrive;
- Cmnd->SCp.have_data_in = Cmnd->lun;
+ Cmnd->SCp.have_data_in = Cmnd->device->lun;
} else {
/* This is not a passthru... */
@@ -3391,17 +3400,17 @@ PFC_LOGGEDIN_PORT fcFindLoggedInPort(
// Report Luns command
if( pLoggedInPort->ScsiNexus.LunMasking == 1)
{
- if (Cmnd->lun > sizeof(pLoggedInPort->ScsiNexus.lun))
+ if (Cmnd->device->lun > sizeof(pLoggedInPort->ScsiNexus.lun))
return NULL;
// we KNOW all the valid LUNs... 0xFF is invalid!
- Cmnd->SCp.have_data_in = pLoggedInPort->ScsiNexus.lun[Cmnd->lun];
- if (pLoggedInPort->ScsiNexus.lun[Cmnd->lun] == 0xFF)
+ Cmnd->SCp.have_data_in = pLoggedInPort->ScsiNexus.lun[Cmnd->device->lun];
+ if (pLoggedInPort->ScsiNexus.lun[Cmnd->device->lun] == 0xFF)
return NULL;
// printk("xlating lun %d to 0x%02x\n", Cmnd->lun,
// pLoggedInPort->ScsiNexus.lun[Cmnd->lun]);
}
else
- Cmnd->SCp.have_data_in = Cmnd->lun; // Linux & target luns match
+ Cmnd->SCp.have_data_in = Cmnd->device->lun; // Linux & target luns match
}
break; // found it!
}
@@ -3507,9 +3516,9 @@ static void UnblockScsiDevice( struct Scsi_Host *HostAdapter,
// Are there any Q'd commands for this target?
- if( (Cmnd->target == pLoggedInPort->ScsiNexus.target)
+ if( (Cmnd->device->id == pLoggedInPort->ScsiNexus.target)
&&
- (Cmnd->channel == pLoggedInPort->ScsiNexus.channel) )
+ (Cmnd->device->channel == pLoggedInPort->ScsiNexus.channel) )
{
Cmnd->result = (DID_SOFT_ERROR <<16); // force retry
if( Cmnd->scsi_done == NULL)
diff --git a/drivers/scsi/dc395x.c b/drivers/scsi/dc395x.c
index 45050fc1505c..0714ea4b8736 100644
--- a/drivers/scsi/dc395x.c
+++ b/drivers/scsi/dc395x.c
@@ -264,6 +264,44 @@ struct SGentry {
};
+/*
+ * The SEEPROM structure for TRM_S1040
+ */
+struct NVRamTarget {
+ u8 cfg0; /* Target configuration byte 0 */
+ u8 period; /* Target period */
+ u8 cfg2; /* Target configuration byte 2 */
+ u8 cfg3; /* Target configuration byte 3 */
+};
+
+
+struct NvRamType {
+ u8 sub_vendor_id[2]; /* 0,1 Sub Vendor ID */
+ u8 sub_sys_id[2]; /* 2,3 Sub System ID */
+ u8 sub_class; /* 4 Sub Class */
+ u8 vendor_id[2]; /* 5,6 Vendor ID */
+ u8 device_id[2]; /* 7,8 Device ID */
+ u8 reserved; /* 9 Reserved */
+ struct NVRamTarget target[DC395x_MAX_SCSI_ID];
+ /** 10,11,12,13
+ ** 14,15,16,17
+ ** ....
+ ** ....
+ ** 70,71,72,73
+ */
+ u8 scsi_id; /* 74 Host Adapter SCSI ID */
+ u8 channel_cfg; /* 75 Channel configuration */
+ u8 delay_time; /* 76 Power on delay time */
+ u8 max_tag; /* 77 Maximum tags */
+ u8 reserved0; /* 78 */
+ u8 boot_target; /* 79 */
+ u8 boot_lun; /* 80 */
+ u8 reserved1; /* 81 */
+ u16 reserved2[22]; /* 82,..125 */
+ u16 cksum; /* 126,127 */
+};
+
+
/*-----------------------------------------------------------------------
SCSI Request Block
-----------------------------------------------------------------------*/
@@ -349,7 +387,6 @@ struct DeviceCtlBlk {
-----------------------------------------------------------------------*/
struct AdapterCtlBlk {
struct Scsi_Host *scsi_host;
- struct AdapterCtlBlk *next_acb;
u16 IOPortBase;
@@ -365,7 +402,6 @@ struct AdapterCtlBlk {
struct timer_list selto_timer;
u16 srb_count;
- u16 adapter_index; /* nth Adapter this driver */
u8 dcb_count;
u8 sel_timeout;
@@ -389,45 +425,11 @@ struct AdapterCtlBlk {
struct ScsiReqBlk srb_array[DC395x_MAX_SRB_CNT];
struct ScsiReqBlk srb;
-};
-
-/*
- * The SEEPROM structure for TRM_S1040
- */
-struct NVRamTarget {
- u8 cfg0; /* Target configuration byte 0 */
- u8 period; /* Target period */
- u8 cfg2; /* Target configuration byte 2 */
- u8 cfg3; /* Target configuration byte 3 */
+ struct NvRamType eeprom; /* eeprom settings for this adapter */
};
-struct NvRamType {
- u8 sub_vendor_id[2]; /* 0,1 Sub Vendor ID */
- u8 sub_sys_id[2]; /* 2,3 Sub System ID */
- u8 sub_class; /* 4 Sub Class */
- u8 vendor_id[2]; /* 5,6 Vendor ID */
- u8 device_id[2]; /* 7,8 Device ID */
- u8 reserved; /* 9 Reserved */
- struct NVRamTarget target[DC395x_MAX_SCSI_ID];
- /** 10,11,12,13
- ** 14,15,16,17
- ** ....
- ** ....
- ** 70,71,72,73
- */
- u8 scsi_id; /* 74 Host Adapter SCSI ID */
- u8 channel_cfg; /* 75 Channel configuration */
- u8 delay_time; /* 76 Power on delay time */
- u8 max_tag; /* 77 Maximum tags */
- u8 reserved0; /* 78 */
- u8 boot_target; /* 79 */
- u8 boot_lun; /* 80 */
- u8 reserved1; /* 81 */
- u16 reserved2[22]; /* 82,..125 */
- u16 cksum; /* 126,127 */
-};
/*---------------------------------------------------------------------------
@@ -512,9 +514,6 @@ static void waiting_timeout(unsigned long ptr);
/*---------------------------------------------------------------------------
Static Data
---------------------------------------------------------------------------*/
-static struct AdapterCtlBlk *acb_list_head = NULL;
-static struct AdapterCtlBlk *acb_list_tail = NULL;
-static u16 adapter_count = 0;
static u16 current_sync_offset = 0;
static char monitor_next_irq = 0;
@@ -546,7 +545,6 @@ static void *dc395x_scsi_phase1[] = {
msgin_phase1, /* phase:7 */
};
-struct NvRamType eeprom_buf[DC395x_MAX_ADAPTER_NUM];
/*
*Fast20: 000 50ns, 20.0 MHz
* 001 75ns, 13.3 MHz
@@ -1611,14 +1609,12 @@ static inline void clear_fifo(struct AdapterCtlBlk *acb, char *txt)
*/
static void reset_dev_param(struct AdapterCtlBlk *acb)
{
- struct DeviceCtlBlk *dcb;
+ struct DeviceCtlBlk *dcb = acb->link_dcb;
struct DeviceCtlBlk *dcb_temp;
- struct NvRamType *eeprom;
+ struct NvRamType *eeprom = &acb->eeprom;
u8 period_index;
- u16 index;
dprintkdbg(DBG_0, "reset_dev_param..............\n");
- dcb = acb->link_dcb;
if (dcb == NULL)
return;
@@ -1627,8 +1623,6 @@ static void reset_dev_param(struct AdapterCtlBlk *acb)
dcb->sync_mode &= ~(SYNC_NEGO_DONE + WIDE_NEGO_DONE);
dcb->sync_period = 0;
dcb->sync_offset = 0;
- index = acb->adapter_index;
- eeprom = &eeprom_buf[index];
dcb->dev_mode = eeprom->target[dcb->target_id].cfg0;
/*dcb->AdpMode = eeprom->channel_cfg; */
@@ -1679,7 +1673,7 @@ static int dc395x_eh_bus_reset(Scsi_Cmnd * cmd)
/* We may be in serious trouble. Wait some seconds */
acb->scsi_host->last_reset =
jiffies + 3 * HZ / 2 +
- HZ * eeprom_buf[acb->adapter_index].delay_time;
+ HZ * acb->eeprom.delay_time;
/*
* re-enable interrupt
@@ -3832,9 +3826,7 @@ static void disconnect(struct AdapterCtlBlk *acb)
/* Suspend queue for a while */
acb->scsi_host->last_reset =
jiffies + HZ / 2 +
- HZ *
- eeprom_buf[acb->adapter_index].
- delay_time;
+ HZ * acb->eeprom.delay_time;
clear_fifo(acb, "DiscEx");
DC395x_write16(acb, TRM_S1040_SCSI_CONTROL, DO_HWRESELECT);
return;
@@ -4640,7 +4632,7 @@ static void scsi_reset_detect(struct AdapterCtlBlk *acb)
/* Maybe we locked up the bus? Then lets wait even longer ... */
acb->scsi_host->last_reset =
jiffies + 5 * HZ / 2 +
- HZ * eeprom_buf[acb->adapter_index].delay_time;
+ HZ * acb->eeprom.delay_time;
clear_fifo(acb, "RstDet");
set_basic_config(acb);
@@ -4731,9 +4723,8 @@ static
void init_dcb(struct AdapterCtlBlk *acb, struct DeviceCtlBlk **pdcb,
u8 target, u8 lun)
{
- struct NvRamType *eeprom;
+ struct NvRamType *eeprom = &acb->eeprom;
u8 period_index;
- u16 index;
struct DeviceCtlBlk *dcb;
struct DeviceCtlBlk *dcb2;
@@ -4771,8 +4762,6 @@ void init_dcb(struct AdapterCtlBlk *acb, struct DeviceCtlBlk **pdcb,
dcb->flag = 0;
dcb->max_command = 1;
/* $$$$$$$ */
- index = acb->adapter_index;
- eeprom = &eeprom_buf[index];
dcb->dev_mode = eeprom->target[target].cfg0;
/*dcb->AdpMode = eeprom->channel_cfg; */
dcb->inquiry7 = 0;
@@ -4951,13 +4940,12 @@ static void __init link_srb(struct AdapterCtlBlk *acb)
***********************************************************************
*/
static
-int __init init_acb(struct Scsi_Host *host, u32 io_port, u8 irq, u16 index)
+int __init init_acb(struct Scsi_Host *host, u32 io_port, u8 irq)
{
- struct NvRamType *eeprom;
- struct AdapterCtlBlk *acb;
+ struct AdapterCtlBlk *acb = (struct AdapterCtlBlk *)host->hostdata;
+ struct NvRamType *eeprom = &acb->eeprom;
u16 i;
- eeprom = &eeprom_buf[index];
host->max_cmd_len = 24;
host->can_queue = DC395x_MAX_CMD_QUEUE;
host->cmd_per_lun = DC395x_MAX_CMD_PER_LUN;
@@ -4969,7 +4957,6 @@ int __init init_acb(struct Scsi_Host *host, u32 io_port, u8 irq, u16 index)
host->irq = irq;
host->last_reset = jiffies;
- acb = (struct AdapterCtlBlk *) host->hostdata;
host->max_id = 16;
if (host->max_id - 1 == eeprom->scsi_id)
@@ -4991,7 +4978,6 @@ int __init init_acb(struct Scsi_Host *host, u32 io_port, u8 irq, u16 index)
acb->dcb_run_robin = NULL;
acb->active_dcb = NULL;
acb->srb_count = DC395x_MAX_SRB_CNT;
- acb->adapter_index = index;
acb->scsi_host->this_id = eeprom->scsi_id;
acb->hostid_bit = (1 << acb->scsi_host->this_id);
/*acb->scsi_host->this_lun = 0; */
@@ -5050,16 +5036,14 @@ int __init init_acb(struct Scsi_Host *host, u32 io_port, u8 irq, u16 index)
* @host: This hosts adapter strcuture
* @io_port: The base I/O port
* @irq: IRQ
- * @index: Card instance number
*
* Returns 0 if the initialization succeeds, any other value on failure.
**/
static
-int __init init_adapter(struct Scsi_Host *host, u32 io_port,
- u8 irq, u16 index)
+int __init init_adapter(struct Scsi_Host *host, u32 io_port, u8 irq)
{
- struct NvRamType *eeprom = &eeprom_buf[index];
struct AdapterCtlBlk *acb = (struct AdapterCtlBlk *)host->hostdata;
+ struct NvRamType *eeprom = &acb->eeprom;
if (!request_region(io_port, host->n_io_port, DC395X_NAME)) {
dprintkl(KERN_ERR, "Failed to reserve IO region 0x%x\n", io_port);
@@ -5106,9 +5090,7 @@ int __init init_adapter(struct Scsi_Host *host, u32 io_port,
acb->scsi_host->last_reset =
jiffies + HZ / 2 +
- HZ *
- eeprom_buf[acb->adapter_index].
- delay_time;
+ HZ * acb->eeprom.delay_time;
/*spin_lock_irq (&io_request_lock); */
}
@@ -5465,22 +5447,22 @@ void __init print_config(struct AdapterCtlBlk *acb)
* print_eeprom_settings - output the eeprom settings
* to the kernel log so people can see what they were.
*
- * @index: Adapter number
+ * @eeprom: The eeprom data strucutre to show details for.
**/
static
-void __init print_eeprom_settings(u16 index)
+void __init print_eeprom_settings(struct NvRamType *eeprom)
{
dprintkl(KERN_INFO, "Used settings: AdapterID=%02i, Speed=%i(%02i.%01iMHz), dev_mode=0x%02x\n",
- eeprom_buf[index].scsi_id,
- eeprom_buf[index].target[0].period,
- clock_speed[eeprom_buf[index].target[0].period] / 10,
- clock_speed[eeprom_buf[index].target[0].period] % 10,
- eeprom_buf[index].target[0].cfg0);
+ eeprom->scsi_id,
+ eeprom->target[0].period,
+ clock_speed[eeprom->target[0].period] / 10,
+ clock_speed[eeprom->target[0].period] % 10,
+ eeprom->target[0].cfg0);
dprintkl(KERN_INFO, " AdaptMode=0x%02x, Tags=%i(%02i), DelayReset=%is\n",
- eeprom_buf[index].channel_cfg,
- eeprom_buf[index].max_tag,
- 1 << eeprom_buf[index].max_tag,
- eeprom_buf[index].delay_time);
+ eeprom->channel_cfg,
+ eeprom->max_tag,
+ 1 << eeprom->max_tag,
+ eeprom->delay_time);
}
@@ -5497,52 +5479,37 @@ void __init print_eeprom_settings(u16 index)
*/
static
struct Scsi_Host *__init host_init(Scsi_Host_Template * host_template,
- u32 io_port, u8 irq,
- u16 index)
+ u32 io_port, u8 irq)
{
struct Scsi_Host *host;
struct AdapterCtlBlk *acb;
- /*
- * Read the eeprom contents info the buffer we supply. Use
- * defaults is eeprom checksum is wrong.
- */
- check_eeprom(&eeprom_buf[index], (u16) io_port);
-
- /*
- *$$$$$$$$$$$ MEMORY ALLOCATE FOR ADAPTER CONTROL BLOCK $$$$$$$$$$$$
- */
host = scsi_host_alloc(host_template, sizeof(struct AdapterCtlBlk));
if (!host) {
- dprintkl(KERN_INFO, "pSH scsi_host_alloc ERROR\n");
- return 0;
+ dprintkl(KERN_INFO, "scsi_host_alloc failed\n");
+ goto failed;
}
- print_eeprom_settings(index);
+ acb = (struct AdapterCtlBlk *)host->hostdata;
- acb = (struct AdapterCtlBlk *) host->hostdata;
- if (init_acb(host, io_port, irq, index)) {
- scsi_host_put(host);
- return 0;
+ check_eeprom(&acb->eeprom, (u16)io_port);
+ print_eeprom_settings(&acb->eeprom);
+
+ if (init_acb(host, io_port, irq)) {
+ goto failed;
}
print_config(acb);
- /*
- *$$$$$$$$$$$$$$$$$ INITIAL ADAPTER $$$$$$$$$$$$$$$$$
- */
- if (!init_adapter(host, io_port, irq, index)) {
- if (!acb_list_head) {
- acb_list_head = acb;
- } else {
- acb_list_tail->next_acb = acb;
- }
- acb_list_tail = acb;
- acb->next_acb = NULL;
- } else {
+ if (init_adapter(host, io_port, irq)) {
dprintkl(KERN_INFO, "DC395x_initAdapter initial ERROR\n");
- scsi_host_put(host);
- host = NULL;
+ goto failed;
}
+
return host;
+
+failed:
+ if (host)
+ scsi_host_put(host);
+ return NULL;
}
#undef SEARCH
@@ -5579,25 +5546,15 @@ struct Scsi_Host *__init host_init(Scsi_Host_Template * host_template,
else SPRINTF(" No ")
static
-int dc395x_proc_info(struct Scsi_Host *shpnt, char *buffer, char **start, off_t offset, int length,
+int dc395x_proc_info(struct Scsi_Host *host, char *buffer, char **start, off_t offset, int length,
int inout)
{
+ struct AdapterCtlBlk *acb = (struct AdapterCtlBlk *)host->hostdata;
int dev, spd, spd1;
char *pos = buffer;
- struct AdapterCtlBlk *acb;
struct DeviceCtlBlk *dcb;
unsigned long flags;
- acb = acb_list_head;
-
- while (acb) {
- if (acb->scsi_host == shpnt)
- break;
- acb = acb->next_acb;
- }
- if (!acb)
- return -ESRCH;
-
if (inout) /* Has data been written to the file ? */
return -EPERM;
@@ -5606,23 +5563,21 @@ int dc395x_proc_info(struct Scsi_Host *shpnt, char *buffer, char **start, off_t
DC395x_LOCK_IO(acb->scsi_host, flags);
- SPRINTF("SCSI Host Nr %i, ", shpnt->host_no);
- SPRINTF("DC395U/UW/F DC315/U %s Adapter Nr %i\n",
- (acb->config & HCC_WIDE_CARD) ? "Wide" : "",
- acb->adapter_index);
+ SPRINTF("SCSI Host Nr %i, ", host->host_no);
+ SPRINTF("DC395U/UW/F DC315/U %s\n",
+ (acb->config & HCC_WIDE_CARD) ? "Wide" : "");
SPRINTF("IOPortBase 0x%04x, ", acb->IOPortBase);
SPRINTF("irq_level 0x%02x, ", acb->irq_level);
SPRINTF(" SelTimeout %ims\n", (1638 * acb->sel_timeout) / 1000);
- SPRINTF("MaxID %i, MaxLUN %i, ", shpnt->max_id, shpnt->max_lun);
- SPRINTF("AdapterID %i\n", shpnt->this_id);
+ SPRINTF("MaxID %i, MaxLUN %i, ", host->max_id, host->max_lun);
+ SPRINTF("AdapterID %i\n", host->this_id);
SPRINTF("tag_max_num %i", acb->tag_max_num);
/*SPRINTF(", DMA_Status %i\n", DC395x_read8(acb, TRM_S1040_DMA_STATUS)); */
SPRINTF(", FilterCfg 0x%02x",
DC395x_read8(acb, TRM_S1040_SCSI_CONFIG1));
- SPRINTF(", DelayReset %is\n",
- eeprom_buf[acb->adapter_index].delay_time);
+ SPRINTF(", DelayReset %is\n", acb->eeprom.delay_time);
/*SPRINTF("\n"); */
SPRINTF("Nr of DCBs: %i\n", acb->dcb_count);
@@ -5852,6 +5807,7 @@ int __devinit dc395x_init_one(struct pci_dev *dev,
u8 irq;
struct Scsi_Host *scsi_host;
static int banner_done = 0;
+ int error = 0;
dprintkdbg(DBG_0, "Init one instance of the dc395x\n");
if (!banner_done)
@@ -5871,29 +5827,27 @@ int __devinit dc395x_init_one(struct pci_dev *dev,
irq = dev->irq;
dprintkdbg(DBG_0, "IO_PORT=%04x,IRQ=%x\n", (unsigned int) io_port, irq);
- scsi_host = host_init(&dc395x_driver_template, io_port, irq, adapter_count);
+ scsi_host = host_init(&dc395x_driver_template, io_port, irq);
if (!scsi_host)
{
dprintkdbg(DBG_0, "host_init failed\n");
return -ENOMEM;
}
-
- pci_set_master(dev);
-
- /* store pci devices in out host data object. */
((struct AdapterCtlBlk *)(scsi_host->hostdata))->dev = dev;
-
- /* increment adaptor count */
- adapter_count++;
-
- /* store ptr to scsi host in the PCI device structure */
+ pci_set_master(dev);
pci_set_drvdata(dev, scsi_host);
/* get the scsi mid level to scan for new devices on the bus */
- scsi_add_host(scsi_host, &dev->dev); /* XXX handle failure */
- scsi_scan_host(scsi_host);
-
- return 0;
+ error = scsi_add_host(scsi_host, &dev->dev);
+ if (error) {
+ dprintkl(KERN_ERR, "scsi_add_host failed\n");
+ error = -ENODEV;
+ host_release(scsi_host);
+ scsi_host_put(scsi_host);
+ } else
+ scsi_scan_host(scsi_host);
+
+ return error;
}
@@ -5906,9 +5860,18 @@ int __devinit dc395x_init_one(struct pci_dev *dev,
static void __devexit dc395x_remove_one(struct pci_dev *dev)
{
struct Scsi_Host *host = pci_get_drvdata(dev);
+
dprintkdbg(DBG_0, "Removing instance\n");
- scsi_remove_host(host);
+ if (!host) {
+ dprintkl(KERN_ERR, "no host allocated\n");
+ return;
+ }
+ if (scsi_remove_host(host)) {
+ dprintkl(KERN_ERR, "scsi_remove_host failed\n");
+ return;
+ }
host_release(host);
+ scsi_host_put(host);
pci_set_drvdata(dev, NULL);
}
diff --git a/drivers/scsi/dc395x.h b/drivers/scsi/dc395x.h
index ae1e57330ccb..031306f2d24f 100644
--- a/drivers/scsi/dc395x.h
+++ b/drivers/scsi/dc395x.h
@@ -28,7 +28,6 @@
#define DC395x_MAX_CMD_QUEUE 32
/* #define DC395x_MAX_QTAGS 32 */
#define DC395x_MAX_QTAGS 16
-#define DC395x_MAX_ADAPTER_NUM 4
#define DC395x_MAX_SCSI_ID 16
#define DC395x_MAX_CMD_PER_LUN DC395x_MAX_QTAGS
#define DC395x_MAX_SG_TABLESIZE 64 /* HW limitation */
diff --git a/drivers/scsi/esp.c b/drivers/scsi/esp.c
index 9b78b350a495..ee7efe46e242 100644
--- a/drivers/scsi/esp.c
+++ b/drivers/scsi/esp.c
@@ -4392,7 +4392,6 @@ static Scsi_Host_Template driver_template = {
.sg_tablesize = SG_ALL,
.cmd_per_lun = 1,
.use_clustering = ENABLE_CLUSTERING,
- .highmem_io = 1,
};
#include "scsi_module.c"
diff --git a/drivers/scsi/hosts.c b/drivers/scsi/hosts.c
index f4f69bf1e148..642c398d294a 100644
--- a/drivers/scsi/hosts.c
+++ b/drivers/scsi/hosts.c
@@ -39,30 +39,35 @@
static int scsi_host_next_hn; /* host_no for next new host */
+
/**
- * scsi_remove_host - check a scsi host for release and release
- * @shost: a pointer to a scsi host to release
- *
- * Return value:
- * 0 on Success / 1 on Failure
+ * scsi_host_cancel - cancel outstanding IO to this host
+ * @shost: pointer to struct Scsi_Host
+ * recovery: recovery requested to run.
**/
-int scsi_remove_host(struct Scsi_Host *shost)
+void scsi_host_cancel(struct Scsi_Host *shost, int recovery)
{
- struct scsi_device *sdev;
-
- /*
- * FIXME Do ref counting. We force all of the devices offline to
- * help prevent race conditions where other hosts/processors could
- * try and get in and queue a command.
- */
- list_for_each_entry(sdev, &shost->my_devices, siblings)
- sdev->online = FALSE;
+ unsigned long flags;
+
+ spin_lock_irqsave(shost->host_lock, flags);
+ set_bit(SHOST_CANCEL, &shost->shost_state);
+ spin_unlock_irqrestore(shost->host_lock, flags);
+ device_for_each_child(&shost->shost_gendev, &recovery,
+ scsi_device_cancel_cb);
+ wait_event(shost->host_wait, (!test_bit(SHOST_RECOVERY,
+ &shost->shost_state)));
+}
+/**
+ * scsi_remove_host - remove a scsi host
+ * @shost: a pointer to a scsi host to remove
+ **/
+void scsi_remove_host(struct Scsi_Host *shost)
+{
+ scsi_host_cancel(shost, 0);
scsi_proc_host_rm(shost);
scsi_forget_host(shost);
scsi_sysfs_remove_host(shost);
-
- return 0;
}
/**
@@ -108,7 +113,7 @@ void scsi_free_shost(struct Scsi_Host *shost)
shost->eh_notify = NULL;
}
- shost->hostt->present--;
+ scsi_proc_hostdir_rm(shost->hostt);
scsi_destroy_command_freelist(shost);
kfree(shost);
}
@@ -182,7 +187,6 @@ struct Scsi_Host *scsi_host_alloc(struct scsi_host_template *sht, int privsize)
shost->unchecked_isa_dma = sht->unchecked_isa_dma;
shost->use_clustering = sht->use_clustering;
shost->use_blk_tcq = sht->use_blk_tcq;
- shost->highmem_io = sht->highmem_io;
if (sht->max_host_blocked)
shost->max_host_blocked = sht->max_host_blocked;
@@ -198,6 +202,14 @@ struct Scsi_Host *scsi_host_alloc(struct scsi_host_template *sht, int privsize)
else
shost->max_sectors = SCSI_DEFAULT_MAX_SECTORS;
+ /*
+ * assume a 4GB boundary, if not set
+ */
+ if (sht->dma_boundary)
+ shost->dma_boundary = sht->dma_boundary;
+ else
+ shost->dma_boundary = 0xffffffff;
+
rval = scsi_setup_command_freelist(shost);
if (rval)
goto fail;
@@ -209,7 +221,7 @@ struct Scsi_Host *scsi_host_alloc(struct scsi_host_template *sht, int privsize)
kernel_thread((int (*)(void *))scsi_error_handler, shost, 0);
wait_for_completion(&complete);
shost->eh_notify = NULL;
- shost->hostt->present++;
+ scsi_proc_hostdir_add(shost->hostt);
return shost;
fail:
kfree(shost);
@@ -249,21 +261,21 @@ struct Scsi_Host *scsi_host_lookup(unsigned short hostnum)
{
struct class *class = class_get(&shost_class);
struct class_device *cdev;
- struct Scsi_Host *shost = NULL, *p;
+ struct Scsi_Host *shost = ERR_PTR(-ENXIO), *p;
if (class) {
down_read(&class->subsys.rwsem);
list_for_each_entry(cdev, &class->children, node) {
p = class_to_shost(cdev);
if (p->host_no == hostnum) {
- scsi_host_get(p);
- shost = p;
+ shost = scsi_host_get(p);
break;
}
}
up_read(&class->subsys.rwsem);
}
+ class_put(&shost_class);
return shost;
}
@@ -271,10 +283,12 @@ struct Scsi_Host *scsi_host_lookup(unsigned short hostnum)
* *scsi_host_get - inc a Scsi_Host ref count
* @shost: Pointer to Scsi_Host to inc.
**/
-void scsi_host_get(struct Scsi_Host *shost)
+struct Scsi_Host *scsi_host_get(struct Scsi_Host *shost)
{
- get_device(&shost->shost_gendev);
- class_device_get(&shost->shost_classdev);
+ if (test_bit(SHOST_DEL, &shost->shost_state) ||
+ !get_device(&shost->shost_gendev))
+ return NULL;
+ return shost;
}
/**
@@ -283,6 +297,5 @@ void scsi_host_get(struct Scsi_Host *shost)
**/
void scsi_host_put(struct Scsi_Host *shost)
{
- class_device_put(&shost->shost_classdev);
put_device(&shost->shost_gendev);
}
diff --git a/drivers/scsi/ips.c b/drivers/scsi/ips.c
index e6cdee3e9611..e7c504d6a53e 100644
--- a/drivers/scsi/ips.c
+++ b/drivers/scsi/ips.c
@@ -268,9 +268,6 @@ static Scsi_Host_Template ips_driver_template = {
.sg_tablesize = IPS_MAX_SG,
.cmd_per_lun = 3,
.use_clustering = ENABLE_CLUSTERING,
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,20) || (defined CONFIG_HIGHIO)
- .highmem_io = 1,
-#endif
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
.use_new_eh_code = 1,
#endif
diff --git a/drivers/scsi/megaraid.c b/drivers/scsi/megaraid.c
index 6dfaf6bacf38..de60f4f54b95 100644
--- a/drivers/scsi/megaraid.c
+++ b/drivers/scsi/megaraid.c
@@ -5361,7 +5361,6 @@ static Scsi_Host_Template driver_template = {
.eh_device_reset_handler = megaraid_reset,
.eh_bus_reset_handler = megaraid_reset,
.eh_host_reset_handler = megaraid_reset,
- .highmem_io = 1,
};
#include "scsi_module.c"
diff --git a/drivers/scsi/pcmcia/aha152x_stub.c b/drivers/scsi/pcmcia/aha152x_stub.c
index af999e9509b6..0e381b816734 100644
--- a/drivers/scsi/pcmcia/aha152x_stub.c
+++ b/drivers/scsi/pcmcia/aha152x_stub.c
@@ -40,7 +40,6 @@
#include <linux/sched.h>
#include <linux/slab.h>
#include <linux/string.h>
-#include <linux/timer.h>
#include <linux/ioport.h>
#include <scsi/scsi.h>
#include <linux/major.h>
@@ -102,7 +101,7 @@ typedef struct scsi_info_t {
struct Scsi_Host *host;
} scsi_info_t;
-static void aha152x_release_cs(u_long arg);
+static void aha152x_release_cs(dev_link_t *link);
static int aha152x_event(event_t event, int priority,
event_callback_args_t *args);
@@ -126,9 +125,6 @@ static dev_link_t *aha152x_attach(void)
if (!info) return NULL;
memset(info, 0, sizeof(*info));
link = &info->link; link->priv = info;
- init_timer(&link->release);
- link->release.function = &aha152x_release_cs;
- link->release.data = (u_long)link;
link->io.NumPorts1 = 0x20;
link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
@@ -181,9 +177,8 @@ static void aha152x_detach(dev_link_t *link)
if (*linkp == NULL)
return;
- del_timer(&link->release);
if (link->state & DEV_CONFIG) {
- aha152x_release_cs((u_long)link);
+ aha152x_release_cs(link);
if (link->state & DEV_STALE_CONFIG) {
link->state |= DEV_STALE_LINK;
return;
@@ -290,13 +285,12 @@ static void aha152x_config_cs(dev_link_t *link)
cs_failed:
cs_error(link->handle, last_fn, last_ret);
- aha152x_release_cs((u_long)link);
+ aha152x_release_cs(link);
return;
}
-static void aha152x_release_cs(u_long arg)
+static void aha152x_release_cs(dev_link_t *link)
{
- dev_link_t *link = (dev_link_t *)arg;
scsi_info_t *info = link->priv;
scsi_remove_host(info->host);
@@ -325,7 +319,7 @@ static int aha152x_event(event_t event, int priority,
case CS_EVENT_CARD_REMOVAL:
link->state &= ~DEV_PRESENT;
if (link->state & DEV_CONFIG)
- mod_timer(&link->release, jiffies + HZ/20);
+ aha152x_release_cs(link);
break;
case CS_EVENT_CARD_INSERTION:
link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
diff --git a/drivers/scsi/pcmcia/fdomain_stub.c b/drivers/scsi/pcmcia/fdomain_stub.c
index e91187dca450..09ef39d759e7 100644
--- a/drivers/scsi/pcmcia/fdomain_stub.c
+++ b/drivers/scsi/pcmcia/fdomain_stub.c
@@ -37,7 +37,6 @@
#include <linux/sched.h>
#include <linux/slab.h>
#include <linux/string.h>
-#include <linux/timer.h>
#include <linux/ioport.h>
#include <scsi/scsi.h>
#include <linux/major.h>
@@ -90,7 +89,7 @@ extern void fdomain_setup(char *str, int *ints);
extern struct Scsi_Host *__fdomain_16x0_detect( Scsi_Host_Template *tpnt );
extern int fdomain_16x0_bus_reset(Scsi_Cmnd *SCpnt);
-static void fdomain_release(u_long arg);
+static void fdomain_release(dev_link_t *link);
static int fdomain_event(event_t event, int priority,
event_callback_args_t *args);
@@ -116,10 +115,6 @@ static dev_link_t *fdomain_attach(void)
if (!info) return NULL;
memset(info, 0, sizeof(*info));
link = &info->link; link->priv = info;
- init_timer(&link->release);
- link->release.function = &fdomain_release;
- link->release.data = (u_long)link;
-
link->io.NumPorts1 = 0x10;
link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
link->io.IOAddrLines = 10;
@@ -171,9 +166,8 @@ static void fdomain_detach(dev_link_t *link)
if (*linkp == NULL)
return;
- del_timer(&link->release);
if (link->state & DEV_CONFIG) {
- fdomain_release((u_long)link);
+ fdomain_release(link);
if (link->state & DEV_STALE_CONFIG) {
link->state |= DEV_STALE_LINK;
return;
@@ -266,16 +260,15 @@ static void fdomain_config(dev_link_t *link)
cs_failed:
cs_error(link->handle, last_fn, last_ret);
- fdomain_release((u_long)link);
+ fdomain_release(link);
return;
} /* fdomain_config */
/*====================================================================*/
-static void fdomain_release(u_long arg)
+static void fdomain_release(dev_link_t *link)
{
- dev_link_t *link = (dev_link_t *)arg;
scsi_info_t *info = link->priv;
DEBUG(0, "fdomain_release(0x%p)\n", link);
@@ -307,7 +300,7 @@ static int fdomain_event(event_t event, int priority,
case CS_EVENT_CARD_REMOVAL:
link->state &= ~DEV_PRESENT;
if (link->state & DEV_CONFIG)
- mod_timer(&link->release, jiffies + HZ/20);
+ fdomain_release(link);
break;
case CS_EVENT_CARD_INSERTION:
link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
diff --git a/drivers/scsi/pcmcia/nsp_cs.c b/drivers/scsi/pcmcia/nsp_cs.c
index 5165af63b6b5..01c56a591d9e 100644
--- a/drivers/scsi/pcmcia/nsp_cs.c
+++ b/drivers/scsi/pcmcia/nsp_cs.c
@@ -38,7 +38,6 @@
#include <linux/sched.h>
#include <linux/slab.h>
#include <linux/string.h>
-#include <linux/timer.h>
#include <linux/ioport.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
@@ -1477,10 +1476,6 @@ static dev_link_t *nsp_cs_attach(void)
link = &info->link;
link->priv = info;
- /* Initialize the dev_link_t structure */
- link->release.function = &nsp_cs_release;
- link->release.data = (u_long)link;
-
/* The io structure describes IO port mapping */
link->io.NumPorts1 = 0x10;
link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
@@ -1558,9 +1553,8 @@ static void nsp_cs_detach(dev_link_t *link)
return;
}
- del_timer(&link->release);
if (link->state & DEV_CONFIG) {
- nsp_cs_release((u_long)link);
+ nsp_cs_release(link);
if (link->state & DEV_STALE_CONFIG) {
link->state |= DEV_STALE_LINK;
return;
@@ -1780,7 +1774,7 @@ static void nsp_cs_config(dev_link_t *link)
cs_failed:
cs_error(link->handle, last_fn, last_ret);
- nsp_cs_release((u_long)link);
+ nsp_cs_release(link);
return;
} /* nsp_cs_config */
@@ -1792,9 +1786,8 @@ cs_failed:
device, and release the PCMCIA configuration. If the device is
still open, this will be postponed until it is closed.
======================================================================*/
-static void nsp_cs_release(u_long arg)
+static void nsp_cs_release(dev_link_t *link)
{
- dev_link_t *link = (dev_link_t *)arg;
scsi_info_t *info = link->priv;
DEBUG(0, "%s(0x%p)\n", __FUNCTION__, link);
@@ -1866,7 +1859,7 @@ static int nsp_cs_event(event_t event,
link->state &= ~DEV_PRESENT;
if (link->state & DEV_CONFIG) {
((scsi_info_t *)link->priv)->stop = 1;
- mod_timer(&link->release, jiffies + HZ/20);
+ nsp_cs_release(link);
}
break;
@@ -1933,7 +1926,7 @@ static void __exit nsp_cs_exit(void)
/* XXX: this really needs to move into generic code.. */
while (dev_list != NULL) {
if (dev_list->state & DEV_CONFIG) {
- nsp_cs_release((u_long)dev_list);
+ nsp_cs_release(dev_list);
}
nsp_cs_detach(dev_list);
}
diff --git a/drivers/scsi/pcmcia/nsp_cs.h b/drivers/scsi/pcmcia/nsp_cs.h
index af862b66840c..905e799e91fc 100644
--- a/drivers/scsi/pcmcia/nsp_cs.h
+++ b/drivers/scsi/pcmcia/nsp_cs.h
@@ -272,7 +272,7 @@ typedef struct _nsp_hw_data {
-static void nsp_cs_release(u_long arg);
+static void nsp_cs_release(dev_link_t *link);
static int nsp_cs_event(event_t event, int priority, event_callback_args_t *args);
static dev_link_t *nsp_cs_attach(void);
static void nsp_cs_detach(dev_link_t *);
diff --git a/drivers/scsi/pcmcia/qlogic_stub.c b/drivers/scsi/pcmcia/qlogic_stub.c
index 503a5fd05d96..8cee766334ec 100644
--- a/drivers/scsi/pcmcia/qlogic_stub.c
+++ b/drivers/scsi/pcmcia/qlogic_stub.c
@@ -37,7 +37,6 @@
#include <linux/sched.h>
#include <linux/slab.h>
#include <linux/string.h>
-#include <linux/timer.h>
#include <linux/ioport.h>
#include <asm/io.h>
#include <scsi/scsi.h>
@@ -90,7 +89,7 @@ typedef struct scsi_info_t {
unsigned short manf_id;
} scsi_info_t;
-static void qlogic_release(u_long arg);
+static void qlogic_release(dev_link_t *link);
static int qlogic_event(event_t event, int priority, event_callback_args_t * args);
static dev_link_t *qlogic_attach(void);
@@ -117,10 +116,6 @@ static dev_link_t *qlogic_attach(void)
memset(info, 0, sizeof(*info));
link = &info->link;
link->priv = info;
- init_timer(&link->release);
- link->release.function = &qlogic_release;
- link->release.data = (u_long) link;
-
link->io.NumPorts1 = 16;
link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
link->io.IOAddrLines = 10;
@@ -170,9 +165,8 @@ static void qlogic_detach(dev_link_t * link)
if (*linkp == NULL)
return;
- del_timer_sync(&link->release);
if (link->state & DEV_CONFIG) {
- qlogic_release((u_long) link);
+ qlogic_release(link);
if (link->state & DEV_STALE_CONFIG) {
link->state |= DEV_STALE_LINK;
return;
@@ -279,16 +273,15 @@ out:
cs_failed:
cs_error(link->handle, last_fn, last_ret);
- qlogic_release((u_long) link);
+ qlogic_release(link);
return;
} /* qlogic_config */
/*====================================================================*/
-static void qlogic_release(u_long arg)
+static void qlogic_release(dev_link_t *link)
{
- dev_link_t *link = (dev_link_t *) arg;
scsi_info_t *info = link->priv;
DEBUG(0, "qlogic_release(0x%p)\n", link);
@@ -319,7 +312,7 @@ static int qlogic_event(event_t event, int priority, event_callback_args_t * arg
case CS_EVENT_CARD_REMOVAL:
link->state &= ~DEV_PRESENT;
if (link->state & DEV_CONFIG)
- mod_timer(&link->release, jiffies + HZ / 20);
+ qlogic_release(link);
break;
case CS_EVENT_CARD_INSERTION:
link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
diff --git a/drivers/scsi/qla1280.c b/drivers/scsi/qla1280.c
index 25e031649be9..72ca360a950a 100644
--- a/drivers/scsi/qla1280.c
+++ b/drivers/scsi/qla1280.c
@@ -3,7 +3,7 @@
*
* QLogic QLA1280 (Ultra2) and QLA12160 (Ultra3) SCSI driver
* Copyright (C) 2000 Qlogic Corporation (www.qlogic.com)
-* Copyright (C) 2001-2002 Jes Sorensen, Wild Open Source Inc.
+* Copyright (C) 2001-2003 Jes Sorensen, Wild Open Source Inc.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
@@ -16,9 +16,52 @@
* General Public License for more details.
*
******************************************************************************/
-#define QLA1280_VERSION "3.23.19 Beta"
-/******************************************************************************
+#define QLA1280_VERSION "3.23.34"
+/*****************************************************************************
Revision History:
+ Rev 3.23.34 July 23, 2003, Jes Sorensen
+ - Remove pointless TRUE/FALSE macros
+ - Clean up vchan handling
+ Rev 3.23.33 July 3, 2003, Jes Sorensen
+ - Don't define register access macros before define determining MMIO.
+ This just happend to work out on ia64 but not elsewhere.
+ - Don't try and read from the card while it is in reset as
+ it won't respond and causes an MCA
+ Rev 3.23.32 June 23, 2003, Jes Sorensen
+ - Basic support for boot time arguments
+ Rev 3.23.31 June 8, 2003, Jes Sorensen
+ - Reduce boot time messages
+ Rev 3.23.30 June 6, 2003, Jes Sorensen
+ - Do not enable sync/wide/ppr before it has been determined
+ that the target device actually supports it
+ - Enable DMA arbitration for multi channel controllers
+ Rev 3.23.29 June 3, 2003, Jes Sorensen
+ - Port to 2.5.69
+ Rev 3.23.28 June 3, 2003, Jes Sorensen
+ - Eliminate duplicate marker commands on bus resets
+ - Handle outstanding commands appropriately on bus/device resets
+ Rev 3.23.27 May 28, 2003, Jes Sorensen
+ - Remove bogus input queue code, let the Linux SCSI layer do the work
+ - Clean up NVRAM handling, only read it once from the card
+ - Add a number of missing default nvram parameters
+ Rev 3.23.26 Beta May 28, 2003, Jes Sorensen
+ - Use completion queue for mailbox commands instead of busy wait
+ Rev 3.23.25 Beta May 27, 2003, James Bottomley
+ - Migrate to use new error handling code
+ Rev 3.23.24 Beta May 21, 2003, James Bottomley
+ - Big endian support
+ - Cleanup data direction code
+ Rev 3.23.23 Beta May 12, 2003, Jes Sorensen
+ - Switch to using MMIO instead of PIO
+ Rev 3.23.22 Beta April 15, 2003, Jes Sorensen
+ - Fix PCI parity problem with 12160 during reset.
+ Rev 3.23.21 Beta April 14, 2003, Jes Sorensen
+ - Use pci_map_page()/pci_unmap_page() instead of map_single version.
+ Rev 3.23.20 Beta April 9, 2003, Jes Sorensen
+ - Remove < 2.4.x support
+ - Introduce HOST_LOCK to make the spin lock changes portable.
+ - Remove a bunch of idiotic and unnecessary typedef's
+ - Kill all leftovers of target-mode support which never worked anyway
Rev 3.23.19 Beta April 11, 2002, Linus Torvalds
- Do qla1280_pci_config() before calling request_irq() and
request_region()
@@ -107,8 +150,8 @@
- Provide compat macros for pci_enable_device(), pci_find_subsys()
and scsi_set_pci_device()
- Call scsi_set_pci_device() for all devices
- - Reduce size of kernel version dependent device probe code
- - Move duplicate probe/init code to separate function
+ - Reduce size of kernel version dependant device probe code
+ - Move duplicate probe/init code to seperate function
- Handle error if qla1280_mem_alloc() fails
- Kill OFFSET() macro and use Linux's PCI definitions instead
- Kill private structure defining PCI config space (struct config_reg)
@@ -131,14 +174,14 @@
- Added check of device_id when handling non
QLA12160s during detect().
Rev 3.22 Beta January 5, 2001 BN Qlogic
- - Changed queue_task() to schedule_work()
+ - Changed queue_task() to schedule_task()
for kernels 2.4.0 and higher.
Note: 2.4.0-testxx kernels released prior to
the actual 2.4.0 kernel release on January 2001
- will get compile/link errors with schedule_work().
+ will get compile/link errors with schedule_task().
Please update your kernel to released 2.4.0 level,
or comment lines in this file flagged with 3.22
- to resolve compile/link error of schedule_work().
+ to resolve compile/link error of schedule_task().
- Added -DCONFIG_SMP in addition to -D__SMP__
in Makefile for 2.4.0 builds of driver as module.
Rev 3.21 Beta January 4, 2001 BN Qlogic
@@ -238,6 +281,7 @@
- Initial Beta Release.
*****************************************************************************/
+
#include <linux/config.h>
#include <linux/module.h>
@@ -246,56 +290,54 @@
#include <linux/string.h>
#include <linux/errno.h>
#include <linux/kernel.h>
-#include <linux/interrupt.h>
#include <linux/ioport.h>
#include <linux/delay.h>
#include <linux/timer.h>
+#include <linux/sched.h>
#include <linux/pci.h>
#include <linux/proc_fs.h>
-#include <linux/blkdev.h>
-#include <linux/workqueue.h>
+#include <linux/blk.h>
#include <linux/stat.h>
#include <linux/slab.h>
+#include <linux/pci_ids.h>
+#include <linux/interrupt.h>
+#include <linux/init.h>
+
#include <asm/io.h>
#include <asm/irq.h>
#include <asm/byteorder.h>
#include <asm/processor.h>
+#include <asm/types.h>
+#include <asm/system.h>
-#ifndef KERNEL_VERSION
-#define KERNEL_VERSION(x,y,z) (((x)<<16)+((y)<<8)+(z))
+#if LINUX_VERSION_CODE < 0x020545
+#include "sd.h"
#endif
+#include "scsi.h"
+#include "hosts.h"
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,3,18)
-#include <linux/pci_ids.h>
+#if LINUX_VERSION_CODE < 0x020407
+#error "Kernels older than 2.4.7 are no longer supported"
#endif
-#include "scsi.h"
-#include "hosts.h"
-#define UNIQUE_FW_NAME
-#include "qla1280.h"
-#include "ql12160_fw.h" /* ISP RISC codes */
-#include "ql1280_fw.h"
/*
* Compile time Options:
* 0 - Disable and 1 - Enable
*/
-#define QL1280_TARGET_MODE_SUPPORT 0 /* Target mode support */
-#define QL1280_LUN_SUPPORT 0
-#define WATCHDOGTIMER 0
-#define MEMORY_MAPPED_IO 0
-#define DEBUG_QLA1280_INTR 0
-#define USE_NVRAM_DEFAULTS 0
-#define DEBUG_PRINT_NVRAM 0
-#define LOADING_RISC_ACTIVITY 0
-#define AUTO_ESCALATE_RESET 0 /* Automatically escalate resets */
-#define AUTO_ESCALATE_ABORT 0 /* Automatically escalate aborts */
-#define STOP_ON_ERROR 0 /* Stop on aborts and resets */
-#define STOP_ON_RESET 0
-#define STOP_ON_ABORT 0
-#define QLA1280_PROFILE 1 /* 3.20 */
-#define DEBUG_QLA1280 0
+#define QL1280_LUN_SUPPORT 0
+#define WATCHDOGTIMER 0
+#define MEMORY_MAPPED_IO 1
+#define DEBUG_QLA1280_INTR 0
+#define DEBUG_PRINT_NVRAM 0
+#define DEBUG_QLA1280 0
+
+#define UNIQUE_FW_NAME
+#include "qla1280.h"
+#include "ql12160_fw.h" /* ISP RISC codes */
+#include "ql1280_fw.h"
+
/*
* Missing PCI ID's
@@ -320,97 +362,65 @@
#define PCI_VENDOR_ID_AMI 0x101e
#endif
+#ifndef BITS_PER_LONG
+#error "BITS_PER_LONG not defined!"
+#endif
#if (BITS_PER_LONG == 64) || defined CONFIG_HIGHMEM
#define QLA_64BIT_PTR 1
#endif
-/* 3.16 */
-#ifdef QLA_64BIT_PTR
-#define pci_dma_lo32(a) (a & 0xffffffff)
-#define pci_dma_hi32(a) ((a >> 16)>>16)
-#else
-#define pci_dma_lo32(a) (a & 0xffffffff)
-#define pci_dma_hi32(a) 0
+#if defined(CONFIG_IA64_GENERIC) || defined(CONFIG_IA64_SGI_SN2)
+#include <asm/sn/pci/pciio.h>
+/* Ugly hack needed for the virtual channel fix on SN2 */
+extern int snia_pcibr_rrb_alloc(struct pci_dev *pci_dev,
+ int *count_vchan0, int *count_vchan1);
#endif
-/* MACROS for managing the endian addresses */
-static inline uint16_t qla1280_addr0_15(dma_addr_t dma)
-{
- return ((uint16_t)(dma & 0xffff));
-}
-static inline uint16_t qla1280_addr16_31(dma_addr_t dma)
-{
- return ((uint16_t)((dma >> 16) & 0xffff));
-}
-static inline uint16_t qla1280_addr32_47(dma_addr_t dma)
-{
- return ((uint16_t)(pci_dma_hi32(dma) & 0xffff));
-}
-static inline uint16_t qla1280_addr48_63(dma_addr_t dma)
-{
- return ((uint16_t)((pci_dma_hi32(dma) >> 16) & 0xffff));
-}
-
-#define NVRAM_DELAY() udelay(500) /* 2 microsecond delay */
-#define CACHE_FLUSH(a) RD_REG_WORD(a)
-#define INVALID_HANDLE (MAX_OUTSTANDING_COMMANDS + 1)
-
-/*
- * Compat macros
- */
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 0)
-#define pci_set_dma_mask(dev, mask) dev->dma_mask = mask;
-#define pci_enable_device(pdev) 0
-#define pci_find_subsys(id, dev, sid, sdev, pdev) pci_find_device(id,dev,pdev)
-#define scsi_set_pci_device(host, pdev)
+#ifdef QLA_64BIT_PTR
+#define pci_dma_hi32(a) ((a >> 16) >> 16)
+#else
+#define pci_dma_hi32(a) 0
#endif
+#define pci_dma_lo32(a) (a & 0xffffffff)
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,18)
-typedef unsigned long dma_addr_t;
+#define NVRAM_DELAY() udelay(500) /* 2 microseconds */
-static inline void *
-pci_alloc_consistent(struct pci_dev *hwdev, size_t size,
- dma_addr_t * dma_handle)
+#if LINUX_VERSION_CODE < 0x020500
+#define HOST_LOCK &io_request_lock
+#define irqreturn_t void
+#define IRQ_RETVAL(foo)
+#define MSG_ORDERED_TAG 1
+static inline void
+scsi_adjust_queue_depth(Scsi_Device *device, int tag, int depth)
{
- void *virt_ptr;
-
- virt_ptr = kmalloc(size, GFP_KERNEL);
- if (!virt_ptr)
- return NULL;
- *dma_handle = virt_to_bus(virt_ptr);
- return virt_ptr;
+ if (tag) {
+ device->tagged_queue = tag;
+ device->current_tag = 0;
+ }
+ device->queue_depth = depth;
}
-
-#define pci_free_consistent(cookie, size, ptr, dma_ptr) kfree(ptr)
-#define pci_map_single(cookie, address, size, dir) virt_to_bus(address)
-#define pci_map_sg(cookie, scatter, ents, dir) ents
-#define pci_unmap_single(cookie, address, size, dir)
-#define pci_unmap_sg(cookie, scatter, ents, dir)
-
-#define pci_resource_start(dev, i) dev->base_address[i]
+#else
+#define HOST_LOCK ha->host->host_lock
+#endif
+#if defined(__ia64__) && !defined(ia64_platform_is)
+#define ia64_platform_is(foo) (!strcmp(x, platform_name))
#endif
/*
* QLogic Driver Support Function Prototypes.
*/
-static void qla1280_done(struct scsi_qla_host *, srb_t **, srb_t **);
-static void qla1280_next(struct scsi_qla_host *, scsi_lu_t *, int);
-static void qla1280_putq_t(scsi_lu_t *, srb_t *);
-static void qla1280_done_q_put(srb_t *, srb_t **, srb_t **);
+static void qla1280_done(struct scsi_qla_host *, struct srb **, struct srb **);
+static void qla1280_done_q_put(struct srb *, struct srb **, struct srb **);
static int qla1280_slave_configure(Scsi_Device *);
-#if STOP_ON_ERROR
-static void qla1280_panic(char *, struct Scsi_Host *host);
+#if LINUX_VERSION_CODE < 0x020545
+static void qla1280_select_queue_depth(struct Scsi_Host *, Scsi_Device *);
+void qla1280_get_target_options(struct scsi_cmnd *, struct scsi_qla_host *);
#endif
-static void qla1280_abort_queue_single(struct scsi_qla_host *, int, int,
- int, uint32_t);
-static int qla1280_return_status(sts_entry_t * sts, Scsi_Cmnd * cp);
-static void qla1280_removeq(scsi_lu_t * q, srb_t * sp);
+static int qla1280_return_status(struct response * sts, Scsi_Cmnd * cp);
static void qla1280_mem_free(struct scsi_qla_host *ha);
void qla1280_do_dpc(void *p);
-#ifdef MODULE
-static char *qla1280_get_token(char *, char *);
-#endif
+static int qla1280_get_token(char *);
static inline void qla1280_enable_intrs(struct scsi_qla_host *);
static inline void qla1280_disable_intrs(struct scsi_qla_host *);
@@ -418,7 +428,6 @@ static inline void qla1280_disable_intrs(struct scsi_qla_host *);
* QLogic ISP1280 Hardware Support Function Prototypes.
*/
static int qla1280_initialize_adapter(struct scsi_qla_host *ha);
-static int qla1280_enable_tgt(struct scsi_qla_host *, int);
static int qla1280_isp_firmware(struct scsi_qla_host *);
static int qla1280_pci_config(struct scsi_qla_host *);
static int qla1280_chip_diag(struct scsi_qla_host *);
@@ -430,23 +439,22 @@ static int qla1280_mailbox_command(struct scsi_qla_host *,
static int qla1280_bus_reset(struct scsi_qla_host *, int);
static int qla1280_device_reset(struct scsi_qla_host *, int, int);
static int qla1280_abort_device(struct scsi_qla_host *, int, int, int);
-static int qla1280_abort_command(struct scsi_qla_host *, srb_t *);
+static int qla1280_abort_command(struct scsi_qla_host *, struct srb *, int);
static int qla1280_abort_isp(struct scsi_qla_host *);
-static int qla1280_64bit_start_scsi(struct scsi_qla_host *, srb_t *);
-static int qla1280_32bit_start_scsi(struct scsi_qla_host *, srb_t *);
+static int qla1280_64bit_start_scsi(struct scsi_qla_host *, struct srb *);
+static int qla1280_32bit_start_scsi(struct scsi_qla_host *, struct srb *);
static void qla1280_nv_write(struct scsi_qla_host *, uint16_t);
static void qla1280_poll(struct scsi_qla_host *);
static void qla1280_reset_adapter(struct scsi_qla_host *);
static void qla1280_marker(struct scsi_qla_host *, int, int, int, u8);
static void qla1280_isp_cmd(struct scsi_qla_host *);
-static void qla1280_isr(struct scsi_qla_host *, srb_t **, srb_t **);
+irqreturn_t qla1280_intr_handler(int, void *, struct pt_regs *);
+static void qla1280_isr(struct scsi_qla_host *, struct srb **, struct srb **);
static void qla1280_rst_aen(struct scsi_qla_host *);
-static void qla1280_status_entry(struct scsi_qla_host *, sts_entry_t *,
- srb_t **, srb_t **);
-static void qla1280_error_entry(struct scsi_qla_host *, response_t *,
- srb_t **, srb_t **);
-static void qla1280_restart_queues(struct scsi_qla_host *);
-static void qla1280_abort_queues(struct scsi_qla_host *);
+static void qla1280_status_entry(struct scsi_qla_host *, struct response *,
+ struct srb **, struct srb **);
+static void qla1280_error_entry(struct scsi_qla_host *, struct response *,
+ struct srb **, struct srb **);
static uint16_t qla1280_get_nvram_word(struct scsi_qla_host *, uint32_t);
static uint16_t qla1280_nvram_request(struct scsi_qla_host *, uint32_t);
static uint16_t qla1280_debounce_register(volatile uint16_t *);
@@ -456,9 +464,14 @@ static int qla1280_check_for_dead_scsi_bus(struct scsi_qla_host *,
static int qla1280_mem_alloc(struct scsi_qla_host *ha);
static void qla12160_get_target_parameters(struct scsi_qla_host *,
- uint32_t, uint32_t, uint32_t);
+ Scsi_Device *);
+static int qla12160_set_target_parameters(struct scsi_qla_host *, int, int);
+
-/* convert scsi data direction to request_t control flags
+static struct qla_driver_setup driver_setup __initdata;
+
+/*
+ * convert scsi data direction to request_t control flags
*/
static inline uint16_t
qla1280_data_direction(struct scsi_cmnd *cmnd)
@@ -491,58 +504,26 @@ qla1280_data_direction(struct scsi_cmnd *cmnd)
static void qla1280_enable_lun(struct scsi_qla_host *, int, int);
#endif
-#if QL1280_TARGET_MODE_SUPPORT
-static void qla1280_notify_ack(struct scsi_qla_host *, notify_entry_t *);
-static void qla1280_immed_notify(struct scsi_qla_host *, notify_entry_t *);
-static void qla1280_accept_io(struct scsi_qla_host *, ctio_ret_entry_t *);
-static void qla1280_64bit_continue_io(struct scsi_qla_host *, atio_entry_t *,
- uint32_t, paddr32_t *);
-static void qla1280_32bit_continue_io(struct scsi_qla_host *, atio_entry_t *,
- uint32_t, paddr32_t *);
-static void qla1280_atio_entry(struct scsi_qla_host *, atio_entry_t *);
-static void qla1280_notify_entry(struct scsi_qla_host *, notify_entry_t *);
-#endif /* QLA1280_TARGET_MODE_SUPPORT */
-
-#ifdef QL_DEBUG_ROUTINES
-/*
- * Driver Debug Function Prototypes.
- */
-static u8 qla1280_getbyte(u8 *);
-static u16 qla1280_getword(u16 *);
-static u32 qla1280_getdword(u32 *);
-static void qla1280_putbyte(u8 *, u8);
-static void qla1280_putword(u16 *, u8);
-static void qla1280_putdword(u32 *, u32);
+#if DEBUG_QLA1280
static void __qla1280_print_scsi_cmd(Scsi_Cmnd * cmd);
-static void __qla1280_dump_buffer(char *, u32);
+static void __qla1280_dump_buffer(char *, int);
#endif
+
/*
* insmod needs to find the variable and make it point to something
*/
#ifdef MODULE
-static char *options = NULL;
+static char *qla1280;
/* insmod qla1280 options=verbose" */
-MODULE_PARM(options, "s");
+MODULE_PARM(qla1280, "s");
+#else
+__setup("qla1280=", qla1280_setup);
#endif
MODULE_LICENSE("GPL");
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,18)
-/*
- * Our directory Entry in /proc/scsi for the user to
- * access the driver.
- */
-/* Need to add in proc_fs.h PROC_SCSI_QL1280 */
-#define PROC_SCSI_QL1280 PROC_SCSI_QLOGICISP
-
-struct proc_dir_entry proc_scsi_qla1280 = {
- PROC_SCSI_QL1280, 7, "qla1280",
- S_IFDIR | S_IRUGO | S_IXUGO, 2,
- 0, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL
-};
-#endif
/* We use the Scsi_Pointer structure that's included with each command
* SCSI_Cmnd as a scratchpad for our SRB.
@@ -565,6 +546,19 @@ struct proc_dir_entry proc_scsi_qla1280 = {
#define CMD_SNSLEN(Cmnd) sizeof(Cmnd->sense_buffer)
#define CMD_RESULT(Cmnd) Cmnd->result
#define CMD_HANDLE(Cmnd) Cmnd->host_scribble
+#if LINUX_VERSION_CODE < 0x020545
+#define CMD_HOST(Cmnd) Cmnd->host
+#define CMD_REQUEST(Cmnd) Cmnd->request.cmd
+#define SCSI_BUS_32(Cmnd) Cmnd->channel
+#define SCSI_TCN_32(Cmnd) Cmnd->target
+#define SCSI_LUN_32(Cmnd) Cmnd->lun
+#else
+#define CMD_HOST(Cmnd) Cmnd->device->host
+#define CMD_REQUEST(Cmnd) Cmnd->request->cmd
+#define SCSI_BUS_32(Cmnd) Cmnd->device->channel
+#define SCSI_TCN_32(Cmnd) Cmnd->device->id
+#define SCSI_LUN_32(Cmnd) Cmnd->device->lun
+#endif
/*****************************************/
/* ISP Boards supported by this driver */
@@ -573,7 +567,7 @@ struct proc_dir_entry proc_scsi_qla1280 = {
#define NUM_OF_ISP_DEVICES 6
struct qla_boards {
- unsigned char bdName[9]; /* Board ID String */
+ unsigned char name[9]; /* Board ID String */
unsigned long device_id; /* Device PCI ID */
int numPorts; /* Number of SCSI ports */
unsigned short *fwcode; /* pointer to FW array */
@@ -584,44 +578,38 @@ struct qla_boards {
struct qla_boards ql1280_board_tbl[NUM_OF_ISP_DEVICES] = {
/* Name , Board PCI Device ID, Number of ports */
- {"QLA12160 ", PCI_DEVICE_ID_QLOGIC_ISP12160, 2,
+ {"QLA12160", PCI_DEVICE_ID_QLOGIC_ISP12160, 2,
&fw12160i_code01[0], &fw12160i_length01,
&fw12160i_addr01, &fw12160i_version_str[0]},
- {"QLA1080 ", PCI_DEVICE_ID_QLOGIC_ISP1080, 1,
+ {"QLA1080", PCI_DEVICE_ID_QLOGIC_ISP1080, 1,
&fw1280ei_code01[0], &fw1280ei_length01,
&fw1280ei_addr01, &fw1280ei_version_str[0]},
- {"QLA1240 ", PCI_DEVICE_ID_QLOGIC_ISP1240, 2,
+ {"QLA1240", PCI_DEVICE_ID_QLOGIC_ISP1240, 2,
&fw1280ei_code01[0], &fw1280ei_length01,
&fw1280ei_addr01, &fw1280ei_version_str[0]},
- {"QLA1280 ", PCI_DEVICE_ID_QLOGIC_ISP1280, 2,
+ {"QLA1280", PCI_DEVICE_ID_QLOGIC_ISP1280, 2,
&fw1280ei_code01[0], &fw1280ei_length01,
&fw1280ei_addr01, &fw1280ei_version_str[0]},
- {"QLA10160 ", PCI_DEVICE_ID_QLOGIC_ISP10160, 1,
+ {"QLA10160", PCI_DEVICE_ID_QLOGIC_ISP10160, 1,
&fw12160i_code01[0], &fw12160i_length01,
&fw12160i_addr01, &fw12160i_version_str[0]},
{" ", 0, 0}
};
static int qla1280_verbose = 1;
-static struct scsi_qla_host *qla1280_hostlist = NULL;
-#if QLA1280_PROFILE
-static int qla1280_buffer_size = 0;
-static char *qla1280_buffer = NULL;
-#endif
+static struct scsi_qla_host *qla1280_hostlist;
+static int qla1280_buffer_size;
+static char *qla1280_buffer;
#if DEBUG_QLA1280
-static int ql_debug_print = 1;
-char debug_buff[80];
-#define DEBUG(x) x
-static int ql_debug_level = 0;
+static int ql_debug_level = 1;
#define dprintk(level, format, a...) \
- if ((ql_debug_level >= level) && ql_debug_print) printk(KERN_DEBUG format, ##a)
+ do { if (ql_debug_level >= level) printk(KERN_ERR format, ##a); } while(0)
#define qla1280_dump_buffer(level, buf, size) \
if (ql_debug_level >= level) __qla1280_dump_buffer(buf, size)
-#define qla1280_dump_print_cmd(level, cmd) \
+#define qla1280_print_scsi_cmd(level, cmd) \
if (ql_debug_level >= level) __qla1280_print_scsi_cmd(cmd)
#else
-#define DEBUG(x)
#define ql_debug_level 0
#define dprintk(level, format, a...) do{}while(0)
#define qla1280_dump_buffer(a, b, c) do{}while(0)
@@ -630,30 +618,9 @@ static int ql_debug_level = 0;
#define ENTER(x) dprintk(3, "qla1280 : Entering %s()\n", x);
#define LEAVE(x) dprintk(3, "qla1280 : Leaving %s()\n", x);
-#define ENTER_INTR(x) dprintk(3, "qla1280 : Entering %s()\n", x);
-#define LEAVE_INTR(x) dprintk(3, "qla1280 : Leaving %s()\n", x);
-
-#define SCSI_BUS_32(scp) scp->device->channel
-#define SCSI_TCN_32(scp) scp->device->id
-#define SCSI_LUN_32(scp) scp->device->lun
-
-/****************************************************************************/
-/* LINUX - Loadable Module Functions. */
-/****************************************************************************/
+#define ENTER_INTR(x) dprintk(4, "qla1280 : Entering %s()\n", x);
+#define LEAVE_INTR(x) dprintk(4, "qla1280 : Leaving %s()\n", x);
-/*************************************************************************
- * qla1280_set_info
- *
- * Description:
- * Set parameters for the driver from the /proc filesystem.
- *
- * Returns:
- *************************************************************************/
-int
-qla1280_set_info(char *buffer, int length, struct Scsi_Host *HBAptr)
-{
- return -ENOSYS; /* Currently this is a no-op */
-}
/*************************************************************************
* qla1280_proc_info
@@ -668,28 +635,39 @@ qla1280_set_info(char *buffer, int length, struct Scsi_Host *HBAptr)
#define PROC_BUF &qla1280_buffer[len]
int
-qla1280_proc_info(struct Scsi_Host *host, char *buffer, char **start, off_t offset, int length,
- int inout)
+qla1280_proc_info(char *buffer, char **start, off_t offset, int length,
+ int hostno, int inout)
{
-#if QLA1280_PROFILE
+ struct Scsi_Host *host;
struct scsi_qla_host *ha;
int size = 0;
- scsi_lu_t *up;
int len = 0;
struct qla_boards *bdp;
+#ifdef BOGUS_QUEUE
+ struct scsi_lu *up;
uint32_t b, t, l;
- host = NULL;
+#endif
/* Find the host that was specified */
- for (ha = qla1280_hostlist; (ha != NULL) && ha->host != host;
- ha = ha->next) ;
-
- if (inout == TRUE) { /* Has data been written to the file? */
- printk(KERN_INFO
- "qla1280_proc: has data been written to the file.\n");
- return qla1280_set_info(buffer, length, host);
+ for (ha = qla1280_hostlist; (ha != NULL)
+ && ha->host->host_no != hostno; ha = ha->next) ;
+
+ /* if host wasn't found then exit */
+ if (!ha) {
+ size = sprintf(buffer, "Can't find adapter for host "
+ "number %d\n", hostno);
+ if (size > length) {
+ return size;
+ } else {
+ return 0;
+ }
}
+ host = ha->host;
+
+ if (inout)
+ return -ENOSYS;
+
/*
* if our old buffer is the right size use it otherwise
* allocate a new one.
@@ -724,10 +702,7 @@ qla1280_proc_info(struct Scsi_Host *host, char *buffer, char **start, off_t offs
len += size;
size = sprintf(PROC_BUF, "SCSI Host Adapter Information: %s\n",
- bdp->bdName);
- len += size;
- size = sprintf(PROC_BUF, "Request Queue = 0x%p, Response Queue = 0x%p\n",
- (void *)ha->request_dma, (void *)ha->response_dma);
+ bdp->name);
len += size;
size = sprintf(PROC_BUF, "Request Queue count= 0x%x, Response "
"Queue count= 0x%x\n",
@@ -736,9 +711,6 @@ qla1280_proc_info(struct Scsi_Host *host, char *buffer, char **start, off_t offs
size = sprintf(PROC_BUF, "Number of pending commands = 0x%lx\n",
ha->actthreads);
len += size;
- size = sprintf(PROC_BUF, "Number of queued commands = 0x%lx\n",
- ha->qthreads);
- len += size;
size = sprintf(PROC_BUF, "Number of free request entries = %d\n",
ha->req_q_cnt);
len += size;
@@ -747,6 +719,7 @@ qla1280_proc_info(struct Scsi_Host *host, char *buffer, char **start, off_t offs
size = sprintf(PROC_BUF, "SCSI device Information:\n");
len += size;
+#ifdef BOGUS_QUEUE
/* scan for all equipment stats */
for (b = 0; b < MAX_BUSES; b++)
for (t = 0; t < MAX_TARGETS; t++) {
@@ -787,6 +760,7 @@ qla1280_proc_info(struct Scsi_Host *host, char *buffer, char **start, off_t offs
if (len >= qla1280_buffer_size)
break;
}
+#endif
if (len >= qla1280_buffer_size) {
printk(KERN_WARNING
@@ -805,11 +779,67 @@ qla1280_proc_info(struct Scsi_Host *host, char *buffer, char **start, off_t offs
}
}
return length;
-#else
- return 0;
-#endif
}
+
+static int qla1280_read_nvram(struct scsi_qla_host *ha)
+{
+ uint16_t *wptr;
+ uint8_t chksum;
+ int cnt;
+ struct nvram *nv;
+
+ ENTER("qla1280_read_nvram");
+
+ if (driver_setup.no_nvram)
+ return 1;
+
+ printk(KERN_INFO "scsi(%ld): Reading NVRAM\n", ha->host_no);
+
+ wptr = (uint16_t *)&ha->nvram;
+ nv = &ha->nvram;
+ chksum = 0;
+ for (cnt = 0; cnt < 3; cnt++) {
+ *wptr = qla1280_get_nvram_word(ha, cnt);
+ chksum += *wptr & 0xff;
+ chksum += (*wptr >> 8) & 0xff;
+ wptr++;
+ }
+
+ if (nv->id0 != 'I' || nv->id1 != 'S' ||
+ nv->id2 != 'P' || nv->id3 != ' ' || nv->version < 1) {
+ dprintk(2, "Invalid nvram ID or version!\n");
+ chksum = 1;
+ } else {
+ for (; cnt < sizeof(struct nvram); cnt++) {
+ *wptr = qla1280_get_nvram_word(ha, cnt);
+ chksum += *wptr & 0xff;
+ chksum += (*wptr >> 8) & 0xff;
+ wptr++;
+ }
+ }
+
+ dprintk(3, "qla1280_read_nvram: NVRAM Magic ID= %c %c %c %02x"
+ " version %i\n", nv->id0, nv->id1, nv->id2, nv->id3,
+ nv->version);
+
+
+ if (chksum) {
+ if (!driver_setup.no_nvram)
+ printk(KERN_WARNING "scsi(%ld): Unable to identify or "
+ "validate NVRAM checksum, using default "
+ "settings\n", ha->host_no);
+ ha->nvram_valid = 0;
+ } else
+ ha->nvram_valid = 1;
+
+ dprintk(1, "qla1280_read_nvram: Completed Reading NVRAM\n");
+ LEAVE("qla1280_read_nvram");
+
+ return chksum;
+}
+
+
/**************************************************************************
* qla1280_do_device_init
* This routine will register the device with the SCSI subsystem,
@@ -827,17 +857,18 @@ qla1280_proc_info(struct Scsi_Host *host, char *buffer, char **start, off_t offs
* host - pointer to SCSI host structure
**************************************************************************/
struct Scsi_Host *
-qla1280_do_device_init(struct pci_dev *pdev,
- Scsi_Host_Template * template,
+qla1280_do_device_init(struct pci_dev *pdev, Scsi_Host_Template * template,
int devnum, struct qla_boards *bdp, int num_hosts)
{
struct Scsi_Host *host;
struct scsi_qla_host *ha;
- struct device_reg *reg;
- printk("qla1x160: Initializing ISP12160 on PCI bus %i, dev %i, irq %i\n",
- pdev->bus->number, PCI_SLOT(pdev->devfn), pdev->irq);
+ printk(KERN_INFO "qla1280: %s found on PCI bus %i, dev %i\n",
+ bdp->name, pdev->bus->number, PCI_SLOT(pdev->devfn));
+#if LINUX_VERSION_CODE >= 0x020545
+ template->slave_configure = qla1280_slave_configure;
+#endif
host = scsi_register(template, sizeof(struct scsi_qla_host));
if (!host) {
printk(KERN_WARNING
@@ -845,7 +876,11 @@ qla1280_do_device_init(struct pci_dev *pdev,
goto error;
}
+#if LINUX_VERSION_CODE < 0x020545
+ scsi_set_pci_device(host, pdev);
+#else
scsi_set_device(host, &pdev->dev);
+#endif
ha = (struct scsi_qla_host *)host->hostdata;
/* Clear our data area */
memset(ha, 0, sizeof(struct scsi_qla_host));
@@ -869,16 +904,13 @@ qla1280_do_device_init(struct pci_dev *pdev,
host->can_queue = 0xfffff; /* unlimited */
host->cmd_per_lun = 1;
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,18)
- host->base = (unsigned char *)ha->mmpbase;
-#else
host->base = (unsigned long)ha->mmpbase;
-#endif
host->max_channel = bdp->numPorts - 1;
host->max_lun = MAX_LUNS - 1;
host->max_id = MAX_TARGETS;
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,7)
host->max_sectors = 1024;
+#if LINUX_VERSION_CODE < 0x020545
+ host->select_queue_depths = qla1280_select_queue_depth;
#endif
ha->instance = num_hosts;
@@ -897,25 +929,25 @@ qla1280_do_device_init(struct pci_dev *pdev,
"qla1280", ha)) {
printk("qla1280 : Failed to reserve interrupt %d already "
"in use\n", host->irq);
- goto error_unmap;
+ goto error_mem_alloced;
}
#if !MEMORY_MAPPED_IO
/* Register the I/O space with Linux */
- if (!request_region(host->io_port, 0xff, "qla1280")) {
- printk("qla1280 : Failed to reserve i/o region 0x%04lx-0x%04lx"
+ if (check_region(host->io_port, 0xff)) {
+ printk("qla1280: Failed to reserve i/o region 0x%04lx-0x%04lx"
" already in use\n",
host->io_port, host->io_port + 0xff);
- goto error_irq;
+ free_irq(host->irq, ha);
+ goto error_mem_alloced;
}
+ request_region(host->io_port, 0xff, "qla1280");
#endif
- reg = ha->iobase;
-
/* load the F/W, read paramaters, and init the H/W */
if (qla1280_initialize_adapter(ha)) {
- printk(KERN_INFO "qla1x160:Failed to initialize adapter\n");
- goto error_region;
+ printk(KERN_INFO "qla1x160: Failed to initialize adapter\n");
+ goto error_mem_alloced;
}
/* set our host ID (need to do something about our two IDs) */
@@ -923,21 +955,6 @@ qla1280_do_device_init(struct pci_dev *pdev,
return host;
- error_region:
-#if !MEMORY_MAPPED_IO
- release_region(host->io_port, 0xff);
-#endif
-
- error_irq:
- free_irq(host->irq, ha);
-
- error_unmap:
-#if MEMORY_MAPPED_IO
- if (ha->mmpbase)
- iounmap((void *)(((unsigned long) ha->mmpbase) & PAGE_MASK));
-#endif
-
-
error_mem_alloced:
qla1280_mem_free(ha);
@@ -975,14 +992,12 @@ qla1280_detect(Scsi_Host_Template * template)
ENTER("qla1280_detect");
- if (sizeof(srb_t) > sizeof(Scsi_Pointer)) {
+ if (sizeof(struct srb) > sizeof(Scsi_Pointer)) {
printk(KERN_WARNING
- "qla1280_detect: [WARNING] srb_t too big\n");
+ "qla1280_detect: [WARNING] struct srb too big\n");
return 0;
}
#ifdef MODULE
- dprintk(1, "DEBUG: qla1280_detect starts at address = %p\n",
- qla1280_detect);
/*
* If we are called as a module, the qla1280 pointer may not be null
* and it would point to our bootup string, just like on the lilo
@@ -995,28 +1010,14 @@ qla1280_detect(Scsi_Host_Template * template)
* which will result in the first four devices on the first two
* controllers being set to a tagged queue depth of 32.
*/
- if (options)
- qla1280_setup(options, NULL);
-
- printk(KERN_WARNING
- "qla1280: Please read the file /usr/src/linux/Documentation"
- "/scsi/qla1280.txt\n"
- "qla1280: to see the proper way to specify options to the qla1280 "
- "module\n"
- "qla1280: Specifically, don't use any commas when passing "
- "arguments to\n"
- "qla1280: insmod or else it might trash certain memory areas.\n");
+ if (qla1280)
+ qla1280_setup(qla1280);
#endif
bdp = &ql1280_board_tbl[0];
qla1280_hostlist = NULL;
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,18)
- template->proc_dir = &proc_scsi_qla1280;
-#else
template->proc_name = "qla1280";
-#endif
- /* 3.20 */
/* First Initialize QLA12160 on PCI Bus 1 Dev 2 */
while ((pdev = pci_find_subsys(PCI_VENDOR_ID_QLOGIC, bdp->device_id,
PCI_ANY_ID, PCI_ANY_ID, pdev))) {
@@ -1059,15 +1060,9 @@ qla1280_detect(Scsi_Host_Template * template)
if (pci_enable_device(pdev))
continue;
/* found an adapter */
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,3,18)
subsys_vendor = pdev->subsystem_vendor;
subsys_device = pdev->subsystem_device;
-#else
- pci_read_config_word(pdev, PCI_SUBSYSTEM_VENDOR_ID,
- &subsys_vendor);
- pci_read_config_word(pdev, PCI_SUBSYSTEM_ID,
- &subsys_device);
-#endif
+
/*
* skip QLA12160 already initialized on
* PCI Bus 1 Dev 2 since we already initialized
@@ -1084,8 +1079,7 @@ qla1280_detect(Scsi_Host_Template * template)
"qla1x160: Skip AMI SubSys Vendor ID Chip\n");
continue;
}
- printk(KERN_INFO
- "qla1x160: Supported Device Found VID=%x "
+ dprintk(1, "qla1x160: Supported Device Found VID=%x "
"DID=%x SSVID=%x SSDID=%x\n", pdev->vendor,
pdev->device, subsys_vendor, subsys_device);
@@ -1135,7 +1129,7 @@ qla1280_release(struct Scsi_Host *host)
#if MEMORY_MAPPED_IO
if (ha->mmpbase)
- iounmap((void *)(((unsigned long) ha->mmpbase) & PAGE_MASK));
+ iounmap(ha->mmpbase);
#else
/* release io space registers */
if (host->io_port)
@@ -1167,7 +1161,7 @@ qla1280_info(struct Scsi_Host *host)
sprintf (bp,
"QLogic %s PCI to SCSI Host Adapter: bus %d device %d irq %d\n"
" Firmware version: %2d.%02d.%02d, Driver version %s",
- &bdp->bdName[0], ha->pci_bus, (ha->pci_device_fn & 0xf8) >> 3,
+ &bdp->name[0], ha->pci_bus, (ha->pci_device_fn & 0xf8) >> 3,
host->irq, bdp->fwver[0], bdp->fwver[1], bdp->fwver[2],
QLA1280_VERSION);
return bp;
@@ -1188,19 +1182,20 @@ int
qla1280_queuecommand(Scsi_Cmnd * cmd, void (*fn) (Scsi_Cmnd *))
{
struct scsi_qla_host *ha;
- srb_t *sp;
+ struct srb *sp;
struct Scsi_Host *host;
int bus, target, lun;
- scsi_lu_t *q;
+ int status;
/*ENTER("qla1280_queuecommand");
*/
+ dprintk(2, "qla1280_queuecommand(): jiffies %li\n", jiffies);
- host = cmd->device->host;
+ host = CMD_HOST(cmd);
ha = (struct scsi_qla_host *)host->hostdata;
/* send command to adapter */
- sp = (srb_t *)CMD_SP(cmd);
+ sp = (struct srb *)CMD_SP(cmd);
sp->cmd = cmd;
cmd->scsi_done = fn;
if (cmd->flags == 0) { /* new command */
@@ -1213,63 +1208,46 @@ qla1280_queuecommand(Scsi_Cmnd * cmd, void (*fn) (Scsi_Cmnd *))
bus = SCSI_BUS_32(cmd);
target = SCSI_TCN_32(cmd);
lun = SCSI_LUN_32(cmd);
- if ((q = LU_Q(ha, bus, target, lun)) == NULL) {
- if ((q = (scsi_lu_t *)kmalloc(sizeof(struct scsi_lu),
- GFP_ATOMIC))) {
- LU_Q(ha, bus, target, lun) = q;
- memset(q, 0, sizeof(struct scsi_lu));
- dprintk(1, "Allocate new device queue 0x%p\n",
- (void *)q);
- } else {
- CMD_RESULT(cmd) = DID_BUS_BUSY << 16;
- qla1280_done_q_put(sp, &ha->done_q_first,
- &ha->done_q_last);
-/* 3.22 */
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0) /* 3.22 */
- schedule_work(&ha->run_qla_bh);
-#else /* 3.22 */
- schedule_work(&ha->run_qla_bh); /* 3.22 */
-#endif /* 3.22 */
- return 0;
- }
- }
- /* Set an invalid handle until we issue the command to ISP */
- /* then we will set the real handle value. */
- CMD_HANDLE(cmd) = (unsigned char *)INVALID_HANDLE;
-
- /* add the command to our queue */
- ha->qthreads++;
- qla1280_putq_t(q, sp);
-
- dprintk(1, "qla1280_QC: t=%x CDB=%x I/OSize=0x%x haQueueCount=0x%lx\n",
- target, cmd->cmnd[0], cmd->request_bufflen, ha->qthreads);
-
- /* send command to adapter */
- if (q->q_outcnt == 0)
- qla1280_restart_queues(ha);
+ if (ha->flags.enable_64bit_addressing)
+ status = qla1280_64bit_start_scsi(ha, sp);
+ else
+ status = qla1280_32bit_start_scsi(ha, sp);
/*LEAVE("qla1280_queuecommand"); */
- return 0;
+ return status;
}
-typedef enum {
+enum action {
ABORT_COMMAND,
ABORT_DEVICE,
DEVICE_RESET,
BUS_RESET,
ADAPTER_RESET,
FAIL
-} action_t;
+};
/* timer action for error action processor */
static void qla1280_error_wait_timeout(unsigned long __data)
{
struct scsi_cmnd *cmd = (struct scsi_cmnd *)__data;
- srb_t *sp = (srb_t *)CMD_SP(cmd);
+ struct srb *sp = (struct srb *)CMD_SP(cmd);
complete(sp->wait);
}
+static void qla1280_mailbox_timeout(unsigned long __data)
+{
+ struct scsi_qla_host *ha = (struct scsi_qla_host *)__data;
+ struct device_reg *reg;
+ reg = ha->iobase;
+
+ ha->mailbox_out[0] = RD_REG_WORD(&reg->mailbox0);
+ printk(KERN_ERR "scsi(%ld): mailbox timed out, mailbox0 %04x, "
+ "ictrl %04x, istatus %04x\n", ha->host_no, ha->mailbox_out[0],
+ RD_REG_WORD(&reg->ictrl), RD_REG_WORD(&reg->istatus));
+ complete(ha->mailbox_wait);
+}
+
/**************************************************************************
* qla1200_error_action
* The function will attempt to perform a specified error action and
@@ -1281,7 +1259,7 @@ static void qla1280_error_wait_timeout(unsigned long __data)
* action = error action to take (see action_t)
*
* Returns:
- * SUCCESS or FAIL
+ * SUCCESS or FAILED
*
* Note:
* Resetting the bus always succeeds - is has to, otherwise the
@@ -1290,39 +1268,43 @@ static void qla1280_error_wait_timeout(unsigned long __data)
* the SCSI bus reset line.
**************************************************************************/
int
-qla1280_error_action(Scsi_Cmnd * cmd, action_t action)
+qla1280_error_action(Scsi_Cmnd * cmd, enum action action)
{
struct scsi_qla_host *ha;
int bus, target, lun;
- srb_t *sp;
+ struct srb *sp;
uint16_t data;
unsigned char *handle;
- scsi_lu_t *q;
- int result;
+ int result, i;
DECLARE_COMPLETION(wait);
struct timer_list timer;
+ ha = (struct scsi_qla_host *)(CMD_HOST(cmd)->hostdata);
+
+ dprintk(4, "error_action %i, istatus 0x%04x\n", action,
+ RD_REG_WORD(&ha->iobase->istatus));
+
+ dprintk(4, "host_cmd 0x%04x, ictrl 0x%04x, jiffies %li\n",
+ RD_REG_WORD(&ha->iobase->host_cmd),
+ RD_REG_WORD(&ha->iobase->ictrl), jiffies);
+
ENTER("qla1280_error_action");
if (qla1280_verbose)
- printk(KERN_INFO "scsi(): Resetting Cmnd=0x%p, Handle=0x%p, "
- "action=0x%x\n", cmd, CMD_HANDLE(cmd), action);
+ printk(KERN_INFO "scsi(%li): Resetting Cmnd=0x%p, "
+ "Handle=0x%p, action=0x%x\n",
+ ha->host_no, cmd, CMD_HANDLE(cmd), action);
if (cmd == NULL) {
- printk(KERN_WARNING
- "(scsi?:?:?:?) Reset called with NULL Scsi_Cmnd "
- "pointer, failing.\n");
+ printk(KERN_WARNING "(scsi?:?:?:?) Reset called with NULL "
+ "si_Cmnd pointer, failing.\n");
LEAVE("qla1280_error_action");
- return FAIL;
+ return FAILED;
}
ha = (struct scsi_qla_host *)cmd->device->host->hostdata;
- sp = (srb_t *)CMD_SP(cmd);
+ sp = (struct srb *)CMD_SP(cmd);
handle = CMD_HANDLE(cmd);
-#if STOP_ON_RESET
- qla1280_panic("qla1280_reset", ha->host);
-#endif
-
/* Check for pending interrupts. */
data = qla1280_debounce_register(&ha->iobase->istatus);
/*
@@ -1337,7 +1319,7 @@ qla1280_error_action(Scsi_Cmnd * cmd, action_t action)
* Determine the suggested action that the mid-level driver wants
* us to perform.
*/
- if (handle == NULL) {
+ if (handle == (unsigned char *)INVALID_HANDLE || handle == NULL) {
if(action == ABORT_COMMAND) {
/* we never got this command */
printk(KERN_INFO "qla1280: Aborting a NULL handle\n");
@@ -1350,23 +1332,16 @@ qla1280_error_action(Scsi_Cmnd * cmd, action_t action)
bus = SCSI_BUS_32(cmd);
target = SCSI_TCN_32(cmd);
lun = SCSI_LUN_32(cmd);
- q = LU_Q(ha, bus, target, lun);
/* Overloading result. Here it means the success or fail of the
* *issue* of the action. When we return from the routine, it must
* mean the actual success or fail of the action */
- result = FAIL;
+ result = FAILED;
switch (action) {
case FAIL:
break;
case ABORT_COMMAND:
- if (q == NULL) {
- /* No lun queue -- command must not be active */
- printk(KERN_WARNING "qla1280 (%d:%d:%d): No LUN queue for the "
- "specified device\n", bus, target, lun);
- break;
- }
if ((sp->flags & SRB_ABORT_PENDING)) {
printk(KERN_WARNING
"scsi(): Command has a pending abort "
@@ -1376,50 +1351,35 @@ qla1280_error_action(Scsi_Cmnd * cmd, action_t action)
break;
}
- /*
- * Normally, would would need to search our queue for
- * the specified command but; since our sp contains
- * the cmd ptr, we can just remove it from our LUN
- * queue.
- */
- if (!(sp->flags & SRB_SENT)) {
- if (qla1280_verbose)
- printk(KERN_WARNING
- "scsi(): Command returned from queue "
- "aborted.\n");
-
- /* Remove srb from SCSI LU queue. */
- qla1280_removeq(q, sp);
- sp->flags |= SRB_ABORTED;
- CMD_RESULT(cmd) = DID_ABORT << 16;
- qla1280_done_q_put(sp, &ha->done_q_first, &ha->done_q_last);
- if (ha->done_q_first)
- qla1280_done(ha, &ha->done_q_first, &ha->done_q_last);
-
- qla1280_restart_queues(ha);
-
- } else { /* find the command in our active list */
- int i;
-
- for (i = 1; i < MAX_OUTSTANDING_COMMANDS; i++) {
- if (sp == ha->outstanding_cmds[i]) {
- dprintk(1,
- "qla1280: RISC aborting command.\n");
- qla1280_abort_command(ha, sp);
+ for (i = 0; i < MAX_OUTSTANDING_COMMANDS; i++) {
+ if (sp == ha->outstanding_cmds[i]) {
+ dprintk(1, "qla1280: RISC aborting command\n");
+ if (qla1280_abort_command(ha, sp, i) == 0)
+ result = SUCCESS;
+ else {
+ /*
+ * Since we don't know what might
+ * have happend to the command, it
+ * is unsafe to remove it from the
+ * device's queue at this point.
+ * Wait and let the escalation
+ * process take care of it.
+ */
+ printk(KERN_WARNING
+ "scsi(%li:%i:%i:%i): Unable"
+ " to abort command!\n",
+ ha->host_no, bus, target, lun);
}
}
}
break;
-
-
case ABORT_DEVICE:
- ha->flags.in_reset = TRUE;
+ ha->flags.in_reset = 1;
if (qla1280_verbose)
printk(KERN_INFO
"scsi(%ld:%d:%d:%d): Queueing abort device "
"command.\n", ha->host_no, bus, target, lun);
- qla1280_abort_queue_single(ha, bus, target, lun, DID_ABORT);
if (qla1280_abort_device(ha, bus, target, lun) == 0)
result = SUCCESS;
break;
@@ -1429,31 +1389,18 @@ qla1280_error_action(Scsi_Cmnd * cmd, action_t action)
printk(KERN_INFO
"scsi(%ld:%d:%d:%d): Queueing device reset "
"command.\n", ha->host_no, bus, target, lun);
- ha->flags.in_reset = TRUE;
- for (lun = 0; lun < MAX_LUNS; lun++)
- qla1280_abort_queue_single(ha, bus, target, lun,
- DID_ABORT);
+ ha->flags.in_reset = 1;
if (qla1280_device_reset(ha, bus, target) == 0)
result = SUCCESS;
- q->q_flag |= QLA1280_QRESET;
break;
case BUS_RESET:
if (qla1280_verbose)
- printk(KERN_INFO "qla1280(%ld:%d:%d:%d): Issuing BUS "
- "DEVICE RESET.\n", ha->host_no, bus, target,
- lun);
- ha->flags.in_reset = TRUE;
- for (target = 0; target < MAX_TARGETS; target++)
- for (lun = 0; lun < MAX_LUNS; lun++)
- qla1280_abort_queue_single(ha, bus, target,
- lun, DID_RESET);
- qla1280_bus_reset(ha, bus);
-
- /* wait 4 seconds */
- schedule_timeout(4*HZ);
-
- result = SUCCESS;
+ printk(KERN_INFO "qla1280(%ld:%d): Issuing BUS "
+ "DEVICE RESET\n", ha->host_no, bus);
+ ha->flags.in_reset = 1;
+ if (qla1280_bus_reset(ha, bus == 0))
+ result = SUCCESS;
break;
@@ -1461,14 +1408,12 @@ qla1280_error_action(Scsi_Cmnd * cmd, action_t action)
default:
if (qla1280_verbose) {
printk(KERN_INFO
- "scsi(%ld:%d:%d:%d): Issued an ADAPTER "
- "RESET.\n", ha->host_no, bus, target, lun);
- printk(KERN_INFO
- "scsi(%ld:%d:%d:%d): I/O processing will "
- "continue automatically.\n", ha->host_no, bus,
- target, lun);
+ "scsi(%ld): Issued ADAPTER RESET\n",
+ ha->host_no);
+ printk(KERN_INFO "scsi(%ld): I/O processing will "
+ "continue automatically\n", ha->host_no);
}
- ha->flags.reset_active = TRUE;
+ ha->flags.reset_active = 1;
/*
* We restarted all of the commands automatically, so the
* mid-level code can expect completions momentitarily.
@@ -1476,17 +1421,17 @@ qla1280_error_action(Scsi_Cmnd * cmd, action_t action)
if (qla1280_abort_isp(ha) == 0)
result = SUCCESS;
- ha->flags.reset_active = FALSE;
+ ha->flags.reset_active = 0;
}
if (ha->done_q_first)
qla1280_done(ha, &ha->done_q_first, &ha->done_q_last);
- qla1280_restart_queues(ha);
- ha->flags.in_reset = FALSE;
+ ha->flags.in_reset = 0;
/* If we didn't manage to issue the action, or we have no
* command to wait for, exit here */
- if(result == FAIL || handle == NULL)
+ if (result == FAILED || handle == NULL ||
+ handle == (unsigned char *)INVALID_HANDLE)
goto leave;
/* set up a timer just in case we're really jammed */
@@ -1497,14 +1442,14 @@ qla1280_error_action(Scsi_Cmnd * cmd, action_t action)
add_timer(&timer);
/* wait for the action to complete (or the timer to expire) */
- spin_unlock_irq(ha->host->host_lock);
+ spin_unlock_irq(HOST_LOCK);
wait_for_completion(&wait);
del_timer_sync(&timer);
- spin_lock_irq(ha->host->host_lock);
+ spin_lock_irq(HOST_LOCK);
sp->wait = NULL;
-
+
/* the only action we might get a fail for is abort */
- if(action == ABORT_COMMAND) {
+ if (action == ABORT_COMMAND) {
if(sp->flags & SRB_ABORTED)
result = SUCCESS;
else
@@ -1519,7 +1464,7 @@ qla1280_error_action(Scsi_Cmnd * cmd, action_t action)
}
/**************************************************************************
- * qla1200_abort
+ * qla1280_abort
* Abort the specified SCSI command(s).
**************************************************************************/
int
@@ -1529,7 +1474,7 @@ qla1280_eh_abort(struct scsi_cmnd * cmd)
}
/**************************************************************************
- * qla1200_device_reset
+ * qla1280_device_reset
* Reset the specified SCSI device
**************************************************************************/
int
@@ -1539,7 +1484,7 @@ qla1280_eh_device_reset(struct scsi_cmnd *cmd)
}
/**************************************************************************
- * qla1200_bus_reset
+ * qla1280_bus_reset
* Reset the specified bus.
**************************************************************************/
int
@@ -1549,7 +1494,7 @@ qla1280_eh_bus_reset(struct scsi_cmnd *cmd)
}
/**************************************************************************
- * qla1200_adapter_reset
+ * qla1280_adapter_reset
* Reset the specified adapter (both channels)
**************************************************************************/
int
@@ -1563,10 +1508,17 @@ qla1280_eh_adapter_reset(struct scsi_cmnd *cmd)
* Return the disk geometry for the given SCSI device.
**************************************************************************/
int
+#if LINUX_VERSION_CODE < 0x020545
+qla1280_biosparam(Disk * disk, kdev_t dev, int geom[])
+#else
qla1280_biosparam(struct scsi_device *sdev, struct block_device *bdev,
- sector_t capacity, int geom[])
+ sector_t capacity, int geom[])
+#endif
{
int heads, sectors, cylinders;
+#if LINUX_VERSION_CODE < 0x020545
+ unsigned long capacity = disk->capacity;
+#endif
heads = 64;
sectors = 32;
@@ -1595,13 +1547,13 @@ qla1280_intr_handler(int irq, void *dev_id, struct pt_regs *regs)
{
struct scsi_qla_host *ha;
struct device_reg *reg;
- int handled = 0;
u16 data;
+ int handled = 0;
ENTER_INTR ("qla1280_intr_handler");
ha = (struct scsi_qla_host *)dev_id;
- spin_lock(ha->host->host_lock);
+ spin_lock(HOST_LOCK);
ha->isr_count++;
reg = ha->iobase;
@@ -1613,16 +1565,11 @@ qla1280_intr_handler(int irq, void *dev_id, struct pt_regs *regs)
if (data & RISC_INT) {
qla1280_isr(ha, &ha->done_q_first, &ha->done_q_last);
handled = 1;
- } else {
- /* spurious interrupts can happen legally */
- dprintk(1, "scsi(%ld): Spurious interrupt - ignoring\n",
- ha->host_no);
}
-
if (ha->done_q_first)
qla1280_done(ha, &ha->done_q_first, &ha->done_q_last);
- spin_unlock(ha->host->host_lock);
+ spin_unlock(HOST_LOCK);
/* enable our interrupt. */
WRT_REG_WORD(&reg->ictrl, (ISP_EN_INT | ISP_EN_RISC));
@@ -1649,10 +1596,7 @@ qla1280_do_dpc(void *p)
struct scsi_qla_host *ha = (struct scsi_qla_host *) p;
unsigned long cpu_flags;
- spin_lock_irqsave(ha->host->host_lock, cpu_flags);
-
- if (ha->flags.isp_abort_needed)
- qla1280_abort_isp(ha);
+ spin_lock_irqsave(HOST_LOCK, cpu_flags);
if (ha->flags.reset_marker)
qla1280_rst_aen(ha);
@@ -1660,9 +1604,58 @@ qla1280_do_dpc(void *p)
if (ha->done_q_first)
qla1280_done(ha, &ha->done_q_first, &ha->done_q_last);
- spin_unlock_irqrestore(ha->host->host_lock, cpu_flags);
+ spin_unlock_irqrestore(HOST_LOCK, cpu_flags);
+}
+
+
+static int
+qla12160_set_target_parameters(struct scsi_qla_host *ha, int bus, int target)
+{
+ uint8_t mr;
+ uint16_t mb[MAILBOX_REGISTER_COUNT];
+ struct nvram *nv;
+ int is1x160, status;
+
+ nv = &ha->nvram;
+
+ if (ha->device_id == PCI_DEVICE_ID_QLOGIC_ISP12160 ||
+ ha->device_id == PCI_DEVICE_ID_QLOGIC_ISP10160)
+ is1x160 = 1;
+ else
+ is1x160 = 0;
+
+ mr = BIT_3 | BIT_2 | BIT_1 | BIT_0;
+
+ /* Set Target Parameters. */
+ mb[0] = MBC_SET_TARGET_PARAMETERS;
+ mb[1] = (uint16_t) (bus ? target | BIT_7 : target);
+ mb[1] <<= 8;
+
+ mb[2] = (nv->bus[bus].target[target].parameter.c << 8);
+
+ if (is1x160)
+ mb[3] = nv->bus[bus].target[target].flags.flags1x160.sync_offset << 8;
+ else
+ mb[3] = nv->bus[bus].target[target].flags.flags1x80.sync_offset << 8;
+ mb[3] |= nv->bus[bus].target[target].sync_period;
+
+ if (is1x160) {
+ mb[2] |= nv->bus[bus].target[target].ppr_1x160.flags.enable_ppr << 5;
+ mb[6] = nv->bus[bus].target[target].ppr_1x160.flags.ppr_options << 8;
+ mb[6] |= nv->bus[bus].target[target].ppr_1x160.flags.ppr_bus_width;
+ mr |= BIT_6;
+ }
+
+ status = qla1280_mailbox_command(ha, mr, &mb[0]);
+
+ if (status)
+ printk(KERN_WARNING "scsi(%ld:%i:%i): "
+ "qla1280_set_target_parameters() failed\n",
+ ha->host_no, bus, target);
+ return status;
}
+
/**************************************************************************
* qla1280_slave_configure
*
@@ -1675,29 +1668,95 @@ qla1280_do_dpc(void *p)
* default queue depth (dependent on the number of hardware SCBs).
**************************************************************************/
static int
-qla1280_slave_configure(Scsi_Device * device)
+qla1280_slave_configure(Scsi_Device *device)
{
- struct scsi_qla_host *p = (struct scsi_qla_host *)device->host->hostdata;
+ struct scsi_qla_host *ha;
+ int default_depth = 3;
int bus = device->channel;
int target = device->id;
+ int status = 0;
+ struct nvram *nv;
+#if LINUX_VERSION_CODE < 0x020500
+ unsigned long flags;
+#endif
+
+ ha = (struct scsi_qla_host *)device->host->hostdata;
+ nv = &ha->nvram;
- if (qla1280_check_for_dead_scsi_bus(p, bus))
+ if (qla1280_check_for_dead_scsi_bus(ha, bus))
return 1;
+
if (device->tagged_supported &&
- (p->bus_settings[bus].qtag_enables & (BIT_0 << target))) {
+ (ha->bus_settings[bus].qtag_enables & (BIT_0 << target))) {
scsi_adjust_queue_depth(device, MSG_ORDERED_TAG,
- p->bus_settings[bus].hiwat);
- /* device->queue_depth = 20; */
- printk(KERN_INFO "scsi(%li:%d:%d:%d): Enabled tagged queuing, "
- "queue depth %d.\n", p->host_no, device->channel,
- device->id, device->lun, device->queue_depth);
+ ha->bus_settings[bus].hiwat);
} else {
- scsi_adjust_queue_depth(device, 0 /* TCQ off */, 3);
+ scsi_adjust_queue_depth(device, 0, default_depth);
}
- qla12160_get_target_parameters(p, bus, target, device->lun);
- return 0;
+
+#if LINUX_VERSION_CODE > 0x020500
+ nv->bus[bus].target[target].parameter.f.enable_sync = device->sdtr;
+ nv->bus[bus].target[target].parameter.f.enable_wide = device->wdtr;
+ nv->bus[bus].target[target].ppr_1x160.flags.enable_ppr = device->ppr;
+#endif
+
+ if (driver_setup.no_sync ||
+ (driver_setup.sync_mask &&
+ (~driver_setup.sync_mask & (1 << target))))
+ nv->bus[bus].target[target].parameter.f.enable_sync = 0;
+ if (driver_setup.no_wide ||
+ (driver_setup.wide_mask &&
+ (~driver_setup.wide_mask & (1 << target))))
+ nv->bus[bus].target[target].parameter.f.enable_wide = 0;
+ if (ha->device_id == PCI_DEVICE_ID_QLOGIC_ISP12160 ||
+ ha->device_id == PCI_DEVICE_ID_QLOGIC_ISP10160) {
+ if (driver_setup.no_ppr ||
+ (driver_setup.ppr_mask &&
+ (~driver_setup.ppr_mask & (1 << target))))
+ nv->bus[bus].target[target].ppr_1x160.flags.enable_ppr = 0;
+ }
+
+#if LINUX_VERSION_CODE < 0x020500
+ spin_lock_irqsave(HOST_LOCK, flags);
+#endif
+ if (nv->bus[bus].target[target].parameter.f.enable_sync) {
+ status = qla12160_set_target_parameters(ha, bus, target);
+ }
+
+ qla12160_get_target_parameters(ha, device);
+#if LINUX_VERSION_CODE < 0x020500
+ spin_unlock_irqrestore(HOST_LOCK, flags);
+#endif
+ return status;
}
+#if LINUX_VERSION_CODE < 0x020545
+/**************************************************************************
+ * qla1280_select_queue_depth
+ *
+ * Sets the queue depth for each SCSI device hanging off the input
+ * host adapter. We use a queue depth of 2 for devices that do not
+ * support tagged queueing.
+ **************************************************************************/
+static void
+qla1280_select_queue_depth(struct Scsi_Host *host, Scsi_Device *scsi_devs)
+{
+ Scsi_Device *device;
+ struct scsi_qla_host *ha = (struct scsi_qla_host *)host->hostdata;
+
+ ENTER("qla1280_select_queue_depth");
+ for (device = scsi_devs; device != NULL; device = device->next) {
+ if (device->host == host)
+ qla1280_slave_configure(device);
+ }
+
+ if (scsi_devs)
+ qla1280_check_for_dead_scsi_bus(ha, scsi_devs->channel);
+
+ LEAVE("qla1280_select_queue_depth");
+}
+#endif
+
/*
* Driver Support Routines
*/
@@ -1712,11 +1771,10 @@ qla1280_slave_configure(Scsi_Device * device)
* done_q_last = done queue last pointer.
*/
static void
-qla1280_done(struct scsi_qla_host *ha, srb_t ** done_q_first,
- srb_t ** done_q_last)
+qla1280_done(struct scsi_qla_host *ha, struct srb ** done_q_first,
+ struct srb ** done_q_last)
{
- srb_t *sp;
- scsi_lu_t *q;
+ struct srb *sp;
int bus, target, lun;
Scsi_Cmnd *cmd;
@@ -1734,24 +1792,9 @@ qla1280_done(struct scsi_qla_host *ha, srb_t ** done_q_first,
bus = SCSI_BUS_32(cmd);
target = SCSI_TCN_32(cmd);
lun = SCSI_LUN_32(cmd);
- q = LU_Q(ha, bus, target, lun);
-
- /* Decrement outstanding commands on device. */
- if (q->q_outcnt)
- q->q_outcnt--;
- if (q->q_outcnt < ha->bus_settings[bus].hiwat) {
- q->q_flag &= ~QLA1280_QBUSY;
- }
-
- q->io_cnt++;
- if (sp->dir & BIT_5)
- q->r_cnt++;
- else
- q->w_cnt++;
switch ((CMD_RESULT(cmd) >> 16)) {
case DID_RESET:
- q->q_flag &= ~QLA1280_QRESET;
/* Issue marker command. */
qla1280_marker(ha, bus, target, 0, MK_SYNC_ID);
break;
@@ -1765,10 +1808,9 @@ qla1280_done(struct scsi_qla_host *ha, srb_t ** done_q_first,
break;
}
- /* 3.13 64 and 32 bit */
/* Release memory used for this I/O */
if (cmd->use_sg) {
- dprintk(1, "S/G unmap_sg cmd=%p\n", cmd);
+ dprintk(3, "S/G unmap_sg cmd=%p\n", cmd);
pci_unmap_sg(ha->pdev, cmd->request_buffer,
cmd->use_sg,
@@ -1777,21 +1819,24 @@ qla1280_done(struct scsi_qla_host *ha, srb_t ** done_q_first,
/*dprintk(1, "No S/G unmap_single cmd=%x saved_dma_handle=%lx\n",
cmd, sp->saved_dma_handle); */
- pci_unmap_single(ha->pdev, sp->saved_dma_handle,
- cmd->request_bufflen,
- scsi_to_pci_dma_dir(cmd->sc_data_direction));
+ pci_unmap_page(ha->pdev, sp->saved_dma_handle,
+ cmd->request_bufflen,
+ scsi_to_pci_dma_dir(cmd->sc_data_direction));
}
/* Call the mid-level driver interrupt handler */
- CMD_HANDLE(sp->cmd) = NULL;
+ CMD_HANDLE(sp->cmd) = (unsigned char *)INVALID_HANDLE;
ha->actthreads--;
+#if LINUX_KERNEL_VERSION < 0x020500
+ if (cmd->cmnd[0] == INQUIRY)
+ qla1280_get_target_options(cmd, ha);
+#endif
(*(cmd)->scsi_done)(cmd);
if(sp->wait != NULL)
complete(sp->wait);
- qla1280_next(ha, q, bus);
}
LEAVE("qla1280_done");
}
@@ -1800,7 +1845,7 @@ qla1280_done(struct scsi_qla_host *ha, srb_t ** done_q_first,
* Translates a ISP error to a Linux SCSI error
*/
static int
-qla1280_return_status(sts_entry_t * sts, Scsi_Cmnd * cp)
+qla1280_return_status(struct response * sts, Scsi_Cmnd * cp)
{
int host_status = DID_ERROR;
#if DEBUG_QLA1280_INTR
@@ -1901,7 +1946,8 @@ qla1280_return_status(sts_entry_t * sts, Scsi_Cmnd * cp)
* done_q_last = done queue last pointer.
*/
static void
-qla1280_done_q_put(srb_t * sp, srb_t ** done_q_first, srb_t ** done_q_last)
+qla1280_done_q_put(struct srb * sp, struct srb ** done_q_first,
+ struct srb ** done_q_last)
{
ENTER("qla1280_put_done_q");
@@ -1917,160 +1963,6 @@ qla1280_done_q_put(srb_t * sp, srb_t ** done_q_first, srb_t ** done_q_last)
LEAVE("qla1280_put_done_q");
}
-/*
- * qla1280_next
- * Retrieve and process next job in the queue.
- *
- * Input:
- * ha = adapter block pointer.
- * q = SCSI LU pointer.
- * bus = SCSI bus number.
- * SCSI_LU_Qlock must be already obtained and no other locks.
- *
- * Output:
- * Releases SCSI_LU_Qupon exit.
- */
-static void
-qla1280_next(struct scsi_qla_host *ha, scsi_lu_t * q, int bus)
-{
- srb_t *sp;
- int cnt, status;
-
- ENTER("qla1280_next");
-
- while (((sp = q->q_first) != NULL) && /* we have a queue pending */
- /* device not busy/suspended */
- !(q->q_flag & (QLA1280_QBUSY | QLA1280_QSUSP)) && !ha->flags.abort_isp_active) { /* not resetting the adapter */
- /* Remove srb from SCSI LU queue. */
- qla1280_removeq(q, sp);
-
- dprintk(1, "starting request 0x%p<-(0x%p)\n", q, sp);
- {
- /* Set busy flag if reached high water mark. */
- q->q_outcnt++;
- if (q->q_outcnt >= ha->bus_settings[bus].hiwat)
- q->q_flag |= QLA1280_QBUSY;
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,18)
- if (ha->flags.enable_64bit_addressing)
- status = qla1280_64bit_start_scsi(ha, sp);
- else
-#endif
- status = qla1280_32bit_start_scsi(ha, sp);
-
- if (status) { /* if couldn't start the request */
- if (q->q_outcnt == 1) {
- /* Wait for 30 sec for command to be accepted. */
- for (cnt = 6000000; cnt; cnt--) {
-#if QLA_64BIT_PTR
- if (ha->flags.enable_64bit_addressing)
- status =
- qla1280_64bit_start_scsi(ha, sp);
- else
-#endif
- status =
- qla1280_32bit_start_scsi(ha, sp);
-
- if (!status)
- break;
-
- /* Go check for pending interrupts. */
- qla1280_poll(ha);
-
- udelay(5); /* 10 */
- }
- if (!cnt) {
- /* Set timeout status */
- CMD_RESULT(sp->cmd) =
- DID_TIME_OUT << 16;
-
-#if WATCHDOGTIMER
- /* Remove command from watchdog queue. */
- if (sp->flags & SRB_WATCHDOG)
- qla1280_timeout_remove
- (ha, sp);
-#endif
- CMD_HANDLE(sp->cmd) = NULL;
-
- /* Call the mid-level driver interrupt handler */
- (*(sp->cmd)->scsi_done)(sp->cmd);
-
- if (q->q_outcnt)
- q->q_outcnt--;
- }
- } else { /* Place request back on top of device queue. */
- qla1280_putq_t(q, sp);
-
- if (q->q_outcnt)
- q->q_outcnt--;
- if (q->q_outcnt <
- ha->bus_settings[bus].hiwat)
- q->q_flag &= ~QLA1280_QBUSY;
- break;
- }
- }
- }
- }
-
- LEAVE("qla1280_next");
-}
-
-/*
- * qla1280_putq_t
- * Add the standard SCB job to the top of standard SCB commands.
- *
- * Input:
- * q = SCSI LU pointer.
- * sp = srb pointer.
- * SCSI_LU_Qlock must be already obtained.
- */
-static void
-qla1280_putq_t(scsi_lu_t * q, srb_t * sp)
-{
- ENTER("qla1280_putq_t");
-
- dprintk(1, "Adding to device q=0x%p<-(0x%p)sp\n", (void *) q,
- (void *) sp);
-
- sp->s_next = NULL;
- if (!q->q_first) { /* If queue empty */
- sp->s_prev = NULL;
- q->q_first = sp;
- q->q_last = sp;
- } else {
- sp->s_prev = q->q_last;
- q->q_last->s_next = sp;
- q->q_last = sp;
- }
-
- LEAVE("qla1280_putq_t");
-}
-
-/*
- * qla1280_removeq
- * Function used to remove a command block from the
- * LU queue.
- *
- * Input:
- * q = SCSI LU pointer.
- * sp = srb pointer.
- * SCSI_LU_Qlock must be already obtained.
- */
-static void
-qla1280_removeq(scsi_lu_t * q, srb_t * sp)
-{
- dprintk(1, "Removing from device_q (0x%p)->(0x%p)\n", q, sp);
-
- if (sp->s_prev) {
- if ((sp->s_prev->s_next = sp->s_next) != NULL)
- sp->s_next->s_prev = sp->s_prev;
- else
- q->q_last = sp->s_prev;
- } else if (!(q->q_first = sp->s_next))
- q->q_last = NULL;
- else
- q->q_first->s_prev = NULL;
-}
/*
* qla1280_mem_alloc
@@ -2088,7 +1980,6 @@ qla1280_mem_alloc(struct scsi_qla_host *ha)
ENTER("qla1280_mem_alloc");
- /* 3.13 */
/* get consistent memory allocated for request and response rings */
ha->request_ring = pci_alloc_consistent(ha->pdev,
((REQUEST_ENTRY_CNT + 1) *
@@ -2099,7 +1990,7 @@ qla1280_mem_alloc(struct scsi_qla_host *ha)
ha->request_dma = dma_handle;
ha->response_ring = pci_alloc_consistent(ha->pdev,
((RESPONSE_ENTRY_CNT + 1) *
- (sizeof(response_t))),
+ (sizeof(struct response))),
&dma_handle);
if (!ha->request_ring)
goto error;
@@ -2124,26 +2015,7 @@ qla1280_mem_alloc(struct scsi_qla_host *ha)
static void
qla1280_mem_free(struct scsi_qla_host *ha)
{
- scsi_lu_t *q;
- int bus, target, lun;
-
ENTER("qlc1280_mem_free");
- if (ha) {
- /* Free device queues. */
- for (bus = 0; bus < MAX_BUSES; bus++) {
- q = LU_Q(ha, bus, ha->bus_settings[bus].id, 0);
- for (target = 0; target < MAX_TARGETS; target++)
- for (lun = 0; lun < MAX_LUNS; lun++)
- if (LU_Q(ha, bus, target, lun) != NULL
- && LU_Q(ha, bus, target, lun) != q)
- kfree(LU_Q(ha, bus, target, lun));
- kfree(q);
- }
- for (bus = 0; bus < MAX_EQ; bus++)
- ha->dev[bus] = NULL;
- }
-
- /* 3.13 */
/* free consistent memory allocated for request and response rings */
if (ha->request_ring)
pci_free_consistent(ha->pdev,
@@ -2154,7 +2026,7 @@ qla1280_mem_free(struct scsi_qla_host *ha)
if (ha->response_ring)
pci_free_consistent(ha->pdev,
((RESPONSE_ENTRY_CNT + 1) *
- (sizeof(response_t))),
+ (sizeof(struct response))),
ha->response_ring, ha->response_dma);
if (qla1280_buffer) {
@@ -2187,10 +2059,8 @@ qla1280_enable_intrs(struct scsi_qla_host *ha)
reg = ha->iobase;
/* enable risc and host interrupts */
WRT_REG_WORD(&reg->ictrl, (ISP_EN_INT | ISP_EN_RISC));
+ RD_REG_WORD(&reg->ictrl); /* PCI Posted Write flush */
ha->flags.ints_enabled = 1;
-#if 0
- printk("Enabling ints\n");
-#endif
}
static inline void
@@ -2201,10 +2071,8 @@ qla1280_disable_intrs(struct scsi_qla_host *ha)
reg = ha->iobase;
/* disable risc and host interrupts */
WRT_REG_WORD(&reg->ictrl, 0);
+ RD_REG_WORD(&reg->ictrl); /* PCI Posted Write flush */
ha->flags.ints_enabled = 0;
-#if 0
- printk("Disabling ints\n");
-#endif
}
/*
@@ -2227,13 +2095,29 @@ qla1280_initialize_adapter(struct scsi_qla_host *ha)
ENTER("qla1280_initialize_adapter");
/* Clear adapter flags. */
- ha->flags.online = FALSE;
- ha->flags.isp_abort_needed = FALSE;
- ha->flags.disable_host_adapter = FALSE;
- ha->flags.reset_active = FALSE;
- ha->flags.abort_isp_active = FALSE;
+ ha->flags.online = 0;
+ ha->flags.disable_host_adapter = 0;
+ ha->flags.reset_active = 0;
+ ha->flags.abort_isp_active = 0;
- ha->flags.ints_enabled = FALSE;
+ ha->flags.ints_enabled = 0;
+#if defined(CONFIG_IA64_GENERIC) || defined(CONFIG_IA64_SGI_SN2)
+ if (ia64_platform_is("sn2")) {
+ int count1, count2;
+ int c;
+
+ count1 = 3;
+ count2 = 3;
+ printk(KERN_INFO "scsi(%li): Enabling SN2 PCI DMA "
+ "dual channel lockup workaround\n", ha->host_no);
+ if ((c = snia_pcibr_rrb_alloc(ha->pdev, &count1, &count2)) < 0)
+ printk(KERN_ERR "scsi(%li): Unable to allocate SN2 "
+ "virtual DMA channels\n", ha->host_no);
+ ha->flags.use_pci_vchannel = 1;
+
+ driver_setup.no_nvram = 1;
+ }
+#endif
dprintk(1, "Configure PCI space for adapter...\n");
@@ -2243,79 +2127,65 @@ qla1280_initialize_adapter(struct scsi_qla_host *ha)
WRT_REG_WORD(&reg->semaphore, 0);
WRT_REG_WORD(&reg->host_cmd, HC_CLR_RISC_INT);
WRT_REG_WORD(&reg->host_cmd, HC_CLR_HOST_INT);
+ RD_REG_WORD(&reg->host_cmd);
+
+ if (qla1280_read_nvram(ha)) {
+ dprintk(2, "qla1280_initialize_adapter: failed to read "
+ "NVRAM\n");
+ }
/* If firmware needs to be loaded */
- if (qla1280_verbose)
- printk(KERN_INFO "scsi(%li): Determining if RISC is "
- "loaded...\n", ha->host_no);
if (qla1280_isp_firmware(ha)) {
- if (qla1280_verbose)
- printk(KERN_INFO "scsi(%ld): Verifying chip...\n",
- ha->host_no);
if (!(status = qla1280_chip_diag (ha))) {
- if (qla1280_verbose)
- printk(KERN_INFO "scsi(%ld): Setup chip...\n",
- ha->host_no);
status = qla1280_setup_chip(ha);
}
} else {
- printk(KERN_ERR "initialize: isp_firmware() failed!\n");
+ printk(KERN_ERR "scsi(%li): isp_firmware() failed!\n",
+ ha->host_no);
status = 1;
}
- if (!status) {
- /* Setup adapter based on NVRAM parameters. */
- if (qla1280_verbose)
- printk(KERN_INFO
- "scsi(%ld): Configure NVRAM parameters...\n",
- ha->host_no);
- qla1280_nvram_config(ha);
-
- if (!ha->flags.disable_host_adapter
- && !qla1280_init_rings(ha)) {
- /* Issue SCSI reset. */
- /* dg 03/13 if we can't reset twice then bus is dead */
- for (bus = 0; bus < ha->ports; bus++) {
- if (!ha->bus_settings[bus].disable_scsi_reset){
+ if (status) {
+ printk(KERN_ERR "scsi(%li): initialize: pci probe failed!\n",
+ ha->host_no);
+ goto out;
+ }
+
+ /* Setup adapter based on NVRAM parameters. */
+ dprintk(1, "scsi(%ld): Configure NVRAM parameters\n", ha->host_no);
+ qla1280_nvram_config(ha);
+
+ if (!ha->flags.disable_host_adapter && !qla1280_init_rings(ha)) {
+ /* Issue SCSI reset. */
+ /* dg 03/13 if we can't reset twice then bus is dead */
+ for (bus = 0; bus < ha->ports; bus++) {
+ if (!ha->bus_settings[bus].disable_scsi_reset){
+ if (qla1280_bus_reset(ha, bus)) {
if (qla1280_bus_reset(ha, bus)) {
- if (qla1280_bus_reset(ha, bus)) {
- ha->bus_settings[bus].scsi_bus_dead = TRUE;
- }
+ ha->bus_settings[bus].scsi_bus_dead = 1;
}
}
}
- do {
- /* Issue marker command. */
- ha->flags.reset_marker = FALSE;
- for (bus = 0; bus < ha->ports; bus++) {
- ha->bus_settings[bus].reset_marker = FALSE;
- qla1280_marker(ha, bus, 0, 0,
- MK_SYNC_ALL);
- }
- } while (ha->flags.reset_marker);
-
- ha->flags.online = TRUE;
+ }
- /* Enable host adapter target mode. */
- for (bus = 0; bus < ha->ports; bus++) {
- if (!(status = qla1280_enable_tgt(ha, bus))) {
+ /*
+ * qla1280_bus_reset() will take care of issueing markers,
+ * no need to do that here as well!
+ */
#if 0
- int cnt;
- for (cnt = 0; cnt < MAX_LUNS; cnt++) {
- qla1280_enable_lun(ha, bus,
- cnt);
- qla1280_poll(ha);
- }
+ /* Issue marker command. */
+ ha->flags.reset_marker = 0;
+ for (bus = 0; bus < ha->ports; bus++) {
+ ha->bus_settings[bus].reset_marker = 0;
+ qla1280_marker(ha, bus, 0, 0, MK_SYNC_ALL);
+ }
#endif
- } else
- break;
- }
- } else
- status = 1;
+
+ ha->flags.online = 1;
} else
- printk(KERN_ERR "scsi(%li): initialize: pci probe failed!\n",
- ha->host_no);
+ status = 1;
+ out:
if (status)
dprintk(2, "qla1280_initialize_adapter: **** FAILED ****\n");
@@ -2323,39 +2193,6 @@ qla1280_initialize_adapter(struct scsi_qla_host *ha)
return status;
}
-/*
- * qla1280_enable_tgt
- * Enable target mode.
- *
- * Input:
- * ha = adapter block pointer.
- * bus = SCSI bus number.
- *
- * Returns:
- * 0 = success.
- */
-static int
-qla1280_enable_tgt(struct scsi_qla_host *ha, int bus)
-{
- int status = 0;
- /* uint16_t mb[MAILBOX_REGISTER_COUNT]; */
-
- dprintk(3, "qla1280_enable_tgt: entered\n");
-
- /* Enable target mode. */
-#if 0
- mb[0] = MBC_ENABLE_TARGET_MODE;
- mb[1] = BIT_15;
- mb[2] = (uint16_t) (bus << 15);
- status = qla1280_mailbox_command(ha, BIT_2 | BIT_1 | BIT_0, &mb[0]);
-#endif
- if (status)
- dprintk(2, "qla1280_enable_tgt: **** FAILED ****\n");
- else
- dprintk(3, "qla1280_enable_tgt: exiting normally\n");
-
- return status;
-}
/*
* ISP Firmware Test
@@ -2371,54 +2208,32 @@ qla1280_enable_tgt(struct scsi_qla_host *ha, int bus)
static int
qla1280_isp_firmware(struct scsi_qla_host *ha)
{
- nvram_t *nv = (nvram_t *) ha->response_ring;
- uint16_t *wptr;
+ struct nvram *nv = (struct nvram *) ha->response_ring;
int status = 0; /* dg 2/27 always loads RISC */
- int cnt;
- uint8_t chksum;
uint16_t mb[MAILBOX_REGISTER_COUNT];
ENTER("qla1280_isp_firmware");
- /* Verify valid NVRAM checksum. */
- wptr = (uint16_t *) ha->response_ring;
- dprintk(1, "qla1280_isp_firmware: Reading NVRAM\n");
-
- chksum = 0;
- for (cnt = 0; cnt < sizeof(nvram_t) / 2; cnt++) {
- *wptr = qla1280_get_nvram_word (ha, cnt);
- chksum += (uint8_t) * wptr;
- chksum += (uint8_t) (*wptr >> 8);
- wptr++;
- }
- dprintk(1, "qla1280_isp_firmware: Completed Reading NVRAM\n");
-
- dprintk(3, "qla1280_isp_firmware: NVRAM Magic ID= %c %c %c\n",
- nv->id0, nv->id1, nv->id2);
+ dprintk(1, "scsi(%li): Determining if RISC is loaded\n", ha->host_no);
/* Bad NVRAM data, load RISC code. */
- if (chksum || nv->id0 != 'I' || nv->id1 != 'S' ||
- nv->id2 != 'P' || nv->id3 != ' ' || nv->version < 1) {
- printk(KERN_INFO "qla1280_isp_firmware: Bad checksum or magic "
- "number or version in NVRAM.\n");
- ha->flags.disable_risc_code_load = FALSE;
+ if (!ha->nvram_valid) {
+ ha->flags.disable_risc_code_load = 0;
} else
ha->flags.disable_risc_code_load =
nv->cntr_flags_1.disable_loading_risc_code;
if (ha->flags.disable_risc_code_load) {
- dprintk(3,
- "qla1280_isp_firmware: Telling RISC to verify checksum "
- "of loaded BIOS code.\n");
+ dprintk(3, "qla1280_isp_firmware: Telling RISC to verify "
+ "checksum of loaded BIOS code.\n");
/* Verify checksum of loaded RISC code. */
mb[0] = MBC_VERIFY_CHECKSUM;
/* mb[1] = ql12_risc_code_addr01; */
mb[1] = *ql1280_board_tbl[ha->devnum].fwstart;
- if (!
- (status =
- qla1280_mailbox_command(ha, BIT_1 | BIT_0, &mb[0]))) {
+ if (!(status =
+ qla1280_mailbox_command(ha, BIT_1 | BIT_0, &mb[0]))) {
/* Start firmware execution. */
dprintk(3, "qla1280_isp_firmware: Startng F/W "
"execution.\n");
@@ -2455,8 +2270,8 @@ static int
qla1280_pci_config(struct scsi_qla_host *ha)
{
#if MEMORY_MAPPED_IO
- uint32_t page_offset, base;
- uint32_t mmapbase;
+ unsigned long base;
+ int size;
#endif
uint16_t buf_wd;
int status = 1;
@@ -2470,16 +2285,14 @@ qla1280_pci_config(struct scsi_qla_host *ha)
*/
pci_read_config_word (ha->pdev, PCI_COMMAND, &buf_wd);
#if MEMORY_MAPPED_IO
- dprintk(1, "qla1280: MEMORY MAPPED IO is enabled.\n");
- buf_wd |= PCI_COMMAND_MEMORY + PCI_COMMAND_IO;
-#else
- buf_wd |= PCI_COMMAND_IO;
+ buf_wd |= PCI_COMMAND_MEMORY;
#endif
+ buf_wd |= PCI_COMMAND_IO;
pci_write_config_word (ha->pdev, PCI_COMMAND, buf_wd);
/*
* Reset expansion ROM address decode enable.
*/
- pci_read_config_word (ha->pdev, PCI_ROM_ADDRESS, &buf_wd);
+ pci_read_config_word(ha->pdev, PCI_ROM_ADDRESS, &buf_wd);
buf_wd &= ~PCI_ROM_ADDRESS_ENABLE;
pci_write_config_word (ha->pdev, PCI_ROM_ADDRESS, buf_wd);
@@ -2489,23 +2302,16 @@ qla1280_pci_config(struct scsi_qla_host *ha)
#if MEMORY_MAPPED_IO
/*
- * Get memory mapped I/O address.
- */
- pci_read_config_word (ha->pdev, PCI_BASE_ADDRESS_1, &mmapbase);
- mmapbase &= PCI_BASE_ADDRESS_MEM_MASK;
-
- /*
* Find proper memory chunk for memory map I/O reg.
*/
- base = mmapbase & PAGE_MASK;
- page_offset = mmapbase - base;
+ base = pci_resource_start(ha->pdev, 1);
+ size = pci_resource_len(ha->pdev, 1);
/*
* Get virtual address for I/O registers.
*/
- ha->mmpbase = ioremap(base, page_offset + 256);
+ ha->mmpbase = ioremap(base, size);
if (ha->mmpbase) {
- ha->mmpbase += page_offset;
- /* ha->iobase = ha->mmpbase; */
+ ha->iobase = (struct device_reg *)ha->mmpbase;
status = 0;
}
#else /* MEMORY_MAPPED_IO */
@@ -2537,50 +2343,69 @@ qla1280_chip_diag(struct scsi_qla_host *ha)
dprintk(3, "qla1280_chip_diag: testing device at 0x%p \n", &reg->id_l);
+ dprintk(1, "scsi(%ld): Verifying chip\n", ha->host_no);
+
/* Soft reset chip and wait for it to finish. */
WRT_REG_WORD(&reg->ictrl, ISP_RESET);
+ /*
+ * We can't do a traditional PCI write flush here by reading
+ * back the register. The card will not respond once the reset
+ * is in action and we end up with a machine check exception
+ * instead. Nothing to do but wait and hope for the best.
+ * A portable pci_write_flush(pdev) call would be very useful here.
+ */
+ udelay(20);
data = qla1280_debounce_register(&reg->ictrl);
/*
- * This is *AWESOME*
+ * Yet another QLogic gem ;-(
*/
- for (cnt = 6000000; cnt && data & ISP_RESET; cnt--) {
+ for (cnt = 1000000; cnt && data & ISP_RESET; cnt--) {
udelay(5);
data = RD_REG_WORD(&reg->ictrl);
}
+
if (cnt) {
- /* Reset register not cleared by chip reset. */
- dprintk(3,
- "qla1280_chip_diag: reset register cleared by chip reset\n");
+ /* Reset register cleared by chip reset. */
+ dprintk(3, "qla1280_chip_diag: reset register cleared by "
+ "chip reset\n");
WRT_REG_WORD(&reg->cfg_1, 0);
/* Reset RISC and disable BIOS which
allows RISC to execute out of RAM. */
+#if 0
WRT_REG_WORD(&reg->host_cmd, HC_RESET_RISC);
+ RD_REG_WORD(&reg->id_l); /* Flush PCI write */
WRT_REG_WORD(&reg->host_cmd, HC_RELEASE_RISC);
+ RD_REG_WORD(&reg->id_l); /* Flush PCI write */
WRT_REG_WORD(&reg->host_cmd, HC_DISABLE_BIOS);
+#else
+ WRT_REG_WORD(&reg->host_cmd, HC_RESET_RISC |
+ HC_RELEASE_RISC | HC_DISABLE_BIOS);
+#endif
+ RD_REG_WORD(&reg->id_l); /* Flush PCI write */
data = qla1280_debounce_register(&reg->mailbox0);
/*
* I *LOVE* this code!
*/
- for (cnt = 6000000; cnt && data == MBS_BUSY; cnt--) {
+ for (cnt = 1000000; cnt && data == MBS_BUSY; cnt--) {
udelay(5);
data = RD_REG_WORD(&reg->mailbox0);
}
if (cnt) {
/* Check product ID of chip */
- dprintk(3,
- "qla1280_chip_diag: Checking product ID of chip\n");
+ dprintk(3, "qla1280_chip_diag: Checking product "
+ "ID of chip\n");
if (RD_REG_WORD(&reg->mailbox1) != PROD_ID_1 ||
(RD_REG_WORD(&reg->mailbox2) != PROD_ID_2 &&
RD_REG_WORD(&reg->mailbox2) != PROD_ID_2a) ||
RD_REG_WORD(&reg->mailbox3) != PROD_ID_3 ||
RD_REG_WORD(&reg->mailbox4) != PROD_ID_4) {
- printk(KERN_INFO
- "qla1280: Wrong product ID = 0x%x,0x%x,0x%x,"
- "0x%x\n", RD_REG_WORD(&reg->mailbox1),
+ printk(KERN_INFO "qla1280: Wrong product ID = "
+ "0x%x,0x%x,0x%x,0x%x\n",
+ RD_REG_WORD(&reg->mailbox1),
RD_REG_WORD(&reg->mailbox2),
RD_REG_WORD(&reg->mailbox3),
RD_REG_WORD(&reg->mailbox4));
@@ -2590,8 +2415,9 @@ qla1280_chip_diag(struct scsi_qla_host *ha)
* Enable ints early!!!
*/
qla1280_enable_intrs(ha);
- dprintk(1,
- "qla1280_chip_diag: Checking mailboxes of chip\n");
+
+ dprintk(1, "qla1280_chip_diag: Checking "
+ "mailboxes of chip\n");
/* Wrap Incoming Mailboxes Test. */
mb[0] = MBC_MAILBOX_REGISTER_TEST;
mb[1] = 0xAAAA;
@@ -2602,14 +2428,7 @@ qla1280_chip_diag(struct scsi_qla_host *ha)
mb[6] = 0x5A5A;
mb[7] = 0x2525;
if (!(status = qla1280_mailbox_command(ha,
- BIT_7 |
- BIT_6 |
- BIT_5 |
- BIT_4 |
- BIT_3 |
- BIT_2 |
- BIT_1 |
- BIT_0,
+ 0xff,
&mb
[0]))) {
if (mb[1] != 0xAAAA ||
@@ -2618,11 +2437,11 @@ qla1280_chip_diag(struct scsi_qla_host *ha)
mb[4] != 0x55AA ||
mb[5] != 0xA5A5 ||
mb[6] != 0x5A5A ||
- mb[7] != 0x2525)
+ mb[7] != 0x2525) {
status = 1;
- if (status == 1)
- printk(KERN_INFO
- "qla1280: Failed mailbox check\n");
+ printk(KERN_INFO "qla1280: "
+ "Failed mbox check\n");
+ }
}
}
} else
@@ -2648,7 +2467,7 @@ qla1280_chip_diag(struct scsi_qla_host *ha)
* Returns:
* 0 = success.
*/
-#define DUMP_IT_BACK 1 /* for debug of RISC loading */
+#define DUMP_IT_BACK 0 /* for debug of RISC loading */
static int
qla1280_setup_chip(struct scsi_qla_host *ha)
{
@@ -2658,9 +2477,8 @@ qla1280_setup_chip(struct scsi_qla_host *ha)
int risc_code_size;
uint16_t mb[MAILBOX_REGISTER_COUNT];
uint16_t cnt;
- int num;
+ int num, i;
#if DUMP_IT_BACK
- int i;
uint8_t *sp;
uint8_t *tbuf;
dma_addr_t p_tbuf;
@@ -2668,7 +2486,8 @@ qla1280_setup_chip(struct scsi_qla_host *ha)
ENTER("qla1280_setup_chip");
- /* 3.13 */
+ dprintk(1, "scsi(%ld): Setup chip\n", ha->host_no);
+
#if DUMP_IT_BACK
/* get consistent memory allocated for setup_chip */
tbuf = pci_alloc_consistent(ha->pdev, 8000, &p_tbuf);
@@ -2691,7 +2510,7 @@ qla1280_setup_chip(struct scsi_qla_host *ha)
if (cnt > risc_code_size)
cnt = risc_code_size;
- dprintk(1, "qla1280_setup_chip: loading risc @ =(0x%p),"
+ dprintk(2, "qla1280_setup_chip: loading risc @ =(0x%p),"
"%d,%d(0x%x)\n",
risc_code_address, cnt, num, risc_address);
for(i = 0; i < cnt; i++)
@@ -2703,18 +2522,18 @@ qla1280_setup_chip(struct scsi_qla_host *ha)
mb[0] = MBC_LOAD_RAM;
mb[1] = risc_address;
mb[4] = cnt;
- mb[3] = qla1280_addr0_15(ha->request_dma);
- mb[2] = qla1280_addr16_31(ha->request_dma);
- mb[7] = qla1280_addr32_47(ha->request_dma);
- mb[6] = qla1280_addr48_63(ha->request_dma);
- dprintk(1, "qla1280_setup_chip: op=%d 0x%p = 0x%4x,0x%4x,"
- "0x%4x,0x%4x\n",
- mb[0], (void *)ha->request_dma, mb[6], mb[7], mb[2], mb[3]);
+ mb[3] = ha->request_dma & 0xffff;
+ mb[2] = (ha->request_dma >> 16) & 0xffff;
+ mb[7] = pci_dma_hi32(ha->request_dma) & 0xffff;
+ mb[6] = pci_dma_hi32(ha->request_dma) >> 16;
+ dprintk(2, "qla1280_setup_chip: op=%d 0x%p = 0x%4x,0x%4x,"
+ "0x%4x,0x%4x\n", mb[0], (void *)(long)ha->request_dma,
+ mb[6], mb[7], mb[2], mb[3]);
if ((status = qla1280_mailbox_command(ha, BIT_4 | BIT_3 |
BIT_2 | BIT_1 | BIT_0,
&mb[0]))) {
- printk(KERN_ERR
- "Failed to load partial segment of f/w\n");
+ printk(KERN_ERR "scsi(%li): Failed to load partial "
+ "segment of f\n", ha->host_no);
break;
}
@@ -2722,10 +2541,10 @@ qla1280_setup_chip(struct scsi_qla_host *ha)
mb[0] = MBC_DUMP_RAM;
mb[1] = risc_address;
mb[4] = cnt;
- mb[3] = qla1280_addr0_15(p_tbuf);
- mb[2] = qla1280_addr16_31(p_tbuf);
- mb[7] = qla1280_addr32_47(p_tbuf);
- mb[6] = qla1280_addr48_63(p_tbuf);
+ mb[3] = p_tbuf & 0xffff;
+ mb[2] = (p_tbuf >> 16) & 0xffff;
+ mb[7] = pci_dma_hi32(p_tbuf) & 0xffff;
+ mb[6] = pci_dma_hi32(p_tbuf) >> 16;
if ((status = qla1280_mailbox_command(ha,
BIT_4 | BIT_3 | BIT_2 |
@@ -2737,7 +2556,7 @@ qla1280_setup_chip(struct scsi_qla_host *ha)
}
sp = (uint8_t *)ha->request_ring;
for (i = 0; i < (cnt << 1); i++) {
- if (tbuf[i] != sp[i] &&warn++ < 10) {
+ if (tbuf[i] != sp[i] && warn++ < 10) {
printk(KERN_ERR "qla1280_setup_chip: FW "
"compare error @ byte(0x%x) loop#=%x\n",
i, num);
@@ -2770,11 +2589,10 @@ qla1280_setup_chip(struct scsi_qla_host *ha)
mb[1] = *ql1280_board_tbl[ha->devnum].fwstart;
qla1280_mailbox_command(ha, BIT_1 | BIT_0, &mb[0]);
} else
- printk(KERN_ERR
- "qla1280_setup_chip: Failed checksum.\n");
+ printk(KERN_ERR "scsi(%li): qla1280_setup_chip: "
+ "Failed checksum\n", ha->host_no);
}
- /* 3.13 */
#if DUMP_IT_BACK
/* free consistent memory allocated for setup_chip */
pci_free_consistent(ha->pdev, 8000, tbuf, p_tbuf);
@@ -2805,13 +2623,12 @@ qla1280_init_rings(struct scsi_qla_host *ha)
{
uint16_t mb[MAILBOX_REGISTER_COUNT];
int status = 0;
- int cnt;
ENTER("qla1280_init_rings");
/* Clear outstanding commands array. */
- for (cnt = 0; cnt < MAX_OUTSTANDING_COMMANDS; cnt++)
- ha->outstanding_cmds[cnt] = 0;
+ memset(ha->outstanding_cmds, 0,
+ sizeof(struct srb *) * MAX_OUTSTANDING_COMMANDS);
/* Initialize request queue. */
ha->request_ring_ptr = ha->request_ring;
@@ -2868,61 +2685,51 @@ static int
qla1280_nvram_config(struct scsi_qla_host *ha)
{
struct device_reg *reg = ha->iobase;
- nvram_t *nv = (nvram_t *)ha->response_ring;
- int status = 0;
- int cnt;
+ struct nvram *nv;
+ int is1x160, status = 0;
int bus, target, lun;
- uint16_t *wptr;
uint16_t mb[MAILBOX_REGISTER_COUNT];
- uint8_t chksum;
- int nvsize;
+ uint16_t mask;
-#if DEBUG_PRINT_NVRAM
- int saved_print_status = ql_debug_print;
-#endif
ENTER("qla1280_nvram_config");
- /* Verify valid NVRAM checksum. */
-#if USE_NVRAM_DEFAULTS
- chksum = 1;
-#else
- wptr = (uint16_t *) ha->response_ring;
- chksum = 0;
if (ha->device_id == PCI_DEVICE_ID_QLOGIC_ISP12160 ||
ha->device_id == PCI_DEVICE_ID_QLOGIC_ISP10160)
- nvsize = sizeof(nvram160_t) / 2;
+ is1x160 = 1;
else
- nvsize = sizeof(nvram_t) / 2;
- for (cnt = 0; cnt < nvsize; cnt++) {
- *wptr = qla1280_get_nvram_word(ha, cnt);
- chksum += (uint8_t) * wptr;
- chksum += (uint8_t) (*wptr >> 8);
- wptr++;
- }
-#endif
+ is1x160 = 0;
- /* Bad NVRAM data, set defaults parameters. */
- if (chksum || nv->id0 != 'I' || nv->id1 != 'S' ||
- nv->id2 != 'P' || nv->id3 != ' ' || nv->version < 1) {
-#if USE_NVRAM_DEFAULTS
- dprintk(1, "Using defaults for NVRAM\n");
-#else
+ nv = &ha->nvram;
+ if (!ha->nvram_valid) {
dprintk(1, "Using defaults for NVRAM: \n");
- dprintk(1, "checksum=0x%x, Id=%c, version=0x%x\n",
- chksum, nv->id[0], nv->version);
- memset(ha->response_ring, 0, sizeof(nvram_t));
-#endif
+ memset(nv, 0, sizeof(struct nvram));
/* nv->cntr_flags_1.disable_loading_risc_code = 1; */
- nv->firmware_feature.w = BIT_0;
+ nv->firmware_feature.f.enable_fast_posting = 1;
+ nv->firmware_feature.f.disable_synchronous_backoff = 1;
+
nv->termination.f.scsi_bus_0_control = 3;
nv->termination.f.scsi_bus_1_control = 3;
nv->termination.f.auto_term_support = 1;
+ /*
+ * Set default FIFO magic - What appropriate values
+ * would be here is unknown. This is what I have found
+ * testing with 12160s.
+ * Now, I would love the magic decoder ring for this one,
+ * the header file provided by QLogic seems to be bogus
+ * or incomplete at best.
+ */
+ nv->isp_config.c = 0x44;
+
+ if (is1x160)
+ nv->isp_parameter = 0x01;
+
for (bus = 0; bus < MAX_BUSES; bus++) {
nv->bus[bus].config_1.initiator_id = 7;
nv->bus[bus].bus_reset_delay = 5;
- nv->bus[bus].config_2.async_data_setup_time = 9;
+ /* 8 = 5.0 clocks */
+ nv->bus[bus].config_2.async_data_setup_time = 8;
nv->bus[bus].config_2.req_ack_active_negation = 1;
nv->bus[bus].config_2.data_line_active_negation = 1;
nv->bus[bus].selection_timeout = 250;
@@ -2930,21 +2737,46 @@ qla1280_nvram_config(struct scsi_qla_host *ha)
for (target = 0; target < MAX_TARGETS; target++) {
nv->bus[bus].target[target].parameter.f.
- auto_request_sense = 1;
+ renegotiate_on_error = 1;
nv->bus[bus].target[target].parameter.f.
- disconnect_allowed = 1;
+ auto_request_sense = 1;
nv->bus[bus].target[target].parameter.f.
tag_queuing = 1;
- nv->bus[bus].target[target].flags.
- device_enable = 1;
+ nv->bus[bus].target[target].parameter.f.
+ enable_sync = 1;
+#if 1 /* Some SCSI Processors do not seem to like this */
+ nv->bus[bus].target[target].parameter.f.
+ enable_wide = 1;
+#endif
+ nv->bus[bus].target[target].parameter.f.
+ parity_checking = 1;
+ nv->bus[bus].target[target].parameter.f.
+ disconnect_allowed = 1;
+ nv->bus[bus].target[target].execution_throttle=
+ nv->bus[bus].max_queue_depth - 1;
+ if (is1x160) {
+ nv->bus[bus].target[target].flags.
+ flags1x160.device_enable = 1;
+ nv->bus[bus].target[target].flags.
+ flags1x160.sync_offset = 0x0e;
+ nv->bus[bus].target[target].
+ sync_period = 9;
+ nv->bus[bus].target[target].
+ ppr_1x160.flags.enable_ppr = 1;
+ nv->bus[bus].target[target].ppr_1x160.
+ flags.ppr_options = 2;
+ nv->bus[bus].target[target].ppr_1x160.
+ flags.ppr_bus_width = 1;
+ } else {
+ nv->bus[bus].target[target].flags.
+ flags1x80.device_enable = 1;
+ nv->bus[bus].target[target].flags.
+ flags1x80.sync_offset = 0x8;
+ nv->bus[bus].target[target].
+ sync_period = 10;
+ }
}
}
-
-#if USE_NVRAM_DEFAULTS
- status = 0;
-#else
- status = 1;
-#endif
} else {
/* Always force AUTO sense for LINUX SCSI */
for (bus = 0; bus < MAX_BUSES; bus++)
@@ -2953,9 +2785,6 @@ qla1280_nvram_config(struct scsi_qla_host *ha)
auto_request_sense = 1;
}
}
-#if DEBUG_PRINT_NVRAM
- ql_debug_print = 1;
-#endif
dprintk(1, "qla1280 : initiator scsi id bus[0]=%d\n",
nv->bus[0].config_1.initiator_id);
dprintk(1, "qla1280 : initiator scsi id bus[1]=%d\n",
@@ -3016,33 +2845,50 @@ qla1280_nvram_config(struct scsi_qla_host *ha)
ha->flags.enable_64bit_addressing = 0;
#endif
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,18)
if (ha->flags.enable_64bit_addressing) {
- printk(KERN_INFO "scsi(%li): 64 Bit PCI Addressing Enabled\n",
- ha->host_no);
+ dprintk(2, "scsi(%li): 64 Bit PCI Addressing Enabled\n",
+ ha->host_no);
pci_set_dma_mask(ha->pdev, (dma_addr_t) ~ 0ULL);
}
-#endif
/* Set ISP hardware DMA burst */
mb[0] = nv->isp_config.c;
+ /* Enable DMA arbitration on dual channel controllers */
+ if (ha->ports > 1)
+ mb[0] |= BIT_13;
WRT_REG_WORD(&reg->cfg_1, mb[0]);
+#if 1 /* Is this safe? */
/* Set SCSI termination. */
WRT_REG_WORD(&reg->gpio_enable, (BIT_3 + BIT_2 + BIT_1 + BIT_0));
mb[0] = nv->termination.c & (BIT_3 + BIT_2 + BIT_1 + BIT_0);
WRT_REG_WORD(&reg->gpio_data, mb[0]);
+#endif
/* ISP parameter word. */
mb[0] = MBC_SET_SYSTEM_PARAMETER;
mb[1] = nv->isp_parameter;
status |= qla1280_mailbox_command(ha, BIT_1 | BIT_0, &mb[0]);
+#if 0
+ /* clock rate - for qla1240 and older, only */
+ mb[0] = MBC_SET_CLOCK_RATE;
+ mb[1] = 0x50;
+ status |= qla1280_mailbox_command(ha, BIT_1 | BIT_0, &mb[0]);
+#endif
/* Firmware feature word. */
mb[0] = MBC_SET_FIRMWARE_FEATURES;
- mb[1] = nv->firmware_feature.w & (BIT_1 | BIT_0);
- status |= qla1280_mailbox_command(ha, BIT_1 | BIT_0, &mb[0]);
+ mask = BIT_5 | BIT_1 | BIT_0;
+ mb[1] = le16_to_cpu(nv->firmware_feature.w) & (mask);
+#if defined(CONFIG_IA64_GENERIC) || defined (CONFIG_IA64_SGI_SN2)
+ if (ia64_platform_is("sn2")) {
+ printk(KERN_INFO "scsi(%li): Enabling SN2 PCI DMA "
+ "workaround\n", ha->host_no);
+ mb[1] |= BIT_9;
+ }
+#endif
+ status |= qla1280_mailbox_command(ha, mask, &mb[0]);
/* Retry count and delay. */
mb[0] = MBC_SET_RETRY_COUNT;
@@ -3050,9 +2896,8 @@ qla1280_nvram_config(struct scsi_qla_host *ha)
mb[2] = nv->bus[0].retry_delay;
mb[6] = nv->bus[1].retry_count;
mb[7] = nv->bus[1].retry_delay;
- status |=
- qla1280_mailbox_command(ha, BIT_7 | BIT_6 | BIT_2 | BIT_1 | BIT_0,
- &mb[0]);
+ status |= qla1280_mailbox_command(ha, BIT_7 | BIT_6 | BIT_2 |
+ BIT_1 | BIT_0, &mb[0]);
/* ASYNC data setup time. */
mb[0] = MBC_SET_ASYNC_DATA_SETUP;
@@ -3074,6 +2919,16 @@ qla1280_nvram_config(struct scsi_qla_host *ha)
mb[2] |= BIT_4;
status |= qla1280_mailbox_command(ha, BIT_2 | BIT_1 | BIT_0, &mb[0]);
+ mb[0] = MBC_SET_DATA_OVERRUN_RECOVERY;
+ mb[1] = 2; /* Reset SCSI bus and return all outstanding IO */
+ status |= qla1280_mailbox_command(ha, BIT_1 | BIT_0, &mb[0]);
+
+ /* thingy */
+ mb[0] = MBC_SET_PCI_CONTROL;
+ mb[1] = 2; /* Data DMA Channel Burst Enable */
+ mb[2] = 2; /* Command DMA Channel Burst Enable */
+ status |= qla1280_mailbox_command(ha, BIT_2 | BIT_1 | BIT_0, &mb[0]);
+
/* Selection timeout. */
mb[0] = MBC_SET_SELECTION_TIMEOUT;
mb[1] = nv->bus[0].selection_timeout;
@@ -3101,36 +2956,52 @@ qla1280_nvram_config(struct scsi_qla_host *ha)
/* Set target parameters. */
for (target = 0; target < MAX_TARGETS; target++) {
- uint8_t mr = BIT_3 | BIT_2 | BIT_1 | BIT_0;
+ uint8_t mr = BIT_2 | BIT_1 | BIT_0;
/* Set Target Parameters. */
mb[0] = MBC_SET_TARGET_PARAMETERS;
mb[1] = (uint16_t) (bus ? target | BIT_7 : target);
mb[1] <<= 8;
+ /*
+ * Do not enable wide, sync, and ppr for the initial
+ * INQUIRY run. We enable this later if we determine
+ * the target actually supports it.
+ */
+ nv->bus[bus].target[target].parameter.f.
+ auto_request_sense = 1;
+ nv->bus[bus].target[target].parameter.f.
+ stop_queue_on_check = 0;
+
+ if (is1x160)
+ nv->bus[bus].target[target].ppr_1x160.
+ flags.enable_ppr = 0;
+ /*
+ * No sync, wide, etc. while probing
+ */
+ mb[2] = (nv->bus[bus].target[target].parameter.c << 8)&
+ ~(TP_SYNC /*| TP_WIDE | TP_PPR*/);
- mb[2] = nv->bus[bus].target[target].parameter.c << 8;
- mb[2] |= TP_AUTO_REQUEST_SENSE;
- mb[2] &= ~TP_STOP_QUEUE;
-
- mb[3] =
- nv->bus[bus].target[target].flags.sync_offset << 8;
+ if (is1x160)
+ mb[3] = nv->bus[bus].target[target].flags.flags1x160.sync_offset << 8;
+ else
+ mb[3] = nv->bus[bus].target[target].flags.flags1x80.sync_offset << 8;
mb[3] |= nv->bus[bus].target[target].sync_period;
+ mr |= BIT_3;
+
+ /*
+ * We don't want to enable ppr etc. before we have
+ * determined that the target actually supports it
+ */
+#if 0
+ if (is1x160) {
+ mb[2] |= nv->bus[bus].target[target].ppr_1x160.flags.enable_ppr << 5;
- if (ha->device_id == PCI_DEVICE_ID_QLOGIC_ISP12160 ||
- ha->device_id == PCI_DEVICE_ID_QLOGIC_ISP10160) {
- nvram160_t *nv2 = (nvram160_t *) nv;
- mb[2] |=
- nv2->bus[bus].target[target].flags2.
- enable_ppr << 5;
-
- mb[6] =
- nv2->bus[bus].target[target].flags2.
- ppr_options << 8;
- mb[6] |=
- nv2->bus[bus].target[target].flags2.
- ppr_bus_width;
+ mb[6] = nv->bus[bus].target[target].ppr_1x160.flags.ppr_options << 8;
+ mb[6] |= nv->bus[bus].target[target].ppr_1x160.flags.ppr_bus_width;
mr |= BIT_6;
}
+#endif
+
status = qla1280_mailbox_command(ha, mr, &mb[0]);
/* Save Tag queuing enable flag. */
@@ -3139,12 +3010,18 @@ qla1280_nvram_config(struct scsi_qla_host *ha)
ha->bus_settings[bus].qtag_enables |= mb[0];
/* Save Device enable flag. */
- if (nv->bus[bus].target[target].flags.device_enable)
- ha->bus_settings[bus].device_enables |= mb[0];
-
- /* Save LUN disable flag. */
- if (nv->bus[bus].target[target].flags.lun_disable)
+ if (is1x160) {
+ if (nv->bus[bus].target[target].flags.flags1x160.device_enable)
+ ha->bus_settings[bus].device_enables |= mb[0];
+ ha->bus_settings[bus].lun_disables |= 0;
+ } else {
+ if (nv->bus[bus].target[target].flags.flags1x80.device_enable)
+ ha->bus_settings[bus].device_enables |= mb[0];
+ /* Save LUN disable flag. */
+ if (nv->bus[bus].target[target].flags.flags1x80.lun_disable)
ha->bus_settings[bus].lun_disables |= mb[0];
+ }
+
/* Set Device Queue Parameters. */
for (lun = 0; lun < MAX_LUNS; lun++) {
@@ -3153,19 +3030,12 @@ qla1280_nvram_config(struct scsi_qla_host *ha)
mb[1] = mb[1] << 8 | lun;
mb[2] = nv->bus[bus].max_queue_depth;
mb[3] = nv->bus[bus].target[target].execution_throttle;
- status |=
- qla1280_mailbox_command(ha,
- BIT_3 | BIT_2 |
- BIT_1 | BIT_0,
- &mb[0]);
+ status |= qla1280_mailbox_command(ha, 0x0f,
+ &mb[0]);
}
}
}
-#if DEBUG_PRINT_NVRAM
- ql_debug_print = saved_print_status;
-#endif
-
if (status)
dprintk(2, "qla1280_nvram_config: **** FAILED ****\n");
@@ -3191,24 +3061,13 @@ qla1280_get_nvram_word(struct scsi_qla_host *ha, uint32_t address)
uint32_t nv_cmd;
uint16_t data;
-#ifdef QL_DEBUG_ROUTINES
- int saved_print_status = ql_debug_print;
-#endif
-
nv_cmd = address << 16;
nv_cmd |= NV_READ_OP;
-#ifdef QL_DEBUG_ROUTINES
- ql_debug_print = FALSE;
-#endif
- data = qla1280_nvram_request(ha, nv_cmd);
-#ifdef QL_DEBUG_ROUTINES
- ql_debug_print = saved_print_status;
-#endif
+ data = le16_to_cpu(qla1280_nvram_request(ha, nv_cmd));
- dprintk(4,
- "qla1280_get_nvram_word: exiting normally NVRAM data = 0x%x",
- data);
+ dprintk(8, "qla1280_get_nvram_word: exiting normally NVRAM data = "
+ "0x%x", data);
return data;
}
@@ -3250,18 +3109,21 @@ qla1280_nvram_request(struct scsi_qla_host *ha, uint32_t nv_cmd)
for (cnt = 0; cnt < 16; cnt++) {
WRT_REG_WORD(&reg->nvram, (NV_SELECT | NV_CLOCK));
+ RD_REG_WORD(&reg->id_l); /* Flush PCI write */
NVRAM_DELAY();
data <<= 1;
reg_data = RD_REG_WORD(&reg->nvram);
if (reg_data & NV_DATA_IN)
data |= BIT_0;
WRT_REG_WORD(&reg->nvram, NV_SELECT);
+ RD_REG_WORD(&reg->id_l); /* Flush PCI write */
NVRAM_DELAY();
}
/* Deselect chip. */
WRT_REG_WORD(&reg->nvram, NV_DESELECT);
+ RD_REG_WORD(&reg->id_l); /* Flush PCI write */
NVRAM_DELAY();
return data;
@@ -3273,10 +3135,13 @@ qla1280_nv_write(struct scsi_qla_host *ha, uint16_t data)
struct device_reg *reg = ha->iobase;
WRT_REG_WORD(&reg->nvram, data | NV_SELECT);
+ RD_REG_WORD(&reg->id_l); /* Flush PCI write */
NVRAM_DELAY();
WRT_REG_WORD(&reg->nvram, data | NV_SELECT | NV_CLOCK);
+ RD_REG_WORD(&reg->id_l); /* Flush PCI write */
NVRAM_DELAY();
WRT_REG_WORD(&reg->nvram, data | NV_SELECT);
+ RD_REG_WORD(&reg->id_l); /* Flush PCI write */
NVRAM_DELAY();
}
@@ -3296,29 +3161,32 @@ qla1280_nv_write(struct scsi_qla_host *ha, uint16_t data)
* 0 = success
*/
static int
-qla1280_mailbox_command(struct scsi_qla_host *ha, uint8_t mr, uint16_t * mb)
+qla1280_mailbox_command(struct scsi_qla_host *ha, uint8_t mr, uint16_t *mb)
{
struct device_reg *reg = ha->iobase;
#if 0
- srb_t *done_q_first = 0;
- srb_t *done_q_last = 0;
+ struct srb *done_q_first = 0;
+ struct srb *done_q_last = 0;
#endif
int status = 0;
int cnt;
uint16_t *optr, *iptr;
uint16_t data;
+ DECLARE_COMPLETION(wait);
+ struct timer_list timer;
ENTER("qla1280_mailbox_command");
- ha->flags.mbox_busy = TRUE;
+ ha->flags.mbox_busy = 1;
+
+ if (ha->mailbox_wait) {
+ printk(KERN_ERR "Warning mailbox wait already in use!\n");
+ }
+ ha->mailbox_wait = &wait;
- if (!ha->flags.ints_enabled)
- printk(KERN_DEBUG
- "Running qla1280_mailbox_command() with interrupts "
- "disabled!\n");
/*
- * We really should start out by verifying that the mailbox is available
- * before starting sending the command data
+ * We really should start out by verifying that the mailbox is
+ * available before starting sending the command data
*/
/* Load mailbox registers. */
optr = (uint16_t *) &reg->mailbox0;
@@ -3334,41 +3202,44 @@ qla1280_mailbox_command(struct scsi_qla_host *ha, uint8_t mr, uint16_t * mb)
}
/* Issue set host interrupt command. */
- ha->flags.mbox_int = FALSE;
- ha->flags.mbox_busy = FALSE;
+ ha->flags.mbox_busy = 0;
+
+ /* set up a timer just in case we're really jammed */
+ init_timer(&timer);
+ timer.expires = jiffies + 20*HZ;
+ timer.data = (unsigned long)ha;
+ timer.function = qla1280_mailbox_timeout;
+ add_timer(&timer);
+
+#if LINUX_VERSION_CODE < 0x020500
+ spin_unlock_irq(HOST_LOCK);
+#endif
WRT_REG_WORD(&reg->host_cmd, HC_SET_HOST_INT);
data = qla1280_debounce_register(&reg->istatus);
- /*
- * This is insane - instead of looping to wait for the interrupt
- * to appear and run the handler (this is insane!!), use a waitqueue
- * and go to sleep.
- *
- * We are never called here from interrupt context anyway! /Jes
- */
- /* Wait for 30 seconds for command to finish. */
- for (cnt = 30000000; cnt > 0 && !ha->flags.mbox_int; cnt--) {
- /* Check for pending interrupts. */
-#if 0
- if (data & RISC_INT) {
- qla1280_isr(ha, &done_q_first, &done_q_last);
- } else
+ wait_for_completion(&wait);
+ del_timer_sync(&timer);
+
+#if LINUX_VERSION_CODE < 0x020500
+ spin_lock_irq(HOST_LOCK);
#endif
- udelay(1);
- data = RD_REG_WORD(&reg->istatus);
- }
+ ha->mailbox_wait = NULL;
/* Check for mailbox command timeout. */
- if (!cnt) {
- printk(KERN_WARNING
- "qla1280_mailbox_command: **** Command Timeout, "
- "mailbox0 = 0x%x****\n", mb[0]);
-
- ha->flags.isp_abort_needed = TRUE;
- status = 1;
- } else if (ha->mailbox_out[0] != MBS_CMD_CMP)
+ if (ha->mailbox_out[0] != MBS_CMD_CMP) {
+ printk(KERN_WARNING "qla1280_mailbox_command: Command failed, "
+ "mailbox0 = 0x%04x, mailbox_out0 = 0x%04x, istatus = "
+ "0x%04x\n",
+ mb[0], ha->mailbox_out[0], RD_REG_WORD(&reg->istatus));
+ printk(KERN_WARNING "m0 %04x, m1 %04x, m2 %04x, m3 %04x\n",
+ RD_REG_WORD(&reg->mailbox0), RD_REG_WORD(&reg->mailbox1),
+ RD_REG_WORD(&reg->mailbox2), RD_REG_WORD(&reg->mailbox3));
+ printk(KERN_WARNING "m4 %04x, m5 %04x, m6 %04x, m7 %04x\n",
+ RD_REG_WORD(&reg->mailbox4), RD_REG_WORD(&reg->mailbox5),
+ RD_REG_WORD(&reg->mailbox6), RD_REG_WORD(&reg->mailbox7));
status = 1;
+ }
/* Load return mailbox registers. */
optr = mb;
@@ -3381,9 +3252,6 @@ qla1280_mailbox_command(struct scsi_qla_host *ha, uint8_t mr, uint16_t * mb)
qla1280_isr(ha, &done_q_first, &done_q_last);
#endif
- if (ha->flags.isp_abort_needed)
- qla1280_abort_isp(ha);
-
if (ha->flags.reset_marker)
qla1280_rst_aen(ha);
@@ -3393,9 +3261,8 @@ qla1280_mailbox_command(struct scsi_qla_host *ha, uint8_t mr, uint16_t * mb)
#endif
if (status)
- dprintk(2,
- "qla1280_mailbox_command: **** FAILED, mailbox0 = 0x%x "
- "****n", mb[0]);
+ dprintk(2, "qla1280_mailbox_command: **** FAILED, mailbox0 = "
+ "0x%x ****\n", mb[0]);
LEAVE("qla1280_mailbox_command");
return status;
@@ -3413,8 +3280,8 @@ qla1280_poll(struct scsi_qla_host *ha)
{
struct device_reg *reg = ha->iobase;
uint16_t data;
- srb_t *done_q_first = 0;
- srb_t *done_q_last = 0;
+ struct srb *done_q_first = 0;
+ struct srb *done_q_last = 0;
/* ENTER("qla1280_poll"); */
@@ -3424,8 +3291,6 @@ qla1280_poll(struct scsi_qla_host *ha)
qla1280_isr(ha, &done_q_first, &done_q_last);
if (!ha->flags.mbox_busy) {
- if (ha->flags.isp_abort_needed)
- qla1280_abort_isp(ha);
if (ha->flags.reset_marker)
qla1280_rst_aen(ha);
}
@@ -3451,38 +3316,42 @@ static int
qla1280_bus_reset(struct scsi_qla_host *ha, int bus)
{
uint16_t mb[MAILBOX_REGISTER_COUNT];
+ uint16_t reset_delay;
int status;
dprintk(3, "qla1280_bus_reset: entered\n");
if (qla1280_verbose)
- printk(KERN_INFO "scsi(%li): Resetting SCSI BUS (%i)\n",
+ printk(KERN_INFO "scsi(%li:%i): Resetting SCSI BUS\n",
ha->host_no, bus);
+ reset_delay = ha->bus_settings[bus].bus_reset_delay;
mb[0] = MBC_BUS_RESET;
- mb[1] = ha->bus_settings[bus].bus_reset_delay;
+ mb[1] = reset_delay;
mb[2] = (uint16_t) bus;
status = qla1280_mailbox_command(ha, BIT_2 | BIT_1 | BIT_0, &mb[0]);
if (status) {
- if (ha->bus_settings[bus].failed_reset_count > 2) /* dg - 03/13/99 */
- ha->bus_settings[bus].scsi_bus_dead = TRUE;
+ if (ha->bus_settings[bus].failed_reset_count > 2)
+ ha->bus_settings[bus].scsi_bus_dead = 1;
ha->bus_settings[bus].failed_reset_count++;
} else {
- /*
- * Eeeeep! This is evil! /Jes
- */
-#if 0
- mdelay(4000);
-#else
- schedule_timeout(4 * HZ);
-#endif
- ha->bus_settings[bus].scsi_bus_dead = FALSE; /* dg - 03/13/99 */
+ spin_unlock_irq(HOST_LOCK);
+ schedule_timeout(reset_delay * HZ);
+ spin_lock_irq(HOST_LOCK);
+
+ ha->bus_settings[bus].scsi_bus_dead = 0;
ha->bus_settings[bus].failed_reset_count = 0;
+ ha->bus_settings[bus].reset_marker = 0;
/* Issue marker command. */
qla1280_marker(ha, bus, 0, 0, MK_SYNC_ALL);
}
+ /*
+ * We should probably call qla1280_set_target_parameters()
+ * here as well for all devices on the bus.
+ */
+
if (status)
dprintk(2, "qla1280_bus_reset: **** FAILED ****\n");
else
@@ -3573,35 +3442,31 @@ qla1280_abort_device(struct scsi_qla_host *ha, int bus, int target, int lun)
* 0 = success
*/
static int
-qla1280_abort_command(struct scsi_qla_host *ha, srb_t * sp)
+qla1280_abort_command(struct scsi_qla_host *ha, struct srb * sp, int handle)
{
uint16_t mb[MAILBOX_REGISTER_COUNT];
unsigned int bus, target, lun;
- uint32_t handle;
int status;
ENTER("qla1280_abort_command");
- /* Locate handle number. */
- for (handle = 0; handle < MAX_OUTSTANDING_COMMANDS; handle++)
- if (ha->outstanding_cmds[handle] == sp)
- break;
-
bus = SCSI_BUS_32(sp->cmd);
target = SCSI_TCN_32(sp->cmd);
lun = SCSI_LUN_32(sp->cmd);
+ sp->flags |= SRB_ABORT_PENDING;
+
mb[0] = MBC_ABORT_COMMAND;
mb[1] = (bus ? target | BIT_7 : target) << 8 | lun;
mb[2] = handle >> 16;
mb[3] = handle & 0xffff;
- status =
- qla1280_mailbox_command(ha, BIT_3 | BIT_2 | BIT_1 | BIT_0, &mb[0]);
+ status = qla1280_mailbox_command(ha, 0x0f, &mb[0]);
- if (status)
+ if (status) {
dprintk(2, "qla1280_abort_command: **** FAILED ****\n");
+ sp->flags &= ~SRB_ABORT_PENDING;
+ }
- sp->flags |= SRB_ABORT_PENDING;
LEAVE("qla1280_abort_command");
return status;
@@ -3622,11 +3487,11 @@ qla1280_reset_adapter(struct scsi_qla_host *ha)
ENTER("qla1280_reset_adapter");
/* Disable ISP chip */
- ha->flags.online = FALSE;
+ ha->flags.online = 0;
WRT_REG_WORD(&reg->ictrl, ISP_RESET);
- WRT_REG_WORD(&reg->host_cmd, HC_RESET_RISC);
- WRT_REG_WORD(&reg->host_cmd, HC_RELEASE_RISC);
- WRT_REG_WORD(&reg->host_cmd, HC_DISABLE_BIOS);
+ WRT_REG_WORD(&reg->host_cmd,
+ HC_RESET_RISC | HC_RELEASE_RISC | HC_DISABLE_BIOS);
+ RD_REG_WORD(&reg->id_l); /* Flush PCI write */
LEAVE("qla1280_reset_adapter");
}
@@ -3645,16 +3510,17 @@ qla1280_reset_adapter(struct scsi_qla_host *ha)
static void
qla1280_marker(struct scsi_qla_host *ha, int bus, int id, int lun, u8 type)
{
- mrk_entry_t *pkt;
+ struct mrk_entry *pkt;
ENTER("qla1280_marker");
/* Get request packet. */
- if ((pkt = (mrk_entry_t *) qla1280_req_pkt(ha))) {
+ if ((pkt = (struct mrk_entry *) qla1280_req_pkt(ha))) {
pkt->entry_type = MARKER_TYPE;
pkt->lun = (uint8_t) lun;
pkt->target = (uint8_t) (bus ? (id | BIT_7) : id);
pkt->modifier = type;
+ pkt->entry_status = 0;
/* Issue command to ISP */
qla1280_isp_cmd(ha);
@@ -3663,7 +3529,7 @@ qla1280_marker(struct scsi_qla_host *ha, int bus, int id, int lun, u8 type)
LEAVE("qla1280_marker");
}
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,3,18)
+
/*
* qla1280_64bit_start_scsi
* The start SCSI is responsible for building request packets on
@@ -3677,7 +3543,7 @@ qla1280_marker(struct scsi_qla_host *ha, int bus, int id, int lun, u8 type)
* 0 = success, was able to issue command.
*/
static int
-qla1280_64bit_start_scsi(struct scsi_qla_host *ha, srb_t * sp)
+qla1280_64bit_start_scsi(struct scsi_qla_host *ha, struct srb * sp)
{
struct device_reg *reg = ha->iobase;
Scsi_Cmnd *cmd = sp->cmd;
@@ -3692,15 +3558,12 @@ qla1280_64bit_start_scsi(struct scsi_qla_host *ha, srb_t * sp)
ENTER("qla1280_64bit_start_scsi:");
- dprintk(1, "64bit_start: cmd=%p sp=%p CDB=%x\n", cmd, sp,
- cmd->cmnd[0]);
-
/* Calculate number of entries and segments required. */
req_cnt = 1;
- if (cmd->use_sg) { /* 3.13 64 bit */
+ if (cmd->use_sg) {
sg = (struct scatterlist *) cmd->request_buffer;
- seg_cnt = pci_map_sg (ha->pdev, sg, cmd->use_sg,
- scsi_to_pci_dma_dir(cmd->sc_data_direction));
+ seg_cnt = pci_map_sg(ha->pdev, sg, cmd->use_sg,
+ scsi_to_pci_dma_dir(cmd->sc_data_direction));
if (seg_cnt > 2) {
req_cnt += (seg_cnt - 2) / 5;
@@ -3724,220 +3587,218 @@ qla1280_64bit_start_scsi(struct scsi_qla_host *ha, srb_t * sp)
}
/* If room for request in request ring. */
- if ((req_cnt + 2) < ha->req_q_cnt) {
- /* Check for room in outstanding command list. */
- for (cnt = 1; cnt < MAX_OUTSTANDING_COMMANDS &&
- ha->outstanding_cmds[cnt] != 0; cnt++) ;
+ if ((req_cnt + 2) >= ha->req_q_cnt) {
+ status = 1;
+ dprintk(2, "qla1280_64bit_start_scsi: in-ptr=0x%x req_q_cnt="
+ "0x%xreq_cnt=0x%x", ha->req_ring_index, ha->req_q_cnt,
+ req_cnt);
+ goto out;
+ }
- if (cnt < MAX_OUTSTANDING_COMMANDS) {
- ha->outstanding_cmds[cnt] = sp;
- ha->req_q_cnt -= req_cnt;
- CMD_HANDLE(sp->cmd) =
- (unsigned char *)(unsigned long)cnt;
+ /* Check for room in outstanding command list. */
+ for (cnt = 0; cnt < MAX_OUTSTANDING_COMMANDS &&
+ ha->outstanding_cmds[cnt] != 0; cnt++);
- /*
- * Build command packet.
- */
- pkt = (cmd_a64_entry_t *) ha->request_ring_ptr;
+ if (cnt >= MAX_OUTSTANDING_COMMANDS) {
+ status = 1;
+ dprintk(2, "qla1280_64bit_start_scsi: NO ROOM IN "
+ "OUTSTANDING ARRAY, req_q_cnt=0x%x", ha->req_q_cnt);
+ goto out;
+ }
- pkt->entry_type = COMMAND_A64_TYPE;
- pkt->entry_count = (uint8_t) req_cnt;
- pkt->sys_define = (uint8_t) ha->req_ring_index;
- pkt->handle = cpu_to_le32(cnt);
+ ha->outstanding_cmds[cnt] = sp;
+ ha->req_q_cnt -= req_cnt;
+ CMD_HANDLE(sp->cmd) = (unsigned char *)(unsigned long)(cnt + 1);
+
+ dprintk(2, "64bit_start: cmd=%p sp=%p CDB=%xm, handle %lx\n", cmd, sp,
+ cmd->cmnd[0], (long)CMD_HANDLE(sp->cmd));
+ dprintk(2, " bus %i, target %i, lun %i\n",
+ SCSI_BUS_32(cmd), SCSI_TCN_32(cmd), SCSI_LUN_32(cmd));
+ qla1280_dump_buffer(2, cmd->cmnd, MAX_COMMAND_SIZE);
+
+ /*
+ * Build command packet.
+ */
+ pkt = (cmd_a64_entry_t *) ha->request_ring_ptr;
+
+ pkt->entry_type = COMMAND_A64_TYPE;
+ pkt->entry_count = (uint8_t) req_cnt;
+ pkt->sys_define = (uint8_t) ha->req_ring_index;
+ pkt->entry_status = 0;
+ pkt->handle = cpu_to_le32(cnt);
- /* Zero out remaining portion of packet. */
- memset(((char *)pkt + 8), 0, (REQUEST_ENTRY_SIZE - 8));
+ /* Zero out remaining portion of packet. */
+ memset(((char *)pkt + 8), 0, (REQUEST_ENTRY_SIZE - 8));
- /* Set ISP command timeout. */
- pkt->timeout = cpu_to_le16(30);
+ /* Set ISP command timeout. */
+ pkt->timeout = cpu_to_le16(30);
- /* Set device target ID and LUN */
- pkt->lun = SCSI_LUN_32(cmd);
- pkt->target = SCSI_BUS_32(cmd) ?
- (SCSI_TCN_32(cmd) | BIT_7) : SCSI_TCN_32(cmd);
+ /* Set device target ID and LUN */
+ pkt->lun = SCSI_LUN_32(cmd);
+ pkt->target = SCSI_BUS_32(cmd) ?
+ (SCSI_TCN_32(cmd) | BIT_7) : SCSI_TCN_32(cmd);
- /* Enable simple tag queuing if device supports it. */
- if (cmd->device->tagged_queue)
- pkt->control_flags |= cpu_to_le16(BIT_3);
+ /* Enable simple tag queuing if device supports it. */
+ if (cmd->device->tagged_queue)
+ pkt->control_flags |= cpu_to_le16(BIT_3);
- /* Load SCSI command packet. */
- pkt->cdb_len = cpu_to_le16(CMD_CDBLEN(cmd));
- memcpy(pkt->scsi_cdb, &(CMD_CDBP(cmd)), CMD_CDBLEN(cmd));
- /* dprintk(1, "Build packet for command[0]=0x%x\n",pkt->scsi_cdb[0]); */
+ /* Load SCSI command packet. */
+ pkt->cdb_len = cpu_to_le16(CMD_CDBLEN(cmd));
+ memcpy(pkt->scsi_cdb, &(CMD_CDBP(cmd)), CMD_CDBLEN(cmd));
+ /* dprintk(1, "Build packet for command[0]=0x%x\n",pkt->scsi_cdb[0]); */
- /* Set transfer direction. */
- sp->dir = qla1280_data_direction(cmd);
- pkt->control_flags |= cpu_to_le16(sp->dir);
-
- /* Set total data segment count. */
- pkt->dseg_count = cpu_to_le16(seg_cnt);
+ /* Set transfer direction. */
+ sp->dir = qla1280_data_direction(cmd);
+ pkt->control_flags |= cpu_to_le16(sp->dir);
+
+ /* Set total data segment count. */
+ pkt->dseg_count = cpu_to_le16(seg_cnt);
+
+ /*
+ * Load data segments.
+ */
+ if (seg_cnt) { /* If data transfer. */
+ /* Setup packet address segment pointer. */
+ dword_ptr = (u32 *)&pkt->dseg_0_address;
+
+ if (cmd->use_sg) { /* If scatter gather */
+ /* Load command entry data segments. */
+ for (cnt = 0; cnt < 2 && seg_cnt; cnt++, seg_cnt--) {
+ dma_handle = sg_dma_address(sg);
+#if defined(CONFIG_IA64_GENERIC) || defined(CONFIG_IA64_SGI_SN2)
+ if (ha->flags.use_pci_vchannel)
+ sn_pci_set_vchan(ha->pdev, &dma_handle,
+ SCSI_BUS_32(cmd));
+#endif
+ *dword_ptr++ =
+ cpu_to_le32(pci_dma_lo32(dma_handle));
+ *dword_ptr++ =
+ cpu_to_le32(pci_dma_hi32(dma_handle));
+ *dword_ptr++ = cpu_to_le32(sg_dma_len(sg));
+ sg++;
+ dprintk(3, "S/G Segment phys_addr=%x %x, len=0x%x\n",
+ cpu_to_le32(pci_dma_hi32(dma_handle)),
+ cpu_to_le32(pci_dma_lo32(dma_handle)),
+ cpu_to_le32(sg_dma_len(sg)));
+ }
+ dprintk(5, "qla1280_64bit_start_scsi: Scatter/gather "
+ "command packet data - b %i, t %i, l %i \n",
+ SCSI_BUS_32(cmd), SCSI_TCN_32(cmd),
+ SCSI_LUN_32(cmd));
+ qla1280_dump_buffer(5, (char *)pkt,
+ REQUEST_ENTRY_SIZE);
/*
- * Load data segments.
+ * Build continuation packets.
*/
- if (seg_cnt) { /* If data transfer. */
- /* Setup packet address segment pointer. */
- dword_ptr = (u32 *)&pkt->dseg_0_address;
-
- if (cmd->use_sg) { /* If scatter gather */
- /* Load command entry data segments. */
- for (cnt = 0; cnt < 2 && seg_cnt;
- cnt++, seg_cnt--) {
- /* 3.13 64 bit */
- *dword_ptr++ =
- cpu_to_le32(pci_dma_lo32(sg_dma_address(sg)));
- *dword_ptr++ =
- cpu_to_le32(pci_dma_hi32(sg_dma_address(sg)));
- *dword_ptr++ =
- cpu_to_le32(sg_dma_len(sg));
- sg++;
- dprintk(1,
- "S/G Segment phys_addr=%x %x, len=0x%x\n",
- cpu_to_le32(pci_dma_hi32(sg_dma_address(sg))),
- cpu_to_le32(pci_dma_lo32(sg_dma_address(sg))),
- cpu_to_le32(sg_dma_len(sg)));
- }
- dprintk(5,
- "qla1280_64bit_start_scsi: Scatter/gather "
- "command packet data - b %i, t %i, l %i \n",
- SCSI_BUS_32(cmd),
- SCSI_TCN_32(cmd),
- SCSI_LUN_32(cmd));
- qla1280_dump_buffer(5, (char *)pkt,
- REQUEST_ENTRY_SIZE);
+ dprintk(3, "S/G Building Continuation...seg_cnt=0x%x "
+ "remains\n", seg_cnt);
+
+ while (seg_cnt > 0) {
+ /* Adjust ring index. */
+ ha->req_ring_index++;
+ if (ha->req_ring_index == REQUEST_ENTRY_CNT) {
+ ha->req_ring_index = 0;
+ ha->request_ring_ptr =
+ ha->request_ring;
+ } else
+ ha->request_ring_ptr++;
- /*
- * Build continuation packets.
- */
- dprintk(1,
- "S/G Building Continuation...seg_cnt=0x%x "
- "remains\n", seg_cnt);
-
- while (seg_cnt > 0) {
- /* Adjust ring index. */
- ha->req_ring_index++;
- if (ha->req_ring_index ==
- REQUEST_ENTRY_CNT) {
- ha->req_ring_index = 0;
- ha->request_ring_ptr =
- ha->request_ring;
- } else
- ha->request_ring_ptr++;
-
- pkt = (cmd_a64_entry_t *)ha->request_ring_ptr;
-
- /* Zero out packet. */
- memset(pkt, 0,
- REQUEST_ENTRY_SIZE);
-
- /* Load packet defaults. */
- ((cont_a64_entry_t *) pkt)->entry_type =
- CONTINUE_A64_TYPE;
- ((cont_a64_entry_t *) pkt)->entry_count = 1;
- ((cont_a64_entry_t *) pkt)->sys_define =
- (uint8_t)ha->req_ring_index;
- /* Setup packet address segment pointer. */
- dword_ptr =
- (u32 *)&((cont_a64_entry_t *) pkt)->dseg_0_address;
-
- /* Load continuation entry data segments. */
- for (cnt = 0;
- cnt < 5 && seg_cnt;
- cnt++, seg_cnt--) {
- /* 3.13 64 bit */
- *dword_ptr++ =
- cpu_to_le32(pci_dma_lo32(sg_dma_address(sg)));
- *dword_ptr++ =
- cpu_to_le32(pci_dma_hi32(sg_dma_address(sg)));
- *dword_ptr++ =
- cpu_to_le32(sg_dma_len(sg));
- dprintk(1,
- "S/G Segment Cont. phys_addr=%x %x, len=0x%x\n",
- cpu_to_le32(pci_dma_hi32(sg_dma_address(sg))),
- cpu_to_le32(pci_dma_lo32(sg_dma_address(sg))),
- cpu_to_le32(sg_dma_len(sg)));
- sg++;
- }
- dprintk(5,
- "qla1280_64bit_start_scsi: continuation "
- "packet data - b %i, t %i, l %i \n",
- SCSI_BUS_32(cmd),
- SCSI_TCN_32(cmd),
- SCSI_LUN_32(cmd));
- qla1280_dump_buffer(5,
- (char *)pkt,
- REQUEST_ENTRY_SIZE);
- }
- } else { /* No scatter gather data transfer */
- /* 3.13 64 bit */
- dma_handle = pci_map_single(ha->pdev,
- cmd->request_buffer,
- cmd->request_bufflen,
- scsi_to_pci_dma_dir(cmd->sc_data_direction));
- /* save dma_handle for pci_unmap_single */
- sp->saved_dma_handle = dma_handle;
+ pkt = (cmd_a64_entry_t *)ha->request_ring_ptr;
+
+ /* Zero out packet. */
+ memset(pkt, 0, REQUEST_ENTRY_SIZE);
+ /* Load packet defaults. */
+ ((struct cont_a64_entry *) pkt)->entry_type =
+ CONTINUE_A64_TYPE;
+ ((struct cont_a64_entry *) pkt)->entry_count = 1;
+ ((struct cont_a64_entry *) pkt)->sys_define =
+ (uint8_t)ha->req_ring_index;
+ /* Setup packet address segment pointer. */
+ dword_ptr =
+ (u32 *)&((struct cont_a64_entry *) pkt)->dseg_0_address;
+
+ /* Load continuation entry data segments. */
+ for (cnt = 0; cnt < 5 && seg_cnt;
+ cnt++, seg_cnt--) {
+ dma_handle = sg_dma_address(sg);
+#if defined(CONFIG_IA64_GENERIC) || defined(CONFIG_IA64_SGI_SN2)
+ if (ha->flags.use_pci_vchannel)
+ sn_pci_set_vchan(ha->pdev, &dma_handle,
+ SCSI_BUS_32(cmd));
+#endif
*dword_ptr++ =
cpu_to_le32(pci_dma_lo32(dma_handle));
*dword_ptr++ =
cpu_to_le32(pci_dma_hi32(dma_handle));
- *dword_ptr =
- (uint32_t)cmd->request_bufflen;
- /* dprintk(1,
- "No S/G map_single saved_dma_handle=%lx\n",dma_handle);
- */
- dprintk(5,
- "qla1280_64bit_start_scsi: No scatter/gather "
- "command packet data - b %i, t %i, l %i \n",
- SCSI_BUS_32(cmd),
- SCSI_TCN_32(cmd),
- SCSI_LUN_32(cmd));
- qla1280_dump_buffer(5, (char *)pkt,
- REQUEST_ENTRY_SIZE);
+ *dword_ptr++ =
+ cpu_to_le32(sg_dma_len(sg));
+ dprintk(3, "S/G Segment Cont. phys_addr=%x %x, len=0x%x\n",
+ cpu_to_le32(pci_dma_hi32(dma_handle)),
+ cpu_to_le32(pci_dma_lo32(dma_handle)),
+ cpu_to_le32(sg_dma_len(sg)));
+ sg++;
}
- } else { /* No data transfer */
-
- dword_ptr = (uint32_t *)(pkt + 1);
- *dword_ptr++ = 0;
- *dword_ptr++ = 0;
- *dword_ptr = 0;
- dprintk(5,
- "qla1280_64bit_start_scsi: No data, command "
- "packet data - b %i, t %i, l %i \n",
- SCSI_BUS_32(cmd), SCSI_TCN_32(cmd),
- SCSI_LUN_32(cmd));
+ dprintk(5, "qla1280_64bit_start_scsi: "
+ "continuation packet data - b %i, t "
+ "%i, l %i \n", SCSI_BUS_32(cmd),
+ SCSI_TCN_32(cmd), SCSI_LUN_32(cmd));
qla1280_dump_buffer(5, (char *)pkt,
REQUEST_ENTRY_SIZE);
}
- /* Adjust ring index. */
- ha->req_ring_index++;
- if (ha->req_ring_index == REQUEST_ENTRY_CNT) {
- ha->req_ring_index = 0;
- ha->request_ring_ptr = ha->request_ring;
- } else
- ha->request_ring_ptr++;
-
- /* Set chip new ring index. */
- dprintk(1,
- "qla1280_64bit_start_scsi: Wakeup RISC for pending command\n");
- ha->qthreads--;
- sp->flags |= SRB_SENT;
- ha->actthreads++;
- WRT_REG_WORD(&reg->mailbox4, ha->req_ring_index);
- } else {
- status = 1;
- dprintk(2, "qla1280_64bit_start_scsi: NO ROOM IN "
- "OUTSTANDING ARRAY, req_q_cnt=0x%x",
- ha->req_q_cnt);
+ } else { /* No scatter gather data transfer */
+ struct page *page = virt_to_page(cmd->request_buffer);
+ unsigned long off = (unsigned long)cmd->request_buffer & ~PAGE_MASK;
+
+ dma_handle = pci_map_page(ha->pdev, page, off,
+ cmd->request_bufflen,
+ scsi_to_pci_dma_dir(cmd->sc_data_direction));
+
+ /* save dma_handle for pci_unmap_page */
+ sp->saved_dma_handle = dma_handle;
+#if defined(CONFIG_IA64_GENERIC) || defined(CONFIG_IA64_SGI_SN2)
+ if (ha->flags.use_pci_vchannel)
+ sn_pci_set_vchan(ha->pdev, &dma_handle,
+ SCSI_BUS_32(cmd));
+#endif
+ *dword_ptr++ = cpu_to_le32(pci_dma_lo32(dma_handle));
+ *dword_ptr++ = cpu_to_le32(pci_dma_hi32(dma_handle));
+ *dword_ptr = (uint32_t)cmd->request_bufflen;
+
+ dprintk(5, "qla1280_64bit_start_scsi: No scatter/"
+ "gather command packet data - b %i, t %i, "
+ "l %i \n", SCSI_BUS_32(cmd), SCSI_TCN_32(cmd),
+ SCSI_LUN_32(cmd));
+ qla1280_dump_buffer(5, (char *)pkt,
+ REQUEST_ENTRY_SIZE);
}
- } else {
- status = 1;
- dprintk(2,
- "qla1280_64bit_start_scsi: in-ptr=0x%x req_q_cnt=0x%x"
- "req_cnt=0x%x", ha->req_ring_index, ha->req_q_cnt,
- req_cnt);
+ } else { /* No data transfer */
+ dword_ptr = (uint32_t *)(pkt + 1);
+ *dword_ptr++ = 0;
+ *dword_ptr++ = 0;
+ *dword_ptr = 0;
+ dprintk(5, "qla1280_64bit_start_scsi: No data, command "
+ "packet data - b %i, t %i, l %i \n",
+ SCSI_BUS_32(cmd), SCSI_TCN_32(cmd), SCSI_LUN_32(cmd));
+ qla1280_dump_buffer(5, (char *)pkt, REQUEST_ENTRY_SIZE);
}
+ /* Adjust ring index. */
+ ha->req_ring_index++;
+ if (ha->req_ring_index == REQUEST_ENTRY_CNT) {
+ ha->req_ring_index = 0;
+ ha->request_ring_ptr = ha->request_ring;
+ } else
+ ha->request_ring_ptr++;
+
+ /* Set chip new ring index. */
+ dprintk(2,
+ "qla1280_64bit_start_scsi: Wakeup RISC for pending command\n");
+ sp->flags |= SRB_SENT;
+ ha->actthreads++;
+ WRT_REG_WORD(&reg->mailbox4, ha->req_ring_index);
+ out:
if (status)
dprintk(2, "qla1280_64bit_start_scsi: **** FAILED ****\n");
else
@@ -3945,7 +3806,7 @@ qla1280_64bit_start_scsi(struct scsi_qla_host *ha, srb_t * sp)
return status;
}
-#endif
+
/*
* qla1280_32bit_start_scsi
@@ -3967,11 +3828,11 @@ qla1280_64bit_start_scsi(struct scsi_qla_host *ha, srb_t * sp)
* 0 = success, was able to issue command.
*/
static int
-qla1280_32bit_start_scsi(struct scsi_qla_host *ha, srb_t * sp)
+qla1280_32bit_start_scsi(struct scsi_qla_host *ha, struct srb * sp)
{
struct device_reg *reg = ha->iobase;
Scsi_Cmnd *cmd = sp->cmd;
- cmd_entry_t *pkt;
+ struct cmd_entry *pkt;
struct scatterlist *sg = NULL;
uint32_t *dword_ptr;
int status = 0;
@@ -3989,15 +3850,14 @@ qla1280_32bit_start_scsi(struct scsi_qla_host *ha, srb_t * sp)
req_cnt = 1;
if (cmd->use_sg) {
/*
- * We must build an SG list in adapter format, as the kernel's SG list
- * cannot be used directly because of data field size (__alpha__)
- * differences and the kernel SG list uses virtual addresses where
- * we need physical addresses.
+ * We must build an SG list in adapter format, as the kernel's
+ * SG list cannot be used directly because of data field size
+ * (__alpha__) differences and the kernel SG list uses virtual
+ * addresses where we need physical addresses.
*/
sg = (struct scatterlist *) cmd->request_buffer;
- /* 3.13 32 bit */
- seg_cnt = pci_map_sg (ha->pdev, sg, cmd->use_sg,
- scsi_to_pci_dma_dir(cmd->sc_data_direction));
+ seg_cnt = pci_map_sg(ha->pdev, sg, cmd->use_sg,
+ scsi_to_pci_dma_dir(cmd->sc_data_direction));
/*
* if greater than four sg entries then we need to allocate
@@ -4008,10 +3868,10 @@ qla1280_32bit_start_scsi(struct scsi_qla_host *ha, srb_t * sp)
if ((seg_cnt - 4) % 7)
req_cnt++;
}
- dprintk(1, "S/G Transfer cmd=%p seg_cnt=0x%x, req_cnt=%x\n",
+ dprintk(3, "S/G Transfer cmd=%p seg_cnt=0x%x, req_cnt=%x\n",
cmd, seg_cnt, req_cnt);
} else if (cmd->request_bufflen) { /* If data transfer. */
- dprintk(1, "No S/G transfer t=%x cmd=%p len=%x CDB=%x\n",
+ dprintk(3, "No S/G transfer t=%x cmd=%p len=%x CDB=%x\n",
SCSI_TCN_32(cmd), cmd, cmd->request_bufflen,
cmd->cmnd[0]);
seg_cnt = 1;
@@ -4030,234 +3890,184 @@ qla1280_32bit_start_scsi(struct scsi_qla_host *ha, srb_t * sp)
REQUEST_ENTRY_CNT - (ha->req_ring_index - cnt);
}
- dprintk(1, "Number of free entries=(%d) seg_cnt=0x%x\n",
+ dprintk(3, "Number of free entries=(%d) seg_cnt=0x%x\n",
ha->req_q_cnt, seg_cnt);
/* If room for request in request ring. */
- if ((req_cnt + 2) < ha->req_q_cnt) {
- /* Check for empty slot in outstanding command list. */
- for (cnt = 1; cnt < MAX_OUTSTANDING_COMMANDS &&
- (ha->outstanding_cmds[cnt] != 0); cnt++) ;
+ if ((req_cnt + 2) >= ha->req_q_cnt) {
+ status = 1;
+ dprintk(2, "qla1280_32bit_start_scsi: in-ptr=0x%x, "
+ "req_q_cnt=0x%x, req_cnt=0x%x", ha->req_ring_index,
+ ha->req_q_cnt, req_cnt);
+ goto out;
+ }
- if (cnt < MAX_OUTSTANDING_COMMANDS) {
- CMD_HANDLE(sp->cmd) =
- (unsigned char *) (unsigned long) cnt;
- ha->outstanding_cmds[cnt] = sp;
- ha->req_q_cnt -= req_cnt;
+ /* Check for empty slot in outstanding command list. */
+ for (cnt = 0; cnt < MAX_OUTSTANDING_COMMANDS &&
+ (ha->outstanding_cmds[cnt] != 0); cnt++) ;
- /*
- * Build command packet.
- */
- pkt = (cmd_entry_t *) ha->request_ring_ptr;
+ if (cnt >= MAX_OUTSTANDING_COMMANDS) {
+ status = 1;
+ dprintk(2, "qla1280_32bit_start_scsi: NO ROOM IN OUTSTANDING "
+ "ARRAY, req_q_cnt=0x%x\n", ha->req_q_cnt);
+ goto out;
+ }
- pkt->entry_type = COMMAND_TYPE;
- pkt->entry_count = (uint8_t) req_cnt;
- pkt->sys_define = (uint8_t) ha->req_ring_index;
- pkt->handle = cpu_to_le32(cnt);
+ CMD_HANDLE(sp->cmd) = (unsigned char *) (unsigned long)(cnt + 1);
+ ha->outstanding_cmds[cnt] = sp;
+ ha->req_q_cnt -= req_cnt;
- /* Zero out remaining portion of packet. */
- memset(((char *)pkt + 8), 0, (REQUEST_ENTRY_SIZE - 8));
+ /*
+ * Build command packet.
+ */
+ pkt = (struct cmd_entry *) ha->request_ring_ptr;
- /* Set ISP command timeout. */
- pkt->timeout = cpu_to_le16(30);
+ pkt->entry_type = COMMAND_TYPE;
+ pkt->entry_count = (uint8_t) req_cnt;
+ pkt->sys_define = (uint8_t) ha->req_ring_index;
+ pkt->entry_status = 0;
+ pkt->handle = cpu_to_le32(cnt);
- /* Set device target ID and LUN */
- pkt->lun = SCSI_LUN_32(cmd);
- pkt->target = SCSI_BUS_32(cmd) ?
- (SCSI_TCN_32(cmd) | BIT_7) : SCSI_TCN_32(cmd);
+ /* Zero out remaining portion of packet. */
+ memset(((char *)pkt + 8), 0, (REQUEST_ENTRY_SIZE - 8));
- /* Enable simple tag queuing if device supports it. */
- if (cmd->device->tagged_queue)
- pkt->control_flags |= cpu_to_le16(BIT_3);
+ /* Set ISP command timeout. */
+ pkt->timeout = cpu_to_le16(30);
- /* Load SCSI command packet. */
- pkt->cdb_len = cpu_to_le16(CMD_CDBLEN(cmd));
- memcpy(pkt->scsi_cdb, &(CMD_CDBP(cmd)), CMD_CDBLEN(cmd));
+ /* Set device target ID and LUN */
+ pkt->lun = SCSI_LUN_32(cmd);
+ pkt->target = SCSI_BUS_32(cmd) ?
+ (SCSI_TCN_32(cmd) | BIT_7) : SCSI_TCN_32(cmd);
- /*dprintk(1, "Build packet for command[0]=0x%x\n",pkt->scsi_cdb[0]); */
- /* Set transfer direction. */
- sp->dir = qla1280_data_direction(cmd);
- pkt->control_flags |= cpu_to_le16(sp->dir);
-
- /* Set total data segment count. */
- pkt->dseg_count = cpu_to_le16(seg_cnt);
+ /* Enable simple tag queuing if device supports it. */
+ if (cmd->device->tagged_queue)
+ pkt->control_flags |= cpu_to_le16(BIT_3);
+ /* Load SCSI command packet. */
+ pkt->cdb_len = cpu_to_le16(CMD_CDBLEN(cmd));
+ memcpy(pkt->scsi_cdb, &(CMD_CDBP(cmd)), CMD_CDBLEN(cmd));
+
+ /*dprintk(1, "Build packet for command[0]=0x%x\n",pkt->scsi_cdb[0]); */
+ /* Set transfer direction. */
+ sp->dir = qla1280_data_direction(cmd);
+ pkt->control_flags |= cpu_to_le16(sp->dir);
+
+ /* Set total data segment count. */
+ pkt->dseg_count = cpu_to_le16(seg_cnt);
+
+ /*
+ * Load data segments.
+ */
+ if (seg_cnt) {
+ /* Setup packet address segment pointer. */
+ dword_ptr = &pkt->dseg_0_address;
+
+ if (cmd->use_sg) { /* If scatter gather */
+ dprintk(3, "Building S/G data segments..\n");
+ qla1280_dump_buffer(1, (char *)sg, 4 * 16);
+
+ /* Load command entry data segments. */
+ for (cnt = 0; cnt < 4 && seg_cnt; cnt++, seg_cnt--) {
+ *dword_ptr++ =
+ cpu_to_le32(pci_dma_lo32(sg_dma_address(sg)));
+ *dword_ptr++ =
+ cpu_to_le32(sg_dma_len(sg));
+ dprintk(3, "S/G Segment phys_addr=0x%lx, len=0x%x\n",
+ (pci_dma_lo32(sg_dma_address(sg))),
+ (sg_dma_len(sg)));
+ sg++;
+ }
/*
- * Load data segments.
+ * Build continuation packets.
*/
- if (seg_cnt) {
+ dprintk(3, "S/G Building Continuation"
+ "...seg_cnt=0x%x remains\n", seg_cnt);
+ while (seg_cnt > 0) {
+ /* Adjust ring index. */
+ ha->req_ring_index++;
+ if (ha->req_ring_index == REQUEST_ENTRY_CNT) {
+ ha->req_ring_index = 0;
+ ha->request_ring_ptr =
+ ha->request_ring;
+ } else
+ ha->request_ring_ptr++;
+
+ pkt = (struct cmd_entry *)ha->request_ring_ptr;
+
+ /* Zero out packet. */
+ memset(pkt, 0, REQUEST_ENTRY_SIZE);
+
+ /* Load packet defaults. */
+ ((struct cont_entry *) pkt)->
+ entry_type = CONTINUE_TYPE;
+ ((struct cont_entry *) pkt)->entry_count = 1;
+
+ ((struct cont_entry *) pkt)->sys_define =
+ (uint8_t) ha->req_ring_index;
+
/* Setup packet address segment pointer. */
- dword_ptr = &pkt->dseg_0_address;
-
- if (cmd->use_sg) { /* If scatter gather */
- dprintk(1, "Building S/G data "
- "segments..\n");
- qla1280_dump_buffer(1, (char *)sg,
- 4 * 16);
-
- /* Load command entry data segments. */
- for (cnt = 0; cnt < 4 && seg_cnt;
- cnt++, seg_cnt--) {
- /* 3.13 32 bit */
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,18)
- *dword_ptr++ =
- cpu_to_le32(virt_to_bus(sg->address));
- *dword_ptr++ = cpu_to_le32(sg->length);
- dprintk(1,
- "S/G Segment phys_addr=0x%x, len=0x%x\n",
- cpu_to_le32(virt_to_bus(sg->address)),
- sg->length);
-#else
- *dword_ptr++ =
- cpu_to_le32(pci_dma_lo32(sg_dma_address(sg)));
- *dword_ptr++ =
- cpu_to_le32(sg_dma_len(sg));
- dprintk(1, "S/G Segment phys_addr=0x%x, len=0x%x\n",
- (pci_dma_lo32(sg_dma_address(sg))),
- (sg_dma_len(sg)));
-#endif
- sg++;
- }
- /*
- * Build continuation packets.
- */
- dprintk(1, "S/G Building Continuation"
- "...seg_cnt=0x%x remains\n",
- seg_cnt);
- while (seg_cnt > 0) {
- /* Adjust ring index. */
- ha->req_ring_index++;
- if (ha->req_ring_index ==
- REQUEST_ENTRY_CNT) {
- ha->req_ring_index = 0;
- ha->request_ring_ptr =
- ha->request_ring;
- } else
- ha->request_ring_ptr++;
-
- pkt = (cmd_entry_t *)
- ha->request_ring_ptr;
-
- /* Zero out packet. */
- memset(pkt, 0,
- REQUEST_ENTRY_SIZE);
-
- /* Load packet defaults. */
- ((cont_entry_t *) pkt)->
- entry_type = CONTINUE_TYPE;
- ((cont_entry_t *) pkt)->
- entry_count = 1;
-
- ((cont_entry_t *) pkt)->
- sys_define =
- (uint8_t) ha->
- req_ring_index;
-
- /* Setup packet address segment pointer. */
- dword_ptr =
- &((cont_entry_t *) pkt)->dseg_0_address;
-
- /* Load continuation entry data segments. */
- for (cnt = 0;
- cnt < 7 && seg_cnt;
- cnt++, seg_cnt--) {
- /* 3.13 32 bit */
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,18)
- *dword_ptr++ =
- cpu_to_le32(virt_to_bus(sg->address));
- *dword_ptr++ = cpu_to_le32(sg->length);
- dprintk(1,
- "S/G Segment Cont. phys_addr=0x%x, len=0x%x\n",
- cpu_to_le32(pci_dma_lo32(virt_to_bus(sg->address))), sg->length);
-#else
- *dword_ptr++ =
- cpu_to_le32(pci_dma_lo32(sg_dma_address(sg)));
- *dword_ptr++ =
- cpu_to_le32(sg_dma_len(sg));
- dprintk(1,
- "S/G Segment Cont. phys_addr=0x%x, "
- "len=0x%x\n",
- cpu_to_le32(pci_dma_lo32(sg_dma_address(sg))),
- cpu_to_le32(sg_dma_len(sg)));
-#endif
- sg++;
- }
- dprintk(5,
- "qla1280_32bit_start_scsi: continuation "
- "packet data - scsi(%i:%i:%i)\n",
- SCSI_BUS_32(cmd),
- SCSI_TCN_32(cmd),
- SCSI_LUN_32(cmd));
- qla1280_dump_buffer(5,
- (char *)pkt,
- REQUEST_ENTRY_SIZE);
- }
- } else { /* No S/G data transfer */
+ dword_ptr =
+ &((struct cont_entry *) pkt)->dseg_0_address;
- /* 3.13 32 bit */
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,18)
+ /* Load continuation entry data segments. */
+ for (cnt = 0; cnt < 7 && seg_cnt;
+ cnt++, seg_cnt--) {
*dword_ptr++ =
- cpu_to_le32 (virt_to_bus
- (cmd->request_buffer));
-#else
- dma_handle = pci_map_single(ha->pdev,
- cmd->request_buffer,
- cmd->request_bufflen,
- scsi_to_pci_dma_dir(cmd->sc_data_direction));
- sp->saved_dma_handle = dma_handle;
-
+ cpu_to_le32(pci_dma_lo32(sg_dma_address(sg)));
*dword_ptr++ =
- cpu_to_le32(pci_dma_lo32(dma_handle));
-#endif
- *dword_ptr =
- cpu_to_le32(cmd->request_bufflen);
- qla1280_dump_buffer(1,(char *)pkt,
- REQUEST_ENTRY_SIZE);
+ cpu_to_le32(sg_dma_len(sg));
+ dprintk(1,
+ "S/G Segment Cont. phys_addr=0x%x, "
+ "len=0x%x\n",
+ cpu_to_le32(pci_dma_lo32(sg_dma_address(sg))),
+ cpu_to_le32(sg_dma_len(sg)));
+ sg++;
}
- } else { /* No data transfer at all */
-
- //dword_ptr = (uint32_t *)(pkt + 1);
- //*dword_ptr++ = 0;
- //*dword_ptr = 0;
- dprintk(5,
- "qla1280_32bit_start_scsi: No data, command "
- "packet data - \n");
+ dprintk(5, "qla1280_32bit_start_scsi: "
+ "continuation packet data - "
+ "scsi(%i:%i:%i)\n", SCSI_BUS_32(cmd),
+ SCSI_TCN_32(cmd), SCSI_LUN_32(cmd));
qla1280_dump_buffer(5, (char *)pkt,
REQUEST_ENTRY_SIZE);
}
- dprintk(5,
- "qla1280_32bit_start_scsi: First IOCB block:\n");
- qla1280_dump_buffer(5, (char *)ha->request_ring_ptr,
- REQUEST_ENTRY_SIZE);
-
- /* Adjust ring index. */
- ha->req_ring_index++;
- if (ha->req_ring_index == REQUEST_ENTRY_CNT) {
- ha->req_ring_index = 0;
- ha->request_ring_ptr = ha->request_ring;
- } else
- ha->request_ring_ptr++;
-
- /* Set chip new ring index. */
- dprintk(1, "qla1280_32bit_start_scsi: Wakeup RISC "
- "for pending command\n");
- ha->qthreads--;
- sp->flags |= SRB_SENT;
- ha->actthreads++;
- WRT_REG_WORD(&reg->mailbox4, ha->req_ring_index);
- } else {
- status = 1;
- dprintk(2,
- "qla1280_32bit_start_scsi: NO ROOM IN OUTSTANDING "
- "ARRAY, req_q_cnt=0x%x\n", ha->req_q_cnt);
+ } else { /* No S/G data transfer */
+ struct page *page = virt_to_page(cmd->request_buffer);
+ unsigned long off = (unsigned long)cmd->request_buffer & ~PAGE_MASK;
+ dma_handle = pci_map_page(ha->pdev, page, off,
+ cmd->request_bufflen,
+ scsi_to_pci_dma_dir(cmd->sc_data_direction));
+ sp->saved_dma_handle = dma_handle;
+
+ *dword_ptr++ = cpu_to_le32(pci_dma_lo32(dma_handle));
+ *dword_ptr = cpu_to_le32(cmd->request_bufflen);
}
- } else {
- status = 1;
- dprintk(2,
- "qla1280_32bit_start_scsi: in-ptr=0x%x, req_q_cnt=0x%x, "
- "req_cnt=0x%x", ha->req_ring_index, ha->req_q_cnt,
- req_cnt);
+ } else { /* No data transfer at all */
+ dword_ptr = (uint32_t *)(pkt + 1);
+ *dword_ptr++ = 0;
+ *dword_ptr = 0;
+ dprintk(5, "qla1280_32bit_start_scsi: No data, command "
+ "packet data - \n");
+ qla1280_dump_buffer(5, (char *)pkt, REQUEST_ENTRY_SIZE);
}
+ dprintk(5, "qla1280_32bit_start_scsi: First IOCB block:\n");
+ qla1280_dump_buffer(5, (char *)ha->request_ring_ptr,
+ REQUEST_ENTRY_SIZE);
+ /* Adjust ring index. */
+ ha->req_ring_index++;
+ if (ha->req_ring_index == REQUEST_ENTRY_CNT) {
+ ha->req_ring_index = 0;
+ ha->request_ring_ptr = ha->request_ring;
+ } else
+ ha->request_ring_ptr++;
+
+ /* Set chip new ring index. */
+ dprintk(2, "qla1280_32bit_start_scsi: Wakeup RISC "
+ "for pending command\n");
+ sp->flags |= SRB_SENT;
+ ha->actthreads++;
+ WRT_REG_WORD(&reg->mailbox4, ha->req_ring_index);
+
+out:
if (status)
dprintk(2, "qla1280_32bit_start_scsi: **** FAILED ****\n");
@@ -4310,6 +4120,10 @@ qla1280_req_pkt(struct scsi_qla_host *ha)
/* Zero out packet. */
memset(pkt, 0, REQUEST_ENTRY_SIZE);
+ /*
+ * How can this be right when we have a ring
+ * size of 512???
+ */
/* Set system defined field. */
pkt->sys_define = (uint8_t) ha->req_ring_index;
@@ -4379,13 +4193,13 @@ qla1280_isp_cmd(struct scsi_qla_host *ha)
static void
qla1280_enable_lun(struct scsi_qla_host *ha, int bus, int lun)
{
- elun_entry_t *pkt;
+ struct elun_entry *pkt;
ENTER("qla1280_enable_lun");
/* Get request packet. */
/*
- if (pkt = (elun_entry_t *)qla1280_req_pkt(ha))
+ if (pkt = (struct elun_entry *)qla1280_req_pkt(ha))
{
pkt->entry_type = ENABLE_LUN_TYPE;
pkt->lun = cpu_to_le16(bus ? lun | BIT_15 : lun);
@@ -4398,7 +4212,7 @@ qla1280_enable_lun(struct scsi_qla_host *ha, int bus, int lun)
qla1280_isp_cmd(ha);
}
*/
- pkt = (elun_entry_t *) 1;
+ pkt = (struct elun_entry *) 1;
if (!pkt)
dprintk(2, "qla1280_enable_lun: **** FAILED ****\n");
@@ -4407,211 +4221,6 @@ qla1280_enable_lun(struct scsi_qla_host *ha, int bus, int lun)
}
#endif
-#if QL1280_TARGET_MODE_SUPPORT
-/****************************************************************************/
-/* Target Mode Support Functions. */
-/****************************************************************************/
-
-/*
- * qla1280_notify_ack
- * Issue notify acknowledge IOCB.
- * If sequence ID is zero, acknowledgement of
- * SCSI bus reset or bus device reset is assumed.
- *
- * Input:
- * ha = adapter block pointer.
- * inotify = immediate notify entry pointer.
- */
-static void
-qla1280_notify_ack(struct scsi_qla_host *ha, notify_entry_t * inotify)
-{
- nack_entry_t *pkt;
-
- dprintk(3, "qla1280_notify_ack: entered\n");
-
- /* Get request packet. */
- if (pkt = (nack_entry_t *) qla1280_req_pkt(ha)) {
- pkt->entry_type = NOTIFY_ACK_TYPE;
- pkt->lun = inotify->lun;
- pkt->initiator_id = inotify->initiator_id;
- pkt->target_id = inotify->target_id;
- if (inotify->seq_id == 0)
- pkt->event = BIT_7;
- else
- pkt->seq_id = cpu_to_le16(inotify->seq_id);
-
- /* Issue command to ISP */
- qla1280_isp_cmd(ha);
- }
-
- if (!pkt)
- dprintk(2, "qla1280_notify_ack: **** FAILED ****\n");
- else
- dprintk(3, "qla1280_notify_ack: exiting normally\n");
-}
-
-/*
- * qla1280_immed_notify
- * Issue immediate notify IOCB for LUN 0.
- *
- * Input:
- * ha = adapter block pointer.
- * inotify = immediate notify entry pointer.
- */
-static void
-qla1280_immed_notify(struct scsi_qla_host *ha, notify_entry_t * inotify)
-{
- notify_entry_t *pkt;
-
- dprintk(3, "qla1280_immed_notify: entered\n");
-
- /* Get request packet. */
- if (pkt = (notify_entry_t *) qla1280_req_pkt(ha)) {
- pkt->entry_type = IMMED_NOTIFY_TYPE;
- pkt->lun = inotify->lun;
- pkt->initiator_id = inotify->initiator_id;
- pkt->target_id = inotify->target_id;
- pkt->status = 1;
-
- /* Issue command to ISP */
- qla1280_isp_cmd(ha);
- }
-
- if (!pkt)
- dprintk(2, "qla1280_immed_notify: **** FAILED ****\n");
- else
- dprintk(3, "qla1280_immed_notify: exiting normally\n");
-}
-
-/*
- * qla1280_accept_io
- * Issue accept target I/O IOCB for LUN 0.
- *
- * Input:
- * ha = adapter block pointer.
- * ctio = ctio returned entry pointer.
- */
-static void
-qla1280_accept_io(struct scsi_qla_host *ha, ctio_ret_entry_t * ctio)
-{
- atio_entry_t *pkt;
-
- dprintk(3, "qla1280_accept_io: entered\n");
-
- /* Get request packet. */
- if (pkt = (atio_entry_t *) qla1280_req_pkt(ha)) {
- pkt->entry_type = ACCEPT_TGT_IO_TYPE;
- pkt->lun = ctio->lun;
- pkt->initiator_id = ctio->initiator_id;
- pkt->target_id = ctio->target_id;
- pkt->tag_value = ctio->tag_value;
- pkt->status = 1;
-
- /* Issue command to ISP */
- qla1280_isp_cmd(ha);
- }
-
- if (!pkt)
- dprintk(2, "qla1280_accept_io: **** FAILED ****\n");
- else
- dprintk(3, "qla1280_accept_io: exiting normally\n");
-}
-
-/*
- * qla1280_64bit_continue_io
- * Issue continue target I/O IOCB.
- *
- * Input:
- * ha = adapter block pointer.
- * atio = atio pointer.
- * len = total bytecount.
- * addr = physical address pointer.
- */
-static void
-qla1280_64bit_continue_io(struct scsi_qla_host *ha, atio_entry_t * atio,
- uint32_t len, paddr32_t * addr)
-{
- ctio_a64_entry_t *pkt;
- uint32_t *dword_ptr;
-
- dprintk(3, "qla1280_64bit_continue_io: entered\n");
-
- /* Get request packet. */
- if (pkt = (ctio_a64_entry_t *) qla1280_req_pkt(ha)) {
- pkt->entry_type = CTIO_A64_TYPE;
- pkt->lun = atio->lun;
- pkt->initiator_id = atio->initiator_id;
- pkt->target_id = atio->target_id;
- pkt->option_flags = cpu_to_le32(atio->option_flags);
- pkt->tag_value = atio->tag_value;
- pkt->scsi_status = atio->scsi_status;
-
- if (len) {
- pkt->dseg_count = cpu_to_le16(1);
- pkt->transfer_length = cpu_to_le32(len);
- pkt->dseg_0_length = cpu_to_le32(len);
- dword_ptr = (uint32_t *) addr;
- pkt->dseg_0_address[0] = cpu_to_le32(*dword_ptr++);
- pkt->dseg_0_address[1] = cpu_to_le32(*dword_ptr);
- }
-
- /* Issue command to ISP */
- qla1280_isp_cmd(ha);
- }
-
- if (!pkt)
- dprintk(2, "qla1280_64bit_continue_io: **** FAILED ****\n");
- else
- dprintk(3, "qla1280_64bit_continue_io: exiting normally\n");
-}
-
-/*
- * qla1280_32bit_continue_io
- * Issue continue target I/O IOCB.
- *
- * Input:
- * ha = adapter block pointer.
- * atio = atio pointer.
- * len = total bytecount.
- * addr = physical address pointer.
- */
-static void
-qla1280_32bit_continue_io(struct scsi_qla_host *ha, atio_entry_t * atio,
- uint32_t len, paddr32_t * addr)
-{
- ctio_entry_t *pkt;
- uint32_t *dword_ptr;
-
- dprintk(3, "qla1280_32bit_continue_io: entered\n");
-
- /* Get request packet. */
- if (pkt = (ctio_entry_t *) qla1280_req_pkt(ha)) {
- pkt->entry_type = CONTINUE_TGT_IO_TYPE;
- pkt->lun = atio->lun;
- pkt->initiator_id = atio->initiator_id;
- pkt->target_id = atio->target_id;
- pkt->option_flags = cpu_to_le32(atio->option_flags);
- pkt->tag_value = atio->tag_value;
- pkt->scsi_status = atio->scsi_status;
-
- if (len) {
- pkt->dseg_count = cpu_to_le16(1);
- pkt->transfer_length = cpu_to_le32(len);
- pkt->dseg_0_length = cpu_to_le32(len);
- dword_ptr = (uint32_t *)addr;
- pkt->dseg_0_address = cpu_to_le32(*dword_ptr);
- }
-
- /* Issue command to ISP */
- qla1280_isp_cmd(ha);
- }
-
- if (!pkt)
- dprintk(2, "qla1280_32bit_continue_io: **** FAILED ****\n");
- else
- dprintk(3, "qla1280_32bit_continue_io: exiting normally\n");
-}
-#endif /* QL1280_TARGET_MODE_SUPPORT */
/****************************************************************************/
/* Interrupt Service Routine. */
@@ -4627,12 +4236,12 @@ qla1280_32bit_continue_io(struct scsi_qla_host *ha, atio_entry_t * atio,
* done_q_last = done queue last pointer.
****************************************************************************/
static void
-qla1280_isr(struct scsi_qla_host *ha, srb_t ** done_q_first,
- srb_t ** done_q_last)
+qla1280_isr(struct scsi_qla_host *ha, struct srb ** done_q_first,
+ struct srb ** done_q_last)
{
struct device_reg *reg = ha->iobase;
- response_t *pkt;
- srb_t *sp = 0;
+ struct response *pkt;
+ struct srb *sp = 0;
uint16_t mailbox[MAILBOX_REGISTER_COUNT];
uint16_t *wptr;
uint32_t index;
@@ -4679,8 +4288,8 @@ qla1280_isr(struct scsi_qla_host *ha, srb_t ** done_q_first,
/* Handle asynchronous event */
switch (mailbox[0]) {
case MBA_SCSI_COMPLETION: /* Response completion */
- dprintk(5,
- "qla1280_isr: mailbox SCSI response completion\n");
+ dprintk(5, "qla1280_isr: mailbox SCSI response "
+ "completion\n");
if (ha->flags.online) {
/* Get outstanding command index. */
@@ -4713,39 +4322,34 @@ qla1280_isr(struct scsi_qla_host *ha, srb_t ** done_q_first,
*/
printk(KERN_WARNING
"qla1280: ISP invalid handle");
- ha->flags.isp_abort_needed = TRUE;
}
}
break;
case MBA_BUS_RESET: /* SCSI Bus Reset */
- ha->flags.reset_marker = TRUE;
+ ha->flags.reset_marker = 1;
index = mailbox[6] & BIT_0;
- ha->bus_settings[index].reset_marker = TRUE;
+ ha->bus_settings[index].reset_marker = 1;
- printk(KERN_DEBUG
- "qla1280_isr(): index %i asynchronous "
- "BUS_RESET\n", index);
+ printk(KERN_DEBUG "qla1280_isr(): index %i "
+ "asynchronous BUS_RESET\n", index);
break;
case MBA_SYSTEM_ERR: /* System Error */
printk(KERN_WARNING
- "qla1280: ISP System Error - mbx1=%xh, mbx2=%xh, "
- "mbx3=%xh\n", mailbox[1], mailbox[2],
+ "qla1280: ISP System Error - mbx1=%xh, mbx2="
+ "%xh, mbx3=%xh\n", mailbox[1], mailbox[2],
mailbox[3]);
- ha->flags.isp_abort_needed = TRUE;
break;
case MBA_REQ_TRANSFER_ERR: /* Request Transfer Error */
printk(KERN_WARNING
"qla1280: ISP Request Transfer Error\n");
- ha->flags.isp_abort_needed = TRUE;
break;
case MBA_RSP_TRANSFER_ERR: /* Response Transfer Error */
printk(KERN_WARNING
"qla1280: ISP Response Transfer Error\n");
- ha->flags.isp_abort_needed = TRUE;
break;
case MBA_WAKEUP_THRES: /* Request Queue Wake-up */
@@ -4758,14 +4362,12 @@ qla1280_isr(struct scsi_qla_host *ha, srb_t ** done_q_first,
break;
case MBA_DEVICE_RESET: /* Bus Device Reset */
- dprintk(2,
- "qla1280_isr: asynchronous BUS_DEVICE_RESET\n");
printk(KERN_INFO "qla1280_isr(): asynchronous "
"BUS_DEVICE_RESET\n");
- ha->flags.reset_marker = TRUE;
+ ha->flags.reset_marker = 1;
index = mailbox[6] & BIT_0;
- ha->bus_settings[index].reset_marker = TRUE;
+ ha->bus_settings[index].reset_marker = 1;
break;
case MBA_BUS_MODE_CHANGE:
@@ -4780,7 +4382,9 @@ qla1280_isr(struct scsi_qla_host *ha, srb_t ** done_q_first,
memcpy((uint16_t *) ha->mailbox_out, wptr,
MAILBOX_REGISTER_COUNT *
sizeof(uint16_t));
- ha->flags.mbox_int = TRUE;
+
+ if(ha->mailbox_wait != NULL)
+ complete(ha->mailbox_wait);
}
break;
}
@@ -4793,123 +4397,68 @@ qla1280_isr(struct scsi_qla_host *ha, srb_t ** done_q_first,
* unnecessary as the mailbox data has been copied to ha->mailbox_out
* by the time we actually get here!
*/
- if (ha->flags.online
+ if (!(ha->flags.online
#if 0
&& !ha->flags.mbox_busy
#endif
- ) {
- if (mailbox[5] < RESPONSE_ENTRY_CNT) {
- while (ha->rsp_ring_index != mailbox[5]) {
- pkt = ha->response_ring_ptr;
-
- dprintk(5,
- "qla1280_isr: ha->rsp_ring_index = 0x%x, "
- "mailbox[5] = 0x%x\n",
- ha->rsp_ring_index, mailbox[5]);
- dprintk(5,
- "qla1280_isr: response packet data\n");
- qla1280_dump_buffer(5, (char *)pkt,
- RESPONSE_ENTRY_SIZE);
-
- if (pkt->entry_type == STATUS_TYPE) {
- if ((le16_to_cpu(pkt->scsi_status) & 0xff)
- || pkt->comp_status
- || pkt->entry_status) {
- dprintk(2,
- "qla1280_isr: ha->rsp_ring_index = 0x%x"
- "mailbox[5] = 0x%x, comp_status = 0x%x, "
- "scsi_status = 0x%x\n",
- ha->rsp_ring_index,
- mailbox[5],
- le16_to_cpu(pkt->comp_status),
- le16_to_cpu(pkt->scsi_status));
- }
- } else {
- dprintk(2,
- "qla1280_isr: ha->rsp_ring_index = 0x%x, "
- "mailbox[5] = 0x%x\n",
- ha->rsp_ring_index,
- mailbox[5]);
- dprintk(2,
- "qla1280_isr: response packet data\n");
- qla1280_dump_buffer(2, (char *)pkt,
- RESPONSE_ENTRY_SIZE);
- }
+ )) {
+ dprintk(2, "qla1280_isr: Response pointer Error\n");
+ goto out;
+ }
- if (pkt->entry_type == STATUS_TYPE
- || pkt->entry_status) {
- if (pkt->entry_type == STATUS_TYPE)
- qla1280_status_entry(ha,
- (sts_entry_t *) pkt,
- done_q_first,
- done_q_last);
- else
- qla1280_error_entry(ha, pkt,
- done_q_first,
- done_q_last);
-
- /* Adjust ring index. */
- ha->rsp_ring_index++;
- if (ha->rsp_ring_index ==
- RESPONSE_ENTRY_CNT) {
- ha->rsp_ring_index = 0;
- ha->response_ring_ptr =
- ha->response_ring;
- } else
- ha->response_ring_ptr++;
- WRT_REG_WORD(&reg->mailbox5,
- ha->rsp_ring_index);
- }
-#if QLA1280_TARGET_MODE_SUPPORT
- else {
- pkt = &response_entry;
-
- /* Copy packet. */
- dptr1 =
- (uint32_t *)ha->response_ring_ptr;
- dptr2 = (uint32_t *) pkt;
- for (index = 0;
- index < RESPONSE_ENTRY_SIZE / 4;
- index++)
- *dptr2++ = *dptr1++;
-
- /* Adjust ring index. */
- ha->rsp_ring_index++;
- if (ha->rsp_ring_index ==
- RESPONSE_ENTRY_CNT) {
- ha->rsp_ring_index = 0;
- ha->response_ring_ptr =
- ha->response_ring;
- } else
- ha->response_ring_ptr++;
- WRT_REG_WORD(&reg->mailbox5,
- ha->rsp_ring_index);
-
- switch (pkt->entry_type) {
- case ACCEPT_TGT_IO_TYPE:
- qla1280_atio_entry(ha,
- (atio_entry_t *) pkt);
- break;
- case IMMED_NOTIFY_TYPE:
- qla1280_notify_entry(ha,
- (notify_entry_t *) pkt);
- break;
- case CTIO_RET_TYPE:
- qla1280_accept_io(ha,
- (ctio_ret_entry_t *) pkt);
- break;
- default:
- break;
- }
- }
-#endif
+ if (mailbox[5] >= RESPONSE_ENTRY_CNT)
+ goto out;
+
+ while (ha->rsp_ring_index != mailbox[5]) {
+ pkt = ha->response_ring_ptr;
+
+ dprintk(5, "qla1280_isr: ha->rsp_ring_index = 0x%x, mailbox[5]"
+ " = 0x%x\n", ha->rsp_ring_index, mailbox[5]);
+ dprintk(5,"qla1280_isr: response packet data\n");
+ qla1280_dump_buffer(5, (char *)pkt, RESPONSE_ENTRY_SIZE);
+
+ if (pkt->entry_type == STATUS_TYPE) {
+ if ((le16_to_cpu(pkt->scsi_status) & 0xff)
+ || pkt->comp_status || pkt->entry_status) {
+ dprintk(2, "qla1280_isr: ha->rsp_ring_index = "
+ "0x%x mailbox[5] = 0x%x, comp_status "
+ "= 0x%x, scsi_status = 0x%x\n",
+ ha->rsp_ring_index, mailbox[5],
+ le16_to_cpu(pkt->comp_status),
+ le16_to_cpu(pkt->scsi_status));
}
} else {
- ha->flags.isp_abort_needed = TRUE;
- dprintk(2, "qla1280_isr: Response pointer Error\n");
+ dprintk(2, "qla1280_isr: ha->rsp_ring_index = "
+ "0x%x, mailbox[5] = 0x%x\n",
+ ha->rsp_ring_index, mailbox[5]);
+ dprintk(2, "qla1280_isr: response packet data\n");
+ qla1280_dump_buffer(2, (char *)pkt,
+ RESPONSE_ENTRY_SIZE);
}
- }
+ if (pkt->entry_type == STATUS_TYPE || pkt->entry_status) {
+ dprintk(2, "status: Cmd %p, handle %i\n",
+ ha->outstanding_cmds[pkt->handle]->cmd,
+ pkt->handle);
+ if (pkt->entry_type == STATUS_TYPE)
+ qla1280_status_entry(ha, pkt, done_q_first,
+ done_q_last);
+ else
+ qla1280_error_entry(ha, pkt, done_q_first,
+ done_q_last);
+
+ /* Adjust ring index. */
+ ha->rsp_ring_index++;
+ if (ha->rsp_ring_index == RESPONSE_ENTRY_CNT) {
+ ha->rsp_ring_index = 0;
+ ha->response_ring_ptr = ha->response_ring;
+ } else
+ ha->response_ring_ptr++;
+ WRT_REG_WORD(&reg->mailbox5, ha->rsp_ring_index);
+ }
+ }
+
+ out:
LEAVE("qla1280_isr");
}
@@ -4923,42 +4472,22 @@ qla1280_isr(struct scsi_qla_host *ha, srb_t ** done_q_first,
static void
qla1280_rst_aen(struct scsi_qla_host *ha)
{
-#if QL1280_TARGET_MODE_SUPPORT
- notify_entry_t nentry;
-#endif
uint8_t bus;
ENTER("qla1280_rst_aen");
if (ha->flags.online && !ha->flags.reset_active &&
!ha->flags.abort_isp_active) {
- ha->flags.reset_active = TRUE;
+ ha->flags.reset_active = 1;
while (ha->flags.reset_marker) {
/* Issue marker command. */
- ha->flags.reset_marker = FALSE;
+ ha->flags.reset_marker = 0;
for (bus = 0; bus < ha->ports &&
!ha->flags.reset_marker; bus++) {
if (ha->bus_settings[bus].reset_marker) {
- ha->bus_settings[bus].reset_marker =
- FALSE;
+ ha->bus_settings[bus].reset_marker = 0;
qla1280_marker(ha, bus, 0, 0,
MK_SYNC_ALL);
-
- if (!ha->flags.reset_marker) {
-#if QL1280_TARGET_MODE_SUPPORT
- /* Issue notify acknowledgement command. */
- memset(&nentry, 0,
- sizeof(notify_entry_t));
-
- nentry.initiator_id =
- nentry.target_id =
- bus ? ha->bus_settings[bus].id | BIT_7 :
- ha->bus_settings[bus].id;
- qla1280_notify_entry(ha,
- &nentry);
-#endif
- /* Asynchronous event notification */
- }
}
}
}
@@ -4967,432 +4496,50 @@ qla1280_rst_aen(struct scsi_qla_host *ha)
LEAVE("qla1280_rst_aen");
}
-#if QL1280_TARGET_MODE_SUPPORT
-/*
- * qla1280_atio_entry
- * Processes received ISP accept target I/O entry.
- *
- * Input:
- * ha = adapter block pointer.
- * pkt = entry pointer.
- */
-static void
-qla1280_atio_entry(struct scsi_qla_host *ha, atio_entry_t * pkt)
-{
- uint64_t *a64;
- uint64_t *end_a64;
- paddr32_t phy_addr[2];
- paddr32_t end_addr[2];
- uint32_t len;
- uint32_t offset;
- uint8_t t;
- uint8_t *sense_ptr;
-
- dprintk(3, "qla1280_atio_entry: entered\n");
-
- t = pkt->initiator_id;
- sense_ptr = ha->tsense + t * TARGET_SENSE_SIZE;
- a64 = (uint64_t *)&phy_addr[0];
- end_a64 = (uint64_t *)&end_addr[0];
-
- switch (pkt->status & ~BIT_7) {
- case 7: /* Path invalid */
- dprintk(2, "qla1280_atio_entry: Path invalid\n");
- break;
-
- case 0x14: /* Target Bus Phase Sequence Failure */
- dprintk(2, "qla1280_atio_entry: Target Bus Phase "
- "Sequence Failure\n");
-
- if (pkt->status & BIT_7) {
- memcpy(sense_ptr, &pkt->sense_data, TARGET_SENSE_SIZE);
- } else {
- memset(sense_ptr, 0, TARGET_SENSE_SIZE);
- *sense_ptr = 0x70;
- *(sense_ptr + 2) = SD_HARDERR;
- *(sense_ptr + 7) = TARGET_SENSE_SIZE - 8;
- *(sense_ptr + 12) = SC_SELFAIL;
- }
- pkt->scsi_status = S_CKCON;
- pkt->option_flags |= cpu_to_le32(OF_SSTS | OF_NO_DATA);
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,18)
- if (ha->flags.enable_64bit_addressing)
- qla1280_64bit_continue_io(ha, pkt, 0, 0);
- else
-#endif
- qla1280_32bit_continue_io(ha, pkt, 0, 0);
- break;
-
- case 0x16: /* Requested Capability Not Available */
- dprintk(2, "qla1280_atio_entry: Target Bus Phase "
- "Sequence Failure\n");
- break;
-
- case 0x17: /* Bus Device Reset Message Received */
- dprintk(2, "qla1280_atio_entry: Target Bus Phase "
- "Sequence Failure\n");
- break;
-
- case 0x3D: /* CDB Received */
-
- /* Check for invalid LUN */
- if (pkt->lun && pkt->cdb[0] != SS_INQUIR &&
- pkt->cdb[0] != SS_REQSEN)
- pkt->cdb[0] = SS_TEST;
-
- switch (pkt->cdb[0]) {
- case SS_TEST:
- dprintk(3, "qla1280_atio_entry: SS_TEST\n");
-
- memset(sense_ptr, 0, TARGET_SENSE_SIZE);
- len = 0;
- if (pkt->lun == 0)
- pkt->scsi_status = S_GOOD;
- else {
- *sense_ptr = 0x70;
- *(sense_ptr + 2) = SD_ILLREQ;
- *(sense_ptr + 7) = TARGET_SENSE_SIZE - 8;
- *(sense_ptr + 12) = SC_INVLUN;
- pkt->scsi_status = S_CKCON;
- }
-
- pkt->option_flags |= cpu_to_le32(OF_SSTS | OF_NO_DATA);
- break;
-
- case SS_REQSEN:
- dprintk(3, "qla1280_atio_entry: SS_REQSEN\n");
-
- phy_addr[0] = ha->tsense_dma;
- phy_addr[1] = 0;
- *a64 += t * TARGET_SENSE_SIZE;
- if (pkt->cdb[4] > TARGET_SENSE_SIZE)
- len = TARGET_SENSE_SIZE;
- else
- len = pkt->cdb[4];
- pkt->scsi_status = S_GOOD;
- pkt->option_flags |= cpu_to_le32(OF_SSTS | OF_DATA_IN);
- break;
-
- case SS_INQUIR:
- dprintk(3, "qla1280_atio_entry: SS_INQUIR\n");
-
- memset(sense_ptr, 0, TARGET_SENSE_SIZE);
- phy_addr[0] = ha->tbuf_dma;
- phy_addr[1] = 0;
- *a64 += TARGET_INQ_OFFSET;
-
- if (pkt->lun == 0) {
- ha->tbuf->inq.id_type = ID_PROCESOR;
- ha->tbuf->inq.id_pqual = ID_QOK;
- } else {
- ha->tbuf->inq.id_type = ID_NODEV;
- ha->tbuf->inq.id_pqual = ID_QNOLU;
- }
-
- if (pkt->cdb[4] > sizeof(struct ident))
- len = sizeof(struct ident);
- else
- len = pkt->cdb[4];
- pkt->scsi_status = S_GOOD;
- pkt->option_flags |= cpu_to_le32(OF_SSTS | OF_DATA_IN);
- break;
-
- case SM_WRDB:
- memset(sense_ptr, 0, TARGET_SENSE_SIZE);
- offset = pkt->cdb[5];
- offset |= pkt->cdb[4] << 8;
- offset |= pkt->cdb[3] << 16;
- len = pkt->cdb[8];
- len |= pkt->cdb[7] << 8;
- len |= pkt->cdb[6] << 16;
- end_addr[0] = phy_addr[0] = ha->tbuf_dma;
- end_addr[1] = phy_addr[1] = 0;
- *end_a64 += TARGET_DATA_OFFSET + TARGET_DATA_SIZE;
- switch (pkt->cdb[1] & 7) {
- case RW_BUF_HDATA:
- dprintk(3, "qla1280_atio_entry: SM_WRDB, "
- "RW_BUF_HDATA\n");
-
- if (len > TARGET_DATA_SIZE + 4) {
- dprintk(2,
- "qla1280_atio_entry: SM_WRDB, "
- "length > buffer size\n");
-
- *sense_ptr = 0x70;
- *(sense_ptr + 2) = SD_ILLREQ;
- *(sense_ptr + 7) =
- TARGET_SENSE_SIZE - 8;
- *(sense_ptr + 12) = SC_ILLCDB;
- pkt->scsi_status = S_CKCON;
- pkt->option_flags |=
- cpu_to_le32(OF_SSTS | OF_NO_DATA);
- len = 0;
- } else if (len) {
- pkt->scsi_status = S_GOOD;
- pkt->option_flags |=
- cpu_to_le32(OF_SSTS | OF_DATA_OUT);
- dprintk(3,
- "qla1280_atio_entry: Issuing "
- "SDI_TARMOD_WRCOMP\n");
-
- sdi_xaen(SDI_TARMOD_WRCOMP, ha->cntlr,
- pkt->target_id, pkt->lun, 0,
- offset);
- } else {
- dprintk(2,
- "qla1280_atio_entry: SM_WRDB, "
- "zero length\n");
-
- pkt->scsi_status = S_GOOD;
- pkt->option_flags |=
- cpu_to_le32(OF_SSTS | OF_NO_DATA);
- }
-
- break;
- case RW_BUF_DATA:
- dprintk(3, "qla1280_atio_entry: SM_WRDB, "
- "RW_BUF_DATA\n");
-
- *a64 += offset + TARGET_DATA_OFFSET;
- if (pkt->cdb[2] != 0 || *a64 >= *end_a64 ||
- *a64 + len > *end_a64) {
- dprintk(2,
- "qla1280_atio_entry: SM_WRDB, "
- "RW_BUF_DATA BAD\n");
- dprintk(2, "buf_id=0x%x, offset=0x%x, "
- "length=0x%x\n", pkt->cdb[2],
- offset, len);
-
- *sense_ptr = 0x70;
- *(sense_ptr + 2) = SD_ILLREQ;
- *(sense_ptr + 7) =
- TARGET_SENSE_SIZE - 8;
- *(sense_ptr + 12) = SC_ILLCDB;
- len = 0;
- pkt->scsi_status = S_CKCON;
- pkt->option_flags |=
- cpu_to_le32(OF_SSTS | OF_NO_DATA);
- } else if (len) {
- pkt->scsi_status = S_GOOD;
- pkt->option_flags |=
- cpu_to_le32(OF_SSTS | OF_DATA_OUT);
- dprintk(3,
- "qla1280_atio_entry: Issuing "
- "SDI_TARMOD_WRCOMP\n");
-
- sdi_xaen(SDI_TARMOD_WRCOMP, ha->cntlr,
- pkt->target_id, pkt->lun, 0,
- offset);
- } else {
- dprintk(2,
- "qla1280_atio_entry: SM_WRDB, "
- "zero length\n");
-
- pkt->scsi_status = S_GOOD;
- pkt->option_flags |=
- cpu_to_le32(OF_SSTS | OF_NO_DATA);
- }
- break;
-
- default:
- dprintk(2, "qla1280_atio_entry: SM_WRDB "
- "unknown mode\n");
-
- *sense_ptr = 0x70;
- *(sense_ptr + 2) = SD_ILLREQ;
- *(sense_ptr + 7) = TARGET_SENSE_SIZE - 8;
- *(sense_ptr + 12) = SC_ILLCDB;
- len = 0;
- pkt->scsi_status = S_CKCON;
- pkt->option_flags |= cpu_to_le32(OF_SSTS | OF_NO_DATA);
- break;
- }
- break;
-
- case SM_RDDB:
- memset(sense_ptr, 0, TARGET_SENSE_SIZE);
- offset = pkt->cdb[5];
- offset |= pkt->cdb[4] << 8;
- offset |= pkt->cdb[3] << 16;
- len = pkt->cdb[8];
- len |= pkt->cdb[7] << 8;
- len |= pkt->cdb[6] << 16;
- end_addr[0] = phy_addr[0] = ha->tbuf_dma;
- end_addr[1] = phy_addr[1] = 0;
- *end_a64 += TARGET_DATA_OFFSET + TARGET_DATA_SIZE;
- switch (pkt->cdb[1] & 7) {
- case RW_BUF_HDATA:
- dprintk(3, "qla1280_atio_entry: SM_RDDB, "
- "RW_BUF_HDATA\n");
-
- if (len) {
- ha->tbuf->hdr[0] = 0;
- ha->tbuf->hdr[1] =
- (TARGET_DATA_SIZE >> 16) & 0xff;
- ha->tbuf->hdr[2] =
- (TARGET_DATA_SIZE >> 8) & 0xff;
- ha->tbuf->hdr[3] =
- TARGET_DATA_SIZE & 0xff;
- if (len > TARGET_DATA_SIZE + 4)
- len = TARGET_DATA_SIZE + 4;
- pkt->scsi_status = S_GOOD;
- pkt->option_flags |=
- cpu_to_le32(OF_SSTS | OF_DATA_IN);
- } else {
- dprintk(2,
- "qla1280_atio_entry: SM_RDDB, "
- "zero length\n");
-
- pkt->scsi_status = S_GOOD;
- pkt->option_flags |=
- cpu_to_le32(OF_SSTS | OF_NO_DATA);
- }
- break;
- case RW_BUF_DATA:
- dprintk(3, "qla1280_atio_entry: SM_RDDB, "
- "RW_BUF_DATA\n");
-
- *a64 += offset + TARGET_DATA_OFFSET;
- if (pkt->cdb[2] != 0 || *a64 >= *end_a64) {
- dprintk(2,
- "qla1280_atio_entry: SM_RDDB, "
- "RW_BUF_DATA BAD\n");
- dprintk(2, "buf_id=0x%x, offset=0x%x\n"
- pkt->cdb[2], offset);
-
- *sense_ptr = 0x70;
- *(sense_ptr + 2) = SD_ILLREQ;
- *(sense_ptr + 7) =
- TARGET_SENSE_SIZE - 8;
- *(sense_ptr + 12) = SC_ILLCDB;
- len = 0;
- pkt->scsi_status = S_CKCON;
- pkt->option_flags |=
- cpu_to_le32(OF_SSTS | OF_NO_DATA);
- } else {
- if (*a64 + len > *end_a64)
- len = *end_a64 - *a64;
- if (len) {
- pkt->scsi_status = S_GOOD;
- pkt->option_flags |=
- (OF_SSTS | OF_DATA_IN);
- } else {
- dprintk(2,
- "qla1280_atio_entry: SM_RDDB, "
- "zero length\n");
-
- pkt->scsi_status = S_GOOD;
- pkt->option_flags |=
- cpu_to_le32(OF_SSTS | OF_NO_DATA);
- }
- }
- break;
- case RW_BUF_DESC:
- dprintk(3, "qla1280_atio_entry: SM_RDDB, "
- "RW_BUF_DESC\n");
-
- if (len) {
- if (len > 4)
- len = 4;
-
- ha->tbuf->hdr[0] = 0;
- if (pkt->cdb[2] != 0) {
- ha->tbuf->hdr[1] = 0;
- ha->tbuf->hdr[2] = 0;
- ha->tbuf->hdr[3] = 0;
- } else {
- ha->tbuf->hdr[1] =
- (TARGET_DATA_SIZE >> 16) &
- 0xff;
- ha->tbuf->hdr[2] =
- (TARGET_DATA_SIZE >> 8) &
- 0xff;
- ha->tbuf->hdr[3] =
- TARGET_DATA_SIZE & 0xff;
- }
- pkt->scsi_status = S_GOOD;
- pkt->option_flags |=
- cpu_to_le32(OF_SSTS | OF_DATA_IN);
- } else {
- dprintk(2,
- "qla1280_atio_entry: SM_RDDB,"
- " zero length\n");
-
- pkt->scsi_status = S_GOOD;
- pkt->option_flags |=
- cpu_to_le32(OF_SSTS | OF_NO_DATA);
- }
- break;
- default:
- dprintk(2, "qla1280_atio_entry: SM_RDDB "
- "unknown mode\n");
-
- *sense_ptr = 0x70;
- *(sense_ptr + 2) = SD_ILLREQ;
- *(sense_ptr + 7) = TARGET_SENSE_SIZE - 8;
- *(sense_ptr + 12) = SC_ILLCDB;
- len = 0;
- pkt->scsi_status = S_CKCON;
- pkt->option_flags |= cpu_to_le32(OF_SSTS | OF_NO_DATA);
- break;
- }
- break;
-
- default:
- dprintk(2,
- "qla1280_atio_entry: Unknown SCSI command\n");
- qla1280_dump_buffer(2, &pkt->cdb[0], pkt->cdb_len);
-
- memset(sense_ptr, 0, TARGET_SENSE_SIZE);
- *sense_ptr = 0x70;
- *(sense_ptr + 2) = SD_ILLREQ;
- *(sense_ptr + 7) = TARGET_SENSE_SIZE - 8;
- *(sense_ptr + 12) = SC_INVOPCODE;
- len = 0;
- pkt->scsi_status = S_CKCON;
- pkt->option_flags |= cpu_to_le32(OF_SSTS | OF_NO_DATA);
- break;
- }
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,18)
- if (ha->flags.enable_64bit_addressing)
- qla1280_64bit_continue_io(ha, pkt, len,
- (paddr32_t *)&phy_addr);
- else
-#endif
- qla1280_32bit_continue_io(ha, pkt, len,
- (paddr32_t *)&phy_addr);
- break;
-
- default:
- break;
- }
-
- dprintk(3, "qla1280_atio_entry: exiting normally\n");
-}
+#if LINUX_KERNEL_VERSION < 0x020500
/*
- * qla1280_notify_entry
- * Processes received ISP immediate notify entry.
*
- * Input:
- * ha = adapter block pointer.
- * pkt = entry pointer.
*/
-static void
-qla1280_notify_entry(struct scsi_qla_host *ha, notify_entry_t * pkt)
+void
+qla1280_get_target_options(struct scsi_cmnd *cmd, struct scsi_qla_host *ha)
{
- dprintk(3, "qla1280_notify_entry: entered\n");
+ unsigned char *result;
+ struct nvram *n;
+ int bus, target, lun;
- /* Acknowledge immediate notify */
- qla1280_notify_ack(ha, pkt);
+ bus = SCSI_BUS_32(cmd);
+ target = SCSI_TCN_32(cmd);
+ lun = SCSI_LUN_32(cmd);
- /* Issue notify entry to increment resource count */
- qla1280_immed_notify(ha, pkt);
+ /*
+ * Make sure to not touch anything if someone is using the
+ * sg interface.
+ */
+ if (cmd->use_sg || (CMD_RESULT(cmd) >> 16) != DID_OK || lun)
+ return;
- dprintk(3, "qla1280_notify_entry: exiting normally\n");
+ result = cmd->request_buffer;
+ n = &ha->nvram;
+
+ n->bus[bus].target[target].parameter.f.enable_wide = 0;
+ n->bus[bus].target[target].parameter.f.enable_sync = 0;
+ n->bus[bus].target[target].ppr_1x160.flags.enable_ppr = 0;
+
+ if (result[7] & 0x60)
+ n->bus[bus].target[target].parameter.f.enable_wide = 1;
+ if (result[7] & 0x10)
+ n->bus[bus].target[target].parameter.f.enable_sync = 1;
+ if ((result[2] >= 3) && (result[4] + 5 > 56) &&
+ (result[56] & 0x4))
+ n->bus[bus].target[target].ppr_1x160.flags.enable_ppr = 1;
+
+ dprintk(2, "get_target_options(): wide %i, sync %i, ppr %i\n",
+ n->bus[bus].target[target].parameter.f.enable_wide,
+ n->bus[bus].target[target].parameter.f.enable_sync,
+ n->bus[bus].target[target].ppr_1x160.flags.enable_ppr);
}
-#endif /* QLA1280_TARGET_MODE_SUPPORT */
+#endif
/*
* qla1280_status_entry
@@ -5405,13 +4552,12 @@ qla1280_notify_entry(struct scsi_qla_host *ha, notify_entry_t * pkt)
* done_q_last = done queue last pointer.
*/
static void
-qla1280_status_entry(struct scsi_qla_host *ha, sts_entry_t * pkt,
- srb_t ** done_q_first, srb_t ** done_q_last)
+qla1280_status_entry(struct scsi_qla_host *ha, struct response *pkt,
+ struct srb **done_q_first, struct srb **done_q_last)
{
unsigned int bus, target, lun;
int sense_sz;
- srb_t *sp;
- scsi_lu_t *q;
+ struct srb *sp;
Scsi_Cmnd *cmd;
uint32_t handle = le32_to_cpu(pkt->handle);
uint16_t scsi_status = le16_to_cpu(pkt->scsi_status);
@@ -5423,73 +4569,73 @@ qla1280_status_entry(struct scsi_qla_host *ha, sts_entry_t * pkt,
if (handle < MAX_OUTSTANDING_COMMANDS)
sp = ha->outstanding_cmds[handle];
else
- sp = 0;
+ sp = NULL;
- if (sp) {
- /* Free outstanding command slot. */
- ha->outstanding_cmds[handle] = 0;
+ if (!sp) {
+ printk(KERN_WARNING "qla1280: Status Entry invalid handle\n");
+ goto out;
+ }
- cmd = sp->cmd;
+ /* Free outstanding command slot. */
+ ha->outstanding_cmds[handle] = 0;
- /* Generate LU queue on cntrl, target, LUN */
- bus = SCSI_BUS_32(cmd);
- target = SCSI_TCN_32(cmd);
- lun = SCSI_LUN_32(cmd);
- q = LU_Q(ha, bus, target, lun);
+ cmd = sp->cmd;
- if (comp_status || scsi_status) {
- dprintk(1, "scsi: comp_status = 0x%x, scsi_status = "
- "0x%x, handle = 0x%lx\n", comp_status,
- scsi_status, handle);
- }
+ /* Generate LU queue on cntrl, target, LUN */
+ bus = SCSI_BUS_32(cmd);
+ target = SCSI_TCN_32(cmd);
+ lun = SCSI_LUN_32(cmd);
- /* Target busy */
- if (scsi_status & SS_BUSY_CONDITION &&
- scsi_status != SS_RESERVE_CONFLICT) {
- CMD_RESULT(cmd) =
- DID_BUS_BUSY << 16 | (scsi_status & 0xff);
- } else {
+ if (comp_status || scsi_status) {
+ dprintk(3, "scsi: comp_status = 0x%x, scsi_status = "
+ "0x%x, handle = 0x%x\n", comp_status,
+ scsi_status, handle);
+ }
- /* Save ISP completion status */
- CMD_RESULT(cmd) = qla1280_return_status(pkt, cmd);
+ /* Target busy */
+ if (scsi_status & SS_BUSY_CONDITION &&
+ scsi_status != SS_RESERVE_CONFLICT) {
+ CMD_RESULT(cmd) =
+ DID_BUS_BUSY << 16 | (scsi_status & 0xff);
+ } else {
- if (scsi_status & SS_CHECK_CONDITION) {
- if (comp_status != CS_ARS_FAILED) {
- uint16_t req_sense_length =
- le16_to_cpu(pkt->req_sense_length);
- if (req_sense_length <
- CMD_SNSLEN(cmd))
- sense_sz = req_sense_length;
- else
- /*
- * Scsi_Cmnd->sense_buffer is
- * 64 bytes, why only copy 63?
- * This looks wrong! /Jes
- */
- sense_sz = CMD_SNSLEN(cmd) - 1;
-
- memcpy(cmd->sense_buffer,
- &pkt->req_sense_data, sense_sz);
- } else
- sense_sz = 0;
- memset(cmd->sense_buffer + sense_sz, 0,
- sizeof(cmd->sense_buffer) - sense_sz);
-
- dprintk(2, "qla1280_status_entry: Check "
- "condition Sense data, b %i, t %i, "
- "l %i\n", bus, target, lun);
- if (sense_sz)
- qla1280_dump_buffer(2, (char *)cmd->sense_buffer,
- sense_sz);
- }
+ /* Save ISP completion status */
+ CMD_RESULT(cmd) = qla1280_return_status(pkt, cmd);
+
+ if (scsi_status & SS_CHECK_CONDITION) {
+ if (comp_status != CS_ARS_FAILED) {
+ uint16_t req_sense_length =
+ le16_to_cpu(pkt->req_sense_length);
+ if (req_sense_length < CMD_SNSLEN(cmd))
+ sense_sz = req_sense_length;
+ else
+ /*
+ * Scsi_Cmnd->sense_buffer is
+ * 64 bytes, why only copy 63?
+ * This looks wrong! /Jes
+ */
+ sense_sz = CMD_SNSLEN(cmd) - 1;
+
+ memcpy(cmd->sense_buffer,
+ &pkt->req_sense_data, sense_sz);
+ } else
+ sense_sz = 0;
+ memset(cmd->sense_buffer + sense_sz, 0,
+ sizeof(cmd->sense_buffer) - sense_sz);
+
+ dprintk(2, "qla1280_status_entry: Check "
+ "condition Sense data, b %i, t %i, "
+ "l %i\n", bus, target, lun);
+ if (sense_sz)
+ qla1280_dump_buffer(2,
+ (char *)cmd->sense_buffer,
+ sense_sz);
}
- /* Place command on done queue. */
- qla1280_done_q_put(sp, done_q_first, done_q_last);
- } else {
- printk(KERN_WARNING "qla1280: Status Entry invalid handle\n");
- ha->flags.isp_abort_needed = TRUE;
}
+ /* Place command on done queue. */
+ qla1280_done_q_put(sp, done_q_first, done_q_last);
+ out:
LEAVE("qla1280_status_entry");
}
@@ -5504,10 +4650,10 @@ qla1280_status_entry(struct scsi_qla_host *ha, sts_entry_t * pkt,
* done_q_last = done queue last pointer.
*/
static void
-qla1280_error_entry(struct scsi_qla_host *ha, response_t * pkt,
- srb_t ** done_q_first, srb_t ** done_q_last)
+qla1280_error_entry(struct scsi_qla_host *ha, struct response * pkt,
+ struct srb ** done_q_first, struct srb ** done_q_last)
{
- srb_t *sp;
+ struct srb *sp;
uint32_t handle = le32_to_cpu(pkt->handle);
ENTER("qla1280_error_entry");
@@ -5548,7 +4694,6 @@ qla1280_error_entry(struct scsi_qla_host *ha, response_t * pkt,
#ifdef QLA_64BIT_PTR
else if (pkt->entry_type == COMMAND_A64_TYPE) {
printk(KERN_WARNING "!qla1280: Error Entry invalid handle");
- ha->flags.isp_abort_needed = TRUE;
}
#endif
@@ -5568,49 +4713,39 @@ qla1280_error_entry(struct scsi_qla_host *ha, response_t * pkt,
static int
qla1280_abort_isp(struct scsi_qla_host *ha)
{
-#if 0
- struct device_reg *reg = ha->iobase;
-#endif
- srb_t *sp;
- scsi_lu_t *q;
+ struct srb *sp;
int status = 0;
int cnt;
- int bus, target, lun;
+ int bus;
ENTER("qla1280_abort_isp");
- ha->flags.isp_abort_needed = FALSE;
if (!ha->flags.abort_isp_active && ha->flags.online) {
- ha->flags.abort_isp_active = TRUE;
+ struct device_reg *reg = ha->iobase;
+ ha->flags.abort_isp_active = 1;
/* Disable ISP interrupts. */
qla1280_disable_intrs(ha);
+ WRT_REG_WORD(&reg->host_cmd, HC_PAUSE_RISC);
+ RD_REG_WORD(&reg->id_l);
+ printk(KERN_INFO "scsi(%li): dequeuing outstanding commands\n",
+ ha->host_no);
/* Dequeue all commands in outstanding command list. */
- for (cnt = 1; cnt < MAX_OUTSTANDING_COMMANDS; cnt++) {
+ for (cnt = 0; cnt < MAX_OUTSTANDING_COMMANDS; cnt++) {
+ Scsi_Cmnd *cmd;
sp = ha->outstanding_cmds[cnt];
if (sp) {
- ha->outstanding_cmds[cnt] = 0;
-
- /* Generate LU queue on controller, target, LUN */
- bus = SCSI_BUS_32(sp->cmd);
- target = SCSI_TCN_32(sp->cmd);
- lun = SCSI_LUN_32(sp->cmd);
- q = LU_Q(ha, bus, target, lun);
+ cmd = sp->cmd;
+ CMD_RESULT(cmd) = DID_RESET << 16;
- /* Reset outstanding command count. */
- q->q_outcnt = 0;
- q->q_flag &= ~QLA1280_QBUSY;
- q->q_flag = 0;
+ sp->cmd = NULL;
+ ha->outstanding_cmds[cnt] = NULL;
- /* Adjust watchdog timer for command. */
- /* if (sp->flags & SRB_WATCHDOG)
- sp->timeout += 2; */
+ (*cmd->scsi_done)(cmd);
- /* Place request back on top of device queue. */
sp->flags = 0;
- qla1280_putq_t(q, sp);
}
}
@@ -5629,38 +4764,21 @@ qla1280_abort_isp(struct scsi_qla_host *ha)
for (bus = 0; bus < ha->ports; bus++) {
qla1280_bus_reset(ha, bus);
}
- do {
- /* Issue marker command. */
- ha->flags.reset_marker = FALSE;
- for (bus = 0; bus < ha->ports; bus++) {
- ha->bus_settings[bus].
- reset_marker = FALSE;
- qla1280_marker(ha, bus, 0, 0,
- MK_SYNC_ALL);
- }
- } while (ha->flags.reset_marker);
-
- /* Enable host adapter target mode. */
+ /*
+ * qla1280_bus_reset() will do the marker
+ * dance - no reason to repeat here!
+ */
+#if 0
+ /* Issue marker command. */
+ ha->flags.reset_marker = 0;
for (bus = 0; bus < ha->ports; bus++) {
- if (!
- (status =
- qla1280_enable_tgt(ha, bus))) {
- for (cnt = 0; cnt < MAX_LUNS;
- cnt++) {
- /* qla1280_enable_lun(ha, bus, cnt); */
- qla1280_poll(ha);
- }
- } else
- break;
- }
-
- if (!status) {
- /* Enable ISP interrupts. */
- qla1280_enable_intrs(ha);
- ha->flags.abort_isp_active = FALSE;
- /* Restart queues that may have been stopped. */
- qla1280_restart_queues(ha);
+ ha->bus_settings[bus].
+ reset_marker = 0;
+ qla1280_marker(ha, bus, 0, 0,
+ MK_SYNC_ALL);
}
+#endif
+ ha->flags.abort_isp_active = 0;
}
}
}
@@ -5669,8 +4787,6 @@ qla1280_abort_isp(struct scsi_qla_host *ha)
printk(KERN_WARNING
"qla1280: ISP error recovery failed, board disabled");
qla1280_reset_adapter(ha);
- qla1280_abort_queues(ha);
-
dprintk(2, "qla1280_abort_isp: **** FAILED ****\n");
}
@@ -5678,86 +4794,6 @@ qla1280_abort_isp(struct scsi_qla_host *ha)
return status;
}
-/*
- * qla1280_restart_queues
- * Restart all device queues.
- *
- * Input:
- * ha = adapter block pointer.
- */
-static void
-qla1280_restart_queues(struct scsi_qla_host *ha)
-{
- scsi_lu_t *q;
- int bus, target, lun;
-
- ENTER("qla1280_restart_queues");
-
- for (bus = 0; bus < ha->ports; bus++)
- for (target = 0; target < MAX_TARGETS; target++)
- for (lun = 0; lun < MAX_LUNS; lun++) {
- q = LU_Q(ha, bus, target, lun);
- if (q != NULL) {
- if (q->q_first)
- qla1280_next(ha, q, bus);
- }
- }
- dprintk(3, "qla1280_restart_queues: exiting normally\n");
-}
-
-/*
- * qla1280_abort_queue_single
- * Abort all commands on a device queues.
- *
- * Input:
- * ha = adapter block pointer.
- */
-static void
-qla1280_abort_queue_single(struct scsi_qla_host *ha, int bus,
- int target, int lun, uint32_t stat)
-{
- scsi_lu_t *q;
- srb_t *sp, *sp_next;
-
- ENTER("qla1280_abort_queue_single");
- q = LU_Q(ha, bus, target, lun);
- if (q != NULL) {
- sp = q->q_first;
- q->q_first = q->q_last = NULL;
-
- while (sp) {
- sp_next = sp->s_next;
- CMD_RESULT(sp->cmd) = stat;
- qla1280_done_q_put(sp, &ha->done_q_first,
- &ha->done_q_last);
- sp = sp_next;
- }
- }
- LEAVE("qla1280_abort_queue_single");
-}
-
-/*
- * qla1280_abort_queues
- * Abort all commands on device queues.
- *
- * Input:
- * ha = adapter block pointer.
- */
-static void
-qla1280_abort_queues(struct scsi_qla_host *ha)
-{
- uint32_t bus, target, lun;
-
- ENTER("qla1280_abort_queues");
-
- for (bus = 0; bus < ha->ports; bus++)
- for (target = 0; target < MAX_TARGETS; target++)
- for (lun = 0; lun < MAX_LUNS; lun++)
- qla1280_abort_queue_single(ha, bus, target,
- lun, DID_RESET);
-
- LEAVE("qla1280_abort_queues");
-}
/*
* qla1280_debounce_register
@@ -5790,27 +4826,11 @@ qla1280_debounce_register(volatile u16 * addr)
return ret;
}
-static Scsi_Host_Template driver_template = {
- .proc_info = qla1280_proc_info,
- .name = "Qlogic ISP 1280/12160",
- .detect = qla1280_detect,
- .release = qla1280_release,
- .info = qla1280_info,
- .queuecommand = qla1280_queuecommand,
- .eh_abort_handler = qla1280_eh_abort,
- .eh_device_reset_handler = qla1280_eh_device_reset,
- .eh_bus_reset_handler = qla1280_eh_bus_reset,
- .eh_host_reset_handler = qla1280_eh_adapter_reset,
- .slave_configure = qla1280_slave_configure,
- .bios_param = qla1280_biosparam,
- .can_queue = 255,
- .this_id = -1,
- .sg_tablesize = SG_ALL,
- .cmd_per_lun = 3,
- .use_clustering = ENABLE_CLUSTERING, \
-};
+
+static Scsi_Host_Template driver_template = QLA1280_LINUX_TEMPLATE;
#include "scsi_module.c"
+
/************************************************************************
* qla1280_check_for_dead_scsi_bus *
* *
@@ -5823,18 +4843,7 @@ qla1280_check_for_dead_scsi_bus(struct scsi_qla_host *ha, unsigned int bus)
{
uint16_t config_reg, scsi_control;
struct device_reg *reg = ha->iobase;
-#if 0
- unsigned int bus;
- Scsi_Cmnd *cp;
- /*
- * If SCSI Bus is Dead because of bad termination,
- * we will return a status of Selection timeout.
- */
-
- cp = sp->cmd;
- bus = SCSI_BUS_32(cp);
-#endif
if (ha->bus_settings[bus].scsi_bus_dead) {
WRT_REG_WORD(&reg->host_cmd, HC_PAUSE_RISC);
config_reg = RD_REG_WORD(&reg->cfg_1);
@@ -5844,218 +4853,82 @@ qla1280_check_for_dead_scsi_bus(struct scsi_qla_host *ha, unsigned int bus)
WRT_REG_WORD(&reg->host_cmd, HC_RELEASE_RISC);
if (scsi_control == SCSI_PHASE_INVALID) {
- ha->bus_settings[bus].scsi_bus_dead = TRUE;
+ ha->bus_settings[bus].scsi_bus_dead = 1;
#if 0
CMD_RESULT(cp) = DID_NO_CONNECT << 16;
- CMD_HANDLE(cp) = NULL;
+ CMD_HANDLE(cp) = INVALID_HANDLE;
/* ha->actthreads--; */
(*(cp)->scsi_done)(cp);
#endif
- return TRUE; /* bus is dead */
+ return 1; /* bus is dead */
} else {
- ha->bus_settings[bus].scsi_bus_dead = FALSE;
+ ha->bus_settings[bus].scsi_bus_dead = 0;
ha->bus_settings[bus].failed_reset_count = 0;
}
}
- return FALSE; /* bus is not dead */
+ return 0; /* bus is not dead */
}
static void
-qla12160_get_target_parameters(struct scsi_qla_host *ha, uint32_t bus,
- uint32_t target, uint32_t lun)
+qla12160_get_target_parameters(struct scsi_qla_host *ha, Scsi_Device *device)
{
uint16_t mb[MAILBOX_REGISTER_COUNT];
+ int bus, target, lun;
+
+ bus = device->channel;
+ target = device->id;
+ lun = device->lun;
+
mb[0] = MBC_GET_TARGET_PARAMETERS;
mb[1] = (uint16_t) (bus ? target | BIT_7 : target);
mb[1] <<= 8;
qla1280_mailbox_command(ha, BIT_6 | BIT_3 | BIT_2 | BIT_1 | BIT_0,
&mb[0]);
- if (mb[3] != 0) {
- printk(KERN_INFO
- "scsi(%ld:%d:%d:%d): Synchronous transfer at period "
- "%d, offset %d. \n", ha->host_no, bus, target, lun,
- (mb[3] & 0xff), (mb[3] >> 8));
- }
-
- if ((mb[2] & BIT_5) && ((mb[6] >> 8) & 0xff) >= 2) {
- printk(KERN_INFO
- "scsi(%ld:%d:%d:%d): Dual Transition enabled.\n",
- ha->host_no, bus, target, lun);
- }
-}
-
-#ifdef QL_DEBUG_ROUTINES
-/****************************************************************************/
-/* Driver Debug Functions. */
-/****************************************************************************/
-
-/*
- * Get byte from I/O port
- */
-static u8
-qla1280_getbyte (u8 * port)
-{
- u8 ret;
-#if MEMORY_MAPPED_IO
- ret = readb((unsigned long) port);
-#else
- ret = inb((unsigned long) port);
-#endif
-
- if (ql_debug_print)
- printk(KERN_DEBUG
- "qla1280_getbyte: address = 0x%p, data = 0x%x", port,
- ret);
-
- return ret;
-}
-
-/*
- * Get word from I/O port
- */
-static u16
-qla1280_getword (u16 * port)
-{
- u16 ret;
-
-#if MEMORY_MAPPED_IO
- ret = readw(unsigned long) port;
-#else
- ret = inw((unsigned long) port);
-#endif
-
- if (ql_debug_print)
- printk(KERN_DEBUG
- "qla1280_getbyte: address = 0x%p, data = 0x%x", port,
- ret);
-
- return ret;
-}
-
-/*
- * Get double word from I/O port
- */
-static u32
-qla1280_getdword (u32 * port)
-{
- u32 ret;
+ printk(KERN_INFO "scsi(%li:%d:%d:%d):", ha->host_no, bus, target, lun);
-#if MEMORY_MAPPED_IO
- ret = readl((unsigned long) port);
-#else
- ret = inl((unsigned long) port);
-#endif
-
- if (ql_debug_print)
- printk(KERN_DEBUG
- "qla1280_getbyte: address = 0x%p, data = 0x%x", port,
- ret);
-
- return ret;
-}
-
-/*
- * Send byte to I/O port
- */
-static void
-qla1280_putbyte(u8 * port, u8 data)
-{
-#if MEMORY_MAPPED_IO
- writeb(data, (unsigned long) port);
-#else
- outb(data, (unsigned long) port);
-#endif
-
- if (ql_debug_print)
- printk(KERN_DEBUG
- "qla1280_getbyte: address = 0x%p, data = 0x%x", port,
- data);
-}
-
-/*
- * Send word to I/O port
- */
-static void
-qla1280_putword(u16 * port, u16 data)
-{
-#if MEMORY_MAPPED_IO
- writew(data, (unsigned long) port);
-#else
- outw(data, (unsigned long) port);
-#endif
-
- if (ql_debug_print)
- printk(KERN_DEBUG
- "qla1280_getbyte: address = 0x%p, data = 0x%x", port,
- data);
-}
-
-/*
- * Send double word to I/O port
- */
-static void
-qla1280_putdword(u32 * port, u32 data)
-{
-#if MEMORY_MAPPED_IO
- writel(data, (unsigned long) port);
-#else
- outl(data, (unsigned long) port);
-#endif
+ if (mb[3] != 0) {
+ printk(" Sync: period %d, offset %d",
+ (mb[3] & 0xff), (mb[3] >> 8));
+ if (mb[2] & BIT_13)
+ printk(", Wide");
+ if ((mb[2] & BIT_5) && ((mb[6] >> 8) & 0xff) >= 2)
+ printk(", DT");
+ } else
+ printk(" Async");
- if (ql_debug_print)
- printk(KERN_DEBUG
- "qla1280_getbyte: address = 0x%p, data = 0x%x", port,
- data);
+ if (device->tagged_queue)
+ printk(", Tagged queuing: depth %d", device->queue_depth);
+ printk("\n");
}
-/*
- * Dummy function to prevent warnings for
- * declared and unused debug functions
- */
-static void
-qla1280_debug(void)
-{
- qla1280_getbyte(0);
- qla1280_getword(0);
- qla1280_getdword(0);
- qla1280_putbyte(0, 0);
- qla1280_putword(0, 0);
- qla1280_putdword(0, 0);
-}
+#if DEBUG_QLA1280
static void
__qla1280_dump_buffer(char *b, int size)
{
int cnt;
u8 c;
- if (ql_debug_print) {
- printk(KERN_DEBUG
- " 0 1 2 3 4 5 6 7 8 9 Ah "
- "Bh Ch Dh Eh Fh\n");
- printk(KERN_DEBUG
- "---------------------------------------------"
- "------------------\n");
-
- for (cnt = 0; cnt < size;) {
- c = *b++;
- if (c < 16)
- printk(' ');
- printk("0x%x", c);
- cnt++;
- if (!(cnt % 16))
- printk("\n");
- else if (c < 10)
- printk(" ");
- else
- printk(' ');
- }
- if (cnt % 16)
+ printk(KERN_DEBUG " 0 1 2 3 4 5 6 7 8 9 Ah "
+ "Bh Ch Dh Eh Fh\n");
+ printk(KERN_DEBUG "---------------------------------------------"
+ "------------------\n");
+
+ for (cnt = 0; cnt < size;) {
+ c = *b++;
+
+ printk("0x%02x", c);
+ cnt++;
+ if (!(cnt % 16))
printk("\n");
+ else
+ printk(" ");
}
+ if (cnt % 16)
+ printk("\n");
}
/**************************************************************************
@@ -6063,20 +4936,21 @@ __qla1280_dump_buffer(char *b, int size)
*
**************************************************************************/
static void
-qla1280_print_scsi_cmd(Scsi_Cmnd * cmd)
+__qla1280_print_scsi_cmd(Scsi_Cmnd * cmd)
{
struct scsi_qla_host *ha;
- struct Scsi_Host *host = cmd->host;
- srb_t *sp;
+ struct Scsi_Host *host = CMD_HOST(cmd);
+ struct srb *sp;
/* struct scatterlist *sg; */
int i;
ha = (struct scsi_qla_host *)host->hostdata;
- sp = (srb_t *)CMD_SP(cmd);
+ sp = (struct srb *)CMD_SP(cmd);
printk("SCSI Command @= 0x%p, Handle=0x%p\n", cmd, CMD_HANDLE(cmd));
printk(" chan=%d, target = 0x%02x, lun = 0x%02x, cmd_len = 0x%02x\n",
- cmd->channel, cmd->target, cmd->lun, cmd->cmd_len);
+ SCSI_BUS_32(cmd), SCSI_TCN_32(cmd), SCSI_LUN_32(cmd),
+ CMD_CDBLEN(cmd));
printk(" CDB = ");
for (i = 0; i < cmd->cmd_len; i++) {
printk("0x%02x ", cmd->cmnd[i]);
@@ -6093,8 +4967,8 @@ qla1280_print_scsi_cmd(Scsi_Cmnd * cmd)
printk(" tag=%d, flags=0x%x, transfersize=0x%x \n",
cmd->tag, cmd->flags, cmd->transfersize);
printk(" Pid=%li, SP=0x%p\n", cmd->pid, CMD_SP(cmd));
- printk(" underflow size = 0x%x, direction=0x%x, req.cmd=0x%x \n",
- cmd->underflow, sp->dir, cmd->request->cmd);
+ printk(" underflow size = 0x%x, direction=0x%x\n",
+ cmd->underflow, sp->dir);
}
/**************************************************************************
@@ -6106,104 +4980,139 @@ ql1280_dump_device(struct scsi_qla_host *ha)
{
Scsi_Cmnd *cp;
- srb_t *sp;
+ struct srb *sp;
int i;
- if (ql_debug_print) {
- printk(KERN_DEBUG "Outstanding Commands on controller:\n");
- for (i = 0; i < MAX_OUTSTANDING_COMMANDS; i++) {
- if ((sp = ha->outstanding_cmds[i]) == NULL)
- continue;
- if ((cp = sp->cmd) == NULL)
- continue;
- qla1280_print_scsi_cmd(1, cp);
- }
+ printk(KERN_DEBUG "Outstanding Commands on controller:\n");
+
+ for (i = 0; i < MAX_OUTSTANDING_COMMANDS; i++) {
+ if ((sp = ha->outstanding_cmds[i]) == NULL)
+ continue;
+ if ((cp = sp->cmd) == NULL)
+ continue;
+ qla1280_print_scsi_cmd(1, cp);
}
}
#endif
-#if STOP_ON_ERROR
-/**************************************************************************
- * ql1280_panic
- *
- **************************************************************************/
-static void
-qla1280_panic(char *cp, struct Scsi_Host *host)
+
+enum tokens {
+ TOKEN_NVRAM,
+ TOKEN_SYNC,
+ TOKEN_WIDE,
+ TOKEN_PPR,
+ TOKEN_VERBOSE,
+ TOKEN_DEBUG,
+};
+
+struct setup_tokens {
+ char *token;
+ int val;
+};
+
+static struct setup_tokens setup_token[] __initdata =
{
- struct scsi_qla_host *ha;
- long *fp;
+ { "nvram", TOKEN_NVRAM },
+ { "sync", TOKEN_SYNC },
+ { "wide", TOKEN_WIDE },
+ { "ppr", TOKEN_PPR },
+ { "verbose", TOKEN_VERBOSE },
+ { "debug", TOKEN_DEBUG },
+};
- ha = (struct scsi_qla_host *)host->hostdata;
- printk(KERN_ERR "qla1280 - PANIC: %s\n", cp);
- printk(KERN_ERR "Current time=0x%lx\n", jiffies);
- printk(KERN_ERR "Number of pending commands =0x%lx\n", ha->actthreads);
- printk(KERN_ERR "Number of SCSI queued commands =0x%lx\n",
- ha->qthreads);
- printk(KERN_ERR "Number of free entries = (%d)\n", ha->req_q_cnt);
- printk(KERN_ERR "Request Queue @ 0x%lx, Response Queue @ 0x%lx\n",
- ha->request_dma, ha->response_dma);
- printk(KERN_ERR "Request In Ptr %d\n", ha->req_ring_index);
- fp = (long *) &ha->flags;
- printk(KERN_ERR "HA flags =0x%lx\n", *fp);
- if (ql_debug_level >= 2) {
- ql_debug_print = 1;
-#if 0
- ql1280_dump_device((struct scsi_qla_host *)host->hostdata);
-#endif
- }
- sti();
- panic("Ooops");
- /* cli();
- for(;;)
- {
- barrier();
- sti();
- }
- */
-}
-#endif
-#ifdef MODULE
/**************************************************************************
* qla1280_setup
*
- * Handle Linux boot parameters. This routine allows for assigning a value
- * to a parameter with a ':' between the parameter and the value.
- * ie. qla1280=max_reqs:0x0A,verbose
+ * Handle boot parameters. This really needs to be changed so one
+ * can specify per adapter parameters.
**************************************************************************/
-void
-qla1280_setup(char *s, int *dummy)
+int __init
+qla1280_setup(char *s)
{
- char *end, *str, *cp;
-
- printk(KERN_INFO "scsi: Processing Option str = %s\n", s);
- end = strchr (s, '\0');
- /* locate command */
- str = s;
- for (cp = s; *cp && cp != end; cp++) {
- cp = qla1280_get_token(cp, str);
- printk(KERN_INFO "scsi: token str = %s\n", str);
- /* if found execute routine */
+ char *cp, *ptr;
+ unsigned long val;
+ int toke;
+
+ cp = s;
+
+ while (cp && (ptr = strchr(cp, ':'))) {
+ ptr++;
+ if (!strcmp(ptr, "yes")) {
+ val = 0x10000;
+ ptr += 3;
+ } else if (!strcmp(ptr, "no")) {
+ val = 0;
+ ptr += 2;
+ } else
+ val = simple_strtoul(ptr, &ptr, 0);
+
+ switch ((toke = qla1280_get_token(cp))) {
+ case TOKEN_NVRAM:
+ if (!val)
+ driver_setup.no_nvram = 1;
+ break;
+ case TOKEN_SYNC:
+ if (!val)
+ driver_setup.no_sync = 1;
+ else if (val != 0x10000)
+ driver_setup.sync_mask = val;
+ break;
+ case TOKEN_WIDE:
+ if (!val)
+ driver_setup.no_wide = 1;
+ else if (val != 0x10000)
+ driver_setup.wide_mask = val;
+ break;
+ case TOKEN_PPR:
+ if (!val)
+ driver_setup.no_ppr = 1;
+ else if (val != 0x10000)
+ driver_setup.ppr_mask = val;
+ break;
+ case TOKEN_VERBOSE:
+ qla1280_verbose = val;
+ break;
+ default:
+ printk(KERN_INFO "qla1280: unknown boot option %s\n",
+ cp);
+ }
+
+ cp = strchr(ptr, ';');
+ if (cp)
+ cp++;
+ else {
+ break;
+ }
}
+ return 1;
}
-static char *
-qla1280_get_token(char *cmdline, char *str)
+
+static int
+qla1280_get_token(char *str)
{
- register char *cp = cmdline;
-
- /* skip preceeding spaces */
- while (strchr (cp, ' '))
- ++cp;
- /* symbol starts here */
- str = cp;
- /* skip char if not a space or : */
- while (*cp && !(strchr (cp, ' ') || strchr (cp, ':')))
- cp++;
- *cp = '\0';
- return cp;
+ char *sep;
+ long ret = -1;
+ int i, len;
+
+ len = sizeof(setup_token)/sizeof(struct setup_tokens);
+
+ sep = strchr(str, ':');
+
+ if (sep) {
+ for (i = 0; i < len; i++){
+
+ if (!strncmp(setup_token[i].token, str, (sep - str))) {
+ ret = setup_token[i].val;
+ break;
+ }
+ }
+ }
+
+ return ret;
}
-#endif
+
/*
* Overrides for Emacs so that we almost follow Linus's tabbing style.
diff --git a/drivers/scsi/qla1280.h b/drivers/scsi/qla1280.h
index 103200cb25ed..177107d31976 100644
--- a/drivers/scsi/qla1280.h
+++ b/drivers/scsi/qla1280.h
@@ -21,18 +21,6 @@
#define _IO_HBA_QLA1280_H /* subject to change without notice */
#ifndef HOSTS_C /* included in hosts.c */
-/*
- * Enable define statement to ignore Data Underrun Errors,
- * remove define statement to enable detection.
- */
-/* #define DATA_UNDERRUN_ERROR_DISABLE */
-
-#ifndef TRUE
-#define TRUE 1
-#endif
-#ifndef FALSE
-#define FALSE 0
-#endif
/*
* Data bit definitions.
@@ -70,48 +58,13 @@
#define BIT_30 0x40000000
#define BIT_31 0x80000000
-/*
- * Local Macro Definitions.
- */
-#if defined(QL_DEBUG_LEVEL_1) || defined(QL_DEBUG_LEVEL_2) || \
- defined(QL_DEBUG_LEVEL_3) || defined(QL_DEBUG_LEVEL_4) || \
- defined(QL_DEBUG_LEVEL_5) || defined(QL_DEBUG_LEVEL_6) || \
- defined(QL_DEBUG_LEVEL_7)
-#define QL_DEBUG_ROUTINES
-#endif
-
-/*
- * I/O port macros
-*/
-/* #define MEMORY_MAPPED_IO *//* Enable memory mapped I/O */
-#undef MEMORY_MAPPED_IO /* Disable memory mapped I/O */
-
-#ifdef QL_DEBUG_LEVEL_1
-#define RD_REG_BYTE(addr) qla1280_getbyte((u8 *)addr)
-#define RD_REG_WORD(addr) qla1280_getword((u16 *)addr)
-#define RD_REG_DWORD(addr) qla1280_getdword((u32 *)addr)
-#define WRT_REG_BYTE(addr, data) qla1280_putbyte((u8 *)addr, data)
-#define WRT_REG_WORD(addr, data) qla1280_putword((u16 *)addr, data)
-#define WRT_REG_DWORD(addr, data) qla1280_putdword((u32 *)addr, data)
-#else /* QL_DEBUG_LEVEL_1 */
-
-#ifdef MEMORY_MAPPED_IO
-#define RD_REG_BYTE(addr) readb(addr)
+#if MEMORY_MAPPED_IO
#define RD_REG_WORD(addr) readw(addr)
-#define RD_REG_DWORD(addr) readl(addr)
-#define WRT_REG_BYTE(addr, data) writeb(data, addr)
#define WRT_REG_WORD(addr, data) writew(data, addr)
-#define WRT_REG_DWORD(addr, data) writel(data, addr)
#else /* MEMORY_MAPPED_IO */
-#define RD_REG_BYTE(addr) inb((unsigned long)addr)
#define RD_REG_WORD(addr) inw((unsigned long)addr)
-#define RD_REG_DWORD(addr) inl((unsigned long)addr)
-/* Parameters are reversed in Linux */
-#define WRT_REG_BYTE(addr, data) outb(data, (unsigned long)addr)
#define WRT_REG_WORD(addr, data) outw(data, (unsigned long)addr)
-#define WRT_REG_DWORD(addr, data) outl(data, (unsigned long)addr)
#endif /* MEMORY_MAPPED_IO */
-#endif /* QL_DEBUG_LEVEL_1 */
/*
* Host adapter default definitions.
@@ -133,16 +86,14 @@
/* Command retry count (0-65535) */
#define COMMAND_RETRY_COUNT 255
-/* Maximum outstanding commands in ISP queues (1-65535) */
+/* Maximum outstanding commands in ISP queues */
#define MAX_OUTSTANDING_COMMANDS 512
+#define INVALID_HANDLE (MAX_OUTSTANDING_COMMANDS + 2)
/* ISP request and response entry counts (37-65535) */
#define REQUEST_ENTRY_CNT 256 /* Number of request entries. */
#define RESPONSE_ENTRY_CNT 16 /* Number of response entries. */
-/* Maximum equipage per controller */
-#define MAX_EQ (MAX_BUSES * MAX_TARGETS * MAX_LUNS)
-
/* Number of segments 1 - 65535 */
#define SG_SEGMENTS 32 /* Cmd entry + 6 continuations */
@@ -150,20 +101,20 @@
* SCSI Request Block structure (sp) that is placed
* on cmd->SCp location of every I/O
*/
-typedef struct srb {
+struct srb {
Scsi_Cmnd *cmd; /* (4/8) SCSI command block */
struct srb *s_next; /* (4/8) Next block on LU queue */
struct srb *s_prev; /* (4/8) Previous block on LU queue */
uint8_t flags; /* (1) Status flags. */
uint8_t dir; /* direction of transfer */
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,18)
+ /*
+ * This should be moved around to save space.
+ */
dma_addr_t saved_dma_handle; /* for unmap of single transfers */
/* NOTE: the sp->cmd will be NULL when this completion is
* called, so you should know the scsi_cmnd when using this */
struct completion *wait;
-#endif
-
-} srb_t;
+};
/*
* SRB flag definitions
@@ -176,9 +127,9 @@ typedef struct srb {
/*
* Logical Unit Queue structure
*/
-typedef struct scsi_lu {
- srb_t *q_first; /* First block on LU queue */
- srb_t *q_last; /* Last block on LU queue */
+struct scsi_lu {
+ struct srb *q_first; /* First block on LU queue */
+ struct srb *q_last; /* Last block on LU queue */
uint8_t q_flag; /* LU queue state flags */
uint8_t q_sense[16]; /* sense data */
unsigned long io_cnt; /* total xfer count */
@@ -187,12 +138,7 @@ typedef struct scsi_lu {
unsigned long w_cnt; /* total writes */
unsigned long r_cnt; /* total reads */
uint16_t q_outcnt; /* Pending jobs for this LU */
-#if QL1280_TARGET_MODE_SUPPORT
- void (*q_func)(); /* Target driver event handler */
- int32_t q_param; /* Target driver event param */
- uint8_t q_lock; /* Device Queue Lock */
-#endif
-} scsi_lu_t;
+};
/*
* Logical Unit flags
@@ -317,44 +263,47 @@ struct device_reg {
/*
* ISP mailbox commands
*/
-#define MBC_NOP 0 /* No Operation. */
-#define MBC_LOAD_RAM 1 /* Load RAM. */
-#define MBC_EXECUTE_FIRMWARE 2 /* Execute firmware. */
-#define MBC_DUMP_RAM 3 /* Dump RAM contents */
-#define MBC_WRITE_RAM_WORD 4 /* Write ram word. */
-#define MBC_READ_RAM_WORD 5 /* Read ram word. */
-#define MBC_MAILBOX_REGISTER_TEST 6 /* Wrap incoming mailboxes */
-#define MBC_VERIFY_CHECKSUM 7 /* Verify checksum. */
-#define MBC_ABOUT_FIRMWARE 8 /* Get firmware revision. */
-#define MBC_INIT_REQUEST_QUEUE 0x10 /* Initialize request queue. */
-#define MBC_INIT_RESPONSE_QUEUE 0x11 /* Initialize response queue. */
-#define MBC_EXECUTE_IOCB 0x12 /* Execute IOCB command. */
-#define MBC_ABORT_COMMAND 0x15 /* Abort IOCB command. */
-#define MBC_ABORT_DEVICE 0x16 /* Abort device (ID/LUN). */
-#define MBC_ABORT_TARGET 0x17 /* Abort target (ID). */
-#define MBC_BUS_RESET 0x18 /* SCSI bus reset. */
-#define MBC_GET_RETRY_COUNT 0x22 /* Get retry count and delay. */
-#define MBC_GET_TARGET_PARAMETERS 0x28 /* Get target parameters. */
-#define MBC_SET_INITIATOR_ID 0x30 /* Set initiator SCSI ID. */
-#define MBC_SET_SELECTION_TIMEOUT 0x31 /* Set selection timeout. */
-#define MBC_SET_RETRY_COUNT 0x32 /* Set retry count and delay. */
-#define MBC_SET_TAG_AGE_LIMIT 0x33 /* Set tag age limit. */
-#define MBC_SET_CLOCK_RATE 0x34 /* Set clock rate. */
-#define MBC_SET_ACTIVE_NEGATION 0x35 /* Set active negation state. */
-#define MBC_SET_ASYNC_DATA_SETUP 0x36 /* Set async data setup time. */
-#define MBC_SET_PCI_CONTROL 0x37 /* Set BUS control parameters. */
-#define MBC_SET_TARGET_PARAMETERS 0x38 /* Set target parameters. */
-#define MBC_SET_DEVICE_QUEUE 0x39 /* Set device queue parameters */
-#define MBC_SET_SYSTEM_PARAMETER 0x45 /* Set system parameter word. */
-#define MBC_SET_FIRMWARE_FEATURES 0x4A /* Set firmware feature word. */
-#define MBC_INIT_REQUEST_QUEUE_A64 0x52 /* Initialize request queue A64 */
-#define MBC_INIT_RESPONSE_QUEUE_A64 0x53 /* Initialize response q A64. */
-#define MBC_ENABLE_TARGET_MODE 0x55 /* Enable target mode. */
+#define MBC_NOP 0 /* No Operation */
+#define MBC_LOAD_RAM 1 /* Load RAM */
+#define MBC_EXECUTE_FIRMWARE 2 /* Execute firmware */
+#define MBC_DUMP_RAM 3 /* Dump RAM contents */
+#define MBC_WRITE_RAM_WORD 4 /* Write ram word */
+#define MBC_READ_RAM_WORD 5 /* Read ram word */
+#define MBC_MAILBOX_REGISTER_TEST 6 /* Wrap incoming mailboxes */
+#define MBC_VERIFY_CHECKSUM 7 /* Verify checksum */
+#define MBC_ABOUT_FIRMWARE 8 /* Get firmware revision */
+#define MBC_INIT_REQUEST_QUEUE 0x10 /* Initialize request queue */
+#define MBC_INIT_RESPONSE_QUEUE 0x11 /* Initialize response queue */
+#define MBC_EXECUTE_IOCB 0x12 /* Execute IOCB command */
+#define MBC_ABORT_COMMAND 0x15 /* Abort IOCB command */
+#define MBC_ABORT_DEVICE 0x16 /* Abort device (ID/LUN) */
+#define MBC_ABORT_TARGET 0x17 /* Abort target (ID) */
+#define MBC_BUS_RESET 0x18 /* SCSI bus reset */
+#define MBC_GET_RETRY_COUNT 0x22 /* Get retry count and delay */
+#define MBC_GET_TARGET_PARAMETERS 0x28 /* Get target parameters */
+#define MBC_SET_INITIATOR_ID 0x30 /* Set initiator SCSI ID */
+#define MBC_SET_SELECTION_TIMEOUT 0x31 /* Set selection timeout */
+#define MBC_SET_RETRY_COUNT 0x32 /* Set retry count and delay */
+#define MBC_SET_TAG_AGE_LIMIT 0x33 /* Set tag age limit */
+#define MBC_SET_CLOCK_RATE 0x34 /* Set clock rate */
+#define MBC_SET_ACTIVE_NEGATION 0x35 /* Set active negation state */
+#define MBC_SET_ASYNC_DATA_SETUP 0x36 /* Set async data setup time */
+#define MBC_SET_PCI_CONTROL 0x37 /* Set BUS control parameters */
+#define MBC_SET_TARGET_PARAMETERS 0x38 /* Set target parameters */
+#define MBC_SET_DEVICE_QUEUE 0x39 /* Set device queue parameters */
+#define MBC_SET_RESET_DELAY_PARAMETERS 0x3A /* Set reset delay parameters */
+#define MBC_SET_SYSTEM_PARAMETER 0x45 /* Set system parameter word */
+#define MBC_SET_FIRMWARE_FEATURES 0x4A /* Set firmware feature word */
+#define MBC_INIT_REQUEST_QUEUE_A64 0x52 /* Initialize request queue A64 */
+#define MBC_INIT_RESPONSE_QUEUE_A64 0x53 /* Initialize response q A64 */
+#define MBC_ENABLE_TARGET_MODE 0x55 /* Enable target mode */
+#define MBC_SET_DATA_OVERRUN_RECOVERY 0x5A /* Set data overrun recovery mode */
/*
* ISP Get/Set Target Parameters mailbox command control flags.
*/
-#define TP_RENEGOTIATE BIT_8 /* Renegotiate on error. */
+#define TP_PPR BIT_5 /* PPR */
+#define TP_RENEGOTIATE BIT_8 /* Renegotiate on error. */
#define TP_STOP_QUEUE BIT_9 /* Stop que on check condition */
#define TP_AUTO_REQUEST_SENSE BIT_10 /* Automatic request sense. */
#define TP_TAGGED_QUEUE BIT_11 /* Tagged queuing. */
@@ -374,167 +323,9 @@ struct device_reg {
#define NV_DELAY_COUNT 10
/*
- * QLogic ISP1280 NVRAM structure definition.
- *
- * NOTE: the firmware structure is byte reversed on big-endian systems
- * because it is read a word at a time from the chip, so the in-memory
- * representation becomes correct
+ * QLogic ISP1280/ISP12160 NVRAM structure definition.
*/
-typedef struct {
-#if defined(__BIG_ENDIAN)
- uint8_t id1; /* 1 */
- uint8_t id0; /* 0 */
-
- uint8_t id3; /* 3 */
- uint8_t id2; /* 2 */
-
- struct {
- uint8_t bios_configuration_mode:2;
- uint8_t bios_disable:1;
- uint8_t selectable_scsi_boot_enable:1;
- uint8_t cd_rom_boot_enable:1;
- uint8_t disable_loading_risc_code:1;
- uint8_t enable_64bit_addressing:1;
- uint8_t unused_7:1;
- } cntr_flags_1; /* 5 */
- uint8_t version; /* 4 */
-
- struct {
- uint8_t boot_lun_number:5;
- uint8_t scsi_bus_number:1;
- uint8_t unused_6:1;
- uint8_t unused_7:1;
- uint8_t boot_target_number:4;
- uint8_t unused_12:1;
- uint8_t unused_13:1;
- uint8_t unused_14:1;
- uint8_t unused_15:1;
- } cntr_flags_2; /* 6, 7 */
-
- uint16_t unused_8; /* 8, 9 */
- uint16_t unused_10; /* 10, 11 */
- uint16_t unused_12; /* 12, 13 */
- uint16_t unused_14; /* 14, 15 */
-
- /* Termination
- * 0 = Disable, 1 = high only, 3 = Auto term
- */
- union {
- uint8_t c;
- struct {
- uint8_t scsi_bus_1_control:2;
- uint8_t scsi_bus_0_control:2;
- uint8_t unused_0:1;
- uint8_t unused_1:1;
- uint8_t unused_2:1;
- uint8_t auto_term_support:1;
- } f;
- } termination; /* 17 */
- union {
- uint8_t c;
- struct {
- uint8_t reserved:2;
- uint8_t burst_enable:1;
- uint8_t reserved_1:1;
- uint8_t fifo_threshold:4;
- } f;
- } isp_config; /* 16 */
-
-
- uint16_t isp_parameter; /* 18, 19 */
-
- union {
- uint16_t w;
- struct {
- uint16_t enable_fast_posting:1;
- uint16_t report_lvd_bus_transition:1;
- uint16_t unused_2:1;
- uint16_t unused_3:1;
- uint16_t unused_4:1;
- uint16_t unused_5:1;
- uint16_t unused_6:1;
- uint16_t unused_7:1;
- uint16_t unused_8:1;
- uint16_t unused_9:1;
- uint16_t unused_10:1;
- uint16_t unused_11:1;
- uint16_t unused_12:1;
- uint16_t unused_13:1;
- uint16_t unused_14:1;
- uint16_t unused_15:1;
- } f;
- } firmware_feature; /* 20, 21 */
-
- uint16_t unused_22; /* 22, 23 */
-
- struct {
- uint8_t bus_reset_delay; /* 25 */
- struct {
- uint8_t initiator_id:4;
- uint8_t scsi_reset_disable:1;
- uint8_t scsi_bus_size:1;
- uint8_t scsi_bus_type:1;
- uint8_t unused_7:1;
- } config_1; /* 24 */
-
- uint8_t retry_delay; /* 27 */
- uint8_t retry_count; /* 26 */
-
- uint8_t unused_29; /* 29 */
- struct {
- uint8_t async_data_setup_time:4;
- uint8_t req_ack_active_negation:1;
- uint8_t data_line_active_negation:1;
- uint8_t unused_6:1;
- uint8_t unused_7:1;
- } config_2; /* 28 */
-
-
- uint16_t selection_timeout; /* 30, 31 */
- uint16_t max_queue_depth; /* 32, 33 */
-
- uint16_t unused_34; /* 34, 35 */
- uint16_t unused_36; /* 36, 37 */
- uint16_t unused_38; /* 38, 39 */
-
- struct {
- uint8_t execution_throttle; /* 41 */
- union {
- uint8_t c;
- struct {
- uint8_t renegotiate_on_error:1;
- uint8_t stop_queue_on_check:1;
- uint8_t auto_request_sense:1;
- uint8_t tag_queuing:1;
- uint8_t sync_data_transfers:1;
- uint8_t wide_data_transfers:1;
- uint8_t parity_checking:1;
- uint8_t disconnect_allowed:1;
- } f;
- } parameter; /* 40 */
-
- struct {
- uint8_t sync_offset:4;
- uint8_t device_enable:1;
- uint8_t lun_disable:1;
- uint8_t unused_6:1;
- uint8_t unused_7:1;
- } flags; /* 43 */
- uint8_t sync_period; /* 42 */
-
-
- uint16_t unused_44; /* 44, 45 */
- } target[MAX_TARGETS];
- } bus[MAX_BUSES];
-
- uint16_t unused_248; /* 248, 249 */
-
- uint16_t subsystem_id[2]; /* 250, 251, 252, 253 */
-
- uint8_t chksum; /* 255 */
- uint8_t unused_254; /* 254 */
-
-#elif defined(__LITTLE_ENDIAN)
+struct nvram {
uint8_t id0; /* 0 */
uint8_t id1; /* 1 */
uint8_t id2; /* 2 */
@@ -552,174 +343,6 @@ typedef struct {
} cntr_flags_1; /* 5 */
struct {
- uint8_t boot_lun_number:5;
- uint8_t scsi_bus_number:1;
- uint8_t unused_6:1;
- uint8_t unused_7:1;
- uint8_t boot_target_number:4;
- uint8_t unused_12:1;
- uint8_t unused_13:1;
- uint8_t unused_14:1;
- uint8_t unused_15:1;
- } cntr_flags_2; /* 6, 7 */
-
- uint16_t unused_8; /* 8, 9 */
- uint16_t unused_10; /* 10, 11 */
- uint16_t unused_12; /* 12, 13 */
- uint16_t unused_14; /* 14, 15 */
-
- union {
- uint8_t c;
- struct {
- uint8_t reserved:2;
- uint8_t burst_enable:1;
- uint8_t reserved_1:1;
- uint8_t fifo_threshold:4;
- } f;
- } isp_config; /* 16 */
-
- /* Termination
- * 0 = Disable, 1 = high only, 3 = Auto term
- */
- union {
- uint8_t c;
- struct {
- uint8_t scsi_bus_1_control:2;
- uint8_t scsi_bus_0_control:2;
- uint8_t unused_0:1;
- uint8_t unused_1:1;
- uint8_t unused_2:1;
- uint8_t auto_term_support:1;
- } f;
- } termination; /* 17 */
-
- uint16_t isp_parameter; /* 18, 19 */
-
- union {
- uint16_t w;
- struct {
- uint8_t enable_fast_posting:1;
- uint8_t report_lvd_bus_transition:1;
- uint8_t unused_2:1;
- uint8_t unused_3:1;
- uint8_t unused_4:1;
- uint8_t unused_5:1;
- uint8_t unused_6:1;
- uint8_t unused_7:1;
- uint8_t unused_8:1;
- uint8_t unused_9:1;
- uint8_t unused_10:1;
- uint8_t unused_11:1;
- uint8_t unused_12:1;
- uint8_t unused_13:1;
- uint8_t unused_14:1;
- uint8_t unused_15:1;
- } f;
- } firmware_feature; /* 20, 21 */
-
- uint16_t unused_22; /* 22, 23 */
-
- struct {
- struct {
- uint8_t initiator_id:4;
- uint8_t scsi_reset_disable:1;
- uint8_t scsi_bus_size:1;
- uint8_t scsi_bus_type:1;
- uint8_t unused_7:1;
- } config_1; /* 24 */
-
- uint8_t bus_reset_delay; /* 25 */
- uint8_t retry_count; /* 26 */
- uint8_t retry_delay; /* 27 */
-
- struct {
- uint8_t async_data_setup_time:4;
- uint8_t req_ack_active_negation:1;
- uint8_t data_line_active_negation:1;
- uint8_t unused_6:1;
- uint8_t unused_7:1;
- } config_2; /* 28 */
-
- uint8_t unused_29; /* 29 */
-
- uint16_t selection_timeout; /* 30, 31 */
- uint16_t max_queue_depth; /* 32, 33 */
-
- uint16_t unused_34; /* 34, 35 */
- uint16_t unused_36; /* 36, 37 */
- uint16_t unused_38; /* 38, 39 */
-
- struct {
- union {
- uint8_t c;
- struct {
- uint8_t renegotiate_on_error:1;
- uint8_t stop_queue_on_check:1;
- uint8_t auto_request_sense:1;
- uint8_t tag_queuing:1;
- uint8_t sync_data_transfers:1;
- uint8_t wide_data_transfers:1;
- uint8_t parity_checking:1;
- uint8_t disconnect_allowed:1;
- } f;
- } parameter; /* 40 */
-
- uint8_t execution_throttle; /* 41 */
- uint8_t sync_period; /* 42 */
-
- struct {
- uint8_t sync_offset:4;
- uint8_t device_enable:1;
- uint8_t lun_disable:1;
- uint8_t unused_6:1;
- uint8_t unused_7:1;
- } flags; /* 43 */
-
- uint16_t unused_44; /* 44, 45 */
- } target[MAX_TARGETS];
- } bus[MAX_BUSES];
-
- uint16_t unused_248; /* 248, 249 */
-
- uint16_t subsystem_id[2]; /* 250, 251, 252, 253 */
-
- uint8_t unused_254; /* 254 */
-
- uint8_t chksum; /* 255 */
-#else
-#error neither __BIG_ENDIAN nor __LITTLE_ENDIAN is defined
-#endif
-} nvram_t;
-
-/*
- * QLogic ISP12160 NVRAM structure definition.
- *
- * NOTE: the firmware structure is byte reversed on big-endian systems
- * because it is read a word at a time from the chip, so the in-memory
- * representation becomes correct
- */
-typedef struct {
-#if defined(__BIG_ENDIAN)
- uint8_t id1; /* 1 */
- uint8_t id0; /* 0 */
-
- uint8_t id3; /* 3 */
- uint8_t id2; /* 2 */
-
- /* Host/Bios Flags */
- struct {
- uint8_t bios_configuration_mode:2;
- uint8_t bios_disable:1;
- uint8_t selectable_scsi_boot_enable:1;
- uint8_t cd_rom_boot_enable:1;
- uint8_t disable_loading_risc_code:1;
- uint8_t unused_6:1;
- uint8_t unused_7:1;
- } cntr_flags_1; /* 5 */
- uint8_t version; /* 4 */
-
- /* Selectable Boot Support */
- struct {
uint16_t boot_lun_number:5;
uint16_t scsi_bus_number:1;
uint16_t unused_6:1;
@@ -736,167 +359,6 @@ typedef struct {
uint16_t unused_12; /* 12, 13 */
uint16_t unused_14; /* 14, 15 */
- /* Termination
- * 0 = Disable, 1 = high only, 3 = Auto term
- */
- union {
- uint8_t c;
- struct {
- uint8_t scsi_bus_1_control:2;
- uint8_t scsi_bus_0_control:2;
- uint8_t unused_0:1;
- uint8_t unused_1:1;
- uint8_t unused_2:1;
- uint8_t auto_term_support:1;
- } f;
- } termination; /* 17 */
- /* Auto Term - 3 */
- /* High Only - 1 (GPIO2 = 1 & GPIO3 = 0) */
- /* Disable - 0 (GPIO2 = 0 & GPIO3 = X) */
- /* ISP Config Parameters */
- union {
- uint8_t c;
- struct {
- uint8_t reserved:2;
- uint8_t burst_enable:1;
- uint8_t reserved_1:1;
- uint8_t fifo_threshold:4;
- } f;
- } isp_config; /* 16 */
-
- uint16_t isp_parameter; /* 18, 19 */
-
- union {
- uint16_t w;
- struct {
- uint16_t enable_fast_posting:1;
- uint16_t report_lvd_bus_transition:1;
- uint16_t unused_2:1;
- uint16_t unused_3:1;
- uint16_t unused_4:1;
- uint16_t unused_5:1;
- uint16_t unused_6:1;
- uint16_t unused_7:1;
- uint16_t unused_8:1;
- uint16_t unused_9:1;
- uint16_t unused_10:1;
- uint16_t unused_11:1;
- uint16_t unused_12:1;
- uint16_t unused_13:1;
- uint16_t unused_14:1;
- uint16_t unused_15:1;
- } f;
- } firmware_feature; /* 20, 21 */
-
- uint16_t unused_22; /* 22, 23 */
-
- struct {
- uint8_t bus_reset_delay; /* 25 */
- struct {
- uint8_t initiator_id:4;
- uint8_t scsi_reset_disable:1;
- uint8_t scsi_bus_size:1;
- uint8_t scsi_bus_type:1;
- uint8_t unused_7:1;
- } config_1; /* 24 */
-
- uint8_t retry_delay; /* 27 */
- uint8_t retry_count; /* 26 */
-
- uint8_t unused_29; /* 29 */
- /* Adapter Capabilities bits */
- struct {
- uint8_t async_data_setup_time:4;
- uint8_t req_ack_active_negation:1;
- uint8_t data_line_active_negation:1;
- uint8_t unused_6:1;
- uint8_t unused_7:1;
- } config_2; /* 28 */
-
- uint16_t selection_timeout; /* 30, 31 */
- uint16_t max_queue_depth; /* 32, 33 */
-
- uint16_t unused_34; /* 34, 35 */
- uint16_t unused_36; /* 36, 37 */
- uint16_t unused_38; /* 38, 39 */
-
- struct {
- uint8_t execution_throttle; /* 41 */
- union {
- uint8_t c;
- struct {
- uint8_t renegotiate_on_error:1;
- uint8_t stop_queue_on_check:1;
- uint8_t auto_request_sense:1;
- uint8_t tag_queuing:1;
- uint8_t sync_data_transfers:1;
- uint8_t wide_data_transfers:1;
- uint8_t parity_checking:1;
- uint8_t disconnect_allowed:1;
- } f;
- } parameter; /* 40 */
-
- struct {
- uint8_t sync_offset:5;
- uint8_t device_enable:1;
- uint8_t unused_6:1;
- uint8_t unused_7:1;
- } flags1; /* 43 */
- uint8_t sync_period; /* 42 */
-
- uint8_t unused_45; /* 45 */
- struct {
- uint8_t ppr_options:4;
- uint8_t ppr_bus_width:2;
- uint8_t unused_8:1;
- uint8_t enable_ppr:1;
- } flags2; /* 44 */
-
- } target[MAX_TARGETS];
- } bus[MAX_BUSES];
-
- uint16_t unused_248; /* 248, 249 */
-
- uint16_t subsystem_id[2]; /* 250, 251, 252, 253 */
-
- uint8_t chksum; /* 255 */
- uint8_t System_Id_Pointer; /* 254 */
-
-#elif defined(__LITTLE_ENDIAN)
- uint8_t id0; /* 0 */
- uint8_t id1; /* 1 */
- uint8_t id2; /* 2 */
- uint8_t id3; /* 3 */
- uint8_t version; /* 4 */
- /* Host/Bios Flags */
- struct {
- uint8_t bios_configuration_mode:2;
- uint8_t bios_disable:1;
- uint8_t selectable_scsi_boot_enable:1;
- uint8_t cd_rom_boot_enable:1;
- uint8_t disable_loading_risc_code:1;
- uint8_t unused_6:1;
- uint8_t unused_7:1;
- } cntr_flags_1; /* 5 */
- /* Selectable Boot Support */
- struct {
- uint16_t boot_lun_number:5;
- uint16_t scsi_bus_number:1;
- uint16_t unused_6:1;
- uint16_t unused_7:1;
- uint16_t boot_target_number:4;
- uint16_t unused_12:1;
- uint16_t unused_13:1;
- uint16_t unused_14:1;
- uint16_t unused_15:1;
- } cntr_flags_2; /* 6, 7 */
-
- uint16_t unused_8; /* 8, 9 */
- uint16_t unused_10; /* 10, 11 */
- uint16_t unused_12; /* 12, 13 */
- uint16_t unused_14; /* 14, 15 */
-
- /* ISP Config Parameters */
union {
uint8_t c;
struct {
@@ -921,9 +383,6 @@ typedef struct {
uint8_t auto_term_support:1;
} f;
} termination; /* 17 */
- /* Auto Term - 3 */
- /* High Only - 1 (GPIO2 = 1 & GPIO3 = 0) */
- /* Disable - 0 (GPIO2 = 0 & GPIO3 = X) */
uint16_t isp_parameter; /* 18, 19 */
@@ -934,11 +393,11 @@ typedef struct {
uint16_t report_lvd_bus_transition:1;
uint16_t unused_2:1;
uint16_t unused_3:1;
- uint16_t unused_4:1;
- uint16_t unused_5:1;
+ uint16_t disable_iosbs_with_bus_reset_status:1;
+ uint16_t disable_synchronous_backoff:1;
uint16_t unused_6:1;
- uint16_t unused_7:1;
- uint16_t unused_8:1;
+ uint16_t synchronous_backoff_reporting:1;
+ uint16_t disable_reselection_fairness:1;
uint16_t unused_9:1;
uint16_t unused_10:1;
uint16_t unused_11:1;
@@ -963,7 +422,7 @@ typedef struct {
uint8_t bus_reset_delay; /* 25 */
uint8_t retry_count; /* 26 */
uint8_t retry_delay; /* 27 */
- /* Adapter Capabilities bits */
+
struct {
uint8_t async_data_setup_time:4;
uint8_t req_ack_active_negation:1;
@@ -989,8 +448,8 @@ typedef struct {
uint8_t stop_queue_on_check:1;
uint8_t auto_request_sense:1;
uint8_t tag_queuing:1;
- uint8_t sync_data_transfers:1;
- uint8_t wide_data_transfers:1;
+ uint8_t enable_sync:1;
+ uint8_t enable_wide:1;
uint8_t parity_checking:1;
uint8_t disconnect_allowed:1;
} f;
@@ -999,20 +458,31 @@ typedef struct {
uint8_t execution_throttle; /* 41 */
uint8_t sync_period; /* 42 */
- struct {
- uint8_t sync_offset:5;
- uint8_t device_enable:1;
- uint8_t unused_6:1;
- uint8_t unused_7:1;
- } flags1; /* 43 */
-
- struct {
- uint8_t ppr_options:4;
- uint8_t ppr_bus_width:2;
- uint8_t unused_8:1;
- uint8_t enable_ppr:1;
- } flags2; /* 43 */
-
+ union { /* 43 */
+ uint8_t flags_43;
+ struct {
+ uint8_t sync_offset:4;
+ uint8_t device_enable:1;
+ uint8_t lun_disable:1;
+ uint8_t unused_6:1;
+ uint8_t unused_7:1;
+ } flags1x80;
+ struct {
+ uint8_t sync_offset:5;
+ uint8_t device_enable:1;
+ uint8_t unused_6:1;
+ uint8_t unused_7:1;
+ } flags1x160;
+ } flags;
+ union { /* PPR flags for the 1x160 controllers */
+ uint8_t unused_44;
+ struct {
+ uint8_t ppr_options:4;
+ uint8_t ppr_bus_width:2;
+ uint8_t unused_8:1;
+ uint8_t enable_ppr:1;
+ } flags; /* 44 */
+ } ppr_1x160;
uint8_t unused_45; /* 45 */
} target[MAX_TARGETS];
} bus[MAX_BUSES];
@@ -1021,19 +491,19 @@ typedef struct {
uint16_t subsystem_id[2]; /* 250, 251, 252, 253 */
- uint8_t System_Id_Pointer; /* 254 */
+ union { /* 254 */
+ uint8_t unused_254;
+ uint8_t system_id_pointer;
+ } sysid_1x160;
uint8_t chksum; /* 255 */
-#else
-#error neither __BIG_ENDIAN nor __LITTLE_ENDIAN is defined
-#endif
-} nvram160_t;
+};
/*
* ISP queue - command entry structure definition.
*/
#define MAX_CMDSZ 12 /* SCSI maximum CDB size. */
-typedef struct {
+struct cmd_entry {
uint8_t entry_type; /* Entry type. */
#define COMMAND_TYPE 1 /* Command entry */
uint8_t entry_count; /* Entry count. */
@@ -1056,12 +526,12 @@ typedef struct {
uint32_t dseg_2_length; /* Data segment 2 length. */
uint32_t dseg_3_address; /* Data segment 3 address. */
uint32_t dseg_3_length; /* Data segment 3 length. */
-} cmd_entry_t;
+};
/*
* ISP queue - continuation entry structure definition.
*/
-typedef struct {
+struct cont_entry {
uint8_t entry_type; /* Entry type. */
#define CONTINUE_TYPE 2 /* Continuation entry. */
uint8_t entry_count; /* Entry count. */
@@ -1082,12 +552,12 @@ typedef struct {
uint32_t dseg_5_length; /* Data segment 5 length. */
uint32_t dseg_6_address; /* Data segment 6 address. */
uint32_t dseg_6_length; /* Data segment 6 length. */
-} cont_entry_t;
+};
/*
* ISP queue - status entry structure definition.
*/
-typedef struct {
+struct response {
uint8_t entry_type; /* Entry type. */
#define STATUS_TYPE 3 /* Status entry. */
uint8_t entry_count; /* Entry count. */
@@ -1114,12 +584,12 @@ typedef struct {
uint32_t residual_length; /* Residual transfer length. */
uint16_t reserved[4];
uint8_t req_sense_data[32]; /* Request sense data. */
-} sts_entry_t, response_t;
+};
/*
* ISP queue - marker entry structure definition.
*/
-typedef struct {
+struct mrk_entry {
uint8_t entry_type; /* Entry type. */
#define MARKER_TYPE 4 /* Marker entry. */
uint8_t entry_count; /* Entry count. */
@@ -1133,12 +603,14 @@ typedef struct {
#define MK_SYNC_ID 1 /* Synchronize ID */
#define MK_SYNC_ALL 2 /* Synchronize all ID/LUN */
uint8_t reserved_1[53];
-} mrk_entry_t;
+};
/*
* ISP queue - extended command entry structure definition.
+ *
+ * Unused by the driver!
*/
-typedef struct {
+struct ecmd_entry {
uint8_t entry_type; /* Entry type. */
#define EXTENDED_CMD_TYPE 5 /* Extended command entry. */
uint8_t entry_count; /* Entry count. */
@@ -1153,7 +625,7 @@ typedef struct {
uint16_t timeout; /* Command timeout. */
uint16_t dseg_count; /* Data segment count. */
uint8_t scsi_cdb[88]; /* SCSI command words. */
-} ecmd_entry_t;
+};
/*
* ISP queue - 64-Bit addressing, command entry structure definition.
@@ -1183,7 +655,7 @@ typedef struct {
/*
* ISP queue - 64-Bit addressing, continuation entry structure definition.
*/
-typedef struct {
+struct cont_a64_entry {
uint8_t entry_type; /* Entry type. */
#define CONTINUE_A64_TYPE 0xA /* Continuation A64 entry. */
uint8_t entry_count; /* Entry count. */
@@ -1199,12 +671,12 @@ typedef struct {
uint32_t dseg_3_length; /* Data segment 3 length. */
uint32_t dseg_4_address[2]; /* Data segment 4 address. */
uint32_t dseg_4_length; /* Data segment 4 length. */
-} cont_a64_entry_t;
+};
/*
* ISP queue - enable LUN entry structure definition.
*/
-typedef struct {
+struct elun_entry {
uint8_t entry_type; /* Entry type. */
#define ENABLE_LUN_TYPE 0xB /* Enable LUN entry. */
uint8_t entry_count; /* Entry count. */
@@ -1225,12 +697,14 @@ typedef struct {
/* commands (2-26). */
uint16_t timeout; /* 0 = 30 seconds, 0xFFFF = disable */
uint16_t reserved_6[20];
-} elun_entry_t;
+};
/*
* ISP queue - modify LUN entry structure definition.
+ *
+ * Unused by the driver!
*/
-typedef struct {
+struct modify_lun_entry {
uint8_t entry_type; /* Entry type. */
#define MODIFY_LUN_TYPE 0xC /* Modify LUN entry. */
uint8_t entry_count; /* Entry count. */
@@ -1250,12 +724,12 @@ typedef struct {
uint16_t reserved_6;
uint16_t timeout; /* 0 = 30 seconds, 0xFFFF = disable */
uint16_t reserved_7[20];
-} modify_lun_entry_t;
+};
/*
* ISP queue - immediate notify entry structure definition.
*/
-typedef struct {
+struct notify_entry {
uint8_t entry_type; /* Entry type. */
#define IMMED_NOTIFY_TYPE 0xD /* Immediate notify entry. */
uint8_t entry_count; /* Entry count. */
@@ -1276,12 +750,12 @@ typedef struct {
uint8_t scsi_msg[8]; /* SCSI message not handled by ISP */
uint16_t reserved_5[8];
uint8_t sense_data[18];
-} notify_entry_t;
+};
/*
* ISP queue - notify acknowledge entry structure definition.
*/
-typedef struct {
+struct nack_entry {
uint8_t entry_type; /* Entry type. */
#define NOTIFY_ACK_TYPE 0xE /* Notify acknowledge entry. */
uint8_t entry_count; /* Entry count. */
@@ -1297,12 +771,12 @@ typedef struct {
uint8_t event;
uint16_t seq_id;
uint16_t reserved_4[22];
-} nack_entry_t;
+};
/*
* ISP queue - Accept Target I/O (ATIO) entry structure definition.
*/
-typedef struct {
+struct atio_entry {
uint8_t entry_type; /* Entry type. */
#define ACCEPT_TGT_IO_TYPE 6 /* Accept target I/O entry. */
uint8_t entry_count; /* Entry count. */
@@ -1320,12 +794,12 @@ typedef struct {
uint8_t tag_type; /* Received queue tag message type */
uint8_t cdb[26];
uint8_t sense_data[18];
-} atio_entry_t;
+};
/*
* ISP queue - Continue Target I/O (CTIO) entry structure definition.
*/
-typedef struct {
+struct ctio_entry {
uint8_t entry_type; /* Entry type. */
#define CONTINUE_TGT_IO_TYPE 7 /* CTIO entry */
uint8_t entry_count; /* Entry count. */
@@ -1353,12 +827,12 @@ typedef struct {
uint32_t dseg_2_length; /* Data segment 2 length. */
uint32_t dseg_3_address; /* Data segment 3 address. */
uint32_t dseg_3_length; /* Data segment 3 length. */
-} ctio_entry_t;
+};
/*
* ISP queue - CTIO returned entry structure definition.
*/
-typedef struct {
+struct ctio_ret_entry {
uint8_t entry_type; /* Entry type. */
#define CTIO_RET_TYPE 7 /* CTIO return entry */
uint8_t entry_count; /* Entry count. */
@@ -1383,12 +857,12 @@ typedef struct {
uint32_t dseg_1_address; /* Data segment 1 address. */
uint16_t dseg_1_length; /* Data segment 1 length. */
uint8_t sense_data[18];
-} ctio_ret_entry_t;
+};
/*
* ISP queue - CTIO A64 entry structure definition.
*/
-typedef struct {
+struct ctio_a64_entry {
uint8_t entry_type; /* Entry type. */
#define CTIO_A64_TYPE 0xF /* CTIO A64 entry */
uint8_t entry_count; /* Entry count. */
@@ -1413,12 +887,12 @@ typedef struct {
uint32_t dseg_0_length; /* Data segment 0 length. */
uint32_t dseg_1_address[2]; /* Data segment 1 address. */
uint32_t dseg_1_length; /* Data segment 1 length. */
-} ctio_a64_entry_t;
+};
/*
* ISP queue - CTIO returned entry structure definition.
*/
-typedef struct {
+struct ctio_a64_ret_entry {
uint8_t entry_type; /* Entry type. */
#define CTIO_A64_RET_TYPE 0xF /* CTIO A64 returned entry */
uint8_t entry_count; /* Entry count. */
@@ -1440,12 +914,12 @@ typedef struct {
uint16_t dseg_count; /* Data segment count. */
uint16_t reserved_4[7];
uint8_t sense_data[18];
-} ctio_a64_ret_entry_t;
+};
/*
* ISP request and response queue entry sizes
*/
-#define RESPONSE_ENTRY_SIZE (sizeof(response_t))
+#define RESPONSE_ENTRY_SIZE (sizeof(struct response))
#define REQUEST_ENTRY_SIZE (sizeof(request_t))
/*
@@ -1508,27 +982,11 @@ typedef struct {
#define OF_FORCE_DISC BIT_30 /* Disconnects mandatory */
#define OF_SSTS BIT_31 /* Send SCSI status */
-#if QL1280_TARGET_MODE_SUPPORT
-/*
- * Target Read/Write buffer structure.
- */
-#define TARGET_DATA_OFFSET 4
-#define TARGET_DATA_SIZE 0x2000 /* 8K */
-#define TARGET_INQ_OFFSET (TARGET_DATA_OFFSET + TARGET_DATA_SIZE)
-#define TARGET_SENSE_SIZE 18
-#define TARGET_BUF_SIZE 36
-
-typedef struct {
- uint8_t hdr[4];
- uint8_t data[TARGET_DATA_SIZE];
- struct ident inq;
-} tgt_t;
-#endif
/*
- * BUS parameters/settings structure
+ * BUS parameters/settings structure - UNUSED
*/
-typedef struct {
+struct bus_param {
uint8_t id; /* Host adapter SCSI id */
uint8_t bus_reset_delay; /* SCSI bus reset delay. */
uint8_t failed_reset_count; /* number of time reset failed */
@@ -1540,8 +998,19 @@ typedef struct {
uint8_t reset_marker:1;
uint8_t disable_scsi_reset:1;
uint8_t scsi_bus_dead:1; /* SCSI Bus is Dead, when 5 back to back resets failed */
+};
+
+
+struct qla_driver_setup {
+ uint32_t no_sync:1;
+ uint32_t no_wide:1;
+ uint32_t no_ppr:1;
+ uint32_t no_nvram:1;
+ uint16_t sync_mask;
+ uint16_t wide_mask;
+ uint16_t ppr_mask;
+};
-} bus_param_t;
/*
* Linux Host Adapter structure
@@ -1551,35 +1020,32 @@ struct scsi_qla_host {
struct Scsi_Host *host; /* pointer to host data */
struct scsi_qla_host *next;
struct device_reg *iobase; /* Base Memory-mapped I/O address */
- uint8_t pci_bus;
- uint8_t pci_device_fn;
- uint8_t devnum;
- struct pci_dev *pdev;
- volatile unsigned char *mmpbase; /* memory mapped address */
+ unsigned char *mmpbase; /* memory mapped address */
unsigned long host_no;
unsigned long instance;
+ struct pci_dev *pdev;
+ uint32_t device_id;
+ uint8_t pci_bus;
+ uint8_t pci_device_fn;
+ uint8_t devnum;
uint8_t revision;
uint8_t ports;
unsigned long actthreads;
- unsigned long qthreads;
unsigned long isr_count; /* Interrupt count */
unsigned long spurious_int;
- uint32_t device_id;
-
/* Outstandings ISP commands. */
- srb_t *outstanding_cmds[MAX_OUTSTANDING_COMMANDS];
+ struct srb *outstanding_cmds[MAX_OUTSTANDING_COMMANDS];
/* BUS configuration data */
- bus_param_t bus_settings[MAX_BUSES];
-
- /* Device LUN queues. */
- struct scsi_lu *dev[MAX_EQ]; /* Logical unit queues */
+ struct bus_param bus_settings[MAX_BUSES];
+#if 0
/* bottom half run queue */
- struct work_struct run_qla_bh;
+ struct tq_struct run_qla_bh;
+#endif
/* Received ISP mailbox data. */
volatile uint16_t mailbox_out[MAILBOX_REGISTER_COUNT];
@@ -1595,49 +1061,43 @@ struct scsi_qla_host {
uint16_t req_q_cnt; /* Number of available entries. */
dma_addr_t response_dma; /* Physical address. */
- response_t *response_ring; /* Base virtual address */
- response_t *response_ring_ptr; /* Current address. */
+ struct response *response_ring; /* Base virtual address */
+ struct response *response_ring_ptr; /* Current address. */
uint16_t rsp_ring_index; /* Current index. */
-#if QL1280_TARGET_MODE_SUPPORT
- /* Target buffer and sense data. */
- dma_addr_t tbuf_dma; /* Physical address. */
- dma_addr_t tsense_dma; /* Physical address. */
- tgt_t *tbuf;
- uint8_t *tsense;
-#endif
-
#if WATCHDOGTIMER
/* Watchdog queue, lock and total timer */
uint8_t watchdog_q_lock; /* Lock for watchdog queue */
- srb_t *wdg_q_first; /* First job on watchdog queue */
- srb_t *wdg_q_last; /* Last job on watchdog queue */
+ struct srb *wdg_q_first; /* First job on watchdog queue */
+ struct srb *wdg_q_last; /* Last job on watchdog queue */
uint32_t total_timeout; /* Total timeout (quantum count) */
uint32_t watchdogactive;
#endif
- srb_t *done_q_first; /* First job on done queue */
- srb_t *done_q_last; /* Last job on done queue */
+ struct srb *done_q_first; /* First job on done queue */
+ struct srb *done_q_last; /* Last job on done queue */
+
+ struct completion *mailbox_wait;
volatile struct {
- uint32_t mbox_int:1; /* 0 */
- uint32_t mbox_busy:1; /* 1 */
- uint32_t online:1; /* 2 */
- uint32_t reset_marker:1; /* 3 */
- uint32_t isp_abort_needed:1; /* 4 */
- uint32_t disable_host_adapter:1; /* 5 */
- uint32_t reset_active:1; /* 6 */
- uint32_t abort_isp_active:1; /* 7 */
- uint32_t disable_risc_code_load:1; /* 8 */
- uint32_t enable_64bit_addressing:1; /* 9 */
- uint32_t in_reset:1; /* 10 */
+ uint32_t mbox_busy:1; /* 0 */
+ uint32_t online:1; /* 1 */
+ uint32_t reset_marker:1; /* 2 */
+ uint32_t disable_host_adapter:1; /* 4 */
+ uint32_t reset_active:1; /* 5 */
+ uint32_t abort_isp_active:1; /* 6 */
+ uint32_t disable_risc_code_load:1; /* 7 */
+ uint32_t enable_64bit_addressing:1; /* 8 */
+ uint32_t in_reset:1; /* 9 */
uint32_t ints_enabled:1;
+ uint32_t ignore_nvram:1;
+#ifdef __ia64__
+ uint32_t use_pci_vchannel:1;
+#endif
} flags;
- /* needed holders for PCI ordered list of hosts */
- unsigned long io_port;
- uint32_t irq;
-
+ struct nvram nvram;
+ int nvram_valid;
};
/*
@@ -1651,16 +1111,60 @@ struct scsi_qla_host {
/*
* Linux - SCSI Driver Interface Function Prototypes.
*/
+int qla1280_proc_info(char *, char **, off_t, int, int, int);
const char *qla1280_info(struct Scsi_Host *host);
int qla1280_detect(Scsi_Host_Template *);
int qla1280_release(struct Scsi_Host *);
int qla1280_queuecommand(Scsi_Cmnd *, void (*done) (Scsi_Cmnd *));
-int qla1280_abort(Scsi_Cmnd *);
-int qla1280_reset(Scsi_Cmnd *, unsigned int);
+#if LINUX_VERSION_CODE < 0x020545
+int qla1280_biosparam(Disk *, kdev_t, int[]);
+#else
int qla1280_biosparam(struct scsi_device *, struct block_device *,
- sector_t, int[]);
-static int qla1280_slave_configure(Scsi_Device *);
-irqreturn_t qla1280_intr_handler(int, void *, struct pt_regs *);
-void qla1280_setup(char *s, int *dummy);
+ sector_t, int *);
+#endif
+int __init qla1280_setup(char *s);
+int qla1280_eh_abort(struct scsi_cmnd * cmd);
+int qla1280_eh_device_reset(struct scsi_cmnd *cmd);
+int qla1280_eh_bus_reset(struct scsi_cmnd *cmd);
+int qla1280_eh_adapter_reset(struct scsi_cmnd *cmd);
+
+#if LINUX_VERSION_CODE < 0x020545
+#define USE_NEW_EH .use_new_eh_code= 1
+#else
+#define USE_NEW_EH
+#endif
+
+/*
+ * Scsi_Host_template (see hosts.h)
+ * Device driver Interfaces to mid-level SCSI driver.
+ */
+
+#define QLA1280_LINUX_TEMPLATE { \
+ .module = NULL, \
+ .proc_dir = NULL, \
+ .proc_info = qla1280_proc_info, \
+ .name = "Qlogic ISP 1280/12160", \
+ .detect = qla1280_detect, \
+ .release = qla1280_release, \
+ .info = qla1280_info, \
+ .ioctl = NULL, \
+ .command = NULL, \
+ .queuecommand = qla1280_queuecommand, \
+ .eh_strategy_handler = NULL, \
+ .eh_abort_handler = qla1280_eh_abort, \
+ .eh_device_reset_handler = qla1280_eh_device_reset, \
+ .eh_bus_reset_handler = qla1280_eh_bus_reset, \
+ .eh_host_reset_handler = qla1280_eh_adapter_reset, \
+ .bios_param = qla1280_biosparam, \
+ .can_queue = 255, /* max simultaneous cmds */\
+ .this_id = -1, /* scsi id of host adapter */\
+ .sg_tablesize = SG_ALL, /* max scatter-gather cmds */\
+ .cmd_per_lun = 3, /* cmds per lun (linked cmds) */\
+ .present = 0, /* number of 1280's present */\
+ .unchecked_isa_dma = 0, /* no memory DMA restrictions */\
+ .use_clustering = ENABLE_CLUSTERING, \
+ .emulated = 0, \
+ USE_NEW_EH \
+}
#endif /* _IO_HBA_QLA1280_H */
diff --git a/drivers/scsi/qlogicfc.c b/drivers/scsi/qlogicfc.c
index 7765d8a4afd9..066a316cd2b0 100644
--- a/drivers/scsi/qlogicfc.c
+++ b/drivers/scsi/qlogicfc.c
@@ -2235,6 +2235,5 @@ static Scsi_Host_Template driver_template = {
.sg_tablesize = QLOGICFC_MAX_SG(QLOGICFC_REQ_QUEUE_LEN),
.cmd_per_lun = QLOGICFC_CMD_PER_LUN,
.use_clustering = ENABLE_CLUSTERING,
- .highmem_io = 1,
};
#include "scsi_module.c"
diff --git a/drivers/scsi/qlogicpti.c b/drivers/scsi/qlogicpti.c
index 3116a90b7b27..005d20be5df1 100644
--- a/drivers/scsi/qlogicpti.c
+++ b/drivers/scsi/qlogicpti.c
@@ -1550,10 +1550,6 @@ static Scsi_Host_Template driver_template = {
.sg_tablesize = QLOGICPTI_MAX_SG(QLOGICPTI_REQ_QUEUE_LEN),
.cmd_per_lun = 1,
.use_clustering = ENABLE_CLUSTERING,
-/* Sparc32's iommu code cannot handle highmem pages yet. */
-#ifdef CONFIG_SPARC64
- .highmem_io = 1,
-#endif
};
diff --git a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c
index 633c9a028e29..6e17a28d4afe 100644
--- a/drivers/scsi/scsi.c
+++ b/drivers/scsi/scsi.c
@@ -370,7 +370,7 @@ int scsi_dispatch_cmd(struct scsi_cmnd *cmd)
struct Scsi_Host *host = cmd->device->host;
unsigned long flags = 0;
unsigned long timeout;
- int rtn = 1;
+ int rtn = 0;
/* Assign a unique nonzero serial_number. */
/* XXX(hch): this is racy */
@@ -444,7 +444,12 @@ int scsi_dispatch_cmd(struct scsi_cmnd *cmd)
host->hostt->queuecommand));
spin_lock_irqsave(host->host_lock, flags);
- rtn = host->hostt->queuecommand(cmd, scsi_done);
+ if (unlikely(test_bit(SHOST_CANCEL, &host->shost_state))) {
+ cmd->result = (DID_NO_CONNECT << 16);
+ scsi_done(cmd);
+ } else {
+ rtn = host->hostt->queuecommand(cmd, scsi_done);
+ }
spin_unlock_irqrestore(host->host_lock, flags);
if (rtn) {
scsi_queue_insert(cmd,
@@ -888,33 +893,65 @@ int scsi_track_queue_full(struct scsi_device *sdev, int depth)
int scsi_device_get(struct scsi_device *sdev)
{
- if (!try_module_get(sdev->host->hostt->module))
- return -ENXIO;
+ struct class *class = class_get(&sdev_class);
+ int error = -ENXIO;
+
+ if (class) {
+ down_write(&class->subsys.rwsem);
+ if (!test_bit(SDEV_DEL, &sdev->sdev_state))
+ if (try_module_get(sdev->host->hostt->module))
+ if (get_device(&sdev->sdev_gendev)) {
+ sdev->access_count++;
+ error = 0;
+ }
+ up_write(&class->subsys.rwsem);
+ class_put(&sdev_class);
+ }
- sdev->access_count++;
- return 0;
+ return error;
}
void scsi_device_put(struct scsi_device *sdev)
{
- sdev->access_count--;
+ struct class *class = class_get(&sdev_class);
+
+ if (!class)
+ return;
+
+ down_write(&class->subsys.rwsem);
module_put(sdev->host->hostt->module);
+ if (--sdev->access_count == 0) {
+ if (test_bit(SDEV_DEL, &sdev->sdev_state))
+ device_del(&sdev->sdev_gendev);
+ }
+ put_device(&sdev->sdev_gendev);
+ up_write(&class->subsys.rwsem);
+
+ class_put(&sdev_class);
+}
+
+int scsi_device_cancel_cb(struct device *dev, void *data)
+{
+ struct scsi_device *sdev = to_scsi_device(dev);
+ int recovery = *(int *)data;
+
+ return scsi_device_cancel(sdev, recovery);
}
/**
- * scsi_set_device_offline - set scsi_device offline
- * @sdev: pointer to struct scsi_device to offline.
+ * scsi_device_cancel - cancel outstanding IO to this device
+ * @sdev: pointer to struct scsi_device
+ * @data: pointer to cancel value.
*
- * Locks: host_lock held on entry.
**/
-void scsi_set_device_offline(struct scsi_device *sdev)
+int scsi_device_cancel(struct scsi_device *sdev, int recovery)
{
struct scsi_cmnd *scmd;
LIST_HEAD(active_list);
struct list_head *lh, *lh_sf;
unsigned long flags;
- sdev->online = 0;
+ set_bit(SDEV_CANCEL, &sdev->sdev_state);
spin_lock_irqsave(&sdev->list_lock, flags);
list_for_each_entry(scmd, &sdev->cmd_list, list) {
@@ -934,11 +971,17 @@ void scsi_set_device_offline(struct scsi_device *sdev)
if (!list_empty(&active_list)) {
list_for_each_safe(lh, lh_sf, &active_list) {
scmd = list_entry(lh, struct scsi_cmnd, eh_entry);
- scsi_eh_scmd_add(scmd, SCSI_EH_CANCEL_CMD);
+ list_del_init(lh);
+ if (recovery) {
+ scsi_eh_scmd_add(scmd, SCSI_EH_CANCEL_CMD);
+ } else {
+ scmd->result = (DID_ABORT << 16);
+ scsi_finish_command(scmd);
+ }
}
- } else {
- /* FIXME: Send online state change hotplug event */
}
+
+ return 0;
}
MODULE_DESCRIPTION("SCSI core");
diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c
index 47125ef5d93e..dcf36f1c04fd 100644
--- a/drivers/scsi/scsi_debug.c
+++ b/drivers/scsi/scsi_debug.c
@@ -1722,10 +1722,7 @@ static int sdebug_driver_remove(struct device * dev)
return -ENODEV;
}
- if (scsi_remove_host(sdbg_host->shost)) {
- printk(KERN_ERR "%s: scsi_remove_host failed\n", __FUNCTION__);
- return -EBUSY;
- }
+ scsi_remove_host(sdbg_host->shost);
list_for_each_safe(lh, lh_sf, &sdbg_host->dev_info_list) {
sdbg_devinfo = list_entry(lh, struct sdebug_dev_info,
diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c
index 6fc48eb0f834..f5d18f74beaf 100644
--- a/drivers/scsi/scsi_error.c
+++ b/drivers/scsi/scsi_error.c
@@ -84,7 +84,7 @@ int scsi_eh_scmd_add(struct scsi_cmnd *scmd, int eh_flag)
*/
scmd->serial_number_at_timeout = scmd->serial_number;
list_add_tail(&scmd->eh_entry, &shost->eh_cmd_q);
- shost->in_recovery = 1;
+ set_bit(SHOST_RECOVERY, &shost->shost_state);
shost->host_failed++;
scsi_eh_wakeup(shost);
spin_unlock_irqrestore(shost->host_lock, flags);
@@ -187,7 +187,7 @@ void scsi_times_out(struct scsi_cmnd *scmd)
**/
int scsi_block_when_processing_errors(struct scsi_device *sdev)
{
- wait_event(sdev->host->host_wait, (sdev->host->in_recovery == 0));
+ wait_event(sdev->host->host_wait, (!test_bit(SHOST_RECOVERY, &sdev->host->shost_state)));
SCSI_LOG_ERROR_RECOVERY(5, printk("%s: rtn: %d\n", __FUNCTION__,
sdev->online));
@@ -1389,7 +1389,7 @@ static void scsi_restart_operations(struct Scsi_Host *shost)
SCSI_LOG_ERROR_RECOVERY(3, printk("%s: waking up host to restart\n",
__FUNCTION__));
- shost->in_recovery = 0;
+ clear_bit(SHOST_RECOVERY, &shost->shost_state);
wake_up(&shost->host_wait);
@@ -1599,7 +1599,6 @@ void scsi_error_handler(void *data)
* that's fine. If the user sent a signal to this thing, we are
* potentially in real danger.
*/
- shost->in_recovery = 0;
shost->eh_active = 0;
shost->ehandler = NULL;
diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
index 7ad004d5e072..ef55ac3f119f 100644
--- a/drivers/scsi/scsi_lib.c
+++ b/drivers/scsi/scsi_lib.c
@@ -318,7 +318,8 @@ void scsi_device_unbusy(struct scsi_device *sdev)
spin_lock_irqsave(shost->host_lock, flags);
shost->host_busy--;
- if (unlikely(shost->in_recovery && shost->host_failed))
+ if (unlikely(test_bit(SHOST_RECOVERY, &shost->shost_state) &&
+ shost->host_failed))
scsi_eh_wakeup(shost);
spin_unlock(shost->host_lock);
spin_lock(&sdev->sdev_lock);
@@ -1066,7 +1067,7 @@ static inline int scsi_host_queue_ready(struct request_queue *q,
struct Scsi_Host *shost,
struct scsi_device *sdev)
{
- if (shost->in_recovery)
+ if (test_bit(SHOST_RECOVERY, &shost->shost_state))
return 0;
if (shost->host_busy == 0 && shost->host_blocked) {
/*
@@ -1207,21 +1208,20 @@ static void scsi_request_fn(struct request_queue *q)
u64 scsi_calculate_bounce_limit(struct Scsi_Host *shost)
{
- if (shost->highmem_io) {
- struct device *host_dev = scsi_get_device(shost);
+ struct device *host_dev;
- if (PCI_DMA_BUS_IS_PHYS && host_dev && host_dev->dma_mask)
- return *host_dev->dma_mask;
-
- /*
- * Platforms with virtual-DMA translation
- * hardware have no practical limit.
- */
- return BLK_BOUNCE_ANY;
- } else if (shost->unchecked_isa_dma)
+ if (shost->unchecked_isa_dma)
return BLK_BOUNCE_ISA;
- return BLK_BOUNCE_HIGH;
+ host_dev = scsi_get_device(shost);
+ if (PCI_DMA_BUS_IS_PHYS && host_dev && host_dev->dma_mask)
+ return *host_dev->dma_mask;
+
+ /*
+ * Platforms with virtual-DMA translation
+ * hardware have no practical limit.
+ */
+ return BLK_BOUNCE_ANY;
}
struct request_queue *scsi_alloc_queue(struct scsi_device *sdev)
@@ -1239,6 +1239,7 @@ struct request_queue *scsi_alloc_queue(struct scsi_device *sdev)
blk_queue_max_phys_segments(q, MAX_PHYS_SEGMENTS);
blk_queue_max_sectors(q, shost->max_sectors);
blk_queue_bounce_limit(q, scsi_calculate_bounce_limit(shost));
+ blk_queue_segment_boundary(q, shost->dma_boundary);
if (!shost->use_clustering)
clear_bit(QUEUE_FLAG_CLUSTER, &q->queue_flags);
diff --git a/drivers/scsi/scsi_module.c b/drivers/scsi/scsi_module.c
index 515a3e4b48fe..b8cc3ead92af 100644
--- a/drivers/scsi/scsi_module.c
+++ b/drivers/scsi/scsi_module.c
@@ -33,7 +33,7 @@ static int __init init_this_scsi_driver(void)
INIT_LIST_HEAD(&sht->legacy_hosts);
sht->detect(sht);
- if (!sht->present)
+ if (list_empty(&sht->legacy_hosts))
return -ENODEV;
list_for_each_entry(shost, &sht->legacy_hosts, sht_legacy_list) {
diff --git a/drivers/scsi/scsi_priv.h b/drivers/scsi/scsi_priv.h
index f17bdd42afe6..56566e3eef57 100644
--- a/drivers/scsi/scsi_priv.h
+++ b/drivers/scsi/scsi_priv.h
@@ -90,11 +90,15 @@ extern void scsi_exit_queue(void);
/* scsi_proc.c */
#ifdef CONFIG_PROC_FS
+extern void scsi_proc_hostdir_add(struct scsi_host_template *);
+extern void scsi_proc_hostdir_rm(struct scsi_host_template *);
extern void scsi_proc_host_add(struct Scsi_Host *);
extern void scsi_proc_host_rm(struct Scsi_Host *);
extern int scsi_init_procfs(void);
extern void scsi_exit_procfs(void);
#else
+# define scsi_proc_hostdir_add(sht) do { } while (0)
+# define scsi_proc_hostdir_rm(sht) do { } while (0)
# define scsi_proc_host_add(shost) do { } while (0)
# define scsi_proc_host_rm(shost) do { } while (0)
# define scsi_init_procfs() (0)
@@ -109,7 +113,6 @@ extern void scsi_rescan_device(struct device *);
/* scsi_sysfs.c */
extern int scsi_device_register(struct scsi_device *);
-extern void scsi_device_unregister(struct scsi_device *);
extern void scsi_sysfs_init_host(struct Scsi_Host *);
extern int scsi_sysfs_add_host(struct Scsi_Host *, struct device *);
extern void scsi_sysfs_remove_host(struct Scsi_Host *);
@@ -117,6 +120,7 @@ extern int scsi_sysfs_register(void);
extern void scsi_sysfs_unregister(void);
extern struct class shost_class;
+extern struct class sdev_class;
extern struct bus_type scsi_bus_type;
#endif /* _SCSI_PRIV_H */
diff --git a/drivers/scsi/scsi_proc.c b/drivers/scsi/scsi_proc.c
index 7f671349c28a..02a66f128ace 100644
--- a/drivers/scsi/scsi_proc.c
+++ b/drivers/scsi/scsi_proc.c
@@ -41,6 +41,8 @@
struct proc_dir_entry *proc_scsi;
EXPORT_SYMBOL(proc_scsi);
+/* Protect sht->present and sht->proc_dir */
+static DECLARE_MUTEX(global_host_template_sem);
static int proc_scsi_read(char *buffer, char **start, off_t offset,
int length, int *eof, void *data)
@@ -77,16 +79,10 @@ out:
return ret;
}
-void scsi_proc_host_add(struct Scsi_Host *shost)
+void scsi_proc_hostdir_add(struct scsi_host_template *sht)
{
- struct scsi_host_template *sht = shost->hostt;
- struct proc_dir_entry *p;
- char name[10];
-
- if (!sht->proc_info)
- return;
-
- if (!sht->proc_dir) {
+ down(&global_host_template_sem);
+ if (!sht->present++) {
sht->proc_dir = proc_mkdir(sht->proc_name, proc_scsi);
if (!sht->proc_dir) {
printk(KERN_ERR "%s: proc_mkdir failed for %s\n",
@@ -95,6 +91,27 @@ void scsi_proc_host_add(struct Scsi_Host *shost)
}
sht->proc_dir->owner = sht->module;
}
+ up(&global_host_template_sem);
+}
+
+void scsi_proc_hostdir_rm(struct scsi_host_template *sht)
+{
+ down(&global_host_template_sem);
+ if (!--sht->present && sht->proc_dir) {
+ remove_proc_entry(sht->proc_name, proc_scsi);
+ sht->proc_dir = NULL;
+ }
+ up(&global_host_template_sem);
+}
+
+void scsi_proc_host_add(struct Scsi_Host *shost)
+{
+ struct scsi_host_template *sht = shost->hostt;
+ struct proc_dir_entry *p;
+ char name[10];
+
+ if (!sht->proc_dir)
+ return;
sprintf(name,"%d", shost->host_no);
p = create_proc_read_entry(name, S_IFREG | S_IRUGO | S_IWUSR,
@@ -107,20 +124,18 @@ void scsi_proc_host_add(struct Scsi_Host *shost)
}
p->write_proc = proc_scsi_write_proc;
- p->owner = shost->hostt->module;
+ p->owner = sht->module;
}
void scsi_proc_host_rm(struct Scsi_Host *shost)
{
- struct scsi_host_template *sht = shost->hostt;
char name[10];
- if (sht->proc_info) {
- sprintf(name,"%d", shost->host_no);
- remove_proc_entry(name, sht->proc_dir);
- if (!sht->present)
- remove_proc_entry(sht->proc_name, proc_scsi);
- }
+ if (!shost->hostt->proc_dir)
+ return;
+
+ sprintf(name,"%d", shost->host_no);
+ remove_proc_entry(name, shost->hostt->proc_dir);
}
static int proc_print_scsidevice(struct device *dev, void *data)
@@ -175,11 +190,11 @@ static int scsi_add_single_device(uint host, uint channel, uint id, uint lun)
{
struct Scsi_Host *shost;
struct scsi_device *sdev;
- int error = -ENODEV;
+ int error = -ENXIO;
shost = scsi_host_lookup(host);
- if (!shost)
- return -ENODEV;
+ if (IS_ERR(shost))
+ return PTR_ERR(shost);
if (!scsi_find_device(shost, channel, id, lun)) {
sdev = scsi_add_device(shost, channel, id, lun);
@@ -197,18 +212,19 @@ static int scsi_remove_single_device(uint host, uint channel, uint id, uint lun)
{
struct scsi_device *sdev;
struct Scsi_Host *shost;
- int error = -ENODEV;
+ int error = -ENXIO;
shost = scsi_host_lookup(host);
- if (!shost)
- return -ENODEV;
+ if (IS_ERR(shost))
+ return PTR_ERR(shost);
sdev = scsi_find_device(shost, channel, id, lun);
if (!sdev)
goto out;
if (sdev->access_count)
goto out;
- error = scsi_remove_device(sdev);
+ scsi_remove_device(sdev);
+ error = 0;
out:
scsi_host_put(shost);
return error;
diff --git a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c
index 3b8309105021..55969f3de38f 100644
--- a/drivers/scsi/scsi_scan.c
+++ b/drivers/scsi/scsi_scan.c
@@ -288,8 +288,6 @@ void scsi_free_sdev(struct scsi_device *sdev)
if (sdev->request_queue)
scsi_free_queue(sdev->request_queue);
- if (sdev->host->hostt->slave_destroy)
- sdev->host->hostt->slave_destroy(sdev);
if (sdev->inquiry)
kfree(sdev->inquiry);
spin_lock_irqsave(sdev->host->host_lock, flags);
@@ -1074,12 +1072,6 @@ struct scsi_device *scsi_add_device(struct Scsi_Host *shost,
return sdev;
}
-int scsi_remove_device(struct scsi_device *sdev)
-{
- scsi_device_unregister(sdev);
- return 0;
-}
-
void scsi_rescan_device(struct device *dev)
{
struct scsi_driver *drv = to_scsi_driver(dev->driver);
diff --git a/drivers/scsi/scsi_syms.c b/drivers/scsi/scsi_syms.c
index 2ce7cb6c25bf..5c8dbdb5789c 100644
--- a/drivers/scsi/scsi_syms.c
+++ b/drivers/scsi/scsi_syms.c
@@ -86,7 +86,7 @@ EXPORT_SYMBOL(scsi_device_get);
EXPORT_SYMBOL(scsi_device_put);
EXPORT_SYMBOL(scsi_add_device);
EXPORT_SYMBOL(scsi_remove_device);
-EXPORT_SYMBOL(scsi_set_device_offline);
+EXPORT_SYMBOL(scsi_device_cancel);
EXPORT_SYMBOL(__scsi_mode_sense);
EXPORT_SYMBOL(scsi_mode_sense);
diff --git a/drivers/scsi/scsi_sysfs.c b/drivers/scsi/scsi_sysfs.c
index 3801b768c733..0097b4868923 100644
--- a/drivers/scsi/scsi_sysfs.c
+++ b/drivers/scsi/scsi_sysfs.c
@@ -54,12 +54,52 @@ static struct class_device_attribute *scsi_sysfs_shost_attrs[] = {
NULL
};
+static void scsi_host_cls_release(struct class_device *class_dev)
+{
+ struct Scsi_Host *shost;
+
+ shost = class_to_shost(class_dev);
+ put_device(&shost->shost_gendev);
+}
+
+static void scsi_host_dev_release(struct device *dev)
+{
+ struct Scsi_Host *shost;
+ struct device *parent;
+
+ parent = dev->parent;
+ shost = dev_to_shost(dev);
+ scsi_free_shost(shost);
+ put_device(parent);
+}
+
struct class shost_class = {
.name = "scsi_host",
+ .release = scsi_host_cls_release,
};
-static struct class sdev_class = {
+static void scsi_device_cls_release(struct class_device *class_dev)
+{
+ struct scsi_device *sdev;
+
+ sdev = class_to_sdev(class_dev);
+ put_device(&sdev->sdev_gendev);
+}
+
+static void scsi_device_dev_release(struct device *dev)
+{
+ struct scsi_device *sdev;
+ struct device *parent;
+
+ parent = dev->parent;
+ sdev = to_scsi_device(dev);
+ scsi_free_sdev(sdev);
+ put_device(parent);
+}
+
+struct class sdev_class = {
.name = "scsi_device",
+ .release = scsi_device_cls_release,
};
/* all probing is done in the individual ->probe routines */
@@ -109,7 +149,7 @@ void scsi_sysfs_unregister(void)
*/
#define sdev_show_function(field, format_string) \
static ssize_t \
-show_##field (struct device *dev, char *buf) \
+sdev_show_##field (struct device *dev, char *buf) \
{ \
struct scsi_device *sdev; \
sdev = to_scsi_device(dev); \
@@ -122,7 +162,7 @@ show_##field (struct device *dev, char *buf) \
*/
#define sdev_rd_attr(field, format_string) \
sdev_show_function(field, format_string) \
-static DEVICE_ATTR(field, S_IRUGO, show_##field, NULL)
+static DEVICE_ATTR(field, S_IRUGO, sdev_show_##field, NULL)
/*
@@ -140,7 +180,7 @@ sdev_store_##field (struct device *dev, const char *buf, size_t count) \
snscanf (buf, 20, format_string, &sdev->field); \
return count; \
} \
-static DEVICE_ATTR(field, S_IRUGO | S_IWUSR, show_##field, sdev_store_##field)
+static DEVICE_ATTR(field, S_IRUGO | S_IWUSR, sdev_show_##field, sdev_store_##field)
/*
* sdev_rd_attr: create a function and attribute variable for a
@@ -162,7 +202,7 @@ sdev_store_##field (struct device *dev, const char *buf, size_t count) \
} \
return ret; \
} \
-static DEVICE_ATTR(field, S_IRUGO | S_IWUSR, show_##field, sdev_store_##field)
+static DEVICE_ATTR(field, S_IRUGO | S_IWUSR, sdev_show_##field, sdev_store_##field)
/*
* scsi_sdev_check_buf_bit: return 0 if buf is "0", return 1 if buf is "1",
@@ -218,15 +258,6 @@ static struct device_attribute *scsi_sysfs_sdev_attrs[] = {
NULL
};
-static void scsi_device_release(struct device *dev)
-{
- struct scsi_device *sdev;
-
- sdev = to_scsi_device(dev);
- if (!sdev)
- return;
- scsi_free_sdev(sdev);
-}
static struct device_attribute *attr_overridden(
struct device_attribute **attrs,
@@ -275,12 +306,13 @@ int scsi_device_register(struct scsi_device *sdev)
{
int error = 0, i;
+ set_bit(SDEV_ADD, &sdev->sdev_state);
device_initialize(&sdev->sdev_gendev);
sprintf(sdev->sdev_gendev.bus_id,"%d:%d:%d:%d",
sdev->host->host_no, sdev->channel, sdev->id, sdev->lun);
sdev->sdev_gendev.parent = &sdev->host->shost_gendev;
sdev->sdev_gendev.bus = &scsi_bus_type;
- sdev->sdev_gendev.release = scsi_device_release;
+ sdev->sdev_gendev.release = scsi_device_dev_release;
class_device_initialize(&sdev->sdev_classdev);
sdev->sdev_classdev.dev = &sdev->sdev_gendev;
@@ -293,19 +325,24 @@ int scsi_device_register(struct scsi_device *sdev)
printk(KERN_INFO "error 1\n");
return error;
}
+
+ get_device(sdev->sdev_gendev.parent);
+
error = class_device_add(&sdev->sdev_classdev);
if (error) {
printk(KERN_INFO "error 2\n");
- device_unregister(&sdev->sdev_gendev);
+ goto clean_device;
return error;
}
+ get_device(&sdev->sdev_gendev);
+
if (sdev->host->hostt->sdev_attrs) {
for (i = 0; sdev->host->hostt->sdev_attrs[i]; i++) {
error = attr_add(&sdev->sdev_gendev,
sdev->host->hostt->sdev_attrs[i]);
if (error)
- scsi_device_unregister(sdev);
+ scsi_remove_device(sdev);
}
}
@@ -315,21 +352,40 @@ int scsi_device_register(struct scsi_device *sdev)
error = device_create_file(&sdev->sdev_gendev,
scsi_sysfs_sdev_attrs[i]);
if (error)
- scsi_device_unregister(sdev);
+ scsi_remove_device(sdev);
}
}
return error;
+
+clean_device:
+ device_del(&sdev->sdev_gendev);
+ put_device(&sdev->sdev_gendev);
+ return error;
+
}
/**
- * scsi_device_unregister - unregister a device from the scsi bus
+ * scsi_remove_device - unregister a device from the scsi bus
* @sdev: scsi_device to unregister
**/
-void scsi_device_unregister(struct scsi_device *sdev)
+void scsi_remove_device(struct scsi_device *sdev)
{
+ struct class *class = class_get(&sdev_class);
+
class_device_unregister(&sdev->sdev_classdev);
- device_unregister(&sdev->sdev_gendev);
+
+ if (class) {
+ down_write(&class->subsys.rwsem);
+ set_bit(SDEV_DEL, &sdev->sdev_state);
+ if (sdev->access_count == 0)
+ device_del(&sdev->sdev_gendev);
+ up_write(&class->subsys.rwsem);
+ }
+
+ put_device(&sdev->sdev_gendev);
+
+ class_put(&sdev_class);
}
int scsi_register_driver(struct device_driver *drv)
@@ -346,16 +402,6 @@ int scsi_register_interface(struct class_interface *intf)
return class_interface_register(intf);
}
-static void scsi_host_release(struct device *dev)
-{
- struct Scsi_Host *shost;
-
- shost = dev_to_shost(dev);
- if (!shost)
- return;
-
- scsi_free_shost(shost);
-}
void scsi_sysfs_init_host(struct Scsi_Host *shost)
{
@@ -364,7 +410,7 @@ void scsi_sysfs_init_host(struct Scsi_Host *shost)
shost->host_no);
snprintf(shost->shost_gendev.name, DEVICE_NAME_SIZE, "%s",
shost->hostt->proc_name);
- shost->shost_gendev.release = scsi_host_release;
+ shost->shost_gendev.release = scsi_host_dev_release;
class_device_initialize(&shost->shost_classdev);
shost->shost_classdev.dev = &shost->shost_gendev;
@@ -426,10 +472,14 @@ int scsi_sysfs_add_host(struct Scsi_Host *shost, struct device *dev)
if (error)
return error;
+ set_bit(SHOST_ADD, &shost->shost_state);
+ get_device(shost->shost_gendev.parent);
+
error = class_device_add(&shost->shost_classdev);
if (error)
goto clean_device;
+ get_device(&shost->shost_gendev);
if (shost->hostt->shost_attrs) {
for (i = 0; shost->hostt->shost_attrs[i]; i++) {
error = class_attr_add(&shost->shost_classdev,
@@ -465,6 +515,11 @@ clean_device:
**/
void scsi_sysfs_remove_host(struct Scsi_Host *shost)
{
- class_device_del(&shost->shost_classdev);
+ unsigned long flags;
+ spin_lock_irqsave(shost->host_lock, flags);
+ set_bit(SHOST_DEL, &shost->shost_state);
+ spin_unlock_irqrestore(shost->host_lock, flags);
+
+ class_device_unregister(&shost->shost_classdev);
device_del(&shost->shost_gendev);
}
diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c
index 441ca6e58cfc..30bdd330828a 100644
--- a/drivers/scsi/sd.c
+++ b/drivers/scsi/sd.c
@@ -651,9 +651,11 @@ static void sd_rw_intr(struct scsi_cmnd * SCpnt)
/* An error occurred */
if (driver_byte(result) != 0 && /* An error occurred */
- SCpnt->sense_buffer[0] == 0xF0) { /* Sense data is valid */
+ (SCpnt->sense_buffer[0] & 0x7f) == 0x70) { /* Sense current */
switch (SCpnt->sense_buffer[2]) {
case MEDIUM_ERROR:
+ if (!(SCpnt->sense_buffer[0] & 0x80))
+ break;
error_sector = (SCpnt->sense_buffer[3] << 24) |
(SCpnt->sense_buffer[4] << 16) |
(SCpnt->sense_buffer[5] << 8) |
@@ -696,7 +698,7 @@ static void sd_rw_intr(struct scsi_cmnd * SCpnt)
* hard error.
*/
print_sense("sd", SCpnt);
- result = 0;
+ SCpnt->result = 0;
SCpnt->sense_buffer[0] = 0x0;
good_sectors = this_count;
break;
diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c
index eef2346282e3..dc8e7e2a9095 100644
--- a/drivers/scsi/sg.c
+++ b/drivers/scsi/sg.c
@@ -954,7 +954,8 @@ sg_ioctl(struct inode *inode, struct file *filp,
if (sdp->detached)
return -ENODEV;
if (filp->f_flags & O_NONBLOCK) {
- if (sdp->device->host->in_recovery)
+ if (test_bit(SHOST_RECOVERY,
+ &sdp->device->host->shost_state))
return -EBUSY;
} else if (!scsi_block_when_processing_errors(sdp->device))
return -EBUSY;
diff --git a/drivers/scsi/sr.c b/drivers/scsi/sr.c
index 7c24b78e45e6..e91c870710d9 100644
--- a/drivers/scsi/sr.c
+++ b/drivers/scsi/sr.c
@@ -181,6 +181,7 @@ static void rw_intr(struct scsi_cmnd * SCpnt)
int this_count = SCpnt->bufflen >> 9;
int good_sectors = (result == 0 ? this_count : 0);
int block_sectors = 0;
+ long error_sector;
struct scsi_cd *cd = scsi_cd(SCpnt->request->rq_disk);
#ifdef DEBUG
@@ -194,33 +195,57 @@ static void rw_intr(struct scsi_cmnd * SCpnt)
* memcpy's that could be avoided.
*/
if (driver_byte(result) != 0 && /* An error occurred */
- SCpnt->sense_buffer[0] == 0xF0 && /* Sense data is valid */
- (SCpnt->sense_buffer[2] == MEDIUM_ERROR ||
- SCpnt->sense_buffer[2] == VOLUME_OVERFLOW ||
- SCpnt->sense_buffer[2] == ILLEGAL_REQUEST)) {
- long error_sector = (SCpnt->sense_buffer[3] << 24) |
- (SCpnt->sense_buffer[4] << 16) |
- (SCpnt->sense_buffer[5] << 8) |
- SCpnt->sense_buffer[6];
- if (SCpnt->request->bio != NULL)
- block_sectors = bio_sectors(SCpnt->request->bio);
- if (block_sectors < 4)
- block_sectors = 4;
- if (cd->device->sector_size == 2048)
- error_sector <<= 2;
- error_sector &= ~(block_sectors - 1);
- good_sectors = error_sector - SCpnt->request->sector;
- if (good_sectors < 0 || good_sectors >= this_count)
- good_sectors = 0;
- /*
- * The SCSI specification allows for the value returned by READ
- * CAPACITY to be up to 75 2K sectors past the last readable
- * block. Therefore, if we hit a medium error within the last
- * 75 2K sectors, we decrease the saved size value.
- */
- if (error_sector < get_capacity(cd->disk) &&
- cd->capacity - error_sector < 4 * 75)
- set_capacity(cd->disk, error_sector);
+ (SCpnt->sense_buffer[0] & 0x7f) == 0x70) { /* Sense current */
+ switch (SCpnt->sense_buffer[2]) {
+ case MEDIUM_ERROR:
+ case VOLUME_OVERFLOW:
+ case ILLEGAL_REQUEST:
+ if (!(SCpnt->sense_buffer[0] & 0x90))
+ break;
+ error_sector = (SCpnt->sense_buffer[3] << 24) |
+ (SCpnt->sense_buffer[4] << 16) |
+ (SCpnt->sense_buffer[5] << 8) |
+ SCpnt->sense_buffer[6];
+ if (SCpnt->request->bio != NULL)
+ block_sectors =
+ bio_sectors(SCpnt->request->bio);
+ if (block_sectors < 4)
+ block_sectors = 4;
+ if (cd->device->sector_size == 2048)
+ error_sector <<= 2;
+ error_sector &= ~(block_sectors - 1);
+ good_sectors = error_sector - SCpnt->request->sector;
+ if (good_sectors < 0 || good_sectors >= this_count)
+ good_sectors = 0;
+ /*
+ * The SCSI specification allows for the value
+ * returned by READ CAPACITY to be up to 75 2K
+ * sectors past the last readable block.
+ * Therefore, if we hit a medium error within the
+ * last 75 2K sectors, we decrease the saved size
+ * value.
+ */
+ if (error_sector < get_capacity(cd->disk) &&
+ cd->capacity - error_sector < 4 * 75)
+ set_capacity(cd->disk, error_sector);
+ break;
+
+ case RECOVERED_ERROR:
+
+ /*
+ * An error occured, but it recovered. Inform the
+ * user, but make sure that it's not treated as a
+ * hard error.
+ */
+ print_sense("sr", SCpnt);
+ SCpnt->result = 0;
+ SCpnt->sense_buffer[0] = 0x0;
+ good_sectors = this_count;
+ break;
+
+ default:
+ break;
+ }
}
/*
diff --git a/drivers/scsi/st.c b/drivers/scsi/st.c
index 64d8671c3e76..afd0a5c8b1c5 100644
--- a/drivers/scsi/st.c
+++ b/drivers/scsi/st.c
@@ -17,7 +17,7 @@
Last modified: 18-JAN-1998 Richard Gooch <rgooch@atnf.csiro.au> Devfs support
*/
-static char *verstr = "20030622";
+static char *verstr = "20030811";
#include <linux/module.h>
@@ -1312,6 +1312,19 @@ static int setup_buffering(Scsi_Tape *STp, const char *buf, size_t count, int is
}
+/* Can be called more than once after each setup_buffer() */
+static void release_buffering(Scsi_Tape *STp)
+{
+ ST_buffer *STbp;
+
+ STbp = STp->buffer;
+ if (STbp->do_dio) {
+ sgl_unmap_user_pages(&(STbp->sg[0]), STbp->do_dio, FALSE);
+ STbp->do_dio = 0;
+ }
+}
+
+
/* Write command */
static ssize_t
st_write(struct file *filp, const char *buf, size_t count, loff_t * ppos)
@@ -1589,11 +1602,7 @@ static ssize_t
out:
if (SRpnt != NULL)
scsi_release_request(SRpnt);
- STbp = STp->buffer;
- if (STbp->do_dio) {
- sgl_unmap_user_pages(&(STbp->sg[0]), STbp->do_dio, FALSE);
- STbp->do_dio = 0;
- }
+ release_buffering(STp);
up(&STp->lock);
return retval;
@@ -1601,7 +1610,10 @@ static ssize_t
/* Read data from the tape. Returns zero in the normal case, one if the
eof status has changed, and the negative error code in case of a
- fatal error. Otherwise updates the buffer and the eof state. */
+ fatal error. Otherwise updates the buffer and the eof state.
+
+ Does release user buffer mapping if it is set.
+*/
static long read_tape(Scsi_Tape *STp, long count, Scsi_Request ** aSRpnt)
{
int transfer, blks, bytes;
@@ -1647,6 +1659,7 @@ static long read_tape(Scsi_Tape *STp, long count, Scsi_Request ** aSRpnt)
SRpnt = *aSRpnt;
SRpnt = st_do_scsi(SRpnt, STp, cmd, bytes, SCSI_DATA_READ,
STp->timeout, MAX_RETRIES, TRUE);
+ release_buffering(STp);
*aSRpnt = SRpnt;
if (!SRpnt)
return STbp->syscall_result;
@@ -1788,7 +1801,7 @@ static ssize_t
ssize_t total;
ssize_t retval = 0;
ssize_t i, transfer;
- int special;
+ int special, do_dio = 0;
Scsi_Request *SRpnt = NULL;
Scsi_Tape *STp = filp->private_data;
ST_mode *STm;
@@ -1826,6 +1839,7 @@ static ssize_t
retval = setup_buffering(STp, buf, count, TRUE);
if (retval)
goto out;
+ do_dio = STbp->do_dio;
if (STbp->buffer_bytes == 0 &&
STps->eof >= ST_EOD_1) {
@@ -1838,7 +1852,7 @@ static ssize_t
goto out;
}
- if (!STbp->do_dio) {
+ if (do_dio) {
/* Check the buffer writability before any tape movement. Don't alter
buffer data. */
if (copy_from_user(&i, buf, 1) != 0 ||
@@ -1876,7 +1890,7 @@ static ssize_t
) /* end DEB */
transfer = STbp->buffer_bytes < count - total ?
STbp->buffer_bytes : count - total;
- if (!STbp->do_dio) {
+ if (!do_dio) {
i = from_buffer(STbp, buf, transfer);
if (i) {
retval = i;
@@ -1917,9 +1931,8 @@ static ssize_t
scsi_release_request(SRpnt);
SRpnt = NULL;
}
- if (STbp->do_dio) {
- sgl_unmap_user_pages(&(STbp->sg[0]), STbp->do_dio, TRUE);
- STbp->do_dio = 0;
+ if (do_dio) {
+ release_buffering(STp);
STbp->buffer_bytes = 0;
}
up(&STp->lock);
@@ -2348,6 +2361,7 @@ static int st_int_ioctl(Scsi_Tape *STp, unsigned int cmd_in, unsigned long arg)
int datalen = 0, direction = SCSI_DATA_NONE;
char *name = tape_name(STp);
+ WARN_ON(STp->buffer->do_dio != 0);
if (STp->ready != ST_READY) {
if (STp->ready == ST_NO_TAPE)
return (-ENOMEDIUM);
diff --git a/drivers/scsi/st.h b/drivers/scsi/st.h
index 2c98654769c0..80a0f397ce8a 100644
--- a/drivers/scsi/st.h
+++ b/drivers/scsi/st.h
@@ -11,7 +11,7 @@
typedef struct {
unsigned char in_use;
unsigned char dma; /* DMA-able buffer */
- unsigned char do_dio;
+ unsigned char do_dio; /* direct i/o set up? */
int buffer_size;
int buffer_blocks;
int buffer_bytes;
diff --git a/drivers/scsi/sym53c8xx.c b/drivers/scsi/sym53c8xx.c
index 8a6c3972a7c4..7d534560df2b 100644
--- a/drivers/scsi/sym53c8xx.c
+++ b/drivers/scsi/sym53c8xx.c
@@ -14720,6 +14720,5 @@ static Scsi_Host_Template driver_template = {
.cmd_per_lun = SCSI_NCR_CMD_PER_LUN,
.max_sectors = MAX_HW_SEGMENTS*8,
.use_clustering = DISABLE_CLUSTERING,
- .highmem_io = 1
};
#include "scsi_module.c"
diff --git a/drivers/scsi/sym53c8xx_2/sym_glue.c b/drivers/scsi/sym53c8xx_2/sym_glue.c
index b0266f645172..7498d20f8c28 100644
--- a/drivers/scsi/sym53c8xx_2/sym_glue.c
+++ b/drivers/scsi/sym53c8xx_2/sym_glue.c
@@ -57,35 +57,6 @@
#define NAME53C "sym53c"
#define NAME53C8XX "sym53c8xx"
-/*
- * Simple Wrapper to kernel PCI bus interface.
- */
-
-typedef struct pci_dev *pcidev_t;
-#define PCIDEV_NULL (0)
-#define PciBusNumber(d) (d)->bus->number
-#define PciDeviceFn(d) (d)->devfn
-#define PciVendorId(d) (d)->vendor
-#define PciDeviceId(d) (d)->device
-#define PciIrqLine(d) (d)->irq
-
-static u_long __init
-pci_get_base_cookie(struct pci_dev *pdev, int index)
-{
- u_long base;
-
-#if LINUX_VERSION_CODE > LinuxVersionCode(2,3,12)
- base = pdev->resource[index].start;
-#else
- base = pdev->base_address[index];
-#if BITS_PER_LONG > 32
- if ((base & 0x7) == 0x4)
- base |= (((u_long)pdev->base_address[++index]) << 32);
-#endif
-#endif
- return (base & ~0x7ul);
-}
-
static int __init
pci_get_base_address(struct pci_dev *pdev, int index, u_long *base)
{
@@ -95,7 +66,7 @@ pci_get_base_address(struct pci_dev *pdev, int index, u_long *base)
pci_read_config_dword(pdev, PCI_BAR_OFFSET(index), &tmp);
*base = tmp;
++index;
- if ((tmp & 0x7) == 0x4) {
+ if ((tmp & 0x7) == PCI_BASE_ADDRESS_MEM_TYPE_64) {
#if BITS_PER_LONG > 32
pci_read_config_dword(pdev, PCI_BAR_OFFSET(index), &tmp);
*base |= (((u_long)tmp) << 32);
@@ -106,14 +77,6 @@ pci_get_base_address(struct pci_dev *pdev, int index, u_long *base)
#undef PCI_BAR_OFFSET
}
-#if LINUX_VERSION_CODE < LinuxVersionCode(2,4,0)
-#define pci_enable_device(pdev) (0)
-#endif
-
-#if LINUX_VERSION_CODE < LinuxVersionCode(2,4,4)
-#define scsi_set_pci_device(inst, pdev) do { ;} while (0)
-#endif
-
/*
* Insert a delay in micro-seconds and milli-seconds.
*/
@@ -235,53 +198,8 @@ static void __init pci_unmap_mem(u_long vaddr, u_long size)
*/
static struct Scsi_Host *first_host = NULL;
-/*
- * /proc directory entry and proc_info.
- */
-#if LINUX_VERSION_CODE < LinuxVersionCode(2,3,27)
-static struct proc_dir_entry proc_scsi_sym53c8xx = {
- PROC_SCSI_SYM53C8XX, 9, NAME53C8XX,
- S_IFDIR | S_IRUGO | S_IXUGO, 2
-};
-#endif
-
-/*
- * Transfer direction
- *
- * Until some linux kernel version near 2.3.40, low-level scsi
- * drivers were not told about data transfer direction.
- */
-#if LINUX_VERSION_CODE > LinuxVersionCode(2, 3, 40)
-
#define scsi_data_direction(cmd) (cmd->sc_data_direction)
-#else
-
-static __inline__ int scsi_data_direction(Scsi_Cmnd *cmd)
-{
- int direction;
-
- switch((int) cmd->cmnd[0]) {
- case 0x08: /* READ(6) 08 */
- case 0x28: /* READ(10) 28 */
- case 0xA8: /* READ(12) A8 */
- direction = SCSI_DATA_READ;
- break;
- case 0x0A: /* WRITE(6) 0A */
- case 0x2A: /* WRITE(10) 2A */
- case 0xAA: /* WRITE(12) AA */
- direction = SCSI_DATA_WRITE;
- break;
- default:
- direction = SCSI_DATA_UNKNOWN;
- break;
- }
-
- return direction;
-}
-
-#endif
-
/*
* Driver host data structure.
*/
@@ -305,7 +223,7 @@ typedef dma_addr_t bus_addr_t;
struct sym_eh_wait {
struct semaphore sem;
struct timer_list timer;
- void (*old_done)(Scsi_Cmnd *);
+ void (*old_done)(struct scsi_cmnd *);
int to_do;
int timed_out;
};
@@ -325,7 +243,7 @@ struct sym_ucmd { /* Override the SCSI pointer structure */
typedef struct sym_ucmd *ucmd_p;
#define SYM_UCMD_PTR(cmd) ((ucmd_p)(&(cmd)->SCp))
-#define SYM_SCMD_PTR(ucmd) sym_que_entry(ucmd, Scsi_Cmnd, SCp)
+#define SYM_SCMD_PTR(ucmd) sym_que_entry(ucmd, struct scsi_cmnd, SCp)
#define SYM_SOFTC_PTR(cmd) (((struct host_data *)cmd->device->host->hostdata)->ncb)
/*
@@ -367,7 +285,7 @@ typedef struct sym_ucmd *ucmd_p;
#define bus_sg_dma_address(sc) sg_dma_address(sc)
#define bus_sg_dma_len(sc) sg_dma_len(sc)
-static void __unmap_scsi_data(pcidev_t pdev, Scsi_Cmnd *cmd)
+static void __unmap_scsi_data(struct pci_dev *pdev, struct scsi_cmnd *cmd)
{
int dma_dir = scsi_to_pci_dma_dir(cmd->sc_data_direction);
@@ -383,7 +301,7 @@ static void __unmap_scsi_data(pcidev_t pdev, Scsi_Cmnd *cmd)
SYM_UCMD_PTR(cmd)->data_mapped = 0;
}
-static bus_addr_t __map_scsi_single_data(pcidev_t pdev, Scsi_Cmnd *cmd)
+static bus_addr_t __map_scsi_single_data(struct pci_dev *pdev, struct scsi_cmnd *cmd)
{
bus_addr_t mapping;
int dma_dir = scsi_to_pci_dma_dir(cmd->sc_data_direction);
@@ -398,7 +316,7 @@ static bus_addr_t __map_scsi_single_data(pcidev_t pdev, Scsi_Cmnd *cmd)
return mapping;
}
-static int __map_scsi_sg_data(pcidev_t pdev, Scsi_Cmnd *cmd)
+static int __map_scsi_sg_data(struct pci_dev *pdev, struct scsi_cmnd *cmd)
{
int use_sg;
int dma_dir = scsi_to_pci_dma_dir(cmd->sc_data_direction);
@@ -412,7 +330,7 @@ static int __map_scsi_sg_data(pcidev_t pdev, Scsi_Cmnd *cmd)
return use_sg;
}
-static void __sync_scsi_data(pcidev_t pdev, Scsi_Cmnd *cmd)
+static void __sync_scsi_data(struct pci_dev *pdev, struct scsi_cmnd *cmd)
{
int dma_dir = scsi_to_pci_dma_dir(cmd->sc_data_direction);
@@ -441,14 +359,14 @@ static void __sync_scsi_data(pcidev_t pdev, Scsi_Cmnd *cmd)
/*
* Complete a pending CAM CCB.
*/
-void sym_xpt_done(hcb_p np, Scsi_Cmnd *ccb)
+void sym_xpt_done(hcb_p np, struct scsi_cmnd *ccb)
{
sym_remque(&SYM_UCMD_PTR(ccb)->link_cmdq);
unmap_scsi_data(np, ccb);
ccb->scsi_done(ccb);
}
-void sym_xpt_done2(hcb_p np, Scsi_Cmnd *ccb, int cam_status)
+void sym_xpt_done2(hcb_p np, struct scsi_cmnd *ccb, int cam_status)
{
sym_set_cam_status(ccb, cam_status);
sym_xpt_done(np, ccb);
@@ -460,7 +378,7 @@ void sym_xpt_done2(hcb_p np, Scsi_Cmnd *ccb, int cam_status)
*/
void sym_print_addr (ccb_p cp)
{
- Scsi_Cmnd *cmd = cp->cam_ccb;
+ struct scsi_cmnd *cmd = cp->cam_ccb;
if (cmd)
printf("%s:%d:%d:", sym_name(SYM_SOFTC_PTR(cmd)),
cmd->device->id,cmd->device->lun);
@@ -521,7 +439,7 @@ static int sym_xerr_cam_status(int cam_status, int x_status)
*/
void sym_set_cam_result_error(hcb_p np, ccb_p cp, int resid)
{
- Scsi_Cmnd *csio = cp->cam_ccb;
+ struct scsi_cmnd *csio = cp->cam_ccb;
u_int cam_status, scsi_status, drv_status;
drv_status = 0;
@@ -581,9 +499,7 @@ void sym_set_cam_result_error(hcb_p np, ccb_p cp, int resid)
*/
cam_status = sym_xerr_cam_status(DID_ERROR, cp->xerr_status);
}
-#if LINUX_VERSION_CODE >= LinuxVersionCode(2,3,99)
csio->resid = resid;
-#endif
csio->result = (drv_status << 24) + (cam_status << 16) + scsi_status;
}
@@ -591,7 +507,7 @@ void sym_set_cam_result_error(hcb_p np, ccb_p cp, int resid)
/*
* Called on successfull INQUIRY response.
*/
-void sym_sniff_inquiry(hcb_p np, Scsi_Cmnd *cmd, int resid)
+void sym_sniff_inquiry(hcb_p np, struct scsi_cmnd *cmd, int resid)
{
int retv;
@@ -612,7 +528,7 @@ void sym_sniff_inquiry(hcb_p np, Scsi_Cmnd *cmd, int resid)
* Build the scatter/gather array for an I/O.
*/
-static int sym_scatter_no_sglist(hcb_p np, ccb_p cp, Scsi_Cmnd *cmd)
+static int sym_scatter_no_sglist(hcb_p np, ccb_p cp, struct scsi_cmnd *cmd)
{
struct sym_tblmove *data = &cp->phys.data[SYM_CONF_MAX_SG-1];
int segment;
@@ -634,7 +550,7 @@ static int sym_scatter_no_sglist(hcb_p np, ccb_p cp, Scsi_Cmnd *cmd)
return segment;
}
-static int sym_scatter(hcb_p np, ccb_p cp, Scsi_Cmnd *cmd)
+static int sym_scatter(hcb_p np, ccb_p cp, struct scsi_cmnd *cmd)
{
int segment;
int use_sg = (int) cmd->use_sg;
@@ -671,9 +587,9 @@ static int sym_scatter(hcb_p np, ccb_p cp, Scsi_Cmnd *cmd)
/*
* Queue a SCSI command.
*/
-static int sym_queue_command(hcb_p np, Scsi_Cmnd *ccb)
+static int sym_queue_command(hcb_p np, struct scsi_cmnd *ccb)
{
-/* Scsi_Device *device = ccb->device; */
+/* struct scsi_device *device = ccb->device; */
tcb_p tp;
lcb_p lp;
ccb_p cp;
@@ -736,7 +652,7 @@ static int sym_queue_command(hcb_p np, Scsi_Cmnd *ccb)
/*
* Setup buffers and pointers that address the CDB.
*/
-static int __inline sym_setup_cdb(hcb_p np, Scsi_Cmnd *ccb, ccb_p cp)
+static int __inline sym_setup_cdb(hcb_p np, struct scsi_cmnd *ccb, ccb_p cp)
{
u32 cmd_ba;
int cmd_len;
@@ -762,7 +678,7 @@ static int __inline sym_setup_cdb(hcb_p np, Scsi_Cmnd *ccb, ccb_p cp)
/*
* Setup pointers that address the data and start the I/O.
*/
-int sym_setup_data_and_start(hcb_p np, Scsi_Cmnd *csio, ccb_p cp)
+int sym_setup_data_and_start(hcb_p np, struct scsi_cmnd *csio, ccb_p cp)
{
int dir;
tcb_p tp = &np->target[cp->target];
@@ -841,20 +757,6 @@ static void sym_timer (hcb_p np)
{
u_long thistime = ktime_get(0);
-#if LINUX_VERSION_CODE < LinuxVersionCode(2, 4, 0)
- /*
- * If release process in progress, let's go
- * Set the release stage from 1 to 2 to synchronize
- * with the release process.
- */
-
- if (np->s.release_stage) {
- if (np->s.release_stage == 1)
- np->s.release_stage = 2;
- return;
- }
-#endif
-
/*
* Restart the timer.
*/
@@ -933,7 +835,7 @@ void sym_log_bus_error(hcb_p np)
*/
static void sym_requeue_awaiting_cmds(hcb_p np)
{
- Scsi_Cmnd *cmd;
+ struct scsi_cmnd *cmd;
ucmd_p ucp = SYM_UCMD_PTR(cmd);
SYM_QUEHEAD tmp_cmdq;
int sts;
@@ -954,7 +856,7 @@ static void sym_requeue_awaiting_cmds(hcb_p np)
/*
* Linux entry point of the queuecommand() function
*/
-int sym53c8xx_queue_command (Scsi_Cmnd *cmd, void (*done)(Scsi_Cmnd *))
+int sym53c8xx_queue_command (struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *))
{
hcb_p np = SYM_SOFTC_PTR(cmd);
ucmd_p ucp = SYM_UCMD_PTR(cmd);
@@ -1066,7 +968,7 @@ static void sym53c8xx_timer(unsigned long npref)
/*
* Our general completion handler.
*/
-static void __sym_eh_done(Scsi_Cmnd *cmd, int timed_out)
+static void __sym_eh_done(struct scsi_cmnd *cmd, int timed_out)
{
struct sym_eh_wait *ep = SYM_UCMD_PTR(cmd)->eh_wait;
if (!ep)
@@ -1091,18 +993,18 @@ static void __sym_eh_done(Scsi_Cmnd *cmd, int timed_out)
/*
* scsi_done() alias when error recovery is in progress.
*/
-static void sym_eh_done(Scsi_Cmnd *cmd) { __sym_eh_done(cmd, 0); }
+static void sym_eh_done(struct scsi_cmnd *cmd) { __sym_eh_done(cmd, 0); }
/*
* Some timeout handler to avoid waiting too long.
*/
-static void sym_eh_timeout(u_long p) { __sym_eh_done((Scsi_Cmnd *)p, 1); }
+static void sym_eh_timeout(u_long p) { __sym_eh_done((struct scsi_cmnd *)p, 1); }
/*
* Generic method for our eh processing.
* The 'op' argument tells what we have to do.
*/
-static int sym_eh_handler(int op, char *opname, Scsi_Cmnd *cmd)
+static int sym_eh_handler(int op, char *opname, struct scsi_cmnd *cmd)
{
hcb_p np = SYM_SOFTC_PTR(cmd);
SYM_QUEHEAD *qp;
@@ -1147,11 +1049,7 @@ prepare:
goto finish;
break;
case SYM_EH_DO_WAIT:
-#if LINUX_VERSION_CODE > LinuxVersionCode(2,3,0)
init_MUTEX_LOCKED(&ep->sem);
-#else
- ep->sem = MUTEX_LOCKED;
-#endif
/* fall through */
case SYM_EH_DO_COMPLETE:
ep->old_done = cmd->scsi_done;
@@ -1219,22 +1117,22 @@ finish:
/*
* Error handlers called from the eh thread (one thread per HBA).
*/
-int sym53c8xx_eh_abort_handler(Scsi_Cmnd *cmd)
+int sym53c8xx_eh_abort_handler(struct scsi_cmnd *cmd)
{
return sym_eh_handler(SYM_EH_ABORT, "ABORT", cmd);
}
-int sym53c8xx_eh_device_reset_handler(Scsi_Cmnd *cmd)
+int sym53c8xx_eh_device_reset_handler(struct scsi_cmnd *cmd)
{
return sym_eh_handler(SYM_EH_DEVICE_RESET, "DEVICE RESET", cmd);
}
-int sym53c8xx_eh_bus_reset_handler(Scsi_Cmnd *cmd)
+int sym53c8xx_eh_bus_reset_handler(struct scsi_cmnd *cmd)
{
return sym_eh_handler(SYM_EH_BUS_RESET, "BUS RESET", cmd);
}
-int sym53c8xx_eh_host_reset_handler(Scsi_Cmnd *cmd)
+int sym53c8xx_eh_host_reset_handler(struct scsi_cmnd *cmd)
{
return sym_eh_handler(SYM_EH_HOST_RESET, "HOST RESET", cmd);
}
@@ -1331,7 +1229,7 @@ static int device_queue_depth(hcb_p np, int target, int lun)
* Linux entry point for device queue sizing.
*/
int
-sym53c8xx_slave_configure(Scsi_Device *device)
+sym53c8xx_slave_configure(struct scsi_device *device)
{
struct Scsi_Host *host = device->host;
hcb_p np;
@@ -1853,10 +1751,6 @@ static void sym_free_resources(hcb_p np)
#ifdef SYM_LINUX_DYNAMIC_DMA_MAPPING
static int sym_setup_bus_dma_mask(hcb_p np)
{
-#if LINUX_VERSION_CODE < LinuxVersionCode(2,4,3)
- if (!pci_dma_supported(np->s.device, 0xffffffffUL))
- goto out_err32;
-#else
#if SYM_CONF_DMA_ADDRESSING_MODE == 0
if (pci_set_dma_mask(np->s.device, 0xffffffffUL))
goto out_err32;
@@ -1879,7 +1773,6 @@ static int sym_setup_bus_dma_mask(hcb_p np)
}
#undef PciDmaMask
#endif
-#endif
return 0;
out_err32:
@@ -1899,7 +1792,7 @@ out_err32:
* start the timer daemon.
*/
static int __init
-sym_attach (Scsi_Host_Template *tpnt, int unit, sym_device *dev)
+sym_attach (struct scsi_host_template *tpnt, int unit, sym_device *dev)
{
struct host_data *host_data;
hcb_p np = 0;
@@ -1934,7 +1827,7 @@ sym_attach (Scsi_Host_Template *tpnt, int unit, sym_device *dev)
/*
* Allocate host_data structure
*/
- if (!(instance = scsi_register(tpnt, sizeof(*host_data))))
+ if (!(instance = scsi_host_alloc(tpnt, sizeof(*host_data))))
goto attach_failed;
host_data = (struct host_data *) instance->hostdata;
@@ -1960,6 +1853,8 @@ sym_attach (Scsi_Host_Template *tpnt, int unit, sym_device *dev)
host_data->ncb = np;
np->s.host = instance;
+ pci_set_drvdata(dev->pdev, np);
+
SYM_INIT_LOCK_HCB(np);
/*
@@ -2106,11 +2001,7 @@ sym_attach (Scsi_Host_Template *tpnt, int unit, sym_device *dev)
instance->max_id = np->maxwide ? 16 : 8;
instance->max_lun = SYM_CONF_MAX_LUN;
#ifndef SYM_CONF_IOMAPPED
-#if LINUX_VERSION_CODE >= LinuxVersionCode(2,3,29)
instance->base = (unsigned long) np->s.mmio_va;
-#else
- instance->base = (char *) np->s.mmio_va;
-#endif
#endif
instance->irq = np->s.irq;
instance->unique_id = np->s.io_port;
@@ -2120,23 +2011,21 @@ sym_attach (Scsi_Host_Template *tpnt, int unit, sym_device *dev)
instance->cmd_per_lun = SYM_CONF_MAX_TAG;
instance->can_queue = (SYM_CONF_MAX_START-2);
instance->sg_tablesize = SYM_CONF_MAX_SG;
-#if LINUX_VERSION_CODE >= LinuxVersionCode(2,4,0)
instance->max_cmd_len = 16;
-#endif
- instance->highmem_io = 1;
SYM_UNLOCK_HCB(np, flags);
- scsi_set_device(instance, &dev->pdev->dev);
-
/*
* Now let the generic SCSI driver
* look for the SCSI devices on the bus ..
*/
+ scsi_add_host(instance, &dev->pdev->dev); /* XXX: handle failure */
+ scsi_scan_host(instance);
return 0;
attach_failed:
- if (!instance) return -1;
+ if (!instance)
+ return -1;
printf_info("%s: giving up ...\n", sym_name(np));
if (np)
sym_free_resources(np);
@@ -2371,60 +2260,9 @@ int __init sym53c8xx_setup(char *str)
return 1;
}
-#if LINUX_VERSION_CODE >= LinuxVersionCode(2,3,13)
#ifndef MODULE
__setup("sym53c8xx=", sym53c8xx_setup);
#endif
-#endif
-
-#ifdef SYM_CONF_PQS_PDS_SUPPORT
-/*
- * Detect all NCR PQS/PDS boards and keep track of their bus nr.
- *
- * The NCR PQS or PDS card is constructed as a DEC bridge
- * behind which sit a proprietary NCR memory controller and
- * four or two 53c875s as separate devices. In its usual mode
- * of operation, the 875s are slaved to the memory controller
- * for all transfers. We can tell if an 875 is part of a
- * PQS/PDS or not since if it is, it will be on the same bus
- * as the memory controller. To operate with the Linux
- * driver, the memory controller is disabled and the 875s
- * freed to function independently. The only wrinkle is that
- * the preset SCSI ID (which may be zero) must be read in from
- * a special configuration space register of the 875
- */
-#ifndef SYM_CONF_MAX_PQS_BUS
-#define SYM_CONF_MAX_PQS_BUS 16
-#endif
-static int pqs_bus[SYM_CONF_MAX_PQS_BUS] __initdata = { 0 };
-
-static void __init sym_detect_pqs_pds(void)
-{
- short index;
- pcidev_t dev = PCIDEV_NULL;
-
- for(index=0; index < SYM_CONF_MAX_PQS_BUS; index++) {
- u_char tmp;
-
- dev = pci_find_device(0x101a, 0x0009, dev);
- if (dev == PCIDEV_NULL) {
- pqs_bus[index] = -1;
- break;
- }
- printf_info(NAME53C8XX ": NCR PQS/PDS memory controller detected on bus %d\n", PciBusNumber(dev));
- pci_read_config_byte(dev, 0x44, &tmp);
- /* bit 1: allow individual 875 configuration */
- tmp |= 0x2;
- pci_write_config_byte(dev, 0x44, tmp);
- pci_read_config_byte(dev, 0x45, &tmp);
- /* bit 2: drive individual 875 interrupts to the bus */
- tmp |= 0x4;
- pci_write_config_byte(dev, 0x45, tmp);
-
- pqs_bus[index] = PciBusNumber(dev);
- }
-}
-#endif /* SYM_CONF_PQS_PDS_SUPPORT */
/*
* Read and check the PCI configuration for any detected NCR
@@ -2432,7 +2270,7 @@ static void __init sym_detect_pqs_pds(void)
* been detected.
*/
static int __init
-sym53c8xx_pci_init(Scsi_Host_Template *tpnt, pcidev_t pdev, sym_device *device)
+sym53c8xx_pci_init(struct pci_dev *pdev, sym_device *device)
{
u_short vendor_id, device_id, command, status_reg;
u_char cache_line_size;
@@ -2440,34 +2278,30 @@ sym53c8xx_pci_init(Scsi_Host_Template *tpnt, pcidev_t pdev, sym_device *device)
u_char pci_fix_up = SYM_SETUP_PCI_FIX_UP;
u_char revision;
u_int irq;
- u_long base, base_2, base_io;
+ u_long base, base_2;
u_long base_c, base_2_c, io_port;
int i;
sym_chip *chip;
/* Choose some short name for this device */
- sprintf(device->s.inst_name, "sym.%d.%d.%d",
- PciBusNumber(pdev),
- (int) (PciDeviceFn(pdev) & 0xf8) >> 3,
- (int) (PciDeviceFn(pdev) & 7));
+ sprintf(device->s.inst_name, "sym.%d.%d.%d", pdev->bus->number,
+ PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn));
/*
* Read needed minimal info from the PCI config space.
*/
- vendor_id = PciVendorId(pdev);
- device_id = PciDeviceId(pdev);
- irq = PciIrqLine(pdev);
+ vendor_id = pdev->vendor;
+ device_id = pdev->device;
+ irq = pdev->irq;
- i = pci_get_base_address(pdev, 0, &base_io);
- io_port = pci_get_base_cookie(pdev, 0);
+ io_port = pdev->resource[0].start;
- base_c = pci_get_base_cookie(pdev, i);
- i = pci_get_base_address(pdev, i, &base);
+ base_c = pdev->resource[1].start;
+ i = pci_get_base_address(pdev, 1, &base);
- base_2_c = pci_get_base_cookie(pdev, i);
- (void) pci_get_base_address(pdev, i, &base_2);
+ base_2_c = pdev->resource[i].start;
+ pci_get_base_address(pdev, i, &base_2);
- io_port &= PCI_BASE_ADDRESS_IO_MASK;
base &= PCI_BASE_ADDRESS_MEM_MASK;
base_2 &= PCI_BASE_ADDRESS_MEM_MASK;
@@ -2476,9 +2310,9 @@ sym53c8xx_pci_init(Scsi_Host_Template *tpnt, pcidev_t pdev, sym_device *device)
/*
* If user excluded this chip, donnot initialize it.
*/
- if (base_io) {
+ if (io_port) {
for (i = 0 ; i < 8 ; i++) {
- if (sym_driver_setup.excludes[i] == base_io)
+ if (sym_driver_setup.excludes[i] == io_port)
return -1;
}
}
@@ -2640,8 +2474,8 @@ sym53c8xx_pci_init(Scsi_Host_Template *tpnt, pcidev_t pdev, sym_device *device)
* Initialise device structure with items required by sym_attach.
*/
device->pdev = pdev;
- device->s.bus = PciBusNumber(pdev);
- device->s.device_fn = PciDeviceFn(pdev);
+ device->s.bus = pdev->bus->number;
+ device->s.device_fn = pdev->devfn;
device->s.base = base;
device->s.base_2 = base_2;
device->s.base_c = base_c;
@@ -2653,26 +2487,7 @@ sym53c8xx_pci_init(Scsi_Host_Template *tpnt, pcidev_t pdev, sym_device *device)
return 0;
}
-/*
- * List of supported NCR chip ids
- */
-static u_short sym_chip_ids[] __initdata = {
- PCI_ID_SYM53C810,
- PCI_ID_SYM53C815,
- PCI_ID_SYM53C825,
- PCI_ID_SYM53C860,
- PCI_ID_SYM53C875,
- PCI_ID_SYM53C875_2,
- PCI_ID_SYM53C885,
- PCI_ID_SYM53C875A,
- PCI_ID_SYM53C895,
- PCI_ID_SYM53C896,
- PCI_ID_SYM53C895A,
- PCI_ID_LSI53C1510D,
- PCI_ID_LSI53C1010,
- PCI_ID_LSI53C1010_2
-};
-
+#if 0
/*
* Detect all 53c8xx hosts and then attach them.
*
@@ -2683,9 +2498,9 @@ static u_short sym_chip_ids[] __initdata = {
* If no NVRAM is found or data appears invalid attach boards in
* the order they are detected.
*/
-int __init sym53c8xx_detect(Scsi_Host_Template *tpnt)
+int __init sym53c8xx_detect(struct scsi_host_template *tpnt)
{
- pcidev_t pcidev;
+ struct pci_dev *pcidev;
int i, j, chips, hosts, count;
int attach_count = 0;
sym_device *devtbl, *devp;
@@ -2737,7 +2552,7 @@ if (sym53c8xx)
#endif
j = 0;
count = 0;
- pcidev = PCIDEV_NULL;
+ pcidev = NULL;
while (1) {
char *msg = "";
if (count >= hosts)
@@ -2747,7 +2562,7 @@ if (sym53c8xx)
i = sym_driver_setup.reverse_probe ? chips - 1 - j : j;
pcidev = pci_find_device(PCI_VENDOR_ID_NCR, sym_chip_ids[i],
pcidev);
- if (pcidev == PCIDEV_NULL) {
+ if (pcidev == NULL) {
++j;
continue;
}
@@ -2756,8 +2571,7 @@ if (sym53c8xx)
continue;
devp = &devtbl[count];
devp->host_id = SYM_SETUP_HOST_ID;
- devp->attach_done = 0;
- if (sym53c8xx_pci_init(tpnt, pcidev, devp)) {
+ if (sym53c8xx_pci_init(pcidev, devp)) {
continue;
}
++count;
@@ -2789,7 +2603,7 @@ if (sym53c8xx)
*/
for(i = 0; i < SYM_CONF_MAX_PQS_BUS && pqs_bus[i] != -1; i++) {
u_char tmp;
- if (pqs_bus[i] == PciBusNumber(pcidev)) {
+ if (pqs_bus[i] == pcidev->bus->number) {
pci_read_config_byte(pcidev, 0x84, &tmp);
devp->pqs_pds = 1;
devp->host_id = tmp;
@@ -2868,7 +2682,7 @@ next:
return attach_count;
}
-
+#endif
/*
@@ -2883,32 +2697,7 @@ static int sym_detach(hcb_p np)
{
printk("%s: detaching ...\n", sym_name(np));
- /*
- * Try to delete the timer.
- * In the unlikely situation where this failed,
- * try to synchronize with the timer handler.
- */
-#if LINUX_VERSION_CODE < LinuxVersionCode(2, 4, 0)
- np->s.release_stage = 1;
- if (!del_timer(&np->s.timer)) {
- int i = 1000;
- int k = 1;
- while (1) {
- u_long flags;
- SYM_LOCK_HCB(np, flags);
- k = np->s.release_stage;
- SYM_UNLOCK_HCB(np, flags);
- if (k == 2 || !--i)
- break;
- MDELAY(5);
- }
- if (!i)
- printk("%s: failed to kill timer!\n", sym_name(np));
- }
- np->s.release_stage = 2;
-#else
- (void)del_timer_sync(&np->s.timer);
-#endif
+ del_timer_sync(&np->s.timer);
/*
* Reset NCR chip.
@@ -2928,27 +2717,26 @@ static int sym_detach(hcb_p np)
return 1;
}
+#if 0
int sym53c8xx_release(struct Scsi_Host *host)
{
sym_detach(((struct host_data *) host->hostdata)->ncb);
return 0;
}
+#endif
-/*
- * For bigots to keep silent. :)
- */
-#ifdef MODULE_LICENSE
MODULE_LICENSE("Dual BSD/GPL");
-#endif
/*
* Driver host template.
*/
-static Scsi_Host_Template driver_template = {
+static struct scsi_host_template sym2_template = {
.name = "sym53c8xx",
+#if 0
.detect = sym53c8xx_detect,
.release = sym53c8xx_release,
+#endif
.info = sym53c8xx_info,
.queuecommand = sym53c8xx_queue_command,
.slave_configure = sym53c8xx_slave_configure,
@@ -2958,14 +2746,178 @@ static Scsi_Host_Template driver_template = {
.eh_host_reset_handler = sym53c8xx_eh_host_reset_handler,
.this_id = 7,
.use_clustering = DISABLE_CLUSTERING,
- .highmem_io = 1,
#ifdef SYM_LINUX_PROC_INFO_SUPPORT
.proc_info = sym53c8xx_proc_info,
-#if LINUX_VERSION_CODE < LinuxVersionCode(2,3,27)
- .proc_dir = &proc_scsi_sym53c8xx,
-#else
.proc_name = NAME53C8XX,
#endif
+};
+
+#ifdef _SYM_CONF_PQS_PDS_SUPPORT
+#if 0
+/*
+ * Detect all NCR PQS/PDS boards and keep track of their bus nr.
+ *
+ * The NCR PQS or PDS card is constructed as a DEC bridge
+ * behind which sit a proprietary NCR memory controller and
+ * four or two 53c875s as separate devices. In its usual mode
+ * of operation, the 875s are slaved to the memory controller
+ * for all transfers. We can tell if an 875 is part of a
+ * PQS/PDS or not since if it is, it will be on the same bus
+ * as the memory controller. To operate with the Linux
+ * driver, the memory controller is disabled and the 875s
+ * freed to function independently. The only wrinkle is that
+ * the preset SCSI ID (which may be zero) must be read in from
+ * a special configuration space register of the 875
+ */
+#ifndef SYM_CONF_MAX_PQS_BUS
+#define SYM_CONF_MAX_PQS_BUS 16
+#endif
+static int pqs_bus[SYM_CONF_MAX_PQS_BUS] __initdata = { 0 };
+
+static void __init sym_detect_pqs_pds(void)
+{
+ short index;
+ struct pci_dev *dev = NULL;
+
+ for(index=0; index < SYM_CONF_MAX_PQS_BUS; index++) {
+ u_char tmp;
+
+ dev = pci_find_device(0x101a, 0x0009, dev);
+ if (dev == NULL) {
+ pqs_bus[index] = -1;
+ break;
+ }
+ printf_info(NAME53C8XX ": NCR PQS/PDS memory controller detected on bus %d\n", dev->bus->number);
+ pci_read_config_byte(dev, 0x44, &tmp);
+ /* bit 1: allow individual 875 configuration */
+ tmp |= 0x2;
+ pci_write_config_byte(dev, 0x44, tmp);
+ pci_read_config_byte(dev, 0x45, &tmp);
+ /* bit 2: drive individual 875 interrupts to the bus */
+ tmp |= 0x4;
+ pci_write_config_byte(dev, 0x45, tmp);
+
+ pqs_bus[index] = dev->bus->number;
+ }
+}
+#endif
+
+static int pqs_probe()
+{
+}
+
+static void pqs_remove()
+{
+}
+
+static struct pci_device_id pqs_id_table[] __devinitdata = {
+ { 0x101a, 0x0009, },
+};
+
+MODULE_DEVICE_TABLE(pci, pqs_id_table);
+
+static struct pci_driver pqs_driver = {
+ .name = NAME53C8XX " (PQS)",
+ .id_table = pqs_id_table,
+ .probe = pqs_probe,
+ .remove = __devexit_p(pqs_remove),
+};
+#endif /* PQS */
+
+static int attach_count;
+
+static int __devinit sym2_probe(struct pci_dev *pdev,
+ const struct pci_device_id *ent)
+{
+ sym_device sym_dev;
+ sym_nvram nvram;
+
+ sym_dev.host_id = SYM_SETUP_HOST_ID;
+ if (sym53c8xx_pci_init(pdev, &sym_dev))
+ return -ENODEV;
+ printk(KERN_INFO "%s: 53c%s detected\n", sym_name(&sym_dev), sym_dev.chip.name);
+
+ sym_dev.nvram = &nvram;
+ nvram.type = 0;
+#if SYM_CONF_NVRAM_SUPPORT
+ sym_get_nvram(&sym_dev, &nvram);
#endif
+
+ if (sym_attach(&sym2_template, attach_count, &sym_dev))
+ return -ENODEV;
+
+ attach_count++;
+ return 0;
+}
+
+static void __devexit sym2_remove(struct pci_dev *pdev)
+{
+ sym_detach(pci_get_drvdata(pdev));
+ attach_count--;
+}
+
+static struct pci_device_id sym2_id_table[] __devinitdata = {
+ { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_NCR_53C810,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
+ { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_NCR_53C820,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, /* new */
+ { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_NCR_53C825,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
+ { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_NCR_53C815,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
+ { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_53C810AP,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, /* new */
+ { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_NCR_53C860,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
+ { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_53C1510,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
+ { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_NCR_53C896,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
+ { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_NCR_53C895,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
+ { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_NCR_53C885,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
+ { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_NCR_53C875,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
+ { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_NCR_53C1510,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, /* new */
+ { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_53C895A,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
+ { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_53C875A,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
+ { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_53C1010_33,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
+ { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_53C1010_66,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
+ { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_NCR_53C875J,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
};
-#include "../scsi_module.c"
+
+MODULE_DEVICE_TABLE(pci, sym2_id_table);
+
+static struct pci_driver sym2_driver = {
+ .name = NAME53C8XX,
+ .id_table = sym2_id_table,
+ .probe = sym2_probe,
+ .remove = __devexit_p(sym2_remove),
+};
+
+static int __init sym2_init(void)
+{
+#ifdef _SYM_CONF_PQS_PDS_SUPPORT
+ pci_register_driver(&pqs_driver);
+#endif
+ pci_register_driver(&sym2_driver);
+ return 0;
+}
+
+static void __exit sym2_exit(void)
+{
+ pci_unregister_driver(&sym2_driver);
+#ifdef _SYM_CONF_PQS_PDS_SUPPORT
+ pci_unregister_driver(&pqs_driver);
+#endif
+}
+
+module_init(sym2_init);
+module_exit(sym2_exit);
diff --git a/drivers/scsi/sym53c8xx_2/sym_glue.h b/drivers/scsi/sym53c8xx_2/sym_glue.h
index 10904a7e3188..5ee8c1b63f0f 100644
--- a/drivers/scsi/sym53c8xx_2/sym_glue.h
+++ b/drivers/scsi/sym53c8xx_2/sym_glue.h
@@ -57,20 +57,10 @@
#define SYM_CONF_DMA_ADDRESSING_MODE 2
#endif
-#define LinuxVersionCode(v, p, s) (((v)<<16)+((p)<<8)+(s))
-#include <linux/version.h>
-#if LINUX_VERSION_CODE < LinuxVersionCode(2, 2, 0)
-#error "This driver requires a kernel version not lower than 2.2.0"
-#endif
-
#include <asm/dma.h>
#include <asm/io.h>
#include <asm/system.h>
-#if LINUX_VERSION_CODE >= LinuxVersionCode(2,3,17)
#include <linux/spinlock.h>
-#else
-#include <asm/spinlock.h>
-#endif
#include <linux/delay.h>
#include <linux/signal.h>
#include <linux/sched.h>
@@ -91,29 +81,11 @@
#endif
#include <linux/init.h>
-#ifndef __init
-#define __init
-#endif
-#ifndef __initdata
-#define __initdata
-#endif
-
#include "../scsi.h"
#include "../hosts.h"
#include <linux/types.h>
-/*
- * Define BITS_PER_LONG for earlier linux versions.
- */
-#ifndef BITS_PER_LONG
-#if (~0UL) == 0xffffffffUL
-#define BITS_PER_LONG 32
-#else
-#define BITS_PER_LONG 64
-#endif
-#endif
-
typedef u_long vm_offset_t;
#ifndef bcopy
@@ -139,9 +111,7 @@ typedef u_long vm_offset_t;
/*
* Configuration addendum for Linux.
*/
-#if LINUX_VERSION_CODE >= LinuxVersionCode(2,3,47)
#define SYM_LINUX_DYNAMIC_DMA_MAPPING
-#endif
#define SYM_CONF_TIMER_INTERVAL ((HZ+1)/2)
@@ -472,9 +442,6 @@ struct sym_shcb {
u_long lasttime;
u_long settle_time; /* Resetting the SCSI BUS */
u_char settle_time_valid;
-#if LINUX_VERSION_CODE < LinuxVersionCode(2, 4, 0)
- u_char release_stage; /* Synchronisation on release */
-#endif
};
/*
@@ -647,9 +614,7 @@ static __inline void sym_set_cam_result_ok(hcb_p np, ccb_p cp, int resid)
{
Scsi_Cmnd *cmd = cp->cam_ccb;
-#if LINUX_VERSION_CODE >= LinuxVersionCode(2,3,99)
cmd->resid = resid;
-#endif
cmd->result = (((DID_OK) << 16) + ((cp->ssss_status) & 0x7f));
}
void sym_set_cam_result_error(hcb_p np, ccb_p cp, int resid);
diff --git a/drivers/usb/storage/usb.c b/drivers/usb/storage/usb.c
index ee67b5340adc..245fb97d923b 100644
--- a/drivers/usb/storage/usb.c
+++ b/drivers/usb/storage/usb.c
@@ -978,16 +978,9 @@ BadDevice:
static void storage_disconnect(struct usb_interface *intf)
{
struct us_data *us = usb_get_intfdata(intf);
- struct scsi_device *sdev;
US_DEBUGP("storage_disconnect() called\n");
- /* Set devices offline -- need host lock for this */
- scsi_lock(us->host);
- list_for_each_entry(sdev, &us->host->my_devices, siblings)
- sdev->online = 0;
- scsi_unlock(us->host);
-
/* Prevent new USB transfers and stop the current command */
set_bit(US_FLIDX_DISCONNECTING, &us->flags);
usb_stor_stop_transport(us);
@@ -995,12 +988,7 @@ static void storage_disconnect(struct usb_interface *intf)
/* Dissociate from the USB device */
dissociate_dev(us);
- /* Begin the SCSI host removal sequence */
- if (scsi_remove_host(us->host)) {
- US_DEBUGP("-- SCSI refused to remove the host\n");
- BUG();
- return;
- }
+ scsi_remove_host(us->host);
/* TODO: somehow, wait for the device to
* be 'idle' (tasklet completion) */
diff --git a/fs/Kconfig.binfmt b/fs/Kconfig.binfmt
index 13603b67d7d6..776116d958a9 100644
--- a/fs/Kconfig.binfmt
+++ b/fs/Kconfig.binfmt
@@ -111,6 +111,9 @@ config BINFMT_MISC
feature, and <file:Documentation/java.txt> for information about how
to include Java support.
+ To use binfmt_misc, you will need to mount it:
+ mount binfmt_misc -t binfmt_misc /proc/sys/fs/binfmt_misc
+
You may say M here for module support and later load the module when
you have use for it; the module is called binfmt_misc. If you
don't know what to answer at this point, say Y.
diff --git a/fs/aio.c b/fs/aio.c
index 1232d3ed8e5d..19b5acbbbcf9 100644
--- a/fs/aio.c
+++ b/fs/aio.c
@@ -639,13 +639,13 @@ int aio_complete(struct kiocb *iocb, long res, long res2)
iocb->ki_user_data = res;
if (iocb->ki_users == 1) {
iocb->ki_users = 0;
- return 1;
+ ret = 1;
+ } else {
+ spin_lock_irq(&ctx->ctx_lock);
+ iocb->ki_users--;
+ ret = (0 == iocb->ki_users);
+ spin_unlock_irq(&ctx->ctx_lock);
}
- spin_lock_irq(&ctx->ctx_lock);
- iocb->ki_users--;
- ret = (0 == iocb->ki_users);
- spin_unlock_irq(&ctx->ctx_lock);
-
/* sync iocbs put the task here for us */
wake_up_process(iocb->ki_user_obj);
return ret;
diff --git a/fs/befs/btree.c b/fs/befs/btree.c
index 5d93d273509b..e1a0256f586c 100644
--- a/fs/befs/btree.c
+++ b/fs/befs/btree.c
@@ -86,7 +86,7 @@ typedef struct {
} befs_btree_node;
/* local constants */
-static const befs_off_t befs_bt_inval = 0xffffffffffffffff;
+static const befs_off_t befs_bt_inval = 0xffffffffffffffffULL;
/* local functions */
static int befs_btree_seekleaf(struct super_block *sb, befs_data_stream * ds,
diff --git a/fs/nfs/nfs2xdr.c b/fs/nfs/nfs2xdr.c
index d0396689302e..1461252f66fe 100644
--- a/fs/nfs/nfs2xdr.c
+++ b/fs/nfs/nfs2xdr.c
@@ -90,7 +90,7 @@ xdr_encode_time(u32 *p, struct timespec *timep)
{
*p++ = htonl(timep->tv_sec);
/* Convert nanoseconds into microseconds */
- *p++ = htonl(timep->tv_nsec / 1000);
+ *p++ = htonl(timep->tv_nsec ? timep->tv_nsec / 1000 : 0);
return p;
}
diff --git a/fs/nfsd/nfs3xdr.c b/fs/nfsd/nfs3xdr.c
index 02798d4b8cd8..71ca4d0e2019 100644
--- a/fs/nfsd/nfs3xdr.c
+++ b/fs/nfsd/nfs3xdr.c
@@ -4,6 +4,8 @@
* XDR support for nfsd/protocol version 3.
*
* Copyright (C) 1995, 1996, 1997 Olaf Kirch <okir@monad.swb.de>
+ *
+ * 2003-08-09 Jamie Lokier: Use htonl() for nanoseconds, not htons()!
*/
#include <linux/types.h>
@@ -43,7 +45,7 @@ static u32 nfs3_ftypes[] = {
static inline u32 *
encode_time3(u32 *p, struct timespec *time)
{
- *p++ = htonl((u32) time->tv_sec); *p++ = htons(time->tv_nsec);
+ *p++ = htonl((u32) time->tv_sec); *p++ = htonl(time->tv_nsec);
return p;
}
diff --git a/fs/nfsd/nfsxdr.c b/fs/nfsd/nfsxdr.c
index f724778dc44c..aa6b481595ea 100644
--- a/fs/nfsd/nfsxdr.c
+++ b/fs/nfsd/nfsxdr.c
@@ -123,13 +123,13 @@ decode_sattr(u32 *p, struct iattr *iap)
if (tmp != (u32)-1 && tmp1 != (u32)-1) {
iap->ia_valid |= ATTR_ATIME | ATTR_ATIME_SET;
iap->ia_atime.tv_sec = tmp;
- iap->ia_atime.tv_nsec = tmp1;
+ iap->ia_atime.tv_nsec = tmp1 * 1000;
}
tmp = ntohl(*p++); tmp1 = ntohl(*p++);
if (tmp != (u32)-1 && tmp1 != (u32)-1) {
iap->ia_valid |= ATTR_MTIME | ATTR_MTIME_SET;
iap->ia_mtime.tv_sec = tmp;
- iap->ia_mtime.tv_nsec = tmp1;
+ iap->ia_mtime.tv_nsec = tmp1 * 1000;
}
return p;
}
@@ -171,12 +171,12 @@ encode_fattr(struct svc_rqst *rqstp, u32 *p, struct svc_fh *fhp)
*p++ = htonl((u32) stat.dev);
*p++ = htonl((u32) stat.ino);
*p++ = htonl((u32) stat.atime.tv_sec);
- *p++ = htons(stat.atime.tv_nsec);
+ *p++ = htonl(stat.atime.tv_nsec ? stat.atime.tv_nsec / 1000 : 0);
lease_get_mtime(dentry->d_inode, &time);
*p++ = htonl((u32) time.tv_sec);
- *p++ = htons(time.tv_nsec);
+ *p++ = htonl(time.tv_nsec ? time.tv_nsec / 1000 : 0);
*p++ = htonl((u32) stat.ctime.tv_sec);
- *p++ = htons(stat.ctime.tv_nsec);
+ *p++ = htonl(stat.ctime.tv_nsec ? stat.ctime.tv_nsec / 1000 : 0);
return p;
}
diff --git a/fs/partitions/efi.h b/fs/partitions/efi.h
index bc1f5befea5a..d0eff3120ac8 100644
--- a/fs/partitions/efi.h
+++ b/fs/partitions/efi.h
@@ -39,7 +39,7 @@
#define EFI_PMBR_OSTYPE_EFI_GPT 0xEE
#define GPT_BLOCK_SIZE 512
-#define GPT_HEADER_SIGNATURE 0x5452415020494645L
+#define GPT_HEADER_SIGNATURE 0x5452415020494645ULL
#define GPT_HEADER_REVISION_V1 0x00010000
#define GPT_PRIMARY_PARTITION_TABLE_LBA 1
diff --git a/fs/partitions/ldm.h b/fs/partitions/ldm.h
index e853af05c2df..14abedb995c6 100644
--- a/fs/partitions/ldm.h
+++ b/fs/partitions/ldm.h
@@ -38,8 +38,8 @@ struct parsed_partitions;
/* Magic numbers in CPU format. */
#define MAGIC_VMDB 0x564D4442 /* VMDB */
#define MAGIC_VBLK 0x56424C4B /* VBLK */
-#define MAGIC_PRIVHEAD 0x5052495648454144 /* PRIVHEAD */
-#define MAGIC_TOCBLOCK 0x544F43424C4F434B /* TOCBLOCK */
+#define MAGIC_PRIVHEAD 0x5052495648454144ULL /* PRIVHEAD */
+#define MAGIC_TOCBLOCK 0x544F43424C4F434BULL /* TOCBLOCK */
/* The defined vblk types. */
#define VBLK_VOL5 0x51 /* Volume, version 5 */
diff --git a/fs/reiserfs/hashes.c b/fs/reiserfs/hashes.c
index eee4084e9cbc..08d0508c2d39 100644
--- a/fs/reiserfs/hashes.c
+++ b/fs/reiserfs/hashes.c
@@ -90,10 +90,6 @@ u32 keyed_hash(const signed char *msg, int len)
if (len >= 12)
{
- //assert(len < 16);
- if (len >= 16)
- BUG();
-
a = (u32)msg[ 0] |
(u32)msg[ 1] << 8 |
(u32)msg[ 2] << 16|
@@ -116,9 +112,6 @@ u32 keyed_hash(const signed char *msg, int len)
}
else if (len >= 8)
{
- //assert(len < 12);
- if (len >= 12)
- BUG();
a = (u32)msg[ 0] |
(u32)msg[ 1] << 8 |
(u32)msg[ 2] << 16|
@@ -137,9 +130,6 @@ u32 keyed_hash(const signed char *msg, int len)
}
else if (len >= 4)
{
- //assert(len < 8);
- if (len >= 8)
- BUG();
a = (u32)msg[ 0] |
(u32)msg[ 1] << 8 |
(u32)msg[ 2] << 16|
@@ -154,9 +144,6 @@ u32 keyed_hash(const signed char *msg, int len)
}
else
{
- //assert(len < 4);
- if (len >= 4)
- BUG();
a = b = c = d = pad;
for(i = 0; i < len; i++)
{
diff --git a/include/asm-generic/tlb.h b/include/asm-generic/tlb.h
index 368f65b64360..f14d581fda8a 100644
--- a/include/asm-generic/tlb.h
+++ b/include/asm-generic/tlb.h
@@ -99,7 +99,7 @@ tlb_finish_mmu(struct mmu_gather *tlb, unsigned long start, unsigned long end)
}
-/* void tlb_remove_page(struct mmu_gather *tlb, pte_t *ptep, unsigned long addr)
+/* tlb_remove_page
* Must perform the equivalent to __free_pte(pte_get_and_clear(ptep)), while
* handling the additional races in SMP caused by other CPUs caching valid
* mappings in their TLBs.
diff --git a/include/asm-ppc/smp.h b/include/asm-ppc/smp.h
index 0f458a0f115e..baabf274f815 100644
--- a/include/asm-ppc/smp.h
+++ b/include/asm-ppc/smp.h
@@ -14,6 +14,7 @@
#include <linux/kernel.h>
#include <linux/bitops.h>
#include <linux/errno.h>
+#include <linux/threads.h>
#ifdef CONFIG_SMP
diff --git a/include/asm-x86_64/bitops.h b/include/asm-x86_64/bitops.h
index 493aa82d889c..92260e080c5a 100644
--- a/include/asm-x86_64/bitops.h
+++ b/include/asm-x86_64/bitops.h
@@ -402,12 +402,12 @@ static inline void set_bit_string(unsigned long *bitmap, unsigned long i,
}
}
-static inline void clear_bit_string(unsigned long *bitmap, unsigned long i,
+static inline void __clear_bit_string(unsigned long *bitmap, unsigned long i,
int len)
{
unsigned long end = i + len;
while (i < end) {
- clear_bit(i, bitmap);
+ __clear_bit(i, bitmap);
i++;
}
}
diff --git a/include/asm-x86_64/ia32_unistd.h b/include/asm-x86_64/ia32_unistd.h
index 45b50bf2679c..3d8256926d7c 100644
--- a/include/asm-x86_64/ia32_unistd.h
+++ b/include/asm-x86_64/ia32_unistd.h
@@ -264,7 +264,20 @@
#define __NR_ia32_sys_epoll_wait 256
#define __NR_ia32_remap_file_pages 257
#define __NR_ia32_set_tid_address 258
+#define __NR_ia32_timer_create 259
+#define __NR_ia32_timer_settime (__NR_ia32_timer_create+1)
+#define __NR_ia32_timer_gettime (__NR_ia32_timer_create+2)
+#define __NR_ia32_timer_getoverrun (__NR_ia32_timer_create+3)
+#define __NR_ia32_timer_delete (__NR_ia32_timer_create+4)
+#define __NR_ia32_clock_settime (__NR_ia32_timer_create+5)
+#define __NR_ia32_clock_gettime (__NR_ia32_timer_create+6)
+#define __NR_ia32_clock_getres (__NR_ia32_timer_create+7)
+#define __NR_ia32_clock_nanosleep (__NR_ia32_timer_create+8)
+#define __NR_ia32_statfs64 268
+#define __NR_ia32_fstatfs64 269
+#define __NR_ia32_tgkill 270
+#define __NR_ia32_utimes 271
-#define IA32_NR_syscalls 265 /* must be > than biggest syscall! */
+#define IA32_NR_syscalls 275 /* must be > than biggest syscall! */
#endif /* _ASM_X86_64_IA32_UNISTD_H_ */
diff --git a/include/asm-x86_64/io.h b/include/asm-x86_64/io.h
index b2cc4f1a241a..bf9738f9a23b 100644
--- a/include/asm-x86_64/io.h
+++ b/include/asm-x86_64/io.h
@@ -301,6 +301,12 @@ out:
#define flush_write_buffers()
+/* Disable vmerge for now. Need to fix the block layer code
+ to check for non iommu addresses first.
+ When the IOMMU is force it is safe to enable. */
+extern int force_iommu;
+#define BIO_VERMGE_BOUNDARY (force_iommu ? 4096 : 0)
+
#endif /* __KERNEL__ */
#endif
diff --git a/include/asm-x86_64/nmi.h b/include/asm-x86_64/nmi.h
index 66e9c5efc5e6..df002c539f58 100644
--- a/include/asm-x86_64/nmi.h
+++ b/include/asm-x86_64/nmi.h
@@ -48,6 +48,4 @@ static inline void unset_nmi_pm_callback(struct pm_dev * dev)
extern void default_do_nmi(struct pt_regs *);
-extern void default_do_nmi(struct pt_regs *);
-
#endif /* ASM_NMI_H */
diff --git a/include/asm-x86_64/pci-direct.h b/include/asm-x86_64/pci-direct.h
index 5d9e1bec7144..08a2b783889f 100644
--- a/include/asm-x86_64/pci-direct.h
+++ b/include/asm-x86_64/pci-direct.h
@@ -14,7 +14,26 @@ static inline u32 read_pci_config(u8 bus, u8 slot, u8 func, u8 offset)
u32 v;
outl(0x80000000 | (bus<<16) | (slot<<11) | (func<<8) | offset, 0xcf8);
v = inl(0xcfc);
- PDprintk("%x reading from %x: %x\n", slot, offset, v);
+ if (v != 0xffffffff)
+ PDprintk("%x reading 4 from %x: %x\n", slot, offset, v);
+ return v;
+}
+
+static inline u8 read_pci_config_byte(u8 bus, u8 slot, u8 func, u8 offset)
+{
+ u8 v;
+ outl(0x80000000 | (bus<<16) | (slot<<11) | (func<<8) | offset, 0xcf8);
+ v = inb(0xcfc + (offset&3));
+ PDprintk("%x reading 1 from %x: %x\n", slot, offset, v);
+ return v;
+}
+
+static inline u8 read_pci_config_16(u8 bus, u8 slot, u8 func, u8 offset)
+{
+ u16 v;
+ outl(0x80000000 | (bus<<16) | (slot<<11) | (func<<8) | offset, 0xcf8);
+ v = inw(0xcfc + (offset&2));
+ PDprintk("%x reading 2 from %x: %x\n", slot, offset, v);
return v;
}
diff --git a/include/asm-x86_64/pci.h b/include/asm-x86_64/pci.h
index 33550880dcbd..b072364de2bd 100644
--- a/include/asm-x86_64/pci.h
+++ b/include/asm-x86_64/pci.h
@@ -8,9 +8,6 @@
#include <linux/mm.h> /* for struct page */
-
-extern dma_addr_t bad_dma_address;
-
/* Can be used to override the logic in pci_scan_bus for skipping
already-configured bus numbers - to be used for buggy BIOSes
or architectures with incomplete PCI setup by the loader */
@@ -21,6 +18,8 @@ extern unsigned int pcibios_assign_all_busses(void);
#define pcibios_assign_all_busses() 0
#endif
+extern int no_iommu, force_iommu;
+
extern unsigned long pci_mem_start;
#define PCIBIOS_MIN_IO 0x1000
#define PCIBIOS_MIN_MEM (pci_mem_start)
@@ -46,6 +45,9 @@ struct pci_dev;
extern int iommu_setup(char *opt);
+extern dma_addr_t bad_dma_address;
+#define pci_dma_error(x) ((x) == bad_dma_address)
+
/* Allocate and map kernel buffer using consistent mode DMA for a device.
* hwdev should be valid struct pci_dev pointer for PCI devices,
* NULL for PCI-like buses (ISA, EISA).
@@ -119,10 +121,16 @@ static inline void pci_dma_sync_sg(struct pci_dev *hwdev,
/* The PCI address space does equal the physical memory
* address space. The networking and block device layers use
- * this boolean for bounce buffer decisions.
+ * this boolean for bounce buffer decisions
+ *
+ * On AMD64 it mostly equals, but we set it to zero to tell some subsystems
+ * that an IOMMU is available.
*/
-#define PCI_DMA_BUS_IS_PHYS (0)
+#define PCI_DMA_BUS_IS_PHYS (no_iommu ? 1 : 0)
+/* We lie slightly when the IOMMU is forced to get the device to
+ use SAC instead of DAC. */
+#define pci_dac_dma_supported(pci_dev, mask) (force_iommu ? 0 : 1)
#else
static inline dma_addr_t pci_map_single(struct pci_dev *hwdev, void *ptr,
@@ -206,6 +214,7 @@ static inline void pci_dma_sync_sg(struct pci_dev *hwdev,
#define PCI_DMA_BUS_IS_PHYS 1
+#define pci_dac_dma_supported(pci_dev, mask) 1
#endif
extern int pci_map_sg(struct pci_dev *hwdev, struct scatterlist *sg,
@@ -220,21 +229,7 @@ extern void pci_unmap_sg(struct pci_dev *hwdev, struct scatterlist *sg,
* only drive the low 24-bits during PCI bus mastering, then
* you would pass 0x00ffffff as the mask to this function.
*/
-static inline int pci_dma_supported(struct pci_dev *hwdev, u64 mask)
-{
- /*
- * we fall back to GFP_DMA when the mask isn't all 1s,
- * so we can't guarantee allocations that must be
- * within a tighter range than GFP_DMA..
- */
- if(mask < 0x00ffffff)
- return 0;
-
- return 1;
-}
-
-/* This is always fine. */
-#define pci_dac_dma_supported(pci_dev, mask) (1)
+extern int pci_dma_supported(struct pci_dev *hwdev, u64 mask);
static __inline__ dma64_addr_t
pci_dac_page_to_dma(struct pci_dev *pdev, struct page *page, unsigned long offset, int direction)
diff --git a/include/asm-x86_64/percpu.h b/include/asm-x86_64/percpu.h
index 578c6b12cf2b..832fc326fb02 100644
--- a/include/asm-x86_64/percpu.h
+++ b/include/asm-x86_64/percpu.h
@@ -1,53 +1,51 @@
#ifndef _ASM_X8664_PERCPU_H_
#define _ASM_X8664_PERCPU_H_
+#include <linux/compiler.h>
-#include <asm/pda.h>
+/* Same as asm-generic/percpu.h, except that we store the per cpu offset
+ in the PDA. Longer term the PDA and every per cpu variable
+ should be just put into a single section and referenced directly
+ from %gs */
#ifdef CONFIG_SMP
-/* Same as the generic code except that we cache the per cpu offset
- in the pda. This gives an 3 instruction reference for per cpu data */
-
-#include <linux/compiler.h>
#include <asm/pda.h>
-#define __my_cpu_offset() read_pda(data_offset)
+
#define __per_cpu_offset(cpu) (cpu_pda[cpu].data_offset)
+#define __my_cpu_offset() read_pda(data_offset)
/* Separate out the type, so (int[3], foo) works. */
#define DEFINE_PER_CPU(type, name) \
- __attribute__((__section__(".data.percpu"))) __typeof__(type) name##__per_cpu
+ __attribute__((__section__(".data.percpu"))) __typeof__(type) per_cpu__##name
/* var is in discarded region: offset to particular copy we want */
-#define per_cpu(var, cpu) (*RELOC_HIDE(&var##__per_cpu, __per_cpu_offset(cpu)))
-#define __get_cpu_var(var) \
- (*RELOC_HIDE(&var##__per_cpu, __my_cpu_offset()))
-
-static inline void percpu_modcopy(void *pcpudst, const void *src,
- unsigned long size)
-{
- unsigned int i;
- for (i = 0; i < NR_CPUS; i++)
- if (cpu_possible(i))
- memcpy(pcpudst + __per_cpu_offset(i), src, size);
-}
-
-extern void setup_per_cpu_areas(void);
-
+#define per_cpu(var, cpu) (*RELOC_HIDE(&per_cpu__##var, __per_cpu_offset(cpu)))
+#define __get_cpu_var(var) (*RELOC_HIDE(&per_cpu__##var, __my_cpu_offset()))
+
+/* A macro to avoid #include hell... */
+#define percpu_modcopy(pcpudst, src, size) \
+do { \
+ unsigned int __i; \
+ for (__i = 0; __i < NR_CPUS; __i++) \
+ if (cpu_possible(__i)) \
+ memcpy((pcpudst)+__per_cpu_offset(__i), \
+ (src), (size)); \
+} while (0)
#else /* ! SMP */
#define DEFINE_PER_CPU(type, name) \
- __typeof__(type) name##__per_cpu
+ __typeof__(type) per_cpu__##name
-#define per_cpu(var, cpu) ((void)cpu, var##__per_cpu)
-#define __get_cpu_var(var) var##__per_cpu
+#define per_cpu(var, cpu) ((void)cpu, per_cpu__##var)
+#define __get_cpu_var(var) per_cpu__##var
#endif /* SMP */
-#define DECLARE_PER_CPU(type, name) extern __typeof__(type) name##__per_cpu
+#define DECLARE_PER_CPU(type, name) extern __typeof__(type) per_cpu__##name
-#define EXPORT_PER_CPU_SYMBOL(var) EXPORT_SYMBOL(var##__per_cpu)
-#define EXPORT_PER_CPU_SYMBOL_GPL(var) EXPORT_SYMBOL_GPL(var##__per_cpu)
+#define EXPORT_PER_CPU_SYMBOL(var) EXPORT_SYMBOL(per_cpu__##var)
+#define EXPORT_PER_CPU_SYMBOL_GPL(var) EXPORT_SYMBOL_GPL(per_cpu__##var)
-DECLARE_PER_CPU(struct x8664_pda, per_cpu_pda);
+extern void setup_per_cpu_areas(void);
-#endif
+#endif /* _ASM_X8664_PERCPU_H_ */
diff --git a/include/asm-x86_64/proto.h b/include/asm-x86_64/proto.h
index ed86ba7abf06..5e176402f5c1 100644
--- a/include/asm-x86_64/proto.h
+++ b/include/asm-x86_64/proto.h
@@ -77,7 +77,7 @@ extern unsigned long end_pfn;
extern unsigned long table_start, table_end;
extern int exception_trace;
-extern int no_iommu, force_mmu;
+extern int force_iommu, no_iommu;
extern int using_apic_timer;
extern int disable_apic;
extern unsigned cpu_khz;
diff --git a/include/asm-x86_64/siginfo.h b/include/asm-x86_64/siginfo.h
index dcb6b5731012..d09a1e6e7246 100644
--- a/include/asm-x86_64/siginfo.h
+++ b/include/asm-x86_64/siginfo.h
@@ -1,6 +1,8 @@
#ifndef _X8664_SIGINFO_H
#define _X8664_SIGINFO_H
+#define __ARCH_SI_PREAMBLE_SIZE (4 * sizeof(int))
+
#include <asm-generic/siginfo.h>
#endif
diff --git a/include/asm-x86_64/unistd.h b/include/asm-x86_64/unistd.h
index 027d47e870ff..ac85fa9cd769 100644
--- a/include/asm-x86_64/unistd.h
+++ b/include/asm-x86_64/unistd.h
@@ -461,7 +461,7 @@ __SYSCALL(__NR_fremovexattr, sys_fremovexattr)
#define __NR_tkill 200
__SYSCALL(__NR_tkill, sys_tkill)
#define __NR_time 201
-__SYSCALL(__NR_time, sys_time)
+__SYSCALL(__NR_time, sys_time64)
#define __NR_futex 202
__SYSCALL(__NR_futex, sys_futex)
#define __NR_sched_setaffinity 203
diff --git a/include/linux/if_tun.h b/include/linux/if_tun.h
index f8459e01c896..ad1e168004ee 100644
--- a/include/linux/if_tun.h
+++ b/include/linux/if_tun.h
@@ -32,7 +32,7 @@
#endif
struct tun_struct {
- char *name;
+ struct list_head list;
unsigned long flags;
int attached;
uid_t owner;
diff --git a/include/linux/ipv6.h b/include/linux/ipv6.h
index 49207c629e4f..e4f91218676d 100644
--- a/include/linux/ipv6.h
+++ b/include/linux/ipv6.h
@@ -71,7 +71,7 @@ struct rt0_hdr {
__u32 bitmap; /* strict/loose bit map */
struct in6_addr addr[0];
-#define rt0_type rt_hdr.type;
+#define rt0_type rt_hdr.type
};
struct ipv6_auth_hdr {
diff --git a/include/linux/ppp-comp.h b/include/linux/ppp-comp.h
index 82dd01c38920..7227e653b3be 100644
--- a/include/linux/ppp-comp.h
+++ b/include/linux/ppp-comp.h
@@ -185,10 +185,9 @@ struct compressor {
#define DEFLATE_MIN_SIZE 9
#define DEFLATE_MAX_SIZE 15
#define DEFLATE_METHOD_VAL 8
-#define DEFLATE_SIZE(x) (((x) >> 4) + DEFLATE_MIN_SIZE)
+#define DEFLATE_SIZE(x) (((x) >> 4) + 8)
#define DEFLATE_METHOD(x) ((x) & 0x0F)
-#define DEFLATE_MAKE_OPT(w) ((((w) - DEFLATE_MIN_SIZE) << 4) \
- + DEFLATE_METHOD_VAL)
+#define DEFLATE_MAKE_OPT(w) ((((w) - 8) << 4) + DEFLATE_METHOD_VAL)
#define DEFLATE_CHK_SEQUENCE 0
/*
diff --git a/include/linux/xfrm.h b/include/linux/xfrm.h
index a4dd169d9f6f..430370b12d13 100644
--- a/include/linux/xfrm.h
+++ b/include/linux/xfrm.h
@@ -37,6 +37,7 @@ struct xfrm_selector
__u16 dport_mask;
__u16 sport;
__u16 sport_mask;
+ __u16 family;
__u8 prefixlen_d;
__u8 prefixlen_s;
__u8 proto;
@@ -125,6 +126,7 @@ enum
struct xfrm_user_tmpl {
struct xfrm_id id;
+ __u16 family;
xfrm_address_t saddr;
__u32 reqid;
__u8 mode;
@@ -189,7 +191,6 @@ struct xfrm_userpolicy_info {
struct xfrm_lifetime_cur curlft;
__u32 priority;
__u32 index;
- __u16 family;
__u8 dir;
__u8 action;
#define XFRM_POLICY_ALLOW 0
diff --git a/include/net/dst.h b/include/net/dst.h
index 8282f41ec600..42dd8f511cef 100644
--- a/include/net/dst.h
+++ b/include/net/dst.h
@@ -247,8 +247,16 @@ static inline int dst_input(struct sk_buff *skb)
extern void dst_init(void);
struct flowi;
+#ifndef CONFIG_XFRM
+static inline int xfrm_lookup(struct dst_entry **dst_p, struct flowi *fl,
+ struct sock *sk, int flags)
+{
+ return 0;
+}
+#else
extern int xfrm_lookup(struct dst_entry **dst_p, struct flowi *fl,
struct sock *sk, int flags);
#endif
+#endif
#endif /* _NET_DST_H */
diff --git a/include/net/ipv6.h b/include/net/ipv6.h
index 8aeb974d8592..9ed62a7db079 100644
--- a/include/net/ipv6.h
+++ b/include/net/ipv6.h
@@ -353,9 +353,7 @@ extern int ip6_push_pending_frames(struct sock *sk);
extern void ip6_flush_pending_frames(struct sock *sk);
-extern int ip6_dst_lookup(struct sock *sk,
- struct dst_entry **dst,
- struct flowi *fl);
+extern struct dst_entry * ip6_dst_lookup(struct sock *sk, struct flowi *fl);
/*
* skb processing functions
diff --git a/include/net/xfrm.h b/include/net/xfrm.h
index 337061ce242e..bca38f50f681 100644
--- a/include/net/xfrm.h
+++ b/include/net/xfrm.h
@@ -588,6 +588,8 @@ xfrm_state_addr_cmp(struct xfrm_tmpl *tmpl, struct xfrm_state *x, unsigned short
return !0;
}
+#ifdef CONFIG_XFRM
+
extern int __xfrm_policy_check(struct sock *, int dir, struct sk_buff *skb, unsigned short family);
static inline int xfrm_policy_check(struct sock *sk, int dir, struct sk_buff *skb, unsigned short family)
@@ -653,6 +655,26 @@ static inline void xfrm_sk_free_policy(struct sock *sk)
}
}
+#else
+
+static inline void xfrm_sk_free_policy(struct sock *sk) {}
+static inline int xfrm_sk_clone_policy(struct sock *sk) { return 0; }
+static inline int xfrm6_route_forward(struct sk_buff *skb) { return 1; }
+static inline int xfrm4_route_forward(struct sk_buff *skb) { return 1; }
+static inline int xfrm6_policy_check(struct sock *sk, int dir, struct sk_buff *skb)
+{
+ return 1;
+}
+static inline int xfrm4_policy_check(struct sock *sk, int dir, struct sk_buff *skb)
+{
+ return 1;
+}
+static inline int xfrm_policy_check(struct sock *sk, int dir, struct sk_buff *skb, unsigned short family)
+{
+ return 1;
+}
+#endif
+
static __inline__
xfrm_address_t *xfrm_flowi_daddr(struct flowi *fl, unsigned short family)
{
@@ -783,12 +805,32 @@ extern void xfrm_replay_advance(struct xfrm_state *x, u32 seq);
extern int xfrm_check_selectors(struct xfrm_state **x, int n, struct flowi *fl);
extern int xfrm_check_output(struct xfrm_state *x, struct sk_buff *skb, unsigned short family);
extern int xfrm4_rcv(struct sk_buff *skb);
-extern int xfrm4_rcv_encap(struct sk_buff *skb, __u16 encap_type);
extern int xfrm4_tunnel_register(struct xfrm_tunnel *handler);
extern int xfrm4_tunnel_deregister(struct xfrm_tunnel *handler);
extern int xfrm4_tunnel_check_size(struct sk_buff *skb);
extern int xfrm6_rcv(struct sk_buff **pskb, unsigned int *nhoffp);
+
+#ifdef CONFIG_XFRM
+extern int xfrm4_rcv_encap(struct sk_buff *skb, __u16 encap_type);
extern int xfrm_user_policy(struct sock *sk, int optname, u8 *optval, int optlen);
+extern int xfrm_dst_lookup(struct xfrm_dst **dst, struct flowi *fl, unsigned short family);
+#else
+static inline int xfrm_user_policy(struct sock *sk, int optname, u8 *optval, int optlen)
+{
+ return -ENOPROTOOPT;
+}
+
+static inline int xfrm4_rcv_encap(struct sk_buff *skb, __u16 encap_type)
+{
+ /* should not happen */
+ kfree_skb(skb);
+ return 0;
+}
+static inline int xfrm_dst_lookup(struct xfrm_dst **dst, struct flowi *fl, unsigned short family)
+{
+ return -EINVAL;
+}
+#endif
void xfrm_policy_init(void);
void xfrm4_policy_init(void);
@@ -810,7 +852,6 @@ extern void xfrm_policy_kill(struct xfrm_policy *);
extern int xfrm_sk_policy_insert(struct sock *sk, int dir, struct xfrm_policy *pol);
extern struct xfrm_policy *xfrm_sk_policy_lookup(struct sock *sk, int dir, struct flowi *fl);
extern int xfrm_flush_bundles(struct xfrm_state *x);
-extern int xfrm_dst_lookup(struct xfrm_dst **dst, struct flowi *fl, unsigned short family);
extern wait_queue_head_t km_waitq;
extern void km_state_expired(struct xfrm_state *x, int hard);
diff --git a/include/scsi/scsi_device.h b/include/scsi/scsi_device.h
index de5ff9fd6c4a..04b8f47837a9 100644
--- a/include/scsi/scsi_device.h
+++ b/include/scsi/scsi_device.h
@@ -10,6 +10,16 @@ struct scsi_cmnd;
struct scsi_mode_data;
+/*
+ * sdev state
+ */
+enum {
+ SDEV_ADD,
+ SDEV_DEL,
+ SDEV_CANCEL,
+ SDEV_RECOVERY,
+};
+
struct scsi_device {
struct list_head siblings; /* list of all devices on this host */
struct list_head same_target_siblings; /* just the devices sharing same target id */
@@ -86,14 +96,19 @@ struct scsi_device {
struct device sdev_gendev;
struct class_device sdev_classdev;
+
+ unsigned long sdev_state;
};
#define to_scsi_device(d) \
container_of(d, struct scsi_device, sdev_gendev)
+#define class_to_sdev(d) \
+ container_of(d, struct scsi_device, sdev_classdev)
extern struct scsi_device *scsi_add_device(struct Scsi_Host *,
uint, uint, uint);
-extern int scsi_remove_device(struct scsi_device *);
-extern void scsi_set_device_offline(struct scsi_device *);
+extern void scsi_remove_device(struct scsi_device *);
+extern int scsi_device_cancel_cb(struct device *, void *);
+extern int scsi_device_cancel(struct scsi_device *, int);
extern int scsi_device_get(struct scsi_device *);
extern void scsi_device_put(struct scsi_device *);
@@ -106,5 +121,4 @@ extern int scsi_set_medium_removal(struct scsi_device *, char);
extern int scsi_mode_sense(struct scsi_device *sdev, int dbd, int modepage,
unsigned char *buffer, int len, int timeout,
int retries, struct scsi_mode_data *data);
-
#endif /* _SCSI_SCSI_DEVICE_H */
diff --git a/include/scsi/scsi_host.h b/include/scsi/scsi_host.h
index 3ef701078fef..7a2ccdf81e55 100644
--- a/include/scsi/scsi_host.h
+++ b/include/scsi/scsi_host.h
@@ -262,6 +262,12 @@ struct scsi_host_template {
unsigned short max_sectors;
/*
+ * dma scatter gather segment boundary limit. a segment crossing this
+ * boundary will be split in two.
+ */
+ unsigned long dma_boundary;
+
+ /*
* This specifies "machine infinity" for host templates which don't
* limit the transfer size. Note this limit represents an absolute
* maximum, and may be over the transfer limits allowed for
@@ -306,8 +312,6 @@ struct scsi_host_template {
*/
unsigned emulated:1;
- unsigned highmem_io:1;
-
/*
* True if the driver wishes to use the generic block layer
* tag queueing functions
@@ -348,6 +352,16 @@ struct scsi_host_template {
struct list_head legacy_hosts;
};
+/*
+ * shost states
+ */
+enum {
+ SHOST_ADD,
+ SHOST_DEL,
+ SHOST_CANCEL,
+ SHOST_RECOVERY,
+};
+
struct Scsi_Host {
struct list_head my_devices;
struct scsi_host_cmd_pool *cmd_pool;
@@ -412,8 +426,8 @@ struct Scsi_Host {
short cmd_per_lun;
short unsigned int sg_tablesize;
short unsigned int max_sectors;
+ unsigned long dma_boundary;
- unsigned in_recovery:1;
unsigned unchecked_isa_dma:1;
unsigned use_clustering:1;
unsigned highmem_io:1;
@@ -448,6 +462,9 @@ struct Scsi_Host {
unsigned char n_io_port;
unsigned char dma_channel;
unsigned int irq;
+
+
+ unsigned long shost_state;
/* ldm bits */
struct device shost_gendev;
@@ -478,8 +495,8 @@ struct Scsi_Host {
extern struct Scsi_Host *scsi_host_alloc(struct scsi_host_template *, int);
extern int scsi_add_host(struct Scsi_Host *, struct device *);
extern void scsi_scan_host(struct Scsi_Host *);
-extern int scsi_remove_host(struct Scsi_Host *);
-extern void scsi_host_get(struct Scsi_Host *);
+extern void scsi_remove_host(struct Scsi_Host *);
+extern struct Scsi_Host *scsi_host_get(struct Scsi_Host *);
extern void scsi_host_put(struct Scsi_Host *t);
extern struct Scsi_Host *scsi_host_lookup(unsigned short);
diff --git a/ipc/sem.c b/ipc/sem.c
index d1a54864f753..b0d886377bb7 100644
--- a/ipc/sem.c
+++ b/ipc/sem.c
@@ -425,7 +425,7 @@ static void freeary (struct sem_array *sma, int id)
ipc_rcu_free(sma, size);
}
-static unsigned long copy_semid_to_user(void *buf, struct semid64_ds *in, int version)
+static unsigned long copy_semid_to_user(void __user *buf, struct semid64_ds *in, int version)
{
switch(version) {
case IPC_64:
@@ -686,7 +686,7 @@ struct sem_setbuf {
mode_t mode;
};
-static inline unsigned long copy_semid_from_user(struct sem_setbuf *out, void *buf, int version)
+static inline unsigned long copy_semid_from_user(struct sem_setbuf *out, void __user *buf, int version)
{
switch(version) {
case IPC_64:
@@ -960,13 +960,13 @@ out:
return un;
}
-asmlinkage long sys_semop (int semid, struct sembuf *tsops, unsigned nsops)
+asmlinkage long sys_semop (int semid, struct sembuf __user *tsops, unsigned nsops)
{
return sys_semtimedop(semid, tsops, nsops, NULL);
}
-asmlinkage long sys_semtimedop(int semid, struct sembuf *tsops,
- unsigned nsops, const struct timespec *timeout)
+asmlinkage long sys_semtimedop(int semid, struct sembuf __user *tsops,
+ unsigned nsops, const struct timespec __user *timeout)
{
int error = -EINVAL;
struct sem_array *sma;
diff --git a/kernel/signal.c b/kernel/signal.c
index bab76d941a3d..cd83653ef5d2 100644
--- a/kernel/signal.c
+++ b/kernel/signal.c
@@ -1011,9 +1011,11 @@ void zap_other_threads(struct task_struct *p)
* killed as part of a thread group due to another
* thread doing an execve() or similar. So set the
* exit signal to -1 to allow immediate reaping of
- * the process.
+ * the process. But don't detach the thread group
+ * leader.
*/
- t->exit_signal = -1;
+ if (t != p->group_leader)
+ t->exit_signal = -1;
sigaddset(&t->pending.signal, SIGKILL);
rm_from_queue(SIG_KERNEL_STOP_MASK, &t->pending);
diff --git a/mm/page-writeback.c b/mm/page-writeback.c
index 1bdfbac68637..80047ad9a25e 100644
--- a/mm/page-writeback.c
+++ b/mm/page-writeback.c
@@ -345,7 +345,7 @@ static void wb_kupdate(unsigned long arg)
* sysctl handler for /proc/sys/vm/dirty_writeback_centisecs
*/
int dirty_writeback_centisecs_handler(ctl_table *table, int write,
- struct file *file, void *buffer, size_t *length)
+ struct file *file, void __user *buffer, size_t *length)
{
proc_dointvec(table, write, file, buffer, length);
if (dirty_writeback_centisecs) {
diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index 0ada7181364f..4d2d3ce1d430 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -1610,7 +1610,7 @@ void setup_per_zone_pages_min(void)
* changes.
*/
int min_free_kbytes_sysctl_handler(ctl_table *table, int write,
- struct file *file, void *buffer, size_t *length)
+ struct file *file, void __user *buffer, size_t *length)
{
proc_dointvec(table, write, file, buffer, length);
setup_per_zone_pages_min();
diff --git a/net/Kconfig b/net/Kconfig
index 7b68450d1252..e2aa43ed5c15 100644
--- a/net/Kconfig
+++ b/net/Kconfig
@@ -83,6 +83,7 @@ config UNIX
config NET_KEY
tristate "PF_KEY sockets"
+ select XFRM
---help---
PF_KEYv2 socket family, compatible to KAME ones.
They are required if you are going to use IPsec tools ported
diff --git a/net/core/skbuff.c b/net/core/skbuff.c
index ef7095747c88..fceff2112058 100644
--- a/net/core/skbuff.c
+++ b/net/core/skbuff.c
@@ -225,7 +225,7 @@ void __kfree_skb(struct sk_buff *skb)
}
dst_release(skb->dst);
-#ifdef CONFIG_INET
+#ifdef CONFIG_XFRM
secpath_put(skb->sp);
#endif
if(skb->destructor) {
diff --git a/net/ipv4/Kconfig b/net/ipv4/Kconfig
index 22e98d25d467..cd82363b5897 100644
--- a/net/ipv4/Kconfig
+++ b/net/ipv4/Kconfig
@@ -187,6 +187,7 @@ config IP_PNP_RARP
config NET_IPIP
tristate "IP: tunneling"
depends on INET
+ select XFRM
---help---
Tunneling means encapsulating data of one protocol type within
another protocol and sending it over a channel that understands the
@@ -205,6 +206,7 @@ config NET_IPIP
config NET_IPGRE
tristate "IP: GRE tunnels over IP"
depends on INET
+ select XFRM
help
Tunneling means encapsulating data of one protocol type within
another protocol and sending it over a channel that understands the
@@ -343,6 +345,7 @@ config SYN_COOKIES
config INET_AH
tristate "IP: AH transformation"
+ select XFRM
select CRYPTO
select CRYPTO_HMAC
select CRYPTO_MD5
@@ -354,6 +357,7 @@ config INET_AH
config INET_ESP
tristate "IP: ESP transformation"
+ select XFRM
select CRYPTO
select CRYPTO_HMAC
select CRYPTO_MD5
@@ -366,6 +370,7 @@ config INET_ESP
config INET_IPCOMP
tristate "IP: IPComp transformation"
+ select XFRM
select CRYPTO
select CRYPTO_DEFLATE
---help---
diff --git a/net/ipv4/Makefile b/net/ipv4/Makefile
index 99c8f308bb60..5412b1caa989 100644
--- a/net/ipv4/Makefile
+++ b/net/ipv4/Makefile
@@ -23,4 +23,4 @@ obj-$(CONFIG_IP_PNP) += ipconfig.o
obj-$(CONFIG_NETFILTER) += netfilter/
obj-$(CONFIG_IP_VS) += ipvs/
-obj-y += xfrm4_policy.o xfrm4_state.o xfrm4_input.o xfrm4_tunnel.o
+obj-$(CONFIG_XFRM) += xfrm4_policy.o xfrm4_state.o xfrm4_input.o xfrm4_tunnel.o
diff --git a/net/ipv4/ipcomp.c b/net/ipv4/ipcomp.c
index 5ebb565c77d9..a713530ae557 100644
--- a/net/ipv4/ipcomp.c
+++ b/net/ipv4/ipcomp.c
@@ -279,6 +279,7 @@ static struct xfrm_state *ipcomp_tunnel_create(struct xfrm_state *x)
t->props.family = AF_INET;
t->props.mode = 1;
t->props.saddr.a4 = x->props.saddr.a4;
+ t->props.flags = x->props.flags;
t->type = xfrm_get_type(IPPROTO_IPIP, t->props.family);
if (t->type == NULL)
diff --git a/net/ipv4/ipvs/Kconfig b/net/ipv4/ipvs/Kconfig
index 33f519fc26da..49189f15a4d4 100644
--- a/net/ipv4/ipvs/Kconfig
+++ b/net/ipv4/ipvs/Kconfig
@@ -241,7 +241,7 @@ comment 'IPVS application helper'
config IP_VS_FTP
tristate "FTP protocol helper"
- depends on IP_VS
+ depends on IP_VS && IP_VS_PROTO_TCP
---help---
FTP is a protocol that transfers IP address and/or port number in
the payload. In the virtual server via Network Address Translation,
diff --git a/net/ipv4/ipvs/ip_vs_core.c b/net/ipv4/ipvs/ip_vs_core.c
index 5695301dc253..f08b55144cb4 100644
--- a/net/ipv4/ipvs/ip_vs_core.c
+++ b/net/ipv4/ipvs/ip_vs_core.c
@@ -53,7 +53,9 @@ EXPORT_SYMBOL(ip_vs_proto_name);
EXPORT_SYMBOL(ip_vs_conn_new);
EXPORT_SYMBOL(ip_vs_conn_in_get);
EXPORT_SYMBOL(ip_vs_conn_out_get);
+#ifdef CONFIG_IP_VS_PROTO_TCP
EXPORT_SYMBOL(ip_vs_tcp_conn_listen);
+#endif
EXPORT_SYMBOL(ip_vs_conn_put);
#ifdef CONFIG_IP_VS_DEBUG
EXPORT_SYMBOL(ip_vs_get_debug_level);
diff --git a/net/ipv4/route.c b/net/ipv4/route.c
index f54290251fc8..e60f43256f7a 100644
--- a/net/ipv4/route.c
+++ b/net/ipv4/route.c
@@ -2785,8 +2785,10 @@ int __init ip_rt_init(void)
create_proc_read_entry("net/rt_acct", 0, 0, ip_rt_acct_read, NULL);
#endif
#endif
+#ifdef CONFIG_XFRM
xfrm_init();
xfrm4_init();
+#endif
out:
return rc;
out_enomem:
diff --git a/net/ipv4/sysctl_net_ipv4.c b/net/ipv4/sysctl_net_ipv4.c
index fbd17044ec5b..a4c77ae53c21 100644
--- a/net/ipv4/sysctl_net_ipv4.c
+++ b/net/ipv4/sysctl_net_ipv4.c
@@ -109,6 +109,7 @@ static int ipv4_sysctl_forward_strategy(ctl_table *table, int *name, int nlen,
}
}
+ *valp = new;
inet_forward_change();
return 1;
}
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
index 6049b4853a65..08c3a40a4bd2 100644
--- a/net/ipv4/udp.c
+++ b/net/ipv4/udp.c
@@ -938,6 +938,9 @@ static void udp_close(struct sock *sk, long timeout)
*/
static int udp_encap_rcv(struct sock * sk, struct sk_buff *skb)
{
+#ifndef CONFIG_XFRM
+ return 1;
+#else
struct udp_opt *up = udp_sk(sk);
struct udphdr *uh = skb->h.uh;
struct iphdr *iph;
@@ -997,10 +1000,12 @@ static int udp_encap_rcv(struct sock * sk, struct sk_buff *skb)
return -1;
default:
- printk(KERN_INFO "udp_encap_rcv(): Unhandled UDP encap type: %u\n",
- encap_type);
+ if (net_ratelimit())
+ printk(KERN_INFO "udp_encap_rcv(): Unhandled UDP encap type: %u\n",
+ encap_type);
return 1;
}
+#endif
}
/* returns:
diff --git a/net/ipv4/xfrm4_input.c b/net/ipv4/xfrm4_input.c
index 2412f9398682..9040408dbf81 100644
--- a/net/ipv4/xfrm4_input.c
+++ b/net/ipv4/xfrm4_input.c
@@ -27,6 +27,20 @@ static inline void ipip_ecn_decapsulate(struct iphdr *outer_iph, struct sk_buff
IP_ECN_set_ce(inner_iph);
}
+static int xfrm4_parse_spi(struct sk_buff *skb, u8 nexthdr, u32 *spi, u32 *seq)
+{
+ switch (nexthdr) {
+ case IPPROTO_IPIP:
+ if (!pskb_may_pull(skb, sizeof(struct iphdr)))
+ return -EINVAL;
+ *spi = skb->nh.iph->saddr;
+ *seq = 0;
+ return 0;
+ }
+
+ return xfrm_parse_spi(skb, nexthdr, spi, seq);
+}
+
int xfrm4_rcv_encap(struct sk_buff *skb, __u16 encap_type)
{
int err;
@@ -36,7 +50,7 @@ int xfrm4_rcv_encap(struct sk_buff *skb, __u16 encap_type)
int xfrm_nr = 0;
int decaps = 0;
- if ((err = xfrm_parse_spi(skb, skb->nh.iph->protocol, &spi, &seq)) != 0)
+ if ((err = xfrm4_parse_spi(skb, skb->nh.iph->protocol, &spi, &seq)) != 0)
goto drop;
do {
diff --git a/net/ipv4/xfrm4_tunnel.c b/net/ipv4/xfrm4_tunnel.c
index 1d0d2417893b..c4389b6f8d29 100644
--- a/net/ipv4/xfrm4_tunnel.c
+++ b/net/ipv4/xfrm4_tunnel.c
@@ -83,31 +83,8 @@ error_nolock:
return err;
}
-static inline void ipip_ecn_decapsulate(struct iphdr *outer_iph, struct sk_buff *skb)
-{
- struct iphdr *inner_iph = skb->nh.iph;
-
- if (INET_ECN_is_ce(outer_iph->tos) &&
- INET_ECN_is_not_ce(inner_iph->tos))
- IP_ECN_set_ce(inner_iph);
-}
-
static int ipip_xfrm_rcv(struct xfrm_state *x, struct xfrm_decap_state *decap, struct sk_buff *skb)
{
- struct iphdr *outer_iph = skb->nh.iph;
-
- if (!pskb_may_pull(skb, sizeof(struct iphdr)))
- return -EINVAL;
- skb->mac.raw = skb->nh.raw;
- skb->nh.raw = skb->data;
- memset(&(IPCB(skb)->opt), 0, sizeof(struct ip_options));
- dst_release(skb->dst);
- skb->dst = NULL;
- skb->protocol = htons(ETH_P_IP);
- skb->pkt_type = PACKET_HOST;
- ipip_ecn_decapsulate(outer_iph, skb);
- netif_rx(skb);
-
return 0;
}
@@ -149,46 +126,12 @@ int xfrm4_tunnel_deregister(struct xfrm_tunnel *handler)
static int ipip_rcv(struct sk_buff *skb)
{
struct xfrm_tunnel *handler = ipip_handler;
- struct xfrm_state *x = NULL;
- int err;
/* Tunnel devices take precedence. */
- if (handler) {
- err = handler->handler(skb);
- if (!err)
- goto out;
- }
+ if (handler && handler->handler(skb) == 0)
+ return 0;
- x = xfrm_state_lookup((xfrm_address_t *)&skb->nh.iph->daddr,
- skb->nh.iph->saddr,
- IPPROTO_IPIP, AF_INET);
-
- if (!x)
- goto drop;
-
- spin_lock(&x->lock);
-
- if (unlikely(x->km.state != XFRM_STATE_VALID))
- goto drop_unlock;
-
- err = ipip_xfrm_rcv(x, NULL, skb);
- if (err)
- goto drop_unlock;
-
- x->curlft.bytes += skb->len;
- x->curlft.packets++;
- spin_unlock(&x->lock);
- xfrm_state_put(x);
-out:
- return err;
-
-drop_unlock:
- spin_unlock(&x->lock);
- xfrm_state_put(x);
-drop:
- err = NET_RX_DROP;
- kfree_skb(skb);
- goto out;
+ return xfrm4_rcv_encap(skb, 0);
}
static void ipip_err(struct sk_buff *skb, u32 info)
diff --git a/net/ipv6/Kconfig b/net/ipv6/Kconfig
index e74a41b878d9..f5b568867e08 100644
--- a/net/ipv6/Kconfig
+++ b/net/ipv6/Kconfig
@@ -22,6 +22,7 @@ config IPV6_PRIVACY
config INET6_AH
tristate "IPv6: AH transformation"
depends on IPV6
+ select XFRM
select CRYPTO
select CRYPTO_HMAC
select CRYPTO_MD5
@@ -34,6 +35,7 @@ config INET6_AH
config INET6_ESP
tristate "IPv6: ESP transformation"
depends on IPV6
+ select XFRM
select CRYPTO
select CRYPTO_HMAC
select CRYPTO_MD5
@@ -47,6 +49,7 @@ config INET6_ESP
config INET6_IPCOMP
tristate "IPv6: IPComp transformation"
depends on IPV6
+ select XFRM
select CRYPTO
select CRYPTO_DEFLATE
---help---
diff --git a/net/ipv6/Makefile b/net/ipv6/Makefile
index cb3303428145..07d9848f02df 100644
--- a/net/ipv6/Makefile
+++ b/net/ipv6/Makefile
@@ -8,8 +8,10 @@ ipv6-objs := af_inet6.o anycast.o ip6_output.o ip6_input.o addrconf.o sit.o \
route.o ip6_fib.o ipv6_sockglue.o ndisc.o udp.o raw.o \
protocol.o icmp.o mcast.o reassembly.o tcp_ipv6.o \
exthdrs.o sysctl_net_ipv6.o datagram.o proc.o \
- ip6_flowlabel.o ipv6_syms.o \
- xfrm6_policy.o xfrm6_state.o xfrm6_input.o
+ ip6_flowlabel.o ipv6_syms.o
+
+ipv6-$(CONFIG_XFRM) += xfrm6_policy.o xfrm6_state.o xfrm6_input.o
+ipv6-objs += $(ipv6-y)
obj-$(CONFIG_INET6_AH) += ah6.o
obj-$(CONFIG_INET6_ESP) += esp6.o
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index 925effb2390c..774ae2156efa 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -2593,6 +2593,53 @@ int addrconf_sysctl_forward(ctl_table *ctl, int write, struct file * filp,
return ret;
}
+static int addrconf_sysctl_forward_strategy(ctl_table *table,
+ int *name, int nlen,
+ void *oldval, size_t *oldlenp,
+ void *newval, size_t newlen,
+ void **context)
+{
+ int *valp = table->data;
+ int new;
+
+ if (!newval || !newlen)
+ return 0;
+ if (newlen != sizeof(int))
+ return -EINVAL;
+ if (get_user(new, (int *)newval))
+ return -EFAULT;
+ if (new == *valp)
+ return 0;
+ if (oldval && oldlenp) {
+ size_t len;
+ if (get_user(len, oldlenp))
+ return -EFAULT;
+ if (len) {
+ if (len > table->maxlen)
+ len = table->maxlen;
+ if (copy_to_user(oldval, valp, len))
+ return -EFAULT;
+ if (put_user(len, oldlenp))
+ return -EFAULT;
+ }
+ }
+
+ if (valp != &ipv6_devconf_dflt.forwarding) {
+ struct inet6_dev *idev;
+ if (valp != &ipv6_devconf.forwarding) {
+ idev = (struct inet6_dev *)table->extra1;
+ if (unlikely(idev == NULL))
+ return -ENODEV;
+ } else
+ idev = NULL;
+ *valp = new;
+ addrconf_forward_change(idev);
+ } else
+ *valp = new;
+
+ return 1;
+}
+
static struct addrconf_sysctl_table
{
struct ctl_table_header *sysctl_header;
@@ -2611,6 +2658,7 @@ static struct addrconf_sysctl_table
.maxlen = sizeof(int),
.mode = 0644,
.proc_handler = &addrconf_sysctl_forward,
+ .strategy = &addrconf_sysctl_forward_strategy,
},
{
.ctl_name = NET_IPV6_HOP_LIMIT,
diff --git a/net/ipv6/ah6.c b/net/ipv6/ah6.c
index 07d92a2e48a3..c13efb13eaf9 100644
--- a/net/ipv6/ah6.c
+++ b/net/ipv6/ah6.c
@@ -265,13 +265,12 @@ int ah6_input(struct xfrm_state *x, struct xfrm_decap_state *decap, struct sk_bu
* There is offset of AH before IPv6 header after the process.
*/
- struct ipv6hdr *iph = skb->nh.ipv6h;
struct ipv6_auth_hdr *ah;
struct ah_data *ahp;
unsigned char *tmp_hdr = NULL;
- u16 hdr_len = skb->data - skb->nh.raw;
+ u16 hdr_len;
u16 ah_hlen;
- u16 cleared_hlen = hdr_len;
+ u16 cleared_hlen;
u16 nh_offset = 0;
u8 nexthdr = 0;
u8 *prevhdr;
@@ -279,6 +278,14 @@ int ah6_input(struct xfrm_state *x, struct xfrm_decap_state *decap, struct sk_bu
if (!pskb_may_pull(skb, sizeof(struct ip_auth_hdr)))
goto out;
+ /* We are going to _remove_ AH header to keep sockets happy,
+ * so... Later this can change. */
+ if (skb_cloned(skb) &&
+ pskb_expand_head(skb, 0, 0, GFP_ATOMIC))
+ goto out;
+
+ hdr_len = skb->data - skb->nh.raw;
+ cleared_hlen = hdr_len;
ah = (struct ipv6_auth_hdr*)skb->data;
ahp = x->data;
nexthdr = ah->nexthdr;
@@ -297,27 +304,22 @@ int ah6_input(struct xfrm_state *x, struct xfrm_decap_state *decap, struct sk_bu
if (!pskb_may_pull(skb, ah_hlen))
goto out;
- /* We are going to _remove_ AH header to keep sockets happy,
- * so... Later this can change. */
- if (skb_cloned(skb) &&
- pskb_expand_head(skb, 0, 0, GFP_ATOMIC))
- goto out;
-
tmp_hdr = kmalloc(cleared_hlen, GFP_ATOMIC);
if (!tmp_hdr)
goto out;
memcpy(tmp_hdr, skb->nh.raw, cleared_hlen);
ipv6_clear_mutable_options(skb, &nh_offset, XFRM_POLICY_IN);
- iph->priority = 0;
- iph->flow_lbl[0] = 0;
- iph->flow_lbl[1] = 0;
- iph->flow_lbl[2] = 0;
- iph->hop_limit = 0;
+ skb->nh.ipv6h->priority = 0;
+ skb->nh.ipv6h->flow_lbl[0] = 0;
+ skb->nh.ipv6h->flow_lbl[1] = 0;
+ skb->nh.ipv6h->flow_lbl[2] = 0;
+ skb->nh.ipv6h->hop_limit = 0;
{
u8 auth_data[ahp->icv_trunc_len];
memcpy(auth_data, ah->auth_data, ahp->icv_trunc_len);
+ memset(ah->auth_data, 0, ahp->icv_trunc_len);
skb_push(skb, skb->data - skb->nh.raw);
ahp->icv(ahp, skb, ah->auth_data);
if (memcmp(ah->auth_data, auth_data, ahp->icv_trunc_len)) {
diff --git a/net/ipv6/icmp.c b/net/ipv6/icmp.c
index 727b681325aa..cbf54afae93b 100644
--- a/net/ipv6/icmp.c
+++ b/net/ipv6/icmp.c
@@ -355,8 +355,8 @@ void icmpv6_send(struct sk_buff *skb, int type, int code, __u32 info,
if (!fl.oif && ipv6_addr_is_multicast(&fl.fl6_dst))
fl.oif = np->mcast_oif;
- err = ip6_dst_lookup(sk, &dst, &fl);
- if (err) goto out;
+ dst = ip6_dst_lookup(sk, &fl);
+ if (dst->error) goto out;
if (hlimit < 0) {
if (ipv6_addr_is_multicast(&fl.fl6_dst))
@@ -434,9 +434,9 @@ static void icmpv6_echo_reply(struct sk_buff *skb)
if (!fl.oif && ipv6_addr_is_multicast(&fl.fl6_dst))
fl.oif = np->mcast_oif;
- err = ip6_dst_lookup(sk, &dst, &fl);
+ dst = ip6_dst_lookup(sk, &fl);
- if (err) goto out;
+ if (dst->error) goto out;
if (hlimit < 0) {
if (ipv6_addr_is_multicast(&fl.fl6_dst))
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
index 6a5eaec0c3bd..840d4117d419 100644
--- a/net/ipv6/ip6_output.c
+++ b/net/ipv6/ip6_output.c
@@ -209,11 +209,6 @@ int ip6_xmit(struct sock *sk, struct sk_buff *skb, struct flowi *fl,
int seg_len = skb->len;
int hlimit;
u32 mtu;
- int err = 0;
-
- if ((err = xfrm_lookup(&skb->dst, fl, sk, 0)) < 0) {
- return err;
- }
if (opt) {
int head_room;
@@ -1141,72 +1136,73 @@ fail:
return err;
}
-int ip6_dst_lookup(struct sock *sk, struct dst_entry **dst, struct flowi *fl)
+struct dst_entry *ip6_dst_lookup(struct sock *sk, struct flowi *fl)
{
- struct ipv6_pinfo *np = inet6_sk(sk);
+ struct dst_entry *dst = NULL;
int err = 0;
- *dst = __sk_dst_check(sk, np->dst_cookie);
- if (*dst) {
- struct rt6_info *rt = (struct rt6_info*)*dst;
-
- /* Yes, checking route validity in not connected
- case is not very simple. Take into account,
- that we do not support routing by source, TOS,
- and MSG_DONTROUTE --ANK (980726)
-
- 1. If route was host route, check that
- cached destination is current.
- If it is network route, we still may
- check its validity using saved pointer
- to the last used address: daddr_cache.
- We do not want to save whole address now,
- (because main consumer of this service
- is tcp, which has not this problem),
- so that the last trick works only on connected
- sockets.
- 2. oif also should be the same.
- */
-
- if (((rt->rt6i_dst.plen != 128 ||
- ipv6_addr_cmp(&fl->fl6_dst, &rt->rt6i_dst.addr))
- && (np->daddr_cache == NULL ||
- ipv6_addr_cmp(&fl->fl6_dst, np->daddr_cache)))
- || (fl->oif && fl->oif != (*dst)->dev->ifindex)) {
- *dst = NULL;
- } else
- dst_hold(*dst);
+ if (sk) {
+ struct ipv6_pinfo *np = inet6_sk(sk);
+
+ dst = __sk_dst_check(sk, np->dst_cookie);
+ if (dst) {
+ struct rt6_info *rt = (struct rt6_info*)dst;
+
+ /* Yes, checking route validity in not connected
+ case is not very simple. Take into account,
+ that we do not support routing by source, TOS,
+ and MSG_DONTROUTE --ANK (980726)
+
+ 1. If route was host route, check that
+ cached destination is current.
+ If it is network route, we still may
+ check its validity using saved pointer
+ to the last used address: daddr_cache.
+ We do not want to save whole address now,
+ (because main consumer of this service
+ is tcp, which has not this problem),
+ so that the last trick works only on connected
+ sockets.
+ 2. oif also should be the same.
+ */
+
+ if (((rt->rt6i_dst.plen != 128 ||
+ ipv6_addr_cmp(&fl->fl6_dst, &rt->rt6i_dst.addr))
+ && (np->daddr_cache == NULL ||
+ ipv6_addr_cmp(&fl->fl6_dst, np->daddr_cache)))
+ || (fl->oif && fl->oif != dst->dev->ifindex)) {
+ dst = NULL;
+ } else
+ dst_hold(dst);
+ }
}
- if (*dst == NULL)
- *dst = ip6_route_output(sk, fl);
+ if (dst == NULL)
+ dst = ip6_route_output(sk, fl);
- if ((*dst)->error) {
- IP6_INC_STATS(Ip6OutNoRoutes);
- dst_release(*dst);
- return -ENETUNREACH;
- }
+ if (dst->error)
+ return dst;
if (ipv6_addr_any(&fl->fl6_src)) {
- err = ipv6_get_saddr(*dst, &fl->fl6_dst, &fl->fl6_src);
+ err = ipv6_get_saddr(dst, &fl->fl6_dst, &fl->fl6_src);
if (err) {
#if IP6_DEBUG >= 2
printk(KERN_DEBUG "ip6_build_xmit: "
"no available source address\n");
#endif
- return err;
+ dst->error = err;
+ return dst;
}
}
- if (*dst) {
- if ((err = xfrm_lookup(dst, fl, sk, 0)) < 0) {
- dst_release(*dst);
- return -ENETUNREACH;
+ if (dst) {
+ if ((err = xfrm_lookup(&dst, fl, sk, 0)) < 0) {
+ dst->error = -ENETUNREACH;
}
}
- return 0;
+ return dst;
}
int ip6_append_data(struct sock *sk, int getfrag(void *from, char *to, int offset, int len, int odd, struct sk_buff *skb),
diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c
index 221a1dd22cbc..8aff8d51527e 100644
--- a/net/ipv6/ip6_tunnel.c
+++ b/net/ipv6/ip6_tunnel.c
@@ -621,6 +621,14 @@ merge_options(struct sock *sk, __u8 encap_limit,
return opt;
}
+static int
+ip6ip6_getfrag(void *from, char *to, int offset, int len, int odd,
+ struct sk_buff *skb)
+{
+ memcpy(to, (char *) from + offset, len);
+ return 0;
+}
+
/**
* ip6ip6_tnl_addr_conflict - compare packet addresses to tunnel's own
* @t: the outgoing tunnel device
@@ -755,9 +763,9 @@ int ip6ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev)
}
if (skb->len > mtu) {
icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu, dev);
- goto tx_err_opt_release;
+ goto tx_err_dst_release;
}
- err = ip6_append_data(sk, ip_generic_getfrag, skb->nh.raw, skb->len, 0,
+ err = ip6_append_data(sk, ip6ip6_getfrag, skb->nh.raw, skb->len, 0,
t->parms.hop_limit, opt, &fl,
(struct rt6_info *)dst, MSG_DONTWAIT);
@@ -785,7 +793,6 @@ int ip6ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev)
return 0;
tx_err_dst_release:
dst_release(dst);
-tx_err_opt_release:
if (opt && opt != orig_opt)
sock_kfree_s(sk, opt, opt->tot_len);
tx_err_free_fl_lbl:
diff --git a/net/ipv6/ipv6_syms.c b/net/ipv6/ipv6_syms.c
index a6eba6e81dbf..178f2cb0f629 100644
--- a/net/ipv6/ipv6_syms.c
+++ b/net/ipv6/ipv6_syms.c
@@ -36,7 +36,9 @@ EXPORT_SYMBOL(in6addr_any);
EXPORT_SYMBOL(in6addr_loopback);
EXPORT_SYMBOL(in6_dev_finish_destroy);
EXPORT_SYMBOL(ip6_find_1stfragopt);
+#ifdef CONFIG_XFRM
EXPORT_SYMBOL(xfrm6_rcv);
+#endif
EXPORT_SYMBOL(rt6_lookup);
EXPORT_SYMBOL(fl6_sock_lookup);
EXPORT_SYMBOL(ipv6_ext_hdr);
diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c
index ac2dbb6d0a0e..c5d193728e75 100644
--- a/net/ipv6/raw.c
+++ b/net/ipv6/raw.c
@@ -658,8 +658,8 @@ static int rawv6_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg
if (!fl.oif && ipv6_addr_is_multicast(&fl.fl6_dst))
fl.oif = np->mcast_oif;
- err = ip6_dst_lookup(sk, &dst, &fl);
- if (err)
+ dst = ip6_dst_lookup(sk, &fl);
+ if ((err = dst->error))
goto out;
if (hlimit < 0) {
diff --git a/net/ipv6/route.c b/net/ipv6/route.c
index b3adf22ef02e..692c0477837c 100644
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -1988,7 +1988,9 @@ void __init ip6_route_init(void)
if (p)
p->proc_fops = &rt6_stats_seq_fops;
#endif
+#ifdef CONFIG_XFRM
xfrm6_init();
+#endif
}
#ifdef MODULE
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
index e5cd4c372577..4d16e99a8e84 100644
--- a/net/ipv6/tcp_ipv6.c
+++ b/net/ipv6/tcp_ipv6.c
@@ -663,7 +663,7 @@ static int tcp_v6_connect(struct sock *sk, struct sockaddr *uaddr,
ipv6_addr_copy(&fl.fl6_dst, rt0->addr);
}
- dst = ip6_route_output(sk, &fl);
+ dst = ip6_dst_lookup(sk, &fl);
if ((err = dst->error) != 0) {
dst_release(dst);
@@ -691,6 +691,8 @@ static int tcp_v6_connect(struct sock *sk, struct sockaddr *uaddr,
tp->ext_header_len = 0;
if (np->opt)
tp->ext_header_len = np->opt->opt_flen + np->opt->opt_nflen;
+ tp->ext2_header_len = dst->header_len;
+
tp->mss_clamp = IPV6_MIN_MTU - sizeof(struct tcphdr) - sizeof(struct ipv6hdr);
inet->dport = usin->sin6_port;
@@ -788,7 +790,7 @@ static void tcp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
fl.fl_ip_dport = inet->dport;
fl.fl_ip_sport = inet->sport;
- dst = ip6_route_output(sk, &fl);
+ dst = ip6_dst_lookup(sk, &fl);
} else
dst_hold(dst);
@@ -889,7 +891,7 @@ static int tcp_v6_send_synack(struct sock *sk, struct open_request *req,
ipv6_addr_copy(&fl.fl6_dst, rt0->addr);
}
- dst = ip6_route_output(sk, &fl);
+ dst = ip6_dst_lookup(sk, &fl);
if (dst->error)
goto done;
}
@@ -1018,7 +1020,7 @@ static void tcp_v6_send_reset(struct sk_buff *skb)
fl.fl_ip_sport = t1->source;
/* sk = NULL, but it is safe for now. RST socket required. */
- buff->dst = ip6_route_output(NULL, &fl);
+ buff->dst = ip6_dst_lookup(NULL, &fl);
if (buff->dst->error == 0) {
ip6_xmit(NULL, buff, &fl, NULL, 0);
@@ -1081,7 +1083,7 @@ static void tcp_v6_send_ack(struct sk_buff *skb, u32 seq, u32 ack, u32 win, u32
fl.fl_ip_dport = t1->dest;
fl.fl_ip_sport = t1->source;
- buff->dst = ip6_route_output(NULL, &fl);
+ buff->dst = ip6_dst_lookup(NULL, &fl);
if (buff->dst->error == 0) {
ip6_xmit(NULL, buff, &fl, NULL, 0);
@@ -1329,7 +1331,7 @@ static struct sock * tcp_v6_syn_recv_sock(struct sock *sk, struct sk_buff *skb,
fl.fl_ip_dport = req->rmt_port;
fl.fl_ip_sport = inet_sk(sk)->sport;
- dst = ip6_route_output(sk, &fl);
+ dst = ip6_dst_lookup(sk, &fl);
}
if (dst->error)
@@ -1401,6 +1403,7 @@ static struct sock * tcp_v6_syn_recv_sock(struct sock *sk, struct sk_buff *skb,
if (newnp->opt)
newtp->ext_header_len = newnp->opt->opt_nflen +
newnp->opt->opt_flen;
+ newtp->ext2_header_len = dst->header_len;
tcp_sync_mss(newsk, dst_pmtu(dst));
newtp->advmss = dst_metric(dst, RTAX_ADVMSS);
@@ -1727,7 +1730,7 @@ static int tcp_v6_rebuild_header(struct sock *sk)
ipv6_addr_copy(&fl.fl6_dst, rt0->addr);
}
- dst = ip6_route_output(sk, &fl);
+ dst = ip6_dst_lookup(sk, &fl);
if (dst->error) {
err = dst->error;
@@ -1770,7 +1773,7 @@ static int tcp_v6_xmit(struct sk_buff *skb, int ipfragok)
dst = __sk_dst_check(sk, np->dst_cookie);
if (dst == NULL) {
- dst = ip6_route_output(sk, &fl);
+ dst = ip6_dst_lookup(sk, &fl);
if (dst->error) {
sk->sk_err_soft = -dst->error;
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c
index 40859abf1600..699cbc866c77 100644
--- a/net/ipv6/udp.c
+++ b/net/ipv6/udp.c
@@ -811,8 +811,10 @@ static int udpv6_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg
* The socket lock must be held while it's corked.
*/
lock_sock(sk);
- if (likely(up->pending))
+ if (likely(up->pending)) {
+ dst = NULL;
goto do_append_data;
+ }
release_sock(sk);
}
ulen += sizeof(struct udphdr);
@@ -928,8 +930,8 @@ static int udpv6_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg
if (!fl.oif && ipv6_addr_is_multicast(&fl.fl6_dst))
fl.oif = np->mcast_oif;
- err = ip6_dst_lookup(sk, &dst, &fl);
- if (err)
+ dst = ip6_dst_lookup(sk, &fl);
+ if ((err = dst->error))
goto out;
if (hlimit < 0) {
@@ -968,9 +970,10 @@ do_append_data:
else if (!corkreq)
err = udp_v6_push_pending_frames(sk, up);
- ip6_dst_store(sk, dst,
- !ipv6_addr_cmp(&fl.fl6_dst, &np->daddr) ?
- &np->daddr : NULL);
+ if (dst)
+ ip6_dst_store(sk, dst,
+ !ipv6_addr_cmp(&fl.fl6_dst, &np->daddr) ?
+ &np->daddr : NULL);
if (err > 0)
err = np->recverr ? net_xmit_errno(err) : 0;
release_sock(sk);
diff --git a/net/netsyms.c b/net/netsyms.c
index 78efec6ffb89..2fa1ef842b1b 100644
--- a/net/netsyms.c
+++ b/net/netsyms.c
@@ -56,7 +56,6 @@ extern __u32 sysctl_rmem_max;
#include <linux/inet.h>
#include <linux/mroute.h>
#include <linux/igmp.h>
-#include <net/xfrm.h>
#if defined(CONFIG_INET_AH) || defined(CONFIG_INET_AH_MODULE) || defined(CONFIG_INET6_AH) || defined(CONFIG_INET6_AH_MODULE)
#include <net/ah.h>
#endif
@@ -276,6 +275,7 @@ EXPORT_SYMBOL(ip_dev_find);
EXPORT_SYMBOL(inetdev_by_index);
EXPORT_SYMBOL(in_dev_finish_destroy);
EXPORT_SYMBOL(ip_defrag);
+EXPORT_SYMBOL(inet_peer_idlock);
/* Route manipulation */
EXPORT_SYMBOL(ip_rt_ioctl);
@@ -293,80 +293,6 @@ EXPORT_SYMBOL(tcp_proc_unregister);
/* needed for ip_gre -cw */
EXPORT_SYMBOL(ip_statistics);
-
-EXPORT_SYMBOL(xfrm_user_policy);
-EXPORT_SYMBOL(km_waitq);
-EXPORT_SYMBOL(km_new_mapping);
-EXPORT_SYMBOL(xfrm_cfg_sem);
-EXPORT_SYMBOL(xfrm_policy_alloc);
-EXPORT_SYMBOL(__xfrm_policy_destroy);
-EXPORT_SYMBOL(xfrm_lookup);
-EXPORT_SYMBOL(__xfrm_policy_check);
-EXPORT_SYMBOL(__xfrm_route_forward);
-EXPORT_SYMBOL(xfrm_state_alloc);
-EXPORT_SYMBOL(__xfrm_state_destroy);
-EXPORT_SYMBOL(xfrm_state_find);
-EXPORT_SYMBOL(xfrm_state_insert);
-EXPORT_SYMBOL(xfrm_state_add);
-EXPORT_SYMBOL(xfrm_state_update);
-EXPORT_SYMBOL(xfrm_state_check_expire);
-EXPORT_SYMBOL(xfrm_state_check_space);
-EXPORT_SYMBOL(xfrm_state_lookup);
-EXPORT_SYMBOL(xfrm_state_register_afinfo);
-EXPORT_SYMBOL(xfrm_state_unregister_afinfo);
-EXPORT_SYMBOL(xfrm_state_get_afinfo);
-EXPORT_SYMBOL(xfrm_state_put_afinfo);
-EXPORT_SYMBOL(xfrm_state_delete_tunnel);
-EXPORT_SYMBOL(xfrm_replay_check);
-EXPORT_SYMBOL(xfrm_replay_advance);
-EXPORT_SYMBOL(xfrm_check_selectors);
-EXPORT_SYMBOL(xfrm_check_output);
-EXPORT_SYMBOL(__secpath_destroy);
-EXPORT_SYMBOL(secpath_dup);
-EXPORT_SYMBOL(xfrm_get_acqseq);
-EXPORT_SYMBOL(xfrm_parse_spi);
-EXPORT_SYMBOL(xfrm4_rcv);
-EXPORT_SYMBOL(xfrm4_tunnel_register);
-EXPORT_SYMBOL(xfrm4_tunnel_deregister);
-EXPORT_SYMBOL(xfrm4_tunnel_check_size);
-EXPORT_SYMBOL(xfrm_register_type);
-EXPORT_SYMBOL(xfrm_unregister_type);
-EXPORT_SYMBOL(xfrm_get_type);
-EXPORT_SYMBOL(inet_peer_idlock);
-EXPORT_SYMBOL(xfrm_register_km);
-EXPORT_SYMBOL(xfrm_unregister_km);
-EXPORT_SYMBOL(xfrm_state_delete);
-EXPORT_SYMBOL(xfrm_state_walk);
-EXPORT_SYMBOL(xfrm_find_acq_byseq);
-EXPORT_SYMBOL(xfrm_find_acq);
-EXPORT_SYMBOL(xfrm_alloc_spi);
-EXPORT_SYMBOL(xfrm_state_flush);
-EXPORT_SYMBOL(xfrm_policy_kill);
-EXPORT_SYMBOL(xfrm_policy_bysel);
-EXPORT_SYMBOL(xfrm_policy_insert);
-EXPORT_SYMBOL(xfrm_policy_walk);
-EXPORT_SYMBOL(xfrm_policy_flush);
-EXPORT_SYMBOL(xfrm_policy_byid);
-EXPORT_SYMBOL(xfrm_policy_list);
-EXPORT_SYMBOL(xfrm_dst_lookup);
-EXPORT_SYMBOL(xfrm_policy_register_afinfo);
-EXPORT_SYMBOL(xfrm_policy_unregister_afinfo);
-EXPORT_SYMBOL(xfrm_policy_get_afinfo);
-EXPORT_SYMBOL(xfrm_policy_put_afinfo);
-
-EXPORT_SYMBOL_GPL(xfrm_probe_algs);
-EXPORT_SYMBOL_GPL(xfrm_count_auth_supported);
-EXPORT_SYMBOL_GPL(xfrm_count_enc_supported);
-EXPORT_SYMBOL_GPL(xfrm_aalg_get_byidx);
-EXPORT_SYMBOL_GPL(xfrm_ealg_get_byidx);
-EXPORT_SYMBOL_GPL(xfrm_calg_get_byidx);
-EXPORT_SYMBOL_GPL(xfrm_aalg_get_byid);
-EXPORT_SYMBOL_GPL(xfrm_ealg_get_byid);
-EXPORT_SYMBOL_GPL(xfrm_calg_get_byid);
-EXPORT_SYMBOL_GPL(xfrm_aalg_get_byname);
-EXPORT_SYMBOL_GPL(xfrm_ealg_get_byname);
-EXPORT_SYMBOL_GPL(xfrm_calg_get_byname);
-EXPORT_SYMBOL_GPL(skb_icv_walk);
#if defined(CONFIG_INET_ESP) || defined(CONFIG_INET_ESP_MODULE) || defined(CONFIG_INET6_ESP) || defined(CONFIG_INET6_ESP_MODULE)
EXPORT_SYMBOL_GPL(skb_cow_data);
EXPORT_SYMBOL_GPL(pskb_put);
@@ -482,10 +408,8 @@ EXPORT_SYMBOL(sysctl_tcp_tw_recycle);
EXPORT_SYMBOL(sysctl_max_syn_backlog);
#endif
-#endif
-
-#if defined (CONFIG_IPV6_MODULE) || defined (CONFIG_IP_SCTP_MODULE) || defined (CONFIG_IPV6_TUNNEL_MODULE)
EXPORT_SYMBOL(ip_generic_getfrag);
+
#endif
EXPORT_SYMBOL(tcp_read_sock);
diff --git a/net/sunrpc/svcsock.c b/net/sunrpc/svcsock.c
index f6eea03b1e47..42f9f6bc359b 100644
--- a/net/sunrpc/svcsock.c
+++ b/net/sunrpc/svcsock.c
@@ -567,14 +567,17 @@ svc_udp_recvfrom(struct svc_rqst *rqstp)
(serv->sv_nrthreads+3) * serv->sv_bufsz,
(serv->sv_nrthreads+3) * serv->sv_bufsz);
- if ((rqstp->rq_deferred = svc_deferred_dequeue(svsk)))
+ if ((rqstp->rq_deferred = svc_deferred_dequeue(svsk))) {
+ svc_sock_received(svsk);
return svc_deferred_recv(rqstp);
+ }
clear_bit(SK_DATA, &svsk->sk_flags);
while ((skb = skb_recv_datagram(svsk->sk_sk, 0, 1, &err)) == NULL) {
- svc_sock_received(svsk);
- if (err == -EAGAIN)
+ if (err == -EAGAIN) {
+ svc_sock_received(svsk);
return err;
+ }
/* possibly an icmp error */
dprintk("svc: recvfrom returned error %d\n", -err);
}
@@ -869,8 +872,10 @@ svc_tcp_recvfrom(struct svc_rqst *rqstp)
test_bit(SK_CONN, &svsk->sk_flags),
test_bit(SK_CLOSE, &svsk->sk_flags));
- if ((rqstp->rq_deferred = svc_deferred_dequeue(svsk)))
+ if ((rqstp->rq_deferred = svc_deferred_dequeue(svsk))) {
+ svc_sock_received(svsk);
return svc_deferred_recv(rqstp);
+ }
if (test_bit(SK_CLOSE, &svsk->sk_flags)) {
svc_delete_socket(svsk);
@@ -1545,6 +1550,5 @@ static struct svc_deferred_req *svc_deferred_dequeue(struct svc_sock *svsk)
set_bit(SK_DEFERRED, &svsk->sk_flags);
}
spin_unlock(&serv->sv_lock);
- svc_sock_received(svsk);
return dr;
}
diff --git a/net/xfrm/Kconfig b/net/xfrm/Kconfig
index f58b5094b183..58c7d2671389 100644
--- a/net/xfrm/Kconfig
+++ b/net/xfrm/Kconfig
@@ -1,9 +1,13 @@
#
# XFRM configuration
#
+config XFRM
+ bool
+ depends on NET
+
config XFRM_USER
tristate "IPsec user configuration interface"
- depends on INET
+ depends on INET && XFRM
---help---
Support for IPsec user configuration interface used
by native Linux tools.
diff --git a/net/xfrm/Makefile b/net/xfrm/Makefile
index 227f8ec08a69..7cf00be13197 100644
--- a/net/xfrm/Makefile
+++ b/net/xfrm/Makefile
@@ -2,6 +2,7 @@
# Makefile for the XFRM subsystem.
#
-obj-y := xfrm_policy.o xfrm_state.o xfrm_input.o xfrm_algo.o xfrm_output.o
+obj-$(CONFIG_XFRM) := xfrm_policy.o xfrm_state.o xfrm_input.o xfrm_algo.o xfrm_output.o \
+ xfrm_export.o
obj-$(CONFIG_XFRM_USER) += xfrm_user.o
diff --git a/net/xfrm/xfrm_export.c b/net/xfrm/xfrm_export.c
new file mode 100644
index 000000000000..fdd4d0ee7af7
--- /dev/null
+++ b/net/xfrm/xfrm_export.c
@@ -0,0 +1,75 @@
+#include <linux/module.h>
+#include <net/xfrm.h>
+
+EXPORT_SYMBOL(xfrm_user_policy);
+EXPORT_SYMBOL(km_waitq);
+EXPORT_SYMBOL(km_new_mapping);
+EXPORT_SYMBOL(xfrm_cfg_sem);
+EXPORT_SYMBOL(xfrm_policy_alloc);
+EXPORT_SYMBOL(__xfrm_policy_destroy);
+EXPORT_SYMBOL(xfrm_lookup);
+EXPORT_SYMBOL(__xfrm_policy_check);
+EXPORT_SYMBOL(__xfrm_route_forward);
+EXPORT_SYMBOL(xfrm_state_alloc);
+EXPORT_SYMBOL(__xfrm_state_destroy);
+EXPORT_SYMBOL(xfrm_state_find);
+EXPORT_SYMBOL(xfrm_state_insert);
+EXPORT_SYMBOL(xfrm_state_add);
+EXPORT_SYMBOL(xfrm_state_update);
+EXPORT_SYMBOL(xfrm_state_check_expire);
+EXPORT_SYMBOL(xfrm_state_check_space);
+EXPORT_SYMBOL(xfrm_state_lookup);
+EXPORT_SYMBOL(xfrm_state_register_afinfo);
+EXPORT_SYMBOL(xfrm_state_unregister_afinfo);
+EXPORT_SYMBOL(xfrm_state_get_afinfo);
+EXPORT_SYMBOL(xfrm_state_put_afinfo);
+EXPORT_SYMBOL(xfrm_state_delete_tunnel);
+EXPORT_SYMBOL(xfrm_replay_check);
+EXPORT_SYMBOL(xfrm_replay_advance);
+EXPORT_SYMBOL(xfrm_check_selectors);
+EXPORT_SYMBOL(xfrm_check_output);
+EXPORT_SYMBOL(__secpath_destroy);
+EXPORT_SYMBOL(secpath_dup);
+EXPORT_SYMBOL(xfrm_get_acqseq);
+EXPORT_SYMBOL(xfrm_parse_spi);
+EXPORT_SYMBOL(xfrm4_rcv);
+EXPORT_SYMBOL(xfrm4_tunnel_register);
+EXPORT_SYMBOL(xfrm4_tunnel_deregister);
+EXPORT_SYMBOL(xfrm4_tunnel_check_size);
+EXPORT_SYMBOL(xfrm_register_type);
+EXPORT_SYMBOL(xfrm_unregister_type);
+EXPORT_SYMBOL(xfrm_get_type);
+EXPORT_SYMBOL(xfrm_register_km);
+EXPORT_SYMBOL(xfrm_unregister_km);
+EXPORT_SYMBOL(xfrm_state_delete);
+EXPORT_SYMBOL(xfrm_state_walk);
+EXPORT_SYMBOL(xfrm_find_acq_byseq);
+EXPORT_SYMBOL(xfrm_find_acq);
+EXPORT_SYMBOL(xfrm_alloc_spi);
+EXPORT_SYMBOL(xfrm_state_flush);
+EXPORT_SYMBOL(xfrm_policy_kill);
+EXPORT_SYMBOL(xfrm_policy_bysel);
+EXPORT_SYMBOL(xfrm_policy_insert);
+EXPORT_SYMBOL(xfrm_policy_walk);
+EXPORT_SYMBOL(xfrm_policy_flush);
+EXPORT_SYMBOL(xfrm_policy_byid);
+EXPORT_SYMBOL(xfrm_policy_list);
+EXPORT_SYMBOL(xfrm_dst_lookup);
+EXPORT_SYMBOL(xfrm_policy_register_afinfo);
+EXPORT_SYMBOL(xfrm_policy_unregister_afinfo);
+EXPORT_SYMBOL(xfrm_policy_get_afinfo);
+EXPORT_SYMBOL(xfrm_policy_put_afinfo);
+
+EXPORT_SYMBOL_GPL(xfrm_probe_algs);
+EXPORT_SYMBOL_GPL(xfrm_count_auth_supported);
+EXPORT_SYMBOL_GPL(xfrm_count_enc_supported);
+EXPORT_SYMBOL_GPL(xfrm_aalg_get_byidx);
+EXPORT_SYMBOL_GPL(xfrm_ealg_get_byidx);
+EXPORT_SYMBOL_GPL(xfrm_calg_get_byidx);
+EXPORT_SYMBOL_GPL(xfrm_aalg_get_byid);
+EXPORT_SYMBOL_GPL(xfrm_ealg_get_byid);
+EXPORT_SYMBOL_GPL(xfrm_calg_get_byid);
+EXPORT_SYMBOL_GPL(xfrm_aalg_get_byname);
+EXPORT_SYMBOL_GPL(xfrm_ealg_get_byname);
+EXPORT_SYMBOL_GPL(xfrm_calg_get_byname);
+EXPORT_SYMBOL_GPL(skb_icv_walk);
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c
index b1c87c9924f2..049c7c833d95 100644
--- a/net/xfrm/xfrm_user.c
+++ b/net/xfrm/xfrm_user.c
@@ -527,7 +527,7 @@ static int verify_newpolicy_info(struct xfrm_userpolicy_info *p)
return -EINVAL;
};
- switch (p->family) {
+ switch (p->sel.family) {
case AF_INET:
break;
@@ -594,7 +594,7 @@ static void copy_from_user_policy(struct xfrm_policy *xp, struct xfrm_userpolicy
memcpy(&xp->lft, &p->lft, sizeof(xp->lft));
xp->action = p->action;
xp->flags = p->flags;
- xp->family = p->family;
+ xp->family = p->sel.family;
/* XXX xp->share = p->share; */
}
@@ -605,7 +605,7 @@ static void copy_to_user_policy(struct xfrm_policy *xp, struct xfrm_userpolicy_i
memcpy(&p->curlft, &xp->curlft, sizeof(p->curlft));
p->priority = xp->priority;
p->index = xp->index;
- p->family = xp->family;
+ p->sel.family = xp->family;
p->dir = dir;
p->action = xp->action;
p->flags = xp->flags;
diff --git a/security/selinux/avc.c b/security/selinux/avc.c
index 13372c7e3a61..5bfa82933ca0 100644
--- a/security/selinux/avc.c
+++ b/security/selinux/avc.c
@@ -16,6 +16,7 @@
#include <linux/slab.h>
#include <linux/fs.h>
#include <linux/dcache.h>
+#include <linux/init.h>
#include <linux/skbuff.h>
#include <net/sock.h>
#include <linux/un.h>
diff --git a/security/selinux/ss/global.h b/security/selinux/ss/global.h
index 5835dec93839..2358c85da0ae 100644
--- a/security/selinux/ss/global.h
+++ b/security/selinux/ss/global.h
@@ -7,7 +7,7 @@
#include <linux/ctype.h>
#include <linux/in.h>
#include <linux/spinlock.h>
-#include <asm/semaphore.h>
+#include <linux/sched.h>
#include "flask.h"
#include "avc.h"
diff --git a/sound/oss/ad1848.c b/sound/oss/ad1848.c
index 2ff998428774..b53b9d1809a1 100644
--- a/sound/oss/ad1848.c
+++ b/sound/oss/ad1848.c
@@ -2971,8 +2971,10 @@ static struct isapnp_device_id id_table[] __devinitdata = {
ISAPNP_VENDOR('C','S','C'), ISAPNP_FUNCTION(0x0000), 0 },
{ ISAPNP_ANY_ID, ISAPNP_ANY_ID,
ISAPNP_VENDOR('C','S','C'), ISAPNP_FUNCTION(0x0100), 0 },
+ /* The main driver for this card is opl3sa2
{ ISAPNP_ANY_ID, ISAPNP_ANY_ID,
ISAPNP_VENDOR('Y','M','H'), ISAPNP_FUNCTION(0x0021), 0 },
+ */
{ ISAPNP_VENDOR('G','R','V'), ISAPNP_DEVICE(0x0001),
ISAPNP_VENDOR('G','R','V'), ISAPNP_FUNCTION(0x0000), 0 },
{0}
diff --git a/sound/oss/gus_wave.c b/sound/oss/gus_wave.c
index 8be49423b6d9..1baa1e62be42 100644
--- a/sound/oss/gus_wave.c
+++ b/sound/oss/gus_wave.c
@@ -3034,7 +3034,7 @@ void __init gus_wave_init(struct address_info *hw_config)
gus_initialize();
- if ((gus_mem_size > 0) & !gus_no_wave_dma)
+ if ((gus_mem_size > 0) && !gus_no_wave_dma)
{
hw_config->slots[4] = -1;
if ((gus_devnum = sound_install_audiodrv(AUDIO_DRIVER_VERSION,
diff --git a/sound/oss/trident.c b/sound/oss/trident.c
index a39163190630..117535456d47 100644
--- a/sound/oss/trident.c
+++ b/sound/oss/trident.c
@@ -3017,6 +3017,8 @@ static u16 ali_ac97_get(struct trident_card *card, int secondary, u8 reg)
}
data = inl(TRID_REG(card, address));
+
+ spin_unlock_irqrestore(&card->lock, flags);
return ((u16) (data >> 16));